commit e1a4931375ea6fea213ba32bf56e22817b16cad3 Author: Dmytro Bogovych Date: Tue Jun 5 11:05:37 2018 +0300 - initial import diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..09b6686f --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,57 @@ +project(rtphone) + +# Rely on C++ 11 +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +set (rtphone_libs libs) +set (rtphone_engine engine) + +set (RTPHONE_SOURCES + ${rtphone_engine}/media/MT_Statistics.cpp + ${rtphone_engine}/media/MT_WebRtc.cpp + ${rtphone_engine}/media/MT_Stream.cpp + ${rtphone_engine}/media/MT_SrtpHelper.cpp + ${rtphone_engine}/media/MT_SingleAudioStream.cpp + ${rtphone_engine}/media/MT_NativeRtpSender.cpp + ${rtphone_engine}/media/MT_Dtmf.cpp + ${rtphone_engine}/media/MT_CodecList.cpp + ${rtphone_engine}/media/MT_Codec.cpp + ${rtphone_engine}/media/MT_Box.cpp + ${rtphone_engine}/media/MT_AudioStream.cpp + ${rtphone_engine}/media/MT_AudioReceiver.cpp + ${rtphone_engine}/media/MT_AudioCodec.cpp + ${rtphone_engine}/media/MT_SevanaMos.cpp + ${rtphone_engine}/media/MT_AmrCodec.cpp + ${rtphone_engine}/media/MT_CngHelper.cpp + ${rtphone_engine}/agent/Agent_Impl.cpp + ${rtphone_engine}/agent/Agent_AudioManager.cpp + ${rtphone_engine}/endpoint/EP_Account.cpp + ${rtphone_engine}/endpoint/EP_AudioProvider.cpp + ${rtphone_engine}/endpoint/EP_DataProvider.cpp + ${rtphone_engine}/endpoint/EP_Engine.cpp + ${rtphone_engine}/endpoint/EP_NetworkQueue.cpp + ${rtphone_engine}/endpoint/EP_Observer.cpp + ${rtphone_engine}/endpoint/EP_Session.cpp +) + +add_library(rtphone STATIC ${RTPHONE_SOURCES}) + +add_subdirectory(${rtphone_engine}/helper) +add_subdirectory(${rtphone_engine}/audio) +add_subdirectory(${rtphone_libs}/resiprocate) +add_subdirectory(${rtphone_libs}/ice) +add_subdirectory(${rtphone_libs}/jrtplib/src) +add_subdirectory(${rtphone_libs}/libg729) +add_subdirectory(${rtphone_libs}/libgsm) +add_subdirectory(${rtphone_libs}/gsmhr) +add_subdirectory(${rtphone_libs}/g722) +add_subdirectory(${rtphone_libs}/speexdsp) +add_subdirectory(${rtphone_libs}/srtp) +add_subdirectory(${rtphone_libs}/webrtc) + +target_link_libraries(rtphone ice_stack jrtplib g729_codec gsm_codec + gsmhr_codec g722_codec srtp resiprocate + opencore-amrnb opencore-amrwb + helper_lib audio_lib webrtc speexdsp + ssl crypto opus uuid dl) diff --git a/src/engine/agent/Agent_AudioManager.cpp b/src/engine/agent/Agent_AudioManager.cpp new file mode 100644 index 00000000..9bd3c74a --- /dev/null +++ b/src/engine/agent/Agent_AudioManager.cpp @@ -0,0 +1,193 @@ +/* Copyright(C) 2007-2017 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "Agent_AudioManager.h" +#include "../engine/audio/Audio_WavFile.h" +#include "../engine/helper/HL_String.h" +#include "../engine/audio/Audio_Null.h" + +#if defined(TARGET_ANDROID) +# include "../engine/audio/Audio_Android.h" +#endif + +#define LOG_SUBSYSTEM "AudioManager" + + +// ---------------- AudioManager ------------- +//static AudioManager GAudioManager; + +AudioManager::AudioManager() +:mTerminal(nullptr) +{ + mPlayer.setDelegate(this); +} + +AudioManager::~AudioManager() +{ + //stop(); +} + +AudioManager& AudioManager::instance() +{ + static std::shared_ptr GAudioManager; + + if (!GAudioManager) + GAudioManager = std::make_shared(); + + return *GAudioManager; +} + +void AudioManager::setTerminal(MT::Terminal* terminal) +{ + mTerminal = terminal; +} + +MT::Terminal* AudioManager::terminal() +{ + return mTerminal; +} + +#define LOCK_MANAGER std::unique_lock l(mGuard) +void AudioManager::start(int usageId) +{ + assert(mTerminal); + LOCK_MANAGER; + + ICELogInfo(<< "Start main audio with usage id " << usageId); + + if (mUsage.obtain(usageId) > 1) + return; + + if (Audio::OsEngine::instance()) + Audio::OsEngine::instance()->open(); + + if (!mAudioInput || !mAudioOutput) + { + // Disable AEC for now - because PVQA conflicts with speex AEC. + std::shared_ptr enumerator(Audio::Enumerator::make(usageId == atNull)); + if (!mTerminal->audio()) + mTerminal->setAudio(std::make_shared(false, true)); + + if (!mAudioInput) + { + enumerator->open(Audio::myMicrophone); + int inputIndex = enumerator->indexOfDefaultDevice(); + + // Construct and set to terminal's audio pair input device + if (usageId != atNull) + mAudioInput = Audio::PInputDevice(Audio::InputDevice::make(enumerator->idAt(inputIndex))); + else + mAudioInput = Audio::PInputDevice(new Audio::NullInputDevice()); + + mTerminal->audio()->setInput(mAudioInput); + } + + if (!mAudioOutput) + { + Audio::Enumerator *enumerator = Audio::Enumerator::make(usageId == atNull); + enumerator->open(Audio::mySpeaker); + int outputIndex = enumerator->indexOfDefaultDevice(); + + // Construct and set terminal's audio pair output device + if (usageId != atNull) + { + if (outputIndex >= enumerator->count()) + outputIndex = 0; + + mAudioOutput = Audio::POutputDevice( + Audio::OutputDevice::make(enumerator->idAt(outputIndex))); + } + else + mAudioOutput = Audio::POutputDevice(new Audio::NullOutputDevice()); + + mTerminal->audio()->setOutput(mAudioOutput); + } + } + + // Open audio + if (mAudioInput) + mAudioInput->open(); + if (mAudioOutput) + mAudioOutput->open(); +} + +void AudioManager::close() +{ + mUsage.clear(); + if (mAudioInput) + { + mAudioInput->close(); + mAudioInput.reset(); + } + + if (mAudioOutput) + { + mAudioOutput->close(); + mAudioOutput.reset(); + } + mPlayer.setOutput(Audio::POutputDevice()); +} + +void AudioManager::stop(int usageId) +{ + LOCK_MANAGER; + + ICELogInfo( << "Stop main audio with usage id " << usageId); + if (mTerminal) + { + if (mTerminal->audio()) + mTerminal->audio()->player().release(usageId); + } + + if (!mUsage.release(usageId)) + { + close(); + + // Reset device pair on terminal side + mTerminal->setAudio(Audio::PDevicePair()); + + if (Audio::OsEngine::instance()) + Audio::OsEngine::instance()->close(); + } +} + +void AudioManager::startPlayFile(int usageId, const std::string& path, AudioTarget target, LoopMode lm, int timelimit) +{ + // Check if file exists + Audio::PWavFileReader r = std::make_shared(); +#ifdef TARGET_WIN + r->open(StringHelper::makeTstring(path)); +#else + r->open(path); +#endif + if (!r->isOpened()) + { + ICELogCritical(<< "Cannot open file to play"); + return; + } + + // Delegate processing to existing audio device pair manager + mTerminal->audio()->player().add(usageId, r, lm == lmLoopAudio, timelimit); + start(usageId); +} + +void AudioManager::stopPlayFile(int usageId) +{ + stop(usageId); + mPlayer.release(usageId); +} + +void AudioManager::onFilePlayed(Audio::Player::PlaylistItem& item) +{ +} + +void AudioManager::process() +{ + mPlayer.releasePlayed(); + std::vector ids; + mTerminal->audio()->player().retrieveUsageIds(ids); + for (unsigned i=0; i UsageMap; + UsageCounter mUsage; + std::mutex mGuard; +}; +#endif diff --git a/src/engine/agent/Agent_Impl.cpp b/src/engine/agent/Agent_Impl.cpp new file mode 100644 index 00000000..1205c8fd --- /dev/null +++ b/src/engine/agent/Agent_Impl.cpp @@ -0,0 +1,908 @@ +#include "Agent_Impl.h" +#include "json/json.h" +#include "helper/HL_String.h" +#include "helper/HL_StreamState.h" +#include "helper/HL_VariantMap.h" +#include "helper/HL_CsvReader.h" + +#if defined(TARGET_ANDROID) +//# include "CAndroidSystemInfo.h" +#endif +#include + +const std::string Status_Ok = "ok"; +const std::string Status_SessionNotFound = "session not found"; +const std::string Status_AccountNotFound = "account not found"; +const std::string Status_FailedToOpenFile = "failed to open file"; +const std::string Status_NoActiveProvider = "no active provider"; +const std::string Status_NoMediaAction = "no valid media action"; +const std::string Status_NoCommand = "no valid command"; + + +#define LOG_SUBSYSTEM "Agent" + +AgentImpl::AgentImpl() + :mShutdown(false), mEventListChangeCondVar() +{ +#if defined(TARGET_ANDROID) || defined(TARGET_WIN) + ice::GLogger.useDebugWindow(true); +#endif + ice::GLogger.setLevel(ice::LogLevel::LL_DEBUG); +} + +AgentImpl::~AgentImpl() +{ + stopAgentAndThread(); +} + +void AgentImpl::run() +{ + while (!mShutdown) + { + { + std::unique_lock l(mAgentMutex); + process(); + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } +} + +std::string AgentImpl::command(const std::string& command) +{ + if (command.empty()) + return ""; + + Json::Value d, answer; + try + { + Json::Reader r; + if (!r.parse(command, d)) + return ""; + + std::string cmd = d["command"].asString(); + + if (cmd == "config") + processConfig(d, answer); + else + if (cmd == "start") + processStart(d, answer); + else + if (cmd == "stop") + processStop(d, answer); + else + if (cmd == "account_create") + processCreateAccount(d, answer); + else + if (cmd == "account_start") + processStartAccount(d, answer); + else + if (cmd == "account_setuserinfo") + processSetUserInfoToAccount(d, answer); + else + if (cmd == "session_create") + processCreateSession(d, answer); + else + if (cmd == "session_start") + processStartSession(d, answer); + else + if (cmd == "session_stop") + processStopSession(d, answer); + else + if (cmd == "session_accept") + processAcceptSession(d, answer); + else + if (cmd == "session_destroy") + processDestroySession(d, answer); + else + if (cmd == "session_use_stream") + processUseStreamForSession(d, answer); + else + if (cmd == "wait_for_event") + processWaitForEvent(d, answer); + else + if (cmd == "session_get_media_stats") + processGetMediaStats(d, answer); + else + if (cmd == "agent_network_changed") + processNetworkChanged(d, answer); + else + if (cmd == "agent_add_root_cert") + processAddRootCert(d, answer); + else + if (cmd == "detach_log") + { + GLogger.closeFile(); + answer["status"] = Status_Ok; + } + else + if (cmd == "attach_log") + { + GLogger.openFile(); + answer["status"] = Status_Ok; + } + else + if (cmd == "log_message") + processLogMessage(d, answer); + else + { + answer["status"] = Status_NoCommand; + } + } + catch(std::exception& e) + { + answer["status"] = e.what(); + } + return answer.toStyledString(); +} + +bool AgentImpl::waitForData(int milliseconds) +{ + return false; +} + +std::string AgentImpl::read() +{ + return ""; +} + +void AgentImpl::processConfig(Json::Value &d, Json::Value &answer) +{ + std::unique_lock l(mAgentMutex); + +#if !defined(TARGET_ANDROID) && defined(USE_PVQA_LIBRARY) + // It works for desktop OSes only + // Because Android requires special initializing procedure (valid JNI environment context) + std::string pvqaLicense = d["pvqa-license"].asString(), pvqaConfig = d["pvqa-config"].asString(); + if (!pvqaLicense.empty() && !pvqaConfig.empty()) + MT::SevanaPVQA::initializeLibrary(pvqaLicense, pvqaConfig); +#endif + +#if !defined(TARGET_ANDROID) && defined(USE_AQUA_LIBRARY) + std::string aquaLicense = d["aqua-license"].asString(); + if (!aquaLicense.empty()) + MT::SevanaAqua::initializeLibrary(aquaLicense); +#endif + + std::string transport = d["transport"].asString(); + config()[CONFIG_TRANSPORT] = (transport == "any") ? 0 : (transport == "udp" ? 1 : (transport == "tcp" ? 2 : 3)); + config()[CONFIG_IPV4] = d["ipv4"].asBool(); + config()[CONFIG_IPV6] = d["ipv6"].asBool(); + + // Log file + std::string logfile = d["logfile"].asString(); + ice::Logger& logger = ice::GLogger; + + logger.useFile(logfile.empty() ? nullptr : logfile.c_str()); + + config()[CONFIG_MULTIPLEXING] = true; + config()[CONFIG_DISPLAYNAME] = "Voip quality tester"; + + mUseNativeAudio = d["nativeaudio"].asBool(); + config()[CONFIG_OWN_DNS] = d["dns_servers"].asString(); + answer["status"] = Status_Ok; +} + +void AgentImpl::processStart(Json::Value &request, Json::Value &answer) +{ + std::unique_lock l(mAgentMutex); + if (mThread) + { + answer["status"] = Status_Ok; + return; // Started already + } + + // Start socket thread + SocketHeap::instance().start(); + + // Initialize terminal + MT::CodecList::Settings settings; + mTerminal = std::make_shared(settings); + + // Enable/disable codecs + PVariantMap priorityConfig = std::make_shared(); + MT::CodecList& cl = mTerminal->codeclist(); + for (int i=0; iat(i) = i; + else + priorityConfig->at(i) = -1; + + config()[CONFIG_CODEC_PRIORITY] = priorityConfig; + + // Enable audio + mAudioManager = std::make_shared(); + mAudioManager->setTerminal(mTerminal.get()); + + // Do not start here. Start right before call. + + // Initialize endpoint + start(); + + // Start worker thread + mShutdown = false; + mThread = std::make_shared(&AgentImpl::run, this); + answer["status"] = Status_Ok; +} + +void AgentImpl::processStop(Json::Value& request, Json::Value& answer) +{ + stopAgentAndThread(); + answer["status"] = Status_Ok; +} + +void AgentImpl::processCreateAccount(Json::Value &d, Json::Value& answer) +{ + std::unique_lock l(mAgentMutex); + PVariantMap c = std::make_shared(); + + (*c)[CONFIG_USERNAME] = d["username"].asString(); + (*c)[CONFIG_PASSWORD] = d["password"].asString(); + (*c)[CONFIG_DOMAIN] = d["domain"].asString(); + (*c)[CONFIG_EXTERNALIP] = d["use_external_ip"].asBool(); + + auto nameAndPort = StringHelper::parseHost(d["stun_server"].asString(), 3478); + (*c)[CONFIG_STUNSERVER_NAME] = nameAndPort.first; + (*c)[CONFIG_STUNSERVER_PORT] = nameAndPort.second; + + PAccount account = createAccount(c); + mAccountMap[account->id()] = account; + answer["account_id"] = account->id(); + answer["status"] = Status_Ok; +} + +void AgentImpl::processStartAccount(Json::Value& request, Json::Value& answer) +{ + std::unique_lock l(mAgentMutex); + // Locate account in map + auto accountIter = mAccountMap.find(request["account_id"].asInt()); + if (accountIter != mAccountMap.end()) + { + accountIter->second->start(); + answer["status"] = Status_Ok; + } + else + answer["status"] = Status_AccountNotFound; +} + +void AgentImpl::processSetUserInfoToAccount(Json::Value &request, Json::Value &answer) +{ + std::unique_lock l(mAgentMutex); + // Locate account in map + auto accountIter = mAccountMap.find(request["account_id"].asInt()); + if (accountIter != mAccountMap.end()) + { + Account::UserInfo info; + Json::Value& arg = request["userinfo"]; + std::vector keys = arg.getMemberNames(); + for (const std::string& k: keys) + info[k] = arg[k].asString(); + accountIter->second->setUserInfo(info); + + answer["status"] = Status_Ok; + } + else + answer["status"] = Status_AccountNotFound; +} + +void AgentImpl::processCreateSession(Json::Value &request, Json::Value &answer) +{ + std::unique_lock l(mAgentMutex); + auto accountIter = mAccountMap.find(request["account_id"].asInt()); + if (accountIter != mAccountMap.end()) + { + PSession session = createSession(accountIter->second); + mSessionMap[session->id()] = session; + answer["session_id"] = session->id(); + answer["status"] = Status_Ok; + } + else + answer["status"] = Status_AccountNotFound; +} + +void AgentImpl::processStartSession(Json::Value& request, Json::Value& answer) +{ + std::unique_lock l(mAgentMutex); + + // For debugging only + /*mIncomingAudioDump = std::make_shared(); + mIncomingAudioDump->open("incoming_dump", AUDIO_SAMPLERATE, AUDIO_CHANNELS); + mOutgoingAudioDump = std::make_shared(); + mOutgoingAudioDump->open("outgoing_dump", AUDIO_SAMPLERATE, AUDIO_CHANNELS);*/ + + // Start audio manager + if (!mAudioManager) + { + // Agent was not started + ICELogCritical(<< "No audio manager installed."); + answer["status"] = "Audio manager not started. Most probably agent is not started."; + return; + } + + mAudioManager->start(mUseNativeAudio ? AudioManager::atReceiver : AudioManager::atNull); + + auto sessionIter = mSessionMap.find(request["session_id"].asInt()); + if (sessionIter != mSessionMap.end()) + { + // Ensure audio provider is here + PSession session = sessionIter->second; + PDataProvider audioProvider = std::make_shared(*this, *mTerminal); + audioProvider->setState(audioProvider->state() | (int)StreamState::Grabbing | (int)StreamState::Playing); + +#if defined(USE_AQUA_LIBRARY) + std::string temp_path = request["aqua_temp_path"].asString(); + std::string config = "-avlp on -smtnrm on -decor off -mprio off -npnt auto -voip off -enorm off -g711 on -spfrcor off -grad off -tmc on -miter 1 -trim a 10"; + if (temp_path.size()) + config += " -fau " + temp_path; + + MT::PSevanaAqua qc = std::make_shared(); + qc->setTempPath(temp_path); + qc->configureWith(MT::SevanaAqua::parseConfig(config)); + + mAquaMap[sessionIter->first] = qc; + dynamic_cast(audioProvider.get())->configureMediaObserver(this, (void*)qc.get()); +#endif + + // TODO: support SRTP via StreamState::Srtp option in audio provider state + + // Get user headers + Session::UserHeaders info; + Json::Value& arg = request["userinfo"]; + std::vector keys = arg.getMemberNames(); + for (const std::string& k: keys) + info[k] = arg[k].asString(); + session->setUserHeaders(info); + + session->addProvider(audioProvider); + session->start(request["target"].asString()); + answer["status"] = Status_Ok; + } + else + { + answer["status"] = Status_SessionNotFound; + } +} + +void AgentImpl::processStopSession(Json::Value& request, Json::Value& answer) +{ + std::unique_lock l(mAgentMutex); + + auto sessionIter = mSessionMap.find(request["session_id"].asInt()); + if (sessionIter != mSessionMap.end()) + { + PSession session = sessionIter->second; + session->stop(); + answer["status"] = Status_Ok; + } + else + answer["status"] = Status_SessionNotFound; +} + +void AgentImpl::processAcceptSession(Json::Value& request, Json::Value& answer) +{ + std::unique_lock l(mAgentMutex); + auto sessionIter = mSessionMap.find(request["session_id"].asInt()); + if (sessionIter != mSessionMap.end()) + { + // Ensure audio manager is here + mAudioManager->start(mUseNativeAudio ? AudioManager::atReceiver : AudioManager::atNull); + + // Accept session on SIP level + PSession session = sessionIter->second; + + // Get user headers + Session::UserHeaders info; + Json::Value& arg = request["userinfo"]; + std::vector keys = arg.getMemberNames(); + for (const std::string& k: keys) + info[k] = arg[k].asString(); + session->setUserHeaders(info); + + // Accept finally + session->accept(); + + answer["status"] = Status_Ok; + } + else + answer["status"] = Status_SessionNotFound; + +} + +void AgentImpl::processDestroySession(Json::Value& request, Json::Value& answer) +{ + std::unique_lock l(mAgentMutex); + + int sessionId = request["session_id"].asInt(); + auto sessionIter = mSessionMap.find(sessionId); + if (sessionIter != mSessionMap.end()) + mSessionMap.erase(sessionIter); +#if defined(USE_AQUA_LIBRARY) + auto aquaIter = mAquaMap.find(sessionId); + if (aquaIter != mAquaMap.end()) + mAquaMap.erase(aquaIter); +#endif + answer["status"] = Status_Ok; +} + +void AgentImpl::processWaitForEvent(Json::Value &request, Json::Value &answer) +{ + std::unique_lock l(mAgentMutex); + + //int x = 0; + //int y = 1/x; + + int timeout = request["timeout"].asInt(); + std::unique_lock eventLock(mEventListMutex); + if (mEventList.empty()) + mEventListChangeCondVar.wait_for(eventLock, chrono::milliseconds(timeout)); + + if (!mEventList.empty()) + { + answer = mEventList.front(); + mEventList.erase(mEventList.begin()); + } + answer["status"] = Status_Ok; +} + +#if defined(USE_PVQA_LIBRARY) +static Json::Value CsvReportToJson(const std::string& report) +{ + Json::Value detectorValues; + std::istringstream iss(report); + CsvReader reader(iss); + std::vector cells; + if (reader.readLine(cells)) + { + Json::Value detectorNames; + for (int nameIndex = 0; nameIndex < (int)cells.size(); nameIndex++) + detectorNames[nameIndex] = StringHelper::trim(cells[nameIndex]); + // Put first line name of columns + detectorValues[0] = detectorNames; + + int rowIndex = 1; + while (reader.readLine(cells)) + { + // Skip last column for now + Json::Value row; + for (int valueIndex = 0; valueIndex < (int)cells.size(); valueIndex++) + { + bool isFloat = true; + float v = StringHelper::toFloat(cells[valueIndex], 0.0, &isFloat); + if (isFloat) + row[valueIndex] = v; + else + row[valueIndex] = cells[valueIndex]; + } + detectorValues[rowIndex++] = row; + } + } + return detectorValues; +} +#endif + +void AgentImpl::processGetMediaStats(Json::Value& request, Json::Value& answer) +{ + std::unique_lock l(mAgentMutex); + int sessionId = request["session_id"].asInt(); + SessionMap::iterator sessionIter = mSessionMap.find(sessionId); + if (sessionIter != mSessionMap.end()) + { + PSession session = sessionIter->second; + VariantMap result; + bool includePvqa = request["include_pvqa"].asBool(); +#if defined(USE_AQUA_LIBRARY) + bool includeAqua = request["include_aqua"].asBool(); + std::string aquaReference = request["aqua_reference_audio"].asString(); +#endif + session->getSessionInfo(includePvqa ? Session::InfoOptions::Detailed : Session::InfoOptions::Standard, + result); + + if (result.exists(SessionInfo_AudioCodec)) + answer["codec"] = result[SessionInfo_AudioCodec].asStdString(); + if (result.exists(SessionInfo_NetworkMos)) + answer["network_mos"] = result[SessionInfo_NetworkMos].asFloat(); +#if defined(USE_PVQA_LIBRARY) + if (result.exists(SessionInfo_PvqaMos)) + answer["pvqa_mos"] = result[SessionInfo_PvqaMos].asFloat(); + if (result.exists(SessionInfo_PvqaReport)) + answer["pvqa_report"] = CsvReportToJson(result[SessionInfo_PvqaReport].asStdString()); +#endif + if (result.exists(SessionInfo_PacketLoss)) + answer["rtp_lost"] = result[SessionInfo_LostRtp].asInt(); + if (result.exists(SessionInfo_SentRtp)) + answer["rtp_sent"] = result[SessionInfo_SentRtp].asInt(); + if (result.exists(SessionInfo_ReceivedRtp)) + answer["rtp_received"] = result[SessionInfo_ReceivedRtp].asInt(); + if (result.exists(SessionInfo_Duration)) + answer["duration"] = result[SessionInfo_Duration].asInt(); + if (result.exists(SessionInfo_Jitter)) + answer["jitter"] = result[SessionInfo_Jitter].asFloat() * 1000; // Take milliseconds + if (result.exists(SessionInfo_Rtt)) + answer["rtt"] = result[SessionInfo_Rtt].asFloat(); + if (result.exists(SessionInfo_BitrateSwitchCounter)) + answer["bitrate_switch_counter"] = result[SessionInfo_BitrateSwitchCounter].asInt(); + if (result.exists(SessionInfo_SSRC)) + answer["rtp_ssrc"] = result[SessionInfo_SSRC].asInt(); + if (result.exists(SessionInfo_RemotePeer)) + answer["rtp_remotepeer"] = result[SessionInfo_RemotePeer].asStdString(); + +#if defined(USE_AQUA_LIBRARY) + if (includeAqua) + { + ByteBuffer referenceAudio; + // Read AQuA reference audio from file if available + if (!aquaReference.empty()) + { + Audio::WavFileReader reader; + reader.open(aquaReference); + if (reader.isOpened()) + { + char buffer[1024]; + int wasRead = 0; + do + { + wasRead = reader.read(buffer, 1024); + if (wasRead > 0) + referenceAudio.appendBuffer(buffer, wasRead); + } + while (wasRead == 1024); + } + } + MT::PSevanaAqua sa = mAquaMap[sessionIter->first]; + MT::SevanaAqua::AudioBuffer test, reference; + test.mRate = AUDIO_SAMPLERATE; reference.mRate = AUDIO_SAMPLERATE; + test.mChannels = AUDIO_CHANNELS; reference.mChannels = AUDIO_CHANNELS; + test.mData = mAquaIncoming.mutableData(); reference.mData = referenceAudio.mutableData(); + test.mSize = mAquaIncoming.size(); reference.mSize = referenceAudio.size(); + + MT::SevanaAqua::CompareResult r = sa->compare(reference, test); + answer["aqua_mos"] = r.mMos; + + if (r.mFaults) + { + Json::Value json(r.mReport); + Json::Value faults = r.mFaults->toJson(); + json["faults"] = faults; + answer["aqua_report"] = json.toStyledString(); + } + else + answer["aqua_report"] = r.mReport; + } +#endif + + answer["status"] = Status_Ok; + } + else + answer["status"] = Status_SessionNotFound; +} + +void AgentImpl::processNetworkChanged(Json::Value& request, Json::Value& answer) +{ + std::unique_lock l(mAgentMutex); +} + +const std::string BeginCertificate = "-----BEGIN CERTIFICATE-----"; +const std::string EndCertificate = "-----END CERTIFICATE-----"; + +void AgentImpl::processAddRootCert(Json::Value& request, Json::Value& answer) +{ + std::unique_lock l(mAgentMutex); + std::string pem = request["cert"].asString(); + + std::string::size_type pb = 0, pe = 0; + + for(pb = pem.find(BeginCertificate, pb), pe = pem.find(EndCertificate, pe); + pb != std::string::npos && pe != std::string::npos; + pb = pem.find(BeginCertificate, pb + BeginCertificate.size()), pe = pem.find(EndCertificate, pe + EndCertificate.size())) + { + // Get single certificate + std::string cert = pem.substr(pb, pe + EndCertificate.size()); + int size = cert.size(); + addRootCert(ByteBuffer(cert.c_str(), cert.size())); + + // Delete processed part + pem.erase(0, pe + EndCertificate.size()); + } + + answer["status"] = Status_Ok; +} + +void AgentImpl::processLogMessage(Json::Value &request, Json::Value &answer) +{ + int level = request["level"].asInt(); + std::string message = request["message"].asString(); + + ICELog((ice::LogLevel)level, "App", << message); + + answer["status"] = Status_Ok; +} + +void AgentImpl::stopAgentAndThread() +{ + // Stop user agent + std::unique_lock l(mAgentMutex); + try + { + stop(); + } + catch (...) + {} + + // Stop worker thread + if (mThread) + { + mShutdown = true; + if (mThread->joinable()) + { + l.unlock(); + mThread->join(); + l.lock(); + } + mThread.reset(); + } + + // Close used audio + if (mAudioManager) + { + // Ensure audio manager is stopped + mAudioManager->stop(mUseNativeAudio ? AudioManager::atReceiver : AudioManager::atNull); + + // Free audio manager + mAudioManager.reset(); + } + + // Close terminal after audio manager - because audio manager has reference to terminal + mTerminal.reset(); + + SocketHeap::instance().stop(); +} + +void AgentImpl::processUseStreamForSession(Json::Value& request, Json::Value& answer) +{ + std::unique_lock l(mAgentMutex); + SessionMap::iterator sessionIter = mSessionMap.find(request["session_id"].asInt()); + if (sessionIter != mSessionMap.end()) + { + // Extract ptr to session + PSession session = sessionIter->second; + + // Parse command + std::string actionText = request["media_action"].asString(), + directionText = request["media_direction"].asString(); + + MT::Stream::MediaDirection direction = directionText == "incoming" ? MT::Stream::MediaDirection::Incoming + : MT::Stream::MediaDirection::Outgoing; + std::string path = request["path"].asString(); + + // Try to open file + AudioProvider* prov = session->findProviderForActiveAudio(); + if (prov) + { + if (actionText == "read") + { + if (path.empty()) + { + // Turn off playing into the stream + prov->readFile(Audio::PWavFileReader(), direction); + answer["status"] = Status_Ok; + } + else + { + Audio::PWavFileReader reader = std::make_shared(); + if (!reader->open(StringHelper::makeTstring(path))) + answer["status"] = Status_FailedToOpenFile; + else + { + prov->readFile(reader, direction); + answer["status"] = Status_Ok; + } + } + } + else + if (actionText == "write") + { + if (path.empty()) + { + // Turn off recording from the stream + prov->writeFile(Audio::PWavFileWriter(), direction); + answer["status"] = Status_Ok; + } + else + { + Audio::PWavFileWriter writer = std::make_shared(); + if (!writer->open(StringHelper::makeTstring(path), AUDIO_SAMPLERATE, AUDIO_CHANNELS)) + answer["status"] = Status_FailedToOpenFile; + else + { + prov->writeFile(writer, direction); + answer["status"] = Status_Ok; + } + } + } + else + if (actionText == "mirror") + { + prov->setupMirror(request["enable"].asBool()); + answer["status"] = Status_Ok; + } + else + answer["status"] = Status_AccountNotFound; + } + else + answer["status"] = Status_NoMediaAction; + } +} + +#if defined(USE_AQUA_LIBRARY) +void AgentImpl::onMedia(const void* data, int length, MT::Stream::MediaDirection direction, void* context, void* userTag) +{ +/* if (mIncomingAudioDump && direction == MT::Stream::MediaDirection::Incoming) + mIncomingAudioDump->write(data, length); + + if (mOutgoingAudioDump && direction == MT::Stream::MediaDirection::Outgoing) + mOutgoingAudioDump->write(data, length);*/ + + // User tag points to accumulator object which includes + MT::SevanaAqua* sa = reinterpret_cast(userTag); + + switch (direction) + { + case MT::Stream::MediaDirection::Incoming: mAquaIncoming.appendBuffer(data, length); break; + case MT::Stream::MediaDirection::Outgoing: mAquaOutgoing.appendBuffer(data, length); break; + } +} +#endif + + +// Called on new incoming session; providers shoukld +#define EVENT_WITH_NAME(X) Json::Value v; v["event_name"] = X; + +PDataProvider AgentImpl::onProviderNeeded(const std::string& name) +{ + EVENT_WITH_NAME("provider_needed"); + v["provider_name"] = name; + addEvent(v); + + return PDataProvider(new AudioProvider(*this, *mTerminal)); +} + +// Called on new session offer +void AgentImpl::onNewSession(PSession s) +{ + EVENT_WITH_NAME("session_incoming"); + v["session_id"] = s->id(); + v["remote_peer"] = s->remoteAddress(); + mSessionMap[s->id()] = s; + + addEvent(v); +} + +// Called when session is terminated +void AgentImpl::onSessionTerminated(PSession s, int responsecode, int reason) +{ + /*if (mIncomingAudioDump) + mIncomingAudioDump->close(); + if (mOutgoingAudioDump) + mOutgoingAudioDump->close(); + */ + mAudioManager->stop(mUseNativeAudio ? AudioManager::atReceiver : AudioManager::atNull); + // Gather statistics before + EVENT_WITH_NAME("session_terminated"); + v["session_id"] = s->id(); + v["error_code"] = responsecode; + v["reason_code"] = reason; + addEvent(v); +} + +// Called when session is established ok i.e. after all ICE signalling is finished +// Conntype is type of establish event - EV_SIP or EV_ICE +void AgentImpl::onSessionEstablished(PSession s, int conntype, const RtpPair& p) +{ + EVENT_WITH_NAME("session_established"); + v["session_id"] = s->id(); + v["conn_type"] = conntype == EV_SIP ? "sip" : "ice"; + if (conntype == EV_ICE) + v["media_target"] = p.mRtp.toStdString(); + + addEvent(v); +} + +void AgentImpl::onSessionProvisional(PSession s, int code) +{ + EVENT_WITH_NAME("session_provisional"); + v["session_id"] = s->id(); + v["code"] = code; + addEvent(v); +} + +// Called when user agent started +void AgentImpl::onStart(int errorcode) +{ + EVENT_WITH_NAME("agent_started"); + v["error_code"] = errorcode; + addEvent(v); +} + +// Called when user agent stopped +void AgentImpl::onStop() +{ + EVENT_WITH_NAME("agent_stopped"); + addEvent(v); +} + +// Called when account registered +void AgentImpl::onAccountStart(PAccount account) +{ + EVENT_WITH_NAME("account_started"); + v["account_id"] = account->id(); + addEvent(v); +} + +// Called when account removed or failed (non zero error code) +void AgentImpl::onAccountStop(PAccount account, int error) +{ + EVENT_WITH_NAME("account_stopped"); + v["account_id"] = account->id(); + v["error_code"] = error; + addEvent(v); +} + +// Called when connectivity checks failed. +void AgentImpl::onConnectivityFailed(PSession s) +{ + EVENT_WITH_NAME("session_connectivity_failed"); + v["session_id"] = s->id(); + addEvent(v); +} + +// Called when new candidate is gathered +void AgentImpl::onCandidateGathered(PSession s, const char* address) +{ + EVENT_WITH_NAME("session_candidate_gathered"); + v["session_id"] = s->id(); + v["address"] = address; + addEvent(v); +} + +// Called when network change detected +void AgentImpl::onNetworkChange(PSession s) +{ + EVENT_WITH_NAME("session_network_changed"); + v["session_id"] = s->id(); + addEvent(v); +} + +// Called when all candidates are gathered +void AgentImpl::onGathered(PSession s) +{ + EVENT_WITH_NAME("session_candidates_gathered"); + v["session_id"] = s->id(); + addEvent(v); +} + +// Called when new connectivity check is finished +void AgentImpl::onCheckFinished(PSession s, const char* description) +{ + EVENT_WITH_NAME("session_conncheck_finished"); + v["session_id"] = s->id(); + v["description"] = description; + addEvent(v); +} + +// Called when log message must be recorded +void AgentImpl::onLog(const char* msg) +{} + +// Called when problem with SIP connection(s) detected +void AgentImpl::onSipConnectionFailed() +{ + EVENT_WITH_NAME("sip_connection_failed"); + addEvent(v); +} + +void AgentImpl::addEvent(const Json::Value& v) +{ + std::unique_lock lock(mEventListMutex); + mEventList.push_back(v); + mEventListChangeCondVar.notify_one(); +} + diff --git a/src/engine/agent/Agent_Impl.h b/src/engine/agent/Agent_Impl.h new file mode 100644 index 00000000..c4fbf8cf --- /dev/null +++ b/src/engine/agent/Agent_Impl.h @@ -0,0 +1,132 @@ +#ifndef __AGENT_IMPL_H +#define __AGENT_IMPL_H + +#include +#include +#include +#include "../endpoint/EP_Engine.h" +#include "../endpoint/EP_AudioProvider.h" +#include "../media/MT_Box.h" +#include "../helper/HL_ByteBuffer.h" + +#include "json/json.h" +#include "Agent_AudioManager.h" +#include +#include + +class AgentImpl: public UserAgent +#if defined(USE_AQUA_LIBRARY) + , public MT::Stream::MediaObserver +#endif +{ +protected: + std::recursive_mutex mAgentMutex; + std::mutex mEventListMutex; + std::condition_variable mEventListChangeCondVar; + std::vector mEventList; + bool mUseNativeAudio = false; + + typedef std::map AccountMap; + AccountMap mAccountMap; + + typedef std::map SessionMap; + SessionMap mSessionMap; + +#if defined(USE_AQUA_LIBRARY) + // Keys are the same as used in mSessionMap + typedef std::map AquaMap; + AquaMap mAquaMap; + ByteBuffer mAquaIncoming, mAquaOutgoing; +#endif + + std::shared_ptr mThread; + volatile bool mShutdown; + std::shared_ptr mTerminal; + std::shared_ptr mAudioManager; + //Audio::PWavFileWriter mIncomingAudioDump, mOutgoingAudioDump; + + void run(); + void addEvent(const Json::Value& v); + void processConfig(Json::Value& request, Json::Value& answer); + void processStart(Json::Value& request, Json::Value& answer); + void processStop(Json::Value& request, Json::Value& answer); + void processCreateAccount(Json::Value& request, Json::Value& answer); + void processStartAccount(Json::Value& request, Json::Value& answer); + void processSetUserInfoToAccount(Json::Value& request, Json::Value& answer); + void processCreateSession(Json::Value& request, Json::Value& answer); + void processStartSession(Json::Value& request, Json::Value& answer); + void processStopSession(Json::Value& request, Json::Value& answer); + void processAcceptSession(Json::Value& request, Json::Value& answer); + void processDestroySession(Json::Value& request, Json::Value& answer); + void processWaitForEvent(Json::Value& request, Json::Value& answer); + void processGetMediaStats(Json::Value& request, Json::Value& answer); + void processUseStreamForSession(Json::Value& request, Json::Value& answer); + void processNetworkChanged(Json::Value& request, Json::Value& answer); + void processAddRootCert(Json::Value& request, Json::Value& answer); + void processLogMessage(Json::Value& request, Json::Value& answer); + void stopAgentAndThread(); + +public: + AgentImpl(); + ~AgentImpl(); + + std::string command(const std::string& command); + bool waitForData(int milliseconds); + std::string read(); + + // UserAgent overrides + // Called on new incoming session; providers shoukld + PDataProvider onProviderNeeded(const std::string& name) override; + + // Called on new session offer + void onNewSession(PSession s) override; + + // Called when session is terminated + void onSessionTerminated(PSession s, int responsecode, int reason) override; + + // Called when session is established ok i.e. after all ICE signalling is finished + // Conntype is type of establish event - EV_SIP or EV_ICE + void onSessionEstablished(PSession s, int conntype, const RtpPair& p) override; + + void onSessionProvisional(PSession s, int code) override; + + // Called when user agent started + void onStart(int errorcode) override; + + // Called when user agent stopped + void onStop() override; + + // Called when account registered + void onAccountStart(PAccount account) override; + + // Called when account removed or failed (non zero error code) + void onAccountStop(PAccount account, int error) override; + + // Called when connectivity checks failed. + void onConnectivityFailed(PSession s) override; + + // Called when new candidate is gathered + void onCandidateGathered(PSession s, const char* address) override; + + // Called when network change detected + void onNetworkChange(PSession s) override; + + // Called when all candidates are gathered + void onGathered(PSession s) override; + + // Called when new connectivity check is finished + void onCheckFinished(PSession s, const char* description) override; + + // Called when log message must be recorded + void onLog(const char* msg) override; + + // Called when problem with SIP connection(s) detected + void onSipConnectionFailed() override; + +#if defined(USE_AQUA_LIBRARY) + // Called on incoming & outgoing audio for voice sessions + void onMedia(const void* data, int length, MT::Stream::MediaDirection direction, void* context, void* userTag) override; +#endif +}; + +#endif diff --git a/src/engine/agent/Agent_Interface.cpp b/src/engine/agent/Agent_Interface.cpp new file mode 100644 index 00000000..18e5bc57 --- /dev/null +++ b/src/engine/agent/Agent_Interface.cpp @@ -0,0 +1,27 @@ +#include "Agent_Interface.h" +#include "Agent_Impl.h" +Agent::Agent() + :mContext(new AgentImpl()); +{ + +} + +Agent::~Agent() +{ + +} + +void Agent::write(const std::string& command) +{ + +} + +bool Agent::waitForData(int milliseconds) +{ + return false; +} + +std::string Agent::read() +{ + +} diff --git a/src/engine/agent/Agent_Interface.h b/src/engine/agent/Agent_Interface.h new file mode 100644 index 00000000..1790de70 --- /dev/null +++ b/src/engine/agent/Agent_Interface.h @@ -0,0 +1,19 @@ +#ifndef __AGENT_JSON_H +#define __AGENT_JSON_H + +#include + +class Agent +{ +protected: + void* mContext; + +public: + Agent(); + ~Agent(); + void write(const std::string& command); + bool waitForData(int milliseconds); + std::string read(); +}; + +#endif diff --git a/src/engine/audio/Audio_Android.cpp b/src/engine/audio/Audio_Android.cpp new file mode 100644 index 00000000..ab2fa806 --- /dev/null +++ b/src/engine/audio/Audio_Android.cpp @@ -0,0 +1,583 @@ +#include "Audio_Android.h" +#include "../helper/HL_Sync.h" +#include "../helper/HL_Log.h" +#include +#include +#include "../helper/HL_String.h" + +#ifdef TARGET_ANDROID + +#define LOG_SUBSYSTEM "Audio" + +using namespace Audio; + + +// -------------------- AndroidEnumerator ----------------------------- + +AndroidEnumerator::AndroidEnumerator() +{} + +AndroidEnumerator::~AndroidEnumerator() +{} + +int AndroidEnumerator::indexOfDefaultDevice() +{ + return 0; +} + +int AndroidEnumerator::count() +{ + return 1; +} + +int AndroidEnumerator::idAt(int index) +{ + return 0; +} + +std::string AndroidEnumerator::nameAt(int index) +{ + return "Audio"; +} + +void AndroidEnumerator::open(int direction) +{} + +void AndroidEnumerator::close() +{} + +// ----------------------- + +OpenSLEngine::OpenSLEngine() +{} + +OpenSLEngine::~OpenSLEngine() +{} + +void OpenSLEngine::open() +{ + std::unique_lock l(mMutex); + if (++mUsageCounter == 1) + internalOpen(); + +} + +void OpenSLEngine::close() +{ + std::unique_lock l(mMutex); + if (--mUsageCounter == 0) + internalClose(); +} + +#define CHECK_OPENSLES_ERROR if (resultCode != SL_RESULT_SUCCESS) throw Exception(ERR_OPENSLES, (int)resultCode) + +void OpenSLEngine::internalOpen() +{ + SLresult resultCode; + + // Instantiate OpenSL ES engine object + resultCode = slCreateEngine(&mEngineObject, 0, nullptr, 0, nullptr, nullptr); + CHECK_OPENSLES_ERROR; + + // Bring it online (realize) + resultCode = (*mEngineObject)->Realize(mEngineObject, SL_BOOLEAN_FALSE); + CHECK_OPENSLES_ERROR; + + // Get interface finally + resultCode = (*mEngineObject)->GetInterface(mEngineObject, SL_IID_ENGINE, &mEngineInterface); + CHECK_OPENSLES_ERROR; + + ICELogInfo(<< "OpenSL engine object created."); +} + +void OpenSLEngine::internalClose() +{ + if (mEngineObject != nullptr) + { + ICELogInfo(<< "Destroy OpenSL engine object."); + + (*mEngineObject)->Destroy(mEngineObject); + mEngineObject = nullptr; + mEngineInterface = nullptr; + } +} + +SLEngineItf OpenSLEngine::getNativeEngine() const +{ + return mEngineInterface; +} + +static OpenSLEngine OpenSLEngineInstance; + +OpenSLEngine& OpenSLEngine::instance() +{ + return OpenSLEngineInstance; +} + +// --------------- Input implementation ---------------- +AndroidInputDevice::AndroidInputDevice(int devId) +{} + +AndroidInputDevice::~AndroidInputDevice() +{} + +static int RateToProbe[12][2] = { + { SL_SAMPLINGRATE_16, 16000 }, + { SL_SAMPLINGRATE_8, 8000 }, + { SL_SAMPLINGRATE_32, 32000 }, + { SL_SAMPLINGRATE_44_1, 44100 }, + { SL_SAMPLINGRATE_11_025, 10025 }, + { SL_SAMPLINGRATE_22_05, 22050 }, + { SL_SAMPLINGRATE_24, 24000 }, + { SL_SAMPLINGRATE_48, 48000 }, + { SL_SAMPLINGRATE_64, 64000 }, + { SL_SAMPLINGRATE_88_2, 88200 }, + { SL_SAMPLINGRATE_96, 96000 }, + { SL_SAMPLINGRATE_192, 192000} }; + +bool AndroidInputDevice::open() +{ + if (active()) + return true; + + OpenSLEngine::instance().open(); + + // Probe few sampling rates + bool opened = false; + for (int rateIndex = 0; rateIndex < 12 && !opened; rateIndex++) + { + try + { + internalOpen(RateToProbe[rateIndex][0], RateToProbe[rateIndex][1]); + mDeviceRate = RateToProbe[rateIndex][1]; + ICELogInfo(<< "Input Opened with rate " << mDeviceRate << " and rate index " << rateIndex); + opened = mDeviceRate != 0; + if (!opened) + internalClose(); + } + catch(...) + { + opened = false; + internalClose(); + } + } + mActive = opened; + + return opened; +} + +void AndroidInputDevice::close() +{ + // There is no check for active() value because close() can be called to cleanup after bad open() call. + internalClose(); + OpenSLEngine::instance().close(); + mActive = false; +} + +Format AndroidInputDevice::getFormat() +{ + return Format(mDeviceRate, 1); +} + +bool AndroidInputDevice::active() const +{ + return mActive; +} + +bool AndroidInputDevice::fakeMode() +{ + return false; +} + +void AndroidInputDevice::setFakeMode(bool fakemode) +{} + +int AndroidInputDevice::readBuffer(void* buffer) +{ + std::unique_lock l(mMutex); + while (mSdkRateCache.filled() < AUDIO_MIC_BUFFER_SIZE) + { + mDataCondVar.wait(l); + } + + return mSdkRateCache.read(buffer, AUDIO_MIC_BUFFER_SIZE); +} + +void AndroidInputDevice::internalOpen(int rateCode, int rate) +{ + SLresult resultCode = 0; + SLuint32 nrOfChannels = 1; + + // Prepare audio source + SLDataLocator_IODevice devDescription = { SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, NULL}; + SLDataSource audioSource = { &devDescription, NULL }; + + // Source flags + SLuint32 speakersFlags = nrOfChannels > 1 ? (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT) : SL_SPEAKER_FRONT_CENTER; + + // Buffer queue + SLDataLocator_AndroidSimpleBufferQueue queueDescription = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 }; + + // Audio format + SLDataFormat_PCM formatDescription = { SL_DATAFORMAT_PCM, nrOfChannels, (SLuint32)rateCode, SL_PCMSAMPLEFORMAT_FIXED_16, + SL_PCMSAMPLEFORMAT_FIXED_16, (SLuint32)speakersFlags, SL_BYTEORDER_LITTLEENDIAN }; + + SLDataSink audioSink = { &queueDescription, &formatDescription }; + + // Create recorder + // Do not forget about RECORD_AUDIO permission + const SLInterfaceID interfacesList[2] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION }; + const SLboolean interfacesRequirements[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE }; + if (*OpenSLEngine::instance().getNativeEngine() == nullptr) + throw Exception(ERR_OPENSLES, -1); + + resultCode = (*OpenSLEngine::instance().getNativeEngine())->CreateAudioRecorder( + OpenSLEngine::instance().getNativeEngine(), + &mRecorderObject, &audioSource, &audioSink, 2, interfacesList, interfacesRequirements); + CHECK_OPENSLES_ERROR; + + // Obtain stream type + resultCode = (*mRecorderObject)->GetInterface(mRecorderObject, SL_IID_ANDROIDCONFIGURATION, &mAndroidCfg); + CHECK_OPENSLES_ERROR; + + // Now audio recorder goes to real world + resultCode = (*mRecorderObject)->Realize(mRecorderObject, SL_BOOLEAN_FALSE); + CHECK_OPENSLES_ERROR; + + // Get recorder interface + resultCode = (*mRecorderObject)->GetInterface(mRecorderObject, SL_IID_RECORD, &mRecorderInterface); + CHECK_OPENSLES_ERROR; + + // Now buffer queue interface... + resultCode = (*mRecorderObject)->GetInterface(mRecorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &mRecorderBufferInterface); + CHECK_OPENSLES_ERROR; + + // Resampler is needed to provide SDK's rate + mResampler = std::make_shared(); + mResampler->start(nrOfChannels, rate, AUDIO_SAMPLERATE); + + // Allocate recorder buffer size + mBufferSize = (AUDIO_MIC_BUFFER_LENGTH / 10) * (rate / 100) * 2; + mRecorderBuffer.setCapacity(mBufferSize * AUDIO_MIC_BUFFER_COUNT); + mRecorderBufferIndex = 0; + + // Setup data consuming callback + resultCode = (*mRecorderBufferInterface)->RegisterCallback(mRecorderBufferInterface, DeviceCallback, (void*)this); + CHECK_OPENSLES_ERROR; + + // Setup buffers + for (int i=0; iEnqueue(mRecorderBufferInterface, mRecorderBuffer.data() + i * mBufferSize, mBufferSize); + + // Start finally + resultCode = (*mRecorderInterface)->SetRecordState(mRecorderInterface, SL_RECORDSTATE_RECORDING); + CHECK_OPENSLES_ERROR; +} + +void AndroidInputDevice::internalClose() +{ + if (!mRecorderObject) + return; + + if (*mRecorderObject) + { + if (active()) + { + // Stop recording + (*mRecorderInterface)->SetRecordState(mRecorderInterface, SL_RECORDSTATE_STOPPED); + + // Wait until recording will not stop really + SLuint32 state = SL_RECORDSTATE_STOPPED; + do + { + (*mRecorderInterface)->GetRecordState(mRecorderInterface, &state); + SyncHelper::delay(1); + } + while (state == SL_RECORDSTATE_RECORDING); + } + (*mRecorderObject)->Destroy(mRecorderObject); + } + + mRecorderObject = nullptr; + mRecorderInterface = nullptr; + mRecorderBufferInterface = nullptr; + mAndroidCfg = nullptr; +} + +void AndroidInputDevice::handleCallback(SLAndroidSimpleBufferQueueItf bq) +{ + std::unique_lock l(mMutex); + + // Send data to AudioPair + if (mConnection) + mConnection->onMicData(getFormat(), mRecorderBuffer.data() + mRecorderBufferIndex * mBufferSize, mBufferSize); + /* + // Send audio to cache with native sample rate + mDeviceRateCache.add(mRecorderBuffer.data() + mRecorderBufferIndex * mBufferSize, mBufferSize); + + // Check if there is enough data (10 ms) to send + int tenMsSize = (int)Format(mDeviceRate, 1).sizeFromTime(10); + while (mDeviceRateCache.filled() >= tenMsSize) + { + char* resampled = (char*)alloca(Format().sizeFromTime(10)); + int processed = 0; + int outlen = mResampler->processBuffer(mDeviceRateCache.data(), tenMsSize, processed, resampled, Format().sizeFromTime(10)); + if (outlen > 0) + mSdkRateCache.add(resampled, (int)Format().sizeFromTime(10)); + mDeviceRateCache.erase(tenMsSize); + } + + // Tell about data + while (mSdkRateCache.filled() >= AUDIO_MIC_BUFFER_SIZE) + { + if (mConnection) + mConnection->onMicData(Format(), mSdkRateCache.data(), AUDIO_MIC_BUFFER_SIZE); + mSdkRateCache.erase(AUDIO_MIC_BUFFER_SIZE); + } + */ + // Re-enqueue used buffer + (*mRecorderBufferInterface)->Enqueue(mRecorderBufferInterface, mRecorderBuffer.data() + mRecorderBufferIndex * mBufferSize, mBufferSize); + mRecorderBufferIndex++; + mRecorderBufferIndex %= AUDIO_MIC_BUFFER_COUNT; +} + +void AndroidInputDevice::DeviceCallback(SLAndroidSimpleBufferQueueItf bq, void *context) +{ + try + { + if (context) + reinterpret_cast(context)->handleCallback(bq); + } + catch(...) + {} +} + +// ------------ AndroidOutputDevice ----------------- +AndroidOutputDevice::AndroidOutputDevice(int devId) +{ + ICELogDebug(<< "Creating AndroidOutputDevice. This is: " << StringHelper::toHex(this)); +} +AndroidOutputDevice::~AndroidOutputDevice() +{ + ICELogDebug(<< "Deleting AndroidOutputDevice."); + close(); +} + +bool AndroidOutputDevice::open() +{ + std::unique_lock l(mMutex); + bool opened = false; + for (int rateIndex = 0; rateIndex < 12 && !opened; rateIndex++) + { + try + { + internalOpen(RateToProbe[rateIndex][0], RateToProbe[rateIndex][1], true); + opened = true; + mDeviceRate = RateToProbe[rateIndex][1]; + ICELogCritical(<< "Output opened with rate " << mDeviceRate << " and index " << rateIndex); + } + catch(...) + { + opened = false; + } + } + if (opened) + ICELogInfo(<< "Speaker opened on rate " << mDeviceRate); + + return opened; +} + +void AndroidOutputDevice::close() +{ + std::unique_lock l(mMutex); + internalClose(); +} + +Format AndroidOutputDevice::getFormat() +{ + return Format(mDeviceRate, 1); +} + +bool AndroidOutputDevice::fakeMode() +{ + return false; +} + +void AndroidOutputDevice::setFakeMode(bool fakemode) +{ +} + +void AndroidOutputDevice::internalOpen(int rateId, int rate, bool voice) +{ + mInShutdown = false; + + SLresult resultCode; + SLuint32 channels = 1; + + // Configure audio source + SLDataLocator_AndroidSimpleBufferQueue queue_desc = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 }; + + const SLInterfaceID interfacesList[] = { SL_IID_VOLUME }; + const SLboolean interfaceRequirements[] = { SL_BOOLEAN_FALSE }; + resultCode = (*OpenSLEngine::instance().getNativeEngine())->CreateOutputMix( + OpenSLEngine::instance().getNativeEngine(), &mMixer, 1, interfacesList, + interfaceRequirements); + CHECK_OPENSLES_ERROR; + + // Bring mixer online + resultCode = (*mMixer)->Realize(mMixer, SL_BOOLEAN_FALSE); + CHECK_OPENSLES_ERROR; + + // Prepare mixer configuration + SLuint32 speakers = + channels > 1 ? (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT) : SL_SPEAKER_FRONT_CENTER; + + // Describe audio format + SLDataFormat_PCM pcm_format = {SL_DATAFORMAT_PCM, channels, (SLuint32) rateId, + SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, + speakers, SL_BYTEORDER_LITTLEENDIAN}; + + // Describe audio source - buffers + audio format + SLDataSource audio_source = { &queue_desc, &pcm_format }; + + // Describe audio sink + SLDataLocator_OutputMix mixer_desc = { SL_DATALOCATOR_OUTPUTMIX, mMixer }; + SLDataSink audio_sink = { &mixer_desc, NULL }; + + // Create player instance + const SLInterfaceID playerInterfaces[] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, + SL_IID_VOLUME, + SL_IID_ANDROIDCONFIGURATION }; + const SLboolean playerInterfacesReqs[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE }; + + resultCode = (*OpenSLEngine::instance().getNativeEngine())->CreateAudioPlayer( + OpenSLEngine::instance().getNativeEngine(), &mPlayer, + &audio_source, &audio_sink, 3, playerInterfaces, playerInterfacesReqs); + CHECK_OPENSLES_ERROR; + + // Get android config interface + resultCode = (*mPlayer)->GetInterface(mPlayer, SL_IID_ANDROIDCONFIGURATION, &mAndroidConfig); + + if (resultCode == SL_RESULT_SUCCESS) + { + SLint32 streamType = voice ? SL_ANDROID_STREAM_VOICE : SL_ANDROID_STREAM_MEDIA; + resultCode = (*mAndroidConfig)->SetConfiguration(mAndroidConfig, SL_ANDROID_KEY_STREAM_TYPE, + &streamType, sizeof(SLint32)); + if (resultCode != SL_RESULT_SUCCESS) + ICELogCritical(<< "Failed to set audio destination with error " << (unsigned)resultCode); + } + else + ICELogCritical(<< "Failed to obtain android cfg audio interface with error " << (unsigned)resultCode); + + // Bring player online + resultCode = (*mPlayer)->Realize(mPlayer, SL_BOOLEAN_FALSE); + CHECK_OPENSLES_ERROR; + + // Obtain player control + resultCode = (*mPlayer)->GetInterface(mPlayer, SL_IID_PLAY, &mPlayerControl); + CHECK_OPENSLES_ERROR; + + // Get the buffer queue interface + resultCode = (*mPlayer)->GetInterface(mPlayer, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, + &mBufferQueue); + CHECK_OPENSLES_ERROR; + + // Setup callback + resultCode = (*mBufferQueue)->RegisterCallback(mBufferQueue, DeviceCallback, this); + CHECK_OPENSLES_ERROR; + + // Enqueue buffers + mBufferSize = (int)Format(rate, channels).sizeFromTime(AUDIO_SPK_BUFFER_LENGTH); + mPlayBuffer.setCapacity(AUDIO_SPK_BUFFER_COUNT * mBufferSize); + + mBufferIndex = 0; + for (int i = 0; i < AUDIO_SPK_BUFFER_COUNT; i++) + (*mBufferQueue)->Enqueue(mBufferQueue, mPlayBuffer.data() + i * mBufferSize, + (SLuint32)mBufferSize); + + // Set the player's state to playing + resultCode = (*mPlayerControl)->SetPlayState(mPlayerControl, SL_PLAYSTATE_PLAYING); + CHECK_OPENSLES_ERROR; +} + +void AndroidOutputDevice::internalClose() +{ + if (mPlayer) + { + if (*mPlayer) + { + mInShutdown = true; + ICELogInfo(<< "Stop player"); + if (mPlayerControl) { + if (*mPlayerControl) { + SLuint32 state = SL_PLAYSTATE_PLAYING; + (*mPlayerControl)->SetPlayState(mPlayerControl, SL_PLAYSTATE_STOPPED); + + while (state != SL_PLAYSTATE_STOPPED) { + (*mPlayerControl)->GetPlayState(mPlayerControl, &state); + SyncHelper::delay(1); + } + } + } + + // Clear buffer queue + ICELogInfo(<< "Clear player buffer queue"); + (*mBufferQueue)->Clear(mBufferQueue); + + ICELogInfo(<< "Destroy player object"); + // Destroy player object + (*mPlayer)->Destroy(mPlayer); + + mPlayer = nullptr; + mPlayerControl = nullptr; + mBufferQueue = nullptr; + mEffect = nullptr; + mAndroidConfig = nullptr; + } + } + + if (mMixer) + { + if (*mMixer) + (*mMixer)->Destroy(mMixer); + mMixer = nullptr; + } +} + +void AndroidOutputDevice::handleCallback(SLAndroidSimpleBufferQueueItf bq) +{ + if (mInShutdown) + { + char silence[mBufferSize]; memset(silence, 0, mBufferSize); + (*mBufferQueue)->Enqueue(mBufferQueue, silence, mBufferSize); + return; + } + + // Ask producer about data + char* buffer = mPlayBuffer.mutableData() + mBufferIndex * mBufferSize; + if (mConnection) + { + Format f = getFormat(); + if (f.mRate != 0) + mConnection->onSpkData(f, buffer, mBufferSize); + } + (*mBufferQueue)->Enqueue(mBufferQueue, buffer, (SLuint32)mBufferSize); + + mBufferIndex++; + mBufferIndex %= AUDIO_SPK_BUFFER_COUNT; +} + +void AndroidOutputDevice::DeviceCallback(SLAndroidSimpleBufferQueueItf bq, void* context) +{ + if (!context) + return; + + try + { + reinterpret_cast(context)->handleCallback(bq); + } + catch(...) + {} +} + +#endif // TARGET_ANDROID \ No newline at end of file diff --git a/src/engine/audio/Audio_Android.h b/src/engine/audio/Audio_Android.h new file mode 100644 index 00000000..33f3af27 --- /dev/null +++ b/src/engine/audio/Audio_Android.h @@ -0,0 +1,147 @@ +/* Copyright(C) 2007-2017 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#ifndef __AUDIO_ANDROID_H +#define __AUDIO_ANDROID_H + +#ifdef TARGET_ANDROID + +#include "Audio_Interface.h" +#include "Audio_Helper.h" +#include "Audio_Resampler.h" +#include "Audio_DataWindow.h" +#include "../Helper/HL_Pointer.h" +#include "../Helper/HL_ByteBuffer.h" +#include "../Helper/HL_Exception.h" +#include +#include + +#include +#include +#include + +namespace Audio +{ + + class AndroidEnumerator: public Enumerator + { + public: + AndroidEnumerator(); + ~AndroidEnumerator(); + + void open(int direction); + void close(); + + int count(); + std::string nameAt(int index); + int idAt(int index); + int indexOfDefaultDevice(); + + protected: + }; + + class AndroidInputDevice: public InputDevice + { + public: + AndroidInputDevice(int devId); + ~AndroidInputDevice(); + + bool open(); + void close(); + Format getFormat(); + + bool fakeMode(); + void setFakeMode(bool fakemode); + int readBuffer(void* buffer); + bool active() const; + + protected: + bool mActive = false; + SLObjectItf mRecorderObject = nullptr; + SLRecordItf mRecorderInterface = nullptr; + SLAndroidSimpleBufferQueueItf mRecorderBufferInterface = nullptr; + SLAndroidConfigurationItf mAndroidCfg = nullptr; + + PResampler mResampler; + DataWindow mDeviceRateCache, mSdkRateCache; + int mDeviceRate; // Actual rate of opened recorder + int mBufferSize; // Size of buffer used for recording (at native sample rate) + DataWindow mRecorderBuffer; + std::condition_variable mDataCondVar; + int mRecorderBufferIndex; + std::mutex mMutex; + + void internalOpen(int rateCode, int rate); + void internalClose(); + void handleCallback(SLAndroidSimpleBufferQueueItf bq); + static void DeviceCallback(SLAndroidSimpleBufferQueueItf bq, void* context); + }; + + class AndroidOutputDevice: public OutputDevice + { + public: + AndroidOutputDevice(int devId); + ~AndroidOutputDevice(); + + bool open(); + void close(); + Format getFormat(); + + bool fakeMode(); + void setFakeMode(bool fakemode); + + protected: + std::mutex mMutex; + int mDeviceRate = 0; + SLObjectItf mMixer = nullptr; + SLObjectItf mPlayer = nullptr; + SLPlayItf mPlayerControl = nullptr; + SLAndroidSimpleBufferQueueItf mBufferQueue = nullptr; + SLAndroidConfigurationItf mAndroidConfig = nullptr; + SLEffectSendItf mEffect = nullptr; + + DataWindow mPlayBuffer; + int mBufferIndex = 0, mBufferSize = 0; + bool mInShutdown = false; + + void internalOpen(int rateId, int rate, bool voice); + void internalClose(); + + void handleCallback(SLAndroidSimpleBufferQueueItf bq); + static void DeviceCallback(SLAndroidSimpleBufferQueueItf bq, void* context); + + }; + + class OpenSLEngine: public OsEngine + { + public: + OpenSLEngine(); + ~OpenSLEngine(); + + // open() / close() methods are based on usage counting. + // It means every close() call must be matched by corresponding open() call. + // True audio engine close will happen only on last close() call. + void open() override; + void close() override; + + SLEngineItf getNativeEngine() const; + + static OpenSLEngine& instance(); + + protected: + std::mutex mMutex; + int mUsageCounter = 0; + SLObjectItf mEngineObject = nullptr; + SLEngineItf mEngineInterface = nullptr; + + void internalOpen(); + void internalClose(); + }; +} + +#endif // TARGET_ANDROID + +#endif // __AUDIO_ANDROID_H diff --git a/src/engine/audio/Audio_CoreAudio.cpp b/src/engine/audio/Audio_CoreAudio.cpp new file mode 100644 index 00000000..a6547bd6 --- /dev/null +++ b/src/engine/audio/Audio_CoreAudio.cpp @@ -0,0 +1,1040 @@ +/* Copyright(C) 2007-2017 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifdef TARGET_OSX + +#include "Audio_CoreAudio.h" +#include "../Helper/HL_Log.h" +//#include +#include +#include + +using namespace Audio; + +#define LOG_SUBSYSTEM "CoreAudio" + +enum +{ + Bus_Speaker = 0, + Bus_Microphone = 1 +}; + +static inline short Float32ToInt16(Float32 v) +{ + //assert (v <= 1.0); + int r = int(v * 32768); + if (r >= 32768) + return (short)32767; + else + if (r < -32768) + return (short)-32768; + else + return (short)r; +} + +static inline Float32 Int16ToFloat32(short v) +{ + Float32 r = Float32(v) / 32768.0; + return r; +} + +static inline Float32 StereoToMono(bool interleaved, Float32* buffer, int samples, int index, int channels) +{ + Float32 sum = 0; + for (int i = 0; i(inRefCon); + if (!d) + return noErr; + + if (!ioData->mNumberBuffers) + return noErr; + + // Here deinterleaving is expected; it means coreaudio will request multiple buffers - one buffer for one channel + // So only single buffer is filled from MacDevice; other are copies + AudioBuffer& ab = ioData->mBuffers[0]; + if (ab.mNumberChannels == 1) + { + ICELogMedia(<< "CoreAudio output callback for mono " << (int)ab.mDataByteSize << + " bytes"); + memset(ab.mData, 0, ab.mDataByteSize); + d->provideAudioToSpeaker(ab.mNumberChannels, ab.mData, ab.mDataByteSize); + + for (int i=1; imNumberBuffers; i++) + memcpy(ioData->mBuffers[i].mData, ab.mData, ab.mDataByteSize); + } + else + { + ICELogMedia(<< "CoreAudio output callback for stereo " << (int)ab.mDataByteSize << + " bytes") + // Iterate requested buffers + for (unsigned i=0; imNumberBuffers; i++) + { + unsigned channels = ioData->mBuffers[i].mNumberChannels; + short* dataPtr = (short*)ioData->mBuffers[i].mData; + unsigned dataSize = ioData->mBuffers[i].mDataByteSize; + + // Preset with silence + memset(dataPtr, 0, dataSize); + + // Find how much PCM16 samples are required to fill the requested space + d->provideAudioToSpeaker(channels, dataPtr, dataSize); + } + } + + return noErr; +} + +static char GlobalInputBuffer[AUDIO_MIC_BUFFER_COUNT * AUDIO_MIC_BUFFER_SIZE]; + +OSStatus MacDevice::inputCallback(void *inRefCon, + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList *ioData) +{ + //ICELogDebug(<< "CoreAudio input callback"); + MacDevice* d = reinterpret_cast(inRefCon); + if (!d) + return 0; + + OSStatus ostatus; + AudioBuffer& b = d->mInputBufferList->mBuffers[0]; + //b.mDataByteSize = 65536; + + b.mNumberChannels = d->mStreamFormat.mChannelsPerFrame; + b.mData = NULL; + b.mDataByteSize = inNumberFrames * d->mStreamFormat.mChannelsPerFrame; + + // Render the unit to get input data + ostatus = AudioUnitRender(d->mAudioUnit.getHandle(), + ioActionFlags, + inTimeStamp, + inBusNumber, + inNumberFrames, + d->mInputBufferList); + + if (ostatus != noErr) + { + ICELogCritical(<< "Cannot render input audio data, error " << int(ostatus)); + } + else + { + d->obtainAudioFromMic(b.mNumberChannels, b.mData, b.mDataByteSize); + } + return noErr; +} + +#ifdef TARGET_IOS +void MacDevice::propListener(void *inClientData, + AudioSessionPropertyID inID, + UInt32 inDataSize, + const void * inData) +{ + MacDevice* d = reinterpret_cast(inClientData); + CFDictionaryRef routeDictionary; + CFNumberRef reason; + SInt32 reasonVal; + + if (!d || inID != kAudioSessionProperty_AudioRouteChange) + return; + + routeDictionary = (CFDictionaryRef)inData; + reason = (CFNumberRef)CFDictionaryGetValue(routeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_Reason)); + CFNumberGetValue(reason, kCFNumberSInt32Type, &reasonVal); + + if (reasonVal != kAudioSessionRouteChangeReason_OldDeviceUnavailable) + { + return; + } + + // Audio route changed. Nothing to do in this implementation. + +} + +void MacDevice::interruptionListener(void *inClientData, UInt32 inInterruption) +{ + MacDevice* d = reinterpret_cast(inClientData); + + if (inInterruption == kAudioSessionEndInterruption) + { + UInt32 audioCategory; + OSStatus ostatus; + + /* Make sure that your application can receive remote control + * events by adding the code: + * [[UIApplication sharedApplication] + * beginReceivingRemoteControlEvents]; + * Otherwise audio unit will fail to restart while your + * application is in the background mode. + */ + /* Make sure we set the correct audio category before restarting */ + audioCategory = kAudioSessionCategory_PlayAndRecord; + ostatus = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, + sizeof(audioCategory), + &audioCategory); + if (ostatus != kAudioSessionNoError) + { + ICELogCritical(<<"Cannot set the audio session category, error " << ostatus); + } + + // Start stream + d->startStream(); + } + else + if (inInterruption == kAudioSessionBeginInterruption) + { + d->stopStream(); + } +} + +#endif +MacDevice::MacDevice(int devId) +:mDeviceId(devId), mCapture(false), mRender(false), mActive(false), + mConnection(nullptr), mUsageCount(0) +{ + mInputBuffer.setCapacity(AUDIO_MIC_BUFFER_COUNT * AUDIO_MIC_BUFFER_SIZE); + mOutputBuffer.setCapacity(AUDIO_SPK_BUFFER_SIZE); +} + +MacDevice::~MacDevice() +{ +} + +DataConnection* MacDevice::connection() +{ + return mConnection; +} + +void MacDevice::setConnection(DataConnection *c) +{ + mConnection = c; +} + +void MacDevice::provideAudioToSpeaker(int channels, void *buffer, int length) +{ + if (!mConnection) + return; + + mConnection->onSpkData(getFormat(), buffer, length); + return; +} + +void MacDevice::obtainAudioFromMic(int channels, const void *buffer, int length) +{ + if (!mConnection) + return; + + // Put audio into internal buffer and see if there are ready AUDIO_BUFFER_SIZE chunks + mConnection->onMicData(getFormat(), buffer, length); + return; +} + +bool MacDevice::open() +{ + Lock l(mGuard); + mUsageCount++; + if (mUsageCount == 1) + { + if (!createUnit(true)) + { + ICELogCritical(<< "Unable to create&adjust AudioUnit"); + return false; + // TODO - enable stub for iOS + } + startStream(); + } + return true; +} + +void MacDevice::close() +{ + Lock l(mGuard); + if (mUsageCount == 1) + { + stopStream(); + destroyUnit(); + } + if (mUsageCount > 0) + mUsageCount--; +} + +void MacDevice::setRender(bool render) +{ + mRender = render; +} + +void MacDevice::setCapture(bool capture) +{ + mCapture = capture; +} + +int MacDevice::getId() +{ + return this->mDeviceId; +} + +Format MacDevice::getFormat() +{ + Format result; + result.mChannels = mStreamFormat.mChannelsPerFrame; + result.mRate = mStreamFormat.mSampleRate; + return result; +} + +void MacDevice::setupStreamFormat() +{ + mStreamFormat.mSampleRate = AUDIO_SAMPLERATE; + mStreamFormat.mFormatID = kAudioFormatLinearPCM; + mStreamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; + mStreamFormat.mBitsPerChannel = AUDIO_SAMPLE_WIDTH; + mStreamFormat.mChannelsPerFrame = AUDIO_CHANNELS; + mStreamFormat.mBytesPerFrame = mStreamFormat.mChannelsPerFrame * mStreamFormat.mBitsPerChannel >> 3; + mStreamFormat.mFramesPerPacket = 1; + mStreamFormat.mBytesPerPacket = mStreamFormat.mFramesPerPacket * mStreamFormat.mBytesPerFrame; +} + +bool MacDevice::createUnit(bool voice) +{ + OSStatus ostatus; + + mAudioUnit.open(voice); + + //if (mCapture != mAudioUnit.getEnabled(kAudioUnitScope_Input, Bus_Microphone)) + mAudioUnit.setEnabled(mCapture, kAudioUnitScope_Input, Bus_Microphone); + //mAudioUnit.setEnabled(mCapture, kAudioUnitScope_Output, Bus_Microphone); + + //if (mRender != mAudioUnit.getEnabled(kAudioUnitScope_Output, Bus_Speaker)) + mAudioUnit.setEnabled(mRender, kAudioUnitScope_Output, Bus_Speaker); + //mAudioUnit.setEnabled(mRender, kAudioUnitScope_Input, Bus_Speaker); + + +#ifdef TARGET_OSX + // Open device + + if (mCapture) + mAudioUnit.makeCurrent(mDeviceId, kAudioUnitScope_Global, Bus_Microphone); + + if (mRender) + mAudioUnit.makeCurrent(mDeviceId, kAudioUnitScope_Global, Bus_Speaker); + +#endif + setupStreamFormat(); + + if (mCapture) + { + mCaptureInputFormat = mAudioUnit.getFormat(kAudioUnitScope_Input, Bus_Microphone); + mCaptureOutputFormat = mAudioUnit.getFormat(kAudioUnitScope_Output, Bus_Microphone); + mStreamFormat.mSampleRate = mCaptureInputFormat.mSampleRate; + if (mCaptureOutputFormat.mFormatFlags & kAudioFormatFlagIsNonInterleaved) + ICELogDebug(<< "Input device produces noninterleaved data"); + + mAudioUnit.setFormat(mStreamFormat, kAudioUnitScope_Output, Bus_Microphone); + // Start resampler + mCaptureResampler.start(mStreamFormat.mChannelsPerFrame, mStreamFormat.mSampleRate, AUDIO_SAMPLERATE); + } + + if (mRender) + { + // Init resample + mRenderOutputFormat = mAudioUnit.getFormat(kAudioUnitScope_Output, Bus_Speaker); + mRenderInputFormat = mAudioUnit.getFormat(kAudioUnitScope_Input, Bus_Speaker); + mAudioUnit.setFormat(mStreamFormat, kAudioUnitScope_Input, Bus_Speaker); + // Start resample + mRenderResampler.start(mStreamFormat.mChannelsPerFrame, AUDIO_SAMPLERATE, mStreamFormat.mSampleRate); + + // Set current render format - it is format required by unit from application; scope is Input and bus is 0 (speaker) + //mAudioUnit.setFormat(mRenderInputFormat, kAudioUnitScope_Input, Bus_Speaker); + + // Configure callback + AURenderCallbackStruct cb; + cb.inputProc = outputCallback; + cb.inputProcRefCon = this; + mAudioUnit.setCallback(cb, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, Bus_Speaker); + } + + if (mCapture) + { + AURenderCallbackStruct cb; + cb.inputProc = inputCallback; + cb.inputProcRefCon = this; + mAudioUnit.setCallback(cb, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, Bus_Microphone); //!!! +#ifdef TARGET_OSX + AudioBuffer *ab; + UInt32 size, bufsize; + + mAudioUnit.setBufferFrameSizeInMilliseconds(COREAUDIO_BUFFER_TIME); + + // Get device's buffer frame size + bufsize = mAudioUnit.getBufferFrameSize(); + mInputBufferList = (AudioBufferList*)malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer)); + if (!mInputBufferList) + { + ICELogCritical(<< "No memory for buffer list"); + return false; + } + mInputBufferList->mNumberBuffers = 1; + ab = &mInputBufferList->mBuffers[0]; + ab->mNumberChannels = mStreamFormat.mChannelsPerFrame; + ab->mDataByteSize = 0;//bufsize * ab->mNumberChannels * mCaptureOutputFormat.mBitsPerChannel / 8 * 8; + ab->mData = NULL;//malloc(ab->mDataByteSize); + if (!ab->mData) + { + //ICELogCritical(<< "No memory for capture buffer"); + } +#endif +#ifdef TARGET_IOS + /* We will let AudioUnitRender() to allocate the buffer + * for us later + */ + mInputBufferList = (AudioBufferList*)malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer)); + if (!mInputBufferList) + { + ICELogCritical(<< "No memory for buffer list"); + return false; + } + mInputBufferList->mNumberBuffers = 1; + mInputBufferList->mBuffers[0].mNumberChannels = 2; +#endif + } + + // Finally bring it online + mAudioUnit.initialize(); + return true; +} + +void MacDevice::destroyUnit() +{ + mAudioUnit.close(); + mCaptureResampler.stop(); + mRenderResampler.stop(); +} + +void MacDevice::startStream() +{ + if (mActive) + return; + +#ifdef TARGET_IOS + if (iosVersion() > 4) + { + UInt32 sessionMode = kAudioSessionMode_VoiceChat; + AudioSessionSetProperty(kAudioSessionProperty_Mode, sizeof(sessionMode), &sessionMode); + } + + // Share audio chain + //UInt32 allowMixing = YES; + //AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof (allowMixing), &allowMixing); + + // Activate audio chain + AudioSessionSetActive(true); +#endif + + OSStatus ostatus; + if (mAudioUnit.getHandle()) + { + ostatus = AudioOutputUnitStart(mAudioUnit.getHandle()); + if (ostatus != noErr) + { + ICELogCritical(<< "Failed to start audio unit, error " << int(ostatus)); + return; + } + } + mActive = true; +} + +void MacDevice::stopStream() +{ + if (!mActive || !mAudioUnit.getHandle()) + return; + OSStatus ostatus; + ostatus = AudioOutputUnitStop(mAudioUnit.getHandle()); + if (ostatus != noErr) + { + ICELogCritical(<< "Failed to stop audio unit, error " << int(ostatus)); + } + +#ifdef TARGET_IOS + AudioSessionSetActive(false); +#endif + mActive = false; +} + +bool MacDevice::createResampleUnit(AudioStreamBasicDescription format) +{ + return true; +} + +class MacDeviceList +{ +public: + MacDeviceList(); + ~MacDeviceList(); + PMacDevice findDevice(int devId); + + static MacDeviceList& instance(); + +protected: + Mutex mGuard; + std::vector mDeviceList; + static MacDeviceList* mInstance; +}; + +MacDeviceList* MacDeviceList::mInstance = NULL; + +MacDeviceList::MacDeviceList() +{ + +} + +MacDeviceList::~MacDeviceList() +{ + +} + +MacDeviceList& MacDeviceList::instance() +{ + if (!mInstance) + mInstance = new MacDeviceList(); + return *mInstance; +} + +PMacDevice MacDeviceList::findDevice(int devId) +{ + Lock l(mGuard); + for (unsigned i=0; igetId() == devId) + return d; + } + + PMacDevice d(new MacDevice(devId)); + mDeviceList.push_back(d); + return d; +} + +// Share list of opened devices +MacInputDevice::MacInputDevice(int devId) + :InputDevice() +{ + // Look for MacDevice + mDevice = MacDeviceList::instance().findDevice(devId); + mDevice->setCapture(true); + mDevice->setConnection(mConnection); +} + +MacInputDevice::~MacInputDevice() +{ + mDevice.reset(); +} + +bool MacInputDevice::open() +{ + mDevice->setConnection(mConnection); + return mDevice->open(); +} + +void MacInputDevice::close() +{ + mDevice->close(); +} + +Format MacInputDevice::getFormat() +{ + return mDevice->getFormat(); +} + +MacOutputDevice::MacOutputDevice(int devId) + :OutputDevice() +{ + // Look for MacDevice + mDevice = MacDeviceList::instance().findDevice(devId); + mDevice->setRender(true); + mDevice->setConnection(mConnection); +} + +MacOutputDevice::~MacOutputDevice() +{ + mDevice.reset(); +} + +bool MacOutputDevice::open() +{ + mDevice->setConnection(mConnection); + return mDevice->open(); +} + +void MacOutputDevice::close() +{ + mDevice->close(); +} + +Format MacOutputDevice::getFormat() +{ + return mDevice->getFormat(); +} + +MacEnumerator::MacEnumerator() + :mDefaultInput(0), mDefaultOutput(0) +{ + +} + +MacEnumerator::~MacEnumerator() +{ + +} + +void MacEnumerator::open(int direction) +{ + mDirection = direction; + +#ifdef TARGET_OSX + mDefaultInput = 0; + mDefaultOutput = 0; + mDeviceList.clear(); + + AudioObjectPropertyAddress addr; + OSStatus osstatus; + UInt32 devSize, size; + // Get audio list size + addr.mSelector = kAudioHardwarePropertyDevices; + addr.mScope = kAudioObjectPropertyScopeGlobal; + addr.mElement = kAudioObjectPropertyElementMaster; + osstatus = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr, + 0, NULL, &devSize); + if (osstatus != noErr) + { + devSize = 0; + return; + } + + UInt32 devCount = devSize / sizeof(AudioDeviceID); + std::vector deviceIds; + deviceIds.resize(devCount); + + // Get actual list + osstatus = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, + 0, NULL, &devSize, (void *)&deviceIds.front()); + if (osstatus != noErr) + return; + for (unsigned i=0; i::iterator r = std::find_if(mDeviceList.begin(), mDeviceList.end(), + [devId] (const DeviceInfo& di) { return di.mId == devId;}); + if (r != mDeviceList.end()) + mDefaultInput = r - mDeviceList.begin(); + } + } + + /* Find default audio output device */ + if (direction == mySpeaker) + { + addr.mSelector = kAudioHardwarePropertyDefaultOutputDevice; + osstatus = AudioObjectGetPropertyData(kAudioObjectSystemObject, + &addr, 0, NULL, + &size, (void *)&devId); + if (osstatus == noErr) + { + std::vector::iterator r = std::find_if(mDeviceList.begin(), mDeviceList.end(), + [devId](const DeviceInfo& di) { return di.mId == devId;}); + if (r != mDeviceList.end()) + mDefaultOutput = r - mDeviceList.begin(); + } + } + +#endif +} + +void MacEnumerator::getInfo(DeviceInfo &di) +{ + UInt32 size; + OSStatus osstatus; + + // Name + AudioObjectPropertyAddress addr; + addr.mSelector = kAudioDevicePropertyDeviceName; + addr.mScope = kAudioObjectPropertyScopeGlobal; + addr.mElement = kAudioObjectPropertyElementMaster; + char name[256]; + size = sizeof(name); + AudioObjectGetPropertyData(di.mId, &addr, 0, NULL, &size, (void *)name); + di.mName = name; + + // Get the number of input channels + addr.mSelector = kAudioDevicePropertyStreamConfiguration; + addr.mScope = kAudioDevicePropertyScopeInput; + size = 0; + osstatus = AudioObjectGetPropertyDataSize(di.mId, &addr, 0, NULL, &size); + AudioBufferList* buf = NULL; + if (osstatus == noErr && size > 0) + buf = (AudioBufferList*)malloc(size); + + if (buf) + { + UInt32 idx; + + /* Get the input stream configuration */ + osstatus = AudioObjectGetPropertyData(di.mId, &addr, 0, NULL, &size, buf); + if (osstatus == noErr) + { + /* Count the total number of input channels in + * the stream + */ + for (idx = 0; idx < buf->mNumberBuffers; idx++) + { + di.mInputCount += buf->mBuffers[idx].mNumberChannels; + } + } + free(buf); + buf = NULL; + } + + // Get the number of output channels + addr.mScope = kAudioDevicePropertyScopeOutput; + size = 0; + osstatus = AudioObjectGetPropertyDataSize(di.mId, &addr, 0, NULL, &size); + if (osstatus == noErr && size > 0) + buf = (AudioBufferList*)malloc(size); + if (buf) + { + UInt32 idx; + + /* Get the output stream configuration */ + osstatus = AudioObjectGetPropertyData(di.mId, &addr, 0, NULL, &size, buf); + if (osstatus == noErr) + { + /* Count the total number of output channels in + * the stream + */ + for (idx = 0; idx < buf->mNumberBuffers; idx++) + { + di.mOutputCount += buf->mBuffers[idx].mNumberChannels; + } + } + free(buf); buf = NULL; + } + + /* Get default sample rate */ + addr.mSelector = kAudioDevicePropertyNominalSampleRate; + addr.mScope = kAudioObjectPropertyScopeGlobal; + size = sizeof(Float64); + Float64 sampleRate; + osstatus = AudioObjectGetPropertyData (di.mId, &addr, 0, NULL, &size, &sampleRate); + if (osstatus == noErr) + di.mDefaultRate = int(sampleRate); + + /* Set device capabilities here */ + if (di.mOutputCount > 0) + { + addr.mSelector = kAudioDevicePropertyVolumeScalar; + addr.mScope = kAudioDevicePropertyScopeOutput; + osstatus = AudioObjectHasProperty(di.mId, &addr); + if (osstatus == noErr) + { + di.mCanChangeOutputVolume = true; + } + } +} + +void MacEnumerator::close() +{ + +} + +int MacEnumerator::count() +{ + return mDeviceList.size(); +} + +std::tstring MacEnumerator::nameAt(int index) +{ + return mDeviceList[index].mName; +} + +int MacEnumerator::idAt(int index) +{ + return mDeviceList[index].mId; +} + +int MacEnumerator::indexOfDefaultDevice() +{ + if (mDirection == myMicrophone) + return mDefaultInput; + else + return mDefaultOutput; +} + +#endif diff --git a/src/engine/audio/Audio_CoreAudio.h b/src/engine/audio/Audio_CoreAudio.h new file mode 100644 index 00000000..40cc6410 --- /dev/null +++ b/src/engine/audio/Audio_CoreAudio.h @@ -0,0 +1,196 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#ifndef __AUDIO_COREAUDIO_H +#define __AUDIO_COREAUDIO_H + +#ifdef TARGET_OSX + +#include "Audio_Interface.h" +#include "Audio_Helper.h" +#include "Audio_Resampler.h" +#include "Audio_DataWindow.h" +#include "../Helper/HL_Pointer.h" +#include "../Helper/HL_ByteBuffer.h" +#include "../Helper/HL_Exception.h" +#include + +// Define CoreAudio buffer time length in milliseconds +#define COREAUDIO_BUFFER_TIME 20 + +namespace Audio +{ + +class AudioException: public Exception +{ +public: + AudioException(int code, OSStatus subcode) + :Exception(code, int(subcode)) + {} +}; + +//#ifndef AudioDeviceID +//# define AudioDeviceID unsigned +//#endif +class MacEnumerator: public Enumerator +{ +public: + MacEnumerator(); + ~MacEnumerator(); + + void open(int direction); + void close(); + + int count(); + std::tstring nameAt(int index); + int idAt(int index); + int indexOfDefaultDevice(); + +protected: + struct DeviceInfo + { + AudioDeviceID mId; + std::string mName; + bool mCanChangeOutputVolume; + bool mCanChangeInputVolume; + int mInputCount, mOutputCount; + int mDefaultRate; + DeviceInfo(): mId(0), mCanChangeOutputVolume(false), mCanChangeInputVolume(false), mInputCount(0), mOutputCount(0), mDefaultRate(16000) {} + }; + std::vector mDeviceList; + unsigned mDefaultInput, mDefaultOutput; + int mDirection; + void getInfo(DeviceInfo& di); +}; + +class CoreAudioUnit +{ +public: + CoreAudioUnit(); + ~CoreAudioUnit(); + + void open(bool voice); + void close(); + AudioStreamBasicDescription getFormat(int scope, int bus); + void setFormat(AudioStreamBasicDescription& format, int scope, int bus); + bool getEnabled(int scope, int bus); + void setEnabled(bool enabled, int scope, int bus); + void makeCurrent(AudioDeviceID deviceId, int scope, int bus); + void setCallback(AURenderCallbackStruct cb, int callbackType, int scope, int bus); + void setBufferFrameSizeInMilliseconds(int ms); + int getBufferFrameSize(); + void initialize(); + AudioUnit getHandle(); + +protected: + AudioUnit mUnit; +}; + +class MacDevice +{ +public: + MacDevice(int devId); + ~MacDevice(); + + bool open(); + void close(); + void setRender(bool render); + void setCapture(bool capture); + int getId(); + Format getFormat(); + + DataConnection* connection(); + void setConnection(DataConnection* c); + void provideAudioToSpeaker(int channels, void* buffer, int length); + void obtainAudioFromMic(int channels, const void* buffer, int length); + +protected: + AudioDeviceID mDeviceId; + bool mCapture, mRender; + bool mActive; + int mUsageCount; + Mutex mGuard; + + CoreAudioUnit mAudioUnit; + AudioComponent mComponent; + AudioStreamBasicDescription mCaptureInputFormat, mCaptureOutputFormat, mRenderInputFormat, mRenderOutputFormat, mStreamFormat; + AudioBufferList* mInputBufferList; + DataConnection* mConnection; + SpeexResampler mCaptureResampler, mRenderResampler; + ByteBuffer mTail; + DataWindow mInputBuffer, mOutputBuffer; + bool createUnit(bool voice); + void destroyUnit(); + void startStream(); + void stopStream(); + void setupStreamFormat(); + bool createResampleUnit(AudioStreamBasicDescription format); + + static OSStatus outputCallback( void *inRefCon, + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList *ioData ); + + static OSStatus inputCallback(void *inRefCon, + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList *ioData); +#ifdef TARGET_IOS + static void propListener(void *inClientData, + AudioSessionPropertyID inID, + UInt32 inDataSize, + const void * inData); + static void interruptionListener(void *inClientData, UInt32 inInterruption); +#endif + +}; + +typedef SharedPtr PMacDevice; + +class MacInputDevice: public InputDevice +{ +public: + MacInputDevice(int devId); + ~MacInputDevice(); + + bool open(); + void close(); + Format getFormat(); + + bool fakeMode(); + void setFakeMode(bool fakemode); + int readBuffer(void* buffer); +protected: + PMacDevice mDevice; + +}; + +class MacOutputDevice: public OutputDevice +{ +public: + MacOutputDevice(int devId); + ~MacOutputDevice(); + + bool open(); + void close(); + Format getFormat(); + + bool fakeMode(); + void setFakeMode(bool fakemode); + +protected: + PMacDevice mDevice; +}; + +} + +#endif // TARGET_OSX + +#endif // __AUDIO_COREAUDIO_H diff --git a/src/engine/audio/Audio_DataWindow.cpp b/src/engine/audio/Audio_DataWindow.cpp new file mode 100644 index 00000000..9814d750 --- /dev/null +++ b/src/engine/audio/Audio_DataWindow.cpp @@ -0,0 +1,171 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "Audio_DataWindow.h" + +using namespace Audio; + +DataWindow::DataWindow() +{ + mFilled = 0; + mData = NULL; + mCapacity = 0; +} + +DataWindow::~DataWindow() +{ + if (mData) + free(mData); +} + +void DataWindow::setCapacity(int capacity) +{ + Lock l(mMutex); + int tail = capacity - mCapacity; + mData = (char*)realloc(mData, capacity); + if (tail > 0) + memset(mData + mCapacity, 0, tail); + mCapacity = capacity; +} + +void DataWindow::addZero(int length) +{ + Lock l(mMutex); + + if (length > mCapacity) + length = mCapacity; + + int avail = mCapacity - mFilled; + + if (avail < length) + { + memmove(mData, mData + length - avail, mFilled - (length - avail)); + mFilled -= length - avail; + } + memset(mData + mFilled, 0, length); + mFilled += length; +} + + +void DataWindow::add(const void* data, int length) +{ + Lock l(mMutex); + + if (length > mCapacity) + { + data = (char*)data + length - mCapacity; + length = mCapacity; + } + + int avail = mCapacity - mFilled; + + if (avail < length) + { + memmove(mData, mData + length - avail, mFilled - (length - avail)); + mFilled -= length - avail; + } + memcpy(mData + mFilled, data, length); + mFilled += length; +} + +void DataWindow::add(short sample) +{ + add(&sample, sizeof sample); +} + +void DataWindow::erase(int length) +{ + Lock l(mMutex); + if (length > mFilled) + length = mFilled; + if (length != mFilled) + memmove(mData, mData + length, mFilled - length); + mFilled -= length; +} + +const char* DataWindow::data() const +{ + return mData; +} + +char* DataWindow::mutableData() +{ + return mData; +} + +void DataWindow::clear() +{ + Lock l(mMutex); + mFilled = 0; +} + +short DataWindow::shortAt(int index) const +{ + Lock l(mMutex); + assert(index < mFilled / 2); + return ((short*)mData)[index]; +} + +void DataWindow::setShortAt(short value, int index) +{ + Lock l(mMutex); + assert(index < mFilled / 2); + ((short*)mData)[index] = value; +} + +int DataWindow::read(void* buffer, int length) +{ + Lock l(mMutex); + if (length > mFilled) + length = mFilled; + if (length) + { + if (buffer) + memcpy(buffer, mData, length); + if (length < mFilled) + memmove(mData, mData+length, mFilled - length); + mFilled -= length; + } + return length; +} + +int DataWindow::filled() const +{ + Lock l(mMutex); + return mFilled; +} + +void DataWindow::setFilled(int filled) +{ + Lock l(mMutex); + mFilled = filled; +} + +int DataWindow::capacity() const +{ + Lock l(mMutex); + return mCapacity; +} + +void DataWindow::zero(int length) +{ + Lock l(mMutex); + assert(length <= mCapacity); + mFilled = length; + memset(mData, 0, mFilled); +} + +void DataWindow::makeStereoFromMono(DataWindow& dst, DataWindow& src) +{ + Lock lockDst(dst.mMutex), lockSrc(src.mMutex); + + dst.setCapacity(src.filled()*2); + short* input = (short*)src.mutableData(); + short* output = (short*)dst.mutableData(); + + for (int i=0; i + +#define LOG_SUBSYSTEM "Audio" + +using namespace Audio; + +// --- DevicePair --- +DevicePair::DevicePair(bool aec, bool agc) +:mConfig(NULL), mDelegate(NULL), mAec(aec), mAgc(agc), mAecFilter(AUDIO_MIC_BUFFER_LENGTH*10, AUDIO_MIC_BUFFER_LENGTH, AUDIO_SAMPLERATE), mAgcFilter(AUDIO_CHANNELS) +{ + mInputBuffer.setCapacity(AUDIO_MIC_BUFFER_SIZE * (AUDIO_MIC_BUFFER_COUNT + 1)); + mOutputBuffer.setCapacity(AUDIO_SPK_BUFFER_SIZE * (AUDIO_SPK_BUFFER_COUNT + 1)); + mInputResampingData.setCapacity(AUDIO_MIC_BUFFER_SIZE * (AUDIO_MIC_BUFFER_COUNT + 1)); + mOutput10msBuffer.setCapacity((int)Format().sizeFromTime(AUDIO_SPK_BUFFER_LENGTH)); + mOutputNativeData.setCapacity((int)Format().sizeFromTime(AUDIO_SPK_BUFFER_LENGTH * AUDIO_SPK_BUFFER_COUNT * 24)); +} + +DevicePair::~DevicePair() +{ + if (mInput) + { + if (mInput->connection() == this) + mInput->setConnection(NULL); + mInput.reset(); + } + + if (mOutput) + { + if (mOutput->connection() == this) + mOutput->setConnection(NULL); + mOutput.reset(); + } +} + +VariantMap* DevicePair::config() +{ + return mConfig; +} + +void DevicePair::setConfig(VariantMap* config) +{ + mConfig = config; +} + +PInputDevice DevicePair::input() +{ + return mInput; +} + +void DevicePair::setInput(PInputDevice input) +{ + if (mInput == input) + return; + + mInput = input; + mInput->setConnection(this); + if (mDelegate) + mDelegate->deviceChanged(this); +} + +POutputDevice DevicePair::output() +{ + return mOutput; +} + +void DevicePair::setOutput(POutputDevice output) +{ + if (output == mOutput) + return; + mOutput = output; + mOutput->setConnection(this); + if (mDelegate) + mDelegate->deviceChanged(this); +} + +bool DevicePair::start() +{ + bool result = false; + if (mInput) + result = mInput->open(); + if (mOutput && result) + result &= mOutput->open(); + return result; +} + +void DevicePair::stop() +{ + if (mInput) + mInput->close(); + if (mOutput) + mOutput->close(); +} + +void DevicePair::setDelegate(Delegate* dc) +{ + mDelegate = dc; +} + +DevicePair::Delegate* DevicePair::delegate() +{ + return mDelegate; +} + +Player& DevicePair::player() +{ + return mPlayer; +} + +void DevicePair::onMicData(const Format& f, const void* buffer, int length) +{ +#ifdef DUMP_NATIVEINPUT + if (!mNativeInputDump) + { + mNativeInputDump = std::make_shared(); + mNativeInputDump->open("nativeinput.wav", f.mRate, f.mChannels); + } + if (mNativeInputDump) + mNativeInputDump->write(buffer, length); +#endif + + // send the data to internal queue - it can hold data which were not processed by resampler in last call + mInputResampingData.add(buffer, length); + + // split processing by blocks + int blocks = mInputResampingData.filled() / (int)f.sizeFromTime(AUDIO_MIC_BUFFER_LENGTH); + + for (int blockIndex = 0; blockIndex < blocks; blockIndex++) + { + + int wasProcessed = 0; + + int wasProduced = mMicResampler.resample(f.mRate, // Source rate + mInputResampingData.data(), // Source data + (int)f.sizeFromTime(AUDIO_MIC_BUFFER_LENGTH), // Source size + wasProcessed, + AUDIO_SAMPLERATE, // Dest rate + mInputBuffer.mutableData() + mInputBuffer.filled(), + mInputBuffer.capacity() - mInputBuffer.filled()); + + mInputBuffer.setFilled(mInputBuffer.filled() + wasProduced); + mInputResampingData.erase((int)f.sizeFromTime(AUDIO_MIC_BUFFER_LENGTH)); + processMicData(Format(), mInputBuffer.mutableData(), (int)Format().sizeFromTime(AUDIO_MIC_BUFFER_LENGTH)); + + mInputBuffer.erase((int)Format().sizeFromTime(AUDIO_MIC_BUFFER_LENGTH)); + } + +} + +void DevicePair::onSpkData(const Format& f, void* buffer, int length) +{ + //ICELogMedia(<< "Audio::DevicePair::onSpkData() begin"); +#ifdef DUMP_NATIVEOUTPUT + if (!mNativeOutputDump) + { + mNativeOutputDump = std::make_shared(); + mNativeOutputDump->open("nativeoutput.wav", f.mRate, f.mChannels); + } +#endif +#ifdef CONSOLE_LOGGING + printf("Speaker requests %d\n", length); +#endif + + Format nativeFormat = mOutput->getFormat(); + // See how much bytes are needed yet - mOutputNativeData can contain some data already + int required = length - mOutputNativeData.filled(); + if (required > 0) + { + + // Find how much blocks must be received from RTP/decoder side + int nativeBufferSize = (int)nativeFormat.sizeFromTime(AUDIO_SPK_BUFFER_LENGTH); + int blocks = required / nativeBufferSize; + if (required % nativeBufferSize) + blocks++; + + // Now request data from terminal or whetever delegate is + for (int blockIndex = 0; blockIndex < blocks; blockIndex++) + { + memset(mOutput10msBuffer.mutableData(), 0, (size_t)mOutput10msBuffer.capacity()); + + if (mDelegate) + mDelegate->onSpkData(Format(), mOutput10msBuffer.mutableData(), mOutput10msBuffer.capacity()); + + // Replace received data with custom file or data playing + mPlayer.onSpkData(Format(), mOutput10msBuffer.mutableData(), mOutput10msBuffer.capacity()); + + // Save it to process with AEC + if (mAec) + mAecSpkBuffer.add(mOutput10msBuffer.data(), mOutput10msBuffer.capacity()); + + // Resample these 10 milliseconds it to native format + int wasProcessed = 0; + int wasProduced = mSpkResampler.resample(AUDIO_SAMPLERATE, mOutput10msBuffer.data(), mOutput10msBuffer.capacity(), wasProcessed, f.mRate, + mOutputNativeData.mutableData() + mOutputNativeData.filled(), mOutputNativeData.capacity() - mOutputNativeData.filled()); + mOutputNativeData.setFilled(mOutputNativeData.filled() + wasProduced); +#ifdef CONSOLE_LOGGING + printf("Resampled %d to %d\n", wasProcessed, wasProduced); +#endif + } + } + + assert(mOutputNativeData.filled() >= length); +#ifdef DUMP_NATIVEOUTPUT + if (mNativeOutputDump) + mNativeOutputDump->write(mOutputNativeData.data(), length); +#endif + + mOutputNativeData.read(buffer, length); + + #define AEC_FRAME_SIZE (AUDIO_CHANNELS * (AUDIO_SAMPLERATE / 1000) * AEC_FRAME_TIME * sizeof(short)) + + // AEC filter wants frames. + if (mAec) + { + int nrOfFrames = mAecSpkBuffer.filled() / AEC_FRAME_SIZE; + for (int frameIndex=0; frameIndex < nrOfFrames; frameIndex++) + mAecFilter.toSpeaker(mAecSpkBuffer.mutableData() + AEC_FRAME_SIZE * frameIndex); + mAecSpkBuffer.erase(nrOfFrames * AEC_FRAME_SIZE); + } + //ICELogMedia(<< "Audio::DevicePair::onSpkData() end") +} + +void DevicePair::processMicData(const Format& f, void* buffer, int length) +{ + if (mAgc) + mAgcFilter.process(buffer, length); + + if (mAec) + mAecFilter.fromMic(buffer); + + if (mDelegate) + mDelegate->onMicData(f, buffer, length); +} diff --git a/src/engine/audio/Audio_DevicePair.h b/src/engine/audio/Audio_DevicePair.h new file mode 100644 index 00000000..28abb584 --- /dev/null +++ b/src/engine/audio/Audio_DevicePair.h @@ -0,0 +1,81 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __AUDIO_DEVICEPAIR_H +#define __AUDIO_DEVICEPAIR_H + +#include "Audio_Interface.h" +#include "Audio_Player.h" +#include "Audio_Resampler.h" +#include "Audio_DataWindow.h" + +//#define DUMP_NATIVEOUTPUT +//#define DUMP_NATIVEINPUT + +namespace Audio +{ + + class DevicePair: protected DataConnection + { + public: + class Delegate: public DataConnection + { + public: + virtual void deviceChanged(DevicePair* dpair) = 0; + }; + + DevicePair(bool aec = true, bool agc = true); + virtual ~DevicePair(); + + void setAec(bool aec); + bool aec(); + void setAgc(bool agc); + bool agc(); + + VariantMap* config(); + void setConfig(VariantMap* config); + + PInputDevice input(); + void setInput(PInputDevice input); + + POutputDevice output(); + void setOutput(POutputDevice output); + + bool start(); + void stop(); + + void setDelegate(Delegate* dc); + Delegate* delegate(); + + Player& player(); + + protected: + VariantMap* mConfig; + PInputDevice mInput; + POutputDevice mOutput; + Delegate* mDelegate; + bool mAec; + bool mAgc; + AgcFilter mAgcFilter; + AecFilter mAecFilter; + Player mPlayer; + UniversalResampler mMicResampler, mSpkResampler; + DataWindow mInputBuffer, mOutputBuffer, mAecSpkBuffer, mInputResampingData, mOutputNativeData, mOutput10msBuffer; + +#ifdef DUMP_NATIVEOUTPUT + std::shared_ptr mNativeOutputDump; +#endif +#ifdef DUMP_NATIVEINPUT + std::shared_ptr mNativeInputDump; +#endif + void onMicData(const Format& f, const void* buffer, int length); + void onSpkData(const Format& f, void* buffer, int length); + void processMicData(const Format& f, void* buffer, int length); + }; + + typedef std::shared_ptr PDevicePair; +} + +#endif diff --git a/src/engine/audio/Audio_DirectSound.cpp b/src/engine/audio/Audio_DirectSound.cpp new file mode 100644 index 00000000..91590369 --- /dev/null +++ b/src/engine/audio/Audio_DirectSound.cpp @@ -0,0 +1,1101 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#if defined(TARGET_WIN) && defined(_MSC_VER) + +#include "Audio_DirectSound.h" +#include "Audio_Helper.h" +#include "../Helper/HL_Exception.h" +#include "../Helper/HL_Log.h" + +#include +#include +#pragma comment(lib, "dsound.lib") +#pragma comment(lib, "dxguid.lib") + +#define DRVM_MAPPER_CONSOLEVOICECOM_GET (0x2000 + 23) +#define DRVM_MAPPER_PREFERRED_GET (0x2000 + 21) + +#define DRV_QUERYFUNCTIONINSTANCEID (DRV_RESERVED + 17) +#define DRV_QUERYFUNCTIONINSTANCEIDSIZE (DRV_RESERVED + 18) + +#define LOG_SUBSYSTEM "DirectSound" + +using namespace Audio; + +class DSoundInit +{ +public: + DSoundInit(); + virtual ~DSoundInit(); + + void load(); + void unload(); + + struct EntryPoints + { + HINSTANCE mInstance; + + HRESULT (WINAPI *DirectSoundCreate8)(LPGUID, LPDIRECTSOUND8 *, LPUNKNOWN); + HRESULT (WINAPI *DirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID); + HRESULT (WINAPI *DirectSoundEnumerateA)(LPDSENUMCALLBACKA, LPVOID); + + HRESULT (WINAPI *DirectSoundCaptureCreate8)(LPGUID, LPDIRECTSOUNDCAPTURE8* , LPUNKNOWN); + HRESULT (WINAPI *DirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW, LPVOID); + HRESULT (WINAPI *DirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA, LPVOID); + HRESULT (WINAPI *GetDeviceID)(LPCGUID src, LPGUID dst); + } mRoutines; + +protected: + LPDIRECTSOUND mDirectSound; + Mutex mGuard; + unsigned int mRefCount; +}; + +DSoundInit gDSoundInit; + +DSoundInit::DSoundInit() + :mRefCount(0) +{ +} + +DSoundInit::~DSoundInit() +{ + //Unload(); +} + +void DSoundInit::load() +{ + Lock l(mGuard); + + if (++mRefCount == 1) + { + HRESULT hr = E_FAIL; + + hr = ::CoInitialize(NULL); + + //load the DirectSound DLL + mRoutines.mInstance = ::LoadLibrary(L"dsound.dll"); + if (!mRoutines.mInstance) + throw std::logic_error("Cannot load dsound.dll"); + + mRoutines.DirectSoundCaptureCreate8 = (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUNDCAPTURE8 *, LPUNKNOWN))::GetProcAddress(mRoutines.mInstance, "DirectSoundCaptureCreate8"); + mRoutines.DirectSoundCaptureEnumerateW = (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID))::GetProcAddress(mRoutines.mInstance, "DirectSoundCaptureEnumerateW"); + mRoutines.DirectSoundCreate8 = (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUND8 *, LPUNKNOWN))::GetProcAddress(mRoutines.mInstance, "DirectSoundCreate8"); + mRoutines.DirectSoundEnumerateW = (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID))::GetProcAddress(mRoutines.mInstance, "DirectSoundEnumerateW"); + mRoutines.GetDeviceID = (HRESULT (WINAPI*) (LPCGUID, LPGUID)) GetProcAddress(mRoutines.mInstance, "GetDeviceID"); + } +} + +void DSoundInit::unload() +{ + Lock l(mGuard); + if (--mRefCount == 0) + { + if (mRoutines.mInstance) + { + ::FreeLibrary(mRoutines.mInstance); + mRoutines.mInstance = NULL; + } + + CoUninitialize(); + } +} + +// --------------- VistaEnumerator --------------------- +VistaEnumerator::VistaEnumerator() +:mCollection(NULL), mDefaultDevice(NULL), mEnumerator(NULL), mDirection(eCapture) +{ +} + +VistaEnumerator::~VistaEnumerator() +{ + close(); +} + +void VistaEnumerator::open(int direction) +{ + const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator); + const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator); + + mDirection = (direction == myMicrophone) ? eCapture : eRender; + + HRESULT hr = CoCreateInstance( + CLSID_MMDeviceEnumerator, NULL, + CLSCTX_ALL, IID_IMMDeviceEnumerator, + (void**)&mEnumerator); + if (!mEnumerator) + return; + + hr = mEnumerator->EnumAudioEndpoints(mDirection, DEVICE_STATE_ACTIVE, &mCollection); + if (!mCollection) + return; + hr = mEnumerator->GetDefaultAudioEndpoint(mDirection, eCommunications, &mDefaultDevice); + if (!mDefaultDevice) + return; + + enumerate(); +} + +void VistaEnumerator::close() +{ + try + { + if (mCollection) + { + mCollection->Release(); + mCollection = NULL; + } + + if (mDefaultDevice) + { + //mDefaultDevice->Release(); + mDefaultDevice = NULL; + } + + if (mEnumerator) + { + mEnumerator->Release(); + mEnumerator = NULL; + } + } + catch(...) + { + } +} + +IMMDevice* VistaEnumerator::mapIndexToInterface(int index) +{ + if (!mCollection) + return NULL; + + if (index == -1) + return mDefaultDevice; + + size_t idSize = 0; + MMRESULT mmres = 0; + WCHAR* id = NULL; + if (mDirection == eCapture) + { + mmres = waveInMessage((HWAVEIN)index, DRV_QUERYFUNCTIONINSTANCEIDSIZE, (DWORD_PTR)&idSize, NULL); + + if (mmres != MMSYSERR_NOERROR) + return NULL; + + id = (WCHAR*)_alloca(idSize*sizeof(WCHAR)); + mmres = waveInMessage((HWAVEIN)index, DRV_QUERYFUNCTIONINSTANCEID, (DWORD_PTR)id, idSize); + } + else + { + mmres = waveOutMessage((HWAVEOUT)index, DRV_QUERYFUNCTIONINSTANCEIDSIZE, (DWORD_PTR)&idSize, NULL); + + if (mmres != MMSYSERR_NOERROR) + return NULL; + + id = (WCHAR*)_alloca(idSize*sizeof(WCHAR)); + mmres = waveOutMessage((HWAVEOUT)index, DRV_QUERYFUNCTIONINSTANCEID, (DWORD_PTR)id, idSize); + } + + if (mmres != MMSYSERR_NOERROR) + return NULL; + + IMMDevice* pDevice = NULL; + mEnumerator->GetDevice(id, &pDevice); + + return pDevice; +} + +void VistaEnumerator::enumerate() +{ + mNameList.clear(); + int res = (int)count(); + + for (int i=0; iOpenPropertyStore(STGM_READ, &store); + if (store) + { + PROPVARIANT varName; + PropVariantInit(&varName); + if (store->GetValue(PKEY_Device_FriendlyName, &varName) == S_OK) + mNameList.push_back(varName.pwszVal); + PropVariantClear(&varName); + store->Release(); + } + dev->Release(); + } + } +} + +std::tstring VistaEnumerator::nameAt(int index) +{ + return mNameList[index]; +} + +int VistaEnumerator::idAt(int index) +{ + return index; +} + +int VistaEnumerator::count() +{ + if (mDirection == eCapture) + return waveInGetNumDevs(); + else + return waveOutGetNumDevs(); +} + +int VistaEnumerator::indexOfDefaultDevice() +{ + DWORD devID = -1, status = 0; + + if (mDirection == mySpeaker) + { + if (waveOutMessage((HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET, (DWORD_PTR)&devID, (DWORD_PTR)&status) != MMSYSERR_NOERROR) + waveOutMessage((HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&devID, (DWORD_PTR)&status); + } + else + { + if (waveInMessage((HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET, (DWORD_PTR)&devID, (DWORD_PTR)&status) != MMSYSERR_NOERROR) + waveInMessage((HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&devID, (DWORD_PTR)&status); + } + return devID; +} + +// -------------- XpEnumerator --------------- +XpEnumerator::XpEnumerator() +:mDirection(-1) +{ +} + +XpEnumerator::~XpEnumerator() +{ +} + +void XpEnumerator::open(int direction) +{ + mNameList.clear(); + if (direction == myMicrophone) + { + int count = waveInGetNumDevs(); + for (int i=0; iCreateCaptureBuffer(&dsbd, &dscb, NULL)); + DSoundHelper::checkComResult(dscb->QueryInterface(IID_IDirectSoundCaptureBuffer8, (void**)&mBuffer)); + DSoundHelper::checkComResult(dscb->QueryInterface(IID_IDirectSoundNotify, (void**)&mNotifications)); + DSoundHelper::checkComResult(mNotifications->SetNotificationPositions(AUDIO_MIC_BUFFER_COUNT, mEventArray)); + DSoundHelper::checkComResult(mBuffer->Start(DSCBSTART_LOOPING)); + dscb->Release(); + setSimulate( false ); +} + +bool DSoundInputDevice::open() +{ + ICELogInfo(<< "Request to DirectSound audio input"); + Lock lock(mGuard); + mRefCount++; + if (mRefCount == 1) + { + ICELogInfo(<< "Schedule DirectSound audio input thread"); + mThreadHandle = (HANDLE)_beginthread(&threadProc, 0, this); + } + return true; +} + +void DSoundInputDevice::closeDevice() +{ + ICELogInfo(<<"Close DirectSound audio input"); + Lock l(mGuard); + +#ifdef AUDIO_DUMPINPUT + mDump.close(); +#endif + + if (mBuffer) + { + mBuffer->Stop(); + mBuffer->Release(); + mBuffer = NULL; + } + if (mNotifications) + { + mNotifications->Release(); + mNotifications = NULL; + } + if (mDevice) + { + mDevice->Release(); + mDevice = NULL; + } + else + return; + + ::CoUninitialize(); +} + +void DSoundInputDevice::close() +{ + { + Lock l(mGuard); + mRefCount--; + if (mRefCount != 0) + return; + + // Set shutdown signal + if (!mThreadHandle) + return; + + ::SetEvent(mShutdownSignal); + } + + ::WaitForSingleObject(mThreadHandle, INFINITE); + mThreadHandle = 0; +} + +bool DSoundInputDevice::tryReadBuffer(void* buffer) +{ + // Ensure device exists + if (!mDevice) + { + setSimulate( true ); + return false; + } + + if (mQueue.size() >= AUDIO_MIC_BUFFER_SIZE) + { + memcpy(buffer, mQueue.data(), AUDIO_MIC_BUFFER_SIZE); + if (mEnableDenoiser && AUDIO_CHANNELS == 1) + mDenoiser.fromMic(buffer, AUDIO_MIC_BUFFER_LENGTH); + +#ifdef AUDIO_DUMPINPUT + mDump.write(buffer, AUDIO_MIC_BUFFER_SIZE); +#endif + mQueue.erase(0, AUDIO_MIC_BUFFER_SIZE); + return true; + } + + try + { + if (::WaitForSingleObject(mEventArray[mNextBuffer].hEventNotify, AUDIO_MIC_BUFFER_COUNT * AUDIO_MIC_BUFFER_LENGTH * 4) != WAIT_OBJECT_0) + { + setSimulate( true ); + return false; + } + + // See if all other buffers are signaled + if (::WaitForMultipleObjects(AUDIO_MIC_BUFFER_COUNT, mEventSignals, TRUE, 0) != WAIT_TIMEOUT) + { + // Possible overflow. Consider current buffer resulting. Reset ALL events. + for (int i = 0; iLock(mReadOffset, AUDIO_MIC_BUFFER_SIZE, &ptr1, &len1, &ptr2, &len2, 0)); + + // Copy&Enqueue captured data to mQueue + if (ptr1 && len1) + mQueue.appendBuffer(ptr1, len1); + + if (ptr2 && len2) + mQueue.appendBuffer(ptr2, len2); + + DSoundHelper::checkComResult(mBuffer->Unlock(ptr1, len1, ptr2, len2)); + if (mQueue.size() >= AUDIO_MIC_BUFFER_SIZE) + { + memcpy(buffer, mQueue.data(), AUDIO_MIC_BUFFER_SIZE); + if (mEnableDenoiser && AUDIO_CHANNELS == 1) + mDenoiser.fromMic(buffer, AUDIO_MIC_BUFFER_LENGTH); + +#ifdef AUDIO_DUMPINPUT + mDump.write(buffer, AUDIO_MIC_BUFFER_SIZE); +#endif + mQueue.erase(0, AUDIO_MIC_BUFFER_SIZE); + } + else + return false; + + return true; + } + catch(...) + { + setSimulate( true ); + } + return false; +} + +void DSoundInputDevice::setSimulate(bool s) +{ + if (!mSimulate && s) + mNullAudio.start(); + else + if (mSimulate && !s) + mNullAudio.stop(); + + mSimulate = s; +} + +Format DSoundInputDevice::getFormat() +{ + return Format(); +} + +int DSoundInputDevice::readBuffer(void* buffer) +{ + //Lock lock(mGuard); + if (mRefCount <= 0 || isSimulate()) + return 0; + + // Check for finished buffer + if (!tryReadBuffer(buffer)) + return 0; + + return AUDIO_MIC_BUFFER_SIZE; +} + +void DSoundInputDevice::threadProc(void* arg) +{ + DSoundInputDevice* impl = (DSoundInputDevice*)arg; + + impl->openDevice(); + + while (true) + { + // Poll for shutdown signal + if (::WaitForSingleObject(impl->mShutdownSignal, 0) == WAIT_OBJECT_0) + break; + + // Preset buffer with silence + memset(impl->mTempBuffer, 0, AUDIO_MIC_BUFFER_SIZE); + + // Try to read buffer + if (!impl->readBuffer(impl->mTempBuffer)) + { + // Introduce delay here to simulate true audio + impl->mNullAudio.waitForBuffer(); + } + + // Distribute the captured buffer + if (impl->connection()) + impl->connection()->onMicData(impl->getFormat(), impl->mTempBuffer, AUDIO_MIC_BUFFER_SIZE); + } + + impl->closeDevice(); +} + + +DSoundOutputDevice::DSoundOutputDevice(GUID deviceId) +:mDevice(NULL), mPrimaryBuffer(NULL), mBuffer(NULL), +mWriteOffset(0), mPlayedSamples(0), mTotalPlayed(0), mTail(0), +mThreadHandle(0), mSimulate(false), mGUID(deviceId), +mNullAudio(AUDIO_SPK_BUFFER_LENGTH, AUDIO_SPK_BUFFER_COUNT) +{ + gDSoundInit.load(); + mShutdownSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL); + mBufferSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL); + mRefCount = 0; +} + + +DSoundOutputDevice::~DSoundOutputDevice() +{ + close(); + + // Destroy used signals + ::CloseHandle(mShutdownSignal); + ::CloseHandle(mBufferSignal); + gDSoundInit.unload(); +} + +bool DSoundOutputDevice::open() +{ + ICELogInfo(<< "Request to DirectSound audio output"); + // Start thread + mRefCount++; + if (mRefCount == 1) + { + ICELogInfo(<< "Schedule DirectSound audio output thread"); + mThreadHandle = (HANDLE)_beginthread(&threadProc, 0, this); + ::SetThreadPriority(mThreadHandle, THREAD_PRIORITY_TIME_CRITICAL); + } + return true; +} + +void DSoundOutputDevice::close() +{ + if (mRefCount == 0) + return; + mRefCount--; + if (mRefCount > 0) + return; + + // Tell the thread to exit + SetEvent(mShutdownSignal); + + // Wait for thread + if (mThreadHandle) + WaitForSingleObject(mThreadHandle, INFINITE); + mThreadHandle = 0; +} + +void DSoundOutputDevice::openDevice() +{ + ICELogInfo(<< "Open DirectSound audio output"); + if (IsEqualGUID(mGUID, GUID_NULL)) + { + setSimulate( true ); + return; + } + + mWriteOffset = 0; + mPlayedSamples = 0; + mSentBytes = 0; + mPlayCursor = 0; + mBufferSize = AUDIO_SPK_BUFFER_COUNT * AUDIO_SPK_BUFFER_SIZE; + + DSoundHelper::checkComResult(gDSoundInit.mRoutines.DirectSoundCreate8(&mGUID, &mDevice, NULL)); + DSoundHelper::checkComResult(mDevice->SetCooperativeLevel(::GetDesktopWindow(), DSSCL_PRIORITY)); + + WAVEFORMATEX wfx; + memset(&wfx, 0, sizeof(wfx)); + + wfx.cbSize = sizeof(wfx); + wfx.nChannels = AUDIO_CHANNELS; + wfx.nSamplesPerSec = AUDIO_SAMPLERATE; + wfx.wBitsPerSample = 16; + wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + wfx.wFormatTag = WAVE_FORMAT_PCM; + + DSBUFFERDESC dsbd; + ZeroMemory(&dsbd, sizeof(dsbd)); + dsbd.dwSize = sizeof(DSBUFFERDESC); + dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; + dsbd.dwBufferBytes = 0; + dsbd.lpwfxFormat = NULL;//&wfx; + dsbd.guid3DAlgorithm = DS3DALG_DEFAULT; + + DSoundHelper::checkComResult(mDevice->CreateSoundBuffer(&dsbd, &mPrimaryBuffer, NULL )); + DSBCAPS caps; + caps.dwSize = sizeof(caps); + caps.dwFlags = 0; + caps.dwBufferBytes = 0; + caps.dwPlayCpuOverhead = 0; + caps.dwUnlockTransferRate = 0; + + DSoundHelper::checkComResult(mPrimaryBuffer->GetCaps(&caps)); + + dsbd.dwSize = sizeof(caps); + dsbd.dwFlags = DSBCAPS_GLOBALFOCUS; + dsbd.lpwfxFormat = &wfx; + dsbd.guid3DAlgorithm = DS3DALG_DEFAULT; + dsbd.dwBufferBytes = mBufferSize; + + DSoundHelper::checkComResult(mDevice->CreateSoundBuffer(&dsbd, &mBuffer, NULL)); + + // Fill the buffer with silence + LPVOID ptr1 = NULL, ptr2 = NULL; DWORD len1 = 0, len2 = 0; + DSoundHelper::checkComResult(mBuffer->Lock(0, AUDIO_SPK_BUFFER_SIZE * AUDIO_SPK_BUFFER_COUNT, &ptr1, &len1, &ptr2, &len2, 0)); + if (len1 && ptr1) + memset(ptr1, 0, len1); + if (len2 && ptr2) + memset(ptr2, 0, len2); + DSoundHelper::checkComResult(mBuffer->Unlock(ptr1, len1, ptr2, len2)); + DSoundHelper::checkComResult(mBuffer->Play(0,0,DSBPLAY_LOOPING)); + mBuffer->GetCurrentPosition(NULL, &mWriteCursor); +} + +void DSoundOutputDevice::closeDevice() +{ + if (mBuffer) + { + mBuffer->Stop(); + mBuffer->Release(); + mBuffer = NULL; + } + + if (mPrimaryBuffer) + { + mPrimaryBuffer->Stop(); + mPrimaryBuffer->Release(); + mPrimaryBuffer = NULL; + } + + if (mDevice) + { + mDevice->Release(); + mDevice = NULL; + } +} + +void DSoundOutputDevice::restoreBuffer() +{ + if (mSimulate) + return; + + DWORD status = 0; + DSoundHelper::checkComResult(mBuffer->GetStatus(&status)); + if (DSBSTATUS_BUFFERLOST == status) + DSoundHelper::checkComResult(mBuffer->Restore()); +} + +bool DSoundOutputDevice::getMediaFrame() +{ + try + { + memset(mMediaFrame, 0, sizeof mMediaFrame); + if (mConnection) + mConnection->onSpkData(getFormat(), mMediaFrame, sizeof mMediaFrame); + } + catch(...) + {} + + return true; +} + +bool DSoundOutputDevice::process() +{ + if (mSimulate) + return false; + + // Find amount of written data from last call + DWORD cursor = 0; + DSoundHelper::checkComResult(mBuffer->GetCurrentPosition(NULL, &cursor)); + unsigned written; + if (cursor < mWriteCursor) + written = mBufferSize - mWriteCursor + cursor; + else + written = cursor - mWriteCursor; + + mWriteCursor += (written / AUDIO_SPK_BUFFER_SIZE) * AUDIO_SPK_BUFFER_SIZE; + mWriteCursor %= mBufferSize; + bool finished = false; + for (unsigned frameIndex = 0; frameIndex < written / AUDIO_SPK_BUFFER_SIZE && !finished; frameIndex++) + { + unsigned offset = mWriteOffset + frameIndex * AUDIO_SPK_BUFFER_SIZE; + offset %= mBufferSize; + + // See what we can write + LPVOID ptr1 = NULL, ptr2 = NULL; DWORD len1 = 0, len2 = 0; + DSoundHelper::checkComResult(mBuffer->Lock(offset, AUDIO_SPK_BUFFER_SIZE, &ptr1, &len1, &ptr2, &len2, 0)); + + assert(ptr2 == NULL); + assert(len1 >= AUDIO_SPK_BUFFER_SIZE); + + if (getMediaFrame()) + finished = true; + memmove(ptr1, mMediaFrame, AUDIO_SPK_BUFFER_SIZE); + DSoundHelper::checkComResult(mBuffer->Unlock(ptr1, AUDIO_SPK_BUFFER_SIZE, ptr2, 0)); + } + + // Increase write offset + mWriteOffset += (written / AUDIO_SPK_BUFFER_SIZE) * AUDIO_SPK_BUFFER_SIZE; + mWriteOffset %= mBufferSize; + + return true; +} + + +void DSoundOutputDevice::threadProc(void* arg) +{ + DSoundOutputDevice* impl = (DSoundOutputDevice*)arg; + impl->openDevice(); + + DWORD waitResult = 0; + HANDLE waitArray[2] = {impl->mBufferSignal, impl->mShutdownSignal}; + unsigned exitCount = 0; + bool exitSignal = false; + while (true) + { + // Poll for shutdown signal + if (WAIT_OBJECT_0 == ::WaitForSingleObject(impl->mShutdownSignal, 0)) + break; + + if (impl->isSimulate()) + { + impl->mNullAudio.waitForBuffer(); + impl->getMediaFrame(); + } + else + { + // Poll events + waitResult = ::WaitForMultipleObjects(2, waitArray, FALSE, 5); + if (waitResult == WAIT_OBJECT_0 + 1) + break; + try + { + impl->restoreBuffer(); + impl->process(); + } + catch(const Exception& e) + { + ICELogCritical(<< "DirectSound output failed with code = " << e.code() << ", subcode = " << e.subcode()); + impl->setSimulate(true); + } + catch(...) + { + ICELogCritical(<< "DirectSound output failed due to unexpected exception."); + impl->setSimulate(true); + } + } + } + impl->closeDevice(); +} + +unsigned DSoundOutputDevice::playedTime() const +{ + return 0; +} + + +void DSoundOutputDevice::setSimulate(bool s) +{ + mSimulate = s; +} + +bool DSoundOutputDevice::isSimulate() const +{ + return mSimulate; +} + +Format DSoundOutputDevice::getFormat() +{ + return Format(); +} + +bool DSoundOutputDevice::closing() +{ + return false; +} + +typedef WINUSERAPI HRESULT (WINAPI *LPFNDLLGETCLASSOBJECT) (const CLSID &, const IID &, void **); + +HRESULT DirectSoundPrivateCreate (OUT LPKSPROPERTYSET * ppKsPropertySet) +{ + HMODULE hLibDsound = NULL; + LPFNDLLGETCLASSOBJECT pfnDllGetClassObject = NULL; + LPCLASSFACTORY pClassFactory = NULL; + LPKSPROPERTYSET pKsPropertySet = NULL; + HRESULT hr = DS_OK; + + // Load dsound.dll + hLibDsound = LoadLibrary(TEXT("dsound.dll")); + + if(!hLibDsound) + { + hr = DSERR_GENERIC; + } + + // Find DllGetClassObject + if(SUCCEEDED(hr)) + { + pfnDllGetClassObject = + (LPFNDLLGETCLASSOBJECT)GetProcAddress ( hLibDsound, "DllGetClassObject" ); + + + if(!pfnDllGetClassObject) + { + hr = DSERR_GENERIC; + } + } + + // Create a class factory object + if(SUCCEEDED(hr)) + { + hr = pfnDllGetClassObject (CLSID_DirectSoundPrivate, IID_IClassFactory, (LPVOID *)&pClassFactory ); + } + + // Create the DirectSoundPrivate object and query for an IKsPropertySet + // interface + if(SUCCEEDED(hr)) + { + hr = pClassFactory->CreateInstance ( NULL, IID_IKsPropertySet, (LPVOID *)&pKsPropertySet ); + } + + // Release the class factory + if(pClassFactory) + { + pClassFactory->Release(); + } + + // Handle final success or failure + if(SUCCEEDED(hr)) + { + *ppKsPropertySet = pKsPropertySet; + } + else if(pKsPropertySet) + { + pKsPropertySet->Release(); + } + + FreeLibrary(hLibDsound); + + return hr; +} + +BOOL GetInfoFromDSoundGUID( GUID i_sGUID, int &dwWaveID) +{ + LPKSPROPERTYSET pKsPropertySet = NULL; + HRESULT hr; + BOOL retval = FALSE; + + PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA psDirectSoundDeviceDescription = NULL; + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA sDirectSoundDeviceDescription; + + memset(&sDirectSoundDeviceDescription,0,sizeof(sDirectSoundDeviceDescription)); + hr = DirectSoundPrivateCreate( &pKsPropertySet ); + if(SUCCEEDED(hr)) + { + ULONG ulBytesReturned = 0; + sDirectSoundDeviceDescription.DeviceId = i_sGUID; + + // On the first call the final size is unknown so pass the size of the struct in order to receive + // "Type" and "DataFlow" values, ulBytesReturned will be populated with bytes required for struct+strings. + hr = pKsPropertySet->Get(DSPROPSETID_DirectSoundDevice, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION, + NULL, + 0, + &sDirectSoundDeviceDescription, + sizeof(sDirectSoundDeviceDescription), + &ulBytesReturned + ); + + if (ulBytesReturned) + { + // On the first call it notifies us of the required amount of memory in order to receive the strings. + // Allocate the required memory, the strings will be pointed to the memory space directly after the struct. + psDirectSoundDeviceDescription = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA)new BYTE[ulBytesReturned]; + *psDirectSoundDeviceDescription = sDirectSoundDeviceDescription; + + hr = pKsPropertySet->Get(DSPROPSETID_DirectSoundDevice, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION, + NULL, + 0, + psDirectSoundDeviceDescription, + ulBytesReturned, + &ulBytesReturned + ); + + dwWaveID = psDirectSoundDeviceDescription->WaveDeviceId; + /*Description = psDirectSoundDeviceDescription->Description; + Module = psDirectSoundDeviceDescription->Module; + Interface = psDirectSoundDeviceDescription->Interface;*/ + delete [] psDirectSoundDeviceDescription; + retval = TRUE; + } + + pKsPropertySet->Release(); + } + + return retval; +} + +struct EnumResult +{ + int mDeviceId; + GUID mGuid; +}; + +BOOL CALLBACK DSEnumCallback( + LPGUID lpGuid, + LPCTSTR lpcstrDescription, + LPCTSTR lpcstrModule, + LPVOID lpContext + ) +{ + if (lpGuid) + { + + int devId = -1; + GetInfoFromDSoundGUID(*lpGuid, devId); + EnumResult* er = (EnumResult*)lpContext; + if (er->mDeviceId == devId) + { + er->mGuid = *lpGuid; + return FALSE; + } + else + return TRUE; + } + else + return TRUE; +} + + +GUID DSoundHelper::deviceId2Guid(int deviceId, bool captureDevice) +{ + EnumResult er; + er.mDeviceId = deviceId; + er.mGuid = GUID_NULL; + memset(&er.mGuid, 0, sizeof er.mGuid); + if (captureDevice) + DirectSoundCaptureEnumerate(DSEnumCallback, &er); + else + DirectSoundEnumerate(DSEnumCallback, &er); + + return er.mGuid; +} + +void DSoundHelper::checkComResult(HRESULT code) +{ + if (FAILED(code)) + throw Exception(ERR_DSOUND); +} + +#endif diff --git a/src/engine/audio/Audio_DirectSound.h b/src/engine/audio/Audio_DirectSound.h new file mode 100644 index 00000000..65e686ec --- /dev/null +++ b/src/engine/audio/Audio_DirectSound.h @@ -0,0 +1,187 @@ +/* Copyright(C) 2007-2017 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __AUDIO_DSOUND_H +#define __AUDIO_DSOUND_H + +#include "../config.h" + +#include +#include +#include + +#include "../Helper/HL_Sync.h" +#include "../Helper/HL_ByteBuffer.h" +#include "Audio_WavFile.h" +#include "Audio_Interface.h" +#include "Audio_Helper.h" + +#include +#include +#include +#if defined(_MSC_VER) +# include +#endif +#include +#include +#include +#include + +namespace Audio +{ + class VistaEnumerator: public Enumerator + { + public: + VistaEnumerator(); + ~VistaEnumerator(); + + void open(int direction); + void close(); + + int count(); + std::tstring nameAt(int index); + int idAt(int index); + int indexOfDefaultDevice(); + + protected: + IMMDeviceCollection* mCollection; + IMMDevice* mDefaultDevice; + IMMDeviceEnumerator* mEnumerator; + EDataFlow mDirection; + std::vector mNameList; + + void enumerate(); + IMMDevice* mapIndexToInterface(int index); + }; + + class XpEnumerator: public Enumerator + { + public: + XpEnumerator(); + ~XpEnumerator(); + + void open(int direction); + void close(); + + int count(); + std::tstring nameAt(int index); + int idAt(int index); + int indexOfDefaultDevice(); + + protected: + std::vector mNameList; + int mDirection; + }; + + class DSoundHelper + { + public: + static void checkComResult(HRESULT code); + static GUID deviceId2Guid(int deviceId, bool captureDevice); + }; + +#if !defined(_MSC_VER) + typedef struct IDirectSoundNotify8 *LPDIRECTSOUNDNOTIFY8; +#endif + + class DSoundInputDevice: public InputDevice + { + public: + DSoundInputDevice(GUID deviceId); + ~DSoundInputDevice(); + + void enableDenoiser(bool enable); + bool open(); + void close(); + + bool isSimulate() const; + void setSimulate(bool s); + + int readBuffer(void* buffer); + Format getFormat(); + + protected: + Mutex mGuard; /// Mutex to protect this instance. + LPDIRECTSOUNDCAPTURE8 mDevice; + LPDIRECTSOUNDCAPTUREBUFFER8 mBuffer; + LPDIRECTSOUNDNOTIFY8 mNotifications; + DSBPOSITIONNOTIFY mEventArray[AUDIO_MIC_BUFFER_COUNT]; + HANDLE mEventSignals[AUDIO_MIC_BUFFER_COUNT]; // Helper array to make WaitForMultipleObjects in loop + + int mBufferIndex; + int mNextBuffer; + GUID mGUID; + + HANDLE mThreadHandle; + HANDLE mShutdownSignal; + volatile bool mSimulate; /// Marks if simulate mode is active. + int mRefCount; + ByteBuffer mQueue; + unsigned mReadOffset; + DenoiseFilter mDenoiser; + volatile bool mEnableDenoiser; + char mTempBuffer[AUDIO_MIC_BUFFER_SIZE]; + StubTimer mNullAudio; + +#ifdef AUDIO_DUMPINPUT + WavFileWriter mDump; +#endif + + bool tryReadBuffer(void* buffer); + void openDevice(); + void closeDevice(); + + static void threadProc(void* arg); + }; + + class DSoundOutputDevice: public OutputDevice + { + public: + DSoundOutputDevice(GUID deviceId); + ~DSoundOutputDevice(); + + bool open(); + void close(); + + unsigned playedTime() const; + bool isSimulate() const; + void setSimulate(bool s); + bool closing(); + Format getFormat(); + + protected: + Mutex mGuard; /// Mutex to protect this instance + int mDeviceID; + LPDIRECTSOUND8 mDevice; + LPDIRECTSOUNDBUFFER mPrimaryBuffer; + LPDIRECTSOUNDBUFFER mBuffer; + GUID mGUID; + unsigned mWriteOffset; + unsigned mPlayedSamples; + unsigned mSentBytes; + DWORD mPlayCursor; // Measured in bytes + unsigned mBufferSize; + unsigned mTotalPlayed; // Measured in bytes + unsigned mTail; // Measured in bytes + HANDLE mShutdownSignal; + HANDLE mBufferSignal; + HANDLE mThreadHandle; + bool mSimulate; + StubTimer mNullAudio; + DWORD mWriteCursor; + char mMediaFrame[AUDIO_SPK_BUFFER_SIZE]; + unsigned mRefCount; + + void openDevice(); + void closeDevice(); + void restoreBuffer(); + bool process(); + bool getMediaFrame(); + + static void threadProc(void* arg); + }; +} + +#endif diff --git a/src/engine/audio/Audio_Helper.cpp b/src/engine/audio/Audio_Helper.cpp new file mode 100644 index 00000000..2e08c7d9 --- /dev/null +++ b/src/engine/audio/Audio_Helper.cpp @@ -0,0 +1,148 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifdef TARGET_WIN +# include +#endif + +#include "Audio_Helper.h" +#include "../helper/HL_Exception.h" + +using namespace Audio; + +// --- QPCSource +TimeSource::TimeSource(int quantTime, int nrOfQuants) +{ +#ifdef TARGET_WIN + mCounter.QuadPart = 0; +#endif +#if defined(TARGET_OSX) || defined(TARGET_IOS) + mach_timebase_info(&mTimebase); + mRatio = ((double)mTimebase.numer / (double)mTimebase.denom) / 1000000; + +#endif + mQuantTime = quantTime; + mDepthTime = quantTime * nrOfQuants; + mTailTime = 0; +} + +TimeSource::~TimeSource() +{ +} + +void TimeSource::start() +{ +#ifdef TARGET_WIN + if (!QueryPerformanceFrequency(&mFreq)) + throw Exception(ERR_QPC, GetLastError()); + if (!QueryPerformanceCounter(&mCounter)) + throw Exception(ERR_QPC, GetLastError()); +#endif +} + +void TimeSource::stop() +{ +} + +unsigned TimeSource::time() +{ +#ifdef TARGET_WIN + LARGE_INTEGER c; + if (!QueryPerformanceCounter(&c)) + throw Exception(ERR_QPC, GetLastError()); + + //find the f + double f = (double)mFreq.QuadPart / 1000.0; + + //find the difference + unsigned __int64 diff = c.QuadPart - mCounter.QuadPart; + + mCounter.QuadPart = c.QuadPart; + + diff = (unsigned __int64)((double)diff / f + 0.5); //get ms + diff += mTailTime; + + if (diff > mDepthTime) + { + mTailTime = 0; + return mDepthTime; + } + else + { + mTailTime = (unsigned )(diff % (unsigned __int64)mQuantTime); + unsigned int t = (unsigned )(diff / (unsigned __int64)mQuantTime); + return t * mQuantTime; + } +#endif +#if defined(TARGET_OSX) || defined(TARGET_IOS) + uint64_t t = mach_absolute_time(); + uint64_t c = uint64_t((double)t * mRatio + 0.5); + + uint64_t diff = c - this->mTime + mTailTime; + mTime = c; + if (diff > mDepthTime) + { + mTailTime = 0; + return mDepthTime; + } + else + { + mTailTime = diff % mQuantTime; + uint64_t t = diff / mQuantTime; + return t * mQuantTime; + } +#endif +#if defined(TARGET_LINUX) + assert(0); +#endif +} + +// --- StubTimer --- +StubTimer::StubTimer(int bufferTime, int bufferCount) +:mBufferTime(bufferTime), mBufferCount(bufferCount), mTimeSource(bufferTime, bufferCount), mActive(false) +{ +#ifdef TARGET_WIN + mStubSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL); +#endif +} + +StubTimer::~StubTimer() +{ +#ifdef TARGET_WIN + ::CloseHandle(mStubSignal); +#endif +} + +void StubTimer::start() +{ + mTimeSource.start(); + mCurrentTime = mTimeSource.time(); + mActive = true; +} + +void StubTimer::stop() +{ + mTimeSource.stop(); + mActive = false; +} + +void StubTimer::waitForBuffer() +{ + if (!mActive) + start(); + + unsigned t = mTimeSource.time(); + + while (!t) + { +#ifdef TARGET_WIN + ::WaitForSingleObject(mStubSignal, mBufferTime); +#endif +#if defined(TARGET_OSX) || defined(TARGET_IOS) + usleep(100); +#endif + t = mTimeSource.time(); + } +} diff --git a/src/engine/audio/Audio_Helper.h b/src/engine/audio/Audio_Helper.h new file mode 100644 index 00000000..e3744522 --- /dev/null +++ b/src/engine/audio/Audio_Helper.h @@ -0,0 +1,78 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __AUDIO_HELPER_H +#define __AUDIO_HELPER_H + +#ifdef TARGET_WIN +#include +#include +#if defined(_MSC_VER) +# include +#endif +#endif + +#if defined(TARGET_OSX) || defined(TARGET_IOS) +# include +# include +# include +# include +#endif + +#include + +#include "Audio_Interface.h" + +namespace Audio +{ + class TimeSource + { + protected: +#ifdef TARGET_WIN + LARGE_INTEGER mCounter; /// Current value from QPC. + LARGE_INTEGER mFreq; /// Current frequency from QPC. +#endif + +#if defined(TARGET_OSX) || defined(TARGET_IOS) + uint64_t mTime; + struct mach_timebase_info mTimebase; + double mRatio; +#endif + + unsigned mQuantTime; /// Used time quants length in milliseconds. + unsigned mDepthTime; /// Number of available time quants. + unsigned mTailTime; /// Not-accounted milliseconds. + + public: + TimeSource(int quantTime, int nrOfQuants); + ~TimeSource(); + + void start(); + void stop(); + unsigned time(); + }; + + class StubTimer + { + public: + StubTimer(int bufferTime, int bufferCount); + ~StubTimer(); + void start(); + void stop(); + void waitForBuffer(); + + protected: + unsigned mBufferTime; + unsigned mBufferCount; + unsigned mCurrentTime; + TimeSource mTimeSource; +#ifdef TARGET_WIN + HANDLE mStubSignal; +#endif + bool mActive; + }; +} + +#endif diff --git a/src/engine/audio/Audio_Interface.cpp b/src/engine/audio/Audio_Interface.cpp new file mode 100644 index 00000000..c8a7944f --- /dev/null +++ b/src/engine/audio/Audio_Interface.cpp @@ -0,0 +1,153 @@ +/* Copyright(C) 2007-2017 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "Audio_Interface.h" +#include "../helper/HL_OsVersion.h" + +#if !defined(USE_NULL_AUDIO) +# ifdef TARGET_WIN +# include "Audio_Wmme.h" +# include "Audio_DirectSound.h" +# endif +# ifdef TARGET_OSX +# include "Audio_CoreAudio.h" +# endif +# ifdef TARGET_ANDROID +# include "Audio_Android.h" +# endif +#endif + +#include "Audio_Helper.h" +#include "Audio_Null.h" + +using namespace Audio; + +Device::Device() +:mConnection(nullptr) +{ +} + +Device::~Device() +{ +} + + +void Device::setConnection(DataConnection* connection) +{ + mConnection = connection; +} + +DataConnection* Device::connection() +{ + return mConnection; +} + +InputDevice::InputDevice() +{ +} + +InputDevice::~InputDevice() +{ +} + +InputDevice* InputDevice::make(int devId) +{ +#if defined(USE_NULL_AUDIO) + return new NullInputDevice(); +#else + #if defined(TARGET_WIN) && defined(_MSC_VER) + // return new WmmeInputDevice(index); + return new DSoundInputDevice(DSoundHelper::deviceId2Guid(devId, true)); + #endif + #ifdef TARGET_OSX + return new MacInputDevice(devId); + #endif + #ifdef TARGET_ANDROID + return new AndroidInputDevice(devId); + #endif +#endif + return nullptr; +} + +OutputDevice::OutputDevice() +{ +} + +OutputDevice::~OutputDevice() +{ +} + +OutputDevice* OutputDevice::make(int devId) +{ +#if defined(USE_NULL_AUDIO) + return new NullOutputDevice(); +#else + #if defined(TARGET_WIN) + //return new WmmeOutputDevice(index); + return new DSoundOutputDevice(DSoundHelper::deviceId2Guid(devId, false)); + #endif + #ifdef TARGET_OSX + return new MacOutputDevice(devId); + #endif + #ifdef TARGET_ANDROID + return new AndroidOutputDevice(devId); + #endif +#endif + return nullptr; +} + + +// --- Enumerator --- +Enumerator::Enumerator() +{ +} + +Enumerator::~Enumerator() +{ +} + +int Enumerator::nameToIndex(const std::tstring& name) +{ + for (int i = 0; i < count(); i++) + if (nameAt(i) == name) + return i; + return -1; +} + + +Enumerator* Enumerator::make(bool useNull) +{ + + if (useNull) + return new NullEnumerator(); +#ifndef USE_NULL_AUDIO + + #ifdef TARGET_WIN + if (winVersion() > Win_Xp) + return new VistaEnumerator(); + else + return new XpEnumerator(); + #endif + #ifdef TARGET_OSX + return new MacEnumerator(); + #endif +#endif + return new NullEnumerator(); +} + +// ----- OsEngine ------------ + +OsEngine* OsEngine::instance() +{ +#ifdef USE_NULL_AUDIO + return nullptr; +#endif + +#ifdef TARGET_ANDROID + return &OpenSLEngine::instance(); +#endif + + return nullptr; +} diff --git a/src/engine/audio/Audio_Interface.h b/src/engine/audio/Audio_Interface.h new file mode 100644 index 00000000..6bcc04ea --- /dev/null +++ b/src/engine/audio/Audio_Interface.h @@ -0,0 +1,135 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __AUDIO_INTERFACE_H +#define __AUDIO_INTERFACE_H + +#include +#include "../config.h" +#include "../helper/HL_Types.h" +#include "../helper/HL_VariantMap.h" +#include "../helper/HL_Pointer.h" +#include "Audio_WavFile.h" +#include "Audio_Quality.h" + +namespace Audio +{ + enum + { + myMicrophone = 1, + mySpeaker = 2 + }; + + struct Format + { + int mRate; + int mChannels; + + Format() + :mRate(AUDIO_SAMPLERATE), mChannels(AUDIO_CHANNELS) + {} + + Format(int rate, int channels) + :mRate(rate), mChannels(channels) + {} + + int samplesFromSize(int length) const + { + return length / 2 / mChannels; + } + + // Returns milliseconds + float timeFromSize(int length) const + { + return float(samplesFromSize(length) / (mRate / 1000.0)); + } + + float sizeFromTime(int milliseconds) const + { + return float((milliseconds * mRate) / 500.0 * mChannels); + } + + std::string toString() + { + char buffer[64]; + sprintf(buffer, "%dHz %dch", mRate, mChannels); + return std::string(buffer); + } + }; + + class DataConnection + { + public: + virtual void onMicData(const Format& format, const void* buffer, int length) = 0; + virtual void onSpkData(const Format& format, void* buffer, int length) = 0; + }; + + + class Device + { + public: + Device(); + virtual ~Device(); + + void setConnection(DataConnection* connection); + DataConnection* connection(); + + virtual bool open() = 0; + virtual void close() = 0; + virtual Format getFormat() = 0; + protected: + DataConnection* mConnection; + }; + + + class InputDevice: public Device + { + public: + InputDevice(); + virtual ~InputDevice(); + + static InputDevice* make(int devId); + }; + typedef std::shared_ptr PInputDevice; + + class OutputDevice: public Device + { + public: + OutputDevice(); + virtual ~OutputDevice(); + + static OutputDevice* make(int devId); + }; + typedef std::shared_ptr POutputDevice; + + class Enumerator + { + public: + Enumerator(); + virtual ~Enumerator(); + int nameToIndex(const std::tstring& name); + + virtual void open(int direction) = 0; + virtual void close() = 0; + + virtual int count() = 0; + virtual std::tstring nameAt(int index) = 0; + virtual int idAt(int index) = 0; + virtual int indexOfDefaultDevice() = 0; + + static Enumerator* make(bool useNull = false); + }; + + class OsEngine + { + public: + virtual void open() = 0; + virtual void close() = 0; + + static OsEngine* instance(); + }; +}; + +#endif diff --git a/src/engine/audio/Audio_Mixer.cpp b/src/engine/audio/Audio_Mixer.cpp new file mode 100644 index 00000000..25eb1b22 --- /dev/null +++ b/src/engine/audio/Audio_Mixer.cpp @@ -0,0 +1,330 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "../config.h" +#include "../helper/HL_Exception.h" +#include "Audio_Mixer.h" +#include +#include "../helper/HL_Log.h" + +#define LOG_SUBSYSTEM "Mixer" +using namespace Audio; + +Mixer::Stream::Stream() +{ + mResampler8.start(AUDIO_CHANNELS, 8000, AUDIO_SAMPLERATE); + mResampler16.start(AUDIO_CHANNELS, 16000, AUDIO_SAMPLERATE); + mResampler32.start(AUDIO_CHANNELS, 32000, AUDIO_SAMPLERATE); + mResampler48.start(AUDIO_CHANNELS, 48000, AUDIO_SAMPLERATE); + mActive = false; + mContext = NULL; + mSSRC = 0; + mFadeOutCounter = 0; + mData.setCapacity(AUDIO_SPK_BUFFER_SIZE * AUDIO_SPK_BUFFER_COUNT); +} + +Mixer::Stream::~Stream() +{ +} + +void Mixer::Stream::setSsrc(unsigned ssrc) +{ + mSSRC = ssrc; +} + +unsigned Mixer::Stream::ssrc() +{ + return mSSRC; +} + +void Mixer::Stream::setContext(void* context) +{ + mContext = context; +} +void* Mixer::Stream::context() +{ + return mContext; +} + +DataWindow& Mixer::Stream::data() +{ + return mData; +} + +bool Mixer::Stream::active() +{ + return mActive; +} + +void Mixer::Stream::setActive(bool active) +{ + mActive = active; +} + +void Mixer::Stream::addPcm(int rate, const void* input, int length) +{ + // Resample to internal sample rate + unsigned outputSize = unsigned(0.5 + length * ((float)AUDIO_SAMPLERATE / rate)); + if (mTempBuffer.size() < outputSize) + mTempBuffer.resize(outputSize); + + Resampler* resampler = (rate == 8000) ? &mResampler8 : ((rate == 16000) ? &mResampler16 : ((rate == 32000) ? &mResampler32 : &mResampler48)); + int inputProcessed = 0; + resampler->processBuffer(input, length, inputProcessed, mTempBuffer.mutableData(), outputSize); + // inputProcessed result value is ignored here - rate will be 8/16/32/48k, inputProcessed is equal to length + + // Queue data + mData.add(mTempBuffer.data(), outputSize); +} + +Mixer::Mixer() +{ + mActiveCounter = 0; + mOutput.setCapacity(32768); +} + +Mixer::~Mixer() +{ +} + +void Mixer::unregisterChannel(void* channel) +{ + for (int i=0; iactive()) + { + channel->setSsrc(ssrc); + channel->setContext(context); + channel->data().clear(); + mActiveCounter++; + channel->setActive(true); + return channel; + } + } + return NULL; +} + +void Mixer::addPcm(void* context, unsigned ssrc, + const void* inputData, int inputLength, + int inputRate, bool fadeOut) +{ + assert(inputRate == 8000 || inputRate == 16000 || inputRate == 32000); + + int i; + + // Locate a channel + Stream* channel = NULL; + + for (i=0; iaddPcm(inputRate, inputData, inputLength); +} + +void Mixer::addPcm(void* context, unsigned ssrc, Audio::DataWindow& w, int rate, bool fadeOut) +{ + assert(rate == 8000 || rate == 16000 || rate == 32000 || rate == 48000); + + int i; + + // Locate a channel + Stream* channel = NULL; + + for (i=0; iaddPcm(rate, w.data(), w.filled()); + //ICELogCritical(<<"Mixer stream " << int(this) << " has " << w.filled() << " bytes"); +} + +void Mixer::mix() +{ + // Current sample + int sample = 0; + + // Counter of processed active channels + int processed = 0; + + // Samples & sources counters + unsigned sampleCounter = 0, sourceCounter; + + short outputBuffer[512]; + unsigned outputCounter = 0; + + // Build active channel map + Stream* channelList[AUDIO_MIX_CHANNEL_COUNT]; + int activeCounter = 0; + for (int i=0; i filled2 ? filled1 : filled2; + + // Find how much samples can be mixed + int filled = mOutput.filled() / 2; + + int maxsize = mOutput.capacity() / 2; + if (maxsize - filled < available) + available = maxsize - filled; + + short sample = 0; + for (int i=0; i i ? audio1.data().shortAt(i) : 0; + short sample2 = filled2 > i ? audio2.data().shortAt(i) : 0; + sample = (abs(sample1) > abs(sample2)) ? sample1 : sample2; + + mOutput.add(sample); + } + audio1.data().erase(available*2); + audio2.data().erase(available*2); + } + else + { + do + { + sample = 0; + sourceCounter = 0; + processed = 0; + for (int i=0; i (int)sampleCounter * 2) + { + short currentSample = audio.data().shortAt(sampleCounter); + if (abs(currentSample) > abs(sample)) + sample = currentSample; + sourceCounter++; + } + } + + if (sourceCounter) + { + outputBuffer[outputCounter++] = (short)sample; + sampleCounter++; + } + + // Check if time to flash output buffer + if ((!sourceCounter || outputCounter == 512) && outputCounter) + { + mOutput.add(outputBuffer, outputCounter * 2); + outputCounter = 0; + } + } + while (sourceCounter); + + processed = 0; + for (int i=0; i +#include + +namespace Audio +{ + class Mixer + { + protected: + class Stream + { + protected: + DataWindow mData; + Resampler mResampler8, + mResampler16, + mResampler32, + mResampler48; + bool mActive; + void* mContext; + unsigned mSSRC; + unsigned mFadeOutCounter; + ByteBuffer mTempBuffer; + + public: + Stream(); + ~Stream(); + + void setSsrc(unsigned ssrc); + unsigned ssrc(); + void setContext(void* context); + void* context(); + DataWindow& data(); + bool active(); + void setActive(bool active); + void addPcm(int rate, const void* input, int length); + }; + + Stream mChannelList[AUDIO_MIX_CHANNEL_COUNT]; + Mutex mMutex; + DataWindow mOutput; + std::atomic_int mActiveCounter; + + void mix(); + Stream* allocateChannel(void* context, unsigned ssrc); + + public: + Mixer(); + ~Mixer(); + + void unregisterChannel(void* context); + void clear(void* context, unsigned ssrc); + void addPcm(void* context, unsigned ssrc, const void* inputData, int inputLength, int inputRate, bool fadeOut); + void addPcm(void* context, unsigned ssrc, Audio::DataWindow& w, int rate, bool fadeOut); + int getPcm(void* outputData, int outputLength); + int mixAndGetPcm(Audio::DataWindow& output); + int available(); + }; +} //end of namespace + +#endif diff --git a/src/engine/audio/Audio_Null.cpp b/src/engine/audio/Audio_Null.cpp new file mode 100644 index 00000000..be80e300 --- /dev/null +++ b/src/engine/audio/Audio_Null.cpp @@ -0,0 +1,177 @@ +#include "Audio_Null.h" +#include "helper/HL_Log.h" +#define LOG_SUBSYSTEM "NULL audio" + +using namespace Audio; + +NullTimer::NullTimer(int interval, Delegate *delegate, const char* name) + :mShutdown(false), mDelegate(delegate), mInterval(interval), mThreadName(name) +{ + start(); +} + +NullTimer::~NullTimer() +{ + stop(); +} + +void NullTimer::start() +{ + mShutdown = false; + mWorkerThread = std::thread(&NullTimer::run, this); +} + +void NullTimer::stop() +{ + mShutdown = true; + if (mWorkerThread.joinable()) + mWorkerThread.join(); +} + +void NullTimer::run() +{ + mTail = 0; + while (!mShutdown) + { + // Get current timestamp + std::chrono::system_clock::time_point timestamp = std::chrono::system_clock::now(); + + while (mTail >= mInterval * 1000) + { + if (mDelegate) + mDelegate->onTimerSignal(*this); + mTail -= mInterval * 1000; + } + + // Sleep for mInterval - mTail milliseconds + std::this_thread::sleep_for(std::chrono::microseconds(mInterval * 1000 - mTail)); + + mTail += std::chrono::duration_cast(std::chrono::system_clock::now() - timestamp).count(); + } +} + +// --------------------- NullInputDevice ------------------------- +NullInputDevice::NullInputDevice() + :mBuffer(nullptr) +{ +} + +NullInputDevice::~NullInputDevice() +{ + close(); +} + +bool NullInputDevice::open() +{ + mBuffer = malloc(AUDIO_MIC_BUFFER_SIZE); + memset(mBuffer, 0, AUDIO_MIC_BUFFER_SIZE); + mTimeCounter = 0; mDataCounter = 0; + // Creation of timer starts it also. So first onTimerSignal can come even before open() returns. + mTimer = std::make_shared(AUDIO_MIC_BUFFER_LENGTH, this, "NullMicrophoneThread"); + return true; +} + +void NullInputDevice::close() +{ + mTimer.reset(); + if (mBuffer) + { + free(mBuffer); + mBuffer = nullptr; + } + ICELogInfo(<<"Pseudocaptured " << mTimeCounter << " milliseconds , " << mDataCounter << " bytes."); +} + +Format NullInputDevice::getFormat() +{ + assert (Format().sizeFromTime(AUDIO_MIC_BUFFER_LENGTH) == AUDIO_MIC_BUFFER_SIZE); + return Format(); +} + +void NullInputDevice::onTimerSignal(NullTimer& timer) +{ + mTimeCounter += AUDIO_MIC_BUFFER_LENGTH; + mDataCounter += AUDIO_MIC_BUFFER_SIZE; + if (mConnection) + mConnection->onMicData(getFormat(), mBuffer, AUDIO_MIC_BUFFER_SIZE); +} + +// --------------------- NullOutputDevice -------------------------- +NullOutputDevice::NullOutputDevice() + :mBuffer(nullptr) +{ +} + +NullOutputDevice::~NullOutputDevice() +{ + close(); +} + + +bool NullOutputDevice::open() +{ + mTimeCounter = 0; mDataCounter = 0; + mBuffer = malloc(AUDIO_SPK_BUFFER_SIZE); + // Creation of timer starts it also. So first onSpkData() can come before open() returns even. + mTimer = std::make_shared(AUDIO_SPK_BUFFER_LENGTH, this, "NullSpeakerThread"); + return true; +} + +void NullOutputDevice::close() +{ + mTimer.reset(); + free(mBuffer); mBuffer = nullptr; + ICELogInfo(<< "Pseudoplayed " << mTimeCounter << " milliseconds, " << mDataCounter << " bytes."); +} + +Format NullOutputDevice::getFormat() +{ + assert (Format().sizeFromTime(AUDIO_SPK_BUFFER_LENGTH) == AUDIO_SPK_BUFFER_SIZE); + return Format(); +} + +void NullOutputDevice::onTimerSignal(NullTimer &timer) +{ + mTimeCounter += AUDIO_SPK_BUFFER_LENGTH; + mDataCounter += AUDIO_SPK_BUFFER_SIZE; + if (mConnection) + mConnection->onSpkData(getFormat(), mBuffer, AUDIO_SPK_BUFFER_SIZE); +} + +// ---------------------- NullEnumerator -------------------------- +NullEnumerator::NullEnumerator() +{} + +NullEnumerator::~NullEnumerator() +{} + +void NullEnumerator::open(int direction) +{} + +void NullEnumerator::close() +{} + +int NullEnumerator::count() +{ + return 1; +} + +std::tstring NullEnumerator::nameAt(int index) +{ +#if defined(TARGET_WIN) + return L"null"; +#else + return "null"; +#endif +} + +int NullEnumerator::idAt(int index) +{ + return 0; +} + +int NullEnumerator::indexOfDefaultDevice() +{ + return 0; +} + diff --git a/src/engine/audio/Audio_Null.h b/src/engine/audio/Audio_Null.h new file mode 100644 index 00000000..d3dc4316 --- /dev/null +++ b/src/engine/audio/Audio_Null.h @@ -0,0 +1,86 @@ +#ifndef __AUDIO_NULL_H +#define __AUDIO_NULL_H + +#include +#include "Audio_Interface.h" + +namespace Audio +{ + class NullTimer + { + public: + class Delegate + { + public: + virtual void onTimerSignal(NullTimer& timer) = 0; + }; + + protected: + std::thread mWorkerThread; + volatile bool mShutdown; + Delegate* mDelegate; + int mInterval, // Interval - wanted number of milliseconds + mTail; // Number of milliseconds that can be sent immediately to sink + std::string mThreadName; + + void start(); + void stop(); + void run(); + public: + /* Interval is in milliseconds. */ + NullTimer(int interval, Delegate* delegate, const char* name = nullptr); + ~NullTimer(); + }; + + class NullInputDevice: public InputDevice, public NullTimer::Delegate + { + protected: + void* mBuffer = nullptr; + std::shared_ptr mTimer; + int64_t mTimeCounter = 0, mDataCounter = 0; + public: + NullInputDevice(); + virtual ~NullInputDevice(); + + bool open() override; + void close() override; + Format getFormat() override; + + void onTimerSignal(NullTimer& timer) override; + }; + + class NullOutputDevice: public OutputDevice, public NullTimer::Delegate + { + protected: + std::shared_ptr mTimer; + void* mBuffer = nullptr; + int64_t mDataCounter = 0, mTimeCounter = 0; + public: + NullOutputDevice(); + virtual ~NullOutputDevice(); + + bool open() override; + void close() override; + Format getFormat() override; + + void onTimerSignal(NullTimer& timer) override; + }; + + class NullEnumerator: public Enumerator + { + public: + NullEnumerator(); + ~NullEnumerator(); + + void open(int direction) override; + void close() override; + + int count() override; + std::tstring nameAt(int index) override; + int idAt(int index) override; + int indexOfDefaultDevice() override; + + }; +} + +#endif diff --git a/src/engine/audio/Audio_Player.cpp b/src/engine/audio/Audio_Player.cpp new file mode 100644 index 00000000..cdb1952d --- /dev/null +++ b/src/engine/audio/Audio_Player.cpp @@ -0,0 +1,167 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "Audio_Player.h" + +using namespace Audio; +// -------------- Player ----------- +Player::Player() +:mDelegate(NULL), mPlayedTime(0) +{ +} + +Player::~Player() +{ +} + +void Player::setDelegate(EndOfAudioDelegate* d) +{ + mDelegate = d; +} + +Player::EndOfAudioDelegate* Player::getDelegate() const +{ + return mDelegate; +} + +void Player::setOutput(POutputDevice output) +{ + mOutput = output; + if (mOutput) + mOutput->setConnection(this); +} + +POutputDevice Player::getOutput() const +{ + return mOutput; +} +void Player::onMicData(const Format& f, const void* buffer, int length) +{ + // Do nothing here - this data sink is not used in player +} + +#define BYTES_PER_MILLISECOND (AUDIO_SAMPLERATE / 1000 * 2 * AUDIO_CHANNELS) + +void Player::onSpkData(const Format& f, void* buffer, int length) +{ + Lock l(mGuard); + + // Fill buffer by zero if player owns dedicated device + if (mOutput) + memset(buffer, 0, length); + + // See if there is item in playlist + int produced = 0; + while (mPlaylist.size() && produced < length) + { + PlaylistItem& item = mPlaylist.front(); + // Check for timelength + if (item.mTimelength > 0 && item.mTimelength < mPlayedTime) + { + onFilePlayed(); + continue; + } + + int wasread = item.mFile->read((char*)buffer+produced, length-produced); + mPlayedTime += float(wasread) / BYTES_PER_MILLISECOND; + produced += wasread; + if (wasread < length-produced) + { + if (item.mLoop) + { + item.mFile->rewind(); + wasread = item.mFile->read((char*)buffer+produced, (length - produced)); + mPlayedTime += float(wasread) / BYTES_PER_MILLISECOND; + produced += wasread; + } + else + onFilePlayed(); + } + } +} + +void Player::onFilePlayed() +{ + // Save usage id to release later from main loop + mFinishedUsages.push_back(mPlaylist.front().mUsageId); + + // Send event + if (mDelegate) + mDelegate->onFilePlayed(mPlaylist.front()); + + // Remove played item & reset played time + mPlaylist.pop_front(); + mPlayedTime = 0; +} + +void Player::obtain(int usage) +{ + Lock l(mGuard); + UsageMap::iterator usageIter = mUsage.find(usage); + if (usageIter == mUsage.end()) + mUsage[usage] = 1; + else + usageIter->second = usageIter->second + 1; + + if (mUsage.size() == 1 && mOutput) + mOutput->open(); +} + +void Player::release(int usage) +{ + Lock l(mGuard); + UsageMap::iterator usageIter = mUsage.find(usage); + if (usageIter == mUsage.end()) + return; + + usageIter->second = usageIter->second - 1; + if (!usageIter->second) + mUsage.erase(usageIter); + + for (unsigned i=0; iclose(); +} + +int Player::releasePlayed() +{ + Lock l(mGuard); + int result = mFinishedUsages.size(); + while (mFinishedUsages.size()) + { + release(mFinishedUsages.front()); + mFinishedUsages.erase(mFinishedUsages.begin()); + } + return result; +} + +void Player::add(int usageId, PWavFileReader file, bool loop, int timelength) +{ + Lock l(mGuard); + PlaylistItem item; + item.mFile = file; + item.mLoop = loop; + item.mTimelength = timelength; + item.mUsageId = usageId; + mPlaylist.push_back(item); + + obtain(usageId); +} + +void Player::clear() +{ + Lock l(mGuard); + while (mPlaylist.size()) + onFilePlayed(); +} + +void Player::retrieveUsageIds(std::vector& ids) +{ + ids.assign(mFinishedUsages.begin(), mFinishedUsages.end()); + mFinishedUsages.clear(); +} diff --git a/src/engine/audio/Audio_Player.h b/src/engine/audio/Audio_Player.h new file mode 100644 index 00000000..614855af --- /dev/null +++ b/src/engine/audio/Audio_Player.h @@ -0,0 +1,67 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __AUDIO_PLAYER_H +#define __AUDIO_PLAYER_H + +#include "../helper/HL_Log.h" +#include "../helper/HL_Sync.h" +#include "Audio_Interface.h" +#include +#include +#include + +namespace Audio +{ + class Player: public DataConnection + { + friend class DevicePair; + public: + struct PlaylistItem + { + PWavFileReader mFile; + bool mLoop; + int mTimelength; + int mUsageId; + }; + typedef std::deque Playlist; + + class EndOfAudioDelegate + { + public: + virtual void onFilePlayed(PlaylistItem& item) = 0; + }; + + protected: + typedef std::map UsageMap; + Audio::POutputDevice mOutput; + UsageMap mUsage; // References map + std::vector mFinishedUsages; // Finished plays + + Mutex mGuard; + Playlist mPlaylist; + float mPlayedTime; + EndOfAudioDelegate* mDelegate; + + void onMicData(const Format& f, const void* buffer, int length); + void onSpkData(const Format& f, void* buffer, int length); + void onFilePlayed(); + void scheduleRelease(); + void obtain(int usageId); + public: + Player(); + ~Player(); + void setDelegate(EndOfAudioDelegate* d); + EndOfAudioDelegate* getDelegate() const; + void setOutput(POutputDevice output); + POutputDevice getOutput() const; + void add(int usageId, PWavFileReader file, bool loop, int timelength); + void release(int usageId); + void clear(); + int releasePlayed(); + void retrieveUsageIds(std::vector& ids); + }; +} +#endif diff --git a/src/engine/audio/Audio_Quality.cpp b/src/engine/audio/Audio_Quality.cpp new file mode 100644 index 00000000..11618413 --- /dev/null +++ b/src/engine/audio/Audio_Quality.cpp @@ -0,0 +1,235 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "../config.h" +#include "Audio_Quality.h" +#include "../helper/HL_Exception.h" +#include "../helper/HL_Types.h" +#include "speex/speex_preprocess.h" + +#ifdef WIN32 +# include +#endif +#include +#include + +using namespace Audio; + +#define SHRT_MAX 32767 /* maximum (signed) short value */ +AgcFilter::AgcFilter(int channels) +{ + static const float DefaultLevel = 0.8f; + + for (int i=0; i 1.0f) + level = 1.0f; + else + if (level < 0.5f) + level = 0.5f; + + c.mIpeak = (int)(SHRT_MAX * level * 65536); + + c.mSilenceCounter = 0; + mChannelList.push_back(c); + } +} + +AgcFilter::~AgcFilter() +{ +} + +void AgcFilter::process(void *pcm, int length) +{ + for (size_t i=0; i (int)channel.mSampleMax) + { + /* update the max */ + channel.mSampleMax = (unsigned int)sample; + } + channel.mCounter ++; + + /* Will we get an overflow with the current gain factor? */ + if (((sample * channel.mIgain) >> 16) > channel.mIpeak) + { + /* Yes: Calculate new gain. */ + channel.mIgain = ((channel.mIpeak / channel.mSampleMax) * 62259) >> 16; + channel.mSilenceCounter = 0; + pcm[sampleIndex] = (short) ((pcm[sampleIndex] * channel.mIgain) >> 16); + continue; + } + + /* Calculate new gain factor 10x per second */ + if (channel.mCounter >= AUDIO_SAMPLERATE / 10) + { + if (channel.mSampleMax > AUDIO_SAMPLERATE / 10) /* speaking? */ + { + gain_new = ((channel.mIpeak / channel.mSampleMax) * 62259) >> 16; + + if (channel.mSilenceCounter > 40) /* pause -> speaking */ + channel.mIgain += (gain_new - channel.mIgain) >> 2; + else + channel.mIgain += (gain_new - channel.mIgain) / 20; + + channel.mSilenceCounter = 0; + } + else /* silence */ + { + channel.mSilenceCounter++; + /* silence > 2 seconds: reduce gain */ + if ((channel.mIgain > 65536) && (channel.mSilenceCounter >= 20)) + channel.mIgain = (channel.mIgain * 62259) >> 16; + } + + channel.mCounter = 0; + channel.mSampleMax = 1; + } + pcm[sampleIndex] = (short) ((pcm[sampleIndex] * channel.mIgain) >> 16); + } +} + +// --- AecFilter --- +#ifdef USE_SPEEX_AEC +# include "speex/speex_echo.h" +#include "Audio_Interface.h" + +#if !defined(TARGET_WIN) +# include +#endif + +#endif + +#ifdef USE_WEBRTC_AEC +# include "aec/echo_cancellation.h" +#endif + +#ifdef USE_WEBRTC_AEC +static void CheckWRACode(unsigned errorcode) +{ + if (errorcode) + throw Exception(ERR_WEBRTC, errorcode); +} +#endif + +AecFilter::AecFilter(int tailTime, int frameTime, int rate) +:mCtx(nullptr), mFrameTime(frameTime), mRate(rate) +{ +#ifdef USE_SPEEX_AEC + if (AUDIO_CHANNELS == 2) + mCtx = speex_echo_state_init_mc(frameTime * (mRate / 1000), tailTime * (mRate / 1000), AUDIO_CHANNELS, AUDIO_CHANNELS ); + else + mCtx = speex_echo_state_init(frameTime * (mRate / 1000), tailTime * (mRate / 1000)); + int tmp = rate; + speex_echo_ctl((SpeexEchoState*)mCtx, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp); +#endif + +#ifdef USE_WEBRTC_AEC + CheckWRACode(WebRtcAec_Create(&mCtx)); + CheckWRACode(WebRtcAec_Init(mCtx, rate, rate)); +#endif +} + +AecFilter::~AecFilter() +{ +#ifdef USE_SPEEX_AEC + if (mCtx) + { + //speex_echo_state_destroy((SpeexEchoState*)mCtx); + mCtx = nullptr; + } +#endif + +#ifdef USE_WEBRTC_AEC + CheckWRACode(WebRtcAec_Free(mCtx)); + mCtx = NULL; +#endif +} + +void AecFilter::fromMic(void *data) +{ +#ifdef USE_SPEEX_AEC + short* output = (short*)alloca(Format().sizeFromTime(AUDIO_MIC_BUFFER_LENGTH)); + speex_echo_capture((SpeexEchoState*)mCtx, (short*)data, (short*)output); + memmove(data, output, AUDIO_MIC_BUFFER_SIZE); +#endif + +#ifdef USE_WEBRTC_AEC + short* inputframe = (short*)ALLOCA(framesize); + memcpy(inputframe, (char*)data+framesize*i, framesize); + CheckWRACode(WebRtcAec_Process(mCtx, (short*)inputframe, NULL, (short*)data+framesize/2*i, NULL, mFrameTime * mRate / 1000, 0,0)); +#endif +} + +void AecFilter::toSpeaker(void *data) +{ +#ifdef USE_SPEEX_AEC + speex_echo_playback((SpeexEchoState*)mCtx, (short*)data); +#endif + +#ifdef USE_WEBRTC_AEC + CheckWRACode(WebRtcAec_BufferFarend(mCtx, (short*)data, length / 2 / AUDIO_CHANNELS)); +#endif +} + +int AecFilter::frametime() +{ + return mFrameTime; +} + + +DenoiseFilter::DenoiseFilter(int rate) +:mRate(rate) +{ + mCtx = speex_preprocess_state_init(mRate/100, mRate); +} + +DenoiseFilter::~DenoiseFilter() +{ + if (mCtx) + speex_preprocess_state_destroy((SpeexPreprocessState*)mCtx); +} + +void DenoiseFilter::fromMic(void* data, int timelength) +{ + assert(timelength % 10 == 0); + + // Process by 10-ms blocks + spx_int16_t* in = (spx_int16_t*)data; + + for (int blockIndex=0; blockIndex + +namespace Audio +{ + class AgcFilter + { + protected: + struct Channel + { + unsigned int mSampleMax; + int mCounter; + long mIgain; + int mIpeak; + int mSilenceCounter; + }; + std::vector mChannelList; + void processChannel(short* pcm, int nrOfSamples, int channelIndex); + public: + AgcFilter(int channels); + ~AgcFilter(); + + void process(void* pcm, int length); + }; + + class AecFilter + { + public: + AecFilter(int tailTime, int frameTime, int rate); + ~AecFilter(); + + // These methods accept input block with timelength "frameTime" used in constructor. + void toSpeaker(void* data); + void fromMic(void* data); + int frametime(); + + protected: + void* mCtx; /// The echo canceller context's pointer. + Mutex mGuard; /// Mutex to protect this instance. + int mFrameTime; /// Duration of single audio frame (in milliseconds) + int mRate; + }; + + class DenoiseFilter + { + public: + DenoiseFilter(int rate); + ~DenoiseFilter(); + + void fromMic(void* data, int timelength); + int rate(); + + protected: + Mutex mGuard; /// Mutex to protect this instance. + void* mCtx; /// The denoiser context pointer. + int mRate; /// Duration of single audio frame (in milliseconds) + }; + +} + +#endif diff --git a/src/engine/audio/Audio_Resampler.cpp b/src/engine/audio/Audio_Resampler.cpp new file mode 100644 index 00000000..64b39670 --- /dev/null +++ b/src/engine/audio/Audio_Resampler.cpp @@ -0,0 +1,268 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "../config.h" +#include "Audio_Resampler.h" +#include +#include +#include +#include +#include "speex/speex_resampler.h" + +using namespace Audio; + +#define IS_FRACTIONAL_RATE(X) (((X) % 8000) != 0) + +SpeexResampler::SpeexResampler() +:mContext(NULL), mErrorCode(0), mSourceRate(0), mDestRate(0), mLastSample(0) +{ +} + +void SpeexResampler::start(int channels, int sourceRate, int destRate) +{ + if (mSourceRate == sourceRate && mDestRate == destRate && mContext) + return; + + if (mContext) + stop(); + + mSourceRate = sourceRate; + mDestRate = destRate; + mChannels = channels; + + if (sourceRate != destRate) + { + // Defer context creation until first request + //mContext = speex_resampler_init(channels, sourceRate, destRate, AUDIO_RESAMPLER_QUALITY, &mErrorCode); + //assert(mContext != NULL); + } +} + +void SpeexResampler::stop() +{ + if (mContext) + { + speex_resampler_destroy((SpeexResamplerState*)mContext); + mContext = NULL; + } +} + +SpeexResampler::~SpeexResampler() +{ + stop(); +} + +int SpeexResampler::processBuffer(const void* src, int sourceLength, int& sourceProcessed, void* dest, int destCapacity) +{ + assert(mSourceRate != 0 && mDestRate != 0); + + if (mDestRate == mSourceRate) + { + assert(destCapacity >= sourceLength); + memcpy(dest, src, (size_t)sourceLength); + sourceProcessed = sourceLength; + return sourceLength; + } + + if (!mContext) + { + mContext = speex_resampler_init(mChannels, mSourceRate, mDestRate, AUDIO_RESAMPLER_QUALITY, &mErrorCode); + if (!mContext) + return 0; + } + + // Check if there is zero samples passed + if (sourceLength / (sizeof(short) * mChannels) == 0) + { + // Consume all data + sourceProcessed = sourceLength; + + // But no output + return 0; + } + unsigned outLen = getDestLength(sourceLength); + if (outLen > (unsigned)destCapacity) + return 0; // Skip resampling if not enough space + + assert((unsigned)destCapacity >= outLen); + + // Calculate number of samples - input length is in bytes + unsigned inLen = sourceLength / (sizeof(short) * mChannels); + outLen /= sizeof(short) * mChannels; + assert(mContext != NULL); + int speexCode = speex_resampler_process_interleaved_int((SpeexResamplerState *)mContext, (spx_int16_t*)src, &inLen, + (spx_int16_t*)dest, &outLen); + assert(speexCode == RESAMPLER_ERR_SUCCESS); + + // Return results in bytes + sourceProcessed = inLen * sizeof(short) * mChannels; + return outLen * sizeof(short) * mChannels; +} + +int SpeexResampler::sourceRate() +{ + return mSourceRate; +} + +int SpeexResampler::destRate() +{ + return mDestRate; +} + +int SpeexResampler::getDestLength(int sourceLen) +{ + return int(sourceLen * (float(mDestRate) / mSourceRate) + 0.5) / 2 * 2; +} + +int SpeexResampler::getSourceLength(int destLen) +{ + return int(destLen * (float(mSourceRate) / mDestRate) + 0.5) / 2 * 2; +} + +// Returns instance + speex resampler size in bytes +int SpeexResampler::getSize() const +{ + return sizeof(*this) + 200; // 200 is approximate size of speex resample structure +} + +// -------------------------- ChannelConverter -------------------- +int ChannelConverter::stereoToMono(const void *source, int sourceLength, void *dest, int destLength) +{ + assert(destLength == sourceLength / 2); + const short* input = (const short*)source; + short* output = (short*)dest; + for (int sampleIndex = 0; sampleIndex < destLength/2; sampleIndex++) + { + output[sampleIndex] = (input[sampleIndex*2] + input[sampleIndex*2+1]) >> 1; + } + return sourceLength / 2; +} + +int ChannelConverter::monoToStereo(const void *source, int sourceLength, void *dest, int destLength) +{ + assert(destLength == sourceLength * 2); + const short* input = (const short*)source; + short* output = (short*)dest; + // Convert starting from the end of buffer to allow inplace conversion + for (int sampleIndex = sourceLength/2 - 1; sampleIndex >= 0; sampleIndex--) + { + output[2*sampleIndex] = output[2*sampleIndex+1] = input[sampleIndex]; + } + return sourceLength * 2; +} + + +Resampler48kTo16k::Resampler48kTo16k() +{ + WebRtcSpl_ResetResample48khzTo16khz(&mContext); +} + +Resampler48kTo16k::~Resampler48kTo16k() +{ + WebRtcSpl_ResetResample48khzTo16khz(&mContext); +} + +int Resampler48kTo16k::process(const void *source, int sourceLen, void *dest, int destLen) +{ + const short* input = (const short*)source; int inputLen = sourceLen / 2; + short* output = (short*)dest; //int outputCapacity = destLen / 2; + assert(inputLen % 480 == 0); + int frames = inputLen / 480; + for (int i=0; i= sourceLength); + memcpy(destBuffer, sourceBuffer, (size_t)sourceLength); + sourceProcessed = sourceLength; + result = sourceLength; + } + else + { + PResampler r = findResampler(sourceRate, destRate); + result = r->processBuffer(sourceBuffer, sourceLength, sourceProcessed, destBuffer, destCapacity); + } + return result; +} + +void UniversalResampler::preload() +{ + +} + +int UniversalResampler::getDestLength(int sourceRate, int destRate, int sourceLength) +{ + if (sourceRate == destRate) + return sourceLength; + else + return findResampler(sourceRate, destRate)->getDestLength(sourceLength); +} + +int UniversalResampler::getSourceLength(int sourceRate, int destRate, int destLength) +{ + if (sourceRate == destRate) + return destLength; + else + return findResampler(sourceRate, destRate)->getSourceLength(destLength); +} + +PResampler UniversalResampler::findResampler(int sourceRate, int destRate) +{ + assert(sourceRate != destRate); + ResamplerMap::iterator resamplerIter = mResamplerMap.find(RatePair(sourceRate, destRate)); + PResampler r; + if (resamplerIter == mResamplerMap.end()) + { + r = PResampler(new Resampler()); + r->start(AUDIO_CHANNELS, sourceRate, destRate); + mResamplerMap[RatePair(sourceRate, destRate)] = r; + } + else + r = resamplerIter->second; + return r; +} + diff --git a/src/engine/audio/Audio_Resampler.h b/src/engine/audio/Audio_Resampler.h new file mode 100644 index 00000000..f3f4c4aa --- /dev/null +++ b/src/engine/audio/Audio_Resampler.h @@ -0,0 +1,97 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __AUDIO_RESAMPLER_H +#define __AUDIO_RESAMPLER_H + +#include "signal_processing_library/signal_processing_library.h" +#include "../helper/HL_Pointer.h" +#include +#include + +namespace Audio +{ + class SpeexResampler + { + public: + SpeexResampler(); + ~SpeexResampler(); + + void start(int channels, int sourceRate, int destRate); + void stop(); + int processBuffer(const void* source, int sourceLength, int& sourceProcessed, void* dest, int destCapacity); + int sourceRate(); + int destRate(); + int getDestLength(int sourceLen); + int getSourceLength(int destLen); + + // Returns instance + speex encoder size in bytes + int getSize() const; + + protected: + void* mContext; + int mErrorCode; + int mSourceRate, + mDestRate, + mChannels; + short mLastSample; + }; + + typedef SpeexResampler Resampler; + typedef std::shared_ptr PResampler; + + class ChannelConverter + { + public: + static int stereoToMono(const void* source, int sourceLength, void* dest, int destLength); + static int monoToStereo(const void* source, int sourceLength, void* dest, int destLength); + }; + + // Operates with AUDIO_CHANNELS number of channels + class UniversalResampler + { + public: + UniversalResampler(); + ~UniversalResampler(); + + int resample(int sourceRate, const void* sourceBuffer, int sourceLength, int& sourceProcessed, int destRate, void* destBuffer, int destCapacity); + int getDestLength(int sourceRate, int destRate, int sourceLength); + int getSourceLength(int sourceRate, int destRate, int destLength); + + protected: + typedef std::pair RatePair; + typedef std::map ResamplerMap; + ResamplerMap mResamplerMap; + PResampler findResampler(int sourceRate, int destRate); + + void preload(); + }; + + // n*10 milliseconds buffers required! + class Resampler48kTo16k + { + public: + Resampler48kTo16k(); + ~Resampler48kTo16k(); + int process(const void* source, int sourceLen, void* dest, int destLen); + protected: + WebRtc_Word32 mTemp[496]; + WebRtcSpl_State48khzTo16khz mContext; + }; + + class Resampler16kto48k + { + public: + Resampler16kto48k(); + ~Resampler16kto48k(); + int process(const void* source, int sourceLen, void* dest, int destLen); + + protected: + WebRtc_Word32 mTemp[336]; + WebRtcSpl_State16khzTo48khz mContext; + }; +} + +#endif diff --git a/src/engine/audio/Audio_WavFile.cpp b/src/engine/audio/Audio_WavFile.cpp new file mode 100644 index 00000000..e7176947 --- /dev/null +++ b/src/engine/audio/Audio_WavFile.cpp @@ -0,0 +1,374 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "Audio_WavFile.h" +#include "helper/HL_Exception.h" +#include "helper/HL_String.h" +#include "helper/HL_Log.h" +#include "../config.h" + +#include + +#ifndef WORD +# define WORD unsigned short +#endif +#ifndef DWORD +# define DWORD unsigned int +#endif + +typedef struct { + WORD wFormatTag; + WORD nChannels; + DWORD nSamplesPerSec; + DWORD nAvgBytesPerSec; + WORD nBlockAlign; + WORD wBitsPerSample; + WORD cbSize; +}WAVEFORMATEX; +#define WAVE_FORMAT_PCM 1 + +#define LOG_SUBSYSTEM "WavFileReader" + +using namespace Audio; + +// ---------------------- WavFileReader ------------------------- +WavFileReader::WavFileReader() +:mHandle(NULL), mRate(0) +{ + mDataOffset = 0; +} + +WavFileReader::~WavFileReader() +{ +} + +#define THROW_READERROR throw Exception(ERR_WAVFILE_FAILED); + +std::string WavFileReader::readChunk() +{ + char name[5]; + if (fread(name, 1, 4, mHandle) != 4) + THROW_READERROR; + + name[4] = 0; + std::string result = name; + unsigned size; + if (fread(&size, 4, 1, mHandle) != 1) + THROW_READERROR; + + if (result == "fact") + fread(&mDataLength, 4, 1, mHandle); + else + if (result != "data") + fseek(mHandle, size, SEEK_CUR); + else + mDataLength = size; + + return result; +} + +bool WavFileReader::open(const std::tstring& filename) +{ + Lock lock(mFileMtx); + try + { + #ifdef WIN32 + mHandle = _wfopen(filename.c_str(), L"rb"); + #else + mHandle = fopen(StringHelper::makeUtf8(filename).c_str(), "rb"); + #endif + if (NULL == mHandle) + return false; + + // Read the .WAV header + char riff[4]; + if (fread(riff, 4, 1, mHandle) < 1) + THROW_READERROR; + + if (!(riff[0] == 'R' && riff[1] == 'I' && riff[2] == 'F' && riff[3] == 'F')) + THROW_READERROR; + + // Read the file size + unsigned int filesize = 0; + if (fread(&filesize, 4, 1, mHandle) < 1) + THROW_READERROR; + + char wavefmt[9]; + if (fread(wavefmt, 8, 1, mHandle) < 1) + THROW_READERROR; + + wavefmt[8] = 0; + if (strcmp(wavefmt, "WAVEfmt ") != 0) + THROW_READERROR; + + unsigned fmtSize = 0; + if (fread(&fmtSize, 4, 1, mHandle) < 1) + THROW_READERROR; + + unsigned fmtStart = ftell(mHandle); + + unsigned short formattag = 0; + if (fread(&formattag, 2, 1, mHandle) < 1) + THROW_READERROR; + + if (formattag != 1/*WAVE_FORMAT_PCM*/) + THROW_READERROR; + + mChannels = 0; + if (fread(&mChannels, 2, 1, mHandle) < 1) + THROW_READERROR; + + mRate = 0; + if (fread(&mRate, 4, 1, mHandle) < 1) + THROW_READERROR; + + unsigned int avgbytespersec = 0; + if (fread(&avgbytespersec, 4, 1, mHandle) < 1) + THROW_READERROR; + + unsigned short blockalign = 0; + if (fread(&blockalign, 2, 1, mHandle) < 1) + THROW_READERROR; + + mBits = 0; + if (fread(&mBits, 2, 1, mHandle) < 1) + THROW_READERROR; + + if (mBits !=8 && mBits != 16) + THROW_READERROR; + + // Read the "chunk" + fseek(mHandle, fmtStart + fmtSize, SEEK_SET); + //unsigned pos = ftell(mHandle); + mDataLength = 0; + while (readChunk() != "data") + ; + + mFileName = filename; + mDataOffset = ftell(mHandle); + + mResampler.start(AUDIO_CHANNELS, mRate, AUDIO_SAMPLERATE); + } + catch(...) + { + fclose(mHandle); mHandle = NULL; + } + return isOpened(); +} + +void WavFileReader::close() +{ + Lock lock(mFileMtx); + + if (NULL != mHandle) + fclose(mHandle); + mHandle = NULL; +} + +int WavFileReader::rate() const +{ + return mRate; +} + +unsigned WavFileReader::read(void* buffer, unsigned bytes) +{ + return read((short*)buffer, bytes / (AUDIO_CHANNELS * 2)) * AUDIO_CHANNELS * 2; +} + +unsigned WavFileReader::read(short* buffer, unsigned samples) +{ + Lock lock(mFileMtx); + + if (!mHandle) + return 0; + + // Get number of samples that must be read from source file + int requiredBytes = mResampler.getSourceLength(samples) * mChannels * mBits / 8; + void* temp = alloca(requiredBytes); + memset(temp, 0, requiredBytes); + + // Find required size of input buffer + if (mDataLength) + { + unsigned filePosition = ftell(mHandle); + + // Check how much data we can read + unsigned fileAvailable = mDataLength + mDataOffset - filePosition; + requiredBytes = (int)fileAvailable < requiredBytes ? (int)fileAvailable : requiredBytes; + } + + /*int readSamples = */fread(temp, 1, requiredBytes, mHandle);// / mChannels / (mBits / 8); + int processedBytes = 0; + int result = mResampler.processBuffer(temp, requiredBytes, processedBytes, buffer, samples * 2 * AUDIO_CHANNELS); + + return result / 2 / AUDIO_CHANNELS; +} + +bool WavFileReader::isOpened() +{ + Lock lock(mFileMtx); + + return (mHandle != 0); +} + +void WavFileReader::rewind() +{ + Lock l(mFileMtx); + + if (mHandle) + fseek(mHandle, mDataOffset, SEEK_SET); +} + +std::tstring WavFileReader::filename() const +{ + Lock lock(mFileMtx); + + return mFileName; +} + +unsigned WavFileReader::size() const +{ + Lock l(mFileMtx); + + return mDataLength; +} + +// ------------------------- WavFileWriter ------------------------- +#define LOG_SUBSYTEM "WavFileWriter" + +#define BITS_PER_CHANNEL 16 + +WavFileWriter::WavFileWriter() +:mHandle(NULL), mLengthOffset(0), mRate(AUDIO_SAMPLERATE), mChannels(1) +{ +} + +WavFileWriter::~WavFileWriter() +{ + close(); +} + +void WavFileWriter::checkWriteResult(int result) +{ + if (result < 1) + throw Exception(ERR_WAVFILE_FAILED, errno); +} + +bool WavFileWriter::open(const std::tstring& filename, int rate, int channels) +{ + Lock lock(mFileMtx); + + close(); + + mRate = rate; + mChannels = channels; + +#ifdef WIN32 + mHandle = _wfopen(filename.c_str(), L"wb"); +#else + mHandle = fopen(StringHelper::makeUtf8(filename).c_str(), "wb"); +#endif + if (NULL == mHandle) + { + ICELogCritical(<< "Failed to create .wav file: filename = " << StringHelper::makeUtf8(filename) << " , error = " << errno); + return false; + } + + // Write the .WAV header + const char* riff = "RIFF"; + checkWriteResult( fwrite(riff, 4, 1, mHandle) ); + + // Write the file size + unsigned int filesize = 0; + checkWriteResult( fwrite(&filesize, 4, 1, mHandle) ); + + const char* wavefmt = "WAVEfmt "; + checkWriteResult( fwrite(wavefmt, 8, 1, mHandle) ); + + // Set the format description + DWORD dwFmtSize = 16; /*= 16L*/; + checkWriteResult( fwrite(&dwFmtSize, sizeof(dwFmtSize), 1, mHandle) ); + + WAVEFORMATEX format; + format.wFormatTag = WAVE_FORMAT_PCM; + checkWriteResult( fwrite(&format.wFormatTag, sizeof(format.wFormatTag), 1, mHandle) ); + + format.nChannels = mChannels; + checkWriteResult( fwrite(&format.nChannels, sizeof(format.nChannels), 1, mHandle) ); + + format.nSamplesPerSec = mRate; + checkWriteResult( fwrite(&format.nSamplesPerSec, sizeof(format.nSamplesPerSec), 1, mHandle) ); + + format.nAvgBytesPerSec = mRate * 2 * mChannels; + checkWriteResult( fwrite(&format.nAvgBytesPerSec, sizeof(format.nAvgBytesPerSec), 1, mHandle) ); + + format.nBlockAlign = 2 * mChannels; + checkWriteResult( fwrite(&format.nBlockAlign, sizeof(format.nBlockAlign), 1, mHandle) ); + + format.wBitsPerSample = BITS_PER_CHANNEL; + checkWriteResult( fwrite(&format.wBitsPerSample, sizeof(format.wBitsPerSample), 1, mHandle) ); + + const char* data = "data"; + checkWriteResult( fwrite(data, 4, 1, mHandle)); + + mFileName = filename; + mWritten = 0; + + mLengthOffset = ftell(mHandle); + checkWriteResult( fwrite(&mWritten, 4, 1, mHandle) ); + + return isOpened(); +} + +void WavFileWriter::close() +{ + Lock lock(mFileMtx); + + if (mHandle) + { + fclose(mHandle); + mHandle = NULL; + } +} + +unsigned WavFileWriter::write(const void* buffer, unsigned bytes) +{ + Lock l(mFileMtx); + + if (!mHandle) + return 0; + + // Seek the end of file + fseek(mHandle, 0, SEEK_END); + mWritten += bytes; + + // Write the data + fwrite(buffer, bytes, 1, mHandle); + + // Write file length + fseek(mHandle, 4, SEEK_SET); + unsigned int fl = mWritten + 36; + fwrite(&fl, sizeof(fl), 1, mHandle); + + // Write data length + fseek(mHandle, mLengthOffset, SEEK_SET); + checkWriteResult( fwrite(&mWritten, 4, 1, mHandle) ); + + return bytes; +} + +bool WavFileWriter::isOpened() +{ + Lock lock(mFileMtx); + + return (mHandle != 0); +} + +std::tstring WavFileWriter::filename() +{ + Lock lock(mFileMtx); + return mFileName; +} + diff --git a/src/engine/audio/Audio_WavFile.h b/src/engine/audio/Audio_WavFile.h new file mode 100644 index 00000000..bddd5d3e --- /dev/null +++ b/src/engine/audio/Audio_WavFile.h @@ -0,0 +1,82 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#ifndef __AUDIO_WAVFILE_H +#define __AUDIO_WAVFILE_H + +#include "helper/HL_Sync.h" +#include "helper/HL_Types.h" +#include "Audio_Resampler.h" + +#include +#include +#include + +namespace Audio +{ + + class WavFileReader + { + protected: + FILE* mHandle; + short mChannels; + short mBits; + int mRate; + std::tstring mFileName; + mutable Mutex mFileMtx; + unsigned mDataOffset; + unsigned mDataLength; + Resampler mResampler; + std::string readChunk(); + public: + WavFileReader(); + ~WavFileReader(); + + bool open(const std::tstring& filename); + void close(); + bool isOpened(); + void rewind(); + int rate() const; + + // This method returns number of read bytes + unsigned read(void* buffer, unsigned bytes); + + // This method returns number of read samples + unsigned read(short* buffer, unsigned samples); + std::tstring filename() const; + unsigned size() const; + }; + + typedef std::shared_ptr PWavFileReader; + + class WavFileWriter + { + protected: + FILE* mHandle; /// Handle of audio file. + std::tstring mFileName; /// Path to requested audio file. + Mutex mFileMtx; /// Mutex to protect this instance. + int mWritten; /// Amount of written data (in bytes) + int mLengthOffset; /// Position of length field. + int mRate, mChannels; + + void checkWriteResult(int result); + + public: + WavFileWriter(); + ~WavFileWriter(); + + bool open(const std::tstring& filename, int rate, int channels); + void close(); + bool isOpened(); + unsigned write(const void* buffer, unsigned bytes); + std::tstring filename(); + }; + + typedef std::shared_ptr PWavFileWriter; + +} + +#endif diff --git a/src/engine/audio/Audio_Wmme.cpp b/src/engine/audio/Audio_Wmme.cpp new file mode 100644 index 00000000..f463f815 --- /dev/null +++ b/src/engine/audio/Audio_Wmme.cpp @@ -0,0 +1,555 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifdef TARGET_WIN + +#include "Audio_Wmme.h" +#include "Audio_Helper.h" +#include "../Helper/HL_Exception.h" + +#include +using namespace Audio; + + +WmmeInputDevice::Buffer::Buffer() +{ + // Do not use WAVEHDR allocated on stack! + mHeaderHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof WAVEHDR); + if (!mHeaderHandle) + throw Exception(ERR_WMME_FAILED, GetLastError()); + mHeader = (WAVEHDR*)GlobalLock(mHeaderHandle); + + mDataHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, AUDIO_MIC_BUFFER_SIZE); + if (!mDataHandle) + throw Exception(ERR_WMME_FAILED, GetLastError()); + mData = GlobalLock(mDataHandle); + + memset(mHeader, 0, sizeof *mHeader); + mHeader->dwBufferLength = AUDIO_MIC_BUFFER_SIZE; + mHeader->dwFlags = 0; + mHeader->lpData = (LPSTR)mData; +} + +WmmeInputDevice::Buffer::~Buffer() +{ + if (mDataHandle) + { + GlobalUnlock(mDataHandle); + GlobalFree(mDataHandle); + } + if (mHeaderHandle) + { + GlobalUnlock(mHeaderHandle); + GlobalFree(mHeaderHandle); + } + +} + +bool WmmeInputDevice::Buffer::prepare(HWAVEIN device) +{ + MMRESULT resCode = MMSYSERR_NOERROR; + mHeader->dwFlags = 0; + mHeader->dwBufferLength = AUDIO_MIC_BUFFER_SIZE; + mHeader->lpData = (LPSTR)mData; + + resCode = waveInPrepareHeader(device, mHeader, sizeof *mHeader); + //if (resCode != MMSYSERR_NOERROR) + // LogCritical("Audio", << "Failed to prepare source header. Error code " << resCode << "."); + + return resCode == MMSYSERR_NOERROR; +} + +bool WmmeInputDevice::Buffer::unprepare(HWAVEIN device) +{ + if (mHeader->dwFlags & WHDR_PREPARED) + { + MMRESULT resCode = waveInUnprepareHeader(device, mHeader, sizeof *mHeader); + //if (resCode != MMSYSERR_NOERROR) + // LogCritical("Audio", << "Failed to unprepare source header. Error code " << resCode << "."); + return resCode == MMSYSERR_NOERROR; + } + return true; +} + +bool WmmeInputDevice::Buffer::isFinished() +{ + return (mHeader->dwFlags & WHDR_DONE) != 0; +} + +bool WmmeInputDevice::Buffer::addToDevice(HWAVEIN device) +{ + MMRESULT resCode = waveInAddBuffer(device, mHeader, sizeof(*mHeader)); + //if (resCode != MMSYSERR_NOERROR) + // LogCritical("Audio", << "Failed to add buffer to source audio device. Error code is " << resCode << "."); + return resCode == MMSYSERR_NOERROR; +} + +void* WmmeInputDevice::Buffer::data() +{ + return mData; +} + + +WmmeInputDevice::WmmeInputDevice(int deviceId) +:mDevHandle(NULL), mDoneSignal(INVALID_HANDLE_VALUE), mFakeMode(false), +mBufferIndex(0), mDeviceIndex(deviceId), mThreadHandle(0) +{ + mDoneSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL); + mShutdownSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL); + mRefCount = 0; +} + +WmmeInputDevice::~WmmeInputDevice() +{ + close(); + ::CloseHandle(mDoneSignal); + ::CloseHandle(mShutdownSignal); +} + +bool WmmeInputDevice::fakeMode() +{ + return mFakeMode; +} + +void CALLBACK WmmeInputDevice::callbackProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) +{ + WmmeInputDevice* impl; + switch(uMsg) + { + case WIM_DATA: + impl = (WmmeInputDevice*)dwInstance; + SetEvent(impl->mDoneSignal); + break; + + case WIM_CLOSE: + break; + + case WIM_OPEN: + break; + } +} + +void WmmeInputDevice::openDevice() +{ + // Build WAVEFORMATEX structure + WAVEFORMATEX wfx; + memset(&wfx, 0, sizeof(wfx)); + + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.nChannels = AUDIO_CHANNELS; + wfx.nSamplesPerSec = AUDIO_SAMPLERATE; + wfx.wBitsPerSample = 16; + wfx.cbSize = 0; + wfx.nBlockAlign = wfx.wBitsPerSample * wfx.nChannels / 8; + wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec; + + // Open wavein + + MMRESULT mmres = waveInOpen(&mDevHandle, mDeviceIndex, &wfx, (DWORD_PTR)callbackProc, (DWORD_PTR)this, CALLBACK_FUNCTION); + if (mmres != MMSYSERR_NOERROR) + { + mFakeMode = true; + return; + } + else + mFakeMode = false; + + // Create the buffers for running + mBufferIndex = 0; + for (int i=0; i 1) + return true; + + mThreadHandle = (HANDLE)_beginthread(&threadProc, 0, this); + return true; +} + +void WmmeInputDevice::closeDevice() +{ + // Stop device + if (mDevHandle) + { + MMRESULT mmres = MMSYSERR_NOERROR; + waveInReset(mDevHandle); + waveInStop(mDevHandle); + } + + // Close buffers + for (int i=0; iopenDevice(); + void* buffer = _alloca(AUDIO_MIC_BUFFER_SIZE); + + DWORD waitResult = 0; + HANDLE waitArray[2] = {impl->mDoneSignal, impl->mShutdownSignal}; + DWORD wr; + do + { + wr = ::WaitForMultipleObjects(2, waitArray, FALSE, INFINITE); + + if (wr == WAIT_OBJECT_0) + { + impl->readBuffer(buffer); + if (impl->connection()) + impl->connection()->onMicData(Format(), buffer, AUDIO_MIC_BUFFER_SIZE); + } + } while (wr == WAIT_OBJECT_0); + + impl->closeDevice(); +} + +// --- WmmeOutputDevice --- +WmmeOutputDevice::Buffer::Buffer() +:mHeaderHandle(NULL), mDataHandle(NULL), mData(NULL), mHeader(NULL) +{ + mHeaderHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, AUDIO_SPK_BUFFER_SIZE); + if (!mHeaderHandle) + throw Exception(ERR_NOMEM); + + mDataHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, AUDIO_SPK_BUFFER_SIZE); + if (!mDataHandle) + throw Exception(ERR_NOMEM); + + mHeader = (WAVEHDR*)GlobalLock(mHeaderHandle); + mData = GlobalLock(mDataHandle); + memset(mHeader, 0, sizeof *mHeader); + mHeader->dwBufferLength = AUDIO_SPK_BUFFER_SIZE; + mHeader->lpData = (LPSTR)mData; +} + +WmmeOutputDevice::Buffer::~Buffer() +{ + if (mHeaderHandle) + { + GlobalUnlock(mHeaderHandle); + GlobalFree(mHeaderHandle); + } + if (mDataHandle) + { + GlobalUnlock(mDataHandle); + GlobalFree(mDataHandle); + } +} + +bool WmmeOutputDevice::Buffer::prepare(HWAVEOUT device) +{ + MMRESULT result; + result = ::waveOutPrepareHeader(device, mHeader, sizeof *mHeader); + return result == MMSYSERR_NOERROR; +} + +bool WmmeOutputDevice::Buffer::unprepare(HWAVEOUT device) +{ + MMRESULT result; + result = ::waveOutUnprepareHeader(device, mHeader, sizeof *mHeader); + return result == MMSYSERR_NOERROR; +} + +bool WmmeOutputDevice::Buffer::write(HWAVEOUT device) +{ + MMRESULT result; + result = ::waveOutWrite(device, mHeader, sizeof *mHeader); + return result == MMSYSERR_NOERROR; +} + +WmmeOutputDevice::WmmeOutputDevice(int index) +:mDevice(NULL), mDeviceIndex(index), mPlayedTime(0), mPlayedCount(0), mBufferIndex(0), mThreadHandle(NULL), +mFailed(false), mShutdownMarker(false) +{ + mDoneSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL); + mShutdownSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL); +} + + +WmmeOutputDevice::~WmmeOutputDevice() +{ + close(); + + // Destroy used signals + CloseHandle(mDoneSignal); CloseHandle(mShutdownSignal); +} + +bool WmmeOutputDevice::open() +{ + // Start thread + mThreadHandle = (HANDLE)_beginthread(&threadProc, 0, this); + return true; +} + +void WmmeOutputDevice::close() +{ + // Tell the thread to exit + SetEvent(mShutdownSignal); + mShutdownMarker = true; + + // Wait for thread + if (mThreadHandle) + WaitForSingleObject(mThreadHandle, INFINITE); + mThreadHandle = 0; +} + +void WmmeOutputDevice::openDevice() +{ + mClosing = false; + MMRESULT mmres = 0; + WAVEFORMATEX wfx; + memset(&wfx, 0, sizeof(wfx)); + wfx.wFormatTag = 0x0001; + wfx.nChannels = AUDIO_CHANNELS; + wfx.nSamplesPerSec = AUDIO_SAMPLERATE; + wfx.wBitsPerSample = 16; + wfx.cbSize = 0; + wfx.nBlockAlign = wfx.wBitsPerSample * wfx.nChannels / 8; + wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec; + + mmres = waveOutOpen(&mDevice, mDeviceIndex, &wfx, (DWORD_PTR)&callbackProc, (DWORD_PTR)this, CALLBACK_FUNCTION); + if (mmres != MMSYSERR_NOERROR) + throw Exception(ERR_WMME_FAILED, mmres); + + // Prebuffer silence + for (unsigned i=0; idwFlags & WHDR_DONE || + !mBufferList[i].mHeader->dwFlags; + if (finished) + { +/* if (mBufferList[i].mHeader->dwFlags & WHDR_PREPARED) + mBufferList[i].Unprepare(mDevice); */ + } + result &= finished; + } + + return result; +} + +void WmmeOutputDevice::threadProc(void* arg) +{ + WmmeOutputDevice* impl = (WmmeOutputDevice*)arg; + impl->openDevice(); + + DWORD waitResult = 0; + HANDLE waitArray[2] = {impl->mDoneSignal, impl->mShutdownSignal}; + unsigned index, i; + unsigned exitCount = 0; + bool exitSignal = false; + do + { + // Poll for exit signal + if (!exitSignal) + exitSignal = impl->mShutdownMarker; + + // Wait for played buffer + WaitForSingleObject(impl->mDoneSignal, 500); + + // Iterate buffers to find played + for (i=0; imBufferIndex + i) % AUDIO_SPK_BUFFER_COUNT; + Buffer& buffer = impl->mBufferList[index]; + if (!(buffer.mHeader->dwFlags & WHDR_DONE)) + break; + + buffer.unprepare(impl->mDevice); + if (!exitSignal) + { + bool useAEC = true; + if (impl->connection()) + impl->connection()->onSpkData(Format(), buffer.mData, AUDIO_SPK_BUFFER_SIZE); + else + memset(buffer.mData, 0, AUDIO_SPK_BUFFER_SIZE); + + buffer.prepare(impl->mDevice); + buffer.write(impl->mDevice); + } + else + exitCount++; + } + impl->mBufferIndex = (impl->mBufferIndex + i) % AUDIO_SPK_BUFFER_COUNT; + } + while (!exitSignal || exitCount < AUDIO_SPK_BUFFER_COUNT); + impl->closeDevice(); +} + +HWAVEOUT WmmeOutputDevice::handle() +{ + return mDevice; +} + +unsigned WmmeOutputDevice::playedTime() +{ + if (!mDevice) + return 0; + unsigned result = 0; + + MMTIME mmt; + memset(&mmt, 0, sizeof(mmt)); + mmt.wType = TIME_SAMPLES; + MMRESULT rescode = waveOutGetPosition(mDevice, &mmt, sizeof(mmt)); + if (rescode != MMSYSERR_NOERROR || mmt.wType != TIME_SAMPLES) + closeDevice(); + else + { + if (mmt.u.ms < mPlayedTime) + result = 0; + else + { + result = mmt.u.ms - mPlayedTime; + mPlayedTime = mmt.u.ms - result % 8; + } + } + + return result / 8; +} + +void WmmeOutputDevice::setFakeMode(bool fakemode) +{ + closeDevice(); +} + +bool WmmeOutputDevice::fakeMode() +{ + return mFailed; +} + + +bool WmmeOutputDevice::closing() +{ + return mClosing; +} + +void CALLBACK WmmeOutputDevice::callbackProc(HWAVEOUT hwo, UINT msg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) +{ + WmmeOutputDevice* impl; + + if (msg == WOM_DONE) + { + impl = (WmmeOutputDevice*)dwInstance; + InterlockedIncrement(&impl->mPlayedCount); + SetEvent(impl->mDoneSignal); + } +} + +#endif diff --git a/src/engine/audio/Audio_Wmme.h b/src/engine/audio/Audio_Wmme.h new file mode 100644 index 00000000..c3e90c44 --- /dev/null +++ b/src/engine/audio/Audio_Wmme.h @@ -0,0 +1,148 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __AUDIO_WMME_H +#define __AUDIO_WMME_H + +#ifdef TARGET_WIN + +#include "../config.h" + +#include +#include +#include + +#include "../Helper/HL_Sync.h" +#include "Audio_Interface.h" + +#include +#include +#include +#if defined(_MSC_VER) +#include +#endif +#include +#include + + +namespace Audio +{ + + class WmmeInputDevice: public InputDevice + { + public: + WmmeInputDevice(int index); + ~WmmeInputDevice(); + + bool open(); + void close(); + + bool fakeMode(); + void setFakeMode(bool fakeMode); + + int readBuffer(void* buffer); + HWAVEIN handle(); + + protected: + class Buffer + { + public: + Buffer(); + ~Buffer(); + bool prepare(HWAVEIN device); + bool unprepare(HWAVEIN device); + bool isFinished(); + bool addToDevice(HWAVEIN device); + void* data(); + + protected: + HGLOBAL mDataHandle; + void* mData; + HGLOBAL mHeaderHandle; + WAVEHDR* mHeader; + }; + + Mutex mGuard; /// Mutex to protect this instance. + HWAVEIN mDevHandle; /// Handle of opened capture device. + HANDLE mThreadHandle; + HANDLE mShutdownSignal; + HANDLE mDoneSignal; /// Event handle to signal about finished capture. + Buffer mBufferList[AUDIO_MIC_BUFFER_COUNT]; + unsigned mBufferIndex; + int mDeviceIndex; /// Index of capture device. + volatile bool mFakeMode; /// Marks if fake mode is active. + int mRefCount; + + bool tryReadBuffer(void* buffer); + void openDevice(); + void closeDevice(); + + static void CALLBACK callbackProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2); + static void threadProc(void* arg); + }; + + class WmmeOutputDevice: public OutputDevice + { + public: + WmmeOutputDevice(int index); + ~WmmeOutputDevice(); + + bool open(); + void close(); + + HWAVEOUT handle(); + unsigned playedTime(); + void setFakeMode(bool fakemode); + bool fakeMode(); + bool closing(); + + protected: + class Buffer + { + friend class WmmeOutputDevice; + public: + Buffer(); + ~Buffer(); + bool prepare(HWAVEOUT device); + bool unprepare(HWAVEOUT device); + bool write(HWAVEOUT device); + protected: + WAVEHDR* mHeader; + void* mData; + HGLOBAL mHeaderHandle; + HGLOBAL mDataHandle; + }; + + Mutex mGuard; /// Mutex to protect this instance + int mDeviceIndex; + HWAVEOUT mDevice; /// Handle of opened audio device + Buffer mBufferList[AUDIO_SPK_BUFFER_COUNT]; + unsigned mPlayedTime; /// Amount of played time in milliseconds + bool mClosing; + HANDLE mDoneSignal, + mShutdownSignal, + mThreadHandle; + volatile bool mShutdownMarker; + + volatile LONG mPlayedCount; + unsigned mBufferIndex; + bool mFailed; + + void openDevice(); + void closeDevice(); + bool areBuffersFinished(); + + static void CALLBACK callbackProc(HWAVEOUT hwo, UINT msg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2); + static void threadProc(void* arg); + }; + + + + +} + +#endif + +#endif diff --git a/src/engine/audio/Audio_iOS.cpp b/src/engine/audio/Audio_iOS.cpp new file mode 100644 index 00000000..be5bb9bc --- /dev/null +++ b/src/engine/audio/Audio_iOS.cpp @@ -0,0 +1,2 @@ +#include "Audio_iOS.h" + diff --git a/src/engine/audio/Audio_iOS.h b/src/engine/audio/Audio_iOS.h new file mode 100644 index 00000000..87d346c9 --- /dev/null +++ b/src/engine/audio/Audio_iOS.h @@ -0,0 +1,38 @@ +#ifndef __AUDIO_IOS +#define __AUDIO_IOS + +class IosInputDevice: public InputDevice +{ +protected: + +public: + IosInputDevice(); + ~IosInputDevice(); + + + + void open(); + void close(); +}; + +class IosOutputDevice: public OutputDevice +{ +protected: +public: + IosOutputDevice(); + ~IosOutputDevice(); + enum + { + Receiver, + Speaker, + Bluetooth + }; + + int route(); + void setRoute(int route); + + void open(); + void close(); +}; + +#endif \ No newline at end of file diff --git a/src/engine/audio/CMakeLists.txt b/src/engine/audio/CMakeLists.txt new file mode 100644 index 00000000..d1883ce1 --- /dev/null +++ b/src/engine/audio/CMakeLists.txt @@ -0,0 +1,22 @@ +project (audio_lib) + +# Rely on C++ 11 +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +set (AUDIOLIB_SOURCES + Audio_Resampler.cpp + Audio_Quality.cpp + Audio_Mixer.cpp + Audio_Interface.cpp + Audio_Helper.cpp + Audio_DataWindow.cpp + Audio_DevicePair.cpp + Audio_Player.cpp + Audio_Null.cpp + Audio_CoreAudio.cpp + Audio_DirectSound.cpp + Audio_WavFile.cpp +) + +add_library(audio_lib ${AUDIOLIB_SOURCES}) diff --git a/src/engine/config.h b/src/engine/config.h new file mode 100644 index 00000000..a27ab521 --- /dev/null +++ b/src/engine/config.h @@ -0,0 +1,110 @@ +/* Copyright(C) 2007-2015 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __TOOLKIT_CONFIG_H +#define __TOOLKIT_CONFIG_H + +#define USE_SPEEX_AEC + +// TODO: test implementation with webrtc aec; be careful - it needs fixes! +//#define USE_WEBRTC_AEC +#define USER + + +#define AUDIO_SAMPLE_WIDTH 16 +#define AUDIO_CHANNELS 1 + +// Samplerate must be 8 / 16 / 24 / 32 / 48 KHz +#define AUDIO_SAMPLERATE 8000 +#define AUDIO_MIC_BUFFER_COUNT 16 +#define AUDIO_MIC_BUFFER_LENGTH 10 +#define AUDIO_MIC_BUFFER_SIZE (AUDIO_MIC_BUFFER_LENGTH * AUDIO_SAMPLERATE / 1000 * 2 * AUDIO_CHANNELS) +#define AUDIO_SPK_BUFFER_COUNT 16 +#define AUDIO_SPK_BUFFER_LENGTH 10 +#define AUDIO_SPK_BUFFER_SIZE (AUDIO_SPK_BUFFER_LENGTH * AUDIO_SAMPLERATE / 1000 * 2 * AUDIO_CHANNELS) +#define AUDIO_MIX_CHANNEL_COUNT 16 +#define AUDIO_DEVICEPAIR_INPUTBUFFER 16384 + +// Avoid too high resampler quality - it can take many CPU and cause gaps in playing +#define AUDIO_RESAMPLER_QUALITY 1 +#define AEC_FRAME_TIME 10 +#define AEC_TAIL_TIME 160 + + +// Defined these two lines to get dumping of audio input/output +//#define AUDIO_DUMPINPUT +//#define AUDIO_DUMPOUTPUT + + +#define UA_REGISTRATION_TIME 3600 +#define UA_MEDIA_PORT_START 20000 +#define UA_MEDIA_PORT_FINISH 30000 +#define UA_MAX_UDP_PACKET_SIZE 576 +#define UA_PUBLICATION_ID "314" + +#define MT_SAMPLERATE AUDIO_SAMPLERATE + +#define MT_MAXAUDIOFRAME 1440 +#define MT_MAXRTPPACKET 1500 +#define MT_DTMF_END_PACKETS 3 + +#define RTP_BUFFER_HIGH 480 +#define RTP_BUFFER_LOW 10 +#define RTP_BUFFER_PREBUFFER 80 +#define RTP_DECODED_CAPACITY 2048 + +#define DEFAULT_SUBSCRIPTION_TIME 1200 +#define DEFAULT_SUBSCRIPTION_REFRESHTIME 500 + +#define PRESENCE_IN_REG_HEADER "PresenceInReg" + +// Maximum UDP packet length +#define MAX_UDPPACKET_SIZE 65535 +#define MAX_VALID_UDPPACKET_SIZE 2048 + +// AMR codec defines - it requires USE_AMR_CODEC defined +// #define USE_AMR_CODEC +#define MT_AMRNB_PAYLOADTYPE 97 +#define MT_AMRNB_CODECNAME "amr" + +#define MT_AMRNB_OCTET_PAYLOADTYPE 103 + +#define MT_AMRWB_PAYLOADTYPE 96 +#define MT_AMRWB_CODECNAME "amr-wb" + +#define MT_AMRWB_OCTET_PAYLOADTYPE 104 + +#define MT_GSMEFR_PAYLOADTYPE 110 +#define MT_GSMEFR_CODECNAME "GERAN-EFR" + +// OPUS codec defines +// #define USE_OPUS_CODEC +#define MT_OPUS_CODEC_PT 106 + +// ILBC codec defines +#define MT_ILBC20_PAYLOADTYPE 98 +#define MT_ILBC30_PAYLOADTYPE 99 + +// ISAC codec defines +#define MT_ISAC16K_PAYLOADTYPE 100 +#define MT_ISAC32K_PAYLOADTYPE 101 + +// GSM HR payload type +#define MT_GSMHR_PAYLOADTYPE 111 + +// Mirror buffer capacity +#define MT_MIRROR_CAPACITY 32768 + +// Mirror buffer readiness threshold - 50 milliseconds +#define MT_MIRROR_PREBUFFER (MT_SAMPLERATE / 10) + +#if defined(TARGET_OSX) || defined(TARGET_LINUX) +# define TEXT(X) X +#endif + +// In milliseconds +#define MT_SEVANA_FRAME_TIME 680 + +#endif diff --git a/src/engine/endpoint/EP_Account.cpp b/src/engine/endpoint/EP_Account.cpp new file mode 100644 index 00000000..23604b22 --- /dev/null +++ b/src/engine/endpoint/EP_Account.cpp @@ -0,0 +1,747 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "EP_Engine.h" +#include "../helper/HL_Log.h" +#include "../helper/HL_Exception.h" +#include +#include +#include + +#define LOG_SUBSYSTEM "Account" + +#define CONFIG(X) mConfig->at(X) +#define CONFIG_EXISTS(X) mConfig->exists(X) + +//#define MODIFY_VIA_BEHIND_NAT + +// NAT decorator +class NATDecorator: public resip::MessageDecorator +{ +protected: + UserAgent& mUserAgent; + resip::SipMessage mMessage; + + resip::Data mViaHost; + unsigned short mViaPort; + + resip::Data mContactsHost; + resip::Data mContactsScheme; + unsigned short mContactsPort; + +public: + NATDecorator(UserAgent& endpoint); + virtual ~NATDecorator(); + + virtual void decorateMessage(resip::SipMessage &msg, const resip::Tuple &source, const resip::Tuple &destination, const resip::Data& sigcompId); + virtual void rollbackMessage(resip::SipMessage& msg); + virtual MessageDecorator* clone() const; +}; + + +NATDecorator::NATDecorator(UserAgent& ua) + :mUserAgent(ua), mViaPort(0), mContactsPort(0) +{ +} + +NATDecorator::~NATDecorator() +{ +} + +void NATDecorator::decorateMessage(resip::SipMessage &msg, const resip::Tuple &source, const resip::Tuple &destination, const resip::Data& sigcompId) +{ + // Make a copy to allow rollback + mMessage = msg; + + std::stringstream dump; + mMessage.encode(dump); + //ICELogDebug(<< "Decorating message: \n" << dump.str()); + + // Check From: header and find the account + resip::NameAddr from; + if (msg.isRequest()) + from = msg.header(resip::h_From); + else + from = msg.header(resip::h_To); + + PAccount account = mUserAgent.getAccount(from); + if (!account) + { + ICELogDebug(<< "Bad from header " << from.uri().getAor().c_str() << ". Will skip it"); + return; + } + + if (!account->mConfig->at(CONFIG_EXTERNALIP).asBool()) + return; + + if (!account->mExternalAddress.isEmpty()) + { +#ifdef MODIFY_VIA_BEHIND_NAT + if (msg.header(resip::h_Vias).size() > 0) + { + resip::Via& via = msg.header(resip::h_Vias).front(); + mViaHost = via.sentHost(); + mViaPort = via.sentPort(); + + via.sentHost() = resip::Data(account->mExternalAddress.ip()); + via.sentPort() = account->mExternalAddress.port(); + } +#endif + + if (msg.header(resip::h_Contacts).size() > 0) + { + resip::Uri& uri = msg.header(resip::h_Contacts).front().uri(); + mContactsHost = uri.host(); + mContactsPort = uri.port(); + mContactsScheme = uri.scheme(); + + uri.host() = resip::Data(account->mExternalAddress.ip()); + uri.port() = account->mExternalAddress.port(); + if (account->mConfig->at(CONFIG_SIPS).asBool()) + { + //uri.scheme() = "sips"; + //uri.param(resip::p_transport) = "tls"; + } + + //uri.scheme() = account->mConfig->at(CONFIG_SIPS).asBool() ? "sips" : "sip"; + } + } +} + +void NATDecorator::rollbackMessage(resip::SipMessage& msg) +{ + // Check From: header and find the account + resip::NameAddr from = msg.header(resip::h_From); + PAccount account = mUserAgent.getAccount(from); + if (!account) + return; + + if (!account->mExternalAddress.isEmpty()) + { +#ifdef MODIFY_VIA_BEHIND_NAT + if (msg.header(resip::h_Vias).size() > 0) + { + resip::Via& via = msg.header(resip::h_Vias).front(); + if ((via.sentHost() == resip::Data(account->mExternalAddress.ip())) && + (via.sentPort() == account->mExternalAddress.port())) + { + via.sentHost() = mViaHost; + via.sentPort() = mViaPort; + } + } +#endif + + if (msg.header(resip::h_Contacts).size() > 0) + { + resip::Uri& uri = msg.header(resip::h_Contacts).front().uri(); + if ((uri.host() == resip::Data(account->mExternalAddress.ip())) && + (uri.port() == account->mExternalAddress.port())) + { + uri.host() = mContactsHost; + uri.port() = mContactsPort; + //uri.scheme() = mContactsScheme; + } + } + } +} + +resip::MessageDecorator* NATDecorator::clone() const +{ + return new NATDecorator(mUserAgent); +} + +Account::Account(PVariantMap config, UserAgent& agent) + :mAgent(agent), mId(0), mConfig(config), mRegistrationState(RegistrationState::None), + mRegistration(NULL) +{ + mProfile = resip::SharedPtr(new resip::UserProfile(agent.mProfile)); + mId = Account::generateId(); + setup(*config); +} + +Account::~Account() +{ +} + +void Account::setup(VariantMap &config) +{ + // Credentials + + if (!config.exists(CONFIG_USERNAME) || !config.exists(CONFIG_PASSWORD) || !config.exists(CONFIG_DOMAIN)) + throw Exception(ERR_NO_CREDENTIALS); + + mProfile->clearDigestCredentials(); + mProfile->setDigestCredential(resip::Data(config[CONFIG_DOMAIN].asStdString()), + resip::Data(config[CONFIG_USERNAME].asStdString()), + resip::Data(config[CONFIG_PASSWORD].asStdString())); + ICELogInfo( << "Credentials are set to domain " << config[CONFIG_DOMAIN].asStdString() << + ", username to " << config[CONFIG_USERNAME].asStdString()); + + // Proxy + mProfile->unsetOutboundProxy(); + if (config.exists(CONFIG_PROXY)) + { + if (!config[CONFIG_PROXY].asStdString().empty()) + { + resip::Uri proxyAddr; + proxyAddr.host() = resip::Data(config[CONFIG_PROXY].asStdString()); + proxyAddr.port() = 5060; + if (config.exists(CONFIG_PROXYPORT)) + { + if (config[CONFIG_PROXYPORT].asInt()) + proxyAddr.port() = config[CONFIG_PROXYPORT].asInt(); + } + if (config[CONFIG_SIPS].asBool()) + proxyAddr.param(resip::p_transport) = "tls"; + + mProfile->setOutboundProxy(proxyAddr); + } + } + + // NAT decorator + mProfile->setOutboundDecorator(resip::SharedPtr(new NATDecorator(mAgent))); + + // Rinstance + if (config.exists(CONFIG_INSTANCE_ID)) + { + if (!config[CONFIG_INSTANCE_ID].asStdString().empty()) + mProfile->setInstanceId(config[CONFIG_INSTANCE_ID].asStdString().c_str()); + } + else + mProfile->setInstanceId(resip::Data::Empty); + + if (config.exists(CONFIG_REGID)) + mProfile->setRegId(config[CONFIG_REGID].asInt()); + + if (config.exists(CONFIG_RINSTANCE)) + mProfile->setRinstanceEnabled(config[CONFIG_RINSTANCE].asBool()); + else + mProfile->setRinstanceEnabled(true); + + if (config.exists(CONFIG_RPORT)) + mProfile->setRportEnabled(config[CONFIG_RPORT].asBool()); + else + mProfile->setRportEnabled(true); + + // From header + resip::NameAddr from; + if (config.exists(CONFIG_DISPLAYNAME)) + from.displayName() = resip::Data(config[CONFIG_DISPLAYNAME].asStdString().c_str()); + + from.uri().scheme() = config[CONFIG_SIPS].asBool() ? "sips" : "sip"; + if (config[CONFIG_DOMAINPORT].asInt() != 0) + from.uri().port() = config[CONFIG_DOMAINPORT].asInt(); + else + from.uri().port();// = 5060; + + from.uri().user() = resip::Data(config[CONFIG_USERNAME].asStdString()); + from.uri().host() = resip::Data(config[CONFIG_DOMAIN].asStdString()); + + mProfile->setDefaultFrom(from); + + if (!CONFIG_EXISTS(CONFIG_REGISTERDURATION)) + CONFIG(CONFIG_REGISTERDURATION) = UA_REGISTRATION_TIME; +} + +int Account::id() const +{ + return mId; +} + +void Account::start() +{ + ICELogInfo(<< "Starting account " << this->name()); + if (mRegistrationState != RegistrationState::None) + { + ICELogInfo(<< "Registration is active or in progress already."); + return; + } + if (!mAgent.mDum) + { + ICELogInfo(<< "DUM is not started yet."); + return; + } + + // Create registration + mRegistration = new ResipSession(*mAgent.mDum); + resip::SharedPtr regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile, mConfig->at(CONFIG_REGISTERDURATION).asInt(), mRegistration); + + for (UserInfo::const_iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++) + regmessage->header(resip::ExtensionHeader(iter->first.c_str())).push_back(resip::StringCategory(iter->second.c_str())); + + mRegistrationState = RegistrationState::Registering; + + // Send packet here + mAgent.mDum->send(regmessage); + + // Check if STUN IP is required + bool noStunServerIp = !CONFIG_EXISTS(CONFIG_STUNSERVER_IP); + //bool hasStunServerName = !CONFIG(CONFIG_STUNSERVER_NAME).asStdString().empty(); + if (noStunServerIp) + { + ICELogInfo(<<"No STUN server name or IP is not specified. Has to resolve/discover STUN server IP."); + mRefreshStunServerIpTimer.start(CONFIG(CONFIG_DNS_CACHE_TIME).asInt() * 1000); + mRefreshStunServerIpTimer.isTimeToSend(); + queryStunServerIp(); + } +} + +void Account::stop() +{ + // Close presence publication + if (mPublication.isValid()) + { + mPublication->end(); + mPublication = resip::ClientPublicationHandle(); + } + + // Close client subscriptions + + // Close registration + if (mRegistrationHandle.isValid()) + { + mRegistrationHandle->removeAll(); + mRegistrationHandle = resip::ClientRegistrationHandle(); + } + else + if (mRegistration) + { + mRegistration->end(); + } + mRegistration = NULL; + mRegistrationState = RegistrationState::None; +} + +void Account::refresh() +{ + if (mRegistrationHandle.isValid()) + { + mRegistrationState = RegistrationState::Registering; + mRegistrationHandle->requestRefresh(); + } + + if (mPublication.isValid()) + { + mPublication->refresh(); + } +} + +bool Account::active() +{ + return mRegistrationState == RegistrationState::Registered || + mRegistrationState == RegistrationState::Registering || + mRegistrationState == RegistrationState::Reregistering; +} + +std::string Account::name() +{ + return contact(SecureScheme::Nothing).uri().toString().c_str(); +} + +Account::RegistrationState Account::registrationState() +{ + return mRegistrationState; +} + +void Account::publishPresence(bool online, const std::string& content, int seconds) +{ + if (online == mPresenceOnline && content == mPresenceContent) + return; + + mPresenceOnline = online; + mPresenceContent = content; + + resip::Pidf p; + p.setEntity(contact(SecureScheme::Nothing).uri()); + p.setSimpleId(resip::Data(CONFIG(CONFIG_PRESENCE_ID).asStdString())); + p.setSimpleStatus(online, resip::Data(content)); + + if (mPublication.isValid()) + mPublication->update(&p); + else + mAgent.mDum->send(mAgent.mDum->makePublication(contact(SecureScheme::TlsOnly), mProfile, p, resip::Symbols::Presence, seconds)); +} + +void Account::stopPublish() +{ + if (mPublication.isValid()) + mPublication->end(); +} + +PClientObserver Account::observe(const std::string& target, const std::string& package, void* tag) +{ + // Add subscription functionality + PClientObserver observer(new ClientObserver()); + observer->mSession = new ResipSession(*mAgent.mDum); + observer->mSession->setRemoteAddress(target); + observer->mSession->setTag(tag); + observer->mSessionId = observer->mSession->sessionId(); + observer->mPeer = target; + + resip::SharedPtr msg; + int expires = DEFAULT_SUBSCRIPTION_TIME, refresh = DEFAULT_SUBSCRIPTION_REFRESHTIME; + if (mConfig->exists(CONFIG_SUBSCRIPTION_TIME)) + expires = CONFIG(CONFIG_SUBSCRIPTION_TIME).asInt(); + if (mConfig->exists(CONFIG_SUBSCRIPTION_REFRESHTIME)) + refresh = CONFIG(CONFIG_SUBSCRIPTION_REFRESHTIME).asInt(); + + msg = mAgent.mDum->makeSubscription(resip::NameAddr(resip::Data(target)), mProfile, + resip::Data(package), expires, refresh, observer->mSession); + msg->header(resip::h_Accepts) = mAgent.mDum->getMasterProfile()->getSupportedMimeTypes(resip::NOTIFY); + + mAgent.mClientObserverMap[observer->mSessionId] = observer; + mAgent.mDum->send(msg); + + return observer; +} + +/* Queues message to peer with specified mime type. Returns ID of message. */ +int Account::sendMsg(const std::string& peer, const void* ptr, unsigned length, const std::string& mime, void* tag) +{ + ResipSession* s = new ResipSession(*mAgent.mDum); + s->setUa(&mAgent); + s->setTag(tag); + s->setRemoteAddress(peer); + + // Find MIME type + resip::Mime type; + std::string::size_type p = mime.find('/'); + if (p != std::string::npos) + type = resip::Mime(resip::Data(mime.substr(0, p)), resip::Data(mime.substr(p+1))); + else + type = resip::Mime(resip::Data(mime), resip::Data()); + + resip::ClientPagerMessageHandle msgHandle = mAgent.mDum->makePagerMessage(resip::NameAddr(resip::Data(peer)), mProfile, s); + auto_ptr contentPtr(new resip::PlainContents(resip::Data(std::string((const char*)ptr, length)),type)); + int result = s->sessionId(); + msgHandle->page(contentPtr); + + return result; +} + +resip::NameAddr Account::contact(SecureScheme ss) +{ + resip::NameAddr result; + switch (ss) + { + case SecureScheme::Nothing: + break; + case SecureScheme::SipsOnly: + result.uri().scheme() = mConfig->at(CONFIG_SIPS).asBool() ? "sips" : "sip"; + break; + case SecureScheme::SipsAndTls: + result.uri().scheme() = mConfig->at(CONFIG_SIPS).asBool() ? "sips" : "sip"; + if (mConfig->at(CONFIG_SIPS).asBool()) + result.uri().param(resip::p_transport) = "tls"; + break; + case SecureScheme::TlsOnly: + if (mConfig->at(CONFIG_SIPS).asBool()) + result.uri().param(resip::p_transport) = "tls"; + break; + } + + result.uri().user() = resip::Data(mConfig->at(CONFIG_USERNAME).asStdString()); + result.uri().host() = resip::Data(mConfig->at(CONFIG_DOMAIN).asStdString()); + result.uri().port() = mConfig->at(CONFIG_DOMAINPORT).asInt(); + + return result; +} + +void Account::queryStunServerIp() +{ + ICELogInfo(<<"Looking for STUN/TURN server IP"); + + if (!mConfig->exists(CONFIG_STUNSERVER_NAME)) + { + // Send request to find STUN or TURN service + std::string target = std::string(mConfig->at(CONFIG_RELAY).asBool() ? "_turn" : "_stun") + "._udp." + mConfig->at(CONFIG_DOMAIN).asStdString(); + + // Start lookup + mAgent.mStack->getDnsStub().lookup(resip::Data(target), this); + } + else + { + // Check if host name is ip already + std::string server = mConfig->at(CONFIG_STUNSERVER_NAME).asStdString(); + if (ice::NetworkAddress::isIp(server)) + { + mConfig->at(CONFIG_STUNSERVER_IP) = server; + mRefreshStunServerIpTimer.stop(); + } + else + mAgent.mStack->getDnsStub().lookup(resip::Data(server), this); + } +} + +void Account::prepareIceStack(Session *session, ice::AgentRole icerole) +{ + ice::ServerConfig config; + ice::NetworkAddress addr; + addr.setIp(mConfig->at(CONFIG_STUNSERVER_IP).asStdString()); + if (mConfig->at(CONFIG_STUNSERVER_PORT).asInt()) + addr.setPort(mConfig->at(CONFIG_STUNSERVER_PORT).asInt()); + else + addr.setPort(3478); + + config.mServerList4.push_back(addr); + config.mRelay = mConfig->at(CONFIG_RELAY).asBool(); + if (mConfig->exists(CONFIG_ICETIMEOUT)) + config.mTimeout = mConfig->at(CONFIG_ICETIMEOUT).asInt(); + + config.mUsername = mConfig->at(CONFIG_ICEUSERNAME).asStdString(); + config.mPassword = mConfig->at(CONFIG_ICEPASSWORD).asStdString(); + + config.mUseIPv4 = mAgent.config()[CONFIG_IPV4].asBool(); + config.mUseIPv6 = mAgent.config()[CONFIG_IPV6].asBool(); + //config.mDetectNetworkChange = true; + //config.mNetworkCheckInterval = 5000; + + session->mIceStack = resip::SharedPtr(ice::Stack::makeICEBox(config)); + session->mIceStack->setEventHandler(session, this); + session->mIceStack->setRole(icerole); +} + +void Account::process() +{ + if (mRefreshStunServerIpTimer.isTimeToSend()) + queryStunServerIp(); +} + +void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage &response) +{ + // Save registration handle + mRegistrationHandle = h; + + // Copy user info to registration handle + for (UserInfo::iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++) + mRegistrationHandle->setCustomHeader(resip::Data(iter->first.c_str()), resip::Data(iter->second.c_str())); + + // Get the Via + const resip::Via& via = response.header(resip::h_Vias).front(); + + // Get the sent host + const resip::Data& sentHost = via.sentHost();//response.header(h_Contacts).front().uri().host(); + + // Get the sentPort + int sentPort = via.sentPort(); + + const resip::Data& sourceHost = response.getSource().toData(resip::UDP); + int rport = 0; + if (via.exists(resip::p_rport)) + rport = via.param(resip::p_rport).port(); + + resip::Data received = ""; + if (via.exists(resip::p_received)) + received = via.param(resip::p_received); + + bool hostChanged = sentHost != received && received.size() > 0; + bool portChanged = sentPort != rport && rport != 0; + + // Save external port and IP address + if (received.size() > 0 /*&& mConfig->at(CONFIG_EXTERNALIP).asBool()*/) + { + mExternalAddress.setIp(received.c_str()); + mExternalAddress.setPort(rport ? rport : sentPort); + + // Add new external address to domain list + if (mAgent.mStack) + mAgent.mStack->addAlias(resip::Data(mExternalAddress.ip()), mExternalAddress.port()); + if (mAgent.mDum) + mAgent.mDum->addDomain(resip::Data(mExternalAddress.ip())); + } + + const resip::Transport* transport = response.getReceivedTransport(); + mUsedTransport = transport->transport(); + bool streamTransport = transport->transport() == resip::TCP || transport->transport() == resip::TLS; + + // Retry registration for stream based transport too + if ( (hostChanged || portChanged) && mRegistrationState == RegistrationState::Registering /*&& !streamTransport*/ && mConfig->at(CONFIG_EXTERNALIP).asBool()) + { + //mRegistrationHandle->requestRefresh(); + // Unregister at first + mRegistrationHandle->removeAll(); + mRegistrationState = RegistrationState::Reregistering; + return; + } + + // So here we registered ok + mRegistrationState = RegistrationState::Registered; + mAgent.onAccountStart(mAgent.getAccount(this)); +} + +void Account::onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage &response) +{ + // Check if this unregistering is a part of rport pr + if (mRegistrationState == RegistrationState::Reregistering) + { + //if (/*this->mUseExternalIP && */response.getSource().getType() == resip::UDP) + { + resip::Uri hostport(contact(SecureScheme::TlsOnly).uri()); + hostport.host() = resip::Data(mExternalAddress.ip()); + hostport.port() = mExternalAddress.port(); + if (mUsedTransport != resip::UDP) + { + const char* transportName = nullptr; + switch (mUsedTransport) + { + case resip::TCP: transportName = "tcp"; break; + case resip::TLS: transportName = "tls"; break; + } + + hostport.param(resip::p_transport) = resip::Data(transportName); + } + mProfile->setOverrideHostAndPort(hostport); + //mProfile->setDefaultFrom(from); + } + mProfile->setRegId(mConfig->at(CONFIG_REGID).asInt()); + resip::SharedPtr regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile, UA_REGISTRATION_TIME); + for (UserInfo::const_iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++) + regmessage->header(resip::ExtensionHeader(iter->first.c_str())).push_back(resip::StringCategory(iter->second.c_str())); + + mAgent.mDum->send(regmessage); + return; + } + else + { + mRegistration = NULL; + mRegistrationState = RegistrationState::None; + mRegistrationHandle = resip::ClientRegistrationHandle(); + mAgent.onAccountStop(mAgent.getAccount(this), response.header(resip::h_StatusLine).statusCode()); + } +} + +void Account::onFailure(resip::ClientRegistrationHandle h, const resip::SipMessage& response) +{ + // Reset registration handle + mRegistrationHandle = resip::ClientRegistrationHandle(); + mRegistrationState = RegistrationState::None; + mRegistration = NULL; + mAgent.onAccountStop(mAgent.getAccount(this), response.header(resip::h_StatusLine).statusCode()); +} + +void Account::onDnsResult(const resip::DNSResult& result) +{ + if (result.status == 0) + { + resip::Data foundAddress = result.records.front().host(); + ICELogCritical( << "Success to resolve STUN/TURN address to " << foundAddress.c_str()); + mConfig->at(CONFIG_STUNSERVER_IP) = std::string(foundAddress.c_str()); + + // Here the IP address of STUN/TURN server is found. If account is registered already - it means account is ready. + if (mRegistrationState == RegistrationState::Registered) + mAgent.onAccountStart(mAgent.getAccount(this)); + } + else + { + ICELogCritical( << "Failed to resolve STUN or TURN server IP address."); + if (mRegistrationState == RegistrationState::Registered) + { + int startCode = mConfig->at(CONFIG_STUNSERVER_NAME).asStdString().empty() ? 0 : 503; + mAgent.onAccountStop(mAgent.getAccount(this), startCode); + } + } +} + +void Account::onDnsResult(const resip::DNSResult&) +{ + +} + +void Account::onDnsResult(const resip::DNSResult& result) +{ + if (result.status == 0) + { + // Find lowest priority + int priority = 0x7FFFFFFF; + for (size_t i=0; i= weight) + { + index = i; + weight = result.records[i].weight(); + } + } + + mConfig->at(CONFIG_STUNSERVER_PORT) = result.records[index].port(); + + const char* host = result.records[index].target().c_str(); + + ICELogCritical( << "Success to find STUN/TURN server on " << result.records[index].target().c_str() << + ":" << (int)result.records[index].port()); + + + if (inet_addr(host) == INADDR_NONE) + { + // Try to resolve domain name now + mAgent.mStack->getDnsStub().lookup(result.records[index].target(), this); + //mStack->getDnsStub().lookup(result.records[index].target(), this); + } + else + { + mConfig->at(CONFIG_STUNSERVER_IP) = std::string(host); + } + } + else + { + ICELogCritical( << "Failed to find STUN or TURN service for specified domain."); + //mAgent::shutdown(); + } + +} + +void Account::onDnsResult(const resip::DNSResult&) +{ + +} + +void Account::onDnsResult(const resip::DNSResult&) +{ + +} + +bool Account::isResponsibleFor(const resip::NameAddr &addr) +{ + std::string user = addr.uri().user().c_str(); + std::string domain = addr.uri().host().c_str(); + int p = addr.uri().port(); + if (mConfig->at(CONFIG_USERNAME).asStdString() == user && mConfig->at(CONFIG_DOMAIN).asStdString() == domain) + { + // Check if ports are the same or port is not specified at all + if (mConfig->exists(CONFIG_DOMAINPORT)) + return mConfig->at(CONFIG_DOMAINPORT).asInt() == p || !p; + else + return true; + } + else + return false; +} + +void Account::setUserInfo(const UserInfo &info) +{ + mUserInfo = info; + if (mRegistrationHandle.isValid()) + { + for (UserInfo::iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++) + mRegistrationHandle->setCustomHeader(resip::Data(iter->first.c_str()), resip::Data(iter->second.c_str())); + } +} + +Account::UserInfo Account::getUserInfo() const +{ + return mUserInfo; +} + +resip::AtomicCounter Account::IdGenerator; +int Account::generateId() +{ + return IdGenerator.increment(); +} diff --git a/src/engine/endpoint/EP_Account.h b/src/engine/endpoint/EP_Account.h new file mode 100644 index 00000000..fac58c6c --- /dev/null +++ b/src/engine/endpoint/EP_Account.h @@ -0,0 +1,143 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef EP_ACCOUNT_H +#define EP_ACCOUNT_H + +#include "../helper/HL_Pointer.h" +#include "../helper/HL_VariantMap.h" +#include "ice/ICEAddress.h" +#include "ice/ICETime.h" +#include "ice/ICEBox.h" +#include "resip/dum/UserProfile.hxx" +#include "resip/dum/ClientRegistration.hxx" +#include "resip/dum/ClientPublication.hxx" +#include "resip/stack/DnsInterface.hxx" +#include "resip/stack/NameAddr.hxx" + +#include "EP_Observer.h" + +class UserAgent; +class Session; + +class Account: public resip::DnsResultSink +{ +friend class UserAgent; +friend class NATDecorator; +public: + Account(PVariantMap config, UserAgent& agent); + ~Account(); + + void start(); + void stop(); + void refresh(); + bool active(); + int id() const; + + enum class RegistrationState + { + None, + Registering, + Reregistering, + Registered, + Unregistering + }; + RegistrationState registrationState(); + + /* Publishes new presence information */ + void publishPresence(bool online, const std::string& content, int seconds = 600); + + /* Stops publishing of presence */ + void stopPublish(); + + /* Starts observing on specified target / package */ + PClientObserver observe(const std::string& target, const std::string& package, void* tag); + + /* Queues message to peer with specified mime type. Returns ID of message. */ + int sendMsg(const std::string& peer, const void* ptr, unsigned length, const std::string& mime, void* tag); + + /* Returns name of account - */ + std::string name(); + + /* Updates account with configuration */ + void setup(VariantMap& config); + + /* Returns corresponding resiprocate profile */ + resip::SharedPtr getUserProfile() const { return mProfile; } + + typedef std::map UserInfo; + void setUserInfo(const UserInfo& info); + UserInfo getUserInfo() const; + +protected: + PVariantMap mConfig; + + // Registration + ResipSession* mRegistration; + resip::ClientRegistrationHandle mRegistrationHandle; + resip::ClientPublicationHandle mPublication; + resip::TransportType mUsedTransport; + + RegistrationState mRegistrationState; + + ice::NetworkAddress mExternalAddress; + resip::SharedPtr mProfile; + UserAgent& mAgent; + bool mPresenceOnline; + std::string mPresenceContent; + + // Timer to refresh STUN server IP + ice::ICEScheduleTimer mRefreshStunServerIpTimer; + + // Cached auth + resip::Auth mCachedAuth; + + // Id of account + int mId; + + // User info about current state + UserInfo mUserInfo; + + // List of client subscriptions sent from this account + typedef std::set ClientObserverSet; + ClientObserverSet mClientObserverSet; + + + void process(); + // Method queries new stun server ip from dns (if stun server is specified as dns name) + void queryStunServerIp(); + + bool isResponsibleFor(const resip::NameAddr& addr); + enum class SecureScheme + { + SipsAndTls, + SipsOnly, + TlsOnly, + Nothing + }; + + resip::NameAddr contact(SecureScheme ss = SecureScheme::SipsOnly); + + // This method prepares configuration, creates ice stack and sets ownership to session + void prepareIceStack(Session* session, ice::AgentRole role); + void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response); + void onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response); + void onFailure(resip::ClientRegistrationHandle, const resip::SipMessage& response); + +#pragma region DnsResultSink implementation + void onDnsResult(const resip::DNSResult&); + void onDnsResult(const resip::DNSResult&); + void onDnsResult(const resip::DNSResult&); + void onDnsResult(const resip::DNSResult&); + void onDnsResult(const resip::DNSResult&); +#pragma endregion + + static int generateId(); + static resip::AtomicCounter IdGenerator; +}; + +typedef std::shared_ptr PAccount; + +#endif // EP_ACCOUNT_H diff --git a/src/engine/endpoint/EP_AudioProvider.cpp b/src/engine/endpoint/EP_AudioProvider.cpp new file mode 100644 index 00000000..1c8edc03 --- /dev/null +++ b/src/engine/endpoint/EP_AudioProvider.cpp @@ -0,0 +1,380 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "EP_AudioProvider.h" +#include "EP_Engine.h" +#include "../media/MT_Box.h" +#include "../media/MT_AudioStream.h" +#include "../media/MT_SrtpHelper.h" +#include "../media/MT_Stream.h" +#include "../helper/HL_Rtp.h" +#include "../helper/HL_StreamState.h" +#include "../helper/HL_Log.h" +#include "../helper/HL_String.h" + +#define LOG_SUBSYSTEM "AudioProvider" + +AudioProvider::AudioProvider(UserAgent& agent, MT::Terminal& terminal) +:mUserAgent(agent), mTerminal(terminal), mState(0), +mRemoteTelephoneCodec(0), mRemoteNoSdp(false) +{ + mActive = mfActive; + mRemoteState = msSendRecv; + mActiveStream = mTerminal.createStream(MT::Stream::Audio, mUserAgent.config()); + if (mUserAgent.config().exists(CONFIG_CODEC_PRIORITY)) + mCodecPriority.setupFrom(mUserAgent.config()[CONFIG_CODEC_PRIORITY].asVMap()); + mSrtpSuite = SRTP_NONE; + setState((int)StreamState::SipRecv | (int)StreamState::SipSend | (int)StreamState::Receiving | (int)StreamState::Sending); +} + +AudioProvider::~AudioProvider() +{ +} + +std::string AudioProvider::streamName() +{ + return "audio"; +} + +std::string AudioProvider::streamProfile() +{ + if (mState & (int)StreamState::Srtp) + return "RTP/SAVP"; + else + return "RTP/AVP"; +} + +// Sets destination IP address +void AudioProvider::setDestinationAddress(const RtpPair& addr) +{ + if (!mActiveStream) + return; + + mActiveStream->setDestination(addr); +} + +void AudioProvider::configureMediaObserver(MT::Stream::MediaObserver *observer, void* userTag) +{ + mMediaObserver = observer; + mMediaObserverTag = userTag; + if (mActiveStream) + mActiveStream->configureMediaObserver(observer, userTag); +} + +// Processes incoming data +void AudioProvider::processData(PDatagramSocket s, const void* dataBuffer, int dataSize, InternetAddress& source) +{ + if (!mActiveStream) + return; + + if (RtpHelper::isRtpOrRtcp(dataBuffer, dataSize)) + { + ICELogMedia(<<"Adding new data to stream processing"); + mActiveStream->dataArrived(s, dataBuffer, dataSize, source); + } +} + +// This method is called by user agent to send ICE packet from mediasocket +void AudioProvider::sendData(PDatagramSocket s, InternetAddress& destination, const void* buffer, unsigned int size) +{ + s->sendDatagram(destination, buffer, size); +} + +// Create SDP offer +void AudioProvider::updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) +{ + if (mRemoteNoSdp) + return; + + if (mState & (int)StreamState::Srtp) + { + // Check if SRTP suite is found already or not + if (mSrtpSuite == SRTP_NONE) + { + for (int suite = SRTP_AES_128_AUTH_80; suite <= SRTP_LAST; suite++) + sdp.addAttribute("crypto", resip::Data(createCryptoAttribute((SrtpSuite)suite))); + } + else + sdp.addAttribute("crypto", resip::Data(createCryptoAttribute(mSrtpSuite))); + } + + // Use CodecListPriority mCodecPriority adapter to work with codec priorities + if (mAvailableCodecs.empty()) + { + for (int i=0; iupdateSdp(sdp.codecs(), direction); + if (mRemoteTelephoneCodec) + sdp.addCodec(resip::SdpContents::Session::Codec::TelephoneEvent); + } + + // Publish stream state + const char* attr = nullptr; + switch (mActive) + { + case mfActive: + switch(mRemoteState) + { + case msSendonly: attr = "recvonly"; break; + case msInactive: attr = "recvonly"; break; + } + break; + + case mfPaused: + switch (mRemoteState) + { + case msRecvonly: attr = "sendonly"; break; + case msSendonly: attr = "inactive"; break; + case msInactive: attr = "inactive"; break; + case msSendRecv: attr = "sendonly"; break; + } + break; + } + if (attr) + sdp.addAttribute(attr); +} + +void AudioProvider::sessionDeleted() +{ + sessionTerminated(); +} + +void AudioProvider::sessionTerminated() +{ + ICELogDebug(<< "sessionTerminated() for audio provider"); + setState(state() & ~((int)StreamState::Sending | (int)StreamState::Receiving)); + + if (mActiveStream) + { + ICELogDebug(<< "Copy statistics from existing stream before freeing."); + + // Copy statistics - maybe it will be requested later + mBackupStats = mActiveStream->statistics(); + + ICELogDebug(<< "Remove stream from terminal"); + mTerminal.freeStream(mActiveStream); + + // Retrieve final statistics + MT::AudioStream* audio_stream = dynamic_cast(mActiveStream.get()); + if (audio_stream) + audio_stream->setFinalStatisticsOutput(&mBackupStats); + + ICELogDebug(<< "Reset reference to stream."); + mActiveStream.reset(); + } +} + +void AudioProvider::sessionEstablished(int conntype) +{ + // Start media streams + setState(state() | (int)StreamState::Receiving | (int)StreamState::Sending); + + // Available codec list can be empty in case of no-sdp offers. + if (conntype == EV_SIP && !mAvailableCodecs.empty() && mActiveStream) + { + RemoteCodec& rc = mAvailableCodecs.front(); + mActiveStream->setTransmittingCodec(*rc.mFactory, rc.mRemotePayloadType); + dynamic_cast(mActiveStream.get())->setTelephoneCodec(mRemoteTelephoneCodec); + } +} + +void AudioProvider::setSocket(const RtpPair& p4, const RtpPair& p6) +{ + mSocket4 = p4; + mSocket6 = p6; + mActiveStream->setSocket(p4); +} + +RtpPair& AudioProvider::socket(int family) +{ + switch (family) + { + case AF_INET: + return mSocket4; + + case AF_INET6: + return mSocket6; + } + return mSocket4; +} + + +bool AudioProvider::processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection) +{ + // Check if there is compatible codec + mAvailableCodecs.clear(); + mRemoteTelephoneCodec = 0; + + // Check if there is SDP at all + mRemoteNoSdp = media.codecs().empty(); + if (mRemoteNoSdp) + return true; + + // Update RFC2833 related information + findRfc2833(media.codecs()); + + // Use CodecListPriority mCodecPriority to work with codec priorities + int pt; + for (int localIndex=0; localIndex& vl = media.getValues("crypto"); + SrtpSuite ss = SRTP_NONE; + ByteBuffer key; + for (std::list::const_iterator attrIter = vl.begin(); attrIter != vl.end(); attrIter++) + { + const resip::Data& attr = *attrIter; + ByteBuffer tempkey; + SrtpSuite suite = processCryptoAttribute(attr, tempkey); + if (suite > ss) + { + ss = suite; + mSrtpSuite = suite; + key = tempkey; + } + } + + // If SRTP suite is agreed + if (ss != SRTP_NONE) + { + ICELogInfo(<< "Found SRTP suite " << ss); + mActiveStream->srtp().open(key, ss); + setState(state() | (int)StreamState::Srtp); + } + else + ICELogInfo(<< "Did not find valid SRTP suite"); + } + + DataProvider::processSdpOffer(media, sdpDirection); + + return true; +} + +void AudioProvider::setState(unsigned state) +{ + mState = state; + if (mActiveStream) + mActiveStream->setState(state); +} + +unsigned AudioProvider::state() +{ + return mState; +} + +MT::Statistics AudioProvider::getStatistics() +{ + if (mActiveStream) + return mActiveStream->statistics(); + else + return mBackupStats; +} + +MT::PStream AudioProvider::activeStream() +{ + return mActiveStream; +} + +std::string AudioProvider::createCryptoAttribute(SrtpSuite suite) +{ + if (!mActiveStream) + return ""; + + // Use tag 1 - it is ok, as we use only single crypto attribute + int srtpTag = 1; + + // Print key to base64 string + PByteBuffer keyBuffer = mActiveStream->srtp().outgoingKey(suite).first; + resip::Data d(keyBuffer->data(), keyBuffer->size()); + resip::Data keyText = d.base64encode(); + + // Create "crypto" attribute value + char buffer[512]; + const char* suiteName = NULL; + switch (suite) + { + case SRTP_AES_128_AUTH_80: suiteName = SRTP_SUITE_NAME_1; break; + case SRTP_AES_256_AUTH_80: suiteName = SRTP_SUITE_NAME_2; break; + default: assert(0); + } + sprintf(buffer, "%d %s inline:%s", srtpTag, suiteName, keyText.c_str()); + + return buffer; +} + +SrtpSuite AudioProvider::processCryptoAttribute(const resip::Data& value, ByteBuffer& key) +{ + int srtpTag = 0; + char suite[64], keyChunk[256]; + int components = sscanf(value.c_str(), "%d %63s inline: %255s", &srtpTag, suite, keyChunk); + if (components != 3) + return SRTP_NONE; + + const char* delimiter = strchr(keyChunk, '|'); + resip::Data keyText; + if (delimiter) + keyText = resip::Data(keyChunk, delimiter - keyChunk); + else + keyText = resip::Data(keyChunk); + + resip::Data rawkey = keyText.base64decode(); + key = ByteBuffer(rawkey.c_str(), rawkey.size()); + + // Open srtp + SrtpSuite result = SRTP_NONE; + if (strcmp(suite, SRTP_SUITE_NAME_1) == 0) + result = SRTP_AES_128_AUTH_80; + else + if (strcmp(suite, SRTP_SUITE_NAME_2) == 0) + result = SRTP_AES_256_AUTH_80; + + return result; +} + +void AudioProvider::findRfc2833(const resip::SdpContents::Session::Medium::CodecContainer& codecs) +{ + resip::SdpContents::Session::Medium::CodecContainer::const_iterator codecIter; + for (codecIter = codecs.begin(); codecIter != codecs.end(); codecIter++) + { + if (strcmp("TELEPHONE-EVENT", codecIter->getName().c_str()) == 0 || + strcmp("telephone-event", codecIter->getName().c_str()) == 0) + mRemoteTelephoneCodec = codecIter->payloadType(); + } +} + +void AudioProvider::readFile(const Audio::PWavFileReader& stream, MT::Stream::MediaDirection direction) +{ + // Iterate stream list + if (mActiveStream) + mActiveStream->readFile(stream, direction); +} + +void AudioProvider::writeFile(const Audio::PWavFileWriter& stream, MT::Stream::MediaDirection direction) +{ + if (mActiveStream) + mActiveStream->writeFile(stream, direction); +} + +void AudioProvider::setupMirror(bool enable) +{ + if (mActiveStream) + mActiveStream->setupMirror(enable); +} diff --git a/src/engine/endpoint/EP_AudioProvider.h b/src/engine/endpoint/EP_AudioProvider.h new file mode 100644 index 00000000..5baddea3 --- /dev/null +++ b/src/engine/endpoint/EP_AudioProvider.h @@ -0,0 +1,117 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __AUDIO_PROVIDER_H +#define __AUDIO_PROVIDER_H + +#include "EP_DataProvider.h" +#include "../helper/HL_InternetAddress.h" +#include "../helper/HL_Rtp.h" +#include "../media/MT_Box.h" +#include "../media/MT_Stream.h" +#include "../media/MT_Codec.h" +#include "../audio/Audio_Interface.h" + +#include "rutil/ThreadIf.hxx" +#include +#include + +class UserAgent; + +class AudioProvider: public DataProvider +{ +public: + + AudioProvider(UserAgent& agent, MT::Terminal& terminal); + virtual ~AudioProvider(); + + // Returns provider RTP name + std::string streamName(); + + // Returns provider RTP profile name + std::string streamProfile(); + + // Sets destination IP address + void setDestinationAddress(const RtpPair& addr); + + // Processes incoming data + void processData(PDatagramSocket s, const void* dataBuffer, int dataSize, InternetAddress& source); + + // This method is called by user agent to send ICE packet from mediasocket + void sendData(PDatagramSocket s, InternetAddress& destination, const void* dataBuffer, unsigned int datasize); + + // Updates SDP offer + void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction); + + // Called by user agent when session is deleted. + void sessionDeleted(); + + // Called by user agent when session is terminated. + void sessionTerminated(); + + // Called by user agent when session is started. + void sessionEstablished(int conntype); + + // Called by user agent to save media socket for this provider + void setSocket(const RtpPair& p4, const RtpPair& p6); + + // Called by user agent to get media socket for this provider + RtpPair& socket(int family); + + // Called by user agent to process media stream description from remote peer. + // Returns true if description is processed succesfully. Otherwise method returns false. + // myAnswer sets if the answer will be sent after. + bool processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection); + + void setState(unsigned state); + unsigned state(); + MT::Statistics getStatistics(); + MT::PStream activeStream(); + + void readFile(const Audio::PWavFileReader& stream, MT::Stream::MediaDirection direction); + void writeFile(const Audio::PWavFileWriter& stream, MT::Stream::MediaDirection direction); + void setupMirror(bool enable); + + void configureMediaObserver(MT::Stream::MediaObserver* observer, void* userTag); + +protected: + // SDP's stream name + std::string mStreamName; + + // Socket handles to operate + RtpPair mSocket4, mSocket6; + + // Destination IP4/6 address + RtpPair mDestination; + + MT::PStream mActiveStream; + UserAgent& mUserAgent; + MT::Terminal& mTerminal; + MT::Statistics mBackupStats; + + unsigned mState; + SrtpSuite mSrtpSuite; + struct RemoteCodec + { + RemoteCodec(MT::Codec::Factory* factory, int payloadType) + :mFactory(factory), mRemotePayloadType(payloadType) + { } + + MT::Codec::Factory* mFactory; + int mRemotePayloadType; + }; + std::vector mAvailableCodecs; + int mRemoteTelephoneCodec; // Payload type of remote rfc2833 codec + bool mRemoteNoSdp; // Marks if we got no-sdp offer + MT::CodecListPriority mCodecPriority; + MT::Stream::MediaObserver* mMediaObserver = nullptr; + void* mMediaObserverTag = nullptr; + + std::string createCryptoAttribute(SrtpSuite suite); + SrtpSuite processCryptoAttribute(const resip::Data& value, ByteBuffer& key); + void findRfc2833(const resip::SdpContents::Session::Medium::CodecContainer& codecs); +}; + +#endif diff --git a/src/engine/endpoint/EP_DataProvider.cpp b/src/engine/endpoint/EP_DataProvider.cpp new file mode 100644 index 00000000..dcba1d49 --- /dev/null +++ b/src/engine/endpoint/EP_DataProvider.cpp @@ -0,0 +1,74 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "EP_DataProvider.h" +#include "../helper/HL_StreamState.h" + +bool DataProvider::isSupported(const char* name) +{ + return !strcmp(name, "audio"); + + //return (!strcmp(name, "screen") || !strcmp(name, "data") || !strcmp(name, "audio") || !strcmp(name, "video")); +} + +void DataProvider::pause() +{ + /*if (state() & STATE_SIPRECV) + setState( state() & ~STATE_SIPRECV );*/ + + // Stop receive RTP stream + if (state() & (int)StreamState::Receiving) + setState( state() & ~(int)StreamState::Receiving ); + + mActive = mfPaused; +} + +void DataProvider::resume() +{ + // Tell remote peer about resumed receiving in SDP + //setState( state() | STATE_SIPRECV ); + + // Start receive RTP stream + setState( state() | (int)StreamState::Receiving ); + + mActive = mfActive; +} + +bool DataProvider::processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection) +{ + // Process paused and inactive calls + if (media.exists("sendonly")) + { + mRemoteState = msSendonly; + setState(state() & ~(int)StreamState::Sending); + } + else + if (media.exists("recvonly")) + { + mRemoteState = msRecvonly; + setState(state() & ~(int)StreamState::Receiving); + } + else + if (media.exists("inactive")) + { + mRemoteState = msInactive; + setState(state() & ~((int)StreamState::Sending | (int)StreamState::Receiving) ); + } + else + { + mRemoteState = msSendRecv; + switch (mActive) + { + case mfActive: + setState(state() | (int)StreamState::Sending | (int)StreamState::Receiving); + break; + + case mfPaused: + setState(state() | (int)StreamState::Sending ); + break; + } + } + return true; +} diff --git a/src/engine/endpoint/EP_DataProvider.h b/src/engine/endpoint/EP_DataProvider.h new file mode 100644 index 00000000..5727f8d3 --- /dev/null +++ b/src/engine/endpoint/EP_DataProvider.h @@ -0,0 +1,92 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __DATA_PROVIDER_H +#define __DATA_PROVIDER_H + +#include +#include + +#include "resip/stack/SdpContents.hxx" +#include "rutil/SharedPtr.hxx" + +#include "../helper/HL_InternetAddress.h" +#include "../helper/HL_NetworkSocket.h" +#include "../helper/HL_Pointer.h" +#include "../media/MT_Stream.h" + +class DataProvider +{ +public: + enum MediaFlow + { + mfActive, + mfPaused + }; + + enum MediaState + { + msSendRecv, + msSendonly, + msRecvonly, + msInactive + }; + + static bool isSupported(const char* name); + + // Returns provider RTP name + virtual std::string streamName() = 0; + + // Returns provider RTP profile name + virtual std::string streamProfile() = 0; + + // Sets destination IP address + virtual void setDestinationAddress(const RtpPair& addr) = 0; + + // Processes incoming data + virtual void processData(PDatagramSocket s, const void* dataBuffer, int dataSize, InternetAddress& address) = 0; + + // This method is called by user agent to send ICE packet from mediasocket + virtual void sendData(PDatagramSocket s, InternetAddress& destination, const void* dataBuffer, unsigned int datasize) = 0; + + // Updates SDP offer + virtual void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) = 0; + + // Called by user agent when session is deleted. Comes after sessionTerminated(). + virtual void sessionDeleted() = 0; + + // Called by user agent when session is terminated. + virtual void sessionTerminated() = 0; + + // Called by user agent when session is started. + virtual void sessionEstablished(int conntype) = 0; + + // Called by user agent to save media socket for this provider + virtual void setSocket(const RtpPair& p4, const RtpPair& p6) = 0; + + // Called by user agent to get media socket for this provider + virtual RtpPair& socket(int family) = 0; + + // Called by user agent to process media stream description from remote peer. + // Returns true if description is processed succesfully. Otherwise method returns false. + virtual bool processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection) = 0; + + virtual unsigned state() = 0; + virtual void setState(unsigned state) = 0; + + virtual void pause(); + virtual void resume(); + + virtual MT::Statistics getStatistics() = 0; + +protected: + MediaFlow mActive; + MediaState mRemoteState; +}; + +typedef std::shared_ptr PDataProvider; +typedef std::vector DataProviderVector; + +#endif diff --git a/src/engine/endpoint/EP_Engine.cpp b/src/engine/endpoint/EP_Engine.cpp new file mode 100644 index 00000000..e359d16c --- /dev/null +++ b/src/engine/endpoint/EP_Engine.cpp @@ -0,0 +1,1612 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "EP_Engine.h" +#include "EP_AudioProvider.h" +#include "../media/MT_AudioStream.h" + +#include "../helper/HL_Exception.h" +#include "../helper/HL_Log.h" +#include "../helper/HL_String.h" +#include "rutil/DnsUtil.hxx" +#include "resip/stack/DnsResult.hxx" +#include "resip/stack/SipStack.hxx" +#include "resip/stack/TcpBaseTransport.hxx" +#include "resip/stack/ExtensionParameter.hxx" +#include "resip/stack/MultipartRelatedContents.hxx" +#include "resip/stack/Rlmi.hxx" +#include "resip/stack/Pidf.hxx" +#include "resip/stack/ExtensionHeader.hxx" +#include "resip/stack/ssl/Security.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/XMLCursor.hxx" +#include "rutil/dns/RRVip.hxx" +#include "rutil/dns/QueryTypes.hxx" +#include "rutil/dns/DnsStub.hxx" +#include "resip/stack/Pidf.hxx" +#include "resip/stack/PlainContents.hxx" +#include "resip/dum/InviteSession.hxx" + +#if defined(TARGET_OSX) +# include "resip/stack/ssl/MacSecurity.hxx" +#endif + +#if defined(TARGET_WIN) +# include "resip/stack/ssl/WinSecurity.hxx" +#endif + +#define LOG_SUBSYSTEM "[Engine]" +#define LOCK Lock l(mGuard) +#define CAST2RESIPSESSION(x) (x.isValid() ? (x->getAppDialogSet().isValid() ? dynamic_cast(x->getAppDialogSet().get()) : NULL) : NULL) + +typedef resip::SdpContents::Session::Medium Medium; +typedef resip::SdpContents::Session::MediumContainer MediumContainer; + +//-------------- UserAgent ----------------------- +UserAgent::UserAgent() +{ + mStack = nullptr; + mDum = nullptr; + + mConfig[CONFIG_PRESENCE_ID] = std::string("device"); + mConfig[CONFIG_RTCP_ATTR] = true; + + // Create master profile + mProfile = resip::SharedPtr(new resip::MasterProfile()); + mProfile->clearSupportedMethods(); + mProfile->addSupportedMethod(resip::INVITE); + mProfile->addSupportedMethod(resip::BYE); + mProfile->addSupportedMethod(resip::CANCEL); + mProfile->addSupportedMethod(resip::REGISTER); + mProfile->addSupportedMethod(resip::NOTIFY); + mProfile->addSupportedMethod(resip::SUBSCRIBE); + mProfile->addSupportedMethod(resip::OPTIONS); + mProfile->addSupportedMethod(resip::UPDATE); + mProfile->addSupportedMethod(resip::MESSAGE); + mProfile->addSupportedMethod(resip::ACK); + mProfile->clearDigestCredentials(); + mProfile->unsetOutboundProxy(); +} + +UserAgent::~UserAgent() +{ + LOCK; + + shutdown(); + mAccountSet.clear(); + mClientObserverMap.clear(); + mServerObserverMap.clear(); + mSessionMap.clear(); +} + + +void UserAgent::start() +{ + ICELogInfo(<< "Attempt to start endpoint."); + LOCK; + if (mStack) + { + ICELogCritical(<<"Endpoint is started already."); + return; + } + + // Initialize resip loggег + resip::Log::initialize(resip::Log::OnlyExternal, resip::Log::Info, "Client", *this); + + // Build list of nameservers if specified + resip::DnsStub::NameserverList nslist; + + if (mConfig.exists(CONFIG_OWN_DNS)) + { + std::string line, t = mConfig[CONFIG_OWN_DNS].asStdString(); + std::stringstream ss(t); + + while (std::getline(ss, line)) + { + line = StringHelper::trim(line); + ice::NetworkAddress addr(line.c_str(), 0); addr.setPort(80); // Fake port to make ICEAddress initialized + switch (addr.family()) + { + case AF_INET: nslist.push_back(resip::GenericIPAddress(*addr.sockaddr4())); break; + case AF_INET6: nslist.push_back(resip::GenericIPAddress(*addr.sockaddr6())); break; + } + } + } + + // Security will be deleted in stop() method (in Stack destructor) + resip::Security* s = nullptr; +#if defined(TARGET_WIN) + s = new resip::WinSecurity(); +#elif defined(TARGET_OSX) + s = new resip::MacSecurity(); +#elif defined(TARGET_LINUX) + s = new resip::Security("/etc/ssl/certs"); +#elif defined(TARGET_ANDROID) + s = new resip::Security(); +#endif + mStack = new resip::SipStack(s, nslist); + + // Add root cert if specified + if (mConfig.exists(CONFIG_ROOTCERT)) + { + try + { + resip::Data cert = resip::Data(mConfig[CONFIG_ROOTCERT].asStdString()); + mStack->getSecurity()->addRootCertPEM(cert); + } + catch(resip::BaseException& /*e*/) + { + ICELogCritical(<< "Failed to preload root certificate"); + } + } + + // Add transports + mTransportList.clear(); + resip::InternalTransport* t; + +#define ADD_TRANSPORT4(X) if ((t = dynamic_cast(mStack->addTransport(X, 0, resip::V4)))) { t->setTransportLogger(this); mTransportList.push_back(t);} +#define ADD_TRANSPORT6(X) if ((t = dynamic_cast(mStack->addTransport(X, 0, resip::V6)))) { t->setTransportLogger(this); mTransportList.push_back(t);} + + switch (mConfig[CONFIG_TRANSPORT].asInt()) + { + case 0: + if (mConfig[CONFIG_IPV4].asBool()) + { + ADD_TRANSPORT4(resip::TCP) + ADD_TRANSPORT4(resip::UDP) + ADD_TRANSPORT4(resip::TLS) + } + if (mConfig[CONFIG_IPV6].asBool()) + { + ADD_TRANSPORT6(resip::TCP) + ADD_TRANSPORT6(resip::UDP) + ADD_TRANSPORT6(resip::TLS) + } + break; + + case 1: + if (mConfig[CONFIG_IPV4].asBool()) + ADD_TRANSPORT4(resip::UDP); + if (mConfig[CONFIG_IPV6].asBool()) + ADD_TRANSPORT6(resip::UDP); + break; + + case 2: + if (mConfig[CONFIG_IPV4].asBool()) + ADD_TRANSPORT4(resip::TCP); + if (mConfig[CONFIG_IPV6].asBool()) + ADD_TRANSPORT6(resip::TCP); + break; + + case 3: + if (mConfig[CONFIG_IPV4].asBool()) + ADD_TRANSPORT4(resip::TLS); + if (mConfig[CONFIG_IPV6].asBool()) + ADD_TRANSPORT6(resip::TLS); + break; + + default: + assert(0); + } + + mDum = new resip::DialogUsageManager(*mStack); + + // Set the name of user agent + if (mConfig[CONFIG_USERAGENT].asBool()) + mProfile->setUserAgent(mConfig[CONFIG_USERAGENT].asStdString().c_str()); + + // Configure rport + mProfile->setRportEnabled(mConfig[CONFIG_RPORT].asBool()); + + // Set keep-alive packets interval + if (mConfig.exists(CONFIG_KEEPALIVETIME)) + mProfile->setKeepAliveTimeForDatagram(mConfig[CONFIG_KEEPALIVETIME].asInt()); + else + mProfile->setKeepAliveTimeForDatagram(30); + + int dnsCacheTime = mConfig.exists(CONFIG_DNS_CACHE_TIME) ? mConfig[CONFIG_DNS_CACHE_TIME].asInt() : 86400; + mStack->getDnsStub().setDnsCacheSize(65536); + mStack->getDnsStub().setDnsCacheTTL(dnsCacheTime); + + // Disable statistics + mStack->statisticsManagerEnabled() = false; + + // Allow wildcard certificates + mStack->getSecurity()->setAllowWildcardCertificates(true); + + // Add special body type + mProfile->addSupportedMimeType(resip::MESSAGE, resip::Mime("text", "plain")); + mProfile->addSupportedMimeType(resip::INVITE, resip::Mime("application", "ddp")); + mProfile->addSupportedMimeType(resip::NOTIFY, resip::Pidf::getStaticType()); + mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("application", "simple-message-summary")); + mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("message", "sipfrag")); + mProfile->addSupportedMimeType(resip::OPTIONS, resip::Mime("application", "sdp")); + + // xcap/rls + mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("application", "xcap-diff+xml")); + mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("application", "rlmi+xml")); + mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("multipart", "related")); + mProfile->addSupportedOptionTag(resip::Token("eventlist")); + + mDum->setMasterProfile(mProfile); + mDum->setClientRegistrationHandler(this); + mDum->setClientAuthManager(auto_ptr(new resip::ClientAuthManager())); + + mDum->addClientSubscriptionHandler(resip::Symbols::Presence, this); + mDum->addClientSubscriptionHandler(resip::Data("message-summary"), this); + mDum->addServerSubscriptionHandler(resip::Symbols::Presence, this); + mDum->addServerSubscriptionHandler("refer", this); + mDum->addClientSubscriptionHandler("refer", this); + mDum->addClientPublicationHandler(resip::Symbols::Presence, this); + mDum->setInviteSessionHandler(this); + mDum->setClientPagerMessageHandler(this); + mDum->setServerPagerMessageHandler(this); + + auto_ptr uac_dsf(new ResipSessionFactory(this)); + mDum->setAppDialogSetFactory(uac_dsf); + + // Fire onStart event if stun is not used or stun server ip is known + if (mConfig[CONFIG_STUNSERVER_NAME].asStdString().empty() || !mConfig[CONFIG_STUNSERVER_IP].asStdString().empty()) + onStart(0); +} + + +void UserAgent::shutdown() +{ + if (!mStack) + return; + + ICELogInfo( << "Attempt to stop endpoint."); + + { + LOCK; + for (auto observerIter: mClientObserverMap) + observerIter.second->stop(); + + for (auto observerIter: mServerObserverMap) + observerIter.second->stop(); + + for (auto sessionIter: mSessionMap) + sessionIter.second->stop(); + + for (auto accountIter: mAccountSet) + accountIter->stop(); + } +} + +bool UserAgent::active() +{ + LOCK; + return mStack != NULL; +} + +void UserAgent::refresh() +{ + LOCK; + + for (auto acc: mAccountSet) + acc->refresh(); + + for (auto observer: mClientObserverMap) + observer.second->refresh(); +} + +void UserAgent::onDumCanBeDeleted() +{ + delete mDum; mDum = NULL; + delete mStack; mStack = NULL; + + mClientObserverMap.clear(); + mServerObserverMap.clear(); + + // Generate onStop event here + onStop(); +} + +void UserAgent::stop() +{ + LOCK; + if (!mStack || !mDum) + return; + + // Clear transport list to avoid races + mTransportList.clear(); + + // Dump statistics here + ICELogInfo(<< "Remaining " << Session::InstanceCounter.value() << " session(s), " << ResipSession::InstanceCounter.value() << " resip DialogSet(s), " << resip::ClientRegistration::InstanceCounter.value() << " ClientRegistration(s)"); + + mDum->shutdown(this); + onDumCanBeDeleted(); + +} + + +void UserAgent::process() +{ + resip::FdSet fdset; + if (mStack && mDum) + { + bool connectionFailed = false; + + mStack->buildFdSet(fdset); + //unsigned int t1 = mStack->getTimeTillNextProcessMS(); + int ret = fdset.selectMilliSeconds(0); + if (ret >= 0) // Got any results or time to send new packets? + { + Lock l(mGuard); + //ICELogDebug(<< "Smth on SIP socket(s)"); + mStack->process(fdset); + + // Check if there failed connections + for (unsigned transportIndex = 0; transportIndex < mTransportList.size(); transportIndex++) + if (mTransportList[transportIndex]->getConnectionsDeleted()) + { + connectionFailed = true; + mTransportList[transportIndex]->resetConnectionsDeleted(); + } + } + + { + Lock l(mGuard); + while (mDum->process()) + ; + } + + if (connectionFailed) + this->onSipConnectionFailed(); + } + + // Erase one terminated session. The rule is : seession must not have references from resiprocate and reference count has to be 1. + { + Lock l(mGuard); + SessionMap::iterator sessionIter; + for (sessionIter = mSessionMap.begin(); sessionIter != mSessionMap.end(); ++sessionIter) + { + if (sessionIter->second.use_count() == 1 && !sessionIter->second->mResipSession) + { + mSessionMap.erase(sessionIter); + break; + } + } + } + +#pragma region ICE packet generating + // Iterate available sessions + { + Lock l(mGuard); + + // Find all sessions + std::set idSet; + SessionMap::iterator sessionIter; + for (sessionIter = mSessionMap.begin(); sessionIter != mSessionMap.end(); ++sessionIter) + idSet.insert(sessionIter->first); + + // Now process session one by one checking if current is available yet + std::set::iterator resipIter; + for (resipIter = idSet.begin(); resipIter != idSet.end(); ++resipIter) + { + SessionMap::iterator sessionIter = mSessionMap.find(*resipIter); + if (sessionIter == mSessionMap.end()) + continue; + + // Extract reference to session + Session& session = *sessionIter->second; + + // Send queued offers if possible + session.processQueuedOffer(); + + // Generate outgoing data while available + int iceStreamId = -1, iceComponentId = -1; void* iceTag = NULL; bool iceResponse; + ice::PByteBuffer buffer; + while ((buffer = session.mIceStack->generateOutgoingData(iceResponse, iceStreamId, iceComponentId, iceTag))) + { + // Find corresponding data provider + for (unsigned i=0; i < session.mStreamList.size(); ++i) + { + Session::Stream& stream = session.mStreamList[i]; + + if (stream.provider() && stream.iceInfo().mStreamId == iceStreamId) + { + // Send generated packet via provider's method to allow custom scheme of encryption + ICELogDebug(<<"Sending ICE packet to " << buffer->remoteAddress().toStdString() << " with " << buffer->comment()); + + PDatagramSocket s = iceComponentId == ICE_RTP_ID ? stream.socket4().mRtp : stream.socket4().mRtcp; + stream.provider()->sendData(s, buffer->remoteAddress(), buffer->data(), buffer->size()); + break; + } + } // end of provider iterating + } + } + } +#pragma endregion + + // TODO: see if there expired sessions - stopped and awaiting turn resources deallocation +} + +void UserAgent::addRootCert(const ByteBuffer& data) +{ + LOCK; + resip::Data b(data.data(), data.size()); + mStack->getSecurity()->addRootCertPEM(b); +} + +PAccount UserAgent::createAccount(PVariantMap config) +{ + PAccount account(new Account(config, *this)); + mAccountSet.insert(account); + return account; +} + +void UserAgent::deleteAccount(PAccount account) +{ + // Delete reference from internal list + AccountSet::iterator accountIter = mAccountSet.find(account); + if (accountIter != mAccountSet.end()) + mAccountSet.erase(accountIter); +} + +PSession UserAgent::createSession(PAccount account) +{ + LOCK; + + // Create session object. ICE stack will be created as member of DemoAppDialogSet + PSession session(new Session(account)); + session->setUserAgent(this); + + // Save reference to session + mSessionMap[session->id()] = session; + + // Create ICE stack and configure it + account->prepareIceStack(session.get(), ice::RoleControlling); + + return session; +} + +std::string UserAgent::formatSipAddress(std::string sip) +{ + std::string result; + if (sip.size()) + { + if (sip.find("sip:") == std::string::npos && sip.find("sips:") == std::string::npos) + result = ""; + else + if (sip[0] != '<' && sip.find('<') == std::string::npos) + result = "<" + sip + ">"; + else + result = sip; + } + return result; +} + +bool UserAgent::isSipAddressValid(std::string sip) +{ + bool result = false; + try + { + if (sip.find('<') == std::string::npos) + sip = "<" + sip; + if (sip.find('>') == std::string::npos) + sip += ">"; + + resip::Data d(formatSipAddress(sip)); + resip::Uri uri(d); + result = uri.isWellFormed(); + if (result) + { + if (uri.user().empty() || uri.host().empty()) + result = false; + } + } + catch (...) + { + return result; + } + return result; +} + +UserAgent::SipAddress UserAgent::parseSipAddress(const std::string& sip) +{ + SipAddress result; + + result.mValid = isSipAddressValid(sip); + if (result.mValid) + { + resip::Data d(formatSipAddress(sip)); + resip::NameAddr nameaddr(d); + //resip::Uri uri(d); + if (!nameaddr.isWellFormed()) + result.mValid = false; + else + { + result.mUsername = nameaddr.uri().user().c_str(); + result.mDomain = nameaddr.uri().host().c_str(); + if (nameaddr.uri().port()) + { + char porttext[32]; + sprintf(porttext, ":%u", (unsigned)nameaddr.uri().port()); + result.mDomain += porttext; + } + + result.mScheme = nameaddr.uri().scheme().c_str(); + if (result.mScheme.find('<') == 0) + result.mScheme.erase(0, 1); + result.mDisplayname = nameaddr.displayName().c_str(); + + result.mValid &= !result.mUsername.empty() && !result.mDomain.empty(); + } + } + return result; +} + +bool UserAgent::compareSipAddresses(std::string sip1, std::string sip2) +{ + if (sip1.empty() || sip2.empty()) + return false; + + resip::Data d1(formatSipAddress(sip1)), d2(formatSipAddress(sip2)); + resip::Uri uri1(d1), uri2(d2); + + return uri1.getAorNoPort().uppercase() == uri2.getAorNoPort().uppercase(); +} + + +void UserAgent::onGathered(PSession s) +{ + ICELogCritical(<< "Session " << s->sessionId() << " gathered candidates"); +} + +// Called when new candidate is gathered +void UserAgent::onCandidateGathered(PSession s, const char* address) +{ + ICELogCritical(<< "Session " << s->sessionId() << " gathered new candidate " << address); +} + + +// Called when new connectivity check is finished +void UserAgent::onCheckFinished(PSession s, const char* description) +{ + +} + +void UserAgent::onLog(const char* msg) +{ +} + +void UserAgent::sendOffer(Session* session) +{ + assert(session->mResipSession); + + // Construct SDP + resip::SdpContents sdp; + session->buildSdp(sdp, Sdp_Offer); + + if (session->mOriginVersion == 1) + { + // Construct INVITE session + resip::SharedPtr msg = mDum->makeInviteSession(session->mRemotePeer, session->account()->mProfile, &sdp, session->mResipSession); + + // Include user headers + for (Session::UserHeaders::const_iterator iter = session->mUserHeaders.begin(); iter != session->mUserHeaders.end(); iter++) + { + const std::string& name = iter->first; + const std::string& value = iter->second; + + msg->header(resip::ExtensionHeader(name.c_str())).push_back(resip::StringCategory(value.c_str())); + } + mDum->send(msg); + } + else + { + // Send SDP + resip::InviteSession* h = dynamic_cast(session->mInviteHandle.get()); + if (h) + h->provideOffer(sdp); + else + ICELogCritical(<< "No cast to InviteSession"); + } +} + +#pragma region Registration handler + +void UserAgent::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response) +{ + ICELogInfo (<< "Registration got 200 response."); + Lock l(mGuard); + + // Find account by registration handle + PAccount account = getAccount(response.header(resip::h_From)); + if (account) + account->onSuccess(h, response); +} + +// Called when all of my bindings have been removed +void UserAgent::onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response) +{ + ICELogInfo( << "Registration is removed."); + + + Lock l(mGuard); + for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end(); accountIter++) + if ((*accountIter)->getUserProfile() == h->getUserProfile()) + (*accountIter)->onRemoved(h, response); +} + +/// call on Retry-After failure. +/// return values: -1 = fail, 0 = retry immediately, N = retry in N seconds +int UserAgent::onRequestRetry(resip::ClientRegistrationHandle h, int retrySeconds, const resip::SipMessage& response) +{ + return -1; +} + +// Called if registration fails, usage will be destroyed (unless a +// Registration retry interval is enabled in the Profile) +void UserAgent::onFailure(resip::ClientRegistrationHandle h, const resip::SipMessage& response) +{ + ICELogInfo (<< "Registration failed with code " << response.header(resip::h_StatusLine).statusCode()); + + Lock l(mGuard); + PAccount account = getAccount(response.header(resip::h_From)); + if (account) + account->onFailure(h, response); +} + + +#pragma endregion + +bool UserAgent::operator()(resip::Log::Level level, const resip::Subsystem& subsystem, const resip::Data& appName, const char* file, + int line, const resip::Data& message, const resip::Data& messageWithHeaders) +{ + std::string filename = file; + std::stringstream ss; + + ss << "File " << StringHelper::extractFilename(filename).c_str() << ", line " << line << ": " << message.c_str(); + if (level <= resip::Log::Warning) + ICELogCritical(<< ss.str().c_str()) + else + if (level < resip::Log::Debug) + ICELogInfo(<< ss.str().c_str()) + else + ICELogDebug(<< ss.str().c_str()) + return false; +} + +#pragma region INVITE handler + + +/// called when an initial INVITE or the intial response to an outoing invite +void UserAgent::onNewSession(resip::ClientInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) +{ +} + +void UserAgent::onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) +{ + ResipSession* rs = CAST2RESIPSESSION(h); + if (!rs) + { + h->reject(503); + return; + } + + // Find account + PAccount account = getAccount(h->myAddr()); + if (!account) + { + h->reject(503); + return; + } + + // Bring new user session + PSession s = createSession(account); + + rs->setSession(s.get()); + mSessionMap[s->sessionId()] = s; + + // Save remote address + s->setRemoteAddress(h->peerAddr().uri().getAor().c_str()); + + ICELogInfo( << "Session " << s->sessionId() << ": incoming."); + + h->provisional(100); + + // Create ICE stack and configure it + if (account) + account->prepareIceStack(s.get(), ice::RoleControlled); +} + +/// Received a failure response from UAS +void UserAgent::onFailure(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) +{ +} + + +/// called when an in-dialog provisional response is received that contains an SDP body +void UserAgent::onEarlyMedia(resip::ClientInviteSessionHandle h, const resip::SipMessage&, const resip::SdpContents&) +{ +} + + +/// called when dialog enters the Early state - typically after getting 18x +void UserAgent::onProvisional(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg) +{ + PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); + if (!s) + return; + + if (msg.isResponse()) + { + int responseCode = msg.header(resip::h_StatusLine).statusCode(); + onSessionProvisional(s, responseCode); + } + +} + + +/// called when a dialog initiated as a UAC enters the connected state +void UserAgent::onConnected(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg) +{ + PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); + if (!s) + return; + + if (!s->mOfferAnswerCounter) + { + ICELogInfo (<< "Session " << s->sessionId() << ": connected."); + + // Transfer user headers + if (h.isValid()) + h->setUserHeaders(s->mUserHeaders); + + onSessionEstablished(s, EV_SIP, RtpPair()); + + for (unsigned i=0; imStreamList.size(); i++) + { + if (s->mStreamList[i].provider()) + s->mStreamList[i].provider()->sessionEstablished(EV_SIP); + } + } + s->mOfferAnswerCounter++; +} + + +/// called when a dialog initiated as a UAS enters the connected state +void UserAgent::onConnected(resip::InviteSessionHandle h, const resip::SipMessage& msg) +{ + ResipSession* resipSession = dynamic_cast(h->getAppDialogSet().get()); + if (!resipSession) + return; + PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); + + if (!s) + return; + + ICELogInfo (<< "Session " << s->mSessionId << ": connected."); + + // Transfer user headers + if (h.isValid()) + h->setUserHeaders(s->mUserHeaders); + + onSessionEstablished(s, EV_SIP, RtpPair()); + + for (unsigned i=0; imStreamList.size(); i++) + { + if (s->mStreamList[i].provider()) + s->mStreamList[i].provider()->sessionEstablished(EV_SIP); + } +} + + +void UserAgent::onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* related) +{ + PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); + if (!s) + return; + + ICELogInfo( << "Session " << s->mSessionId << ": terminated."); + + int errorcode = 0; + if (related) + { + if (related->isResponse()) + errorcode = related->header(resip::h_StatusLine).statusCode(); + } + + if (s->mResipSession) + s->mResipSession->runTerminatedEvent(ResipSession::Type_Call, errorcode, (int)reason); + s->clearProviders(); + + // TODO: run turn resource deallocation sequence here. Otherwise release user session object. +} + +/// called when a fork that was created through a 1xx never receives a 2xx +/// because another fork answered and this fork was canceled by a proxy. +void UserAgent::onForkDestroyed(resip::ClientInviteSessionHandle) +{ +} + + +/// called when a 3xx with valid targets is encountered in an early dialog +/// This is different then getting a 3xx in onTerminated, as another +/// request will be attempted, so the DialogSet will not be destroyed. +/// Basically an onTermintated that conveys more information. +/// checking for 3xx respones in onTerminated will not work as there may +/// be no valid targets. +void UserAgent::onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) +{ +} + +/// Called when an SDP answer is received - has nothing to do with user +/// answering the call +void UserAgent::onAnswer(resip::InviteSessionHandle h, const resip::SipMessage& msg, const resip::SdpContents& sdp) +{ + // Check if session casts ok + ResipSession* resipSession = dynamic_cast(h->getAppDialogSet().get()); + if (!resipSession) + return; + Session* s = resipSession->session(); + + bool iceAvailable = true; + + ICELogInfo( << "Session " << s->mSessionId << ": got answer."); + + // Check for remote ICE credentials + std::string icePwd, iceUfrag; + if (sdp.session().exists("ice-pwd")) + icePwd = sdp.session().getValues("ice-pwd").front().c_str(); + if (sdp.session().exists("ice-ufrag")) + iceUfrag = sdp.session().getValues("ice-ufrag").front().c_str(); + + if (s->mStreamList.size() < sdp.session().media().size()) + { + ICELogCritical( << "Answer has wrong number of streams"); + h->end(); + return; + } + + // Get default remote IP + std::string remoteDefaultIP; + if (sdp.session().isConnection()) + remoteDefaultIP = sdp.session().connection().getAddress().c_str(); + + bool mediasupported = false; + + // Iterate SDP's streams + std::list::const_iterator mediaIter; + unsigned streamIndex = 0; + for (mediaIter = sdp.session().media().begin(), streamIndex = 0; + mediaIter != sdp.session().media().end() && streamIndex < s->mStreamList.size(); + ++mediaIter, ++streamIndex) + { + Session::Stream& stream = s->mStreamList[streamIndex]; + const resip::SdpContents::Session::Medium& remoteStream = *mediaIter; + + // Update remote default ip if available + const std::list& streamConnections = remoteStream.getMediumConnections(); + if (streamConnections.size()) + remoteDefaultIP = streamConnections.front().getAddress().c_str(); + + if (remoteDefaultIP.empty()) + continue; + + // Check if stream is active + if (remoteStream.exists("inactive")) + { + // Move to next stream. + // Deactivate rejected provider + if (stream.provider()) + { + stream.provider()->sessionTerminated(); // close corresponding media + stream.setProvider( PDataProvider() ); // free provider + SocketHeap::instance().freeSocketPair( stream.socket4() ); // close provider's socket ip4 + SocketHeap::instance().freeSocketPair( stream.socket6() ); // close provider's socket ip6 + s->mIceStack->removeStream( stream.iceInfo().mStreamId ); // remove stream from ice stack + } + continue; + } + + // Try to parse SDP with ICE stack + unsigned short remoteDefaultPort = remoteStream.port(); + + // Extract remote ICE candidates vector + const std::list candidateList = remoteStream.getValues("candidate"); + if (candidateList.empty()) + iceAvailable = false; + + std::vector candidateVector; + std::list::const_iterator cit = candidateList.begin(); + for (; cit != candidateList.end(); ++cit) + candidateVector.push_back(cit->c_str()); + + if (remoteStream.exists("ice-pwd")) + icePwd = remoteStream.getValues("ice-pwd").front().c_str(); + if (remoteStream.exists("ice-ufrag")) + iceUfrag = remoteStream.getValues("ice-ufrag").front().c_str(); + + // ICEBox::processSdpOffer() may install permissions on TURN peer - so call it anyway. + // Also it can adjust number of ice components per stream; + // Corresponding turn allocation will be removed in this case. + try + { + if (!s->mIceStack->processSdpOffer(stream.iceInfo().mStreamId, candidateVector, remoteDefaultIP, remoteDefaultPort, mConfig[CONFIG_DEFERRELAYED].asBool())) + iceAvailable = false; + } + catch(...) + { + iceAvailable = false; + } + + // Process media description with provider + if (stream.provider()) + { + if (stream.provider()->processSdpOffer( remoteStream, Sdp_Answer )) + { + InternetAddress addr(remoteDefaultIP, remoteDefaultPort), addr2(remoteDefaultIP, remoteDefaultPort+1); + + // See if remote stream has "rtcp" or "rtcp-mux" attributes + if (remoteStream.exists("rtcp")) + addr2.setPort( StringHelper::toInt(remoteStream.getValues("rtcp").front().c_str(), remoteDefaultPort+1) ); + else + if (remoteStream.exists("rtcp-mux")) + addr2.setPort( remoteDefaultPort ); + stream.provider()->setDestinationAddress(RtpPair(addr, addr2)); + mediasupported = true; + } + } + } + + // Save session handle + if (!s->mInviteHandle.isValid()) + s->mInviteHandle = h; + + // Get ICE credentials + if (icePwd.size() && iceUfrag.size()) + { + s->mIceStack->setRemotePassword(icePwd); + s->mIceStack->setRemoteUfrag(iceUfrag); + } + else + iceAvailable = false; + + // Reject session if there is no media + if (!mediasupported) + { + ICELogCritical(<< "Session " << s->mSessionId << ": no supported media."); + h->end(); + return; + } + + // Start connectivity checks now + ICELogInfo(<< "Session " << s->mSessionId << ": attempt to check connectivity."); + + if (iceAvailable) + s->mIceStack->checkConnectivity(); + else + { + if (!mConfig[CONFIG_RELAY].asBool()) + s->mIceStack->clear(); + } + + UInt64 version = sdp.session().origin().getVersion(); + s->mRemoteOriginVersion = version; +} + +/// Called when an SDP offer is received - must send an answer soon after this +void UserAgent::onOffer(resip::InviteSessionHandle h, const resip::SipMessage& msg, const resip::SdpContents& sdp) +{ + PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); + if (!s) + { + h->reject(488); + return; + } + + bool iceAvailable = true; + + ICELogInfo(<< "Session " << s->sessionId() << ": got offer."); + + // Check if sdp includes ICE ufrag/password + std::string icePwd, iceUfrag; + if (sdp.session().exists("ice-pwd")) + icePwd = sdp.session().getValues("ice-pwd").front().c_str(); + if (sdp.session().exists("ice-ufrag")) + iceUfrag = sdp.session().getValues("ice-ufrag").front().c_str(); + + ice::Stack& ice = *s->mIceStack; + + UInt64 version = sdp.session().origin().getVersion(); + std::string remoteIp = sdp.session().connection().getAddress().c_str(); + int code; + if ((UInt64)-1 == s->mRemoteOriginVersion) + { + code = s->processSdp(version, iceAvailable, icePwd, iceUfrag, remoteIp, sdp.session().media()); + } + else + if (version == s->mRemoteOriginVersion) + { + // Timer, answer with previous SDP + //session->processTimer(); + } + if (version == s->mRemoteOriginVersion+1) + { + // Updated offer. Here we must check if ICE has to be restarted. + code = s->processSdp(version, iceAvailable, icePwd, iceUfrag, remoteIp, sdp.session().media()); + } + s->mRemoteOriginVersion = version; + + if (code != 200) + { + h->reject(code); + return; + } + + // Save session handle + if (!s->mInviteHandle.isValid()) + s->mInviteHandle = h; + + // Save reference to resip session + s->mResipSession = CAST2RESIPSESSION(h); + + if (!s->mAcceptedByEngine) + { + // Do not call OnNewSession for this session in future + s->mAcceptedByEngine = true; + + // Notify about new session request + onNewSession(s); + } +} + +/// called when an Invite w/out SDP is sent, or any other context which +/// requires an SDP offer from the user +void UserAgent::onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg) +{ +} + +/// called if an offer in a UPDATE or re-INVITE was rejected - not real +/// useful. A SipMessage is provided if one is available +void UserAgent::onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg) +{ +} + +/// called when INFO message is received +void UserAgent::onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg) +{ +} + +/// called when response to INFO message is received +void UserAgent::onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) +{ +} + +void UserAgent::onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) +{ +} + +/// called when MESSAGE message is received +void UserAgent::onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg) +{ +} + +/// called when response to MESSAGE message is received +void UserAgent::onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) +{ +} + +void UserAgent::onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) +{ +} + +/// called when an REFER message is received. The refer is accepted or +/// rejected using the server subscription. If the offer is accepted, +/// DialogUsageManager::makeInviteSessionFromRefer can be used to create an +/// InviteSession that will send notify messages using the ServerSubscription +void UserAgent::onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg) +{ +} + +void UserAgent::onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg) +{ +} + + +/// called when an REFER message receives a failure response +void UserAgent::onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg) +{ +} + +/// called when an REFER message receives an accepted response +void UserAgent::onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg) +{ +} + +void UserAgent::onDnsResult(const resip::DNSResult& result) +{ + if (result.status == 0) + { + resip::Data foundAddress = result.records.front().host(); + ICELogCritical( << "Success to resolve STUN/TURN address to " << foundAddress.c_str()); + mConfig[CONFIG_STUNSERVER_IP] = std::string(foundAddress.c_str()); + onStart(0); + } + else + { + ICELogCritical( << "Failed to resolve STUN or TURN server IP address."); + int startCode = mConfig[CONFIG_STUNSERVER_NAME].asStdString().empty() ? 0 : 503; + onStart(startCode); + } +} + +void UserAgent::onDnsResult(const resip::DNSResult& result) +{ +} + +void UserAgent::onDnsResult(const resip::DNSResult& result) +{ +} + +void UserAgent::onDnsResult(const resip::DNSResult& result) +{ + ; +} + +void UserAgent::onDnsResult(const resip::DNSResult& result) +{ + ; +} +#pragma endregion + + +#pragma region Publication presence +void UserAgent::onSuccess(resip::ClientPublicationHandle h, const resip::SipMessage& status) +{ + resip::NameAddr from = status.header(resip::h_To); + PAccount account = getAccount(from); + if (account) + account->mPublication = h; + onPublicationSuccess(account); +} + +void UserAgent::onRemove(resip::ClientPublicationHandle, const resip::SipMessage& status) +{ + resip::NameAddr to = status.header(resip::h_To); + PAccount account = getAccount(to); + if (account) + account->mPublication = resip::ClientPublicationHandle(); + onPublicationTerminated(account, 0); +} + +void UserAgent::onFailure(resip::ClientPublicationHandle, const resip::SipMessage& status) +{ + resip::NameAddr to = status.header(resip::h_To); + PAccount account = getAccount(to); + if (account) + account->mPublication = resip::ClientPublicationHandle(); + onPublicationTerminated(account, status.header(resip::h_StatusLine).statusCode()); +} + +int UserAgent::onRequestRetry(resip::ClientPublicationHandle, int retrySeconds, const resip::SipMessage& status) +{ + return -1; +} + + + +void UserAgent::onPublicationSuccess(PAccount account) +{ +} + +void UserAgent::onPublicationTerminated(PAccount account, int code) +{ +} + +#pragma endregion + +#pragma region Subscriptions + +void UserAgent::onClientObserverStart(PClientObserver observer) +{ +} + +void UserAgent::onClientObserverStop(PClientObserver observer, int code) +{ +} + +void UserAgent::onPresenceUpdate(PClientObserver observer, const std::string& peer, bool online, const std::string& content) +{ +} + + +#pragma endregion + +#pragma region SubscriptionHandler + +void UserAgent::onNewSubscription(resip::ServerSubscriptionHandle h, const resip::SipMessage& sub) +{ + ResipSession* s = CAST2RESIPSESSION(h); + + // Get the event package name + const char* event = sub.header(resip::h_Event).value().c_str(); + + // Get the remote party + const char* peer = sub.header(resip::h_From).uri().getAor().c_str(); + + PAccount account = getAccount(sub.header(resip::h_From)); + PServerObserver so(new ServerObserver()); + so->mHandle = h; + so->mPeer = peer; + so->mPackage = event; + so->mSessionId = s->sessionId(); + + s->setRemoteAddress(peer); + mServerObserverMap[so->mSessionId] = so; + onServerObserverStart(so); +} + +void UserAgent::onTerminated(resip::ServerSubscriptionHandle h) +{ + if (!h.isValid()) + return; + ResipSession* s = CAST2RESIPSESSION(h); + if (!s) + return; + + ServerObserverMap::iterator observerIter = mServerObserverMap.find(s->sessionId()); + if (observerIter != mServerObserverMap.end()) + { + onServerObserverStop(observerIter->second, 0); + mServerObserverMap.erase(observerIter); + } +} + +void UserAgent::onServerObserverStart(PServerObserver observer) +{ +} + +void UserAgent::onServerObserverStop(PServerObserver observer, int code) +{ +} + +void UserAgent::onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify) +{ + if (!h.isValid()) + return; + + ResipSession* s = CAST2RESIPSESSION(h); + if (!s) + return; + ClientObserverMap::iterator observerIter = mClientObserverMap.find(s->sessionId()); + if (observerIter == mClientObserverMap.end()) + { + h->rejectUpdate(); + h->end(); + return; + } + PClientObserver observer = observerIter->second; + + std::vector availableContacts; + h->acceptUpdate(); + + // Find "from" header + resip::Uri from = notify.header(resip::h_From).uri(); + + // Find content + resip::Contents* contents = notify.getContents(); + if (contents) + { + // Check if pidf + if (resip::Pidf* pidf = dynamic_cast(contents)) + { + resip::Data body = pidf->getBodyData(); + bool online = pidf->getSimpleStatus(&body); + onPresenceUpdate(observer, observer->peer(), online, std::string(body.c_str(), body.size())); + } + else + if (resip::MultipartRelatedContents* mr = dynamic_cast(contents)) + { + resip::MultipartRelatedContents::Parts& parts = mr->parts(); + for( resip::MultipartRelatedContents::Parts::const_iterator i = parts.begin(); i != parts.end(); ++i) + { + resip::Contents* c = *i; + assert( c ); + resip::Mime m = c->getType(); + if (resip::Rlmi* rlmi = dynamic_cast(c)) + { + resip::Data d = rlmi->getBodyData(); + // Workaround for XMLCursor bug + if (d.find(resip::Data(" tag in rlmi"); + } + else + { + for (bool hasRecord = c.firstChild(); hasRecord; hasRecord = c.nextSibling()) + { + if (c.getTag() != "resource") + { + ICELogCritical( << "Failed to find tag in rlmi"); + } + else + { + // Check if c has + + resip::XMLCursor::AttributeMap::const_iterator attrIter = c.getAttributes().find("uri"); + if (attrIter != c.getAttributes().end()) + { + // Save uri + resip::Data uri = attrIter->second; + + // Check if there is tag + bool instance = false; + for (bool hasChild = c.firstChild(); hasChild; hasChild = c.nextSibling()) + instance |= c.getTag() == "instance"; + c.parent(); + + // Save result + if (instance) + availableContacts.push_back( attrIter->second ); + } + } + } + } + } + else + if (resip::Pidf* pidf = dynamic_cast(c)) + { + resip::Data body = pidf->getBodyData(); + bool online = pidf->getSimpleStatus(&body); + resip::Data entity = pidf->getEntity().getAorNoPort(); + if (entity.find("sip:") == resip::Data::npos && entity.find("sips:") == resip::Data::npos) + entity = resip::Data("sip:") + entity; + onPresenceUpdate(observer, entity.c_str(), online, std::string(body.c_str(), body.size())); + + // Drop corresponding record from availableContacts + std::vector::iterator ci = std::find(availableContacts.begin(), availableContacts.end(), entity); + if (ci != availableContacts.end()) + availableContacts.erase(ci); + } + } + } + } + + for (unsigned i=0; iisResponse()) + code = msg->header(resip::h_StatusLine).statusCode(); + + // Remove subscription from list, call terminated event + rs->runTerminatedEvent(ResipSession::Type_Subscription, code, 0); +} + +void UserAgent::onNewSubscription(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify) +{ + if (!h.isValid()) + return; + + // Find dialog set + ResipSession* s = CAST2RESIPSESSION(h); + if (!s) + return; + + if (!s->mOnWatchingStartSent) + { + s->mOnWatchingStartSent = true; + ClientObserverMap::iterator observerIter = mClientObserverMap.find(s->sessionId()); + if (observerIter != mClientObserverMap.end()) + onClientObserverStart(observerIter->second); + } +} + +/// called to allow app to adorn a message. +void UserAgent::onReadyToSend(resip::ClientSubscriptionHandle, resip::SipMessage& msg) +{ +} + +void UserAgent::onNotifyNotReceived(resip::ClientSubscriptionHandle) +{ +} + +/// Called when a TCP or TLS flow to the server has terminated. This can be caused by socket +/// errors, or missing CRLF keep alives pong responses from the server. +// Called only if clientOutbound is enabled on the UserProfile and the first hop server +/// supports RFC5626 (outbound). +/// Default implementation is to re-form the subscription using a new flow +void UserAgent::onFlowTerminated(resip::ClientSubscriptionHandle) +{ +} +#pragma endregion + +#pragma region PagerHandler +void UserAgent::onSuccess(resip::ClientPagerMessageHandle h, const resip::SipMessage& status) +{ + if (!h.isValid()) + return; + ResipSession* s = CAST2RESIPSESSION(h); + if (!s) + return; + onMessageSent(getAccount(status.header(resip::h_From)), s->sessionId(), s->remoteAddress(), s->tag()); +} + +void UserAgent::onFailure(resip::ClientPagerMessageHandle h, const resip::SipMessage& status, std::auto_ptr contents) +{ + if (!h.isValid()) + return; + ResipSession* s = CAST2RESIPSESSION(h); + if (!s) + return; + onMessageFailed(getAccount(status.header(resip::h_From)), s->sessionId(), s->remoteAddress(), status.header(resip::h_StatusLine).statusCode(), s->tag()); +} + +void UserAgent::onMessageArrived(resip::ServerPagerMessageHandle h, const resip::SipMessage& message) +{ + if (!h.isValid()) + return; + resip::NameAddr from = message.header(resip::h_From); + std::string peer(from.uri().getAor().c_str()); + PAccount account = getAccount(from); + h->send(h->accept()); + resip::Contents* c = message.getContents(); + if (!c) + onMessageArrived(account, peer, NULL, 0); + else + { + resip::Data d = c->getBodyData(); + onMessageArrived(account, peer, d.c_str(), d.size()); + } +} + +void UserAgent::updateInterfaceList() +{ + //ICEImpl::ICENetworkHelper::instance().reload(); +} + +void UserAgent::onMessageArrived(PAccount /*account*/, const std::string& /*peer*/, const void* /*ptr*/, unsigned /*length*/) +{ +} + +void UserAgent::onMessageFailed(PAccount /*account*/, int /*id*/, const std::string& /*peer*/, int /*code*/, void* /*tag*/) +{ +} + +void UserAgent::onMessageSent(PAccount /*account*/, int /*id*/, const std::string& /*peer*/, void* /*tag*/) +{ +} + +VariantMap& UserAgent::config() +{ + return mConfig; +} + +static void splitToHeaders(resip::Data& content, std::vector& output) +{ + resip::Data::size_type startLine = 0, endLine = content.find("\r\n"); + while (endLine != resip::Data::npos) + { + output.push_back(content.substr(startLine, endLine)); + + startLine = endLine + 2; + endLine = content.find("\r\n", startLine); + } + if (0 == startLine) + output.push_back(content); +} + +static bool parseHeader(resip::Data& input, resip::Data& name, resip::Data& value) +{ + resip::Data::size_type p = input.find(":"); + if (p == resip::Data::npos) + { + name = input; + value.clear(); + } + else + { + name = input.substr(0, p); + value = input.substr(p+1, input.size() - p - 1); + + // Trim leading whitespace + if (value.size()) + { + if (value.at(0) == ' ') + value = value.substr(1, value.size()-1); + } + } + return true; +} + +void UserAgent::onSipMessage(int flow, const char* msg, unsigned int length, const sockaddr* addr, unsigned int addrlen) +{ + std::string d(msg, length); + ice::NetworkAddress address(*addr, addrlen); + std::string addressText = address.toStdString(); + + switch (flow) + { + case resip::InternalTransport::TransportLogger::Flow_Received: + ICELogDebug(<< "Received from " << addressText << ":" << "\n" + << StringHelper::prefixLines(d, "--->")); + break; + + case resip::InternalTransport::TransportLogger::Flow_Sent: + ICELogDebug(<< "Sent to " << addressText << "\n" << StringHelper::prefixLines(d, "<---")); + break; + } +} + +PSession UserAgent::getUserSession(int sessionId) +{ + SessionMap::iterator sessionIter = mSessionMap.find(sessionId); + if (sessionIter != mSessionMap.end()) + return sessionIter->second; + else + return PSession(); +} + +PAccount UserAgent::getAccount(const resip::NameAddr& myAddr) +{ + PAccount acc; + for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end() && !acc; accountIter++) + if ((*accountIter)->isResponsibleFor(myAddr)) + acc = *accountIter; + + return acc; +} + +PAccount UserAgent::getAccount(Account* account) +{ + PAccount acc; + for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end() && !acc; accountIter++) + if (accountIter->get() == account) + acc = *accountIter; + + return acc; +} + +PAccount UserAgent::getAccount(int sessionId) +{ + auto profileIter = std::find_if(mAccountSet.begin(), mAccountSet.end(), [=](const AccountSet::value_type& v) {if (v->mRegistration) return v->mRegistration->sessionId() == sessionId; else return false;}); + return (profileIter != mAccountSet.end()) ? *profileIter : PAccount(); +} + +#pragma endregion diff --git a/src/engine/endpoint/EP_Engine.h b/src/engine/endpoint/EP_Engine.h new file mode 100644 index 00000000..0661d374 --- /dev/null +++ b/src/engine/endpoint/EP_Engine.h @@ -0,0 +1,484 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ENGINE_H +#define __ENGINE_H + +#include "resip/stack/SdpContents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/ShutdownMessage.hxx" +#include "resip/stack/SipStack.hxx" +#include "resip/stack/InternalTransport.hxx" +#include "resip/dum/ClientAuthManager.hxx" +#include "resip/dum/ClientInviteSession.hxx" +#include "resip/dum/ClientRegistration.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/DumShutdownHandler.hxx" +#include "resip/dum/InviteSessionHandler.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/RegistrationHandler.hxx" +#include "resip/dum/ServerInviteSession.hxx" +#include "resip/dum/ServerOutOfDialogReq.hxx" +#include "resip/dum/OutOfDialogHandler.hxx" +#include "resip/dum/AppDialog.hxx" +#include "resip/dum/AppDialogSet.hxx" +#include "resip/dum/AppDialogSetFactory.hxx" +#include "resip/dum/ClientPublication.hxx" +#include "resip/dum/ClientSubscription.hxx" +#include "resip/dum/SubscriptionHandler.hxx" +#include "resip/dum/PagerMessageHandler.hxx" +#include "resip/dum/PublicationHandler.hxx" +#include "resip/dum/ClientPagerMessage.hxx" +#include "resip/dum/ServerPagerMessage.hxx" + +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Random.hxx" +#include "rutil/WinLeakCheck.hxx" +#include "rutil/DnsUtil.hxx" +#include "resip/stack/DnsResult.hxx" +#include "resip/stack/SipStack.hxx" +#include "rutil/dns/RRVip.hxx" +#include "rutil/dns/QueryTypes.hxx" +#include "rutil/dns/DnsStub.hxx" +#include "../ice/ICEBox.h" +#include "../ice/ICETime.h" +#include +#include +#include "../config.h" +#include "EP_Session.h" +#include "EP_Observer.h" +#include "EP_DataProvider.h" +#include "../helper/HL_VariantMap.h" +#include "../helper/HL_SocketHeap.h" +#include "../helper/HL_Sync.h" +#include "../helper/HL_ByteBuffer.h" +#include "../media/MT_Stream.h" + +#define RESIPROCATE_SUBSYSTEM Subsystem::TEST + +using namespace std; +enum +{ + CONFIG_IPV4 = 0, // Use IP4 + CONFIG_IPV6, // Use IP6. + CONFIG_USERNAME, // Username. String value. + CONFIG_DOMAIN, // Domain. String value. + CONFIG_PASSWORD, // Password. String value. + CONFIG_RINSTANCE, // Determines if SIP rinstance field has to be used during registration. Boolean value. + CONFIG_INSTANCE_ID, // Instance id. It is alternative option to rinstance. + CONFIG_DISPLAYNAME, // Optional user display name. String value. + CONFIG_DOMAINPORT, // Optional domain port number. Integer value. + CONFIG_REGISTERDURATION, // Wanted duration for registration. Integer value. It is MANDATORY value. + CONFIG_RPORT, // Use SIP rport field. Recommended to set it to true. Boolean value. + CONFIG_KEEPALIVETIME, // Interval between UDP keep-alive messages. Boolean value. + CONFIG_RELAY, // Sets if TURN server must be used instead of STUN. Boolean value. + CONFIG_ICETIMEOUT, // Optional timeout for ICE connectivity checks and candidate gathering. Integer value. + CONFIG_ICEUSERNAME, // Optional username for TURN server. String value. + CONFIG_ICEPASSWORD, // Optional password for TURN server. String value. + CONFIG_SIPS, // Marks if account credentials are sips: scheme. Boolean value. + CONFIG_STUNSERVER_IP, // Optional IP address of STUN/TURN server. String value. It is better to use CONFIG_STUNSERVER_NAME. + CONFIG_STUNSERVER_NAME, // Host name of STUN/TURN server. stun.xten.com for example. String value. + CONFIG_STUNSERVER_PORT, // Port number of STUN/TURN server. Integer value. + CONFIG_USERAGENT, // Name of user agent in SIP headers. String value. + CONFIG_ICEREQUIRED, // ICE MUST be present in remote peer offers and answers. Boolean value. + CONFIG_TRANSPORT, // 0 - all transports, 1 - UDP, 2 - TCP, 3 - TLS, + CONFIG_SUBSCRIPTION_TIME, // Subscription time (in seconds) + CONFIG_SUBSCRIPTION_REFRESHTIME, // Refresh interval for subscriptions + CONFIG_DNS_CACHE_TIME, // DNS cache time; default is 86400 seconds + CONFIG_PRESENCE_ID, // Tuple ID used in presence publishing; determines source device + CONFIG_ROOTCERT, // Additional root cert in PEM format; string. + CONFIG_CACHECREDENTIALS, // Attempt to cache credentials that comes in response from PBX. Use them when possible to reduce number of steps of SIP transaction + CONFIG_RTCP_ATTR, // Use "rtcp" attribute in sdp. Default value is true. + CONFIG_MULTIPLEXING, // Do rtp/rtcp multiplexing + CONFIG_DEFERRELAYED, // Defer relayed media path + CONFIG_PROXY, // Proxy host name or IP address + CONFIG_PROXYPORT, // Proxy port number + CONFIG_CODEC_PRIORITY, // Another VariantMap with codec priorities, + CONFIG_ACCOUNT, // VariantMap with account configuration + CONFIG_EXTERNALIP, // Use external/public IP in outgoing requests + CONFIG_OWN_DNS, // Use predefined DNS servers + CONFIG_REGID // reg-id value from RFC5626 +}; + +// Conntype parameter for OnSessionEstablished event +enum +{ + EV_SIP = 1, + EV_ICE = 2 +}; + +class UserAgent; + +// Define a type for asynchronous requests to user agent +class SIPAction +{ +public: + virtual void Run(UserAgent& ua) = 0; +}; + +typedef std::vector SIPActionVector; + +// Session termination reason +enum +{ + Error, + Timeout, + Replaced, + LocalBye, + RemoteBye, + LocalCancel, + RemoteCancel, + Rejected, //Only as UAS, UAC has distinct onFailure callback + Referred +}; + +class UserAgent: public resip::ClientRegistrationHandler, + public resip::InviteSessionHandler, + public resip::DumShutdownHandler, + public resip::ExternalLogger, + public resip::DnsResultSink, + public resip::ClientSubscriptionHandler, + public resip::ServerSubscriptionHandler, + public resip::ClientPagerMessageHandler, + public resip::ServerPagerMessageHandler, + public resip::ClientPublicationHandler, + public resip::InternalTransport::TransportLogger +{ + friend class Account; + friend class Session; + friend class ResipSession; + friend class NATDecorator; + friend class WatcherQueue; +public: + /* Compares two sip addresses. Returns true if they represent the same entity - user and domain are the same. Otherwise returns false. */ + static bool compareSipAddresses(std::string sip1, std::string sip2); + static std::string formatSipAddress(std::string sip); + static bool isSipAddressValid(std::string sip); + struct SipAddress + { + bool mValid; + std::string mScheme; + std::string mUsername; + std::string mDomain; + std::string mDisplayname; + }; + + static SipAddress parseSipAddress(const std::string& sip); + + UserAgent(); + virtual ~UserAgent(); + + /* Brings user agent online. Basically it creates a signalling socket(s). + This is asynchronous method. */ + void start(); + + /* Shutdowns user agent. It closes all sessions, tries to unregister from server and disconnects from it. + This is asynchronous method. onStop() event will be called later */ + void shutdown(); + + /* Emergency stop. Please always call shutdown() before this. Kills registration, sessions & presence - everything. onStop() is called in context of this method. */ + void stop(); + + /* Checks if user agent is active (started). */ + bool active(); + + /* Used to refresh existing registration(s), publication, subscriptions. */ + void refresh(); + + /* Runs sip & ice stacks. Event handlers are called in its context. */ + void process(); + + /* Adds root cert in PEM format. Usable after start() call. */ + void addRootCert(const ByteBuffer& data); + + PAccount createAccount(PVariantMap config); + void deleteAccount(PAccount account); + + /* Creates session. Returns session ID. */ + PSession createSession(PAccount account); + + // Must be called when IP interface list is changed + void updateInterfaceList(); + + // Called on new incoming session; providers shoukld + virtual PDataProvider onProviderNeeded(const std::string& name) = 0; + + // Called on new session offer + virtual void onNewSession(PSession s) = 0; + + // Called when session is terminated + virtual void onSessionTerminated(PSession s, int responsecode, int reason) = 0; + + // Called when session is established ok i.e. after all ICE signalling is finished + // Conntype is type of establish event - EV_SIP or EV_ICE + virtual void onSessionEstablished(PSession s, int conntype, const RtpPair& p) = 0; + + // Called when client session gets + virtual void onSessionProvisional(PSession s, int code) = 0; + + // Called when user agent started + virtual void onStart(int errorcode) = 0; + + // Called when user agent stopped + virtual void onStop() = 0; + + // Called when account registered + virtual void onAccountStart(PAccount account) = 0; + + // Called when account removed or failed (non zero error code) + virtual void onAccountStop(PAccount account, int error) = 0; + + // Called when connectivity checks failed. + virtual void onConnectivityFailed(PSession s) = 0; + + // Called when new candidate is gathered + virtual void onCandidateGathered(PSession s, const char* address); + + // Called when network change detected + virtual void onNetworkChange(PSession s) = 0; + + // Called when all candidates are gathered + virtual void onGathered(PSession s); + + // Called when new connectivity check is finished + virtual void onCheckFinished(PSession s, const char* description); + + // Called when log message must be recorded + virtual void onLog(const char* msg); + + // Called when problem with SIP connection(s) detected + virtual void onSipConnectionFailed() = 0; + + // Subscribe/publish presence methods + virtual void onPublicationSuccess(PAccount acc); + virtual void onPublicationTerminated(PAccount acc, int code); + virtual void onClientObserverStart(PClientObserver observer); + virtual void onServerObserverStart(PServerObserver observer); + virtual void onClientObserverStop(PClientObserver observer, int code); + virtual void onServerObserverStop(PServerObserver observer, int code); + + virtual void onPresenceUpdate(PClientObserver observer, const std::string& peer, bool online, const std::string& content); + virtual void onMessageArrived(PAccount account, const std::string& peer, const void* ptr, unsigned length); + virtual void onMessageFailed(PAccount account, int id, const std::string& peer, int code, void* tag); + virtual void onMessageSent(PAccount account, int id, const std::string& peer, void* tag); + + // Configuration methods + VariantMap& config(); + +public: + // InviteSessionHandler implementation +#pragma region InviteSessionHandler implementation + /// called when an initial INVITE or the intial response to an outoing invite + virtual void onNewSession(resip::ClientInviteSessionHandle, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) override; + virtual void onNewSession(resip::ServerInviteSessionHandle, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) override; + + /// Received a failure response from UAS + virtual void onFailure(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override; + + /// called when an in-dialog provisional response is received that contains an SDP body + virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&) override; + + /// called when dialog enters the Early state - typically after getting 18x + virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage&) override; + + /// called when a dialog initiated as a UAC enters the connected state + virtual void onConnected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override; + + /// called when a dialog initiated as a UAS enters the connected state + virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + + virtual void onTerminated(resip::InviteSessionHandle, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* related=0) override; + + /// called when a fork that was created through a 1xx never receives a 2xx + /// because another fork answered and this fork was canceled by a proxy. + virtual void onForkDestroyed(resip::ClientInviteSessionHandle) override; + + /// called when a 3xx with valid targets is encountered in an early dialog + /// This is different then getting a 3xx in onTerminated, as another + /// request will be attempted, so the DialogSet will not be destroyed. + /// Basically an onTermintated that conveys more information. + /// checking for 3xx respones in onTerminated will not work as there may + /// be no valid targets. + virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override; + + /// called when an SDP answer is received - has nothing to do with user + /// answering the call + virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&) override; + + /// called when an SDP offer is received - must send an answer soon after this + virtual void onOffer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&) override; + + /// called when an Invite w/out SDP is sent, or any other context which + /// requires an SDP offer from the user + virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + + /// called if an offer in a UPDATE or re-INVITE was rejected - not real + /// useful. A SipMessage is provided if one is available + virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg) override; + + /// called when INFO message is received + virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + + /// called when response to INFO message is received + virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + + /// called when MESSAGE message is received + virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + + /// called when response to MESSAGE message is received + virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + + /// called when an REFER message is received. The refer is accepted or + /// rejected using the server subscription. If the offer is accepted, + /// DialogUsageManager::makeInviteSessionFromRefer can be used to create an + /// InviteSession that will send notify messages using the ServerSubscription + virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg) override; + + virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + + /// called when an REFER message receives a failure response + virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + + /// called when an REFER message receives an accepted response + virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg) override; +#pragma endregion + + // ClientRegistrationHandler implementation +#pragma region ClientRegistrationHandler implementation + /// Called when registraion succeeds or each time it is sucessfully + /// refreshed. + void onSuccess(resip::ClientRegistrationHandle, const resip::SipMessage& response) override; + + // Called when all of my bindings have been removed + void onRemoved(resip::ClientRegistrationHandle, const resip::SipMessage& response) override; + + /// call on Retry-After failure. + /// return values: -1 = fail, 0 = retry immediately, N = retry in N seconds + int onRequestRetry(resip::ClientRegistrationHandle, int retrySeconds, const resip::SipMessage& response) override; + + /// Called if registration fails, usage will be destroyed (unless a + /// Registration retry interval is enabled in the Profile) + void onFailure(resip::ClientRegistrationHandle, const resip::SipMessage& response) override; + +#pragma endregion + +#pragma region ExternalLogger implementation + /** return true to also do default logging, false to suppress default logging. */ + virtual bool operator()(resip::Log::Level level, + const resip::Subsystem& subsystem, + const resip::Data& appName, + const char* file, + int line, + const resip::Data& message, + const resip::Data& messageWithHeaders) override; +#pragma endregion + +#pragma region DnsResultSink implementation + + virtual void onDnsResult(const resip::DNSResult&) override; + virtual void onDnsResult(const resip::DNSResult&) override; + virtual void onDnsResult(const resip::DNSResult&) override; + virtual void onDnsResult(const resip::DNSResult&) override; + virtual void onDnsResult(const resip::DNSResult&) override; + +#pragma endregion + +#pragma region TransportLogger implementation + void onSipMessage(int flow, const char* msg, unsigned int length, const sockaddr* addr, unsigned int addrlen) override; +#pragma endregion + +#pragma region ClientPublicationHandler + void onSuccess(resip::ClientPublicationHandle, const resip::SipMessage& status) override; + void onRemove(resip::ClientPublicationHandle, const resip::SipMessage& status) override; + void onFailure(resip::ClientPublicationHandle, const resip::SipMessage& status) override; + int onRequestRetry(resip::ClientPublicationHandle, int retrySeconds, const resip::SipMessage& status) override; +#pragma endregion + +#pragma region SubscriptionHandler + void onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify); + void onUpdatePending(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override; + void onUpdateActive(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override; + + //unknown Subscription-State value + void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override; + int onRequestRetry(resip::ClientSubscriptionHandle, int retrySeconds, const resip::SipMessage& notify) override; + + //subscription can be ended through a notify or a failure response. + void onTerminated(resip::ClientSubscriptionHandle, const resip::SipMessage* msg) override; + //not sure if this has any value. + void onNewSubscription(resip::ClientSubscriptionHandle, const resip::SipMessage& notify) override; + + /// called to allow app to adorn a message. + void onReadyToSend(resip::ClientSubscriptionHandle, resip::SipMessage& msg) override; + void onNotifyNotReceived(resip::ClientSubscriptionHandle) override; + + /// Called when a TCP or TLS flow to the server has terminated. This can be caused by socket + /// errors, or missing CRLF keep alives pong responses from the server. + // Called only if clientOutbound is enabled on the UserProfile and the first hop server + /// supports RFC5626 (outbound). + /// Default implementation is to re-form the subscription using a new flow + void onFlowTerminated(resip::ClientSubscriptionHandle) override; + void onNewSubscription(resip::ServerSubscriptionHandle, const resip::SipMessage& sub) override; + void onTerminated(resip::ServerSubscriptionHandle) override; +#pragma endregion + +#pragma region PagerHandler + void onSuccess(resip::ClientPagerMessageHandle, const resip::SipMessage& status) override; + void onFailure(resip::ClientPagerMessageHandle, const resip::SipMessage& status, std::auto_ptr contents) override; + void onMessageArrived(resip::ServerPagerMessageHandle, const resip::SipMessage& message) override; +#pragma endregion + + void onDumCanBeDeleted() override; +protected: + // Mutex to protect this instance + Mutex mGuard; + + // Smart pointer to resiprocate's master profile instance. The stack configuration holds here. + resip::SharedPtr mProfile; + + // Resiprocate's SIP stack object pointer + resip::SipStack* mStack; + + // Resiprocate's dialog usage manager object pointer + resip::DialogUsageManager* mDum; + + // List of available transports. They are owned by SipStack - so there is no need to delete instances in UserAgent. + std::vector mTransportList; + + typedef std::map SessionMap; + + // Session's map + SessionMap mSessionMap; + + // Used configuration + VariantMap mConfig; + + // Action vector + SIPActionVector mActionVector; + + typedef std::map ClientObserverMap; + ClientObserverMap mClientObserverMap; + + typedef std::map ServerObserverMap; + ServerObserverMap mServerObserverMap; + + typedef std::set AccountSet; + AccountSet mAccountSet; + + // Constructs and sends INVITE to remote peer. Remote peer address is stored inside session object. + void sendOffer(Session* session); + void internalStopSession(Session& session); + void processWatchingList(); + bool handleMultipartRelatedNotify(const resip::SipMessage& notify); + + PSession getUserSession(int sessionId); + PAccount getAccount(const resip::NameAddr& myAddr); + PAccount getAccount(Account* account); + PAccount getAccount(int sessionId); +}; +#endif diff --git a/src/engine/endpoint/EP_NetworkQueue.cpp b/src/engine/endpoint/EP_NetworkQueue.cpp new file mode 100644 index 00000000..b0600769 --- /dev/null +++ b/src/engine/endpoint/EP_NetworkQueue.cpp @@ -0,0 +1,182 @@ +#include "EP_NetworkQueue.h" +#include "EP_Engine.h" + +WatcherQueue::WatcherQueue(UserAgent& ua) +:mActiveId(0), mAgent(ua) +{} + +WatcherQueue::~WatcherQueue() +{} + +int WatcherQueue::add(std::string peer, std::string package, void* tag) +{ + ice::Lock l(mGuard); + + // Check if queue has similar item + for (unsigned i=0; isetUa(&mAgent); + item.mSession->setType(ResipSession::Type_Subscription); + item.mSession->setTag(tag); + item.mId = item.mSession->sessionId(); + item.mSession->setRemoteAddress(peer); + item.mTag = tag; + mItemList.push_back(item); + process(); + + return item.mId; +} + +void WatcherQueue::remove(int id) +{ + ice::Lock l(mGuard); + + // Check if queue has similar item + for (unsigned i=0; ischeduled(); i++) + ; + if (i == mItemList.end()) + return; + + resip::SharedPtr msg; + int expires = DEFAULT_SUBSCRIPTION_TIME, refresh = DEFAULT_SUBSCRIPTION_REFRESHTIME; + + switch (i->mState) + { + case Item::State_ScheduledToAdd: + if (mAgent.mConfig.exists(CONFIG_SUBSCRIPTION_TIME)) + expires = mAgent.mConfig[CONFIG_SUBSCRIPTION_TIME].asInt(); + if (mAgent.mConfig.exists(CONFIG_SUBSCRIPTION_REFRESHTIME)) + refresh = mAgent.mConfig[CONFIG_SUBSCRIPTION_REFRESHTIME].asInt(); + + msg = mAgent.mDum->makeSubscription(resip::NameAddr(resip::Data(i->mTarget)), resip::Data(i->mPackage), + expires, refresh, i->mSession); + msg->header(resip::h_Accepts) = mAgent.mDum->getMasterProfile()->getSupportedMimeTypes(resip::NOTIFY); + mActiveId = i->mId; + i->mState = Item::State_Adding; + mAgent.mDum->send(msg); + break; + + case Item::State_ScheduledToDelete: + i->mSession->runTerminatedEvent(ResipSession::Type_Subscription, 0, 0); + if (i->mHandle.isValid()) + { + mActiveId = i->mId; + i->mHandle->end(); + i->mState = Item::State_Deleting; + break; + } + else + mItemList.erase(i); + break; + + case Item::State_ScheduledToRefresh: + if (i->mHandle.isValid()) + { + mActiveId = i->mId; + i->mState = Item::State_Refreshing; + i->mHandle->requestRefresh(); + } + else + mItemList.erase(i); + break; + + default: + break; + } + } +} + +void WatcherQueue::onTerminated(int id, int code) +{ + ice::Lock l(mGuard); + ItemList::iterator i = findById(id); + if (i != mItemList.end()) + { + if (i->mSession) + i->mSession->runTerminatedEvent(ResipSession::Type_Subscription, code, 0); + mItemList.erase(i); + if (i->mId == mActiveId) + mActiveId = 0; + } + process(); +} + +void WatcherQueue::onEstablished(int id, int code) +{ + ice::Lock l(mGuard); + ItemList::iterator i = findById(id); + if (i != mItemList.end()) + { + i->mState = Item::State_Active; + if (i->mId == mActiveId) + mActiveId = 0; + } + process(); +} + +WatcherQueue::ItemList::iterator WatcherQueue::findById(int id) +{ + for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++) + if (i->mId == id) + return i; + return mItemList.end(); +} + +void WatcherQueue::clear() +{ + ice::Lock l(mGuard); + for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++) + { + if (i->mHandle.isValid()) + i->mHandle->end(); + } + mItemList.clear(); +} diff --git a/src/engine/endpoint/EP_NetworkQueue.h b/src/engine/endpoint/EP_NetworkQueue.h new file mode 100644 index 00000000..5ff753ee --- /dev/null +++ b/src/engine/endpoint/EP_NetworkQueue.h @@ -0,0 +1,69 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __NETWORK_QUEUE_H +#define __NETWORK_QUEUE_H + +#include "EP_Session.h" +#include + +class UserAgent; +class WatcherQueue +{ +public: + struct Item + { + enum State + { + State_None, + State_Active, + State_ScheduledToAdd, + State_Adding, + State_ScheduledToRefresh, + State_Refreshing, + State_ScheduledToDelete, + State_Deleting + }; + + resip::ClientSubscriptionHandle mHandle; // Subscription handle + ResipSession* mSession; + State mState; + std::string mTarget; // Target's address + std::string mPackage; // Event package + void* mTag; // User tag + int mId; + + Item() + :mSession(NULL), mState(State_None), mTag(NULL), mId(0) + {} + + bool scheduled() + { + return mState == State_ScheduledToAdd || mState == State_ScheduledToDelete || mState == State_ScheduledToRefresh; + } + }; + WatcherQueue(UserAgent& agent); + ~WatcherQueue(); + + int add(std::string peer, std::string package, void* tag); + void remove(int id); + void refresh(int id); + void clear(); + + void onTerminated(int id, int code); + void onEstablished(int id, int code); + +protected: + typedef std::vector ItemList; + ItemList mItemList; + ice::Mutex mGuard; + UserAgent& mAgent; + int mActiveId; + + void process(); + ItemList::iterator findById(int id); +}; + +#endif diff --git a/src/engine/endpoint/EP_Observer.cpp b/src/engine/endpoint/EP_Observer.cpp new file mode 100644 index 00000000..0960f002 --- /dev/null +++ b/src/engine/endpoint/EP_Observer.cpp @@ -0,0 +1,106 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "EP_Observer.h" +#include "EP_Session.h" + +#include +#include + +ClientObserver::ClientObserver() +{ +} + +ClientObserver::~ClientObserver() +{ +} + +void ClientObserver::refresh() +{ + if (mHandle.isValid()) + mHandle->requestRefresh(); +} + +void ClientObserver::stop() +{ + if (mHandle.isValid()) + mHandle->end(); + else + if (mSession) + { + mSession->runTerminatedEvent(ResipSession::Type_Subscription); + if (mSession) + mSession->end(); + } + mSession = NULL; +} + +std::string ClientObserver::peer() +{ + return mPeer; +} + +ServerObserver::ServerObserver() + :mState(State_Incoming) +{ + +} + +ServerObserver::~ServerObserver() +{ + stop(); +} + +std::string ServerObserver::peer() const +{ + return mPeer; +} + +std::string ServerObserver::package() const +{ + return mPackage; +} + +void ServerObserver::update(std::string simpleId, bool online, std::string msg) +{ + if (mState != State_Active) + return; + + resip::Pidf p; + p.setEntity(mContact); + p.setSimpleId(resip::Data(simpleId)); + p.setSimpleStatus(online, resip::Data(msg)); + + if (mHandle.isValid()) + mHandle->send(mHandle->update(&p)); +} + +void ServerObserver::accept() +{ + if (mHandle.isValid() && mState == State_Incoming) + { + mState = State_Active; + mHandle->accept(); + } +} + +void ServerObserver::stop() +{ + if (!mHandle.isValid()) + return; + + switch (mState) + { + case State_Incoming: + mHandle->reject(404); + break; + case State_Active: + mHandle->end(); + break; + default: + break; + } + mState = State_Closed; +} diff --git a/src/engine/endpoint/EP_Observer.h b/src/engine/endpoint/EP_Observer.h new file mode 100644 index 00000000..586bc69e --- /dev/null +++ b/src/engine/endpoint/EP_Observer.h @@ -0,0 +1,73 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef EP_OBSERVER_H +#define EP_OBSERVER_H + +#include "../helper/HL_Pointer.h" +#include "../helper/HL_VariantMap.h" +#include "ice/ICEAddress.h" +#include "ice/ICETime.h" +#include "resip/dum/UserProfile.hxx" +#include "resip/dum/ClientRegistration.hxx" +#include "resip/dum/ClientPublication.hxx" +#include "resip/stack/DnsInterface.hxx" + +class UserAgent; +class Session; +class ResipSession; + +class ClientObserver +{ + friend class Account; + friend class UserAgent; +public: + ClientObserver(); + ~ClientObserver(); + + void refresh(); + void stop(); + std::string peer(); + +protected: + resip::ClientSubscriptionHandle mHandle; + ResipSession* mSession; + int mSessionId; + std::string mPeer; +}; + +typedef SharedPtr PClientObserver; + +class ServerObserver +{ + friend class UserAgent; +public: + ServerObserver(); + ~ServerObserver(); + + std::string peer() const; + std::string package() const; + + void accept(); + void update(std::string simpleId, bool online, std::string msg); + void stop(); + +protected: + enum State + { + State_Incoming, + State_Active, + State_Closed + }; + State mState; + resip::ServerSubscriptionHandle mHandle; + std::string mPeer, mPackage; + resip::Uri mContact; + int mSessionId; +}; + +typedef SharedPtr PServerObserver; + +#endif // EP_OBSERVER_H diff --git a/src/engine/endpoint/EP_ReliableTunnel.cpp b/src/engine/endpoint/EP_ReliableTunnel.cpp new file mode 100644 index 00000000..ece90939 --- /dev/null +++ b/src/engine/endpoint/EP_ReliableTunnel.cpp @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2007-2012 Dmytro Bogovych + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifdef _WIN32 +# include +# include +#endif + +#include + +#include "EP_ReliableTunnel.h" +#include "EP_Engine.h" +#include "Log.h" + +#include "../ICE/ICECRC32.h" + +enum +{ + CONFIRMATION_PT = 1, + DATA_PT = 2 +}; + +#define CONFIRMATION_TIMEOUT 500 +#define LOG_SUBSYSTEM "RT" + +ReliableTunnel::ReliableTunnel(const char* streamname) +{ + mStack.setEncryption(this); + mStreamName = streamname; + mBandwidth = 0; + mExitSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL); + mDataSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL); + +} + +ReliableTunnel::~ReliableTunnel() +{ + ::CloseHandle(mDataSignal); + ::CloseHandle(mExitSignal); +} + +std::string ReliableTunnel::streamName() +{ + return mStreamName; +} + +std::string ReliableTunnel::streamProfile() +{ + return "RTP/DP"; +} + +void ReliableTunnel::setDestinationAddress(InternetAddress& addr) +{ + mDestination = addr; +} + + +void ReliableTunnel::queueData(const void* bufferptr, int buffersize) +{ + assert(bufferptr != NULL); + assert(buffersize != 0); + + resip::Lock l(mNewQueuedGuard); + mNewQueued.push_back(std::string((const char*)bufferptr, buffersize)); + + ::SetEvent(mDataSignal); +} + +// This method is called by user agent to send ICE packet from mediasocket +void ReliableTunnel::sendData(InternetAddress& addr, const void* dataBuffer, unsigned int datasize) +{ + switch (addr.type()) + { + case AF_INET: + mSocket4.sendDatagram(addr, dataBuffer, datasize); + return; + + case AF_INET6: + mSocket4.sendDatagram(addr, dataBuffer, datasize); + return; + } +} + +void ReliableTunnel::sessionEstablished(int conntype) +{ + // Start worker thread + if (conntype == EV_ICE) + run(); +} + +void ReliableTunnel::sessionTerminated() +{ + // Stop worker thread + ::SetEvent(mExitSignal); + shutdown(); + join(); +} + +void ReliableTunnel::updateSdpOffer(resip::SdpContents::Session::Medium& sdp) +{ + // Get new destination port + mDestination.setPort((unsigned short)sdp.port()); + + sdp.addCodec(resip::SdpContents::Session::Codec("rt", 104)); +} + +void ReliableTunnel::setSocket(DatagramSocket& socket4, DatagramSocket& socket6) +{ + mSocket4 = socket4; + mSocket6 = socket6; +} + +DatagramSocket& ReliableTunnel::socket(int family) +{ + switch (family) + { + case AF_INET: + return mSocket4; + + case AF_INET6: + return mSocket4; + + default: + assert(0); + } +} + +bool ReliableTunnel::processSdpOffer(const resip::SdpContents::Session::Medium& media) +{ + //check for default port number + mDestination.setPort(media.port()); + + return true; +} + +void ReliableTunnel::thread() +{ + // Construct event array + while (true) + { + HANDLE eventarray[2] = { mDataSignal, mExitSignal }; + + DWORD rescode = ::WaitForMultipleObjects(2, eventarray, FALSE, INFINITE); + if (rescode == WAIT_OBJECT_0) + { + resip::Lock l(mNewQueuedGuard); + for (unsigned i = 0; imDestination, buffer, length); + } +} + +void ReliableTunnel::setEncryptionKey(void* ptr, unsigned length) +{ +#ifdef USE_OPENSSL + BF_set_key(&mCipher, length, (const unsigned char*)ptr); +#endif + +#ifdef USE_CRYPTOPP + mEncryptor.SetKey((unsigned char*)ptr, length); + mDecryptor.SetKey((unsigned char*)ptr, length); +#endif + + // Save key + mEncryptionKey = std::string((const char*)ptr, length); +} diff --git a/src/engine/endpoint/EP_ReliableTunnel.h b/src/engine/endpoint/EP_ReliableTunnel.h new file mode 100644 index 00000000..94415dd4 --- /dev/null +++ b/src/engine/endpoint/EP_ReliableTunnel.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2007-2010 Dmytro Bogovych + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __RELIABLE_TUNNEL_H +#define __RELIABLE_TUNNEL_H + +#include "DataProvider.h" +#include "InternetAddress.h" +#include "rutil/ThreadIf.hxx" +#include +#include + +#include "../ICE/ICEReliableTransport.h" +#ifdef USE_CRYPTOPP +# include "../Libs/CryptoPP/blowfish.h" +#endif +#ifdef USE_OPENSSL +# include "../Libs/openssl/include/openssl/blowfish.h" +#endif + +class ReliableTunnel: public DataProvider, public resip::ThreadIf, public ICEImpl::ReliableTransport::Encryption +{ +public: + ReliableTunnel(const char* streamname); + virtual ~ReliableTunnel(); + + // Returns provider RTP name + virtual std::string streamName(); + + // Returns provider RTP profile name + virtual std::string streamProfile(); + + // Sets destination IP address + virtual void setDestinationAddress(InternetAddress& addr); + + // Processes incoming data + virtual void processData(const void* dataBuffer, int dataSize); + + // This method is called by user agent to send ICE packet from mediasocket + virtual void sendData(InternetAddress& destination, const void* dataBuffer, unsigned int datasize); + + // Updates SDP offer + virtual void updateSdpOffer(resip::SdpContents::Session::Medium& sdp); + + // Called by user agent when session is terminated. + virtual void sessionTerminated(); + + // Called by user agent when session is started. + virtual void sessionEstablished(int conntype); + + // Called by user agent to save media socket for this provider + virtual void setSocket(DatagramSocket& socket4, DatagramSocket& socket6); + + // Called by user agent to get media socket for this provider + virtual DatagramSocket& socket(int family); + + // Called by user agent to process media stream description from remote peer. + // Returns true if description is processed succesfully. Otherwise method returns false. + virtual bool processSdpOffer(const resip::SdpContents::Session::Medium& media); + + virtual void thread(); + + // Enqueues outgoing packet to sending queue + void queueData(const void* bufferPtr, int bufferSize); + + void setBandwidth(unsigned int bytesPerSecond); + unsigned int bandwidth(); + + // Checks if there is any received application data + bool hasData(); + + // Reads received data. If ptr is NULL - the length of available data is returned. + unsigned getData(void* ptr, unsigned capacity); + + void setEncryptionKey(void* ptr, unsigned length); + +protected: + // SDP's stream name + std::string mStreamName; + + // Transport stack + ICEImpl::ReliableTransport mStack; + + // Socket handles to operate + DatagramSocket mSocket4; + DatagramSocket mSocket6; + + // Destination IP4/6 address + InternetAddress mDestination; + + // Win32 exit signal + HANDLE mExitSignal; + + // Win32 "new outgoing data" signal + HANDLE mDataSignal; + + // Mutex to protect queuing/sending outgoing data + resip::Mutex mOutgoingMtx; + + std::vector + mNewQueued; + resip::Mutex mNewQueuedGuard; + resip::Mutex mStackGuard; + + unsigned int mBandwidth; + std::string mEncryptionKey; + +#ifdef USE_CRYPTOPP + CryptoPP::BlowfishEncryption mEncryptor; + CryptoPP::BlowfishDecryption mDecryptor; +#endif + +#ifdef USE_OPENSSL + BF_KEY mCipher; +#endif + + ICEImpl::ICEByteBuffer mIncomingData; + + // Returns block size for encryption algorythm + int blockSize(); + + // Encrypts dataPtr buffer inplace. dataSize must be odd to GetBlockSize() returned value. + void encrypt(void* dataPtr, int dataSize); + + // Decrypts dataPtr buffer inplace. dataSize must be odd to GetBlockSize() returned value. + void decrypt(void* dataPtr, int dataSize); + + // Calculates CRC + unsigned crc(const void* dataptr, int datasize); + + void sendOutgoing(); +}; +#endif \ No newline at end of file diff --git a/src/engine/endpoint/EP_Session.cpp b/src/engine/endpoint/EP_Session.cpp new file mode 100644 index 00000000..d5a921ac --- /dev/null +++ b/src/engine/endpoint/EP_Session.cpp @@ -0,0 +1,1152 @@ +/* Copyright(C) 2007-2017 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "EP_Session.h" +#include "EP_Engine.h" +#include "EP_AudioProvider.h" +#include "../media/MT_Stream.h" +#include "../media/MT_AudioStream.h" +#include "../media/MT_Dtmf.h" +#include "../helper/HL_Log.h" +#include "../helper/HL_Exception.h" +#include "../helper/HL_StreamState.h" +#include "../helper/HL_Sync.h" +#include "../helper/HL_String.h" + +#define LOG_SUBSYSTEM "[Engine]" + +typedef resip::SdpContents::Session::Medium Medium; +typedef resip::SdpContents::Session::MediumContainer MediumContainer; + +#define DOMULTIPLEX() mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool() ? SocketHeap::DoMultiplexing : SocketHeap::DontMultiplexing + + +//------------ ResipSessionAppDialog ------------ +#pragma region ResipSessionAppDialog +ResipSessionAppDialog::ResipSessionAppDialog(resip::HandleManager& ham) : AppDialog(ham) +{ +} + +ResipSessionAppDialog::~ResipSessionAppDialog() +{ +} +#pragma endregion + + +#pragma region ResipSession + +resip::AtomicCounter ResipSession::InstanceCounter; + +ResipSession::ResipSession(resip::DialogUsageManager& dum) + : resip::AppDialogSet(dum), mUserAgent(NULL), mType(Type_None), mSessionId(0), mSession(0) +{ + ResipSession::InstanceCounter.increment(); + mTag = NULL; + mTerminated = false; + mOnWatchingStartSent = false; + mSessionId = Session::generateId(); +} + +ResipSession::~ResipSession() +{ + try + { + // Detach from user session + if (mSession) + mSession->mResipSession = nullptr; + runTerminatedEvent(Type_Auto, 0, 0); + } + catch(...) + { + } + + ResipSession::InstanceCounter.decrement(); +} + +resip::AppDialog* ResipSession::createAppDialog(const resip::SipMessage& msg) +{ + return new ResipSessionAppDialog(static_cast(mDum)); +} + +void ResipSession::runTerminatedEvent(Type type, int code, int reason) +{ + if (mTerminated) + return; + + Type t = type; + if (type == Type_Auto) + t = mType; + if (t == Type_None) + t = Type_Call; + + mTerminated = true; + if (mUserAgent) + { + switch (t) + { + case Type_Call: + if (mSession) + mUserAgent->onSessionTerminated(mUserAgent->getUserSession(mSessionId), code, reason); + break; + + case Type_Registration: + mUserAgent->onAccountStop(mUserAgent->getAccount(mSessionId), code); + break; + + case Type_Subscription: + if (mSession) + { + UserAgent::ClientObserverMap::iterator observerIter = mUserAgent->mClientObserverMap.find(mSession->sessionId()); + if (observerIter != mUserAgent->mClientObserverMap.end()) + mUserAgent->onClientObserverStop(observerIter->second, code); + } + break; + + default: + break; + } + } +} + +std::string ResipSession::remoteAddress() const +{ + return mRemoteAddress; +} + +void ResipSession::setRemoteAddress(std::string address) +{ + mRemoteAddress = address; +} + +void ResipSession::setType(Type type) +{ + mType = type; +} + +ResipSession::Type ResipSession::type() +{ + return mType; +} + +Session* ResipSession::session() +{ + return mSession; +} + +void* ResipSession::tag() const +{ + return mTag; +} + +void ResipSession::setTag(void* tag) +{ + mTag = tag; +} + +void ResipSession::setSession(Session* session) +{ + mSession = session; + if (mSession) + mSessionId = mSession->sessionId(); +} + +UserAgent* ResipSession::ua() +{ + return mUserAgent; +} + +void ResipSession::setUa(UserAgent* ua) +{ + mUserAgent = ua; +} + +int ResipSession::sessionId() +{ + return mSessionId; +} + +void ResipSession::setUASProfile(SharedPtr profile) +{ + mUASProfile = profile; +} + +SharedPtr ResipSession::selectUASUserProfile(const resip::SipMessage& msg) +{ + assert(mUserAgent != nullptr); + + if (mUserAgent) + { + PAccount account = mUserAgent->getAccount(msg.header(resip::h_To)); + if (account) + return account->getUserProfile(); + else + return mUserAgent->mProfile; + } + return SharedPtr(); +} + +#pragma endregion + +#pragma region Session::Stream +Session::Stream::Stream() + :mRtcpAttr(false), mRtcpMuxAttr(false) +{ +} + +Session::Stream::~Stream() +{ +} + +void Session::Stream::setProvider(PDataProvider provider) +{ + mProvider = provider; +} + +PDataProvider Session::Stream::provider() +{ + return mProvider; +} + +void Session::Stream::setSocket4(const RtpPair& socket) +{ + mSocket4 = socket; +} + +RtpPair& Session::Stream::socket4() +{ + return mSocket4; +} + +void Session::Stream::setSocket6(const RtpPair& socket) +{ + mSocket6 = socket; +} + +RtpPair& Session::Stream::socket6() +{ + return mSocket6; +} + +void Session::Stream::setIceInfo(const IceInfo& ii) +{ + mIceInfo = ii; +} + +Session::IceInfo Session::Stream::iceInfo() const +{ + return mIceInfo; +} + +bool Session::Stream::rtcpAttr() const +{ + return mRtcpAttr; +} + +void Session::Stream::setRtcpAttr(bool value) +{ + mRtcpAttr = value; +} + +bool Session::Stream::rtcpMuxAttr() const +{ + return mRtcpMuxAttr; +} + +void Session::Stream::setRtcpMuxAttr(bool value) +{ + mRtcpMuxAttr = value; +} + +#pragma endregion + +#pragma region Session +resip::AtomicCounter Session::InstanceCounter; + +Session::Session(PAccount account) +{ + InstanceCounter.increment(); + mAccount = account; + mSessionId = Session::generateId(); + mTag = NULL; + mAcceptedByEngine = false; + mAcceptedByUser = false; + mUserAgent = NULL; + mOriginVersion = 0; + mSessionVersion = 0; + mRole = Acceptor; + mGatheredCandidates = false; + mTerminated = false; + mRemoteOriginVersion = (UInt64)-1; + mResipSession = NULL; + mRefCount = 1; + mOfferAnswerCounter = 0; + mHasToSendOffer = false; + mSendOfferUpdateAfterIceGather = false; +} + +Session::~Session() +{ + try + { + if (mResipSession) + mResipSession->setSession(NULL); + clearProvidersAndSockets(); + } + catch(...) + {} + InstanceCounter.decrement(); +} + +void Session::start(const std::string& peer) +{ + ICELogInfo( << "Attempt to start session to " << peer); + Lock l(mGuard); + + if (mResipSession) + { + ICELogCritical(<< "Session " << mSessionId << " is already started."); + return; + } + + // Save target address + mRemoteAddress = UserAgent::formatSipAddress(peer); + + // Create resiprocate session + mResipSession = new ResipSession(*mUserAgent->mDum); + mResipSession->setSession(this); + mResipSession->setUa(mUserAgent); + + // Do not call OnNewSession for this session + mAcceptedByEngine = true; + + // Mark session as Initiator + mRole = Session::Initiator; + + resip::Data addrData(peer); + resip::NameAddr addr(addrData); + + // Save target address + mRemotePeer = addr; + + // Start to gather ICE candidates (streams are created in addProvider() method) + mIceStack->gatherCandidates(); +} + +void Session::stop() +{ + ICELogInfo(<< "Stopping session " << mSessionId); + Lock l(mGuard); + for (unsigned i=0; isessionTerminated(); + + // Free socket + SocketHeap::instance().freeSocketPair( dataStream.socket4() ); + SocketHeap::instance().freeSocketPair( dataStream.socket6() ); + } + } + + if (mResipSession) + mResipSession->runTerminatedEvent(ResipSession::Type_Call, 0, LocalBye); + + if (mResipSession) + mResipSession->end(); // Stop SIP session +} + +void Session::accept() +{ + ICELogInfo(<< "Attempt to accept session " << mSessionId); + + Lock locksession(mGuard); + + // If ICE candidate gathering is not finished - just mark session as accepted. It will be accepted in ICE handling code. + mAcceptedByUser = true; + + if (mGatheredCandidates || mIceStack->state() == ice::IceNone) + { + ICELogInfo(<< "Candidates are gathered for session " << mSessionId << ", build&send answer."); + + // Build SDP + resip::SdpContents sdp; + buildSdp(sdp, Sdp_Answer); + + resip::ServerInviteSession* sis = dynamic_cast(mInviteHandle.get()); + if (sis) + { + /*if (mInviteHandle.isValid()) + mInviteHandle->setUserHeaders(mUserHeaders);*/ + sis->setUserHeaders(mUserHeaders); + sis->provideAnswer(sdp); + sis->accept(); + } + + // Reset mAcceptScheduled & mGatheredCandidates + mGatheredCandidates = false; + + // Start connectivity checks + if (mIceStack->state() > ice::IceNone) + { + ICELogInfo(<< "Start connectivity checks for session " << mSessionId); + mIceStack->checkConnectivity(); + } + } + else + { + ICELogInfo(<< "ICE gathering is not finished yet for session " << mSessionId << " SDP build is deferred."); + } +} + +void Session::reject(int code) +{ + ICELogInfo( << "Attempt to reject session " << mSessionId); + + Lock l(mGuard); + + if (mInviteHandle.isValid()) + { + mInviteHandle->reject(code); + ICELogInfo(<< "Session " << mSessionId << " is rejected."); + } + else + ICELogCritical(<< "Session " << mSessionId << " has not valid invite handle."); +} + +AudioProvider* Session::findProviderForActiveAudio() +{ + for (unsigned streamIndex = 0; streamIndex < mStreamList.size(); streamIndex++) + { + PDataProvider p = mStreamList[streamIndex].provider(); + if (p) + { + if (p->streamName() == "audio") + { + AudioProvider* audio = (AudioProvider*)p.get(); + if (audio->activeStream()) + return audio; + } + } + } + return NULL; +} + +void Session::getSessionInfo(Session::InfoOptions options, VariantMap& info) +{ + Lock l(mGuard); + + // Retrieve remote sip address + info[SessionInfo_RemoteSipAddress] = remoteAddress(); + if (mIceStack) + info[SessionInfo_IceState] = mIceStack->state(); + + // Get media stats + MT::Statistics stat; + + // Iterate all session providers + stat.reset(); + Stream* media = NULL; + for (unsigned streamIndex = 0; streamIndex < mStreamList.size(); streamIndex++) + { + Stream& stream = mStreamList[streamIndex]; + if (stream.provider()) + { + media = &stream; + MT::Statistics s = stream.provider()->getStatistics(); +#if defined(USE_PVQA_LIBRARY) && !defined(PVQA_SERVER) + if (options != InfoOptions::Standard) + { + //if (s.mPvqaMos == 0.0f) + // s.mPvqaMos = calculatePvqaMos(AUDIO_SAMPLERATE); + info[SessionInfo_PvqaMos] = s.mPvqaMos; + info[SessionInfo_PvqaReport] = s.mPvqaReport; + } +#endif + info[SessionInfo_NetworkMos] = (float)s.calculateMos(4.14); + info[SessionInfo_AudioCodec] = s.mCodecName; + + stat += s; + } + } + + info[SessionInfo_ReceivedTraffic] = (int)stat.mReceived; + info[SessionInfo_SentTraffic] = (int)stat.mSent; + info[SessionInfo_ReceivedRtp] = stat.mReceivedRtp; + info[SessionInfo_ReceivedRtcp] = stat.mReceivedRtcp; + info[SessionInfo_LostRtp] = stat.mPacketLoss; + info[SessionInfo_SentRtp] = stat.mSentRtp; + info[SessionInfo_SentRtcp] = stat.mSentRtcp; + if (stat.mFirstRtpTime) + info[SessionInfo_Duration] = (int)std::chrono::duration_cast(std::chrono::system_clock::now() - *(stat.mFirstRtpTime)).count(); + else + info[SessionInfo_Duration] = 0; + + if (stat.mReceivedRtp) + info[SessionInfo_PacketLoss] = (stat.mPacketLoss * 1000) / stat.mReceivedRtp; + + if (media) + info[SessionInfo_AudioPeer] = mIceStack->remoteAddress(media->iceInfo().mStreamId, media->iceInfo().mComponentId.mRtp).toStdString(); + + info[SessionInfo_Jitter] = stat.mJitter; + if (stat.mRttDelay.isInitialized()) + info[SessionInfo_Rtt] = (float)stat.mRttDelay.getCurrent() * 1000; +#if defined(USE_AMR_CODEC) + info[SessionInfo_BitrateSwitchCounter] = stat.mBitrateSwitchCounter; +#endif + info[SessionInfo_SSRC] = stat.mSsrc; + info[SessionInfo_RemotePeer] = stat.mRemotePeer.toStdString(); +} + +int Session::id() const +{ + return mSessionId; +} + +PAccount Session::account() +{ + return mAccount; +} + +void Session::onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr, unsigned receivedSize) +{ + Lock l(mGuard); + + if (mTerminated) + return; + + // Check if it STUN packet and must be processed by ICE stack + //ICELogDebug (<< "Received UDP packet from " << src.ip() << ":" << src.port()); + ice::ByteBuffer received(receivedPtr, receivedSize); + received.setRemoteAddress(src); + + ice::ByteBuffer plain; + + if (ice::Stack::isStun(received)) + { + // Check if it is Data indication packet + if (ice::Stack::isDataIndication(received, &plain)) + { + received = plain; + } + } + else // Check if packet is prefixed with TURN prefix + if (received.size() >= 4) + { + bool turnPrefix = false; + for (unsigned i=0; ifindStreamAndComponent(socket->family(), socket->localport(), &stream, &component)) + { + ice::ByteBuffer buffer(receivedPtr, receivedSize); + buffer.setRemoteAddress(src); + processed = mIceStack->processIncomingData(stream, component, buffer); + } + } + else + { + // Find provider responsible for processing + PDataProvider provider = this->findProviderByPort(socket->family(), socket->localport()); + if (provider) + { + provider->processData(socket, receivedPtr, receivedSize, src); + } + else + { + // Just ignore these data + } + } +} + +// Called when new candidate is gathered +void Session::onCandidateGathered(ice::Stack* stack, void* tag, const char* address) +{ + mUserAgent->onCandidateGathered(mUserAgent->getUserSession(mSessionId), address); +} + + +// Called when connectivity check is finished +void Session::onCheckFinished(ice::Stack* stack, void* tag, const char* checkDescription) +{ + mUserAgent->onCheckFinished(mUserAgent->getUserSession(mSessionId), checkDescription); +} + +void Session::onGathered(ice::Stack* stack, void* tag) +{ + Lock l(mGuard); + + // This part handles situation when network was changed and new ice candidate were gathered + if (mSendOfferUpdateAfterIceGather) + { + mSendOfferUpdateAfterIceGather = false; + enqueueOffer(); + return; + } + + // This is sending of initial offer/answer after first gather of ice candidates + mUserAgent->onGathered(mUserAgent->getUserSession(mSessionId)); + + if (mRole == Initiator) + mUserAgent->sendOffer(this); + else + if (mRole == Acceptor) + { + // Mark session as gathered ICE candidates + mGatheredCandidates = true; + + // if AcceptSession was already called() on session - recall it again to make real work + if (mAcceptedByUser) + { + // Check if session is needed here - because session can be terminated already + if (mResipSession && mInviteHandle.isValid()) + accept(); + } + } +} + +void Session::onSuccess(ice::Stack* stack, void* tag) +{ + ICELogInfo(<< "ICE connectivity check succeed."); + + RtpPair t; + + for (unsigned i=0; imStreamList.size(); i++) + { + PDataProvider p = mStreamList[i].provider(); + if (p) + { + // Set new destination address + t.mRtp = stack->remoteAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTP_ID); + // Check if there remote address for rtcp component + + t.mRtcp = stack->remoteAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTCP_ID); + if (t.mRtcp.isEmpty()) + t.mRtcp = t.mRtp; + + p->setDestinationAddress(t); + + // Notify provider about connectivity checks success + mStreamList[i].provider()->sessionEstablished(EV_ICE); + } + } + + mUserAgent->onSessionEstablished(mUserAgent->getUserSession(mSessionId), EV_ICE, t); + + //time to resend updated media info over SIP + //TODO: +} + +void Session::onFailed(ice::Stack* stack, void* tag) +{ + ICELogCritical(<< "ICE connectivity check failed for session " << mSessionId); + mUserAgent->onConnectivityFailed(mUserAgent->getUserSession(mSessionId)); + + //if (mInviteHandle.isValid()) + // mInviteHandle->end(); +} + +void Session::onNetworkChange(ice::Stack *stack, void *tag) +{ + ICELogCritical(<< "Network change detected by ICE stack for session " << mSessionId); + mUserAgent->onNetworkChange(mUserAgent->getUserSession(mSessionId)); +} + +void Session::buildSdp(resip::SdpContents &sdp, SdpDirection sdpDirection) +{ + sdp.session().name() = "ICE_UA"; + sdp.session().origin().user() = "user"; + + // Set versions + sdp.version() = 0; + sdp.session().version() = mSessionVersion; + sdp.session().origin().getVersion() = ++mOriginVersion; + + // At least 1 stream must exists + if (mStreamList.empty()) + return; + + // Get default ip address for front stream + ice::NetworkAddress defaultAddr = mIceStack->defaultAddress(mStreamList.front().iceInfo().mStreamId, ICE_RTP_ID); + + // Set IP address for origin and connection + sdp.session().origin().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET ? resip::SdpContents::IP4 : resip::SdpContents::IP6); + sdp.session().connection().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET ? resip::SdpContents::IP4 : resip::SdpContents::IP6); + + // Add ICE credentials + if (mIceStack->state() > ice::IceNone) + { + sdp.session().addAttribute("ice-pwd", resip::Data(mIceStack->localPassword())); + sdp.session().addAttribute("ice-ufrag", resip::Data(mIceStack->localUfrag())); + } + + // Iterate media streams + for (unsigned i=0; idefaultAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTP_ID), + rtcpPort = mIceStack->defaultAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTCP_ID); + + // Define media stream SDP's header + resip::SdpContents::Session::Medium media(resip::Data(provider.streamName()), rtpPort.port(), 0, resip::Data(provider.streamProfile())); + + // Add "rtcp" attribute + if (mUserAgent->mConfig[CONFIG_RTCP_ATTR].asBool()) + { + if (mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool()) + rtcpPort = rtpPort; + else + if (rtcpPort.isEmpty()) + { + rtcpPort = rtpPort; + rtcpPort.setPort( rtpPort.port() + 1); + } + + media.addAttribute("rtcp", resip::Data(rtcpPort.port())); + } + + // Add "rtcp-mux" attribute + if (mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool()) + media.addAttribute("rtcp-mux"); + + // Ask provider about specific information + provider.updateSdpOffer(media, sdpDirection); + + // Add ICE information + std::vector candidates; + if (stream.iceInfo().mStreamId != -1) + { + IceInfo ii = stream.iceInfo(); + mIceStack->fillCandidateList(ii.mStreamId, ii.mComponentId.mRtp, candidates); + + if (mIceStack->hasComponent(ii.mStreamId, ii.mComponentId.mRtcp)) + mIceStack->fillCandidateList(ii.mStreamId, ii.mComponentId.mRtcp, candidates); + + for (unsigned c=0; clocalport() == port || s.socket4().mRtcp->localport() == port) && family == AF_INET) + return s.provider(); + if ((s.socket6().mRtp->localport() == port || s.socket6().mRtcp->localport() == port) && family == AF_INET6) + return s.provider(); + } + + return PDataProvider(); +} + +void Session::addProvider(PDataProvider provider) +{ + // Ignore NULL providers + if (!provider) + return; + + // Avoid duplicating providers + for (unsigned i=0; i::iterator streamIter; + + for (streamIter = mStreamList.begin(); streamIter != mStreamList.end(); ++streamIter) + { + if (!streamIter->provider() && (streamIter->socket4().mRtp->isValid() || streamIter->socket6().mRtp->isValid())) + { + streamIter->setProvider( provider ); + provider->setSocket(streamIter->socket4(), streamIter->socket6()); + return; + } + } + + Stream s; + s.setProvider( provider ); + + // Allocate socket for provider + s.setSocket4( SocketHeap::instance().allocSocketPair(AF_INET, this, DOMULTIPLEX()) ); + s.setSocket6( SocketHeap::instance().allocSocketPair(AF_INET6, this, DOMULTIPLEX()) ); + s.provider()->setSocket(s.socket4(), s.socket6()); + + // Create ICE stream/component + IceInfo ii; + ii.mStreamId = mIceStack->addStream(); + ii.mPort4 = s.socket4().mRtp->localport(); + ii.mPort6 = s.socket6().mRtp->localport(); + + ii.mComponentId.mRtp = mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtp->localport(), + s.socket6().mRtp->localport()); + if (!mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool()) + ii.mComponentId.mRtcp = mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtcp->localport(), s.socket6().mRtcp->localport()); + + s.setIceInfo(ii); + + mStreamList.push_back(s); +} + +PDataProvider Session::providerAt(int index) +{ + if (mStreamList.size() > unsigned(index)) + return mStreamList[index].provider(); + return PDataProvider(); +} + +int Session::getProviderCount() +{ + return mStreamList.size(); +} + +int Session::sessionId() +{ + return mSessionId; +} + +resip::AtomicCounter Session::IdGenerator; +int Session::generateId() +{ + return (int)IdGenerator.increment(); +} + +std::string Session::remoteAddress() const +{ + return mRemoteAddress; +} + +void Session::setRemoteAddress(const std::string& address) +{ + mRemoteAddress = address; +} + +void Session::setUserHeaders(const UserHeaders& headers) +{ + mUserHeaders = headers; +} + +void* Session::tag() +{ + return mTag; +} + +void Session::setTag(void* tag) +{ + mTag = tag; +} + +void Session::pause() +{ + for (unsigned i=0; ipause(); + } + enqueueOffer(); +} + +void Session::resume() +{ + for (unsigned i=0; iresume(); + } + enqueueOffer(); +} + +void Session::refreshMediaPath() +{ + // Recreate media sockets + for (unsigned i=0; isocket(AF_INET)); + + // Bring new socket to provider and stream + RtpPair s4 = SocketHeap::instance().allocSocketPair(AF_INET, this, DOMULTIPLEX() ), + s6 = SocketHeap::instance().allocSocketPair(AF_INET, this, DOMULTIPLEX()); + + p->setSocket(s4, s6); + s.setSocket4(s4); + s.setSocket6(s6); + } + + // Recreate new ufrag/pwd and gather ice candidates + mIceStack->refreshPwdUfrag(); + mIceStack->gatherCandidates(); + + // New offer will be enqueued after ice gather finished + mSendOfferUpdateAfterIceGather = true; + mHasToSendOffer = false; +} + +// Received offer with new SDP +int Session::processSdp(UInt64 version, bool iceAvailable, std::string icePwd, std::string iceUfrag, + std::string remoteIp, const resip::SdpContents::Session::MediumContainer& media) +{ + bool iceRestart = false; + + int mediaCompatible = 0; + MediumContainer::const_iterator mediaIter; + unsigned streamIndex = 0; + for (mediaIter = media.begin(); mediaIter != media.end(); ++mediaIter, ++streamIndex) + { + // Get reference to SDP description of remote stream + const resip::SdpContents::Session::Medium& remoteStream = *mediaIter; + + // Get reference to local stream description + if (streamIndex >= mStreamList.size()) + mStreamList.push_back(Session::Stream()); + Session::Stream& stream = mStreamList[streamIndex]; + + // Ask about provider if needed + if (!stream.provider()) + stream.setProvider( mUserAgent->onProviderNeeded(remoteStream.name().c_str()) ); + + // Check the stream validity + if (!stream.provider()) + continue; + if (!stream.provider()->processSdpOffer(remoteStream, Sdp_Offer)) + continue; + + // See for rtcp & rtcp-mux attribute + stream.setRtcpAttr( remoteStream.exists("rtcp") ); + stream.setRtcpMuxAttr( remoteStream.exists("rtcp-mux") ); + + // Set destination address + if (!remoteStream.getConnections().empty()) + remoteIp = remoteStream.getConnections().front().getAddress().c_str(); + + RtpPair targetAddr; + targetAddr.mRtp.setIp(remoteIp); + targetAddr.mRtp.setPort(remoteStream.port()); + + targetAddr.mRtcp.setIp(remoteIp); + if (stream.rtcpMuxAttr()) + targetAddr.mRtcp.setPort( remoteStream.port() ); + else + if (stream.rtcpAttr()) + targetAddr.mRtcp.setPort( StringHelper::toInt(remoteStream.getValues("rtcp").front().c_str(), remoteStream.port() + 1 ) ); + else + targetAddr.mRtcp.setPort( remoteStream.port() + 1); + + stream.provider()->setDestinationAddress(targetAddr); + + // Media is compatible; increase the counter and prepare ice stream/component + mediaCompatible++; + + // Get default remote port number + unsigned short remotePort = remoteStream.port(); + + // Create media socket if needed + if (!stream.socket4().mRtp) + { + try + { + stream.setSocket4(SocketHeap::instance().allocSocketPair(AF_INET, this, DOMULTIPLEX())); + stream.setSocket6(SocketHeap::instance().allocSocketPair(AF_INET6, this, DOMULTIPLEX())); + } + catch(...) + { + ICELogCritical( << "Cannot create media socket."); + return 503; + } + + // Update provider with socket references + stream.provider()->setSocket(stream.socket4(), stream.socket6()); + } + + + const std::list& iceUfragAttr = remoteStream.getValues("ice-ufrag"); + if (iceUfragAttr.size()) + iceUfrag = iceUfragAttr.front().c_str(); + + const std::list& icePwdAttr = remoteStream.getValues("ice-pwd"); + if (icePwdAttr.size()) + icePwd = icePwdAttr.front().c_str(); + + // Create ICE stream; it will be created even if ice is not requested. + // The cause is we need to hold default address and possible STUN requests result + if (stream.iceInfo().mStreamId == -1) + { + IceInfo ii; + ii.mStreamId = mIceStack->addStream(); + ii.mPort4 = stream.socket4().mRtp->localport(); + ii.mPort6 = stream.socket6().mRtp->localport(); + ii.mComponentId.mRtp = mIceStack->addComponent(ii.mStreamId, NULL, ii.mPort4, ii.mPort6); + + // See what remote peer offers - offer only single ice component if it relies on multiplexing + if (!targetAddr.multiplexed() && !mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool()) + ii.mComponentId.mRtcp = mIceStack->addComponent(ii.mStreamId, NULL, stream.socket4().mRtcp->localport(), stream.socket6().mRtcp->localport()); + stream.setIceInfo(ii); + } + + if (iceAvailable) + { + if (mIceStack->remotePassword(stream.iceInfo().mStreamId) != icePwd || mIceStack->remoteUfrag(stream.iceInfo().mStreamId) != iceUfrag) + { + iceRestart = true; + mIceStack->setRemotePassword(icePwd, stream.iceInfo().mStreamId); + mIceStack->setRemoteUfrag(iceUfrag, stream.iceInfo().mStreamId); + } + } + + // Get remote ICE candidates vector + const std::list candidateList = remoteStream.getValues("candidate"); + + // Repackage information about remote candidates + std::vector candidateVector; + std::list::const_iterator cit = candidateList.begin(); + + for (; cit != candidateList.end(); ++cit) + candidateVector.push_back(cit->c_str()); + + if (candidateVector.empty()) + iceAvailable = false; + + // Ask ICE stack to process this information. This call will remove also second component if it is not defined in remote sdp. + if (iceAvailable) + iceAvailable = mIceStack->processSdpOffer(stream.iceInfo().mStreamId, candidateVector, remoteIp, remotePort, mUserAgent->mConfig[CONFIG_DEFERRELAYED].asBool()); + } + + // See if there are compatible media streams + if (!mediaCompatible) + return 488; // Not acceptable media + + // Start ICE check connectivity if required + if (iceRestart && iceAvailable) + { + if (mIceStack->state() > ice::IceGathering) + mIceStack->checkConnectivity(); + else + mIceStack->gatherCandidates(); + } + + return 200; +} + +int Session::increaseSdpVersion() +{ + return ++mOriginVersion; +} + +void Session::setUserAgent(UserAgent* agent) +{ + mUserAgent = agent; +} + +UserAgent* Session::userAgent() +{ + return mUserAgent; +} + +int Session::addRef() +{ + return ++mRefCount; +} + +int Session::release() +{ + mRefCount--; + return mRefCount; +} + +void Session::clearProvidersAndSockets() +{ + for (unsigned i=0; isessionDeleted(); + SocketHeap::instance().freeSocketPair( ds.socket4() ); + SocketHeap::instance().freeSocketPair( ds.socket6() ); + } + } +} + +void Session::clearProviders() +{ + for (unsigned i=0; isessionTerminated(); + } +} + +#pragma endregion + + +void Session::enqueueOffer() +{ + mHasToSendOffer = true; + processQueuedOffer(); +} + +void Session::processQueuedOffer() +{ + if (!mHasToSendOffer) + return; + + if (mInviteHandle.isValid()) + { + if (mInviteHandle->canProvideOffer()) + { + mUserAgent->sendOffer(this); + mHasToSendOffer = false; + } + } +} + +//-------------- ResipSessionFactory --------- +#pragma region ResipSessionFactory + +ResipSessionFactory::ResipSessionFactory(UserAgent* agent) +:mAgent(agent) +{} + +resip::AppDialogSet* ResipSessionFactory::createAppDialogSet(resip::DialogUsageManager& dum, const resip::SipMessage& msg) +{ + ResipSession* s = new ResipSession(dum); + s->setUa( mAgent ); + return s; +} + + +#pragma endregion diff --git a/src/engine/endpoint/EP_Session.h b/src/engine/endpoint/EP_Session.h new file mode 100644 index 00000000..d1dbfcdb --- /dev/null +++ b/src/engine/endpoint/EP_Session.h @@ -0,0 +1,410 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __SESSION_H +#define __SESSION_H + +#include "resip/stack/SdpContents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/ShutdownMessage.hxx" +#include "resip/stack/SipStack.hxx" +#include "resip/dum/ClientAuthManager.hxx" +#include "resip/dum/ClientInviteSession.hxx" +#include "resip/dum/ClientRegistration.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/DumShutdownHandler.hxx" +#include "resip/dum/InviteSessionHandler.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/RegistrationHandler.hxx" +#include "resip/dum/ServerInviteSession.hxx" +#include "resip/dum/ServerOutOfDialogReq.hxx" +#include "resip/dum/OutOfDialogHandler.hxx" +#include "resip/dum/AppDialog.hxx" +#include "resip/dum/AppDialogSet.hxx" +#include "resip/dum/AppDialogSetFactory.hxx" +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Random.hxx" +#include "rutil/WinLeakCheck.hxx" +#include "rutil/AtomicCounter.hxx" + +#include "../ice/ICEBox.h" + +#include +#include + +#include "../config.h" +#include "EP_Session.h" +#include "EP_Account.h" +#include "EP_DataProvider.h" +#include "EP_AudioProvider.h" +#include "../helper/HL_VariantMap.h" +#include "../helper/HL_SocketHeap.h" + +using namespace std; + +class UserAgent; +class ResipSession; + +enum SessionInfo +{ + SessionInfo_RemoteSipAddress, // remote sip address + SessionInfo_ReceivedTraffic, // amount of received traffic in session in bytes + SessionInfo_SentTraffic, // amount of sent traffic in session in bytes + SessionInfo_PacketLoss, // lost packets counter; returns number of 1/1000 fractions (0.1%) + SessionInfo_AudioPeer, // remote peer rtp address in text + SessionInfo_AudioCodec, // selected audio codec as text + SessionInfo_DtmfInterface, // Pointer to DtmfQueue class; returned as void* + SessionInfo_IceState, + SessionInfo_NetworkMos, + SessionInfo_PvqaMos, + SessionInfo_PvqaReport, + SessionInfo_SentRtp, + SessionInfo_SentRtcp, + SessionInfo_ReceivedRtp, + SessionInfo_ReceivedRtcp, + SessionInfo_LostRtp, + SessionInfo_Duration, + SessionInfo_Jitter, + SessionInfo_Rtt, + SessionInfo_BitrateSwitchCounter, // It is for AMR codecs only + SessionInfo_RemotePeer, + SessionInfo_SSRC +}; + + +class Session : + public SocketSink, + public ice::StageHandler +{ +public: + class Command + { + public: + virtual void run(Session& s) = 0; + }; + + // Describes ice stream/component + struct IceInfo + { + IceInfo() + :mStreamId(-1) + { + mPort4 = mPort6 = 0; + mComponentId.mRtp = mComponentId.mRtcp = -1; + } + + RtpPair mComponentId; + int mStreamId; + unsigned short mPort4; + unsigned short mPort6; + }; + + // Describes media stream (audio/video) in session + class Stream + { + public: + Stream(); + ~Stream(); + + void setProvider(PDataProvider provider); + PDataProvider provider(); + + void setSocket4(const RtpPair& socket); + RtpPair& socket4(); + + void setSocket6(const RtpPair& socket); + RtpPair& socket6(); + + void setIceInfo(const IceInfo& info); + IceInfo iceInfo() const; + + // rtcpAttr/rtcpMuxAttr signals about corresponding sip attribute in offer/answer from remote peer + bool rtcpAttr() const; + void setRtcpAttr(bool value); + + bool rtcpMuxAttr() const; + void setRtcpMuxAttr(bool value); + + protected: + // Provider for corresponding stream + PDataProvider mProvider; + + // Socket for stream + RtpPair mSocket4, mSocket6; + + bool mRtcpAttr; + bool mRtcpMuxAttr; + IceInfo mIceInfo; + }; + + Session(PAccount account); + virtual ~Session(); + + // Starts call to specified peer + void start(const std::string& peer); + + // Stops call + void stop(); + + // Accepts call + void accept(); + + // Rejects call + void reject(int code); + + enum class InfoOptions + { + Standard = 0, + Detailed = 1, + }; + + void getSessionInfo(InfoOptions options, VariantMap& result); + + // Returns integer identifier of the session; it is unique amongst all session in application + int id() const; + + // Returns owning account + PAccount account(); + + typedef std::map UserHeaders; + void setUserHeaders(const UserHeaders& headers); + + // Called when new media data are available for this session + void onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr, unsigned receivedSize); + + // Called when new candidate is gathered + void onCandidateGathered(ice::Stack* stack, void* tag, const char* address); + + // Called when connectivity check is finished + void onCheckFinished(ice::Stack* stack, void* tag, const char* checkDescription); + + // Called when ICE candidates are gathered - with success or timeout. + void onGathered(ice::Stack* stack, void* tag); + + // Called when ICE connectivity check is good at least for one of required streams + void onSuccess(ice::Stack* stack, void* tag); + + // Called when ICE connectivity check is failed for all of required streams + void onFailed(ice::Stack* stack, void* tag); + + // Called when ICE stack detects network change during the call + void onNetworkChange(ice::Stack* stack, void* tag); + + // Fills SDP according to ICE and provider's data + void buildSdp(resip::SdpContents& sdp, SdpDirection sdpDirection); + + // Searches provider by its local port number + PDataProvider findProviderByPort(int family, unsigned short port); + + // Add provider to internal list + void addProvider(PDataProvider provider); + PDataProvider providerAt(int index); + int getProviderCount(); + + void setUserAgent(UserAgent* agent); + UserAgent* userAgent(); + + // Pauses and resumes all providers; updates states + void pause(); + void resume(); + void refreshMediaPath(); + + // Processes new sdp from offer. Returns response code (200 is ok, 488 bad codec, 503 internal error). + int processSdp(UInt64 version, bool iceAvailable, std::string icePwd, std::string iceUfrag, + std::string remoteIp, const resip::SdpContents::Session::MediumContainer& media); + + // Session ID + int mSessionId; + + // Media streams collection + std::vector mStreamList; + + // Smart pointer to ICE stack. Actually stack is created in CreateICEStack() method + resip::SharedPtr mIceStack; + + // Pointer to owner user agent instance + UserAgent* mUserAgent; + + // Remote peer SIP address + resip::NameAddr mRemotePeer; + + // Mutex to protect this instance + Mutex mGuard; + + // SDP's origin version for sending + int mOriginVersion; + UInt64 mRemoteOriginVersion; + + // SDP's session version + int mSessionVersion; + + // Marks if this session does not need OnNewSession event + bool mAcceptedByEngine; + bool mAcceptedByUser; + + // Invite session handle + resip::InviteSessionHandle mInviteHandle; + + // Dialog set object pointer + ResipSession* mResipSession; + + // Reference counter + int mRefCount; + + enum + { + Initiator = 1, + Acceptor = 2 + }; + + // Specifies session role - caller (Initiator) or callee (Acceptor) + volatile int mRole; + + // Marks if candidates are gather already + volatile bool mGatheredCandidates; + + // Marks if OnTerminated event was called already on session + volatile bool mTerminated; + + // User friend remote peer's sip address + std::string mRemoteAddress; + + // Application specific data + void* mTag; + + // Used to count number of transistions to Connected state and avoid multiple onEstablished events. + int mOfferAnswerCounter; + + // List of turn prefixes related to sessioj + std::vector mTurnPrefixList; + + // True if user agent has to send offer + bool mHasToSendOffer; + + // True if user agent has to enqueue offer after ice gather finished + bool mSendOfferUpdateAfterIceGather; + + // Related sip account + PAccount mAccount; + + // User headers for INVITE transaction + UserHeaders mUserHeaders; + + std::string remoteAddress() const; + void setRemoteAddress(const std::string& address); + + void* tag(); + void setTag(void* tag); + int sessionId(); + int increaseSdpVersion(); + int addRef(); + int release(); + + // Deletes providers and media sockets + void clearProvidersAndSockets(); + + // Deletes providers + void clearProviders(); + + // Helper method to find audio provider for active sip stream + AudioProvider* findProviderForActiveAudio(); + + void processCommandList(); + void addCommand(Command* cmd); + void enqueueOffer(); + void processQueuedOffer(); + static int generateId(); + static resip::AtomicCounter IdGenerator; + static resip::AtomicCounter InstanceCounter; +}; + +typedef SharedPtr PSession; + +///////////////////////////////////////////////////////////////////////////////// +// +// Classes that provide the mapping between Application Data and DUM +// dialogs/dialogsets +// +// The DUM layer creates an AppDialog/AppDialogSet object for inbound/outbound +// SIP Request that results in Dialog creation. +// +///////////////////////////////////////////////////////////////////////////////// +class ResipSessionAppDialog : public resip::AppDialog +{ +public: + ResipSessionAppDialog(resip::HandleManager& ham); + virtual ~ResipSessionAppDialog(); +}; + +class ResipSession: public resip::AppDialogSet +{ +friend class UserAgent; +friend class Account; + +public: + enum Type + { + Type_None, + Type_Registration, + Type_Subscription, + Type_Call, + Type_Auto + }; + static resip::AtomicCounter InstanceCounter; + + + ResipSession(resip::DialogUsageManager& dum); + virtual ~ResipSession(); + virtual resip::AppDialog* createAppDialog(const resip::SipMessage& msg); + virtual resip::SharedPtr selectUASUserProfile(const resip::SipMessage& msg); + + void setType(Type type); + Type type(); + + Session* session(); + void setSession(Session* session); + + UserAgent* ua(); + void setUa(UserAgent* ua); + + // Used for subscriptions/messages + int sessionId(); + + // Used for subscriptions/messages + void* tag() const; + void setTag(void* tag); + + // Used for subscriptions/messages + std::string remoteAddress() const; + void setRemoteAddress(std::string address); + + void runTerminatedEvent(Type type, int code = 0, int reason = 0); + + void setUASProfile(SharedPtr profile); + +protected: + bool mTerminated; + UserAgent* mUserAgent; + Type mType; + Session* mSession; + int mSessionId; + std::string mRemoteAddress; + void* mTag; + bool mOnWatchingStartSent; + SharedPtr mUASProfile; +}; + + +class ResipSessionFactory : public resip::AppDialogSetFactory +{ +public: + ResipSessionFactory(UserAgent* agent); + virtual resip::AppDialogSet* createAppDialogSet(resip::DialogUsageManager& dum, const resip::SipMessage& msg); +protected: + UserAgent* mAgent; +}; + +#endif diff --git a/src/engine/helper/CMakeLists.txt b/src/engine/helper/CMakeLists.txt new file mode 100644 index 00000000..c670324d --- /dev/null +++ b/src/engine/helper/CMakeLists.txt @@ -0,0 +1,29 @@ +project (helper_lib) + +# Rely on C++ 11 +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +set (HELPER_LIB_SOURCES + HL_AsyncCommand.cpp + HL_Calculator.cpp + HL_CsvReader.cpp + HL_Epoll.cpp + HL_HepSupport.cpp + HL_IuUP.cpp + HL_Log.cpp + HL_NetworkFrame.cpp + HL_NetworkSocket.cpp + HL_OsVersion.cpp + HL_Pointer.cpp + HL_Rtp.cpp + HL_Singletone.cpp + HL_SocketHeap.cpp + HL_String.cpp + HL_Sync.cpp + HL_Usb.cpp + HL_Uuid.cpp + HL_VariantMap.cpp +) + +add_library(helper_lib ${HELPER_LIB_SOURCES}) diff --git a/src/engine/helper/HL_AsyncCommand.cpp b/src/engine/helper/HL_AsyncCommand.cpp new file mode 100644 index 00000000..9d04e3c2 --- /dev/null +++ b/src/engine/helper/HL_AsyncCommand.cpp @@ -0,0 +1,16 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "HL_AsyncCommand.h" + +AsyncCommand::AsyncCommand() +{ + +} + +AsyncCommand::~AsyncCommand() +{ + +} diff --git a/src/engine/helper/HL_AsyncCommand.h b/src/engine/helper/HL_AsyncCommand.h new file mode 100644 index 00000000..aea6ddaf --- /dev/null +++ b/src/engine/helper/HL_AsyncCommand.h @@ -0,0 +1,19 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef HL_ASYNCCOMMAND_H +#define HL_ASYNCCOMMAND_H + +class AsyncCommand +{ +public: + AsyncCommand(); + virtual ~AsyncCommand(); + + virtual void run(void* environment) = 0; + virtual bool finished() = 0; +}; + +#endif // HL_ASYNCCOMMAND_H diff --git a/src/engine/helper/HL_Base64.h b/src/engine/helper/HL_Base64.h new file mode 100644 index 00000000..20e30356 --- /dev/null +++ b/src/engine/helper/HL_Base64.h @@ -0,0 +1,256 @@ +#ifndef HL_BASE64_H +#define HL_BASE64_H + +#include + +const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +class Base64 { + public: + static bool Encode(const std::string &in, std::string *out) { + int i = 0, j = 0; + size_t enc_len = 0; + unsigned char a3[3]; + unsigned char a4[4]; + + out->resize(EncodedLength(in)); + + int input_len = in.size(); + std::string::const_iterator input = in.begin(); + + while (input_len--) { + a3[i++] = *(input++); + if (i == 3) { + a3_to_a4(a4, a3); + + for (i = 0; i < 4; i++) { + (*out)[enc_len++] = kBase64Alphabet[a4[i]]; + } + + i = 0; + } + } + + if (i) { + for (j = i; j < 3; j++) { + a3[j] = '\0'; + } + + a3_to_a4(a4, a3); + + for (j = 0; j < i + 1; j++) { + (*out)[enc_len++] = kBase64Alphabet[a4[j]]; + } + + while ((i++ < 3)) { + (*out)[enc_len++] = '='; + } + } + + return (enc_len == out->size()); + } + + static bool Encode(const char *input, size_t input_length, char *out, size_t out_length) { + int i = 0, j = 0; + char *out_begin = out; + unsigned char a3[3]; + unsigned char a4[4]; + + size_t encoded_length = EncodedLength(input_length); + + if (out_length < encoded_length) return false; + + while (input_length--) { + a3[i++] = *input++; + if (i == 3) { + a3_to_a4(a4, a3); + + for (i = 0; i < 4; i++) { + *out++ = kBase64Alphabet[a4[i]]; + } + + i = 0; + } + } + + if (i) { + for (j = i; j < 3; j++) { + a3[j] = '\0'; + } + + a3_to_a4(a4, a3); + + for (j = 0; j < i + 1; j++) { + *out++ = kBase64Alphabet[a4[j]]; + } + + while ((i++ < 3)) { + *out++ = '='; + } + } + + return (out == (out_begin + encoded_length)); + } + + static bool Decode(const std::string &in, std::string *out) { + int i = 0, j = 0; + size_t dec_len = 0; + unsigned char a3[3]; + unsigned char a4[4]; + + int input_len = in.size(); + std::string::const_iterator input = in.begin(); + + out->resize(DecodedLength(in)); + + while (input_len--) { + if (*input == '=') { + break; + } + + a4[i++] = *(input++); + if (i == 4) { + for (i = 0; i <4; i++) { + a4[i] = b64_lookup(a4[i]); + } + + a4_to_a3(a3,a4); + + for (i = 0; i < 3; i++) { + (*out)[dec_len++] = a3[i]; + } + + i = 0; + } + } + + if (i) { + for (j = i; j < 4; j++) { + a4[j] = '\0'; + } + + for (j = 0; j < 4; j++) { + a4[j] = b64_lookup(a4[j]); + } + + a4_to_a3(a3,a4); + + for (j = 0; j < i - 1; j++) { + (*out)[dec_len++] = a3[j]; + } + } + + return (dec_len == out->size()); + } + + static bool Decode(const char *input, size_t input_length, char *out, size_t out_length) { + int i = 0, j = 0; + char *out_begin = out; + unsigned char a3[3]; + unsigned char a4[4]; + + size_t decoded_length = DecodedLength(input, input_length); + + if (out_length < decoded_length) return false; + + while (input_length--) { + if (*input == '=') { + break; + } + + a4[i++] = *(input++); + if (i == 4) { + for (i = 0; i <4; i++) { + a4[i] = b64_lookup(a4[i]); + } + + a4_to_a3(a3,a4); + + for (i = 0; i < 3; i++) { + *out++ = a3[i]; + } + + i = 0; + } + } + + if (i) { + for (j = i; j < 4; j++) { + a4[j] = '\0'; + } + + for (j = 0; j < 4; j++) { + a4[j] = b64_lookup(a4[j]); + } + + a4_to_a3(a3,a4); + + for (j = 0; j < i - 1; j++) { + *out++ = a3[j]; + } + } + + return (out == (out_begin + decoded_length)); + } + + static int DecodedLength(const char *in, size_t in_length) { + int numEq = 0; + + const char *in_end = in + in_length; + while (*--in_end == '=') ++numEq; + + return ((6 * in_length) / 8) - numEq; + } + + static int DecodedLength(const std::string &in) { + int numEq = 0; + int n = in.size(); + + for (std::string::const_reverse_iterator it = in.rbegin(); *it == '='; ++it) { + ++numEq; + } + + return ((6 * n) / 8) - numEq; + } + + inline static int EncodedLength(size_t length) { + return (length + 2 - ((length + 2) % 3)) / 3 * 4; + } + + inline static int EncodedLength(const std::string &in) { + return EncodedLength(in.length()); + } + + inline static void StripPadding(std::string *in) { + while (!in->empty() && *(in->rbegin()) == '=') in->resize(in->size() - 1); + } + + private: + static inline void a3_to_a4(unsigned char * a4, unsigned char * a3) { + a4[0] = (a3[0] & 0xfc) >> 2; + a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); + a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); + a4[3] = (a3[2] & 0x3f); + } + + static inline void a4_to_a3(unsigned char * a3, unsigned char * a4) { + a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4); + a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2); + a3[2] = ((a4[2] & 0x3) << 6) + a4[3]; + } + + static inline unsigned char b64_lookup(unsigned char c) { + if(c >='A' && c <='Z') return c - 'A'; + if(c >='a' && c <='z') return c - 71; + if(c >='0' && c <='9') return c + 4; + if(c == '+') return 62; + if(c == '/') return 63; + return 255; + } +}; + + + +#endif // HL_BASE64_H \ No newline at end of file diff --git a/src/engine/helper/HL_ByteBuffer.h b/src/engine/helper/HL_ByteBuffer.h new file mode 100644 index 00000000..94711715 --- /dev/null +++ b/src/engine/helper/HL_ByteBuffer.h @@ -0,0 +1,18 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __HL_BYTEBUFFER_H +#define __HL_BYTEBUFFER_H + +#include "ice/ICEByteBuffer.h" + +typedef ice::ByteBuffer ByteBuffer; +typedef ice::PByteBuffer PByteBuffer; +typedef ice::BitReader BitReader; +typedef ice::BitWriter BitWriter; +typedef ice::BufferReader BufferReader; +typedef ice::BufferWriter BufferWriter; + +#endif diff --git a/src/engine/helper/HL_Calculator.cpp b/src/engine/helper/HL_Calculator.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/engine/helper/HL_Calculator.h b/src/engine/helper/HL_Calculator.h new file mode 100644 index 00000000..5bdb146d --- /dev/null +++ b/src/engine/helper/HL_Calculator.h @@ -0,0 +1,625 @@ +#ifndef __HL_CALCULATOR_H +#define __HL_CALCULATOR_H + +#include +#include + +#include "helper/HL_VariantMap.h" +#include "helper/HL_String.h" +#include "helper/HL_InternetAddress.h" + +namespace Calc +{ + class Parser; + namespace Ast + { + enum class Type + { + None, + And, + Or, + Equal, + NotEqual, + Less, + LessOrEqual, + Greater, + GreatorOrEqual, + Add, + Sub, + Mul, + Div, + Number, + String, + Var + }; + + class Item; + typedef Item* PItem; + + class Item + { + friend class Calc::Parser; + public: + bool isVariable() const + { + return mType == Type::Var; + } + bool isFixed() const + { + return mType == Type::Number || mType == Type::String; + } + + bool isOperation() const + { + return mType >= Type::And && mType <= Type::Div; + } + + bool hasBrackets() const + { + return mHasBrackets; + } + + int getOperatorLevel() const + { + switch (mType) + { + case Type::Or: + return -2; + + case Type::And: + return -1; + + case Type::Equal: + case Type::NotEqual: + return 0; + + case Type::Less: + case Type::LessOrEqual: + case Type::Greater: + case Type::GreatorOrEqual: + return 1; + + case Type::Add: + case Type::Sub: + return 2; + + case Type::Mul: + case Type::Div: + return 3; + + default: + return 4; + } + assert(0); + } + + Type getType() const + { + return mType; + } + + std::string getName() const + { + return mName; + } + + Variant& value() + { + return mValue; + } + + std::vector& children() + { + return mChildren; + } + + typedef std::map NameMap; + + std::ostream& print(std::ostream& oss, const NameMap& nm) + { + oss << " ( "; + + if (isOperation()) + mChildren.front()->print(oss, nm); + + oss << " "; + switch (mType) + { + case Type::Number: oss << mValue.asStdString(); break; + case Type::String: oss << '"' << mValue.asStdString() << '"'; break; + case Type::Var: { NameMap::const_iterator iter = nm.find(mName); oss << ((iter != nm.end()) ? iter->second : mName);} break; + case Type::Add: oss << "+"; break; + case Type::Mul: oss << "*"; break; + case Type::Div: oss << "/"; break; + case Type::Sub: oss << "-"; break; + case Type::Equal: oss << "=="; break; + case Type::NotEqual: oss << "!="; break; + case Type::Less: oss << "<"; break; + case Type::LessOrEqual: oss << "<="; break; + case Type::Greater: oss << ">"; break; + case Type::GreatorOrEqual: oss << ">="; break; + case Type::Or: oss << "or"; break; + case Type::And: oss << "and"; break; + default: + throw std::runtime_error("operator expected"); + } + oss << " "; + if (isOperation() && mChildren.size() == 2 && mChildren.back()) + mChildren.back()->print(oss, nm); + + oss << " ) "; + + return oss; + } + + typedef std::map ValueMap; + + Variant eval(const ValueMap& vm) + { + Variant result, left, right; + if (isOperation()) + { + left = mChildren.front()->eval(vm); + right = mChildren.back()->eval(vm); + } + + switch (mType) + { + case Type::Number: + case Type::String: result = mValue; break; + + case Type::Var: { auto iter = vm.find(mName); if (iter != vm.end()) return iter->second; else throw std::runtime_error("Variable " + mName + " did not find."); } + break; + + case Type::Add: result = left + right; break; + case Type::Mul: result = left * right; break; + case Type::Div: result = left / right; break; + case Type::Sub: result = left - right; break; + case Type::Equal: result = left == right; break; + case Type::NotEqual: result = left != right; break; + case Type::Less: result = left < right; break; + case Type::LessOrEqual: result = left <= right; break; + case Type::Greater: result = left > right; break; + case Type::GreatorOrEqual: result = left >= right; break; + case Type::Or: result = left.asBool() || right.asBool(); break; + case Type::And: result = left.asBool() && right.asBool(); break; + default: + assert(0); + } + return result; + } + + ~Item() + { + for (auto node: mChildren) + delete node; + mChildren.clear(); + } + + private: + Type mType = Type::None; + std::string mName; + Variant mValue; + std::vector mChildren; + bool mHasBrackets = false; + }; + } + + static bool ishex(int c) + { + if (isdigit(c)) + return true; + return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); + } + + class Parser + { + private: + enum class LexemType + { + None, + Hex, + Dec, + Float, + Str, + Oper, + Var, + OpenBracket, + CloseBracket + }; + + struct Lexem + { + LexemType mType = LexemType::None; + std::string mValue; + + operator bool () const + { + return mType != LexemType::None; + } + + std::string toString() const + { + return std::to_string((int)mType) + " : " + mValue; + } + }; + Lexem mCurrentLexem; + + Lexem processNewLexem(int c) + { + Lexem result; + + if (c == '(') + mCurrentLexem.mType = LexemType::OpenBracket; + else + if (c == ')') + mCurrentLexem.mType = LexemType::CloseBracket; + else + if (isdigit(c)) + mCurrentLexem.mType = LexemType::Dec; + else + if (isalpha(c)) + mCurrentLexem.mType = LexemType::Var; + else + if (c == '+' || c == '-' || c == '/' || c == '*' || c == '=' || c == '<' || c == '>' || c == '&' || c == '|') + mCurrentLexem.mType = LexemType::Oper; + else + if (c == '"') + mCurrentLexem.mType = LexemType::Str; + else + return Lexem(); + + mCurrentLexem.mValue.push_back(c); + + // Can we return result here already ? + if (mCurrentLexem.mType == LexemType::OpenBracket || mCurrentLexem.mType == LexemType::CloseBracket) + { + // Lexem finished + result = mCurrentLexem; + mCurrentLexem = Lexem(); + return result; + } + + if (mCurrentLexem.mType == LexemType::Oper) + { + if (mCurrentLexem.mValue == "+" || + mCurrentLexem.mValue == "-" || + mCurrentLexem.mValue == "*" || + mCurrentLexem.mValue == "/" || + mCurrentLexem.mValue == ">=" || + mCurrentLexem.mValue == "<=" || + mCurrentLexem.mValue == "==" || + mCurrentLexem.mValue == "||" || + mCurrentLexem.mValue == "&&") + { + // Lexem finished + result = mCurrentLexem; + mCurrentLexem = Lexem(); + return result; + } + } + return Lexem(); + } + + void checkNumericLexem() + { + if (mCurrentLexem.mType != LexemType::Dec) + return; + + // Check if there is ".:" characters + if (mCurrentLexem.mValue.find('.') != std::string::npos) + { + // Dot is here - is it float + bool isFloat = false; + StringHelper::toFloat(mCurrentLexem.mValue, 0.0f, &isFloat); + if (isFloat) + mCurrentLexem.mType = LexemType::Float; + else + { + // Maybe it is IP4/6 address ? + InternetAddress addr(mCurrentLexem.mValue, 8000); + if (!addr.isEmpty()) + { + mCurrentLexem.mValue = "\"" + mCurrentLexem.mValue + "\""; + mCurrentLexem.mType = LexemType::Str; + } + } + } + } + + Lexem getLexem(std::istream& input) + { + Lexem result; + + // Iterate while characters avaialbe from input stream & lexem is not finished + bool putback = false; + int c = input.get(); + while (!input.eof() && c && result.mType == LexemType::None) + { + switch (mCurrentLexem.mType) + { + case LexemType::None: + result = processNewLexem(c); + break; + + case LexemType::Hex: + if (!ishex(c)) + { + // Finish Hex lexem + result = mCurrentLexem; + putback = true; + } + else + mCurrentLexem.mValue.push_back(c); + break; + + case LexemType::Dec: + if (c == 'x' && mCurrentLexem.mValue == "0") + mCurrentLexem.mType = LexemType::Hex; + else + if (isdigit(c) || c == '.') + { + mCurrentLexem.mValue.push_back(c); + } + else + { + checkNumericLexem(); + result = mCurrentLexem; + putback = true; + } + break; + + case LexemType::Oper: + // It must be one of two-characters operations + if (c == '<' || c == '>' || c == '=' || c == '&' || c == '|') + { + mCurrentLexem.mValue.push_back(c); + result = mCurrentLexem; + mCurrentLexem = Lexem(); + } + else + { + result = mCurrentLexem; + putback = true; + } + break; + + case LexemType::Var: + if (isdigit(c) || isalpha(c) || c == '.' || c == '_') + { + mCurrentLexem.mValue.push_back(c); + } + else + { + result = mCurrentLexem; + putback = true; + } + break; + + case LexemType::Str: + mCurrentLexem.mValue.push_back(c); + if (c == '"') + { + result = mCurrentLexem; + // String lexem is finished + mCurrentLexem.mType = LexemType::None; + putback = false; + } + break; + + default: + assert(0); + } + + if (putback) + input.putback(c); + else + if (!result) + c = input.get(); + } + + checkNumericLexem(); + + // Recover partially processed lexem - maybe we finish processing at all but there is dec / float / string / variable + if (mCurrentLexem.mType != LexemType::None && result.mType == LexemType::None) + result = mCurrentLexem; + + // Reset current lexem + mCurrentLexem = Lexem(); + + return result; + } + + // Make AST node from lexem + Ast::PItem makeAst(const Lexem& l) + { + Ast::PItem result(new Ast::Item()); + + switch (l.mType) + { + case LexemType::Oper: + if (l.mValue == "-") + result->mType = Ast::Type::Sub; + else + if (l.mValue == "+") + result->mType = Ast::Type::Add; + else + if (l.mValue == "*") + result->mType = Ast::Type::Mul; + else + if (l.mValue == "/") + result->mType = Ast::Type::Div; + else + if (l.mValue == "<") + result->mType = Ast::Type::Less; + else + if (l.mValue == "<=") + result->mType = Ast::Type::LessOrEqual; + else + if (l.mValue == ">") + result->mType = Ast::Type::Greater; + else + if (l.mValue == ">=") + result->mType = Ast::Type::GreatorOrEqual; + else + if (l.mValue == "==") + result->mType = Ast::Type::Equal; + else + if (l.mValue == "!=") + result->mType = Ast::Type::NotEqual; + else + if (l.mValue == "&&") + result->mType = Ast::Type::And; + else + if (l.mValue == "||") + result->mType = Ast::Type::Or; + break; + + case LexemType::Var: + result->mType = Ast::Type::Var; + result->mName = l.mValue; + break; + + case LexemType::Dec: + result->mType = Ast::Type::Number; + result->mValue = atoi(l.mValue.c_str()); + break; + + case LexemType::Hex: + result->mType = Ast::Type::Number; + result->mValue = StringHelper::fromHex2Int(l.mValue); + break; + + case LexemType::Float: + result->mType = Ast::Type::Number; + result->mValue = (float)atof(l.mValue.c_str()); + break; + + case LexemType::Str: + result->mType = Ast::Type::String; + result->mValue = l.mValue.substr(1, l.mValue.size() - 2); + break; + + default: + throw std::runtime_error("Unexpected lexem."); + } + + return result; + } + + Lexem mLexem; + public: + Ast::PItem parseExpression(std::istream& input) + { + Ast::PItem operationNode(nullptr), leftNode(nullptr), rightNode(nullptr), + currentOperation(nullptr); + + // While we have lexem + while (mLexem = getLexem(input)) + { + std::cout << "Returned lexem: " << mLexem.toString() << std::endl; + + if (!leftNode) + { + // It must be first operand! + switch (mLexem.mType) + { + case LexemType::OpenBracket: + leftNode = parseExpression(input); + leftNode->mHasBrackets = true; + break; + + case LexemType::CloseBracket: + throw std::runtime_error("Expected +/-/constant/variable here."); + + case LexemType::Dec: + case LexemType::Hex: + case LexemType::Str: + case LexemType::Var: + case LexemType::Float: + leftNode = makeAst(mLexem); + break; + + default: + throw std::runtime_error("Open bracket or constant / number / string / variable expected."); + } + } + else + if (!operationNode) + { + // Well, there is left node already + // See operation here + switch (mLexem.mType) + { + case LexemType::Oper: + operationNode = makeAst(mLexem); + break; + + case LexemType::None: + // Finish the tree building + break; + + case LexemType::CloseBracket: + // Finish the tree building in this level + if (leftNode) + return leftNode; + break; + + default: + throw std::runtime_error("Expected operation."); + } + + // Parse rest of expression + rightNode = parseExpression(input); + + // If right part of expression is operation - make left side child of right part - to allow calculation in right order + if (operationNode) + { + if (rightNode->isOperation() && rightNode->getOperatorLevel() <= operationNode->getOperatorLevel() && !rightNode->hasBrackets()) + { + // Get left child of right expression - make it our right child + operationNode->children().push_back(leftNode); + operationNode->children().push_back(rightNode->children().front()); + rightNode->children().front() = operationNode; + currentOperation = rightNode; + } + else + { + operationNode->children().push_back(leftNode); + operationNode->children().push_back(rightNode); + currentOperation = operationNode; + } + } + if (mLexem.mType == LexemType::CloseBracket) + break; // Exit from loop + } + } + return currentOperation ? currentOperation : leftNode; + } + + public: + Ast::PItem parse(std::istream& input) + { + return nullptr; + } + + void testLexemParser(const std::string& test) + { + std::istringstream iss(test); + + for (Lexem l = getLexem(iss); l.mType != LexemType::None; l = getLexem(iss)) + { + std::cout << "Lexem type: " << (int)l.mType << ", value: " << l.mValue << std::endl; + } + } + }; + + class Worker + { + public: + Variant eval(Ast::PItem ast); + }; +} + + +#endif diff --git a/src/engine/helper/HL_CsvReader.cpp b/src/engine/helper/HL_CsvReader.cpp new file mode 100644 index 00000000..30866500 --- /dev/null +++ b/src/engine/helper/HL_CsvReader.cpp @@ -0,0 +1,26 @@ +#include "HL_CsvReader.h" +#include "HL_String.h" + +// --------- CsvFile ---------------- +CsvReader::CsvReader(std::istream& stream) + :mInputStream(stream) +{} + +CsvReader::~CsvReader() +{} + +std::istream& CsvReader::stream() const +{ + return mInputStream; +} + +bool CsvReader::readLine(std::vector& cells) +{ + cells.clear(); + std::string line; + if (!std::getline(mInputStream, line)) + return false; + + StringHelper::split(line, cells, ",;"); + return true; +} diff --git a/src/engine/helper/HL_CsvReader.h b/src/engine/helper/HL_CsvReader.h new file mode 100644 index 00000000..fd6f3738 --- /dev/null +++ b/src/engine/helper/HL_CsvReader.h @@ -0,0 +1,23 @@ +#ifndef __HL_CSVREADER_H +#define __HL_CSVREADER_H + +#include +#include +#include + +class CsvReader +{ +public: + CsvReader(std::istream& stream); + ~CsvReader(); + + void setStream(std::istream& input); + std::istream& stream() const; + + bool readLine(std::vector& cells); + +protected: + std::istream& mInputStream; +}; + +#endif diff --git a/src/engine/helper/HL_Epoll.cpp b/src/engine/helper/HL_Epoll.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/engine/helper/HL_Epoll.h b/src/engine/helper/HL_Epoll.h new file mode 100644 index 00000000..e69de29b diff --git a/src/engine/helper/HL_Exception.h b/src/engine/helper/HL_Exception.h new file mode 100644 index 00000000..a921eaf1 --- /dev/null +++ b/src/engine/helper/HL_Exception.h @@ -0,0 +1,85 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __EXCEPTION_H +#define __EXCEPTION_H + +#include +#include +#include +#include + +enum +{ + ERR_MEDIA_SOCKET_FAILED = 1, // Failed to create media socket + ERR_CANNOT_FIND_SESSION = 2, // Cannot find session + ERR_NO_CREDENTIALS = 3, // No credentials to configure instance + ERR_BAD_VARIANT_TYPE = 4, // Bad variant type conversion + ERR_RINSTANCE = 5, + ERR_SRTP = 6, // libsrtp error + ERR_WEBRTC = 7, // webrtc error + ERR_NOMEM = 8, // no more memory + ERR_WMME_FAILED = 9, // WMME error + ERR_QPC = 10, // QueryPerformanceCounter failed + ERR_BAD_PARAM = 11, // Bad parameter + ERR_NET_FAILED = 12, // Call to OS network subsystem failed + ERR_NOT_IMPLEMENTED = 13, // Not implemented in this build + ERR_MIXER_OVERFLOW = 14, // No more available channels in audio mixer + ERR_WAVFILE_FAILED = 15, // Error with .wav file + ERR_DSOUND = 16, // DSound error + ERR_COREAUDIO = 17, // CoreAudio error + ERR_CREATEWINDOW = 18, // CreateWindow failed + ERR_REGISTERNOTIFICATION = 19, // RegisterDeviceNotification failed + ERR_PCAP = 20, // Smth bad with libpcap + ERR_CACHE_FAILED = 21, // Failed to open cache directory + ERR_FILENOTOPEN = 22, // Cannot open the file + ERR_OPENSLES = 23 // OpenSL ES failed. Subcode has actual error code. +}; + +class Exception: public std::exception +{ +public: + Exception(int code, int subcode = 0) + :mCode(code), mSubcode(subcode) + { + sprintf(mMessage, "%d-%d", code, subcode); + } + + Exception(int code, const char* message) + { + if (message) + strncpy(mMessage, message, (sizeof mMessage) - 1 ); + } + + Exception(const Exception& src) + :mCode(src.mCode), mSubcode(src.mSubcode) + { + memcpy(mMessage, src.mMessage, sizeof mMessage); + } + + ~Exception() + { } + + int code() const + { + return mCode; + } + + int subcode() const + { + return mSubcode; + } + + const char* what() const noexcept + { + return mMessage; + } + +protected: + int mCode, mSubcode; + char mMessage[256]; +}; + +#endif diff --git a/src/engine/helper/HL_HepSupport.cpp b/src/engine/helper/HL_HepSupport.cpp new file mode 100644 index 00000000..f310f962 --- /dev/null +++ b/src/engine/helper/HL_HepSupport.cpp @@ -0,0 +1,220 @@ +#include "HL_HepSupport.h" + +using namespace HEP; + +static const uint32_t HEPID1 = 0x011002; +static const uint32_t HEPID2 = 0x021002; +static const uint32_t HEPID3 = 0x48455033; + + +bool Packet::parseV3(const ByteBuffer& packet) +{ + if (packet.size() < 30) + return false; + + BufferReader r(packet); + char signature[4]; + r.readBuffer(signature, 4); + + if (signature[0] != 'H' || signature[1] != 'E' || signature[2] != 'P' || signature[3] != '3') + return false; + + // Total length + int l = r.readUShort(); + l -= 6; + + InternetAddress sourceAddr4, destAddr4, sourceAddr6, destAddr6; + uint16_t sourcePort = 0, destPort = 0; + while (r.count() < packet.size()) + { + mVendorId = (VendorId)r.readUShort(); + ChunkType chunkType = (ChunkType)r.readUShort(); + int chunkLength = r.readUShort(); + + switch (chunkType) + { + case ChunkType::IPProtocolFamily: + mIpProtocolFamily = r.readUChar(); + break; + + case ChunkType::IPProtocolID: + mIpProtocolId = r.readUChar(); + break; + + case ChunkType::IP4SourceAddress: + sourceAddr4 = r.readIp(AF_INET); + break; + + case ChunkType::IP4DestinationAddress: + destAddr4 = r.readIp(AF_INET); + break; + + case ChunkType::IP6SourceAddress: + sourceAddr6 = r.readIp(AF_INET); + break; + + case ChunkType::IP6DestinationAddress: + destAddr6 = r.readIp(AF_INET6); + break; + + case ChunkType::SourcePort: + sourcePort = r.readUShort(); + break; + + case ChunkType::DestinationPort: + destPort = r.readUShort(); + break; + + case ChunkType::Timestamp: + mTimestamp.tv_sec = r.readUInt(); + break; + + case ChunkType::TimestampMicro: + mTimestamp.tv_usec = r.readUInt() * 1000; + break; + + case ChunkType::ProtocolType: + mProtocolType = (ProtocolId)r.readUChar(); + break; + + case ChunkType::CaptureAgentID: + mCaptureAgentId = r.readUInt(); + break; + + case ChunkType::KeepAliveTimer: + mKeepAliveTimer = r.readUShort(); + break; + + case ChunkType::AuthenticationKey: + mAuthenticateKey.resize(chunkLength - 6); + r.readBuffer(mAuthenticateKey.mutableData(), mAuthenticateKey.size()); + break; + + case ChunkType::PacketPayload: + r.readBuffer(mBody, chunkLength - 6); + break; + + default: + r.readBuffer(nullptr, chunkLength - 6); + } + } + + if (!sourceAddr4.isEmpty()) + mSourceAddress = sourceAddr4; + else + if (!sourceAddr6.isEmpty()) + mSourceAddress = sourceAddr6; + + if (!mSourceAddress.isEmpty()) + mSourceAddress.setPort(sourcePort); + + if (!destAddr4.isEmpty()) + mDestinationAddress = destAddr4; + else + if (!destAddr6.isEmpty()) + mDestinationAddress = destAddr6; + + if (!mDestinationAddress.isEmpty()) + mDestinationAddress.setPort(destPort); + + return true; +} + +bool Packet::parseV2(const ByteBuffer &packet) +{ + if (packet.size() < 31) + return false; + + if (packet[0] != 0x02) + return false; + + BufferReader r(packet); + r.readBuffer(nullptr, 4); + + uint16_t sourcePort = r.readUShort(); + uint16_t dstPort = r.readUShort(); + mSourceAddress = r.readIp(AF_INET); + mSourceAddress.setPort(sourcePort); + mDestinationAddress = r.readIp(AF_INET); + mDestinationAddress.setPort(dstPort); + mTimestamp.tv_sec = r.readUInt(); + mTimestamp.tv_usec = r.readUInt() * 1000; + mCaptureAgentId = r.readUShort(); + r.readBuffer(nullptr, 2); + mBody.clear(); + r.readBuffer(mBody, 65536 - 28); + return true; +} + +#define WRITE_CHUNK_UCHAR(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(1); w.writeUChar((uint8_t)V);} +#define WRITE_CHUNK_USHORT(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(2); w.writeUShort((uint16_t)V);} +#define WRITE_CHUNK_UINT(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(4); w.writeUInt((uint32_t)V);} +#define WRITE_CHUNK_IP4(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(4); w.writeIp(V);} +#define WRITE_CHUNK_IP6(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(8); w.writeIp(V);} +#define WRITE_CHUNK_BUFFER(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(8); w.writeBuffer(V.data(), V.size());} + +ByteBuffer Packet::buildV3() +{ + ByteBuffer r; r.resize(mBody.size() + 512); + BufferWriter w(r); + + // Signature + w.writeBuffer("HEP3", 4); + + // Reserve place for total length + w.writeUShort(0); + + WRITE_CHUNK_UCHAR(ChunkType::IPProtocolFamily, mIpProtocolFamily); + WRITE_CHUNK_UCHAR(ChunkType::IPProtocolID, mIpProtocolId); + + // Source address + if (!mSourceAddress.isEmpty()) + { + if (mSourceAddress.isV4()) + WRITE_CHUNK_IP4(ChunkType::IP4SourceAddress, mSourceAddress) + else + if (mSourceAddress.isV6()) + WRITE_CHUNK_IP6(ChunkType::IP6SourceAddress, mSourceAddress); + + WRITE_CHUNK_USHORT(ChunkType::SourcePort, mSourceAddress.port()); + } + + // Destination address + if (!mDestinationAddress.isEmpty()) + { + if (mDestinationAddress.isV4()) + WRITE_CHUNK_IP4(ChunkType::IP4DestinationAddress, mDestinationAddress) + else + if (mDestinationAddress.isV6()) + WRITE_CHUNK_IP6(ChunkType::IP6DestinationAddress, mDestinationAddress); + + WRITE_CHUNK_USHORT(ChunkType::DestinationPort, mDestinationAddress.port()); + } + + // Timestamp + WRITE_CHUNK_UINT(ChunkType::Timestamp, mTimestamp.tv_sec); + + // TimestampMicro + WRITE_CHUNK_UINT(ChunkType::TimestampMicro, mTimestamp.tv_usec / 1000); + + // Protocol type + WRITE_CHUNK_UINT(ChunkType::ProtocolType, mProtocolType); + + // Capture agent ID + WRITE_CHUNK_UINT(ChunkType::CaptureAgentID, mCaptureAgentId); + + // Keep alive timer value + WRITE_CHUNK_USHORT(ChunkType::KeepAliveTimer, mKeepAliveTimer); + + // Authentication key + WRITE_CHUNK_BUFFER(ChunkType::AuthenticationKey, mAuthenticateKey); + + // Payload + WRITE_CHUNK_BUFFER(ChunkType::PacketPayload, mBody); + + r.resize(w.offset()); + + w.rewind(); w.skip(4); w.writeUShort((uint16_t)r.size()); + + return r; +} diff --git a/src/engine/helper/HL_HepSupport.h b/src/engine/helper/HL_HepSupport.h new file mode 100644 index 00000000..3b1fb8f5 --- /dev/null +++ b/src/engine/helper/HL_HepSupport.h @@ -0,0 +1,84 @@ +#ifndef __HELPER_HEP_SUPPORT_H +#define __HELPER_HEP_SUPPORT_H + +#include "HL_ByteBuffer.h" +#include "HL_InternetAddress.h" + +namespace HEP +{ + enum class ChunkType + { + None = 0, + IPProtocolFamily, + IPProtocolID, + IP4SourceAddress, + IP4DestinationAddress, + IP6SourceAddress, + IP6DestinationAddress, + SourcePort, + DestinationPort, + Timestamp, + TimestampMicro, + ProtocolType, // Maps to Protocol Types below + CaptureAgentID, + KeepAliveTimer, + AuthenticationKey, + PacketPayload, + CompressedPayload, + InternalC + }; + + enum class VendorId + { + None, + FreeSwitch, + Kamailio, + OpenSIPS, + Asterisk, + Homer, + SipXecs + }; + + enum class ProtocolId + { + Reserved = 0, + SIP, + XMPP, + SDP, + RTP, + RTCP, + MGCP, + MEGACO, + M2UA, + M3UA, + IAX, + H322, + H321 + }; + + struct Packet + { + bool parseV3(const ByteBuffer& packet); + bool parseV2(const ByteBuffer& packet); + ByteBuffer buildV3(); + + uint8_t + mIpProtocolFamily, + mIpProtocolId; + + InternetAddress + mSourceAddress, + mDestinationAddress; + + timeval mTimestamp; + ProtocolId mProtocolType; + uint16_t mCaptureAgentId; + uint16_t mKeepAliveTimer; + ByteBuffer mAuthenticateKey; + ByteBuffer mBody; + VendorId mVendorId; + }; + +} + +#endif diff --git a/src/engine/helper/HL_InternetAddress.h b/src/engine/helper/HL_InternetAddress.h new file mode 100644 index 00000000..ac9e5ada --- /dev/null +++ b/src/engine/helper/HL_InternetAddress.h @@ -0,0 +1,12 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __HL_INTERNETADDRESS_H +#define __HL_INTERNETADDRESS_H + +#include "ice/ICEAddress.h" +typedef ice::NetworkAddress InternetAddress; + +#endif diff --git a/src/engine/helper/HL_IuUP.cpp b/src/engine/helper/HL_IuUP.cpp new file mode 100644 index 00000000..65e283c1 --- /dev/null +++ b/src/engine/helper/HL_IuUP.cpp @@ -0,0 +1,1220 @@ +#include "HL_IuUP.h" +#include "HL_ByteBuffer.h" + +bool IuUP::TwoBytePseudoheader = false; + +bool IuUP::parse(const uint8_t *packet, int size, IuUP::Frame &result) +{ + // Wrap incoming packet in byte buffer + BitReader reader(packet, size); + + // Read frame + result.mPduType = (PduType)reader.readBits(4); + + // For now we are interested only in Data with CRC - PDU type 0 (zero) + if (result.mPduType != PduType::DataWithCrc) + return false; + + result.mFrameNumber = reader.readBits(4); + + result.mFqc = reader.readBits(2); + result.mRfci = reader.readBits(6); + result.mHeaderCrc = reader.readBits(6); + result.mPayloadCrc = reader.readBits(10); + result.mPayload = packet + 4; + result.mPayloadSize = size - 4; + + if (result.mFqc /*|| result.mRfci != 1*/) + return false; + + return true; +} + + +uint16_t update_crc6_by_bytes(uint16_t crc6, uint8_t byte1, uint8_t byte2); +uint16_t update_crc10_by_bytes(uint16_t crc10, const uint8_t *data_blk_ptr, int data_blk_size); + +bool IuUP::parse2(const uint8_t* packet, int size, Frame& result) +{ + if (TwoBytePseudoheader) + { + packet += 2; + size -= 2; + } + + BitReader reader(packet, size); + result.mPduType = (PduType)reader.readBits(4); + + // Ignore control commands for now + if (result.mPduType != PduType::DataNoCrc && result.mPduType != PduType::DataWithCrc) + return false; + + result.mFrameNumber = reader.readBits(4); + result.mFqc = reader.readBits(2); + result.mRfci = reader.readBits(6); + result.mHeaderCrc = reader.readBits(6); + + // Check for header type + result.mHeaderCrcOk = update_crc6_by_bytes(result.mHeaderCrc, packet[0], packet[1]) == 0; + + if (result.mPduType == PduType::DataWithCrc) + { + result.mPayloadCrc = reader.readBits(10); + result.mPayload = packet + 4; + result.mPayloadSize = size - 4; + + uint16_t crc = update_crc10_by_bytes(0, result.mPayload, result.mPayloadSize); + uint16_t secondWord = ntohs(((uint16_t*)packet)[1]); + secondWord &= 0x3FF; + uint8_t bytes[2]; + bytes[0] = secondWord >> 2; + bytes[1] = (secondWord << 6) & 0xFF; + crc = update_crc10_by_bytes(crc, bytes, 2); + result.mPayloadCrcOk = crc == 0; + } + else + { + result.mPayloadCrc = 0; + result.mPayload = packet + 3; + result.mPayloadSize = size - 3; + } + + // Skip all frames except good (mFqc == 0) + if (result.mFqc /*|| result.mRfci != 1*/) + return false; + + return true; +} + + +static const unsigned char crc6_table[] = +{ + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26,0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e, + 0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36,0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e, + 0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e, + 0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16,0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e, + 0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01, + 0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11, + 0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21, + 0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, + 0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b,0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23, + 0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b,0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33, + 0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03, + 0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b,0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13, + 0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04,0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c, + 0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c, + 0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24,0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c, + 0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34,0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c, + 0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a,0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12, + 0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02, + 0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a,0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32, + 0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22, + 0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35,0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d, + 0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25,0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d, + 0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d, + 0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05,0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d, + 0x3b,0x3a,0x39,0x38,0x3f,0x3e,0x3d,0x3c,0x33,0x32,0x31,0x30,0x37,0x36,0x35,0x34, + 0x2b,0x2a,0x29,0x28,0x2f,0x2e,0x2d,0x2c,0x23,0x22,0x21,0x20,0x27,0x26,0x25,0x24, + 0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,0x13,0x12,0x11,0x10,0x17,0x16,0x15,0x14, + 0x0b,0x0a,0x09,0x08,0x0f,0x0e,0x0d,0x0c,0x03,0x02,0x01,0x00,0x07,0x06,0x05,0x04, + 0x14,0x15,0x16,0x17,0x10,0x11,0x12,0x13,0x1c,0x1d,0x1e,0x1f,0x18,0x19,0x1a,0x1b, + 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0c,0x0d,0x0e,0x0f,0x08,0x09,0x0a,0x0b, + 0x34,0x35,0x36,0x37,0x30,0x31,0x32,0x33,0x3c,0x3d,0x3e,0x3f,0x38,0x39,0x3a,0x3b, + 0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2c,0x2d,0x2e,0x2f,0x28,0x29,0x2a,0x2b, + 0x0a,0x0b,0x08,0x09,0x0e,0x0f,0x0c,0x0d,0x02,0x03,0x00,0x01,0x06,0x07,0x04,0x05, + 0x1a,0x1b,0x18,0x19,0x1e,0x1f,0x1c,0x1d,0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15, + 0x2a,0x2b,0x28,0x29,0x2e,0x2f,0x2c,0x2d,0x22,0x23,0x20,0x21,0x26,0x27,0x24,0x25, + 0x3a,0x3b,0x38,0x39,0x3e,0x3f,0x3c,0x3d,0x32,0x33,0x30,0x31,0x36,0x37,0x34,0x35, + 0x25,0x24,0x27,0x26,0x21,0x20,0x23,0x22,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a, + 0x35,0x34,0x37,0x36,0x31,0x30,0x33,0x32,0x3d,0x3c,0x3f,0x3e,0x39,0x38,0x3b,0x3a, + 0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a, + 0x15,0x14,0x17,0x16,0x11,0x10,0x13,0x12,0x1d,0x1c,0x1f,0x1e,0x19,0x18,0x1b,0x1a, + 0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b,0x38,0x39, + 0x26,0x27,0x24,0x25,0x22,0x23,0x20,0x21,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b,0x28,0x29, + 0x16,0x17,0x14,0x15,0x12,0x13,0x10,0x11,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b,0x18,0x19, + 0x06,0x07,0x04,0x05,0x02,0x03,0x00,0x01,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b,0x08,0x09, + 0x19,0x18,0x1b,0x1a,0x1d,0x1c,0x1f,0x1e,0x11,0x10,0x13,0x12,0x15,0x14,0x17,0x16, + 0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,0x01,0x00,0x03,0x02,0x05,0x04,0x07,0x06, + 0x39,0x38,0x3b,0x3a,0x3d,0x3c,0x3f,0x3e,0x31,0x30,0x33,0x32,0x35,0x34,0x37,0x36, + 0x29,0x28,0x2b,0x2a,0x2d,0x2c,0x2f,0x2e,0x21,0x20,0x23,0x22,0x25,0x24,0x27,0x26, + 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, + 0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18, + 0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28, + 0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, +}; + + +uint16_t update_crc6_by_bytes(uint16_t crc6, uint8_t byte1, uint8_t byte2) +{ + int bit; + uint32_t remainder = ( byte1<<8 | byte2 ) << 6; + uint32_t polynomial = 0x6F << 15; + + for (bit = 15; + bit >= 0; + --bit) + { + if (remainder & (0x40 << bit)) + { + remainder ^= polynomial; + } + polynomial >>= 1; + } + + return (uint16_t)(remainder ^ crc6); +} + +uint16_t crc6_compute(const uint8_t *data_blk_ptr, int data_blk_size) +{ + uint16_t h; + int byteIndex; + + h = 0; + byteIndex = 0; + + if (data_blk_size == 0) + { + return 0; + } + + do + { + h = (h << 8) | data_blk_ptr[byteIndex]; + + h = crc6_table[h]; + byteIndex++; + } + while (byteIndex < data_blk_size); + + return h; +} + +/* + * Charles Michael Heard's CRC-10 code, from + * + * http://web.archive.org/web/20061005231950/http://cell-relay.indiana.edu/cell-relay/publications/software/CRC/crc10.html + * + * with the CRC table initialized with values computed by + * his "gen_byte_crc10_table()" routine, rather than by calling that + * routine at run time, and with various data type cleanups. + */ +static const uint16_t byte_crc10_table[256] = { + 0x0000, 0x0233, 0x0255, 0x0066, 0x0299, 0x00aa, 0x00cc, 0x02ff, + 0x0301, 0x0132, 0x0154, 0x0367, 0x0198, 0x03ab, 0x03cd, 0x01fe, + 0x0031, 0x0202, 0x0264, 0x0057, 0x02a8, 0x009b, 0x00fd, 0x02ce, + 0x0330, 0x0103, 0x0165, 0x0356, 0x01a9, 0x039a, 0x03fc, 0x01cf, + 0x0062, 0x0251, 0x0237, 0x0004, 0x02fb, 0x00c8, 0x00ae, 0x029d, + 0x0363, 0x0150, 0x0136, 0x0305, 0x01fa, 0x03c9, 0x03af, 0x019c, + 0x0053, 0x0260, 0x0206, 0x0035, 0x02ca, 0x00f9, 0x009f, 0x02ac, + 0x0352, 0x0161, 0x0107, 0x0334, 0x01cb, 0x03f8, 0x039e, 0x01ad, + 0x00c4, 0x02f7, 0x0291, 0x00a2, 0x025d, 0x006e, 0x0008, 0x023b, + 0x03c5, 0x01f6, 0x0190, 0x03a3, 0x015c, 0x036f, 0x0309, 0x013a, + 0x00f5, 0x02c6, 0x02a0, 0x0093, 0x026c, 0x005f, 0x0039, 0x020a, + 0x03f4, 0x01c7, 0x01a1, 0x0392, 0x016d, 0x035e, 0x0338, 0x010b, + 0x00a6, 0x0295, 0x02f3, 0x00c0, 0x023f, 0x000c, 0x006a, 0x0259, + 0x03a7, 0x0194, 0x01f2, 0x03c1, 0x013e, 0x030d, 0x036b, 0x0158, + 0x0097, 0x02a4, 0x02c2, 0x00f1, 0x020e, 0x003d, 0x005b, 0x0268, + 0x0396, 0x01a5, 0x01c3, 0x03f0, 0x010f, 0x033c, 0x035a, 0x0169, + 0x0188, 0x03bb, 0x03dd, 0x01ee, 0x0311, 0x0122, 0x0144, 0x0377, + 0x0289, 0x00ba, 0x00dc, 0x02ef, 0x0010, 0x0223, 0x0245, 0x0076, + 0x01b9, 0x038a, 0x03ec, 0x01df, 0x0320, 0x0113, 0x0175, 0x0346, + 0x02b8, 0x008b, 0x00ed, 0x02de, 0x0021, 0x0212, 0x0274, 0x0047, + 0x01ea, 0x03d9, 0x03bf, 0x018c, 0x0373, 0x0140, 0x0126, 0x0315, + 0x02eb, 0x00d8, 0x00be, 0x028d, 0x0072, 0x0241, 0x0227, 0x0014, + 0x01db, 0x03e8, 0x038e, 0x01bd, 0x0342, 0x0171, 0x0117, 0x0324, + 0x02da, 0x00e9, 0x008f, 0x02bc, 0x0043, 0x0270, 0x0216, 0x0025, + 0x014c, 0x037f, 0x0319, 0x012a, 0x03d5, 0x01e6, 0x0180, 0x03b3, + 0x024d, 0x007e, 0x0018, 0x022b, 0x00d4, 0x02e7, 0x0281, 0x00b2, + 0x017d, 0x034e, 0x0328, 0x011b, 0x03e4, 0x01d7, 0x01b1, 0x0382, + 0x027c, 0x004f, 0x0029, 0x021a, 0x00e5, 0x02d6, 0x02b0, 0x0083, + 0x012e, 0x031d, 0x037b, 0x0148, 0x03b7, 0x0184, 0x01e2, 0x03d1, + 0x022f, 0x001c, 0x007a, 0x0249, 0x00b6, 0x0285, 0x02e3, 0x00d0, + 0x011f, 0x032c, 0x034a, 0x0179, 0x0386, 0x01b5, 0x01d3, 0x03e0, + 0x021e, 0x002d, 0x004b, 0x0278, 0x0087, 0x02b4, 0x02d2, 0x00e1 +}; + +/* Update the data block's CRC-10 remainder one byte at a time */ +uint16_t update_crc10_by_bytes(uint16_t crc10_accum, const uint8_t *data_blk_ptr, int data_blk_size) +{ + register int i; + + for (i = 0; i < data_blk_size; i++) { + crc10_accum = ((crc10_accum << 8) & 0x3ff) + ^ byte_crc10_table[( crc10_accum >> 2) & 0xff] + ^ *data_blk_ptr++; + } + return crc10_accum; +} + diff --git a/src/engine/helper/HL_IuUP.h b/src/engine/helper/HL_IuUP.h new file mode 100644 index 00000000..022d7e7e --- /dev/null +++ b/src/engine/helper/HL_IuUP.h @@ -0,0 +1,39 @@ +#ifndef HL_IUUP_H +#define HL_IUUP_H + +#include + +class IuUP +{ +public: + enum class PduType + { + DataWithCrc = 0, + DataNoCrc = 1, + ControlProc = 14 + }; + + struct Frame + { + PduType mPduType; + uint8_t mFrameNumber; + uint8_t mFqc; + uint8_t mRfci; + uint8_t mHeaderCrc; + bool mHeaderCrcOk; + uint16_t mPayloadCrc; + bool mPayloadCrcOk; + const uint8_t* mPayload; + uint16_t mPayloadSize; + }; + + /* Default value is false */ + static bool TwoBytePseudoheader; + + static bool parse(const uint8_t* packet, int size, Frame& result); + static bool parse2(const uint8_t* packet, int size, Frame& result); +}; + + +#endif // HL_IUUP_H + diff --git a/src/engine/helper/HL_Log.cpp b/src/engine/helper/HL_Log.cpp new file mode 100644 index 00000000..e7c7b17c --- /dev/null +++ b/src/engine/helper/HL_Log.cpp @@ -0,0 +1,5 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + diff --git a/src/engine/helper/HL_Log.h b/src/engine/helper/HL_Log.h new file mode 100644 index 00000000..01eb0ffc --- /dev/null +++ b/src/engine/helper/HL_Log.h @@ -0,0 +1,20 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __LOG_H +#define __LOG_H + +#include "ice/ICELog.h" + +using ice::GLogger; +using ice::LogLock; + +using ice::LL_MEDIA; +using ice::LL_DEBUG; +using ice::LL_INFO; +using ice::LL_CRITICAL; +using ice::LL_NONE; + +#endif diff --git a/src/engine/helper/HL_NetworkFrame.cpp b/src/engine/helper/HL_NetworkFrame.cpp new file mode 100644 index 00000000..3732d9b9 --- /dev/null +++ b/src/engine/helper/HL_NetworkFrame.cpp @@ -0,0 +1,141 @@ +#include "HL_NetworkFrame.h" +#include "HL_InternetAddress.h" + +#define ETHERTYPE_MPLS_UC (0x8847) +#define ETHERTYPE_MPLS_MC (0x8848) + +#define MPLS_STACK_MASK (0x00000100) +#define MPLS_STACK_SHIFT (8) + +NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForEthernet(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination) +{ + PacketData result(packet); + + const EthernetHeader* ethernet = reinterpret_cast(packet.mData); + + // Skip ethernet header + packet.mData += sizeof(EthernetHeader); + packet.mLength -= sizeof(EthernetHeader); + + // See if there is Vlan header + uint16_t proto = 0; + if (ethernet->mEtherType == 129) + { + const VlanHeader* vlan = reinterpret_cast(packet.mData); + packet.mData += sizeof(VlanHeader); + packet.mLength -= sizeof(VlanHeader); + proto = ntohs(vlan->mData); + } + + // Skip MPLS headers + + if (proto == ETHERTYPE_MPLS_UC || proto == ETHERTYPE_MPLS_MC) + { + // Parse MPLS here until marker "bottom of mpls stack" + for(bool bottomOfStack = false; !bottomOfStack; + bottomOfStack = ((ntohl(*(uint32_t*)(packet.mData - 4)) & MPLS_STACK_MASK) >> MPLS_STACK_SHIFT) != 0) + { + packet.mData += 4; + packet.mLength -=4; + } + } + + const Ip4Header* ip4 = reinterpret_cast(packet.mData); + + if (ip4->mProtocol != IPPROTO_UDP) + return PacketData(); + + + switch (ip4->version()) + { + case 4: + return GetUdpPayloadForIp4(packet, source, destination); + + case 6: + return GetUdpPayloadForIp6(packet, source, destination); + + default: + return PacketData(); + } +} + +NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForSLL(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination) +{ + PacketData result(packet); + + if (packet.mLength < 16) + return PacketData(); + + const LinuxSllHeader* sll = reinterpret_cast(packet.mData); + + packet.mData += sizeof(LinuxSllHeader); + packet.mLength -= sizeof(LinuxSllHeader); + + switch (ntohs(sll->mProtocolType)) + { + case 0x0800: + return GetUdpPayloadForIp4(packet, source, destination); + + case 0x86DD: + return GetUdpPayloadForIp6(packet, source, destination); + + default: + return PacketData(); + } +} + + +NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForIp4(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination) +{ + PacketData result(packet); + const Ip4Header* ip4 = reinterpret_cast(packet.mData); + if (ip4->mProtocol != IPPROTO_UDP) + return PacketData(nullptr, 0); + + result.mData += ip4->headerLength(); + result.mLength -= ip4->headerLength(); + + const UdpHeader* udp = reinterpret_cast(result.mData); + result.mData += sizeof(UdpHeader); + result.mLength -= sizeof(UdpHeader); + + // Check if UDP payload length is smaller than full packet length. It can be VLAN trailer data - we need to skip it + size_t length = ntohs(udp->mDatagramLength); + if (length - sizeof(UdpHeader) < (size_t)result.mLength) + result.mLength = length - sizeof(UdpHeader); + + source.setIp(ip4->mSource); + source.setPort(ntohs(udp->mSourcePort)); + + destination.setIp(ip4->mDestination); + destination.setPort(ntohs(udp->mDestinationPort)); + + return result; +} + +NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForIp6(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination) +{ + PacketData result(packet); + const Ip4Header* ip4 = reinterpret_cast(packet.mData); + if (ip4->mProtocol != IPPROTO_UDP) + return PacketData(nullptr, 0); + + result.mData += ip4->headerLength(); + result.mLength -= ip4->headerLength(); + + const UdpHeader* udp = reinterpret_cast(packet.mData); + result.mData += sizeof(UdpHeader); + result.mLength -= sizeof(UdpHeader); + + /* + if (result.mLength != ntohs(udp->mDatagramLength)) + return PacketData(nullptr, 0); + */ + source.setIp(ip4->mSource); + source.setPort(ntohs(udp->mSourcePort)); + + destination.setIp(ip4->mDestination); + destination.setPort(ntohs(udp->mDestinationPort)); + + return result; +} diff --git a/src/engine/helper/HL_NetworkFrame.h b/src/engine/helper/HL_NetworkFrame.h new file mode 100644 index 00000000..5dc5b571 --- /dev/null +++ b/src/engine/helper/HL_NetworkFrame.h @@ -0,0 +1,114 @@ +#ifndef _HL_NETWORK_FRAME_H +#define _HL_NETWORK_FRAME_H + +#include +#include "HL_InternetAddress.h" + +class NetworkFrame +{ +public: + struct PacketData + { + const uint8_t* mData; + int mLength; + + PacketData(const uint8_t* data, int length) + :mData(data), mLength(length) + {} + + PacketData() + :mData(nullptr), mLength(0) + {} + }; + + static PacketData GetUdpPayloadForEthernet(PacketData& packet, InternetAddress& source, InternetAddress& destination); + static PacketData GetUdpPayloadForIp4(PacketData& packet, InternetAddress& source, InternetAddress& destination); + static PacketData GetUdpPayloadForIp6(PacketData& packet, InternetAddress& source, InternetAddress& destination); + static PacketData GetUdpPayloadForSLL(PacketData& packet, InternetAddress& source, InternetAddress& destination); + + struct EthernetHeader + { + /* Ethernet addresses are 6 bytes */ + static const int AddressLength = 6; + uint8_t mEtherDHost[AddressLength]; /* Destination host address */ + uint8_t mEtherSHost[AddressLength]; /* Source host address */ + uint16_t mEtherType; /* IP? ARP? RARP? etc */ + }; + + struct __attribute__((packed)) LinuxSllHeader + { + uint16_t mPacketType; + uint16_t mARPHRD; + uint16_t mAddressLength; + uint64_t mAddress; + uint16_t mProtocolType; + }; + + struct VlanHeader + { + uint16_t mMagicId; + uint16_t mData; + }; + + struct Ip4Header + { + uint8_t mVhl; /* version << 4 | header length >> 2 */ + uint8_t mTos; /* type of service */ + uint16_t mLen; /* total length */ + uint16_t mId; /* identification */ + uint16_t mOffset; /* fragment offset field */ +#define IP_RF 0x8000 /* reserved fragment flag */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + uint8_t mTtl; /* time to live */ + uint8_t mProtocol; /* protocol */ + uint16_t mChecksum; /* checksum */ + in_addr mSource, + mDestination; /* source and dest address */ + + int headerLength() const + { + return (mVhl & 0x0f) * 4; + } + + int version() const + { + return mVhl >> 4; + } + }; + + struct UdpHeader + { + uint16_t mSourcePort; /* source port */ + uint16_t mDestinationPort; + uint16_t mDatagramLength; /* datagram length */ + uint16_t mDatagramChecksum; /* datagram checksum */ + }; + + + struct TcpHeader + { + uint16_t mSourcePort; /* source port */ + uint16_t mDestinationPort; /* destination port */ + uint32_t mSeqNo; /* sequence number */ + uint32_t mAckNo; /* acknowledgement number */ + uint32_t mDataOffset; /* data offset, rsvd */ +#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) + uint8_t mFlags; +#define TH_FIN 0x01 +#define TH_SYN 0x02 +#define TH_RST 0x04 +#define TH_PUSH 0x08 +#define TH_ACK 0x10 +#define TH_URG 0x20 +#define TH_ECE 0x40 +#define TH_CWR 0x80 +#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) + uint16_t mWindow; /* window */ + uint16_t mChecksum; /* checksum */ + uint16_t mUrgentPointer; /* urgent pointer */ + }; + +}; +#endif diff --git a/src/engine/helper/HL_NetworkSocket.cpp b/src/engine/helper/HL_NetworkSocket.cpp new file mode 100644 index 00000000..86f58d3d --- /dev/null +++ b/src/engine/helper/HL_NetworkSocket.cpp @@ -0,0 +1,180 @@ +/* Copyright(C) 2007-2017 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#if defined(TARGET_LINUX) || defined(TARGET_ANDROID) +# include +#endif + +#include "../config.h" +#include "HL_NetworkSocket.h" + +#if defined(TARGET_OSX) || defined(TARGET_LINUX) +# include +#endif + +#include +#include + +DatagramSocket::DatagramSocket() +:mFamily(AF_INET), mHandle(INVALID_SOCKET), mLocalPort(0) +{ + +} + +DatagramSocket::~DatagramSocket() +{ + closeSocket(); +} + +void DatagramSocket::open(int family) +{ + if (mHandle != INVALID_SOCKET || mFamily != family) + closeSocket(); + + assert(family == AF_INET || family == AF_INET6); + mFamily = family; + mHandle = ::socket(mFamily, SOCK_DGRAM, IPPROTO_UDP); + if (mHandle != INVALID_SOCKET) + { + sockaddr_in addr4; sockaddr_in6 addr6; + memset(&addr4, 0, sizeof(addr4)); memset(&addr6, 0, sizeof(addr6)); + socklen_t l = mFamily == AF_INET ? sizeof(addr4) : sizeof(addr6); + int retcode = getsockname(mHandle, (mFamily == AF_INET ? (sockaddr*)&addr4 : (sockaddr*)&addr6), &l); + if (!retcode) + { + mLocalPort = ntohs(mFamily == AF_INET ? addr4.sin_port : addr6.sin6_port); + } + } +} + +int DatagramSocket::localport() +{ + return mLocalPort; +} + +void DatagramSocket::sendDatagram(InternetAddress &dest, const void *packetData, unsigned int packetSize) +{ + if (mHandle == INVALID_SOCKET) + return; + + int sent = ::sendto(mHandle, (const char*)packetData, packetSize, 0, dest.genericsockaddr(), dest.sockaddrLen()); +} + +unsigned DatagramSocket::recvDatagram(InternetAddress &src, void *packetBuffer, unsigned packetCapacity) +{ + if (mHandle == INVALID_SOCKET) + return 0; + + sockaddr_in sourceaddr; +#ifdef WIN32 + int addrlen = sizeof(sourceaddr); +#else + socklen_t addrlen = sizeof(sourceaddr); +#endif + int received = ::recvfrom(mHandle, (char*)packetBuffer, packetCapacity, 0, (sockaddr*)&sourceaddr, &addrlen); + if (received > 0) + { + src = InternetAddress((sockaddr&)sourceaddr, addrlen); + return received; + } + else + return 0; +} + +void DatagramSocket::closeSocket() +{ + if (mHandle != INVALID_SOCKET) + { +#ifdef WIN32 + ::closesocket(mHandle); +#else + close(mHandle); +#endif + mHandle = INVALID_SOCKET; + } +} + +bool DatagramSocket::isValid() const +{ + return mHandle != INVALID_SOCKET; +} + +int DatagramSocket::family() const +{ + return mFamily; +} + +bool DatagramSocket::setBlocking(bool blocking) +{ +#if defined(TARGET_WIN) + unsigned long mode = blocking ? 0 : 1; + return (ioctlsocket(mHandle, FIONBIO, &mode) == 0) ? true : false; +#endif +#if defined(TARGET_OSX) || defined(TARGET_LINUX) + int flags = fcntl(mHandle, F_GETFL, 0); + if (flags < 0) + return false; + flags = blocking ? (flags&~O_NONBLOCK) : (flags|O_NONBLOCK); + return (fcntl(mHandle, F_SETFL, flags) == 0) ? true : false; +#endif +#if defined(TARGET_ANDROID) + unsigned long mode = blocking ? 0 : 1; + return (ioctl(mHandle, FIONBIO, &mode) == 0) ? true : false; +#endif + return false; +} + +SOCKET DatagramSocket::socket() const +{ + return mHandle; +} + +DatagramAgreggator::DatagramAgreggator() +{ + FD_ZERO(&mReadSet); + mMaxHandle = 0; +} + +DatagramAgreggator::~DatagramAgreggator() +{ +} + +void DatagramAgreggator::addSocket(PDatagramSocket socket) +{ + if (socket->mHandle == INVALID_SOCKET) + return; + + FD_SET(socket->mHandle, &mReadSet); + if (socket->mHandle > mMaxHandle) + mMaxHandle = socket->mHandle; + + mSocketVector.push_back(socket); +} + +unsigned DatagramAgreggator::count() +{ + return mSocketVector.size(); +} + +bool DatagramAgreggator::hasDataAtIndex(unsigned index) +{ + PDatagramSocket socket = mSocketVector[index]; + return (FD_ISSET(socket->mHandle, &mReadSet) != 0); +} + +PDatagramSocket DatagramAgreggator::socketAt(unsigned index) +{ + return mSocketVector[index]; +} + +bool DatagramAgreggator::waitForData(unsigned milliseconds) +{ + timeval tv; + tv.tv_sec = milliseconds / 1000; + tv.tv_usec = (milliseconds % 1000) * 1000; + + int rescode = ::select(mMaxHandle, &mReadSet, NULL, NULL, &tv); + return rescode > 0; +} diff --git a/src/engine/helper/HL_NetworkSocket.h b/src/engine/helper/HL_NetworkSocket.h new file mode 100644 index 00000000..b5566664 --- /dev/null +++ b/src/engine/helper/HL_NetworkSocket.h @@ -0,0 +1,66 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __NETWORK_SOCKET_H +#define __NETWORK_SOCKET_H + +#include "HL_InternetAddress.h" +#include +#include + +class NetworkSocket +{ +public: + virtual int localport() = 0; + +}; + +class DatagramSocket +{ +friend class SocketHeap; +friend class DatagramAgreggator; +public: + DatagramSocket(); + virtual ~DatagramSocket(); + + virtual int localport(); + + virtual void sendDatagram(InternetAddress& dest, const void* packetData, unsigned packetSize); + virtual unsigned recvDatagram(InternetAddress& src, void* packetBuffer, unsigned packetCapacity); + virtual void closeSocket(); + virtual bool isValid() const; + virtual int family() const; + virtual bool setBlocking(bool blocking); + virtual SOCKET socket() const; + + virtual void open(int family); +protected: + int mFamily; + SOCKET mHandle; + int mLocalPort; +}; +typedef std::shared_ptr PDatagramSocket; + +class DatagramAgreggator +{ +public: + DatagramAgreggator(); + ~DatagramAgreggator(); + + void addSocket(PDatagramSocket socket); + unsigned count(); + bool hasDataAtIndex(unsigned index); + PDatagramSocket socketAt(unsigned index); + + bool waitForData(unsigned milliseconds); + +protected: + typedef std::vector SocketList; + SocketList mSocketVector; + fd_set mReadSet; + SOCKET mMaxHandle; +}; + +#endif diff --git a/src/engine/helper/HL_Optional.hpp b/src/engine/helper/HL_Optional.hpp new file mode 100644 index 00000000..f8c1acab --- /dev/null +++ b/src/engine/helper/HL_Optional.hpp @@ -0,0 +1,1043 @@ +// Copyright (C) 2011 - 2012 Andrzej Krzemienski. +// +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The idea and interface is based on Boost.Optional library +// authored by Fernando Luis Cacciola Carballal + +# ifndef ___OPTIONAL_HPP___ +# define ___OPTIONAL_HPP___ + +# include +# include +# include +# include +# include +# include +# include + +# define TR2_OPTIONAL_REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false + +# if defined __GNUC__ // NOTE: GNUC is also defined for Clang +# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8) +# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ +# elif (__GNUC__ > 4) +# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ +# endif +# +# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7) +# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___ +# elif (__GNUC__ > 4) +# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___ +# endif +# +# if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1) +# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9) +# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# elif (__GNUC__ > 4) +# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# endif +# endif +# +# if defined __clang_major__ +# if (__clang_major__ == 3 && __clang_minor__ >= 5) +# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ +# elif (__clang_major__ > 3) +# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ +# endif +# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ +# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ +# elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2) +# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ +# endif +# endif +# +# if defined _MSC_VER +# if (_MSC_VER >= 1900) +# define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ +# endif +# endif + +# if defined __clang__ +# if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9) +# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 +# else +# define OPTIONAL_HAS_THIS_RVALUE_REFS 0 +# endif +# elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 +# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ +# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 +# else +# define OPTIONAL_HAS_THIS_RVALUE_REFS 0 +# endif + + +# if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1 +# define OPTIONAL_CONSTEXPR_INIT_LIST constexpr +# else +# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0 +# define OPTIONAL_CONSTEXPR_INIT_LIST +# endif + +# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ && (defined __cplusplus) && (__cplusplus != 201103L) +# define OPTIONAL_HAS_MOVE_ACCESSORS 1 +# else +# define OPTIONAL_HAS_MOVE_ACCESSORS 0 +# endif + +# // In C++11 constexpr implies const, so we need to make non-const members also non-constexpr +# if (defined __cplusplus) && (__cplusplus == 201103L) +# define OPTIONAL_MUTABLE_CONSTEXPR +# else +# define OPTIONAL_MUTABLE_CONSTEXPR constexpr +# endif + +namespace std{ + +namespace experimental{ + +// BEGIN workaround for missing is_trivially_destructible +# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ + // leave it: it is already there +# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ + // leave it: it is already there +# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ + // leave it: it is already there +# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS + // leave it: the user doesn't want it +# else + template + using is_trivially_destructible = std::has_trivial_destructor; +# endif +// END workaround for missing is_trivially_destructible + +# if (defined TR2_OPTIONAL_GCC_4_7_AND_HIGHER___) + // leave it; our metafunctions are already defined. +# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ + // leave it; our metafunctions are already defined. +# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ + // leave it: it is already there +# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS + // leave it: the user doesn't want it +# else + + +// workaround for missing traits in GCC and CLANG +template +struct is_nothrow_move_constructible +{ + constexpr static bool value = std::is_nothrow_constructible::value; +}; + + +template +struct is_assignable +{ + template + constexpr static bool has_assign(...) { return false; } + + template () = std::declval(), true)) > + // the comma operator is necessary for the cases where operator= returns void + constexpr static bool has_assign(bool) { return true; } + + constexpr static bool value = has_assign(true); +}; + + +template +struct is_nothrow_move_assignable +{ + template + struct has_nothrow_move_assign { + constexpr static bool value = false; + }; + + template + struct has_nothrow_move_assign { + constexpr static bool value = noexcept( std::declval() = std::declval() ); + }; + + constexpr static bool value = has_nothrow_move_assign::value>::value; +}; +// end workaround + + +# endif + + + +// 20.5.4, optional for object types +template class optional; + +// 20.5.5, optional for lvalue reference types +template class optional; + + +// workaround: std utility functions aren't constexpr yet +template inline constexpr T&& constexpr_forward(typename std::remove_reference::type& t) noexcept +{ + return static_cast(t); +} + +template inline constexpr T&& constexpr_forward(typename std::remove_reference::type&& t) noexcept +{ + static_assert(!std::is_lvalue_reference::value, "!!"); + return static_cast(t); +} + +template inline constexpr typename std::remove_reference::type&& constexpr_move(T&& t) noexcept +{ + return static_cast::type&&>(t); +} + + +#if defined NDEBUG +# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR) +#else +# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(!#CHECK);}(), (EXPR))) +#endif + + +namespace detail_ +{ + +// static_addressof: a constexpr version of addressof +template +struct has_overloaded_addressof +{ + template + constexpr static bool has_overload(...) { return false; } + + template ().operator&()) > + constexpr static bool has_overload(bool) { return true; } + + constexpr static bool value = has_overload(true); +}; + +template )> +constexpr T* static_addressof(T& ref) +{ + return &ref; +} + +template )> +T* static_addressof(T& ref) +{ + return std::addressof(ref); +} + + +// the call to convert(b) has return type A and converts b to type A iff b decltype(b) is implicitly convertible to A +template +constexpr U convert(U v) { return v; } + +} // namespace detail + + +constexpr struct trivial_init_t{} trivial_init{}; + + +// 20.5.6, In-place construction +constexpr struct in_place_t{} in_place{}; + + +// 20.5.7, Disengaged state indicator +struct nullopt_t +{ + struct init{}; + constexpr explicit nullopt_t(init){} +}; +constexpr nullopt_t nullopt{nullopt_t::init()}; + + +// 20.5.8, class bad_optional_access +class bad_optional_access : public logic_error { +public: + explicit bad_optional_access(const string& what_arg) : logic_error{what_arg} {} + explicit bad_optional_access(const char* what_arg) : logic_error{what_arg} {} +}; + + +template +union storage_t +{ + unsigned char dummy_; + T value_; + + constexpr storage_t( trivial_init_t ) noexcept : dummy_() {}; + + template + constexpr storage_t( Args&&... args ) : value_(constexpr_forward(args)...) {} + + ~storage_t(){} +}; + + +template +union constexpr_storage_t +{ + unsigned char dummy_; + T value_; + + constexpr constexpr_storage_t( trivial_init_t ) noexcept : dummy_() {}; + + template + constexpr constexpr_storage_t( Args&&... args ) : value_(constexpr_forward(args)...) {} + + ~constexpr_storage_t() = default; +}; + + +template +struct optional_base +{ + bool init_; + storage_t storage_; + + constexpr optional_base() noexcept : init_(false), storage_(trivial_init) {}; + + explicit constexpr optional_base(const T& v) : init_(true), storage_(v) {} + + explicit constexpr optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {} + + template explicit optional_base(in_place_t, Args&&... args) + : init_(true), storage_(constexpr_forward(args)...) {} + + template >)> + explicit optional_base(in_place_t, std::initializer_list il, Args&&... args) + : init_(true), storage_(il, std::forward(args)...) {} + + ~optional_base() { if (init_) storage_.value_.T::~T(); } +}; + + +template +struct constexpr_optional_base +{ + bool init_; + constexpr_storage_t storage_; + + constexpr constexpr_optional_base() noexcept : init_(false), storage_(trivial_init) {}; + + explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_(v) {} + + explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {} + + template explicit constexpr constexpr_optional_base(in_place_t, Args&&... args) + : init_(true), storage_(constexpr_forward(args)...) {} + + template >)> + OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, std::initializer_list il, Args&&... args) + : init_(true), storage_(il, std::forward(args)...) {} + + ~constexpr_optional_base() = default; +}; + +template +using OptionalBase = typename std::conditional< + is_trivially_destructible::value, // if possible + constexpr_optional_base::type>, // use base with trivial destructor + optional_base::type> +>::type; + + + +template +class optional : private OptionalBase +{ + static_assert( !std::is_same::type, nullopt_t>::value, "bad T" ); + static_assert( !std::is_same::type, in_place_t>::value, "bad T" ); + + + constexpr bool initialized() const noexcept { return OptionalBase::init_; } + typename std::remove_const::type* dataptr() { return std::addressof(OptionalBase::storage_.value_); } + constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase::storage_.value_); } + +# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 + constexpr const T& contained_val() const& { return OptionalBase::storage_.value_; } +# if OPTIONAL_HAS_MOVE_ACCESSORS == 1 + OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return std::move(OptionalBase::storage_.value_); } + OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase::storage_.value_; } +# else + T& contained_val() & { return OptionalBase::storage_.value_; } + T&& contained_val() && { return std::move(OptionalBase::storage_.value_); } +# endif +# else + constexpr const T& contained_val() const { return OptionalBase::storage_.value_; } + T& contained_val() { return OptionalBase::storage_.value_; } +# endif + + void clear() noexcept { + if (initialized()) dataptr()->T::~T(); + OptionalBase::init_ = false; + } + + template + void initialize(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) + { + assert(!OptionalBase::init_); + ::new (static_cast(dataptr())) T(std::forward(args)...); + OptionalBase::init_ = true; + } + + template + void initialize(std::initializer_list il, Args&&... args) noexcept(noexcept(T(il, std::forward(args)...))) + { + assert(!OptionalBase::init_); + ::new (static_cast(dataptr())) T(il, std::forward(args)...); + OptionalBase::init_ = true; + } + +public: + typedef T value_type; + + // 20.5.5.1, constructors + constexpr optional() noexcept : OptionalBase() {}; + constexpr optional(nullopt_t) noexcept : OptionalBase() {}; + + optional(const optional& rhs) + : OptionalBase() + { + if (rhs.initialized()) { + ::new (static_cast(dataptr())) T(*rhs); + OptionalBase::init_ = true; + } + } + + optional(optional&& rhs) noexcept(is_nothrow_move_constructible::value) + : OptionalBase() + { + if (rhs.initialized()) { + ::new (static_cast(dataptr())) T(std::move(*rhs)); + OptionalBase::init_ = true; + } + } + + constexpr optional(const T& v) : OptionalBase(v) {} + + constexpr optional(T&& v) : OptionalBase(constexpr_move(v)) {} + + template + explicit constexpr optional(in_place_t, Args&&... args) + : OptionalBase(in_place_t{}, constexpr_forward(args)...) {} + + template >)> + OPTIONAL_CONSTEXPR_INIT_LIST explicit optional(in_place_t, std::initializer_list il, Args&&... args) + : OptionalBase(in_place_t{}, il, constexpr_forward(args)...) {} + + // 20.5.4.2, Destructor + ~optional() = default; + + // 20.5.4.3, assignment + optional& operator=(nullopt_t) noexcept + { + clear(); + return *this; + } + + optional& operator=(const optional& rhs) + { + if (initialized() == true && rhs.initialized() == false) clear(); + else if (initialized() == false && rhs.initialized() == true) initialize(*rhs); + else if (initialized() == true && rhs.initialized() == true) contained_val() = *rhs; + return *this; + } + + optional& operator=(optional&& rhs) + noexcept(is_nothrow_move_assignable::value && is_nothrow_move_constructible::value) + { + if (initialized() == true && rhs.initialized() == false) clear(); + else if (initialized() == false && rhs.initialized() == true) initialize(std::move(*rhs)); + else if (initialized() == true && rhs.initialized() == true) contained_val() = std::move(*rhs); + return *this; + } + + template + auto operator=(U&& v) + -> typename enable_if + < + is_same::type, T>::value, + optional& + >::type + { + if (initialized()) { contained_val() = std::forward(v); } + else { initialize(std::forward(v)); } + return *this; + } + + + template + void emplace(Args&&... args) + { + clear(); + initialize(std::forward(args)...); + } + + template + void emplace(initializer_list il, Args&&... args) + { + clear(); + initialize(il, std::forward(args)...); + } + + // 20.5.4.4, Swap + void swap(optional& rhs) noexcept(is_nothrow_move_constructible::value && noexcept(swap(declval(), declval()))) + { + if (initialized() == true && rhs.initialized() == false) { rhs.initialize(std::move(**this)); clear(); } + else if (initialized() == false && rhs.initialized() == true) { initialize(std::move(*rhs)); rhs.clear(); } + else if (initialized() == true && rhs.initialized() == true) { using std::swap; swap(**this, *rhs); } + } + + // 20.5.4.5, Observers + + explicit constexpr operator bool() const noexcept { return initialized(); } + bool is_initialized() const noexcept { return initialized(); } + + constexpr T const* operator ->() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr()); + } + +# if OPTIONAL_HAS_MOVE_ACCESSORS == 1 + + OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() { + assert (initialized()); + return dataptr(); + } + + constexpr T const& operator *() const& { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val()); + } + + OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & { + assert (initialized()); + return contained_val(); + } + + OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && { + assert (initialized()); + return constexpr_move(contained_val()); + } + + constexpr T const& value() const& { + return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); + } + + OPTIONAL_MUTABLE_CONSTEXPR T& value() & { + return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); + } + + OPTIONAL_MUTABLE_CONSTEXPR T&& value() && { + if (!initialized()) throw bad_optional_access("bad optional access"); + return std::move(contained_val()); + } + +# else + + T* operator ->() { + assert (initialized()); + return dataptr(); + } + + constexpr T const& operator *() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val()); + } + + T& operator *() { + assert (initialized()); + return contained_val(); + } + + constexpr T const& value() const { + return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); + } + + T& value() { + return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); + } + +# endif + +# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 + + template + constexpr T value_or(V&& v) const& + { + return *this ? **this : detail_::convert(constexpr_forward(v)); + } + +# if OPTIONAL_HAS_MOVE_ACCESSORS == 1 + + template + OPTIONAL_MUTABLE_CONSTEXPR T value_or(V&& v) && + { + return *this ? constexpr_move(const_cast&>(*this).contained_val()) : detail_::convert(constexpr_forward(v)); + } + +# else + + template + T value_or(V&& v) && + { + return *this ? constexpr_move(const_cast&>(*this).contained_val()) : detail_::convert(constexpr_forward(v)); + } + +# endif + +# else + + template + constexpr T value_or(V&& v) const + { + return *this ? **this : detail_::convert(constexpr_forward(v)); + } + +# endif + +}; + + +template +class optional +{ + static_assert( !std::is_same::value, "bad T" ); + static_assert( !std::is_same::value, "bad T" ); + T* ref; + +public: + + // 20.5.5.1, construction/destruction + constexpr optional() noexcept : ref(nullptr) {} + + constexpr optional(nullopt_t) noexcept : ref(nullptr) {} + + constexpr optional(T& v) noexcept : ref(detail_::static_addressof(v)) {} + + optional(T&&) = delete; + + constexpr optional(const optional& rhs) noexcept : ref(rhs.ref) {} + + explicit constexpr optional(in_place_t, T& v) noexcept : ref(detail_::static_addressof(v)) {} + + explicit optional(in_place_t, T&&) = delete; + + ~optional() = default; + + // 20.5.5.2, mutation + optional& operator=(nullopt_t) noexcept { + ref = nullptr; + return *this; + } + + // optional& operator=(const optional& rhs) noexcept { + // ref = rhs.ref; + // return *this; + // } + + // optional& operator=(optional&& rhs) noexcept { + // ref = rhs.ref; + // return *this; + // } + + template + auto operator=(U&& rhs) noexcept + -> typename enable_if + < + is_same::type, optional>::value, + optional& + >::type + { + ref = rhs.ref; + return *this; + } + + template + auto operator=(U&& rhs) noexcept + -> typename enable_if + < + !is_same::type, optional>::value, + optional& + >::type + = delete; + + void emplace(T& v) noexcept { + ref = detail_::static_addressof(v); + } + + void emplace(T&&) = delete; + + + void swap(optional& rhs) noexcept + { + std::swap(ref, rhs.ref); + } + + // 20.5.5.3, observers + constexpr T* operator->() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref); + } + + constexpr T& operator*() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref); + } + + constexpr T& value() const { + return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref); + } + + explicit constexpr operator bool() const noexcept { + return ref != nullptr; + } + + template + constexpr typename decay::type value_or(V&& v) const + { + return *this ? **this : detail_::convert::type>(constexpr_forward(v)); + } +}; + + +template +class optional +{ + static_assert( sizeof(T) == 0, "optional rvalue references disallowed" ); +}; + + +// 20.5.8, Relational operators +template constexpr bool operator==(const optional& x, const optional& y) +{ + return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y; +} + +template constexpr bool operator!=(const optional& x, const optional& y) +{ + return !(x == y); +} + +template constexpr bool operator<(const optional& x, const optional& y) +{ + return (!y) ? false : (!x) ? true : *x < *y; +} + +template constexpr bool operator>(const optional& x, const optional& y) +{ + return (y < x); +} + +template constexpr bool operator<=(const optional& x, const optional& y) +{ + return !(y < x); +} + +template constexpr bool operator>=(const optional& x, const optional& y) +{ + return !(x < y); +} + + +// 20.5.9, Comparison with nullopt +template constexpr bool operator==(const optional& x, nullopt_t) noexcept +{ + return (!x); +} + +template constexpr bool operator==(nullopt_t, const optional& x) noexcept +{ + return (!x); +} + +template constexpr bool operator!=(const optional& x, nullopt_t) noexcept +{ + return bool(x); +} + +template constexpr bool operator!=(nullopt_t, const optional& x) noexcept +{ + return bool(x); +} + +template constexpr bool operator<(const optional&, nullopt_t) noexcept +{ + return false; +} + +template constexpr bool operator<(nullopt_t, const optional& x) noexcept +{ + return bool(x); +} + +template constexpr bool operator<=(const optional& x, nullopt_t) noexcept +{ + return (!x); +} + +template constexpr bool operator<=(nullopt_t, const optional&) noexcept +{ + return true; +} + +template constexpr bool operator>(const optional& x, nullopt_t) noexcept +{ + return bool(x); +} + +template constexpr bool operator>(nullopt_t, const optional&) noexcept +{ + return false; +} + +template constexpr bool operator>=(const optional&, nullopt_t) noexcept +{ + return true; +} + +template constexpr bool operator>=(nullopt_t, const optional& x) noexcept +{ + return (!x); +} + + + +// 20.5.10, Comparison with T +template constexpr bool operator==(const optional& x, const T& v) +{ + return bool(x) ? *x == v : false; +} + +template constexpr bool operator==(const T& v, const optional& x) +{ + return bool(x) ? v == *x : false; +} + +template constexpr bool operator!=(const optional& x, const T& v) +{ + return bool(x) ? *x != v : true; +} + +template constexpr bool operator!=(const T& v, const optional& x) +{ + return bool(x) ? v != *x : true; +} + +template constexpr bool operator<(const optional& x, const T& v) +{ + return bool(x) ? *x < v : true; +} + +template constexpr bool operator>(const T& v, const optional& x) +{ + return bool(x) ? v > *x : true; +} + +template constexpr bool operator>(const optional& x, const T& v) +{ + return bool(x) ? *x > v : false; +} + +template constexpr bool operator<(const T& v, const optional& x) +{ + return bool(x) ? v < *x : false; +} + +template constexpr bool operator>=(const optional& x, const T& v) +{ + return bool(x) ? *x >= v : false; +} + +template constexpr bool operator<=(const T& v, const optional& x) +{ + return bool(x) ? v <= *x : false; +} + +template constexpr bool operator<=(const optional& x, const T& v) +{ + return bool(x) ? *x <= v : true; +} + +template constexpr bool operator>=(const T& v, const optional& x) +{ + return bool(x) ? v >= *x : true; +} + + +// Comparison of optional with T +template constexpr bool operator==(const optional& x, const T& v) +{ + return bool(x) ? *x == v : false; +} + +template constexpr bool operator==(const T& v, const optional& x) +{ + return bool(x) ? v == *x : false; +} + +template constexpr bool operator!=(const optional& x, const T& v) +{ + return bool(x) ? *x != v : true; +} + +template constexpr bool operator!=(const T& v, const optional& x) +{ + return bool(x) ? v != *x : true; +} + +template constexpr bool operator<(const optional& x, const T& v) +{ + return bool(x) ? *x < v : true; +} + +template constexpr bool operator>(const T& v, const optional& x) +{ + return bool(x) ? v > *x : true; +} + +template constexpr bool operator>(const optional& x, const T& v) +{ + return bool(x) ? *x > v : false; +} + +template constexpr bool operator<(const T& v, const optional& x) +{ + return bool(x) ? v < *x : false; +} + +template constexpr bool operator>=(const optional& x, const T& v) +{ + return bool(x) ? *x >= v : false; +} + +template constexpr bool operator<=(const T& v, const optional& x) +{ + return bool(x) ? v <= *x : false; +} + +template constexpr bool operator<=(const optional& x, const T& v) +{ + return bool(x) ? *x <= v : true; +} + +template constexpr bool operator>=(const T& v, const optional& x) +{ + return bool(x) ? v >= *x : true; +} + +// Comparison of optional with T +template constexpr bool operator==(const optional& x, const T& v) +{ + return bool(x) ? *x == v : false; +} + +template constexpr bool operator==(const T& v, const optional& x) +{ + return bool(x) ? v == *x : false; +} + +template constexpr bool operator!=(const optional& x, const T& v) +{ + return bool(x) ? *x != v : true; +} + +template constexpr bool operator!=(const T& v, const optional& x) +{ + return bool(x) ? v != *x : true; +} + +template constexpr bool operator<(const optional& x, const T& v) +{ + return bool(x) ? *x < v : true; +} + +template constexpr bool operator>(const T& v, const optional& x) +{ + return bool(x) ? v > *x : true; +} + +template constexpr bool operator>(const optional& x, const T& v) +{ + return bool(x) ? *x > v : false; +} + +template constexpr bool operator<(const T& v, const optional& x) +{ + return bool(x) ? v < *x : false; +} + +template constexpr bool operator>=(const optional& x, const T& v) +{ + return bool(x) ? *x >= v : false; +} + +template constexpr bool operator<=(const T& v, const optional& x) +{ + return bool(x) ? v <= *x : false; +} + +template constexpr bool operator<=(const optional& x, const T& v) +{ + return bool(x) ? *x <= v : true; +} + +template constexpr bool operator>=(const T& v, const optional& x) +{ + return bool(x) ? v >= *x : true; +} + + +// 20.5.12, Specialized algorithms +template +void swap(optional& x, optional& y) noexcept(noexcept(x.swap(y))) +{ + x.swap(y); +} + + +template +constexpr optional::type> make_optional(T&& v) +{ + return optional::type>(constexpr_forward(v)); +} + +template +constexpr optional make_optional(reference_wrapper v) +{ + return optional(v.get()); +} + + +} // namespace experimental +} // namespace std + +namespace std +{ + template + struct hash> + { + typedef typename hash::result_type result_type; + typedef std::experimental::optional argument_type; + + constexpr result_type operator()(argument_type const& arg) const { + return arg ? std::hash{}(*arg) : result_type{}; + } + }; + + template + struct hash> + { + typedef typename hash::result_type result_type; + typedef std::experimental::optional argument_type; + + constexpr result_type operator()(argument_type const& arg) const { + return arg ? std::hash{}(*arg) : result_type{}; + } + }; +} + +# undef TR2_OPTIONAL_REQUIRES +# undef TR2_OPTIONAL_ASSERTED_EXPRESSION + +# endif //___OPTIONAL_HPP___ diff --git a/src/engine/helper/HL_OsVersion.cpp b/src/engine/helper/HL_OsVersion.cpp new file mode 100644 index 00000000..52017c6b --- /dev/null +++ b/src/engine/helper/HL_OsVersion.cpp @@ -0,0 +1,125 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "HL_OsVersion.h" + +#ifdef TARGET_WIN + +#include + +#if defined(USE_MINIDUMP) +# include +#endif + +int winVersion() +{ + DWORD dwVersion = 0; + DWORD dwMajorVersion = 0; + DWORD dwMinorVersion = 0; + DWORD dwBuild = 0; + + dwVersion = GetVersion(); + + // Get the Windows version. + + dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); + dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion))); + + // Get the build number. + + if (dwVersion < 0x80000000) + dwBuild = (DWORD)(HIWORD(dwVersion)); + + if (dwMajorVersion == 5) + return Win_Xp; + + if (dwMinorVersion == 1) + return Win_Seven; + else + return Win_Vista; + } + +// ----------------- CrashMiniDump ----------------- +#if defined(USE_MINIDUMP) +static LONG WINAPI MyExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo) +{ + // Open the file + HANDLE hFile = CreateFile( L"MiniDump.dmp", GENERIC_READ | GENERIC_WRITE, + 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + + if( ( hFile != NULL ) && ( hFile != INVALID_HANDLE_VALUE ) ) + { + // Create the minidump + MINIDUMP_EXCEPTION_INFORMATION mdei; + + mdei.ThreadId = GetCurrentThreadId(); + mdei.ExceptionPointers = ExceptionInfo; + mdei.ClientPointers = FALSE; + + MINIDUMP_TYPE mdt = MiniDumpWithFullMemory; + + BOOL rv = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), + hFile, mdt, (ExceptionInfo != 0) ? &mdei : 0, 0, 0 ); + + // Close the file + CloseHandle( hFile ); + } + else + { + } + + return EXCEPTION_CONTINUE_SEARCH; +} + +static LPTOP_LEVEL_EXCEPTION_FILTER OldExceptionHandler = nullptr; + +void CrashMiniDump::registerHandler() +{ + OldExceptionHandler = ::SetUnhandledExceptionFilter(&MyExceptionHandler); +} + +void CrashMiniDump::unregisterHandler() +{ + ::SetUnhandledExceptionFilter(nullptr); +} + +#endif + +#endif + +#ifdef TARGET_IOS +int iosVersion() +{ + return 4; // Stick with this for now +} +#endif + +#if defined(TARGET_LINUX) || defined(TARGET_OSX) +#include +#include +#include +#include + +int _kbhit() +{ + static const int STDIN = 0; + static bool initialized = false; + + if (! initialized) { + // Use termios to turn off line buffering + termios term; + tcgetattr(STDIN, &term); + term.c_lflag &= ~ICANON; + tcsetattr(STDIN, TCSANOW, &term); + setbuf(stdin, NULL); + initialized = true; + } + + int bytesWaiting; + ioctl(STDIN, FIONREAD, &bytesWaiting); + return bytesWaiting; +} + +#endif diff --git a/src/engine/helper/HL_OsVersion.h b/src/engine/helper/HL_OsVersion.h new file mode 100644 index 00000000..952019c5 --- /dev/null +++ b/src/engine/helper/HL_OsVersion.h @@ -0,0 +1,51 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __OS_VERSION_H +#define __OS_VERSION_H + +#ifdef TARGET_WIN + +enum +{ + Win_Xp = 0, + Win_Vista = 1, + Win_Seven = 2, + Win_Eight = 3, + Win_Ten = 4 +}; + +extern int winVersion(); + +class CrashMiniDump +{ +public: + static void registerHandler(); + static void unregisterHandler(); +}; + +extern void writeMiniDump(); + +#endif + +#ifdef TARGET_IOS +int iosVersion(); +#endif + + +#if defined(TARGET_LINUX) || defined(TARGET_OSX) + +#include +#include +#include +#if defined(TARGET_LINUX) +# include +#endif + +extern int _kbhit(); + +#endif + +#endif diff --git a/src/engine/helper/HL_Pointer.cpp b/src/engine/helper/HL_Pointer.cpp new file mode 100644 index 00000000..a6d72156 --- /dev/null +++ b/src/engine/helper/HL_Pointer.cpp @@ -0,0 +1,55 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "HL_Pointer.h" + +UsageCounter::UsageCounter() +{} + +UsageCounter::~UsageCounter() +{} + +int UsageCounter::obtain(int usageId) +{ + Lock l(mGuard); + UsageMap::iterator usageIter = mUsage.find(usageId); + if (usageIter != mUsage.end()) + usageIter->second = usageIter->second + 1; + else + mUsage[usageId] = 1; + + return usageCount(); +} + +int UsageCounter::release(int usageId) +{ + Lock l(mGuard); + UsageMap::iterator usageIter = mUsage.find(usageId); + if (usageIter == mUsage.end()) + return usageCount(); + + usageIter->second = usageIter->second - 1; + if (!usageIter->second) + mUsage.erase(usageIter); + + return usageCount(); +} + +int UsageCounter::usageCount() +{ + Lock l(mGuard); + UsageMap::const_iterator usageIter; + int result = 0; + for (usageIter = mUsage.begin(); usageIter != mUsage.end(); usageIter++) + result += usageIter->second; + + return result; +} + +void UsageCounter::clear() +{ + Lock l(mGuard); + mUsage.clear(); +} diff --git a/src/engine/helper/HL_Pointer.h b/src/engine/helper/HL_Pointer.h new file mode 100644 index 00000000..c63e183d --- /dev/null +++ b/src/engine/helper/HL_Pointer.h @@ -0,0 +1,34 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __SMART_POINTER_H +#define __SMART_POINTER_H + +#ifdef USE_NATIVE_SMARTPTR +# include +# define SharedPtr std::shared_ptr +#else +#include "../../libs/resiprocate/rutil/SharedPtr.hxx" +using resip::SharedPtr; +#endif +#include "HL_Sync.h" +#include +class UsageCounter +{ +public: + UsageCounter(); + ~UsageCounter(); + int obtain(int usageId); + int release(int usageId); + int usageCount(); + void clear(); + +protected: + typedef std::map UsageMap; + UsageMap mUsage; + Mutex mGuard; +}; + +#endif diff --git a/src/engine/helper/HL_Rtp.cpp b/src/engine/helper/HL_Rtp.cpp new file mode 100644 index 00000000..1f932282 --- /dev/null +++ b/src/engine/helper/HL_Rtp.cpp @@ -0,0 +1,222 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "HL_Rtp.h" +#include "HL_Exception.h" +#include "HL_String.h" + +#include "rtprawpacket.h" +#include "rtpipv4address.h" +#include +#include +#include + +struct RtpHeader +{ + unsigned char cc:4; /* CSRC count */ + unsigned char x:1; /* header extension flag */ + unsigned char p:1; /* padding flag */ + unsigned char version:2; /* protocol version */ + unsigned char pt:7; /* payload type */ + unsigned char m:1; /* marker bit */ + unsigned short seq; /* sequence number */ + unsigned int ts; /* timestamp */ + unsigned int ssrc; /* synchronization source */ +}; + +struct RtcpHeader +{ + unsigned char rc:5; /* reception report count */ + unsigned char p:1; /* padding flag */ + unsigned char version:2; /* protocol version */ + unsigned char pt:8; /* payload type */ + uint16_t len; /* length */ + uint32_t ssrc; /* synchronization source */ +}; + +bool RtpHelper::isRtp(const void* buffer, int length) +{ + if (length < 12) + return false; + + unsigned char _type = reinterpret_cast(buffer)->pt; + bool rtp = ( (_type & 0x7F) >= 96 && (_type & 0x7F) < 127) || ((_type & 0x7F) < 35); + return rtp; +} + + +bool RtpHelper::isRtpOrRtcp(const void* buffer, int length) +{ + if (length < 12) + return false; + unsigned char b = ((const unsigned char*)buffer)[0]; + + return (b & 0xC0 ) == 128; +} + +bool RtpHelper::isRtcp(const void* buffer, int length) +{ + return (isRtpOrRtcp(buffer, length) && !isRtp(buffer, length)); +} + +unsigned RtpHelper::findSsrc(const void* buffer, int length) +{ + if (isRtp(buffer, length)) + return reinterpret_cast(buffer)->ssrc; + else + return reinterpret_cast(buffer)->ssrc; +} + +int RtpHelper::findPtype(const void* buffer, int length) +{ + if (isRtp(buffer, length)) + return reinterpret_cast(buffer)->pt; + else + return -1; +} + +int RtpHelper::findPayloadLength(const void* buffer, int length) +{ + if (isRtp(buffer, length)) + { + return length - 12; + } + else + return -1; +} + +RtpDump::RtpDump(const char *filename) +:mFilename(filename) +{} + +RtpDump::~RtpDump() +{ + flush(); + for (PacketList::iterator packetIter=mPacketList.begin(); packetIter!=mPacketList.end(); ++packetIter) + { + //free(packetIter->mData); + delete packetIter->mPacket; + } +} + +void RtpDump::load() +{ + FILE* f = fopen(mFilename.c_str(), "rb"); + if (!f) + throw Exception(ERR_WAVFILE_FAILED); + + while (!feof(f)) + { + RtpData data; + fread(&data.mLength, sizeof data.mLength, 1, f); + data.mData = new char[data.mLength]; + fread(data.mData, 1, data.mLength, f); + jrtplib::RTPIPv4Address addr(jrtplib::RTPAddress::IPv4Address); + jrtplib::RTPTime t(0); + jrtplib::RTPRawPacket* raw = new jrtplib::RTPRawPacket((unsigned char*)data.mData, data.mLength, &addr, t, true); + data.mPacket = new jrtplib::RTPPacket(*raw); + mPacketList.push_back(data); + } +} + +int RtpDump::count() const +{ + return mPacketList.size(); +} + +jrtplib::RTPPacket& RtpDump::packetAt(int index) +{ + return *mPacketList[index].mPacket; +} + +void RtpDump::add(const void* buffer, int len) +{ + RtpData data; + data.mData = malloc(len); + memcpy(data.mData, buffer, len); + data.mLength = len; + + jrtplib::RTPIPv4Address addr(jrtplib::RTPAddress::IPv4Address); + jrtplib::RTPTime t(0); + jrtplib::RTPRawPacket* raw = new jrtplib::RTPRawPacket((unsigned char*)const_cast(data.mData), data.mLength, &addr, t, true); + data.mPacket = new jrtplib::RTPPacket(*raw); + //delete raw; + mPacketList.push_back(data); +} + +void RtpDump::flush() +{ + FILE* f = fopen(mFilename.c_str(), "wb"); + if (!f) + throw Exception(ERR_WAVFILE_FAILED); + + PacketList::iterator packetIter = mPacketList.begin(); + for (;packetIter != mPacketList.end(); ++packetIter) + { + RtpData& data = *packetIter; + // Disabled for debugging only + //fwrite(&data.mLength, sizeof data.mLength, 1, f); + fwrite(data.mData, data.mLength, 1, f); + } + fclose(f); +} + +// -------------- MediaStreamId -------------------- +bool MediaStreamId::operator < (const MediaStreamId& right) const +{ + if (mSsrcIsId) + return std::tie(mSSRC, mSource, mDestination) < std::tie(right.mSSRC, right.mSource, right.mDestination); + else + return std::tie(mSource, mDestination) < std::tie(right.mSource, right.mDestination); + +} + +bool MediaStreamId::operator == (const MediaStreamId& right) const +{ + if (mSsrcIsId) + return std::tie(mSSRC, mSource, mDestination) == std::tie(right.mSSRC, right.mSource, right.mDestination); + else + return std::tie(mSource, mDestination) == std::tie(right.mSource, right.mDestination); +} + +std::string MediaStreamId::toString() const +{ + std::ostringstream oss; + oss << "src: " << mSource.toStdString() << + " dst: " << mDestination.toStdString() << + " ssrc: " << StringHelper::toHex(mSSRC); + return oss.str(); +} + + +void writeToJson(const MediaStreamId& id, std::ostringstream& oss) +{ + oss << " \"src\": \"" << id.mSource.toStdString() << "\"," << std::endl + << " \"dst\": \"" << id.mDestination.toStdString() << "\"," << std::endl + << " \"ssrc\": \"" << StringHelper::toHex(id.mSSRC) << "\"," << std::endl + << " \"link_id\": \"" << id.mLinkId.toString() << "\"" << std::endl; +} + +std::string MediaStreamId::getDetectDescription() const +{ + std::ostringstream oss; + oss << "{\"event\": \"stream_detected\"," << std::endl; + writeToJson(*this, oss); + oss << "}"; + + return oss.str(); +} + +std::string MediaStreamId::getFinishDescription() const +{ + std::ostringstream oss; + oss << "{" << std::endl + << " \"event\": \"stream_finished\", " << std::endl; + writeToJson(*this, oss); + oss << "}"; + + return oss.str(); +} + diff --git a/src/engine/helper/HL_Rtp.h b/src/engine/helper/HL_Rtp.h new file mode 100644 index 00000000..6edc9673 --- /dev/null +++ b/src/engine/helper/HL_Rtp.h @@ -0,0 +1,85 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __HL_RTP_H +#define __HL_RTP_H + +#include "jrtplib/src/rtppacket.h" +#include "HL_Uuid.h" +#include "HL_InternetAddress.h" + +#include +#include + +// Class to carry rtp/rtcp socket pair +template +struct RtpPair +{ + T mRtp; + T mRtcp; + + RtpPair() + {} + + RtpPair(const T& rtp, const T& rtcp) + :mRtp(rtp), mRtcp(rtcp) + {} + + bool multiplexed() { return mRtp == mRtcp; } +}; + +class RtpHelper +{ +public: + static bool isRtp(const void* buffer, int length); + static int findPtype(const void* buffer, int length); + static bool isRtpOrRtcp(const void* buffer, int length); + static bool isRtcp(const void* buffer, int length); + static unsigned findSsrc(const void* buffer, int length); + static int findPayloadLength(const void* buffer, int length); +}; + +class RtpDump +{ +protected: + struct RtpData + { + jrtplib::RTPPacket* mPacket; + void* mData; + unsigned mLength; + }; + + typedef std::vector PacketList; + PacketList mPacketList; + std::string mFilename; + +public: + RtpDump(const char* filename); + ~RtpDump(); + + void load(); + int count() const; + jrtplib::RTPPacket& packetAt(int index); + void add(const void* data, int len); + void flush(); +}; + +struct MediaStreamId +{ + InternetAddress mSource; + InternetAddress mDestination; + uint32_t mSSRC = 0; + bool mSsrcIsId = true; + Uuid mLinkId; + + bool operator < (const MediaStreamId& s2) const; + bool operator == (const MediaStreamId& right) const; + + std::string toString() const; + std::string getDetectDescription() const; + std::string getFinishDescription() const; +}; + +#endif diff --git a/src/engine/helper/HL_Singletone.cpp b/src/engine/helper/HL_Singletone.cpp new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/src/engine/helper/HL_Singletone.cpp @@ -0,0 +1 @@ + diff --git a/src/engine/helper/HL_Singletone.h b/src/engine/helper/HL_Singletone.h new file mode 100644 index 00000000..4999236f --- /dev/null +++ b/src/engine/helper/HL_Singletone.h @@ -0,0 +1,38 @@ +#ifndef __HL_SINGLETONE_H +#define __HL_SINGLETONE_H + +#include +#include + +template +class SafeSingleton +{ +protected: + static std::atomic SharedInstance; + static std::mutex mMutex; +public: + static T& instance() + { + T* tmp = SharedInstance.load(std::memory_order_relaxed); + std::atomic_thread_fence(std::memory_order_acquire); + if (tmp == nullptr) + { + std::lock_guard lock(mMutex); + tmp = SharedInstance.load(std::memory_order_relaxed); + if (tmp == nullptr) + { + tmp = new T(); + std::atomic_thread_fence(std::memory_order_release); + SharedInstance.store(tmp, std::memory_order_relaxed); + } + } + return *tmp; + } +}; + +template +std::atomic SafeSingleton::SharedInstance; +template +std::mutex SafeSingleton::mMutex; + +#endif diff --git a/src/engine/helper/HL_SocketHeap.cpp b/src/engine/helper/HL_SocketHeap.cpp new file mode 100644 index 00000000..a03466e0 --- /dev/null +++ b/src/engine/helper/HL_SocketHeap.cpp @@ -0,0 +1,290 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "../config.h" +#ifdef WIN32 +#include +#include +#endif +#include +#include +#include "HL_SocketHeap.h" +#include "HL_Log.h" +#include "HL_Sync.h" +#include "HL_Exception.h" + +#define LOG_SUBSYSTEM "[SocketHeap]" + +#ifndef WIN32 +#define WSAGetLastError(X) errno +#define closesocket(X) close(X) +#define WSAEADDRINUSE EADDRINUSE +#endif + + +// ----------------------------- SocketHeap ------------------------- + +SocketHeap::SocketHeap(unsigned short start, unsigned short finish) +{ + mStart = start; + mFinish = finish; +} + +SocketHeap::~SocketHeap() +{ + stop(); +} + +void SocketHeap::start() +{ +#if defined(USE_RESIP_INTEGRATION) + if (!mId) + run(); +#else +#endif +} + +void SocketHeap::stop() +{ +#if defined(USE_RESIP_INTEGRATION) + if (mId) + { + shutdown(); + // Wait for worker thread + join(); + } +#endif +} + +void SocketHeap::setRange(unsigned short start, unsigned short finish) +{ + assert(mStart <= mFinish); + + Lock l(mGuard); + mStart = start; + mFinish = finish; +} + +void SocketHeap::range(unsigned short &start, unsigned short &finish) +{ + Lock l(mGuard); + + start = mStart; + finish = mFinish; +} + +RtpPair SocketHeap::allocSocketPair(int family, SocketSink *sink, Multiplex m) +{ + PDatagramSocket rtp, rtcp; + for (int attempt=0; (!rtp || !rtcp) && attempt < (mFinish - mStart)/2; attempt++) + { + // Allocate RTP + try + { + rtp = allocSocket(family, sink); + if (m == DoMultiplexing) + rtcp = rtp; + else + rtcp = allocSocket(family, sink, rtp->localport() + 1); + } + catch(...) + {} + } + + if (!rtp || !rtcp) + { + if (rtp) + freeSocket(rtp); + if (rtcp) + freeSocket(rtcp); + throw Exception(ERR_NET_FAILED); + } + ICELogInfo(<< "Allocated socket pair " << (family == AF_INET ? "AF_INET" : "AF_INET6") << " " + << rtp->socket() << ":" << rtcp->socket() + << " at ports " << rtp->localport() << ":"<< rtcp->localport()); + + return RtpPair(rtp, rtcp); +} + +void SocketHeap::freeSocketPair(const RtpPair &p) +{ + freeSocket(p.mRtp); + freeSocket(p.mRtcp); +} + +PDatagramSocket SocketHeap::allocSocket(int family, SocketSink* sink, int port) +{ + Lock l(mGuard); + SOCKET sock = ::socket(family, SOCK_DGRAM, IPPROTO_UDP); + if (sock == INVALID_SOCKET) + { + // Return null socket + PDatagramSocket result(new DatagramSocket()); + result->mLocalPort = port; + result->mFamily = family; + return result; + } + + // Obtain port number + sockaddr_in addr; + sockaddr_in6 addr6; + int result; + int testport; + do + { + testport = port ? port : rand() % ((mFinish - mStart) / 2) * 2 + mStart; + + switch (family) + { + case AF_INET: + memset(&addr, 0, sizeof addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(testport); + result = ::bind(sock, (const sockaddr*)&addr, sizeof addr); + if (result) + result = WSAGetLastError(); + break; + + case AF_INET6: + memset(&addr6, 0, sizeof addr6); + addr6.sin6_family = AF_INET6; + addr6.sin6_port = htons(testport); + result = ::bind(sock, (const sockaddr*)&addr6, sizeof addr6); + if (result) + result = WSAGetLastError(); + break; + } + + } while (result == WSAEADDRINUSE); + + if (result) + { + closesocket(sock); + throw Exception(ERR_NET_FAILED, WSAGetLastError()); + } + PDatagramSocket resultObject(new DatagramSocket()); + resultObject->mLocalPort = testport; + resultObject->mHandle = sock; + if (!resultObject->setBlocking(false)) + { + resultObject->closeSocket(); + throw Exception(ERR_NET_FAILED, WSAGetLastError()); + } + + // Put socket object to the map + mSocketMap[sock].mSink = sink; + mSocketMap[sock].mSocket = resultObject; + + return resultObject; +} + + +void SocketHeap::freeSocket(PDatagramSocket socket) +{ + if (!socket) + return; + + Lock l(mDeleteGuard); + mDeleteVector.push_back(socket); +} + +void SocketHeap::processDeleted() +{ + Lock l(mDeleteGuard); + + SocketVector::iterator socketIter = mDeleteVector.begin(); + while (socketIter != mDeleteVector.end()) + { + // Find socket to delete in main socket map + SocketMap::iterator itemIter = mSocketMap.find((*socketIter)->mHandle); + + if (itemIter != mSocketMap.end()) + { + // If found - delete socket object from map + mSocketMap.erase(itemIter); + } + + socketIter++; + } + + mDeleteVector.clear(); +} + +void SocketHeap::thread() +{ +/*#ifdef __linux__ + // TODO: make epoll implementation for massive polling +#else*/ + while (!isShutdown()) + { + // Define socket agreggator + DatagramAgreggator agreggator; + + // Make a protected copy of sockets + { + Lock l(mGuard); + + // Remove deleted sockets from map and close them + { + processDeleted(); + } + + // Update socket set + for (SocketMap::iterator socketIter = mSocketMap.begin(); socketIter != mSocketMap.end(); ++socketIter) + { + // Add handle to set + agreggator.addSocket(socketIter->second.mSocket); + } + } + + // If set is not empty + if (agreggator.count() > 0) + { + if (agreggator.waitForData(10)) + { + ICELogMedia(<< "There is data on UDP sockets"); + Lock l(mGuard); + + // Remove deleted sockets to avoid call non-existant sinks + processDeleted(); + + for (unsigned i=0; imHandle); + + if (socketItemIter != mSocketMap.end()) + { + InternetAddress src; + unsigned received = sock->recvDatagram(src, mTempPacket, sizeof mTempPacket); + + if ( received > 0 && received <= MAX_VALID_UDPPACKET_SIZE) + socketItemIter->second.mSink->onReceivedData(sock, src, mTempPacket, received); + } + + // There is a call to ProcessDeleted() as OnReceivedData() could delete sockets + processDeleted(); + } + } //of for + } + } + else + SyncHelper::delay(1000); // Delay for 1 millisecond + } + mId = 0; +//#endif +} + + +static SocketHeap GRTPSocketHeap(20002, 25100); +SocketHeap& SocketHeap::instance() +{ + return GRTPSocketHeap; +} diff --git a/src/engine/helper/HL_SocketHeap.h b/src/engine/helper/HL_SocketHeap.h new file mode 100644 index 00000000..82260bc4 --- /dev/null +++ b/src/engine/helper/HL_SocketHeap.h @@ -0,0 +1,114 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __SOCKET_HEAP_H +#define __SOCKET_HEAP_H + +#include "../config.h" +#include +#include +#include + +#ifdef USE_RESIP_INTEGRATION +# include "resiprocate/rutil/ThreadIf.hxx" +#else +# include +#endif + +#include "HL_NetworkSocket.h" +#include "HL_Sync.h" +#include "HL_Rtp.h" + +// Class is used to process incoming datagrams +class SocketSink +{ +public: + virtual void onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr, unsigned receivedSize) = 0; +}; + +// Class allocates new UDP sockets and tracks incoming packets on them. It runs in separate thread +#ifdef USE_RESIP_INTEGRATION +class SocketHeap: public resip::ThreadIf +#else +class SocketHeap: public std::thread +#endif +{ +public: + enum Multiplex + { + DoMultiplexing, + DontMultiplexing + }; + + SocketHeap(unsigned short start, unsigned short finish); + ~SocketHeap(); + + static SocketHeap& instance(); + + void start(); + void stop(); + + // Specifies ne\ port number range. The sockets will be allocated in range [start..finish] + void setRange(unsigned short start, unsigned short finish); + + // Returns used port number range + void range(unsigned short& start, unsigned short& finish); + + // Attempts to allocate and return socket + allocated port number. REQUIRES pointer to data sink - it will be used to process incoming datagrams + PDatagramSocket allocSocket(int family, SocketSink* sink, int port = 0); + RtpPair allocSocketPair(int family, SocketSink* sink, Multiplex m); + + // Stops receiving data for specified socket and frees socket itself. + void freeSocket(PDatagramSocket socket); + void freeSocketPair(const RtpPair& p); + + // Sends data to specified address on specified socket. + void sendData(DatagramSocket& socket, InternetAddress& dest, const void* dataPtr, int dataSize); + +protected: + struct SocketItem + { + // Local port number for socket + PDatagramSocket mSocket; + + // Data sink pointer + SocketSink* mSink; + + SocketItem() + :mSink(NULL) + { } + + SocketItem(unsigned short portnumber, SocketSink* sink) + :mSink(sink) + { + mSocket->mLocalPort = portnumber; + } + + ~SocketItem() + { } + }; + + typedef std::map SocketMap; + typedef std::vector PortVector; + typedef std::vector SocketVector; + + Mutex mGuard; + SocketMap mSocketMap; + PortVector mPortVector; + unsigned short mStart, + mFinish; + SocketVector mDeleteVector; + Mutex mDeleteGuard; + + char mTempPacket[MAX_UDPPACKET_SIZE]; + + virtual void thread(); + + // Processes mDeleteVector -> updates mSocketMap, removes socket items and closes sockets specified in mDeleteVector + void processDeleted(); + +}; + +#endif diff --git a/src/engine/helper/HL_StreamState.h b/src/engine/helper/HL_StreamState.h new file mode 100644 index 00000000..542f7398 --- /dev/null +++ b/src/engine/helper/HL_StreamState.h @@ -0,0 +1,24 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __HL_STREAM_STATE +#define __HL_STREAM_STATE + +// How to use stream state flags. + +enum class StreamState +{ + Sending = 1, // Transmitting RTP. Set this flag to allow outgoing media stream. + Receiving = 2, // Receiving RTP. Set this flag to allow receiving media stream. + Playing = 4, // Play to audio. Unmutes the audio from specified stream. + Grabbing = 8, // Capture audio. Unmutes the audio to specified stream. + Srtp = 16, // Use SRTP. Make attempt + SipSend = 32, // Declare send capability in SDP + SipRecv = 64 // Declare recv capability in SDP +}; + + + +#endif diff --git a/src/engine/helper/HL_String.cpp b/src/engine/helper/HL_String.cpp new file mode 100644 index 00000000..b321fe8e --- /dev/null +++ b/src/engine/helper/HL_String.cpp @@ -0,0 +1,439 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "HL_String.h" +#include +#include +#include +#include + +#ifdef TARGET_WIN +# include +# include +# include +#endif + +std::string StringHelper::extractFilename(const std::string& path) +{ + // Look for separator from end of string + for (int i = path.size() - 1; i >= 0; i--) + { + if (path[i] == '/' || path[i] == '\\') + return path.substr(i+1); + } + return ""; + +} + +std::string StringHelper::makeUtf8(const std::tstring &arg) +{ +#if defined(TARGET_WIN) + size_t required = WideCharToMultiByte(CP_UTF8, 0, arg.c_str(), -1, NULL, 0, NULL, NULL); + char *result = (char*)_alloca(required + 1); + WideCharToMultiByte(CP_UTF8, 0, arg.c_str(), -1, result, required+1, NULL, NULL); + return result; +#else + return arg; +#endif +} + +std::tstring StringHelper::makeTstring(const std::string& arg) +{ +#if defined(TARGET_WIN) + size_t count = MultiByteToWideChar(CP_UTF8, 0, arg.c_str(), -1, NULL, 0); + wchar_t* result = (wchar_t*)_alloca(count * 2); + MultiByteToWideChar(CP_UTF8, 0, arg.c_str(), -1, result, count); + return result; +#else + return arg; +#endif +} + +int StringHelper::toInt(const char *s, int defaultValue, bool* isOk) +{ + int result; + if (sscanf(s, "%d", &result) != 1) + { + if (isOk) + *isOk = false; + result = defaultValue; + } + else + if (isOk) + *isOk = true; + + return result; +} + +uint64_t StringHelper::toUint64(const char* s, uint64_t def, bool *isOk) +{ + uint64_t result = def; +#if defined(TARGET_WIN) + if (sscanf(s, "%d", &result) != 1) +#else + if (sscanf(s, "%llu", &result) != 1) +#endif + { + if (isOk) + *isOk = false; + result = def; + } + else + if (isOk) + *isOk = true; + + return result; +} + +std::string StringHelper::toHex(unsigned int value) +{ + char buffer[32]; + sprintf(buffer, "%x", value); + return buffer; +} + +std::string StringHelper::toHex(const void *ptr) +{ + std::ostringstream oss; + oss << std::hex << ptr; + return oss.str(); +} + +//must be lowercase for MD5 +static const char hexmap[] = "0123456789abcdef"; + +std::string StringHelper::toHex(const uint8_t* input, size_t inputLength) +{ + std::string result; result.resize(inputLength * 2); + + const char* p = (const char*)input; + char* r = &result[0]; + for (size_t i=0; i < inputLength; ++i) + { + unsigned char temp = *p++; + + int hi = (temp & 0xf0)>>4; + int low = (temp & 0xf); + + *r++ = hexmap[hi]; + *r++ = hexmap[low]; + } + *r = 0; + + return result; +} + +std::string StringHelper::prefixLines(const std::string &source, const std::string &prefix) +{ + // Read source line by line + std::istringstream iss(source); + std::ostringstream oss; + std::string line; + while (std::getline(iss,line)) + { + oss << prefix << line << std::endl; + } + return oss.str(); +} + +std::string StringHelper::doubleToString(double value, int precision) +{ + std::stringstream ss; + ss << std::fixed << std::setprecision(precision) << value; + return ss.str(); +} + + +const char* StringHelper::findSubstring(const char* buffer, const char* substring, size_t bufferLength) +{ +#if defined(TARGET_WIN) + return (const char*)strstr(buffer, substring); +#else + return (const char*)memmem(buffer, bufferLength, substring, strlen(substring)); +#endif +} + + +void StringHelper::split(const std::string& src, std::vector& dst, const std::string& delims) +{ + dst.clear(); + std::string::size_type p = 0; + while (p < src.size()) + { + std::string::size_type f = src.find_first_of(delims, p); + if (f == std::string::npos) + { + std::string t = src.substr(p); + if (!t.empty()) + dst.push_back(t); + p = src.size(); + } + else + { + std::string t = src.substr(p, f-p); + if (!t.empty()) + dst.push_back(t); + p = f + 1; + } + } +} + +std::pair StringHelper::parseHost(const std::string& host, int defaultPort) +{ + std::pair result; + std::size_t p = host.find(':'); + if (p != std::string::npos) + { + result.first = host.substr(0, p); + result.second = StringHelper::toInt(host.c_str() + p + 1, defaultPort); + } + else + { + result.first = host; + result.second = defaultPort; + } + return result; +} + +std::pair StringHelper::parseAssignment(const std::string& s, bool trimQuotes) +{ + std::pair result; + + std::string::size_type p = s.find('='); + if (p != std::string::npos) + { + result.first = StringHelper::trim(s.substr(0, p)); + result.second = StringHelper::trim(s.substr(p+1)); + if (trimQuotes && result.second.size() >= 2) + { + if (result.second[0] == '"' && result.second[result.second.size()-1] == '"' || + result.second[0] == '\'' && result.second[result.second.size()-1] == '\'') + result.second = result.second.substr(1, result.second.size() - 2); + } + } + else + result.first = StringHelper::trim(s); + + return result; +} + +std::string StringHelper::intToString(int value) +{ + char buffer[32]; + sprintf(buffer, "%d", value); + return buffer; +} + +float StringHelper::toFloat(const std::string &s, float v, bool* isOk) +{ + float result = 0.0; + int code = sscanf(s.c_str(), "%f", &result); + if (code == 1) + { + if (isOk) + *isOk = true; + } + else + { + result = v; + if (isOk) + *isOk = false; + } + + return result; +} + +std::string StringHelper::trim(const std::string &s) +{ + auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c) { return std::isspace(c); }); + auto wsback = std::find_if_not(s.rbegin(), s.rend(), [](int c) { return std::isspace(c); }).base(); + return (wsback <= wsfront ? std::string() : std::string(wsfront,wsback)); +} + +std::string StringHelper::timeToString(time_t t) +{ + char buffer[96]; + struct tm lt; +#if defined(TARGET_LINUX) || defined(TARGET_OSX) || defined(TARGET_ANDROID) + localtime_r(&t, <); +#else + lt = *localtime(&t); +#endif + strftime(buffer, sizeof(buffer)-1, "%Y-%m-%d %H:%M:%S", <); + return buffer; +} + +std::string StringHelper::millisecondsToString(uint64_t t) +{ + return timeToString(t/1000); +} + +int StringHelper::fromHex2Int(const std::string &s) +{ + int result = 0; + sscanf(s.c_str(), "%x", &result); + return result; +} + +static int hex2code(char s) +{ + if (s >= '0' && s <= '9') + return s - '0'; + if (s >= 'a' && s <= 'f') + return s - 'a' + 10; + if (s >= 'A' && s <= 'F') + return s - 'A' + 10; + return 0; +} + +static int hex2code(const char* s) +{ + return hex2code(s[0]) << 4 + hex2code(s[1]); +} + +std::string StringHelper::fromHex2String(const std::string& s) +{ + std::string result; result.resize(s.size() / 2); + const char* t = s.c_str(); + for (size_t i = 0; i < result.size(); i++) + result[i] = hex2code(t[i*2]); + + return result; +} + +std::string StringHelper::replace(const std::string& s, char f, char r) +{ + std::string result(s); + for (std::string::size_type i = 0; i < result.size(); i++) + if (result[i] == 'f') + result[i] = r; + + return result; +} + +std::string StringHelper::replace(const std::string& s, const std::string& tmpl, const std::string& n) +{ + std::string result(s); + std::string::size_type p; + while ( (p = result.find(tmpl)) != std::string::npos) + { + result.replace(p, tmpl.size(), n); + } + + return result; +} + +std::string StringHelper::decodeUri(const std::string& s) +{ + std::string ret; + ret.reserve(s.size()); + + char ch; + + int i, ii; + for (i=0; i<(int)s.length(); i++) + { + if (s[i] == 37) + { + sscanf(s.substr(i+1,2).c_str(), "%x", &ii); + ch = static_cast(ii); + ret += ch; + i += 2; + } + else + ret += s[i]; + } + return ret; +} + +#define XML_HEADER "" +// --------------------- XcapHelper ----------------- +std::string XcapHelper::buildBuddyList(std::string listName, std::vector buddies) +{ + std::ostringstream result; + result << XML_HEADER << + "" << + ""; + + // to test CT only! + //result << ""; + //result << ""; + + for (unsigned i = 0; i"; + } + result << ""; + return result.str(); +} + +std::string XcapHelper::buildRules(std::vector buddies) +{ + std::ostringstream result; + result << XML_HEADER << + "" << + "" << + ""; + + for (unsigned i = 0; i"; + } + result << "" << + "" << + "" << + "allow" << + "" << + "" << + "" << + "" << + "" << + "" << + "" << + "" << + "" << + "" << + "" << + "" << + "" << + "" << + ""; + return result.str(); +} + +std::string XcapHelper::buildServices(std::string serviceUri, std::string listRef) +{ + std::ostringstream result; + + result << "" << std::endl << + "" << std::endl << + "" << std::endl << + "" << listRef.c_str() << "" << std::endl << + "" << std::endl << + "presence" << std::endl << + "" << std::endl << + "" << std::endl << + ""; + + return result.str(); +} + +std::string XcapHelper::normalizeSipUri(std::string uri) +{ + if (uri.length()) + { + if (uri[0] == '<') + uri.erase(0,1); + if (uri.length()) + { + if (uri[uri.length()-1] == '>') + uri.erase(uri.length()-1, 1); + } + } + return uri; +} diff --git a/src/engine/helper/HL_String.h b/src/engine/helper/HL_String.h new file mode 100644 index 00000000..63c091a1 --- /dev/null +++ b/src/engine/helper/HL_String.h @@ -0,0 +1,73 @@ +/* Copyright(C) 2007-2018 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __HELPER_STRING_H +#define __HELPER_STRING_H + +#include +#include +#include +#include "HL_Types.h" + +#ifdef TARGET_OSX +#define stricmp strcasecmp +#endif + + +class StringHelper +{ +public: + static std::string extractFilename(const std::string& path); + static std::string makeUtf8(const std::tstring& arg); + static std::tstring makeTstring(const std::string& arg); + static int toInt(const char* s, int defaultValue, bool* isOk = nullptr); + static uint64_t toUint64(const char* s, uint64_t def, bool *isOk = nullptr); + static std::string toHex(unsigned int value); + static std::string toHex(const void* ptr); + static std::string toHex(const uint8_t* input, size_t inputLength); + static std::string intToString(int value); + static std::string prefixLines(const std::string& source, const std::string& prefix); + static std::string doubleToString(double value, int precision); + + static const char* findSubstring(const char* buffer, const char* substring, size_t bufferLength); + static void split(const std::string& src, std::vector& dst, const std::string& delims); + + template + static std::string join(const std::vector& v, const std::string& delimiter) + { + std::ostringstream s; + for (const auto& i : v) + { + if (&i != &v[0]) + s << delimiter; + s << i; + } + return s.str(); + } + + static std::pair parseHost(const std::string& host, int defaultPort); + static std::pair parseAssignment(const std::string& s, bool trimQuotes = true); + static float toFloat(const std::string& s, float defaultValue = 0.0, bool* isOk = nullptr); + static std::string trim(const std::string& s); + static std::string timeToString(time_t t); + static std::string millisecondsToString(uint64_t t); + static int fromHex2Int(const std::string& s); + static std::string fromHex2String(const std::string& s); + static std::string replace(const std::string& s, char f, char r); + static std::string replace(const std::string& s, const std::string& tmpl, const std::string& n); + static std::string decodeUri(const std::string& s); +}; + +class XcapHelper +{ +public: + static std::string buildBuddyList(std::string listName, std::vector buddies); + static std::string buildRules(std::vector buddies); + static std::string buildServices(std::string serviceUri, std::string listRef); + static std::string normalizeSipUri(std::string uri); +}; + + +#endif diff --git a/src/engine/helper/HL_Sync.cpp b/src/engine/helper/HL_Sync.cpp new file mode 100644 index 00000000..1ae41867 --- /dev/null +++ b/src/engine/helper/HL_Sync.cpp @@ -0,0 +1,86 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "HL_Sync.h" +#include +#include + +#ifdef TARGET_OSX +# include +#endif + +#ifdef TARGET_WIN +# include +#endif + +void SyncHelper::delay(unsigned int microseconds) +{ +#ifdef TARGET_WIN + ::Sleep(microseconds/1000); +#endif +#if defined(TARGET_OSX) || defined(TARGET_LINUX) + timespec requested, remaining; + requested.tv_sec = microseconds / 1000000; + requested.tv_nsec = (microseconds % 1000000) * 1000; + remaining.tv_nsec = 0; + remaining.tv_sec = 0; + nanosleep(&requested, &remaining); +#endif +} + +long SyncHelper::increment(long *value) +{ + assert(value); +#ifdef TARGET_WIN + return ::InterlockedIncrement((LONG*)value); +#elif TARGET_OSX + return OSAtomicIncrement32((int32_t*)value); +#elif TARGET_LINUX + return -1; +#endif +} + +// ------------------- ThreadHelper ------------------- +void ThreadHelper::setName(const std::string &name) +{ +#if defined(TARGET_LINUX) + pthread_setname_np(pthread_self(), name.c_str()); +#endif +} + +// ------------------- TimeHelper --------------- +using namespace std::chrono; + +static uint64_t TimestampStartPoint = duration_cast(steady_clock::now().time_since_epoch()).count(); +static time_t TimestampBase = time(nullptr); + +uint64_t TimeHelper::getTimestamp() +{ + time_point t = steady_clock::now(); + + uint64_t ms = duration_cast< milliseconds >(t.time_since_epoch()).count(); + + return ms - TimestampStartPoint + TimestampBase * 1000; +} + +uint64_t TimeHelper::getUptime() +{ + time_point t = steady_clock::now(); + + uint64_t ms = duration_cast< milliseconds >(t.time_since_epoch()).count(); + + return ms - TimestampStartPoint; +} + +uint32_t TimeHelper::getDelta(uint32_t later, uint32_t earlier) +{ + if (later > earlier) + return later - earlier; + + if (later < earlier && later < 0x7FFFFFFF && earlier >= 0x7FFFFFFF) + return 0xFFFFFFFF - earlier + later; + + return 0; +} diff --git a/src/engine/helper/HL_Sync.h b/src/engine/helper/HL_Sync.h new file mode 100644 index 00000000..d4e5726d --- /dev/null +++ b/src/engine/helper/HL_Sync.h @@ -0,0 +1,80 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __HL_SYNC_H +#define __HL_SYNC_H + +#include +#include +#include +#include + +typedef std::recursive_mutex Mutex; +typedef std::unique_lock Lock; + +class SyncHelper +{ +public: + static void delay(unsigned microseconds); + static long increment(long* value); +}; + +class Semaphore +{ +private: + unsigned int m_uiCount; + std::mutex m_mutex; + std::condition_variable m_condition; + +public: + inline Semaphore(unsigned int uiCount) + : m_uiCount(uiCount) { } + + inline void Wait() + { + std::unique_lock< std::mutex > lock(m_mutex); + m_condition.wait(lock,[&]()->bool{ return m_uiCount>0; }); + --m_uiCount; + } + + template< typename R,typename P > + bool Wait(const std::chrono::duration& crRelTime) + { + std::unique_lock< std::mutex > lock(m_mutex); + if (!m_condition.wait_for(lock,crRelTime,[&]()->bool{ return m_uiCount>0; })) + return false; + --m_uiCount; + return true; + } + + inline void Signal() + { + std::unique_lock< std::mutex > lock(m_mutex); + ++m_uiCount; + m_condition.notify_one(); + } +}; + +class ThreadHelper +{ +public: + static void setName(const std::string& name); +}; + +class TimeHelper +{ +public: + // Returns current timestamp in milliseconds + static uint64_t getTimestamp(); + + // Returns uptime (of calling process) in milliseconds + static uint64_t getUptime(); + + // Finds time delta between 'later' and 'earlier' time points. + // Handles cases when clock is wrapped. + static uint32_t getDelta(uint32_t later, uint32_t earlier); +}; + +#endif diff --git a/src/engine/helper/HL_ThreadPool.h b/src/engine/helper/HL_ThreadPool.h new file mode 100644 index 00000000..ddde688a --- /dev/null +++ b/src/engine/helper/HL_ThreadPool.h @@ -0,0 +1,98 @@ +#ifndef __HL_THREAD_POOL_H +#define __HL_THREAD_POOL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class ThreadPool { +public: + ThreadPool(size_t); + template + auto enqueue(F&& f, Args&&... args) + -> std::future::type>; + ~ThreadPool(); +private: + // need to keep track of threads so we can join them + std::vector< std::thread > workers; + // the task queue + std::queue< std::function > tasks; + + // synchronization + std::mutex queue_mutex; + std::condition_variable condition; + bool stop; +}; + +// the constructor just launches some amount of workers +inline ThreadPool::ThreadPool(size_t threads) + : stop(false) +{ + for(size_t i = 0;i task; + + { + std::unique_lock lock(this->queue_mutex); + this->condition.wait(lock, + [this]{ return this->stop || !this->tasks.empty(); }); + if(this->stop && this->tasks.empty()) + return; + task = std::move(this->tasks.front()); + this->tasks.pop(); + } + + task(); + } + } + ); +} + +// add new work item to the pool +template +auto ThreadPool::enqueue(F&& f, Args&&... args) + -> std::future::type> +{ + using return_type = typename std::result_of::type; + + auto task = std::make_shared< std::packaged_task >( + std::bind(std::forward(f), std::forward(args)...) + ); + + std::future res = task->get_future(); + { + std::unique_lock lock(queue_mutex); + + // don't allow enqueueing after stopping the pool + if(stop) + throw std::runtime_error("enqueue on stopped ThreadPool"); + + tasks.emplace([task](){ (*task)(); }); + } + condition.notify_one(); + return res; +} + +// the destructor joins all threads +inline ThreadPool::~ThreadPool() +{ + { + std::unique_lock lock(queue_mutex); + stop = true; + } + condition.notify_all(); + for(std::thread &worker: workers) + worker.join(); +} + +#endif diff --git a/src/engine/helper/HL_Types.h b/src/engine/helper/HL_Types.h new file mode 100644 index 00000000..1f66539b --- /dev/null +++ b/src/engine/helper/HL_Types.h @@ -0,0 +1,29 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __HL_TYPES_H +#define __HL_TYPES_H + +#ifdef WIN32 +# define tstring wstring +# define to_tstring to_wstring +#else +# define tstring string +# define to_tstring to_string +#endif + +#ifdef WIN32 +#define ALLOCA(X) _alloca(X) +#else +#define ALLOCA(X) alloca(X) +#endif + +enum SdpDirection +{ + Sdp_Answer, + Sdp_Offer +}; + +#endif diff --git a/src/engine/helper/HL_Usb.cpp b/src/engine/helper/HL_Usb.cpp new file mode 100644 index 00000000..f474357d --- /dev/null +++ b/src/engine/helper/HL_Usb.cpp @@ -0,0 +1,109 @@ +#include "HL_Usb.h" +#include "HL_Exception.h" +#ifdef TARGET_WIN +#include + +#define ADR_WINDOW_CLASS_NAME L"HIDDEN_USB_CHANGE_DELEGATE_WINDOWCLASS_%u" +#define ADR_WINDOW_NAME L"HIDDEN_USB_CHANGE_DELEGATE_WINDOW_%u" + +UsbChangeListener::UsbChangeListener() +:mNotifyHandle(NULL), mHiddenWindow(NULL), mDelegate(NULL) +{ + wsprintf(mWindowClassName, ADR_WINDOW_CLASS_NAME, (unsigned int)rand()); +} + +UsbChangeListener::~UsbChangeListener() +{ + stop(); +} + +void UsbChangeListener::setDelegate(Delegate* d) +{ + mDelegate = d; +} + +UsbChangeListener::Delegate* UsbChangeListener::getDelegate() const +{ + return mDelegate; +} + +void UsbChangeListener::start() +{ + // Exposing Window to Mixer + WNDCLASSEX wcx; + memset( &wcx, 0, sizeof(WNDCLASSEX) ); + wcx.cbSize = sizeof(WNDCLASSEX); + wcx.lpszClassName = mWindowClassName; + wcx.lpfnWndProc = (WNDPROC)ADRWindowProc; + ::RegisterClassEx(&wcx); + + wchar_t windowname[128]; + wsprintf(windowname, ADR_WINDOW_NAME, rand()); + mHiddenWindow = CreateWindow( mWindowClassName, + windowname, + WS_POPUP | WS_DISABLED, + 0, 0, 0, 0, + NULL, NULL, NULL, NULL ); + if (!mHiddenWindow) + throw Exception(ERR_CREATEWINDOW, GetLastError()); + if (!SetWindowLongPtr(mHiddenWindow, GWLP_USERDATA, (LONG_PTR)this)) + throw Exception(ERR_CREATEWINDOW, GetLastError()); + + // Adjust notification filter + memset(&mNotificationFilter, 0, sizeof(mNotificationFilter)); + + mNotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); + mNotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + + // Register notification + if (!RegisterDeviceNotification(mHiddenWindow, &mNotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES)) + throw Exception(ERR_REGISTERNOTIFICATION, GetLastError()); +} + +LRESULT CALLBACK UsbChangeListener::ADRWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if ( uMsg == WM_DEVICECHANGE ) + { + if (wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE) + { + LONG_PTR l = GetWindowLongPtr(hwnd, GWLP_USERDATA); + if (l) + { + UsbChangeListener* obj = reinterpret_cast(l); + switch (wParam) + { + case DBT_DEVICEARRIVAL: + obj->getDelegate()->onDeviceInsert(NULL); + break; + + case DBT_DEVICEREMOVECOMPLETE: + obj->getDelegate()->onDeviceRemove(NULL); + break; + } + } + } + } + return ::DefWindowProc( hwnd, uMsg, wParam, lParam); +} + + +void UsbChangeListener::stop() +{ + // Unregister + if (mNotifyHandle != NULL) + { + ::UnregisterDeviceNotification(mNotifyHandle); + mNotifyHandle = NULL; + } + + //Destroy the window + if (mHiddenWindow != NULL) + { + ::DestroyWindow(mHiddenWindow); + mHiddenWindow = NULL; + + ::UnregisterClass(mWindowClassName, NULL); + } +} + +#endif \ No newline at end of file diff --git a/src/engine/helper/HL_Usb.h b/src/engine/helper/HL_Usb.h new file mode 100644 index 00000000..81318601 --- /dev/null +++ b/src/engine/helper/HL_Usb.h @@ -0,0 +1,47 @@ +#ifndef __HELPER_USB_H +#define __HELPER_USB_H + +#ifdef TARGET_WIN + +#include +#include +#include + + class UsbChangeListener + { + public: + class Delegate + { + public: + virtual void onDeviceInsert(const wchar_t* name) = 0; + virtual void onDeviceRemove(const wchar_t* name) = 0; + }; + + UsbChangeListener(); + ~UsbChangeListener(); + + void setDelegate(Delegate* d); + Delegate* getDelegate() const; + + void start(); + void stop(); + + protected: + HDEVNOTIFY mNotifyHandle; /// Handle to track notifications about USB insert/removal. + HWND mHiddenWindow; /// Hidden window to receive notifications + DEV_BROADCAST_DEVICEINTERFACE mNotificationFilter; /// Notifications filter + wchar_t mWindowClassName[256]; /// Hidden window class + Delegate* mDelegate; /// Event handler pointer + + /// Hidden window procedure. + /// @param hwnd Window handle + /// @param uMsg Message ID + /// @param wParam First param + /// @param lParam Second param + static LRESULT CALLBACK ADRWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + }; + + +#endif + +#endif \ No newline at end of file diff --git a/src/engine/helper/HL_Uuid.cpp b/src/engine/helper/HL_Uuid.cpp new file mode 100644 index 00000000..b727fa55 --- /dev/null +++ b/src/engine/helper/HL_Uuid.cpp @@ -0,0 +1,67 @@ +#include "HL_Uuid.h" +#include + +Uuid::Uuid() +{ +#if defined(TARGET_WIN) || defined(TARGET_LINUX) || defined(TARGET_OSX) + memset(mUuid, 0, sizeof mUuid); +#endif +} + +Uuid Uuid::generateOne() +{ + Uuid result; +#if defined(TARGET_LINUX) || defined(TARGET_OSX) + uuid_generate(result.mUuid); +#endif +#if defined(TARGET_WIN) + UuidCreate(&result.mUuid); +#endif + + return result; +} + +Uuid Uuid::parse(const std::string &s) +{ + Uuid result; +#if defined(TARGET_LINUX) || defined(TARGET_OSX) + uuid_parse(s.c_str(), result.mUuid); +#endif + +#if defined(TARGET_WIN) + UuidFromStringA((RPC_CSTR)s.c_str(), &result.mUuid); +#endif + return result; +} + +std::string Uuid::toString() const +{ + char buf[64]; +#if defined(TARGET_LINUX) || defined(TARGET_OSX) + uuid_unparse_lower(mUuid, buf); +#endif + +#if defined(TARGET_WIN) + RPC_CSTR s = nullptr; + UuidToStringA(&mUuid, &s); + if (s) + { + strcpy(buf, (const char*)s); + RpcStringFreeA(&s); + s = nullptr; + } +#endif + + return buf; +} + +bool Uuid::operator < (const Uuid& right) const +{ +#if defined(TARGET_LINUX) || defined(TARGET_OSX) + return memcmp(mUuid, right.mUuid, sizeof(mUuid)) < 0; +#endif + +#if defined(TARGET_WIN) + return memcmp(&mUuid, &right.mUuid, sizeof(mUuid)) < 0; +#endif +} diff --git a/src/engine/helper/HL_Uuid.h b/src/engine/helper/HL_Uuid.h new file mode 100644 index 00000000..8d977bb9 --- /dev/null +++ b/src/engine/helper/HL_Uuid.h @@ -0,0 +1,35 @@ +#ifndef __HL_UUID_H +#define __HL_UUID_H + +#include + +#if defined(TARGET_LINUX) || defined(TARGET_OSX) +# include +#endif +#if defined(TARGET_WIN) +# include +#endif + +class Uuid +{ +public: + Uuid(); + static Uuid generateOne(); + static Uuid parse(const std::string& s); + std::string toString() const; + bool operator < (const Uuid& right) const; + +protected: +#if defined(TARGET_LINUX) || defined(TARGET_OSX) + uuid_t mUuid; +#endif +#if defined(TARGET_WIN) + UUID mUuid; +#endif +#if defined(TARGET_ANDROID) + // Stub only +#endif +}; + + +#endif diff --git a/src/engine/helper/HL_VariantMap.cpp b/src/engine/helper/HL_VariantMap.cpp new file mode 100644 index 00000000..86b41ac7 --- /dev/null +++ b/src/engine/helper/HL_VariantMap.cpp @@ -0,0 +1,373 @@ +/* Copyright(C) 2007-2017 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "HL_VariantMap.h" +#include "HL_Exception.h" +#include + +#if defined(TARGET_ANDROID) +# define __STDC_FORMAT_MACROS +#endif + +#include +#include + +Variant::Variant() +{ + mType = VTYPE_INT; + mInt = 0; + mInt64 = 0; + mBool = 0; + mFloat = 0; + + mPointer = NULL; +} + +Variant::~Variant() +{ +} + +Variant::Variant(bool value) + :mType(VTYPE_BOOL), mBool(value) +{} + +Variant::Variant(int value) + :mType(VTYPE_INT), mInt(value) +{} + +Variant::Variant(int64_t value) + :mType(VTYPE_INT64), mInt64(value) +{} + +Variant::Variant(float value) + :mType(VTYPE_FLOAT), mFloat(value) +{} + +Variant::Variant(double value) + :mType(VTYPE_FLOAT), mFloat((float)value) +{} + +Variant::Variant(const std::string& value) + :mType(VTYPE_STRING), mString(value) +{} + +Variant& Variant::operator = (bool value) +{ + mType = VTYPE_BOOL; + mBool = value; + + return *this; +} + +Variant& Variant::operator = (int value) +{ + mType = VTYPE_INT; + mInt = value; + + return *this; +} + +Variant& Variant::operator = (int64_t value) +{ + mType = VTYPE_INT64; + mInt64 = value; + + return *this; +} + +Variant& Variant::operator = (float value) +{ + mType = VTYPE_FLOAT; + mFloat = value; + + return *this; +} + +Variant& Variant::operator = (const std::string& value) +{ + mType = VTYPE_STRING; + mString = value; + + return *this; +} + +Variant& Variant::operator = (const char* value) +{ + mType = VTYPE_STRING; + mString = value; + + return *this; +} + +Variant& Variant::operator = (void* value) +{ + mType = VTYPE_POINTER; + mPointer = value; + + return *this; +} + +Variant& Variant::operator = (PVariantMap map) +{ + mType = VTYPE_VMAP; + mVMap = map; + + return *this; +} + +Variant Variant::operator + (const Variant& rhs) +{ + switch (type()) + { + case VTYPE_BOOL: + case VTYPE_INT: return asInt() + rhs.asInt(); + case VTYPE_INT64: return asInt64() + rhs.asInt64(); + case VTYPE_FLOAT: return asFloat() + rhs.asFloat(); + case VTYPE_STRING: return asStdString() + rhs.asStdString(); + default: + return false; + } +} + +Variant Variant::operator - (const Variant& rhs) +{ + switch (type()) + { + case VTYPE_BOOL: + case VTYPE_STRING: + case VTYPE_INT: return asInt() - rhs.asInt(); + case VTYPE_INT64: return asInt64() - rhs.asInt64(); + case VTYPE_FLOAT: return asFloat() - rhs.asFloat(); + + default: + return false; + } +} + +Variant Variant::operator * (const Variant& rhs) +{ + switch (type()) + { + case VTYPE_BOOL: + case VTYPE_STRING: + case VTYPE_INT: return asInt() * rhs.asInt(); + case VTYPE_INT64: return asInt64() * rhs.asInt64(); + case VTYPE_FLOAT: return asFloat() * rhs.asFloat(); + default: + return false; + } +} + +Variant Variant::operator / (const Variant& rhs) +{ + switch (type()) + { + case VTYPE_BOOL: + case VTYPE_STRING: + case VTYPE_INT: return asInt() / rhs.asInt(); + case VTYPE_INT64: return asInt64() / rhs.asInt64(); + case VTYPE_FLOAT: return asFloat() / rhs.asFloat(); + + default: + return false; + } +} + +bool Variant::operator < (const Variant& rhs) const +{ + switch (type()) + { + case VTYPE_STRING: return asStdString() < rhs.asStdString(); + case VTYPE_BOOL: + case VTYPE_INT: return asInt() < rhs.asInt(); + case VTYPE_INT64: return asInt64() < rhs.asInt64(); + case VTYPE_FLOAT: return asFloat() < rhs.asFloat(); + default: + return false; + } +} + +bool Variant::operator > (const Variant& rhs) const +{ + return !(*this == rhs) && !(*this < rhs); +} + +bool Variant::operator == (const Variant& rhs) const +{ + switch (type()) + { + case VTYPE_STRING: return asStdString() == rhs.asStdString(); + case VTYPE_BOOL: return asBool() == rhs.asBool(); + case VTYPE_INT: return asInt() == rhs.asInt(); + case VTYPE_INT64: return asInt64() == rhs.asInt64(); + case VTYPE_FLOAT: return asFloat() == rhs.asFloat(); + case VTYPE_POINTER: return asPointer() == rhs.asPointer(); + case VTYPE_VMAP: assert(0); break; + default: + return false; + } +} + +bool Variant::operator != (const Variant& rhs) const +{ + return !(*this == rhs); +} + +bool Variant::operator <= (const Variant& rhs) const +{ + return (*this < rhs) || (*this == rhs); +} + +bool Variant::operator >= (const Variant& rhs) const +{ + return (*this > rhs) || (*this == rhs); +} + +int Variant::asInt() const +{ + if (mType != VTYPE_INT) + throw Exception(ERR_BAD_VARIANT_TYPE); + + return mInt; +} + +int64_t Variant::asInt64() const +{ + if (mType != VTYPE_INT64) + throw Exception(ERR_BAD_VARIANT_TYPE); + + return mInt; +} + +bool Variant::asBool() const +{ + switch (mType) + { + case VTYPE_INT: + return mInt != 0; + + case VTYPE_INT64: + return mInt64 != 0; + + case VTYPE_BOOL: + return mBool; + + case VTYPE_FLOAT: + return mFloat != 0; + + case VTYPE_STRING: + return mString.length() != 0; + + default: + throw Exception(ERR_BAD_VARIANT_TYPE); + } +} + +float Variant::asFloat() const +{ + switch (mType) + { + case VTYPE_INT: + return (float)mInt; + + case VTYPE_INT64: + return (float)mInt64; + + case VTYPE_FLOAT: + return mFloat; + + default: + throw Exception(ERR_BAD_VARIANT_TYPE); + } +} + + +std::string Variant::asStdString() const +{ + char buffer[32]; + switch (mType) + { + case VTYPE_STRING: + return mString; + + case VTYPE_INT: + sprintf(buffer, "%d", mInt); + return buffer; + + case VTYPE_INT64: + sprintf(buffer, "%" PRId64, mInt64); + return buffer; + + case VTYPE_BOOL: + return mBool ? "true" : "false"; + + case VTYPE_FLOAT: + sprintf(buffer, "%f", mFloat); + return buffer; + + default: + throw Exception(ERR_BAD_VARIANT_TYPE); + } +} + +void* Variant::asPointer() const +{ + switch (mType) + { + case VTYPE_POINTER: + return mPointer; + default: + throw Exception(ERR_BAD_VARIANT_TYPE); + } +} + +PVariantMap Variant::asVMap() +{ + switch (mType) + { + case VTYPE_VMAP: + return mVMap; + default: + throw Exception(ERR_BAD_VARIANT_TYPE); + } +} + +VariantType Variant::type() const +{ + return mType; +} + +VariantMap::VariantMap() +{ +} + +VariantMap::~VariantMap() +{ +} + +bool VariantMap::empty() const +{ + return mData.empty(); +} + +void VariantMap::clear() +{ + mData.clear(); +} + +bool VariantMap::exists(int itemId) const +{ + return mData.find(itemId) != mData.end(); +} + +Variant& VariantMap::operator [](int itemId) +{ + return mData[itemId]; +} + +Variant& VariantMap::at(int itemId) +{ + return mData[itemId]; +} diff --git a/src/engine/helper/HL_VariantMap.h b/src/engine/helper/HL_VariantMap.h new file mode 100644 index 00000000..26827a40 --- /dev/null +++ b/src/engine/helper/HL_VariantMap.h @@ -0,0 +1,99 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __VARIANT_MAP_H +#define __VARIANT_MAP_H + +#include +#include +#include "HL_Pointer.h" + +enum VariantType +{ + VTYPE_BOOL, + VTYPE_INT, + VTYPE_INT64, + VTYPE_FLOAT, + VTYPE_STRING, + VTYPE_POINTER, + VTYPE_VMAP +}; + +class VariantMap; +typedef std::shared_ptr PVariantMap; + +class Variant +{ +public: + Variant(); + ~Variant(); + + Variant(bool value); + Variant(int value); + Variant(int64_t value); + Variant(float value); + Variant(double value); + Variant(const std::string& value); + + Variant& operator = (bool value); + Variant& operator = (int value); + Variant& operator = (int64_t value); + Variant& operator = (float value); + Variant& operator = (const std::string& value); + Variant& operator = (const char* value); + Variant& operator = (void* value); + Variant& operator = (PVariantMap vmap); + + Variant operator + (const Variant& rhs); + Variant operator - (const Variant& rhs); + Variant operator * (const Variant& rhs); + Variant operator / (const Variant& rhs); + bool operator < (const Variant& rhs) const; + bool operator > (const Variant& rhs) const; + bool operator == (const Variant& rhs) const; + bool operator != (const Variant& rhs) const; + bool operator <= (const Variant& rhs) const; + bool operator >= (const Variant& rhs) const; + + int asInt() const; + int64_t asInt64() const; + bool asBool() const; + float asFloat() const ; + std::string asStdString() const; + //const char* asString(); + void* asPointer() const; + + PVariantMap asVMap(); + + VariantType type() const; + +protected: + VariantType mType; + bool mBool; + int mInt; + int64_t mInt64; + float mFloat; + std::string mString; + void* mPointer; + PVariantMap mVMap; +}; + +class VariantMap +{ +public: + VariantMap(); + ~VariantMap(); + + bool empty() const; + void clear(); + bool exists(int itemId) const; + + Variant& operator[](int itemId); + Variant& at(int itemId); +protected: + std::map mData; +}; + +#endif diff --git a/src/engine/media/MT_AmrCodec.cpp b/src/engine/media/MT_AmrCodec.cpp new file mode 100644 index 00000000..71a7c7fd --- /dev/null +++ b/src/engine/media/MT_AmrCodec.cpp @@ -0,0 +1,958 @@ +#include "MT_AmrCodec.h" +#include "../helper/HL_ByteBuffer.h" +#include "../helper/HL_Log.h" +#include "../helper/HL_IuUP.h" + +#define LOG_SUBSYSTEM "AmrCodec" +#ifdef USE_AMR_CODEC +using namespace MT; + + +static const uint8_t amr_block_size[16]={ 13, 14, 16, 18, 20, 21, 27, 32, + 6 , 0 , 0 , 0 , 0 , 0 , 0 , 1 }; + + +/** + * Constant of AMR-NB frame lengths in bytes. + */ +const uint8_t amrnb_framelen[16] = + {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0}; + +/** + * Constant of AMR-NB frame lengths in bits. + */ +const uint16_t amrnb_framelenbits[9] = + {95, 103, 118, 134, 148, 159, 204, 244, 39}; + +/** + * Constant of AMR-NB bitrates. + */ +const uint16_t amrnb_bitrates[8] = + {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200}; + +/** + * Constant of AMR-WB frame lengths in bytes. + */ +const uint8_t amrwb_framelen[16] = + {17, 23, 32, 37, 40, 46, 50, 58, 60, 5, 0, 0, 0, 0, 0, 0}; + +/** + * Constant of AMR-WB frame lengths in bits. + */ +const uint16_t amrwb_framelenbits[10] = + {132, 177, 253, 285, 317, 365, 397, 461, 477, 40}; + +/** + * Constant of AMR-WB bitrates. + */ +const uint16_t amrwb_bitrates[9] = + {6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850}; + + +// Helper routines + +/*static int8_t bitrateToMode(uint16_t bitrate) +{ + int8_t mode = -1; + + switch (bitrate) + { + // AMR NB + case 4750: mode = 0; break; + case 5150: mode = 1; break; + case 5900: mode = 2; break; + case 6700: mode = 3; break; + case 7400: mode = 4; break; + case 7950: mode = 5; break; + case 10200: mode = 6; break; + case 12200: mode = 7; break; + + // AMRWB + case 6600: mode = 0; break; + case 8850: mode = 1; break; + case 12650: mode = 2; break; + case 14250: mode = 3; break; + case 15850: mode = 4; break; + case 18250: mode = 5; break; + case 19850: mode = 6; break; + case 23050: mode = 7; break; + case 23850: mode = 8; break; + } + + return mode; +}*/ + +struct AmrPayloadInfo +{ + const uint8_t* mPayload; + int mPayloadLength; + bool mOctetAligned; + bool mInterleaving; + bool mWideband; + uint64_t mCurrentTimestamp; +}; + + +struct AmrFrame +{ + uint8_t mFrameType; + uint8_t mMode; + bool mGoodQuality; + uint64_t mTimestamp; + std::shared_ptr mData; + uint8_t mSTI; +}; + +struct AmrPayload +{ + uint8_t mCodeModeRequest; + std::vector mFrames; + bool mDiscardPacket; +}; + +// ARM RTP payload has next structure +// Header +// Table of Contents +// Frames +static AmrPayload parseAmrPayload(AmrPayloadInfo& input) +{ + AmrPayload result; + result.mDiscardPacket = false; + + // Wrap incoming data with ByteArray to make bit dequeuing easy + ByteBuffer dataIn(input.mPayload, input.mPayloadLength); + BitReader br(input.mPayload, input.mPayloadLength); + + result.mCodeModeRequest = br.readBits(4); + //ICELogMedia(<< "CMR: " << result.mCodeModeRequest); + + // Consume extra 4 bits for octet aligned profile + if (input.mOctetAligned) + br.readBits(4); + + // Skip interleaving flags for now for octet aligned mode + if (input.mInterleaving && input.mOctetAligned) + br.readBits(8); + + uint8_t SID_FT = input.mWideband ? 9 : 8; + + // Table of contents + uint8_t F, FT, Q; + + do + { + F = br.readBit(); + FT = br.readBits(4); + Q = br.readBit(); + + if (FT > SID_FT && FT < 14) + { + ICELogMedia(<< "Discard corrupted packet"); + // Discard bad packet + result.mDiscardPacket = true; + return result; + } + + // Handle padding for octet alignment + if (input.mOctetAligned) + br.readBits(2); + + AmrFrame frame; + frame.mFrameType = FT; + assert (frame.mFrameType < 10); + frame.mMode = FT < SID_FT ? FT : -1; + frame.mGoodQuality = Q == 1; + frame.mTimestamp = input.mCurrentTimestamp; + + result.mFrames.push_back(frame); + + input.mCurrentTimestamp += input.mWideband ? 320 : 160; + } + while (F != 0); + + for (int frameIndex=0; frameIndex < (int)result.mFrames.size(); frameIndex++) + { + AmrFrame& frame = result.mFrames[frameIndex]; + int bitsLength = input.mWideband ? amrwb_framelenbits[frame.mFrameType] : amrnb_framelenbits[frame.mFrameType]; + int byteLength = input.mWideband ? amrwb_framelen[frame.mFrameType] : amrnb_framelen[frame.mFrameType]; + ICELogMedia(<< "New AMR speech frame: frame type = " << FT << ", mode = " << frame.mMode << + ", good quality = " << frame.mGoodQuality << ", timestamp = " << (int)frame.mTimestamp << + ", bits length = " << bitsLength << ", byte length =" << byteLength << + ", remaining packet length = " << (int)dataIn.size() ); + + if (bitsLength > 0) + { + if (input.mOctetAligned) + { + if ((int)dataIn.size() < byteLength) + { + frame.mGoodQuality = false; + } + else + { + // It is octet aligned scheme, so we are on byte boundary now + int byteOffset = br.count() / 8; + + // Copy data of AMR frame + frame.mData = std::make_shared(input.mPayload + byteOffset, byteLength); + } + } + else + { + // Allocate place for copying + frame.mData = std::make_shared(); + frame.mData->resize(bitsLength / 8 + ((bitsLength % 8) ? 1 : 0) + 1); + + // Add header for decoder + frame.mData->mutableData()[0] = (frame.mFrameType << 3) | (1 << 2); + + // Read bits + if (br.readBits(frame.mData->mutableData() + 1, bitsLength /*+ bitsLength*/ ) < (size_t)bitsLength) + frame.mGoodQuality = false; + } + } + } + // Padding bits are skipped + + if (br.count() / 8 != br.position() / 8 && + br.count() / 8 != br.position() / 8 + 1) + throw std::runtime_error("Failed to parse AMR frame"); +} + +/*static void predecodeAmrFrame(AmrFrame& frame, ByteBuffer& data) +{ + // Data are already moved into +}*/ + +AmrNbCodec::CodecFactory::CodecFactory(const AmrCodecConfig& config) + :mConfig(config) +{ + +} + +const char* AmrNbCodec::CodecFactory::name() +{ + return MT_AMRNB_CODECNAME; +} + +int AmrNbCodec::CodecFactory::samplerate() +{ + return 8000; +} + +int AmrNbCodec::CodecFactory::payloadType() +{ + return mConfig.mPayloadType; +} + +#ifdef USE_RESIP_INTEGRATION + +void AmrNbCodec::CodecFactory::updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) +{ + +} + +int AmrNbCodec::CodecFactory::processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) +{ + return 0; +} + +void AmrNbCodec::CodecFactory::create(CodecMap& codecs) +{ + codecs[payloadType()] = std::shared_ptr(new AmrNbCodec(mConfig)); +} + +#endif +PCodec AmrNbCodec::CodecFactory::create() +{ + return PCodec(new AmrNbCodec(mConfig)); +} + + +AmrNbCodec::AmrNbCodec(const AmrCodecConfig& config) + :mEncoderCtx(nullptr), mDecoderCtx(nullptr), mConfig(config), mCurrentDecoderTimestamp(0), + mSwitchCounter(0), mPreviousPacketLength(0) +{ + mEncoderCtx = Encoder_Interface_init(1); + mDecoderCtx = Decoder_Interface_init(); +} + +AmrNbCodec::~AmrNbCodec() +{ + if (mEncoderCtx) + { + Encoder_Interface_exit(mEncoderCtx); + mEncoderCtx = nullptr; + } + + if (mDecoderCtx) + { + Decoder_Interface_exit(mDecoderCtx); + mDecoderCtx = nullptr; + } +} + +const char* AmrNbCodec::name() +{ + return MT_AMRNB_CODECNAME; +} + +int AmrNbCodec::pcmLength() +{ + return 20 * 16; +} + +int AmrNbCodec::rtpLength() +{ + return 0; +} + +int AmrNbCodec::frameTime() +{ + return 20; +} + +int AmrNbCodec::samplerate() +{ + return 8000; +} + +int AmrNbCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + if (inputBytes % pcmLength()) + return 0; + + // Declare the data input pointer + const short *dataIn = (const short *)input; + + // Declare the data output pointer + unsigned char *dataOut = (unsigned char *)output; + + // Find how much RTP frames will be generated + unsigned int frames = inputBytes / pcmLength(); + + // Generate frames + for (unsigned int i = 0; i < frames; i++) + { + dataOut += Encoder_Interface_Encode(mEncoderCtx, Mode::MRDTX, dataIn, dataOut, 1); + dataIn += pcmLength() / 2; + } + + return frames * rtpLength(); +} + +#define L_FRAME 160 +#define AMR_BITRATE_DTX 15 +int AmrNbCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + if (mConfig.mIuUP) + { + // Try to parse IuUP frame + IuUP::Frame frame; + if (!IuUP::parse2((const uint8_t*)input, inputBytes, frame)) + return 0; + + // Check if CRC failed - it is check from IuUP data + if (!frame.mHeaderCrcOk || !frame.mPayloadCrcOk) + { + ICELogInfo(<< "CRC check failed."); + return 0; + } + + // Build NB frame to decode + ByteBuffer dataToDecode; + dataToDecode.resize(1 + frame.mPayloadSize); // Reserve place + + // Copy AMR data + memmove(dataToDecode.mutableData() + 1, frame.mPayload, frame.mPayloadSize); + + uint8_t frameType = 0xFF; + for (uint8_t ftIndex = 0; ftIndex <= 9 && frameType == 0xFF; ftIndex++) + if (amrnb_framelen[ftIndex] == frame.mPayloadSize) + frameType = ftIndex; + + // Check if frameType comparing is correct + if (frameType == 0xFF) + return 0; + + dataToDecode.mutableData()[0] = (frameType << 3) | (1 << 2); + + Decoder_Interface_Decode(mDecoderCtx, (const unsigned char*)dataToDecode.data(), (short*)output, 0); + return pcmLength(); + } + else + { + if (outputCapacity < pcmLength()) + return 0; + + if (inputBytes == 0) + { // PLC part + unsigned char buffer[32]; + buffer[0] = (AMR_BITRATE_DTX << 3)|4; + Decoder_Interface_Decode(mDecoderCtx, buffer, (short*)output, 0); // Handle missing data + return pcmLength(); + } + + AmrPayloadInfo info; + info.mCurrentTimestamp = mCurrentDecoderTimestamp; + info.mOctetAligned = mConfig.mOctetAligned; + info.mPayload = (const uint8_t*)input; + info.mPayloadLength = inputBytes; + info.mWideband = false; + info.mInterleaving = false; + + AmrPayload ap = parseAmrPayload(info); + + // Save current timestamp + mCurrentDecoderTimestamp = info.mCurrentTimestamp; + + // Check if packet is corrupted + if (ap.mDiscardPacket) + return 0; + + + // Check for output buffer capacity + if (outputCapacity < (int)ap.mFrames.size() * pcmLength()) + return 0; + + if (ap.mFrames.empty()) + { + ICELogCritical(<< "No AMR frames"); + } + short* dataOut = (short*)output; + for (AmrFrame& frame: ap.mFrames) + { + if (frame.mData) + { + // Call decoder + Decoder_Interface_Decode(mDecoderCtx, (const unsigned char*)frame.mData->data(), (short*)dataOut, 0); + dataOut += pcmLength() / 2; + } + } + return pcmLength() * ap.mFrames.size(); + } + + return pcmLength(); +} + +int AmrNbCodec::plc(int lostFrames, void* output, int outputCapacity) +{ + if (outputCapacity < lostFrames * pcmLength()) + return 0; + + short* dataOut = (short*)output; + + for (int i=0; i < lostFrames; i++) + { + unsigned char buffer[32]; + buffer[0] = (AMR_BITRATE_DTX << 3)|4; + Decoder_Interface_Decode(mDecoderCtx, buffer, dataOut, 0); // Handle missing data + dataOut += L_FRAME; + } + + return lostFrames * pcmLength(); +} + +int AmrNbCodec::getSwitchCounter() const +{ + return mSwitchCounter; +} + +// -------- AMR WB codec +AmrWbCodec::CodecFactory::CodecFactory(const AmrCodecConfig& config) + :mConfig(config) +{} + +const char* AmrWbCodec::CodecFactory::name() +{ + return MT_AMRWB_CODECNAME; +} + +int AmrWbCodec::CodecFactory::samplerate() +{ + return 16000; +} + +int AmrWbCodec::CodecFactory::payloadType() +{ + return mConfig.mPayloadType; +} + +#ifdef USE_RESIP_INTEGRATION + +void AmrWbCodec::CodecFactory::updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) +{ + +} + +int AmrWbCodec::CodecFactory::processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) +{ + return 0; +} + +void AmrWbCodec::CodecFactory::create(CodecMap& codecs) +{ + codecs[payloadType()] = std::shared_ptr(new AmrWbCodec(mConfig)); +} + +#endif + +PCodec AmrWbCodec::CodecFactory::create() +{ + return PCodec(new AmrWbCodec(mConfig)); +} + + +AmrWbCodec::AmrWbCodec(const AmrCodecConfig& config) + :mEncoderCtx(nullptr), mDecoderCtx(nullptr), mConfig(config), + mSwitchCounter(0), mPreviousPacketLength(0) +{ + //mEncoderCtx = E_IF_init(); + mDecoderCtx = D_IF_init(); + mCurrentDecoderTimestamp = 0; +} + +AmrWbCodec::~AmrWbCodec() +{ + if (mEncoderCtx) + { + //E_IF_exit(mEncoderCtx); + mEncoderCtx = nullptr; + } + + if (mDecoderCtx) + { + D_IF_exit(mDecoderCtx); + mDecoderCtx = nullptr; + } +} + +const char* AmrWbCodec::name() +{ + return MT_AMRWB_CODECNAME; +} + +int AmrWbCodec::pcmLength() +{ + return 20 * 16 * 2; +} + +int AmrWbCodec::rtpLength() +{ + return 0; // VBR +} + +int AmrWbCodec::frameTime() +{ + return 20; +} + +int AmrWbCodec::samplerate() +{ + return 16000; +} + +int AmrWbCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + if (inputBytes % pcmLength()) + return 0; + + // Declare the data input pointer + const short *dataIn = (const short *)input; + + // Declare the data output pointer + unsigned char *dataOut = (unsigned char *)output; + + // Find how much RTP frames will be generated + unsigned int frames = inputBytes / pcmLength(); + + // Generate frames + for (unsigned int i = 0; i < frames; i++) + { + // dataOut += Encoder_Interface_Encode(mEncoderCtx, Mode::MRDTX, dataIn, dataOut, 1); + // dataIn += pcmLength() / 2; + } + + return frames * rtpLength(); +} + +#define L_FRAME 160 +#define AMR_BITRATE_DTX 15 +int AmrWbCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + if (mConfig.mIuUP) + { + IuUP::Frame frame; + if (!IuUP::parse2((const uint8_t*)input, inputBytes, frame)) + return 0; + + if (!frame.mHeaderCrcOk || !frame.mPayloadCrcOk) + { + ICELogInfo(<< "CRC check failed."); + return 0; + } + + // Build first byte to help decoder + //ICELogDebug(<< "Decoding AMR frame length = " << frame.mPayloadSize); + + // Reserve space + ByteBuffer dataToDecode; + dataToDecode.resize(1 + frame.mPayloadSize); + + // Copy AMR data + memmove(dataToDecode.mutableData() + 1, frame.mPayload, frame.mPayloadSize); + uint8_t frameType = 0xFF; + for (uint8_t ftIndex = 0; ftIndex <= 9 && frameType == 0xFF; ftIndex++) + if (amrwb_framelen[ftIndex] == frame.mPayloadSize) + frameType = ftIndex; + + if (frameType == 0xFF) + return 0; + + dataToDecode.mutableData()[0] = (frameType << 3) | (1 << 2); + + D_IF_decode(mDecoderCtx, (const unsigned char*)dataToDecode.data(), (short*)output, 0); + return pcmLength(); + } + else + { + AmrPayloadInfo info; + info.mCurrentTimestamp = mCurrentDecoderTimestamp; + info.mOctetAligned = mConfig.mOctetAligned; + info.mPayload = (const uint8_t*)input; + info.mPayloadLength = inputBytes; + info.mWideband = true; + info.mInterleaving = false; + + AmrPayload ap = parseAmrPayload(info); + + // Save current timestamp + mCurrentDecoderTimestamp = info.mCurrentTimestamp; + + // Check if packet is corrupted + if (ap.mDiscardPacket) + return 0; + + // Check for output buffer capacity + if (outputCapacity < (int)ap.mFrames.size() * pcmLength()) + return 0; + + short* dataOut = (short*)output; + for (AmrFrame& frame: ap.mFrames) + { + if (frame.mData) + { + D_IF_decode(mDecoderCtx, (const unsigned char*)frame.mData->data(), (short*)dataOut, 0); + dataOut += pcmLength() / 2; + } + } + return pcmLength() * ap.mFrames.size(); + } + + return 0; +} + +int AmrWbCodec::plc(int lostFrames, void* output, int outputCapacity) +{ +/* if (outputCapacity < lostFrames * pcmLength()) + return 0; + + short* dataOut = (short*)output; + + for (int i=0; i < lostFrames; i++) + { + unsigned char buffer[32]; + buffer[0] = (AMR_BITRATE_DTX << 3)|4; + Decoder_Interface_Decode(mDecoderCtx, buffer, dataOut, 0); // Handle missing data + dataOut += L_FRAME; + } + */ + return lostFrames * pcmLength(); +} + +int AmrWbCodec::getSwitchCounter() const +{ + return mSwitchCounter; +} + + +// ------------- GSM EFR ----------------- + +GsmEfrCodec::GsmEfrFactory::GsmEfrFactory(bool iuup, int ptype) + :mIuUP(iuup), mPayloadType(ptype) +{ + +} + +const char* GsmEfrCodec::GsmEfrFactory::name() +{ + return MT_GSMEFR_CODECNAME; +} + +int GsmEfrCodec::GsmEfrFactory::samplerate() +{ + return 8000; +} + +int GsmEfrCodec::GsmEfrFactory::payloadType() +{ + return mPayloadType; +} + +#ifdef USE_RESIP_INTEGRATION + +void GsmEfrCodec::GsmEfrFactory::updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) +{ + +} + +int GsmEfrCodec::GsmEfrFactory::processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) +{ + return 0; +} + +void GsmEfrCodec::GsmEfrFactory::create(CodecMap& codecs) +{ + codecs[payloadType()] = std::shared_ptr(new GsmEfrCodec(mIuUP)); +} + +#endif + +PCodec GsmEfrCodec::GsmEfrFactory::create() +{ + return PCodec(new GsmEfrCodec(mIuUP)); +} + +GsmEfrCodec::GsmEfrCodec(bool iuup) + :mEncoderCtx(nullptr), mDecoderCtx(nullptr), mIuUP(iuup) +{ + mEncoderCtx = Encoder_Interface_init(1); + mDecoderCtx = Decoder_Interface_init(); +} + +GsmEfrCodec::~GsmEfrCodec() +{ + if (mEncoderCtx) + { + Encoder_Interface_exit(mEncoderCtx); + mEncoderCtx = nullptr; + } + + if (mDecoderCtx) + { + Decoder_Interface_exit(mDecoderCtx); + mDecoderCtx = nullptr; + } +} + +const char* GsmEfrCodec::name() +{ + return MT_GSMEFR_CODECNAME; +} + +int GsmEfrCodec::pcmLength() +{ + return 20 * 16; +} + +int GsmEfrCodec::rtpLength() +{ + return 0; +} + +int GsmEfrCodec::frameTime() +{ + return 20; +} + +int GsmEfrCodec::samplerate() +{ + return 8000; +} + +int GsmEfrCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + if (inputBytes % pcmLength()) + return 0; + + // Declare the data input pointer + const short *dataIn = (const short *)input; + + // Declare the data output pointer + unsigned char *dataOut = (unsigned char *)output; + + // Find how much RTP frames will be generated + unsigned int frames = inputBytes / pcmLength(); + + // Generate frames + for (unsigned int i = 0; i < frames; i++) + { + dataOut += Encoder_Interface_Encode(mEncoderCtx, Mode::MRDTX, dataIn, dataOut, 1); + dataIn += pcmLength() / 2; + } + + return frames * rtpLength(); +} + +#define L_FRAME 160 +#define AMR_BITRATE_DTX 15 +#define GSM_EFR_SAMPLES 160 +#define GSM_EFR_FRAME_LEN 31 + +static void +msb_put_bit(uint8_t *buf, int bn, int bit) +{ + int pos_byte = bn >> 3; + int pos_bit = 7 - (bn & 7); + + if (bit) + buf[pos_byte] |= (1 << pos_bit); + else + buf[pos_byte] &= ~(1 << pos_bit); +} + +static int +msb_get_bit(const uint8_t *buf, int bn) +{ + int pos_byte = bn >> 3; + int pos_bit = 7 - (bn & 7); + + return (buf[pos_byte] >> pos_bit) & 1; +} + +const uint16_t gsm690_12_2_bitorder[244] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 23, 15, 16, 17, 18, + 19, 20, 21, 22, 24, 25, 26, 27, 28, 38, + 141, 39, 142, 40, 143, 41, 144, 42, 145, 43, + 146, 44, 147, 45, 148, 46, 149, 47, 97, 150, + 200, 48, 98, 151, 201, 49, 99, 152, 202, 86, + 136, 189, 239, 87, 137, 190, 240, 88, 138, 191, + 241, 91, 194, 92, 195, 93, 196, 94, 197, 95, + 198, 29, 30, 31, 32, 33, 34, 35, 50, 100, + 153, 203, 89, 139, 192, 242, 51, 101, 154, 204, + 55, 105, 158, 208, 90, 140, 193, 243, 59, 109, + 162, 212, 63, 113, 166, 216, 67, 117, 170, 220, + 36, 37, 54, 53, 52, 58, 57, 56, 62, 61, + 60, 66, 65, 64, 70, 69, 68, 104, 103, 102, + 108, 107, 106, 112, 111, 110, 116, 115, 114, 120, + 119, 118, 157, 156, 155, 161, 160, 159, 165, 164, + 163, 169, 168, 167, 173, 172, 171, 207, 206, 205, + 211, 210, 209, 215, 214, 213, 219, 218, 217, 223, + 222, 221, 73, 72, 71, 76, 75, 74, 79, 78, + 77, 82, 81, 80, 85, 84, 83, 123, 122, 121, + 126, 125, 124, 129, 128, 127, 132, 131, 130, 135, + 134, 133, 176, 175, 174, 179, 178, 177, 182, 181, + 180, 185, 184, 183, 188, 187, 186, 226, 225, 224, + 229, 228, 227, 232, 231, 230, 235, 234, 233, 238, + 237, 236, 96, 199, +}; + +int GsmEfrCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity) +{ +/* if (mIuUP) + { + // Try to parse IuUP frame + IuUP::Frame frame; + if (!IuUP::parse2((const uint8_t*)input, inputBytes, frame)) + return 0; + + // Check if CRC failed - it is check from IuUP data + if (!frame.mHeaderCrcOk || !frame.mPayloadCrcOk) + { + ICELogInfo(<< "CRC check failed."); + return 0; + } + + // Build NB frame to decode + ByteBuffer dataToDecode; + dataToDecode.resize(1 + frame.mPayloadSize); // Reserve place + + // Copy AMR data + memmove(dataToDecode.mutableData() + 1, frame.mPayload, frame.mPayloadSize); + + uint8_t frameType = 0xFF; + for (uint8_t ftIndex = 0; ftIndex <= 9 && frameType == 0xFF; ftIndex++) + if (amrnb_framelen[ftIndex] == frame.mPayloadSize) + frameType = ftIndex; + + // Check if frameType comparing is correct + if (frameType == 0xFF) + return 0; + + dataToDecode.mutableData()[0] = (frameType << 3) | (1 << 2); + + Decoder_Interface_Decode(mDecoderCtx, (const unsigned char*)dataToDecode.data(), (short*)output, 0); + return pcmLength(); + } + else */ + { + if (outputCapacity < pcmLength()) + return 0; + + if (inputBytes == 0) + { // PLC part + unsigned char buffer[32]; + buffer[0] = (AMR_BITRATE_DTX << 3)|4; + Decoder_Interface_Decode(mDecoderCtx, buffer, (short*)output, 0); // Handle missing data + } + else + { + // Reorder bytes from input to dst + uint8_t dst[GSM_EFR_FRAME_LEN]; + const uint8_t* src = (const uint8_t*)input; + for (int i=0; i<(GSM_EFR_FRAME_LEN-1); i++) + dst[i] = (src[i] << 4) | (src[i+1] >> 4); + dst[GSM_EFR_FRAME_LEN-1] = src[GSM_EFR_FRAME_LEN-1] << 4; + + unsigned char in[GSM_EFR_FRAME_LEN + 1]; + + // Reorder bits + in[0] = 0x3c; /* AMR mode 7 = GSM-EFR, Quality bit is set */ + in[GSM_EFR_FRAME_LEN] = 0x0; + + for (int i=0; i<244; i++) + { + int si = gsm690_12_2_bitorder[i]; + int di = i; + msb_put_bit(in + 1, di, msb_get_bit(dst, si)); + } + + // Decode + memset(output, 0, pcmLength()); + Decoder_Interface_Decode(mDecoderCtx, in, (short*)output, 0); + + + uint8_t* pcm = (uint8_t*)output; + for (int i=0; i<160; i++) + { + uint16_t w = ((uint16_t*)output)[i]; + pcm[(i<<1) ] = w & 0xff; + pcm[(i<<1)+1] = (w >> 8) & 0xff; + } + } + } + + return pcmLength(); +} + +int GsmEfrCodec::plc(int lostFrames, void* output, int outputCapacity) +{ + if (outputCapacity < lostFrames * pcmLength()) + return 0; + + short* dataOut = (short*)output; + + for (int i=0; i < lostFrames; i++) + { + unsigned char buffer[32]; + buffer[0] = (AMR_BITRATE_DTX << 3)|4; + Decoder_Interface_Decode(mDecoderCtx, buffer, dataOut, 0); // Handle missing data + dataOut += L_FRAME; + } + + return lostFrames * pcmLength(); +} + + +#endif diff --git a/src/engine/media/MT_AmrCodec.h b/src/engine/media/MT_AmrCodec.h new file mode 100644 index 00000000..22fb49af --- /dev/null +++ b/src/engine/media/MT_AmrCodec.h @@ -0,0 +1,162 @@ +#ifndef MT_AMRCODEC_H +#define MT_AMRCODEC_H + +#include "../config.h" +#include +#include "MT_Codec.h" +#include "../helper/HL_Pointer.h" + +#if defined(USE_AMR_CODEC) +# include "opencore-amr/amrnb/interf_enc.h" +# include "opencore-amr/amrnb/interf_dec.h" + +# include "opencore-amr/amrwb/if_rom.h" +# include "opencore-amr/amrwb/dec_if.h" + +namespace MT +{ + struct AmrCodecConfig + { + bool mIuUP; + bool mOctetAligned; + int mPayloadType; + }; + + class AmrNbCodec : public Codec + { + protected: + void* mEncoderCtx; + void* mDecoderCtx; + AmrCodecConfig mConfig; + unsigned mCurrentDecoderTimestamp; + int mSwitchCounter; + int mPreviousPacketLength; + + public: + class CodecFactory: public Factory + { + public: + CodecFactory(const AmrCodecConfig& config); + + const char* name() override; + int samplerate() override; + int payloadType() override; + +#ifdef USE_RESIP_INTEGRATION + void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override; + int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override; + void create(CodecMap& codecs) override; +#endif + PCodec create() override; + + protected: + AmrCodecConfig mConfig; + }; + + AmrNbCodec(const AmrCodecConfig& config); + + virtual ~AmrNbCodec(); + const char* name() override; + int pcmLength() override; + int rtpLength() override; + int frameTime() override; + int samplerate() override; + int encode(const void* input, int inputBytes, void* output, int outputCapacity) override; + int decode(const void* input, int inputBytes, void* output, int outputCapacity) override; + int plc(int lostFrames, void* output, int outputCapacity) override; + int getSwitchCounter() const; + }; + + class AmrWbCodec : public Codec + { + protected: + void* mEncoderCtx; + void* mDecoderCtx; + AmrCodecConfig mConfig; + uint64_t mCurrentDecoderTimestamp; + int mSwitchCounter; + int mPreviousPacketLength; + + public: + class CodecFactory: public Factory + { + public: + CodecFactory(const AmrCodecConfig& config); + + const char* name() override; + int samplerate() override; + int payloadType() override; + +#ifdef USE_RESIP_INTEGRATION + void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override; + int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override; + void create(CodecMap& codecs) override; +#endif + PCodec create() override; + + protected: + AmrCodecConfig mConfig; + }; + + AmrWbCodec(const AmrCodecConfig& config); + virtual ~AmrWbCodec(); + + const char* name() override; + int pcmLength() override; + int rtpLength() override; + int frameTime() override; + int samplerate() override; + int encode(const void* input, int inputBytes, void* output, int outputCapacity) override; + int decode(const void* input, int inputBytes, void* output, int outputCapacity) override; + int plc(int lostFrames, void* output, int outputCapacity) override; + int getSwitchCounter() const; + }; + + class GsmEfrCodec : public Codec + { + protected: + void* mEncoderCtx; + void* mDecoderCtx; + bool mIuUP; + + public: + class GsmEfrFactory: public Factory + { + public: + GsmEfrFactory(bool iuup, int ptype); + + const char* name() override; + int samplerate() override; + int payloadType() override; + +#ifdef USE_RESIP_INTEGRATION + void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override; + int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override; + void create(CodecMap& codecs) override; +#endif + PCodec create() override; + + protected: + bool mIuUP; + int mPayloadType; + }; + + GsmEfrCodec(bool iuup = false); + + virtual ~GsmEfrCodec(); + const char* name() override; + int pcmLength() override; + int rtpLength() override; + int frameTime() override; + int samplerate() override; + int encode(const void* input, int inputBytes, void* output, int outputCapacity) override; + int decode(const void* input, int inputBytes, void* output, int outputCapacity) override; + int plc(int lostFrames, void* output, int outputCapacity) override; + }; + +} // End of MT namespace + +#endif + +#endif // MT_AMRCODEC_H + diff --git a/src/engine/media/MT_AudioCodec.cpp b/src/engine/media/MT_AudioCodec.cpp new file mode 100644 index 00000000..cab9993e --- /dev/null +++ b/src/engine/media/MT_AudioCodec.cpp @@ -0,0 +1,1433 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "../config.h" +#include "MT_AudioCodec.h" +#include "MT_CodecList.h" +#include "../helper/HL_Exception.h" +#include "../helper/HL_Types.h" +#include "../helper/HL_String.h" +#include "../helper/HL_Log.h" +#include "../helper/HL_ByteBuffer.h" +#include "../helper/HL_Pointer.h" +#include "../gsmhr/gsmhr.h" + +#include "libg729/g729_pre_proc.h" +#include "libg729/g729_util.h" +#include "libg729/g729_ld8a.h" + +#include +#include +#include +#include +#include + +#define LOG_SUBSYSTEM "Codec" + +#ifdef TARGET_LINUX +# define stricmp strcasecmp +#endif + +using namespace MT; + + +// ------------ G729Codec ---------------- + +const char* G729Codec::G729Factory::name() +{ + return "G729"; +} + +int G729Codec::G729Factory::channels() +{ + return 1; +} + +int G729Codec::G729Factory::samplerate() +{ + return 8000; +} + +int G729Codec::G729Factory::payloadType() +{ + return 18; +} + +#if defined(USE_RESIP_INTEGRATION) +void G729Codec::G729Factory::updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) +{ +} + +int G729Codec::G729Factory::processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) +{ + return 0; +} + +#endif + +PCodec G729Codec::G729Factory::create() +{ + return std::make_shared(); +} + +G729Codec::G729Codec() + :mEncoder(nullptr), mDecoder(nullptr) +{ +} + +G729Codec::~G729Codec() +{ + if (mEncoder) + { + free(mEncoder); + mEncoder = nullptr; + } + + if (mDecoder) + { + free(mDecoder); + mDecoder = nullptr; + } +} + +const char* G729Codec::name() +{ + return "G729"; +} + +int G729Codec::pcmLength() +{ + return 10 * 8 * 2; +} + +int G729Codec::rtpLength() +{ + return 10; +} + +int G729Codec::frameTime() +{ + return 10; +} + +int G729Codec::samplerate() +{ + return 8000; +} + +int G729Codec::channels() +{ + return 1; +} + +static const int SamplesPerFrame = 80; +int G729Codec::encode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + // Create encoder if it is not done yet + if (!mEncoder) + { + mEncoder = Init_Coder_ld8a(); + if (mEncoder) + Init_Pre_Process(mEncoder); + } + int result = 0; + if (mEncoder) + { + int nrOfFrames = inputBytes / 160; // 10ms frames + Word16 parm[PRM_SIZE]; // ITU's service buffer + for (int frameIndex = 0; frameIndex < nrOfFrames; frameIndex++) + { + Copy((int16_t*)input + frameIndex * pcmLength() / 2, mEncoder->new_speech, pcmLength() / 2); + Pre_Process(mEncoder, mEncoder->new_speech, pcmLength() / 2); + Coder_ld8a(mEncoder, parm); + Store_Params(parm, (uint8_t*)output + frameIndex * rtpLength()); + result += rtpLength(); + } + } + return result; +} + +int G729Codec::decode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + if (!mDecoder) + { + mDecoder = Init_Decod_ld8a(); + if (mDecoder) + { + Init_Post_Filter(mDecoder); + Init_Post_Process(mDecoder); + } + } + + int result = 0; + if (mDecoder) + { + // See if there are silence bytes in the end + bool isSilence = (inputBytes % rtpLength()) / 2 != 0; + + // Find number of frames + int nrOfFrames = inputBytes / rtpLength(); + nrOfFrames = std::min(outputCapacity / pcmLength(), nrOfFrames); + + for (int frameIndex = 0; frameIndex < nrOfFrames; frameIndex++) + decodeFrame((const uint8_t*)input + frameIndex * rtpLength(), (int16_t*)output + frameIndex * pcmLength()); + + result += nrOfFrames * pcmLength(); + + if (isSilence && nrOfFrames < outputCapacity / pcmLength()) + { + memset((uint8_t*)output + nrOfFrames * pcmLength(), 0, pcmLength()); + result += pcmLength(); + } + } + + return result; +} + +void G729Codec::decodeFrame(const uint8_t* rtp, int16_t* pcm) +{ + Word16 i; + Word16 *synth; + Word16 parm[PRM_SIZE + 1]; + + Restore_Params(rtp, &parm[1]); + + synth = mDecoder->synth_buf + M10; + + parm[0] = 1; + for (i = 0; i < PRM_SIZE; i++) + { + if (parm[i + 1] != 0) + { + parm[0] = 0; + break; + } + } + + parm[4] = Check_Parity_Pitch(parm[3], parm[4]); + + Decod_ld8a(mDecoder, parm, synth, mDecoder->Az_dec, mDecoder->T2, &mDecoder->bad_lsf); + Post_Filter(mDecoder, synth, mDecoder->Az_dec, mDecoder->T2); + Post_Process(mDecoder, synth, L_FRAME); + + for (i = 0; i < pcmLength() / 2; i++) + pcm[i] = synth[i]; + +} + + +int G729Codec::plc(int lostFrames, void* output, int outputCapacity) +{ + return 0; +} + + +#ifdef USE_OPUS_CODEC +// -------------- Opus ------------------- +#define OPUS_CODEC_NAME "OPUS" +#define OPUS_CODEC_RATE 16000 +#define OPUS_TARGET_BITRATE 64000 +#define OPUS_PACKET_LOSS 30 +#define OPUS_CODEC_COMPLEXITY 2 + +OpusCodec::Params::Params() + :mUseDtx(false), mUseInbandFec(true), mStereo(true), mPtime(20) +{ + mExpectedPacketLoss = OPUS_PACKET_LOSS; + mTargetBitrate = OPUS_TARGET_BITRATE; +} + +#if defined(USE_RESIP_INTEGRATION) +resip::Data OpusCodec::Params::toString() const +{ + std::ostringstream oss; + //oss << "ptime=" << mPTime << ";"; + if (mUseDtx) + oss << "usedtx=" << (mUseDtx ? "1" : "0") << ";"; + if (mUseInbandFec) + oss << "useinbandfec=" << (mUseInbandFec ? "1" : "0") << ";"; + std::string r = oss.str(); + + // Erase last semicolon + if (r.size()) + r.erase(r.size()-1); + + //oss << "stereo=" << (mStereo ? "1" : "0") << ";"; + return resip::Data(r); +} + +struct CodecParam +{ + resip::Data mName; + resip::Data mValue; +}; + +static void splitParams(const resip::Data& s, std::list& params) +{ + resip::Data::size_type p = 0; + while (p != resip::Data::npos) + { + resip::Data::size_type p1 = s.find(";", p); + + resip::Data param; + if (p1 != resip::Data::npos) + { + param = s.substr(p, p1 - p); + p = p1 + 1; + } + else + { + param = s.substr(p); + p = resip::Data::npos; + } + + + CodecParam cp; + // See if there is '=' inside + resip::Data::size_type ep = param.find("="); + if (ep != resip::Data::npos) + { + cp.mName = param.substr(0, ep); + cp.mValue = param.substr(ep + 1); + } + else + cp.mName = param; + + params.push_back(cp); + } +} + + +void OpusCodec::Params::parse(const resip::Data ¶ms) +{ + // There is opus codec in sdp. Be simple - use the parameters from remote peer to operate + std::list parsed; + splitParams(params, parsed); + + std::list::const_iterator paramIter; + for (paramIter = parsed.begin(); paramIter != parsed.end(); ++paramIter) + { + if (paramIter->mName == "usedtx") + mUseDtx = paramIter->mValue == "1"; + else + if (paramIter->mName == "useinbandfec") + mUseInbandFec = paramIter->mValue == "1"; + else + if (paramIter->mName == "stereo") + mStereo = paramIter->mValue == "1"; + else + if (paramIter->mName == "ptime") + mPtime = StringHelper::toInt(paramIter->mValue.c_str(), 20); + } +} +#endif +OpusCodec::OpusFactory::OpusFactory(int samplerate, int channels, int ptype) +{ + mSamplerate = samplerate; + mChannels = channels; + mPType = ptype; +} + +const char* OpusCodec::OpusFactory::name() +{ + return OPUS_CODEC_NAME; +} + +int OpusCodec::OpusFactory::channels() +{ + return mChannels; +} + +int OpusCodec::OpusFactory::samplerate() +{ + return mSamplerate; +} + +int OpusCodec::OpusFactory::payloadType() +{ + return mPType; +} + +#if defined(USE_RESIP_INTEGRATION) +void OpusCodec::OpusFactory::updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) +{ + // Put opus codec record + resip::Codec opus(name(), payloadType(), samplerate()); + if (mParams.mStereo) + opus.encodingParameters() = "2"; + opus.parameters() = resip::Data(mParams.toString().c_str()); + + codecs.push_back(opus); +} + +#if defined(TARGET_ANDROID) +# define stricmp strcasecmp +#endif + +int OpusCodec::OpusFactory::processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) +{ + resip::SdpContents::Session::Medium::CodecContainer::const_iterator codecIter; + for (codecIter = codecs.begin(); codecIter != codecs.end(); ++codecIter) + { + const resip::Codec& resipCodec = *codecIter; + // Accept only 48000Hz configurations + if (stricmp(resipCodec.getName().c_str(), name()) == 0 && resipCodec.getRate() == 48000) + { + mParams.parse(resipCodec.parameters()); + + // Check number of channels + mParams.mStereo |= codecIter->encodingParameters() == "2"; + + // Here changes must be applied to instantiated codec + for (CodecList::iterator instanceIter = mCodecList.begin(); instanceIter != mCodecList.end(); ++instanceIter) + { + Codec& c = **instanceIter; + if ((c.channels() == (mParams.mStereo ? 2 : 1)) && resipCodec.getRate() == c.samplerate()) + dynamic_cast(c).applyParams(mParams); + } + return codecIter->payloadType(); + } + } + return -1; +} +#endif + +PCodec OpusCodec::OpusFactory::create() +{ + OpusCodec* result = new OpusCodec(mSamplerate, mChannels, mParams.mPtime); + result->applyParams(mParams); + PCodec c(result); + mCodecList.push_back(c); + return c; +} + +OpusCodec::OpusCodec(int samplerate, int channels, int ptime) + :mEncoderCtx(NULL), mDecoderCtx(NULL), mChannels(channels), mPTime(ptime), mSamplerate(samplerate) +{ + int status; + mEncoderCtx = opus_encoder_create(48000, mChannels, OPUS_APPLICATION_VOIP, &status); + if (OPUS_OK != opus_encoder_ctl(mEncoderCtx, OPUS_SET_COMPLEXITY(OPUS_CODEC_COMPLEXITY))) + ICELogCritical(<< "Failed to set encoder complexity"); + //if (OPUS_OK != opus_encoder_ctl(mEncoderCtx, OPUS_SET_FORCE_CHANNELS(AUDIO_CHANNELS))) + // ICELogCritical(<<"Failed to set channel number in Opus encoder"); + mDecoderCtx = opus_decoder_create(48000, mChannels, &status); +} + +void OpusCodec::applyParams(const Params ¶ms) +{ + int error; + if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_DTX(params.mUseDtx ? 1 : 0)))) + ICELogCritical(<< "Failed to (un)set DTX mode in Opus encoder. Error " << opus_strerror(error)); + + if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_INBAND_FEC(params.mUseInbandFec ? 1 : 0)))) + ICELogCritical(<< "Failed to (un)set FEC mode in Opus encoder. Error " << opus_strerror(error)); + + if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_BITRATE(params.mTargetBitrate ? params.mTargetBitrate : OPUS_AUTO)))) + ICELogCritical(<< "Failed to (un)set target bandwidth. Error " << opus_strerror(error)); + + if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_PACKET_LOSS_PERC(params.mExpectedPacketLoss)))) + ICELogCritical(<< "Failed to (un)set expected packet loss. Error " << opus_strerror(error)); + + mDecodeResampler.start(channels(), 48000, mSamplerate); +} + +OpusCodec::~OpusCodec() +{ + if (mDecoderCtx) + { + opus_decoder_destroy(mDecoderCtx); + mDecoderCtx = NULL; + } + + if (mEncoderCtx) + { + opus_encoder_destroy(mEncoderCtx); + mEncoderCtx = NULL; + } +} + +const char* OpusCodec::name() +{ + return OPUS_CODEC_NAME; +} + +int OpusCodec::pcmLength() +{ + return (samplerate() / 1000 ) * frameTime() * sizeof(short) * channels(); +} + +int OpusCodec::channels() +{ + return mChannels; +} + +int OpusCodec::rtpLength() +{ + return 0; // VBR +} + +int OpusCodec::frameTime() +{ + return mPTime; +} + +int OpusCodec::samplerate() +{ + return mSamplerate; +} + +int OpusCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + // Send number of samples for input and number of bytes for output + int written = opus_encode(mEncoderCtx, (const opus_int16*)input, inputBytes / (sizeof(short) * channels()), (unsigned char*)output, outputCapacity / (sizeof(short) * channels())); + if (written < 0) + return 0; + else + return written; +} + +int OpusCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + int nrOfChannelsInPacket = opus_packet_get_nb_channels((const unsigned char*)input); + assert(nrOfChannelsInPacket == 1); + + int nrOfSamplesInPacket = opus_decoder_get_nb_samples(mDecoderCtx, (const unsigned char*)input, inputBytes); + if (nrOfSamplesInPacket > 0) + { + // Send number of bytes for input and number of samples for output + int capacity = nrOfSamplesInPacket * sizeof(opus_int16) * channels(); + opus_int16* buffer = (opus_int16*)alloca(capacity); + int decoded = opus_decode(mDecoderCtx, (const unsigned char*)input, inputBytes, (opus_int16*)buffer, capacity / (sizeof(short) * channels()), 1); + if (decoded < 0) + return 0; + else + { + // Resample 48000 to requested samplerate + int processed = 0; + return mDecodeResampler.processBuffer(buffer, decoded * sizeof(short) * channels(), processed, output, outputCapacity); + } + } + else + return 0; +} + +int OpusCodec::plc(int lostFrames, void* output, int outputCapacity) +{ + int nrOfSamplesInFrame = pcmLength() / (sizeof(short) * channels()); + memset(output, 0, outputCapacity); + for (int i=0; igetName().c_str(), "ilbc") == 0) + { + const resip::Data& p = codecIter->parameters(); + int codecPtime = 0; + if (p.size()) + { + if (strstr(p.c_str(), "mode=") == p.c_str()) + sscanf(p.c_str(), "mode=%d", &codecPtime); + else + if (strstr(p.c_str(), "ptime=")) + sscanf(p.c_str(), "ptime=%d", &codecPtime); + } + + if (codecPtime > ptime) + { + pt = codecIter->payloadType(); + ptime = codecPtime; + } + else + if (!codecPtime) + { + // Suppose it is 30ms ilbc + pt = codecIter->payloadType(); + ptime = 30; + } + } + } + + if (pt != -1) + mPtime = ptime; + return pt; +} + +#endif + +// --- IsacCodec(s) --- +#define ISAC_CODEC_NAME "ISAC" + +IsacCodec::IsacCodec(int samplerate) +:mSamplerate(samplerate) +{ + // This code initializes isac encoder to automatic mode - it will adjust its bitrate automatically. + // Frame time is 60 ms + WebRtcIsacfix_Create(&mEncoderCtx); + WebRtcIsacfix_EncoderInit(mEncoderCtx, 0); + //WebRtcIsacfix_Control(mEncoderCtx, mSamplerate, 30); + //WebRtcIsacfix_SetEncSampRate(mEncoderCtx, mSampleRate == 16000 ? kIsacWideband : kIsacSuperWideband); + WebRtcIsacfix_Create(&mDecoderCtx); + WebRtcIsacfix_DecoderInit(mDecoderCtx); + //WebRtcIsacfix_Control(mDecoderCtx, mSamplerate, 30); + //WebRtcIsacfix_SetDecSampRate(mDecoderCtx, mSampleRate == 16000 ? kIsacWideband : kIsacSuperWideband); +} + +IsacCodec::~IsacCodec() +{ + WebRtcIsacfix_Free(mEncoderCtx); mEncoderCtx = NULL; + WebRtcIsacfix_Free(mDecoderCtx); mDecoderCtx = NULL; +} + +const char* IsacCodec::name() +{ + return "isac"; +} + +int IsacCodec::frameTime() +{ + return 60; +} + +int IsacCodec::samplerate() +{ + return mSamplerate; +} + +int IsacCodec::pcmLength() +{ + return frameTime() * samplerate() / 1000 * sizeof(short); +} + +int IsacCodec::rtpLength() +{ + return 0; +} + +int IsacCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + unsigned nrOfSamples = inputBytes / 2; + unsigned timeLength = nrOfSamples / (mSamplerate / 1000); + int encoded = 0; + char* dataOut = (char*)output; + const WebRtc_Word16* dataIn = (const WebRtc_Word16*)input; + + // Iterate 10 milliseconds chunks + for (unsigned i=0; i 0) + dataOut += encoded; + } + return dataOut - (char*)output; +} + +int IsacCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + WebRtc_Word16 speechType = 0; + unsigned produced = WebRtcIsacfix_Decode(mDecoderCtx, (const WebRtc_UWord16*)input, inputBytes, (WebRtc_Word16*)output, &speechType); + if (produced == (unsigned)-1) + return 0; + + return produced * 2; +} + +int IsacCodec::plc(int lostFrames, void* output, int outputCapacity) +{ + // lostFrames are 30-milliseconds frames; but used encoding mode is 60 milliseconds. + // So lostFrames * 2 + lostFrames *=2 ; + if (-1 == WebRtcIsacfix_DecodePlc(mDecoderCtx, (WebRtc_Word16*)output, lostFrames )) + return 0; + + return lostFrames * 30 * (samplerate()/1000 * sizeof(short)); +} + +// --- IsacFactory16K --- +IsacCodec::IsacFactory16K::IsacFactory16K(int ptype) + :mPType(ptype) +{} + +const char* IsacCodec::IsacFactory16K::name() +{ + return ISAC_CODEC_NAME; +} + +int IsacCodec::IsacFactory16K::samplerate() +{ + return 16000; +} + +int IsacCodec::IsacFactory16K::payloadType() +{ + return mPType; +} + +PCodec IsacCodec::IsacFactory16K::create() +{ + return PCodec(new IsacCodec(16000)); +} + +// --- IsacFactory32K --- +IsacCodec::IsacFactory32K::IsacFactory32K(int ptype) + :mPType(ptype) +{} + + +const char* IsacCodec::IsacFactory32K::name() +{ + return ISAC_CODEC_NAME; +} + +int IsacCodec::IsacFactory32K::samplerate() +{ + return 32000; +} + +int IsacCodec::IsacFactory32K::payloadType() +{ + return mPType; +} + +PCodec IsacCodec::IsacFactory32K::create() +{ + return PCodec(new IsacCodec(32000)); +} + +// --- G711 --- +#define ULAW_CODEC_NAME "PCMU" +#define ALAW_CODEC_NAME "PCMA" + +G711Codec::G711Codec(int type) +:mType(type) +{ +} + +G711Codec::~G711Codec() +{ +} + +const char* G711Codec::name() +{ + return "g711"; +} + +int G711Codec::pcmLength() +{ + return frameTime() * 16; +} + +int G711Codec::rtpLength() +{ + return frameTime() * 8; +} + +int G711Codec::frameTime() +{ + return 10; +} + +int G711Codec::samplerate() +{ + return 8000; +} + +int G711Codec::encode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + int result; + if (mType == ALaw) + result = WebRtcG711_EncodeA(NULL, (WebRtc_Word16*)input, inputBytes/2, (WebRtc_Word16*)output); + else + result = WebRtcG711_EncodeU(NULL, (WebRtc_Word16*)input, inputBytes/2, (WebRtc_Word16*)output); + + if (result == -1) + throw Exception(ERR_WEBRTC, -1); + + return result; +} + +int G711Codec::decode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + assert(outputCapacity >= inputBytes * 2); + + int result; + WebRtc_Word16 speechType; + + if (mType == ALaw) + result = WebRtcG711_DecodeA(NULL, (WebRtc_Word16*)input, inputBytes, (WebRtc_Word16*)output, &speechType); + else + result = WebRtcG711_DecodeU(NULL, (WebRtc_Word16*)input, inputBytes, (WebRtc_Word16*)output, &speechType); + + if (result == -1) + throw Exception(ERR_WEBRTC, -1); + + return result * 2; +} + +int G711Codec::plc(int lostSamples, void* output, int outputCapacity) +{ + return 0; +} + +// --- AlawFactory --- +const char* G711Codec::AlawFactory::name() +{ + return ALAW_CODEC_NAME; +} +int G711Codec::AlawFactory::samplerate() +{ + return 8000; +} +int G711Codec::AlawFactory::payloadType() +{ + return 8; +} +PCodec G711Codec::AlawFactory::create() +{ + return PCodec(new G711Codec(G711Codec::ALaw)); +} + +// --- UlawFactory --- +const char* G711Codec::UlawFactory::name() +{ + return ULAW_CODEC_NAME; +} +int G711Codec::UlawFactory::samplerate() +{ + return 8000; +} +int G711Codec::UlawFactory::payloadType() +{ + return 0; +} +PCodec G711Codec::UlawFactory::create() +{ + return PCodec(new G711Codec(G711Codec::ULaw)); +} + +// ---------- GsmCodec ------------- + +GsmCodec::GsmFactory::GsmFactory(Type codecType, int pt) + :mCodecType(codecType), mPayloadType(pt) +{} + +const char* GsmCodec::GsmFactory::name() +{ + return GSM_MIME_NAME; +} + +int GsmCodec::GsmFactory::samplerate() +{ + return 8000; +} + +int GsmCodec::GsmFactory::payloadType() +{ + return mPayloadType; +} + +PCodec GsmCodec::GsmFactory::create() +{ + return PCodec(new GsmCodec(mCodecType)); +} + +GsmCodec::GsmCodec(Type codecType) + :mCodecType(codecType) +{ + mGSM = gsm_create(); + if (codecType != Type::Bytes_33) + { + int optval = 1; + gsm_option(mGSM, GSM_OPT_WAV49, &optval); + } +} + +GsmCodec::~GsmCodec() +{ + gsm_destroy(mGSM); +} + +const char* GsmCodec::name() +{ + return "GSM-06.10"; +} + +int GsmCodec::rtpLength() +{ + switch (mCodecType) + { + case Type::Bytes_31: + return GSM_RTPFRAME_SIZE_31; + break; + + case Type::Bytes_32: + return GSM_RTPFRAME_SIZE_32; + + case Type::Bytes_33: + return GSM_RTPFRAME_SIZE_33; + + case Type::Bytes_65: + return GSM_RTPFRAME_SIZE_32 + GSM_RTPFRAME_SIZE_33; + + } + + return GSM_RTPFRAME_SIZE_33; +} + +int GsmCodec::pcmLength() +{ + return GSM_AUDIOFRAME_TIME * 16; +} + +int GsmCodec::frameTime() +{ + return GSM_AUDIOFRAME_TIME; +} + +int GsmCodec::samplerate() +{ + return 8000; +} + +int GsmCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + int outputBytes = 0; + + char* outputBuffer = (char*)output; + + for (int i = 0; i < inputBytes/pcmLength(); i++) + { + gsm_encode(mGSM, (gsm_signal *)input+160*i, (gsm_byte*)outputBuffer); + outputBuffer += rtpLength(); + outputBytes += rtpLength(); + } + return outputBytes; +} + + +int GsmCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + if (inputBytes % rtpLength() != 0) + return 0; + + int i=0; + for (i = 0; i < inputBytes/rtpLength(); i++) + gsm_decode(mGSM, (gsm_byte *)input + 33 * i, (gsm_signal *)output + 160 * i); + + return i * 320; +} + +int GsmCodec::plc(int lostFrames, void* output, int outputCapacity) +{ + if (outputCapacity < lostFrames * pcmLength()) + return 0; + + // Return silence frames + memset(output, 0, lostFrames * pcmLength()); + return lostFrames * pcmLength(); +} + + +// ------------- G722Codec ----------------- + +G722Codec::G722Codec() +{ + mEncoder = g722_encode_init(NULL, 64000, 0); + mDecoder = g722_decode_init(NULL, 64000, 0); + +} + +G722Codec::~G722Codec() +{ + g722_decode_release((g722_decode_state_t*)mDecoder); + g722_encode_release((g722_encode_state_t*)mEncoder); +} + +const char* G722Codec::name() +{ + return G722_MIME_NAME; +} + +int G722Codec::pcmLength() +{ + return 640; +} + +int G722Codec::frameTime() +{ + return 20; +} + +int G722Codec::rtpLength() +{ + return 160; +} + +int G722Codec::samplerate() +{ + return 8000; +} + +int G722Codec::encode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + if (outputCapacity < inputBytes / 4) + return 0; // Destination buffer not big enough + + return g722_encode((g722_encode_state_t *)mEncoder, (unsigned char*)output, ( short*)input, inputBytes / 2); +} + +int G722Codec::decode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + if (outputCapacity < inputBytes * 4) + return 0; // Destination buffer not big enough + + return g722_decode((g722_decode_state_t *)mDecoder, ( short*)output, (unsigned char*)input, inputBytes) * 2; +} + +int G722Codec::plc(int lostFrames, void* output, int outputCapacity) +{ + if (outputCapacity < lostFrames * pcmLength()) + return 0; + + // Return silence frames + memset(output, 0, lostFrames * pcmLength()); + return lostFrames * pcmLength(); +} + +G722Codec::G722Factory::G722Factory() +{} + +const char* G722Codec::G722Factory::name() +{ + return G722_MIME_NAME; +} + +int G722Codec::G722Factory::samplerate() +{ + // Although G722 uses 16000 as rate for timestamping RTP frames - in fact it is 8KHz codec. So return 8KHz here. + return 8000; +} + +int G722Codec::G722Factory::payloadType() +{ + return G722_PAYLOAD_TYPE; +} + +PCodec G722Codec::G722Factory::create() +{ + return PCodec(new G722Codec()); +} + +#ifndef TARGET_ANDROID +// --------------- GsmHrCodec ------------------- + +// Returns false if error occured. +#define GSMHR_GOODSPEECH (0) +#define GSMHR_GOODSID (2) +#define GSMHR_NODATA (7) + +static bool repackHalfRate(BitReader& br, uint16_t frame[22], bool& lastItem) +{ + // Check if it is last chunk + lastItem = br.readBit() == 0; + + // Read frame type + uint8_t frametype = (uint8_t)br.readBits(3); // Read frame type + + // Read reserved bits + br.readBits(4); + + switch (frametype) + { + case GSMHR_GOODSPEECH: + case GSMHR_GOODSID: + frame[0] = br.readBits(5); // R0 + frame[1] = br.readBits(11); // LPC1 + frame[2] = br.readBits(9); // LPC2 + frame[3] = br.readBits(8); // LPC3 + frame[4] = br.readBits(1); // INT_LPC + frame[5] = br.readBits(2); // MODE + // Parse speech frame + if (frame[5]) + { + // Voiced mode + frame[6] = br.readBits(8); // LAG_1 + frame[7] = br.readBits(9); // CODE_1 + frame[8] = br.readBits(5); // GSP0_1 + + frame[9] = br.readBits(4); // LAG_2 + frame[10] = br.readBits(9); // CODE_2 + frame[11] = br.readBits(5); // GSP0_2 + + frame[12] = br.readBits(4); // LAG_3 + frame[13] = br.readBits(9); // CODE_3 + frame[14] = br.readBits(5); // GSP0_3 + + frame[15] = br.readBits(4); // LAG_4 + frame[16] = br.readBits(9); // CODE_4 + frame[17] = br.readBits(5); // GSP0_4 + } + else + { + // Unvoiced mode + frame[6] = br.readBits(7); // CODE1_1 + frame[7] = br.readBits(7); // CODE2_1 + frame[8] = br.readBits(5); // GSP0_1 + + frame[9] = br.readBits(7); // CODE1_2 + frame[10] = br.readBits(7); // CODE2_2 + frame[11] = br.readBits(5); // GSP0_2 + + frame[12] = br.readBits(7); // CODE1_3 + frame[13] = br.readBits(7); // CODE2_3 + frame[14] = br.readBits(5); // GSP0_3; + + frame[15] = br.readBits(7); // CODE1_4; + frame[16] = br.readBits(7); // CODE2_4; + frame[17] = br.readBits(5); // GSP0_4; + } + + frame[18] = 0; frame[19] = 0; + frame[20] = 0; frame[21] = 0; + break; + + case GSMHR_NODATA: + break; + + default: + return false; + } + + return true; +} + +GsmHrCodec::GsmHrCodec() + :mDecoder(nullptr) +{ + mDecoder = new GsmHr::Codec(); +} + +GsmHrCodec::~GsmHrCodec() +{ + delete reinterpret_cast(mDecoder); + mDecoder = nullptr; +} + +const char* GsmHrCodec::name() +{ + return "GSM-HR-08"; +} + +int GsmHrCodec::pcmLength() +{ + return frameTime() * 8 * 2; +} + +int GsmHrCodec::rtpLength() +{ + return 0; +} + +int GsmHrCodec::frameTime() +{ + return 20; +} + +int GsmHrCodec::samplerate() +{ + return 8000; +} + +int GsmHrCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity) +{ + return 0; +} + +static const int params_unvoiced[] = { + 5, /* R0 */ + 11, /* k1Tok3 */ + 9, /* k4Tok6 */ + 8, /* k7Tok10 */ + 1, /* softInterpolation */ + 2, /* voicingDecision */ + 7, /* code1_1 */ + 7, /* code2_1 */ + 5, /* gsp0_1 */ + 7, /* code1_2 */ + 7, /* code2_2 */ + 5, /* gsp0_2 */ + 7, /* code1_3 */ + 7, /* code2_3 */ + 5, /* gsp0_3 */ + 7, /* code1_4 */ + 7, /* code2_4 */ + 5, /* gsp0_4 */ +}; + +static const int params_voiced[] = { + 5, /* R0 */ + 11, /* k1Tok3 */ + 9, /* k4Tok6 */ + 8, /* k7Tok10 */ + 1, /* softInterpolation */ + 2, /* voicingDecision */ + 8, /* frameLag */ + 9, /* code_1 */ + 5, /* gsp0_1 */ + 4, /* deltaLag_2 */ + 9, /* code_2 */ + 5, /* gsp0_2 */ + 4, /* deltaLag_3 */ + 9, /* code_3 */ + 5, /* gsp0_3 */ + 4, /* deltaLag_4 */ + 9, /* code_4 */ + 5, /* gsp0_4 */ +}; + +static int +msb_get_bit(const uint8_t *buf, int bn) +{ + int pos_byte = bn >> 3; + int pos_bit = 7 - (bn & 7); + + return (buf[pos_byte] >> pos_bit) & 1; +} + +static int +hr_ref_from_canon(uint16_t *hr_ref, const uint8_t *canon) +{ + int i, j, voiced; + const int *params; + + voiced = (msb_get_bit(canon, 34) << 1) | msb_get_bit(canon, 35); + params = voiced ? ¶ms_voiced[0] : ¶ms_unvoiced[0]; + + for (i=0,j=0; i<18; i++) + { + uint16_t w; + int l, k; + + l = params[i]; + + w = 0; + for (k=0; k(mDecoder)->speechDecoder((int16_t*)hr_ref, (int16_t*)output); + return 320; +} + +int GsmHrCodec::plc(int lostFrames, void* output, int outputCapacity) +{ + return 0; +} + +GsmHrCodec::GsmHrFactory::GsmHrFactory(int ptype) + :mPtype(ptype) +{} + +const char* GsmHrCodec::GsmHrFactory::name() +{ + return "GSM-HR-08"; +} + +int GsmHrCodec::GsmHrFactory::samplerate() +{ + return 8000; +} + +int GsmHrCodec::GsmHrFactory::payloadType() +{ + return mPtype; +} + +PCodec GsmHrCodec::GsmHrFactory::create() +{ + return PCodec(new GsmHrCodec()); +} +#endif \ No newline at end of file diff --git a/src/engine/media/MT_AudioCodec.h b/src/engine/media/MT_AudioCodec.h new file mode 100644 index 00000000..e7a91a4b --- /dev/null +++ b/src/engine/media/MT_AudioCodec.h @@ -0,0 +1,421 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __AUDIO_CODEC_H +#define __AUDIO_CODEC_H + +#include "../config.h" +#include +#include "MT_Codec.h" +#include "../audio/Audio_Resampler.h" +#include "../helper/HL_Pointer.h" +#include "webrtc/ilbcfix/ilbc.h" +#include "webrtc/isac/isacfix.h" +#include "webrtc/g711/g711_interface.h" + +extern "C" +{ + #include "libgsm/gsm.h" + #include "g722/g722.h" +} + +#include "libg729/g729_typedef.h" +#include "libg729/g729_ld8a.h" + +#ifdef USE_OPUS_CODEC +# include "opus.h" +#endif + +namespace MT +{ + class G729Codec: public Codec + { + protected: + CodState* mEncoder = nullptr; + DecState* mDecoder = nullptr; + void decodeFrame(const uint8_t* rtp, int16_t* pcm); + + public: + class G729Factory: public Factory + { + public: + const char* name() override; + int channels() override; + int samplerate() override; + int payloadType() override; + +#if defined(USE_RESIP_INTEGRATION) + void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override; + int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override; +#endif + PCodec create() override; + }; + G729Codec(); + ~G729Codec(); + + const char* name() override; + int pcmLength() override; + int rtpLength() override; + int frameTime() override; + int samplerate() override; + int channels() override; + int encode(const void* input, int inputBytes, void* output, int outputCapacity) override; + int decode(const void* input, int inputBytes, void* output, int outputCapacity) override; + int plc(int lostFrames, void* output, int outputCapacity) override; + }; + +#ifdef USE_OPUS_CODEC + + class OpusCodec: public Codec + { + protected: + OpusEncoder *mEncoderCtx; + OpusDecoder *mDecoderCtx; + int mPTime, mSamplerate, mChannels; + Audio::SpeexResampler mDecodeResampler; + public: + struct Params + { + bool mUseDtx, mUseInbandFec, mStereo; + int mPtime, mTargetBitrate, mExpectedPacketLoss; + + Params(); +#if defined(USE_RESIP_INTEGRATION) + resip::Data toString() const; + void parse(const resip::Data& params); +#endif + }; + + class OpusFactory: public Factory + { + protected: + int mSamplerate, mChannels, mPType; + OpusCodec::Params mParams; + typedef std::vector CodecList; + CodecList mCodecList; + + public: + OpusFactory(int samplerate, int channels, int ptype); + + const char* name() override; + int channels() override; + int samplerate() override; + int payloadType() override; +#if defined(USE_RESIP_INTEGRATION) + void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override; + int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override; +#endif + PCodec create() override; + }; + + OpusCodec(int samplerate, int channels, int ptime); + ~OpusCodec(); + void applyParams(const Params& params); + + const char* name(); + int pcmLength(); + int rtpLength(); + int frameTime(); + int samplerate(); + int channels(); + int encode(const void* input, int inputBytes, void* output, int outputCapacity); + int decode(const void* input, int inputBytes, void* output, int outputCapacity); + int plc(int lostFrames, void* output, int outputCapacity); + }; +#endif + + class IlbcCodec: public Codec + { + protected: + int mPacketTime; /// Single frame time (20 or 30 ms) + iLBC_encinst_t* mEncoderCtx; + iLBC_decinst_t* mDecoderCtx; + + public: + class IlbcFactory: public Factory + { + protected: + int mPtime; + int mPType20ms, mPType30ms; + + public: + + IlbcFactory(int ptype20ms, int ptype30ms); + const char* name(); + int samplerate(); + int payloadType(); +#ifdef USE_RESIP_INTEGRATION + void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction); + int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction); + void create(CodecMap& codecs); +#endif + PCodec create(); + }; + + IlbcCodec(int packetTime); + virtual ~IlbcCodec(); + const char* name(); + int pcmLength(); + int rtpLength(); + int frameTime(); + int samplerate(); + int encode(const void* input, int inputBytes, void* output, int outputCapacity); + int decode(const void* input, int inputBytes, void* output, int outputCapacity); + int plc(int lostFrames, void* output, int outputCapacity); + }; + + class G711Codec: public Codec + { + public: + class AlawFactory: public Factory + { + public: + const char* name(); + int samplerate(); + int payloadType(); + PCodec create(); + }; + + class UlawFactory: public Factory + { + public: + const char* name(); + int samplerate(); + int payloadType(); + PCodec create(); + }; + + enum + { + ALaw = 0, /// a-law codec type + ULaw = 1 /// u-law codec type + }; + + G711Codec(int type); + ~G711Codec(); + + const char* name(); + int pcmLength(); + int frameTime(); + int rtpLength(); + int samplerate(); + + int encode(const void* input, int inputBytes, void* output, int outputCapacity); + int decode(const void* input, int inputBytes, void* output, int outputCapacity); + int plc(int lostSamples, void* output, int outputCapacity); + + protected: + int mType; /// Determines if it is u-law or a-law codec. Its value is ALaw or ULaw. + }; + + class IsacCodec: public Codec + { + protected: + int mSamplerate; + ISACFIX_MainStruct* mEncoderCtx; + ISACFIX_MainStruct* mDecoderCtx; + public: + class IsacFactory16K: public Factory + { + public: + IsacFactory16K(int ptype); + const char* name(); + int samplerate(); + int payloadType(); + PCodec create(); + + protected: + int mPType; + }; + + class IsacFactory32K: public Factory + { + public: + IsacFactory32K(int ptype); + + const char* name(); + int samplerate(); + int payloadType(); + PCodec create(); + + protected: + int mPType; + }; + + IsacCodec(int sampleRate); + ~IsacCodec(); + + const char* name(); + int pcmLength(); + int rtpLength(); + int frameTime(); + int samplerate(); + + int encode(const void* input, int inputBytes, void* output, int outputCapacity); + int decode(const void* input, int inputBytes, void* output, int outputCapacity); + int plc(int lostFrames, void* output, int outputCapacity); + }; + + + + /// GSM MIME name + #define GSM_MIME_NAME "gsm" + + /// Optional GSM SIP attributes + #define GSM_SIP_ATTR "" + + /// GSM codec single frame time in milliseconds + #define GSM_AUDIOFRAME_TIME 20 + + /// GSM codec single RTP frame size in bytes + #define GSM_RTPFRAME_SIZE_33 33 + #define GSM_RTPFRAME_SIZE_32 32 + #define GSM_RTPFRAME_SIZE_31 31 + + /// GSM payload type + #define GSM_PAYLOAD_TYPE 3 + + /// GSM bitrate (bits/sec) + #define GSM_BITRATE 13000 + + + /*! + * GSM codec wrapper. Based on implementation located in libgsm directory. + * @see IMediaCodec + */ + class GsmCodec: public Codec + { + public: + enum class Type + { + Bytes_33, + Bytes_32, + Bytes_31, + Bytes_65 + }; + protected: + struct gsm_state * mGSM; /// Pointer to codec context + Type mCodecType; + + public: + class GsmFactory: public Factory + { + protected: + int mPayloadType; + Type mCodecType; + + public: + GsmFactory(Type codecType = Type::Bytes_33, int pt = GSM_PAYLOAD_TYPE); + + const char* name(); + int samplerate(); + int payloadType(); + PCodec create(); + }; + + /*! Default constructor. Initializes codec context's pointer to NULL. */ + GsmCodec(Type codecType); + + /*! Destructor. */ + virtual ~GsmCodec(); + + const char* name(); + int pcmLength(); + int rtpLength(); + int frameTime(); + int samplerate(); + + int encode(const void* input, int inputBytes, void* output, int outputCapacity); + int decode(const void* input, int inputBytes, void* output, int outputCapacity); + int plc(int lostFrames, void* output, int outputCapacity); + }; + + /// GSM MIME name + #define G722_MIME_NAME "g722" + + /// Optional GSM SIP attributes + #define G722_SIP_ATTR "" + + /// GSM codec single frame time in milliseconds + #define G722_AUDIOFRAME_TIME 20 + + /// GSM codec single RTP frame size in bytes + #define G722_RTPFRAME_SIZE 80 + + /// GSM payload type + #define G722_PAYLOAD_TYPE 9 + + /// GSM bitrate (bits/sec) + #define G722_BITRATE 64000 + + class G722Codec: public Codec + { + protected: + void* mEncoder; + void* mDecoder; + + public: + class G722Factory: public Factory + { + public: + G722Factory(); + + const char* name(); + int samplerate(); + int payloadType(); + PCodec create(); + }; + G722Codec(); + virtual ~G722Codec(); + + const char* name(); + int pcmLength(); + int rtpLength(); + int frameTime(); + int samplerate(); + + int encode(const void* input, int inputBytes, void* output, int outputCapacity); + int decode(const void* input, int inputBytes, void* output, int outputCapacity); + int plc(int lostFrames, void* output, int outputCapacity); + + //unsigned GetSamplerate() { return 16000; } + }; + + class GsmHrCodec: public Codec + { + protected: + void* mDecoder; + + public: + class GsmHrFactory: public Factory + { + protected: + int mPtype; + + public: + GsmHrFactory(int ptype); + + const char* name() override; + int samplerate() override; + int payloadType() override; + PCodec create() override; + }; + + GsmHrCodec(); + virtual ~GsmHrCodec(); + + const char* name() override; + int pcmLength() override; + int rtpLength() override; + int frameTime() override; + int samplerate() override; + + int encode(const void* input, int inputBytes, void* output, int outputCapacity) override; + int decode(const void* input, int inputBytes, void* output, int outputCapacity) override; + int plc(int lostFrames, void* output, int outputCapacity) override; + }; +} + +#endif diff --git a/src/engine/media/MT_AudioReceiver.cpp b/src/engine/media/MT_AudioReceiver.cpp new file mode 100644 index 00000000..4ef52374 --- /dev/null +++ b/src/engine/media/MT_AudioReceiver.cpp @@ -0,0 +1,723 @@ +/* Copyright(C) 2007-2018 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#include "../config.h" +#include "MT_AudioReceiver.h" +#include "MT_AudioCodec.h" +#include "MT_CngHelper.h" +#include "../helper/HL_Log.h" +#include "../audio/Audio_Interface.h" +#include "../audio/Audio_Resampler.h" + +#if defined(USE_AMR_CODEC) +# include "MT_AmrCodec.h" +#endif + +#define LOG_SUBSYSTEM "AudioReceiver" + +//#define DUMP_DECODED + +using namespace MT; + +// ----------------- RtpBuffer::Packet -------------- +RtpBuffer::Packet::Packet(std::shared_ptr packet, int timelength, int rate) +:mRtp(packet), mTimelength(timelength), mRate(rate) +{ +} + +std::shared_ptr RtpBuffer::Packet::rtp() const +{ + return mRtp; +} + +int RtpBuffer::Packet::timelength() const +{ + return mTimelength; +} + +int RtpBuffer::Packet::rate() const +{ + return mRate; +} + +// ------------ RtpBuffer ---------------- +RtpBuffer::RtpBuffer(Statistics& stat) +:mStat(stat), mSsrc(0), mHigh(RTP_BUFFER_HIGH), mLow(RTP_BUFFER_LOW), mPrebuffer(RTP_BUFFER_PREBUFFER), + mFirstPacketWillGo(true), + mReturnedCounter(0), mAddCounter(0), mFetchedPacket(std::shared_ptr(), 0, 0) +{ +} + +RtpBuffer::~RtpBuffer() +{ + ICELogInfo(<< "Number of add packets: " << mAddCounter << ", number of retrieved packets " << mReturnedCounter); +} + +void RtpBuffer::setHigh(int milliseconds) +{ + mHigh = milliseconds; +} + +int RtpBuffer::high() +{ + return mHigh; +} + +void RtpBuffer::setLow(int milliseconds) +{ + mLow = milliseconds; +} + +int RtpBuffer::low() +{ + return mLow; +} + +void RtpBuffer::setPrebuffer(int milliseconds) +{ + mPrebuffer = milliseconds; +} + +int RtpBuffer::prebuffer() +{ + return mPrebuffer; +} + +int RtpBuffer::getCount() const +{ + Lock l(mGuard); + return mPacketList.size(); +} + +bool SequenceSort(const RtpBuffer::Packet& p1, const RtpBuffer::Packet& p2) +{ + return p1.rtp()->GetExtendedSequenceNumber() < p2.rtp()->GetExtendedSequenceNumber(); +} + +bool RtpBuffer::add(std::shared_ptr packet, int timelength, int rate) +{ + if (!packet) + return false; + + Lock l(mGuard); + + // Update statistics + mStat.mSsrc = packet->GetSSRC(); + + // Update jitter + ICELogMedia(<< "Adding new packet into jitter buffer"); + mAddCounter++; + + // Look for maximum&minimal sequence number; check for dublicates + unsigned maxno = 0xFFFFFFFF, minno = 0; + + // New sequence number + unsigned newSeqno = packet->GetExtendedSequenceNumber(); + + for (PacketList::iterator iter = mPacketList.begin(); iter != mPacketList.end(); iter++) + { + Packet& p = *iter; + unsigned seqno = p.rtp()->GetExtendedSequenceNumber(); + + if (seqno == newSeqno) + { + mStat.mDuplicatedRtp++; + ICELogMedia(<< "Discovered duplicated packet, skipping"); + return false; + } + + if (seqno > maxno) + maxno = seqno; + if (seqno < minno) + minno = seqno; + } + + int available = findTimelength(); + + if (newSeqno > minno || (available < mHigh)) + { + Packet p(packet, timelength, rate); + mPacketList.push_back(p); + std::sort(mPacketList.begin(), mPacketList.end(), SequenceSort); + + // Limit by max timelength + available = findTimelength(); + + while (available > mHigh && mPacketList.size()) + { + //ICELogCritical( << "Dropping RTP packet from jitter"); + available -= mPacketList.front().timelength(); + mPacketList.erase(mPacketList.begin()); + } + } + else + { + ICELogMedia(<< "Too old packet, skipping"); + mStat.mOldRtp++; + return false; + } + + return true; +} + +RtpBuffer::FetchResult RtpBuffer::fetch(ResultList& rl) +{ + Lock l(mGuard); + + FetchResult result = FetchResult::NoPacket; + rl.clear(); + + // See if there is enough information in buffer + int total = findTimelength(); + + if (total < mLow) + result = FetchResult::NoPacket; + else + { + if (mFetchedPacket.rtp()) + { + if (mPacketList.empty()) + { + result = FetchResult::NoPacket; + mStat.mPacketLoss++; + } + else + { + // Current sequence number ? + unsigned seqno = mPacketList.front().rtp()->GetExtendedSequenceNumber(); + + // Gap between new packet and previous on + int gap = seqno - mFetchedPacket.rtp()->GetSequenceNumber() - 1; + gap = std::min(gap, 127); + if (gap > 0 && mPacketList.empty()) + { + result = FetchResult::Gap; + mStat.mPacketLoss += gap; + mStat.mLoss[gap]++; + } + else + { + if (gap > 0) + { + mStat.mPacketLoss += gap; + mStat.mLoss[gap]++; + } + + result = FetchResult::RegularPacket; + Packet& p = mPacketList.front(); + rl.push_back(p.rtp()); + + // Maybe it is time to replay packet right now ? For case of AMR SID packets + if (mFetchedPacket.rtp() && gap == 0 && mFetchedPacket.timelength() >= 10 && p.timelength() >= 10) + { + // Timestamp difference + int timestampDelta = TimeHelper::getDelta(p.rtp()->GetTimestamp(), mFetchedPacket.rtp()->GetTimestamp()); + + // Timestamp units per packet + int nrOfPackets = timestampDelta / (p.timelength() * (p.rate() / 1000)); + + // Add more copies of SID (most probably) packets + for (int i = 0; i < nrOfPackets - 1; i++) + { + //assert(false); + rl.push_back(p.rtp()); + } + } + + // Save last returned normal packet + mFetchedPacket = mPacketList.front(); + + // Remove returned packet from the list + mPacketList.erase(mPacketList.begin()); + } + } + } + else + { + // See if prebuffer limit is reached + if (findTimelength() >= mPrebuffer) + { + // Normal packet will be returned + result = FetchResult::RegularPacket; + + // Put it to output list + rl.push_back(mPacketList.front().rtp()); + + // Remember returned packet + mFetchedPacket = mPacketList.front(); + + // Remove returned packet from buffer list + mPacketList.erase(mPacketList.begin()); + } + else + { + ICELogMedia(<< "Jitter buffer was not prebuffered yet; resulting no packet"); + result = FetchResult::NoPacket; + } + } + } + + if (result != FetchResult::NoPacket) + mReturnedCounter++; + + return result; +} + +int RtpBuffer::findTimelength() +{ + int available = 0; + for (unsigned i = 0; i < mPacketList.size(); i++) + available += mPacketList[i].timelength(); + return available; +} + +int RtpBuffer::getNumberOfReturnedPackets() const +{ + return mReturnedCounter; +} + +int RtpBuffer::getNumberOfAddPackets() const +{ + return mAddCounter; +} + +//-------------- Receiver --------------- +Receiver::Receiver(Statistics& stat) +:mStat(stat) +{ +} + +Receiver::~Receiver() +{ +} + +//-------------- AudioReceiver ---------------- +AudioReceiver::AudioReceiver(const CodecList::Settings& settings, MT::Statistics &stat) +:Receiver(stat), mBuffer(stat), mFrameCount(0), mFailedCount(0), mCodecSettings(settings), + mCodecList(settings) +{ + // Init resamplers + mResampler8.start(AUDIO_CHANNELS, 8000, AUDIO_SAMPLERATE); + mResampler16.start(AUDIO_CHANNELS, 16000, AUDIO_SAMPLERATE); + mResampler32.start(AUDIO_CHANNELS, 32000, AUDIO_SAMPLERATE); + mResampler48.start(AUDIO_CHANNELS, 48000, AUDIO_SAMPLERATE); + + // Init codecs + mCodecList.fillCodecMap(mCodecMap); + +#if defined(DUMP_DECODED) + mDecodedDump = std::make_shared(); + mDecodedDump->open("decoded.wav", 8000 /*G711*/, AUDIO_CHANNELS); +#endif +} + +AudioReceiver::~AudioReceiver() +{ +#if defined(USE_PVQA_LIBRARY) && !defined(PVQA_SERVER) + if (mPVQA && mPvqaBuffer) + { + mStat.mPvqaMos = calculatePvqaMos(AUDIO_SAMPLERATE, mStat.mPvqaReport); + } +#endif + mResampler8.stop(); + mResampler16.stop(); + mResampler32.stop(); + mResampler48.stop(); + mDecodedDump.reset(); +} + + +bool AudioReceiver::add(std::shared_ptr p, Codec** codec) +{ + // Increase codec counter + mStat.mCodecCount[p->GetPayloadType()]++; + + // Check if codec can be handled + CodecMap::iterator codecIter = mCodecMap.find(p->GetPayloadType()); + if (codecIter == mCodecMap.end()) + { + ICELogMedia(<< "Cannot find codec in available codecs"); + return false; // Reject packet with unknown payload type + } + + // Check if codec is created actually + if (!codecIter->second) + { + // Look for ptype + for (int codecIndex = 0; codecIndex < mCodecList.count(); codecIndex++) + if (mCodecList.codecAt(codecIndex).payloadType() == p->GetPayloadType()) + codecIter->second = mCodecList.codecAt(codecIndex).create(); + } + + // Return pointer to codec if needed + if (codec) + *codec = codecIter->second.get(); + + if (mStat.mCodecName.empty()) + mStat.mCodecName = codecIter->second.get()->name(); + + // Estimate time length + int timelen = 0, payloadLength = p->GetPayloadLength(), ptype = p->GetPayloadType(); + + if (!codecIter->second->rtpLength()) + timelen = codecIter->second->frameTime(); + else + timelen = int(double(payloadLength) / codecIter->second->rtpLength() * codecIter->second->frameTime() + 0.5); + + // Process jitter + mJitterStats.process(p.get(), codecIter->second->samplerate()); + mStat.mJitter = (float)mJitterStats.get().getCurrent(); + + // Check if packet is CNG + if (payloadLength >= 1 && payloadLength <= 6 && (ptype == 0 || ptype == 8)) + timelen = mLastPacketTimeLength ? mLastPacketTimeLength : 20; + else + // Check if packet is too short from time length side + if (timelen < 2) + { + // It will cause statistics to report about bad RTP packet + // I have to replay last packet payload here to avoid report about lost packet + mBuffer.add(p, timelen, codecIter->second->samplerate()); + return false; + } + + // Queue packet to buffer + return mBuffer.add(p, timelen, codecIter->second->samplerate()); +} + +void AudioReceiver::processDecoded(Audio::DataWindow& output, DecodeOptions options) +{ + // Write to audio dump if requested + if (mDecodedDump && mDecodedLength) + mDecodedDump->write(mDecodedFrame, mDecodedLength); + + // Resample to target rate + bool resample = !((int)options & (int)DecodeOptions::DontResample); + makeMonoAndResample(resample ? mCodec->samplerate() : 0, + mCodec->channels()); + + // Update PVQA with stats +#if defined(USE_PVQA_LIBRARY) && !defined(PVQA_SERVER) + updatePvqa(mResampledFrame, mResampledLength); +#endif + + // Send to output + output.add(mResampledFrame, mResampledLength); +} + +bool AudioReceiver::getAudio(Audio::DataWindow& output, DecodeOptions options, int* rate) +{ + bool result = false; + + // Get next packet from buffer + RtpBuffer::ResultList rl; + RtpBuffer::FetchResult fr = mBuffer.fetch(rl); + switch (fr) + { + case RtpBuffer::FetchResult::Gap: + ICELogInfo(<< "Gap detected."); + + mDecodedLength = mResampledLength = 0; + if (mCngPacket && mCodec) + { + // Synthesize comfort noise. It will be done on AUDIO_SAMPLERATE rate directly to mResampledFrame buffer. + // Do not forget to send this noise to analysis + mDecodedLength = mCngDecoder.produce(mCodec->samplerate(), mLastPacketTimeLength, (short*)mDecodedFrame, false); + } + else + if (mCodec && mFrameCount && !mCodecSettings.mSkipDecode) + { + // Do PLC to mDecodedFrame/mDecodedLength + mDecodedLength = mCodec->plc(mFrameCount, mDecodedFrame, sizeof mDecodedFrame); + } + if (mDecodedLength) + { + processDecoded(output, options); + result = true; + } + break; + + case RtpBuffer::FetchResult::NoPacket: + ICELogDebug(<< "No packet available in jitter buffer"); + mFailedCount++; +#if defined(USE_PVQA_LIBRARY) && !defined(PVQA_SERVER) + if (mResampledLength > 0) + updatePvqa(nullptr, mResampledLength); +#endif + break; + + case RtpBuffer::FetchResult::RegularPacket: + mFailedCount = 0; + + for (std::shared_ptr& p: rl) + { + assert(p); + // Check if previously CNG packet was detected. Emit CNG audio here if needed. + if ((int)options & (int)DecodeOptions::FillCngGap && mCngPacket && mCodec) + { + // Fill CNG audio is server mode is present + int units = p->GetTimestamp() - mCngPacket->GetTimestamp(); + int milliseconds = units / (mCodec->samplerate() / 1000); + if (milliseconds > mLastPacketTimeLength) + { + int frames100ms = milliseconds / 100; + for (int frameIndex = 0; frameIndex < frames100ms; frameIndex++) + { + mDecodedLength = mCngDecoder.produce(mCodec->samplerate(), 100, (short*)mDecodedFrame, false); + if (mDecodedLength) + processDecoded(output, options); + } + // Do not forget about tail! + int tail = milliseconds % 100; + if (tail) + { + mDecodedLength = mCngDecoder.produce(mCodec->samplerate(), tail, (short*)mDecodedFrame, false); + if (mDecodedLength) + processDecoded(output, options); + } + result = true; + } + } + + // Find codec + mCodec = mCodecMap[p->GetPayloadType()]; + if (mCodec) + { + if (rate) + *rate = mCodec->samplerate(); + + // Check if it is CNG packet + if ((p->GetPayloadType() == 0 || p->GetPayloadType() == 8) && p->GetPayloadLength() >= 1 && p->GetPayloadLength() <= 6) + { + mCngPacket = p; + mCngDecoder.decode3389(p->GetPayloadData(), p->GetPayloadLength()); + // Emit CNG mLastPacketLength milliseconds + mDecodedLength = mCngDecoder.produce(mCodec->samplerate(), mLastPacketTimeLength, (short*)mDecodedFrame, true); + if (mDecodedLength) + processDecoded(output, options); + result = true; + } + else + { + // Reset CNG packet + mCngPacket.reset(); + + // Handle here regular RTP packets + // Check if payload length is ok + int tail = mCodec->rtpLength() ? p->GetPayloadLength() % mCodec->rtpLength() : 0; + + if (!tail) + { + // Find number of frames + mFrameCount = mCodec->rtpLength() ? p->GetPayloadLength() / mCodec->rtpLength() : 1; + int frameLength = mCodec->rtpLength() ? mCodec->rtpLength() : (int)p->GetPayloadLength(); + + // Save last packet time length + mLastPacketTimeLength = mFrameCount * mCodec->frameTime(); + + // Decode + for (int i=0; idecode(p->GetPayloadData() + i*mCodec->rtpLength(), + frameLength, mDecodedFrame, sizeof mDecodedFrame); + if (mDecodedLength) + processDecoded(output, options); + } + result = mFrameCount > 0; + + // Check for bitrate counter + #if defined(USE_AMR_CODEC) + processStatisticsWithAmrCodec(mCodec.get()); + #endif + } + else + ICELogMedia(<< "RTP packet with tail."); + } + } + } + break; + + default: + assert(0); + } + + return result; +} + +void AudioReceiver::makeMonoAndResample(int rate, int channels) +{ + // Make mono from stereo - engine works with mono only for now + mConvertedLength = 0; + if (channels != AUDIO_CHANNELS) + { + if (channels == 1) + mConvertedLength = Audio::ChannelConverter::monoToStereo(mDecodedFrame, mDecodedLength, mConvertedFrame, mDecodedLength * 2); + else + mDecodedLength = Audio::ChannelConverter::stereoToMono(mDecodedFrame, mDecodedLength, mDecodedFrame, mDecodedLength / 2); + } + + void* frames = mConvertedLength ? mConvertedFrame : mDecodedFrame; + unsigned length = mConvertedLength ? mConvertedLength : mDecodedLength; + + Audio::Resampler* r = NULL; + switch (rate) + { + case 8000: r = &mResampler8; break; + case 16000: r = &mResampler16; break; + case 32000: r = &mResampler32; break; + case 48000: r = &mResampler48; break; + default: + memcpy(mResampledFrame, frames, length); + mResampledLength = length; + return; + } + + int processedInput = 0; + mResampledLength = r->processBuffer(frames, length, processedInput, mResampledFrame, r->getDestLength(length)); + // processedInput result value is ignored - it is always equal to length as internal sample rate is 8/16/32/48K +} + +Codec* AudioReceiver::findCodec(int payloadType) +{ + MT::CodecMap::const_iterator codecIter = mCodecMap.find(payloadType); + if (codecIter == mCodecMap.end()) + return nullptr; + + return codecIter->second.get(); +} + +#if defined(USE_PVQA_LIBRARY) && !defined(PVQA_SERVER) +void AudioReceiver::initPvqa() +{ + // Allocate space for 20 seconds audio + if (!mPvqaBuffer) + { + mPvqaBuffer = std::make_shared(); + mPvqaBuffer->setCapacity(Audio::Format().sizeFromTime(20000)); + } + + // Instantiate & open PVQA analyzer + if (!mPVQA) + { + mPVQA = std::make_shared(); + mPVQA->open(PVQA_INTERVAL, MT::SevanaPVQA::Model::Stream); + } +} + +void AudioReceiver::updatePvqa(const void *data, int size) +{ + if (!mPVQA) + initPvqa(); + + if (mPVQA) + { + if (data) + mPvqaBuffer->add(data, size); + else + mPvqaBuffer->addZero(size); + + Audio::Format fmt; + int frames = (int)fmt.timeFromSize(mPvqaBuffer->filled()) / (PVQA_INTERVAL * 1000); + if (frames > 0) + { + int time4pvqa = (int)(frames * PVQA_INTERVAL * 1000); + int size4pvqa = (int)fmt.sizeFromTime(time4pvqa); + ICELogInfo(<< "Updating PVQA with " << time4pvqa << " milliseconds of audio."); + mPVQA->update(fmt.mRate, fmt.mChannels, mPvqaBuffer->data(), size4pvqa); + mPvqaBuffer->erase(size4pvqa); + } + } +} + +float AudioReceiver::calculatePvqaMos(int rate, std::string& report) +{ + if (mPVQA && mPvqaBuffer) + { + // Flush remaining audio to analyzer + /*if (mPvqaBuffer->filled()) + { + mPVQA->update(rate, AUDIO_CHANNELS, mPvqaBuffer->data(), mPvqaBuffer->filled()); + mPvqaBuffer->clear(); + }*/ + return mPVQA->getResults(report, nullptr, rate, MT::SevanaPVQA::Codec::None); + } + return 0.0f; +} +#endif + + +#if defined(USE_AMR_CODEC) +void AudioReceiver::processStatisticsWithAmrCodec(Codec* c) +{ + AmrNbCodec* nb = dynamic_cast(c); + AmrWbCodec* wb = dynamic_cast(c); + + if (nb != nullptr) + mStat.mBitrateSwitchCounter = nb->getSwitchCounter(); + else + if (wb != nullptr) + mStat.mBitrateSwitchCounter = wb->getSwitchCounter(); +} +#endif + +int AudioReceiver::getSize() const +{ + int result = 0; + result += sizeof(*this) + mResampler8.getSize() + mResampler16.getSize() + mResampler32.getSize() + + mResampler48.getSize(); + + if (mCodec) + result += mCodec->getSize(); + + return result; +} + +int AudioReceiver::timelengthFor(jrtplib::RTPPacket& p) +{ + CodecMap::iterator codecIter = mCodecMap.find(p.GetPayloadType()); + if (codecIter == mCodecMap.end()) + return 0; + + PCodec codec = codecIter->second; + if (codec) + { + int frameCount = p.GetPayloadLength() / codec->rtpLength(); + if (p.GetPayloadType() == 9/*G729A silence*/ && p.GetPayloadLength() % codec->rtpLength()) + frameCount++; + + return frameCount * codec->frameTime(); + } + else + return 0; +} + +int AudioReceiver::samplerateFor(jrtplib::RTPPacket& p) +{ + CodecMap::iterator codecIter = mCodecMap.find(p.GetPayloadType()); + if (codecIter != mCodecMap.end()) + { + PCodec codec = codecIter->second; + if (codec) + return codec->samplerate(); + } + + return 8000; +} + +// ----------------------- DtmfReceiver ------------------- +DtmfReceiver::DtmfReceiver(Statistics& stat) +:Receiver(stat) +{ +} + +DtmfReceiver::~DtmfReceiver() +{ +} + +void DtmfReceiver::add(std::shared_ptr p) +{ +} diff --git a/src/engine/media/MT_AudioReceiver.h b/src/engine/media/MT_AudioReceiver.h new file mode 100644 index 00000000..4a608bc0 --- /dev/null +++ b/src/engine/media/MT_AudioReceiver.h @@ -0,0 +1,199 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __MT_AUDIO_RECEIVER_H +#define __MT_AUDIO_RECEIVER_H + +#include "MT_Stream.h" +#include "MT_CodecList.h" +#include "MT_AudioCodec.h" +#include "MT_CngHelper.h" +#include "../helper/HL_Pointer.h" +#include "../helper/HL_Sync.h" +#include "../helper/HL_Optional.hpp" + +#include "jrtplib/src/rtppacket.h" +#include "jrtplib/src/rtcppacket.h" +#include "jrtplib/src/rtpsourcedata.h" +#include "../audio/Audio_DataWindow.h" +#include "../audio/Audio_Resampler.h" + +#include + +#if defined(USE_PVQA_LIBRARY) +# include "MT_SevanaMos.h" +#endif + + +// #define DUMP_DECODED + +namespace MT +{ + using jrtplib::RTPPacket; + class RtpBuffer + { + public: + enum class FetchResult + { + RegularPacket, + Gap, + NoPacket + }; + + // Owns rtp packet data + class Packet + { + public: + Packet(std::shared_ptr packet, int timelen, int rate); + std::shared_ptr rtp() const; + int timelength() const; + int rate() const; + + protected: + std::shared_ptr mRtp; + int mTimelength = 0, mRate = 0; + }; + + RtpBuffer(Statistics& stat); + ~RtpBuffer(); + + unsigned ssrc(); + void setSsrc(unsigned ssrc); + void setHigh(int milliseconds); + int high(); + void setLow(int milliseconds); + int low(); + void setPrebuffer(int milliseconds); + int prebuffer(); + int getNumberOfReturnedPackets() const; + int getNumberOfAddPackets() const; + int findTimelength(); + int getCount() const; + // Returns false if packet was not add - maybe too old or too new or duplicate + bool add(std::shared_ptr packet, int timelength, int rate); + + typedef std::vector> ResultList; + typedef std::shared_ptr PResultList; + + FetchResult fetch(ResultList& rl); + + protected: + unsigned mSsrc; + int mHigh, mLow, mPrebuffer; + int mReturnedCounter, mAddCounter; + mutable Mutex mGuard; + typedef std::vector PacketList; + PacketList mPacketList; + Statistics& mStat; + bool mFirstPacketWillGo; + jrtplib::RTPSourceStats mRtpStats; + Packet mFetchedPacket; + }; + + class Receiver + { + public: + Receiver(Statistics& stat); + virtual ~Receiver(); + + protected: + Statistics& mStat; + }; + + class AudioReceiver: public Receiver + { + public: + AudioReceiver(const CodecList::Settings& codecSettings, Statistics& stat); + ~AudioReceiver(); + + // Returns false when packet is rejected as illegal. codec parameter will show codec which will be used for decoding. + // Lifetime of pointer to codec is limited by lifetime of AudioReceiver (it is container). + bool add(std::shared_ptr p, Codec** codec = nullptr); + + // Returns false when there is no rtp data from jitter + enum class DecodeOptions + { + ResampleToMainRate = 0, + DontResample = 1, + FillCngGap = 2 + }; + + bool getAudio(Audio::DataWindow& output, DecodeOptions options = DecodeOptions::ResampleToMainRate, int* rate = nullptr); + + // Looks for codec by payload type + Codec* findCodec(int payloadType); + RtpBuffer& getRtpBuffer() { return mBuffer; } + + // Returns size of AudioReceiver's instance in bytes (including size of all data + codecs + etc.) + int getSize() const; + + // Returns timelength for given packet + int timelengthFor(jrtplib::RTPPacket& p); + + // Return samplerate for given packet + int samplerateFor(jrtplib::RTPPacket& p); + + protected: + RtpBuffer mBuffer; + CodecMap mCodecMap; + PCodec mCodec; + int mFrameCount = 0; + CodecList::Settings mCodecSettings; + CodecList mCodecList; + JitterStatistics mJitterStats; + std::shared_ptr mCngPacket; + CngDecoder mCngDecoder; + + // Buffer to hold decoded data + char mDecodedFrame[65536]; + int mDecodedLength = 0; + + // Buffer to hold data converted to stereo/mono + char mConvertedFrame[32768]; + int mConvertedLength = 0; + + // Buffer to hold data resampled to AUDIO_SAMPLERATE + char mResampledFrame[65536]; + int mResampledLength = 0; + + // Last packet time length + int mLastPacketTimeLength = 0; + + int mFailedCount; + Audio::Resampler mResampler8, mResampler16, + mResampler32, mResampler48; + + Audio::PWavFileWriter mDecodedDump; + + // Zero rate will make audio mono but resampling will be skipped + void makeMonoAndResample(int rate, int channels); + + // Resamples, sends to analysis, writes to dump and queues to output decoded frames from mDecodedFrame + void processDecoded(Audio::DataWindow& output, DecodeOptions options); + +#if defined(USE_PVQA_LIBRARY) && !defined(PVQA_SERVER) + std::shared_ptr mPVQA; + void initPvqa(); + void updatePvqa(const void* data, int size); + float calculatePvqaMos(int rate, std::string& report); + std::shared_ptr mPvqaBuffer; +#endif + +#if defined(USE_AMR_CODEC) + void processStatisticsWithAmrCodec(Codec* c); +#endif + }; + + class DtmfReceiver: public Receiver + { + public: + DtmfReceiver(Statistics& stat); + ~DtmfReceiver(); + + void add(std::shared_ptr p); + }; +} + +#endif diff --git a/src/engine/media/MT_AudioStream.cpp b/src/engine/media/MT_AudioStream.cpp new file mode 100644 index 00000000..fbb3fb3a --- /dev/null +++ b/src/engine/media/MT_AudioStream.cpp @@ -0,0 +1,426 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "MT_AudioStream.h" +#include "MT_Dtmf.h" +#include "../helper/HL_StreamState.h" +#include "../helper/HL_Log.h" +#include "../audio/Audio_Resampler.h" +#include "../audio/Audio_Interface.h" + +#include "jrtplib/src/rtpipv4address.h" +#include "jrtplib/src/rtpipv6address.h" +#include "jrtplib/src/rtppacket.h" +#include "jrtplib/src/rtptransmitter.h" +#include "jrtplib/src/rtpsessionparams.h" + +#define LOG_SUBSYSTEM "AudioStream" + +//#define DUMP_SENDING_AUDIO + +using namespace MT; +AudioStream::AudioStream(const CodecList::Settings& settings) +:mPacketTime(0), mEncodedTime(0), mCodecSettings(settings), +mRemoteTelephoneCodec(0), mRtpSession(), mTransmittingPayloadType(-1), +mRtpSender(mStat), mRtpDump(NULL) +{ + mOutputBuffer.setCapacity(16384); + mCapturedAudio.setCapacity(16384); + mCaptureResampler8.start(AUDIO_CHANNELS, AUDIO_SAMPLERATE, 8000); + mCaptureResampler16.start(AUDIO_CHANNELS, AUDIO_SAMPLERATE, 16000); + mCaptureResampler32.start(AUDIO_CHANNELS, AUDIO_SAMPLERATE, 32000); + mCaptureResampler48.start(AUDIO_CHANNELS, AUDIO_SAMPLERATE, 48000); + + // Configure transmitter + jrtplib::RTPExternalTransmissionParams params(&mRtpSender, 0); + + jrtplib::RTPSessionParams sessionParams; + sessionParams.SetAcceptOwnPackets(true); + sessionParams.SetMaximumPacketSize(MT_MAXRTPPACKET); + sessionParams.SetResolveLocalHostname(false); + sessionParams.SetUsePollThread(false); + sessionParams.SetOwnTimestampUnit(1/8000.0); + mRtpSession.Create(sessionParams, ¶ms, jrtplib::RTPTransmitter::ExternalProto); + mRtpDtmfSession.Create(sessionParams, ¶ms, jrtplib::RTPTransmitter::ExternalProto); + + // Attach srtp session to sender + mRtpSender.setSrtpSession(&mSrtpSession); + //mRtpDump = new RtpDump("d:\\outgoing.rtp"); + //mRtpSender.setDumpWriter(mRtpDump); + +#if defined(DUMP_SENDING_AUDIO) + mSendingDump = std::make_shared(); + mSendingDump->open("sending_audio.wav", 8000, 1); +#endif +} + +AudioStream::~AudioStream() +{ + ICELogInfo(<< "Delete AudioStream instance"); + if (mSendingDump) + { + mSendingDump->close(); + mSendingDump.reset(); + } + + // Delete used rtp streams + for (AudioStreamMap::iterator streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + delete streamIter->second; + mStreamMap.clear(); + + if (mRtpDtmfSession.IsActive()) + mRtpDtmfSession.Destroy(); + if (mRtpSession.IsActive()) + mRtpSession.Destroy(); + + if (mRtpDump) + { + mRtpDump->flush(); + delete mRtpDump; + } + + mCaptureResampler8.stop(); + mCaptureResampler16.stop(); + mCaptureResampler32.stop(); + mCaptureResampler48.stop(); + ICELogInfo(<< "Encoded " << mEncodedTime << " milliseconds of audio"); + + if (mDumpStreams.mStreamForRecordingIncoming) + mDumpStreams.mStreamForRecordingIncoming->close(); + if (mDumpStreams.mStreamForReadingOutgoing) + mDumpStreams.mStreamForReadingOutgoing->close(); + + if (mFinalStatistics) + *mFinalStatistics = mStat; + + ICELogInfo(<< mStat.toShortString()); +} + +void AudioStream::setDestination(const RtpPair& dest) +{ + Lock l(mMutex); + Stream::setDestination(dest); + mRtpSender.setDestination(dest); +} + +void AudioStream::setTransmittingCodec(Codec::Factory& factory, int payloadType) +{ + ICELogInfo(<< "Selected codec " << factory.name() << "/" << factory.samplerate() << " for transmitting"); + Lock l(mMutex); + mTransmittingCodec = factory.create(); + mTransmittingPayloadType = payloadType; + if (mRtpSession.IsActive()) + mRtpSession.SetTimestampUnit(1.0 / mTransmittingCodec->samplerate()); +} + +PCodec AudioStream::transmittingCodec() +{ + Lock l(mMutex); + return mTransmittingCodec; +} + +void AudioStream::addData(const void* buffer, int bytes) +{ + assert(bytes == AUDIO_MIC_BUFFER_SIZE); + + // Read predefined audio if configured + if (mDumpStreams.mStreamForReadingOutgoing) + { + if (mDumpStreams.mStreamForReadingOutgoing->isOpened()) + mDumpStreams.mStreamForReadingOutgoing->read(const_cast(buffer), bytes); + } + + // Read mirrored audio if needed + if (mMirror && mMirrorPrebuffered) + mMirrorBuffer.read(const_cast(buffer), bytes); + + if (mMediaObserver) + mMediaObserver->onMedia(buffer, bytes, MT::Stream::MediaDirection::Outgoing, this, mMediaObserverTag); + + Codec* codec = NULL; + { + Lock l(mMutex); + codec = mTransmittingCodec.get(); + if (!codec) + return; + } + + // Resample + unsigned dstlen = unsigned(float(codec->samplerate() / float(AUDIO_SAMPLERATE)) * bytes); + Audio::Resampler* r = NULL; + switch (codec->samplerate()) + { + case 8000: r = &mCaptureResampler8; break; + case 16000: r = &mCaptureResampler16; break; + case 32000: r = &mCaptureResampler32; break; + case 48000: r = &mCaptureResampler48; break; + default: + assert(0); + } + + int processedInput = 0; + dstlen = r->processBuffer(buffer, bytes, processedInput, mResampleBuffer, dstlen); + // ProcessedInput output value is ignored - because sample rate of input is always 8/16/32/48K - so all buffer is processed + + // See if we need stereo <-> mono conversions + unsigned stereolen = 0; + if (codec->channels() != AUDIO_CHANNELS) + { + if (codec->channels() == 2) + stereolen = Audio::ChannelConverter::monoToStereo(mResampleBuffer, dstlen, mStereoBuffer, dstlen * 2); + else + dstlen = Audio::ChannelConverter::stereoToMono(mResampleBuffer, dstlen, mResampleBuffer, dstlen / 2); + } + + // See if inband dtmf audio should be sent instead + ByteBuffer dtmf; + if (mDtmfContext.type() == DtmfContext::Dtmf_Inband && mDtmfContext.getInband(AUDIO_MIC_BUFFER_LENGTH, codec->samplerate(), dtmf)) + mCapturedAudio.add(dtmf.data(), dtmf.size()); + else + mCapturedAudio.add(stereolen ? mStereoBuffer : mResampleBuffer, stereolen ? stereolen : dstlen); + + // See if it is time to send RFC2833 tone + ByteBuffer rfc2833, stopPacket; + if (mDtmfContext.type() == DtmfContext::Dtmf_Rfc2833 && mDtmfContext.getRfc2833(AUDIO_MIC_BUFFER_LENGTH, rfc2833, stopPacket)) + { + if (rfc2833.size()) + mRtpDtmfSession.SendPacket(rfc2833.data(), rfc2833.size(), mRemoteTelephoneCodec, true, AUDIO_MIC_BUFFER_LENGTH * 8); + + if (stopPacket.size()) + { + for (int i=0; i<3; i++) + mRtpDtmfSession.SendPacket(stopPacket.data(), stopPacket.size(), mRemoteTelephoneCodec, true, AUDIO_MIC_BUFFER_LENGTH * 8); + } + } + + int processed = 0; + int encodedTime = 0; + int packetTime = mPacketTime ? mPacketTime : codec->frameTime(); + + // Make stereo version if required + for (int i=0; ipcmLength(); i++) + { + if (mSendingDump) + mSendingDump->write((const char*)mCapturedAudio.data() + codec->pcmLength() * i, codec->pcmLength()); + + int produced; + produced = codec->encode((const char*)mCapturedAudio.data() + codec->pcmLength()*i, + codec->pcmLength(), mFrameBuffer, MT_MAXAUDIOFRAME); + + // Counter of processed input bytes of raw pcm data from microphone + processed += codec->pcmLength(); + encodedTime += codec->frameTime(); + mEncodedTime += codec->frameTime(); + + if (produced) + { + mEncodedAudio.appendBuffer(mFrameBuffer, produced); + if (packetTime <= encodedTime) + { + // Time to send packet + ICELogMedia(<< "Sending RTP packet pt = " << mTransmittingPayloadType << ", plength = " << (int)mEncodedAudio.size()); + mRtpSession.SendPacketEx(mEncodedAudio.data(), mEncodedAudio.size(), mTransmittingPayloadType, false, + packetTime * codec->samplerate()/1000, 0, NULL, 0); + mEncodedAudio.clear(); + encodedTime = 0; + } + } + } + mCapturedAudio.erase(processed); +} + +void AudioStream::copyDataTo(Audio::Mixer& mixer, int needed) +{ + // Local audio mixer - used to send audio to media observer + Audio::Mixer localMixer; + Audio::DataWindow forObserver; + + // Iterate + for (auto& streamIter: mStreamMap) + { + Audio::DataWindow w; + w.setCapacity(32768); + + SingleAudioStream* sas = streamIter.second; + if (sas) + { + sas->copyPcmTo(w, needed); + + // Provide mirroring if needed + if (mMirror) + { + mMirrorBuffer.add(w.data(), w.filled()); + if (!mMirrorPrebuffered) + mMirrorPrebuffered = mMirrorBuffer.filled() >= MT_MIRROR_PREBUFFER; + } + + if (!(state() & (int)StreamState::Receiving)) + w.zero(needed); + + // Check if we do not need input from this stream + if (w.filled()) + { + if (mDumpStreams.mStreamForRecordingIncoming) + { + if (mDumpStreams.mStreamForRecordingIncoming->isOpened()) + mDumpStreams.mStreamForRecordingIncoming->write(w.data(), w.filled()); + } + mixer.addPcm(this, streamIter.first, w, AUDIO_SAMPLERATE, false); + + if (mMediaObserver) + localMixer.addPcm(this, streamIter.first, w, AUDIO_SAMPLERATE, false); + } + } + } + + if (mMediaObserver) + { + localMixer.mixAndGetPcm(forObserver); + mMediaObserver->onMedia(forObserver.data(), forObserver.capacity(), MT::Stream::MediaDirection::Incoming, this, mMediaObserverTag); + } +} + +void AudioStream::dataArrived(PDatagramSocket s, const void* buffer, int length, InternetAddress& source) +{ + jrtplib::RTPIPv6Address addr6; + jrtplib::RTPIPv4Address addr4; + jrtplib::RTPExternalTransmissionInfo* info = dynamic_cast(mRtpSession.GetTransmissionInfo()); + assert(info); + + // Drop RTP packets if stream is not receiving now; let RTCP go + if (!(state() & (int)StreamState::Receiving) && RtpHelper::isRtp(buffer, length)) + { + ICELogMedia(<< "Stream is not allowed to receive RTP stream. Ignore the packet"); + return; + } + + // Copy incoming data to temp buffer to perform possible srtp unprotect + int receiveLength = length; + memcpy(mReceiveBuffer, buffer, length); + + bool srtpResult; + if (mSrtpSession.active()) + { + if (RtpHelper::isRtp(mReceiveBuffer, receiveLength)) + srtpResult = mSrtpSession.unprotectRtp(mReceiveBuffer, &receiveLength); + else + srtpResult = mSrtpSession.unprotectRtcp(mReceiveBuffer, &receiveLength); + if (!srtpResult) + { + ICELogCritical(<<"Cannot decrypt SRTP packet."); + return; + } + } + + switch (source.family()) + { + case AF_INET: + addr4.SetIP(source.sockaddr4()->sin_addr.s_addr); + addr4.SetPort(source.port()); + ICELogMedia(<< "Injecting RTP/RTCP packet into jrtplib"); + info->GetPacketInjector()->InjectRTPorRTCP(mReceiveBuffer, receiveLength, addr4); + break; + + case AF_INET6: + addr6.SetIP(source.sockaddr6()->sin6_addr); + addr6.SetPort(source.port()); + ICELogMedia(<< "Injecting RTP/RTCP packet into jrtplib"); + info->GetPacketInjector()->InjectRTPorRTCP(mReceiveBuffer, receiveLength, addr6); + break; + + default: + assert(0); + } + + mStat.mReceived += length; + if (RtpHelper::isRtp(mReceiveBuffer, receiveLength)) + { + if (!mStat.mFirstRtpTime.is_initialized()) + mStat.mFirstRtpTime = std::chrono::system_clock::now(); + mStat.mReceivedRtp++; + } + else + mStat.mReceivedRtcp++; + + mRtpSession.Poll(); // maybe it is extra with external transmitter + bool hasData = mRtpSession.GotoFirstSourceWithData(); + while (hasData) + { + std::shared_ptr packet(mRtpSession.GetNextPacket()); + if (packet) + { + ICELogMedia(<< "jrtplib returned packet"); + // Find right handler for rtp stream + SingleAudioStream* rtpStream = nullptr; + AudioStreamMap::iterator streamIter = mStreamMap.find(packet->GetSSRC()); + if (streamIter == mStreamMap.end()) + mStreamMap[packet->GetSSRC()] = rtpStream = new SingleAudioStream(mCodecSettings, mStat); + else + rtpStream = streamIter->second; + + // Process incoming data packet + rtpStream->process(packet); + + double rtt = mRtpSession.GetCurrentSourceInfo()->INF_GetRoundtripTime().GetDouble(); + if (rtt > 0) + mStat.mRttDelay.process(rtt); + } + hasData = mRtpSession.GotoNextSourceWithData(); + } +} + +void AudioStream::setState(unsigned state) +{ + Stream::setState(state); +} + +void AudioStream::setTelephoneCodec(int payloadType) +{ + mRemoteTelephoneCodec = payloadType; +} + +void AudioStream::setSocket(const RtpPair& socket) +{ + Stream::setSocket(socket); + mRtpSender.setSocket(socket); +} + +DtmfContext& AudioStream::queueOfDtmf() +{ + return mDtmfContext; +} + +void AudioStream::readFile(const Audio::PWavFileReader& stream, MediaDirection direction) +{ + switch (direction) + { + case MediaDirection::Outgoing: mDumpStreams.mStreamForReadingOutgoing = stream; break; + case MediaDirection::Incoming: mDumpStreams.mStreamForReadingIncoming = stream; break; + } +} + +void AudioStream::writeFile(const Audio::PWavFileWriter& writer, MediaDirection direction) +{ + switch (direction) + { + case MediaDirection::Outgoing: mDumpStreams.mStreamForRecordingOutgoing = writer; break; + case MediaDirection::Incoming: mDumpStreams.mStreamForRecordingIncoming = writer; break; + } +} + +void AudioStream::setupMirror(bool enable) +{ + if (!mMirror && enable) + { + mMirrorBuffer.setCapacity(MT_MIRROR_CAPACITY); + mMirrorPrebuffered = false; + } + mMirror = enable; +} + +void AudioStream::setFinalStatisticsOutput(Statistics* stats) +{ + mFinalStatistics = stats; +} diff --git a/src/engine/media/MT_AudioStream.h b/src/engine/media/MT_AudioStream.h new file mode 100644 index 00000000..648b8ad0 --- /dev/null +++ b/src/engine/media/MT_AudioStream.h @@ -0,0 +1,110 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __MT_AUDIOSTREAM_H +#define __MT_AUDIOSTREAM_H + +#include "../config.h" +#include "MT_Stream.h" +#include "MT_NativeRtpSender.h" +#include "MT_SingleAudioStream.h" +#include "MT_Dtmf.h" +#include "../helper/HL_VariantMap.h" +#include "../helper/HL_ByteBuffer.h" +#include "../helper/HL_NetworkSocket.h" +#include "../helper/HL_Rtp.h" +#include "../audio/Audio_DataWindow.h" +#include "../audio/Audio_Mixer.h" +#include "../audio/Audio_Resampler.h" +#include "ice/ICESync.h" +#include "jrtplib/src/rtpsession.h" +#include "jrtplib/src/rtpexternaltransmitter.h" +#include "audio/Audio_WavFile.h" + +namespace MT +{ + + class AudioStream: public Stream + { + public: + AudioStream(const CodecList::Settings& codecSettings); + ~AudioStream(); + + void setDestination(const RtpPair& dest) override; + //void setPacketTime(int packetTime); + + void setTransmittingCodec(Codec::Factory& factory, int payloadType) override; + PCodec transmittingCodec(); + + // Called to queue data captured from microphone. + // Buffer holds 16bits PCM data with AUDIO_SAMPLERATE rate and AUDIO_CHANNELS channels. + void addData(const void* buffer, int length); + + // Called to get data to speaker (or mixer) + void copyDataTo(Audio::Mixer& mixer, int needed); + + // Called to process incoming rtp packet + void dataArrived(PDatagramSocket s, const void* buffer, int length, InternetAddress& source) override; + void setSocket(const RtpPair& socket) override; + void setState(unsigned state) override; + + void setTelephoneCodec(int payloadType); + DtmfContext& queueOfDtmf(); + + void readFile(const Audio::PWavFileReader& stream, MediaDirection direction) override; + void writeFile(const Audio::PWavFileWriter& writer, MediaDirection direction) override; + void setupMirror(bool enable) override; + + void setFinalStatisticsOutput(Statistics* stats); + + protected: + Audio::DataWindow mCapturedAudio; // Data from microphone + Audio::DataWindow mStereoCapturedAudio; + char mIncomingPcmBuffer[AUDIO_MIC_BUFFER_SIZE]; // Temporary buffer to allow reading from file + char mResampleBuffer[AUDIO_MIC_BUFFER_SIZE*8]; // Temporary buffer to hold data + char mStereoBuffer[AUDIO_MIC_BUFFER_SIZE*8]; // Temporary buffer to hold data converted to stereo + PCodec mTransmittingCodec; // Current encoding codec + int mTransmittingPayloadType; // Payload type to mark outgoing packets + int mPacketTime; // Required packet time + char mFrameBuffer[MT_MAXAUDIOFRAME]; // Temporary buffer to hold results of encoder + ByteBuffer mEncodedAudio; // Encoded frame(s) + int mEncodedTime; // Time length of encoded audio + const CodecList::Settings& mCodecSettings; // Configuration for stream + Mutex mMutex; // Mutex + int mRemoteTelephoneCodec; // Payload for remote telephone codec + jrtplib::RTPSession mRtpSession; // Rtp session + jrtplib::RTPSession mRtpDtmfSession; // Rtp dtmf session + NativeRtpSender mRtpSender; + AudioStreamMap mStreamMap; // Map of media streams. Key is RTP's SSRC value. + Audio::DataWindow mOutputBuffer; + RtpDump* mRtpDump; + Audio::Resampler mCaptureResampler8, + mCaptureResampler16, + mCaptureResampler32, + mCaptureResampler48; + DtmfContext mDtmfContext; + char mReceiveBuffer[MAX_VALID_UDPPACKET_SIZE]; + + struct + { + Audio::PWavFileWriter mStreamForRecordingIncoming, + mStreamForRecordingOutgoing; + Audio::PWavFileReader mStreamForReadingIncoming, + mStreamForReadingOutgoing; + } mDumpStreams; + + Audio::PWavFileWriter mSendingDump; + + bool mMirror = false; + bool mMirrorPrebuffered = false; + Audio::DataWindow mMirrorBuffer; + + Statistics* mFinalStatistics = nullptr; + + bool decryptSrtp(void* data, int* len); + }; +}; + +#endif diff --git a/src/engine/media/MT_Box.cpp b/src/engine/media/MT_Box.cpp new file mode 100644 index 00000000..6c0a2df5 --- /dev/null +++ b/src/engine/media/MT_Box.cpp @@ -0,0 +1,132 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "MT_Box.h" +#include "MT_AudioStream.h" +#include "MT_SrtpHelper.h" + +#include "../helper/HL_VariantMap.h" +#include "../helper/HL_Exception.h" +#include "../helper/HL_StreamState.h" +#include "../helper/HL_Log.h" + +#define LOG_SUBSYSTEM "MT::Box" + +using namespace MT; + +Terminal::Terminal(const CodecList::Settings& settings) + :mCodecList(settings) +{ + ICELogDebug(<< "Opening Terminal instance"); + + // Alloc memory for captured audio + mCapturedAudio.setCapacity(AUDIO_MIC_BUFFER_COUNT * AUDIO_MIC_BUFFER_SIZE); + + // Init srtp library + SrtpSession::initSrtp(); +} + +Terminal::~Terminal() +{ + ICELogDebug(<< "Closing Terminal instance"); + mAudioPair.reset(); +} + +PStream Terminal::createStream(int type, VariantMap& config) +{ + PStream result; + switch (type) + { + case Stream::Audio: + result = PStream(new AudioStream(MT::CodecList::Settings::DefaultSettings)); + mAudioList.add(result); + break; + + case Stream::Video: + default: + throw Exception(ERR_NOT_IMPLEMENTED); + } + + return result; +} + +void Terminal::freeStream(PStream stream) +{ + if (AudioStream* audio = dynamic_cast(stream.get())) + { + ICELogDebug(<< "Unregister audio stream from mixer."); + mAudioMixer.unregisterChannel(audio); + + ICELogDebug(<< "Remove audio stream from list."); + mAudioList.remove(stream); + } +} + +CodecList& Terminal::codeclist() +{ + return mCodecList; +} + +Audio::PDevicePair Terminal::audio() +{ + return mAudioPair; +} + +void Terminal::setAudio(const Audio::PDevicePair& audio) +{ + mAudioPair = audio; + if (mAudioPair) + mAudioPair->setDelegate(this); +} + +void Terminal::deviceChanged(Audio::DevicePair* dp) +{ +} + +void Terminal::onMicData(const Audio::Format& f, const void* buffer, int length) +{ + //ICELogMedia(<< "Got " << length << " bytes from microphone"); + + // See if it is enough data to feed streams + mCapturedAudio.add(buffer, length); + if (mCapturedAudio.filled() < AUDIO_MIC_BUFFER_SIZE) + return; + + StreamList sl; + mAudioList.copyTo(&sl); + + // Iterate streams. See what of them requires microphone data. + for (int frameIndex=0; frameIndex < mCapturedAudio.filled() / AUDIO_MIC_BUFFER_SIZE; frameIndex++) + { + for (int i=0; i(sl.streamAt(i).get())) + { + if (stream->state() & (int)StreamState::Sending) + stream->addData(mCapturedAudio.data(), AUDIO_MIC_BUFFER_SIZE); + } + } + mCapturedAudio.erase(AUDIO_MIC_BUFFER_SIZE); + } +} + +void Terminal::onSpkData(const Audio::Format& f, void* buffer, int length) +{ + ICELogMedia(<< "Speaker requests " << length << " bytes"); + if (mAudioMixer.available() < length) + { + Lock l(mAudioList.getMutex()); + + for (int i=0; i(mAudioList.streamAt(i).get())) + { + //if (stream->state() & STATE_RECEIVING) + stream->copyDataTo(mAudioMixer, length - mAudioMixer.available()); + } + } + } + mAudioMixer.getPcm(buffer, length); +} diff --git a/src/engine/media/MT_Box.h b/src/engine/media/MT_Box.h new file mode 100644 index 00000000..70e4e2c1 --- /dev/null +++ b/src/engine/media/MT_Box.h @@ -0,0 +1,47 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __MT_BOX_H +#define __MT_BOX_H + +#include +#include "MT_Stream.h" +#include "MT_CodecList.h" +#include "../audio/Audio_Interface.h" +#include "../audio/Audio_DevicePair.h" +#include "../audio/Audio_Mixer.h" +#include "../helper/HL_VariantMap.h" + +namespace MT +{ + + class Terminal: public Audio::DevicePair::Delegate + { + public: + Terminal(const CodecList::Settings& codecSettings); + ~Terminal(); + + CodecList& codeclist(); + + PStream createStream(int type, VariantMap& config); + void freeStream(PStream s); + + Audio::PDevicePair audio(); + void setAudio(const Audio::PDevicePair& audio); + protected: + StreamList mAudioList; + std::mutex mAudioListMutex; + CodecList mCodecList; + Audio::PDevicePair mAudioPair; + Audio::Mixer mAudioMixer; + Audio::DataWindow mCapturedAudio; + + void deviceChanged(Audio::DevicePair* dp); + void onMicData(const Audio::Format& f, const void* buffer, int length); + void onSpkData(const Audio::Format& f, void* buffer, int length); + }; + +} +#endif diff --git a/src/engine/media/MT_CngHelper.cpp b/src/engine/media/MT_CngHelper.cpp new file mode 100644 index 00000000..0f593706 --- /dev/null +++ b/src/engine/media/MT_CngHelper.cpp @@ -0,0 +1,181 @@ +#include "../config.h" + +#include "MT_CngHelper.h" +#include +#include +#include +#include + +#define NOISE_AMPL 8031 + +#ifndef TARGET_WIN +typedef short __int16; +typedef int __int32; +#endif + +namespace MT +{ + static int GenerateRandom(int maxvalue) + { + assert(maxvalue <= RAND_MAX); + + int result = rand(); + + result = (int)(result / ((float)RAND_MAX / maxvalue) + 0.5); + if (result > maxvalue) + result = maxvalue; + + return result; + } + + class LPFilter + { + public: + static const int NCoef = 1; + static const int DCgain = 128; + + __int16 ACoef[NCoef+1]; + __int16 BCoef[NCoef+1]; + + __int32 y[NCoef+1] = {0, 0}; + __int16 x[NCoef+1] = {0, 0}; + + LPFilter() + { + ACoef[0] = 16707; ACoef[1] = 16707; + BCoef[0] = 32767; BCoef[1] = -32511; + } + + ~LPFilter() + { + + } + + __int16 Do(__int16 sample) + { + int n; + + //shift the old samples + for(n=NCoef; n>0; n--) { + x[n] = x[n-1]; + y[n] = y[n-1]; + } + + //Calculate the new output + x[0] = sample; + y[0] = ACoef[0] * x[0]; + for(n=1; n<=NCoef; n++) + y[0] += ACoef[n] * x[n] - BCoef[n] * y[n]; + + y[0] /= BCoef[0]; + + return y[0] / DCgain; + } + }; + + class HPFilter + { + public: + static const int NCoef = 1; + static const int DCgain = 128; + + __int16 ACoef[NCoef+1]; + __int16 BCoef[NCoef+1]; + + __int32 y[NCoef+1] = {0, 0}; + __int16 x[NCoef+1] = {0, 0}; + + HPFilter() + { + ACoef[0] = 16384; ACoef[1] = -16384; + BCoef[0] = 32767; BCoef[1] = 0; + } + + ~HPFilter() + { + + } + + __int16 Do(__int16 sample) + { + int n; + + //shift the old samples + for(n=NCoef; n>0; n--) { + x[n] = x[n-1]; + y[n] = y[n-1]; + } + + //Calculate the new output + x[0] = sample; + y[0] = ACoef[0] * x[0]; + for(n=1; n<=NCoef; n++) + y[0] += ACoef[n] * x[n] - BCoef[n] * y[n]; + + y[0] /= BCoef[0]; + + return y[0] / DCgain; + } + }; + + + // --------------------- CngHelper ---------------------------- + int CngHelper::parse3389(const void* buf, int size, int rate, int requestLengthInMilliseconds, short* output) + { + assert(buf); + assert(output); + + if (!size || !requestLengthInMilliseconds) + return 0; + + int outputSize = requestLengthInMilliseconds * (rate / 1000); + + // Cast pointer to input data + const unsigned char* dataIn = (const unsigned char*)buf; + + // Get noise level + unsigned char noiseLevel = *dataIn; + float linear = float(1.0 / noiseLevel ? noiseLevel : 1); + + // Generate white noise for 16KHz sample rate + LPFilter lpf; HPFilter hpf; + for (int sampleIndex = 0; sampleIndex < outputSize; sampleIndex++) + { + output[sampleIndex] = GenerateRandom(NOISE_AMPL*2) - NOISE_AMPL; + output[sampleIndex] = lpf.Do(output[sampleIndex]); + output[sampleIndex] = hpf.Do(output[sampleIndex]); + output[sampleIndex] = (short)((float)output[sampleIndex] * linear); + } + + return outputSize * 2; + } + + + // ------------------- CngDecoder -------------------- + + CngDecoder::CngDecoder() + { + WebRtcCng_CreateDec(&mContext); + if (mContext) + WebRtcCng_InitDec(mContext); + } + + CngDecoder::~CngDecoder() + { + if (mContext) + WebRtcCng_FreeDec(mContext); + } + + void CngDecoder::decode3389(const void *buf, int size) + { + if (mContext) + WebRtcCng_UpdateSid(mContext, (WebRtc_UWord8*)buf, size); + } + + int CngDecoder::produce(int rate, int requestedMilliseconds, short *output, bool newPeriod) + { + WebRtcCng_Generate(mContext, output, requestedMilliseconds * rate / 1000, newPeriod ? 1 : 0); + return requestedMilliseconds * rate / 1000 * 2; + } + +} diff --git a/src/engine/media/MT_CngHelper.h b/src/engine/media/MT_CngHelper.h new file mode 100644 index 00000000..6b82934d --- /dev/null +++ b/src/engine/media/MT_CngHelper.h @@ -0,0 +1,29 @@ +#ifndef __MT_CNG_HELPER_H +#define __MT_CNG_HELPER_H + +#include "webrtc/cng/webrtc_cng.h" + +namespace MT +{ + class CngHelper + { + public: + /* Parses RTP 3389 payload and produces CNG to audio buffer. Returns size of produced audio in bytes. */ + static int parse3389(const void* buf, int size, int rate, int requestLengthInMilliseconds, short* output); + }; + + class CngDecoder + { + protected: + CNG_dec_inst* mContext; + + public: + CngDecoder(); + ~CngDecoder(); + + void decode3389(const void* buf, int size); + int produce(int rate, int requestedMilliseconds, short* output, bool newPeriod); + }; +} + +#endif diff --git a/src/engine/media/MT_Codec.cpp b/src/engine/media/MT_Codec.cpp new file mode 100644 index 00000000..a561cfa9 --- /dev/null +++ b/src/engine/media/MT_Codec.cpp @@ -0,0 +1,41 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "MT_Codec.h" + +using namespace MT; + +int Codec::Factory::channels() +{ + return 1; +} + +#ifdef USE_RESIP_INTEGRATION +void Codec::Factory::create(CodecMap& codecs) +{ + codecs[payloadType()] = std::shared_ptr(create()); +} + +void Codec::Factory::updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) +{ + codecs.push_back(resipCodec()); +} + +resip::Codec Codec::Factory::resipCodec() +{ + resip::Codec c(this->name(), this->payloadType(), this->samplerate()); + return c; +} + +int Codec::Factory::processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) +{ + for (resip::SdpContents::Session::Medium::CodecContainer::const_iterator codecIter = codecs.begin(); codecIter != codecs.end(); ++codecIter) + { + if (resipCodec() == *codecIter) + return codecIter->payloadType(); + } + return -1; +} +#endif diff --git a/src/engine/media/MT_Codec.h b/src/engine/media/MT_Codec.h new file mode 100644 index 00000000..61014de7 --- /dev/null +++ b/src/engine/media/MT_Codec.h @@ -0,0 +1,64 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __MT_CODEC_H +#define __MT_CODEC_H + +#ifdef USE_RESIP_INTEGRATION +# include "resiprocate/resip/stack/SdpContents.hxx" +#endif +#include "../helper/HL_Types.h" +#include +#include "../helper/HL_Pointer.h" + + +namespace MT +{ + class Codec; + typedef std::shared_ptr PCodec; + + class CodecMap: public std::map + { + }; + + class Codec + { + public: + class Factory + { + public: + virtual ~Factory() {} + virtual const char* name() = 0; + virtual int samplerate() = 0; + virtual int payloadType() = 0; + virtual PCodec create() = 0; + + virtual int channels(); +#ifdef USE_RESIP_INTEGRATION + typedef std::map CodecMap; + virtual void create(CodecMap& codecs); + virtual void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction); + // Returns payload type from chosen codec if success. -1 is returned for negative result. + virtual int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction); + resip::Codec resipCodec(); +#endif + }; + virtual ~Codec() {} + virtual const char* name() = 0; + virtual int samplerate() = 0; + virtual float timestampUnit() { return float(1.0 / samplerate()); } + virtual int pcmLength() = 0; + virtual int frameTime() = 0; + virtual int rtpLength() = 0; + virtual int channels() { return 1; } + virtual int encode(const void* input, int inputBytes, void* output, int outputCapacity) = 0; + virtual int decode(const void* input, int inputBytes, void* output, int outputCapacity) = 0; + virtual int plc(int lostFrames, void* output, int outputCapacity) = 0; + + // Returns size of codec in memory + virtual int getSize() const { return 0; }; + }; +} +#endif diff --git a/src/engine/media/MT_CodecList.cpp b/src/engine/media/MT_CodecList.cpp new file mode 100644 index 00000000..6e1d1956 --- /dev/null +++ b/src/engine/media/MT_CodecList.cpp @@ -0,0 +1,160 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "../config.h" +#include "MT_CodecList.h" +#include "MT_AudioCodec.h" +#include "MT_AmrCodec.h" + +#include + +using namespace MT; + +CodecList::Settings CodecList::Settings::DefaultSettings; + +CodecList::CodecList(const Settings& settings) + :mSettings(settings) +{ + //mFactoryList.push_back(new OpusCodec::OpusFactory(16000, 1)); +#ifdef USE_OPUS_CODEC + if (settings.mOpusSpec.empty()) + { + mFactoryList.push_back(new OpusCodec::OpusFactory(48000, 2, MT_OPUS_CODEC_PT)); + } + else + { + for (auto spec: settings.mOpusSpec) + { + mFactoryList.push_back(new OpusCodec::OpusFactory(spec.mRate, spec.mChannels, spec.mPayloadType)); + } + } +#endif +#ifdef USE_AMR_CODEC + for (int pt: mSettings.mAmrWbPayloadType) + mFactoryList.push_back(new AmrWbCodec::CodecFactory({mSettings.mWrapIuUP, false, pt})); + for (int pt: mSettings.mAmrWbOctetPayloadType) + mFactoryList.push_back(new AmrWbCodec::CodecFactory({mSettings.mWrapIuUP, true, pt})); + + for (int pt: mSettings.mAmrNbPayloadType) + mFactoryList.push_back(new AmrNbCodec::CodecFactory({mSettings.mWrapIuUP, false, pt})); + for (int pt: mSettings.mAmrNbOctetPayloadType) + mFactoryList.push_back(new AmrNbCodec::CodecFactory({mSettings.mWrapIuUP, true, pt})); + + mFactoryList.push_back(new GsmEfrCodec::GsmEfrFactory(mSettings.mWrapIuUP, mSettings.mGsmEfrPayloadType)); + +#endif + //mFactoryList.push_back(new IsacCodec::IsacFactory16K(mSettings.mIsac16KPayloadType)); + //mFactoryList.push_back(new IlbcCodec::IlbcFactory(mSettings.mIlbc20PayloadType, mSettings.mIlbc30PayloadType)); + mFactoryList.push_back(new G711Codec::AlawFactory()); + mFactoryList.push_back(new G711Codec::UlawFactory()); + + mFactoryList.push_back(new GsmCodec::GsmFactory(mSettings.mGsmFrPayloadLength == 32 ? GsmCodec::Type::Bytes_32 : GsmCodec::Type::Bytes_33, mSettings.mGsmFrPayloadType)); + mFactoryList.push_back(new G722Codec::G722Factory()); + mFactoryList.push_back(new G729Codec::G729Factory()); +#ifndef TARGET_ANDROID + mFactoryList.push_back(new GsmHrCodec::GsmHrFactory(mSettings.mGsmHrPayloadType)); +#endif +} + +CodecList::~CodecList() +{ + for (FactoryList::size_type i=0; ipayloadType()] = factory->create(); + } +} + + +CodecListPriority::CodecListPriority() +{ + +} + +CodecListPriority::~CodecListPriority() +{ + +} + +bool CodecListPriority::isNegativePriority(const CodecListPriority::Item& item) +{ + return item.mPriority < 0; +} + +bool CodecListPriority::compare(const Item& item1, const Item& item2) +{ + return item1.mPriority < item2.mPriority; +} + +void CodecListPriority::setupFrom(PVariantMap vmap) +{ + CodecList::Settings settings; + CodecList cl(settings); + //mPriorityList.resize(cl.count()); + bool emptyVmap = vmap ? vmap->empty() : true; + + if (emptyVmap) + { + for (int i=0; iexists(i) ? vmap->at(i).asInt() : -1; + mPriorityList.push_back(item); + } + + // Remove -1 records + mPriorityList.erase(std::remove_if(mPriorityList.begin(), mPriorityList.end(), isNegativePriority), mPriorityList.end()); + + // Sort by priority + std::sort(mPriorityList.begin(), mPriorityList.end(), compare); + } +} + +int CodecListPriority::count(const CodecList &cl) const +{ + return mPriorityList.size(); +} + +Codec::Factory& CodecListPriority::codecAt(const CodecList& cl, int index) const +{ + return cl.codecAt(mPriorityList[index].mCodecIndex); +} diff --git a/src/engine/media/MT_CodecList.h b/src/engine/media/MT_CodecList.h new file mode 100644 index 00000000..6aec5427 --- /dev/null +++ b/src/engine/media/MT_CodecList.h @@ -0,0 +1,95 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __MT_CODEC_LIST_H +#define __MT_CODEC_LIST_H + +#include "../config.h" +#ifdef USE_RESIP_INTEGRATION +# include "resiprocate/resip/stack/SdpContents.hxx" +#endif +#include "MT_Codec.h" +#include +#include +#include "../helper/HL_VariantMap.h" + +#define ALL_CODECS_STRING "OPUS,ISAC,ILBC,PCMU,PCMA,G722,GSM" + +namespace MT +{ + class CodecList + { + public: + struct Settings + { + bool mWrapIuUP = false; + bool mSkipDecode = false; + + // AMR payload types + std::set mAmrWbPayloadType = { MT_AMRWB_PAYLOADTYPE }; + std::set mAmrNbPayloadType = { MT_AMRNB_PAYLOADTYPE }; + std::set mAmrWbOctetPayloadType = { MT_AMRWB_OCTET_PAYLOADTYPE }; + std::set mAmrNbOctetPayloadType = { MT_AMRNB_OCTET_PAYLOADTYPE }; + + bool isAmrWb(int ptype) const { return mAmrWbOctetPayloadType.count(ptype) > 0 || mAmrWbPayloadType.count(ptype) > 0; } + bool isAmrNb(int ptype) const { return mAmrNbOctetPayloadType.count(ptype) > 0 || mAmrNbPayloadType.count(ptype) > 0; } + + int mIsac16KPayloadType = MT_ISAC16K_PAYLOADTYPE; + int mIsac32KPayloadType = MT_ISAC32K_PAYLOADTYPE; + int mIlbc20PayloadType = MT_ILBC20_PAYLOADTYPE; + int mIlbc30PayloadType = MT_ILBC30_PAYLOADTYPE; + int mGsmFrPayloadType = 3; // GSM is codec with fixed payload type. But sometimes it has to be overwritten. + int mGsmFrPayloadLength = 33; // Expected GSM payload length + int mGsmHrPayloadType = MT_GSMHR_PAYLOADTYPE; + int mGsmEfrPayloadType = MT_GSMEFR_PAYLOADTYPE; + + struct OpusSpec + { + int mPayloadType = 0; + int mRate = 0; + int mChannels = 0; + }; + std::vector mOpusSpec; + + static Settings DefaultSettings; + }; + + CodecList(const Settings& settings); + ~CodecList(); + + int count() const; + Codec::Factory& codecAt(int index) const; + int findCodec(const std::string& name) const; + void fillCodecMap(CodecMap& cm); + + protected: + typedef std::vector FactoryList; + FactoryList mFactoryList; + Settings mSettings; + }; + + class CodecListPriority + { + public: + CodecListPriority(); + ~CodecListPriority(); + + void setupFrom(PVariantMap vmap); + int count(const CodecList& cl) const; + Codec::Factory& codecAt(const CodecList& cl, int index) const; + + protected: + struct Item + { + int mCodecIndex; + int mPriority; + }; + std::vector mPriorityList; + + static bool isNegativePriority(const CodecListPriority::Item& item); + static bool compare(const Item& item1, const Item& item2); + }; +} +#endif diff --git a/src/engine/media/MT_Dtmf.cpp b/src/engine/media/MT_Dtmf.cpp new file mode 100644 index 00000000..7bc2bc53 --- /dev/null +++ b/src/engine/media/MT_Dtmf.cpp @@ -0,0 +1,889 @@ +/* Copyright(C) 2007-2017 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "../config.h" +#include "MT_Dtmf.h" + + +#ifdef TARGET_WIN +# include +#endif +#include +#include +#include + +using namespace MT; + +void DtmfBuilder::buildRfc2833(int tone, int duration, int volume, bool endOfEvent, void* output) +{ + assert(duration); + assert(output); + assert(tone); + + unsigned char toneValue = 0; + if (tone >= '0' && tone <='9') + toneValue = tone - '0'; + else + if (tone >= 'A' && tone <='D' ) + toneValue = tone - 'A' + 12; + else + if (tone == '*') + toneValue = 10; + else + if (tone == '#') + toneValue = 11; + + char* packet = (char*)output; + + packet[0] = toneValue; + packet[1] = 1 | (volume << 2); + if (endOfEvent) + packet[1] |= 128; + else + packet[1] &= 127; + + unsigned short durationValue = htons(duration); + memcpy(packet + 2, &durationValue, 2); +} + +#pragma region Inband DTMF support +#include +#ifndef TARGET_WIN +# include +# if !defined(TARGET_ANDROID) && !defined(TARGET_WIN) +# include +# endif +#endif + +static bool sineTabInit = false; + +static double sinetab[1 << 11]; +static inline double sine(unsigned int ptr) +{ + return sinetab[ptr >> (32-11)]; +} + +#define TWOPI (2.0 * 3.14159265358979323846) +#define MAXSTR 512 +#define SINEBITS 11 +#define SINELEN (1 << SINEBITS) +#define TWO32 4294967296.0 /* 2^32 */ + + +static double amptab[2] = { 8191.75, 16383.5 }; +static inline int ifix(double x) +{ + return (x >= 0.0) ? (int) (x+0.5) : (int) (x-0.5); +} + +// given frequency f, return corresponding phase increment +static inline int phinc(double f) +{ + return ifix(TWO32 * f / (double) AUDIO_SAMPLERATE); +} + +static char dtmfSymbols[16] = { + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + 'A', + 'B', + 'C', + 'D', + '*', + '#' +}; + +char PDTMFEncoder_DtmfChar(int i) +{ + + if (i < 16) + return dtmfSymbols[i]; + else + return 0; +} + +// DTMF frequencies as per http://www.commlinx.com.au/DTMF_frequencies.htm + +static double dtmfFreqs[16][2] = { + { 941.0, 1336.0 }, // 0 + { 697.0, 1209.0 }, // 1 + { 697.0, 1336.0 }, // 2 + { 697.0, 1477.0 }, // 3 + { 770.0, 1209.0 }, // 4 + { 770.0, 1336.0 }, // 5 + { 770.0, 1477.0 }, // 6 + { 852.0, 1209.0 }, // 7 + { 852.0, 1336.0 }, // 8 + { 852.0, 1477.0 }, // 9 + { 697.0, 1633.0 }, // A + { 770.0, 1633.0 }, // B + { 852.0, 1633.0 }, // C + { 941.0, 1633.0 }, // D + { 941.0, 1209.0 }, // * + { 941.0, 1477.0 } // # +}; + + +static Mutex LocalDtmfMutex; + +void PDTMFEncoder_MakeSineTable() +{ + Lock lock(LocalDtmfMutex); + + if (!sineTabInit) { + for (int k = 0; k < SINELEN; k++) { + double th = TWOPI * (double) k / (double) SINELEN; + double v = sin(th); + sinetab[k] = v; + } + sineTabInit = true; + } +} + +void PDTMFEncoder_AddTone(double f1, double f2, unsigned ms1, unsigned ms2, unsigned rate, short* result) +{ + int ak = 0; + + PDTMFEncoder_MakeSineTable(); + + int dataPtr = 0; + + double amp = amptab[ak]; + int phinc1 = phinc(f1), phinc2 = phinc(f2); + int ns1 = ms1 * (rate/1000); + int ns2 = ms2 * (rate/1000); + unsigned int ptr1 = 0, ptr2 = 0; + ptr1 += phinc1 * ns1; + ptr2 += phinc2 * ns1; + + for (int n = ns1; n < ns2; n++) { + + double val = amp * (sine(ptr1) + sine(ptr2)); + int ival = ifix(val); + if (ival < -32768) + ival = -32768; + else if (val > 32767) + ival = 32767; + + result[dataPtr++] = ival / 2; + + ptr1 += phinc1; + ptr2 += phinc2; + } +} + +void PDTMFEncoder_AddTone(char _digit, unsigned startTime, unsigned finishTime, unsigned rate, short* result) +{ + char digit = (char)toupper(_digit); + if ('0' <= digit && digit <= '9') + digit = digit - '0'; + + else if ('A' <= digit && digit <= 'D') + digit = digit + 10 - 'A'; + + else if (digit == '*') + digit = 14; + + else if (digit == '#') + digit = 15; + + else + return ; + + PDTMFEncoder_AddTone(dtmfFreqs[(int)digit][0], dtmfFreqs[(int)digit][1], startTime, finishTime, rate, result); +} + +#pragma endregion + +void DtmfBuilder::buildInband(int tone, int startTime, int finishTime, int rate, short* buf) +{ + PDTMFEncoder_AddTone(tone, startTime, finishTime, rate, buf); +} + +#pragma region DtmfContext +DtmfContext::DtmfContext() +:mType(Dtmf_Rfc2833) +{ +} + +DtmfContext::~DtmfContext() +{ +} + +void DtmfContext::setType(Type t) +{ + mType = t; +} + +DtmfContext::Type DtmfContext::type() +{ + return mType; +} + +void DtmfContext::startTone(int tone, int volume) +{ + Lock l(mGuard); + + // Stop current tone if needed + if (mQueue.size()) + stopTone(); + mQueue.push_back(Dtmf(tone, volume, 0)); +} + +void DtmfContext::stopTone() +{ + Lock l(mGuard); + + // Switch to "emit 3 terminating packets" mode + if (mQueue.size()) + { + switch (mType) + { + case Dtmf_Rfc2833: + mQueue.front().mStopped = true; + mQueue.erase(mQueue.begin()); + break; + + case Dtmf_Inband: + if (!mQueue.front().mFinishCount) + mQueue.front().mFinishCount = MT_DTMF_END_PACKETS; + break; + } + } +} + +void DtmfContext::queueTone(int tone, int volume, int duration) +{ + Lock l(mGuard); + mQueue.push_back(Dtmf(tone, volume, duration)); +} + +void DtmfContext::clearAllTones() +{ + Lock l(mGuard); + mQueue.clear(); +} + +bool DtmfContext::getInband(int milliseconds, int rate, ByteBuffer& output) +{ + Lock l(mGuard); + + if (!mQueue.size() || mType != Dtmf_Inband) + return false; + + // + Dtmf& d = mQueue.front(); + + output.resize(milliseconds * rate / 1000 * 2); + DtmfBuilder::buildInband(d.mTone, d.mCurrentTime, d.mCurrentTime + milliseconds, rate, (short*)output.mutableData()); + d.mCurrentTime += milliseconds; + return true; +} + +bool DtmfContext::getRfc2833(int milliseconds, ByteBuffer& output, ByteBuffer& stopPacket) +{ + Lock l(mGuard); + if (!mQueue.size() || mType != Dtmf_Rfc2833) + return false; + + Dtmf& d = mQueue.front(); + // See if tone has enough duration to produce another packet + if (d.mDuration > 0) + { + // Emit rfc2833 packet + output.resize(4); + DtmfBuilder::buildRfc2833(d.mTone, milliseconds, d.mVolume, false, output.mutableData()); + d.mDuration -= milliseconds; + if(d.mDuration <= 0) + d.mStopped = true; + } + else + if (!d.mStopped) + { + output.resize(4); + DtmfBuilder::buildRfc2833(d.mTone, milliseconds, d.mVolume, false, output.mutableData()); + } + else + output.clear(); + + if (d.mStopped) + { + stopPacket.resize(4); + DtmfBuilder::buildRfc2833(d.mTone, milliseconds, d.mVolume, true, stopPacket.mutableData()); + } + else + stopPacket.clear(); + + if (d.mStopped) + mQueue.erase(mQueue.begin()); + + return true; +} + +typedef struct +{ + float v2; + float v3; + float fac; +} goertzel_state_t; + +#define MAX_DTMF_DIGITS 128 + +typedef struct +{ + int hit1; + int hit2; + int hit3; + int hit4; + int mhit; + + goertzel_state_t row_out[4]; + goertzel_state_t col_out[4]; + goertzel_state_t row_out2nd[4]; + goertzel_state_t col_out2nd[4]; + goertzel_state_t fax_tone; + goertzel_state_t fax_tone2nd; + float energy; + + int current_sample; + char digits[MAX_DTMF_DIGITS + 1]; + int current_digits; + int detected_digits; + int lost_digits; + int digit_hits[16]; + int fax_hits; +} dtmf_detect_state_t; + +typedef struct +{ + float fac; +} tone_detection_descriptor_t; + +void zap_goertzel_update(goertzel_state_t *s, int16_t x[], int samples); +float zap_goertzel_result (goertzel_state_t *s); +void zap_dtmf_detect_init(dtmf_detect_state_t *s); +int zap_dtmf_detect(dtmf_detect_state_t *s, int16_t amp[], int samples, int isradio); +int zap_dtmf_get(dtmf_detect_state_t *s, char *buf, int max); + +DTMFDetector::DTMFDetector() +:mState(NULL) +{ + mState = malloc(sizeof(dtmf_detect_state_t)); + + memset(mState, 0, sizeof(dtmf_detect_state_t)); + zap_dtmf_detect_init((dtmf_detect_state_t*)mState); +} + +DTMFDetector::~DTMFDetector() +{ + if (mState) + free(mState); +} + +std::string DTMFDetector::streamPut(unsigned char* samples, unsigned int size) +{ + char buf[16]; buf[0] = 0; + if (zap_dtmf_detect((dtmf_detect_state_t*)mState, (int16_t*)samples, size/2, 0)) + zap_dtmf_get((dtmf_detect_state_t*)mState, buf, 15); + return buf; +} + +void DTMFDetector::resetState() +{ + zap_dtmf_detect_init((dtmf_detect_state_t*)mState); +} + +#ifndef TRUE + +# define FALSE 0 +# define TRUE (!FALSE) + +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +//#define USE_3DNOW + +/* Basic DTMF specs: + * + * Minimum tone on = 40ms + * Minimum tone off = 50ms + * Maximum digit rate = 10 per second + * Normal twist <= 8dB accepted + * Reverse twist <= 4dB accepted + * S/N >= 15dB will detect OK + * Attenuation <= 26dB will detect OK + * Frequency tolerance +- 1.5% will detect, +-3.5% will reject + */ + +#define SAMPLE_RATE 8000.0 + +#define DTMF_THRESHOLD 8.0e7 +#define FAX_THRESHOLD 8.0e7 +#define FAX_2ND_HARMONIC 2.0 /* 4dB */ +#define DTMF_NORMAL_TWIST 6.3 /* 8dB */ +#define DTMF_REVERSE_TWIST ((isradio) ? 4.0 : 2.5) /* 4dB normal */ +#define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */ +#define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */ +#define DTMF_2ND_HARMONIC_ROW ((isradio) ? 1.7 : 2.5) /* 4dB normal */ +#define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */ + +static tone_detection_descriptor_t dtmf_detect_row[4]; +static tone_detection_descriptor_t dtmf_detect_col[4]; +static tone_detection_descriptor_t dtmf_detect_row_2nd[4]; +static tone_detection_descriptor_t dtmf_detect_col_2nd[4]; +static tone_detection_descriptor_t fax_detect; +static tone_detection_descriptor_t fax_detect_2nd; + +static float dtmf_row[] = +{ + 697.0, 770.0, 852.0, 941.0 +}; +static float dtmf_col[] = +{ + 1209.0, 1336.0, 1477.0, 1633.0 +}; + +static float fax_freq = 1100.0; + +static char dtmf_positions[] = "123A" "456B" "789C" "*0#D"; + +static void goertzel_init(goertzel_state_t *s, + tone_detection_descriptor_t *t) +{ + s->v2 = + s->v3 = 0.0; + s->fac = t->fac; +} +/*- End of function --------------------------------------------------------*/ + +#if defined(USE_3DNOW) +static inline void _dtmf_goertzel_update(goertzel_state_t *s, + float x[], + int samples) +{ + int n; + float v; + int i; + float vv[16]; + + vv[4] = s[0].v2; + vv[5] = s[1].v2; + vv[6] = s[2].v2; + vv[7] = s[3].v2; + vv[8] = s[0].v3; + vv[9] = s[1].v3; + vv[10] = s[2].v3; + vv[11] = s[3].v3; + vv[12] = s[0].fac; + vv[13] = s[1].fac; + vv[14] = s[2].fac; + vv[15] = s[3].fac; + + //v1 = s->v2; + //s->v2 = s->v3; + //s->v3 = s->fac*s->v2 - v1 + x[0]; + + __asm__ __volatile__ ( + " femms;\n" + + " movq 16(%%edx),%%mm2;\n" + " movq 24(%%edx),%%mm3;\n" + " movq 32(%%edx),%%mm4;\n" + " movq 40(%%edx),%%mm5;\n" + " movq 48(%%edx),%%mm6;\n" + " movq 56(%%edx),%%mm7;\n" + + " jmp 1f;\n" + " .align 32;\n" + + " 1: ;\n" + " prefetch (%%eax);\n" + " movq %%mm3,%%mm1;\n" + " movq %%mm2,%%mm0;\n" + " movq %%mm5,%%mm3;\n" + " movq %%mm4,%%mm2;\n" + + " pfmul %%mm7,%%mm5;\n" + " pfmul %%mm6,%%mm4;\n" + " pfsub %%mm1,%%mm5;\n" + " pfsub %%mm0,%%mm4;\n" + + " movq (%%eax),%%mm0;\n" + " movq %%mm0,%%mm1;\n" + " punpckldq %%mm0,%%mm1;\n" + " add $4,%%eax;\n" + " pfadd %%mm1,%%mm5;\n" + " pfadd %%mm1,%%mm4;\n" + + " dec %%ecx;\n" + + " jnz 1b;\n" + + " movq %%mm2,16(%%edx);\n" + " movq %%mm3,24(%%edx);\n" + " movq %%mm4,32(%%edx);\n" + " movq %%mm5,40(%%edx);\n" + + " femms;\n" + : + : "c" (samples), "a" (x), "d" (vv) + : "memory", "eax", "ecx"); + + s[0].v2 = vv[4]; + s[1].v2 = vv[5]; + s[2].v2 = vv[6]; + s[3].v2 = vv[7]; + s[0].v3 = vv[8]; + s[1].v3 = vv[9]; + s[2].v3 = vv[10]; + s[3].v3 = vv[11]; +} +#endif +/*- End of function --------------------------------------------------------*/ + +void zap_goertzel_update(goertzel_state_t *s, + int16_t x[], + int samples) +{ + int i; + float v1; + + for (i = 0; i < samples; i++) + { + v1 = s->v2; + s->v2 = s->v3; + s->v3 = s->fac*s->v2 - v1 + x[i]; + } +} +/*- End of function --------------------------------------------------------*/ + +float zap_goertzel_result (goertzel_state_t *s) +{ + return s->v3*s->v3 + s->v2*s->v2 - s->v2*s->v3*s->fac; +} +/*- End of function --------------------------------------------------------*/ + +void zap_dtmf_detect_init (dtmf_detect_state_t *s) +{ + int i; + float theta; + + s->hit1 = + s->hit2 = 0; + + for (i = 0; i < 4; i++) + { + theta = float(2.0*M_PI*(dtmf_row[i]/SAMPLE_RATE)); + dtmf_detect_row[i].fac = float(2.0*cos(theta)); + + theta = float(2.0*M_PI*(dtmf_col[i]/SAMPLE_RATE)); + dtmf_detect_col[i].fac = float(2.0*cos(theta)); + + theta = float(2.0*M_PI*(dtmf_row[i]*2.0/SAMPLE_RATE)); + dtmf_detect_row_2nd[i].fac = float(2.0*cos(theta)); + + theta = float(2.0*M_PI*(dtmf_col[i]*2.0/SAMPLE_RATE)); + dtmf_detect_col_2nd[i].fac = float(2.0*cos(theta)); + + goertzel_init (&s->row_out[i], &dtmf_detect_row[i]); + goertzel_init (&s->col_out[i], &dtmf_detect_col[i]); + goertzel_init (&s->row_out2nd[i], &dtmf_detect_row_2nd[i]); + goertzel_init (&s->col_out2nd[i], &dtmf_detect_col_2nd[i]); + +s->energy = 0.0; + } + + /* Same for the fax dector */ + theta = float(2.0*M_PI*(fax_freq/SAMPLE_RATE)); + fax_detect.fac = float(2.0 * cos(theta)); + goertzel_init (&s->fax_tone, &fax_detect); + + /* Same for the fax dector 2nd harmonic */ + theta = float(2.0*M_PI*(fax_freq * 2.0/SAMPLE_RATE)); + fax_detect_2nd.fac = float(2.0 * cos(theta)); + goertzel_init (&s->fax_tone2nd, &fax_detect_2nd); + + s->current_sample = 0; + s->detected_digits = 0; + s->lost_digits = 0; + s->digits[0] = '\0'; + s->mhit = 0; +} +/*- End of function --------------------------------------------------------*/ + +int zap_dtmf_detect (dtmf_detect_state_t *s, + int16_t amp[], + int samples, + int isradio) +{ + + float row_energy[4]; + float col_energy[4]; + float fax_energy; + float fax_energy_2nd; + float famp; + float v1; + int i; + int j; + int sample; + int best_row; + int best_col; + int hit; + int limit; + + hit = 0; + for (sample = 0; sample < samples; sample = limit) + { + /* 102 is optimised to meet the DTMF specs. */ + if ((samples - sample) >= (102 - s->current_sample)) + limit = sample + (102 - s->current_sample); + else + limit = samples; +#if defined(USE_3DNOW) + _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample); + _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample); + _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample); + _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample); +/* XXX Need to fax detect for 3dnow too XXX */ +#warning "Fax Support Broken" +#else + /* The following unrolled loop takes only 35% (rough estimate) of the + time of a rolled loop on the machine on which it was developed */ + for (j = sample; j < limit; j++) + { + famp = amp[j]; + + s->energy += famp*famp; + + /* With GCC 2.95, the following unrolled code seems to take about 35% + (rough estimate) as long as a neat little 0-3 loop */ + v1 = s->row_out[0].v2; + s->row_out[0].v2 = s->row_out[0].v3; + s->row_out[0].v3 = s->row_out[0].fac*s->row_out[0].v2 - v1 + famp; + + v1 = s->col_out[0].v2; + s->col_out[0].v2 = s->col_out[0].v3; + s->col_out[0].v3 = s->col_out[0].fac*s->col_out[0].v2 - v1 + famp; + + v1 = s->row_out[1].v2; + s->row_out[1].v2 = s->row_out[1].v3; + s->row_out[1].v3 = s->row_out[1].fac*s->row_out[1].v2 - v1 + famp; + + v1 = s->col_out[1].v2; + s->col_out[1].v2 = s->col_out[1].v3; + s->col_out[1].v3 = s->col_out[1].fac*s->col_out[1].v2 - v1 + famp; + + v1 = s->row_out[2].v2; + s->row_out[2].v2 = s->row_out[2].v3; + s->row_out[2].v3 = s->row_out[2].fac*s->row_out[2].v2 - v1 + famp; + + v1 = s->col_out[2].v2; + s->col_out[2].v2 = s->col_out[2].v3; + s->col_out[2].v3 = s->col_out[2].fac*s->col_out[2].v2 - v1 + famp; + + v1 = s->row_out[3].v2; + s->row_out[3].v2 = s->row_out[3].v3; + s->row_out[3].v3 = s->row_out[3].fac*s->row_out[3].v2 - v1 + famp; + + v1 = s->col_out[3].v2; + s->col_out[3].v2 = s->col_out[3].v3; + s->col_out[3].v3 = s->col_out[3].fac*s->col_out[3].v2 - v1 + famp; + + v1 = s->col_out2nd[0].v2; + s->col_out2nd[0].v2 = s->col_out2nd[0].v3; + s->col_out2nd[0].v3 = s->col_out2nd[0].fac*s->col_out2nd[0].v2 - v1 + famp; + + v1 = s->row_out2nd[0].v2; + s->row_out2nd[0].v2 = s->row_out2nd[0].v3; + s->row_out2nd[0].v3 = s->row_out2nd[0].fac*s->row_out2nd[0].v2 - v1 + famp; + + v1 = s->col_out2nd[1].v2; + s->col_out2nd[1].v2 = s->col_out2nd[1].v3; + s->col_out2nd[1].v3 = s->col_out2nd[1].fac*s->col_out2nd[1].v2 - v1 + famp; + + v1 = s->row_out2nd[1].v2; + s->row_out2nd[1].v2 = s->row_out2nd[1].v3; + s->row_out2nd[1].v3 = s->row_out2nd[1].fac*s->row_out2nd[1].v2 - v1 + famp; + + v1 = s->col_out2nd[2].v2; + s->col_out2nd[2].v2 = s->col_out2nd[2].v3; + s->col_out2nd[2].v3 = s->col_out2nd[2].fac*s->col_out2nd[2].v2 - v1 + famp; + + v1 = s->row_out2nd[2].v2; + s->row_out2nd[2].v2 = s->row_out2nd[2].v3; + s->row_out2nd[2].v3 = s->row_out2nd[2].fac*s->row_out2nd[2].v2 - v1 + famp; + + v1 = s->col_out2nd[3].v2; + s->col_out2nd[3].v2 = s->col_out2nd[3].v3; + s->col_out2nd[3].v3 = s->col_out2nd[3].fac*s->col_out2nd[3].v2 - v1 + famp; + + v1 = s->row_out2nd[3].v2; + s->row_out2nd[3].v2 = s->row_out2nd[3].v3; + s->row_out2nd[3].v3 = s->row_out2nd[3].fac*s->row_out2nd[3].v2 - v1 + famp; + +/* Update fax tone */ + v1 = s->fax_tone.v2; + s->fax_tone.v2 = s->fax_tone.v3; + s->fax_tone.v3 = s->fax_tone.fac*s->fax_tone.v2 - v1 + famp; + + v1 = s->fax_tone.v2; + s->fax_tone2nd.v2 = s->fax_tone2nd.v3; + s->fax_tone2nd.v3 = s->fax_tone2nd.fac*s->fax_tone2nd.v2 - v1 + famp; + } +#endif + s->current_sample += (limit - sample); + if (s->current_sample < 102) + continue; + +/* Detect the fax energy, too */ +fax_energy = zap_goertzel_result(&s->fax_tone); + + /* We are at the end of a DTMF detection block */ + /* Find the peak row and the peak column */ + row_energy[0] = zap_goertzel_result (&s->row_out[0]); + col_energy[0] = zap_goertzel_result (&s->col_out[0]); + +for (best_row = best_col = 0, i = 1; i < 4; i++) +{ + row_energy[i] = zap_goertzel_result (&s->row_out[i]); + if (row_energy[i] > row_energy[best_row]) + best_row = i; + col_energy[i] = zap_goertzel_result (&s->col_out[i]); + if (col_energy[i] > col_energy[best_col]) + best_col = i; + } + hit = 0; + /* Basic signal level test and the twist test */ + if (row_energy[best_row] >= DTMF_THRESHOLD + && + col_energy[best_col] >= DTMF_THRESHOLD + && + col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST + && + col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) + { + /* Relative peak test */ + for (i = 0; i < 4; i++) + { + if ((i != best_col && col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) + || + (i != best_row && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) + { + break; + } + } + /* ... and second harmonic test */ + if (i >= 4 + && +(row_energy[best_row] + col_energy[best_col]) > 42.0*s->energy + && + zap_goertzel_result (&s->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col] + && + zap_goertzel_result (&s->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row]) + { + hit = dtmf_positions[(best_row << 2) + best_col]; + /* Look for two successive similar results */ + /* The logic in the next test is: + We need two successive identical clean detects, with + something different preceeding it. This can work with + back to back differing digits. More importantly, it + can work with nasty phones that give a very wobbly start + to a digit. */ + if (hit == s->hit3 && s->hit3 != s->hit2) + { + s->mhit = hit; + s->digit_hits[(best_row << 2) + best_col]++; + s->detected_digits++; + if (s->current_digits < MAX_DTMF_DIGITS) + { + s->digits[s->current_digits++] = hit; + s->digits[s->current_digits] = '\0'; + } + else + { + s->lost_digits++; + } + } + } + } +if (!hit && (fax_energy >= FAX_THRESHOLD) && (fax_energy > s->energy * 21.0)) { +fax_energy_2nd = zap_goertzel_result(&s->fax_tone2nd); +if (fax_energy_2nd * FAX_2ND_HARMONIC < fax_energy) { +#if 0 +printf("Fax energy/Second Harmonic: %f/%f\n", fax_energy, fax_energy_2nd); +#endif +/* XXX Probably need better checking than just this the energy XXX */ +hit = 'f'; +s->fax_hits++; +} /* Don't reset fax hits counter */ +} else { +if (s->fax_hits > 5) { + s->mhit = 'f'; + s->detected_digits++; + if (s->current_digits < MAX_DTMF_DIGITS) + { + s->digits[s->current_digits++] = hit; + s->digits[s->current_digits] = '\0'; + } + else + { + s->lost_digits++; + } +} +s->fax_hits = 0; +} + s->hit1 = s->hit2; + s->hit2 = s->hit3; + s->hit3 = hit; + /* Reinitialise the detector for the next block */ + for (i = 0; i < 4; i++) + { + goertzel_init (&s->row_out[i], &dtmf_detect_row[i]); + goertzel_init (&s->col_out[i], &dtmf_detect_col[i]); + goertzel_init (&s->row_out2nd[i], &dtmf_detect_row_2nd[i]); + goertzel_init (&s->col_out2nd[i], &dtmf_detect_col_2nd[i]); + } + goertzel_init (&s->fax_tone, &fax_detect); + goertzel_init (&s->fax_tone2nd, &fax_detect_2nd); +s->energy = 0.0; + s->current_sample = 0; + } + if ((!s->mhit) || (s->mhit != hit)) + { +s->mhit = 0; +return(0); + } + return (hit); +} +/*- End of function --------------------------------------------------------*/ + +int zap_dtmf_get (dtmf_detect_state_t *s, + char *buf, + int max) +{ + if (max > s->current_digits) + max = s->current_digits; + if (max > 0) + { + memcpy (buf, s->digits, max); + memmove (s->digits, s->digits + max, s->current_digits - max); + s->current_digits -= max; + } + buf[max] = '\0'; + return max; +} + + diff --git a/src/engine/media/MT_Dtmf.h b/src/engine/media/MT_Dtmf.h new file mode 100644 index 00000000..b8facfa1 --- /dev/null +++ b/src/engine/media/MT_Dtmf.h @@ -0,0 +1,97 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MT_DTMF +#define MT_DTMF + +#include "../config.h" +#include +#include +#include "../helper/HL_ByteBuffer.h" +#include "../helper/HL_Sync.h" + +namespace MT +{ + + class DtmfBuilder + { + public: + // Output should be 4 bytes length + static void buildRfc2833(int tone, int duration, int volume, bool endOfEvent, void* output); + + // Buf receives PCM audio + static void buildInband(int tone, int startTime, int finishTime, int rate, short* buf); + }; + + struct Dtmf + { + Dtmf(): mTone(0), mDuration(0), mVolume(0), mFinishCount(3), mCurrentTime(0), mStopped(false) {} + Dtmf(int tone, int volume, int duration): mTone(tone), mVolume(volume), mDuration(duration), mFinishCount(3), mCurrentTime(0), mStopped(false) {} + + int mStopped; + int mTone; + int mDuration; // It is zero for tones generated by startTone()..stopTone() calls. + int mVolume; + int mFinishCount; + int mCurrentTime; + }; + + typedef std::vector DtmfQueue; + + class DtmfContext + { + public: + enum Type + { + Dtmf_Inband, + Dtmf_Rfc2833 + }; + + DtmfContext(); + ~DtmfContext(); + + void setType(Type t); + Type type(); + + void startTone(int tone, int volume); + void stopTone(); + + void queueTone(int tone, int volume, int duration); + void clearAllTones(); + + // Returns true if result was sent to output. Output will be resized automatically. + bool getInband(int milliseconds, int rate, ByteBuffer& output); + bool getRfc2833(int milliseconds, ByteBuffer& output, ByteBuffer& stopPacket); + + protected: + Mutex mGuard; + Type mType; + DtmfQueue mQueue; + }; + +class DTMFDetector +{ +public: + /*! The default constructor. Allocates space for detector context. */ + DTMFDetector(); + + /*! The destructor. Free the detector context's memory. */ + ~DTMFDetector(); + + /*! This method receives the input PCM 16-bit data and returns found DTMF event(s) in string representation. + * @param samples Input PCM buffer pointer. + * @param size Size of input buffer in bytes + * @return Found DTMF event(s) in string representation. The returned value has variable length. + */ + std::string streamPut(unsigned char* samples, unsigned int size); + + void resetState(); + +protected: + void* mState; /// DTMF detector context +}; +} + +#endif diff --git a/src/engine/media/MT_NativeRtpSender.cpp b/src/engine/media/MT_NativeRtpSender.cpp new file mode 100644 index 00000000..40b37c86 --- /dev/null +++ b/src/engine/media/MT_NativeRtpSender.cpp @@ -0,0 +1,121 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "MT_NativeRtpSender.h" +#include + +using namespace MT; + +NativeRtpSender::NativeRtpSender(Statistics& stat) +:mDumpWriter(NULL), mStat(stat), mSrtpSession(NULL) +{ +} + +NativeRtpSender::~NativeRtpSender() +{ +} + +bool NativeRtpSender::SendRTP(const void *data, size_t len) +{ + if (mTarget.mRtp.isEmpty() || !mSocket.mRtp) + return false; + + if (mDumpWriter) + mDumpWriter->add(data, len); + + // Copy data to intermediary buffer bigger that original + int sendLength = len; + memcpy(mSendBuffer, data, len); + + // Encrypt SRTP if needed + if (mSrtpSession) + { + if (mSrtpSession->active()) + { + if (!mSrtpSession->protectRtp(mSendBuffer, &sendLength)) + return false; + } + } + + mSocket.mRtp->sendDatagram(mTarget.mRtp, mSendBuffer, sendLength); + mStat.mSentRtp++; + mStat.mSent += len; + + return true; +} + +/** This member function will be called when an RTCP packet needs to be transmitted. */ +bool NativeRtpSender::SendRTCP(const void *data, size_t len) +{ + if (mTarget.mRtp.isEmpty() || !mSocket.mRtcp) + return false; + // Copy data to intermediary buffer bigger that original + int sendLength = len; + memcpy(mSendBuffer, data, len); + + // Encrypt SRTP if needed + if (mSrtpSession) + { + if (mSrtpSession->active()) + { + if (!mSrtpSession->protectRtcp(mSendBuffer, &sendLength)) + return false; + } + } + + mSocket.mRtcp->sendDatagram(mTarget.mRtcp, mSendBuffer, sendLength); + mStat.mSentRtcp++; + mStat.mSent += len; + + return true; +} + + +/** Used to identify if an RTPAddress instance originated from this sender (to be able to detect own packets). */ +bool NativeRtpSender::ComesFromThisSender(const jrtplib::RTPAddress *a) +{ + return false; +} + +void NativeRtpSender::setDestination(RtpPair target) +{ + mTarget = target; +} + +RtpPair NativeRtpSender::destination() +{ + return mTarget; +} + +void NativeRtpSender::setSocket(const RtpPair& socket) +{ + mSocket = socket; +} + +RtpPair& NativeRtpSender::socket() +{ + return mSocket; +} + +void NativeRtpSender::setDumpWriter(RtpDump *dump) +{ + mDumpWriter = dump; +} + +RtpDump* NativeRtpSender::dumpWriter() +{ + return mDumpWriter; +} + +void NativeRtpSender::setSrtpSession(SrtpSession* srtp) +{ + mSrtpSession = srtp; +} + +SrtpSession* NativeRtpSender::srtpSession() +{ + return mSrtpSession; +} + diff --git a/src/engine/media/MT_NativeRtpSender.h b/src/engine/media/MT_NativeRtpSender.h new file mode 100644 index 00000000..677b82ee --- /dev/null +++ b/src/engine/media/MT_NativeRtpSender.h @@ -0,0 +1,58 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __MT_NATIVE_RTP_SENDER_H +#define __MT_NATIVE_RTP_SENDER_H + +#include "../config.h" +#include "jrtplib/src/rtpexternaltransmitter.h" +#include "srtp/include/srtp.h" +#include "../helper/HL_NetworkSocket.h" +#include "../helper/HL_InternetAddress.h" +#include "../helper/HL_Rtp.h" +#include "../helper/HL_SocketHeap.h" +#include "MT_Stream.h" +#include "MT_SrtpHelper.h" + +namespace MT +{ + class NativeRtpSender: public jrtplib::RTPExternalSender + { + public: + NativeRtpSender(Statistics& stat); + ~NativeRtpSender(); + + /** This member function will be called when RTP data needs to be transmitted. */ + bool SendRTP(const void *data, size_t len); + + /** This member function will be called when an RTCP packet needs to be transmitted. */ + bool SendRTCP(const void *data, size_t len); + + /** Used to identify if an RTPAddress instance originated from this sender (to be able to detect own packets). */ + bool ComesFromThisSender(const jrtplib::RTPAddress *a); + + void setDestination(RtpPair destination); + RtpPair destination(); + + void setSocket(const RtpPair& socket); + RtpPair& socket(); + + void setDumpWriter(RtpDump* dump); + RtpDump* dumpWriter(); + + void setSrtpSession(SrtpSession* srtp); + SrtpSession* srtpSession(); + + protected: + RtpPair mSocket; + RtpPair mTarget; + Statistics& mStat; + RtpDump* mDumpWriter; + SrtpSession* mSrtpSession; + char mSendBuffer[MAX_VALID_UDPPACKET_SIZE]; + }; +} + +#endif diff --git a/src/engine/media/MT_SevanaMos.cpp b/src/engine/media/MT_SevanaMos.cpp new file mode 100644 index 00000000..67c9cef7 --- /dev/null +++ b/src/engine/media/MT_SevanaMos.cpp @@ -0,0 +1,919 @@ +//#include "config.h" +#include "MT_SevanaMos.h" + +#if defined(USE_PVQA_LIBRARY) + +#if defined(PVQA_SERVER) +# include +# include +using namespace boost::filesystem; +#endif + +#include "../engine/helper/HL_Log.h" +#include "../engine/helper/HL_CsvReader.h" +#include "../engine/helper/HL_String.h" +#include "../engine/audio/Audio_WavFile.h" + +#include +#include +#include +#include +#include + +#if defined(PVQA_SERVER) +extern std::string IntervalCacheDir; +#endif + +#define LOG_SUBSYSTEM "Sevana" + +#ifdef WIN32 +# define popen _popen +# define pclose _pclose +#endif + +#define PVQA_ECHO_DETECTOR_NAME "ECHO" +//#define PVQA_ECHO_DETECTOR_NAME "EchoM-00" + +namespace MT { + +#if !defined(MOS_BEST_COLOR) +# define MOS_BEST_COLOR 0x11FF11 +# define MOS_BAD_COLOR 0x000000 +#endif + +static std::string execCommand(const char* cmd) +{ + std::shared_ptr pipe(popen(cmd, "r"), pclose); + if (!pipe) return "ERROR"; + char buffer[128]; + std::string result = ""; + while (!feof(pipe.get())) + { + if (fgets(buffer, 128, pipe.get()) != NULL) + result += buffer; + } + return result; +} + +void SevanaMosUtility::run(const std::string& pcmPath, const std::string& intervalPath, + std::string& estimation, std::string& intervals) +{ +#if defined(PVQA_SERVER) + path sevana = current_path() / "sevana"; +#if defined(TARGET_LINUX) || defined(TARGET_OSX) + path exec = sevana / "pvqa"; +#else + path exec = sevana / "pvqa.exe"; +#endif + path lic = sevana / "pvqa.lic"; + path cfg = sevana / "settings.cfg"; + + estimation.clear(); + char cmdbuffer[1024]; + sprintf(cmdbuffer, "%s %s analysis %s %s %s 0.799", exec.string().c_str(), lic.string().c_str(), + intervalPath.c_str(), cfg.string().c_str(), pcmPath.c_str()); + std::string output = execCommand(cmdbuffer); + + //ICELogDebug(<< "Got PVQA analyzer output: " << output); + + std::string line; + std::istringstream is(output); + while (std::getline(is, line)) + { + std::string::size_type mosPosition = line.find("MOS = "); + if ( mosPosition != std::string::npos) + { + estimation = line.substr(mosPosition + 6); + boost::algorithm::trim(estimation); + } + } + + if (!estimation.size()) + { + // Dump utility output if estimation failed + ICELogCritical(<< "PVQA failed with message: " << output); + return; + } + + // Read intervals report file + if (boost::filesystem::exists(intervalPath) && !estimation.empty()) + { + std::ifstream t(intervalPath); + std::string str((std::istreambuf_iterator(t)), + std::istreambuf_iterator()); + intervals = str; + } +#endif +} + +float getSevanaMos(const std::string& audioPath, const std::string& intervalReportPath, + std::string& intervalReport) +{ + // Find Sevana MOS estimation + ICELogDebug( << "Running MOS utitlity on resulted PCM file " << audioPath ); + try + { + std::string buffer; + SevanaMosUtility::run(audioPath, intervalReportPath, buffer, intervalReport); + ICELogDebug( << "MOS utility is finished on PCM file " << audioPath ); + return (float)atof(buffer.c_str()); + } + catch(std::exception& e) + { + ICELogCritical( << "MOS utility failed on PCM file " << audioPath << ". Error msg: " << e.what() ); + return 0.0; + } +} + +// ------------------- SevanaPVQA ------------------- +void* SevanaPVQA::mLibraryConfiguration = nullptr; +int SevanaPVQA::mLibraryErrorCode = 0; +std::atomic_int SevanaPVQA::mInstanceCounter; +std::atomic_uint_least64_t SevanaPVQA::mAllProcessedMilliseconds; +bool SevanaPVQA::mPvqaLoaded = false; + +std::string SevanaPVQA::getVersion() +{ + return PVQA_GetVersion(); +} + +#if defined(TARGET_ANDROID) +void SevanaPVQA::setupAndroidEnvironment(void *environment, void *appcontext) +{ + PVQA_SetupAndroidEnvironment(environment, appcontext); +} +#endif + +bool SevanaPVQA::initializeLibrary(const std::string& pathToLicenseFile, const std::string& pathToConfigFile) +{ + mPvqaLoaded = false; + + ICELogInfo(<< "Sevana PVQA is about to be initialized."); + + // Initialize PVQA library + if (!mLibraryConfiguration) + { + mInstanceCounter = 0; + mLibraryErrorCode = PVQA_InitLib(const_cast(pathToLicenseFile.c_str())); + if (mLibraryErrorCode) + { + ICELogCritical(<< "Problem when initializing PVQA library. Error code: " << mLibraryErrorCode + << ". Path to license file is " << pathToLicenseFile + << ". Path to config file is " << pathToConfigFile); + return false; + } + + mLibraryConfiguration = PVQA_LoadCFGFile(const_cast(pathToConfigFile.c_str()), &mLibraryErrorCode); + if (!mLibraryConfiguration) + { + PVQA_ReleaseLib(); + ICELogCritical(<< "Problem with PVQA configuration file."); + return false; + } + mPvqaLoaded = true; + } + return true; +} + +bool SevanaPVQA::isInitialized() +{ + return mPvqaLoaded; +} + +int SevanaPVQA::getLibraryError() +{ + return mLibraryErrorCode; +} + +void SevanaPVQA::releaseLibrary() +{ + PVQA_ReleaseLib(); +} + +SevanaPVQA::SevanaPVQA() +{ +} + +SevanaPVQA::~SevanaPVQA() +{ + close(); +} + +void SevanaPVQA::open(double interval, Model model) +{ + if (!isInitialized()) + { + ICELogCritical(<< "PVQA library is not initialized."); + return; + } + + if (mOpenFailed) + { + ICELogCritical(<< "Open failed already, reject this attempt."); + return; + } + + if (mContext) + { + ICELogCritical(<< "Already opened (context is not nullptr)."); + return; + } + + ICELogDebug(<<"Attempt to create PVQA instance."); + mProcessedSamples = 0; + mModel = model; + mIntervalLength = interval; + mAudioLineInitialized = false; + + mContext = PVQA_CreateAudioQualityAnalyzer(mLibraryConfiguration); + if (!mContext) + { + ICELogCritical(<< "Failed to create PVQA instance. Instance counter: " << mInstanceCounter); + mOpenFailed = true; + return; + } + + mInstanceCounter++; + + int rescode = 0; + rescode = PVQA_AudioQualityAnalyzerSetIntervalLength(mContext, interval); + if (rescode) + { + ICELogCritical(<< "Failed to set interval length on PVQA instance. Result code: " << rescode); + close(); + mOpenFailed = true; + return; + } + + if (mModel == Model::Stream) + { + rescode = PVQA_OnStartStreamData(mContext); + if (rescode) + { + ICELogCritical(<< "Failed to start streaming analysis on PVQA instance. Result code: " << rescode); + close(); + mOpenFailed = true; + return; + } + } + ICELogDebug(<<"PVQA instance is created. Instance counter: " << mInstanceCounter); +} + +void SevanaPVQA::close() +{ + if (mContext) + { + ICELogDebug(<< "Attempt to destroy PVQA instance."); + PVQA_ReleaseAudioQualityAnalyzer(mContext); + mInstanceCounter--; + ICELogDebug(<< "PVQA instance destroyed. Current instance counter: " << mInstanceCounter); + mContext = nullptr; + mOpenFailed = false; + } +} + +bool SevanaPVQA::isOpen() const +{ + return mContext != nullptr; +} + +void SevanaPVQA::update(int samplerate, int channels, const void *pcmBuffer, int pcmLength) +{ + if (!mContext) + { + ICELogCritical(<< "No PVQA context."); + return; + } + // Model is assert here as it can be any if context is not created. + assert (mModel == Model::Stream); + + TPVQA_AudioItem item; + item.dNChannels = channels; + item.dSampleRate = samplerate; + item.dNSamples = pcmLength / 2 / channels; + item.pSamples = (short*)pcmBuffer; + int rescode = PVQA_OnAddStreamAudioData(mContext, &item); + if (rescode) + { + ICELogCritical(<< "Failed to stream data to PVQA instance. Result code: " << rescode); + } + int milliseconds = pcmLength / 2 / channels / (samplerate / 1000); + mProcessedMilliseconds += milliseconds; + mAllProcessedMilliseconds += milliseconds; +} + +SevanaPVQA::DetectorsList SevanaPVQA::getDetectorsNames(const std::string& report) +{ + DetectorsList result; + + if (!report.empty()) + { + std::istringstream iss(report); + CsvReader reader(iss); + reader.readLine(result.mNames); + result.mStartIndex = 2; + + // Remove first columns + if (result.mStartIndex < (int)result.mNames.size() - 1) + { + result.mNames.erase(result.mNames.begin(), result.mNames.begin() + result.mStartIndex); + + // Remove last column + result.mNames.erase(result.mNames.begin() + result.mNames.size() - 1); + + for (auto& name: result.mNames) + name = StringHelper::trim(name); + } + } + return result; +} + +float SevanaPVQA::getResults(std::string& report, const EchoData** echo, int samplerate, Codec codec) +{ + if (!mContext) + { + ICELogCritical(<< "No PVQA context."); + return 0.0; + } + + if (mModel == Model::Stream) + { + if (mProcessedMilliseconds == 0) + { + ICELogCritical(<< "No audio in PVQA."); + return -1; + } + + if (PVQA_OnFinalizeStream(mContext, (long)samplerate)) + { + ICELogCritical(<< "Failed to finalize results from PVQA."); + return -1; + } + ICELogInfo(<< "Processed " << mProcessedMilliseconds << " milliseconds."); + } + + TPVQA_Results results; + if (PVQA_FillQualityResultsStruct(mContext, &results)) + { + ICELogCritical(<< "Failed to get results from PVQA."); + return -1; + } + + int reportLength = PVQA_GetQualityStringSize(mContext); + if (reportLength) + { + char* buffer = (char*)alloca(reportLength + 1); + if (PVQA_FillQualityString(mContext, buffer)) + { + ICELogCritical(<< "Failed to fill intervals report."); + } + else + report = buffer; + } + +#if defined(TARGET_LINUX) && defined(PVQA_WITH_ECHO_DATA) + if (mModel == SevanaPVQA::Model::Stream && echo) + { + // Return echo detector counters + // Get list of names for echo detector - for debugging only + std::vector names; + int errCode = 0; + const char** iNames = (const char **)PVQA_GetProcessorValuesNamesList(mContext, PVQA_ECHO_DETECTOR_NAME, &errCode); + if (!errCode && iNames) + { + int nameIndex = 0; + for(const char * locName = iNames[nameIndex]; locName; locName = iNames[++nameIndex]) + names.push_back(locName); + + // Get values for echo detector + *echo = PVQA_GetProcessorValuesList(mContext, PVQA_ECHO_DETECTOR_NAME, 0, mProcessedMilliseconds, "values", &errCode); + + // For debugging only + /*if (*echo) + { + for (const auto& row: **echo) + { + std::cout << "<"; + for (const auto& v: row) + std::cout << v << " "; + std::cout << ">" << std::endl; + } + }*/ + // No need to delete maxValues - it will be deleted on PVQA analyzer context freeing. + } + } +#endif + + // Limit maximal value of MOS depending on codec + float result = (float)results.dMOSLike; + float mv = 5.0; + switch (codec) + { + case Codec::G711: mv = 4.1f; break; + case Codec::G729: mv = 3.92f; break; + default: + mv = 5.0; + } + + return std::min(result, mv); +} + +void SevanaPVQA::setPathToDumpFile(const std::string& path) +{ + mDumpWavPath = path; +} + +float SevanaPVQA::process(int samplerate, int channels, const void *pcmBuffer, int pcmLength, std::string &report, Codec codec) +{ + //std::cout << "Sent " << pcmLength << " bytes of audio to analyzer." << std::endl; + assert (mModel == Model::Interval); + if (!mContext) + return 0.0; + + /*if (!mAudioLineInitialized) + { + mAudioLineInitialized = true; + if (PVQA_AudioQualityAnalyzerCreateDelayLine(mContext, samplerate, channels, 20)) + ICELogCritical(<< "Failed to create delay line."); + }*/ + + TPVQA_AudioItem item; + item.dNChannels = channels; + item.dSampleRate = samplerate; + item.dNSamples = pcmLength / 2 / channels; + item.pSamples = (short*)pcmBuffer; + + //std::cout << "Sending chunk of audio with rate = " << samplerate << ", channels = " << channels << ", number of samples " << item.dNSamples << std::endl; + + /* + if (!mDumpWavPath.empty()) + { + WavFileWriter writer; + writer.open(mDumpWavPath, samplerate, channels); + writer.write(item.pSamples, item.dNSamples * 2 * channels); + writer.close(); + ICELogCritical(<< "Sending chunk of audio with rate = " << samplerate << ", channels = " << channels << ", number of samples " << item.dNSamples); + } + */ + int code = PVQA_OnTestAudioData(mContext, &item); + if (code) + { + ICELogCritical(<< "Failed to run PVQA on audio buffer with code " << code); + return 0.0; + } + + /* + if (item.pSamples != pcmBuffer || item.dNSamples != pcmLength / 2 / channels || item.dSampleRate != samplerate || item.dNChannels != channels) + { + ICELogCritical(<< "PVQA changed input parameters!!!!"); + } + */ + // Increase counter of processed samples + mProcessedSamples += pcmLength / channels / 2; + + int milliseconds = pcmLength / channels / 2 / (samplerate / 1000); + mProcessedMilliseconds += milliseconds; + + // Overall counter + mAllProcessedMilliseconds += milliseconds; + + // Get results + return getResults(report, nullptr, samplerate, codec); +} + +struct RgbColor +{ + uint8_t mRed = 0; + uint8_t mGreen = 0; + uint8_t mBlue = 0; + + static RgbColor parse(uint32_t rgb) + { + RgbColor result; + result.mBlue = (uint8_t)(rgb & 0xff); + result.mGreen = (uint8_t)((rgb >> 8) & 0xff); + result.mRed = (uint8_t)((rgb >> 16) & 0xff); + return result; + } + + std::string toHex() const + { + char result[7]; + sprintf(result, "%02x%02x%02x", int(mRed), int(mGreen), int(mBlue)); + return std::string(result); + } +}; + +int SevanaPVQA::getSize() const +{ + int result = 0; + result += sizeof(*this); + + // TODO: add PVQA analyzer size + return result; +} + + +std::string SevanaPVQA::mosToColor(float mos) +{ + // Limit MOS value by 5.0 + mos = mos > 5.0f ? 5.0f : mos; + mos = mos < 1.0f ? 1.0f : mos; + + // Split to components + RgbColor start = RgbColor::parse(MOS_BEST_COLOR), end = RgbColor::parse(MOS_BAD_COLOR); + + float mosFraction = (mos - 1.0f) / 4.0f; + + end.mBlue += (start.mBlue - end.mBlue) * mosFraction; + end.mGreen += (start.mGreen - end.mGreen) * mosFraction; + end.mRed += (start.mRed - end.mRed) * mosFraction; + + return end.toHex(); +} + +} // end of namespace MT +#endif + +#if defined(USE_AQUA_LIBRARY) + +#include +#include "helper/HL_String.h" +#include +#include + +namespace MT +{ + +int SevanaAqua::initializeLibrary(const std::string& pathToLicenseFile) +{ + //char buffer[pathToLicenseFile.length() + 1]; + //strcpy(buffer, pathToLicenseFile.c_str()); + return SSA_InitLib(const_cast(pathToLicenseFile.data())); +} + + +void SevanaAqua::releaseLibrary() +{ + SSA_ReleaseLib(); +} + +std::string SevanaAqua::FaultsReport::toText() const +{ + std::ostringstream oss; + + if (mSignalAdvancedInMilliseconds > -4999.0) + oss << "Signal advanced in milliseconds: " << mSignalAdvancedInMilliseconds << std::endl; + if (mMistimingInPercents > -4999.0) + oss << "Mistiming in percents: " << mMistimingInPercents << std::endl; + + for (ResultMap::const_iterator resultIter = mResultMap.begin(); resultIter != mResultMap.end(); resultIter++) + { + oss << resultIter->first << ":\t\t\t" << resultIter->second.mSource << " : \t" << resultIter->second.mDegrated << " \t" << resultIter->second.mUnit << std::endl; + } + + return oss.str(); +} + +Json::Value SevanaAqua::FaultsReport::toJson() const +{ + std::ostringstream oss; + Json::Value result; + + result["Mistiming"] = mMistimingInPercents; + result["SignalAdvanced"] = mSignalAdvancedInMilliseconds; + Json::Value items; + for (ResultMap::const_iterator resultIter = mResultMap.begin(); resultIter != mResultMap.end(); resultIter++) + { + Json::Value item; + item["name"] = resultIter->first; + item["source"] = resultIter->second.mSource; + item["degrated"] = resultIter->second.mDegrated; + item["unit"] = resultIter->second.mUnit; + + items.append(item); + } + + result["items"] = items; + + return result; +} + +std::string SevanaAqua::getVersion() +{ + TSSA_AQuA_Info* info = SSA_GetPAQuAInfo(); + if (info) + return info->dVersionString; + + return ""; +} + +SevanaAqua::SevanaAqua() +{ + open(); +} + +SevanaAqua::~SevanaAqua() +{ + close(); +} + +void SevanaAqua::open() +{ + std::unique_lock l(mMutex); + if (mContext) + return; + + mContext = SSA_CreateAudioQualityAnalyzer(); + if (!mContext) + ; + + //setParam("OutputFormats", "json"); +} + +void SevanaAqua::close() +{ + std::unique_lock l(mMutex); + if (!mContext) + return; + SSA_ReleaseAudioQualityAnalyzer(mContext); + mContext = nullptr; +} + +bool SevanaAqua::isOpen() const +{ + return mContext != nullptr; +} + +void SevanaAqua::setTempPath(const std::string& temp_path) +{ + mTempPath = temp_path; +} + +std::string SevanaAqua::getTempPath() const +{ + return mTempPath; +} + +SevanaAqua::CompareResult SevanaAqua::compare(AudioBuffer& reference, AudioBuffer& test) +{ + // Clear previous temporary file + if (!mTempPath.empty()) + ::remove(mTempPath.c_str()); + + // Result value + CompareResult r; + + std::unique_lock l(mMutex); + + if (!mContext) + return r; + + // Make analysis + TSSA_AQuA_AudioData aad; + aad.dSrcData.dNChannels = reference.mChannels; + aad.dSrcData.dSampleRate = reference.mRate; + aad.dSrcData.pSamples = (short*)reference.mData; + aad.dSrcData.dNSamples = (long)reference.mSize / 2 / reference.mChannels; + + aad.dTstData.dNChannels = test.mChannels; + aad.dTstData.dSampleRate = test.mRate; + aad.dTstData.pSamples = (short*)test.mData; + aad.dTstData.dNSamples = (long)test.mSize / 2 / test.mChannels; + + int rescode; + rescode = SSA_OnTestAudioData(mContext, &aad); + if (rescode) + return r; + + // Get results + + int len = SSA_GetQualityStringSize(mContext); + char* qs = (char*)alloca(len + 10); + SSA_FillQualityString(mContext, qs); + //std::cout << qs << std::endl; + std::istringstream iss(qs); + while (!iss.eof()) + { + std::string l; + std::getline(iss, l); + + // Split by : + std::vector p; + StringHelper::split(l, p, "\t"); + if (p.size() == 3) + { + p[1] = StringHelper::trim(p[1]); + p[2] = StringHelper::trim(p[2]); + r.mReport[p[1]] = p[2]; + } + } + + len = SSA_GetSrcSignalSpecSize(mContext); + float* srcSpecs = new float[len]; + SSA_FillSrcSignalSpecArray(mContext, srcSpecs); + Json::Value src_spec_signal; + + for(int i=0; i<16 && i 0) { + faults_str = new char[faults_str_len + 1]; + SSA_FillFaultsAnalysisString(mContext, faults_str); + faults_str[faults_str_len] = 0; + } + } + + char* pairs_str = nullptr; + int pairs_str_len = SSA_GetSpecPairsStringSize(mContext); + if (pairs_str_len > 0) + { + char *pairs_str = new char[pairs_str_len + 1]; + SSA_FillSpecPairsString(mContext, pairs_str, pairs_str_len); + pairs_str[pairs_str_len] = 0; + } + + TSSA_AQuA_Results iResults; + SSA_FillQualityResultsStruct(mContext, &iResults); + r.mReport["dPercent"] = iResults.dPercent; + r.mReport["dMOSLike"] = iResults.dMOSLike; + + if (faults_str_len > 0) + { + std::istringstream iss(faults_str); + r.mFaults = loadFaultsReport(iss); + } + else + if (!mTempPath.empty()) + { + std::ifstream ifs(mTempPath.c_str()); + r.mFaults = loadFaultsReport(ifs); + } + + delete[] faults_str; faults_str = nullptr; + delete[] pairs_str; pairs_str = nullptr; + + r.mMos = (float)iResults.dMOSLike; + + return r; +} + +void SevanaAqua::configureWith(const Config& config) +{ + if (!mContext) + return; + + for (auto& item: config) + { + const std::string& name = item.first; + const std::string& value = item.second; + if (!SSA_SetAnyString(mContext, const_cast(name.c_str()), const_cast(value.c_str()))) + throw std::runtime_error(std::string("SSA_SetAnyString returned failed for pair ") + name + " " + value); + } +} + +SevanaAqua::Config SevanaAqua::parseConfig(const std::string& line) +{ + Config result; + + // Split command line to parts + std::vector pl; + StringHelper::split(line, pl, "-"); + + for (const std::string& s: pl) + { + std::string::size_type p = s.find(' '); + if (p != std::string::npos) + { + std::string name = StringHelper::trim(s.substr(0, p)); + std::string value = StringHelper::trim(s.substr(p + 1)); + + result[name] = value; + } + } + + return result; +} + + +SevanaAqua::PFaultsReport SevanaAqua::loadFaultsReport(std::istream& input) +{ + PFaultsReport result = std::make_shared(); + std::string line; + std::vector parts; + + // Parse output + while (!input.eof()) + { + std::getline(input, line); + if (line.size() < 3) + continue; + + std::string::size_type p = line.find(":"); + if (p != std::string::npos) + { + std::string name = StringHelper::trim(line.substr(0, p)); + + FaultsReport::Result r; + + // Split report line to components + parts.clear(); + StringHelper::split(line.substr(p + 1), parts, " \t"); + + // Remove empty components + parts.erase(std::remove_if(parts.begin(), parts.end(), [](const std::string& item){return item.empty();}), parts.end()); + + if (parts.size() >= 2) + { + r.mSource = parts[0]; + r.mDegrated = parts[1]; + if (parts.size()> 2) + r.mUnit = parts[2]; + result->mResultMap[name] = r; + } + } + else + { + p = line.find("ms."); + if (p != std::string::npos) + { + parts.clear(); + StringHelper::split(line, parts, " \t"); + if (parts.size() >= 3) + { + if (parts.back() == "ms.") + result->mSignalAdvancedInMilliseconds = std::atof(parts[parts.size() - 2].c_str()); + } + } + else + { + p = line.find("percent."); + if (p != std::string::npos) + { + parts.clear(); + StringHelper::split(line, parts, " \t"); + if (parts.size() >= 3) + { + if (parts.back() == "percent.") + result->mMistimingInPercents = std::atof(parts[parts.size() - 2].c_str()); + } + } + } + } + } + + return result; +} + +} // end of namespace MT + +// It is to workaround old AQuA NDK build - it has reference to ftime +/*#if defined(TARGET_ANDROID) +#include + +// This was removed from POSIX 2008. +int ftime(struct timeb* tb) { + struct timeval tv; + struct timezone tz; + + if (gettimeofday(&tv, &tz) < 0) + return -1; + + tb->time = tv.tv_sec; + tb->millitm = (tv.tv_usec + 500) / 1000; + + if (tb->millitm == 1000) { + ++tb->time; + tb->millitm = 0; + } + + tb->timezone = tz.tz_minuteswest; + tb->dstflag = tz.tz_dsttime; + + return 0; +} +#endif*/ + +#endif + diff --git a/src/engine/media/MT_SevanaMos.h b/src/engine/media/MT_SevanaMos.h new file mode 100644 index 00000000..c83f43b6 --- /dev/null +++ b/src/engine/media/MT_SevanaMos.h @@ -0,0 +1,208 @@ +#ifndef _SEVANA_MOS_H +#define _SEVANA_MOS_H + +#include +#include +#include +#include +#include +#include + + +#if defined(USE_PVQA_LIBRARY) +# include "pvqa.h" +# if !defined(PVQA_INTERVAL) +# define PVQA_INTERVAL (0.68) +# endif +#endif + +#if defined(USE_AQUA_LIBRARY) +# include "aqua.h" +# include +#endif + + +namespace MT +{ + enum class ReportType + { + PlainText, + Html + }; + + #if defined(USE_PVQA_LIBRARY) + class SevanaMosUtility + { + public: + // Returns MOS estimation as text representation of float value or "failed" word. + static void run(const std::string& pcmPath, const std::string& intervalPath, + std::string& estimation, std::string& intervals); + }; + + extern float getSevanaMos(const std::string& audioPath, const std::string& intervalReportPath, + std::string& intervalReport); + + class SevanaPVQA + { + public: + enum class Model + { + Stream, + Interval + }; + + protected: + static void* mLibraryConfiguration; + static int mLibraryErrorCode; + static std::atomic_int mInstanceCounter; + static std::atomic_uint_least64_t mAllProcessedMilliseconds; + static bool mPvqaLoaded; + + void* mContext = nullptr; + Model mModel = Model::Interval; + double mIntervalLength = 0.68; + uint64_t mProcessedSamples = 0, + mProcessedMilliseconds = 0; + + bool mAudioLineInitialized = false; + std::string mDumpWavPath; + bool mOpenFailed = false; + + public: + static std::string getVersion(); + + // Required to call before any call to SevanaPVQA instance methods + + #if defined(TARGET_ANDROID) + static void setupAndroidEnvironment(void* environment, void* appcontext); + #endif + static bool initializeLibrary(const std::string& pathToLicenseFile, const std::string& pathToConfigFile); + static bool isInitialized(); + + static int getLibraryError(); + static void releaseLibrary(); + static int getInstanceCounter() { return mInstanceCounter; } + static uint64_t getProcessedMilliseconds() { return mAllProcessedMilliseconds; } + + SevanaPVQA(); + ~SevanaPVQA(); + + void open(double interval, Model model); + void close(); + bool isOpen() const; + + // Update/Get model + void update(int samplerate, int channels, const void* pcmBuffer, int pcmLength); + + typedef std::vector> EchoData; + enum class Codec + { + None, + G711, + ILBC, + G722, + G729, + GSM, + AMRNB, + AMRWB, + OPUS + }; + + float getResults(std::string& report, const EchoData** echo, int samplerate, Codec codec); + + // Report is interval report. Names are output detector names. startIndex is column's start index in interval report of first detector. + struct DetectorsList + { + std::vector mNames; + int mStartIndex = 0; + }; + + static DetectorsList getDetectorsNames(const std::string& report); + + // Get MOS in one shot + void setPathToDumpFile(const std::string& path); + float process(int samplerate, int channels, const void* pcmBuffer, int pcmLength, std::string& report, Codec codec); + + Model getModel() const { return mModel; } + + int getSize() const; + + static std::string mosToColor(float mos); + }; + + typedef std::shared_ptr PSevanaPVQA; + #endif + + #if defined(USE_AQUA_LIBRARY) + class SevanaAqua + { + protected: + void* mContext = nullptr; + std::mutex mMutex; + std::string mTempPath; + + public: + // Returns 0 (zero) on successful initialization, otherwise it is error code + static int initializeLibrary(const std::string& pathToLicenseFile); + static void releaseLibrary(); + static std::string getVersion(); + + SevanaAqua(); + ~SevanaAqua(); + + void open(); + void close(); + bool isOpen() const; + + void setTempPath(const std::string& temp_path); + std::string getTempPath() const; + + typedef std::map Config; + void configureWith(const Config& config); + static Config parseConfig(const std::string& line); + + // Report is returned in JSON format + struct AudioBuffer + { + int mRate = 8000; + int mChannels = 1; + void* mData = nullptr; + int mSize = 0; // In bytes + }; + + + struct FaultsReport + { + float mSignalAdvancedInMilliseconds = -5000.0; + float mMistimingInPercents = -5000.0; + + struct Result + { + std::string mSource, mDegrated, mUnit; + }; + typedef std::map ResultMap; + ResultMap mResultMap; + + Json::Value toJson() const; + std::string toText() const; + }; + + typedef std::shared_ptr PFaultsReport; + + static PFaultsReport loadFaultsReport(std::istream& input); + + // Compare in one shot. Report will include text representation of json report. + struct CompareResult + { + float mMos = 0.0f; + Json::Value mReport; + PFaultsReport mFaults; + }; + + CompareResult compare(AudioBuffer& reference, AudioBuffer& test); + }; + typedef std::shared_ptr PSevanaAqua; + #endif +} + +#endif diff --git a/src/engine/media/MT_SingleAudioStream.cpp b/src/engine/media/MT_SingleAudioStream.cpp new file mode 100644 index 00000000..ebd4643a --- /dev/null +++ b/src/engine/media/MT_SingleAudioStream.cpp @@ -0,0 +1,42 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "MT_SingleAudioStream.h" +#include "MT_CodecList.h" +#include "resip/stack/SdpContents.hxx" +#include "../engine/helper/HL_Log.h" + +#define LOG_SUBSYSTEM "SingleAudioStream" + +using namespace MT; + +SingleAudioStream::SingleAudioStream(const CodecList::Settings& codecSettings, Statistics& stat) +:mReceiver(codecSettings, stat), mDtmfReceiver(stat) +{ +} + +SingleAudioStream::~SingleAudioStream() +{ +} + +void SingleAudioStream::process(std::shared_ptr packet) +{ + ICELogMedia(<< "Processing incoming RTP/RTCP packet"); + if (packet->GetPayloadType() == resip::Codec::TelephoneEvent.payloadType()) + mDtmfReceiver.add(packet); + else + mReceiver.add(packet); +} + +void SingleAudioStream::copyPcmTo(Audio::DataWindow& output, int needed) +{ + while (output.filled() < needed) + if (!mReceiver.getAudio(output)) + break; + + if (output.filled() < needed) + ICELogCritical(<< "Not enough data for speaker's mixer"); +} + diff --git a/src/engine/media/MT_SingleAudioStream.h b/src/engine/media/MT_SingleAudioStream.h new file mode 100644 index 00000000..866ab2c9 --- /dev/null +++ b/src/engine/media/MT_SingleAudioStream.h @@ -0,0 +1,31 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __MT_SSRC_STREAM_H +#define __MT_SSRC_STREAM_H + +#include "jrtplib/src/rtppacket.h" +#include +#include "MT_Codec.h" +#include "MT_WebRtc.h" +#include "MT_AudioReceiver.h" +namespace MT +{ + class SingleAudioStream + { + public: + SingleAudioStream(const CodecList::Settings& codecSettings, Statistics& stat); + ~SingleAudioStream(); + void process(std::shared_ptr packet); + void copyPcmTo(Audio::DataWindow& output, int needed); + + protected: + DtmfReceiver mDtmfReceiver; + AudioReceiver mReceiver; + }; + + typedef std::map AudioStreamMap; +} +#endif diff --git a/src/engine/media/MT_SrtpHelper.cpp b/src/engine/media/MT_SrtpHelper.cpp new file mode 100644 index 00000000..d0bb355a --- /dev/null +++ b/src/engine/media/MT_SrtpHelper.cpp @@ -0,0 +1,231 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "MT_SrtpHelper.h" +#include "../helper/HL_Log.h" +#include "../helper/HL_Exception.h" +#include "../helper/HL_Rtp.h" +#include + +// --- SrtpStream --- +void initSrtpStream(SrtpStream& s, unsigned ssrc, SrtpSuite suite) +{ + s.second.ssrc.type = ssrc_specific; + s.second.ssrc.value = ntohl(ssrc); + s.second.next = NULL; + switch (suite) + { + case SRTP_AES_128_AUTH_80: + crypto_policy_set_aes_cm_128_hmac_sha1_80(&s.second.rtp); + crypto_policy_set_aes_cm_128_hmac_sha1_80(&s.second.rtcp); + break; + + case SRTP_AES_256_AUTH_80: + crypto_policy_set_aes_cm_256_hmac_sha1_80(&s.second.rtp); + crypto_policy_set_aes_cm_256_hmac_sha1_80(&s.second.rtcp); + break; + + default: + assert(0); + } +} + +SrtpSession::SrtpSession() +:mInboundSession(NULL), mOutboundSession(NULL) +{ + mInboundSession = NULL; + mOutboundSession = NULL; + mSuite = SRTP_NONE; + + memset(&mInboundPolicy, 0, sizeof mInboundPolicy); + mInboundPolicy.ssrc.type = ssrc_specific; + + memset(&mOutboundPolicy, 0, sizeof mOutboundPolicy); + mOutboundPolicy.ssrc.type = ssrc_specific; + + // Generate outgoing keys + + mOutgoingKey[SRTP_AES_128_AUTH_80-1].first = PByteBuffer(new ByteBuffer()); + mOutgoingKey[SRTP_AES_128_AUTH_80-1].first->resize(30); + crypto_get_random((unsigned char*)mOutgoingKey[SRTP_AES_128_AUTH_80-1].first->mutableData(), 30); + + mOutgoingKey[SRTP_AES_256_AUTH_80-1].first = PByteBuffer(new ByteBuffer()); + mOutgoingKey[SRTP_AES_256_AUTH_80-1].first->resize(46); + crypto_get_random((unsigned char*)mOutgoingKey[SRTP_AES_256_AUTH_80-1].first->mutableData(), 46); + +} + +SrtpSession::~SrtpSession() +{ +} + +void SrtpSession::addSsrc(unsigned ssrc, SsrcDirection d) +{ + Lock l(mGuard); + assert(mSuite != SRTP_NONE); + + // Look in map - if the srtp stream for this ssrc is created already + SrtpStreamMap::iterator streamIter; + SrtpStream s; + switch (d) + { + case sdIncoming: + streamIter = mIncomingMap.find(ssrc); + if (streamIter != mIncomingMap.end()) + return; + + initSrtpStream(s, ssrc, mSuite); + s.second.key = (unsigned char*)mIncomingKey.first->mutableData(); + mIncomingMap[ssrc] = s; + srtp_add_stream(mInboundSession, &s.second); + return; + + case sdOutgoing: + streamIter = mOutgoingMap.find(ssrc); + if (streamIter != mOutgoingMap.end()) + return; + initSrtpStream(s, ssrc, mSuite); + s.second.key = (unsigned char*)mOutgoingKey[int(mSuite)-1].first->mutableData(); + mOutgoingMap[ssrc] = s; + srtp_add_stream(mOutboundSession, &s.second); + return; + } +} + +void SrtpSession::open(ByteBuffer& incomingKey, SrtpSuite suite) +{ + Lock l(mGuard); + + // Check if session is here already + if (mInboundSession || mOutboundSession) + return; + + // Save used SRTP suite + mSuite = suite; + + // Save key + mIncomingKey.first = PByteBuffer(new ByteBuffer(incomingKey)); + + // Update policy + switch (suite) + { + case SRTP_AES_128_AUTH_80: + crypto_policy_set_aes_cm_128_hmac_sha1_80(&mInboundPolicy.rtp); + crypto_policy_set_aes_cm_128_hmac_sha1_80(&mInboundPolicy.rtcp); + crypto_policy_set_aes_cm_128_hmac_sha1_80(&mOutboundPolicy.rtp); + crypto_policy_set_aes_cm_128_hmac_sha1_80(&mOutboundPolicy.rtcp); + break; + + case SRTP_AES_256_AUTH_80: + crypto_policy_set_aes_cm_256_hmac_sha1_80(&mInboundPolicy.rtp); + crypto_policy_set_aes_cm_256_hmac_sha1_80(&mInboundPolicy.rtcp); + crypto_policy_set_aes_cm_256_hmac_sha1_80(&mOutboundPolicy.rtp); + crypto_policy_set_aes_cm_256_hmac_sha1_80(&mOutboundPolicy.rtcp); + break; + + case SRTP_NONE: + break; + } + mOutboundPolicy.key = (unsigned char*)mOutgoingKey[int(suite)-1].first->mutableData(); + mInboundPolicy.key = (unsigned char*)mIncomingKey.first->mutableData(); + + // Create SRTP session + err_status_t err; + + err = srtp_create(&mOutboundSession, &mOutboundPolicy); + if (err) + throw Exception(ERR_SRTP, err); + + err = srtp_create(&mInboundSession, &mInboundPolicy); + if (err) + throw Exception(ERR_SRTP, err); +} + +bool SrtpSession::active() +{ + Lock l(mGuard); + return mInboundSession != 0 && mOutboundSession != 0; +} + +void SrtpSession::close() +{ + Lock l(mGuard); + + if (mOutboundSession) + { + srtp_dealloc(mOutboundSession); + mOutboundSession = NULL; + } + + if (mInboundSession) + { + srtp_dealloc(mInboundSession); + mInboundSession = NULL; + } +} + +SrtpKeySalt& SrtpSession::outgoingKey(SrtpSuite suite) +{ + Lock l(mGuard); + assert(suite > SRTP_NONE && suite <= SRTP_LAST); + return mOutgoingKey[int(suite)-1]; +} + +bool SrtpSession::protectRtp(void* buffer, int* length) +{ + addSsrc(RtpHelper::findSsrc(buffer, *length), sdOutgoing); + + Lock l(mGuard); + if (mOutboundSession) + return srtp_protect(mOutboundSession, buffer, length) == 0; + else + return false; +} + +bool SrtpSession::protectRtcp(void* buffer, int* length) +{ + addSsrc(RtpHelper::findSsrc(buffer, *length), sdOutgoing); + + Lock l(mGuard); + if (mOutboundSession) + return srtp_protect_rtcp(mOutboundSession, buffer, length) == 0; + else + return false; +} + +bool SrtpSession::unprotectRtp(void* buffer, int* length) +{ + addSsrc(RtpHelper::findSsrc(buffer, *length), sdIncoming); + + Lock l(mGuard); + if (mInboundSession) + return srtp_unprotect(mInboundSession, buffer, length) == 0; + else + return false; +} + +bool SrtpSession::unprotectRtcp(void* buffer, int* length) +{ + addSsrc(RtpHelper::findSsrc(buffer, *length), sdIncoming); + + Lock l(mGuard); + if (mInboundSession) + return srtp_unprotect_rtcp(mInboundSession, buffer, (int*)length) == 0; + else + return false; +} + +static bool GSrtpInitialized = false; +void SrtpSession::initSrtp() +{ + if (GSrtpInitialized) + return; + + err_status_t err = srtp_init(); + + if (err != err_status_ok) + throw Exception(ERR_SRTP, err); + GSrtpInitialized = true; +} diff --git a/src/engine/media/MT_SrtpHelper.h b/src/engine/media/MT_SrtpHelper.h new file mode 100644 index 00000000..47f0d011 --- /dev/null +++ b/src/engine/media/MT_SrtpHelper.h @@ -0,0 +1,73 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __MT_SRTP_HELPER_H +#define __MT_SRTP_HELPER_H + +#include +#include +#include + +#include "srtp/include/srtp.h" +#include "../helper/HL_Sync.h" +#include "../helper/HL_ByteBuffer.h" + +#define SRTP_SUITE_NAME_2 "AES_CM_256_HMAC_SHA1_80" +#define SRTP_SUITE_NAME_1 "AES_CM_128_HMAC_SHA1_80" + +enum SrtpSuite +{ + SRTP_NONE, + SRTP_AES_128_AUTH_80, + SRTP_AES_256_AUTH_80, + SRTP_LAST = SRTP_AES_256_AUTH_80 +}; + +typedef std::pair SrtpKeySalt; +typedef std::pair SrtpStream; + +class SrtpSession +{ +public: + SrtpSession(); + ~SrtpSession(); + + enum SsrcDirection + { + sdIncoming, + sdOutgoing + }; + SrtpKeySalt& outgoingKey(SrtpSuite suite); + + void open(ByteBuffer& incomingKey, SrtpSuite suite); + void close(); + bool active(); + + /* bufferPtr is RTP packet data i.e. header + payload. Buffer must be big enough to hold encrypted data. */ + bool protectRtp(void* buffer, int* length); + bool protectRtcp(void* buffer, int* length); + bool unprotectRtp(void* buffer, int* length); + bool unprotectRtcp(void* buffer, int* length); + + + static void initSrtp(); +protected: + srtp_t mInboundSession, + mOutboundSession; + + SrtpKeySalt mIncomingKey, + mOutgoingKey[SRTP_LAST]; + srtp_policy_t mInboundPolicy; + srtp_policy_t mOutboundPolicy; + SrtpSuite mSuite; + + typedef std::map SrtpStreamMap; + SrtpStreamMap mIncomingMap, mOutgoingMap; + Mutex mGuard; + + void addSsrc(unsigned ssrc, SsrcDirection d); +}; + +#endif diff --git a/src/engine/media/MT_Statistics.cpp b/src/engine/media/MT_Statistics.cpp new file mode 100644 index 00000000..9961d7ed --- /dev/null +++ b/src/engine/media/MT_Statistics.cpp @@ -0,0 +1,276 @@ +#include + +#include "MT_Statistics.h" +#include "audio/Audio_Interface.h" +#include "helper/HL_Log.h" +#define LOG_SUBSYSTEM "Statistics" + +using namespace MT; + +void JitterStatistics::process(jrtplib::RTPPacket* packet, int rate) +{ + jrtplib::RTPTime receiveTime = packet->GetReceiveTime(); + uint32_t timestamp = packet->GetTimestamp(); + + if (!mLastJitter.is_initialized()) + { + mReceiveTime = receiveTime; + mReceiveTimestamp = timestamp; + mLastJitter = 0.0; + } + else + { + double delta = (receiveTime.GetDouble() - mReceiveTime.GetDouble()) - double(timestamp - mReceiveTimestamp) / rate; + if (fabs(delta) > mMaxDelta) + mMaxDelta = fabs(delta); + + mLastJitter = mLastJitter.value() + (fabs(delta) - mLastJitter.value()) / 16.0; + mReceiveTime = receiveTime; + mReceiveTimestamp = timestamp; + + mJitter.process(mLastJitter.value()); + } +} + + +// ---------------------------- Statistics ------------------------------------ + + +Statistics::Statistics() + :mReceived(0), mSent(0), mReceivedRtp(0), mSentRtp(0), + mReceivedRtcp(0), mSentRtcp(0), mDuplicatedRtp(0), mOldRtp(0), mIllegalRtp(0), + mPacketLoss(0), mJitter(0.0), mAudioTime(0), mSsrc(0) +{ +#if defined(USE_AMR_CODEC) + mBitrateSwitchCounter = 0; +#endif + + memset(mLoss, 0, sizeof mLoss); + + // It is to keep track of statistics instance via grep | wc -l + //ICELogDebug(<< "Create statistics instance."); +} + +Statistics::~Statistics() +{ +} + +void Statistics::reset() +{ + mReceived = 0; + mSent = 0; + mReceivedRtp = 0; + mSentRtp = 0; + mReceivedRtcp = 0; + mSentRtcp = 0; + mDuplicatedRtp = 0; + mOldRtp = 0; + mPacketLoss = 0; + mIllegalRtp = 0; + mJitter = 0.0; + mAudioTime = 0; + memset(mLoss, 0, sizeof mLoss); +} + +/* +double calculate_mos_g711(double ppl, double burstr, int version) { +double r; +double bpl = 8.47627; //mos = -4.23836 + 0.29873 * r - 0.00416744 * r * r + 0.0000209855 * r * r * r; +double mos; + +if(ppl == 0 or burstr == 0) { +return 4.5; +} + +if(ppl > 0.5) { +return 1; +} + +switch(version) { +case 1: +case 2: +default: +// this mos is calculated for G.711 and PLC +bpl = 17.2647; +r = 93.2062077233 - 95.0 * (ppl*100/(ppl*100/burstr + bpl)); +mos = 2.06405 + 0.031738 * r - 0.000356641 * r * r + 2.93143 * pow(10,-6) * r * r * r; +if(mos < 1) +return 1; +if(mos > 4.5) +return 4.5; +} + +return mos; +} + + +double calculate_mos(double ppl, double burstr, int codec, unsigned int received) { +if(codec == PAYLOAD_G729) { +if(opt_mos_g729) { +if(received < 100) { +return 3.92; +} +return (double)mos_g729((long double)ppl, (long double)burstr); +} else { +if(received < 100) { +return 4.5; +} +return calculate_mos_g711(ppl, burstr, 2); +} +} else { +if(received < 100) { +return 4.5; +} +return calculate_mos_g711(ppl, burstr, 2); +} +} + +*/ + +void Statistics::calculateBurstr(double* burstr, double* lossr) const +{ + int lost = 0; + int bursts = 0; + for (int i = 0; i < 128; i++) + { + lost += i * mLoss[i]; + bursts += mLoss[i]; + } + + if (lost < 5) + { + // ignore such small packet loss + *lossr = *burstr = 0; + return; + } + + if (mReceivedRtp > 0 && bursts > 0) + { + *burstr = (double)((double)lost / (double)bursts) / (double)(1.0 / (1.0 - (double)lost / (double)mReceivedRtp)); + if (*burstr < 0) + *burstr = -*burstr; + else if (*burstr < 1) + *burstr = 1; + } + else + *burstr = 0; + //printf("total loss: %d\n", lost); + if (mReceivedRtp > 0) + *lossr = (double)((double)lost / (double)mReceivedRtp); + else + *lossr = 0; +} + +double Statistics::calculateMos(double maximalMos) const +{ + // calculate lossrate and burst rate + double burstr, lossr; + calculateBurstr(&burstr, &lossr); + + double r; + double bpl = 8.47627; //mos = -4.23836 + 0.29873 * r - 0.00416744 * r * r + 0.0000209855 * r * r * r; + double mos; + + if (mReceivedRtp < 100) + return 0.0; + + if (lossr == 0 || burstr == 0) + { + return maximalMos; + } + + if (lossr > 0.5) + return 1; + + bpl = 17.2647; + r = 93.2062077233 - 95.0 * (lossr * 100 / (lossr * 100 / burstr + bpl)); + mos = 2.06405 + 0.031738 * r - 0.000356641 * r * r + 2.93143 * pow(10, -6) * r * r * r; + if (mos < 1) + return 1; + + if (mos > maximalMos) + return maximalMos; + + return mos; +} + +Statistics& Statistics::operator += (const Statistics& src) +{ + mReceived += src.mReceived; + mSent += src.mSent; + mReceivedRtp += src.mReceivedRtp; + mSentRtp += src.mSentRtp; + mReceivedRtcp += src.mReceivedRtcp; + mSentRtcp += src.mSentRtcp; + mDuplicatedRtp += src.mDuplicatedRtp; + mOldRtp += src.mOldRtp; + mPacketLoss += src.mPacketLoss; + mAudioTime += src.mAudioTime; + + for (auto codecStat: src.mCodecCount) + { + if (mCodecCount.find(codecStat.first) == mCodecCount.end()) + mCodecCount[codecStat.first] = codecStat.second; + else + mCodecCount[codecStat.first] += codecStat.second; + } + + mJitter = src.mJitter; + mRttDelay = src.mRttDelay; + if (!src.mCodecName.empty()) + mCodecName = src.mCodecName; + + // Find minimal + if (mFirstRtpTime.is_initialized()) + { + if (src.mFirstRtpTime.is_initialized()) + { + if (mFirstRtpTime.value() > src.mFirstRtpTime.value()) + mFirstRtpTime = src.mFirstRtpTime; + } + } + else + if (src.mFirstRtpTime.is_initialized()) + mFirstRtpTime = src.mFirstRtpTime; + +#if defined(USE_AMR_CODEC) + mBitrateSwitchCounter += src.mBitrateSwitchCounter; +#endif + mRemotePeer = src.mRemotePeer; + mSsrc = src.mSsrc; + + return *this; +} + +Statistics& Statistics::operator -= (const Statistics& src) +{ + mReceived -= src.mReceived; + mSent -= src.mSent; + mReceivedRtp -= src.mReceivedRtp; + mIllegalRtp -= src.mIllegalRtp; + mSentRtp -= src.mSentRtp; + mReceivedRtcp -= src.mReceivedRtcp; + mSentRtcp -= src.mSentRtcp; + mDuplicatedRtp -= src.mDuplicatedRtp; + mOldRtp -= src.mOldRtp; + mPacketLoss -= src.mPacketLoss; + mAudioTime -= src.mAudioTime; + for (auto codecStat: src.mCodecCount) + { + if (mCodecCount.find(codecStat.first) != mCodecCount.end()) + mCodecCount[codecStat.first] -= codecStat.second; + } + + return *this; +} + + +std::string Statistics::toShortString() const +{ + std::ostringstream oss; + oss << "Received: " << mReceivedRtp + << ", lost: " << mPacketLoss + << ", sent: " << mSentRtp; + + return oss.str(); +} diff --git a/src/engine/media/MT_Statistics.h b/src/engine/media/MT_Statistics.h new file mode 100644 index 00000000..3cd311b7 --- /dev/null +++ b/src/engine/media/MT_Statistics.h @@ -0,0 +1,150 @@ +#ifndef _MT_STATISTICS_H +#define _MT_STATISTICS_H + +#include +#include + +#include "audio/Audio_DataWindow.h" +#include "helper/HL_Optional.hpp" +#include "jrtplib/src/rtptimeutilities.h" +#include "jrtplib/src/rtppacket.h" + +#include "MT_SevanaMos.h" + +using std::experimental::optional; + +namespace MT +{ + template + struct Average + { + int mCount = 0; + T mSum = 0; + T getAverage() const + { + if (!mCount) + return 0; + return mSum / mCount; + } + + void process(T value) + { + mCount++; + mSum += value; + } + }; + + template + struct ProbeStats + { + T mMin = minimum; + T mMax = maximum; + Average mAverage; + T mCurrent = minimum; + + void process(T value) + { + if (mMin > value) + mMin = value; + if (mMax < value) + mMax = value; + mCurrent = value; + mAverage.process(value); + } + + bool isInitialized() const + { + return mAverage.mCount > 0; + } + + T getCurrent() const + { + if (isInitialized()) + return mCurrent; + else + return 0; + } + }; + + + template + struct StreamStats + { + T mChunk; + T mTotal; + }; + + + class JitterStatistics + { + public: + void process(jrtplib::RTPPacket* packet, int samplerate); + ProbeStats get() const { return mJitter; } + double getMaxDelta() const { return mMaxDelta; } + + protected: + // Jitter calculation + jrtplib::RTPTime mReceiveTime = jrtplib::RTPTime(0,0); + uint32_t mReceiveTimestamp = 0; + optional mLastJitter; + ProbeStats mJitter; + double mMaxDelta = 0.0; + }; + + class Statistics + { + public: + int mReceived, // Received traffic in bytes + mSent, // Sent traffic in bytes + mReceivedRtp, // Number of received rtp packets + mSentRtp, // Number of sent rtp packets + mReceivedRtcp, // Number of received rtcp packets + mSentRtcp, // Number of sent rtcp packets + mDuplicatedRtp, // Number of received duplicated rtp packets + mOldRtp, // Number of late rtp packets + mPacketLoss, // Number of lost packets + mIllegalRtp; // Number of rtp packets with bad payload type + int mLoss[128]; // Every item is number of loss of corresping length + int mAudioTime; // Decoded/found time in milliseconds + uint16_t mSsrc; // Last known SSRC ID in a RTP stream + ice::NetworkAddress mRemotePeer; // Last known remote RTP address + +#if defined(USE_AMR_CODEC) + int mBitrateSwitchCounter; +#endif + + std::string mCodecName; + + float mJitter; // Jitter + + ProbeStats mRttDelay; // RTT delay + + // Timestamp when first RTP packet has arrived + optional mFirstRtpTime; + + std::map mCodecCount; // Stats on used codecs + + // It is to calculate network MOS + void calculateBurstr(double* burstr, double* loss) const; + double calculateMos(double maximalMos) const; + + Statistics(); + ~Statistics(); + void reset(); + + Statistics& operator += (const Statistics& src); + Statistics& operator -= (const Statistics& src); + + float mNetworkMos = 0.0; + #if defined(USE_PVQA_LIBRARY) && !defined(PVQA_SERVER) + float mPvqaMos = 0.0; + std::string mPvqaReport; + #endif + + std::string toShortString() const; + }; + +} // end of namespace MT + + +#endif diff --git a/src/engine/media/MT_Stream.cpp b/src/engine/media/MT_Stream.cpp new file mode 100644 index 00000000..68fee660 --- /dev/null +++ b/src/engine/media/MT_Stream.cpp @@ -0,0 +1,130 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "MT_Stream.h" +#include "../audio/Audio_Interface.h" +#include "../helper/HL_Log.h" +#include + +#define LOG_SUBSYSTEM "[Media]" + +using namespace MT; + + + +Stream::Stream() +:mState(0) +{ +} + +Stream::~Stream() +{ + +} + +void Stream::setDestination(const RtpPair& dest) +{ + ICELogInfo(<< "Set RTP destination to " << dest.mRtp.toStdString()); + mDestination = dest; + + mStat.mRemotePeer = dest.mRtp; +} + +void Stream::setState(unsigned state) +{ + mState = state; +} + +unsigned Stream::state() +{ + return mState; +} + +void Stream::setSocket(const RtpPair& socket) +{ + mSocket = socket; +} + +RtpPair& Stream::socket() +{ + return mSocket; +} + +Statistics& Stream::statistics() +{ + return mStat; +} + +SrtpSession& Stream::srtp() +{ + return mSrtpSession; +} + +void Stream::configureMediaObserver(MediaObserver *observer, void* userTag) +{ + mMediaObserver = observer; + mMediaObserverTag = userTag; +} + +StreamList::StreamList() +{ +} + +StreamList::~StreamList() +{ + clear(); +} + +void StreamList::add(PStream s) +{ + Lock l(mMutex); + mStreamVector.push_back(s); +} + +void StreamList::remove(PStream s) +{ + Lock l(mMutex); + + StreamVector::iterator streamIter = std::find(mStreamVector.begin(), mStreamVector.end(), s); + if (streamIter != mStreamVector.end()) + mStreamVector.erase(streamIter); +} + +void StreamList::clear() +{ + Lock l(mMutex); + mStreamVector.clear(); +} + +bool StreamList::has(PStream s) +{ + Lock l(mMutex); + return std::find(mStreamVector.begin(), mStreamVector.end(), s) != mStreamVector.end(); +} + +int StreamList::size() +{ + Lock l(mMutex); + return mStreamVector.size(); +} + +PStream StreamList::streamAt(int index) +{ + return mStreamVector[index]; +} + +void StreamList::copyTo(StreamList* sl) +{ + Lock l(mMutex); + Lock l2(sl->mMutex); + StreamVector::iterator streamIter = mStreamVector.begin(); + for(;streamIter != mStreamVector.end(); ++streamIter) + sl->add(*streamIter); +} + +Mutex& StreamList::getMutex() +{ + return mMutex; +} \ No newline at end of file diff --git a/src/engine/media/MT_Stream.h b/src/engine/media/MT_Stream.h new file mode 100644 index 00000000..b4b7d523 --- /dev/null +++ b/src/engine/media/MT_Stream.h @@ -0,0 +1,114 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __MT_STREAM_H +#define __MT_STREAM_H + +#include "ice/ICEAddress.h" +#include "MT_Codec.h" +#include "MT_SrtpHelper.h" +#include "MT_Statistics.h" +#include "../helper/HL_InternetAddress.h" +#include "../helper/HL_NetworkSocket.h" +#include "../helper/HL_Sync.h" +#include "../helper/HL_Rtp.h" +#include "../audio/Audio_WavFile.h" +#include "../audio/Audio_DataWindow.h" +#include +#include +#include +#include "../helper/HL_Optional.hpp" + +#if defined(USE_PVQA_LIBRARY) +# include "MT_SevanaMos.h" +#endif + +using std::experimental::optional; + +namespace MT +{ + class Stream + { + public: + enum Type + { + Audio = 1, + Video = 2 + }; + + enum class MediaDirection + { + Incoming, + Outgoing + }; + + class MediaObserver + { + public: + virtual void onMedia(const void* buffer, int length, MT::Stream::MediaDirection direction, + void* context, void* userTag) = 0; + }; + + Stream(); + virtual ~Stream(); + + virtual void setDestination(const RtpPair& dest); + + virtual void setTransmittingCodec(Codec::Factory& factory, int payloadType) = 0; + virtual void dataArrived(PDatagramSocket s, const void* buffer, int length, InternetAddress& source) = 0; + + + virtual void readFile(const Audio::PWavFileReader& reader, MediaDirection direction) = 0; + virtual void writeFile(const Audio::PWavFileWriter& writer, MediaDirection direction) = 0; + virtual void setupMirror(bool enable) = 0; + + virtual void setState(unsigned state); + virtual unsigned state(); + + virtual void setSocket(const RtpPair& socket); + virtual RtpPair& socket(); + + Statistics& statistics(); + SrtpSession& srtp(); + void configureMediaObserver(MediaObserver* observer, void* userTag); + + protected: + unsigned mState; + RtpPair mDestination; + RtpPair mSocket; + Statistics mStat; + SrtpSession mSrtpSession; + MediaObserver* mMediaObserver = nullptr; + void* mMediaObserverTag = nullptr; + }; + + typedef std::shared_ptr PStream; + + class StreamList + { + public: + StreamList(); + ~StreamList(); + + void add(PStream s); + void remove(PStream s); + void clear(); + bool has(PStream s); + + int size(); + PStream streamAt(int index); + + void copyTo(StreamList* sl); + + Mutex& getMutex(); + protected: + typedef std::vector StreamVector; + StreamVector mStreamVector; + Mutex mMutex; + }; +} + + +#endif diff --git a/src/engine/media/MT_WebRtc.cpp b/src/engine/media/MT_WebRtc.cpp new file mode 100644 index 00000000..965bfbe1 --- /dev/null +++ b/src/engine/media/MT_WebRtc.cpp @@ -0,0 +1,70 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "../config.h" +#include "MT_WebRtc.h" +#include "../helper/HL_Exception.h" + +#include + +static void checkResultCode(unsigned short code) +{ + if (code) + throw Exception(ERR_WEBRTC, code); +} + +Vad::Vad(int sampleRate) +:mSampleRate(sampleRate), mContext(NULL) +{ + checkResultCode(WebRtcVad_Create(&mContext)); +} + +Vad::~Vad() +{ + if (mContext) + WebRtcVad_Free(mContext); +} + +bool Vad::isSilence(short* samplePtr, int nrOfSamples) +{ + short resultCode = WebRtcVad_Process(mContext, mSampleRate, samplePtr, nrOfSamples); + return !resultCode; +} + +// -- Cng --- +Cng::Cng() +:mEncoder(NULL), mDecoder(NULL) +{ + checkResultCode(WebRtcCng_CreateEnc(&mEncoder)); + checkResultCode(WebRtcCng_CreateDec(&mDecoder)); +} + +Cng::~Cng() +{ + if (mEncoder) + WebRtcCng_FreeEnc(mEncoder); + if (mDecoder) + WebRtcCng_FreeDec(mDecoder); +} + +void Cng::updateSid(unsigned char *sidPacket, int sidLength) +{ + WebRtcCng_UpdateSid(mDecoder, sidPacket, sidLength); +} + +void Cng::generateSid(short* samples, int nrOfSamples, unsigned char* sidPacket, int* sidLength) +{ + WebRtc_Word16 produced = 0; + checkResultCode(WebRtcCng_Encode(mEncoder, (WebRtc_Word16*)samples, nrOfSamples, sidPacket, &produced, 1/*TRUE*/)); + + *sidLength = (int)produced; +} + +void Cng::generateNoise(short* buffer, int nrOfSamples) +{ + checkResultCode(WebRtcCng_Generate(mDecoder, buffer, nrOfSamples, 1 /*Reset CNG history*/)); +} + + diff --git a/src/engine/media/MT_WebRtc.h b/src/engine/media/MT_WebRtc.h new file mode 100644 index 00000000..ff525ccd --- /dev/null +++ b/src/engine/media/MT_WebRtc.h @@ -0,0 +1,46 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __MT_WEBRTC_H +#define __MT_WEBRTC_H + +#include +#include +#include "jrtplib/src/rtppacket.h" +#include "webrtc/cng/webrtc_cng.h" +#include "webrtc/vad/webrtc_vad.h" + +// Voice activity detector. It is tiny wrapper for webrtc functionality. +class Vad +{ +public: + Vad(int sampleRate); + ~Vad(); + + bool isSilence(short* samplePtr, int sampleCount); + +protected: + int mSampleRate; + bool mEnabled; + VadInst* mContext; +}; + +// Comfort noise helper. It is tiny wrapper for webrtc functionality. +class Cng +{ +public: + Cng(); + ~Cng(); + + void updateSid(unsigned char *sidPacket, int sidLength); + void generateSid(short* samples, int nrOfSamples, unsigned char* sidPacket, int* sidLength); + void generateNoise(short* buffer, int nrOfSamples); + +protected: + CNG_enc_inst* mEncoder; + CNG_dec_inst* mDecoder; +}; + +#endif diff --git a/src/libs/android-ifaddrs/ifaddrs.cpp b/src/libs/android-ifaddrs/ifaddrs.cpp new file mode 100644 index 00000000..305576af --- /dev/null +++ b/src/libs/android-ifaddrs/ifaddrs.cpp @@ -0,0 +1,205 @@ +#include "ifaddrs.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct netlinkrequest { + nlmsghdr header; + ifaddrmsg msg; +}; + +const int kMaxReadSize = 4096; + + +int set_ifname(struct ifaddrs* ifaddr, int interface) { + char buf[IFNAMSIZ] = {0}; + char* name = if_indextoname(interface, buf); + if (name == NULL) { + return -1; + } + ifaddr->ifa_name = new char[strlen(name) + 1]; + strncpy(ifaddr->ifa_name, name, strlen(name) + 1); + return 0; +} + +int set_flags(struct ifaddrs* ifaddr) { + int fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd == -1) { + return -1; + } + ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, ifaddr->ifa_name, IFNAMSIZ - 1); + int rc = ioctl(fd, SIOCGIFFLAGS, &ifr); + close(fd); + if (rc == -1) { + return -1; + } + ifaddr->ifa_flags = ifr.ifr_flags; + return 0; +} + +int set_addresses(struct ifaddrs* ifaddr, ifaddrmsg* msg, void* data, + size_t len) { + if (msg->ifa_family == AF_INET) { + sockaddr_in* sa = new sockaddr_in; + sa->sin_family = AF_INET; + memcpy(&sa->sin_addr, data, len); + ifaddr->ifa_addr = reinterpret_cast(sa); + } else if (msg->ifa_family == AF_INET6) { + sockaddr_in6* sa = new sockaddr_in6; + sa->sin6_family = AF_INET6; + sa->sin6_scope_id = msg->ifa_index; + memcpy(&sa->sin6_addr, data, len); + ifaddr->ifa_addr = reinterpret_cast(sa); + } else { + return -1; + } + return 0; +} + +int make_prefixes(struct ifaddrs* ifaddr, int family, int prefixlen) { + char* prefix = NULL; + if (family == AF_INET) { + sockaddr_in* mask = new sockaddr_in; + mask->sin_family = AF_INET; + memset(&mask->sin_addr, 0, sizeof(in_addr)); + ifaddr->ifa_netmask = reinterpret_cast(mask); + if (prefixlen > 32) { + prefixlen = 32; + } + prefix = reinterpret_cast(&mask->sin_addr); + } else if (family == AF_INET6) { + sockaddr_in6* mask = new sockaddr_in6; + mask->sin6_family = AF_INET6; + memset(&mask->sin6_addr, 0, sizeof(in6_addr)); + ifaddr->ifa_netmask = reinterpret_cast(mask); + if (prefixlen > 128) { + prefixlen = 128; + } + prefix = reinterpret_cast(&mask->sin6_addr); + } else { + return -1; + } + for (int i = 0; i < (prefixlen / 8); i++) { + *prefix++ = 0xFF; + } + char remainder = 0xff; + remainder <<= (8 - prefixlen % 8); + *prefix = remainder; + return 0; +} + +int populate_ifaddrs(struct ifaddrs* ifaddr, ifaddrmsg* msg, void* bytes, + size_t len) { + if (set_ifname(ifaddr, msg->ifa_index) != 0) { + return -1; + } + if (set_flags(ifaddr) != 0) { + return -1; + } + if (set_addresses(ifaddr, msg, bytes, len) != 0) { + return -1; + } + if (make_prefixes(ifaddr, msg->ifa_family, msg->ifa_prefixlen) != 0) { + return -1; + } + return 0; +} + +int getifaddrs(struct ifaddrs** result) { + int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (fd < 0) { + return -1; + } + + netlinkrequest ifaddr_request; + memset(&ifaddr_request, 0, sizeof(ifaddr_request)); + ifaddr_request.header.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST; + ifaddr_request.header.nlmsg_type = RTM_GETADDR; + ifaddr_request.header.nlmsg_len = NLMSG_LENGTH(sizeof(ifaddrmsg)); + + ssize_t count = send(fd, &ifaddr_request, ifaddr_request.header.nlmsg_len, 0); + if (static_cast(count) != ifaddr_request.header.nlmsg_len) { + close(fd); + return -1; + } + struct ifaddrs* start = NULL; + struct ifaddrs* current = NULL; + char buf[kMaxReadSize]; + ssize_t amount_read = recv(fd, &buf, kMaxReadSize, 0); + while (amount_read > 0) { + nlmsghdr* header = reinterpret_cast(&buf[0]); + size_t header_size = static_cast(amount_read); + for ( ; NLMSG_OK(header, header_size); + header = NLMSG_NEXT(header, header_size)) { + switch (header->nlmsg_type) { + case NLMSG_DONE: + // Success. Return. + *result = start; + close(fd); + return 0; + case NLMSG_ERROR: + close(fd); + freeifaddrs(start); + return -1; + case RTM_NEWADDR: { + ifaddrmsg* address_msg = + reinterpret_cast(NLMSG_DATA(header)); + rtattr* rta = IFA_RTA(address_msg); + ssize_t payload_len = IFA_PAYLOAD(header); + while (RTA_OK(rta, payload_len)) { + if (rta->rta_type == IFA_ADDRESS) { + int family = address_msg->ifa_family; + if (family == AF_INET || family == AF_INET6) { + ifaddrs* newest = new ifaddrs; + memset(newest, 0, sizeof(ifaddrs)); + if (current) { + current->ifa_next = newest; + } else { + start = newest; + } + if (populate_ifaddrs(newest, address_msg, RTA_DATA(rta), + RTA_PAYLOAD(rta)) != 0) { + freeifaddrs(start); + *result = NULL; + return -1; + } + current = newest; + } + } + rta = RTA_NEXT(rta, payload_len); + } + break; + } + } + } + amount_read = recv(fd, &buf, kMaxReadSize, 0); + } + close(fd); + freeifaddrs(start); + return -1; +} + +void freeifaddrs(struct ifaddrs* addrs) { + struct ifaddrs* last = NULL; + struct ifaddrs* cursor = addrs; + while (cursor) { + delete[] cursor->ifa_name; + delete cursor->ifa_addr; + delete cursor->ifa_netmask; + last = cursor; + cursor = cursor->ifa_next; + delete last; + } +} diff --git a/src/libs/android-ifaddrs/ifaddrs.h b/src/libs/android-ifaddrs/ifaddrs.h new file mode 100644 index 00000000..e9d36c44 --- /dev/null +++ b/src/libs/android-ifaddrs/ifaddrs.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1995, 1999 + * Berkeley Software Design, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp + */ + +#ifndef _ANDROID_IFADDRS_H_ +#define _ANDROID_IFADDRS_H_ + +#include +#include + +// Implementation of getifaddrs for Android. +// Fills out a list of ifaddr structs (see below) which contain information +// about every network interface available on the host. +// See 'man getifaddrs' on Linux or OS X (nb: it is not a POSIX function). +struct ifaddrs { + struct ifaddrs* ifa_next; + char* ifa_name; + unsigned int ifa_flags; + struct sockaddr* ifa_addr; + struct sockaddr* ifa_netmask; + // Real ifaddrs has broadcast, point to point and data members. + // We don't need them (yet?). +}; + +int getifaddrs(struct ifaddrs** result); +void freeifaddrs(struct ifaddrs* addrs); + +#endif diff --git a/src/libs/dxguid.lib b/src/libs/dxguid.lib new file mode 100644 index 00000000..82835ab2 Binary files /dev/null and b/src/libs/dxguid.lib differ diff --git a/src/libs/g722/CMakeLists.txt b/src/libs/g722/CMakeLists.txt new file mode 100644 index 00000000..ce41bc6b --- /dev/null +++ b/src/libs/g722/CMakeLists.txt @@ -0,0 +1,13 @@ +project (g722_codec) + +# Rely on C++ 11 +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +set (G722_SOURCES + g722_bitstream.c + g722_decode.c + g722_encode.c +) + +add_library(g722_codec ${G722_SOURCES}) diff --git a/src/libs/g722/g722.h b/src/libs/g722/g722.h new file mode 100644 index 00000000..23bd782a --- /dev/null +++ b/src/libs/g722/g722.h @@ -0,0 +1,184 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * g722.h - The ITU G.722 codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, or + * the Lesser GNU General Public License version 2.1, as published by + * the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based on a single channel G.722 codec which is: + * + ***** Copyright (c) CMU 1993 ***** + * Computer Science, Speech Group + * Chengxiang Lu and Alex Hauptmann + * + * $Id: g722.h,v 1.17 2008/02/09 15:32:26 steveu Exp $ + */ + + +/*! \file */ + +#if !defined(_SPANDSP_G722_H_) +#define _SPANDSP_G722_H_ + +#include "inttypes.h" + + +/*! \page g722_page G.722 encoding and decoding +\section g722_page_sec_1 What does it do? +The G.722 module is a bit exact implementation of the ITU G.722 specification for all three +specified bit rates - 64000bps, 56000bps and 48000bps. It passes the ITU tests. + +To allow fast and flexible interworking with narrow band telephony, the encoder and decoder +support an option for the linear audio to be an 8k samples/second stream. In this mode the +codec is considerably faster, and still fully compatible with wideband terminals using G.722. + +\section g722_page_sec_2 How does it work? +???. +*/ + +enum +{ + G722_SAMPLE_RATE_8000 = 0x0001, + G722_PACKED = 0x0002 +}; + +typedef struct +{ + /*! TRUE if the operating in the special ITU test mode, with the band split filters + disabled. */ + int itu_test_mode; + /*! TRUE if the G.722 data is packed */ + int packed; + /*! TRUE if encode from 8k samples/second */ + int eight_k; + /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */ + int bits_per_sample; + + /*! Signal history for the QMF */ + int x[24]; + + struct + { + int s; + int sp; + int sz; + int r[3]; + int a[3]; + int ap[3]; + int p[3]; + int d[7]; + int b[7]; + int bp[7]; + int sg[7]; + int nb; + int det; + } band[2]; + + unsigned int in_buffer; + int in_bits; + unsigned int out_buffer; + int out_bits; +} g722_encode_state_t; + +typedef struct +{ + /*! TRUE if the operating in the special ITU test mode, with the band split filters + disabled. */ + int itu_test_mode; + /*! TRUE if the G.722 data is packed */ + int packed; + /*! TRUE if decode to 8k samples/second */ + int eight_k; + /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */ + int bits_per_sample; + + /*! Signal history for the QMF */ + int x[24]; + + struct + { + int s; + int sp; + int sz; + int r[3]; + int a[3]; + int ap[3]; + int p[3]; + int d[7]; + int b[7]; + int bp[7]; + int sg[7]; + int nb; + int det; + } band[2]; + + unsigned int in_buffer; + int in_bits; + unsigned int out_buffer; + int out_bits; +} g722_decode_state_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! Initialise an G.722 encode context. + \param s The G.722 encode context. + \param rate The required bit rate for the G.722 data. + The valid rates are 64000, 56000 and 48000. + \param options + \return A pointer to the G.722 encode context, or NULL for error. */ +g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options); + +int g722_encode_release(g722_encode_state_t *s); + +/*! Encode a buffer of linear PCM data to G.722 + \param s The G.722 context. + \param g722_data The G.722 data produced. + \param amp The audio sample buffer. + \param len The number of samples in the buffer. + \return The number of bytes of G.722 data produced. */ +int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len); + +/*! Initialise an G.722 decode context. + \param s The G.722 decode context. + \param rate The bit rate of the G.722 data. + The valid rates are 64000, 56000 and 48000. + \param options + \return A pointer to the G.722 decode context, or NULL for error. */ +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options); + +int g722_decode_release(g722_decode_state_t *s); + +/*! Decode a buffer of G.722 data to linear PCM. + \param s The G.722 context. + \param amp The audio sample buffer. + \param g722_data + \param len + \return The number of samples returned. */ +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/src/libs/g722/g722_bitstream.c b/src/libs/g722/g722_bitstream.c new file mode 100644 index 00000000..19a33935 --- /dev/null +++ b/src/libs/g722/g722_bitstream.c @@ -0,0 +1,137 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * bitstream.c - Bitstream composition and decomposition routines. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser Lesser GNU General Public License version 2.1.1, as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: bitstream.c,v 1.8 2007/08/20 15:22:21 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "inttypes.h" +#include +#include +#include + +#include "g722_telephony.h" +#include "g722_bitstream.h" + +void bitstream_put(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits) +{ + value &= ((1 << bits) - 1); + if (s->residue + bits <= 32) + { + s->bitstream |= (value << s->residue); + s->residue += bits; + } + while (s->residue >= 8) + { + s->residue -= 8; + *(*c)++ = (uint8_t) (s->bitstream & 0xFF); + s->bitstream >>= 8; + } +} +/*- End of function --------------------------------------------------------*/ + +void bitstream_put2(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits) +{ + value &= ((1 << bits) - 1); + if (s->residue + bits <= 32) + { + s->bitstream = (s->bitstream << bits) | value; + s->residue += bits; + } + while (s->residue >= 8) + { + s->residue -= 8; + *(*c)++ = (uint8_t) ((s->bitstream >> s->residue) & 0xFF); + } +} +/*- End of function --------------------------------------------------------*/ + +unsigned int bitstream_get(bitstream_state_t *s, const uint8_t **c, int bits) +{ + unsigned int x; + + while (s->residue < (unsigned int) bits) + { + x = (unsigned int) *(*c)++; + s->bitstream |= (x << s->residue); + s->residue += 8; + } + s->residue -= bits; + x = s->bitstream & ((1 << bits) - 1); + s->bitstream >>= bits; + return x; +} +/*- End of function --------------------------------------------------------*/ + +unsigned int bitstream_get2(bitstream_state_t *s, const uint8_t **c, int bits) +{ + unsigned int x; + + while (s->residue < (unsigned int) bits) + { + x = (unsigned int) *(*c)++; + s->bitstream = (s->bitstream << 8) | x; + s->residue += 8; + } + s->residue -= bits; + x = (s->bitstream >> s->residue) & ((1 << bits) - 1); + return x; +} +/*- End of function --------------------------------------------------------*/ + +void bitstream_flush(bitstream_state_t *s, uint8_t **c) +{ + if (s->residue > 0) + { + *(*c)++ = (uint8_t) ((s->bitstream << (8 - s->residue)) & 0xFF); + s->residue = 0; + } +} +/*- End of function --------------------------------------------------------*/ + +void bitstream_flush2(bitstream_state_t *s, uint8_t **c) +{ + if (s->residue > 0) + { + *(*c)++ = (uint8_t) ((s->bitstream << (8 - s->residue)) & 0xFF); + s->residue = 0; + } +} +/*- End of function --------------------------------------------------------*/ + +bitstream_state_t *bitstream_init(bitstream_state_t *s) +{ + if (s == NULL) + return NULL; + s->bitstream = 0; + s->residue = 0; + return s; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/src/libs/g722/g722_bitstream.h b/src/libs/g722/g722_bitstream.h new file mode 100644 index 00000000..cb535990 --- /dev/null +++ b/src/libs/g722/g722_bitstream.h @@ -0,0 +1,89 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * bitstream.h - Bitstream composition and decomposition routines. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: bitstream.h,v 1.8 2007/12/13 11:31:32 steveu Exp $ + */ + +/*! \file */ + +#if !defined(_SPANDSP_BITSTREAM_H_) +#define _SPANDSP_BITSTREAM_H_ + +/*! \page bitstream_page Bitstream composition and decomposition +\section bitstream_page_sec_1 What does it do? + +\section bitstream_page_sec_2 How does it work? +*/ + +/*! Bitstream handler state */ +typedef struct +{ + /*! The bit stream. */ + unsigned int bitstream; + /*! The residual bits in bitstream. */ + unsigned int residue; +} bitstream_state_t; + + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! \brief Put a chunk of bits into the output buffer. + \param s A pointer to the bitstream context. + \param c A pointer to the bitstream output buffer. + \param value The value to be pushed into the output buffer. + \param bits The number of bits of value to be pushed. 1 to 25 bit is valid. */ +void bitstream_put(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits); + +void bitstream_put2(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits); + +/*! \brief Get a chunk of bits from the input buffer. + \param s A pointer to the bitstream context. + \param c A pointer to the bitstream input buffer. + \param bits The number of bits of value to be grabbed. 1 to 25 bit is valid. + \return The value retrieved from the input buffer. */ +unsigned int bitstream_get(bitstream_state_t *s, const uint8_t **c, int bits); + +unsigned int bitstream_get2(bitstream_state_t *s, const uint8_t **c, int bits); + +/*! \brief Flush any residual bit to the output buffer. + \param s A pointer to the bitstream context. + \param c A pointer to the bitstream output buffer. */ +void bitstream_flush(bitstream_state_t *s, uint8_t **c); + +void bitstream_flush2(bitstream_state_t *s, uint8_t **c); + +/*! \brief Initialise a bitstream context. + \param s A pointer to the bitstream context. + \return A pointer to the bitstream context. */ +bitstream_state_t *bitstream_init(bitstream_state_t *s); + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/src/libs/g722/g722_dc_restore.h b/src/libs/g722/g722_dc_restore.h new file mode 100644 index 00000000..f166d320 --- /dev/null +++ b/src/libs/g722/g722_dc_restore.h @@ -0,0 +1,157 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * dc_restore.h - General telephony routines to restore the zero D.C. + * level to audio which has a D.C. bias. + * + * Written by Steve Underwood + * + * Copyright (C) 2001 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: dc_restore.h,v 1.18 2007/04/08 08:16:17 steveu Exp $ + */ + +/*! \file */ + +#if !defined(_SPANDSP_DC_RESTORE_H_) +#define _SPANDSP_DC_RESTORE_H_ + +/*! \page dc_restore_page Removing DC bias from a signal + +\section dc_restore_page_sec_1 What does it do? + +Telecoms signals often contain considerable DC, but DC upsets a lot of signal +processing functions. Placing a zero DC restorer at the front of the processing +chain can often simplify the downstream processing. + +\section dc_restore_page_sec_2 How does it work? + +The DC restorer uses a leaky integrator to provide a long-ish term estimate of +the DC bias in the signal. A 32 bit estimate is used for the 16 bit audio, so +the noise introduced by the estimation can be keep in the lower bits, and the 16 +bit DC value, which is subtracted from the signal, is fairly clean. The +following code fragment shows the algorithm used. dc_bias is a 32 bit integer, +while the sample and the resulting clean_sample are 16 bit integers. + + dc_bias += ((((int32_t) sample << 15) - dc_bias) >> 14); + clean_sample = sample - (dc_bias >> 15); +*/ + +/*! + Zero DC restoration descriptor. This defines the working state for a single + instance of DC content filter. +*/ +typedef struct +{ + int32_t state; +} dc_restore_state_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +static __inline__ void dc_restore_init(dc_restore_state_t *dc) +{ + dc->state = 0; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t dc_restore(dc_restore_state_t *dc, int16_t sample) +{ + dc->state += ((((int32_t) sample << 15) - dc->state) >> 14); + return (int16_t) (sample - (dc->state >> 15)); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t dc_restore_estimate(dc_restore_state_t *dc) +{ + return (int16_t) (dc->state >> 15); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t saturate(int32_t amp) +{ + int16_t amp16; + + /* Hopefully this is optimised for the common case - not clipping */ + amp16 = (int16_t) amp; + if (amp == amp16) + return amp16; + if (amp > INT16_MAX) + return INT16_MAX; + return INT16_MIN; +} +/*- End of function --------------------------------------------------------*/ + +/*#ifdef _MSC_VER +__inline float rintf (float flt) +{ + _asm + { fld flt + frndint + } +} + +__inline double rint(double dbl) +{ + __asm + { + fld dbl + frndint + } +} + +__inline long lrintf (float flt) +{ + long retval; + _asm + { fld flt + fistp retval + } + return retval; +} +#endif +*/ + +static __inline__ int16_t fsaturatef(float famp) +{ + if (famp > 32767.0) + return INT16_MAX; + if (famp < -32768.0) + return INT16_MIN; + return (int16_t) rintf(famp); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t fsaturate(double damp) +{ + if (damp > 32767.0) + return INT16_MAX; + if (damp < -32768.0) + return INT16_MIN; + return (int16_t) rint(damp); +} +/*- End of function --------------------------------------------------------*/ + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/src/libs/g722/g722_decode.c b/src/libs/g722/g722_decode.c new file mode 100644 index 00000000..3f6d9968 --- /dev/null +++ b/src/libs/g722/g722_decode.c @@ -0,0 +1,403 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * g722_decode.c - The ITU G.722 codec, decode part. + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, or + * the Lesser GNU General Public License version 2.1, as published by + * the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based in part on a single channel G.722 codec which is: + * + * Copyright (c) CMU 1993 + * Computer Science, Speech Group + * Chengxiang Lu and Alex Hauptmann + * + * $Id: g722_decode.c,v 1.20 2008/02/09 15:32:56 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "g722_inttypes.h" +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#include + +#include "g722_telephony.h" +#include "g722_dc_restore.h" +#include "g722.h" + +static void block4(g722_decode_state_t *s, int band, int d); + +static void block4(g722_decode_state_t *s, int band, int d) +{ + int wd1; + int wd2; + int wd3; + int i; + + /* Block 4, RECONS */ + s->band[band].d[0] = d; + s->band[band].r[0] = saturate(s->band[band].s + d); + + /* Block 4, PARREC */ + s->band[band].p[0] = saturate(s->band[band].sz + d); + + /* Block 4, UPPOL2 */ + for (i = 0; i < 3; i++) + s->band[band].sg[i] = s->band[band].p[i] >> 15; + wd1 = saturate(s->band[band].a[1] << 2); + + wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1; + if (wd2 > 32767) + wd2 = 32767; + wd3 = (s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128; + wd3 += (wd2 >> 7); + wd3 += (s->band[band].a[2]*32512) >> 15; + if (wd3 > 12288) + wd3 = 12288; + else if (wd3 < -12288) + wd3 = -12288; + s->band[band].ap[2] = wd3; + + /* Block 4, UPPOL1 */ + s->band[band].sg[0] = s->band[band].p[0] >> 15; + s->band[band].sg[1] = s->band[band].p[1] >> 15; + wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192; + wd2 = (s->band[band].a[1]*32640) >> 15; + + s->band[band].ap[1] = saturate(wd1 + wd2); + wd3 = saturate(15360 - s->band[band].ap[2]); + if (s->band[band].ap[1] > wd3) + s->band[band].ap[1] = wd3; + else if (s->band[band].ap[1] < -wd3) + s->band[band].ap[1] = -wd3; + + /* Block 4, UPZERO */ + wd1 = (d == 0) ? 0 : 128; + s->band[band].sg[0] = d >> 15; + for (i = 1; i < 7; i++) + { + s->band[band].sg[i] = s->band[band].d[i] >> 15; + wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1; + wd3 = (s->band[band].b[i]*32640) >> 15; + s->band[band].bp[i] = saturate(wd2 + wd3); + } + + /* Block 4, DELAYA */ + for (i = 6; i > 0; i--) + { + s->band[band].d[i] = s->band[band].d[i - 1]; + s->band[band].b[i] = s->band[band].bp[i]; + } + + for (i = 2; i > 0; i--) + { + s->band[band].r[i] = s->band[band].r[i - 1]; + s->band[band].p[i] = s->band[band].p[i - 1]; + s->band[band].a[i] = s->band[band].ap[i]; + } + + /* Block 4, FILTEP */ + wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]); + wd1 = (s->band[band].a[1]*wd1) >> 15; + wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]); + wd2 = (s->band[band].a[2]*wd2) >> 15; + s->band[band].sp = saturate(wd1 + wd2); + + /* Block 4, FILTEZ */ + s->band[band].sz = 0; + for (i = 6; i > 0; i--) + { + wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]); + s->band[band].sz += (s->band[band].b[i]*wd1) >> 15; + } + s->band[band].sz = saturate(s->band[band].sz); + + /* Block 4, PREDIC */ + s->band[band].s = saturate(s->band[band].sp + s->band[band].sz); +} +/*- End of function --------------------------------------------------------*/ + +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options) +{ + if (s == NULL) + { + if ((s = (g722_decode_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + memset(s, 0, sizeof(*s)); + if (rate == 48000) + s->bits_per_sample = 6; + else if (rate == 56000) + s->bits_per_sample = 7; + else + s->bits_per_sample = 8; + if ((options & G722_SAMPLE_RATE_8000)) + s->eight_k = TRUE; + if ((options & G722_PACKED) && s->bits_per_sample != 8) + s->packed = TRUE; + else + s->packed = FALSE; + s->band[0].det = 32; + s->band[1].det = 8; + return s; +} +/*- End of function --------------------------------------------------------*/ + +int g722_decode_release(g722_decode_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len) +{ + static const int wl[8] = + { + -60, -30, 58, 172, 334, 538, 1198, 3042 + }; + static const int rl42[16] = + { + 0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 + }; + static const int ilb[32] = + { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, + 2383, 2435, 2489, 2543, 2599, 2656, 2714, + 2774, 2834, 2896, 2960, 3025, 3091, 3158, + 3228, 3298, 3371, 3444, 3520, 3597, 3676, + 3756, 3838, 3922, 4008 + }; + static const int wh[3] = + { + 0, -214, 798 + }; + static const int rh2[4] = + { + 2, 1, 2, 1 + }; + static const int qm2[4] = + { + -7408, -1616, 7408, 1616 + }; + static const int qm4[16] = + { + 0, -20456, -12896, -8968, + -6288, -4240, -2584, -1200, + 20456, 12896, 8968, 6288, + 4240, 2584, 1200, 0 + }; + static const int qm5[32] = + { + -280, -280, -23352, -17560, + -14120, -11664, -9752, -8184, + -6864, -5712, -4696, -3784, + -2960, -2208, -1520, -880, + 23352, 17560, 14120, 11664, + 9752, 8184, 6864, 5712, + 4696, 3784, 2960, 2208, + 1520, 880, 280, -280 + }; + static const int qm6[64] = + { + -136, -136, -136, -136, + -24808, -21904, -19008, -16704, + -14984, -13512, -12280, -11192, + -10232, -9360, -8576, -7856, + -7192, -6576, -6000, -5456, + -4944, -4464, -4008, -3576, + -3168, -2776, -2400, -2032, + -1688, -1360, -1040, -728, + 24808, 21904, 19008, 16704, + 14984, 13512, 12280, 11192, + 10232, 9360, 8576, 7856, + 7192, 6576, 6000, 5456, + 4944, 4464, 4008, 3576, + 3168, 2776, 2400, 2032, + 1688, 1360, 1040, 728, + 432, 136, -432, -136 + }; + static const int qmf_coeffs[12] = + { + 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11, + }; + int dlowt; + int rlow; + int ihigh; + int dhigh; + int rhigh; + int xout1; + int xout2; + int wd1; + int wd2; + int wd3; + int code; + int outlen; + int i; + int j; + + outlen = 0; + rhigh = 0; + for (j = 0; j < len; ) + { + if (s->packed) + { + /* Unpack the code bits */ + if (s->in_bits < s->bits_per_sample) + { + s->in_buffer |= (g722_data[j++] << s->in_bits); + s->in_bits += 8; + } + code = s->in_buffer & ((1 << s->bits_per_sample) - 1); + s->in_buffer >>= s->bits_per_sample; + s->in_bits -= s->bits_per_sample; + } + else + { + code = g722_data[j++]; + } + + switch (s->bits_per_sample) + { + default: + case 8: + wd1 = code & 0x3F; + ihigh = (code >> 6) & 0x03; + wd2 = qm6[wd1]; + wd1 >>= 2; + break; + case 7: + wd1 = code & 0x1F; + ihigh = (code >> 5) & 0x03; + wd2 = qm5[wd1]; + wd1 >>= 1; + break; + case 6: + wd1 = code & 0x0F; + ihigh = (code >> 4) & 0x03; + wd2 = qm4[wd1]; + break; + } + /* Block 5L, LOW BAND INVQBL */ + wd2 = (s->band[0].det*wd2) >> 15; + /* Block 5L, RECONS */ + rlow = s->band[0].s + wd2; + /* Block 6L, LIMIT */ + if (rlow > 16383) + rlow = 16383; + else if (rlow < -16384) + rlow = -16384; + + /* Block 2L, INVQAL */ + wd2 = qm4[wd1]; + dlowt = (s->band[0].det*wd2) >> 15; + + /* Block 3L, LOGSCL */ + wd2 = rl42[wd1]; + wd1 = (s->band[0].nb*127) >> 7; + wd1 += wl[wd2]; + if (wd1 < 0) + wd1 = 0; + else if (wd1 > 18432) + wd1 = 18432; + s->band[0].nb = wd1; + + /* Block 3L, SCALEL */ + wd1 = (s->band[0].nb >> 6) & 31; + wd2 = 8 - (s->band[0].nb >> 11); + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); + s->band[0].det = wd3 << 2; + + block4(s, 0, dlowt); + + if (!s->eight_k) + { + /* Block 2H, INVQAH */ + wd2 = qm2[ihigh]; + dhigh = (s->band[1].det*wd2) >> 15; + /* Block 5H, RECONS */ + rhigh = dhigh + s->band[1].s; + /* Block 6H, LIMIT */ + if (rhigh > 16383) + rhigh = 16383; + else if (rhigh < -16384) + rhigh = -16384; + + /* Block 2H, INVQAH */ + wd2 = rh2[ihigh]; + wd1 = (s->band[1].nb*127) >> 7; + wd1 += wh[wd2]; + if (wd1 < 0) + wd1 = 0; + else if (wd1 > 22528) + wd1 = 22528; + s->band[1].nb = wd1; + + /* Block 3H, SCALEH */ + wd1 = (s->band[1].nb >> 6) & 31; + wd2 = 10 - (s->band[1].nb >> 11); + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); + s->band[1].det = wd3 << 2; + + block4(s, 1, dhigh); + } + + if (s->itu_test_mode) + { + amp[outlen++] = (int16_t) (rlow << 1); + amp[outlen++] = (int16_t) (rhigh << 1); + } + else + { + if (s->eight_k) + { + amp[outlen++] = (int16_t) rlow; + } + else + { + /* Apply the receive QMF */ + memcpy(s->x, &s->x[2], 22*sizeof(s->x[0])); + s->x[22] = rlow + rhigh; + s->x[23] = rlow - rhigh; + + xout1 = 0; + xout2 = 0; + for (i = 0; i < 12; i++) + { + xout2 += s->x[2*i]*qmf_coeffs[i]; + xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i]; + } + amp[outlen++] = (int16_t) (xout1 >> 12); + amp[outlen++] = (int16_t) (xout2 >> 12); + } + } + } + return outlen; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/src/libs/g722/g722_encode.c b/src/libs/g722/g722_encode.c new file mode 100644 index 00000000..f3898192 --- /dev/null +++ b/src/libs/g722/g722_encode.c @@ -0,0 +1,389 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * g722_encode.c - The ITU G.722 codec, encode part. + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, or + * the Lesser GNU General Public License version 2.1, as published by + * the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based on a single channel 64kbps only G.722 codec which is: + * + ***** Copyright (c) CMU 1993 ***** + * Computer Science, Speech Group + * Chengxiang Lu and Alex Hauptmann + * + * $Id: g722_encode.c,v 1.18 2008/02/09 15:32:56 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "g722_inttypes.h" +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#include + +#include "g722_telephony.h" +#include "g722_dc_restore.h" +#include "g722.h" + +static void block4(g722_encode_state_t *s, int band, int d) +{ + int wd1; + int wd2; + int wd3; + int i; + + /* Block 4, RECONS */ + s->band[band].d[0] = d; + s->band[band].r[0] = saturate(s->band[band].s + d); + + /* Block 4, PARREC */ + s->band[band].p[0] = saturate(s->band[band].sz + d); + + /* Block 4, UPPOL2 */ + for (i = 0; i < 3; i++) + s->band[band].sg[i] = s->band[band].p[i] >> 15; + wd1 = saturate(s->band[band].a[1] << 2); + + wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1; + if (wd2 > 32767) + wd2 = 32767; + wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128); + wd3 += (s->band[band].a[2]*32512) >> 15; + if (wd3 > 12288) + wd3 = 12288; + else if (wd3 < -12288) + wd3 = -12288; + s->band[band].ap[2] = wd3; + + /* Block 4, UPPOL1 */ + s->band[band].sg[0] = s->band[band].p[0] >> 15; + s->band[band].sg[1] = s->band[band].p[1] >> 15; + wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192; + wd2 = (s->band[band].a[1]*32640) >> 15; + + s->band[band].ap[1] = saturate(wd1 + wd2); + wd3 = saturate(15360 - s->band[band].ap[2]); + if (s->band[band].ap[1] > wd3) + s->band[band].ap[1] = wd3; + else if (s->band[band].ap[1] < -wd3) + s->band[band].ap[1] = -wd3; + + /* Block 4, UPZERO */ + wd1 = (d == 0) ? 0 : 128; + s->band[band].sg[0] = d >> 15; + for (i = 1; i < 7; i++) + { + s->band[band].sg[i] = s->band[band].d[i] >> 15; + wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1; + wd3 = (s->band[band].b[i]*32640) >> 15; + s->band[band].bp[i] = saturate(wd2 + wd3); + } + + /* Block 4, DELAYA */ + for (i = 6; i > 0; i--) + { + s->band[band].d[i] = s->band[band].d[i - 1]; + s->band[band].b[i] = s->band[band].bp[i]; + } + + for (i = 2; i > 0; i--) + { + s->band[band].r[i] = s->band[band].r[i - 1]; + s->band[band].p[i] = s->band[band].p[i - 1]; + s->band[band].a[i] = s->band[band].ap[i]; + } + + /* Block 4, FILTEP */ + wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]); + wd1 = (s->band[band].a[1]*wd1) >> 15; + wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]); + wd2 = (s->band[band].a[2]*wd2) >> 15; + s->band[band].sp = saturate(wd1 + wd2); + + /* Block 4, FILTEZ */ + s->band[band].sz = 0; + for (i = 6; i > 0; i--) + { + wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]); + s->band[band].sz += (s->band[band].b[i]*wd1) >> 15; + } + s->band[band].sz = saturate(s->band[band].sz); + + /* Block 4, PREDIC */ + s->band[band].s = saturate(s->band[band].sp + s->band[band].sz); +} +/*- End of function --------------------------------------------------------*/ + +g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options) +{ + if (s == NULL) + { + if ((s = (g722_encode_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + memset(s, 0, sizeof(*s)); + if (rate == 48000) + s->bits_per_sample = 6; + else if (rate == 56000) + s->bits_per_sample = 7; + else + s->bits_per_sample = 8; + if ((options & G722_SAMPLE_RATE_8000)) + s->eight_k = TRUE; + if ((options & G722_PACKED) && s->bits_per_sample != 8) + s->packed = TRUE; + else + s->packed = FALSE; + s->band[0].det = 32; + s->band[1].det = 8; + return s; +} +/*- End of function --------------------------------------------------------*/ + +int g722_encode_release(g722_encode_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len) +{ + static const int q6[32] = + { + 0, 35, 72, 110, 150, 190, 233, 276, + 323, 370, 422, 473, 530, 587, 650, 714, + 786, 858, 940, 1023, 1121, 1219, 1339, 1458, + 1612, 1765, 1980, 2195, 2557, 2919, 0, 0 + }; + static const int iln[32] = + { + 0, 63, 62, 31, 30, 29, 28, 27, + 26, 25, 24, 23, 22, 21, 20, 19, + 18, 17, 16, 15, 14, 13, 12, 11, + 10, 9, 8, 7, 6, 5, 4, 0 + }; + static const int ilp[32] = + { + 0, 61, 60, 59, 58, 57, 56, 55, + 54, 53, 52, 51, 50, 49, 48, 47, + 46, 45, 44, 43, 42, 41, 40, 39, + 38, 37, 36, 35, 34, 33, 32, 0 + }; + static const int wl[8] = + { + -60, -30, 58, 172, 334, 538, 1198, 3042 + }; + static const int rl42[16] = + { + 0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 + }; + static const int ilb[32] = + { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, + 2383, 2435, 2489, 2543, 2599, 2656, 2714, + 2774, 2834, 2896, 2960, 3025, 3091, 3158, + 3228, 3298, 3371, 3444, 3520, 3597, 3676, + 3756, 3838, 3922, 4008 + }; + static const int qm4[16] = + { + 0, -20456, -12896, -8968, + -6288, -4240, -2584, -1200, + 20456, 12896, 8968, 6288, + 4240, 2584, 1200, 0 + }; + static const int qm2[4] = + { + -7408, -1616, 7408, 1616 + }; + static const int qmf_coeffs[12] = + { + 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11, + }; + static const int ihn[3] = {0, 1, 0}; + static const int ihp[3] = {0, 3, 2}; + static const int wh[3] = {0, -214, 798}; + static const int rh2[4] = {2, 1, 2, 1}; + + int dlow; + int dhigh; + int el; + int wd; + int wd1; + int ril; + int wd2; + int il4; + int ih2; + int wd3; + int eh; + int mih; + int i; + int j; + /* Low and high band PCM from the QMF */ + int xlow; + int xhigh; + int g722_bytes; + /* Even and odd tap accumulators */ + int sumeven; + int sumodd; + int ihigh; + int ilow; + int code; + + g722_bytes = 0; + xhigh = 0; + for (j = 0; j < len; ) + { + if (s->itu_test_mode) + { + xlow = + xhigh = amp[j++] >> 1; + } + else + { + if (s->eight_k) + { + xlow = amp[j++]; + } + else + { + /* Apply the transmit QMF */ + /* Shuffle the buffer down */ + memcpy(s->x, &s->x[2], 22*sizeof(s->x[0])); + s->x[22] = amp[j++]; + s->x[23] = amp[j++]; + + /* Discard every other QMF output */ + sumeven = 0; + sumodd = 0; + for (i = 0; i < 12; i++) + { + sumodd += s->x[2*i]*qmf_coeffs[i]; + sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i]; + } + xlow = (sumeven + sumodd) >> 13; + xhigh = (sumeven - sumodd) >> 13; + } + } + /* Block 1L, SUBTRA */ + el = saturate(xlow - s->band[0].s); + + /* Block 1L, QUANTL */ + wd = (el >= 0) ? el : -(el + 1); + + for (i = 1; i < 30; i++) + { + wd1 = (q6[i]*s->band[0].det) >> 12; + if (wd < wd1) + break; + } + ilow = (el < 0) ? iln[i] : ilp[i]; + + /* Block 2L, INVQAL */ + ril = ilow >> 2; + wd2 = qm4[ril]; + dlow = (s->band[0].det*wd2) >> 15; + + /* Block 3L, LOGSCL */ + il4 = rl42[ril]; + wd = (s->band[0].nb*127) >> 7; + s->band[0].nb = wd + wl[il4]; + if (s->band[0].nb < 0) + s->band[0].nb = 0; + else if (s->band[0].nb > 18432) + s->band[0].nb = 18432; + + /* Block 3L, SCALEL */ + wd1 = (s->band[0].nb >> 6) & 31; + wd2 = 8 - (s->band[0].nb >> 11); + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); + s->band[0].det = wd3 << 2; + + block4(s, 0, dlow); + + if (s->eight_k) + { + /* Just leave the high bits as zero */ + code = (0xC0 | ilow) >> (8 - s->bits_per_sample); + } + else + { + /* Block 1H, SUBTRA */ + eh = saturate(xhigh - s->band[1].s); + + /* Block 1H, QUANTH */ + wd = (eh >= 0) ? eh : -(eh + 1); + wd1 = (564*s->band[1].det) >> 12; + mih = (wd >= wd1) ? 2 : 1; + ihigh = (eh < 0) ? ihn[mih] : ihp[mih]; + + /* Block 2H, INVQAH */ + wd2 = qm2[ihigh]; + dhigh = (s->band[1].det*wd2) >> 15; + + /* Block 3H, LOGSCH */ + ih2 = rh2[ihigh]; + wd = (s->band[1].nb*127) >> 7; + s->band[1].nb = wd + wh[ih2]; + if (s->band[1].nb < 0) + s->band[1].nb = 0; + else if (s->band[1].nb > 22528) + s->band[1].nb = 22528; + + /* Block 3H, SCALEH */ + wd1 = (s->band[1].nb >> 6) & 31; + wd2 = 10 - (s->band[1].nb >> 11); + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); + s->band[1].det = wd3 << 2; + + block4(s, 1, dhigh); + code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample); + } + + if (s->packed) + { + /* Pack the code bits */ + s->out_buffer |= (code << s->out_bits); + s->out_bits += s->bits_per_sample; + if (s->out_bits >= 8) + { + g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF); + s->out_bits -= 8; + s->out_buffer >>= 8; + } + } + else + { + g722_data[g722_bytes++] = (uint8_t) code; + } + } + return g722_bytes; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/src/libs/g722/g722_inttypes.h b/src/libs/g722/g722_inttypes.h new file mode 100644 index 00000000..28856ee7 --- /dev/null +++ b/src/libs/g722/g722_inttypes.h @@ -0,0 +1,103 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * inttypes.h - a fudge for MSVC, which lacks this header + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Michael Jerris + * + * + * This file is released in the public domain. + * + */ + +#if !defined(_INTTYPES_H_) +#define _INTTYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER + #if (_MSC_VER >= 1400) // VC8+ + #ifndef _CRT_SECURE_NO_DEPRECATE + #define _CRT_SECURE_NO_DEPRECATE + #endif + #ifndef _CRT_NONSTDC_NO_DEPRECATE + #define _CRT_NONSTDC_NO_DEPRECATE + #endif + #endif // VC8+ + + #include + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + #define inline __inline + #define __inline__ __inline + #define INT16_MAX 0x7fff + #define INT16_MIN (-INT16_MAX - 1) + #define _MMX_H_ + + /* disable the following warnings + * C4100: The formal parameter is not referenced in the body of the function. The unreferenced parameter is ignored. + * C4200: Non standard extension C zero sized array + * C4706: assignment within conditional expression + * C4244: conversion from 'type1' to 'type2', possible loss of data + * C4295: array is too small to include a terminating null character + * C4125: decimal digit terminates octal escape sequence + */ + #pragma warning(disable:4100 4200 4706 4295 4125) + + //#pragma comment(lib, "ws2_32.lib") + + #define strncasecmp _strnicmp + #define strcasecmp _stricmp + #define snprintf _snprintf + + #if !defined(INFINITY) + #define INFINITY 0x7fffffff + #endif +#else + #include +#endif + +#define PACKAGE "voipcodecs" +#define VERSION "0.0.1andabit" + +#ifndef INT32_MAX + #define INT32_MAX (2147483647) +#endif +#ifndef INT32_MIN + #define INT32_MIN (-2147483647 - 1) +#endif + +#define PRId8 "d" +#define PRId16 "d" +#ifndef PRId32 +# define PRId32 "ld" +#endif + +#ifndef PRId64 +# define PRId64 "lld" +#endif + +#define PRIu8 "u" +#define PRIu16 "u" +#ifndef PRIu32 +# define PRIu32 "lu" +#endif +#ifndef PRIu64 +# define PRIu64 "llu" +#endif +#ifdef __cplusplus +} +#endif + +#endif // _INTTYPES_H_ + diff --git a/src/libs/g722/g722_telephony.h b/src/libs/g722/g722_telephony.h new file mode 100644 index 00000000..53c92fd2 --- /dev/null +++ b/src/libs/g722/g722_telephony.h @@ -0,0 +1,74 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * telephony.h - some very basic telephony definitions + * + * Written by Steve Underwood + * + * Copyright (C) 2003 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: telephony.h,v 1.10 2007/04/05 19:20:50 steveu Exp $ + */ + +#if !defined(_SPANDSP_TELEPHONY_H_) +#define _SPANDSP_TELEPHONY_H_ + +#define SAMPLE_RATE 8000 + +/* This is based on A-law, but u-law is only 0.03dB different */ +#define DBM0_MAX_POWER (3.14f + 3.02f) +#define DBM0_MAX_SINE_POWER (3.14f) +/* This is based on the ITU definition of dbOv in G.100.1 */ +#define DBOV_MAX_POWER (0.0f) +#define DBOV_MAX_SINE_POWER (-3.02f) + +/*! \brief A handler for pure receive. The buffer cannot be altered. */ +typedef int (span_rx_handler_t)(void *s, const int16_t amp[], int len); + +/*! \brief A handler for receive, where the buffer can be altered. */ +typedef int (span_mod_handler_t)(void *s, int16_t amp[], int len); + +/*! \brief A handler for transmit, where the buffer will be filled. */ +typedef int (span_tx_handler_t)(void *s, int16_t amp[], int max_len); + +#define ms_to_samples(t) (((t)*SAMPLE_RATE)/1000) + +#if !defined(FALSE) +#define FALSE 0 +#endif +#if !defined(TRUE) +#define TRUE (!FALSE) +#endif + +#include +#if (_MSC_VER >= 1400) // VC8+ +#define vc_assert(expr) assert(expr);__analysis_assume( expr ) +#else +#define vc_assert(expr) assert(expr) +#endif + +#if defined(__cplusplus) +/* C++ doesn't seem to have sane rounding functions/macros yet */ +#ifndef _MSC_VER +#define lrint(x) ((long int) (x)) +#define lrintf(x) ((long int) (x)) +#endif +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/src/libs/g722/g722codec.c b/src/libs/g722/g722codec.c new file mode 100644 index 00000000..6ec50dd5 --- /dev/null +++ b/src/libs/g722/g722codec.c @@ -0,0 +1,300 @@ +/* + * G.722 Plugin codec for OpenH323/OPAL + * + * Copyright (C) 2008 by Hermon Labs, All Rights Reserved + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Open Phone Abstraction Library. + * + * The Initial Developer of the Original Code is Eugene Mednikov + * + * Contributor(s): ______________________________________. + * + * $Revision: 23265 $ + * $Author: rjongbloed $ + * $Date: 2009-08-25 04:25:58 +0300 (вт, 25 серп 2009) $ + */ + +#ifndef PLUGIN_CODEC_DLL_EXPORTS +#include "plugin-config.h" +#endif + +#include + +#include "VoIPCodecs/inttypes.h" +#include "VoIPCodecs/g722.h" + + +#define INCLUDE_SDP_16000_VERSION 0 + +/* Due to a spec error, clock rate is 8kHz even though this is 16kHz codec, + see RFC3551/4.5.2. So some of these values have to be lied about so that + the OPAL system gets it right. + */ +#define CLOCK_RATE 8000 // Clock rate is not samples/second in this case! +#define BITS_PER_SECOND 64000 // raw bits per second +#define FRAME_TIME 1000 // Microseconds in a millisecond +#define SAMPLES_PER_FRAME 16 // Samples in a millisecond +#define BYTES_PER_FRAME 8 // Bytes in a millisecond +#define MAX_FRAMES_PER_PACKET 90 // 90 milliseconds, which means RTP packets smaller than 1500 bytes typical LAN maximum +#define PREF_FRAMES_PER_PACKET 20 // 20 milliseconds + +static const char L16Desc[] = "PCM-16-16kHz"; // Cannot use "L16" as usual, force 16kHz PCM +static const char g722[] = "G.722-64k"; +static const char sdpG722[] = "G722"; + +#if INCLUDE_SDP_16000_VERSION +static const char g722_16[] = "G.722-16kHz"; +#endif + +#define PAYLOAD_CODE 9 + + +///////////////////////////////////////////////////////////////////////////// + +static void * create_encoder(const struct PluginCodec_Definition * codec) +{ + return g722_encode_init(NULL, BITS_PER_SECOND, 0); +} + +static void destroy_encoder(const struct PluginCodec_Definition * codec, void * context) +{ + g722_encode_release(context); +} + +static int encode(const struct PluginCodec_Definition * codec, + void * context, + const void * from, + unsigned * fromLen, + void * to, + unsigned * toLen, + unsigned int * flag) +{ + g722_encode_state_t * state = context; + + if (*toLen < *fromLen / 4) + return 0; // Destination buffer not big enough + + *toLen = g722_encode(state, to, from, *fromLen / 2); + return 1; +} + + +///////////////////////////////////////////////////////////////////////////// + +static void * create_decoder(const struct PluginCodec_Definition * codec) +{ + return g722_decode_init(NULL, BITS_PER_SECOND, 0); +} + +static void destroy_decoder(const struct PluginCodec_Definition * codec, void * context) +{ + g722_decode_release(context); +} + + +static int decode(const struct PluginCodec_Definition * codec, + void * _context, + const void * from, + unsigned * fromLen, + void * to, + unsigned * toLen, + unsigned int * flag) +{ + g722_decode_state_t * state = _context; + + if (*toLen < *fromLen * 4) + return 0; // Destination buffer not big enough + + *toLen = g722_decode(state, to, from, *fromLen) * 2; + return 1; +} + + +///////////////////////////////////////////////////////////////////////////// + +static struct PluginCodec_information licenseInfo = { + 1084181196, // timestamp = Mon 10 May 2004 09:26:36 AM UTC + + "Eugene Mednikov", // source code author + "1.0", // source code version + "em@hermonlabs.com", // source code email + "http://www.hermonlabs.com", // source code URL + "Copyright (C) 2008 by Hermon Labs, All Rights Reserved", // source code copyright + "MPL 1.0", // source code license + PluginCodec_License_MPL, // source code license + + "ITU G.722", // codec description + "Steve Underwood", // codec author + NULL, // codec version + "steveu@coppice.org", // codec email + NULL, // codec URL + NULL, // codec copyright information + NULL, // codec license + PluginCodec_License_LGPL // codec license code +}; + +///////////////////////////////////////////////////////////////////////////// + +static struct PluginCodec_Definition g722CodecDefn[] = +{ +#if INCLUDE_SDP_16000_VERSION + // Include a version for SIP/SDP that indicates the more logical, though + // incorrect by RFC3551/4.5.2, 16000Hz version of G.722. We use dynamic + // payload types to avoid conflict with the compliant 8000Hz version. + { + // encoder + PLUGIN_CODEC_VERSION_WIDEBAND, // codec API version + &licenseInfo, // license information + + PluginCodec_MediaTypeAudio | // audio codec + PluginCodec_InputTypeRaw | // raw input data + PluginCodec_OutputTypeRaw | // raw output data + PluginCodec_RTPTypeDynamic, // specified RTP type + + g722_16, // text decription + L16Desc, // source format + g722_16, // destination format + + 0, // user data + + 16000, // samples per second + BITS_PER_SECOND, // raw bits per second + FRAME_TIME, // microseconds per frame + SAMPLES_PER_FRAME, // samples per frame + BYTES_PER_FRAME, // bytes per frame + PREF_FRAMES_PER_PACKET, // recommended number of frames per packet + MAX_FRAMES_PER_PACKET, // maximum number of frames per packe + PAYLOAD_CODE, // IANA RTP payload code + sdpG722, // RTP payload name + + create_encoder, // create codec function + destroy_encoder, // destroy codec + encode, // encode/decode + NULL, // codec controls + + 0, // h323CapabilityType + NULL // h323CapabilityData + }, + + { + // decoder + PLUGIN_CODEC_VERSION_WIDEBAND, // codec API version + &licenseInfo, // license information + + PluginCodec_MediaTypeAudio | // audio codec + PluginCodec_InputTypeRaw | // raw input data + PluginCodec_OutputTypeRaw | // raw output data + PluginCodec_RTPTypeDynamic, // specified RTP type + + g722_16, // text decription + g722_16, // source format + L16Desc, // destination format + + 0, // user data + + 16000, // samples per second + BITS_PER_SECOND, // raw bits per second + FRAME_TIME, // microseconds per frame + SAMPLES_PER_FRAME, // samples per frame + BYTES_PER_FRAME, // bytes per frame + PREF_FRAMES_PER_PACKET, // recommended number of frames per packet + MAX_FRAMES_PER_PACKET, // maximum number of frames per packe + PAYLOAD_CODE, // IANA RTP payload code + sdpG722, // RTP payload name + + create_decoder, // create codec function + destroy_decoder, // destroy codec + decode, // encode/decode + NULL, // codec controls + + 0, // h323CapabilityType + NULL // h323CapabilityData + }, +#endif + + // Standards compliant version + { + // encoder + PLUGIN_CODEC_VERSION_WIDEBAND, // codec API version + &licenseInfo, // license information + + PluginCodec_MediaTypeAudio | // audio codec + PluginCodec_InputTypeRaw | // raw input data + PluginCodec_OutputTypeRaw | // raw output data + PluginCodec_RTPTypeExplicit, // specified RTP type + + g722, // text decription + L16Desc, // source format + g722, // destination format + + 0, // user data + + CLOCK_RATE, // samples per second + BITS_PER_SECOND, // raw bits per second + FRAME_TIME, // microseconds per frame + SAMPLES_PER_FRAME, // samples per frame + BYTES_PER_FRAME, // bytes per frame + PREF_FRAMES_PER_PACKET, // recommended number of frames per packet + MAX_FRAMES_PER_PACKET, // maximum number of frames per packe + PAYLOAD_CODE, // IANA RTP payload code + sdpG722, // RTP payload name + + create_encoder, // create codec function + destroy_encoder, // destroy codec + encode, // encode/decode + NULL, // codec controls + + PluginCodec_H323AudioCodec_g722_64k, // h323CapabilityType + NULL // h323CapabilityData + }, + + { + // decoder + PLUGIN_CODEC_VERSION_WIDEBAND, // codec API version + &licenseInfo, // license information + + PluginCodec_MediaTypeAudio | // audio codec + PluginCodec_InputTypeRaw | // raw input data + PluginCodec_OutputTypeRaw | // raw output data + PluginCodec_RTPTypeExplicit, // specified RTP type + + g722, // text decription + g722, // source format + L16Desc, // destination format + + 0, // user data + + CLOCK_RATE, // samples per second + BITS_PER_SECOND, // raw bits per second + FRAME_TIME, // microseconds per frame + SAMPLES_PER_FRAME, // samples per frame + BYTES_PER_FRAME, // bytes per frame + PREF_FRAMES_PER_PACKET, // recommended number of frames per packet + MAX_FRAMES_PER_PACKET, // maximum number of frames per packe + PAYLOAD_CODE, // IANA RTP payload code + sdpG722, // RTP payload name + + create_decoder, // create codec function + destroy_decoder, // destroy codec + decode, // encode/decode + NULL, // codec controls + + PluginCodec_H323AudioCodec_g722_64k, // h323CapabilityType + NULL // h323CapabilityData + } +}; + + +PLUGIN_CODEC_IMPLEMENT_ALL(G722, g722CodecDefn, PLUGIN_CODEC_VERSION_WIDEBAND) + +///////////////////////////////////////////////////////////////////////////// diff --git a/src/libs/gsmhr/CMakeLists.txt b/src/libs/gsmhr/CMakeLists.txt new file mode 100644 index 00000000..55841130 --- /dev/null +++ b/src/libs/gsmhr/CMakeLists.txt @@ -0,0 +1,12 @@ +project (gsmhr_codec) + +# Rely on C++ 11 +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +set (GSMHR_SOURCES + gsmhr.cpp + gsmhr_sp_rom.c +) + +add_library(gsmhr_codec ${GSMHR_SOURCES}) diff --git a/src/libs/gsmhr/gsmhr.cpp b/src/libs/gsmhr/gsmhr.cpp new file mode 100644 index 00000000..23236a5d --- /dev/null +++ b/src/libs/gsmhr/gsmhr.cpp @@ -0,0 +1,15726 @@ +#include "gsmhr.h" + +namespace GsmHr { + +/*************************************************************************** + * + * File Name: mathdp31.c + * + * Purpose: Contains functions increased-precision arithmetic operations. + * + * Below is a listing of all the functions in this file. There + * is no interdependence among the functions. + * + * L_mpy_ls() + * L_mpy_ll() + * isLwLimit() + * isSwLimit() + * + ***************************************************************************/ +/*_________________________________________________________________________ + | | + | Include Files | + |_________________________________________________________________________| +*/ + + +/**************************************************************************** + * + * FUNCTION NAME: isLwLimit + * + * PURPOSE: + * + * Check to see if the input int32_t is at the + * upper or lower limit of its range. i.e. + * 0x7fff ffff or -0x8000 0000 + * + * Ostensibly this is a check for an overflow. + * This does not truly mean an overflow occurred, + * it means the value reached is the + * maximum/minimum value representable. It may + * have come about due to an overflow. + * + * INPUTS: + * + * L_In A int32_t input variable + * + * + * OUTPUTS: none + * + * RETURN VALUE: 1 if input == 0x7fff ffff or -0x8000 0000 + * 0 otherwise + * + * KEYWORDS: saturation, limit + * + ***************************************************************************/ + +short isLwLimit(int32_t L_In) +{ + + int32_t L_ls; + short siOut; + + if (L_In != 0) + { + L_ls = L_shl(L_In, 1); + if (L_sub(L_In, L_ls) == 0) + siOut = 1; + else + siOut = 0; + } + else + { + siOut = 0; + } + return (siOut); +} + +/**************************************************************************** + * + * FUNCTION NAME: isSwLimit + * + * PURPOSE: + * + * Check to see if the input int16_t is at the + * upper or lower limit of its range. i.e. + * 0x7fff or -0x8000 + * + * Ostensibly this is a check for an overflow. + * This does not truly mean an overflow occurred, + * it means the value reached is the + * maximum/minimum value representable. It may + * have come about due to an overflow. + * + * INPUTS: + * + * swIn A int16_t input variable + * + * + * OUTPUTS: none + * + * RETURN VALUE: 1 if input == 0x7fff or -0x8000 + * 0 otherwise + * + * KEYWORDS: saturation, limit + * + ***************************************************************************/ + +short isSwLimit(int16_t swIn) +{ + + int16_t swls; + short siOut; + + if (swIn != 0) + { + swls = shl(swIn, 1); + if (sub(swIn, swls) == 0) /* logical compare outputs 1/0 */ + siOut = 1; + else + siOut = 0; + } + else + { + siOut = 0; + } + return (siOut); + +} + +/**************************************************************************** + * + * FUNCTION NAME: L_mpy_ll + * + * PURPOSE: Multiply a 32 bit number (L_var1) and a 32 bit number + * (L_var2), and return a 32 bit result. + * + * INPUTS: + * + * L_var1 A int32_t input variable + * + * L_var2 A int32_t input variable + * + * OUTPUTS: none + * + * IMPLEMENTATION: + * + * Performs a 31x31 bit multiply, Complexity=24 Ops. + * + * Let x1x0, or y1y0, be the two constituent halves + * of a 32 bit number. This function performs the + * following: + * + * low = ((x0 >> 1)*(y0 >> 1)) >> 16 (low * low) + * mid1 = [(x1 * (y0 >> 1)) >> 1 ] (high * low) + * mid2 = [(y1 * (x0 >> 1)) >> 1] (high * low) + * mid = (mid1 + low + mid2) >> 14 (sum so far) + * output = (y1*x1) + mid (high * high) + * + * + * RETURN VALUE: A int32_t value + * + * KEYWORDS: mult,mpy,multiplication + * + ***************************************************************************/ + +int32_t L_mpy_ll(int32_t L_var1, int32_t L_var2) +{ + int16_t swLow1, + swLow2, + swHigh1, + swHigh2; + int32_t L_varOut, + L_low, + L_mid1, + L_mid2, + L_mid; + + + swLow1 = shr(extract_l(L_var1), 1); + swLow1 = SW_MAX & swLow1; + + swLow2 = shr(extract_l(L_var2), 1); + swLow2 = SW_MAX & swLow2; + swHigh1 = extract_h(L_var1); + swHigh2 = extract_h(L_var2); + + L_low = L_mult(swLow1, swLow2); + L_low = L_shr(L_low, 16); + + L_mid1 = L_mult(swHigh1, swLow2); + L_mid1 = L_shr(L_mid1, 1); + L_mid = L_add(L_mid1, L_low); + + L_mid2 = L_mult(swHigh2, swLow1); + L_mid2 = L_shr(L_mid2, 1); + L_mid = L_add(L_mid, L_mid2); + + L_mid = L_shr(L_mid, 14); + L_varOut = L_mac(L_mid, swHigh1, swHigh2); + + return (L_varOut); +} + +/**************************************************************************** + * + * FUNCTION NAME: L_mpy_ls + * + * PURPOSE: Multiply a 32 bit number (L_var2) and a 16 bit + * number (var1) returning a 32 bit result. L_var2 + * is truncated to 31 bits prior to executing the + * multiply. + * + * INPUTS: + * + * L_var2 A int32_t input variable + * + * var1 A int16_t input variable + * + * OUTPUTS: none + * + * RETURN VALUE: A int32_t value + * + * KEYWORDS: mult,mpy,multiplication + * + ***************************************************************************/ + +int32_t L_mpy_ls(int32_t L_var2, int16_t var1) +{ + int32_t L_varOut; + int16_t swtemp; + + swtemp = shr(extract_l(L_var2), 1); + swtemp = (short) 32767 & (short) swtemp; + + L_varOut = L_mult(var1, swtemp); + L_varOut = L_shr(L_varOut, 15); + L_varOut = L_mac(L_varOut, var1, extract_h(L_var2)); + return (L_varOut); +} + +// From mathhalf.c + +/*************************************************************************** + * + * FUNCTION NAME: saturate + * + * PURPOSE: + * + * Limit the 32 bit input to the range of a 16 bit word. + * + * + * INPUTS: + * + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * KEYWORDS: saturation, limiting, limit, saturate, 16 bits + * + *************************************************************************/ + +static int16_t saturate(int32_t L_var1) +{ + int16_t swOut; + + if (L_var1 > SW_MAX) + { + swOut = SW_MAX; + } + else if (L_var1 < SW_MIN) + { + swOut = SW_MIN; + } + else + swOut = (int16_t) L_var1; /* automatic type conversion */ + return (swOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: abs_s + * + * PURPOSE: + * + * Take the absolute value of the 16 bit input. An input of + * -0x8000 results in a return value of 0x7fff. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0x0000 0000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * Take the absolute value of the 16 bit input. An input of + * -0x8000 results in a return value of 0x7fff. + * + * KEYWORDS: absolute value, abs + * + *************************************************************************/ + +int16_t abs_s(int16_t var1) +{ + int16_t swOut; + + if (var1 == SW_MIN) + { + swOut = SW_MAX; + } + else + { + if (var1 < 0) + swOut = -var1; + else + swOut = var1; + } + return (swOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: add + * + * PURPOSE: + * + * Perform the addition of the two 16 bit input variable with + * saturation. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * Perform the addition of the two 16 bit input variable with + * saturation. + * + * swOut = var1 + var2 + * + * swOut is set to 0x7fff if the operation results in an + * overflow. swOut is set to 0x8000 if the operation results + * in an underflow. + * + * KEYWORDS: add, addition + * + *************************************************************************/ + +int16_t add(int16_t var1, int16_t var2) +{ + int32_t L_sum; + int16_t swOut; + + L_sum = (int32_t) var1 + var2; + swOut = saturate(L_sum); + return (swOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: divide_s + * + * PURPOSE: + * + * Divide var1 by var2. Note that both must be positive, and + * var1 >= var2. The output is set to 0 if invalid input is + * provided. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * In the case where var1==var2 the function returns 0x7fff. The output + * is undefined for invalid inputs. This implementation returns zero + * and issues a warning via stdio if invalid input is presented. + * + * KEYWORDS: divide + * + *************************************************************************/ + +int16_t divide_s(int16_t var1, int16_t var2) +{ + int32_t L_div; + int16_t swOut; + + if (var1 < 0 || var2 < 0 || var1 > var2) + { + /* undefined output for invalid input into divide_s */ + return (0); + } + + if (var1 == var2) + return (0x7fff); + + L_div = ((0x00008000L * (int32_t) var1) / (int32_t) var2); + swOut = saturate(L_div); + return (swOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: extract_h + * + * PURPOSE: + * + * Extract the 16 MS bits of a 32 bit int32_t. Return the 16 bit + * number as a int16_t. This is used as a "truncation" of a fractional + * number. + * + * INPUTS: + * + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * KEYWORDS: assign, truncate + * + *************************************************************************/ + +int16_t extract_h(int32_t L_var1) +{ + int16_t var2; + + var2 = (int16_t) (0x0000ffffL & (L_var1 >> 16)); + return (var2); +} + +/*************************************************************************** + * + * FUNCTION NAME: extract_l + * + * PURPOSE: + * + * Extract the 16 LS bits of a 32 bit int32_t. Return the 16 bit + * number as a int16_t. The upper portion of the input int32_t + * has no impact whatsoever on the output. + * + * INPUTS: + * + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * + * KEYWORDS: extract, assign + * + *************************************************************************/ + +int16_t extract_l(int32_t L_var1) +{ + int16_t var2; + + var2 = (int16_t) (0x0000ffffL & L_var1); + return (var2); +} + +/*************************************************************************** + * + * FUNCTION NAME: L_abs + * + * PURPOSE: + * + * Take the absolute value of the 32 bit input. An input of + * -0x8000 0000 results in a return value of 0x7fff ffff. + * + * INPUTS: + * + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * + * + * KEYWORDS: absolute value, abs + * + *************************************************************************/ +int32_t L_abs(int32_t L_var1) +{ + int32_t L_Out; + + if (L_var1 == LW_MIN) + { + L_Out = LW_MAX; + } + else + { + if (L_var1 < 0) + L_Out = -L_var1; + else + L_Out = L_var1; + } + return (L_Out); +} + +/*************************************************************************** + * + * FUNCTION NAME: L_add + * + * PURPOSE: + * + * Perform the addition of the two 32 bit input variables with + * saturation. + * + * INPUTS: + * + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * L_var2 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var2 <= 0x7fff ffff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * IMPLEMENTATION: + * + * Perform the addition of the two 32 bit input variables with + * saturation. + * + * L_Out = L_var1 + L_var2 + * + * L_Out is set to 0x7fff ffff if the operation results in an + * overflow. L_Out is set to 0x8000 0000 if the operation + * results in an underflow. + * + * KEYWORDS: add, addition + * + *************************************************************************/ +int32_t L_add(int32_t L_var1, int32_t L_var2) +{ + + int32_t L_Sum, + L_SumLow, + L_SumHigh; + + L_Sum = L_var1 + L_var2; + + if ((L_var1 > 0 && L_var2 > 0) || (L_var1 < 0 && L_var2 < 0)) + { + + /* an overflow is possible */ + + L_SumLow = (L_var1 & 0xffff) + (L_var2 & 0xffff); + L_SumHigh = ((L_var1 >> 16) & 0xffff) + ((L_var2 >> 16) & 0xffff); + if (L_SumLow & 0x10000) + { + /* carry into high word is set */ + L_SumHigh += 1; + } + + /* update sum only if there is an overflow or underflow */ + /*------------------------------------------------------*/ + + if ((0x10000 & L_SumHigh) && !(0x8000 & L_SumHigh)) + L_Sum = LW_MIN; /* underflow */ + else if (!(0x10000 & L_SumHigh) && (0x8000 & L_SumHigh)) + L_Sum = LW_MAX; /* overflow */ + } + + return (L_Sum); + +} + +/*************************************************************************** + * + * FUNCTION NAME: L_deposit_h + * + * PURPOSE: + * + * Put the 16 bit input into the 16 MSB's of the output int32_t. The + * LS 16 bits are zeroed. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff 0000. + * + * + * KEYWORDS: deposit, assign, fractional assign + * + *************************************************************************/ + +int32_t L_deposit_h(int16_t var1) +{ + int32_t L_var2; + + L_var2 = (int32_t) var1 << 16; + return (L_var2); +} + +/*************************************************************************** + * + * FUNCTION NAME: L_deposit_l + * + * PURPOSE: + * + * Put the 16 bit input into the 16 LSB's of the output int32_t with + * sign extension i.e. the top 16 bits are set to either 0 or 0xffff. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0xffff 8000 <= L_var1 <= 0x0000 7fff. + * + * KEYWORDS: deposit, assign + * + *************************************************************************/ + +int32_t L_deposit_l(int16_t var1) +{ + int32_t L_Out; + + L_Out = var1; + return (L_Out); +} + +/*************************************************************************** + * + * FUNCTION NAME: L_mac + * + * PURPOSE: + * + * Multiply accumulate. Fractionally multiply two 16 bit + * numbers together with saturation. Add that result to the + * 32 bit input with saturation. Return the 32 bit result. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * L_var3 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var2 <= 0x7fff ffff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * IMPLEMENTATION: + * + * Fractionally multiply two 16 bit numbers together with + * saturation. The only numbers which will cause saturation on + * the multiply are 0x8000 * 0x8000. + * + * Add that result to the 32 bit input with saturation. + * Return the 32 bit result. + * + * Please note that this is not a true multiply accumulate as + * most processors would implement it. The 0x8000*0x8000 + * causes and overflow for this instruction. On most + * processors this would cause an overflow only if the 32 bit + * input added to it were positive or zero. + * + * KEYWORDS: mac, multiply accumulate + * + *************************************************************************/ + +int32_t L_mac(int32_t L_var3, int16_t var1, int16_t var2) +{ + return (L_add(L_var3, L_mult(var1, var2))); +} + +/*************************************************************************** + * + * FUNCTION NAME: L_msu + * + * PURPOSE: + * + * Multiply and subtract. Fractionally multiply two 16 bit + * numbers together with saturation. Subtract that result from + * the 32 bit input with saturation. Return the 32 bit result. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * L_var3 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var2 <= 0x7fff ffff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * IMPLEMENTATION: + * + * Fractionally multiply two 16 bit numbers together with + * saturation. The only numbers which will cause saturation on + * the multiply are 0x8000 * 0x8000. + * + * Subtract that result from the 32 bit input with saturation. + * Return the 32 bit result. + * + * Please note that this is not a true multiply accumulate as + * most processors would implement it. The 0x8000*0x8000 + * causes and overflow for this instruction. On most + * processors this would cause an overflow only if the 32 bit + * input added to it were negative or zero. + * + * KEYWORDS: mac, multiply accumulate, msu + * + *************************************************************************/ + +int32_t L_msu(int32_t L_var3, int16_t var1, int16_t var2) +{ + return (L_sub(L_var3, L_mult(var1, var2))); +} + +/*************************************************************************** + * + * FUNCTION NAME: L_mult + * + * PURPOSE: + * + * Perform a fractional multipy of the two 16 bit input numbers + * with saturation. Output a 32 bit number. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * IMPLEMENTATION: + * + * Multiply the two the two 16 bit input numbers. If the + * result is within this range, left shift the result by one + * and output the 32 bit number. The only possible overflow + * occurs when var1==var2==-0x8000. In this case output + * 0x7fff ffff. + * + * KEYWORDS: multiply, mult, mpy + * + *************************************************************************/ + +int32_t L_mult(int16_t var1, int16_t var2) +{ + int32_t L_product; + + if (var1 == SW_MIN && var2 == SW_MIN) + L_product = LW_MAX; /* overflow */ + else + { + L_product = (int32_t) var1 *var2; /* integer multiply */ + + L_product = L_product << 1; + } + return (L_product); +} + +/*************************************************************************** + * + * FUNCTION NAME: L_negate + * + * PURPOSE: + * + * Negate the 32 bit input. 0x8000 0000's negated value is + * 0x7fff ffff. + * + * INPUTS: + * + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0001 <= L_var1 <= 0x7fff ffff. + * + * KEYWORDS: negate, negative + * + *************************************************************************/ + +int32_t L_negate(int32_t L_var1) +{ + int32_t L_Out; + + if (L_var1 == LW_MIN) + L_Out = LW_MAX; + else + L_Out = -L_var1; + return (L_Out); +} + +/*************************************************************************** + * + * FUNCTION NAME: L_shift_r + * + * PURPOSE: + * + * Shift and round. Perform a shift right. After shifting, use + * the last bit shifted out of the LSB to round the result up + * or down. + * + * INPUTS: + * + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * + * IMPLEMENTATION: + * + * Shift and round. Perform a shift right. After shifting, use + * the last bit shifted out of the LSB to round the result up + * or down. This is just like shift_r above except that the + * input/output is 32 bits as opposed to 16. + * + * if var2 is positve perform a arithmetic left shift + * with saturation (see L_shl() above). + * + * If var2 is zero simply return L_var1. + * + * If var2 is negative perform a arithmetic right shift (L_shr) + * of L_var1 by (-var2)+1. Add the LS bit of the result to + * L_var1 shifted right (L_shr) by -var2. + * + * Note that there is no constraint on var2, so if var2 is + * -0xffff 8000 then -var2 is 0x0000 8000, not 0x0000 7fff. + * This is the reason the L_shl function is used. + * + * + * KEYWORDS: + * + *************************************************************************/ + +int32_t L_shift_r(int32_t L_var1, int16_t var2) +{ + int32_t L_Out, + L_rnd; + + if (var2 < -31) + { + L_Out = 0; + } + else if (var2 < 0) + { + /* right shift */ + L_rnd = L_shl(L_var1, var2 + 1) & 0x1; + L_Out = L_add(L_shl(L_var1, var2), L_rnd); + } + else + L_Out = L_shl(L_var1, var2); + + return (L_Out); +} + +/*************************************************************************** + * + * FUNCTION NAME: L_shl + * + * PURPOSE: + * + * Arithmetic shift left (or right). + * Arithmetically shift the input left by var2. If var2 is + * negative then an arithmetic shift right (L_shr) of L_var1 by + * -var2 is performed. + * + * INPUTS: + * + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * + * IMPLEMENTATION: + * + * Arithmetically shift the 32 bit input left by var2. This + * operation maintains the sign of the input number. If var2 is + * negative then an arithmetic shift right (L_shr) of L_var1 by + * -var2 is performed. See description of L_shr for details. + * + * Equivalent to the Full-Rate GSM ">> n" operation. Note that + * ANSI-C does not guarantee operation of the C ">>" or "<<" + * operator for negative numbers. + * + * KEYWORDS: shift, arithmetic shift left, + * + *************************************************************************/ + +int32_t L_shl(int32_t L_var1, int16_t var2) +{ + + int32_t L_Mask, + L_Out; + int i, + iOverflow = 0; + + if (var2 == 0 || L_var1 == 0) + { + L_Out = L_var1; + } + else if (var2 < 0) + { + if (var2 <= -31) + { + if (L_var1 > 0) + L_Out = 0; + else + L_Out = 0xffffffffL; + } + else + L_Out = L_shr(L_var1, -var2); + } + else + { + + if (var2 >= 31) + iOverflow = 1; + + else + { + + if (L_var1 < 0) + L_Mask = LW_SIGN; /* sign bit mask */ + else + L_Mask = 0x0; + L_Out = L_var1; + for (i = 0; i < var2 && !iOverflow; i++) + { + /* check the sign bit */ + L_Out = (L_Out & 0x7fffffffL) << 1; + if ((L_Mask ^ L_Out) & LW_SIGN) + iOverflow = 1; + } + } + + if (iOverflow) + { + /* saturate */ + if (L_var1 > 0) + L_Out = LW_MAX; + else + L_Out = LW_MIN; + } + } + + return (L_Out); +} + +/*************************************************************************** + * + * FUNCTION NAME: L_shr + * + * PURPOSE: + * + * Arithmetic shift right (or left). + * Arithmetically shift the input right by var2. If var2 is + * negative then an arithmetic shift left (shl) of var1 by + * -var2 is performed. + * + * INPUTS: + * + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * + * IMPLEMENTATION: + * + * Arithmetically shift the input right by var2. This + * operation maintains the sign of the input number. If var2 is + * negative then an arithmetic shift left (shl) of L_var1 by + * -var2 is performed. See description of L_shl for details. + * + * The input is a 32 bit number, as is the output. + * + * Equivalent to the Full-Rate GSM ">> n" operation. Note that + * ANSI-C does not guarantee operation of the C ">>" or "<<" + * operator for negative numbers. + * + * KEYWORDS: shift, arithmetic shift right, + * + *************************************************************************/ + +int32_t L_shr(int32_t L_var1, int16_t var2) +{ + + int32_t L_Mask, + L_Out; + + if (var2 == 0 || L_var1 == 0) + { + L_Out = L_var1; + } + else if (var2 < 0) + { + /* perform a left shift */ + /*----------------------*/ + if (var2 <= -31) + { + /* saturate */ + if (L_var1 > 0) + L_Out = LW_MAX; + else + L_Out = LW_MIN; + } + else + L_Out = L_shl(L_var1, -var2); + } + else + { + + if (var2 >= 31) + { + if (L_var1 > 0) + L_Out = 0; + else + L_Out = 0xffffffffL; + } + else + { + L_Mask = 0; + + if (L_var1 < 0) + { + L_Mask = ~L_Mask << (32 - var2); + } + + L_var1 >>= var2; + L_Out = L_Mask | L_var1; + } + } + return (L_Out); +} + +/*************************************************************************** + * + * FUNCTION NAME: L_sub + * + * PURPOSE: + * + * Perform the subtraction of the two 32 bit input variables with + * saturation. + * + * INPUTS: + * + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * L_var2 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var2 <= 0x7fff ffff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * IMPLEMENTATION: + * + * Perform the subtraction of the two 32 bit input variables with + * saturation. + * + * L_Out = L_var1 - L_var2 + * + * L_Out is set to 0x7fff ffff if the operation results in an + * overflow. L_Out is set to 0x8000 0000 if the operation + * results in an underflow. + * + * KEYWORDS: sub, subtraction + * + *************************************************************************/ +int32_t L_sub(int32_t L_var1, int32_t L_var2) +{ + int32_t L_Sum; + + /* check for overflow */ + if ((L_var1 > 0 && L_var2 < 0) || (L_var1 < 0 && L_var2 > 0)) + { + if (L_var2 == LW_MIN) + { + L_Sum = L_add(L_var1, LW_MAX); + L_Sum = L_add(L_Sum, 1); + } + else + L_Sum = L_add(L_var1, -L_var2); + } + else + { /* no overflow possible */ + L_Sum = L_var1 - L_var2; + } + return (L_Sum); +} + +/*************************************************************************** + * + * FUNCTION NAME:mac_r + * + * PURPOSE: + * + * Multiply accumulate and round. Fractionally multiply two 16 + * bit numbers together with saturation. Add that result to + * the 32 bit input with saturation. Finally round the result + * into a 16 bit number. + * + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * L_var3 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var2 <= 0x7fff ffff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * Fractionally multiply two 16 bit numbers together with + * saturation. The only numbers which will cause saturation on + * the multiply are 0x8000 * 0x8000. + * + * Add that result to the 32 bit input with saturation. + * Round the 32 bit result by adding 0x0000 8000 to the input. + * The result may overflow due to the add. If so, the result + * is saturated. The 32 bit rounded number is then shifted + * down 16 bits and returned as a int16_t. + * + * Please note that this is not a true multiply accumulate as + * most processors would implement it. The 0x8000*0x8000 + * causes and overflow for this instruction. On most + * processors this would cause an overflow only if the 32 bit + * input added to it were positive or zero. + * + * KEYWORDS: mac, multiply accumulate, macr + * + *************************************************************************/ + +int16_t mac_r(int32_t L_var3, int16_t var1, int16_t var2) +{ + return (round(L_add(L_var3, L_mult(var1, var2)))); +} + +/*************************************************************************** + * + * FUNCTION NAME: msu_r + * + * PURPOSE: + * + * Multiply subtract and round. Fractionally multiply two 16 + * bit numbers together with saturation. Subtract that result from + * the 32 bit input with saturation. Finally round the result + * into a 16 bit number. + * + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * L_var3 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var2 <= 0x7fff ffff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * Fractionally multiply two 16 bit numbers together with + * saturation. The only numbers which will cause saturation on + * the multiply are 0x8000 * 0x8000. + * + * Subtract that result from the 32 bit input with saturation. + * Round the 32 bit result by adding 0x0000 8000 to the input. + * The result may overflow due to the add. If so, the result + * is saturated. The 32 bit rounded number is then shifted + * down 16 bits and returned as a int16_t. + * + * Please note that this is not a true multiply accumulate as + * most processors would implement it. The 0x8000*0x8000 + * causes and overflow for this instruction. On most + * processors this would cause an overflow only if the 32 bit + * input added to it were positive or zero. + * + * KEYWORDS: mac, multiply accumulate, macr + * + *************************************************************************/ + +int16_t msu_r(int32_t L_var3, int16_t var1, int16_t var2) +{ + return (round(L_sub(L_var3, L_mult(var1, var2)))); +} + +/*************************************************************************** + * + * FUNCTION NAME: mult + * + * PURPOSE: + * + * Perform a fractional multipy of the two 16 bit input numbers + * with saturation and truncation. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * Perform a fractional multipy of the two 16 bit input + * numbers. If var1 == var2 == -0x8000, output 0x7fff. + * Otherwise output var1*var2 >> 15. The output is a + * 16 bit number. + * + * KEYWORDS: mult, mulitply, mpy + * + *************************************************************************/ + +int16_t mult(int16_t var1, int16_t var2) +{ + int32_t L_product; + int16_t swOut; + + L_product = L_mult(var1, var2); + swOut = extract_h(L_product); + return (swOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: mult_r + * + * PURPOSE: + * + * Perform a fractional multipy and round of the two 16 bit + * input numbers with saturation. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * This routine is defined as the concatenation of the multiply + * operation and the round operation. + * + * The fractional multiply (L_mult) produces a saturated 32 bit + * output. This is followed by a an add of 0x0000 8000 to the + * 32 bit result. The result may overflow due to the add. If + * so, the result is saturated. The 32 bit rounded number is + * then shifted down 16 bits and returned as a int16_t. + * + * + * KEYWORDS: multiply and round, round, mult_r, mpyr + * + *************************************************************************/ + + +int16_t mult_r(int16_t var1, int16_t var2) +{ + int16_t swOut; + + swOut = round(L_mult(var1, var2)); + return (swOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: negate + * + * PURPOSE: + * + * Negate the 16 bit input. 0x8000's negated value is 0x7fff. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8001 <= swOut <= 0x0000 7fff. + * + * KEYWORDS: negate, negative, invert + * + *************************************************************************/ + +int16_t negate(int16_t var1) +{ + int16_t swOut; + + if (var1 == SW_MIN) + swOut = SW_MAX; + else + swOut = -var1; + return (swOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: norm_l + * + * PURPOSE: + * + * Get normalize shift count: + * + * A 32 bit number is input (possiblly unnormalized). Output + * the positive (or zero) shift count required to normalize the + * input. + * + * INPUTS: + * + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0 <= swOut <= 31 + * + * + * + * IMPLEMENTATION: + * + * Get normalize shift count: + * + * A 32 bit number is input (possiblly unnormalized). Output + * the positive (or zero) shift count required to normalize the + * input. + * + * If zero in input, return 0 as the shift count. + * + * For non-zero numbers, count the number of left shift + * required to get the number to fall into the range: + * + * 0x4000 0000 >= normlzd number >= 0x7fff ffff (positive number) + * or + * 0x8000 0000 <= normlzd number < 0xc000 0000 (negative number) + * + * Return the number of shifts. + * + * This instruction corresponds exactly to the Full-Rate "norm" + * instruction. + * + * KEYWORDS: norm, normalization + * + *************************************************************************/ + +int16_t norm_l(int32_t L_var1) +{ + + int16_t swShiftCnt; + + if (L_var1 != 0) + { + if (!(L_var1 & LW_SIGN)) + { + + /* positive input */ + for (swShiftCnt = 0; !(L_var1 <= LW_MAX && L_var1 >= 0x40000000L); + swShiftCnt++) + { + L_var1 = L_var1 << 1; + } + + } + else + { + /* negative input */ + int32_t lwMin = (int32_t)LW_MIN; + int32_t upperLimit = (int32_t)0xc0000000L; + for (swShiftCnt = 0; !(L_var1 >= lwMin && L_var1 < upperLimit ); swShiftCnt++) + { + L_var1 = L_var1 << 1; + } + } + } + else + { + swShiftCnt = 0; + } + return (swShiftCnt); +} + +/*************************************************************************** + * + * FUNCTION NAME: norm_s + * + * PURPOSE: + * + * Get normalize shift count: + * + * A 16 bit number is input (possiblly unnormalized). Output + * the positive (or zero) shift count required to normalize the + * input. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0 <= swOut <= 15 + * + * + * + * IMPLEMENTATION: + * + * Get normalize shift count: + * + * A 16 bit number is input (possiblly unnormalized). Output + * the positive (or zero) shift count required to normalize the + * input. + * + * If zero in input, return 0 as the shift count. + * + * For non-zero numbers, count the number of left shift + * required to get the number to fall into the range: + * + * 0x4000 >= normlzd number >= 0x7fff (positive number) + * or + * 0x8000 <= normlzd number < 0xc000 (negative number) + * + * Return the number of shifts. + * + * This instruction corresponds exactly to the Full-Rate "norm" + * instruction. + * + * KEYWORDS: norm, normalization + * + *************************************************************************/ + +int16_t norm_s(int16_t var1) +{ + + short swShiftCnt; + int32_t L_var1; + + L_var1 = L_deposit_h(var1); + swShiftCnt = norm_l(L_var1); + return (swShiftCnt); +} + +/*************************************************************************** + * + * FUNCTION NAME: round + * + * PURPOSE: + * + * Round the 32 bit int32_t into a 16 bit int16_t with saturation. + * + * INPUTS: + * + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * Perform a two's complement round on the input int32_t with + * saturation. + * + * This is equivalent to adding 0x0000 8000 to the input. The + * result may overflow due to the add. If so, the result is + * saturated. The 32 bit rounded number is then shifted down + * 16 bits and returned as a int16_t. + * + * + * KEYWORDS: round + * + *************************************************************************/ + +int16_t round(int32_t L_var1) +{ + int32_t L_Prod; + + L_Prod = L_add(L_var1, 0x00008000L); /* round MSP */ + return (extract_h(L_Prod)); +} + +/*************************************************************************** + * + * FUNCTION NAME: shift_r + * + * PURPOSE: + * + * Shift and round. Perform a shift right. After shifting, use + * the last bit shifted out of the LSB to round the result up + * or down. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * + * IMPLEMENTATION: + * + * Shift and round. Perform a shift right. After shifting, use + * the last bit shifted out of the LSB to round the result up + * or down. + * + * If var2 is positive perform a arithmetic left shift + * with saturation (see shl() above). + * + * If var2 is zero simply return var1. + * + * If var2 is negative perform a arithmetic right shift (shr) + * of var1 by (-var2)+1. Add the LS bit of the result to var1 + * shifted right (shr) by -var2. + * + * Note that there is no constraint on var2, so if var2 is + * -0xffff 8000 then -var2 is 0x0000 8000, not 0x0000 7fff. + * This is the reason the shl function is used. + * + * + * KEYWORDS: + * + *************************************************************************/ + +int16_t shift_r(int16_t var1, int16_t var2) +{ + int16_t swOut, + swRnd; + + if (var2 >= 0) + swOut = shl(var1, var2); + else + { + + /* right shift */ + + if (var2 < -15) + { + + swOut = 0; + + } + else + { + + swRnd = shl(var1, var2 + 1) & 0x1; + swOut = add(shl(var1, var2), swRnd); + + } + } + return (swOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: shl + * + * PURPOSE: + * + * Arithmetically shift the input left by var2. + * + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * If Arithmetically shift the input left by var2. If var2 is + * negative then an arithmetic shift right (shr) of var1 by + * -var2 is performed. See description of shr for details. + * When an arithmetic shift left is performed the var2 LS bits + * are zero filled. + * + * The only exception is if the left shift causes an overflow + * or underflow. In this case the LS bits are not modified. + * The number returned is 0x8000 in the case of an underflow or + * 0x7fff in the case of an overflow. + * + * The shl is equivalent to the Full-Rate GSM "<< n" operation. + * Note that ANSI-C does not guarantee operation of the C ">>" + * or "<<" operator for negative numbers - it is not specified + * whether this shift is an arithmetic or logical shift. + * + * KEYWORDS: asl, arithmetic shift left, shift + * + *************************************************************************/ + +int16_t shl(int16_t var1, int16_t var2) +{ + int16_t swOut; + int32_t L_Out; + + if (var2 == 0 || var1 == 0) + { + swOut = var1; + } + else if (var2 < 0) + { + + /* perform a right shift */ + /*-----------------------*/ + + if (var2 <= -15) + { + if (var1 < 0) + swOut = (int16_t) 0xffff; + else + swOut = 0x0; + } + else + swOut = shr(var1, -var2); + + } + else + { + /* var2 > 0 */ + if (var2 >= 15) + { + /* saturate */ + if (var1 > 0) + swOut = SW_MAX; + else + swOut = SW_MIN; + } + else + { + + L_Out = (int32_t) var1 *(1 << var2); + + swOut = (int16_t) L_Out; /* copy low portion to swOut, overflow + * could have hpnd */ + if (swOut != L_Out) + { + /* overflow */ + if (var1 > 0) + swOut = SW_MAX; /* saturate */ + else + swOut = SW_MIN; /* saturate */ + } + } + } + return (swOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: shr + * + * PURPOSE: + * + * Arithmetic shift right (or left). + * Arithmetically shift the input right by var2. If var2 is + * negative then an arithmetic shift left (shl) of var1 by + * -var2 is performed. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * Arithmetically shift the input right by var2. This + * operation maintains the sign of the input number. If var2 is + * negative then an arithmetic shift left (shl) of var1 by + * -var2 is performed. See description of shl for details. + * + * Equivalent to the Full-Rate GSM ">> n" operation. Note that + * ANSI-C does not guarantee operation of the C ">>" or "<<" + * operator for negative numbers. + * + * KEYWORDS: shift, arithmetic shift right, + * + *************************************************************************/ + +int16_t shr(int16_t var1, int16_t var2) +{ + + int16_t swMask, + swOut; + + if (var2 == 0 || var1 == 0) + swOut = var1; + + else if (var2 < 0) + { + /* perform an arithmetic left shift */ + /*----------------------------------*/ + if (var2 <= -15) + { + /* saturate */ + if (var1 > 0) + swOut = SW_MAX; + else + swOut = SW_MIN; + } + else + swOut = shl(var1, -var2); + } + + else + { + + /* positive shift count */ + /*----------------------*/ + + if (var2 >= 15) + { + if (var1 < 0) + swOut = (int16_t) 0xffff; + else + swOut = 0x0; + } + else + { + /* take care of sign extension */ + /*-----------------------------*/ + + swMask = 0; + if (var1 < 0) + { + swMask = ~swMask << (16 - var2); + } + + var1 >>= var2; + swOut = swMask | var1; + + } + } + return (swOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: sub + * + * PURPOSE: + * + * Perform the subtraction of the two 16 bit input variable with + * saturation. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * Perform the subtraction of the two 16 bit input variable with + * saturation. + * + * swOut = var1 - var2 + * + * swOut is set to 0x7fff if the operation results in an + * overflow. swOut is set to 0x8000 if the operation results + * in an underflow. + * + * KEYWORDS: sub, subtraction + * + *************************************************************************/ +int16_t sub(int16_t var1, int16_t var2) +{ + int32_t L_diff; + int16_t swOut; + + L_diff = (int32_t) var1 - var2; + swOut = saturate(L_diff); + + return (swOut); +} + +// From err_conc.c + +#define MIN_MUTE_LEVEL -45 + +/***************************************************************************** + * + * FUNCTION NAME: para_conceal_speech_decoder + * + * This subroutine performs concealment on parameter level. If the + * badframe flag (swErrorFlag[0]) has been set in the channel decoder + * parameter repetition is performed. + * If the average frame energy R0 shows an abnormal increase between two + * subsequent frames the badframe flag is also set and parameter + * repetition is performed. + * If R0 shows an important increase muting is permitted in the signal + * concealment unit. There the level of the synthesized speech signal is + * controlled and corrected if necessary. + * + * In table "psrR0RepeatThreshold[]" the maximum allowed + * increase of R0 for badframe setting is stored. The table + * is controlled by the value of R0 of the last frame. + * If e.g. the previous R0 is 10 the allowed maximum increase + * is 9 (psrR0RepeatThreshold[10]). + * The figures in psrR0RepeatThreshold[] have been determined + * by measuring the R0 statistics of an error free speech + * signal. In approximately 95 % of the frames the increase of + * R0 is less than the defined figures for error free speech. + * If the level increase is higher than the determined limit + * then the badframe flag is set. + * + * In table "psrR0MuteThreshold[]" the maximum allowed + * increase of R0 for muting is stored. + * The table is controlled by the value of R0 of the last frame + * If e.g. the previous R0 is 10 the allowed maximum increase + * is 7 (psrR0MuteThreshold[10]). + * The figures in psrR0MuteThreshold[] have been determined + * by measuring the R0 statistics of an error free speech + * signal. In approximately 85 % of the frames the increase of + * R0 is less than the defined figures for error free speech. + * If the level increase is higher than the determined limit + * then muting is allowed. + * + * Input: pswErrorFlag[0] badframe flag from channel decoder + * pswErrorFlag[1] unreliable frame flag from channel decoder + * pswSpeechPara[] unconcealed speech parameters + * Output: pswSpeechPara[] concealed speech parameters + * swMutePermit flag, indicating whether muting is + * permitted + * + * Constants: psrR0RepeatThreshold[32] maximum allowed R0 difference + * before frame is repeated + * psrR0MuteThreshold[32] maximum allowed R0 difference + * before muting is permitted + * + * + ****************************************************************************/ + +void Codec::para_conceal_speech_decoder(int16_t pswErrorFlag[], + int16_t pswSpeechPara[], int16_t *pswMutePermit) +{ + +/*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| +*/ + static const int16_t psrR0RepeatThreshold[32] = + {15, 15, 15, 12, 12, 12, 12, 11, + 10, 10, 9, 9, 9, 9, 8, 8, + 7, 6, 5, 5, 5, 4, 4, 3, + 2, 2, 2, 2, 2, 2, 10, 10}; + static const int16_t psrR0MuteThreshold[32] = + {14, 12, 11, 9, 9, 9, 9, 7, + 7, 7, 7, 7, 6, 6, 6, 5, + 5, 4, 3, 3, 3, 3, 3, 2, + 1, 1, 1, 1, 1, 1, 10, 10}; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int16_t swLastLag, + swR0, + swLag, + r0_diff, + i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Initialise mute permission flag */ + /* ------------------------------- */ + *pswMutePermit = 0; + + /* Determine R0-difference to last frame */ + /* ------------------------------------- */ + r0_diff = sub(pswSpeechPara[0], lastR0); + + /* If no badframe has been declared, but the frame is unreliable then */ + /* check whether there is an abnormal increase of R0 */ + /* ------------------------------------------------------------------ */ + if ((pswErrorFlag[0] == 0) && (pswErrorFlag[1] > 0)) + { + + /* Check if difference exceeds the maximum allowed threshold. */ + /* If yes, set badframe flag */ + /* ---------------------------------------------------------- */ + if (sub(r0_diff, psrR0RepeatThreshold[lastR0]) >= 0) + { + pswErrorFlag[0] = 1; + } + else + { + /* Allow muting if R0 >= 30 */ + /* ------------------------ */ + if (sub(pswSpeechPara[0], 30) >= 0) + *pswMutePermit = 1; + } + } + + /* If no badframe has been declared, but the frame is unreliable then */ + /* check whether there is an important increase of R0 */ + /* ------------------------------------------------------------------ */ + if ((pswErrorFlag[1] > 0) && (pswErrorFlag[0] == 0)) + { + + /* Check if difference exceeds a threshold. */ + /* If yes, allow muting in the signal concealment unit */ + /* ---------------------------------------------------------- */ + if (sub(r0_diff, psrR0MuteThreshold[lastR0]) >= 0) + { + *pswMutePermit = 1; + } + } + + + /* Perform parameter repetition, if necessary (badframe handling) */ + /* -------------------------------------------------------------- */ + + if (pswErrorFlag[0] > 0) + { + swState = add(swState, 1); /* update the bad frame + * masking state */ + if (sub(swState, 6) > 0) + swState = 6; + } + else + { + if (sub(swState, 6) < 0) + swState = 0; + else if (swLastFlag == 0) + swState = 0; + } + + swLastFlag = pswErrorFlag[0]; + + /* if the decoded frame is good, save it */ + /* ------------------------------------- */ + if (swState == 0) + { + for (i = 0; i < 18; i++) + pswLastGood[i] = pswSpeechPara[i]; + } + + /* if the frame is bad, attenuate and repeat last good frame */ + /* --------------------------------------------------------- */ + else + { + if ((sub(swState, 3) >= 0) && (sub(swState, 5) <= 0)) + { + swR0 = sub(pswLastGood[0], 2); /* attenuate by 4 dB */ + if (swR0 < 0) + swR0 = 0; + pswLastGood[0] = swR0; + } + + if (sub(swState, 6) >= 0) /* mute */ + pswLastGood[0] = 0; + + /* If the last good frame is unvoiced, use its energy, voicing mode, lpc + * coefficients, and soft interpolation. For gsp0, use only the gsp0 + * value from the last good subframe. If the current bad frame is + * unvoiced, use the current codewords. If not, use the codewords from + * the last good frame. */ + /* -------------------------------------------------------------- */ + if (pswLastGood[5] == 0) + { /* unvoiced good frame */ + if (pswSpeechPara[5] == 0) + { /* unvoiced bad frame */ + for (i = 0; i < 5; i++) + pswSpeechPara[i] = pswLastGood[i]; + for (i = 0; i < 4; i++) + pswSpeechPara[3 * i + 8] = pswLastGood[17]; + } + else + { /* voiced bad frame */ + for (i = 0; i < 18; i++) + pswSpeechPara[i] = pswLastGood[i]; + for (i = 0; i < 3; i++) + pswSpeechPara[3 * i + 8] = pswLastGood[17]; + } + } + + /* If the last good frame is voiced, the long term predictor lag at the + * last subframe is used for all subsequent subframes. Use the last good + * frame's energy, voicing mode, lpc coefficients, and soft + * interpolation. For gsp0 in all subframes, use the gsp0 value from the + * last good subframe. If the current bad frame is voiced, use the + * current codewords. If not, use the codewords from the last good + * frame. */ + /* ---------------------------------------------------------------- */ + else + { /* voiced good frame */ + swLastLag = pswLastGood[6]; /* frame lag */ + for (i = 0; i < 3; i++) + { /* each delta lag */ + swLag = sub(pswLastGood[3 * i + 9], 0x8); /* biased around 0 */ + swLag = add(swLag, swLastLag); /* reconstruct pitch */ + if (sub(swLag, 0x00ff) > 0) + { /* limit, as needed */ + swLastLag = 0x00ff; + } + else if (swLag < 0) + { + swLastLag = 0; + } + else + swLastLag = swLag; + } + pswLastGood[6] = swLastLag; /* saved frame lag */ + pswLastGood[9] = 0x8; /* saved delta lags */ + pswLastGood[12] = 0x8; + pswLastGood[15] = 0x8; + + if (pswSpeechPara[5] != 0) + { /* voiced bad frame */ + for (i = 0; i < 6; i++) + pswSpeechPara[i] = pswLastGood[i]; + for (i = 0; i < 4; i++) + pswSpeechPara[3 * i + 6] = pswLastGood[3 * i + 6]; + for (i = 0; i < 4; i++) + pswSpeechPara[3 * i + 8] = pswLastGood[17]; + } + else + { /* unvoiced bad frame */ + for (i = 0; i < 18; i++) + pswSpeechPara[i] = pswLastGood[i]; + for (i = 0; i < 3; i++) + pswSpeechPara[3 * i + 8] = pswLastGood[17]; + } + } + + } /* end of bad frame */ + + + /* Update last value of R0 */ + /* ----------------------- */ + lastR0 = pswSpeechPara[0]; + +} + + +/**************************************************************************** + * + * FUNCTION NAME: level_estimator + * + * This subroutine determines the mean level and the maximum level + * of the last four speech sub-frames. These parameters are the basis + * for the level estimation in signal_conceal_sub(). + * + * Input: swUpdate = 0: the levels are determined + * = 1: the memory of the level estimator + * is updated + * pswDecodedSpeechFrame[] synthesized speech signal + * + * Output: swLevelMean mean level of the last 4 sub-frames + * swLevelMax maximum level of the last 4 sub-frames + * + ***************************************************************************/ + +void Codec::level_estimator(int16_t update, int16_t *pswLevelMean, + int16_t *pswLevelMax, + int16_t pswDecodedSpeechFrame[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int16_t i, + tmp, + swLevelSub; + int32_t L_sum; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + if (update == 0) + { + + /* Determine mean level of the last 4 sub-frames: */ + /* ---------------------------------------------- */ + for (i = 0, L_sum = 0; i < 4; ++i) + { + L_sum = L_add(L_sum, plSubfrEnergyMem[i]); + } + *pswLevelMean = level_calc(1, &L_sum); + + /* Determine maximum level of the last 4 sub-frames: */ + /* ------------------------------------------------- */ + *pswLevelMax = -72; + for (i = 0; i < 4; ++i) + { + if (sub(swLevelMem[i], *pswLevelMax) > 0) + *pswLevelMax = swLevelMem[i]; + } + + } + else + { + /* Determine the energy of the synthesized speech signal: */ + /* ------------------------------------------------------ */ + for (i = 0, L_sum = 0; i < S_LEN; ++i) + { + tmp = shr(pswDecodedSpeechFrame[i], 3); + L_sum = L_mac(L_sum, tmp, tmp); + } + swLevelSub = level_calc(0, &L_sum); + + /* Update memories of level estimator: */ + /* ----------------------------------- */ + for (i = 0; i < 3; ++i) + plSubfrEnergyMem[i] = plSubfrEnergyMem[i + 1]; + plSubfrEnergyMem[3] = L_sum; + + for (i = 0; i < 3; ++i) + swLevelMem[i] = swLevelMem[i + 1]; + swLevelMem[3] = swLevelSub; + } +} + + +/***************************************************************************** + * + * FUNCTION NAME: signal_conceal_sub + * + * This subroutine performs concealment on subframe signal level. + * A test synthesis is performed and the level of the synthesized speech + * signal is compared to the estimated level. Depending on the control + * flag "swMutePermit" a muting factor is determined. + * If muting is permitted (swMutePermit=1) and the actual sub-frame level + * exceeds the maximum level of the last four sub-frames "swLevelMax" plus + * an allowed increase "psrLevelMaxIncrease[]" then the synthesized speech + * signal together with the signal memories is muted. + * In table "psrLevelMaxIncrease[]" the maximum allowed increase + * of the maximum sub-frame level is stored. The table is controled by the + * mean level "swMeanLevel". + * If e.g. the level is in the range between -30 and -35 db + * the allowed maximum increase is 4 db (psrLevelMaxIncrease[6]). + * The figures in psrLevelMaxIncrease[] have been determined + * by measuring the level statistics of error free synthesized speech. + * + * Input: pswPPFExcit[] excitation signal + * pswSynthFiltState[] state of LPC synthesis filter + * ppswSynthAs[] LPC coefficients + * pswLtpStateOut[] state of long term predictor + * pswPPreState[] state of pitch prefilter + * swLevelMean mean level + * swLevelMax maximum level + * swUFI unreliable frame flag + * swMuteFlagOld last muting flag + * pswMuteFlag actual muting flag + * swMutePermit mute permission + * + * Output: pswPPFExcit[] muted excitation signal + * pswSynthFiltState[] muted state of LPC synthesis filter + * pswLtpStateOut[] muted state of long term predictor + * pswPPreState[] muted state of pitch prefilter + * + * Constants: psrConceal[0:15] muting factors + * psrLevelMaxIncrease[0:7] maximum allowed level increase + * + * + ****************************************************************************/ + +void Codec::signal_conceal_sub(int16_t pswPPFExcit[], + int16_t ppswSynthAs[], int16_t pswSynthFiltState[], + int16_t pswLtpStateOut[], int16_t pswPPreState[], + int16_t swLevelMean, int16_t swLevelMax, + int16_t swUFI, int16_t swMuteFlagOld, + int16_t *pswMuteFlag, int16_t swMutePermit) +{ + +/*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| +*/ + static const int16_t psrConceal[15] = {29205, 27571, 24573, 21900, + 19519, 17396, 15504, 13818, 12315, 10976, 9783, 8719, 7771, 6925, 6172}; + static const int16_t psrLevelMaxIncrease[16] = + {0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16}; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int16_t swMute, + swLevelSub, + i, + swIndex; + int16_t swTmp, + pswStateTmp[10], + swOutTmp[40], + swPermitMuteSub; + int32_t L_sum; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Test synthesis filter: */ + /* ---------------------- */ + for (i = 0; i < 10; ++i) + pswStateTmp[i] = pswSynthFiltState[i]; + + lpcIir(pswPPFExcit, ppswSynthAs, pswStateTmp, swOutTmp); + + + /* Determine level in db of synthesized signal: */ + /* -------------------------------------------- */ + L_sum = 0; + for (i = 0; i < S_LEN; ++i) + { + swTmp = shr(swOutTmp[i], 2); + L_sum = L_mac(L_sum, swTmp, swTmp); + } + swLevelSub = level_calc(0, &L_sum); + + + /* Determine index to table, specifying the allowed level increase: */ + /* level [ 0 .. -5] --> swIndex = 0 */ + /* level [-5 .. -10] --> swIndex = 1 etc. */ + /*---------------------------------------------*/ + swIndex = mult(negate(swLevelMean), 1638); + if (sub(swIndex, 15) > 0) + swIndex = 15; + + /* Muting is permitted, if it is signalled from the parameter concealment */ + /* unit or if muting has been performed in the last frame */ + /*-----------------------------------------------------------------------*/ + swPermitMuteSub = swMutePermit; + if (swMuteFlagOld > 0) + swPermitMuteSub = 1; + + if (swPermitMuteSub > 0) + { + /* Muting is not permitted if the sub-frame level is less than */ + /* MIN_MUTE_LEVEL */ + /* ------------------------------------------------------------ */ + if (sub(swLevelSub, MIN_MUTE_LEVEL) <= 0) + swPermitMuteSub = 0; + + /* Muting is not permitted if the sub-frame level is less than */ + /* the maximum level of the last 4 sub-frames plus the allowed */ + /* increase */ + /* ------------------------------------------------------------ */ + swMute = sub(swLevelSub, add(swLevelMax, psrLevelMaxIncrease[swIndex])); + if (swMute <= 0) + swPermitMuteSub = 0; + } + + + /* Perform muting, if allowed */ + /* -------------------------- */ + if (swPermitMuteSub > 0) + { + + if (sub(swMute, (int16_t) 15) > 0) + swMute = 15; + + /* Keep information that muting occured for next frame */ + /* --------------------------------------------------- */ + if (swUFI > 0) + *pswMuteFlag = 1; + + + /* Mute excitation signal: */ + /* ----------------------- */ + for (i = 0; i < 10; ++i) + pswSynthFiltState[i] = + mult_r(pswSynthFiltState[i], psrConceal[swMute - 1]); + for (i = 0; i < S_LEN; ++i) + pswPPFExcit[i] = mult_r(pswPPFExcit[i], psrConceal[swMute - 1]); + + /* Mute pitch memory: */ + /* ------------------ */ + for (i = 0; i < S_LEN; ++i) + pswLtpStateOut[i] = + mult_r(pswLtpStateOut[i], psrConceal[swMute - 1]); + + + /* Mute pitch prefilter memory: */ + /* ---------------------------- */ + for (i = 0; i < S_LEN; ++i) + pswPPreState[i] = mult_r(pswPPreState[i], psrConceal[swMute - 1]); + } +} + + +/**************************************************************************** + * + * FUNCTION NAME: level_calc + * + * This subroutine calculates the level (db) from the energy + * of a speech sub-frame (swInd=0) or a speech frame (swInd=1): + * The level of a speech subframe is: + * swLevel = 10 * lg(EN/(40.*4096*4096)) + * = 3 * ld(EN) - 88.27 + * = (3*4*ld(EN) - 353)/4 + * = (3*(4*POS(MSB(EN)) + 2*BIT(MSB-1) + BIT(MSB-2)) - 353)/4 + * + * Input: pl_en energy of the speech subframe or frame + * The energy is multiplied by 2 because of the + * MAC routines !! + * swInd = 0: EN is the energy of one subframe + * = 1: EN is the energy of one frame + * + * Output: swLevel level in db + * + * + ***************************************************************************/ + +int16_t Codec::level_calc(int16_t swInd, int32_t *pl_en) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int16_t swPos, + swLevel; + int32_t L_tmp; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + if (*pl_en != 0) + swPos = sub((int16_t) 29, norm_l(*pl_en)); + else + swPos = 0; + + /* Determine the term: 4*POS(MSB(EN)): */ + /* ----------------------------------- */ + swLevel = shl(swPos, 2); + + /* Determine the term: 2*BIT(MSB-1): */ + /* --------------------------------- */ + if (swPos >= 0) + { + L_tmp = L_shl((int32_t) 1, swPos); + if ((*pl_en & L_tmp) != 0) + swLevel += 2; + } + + /* Determine the term: BIT(MSB-2): */ + /* ------------------------------- */ + if (--swPos >= 0) + { + L_tmp = L_shl((int32_t) 1, swPos); + if ((*pl_en & L_tmp) != 0) + ++swLevel; + } + + /* Multiply by 3: */ + /* -------------- */ + swLevel += shl(swLevel, 1); + swLevel -= (swInd == 0) ? 353 : 377; + swLevel = mult_r(swLevel, 0X2000); /* >> 2 */ + + if (sub(swLevel, -72) < 0) + { + swLevel = -72; + *pl_en = (swInd == 0) ? 80 : 320; + } + + return (swLevel); +} + +// From sp_dec.c + static short aToRc(int16_t swAshift, int16_t pswAin[], + int16_t pswRc[]); + + + static void lookupVq(int16_t pswVqCodeWds[], int16_t pswRCOut[]); + + +#define P_INT_MACS 10 +#define ASCALE 0x0800 +#define ASHIFT 4 +#define DELTA_LEVELS 16 +#define GSP0_SCALE 1 +#define C_BITS_V 9 /* number of bits in any voiced VSELP + * codeword */ +#define C_BITS_UV 7 /* number of bits in a unvoiced VSELP + * codeword */ +#define MAXBITS C_BITS_V /* max number of bits in any VSELP + * codeword */ +#define SQRT_ONEHALF 0x5a82 /* the 0.5 ** 0.5 */ +#define LPC_ROUND 0x00000800L /* 0x8000 >> ASHIFT */ +#define AFSHIFT 2 /* number of right shifts to be + * applied to the autocorrelation + * sequence in aFlatRcDp */ + + void Codec::aFlatRcDp(int32_t *pL_R, int16_t *pswRc) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t pL_pjNewSpace[NP]; + int32_t pL_pjOldSpace[NP]; + int32_t pL_vjNewSpace[2 * NP - 1]; + int32_t pL_vjOldSpace[2 * NP - 1]; + + int32_t *pL_pjOld; + int32_t *pL_pjNew; + int32_t *pL_vjOld; + int32_t *pL_vjNew; + int32_t *pL_swap; + + int32_t L_temp; + int32_t L_sum; + int16_t swRc, + swRcSq, + swTemp, + swTemp1, + swAbsTemp1, + swTemp2; + int i, + j; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + pL_pjOld = pL_pjOldSpace; + pL_pjNew = pL_pjNewSpace; + pL_vjOld = pL_vjOldSpace + NP - 1; + pL_vjNew = pL_vjNewSpace + NP - 1; + + + /* Extract the 0-th reflection coefficient */ + /*-----------------------------------------*/ + + swTemp1 = round(pL_R[1]); + swTemp2 = round(pL_R[0]); + swAbsTemp1 = abs_s(swTemp1); + if (swTemp2 <= 0 || sub(swAbsTemp1, swTemp2) >= 0) + { + j = 0; + for (i = j; i < NP; i++) + { + pswRc[i] = 0; + } + return; + } + + swRc = divide_s(swAbsTemp1, swTemp2);/* return division result */ + + if (sub(swTemp1, swAbsTemp1) == 0) + swRc = negate(swRc); /* negate reflection Rc[j] */ + + pswRc[0] = swRc; /* copy into the output Rc array */ + + for (i = 0; i <= NP; i++) + { + pL_R[i] = L_shr(pL_R[i], AFSHIFT); + } + + /* Initialize the pjOld and vjOld recursion arrays */ + /*-------------------------------------------------*/ + + for (i = 0; i < NP; i++) + { + pL_pjOld[i] = pL_R[i]; + pL_vjOld[i] = pL_R[i + 1]; + } + for (i = -1; i > -NP; i--) + pL_vjOld[i] = pL_R[-(i + 1)]; + + + /* Compute the square of the j=0 reflection coefficient */ + /*------------------------------------------------------*/ + + swRcSq = mult_r(swRc, swRc); + + /* Update pjNew and vjNew arrays for lattice stage j=1 */ + /*-----------------------------------------------------*/ + + /* Updating pjNew: */ + /*-------------------*/ + + for (i = 0; i <= NP - 2; i++) + { + L_temp = L_mpy_ls(pL_vjOld[i], swRc); + L_sum = L_add(L_temp, pL_pjOld[i]); + L_temp = L_mpy_ls(pL_pjOld[i], swRcSq); + L_sum = L_add(L_temp, L_sum); + L_temp = L_mpy_ls(pL_vjOld[-i], swRc); + pL_pjNew[i] = L_add(L_sum, L_temp); + } + + /* Updating vjNew: */ + /*-------------------*/ + + for (i = -NP + 2; i <= NP - 2; i++) + { + L_temp = L_mpy_ls(pL_vjOld[-i - 1], swRcSq); + L_sum = L_add(L_temp, pL_vjOld[i + 1]); + L_temp = L_mpy_ls(pL_pjOld[(((i + 1) >= 0) ? i + 1 : -(i + 1))], swRc); + L_temp = L_shl(L_temp, 1); + pL_vjNew[i] = L_add(L_temp, L_sum); + } + + + + j = 0; + + /* Compute reflection coefficients Rc[1],...,Rc[9] */ + /*-------------------------------------------------*/ + + for (j = 1; j < NP; j++) + { + + /* Swap pjNew and pjOld buffers */ + /*------------------------------*/ + + pL_swap = pL_pjNew; + pL_pjNew = pL_pjOld; + pL_pjOld = pL_swap; + + /* Swap vjNew and vjOld buffers */ + /*------------------------------*/ + + pL_swap = pL_vjNew; + pL_vjNew = pL_vjOld; + pL_vjOld = pL_swap; + + /* Compute the j-th reflection coefficient */ + /*-----------------------------------------*/ + + swTemp = norm_l(pL_pjOld[0]); /* get shift count */ + swTemp1 = round(L_shl(pL_vjOld[0], swTemp)); /* normalize num. */ + swTemp2 = round(L_shl(pL_pjOld[0], swTemp)); /* normalize den. */ + + /* Test for invalid divide conditions: a) devisor < 0 b) abs(divident) > + * abs(devisor) If either of these conditions is true, zero out + * reflection coefficients for i=j,...,NP-1 and return. */ + + swAbsTemp1 = abs_s(swTemp1); + if (swTemp2 <= 0 || sub(swAbsTemp1, swTemp2) >= 0) + { + i = j; + for (i = j; i < NP; i++) + { + pswRc[i] = 0; + } + return; + } + + swRc = divide_s(swAbsTemp1, swTemp2); /* return division result */ + if (sub(swTemp1, swAbsTemp1) == 0) + swRc = negate(swRc); /* negate reflection Rc[j] */ + swRcSq = mult_r(swRc, swRc); /* compute Rc^2 */ + pswRc[j] = swRc; /* copy Rc[j] to output array */ + + /* Update pjNew and vjNew arrays for the next lattice stage if j < NP-1 */ + /*---------------------------------------------------------------------*/ + + /* Updating pjNew: */ + /*-----------------*/ + + for (i = 0; i <= NP - j - 2; i++) + { + L_temp = L_mpy_ls(pL_vjOld[i], swRc); + L_sum = L_add(L_temp, pL_pjOld[i]); + L_temp = L_mpy_ls(pL_pjOld[i], swRcSq); + L_sum = L_add(L_temp, L_sum); + L_temp = L_mpy_ls(pL_vjOld[-i], swRc); + pL_pjNew[i] = L_add(L_sum, L_temp); + } + + /* Updating vjNew: */ + /*-----------------*/ + + for (i = -NP + j + 2; i <= NP - j - 2; i++) + { + L_temp = L_mpy_ls(pL_vjOld[-i - 1], swRcSq); + L_sum = L_add(L_temp, pL_vjOld[i + 1]); + L_temp = L_mpy_ls(pL_pjOld[(((i + 1) >= 0) ? i + 1 : -(i + 1))], swRc); + L_temp = L_shl(L_temp, 1); + pL_vjNew[i] = L_add(L_temp, L_sum); + } + } + return; + } + + + static short aToRc(int16_t swAshift, int16_t pswAin[], + int16_t pswRc[]) + { + + /*_________________________________________________________________________ + | | + | Constants | + |_________________________________________________________________________| + */ + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t pswTmpSpace[NP], + pswASpace[NP], + swNormShift, + swActShift, + swNormProd, + swRcOverE, + swDiv, + *pswSwap, + *pswTmp, + *pswA; + + int32_t L_temp; + + short int siUnstableFlt, + i, + j; /* Loop control variables */ + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Initialize starting addresses for temporary buffers */ + /*-----------------------------------------------------*/ + + pswA = pswASpace; + pswTmp = pswTmpSpace; + + /* Copy the direct form filter coefficients to a temporary array */ + /*---------------------------------------------------------------*/ + + for (i = 0; i < NP; i++) + { + pswA[i] = pswAin[i]; + } + + /* Initialize the flag for filter stability check */ + /*------------------------------------------------*/ + + siUnstableFlt = 0; + + /* Start computation of the reflection coefficients, Rc[9],...,Rc[1] */ + /*-------------------------------------------------------------------*/ + + for (i = NP - 1; i >= 1; i--) + { + + pswRc[i] = shl(pswA[i], swAshift); /* write Rc[i] to output array */ + + /* Check the stability of i-th reflection coefficient */ + /*----------------------------------------------------*/ + + siUnstableFlt = siUnstableFlt | isSwLimit(pswRc[i]); + + /* Precompute intermediate variables for needed for the computation */ + /* of direct form filter of order i-1 */ + /*------------------------------------------------------------------*/ + + if (sub(pswRc[i], SW_MIN) == 0) + { + siUnstableFlt = 1; + swRcOverE = 0; + swDiv = 0; + swActShift = 2; + } + else + { + L_temp = LW_MAX; /* Load ~1.0 into accum */ + L_temp = L_msu(L_temp, pswRc[i], pswRc[i]); /* 1.-Rc[i]*Rc[i] */ + swNormShift = norm_l(L_temp); + L_temp = L_shl(L_temp, swNormShift); + swNormProd = extract_h(L_temp); + swActShift = add(2, swNormShift); + swDiv = divide_s(0x2000, swNormProd); + swRcOverE = mult_r(pswRc[i], swDiv); + } + /* Check stability */ + /*---------------------*/ + siUnstableFlt = siUnstableFlt | isSwLimit(swRcOverE); + + /* Compute direct form filter coefficients corresponding to */ + /* a direct form filter of order i-1 */ + /*----------------------------------------------------------*/ + + for (j = 0; j <= i - 1; j++) + { + L_temp = L_mult(pswA[j], swDiv); + L_temp = L_msu(L_temp, pswA[i - j - 1], swRcOverE); + L_temp = L_shl(L_temp, swActShift); + pswTmp[j] = round(L_temp); + siUnstableFlt = siUnstableFlt | isSwLimit(pswTmp[j]); + } + + /* Swap swA and swTmp buffers */ + /*----------------------------*/ + + pswSwap = pswA; + pswA = pswTmp; + pswTmp = pswSwap; + } + + /* Compute reflection coefficient Rc[0] */ + /*--------------------------------------*/ + + pswRc[0] = shl(pswA[0], swAshift); /* write Rc[0] to output array */ + + /* Check the stability of 0-th reflection coefficient */ + /*----------------------------------------------------*/ + + siUnstableFlt = siUnstableFlt | isSwLimit(pswRc[0]); + + return (siUnstableFlt); + } + + void Codec::a_sst(int16_t swAshift, int16_t swAscale, + int16_t pswDirectFormCoefIn[], + int16_t pswDirectFormCoefOut[]) + { + + /*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| + */ + + static int16_tRom psrSST[NP + 1] = {0x7FFF, + 0x7F5C, 0x7D76, 0x7A5B, 0x7622, 0x70EC, + 0x6ADD, 0x641F, 0x5CDD, 0x5546, 0x4D86, + }; + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t pL_CorrTemp[NP + 1]; + + int16_t pswRCNum[NP], + pswRCDenom[NP]; + + short int siLoopCnt; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* convert direct form coefs to reflection coefs */ + /* --------------------------------------------- */ + + aToRc(swAshift, pswDirectFormCoefIn, pswRCDenom); + + /* convert to autocorrelation coefficients */ + /* --------------------------------------- */ + + rcToCorrDpL(swAshift, swAscale, pswRCDenom, pL_CorrTemp); + + /* do spectral smoothing technique */ + /* ------------------------------- */ + + for (siLoopCnt = 1; siLoopCnt <= NP; siLoopCnt++) + { + pL_CorrTemp[siLoopCnt] = L_mpy_ls(pL_CorrTemp[siLoopCnt], + psrSST[siLoopCnt]); + } + + /* Compute the reflection coefficients via AFLAT */ + /*-----------------------------------------------*/ + + aFlatRcDp(pL_CorrTemp, pswRCNum); + + + /* Convert reflection coefficients to direct form filter coefficients */ + /*-------------------------------------------------------------------*/ + + rcToADp(swAscale, pswRCNum, pswDirectFormCoefOut); + } + + + int16_t Codec::agcGain(int16_t pswStateCurr[], + struct NormSw snsInSigEnergy, int16_t swEngyRShft) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_OutEnergy, + L_AgcGain; + + struct NormSw snsOutEnergy, + snsAgc; + + int16_t swAgcOut, + swAgcShftCnt; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Calculate the energy in the output vector divided by 2 */ + /*--------------------------------------------------------*/ + + snsOutEnergy.sh = g_corr1s(pswStateCurr, swEngyRShft, &L_OutEnergy); + + /* reduce energy by a factor of 2 */ + snsOutEnergy.sh = add(snsOutEnergy.sh, 1); + + /* if waveform has nonzero energy, find AGC gain */ + /*-----------------------------------------------*/ + + if (L_OutEnergy == 0) + { + swAgcOut = 0; + } + else + { + + snsOutEnergy.man = round(L_OutEnergy); + + /* divide input energy by 2 */ + snsInSigEnergy.man = shr(snsInSigEnergy.man, 1); + + + /* Calculate AGC gain squared */ + /*----------------------------*/ + + snsAgc.man = divide_s(snsInSigEnergy.man, snsOutEnergy.man); + swAgcShftCnt = norm_s(snsAgc.man); + snsAgc.man = shl(snsAgc.man, swAgcShftCnt); + + /* find shift count for G^2 */ + /*--------------------------*/ + + snsAgc.sh = add(sub(snsInSigEnergy.sh, snsOutEnergy.sh), + swAgcShftCnt); + L_AgcGain = L_deposit_h(snsAgc.man); + + + /* Calculate AGC gain */ + /*--------------------*/ + + snsAgc.man = sqroot(L_AgcGain); + + + /* check if 1/2 sqrt(G^2) >= 1.0 */ + /* This is equivalent to checking if shiftCnt/2+1 < 0 */ + /*----------------------------------------------------*/ + + if (add(snsAgc.sh, 2) < 0) + { + swAgcOut = SW_MAX; + } + else + { + + if (0x1 & snsAgc.sh) + { + snsAgc.man = mult(snsAgc.man, SQRT_ONEHALF); + } + + snsAgc.sh = shr(snsAgc.sh, 1); /* shiftCnt/2 */ + snsAgc.sh = add(snsAgc.sh, 1); /* shiftCnt/2 + 1 */ + + if (snsAgc.sh > 0) + { + snsAgc.man = shr(snsAgc.man, snsAgc.sh); + } + swAgcOut = snsAgc.man; + } + } + + return (swAgcOut); + } + + void Codec::b_con(int16_t swCodeWord, short siNumBits, + int16_t pswVectOut[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + short int siLoopCnt; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + for (siLoopCnt = 0; siLoopCnt < siNumBits; siLoopCnt++) + { + + if (swCodeWord & 1) /* temp accumulator get 0.5 */ + pswVectOut[siLoopCnt] = (int16_t) 0x4000; + else /* temp accumulator gets -0.5 */ + pswVectOut[siLoopCnt] = (int16_t) 0xc000; + + swCodeWord = shr(swCodeWord, 1); + } + } + + void Codec::fp_ex(int16_t swOrigLagIn, + int16_t pswLTPState[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_Temp; + int16_t swIntLag, + swRemain, + swRunningLag; + short int siSampsSoFar, + siSampsThisPass, + i, + j; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Loop: execute until all samples in the vector have been looked up */ + /*-------------------------------------------------------------------*/ + + swRunningLag = swOrigLagIn; + siSampsSoFar = 0; + while (siSampsSoFar < S_LEN) + { + + /* Get integer lag and remainder. These are used in addressing */ + /* the LTP state and the interpolating filter, respectively */ + /*--------------------------------------------------------------*/ + + get_ipjj(swRunningLag, &swIntLag, &swRemain); + + + /* Get the number of samples to look up in this pass */ + /*---------------------------------------------------*/ + + if (sub(swIntLag, S_LEN) < 0) + siSampsThisPass = swIntLag - siSampsSoFar; + else + siSampsThisPass = S_LEN - siSampsSoFar; + + /* Look up samples by interpolating (fractional lag), or copying */ + /* (integer lag). */ + /*---------------------------------------------------------------*/ + + if (swRemain == 0) + { + + /* Integer lag: copy samples from history */ + /*----------------------------------------*/ + + for (i = siSampsSoFar; i < siSampsSoFar + siSampsThisPass; i++) + pswLTPState[i] = pswLTPState[i - swIntLag]; + } + else + { + + /* Fractional lag: interpolate to get samples */ + /*--------------------------------------------*/ + + for (i = siSampsSoFar; i < siSampsSoFar + siSampsThisPass; i++) + { + + /* first tap with rounding offset */ + /*--------------------------------*/ + L_Temp = L_mac((long) 32768, + pswLTPState[i - swIntLag - P_INT_MACS / 2], + ppsrPVecIntFilt[0][swRemain]); + + for (j = 1; j < P_INT_MACS - 1; j++) + { + + L_Temp = L_mac(L_Temp, + pswLTPState[i - swIntLag - P_INT_MACS / 2 + j], + ppsrPVecIntFilt[j][swRemain]); + + } + + pswLTPState[i] = extract_h(L_mac(L_Temp, + pswLTPState[i - swIntLag + P_INT_MACS / 2 - 1], + ppsrPVecIntFilt[P_INT_MACS - 1][swRemain])); + } + } + + /* Done with this pass: update loop controls */ + /*-------------------------------------------*/ + + siSampsSoFar += siSampsThisPass; + swRunningLag = add(swRunningLag, swOrigLagIn); + } + } + + + int16_t Codec::g_corr1(int16_t *pswIn, int32_t *pL_out) + { + + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_sum; + int16_t swEngyLShft; + int i; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + + /* Calculate energy in subframe vector (40 samples) */ + /*--------------------------------------------------*/ + + L_sum = L_mult(pswIn[0], pswIn[0]); + for (i = 1; i < S_LEN; i++) + { + L_sum = L_mac(L_sum, pswIn[i], pswIn[i]); + } + + + + if (L_sum != 0) + { + + /* Normalize the energy in the output int32_t */ + /*---------------------------------------------*/ + + swEngyLShft = norm_l(L_sum); + *pL_out = L_shl(L_sum, swEngyLShft); /* normalize output + * int32_t */ + } + else + { + + /* Special case: energy is zero */ + /*------------------------------*/ + + *pL_out = L_sum; + swEngyLShft = 0; + } + + return (swEngyLShft); + } + + + int16_t Codec::g_corr1s(int16_t pswIn[], int16_t swEngyRShft, + int32_t *pL_out) + { + + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_sum; + int16_t swTemp, + swEngyLShft; + int16_t swInputRShft; + + int i; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + + /* Calculate energy in subframe vector (40 samples) */ + /*--------------------------------------------------*/ + + if (sub(swEngyRShft, 1) <= 0) + { + + /* use the energy shift factor, although it is an odd shift count */ + /*----------------------------------------------------------------*/ + + swTemp = shr(pswIn[0], swEngyRShft); + L_sum = L_mult(pswIn[0], swTemp); + for (i = 1; i < S_LEN; i++) + { + swTemp = shr(pswIn[i], swEngyRShft); + L_sum = L_mac(L_sum, pswIn[i], swTemp); + } + + } + else + { + + /* convert energy shift factor to an input shift factor */ + /*------------------------------------------------------*/ + + swInputRShft = shift_r(swEngyRShft, -1); + swEngyRShft = shl(swInputRShft, 1); + + swTemp = shr(pswIn[0], swInputRShft); + L_sum = L_mult(swTemp, swTemp); + for (i = 1; i < S_LEN; i++) + { + swTemp = shr(pswIn[i], swInputRShft); + L_sum = L_mac(L_sum, swTemp, swTemp); + } + } + + if (L_sum != 0) + { + + /* Normalize the energy in the output int32_t */ + /*---------------------------------------------*/ + + swTemp = norm_l(L_sum); + *pL_out = L_shl(L_sum, swTemp); /* normalize output int32_t */ + swEngyLShft = sub(swTemp, swEngyRShft); + } + else + { + + /* Special case: energy is zero */ + /*------------------------------*/ + + *pL_out = L_sum; + swEngyLShft = 0; + } + + return (swEngyLShft); + } + + void Codec::getSfrmLpc(short int siSoftInterpolation, + int16_t swPrevR0, int16_t swNewR0, + /* last frm */ int16_t pswPrevFrmKs[], int16_t pswPrevFrmAs[], + int16_t pswPrevFrmPFNum[], + int16_t pswPrevFrmPFDenom[], + + /* this frm */ int16_t pswNewFrmKs[], int16_t pswNewFrmAs[], + int16_t pswNewFrmPFNum[], + int16_t pswNewFrmPFDenom[], + + /* output */ struct NormSw *psnsSqrtRs, + int16_t *ppswSynthAs[], int16_t *ppswPFNumAs[], + int16_t *ppswPFDenomAs[]) + { + + /*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| + */ + + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + short int siSfrm, + siStable, + i; + + int32_t L_Temp1, + L_Temp2; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + if (siSoftInterpolation) + { + /* yes, interpolating */ + /* ------------------ */ + + siSfrm = 0; + + siStable = interpolateCheck(pswPrevFrmKs, pswPrevFrmAs, + pswPrevFrmAs, pswNewFrmAs, + psrOldCont[siSfrm], psrNewCont[siSfrm], + swPrevR0, + &psnsSqrtRs[siSfrm], + ppswSynthAs[siSfrm]); + if (siStable) + { + + /* interpolate between direct form coefficient sets */ + /* for both numerator and denominator coefficients */ + /* assume output will be stable */ + /* ------------------------------------------------ */ + + for (i = 0; i < NP; i++) + { + L_Temp1 = L_mult(pswNewFrmPFNum[i], psrNewCont[siSfrm]); + ppswPFNumAs[siSfrm][i] = mac_r(L_Temp1, pswPrevFrmPFNum[i], + psrOldCont[siSfrm]); + L_Temp2 = L_mult(pswNewFrmPFDenom[i], psrNewCont[siSfrm]); + ppswPFDenomAs[siSfrm][i] = mac_r(L_Temp2, pswPrevFrmPFDenom[i], + psrOldCont[siSfrm]); + } + } + else + { + /* this subframe is unstable */ + /* ------------------------- */ + for (i = 0; i < NP; i++) + { + ppswPFNumAs[siSfrm][i] = pswPrevFrmPFNum[i]; + ppswPFDenomAs[siSfrm][i] = pswPrevFrmPFDenom[i]; + } + } + for (siSfrm = 1; siSfrm < N_SUB - 1; siSfrm++) + { + + siStable = interpolateCheck(pswNewFrmKs, pswNewFrmAs, + pswPrevFrmAs, pswNewFrmAs, + psrOldCont[siSfrm], psrNewCont[siSfrm], + swNewR0, + &psnsSqrtRs[siSfrm], + ppswSynthAs[siSfrm]); + if (siStable) + { + + /* interpolate between direct form coefficient sets */ + /* for both numerator and denominator coefficients */ + /* assume output will be stable */ + /* ------------------------------------------------ */ + + for (i = 0; i < NP; i++) + { + L_Temp1 = L_mult(pswNewFrmPFNum[i], psrNewCont[siSfrm]); + ppswPFNumAs[siSfrm][i] = mac_r(L_Temp1, pswPrevFrmPFNum[i], + psrOldCont[siSfrm]); + L_Temp2 = L_mult(pswNewFrmPFDenom[i], psrNewCont[siSfrm]); + ppswPFDenomAs[siSfrm][i] = mac_r(L_Temp2, pswPrevFrmPFDenom[i], + psrOldCont[siSfrm]); + } + } + else + { + /* this subframe has unstable filter coeffs, would like to + * interpolate but can not */ + /* -------------------------------------- */ + for (i = 0; i < NP; i++) + { + ppswPFNumAs[siSfrm][i] = pswNewFrmPFNum[i]; + ppswPFDenomAs[siSfrm][i] = pswNewFrmPFDenom[i]; + } + } + } + /* the last subframe never interpolate */ + /* ----------------------------------- */ + siSfrm = 3; + for (i = 0; i < NP; i++) + { + ppswPFNumAs[siSfrm][i] = pswNewFrmPFNum[i]; + ppswPFDenomAs[siSfrm][i] = pswNewFrmPFDenom[i]; + ppswSynthAs[siSfrm][i] = pswNewFrmAs[i]; + } + + res_eng(pswNewFrmKs, swNewR0, &psnsSqrtRs[siSfrm]); + + } + /* SoftInterpolation == 0 - no interpolation */ + /* ------------------------------------------ */ + else + { + siSfrm = 0; + for (i = 0; i < NP; i++) + { + ppswPFNumAs[siSfrm][i] = pswPrevFrmPFNum[i]; + ppswPFDenomAs[siSfrm][i] = pswPrevFrmPFDenom[i]; + ppswSynthAs[siSfrm][i] = pswPrevFrmAs[i]; + } + + res_eng(pswPrevFrmKs, swPrevR0, &psnsSqrtRs[siSfrm]); + + /* for subframe 1 and all subsequent sfrms, use result from new frm */ + /* ---------------------------------------------------------------- */ + + + res_eng(pswNewFrmKs, swNewR0, &psnsSqrtRs[1]); + + for (siSfrm = 1; siSfrm < N_SUB; siSfrm++) + { + + + psnsSqrtRs[siSfrm].man = psnsSqrtRs[1].man; + psnsSqrtRs[siSfrm].sh = psnsSqrtRs[1].sh; + + for (i = 0; i < NP; i++) + { + ppswPFNumAs[siSfrm][i] = pswNewFrmPFNum[i]; + ppswPFDenomAs[siSfrm][i] = pswNewFrmPFDenom[i]; + ppswSynthAs[siSfrm][i] = pswNewFrmAs[i]; + } + } + } + } + + void Codec::get_ipjj(int16_t swLagIn, + int16_t *pswIp, int16_t *pswJj) + { + + /*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| + */ + + #define OS_FCTR_INV (int16_t)0x1555/* SW_MAX/OS_FCTR */ + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_Temp; + + int16_t swTemp, + swTempIp, + swTempJj; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* calculate ip */ + /* ------------ */ + + L_Temp = L_mult(OS_FCTR_INV, swLagIn); /* lag/OS_FCTR */ + swTempIp = extract_h(L_Temp); + + /* calculate jj */ + /* ------------ */ + + swTemp = extract_l(L_Temp); /* loose ip */ + swTemp = shr(swTemp, 1); /* isolate jj fraction */ + swTemp = swTemp & SW_MAX; + L_Temp = L_mult(swTemp, OS_FCTR); /* ((lag/OS_FCTR)-ip))*(OS_FCTR) */ + swTemp = round(L_Temp); /* round and pick-off jj */ + if (sub(swTemp, OS_FCTR) == 0) + { /* if 'overflow ' */ + swTempJj = 0; /* set remainder,jj to 0 */ + swTempIp = add(swTempIp, 1); /* 'carry' overflow into ip */ + } + else + { + swTempJj = swTemp; /* read-off remainder,jj */ + } + + /* return ip and jj */ + /* ---------------- */ + + *pswIp = swTempIp; + *pswJj = swTempJj; + } + + short int Codec::interpolateCheck(int16_t pswRefKs[], + int16_t pswRefCoefsA[], + int16_t pswOldCoefsA[], int16_t pswNewCoefsA[], + int16_t swOldPer, int16_t swNewPer, + int16_t swRq, + struct NormSw *psnsSqrtRsOut, + int16_t pswCoefOutA[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t pswRcTemp[NP]; + + int32_t L_Temp; + + short int siInterp_flg, + i; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Interpolation loop, NP is order of LPC filter */ + /* --------------------------------------------- */ + + for (i = 0; i < NP; i++) + { + L_Temp = L_mult(pswNewCoefsA[i], swNewPer); + pswCoefOutA[i] = mac_r(L_Temp, pswOldCoefsA[i], swOldPer); + } + + /* Convert to reflection coefficients and check stability */ + /* ------------------------------------------------------ */ + + if (aToRc(ASHIFT, pswCoefOutA, pswRcTemp) != 0) + { + + /* Unstable, use uninterpolated parameters and compute RS update the + * state with the frame data closest to this subfrm */ + /* --------------------------------------------------------- */ + + res_eng(pswRefKs, swRq, psnsSqrtRsOut); + + for (i = 0; i < NP; i++) + { + pswCoefOutA[i] = pswRefCoefsA[i]; + } + siInterp_flg = 0; + } + else + { + + /* Stable, compute RS */ + /* ------------------ */ + res_eng(pswRcTemp, swRq, psnsSqrtRsOut); + + /* Set temporary subframe interpolation flag */ + /* ----------------------------------------- */ + siInterp_flg = 1; + } + + /* Return subframe interpolation flag */ + /* ---------------------------------- */ + return (siInterp_flg); + } + + /*************************************************************************** + * + * FUNCTION NAME: lagDecode + * + * PURPOSE: + * + * The purpose of this function is to decode the lag received from the + * speech encoder into a full resolution lag for the speech decoder + * + * INPUTS: + * + * swDeltaLag + * + * lag received from channel decoder + * + * giSfrmCnt + * + * current sub-frame count + * + * swLastLag + * + * previous lag to un-delta this sub-frame's lag + * + * psrLagTbl[0:255] + * + * table used to look up full resolution lag + * + * OUTPUTS: + * + * swLastLag + * + * new previous lag for next sub-frame + * + * RETURN VALUE: + * + * swLag + * + * decoded full resolution lag + * + * DESCRIPTION: + * + * If first subframe, use lag as index to look up table directly. + * + * If it is one of the other subframes, the codeword represents a + * delta offset. The previously decoded lag is used as a starting + * point for decoding the current lag. + * + * REFERENCES: Sub-clause 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: deltalags, lookup lag + * + *************************************************************************/ + + int16_t Codec::lagDecode(int16_t swDeltaLag) + { + + /*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| + */ + + #define DELTA_LEVELS_D2 DELTA_LEVELS/2 + #define MAX_LAG 0x00ff + #define MIN_LAG 0x0000 + + /*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| + */ + + + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swLag; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* first sub-frame */ + /* --------------- */ + + if (giSfrmCnt == 0) + { + swLastLag = swDeltaLag; + } + + /* remaining sub-frames */ + /* -------------------- */ + + else + { + + /* get lag biased around 0 */ + /* ----------------------- */ + + swLag = sub(swDeltaLag, DELTA_LEVELS_D2); + + /* get real lag relative to last */ + /* ----------------------------- */ + + swLag = add(swLag, swLastLag); + + /* clip to max or min */ + /* ------------------ */ + + if (sub(swLag, MAX_LAG) > 0) + { + swLastLag = MAX_LAG; + } + else if (sub(swLag, MIN_LAG) < 0) + { + swLastLag = MIN_LAG; + } + else + { + swLastLag = swLag; + } + } + + /* return lag after look up */ + /* ------------------------ */ + + swLag = psrLagTbl[swLastLag]; + return (swLag); + } + + /*************************************************************************** + * + * FUNCTION NAME: lookupVq + * + * PURPOSE: + * + * The purpose of this function is to recover the reflection coeffs from + * the received LPC codewords. + * + * INPUTS: + * + * pswVqCodeWds[0:2] + * + * the codewords for each of the segments + * + * OUTPUTS: + * + * pswRCOut[0:NP-1] + * + * the decoded reflection coefficients + * + * RETURN VALUE: + * + * none. + * + * DESCRIPTION: + * + * For each segment do the following: + * setup the retrieval pointers to the correct vector + * get that vector + * + * REFERENCES: Sub-clause 4.2.3 of GSM Recomendation 06.20 + * + * KEYWORDS: vq, vectorquantizer, lpc + * + *************************************************************************/ + + static void lookupVq(int16_t pswVqCodeWds[], int16_t pswRCOut[]) + { + /*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| + */ + + #define LSP_MASK 0x00ff + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + short int siSeg, + siIndex, + siVector, + siVector1, + siVector2, + siWordPtr; + + int16_tRom *psrQTable; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* for each segment */ + /* ---------------- */ + + for (siSeg = 0; siSeg < QUANT_NUM_OF_TABLES; siSeg++) + { + + siVector = pswVqCodeWds[siSeg]; + siIndex = psvqIndex[siSeg].l; + + if (sub(siSeg, 2) == 0) + { /* segment 3 */ + + /* set table */ + /* --------- */ + + psrQTable = psrQuant3; + + /* set offset into table */ + /* ---------------------- */ + + siWordPtr = add(siVector, siVector); + + /* look up coeffs */ + /* -------------- */ + + siVector1 = psrQTable[siWordPtr]; + siVector2 = psrQTable[siWordPtr + 1]; + + pswRCOut[siIndex - 1] = psrSQuant[shr(siVector1, 8) & LSP_MASK]; + pswRCOut[siIndex] = psrSQuant[siVector1 & LSP_MASK]; + pswRCOut[siIndex + 1] = psrSQuant[shr(siVector2, 8) & LSP_MASK]; + pswRCOut[siIndex + 2] = psrSQuant[siVector2 & LSP_MASK]; + } + else + { /* segments 1 and 2 */ + + /* set tables */ + /* ---------- */ + + if (siSeg == 0) + { + psrQTable = psrQuant1; + } + else + { + psrQTable = psrQuant2; + + } + + /* set offset into table */ + /* --------------------- */ + + siWordPtr = add(siVector, siVector); + siWordPtr = add(siWordPtr, siVector); + siWordPtr = shr(siWordPtr, 1); + + /* look up coeffs */ + /* -------------- */ + + siVector1 = psrQTable[siWordPtr]; + siVector2 = psrQTable[siWordPtr + 1]; + + if ((siVector & 0x0001) == 0) + { + pswRCOut[siIndex - 1] = psrSQuant[shr(siVector1, 8) & LSP_MASK]; + pswRCOut[siIndex] = psrSQuant[siVector1 & LSP_MASK]; + pswRCOut[siIndex + 1] = psrSQuant[shr(siVector2, 8) & LSP_MASK]; + } + else + { + pswRCOut[siIndex - 1] = psrSQuant[siVector1 & LSP_MASK]; + pswRCOut[siIndex] = psrSQuant[shr(siVector2, 8) & LSP_MASK]; + pswRCOut[siIndex + 1] = psrSQuant[siVector2 & LSP_MASK]; + } + } + } + } + + /*************************************************************************** + * + * FUNCTION NAME: lpcFir + * + * PURPOSE: + * + * The purpose of this function is to perform direct form fir filtering + * assuming a NP order filter and given state, coefficients, and input. + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter + * + * pswInput[0:S_LEN-1] + * + * input array of points to be filtered. + * pswInput[0] is the oldest point (first to be filtered) + * pswInput[siLen-1] is the last point filtered (newest) + * + * pswCoef[0:NP-1] + * + * array of direct form coefficients + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * pswState[0:NP-1] + * + * array of the filter state following form of pswCoef + * pswState[0] = state of filter for delay n = -1 + * pswState[NP-1] = state of filter for delay n = -NP + * + * OUTPUTS: + * + * pswState[0:NP-1] + * + * updated filter state, ready to filter + * pswInput[siLen], i.e. the next point + * + * pswFiltOut[0:S_LEN-1] + * + * the filtered output + * same format as pswInput, pswFiltOut[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] += state[j]*coef[j] (state is taken from either input + * state[] or input in[] arrays) + * rescale(out[i]) + * out[i] += in[i] + * update final state array using in[] + * + * REFERENCES: Sub-clause 4.1.7 and 4.2.4 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, fir, lpcFir, inversefilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set, i_dir_mod + * + *************************************************************************/ + + void Codec::lpcFir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswState[], int16_t pswFiltOut[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_Sum; + short int siStage, + siSmp; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* filter 1st sample */ + /* ----------------- */ + + /* sum past state outputs */ + /* ---------------------- */ + /* 0th coef, with rounding */ + L_Sum = L_mac(LPC_ROUND, pswState[0], pswCoef[0]); + + for (siStage = 1; siStage < NP; siStage++) + { /* remaining coefs */ + L_Sum = L_mac(L_Sum, pswState[siStage], pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswInput[0], 0x8000); + + /* save 1st output sample */ + /* ---------------------- */ + + pswFiltOut[0] = extract_h(L_Sum); + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_mac(LPC_ROUND, pswInput[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_mac(L_Sum, pswInput[siSmp - siStage - 1], pswCoef[siStage]); + } + + /* sum past states, if any */ + /* ----------------------- */ + + for (siStage = siSmp; siStage < NP; siStage++) + { + L_Sum = L_mac(L_Sum, pswState[siStage - siSmp], pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswInput[siSmp], 0x8000); + + /* save current output sample */ + /* -------------------------- */ + + pswFiltOut[siSmp] = extract_h(L_Sum); + } + + /* save final state */ + /* ---------------- */ + + for (siStage = 0; siStage < NP; siStage++) + { + pswState[siStage] = pswInput[S_LEN - siStage - 1]; + } + + } + + /*************************************************************************** + * + * FUNCTION NAME: lpcIir + * + * PURPOSE: + * + * The purpose of this function is to perform direct form IIR filtering + * assuming a NP order filter and given state, coefficients, and input + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter + * + * pswInput[0:S_LEN-1] + * + * input array of points to be filtered + * pswInput[0] is the oldest point (first to be filtered) + * pswInput[siLen-1] is the last point filtered (newest) + * + * pswCoef[0:NP-1] + * array of direct form coefficients + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * pswState[0:NP-1] + * + * array of the filter state following form of pswCoef + * pswState[0] = state of filter for delay n = -1 + * pswState[NP-1] = state of filter for delay n = -NP + * + * OUTPUTS: + * + * pswState[0:NP-1] + * + * updated filter state, ready to filter + * pswInput[siLen], i.e. the next point + * + * pswFiltOut[0:S_LEN-1] + * + * the filtered output + * same format as pswInput, pswFiltOut[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] -= state[j]*coef[j] (state is taken from either input + * state[] or prior out[] arrays) + * rescale(out[i]) + * out[i] += in[i] + * update final state array using out[] + * + * REFERENCES: Sub-clause 4.1.7 and 4.2.4 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, iir, synthesisfilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set + * + *************************************************************************/ + + void Codec::lpcIir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswState[], int16_t pswFiltOut[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_Sum; + short int siStage, + siSmp; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* filter 1st sample */ + /* ----------------- */ + + /* sum past state outputs */ + /* ---------------------- */ + /* 0th coef, with rounding */ + L_Sum = L_msu(LPC_ROUND, pswState[0], pswCoef[0]); + + for (siStage = 1; siStage < NP; siStage++) + { /* remaining coefs */ + L_Sum = L_msu(L_Sum, pswState[siStage], pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswInput[0], 0x8000); + + /* save 1st output sample */ + /* ---------------------- */ + + pswFiltOut[0] = extract_h(L_Sum); + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_msu(LPC_ROUND, pswFiltOut[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_msu(L_Sum, pswFiltOut[siSmp - siStage - 1], + pswCoef[siStage]); + } + + /* sum past states, if any */ + /* ----------------------- */ + + for (siStage = siSmp; siStage < NP; siStage++) + { + L_Sum = L_msu(L_Sum, pswState[siStage - siSmp], pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswInput[siSmp], 0x8000); + + /* save current output sample */ + /* -------------------------- */ + + pswFiltOut[siSmp] = extract_h(L_Sum); + } + + /* save final state */ + /* ---------------- */ + + for (siStage = 0; siStage < NP; siStage++) + { + pswState[siStage] = pswFiltOut[S_LEN - siStage - 1]; + } + } + + /*************************************************************************** + * + * FUNCTION NAME: lpcIrZsIir + * + * PURPOSE: + * + * The purpose of this function is to calculate the impulse response + * via direct form IIR filtering with zero state assuming a NP order + * filter and given coefficients + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter + * + * pswCoef[0:NP-1] + * array of direct form coefficients + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * OUTPUTS: + * + * pswFiltOut[0:S_LEN-1] + * + * the filtered output + * same format as pswInput, pswFiltOut[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * This routine is called by getNWCoefs(). + * + * Because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] -= state[j]*coef[j] (state taken from prior output[]) + * rescale(out[i]) + * + * REFERENCES: Sub-clause 4.1.8 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, iir, synthesisfilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set + * + *************************************************************************/ + + void Codec::lpcIrZsIir(int16_t pswCoef[], int16_t pswFiltOut[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_Sum; + short int siStage, + siSmp; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* output 1st sample */ + /* ----------------- */ + + pswFiltOut[0] = 0x0400; + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_msu(LPC_ROUND, pswFiltOut[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_msu(L_Sum, pswFiltOut[siSmp - siStage - 1], + pswCoef[siStage]); + } + + /* scale output */ + /* ------------ */ + + L_Sum = L_shl(L_Sum, ASHIFT); + + /* save current output sample */ + /* -------------------------- */ + + pswFiltOut[siSmp] = extract_h(L_Sum); + } + } + + /*************************************************************************** + * + * FUNCTION NAME: lpcZiIir + * + * PURPOSE: + * The purpose of this function is to perform direct form iir filtering + * with zero input assuming a NP order filter, and given state and + * coefficients + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter MUST be <= MAX_ZIS + * + * pswCoef[0:NP-1] + * + * array of direct form coefficients. + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * pswState[0:NP-1] + * + * array of the filter state following form of pswCoef + * pswState[0] = state of filter for delay n = -1 + * pswState[NP-1] = state of filter for delay n = -NP + * + * OUTPUTS: + * + * pswFiltOut[0:S_LEN-1] + * + * the filtered output + * same format as pswIn, pswFiltOut[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * The routine is called from sfrmAnalysis, and is used to let the + * LPC filters ring out. + * + * because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] -= state[j]*coef[j] (state is taken from either input + * state[] or prior output[] arrays) + * rescale(out[i]) + * + * REFERENCES: Sub-clause 4.1.7 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, iir, synthesisfilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set + * + *************************************************************************/ + + void Codec::lpcZiIir(int16_t pswCoef[], int16_t pswState[], + int16_t pswFiltOut[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_Sum; + short int siStage, + siSmp; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* filter 1st sample */ + /* ----------------- */ + + /* sum past state outputs */ + /* ---------------------- */ + /* 0th coef, with rounding */ + L_Sum = L_msu(LPC_ROUND, pswState[0], pswCoef[0]); + + for (siStage = 1; siStage < NP; siStage++) + { /* remaining coefs */ + L_Sum = L_msu(L_Sum, pswState[siStage], pswCoef[siStage]); + } + + /* scale output */ + /* ------------ */ + + L_Sum = L_shl(L_Sum, ASHIFT); + + /* save 1st output sample */ + /* ---------------------- */ + + pswFiltOut[0] = extract_h(L_Sum); + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_msu(LPC_ROUND, pswFiltOut[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_msu(L_Sum, pswFiltOut[siSmp - siStage - 1], + pswCoef[siStage]); + } + + /* sum past states, if any */ + /* ----------------------- */ + + for (siStage = siSmp; siStage < NP; siStage++) + { + L_Sum = L_msu(L_Sum, pswState[siStage - siSmp], pswCoef[siStage]); + } + + /* scale output */ + /* ------------ */ + + L_Sum = L_shl(L_Sum, ASHIFT); + + /* save current output sample */ + /* -------------------------- */ + + pswFiltOut[siSmp] = extract_h(L_Sum); + } + } + + /*************************************************************************** + * + * FUNCTION NAME: lpcZsFir + * + * PURPOSE: + * The purpose of this function is to perform direct form fir filtering + * with zero state, assuming a NP order filter and given coefficients + * and non-zero input. + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter + * + * pswInput[0:S_LEN-1] + * + * input array of points to be filtered. + * pswInput[0] is the oldest point (first to be filtered) + * pswInput[siLen-1] is the last point filtered (newest) + * + * pswCoef[0:NP-1] + * + * array of direct form coefficients + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * OUTPUTS: + * + * pswFiltOut[0:S_LEN-1] + * + * the filtered output + * same format as pswInput, pswFiltOut[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * This routine is used in getNWCoefs(). See section 4.1.7. + * + * because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] += state[j]*coef[j] (state taken from in[]) + * rescale(out[i]) + * out[i] += in[i] + * + * REFERENCES: Sub-clause 4.1.7 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, fir, lpcFir, inversefilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set, i_dir_mod + * + *************************************************************************/ + + void Codec::lpcZsFir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswFiltOut[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_Sum; + short int siStage, + siSmp; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* output 1st sample */ + /* ----------------- */ + + pswFiltOut[0] = pswInput[0]; + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_mac(LPC_ROUND, pswInput[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_mac(L_Sum, pswInput[siSmp - siStage - 1], + pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswInput[siSmp], 0x8000); + + /* save current output sample */ + /* -------------------------- */ + + pswFiltOut[siSmp] = extract_h(L_Sum); + } + } + + /*************************************************************************** + * + * FUNCTION NAME: lpcZsIir + * + * PURPOSE: + * + * The purpose of this function is to perform direct form IIR filtering + * with zero state, assuming a NP order filter and given coefficients + * and non-zero input. + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter + * + * pswInput[0:S_LEN-1] + * + * input array of points to be filtered + * pswInput[0] is the oldest point (first to be filtered) + * pswInput[siLen-1] is the last point filtered (newest) + * + * pswCoef[0:NP-1] + * array of direct form coefficients + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * OUTPUTS: + * + * pswFiltOut[0:S_LEN-1] + * + * the filtered output + * same format as pswInput, pswFiltOut[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * This routine is used in the subframe analysis process. It is + * called by sfrmAnalysis() and fnClosedLoop(). It is this function + * which performs the weighting of the excitation vectors. + * + * because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] -= state[j]*coef[j] (state taken from prior out[]) + * rescale(out[i]) + * out[i] += in[i] + * + * REFERENCES: Sub-clause 4.1.8.5 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, iir, synthesisfilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set + * + *************************************************************************/ + + void Codec::lpcZsIir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswFiltOut[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_Sum; + short int siStage, + siSmp; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* output 1st sample */ + /* ----------------- */ + + pswFiltOut[0] = pswInput[0]; + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_msu(LPC_ROUND, pswFiltOut[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_msu(L_Sum, pswFiltOut[siSmp - siStage - 1], + pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswInput[siSmp], 0x8000); + + /* save current output sample */ + /* -------------------------- */ + + pswFiltOut[siSmp] = extract_h(L_Sum); + } + } + + /*************************************************************************** + * + * FUNCTION NAME: lpcZsIirP + * + * PURPOSE: + * + * The purpose of this function is to perform direct form iir filtering + * with zero state, assuming a NP order filter and given coefficients + * and input + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter + * + * pswCommonIO[0:S_LEN-1] + * + * input array of points to be filtered + * pswCommonIO[0] is oldest point (first to be filtered) + * pswCommonIO[siLen-1] is last point filtered (newest) + * + * pswCoef[0:NP-1] + * array of direct form coefficients + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * OUTPUTS: + * + * pswCommonIO[0:S_LEN-1] + * + * the filtered output + * pswCommonIO[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * This function is called by geNWCoefs(). See section 4.1.7. + * + * because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] += state[j]*coef[j] (state taken from prior out[]) + * rescale(out[i]) + * out[i] += in[i] + * + * REFERENCES: Sub-clause 4.1.7 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, iir, synthesisfilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set + * + *************************************************************************/ + + void Codec::lpcZsIirP(int16_t pswCommonIO[], int16_t pswCoef[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_Sum; + short int siStage, + siSmp; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_mac(LPC_ROUND, pswCommonIO[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_mac(L_Sum, pswCommonIO[siSmp - siStage - 1], + pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswCommonIO[siSmp], 0x8000); + + /* save current output sample */ + /* -------------------------- */ + + pswCommonIO[siSmp] = extract_h(L_Sum); + } + } + + /************************************************************************** + * + * FUNCTION NAME: pitchPreFilt + * + * PURPOSE: + * + * Performs pitch pre-filter on excitation in speech decoder. + * + * INPUTS: + * + * pswExcite[0:39] + * + * Synthetic residual signal to be filtered, a subframe- + * length vector. + * + * ppsrPVecIntFilt[0:9][0:5] ([tap][phase]) + * + * Interpolation filter coefficients. + * + * ppsrSqtrP0[0:2][0:31] ([voicing level-1][gain code]) + * + * Sqrt(P0) look-up table, used to determine pitch + * pre-filtering coefficient. + * + * swRxGsp0 + * + * Coded value from gain quantizer, used to look up + * sqrt(P0). + * + * swRxLag + * + * Full-resolution lag value (fractional lag * + * oversampling factor), used to index pitch pre-filter + * state. + * + * swUvCode + * + * Coded voicing level, used to distinguish between + * voiced and unvoiced conditions, and to look up + * sqrt(P0). + * + * swSemiBeta + * + * The gain applied to the adaptive codebook excitation + * (long-term predictor excitation) limited to a maximum + * of 1.0, used to determine the pitch pre-filter + * coefficient. + * + * snsSqrtRs + * + * The estimate of the energy in the residual, used only + * for scaling. + * + * OUTPUTS: + * + * pswExciteOut[0:39] + * + * The output pitch pre-filtered excitation. + * + * pswPPreState[0:44] + * + * Contains the state of the pitch pre-filter + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * If the voicing mode for the frame is unvoiced, then the pitch pre- + * filter state is updated with the input excitation, and the input + * excitation is copied to the output. + * + * If voiced: first the energy in the input excitation is calculated. + * Then, the coefficient of the pitch pre-filter is obtained: + * + * PpfCoef = POST_EPSILON * min(beta, sqrt(P0)). + * + * Then, the pitch pre-filter is performed: + * + * ex_p(n) = ex(n) + PpfCoef * ex_p(n-L) + * + * The ex_p(n-L) sample is interpolated from the surrounding samples, + * even for integer values of L. + * + * Note: The coefficients of the interpolating filter are multiplied + * by PpfCoef, rather multiplying ex_p(n_L) after interpolation. + * + * Finally, the energy in the output excitation is calculated, and + * automatic gain control is applied to the output signal so that + * its energy matches the original. + * + * The pitch pre-filter is described in section 4.2.2. + * + * REFERENCES: Sub-clause 4.2.2 of GSM Recomendation 06.20 + * + * KEYWORDS: prefilter, pitch, pitchprefilter, excitation, residual + * + *************************************************************************/ + + void Codec::pitchPreFilt(int16_t pswExcite[], + int16_t swRxGsp0, + int16_t swRxLag, int16_t swUvCode, + int16_t swSemiBeta, struct NormSw snsSqrtRs, + int16_t pswExciteOut[], + int16_t pswPPreState[]) + { + + /*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| + */ + + #define POST_EPSILON 0x2666 + + /*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| + */ + + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_1, + L_OrigEnergy; + + int16_t swScale, + swSqrtP0, + swIntLag, + swRemain, + swEnergy, + pswInterpCoefs[P_INT_MACS]; + + short int i, + j; + + struct NormSw snsOrigEnergy; + + int16_t *pswPPreCurr = &pswPPreState[LTP_LEN]; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Initialization */ + /*----------------*/ + + swEnergy = 0; + + /* Check voicing level */ + /*---------------------*/ + + if (swUvCode == 0) + { + + /* Unvoiced: perform one subframe of delay on state, copy input to */ + /* state, copy input to output (if not same) */ + /*-----------------------------------------------------------------*/ + + for (i = 0; i < LTP_LEN - S_LEN; i++) + pswPPreState[i] = pswPPreState[i + S_LEN]; + + for (i = 0; i < S_LEN; i++) + pswPPreState[i + LTP_LEN - S_LEN] = pswExcite[i]; + + if (pswExciteOut != pswExcite) + { + + for (i = 0; i < S_LEN; i++) + pswExciteOut[i] = pswExcite[i]; + } + } + else + { + + /* Voiced: calculate energy in input, filter, calculate energy in */ + /* output, scale */ + /*----------------------------------------------------------------*/ + + /* Get energy in input excitation vector */ + /*---------------------------------------*/ + + swEnergy = add(negate(shl(snsSqrtRs.sh, 1)), 3); + + if (swEnergy > 0) + { + + /* High-energy residual: scale input vector during energy */ + /* calculation. The shift count + 1 of the energy of the */ + /* residual estimate is used as an estimate of the shift */ + /* count needed for the excitation energy */ + /*--------------------------------------------------------*/ + + + snsOrigEnergy.sh = g_corr1s(pswExcite, swEnergy, &L_OrigEnergy); + snsOrigEnergy.man = round(L_OrigEnergy); + + } + else + { + + /* set shift count to zero for AGC later */ + /*---------------------------------------*/ + + swEnergy = 0; + + /* Lower-energy residual: no overflow protection needed */ + /*------------------------------------------------------*/ + + L_OrigEnergy = 0; + for (i = 0; i < S_LEN; i++) + { + + L_OrigEnergy = L_mac(L_OrigEnergy, pswExcite[i], pswExcite[i]); + } + + snsOrigEnergy.sh = norm_l(L_OrigEnergy); + snsOrigEnergy.man = round(L_shl(L_OrigEnergy, snsOrigEnergy.sh)); + } + + /* Determine pitch pre-filter coefficient, and scale the appropriate */ + /* phase of the interpolating filter by it */ + /*-------------------------------------------------------------------*/ + + swSqrtP0 = ppsrSqrtP0[swUvCode - 1][swRxGsp0]; + + if (sub(swSqrtP0, swSemiBeta) > 0) + swScale = swSemiBeta; + else + swScale = swSqrtP0; + + swScale = mult_r(POST_EPSILON, swScale); + + get_ipjj(swRxLag, &swIntLag, &swRemain); + + for (i = 0; i < P_INT_MACS; i++) + pswInterpCoefs[i] = mult_r(ppsrPVecIntFilt[i][swRemain], swScale); + + /* Perform filter */ + /*----------------*/ + + for (i = 0; i < S_LEN; i++) + { + + L_1 = L_deposit_h(pswExcite[i]); + + for (j = 0; j < P_INT_MACS - 1; j++) + { + + L_1 = L_mac(L_1, pswPPreCurr[i - swIntLag - P_INT_MACS / 2 + j], + pswInterpCoefs[j]); + } + + pswPPreCurr[i] = mac_r(L_1, + pswPPreCurr[i - swIntLag + P_INT_MACS / 2 - 1], + pswInterpCoefs[P_INT_MACS - 1]); + } + + /* Get energy in filtered vector, determine automatic-gain-control */ + /* scale factor */ + /*-----------------------------------------------------------------*/ + + swScale = agcGain(pswPPreCurr, snsOrigEnergy, swEnergy); + + /* Scale filtered vector by AGC, put out. NOTE: AGC scale returned */ + /* by routine above is divided by two, hence the shift below */ + /*------------------------------------------------------------------*/ + + for (i = 0; i < S_LEN; i++) + { + + L_1 = L_mult(pswPPreCurr[i], swScale); + L_1 = L_shl(L_1, 1); + pswExciteOut[i] = round(L_1); + } + + /* Update pitch pre-filter state */ + /*-------------------------------*/ + + for (i = 0; i < LTP_LEN; i++) + pswPPreState[i] = pswPPreState[i + S_LEN]; + } + } + + /*************************************************************************** + * + * FUNCTION NAME: r0BasedEnergyShft + * + * PURPOSE: + * + * Given an R0 voicing level, find the number of shifts to be + * performed on the energy to ensure that the subframe energy does + * not overflow. example if energy can maximally take the value + * 4.0, then 2 shifts are required. + * + * INPUTS: + * + * swR0Index + * R0 codeword (0-0x1f) + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swShiftDownSignal + * + * number of right shifts to apply to energy (0..6) + * + * DESCRIPTION: + * + * Based on the R0, the average frame energy, we can get an + * upper bound on the energy any one subframe can take on. + * Using this upper bound we can calculate what right shift is + * needed to ensure an unsaturated output out of a subframe + * energy calculation (g_corr). + * + * REFERENCES: Sub-clause 4.1.9 and 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: spectral postfilter + * + *************************************************************************/ + + int16_t Codec::r0BasedEnergyShft(int16_t swR0Index) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swShiftDownSignal; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + if (sub(swR0Index, 26) <= 0) + { + if (sub(swR0Index, 23) <= 0) + { + if (sub(swR0Index, 21) <= 0) + swShiftDownSignal = 0; /* r0 [0, 21] */ + else + swShiftDownSignal = 1; /* r0 [22, 23] */ + } + else + { + if (sub(swR0Index, 24) <= 0) + swShiftDownSignal = 2; /* r0 [23, 24] */ + else + swShiftDownSignal = 3; /* r0 [24, 26] */ + } + } + else + { /* r0 index > 26 */ + if (sub(swR0Index, 28) <= 0) + { + swShiftDownSignal = 4; /* r0 [26, 28] */ + } + else + { + if (sub(swR0Index, 29) <= 0) + swShiftDownSignal = 5; /* r0 [28, 29] */ + else + swShiftDownSignal = 6; /* r0 [29, 31] */ + } + } + if (sub(swR0Index, 18) > 0) + swShiftDownSignal = add(swShiftDownSignal, 2); + + return (swShiftDownSignal); + } + + /*************************************************************************** + * + * FUNCTION NAME: rcToADp + * + * PURPOSE: + * + * This subroutine computes a vector of direct form LPC filter + * coefficients, given an input vector of reflection coefficients. + * Double precision is used internally, but 16 bit direct form + * filter coefficients are returned. + * + * INPUTS: + * + * NP + * order of the LPC filter (global constant) + * + * swAscale + * The multiplier which scales down the direct form + * filter coefficients. + * + * pswRc[0:NP-1] + * The input vector of reflection coefficients. + * + * OUTPUTS: + * + * pswA[0:NP-1] + * Array containing the scaled down direct form LPC + * filter coefficients. + * + * RETURN VALUE: + * + * siLimit + * 1 if limiting occured in computation, 0 otherwise. + * + * DESCRIPTION: + * + * This function performs the conversion from reflection coefficients + * to direct form LPC filter coefficients. The direct form coefficients + * are scaled by multiplication by swAscale. NP, the filter order is 10. + * The a's and rc's each have NP elements in them. Double precision + * calculations are used internally. + * + * The equations are: + * for i = 0 to NP-1{ + * + * a(i)(i) = rc(i) (scaling by swAscale occurs here) + * + * for j = 0 to i-1 + * a(i)(j) = a(i-1)(j) + rc(i)*a(i-1)(i-j-1) + * } + * + * See page 443, of + * "Digital Processing of Speech Signals" by L.R. Rabiner and R.W. + * Schafer; Prentice-Hall; Englewood Cliffs, NJ (USA). 1978. + * + * REFERENCES: Sub-clause 4.1.7 and 4.2.3 of GSM Recomendation 06.20 + * + * KEYWORDS: reflectioncoefficients, parcors, conversion, rctoadp, ks, as + * KEYWORDS: parcorcoefficients, lpc, flat, vectorquantization + * + *************************************************************************/ + + short Codec::rcToADp(int16_t swAscale, int16_t pswRc[], + int16_t pswA[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t pL_ASpace[NP], + pL_tmpSpace[NP], + L_temp, + *pL_A, + *pL_tmp, + *pL_swap; + + short int i, + j, /* loop counters */ + siLimit; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Initialize starting addresses for temporary buffers */ + /*-----------------------------------------------------*/ + + pL_A = pL_ASpace; + pL_tmp = pL_tmpSpace; + + /* Initialize the flag for checking if limiting has occured */ + /*----------------------------------------------------------*/ + + siLimit = 0; + + /* Compute direct form filter coefficients, pswA[0],...,pswA[9] */ + /*-------------------------------------------------------------------*/ + + for (i = 0; i < NP; i++) + { + + pL_tmp[i] = L_mult(swAscale, pswRc[i]); + for (j = 0; j <= i - 1; j++) + { + L_temp = L_mpy_ls(pL_A[i - j - 1], pswRc[i]); + pL_tmp[j] = L_add(L_temp, pL_A[j]); + siLimit |= isLwLimit(pL_tmp[j]); + } + if (i != NP - 1) + { + /* Swap swA and swTmp buffers */ + + pL_swap = pL_tmp; + pL_tmp = pL_A; + pL_A = pL_swap; + } + } + + for (i = 0; i < NP; i++) + { + pswA[i] = round(pL_tmp[i]); + siLimit |= isSwLimit(pswA[i]); + } + return (siLimit); + } + + /*************************************************************************** + * + * FUNCTION NAME: rcToCorrDpL + * + * PURPOSE: + * + * This subroutine computes an autocorrelation vector, given a vector + * of reflection coefficients as an input. Double precision calculations + * are used internally, and a double precision (int32_t) + * autocorrelation sequence is returned. + * + * INPUTS: + * + * NP + * LPC filter order passed in as a global constant. + * + * swAshift + * Number of right shifts to be applied to the + * direct form filter coefficients being computed + * as an intermediate step to generating the + * autocorrelation sequence. + * + * swAscale + * A multiplicative scale factor corresponding to + * swAshift; i.e. swAscale = 2 ^(-swAshift). + * + * pswRc[0:NP-1] + * An input vector of reflection coefficients. + * + * OUTPUTS: + * + * pL_R[0:NP] + * An output int32_t array containing the + * autocorrelation vector where + * pL_R[0] = 0x7fffffff; (i.e., ~1.0). + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * The algorithm used for computing the correlation sequence is + * described on page 232 of the book "Linear Prediction of Speech", + * by J.D. Markel and A.H. Gray, Jr.; Springer-Verlag, Berlin, + * Heidelberg, New York, 1976. + * + * REFERENCES: Sub_Clause 4.1.4 and 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: normalized autocorrelation, reflection coefficients + * KEYWORDS: conversion + * + **************************************************************************/ + + void Codec::rcToCorrDpL(int16_t swAshift, int16_t swAscale, + int16_t pswRc[], int32_t pL_R[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t pL_ASpace[NP], + pL_tmpSpace[NP], + L_temp, + L_sum, + *pL_A, + *pL_tmp, + *pL_swap; + + short int i, + j; /* loop control variables */ + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Set R[0] = 0x7fffffff, (i.e., R[0] = 1.0) */ + /*-------------------------------------------*/ + + pL_R[0] = LW_MAX; + + /* Assign an address onto each of the two temporary buffers */ + /*----------------------------------------------------------*/ + + pL_A = pL_ASpace; + pL_tmp = pL_tmpSpace; + + /* Compute correlations R[1],...,R[10] */ + /*------------------------------------*/ + + for (i = 0; i < NP; i++) + { + + /* Compute, as an intermediate step, the filter coefficients for */ + /* for an i-th order direct form filter (pL_tmp[j],j=0,i) */ + /*---------------------------------------------------------------*/ + + pL_tmp[i] = L_mult(swAscale, pswRc[i]); + for (j = 0; j <= i - 1; j++) + { + L_temp = L_mpy_ls(pL_A[i - j - 1], pswRc[i]); + pL_tmp[j] = L_add(L_temp, pL_A[j]); + } + + /* Swap pL_A and pL_tmp buffers */ + /*------------------------------*/ + + pL_swap = pL_A; + pL_A = pL_tmp; + pL_tmp = pL_swap; + + /* Given the direct form filter coefficients for an i-th order filter */ + /* and the autocorrelation vector computed up to and including stage i */ + /* compute the autocorrelation coefficient R[i+1] */ + /*---------------------------------------------------------------------*/ + + L_temp = L_mpy_ll(pL_A[0], pL_R[i]); + L_sum = L_negate(L_temp); + + for (j = 1; j <= i; j++) + { + L_temp = L_mpy_ll(pL_A[j], pL_R[i - j]); + L_sum = L_sub(L_sum, L_temp); + } + pL_R[i + 1] = L_shl(L_sum, swAshift); + + } + } + + /*************************************************************************** + * + * FUNCTION NAME: res_eng + * + * PURPOSE: + * + * Calculates square root of subframe residual energy estimate: + * + * sqrt( R(0)(1-k1**2)...(1-k10**2) ) + * + * INPUTS: + * + * pswReflecCoefIn[0:9] + * + * Array of reflection coeffcients. + * + * swRq + * + * Subframe energy = sqrt(frame_energy * S_LEN/2**S_SH) + * (quantized). + * + * OUTPUTS: + * + * psnsSqrtRsOut + * + * (Pointer to) the output residual energy estimate. + * + * RETURN VALUE: + * + * The shift count of the normalized residual energy estimate, as int. + * + * DESCRIPTION: + * + * First, the canonic product of the (1-ki**2) terms is calculated + * (normalizations are done to maintain precision). Also, a factor of + * 2**S_SH is applied to the product to offset this same factor in the + * quantized square root of the subframe energy. + * + * Then the product is square-rooted, and multiplied by the quantized + * square root of the subframe energy. This combined product is put + * out as a normalized fraction and shift count (mantissa and exponent). + * + * REFERENCES: Sub-clause 4.1.7 and 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: residualenergy, res_eng, rs + * + *************************************************************************/ + + void Codec::res_eng(int16_t pswReflecCoefIn[], int16_t swRq, + struct NormSw *psnsSqrtRsOut) + { + /*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| + */ + + #define S_SH 6 /* ceiling(log2(S_LEN)) */ + #define MINUS_S_SH -S_SH + + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_Product, + L_Shift, + L_SqrtResEng; + + int16_t swPartialProduct, + swPartialProductShift, + swTerm, + swShift, + swSqrtPP, + swSqrtPPShift, + swSqrtResEng, + swSqrtResEngShift; + + short int i; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Form canonic product, maintain precision and shift count */ + /*----------------------------------------------------------*/ + + /* (Start off with unity product (actually -1), and shift offset) */ + /*----------------------------------------------------------------*/ + swPartialProduct = SW_MIN; + swPartialProductShift = MINUS_S_SH; + + for (i = 0; i < NP; i++) + { + + /* Get next (-1 + k**2) term, form partial canonic product */ + /*---------------------------------------------------------*/ + + + swTerm = mac_r(LW_MIN, pswReflecCoefIn[i], pswReflecCoefIn[i]); + + L_Product = L_mult(swTerm, swPartialProduct); + + /* Normalize partial product, round */ + /*----------------------------------*/ + + swShift = norm_s(extract_h(L_Product)); + swPartialProduct = round(L_shl(L_Product, swShift)); + swPartialProductShift = add(swPartialProductShift, swShift); + } + + /* Correct sign of product, take square root */ + /*-------------------------------------------*/ + + swPartialProduct = abs_s(swPartialProduct); + + swSqrtPP = sqroot(L_deposit_h(swPartialProduct)); + + L_Shift = L_shr(L_deposit_h(swPartialProductShift), 1); + + swSqrtPPShift = extract_h(L_Shift); + + if (extract_l(L_Shift) != 0) + { + + /* Odd exponent: shr above needs to be compensated by multiplying */ + /* mantissa by sqrt(0.5) */ + /*----------------------------------------------------------------*/ + + swSqrtPP = mult_r(swSqrtPP, SQRT_ONEHALF); + } + + /* Form final product, the residual energy estimate, and do final */ + /* normalization */ + /*----------------------------------------------------------------*/ + + L_SqrtResEng = L_mult(swRq, swSqrtPP); + + swShift = norm_l(L_SqrtResEng); + swSqrtResEng = round(L_shl(L_SqrtResEng, swShift)); + swSqrtResEngShift = add(swSqrtPPShift, swShift); + + /* Return */ + /*--------*/ + psnsSqrtRsOut->man = swSqrtResEng; + psnsSqrtRsOut->sh = swSqrtResEngShift; + + return; + } + + /*************************************************************************** + * + * FUNCTION NAME: rs_rr + * + * PURPOSE: + * + * Calculates sqrt(RS/R(x,x)) using floating point format, + * where RS is the approximate residual energy in a given + * subframe and R(x,x) is the power in each long term + * predictor vector or in each codevector. + * Used in the joint optimization of the gain and the long + * term predictor coefficient. + * + * INPUTS: + * + * pswExcitation[0:39] - excitation signal array + * snsSqrtRs - structure sqrt(RS) normalized with mantissa and shift + * + * OUTPUTS: + * + * snsSqrtRsRr - structure sqrt(RS/R(x,x)) with mantissa and shift + * + * RETURN VALUE: + * + * None + * + * DESCRIPTION: + * + * Implemented as sqrt(RS)/sqrt(R(x,x)) where both sqrts + * are stored normalized (0.5<=x<1.0) and the associated + * shift. See section 4.1.11.1 for details + * + * REFERENCES: Sub-clause 4.1.11.1 and 4.2.1 of GSM + * Recomendation 06.20 + * + * KEYWORDS: rs_rr, sqroot + * + *************************************************************************/ + + void Codec::rs_rr(int16_t pswExcitation[], struct NormSw snsSqrtRs, + struct NormSw *snsSqrtRsRr) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + int32_t L_Temp; + int16_t swTemp, + swTemp2, + swEnergy, + swNormShift, + swShift; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + swEnergy = sub(shl(snsSqrtRs.sh, 1), 3); /* shift*2 + margin == + * energy. */ + + + if (swEnergy < 0) + { + + /* High-energy residual: scale input vector during energy */ + /* calculation. The shift count of the energy of the */ + /* residual estimate is used as an estimate of the shift */ + /* count needed for the excitation energy */ + /*--------------------------------------------------------*/ + + swNormShift = g_corr1s(pswExcitation, negate(swEnergy), &L_Temp); + + } + else + { + + /* Lower-energy residual: no overflow protection needed */ + /*------------------------------------------------------*/ + + swNormShift = g_corr1(pswExcitation, &L_Temp); + } + + /* Compute single precision square root of energy sqrt(R(x,x)) */ + /* ----------------------------------------------------------- */ + swTemp = sqroot(L_Temp); + + /* If odd no. of shifts compensate by sqrt(0.5) */ + /* -------------------------------------------- */ + if (swNormShift & 1) + { + + /* Decrement no. of shifts in accordance with sqrt(0.5) */ + /* ---------------------------------------------------- */ + swNormShift = sub(swNormShift, 1); + + /* sqrt(R(x,x) = sqrt(R(x,x)) * sqrt(0.5) */ + /* -------------------------------------- */ + L_Temp = L_mult(0x5a82, swTemp); + } + else + { + L_Temp = L_deposit_h(swTemp); + } + + /* Normalize again and update shifts */ + /* --------------------------------- */ + swShift = norm_l(L_Temp); + swNormShift = add(shr(swNormShift, 1), swShift); + L_Temp = L_shl(L_Temp, swShift); + + /* Shift sqrt(RS) to make sure less than divisor */ + /* --------------------------------------------- */ + swTemp = shr(snsSqrtRs.man, 1); + + /* Divide sqrt(RS)/sqrt(R(x,x)) */ + /* ---------------------------- */ + swTemp2 = divide_s(swTemp, round(L_Temp)); + + /* Calculate shift for division, compensate for shift before division */ + /* ------------------------------------------------------------------ */ + swNormShift = sub(snsSqrtRs.sh, swNormShift); + swNormShift = sub(swNormShift, 1); + + /* Normalize and get no. of shifts */ + /* ------------------------------- */ + swShift = norm_s(swTemp2); + snsSqrtRsRr->sh = add(swNormShift, swShift); + snsSqrtRsRr->man = shl(swTemp2, swShift); + + } + + /*************************************************************************** + * + * FUNCTION NAME: rs_rrNs + * + * PURPOSE: + * + * Calculates sqrt(RS/R(x,x)) using floating point format, + * where RS is the approximate residual energy in a given + * subframe and R(x,x) is the power in each long term + * predictor vector or in each codevector. + * + * Used in the joint optimization of the gain and the long + * term predictor coefficient. + * + * INPUTS: + * + * pswExcitation[0:39] - excitation signal array + * snsSqrtRs - structure sqrt(RS) normalized with mantissa and shift + * + * OUTPUTS: + * + * snsSqrtRsRr - structure sqrt(RS/R(x,x)) with mantissa and shift + * + * RETURN VALUE: + * + * None + * + * DESCRIPTION: + * + * Implemented as sqrt(RS)/sqrt(R(x,x)) where both sqrts + * are stored normalized (0.5<=x<1.0) and the associated + * shift. + * + * REFERENCES: Sub-clause 4.1.11.1 and 4.2.1 of GSM + * Recomendation 06.20 + * + * KEYWORDS: rs_rr, sqroot + * + *************************************************************************/ + + void Codec::rs_rrNs(int16_t pswExcitation[], struct NormSw snsSqrtRs, + struct NormSw *snsSqrtRsRr) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + int32_t L_Temp; + int16_t swTemp, + swTemp2, + swNormShift, + swShift; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Lower-energy residual: no overflow protection needed */ + /*------------------------------------------------------*/ + + swNormShift = g_corr1(pswExcitation, &L_Temp); + + + /* Compute single precision square root of energy sqrt(R(x,x)) */ + /* ----------------------------------------------------------- */ + swTemp = sqroot(L_Temp); + + /* If odd no. of shifts compensate by sqrt(0.5) */ + /* -------------------------------------------- */ + if (swNormShift & 1) + { + + /* Decrement no. of shifts in accordance with sqrt(0.5) */ + /* ---------------------------------------------------- */ + swNormShift = sub(swNormShift, 1); + + /* sqrt(R(x,x) = sqrt(R(x,x)) * sqrt(0.5) */ + /* -------------------------------------- */ + L_Temp = L_mult(0x5a82, swTemp); + } + else + { + L_Temp = L_deposit_h(swTemp); + } + + /* Normalize again and update shifts */ + /* --------------------------------- */ + + swShift = norm_l(L_Temp); + swNormShift = add(shr(swNormShift, 1), swShift); + L_Temp = L_shl(L_Temp, swShift); + + /* Shift sqrt(RS) to make sure less than divisor */ + /* --------------------------------------------- */ + swTemp = shr(snsSqrtRs.man, 1); + + /* Divide sqrt(RS)/sqrt(R(x,x)) */ + /* ---------------------------- */ + swTemp2 = divide_s(swTemp, round(L_Temp)); + + /* Calculate shift for division, compensate for shift before division */ + /* ------------------------------------------------------------------ */ + swNormShift = sub(snsSqrtRs.sh, swNormShift); + swNormShift = sub(swNormShift, 1); + + /* Normalize and get no. of shifts */ + /* ------------------------------- */ + swShift = norm_s(swTemp2); + snsSqrtRsRr->sh = add(swNormShift, swShift); + snsSqrtRsRr->man = shl(swTemp2, swShift); + + } + + + /*************************************************************************** + * + * FUNCTION NAME: scaleExcite + * + * PURPOSE: + * + * Scale an arbitrary excitation vector (codevector or + * pitch vector) + * + * INPUTS: + * + * pswVect[0:39] - the unscaled vector. + * iGsp0Scale - an positive offset to compensate for the fact + * that GSP0 table is scaled down. + * swErrTerm - rather than a gain being passed in, (beta, gamma) + * it is calculated from this error term - either + * Gsp0[][][0] error term A or Gsp0[][][1] error + * term B. Beta is calculated from error term A, + * gamma from error term B. + * snsRS - the RS_xx appropriate to pswVect. + * + * OUTPUTS: + * + * pswScldVect[0:39] - the output, scaled excitation vector. + * + * RETURN VALUE: + * + * swGain - One of two things. Either a clamped value of 0x7fff if the + * gain's shift was > 0 or the rounded vector gain otherwise. + * + * DESCRIPTION: + * + * If gain > 1.0 then + * (do not shift gain up yet) + * partially scale vector element THEN shift and round save + * else + * shift gain correctly + * scale vector element and round save + * update state array + * + * REFERENCES: Sub-clause 4.1.10.2 and 4.2.1 of GSM + * Recomendation 06.20 + * + * KEYWORDS: excite_vl, sc_ex, excitevl, scaleexcite, codevector, p_vec, + * KEYWORDS: x_vec, pitchvector, gain, gsp0 + * + *************************************************************************/ + + int16_t Codec::scaleExcite(int16_t pswVect[], + int16_t swErrTerm, struct NormSw snsRS, + int16_t pswScldVect[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + int32_t L_GainUs, + L_scaled, + L_Round_off; + int16_t swGain, + swGainUs, + swGainShift, + i, + swGainUsShft; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + + L_GainUs = L_mult(swErrTerm, snsRS.man); + swGainUsShft = norm_s(extract_h(L_GainUs)); + L_GainUs = L_shl(L_GainUs, swGainUsShft); + + swGainShift = add(swGainUsShft, snsRS.sh); + swGainShift = sub(swGainShift, GSP0_SCALE); + + + /* gain > 1.0 */ + /* ---------- */ + + if (swGainShift < 0) + { + swGainUs = round(L_GainUs); + + L_Round_off = L_shl((long) 32768, swGainShift); + + for (i = 0; i < S_LEN; i++) + { + L_scaled = L_mac(L_Round_off, swGainUs, pswVect[i]); + L_scaled = L_shr(L_scaled, swGainShift); + pswScldVect[i] = extract_h(L_scaled); + } + + if (swGainShift == 0) + swGain = swGainUs; + else + swGain = 0x7fff; + } + + /* gain < 1.0 */ + /* ---------- */ + + else + { + + /* shift down or not at all */ + /* ------------------------ */ + if (swGainShift > 0) + L_GainUs = L_shr(L_GainUs, swGainShift); + + /* the rounded actual vector gain */ + /* ------------------------------ */ + swGain = round(L_GainUs); + + /* now scale the vector (with rounding) */ + /* ------------------------------------ */ + + for (i = 0; i < S_LEN; i++) + { + L_scaled = L_mac((long) 32768, swGain, pswVect[i]); + pswScldVect[i] = extract_h(L_scaled); + } + } + return (swGain); + } + + /*************************************************************************** + * + * FUNCTION NAME: spectralPostFilter + * + * PURPOSE: + * + * Perform spectral post filter on the output of the + * synthesis filter. + * + * + * INPUT: + * + * S_LEN a global constant + * + * pswSPFIn[0:S_LEN-1] + * + * input to the routine. Unmodified + * pswSPFIn[0] is the oldest point (first to be filtered), + * pswSPFIn[iLen-1] is the last pointer filtered, + * the newest. + * + * pswNumCoef[0:NP-1],pswDenomCoef[0:NP-1] + * + * numerator and denominator + * direct form coeffs used by postfilter. + * Exactly like lpc coefficients in format. Shifted down + * by iAShift to ensure that they are < 1.0. + * + * gpswPostFiltStateNum[0:NP-1], gpswPostFiltStateDenom[0:NP-1] + * + * array of the filter state. + * Same format as coefficients: *praState = state of + * filter for delay n = -1 praState[NP] = state of + * filter for delay n = -NP These numbers are not + * shifted at all. These states are static to this + * file. + * + * OUTPUT: + * + * gpswPostFiltStateNum[0:NP-1], gpswPostFiltStateDenom[0:NP-1] + * + * See above for description. These are updated. + * + * pswSPFOut[0:S_LEN-1] + * + * same format as pswSPFIn, + * *pswSPFOut is oldest point. The filtered output. + * Note this routine can handle pswSPFOut = pswSPFIn. + * output can be the same as input. i.e. in place + * calculation. + * + * RETURN: + * + * none + * + * DESCRIPTION: + * + * find energy in input, + * perform the numerator fir + * perform the denominator iir + * perform the post emphasis + * find energy in signal, + * perform the agc using energy in and energy in signam after + * post emphasis signal + * + * The spectral postfilter is described in section 4.2.4. + * + * REFERENCES: Sub-clause 4.2.4 of GSM Recomendation 06.20 + * + * KEYWORDS: postfilter, emphasis, postemphasis, brightness, + * KEYWORDS: numerator, deminator, filtering, lpc, + * + *************************************************************************/ + + void Codec::spectralPostFilter(int16_t pswSPFIn[], + int16_t pswNumCoef[], + int16_t pswDenomCoef[], int16_t pswSPFOut[]) + { + /*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| + */ + + #define AGC_COEF (int16_t)0x19a /* (1.0 - POST_AGC_COEF) + * 1.0-.9875 */ + #define POST_EMPHASIS (int16_t)0x199a /* 0.2 */ + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + short int i; + + int32_t L_OrigEnergy, + L_runningGain, + L_Output; + + int16_t swAgcGain, + swRunningGain, + swTemp; + + struct NormSw snsOrigEnergy; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* calculate the energy in the input and save it */ + /*-----------------------------------------------*/ + + snsOrigEnergy.sh = g_corr1s(pswSPFIn, swEngyRShift, &L_OrigEnergy); + snsOrigEnergy.man = round(L_OrigEnergy); + + /* numerator of the postfilter */ + /*-----------------------------*/ + + lpcFir(pswSPFIn, pswNumCoef, gpswPostFiltStateNum, pswSPFOut); + + /* denominator of the postfilter */ + /*-------------------------------*/ + + lpcIir(pswSPFOut, pswDenomCoef, gpswPostFiltStateDenom, pswSPFOut); + + /* postemphasis section of postfilter */ + /*------------------------------------*/ + + for (i = 0; i < S_LEN; i++) + { + swTemp = msu_r(L_deposit_h(pswSPFOut[i]), swPostEmphasisState, + POST_EMPHASIS); + swPostEmphasisState = pswSPFOut[i]; + pswSPFOut[i] = swTemp; + } + + swAgcGain = agcGain(pswSPFOut, snsOrigEnergy, swEngyRShift); + + /* scale the speech vector */ + /*-----------------------------*/ + + swRunningGain = gswPostFiltAgcGain; + L_runningGain = L_deposit_h(gswPostFiltAgcGain); + for (i = 0; i < S_LEN; i++) + { + L_runningGain = L_msu(L_runningGain, swRunningGain, AGC_COEF); + L_runningGain = L_mac(L_runningGain, swAgcGain, AGC_COEF); + swRunningGain = extract_h(L_runningGain); + + /* now scale input with gain */ + + L_Output = L_mult(swRunningGain, pswSPFOut[i]); + pswSPFOut[i] = extract_h(L_shl(L_Output, 2)); + } + gswPostFiltAgcGain = swRunningGain; + + } + + /*************************************************************************** + * + * FUNCTION NAME: speechDecoder + * + * PURPOSE: + * The purpose of this function is to call all speech decoder + * subroutines. This is the top level routine for the speech + * decoder. + * + * INPUTS: + * + * pswParameters[0:21] + * + * pointer to this frame's parameters. See below for input + * data format. + * + * OUTPUTS: + * + * pswDecodedSpeechFrame[0:159] + * + * this frame's decoded 16 bit linear pcm frame + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * The sequence of events in the decoder, and therefore this routine + * follow a simple plan. First, the frame based parameters are + * decoded. Second, on a subframe basis, the subframe based + * parameters are decoded and the excitation is generated. Third, + * on a subframe basis, the combined and scaled excitation is + * passed through the synthesis filter, and then the pitch and + * spectral postfilters. + * + * The in-line comments for the routine speechDecoder, are very + * detailed. Here in a more consolidated form, are the main + * points. + * + * The R0 parameter is decoded using the lookup table + * psrR0DecTbl[]. The LPC codewords are looked up using lookupVQ(). + * The decoded parameters are reflection coefficients + * (pswFrmKs[]). + * + * The decoder does not use reflection coefficients directly. + * Instead it converts them to direct form coeficients. This is + * done using rcToADp(). If this conversion results in invalid + * results, the previous frames parameters are used. + * + * The direct form coeficients are used to derive the spectal + * postfilter's numerator and denominator coeficients. The + * denominators coefficients are widened, and the numerators + * coefficients are a spectrally smoothed version of the + * denominator. The smoothing is done with a_sst(). + * + * The frame based LPC coefficients are either used directly as the + * subframe coefficients, or are derived through interpolation. + * The subframe based coeffiecients are calculated in getSfrmLpc(). + * + * Based on voicing mode, the decoder will construct and scale the + * excitation in one of two ways. For the voiced mode the lag is + * decoded using lagDecode(). The fractional pitch LTP lookup is + * done by the function fp_ex(). In both voiced and unvoiced + * mode, the VSELP codewords are decoded into excitation vectors + * using b_con() and v_con(). + * + * rs_rr(), rs_rrNs(), and scaleExcite() are used to calculate + * the gamma's, codevector gains, as well as beta, the LTP vector + * gain. Description of this can be found in section 4.1.11. Once + * the vectors have been scaled and combined, the excitation is + * stored in the LTP history. + * + * The excitation, pswExcite[], passes through the pitch pre-filter + * (pitchPreFilt()). Then the harmonically enhanced excitation + * passes through the synthesis filter, lpcIir(), and finally the + * reconstructed speech passes through the spectral post-filter + * (spectalPostFilter()). The final output speech is passed back in + * the array pswDecodedSpeechFrame[]. + * + * INPUT DATA FORMAT: + * + * The format/content of the input parameters is the so called + * bit alloc format. + * + * voiced mode bit alloc format: + * ----------------------------- + * index number of bits parameter name + * 0 5 R0 + * 1 11 k1Tok3 + * 2 9 k4Tok6 + * 3 8 k7Tok10 + * 4 1 softInterpolation + * 5 2 voicingDecision + * 6 8 frameLag + * 7 9 code_1 + * 8 5 gsp0_1 + * 9 4 deltaLag_2 + * 10 9 code_2 + * 11 5 gsp0_2 + * 12 4 deltaLag_3 + * 13 9 code_3 + * 14 5 gsp0_3 + * 15 4 deltaLag_4 + * 16 9 code_4 + * 17 5 gsp0_4 + * + * 18 1 BFI + * 19 1 UFI + * 20 2 SID + * 21 1 TAF + * + * + * unvoiced mode bit alloc format: + * ------------------------------- + * + * index number of bits parameter name + * 0 5 R0 + * 1 11 k1Tok3 + * 2 9 k4Tok6 + * 3 8 k7Tok10 + * 4 1 softInterpolation + * 5 2 voicingDecision + * 6 7 code1_1 + * 7 7 code2_1 + * 8 5 gsp0_1 + * 9 7 code1_2 + * 10 7 code2_2 + * 11 5 gsp0_2 + * 12 7 code1_3 + * 13 7 code2_3 + * 14 5 gsp0_3 + * 15 7 code1_4 + * 16 7 code2_4 + * 17 5 gsp0_4 + * + * 18 1 BFI + * 19 1 UFI + * 20 2 SID + * 21 1 TAF + * + * + * REFERENCES: Sub_Clause 4.2 of GSM Recomendation 06.20 + * + * KEYWORDS: synthesis, speechdecoder, decoding + * KEYWORDS: codewords, lag, codevectors, gsp0 + * + *************************************************************************/ + + void Codec::speechDecoder(int16_t pswParameters[], + int16_t pswDecodedSpeechFrame[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + short int i, + j, + siLagCode, + siGsp0Code, + psiVselpCw[2], + siVselpCw, + siNumBits, + siCodeBook; + + int16_t pswFrmKs[NP], + pswFrmAs[NP], + pswFrmPFNum[NP], + pswFrmPFDenom[NP], + pswPVec[S_LEN], + ppswVselpEx[2][S_LEN], + pswExcite[S_LEN], + pswPPFExcit[S_LEN], + pswSynthFiltOut[S_LEN], + swR0Index, + swLag, + swSemiBeta, + pswBitArray[MAXBITS]; + + struct NormSw psnsSqrtRs[N_SUB], + snsRs00, + snsRs11, + snsRs22; + + + int16_t swMutePermit, + swLevelMean, + swLevelMax, /* error concealment */ + swMuteFlag; /* error concealment */ + + + int16_t swTAF, + swSID, + swBfiDtx; /* DTX mode */ + int16_t swFrameType; /* DTX mode */ + + int32_t L_RxDTXGs; /* DTX mode */ + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* -------------------------------------------------------------------- */ + /* do bad frame handling (error concealment) and comfort noise */ + /* insertion */ + /* -------------------------------------------------------------------- */ + + + /* This flag indicates whether muting is performed in the actual frame */ + /* ------------------------------------------------------------------- */ + swMuteFlag = 0; + + + /* This flag indicates whether muting is allowed in the actual frame */ + /* ----------------------------------------------------------------- */ + swMutePermit = 0; + + + /* frame classification */ + /* -------------------- */ + + swSID = pswParameters[20]; + swTAF = pswParameters[21]; + + swBfiDtx = pswParameters[18] | pswParameters[19]; /* BFI | UFI */ + + if ((swSID == 2) && (swBfiDtx == 0)) + swFrameType = VALIDSID; + else if ((swSID == 0) && (swBfiDtx == 0)) + swFrameType = GOODSPEECH; + else if ((swSID == 0) && (swBfiDtx != 0)) + swFrameType = UNUSABLE; + else + swFrameType = INVALIDSID; + + + /* update of decoder state */ + /* ----------------------- */ + + if (swDecoMode == SPEECH) + { + /* speech decoding mode */ + /* -------------------- */ + + if (swFrameType == VALIDSID) + swDecoMode = CNIFIRSTSID; + else if (swFrameType == INVALIDSID) + swDecoMode = CNIFIRSTSID; + else if (swFrameType == UNUSABLE) + swDecoMode = SPEECH; + else if (swFrameType == GOODSPEECH) + swDecoMode = SPEECH; + } + else + { + /* comfort noise insertion mode */ + /* ---------------------------- */ + + if (swFrameType == VALIDSID) + swDecoMode = CNICONT; + else if (swFrameType == INVALIDSID) + swDecoMode = CNICONT; + else if (swFrameType == UNUSABLE) + swDecoMode = CNIBFI; + else if (swFrameType == GOODSPEECH) + swDecoMode = SPEECH; + } + + + if (swDecoMode == SPEECH) + { + /* speech decoding mode */ + /* -------------------- */ + + /* Perform parameter concealment, depending on BFI (pswParameters[18]) */ + /* or UFI (pswParameters[19]) */ + /* ------------------------------------------------------------------- */ + para_conceal_speech_decoder(&pswParameters[18], + pswParameters, &swMutePermit); + + + /* copy the frame rate parameters */ + /* ------------------------------ */ + + swR0Index = pswParameters[0]; /* R0 Index */ + pswVq[0] = pswParameters[1]; /* LPC1 */ + pswVq[1] = pswParameters[2]; /* LPC2 */ + pswVq[2] = pswParameters[3]; /* LPC3 */ + swSi = pswParameters[4]; /* INT_LPC */ + swVoicingMode = pswParameters[5]; /* MODE */ + + + /* lookup R0 and VQ parameters */ + /* --------------------------- */ + + swR0Dec = psrR0DecTbl[swR0Index * 2]; /* R0 */ + lookupVq(pswVq, pswFrmKs); + + + /* save this frames GS values */ + /* -------------------------- */ + + for (i = 0; i < N_SUB; i++) + { + pL_RxGsHist[swRxGsHistPtr] = + ppLr_gsTable[swVoicingMode][pswParameters[(i * 3) + 8]]; + swRxGsHistPtr++; + if (swRxGsHistPtr > ((OVERHANG - 1) * N_SUB) - 1) + swRxGsHistPtr = 0; + } + + + /* DTX variables */ + /* ------------- */ + + swDtxBfiCnt = 0; + swDtxMuting = 0; + swRxDTXState = CNINTPER - 1; + + } + else + { + /* comfort noise insertion mode */ + /*----------------------------- */ + + /* copy the frame rate parameters */ + /* ------------------------------ */ + + swR0Index = pswParameters[0]; /* R0 Index */ + pswVq[0] = pswParameters[1]; /* LPC1 */ + pswVq[1] = pswParameters[2]; /* LPC2 */ + pswVq[2] = pswParameters[3]; /* LPC3 */ + swSi = 1; /* INT_LPC */ + swVoicingMode = 0; /* MODE */ + + + /* bad frame handling in comfort noise insertion mode */ + /* -------------------------------------------------- */ + + if (swDecoMode == CNIFIRSTSID) /* first SID frame */ + { + swDtxBfiCnt = 0; + swDtxMuting = 0; + swRxDTXState = CNINTPER - 1; + + if (swFrameType == VALIDSID) /* valid SID frame */ + { + swR0NewCN = psrR0DecTbl[swR0Index * 2]; + lookupVq(pswVq, pswFrmKs); + } + else if (swFrameType == INVALIDSID) /* invalid SID frame */ + { + swR0NewCN = psrR0DecTbl[swOldR0IndexDec * 2]; + swR0Index = swOldR0IndexDec; + for (i = 0; i < NP; i++) + pswFrmKs[i] = pswOldFrmKsDec[i]; + } + + } + else if (swDecoMode == CNICONT) /* SID frame detected, but */ + { /* not the first SID */ + swDtxBfiCnt = 0; + swDtxMuting = 0; + + if (swFrameType == VALIDSID) /* valid SID frame */ + { + swRxDTXState = 0; + swR0NewCN = psrR0DecTbl[swR0Index * 2]; + lookupVq(pswVq, pswFrmKs); + } + else if (swFrameType == INVALIDSID) /* invalid SID frame */ + { + if (swRxDTXState < (CNINTPER - 1)) + swRxDTXState = add(swRxDTXState, 1); + swR0Index = swOldR0IndexDec; + } + + } + else if (swDecoMode == CNIBFI) /* bad frame received in */ + { /* CNI mode */ + if (swRxDTXState < (CNINTPER - 1)) + swRxDTXState = add(swRxDTXState, 1); + swR0Index = swOldR0IndexDec; + + if (swDtxMuting == 1) + { + swOldR0IndexDec = sub(swOldR0IndexDec, 2); /* attenuate + * by 4 dB */ + if (swOldR0IndexDec < 0) + swOldR0IndexDec = 0; + + swR0Index = swOldR0IndexDec; + + swR0NewCN = psrR0DecTbl[swOldR0IndexDec * 2]; /* R0 */ + + } + + swDtxBfiCnt = add(swDtxBfiCnt, 1); + if ((swTAF == 1) && (swDtxBfiCnt >= (2 * CNINTPER + 1))) /* 25 */ + swDtxMuting = 1; + + } + + + if (swDecoMode == CNIFIRSTSID) + { + + /* the first SID frame is received */ + /* ------------------------------- */ + + /* initialize the decoders pn-generator */ + /* ------------------------------------ */ + + L_RxPNSeed = PN_INIT_SEED; + + + /* using the stored rx history, generate averaged GS */ + /* ------------------------------------------------- */ + + avgGsHistQntz(pL_RxGsHist, &L_RxDTXGs); + swRxDtxGsIndex = gsQuant(L_RxDTXGs, 0); + + } + + + /* Replace the "transmitted" subframe parameters with */ + /* synthetic ones */ + /* -------------------------------------------------- */ + + for (i = 0; i < 4; i++) + { + /* initialize the GSP0 parameter */ + pswParameters[(i * 3) + 8] = swRxDtxGsIndex; + + /* CODE1 */ + pswParameters[(i * 3) + 6] = getPnBits(7, &L_RxPNSeed); + /* CODE2 */ + pswParameters[(i * 3) + 7] = getPnBits(7, &L_RxPNSeed); + } + + + /* Interpolation of CN parameters */ + /* ------------------------------ */ + + rxInterpR0Lpc(pswOldFrmKsDec, pswFrmKs, swRxDTXState, + swDecoMode, swFrameType); + + } + + + /* ------------------- */ + /* do frame processing */ + /* ------------------- */ + + /* generate the direct form coefs */ + /* ------------------------------ */ + + if (!rcToADp(ASCALE, pswFrmKs, pswFrmAs)) + { + + /* widen direct form coefficients using the widening coefs */ + /* ------------------------------------------------------- */ + + for (i = 0; i < NP; i++) + { + pswFrmPFDenom[i] = mult_r(pswFrmAs[i], psrSPFDenomWidenCf[i]); + } + + a_sst(ASHIFT, ASCALE, pswFrmPFDenom, pswFrmPFNum); + } + else + { + + + for (i = 0; i < NP; i++) + { + pswFrmKs[i] = pswOldFrmKsDec[i]; + pswFrmAs[i] = pswOldFrmAsDec[i]; + pswFrmPFDenom[i] = pswOldFrmPFDenom[i]; + pswFrmPFNum[i] = pswOldFrmPFNum[i]; + } + } + + /* interpolate, or otherwise get sfrm reflection coefs */ + /* --------------------------------------------------- */ + + getSfrmLpc(swSi, swOldR0Dec, swR0Dec, pswOldFrmKsDec, pswOldFrmAsDec, + pswOldFrmPFNum, pswOldFrmPFDenom, pswFrmKs, pswFrmAs, + pswFrmPFNum, pswFrmPFDenom, psnsSqrtRs, ppswSynthAs, + ppswPFNumAs, ppswPFDenomAs); + + /* calculate shift for spectral postfilter */ + /* --------------------------------------- */ + + swEngyRShift = r0BasedEnergyShft(swR0Index); + + + /* ----------------------- */ + /* do sub-frame processing */ + /* ----------------------- */ + + for (giSfrmCnt = 0; giSfrmCnt < 4; giSfrmCnt++) + { + + /* copy this sub-frame's parameters */ + /* -------------------------------- */ + + if (sub(swVoicingMode, 0) == 0) + { /* unvoiced */ + psiVselpCw[0] = pswParameters[(giSfrmCnt * 3) + 6]; /* CODE_1 */ + psiVselpCw[1] = pswParameters[(giSfrmCnt * 3) + 7]; /* CODE_2 */ + siGsp0Code = pswParameters[(giSfrmCnt * 3) + 8]; /* GSP0 */ + } + else + { /* voiced */ + siLagCode = pswParameters[(giSfrmCnt * 3) + 6]; /* LAG */ + psiVselpCw[0] = pswParameters[(giSfrmCnt * 3) + 7]; /* CODE */ + siGsp0Code = pswParameters[(giSfrmCnt * 3) + 8]; /* GSP0 */ + } + + /* for voiced mode, reconstruct the pitch vector */ + /* --------------------------------------------- */ + + if (swVoicingMode) + { + + /* convert delta lag to lag and convert to fractional lag */ + /* ------------------------------------------------------ */ + + swLag = lagDecode(siLagCode); + + /* state followed by out */ + /* --------------------- */ + + fp_ex(swLag, pswLtpStateOut); + + /* extract a piece of pswLtpStateOut into newly named vector pswPVec */ + /* ----------------------------------------------------------------- */ + + for (i = 0; i < S_LEN; i++) + { + pswPVec[i] = pswLtpStateOut[i]; + } + } + + /* for unvoiced, do not reconstruct a pitch vector */ + /* ----------------------------------------------- */ + + else + { + swLag = 0; /* indicates invalid lag + * and unvoiced */ + } + + /* now work on the VSELP codebook excitation output */ + /* x_vec, x_a_vec here named ppswVselpEx[0] and [1] */ + /* ------------------------------------------------ */ + + if (swVoicingMode) + { /* voiced */ + + siNumBits = C_BITS_V; + siVselpCw = psiVselpCw[0]; + + b_con(siVselpCw, siNumBits, pswBitArray); + + v_con(pppsrVcdCodeVec[0][0], ppswVselpEx[0], pswBitArray, siNumBits); + } + + else + { /* unvoiced */ + + siNumBits = C_BITS_UV; + + for (siCodeBook = 0; siCodeBook < 2; siCodeBook++) + { + + siVselpCw = psiVselpCw[siCodeBook]; + + b_con(siVselpCw, siNumBits, (int16_t *) pswBitArray); + + v_con(pppsrUvCodeVec[siCodeBook][0], ppswVselpEx[siCodeBook], + pswBitArray, siNumBits); + } + } + + /* all excitation vectors have been created: ppswVselpEx and pswPVec */ + /* if voiced compute rs00 and rs11; if unvoiced cmpute rs11 and rs22 */ + /* ------------------------------------------------------------------ */ + + if (swLag) + { + rs_rr(pswPVec, psnsSqrtRs[giSfrmCnt], &snsRs00); + } + + rs_rrNs(ppswVselpEx[0], psnsSqrtRs[giSfrmCnt], &snsRs11); + + if (!swVoicingMode) + { + rs_rrNs(ppswVselpEx[1], psnsSqrtRs[giSfrmCnt], &snsRs22); + } + + /* now implement synthesis - combine the excitations */ + /* ------------------------------------------------- */ + + if (swVoicingMode) + { /* voiced */ + + /* scale pitch and codebook excitations and get beta */ + /* ------------------------------------------------- */ + swSemiBeta = scaleExcite(pswPVec, + pppsrGsp0[swVoicingMode][siGsp0Code][0], + snsRs00, pswPVec); + scaleExcite(ppswVselpEx[0], + pppsrGsp0[swVoicingMode][siGsp0Code][1], + snsRs11, ppswVselpEx[0]); + + /* combine the two scaled excitations */ + /* ---------------------------------- */ + for (i = 0; i < S_LEN; i++) + { + pswExcite[i] = add(pswPVec[i], ppswVselpEx[0][i]); + } + } + else + { /* unvoiced */ + + /* scale codebook excitations and set beta to 0 as not applicable */ + /* -------------------------------------------------------------- */ + swSemiBeta = 0; + scaleExcite(ppswVselpEx[0], + pppsrGsp0[swVoicingMode][siGsp0Code][0], + snsRs11, ppswVselpEx[0]); + scaleExcite(ppswVselpEx[1], + pppsrGsp0[swVoicingMode][siGsp0Code][1], + snsRs22, ppswVselpEx[1]); + + /* combine the two scaled excitations */ + /* ---------------------------------- */ + for (i = 0; i < S_LEN; i++) + { + pswExcite[i] = add(ppswVselpEx[1][i], ppswVselpEx[0][i]); + } + } + + /* now update the pitch state using the combined/scaled excitation */ + /* --------------------------------------------------------------- */ + + for (i = 0; i < LTP_LEN; i++) + { + pswLtpStateBaseDec[i] = pswLtpStateBaseDec[i + S_LEN]; + } + + /* add the current sub-frames data to the state */ + /* -------------------------------------------- */ + + for (i = -S_LEN, j = 0; j < S_LEN; i++, j++) + { + pswLtpStateOut[i] = pswExcite[j];/* add new frame at t = -S_LEN */ + } + + /* given the excitation perform pitch prefiltering */ + /* ----------------------------------------------- */ + + pitchPreFilt(pswExcite, siGsp0Code, swLag, + swVoicingMode, swSemiBeta, psnsSqrtRs[giSfrmCnt], + pswPPFExcit, pswPPreState); + + + /* Concealment on subframe signal level: */ + /* ------------------------------------- */ + level_estimator(0, &swLevelMean, &swLevelMax, + &pswDecodedSpeechFrame[giSfrmCnt * S_LEN]); + + signal_conceal_sub(pswPPFExcit, ppswSynthAs[giSfrmCnt], pswSynthFiltState, + &pswLtpStateOut[-S_LEN], &pswPPreState[LTP_LEN - S_LEN], + swLevelMean, swLevelMax, + pswParameters[19], swMuteFlagOld, + &swMuteFlag, swMutePermit); + + + /* synthesize the speech through the synthesis filter */ + /* -------------------------------------------------- */ + + lpcIir(pswPPFExcit, ppswSynthAs[giSfrmCnt], pswSynthFiltState, + pswSynthFiltOut); + + /* pass reconstructed speech through adaptive spectral postfilter */ + /* -------------------------------------------------------------- */ + + spectralPostFilter(pswSynthFiltOut, ppswPFNumAs[giSfrmCnt], + ppswPFDenomAs[giSfrmCnt], + &pswDecodedSpeechFrame[giSfrmCnt * S_LEN]); + + level_estimator(1, &swLevelMean, &swLevelMax, + &pswDecodedSpeechFrame[giSfrmCnt * S_LEN]); + + } + + /* Save muting information for next frame */ + /* -------------------------------------- */ + swMuteFlagOld = swMuteFlag; + + /* end of frame processing - save this frame's frame energy, */ + /* reflection coefs, direct form coefs, and post filter coefs */ + /* ---------------------------------------------------------- */ + + swOldR0Dec = swR0Dec; + swOldR0IndexDec = swR0Index; /* DTX mode */ + + for (i = 0; i < NP; i++) + { + pswOldFrmKsDec[i] = pswFrmKs[i]; + pswOldFrmAsDec[i] = pswFrmAs[i]; + pswOldFrmPFNum[i] = pswFrmPFNum[i]; + pswOldFrmPFDenom[i] = pswFrmPFDenom[i]; + } + } + + + /*************************************************************************** + * + * FUNCTION NAME: sqroot + * + * PURPOSE: + * + * The purpose of this function is to perform a single precision square + * root function on a int32_t + * + * INPUTS: + * + * L_SqrtIn + * input to square root function + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swSqrtOut + * output to square root function + * + * DESCRIPTION: + * + * Input assumed to be normalized + * + * The algorithm is based around a six term Taylor expansion : + * + * y^0.5 = (1+x)^0.5 + * ~= 1 + (x/2) - 0.5*((x/2)^2) + 0.5*((x/2)^3) + * - 0.625*((x/2)^4) + 0.875*((x/2)^5) + * + * Max error less than 0.08 % for normalized input ( 0.5 <= x < 1 ) + * + * REFERENCES: Sub-clause 4.1.4.1, 4.1.7, 4.1.11.1, 4.2.1, + * 4.2.2, 4.2.3 and 4.2.4 of GSM Recomendation 06.20 + * + * KEYWORDS: sqrt, squareroot, sqrt016 + * + *************************************************************************/ + + int16_t Codec::sqroot(int32_t L_SqrtIn) + { + + /*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| + */ + + #define PLUS_HALF 0x40000000L /* 0.5 */ + #define MINUS_ONE 0x80000000L /* -1 */ + #define TERM5_MULTIPLER 0x5000 /* 0.625 */ + #define TERM6_MULTIPLER 0x7000 /* 0.875 */ + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_Temp0, + L_Temp1; + + int16_t swTemp, + swTemp2, + swTemp3, + swTemp4, + swSqrtOut; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* determine 2nd term x/2 = (y-1)/2 */ + /* -------------------------------- */ + + L_Temp1 = L_shr(L_SqrtIn, 1); /* L_Temp1 = y/2 */ + L_Temp1 = L_sub(L_Temp1, PLUS_HALF); /* L_Temp1 = (y-1)/2 */ + swTemp = extract_h(L_Temp1); /* swTemp = x/2 */ + + /* add contribution of 2nd term */ + /* ---------------------------- */ + + L_Temp1 = L_sub(L_Temp1, MINUS_ONE); /* L_Temp1 = 1 + x/2 */ + + /* determine 3rd term */ + /* ------------------ */ + + L_Temp0 = L_msu(0L, swTemp, swTemp); /* L_Temp0 = -(x/2)^2 */ + swTemp2 = extract_h(L_Temp0); /* swTemp2 = -(x/2)^2 */ + L_Temp0 = L_shr(L_Temp0, 1); /* L_Temp0 = -0.5*(x/2)^2 */ + + /* add contribution of 3rd term */ + /* ---------------------------- */ + + L_Temp0 = L_add(L_Temp1, L_Temp0); /* L_Temp0 = 1 + x/2 - 0.5*(x/2)^2 */ + + /* determine 4rd term */ + /* ------------------ */ + + L_Temp1 = L_msu(0L, swTemp, swTemp2);/* L_Temp1 = (x/2)^3 */ + swTemp3 = extract_h(L_Temp1); /* swTemp3 = (x/2)^3 */ + L_Temp1 = L_shr(L_Temp1, 1); /* L_Temp1 = 0.5*(x/2)^3 */ + + /* add contribution of 4rd term */ + /* ---------------------------- */ + + /* L_Temp1 = 1 + x/2 - 0.5*(x/2)^2 + 0.5*(x/2)^3 */ + + L_Temp1 = L_add(L_Temp0, L_Temp1); + + /* determine partial 5th term */ + /* -------------------------- */ + + L_Temp0 = L_mult(swTemp, swTemp3); /* L_Temp0 = (x/2)^4 */ + swTemp4 = round(L_Temp0); /* swTemp4 = (x/2)^4 */ + + /* determine partial 6th term */ + /* -------------------------- */ + + L_Temp0 = L_msu(0L, swTemp2, swTemp3); /* L_Temp0 = (x/2)^5 */ + swTemp2 = round(L_Temp0); /* swTemp2 = (x/2)^5 */ + + /* determine 5th term and add its contribution */ + /* ------------------------------------------- */ + + /* L_Temp0 = -0.625*(x/2)^4 */ + + L_Temp0 = L_msu(0L, TERM5_MULTIPLER, swTemp4); + + /* L_Temp1 = 1 + x/2 - 0.5*(x/2)^2 + 0.5*(x/2)^3 - 0.625*(x/2)^4 */ + + L_Temp1 = L_add(L_Temp0, L_Temp1); + + /* determine 6th term and add its contribution */ + /* ------------------------------------------- */ + + /* swSqrtOut = 1 + x/2 - 0.5*(x/2)^2 + 0.5*(x/2)^3 */ + /* - 0.625*(x/2)^4 + 0.875*(x/2)^5 */ + + swSqrtOut = mac_r(L_Temp1, TERM6_MULTIPLER, swTemp2); + + /* return output */ + /* ------------- */ + + return (swSqrtOut); + } + + /*************************************************************************** + * + * FUNCTION NAME: v_con + * + * PURPOSE: + * + * This subroutine constructs a codebook excitation + * vector from basis vectors + * + * INPUTS: + * + * pswBVects[0:siNumBVctrs*S_LEN-1] + * + * Array containing a set of basis vectors. + * + * pswBitArray[0:siNumBVctrs-1] + * + * Bit array dictating the polarity of the + * basis vectors in the output vector. + * Each element of the bit array is either -0.5 or +0.5 + * + * siNumBVctrs + * Number of bits in codeword + * + * OUTPUTS: + * + * pswOutVect[0:39] + * + * Array containing the contructed output vector + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * The array pswBitArray is used to multiply each of the siNumBVctrs + * basis vectors. The input pswBitArray[] is an array whose + * elements are +/-0.5. These multiply the VSELP basis vectors and + * when summed produce a VSELP codevector. b_con() is the function + * used to translate a VSELP codeword into pswBitArray[]. + * + * + * REFERENCES: Sub-clause 4.1.10 and 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: v_con, codeword, reconstruct, basis vector, excitation + * + *************************************************************************/ + + void Codec::v_con(int16_t pswBVects[], int16_t pswOutVect[], + int16_t pswBitArray[], short int siNumBVctrs) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_Temp; + + short int siSampleCnt, + siCVectCnt; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Sample loop */ + /*--------------*/ + for (siSampleCnt = 0; siSampleCnt < S_LEN; siSampleCnt++) + { + + /* First element of output vector */ + L_Temp = L_mult(pswBitArray[0], pswBVects[0 * S_LEN + siSampleCnt]); + + /* Construct output vector */ + /*-------------------------*/ + for (siCVectCnt = 1; siCVectCnt < siNumBVctrs; siCVectCnt++) + { + L_Temp = L_mac(L_Temp, pswBitArray[siCVectCnt], + pswBVects[siCVectCnt * S_LEN + siSampleCnt]); + } + + /* store the output vector sample */ + /*--------------------------------*/ + L_Temp = L_shl(L_Temp, 1); + pswOutVect[siSampleCnt] = extract_h(L_Temp); + } + } + + // from dtx.c + +#define PN_XOR_REG (int32_t)0x00000005L +#define PN_XOR_ADD (int32_t)0x40000000L + +#define OH_SHIFT 3 /* shift corresponding to OVERHANG */ + +#define NP_AFLAT 4 +#define LPC_VQ_SEG 3 + +#define ASHIFT 4 +#define ASCALE 0x0800 + + /* interpolation curve for comfort noise (i*1/12) i=1..12 */ + int16_t psrCNNewFactor[12] = {0x0aaa, 0x1554, 0x1ffe, 0x2aa8, 0x3552, + 0x3ffc, 0x4aa6, 0x5550, 0x5ffa, 0x6aa4, + 0x754e, 0x7fff}; + + + /* Values of GS for voicing state 0, all values shifted down by 2 + shifts */ + int32_tRom ppLr_gsTable[4][32] = + { + { + 0x000011ab, 0x000038d2, 0x0000773e, 0x000144ef, + 0x00035675, 0x000648c5, 0x000c3d65, 0x0017ae17, + 0x002a3dbb, 0x005238e7, 0x00695c1a, 0x00a60d45, + 0x00e4cc68, 0x01c3ba6a, 0x019e3c96, 0x02d1fbac, + 0x030453ec, 0x0549a998, 0x05190298, 0x08258920, + 0x08daff30, 0x0c3150e0, 0x0e45d850, 0x14c111a0, + 0x0ff7e1c0, 0x18a06860, 0x13810400, 0x1abc9ee0, + 0x28500940, 0x41f22800, 0x22fc5040, 0x2cd90180 + }, + + { + 0x00003ede, 0x00021fc9, 0x0013f0c3, 0x003a7be2, + 0x007a6663, 0x00fe3773, 0x012fabf4, 0x02275cd0, + 0x01c0ef14, 0x02c0b1d8, 0x0350fc70, 0x05505078, + 0x04175f30, 0x052c1098, 0x08ed3310, 0x0a63b470, + 0x05417870, 0x08995ee0, 0x07bbe018, 0x0a19fa10, + 0x0b5818c0, 0x0fd96ea0, 0x0e5cad10, 0x13b40d40, + 0x12d45840, 0x14577320, 0x2b2e5e00, 0x333e9640, + 0x194c35c0, 0x1c30f8c0, 0x2d16db00, 0x2cc970ff + }, + { + 0x002f18e7, 0x00a47be0, 0x01222efe, 0x01c42df8, + 0x024be794, 0x03424c40, 0x036950fc, 0x04973108, + 0x038405b4, 0x05d8c8f0, 0x05063e08, 0x070cdea0, + 0x05812be8, 0x06da5fc8, 0x088fcd60, 0x0a013cb0, + 0x0909a460, 0x09e6cf40, 0x0ee581d0, 0x0ec99f20, + 0x0b4e7470, 0x0c730e80, 0x0ff39d20, 0x105d0d80, + 0x158b0b00, 0x172babe0, 0x14576460, 0x181a6720, + 0x26126e80, 0x1f590180, 0x1fdaad60, 0x2e0e8000 + }, + { + 0x00c7f603, 0x01260cda, 0x01b3926a, 0x026d82bc, + 0x0228fba0, 0x036ec5b0, 0x034bf4cc, 0x043a55d0, + 0x044f9c20, 0x05c66f50, 0x0515f890, 0x06065300, + 0x0665dc00, 0x0802b630, 0x0737a1c0, 0x087294e0, + 0x09253fc0, 0x0a619760, 0x097bd060, 0x0a6d4e50, + 0x0d19e520, 0x0e15c420, 0x0c4e4eb0, 0x0e8880e0, + 0x11cdf480, 0x12c85800, 0x10f4c0a0, 0x13e51b00, + 0x189dbaa0, 0x18a6bb60, 0x22e31500, 0x21615240 + } + }; + + /************************************************************************* + * + * FUNCTION NAME: swComfortNoise + * + * PURPOSE: + * + * This routine perform the following tasks: + * - generation of the speech flag (swSP) + * - averaging and encoding of the comfort noise parameters + * - randomization of the codebook indices + * + * + * INPUTS: + * + * swVadFrmCnt (global) - swVadFlag=0 frame counter. + * If swVadFlag=1 then this counter is 0, the first frame with + * swVadFlag=0 will set this counter to 1, with each additional + * swVadFlag=0 frame the counter is incremented. + * + * swVadFlag - voise activity flag. swVadFlag=0 frame with + * no voice activity, swVadFlag=0 frame with voice activity + * + * L_UnqntzdR0 - unquantized R(0), 32 bit value, output of + * FLAT. + * + * pL_UnqntzdCorr[NP+1] - unquantized correlation sequence, + * also an output of FLAT. + * + * + * OUTPUTS: + * + * swCNR0 - global variable, the output quantized R0 index + * + * pswCNLpc[3] - global variable, the output quantized LPC to the + * transmitted in the SID frame + * + * pswCNGsp0Code[N_SUB] - global variable, the output quantized GSP0 indices + * + * pswCNVSCode1[N_SUB] - global variable, the output quantized codevector 1 + * indices. + * + * pswCNVSCode2[N_SUB] - global variable, the output quantized codevector 2 + * indices. + * + * + * RETURN VALUE: + * + * swSP - speech flag, swSP=1 speech frames are generated, swSP=0 + * SID frames are generated. + * + *************************************************************************/ + + int16_t Codec::swComfortNoise(int16_t swVadFlag, + int32_t L_UnqntzdR0, int32_t *pL_UnqntzdCorr) + { + + + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swSP; + int16_t pswFinalRc[NP]; + + /* unquantized reference parameters */ + int32_t L_RefR0; + int32_t pL_RefCorr[NP + 1]; + int32_t L_RefGs; + + int i; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + swSP = 1; + + /* VadFrmCnt will indicate the number of sequential frames where */ + /* swVadFlag == 0 */ + /* ------------------------------------------------------------- */ + + if (swVadFlag) + swVadFrmCnt = 0; /* Voice acitvity present */ + else + swVadFrmCnt = add(swVadFrmCnt, 1); /* no voice activity */ + + + /* swNElapsed will indicate the number of frames that have elapsed */ + /* since the last SID frame with updated comfort noise parameters */ + /* was generated */ + /* --------------------------------------------------------------- */ + + swNElapsed = add(swNElapsed, 1); + + + /* If no voice activity was detected. */ + /* ----------------------------------- */ + + if (swVadFrmCnt) + { + + /* Short speech burst ? */ + /* -------------------- */ + + if (swVadFrmCnt == 1) + { + if (sub(swNElapsed, 24) < 0) + swShortBurst = 1; /* short speech burst detected */ + else + swShortBurst = 0; /* long speech burst detected */ + } + + + /* Update history, with this frames data */ + /* ------------------------------------- */ + + updateCNHist(L_UnqntzdR0, pL_UnqntzdCorr, + pL_R0Hist, ppL_CorrHist); + + + /* first SID frame */ + /* --------------- */ + + if (((swShortBurst == 0) && (swVadFrmCnt == OVERHANG)) || + ((swShortBurst == 1) && (swVadFrmCnt == 1))) + { + + /* init. random generator */ + /* ---------------------- */ + L_TxPNSeed = PN_INIT_SEED; + + + /* average GS */ + /* ---------- */ + avgGsHistQntz(pL_GsHist, &L_RefGs); + + + /* GS quantization */ + /* --------------- */ + swRefGsIndex = gsQuant(L_RefGs, 0); + + } + + + /* No Overhang in case of short speech bursts, */ + /* generate SID frames with repeated comfort noise parameters */ + /* ---------------------------------------------------------- */ + + if ((swShortBurst == 1) && (swVadFrmCnt < OVERHANG)) + { + + /* generate a SID frame with repeated parameters */ + /* --------------------------------------------- */ + + swSP = 0; + + + /* repeat data: r0, LPC, GS */ + /* ------------------------ */ + + swCNR0 = swQntRefR0; + + for (i = 0; i < 3; i++) + pswCNLpc[i] = piRefVqCodewds[i]; + + for (i = 0; i < N_SUB; i++) + pswCNGsp0Code[i] = swRefGsIndex; + + } + + + /* generate SID frames with updated comfort noise parameters */ + /* --------------------------------------------------------- */ + + if (swVadFrmCnt >= OVERHANG) + { + + /* A SID frame with updated parameters */ + /* ----------------------------------- */ + + swSP = 0; + swNElapsed = 0; + + + /* average R0 and correlation values */ + /* --------------------------------- */ + + avgCNHist(pL_R0Hist, ppL_CorrHist, &L_RefR0, + pL_RefCorr); + + + /* now quantize the averaged R(0) */ + /* ------------------------------ */ + + swQntRefR0 = r0Quant(L_RefR0); + + + /* Quantize the averaged correlation */ + /* --------------------------------- */ + + lpcCorrQntz(pL_RefCorr, + pswFinalRc, + piRefVqCodewds); + + + /* update frame data: r0, LPC */ + /* -------------------------- */ + + swCNR0 = swQntRefR0; + for (i = 0; i < 3; i++) + pswCNLpc[i] = piRefVqCodewds[i]; + + + /* update subframe data (unvoiced mode): GSP0 */ + /* ------------------------------------------ */ + + for (i = 0; i < N_SUB; i++) + pswCNGsp0Code[i] = swRefGsIndex; + + } + + + /* random codevectors */ + /* ------------------ */ + + if (swSP == 0) + { + for (i = 0; i < N_SUB; i++) + { + pswCNVSCode1[i] = getPnBits(7, &L_TxPNSeed); + pswCNVSCode2[i] = getPnBits(7, &L_TxPNSeed); + } + } + + + } + + return (swSP); + } + + + /************************************************************************* + * + * FUNCTION NAME: updateCNHist + * + * PURPOSE: + * + * Add current frame's unquantized R(0) and LPC information to the + * comfort noise history, so that it will be available for + * averaging. + * + * INPUTS: + * + * Unquantized values from the coder: + * + * + * L_UnqntzdR0 - unquantized frame energy R(0), an output of FLAT + * + * pL_UnqntzdCorr[NP+1] - unquantized correlation coefficient + * array. Also an output of FLAT. + * + * siUpdPointer (global) - A modulo counter which counts up from + * 0 to OVERHANG-1. + * + * OUTPUTS: + * + * pL_R0History[OVERHANG] - history of the OVERHANG frames worth of + * R(0). + * + * ppL_CorrHistory[OVERHANG][NP+1] - - history of the OVERHANG + * frames worth of pL_UnqntzdCorr[]. + * + * RETURN VALUE: + * + * none + * + *************************************************************************/ + + void Codec::updateCNHist(int32_t L_UnqntzdR0, + int32_t *pL_UnqntzdCorr, + int32_t pL_R0History[], + int32_t ppL_CorrHistory[OVERHANG][NP + 1]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int i; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* update */ + pL_R0History[siUpdPointer] = L_UnqntzdR0; + + for (i = 0; i < NP + 1; i++) + ppL_CorrHistory[siUpdPointer][i] = pL_UnqntzdCorr[i]; + + siUpdPointer = (siUpdPointer + 1) % OVERHANG; + } + + + /************************************************************************* + * + * FUNCTION NAME: avgGsHistQntz + * + * PURPOSE: + * + * Average gs history, where history is of length OVERHANG-1 + * frames. The last frame's (i.e. this frame) gs values are not + * available since quantization would have occured only after the + * VAD decision is made. + * + * INPUTS: + * + * pL_GsHistory[(OVERHANG-1)*N_SUB] - the GS of the past + * OVERHANG-1 frames. The GS values are stored shifted down by 2 + * shifts to avoid overflow (the largest GS is greater than 2.0). + * + * + * OUTPUTS: + * + * *pL_GsAvgd - the average of pL_GsHistory[], also shifted down + * by two shifts. + * + * RETURN VALUE: + * + * none. + * + * + *************************************************************************/ + + void Codec::avgGsHistQntz(int32_t pL_GsHistory[], int32_t *pL_GsAvgd) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int i; + int32_t L_avg; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + L_avg = L_shift_r(pL_GsHistory[0], -(OH_SHIFT + 2)); + + for (i = 1; i < N_SUB * (OVERHANG - 1); i++) + L_avg = L_add(L_shift_r(pL_GsHistory[i], -(OH_SHIFT + 2)), L_avg); + + /* avg number x/32 not x/28 */ + + *pL_GsAvgd = L_add(L_avg, L_mpy_ls(L_avg, 0x1249)); /* L_avg *= 32/28 */ + + } + + + /************************************************************************* + * + * FUNCTION NAME: gsQuant + * + * PURPOSE: + * + * Quantize a value of gs in any of the voicing modes. Input GS + * is a 32 bit number. The GSP0 index is returned. + * + * INPUTS: + * + * L_GsIn - 32 bit GS value, shifted down by 2 shifts. + * + * swVoicingMode - voicing level + * + * ppLr_gsTable[4][32] - Rom GS Table. (global), all GS values + * have been shifted down by 2 from their true value. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * + * GSP0 Index closest to the input value of GS. + * + * + *************************************************************************/ + + int16_t Codec::gsQuant(int32_t L_GsIn, int16_t swVoicingMode) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swGsIndex, + swBestGs; + int32_t L_diff, + L_min = LW_MAX; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + for (swGsIndex = 0; swGsIndex < 32; swGsIndex++) + { + L_diff = L_abs(L_sub(L_GsIn, ppLr_gsTable[swVoicingMode][swGsIndex])); + + if (L_sub(L_diff, L_min) < 0) + { + /* new minimum */ + /* ----------- */ + + swBestGs = swGsIndex; + L_min = L_diff; + + } + } + + return (swBestGs); + + } + + + /************************************************************************* + * + * FUNCTION NAME: avgCNHist + * + * PURPOSE: + * + * Average the unquantized R0 and LPC data stored at the encoder + * to arrive at an average R0 and LPC frame for use in a SID + * frame. + * + * INPUTS: + * + * pL_R0History[OVERHANG] - contains unquantized R(0) data from the + * most recent OVERHANG frame (including this one). + * + * ppL_CorrHistory[OVERHANG][NP+1] - Unquantized correlation + * coefficients from the most recent OVERHANG frame (including this + * one). The data stored here is an output of FLAT. + * + * OUTPUTS: + * + * *pL_AvgdR0 - the average of pL_R0History[] + * + * pL_AvgdCorrSeq[NP+1] - the average of ppL_CorrHistory[][]. + * + * + * RETURN VALUE: + * + * none + * + *************************************************************************/ + + void Codec::avgCNHist(int32_t pL_R0History[], + int32_t ppL_CorrHistory[OVERHANG][NP + 1], + int32_t *pL_AvgdR0, + int32_t pL_AvgdCorrSeq[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int i, + j; + int32_t L_avg; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* R0 Averaging */ + /* ------------ */ + + for (L_avg = 0, i = 0; i < OVERHANG; i++) + L_avg = L_add(L_shr(pL_R0History[i], OH_SHIFT), L_avg); + + *pL_AvgdR0 = L_avg; + + + /* LPC: average the last OVERHANG frames */ + /* ------------------------------------- */ + + for (j = 0; j < NP + 1; j++) + { + for (L_avg = 0, i = 0; i < OVERHANG; i++) + { + L_avg = L_add(L_shift_r(ppL_CorrHistory[i][j], -OH_SHIFT), L_avg); + } + + pL_AvgdCorrSeq[j] = L_avg; + } + + } + + + /*************************************************************************** + * + * FUNCTION NAME: lpcCorrQntz + * + * PURPOSE: Quantize a correlation sequence + * + * + * INPUT: + * + * pL_CorrelSeq[NP+1] + * Correlation sequence to quantize. + * + * OUTPUTS: + * + * pswFinalRc[0:NP-1] + * A quantized set of NP reflection coefficients. + * + * piVQCodewds[0:2] + * An array containing the indices of the 3 reflection + * coefficient vectors selected from the three segment + * Rc-VQ. + * + * RETURN: + * None. + * + * KEYWORDS: AFLAT,aflat,flat,vectorquantization, reflectioncoefficients + * + *************************************************************************/ + + void Codec::lpcCorrQntz(int32_t pL_CorrelSeq[], + int16_t pswFinalRc[], + int piVQCodewds[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t pswPOldSpace[NP_AFLAT], + pswPNewSpace[NP_AFLAT], + pswVOldSpace[2 * NP_AFLAT - 1], + pswVNewSpace[2 * NP_AFLAT - 1], + *ppswPAddrs[2], + *ppswVAddrs[2], + *pswVBar, + pswPBar[NP_AFLAT], + pswVBarSpace[2 * NP_AFLAT - 1], + pswFlatsRc[NP], /* Unquantized Rc's computed by FLAT */ + pswRc[NP + 1]; /* Temp list for the converted RC's */ + int32_t *pL_VBarFull, + pL_PBarFull[NP], + pL_VBarFullSpace[2 * NP - 1]; + + int i, + iVec, + iSeg, + iCnt; /* Loop counter */ + struct QuantList quantList, /* A list of vectors */ + bestPql[4]; /* The four best vectors from + * the PreQ */ + struct QuantList bestQl[LPC_VQ_SEG + 1]; /* Best vectors for each of + * the three segments */ + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Setup pointers temporary space */ + /*--------------------------------*/ + + pswVBar = pswVBarSpace + NP_AFLAT - 1; + pL_VBarFull = pL_VBarFullSpace + NP - 1; + ppswPAddrs[0] = pswPOldSpace; + ppswPAddrs[1] = pswPNewSpace; + ppswVAddrs[0] = pswVOldSpace + NP_AFLAT - 1; + ppswVAddrs[1] = pswVNewSpace + NP_AFLAT - 1; + + + /* Set up pL_PBarFull and pL_VBarFull initial conditions, using the */ + /* autocorrelation sequence derived from the optimal reflection */ + /* coefficients computed by FLAT. The initial conditions are shifted */ + /* right by RSHIFT bits. These initial conditions, stored as */ + /* int32_ts, are used to initialize PBar and VBar arrays for the */ + /* next VQ segment. */ + /*--------------------------------------------------------------------*/ + + initPBarFullVBarFullL(pL_CorrelSeq, pL_PBarFull, pL_VBarFull); + + /* Set up initial PBar and VBar initial conditions, using pL_PBarFull */ + /* and pL_VBarFull arrays initialized above. These are the initial */ + /* PBar and VBar conditions to be used by the AFLAT recursion at the */ + /* 1-st Rc-VQ segment. */ + /*--------------------------------------------------------------------*/ + + initPBarVBarL(pL_PBarFull, pswPBar, pswVBar); + + for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++) + { + /* initialize candidate list */ + /*---------------------------*/ + + quantList.iNum = psrPreQSz[iSeg - 1]; + quantList.iRCIndex = 0; + + /* do aflat for all vectors in the list */ + /*--------------------------------------*/ + + setupPreQ(iSeg, quantList.iRCIndex); /* set up vector ptrs */ + + for (iCnt = 0; iCnt < quantList.iNum; iCnt++) + { + /* get a vector */ + /*--------------*/ + + getNextVec(pswRc); + + /* clear the limiter flag */ + /*------------------------*/ + + iLimit = 0; + + /* find the error values for each vector */ + /*---------------------------------------*/ + + quantList.pswPredErr[iCnt] = + aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l], + pswPBar, pswVBar, + ppswPAddrs, ppswVAddrs, + psvqIndex[iSeg - 1].len); + + /* check the limiter flag */ + /*------------------------*/ + + if (iLimit) + quantList.pswPredErr[iCnt] = 0x7fff; /* set error to bad value */ + + } /* done list loop */ + + /* find 4 best prequantizer levels */ + /*---------------------------------*/ + + findBestInQuantList(quantList, 4, bestPql); + + for (iVec = 0; iVec < 4; iVec++) + { + + /* initialize quantizer list */ + /*---------------------------*/ + + quantList.iNum = psrQuantSz[iSeg - 1]; + quantList.iRCIndex = bestPql[iVec].iRCIndex * psrQuantSz[iSeg - 1]; + + setupQuant(iSeg, quantList.iRCIndex); /* set up vector ptrs */ + + /* do aflat recursion on each element of list */ + /*--------------------------------------------*/ + + for (iCnt = 0; iCnt < quantList.iNum; iCnt++) + { + /* get a vector */ + /*--------------*/ + + getNextVec(pswRc); + + /* clear the limiter flag */ + /*------------------------*/ + + iLimit = 0; + + /* find the error values for each vector */ + /*---------------------------------------*/ + + quantList.pswPredErr[iCnt] = + aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l], + pswPBar, pswVBar, + ppswPAddrs, ppswVAddrs, + psvqIndex[iSeg - 1].len); + + /* check the limiter flag */ + /*------------------------*/ + + if (iLimit) + quantList.pswPredErr[iCnt] = 0x7fff; /* set error to the worst + * value */ + + } /* done list loop */ + + /* find best quantizer vector for this segment, and save it */ + /*----------------------------------------------------------*/ + + findBestInQuantList(quantList, 1, bestQl); + if (iVec == 0) + bestQl[iSeg] = bestQl[0]; + else if (sub(bestQl[iSeg].pswPredErr[0], bestQl[0].pswPredErr[0]) > 0) + bestQl[iSeg] = bestQl[0]; + + } + + /* find the quantized reflection coefficients */ + /*--------------------------------------------*/ + + setupQuant(iSeg, bestQl[iSeg].iRCIndex); /* set up vector ptrs */ + getNextVec((int16_t *) (pswFinalRc - 1)); + + + /* Update pBarFull and vBarFull for the next Rc-VQ segment, and */ + /* update the pswPBar and pswVBar for the next Rc-VQ segment */ + /*--------------------------------------------------------------*/ + + if (iSeg < LPC_VQ_SEG) + aflatNewBarRecursionL(&pswFinalRc[psvqIndex[iSeg - 1].l - 1], iSeg, + pL_PBarFull, pL_VBarFull, pswPBar, pswVBar); + + } + + /* find the quantizer index (the values to be output in the symbol file) */ + /*-----------------------------------------------------------------*/ + + for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++) + piVQCodewds[iSeg - 1] = bestQl[iSeg].iRCIndex; + + } + + + /************************************************************************* + * + * FUNCTION NAME: getPnBits + * + * PURPOSE: + * + * Generate iBits pseudo-random bits using *pL_PNSeed as the + * pn-generators seed. + * + * INPUTS: + * + * iBits - integer indicating how many random bits to return. + * range [0,15], 0 yields 1 bit output + * + * *pL_PNSeed - 32 bit seed (changed by function) + * + * OUTPUTS: + * + * *pL_PNSeed - 32 bit seed, modified. + * + * RETURN VALUE: + * + * random bits in iBits LSB's. + * + * + * IMPLEMENTATION: + * + * implementation of x**31 + x**3 + 1 == PN_XOR_REG | PN_XOR_ADD a + * PN sequence generator using int32_ts generating a 2**31 -1 + * length pn-sequence. + * + *************************************************************************/ + + int16_t Codec::getPnBits(int iBits, int32_t *pL_PNSeed) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swPnBits = 0; + int32_t L_Taps, + L_FeedBack; + int i; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + for (i = 0; i < iBits; i++) + { + /* update the state */ + /* ---------------- */ + + L_Taps = *pL_PNSeed & PN_XOR_REG; + L_FeedBack = L_Taps; /* Xor tap bits to yield + * feedback bit */ + L_Taps = L_shr(L_Taps, 1); + + while (L_Taps) + { + L_FeedBack = L_FeedBack ^ L_Taps; + L_Taps = L_shr(L_Taps, 1); + } + + /* LSB of L_FeedBack is next MSB of PN register */ + + *pL_PNSeed = L_shr(*pL_PNSeed, 1); + if (L_FeedBack & 1) + *pL_PNSeed = *pL_PNSeed | PN_XOR_ADD; + + /* State update complete. Get the output bit from the state, add/or it + * into output */ + + swPnBits = shl(swPnBits, 1); + swPnBits = swPnBits | (extract_l(*pL_PNSeed) & 0x0001); + + } + return (swPnBits); + } + + + /************************************************************************* + * + * FUNCTION NAME: rxInterpR0Lpc + * + * PURPOSE: + * + * Perform part of the comfort noise algorithm at the decoder. + * LPC and R0 are derived in this routine + * + * INPUTS: + * + * pswOldKs - Last frame's reflection coeffs. + * + * pswNewKs - This frame's decoded/received reflection coeffs. + * This will serve a new endpoint in interpolation. + * + * swRxDTXState - primary DTX state variable (at the receiver). A + * modulo 12 counter, which is 0 at SID frame. + * + * swDecoMode - actual mode the decoder: speech decoding mode + * or comfort noise insertion mode (SPEECH = speech decoding; + * CNIFIRSTSID = comfort noise, 1st SID received; CNICONT = comfort + * noise, SID frame received, but not 1st SID; CNIBFI = comfort + * noise, bad frame received) + * + * swFrameType - type of the received frame (VALIDSID, INVALIDSID + * GOODSPEECH or UNUSABLE) + * + * swOldR0Dec - global variable, the decoded R0 value from the last + * frame . This will be modified. + * + * swR0NewCN - global variable the decoded R0 value from the frame + * just received. Valid information if current frame is a SID frame. + * + * + * OUTPUTS: + * + * pswNewKs - This frames LPC coeffs. modified to reflect + * interpolated correlation sequence pL_CorrSeq[]. + * + * swR0Dec - global variable, interpolated R0 value + * + * swR0OldCN - global variable, R0 interpolation point to + * interpolate from. + * + * swR0NewCN - global variable, R0 interpolation point to + * interpolate to. + * + * pL_OldCorrSeq[NP+1] - global variable, starting point for + * interpolation of LPC information. + * + * pL_NewCorrSeq[NP+1] - global variable, end point for + * interpolation of LPC information. + * + * pL_CorrSeq[NP+1] - global variable, interpolated value of LPC + * information to be used in this frame. + * + * + * RETURN VALUE: + * + * None. + * + * KEYWORDS: interpolation, comfort noise, SID, DTX + * + *************************************************************************/ + + void Codec::rxInterpR0Lpc(int16_t *pswOldKs, int16_t *pswNewKs, + int16_t swRxDTXState, + int16_t swDecoMode, int16_t swFrameType) + { + + /*________________________________________________________________________ + | | + | Static Variables | + |________________________________________________________________________| + */ + + + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int i; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + if (swDecoMode == CNIFIRSTSID) + { + /* first SID frame arrived */ + /* ----------------------- */ + + /* use tx'd R0 frame as both endpoints of interp curve. */ + /* i.e. no interpolation for the first frames */ + /* ---------------------------------------------------- */ + + + swR0OldCN = swOldR0Dec; /* last non-SID, received R0 */ + swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState); + + + /* generate the LPC end points for interpolation */ + /* --------------------------------------------- */ + + rcToCorrDpL(ASHIFT, ASCALE, pswOldKs, pL_OldCorrSeq); + rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, pL_NewCorrSeq); + + /* linearly interpolate between the two sets of correlation coefs */ + /* -------------------------------------------------------------- */ + + for (i = 0; i < NP + 1; i++) + { + pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i], + swRxDTXState); + } + + /* Generate this frames K's (overwrite input) */ + /* ------------------------------------------ */ + + aFlatRcDp(pL_CorrSeq, pswNewKs); + + } + else if ((swDecoMode == CNICONT) && (swFrameType == VALIDSID)) + { + /* new (not the first) SID frame arrived */ + /* ------------------------------------- */ + + swR0OldCN = swOldR0Dec; /* move current state of R0 to old */ + swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState); + + + /* LPC: generate new endpoints for interpolation */ + /* --------------------------------------------- */ + + for (i = 0; i < NP + 1; i++) + { + pL_OldCorrSeq[i] = pL_CorrSeq[i]; + } + + rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, pL_NewCorrSeq); + + + /* linearly interpolate between the two sets of correlation coefs */ + /* -------------------------------------------------------------- */ + + for (i = 0; i < NP + 1; i++) + { + pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i], + swRxDTXState); + } + + + /* Use interpolated LPC for this frame, overwrite the input K's */ + /* ------------------------------------------------------------ */ + + aFlatRcDp(pL_CorrSeq, pswNewKs); + + } + else + { + /* in between SID frames / invalid SID frames */ + /* ------------------------------------------ */ + + swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState); + + + /* linearly interpolate between the two sets of correlation coefs */ + /* -------------------------------------------------------------- */ + + for (i = 0; i < NP + 1; i++) + { + pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i], + swRxDTXState); + } + + + /* Use interpolated LPC for this frame, overwrite the input K's */ + /* ------------------------------------------------------------ */ + + aFlatRcDp(pL_CorrSeq, pswNewKs); + + } + } + + + /************************************************************************* + * + * FUNCTION NAME: linInterpSid + * + * PURPOSE: + * + * Linearly interpolate between two input numbers based on what the + * current DtxState is. + * + * INPUTS: + * + * L_New - int32_t more current value + * + * L_Old - int32_t oldest value + * + * swDtxState - state is 0 at the transmitted SID Frame. + * + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * A value between old and new inputs with dtxState+1/12 of the new + * (dtxState+1)-12/12 of the old + * + * + *************************************************************************/ + + int32_t Codec::linInterpSid(int32_t L_New, int32_t L_Old, int16_t swDtxState) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swOldFactor; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* old factor = (1.0 - newFactor) */ + /* ------------------------------ */ + + swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]); + swOldFactor = add(0x1, swOldFactor); + + + /* contributions from new and old */ + /* ------------------------------ */ + + L_New = L_mpy_ls(L_New, psrCNNewFactor[swDtxState]); + L_Old = L_mpy_ls(L_Old, swOldFactor); + + return (L_add(L_New, L_Old)); + + } + + + /************************************************************************* + * + * FUNCTION NAME: linInterpSidShort + * + * PURPOSE: + * + * Linearly interpolate between two input numbers based on what + * the current DtxState is. + * + * INPUTS: + * + * swNew - 16 bit, more current value + * + * swOld - 16 bit, oldest value + * + * swDtxState - state is 0 at the transmitted SID Frame. + * + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * A value between old and new inputs with dtxState+1/12 of the new + * (dtxState+1)-12/12 of the old + * + *************************************************************************/ + + int16_t Codec::linInterpSidShort(int16_t swNew, int16_t swOld, + int16_t swDtxState) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swOldFactor; + int32_t L_New, + L_Old; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* old factor = (1.0 - newFactor) */ + /* ------------------------------ */ + + swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]); + swOldFactor = add(0x1, swOldFactor); + + + /* contributions from new and old */ + /* ------------------------------ */ + + L_New = L_mult(swNew, psrCNNewFactor[swDtxState]); + L_Old = L_mult(swOld, swOldFactor); + + + return (round(L_add(L_New, L_Old))); + + } + + // sp_frm.c + + #define ASCALE 0x0800 + #define ASHIFT 4 + #define CG_INT_MACS 6 + #define CG_TERMS (LSMAX - LSMIN + 1) + #define CVSHIFT 2 /* Number of right shifts to be + * applied to the normalized Phi + * array in cov32, also used in flat + * to shift down normalized F, B, C + * matrices. */ + #define C_FRAME_LEN (N_SUB * CG_TERMS) + #define DELTA_LEVELS 16 + #define G_FRAME_LEN (LSMAX + (N_SUB-1) * S_LEN - LSMIN + 1) + #define HIGH 1 + #define INV_OS_FCTR 0x1555 /* 1.0/6.0 */ + #define LAG_TABLE_LEN (1 << L_BITS) + #define LMAX 142 + #define LMAX_FR (LMAX * OS_FCTR) + #define LMIN 21 + #define LMIN_FR (LMIN * OS_FCTR) + #define LOW 0 + #define LPC_VQ_SEG 3 + #define LSMAX (LMAX + CG_INT_MACS/2) + #define LSMIN (LMIN - CG_INT_MACS/2) + #define LSP_MASK 0xffff + #define L_BITS 8 + #define L_ROUND (int32_t)0x8000 /* Preload accumulator value for + * rounding */ + #define NP_AFLAT 4 + #define NUM_CLOSED 3 + #define NUM_TRAJ_MAX 2 + #define ONE_EIGHTH 0x1000 + #define ONE_HALF 0x4000 + #define ONE_QUARTER 0x2000 + #define PEAK_VICINITY 3 + #define PGAIN_CLAMP 0x0021 /* 0.001 */ + #define PGAIN_SCALE 0x6000 /* 0.75 */ + #define PW_FRAC 0x3333 /* 0.4 */ + #define R0BITS 5 + #define RSHIFT 2 + #define S_SH 6 /* Shift offset for computing frame + * energy */ + #define UV_SCALE0 -0x2976 + #define UV_SCALE1 -0x46d3 + #define UV_SCALE2 -0x6676 + #define W_F_BUFF_LEN (F_LEN + LSMAX) + #define high(x) (shr(x,8) & 0x00ff) + #define low(x) x & 0x00ff /* This macro will return the low + * byte of a word */ + #define odd(x) (x & 0x0001) /* This macro will determine if an + * integer is odd */ + + + /*************************************************************************** + * + * FUNCTION NAME: aflat + * + * PURPOSE: Given a vector of high-pass filtered input speech samples + * (A_LEN samples), function aflat computes the NP unquantized + * reflection coefficients using the FLAT algorithm, searches + * the three segment Rc-VQ based on the AFLAT recursion, and + * outputs a quantized set of NP reflection coefficients, along + * with the three indices specifying the selected vectors + * from the Rc-VQ. The index of the quantized frame energy R0 + * is also output. + * + * + * INPUT: + * + * pswSpeechToLpc[0:A_LEN-1] + * A vector of high-pass filtered input speech, from + * which the unquantized reflection coefficients and + * the index of the quantized frame energy are + * computed. + * + * OUTPUTS: + * + * piR0Index[0:0] + * An index into a 5 bit table of quantized frame + * energies. + * + * pswFinalRc[0:NP-1] + * A quantized set of NP reflection coefficients. + * + * piVQCodewds[0:2] + * An array containing the indices of the 3 reflection + * coefficient vectors selected from the three segment + * Rc-VQ. + * + * swPtch + * Flag to indicate a periodic signal component + * + * pswVadFlag + * Voice activity decision flag + * = 1: voice activity + * = 0: no voice activity + * + * pswSP + * Speech flag + * = 1: encoder generates speech frames + * = 0: encoder generate SID frames + * + * + * RETURN: + * None. + * + * REFERENCE: Sub-clauses 4.1.3, 4.1.4, and 4.1.4.1 + * of GSM Recommendation 06.20 + * + * KEYWORDS: AFLAT,aflat,flat,vectorquantization, reflectioncoefficients + * + *************************************************************************/ + + void Codec::aflat(int16_t pswSpeechToLPC[], + int piR0Index[], + int16_t pswFinalRc[], + int piVQCodewds[], + int16_t swPtch, + int16_t *pswVadFlag, + int16_t *pswSP) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t pswPOldSpace[NP_AFLAT], + pswPNewSpace[NP_AFLAT], + pswVOldSpace[2 * NP_AFLAT - 1], + pswVNewSpace[2 * NP_AFLAT - 1], + *ppswPAddrs[2], + *ppswVAddrs[2], + *pswVBar, + pswPBar[NP_AFLAT], + pswVBarSpace[2 * NP_AFLAT - 1], + pswFlatsRc[NP], /* Unquantized Rc's computed by FLAT */ + pswRc[NP + 1]; /* Temp list for the converted RC's */ + int32_t pL_CorrelSeq[NP + 1], + *pL_VBarFull, + pL_PBarFull[NP], + pL_VBarFullSpace[2 * NP - 1]; + + int i, + iVec, + iSeg, + iCnt; /* Loop counter */ + struct QuantList quantList, /* A list of vectors */ + bestPql[4]; /* The four best vectors from the + * PreQ */ + struct QuantList bestQl[LPC_VQ_SEG + 1]; /* Best vectors for each of + * the three segments */ + int16_t swVadScalAuto; + int16_t pswVadRc[4]; + int32_t pL_VadAcf[9]; + + int32_t L_R0; /* Normalized R0 (use swRShifts to + * unnormalize). This is done prior + * to r0quant(). After this, its is + * a unnormalized number */ + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Setup pointers temporary space */ + /*--------------------------------*/ + + pswVBar = pswVBarSpace + NP_AFLAT - 1; + pL_VBarFull = pL_VBarFullSpace + NP - 1; + ppswPAddrs[0] = pswPOldSpace; + ppswPAddrs[1] = pswPNewSpace; + ppswVAddrs[0] = pswVOldSpace + NP_AFLAT - 1; + ppswVAddrs[1] = pswVNewSpace + NP_AFLAT - 1; + + /* Given the input speech, compute the optimal reflection coefficients */ + /* using the FLAT algorithm. */ + /*---------------------------------------------------------------------*/ + + L_R0 = flat(pswSpeechToLPC, pswFlatsRc, piR0Index, pL_VadAcf, + &swVadScalAuto); + + /* Get unquantized reflection coefficients for VAD */ /* DTX mode */ + /* algorithm */ /* DTX mode */ + /* ----------------------------------------------- */ /* DTX mode */ + + for (i = 0; i < 4; i++) /* DTX mode */ + pswVadRc[i] = pswFlatsRc[i]; /* DTX mode */ + + + /* convert reflection coefficients to correlation */ /* DTX mode */ + /* sequence */ /* DTX mode */ + /* ---------------------------------------------- */ /* DTX mode */ + + rcToCorrDpL(ASHIFT, ASCALE, pswFlatsRc, pL_CorrelSeq); /* DTX mode */ + + + /* Make the voice activity detection. Only swVadFlag is */ /* DTX mode */ + /* modified. */ /* DTX mode */ + /* ---------------------------------------------------- */ /* DTX mode */ + + vad_algorithm(pL_VadAcf, swVadScalAuto, pswVadRc, swPtch, /* DTX mode */ + pswVadFlag); + + + /* if DTX mode off, then always voice activity */ /* DTX mode */ + /* ------------------------------------------- */ /* DTX mode */ + if (!giDTXon) *pswVadFlag = 1; /* DTX mode */ + + + /* determination of comfort noise parameters */ /* DTX mode */ + /* ----------------------------------------- */ /* DTX mode */ + + *pswSP = swComfortNoise(*pswVadFlag, /* DTX mode */ + L_R0, /* DTX mode */ + pL_CorrelSeq); /* DTX mode */ + + if (*pswSP == 0) /* DTX mode */ + { /* SID frame generation */ /* DTX mode */ + + /* use unquantized reflection coefficients in the */ /* DTX mode */ + /* encoder, when SID frames are generated */ /* DTX mode */ + /* ---------------------------------------------- */ /* DTX mode */ + + for (i = 0; i < NP; i++) /* DTX mode */ + pswFinalRc[i] = pswFlatsRc[i]; /* DTX mode */ + + } /* DTX mode */ + else /* DTX mode */ + { /* speech frame generation */ + + /* Set up pL_PBarFull and pL_VBarFull initial conditions, using the */ + /* autocorrelation sequence derived from the optimal reflection */ + /* coefficients computed by FLAT. The initial conditions are shifted */ + /* right by RSHIFT bits. These initial conditions, stored as */ + /* int32_ts, are used to initialize PBar and VBar arrays for the */ + /* next VQ segment. */ + /*--------------------------------------------------------------------*/ + + initPBarFullVBarFullL(pL_CorrelSeq, pL_PBarFull, pL_VBarFull); + + /* Set up initial PBar and VBar initial conditions, using pL_PBarFull */ + /* and pL_VBarFull arrays initialized above. These are the initial */ + /* PBar and VBar conditions to be used by the AFLAT recursion at the */ + /* 1-st Rc-VQ segment. */ + /*--------------------------------------------------------------------*/ + + initPBarVBarL(pL_PBarFull, pswPBar, pswVBar); + + for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++) + { + + /* initialize candidate list */ + /*---------------------------*/ + + quantList.iNum = psrPreQSz[iSeg - 1]; + quantList.iRCIndex = 0; + + /* do aflat for all vectors in the list */ + /*--------------------------------------*/ + + setupPreQ(iSeg, quantList.iRCIndex); /* set up vector ptrs */ + + for (iCnt = 0; iCnt < quantList.iNum; iCnt++) + { + /* get a vector */ + /*--------------*/ + + getNextVec(pswRc); + + /* clear the limiter flag */ + /*------------------------*/ + + iLimit = 0; + + /* find the error values for each vector */ + /*---------------------------------------*/ + + quantList.pswPredErr[iCnt] = + aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l], + pswPBar, pswVBar, + ppswPAddrs, ppswVAddrs, + psvqIndex[iSeg - 1].len); + + /* check the limiter flag */ + /*------------------------*/ + + if (iLimit) + { + quantList.pswPredErr[iCnt] = 0x7fff; /* set error to bad value */ + } + + } /* done list loop */ + + /* find 4 best prequantizer levels */ + /*---------------------------------*/ + + findBestInQuantList(quantList, 4, bestPql); + + for (iVec = 0; iVec < 4; iVec++) + { + + /* initialize quantizer list */ + /*---------------------------*/ + + quantList.iNum = psrQuantSz[iSeg - 1]; + quantList.iRCIndex = bestPql[iVec].iRCIndex * psrQuantSz[iSeg - 1]; + + setupQuant(iSeg, quantList.iRCIndex); /* set up vector ptrs */ + + /* do aflat recursion on each element of list */ + /*--------------------------------------------*/ + + for (iCnt = 0; iCnt < quantList.iNum; iCnt++) + { + + /* get a vector */ + /*--------------*/ + + getNextVec(pswRc); + + /* clear the limiter flag */ + /*------------------------*/ + + iLimit = 0; + + /* find the error values for each vector */ + /*---------------------------------------*/ + + quantList.pswPredErr[iCnt] = + aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l], + pswPBar, pswVBar, + ppswPAddrs, ppswVAddrs, + psvqIndex[iSeg - 1].len); + + /* check the limiter flag */ + /*------------------------*/ + + if (iLimit) + { + quantList.pswPredErr[iCnt] = 0x7fff; /* set error to the worst + * value */ + } + + } /* done list loop */ + + /* find best quantizer vector for this segment, and save it */ + /*----------------------------------------------------------*/ + + findBestInQuantList(quantList, 1, bestQl); + if (iVec == 0) + { + bestQl[iSeg] = bestQl[0]; + } + else + { + if (sub(bestQl[iSeg].pswPredErr[0], + bestQl[0].pswPredErr[0]) > 0) + { + bestQl[iSeg] = bestQl[0]; + } + } + } + + /* find the quantized reflection coefficients */ + /*--------------------------------------------*/ + + setupQuant(iSeg, bestQl[iSeg].iRCIndex); /* set up vector ptrs */ + getNextVec((int16_t *) (pswFinalRc - 1)); + + + /* Update pBarFull and vBarFull for the next Rc-VQ segment, and */ + /* update the pswPBar and pswVBar for the next Rc-VQ segment */ + /*--------------------------------------------------------------*/ + + if (iSeg < LPC_VQ_SEG) + { + + aflatNewBarRecursionL(&pswFinalRc[psvqIndex[iSeg - 1].l - 1], iSeg, + pL_PBarFull, pL_VBarFull, pswPBar, pswVBar); + + } + + } + + /* find the quantizer index (the values */ + /* to be output in the symbol file) */ + /*--------------------------------------*/ + + for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++) + { + piVQCodewds[iSeg - 1] = bestQl[iSeg].iRCIndex; + } + + } + + } + + /*************************************************************************** + * + * FUNCTION NAME: aflatNewBarRecursionL + * + * PURPOSE: Given the int32_t initial condition arrays, pL_PBarFull and + * pL_VBarFull, a reflection coefficient vector selected from + * the Rc-VQ at the current stage, and index of the current + * Rc-VQ stage, the AFLAT recursion is evaluated to obtain the + * updated initial conditions for the AFLAT recursion at the + * next Rc-VQ stage. At each lattice stage the pL_PBarFull and + * pL_VBarFull arrays are shifted to be RSHIFT down from full + * scale. Two sets of initial conditions are output: + * + * 1) pswPBar and pswVBar int16_t arrays are used at the + * next Rc-VQ segment as the AFLAT initial conditions + * for the Rc prequantizer and the Rc quantizer searches. + * 2) pL_PBarFull and pL_VBarFull arrays are output and serve + * as the initial conditions for the function call to + * aflatNewBarRecursionL at the next lattice stage. + * + * + * This is an implementation of equations 4.24 through + * 4.27. + * INPUTS: + * + * pswQntRc[0:NP_AFLAT-1] + * An input reflection coefficient vector selected from + * the Rc-VQ quantizer at the current stage. + * + * iSegment + * An input describing the current Vector quantizer + * quantizer segment (1, 2, or 3). + * + * RSHIFT The number of shifts down from full scale the + * pL_PBarFull and pL_VBarFull arrays are to be shifted + * at each lattice stage. RSHIFT is a global constant. + * + * pL_PBar[0:NP-1] + * A int32_t input array containing the P initial + * conditions for the full 10-th order LPC filter. + * The address of the 0-th element of pL_PBarFull + * is passed in when function aflatNewBarRecursionL + * is called. + * + * pL_VBar[-NP+1:NP-1] + * A int32_t input array containing the V initial + * conditions for the full 10-th order LPC filter. + * The address of the 0-th element of pL_VBarFull + * is passed in when function aflatNewBarRecursionL + * is called. + * + * OUTPUTS: + * + * pL_PBar[0:NP-1] + * A int32_t output array containing the updated P + * initial conditions for the full 10-th order LPC + * filter. + * + * pL_VBar[-NP+1:NP-1] + * A int32_t output array containing the updated V + * initial conditions for the full 10-th order LPC + * filter. + * + * pswPBar[0:NP_AFLAT-1] + * An output int16_t array containing the P initial + * conditions for the P-V AFLAT recursion for the next + * Rc-VQ segment. The address of the 0-th element of + * pswVBar is passed in. + * + * pswVBar[-NP_AFLAT+1:NP_AFLAT-1] + * The output int16_t array containing the V initial + * conditions for the P-V AFLAT recursion, for the next + * Rc-VQ segment. The address of the 0-th element of + * pswVBar is passed in. + * + * RETURN: + * None. + * + * REFERENCE: Sub-clause 4.1.4.1 GSM Recommendation 06.20 + * + *************************************************************************/ + + void Codec::aflatNewBarRecursionL(int16_t pswQntRc[], int iSegment, + int32_t pL_PBar[], int32_t pL_VBar[], + int16_t pswPBar[], int16_t pswVBar[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + int32_t *pL_VOld, + *pL_VNew, + *pL_POld, + *pL_PNew, + *ppL_PAddrs[2], + *ppL_VAddrs[2], + pL_VOldSpace[2 * NP - 1], + pL_VNewSpace[2 * NP - 1], + pL_POldSpace[NP], + pL_PNewSpace[NP], + L_temp, + L_sum; + int16_t swQntRcSq, + swNShift; + short int i, + j, + bound; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + /* Copy the addresses of the input PBar and VBar arrays into */ + /* pL_POld and pL_VOld respectively. */ + /*------------------------------------------------------------*/ + + pL_POld = pL_PBar; + pL_VOld = pL_VBar; + + /* Point to PNew and VNew temporary arrays */ + /*-----------------------------------------*/ + + pL_PNew = pL_PNewSpace; + pL_VNew = pL_VNewSpace + NP - 1; + + /* Load the addresses of the temporary buffers into the address arrays. */ + /* The address arrays are used to swap PNew and POld (VNew and VOLd) */ + /* buffers to avoid copying of the buffer contents at the end of a */ + /* lattice filter stage. */ + /*----------------------------------------------------------------------*/ + + ppL_PAddrs[0] = pL_POldSpace; + ppL_PAddrs[1] = pL_PNewSpace; + ppL_VAddrs[0] = pL_VOldSpace + NP - 1; + ppL_VAddrs[1] = pL_VNewSpace + NP - 1; + + + /* Update AFLAT recursion initial conditions for searching the Rc vector */ + /* quantizer at the next VQ segment. */ + /*-------------------------------------------------------------------*/ + + for (j = 0; j < psvqIndex[iSegment - 1].len; j++) + { + bound = NP - psvqIndex[iSegment - 1].l - j - 1; + + /* Compute rc squared, used by the recursion at the j-th lattice stage. */ + /*---------------------------------------------------------------------*/ + + swQntRcSq = mult_r(pswQntRc[j], pswQntRc[j]); + + /* Calculate PNew(i) */ + /*-------------------*/ + + L_temp = L_mpy_ls(pL_VOld[0], pswQntRc[j]); + L_sum = L_add(L_temp, pL_POld[0]); + L_temp = L_mpy_ls(pL_POld[0], swQntRcSq); + L_sum = L_add(L_temp, L_sum); + L_temp = L_mpy_ls(pL_VOld[0], pswQntRc[j]); + L_temp = L_add(L_sum, L_temp); + + /* Compute the number of bits to shift left by to achieve */ + /* the nominal value of PNew[0] which is right shifted by */ + /* RSHIFT bits relative to full scale. */ + /*---------------------------------------------------------*/ + + swNShift = sub(norm_s(extract_h(L_temp)), RSHIFT); + + /* Rescale PNew[0] by shifting left by swNShift bits */ + /*---------------------------------------------------*/ + + pL_PNew[0] = L_shl(L_temp, swNShift); + + for (i = 1; i <= bound; i++) + { + L_temp = L_mpy_ls(pL_VOld[i], pswQntRc[j]); + L_sum = L_add(L_temp, pL_POld[i]); + L_temp = L_mpy_ls(pL_POld[i], swQntRcSq); + L_sum = L_add(L_temp, L_sum); + L_temp = L_mpy_ls(pL_VOld[-i], pswQntRc[j]); + L_temp = L_add(L_sum, L_temp); + pL_PNew[i] = L_shl(L_temp, swNShift); + } + + /* Calculate VNew(i) */ + /*-------------------*/ + + for (i = -bound; i < 0; i++) + { + L_temp = L_mpy_ls(pL_VOld[-i - 1], swQntRcSq); + L_sum = L_add(L_temp, pL_VOld[i + 1]); + L_temp = L_mpy_ls(pL_POld[-i - 1], pswQntRc[j]); + L_temp = L_shl(L_temp, 1); + L_temp = L_add(L_temp, L_sum); + pL_VNew[i] = L_shl(L_temp, swNShift); + } + for (i = 0; i <= bound; i++) + { + L_temp = L_mpy_ls(pL_VOld[-i - 1], swQntRcSq); + L_sum = L_add(L_temp, pL_VOld[i + 1]); + L_temp = L_mpy_ls(pL_POld[i + 1], pswQntRc[j]); + L_temp = L_shl(L_temp, 1); + L_temp = L_add(L_temp, L_sum); + pL_VNew[i] = L_shl(L_temp, swNShift); + } + + if (j < psvqIndex[iSegment - 1].len - 2) + { + + /* Swap POld and PNew buffers, using modulo addressing */ + /*-----------------------------------------------------*/ + + pL_POld = ppL_PAddrs[(j + 1) % 2]; + pL_PNew = ppL_PAddrs[j % 2]; + + /* Swap VOld and VNew buffers, using modulo addressing */ + /*-----------------------------------------------------*/ + + pL_VOld = ppL_VAddrs[(j + 1) % 2]; + pL_VNew = ppL_VAddrs[j % 2]; + } + else + { + if (j == psvqIndex[iSegment - 1].len - 2) + { + + /* Then recursion to be done for one more lattice stage */ + /*------------------------------------------------------*/ + + /* Copy address of PNew into POld */ + /*--------------------------------*/ + pL_POld = ppL_PAddrs[(j + 1) % 2]; + + /* Copy address of the input pL_PBar array into pswPNew; this will */ + /* cause the PNew array to overwrite the input pL_PBar array, thus */ + /* updating it at the final lattice stage of the current segment */ + /*-----------------------------------------------------------------*/ + + pL_PNew = pL_PBar; + + /* Copy address of VNew into VOld */ + /*--------------------------------*/ + + pL_VOld = ppL_VAddrs[(j + 1) % 2]; + + /* Copy address of the input pL_VBar array into pswVNew; this will */ + /* cause the VNew array to overwrite the input pL_VBar array, thus */ + /* updating it at the final lattice stage of the current segment */ + /*-----------------------------------------------------------------*/ + + pL_VNew = pL_VBar; + + } + } + } + + /* Update the pswPBar and pswVBar initial conditions for the AFLAT */ + /* Rc-VQ search at the next segment. */ + /*----------------------------------------------------------------------*/ + + bound = psvqIndex[iSegment].len - 1; + + for (i = 0; i <= bound; i++) + { + pswPBar[i] = round(pL_PBar[i]); + pswVBar[i] = round(pL_VBar[i]); + } + for (i = -bound; i < 0; i++) + { + pswVBar[i] = round(pL_VBar[i]); + } + + return; + } + + /*************************************************************************** + * + * FUNCTION NAME: aflatRecursion + * + * PURPOSE: Given the int16_t initial condition arrays, pswPBar and + * pswVBar, a reflection coefficient vector from the quantizer + * (or a prequantizer), and the order of the current Rc-VQ + * segment, function aflatRecursion computes and returns the + * residual error energy by evaluating the AFLAT recursion. + * + * This is an implementation of equations 4.18 to 4.23. + * INPUTS: + * + * pswQntRc[0:NP_AFLAT-1] + * An input reflection coefficient vector from the + * Rc-prequantizer or the Rc-VQ codebook. + * + * pswPBar[0:NP_AFLAT-1] + * The input int16_t array containing the P initial + * conditions for the P-V AFLAT recursion at the current + * Rc-VQ segment. The address of the 0-th element of + * pswVBar is passed in. + * + * pswVBar[-NP_AFLAT+1:NP_AFLAT-1] + * The input int16_t array containing the V initial + * conditions for the P-V AFLAT recursion, at the current + * Rc-VQ segment. The address of the 0-th element of + * pswVBar is passed in. + * + * *ppswPAddrs[0:1] + * An input array containing the address of temporary + * space P1 in its 0-th element, and the address of + * temporary space P2 in its 1-st element. Each of + * these addresses is alternately assigned onto + * pswPNew and pswPOld pointers using modulo + * arithmetic, so as to avoid copying the contents of + * pswPNew array into the pswPOld array at the end of + * each lattice stage of the AFLAT recursion. + * Temporary space P1 and P2 is allocated outside + * aflatRecursion by the calling function aflat. + * + * *ppswVAddrs[0:1] + * An input array containing the address of temporary + * space V1 in its 0-th element, and the address of + * temporary space V2 in its 1-st element. Each of + * these addresses is alternately assigned onto + * pswVNew and pswVOld pointers using modulo + * arithmetic, so as to avoid copying the contents of + * pswVNew array into the pswVOld array at the end of + * each lattice stage of the AFLAT recursion. + * Temporary space V1 and V2 is allocated outside + * aflatRecursion by the calling function aflat. + * + * swSegmentOrder + * This input short word describes the number of + * stages needed to compute the vector + * quantization of the given segment. + * + * OUTPUTS: + * None. + * + * RETURN: + * swRe The int16_t value of residual energy for the + * Rc vector, given the pswPBar and pswVBar initial + * conditions. + * + * REFERENCE: Sub-clause 4.1.4.1 GSM Recommendation 06.20 + * + *************************************************************************/ + + int16_t Codec::aflatRecursion(int16_t pswQntRc[], + int16_t pswPBar[], + int16_t pswVBar[], + int16_t *ppswPAddrs[], + int16_t *ppswVAddrs[], + int16_t swSegmentOrder) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t *pswPOld, + *pswPNew, + *pswVOld, + *pswVNew, + pswQntRcSqd[NP_AFLAT], + swRe; + int32_t L_sum; + short int i, + j, + bound; /* loop control variables */ + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Point to PBar and VBar, the initial condition arrays for the AFLAT */ + /* recursion. */ + /*---------------------------------------------------------------------*/ + + pswPOld = pswPBar; + pswVOld = pswVBar; + + /* Point to PNew and VNew, the arrays into which updated values of P */ + /* and V functions will be written. */ + /*---------------------------------------------------------------------*/ + + pswPNew = ppswPAddrs[1]; + pswVNew = ppswVAddrs[1]; + + /* Compute the residual error energy due to the selected Rc vector */ + /* using the AFLAT recursion. */ + /*-----------------------------------------------------------------*/ + + /* Compute rc squared, used by the recursion */ + /*-------------------------------------------*/ + + for (j = 0; j < swSegmentOrder; j++) + { + pswQntRcSqd[j] = mult_r(pswQntRc[j], pswQntRc[j]); + } + + /* Compute the residual error energy due to the selected Rc vector */ + /* using the AFLAT recursion. */ + /*-----------------------------------------------------------------*/ + + for (j = 0; j < swSegmentOrder - 1; j++) + { + bound = swSegmentOrder - j - 2; + + /* Compute Psubj(i), for i = 0, bound */ + /*-------------------------------------*/ + + for (i = 0; i <= bound; i++) + { + L_sum = L_mac(L_ROUND, pswVOld[i], pswQntRc[j]); + L_sum = L_mac(L_sum, pswVOld[-i], pswQntRc[j]); + L_sum = L_mac(L_sum, pswPOld[i], pswQntRcSqd[j]); + L_sum = L_msu(L_sum, pswPOld[i], SW_MIN); + pswPNew[i] = extract_h(L_sum); + } + + /* Check if potential for limiting exists. */ + /*-----------------------------------------*/ + + if (sub(pswPNew[0], 0x4000) >= 0) + iLimit = 1; + + /* Compute the new Vsubj(i) */ + /*--------------------------*/ + + for (i = -bound; i < 0; i++) + { + L_sum = L_msu(L_ROUND, pswVOld[i + 1], SW_MIN); + L_sum = L_mac(L_sum, pswQntRcSqd[j], pswVOld[-i - 1]); + L_sum = L_mac(L_sum, pswQntRc[j], pswPOld[-i - 1]); + L_sum = L_mac(L_sum, pswQntRc[j], pswPOld[-i - 1]); + pswVNew[i] = extract_h(L_sum); + } + + for (i = 0; i <= bound; i++) + { + L_sum = L_msu(L_ROUND, pswVOld[i + 1], SW_MIN); + L_sum = L_mac(L_sum, pswQntRcSqd[j], pswVOld[-i - 1]); + L_sum = L_mac(L_sum, pswQntRc[j], pswPOld[i + 1]); + L_sum = L_mac(L_sum, pswQntRc[j], pswPOld[i + 1]); + pswVNew[i] = extract_h(L_sum); + } + + if (j < swSegmentOrder - 2) + { + + /* Swap POld and PNew buffers, using modulo addressing */ + /*-----------------------------------------------------*/ + + pswPOld = ppswPAddrs[(j + 1) % 2]; + pswPNew = ppswPAddrs[j % 2]; + + /* Swap VOld and VNew buffers, using modulo addressing */ + /*-----------------------------------------------------*/ + + pswVOld = ppswVAddrs[(j + 1) % 2]; + pswVNew = ppswVAddrs[j % 2]; + + } + } + + /* Computing Psubj(0) for the last lattice stage */ + /*-----------------------------------------------*/ + + j = swSegmentOrder - 1; + + L_sum = L_mac(L_ROUND, pswVNew[0], pswQntRc[j]); + L_sum = L_mac(L_sum, pswVNew[0], pswQntRc[j]); + L_sum = L_mac(L_sum, pswPNew[0], pswQntRcSqd[j]); + L_sum = L_msu(L_sum, pswPNew[0], SW_MIN); + swRe = extract_h(L_sum); + + /* Return the residual energy corresponding to the reflection */ + /* coefficient vector being evaluated. */ + /*--------------------------------------------------------------*/ + + return (swRe); /* residual error is returned */ + + } + + /*************************************************************************** + * + * FUNCTION NAME: bestDelta + * + * PURPOSE: + * + * This function finds the delta-codeable lag which maximizes CC/G. + * + * INPUTS: + * + * pswLagList[0:siNumLags-1] + * + * List of delta-codeable lags over which search is done. + * + * pswCSfrm[0:127] + * + * C(k) sequence, k integer. + * + * pswGSfrm[0:127] + * + * G(k) sequence, k integer. + * + * siNumLags + * + * Number of lags in contention. + * + * siSfrmIndex + * + * The index of the subframe to which the delta-code + * applies. + * + * + * OUTPUTS: + * + * pswLTraj[0:3] + * + * The winning lag is put into this array at + * pswLTraj[siSfrmIndex] + * + * pswCCTraj[0:3] + * + * The corresponding winning C**2 is put into this + * array at pswCCTraj[siSfrmIndex] + * + * pswGTraj[0:3] + * + * The corresponding winning G is put into this arrray + * at pswGTraj[siSfrmIndex] + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * REFERENCE: Sub-clause 4.1.8.3 of GSM Recommendation 06.20 + * + * KEYWORDS: + * + *************************************************************************/ + + void Codec::bestDelta(int16_t pswLagList[], + int16_t pswCSfrm[], + int16_t pswGSfrm[], + short int siNumLags, + short int siSfrmIndex, + int16_t pswLTraj[], + int16_t pswCCTraj[], + int16_t pswGTraj[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t pswCBuf[DELTA_LEVELS + CG_INT_MACS + 2], + pswGBuf[DELTA_LEVELS + CG_INT_MACS + 2], + pswCInterp[DELTA_LEVELS + 2], + pswGInterp[DELTA_LEVELS + 2], + *psw1, + *psw2, + swCmaxSqr, + swGmax, + swPeak; + short int siIPLo, + siRemLo, + siIPHi, + siRemHi, + siLoLag, + siHiLag, + siI; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* get bounds for integer C's and G's needed for interpolation */ + /* get integer and fractional portions of boundary lags */ + /* ----------------------------------------------------------- */ + + get_ipjj(pswLagList[0], &siIPLo, &siRemLo); + + get_ipjj(pswLagList[siNumLags - 1], &siIPHi, &siRemHi); + + /* get lag for first and last C and G required */ + /* ------------------------------------------- */ + + siLoLag = sub(siIPLo, CG_INT_MACS / 2 - 1); + + if (siRemHi != 0) + { + siHiLag = add(siIPHi, CG_INT_MACS / 2); + } + else + { + siHiLag = add(siIPHi, CG_INT_MACS / 2 - 1); + } + + /* transfer needed integer C's and G's to temp buffers */ + /* --------------------------------------------------- */ + + psw1 = pswCBuf; + psw2 = pswGBuf; + + if (siRemLo == 0) + { + + /* first lag in list is integer: don't care about first entries */ + /* (they will be paired with zero tap in interpolating filter) */ + /* ------------------------------------------------------------ */ + + psw1[0] = 0; + psw2[0] = 0; + psw1 = &psw1[1]; + psw2 = &psw2[1]; + } + + for (siI = siLoLag; siI <= siHiLag; siI++) + { + psw1[siI - siLoLag] = pswCSfrm[siI - LSMIN]; + psw2[siI - siLoLag] = pswGSfrm[siI - LSMIN]; + } + + if (siRemLo == 0) + { + /* make siLoLag correspond to first entry in temp buffers */ + /* ------------------------------------------------------ */ + siLoLag = sub(siLoLag, 1); + } + + /* interpolate to get C's and G's which correspond to lags in list */ + /* --------------------------------------------------------------- */ + + CGInterp(pswLagList, siNumLags, pswCBuf, pswGBuf, siLoLag, + pswCInterp, pswGInterp); + + /* find max C*C*sgn(C)/G */ + /* --------------------- */ + + swPeak = maxCCOverGWithSign(pswCInterp, pswGInterp, &swCmaxSqr, &swGmax, + siNumLags); + + /* store best lag and corresponding C*C and G */ + /* ------------------------------------------ */ + + pswLTraj[siSfrmIndex] = pswLagList[swPeak]; + pswCCTraj[siSfrmIndex] = swCmaxSqr; + pswGTraj[siSfrmIndex] = swGmax; + + } + + + /*************************************************************************** + * + * FUNCTION NAME: CGInterp + * + * PURPOSE: + * + * Given a list of fractional lags, a C(k) array, and a G(k) array + * (k integer), this function generates arrays of C's and G's + * corresponding to the list of fractional lags by interpolating the + * integer C(k) and G(k) arrays. + * + * INPUTS: + * + * pswLIn[0:siNum-1] + * + * List of valid lags + * + * siNum + * + * Length of output lists + * + * pswCIn[0:variable] + * + * C(k) sequence, k integer. The zero index corresponds + * to k = siLoIntLag. + * + * pswGIn[0:variable] + * + * G(k) sequence, k integer. The zero index corresponds + * to k = siLoIntLag. + * + * siLoIntLag + * + * Integer lag corresponding to the first entry in the + * C(k) and G(k) input arrays. + * + * ppsrCGIntFilt[0:5][0:5] + * + * The FIR interpolation filter for C's and G's. + * + * OUTPUTS: + * + * pswCOut[0:siNum-1] + * + * List of interpolated C's corresponding to pswLIn. + * + * pswGOut[0:siNum-1] + * + * List of interpolated G's corresponding to pswLIn + * + * RETURN VALUE: none + * + * DESCRIPTION: + * + * + * REFERENCE: Sub-clause 4.1.8.2, 4.1.8.3 of GSM Recommendation 06.20 + * + * KEYWORDS: lag, interpolateCG + * + *************************************************************************/ + + void Codec::CGInterp(int16_t pswLIn[], + short siNum, + int16_t pswCIn[], + int16_t pswGIn[], + short siLoIntLag, + int16_t pswCOut[], + int16_t pswGOut[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + int16_t i, + swBig, + swLoIntLag; + int16_t swLagInt, + swTempRem, + swLagRem; + int32_t L_Temp, + L_Temp1, + L_Temp2; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + swLoIntLag = add(siLoIntLag, (CG_INT_MACS / 2) - 1); + + for (swBig = 0; swBig < siNum; swBig++) + { + + /* Separate integer and fractional portions of lag */ + /*-------------------------------------------------*/ + L_Temp = L_mult(pswLIn[swBig], INV_OS_FCTR); + swLagInt = extract_h(L_Temp); + + /* swLagRem = (OS_FCTR - pswLIn[iBig] % OS_FCTR)) */ + /*---------------------------------------------------*/ + swTempRem = extract_l(L_Temp); + swTempRem = shr(swTempRem, 1); + swLagRem = swTempRem & SW_MAX; + swLagRem = mult_r(swLagRem, OS_FCTR); + swLagRem = sub(OS_FCTR, swLagRem); + + /* Get interpolated C and G values */ + /*--------------------------*/ + + L_Temp1 = L_mac(32768, pswCIn[swLagInt - swLoIntLag], + ppsrCGIntFilt[0][swLagRem]); + L_Temp2 = L_mac(32768, pswGIn[swLagInt - swLoIntLag], + ppsrCGIntFilt[0][swLagRem]); + + for (i = 1; i <= CG_INT_MACS - 1; i++) + { + L_Temp1 = L_mac(L_Temp1, pswCIn[i + swLagInt - swLoIntLag], + ppsrCGIntFilt[i][swLagRem]); + L_Temp2 = L_mac(L_Temp2, pswGIn[i + swLagInt - swLoIntLag], + ppsrCGIntFilt[i][swLagRem]); + + } + pswCOut[swBig] = extract_h(L_Temp1); + pswGOut[swBig] = extract_h(L_Temp2); + } + } + + /*************************************************************************** + * + * FUNCTION NAME: CGInterpValid + * + * PURPOSE: + * + * The purpose of this function is to retrieve the valid (codeable) lags + * within one (exclusive) integer sample of the given integer lag, and + * interpolate the corresponding C's and G's from the integer arrays + * + * INPUTS: + * + * swFullResLag + * + * integer lag * OS_FCTR + * + * pswCIn[0:127] + * + * integer C sequence + * + * pswGIn[0:127] + * + * integer G sequence + * + * psrLagTbl[0:255] + * + * reference table of valid (codeable) lags + * + * + * OUTPUTS: + * + * pswLOut[0:*psiNum-1] + * + * list of valid lags within 1 of swFullResLag + * + * pswCOut[0:*psiNum-1] + * + * list of interpolated C's corresponding to pswLOut + * + * pswGOut[0:*psiNum-1] + * + * list of interpolated G's corresponding to pswLOut + * + * RETURN VALUE: + * + * siNum + * + * length of output lists + * + * DESCRIPTION: + * + * REFERENCE: Sub-clause 4.1.8.2, 4.1.9 of GSM Recommendation 06.20 + * + * KEYWORDS: CGInterpValid, cginterpvalid, CG_INT_VALID + * + *************************************************************************/ + + short Codec::CGInterpValid(int16_t swFullResLag, + int16_t pswCIn[], + int16_t pswGIn[], + int16_t pswLOut[], + int16_t pswCOut[], + int16_t pswGOut[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + short int siLowerBound, + siUpperBound, + siNum, + siI; + int16_t swLag; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Get lower and upper bounds for valid lags */ + /* within 1 (exclusive) integer lag of input lag */ + /* --------------------------------------------- */ + + swLag = sub(swFullResLag, OS_FCTR); + swLag = quantLag(swLag, &siLowerBound); + if (sub(swLag, swFullResLag) != 0) + { + siLowerBound = add(siLowerBound, 1); + } + + swLag = add(swFullResLag, OS_FCTR); + swLag = quantLag(swLag, &siUpperBound); + if (sub(swLag, swFullResLag) != 0) + { + siUpperBound = sub(siUpperBound, 1); + } + + /* Get list of full resolution lags whose */ + /* C's and G's will be interpolated */ + /* -------------------------------------- */ + + siNum = sub(siUpperBound, siLowerBound); + siNum = add(siNum, 1); + + for (siI = 0; siI < siNum; siI++) + { + pswLOut[siI] = psrLagTbl[siI + siLowerBound]; + } + + /* Interpolate C's and G's */ + /* ----------------------- */ + + CGInterp(pswLOut, siNum, pswCIn, pswGIn, LSMIN, pswCOut, + pswGOut); + + /* Return the length of the output lists */ + /* ------------------------------------- */ + + return (siNum); + } + + /*************************************************************************** + * + * FUNCTION NAME: compResidEnergy + * + * PURPOSE: + * + * Computes and compares the residual energy from interpolated and + * non-interpolated coefficients. From the difference determines + * the soft interpolation decision. + * + * INPUTS: + * + * pswSpeech[0:159] ( [0:F_LEN-1] ) + * + * Input speech frame (after high-pass filtering). + * + * ppswInterpCoef[0:3][0:9] ( [0:N_SUB-1][0:NP-1] ) + * + * Set of interpolated LPC direct-form coefficients for + * each subframe. + * + * pswPreviousCoef[0:9} ( [0:NP-1] ) + * + * Set of LPC direct-form coefficients corresponding to + * the previous frame + * + * pswCurrentCoef[0:9} ( [0:NP-1] ) + * + * Set of LPC direct-form coefficients corresponding to + * the current frame + * + * psnsSqrtRs[0:3] ( [0:N_SUB-1] ) + * + * Array of residual energy estimates for each subframe + * based on interpolated coefficients. Used for scaling. + * + * RETURN: + * + * Returned value indicates the coefficients to use for each subframe: + * One indicates interpolated coefficients are to be used, zero indicates + * un-interpolated coefficients are to be used. + * + * DESCRIPTION: + * + * + * REFERENCE: Sub-clause 4.1.6 of GSM Recommendation 06.20 + * + * Keywords: openlooplagsearch, openloop, lag, pitch + * + **************************************************************************/ + + + + short Codec::compResidEnergy(int16_t pswSpeech[], + int16_t ppswInterpCoef[][NP], + int16_t pswPreviousCoef[], + int16_t pswCurrentCoef[], + struct NormSw psnsSqrtRs[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + short i, + j, + siOverflowPossible, + siInterpDecision; + int16_t swMinShift, + swShiftFactor, + swSample, + *pswCoef; + int16_t pswTempState[NP]; + int16_t pswResidual[S_LEN]; + int32_t L_ResidualEng; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Find minimum shift count of the square-root of residual energy */ + /* estimates over the four subframes. According to this minimum, */ + /* find a shift count for the residual signal which will be used */ + /* to avoid overflow when the actual residual energies are */ + /* calculated over the frame */ + /*----------------------------------------------------------------*/ + + swMinShift = SW_MAX; + for (i = 0; i < N_SUB; i++) + { + + if (sub(psnsSqrtRs[i].sh, swMinShift) < 0 && psnsSqrtRs[i].man > 0) + swMinShift = psnsSqrtRs[i].sh; + } + + if (sub(swMinShift, 1) >= 0) + { + + siOverflowPossible = 0; + } + + else if (swMinShift == 0) + { + siOverflowPossible = 1; + swShiftFactor = ONE_HALF; + } + + else if (sub(swMinShift, -1) == 0) + { + siOverflowPossible = 1; + swShiftFactor = ONE_QUARTER; + } + + else + { + siOverflowPossible = 1; + swShiftFactor = ONE_EIGHTH; + } + + /* Copy analysis filter state into temporary buffer */ + /*--------------------------------------------------*/ + + for (i = 0; i < NP; i++) + pswTempState[i] = pswAnalysisState[i]; + + /* Send the speech frame, one subframe at a time, through the analysis */ + /* filter which is based on interpolated coefficients. After each */ + /* subframe, accumulate the energy in the residual signal, scaling to */ + /* avoid overflow if necessary. */ + /*---------------------------------------------------------------------*/ + + L_ResidualEng = 0; + + for (i = 0; i < N_SUB; i++) + { + + lpcFir(&pswSpeech[i * S_LEN], ppswInterpCoef[i], pswTempState, + pswResidual); + + if (siOverflowPossible) + { + + for (j = 0; j < S_LEN; j++) + { + + swSample = mult_r(swShiftFactor, pswResidual[j]); + L_ResidualEng = L_mac(L_ResidualEng, swSample, swSample); + } + } + + else + { + + for (j = 0; j < S_LEN; j++) + { + + L_ResidualEng = L_mac(L_ResidualEng, pswResidual[j], pswResidual[j]); + } + } + } + + /* Send the speech frame, one subframe at a time, through the analysis */ + /* filter which is based on un-interpolated coefficients. After each */ + /* subframe, subtract the energy in the residual signal from the */ + /* accumulated residual energy due to the interpolated coefficient */ + /* analysis filter, again scaling to avoid overflow if necessary. */ + /* Note that the analysis filter state is updated during these */ + /* filtering operations. */ + /*---------------------------------------------------------------------*/ + + for (i = 0; i < N_SUB; i++) + { + + switch (i) + { + + case 0: + + pswCoef = pswPreviousCoef; + break; + + case 1: + case 2: + case 3: + + pswCoef = pswCurrentCoef; + break; + } + + lpcFir(&pswSpeech[i * S_LEN], pswCoef, pswAnalysisState, + pswResidual); + + if (siOverflowPossible) + { + + for (j = 0; j < S_LEN; j++) + { + + swSample = mult_r(swShiftFactor, pswResidual[j]); + L_ResidualEng = L_msu(L_ResidualEng, swSample, swSample); + } + } + + else + { + + for (j = 0; j < S_LEN; j++) + { + + L_ResidualEng = L_msu(L_ResidualEng, pswResidual[j], pswResidual[j]); + } + } + } + + /* Make soft-interpolation decision based on the difference in residual */ + /* energies */ + /*----------------------------------------------------------------------*/ + + if (L_ResidualEng < 0) + siInterpDecision = 1; + + else + siInterpDecision = 0; + + return siInterpDecision; + } + + /*************************************************************************** + * + * FUNCTION NAME: cov32 + * + * PURPOSE: Calculates B, F, and C correlation matrices from which + * the reflection coefficients are computed using the FLAT + * algorithm. The Spectral Smoothing Technique (SST) is applied + * to the correlations. End point correction is employed + * in computing the correlations to minimize computation. + * + * INPUT: + * + * pswIn[0:169] + * A sampled speech vector used to compute + * correlations need for generating the optimal + * reflection coefficients via the FLAT algorithm. + * + * CVSHIFT The number of right shifts by which the normalized + * correlations are to be shifted down prior to being + * rounded into the int16_t output correlation arrays + * B, F, and C. + * + * pL_rFlatSstCoefs[NP] + * + * A table stored in Rom containing the spectral + * smoothing function coefficients. + * + * OUTPUTS: + * + * pppL_B[0:NP-1][0:NP-1][0:1] + * An output correlation array containing the backward + * correlations of the input signal. It is a square + * matrix symmetric about the diagonal. Only the upper + * right hand triangular region of this matrix is + * initialized, but two dimensional indexing is retained + * to enhance clarity. The third array dimension is used + * by function flat to swap the current and the past + * values of B array, eliminating the need to copy + * the updated B values onto the old B values at the + * end of a given lattice stage. The third dimension + * is similarily employed in arrays F and C. + * + * pppL_F[0:NP-1][0:NP-1][0:1] + * An output correlation array containing the forward + * correlations of the input signal. It is a square + * matrix symmetric about the diagonal. Only the upper + * right hand triangular region of this matrix is + * initialized. + * + * pppL_C[0:NP-1][0:NP-1][0:1] + * An output correlation array containing the cross + * correlations of the input signal. It is a square + * matrix which is not symmetric. All its elements + * are initialized, for the third dimension index = 0. + * + * pL_R0 Average normalized signal power over F_LEN + * samples, given by 0.5*(Phi(0,0)+Phi(NP,NP)), where + * Phi(0,0) and Phi(NP,NP) are normalized signal + * autocorrelations. The average unnormalized signal + * power over the frame is given by adjusting L_R0 by + * the shift count which is returned. pL_R0 along + * with the returned shift count are the inputs to + * the frame energy quantizer. + * + * int32_t pL_VadAcf[4] + * An array with the autocorrelation coefficients to be + * used by the VAD. + * + * int16_t *pswVadScalAuto + * Input scaling factor used by the VAD. + * + * RETURN: + * + * swNormPwr The shift count to be applied to pL_R0 for + * reconstructing the average unnormalized + * signal power over the frame. + * Negative shift count means that a left shift was + * applied to the correlations to achieve a normalized + * value of pL_R0. + * + * DESCRIPTION: + * + * + * The input energy of the signal is assumed unknown. It maximum + * can be F_LEN*0.5. The 0.5 factor accounts for scaling down of the + * input signal in the high-pass filter. Therefore the signal is + * shifted down by 3 shifts producing an energy reduction of 2^(2*3)=64. + * The resulting energy is then normalized. Based on the shift count, + * the correlations F, B, and C are computed using as few shifts as + * possible, so a precise result is attained. + * This is an implementation of equations: 2.1 through 2.11. + * + * REFERENCE: Sub-clause 4.1.3 of GSM Recommendation 06.20 + * + * keywords: energy, autocorrelation, correlation, cross-correlation + * keywords: spectral smoothing, SST, LPC, FLAT, flat + * + *************************************************************************/ + + int16_t Codec::cov32(int16_t pswIn[], + int32_t pppL_B[NP][NP][2], + int32_t pppL_F[NP][NP][2], + int32_t pppL_C[NP][NP][2], + int32_t *pL_R0, + int32_t pL_VadAcf[], + int16_t *pswVadScalAuto) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_max, + L_Pwr0, + L_Pwr, + L_temp, + pL_Phi[NP + 1]; + int16_t swTemp, + swNorm, + swNormSig, + swNormPwr, + pswInScale[A_LEN], + swPhiNorm; + short int i, + k, + kk, + n; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Calculate energy in the frame vector (160 samples) for each */ + /* of NP frame placements. The energy is reduced by 64. This is */ + /* accomplished by shifting the input right by 3 bits. An offset */ + /* of 0x117f0b is placed into the accumulator to account for */ + /* the worst case power gain due to the 3 LSB's of the input */ + /* signal which were right shifted. The worst case is that the */ + /* 3 LSB's were all set to 1 for each of the samples. Scaling of */ + /* the input by a half is assumed here. */ + /*---------------------------------------------------------------*/ + + L_max = 0; + for (L_Pwr = 0x117f0b, i = 0; i < F_LEN; i++) + { + swTemp = shr(pswIn[i], 3); + L_Pwr = L_mac(L_Pwr, swTemp, swTemp); + } + L_max |= L_Pwr; + + /* L_max tracks the maximum power over NP window placements */ + /*----------------------------------------------------------*/ + + for (i = 1; i <= NP; i++) + { + + /* Subtract the power due to 1-st sample from previous window + * placement. */ + /*-----------------------------------------------------------*/ + + swTemp = shr(pswIn[i - 1], 3); + L_Pwr = L_msu(L_Pwr, swTemp, swTemp); + + /* Add the power due to new sample at the current window placement. */ + /*------------------------------------------------------------------*/ + + swTemp = shr(pswIn[F_LEN + i - 1], 3); + L_Pwr = L_mac(L_Pwr, swTemp, swTemp); + + L_max |= L_Pwr; + + } + + /* Compute the shift count needed to achieve normalized value */ + /* of the correlations. */ + /*------------------------------------------------------------*/ + + swTemp = norm_l(L_max); + swNorm = sub(6, swTemp); + + if (swNorm >= 0) + { + + /* The input signal needs to be shifted down, to avoid limiting */ + /* so compute the shift count to be applied to the input. */ + /*--------------------------------------------------------------*/ + + swTemp = add(swNorm, 1); + swNormSig = shr(swTemp, 1); + swNormSig = add(swNormSig, 0x0001); + + } + else + { + /* No scaling down of the input is necessary */ + /*-------------------------------------------*/ + + swNormSig = 0; + + } + + /* Convert the scaling down, if any, which was done to the time signal */ + /* to the power domain, and save. */ + /*---------------------------------------------------------------------*/ + + swNormPwr = shl(swNormSig, 1); + + /* Buffer the input signal, scaling it down if needed. */ + /*-----------------------------------------------------*/ + + for (i = 0; i < A_LEN; i++) + { + pswInScale[i] = shr(pswIn[i], swNormSig); + } + + /* Compute from buffered (scaled) input signal the correlations */ + /* needed for the computing the reflection coefficients. */ + /*------------------------------------------------------------------*/ + + /* Compute correlation Phi(0,0) */ + /*------------------------------*/ + + L_Pwr = L_mult(pswInScale[NP], pswInScale[NP]); + for (n = 1; n < F_LEN; n++) + { + L_Pwr = L_mac(L_Pwr, pswInScale[NP + n], pswInScale[NP + n]); + } + pL_Phi[0] = L_Pwr; + + /* Get ACF[0] and input scaling factor for VAD algorithm */ + *pswVadScalAuto = swNormSig; + pL_VadAcf[0] = L_Pwr; + + /* Compute the remaining correlations along the diagonal which */ + /* starts at Phi(0,0). End-point correction is employed to */ + /* limit computation. */ + /*-------------------------------------------------------------*/ + + for (i = 1; i <= NP; i++) + { + + /* Compute the power in the last sample from the previous */ + /* window placement, and subtract it from correlation accumulated */ + /* at the previous window placement. */ + /*----------------------------------------------------------------*/ + + L_Pwr = L_msu(L_Pwr, pswInScale[NP + F_LEN - i], + pswInScale[NP + F_LEN - i]); + + /* Compute the power in the new sample for the current window */ + /* placement, and add it to L_Pwr to obtain the value of Phi(i,i). */ + /*------------------------------------------------------------------*/ + + L_Pwr = L_mac(L_Pwr, pswInScale[NP - i], pswInScale[NP - i]); + + pL_Phi[i] = L_Pwr; + + } + + /* Compute the shift count necessary to normalize the Phi array */ + /*---------------------------------------------------------------*/ + + L_max = 0; + for (i = 0; i <= NP; i++) + { + L_max |= pL_Phi[i]; + } + swPhiNorm = norm_l(L_max); + + /* Adjust the shift count to be returned to account for any scaling */ + /* down which might have been done to the input signal prior to */ + /* computing the correlations. */ + /*------------------------------------------------------------------*/ + + swNormPwr = sub(swNormPwr, swPhiNorm); + + /* Compute the average power over the frame; i.e., */ + /* 0.5*(Phi(0,0)+Phi(NP,NP)), given a normalized pL_Phi array. */ + /*-------------------------------------------------------------------*/ + + swTemp = sub(swPhiNorm, 1); + L_Pwr0 = L_shl(pL_Phi[0], swTemp); + L_Pwr = L_shl(pL_Phi[NP], swTemp); + *pL_R0 = L_add(L_Pwr, L_Pwr0); /* Copy power to output pointer */ + + /* Check if the average power is normalized; if not, shift left by 1 bit */ + /*-----------------------------------------------------------------------*/ + + if (!(*pL_R0 & 0x40000000)) + { + *pL_R0 = L_shl(*pL_R0, 1); /* normalize the average power */ + swNormPwr = sub(swNormPwr, 1); /* adjust the shift count */ + } + + /* Reduce the shift count needed to normalize the correlations */ + /* by CVSHIFT bits. */ + /*---------------------------------------------------------------*/ + + swNorm = sub(swPhiNorm, CVSHIFT); + + /* Initialize the F, B, and C output correlation arrays, using the */ + /* Phi correlations computed along the diagonal of symmetry. */ + /*-----------------------------------------------------------------*/ + + L_temp = L_shl(pL_Phi[0], swNorm); /* Normalize the result */ + + pppL_F[0][0][0] = L_temp; /* Write to output array */ + + for (i = 1; i <= NP - 1; i++) + { + + L_temp = L_shl(pL_Phi[i], swNorm); /* Normalize the result */ + + + pppL_F[i][i][0] = L_temp; /* Write to output array */ + pppL_B[i - 1][i - 1][0] = L_temp; /* Write to output array */ + pppL_C[i][i - 1][0] = L_temp; /* Write to output array */ + + } + + L_temp = L_shl(pL_Phi[NP], swNorm); /* Normalize the result */ + + pppL_B[NP - 1][NP - 1][0] = L_temp; /* Write to output array */ + + for (k = 1; k <= NP - 1; k++) + { + + /* Compute correlation Phi(0,k) */ + /*------------------------------*/ + + L_Pwr = L_mult(pswInScale[NP], pswInScale[NP - k]); + for (n = 1; n < F_LEN; n++) + { + L_Pwr = L_mac(L_Pwr, pswInScale[NP + n], pswInScale[NP + n - k]); + } + /* convert covariance values to ACF and store for VAD algorithm */ + if (k < 9) + { + pL_VadAcf[k] = L_Pwr; + for (kk = 0; kk < k; kk++) + { + pL_VadAcf[k] = L_msu(pL_VadAcf[k], pswInScale[NP + kk], + pswInScale[NP + kk - k]); + } + } + + L_temp = L_shl(L_Pwr, swNorm); /* Normalize the result */ + L_temp = L_mpy_ll(L_temp, pL_rFlatSstCoefs[k - 1]); /* Apply SST */ + + pppL_F[0][k][0] = L_temp; /* Write to output array */ + pppL_C[0][k - 1][0] = L_temp; /* Write to output array */ + + + /* Compute the remaining correlations along the diagonal which */ + /* starts at Phi(0,k). End-point correction is employed to */ + /* limit computation. */ + /*-------------------------------------------------------------*/ + + for (kk = k + 1, i = 1; kk <= NP - 1; kk++, i++) + { + + /* Compute the power in the last sample from the previous */ + /* window placement, and subtract it from correlation accumulated */ + /* at the previous window placement. */ + /*----------------------------------------------------------------*/ + + L_Pwr = L_msu(L_Pwr, pswInScale[NP + F_LEN - i], + pswInScale[NP + F_LEN - kk]); + + /* Compute the power in the new sample for the current window */ + /* placement, and add it to L_Pwr to obtain the value of Phi(i,kk). */ + /*------------------------------------------------------------------*/ + + L_Pwr = L_mac(L_Pwr, pswInScale[NP - i], pswInScale[NP - kk]); + + L_temp = L_shl(L_Pwr, swNorm); /* Normalize */ + L_temp = L_mpy_ll(L_temp, pL_rFlatSstCoefs[k - 1]); /* Apply SST */ + + pppL_F[i][kk][0] = L_temp; /* Write to output array */ + pppL_B[i - 1][kk - 1][0] = L_temp; /* Write to output array */ + pppL_C[i][kk - 1][0] = L_temp; /* Write to output array */ + pppL_C[kk][i - 1][0] = L_temp; /* Write to output array */ + + } + + /* Compute the power in the last sample from the previous */ + /* window placement, and subtract it from correlation accumulated */ + /* at the previous window placement. */ + /*----------------------------------------------------------------*/ + + L_Pwr = L_msu(L_Pwr, pswInScale[F_LEN + k], pswInScale[F_LEN]); + + /* Compute the power in the new sample for the current window */ + /* placement, and add it to L_Pwr to obtain the value of Phi(i,kk). */ + /*------------------------------------------------------------------*/ + + L_Pwr = L_mac(L_Pwr, pswInScale[k], pswInScale[0]); + + L_temp = L_shl(L_Pwr, swNorm); /* Normalize the result */ + L_temp = L_mpy_ll(L_temp, pL_rFlatSstCoefs[k - 1]); /* Apply SST */ + + pppL_B[NP - k - 1][NP - 1][0] = L_temp; /* Write to output array */ + pppL_C[NP - k][NP - 1][0] = L_temp;/* Write to output array */ + + } + + /* Compute correlation Phi(0,NP) */ + /*-------------------------------*/ + + L_Pwr = L_mult(pswInScale[NP], pswInScale[0]); + for (n = 1; n < F_LEN; n++) + { + L_Pwr = L_mac(L_Pwr, pswInScale[NP + n], pswInScale[n]); + } + + L_temp = L_shl(L_Pwr, swNorm); /* Normalize the result */ + L_temp = L_mpy_ll(L_temp, pL_rFlatSstCoefs[NP - 1]); /* Apply SST */ + + pppL_C[0][NP - 1][0] = L_temp; /* Write to output array */ + + return (swNormPwr); + + } + + /*************************************************************************** + * + * FUNCTION NAME: filt4_2nd + * + * PURPOSE: Implements a fourth order filter by cascading two second + * order sections. + * + * INPUTS: + * + * pswCoef[0:9] An array of two sets of filter coefficients. + * + * pswIn[0:159] An array of input samples to be filtered, filtered + * output samples written to the same array. + * + * pswXstate[0:3] An array containing x-state memory for two 2nd order + * filter sections. + * + * pswYstate[0:7] An array containing y-state memory for two 2nd order + * filter sections. + * + * npts Number of samples to filter (must be even). + * + * shifts number of shifts to be made on output y(n). + * + * OUTPUTS: + * + * pswIn[0:159] Output array containing the filtered input samples. + * + * RETURN: + * + * none. + * + * DESCRIPTION: + * + * data structure: + * + * Coeff array order: (b2,b1,b0,a2,a1)Section 1;(b2,b1,b0,a2,a1)Section 2 + * Xstate array order: (x(n-2),x(n-1))Section 1; (x(n-2),x(n-1))Section 2 + * Ystate array order: y(n-2)MSB,y(n-2)LSB,y(n-1)MSB,y(n-1)LSB Section 1 + * y(n-2)MSB,y(n-2)LSB,y(n-1)MSB,y(n-1)LSB Section 2 + * + * REFERENCE: Sub-clause 4.1.1 GSM Recommendation 06.20 + * + * KEYWORDS: highpass filter, hp, HP, filter + * + *************************************************************************/ + + void Codec::filt4_2nd(int16_t pswCoeff[], int16_t pswIn[], + int16_t pswXstate[], int16_t pswYstate[], + int npts, int shifts) + { + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Do first second order section */ + /*-------------------------------*/ + + iir_d(&pswCoeff[0],pswIn,&pswXstate[0],&pswYstate[0],npts,shifts,1,0); + + + /* Do second second order section */ + /*--------------------------------*/ + + iir_d(&pswCoeff[5],pswIn,&pswXstate[2],&pswYstate[4],npts,shifts,0,1); + + } + + /*************************************************************************** + * + * FUNCTION NAME: findBestInQuantList + * + * PURPOSE: + * Given a list of quantizer vectors and their associated prediction + * errors, search the list for the iNumVectOut vectors and output them + * as a new list. + * + * INPUTS: psqlInList, iNumVectOut + * + * OUTPUTS: psqlBestOutList + * + * RETURN VALUE: none + * + * DESCRIPTION: + * + * The AFLAT recursion yields prediction errors. This routine finds + * the lowest candidate is the AFLAT recursion outputs. + * + * + * KEYWORDS: best quantlist find + * + * REFERENCE: Sub-clause 4.1.4.1 GSM Recommendation 06.20 + * + *************************************************************************/ + + void Codec::findBestInQuantList(struct QuantList psqlInList, + int iNumVectOut, + struct QuantList psqlBestOutList[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + int quantIndex, + bstIndex, + i; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* initialize the best list */ + /* invalidate, ensure they will be dropped */ + for (bstIndex = 0; bstIndex < iNumVectOut; bstIndex++) + { + psqlBestOutList[bstIndex].iNum = 1; + psqlBestOutList[bstIndex].iRCIndex = psqlInList.iRCIndex; + psqlBestOutList[bstIndex].pswPredErr[0] = 0x7fff; + } + + /* best list elements replaced in the order: 0,1,2,3... challenger must + * be < (not <= ) current best */ + for (quantIndex = 0; quantIndex < psqlInList.iNum; quantIndex++) + { + bstIndex = 0; + while (sub(psqlInList.pswPredErr[quantIndex], + psqlBestOutList[bstIndex].pswPredErr[0]) >= 0 && + bstIndex < iNumVectOut) + { + bstIndex++; /* only increments to next upon + * failure to beat "best" */ + } + + if (bstIndex < iNumVectOut) + { /* a new value is found */ + /* now add challenger to best list at index bstIndex */ + for (i = iNumVectOut - 1; i > bstIndex; i--) + { + psqlBestOutList[i].pswPredErr[0] = + psqlBestOutList[i - 1].pswPredErr[0]; + psqlBestOutList[i].iRCIndex = + psqlBestOutList[i - 1].iRCIndex; + } + /* get new best value and place in list */ + psqlBestOutList[bstIndex].pswPredErr[0] = + psqlInList.pswPredErr[quantIndex]; + psqlBestOutList[bstIndex].iRCIndex = + psqlInList.iRCIndex + quantIndex; + } + } + } + + /*************************************************************************** + * + * FUNCTION NAME: findPeak + * + * PURPOSE: + * + * The purpose of this function is to return the lag + * that maximizes CC/G within +- PEAK_VICINITY of the + * input lag. The input lag is an integer lag, and + * the search for a peak is done on the surrounding + * integer lags. + * + * INPUTS: + * + * swSingleResLag + * + * Input integer lag, expressed as lag * OS_FCTR + * + * pswCIn[0:127] + * + * C(k) sequence, k an integer + * + * pswGIn[0:127] + * + * G(k) sequence, k an integer + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * Integer lag where peak was found, or zero if no peak was found. + * The lag is expressed as lag * OS_FCTR + * + * DESCRIPTION: + * + * This routine is called from pitchLags(), and is used to do the + * interpolating CC/G peak search. This is used in a number of + * places in pitchLags(). See description 5.3.1. + * + * REFERENCE: Sub-clause 4.1.8.2 of GSM Recommendation 06.20 + * + * KEYWORDS: + * + *************************************************************************/ + + int16_t Codec::findPeak(int16_t swSingleResLag, + int16_t pswCIn[], + int16_t pswGIn[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swCmaxSqr, + swGmax, + swFullResPeak; + short int siUpperBound, + siLowerBound, + siRange, + siPeak; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* get upper and lower bounds for integer lags for peak search */ + /* ----------------------------------------------------------- */ + + siUpperBound = add(swSingleResLag, PEAK_VICINITY + 1); + if (sub(siUpperBound, LMAX + 1) > 0) + { + siUpperBound = LMAX + 1; + } + + siLowerBound = sub(swSingleResLag, PEAK_VICINITY + 1); + if (sub(siLowerBound, LMIN - 1) < 0) + { + siLowerBound = LMIN - 1; + } + + siRange = sub(siUpperBound, siLowerBound); + siRange = add(siRange, 1); + + /* do peak search */ + /* -------------- */ + + swCmaxSqr = 0; + swGmax = 0x3f; + + siPeak = fnBest_CG(&pswCIn[siLowerBound - LSMIN], + &pswGIn[siLowerBound - LSMIN], &swCmaxSqr, &swGmax, + siRange); + + /* if no max found, flag no peak */ + /* ----------------------------- */ + + if (add(siPeak, 1) == 0) + { + swFullResPeak = 0; + } + + /* determine peak location */ + /* if at boundary, flag no peak */ + /* else return lag at peak */ + /* ---------------------------- */ + + else + { + siPeak = add(siPeak, siLowerBound); + + if ((sub(siPeak, siLowerBound) == 0) || + (sub(siPeak, siUpperBound) == 0)) + { + swFullResPeak = 0; + } + else + { + swFullResPeak = shr(extract_l(L_mult(siPeak, OS_FCTR)), 1); + } + } + return (swFullResPeak); + } + + /*************************************************************************** + * + * FUNCTION NAME: flat + * + * PURPOSE: Computes the unquantized reflection coefficients from the + * input speech using the FLAT algorithm. Also computes the + * frame energy, and the index of the element in the R0 + * quantization table which best represents the frame energy. + * Calls function cov32 which computes the F, B, and C + * correlation arrays, required by the FLAT algorithm to + * compute the reflection coefficients. + * + * INPUT: + * + * pswSpeechIn[0:169] + * A sampled speech vector used to compute + * correlations need for generating the optimal + * reflection coefficients via the FLAT algorithm. + * + * OUTPUTS: + * + * pswRc[NP] An array of unquantized reflection coefficients. + * + * *piR0Inx An index of the quantized frame energy value. + * + * int32_t pL_VadAcf[4] + * An array with the autocorrelation coefficients to be + * used by the VAD. Generated by cov16(), a daughter + * function of flat(). + * + * int16_t *pswVadScalAuto + * Input scaling factor used by the VAD. + * Generated by cov16(), a daughter function of flat(). + * function. + * + * RETURN: L_R0 normalized frame energy value, required in DTX + * mode. + * + * DESCRIPTION: + * + * An efficient Fixed point LAtice Technique (FLAT) is used to compute + * the reflection coefficients, given B, F, and C arrays returned by + * function cov32. B, F, and C are backward, forward, and cross + * correlations computed from the input speech. The correlations + * are spectrally smoothed in cov32. + * + * + * REFERENCE: Sub-clause 4.1.3 of GSM Recommendation 06.20 + * + * keywords: LPC, FLAT, reflection coefficients, covariance, correlation, + * keywords: spectrum, energy, R0, spectral smoothing, SST + * + *************************************************************************/ + + int32_t Codec::flat(int16_t pswSpeechIn[], + int16_t pswRc[], + int *piR0Inx, + int32_t pL_VadAcf[], + int16_t *pswVadScalAuto) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + int16_t + swNum, + swDen, + swRcSq, + swSqrtOut, + swRShifts, + swShift, + swShift1; + int32_t + pppL_F[NP][NP][2], + pppL_B[NP][NP][2], + pppL_C[NP][NP][2], + L_Num, + L_TmpA, + L_TmpB, + L_temp, + L_sum, + L_R0, + L_Fik, + L_Bik, + L_Cik, + L_Cki; + short int i, + j, + k, + l, + j_0, + j_1; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Compute from the input speech the elements of the B, F, and C */ + /* arrays, which form the initial conditions for the FLAT algorithm. */ + /*-------------------------------------------------------------------*/ + + swRShifts = cov32(pswSpeechIn, pppL_B, pppL_F, pppL_C, &L_R0, + pL_VadAcf, pswVadScalAuto); + + /* Compute the intermediate quantities required by the R0 quantizer */ + /*------------------------------------------------------------------*/ + + if (L_R0 != 0) + { + swSqrtOut = sqroot(L_R0); /* If L_R0 > 0, compute sqrt */ + } + else + { + swSqrtOut = 0; /* L_R0 = 0, initialize sqrt(0) */ + } + + swRShifts = sub(S_SH + 2, swRShifts); + + /* If odd number of shifts compensate by sqrt(0.5) */ + /*-------------------------------------------------*/ + + if (swRShifts & 1) + { + L_temp = L_mult(swSqrtOut, 0x5a82); + } + else + { + L_temp = L_deposit_h(swSqrtOut); + } + swRShifts = shr(swRShifts, 1); + + if (swRShifts > 0) + { + L_temp = L_shr(L_temp, swRShifts); + } + else if (swRShifts < 0) + { + L_temp = 0; + } + + /* Given average energy L_temp, find the index in the R0 quantization */ + /* table which best represents it. */ + /*--------------------------------------------------------------------*/ + + *piR0Inx = r0Quant(L_temp); + + L_R0 = L_temp; /* save the unquantized R0 */ /* DTX mode */ + + /* Zero out the number of left-shifts to be applied to the */ + /* F, B, and C matrices. */ + /*----------------------------------------------------------*/ + + swShift = 0; + + /* Now compute the NP reflection coefficients */ + /*---------------------------------------------*/ + + for (j = 0; j < NP; j++) + { + + /* Initialize the modulo indices of the third dimension of arrays */ + /* F, B, and C, where indices j_0 and j_1 point to: */ + /* */ + /* j_0 = points to F, B, and C matrix values at stage j-0, which */ + /* is the current lattice stage. */ + /* j_1 = points to F, B, and C matrix values at stage j-1, which */ + /* is the previous lattice stage. */ + /* */ + /* Use of modulo address arithmetic permits to swap values of j_0 and */ + /* and j_1 at each lattice stage, thus eliminating the need to copy */ + /* the current elements of F, B, and C arrays, into the F, B, and C */ + /* arrays corresponding to the previous lattice stage, prior to */ + /* incrementing j, the index of the lattice filter stage. */ + /*--------------------------------------------------------------------*/ + + j_0 = (j + 1) % 2; + j_1 = j % 2; + + /* Get the numerator for computing the j-th reflection coefficient */ + /*-----------------------------------------------------------------*/ + + L_Num = L_add(L_shl(pppL_C[0][0][j_1], swShift), + L_shl(pppL_C[NP - j - 1][NP - j - 1][j_1], swShift)); + + /* Get the denominator for computing the j-th reflection coefficient */ + /*-------------------------------------------------------------------*/ + + L_temp = L_add(L_shl(pppL_F[0][0][j_1], swShift), + L_shl(pppL_B[0][0][j_1], swShift)); + L_TmpA = L_add(L_shl(pppL_F[NP - j - 1][NP - j - 1][j_1], swShift), + L_shl(pppL_B[NP - j - 1][NP - j - 1][j_1], swShift)); + L_sum = L_add(L_TmpA, L_temp); + L_sum = L_shr(L_sum, 1); + + /* Normalize the numerator and the denominator terms */ + /*---------------------------------------------------*/ + + swShift1 = norm_s(extract_h(L_sum)); + + L_sum = L_shl(L_sum, swShift1); + L_Num = L_shl(L_Num, swShift1); + + swNum = round(L_Num); + swDen = round(L_sum); + + if (swDen <= 0) + { + + /* Zero prediction error at the j-th lattice stage, zero */ + /* out remaining reflection coefficients and return. */ + /*-------------------------------------------------------*/ + + for (i = j; i < NP; i++) + { + pswRc[i] = 0; + } + + return (L_R0); + } + else + { + + /* Non-zero prediction error, check if the j-th reflection + * coefficient */ + /* about to be computed is stable. */ + /*-----------------------------------------------------------*/ + + if (sub(abs_s(swNum), swDen) >= 0) + { + + /* Reflection coefficient at j-th lattice stage unstable, so zero */ + /* out reflection coefficients for lattice stages i=j,...,NP-1, and */ + /* return. */ + /*-----------------------------------------------------------------*/ + + for (i = j; i < NP; i++) + { + pswRc[i] = 0; + } + + return (L_R0); + } + else + { + + /* j-th reflection coefficient is stable, compute it. */ + /*----------------------------------------------------*/ + + if (swNum < 0) + { + + swNum = negate(swNum); + pswRc[j] = divide_s(swNum, swDen); + + } + else + { + + pswRc[j] = divide_s(swNum, swDen); + pswRc[j] = negate(pswRc[j]); + + } /* j-th reflection coefficient + * sucessfully computed. */ + /*----------------------------------------------------*/ + + + } /* End of reflection coefficient + * stability test (and computation) */ + /*------------------------------------------------------------------*/ + + } /* End of non-zero prediction error + * case */ + /*----------------------------------------*/ + + + + /* If not at the last lattice stage, update F, B, and C arrays */ + /*-------------------------------------------------------------*/ + + if (j != NP - 1) + { + + /* Compute squared Rc[j] */ + /*-----------------------*/ + + swRcSq = mult_r(pswRc[j], pswRc[j]); + + i = 0; + k = 0; + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + + L_TmpA = L_add(L_Cik, L_Cik); + L_TmpA = L_mpy_ls(L_TmpA, pswRc[j]); + + /* Update the F array */ + /*--------------------*/ + + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + + L_temp = L_mpy_ls(L_Bik, swRcSq); + L_temp = L_add(L_temp, L_Fik); + pppL_F[i][k][j_0] = L_add(L_temp, L_TmpA); + + for (k = i + 1; k <= NP - j - 2; k++) + { + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + L_Cki = L_shl(pppL_C[k][i][j_1], swShift); + + L_TmpA = L_add(L_Cik, L_Cki); + L_TmpA = L_mpy_ls(L_TmpA, pswRc[j]); + + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + + L_TmpB = L_add(L_Bik, L_Fik); + L_TmpB = L_mpy_ls(L_TmpB, pswRc[j]); + + /* Update the F and C arrays */ + /*---------------------------------*/ + + L_temp = L_mpy_ls(L_Bik, swRcSq); + L_temp = L_add(L_temp, L_Fik); + pppL_F[i][k][j_0] = L_add(L_temp, L_TmpA); + + L_temp = L_mpy_ls(L_Cki, swRcSq); + L_temp = L_add(L_temp, L_Cik); + pppL_C[i][k - 1][j_0] = L_add(L_temp, L_TmpB); + + } + + k = NP - j - 1; + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + + L_TmpB = L_add(L_Bik, L_Fik); + L_TmpB = L_mpy_ls(L_TmpB, pswRc[j]); + + /* Update the C array */ + /*-----------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + L_Cki = L_shl(pppL_C[k][i][j_1], swShift); + + L_temp = L_mpy_ls(L_Cki, swRcSq); + L_temp = L_add(L_temp, L_Cik); + pppL_C[i][k - 1][j_0] = L_add(L_temp, L_TmpB); + + + for (i = 1; i <= NP - j - 2; i++) + { + + k = i; + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + + L_TmpA = L_add(L_Cik, L_Cik); + L_TmpA = L_mpy_ls(L_TmpA, pswRc[j]); + + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + + L_TmpB = L_add(L_Bik, L_Fik); + L_TmpB = L_mpy_ls(L_TmpB, pswRc[j]); + + /* Update F, B and C arrays */ + /*-----------------------------------*/ + + L_temp = L_mpy_ls(L_Bik, swRcSq); + L_temp = L_add(L_temp, L_Fik); + pppL_F[i][k][j_0] = L_add(L_temp, L_TmpA); + + L_temp = L_mpy_ls(L_Fik, swRcSq); + L_temp = L_add(L_temp, L_Bik); + pppL_B[i - 1][k - 1][j_0] = L_add(L_temp, L_TmpA); + + L_temp = L_mpy_ls(L_Cik, swRcSq); + L_temp = L_add(L_temp, L_Cik); + pppL_C[i][k - 1][j_0] = L_add(L_temp, L_TmpB); + + for (k = i + 1; k <= NP - j - 2; k++) + { + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + L_Cki = L_shl(pppL_C[k][i][j_1], swShift); + + L_TmpA = L_add(L_Cik, L_Cki); + L_TmpA = L_mpy_ls(L_TmpA, pswRc[j]); + + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + + L_TmpB = L_add(L_Bik, L_Fik); + L_TmpB = L_mpy_ls(L_TmpB, pswRc[j]); + + /* Update F, B and C arrays */ + /*-----------------------------------*/ + + L_temp = L_mpy_ls(L_Bik, swRcSq); + L_temp = L_add(L_temp, L_Fik); + pppL_F[i][k][j_0] = L_add(L_temp, L_TmpA); + + L_temp = L_mpy_ls(L_Fik, swRcSq); + L_temp = L_add(L_temp, L_Bik); + pppL_B[i - 1][k - 1][j_0] = L_add(L_temp, L_TmpA); + + L_temp = L_mpy_ls(L_Cki, swRcSq); + L_temp = L_add(L_temp, L_Cik); + pppL_C[i][k - 1][j_0] = L_add(L_temp, L_TmpB); + + L_temp = L_mpy_ls(L_Cik, swRcSq); + L_temp = L_add(L_temp, L_Cki); + pppL_C[k][i - 1][j_0] = L_add(L_temp, L_TmpB); + + } /* end of loop indexed by k */ + /*---------------------------*/ + + k = NP - j - 1; + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + L_Cki = L_shl(pppL_C[k][i][j_1], swShift); + + L_TmpA = L_add(L_Cik, L_Cki); + L_TmpA = L_mpy_ls(L_TmpA, pswRc[j]); + + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + + L_TmpB = L_add(L_Bik, L_Fik); + L_TmpB = L_mpy_ls(L_TmpB, pswRc[j]); + + /* Update B and C arrays */ + /*-----------------------------------*/ + + L_temp = L_mpy_ls(L_Fik, swRcSq); + L_temp = L_add(L_temp, L_Bik); + pppL_B[i - 1][k - 1][j_0] = L_add(L_temp, L_TmpA); + + L_temp = L_mpy_ls(L_Cki, swRcSq); + L_temp = L_add(L_temp, L_Cik); + pppL_C[i][k - 1][j_0] = L_add(L_temp, L_TmpB); + + } /* end of loop indexed by i */ + /*---------------------------*/ + + i = NP - j - 1; + for (k = i; k <= NP - j - 1; k++) + { + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + + L_TmpA = L_add(L_Cik, L_Cik); + L_TmpA = L_mpy_ls(L_TmpA, pswRc[j]); + + /* Update B array */ + /*-----------------------------------*/ + + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + + L_temp = L_mpy_ls(L_Fik, swRcSq); + L_temp = L_add(L_temp, L_Bik); + pppL_B[i - 1][k - 1][j_0] = L_add(L_temp, L_TmpA); + + } /* end of loop indexed by k */ + /*-----------------------------------------------------------*/ + + /* OR the F and B matrix diagonals to find maximum for normalization */ + /*********************************************************************/ + + L_TmpA = 0; + for (l = 0; l <= NP - j - 2; l++) + { + L_TmpA |= pppL_F[l][l][j_0]; + L_TmpA |= pppL_B[l][l][j_0]; + } + /* Compute the shift count to be applied to F, B, and C arrays */ + /* at the next lattice stage. */ + /*-------------------------------------------------------------*/ + + if (L_TmpA > 0) + { + swShift = norm_l(L_TmpA); + swShift = sub(swShift, CVSHIFT); + } + else + { + swShift = 0; + } + + } /* End of update of F, B, and C + * arrays for the next lattice stage */ + /*----------------------------------------------------------------*/ + + } /* Finished computation of + * reflection coefficients */ + /*--------------------------------------------------------------*/ + + return (L_R0); + + } + + /************************************************************************** + * + * FUNCTION NAME: fnBest_CG + * + * PURPOSE: + * The purpose of this function is to determine the C:G pair from the + * input arrays which maximize C*C/G + * + * INPUTS: + * + * pswCframe[0:siNumPairs] + * + * pointer to start of the C frame vector + * + * pswGframe[0:siNumPairs] + * + * pointer to start of the G frame vector + * + * pswCmaxSqr + * + * threshold Cmax**2 or 0 if no threshold + * + * pswGmax + * + * threshold Gmax, must be > 0 + * + * siNumPairs + * + * number of C:G pairs to test + * + * OUTPUTS: + * + * pswCmaxSqr + * + * final Cmax**2 value + * + * pswGmax + * + * final Gmax value + * + * RETURN VALUE: + * + * siMaxLoc + * + * index of Cmax in the input C matrix or -1 if none + * + * DESCRIPTION: + * + * test the result of (C * C * Gmax) - (Cmax**2 * G) + * if the result is > 0 then a new max has been found + * the Cmax**2, Gmax and MaxLoc parameters are all updated accordingly. + * if no new max is found for all NumPairs then MaxLoc will retain its + * original value + * + * REFERENCE: Sub-clause 4.1.8.1, 4.1.8.2, and 4.1.8.3 of GSM + * Recommendation 06.20 + * + * KEYWORDS: C_Frame, G_Frame, Cmax, Gmax, DELTA_LAGS, PITCH_LAGS + * + + ****************************************************************************/ + + short int Codec::fnBest_CG(int16_t pswCframe[], int16_t pswGframe[], + int16_t *pswCmaxSqr, int16_t *pswGmax, + short int siNumPairs) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |___________________________________________________________________________| + */ + + int32_t L_Temp2; + int16_t swCmaxSqr, + swGmax, + swTemp; + short int siLoopCnt, + siMaxLoc; + + /*_________________________________________________________________________ + | | + | Executable Code | + |___________________________________________________________________________| + */ + + /* initialize */ + /* ---------- */ + + swCmaxSqr = *pswCmaxSqr; + swGmax = *pswGmax; + siMaxLoc = -1; + + for (siLoopCnt = 0; siLoopCnt < siNumPairs; siLoopCnt++) + { + + /* make sure both C and energy > 0 */ + /* ------------------------------- */ + + if ((pswGframe[siLoopCnt] > 0) && (pswCframe[siLoopCnt] > 0)) + { + + /* calculate (C * C) */ + /* ----------------- */ + + swTemp = mult_r(pswCframe[siLoopCnt], pswCframe[siLoopCnt]); + + /* calculate (C * C * Gmax) */ + /* ------------------------ */ + + L_Temp2 = L_mult(swTemp, swGmax); + + /* calculate (C * C * Gmax) - (Cmax**2 * G) */ + /* ----------------------------------------- */ + + L_Temp2 = L_msu(L_Temp2, swCmaxSqr, pswGframe[siLoopCnt]); + + /* if new max found, update it and its location */ + /* -------------------------------------------- */ + + if (L_Temp2 > 0) + { + swCmaxSqr = swTemp; /* Cmax**2 = current C * C */ + swGmax = pswGframe[siLoopCnt]; /* Gmax */ + siMaxLoc = siLoopCnt; /* max location = current (C) + * location */ + } + } + } + + /* set output */ + /* ---------- */ + + *pswCmaxSqr = swCmaxSqr; + *pswGmax = swGmax; + return (siMaxLoc); + } + + /*************************************************************************** + * + * FUNCTION NAME: fnExp2 + * + * PURPOSE: + * The purpose of this function is to implement a base two exponential + * 2**(32*x) by polynomial approximation + * + * + * INPUTS: + * + * L_Input + * + * unnormalized input exponent (input range constrained + * to be < 0; for input < -0.46 output is 0) + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swTemp4 + * + * exponential output + * + * DESCRIPTION: + * + * polynomial approximation is used for the generation of the exponential + * + * 2**(32*X) = 0.1713425*X*X + 0.6674432*X + 0.9979554 + * c2 c1 c0 + * + * REFERENCE: Sub-clause 4.1.8.2 of GSM Recommendation 06.20, eqn 3.9 + * + * KEYWORDS: EXP2, DELTA_LAGS + * + *************************************************************************/ + + int16_t Codec::fnExp2(int32_t L_Input) + { + + /*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| + */ + static int16_t pswPCoefE[3] = + { /* c2, c1, c0 */ + 0x15ef, 0x556f, 0x7fbd + }; + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swTemp1, + swTemp2, + swTemp3, + swTemp4; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* initialize */ + /* ---------- */ + + swTemp3 = 0x0020; + + /* determine normlization shift count */ + /* ---------------------------------- */ + + swTemp1 = extract_h(L_Input); + L_Input = L_mult(swTemp1, swTemp3); + swTemp2 = extract_h(L_Input); + + /* determine un-normalized shift count */ + /* ----------------------------------- */ + + swTemp3 = -0x0001; + swTemp4 = sub(swTemp3, swTemp2); + + /* normalize input */ + /* --------------- */ + + L_Input = L_Input & LSP_MASK; + L_Input = L_add(L_Input, L_deposit_h(swTemp3)); + + L_Input = L_shr(L_Input, 1); + swTemp1 = extract_l(L_Input); + + /* calculate x*x*c2 */ + /* ---------------- */ + + swTemp2 = mult_r(swTemp1, swTemp1); + L_Input = L_mult(swTemp2, pswPCoefE[0]); + + /* calculate x*x*c2 + x*c1 */ + /* ----------------------- */ + + L_Input = L_mac(L_Input, swTemp1, pswPCoefE[1]); + + /* calculate x*x*c2 + x*c1 + c0 */ + /* --------------------------- */ + + L_Input = L_add(L_Input, L_deposit_h(pswPCoefE[2])); + + /* un-normalize exponent if its requires it */ + /* ---------------------------------------- */ + + if (swTemp4 > 0) + { + L_Input = L_shr(L_Input, swTemp4); + } + + /* return result */ + /* ------------- */ + + swTemp4 = extract_h(L_Input); + return (swTemp4); + } + + /*************************************************************************** + * + * FUNCTION NAME: fnLog2 + * + * PURPOSE: + * The purpose of this function is to take the log base 2 of input and + * divide by 32 and return; i.e. output = log2(input)/32 + * + * INPUTS: + * + * L_Input + * + * input + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * int16_t + * + * output + * + * DESCRIPTION: + * + * log2(x) = 4.0 * (-.3372223*x*x + .9981958*x -.6626105) + * c0 c1 c2 (includes sign) + * + * REFERENCE: Sub-clause 4.1.8.2 of GSM Recommendation 06.20, eqn 3.9 + * + * KEYWORDS: log, logarithm, logbase2, fnLog2 + * + *************************************************************************/ + + int16_t Codec::fnLog2(int32_t L_Input) + { + + /*_________________________________________________________________________ + | | + | Static Variables | + |_________________________________________________________________________| + */ + + static int16_t + swC0 = -0x2b2a, + swC1 = 0x7fc5, + swC2 = -0x54d0; + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + short int siShiftCnt; + int16_t swInSqrd, + swIn; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* normalize input and store shifts required */ + /* ----------------------------------------- */ + + siShiftCnt = norm_l(L_Input); + L_Input = L_shl(L_Input, siShiftCnt); + siShiftCnt = add(siShiftCnt, 1); + siShiftCnt = negate(siShiftCnt); + + /* calculate x*x*c0 */ + /* ---------------- */ + + swIn = extract_h(L_Input); + swInSqrd = mult_r(swIn, swIn); + L_Input = L_mult(swInSqrd, swC0); + + /* add x*c1 */ + /* --------- */ + + L_Input = L_mac(L_Input, swIn, swC1); + + /* add c2 */ + /* ------ */ + + L_Input = L_add(L_Input, L_deposit_h(swC2)); + + /* apply *(4/32) */ + /* ------------- */ + + L_Input = L_shr(L_Input, 3); + L_Input = L_Input & 0x03ffffff; + siShiftCnt = shl(siShiftCnt, 10); + L_Input = L_add(L_Input, L_deposit_h(siShiftCnt)); + + /* return log */ + /* ---------- */ + + return (round(L_Input)); + } + + /*************************************************************************** + * + * FUNCTION NAME: getCCThreshold + * + * PURPOSE: + * The purpose of this function is to calculate a threshold for other + * correlations (subject to limits), given subframe energy (Rp0), + * correlation squared (CC), and energy of delayed sequence (G) + * + * INPUTS: + * + * swRp0 + * + * energy of the subframe + * + * swCC + * + * correlation (squared) of subframe and delayed sequence + * + * swG + * + * energy of delayed sequence + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swCCThreshold + * + * correlation (squared) threshold + * + * DESCRIPTION: + * + * CCt/0.5 = R - R(antilog(SCALE*log(max(CLAMP,(RG-CC)/RG)))) + * + * The threshold CCt is then applied with an understood value of Gt = 0.5 + * + * REFERENCE: Sub-clause 4.1.8.2 of GSM Recommendation 06.20, eqn 3.9 + * + * KEYWORDS: getCCThreshold, getccthreshold, GET_CSQ_THRES + * + *************************************************************************/ + + int16_t Codec::getCCThreshold(int16_t swRp0, + int16_t swCC, + int16_t swG) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swPGainClamp, + swPGainScale, + sw1; + int32_t L_1; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* load CLAMP and SCALE */ + /* -------------------- */ + + swPGainClamp = PGAIN_CLAMP; + swPGainScale = PGAIN_SCALE; + + /* calculate RG-CC */ + /* --------------- */ + + L_1 = L_mult(swRp0, swG); + sw1 = extract_h(L_1); + L_1 = L_sub(L_1, L_deposit_h(swCC)); + + /* if RG - CC > 0 do max(CLAMP, (RG-CC)/RG) */ + /* ---------------------------------------- */ + + if (L_1 > 0) + { + + sw1 = divide_s(extract_h(L_1), sw1); + + L_1 = L_deposit_h(sw1); + + if (sub(sw1, swPGainClamp) <= 0) + { + L_1 = L_deposit_h(swPGainClamp); + } + } + /* else max(CLAMP, (RG-CC)/RG) is CLAMP */ + /* ------------------------------------ */ + + else + { + L_1 = L_deposit_h(swPGainClamp); + } + + /* L_1 holds max(CLAMP, (RG-CC)/RG) */ + /* do antilog( SCALE * log( max() ) ) */ + /* ---------------------------------- */ + + sw1 = fnLog2(L_1); + + L_1 = L_mult(sw1, swPGainScale); + + sw1 = fnExp2(L_1); + + + /* do R - (R * antilog()) */ + /* ---------------------- */ + + L_1 = L_deposit_h(swRp0); + L_1 = L_msu(L_1, swRp0, sw1); + + /* apply Gt value */ + /* -------------- */ + + L_1 = L_shr(L_1, 1); + + return (extract_h(L_1)); + } + + + /*************************************************************************** + * + * FUNCTION NAME: getNWCoefs + * + * PURPOSE: + * + * Obtains best all-pole fit to various noise weighting + * filter combinations + * + * INPUTS: + * + * pswACoefs[0:9] - A(z) coefficient array + * psrNWCoefs[0:9] - filter smoothing coefficients + * + * OUTPUTS: + * + * pswHCoefs[0:9] - H(z) coefficient array + * + * RETURN VALUE: + * + * None + * + * DESCRIPTION: + * + * The function getNWCoefs() derives the spectral noise weighting + * coefficients W(z)and H(z). W(z) and H(z) actually consist of + * three filters in cascade. To avoid having such a complicated + * filter required for weighting, the filters are reduced to a + * single filter. + * + * This is accomplished by passing an impulse through the cascased + * filters. The impulse response of the filters is used to generate + * autocorrelation coefficients, which are then are transformed into + * a single direct form estimate of W(z) and H(z). This estimate is + * called HHat(z) in the documentation. + * + * + * REFERENCE: Sub-clause 4.1.7 of GSM Recommendation 06.20 + * + * KEYWORDS: spectral noise weighting, direct form coefficients + * KEYWORDS: getNWCoefs + * + *************************************************************************/ + + void Codec::getNWCoefs(int16_t pswACoefs[], + int16_t pswHCoefs[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t pswCoefTmp2[NP], + pswCoefTmp3[NP], + pswVecTmp[S_LEN], + pswVecTmp2[S_LEN], + pswTempRc[NP]; + int16_t swNormShift, + iLoopCnt, + iLoopCnt2; + int32_t pL_AutoCorTmp[NP + 1], + L_Temp; + short int siNum, + k; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Calculate smoothing parameters for all-zero filter */ + /* -------------------------------------------------- */ + + for (iLoopCnt = 0; iLoopCnt < NP; iLoopCnt++) + { + pswCoefTmp2[iLoopCnt] + = mult_r(psrNWCoefs[iLoopCnt], pswACoefs[iLoopCnt]); + } + + /* Calculate smoothing parameters for all-pole filter */ + /* -------------------------------------------------- */ + + for (iLoopCnt = 0; iLoopCnt < NP; iLoopCnt++) + { + pswCoefTmp3[iLoopCnt] = msu_r(0, psrNWCoefs[iLoopCnt + NP], + pswACoefs[iLoopCnt]); + } + + /* Get impulse response of 1st filter */ + /* Done by direct form IIR filter of order NP zero input response */ + /* -------------------------------------------------------------- */ + + lpcIrZsIir(pswACoefs, pswVecTmp2); + + /* Send impulse response of 1st filter through 2nd filter */ + /* All-zero filter (FIR) */ + /* ------------------------------------------------------ */ + + lpcZsFir(pswVecTmp2, pswCoefTmp2, pswVecTmp); + + /* Send impulse response of 2nd filter through 3rd filter */ + /* All-pole filter (IIR) */ + /* ------------------------------------------------------ */ + + lpcZsIirP(pswVecTmp, pswCoefTmp3); + + /* Calculate energy in impulse response */ + /* ------------------------------------ */ + + swNormShift = g_corr1(pswVecTmp, &L_Temp); + + pL_AutoCorTmp[0] = L_Temp; + + /* Calculate normalized autocorrelation function */ + /* --------------------------------------------- */ + + for (k = 1; k <= NP; k++) + { + + /* Calculate R(k), equation 2.31 */ + /* ----------------------------- */ + + L_Temp = L_mult(pswVecTmp[0], pswVecTmp[0 + k]); + + for (siNum = S_LEN - k, iLoopCnt2 = 1; iLoopCnt2 < siNum; iLoopCnt2++) + { + L_Temp = L_mac(L_Temp, pswVecTmp[iLoopCnt2], + pswVecTmp[iLoopCnt2 + k]); + } + + /* Normalize R(k) relative to R(0): */ + /* -------------------------------- */ + + pL_AutoCorTmp[k] = L_shl(L_Temp, swNormShift); + + } + + + /* Convert normalized autocorrelations to direct form coefficients */ + /* --------------------------------------------------------------- */ + + aFlatRcDp(pL_AutoCorTmp, pswTempRc); + rcToADp(ASCALE, pswTempRc, pswHCoefs); + + } + + /*************************************************************************** + * + * FUNCTION NAME: getNextVec + * + * PURPOSE: + * The purpose of this function is to get the next vector in the list. + * + * INPUTS: none + * + * OUTPUTS: pswRc + * + * RETURN VALUE: none + * + * DESCRIPTION: + * + * Both the quantizer and pre-quantizer are set concatenated 8 bit + * words. Each of these words represents a reflection coefficient. + * The 8 bit words, are actually indices into a reflection + * coefficient lookup table. Memory is organized in 16 bit words, so + * there are two reflection coefficients per ROM word. + * + * + * The full quantizer is subdivided into blocks. Each of the + * pre-quantizers vectors "points" to a full quantizer block. The + * vectors in a block, are comprised of either three or four + * elements. These are concatenated, without leaving any space + * between them. + * + * A block of full quantizer elements always begins on an even word. + * This may or may not leave a space depending on vector quantizer + * size. + * + * getNextVec(), serves to abstract this arcane data format. Its + * function is to simply get the next reflection coefficient vector + * in the list, be it a pre or full quantizer list. This involves + * figuring out whether to pick the low or the high part of the 16 + * bit ROM word. As well as transforming the 8 bit stored value + * into a fractional reflection coefficient. It also requires a + * setup routine to initialize iWordPtr and iWordHalfPtr, two + * variables global to this file. + * + * + * + * REFERENCE: Sub-clause 4.1.4.1 of GSM Recommendation 06.20 + * + * KEYWORDS: Quant quant vector quantizer + * + *************************************************************************/ + + void Codec::getNextVec(int16_t pswRc[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + int i; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + i = iLow; + + if (iThree) + { + + if (iWordHalfPtr == HIGH) + { + pswRc[i++] = psrSQuant[high(psrTable[iWordPtr])]; + pswRc[i++] = psrSQuant[low(psrTable[iWordPtr++])]; + pswRc[i] = psrSQuant[high(psrTable[iWordPtr])]; + iWordHalfPtr = LOW; + } + else + { + pswRc[i++] = psrSQuant[low(psrTable[iWordPtr++])]; + pswRc[i++] = psrSQuant[high(psrTable[iWordPtr])]; + pswRc[i] = psrSQuant[low(psrTable[iWordPtr++])]; + iWordHalfPtr = HIGH; + } + + } + else + { + pswRc[i++] = psrSQuant[high(psrTable[iWordPtr])]; + pswRc[i++] = psrSQuant[low(psrTable[iWordPtr++])]; + pswRc[i++] = psrSQuant[high(psrTable[iWordPtr])]; + pswRc[i] = psrSQuant[low(psrTable[iWordPtr++])]; + } + } + + /*************************************************************************** + * + * FUNCTION NAME: getSfrmLpcTx + * + * PURPOSE: + * Given frame information from past and present frame, interpolate + * (or copy) the frame based lpc coefficients into subframe + * lpc coeffs, i.e. the ones which will be used by the subframe + * as opposed to those coded and transmitted. + * + * INPUT: + * swPrevR0,swNewR0 - Rq0 for the last frame and for this frame. + * These are the decoded values, not the codewords. + * + * Previous lpc coefficients from the previous FRAME: + * in all filters below array[0] is the t=-1 element array[NP-1] + * t=-NP element. + * pswPrevFrmKs[NP] - decoded version of the rc's tx'd last frame + * pswPrevFrmAs[NP] - the above K's converted to A's. i.e. direct + * form coefficients. + * pswPrevFrmSNWCoef[NP] - Coefficients for the Spectral Noise + * weighting filter from the previous frame + * + * pswHPFSppech - pointer to High Pass Filtered Input speech + * + * pswSoftInterp - a flag containing the soft interpolation + * decision. + * + * Current lpc coefficients from the current frame: + * pswNewFrmKs[NP],pswNewFrmAs[NP], + * pswNewFrmSNWCoef[NP] - Spectral Noise Weighting Coefficients + * for the current frame + * ppswSNWCoefAs[1][NP] - pointer into a matrix containing + * the interpolated and uninterpolated LP Coefficient + * values for the Spectral Noise Weighting Filter. + * + * OUTPUT: + * psnsSqrtRs[N_SUB] - a normalized number (struct NormSw) + * containing an estimate + * of RS for each subframe. (number and a shift) + * + * ppswSynthAs[N_SUM][NP] - filter coefficients used by the + * synthesis filter. + * + * DESCRIPTION: + * For interpolated subframes, the direct form coefficients + * are converted to reflection coeffiecients to check for + * filter stability. If unstable, the uninterpolated coef. + * are used for that subframe. + * + * + * REFERENCE: Sub-clause of 4.1.6 and 4.1.7 of GSM Recommendation + * 06.20 + * + * KEYWORDS: soft interpolation, int_lpc, interpolate, atorc, res_eng + * + *************************************************************************/ + + + void Codec::getSfrmLpcTx(int16_t swPrevR0, int16_t swNewR0, + /* last frm*/ + int16_t pswPrevFrmKs[], int16_t pswPrevFrmAs[], + int16_t pswPrevFrmSNWCoef[], + /* this frm*/ + int16_t pswNewFrmKs[], int16_t pswNewFrmAs[], + int16_t pswNewFrmSNWCoef[], + int16_t pswHPFSpeech[], + /* output */ + short *pswSoftInterp, + struct NormSw *psnsSqrtRs, + int16_t ppswSynthAs[][NP], int16_t ppswSNWCoefAs[][NP]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swSi; + int32_t L_Temp; + short int siSfrm, + siStable, + i; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* perform interpolation - both for synth filter and noise wgt filt */ + /*------------------------------------------------------------------*/ + siSfrm = 0; + siStable = interpolateCheck(pswPrevFrmKs, pswPrevFrmAs, + pswPrevFrmAs, pswNewFrmAs, + psrOldCont[siSfrm], psrNewCont[siSfrm], + swPrevR0, + &psnsSqrtRs[siSfrm], + ppswSynthAs[siSfrm]); + if (siStable) + { + for (i = 0; i < NP; i++) + { + L_Temp = L_mult(pswNewFrmSNWCoef[i], psrNewCont[siSfrm]); + ppswSNWCoefAs[siSfrm][i] = mac_r(L_Temp, pswPrevFrmSNWCoef[i], + psrOldCont[siSfrm]); + } + } + else + { + + /* this subframe is unstable */ + /*---------------------------*/ + + for (i = 0; i < NP; i++) + { + ppswSNWCoefAs[siSfrm][i] = pswPrevFrmSNWCoef[i]; + } + + } + + /* interpolate subframes one and two */ + /*-----------------------------------*/ + + for (siSfrm = 1; siSfrm < N_SUB - 1; siSfrm++) + { + siStable = interpolateCheck(pswNewFrmKs, pswNewFrmAs, + pswPrevFrmAs, pswNewFrmAs, + psrOldCont[siSfrm], psrNewCont[siSfrm], + swNewR0, + &psnsSqrtRs[siSfrm], + ppswSynthAs[siSfrm]); + if (siStable) + { + for (i = 0; i < NP; i++) + { + L_Temp = L_mult(pswNewFrmSNWCoef[i], psrNewCont[siSfrm]); + ppswSNWCoefAs[siSfrm][i] = mac_r(L_Temp, pswPrevFrmSNWCoef[i], + psrOldCont[siSfrm]); + } + } + else + { + /* this sfrm has unstable filter coeffs, would like to interp but + * cant */ + /*--------------------------------------*/ + + for (i = 0; i < NP; i++) + { + ppswSNWCoefAs[siSfrm][i] = pswNewFrmSNWCoef[i]; + } + + } + } + + + /* the last subframe: never interpolate. */ + /*--------------------------------------*/ + + siSfrm = 3; + for (i = 0; i < NP; i++) + { + ppswSNWCoefAs[siSfrm][i] = pswNewFrmSNWCoef[i]; + ppswSynthAs[siSfrm][i] = pswNewFrmAs[i]; + } + + /* calculate the residual energy for the last subframe */ + /*-----------------------------------------------------*/ + + res_eng(pswNewFrmKs, swNewR0, &psnsSqrtRs[siSfrm]); + + + + /* done with interpolation, now compare the two sets of coefs. */ + /* make the decision whether to interpolate (1) or not (0) */ + /*---------------------------------------------------------------*/ + + swSi = compResidEnergy(pswHPFSpeech, + ppswSynthAs, pswPrevFrmAs, + pswNewFrmAs, psnsSqrtRs); + + if (swSi == 0) + { + + /* no interpolation done: copy the frame based data to output + * coeffiecient arrays */ + + siSfrm = 0; + for (i = 0; i < NP; i++) + { + ppswSNWCoefAs[siSfrm][i] = pswPrevFrmSNWCoef[i]; + ppswSynthAs[siSfrm][i] = pswPrevFrmAs[i]; + } + + /* get RS (energy in the residual) for subframe 0 */ + /*------------------------------------------------*/ + + res_eng(pswPrevFrmKs, swPrevR0, &psnsSqrtRs[siSfrm]); + + /* for subframe 1 and all subsequent sfrms, use lpc and R0 from new frm */ + /*---------------------------------------------------------------------*/ + + res_eng(pswNewFrmKs, swNewR0, &psnsSqrtRs[1]); + + for (siSfrm = 2; siSfrm < N_SUB; siSfrm++) + psnsSqrtRs[siSfrm] = psnsSqrtRs[1]; + + for (siSfrm = 1; siSfrm < N_SUB; siSfrm++) + { + for (i = 0; i < NP; i++) + { + ppswSNWCoefAs[siSfrm][i] = pswNewFrmSNWCoef[i]; + ppswSynthAs[siSfrm][i] = pswNewFrmAs[i]; + } + } + } + + *pswSoftInterp = swSi; + } + + /*************************************************************************** + * + * FUNCTION NAME: iir_d + * + * PURPOSE: Performs one second order iir section using double-precision. + * feedback,single precision xn and filter coefficients + * + * INPUTS: + * + * pswCoef[0:4] An array of filter coefficients. + * + * pswIn[0:159] An array of input samples to be filtered, filtered + * output samples written to the same array. + * + * pswXstate[0:1] An array containing x-state memory. + * + * pswYstate[0:3] An array containing y-state memory. + * + * npts Number of samples to filter (must be even). + * + * shifts number of shifts to be made on output y(n) before + * storing to y(n) states. + * + * swPreFirDownSh number of shifts apply to signal before the FIR. + * + * swFinalUpShift number of shifts apply to signal before outputting. + * + * OUTPUTS: + * + * pswIn[0:159] Output array containing the filtered input samples. + * + * RETURN: + * + * none. + * + * DESCRIPTION: + * + * Transfer function implemented: + * (b0 + b1*z-1 + b2*z-2)/(a0 - a1*z-1 - a2*z-2+ + * data structure: + * Coeff array order: b2,b1,b0,a2,a1 + * Xstate array order: x(n-2),x(n-1) + * Ystate array order: y(n-2)MSB,y(n-2)LSB,y(n-1)MSB,y(n-1)LSB + * + * There is no elaborate discussion of the filter, since it is + * trivial. + * + * The filter's cutoff frequency is 120 Hz. + * + * REFERENCE: Sub-clause 4.1.1 GSM Recommendation 06.20 + * + * KEYWORDS: highpass filter, hp, HP, filter + * + *************************************************************************/ + + void Codec::iir_d(int16_t pswCoeff[], int16_t pswIn[], int16_t pswXstate[], + int16_t pswYstate[], int npts, int shifts, + int16_t swPreFirDownSh, int16_t swFinalUpShift) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int loop_cnt; + int32_t L_sumA, + L_sumB; + int16_t swTemp, + pswYstate_0, + pswYstate_1, + pswYstate_2, + pswYstate_3, + pswXstate_0, + pswXstate_1, + swx0, + swx1; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* initialize the temporary state variables */ + /*------------------------------------------*/ + + pswYstate_0 = pswYstate[0]; + pswYstate_1 = pswYstate[1]; + pswYstate_2 = pswYstate[2]; + pswYstate_3 = pswYstate[3]; + + pswXstate_0 = pswXstate[0]; + pswXstate_1 = pswXstate[1]; + + for (loop_cnt = 0; loop_cnt < npts; loop_cnt += 2) + { + + swx0 = shr(pswIn[loop_cnt], swPreFirDownSh); + swx1 = shr(pswIn[loop_cnt + 1], swPreFirDownSh); + + L_sumB = L_mult(pswYstate_1, pswCoeff[3]); + L_sumB = L_mac(L_sumB, pswYstate_3, pswCoeff[4]); + L_sumB = L_shr(L_sumB, 14); + L_sumB = L_mac(L_sumB, pswYstate_0, pswCoeff[3]); + L_sumB = L_mac(L_sumB, pswYstate_2, pswCoeff[4]); + + + L_sumA = L_mac(L_sumB, pswCoeff[0], pswXstate_0); + L_sumA = L_mac(L_sumA, pswCoeff[1], pswXstate_1); + L_sumA = L_mac(L_sumA, pswCoeff[2], swx0); + + L_sumA = L_shl(L_sumA, shifts); + + pswXstate_0 = swx0; /* Update X state x(n-1) <- x(n) */ + + /* Update double precision Y state temporary variables */ + /*-----------------------------------------------------*/ + + pswYstate_0 = extract_h(L_sumA); + swTemp = extract_l(L_sumA); + swTemp = shr(swTemp, 2); + pswYstate_1 = 0x3fff & swTemp; + + /* Round, store output sample and increment to next input sample */ + /*---------------------------------------------------------------*/ + + pswIn[loop_cnt] = round(L_shl(L_sumA, swFinalUpShift)); + + L_sumB = L_mult(pswYstate_3, pswCoeff[3]); + L_sumB = L_mac(L_sumB, pswYstate_1, pswCoeff[4]); + L_sumB = L_shr(L_sumB, 14); + L_sumB = L_mac(L_sumB, pswYstate_2, pswCoeff[3]); + L_sumB = L_mac(L_sumB, pswYstate_0, pswCoeff[4]); + + + L_sumA = L_mac(L_sumB, pswCoeff[0], pswXstate_1); + L_sumA = L_mac(L_sumA, pswCoeff[1], pswXstate_0); + L_sumA = L_mac(L_sumA, pswCoeff[2], swx1); + + L_sumA = L_shl(L_sumA, shifts); + + pswXstate_1 = swx1; /* Update X state x(n-1) <- x(n) */ + + /* Update double precision Y state temporary variables */ + /*-----------------------------------------------------*/ + + pswYstate_2 = extract_h(L_sumA); + + swTemp = extract_l(L_sumA); + swTemp = shr(swTemp, 2); + pswYstate_3 = 0x3fff & swTemp; + + /* Round, store output sample and increment to next input sample */ + /*---------------------------------------------------------------*/ + + pswIn[loop_cnt + 1] = round(L_shl(L_sumA, swFinalUpShift)); + + } + + /* update the states for the next frame */ + /*--------------------------------------*/ + + pswYstate[0] = pswYstate_0; + pswYstate[1] = pswYstate_1; + pswYstate[2] = pswYstate_2; + pswYstate[3] = pswYstate_3; + + pswXstate[0] = pswXstate_0; + pswXstate[1] = pswXstate_1; + + } + + /*************************************************************************** + * + * FUNCTION NAME: initPBarVBarFullL + * + * PURPOSE: Given the int32_t normalized correlation sequence, function + * initPBarVBarL initializes the int32_t initial condition + * arrays pL_PBarFull and pL_VBarFull for a full 10-th order LPC + * filter. It also shifts down the pL_VBarFull and pL_PBarFull + * arrays by a global constant RSHIFT bits. The pL_PBarFull and + * pL_VBarFull arrays are used to set the initial int16_t + * P and V conditions which are used in the actual search of the + * Rc prequantizer and the Rc quantizer. + * + * This is an implementation of equations 4.14 and + * 4.15. + * + * INPUTS: + * + * pL_CorrelSeq[0:NP] + * A int32_t normalized autocorrelation array computed + * from unquantized reflection coefficients. + * + * RSHIFT The number of right shifts to be applied to the + * input correlations prior to initializing the elements + * of pL_PBarFull and pL_VBarFull output arrays. RSHIFT + * is a global constant. + * + * OUTPUTS: + * + * pL_PBarFull[0:NP-1] + * A int32_t output array containing the P initial + * conditions for the full 10-th order LPC filter. + * The address of the 0-th element of pL_PBarFull + * is passed in when function initPBarVBarFullL is + * called. + * + * pL_VBarFull[-NP+1:NP-1] + * A int32_t output array containing the V initial + * conditions for the full 10-th order LPC filter. + * The address of the 0-th element of pL_VBarFull is + * passed in when function initPBarVBarFullL is called. + * RETURN: + * none. + * + * REFERENCE: Sub-clause 4.1.4.1 GSM Recommendation 06.20 + * + *************************************************************************/ + + void Codec::initPBarFullVBarFullL(int32_t pL_CorrelSeq[], + int32_t pL_PBarFull[], + int32_t pL_VBarFull[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int i, + bound; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Initialize the AFLAT recursion PBarFull and VBarFull 32 bit arrays */ + /* for a 10-th order LPC filter. */ + /*--------------------------------------------------------------------*/ + + bound = NP - 1; + + for (i = 0; i <= bound; i++) + { + pL_PBarFull[i] = L_shr(pL_CorrelSeq[i], RSHIFT); + } + + for (i = -bound; i < 0; i++) + { + pL_VBarFull[i] = pL_PBarFull[-i - 1]; + } + + for (i = 0; i < bound; i++) + { + pL_VBarFull[i] = pL_PBarFull[i + 1]; + } + + pL_VBarFull[bound] = L_shr(pL_CorrelSeq[bound + 1], RSHIFT); + + } + + /*************************************************************************** + * + * FUNCTION NAME: initPBarVBarL + * + * PURPOSE: Given the int32_t pL_PBarFull array, + * function initPBarVBarL initializes the int16_t initial + * condition arrays pswPBar and pswVBar for a 3-rd order LPC + * filter, since the order of the 1st Rc-VQ segment is 3. + * The pswPBar and pswVBar arrays are a int16_t subset + * of the initial condition array pL_PBarFull. + * pswPBar and pswVBar are the initial conditions for the AFLAT + * recursion at a given segment. The AFLAT recursion is used + * to evaluate the residual error due to an Rc vector selected + * from a prequantizer or a quantizer. + * + * This is an implementation of equation 4.18 and 4.19. + * + * INPUTS: + * + * pL_PBarFull[0:NP-1] + * A int32_t input array containing the P initial + * conditions for the full 10-th order LPC filter. + * The address of the 0-th element of pL_PBarFull + * is passed in when function initPBarVBarL is called. + * + * OUTPUTS: + * + * pswPBar[0:NP_AFLAT-1] + * The output int16_t array containing the P initial + * conditions for the P-V AFLAT recursion, set here + * for the Rc-VQ search at the 1st Rc-VQ segment. + * The address of the 0-th element of pswPBar is + * passed in when function initPBarVBarL is called. + * + * pswVBar[-NP_AFLAT+1:NP_AFLAT-1] + * The output int16_t array containing the V initial + * conditions for the P-V AFLAT recursion, set here + * for the Rc-VQ search at the 1st Rc-VQ segment. + * The address of the 0-th element of pswVBar is + * passed in when function initPBarVBarL is called. + * + * RETURN: + * + * none. + * + * REFERENCE: Sub-clause 4.1.4.1 GSM Recommendation 06.20 + * + * + *************************************************************************/ + + void Codec::initPBarVBarL(int32_t pL_PBarFull[], + int16_t pswPBar[], + int16_t pswVBar[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int bound, + i; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Initialize the AFLAT recursion P and V 16 bit arrays for a 3-rd */ + /* order LPC filter corresponding to the 1-st reflection coefficient */ + /* VQ segment. The PBar and VBar arrays store the initial conditions */ + /* for the evaluating the residual error due to Rc vectors being */ + /* evaluated from the Rc-VQ codebook at the 1-st Rc-VQ segment. */ + /*--------------------------------------------------------------------*/ + bound = 2; + + for (i = 0; i <= bound; i++) + { + pswPBar[i] = round(pL_PBarFull[i]); + } + for (i = -bound; i < 0; i++) + { + pswVBar[i] = pswPBar[-i - 1]; + } + for (i = 0; i < bound; i++) + { + pswVBar[i] = pswPBar[i + 1]; + } + pswVBar[bound] = round(pL_PBarFull[bound + 1]); + + } + + /*************************************************************************** + * + * FUNCTION NAME: maxCCOverGWithSign + * + * PURPOSE: + * + * Finds lag which maximizes C^2/G ( C is allowed to be negative ). + * + * INPUTS: + * + * pswCIn[0:swNum-1] + * + * Array of C values + * + * pswGIn[0:swNum-1] + * + * Array of G values + * + * pswCCmax + * + * Initial value of CCmax + * + * pswGmax + * + * Initial value of Gmax + * + * swNum + * + * Number of lags to be searched + * + * OUTPUTS: + * + * pswCCmax + * + * Value of CCmax after search + * + * pswGmax + * + * Value of Gmax after search + * + * RETURN VALUE: + * + * maxCCGIndex - index for max C^2/G, defaults to zero if all G <= 0 + * + * DESCRIPTION: + * + * This routine is called from bestDelta(). The routine is a simple + * find the best in a list search. + * + * REFERENCE: Sub-clause 4.1.8.3 of GSM Recommendation 06.20 + * + * KEYWORDS: LTP correlation peak + * + *************************************************************************/ + + int16_t Codec::maxCCOverGWithSign(int16_t pswCIn[], + int16_t pswGIn[], + int16_t *pswCCMax, + int16_t *pswGMax, + int16_t swNum) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swCC, + i, + maxCCGIndex, + swCCMax, + swGMax; + int32_t L_Temp; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* initialize max c^2/g to be the initial trajectory */ + /*---------------------------------------------------*/ + + maxCCGIndex = 0; + swGMax = pswGIn[0]; + + if (pswCIn[0] < 0) + swCCMax = negate(mult_r(pswCIn[0], pswCIn[0])); + else + swCCMax = mult_r(pswCIn[0], pswCIn[0]); + + for (i = 1; i < swNum; i++) + { + + /* Imperfect interpolation can result in negative energies. */ + /* Check for this */ + /*----------------------------------------------------------*/ + + if (pswGIn[i] > 0) + { + + swCC = mult_r(pswCIn[i], pswCIn[i]); + + if (pswCIn[i] < 0) + swCC = negate(swCC); + + L_Temp = L_mult(swCC, swGMax); + L_Temp = L_msu(L_Temp, pswGIn[i], swCCMax); + + /* Check if C^2*Gmax - G*Cmax^2 > 0 */ + /* -------------------------------- */ + + if (L_Temp > 0) + { + swGMax = pswGIn[i]; + swCCMax = swCC; + maxCCGIndex = i; + } + } + } + *pswGMax = swGMax; + *pswCCMax = swCCMax; + + return (maxCCGIndex); + } /* end of maxCCOverGWithSign */ + + /*************************************************************************** + * + * FUNCTION NAME: openLoopLagSearch + * + * PURPOSE: + * + * Determines voicing level for the frame. If voiced, obtains list of + * lags to be searched in closed-loop lag search; and value of smoothed + * pitch and coefficient for harmonic-noise-weighting. + * + * INPUTS: + * + * pswWSpeech[-145:159] ( [-LSMAX:F_LEN-1] ) + * + * W(z) filtered speech frame, with some history. + * + * swPrevR0Index + * + * Index of R0 from the previous frame. + * + * swCurrR0Index + * + * Index of R0 for the current frame. + * + * psrLagTbl[0:255] + * + * Lag quantization table, in global ROM. + * + * ppsrCGIntFilt[0:5][0:5] ( [tap][phase] ) + * + * Interpolation smoothing filter for generating C(k) + * and G(k) terms, where k is fractional. Global ROM. + * + * swSP + * speech flag, required for DTX mode + * + * OUTPUTS: + * + * psiUVCode + * + * (Pointer to) the coded voicing level. + * + * pswLagList[0:?] + * + * Array of lags to use in the search of the adaptive + * codebook (long-term predictor). Length determined + * by pswNumLagList[]. + * + * pswNumLagList[0:3] ( [0:N_SUB-1] ) + * + * Array of number of lags to use in search of adaptive + * codebook (long-term predictor) for each subframe. + * + * pswPitchBuf[0:3] ( [0:N_SUB-1] ) + * + * Array of estimates of pitch, to be used in harmonic- + * noise-weighting. + * + * pswHNWCoefBuf[0:3] ( [0:N_SUB-1] ) + * + * Array of harmonic-noise-weighting coefficients. + * + * psnsWSfrmEng[-4:3] ( [-N_SUB:N_SUB-1] ) + * + * Array of energies of weighted speech (input speech + * sent through W(z) weighting filter), each stored as + * normalized fraction and shift count. The zero index + * corresponds to the first subframe of the current + * frame, so there is some history represented. The + * energies are used for scaling purposes only. + * + * pswVadLags[4] + * + * An array of int16_ts containing the best open + * loop LTP lags for the four subframes. + + * + * DESCRIPTION: + * + * Scaling is done on the input weighted speech, such that the C(k) and + * G(k) terms will all be representable. The amount of scaling is + * determined by the maximum energy of any subframe of weighted speech + * from the current frame or last frame. These energies are maintained + * in a buffer, and used for scaling when the excitation is determined + * later in the analysis. + * + * This function is the main calling program for the open loop lag + * search. + * + * REFERENCE: Sub-clauses 4.1.8.1-4.1.8.4 of GSM Recommendation 06.20 + * + * Keywords: openlooplagsearch, openloop, lag, pitch + * + **************************************************************************/ + + + + void Codec::openLoopLagSearch(int16_t pswWSpeech[], + int16_t swPrevR0Index, + int16_t swCurrR0Index, + int16_t *psiUVCode, + int16_t pswLagList[], + int16_t pswNumLagList[], + int16_t pswPitchBuf[], + int16_t pswHNWCoefBuf[], + struct NormSw psnsWSfrmEng[], + int16_t pswVadLags[], + int16_t swSP) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_WSfrmEng, + L_G, + L_C, + L_Voicing; + int16_t swBestPG, + swCCMax, + swGMax, + swCCDivG; + int16_t swTotalCCDivG, + swCC, + swG, + swRG; + short i, + j, + k, + siShift, + siIndex, + siTrajIndex, + siAnchorIndex; + short siNumPeaks, + siNumTrajToDo, + siPeakIndex, + siFIndex; + short siNumDelta, + siBIndex, + siBestTrajIndex = 0; + short siLowestSoFar, + siLagsSoFar, + si1, + si2, + si3; + struct NormSw snsMax; + + int16_t pswGFrame[G_FRAME_LEN]; + int16_t *ppswGSfrm[N_SUB]; + int16_t pswSfrmEng[N_SUB]; + int16_t pswCFrame[C_FRAME_LEN]; + int16_t *ppswCSfrm[N_SUB]; + int16_t pswLIntBuf[N_SUB]; + int16_t pswCCThresh[N_SUB]; + int16_t pswScaledWSpeechBuffer[W_F_BUFF_LEN]; + int16_t *pswScaledWSpeech; + int16_t ppswTrajLBuf[N_SUB * NUM_TRAJ_MAX][N_SUB]; + int16_t ppswTrajCCBuf[N_SUB * NUM_TRAJ_MAX][N_SUB]; + int16_t ppswTrajGBuf[N_SUB * NUM_TRAJ_MAX][N_SUB]; + int16_t pswLPeaks[2 * LMAX / LMIN]; + int16_t pswCPeaks[2 * LMAX / LMIN]; + int16_t pswGPeaks[2 * LMAX / LMIN]; + int16_t pswLArray[DELTA_LEVELS]; + + pswScaledWSpeech = pswScaledWSpeechBuffer + LSMAX; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Scale the weighted speech so that all correlations and energies */ + /* will be less than 1.0 in magnitude. The scale factor is */ + /* determined by the maximum energy of any subframe contained in */ + /* the weighted speech buffer */ + /*-----------------------------------------------------------------*/ + + /* Perform one frame of delay on the subframe energy array */ + /*---------------------------------------------------------*/ + + for (i = 0; i < N_SUB; i++) + psnsWSfrmEng[i - N_SUB] = psnsWSfrmEng[i]; + + /* Calculate the subframe energies of the current weighted speech frame. */ + /* Overflow protection is done based on the energy in the LPC analysis */ + /* window (previous or current) which is closest to the subframe. */ + /*----------------------------------------------------------------------*/ + + psnsWSfrmEng[0].sh = g_corr1s(&pswWSpeech[0], + r0BasedEnergyShft(swPrevR0Index), + &L_WSfrmEng); + psnsWSfrmEng[0].man = round(L_WSfrmEng); + + psnsWSfrmEng[1].sh = g_corr1s(&pswWSpeech[S_LEN], + r0BasedEnergyShft(swCurrR0Index), + &L_WSfrmEng); + psnsWSfrmEng[1].man = round(L_WSfrmEng); + + psnsWSfrmEng[2].sh = g_corr1s(&pswWSpeech[2 * S_LEN], + r0BasedEnergyShft(swCurrR0Index), + &L_WSfrmEng); + psnsWSfrmEng[2].man = round(L_WSfrmEng); + + psnsWSfrmEng[3].sh = g_corr1s(&pswWSpeech[3 * S_LEN], + r0BasedEnergyShft(swCurrR0Index), + &L_WSfrmEng); + psnsWSfrmEng[3].man = round(L_WSfrmEng); + + /* Find the maximum weighted speech subframe energy from all values */ + /* in the array (the array includes the previous frame's subframes, */ + /* and the current frame's subframes) */ + /*------------------------------------------------------------------*/ + + snsMax.man = 0; + snsMax.sh = 0; + for (i = -N_SUB; i < N_SUB; i++) + { + + if (psnsWSfrmEng[i].man > 0) + { + + if (snsMax.man == 0) + snsMax = psnsWSfrmEng[i]; + + if (sub(psnsWSfrmEng[i].sh, snsMax.sh) < 0) + snsMax = psnsWSfrmEng[i]; + + if (sub(psnsWSfrmEng[i].sh, snsMax.sh) == 0 && + sub(psnsWSfrmEng[i].man, snsMax.man) > 0) + snsMax = psnsWSfrmEng[i]; + } + } + + /* Now scale speech up or down, such that the maximum subframe */ + /* energy value will be in range [0.125, 0.25). This gives a */ + /* little room for other maxima, and interpolation filtering */ + /*-------------------------------------------------------------*/ + + siShift = sub(shr(snsMax.sh, 1), 1); + + for (i = 0; i < W_F_BUFF_LEN; i++) + pswScaledWSpeech[i - LSMAX] = shl(pswWSpeech[i - LSMAX], siShift); + + /* Calculate the G(k) (k an integer) terms for all subframes. (A note */ + /* on the organization of the G buffer: G(k) for a given subframe is */ + /* the energy in the weighted speech sequence of length S_LEN (40) */ + /* which begins k back from the beginning of the given subframe-- that */ + /* is, it begins at a lag of k. These sequences overlap from one */ + /* subframe to the next, so it is only necessary to compute and store */ + /* the unique energies. The unique energies are computed and stored */ + /* in this buffer, and pointers are assigned for each subframe to make */ + /* array indexing for each subframe easier. */ + /* */ + /* (Terms in the G buffer are in order of increasing k, so the energy */ + /* of the first sequence-- that is, the oldest sequence-- in the */ + /* weighted speech buffer appears at the end of the G buffer. */ + /* */ + /* (The subframe pointers are assigned so that they point to the first */ + /* k for their respective subframes, k = LSMIN.) */ + /*---------------------------------------------------------------------*/ + + L_G = 0; + for (i = -LSMAX; i < -LSMAX + S_LEN; i++) + L_G = L_mac(L_G, pswScaledWSpeech[i], pswScaledWSpeech[i]); + + pswGFrame[G_FRAME_LEN - 1] = extract_h(L_G); + + for (i = -LSMAX; i < G_FRAME_LEN - LSMAX - 1; i++) + { + + L_G = L_msu(L_G, pswScaledWSpeech[i], pswScaledWSpeech[i]); + L_G = L_mac(L_G, pswScaledWSpeech[i + S_LEN], + pswScaledWSpeech[i + S_LEN]); + pswGFrame[G_FRAME_LEN - LSMAX - 2 - i] = extract_h(L_G); + } + + ppswGSfrm[0] = pswGFrame + 3 * S_LEN; + ppswGSfrm[1] = pswGFrame + 2 * S_LEN; + ppswGSfrm[2] = pswGFrame + S_LEN; + ppswGSfrm[3] = pswGFrame; + + /* Copy the G(k) terms which also happen to be the subframe energies; */ + /* calculate the 4th subframe energy, which is not a G(k) */ + /*--------------------------------------------------------------------*/ + + pswSfrmEng[0] = pswGFrame[G_FRAME_LEN - 1 - LSMAX]; + pswSfrmEng[1] = pswGFrame[G_FRAME_LEN - 1 - LSMAX - S_LEN]; + pswSfrmEng[2] = pswGFrame[G_FRAME_LEN - 1 - LSMAX - 2 * S_LEN]; + + L_WSfrmEng = 0; + for (i = F_LEN - S_LEN; i < F_LEN; i++) + L_WSfrmEng = L_mac(L_WSfrmEng, pswScaledWSpeech[i], pswScaledWSpeech[i]); + + pswSfrmEng[3] = extract_h(L_WSfrmEng); + + /* Calculate the C(k) (k an integer) terms for all subframes. */ + /* (The C(k) terms are all unique, so there is no overlapping */ + /* as in the G buffer.) */ + /*------------------------------------------------------------*/ + + for (i = 0; i < N_SUB; i++) + { + + for (j = LSMIN; j <= LSMAX; j++) + { + + L_C = 0; + for (k = 0; k < S_LEN; k++) + { + + L_C = L_mac(L_C, pswScaledWSpeech[i * S_LEN + k], + pswScaledWSpeech[i * S_LEN - j + k]); + } + + pswCFrame[i * CG_TERMS + j - LSMIN] = extract_h(L_C); + } + } + + ppswCSfrm[0] = pswCFrame; + ppswCSfrm[1] = pswCFrame + CG_TERMS; + ppswCSfrm[2] = pswCFrame + 2 * CG_TERMS; + ppswCSfrm[3] = pswCFrame + 3 * CG_TERMS; + + /* For each subframe: find the max C(k)*C(k)/G(k) where C(k) > 0 and */ + /* k is integer; save the corresponding k; calculate the */ + /* threshold against which other peaks in the interpolated CC/G */ + /* sequence will be checked. Meanwhile, accumulate max CC/G over */ + /* the frame for the voiced/unvoiced determination. */ + /*-------------------------------------------------------------------*/ + + swBestPG = 0; + for (i = 0; i < N_SUB; i++) + { + + /* Find max CC/G (C > 0), store corresponding k */ + /*----------------------------------------------*/ + + swCCMax = 0; + swGMax = 0x003f; + siIndex = fnBest_CG(&ppswCSfrm[i][LMIN - LSMIN], + &ppswGSfrm[i][LMIN - LSMIN], + &swCCMax, &swGMax, + LMAX - LMIN + 1); + + if (siIndex == -1) + { + pswLIntBuf[i] = 0; + pswVadLags[i] = LMIN; /* store lag value for VAD algorithm */ + } + else + { + pswLIntBuf[i] = add(LMIN, (int16_t) siIndex); + pswVadLags[i] = pswLIntBuf[i]; /* store lag value for VAD algorithm */ + } + + if (pswLIntBuf[i] > 0) + { + + /* C > 0 was found: accumulate CC/G, get threshold */ + /*-------------------------------------------------*/ + + if (sub(swCCMax, swGMax) < 0) + swCCDivG = divide_s(swCCMax, swGMax); + else + swCCDivG = SW_MAX; + + swBestPG = add(swCCDivG, swBestPG); + + pswCCThresh[i] = getCCThreshold(pswSfrmEng[i], swCCMax, swGMax); + } + else + pswCCThresh[i] = 0; + } + + /* Make voiced/unvoiced decision */ + /*-------------------------------*/ + + L_Voicing = 0; + for (i = 0; i < N_SUB; i++) + L_Voicing = L_mac(L_Voicing, pswSfrmEng[i], UV_SCALE0); + + L_Voicing = L_add(L_Voicing, L_deposit_h(swBestPG)); + + if ( (L_Voicing <= 0) || (swSP == 0) ) + { + + /* Unvoiced: set return values to zero */ + /*-------------------------------------*/ + + for (i = 0; i < N_SUB; i++) + { + + pswNumLagList[i] = 0; + pswLagList[i] = 0; + pswPitchBuf[i] = 0; + pswHNWCoefBuf[i] = 0; + } + + *psiUVCode = 0; + } + else + { + + /* Voiced: get best delta-codeable lag trajectory; find pitch and */ + /* harmonic-noise-weighting coefficients for each subframe */ + /*----------------------------------------------------------------*/ + + siTrajIndex = 0; + swBestPG = SW_MIN; + for (siAnchorIndex = 0; siAnchorIndex < N_SUB; siAnchorIndex++) + { + + /* Call pitchLags: for the current subframe, find peaks in the */ + /* C(k)**2/G(k) (k fractional) function which exceed the */ + /* threshold set by the maximum C(k)**2/G(k) (k integer) */ + /* (also get the smoothed pitch and harmonic-noise-weighting */ + /* coefficient). */ + /* */ + /* If there is no C(k) > 0 (k integer), set the smoothed pitch */ + /* to its minimum value and set the harmonic-noise-weighting */ + /* coefficient to zero. */ + /*-------------------------------------------------------------*/ + + if (pswLIntBuf[siAnchorIndex] != 0) + { + + pitchLags(pswLIntBuf[siAnchorIndex], + ppswCSfrm[siAnchorIndex], + ppswGSfrm[siAnchorIndex], + pswCCThresh[siAnchorIndex], + pswLPeaks, + pswCPeaks, + pswGPeaks, + &siNumPeaks, + &pswPitchBuf[siAnchorIndex], + &pswHNWCoefBuf[siAnchorIndex]); + + siPeakIndex = 0; + } + else + { + + /* No C(k) > 0 (k integer): set pitch to min, coef to zero, */ + /* go to next subframe. */ + /*----------------------------------------------------------*/ + + pswPitchBuf[siAnchorIndex] = LMIN_FR; + pswHNWCoefBuf[siAnchorIndex] = 0; + continue; + } + + /* It is possible that by interpolating, the only positive */ + /* C(k) was made negative. Check for this here */ + /*---------------------------------------------------------*/ + + if (siNumPeaks == 0) + { + + pswPitchBuf[siAnchorIndex] = LMIN_FR; + pswHNWCoefBuf[siAnchorIndex] = 0; + continue; + } + + /* Peak(s) found in C**2/G function: find the best delta-codeable */ + /* trajectory through each peak (unless that peak has already */ + /* paritcipated in a trajectory) up to a total of NUM_TRAJ_MAX */ + /* peaks. After each trajectory is found, check to see if that */ + /* trajectory is the best one so far. */ + /*----------------------------------------------------------------*/ + + if (siNumPeaks > NUM_TRAJ_MAX) + siNumTrajToDo = NUM_TRAJ_MAX; + else + siNumTrajToDo = siNumPeaks; + + while (siNumTrajToDo) + { + + /* Check if this peak has already participated in a trajectory. */ + /* If so, skip it, decrement the number of trajectories yet to */ + /* be evaluated, and go on to the next best peak */ + /*--------------------------------------------------------------*/ + + si1 = 0; + for (i = 0; i < siTrajIndex; i++) + { + + if (sub(pswLPeaks[siPeakIndex], + ppswTrajLBuf[i][siAnchorIndex]) == 0) + si1 = 1; + } + + if (si1) + { + + siNumTrajToDo--; + if (siNumTrajToDo) + { + + siPeakIndex++; + continue; + } + else + break; + } + + /* The current peak is not in a previous trajectory: find */ + /* the best trajectory through it. */ + /* */ + /* First, store the lag, C**2, and G for the peak in the */ + /* trajectory storage buffer */ + /*--------------------------------------------------------*/ + + ppswTrajLBuf[siTrajIndex][siAnchorIndex] = pswLPeaks[siPeakIndex]; + ppswTrajGBuf[siTrajIndex][siAnchorIndex] = pswGPeaks[siPeakIndex]; + ppswTrajCCBuf[siTrajIndex][siAnchorIndex] = + mult_r(pswCPeaks[siPeakIndex], pswCPeaks[siPeakIndex]); + + /* Complete the part of the trajectory that extends forward */ + /* from the anchor subframe */ + /*----------------------------------------------------------*/ + + for (siFIndex = siAnchorIndex + 1; siFIndex < N_SUB; siFIndex++) + { + + /* Get array of lags which are delta-codeable */ + /* */ + /* First, get code for largest lag in array */ + /* (limit it) */ + /*--------------------------------------------*/ + + quantLag(ppswTrajLBuf[siTrajIndex][siFIndex - 1], + &si1); + si2 = add(si1, (DELTA_LEVELS / 2 - 1) - (NUM_CLOSED - 1)); + if (sub(si2, (1 << L_BITS) - 1) > 0) + si2 = (1 << L_BITS) - 1; + + /* Get code for smallest lag in array (limit it) */ + /*-----------------------------------------------*/ + + si3 = sub(si1, (DELTA_LEVELS / 2) - (NUM_CLOSED - 1)); + if (si3 < 0) + si3 = 0; + + /* Generate array of lags */ + /*------------------------*/ + + for (i = si3, j = 0; i <= si2; i++, j++) + pswLArray[j] = psrLagTbl[i]; + + siNumDelta = add(sub(si2, si3), 1); + + /* Search array of delta-codeable lags for one which maximizes */ + /* C**2/G */ + /*-------------------------------------------------------------*/ + + bestDelta(pswLArray, ppswCSfrm[siFIndex], ppswGSfrm[siFIndex], + siNumDelta, siFIndex, + ppswTrajLBuf[siTrajIndex], ppswTrajCCBuf[siTrajIndex], + ppswTrajGBuf[siTrajIndex]); + } + + /* Complete the part of the trajectory that extends backward */ + /* from the anchor subframe */ + /*-----------------------------------------------------------*/ + + for (siBIndex = siAnchorIndex - 1; siBIndex >= 0; siBIndex--) + { + + /* Get array of lags which are delta-codeable */ + /* */ + /* First, get code for largest lag in array */ + /* (limit it) */ + /*--------------------------------------------*/ + + quantLag(ppswTrajLBuf[siTrajIndex][siBIndex + 1], + &si1); + si2 = add(si1, (DELTA_LEVELS / 2) - (NUM_CLOSED - 1)); + if (sub(si2, (1 << L_BITS) - 1) > 0) + si2 = (1 << L_BITS) - 1; + + /* Get code for smallest lag in array (limit it) */ + /*-----------------------------------------------*/ + + si3 = sub(si1, (DELTA_LEVELS / 2 - 1) - (NUM_CLOSED - 1)); + if (si3 < 0) + si3 = 0; + + /* Generate array of lags */ + /*------------------------*/ + + for (i = si3, j = 0; i <= si2; i++, j++) + pswLArray[j] = psrLagTbl[i]; + + siNumDelta = add(sub(si2, si3), 1); + + /* Search array of delta-codeable lags for one which maximizes */ + /* C**2/G */ + /*-------------------------------------------------------------*/ + + bestDelta(pswLArray, ppswCSfrm[siBIndex], ppswGSfrm[siBIndex], + siNumDelta, siBIndex, + ppswTrajLBuf[siTrajIndex], ppswTrajCCBuf[siTrajIndex], + ppswTrajGBuf[siTrajIndex]); + } + + /* This trajectory done: check total C**2/G for this trajectory */ + /* against current best trajectory */ + /* */ + /* Get total C**2/G for this trajectory */ + /*--------------------------------------------------------------*/ + + swTotalCCDivG = 0; + for (i = 0; i < N_SUB; i++) + { + + swCC = ppswTrajCCBuf[siTrajIndex][i]; + swG = ppswTrajGBuf[siTrajIndex][i]; + + if (swG <= 0) + { + + /* Negative G (imperfect interpolation): do not include in */ + /* total */ + /*---------------------------------------------------------*/ + + swCCDivG = 0; + } + else if (sub(abs_s(swCC), swG) > 0) + { + + /* C**2/G > 0: limit quotient, add to total */ + /*------------------------------------------*/ + + if (swCC > 0) + swCCDivG = SW_MAX; + else + swCCDivG = SW_MIN; + + swTotalCCDivG = add(swTotalCCDivG, swCCDivG); + } + else + { + + /* accumulate C**2/G */ + /*-------------------*/ + + if (swCC < 0) + { + + swCCDivG = divide_s(negate(swCC), swG); + swTotalCCDivG = sub(swTotalCCDivG, swCCDivG); + } + else + { + + swCCDivG = divide_s(swCC, swG); + swTotalCCDivG = add(swTotalCCDivG, swCCDivG); + } + } + } + + /* Compare this trajectory with current best, update if better */ + /*-------------------------------------------------------------*/ + + if (sub(swTotalCCDivG, swBestPG) > 0) + { + + swBestPG = swTotalCCDivG; + siBestTrajIndex = siTrajIndex; + } + + /* Update trajectory index, peak index, decrement the number */ + /* of trajectories left to do. */ + /*-----------------------------------------------------------*/ + + siTrajIndex++; + siPeakIndex++; + siNumTrajToDo--; + } + } + + if (siTrajIndex == 0) + { + + /* No trajectories searched despite voiced designation: change */ + /* designation to unvoiced. */ + /*-------------------------------------------------------------*/ + + for (i = 0; i < N_SUB; i++) + { + + pswNumLagList[i] = 0; + pswLagList[i] = 0; + pswPitchBuf[i] = 0; + pswHNWCoefBuf[i] = 0; + } + + *psiUVCode = 0; + } + else + { + + /* Best trajectory determined: get voicing level, generate the */ + /* constrained list of lags to search in the adaptive codebook */ + /* for each subframe */ + /* */ + /* First, get voicing level */ + /*-------------------------------------------------------------*/ + + *psiUVCode = 3; + siLowestSoFar = 2; + for (i = 0; i < N_SUB; i++) + { + + /* Check this subframe against highest voicing threshold */ + /*-------------------------------------------------------*/ + + swCC = ppswTrajCCBuf[siBestTrajIndex][i]; + swG = ppswTrajGBuf[siBestTrajIndex][i]; + + swRG = mult_r(swG, pswSfrmEng[i]); + L_Voicing = L_deposit_h(swCC); + L_Voicing = L_mac(L_Voicing, swRG, UV_SCALE2); + + if (L_Voicing < 0) + { + + /* Voicing for this subframe failed to meet 2/3 threshold: */ + /* therefore, voicing level for entire frame can only be as */ + /* high as 2 */ + /*----------------------------------------------------------*/ + + *psiUVCode = siLowestSoFar; + + L_Voicing = L_deposit_h(swCC); + L_Voicing = L_mac(L_Voicing, swRG, UV_SCALE1); + + if (L_Voicing < 0) + { + + /* Voicing for this subframe failed to meet 1/2 threshold: */ + /* therefore, voicing level for entire frame can only be */ + /* as high as 1 */ + /*---------------------------------------------------------*/ + + *psiUVCode = siLowestSoFar = 1; + } + } + } + + /* Generate list of lags to be searched in closed-loop */ + /*-----------------------------------------------------*/ + + siLagsSoFar = 0; + for (i = 0; i < N_SUB; i++) + { + + quantLag(ppswTrajLBuf[siBestTrajIndex][i], &si1); + + si2 = add(si1, NUM_CLOSED / 2); + if (sub(si2, (1 << L_BITS) - 1) > 0) + si2 = (1 << L_BITS) - 1; + + si3 = sub(si1, NUM_CLOSED / 2); + if (si3 < 0) + si3 = 0; + + pswNumLagList[i] = add(sub(si2, si3), 1); + + for (j = siLagsSoFar; j < siLagsSoFar + pswNumLagList[i]; j++) + pswLagList[j] = psrLagTbl[si3++]; + + siLagsSoFar += pswNumLagList[i]; + } + } + } + } /* end of openLoopLagSearch */ + + /*************************************************************************** + * + * FUNCTION NAME: pitchLags + * + * PURPOSE: + * + * Locates peaks in the interpolated C(k)*C(k)/G(k) sequence for a + * subframe which exceed a given threshold. Also determines the + * fundamental pitch, and a harmonic-noise-weighting coefficient. + * + * INPUTS: + * + * swBestIntLag + * + * The integer lag for which CC/G is maximum. + * + * pswIntCs[0:127] + * + * The C(k) sequence for the subframe, with k an integer. + * + * pswIntGs[0:127] + * + * The G(k) sequence for the subframe, with k an integer. + * + * swCCThreshold + * + * The CC/G threshold which peaks must exceed (G is + * understood to be 0.5). + * + * psrLagTbl[0:255] + * + * The lag quantization table. + * + * + * OUTPUTS: + * + * pswLPeaksSorted[0:10(max)] + * + * List of fractional lags where CC/G peaks, highest + * peak first. + * + * pswCPeaksSorted[0:10(max)] + * + * List of C's where CC/G peaks. + * + * pswGPeaksSorted[0:10(max)] + * + * List of G's where CC/G peaks. + * + * psiNumSorted + * + * Number of peaks found. + * + * pswPitch + * + * The fundamental pitch for current subframe. + * + * pswHNWCoef + * + * The harmonic-noise-weighting coefficient for the + * current subframe. + * + * RETURN VALUE: + * + * None + * + * DESCRIPTION: + * + * + * REFERENCE: Sub-clauses 4.1.9, 4.1.8.2 of GSM Recommendation 06.20 + * + * KEYWORDS: pitchLags, pitchlags, PITCH_LAGS + * + *************************************************************************/ + + void Codec::pitchLags(int16_t swBestIntLag, + int16_t pswIntCs[], + int16_t pswIntGs[], + int16_t swCCThreshold, + int16_t pswLPeaksSorted[], + int16_t pswCPeaksSorted[], + int16_t pswGPeaksSorted[], + int16_t *psiNumSorted, + int16_t *pswPitch, + int16_t *pswHNWCoef) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t pswLBuf[2 * OS_FCTR - 1], + pswCBuf[2 * OS_FCTR - 1]; + int16_t pswGBuf[2 * OS_FCTR - 1], + pswLPeaks[2 * LMAX / LMIN]; + int16_t pswCPeaks[2 * LMAX / LMIN], + pswGPeaks[2 * LMAX / LMIN]; + short siLPeakIndex, + siCPeakIndex, + siGPeakIndex, + siPeakIndex; + short siSortedIndex, + siLPeaksSortedInit, + swWorkingLag; + int16_t swSubMult, + swFullResPeak, + swCPitch, + swGPitch, + swMult; + int16_t swMultInt, + sw1, + sw2, + si1, + si2; + int32_t L_1; + short siNum, + siUpperBound, + siLowerBound, + siSMFIndex; + short siNumPeaks, + siRepeat, + i, + j; + + static int16_tRom psrSubMultFactor[] = {0x0aab, /* 1.0/12.0 */ + 0x071c, /* 1.0/18.0 */ + 0x0555, /* 1.0/24.0 */ + 0x0444, /* 1.0/30.0 */ + 0x038e}; /* 1.0/36.0 */ + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Get array of valid lags within one integer lag of the best open-loop */ + /* integer lag; get the corresponding interpolated C and G arrays; */ + /* find the best among these; store the info corresponding to this peak */ + /* in the interpolated CC/G sequence */ + /*----------------------------------------------------------------------*/ + + sw1 = shr(extract_l(L_mult(swBestIntLag, OS_FCTR)), 1); + + siNum = CGInterpValid(sw1, pswIntCs, pswIntGs, + pswLBuf, pswCBuf, pswGBuf); + + sw1 = 0; + sw2 = 0x003f; + siPeakIndex = fnBest_CG(pswCBuf, pswGBuf, &sw1, &sw2, siNum); + if (siPeakIndex == -1) + { + + /* It is possible, although rare, that the interpolated sequence */ + /* will not have a peak where the original sequence did. */ + /* Indicate this on return */ + /*---------------------------------------------------------------*/ + + *psiNumSorted = 0; + return; + } + + siLPeakIndex = 0; + siCPeakIndex = 0; + siGPeakIndex = 0; + siSortedIndex = 0; + pswCPeaks[siCPeakIndex] = pswCBuf[siPeakIndex]; + siCPeakIndex = add(siCPeakIndex, 1); + pswLPeaks[siLPeakIndex] = pswLBuf[siPeakIndex]; + siLPeakIndex = add(siLPeakIndex, 1); + pswGPeaks[siGPeakIndex] = pswGBuf[siPeakIndex]; + siGPeakIndex = add(siGPeakIndex, 1); + + /* Find all peaks at submultiples of the first peak */ + /*--------------------------------------------------*/ + + siSMFIndex = 0; + swSubMult = mult_r(pswLPeaks[0], psrSubMultFactor[siSMFIndex++]); + + while (sub(swSubMult, LMIN) >= 0 && siSMFIndex <= 5) + { + + /* Check if there is peak in the integer CC/G sequence within */ + /* PEAK_VICINITY of the submultiple */ + /*------------------------------------------------------------*/ + + swFullResPeak = findPeak(swSubMult, pswIntCs, pswIntGs); + + if (swFullResPeak) + { + + /* Peak found at submultiple: interpolate to get C's and G's */ + /* corresponding to valid lags within one of the new found */ + /* peak; get best C**2/G from these; if it meets threshold, */ + /* store the info corresponding to this peak */ + /*-----------------------------------------------------------*/ + + siNum = CGInterpValid(swFullResPeak, pswIntCs, pswIntGs, + pswLBuf, pswCBuf, pswGBuf); + + sw1 = swCCThreshold; + sw2 = 0x4000; + siPeakIndex = fnBest_CG(pswCBuf, pswGBuf, &sw1, &sw2, siNum); + if (siPeakIndex != -1) + { + + pswCPeaks[siCPeakIndex] = pswCBuf[siPeakIndex]; + siCPeakIndex = add(siCPeakIndex, 1); + pswLPeaks[siLPeakIndex] = pswLBuf[siPeakIndex]; + siLPeakIndex = add(siLPeakIndex, 1); + pswGPeaks[siGPeakIndex] = pswGBuf[siPeakIndex]; + siGPeakIndex = add(siGPeakIndex, 1); + + } + } + + + if (siSMFIndex < 5) + { + + /* Get next submultiple */ + /*----------------------*/ + swSubMult = mult_r(pswLPeaks[0], psrSubMultFactor[siSMFIndex]); + + } + + siSMFIndex++; + } + + /* Get pitch from fundamental peak: first, build array of fractional */ + /* lags around which to search for peak. Note that these lags are */ + /* NOT restricted to those in the lag table, but may take any value */ + /* in the range LMIN_FR to LMAX_FR */ + /*-------------------------------------------------------------------*/ + + siUpperBound = add(pswLPeaks[siLPeakIndex - 1], OS_FCTR); + siUpperBound = sub(siUpperBound, 1); + if (sub(siUpperBound, LMAX_FR) > 0) + siUpperBound = LMAX_FR; + + siLowerBound = sub(pswLPeaks[siLPeakIndex - 1], OS_FCTR); + siLowerBound = add(siLowerBound, 1); + if (sub(siLowerBound, LMIN_FR) < 0) + siLowerBound = LMIN_FR; + for (i = siLowerBound, j = 0; i <= siUpperBound; i++, j++) + pswLBuf[j] = i; + + /* Second, find peak in the interpolated CC/G sequence. */ + /* The corresponding lag is the fundamental pitch. The */ + /* interpolated C(pitch) and G(pitch) values are stored */ + /* for later use in calculating the Harmonic-Noise- */ + /* Weighting coefficient */ + /*------------------------------------------------------*/ + + siNum = sub(siUpperBound, siLowerBound); + siNum = add(siNum, 1); + CGInterp(pswLBuf, siNum, pswIntCs, pswIntGs, LSMIN, + pswCBuf, pswGBuf); + sw1 = 0; + sw2 = 0x003f; + siPeakIndex = fnBest_CG(pswCBuf, pswGBuf, &sw1, &sw2, siNum); + if (siPeakIndex == -1) + { + swCPitch = 0; + *pswPitch = LMIN_FR; + swGPitch = 0x003f; + } + else + { + swCPitch = pswCBuf[siPeakIndex]; + *pswPitch = pswLBuf[siPeakIndex]; + swGPitch = pswGBuf[siPeakIndex]; + } + + /* Find all peaks which are multiples of fundamental pitch */ + /*---------------------------------------------------------*/ + + swMult = add(*pswPitch, *pswPitch); + swMultInt = mult_r(swMult, INV_OS_FCTR); + + while (sub(swMultInt, LMAX) <= 0) + { + + /* Check if there is peak in the integer CC/G sequence within */ + /* PEAK_VICINITY of the multiple */ + /*------------------------------------------------------------*/ + + swFullResPeak = findPeak(swMultInt, pswIntCs, pswIntGs); + + if (swFullResPeak) + { + + /* Peak found at multiple: interpolate to get C's and G's */ + /* corresponding to valid lags within one of the new found */ + /* peak; get best C**2/G from these; if it meets threshold, */ + /* store the info corresponding to this peak */ + /*-----------------------------------------------------------*/ + + siNum = CGInterpValid(swFullResPeak, pswIntCs, pswIntGs, + pswLBuf, pswCBuf, pswGBuf); + + sw1 = swCCThreshold; + sw2 = 0x4000; + siPeakIndex = fnBest_CG(pswCBuf, pswGBuf, &sw1, &sw2, siNum); + if (siPeakIndex != -1) + { + + pswCPeaks[siCPeakIndex] = pswCBuf[siPeakIndex]; + siCPeakIndex = add(siCPeakIndex, 1); + pswLPeaks[siLPeakIndex] = pswLBuf[siPeakIndex]; + siLPeakIndex = add(siLPeakIndex, 1); + pswGPeaks[siGPeakIndex] = pswGBuf[siPeakIndex]; + siGPeakIndex = add(siGPeakIndex, 1); + + } + } + + /* Get next multiple */ + /*-------------------*/ + + swMult = add(*pswPitch, swMult); + swMultInt = mult_r(swMult, INV_OS_FCTR); + } + + /* Get Harmonic-Noise-Weighting coefficient = 0.4 * C(pitch) / G(pitch) */ + /* Note: a factor of 0.5 is applied the the HNW coeffcient */ + /*----------------------------------------------------------------------*/ + + si2 = norm_s(swCPitch); + sw1 = shl(swCPitch, si2); + L_1 = L_mult(sw1, PW_FRAC); + + si1 = norm_s(swGPitch); + sw1 = shl(swGPitch, si1); + + sw2 = round(L_shr(L_1, 1)); + sw2 = divide_s(sw2, sw1); + + if (sub(si1, si2) > 0) + sw2 = shl(sw2, sub(si1, si2)); + + if (sub(si1, si2) < 0) + sw2 = shift_r(sw2, sub(si1, si2)); + + *pswHNWCoef = sw2; + + /* Sort peaks into output arrays, largest first */ + /*----------------------------------------------*/ + + siLPeaksSortedInit = siSortedIndex; + *psiNumSorted = 0; + siNumPeaks = siLPeakIndex; + for (i = 0; i < siNumPeaks; i++) + { + + sw1 = 0; + sw2 = 0x003f; + siPeakIndex = fnBest_CG(pswCPeaks, pswGPeaks, &sw1, &sw2, siNumPeaks); + + siRepeat = 0; + swWorkingLag = pswLPeaks[siPeakIndex]; + for (j = 0; j < *psiNumSorted; j++) + { + + if (sub(swWorkingLag, pswLPeaksSorted[j + siLPeaksSortedInit]) == 0) + siRepeat = 1; + } + + if (!siRepeat) + { + + pswLPeaksSorted[siSortedIndex] = swWorkingLag; + pswCPeaksSorted[siSortedIndex] = pswCPeaks[siPeakIndex]; + pswGPeaksSorted[siSortedIndex] = pswGPeaks[siPeakIndex]; + siSortedIndex = add(siSortedIndex, 1); + *psiNumSorted = add(*psiNumSorted, 1); + } + + pswCPeaks[siPeakIndex] = 0x0; + } + } /* end of pitchLags */ + + + + /*************************************************************************** + * + * FUNCTION NAME: quantLag + * + * PURPOSE: + * + * Quantizes a given fractional lag according to the provided table + * of allowable fractional lags. + * + * INPUTS: + * + * swRawLag + * + * Raw lag value: a fractional lag value*OS_FCTR. + * + * psrLagTbl[0:255] + * + * Fractional lag table. + * + * OUTPUTS: + * + * pswCode + * + * Index in lag table of the quantized lag-- that is, + * the coded value of the lag. + * + * RETURN VALUE: + * + * Quantized lag value. + * + * + * REFERENCE: Sub-clause 4.1.8.3 of GSM Recommendation 06.20 + * + * KEYWORDS: quantization, LTP, adaptive codebook + * + *************************************************************************/ + + int16_t Codec::quantLag(int16_t swRawLag, + int16_t *pswCode) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + int16_t siOffset, + swIndex1, + swIndex2; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + swIndex1 = 0; + siOffset = shr(LAG_TABLE_LEN, 1); + swIndex2 = siOffset; + siOffset = shr(siOffset, 1); + + while (sub(swIndex2, swIndex1) != 0) + { + if (sub(swRawLag, psrLagTbl[swIndex2]) >= 0) + swIndex1 = swIndex2; + swIndex2 = add(swIndex1, siOffset); + siOffset = shr(siOffset, 1); + } + *pswCode = swIndex2; + + return (psrLagTbl[swIndex2]); + + } /* end of quantLag */ + + /*************************************************************************** + * + * FUNCTION NAME: r0Quant + * + * PURPOSE: + * + * Quantize the unquantized R(0). Returns r0 codeword (index). + * + * INPUTS: + * + * L_UnqntzdR0 + * The average frame energy R(0) + * + * OUTPUTS: none + * + * RETURN VALUE: + * + * A 16 bit number representing the codeword whose + * associated R(0) is closest to the input frame energy. + * + * DESCRIPTION: + * + * Returns r0 codeword (index) not the actual Rq(0). + * + * Level compare input with boundary value (the boundary + * above ,louder) of candidate r0Index i.e. + * lowerBnd[i] <= inputR(0) < upperBnd[i+1] + * + * The compare in the routine is: + * inputR(0) < upperBnd[i+1] if false return i as codeword + * + * REFERENCE: Sub-clause 4.1.3 of GSM Recommendation 06.20 + * + * + *************************************************************************/ + + int16_t Codec::r0Quant(int32_t L_UnqntzdR0) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t swR0Index, + swUnqntzdR0; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + swUnqntzdR0 = round(L_UnqntzdR0); + + for (swR0Index = 0; swR0Index < (1 << R0BITS) - 1; swR0Index++) + { + if (sub(swUnqntzdR0, psrR0DecTbl[2 * swR0Index + 1]) < 0) + { + return (swR0Index); + } + } + return ((1 << R0BITS) - 1); /* return the maximum */ + } + + /*************************************************************************** + * + * FUNCTION NAME: setupPreQ + * + * PURPOSE: + * The purpose of this function is to setup the internal pointers so that + * getNextVec knows where to start. + * + * INPUTS: iSeg, iVector + * + * OUTPUTS: None + * + * RETURN VALUE: none + * + * DESCRIPTION: + * + * REFERENCE: Sub-clause 4.1.4.1 of GSM Recommendation 06.20 + * + * KEYWORDS: vector quantizer preQ + * + *************************************************************************/ + + void Codec::setupPreQ(int iSeg, int iVector) + { + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + iLow = psvqIndex[iSeg - 1].l; + iThree = ((psvqIndex[iSeg - 1].h - iLow) == 2); + + switch (iSeg) + { + case 1: + { + psrTable = psrPreQ1; + iWordPtr = (iVector * 3) >> 1; + if (odd(iVector)) + iWordHalfPtr = LOW; + else + iWordHalfPtr = HIGH; + break; + } + + case 2: + { + psrTable = psrPreQ2; + iWordPtr = (iVector * 3) >> 1; + if (odd(iVector)) + iWordHalfPtr = LOW; + else + iWordHalfPtr = HIGH; + break; + } + + case 3: + { + psrTable = psrPreQ3; + iWordPtr = iVector * 2; + iWordHalfPtr = HIGH; + break; + } + } + } + + /*************************************************************************** + * + * FUNCTION NAME: setupQuant + * + * PURPOSE: + * The purpose of this function is to setup the internal pointers so that + * getNextVec knows where to start. + * + * + * INPUTS: iSeg, iVector + * + * OUTPUTS: None + * + * RETURN VALUE: none + * + * DESCRIPTION: + * + * REFERENCE: Sub-clause 4.1.4.1 of GSM Recommendation 06.20 + * + * KEYWORDS: vector quantizer Quant + * + *************************************************************************/ + + void Codec::setupQuant(int iSeg, int iVector) + { + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + iLow = psvqIndex[iSeg - 1].l; + iThree = ((psvqIndex[iSeg - 1].h - iLow) == 2); + + switch (iSeg) + { + case 1: + { + psrTable = psrQuant1; + iWordPtr = (iVector * 3) >> 1; + if (odd(iVector)) + iWordHalfPtr = LOW; + else + iWordHalfPtr = HIGH; + break; + } + + case 2: + { + psrTable = psrQuant2; + iWordPtr = (iVector * 3) >> 1; + if (odd(iVector)) + iWordHalfPtr = LOW; + else + iWordHalfPtr = HIGH; + break; + } + + case 3: + { + psrTable = psrQuant3; + iWordPtr = iVector * 2; + iWordHalfPtr = HIGH; + break; + } + } + } + + /*************************************************************************** + * + * FUNCTION NAME: weightSpeechFrame + * + * PURPOSE: + * + * The purpose of this function is to perform the spectral + * weighting filter (W(z)) of the input speech frame. + * + * INPUTS: + * + * pswSpeechFrm[0:F_LEN] + * + * high pass filtered input speech frame + * + * pswWNumSpace[0:NP*N_SUB] + * + * W(z) numerator coefficients + * + * pswWDenomSpace[0:NP*N_SUB] + * + * W(z) denominator coefficients + * + * pswWSpeechBuffBase[0:F_LEN+LMAX+CG_INT_MACS/2] + * + * previous W(z) filtered speech + * + * OUTPUTS: + * + * pswWSpeechBuffBase[0:F_LEN+LMAX+CG_INT_MACS/2] + * + * W(z) filtered speech frame + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * REFERENCE: Sub-clause 4.1.7 of GSM Recommendation 06.20 + * + * KEYWORDS: + * + *************************************************************************/ + + void Codec::weightSpeechFrame(int16_t pswSpeechFrm[], + int16_t pswWNumSpace[], + int16_t pswWDenomSpace[], + int16_t pswWSpeechBuffBase[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t pswScratch0[W_F_BUFF_LEN], + *pswWSpeechFrm; + short int siI; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* Delay the weighted speech buffer by one frame */ + /* --------------------------------------------- */ + + for (siI = 0; siI < LSMAX; siI++) + { + pswWSpeechBuffBase[siI] = pswWSpeechBuffBase[siI + F_LEN]; + } + + /* pass speech frame through W(z) */ + /* ------------------------------ */ + + pswWSpeechFrm = pswWSpeechBuffBase + LSMAX; + + for (siI = 0; siI < N_SUB; siI++) + { + lpcFir(&pswSpeechFrm[siI * S_LEN], &pswWNumSpace[siI * NP], + pswWStateNum, &pswScratch0[siI * S_LEN]); + } + + for (siI = 0; siI < N_SUB; siI++) + { + lpcIir(&pswScratch0[siI * S_LEN], &pswWDenomSpace[siI * NP], + pswWStateDenom, &pswWSpeechFrm[siI * S_LEN]); + } + } + + // vad.c + + void Codec::vad_reset(void) + + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int i; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + pswRvad[0] = 24576; + swNormRvad = 7; + swPt_sacf = 0; + swPt_sav0 = 0; + L_lastdm = 0; + swE_thvad = 21; + swM_thvad = 21875; + swAdaptCount = 0; + swBurstCount = 0; + swHangCount = -1; + swOldLagCount = 0; + swVeryOldLagCount = 0; + swOldLag = 21; + + for (i = 1; i < 9; i++) + pswRvad[i] = 0; + for (i = 0; i < 27; i++) + pL_sacf[i] = 0; + for (i = 0; i < 36; i++) + pL_sav0[i] = 0; + + } + + /**************************************************************************** + * + * FUNCTION: vad_algorithm + * + * VERSION: 1.2 + * + * PURPOSE: Returns a decision as to whether the current frame being + * processed by the speech encoder contains speech or not. + * + * INPUTS: pL_acf[0..8] autocorrelation of input signal frame + * swScaleAcf L_acf scaling factor + * pswRc[0..3] speech encoder reflection coefficients + * swPtch flag to indicate a periodic signal component + * + * OUTPUTS: pswVadFlag vad decision + * + ***************************************************************************/ + + void Codec::vad_algorithm(int32_t pL_acf[9], + int16_t swScaleAcf, + int16_t pswRc[4], + int16_t swPtch, + int16_t *pswVadFlag) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t + pL_av0[9], + pL_av1[9]; + + int16_t + swM_acf0, + swE_acf0, + pswRav1[9], + swNormRav1, + swM_pvad, + swE_pvad, + swStat, + swTone, + swVvad; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + energy_computation + ( + pL_acf, swScaleAcf, + pswRvad, swNormRvad, + &swM_pvad, &swE_pvad, + &swM_acf0, &swE_acf0 + ); + + average_acf + ( + pL_acf, swScaleAcf, + pL_av0, pL_av1 + ); + + predictor_values + ( + pL_av1, + pswRav1, + &swNormRav1 + ); + + spectral_comparison + ( + pswRav1, swNormRav1, + pL_av0, + &swStat + ); + + tone_detection + ( + pswRc, + &swTone + ); + + threshold_adaptation + ( + swStat, swPtch, swTone, + pswRav1, swNormRav1, + swM_pvad, swE_pvad, + swM_acf0, swE_acf0, + pswRvad, &swNormRvad, + &swM_thvad, &swE_thvad + ); + + vad_decision + ( + swM_pvad, swE_pvad, + swM_thvad, swE_thvad, + &swVvad + ); + + vad_hangover + ( + swVvad, + pswVadFlag + ); + + } + + /**************************************************************************** + * + * FUNCTION: energy_computation + * + * VERSION: 1.2 + * + * PURPOSE: Computes the input and residual energies of the adaptive + * filter in a floating point representation. + * + * INPUTS: pL_acf[0..8] autocorrelation of input signal frame + * swScaleAcf L_acf scaling factor + * pswRvad[0..8] autocorrelated adaptive filter coefficients + * swNormRvad rvad scaling factor + * + * OUTPUTS: pswM_pvad mantissa of filtered signal energy + * pswE_pvad exponent of filtered signal energy + * pswM_acf0 mantissa of signal frame energy + * pswE_acf0 exponent of signal frame energy + * + ***************************************************************************/ + + void Codec::energy_computation(int32_t pL_acf[], + int16_t swScaleAcf, + int16_t pswRvad[], + int16_t swNormRvad, + int16_t *pswM_pvad, + int16_t *pswE_pvad, + int16_t *pswM_acf0, + int16_t *pswE_acf0) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t + L_temp; + + int16_t + pswSacf[9], + swNormAcf, + swNormProd, + swShift; + + int + i; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /*** Test if acf[0] is zero ***/ + + if (pL_acf[0] == 0) + { + *pswE_pvad = -0x8000; + *pswM_pvad = 0; + *pswE_acf0 = -0x8000; + *pswM_acf0 = 0; + return; + } + + + /*** Re-normalisation of L_acf[0..8] ***/ + + swNormAcf = norm_l(pL_acf[0]); + swShift = sub(swNormAcf, 3); + + for (i = 0; i <= 8; i++) + pswSacf[i] = extract_h(L_shl(pL_acf[i], swShift)); + + + /*** Computation of e_acf0 and m_acf0 ***/ + + *pswE_acf0 = add(32, shl(swScaleAcf, 1)); + *pswE_acf0 = sub(*pswE_acf0, swNormAcf); + *pswM_acf0 = shl(pswSacf[0], 3); + + + /*** Computation of e_pvad and m_pvad ***/ + + *pswE_pvad = add(*pswE_acf0, 14); + *pswE_pvad = sub(*pswE_pvad, swNormRvad); + + L_temp = 0; + + for (i = 1; i <= 8; i++) + L_temp = L_mac(L_temp, pswSacf[i], pswRvad[i]); + + L_temp = L_add(L_temp, L_shr(L_mult(pswSacf[0], pswRvad[0]), 1)); + + if (L_temp <= 0) + L_temp = 1; + + swNormProd = norm_l(L_temp); + *pswE_pvad = sub(*pswE_pvad, swNormProd); + *pswM_pvad = extract_h(L_shl(L_temp, swNormProd)); + + } + + /**************************************************************************** + * + * FUNCTION: average_acf + * + * VERSION: 1.2 + * + * PURPOSE: Computes the arrays L_av0 [0..8] and L_av1 [0..8]. + * + * INPUTS: pL_acf[0..8] autocorrelation of input signal frame + * swScaleAcf L_acf scaling factor + * + * OUTPUTS: pL_av0[0..8] ACF averaged over last four frames + * pL_av1[0..8] ACF averaged over previous four frames + * + ***************************************************************************/ + + void Codec::average_acf(int32_t pL_acf[], + int16_t swScaleAcf, + int32_t pL_av0[], + int32_t pL_av1[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t L_temp; + + int16_t swScale; + + int i; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /*** computation of the scaleing factor ***/ + + swScale = sub(10, shl(swScaleAcf, 1)); + + + /*** Computation of the arrays L_av0 and L_av1 ***/ + + for (i = 0; i <= 8; i++) + { + L_temp = L_shr(pL_acf[i], swScale); + pL_av0[i] = L_add(pL_sacf[i], L_temp); + pL_av0[i] = L_add(pL_sacf[i + 9], pL_av0[i]); + pL_av0[i] = L_add(pL_sacf[i + 18], pL_av0[i]); + pL_sacf[swPt_sacf + i] = L_temp; + pL_av1[i] = pL_sav0[swPt_sav0 + i]; + pL_sav0[swPt_sav0 + i] = pL_av0[i]; + } + + + /*** Update the array pointers ***/ + + if (swPt_sacf == 18) + swPt_sacf = 0; + else + swPt_sacf = add(swPt_sacf, 9); + + if (swPt_sav0 == 27) + swPt_sav0 = 0; + else + swPt_sav0 = add(swPt_sav0, 9); + + } + + /**************************************************************************** + * + * FUNCTION: predictor_values + * + * VERSION: 1.2 + * + * PURPOSE: Computes the array rav [0..8] needed for the spectral + * comparison and the threshold adaptation. + * + * INPUTS: pL_av1 [0..8] ACF averaged over previous four frames + * + * OUTPUTS: pswRav1 [0..8] ACF obtained from L_av1 + * pswNormRav1 r_av1 scaling factor + * + ***************************************************************************/ + + void Codec::predictor_values(int32_t pL_av1[], + int16_t pswRav1[], + int16_t *pswNormRav1) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t + pswVpar[8], + pswAav1[9]; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + schur_recursion(pL_av1, pswVpar); + step_up(8, pswVpar, pswAav1); + compute_rav1(pswAav1, pswRav1, pswNormRav1); + + } + + /**************************************************************************** + * + * FUNCTION: schur_recursion + * + * VERSION: 1.2 + * + * PURPOSE: Uses the Schur recursion to compute adaptive filter + * reflection coefficients from an autorrelation function. + * + * INPUTS: pL_av1[0..8] autocorrelation function + * + * OUTPUTS: pswVpar[0..7] reflection coefficients + * + ***************************************************************************/ + + void Codec::schur_recursion(int32_t pL_av1[], + int16_t pswVpar[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t + pswAcf[9], + pswPp[9], + pswKk[9], + swTemp; + + int i, + k, + m, + n; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /*** Schur recursion with 16-bit arithmetic ***/ + + if (pL_av1[0] == 0) + { + for (i = 0; i < 8; i++) + pswVpar[i] = 0; + return; + } + + swTemp = norm_l(pL_av1[0]); + + for (k = 0; k <= 8; k++) + pswAcf[k] = extract_h(L_shl(pL_av1[k], swTemp)); + + + /*** Initialise array pp[..] and kk[..] for the recursion: ***/ + + for (i = 1; i <= 7; i++) + pswKk[9 - i] = pswAcf[i]; + + for (i = 0; i <= 8; i++) + pswPp[i] = pswAcf[i]; + + + /*** Compute Parcor coefficients: ***/ + + for (n = 0; n < 8; n++) + { + if (pswPp[0] < abs_s(pswPp[1])) + { + for (i = n; i < 8; i++) + pswVpar[i] = 0; + return; + } + pswVpar[n] = divide_s(abs_s(pswPp[1]), pswPp[0]); + + if (pswPp[1] > 0) + pswVpar[n] = negate(pswVpar[n]); + if (n == 7) + return; + + + /*** Schur recursion: ***/ + + pswPp[0] = add(pswPp[0], mult_r(pswPp[1], pswVpar[n])); + + for (m = 1; m <= (7 - n); m++) + { + pswPp[m] = add(pswPp[1 + m], mult_r(pswKk[9 - m], pswVpar[n])); + pswKk[9 - m] = add(pswKk[9 - m], mult_r(pswPp[1 + m], pswVpar[n])); + } + } + + } + + /**************************************************************************** + * + * FUNCTION: step_up + * + * VERSION: 1.2 + * + * PURPOSE: Computes the transversal filter coefficients from the + * reflection coefficients. + * + * INPUTS: swNp filter order (2..8) + * pswVpar[0..np-1] reflection coefficients + * + * OUTPUTS: pswAav1[0..np] transversal filter coefficients + * + ***************************************************************************/ + + void Codec::step_up(int16_t swNp, + int16_t pswVpar[], + int16_t pswAav1[]) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t + pL_coef[9], + pL_work[9]; + + int16_t + swTemp; + + int + i, + m; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /*** Initialisation of the step-up recursion ***/ + + pL_coef[0] = L_shl(0x4000L, 15); + pL_coef[1] = L_shl(L_deposit_l(pswVpar[0]), 14); + + + /*** Loop on the LPC analysis order: ***/ + + for (m = 2; m <= swNp; m++) + { + for (i = 1; i < m; i++) + { + swTemp = extract_h(pL_coef[m - i]); + pL_work[i] = L_mac(pL_coef[i], pswVpar[m - 1], swTemp); + } + for (i = 1; i < m; i++) + pL_coef[i] = pL_work[i]; + pL_coef[m] = L_shl(L_deposit_l(pswVpar[m - 1]), 14); + } + + + /*** Keep the aav1[0..swNp] in 15 bits for the following subclause ***/ + + for (i = 0; i <= swNp; i++) + pswAav1[i] = extract_h(L_shr(pL_coef[i], 3)); + + } + + /**************************************************************************** + * + * FUNCTION: compute_rav1 + * + * VERSION: 1.2 + * + * PURPOSE: Computes the autocorrelation function of the adaptive + * filter coefficients. + * + * INPUTS: pswAav1[0..8] adaptive filter coefficients + * + * OUTPUTS: pswRav1[0..8] ACF of aav1 + * pswNormRav1 r_av1 scaling factor + * + ***************************************************************************/ + + void Codec::compute_rav1(int16_t pswAav1[], + int16_t pswRav1[], + int16_t *pswNormRav1) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t + pL_work[9]; + + int + i, + k; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /*** Computation of the rav1[0..8] ***/ + + for (i = 0; i <= 8; i++) + { + pL_work[i] = 0; + + for (k = 0; k <= 8 - i; k++) + pL_work[i] = L_mac(pL_work[i], pswAav1[k], pswAav1[k + i]); + } + + if (pL_work[0] == 0) + *pswNormRav1 = 0; + else + *pswNormRav1 = norm_l(pL_work[0]); + + for (i = 0; i <= 8; i++) + pswRav1[i] = extract_h(L_shl(pL_work[i], *pswNormRav1)); + + } + + /**************************************************************************** + * + * FUNCTION: spectral_comparison + * + * VERSION: 1.2 + * + * PURPOSE: Computes the stat flag needed for the threshold + * adaptation decision. + * + * INPUTS: pswRav1[0..8] ACF obtained from L_av1 + * swNormRav1 rav1 scaling factor + * pL_av0[0..8] ACF averaged over last four frames + * + * OUTPUTS: pswStat flag to indicate spectral stationarity + * + ***************************************************************************/ + + void Codec::spectral_comparison(int16_t pswRav1[], + int16_t swNormRav1, + int32_t pL_av0[], + int16_t *pswStat) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t + L_dm, + L_sump, + L_temp; + + int16_t + pswSav0[9], + swShift, + swDivShift, + swTemp; + + int + i; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /*** Re-normalise L_av0[0..8] ***/ + + if (pL_av0[0] == 0) + { + for (i = 0; i <= 8; i++) + pswSav0[i] = 4095; + } + else + { + swShift = sub(norm_l(pL_av0[0]), 3); + for (i = 0; i <= 8; i++) + pswSav0[i] = extract_h(L_shl(pL_av0[i], swShift)); + } + + /*** compute partial sum of dm ***/ + + L_sump = 0; + + for (i = 1; i <= 8; i++) + L_sump = L_mac(L_sump, pswRav1[i], pswSav0[i]); + + /*** compute the division of the partial sum by sav0[0] ***/ + + if (L_sump < 0) + L_temp = L_negate(L_sump); + else + L_temp = L_sump; + + if (L_temp == 0) + { + L_dm = 0; + swShift = 0; + } + else + { + pswSav0[0] = shl(pswSav0[0], 3); + swShift = norm_l(L_temp); + swTemp = extract_h(L_shl(L_temp, swShift)); + + if (pswSav0[0] >= swTemp) + { + swDivShift = 0; + swTemp = divide_s(swTemp, pswSav0[0]); + } + else + { + swDivShift = 1; + swTemp = sub(swTemp, pswSav0[0]); + swTemp = divide_s(swTemp, pswSav0[0]); + } + + if (swDivShift == 1) + L_dm = 0x8000L; + else + L_dm = 0; + + L_dm = L_shl((L_add(L_dm, L_deposit_l(swTemp))), 1); + + if (L_sump < 0) + L_dm = L_sub(0L, L_dm); + } + + + /*** Re-normalisation and final computation of L_dm ***/ + + L_dm = L_shl(L_dm, 14); + L_dm = L_shr(L_dm, swShift); + L_dm = L_add(L_dm, L_shl(L_deposit_l(pswRav1[0]), 11)); + L_dm = L_shr(L_dm, swNormRav1); + + + /*** Compute the difference and save L_dm ***/ + + L_temp = L_sub(L_dm, L_lastdm); + L_lastdm = L_dm; + + if (L_temp < 0L) + L_temp = L_negate(L_temp); + + + /*** Evaluation of the state flag ***/ + + L_temp = L_sub(L_temp, 4456L); + + if (L_temp < 0) + *pswStat = 1; + else + *pswStat = 0; + + } + + /**************************************************************************** + * + * FUNCTION: tone_detection + * + * VERSION: 1.2 + * + * PURPOSE: Computes the tone flag needed for the threshold + * adaptation decision. + * + * INPUTS: pswRc[0..3] reflection coefficients calculated in the + * speech encoder short term predictor + * + * OUTPUTS: pswTone flag to indicate a periodic signal component + * + ***************************************************************************/ + + void Codec::tone_detection(int16_t pswRc[4], + int16_t *pswTone) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t + L_num, + L_den, + L_temp; + + int16_t + swTemp, + swPredErr, + pswA[3]; + + int + i; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + *pswTone = 0; + + + /*** Calculate filter coefficients ***/ + + step_up(2, pswRc, pswA); + + + /*** Calculate ( a[1] * a[1] ) ***/ + + swTemp = shl(pswA[1], 3); + L_den = L_mult(swTemp, swTemp); + + + /*** Calculate ( 4*a[2] - a[1]*a[1] ) ***/ + + L_temp = L_shl(L_deposit_h(pswA[2]), 3); + L_num = L_sub(L_temp, L_den); + + + /*** Check if pole frequency is less than 385 Hz ***/ + + if (L_num <= 0) + return; + + if (pswA[1] < 0) + { + swTemp = extract_h(L_den); + L_temp = L_msu(L_num, swTemp, 3189); + + if (L_temp < 0) + return; + } + + + /*** Calculate normalised prediction error ***/ + + swPredErr = 0x7fff; + + for (i = 0; i < 4; i++) + { + swTemp = mult(pswRc[i], pswRc[i]); + swTemp = sub(32767, swTemp); + swPredErr = mult(swPredErr, swTemp); + } + + + /*** Test if prediction error is smaller than threshold ***/ + + swTemp = sub(swPredErr, 1464); + + if (swTemp < 0) + *pswTone = 1; + + } + + #define M_PTH 26250 + #define E_PTH 18 + #define M_PLEV 17500 + #define E_PLEV 20 + #define M_MARGIN 27343 + #define E_MARGIN 27 + /**************************************************************************** + * + * FUNCTION: threshold_adaptation + * + * VERSION: 1.2 + * + * PURPOSE: Evaluates the secondary VAD decision. If speech is not + * present then the noise model rvad and adaptive threshold + * thvad are updated. + * + * INPUTS: swStat flag to indicate spectral stationarity + * swPtch flag to indicate a periodic signal component + * swTone flag to indicate a tone signal component + * pswRav1[0..8] ACF obtained from l_av1 + * swNormRav1 r_av1 scaling factor + * swM_pvad mantissa of filtered signal energy + * swE_pvad exponent of filtered signal energy + * swM_acf0 mantissa of signal frame energy + * swE_acf0 exponent of signal frame energy + * + * OUTPUTS: pswRvad[0..8] autocorrelated adaptive filter coefficients + * pswNormRvad rvad scaling factor + * pswM_thvad mantissa of decision threshold + * pswE_thvad exponent of decision threshold + * + ***************************************************************************/ + + void Codec::threshold_adaptation(int16_t swStat, + int16_t swPtch, + int16_t swTone, + int16_t pswRav1[], + int16_t swNormRav1, + int16_t swM_pvad, + int16_t swE_pvad, + int16_t swM_acf0, + int16_t swE_acf0, + int16_t pswRvad[], + int16_t *pswNormRvad, + int16_t *pswM_thvad, + int16_t *pswE_thvad) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int32_t + L_temp; + + int16_t + swTemp, + swComp, + swComp2, + swM_temp, + swE_temp; + + int + i; + + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + swComp = 0; + + /*** Test if acf0 < pth; if yes set thvad to plev ***/ + + if (swE_acf0 < E_PTH) + swComp = 1; + if ((swE_acf0 == E_PTH) && (swM_acf0 < M_PTH)) + swComp = 1; + + if (swComp == 1) + { + *pswE_thvad = E_PLEV; + *pswM_thvad = M_PLEV; + + return; + } + + + /*** Test if an adaption is required ***/ + + if (swPtch == 1) + swComp = 1; + if (swStat == 0) + swComp = 1; + if (swTone == 1) + swComp = 1; + + if (swComp == 1) + { + swAdaptCount = 0; + return; + } + + + /*** Increment adaptcount ***/ + + swAdaptCount = add(swAdaptCount, 1); + if (swAdaptCount <= 8) + return; + + + /*** computation of thvad-(thvad/dec) ***/ + + *pswM_thvad = sub(*pswM_thvad, shr(*pswM_thvad, 5)); + + if (*pswM_thvad < 0x4000) + { + *pswM_thvad = shl(*pswM_thvad, 1); + *pswE_thvad = sub(*pswE_thvad, 1); + } + + + /*** computation of pvad*fac ***/ + + L_temp = L_mult(swM_pvad, 20889); + L_temp = L_shr(L_temp, 15); + swE_temp = add(swE_pvad, 1); + + if (L_temp > 0x7fffL) + { + L_temp = L_shr(L_temp, 1); + swE_temp = add(swE_temp, 1); + } + swM_temp = extract_l(L_temp); + + + /*** test if thvad < pavd*fac ***/ + + if (*pswE_thvad < swE_temp) + swComp = 1; + + if ((*pswE_thvad == swE_temp) && (*pswM_thvad < swM_temp)) + swComp = 1; + + + /*** compute minimum(thvad+(thvad/inc), pvad*fac) when comp = 1 ***/ + + if (swComp == 1) + { + + /*** compute thvad + (thvad/inc) ***/ + + L_temp = L_add(L_deposit_l(*pswM_thvad),L_deposit_l(shr(*pswM_thvad, 4))); + + if (L_temp > 0x7fffL) + { + *pswM_thvad = extract_l(L_shr(L_temp, 1)); + *pswE_thvad = add(*pswE_thvad, 1); + } + else + *pswM_thvad = extract_l(L_temp); + + swComp2 = 0; + + if (swE_temp < *pswE_thvad) + swComp2 = 1; + + if ((swE_temp == *pswE_thvad) && (swM_temp < *pswM_thvad)) + swComp2 = 1; + + if (swComp2 == 1) + { + *pswE_thvad = swE_temp; + *pswM_thvad = swM_temp; + } + } + + + /*** compute pvad + margin ***/ + + if (swE_pvad == E_MARGIN) + { + L_temp = L_add(L_deposit_l(swM_pvad), L_deposit_l(M_MARGIN)); + swM_temp = extract_l(L_shr(L_temp, 1)); + swE_temp = add(swE_pvad, 1); + } + else + { + if (swE_pvad > E_MARGIN) + { + swTemp = sub(swE_pvad, E_MARGIN); + swTemp = shr(M_MARGIN, swTemp); + L_temp = L_add(L_deposit_l(swM_pvad), L_deposit_l(swTemp)); + + if (L_temp > 0x7fffL) + { + swE_temp = add(swE_pvad, 1); + swM_temp = extract_l(L_shr(L_temp, 1)); + } + else + { + swE_temp = swE_pvad; + swM_temp = extract_l(L_temp); + } + } + else + { + swTemp = sub(E_MARGIN, swE_pvad); + swTemp = shr(swM_pvad, swTemp); + L_temp = L_add(L_deposit_l(M_MARGIN), L_deposit_l(swTemp)); + + if (L_temp > 0x7fffL) + { + swE_temp = add(E_MARGIN, 1); + swM_temp = extract_l(L_shr(L_temp, 1)); + } + else + { + swE_temp = E_MARGIN; + swM_temp = extract_l(L_temp); + } + } + } + + /*** Test if thvad > pvad + margin ***/ + + swComp = 0; + + if (*pswE_thvad > swE_temp) + swComp = 1; + + if ((*pswE_thvad == swE_temp) && (*pswM_thvad > swM_temp)) + swComp = 1; + + if (swComp == 1) + { + *pswE_thvad = swE_temp; + *pswM_thvad = swM_temp; + } + + /*** Normalise and retain rvad[0..8] in memory ***/ + + *pswNormRvad = swNormRav1; + + for (i = 0; i <= 8; i++) + pswRvad[i] = pswRav1[i]; + + /*** Set adaptcount to adp + 1 ***/ + + swAdaptCount = 9; + + } + + /**************************************************************************** + * + * FUNCTION: vad_decision + * + * VERSION: 1.2 + * + * PURPOSE: Computes the VAD decision based on the comparison of the + * floating point representations of pvad and thvad. + * + * INPUTS: swM_pvad mantissa of filtered signal energy + * swE_pvad exponent of filtered signal energy + * swM_thvad mantissa of decision threshold + * swE_thvad exponent of decision threshold + * + * OUTPUTS: pswVvad vad decision before hangover is added + * + ***************************************************************************/ + + void Codec::vad_decision(int16_t swM_pvad, + int16_t swE_pvad, + int16_t swM_thvad, + int16_t swE_thvad, + int16_t *pswVvad) + { + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + *pswVvad = 0; + + if (swE_pvad > swE_thvad) + *pswVvad = 1; + if ((swE_pvad == swE_thvad) && (swM_pvad > swM_thvad)) + *pswVvad = 1; + + } + + /**************************************************************************** + * + * FUNCTION: vad_hangover + * + * VERSION: 1.2 + * + * PURPOSE: Computes the final VAD decision for the current frame + * being processed. + * + * INPUTS: swVvad vad decision before hangover is added + * + * OUTPUTS: pswVadFlag vad decision after hangover is added + * + ***************************************************************************/ + + void Codec::vad_hangover(int16_t swVvad, + int16_t *pswVadFlag) + { + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + if (swVvad == 1) + swBurstCount = add(swBurstCount, 1); + else + swBurstCount = 0; + + if (swBurstCount >= 3) + { + swHangCount = 5; + swBurstCount = 3; + } + + *pswVadFlag = swVvad; + + if (swHangCount >= 0) + { + *pswVadFlag = 1; + swHangCount = sub(swHangCount, 1); + } + + } + + /**************************************************************************** + * + * FUNCTION: periodicity_update + * + * VERSION: 1.2 + * + * PURPOSE: Computes the ptch flag needed for the threshold + * adaptation decision for the next frame. + * + * INPUTS: pswLags[0..3] speech encoder long term predictor lags + * + * OUTPUTS: pswPtch Boolean voiced / unvoiced decision + * + ***************************************************************************/ + + void Codec::periodicity_update(int16_t pswLags[4], + int16_t *pswPtch) + { + + /*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| + */ + + int16_t + swMinLag, + swMaxLag, + swSmallLag, + swLagCount, + swTemp; + + int + i, + j; + + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /*** Run loop for No. of sub-segments in the frame ***/ + + swLagCount = 0; + + for (i = 0; i <= 3; i++) + { + /*** Search the maximum and minimum of consecutive lags ***/ + + if (swOldLag > pswLags[i]) + { + swMinLag = pswLags[i]; + swMaxLag = swOldLag; + } + else + { + swMinLag = swOldLag; + swMaxLag = pswLags[i]; + } + + + /*** Compute smallag (modulo operation not defined) ***/ + + swSmallLag = swMaxLag; + + for (j = 0; j <= 2; j++) + { + if (swSmallLag >= swMinLag) + swSmallLag = sub(swSmallLag, swMinLag); + } + + + /*** Minimum of smallag and minlag - smallag ***/ + + swTemp = sub(swMinLag, swSmallLag); + + if (swTemp < swSmallLag) + swSmallLag = swTemp; + + if (swSmallLag < 2) + swLagCount = add(swLagCount, 1); + + + /*** Save the current LTP lag ***/ + + swOldLag = pswLags[i]; + } + + + /*** Update the veryoldlagcount and oldlagcount ***/ + + swVeryOldLagCount = swOldLagCount; + swOldLagCount = swLagCount; + + + /*** Make ptch decision ready for next frame ***/ + + swTemp = add(swOldLagCount, swVeryOldLagCount); + + if (swTemp >= 7) + *pswPtch = 1; + else + *pswPtch = 0; + + } + +} // end of namespace diff --git a/src/libs/gsmhr/gsmhr.h b/src/libs/gsmhr/gsmhr.h new file mode 100644 index 00000000..3842a426 --- /dev/null +++ b/src/libs/gsmhr/gsmhr.h @@ -0,0 +1,804 @@ +#ifndef __GSM_HR_CODEC_H +#define __GSM_HR_CODEC_H + +#include +#include "gsmhr_sp_rom.h" + +namespace GsmHr +{ + #define DATE "August 8, 1996 " + #define VERSION "Version 4.2 " + + #define LW_SIGN (long)0x80000000 /* sign bit */ + #define LW_MIN (long)0x80000000 + #define LW_MAX (long)0x7fffffff + + #define SW_SIGN (short)0x8000 /* sign bit for int16_t type */ + #define SW_MIN (short)0x8000 /* smallest Ram */ + #define SW_MAX (short)0x7fff /* largest Ram */ + #define SPEECH 1 + #define CNIFIRSTSID 2 + #define PN_INIT_SEED (int32_t)0x1091988L /* initial seed for Comfort + * noise pn-generator */ + + #define CNICONT 3 + #define CNIBFI 4 + #define VALIDSID 11 + #define INVALIDSID 22 + #define GOODSPEECH 33 + #define UNUSABLE 44 + + typedef short int int16_tRom; /* 16 bit ROM data (sr*) */ + typedef long int int32_tRom; /* 32 bit ROM data (L_r*) */ + + struct NormSw + { /* normalized int16_t fractional + * number snr.man precedes snr.sh (the + * shift count)i */ + int16_t man; /* "mantissa" stored in 16 bit + * location */ + int16_t sh; /* the shift count, stored in 16 bit + * location */ + }; + + + struct QuantList + { + /* structure which points to the beginning of a block of candidate vq + * vectors. It also stores the residual error for each vector. */ + int iNum; /* total number in list */ + int iRCIndex; /* an index to the first vector of the + * block */ + int16_t pswPredErr[PREQ1_NUM_OF_ROWS]; /* PREQ1 is the biggest block */ + }; + + /* Global constants * + ********************/ + + #define NP 10 /* order of the lpc filter */ + #define N_SUB 4 /* number of subframes */ + #define F_LEN 160 /* number of samples in a frame */ + #define S_LEN 40 /* number of samples in a subframe */ + #define A_LEN 170 /* LPC analysis length */ + #define OS_FCTR 6 /* maximum LTP lag oversampling + * factor */ + + #define OVERHANG 8 /* vad parameter */ + #define strStr strStr16 + + #define LTP_LEN 147 /* 147==0x93 length of LTP history */ + #define CNINTPER 12 + + class Codec + { + protected: + + // From typedefs.h + int giFrmCnt; /* 0,1,2,3,4..... */ + int giSfrmCnt = 0; /* 0,1,2,3 */ + + int giDTXon = 1; /* DTX Mode on/off */ + + + // From err_conc.c + int32_t plSubfrEnergyMem[4]; + int16_t swLevelMem[4], + lastR0, + pswLastGood[18], + swState, + swLastFlag; + + + // From sp_dec.c + + int16_t gswPostFiltAgcGain, + gpswPostFiltStateNum[NP], + gpswPostFiltStateDenom[NP], + swPostEmphasisState, + pswSynthFiltState[NP], + pswOldFrmKsDec[NP], + pswOldFrmAsDec[NP], + pswOldFrmPFNum[NP], + pswOldFrmPFDenom[NP], + swOldR0Dec, + pswLtpStateBaseDec[LTP_LEN + S_LEN], + pswPPreState[LTP_LEN + S_LEN]; + + + int16_t swMuteFlagOld; /* error concealment */ + + + + int16_t swRxDTXState = CNINTPER - 1; /* DTX State at the rx. + * Modulo */ + + int16_t swDecoMode = SPEECH; + int16_t swDtxMuting = 0; + int16_t swDtxBfiCnt = 0; + + int16_t swOldR0IndexDec = 0; + + int16_t swRxGsHistPtr = 0; + int32_t pL_RxGsHist[(OVERHANG - 1) * N_SUB]; + + int16_t swR0Dec; + + int16_t swVoicingMode, /* MODE */ + pswVq[3], /* LPC1, LPC2, LPC3 */ + swSi, /* INT_LPC */ + swEngyRShift; /* for use by spectral postfilter */ + + + int16_t swR0NewCN; /* DTX mode */ + + int32_tRom ppLr_gsTable[4][32]; /* DTX mode */ + + int16_t + *pswLtpStateOut = &pswLtpStateBaseDec[LTP_LEN], + pswSythAsSpace[NP * N_SUB], + pswPFNumAsSpace[NP * N_SUB], + pswPFDenomAsSpace[NP * N_SUB], + *ppswSynthAs[N_SUB] = { + &pswSythAsSpace[0], + &pswSythAsSpace[10], + &pswSythAsSpace[20], + &pswSythAsSpace[30], + }, + + *ppswPFNumAs[N_SUB] = { + &pswPFNumAsSpace[0], + &pswPFNumAsSpace[10], + &pswPFNumAsSpace[20], + &pswPFNumAsSpace[30], + }, + *ppswPFDenomAs[N_SUB] = { + &pswPFDenomAsSpace[0], + &pswPFDenomAsSpace[10], + &pswPFDenomAsSpace[20], + &pswPFDenomAsSpace[30], + }; + + int16_tRom + psrSPFDenomWidenCf[NP] = { + 0x6000, 0x4800, 0x3600, 0x2880, 0x1E60, + 0x16C8, 0x1116, 0x0CD0, 0x099C, 0x0735, + }; + + + int32_t L_RxPNSeed; /* DTX mode */ + int16_t swRxDtxGsIndex; /* DTX mode */ + + // From dtx.c + int16_t swVadFrmCnt = 0; /* Indicates the number of sequential + * frames where VAD == 0 */ + + short int siUpdPointer = 0; + int16_t swNElapsed = 50; + + int32_t pL_GsHist[N_SUB * (OVERHANG - 1)]; + + /* history of unquantized parameters */ + int32_t pL_R0Hist[OVERHANG]; + int32_t ppL_CorrHist[OVERHANG][NP + 1]; + + /* quantized reference parameters */ + int16_t swQntRefR0, + swRefGsIndex; + int piRefVqCodewds[3]; + + /* handling of short speech bursts */ + int16_t swShortBurst; + + /* state value of random generator */ + int32_t L_TxPNSeed; + + int16_t swR0OldCN; + int32_t pL_OldCorrSeq[NP + 1], + pL_NewCorrSeq[NP + 1], + pL_CorrSeq[NP + 1]; + + // From sp_enc.c + int16_t swTxGsHistPtr = 0; + + int16_t pswCNVSCode1[N_SUB], + pswCNVSCode2[N_SUB], + pswCNGsp0Code[N_SUB], + pswCNLpc[3], + swCNR0; + + int16_t pswAnalysisState[NP]; + + int16_t pswWStateNum[NP], + pswWStateDenom[NP]; + + int16_t swLastLag; + /*_________________________________________________________________________ + | | + | Other External Variables | + |_________________________________________________________________________| + */ + + int16_tRom *psrTable; /* points to correct table of + * vectors */ + int iLimit; /* accessible to all in this file + * and to lpcCorrQntz() in dtx.c */ + int iLow; /* the low element in this segment */ + int iThree; /* boolean, is this a three element + * vector */ + int iWordHalfPtr; /* points to the next byte */ + int iWordPtr; /* points to the next word to be */ + + // from vad.c + + int16_t + pswRvad[9], + swNormRvad, + swPt_sacf, + swPt_sav0, + swE_thvad, + swM_thvad, + swAdaptCount, + swBurstCount, + swHangCount, + swOldLagCount, + swVeryOldLagCount, + swOldLag; + + int32_t + pL_sacf[27], + pL_sav0[36], + L_lastdm; + + public: + + // From VAD + void vad_reset(void); + + void vad_algorithm + ( + int32_t pL_acf[9], + int16_t swScaleAcf, + int16_t pswRc[4], + int16_t swPtch, + int16_t *pswVadFlag + ); + + void energy_computation + ( + int32_t pL_acf[], + int16_t swScaleAcf, + int16_t pswRvad[], + int16_t swNormRvad, + int16_t *pswM_pvad, + int16_t *pswE_pvad, + int16_t *pswM_acf0, + int16_t *pswE_acf0 + ); + + + void average_acf + ( + int32_t pL_acf[], + int16_t swScaleAcf, + int32_t pL_av0[], + int32_t pL_av1[] + ); + + void predictor_values + ( + int32_t pL_av1[], + int16_t pswRav1[], + int16_t *pswNormRav1 + ); + + void schur_recursion + ( + int32_t pL_av1[], + int16_t pswVpar[] + ); + + void step_up + ( + int16_t swNp, + int16_t pswVpar[], + int16_t pswAav1[] + ); + + void compute_rav1 + ( + int16_t pswAav1[], + int16_t pswRav1[], + int16_t *pswNormRav1 + ); + + void spectral_comparison + ( + int16_t pswRav1[], + int16_t swNormRav1, + int32_t pL_av0[], + int16_t *pswStat + ); + + void tone_detection + ( + int16_t pswRc[4], + int16_t *pswTone + ); + + + void threshold_adaptation + ( + int16_t swStat, + int16_t swPtch, + int16_t swTone, + int16_t pswRav1[], + int16_t swNormRav1, + int16_t swM_pvad, + int16_t swE_pvad, + int16_t swM_acf0, + int16_t swE_acf0, + int16_t pswRvad[], + int16_t *pswNormRvad, + int16_t *pswM_thvad, + int16_t *pswE_thvad + ); + + void vad_decision + ( + int16_t swM_pvad, + int16_t swE_pvad, + int16_t swM_thvad, + int16_t swE_thvad, + int16_t *pswVvad + ); + + void vad_hangover + ( + int16_t swVvad, + int16_t *pswVadFlag + ); + + void periodicity_update + ( + int16_t pswLags[4], + int16_t *pswPtch + ); + + + // From err_conc.h + + void para_conceal_speech_decoder(int16_t pswErrorFlag[], + int16_t pswSpeechPara[], int16_t *pswMutePermit); + + int16_t level_calc(int16_t swInd, int32_t *pl_en); + + void level_estimator(int16_t update, int16_t *pswLevelMean, + int16_t *pswLevelMax, + int16_t pswDecodedSpeechFrame[]); + + void signal_conceal_sub(int16_t pswPPFExcit[], + int16_t ppswSynthAs[], int16_t pswSynthFiltState[], + int16_t pswLtpStateOut[], int16_t pswPPreState[], + int16_t swLevelMean, int16_t swLevelMax, + int16_t swErrorFlag1, int16_t swMuteFlagOld, + int16_t *pswMuteFlag, int16_t swMutePermit); + + + + void speechDecoder(int16_t pswParameters[], + int16_t pswDecodedSpeechFrame[]); + + void aFlatRcDp(int32_t *pL_R, int16_t *pswRc); + + void b_con(int16_t swCodeWord, short siNumBits, + int16_t pswVectOut[]); + + void fp_ex(int16_t swOrigLagIn, int16_t pswLTPState[]); + + int16_t g_corr1(int16_t *pswIn, int32_t *pL_out); + + int16_t g_corr1s(int16_t pswIn[], int16_t swEngyRShft, + int32_t *pL_out); + + void getSfrmLpc(short int siSoftInterpolation, + int16_t swPrevR0, int16_t swNewR0, + int16_t pswPrevFrmKs[], + int16_t pswPrevFrmAs[], + int16_t pswPrevFrmPFNum[], + int16_t pswPrevFrmPFDenom[], + int16_t pswNewFrmKs[], + int16_t pswNewFrmAs[], + int16_t pswNewFrmPFNum[], + int16_t pswNewFrmPFDenom[], + struct NormSw *psnsSqrtRs, + int16_t *ppswSynthAs[], + int16_t *ppswPFNumAs[], + int16_t *ppswPFDenomAs[]); + + void get_ipjj(int16_t swLagIn, + int16_t *pswIp, int16_t *pswJj); + + short int interpolateCheck(int16_t pswRefKs[], + int16_t pswRefCoefsA[], + int16_t pswOldCoefsA[], + int16_t pswNewCoefsA[], + int16_t swOldPer, + int16_t swNewPer, + int16_t swRq, + struct NormSw *psnsSqrtRsOut, + int16_t pswCoefOutA[]); + + void lpcFir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswState[], int16_t pswFiltOut[]); + + void lpcIir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswState[], int16_t pswFiltOut[]); + + void lpcIrZsIir(int16_t pswCoef[], int16_t pswFiltOut[]); + + void lpcZiIir(int16_t pswCoef[], int16_t pswState[], + int16_t pswFiltOut[]); + + void lpcZsFir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswFiltOut[]); + + void lpcZsIir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswFiltOut[]); + + void lpcZsIirP(int16_t pswCommonIO[], int16_t pswCoef[]); + + int16_t r0BasedEnergyShft(int16_t swR0Index); + + short rcToADp(int16_t swAscale, int16_t pswRc[], + int16_t pswA[]); + + void rcToCorrDpL(int16_t swAshift, int16_t swAscale, + int16_t pswRc[], int32_t pL_R[]); + + void res_eng(int16_t pswReflecCoefIn[], int16_t swRq, + struct NormSw *psnsSqrtRsOut); + + void rs_rr(int16_t pswExcitation[], struct NormSw snsSqrtRs, + struct NormSw *snsSqrtRsRr); + + void rs_rrNs(int16_t pswExcitation[], struct NormSw snsSqrtRs, + struct NormSw *snsSqrtRsRr); + + int16_t scaleExcite(int16_t pswVect[], + int16_t swErrTerm, struct NormSw snsRS, + int16_t pswScldVect[]); + + int16_t sqroot(int32_t L_SqrtIn); + + void v_con(int16_t pswBVects[], int16_t pswOutVect[], + int16_t pswBitArray[], short int siNumBVctrs); + + void a_sst(int16_t swAshift, int16_t swAscale, + int16_t pswDirectFormCoefIn[], + int16_t pswDirectFormCoefOut[]); + + int16_t agcGain(int16_t pswStateCurr[], + struct NormSw snsInSigEnergy, int16_t swEngyRShft); + + void pitchPreFilt(int16_t pswExcite[], + int16_t swRxGsp0, + int16_t swRxLag, int16_t swUvCode, + int16_t swSemiBeta, struct NormSw snsSqrtRs, + int16_t pswExciteOut[], + int16_t pswPPreState[]); + + void spectralPostFilter(int16_t pswSPFIn[], + int16_t pswNumCoef[], + int16_t pswDenomCoef[], int16_t pswSPFOut[]); + // From dtx.c + void avgCNHist(int32_t pL_R0History[], + int32_t ppL_CorrHistory[OVERHANG][NP + 1], + int32_t *pL_AvgdR0, + int32_t pL_AvgdCorrSeq[]); + + void avgGsHistQntz(int32_t pL_GsHistory[], int32_t *pL_GsAvgd); + + int16_t swComfortNoise(int16_t swVadFlag, + int32_t L_UnqntzdR0, int32_t *pL_UnqntzdCorr); + + int16_t getPnBits(int iBits, int32_t *L_PnSeed); + + int16_t gsQuant(int32_t L_GsIn, int16_t swVoicingMode); + + void updateCNHist(int32_t L_UnqntzdR0, + int32_t *pL_UnqntzdCorr, + int32_t pL_R0Hist[], + int32_t ppL_CorrHist[OVERHANG][NP + 1]); + + void lpcCorrQntz(int32_t pL_CorrelSeq[], + int16_t pswFinalRc[], + int piVQCodewds[]); + + int32_t linInterpSid(int32_t L_New, int32_t L_Old, int16_t swDtxState); + + int16_t linInterpSidShort(int16_t swNew, + int16_t swOld, + int16_t swDtxState); + + void rxInterpR0Lpc(int16_t *pswOldKs, int16_t *pswNewKs, + int16_t swRxDTXState, + int16_t swDecoMode, int16_t swFrameType); + + // From sp_frm.c + void iir_d(int16_t pswCoeff[], int16_t pswIn[], + int16_t pswXstate[], + int16_t pswYstate[], + int npts, int shifts, + int16_t swPreFirDownSh, + int16_t swFinalUpShift); + + + void filt4_2nd(int16_t pswCoeff[], + int16_t pswIn[], + int16_t pswXstate[], + int16_t pswYstate[], + int npts, + int shifts); + + void initPBarVBarL(int32_t pL_PBarFull[], + int16_t pswPBar[], + int16_t pswVBar[]); + + void initPBarFullVBarFullL(int32_t pL_CorrelSeq[], + int32_t pL_PBarFull[], + int32_t pL_VBarFull[]); + + int16_t aflatRecursion(int16_t pswQntRc[], + int16_t pswPBar[], + int16_t pswVBar[], + int16_t *ppswPAddrs[], + int16_t *ppswVAddrs[], + int16_t swSegmentOrder); + + void aflatNewBarRecursionL(int16_t pswQntRc[], + int iSegment, + int32_t pL_PBar[], + int32_t pL_VBar[], + int16_t pswPBar[], + int16_t pswVBar[]); + + + void setupPreQ(int iSeg, int iVector); + + void setupQuant(int iSeg, int iVector); + + void getNextVec(int16_t pswRc[]); + + void aflat(int16_t pswSpeechToLPC[], + int piR0Index[], + int16_t pswFinalRc[], + int piVQCodewds[], + int16_t swPtch, + int16_t *pswVadFlag, + int16_t *pswSP); + + + int16_t fnExp2(int32_t L_Input); + + int16_t fnLog2(int32_t L_Input); + + void weightSpeechFrame(int16_t pswSpeechFrm[], + int16_t pswWNumSpace[], + int16_t pswWDenomSpace[], + int16_t pswWSpeechBuffBase[]); + + void getSfrmLpcTx(int16_t swPrevR0, int16_t swNewR0, + int16_t pswPrevFrmKs[], + int16_t pswPrevFrmAs[], + int16_t pswPrevFrmSNWCoef[], + int16_t pswNewFrmKs[], + int16_t pswNewFrmAs[], + int16_t pswNewFrmSNWCoef[], + int16_t pswHPFSpeech[], + short *pswSoftInterp, + struct NormSw *psnsSqrtRs, + int16_t ppswSynthAs[][NP], + int16_t ppswSNWCoefAs[][NP]); + + short int fnBest_CG(int16_t pswCframe[], + int16_t pswGframe[], + int16_t *pswCmaxSqr, + int16_t *pswGmax, + short int siNumPairs); + + short compResidEnergy(int16_t pswSpeech[], + int16_t ppswInterpCoef[][NP], + int16_t pswPreviousCoef[], + int16_t pswCurrentCoef[], + struct NormSw psnsSqrtRs[]); + + int16_t r0Quant(int32_t L_UnqntzdR0); + + int16_t cov32(int16_t pswIn[], + int32_t pppL_B[NP][NP][2], + int32_t pppL_F[NP][NP][2], + int32_t pppL_C[NP][NP][2], + int32_t *pL_R0, + int32_t pL_VadAcf[], + int16_t *pswVadScalAuto); + + int32_t flat(int16_t pswSpeechIn[], + int16_t pswRc[], + int *piR0Inx, + int32_t pL_VadAcf[], + int16_t *pswVadScalAuto); + + + + void openLoopLagSearch(int16_t pswWSpeech[], + int16_t swPrevR0Index, + int16_t swCurrR0Index, + int16_t *psiUVCode, + int16_t pswLagList[], + int16_t pswNumLagList[], + int16_t pswPitchBuf[], + int16_t pswHNWCoefBuf[], + struct NormSw psnsWSfrmEng[], + int16_t pswVadLags[], + int16_t swSP); + + int16_t getCCThreshold(int16_t swRp0, + int16_t swCC, + int16_t swG); + + void pitchLags(int16_t swBestIntLag, + int16_t pswIntCs[], + int16_t pswIntGs[], + int16_t swCCThreshold, + int16_t pswLPeaksSorted[], + int16_t pswCPeaksSorted[], + int16_t pswGPeaksSorted[], + int16_t *psiNumSorted, + int16_t *pswPitch, + int16_t *pswHNWCoef); + + short CGInterpValid(int16_t swFullResLag, + int16_t pswCIn[], + int16_t pswGIn[], + int16_t pswLOut[], + int16_t pswCOut[], + int16_t pswGOut[]); + + void CGInterp(int16_t pswLIn[], + short siNum, + int16_t pswCIn[], + int16_t pswGIn[], + short siLoIntLag, + int16_t pswCOut[], + int16_t pswGOut[]); + + int16_t quantLag(int16_t swRawLag, + int16_t *psiCode); + + void findBestInQuantList(struct QuantList psqlInList, + int iNumVectOut, + struct QuantList psqlBestOutList[]); + + int16_t findPeak(int16_t swSingleResLag, + int16_t pswCIn[], + int16_t pswGIn[]); + + void bestDelta(int16_t pswLagList[], + int16_t pswCSfrm[], + int16_t pswGSfrm[], + short int siNumLags, + short int siSfrmIndex, + int16_t pswLTraj[], + int16_t pswCCTraj[], + int16_t pswGTraj[]); + + int16_t + maxCCOverGWithSign(int16_t pswCIn[], + int16_t pswGIn[], + int16_t *pswCCMax, + int16_t *pswGMax, + int16_t swNum); + + void getNWCoefs(int16_t pswACoefs[], + int16_t pswHCoefs[]); + + int16_t lagDecode(int16_t swDeltaLag); + + }; + + // From mathdp31 + extern int32_t L_mpy_ls(int32_t L_var2, int16_t var1); + extern int32_t L_mpy_ll(int32_t L_var1, int32_t L_var2); + extern short isSwLimit(int16_t swIn); + extern short isLwLimit(int32_t L_In); + + // From mathhalf + /* addition */ + /************/ + + extern int16_t add(int16_t var1, int16_t var2); /* 1 ops */ + extern int16_t sub(int16_t var1, int16_t var2); /* 1 ops */ + extern int32_t L_add(int32_t L_var1, int32_t L_var2); /* 2 ops */ + extern int32_t L_sub(int32_t L_var1, int32_t L_var2); /* 2 ops */ + + /* multiplication */ + /******************/ + + extern int16_t mult(int16_t var1, int16_t var2); /* 1 ops */ + extern int32_t L_mult(int16_t var1, int16_t var2); /* 1 ops */ + extern int16_t mult_r(int16_t var1, int16_t var2); /* 2 ops */ + + + /* arithmetic shifts */ + /*********************/ + + extern int16_t shr(int16_t var1, int16_t var2); /* 1 ops */ + extern int16_t shl(int16_t var1, int16_t var2); /* 1 ops */ + extern int32_t L_shr(int32_t L_var1, int16_t var2); /* 2 ops */ + extern int32_t L_shl(int32_t L_var1, int16_t var2); /* 2 ops */ + extern int16_t shift_r(int16_t var, int16_t var2); /* 2 ops */ + extern int32_t L_shift_r(int32_t L_var, int16_t var2); /* 3 ops */ + + /* absolute value */ + /*******************/ + + extern int16_t abs_s(int16_t var1); /* 1 ops */ + extern int32_t L_abs(int32_t var1); /* 3 ops */ + + + /* multiply accumulate */ + /************************/ + + extern int32_t L_mac(int32_t L_var3, + int16_t var1, int16_t var2); /* 1 op */ + extern int16_t mac_r(int32_t L_var3, + int16_t var1, int16_t var2); /* 2 op */ + extern int32_t L_msu(int32_t L_var3, + int16_t var1, int16_t var2); /* 1 op */ + extern int16_t msu_r(int32_t L_var3, + int16_t var1, int16_t var2); /* 2 op */ + + /* negation */ + /*************/ + + extern int16_t negate(int16_t var1); /* 1 ops */ + extern int32_t L_negate(int32_t L_var1); /* 2 ops */ + + + /* Accumulator manipulation */ + /****************************/ + + extern int32_t L_deposit_l(int16_t var1); /* 1 ops */ + extern int32_t L_deposit_h(int16_t var1); /* 1 ops */ + extern int16_t extract_l(int32_t L_var1); /* 1 ops */ + extern int16_t extract_h(int32_t L_var1); /* 1 ops */ + + /* Round */ + /*********/ + + extern int16_t round(int32_t L_var1); /* 1 ops */ + + /* Normalization */ + /*****************/ + + extern int16_t norm_l(int32_t L_var1); /* 30 ops */ + extern int16_t norm_s(int16_t var1); /* 15 ops */ + + /* Division */ + /************/ + extern int16_t divide_s(int16_t var1, int16_t var2); /* 18 ops */ + + /* Non-saturating instructions */ + /*******************************/ + extern int32_t L_add_c(int32_t L_Var1, int32_t L_Var2); /* 2 ops */ + extern int32_t L_sub_c(int32_t L_Var1, int32_t L_Var2); /* 2 ops */ + extern int32_t L_sat(int32_t L_var1); /* 4 ops */ + extern int32_t L_macNs(int32_t L_var3, + int16_t var1, int16_t var2); /* 1 ops */ + extern int32_t L_msuNs(int32_t L_var3, + int16_t var1, int16_t var2); /* 1 ops */ + + +} + +#endif diff --git a/src/libs/gsmhr/gsmhr_dtx.c b/src/libs/gsmhr/gsmhr_dtx.c new file mode 100644 index 00000000..ff5eb814 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_dtx.c @@ -0,0 +1,1341 @@ +/*************************************************************************** + * + * File Name: dtx.c + * + * Purpose: DTX and comfort noise functions of the GSM half rate + * system + * + * Reference: Recommendation GSM 06.41 (DTX) + * Recommendation GSM 06.22 (Comfort Noise) + * + * Below is a listing of all the functions appearing in the file. + * The functions are arranged according to their purpose. Under + * each heading, the ordering is hierarchical. + * + * Evaluation of comfort noise parameters + * swComfortNoise() + * updateCNHist() + * avgGsHistQntz() + * gsQuant() + * avgCNHist() + * lpcCorrQntz() + * getPnBits() + * + * Interpolation of comfort noise parameters + * rxInterpR0Lpc() + * linInterpSid() + * + **************************************************************************/ + +/*________________________________________________________________________ + | | + | Include Files | + |________________________________________________________________________| +*/ + +#include "typedefs.h" +#include "mathhalf.h" +#include "mathdp31.h" +#include "dtx.h" +#include "sp_dec.h" +#include "sp_rom.h" +#include "sp_frm.h" + +/*________________________________________________________________________ + | | + | Defines | + |________________________________________________________________________| +*/ + +#define PN_XOR_REG (int32_t)0x00000005L +#define PN_XOR_ADD (int32_t)0x40000000L + +#define OH_SHIFT 3 /* shift corresponding to OVERHANG */ + +#define NP_AFLAT 4 +#define LPC_VQ_SEG 3 + +#define ASHIFT 4 +#define ASCALE 0x0800 + + +/*________________________________________________________________________ + | | + | Global Variables | + |________________________________________________________________________| +*/ + +int16_t swVadFrmCnt = 0; /* Indicates the number of sequential + * frames where VAD == 0 */ + +short int siUpdPointer = 0; +int16_t swNElapsed = 50; + + +int32_t pL_GsHist[N_SUB * (OVERHANG - 1)]; + + +/*________________________________________________________________________ + | | + | Other External Variables | + |________________________________________________________________________| +*/ + +extern int iLimit; + +extern int16_t swR0Dec, + swOldR0Dec, + swR0NewCN; + +extern int16_t swCNR0, + pswCNLpc[], + pswCNGsp0Code[], + pswCNVSCode1[], + pswCNVSCode2[]; + +/*________________________________________________________________________ + | | + | DTX Rom Tables | + |________________________________________________________________________| +*/ + +/* interpolation curve for comfort noise (i*1/12) i=1..12 */ +int16_t psrCNNewFactor[12] = {0x0aaa, 0x1554, 0x1ffe, 0x2aa8, 0x3552, + 0x3ffc, 0x4aa6, 0x5550, 0x5ffa, 0x6aa4, +0x754e, 0x7fff}; + + +/* Values of GS for voicing state 0, all values shifted down by 2 + shifts */ +int32_tRom ppLr_gsTable[4][32] = +{ + { + 0x000011ab, 0x000038d2, 0x0000773e, 0x000144ef, + 0x00035675, 0x000648c5, 0x000c3d65, 0x0017ae17, + 0x002a3dbb, 0x005238e7, 0x00695c1a, 0x00a60d45, + 0x00e4cc68, 0x01c3ba6a, 0x019e3c96, 0x02d1fbac, + 0x030453ec, 0x0549a998, 0x05190298, 0x08258920, + 0x08daff30, 0x0c3150e0, 0x0e45d850, 0x14c111a0, + 0x0ff7e1c0, 0x18a06860, 0x13810400, 0x1abc9ee0, + 0x28500940, 0x41f22800, 0x22fc5040, 0x2cd90180 + }, + + { + 0x00003ede, 0x00021fc9, 0x0013f0c3, 0x003a7be2, + 0x007a6663, 0x00fe3773, 0x012fabf4, 0x02275cd0, + 0x01c0ef14, 0x02c0b1d8, 0x0350fc70, 0x05505078, + 0x04175f30, 0x052c1098, 0x08ed3310, 0x0a63b470, + 0x05417870, 0x08995ee0, 0x07bbe018, 0x0a19fa10, + 0x0b5818c0, 0x0fd96ea0, 0x0e5cad10, 0x13b40d40, + 0x12d45840, 0x14577320, 0x2b2e5e00, 0x333e9640, + 0x194c35c0, 0x1c30f8c0, 0x2d16db00, 0x2cc970ff + }, + { + 0x002f18e7, 0x00a47be0, 0x01222efe, 0x01c42df8, + 0x024be794, 0x03424c40, 0x036950fc, 0x04973108, + 0x038405b4, 0x05d8c8f0, 0x05063e08, 0x070cdea0, + 0x05812be8, 0x06da5fc8, 0x088fcd60, 0x0a013cb0, + 0x0909a460, 0x09e6cf40, 0x0ee581d0, 0x0ec99f20, + 0x0b4e7470, 0x0c730e80, 0x0ff39d20, 0x105d0d80, + 0x158b0b00, 0x172babe0, 0x14576460, 0x181a6720, + 0x26126e80, 0x1f590180, 0x1fdaad60, 0x2e0e8000 + }, + { + 0x00c7f603, 0x01260cda, 0x01b3926a, 0x026d82bc, + 0x0228fba0, 0x036ec5b0, 0x034bf4cc, 0x043a55d0, + 0x044f9c20, 0x05c66f50, 0x0515f890, 0x06065300, + 0x0665dc00, 0x0802b630, 0x0737a1c0, 0x087294e0, + 0x09253fc0, 0x0a619760, 0x097bd060, 0x0a6d4e50, + 0x0d19e520, 0x0e15c420, 0x0c4e4eb0, 0x0e8880e0, + 0x11cdf480, 0x12c85800, 0x10f4c0a0, 0x13e51b00, + 0x189dbaa0, 0x18a6bb60, 0x22e31500, 0x21615240 + } +}; + +/************************************************************************* + * + * FUNCTION NAME: swComfortNoise + * + * PURPOSE: + * + * This routine perform the following tasks: + * - generation of the speech flag (swSP) + * - averaging and encoding of the comfort noise parameters + * - randomization of the codebook indices + * + * + * INPUTS: + * + * swVadFrmCnt (global) - swVadFlag=0 frame counter. + * If swVadFlag=1 then this counter is 0, the first frame with + * swVadFlag=0 will set this counter to 1, with each additional + * swVadFlag=0 frame the counter is incremented. + * + * swVadFlag - voise activity flag. swVadFlag=0 frame with + * no voice activity, swVadFlag=0 frame with voice activity + * + * L_UnqntzdR0 - unquantized R(0), 32 bit value, output of + * FLAT. + * + * pL_UnqntzdCorr[NP+1] - unquantized correlation sequence, + * also an output of FLAT. + * + * + * OUTPUTS: + * + * swCNR0 - global variable, the output quantized R0 index + * + * pswCNLpc[3] - global variable, the output quantized LPC to the + * transmitted in the SID frame + * + * pswCNGsp0Code[N_SUB] - global variable, the output quantized GSP0 indices + * + * pswCNVSCode1[N_SUB] - global variable, the output quantized codevector 1 + * indices. + * + * pswCNVSCode2[N_SUB] - global variable, the output quantized codevector 2 + * indices. + * + * + * RETURN VALUE: + * + * swSP - speech flag, swSP=1 speech frames are generated, swSP=0 + * SID frames are generated. + * + *************************************************************************/ + +int16_t swComfortNoise(int16_t swVadFlag, + int32_t L_UnqntzdR0, int32_t *pL_UnqntzdCorr) +{ + +/*________________________________________________________________________ + | | + | Static Variables | + |________________________________________________________________________| +*/ + + /* history of unquantized parameters */ + static int32_t pL_R0Hist[OVERHANG]; + static int32_t ppL_CorrHist[OVERHANG][NP + 1]; + + /* quantized reference parameters */ + static int16_t swQntRefR0, + swRefGsIndex; + static int piRefVqCodewds[3]; + + /* handling of short speech bursts */ + static int16_t swShortBurst; + + /* state value of random generator */ + static int32_t L_TxPNSeed; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swSP; + int16_t pswFinalRc[NP]; + + /* unquantized reference parameters */ + int32_t L_RefR0; + int32_t pL_RefCorr[NP + 1]; + int32_t L_RefGs; + + int i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + swSP = 1; + + /* VadFrmCnt will indicate the number of sequential frames where */ + /* swVadFlag == 0 */ + /* ------------------------------------------------------------- */ + + if (swVadFlag) + swVadFrmCnt = 0; /* Voice acitvity present */ + else + swVadFrmCnt = add(swVadFrmCnt, 1); /* no voice activity */ + + + /* swNElapsed will indicate the number of frames that have elapsed */ + /* since the last SID frame with updated comfort noise parameters */ + /* was generated */ + /* --------------------------------------------------------------- */ + + swNElapsed = add(swNElapsed, 1); + + + /* If no voice activity was detected. */ + /* ----------------------------------- */ + + if (swVadFrmCnt) + { + + /* Short speech burst ? */ + /* -------------------- */ + + if (swVadFrmCnt == 1) + { + if (sub(swNElapsed, 24) < 0) + swShortBurst = 1; /* short speech burst detected */ + else + swShortBurst = 0; /* long speech burst detected */ + } + + + /* Update history, with this frames data */ + /* ------------------------------------- */ + + updateCNHist(L_UnqntzdR0, pL_UnqntzdCorr, + pL_R0Hist, ppL_CorrHist); + + + /* first SID frame */ + /* --------------- */ + + if (((swShortBurst == 0) && (swVadFrmCnt == OVERHANG)) || + ((swShortBurst == 1) && (swVadFrmCnt == 1))) + { + + /* init. random generator */ + /* ---------------------- */ + L_TxPNSeed = PN_INIT_SEED; + + + /* average GS */ + /* ---------- */ + avgGsHistQntz(pL_GsHist, &L_RefGs); + + + /* GS quantization */ + /* --------------- */ + swRefGsIndex = gsQuant(L_RefGs, 0); + + } + + + /* No Overhang in case of short speech bursts, */ + /* generate SID frames with repeated comfort noise parameters */ + /* ---------------------------------------------------------- */ + + if ((swShortBurst == 1) && (swVadFrmCnt < OVERHANG)) + { + + /* generate a SID frame with repeated parameters */ + /* --------------------------------------------- */ + + swSP = 0; + + + /* repeat data: r0, LPC, GS */ + /* ------------------------ */ + + swCNR0 = swQntRefR0; + + for (i = 0; i < 3; i++) + pswCNLpc[i] = piRefVqCodewds[i]; + + for (i = 0; i < N_SUB; i++) + pswCNGsp0Code[i] = swRefGsIndex; + + } + + + /* generate SID frames with updated comfort noise parameters */ + /* --------------------------------------------------------- */ + + if (swVadFrmCnt >= OVERHANG) + { + + /* A SID frame with updated parameters */ + /* ----------------------------------- */ + + swSP = 0; + swNElapsed = 0; + + + /* average R0 and correlation values */ + /* --------------------------------- */ + + avgCNHist(pL_R0Hist, ppL_CorrHist, &L_RefR0, + pL_RefCorr); + + + /* now quantize the averaged R(0) */ + /* ------------------------------ */ + + swQntRefR0 = r0Quant(L_RefR0); + + + /* Quantize the averaged correlation */ + /* --------------------------------- */ + + lpcCorrQntz(pL_RefCorr, + pswFinalRc, + piRefVqCodewds); + + + /* update frame data: r0, LPC */ + /* -------------------------- */ + + swCNR0 = swQntRefR0; + for (i = 0; i < 3; i++) + pswCNLpc[i] = piRefVqCodewds[i]; + + + /* update subframe data (unvoiced mode): GSP0 */ + /* ------------------------------------------ */ + + for (i = 0; i < N_SUB; i++) + pswCNGsp0Code[i] = swRefGsIndex; + + } + + + /* random codevectors */ + /* ------------------ */ + + if (swSP == 0) + { + for (i = 0; i < N_SUB; i++) + { + pswCNVSCode1[i] = getPnBits(7, &L_TxPNSeed); + pswCNVSCode2[i] = getPnBits(7, &L_TxPNSeed); + } + } + + + } + + return (swSP); +} + + +/************************************************************************* + * + * FUNCTION NAME: updateCNHist + * + * PURPOSE: + * + * Add current frame's unquantized R(0) and LPC information to the + * comfort noise history, so that it will be available for + * averaging. + * + * INPUTS: + * + * Unquantized values from the coder: + * + * + * L_UnqntzdR0 - unquantized frame energy R(0), an output of FLAT + * + * pL_UnqntzdCorr[NP+1] - unquantized correlation coefficient + * array. Also an output of FLAT. + * + * siUpdPointer (global) - A modulo counter which counts up from + * 0 to OVERHANG-1. + * + * OUTPUTS: + * + * pL_R0History[OVERHANG] - history of the OVERHANG frames worth of + * R(0). + * + * ppL_CorrHistory[OVERHANG][NP+1] - - history of the OVERHANG + * frames worth of pL_UnqntzdCorr[]. + * + * RETURN VALUE: + * + * none + * + *************************************************************************/ + +void updateCNHist(int32_t L_UnqntzdR0, + int32_t *pL_UnqntzdCorr, + int32_t pL_R0History[], + int32_t ppL_CorrHistory[OVERHANG][NP + 1]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* update */ + pL_R0History[siUpdPointer] = L_UnqntzdR0; + + for (i = 0; i < NP + 1; i++) + ppL_CorrHistory[siUpdPointer][i] = pL_UnqntzdCorr[i]; + + siUpdPointer = (siUpdPointer + 1) % OVERHANG; +} + + +/************************************************************************* + * + * FUNCTION NAME: avgGsHistQntz + * + * PURPOSE: + * + * Average gs history, where history is of length OVERHANG-1 + * frames. The last frame's (i.e. this frame) gs values are not + * available since quantization would have occured only after the + * VAD decision is made. + * + * INPUTS: + * + * pL_GsHistory[(OVERHANG-1)*N_SUB] - the GS of the past + * OVERHANG-1 frames. The GS values are stored shifted down by 2 + * shifts to avoid overflow (the largest GS is greater than 2.0). + * + * + * OUTPUTS: + * + * *pL_GsAvgd - the average of pL_GsHistory[], also shifted down + * by two shifts. + * + * RETURN VALUE: + * + * none. + * + * + *************************************************************************/ + +void avgGsHistQntz(int32_t pL_GsHistory[], int32_t *pL_GsAvgd) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + int32_t L_avg; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + L_avg = L_shift_r(pL_GsHistory[0], -(OH_SHIFT + 2)); + + for (i = 1; i < N_SUB * (OVERHANG - 1); i++) + L_avg = L_add(L_shift_r(pL_GsHistory[i], -(OH_SHIFT + 2)), L_avg); + + /* avg number x/32 not x/28 */ + + *pL_GsAvgd = L_add(L_avg, L_mpy_ls(L_avg, 0x1249)); /* L_avg *= 32/28 */ + +} + + +/************************************************************************* + * + * FUNCTION NAME: gsQuant + * + * PURPOSE: + * + * Quantize a value of gs in any of the voicing modes. Input GS + * is a 32 bit number. The GSP0 index is returned. + * + * INPUTS: + * + * L_GsIn - 32 bit GS value, shifted down by 2 shifts. + * + * swVoicingMode - voicing level + * + * ppLr_gsTable[4][32] - Rom GS Table. (global), all GS values + * have been shifted down by 2 from their true value. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * + * GSP0 Index closest to the input value of GS. + * + * + *************************************************************************/ + +int16_t gsQuant(int32_t L_GsIn, int16_t swVoicingMode) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swGsIndex, + swBestGs; + int32_t L_diff, + L_min = LW_MAX; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + for (swGsIndex = 0; swGsIndex < 32; swGsIndex++) + { + L_diff = L_abs(L_sub(L_GsIn, ppLr_gsTable[swVoicingMode][swGsIndex])); + + if (L_sub(L_diff, L_min) < 0) + { + /* new minimum */ + /* ----------- */ + + swBestGs = swGsIndex; + L_min = L_diff; + + } + } + + return (swBestGs); + +} + + +/************************************************************************* + * + * FUNCTION NAME: avgCNHist + * + * PURPOSE: + * + * Average the unquantized R0 and LPC data stored at the encoder + * to arrive at an average R0 and LPC frame for use in a SID + * frame. + * + * INPUTS: + * + * pL_R0History[OVERHANG] - contains unquantized R(0) data from the + * most recent OVERHANG frame (including this one). + * + * ppL_CorrHistory[OVERHANG][NP+1] - Unquantized correlation + * coefficients from the most recent OVERHANG frame (including this + * one). The data stored here is an output of FLAT. + * + * OUTPUTS: + * + * *pL_AvgdR0 - the average of pL_R0History[] + * + * pL_AvgdCorrSeq[NP+1] - the average of ppL_CorrHistory[][]. + * + * + * RETURN VALUE: + * + * none + * + *************************************************************************/ + +void avgCNHist(int32_t pL_R0History[], + int32_t ppL_CorrHistory[OVERHANG][NP + 1], + int32_t *pL_AvgdR0, + int32_t pL_AvgdCorrSeq[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i, + j; + int32_t L_avg; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* R0 Averaging */ + /* ------------ */ + + for (L_avg = 0, i = 0; i < OVERHANG; i++) + L_avg = L_add(L_shr(pL_R0History[i], OH_SHIFT), L_avg); + + *pL_AvgdR0 = L_avg; + + + /* LPC: average the last OVERHANG frames */ + /* ------------------------------------- */ + + for (j = 0; j < NP + 1; j++) + { + for (L_avg = 0, i = 0; i < OVERHANG; i++) + { + L_avg = L_add(L_shift_r(ppL_CorrHistory[i][j], -OH_SHIFT), L_avg); + } + + pL_AvgdCorrSeq[j] = L_avg; + } + +} + + +/*************************************************************************** + * + * FUNCTION NAME: lpcCorrQntz + * + * PURPOSE: Quantize a correlation sequence + * + * + * INPUT: + * + * pL_CorrelSeq[NP+1] + * Correlation sequence to quantize. + * + * OUTPUTS: + * + * pswFinalRc[0:NP-1] + * A quantized set of NP reflection coefficients. + * + * piVQCodewds[0:2] + * An array containing the indices of the 3 reflection + * coefficient vectors selected from the three segment + * Rc-VQ. + * + * RETURN: + * None. + * + * KEYWORDS: AFLAT,aflat,flat,vectorquantization, reflectioncoefficients + * + *************************************************************************/ + +void lpcCorrQntz(int32_t pL_CorrelSeq[], + int16_t pswFinalRc[], + int piVQCodewds[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t pswPOldSpace[NP_AFLAT], + pswPNewSpace[NP_AFLAT], + pswVOldSpace[2 * NP_AFLAT - 1], + pswVNewSpace[2 * NP_AFLAT - 1], + *ppswPAddrs[2], + *ppswVAddrs[2], + *pswVBar, + pswPBar[NP_AFLAT], + pswVBarSpace[2 * NP_AFLAT - 1], + pswFlatsRc[NP], /* Unquantized Rc's computed by FLAT */ + pswRc[NP + 1]; /* Temp list for the converted RC's */ + int32_t *pL_VBarFull, + pL_PBarFull[NP], + pL_VBarFullSpace[2 * NP - 1]; + + int i, + iVec, + iSeg, + iCnt; /* Loop counter */ + struct QuantList quantList, /* A list of vectors */ + bestPql[4]; /* The four best vectors from + * the PreQ */ + struct QuantList bestQl[LPC_VQ_SEG + 1]; /* Best vectors for each of + * the three segments */ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Setup pointers temporary space */ + /*--------------------------------*/ + + pswVBar = pswVBarSpace + NP_AFLAT - 1; + pL_VBarFull = pL_VBarFullSpace + NP - 1; + ppswPAddrs[0] = pswPOldSpace; + ppswPAddrs[1] = pswPNewSpace; + ppswVAddrs[0] = pswVOldSpace + NP_AFLAT - 1; + ppswVAddrs[1] = pswVNewSpace + NP_AFLAT - 1; + + + /* Set up pL_PBarFull and pL_VBarFull initial conditions, using the */ + /* autocorrelation sequence derived from the optimal reflection */ + /* coefficients computed by FLAT. The initial conditions are shifted */ + /* right by RSHIFT bits. These initial conditions, stored as */ + /* int32_ts, are used to initialize PBar and VBar arrays for the */ + /* next VQ segment. */ + /*--------------------------------------------------------------------*/ + + initPBarFullVBarFullL(pL_CorrelSeq, pL_PBarFull, pL_VBarFull); + + /* Set up initial PBar and VBar initial conditions, using pL_PBarFull */ + /* and pL_VBarFull arrays initialized above. These are the initial */ + /* PBar and VBar conditions to be used by the AFLAT recursion at the */ + /* 1-st Rc-VQ segment. */ + /*--------------------------------------------------------------------*/ + + initPBarVBarL(pL_PBarFull, pswPBar, pswVBar); + + for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++) + { + /* initialize candidate list */ + /*---------------------------*/ + + quantList.iNum = psrPreQSz[iSeg - 1]; + quantList.iRCIndex = 0; + + /* do aflat for all vectors in the list */ + /*--------------------------------------*/ + + setupPreQ(iSeg, quantList.iRCIndex); /* set up vector ptrs */ + + for (iCnt = 0; iCnt < quantList.iNum; iCnt++) + { + /* get a vector */ + /*--------------*/ + + getNextVec(pswRc); + + /* clear the limiter flag */ + /*------------------------*/ + + iLimit = 0; + + /* find the error values for each vector */ + /*---------------------------------------*/ + + quantList.pswPredErr[iCnt] = + aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l], + pswPBar, pswVBar, + ppswPAddrs, ppswVAddrs, + psvqIndex[iSeg - 1].len); + + /* check the limiter flag */ + /*------------------------*/ + + if (iLimit) + quantList.pswPredErr[iCnt] = 0x7fff; /* set error to bad value */ + + } /* done list loop */ + + /* find 4 best prequantizer levels */ + /*---------------------------------*/ + + findBestInQuantList(quantList, 4, bestPql); + + for (iVec = 0; iVec < 4; iVec++) + { + + /* initialize quantizer list */ + /*---------------------------*/ + + quantList.iNum = psrQuantSz[iSeg - 1]; + quantList.iRCIndex = bestPql[iVec].iRCIndex * psrQuantSz[iSeg - 1]; + + setupQuant(iSeg, quantList.iRCIndex); /* set up vector ptrs */ + + /* do aflat recursion on each element of list */ + /*--------------------------------------------*/ + + for (iCnt = 0; iCnt < quantList.iNum; iCnt++) + { + /* get a vector */ + /*--------------*/ + + getNextVec(pswRc); + + /* clear the limiter flag */ + /*------------------------*/ + + iLimit = 0; + + /* find the error values for each vector */ + /*---------------------------------------*/ + + quantList.pswPredErr[iCnt] = + aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l], + pswPBar, pswVBar, + ppswPAddrs, ppswVAddrs, + psvqIndex[iSeg - 1].len); + + /* check the limiter flag */ + /*------------------------*/ + + if (iLimit) + quantList.pswPredErr[iCnt] = 0x7fff; /* set error to the worst + * value */ + + } /* done list loop */ + + /* find best quantizer vector for this segment, and save it */ + /*----------------------------------------------------------*/ + + findBestInQuantList(quantList, 1, bestQl); + if (iVec == 0) + bestQl[iSeg] = bestQl[0]; + else if (sub(bestQl[iSeg].pswPredErr[0], bestQl[0].pswPredErr[0]) > 0) + bestQl[iSeg] = bestQl[0]; + + } + + /* find the quantized reflection coefficients */ + /*--------------------------------------------*/ + + setupQuant(iSeg, bestQl[iSeg].iRCIndex); /* set up vector ptrs */ + getNextVec((int16_t *) (pswFinalRc - 1)); + + + /* Update pBarFull and vBarFull for the next Rc-VQ segment, and */ + /* update the pswPBar and pswVBar for the next Rc-VQ segment */ + /*--------------------------------------------------------------*/ + + if (iSeg < LPC_VQ_SEG) + aflatNewBarRecursionL(&pswFinalRc[psvqIndex[iSeg - 1].l - 1], iSeg, + pL_PBarFull, pL_VBarFull, pswPBar, pswVBar); + + } + + /* find the quantizer index (the values to be output in the symbol file) */ + /*-----------------------------------------------------------------*/ + + for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++) + piVQCodewds[iSeg - 1] = bestQl[iSeg].iRCIndex; + +} + + +/************************************************************************* + * + * FUNCTION NAME: getPnBits + * + * PURPOSE: + * + * Generate iBits pseudo-random bits using *pL_PNSeed as the + * pn-generators seed. + * + * INPUTS: + * + * iBits - integer indicating how many random bits to return. + * range [0,15], 0 yields 1 bit output + * + * *pL_PNSeed - 32 bit seed (changed by function) + * + * OUTPUTS: + * + * *pL_PNSeed - 32 bit seed, modified. + * + * RETURN VALUE: + * + * random bits in iBits LSB's. + * + * + * IMPLEMENTATION: + * + * implementation of x**31 + x**3 + 1 == PN_XOR_REG | PN_XOR_ADD a + * PN sequence generator using int32_ts generating a 2**31 -1 + * length pn-sequence. + * + *************************************************************************/ + +int16_t getPnBits(int iBits, int32_t *pL_PNSeed) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swPnBits = 0; + int32_t L_Taps, + L_FeedBack; + int i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + for (i = 0; i < iBits; i++) + { + /* update the state */ + /* ---------------- */ + + L_Taps = *pL_PNSeed & PN_XOR_REG; + L_FeedBack = L_Taps; /* Xor tap bits to yield + * feedback bit */ + L_Taps = L_shr(L_Taps, 1); + + while (L_Taps) + { + L_FeedBack = L_FeedBack ^ L_Taps; + L_Taps = L_shr(L_Taps, 1); + } + + /* LSB of L_FeedBack is next MSB of PN register */ + + *pL_PNSeed = L_shr(*pL_PNSeed, 1); + if (L_FeedBack & 1) + *pL_PNSeed = *pL_PNSeed | PN_XOR_ADD; + + /* State update complete. Get the output bit from the state, add/or it + * into output */ + + swPnBits = shl(swPnBits, 1); + swPnBits = swPnBits | (extract_l(*pL_PNSeed) & 0x0001); + + } + return (swPnBits); +} + + +/************************************************************************* + * + * FUNCTION NAME: rxInterpR0Lpc + * + * PURPOSE: + * + * Perform part of the comfort noise algorithm at the decoder. + * LPC and R0 are derived in this routine + * + * INPUTS: + * + * pswOldKs - Last frame's reflection coeffs. + * + * pswNewKs - This frame's decoded/received reflection coeffs. + * This will serve a new endpoint in interpolation. + * + * swRxDTXState - primary DTX state variable (at the receiver). A + * modulo 12 counter, which is 0 at SID frame. + * + * swDecoMode - actual mode the decoder: speech decoding mode + * or comfort noise insertion mode (SPEECH = speech decoding; + * CNIFIRSTSID = comfort noise, 1st SID received; CNICONT = comfort + * noise, SID frame received, but not 1st SID; CNIBFI = comfort + * noise, bad frame received) + * + * swFrameType - type of the received frame (VALIDSID, INVALIDSID + * GOODSPEECH or UNUSABLE) + * + * swOldR0Dec - global variable, the decoded R0 value from the last + * frame . This will be modified. + * + * swR0NewCN - global variable the decoded R0 value from the frame + * just received. Valid information if current frame is a SID frame. + * + * + * OUTPUTS: + * + * pswNewKs - This frames LPC coeffs. modified to reflect + * interpolated correlation sequence pL_CorrSeq[]. + * + * swR0Dec - global variable, interpolated R0 value + * + * swR0OldCN - global variable, R0 interpolation point to + * interpolate from. + * + * swR0NewCN - global variable, R0 interpolation point to + * interpolate to. + * + * pL_OldCorrSeq[NP+1] - global variable, starting point for + * interpolation of LPC information. + * + * pL_NewCorrSeq[NP+1] - global variable, end point for + * interpolation of LPC information. + * + * pL_CorrSeq[NP+1] - global variable, interpolated value of LPC + * information to be used in this frame. + * + * + * RETURN VALUE: + * + * None. + * + * KEYWORDS: interpolation, comfort noise, SID, DTX + * + *************************************************************************/ + +void rxInterpR0Lpc(int16_t *pswOldKs, int16_t *pswNewKs, + int16_t swRxDTXState, + int16_t swDecoMode, int16_t swFrameType) +{ + +/*________________________________________________________________________ + | | + | Static Variables | + |________________________________________________________________________| +*/ + + static int16_t swR0OldCN; + static int32_t pL_OldCorrSeq[NP + 1], + pL_NewCorrSeq[NP + 1], + pL_CorrSeq[NP + 1]; + + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + if (swDecoMode == CNIFIRSTSID) + { + /* first SID frame arrived */ + /* ----------------------- */ + + /* use tx'd R0 frame as both endpoints of interp curve. */ + /* i.e. no interpolation for the first frames */ + /* ---------------------------------------------------- */ + + + swR0OldCN = swOldR0Dec; /* last non-SID, received R0 */ + swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState); + + + /* generate the LPC end points for interpolation */ + /* --------------------------------------------- */ + + rcToCorrDpL(ASHIFT, ASCALE, pswOldKs, pL_OldCorrSeq); + rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, pL_NewCorrSeq); + + /* linearly interpolate between the two sets of correlation coefs */ + /* -------------------------------------------------------------- */ + + for (i = 0; i < NP + 1; i++) + { + pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i], + swRxDTXState); + } + + /* Generate this frames K's (overwrite input) */ + /* ------------------------------------------ */ + + aFlatRcDp(pL_CorrSeq, pswNewKs); + + } + else if ((swDecoMode == CNICONT) && (swFrameType == VALIDSID)) + { + /* new (not the first) SID frame arrived */ + /* ------------------------------------- */ + + swR0OldCN = swOldR0Dec; /* move current state of R0 to old */ + swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState); + + + /* LPC: generate new endpoints for interpolation */ + /* --------------------------------------------- */ + + for (i = 0; i < NP + 1; i++) + { + pL_OldCorrSeq[i] = pL_CorrSeq[i]; + } + + rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, pL_NewCorrSeq); + + + /* linearly interpolate between the two sets of correlation coefs */ + /* -------------------------------------------------------------- */ + + for (i = 0; i < NP + 1; i++) + { + pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i], + swRxDTXState); + } + + + /* Use interpolated LPC for this frame, overwrite the input K's */ + /* ------------------------------------------------------------ */ + + aFlatRcDp(pL_CorrSeq, pswNewKs); + + } + else + { + /* in between SID frames / invalid SID frames */ + /* ------------------------------------------ */ + + swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState); + + + /* linearly interpolate between the two sets of correlation coefs */ + /* -------------------------------------------------------------- */ + + for (i = 0; i < NP + 1; i++) + { + pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i], + swRxDTXState); + } + + + /* Use interpolated LPC for this frame, overwrite the input K's */ + /* ------------------------------------------------------------ */ + + aFlatRcDp(pL_CorrSeq, pswNewKs); + + } +} + + +/************************************************************************* + * + * FUNCTION NAME: linInterpSid + * + * PURPOSE: + * + * Linearly interpolate between two input numbers based on what the + * current DtxState is. + * + * INPUTS: + * + * L_New - int32_t more current value + * + * L_Old - int32_t oldest value + * + * swDtxState - state is 0 at the transmitted SID Frame. + * + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * A value between old and new inputs with dtxState+1/12 of the new + * (dtxState+1)-12/12 of the old + * + * + *************************************************************************/ + +int32_t linInterpSid(int32_t L_New, int32_t L_Old, int16_t swDtxState) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swOldFactor; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* old factor = (1.0 - newFactor) */ + /* ------------------------------ */ + + swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]); + swOldFactor = add(0x1, swOldFactor); + + + /* contributions from new and old */ + /* ------------------------------ */ + + L_New = L_mpy_ls(L_New, psrCNNewFactor[swDtxState]); + L_Old = L_mpy_ls(L_Old, swOldFactor); + + return (L_add(L_New, L_Old)); + +} + + +/************************************************************************* + * + * FUNCTION NAME: linInterpSidShort + * + * PURPOSE: + * + * Linearly interpolate between two input numbers based on what + * the current DtxState is. + * + * INPUTS: + * + * swNew - 16 bit, more current value + * + * swOld - 16 bit, oldest value + * + * swDtxState - state is 0 at the transmitted SID Frame. + * + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * A value between old and new inputs with dtxState+1/12 of the new + * (dtxState+1)-12/12 of the old + * + *************************************************************************/ + +int16_t linInterpSidShort(int16_t swNew, int16_t swOld, + int16_t swDtxState) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swOldFactor; + int32_t L_New, + L_Old; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* old factor = (1.0 - newFactor) */ + /* ------------------------------ */ + + swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]); + swOldFactor = add(0x1, swOldFactor); + + + /* contributions from new and old */ + /* ------------------------------ */ + + L_New = L_mult(swNew, psrCNNewFactor[swDtxState]); + L_Old = L_mult(swOld, swOldFactor); + + + return (round(L_add(L_New, L_Old))); + +} diff --git a/src/libs/gsmhr/gsmhr_dtx.cpp b/src/libs/gsmhr/gsmhr_dtx.cpp new file mode 100644 index 00000000..92ef5db8 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_dtx.cpp @@ -0,0 +1,1334 @@ +/*************************************************************************** + * + * File Name: dtx.c + * + * Purpose: DTX and comfort noise functions of the GSM half rate + * system + * + * Reference: Recommendation GSM 06.41 (DTX) + * Recommendation GSM 06.22 (Comfort Noise) + * + * Below is a listing of all the functions appearing in the file. + * The functions are arranged according to their purpose. Under + * each heading, the ordering is hierarchical. + * + * Evaluation of comfort noise parameters + * swComfortNoise() + * updateCNHist() + * avgGsHistQntz() + * gsQuant() + * avgCNHist() + * lpcCorrQntz() + * getPnBits() + * + * Interpolation of comfort noise parameters + * rxInterpR0Lpc() + * linInterpSid() + * + **************************************************************************/ + +/*________________________________________________________________________ + | | + | Include Files | + |________________________________________________________________________| +*/ + +#include "gsmhr_typedefs.h" +#include "gsmhr_mathhalf.h" +#include "gsmhr_mathdp31.h" +#include "gsmhr_dtx.h" +#include "gsmhr_sp_dec.h" +#include "gsmhr_sp_rom.h" +#include "gsmhr_sp_frm.h" + +using namespace GsmHr; +/*________________________________________________________________________ + | | + | Defines | + |________________________________________________________________________| +*/ + +#define PN_XOR_REG (int32_t)0x00000005L +#define PN_XOR_ADD (int32_t)0x40000000L + +#define OH_SHIFT 3 /* shift corresponding to OVERHANG */ + +#define NP_AFLAT 4 +#define LPC_VQ_SEG 3 + +#define ASHIFT 4 +#define ASCALE 0x0800 + + +/*________________________________________________________________________ + | | + | Global Variables | + |________________________________________________________________________| +*/ + + + +/*________________________________________________________________________ + | | + | Other External Variables | + |________________________________________________________________________| +*/ + +extern int iLimit; + +extern int16_t swR0Dec, + swOldR0Dec, + swR0NewCN; + +extern int16_t swCNR0, + pswCNLpc[], + pswCNGsp0Code[], + pswCNVSCode1[], + pswCNVSCode2[]; + +/*________________________________________________________________________ + | | + | DTX Rom Tables | + |________________________________________________________________________| +*/ + +/* interpolation curve for comfort noise (i*1/12) i=1..12 */ +int16_t psrCNNewFactor[12] = {0x0aaa, 0x1554, 0x1ffe, 0x2aa8, 0x3552, + 0x3ffc, 0x4aa6, 0x5550, 0x5ffa, 0x6aa4, +0x754e, 0x7fff}; + + +/* Values of GS for voicing state 0, all values shifted down by 2 + shifts */ +int32_tRom ppLr_gsTable[4][32] = +{ + { + 0x000011ab, 0x000038d2, 0x0000773e, 0x000144ef, + 0x00035675, 0x000648c5, 0x000c3d65, 0x0017ae17, + 0x002a3dbb, 0x005238e7, 0x00695c1a, 0x00a60d45, + 0x00e4cc68, 0x01c3ba6a, 0x019e3c96, 0x02d1fbac, + 0x030453ec, 0x0549a998, 0x05190298, 0x08258920, + 0x08daff30, 0x0c3150e0, 0x0e45d850, 0x14c111a0, + 0x0ff7e1c0, 0x18a06860, 0x13810400, 0x1abc9ee0, + 0x28500940, 0x41f22800, 0x22fc5040, 0x2cd90180 + }, + + { + 0x00003ede, 0x00021fc9, 0x0013f0c3, 0x003a7be2, + 0x007a6663, 0x00fe3773, 0x012fabf4, 0x02275cd0, + 0x01c0ef14, 0x02c0b1d8, 0x0350fc70, 0x05505078, + 0x04175f30, 0x052c1098, 0x08ed3310, 0x0a63b470, + 0x05417870, 0x08995ee0, 0x07bbe018, 0x0a19fa10, + 0x0b5818c0, 0x0fd96ea0, 0x0e5cad10, 0x13b40d40, + 0x12d45840, 0x14577320, 0x2b2e5e00, 0x333e9640, + 0x194c35c0, 0x1c30f8c0, 0x2d16db00, 0x2cc970ff + }, + { + 0x002f18e7, 0x00a47be0, 0x01222efe, 0x01c42df8, + 0x024be794, 0x03424c40, 0x036950fc, 0x04973108, + 0x038405b4, 0x05d8c8f0, 0x05063e08, 0x070cdea0, + 0x05812be8, 0x06da5fc8, 0x088fcd60, 0x0a013cb0, + 0x0909a460, 0x09e6cf40, 0x0ee581d0, 0x0ec99f20, + 0x0b4e7470, 0x0c730e80, 0x0ff39d20, 0x105d0d80, + 0x158b0b00, 0x172babe0, 0x14576460, 0x181a6720, + 0x26126e80, 0x1f590180, 0x1fdaad60, 0x2e0e8000 + }, + { + 0x00c7f603, 0x01260cda, 0x01b3926a, 0x026d82bc, + 0x0228fba0, 0x036ec5b0, 0x034bf4cc, 0x043a55d0, + 0x044f9c20, 0x05c66f50, 0x0515f890, 0x06065300, + 0x0665dc00, 0x0802b630, 0x0737a1c0, 0x087294e0, + 0x09253fc0, 0x0a619760, 0x097bd060, 0x0a6d4e50, + 0x0d19e520, 0x0e15c420, 0x0c4e4eb0, 0x0e8880e0, + 0x11cdf480, 0x12c85800, 0x10f4c0a0, 0x13e51b00, + 0x189dbaa0, 0x18a6bb60, 0x22e31500, 0x21615240 + } +}; + +/************************************************************************* + * + * FUNCTION NAME: swComfortNoise + * + * PURPOSE: + * + * This routine perform the following tasks: + * - generation of the speech flag (swSP) + * - averaging and encoding of the comfort noise parameters + * - randomization of the codebook indices + * + * + * INPUTS: + * + * swVadFrmCnt (global) - swVadFlag=0 frame counter. + * If swVadFlag=1 then this counter is 0, the first frame with + * swVadFlag=0 will set this counter to 1, with each additional + * swVadFlag=0 frame the counter is incremented. + * + * swVadFlag - voise activity flag. swVadFlag=0 frame with + * no voice activity, swVadFlag=0 frame with voice activity + * + * L_UnqntzdR0 - unquantized R(0), 32 bit value, output of + * FLAT. + * + * pL_UnqntzdCorr[NP+1] - unquantized correlation sequence, + * also an output of FLAT. + * + * + * OUTPUTS: + * + * swCNR0 - global variable, the output quantized R0 index + * + * pswCNLpc[3] - global variable, the output quantized LPC to the + * transmitted in the SID frame + * + * pswCNGsp0Code[N_SUB] - global variable, the output quantized GSP0 indices + * + * pswCNVSCode1[N_SUB] - global variable, the output quantized codevector 1 + * indices. + * + * pswCNVSCode2[N_SUB] - global variable, the output quantized codevector 2 + * indices. + * + * + * RETURN VALUE: + * + * swSP - speech flag, swSP=1 speech frames are generated, swSP=0 + * SID frames are generated. + * + *************************************************************************/ + +int16_t swComfortNoise(int16_t swVadFlag, + int32_t L_UnqntzdR0, int32_t *pL_UnqntzdCorr) +{ + +/*________________________________________________________________________ + | | + | Static Variables | + |________________________________________________________________________| +*/ + + /* history of unquantized parameters */ + static int32_t pL_R0Hist[OVERHANG]; + static int32_t ppL_CorrHist[OVERHANG][NP + 1]; + + /* quantized reference parameters */ + static int16_t swQntRefR0, + swRefGsIndex; + static int piRefVqCodewds[3]; + + /* handling of short speech bursts */ + static int16_t swShortBurst; + + /* state value of random generator */ + static int32_t L_TxPNSeed; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swSP; + int16_t pswFinalRc[NP]; + + /* unquantized reference parameters */ + int32_t L_RefR0; + int32_t pL_RefCorr[NP + 1]; + int32_t L_RefGs; + + int i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + swSP = 1; + + /* VadFrmCnt will indicate the number of sequential frames where */ + /* swVadFlag == 0 */ + /* ------------------------------------------------------------- */ + + if (swVadFlag) + swVadFrmCnt = 0; /* Voice acitvity present */ + else + swVadFrmCnt = add(swVadFrmCnt, 1); /* no voice activity */ + + + /* swNElapsed will indicate the number of frames that have elapsed */ + /* since the last SID frame with updated comfort noise parameters */ + /* was generated */ + /* --------------------------------------------------------------- */ + + swNElapsed = add(swNElapsed, 1); + + + /* If no voice activity was detected. */ + /* ----------------------------------- */ + + if (swVadFrmCnt) + { + + /* Short speech burst ? */ + /* -------------------- */ + + if (swVadFrmCnt == 1) + { + if (sub(swNElapsed, 24) < 0) + swShortBurst = 1; /* short speech burst detected */ + else + swShortBurst = 0; /* long speech burst detected */ + } + + + /* Update history, with this frames data */ + /* ------------------------------------- */ + + updateCNHist(L_UnqntzdR0, pL_UnqntzdCorr, + pL_R0Hist, ppL_CorrHist); + + + /* first SID frame */ + /* --------------- */ + + if (((swShortBurst == 0) && (swVadFrmCnt == OVERHANG)) || + ((swShortBurst == 1) && (swVadFrmCnt == 1))) + { + + /* init. random generator */ + /* ---------------------- */ + L_TxPNSeed = PN_INIT_SEED; + + + /* average GS */ + /* ---------- */ + avgGsHistQntz(pL_GsHist, &L_RefGs); + + + /* GS quantization */ + /* --------------- */ + swRefGsIndex = gsQuant(L_RefGs, 0); + + } + + + /* No Overhang in case of short speech bursts, */ + /* generate SID frames with repeated comfort noise parameters */ + /* ---------------------------------------------------------- */ + + if ((swShortBurst == 1) && (swVadFrmCnt < OVERHANG)) + { + + /* generate a SID frame with repeated parameters */ + /* --------------------------------------------- */ + + swSP = 0; + + + /* repeat data: r0, LPC, GS */ + /* ------------------------ */ + + swCNR0 = swQntRefR0; + + for (i = 0; i < 3; i++) + pswCNLpc[i] = piRefVqCodewds[i]; + + for (i = 0; i < N_SUB; i++) + pswCNGsp0Code[i] = swRefGsIndex; + + } + + + /* generate SID frames with updated comfort noise parameters */ + /* --------------------------------------------------------- */ + + if (swVadFrmCnt >= OVERHANG) + { + + /* A SID frame with updated parameters */ + /* ----------------------------------- */ + + swSP = 0; + swNElapsed = 0; + + + /* average R0 and correlation values */ + /* --------------------------------- */ + + avgCNHist(pL_R0Hist, ppL_CorrHist, &L_RefR0, + pL_RefCorr); + + + /* now quantize the averaged R(0) */ + /* ------------------------------ */ + + swQntRefR0 = r0Quant(L_RefR0); + + + /* Quantize the averaged correlation */ + /* --------------------------------- */ + + lpcCorrQntz(pL_RefCorr, + pswFinalRc, + piRefVqCodewds); + + + /* update frame data: r0, LPC */ + /* -------------------------- */ + + swCNR0 = swQntRefR0; + for (i = 0; i < 3; i++) + pswCNLpc[i] = piRefVqCodewds[i]; + + + /* update subframe data (unvoiced mode): GSP0 */ + /* ------------------------------------------ */ + + for (i = 0; i < N_SUB; i++) + pswCNGsp0Code[i] = swRefGsIndex; + + } + + + /* random codevectors */ + /* ------------------ */ + + if (swSP == 0) + { + for (i = 0; i < N_SUB; i++) + { + pswCNVSCode1[i] = getPnBits(7, &L_TxPNSeed); + pswCNVSCode2[i] = getPnBits(7, &L_TxPNSeed); + } + } + + + } + + return (swSP); +} + + +/************************************************************************* + * + * FUNCTION NAME: updateCNHist + * + * PURPOSE: + * + * Add current frame's unquantized R(0) and LPC information to the + * comfort noise history, so that it will be available for + * averaging. + * + * INPUTS: + * + * Unquantized values from the coder: + * + * + * L_UnqntzdR0 - unquantized frame energy R(0), an output of FLAT + * + * pL_UnqntzdCorr[NP+1] - unquantized correlation coefficient + * array. Also an output of FLAT. + * + * siUpdPointer (global) - A modulo counter which counts up from + * 0 to OVERHANG-1. + * + * OUTPUTS: + * + * pL_R0History[OVERHANG] - history of the OVERHANG frames worth of + * R(0). + * + * ppL_CorrHistory[OVERHANG][NP+1] - - history of the OVERHANG + * frames worth of pL_UnqntzdCorr[]. + * + * RETURN VALUE: + * + * none + * + *************************************************************************/ + +void updateCNHist(int32_t L_UnqntzdR0, + int32_t *pL_UnqntzdCorr, + int32_t pL_R0History[], + int32_t ppL_CorrHistory[OVERHANG][NP + 1]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* update */ + pL_R0History[siUpdPointer] = L_UnqntzdR0; + + for (i = 0; i < NP + 1; i++) + ppL_CorrHistory[siUpdPointer][i] = pL_UnqntzdCorr[i]; + + siUpdPointer = (siUpdPointer + 1) % OVERHANG; +} + + +/************************************************************************* + * + * FUNCTION NAME: avgGsHistQntz + * + * PURPOSE: + * + * Average gs history, where history is of length OVERHANG-1 + * frames. The last frame's (i.e. this frame) gs values are not + * available since quantization would have occured only after the + * VAD decision is made. + * + * INPUTS: + * + * pL_GsHistory[(OVERHANG-1)*N_SUB] - the GS of the past + * OVERHANG-1 frames. The GS values are stored shifted down by 2 + * shifts to avoid overflow (the largest GS is greater than 2.0). + * + * + * OUTPUTS: + * + * *pL_GsAvgd - the average of pL_GsHistory[], also shifted down + * by two shifts. + * + * RETURN VALUE: + * + * none. + * + * + *************************************************************************/ + +void avgGsHistQntz(int32_t pL_GsHistory[], int32_t *pL_GsAvgd) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + int32_t L_avg; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + L_avg = L_shift_r(pL_GsHistory[0], -(OH_SHIFT + 2)); + + for (i = 1; i < N_SUB * (OVERHANG - 1); i++) + L_avg = L_add(L_shift_r(pL_GsHistory[i], -(OH_SHIFT + 2)), L_avg); + + /* avg number x/32 not x/28 */ + + *pL_GsAvgd = L_add(L_avg, L_mpy_ls(L_avg, 0x1249)); /* L_avg *= 32/28 */ + +} + + +/************************************************************************* + * + * FUNCTION NAME: gsQuant + * + * PURPOSE: + * + * Quantize a value of gs in any of the voicing modes. Input GS + * is a 32 bit number. The GSP0 index is returned. + * + * INPUTS: + * + * L_GsIn - 32 bit GS value, shifted down by 2 shifts. + * + * swVoicingMode - voicing level + * + * ppLr_gsTable[4][32] - Rom GS Table. (global), all GS values + * have been shifted down by 2 from their true value. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * + * GSP0 Index closest to the input value of GS. + * + * + *************************************************************************/ + +int16_t gsQuant(int32_t L_GsIn, int16_t swVoicingMode) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swGsIndex, + swBestGs; + int32_t L_diff, + L_min = LW_MAX; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + for (swGsIndex = 0; swGsIndex < 32; swGsIndex++) + { + L_diff = L_abs(L_sub(L_GsIn, ppLr_gsTable[swVoicingMode][swGsIndex])); + + if (L_sub(L_diff, L_min) < 0) + { + /* new minimum */ + /* ----------- */ + + swBestGs = swGsIndex; + L_min = L_diff; + + } + } + + return (swBestGs); + +} + + +/************************************************************************* + * + * FUNCTION NAME: avgCNHist + * + * PURPOSE: + * + * Average the unquantized R0 and LPC data stored at the encoder + * to arrive at an average R0 and LPC frame for use in a SID + * frame. + * + * INPUTS: + * + * pL_R0History[OVERHANG] - contains unquantized R(0) data from the + * most recent OVERHANG frame (including this one). + * + * ppL_CorrHistory[OVERHANG][NP+1] - Unquantized correlation + * coefficients from the most recent OVERHANG frame (including this + * one). The data stored here is an output of FLAT. + * + * OUTPUTS: + * + * *pL_AvgdR0 - the average of pL_R0History[] + * + * pL_AvgdCorrSeq[NP+1] - the average of ppL_CorrHistory[][]. + * + * + * RETURN VALUE: + * + * none + * + *************************************************************************/ + +void avgCNHist(int32_t pL_R0History[], + int32_t ppL_CorrHistory[OVERHANG][NP + 1], + int32_t *pL_AvgdR0, + int32_t pL_AvgdCorrSeq[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i, + j; + int32_t L_avg; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* R0 Averaging */ + /* ------------ */ + + for (L_avg = 0, i = 0; i < OVERHANG; i++) + L_avg = L_add(L_shr(pL_R0History[i], OH_SHIFT), L_avg); + + *pL_AvgdR0 = L_avg; + + + /* LPC: average the last OVERHANG frames */ + /* ------------------------------------- */ + + for (j = 0; j < NP + 1; j++) + { + for (L_avg = 0, i = 0; i < OVERHANG; i++) + { + L_avg = L_add(L_shift_r(ppL_CorrHistory[i][j], -OH_SHIFT), L_avg); + } + + pL_AvgdCorrSeq[j] = L_avg; + } + +} + + +/*************************************************************************** + * + * FUNCTION NAME: lpcCorrQntz + * + * PURPOSE: Quantize a correlation sequence + * + * + * INPUT: + * + * pL_CorrelSeq[NP+1] + * Correlation sequence to quantize. + * + * OUTPUTS: + * + * pswFinalRc[0:NP-1] + * A quantized set of NP reflection coefficients. + * + * piVQCodewds[0:2] + * An array containing the indices of the 3 reflection + * coefficient vectors selected from the three segment + * Rc-VQ. + * + * RETURN: + * None. + * + * KEYWORDS: AFLAT,aflat,flat,vectorquantization, reflectioncoefficients + * + *************************************************************************/ + +void lpcCorrQntz(int32_t pL_CorrelSeq[], + int16_t pswFinalRc[], + int piVQCodewds[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t pswPOldSpace[NP_AFLAT], + pswPNewSpace[NP_AFLAT], + pswVOldSpace[2 * NP_AFLAT - 1], + pswVNewSpace[2 * NP_AFLAT - 1], + *ppswPAddrs[2], + *ppswVAddrs[2], + *pswVBar, + pswPBar[NP_AFLAT], + pswVBarSpace[2 * NP_AFLAT - 1], + pswFlatsRc[NP], /* Unquantized Rc's computed by FLAT */ + pswRc[NP + 1]; /* Temp list for the converted RC's */ + int32_t *pL_VBarFull, + pL_PBarFull[NP], + pL_VBarFullSpace[2 * NP - 1]; + + int i, + iVec, + iSeg, + iCnt; /* Loop counter */ + struct QuantList quantList, /* A list of vectors */ + bestPql[4]; /* The four best vectors from + * the PreQ */ + struct QuantList bestQl[LPC_VQ_SEG + 1]; /* Best vectors for each of + * the three segments */ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Setup pointers temporary space */ + /*--------------------------------*/ + + pswVBar = pswVBarSpace + NP_AFLAT - 1; + pL_VBarFull = pL_VBarFullSpace + NP - 1; + ppswPAddrs[0] = pswPOldSpace; + ppswPAddrs[1] = pswPNewSpace; + ppswVAddrs[0] = pswVOldSpace + NP_AFLAT - 1; + ppswVAddrs[1] = pswVNewSpace + NP_AFLAT - 1; + + + /* Set up pL_PBarFull and pL_VBarFull initial conditions, using the */ + /* autocorrelation sequence derived from the optimal reflection */ + /* coefficients computed by FLAT. The initial conditions are shifted */ + /* right by RSHIFT bits. These initial conditions, stored as */ + /* int32_ts, are used to initialize PBar and VBar arrays for the */ + /* next VQ segment. */ + /*--------------------------------------------------------------------*/ + + initPBarFullVBarFullL(pL_CorrelSeq, pL_PBarFull, pL_VBarFull); + + /* Set up initial PBar and VBar initial conditions, using pL_PBarFull */ + /* and pL_VBarFull arrays initialized above. These are the initial */ + /* PBar and VBar conditions to be used by the AFLAT recursion at the */ + /* 1-st Rc-VQ segment. */ + /*--------------------------------------------------------------------*/ + + initPBarVBarL(pL_PBarFull, pswPBar, pswVBar); + + for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++) + { + /* initialize candidate list */ + /*---------------------------*/ + + quantList.iNum = psrPreQSz[iSeg - 1]; + quantList.iRCIndex = 0; + + /* do aflat for all vectors in the list */ + /*--------------------------------------*/ + + setupPreQ(iSeg, quantList.iRCIndex); /* set up vector ptrs */ + + for (iCnt = 0; iCnt < quantList.iNum; iCnt++) + { + /* get a vector */ + /*--------------*/ + + getNextVec(pswRc); + + /* clear the limiter flag */ + /*------------------------*/ + + iLimit = 0; + + /* find the error values for each vector */ + /*---------------------------------------*/ + + quantList.pswPredErr[iCnt] = + aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l], + pswPBar, pswVBar, + ppswPAddrs, ppswVAddrs, + psvqIndex[iSeg - 1].len); + + /* check the limiter flag */ + /*------------------------*/ + + if (iLimit) + quantList.pswPredErr[iCnt] = 0x7fff; /* set error to bad value */ + + } /* done list loop */ + + /* find 4 best prequantizer levels */ + /*---------------------------------*/ + + findBestInQuantList(quantList, 4, bestPql); + + for (iVec = 0; iVec < 4; iVec++) + { + + /* initialize quantizer list */ + /*---------------------------*/ + + quantList.iNum = psrQuantSz[iSeg - 1]; + quantList.iRCIndex = bestPql[iVec].iRCIndex * psrQuantSz[iSeg - 1]; + + setupQuant(iSeg, quantList.iRCIndex); /* set up vector ptrs */ + + /* do aflat recursion on each element of list */ + /*--------------------------------------------*/ + + for (iCnt = 0; iCnt < quantList.iNum; iCnt++) + { + /* get a vector */ + /*--------------*/ + + getNextVec(pswRc); + + /* clear the limiter flag */ + /*------------------------*/ + + iLimit = 0; + + /* find the error values for each vector */ + /*---------------------------------------*/ + + quantList.pswPredErr[iCnt] = + aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l], + pswPBar, pswVBar, + ppswPAddrs, ppswVAddrs, + psvqIndex[iSeg - 1].len); + + /* check the limiter flag */ + /*------------------------*/ + + if (iLimit) + quantList.pswPredErr[iCnt] = 0x7fff; /* set error to the worst + * value */ + + } /* done list loop */ + + /* find best quantizer vector for this segment, and save it */ + /*----------------------------------------------------------*/ + + findBestInQuantList(quantList, 1, bestQl); + if (iVec == 0) + bestQl[iSeg] = bestQl[0]; + else if (sub(bestQl[iSeg].pswPredErr[0], bestQl[0].pswPredErr[0]) > 0) + bestQl[iSeg] = bestQl[0]; + + } + + /* find the quantized reflection coefficients */ + /*--------------------------------------------*/ + + setupQuant(iSeg, bestQl[iSeg].iRCIndex); /* set up vector ptrs */ + getNextVec((int16_t *) (pswFinalRc - 1)); + + + /* Update pBarFull and vBarFull for the next Rc-VQ segment, and */ + /* update the pswPBar and pswVBar for the next Rc-VQ segment */ + /*--------------------------------------------------------------*/ + + if (iSeg < LPC_VQ_SEG) + aflatNewBarRecursionL(&pswFinalRc[psvqIndex[iSeg - 1].l - 1], iSeg, + pL_PBarFull, pL_VBarFull, pswPBar, pswVBar); + + } + + /* find the quantizer index (the values to be output in the symbol file) */ + /*-----------------------------------------------------------------*/ + + for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++) + piVQCodewds[iSeg - 1] = bestQl[iSeg].iRCIndex; + +} + + +/************************************************************************* + * + * FUNCTION NAME: getPnBits + * + * PURPOSE: + * + * Generate iBits pseudo-random bits using *pL_PNSeed as the + * pn-generators seed. + * + * INPUTS: + * + * iBits - integer indicating how many random bits to return. + * range [0,15], 0 yields 1 bit output + * + * *pL_PNSeed - 32 bit seed (changed by function) + * + * OUTPUTS: + * + * *pL_PNSeed - 32 bit seed, modified. + * + * RETURN VALUE: + * + * random bits in iBits LSB's. + * + * + * IMPLEMENTATION: + * + * implementation of x**31 + x**3 + 1 == PN_XOR_REG | PN_XOR_ADD a + * PN sequence generator using int32_ts generating a 2**31 -1 + * length pn-sequence. + * + *************************************************************************/ + +int16_t getPnBits(int iBits, int32_t *pL_PNSeed) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swPnBits = 0; + int32_t L_Taps, + L_FeedBack; + int i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + for (i = 0; i < iBits; i++) + { + /* update the state */ + /* ---------------- */ + + L_Taps = *pL_PNSeed & PN_XOR_REG; + L_FeedBack = L_Taps; /* Xor tap bits to yield + * feedback bit */ + L_Taps = L_shr(L_Taps, 1); + + while (L_Taps) + { + L_FeedBack = L_FeedBack ^ L_Taps; + L_Taps = L_shr(L_Taps, 1); + } + + /* LSB of L_FeedBack is next MSB of PN register */ + + *pL_PNSeed = L_shr(*pL_PNSeed, 1); + if (L_FeedBack & 1) + *pL_PNSeed = *pL_PNSeed | PN_XOR_ADD; + + /* State update complete. Get the output bit from the state, add/or it + * into output */ + + swPnBits = shl(swPnBits, 1); + swPnBits = swPnBits | (extract_l(*pL_PNSeed) & 0x0001); + + } + return (swPnBits); +} + + +/************************************************************************* + * + * FUNCTION NAME: rxInterpR0Lpc + * + * PURPOSE: + * + * Perform part of the comfort noise algorithm at the decoder. + * LPC and R0 are derived in this routine + * + * INPUTS: + * + * pswOldKs - Last frame's reflection coeffs. + * + * pswNewKs - This frame's decoded/received reflection coeffs. + * This will serve a new endpoint in interpolation. + * + * swRxDTXState - primary DTX state variable (at the receiver). A + * modulo 12 counter, which is 0 at SID frame. + * + * swDecoMode - actual mode the decoder: speech decoding mode + * or comfort noise insertion mode (SPEECH = speech decoding; + * CNIFIRSTSID = comfort noise, 1st SID received; CNICONT = comfort + * noise, SID frame received, but not 1st SID; CNIBFI = comfort + * noise, bad frame received) + * + * swFrameType - type of the received frame (VALIDSID, INVALIDSID + * GOODSPEECH or UNUSABLE) + * + * swOldR0Dec - global variable, the decoded R0 value from the last + * frame . This will be modified. + * + * swR0NewCN - global variable the decoded R0 value from the frame + * just received. Valid information if current frame is a SID frame. + * + * + * OUTPUTS: + * + * pswNewKs - This frames LPC coeffs. modified to reflect + * interpolated correlation sequence pL_CorrSeq[]. + * + * swR0Dec - global variable, interpolated R0 value + * + * swR0OldCN - global variable, R0 interpolation point to + * interpolate from. + * + * swR0NewCN - global variable, R0 interpolation point to + * interpolate to. + * + * pL_OldCorrSeq[NP+1] - global variable, starting point for + * interpolation of LPC information. + * + * pL_NewCorrSeq[NP+1] - global variable, end point for + * interpolation of LPC information. + * + * pL_CorrSeq[NP+1] - global variable, interpolated value of LPC + * information to be used in this frame. + * + * + * RETURN VALUE: + * + * None. + * + * KEYWORDS: interpolation, comfort noise, SID, DTX + * + *************************************************************************/ + +void GsmHrDtx::rxInterpR0Lpc(int16_t *pswOldKs, int16_t *pswNewKs, + int16_t swRxDTXState, + int16_t swDecoMode, int16_t swFrameType) +{ + +/*________________________________________________________________________ + | | + | Static Variables | + |________________________________________________________________________| +*/ + + static int16_t swR0OldCN; + static int32_t pL_OldCorrSeq[NP + 1], + pL_NewCorrSeq[NP + 1], + pL_CorrSeq[NP + 1]; + + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + if (swDecoMode == CNIFIRSTSID) + { + /* first SID frame arrived */ + /* ----------------------- */ + + /* use tx'd R0 frame as both endpoints of interp curve. */ + /* i.e. no interpolation for the first frames */ + /* ---------------------------------------------------- */ + + + swR0OldCN = swOldR0Dec; /* last non-SID, received R0 */ + swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState); + + + /* generate the LPC end points for interpolation */ + /* --------------------------------------------- */ + + rcToCorrDpL(ASHIFT, ASCALE, pswOldKs, pL_OldCorrSeq); + rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, pL_NewCorrSeq); + + /* linearly interpolate between the two sets of correlation coefs */ + /* -------------------------------------------------------------- */ + + for (i = 0; i < NP + 1; i++) + { + pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i], + swRxDTXState); + } + + /* Generate this frames K's (overwrite input) */ + /* ------------------------------------------ */ + + aFlatRcDp(pL_CorrSeq, pswNewKs); + + } + else if ((swDecoMode == CNICONT) && (swFrameType == VALIDSID)) + { + /* new (not the first) SID frame arrived */ + /* ------------------------------------- */ + + swR0OldCN = swOldR0Dec; /* move current state of R0 to old */ + swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState); + + + /* LPC: generate new endpoints for interpolation */ + /* --------------------------------------------- */ + + for (i = 0; i < NP + 1; i++) + { + pL_OldCorrSeq[i] = pL_CorrSeq[i]; + } + + rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, pL_NewCorrSeq); + + + /* linearly interpolate between the two sets of correlation coefs */ + /* -------------------------------------------------------------- */ + + for (i = 0; i < NP + 1; i++) + { + pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i], + swRxDTXState); + } + + + /* Use interpolated LPC for this frame, overwrite the input K's */ + /* ------------------------------------------------------------ */ + + aFlatRcDp(pL_CorrSeq, pswNewKs); + + } + else + { + /* in between SID frames / invalid SID frames */ + /* ------------------------------------------ */ + + swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState); + + + /* linearly interpolate between the two sets of correlation coefs */ + /* -------------------------------------------------------------- */ + + for (i = 0; i < NP + 1; i++) + { + pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i], + swRxDTXState); + } + + + /* Use interpolated LPC for this frame, overwrite the input K's */ + /* ------------------------------------------------------------ */ + + aFlatRcDp(pL_CorrSeq, pswNewKs); + + } +} + + +/************************************************************************* + * + * FUNCTION NAME: linInterpSid + * + * PURPOSE: + * + * Linearly interpolate between two input numbers based on what the + * current DtxState is. + * + * INPUTS: + * + * L_New - int32_t more current value + * + * L_Old - int32_t oldest value + * + * swDtxState - state is 0 at the transmitted SID Frame. + * + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * A value between old and new inputs with dtxState+1/12 of the new + * (dtxState+1)-12/12 of the old + * + * + *************************************************************************/ + +int32_t linInterpSid(int32_t L_New, int32_t L_Old, int16_t swDtxState) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swOldFactor; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* old factor = (1.0 - newFactor) */ + /* ------------------------------ */ + + swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]); + swOldFactor = add(0x1, swOldFactor); + + + /* contributions from new and old */ + /* ------------------------------ */ + + L_New = L_mpy_ls(L_New, psrCNNewFactor[swDtxState]); + L_Old = L_mpy_ls(L_Old, swOldFactor); + + return (L_add(L_New, L_Old)); + +} + + +/************************************************************************* + * + * FUNCTION NAME: linInterpSidShort + * + * PURPOSE: + * + * Linearly interpolate between two input numbers based on what + * the current DtxState is. + * + * INPUTS: + * + * swNew - 16 bit, more current value + * + * swOld - 16 bit, oldest value + * + * swDtxState - state is 0 at the transmitted SID Frame. + * + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * A value between old and new inputs with dtxState+1/12 of the new + * (dtxState+1)-12/12 of the old + * + *************************************************************************/ + +int16_t linInterpSidShort(int16_t swNew, int16_t swOld, + int16_t swDtxState) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swOldFactor; + int32_t L_New, + L_Old; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* old factor = (1.0 - newFactor) */ + /* ------------------------------ */ + + swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]); + swOldFactor = add(0x1, swOldFactor); + + + /* contributions from new and old */ + /* ------------------------------ */ + + L_New = L_mult(swNew, psrCNNewFactor[swDtxState]); + L_Old = L_mult(swOld, swOldFactor); + + + return (round(L_add(L_New, L_Old))); + +} diff --git a/src/libs/gsmhr/gsmhr_dtx.h b/src/libs/gsmhr/gsmhr_dtx.h new file mode 100644 index 00000000..9e565693 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_dtx.h @@ -0,0 +1,62 @@ +#ifndef __DTX +#define __DTX + +#include "typedefs.h" + + +#define PN_INIT_SEED (int32_t)0x1091988L /* initial seed for Comfort + * noise pn-generator */ + +#define CNINTPER 12 /* inperpolation period of CN + * parameters */ + +#define SPEECH 1 +#define CNIFIRSTSID 2 +#define CNICONT 3 +#define CNIBFI 4 + +#define VALIDSID 11 +#define INVALIDSID 22 +#define GOODSPEECH 33 +#define UNUSABLE 44 + +/*________________________________________________________________________ + | | + | Function Prototypes | + |________________________________________________________________________| +*/ + +void avgCNHist(int32_t pL_R0History[], + int32_t ppL_CorrHistory[OVERHANG][NP + 1], + int32_t *pL_AvgdR0, + int32_t pL_AvgdCorrSeq[]); + + void avgGsHistQntz(int32_t pL_GsHistory[], int32_t *pL_GsAvgd); + + int16_t swComfortNoise(int16_t swVadFlag, + int32_t L_UnqntzdR0, int32_t *pL_UnqntzdCorr); + + int16_t getPnBits(int iBits, int32_t *L_PnSeed); + + int16_t gsQuant(int32_t L_GsIn, int16_t swVoicingMode); + + void updateCNHist(int32_t L_UnqntzdR0, + int32_t *pL_UnqntzdCorr, + int32_t pL_R0Hist[], + int32_t ppL_CorrHist[OVERHANG][NP + 1]); + + void lpcCorrQntz(int32_t pL_CorrelSeq[], + int16_t pswFinalRc[], + int piVQCodewds[]); + + int32_t linInterpSid(int32_t L_New, int32_t L_Old, int16_t swDtxState); + + int16_t linInterpSidShort(int16_t swNew, + int16_t swOld, + int16_t swDtxState); + + void rxInterpR0Lpc(int16_t *pswOldKs, int16_t *pswNewKs, + int16_t swRxDTXState, + int16_t swDecoMode, int16_t swFrameType); + +#endif diff --git a/src/libs/gsmhr/gsmhr_gsm_hr.c b/src/libs/gsmhr/gsmhr_gsm_hr.c new file mode 100644 index 00000000..e72e20a1 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_gsm_hr.c @@ -0,0 +1,480 @@ +/************************************************************************** + * + * File Name: gsm_hr.c + * + * Purpose: + * + * This file contains the main routine for the GSM Half Rate speech + * codec. The code for the speech coder, including the VAD, DTX, + * Comfort Noise, bad frame handling (error concealment), and codec + * homing functions is in the files listed below: + * + * gsm_hr.c globdefs.c homing.c host.c + * mathdp31.c mathhalf.c sp_dec.c sp_enc.c + * sp_frm.c sp_rom.c sp_sfrm.c vad.c + * dtx.c err_conc.c + * + * This particular file only has the level 0, main(), and all level + * 1, main()'s daughter functions, in it. + * + * Details on how to run gsm_hr are in the readme.txt file. + * + * Below is a listing of all the functions appearing in the file. + * The ordering is hierarchical. + * + * main() "gsm_hr", main program. + * encode() - encodes a speech file, outputs an encoded parameter file + * decode() - decodes a parameter file, outputs a decoded speech file + * + **************************************************************************/ + +/*_________________________________________________________________________ + | | + | Include Files | + |_________________________________________________________________________| +*/ + +#include +#include +#include +#include + +#include "gsmhr_gsm_hr.h" +#include "gsmhr_homing.h" +#include "gsmhr_host.h" +#include "gsmhr_sp_dec.h" +#include "gsmhr_sp_enc.h" +#include "gsmhr_typedefs.h" + +/**************************************************************************** + * + * PROGRAM NAME: gsm_hr + * + * PURPOSE: + * gsm_hr - main program for the GSM Half-Rate speech coder. + * Allows running one of the following operational modes: + * 0. Encoder only with speech input / encoded parameter data output. + * 1. Decoder only with speech parameter data input / speech output. + * + * INPUT: + * inputFileName 0. speech file in 8 kHz, pcm format. + * 1. speech parameter file in decoder input format. + * - number of frames to be processed (optional). + * - switch to enable/disable the DTX functions. + * + * OUTPUT: + * outputFileName 0. encoded paramter output file. + * 1. synthesized speech file in 8 kHz, pcm format. + * + * RETURN: + * none + * + * REFERENCES: Sub-clause 4.0 of GSM Recomendation 06.20 + * + * KEYWORDS: main, gsm_hr, speech codec, top level + * + ***************************************************************************/ + +int main(int argc, char *argv[]) +{ + +/*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| +*/ + +#define DEFAULT_NUMFRAMES 32766 + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int iDoneFrm, + iMaxNumFrms, + option, + i; + + FILE *pfileInFile, + *pfileOutFile; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* check command line arguments */ + /* ---------------------------- */ + + iMaxNumFrms = DEFAULT_NUMFRAMES; + giDTXon = 1; + + /* check command line arguments */ + /* ---------------------------- */ + + switch (argc) + { + case 4: + + break; + + case 5: + case 6: + + for (i = 4; i < argc; i++) + { + if (!strcmp(argv[i], "dtx")) + giDTXon = 1; + else if (!strcmp(argv[i], "nodtx")) + giDTXon = 0; + else if ((iMaxNumFrms = atoi(argv[i])) <= 0) + { + printf("invalid number of frames or wrong DTX switch, %s", argv[i]); + exit(1); + } + } + break; + + default: + + printf("\n\nUsage:\n\n"); + printf("gsm_hr option inputFileName outputFileName "); + printf(" \n"); + printf(" or\n"); + printf("gsm_hr option inputFileName outputFileName "); + printf(" \n"); + printf("\nOptions: "); + printf("enc "); + puts("inputFileName: speech --> outputFileName: encoder output"); + printf(" "); + printf("dec "); + puts("inputFileName: decoder input --> outputFileName: speech"); + printf("\n"); + exit(1); + } + + /* check encoding and decoding options */ + /* ----------------------------------- */ + + if (!strcmp(argv[1], "enc")) + option = 0; + else if (!strcmp(argv[1], "dec")) + option = 1; + else + { + printf("error in option selection\n"); + printf(" Your entry : %s \n", argv[1]); + printf("\n\nUsage:\n\n"); + printf("gsm_hr option inputFileName outputFileName "); + printf(" \n"); + printf(" or\n"); + printf("gsm_hr option inputFileName outputFileName "); + printf(" \n"); + printf("\nOptions: "); + printf("enc "); + puts("inputFileName: speech --> outputFileName: encoder output"); + printf(" "); + printf("dec "); + puts("inputFileName: decoder input --> outputFileName: speech"); + printf("\n"); + exit(1); + } + + + /* open the input and output files */ + /* ------------------------------- */ + +#ifdef VAX + pfileInFile = fopen(argv[2], "rb", "mrs=2", "rfm=fix", "ctx=stm"); + pfileOutFile = fopen(argv[3], "wb", "mrs=2", "rfm=fix", "ctx=stm"); +#else + pfileInFile = fopen(argv[2], "rb"); + pfileOutFile = fopen(argv[3], "wb"); +#endif + + if (pfileInFile == NULL) + { + printf("error: can not open file %s\n", argv[2]); + exit(1); + } + if (pfileOutFile == NULL) + { + printf("error: can not open file %s\n", argv[3]); + exit(1); + } + + puts("\n\n"); + puts(" ****************************************"); + puts(" * *"); + puts(" * GSM Half-Rate Speech Coder *"); + puts(" * *"); + puts(" * *"); + printf(" * %s *\n", VERSION); + printf(" * %s *\n", DATE); + puts(" * *"); + puts(" ****************************************"); + puts("\n"); + + + printf("option: "); + + switch (option) + { + case 0: + puts("enc (speech encoder)"); + break; + case 1: + puts("dec (speech decoder)"); + break; + default: + puts("invalid option"); + exit(1); + } + + if (giDTXon) + printf("DTX mode: enabled\n"); + else + printf("DTX mode: disabled\n"); + + printf("input file: %s\n", argv[2]); + printf("output file: %s\n\n", argv[3]); + + + switch (option) + { + case 0: /* encode */ + + /* start the encoder, VAD, and transmit DTX in the home state */ + /* ---------------------------------------------------------- */ + + resetEnc(); + + /* encode: analyze 8 kHz speech and output encoded parameter file */ + /* --------------------------------------------------------------- */ + + for (giFrmCnt = 1, iDoneFrm = 0; + !iDoneFrm && giFrmCnt <= iMaxNumFrms; + giFrmCnt++) + { + +#ifndef SILENT + printf("encoding frame %d \r", giFrmCnt); +#endif + + if (encode(pfileInFile, pfileOutFile)) + iDoneFrm = 1; + } + + if (iDoneFrm) + giFrmCnt--; + + printf(" %d speech frames encoded\n", giFrmCnt - 1); + break; + + case 1: /* decode */ + + /* start the decoder and receive DTX in the home state */ + /* --------------------------------------------------- */ + + resetDec(); + + /* decode: synthesize speech */ + /* -------------------------- */ + + for (giFrmCnt = 1, iDoneFrm = 0; + !iDoneFrm && giFrmCnt <= iMaxNumFrms; + giFrmCnt++) + { + +#ifndef SILENT + printf("decoding frame %d \r", giFrmCnt); +#endif + + if (decode(pfileInFile, pfileOutFile)) + iDoneFrm = 1; + } + + if (iDoneFrm) + giFrmCnt--; + + printf(" %d speech frames decoded\n", giFrmCnt - 1); + break; + } + + fclose(pfileInFile); + fclose(pfileOutFile); + + return (0); +} + +/************************************************************************** + * + * FUNCTION NAME: decode + * + * PURPOSE: + * Reads in one frame of speech parameters and outputs one frame of + * synthesized speech. Resets the decoder to the home state if the + * Decoder Homing Frame pattern is detected. + * + * INPUT: + * pfileDec speech parameter input file. + * + * OUTPUT: + * pfileSpeechOut synthesized speech file + * + * RETURN: + * 0 successfully synthesized a complete frame of speech + * 1 failed to synthesize a complete frame of speech + * + * REFERENCES: Sub-clause 4.2 of GSM Recomendation 06.20 + * + * KEYWORDS: + * pfileDec, pfileSpeechOut + **************************************************************************/ + +int decode(FILE *pfileDec, FILE *pfileSpeechOut) +{ + +/*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| +*/ + +/* These constants define the number of consecutive */ +/* parameters that decoderHomingFrameTest checks. */ +/* -------------------------------------------------*/ + +#define WHOLE_FRAME 18 +#define TO_FIRST_SUBFRAME 9 + +/*_________________________________________________________________________ + | | + | Static Variables | + |_________________________________________________________________________| +*/ + static int16_t pswSpeechPara[22], + pswDecodedSpeechFrame[F_LEN]; + + static int reset_flag_decoder_old = 1; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int i, + reset_flag_decoder; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + if (readDecfile(pfileDec, pswSpeechPara)) + return (1); + + if(reset_flag_decoder_old) + reset_flag_decoder=decoderHomingFrameTest(pswSpeechPara, + TO_FIRST_SUBFRAME); + else + reset_flag_decoder=0; + + if (reset_flag_decoder && reset_flag_decoder_old) + { + /* force the output to be the encoder homing frame pattern */ + + for (i = 0; i < F_LEN; i++) + pswDecodedSpeechFrame[i] = EHF_MASK; + } + else + { + speechDecoder(pswSpeechPara, pswDecodedSpeechFrame); + } + + speechDecoderHostInterface(pswDecodedSpeechFrame, pfileSpeechOut); + + if(!reset_flag_decoder_old) + reset_flag_decoder=decoderHomingFrameTest(pswSpeechPara, WHOLE_FRAME); + + if (reset_flag_decoder) + resetDec(); /* bring the decoder and receive DTX + * to the home state */ + + reset_flag_decoder_old = reset_flag_decoder; + + return (0); +} + +/************************************************************************** + * + * FUNCTION NAME: encode + * + * PURPOSE: + * Reads in one frame of speech samples and outputs one frame of + * speech parameters. Resets the encoder to the home state if the + * Encoder Homing Frame pattern is detected. + * + * INPUT: + * pfileSpeechIn speech file + * + * OUTPUT: + * pfileEnc speech, encoded paramater data + * + * RETURN: + * 0 successfully wrote a complete frame of data + * 1 failed to write a complete frame of data + * + * REFERENCES: Sub-clause 4.1 of GSM Recomendation 06.20 + * + * KEYWORDS: + * pfileSpeechIn, pfileEnc + **************************************************************************/ + +int encode(FILE *pfileSpeechIn, FILE *pfileEnc) +{ + +/*_________________________________________________________________________ + | | + | Static Variables | + |_________________________________________________________________________| +*/ + static int16_t pswSpeechPara[20]; + static int16_t pswSpeechBuff[F_LEN]; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int iNumRead, + reset_flag; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + iNumRead = hostEncoderInterface(pfileSpeechIn, F_LEN, &pswSpeechBuff[0]); + + if (iNumRead < F_LEN) + return (1); + + reset_flag = encoderHomingFrameTest(&pswSpeechBuff[0]); + + speechEncoder(&pswSpeechBuff[0], pswSpeechPara); + + if (writeEncfile(pswSpeechPara, pfileEnc) != 20) + return (1); + + if (reset_flag) + resetEnc(); /* Bring the encoder, VAD, and DTX to + * the home state */ + + return (0); +} diff --git a/src/libs/gsmhr/gsmhr_gsm_hr.h b/src/libs/gsmhr/gsmhr_gsm_hr.h new file mode 100644 index 00000000..46dec512 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_gsm_hr.h @@ -0,0 +1,15 @@ +#ifndef __GSM_HR +#define __GSM_HR + +#include + +/*_________________________________________________________________________ + | | + | Function Prototypes | + |_________________________________________________________________________| +*/ + +int encode(FILE *pfileSpeechIn, FILE *pfileEnc); +int decode(FILE *pfileDec, FILE *pfileSpeechOut); + +#endif diff --git a/src/libs/gsmhr/gsmhr_homing.c b/src/libs/gsmhr/gsmhr_homing.c new file mode 100644 index 00000000..c3076ed1 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_homing.c @@ -0,0 +1,648 @@ +/************************************************************************** + * + * File Name: homing.c + * + * Purpose: + * This file contains the following functions: + * + * decoderHomingFrameTest() - checks if a frame of input speech + * parameters matches the Decoder Homing + * Frame pattern. + * + * decoderReset() - called by resetDec() to reset all of the state + * variables for the decoder + * + * encoderHomingFrameTest() - checks if a frame of input samples + * matches the Encoder Homing Frame pattern. + * + * encoderReset() - called by resetEnc() to reset all the state + * variables for the encoder. + * + * resetDec() - calls functions to reset the state variables for the + * decoder, and for the receive DTX and Comfort Noise. + * + * resetEnc() - calls functions to reset the state variables for the + * encoder and VAD, and for the transmit DTX and + * Comfort Noise. + * + * dtxResetTx() - called by resetEnc() to reset all of the transmit + * DTX and Comfort Noise state variables + * + * dtxResetRx() - called by resetDec() to reset all of the receive + * DTX and Comfort Noise state variables + * + **************************************************************************/ + +/*_________________________________________________________________________ + | | + | Include Files | + |_________________________________________________________________________| +*/ + +#include "typedefs.h" +#include "vad.h" +#include "dtx.h" +#include "homing.h" + +/*_________________________________________________________________________ + | | + | Local Defines | + |_________________________________________________________________________| +*/ + +#define EHF_MASK 0x0008 /* Encoder Homing Frame pattern */ +#define LMAX 142 /* largest lag (integer sense) */ +#define CG_INT_MACS 6 /* Number of multiply-accumulates in + * one interpolation */ +#define NUM_CLOSED 3 /* maximum number of lags searched */ +#define LPCSTARTINDEX 25 /* where the LPC analysis window + * starts */ +#define INBUFFSZ LPCSTARTINDEX + A_LEN /* input buffer size */ + + +#define LTP_LEN 147 /* maximum ltp lag */ +#define LSMAX (LMAX + CG_INT_MACS/2) +#define HNW_BUFF_LEN LSMAX + + +/*************************************************************************** + * + * FUNCTION NAME: decoderHomingFrameTest + * + * PURPOSE: + * Checks if a frame of input speech parameters matches the Decoder + * Homing Frame pattern, which is: + * + * parameter decimal value hexidecimal value + * --------- ------------- ----------------- + * R0 0 0x0000 + * LPC1 881 0x0371 + * LPC2 350 0x015E + * LPC3 195 0x00c3 + * INT_LPC 1 0x0001 + * MODE 0 0x0000 + * CODE1_1 71 0x0047 + * CODE2_1 74 0x004a + * GSP0_1 0 0x0000 + * CODE1_2 9 0x0009 + * CODE2_2 38 0x0026 + * GSP0_2 7 0x0007 + * CODE1_3 0 0x0000 + * CODE2_3 0 0x0000 + * GSP0_3 0 0x0000 + * CODE1_4 0 0x0000 + * CODE2_4 0 0x0000 + * GSP0_4 0 0x0000 + * + * INPUT: + * pswSpeechPara[] - one frame of speech parameters + * in decoder input format + * + * iLastPara - the number of consecutive parameters in + * pswSpeechPara[] to match. + * + * OUTPUT: + * None + * + * RETURN: + * 0 input frame does not match the Decoder Homing Frame pattern. + * 1 input frame matches the Decoder Homing Frame pattern. + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + * pswSpeechPara + **************************************************************************/ + +int decoderHomingFrameTest(Shortword pswSpeechPara[], int iLastPara) +{ + /* the n[] array contains the number of bits in each speech parameter */ + static int n[] = {5, 11, 9, 8, 1, 2, 7, 7, 5, 7, 7, 5, 7, 7, 5, 7, 7, 5}; + + static Shortword dhf_mask[] = + { + 0x0000, /* R0 */ + 0x0371, /* LPC1 */ + 0x015E, /* LPC2 */ + 0x00c3, /* LPC3 */ + 0x0001, /* INT_LPC */ + 0x0000, /* MODE */ + 0x0047, /* CODE1_1 */ + 0x004a, /* CODE2_1 */ + 0x0000, /* GSP0_1 */ + 0x0009, /* CODE1_2 */ + 0x0026, /* CODE2_2 */ + 0x0007, /* GSP0_2 */ + 0x0000, /* CODE1_3 */ + 0x0000, /* CODE2_3 */ + 0x0000, /* GSP0_3 */ + 0x0000, /* CODE1_4 */ + 0x0000, /* CODE2_4 */ + 0x0000 /* GSP0_4 */ + }; + + int i; + int j; + + for (i = 0; i < iLastPara; i++) + { + j = ((pswSpeechPara[i] & ~(~0 << n[i])) ^ dhf_mask[i]); + if (j) + break; + } + + return !j; +} + + +/*************************************************************************** + * + * FUNCTION NAME: decoderReset + * + * PURPOSE: + * resets all of the state variables for the decoder + * + * INPUT: + * None + * + * OUTPUT: + * None + * + * RETURN: + * None + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + **************************************************************************/ + +void decoderReset(void) +{ +/*_________________________________________________________________________ + | | + | External declarations for decoder variables which need to be reset | + |_________________________________________________________________________| +*/ + + /* variables defined in sp_dec.c */ + /* ----------------------------- */ + + extern Shortword gswPostFiltAgcGain, + gpswPostFiltStateNum[NP], + gpswPostFiltStateDenom[NP], + swPostEmphasisState, + pswSynthFiltState[NP], + pswOldFrmKsDec[NP], + pswOldFrmAsDec[NP], + pswOldFrmPFNum[NP], + pswOldFrmPFDenom[NP], + swOldR0Dec, + pswLtpStateBaseDec[LTP_LEN + S_LEN], + pswPPreState[LTP_LEN + S_LEN]; + + extern Shortword swMuteFlagOld; /* error concealment */ + + + /* variables defined in err_conc.c *//* error concealment */ + /* ------------------------------- *//* error concealment */ + + extern Longword plSubfrEnergyMem[4]; /* error concealment */ + extern Shortword swLevelMem[4], + lastR0, /* error concealment */ + pswLastGood[18], /* error concealment */ + swState, + swLastFlag; /* error concealment */ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + +/*_________________________________________________________________________ + | | + | Executable code | + |_________________________________________________________________________| +*/ + + /* reset all the decoder state variables */ + /* ------------------------------------- */ + + swOldR0Dec = 0; + + gswPostFiltAgcGain = 0; + + swPostEmphasisState = 0; + + for (i = 0; i < NP; i++) + { + gpswPostFiltStateNum[i] = 0; + gpswPostFiltStateDenom[i] = 0; + pswSynthFiltState[i] = 0; + pswOldFrmKsDec[i] = 0; + pswOldFrmAsDec[i] = 0; + pswOldFrmPFNum[i] = 0; + pswOldFrmPFDenom[i] = 0; + } + + for (i = 0; i < (LTP_LEN + S_LEN); i++) + { + pswLtpStateBaseDec[i] = 0; + pswPPreState[i] = 0; + } + + + /* reset all the error concealment state variables */ + /* ----------------------------------------------- */ + + swMuteFlagOld = 0; + + lastR0 = 0; + swState = 7; + swLastFlag = 0; + for (i = 0; i < 3; i++) + { + plSubfrEnergyMem[i] = 80; + swLevelMem[i] = -72; + } + for (i = 0; i < 18; i++) + { + pswLastGood[i] = 0; + } + + +} + +/*************************************************************************** + * + * FUNCTION NAME: encoderHomingFrameTest + * + * PURPOSE: + * Checks if a frame of input samples matches the Encoder Homing Frame + * pattern, which is 0x0008 for all 160 samples in the frame. + * + * INPUT: + * pswSpeech[] one frame of speech samples + * + * OUTPUT: + * None + * + * RETURN: + * 0 input frame does not match the Encoder Homing Frame pattern. + * 1 input frame matches the Encoder Homing Frame pattern. + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + * pswSpeech + **************************************************************************/ + +int encoderHomingFrameTest(Shortword pswSpeech[]) +{ + int i; + Shortword j; + + for (i = 0; i < F_LEN; i++) + { + j = pswSpeech[i] ^ EHF_MASK; + if (j) + break; + } + + return !j; +} + +/*************************************************************************** + * + * FUNCTION NAME: encoderReset + * + * PURPOSE: + * resets all of the state variables for the encoder + * + * INPUT: + * None + * + * OUTPUT: + * None + * + * RETURN: + * None + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + **************************************************************************/ + +void encoderReset(void) +{ + +/*_________________________________________________________________________ + | | + | External declarations for encoder variables which need to be reset | + |_________________________________________________________________________| +*/ + + /* variables defined in sp_enc.c */ + /* ----------------------------- */ + + extern Shortword swOldR0; + extern Shortword swOldR0Index; + + extern struct NormSw psnsWSfrmEngSpace[]; + + extern Shortword pswHPFXState[]; + extern Shortword pswHPFYState[]; + extern Shortword pswOldFrmKs[]; + extern Shortword pswOldFrmAs[]; + extern Shortword pswOldFrmSNWCoefs[]; + extern Shortword pswWgtSpeechSpace[]; + + extern Shortword pswSpeech[]; /* input speech */ + + extern Shortword swPtch; + + + /* variables defined in sp_frm.c */ + /* ----------------------------- */ + + extern Shortword pswAnalysisState[NP]; + + extern Shortword pswWStateNum[NP], + pswWStateDenom[NP]; + + + /* variables defined in sp_sfrm.c */ + /* ------------------------------ */ + + extern Shortword pswLtpStateBase[LTP_LEN + S_LEN]; + extern Shortword pswHState[NP]; + extern Shortword pswHNWState[HNW_BUFF_LEN]; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + +/*_________________________________________________________________________ + | | + | Executable code | + |_________________________________________________________________________| +*/ + + /* reset all the encoder state variables */ + /* ------------------------------------- */ + + swOldR0Index = 0; + swOldR0 = 0; + + for (i = 0; i < 2 * N_SUB; i++) + { + psnsWSfrmEngSpace[i].man = 0; + psnsWSfrmEngSpace[i].sh = 0; + } + + for (i = 0; i < 4; i++) + pswHPFXState[i] = 0; + + for (i = 0; i < 8; i++) + pswHPFYState[i] = 0; + + for (i = 0; i < NP; i++) + { + pswOldFrmKs[i] = 0; + pswOldFrmAs[i] = 0; + pswOldFrmSNWCoefs[i] = 0; + pswAnalysisState[i] = 0; + pswWStateNum[i] = 0; + pswWStateDenom[i] = 0; + pswHState[i] = 0; + } + + for (i = 0; i < (F_LEN + LMAX + CG_INT_MACS / 2); i++) + pswWgtSpeechSpace[i] = 0; + + for (i = 0; i < INBUFFSZ; i++) + pswSpeech[i] = 0; + + for (i = 0; i < (LTP_LEN + S_LEN); i++) + pswLtpStateBase[i] = 0; + + for (i = 0; i < HNW_BUFF_LEN; i++) + pswHNWState[i] = 0; + + swPtch = 1; +} + +/*************************************************************************** + * + * FUNCTION NAME: resetDec + * + * PURPOSE: + * resets all of the state variables for the decoder, and for the + * receive DTX and Comfort Noise. + * + * INPUT: + * None + * + * OUTPUT: + * None + * + * RETURN: + * None + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + **************************************************************************/ + +void resetDec(void) +{ + decoderReset(); /* reset all the state variables in + * the speech decoder */ + dtxResetRx(); /* reset all the receive DTX and CN + * state variables */ +} + +/*************************************************************************** + * + * FUNCTION NAME: resetEnc + * + * PURPOSE: + * resets all of the state variables for the encoder and VAD, and for + * the transmit DTX and Comfort Noise. + * + * INPUT: + * None + * + * OUTPUT: + * None + * + * RETURN: + * None + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + **************************************************************************/ + +void resetEnc(void) +{ + + encoderReset(); /* reset all the state variables in + * the speech encoder */ + vad_reset(); /* reset all the VAD state variables */ + + dtxResetTx(); /* reset all the transmit DTX and CN + * state variables */ +} + +/*************************************************************************** + * + * FUNCTION NAME: dtxResetTx + * + * PURPOSE: + * reset all the transmit DTX and CN state variables + * + * INPUT: + * None + * + * OUTPUT: + * None + * + * RETURN: + * None + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + **************************************************************************/ + +void dtxResetTx(void) +{ + +/*_________________________________________________________________________ + | | + | External declarations for encoder variables which need to be reset | + |_________________________________________________________________________| +*/ + + /* variables defined in sp_enc.c */ + /* ----------------------------- */ + + extern Shortword swTxGsHistPtr; + + + /* variables defined in dtx.c */ + /* -------------------------- */ + + extern Shortword swVadFrmCnt; /* Indicates the number of sequential + * frames where VAD == 0 */ + extern short int siUpdPointer; + extern Shortword swNElapsed; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + +/*_________________________________________________________________________ + | | + | Executable code | + |_________________________________________________________________________| +*/ + + /* reset all the transmit DTX and CN state variables */ + /* ------------------------------------------------- */ + + swTxGsHistPtr = 0; + + swVadFrmCnt = 0; + + siUpdPointer = 0; + + swNElapsed = 50; + +} + +/*************************************************************************** + * + * FUNCTION NAME: dtxResetRx + * + * PURPOSE: + * reset all the receive DTX and CN state variables + * + * INPUT: + * None + * + * OUTPUT: + * None + * + * RETURN: + * None + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + **************************************************************************/ + +void dtxResetRx(void) +{ + +/*_________________________________________________________________________ + | | + | External declarations for encoder variables which need to be reset | + |_________________________________________________________________________| +*/ + + /* variables defined in sp_dec.c */ + /* ----------------------------- */ + + extern Shortword swRxDTXState; + extern Shortword swDecoMode; + extern Shortword swDtxMuting; + extern Shortword swDtxBfiCnt; + + extern Shortword swOldR0IndexDec; + + extern Shortword swRxGsHistPtr; + extern Longword pL_RxGsHist[(OVERHANG - 1) * N_SUB]; + + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + + +/*_________________________________________________________________________ + | | + | Executable code | + |_________________________________________________________________________| +*/ + + /* reset all the receive DTX and CN state variables */ + /* ------------------------------------------------ */ + + swRxDTXState = CNINTPER - 1; + swDecoMode = SPEECH; + swDtxMuting = 0; + swDtxBfiCnt = 0; + + swOldR0IndexDec = 0; + + swRxGsHistPtr = 0; + + for (i = 0; i < (OVERHANG - 1) * N_SUB; i++) + pL_RxGsHist[i] = 0; + +} diff --git a/src/libs/gsmhr/gsmhr_homing.cpp b/src/libs/gsmhr/gsmhr_homing.cpp new file mode 100644 index 00000000..a371baf1 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_homing.cpp @@ -0,0 +1,648 @@ +/************************************************************************** + * + * File Name: homing.c + * + * Purpose: + * This file contains the following functions: + * + * decoderHomingFrameTest() - checks if a frame of input speech + * parameters matches the Decoder Homing + * Frame pattern. + * + * decoderReset() - called by resetDec() to reset all of the state + * variables for the decoder + * + * encoderHomingFrameTest() - checks if a frame of input samples + * matches the Encoder Homing Frame pattern. + * + * encoderReset() - called by resetEnc() to reset all the state + * variables for the encoder. + * + * resetDec() - calls functions to reset the state variables for the + * decoder, and for the receive DTX and Comfort Noise. + * + * resetEnc() - calls functions to reset the state variables for the + * encoder and VAD, and for the transmit DTX and + * Comfort Noise. + * + * dtxResetTx() - called by resetEnc() to reset all of the transmit + * DTX and Comfort Noise state variables + * + * dtxResetRx() - called by resetDec() to reset all of the receive + * DTX and Comfort Noise state variables + * + **************************************************************************/ + +/*_________________________________________________________________________ + | | + | Include Files | + |_________________________________________________________________________| +*/ + +#include "gsmhr_typedefs.h" +#include "gsmhr_vad.h" +#include "gsmhr_dtx.h" +#include "gsmhr_homing.h" + +/*_________________________________________________________________________ + | | + | Local Defines | + |_________________________________________________________________________| +*/ + +#define EHF_MASK 0x0008 /* Encoder Homing Frame pattern */ +#define LMAX 142 /* largest lag (integer sense) */ +#define CG_INT_MACS 6 /* Number of multiply-accumulates in + * one interpolation */ +#define NUM_CLOSED 3 /* maximum number of lags searched */ +#define LPCSTARTINDEX 25 /* where the LPC analysis window + * starts */ +#define INBUFFSZ LPCSTARTINDEX + A_LEN /* input buffer size */ + + +#define LTP_LEN 147 /* maximum ltp lag */ +#define LSMAX (LMAX + CG_INT_MACS/2) +#define HNW_BUFF_LEN LSMAX + + +/*************************************************************************** + * + * FUNCTION NAME: decoderHomingFrameTest + * + * PURPOSE: + * Checks if a frame of input speech parameters matches the Decoder + * Homing Frame pattern, which is: + * + * parameter decimal value hexidecimal value + * --------- ------------- ----------------- + * R0 0 0x0000 + * LPC1 881 0x0371 + * LPC2 350 0x015E + * LPC3 195 0x00c3 + * INT_LPC 1 0x0001 + * MODE 0 0x0000 + * CODE1_1 71 0x0047 + * CODE2_1 74 0x004a + * GSP0_1 0 0x0000 + * CODE1_2 9 0x0009 + * CODE2_2 38 0x0026 + * GSP0_2 7 0x0007 + * CODE1_3 0 0x0000 + * CODE2_3 0 0x0000 + * GSP0_3 0 0x0000 + * CODE1_4 0 0x0000 + * CODE2_4 0 0x0000 + * GSP0_4 0 0x0000 + * + * INPUT: + * pswSpeechPara[] - one frame of speech parameters + * in decoder input format + * + * iLastPara - the number of consecutive parameters in + * pswSpeechPara[] to match. + * + * OUTPUT: + * None + * + * RETURN: + * 0 input frame does not match the Decoder Homing Frame pattern. + * 1 input frame matches the Decoder Homing Frame pattern. + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + * pswSpeechPara + **************************************************************************/ + +int GsmHrCodec::decoderHomingFrameTest(int16_t pswSpeechPara[], int iLastPara) +{ + /* the n[] array contains the number of bits in each speech parameter */ + static int n[] = {5, 11, 9, 8, 1, 2, 7, 7, 5, 7, 7, 5, 7, 7, 5, 7, 7, 5}; + + static int16_t dhf_mask[] = + { + 0x0000, /* R0 */ + 0x0371, /* LPC1 */ + 0x015E, /* LPC2 */ + 0x00c3, /* LPC3 */ + 0x0001, /* INT_LPC */ + 0x0000, /* MODE */ + 0x0047, /* CODE1_1 */ + 0x004a, /* CODE2_1 */ + 0x0000, /* GSP0_1 */ + 0x0009, /* CODE1_2 */ + 0x0026, /* CODE2_2 */ + 0x0007, /* GSP0_2 */ + 0x0000, /* CODE1_3 */ + 0x0000, /* CODE2_3 */ + 0x0000, /* GSP0_3 */ + 0x0000, /* CODE1_4 */ + 0x0000, /* CODE2_4 */ + 0x0000 /* GSP0_4 */ + }; + + int i; + int j; + + for (i = 0; i < iLastPara; i++) + { + j = ((pswSpeechPara[i] & ~(~0 << n[i])) ^ dhf_mask[i]); + if (j) + break; + } + + return !j; +} + + +/*************************************************************************** + * + * FUNCTION NAME: decoderReset + * + * PURPOSE: + * resets all of the state variables for the decoder + * + * INPUT: + * None + * + * OUTPUT: + * None + * + * RETURN: + * None + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + **************************************************************************/ + +void GsmHrCodec::decoderReset(void) +{ +/*_________________________________________________________________________ + | | + | External declarations for decoder variables which need to be reset | + |_________________________________________________________________________| +*/ + + /* variables defined in sp_dec.c */ + /* ----------------------------- */ + + extern int16_t gswPostFiltAgcGain, + gpswPostFiltStateNum[NP], + gpswPostFiltStateDenom[NP], + swPostEmphasisState, + pswSynthFiltState[NP], + pswOldFrmKsDec[NP], + pswOldFrmAsDec[NP], + pswOldFrmPFNum[NP], + pswOldFrmPFDenom[NP], + swOldR0Dec, + pswLtpStateBaseDec[LTP_LEN + S_LEN], + pswPPreState[LTP_LEN + S_LEN]; + + extern int16_t swMuteFlagOld; /* error concealment */ + + + /* variables defined in err_conc.c *//* error concealment */ + /* ------------------------------- *//* error concealment */ + + extern int32_t plSubfrEnergyMem[4]; /* error concealment */ + extern int16_t swLevelMem[4], + lastR0, /* error concealment */ + pswLastGood[18], /* error concealment */ + swState, + swLastFlag; /* error concealment */ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + +/*_________________________________________________________________________ + | | + | Executable code | + |_________________________________________________________________________| +*/ + + /* reset all the decoder state variables */ + /* ------------------------------------- */ + + swOldR0Dec = 0; + + gswPostFiltAgcGain = 0; + + swPostEmphasisState = 0; + + for (i = 0; i < NP; i++) + { + gpswPostFiltStateNum[i] = 0; + gpswPostFiltStateDenom[i] = 0; + pswSynthFiltState[i] = 0; + pswOldFrmKsDec[i] = 0; + pswOldFrmAsDec[i] = 0; + pswOldFrmPFNum[i] = 0; + pswOldFrmPFDenom[i] = 0; + } + + for (i = 0; i < (LTP_LEN + S_LEN); i++) + { + pswLtpStateBaseDec[i] = 0; + pswPPreState[i] = 0; + } + + + /* reset all the error concealment state variables */ + /* ----------------------------------------------- */ + + swMuteFlagOld = 0; + + lastR0 = 0; + swState = 7; + swLastFlag = 0; + for (i = 0; i < 3; i++) + { + plSubfrEnergyMem[i] = 80; + swLevelMem[i] = -72; + } + for (i = 0; i < 18; i++) + { + pswLastGood[i] = 0; + } + + +} + +/*************************************************************************** + * + * FUNCTION NAME: encoderHomingFrameTest + * + * PURPOSE: + * Checks if a frame of input samples matches the Encoder Homing Frame + * pattern, which is 0x0008 for all 160 samples in the frame. + * + * INPUT: + * pswSpeech[] one frame of speech samples + * + * OUTPUT: + * None + * + * RETURN: + * 0 input frame does not match the Encoder Homing Frame pattern. + * 1 input frame matches the Encoder Homing Frame pattern. + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + * pswSpeech + **************************************************************************/ + +int encoderHomingFrameTest(int16_t pswSpeech[]) +{ + int i; + int16_t j; + + for (i = 0; i < F_LEN; i++) + { + j = pswSpeech[i] ^ EHF_MASK; + if (j) + break; + } + + return !j; +} + +/*************************************************************************** + * + * FUNCTION NAME: encoderReset + * + * PURPOSE: + * resets all of the state variables for the encoder + * + * INPUT: + * None + * + * OUTPUT: + * None + * + * RETURN: + * None + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + **************************************************************************/ + +void encoderReset(void) +{ + +/*_________________________________________________________________________ + | | + | External declarations for encoder variables which need to be reset | + |_________________________________________________________________________| +*/ + + /* variables defined in sp_enc.c */ + /* ----------------------------- */ + + extern int16_t swOldR0; + extern int16_t swOldR0Index; + + extern struct NormSw psnsWSfrmEngSpace[]; + + extern int16_t pswHPFXState[]; + extern int16_t pswHPFYState[]; + extern int16_t pswOldFrmKs[]; + extern int16_t pswOldFrmAs[]; + extern int16_t pswOldFrmSNWCoefs[]; + extern int16_t pswWgtSpeechSpace[]; + + extern int16_t pswSpeech[]; /* input speech */ + + extern int16_t swPtch; + + + /* variables defined in sp_frm.c */ + /* ----------------------------- */ + + extern int16_t pswAnalysisState[NP]; + + extern int16_t pswWStateNum[NP], + pswWStateDenom[NP]; + + + /* variables defined in sp_sfrm.c */ + /* ------------------------------ */ + + extern int16_t pswLtpStateBase[LTP_LEN + S_LEN]; + extern int16_t pswHState[NP]; + extern int16_t pswHNWState[HNW_BUFF_LEN]; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + +/*_________________________________________________________________________ + | | + | Executable code | + |_________________________________________________________________________| +*/ + + /* reset all the encoder state variables */ + /* ------------------------------------- */ + + swOldR0Index = 0; + swOldR0 = 0; + + for (i = 0; i < 2 * N_SUB; i++) + { + psnsWSfrmEngSpace[i].man = 0; + psnsWSfrmEngSpace[i].sh = 0; + } + + for (i = 0; i < 4; i++) + pswHPFXState[i] = 0; + + for (i = 0; i < 8; i++) + pswHPFYState[i] = 0; + + for (i = 0; i < NP; i++) + { + pswOldFrmKs[i] = 0; + pswOldFrmAs[i] = 0; + pswOldFrmSNWCoefs[i] = 0; + pswAnalysisState[i] = 0; + pswWStateNum[i] = 0; + pswWStateDenom[i] = 0; + pswHState[i] = 0; + } + + for (i = 0; i < (F_LEN + LMAX + CG_INT_MACS / 2); i++) + pswWgtSpeechSpace[i] = 0; + + for (i = 0; i < INBUFFSZ; i++) + pswSpeech[i] = 0; + + for (i = 0; i < (LTP_LEN + S_LEN); i++) + pswLtpStateBase[i] = 0; + + for (i = 0; i < HNW_BUFF_LEN; i++) + pswHNWState[i] = 0; + + swPtch = 1; +} + +/*************************************************************************** + * + * FUNCTION NAME: resetDec + * + * PURPOSE: + * resets all of the state variables for the decoder, and for the + * receive DTX and Comfort Noise. + * + * INPUT: + * None + * + * OUTPUT: + * None + * + * RETURN: + * None + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + **************************************************************************/ + +void resetDec(void) +{ + decoderReset(); /* reset all the state variables in + * the speech decoder */ + dtxResetRx(); /* reset all the receive DTX and CN + * state variables */ +} + +/*************************************************************************** + * + * FUNCTION NAME: resetEnc + * + * PURPOSE: + * resets all of the state variables for the encoder and VAD, and for + * the transmit DTX and Comfort Noise. + * + * INPUT: + * None + * + * OUTPUT: + * None + * + * RETURN: + * None + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + **************************************************************************/ + +void resetEnc(void) +{ + + encoderReset(); /* reset all the state variables in + * the speech encoder */ + vad_reset(); /* reset all the VAD state variables */ + + dtxResetTx(); /* reset all the transmit DTX and CN + * state variables */ +} + +/*************************************************************************** + * + * FUNCTION NAME: dtxResetTx + * + * PURPOSE: + * reset all the transmit DTX and CN state variables + * + * INPUT: + * None + * + * OUTPUT: + * None + * + * RETURN: + * None + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + **************************************************************************/ + +void dtxResetTx(void) +{ + +/*_________________________________________________________________________ + | | + | External declarations for encoder variables which need to be reset | + |_________________________________________________________________________| +*/ + + /* variables defined in sp_enc.c */ + /* ----------------------------- */ + + extern int16_t swTxGsHistPtr; + + + /* variables defined in dtx.c */ + /* -------------------------- */ + + extern int16_t swVadFrmCnt; /* Indicates the number of sequential + * frames where VAD == 0 */ + extern short int siUpdPointer; + extern int16_t swNElapsed; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + +/*_________________________________________________________________________ + | | + | Executable code | + |_________________________________________________________________________| +*/ + + /* reset all the transmit DTX and CN state variables */ + /* ------------------------------------------------- */ + + swTxGsHistPtr = 0; + + swVadFrmCnt = 0; + + siUpdPointer = 0; + + swNElapsed = 50; + +} + +/*************************************************************************** + * + * FUNCTION NAME: dtxResetRx + * + * PURPOSE: + * reset all the receive DTX and CN state variables + * + * INPUT: + * None + * + * OUTPUT: + * None + * + * RETURN: + * None + * + * REFERENCES: Sub-clause 10 of GSM Recomendation 06.02 + * + * KEYWORDS: + **************************************************************************/ + +void dtxResetRx(void) +{ + +/*_________________________________________________________________________ + | | + | External declarations for encoder variables which need to be reset | + |_________________________________________________________________________| +*/ + + /* variables defined in sp_dec.c */ + /* ----------------------------- */ + + extern int16_t swRxDTXState; + extern int16_t swDecoMode; + extern int16_t swDtxMuting; + extern int16_t swDtxBfiCnt; + + extern int16_t swOldR0IndexDec; + + extern int16_t swRxGsHistPtr; + extern int32_t pL_RxGsHist[(OVERHANG - 1) * N_SUB]; + + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + + +/*_________________________________________________________________________ + | | + | Executable code | + |_________________________________________________________________________| +*/ + + /* reset all the receive DTX and CN state variables */ + /* ------------------------------------------------ */ + + swRxDTXState = CNINTPER - 1; + swDecoMode = SPEECH; + swDtxMuting = 0; + swDtxBfiCnt = 0; + + swOldR0IndexDec = 0; + + swRxGsHistPtr = 0; + + for (i = 0; i < (OVERHANG - 1) * N_SUB; i++) + pL_RxGsHist[i] = 0; + +} diff --git a/src/libs/gsmhr/gsmhr_homing.h b/src/libs/gsmhr/gsmhr_homing.h new file mode 100644 index 00000000..5a5fdede --- /dev/null +++ b/src/libs/gsmhr/gsmhr_homing.h @@ -0,0 +1,30 @@ +#ifndef __HOMING +#define __HOMING + +#include "typedefs.h" + +#define EHF_MASK 0x0008 /* Encoder Homing Frame pattern */ + +/*_________________________________________________________________________ + | | + | Function Prototypes | + |_________________________________________________________________________| +*/ + +int decoderHomingFrameTest(Shortword pswSpeechPara[], int iLastPara); + +void decoderReset(void); + +int encoderHomingFrameTest(Shortword pswSpeech[]); + +void encoderReset(void); + +void resetDec(void); + +void resetEnc(void); + +void dtxResetTx(void); + +void dtxResetRx(void); + +#endif diff --git a/src/libs/gsmhr/gsmhr_host.c b/src/libs/gsmhr/gsmhr_host.c new file mode 100644 index 00000000..fd6ad3db --- /dev/null +++ b/src/libs/gsmhr/gsmhr_host.c @@ -0,0 +1,347 @@ +/*************************************************************************** + * + * File Name: host.c + * + * Purpose: Contains functions for file I/O and formatting, no signal + * processing. + * + * The functions in this file are listed below. All are level 2 + * fuctions, where level 0 is main(), except for fillBitAlloc() which + * is level 3. The two "Interface" routines perform truncation of the + * three least significant bits of the 16 bit linear input. The others + * are simply file I/O functions and data reformatters. + * + * fillBitAlloc() + * hostEncoderInterface() + * readDecfile() + * speechDecoderHostInterface() + * writeEncfile() + * + **************************************************************************/ + +/*_________________________________________________________________________ + | | + | Include Files | + |_________________________________________________________________________| +*/ + +#include +#include "gsmhr_typedefs.h" + +/*************************************************************************** + * + * FUNCTION NAME: fillBitAlloc + * + * PURPOSE: + * + * Arrange speech parameters for encoder output + * + * INPUTS: + * + * The speechcoders codewords: + * iR0 - Frame energy + * piVqIndeces[0:2] - LPC vector quantizer codewords + * iSoftInterp - Soft interpolation bit 1 or 0 + * iVoicing - voicing mode 0,1,2,3 + * piLags[0:3] - Frame and delta lag codewords + * piCodeWrdsA[0:3] - VSELP codevector 1 + * piCodeWrdsB[0:3] - VSELP codevector 2 (n/a for voiced modes) + * piGsp0s[0:3] - GSP0 codewords + * swVadFlag - voice activity detection flag + * swSP - Speech flag + * + * OUTPUTS: + * + * pswBAlloc[0:20] - an array into which the coded data is moved + * + * RETURN VALUE: + * + * none + * + * REFERENCES: Sub-clause 2.1 and 4.1.12 of GSM Recomendation 06.20 + * + **************************************************************************/ + +void fillBitAlloc(int iVoicing, int iR0, int *piVqIndeces, + int iSoftInterp, int *piLags, + int *piCodeWrdsA, int *piCodeWrdsB, + int *piGsp0s, int16_t swVadFlag, + int16_t swSP, int16_t *pswBAlloc) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + int16_t *pswNxt; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + pswNxt = pswBAlloc; + *pswNxt++ = iR0; + for (i = 0; i < 3; i++) + *pswNxt++ = *piVqIndeces++; + *pswNxt++ = iSoftInterp; + *pswNxt++ = iVoicing; + + /* check voicing mode */ + if (iVoicing) + { + /* voiced mode */ + for (i = 0; i < N_SUB; i++) + { + *pswNxt++ = *piLags++; + *pswNxt++ = *piCodeWrdsA++; + *pswNxt++ = *piGsp0s++; + } + } + else + { /* unvoiced frame */ + for (i = 0; i < N_SUB; i++) + { + *pswNxt++ = *piCodeWrdsA++; + *pswNxt++ = *piCodeWrdsB++; + *pswNxt++ = *piGsp0s++; + } + } + *pswNxt++ = swVadFlag; + *pswNxt++ = swSP; +} + +/*************************************************************************** + * + * FUNCTION NAME: hostEncoderInterface + * + * PURPOSE: + * + * Read in speech data from a file. Zero the least significant 3 bits. + * + * + * INPUTS: + * + * pfileInSpeech + * FILE pointer to the binary input file + * + * iNumToRead + * Number of samples to read from the file, typically + * 160 (20 ms of speech). + * + * + * OUTPUTS: + * + * pswSamplesRead[] + * The speech samples read in from the file. + * + * + * RETURN VALUE: + * + * iNumRead + * The number of samples actually read. + * + * IMPLEMENTATION: + * + * The input speech file should be in "native" format. This means that + * the file is to be read (by this program) and written (by another + * program) as short ints (not chars). + * + * If not enough samples are available in the file, the number actually + * read is returned. If the read fails to fill the requested iNumToRead + * samples, then the rest are zeroed. + * + * In all cases the least significant 3 bits of all speech samples are + * zeroed. + * + * REFERENCES: Sub-clause 4.1 of GSM Recomendation 06.20 + * + * KEYWORDS: read, read speech, get speech data + * + **************************************************************************/ + +int hostEncoderInterface(FILE *pfileInSpeech, int iNumToRead, + int16_t pswSamplesRead[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int iNumRead, + i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + iNumRead = fread((char *) pswSamplesRead, sizeof (int16_t), + iNumToRead, pfileInSpeech); + + /* Delete the 3 LSB's - 13 bit speech input */ + /*------------------------------------------*/ + + for (i = 0; i < iNumRead; i++) + { + pswSamplesRead[i] &= 0xfff8; + } + + + /* Fill out the iNumToRead buffer with zeroes */ + /*--------------------------------------------*/ + + if (iNumRead != iNumToRead) + { + for (i = iNumRead; i < iNumToRead; i++) + { + pswSamplesRead[i] = 0; + } + } + return (iNumRead); +} + +/*************************************************************************** + * + * FUNCTION NAME: readDecfile + * + * PURPOSE: + * Reads decoder parameter input file + * + * INPUT: + * infile decoder parameter input file. + * + * OUTPUT: + * pswSpeechPara array of received 16-bit values + * + * RETURN: + * 0 successfully read a complete frame of data + * + * REFERENCES: Sub-clause 4.2 of GSM Recomendation 06.20 + * + * KEYWORDS: pswSpeechPara + * + **************************************************************************/ + +int readDecfile(FILE *infile, int16_t pswSpeechPara[]) +{ + if (fread((char *) pswSpeechPara, sizeof (int16_t), 22, infile) == 0) + return (1); + else + return (0); +} + +/*************************************************************************** + * + * FUNCTION NAME: speechDecoderHostInterface + * + * PURPOSE: + * The purpose of this function is to truncate the linear pcm and write + * it into the output file + * + * INPUTS: + * + * F_LEN + * + * 160 = linear pcm output frame size + * + * pswDecodedSpeechFrame[0:F_LEN-1] + * + * 16 bit linear pcm + * + * OUTPUTS: + * + * fpfileSpeechOut + * + * 13 bit linear pcm stored to file given by this pointer + * + * RETURN VALUE: + * + * none + * + * IMPLEMENTATION: + * + * REFERENCES: Sub-clause 4.2 of GSM Recomendation 06.20 + * + * KEYWORDS: synthesis, speechdecoder, decoding, truncation + * + **************************************************************************/ + +void speechDecoderHostInterface(int16_t pswDecodedSpeechFrame[], + FILE *fpfileSpeechOut) +{ + +/*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| +*/ + +#define PCM_MASK 0xfff8 /* 16 to 13 bit linear PCM mask */ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + short int i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* truncate the 16 bit linear pcm to 13 bits */ + /* ----------------------------------------- */ + + for (i = 0; i < F_LEN; i++) + { + pswDecodedSpeechFrame[i] = pswDecodedSpeechFrame[i] & PCM_MASK; + } + + /* F_LEN samples of linear pcm to output file */ + /* ------------------------------------------ */ + + fwrite((char *) pswDecodedSpeechFrame, sizeof (int16_t), + F_LEN, fpfileSpeechOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: writeEncfile + * + * PURPOSE: + * Writes encoded parameters to ouput file + * + * INPUT: + * pswSpeechPara array of encoded parameter words. + * + * OUTPUT: + * fpfileEnc 16-bit encoded values. + * + * RETURN: + * i number of bytes written + * + * REFERENCES: Sub-clause 4.1 of GSM Recomendation 06.20 + * + * KEYWORDS: pswSpeechPara, fpfileEnc + * + ************************************************************************** +*/ + +int writeEncfile(int16_t pswSpeechPara[], FILE *fpfileEnc) +{ + int i; + + i = fwrite((char *) pswSpeechPara, sizeof (int16_t), 20, fpfileEnc); + + return (i); +} diff --git a/src/libs/gsmhr/gsmhr_host.h b/src/libs/gsmhr/gsmhr_host.h new file mode 100644 index 00000000..12fffaf2 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_host.h @@ -0,0 +1,29 @@ +#ifndef __HOSTGSM +#define __HOSTGSM + +#include +#include "typedefs.h" + +/*_________________________________________________________________________ + | | + | Function Prototypes | + |_________________________________________________________________________| +*/ + +void fillBitAlloc(int iVoicing, int iR0, int *piVqIndeces, + int iSoftInterp, int *piLags, + int *piCodeWrdsA, int *piCodeWrdsB, + int *piGsp0s, int16_t swVadFlag, + int16_t swSP, int16_t *pswBAlloc); + +int hostEncoderInterface(FILE *pfileInSpeech, int iNumToRead, + int16_t pswSamplesRead[]); + + int readDecfile(FILE *infile, int16_t pswSpeechPara[]); + + void speechDecoderHostInterface(int16_t pswDecodedSpeechFrame[], + FILE *fpfileSpeechOut); + + int writeEncfile(int16_t pswOutBit[], FILE *fpfileEnc); + +#endif diff --git a/src/libs/gsmhr/gsmhr_sp_dec.c b/src/libs/gsmhr/gsmhr_sp_dec.c new file mode 100644 index 00000000..51c838c2 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_sp_dec.c @@ -0,0 +1,5471 @@ +/*************************************************************************** + * + * File Name: sp_dec.c + * + * Purpose: + * Contains all functions for decoding speech. It does not + * include those routines needed to decode channel information. + * + * Since the GSM half-rate speech coder is an analysis-by-synthesis + * coder, many of the routines in this file are also called by the + * encoder. Functions are included for coded-parameter lookup, + * LPC filter coefficient interpolation, excitation vector lookup + * and construction, vector quantized gain lookup, and LPC synthesis + * filtering. In addition, some post-processing functions are + * included. + * + * Below is a listing of all the functions appearing in the file. + * The functions are arranged according to their purpose. Under + * each heading, the ordering is hierarchical. + * + * The entire speech decoder, under which all these routines fall, + * except were noted: + * speechDecoder() + * + * Spectral Smoothing of LPC: + * a_sst() + * aFlatRcDp() + * rcToCorrDpL() + * aToRc() + * rcToADp() + * VSELP codevector construction: + * b_con() + * v_con() + * LTP vector contruction: + * fp_ex() + * get_ipjj() + * lagDecode() + * LPC contruction + * getSfrmLpc() + * interpolateCheck() + * res_eng() + * lookupVq() + * Excitation scaling: + * rs_rr() + * g_corr1() (no scaling) + * rs_rrNs() + * g_corr1s() (g_corr1 with scaling) + * scaleExcite() + * Post filtering: + * pitchPreFilt() + * agcGain() + * lpcIir() + * r0BasedEnergyShft() + * spectralPostFilter() + * lpcFir() + * + * + * Routines not referenced by speechDecoder() + * Filtering routines: + * lpcIrZsIir() + * lpcZiIir() + * lpcZsFir() + * lpcZsIir() + * lpcZsIirP() + * Square root: + * sqroot() + * + **************************************************************************/ + +/*_________________________________________________________________________ + | | + | Include Files | + |_________________________________________________________________________| +*/ + +#include "typedefs.h" +#include "mathhalf.h" +#include "sp_rom.h" +#include "sp_dec.h" +#include "err_conc.h" +#include "dtx.h" + + +/*_________________________________________________________________________ + | | + | Local Functions (scope is limited to this file) | + |_________________________________________________________________________| +*/ + +static void a_sst(int16_t swAshift, int16_t swAscale, + int16_t pswDirectFormCoefIn[], + int16_t pswDirectFormCoefOut[]); + + static short aToRc(int16_t swAshift, int16_t pswAin[], + int16_t pswRc[]); + + static int16_t agcGain(int16_t pswStateCurr[], + struct NormSw snsInSigEnergy, + int16_t swEngyRShft); + + static int16_t lagDecode(int16_t swDeltaLag); + + static void lookupVq(int16_t pswVqCodeWds[], int16_t pswRCOut[]); + + static void pitchPreFilt(int16_t pswExcite[], + int16_t swRxGsp0, + int16_t swRxLag, + int16_t swUvCode, + int16_t swSemiBeta, + struct NormSw snsSqrtRs, + int16_t pswExciteOut[], + int16_t pswPPreState[]); + + static void spectralPostFilter(int16_t pswSPFIn[], + int16_t pswNumCoef[], int16_t pswDenomCoef[], + int16_t pswSPFOut[]); + +/*_________________________________________________________________________ + | | + | Local Defines | + |_________________________________________________________________________| +*/ + +#define P_INT_MACS 10 +#define ASCALE 0x0800 +#define ASHIFT 4 +#define DELTA_LEVELS 16 +#define GSP0_SCALE 1 +#define C_BITS_V 9 /* number of bits in any voiced VSELP + * codeword */ +#define C_BITS_UV 7 /* number of bits in a unvoiced VSELP + * codeword */ +#define MAXBITS C_BITS_V /* max number of bits in any VSELP + * codeword */ +#define LTP_LEN 147 /* 147==0x93 length of LTP history */ +#define SQRT_ONEHALF 0x5a82 /* the 0.5 ** 0.5 */ +#define LPC_ROUND 0x00000800L /* 0x8000 >> ASHIFT */ +#define AFSHIFT 2 /* number of right shifts to be + * applied to the autocorrelation + * sequence in aFlatRcDp */ + +/*_________________________________________________________________________ + | | + | State variables (globals) | + |_________________________________________________________________________| +*/ + + int16_t gswPostFiltAgcGain, + gpswPostFiltStateNum[NP], + gpswPostFiltStateDenom[NP], + swPostEmphasisState, + pswSynthFiltState[NP], + pswOldFrmKsDec[NP], + pswOldFrmAsDec[NP], + pswOldFrmPFNum[NP], + pswOldFrmPFDenom[NP], + swOldR0Dec, + pswLtpStateBaseDec[LTP_LEN + S_LEN], + pswPPreState[LTP_LEN + S_LEN]; + + + int16_t swMuteFlagOld; /* error concealment */ + + + /* DTX state variables */ + /* ------------------- */ + + int16_t swRxDTXState = CNINTPER - 1; /* DTX State at the rx. + * Modulo */ + + /* counter [0,11]. */ + + int16_t swDecoMode = SPEECH; + int16_t swDtxMuting = 0; + int16_t swDtxBfiCnt = 0; + + int16_t swOldR0IndexDec = 0; + + int16_t swRxGsHistPtr = 0; + int32_t pL_RxGsHist[(OVERHANG - 1) * N_SUB]; + + +/*_________________________________________________________________________ + | | + | Global Data | + | (scope is global to this file) | + |_________________________________________________________________________| +*/ + + int16_t swR0Dec; + + int16_t swVoicingMode, /* MODE */ + pswVq[3], /* LPC1, LPC2, LPC3 */ + swSi, /* INT_LPC */ + swEngyRShift; /* for use by spectral postfilter */ + + + int16_t swR0NewCN; /* DTX mode */ + + extern int32_tRom ppLr_gsTable[4][32]; /* DTX mode */ + + +/*************************************************************************** + * + * FUNCTION NAME: aFlatRcDp + * + * PURPOSE: + * + * Given a int32_t autocorrelation sequence, representing LPC + * information, aFlatRcDp converts the vector to one of NP + * int16_t reflection coefficients. + * + * INPUT: + * + * + * pL_R[0:NP] - An input int32_t autocorrelation sequence, (pL_R[0] = + * not necessarily 0x7fffffffL). pL_R is altered in the + * call, by being right shifted by global constant + * AFSHIFT bits. + * + * The input array pL_R[] should be shifted left as much + * as possible to improve precision. + * + * AFSHIFT - The number of right shifts to be applied to the + * normalized autocorrelation sequence pL_R. + * + * OUTPUT: + * + * pswRc[0:NP-1] - A int16_t output vector of NP reflection + * coefficients. + * + * RETURN VALUE: + * + * None + * + * DESCRIPTION: + * + * This routine transforms LPC information from one set of + * parameters to another. It is better suited for fixed point + * implementations than the Levinson-Dubin recursion. + * + * The function is called by a_sst(), and getNWCoefs(). In a_sst() + * direct form coefficients are converted to autocorrelations, + * and smoothed in that domain. Conversion back to direct form + * coefficients is done by calling aFlatRc(), followed by rcToADp(). + * + * In getNwCoefs() again the conversion back to direct form + * coefficients is done by calling aFlatRc(), followed by rcToADp(). + * In getNwCoefs() an autocorrelation sequence is generated from the + * impulse response of the weighting filters. + * + * The fundamental recursion is derived from AFLAT, which is + * described in section 4.1.4.1. + * + * Unlike in AFLAT where the reflection coefficients are known, here + * they are the unknowns. PBar and VBar for j==0 are initially + * known, as is rSub1. From this information the next set of P's + * and V's are generated. At the end of the recursion the next, + * reflection coefficient rSubj (pswRc[j]) can be calcluated by + * dividing Vsubj by Psubj. + * + * Precision is crucial in this routine. At each stage, a + * normalization is performed prior to the reflection coefficient + * calculation. In addition, to prevent overflow, the + * autocorrelation sequence is scaled down by ASHIFT (4) right + * shifts. + * + * + * REFERENCES: Sub_Clause 4.1.9 and 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: reflection coefficients, AFLAT, aflat, recursion, LPC + * KEYWORDS: autocorrelation + * + *************************************************************************/ + +void aFlatRcDp(int32_t *pL_R, int16_t *pswRc) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t pL_pjNewSpace[NP]; + int32_t pL_pjOldSpace[NP]; + int32_t pL_vjNewSpace[2 * NP - 1]; + int32_t pL_vjOldSpace[2 * NP - 1]; + + int32_t *pL_pjOld; + int32_t *pL_pjNew; + int32_t *pL_vjOld; + int32_t *pL_vjNew; + int32_t *pL_swap; + + int32_t L_temp; + int32_t L_sum; + int16_t swRc, + swRcSq, + swTemp, + swTemp1, + swAbsTemp1, + swTemp2; + int i, + j; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + pL_pjOld = pL_pjOldSpace; + pL_pjNew = pL_pjNewSpace; + pL_vjOld = pL_vjOldSpace + NP - 1; + pL_vjNew = pL_vjNewSpace + NP - 1; + + + /* Extract the 0-th reflection coefficient */ + /*-----------------------------------------*/ + + swTemp1 = round(pL_R[1]); + swTemp2 = round(pL_R[0]); + swAbsTemp1 = abs_s(swTemp1); + if (swTemp2 <= 0 || sub(swAbsTemp1, swTemp2) >= 0) + { + j = 0; + for (i = j; i < NP; i++) + { + pswRc[i] = 0; + } + return; + } + + swRc = divide_s(swAbsTemp1, swTemp2);/* return division result */ + + if (sub(swTemp1, swAbsTemp1) == 0) + swRc = negate(swRc); /* negate reflection Rc[j] */ + + pswRc[0] = swRc; /* copy into the output Rc array */ + + for (i = 0; i <= NP; i++) + { + pL_R[i] = L_shr(pL_R[i], AFSHIFT); + } + + /* Initialize the pjOld and vjOld recursion arrays */ + /*-------------------------------------------------*/ + + for (i = 0; i < NP; i++) + { + pL_pjOld[i] = pL_R[i]; + pL_vjOld[i] = pL_R[i + 1]; + } + for (i = -1; i > -NP; i--) + pL_vjOld[i] = pL_R[-(i + 1)]; + + + /* Compute the square of the j=0 reflection coefficient */ + /*------------------------------------------------------*/ + + swRcSq = mult_r(swRc, swRc); + + /* Update pjNew and vjNew arrays for lattice stage j=1 */ + /*-----------------------------------------------------*/ + + /* Updating pjNew: */ + /*-------------------*/ + + for (i = 0; i <= NP - 2; i++) + { + L_temp = L_mpy_ls(pL_vjOld[i], swRc); + L_sum = L_add(L_temp, pL_pjOld[i]); + L_temp = L_mpy_ls(pL_pjOld[i], swRcSq); + L_sum = L_add(L_temp, L_sum); + L_temp = L_mpy_ls(pL_vjOld[-i], swRc); + pL_pjNew[i] = L_add(L_sum, L_temp); + } + + /* Updating vjNew: */ + /*-------------------*/ + + for (i = -NP + 2; i <= NP - 2; i++) + { + L_temp = L_mpy_ls(pL_vjOld[-i - 1], swRcSq); + L_sum = L_add(L_temp, pL_vjOld[i + 1]); + L_temp = L_mpy_ls(pL_pjOld[(((i + 1) >= 0) ? i + 1 : -(i + 1))], swRc); + L_temp = L_shl(L_temp, 1); + pL_vjNew[i] = L_add(L_temp, L_sum); + } + + + + j = 0; + + /* Compute reflection coefficients Rc[1],...,Rc[9] */ + /*-------------------------------------------------*/ + + for (j = 1; j < NP; j++) + { + + /* Swap pjNew and pjOld buffers */ + /*------------------------------*/ + + pL_swap = pL_pjNew; + pL_pjNew = pL_pjOld; + pL_pjOld = pL_swap; + + /* Swap vjNew and vjOld buffers */ + /*------------------------------*/ + + pL_swap = pL_vjNew; + pL_vjNew = pL_vjOld; + pL_vjOld = pL_swap; + + /* Compute the j-th reflection coefficient */ + /*-----------------------------------------*/ + + swTemp = norm_l(pL_pjOld[0]); /* get shift count */ + swTemp1 = round(L_shl(pL_vjOld[0], swTemp)); /* normalize num. */ + swTemp2 = round(L_shl(pL_pjOld[0], swTemp)); /* normalize den. */ + + /* Test for invalid divide conditions: a) devisor < 0 b) abs(divident) > + * abs(devisor) If either of these conditions is true, zero out + * reflection coefficients for i=j,...,NP-1 and return. */ + + swAbsTemp1 = abs_s(swTemp1); + if (swTemp2 <= 0 || sub(swAbsTemp1, swTemp2) >= 0) + { + i = j; + for (i = j; i < NP; i++) + { + pswRc[i] = 0; + } + return; + } + + swRc = divide_s(swAbsTemp1, swTemp2); /* return division result */ + if (sub(swTemp1, swAbsTemp1) == 0) + swRc = negate(swRc); /* negate reflection Rc[j] */ + swRcSq = mult_r(swRc, swRc); /* compute Rc^2 */ + pswRc[j] = swRc; /* copy Rc[j] to output array */ + + /* Update pjNew and vjNew arrays for the next lattice stage if j < NP-1 */ + /*---------------------------------------------------------------------*/ + + /* Updating pjNew: */ + /*-----------------*/ + + for (i = 0; i <= NP - j - 2; i++) + { + L_temp = L_mpy_ls(pL_vjOld[i], swRc); + L_sum = L_add(L_temp, pL_pjOld[i]); + L_temp = L_mpy_ls(pL_pjOld[i], swRcSq); + L_sum = L_add(L_temp, L_sum); + L_temp = L_mpy_ls(pL_vjOld[-i], swRc); + pL_pjNew[i] = L_add(L_sum, L_temp); + } + + /* Updating vjNew: */ + /*-----------------*/ + + for (i = -NP + j + 2; i <= NP - j - 2; i++) + { + L_temp = L_mpy_ls(pL_vjOld[-i - 1], swRcSq); + L_sum = L_add(L_temp, pL_vjOld[i + 1]); + L_temp = L_mpy_ls(pL_pjOld[(((i + 1) >= 0) ? i + 1 : -(i + 1))], swRc); + L_temp = L_shl(L_temp, 1); + pL_vjNew[i] = L_add(L_temp, L_sum); + } + } + return; +} + +/*************************************************************************** + * + * FUNCTION NAME: aToRc + * + * PURPOSE: + * + * This subroutine computes a vector of reflection coefficients, given + * an input vector of direct form LPC filter coefficients. + * + * INPUTS: + * + * NP + * order of the LPC filter (global constant) + * + * swAshift + * The number of right shifts applied externally + * to the direct form filter coefficients. + * + * pswAin[0:NP-1] + * The input vector of direct form LPC filter + * coefficients. + * + * OUTPUTS: + * + * pswRc[0:NP-1] + * Array containing the reflection coefficients. + * + * RETURN VALUE: + * + * siUnstableFlt + * If stable reflection coefficients 0, 1 if unstable. + * + * + * DESCRIPTION: + * + * This function performs the conversion from direct form + * coefficients to reflection coefficients. It is used in a_sst() + * and interpolateCheck(). In a_sst() reflection coefficients used + * as a transitional data format. aToRc() is used for this + * conversion. + * + * When performing interpolation, a stability check must be + * performed. interpolateCheck() does this by calling aToRc(). + * + * First coefficients are shifted down by iAshift. NP, the filter + * order is 10. The a's and rc's each have NP elements in them. An + * elaborate algorithm description can be found on page 443, of + * "Digital Processing of Speech Signals" by L.R. Rabiner and R.W. + * Schafer; Prentice-Hall; Englewood Cliffs, NJ (USA). 1978. + * + * REFERENCES: Sub_Clause 4.1.6, and 4.2.3 of GSM Recomendation 06.20 + * + * KEYWORDS: reflectioncoefficients, parcors, conversion, atorc, ks, as + * KEYWORDS: parcorcoefficients, lpc, flat, vectorquantization + * + *************************************************************************/ + +static short aToRc(int16_t swAshift, int16_t pswAin[], + int16_t pswRc[]) +{ + +/*_________________________________________________________________________ + | | + | Constants | + |_________________________________________________________________________| +*/ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t pswTmpSpace[NP], + pswASpace[NP], + swNormShift, + swActShift, + swNormProd, + swRcOverE, + swDiv, + *pswSwap, + *pswTmp, + *pswA; + + int32_t L_temp; + + short int siUnstableFlt, + i, + j; /* Loop control variables */ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Initialize starting addresses for temporary buffers */ + /*-----------------------------------------------------*/ + + pswA = pswASpace; + pswTmp = pswTmpSpace; + + /* Copy the direct form filter coefficients to a temporary array */ + /*---------------------------------------------------------------*/ + + for (i = 0; i < NP; i++) + { + pswA[i] = pswAin[i]; + } + + /* Initialize the flag for filter stability check */ + /*------------------------------------------------*/ + + siUnstableFlt = 0; + + /* Start computation of the reflection coefficients, Rc[9],...,Rc[1] */ + /*-------------------------------------------------------------------*/ + + for (i = NP - 1; i >= 1; i--) + { + + pswRc[i] = shl(pswA[i], swAshift); /* write Rc[i] to output array */ + + /* Check the stability of i-th reflection coefficient */ + /*----------------------------------------------------*/ + + siUnstableFlt = siUnstableFlt | isSwLimit(pswRc[i]); + + /* Precompute intermediate variables for needed for the computation */ + /* of direct form filter of order i-1 */ + /*------------------------------------------------------------------*/ + + if (sub(pswRc[i], SW_MIN) == 0) + { + siUnstableFlt = 1; + swRcOverE = 0; + swDiv = 0; + swActShift = 2; + } + else + { + L_temp = LW_MAX; /* Load ~1.0 into accum */ + L_temp = L_msu(L_temp, pswRc[i], pswRc[i]); /* 1.-Rc[i]*Rc[i] */ + swNormShift = norm_l(L_temp); + L_temp = L_shl(L_temp, swNormShift); + swNormProd = extract_h(L_temp); + swActShift = add(2, swNormShift); + swDiv = divide_s(0x2000, swNormProd); + swRcOverE = mult_r(pswRc[i], swDiv); + } + /* Check stability */ + /*---------------------*/ + siUnstableFlt = siUnstableFlt | isSwLimit(swRcOverE); + + /* Compute direct form filter coefficients corresponding to */ + /* a direct form filter of order i-1 */ + /*----------------------------------------------------------*/ + + for (j = 0; j <= i - 1; j++) + { + L_temp = L_mult(pswA[j], swDiv); + L_temp = L_msu(L_temp, pswA[i - j - 1], swRcOverE); + L_temp = L_shl(L_temp, swActShift); + pswTmp[j] = round(L_temp); + siUnstableFlt = siUnstableFlt | isSwLimit(pswTmp[j]); + } + + /* Swap swA and swTmp buffers */ + /*----------------------------*/ + + pswSwap = pswA; + pswA = pswTmp; + pswTmp = pswSwap; + } + + /* Compute reflection coefficient Rc[0] */ + /*--------------------------------------*/ + + pswRc[0] = shl(pswA[0], swAshift); /* write Rc[0] to output array */ + + /* Check the stability of 0-th reflection coefficient */ + /*----------------------------------------------------*/ + + siUnstableFlt = siUnstableFlt | isSwLimit(pswRc[0]); + + return (siUnstableFlt); +} + +/*************************************************************************** + * + * FUNCTION NAME: a_sst + * + * PURPOSE: + * + * The purpose of this function is to perform spectral smoothing of the + * direct form filter coefficients + * + * INPUTS: + * + * swAshift + * number of shift for coefficients + * + * swAscale + * scaling factor for coefficients + * + * pswDirectFormCoefIn[0:NP-1] + * + * array of input direct form coefficients + * + * OUTPUTS: + * + * pswDirectFormCoefOut[0:NP-1] + * + * array of output direct form coefficients + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * In a_sst() direct form coefficients are converted to + * autocorrelations, and smoothed in that domain. The function is + * used in the spectral postfilter. A description can be found in + * section 3.2.4 as well as in the reference by Y. Tohkura et al. + * "Spectral Smoothing Technique in PARCOR Speech + * Analysis-Synthesis", IEEE Trans. ASSP, vol. ASSP-26, pp. 591-596, + * Dec. 1978. + * + * After smoothing is performed conversion back to direct form + * coefficients is done by calling aFlatRc(), followed by rcToADp(). + * + * The spectral smoothing filter coefficients with bandwidth set to 300 + * and a sampling rate of 8000 be : + * static int16_tRom psrSST[NP+1] = { 0x7FFF, + * 0x7F5C, 0x7D76, 0x7A5B, 0x7622, 0x70EC, + * 0x6ADD, 0x641F, 0x5CDD, 0x5546, 0x4D86 + * } + * + * REFERENCES: Sub_Clause 4.2.4 of GSM Recomendation 06.20 + * + * KEYWORDS: spectral smoothing, direct form coef, sst, atorc, atocor + * KEYWORDS: levinson + * + *************************************************************************/ + +static void a_sst(int16_t swAshift, int16_t swAscale, + int16_t pswDirectFormCoefIn[], + int16_t pswDirectFormCoefOut[]) +{ + +/*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| +*/ + + static int16_tRom psrSST[NP + 1] = {0x7FFF, + 0x7F5C, 0x7D76, 0x7A5B, 0x7622, 0x70EC, + 0x6ADD, 0x641F, 0x5CDD, 0x5546, 0x4D86, + }; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t pL_CorrTemp[NP + 1]; + + int16_t pswRCNum[NP], + pswRCDenom[NP]; + + short int siLoopCnt; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* convert direct form coefs to reflection coefs */ + /* --------------------------------------------- */ + + aToRc(swAshift, pswDirectFormCoefIn, pswRCDenom); + + /* convert to autocorrelation coefficients */ + /* --------------------------------------- */ + + rcToCorrDpL(swAshift, swAscale, pswRCDenom, pL_CorrTemp); + + /* do spectral smoothing technique */ + /* ------------------------------- */ + + for (siLoopCnt = 1; siLoopCnt <= NP; siLoopCnt++) + { + pL_CorrTemp[siLoopCnt] = L_mpy_ls(pL_CorrTemp[siLoopCnt], + psrSST[siLoopCnt]); + } + + /* Compute the reflection coefficients via AFLAT */ + /*-----------------------------------------------*/ + + aFlatRcDp(pL_CorrTemp, pswRCNum); + + + /* Convert reflection coefficients to direct form filter coefficients */ + /*-------------------------------------------------------------------*/ + + rcToADp(swAscale, pswRCNum, pswDirectFormCoefOut); +} + +/************************************************************************** + * + * FUNCTION NAME: agcGain + * + * PURPOSE: + * + * Figure out what the agc gain should be to make the energy in the + * output signal match that of the input signal. Used in the post + * filters. + * + * INPUT: + * + * pswStateCurr[0:39] + * Input signal into agc block whose energy is + * to be modified using the gain returned. Signal is not + * modified in this routine. + * + * snsInSigEnergy + * Normalized number with shift count - the energy in + * the input signal. + * + * swEngyRShft + * Number of right shifts to apply to the vectors energy + * to ensure that it remains less than 1.0 + * (swEngyRShft is always positive or zero) + * + * OUTPUT: + * + * none + * + * RETURN: + * + * the agc's gain/2 note DIVIDED by 2 + * + * + * REFERENCES: Sub_Clause 4.2.2 and 4.2.4 of GSM Recomendation 06.20 + * + * KEYWORDS: postfilter, agc, automaticgaincontrol, leveladjust + * + *************************************************************************/ + +static int16_t agcGain(int16_t pswStateCurr[], + struct NormSw snsInSigEnergy, int16_t swEngyRShft) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_OutEnergy, + L_AgcGain; + + struct NormSw snsOutEnergy, + snsAgc; + + int16_t swAgcOut, + swAgcShftCnt; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Calculate the energy in the output vector divided by 2 */ + /*--------------------------------------------------------*/ + + snsOutEnergy.sh = g_corr1s(pswStateCurr, swEngyRShft, &L_OutEnergy); + + /* reduce energy by a factor of 2 */ + snsOutEnergy.sh = add(snsOutEnergy.sh, 1); + + /* if waveform has nonzero energy, find AGC gain */ + /*-----------------------------------------------*/ + + if (L_OutEnergy == 0) + { + swAgcOut = 0; + } + else + { + + snsOutEnergy.man = round(L_OutEnergy); + + /* divide input energy by 2 */ + snsInSigEnergy.man = shr(snsInSigEnergy.man, 1); + + + /* Calculate AGC gain squared */ + /*----------------------------*/ + + snsAgc.man = divide_s(snsInSigEnergy.man, snsOutEnergy.man); + swAgcShftCnt = norm_s(snsAgc.man); + snsAgc.man = shl(snsAgc.man, swAgcShftCnt); + + /* find shift count for G^2 */ + /*--------------------------*/ + + snsAgc.sh = add(sub(snsInSigEnergy.sh, snsOutEnergy.sh), + swAgcShftCnt); + L_AgcGain = L_deposit_h(snsAgc.man); + + + /* Calculate AGC gain */ + /*--------------------*/ + + snsAgc.man = sqroot(L_AgcGain); + + + /* check if 1/2 sqrt(G^2) >= 1.0 */ + /* This is equivalent to checking if shiftCnt/2+1 < 0 */ + /*----------------------------------------------------*/ + + if (add(snsAgc.sh, 2) < 0) + { + swAgcOut = SW_MAX; + } + else + { + + if (0x1 & snsAgc.sh) + { + snsAgc.man = mult(snsAgc.man, SQRT_ONEHALF); + } + + snsAgc.sh = shr(snsAgc.sh, 1); /* shiftCnt/2 */ + snsAgc.sh = add(snsAgc.sh, 1); /* shiftCnt/2 + 1 */ + + if (snsAgc.sh > 0) + { + snsAgc.man = shr(snsAgc.man, snsAgc.sh); + } + swAgcOut = snsAgc.man; + } + } + + return (swAgcOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: b_con + * + * PURPOSE: + * Expands codeword into an one dimensional array. The 0/1 input is + * changed to an element with magnitude +/- 0.5. + * + * input output + * + * 0 -0.5 + * 1 +0.5 + * + * INPUT: + * + * swCodeWord + * Input codeword, information in the LSB's + * + * siNumBits + * number of bits in the input codeword and number + * of elements in output vector + * + * pswVectOut[0:siNumBits] + * + * pointer to bit array + * + * OUTPUT: + * + * pswVectOut[0:siNumBits] + * + * signed bit array + * + * RETURN: + * + * none + * + * REFERENCES: Sub_Clause 4.1.10 and 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: b_con, codeword, expansion + * + *************************************************************************/ + +void b_con(int16_t swCodeWord, short siNumBits, + int16_t pswVectOut[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + short int siLoopCnt; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + for (siLoopCnt = 0; siLoopCnt < siNumBits; siLoopCnt++) + { + + if (swCodeWord & 1) /* temp accumulator get 0.5 */ + pswVectOut[siLoopCnt] = (int16_t) 0x4000; + else /* temp accumulator gets -0.5 */ + pswVectOut[siLoopCnt] = (int16_t) 0xc000; + + swCodeWord = shr(swCodeWord, 1); + } +} + +/*************************************************************************** + * + * FUNCTION NAME: fp_ex + * + * PURPOSE: + * + * Looks up a vector in the adaptive excitation codebook (long-term + * predictor). + * + * INPUTS: + * + * swOrigLagIn + * + * Extended resolution lag (lag * oversampling factor) + * + * pswLTPState[-147:39] + * + * Adaptive codebook (with space at end for looked up + * vector). Indicies [-147:-1] are the history, [0:39] + * are for the looked up vector. + * + * psrPitchIntrpFirBase[0:59] + * ppsrPVecIntFilt[0:9][0:5] ([tap][phase]) + * + * Interpolating FIR filter coefficients. + * + * OUTPUTS: + * + * pswLTPState[0:39] + * + * Array containing the contructed output vector + * + * RETURN VALUE: + * none + * + * DESCRIPTION: + * + * The adaptive codebook consists of the history of the excitation. + * The vector is looked up by going back into this history + * by the amount of the input lag. If the input lag is fractional, + * then the samples to be looked up are interpolated from the existing + * samples in the history. + * + * If the lag is less than the length of the vector to be generated + * (i.e. less than the subframe length), then the lag is doubled + * after the first n samples have been looked up (n = input lag). + * In this way, the samples being generated are not part of the + * codebook. This is described in section 4.1.8. + * + * REFERENCES: Sub_Clause 4.1.8.5 and 4.2.1 of GSM Recomendation 06.20 + * + * Keywords: pitch, excitation vector, long term filter, history, + * Keywords: fractional lag, get_ipjj + * + *************************************************************************/ + + + +void fp_ex(int16_t swOrigLagIn, + int16_t pswLTPState[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Temp; + int16_t swIntLag, + swRemain, + swRunningLag; + short int siSampsSoFar, + siSampsThisPass, + i, + j; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Loop: execute until all samples in the vector have been looked up */ + /*-------------------------------------------------------------------*/ + + swRunningLag = swOrigLagIn; + siSampsSoFar = 0; + while (siSampsSoFar < S_LEN) + { + + /* Get integer lag and remainder. These are used in addressing */ + /* the LTP state and the interpolating filter, respectively */ + /*--------------------------------------------------------------*/ + + get_ipjj(swRunningLag, &swIntLag, &swRemain); + + + /* Get the number of samples to look up in this pass */ + /*---------------------------------------------------*/ + + if (sub(swIntLag, S_LEN) < 0) + siSampsThisPass = swIntLag - siSampsSoFar; + else + siSampsThisPass = S_LEN - siSampsSoFar; + + /* Look up samples by interpolating (fractional lag), or copying */ + /* (integer lag). */ + /*---------------------------------------------------------------*/ + + if (swRemain == 0) + { + + /* Integer lag: copy samples from history */ + /*----------------------------------------*/ + + for (i = siSampsSoFar; i < siSampsSoFar + siSampsThisPass; i++) + pswLTPState[i] = pswLTPState[i - swIntLag]; + } + else + { + + /* Fractional lag: interpolate to get samples */ + /*--------------------------------------------*/ + + for (i = siSampsSoFar; i < siSampsSoFar + siSampsThisPass; i++) + { + + /* first tap with rounding offset */ + /*--------------------------------*/ + L_Temp = L_mac((long) 32768, + pswLTPState[i - swIntLag - P_INT_MACS / 2], + ppsrPVecIntFilt[0][swRemain]); + + for (j = 1; j < P_INT_MACS - 1; j++) + { + + L_Temp = L_mac(L_Temp, + pswLTPState[i - swIntLag - P_INT_MACS / 2 + j], + ppsrPVecIntFilt[j][swRemain]); + + } + + pswLTPState[i] = extract_h(L_mac(L_Temp, + pswLTPState[i - swIntLag + P_INT_MACS / 2 - 1], + ppsrPVecIntFilt[P_INT_MACS - 1][swRemain])); + } + } + + /* Done with this pass: update loop controls */ + /*-------------------------------------------*/ + + siSampsSoFar += siSampsThisPass; + swRunningLag = add(swRunningLag, swOrigLagIn); + } +} + +/*************************************************************************** + * + * FUNCTION NAME: g_corr1 (no scaling) + * + * PURPOSE: + * + * Calculates energy in subframe vector. Differs from g_corr1s, + * in that there the estimate of the maximum possible + * energy is < 1.0 + * + * + * INPUT: + * + * pswIn[0:39] + * A subframe vector. + * + * + * OUTPUT: + * + * *pL_out + * A int32_t containing the normalized energy + * in the input vector. + * + * RETURN: + * + * swOut + * Number of right shifts which the accumulator was + * shifted to normalize it. Negative number implies + * a left shift, and therefore an energy larger than + * 1.0. + * + * REFERENCES: Sub_Clause 4.1.10.2 and 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: energy, autocorrelation, correlation, g_corr1 + * + * + *************************************************************************/ + +int16_t g_corr1(int16_t *pswIn, int32_t *pL_out) +{ + + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_sum; + int16_t swEngyLShft; + int i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + + /* Calculate energy in subframe vector (40 samples) */ + /*--------------------------------------------------*/ + + L_sum = L_mult(pswIn[0], pswIn[0]); + for (i = 1; i < S_LEN; i++) + { + L_sum = L_mac(L_sum, pswIn[i], pswIn[i]); + } + + + + if (L_sum != 0) + { + + /* Normalize the energy in the output int32_t */ + /*---------------------------------------------*/ + + swEngyLShft = norm_l(L_sum); + *pL_out = L_shl(L_sum, swEngyLShft); /* normalize output + * int32_t */ + } + else + { + + /* Special case: energy is zero */ + /*------------------------------*/ + + *pL_out = L_sum; + swEngyLShft = 0; + } + + return (swEngyLShft); +} + +/*************************************************************************** + * + * FUNCTION NAME: g_corr1s (g_corr1 with scaling) + * + * PURPOSE: + * + * Calculates energy in subframe vector. Differs from g_corr1, + * in that there is an estimate of the maximum possible energy in the + * vector. + * + * INPUT: + * + * pswIn[0:39] + * A subframe vector. + * + * swEngyRShft + * + * Number of right shifts to apply to the vectors energy + * to ensure that it remains less than 1.0 + * (swEngyRShft is always positive or zero) + * + * OUTPUT: + * + * *pL_out + * A int32_t containing the normalized energy + * in the input vector. + * + * RETURN: + * + * swOut + * Number of right shifts which the accumulator was + * shifted to normalize it. Negative number implies + * a left shift, and therefore an energy larger than + * 1.0. + * + * REFERENCES: Sub-Clause 4.1.8, 4.2.1, 4.2.2, and 4.2.4 + * of GSM Recomendation 06.20 + * + * keywords: energy, autocorrelation, correlation, g_corr1 + * + * + *************************************************************************/ + +int16_t g_corr1s(int16_t pswIn[], int16_t swEngyRShft, + int32_t *pL_out) +{ + + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_sum; + int16_t swTemp, + swEngyLShft; + int16_t swInputRShft; + + int i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + + /* Calculate energy in subframe vector (40 samples) */ + /*--------------------------------------------------*/ + + if (sub(swEngyRShft, 1) <= 0) + { + + /* use the energy shift factor, although it is an odd shift count */ + /*----------------------------------------------------------------*/ + + swTemp = shr(pswIn[0], swEngyRShft); + L_sum = L_mult(pswIn[0], swTemp); + for (i = 1; i < S_LEN; i++) + { + swTemp = shr(pswIn[i], swEngyRShft); + L_sum = L_mac(L_sum, pswIn[i], swTemp); + } + + } + else + { + + /* convert energy shift factor to an input shift factor */ + /*------------------------------------------------------*/ + + swInputRShft = shift_r(swEngyRShft, -1); + swEngyRShft = shl(swInputRShft, 1); + + swTemp = shr(pswIn[0], swInputRShft); + L_sum = L_mult(swTemp, swTemp); + for (i = 1; i < S_LEN; i++) + { + swTemp = shr(pswIn[i], swInputRShft); + L_sum = L_mac(L_sum, swTemp, swTemp); + } + } + + if (L_sum != 0) + { + + /* Normalize the energy in the output int32_t */ + /*---------------------------------------------*/ + + swTemp = norm_l(L_sum); + *pL_out = L_shl(L_sum, swTemp); /* normalize output int32_t */ + swEngyLShft = sub(swTemp, swEngyRShft); + } + else + { + + /* Special case: energy is zero */ + /*------------------------------*/ + + *pL_out = L_sum; + swEngyLShft = 0; + } + + return (swEngyLShft); +} + +/*************************************************************************** + * + * FUNCTION NAME: getSfrmLpc + * + * PURPOSE: + * + * Given frame information from past and present frame, interpolate + * (or copy) the frame based LPC coefficients into subframe + * lpc coeffs, i.e. the ones which will be used by the subframe + * as opposed to those coded and transmitted. + * + * INPUTS: + * + * siSoftInterpolation + * + * interpolate 1/0, a coded parameter. + * + * swPrevR0,swNewR0 + * + * Rq0 for the last frame and for this frame. + * These are the decoded values, not the codewords. + * + * Previous lpc coefficients from the previous frame: + * in all filters below array[0] is the t=-1 element array[9] + * t=-10 element. + * + * pswPrevFrmKs[0:9] + * + * decoded version of the rc's tx'd last frame + * + * pswPrevFrmAs[0:9] + * + * the above K's converted to A's. i.e. direct + * form coefficients. + * + * pswPrevFrmPFNum[0:9], pswPrevFrmPFDenom[0:9] + * + * numerator and denominator coefficients used in the + * postfilter + * + * Current lpc coefficients from the current frame: + * + * pswNewFrmKs[0:9], pswNewFrmAs[0:9], + * pswNewFrmPFNum[0:9], pswNewFrmPFDenom[0:9] same as above. + * + * OUTPUTS: + * + * psnsSqrtRs[0:3] + * + * a normalized number (struct NormSw) + * containing an estimate of RS for each subframe. + * (number and a shift) + * + * ppswSynthAs[0:3][0:9] + * + * filter coefficients used by the synthesis filter. + * + * ppswPFNumAs[0:3][0:9] + * + * filter coefficients used by the postfilters + * numerator. + * + * ppswPFDenomAs[0:3][0:9] + * + * filter coefficients used by postfilters denominator. + * + * RETURN VALUE: + * + * None + * + * DESCRIPTION: + * + * For interpolated subframes, the direct form coefficients + * are converted to reflection coeffiecients to check for + * filter stability. If unstable, the uninterpolated coef. + * are used for that subframe. + * + * Interpolation is described in section 4.1.6, "Soft Interpolation + * of the Spectral Parameters" + * + * REFERENCES: Sub_clause 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: soft interpolation, int_lpc, interpolate, atorc,res_eng,i_mov + * + *************************************************************************/ + +void getSfrmLpc(short int siSoftInterpolation, + int16_t swPrevR0, int16_t swNewR0, + /* last frm */ int16_t pswPrevFrmKs[], int16_t pswPrevFrmAs[], + int16_t pswPrevFrmPFNum[], + int16_t pswPrevFrmPFDenom[], + + /* this frm */ int16_t pswNewFrmKs[], int16_t pswNewFrmAs[], + int16_t pswNewFrmPFNum[], + int16_t pswNewFrmPFDenom[], + + /* output */ struct NormSw *psnsSqrtRs, + int16_t *ppswSynthAs[], int16_t *ppswPFNumAs[], + int16_t *ppswPFDenomAs[]) +{ + +/*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| +*/ + + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + short int siSfrm, + siStable, + i; + + int32_t L_Temp1, + L_Temp2; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + if (siSoftInterpolation) + { + /* yes, interpolating */ + /* ------------------ */ + + siSfrm = 0; + + siStable = interpolateCheck(pswPrevFrmKs, pswPrevFrmAs, + pswPrevFrmAs, pswNewFrmAs, + psrOldCont[siSfrm], psrNewCont[siSfrm], + swPrevR0, + &psnsSqrtRs[siSfrm], + ppswSynthAs[siSfrm]); + if (siStable) + { + + /* interpolate between direct form coefficient sets */ + /* for both numerator and denominator coefficients */ + /* assume output will be stable */ + /* ------------------------------------------------ */ + + for (i = 0; i < NP; i++) + { + L_Temp1 = L_mult(pswNewFrmPFNum[i], psrNewCont[siSfrm]); + ppswPFNumAs[siSfrm][i] = mac_r(L_Temp1, pswPrevFrmPFNum[i], + psrOldCont[siSfrm]); + L_Temp2 = L_mult(pswNewFrmPFDenom[i], psrNewCont[siSfrm]); + ppswPFDenomAs[siSfrm][i] = mac_r(L_Temp2, pswPrevFrmPFDenom[i], + psrOldCont[siSfrm]); + } + } + else + { + /* this subframe is unstable */ + /* ------------------------- */ + for (i = 0; i < NP; i++) + { + ppswPFNumAs[siSfrm][i] = pswPrevFrmPFNum[i]; + ppswPFDenomAs[siSfrm][i] = pswPrevFrmPFDenom[i]; + } + } + for (siSfrm = 1; siSfrm < N_SUB - 1; siSfrm++) + { + + siStable = interpolateCheck(pswNewFrmKs, pswNewFrmAs, + pswPrevFrmAs, pswNewFrmAs, + psrOldCont[siSfrm], psrNewCont[siSfrm], + swNewR0, + &psnsSqrtRs[siSfrm], + ppswSynthAs[siSfrm]); + if (siStable) + { + + /* interpolate between direct form coefficient sets */ + /* for both numerator and denominator coefficients */ + /* assume output will be stable */ + /* ------------------------------------------------ */ + + for (i = 0; i < NP; i++) + { + L_Temp1 = L_mult(pswNewFrmPFNum[i], psrNewCont[siSfrm]); + ppswPFNumAs[siSfrm][i] = mac_r(L_Temp1, pswPrevFrmPFNum[i], + psrOldCont[siSfrm]); + L_Temp2 = L_mult(pswNewFrmPFDenom[i], psrNewCont[siSfrm]); + ppswPFDenomAs[siSfrm][i] = mac_r(L_Temp2, pswPrevFrmPFDenom[i], + psrOldCont[siSfrm]); + } + } + else + { + /* this subframe has unstable filter coeffs, would like to + * interpolate but can not */ + /* -------------------------------------- */ + for (i = 0; i < NP; i++) + { + ppswPFNumAs[siSfrm][i] = pswNewFrmPFNum[i]; + ppswPFDenomAs[siSfrm][i] = pswNewFrmPFDenom[i]; + } + } + } + /* the last subframe never interpolate */ + /* ----------------------------------- */ + siSfrm = 3; + for (i = 0; i < NP; i++) + { + ppswPFNumAs[siSfrm][i] = pswNewFrmPFNum[i]; + ppswPFDenomAs[siSfrm][i] = pswNewFrmPFDenom[i]; + ppswSynthAs[siSfrm][i] = pswNewFrmAs[i]; + } + + res_eng(pswNewFrmKs, swNewR0, &psnsSqrtRs[siSfrm]); + + } + /* SoftInterpolation == 0 - no interpolation */ + /* ------------------------------------------ */ + else + { + siSfrm = 0; + for (i = 0; i < NP; i++) + { + ppswPFNumAs[siSfrm][i] = pswPrevFrmPFNum[i]; + ppswPFDenomAs[siSfrm][i] = pswPrevFrmPFDenom[i]; + ppswSynthAs[siSfrm][i] = pswPrevFrmAs[i]; + } + + res_eng(pswPrevFrmKs, swPrevR0, &psnsSqrtRs[siSfrm]); + + /* for subframe 1 and all subsequent sfrms, use result from new frm */ + /* ---------------------------------------------------------------- */ + + + res_eng(pswNewFrmKs, swNewR0, &psnsSqrtRs[1]); + + for (siSfrm = 1; siSfrm < N_SUB; siSfrm++) + { + + + psnsSqrtRs[siSfrm].man = psnsSqrtRs[1].man; + psnsSqrtRs[siSfrm].sh = psnsSqrtRs[1].sh; + + for (i = 0; i < NP; i++) + { + ppswPFNumAs[siSfrm][i] = pswNewFrmPFNum[i]; + ppswPFDenomAs[siSfrm][i] = pswNewFrmPFDenom[i]; + ppswSynthAs[siSfrm][i] = pswNewFrmAs[i]; + } + } + } +} + +/*************************************************************************** + * + * FUNCTION NAME: get_ipjj + * + * PURPOSE: + * + * This subroutine calculates IP, the single-resolution lag rounded + * down to the nearest integer, and JJ, the remainder when the + * extended resolution lag is divided by the oversampling factor + * + * INPUTS: + * + * swLagIn + * extended resolution lag as an integer, i.e. + * fractional lag x oversampling factor + * + * OUTPUTS: + * + * *pswIp + * fractional lag rounded down to nearest integer, IP + * + * *pswJj + * the remainder JJ + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * ip = integer[lag/OS_FCTR] + * jj = integer_round[((lag/OS_FCTR)-ip)*(OS_FCTR)] + * if the rounding caused an 'overflow' + * set remainder jj to 0 and add 'carry' to ip + * + * This routine is involved in the mechanics of fractional and + * integer LTP searchs. The LTP is described in section 5. + * + * REFERENCES: Sub-clause 4.1.8 and 4.2.2 of GSM Recomendation 06.20 + * + * KEYWORDS: lag, fractional, remainder, ip, jj, get_ipjj + * + *************************************************************************/ + +void get_ipjj(int16_t swLagIn, + int16_t *pswIp, int16_t *pswJj) +{ + +/*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| +*/ + +#define OS_FCTR_INV (int16_t)0x1555/* SW_MAX/OS_FCTR */ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Temp; + + int16_t swTemp, + swTempIp, + swTempJj; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* calculate ip */ + /* ------------ */ + + L_Temp = L_mult(OS_FCTR_INV, swLagIn); /* lag/OS_FCTR */ + swTempIp = extract_h(L_Temp); + + /* calculate jj */ + /* ------------ */ + + swTemp = extract_l(L_Temp); /* loose ip */ + swTemp = shr(swTemp, 1); /* isolate jj fraction */ + swTemp = swTemp & SW_MAX; + L_Temp = L_mult(swTemp, OS_FCTR); /* ((lag/OS_FCTR)-ip))*(OS_FCTR) */ + swTemp = round(L_Temp); /* round and pick-off jj */ + if (sub(swTemp, OS_FCTR) == 0) + { /* if 'overflow ' */ + swTempJj = 0; /* set remainder,jj to 0 */ + swTempIp = add(swTempIp, 1); /* 'carry' overflow into ip */ + } + else + { + swTempJj = swTemp; /* read-off remainder,jj */ + } + + /* return ip and jj */ + /* ---------------- */ + + *pswIp = swTempIp; + *pswJj = swTempJj; +} + +/*************************************************************************** + * + * FUNCTION NAME: interpolateCheck + * + * PURPOSE: + * + * Interpolates between direct form coefficient sets. + * Before releasing the interpolated coefficients, they are checked. + * If unstable, the "old" parameters are used. + * + * INPUTS: + * + * pswRefKs[0:9] + * decoded version of the rc's tx'd last frame + * + * pswRefCoefsA[0:9] + * above K's converted to direct form coefficients + * + * pswOldCoefsA[0:9] + * array of old Coefseters + * + * pswNewCoefsA[0:9] + * array of new Coefseters + * + * swOldPer + * amount old coefs supply to the output + * + * swNewPer + * amount new coefs supply to the output + * + * ASHIFT + * shift for reflection coef. conversion + * + * swRq + * quantized energy to use for subframe + * * + * OUTPUTS: + * + * psnsSqrtRsOut + * output pointer to sqrt(RS) normalized + * + * pswCoefOutA[0:9] + * output coefficients + * + * RETURN VALUE: + * + * siInterp_flg + * temporary subframe interpolation flag + * 0 - coef. interpolated, 1 -coef. not interpolated + * + * DESCRIPTION: + * + * For interpolated subframes, the direct form coefficients + * are converted to reflection coefficients to check for + * filter stability. If unstable, the uninterpolated coef. + * are used for that subframe. Section 4.1.6 describes + * interpolation. + * + * REFERENCES: Sub-clause 4.1.6 and 4.2.3 of GSM Recomendation 06.20 + * + * KEYWORDS: soft interpolation, int_lpc, interpolate, atorc,res_eng,i_mov + * + *************************************************************************/ + +short int interpolateCheck(int16_t pswRefKs[], + int16_t pswRefCoefsA[], + int16_t pswOldCoefsA[], int16_t pswNewCoefsA[], + int16_t swOldPer, int16_t swNewPer, + int16_t swRq, + struct NormSw *psnsSqrtRsOut, + int16_t pswCoefOutA[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t pswRcTemp[NP]; + + int32_t L_Temp; + + short int siInterp_flg, + i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Interpolation loop, NP is order of LPC filter */ + /* --------------------------------------------- */ + + for (i = 0; i < NP; i++) + { + L_Temp = L_mult(pswNewCoefsA[i], swNewPer); + pswCoefOutA[i] = mac_r(L_Temp, pswOldCoefsA[i], swOldPer); + } + + /* Convert to reflection coefficients and check stability */ + /* ------------------------------------------------------ */ + + if (aToRc(ASHIFT, pswCoefOutA, pswRcTemp) != 0) + { + + /* Unstable, use uninterpolated parameters and compute RS update the + * state with the frame data closest to this subfrm */ + /* --------------------------------------------------------- */ + + res_eng(pswRefKs, swRq, psnsSqrtRsOut); + + for (i = 0; i < NP; i++) + { + pswCoefOutA[i] = pswRefCoefsA[i]; + } + siInterp_flg = 0; + } + else + { + + /* Stable, compute RS */ + /* ------------------ */ + res_eng(pswRcTemp, swRq, psnsSqrtRsOut); + + /* Set temporary subframe interpolation flag */ + /* ----------------------------------------- */ + siInterp_flg = 1; + } + + /* Return subframe interpolation flag */ + /* ---------------------------------- */ + return (siInterp_flg); +} + +/*************************************************************************** + * + * FUNCTION NAME: lagDecode + * + * PURPOSE: + * + * The purpose of this function is to decode the lag received from the + * speech encoder into a full resolution lag for the speech decoder + * + * INPUTS: + * + * swDeltaLag + * + * lag received from channel decoder + * + * giSfrmCnt + * + * current sub-frame count + * + * swLastLag + * + * previous lag to un-delta this sub-frame's lag + * + * psrLagTbl[0:255] + * + * table used to look up full resolution lag + * + * OUTPUTS: + * + * swLastLag + * + * new previous lag for next sub-frame + * + * RETURN VALUE: + * + * swLag + * + * decoded full resolution lag + * + * DESCRIPTION: + * + * If first subframe, use lag as index to look up table directly. + * + * If it is one of the other subframes, the codeword represents a + * delta offset. The previously decoded lag is used as a starting + * point for decoding the current lag. + * + * REFERENCES: Sub-clause 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: deltalags, lookup lag + * + *************************************************************************/ + +static int16_t lagDecode(int16_t swDeltaLag) +{ + +/*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| +*/ + +#define DELTA_LEVELS_D2 DELTA_LEVELS/2 +#define MAX_LAG 0x00ff +#define MIN_LAG 0x0000 + +/*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| +*/ + + static int16_t swLastLag; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swLag; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* first sub-frame */ + /* --------------- */ + + if (giSfrmCnt == 0) + { + swLastLag = swDeltaLag; + } + + /* remaining sub-frames */ + /* -------------------- */ + + else + { + + /* get lag biased around 0 */ + /* ----------------------- */ + + swLag = sub(swDeltaLag, DELTA_LEVELS_D2); + + /* get real lag relative to last */ + /* ----------------------------- */ + + swLag = add(swLag, swLastLag); + + /* clip to max or min */ + /* ------------------ */ + + if (sub(swLag, MAX_LAG) > 0) + { + swLastLag = MAX_LAG; + } + else if (sub(swLag, MIN_LAG) < 0) + { + swLastLag = MIN_LAG; + } + else + { + swLastLag = swLag; + } + } + + /* return lag after look up */ + /* ------------------------ */ + + swLag = psrLagTbl[swLastLag]; + return (swLag); +} + +/*************************************************************************** + * + * FUNCTION NAME: lookupVq + * + * PURPOSE: + * + * The purpose of this function is to recover the reflection coeffs from + * the received LPC codewords. + * + * INPUTS: + * + * pswVqCodeWds[0:2] + * + * the codewords for each of the segments + * + * OUTPUTS: + * + * pswRCOut[0:NP-1] + * + * the decoded reflection coefficients + * + * RETURN VALUE: + * + * none. + * + * DESCRIPTION: + * + * For each segment do the following: + * setup the retrieval pointers to the correct vector + * get that vector + * + * REFERENCES: Sub-clause 4.2.3 of GSM Recomendation 06.20 + * + * KEYWORDS: vq, vectorquantizer, lpc + * + *************************************************************************/ + +static void lookupVq(int16_t pswVqCodeWds[], int16_t pswRCOut[]) +{ +/*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| +*/ + +#define LSP_MASK 0x00ff + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + short int siSeg, + siIndex, + siVector, + siVector1, + siVector2, + siWordPtr; + + int16_tRom *psrQTable; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* for each segment */ + /* ---------------- */ + + for (siSeg = 0; siSeg < QUANT_NUM_OF_TABLES; siSeg++) + { + + siVector = pswVqCodeWds[siSeg]; + siIndex = psvqIndex[siSeg].l; + + if (sub(siSeg, 2) == 0) + { /* segment 3 */ + + /* set table */ + /* --------- */ + + psrQTable = psrQuant3; + + /* set offset into table */ + /* ---------------------- */ + + siWordPtr = add(siVector, siVector); + + /* look up coeffs */ + /* -------------- */ + + siVector1 = psrQTable[siWordPtr]; + siVector2 = psrQTable[siWordPtr + 1]; + + pswRCOut[siIndex - 1] = psrSQuant[shr(siVector1, 8) & LSP_MASK]; + pswRCOut[siIndex] = psrSQuant[siVector1 & LSP_MASK]; + pswRCOut[siIndex + 1] = psrSQuant[shr(siVector2, 8) & LSP_MASK]; + pswRCOut[siIndex + 2] = psrSQuant[siVector2 & LSP_MASK]; + } + else + { /* segments 1 and 2 */ + + /* set tables */ + /* ---------- */ + + if (siSeg == 0) + { + psrQTable = psrQuant1; + } + else + { + psrQTable = psrQuant2; + + } + + /* set offset into table */ + /* --------------------- */ + + siWordPtr = add(siVector, siVector); + siWordPtr = add(siWordPtr, siVector); + siWordPtr = shr(siWordPtr, 1); + + /* look up coeffs */ + /* -------------- */ + + siVector1 = psrQTable[siWordPtr]; + siVector2 = psrQTable[siWordPtr + 1]; + + if ((siVector & 0x0001) == 0) + { + pswRCOut[siIndex - 1] = psrSQuant[shr(siVector1, 8) & LSP_MASK]; + pswRCOut[siIndex] = psrSQuant[siVector1 & LSP_MASK]; + pswRCOut[siIndex + 1] = psrSQuant[shr(siVector2, 8) & LSP_MASK]; + } + else + { + pswRCOut[siIndex - 1] = psrSQuant[siVector1 & LSP_MASK]; + pswRCOut[siIndex] = psrSQuant[shr(siVector2, 8) & LSP_MASK]; + pswRCOut[siIndex + 1] = psrSQuant[siVector2 & LSP_MASK]; + } + } + } +} + +/*************************************************************************** + * + * FUNCTION NAME: lpcFir + * + * PURPOSE: + * + * The purpose of this function is to perform direct form fir filtering + * assuming a NP order filter and given state, coefficients, and input. + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter + * + * pswInput[0:S_LEN-1] + * + * input array of points to be filtered. + * pswInput[0] is the oldest point (first to be filtered) + * pswInput[siLen-1] is the last point filtered (newest) + * + * pswCoef[0:NP-1] + * + * array of direct form coefficients + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * pswState[0:NP-1] + * + * array of the filter state following form of pswCoef + * pswState[0] = state of filter for delay n = -1 + * pswState[NP-1] = state of filter for delay n = -NP + * + * OUTPUTS: + * + * pswState[0:NP-1] + * + * updated filter state, ready to filter + * pswInput[siLen], i.e. the next point + * + * pswFiltOut[0:S_LEN-1] + * + * the filtered output + * same format as pswInput, pswFiltOut[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] += state[j]*coef[j] (state is taken from either input + * state[] or input in[] arrays) + * rescale(out[i]) + * out[i] += in[i] + * update final state array using in[] + * + * REFERENCES: Sub-clause 4.1.7 and 4.2.4 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, fir, lpcFir, inversefilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set, i_dir_mod + * + *************************************************************************/ + +void lpcFir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswState[], int16_t pswFiltOut[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Sum; + short int siStage, + siSmp; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* filter 1st sample */ + /* ----------------- */ + + /* sum past state outputs */ + /* ---------------------- */ + /* 0th coef, with rounding */ + L_Sum = L_mac(LPC_ROUND, pswState[0], pswCoef[0]); + + for (siStage = 1; siStage < NP; siStage++) + { /* remaining coefs */ + L_Sum = L_mac(L_Sum, pswState[siStage], pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswInput[0], 0x8000); + + /* save 1st output sample */ + /* ---------------------- */ + + pswFiltOut[0] = extract_h(L_Sum); + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_mac(LPC_ROUND, pswInput[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_mac(L_Sum, pswInput[siSmp - siStage - 1], pswCoef[siStage]); + } + + /* sum past states, if any */ + /* ----------------------- */ + + for (siStage = siSmp; siStage < NP; siStage++) + { + L_Sum = L_mac(L_Sum, pswState[siStage - siSmp], pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswInput[siSmp], 0x8000); + + /* save current output sample */ + /* -------------------------- */ + + pswFiltOut[siSmp] = extract_h(L_Sum); + } + + /* save final state */ + /* ---------------- */ + + for (siStage = 0; siStage < NP; siStage++) + { + pswState[siStage] = pswInput[S_LEN - siStage - 1]; + } + +} + +/*************************************************************************** + * + * FUNCTION NAME: lpcIir + * + * PURPOSE: + * + * The purpose of this function is to perform direct form IIR filtering + * assuming a NP order filter and given state, coefficients, and input + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter + * + * pswInput[0:S_LEN-1] + * + * input array of points to be filtered + * pswInput[0] is the oldest point (first to be filtered) + * pswInput[siLen-1] is the last point filtered (newest) + * + * pswCoef[0:NP-1] + * array of direct form coefficients + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * pswState[0:NP-1] + * + * array of the filter state following form of pswCoef + * pswState[0] = state of filter for delay n = -1 + * pswState[NP-1] = state of filter for delay n = -NP + * + * OUTPUTS: + * + * pswState[0:NP-1] + * + * updated filter state, ready to filter + * pswInput[siLen], i.e. the next point + * + * pswFiltOut[0:S_LEN-1] + * + * the filtered output + * same format as pswInput, pswFiltOut[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] -= state[j]*coef[j] (state is taken from either input + * state[] or prior out[] arrays) + * rescale(out[i]) + * out[i] += in[i] + * update final state array using out[] + * + * REFERENCES: Sub-clause 4.1.7 and 4.2.4 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, iir, synthesisfilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set + * + *************************************************************************/ + +void lpcIir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswState[], int16_t pswFiltOut[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Sum; + short int siStage, + siSmp; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* filter 1st sample */ + /* ----------------- */ + + /* sum past state outputs */ + /* ---------------------- */ + /* 0th coef, with rounding */ + L_Sum = L_msu(LPC_ROUND, pswState[0], pswCoef[0]); + + for (siStage = 1; siStage < NP; siStage++) + { /* remaining coefs */ + L_Sum = L_msu(L_Sum, pswState[siStage], pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswInput[0], 0x8000); + + /* save 1st output sample */ + /* ---------------------- */ + + pswFiltOut[0] = extract_h(L_Sum); + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_msu(LPC_ROUND, pswFiltOut[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_msu(L_Sum, pswFiltOut[siSmp - siStage - 1], + pswCoef[siStage]); + } + + /* sum past states, if any */ + /* ----------------------- */ + + for (siStage = siSmp; siStage < NP; siStage++) + { + L_Sum = L_msu(L_Sum, pswState[siStage - siSmp], pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswInput[siSmp], 0x8000); + + /* save current output sample */ + /* -------------------------- */ + + pswFiltOut[siSmp] = extract_h(L_Sum); + } + + /* save final state */ + /* ---------------- */ + + for (siStage = 0; siStage < NP; siStage++) + { + pswState[siStage] = pswFiltOut[S_LEN - siStage - 1]; + } +} + +/*************************************************************************** + * + * FUNCTION NAME: lpcIrZsIir + * + * PURPOSE: + * + * The purpose of this function is to calculate the impulse response + * via direct form IIR filtering with zero state assuming a NP order + * filter and given coefficients + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter + * + * pswCoef[0:NP-1] + * array of direct form coefficients + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * OUTPUTS: + * + * pswFiltOut[0:S_LEN-1] + * + * the filtered output + * same format as pswInput, pswFiltOut[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * This routine is called by getNWCoefs(). + * + * Because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] -= state[j]*coef[j] (state taken from prior output[]) + * rescale(out[i]) + * + * REFERENCES: Sub-clause 4.1.8 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, iir, synthesisfilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set + * + *************************************************************************/ + +void lpcIrZsIir(int16_t pswCoef[], int16_t pswFiltOut[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Sum; + short int siStage, + siSmp; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* output 1st sample */ + /* ----------------- */ + + pswFiltOut[0] = 0x0400; + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_msu(LPC_ROUND, pswFiltOut[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_msu(L_Sum, pswFiltOut[siSmp - siStage - 1], + pswCoef[siStage]); + } + + /* scale output */ + /* ------------ */ + + L_Sum = L_shl(L_Sum, ASHIFT); + + /* save current output sample */ + /* -------------------------- */ + + pswFiltOut[siSmp] = extract_h(L_Sum); + } +} + +/*************************************************************************** + * + * FUNCTION NAME: lpcZiIir + * + * PURPOSE: + * The purpose of this function is to perform direct form iir filtering + * with zero input assuming a NP order filter, and given state and + * coefficients + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter MUST be <= MAX_ZIS + * + * pswCoef[0:NP-1] + * + * array of direct form coefficients. + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * pswState[0:NP-1] + * + * array of the filter state following form of pswCoef + * pswState[0] = state of filter for delay n = -1 + * pswState[NP-1] = state of filter for delay n = -NP + * + * OUTPUTS: + * + * pswFiltOut[0:S_LEN-1] + * + * the filtered output + * same format as pswIn, pswFiltOut[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * The routine is called from sfrmAnalysis, and is used to let the + * LPC filters ring out. + * + * because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] -= state[j]*coef[j] (state is taken from either input + * state[] or prior output[] arrays) + * rescale(out[i]) + * + * REFERENCES: Sub-clause 4.1.7 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, iir, synthesisfilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set + * + *************************************************************************/ + +void lpcZiIir(int16_t pswCoef[], int16_t pswState[], + int16_t pswFiltOut[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Sum; + short int siStage, + siSmp; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* filter 1st sample */ + /* ----------------- */ + + /* sum past state outputs */ + /* ---------------------- */ + /* 0th coef, with rounding */ + L_Sum = L_msu(LPC_ROUND, pswState[0], pswCoef[0]); + + for (siStage = 1; siStage < NP; siStage++) + { /* remaining coefs */ + L_Sum = L_msu(L_Sum, pswState[siStage], pswCoef[siStage]); + } + + /* scale output */ + /* ------------ */ + + L_Sum = L_shl(L_Sum, ASHIFT); + + /* save 1st output sample */ + /* ---------------------- */ + + pswFiltOut[0] = extract_h(L_Sum); + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_msu(LPC_ROUND, pswFiltOut[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_msu(L_Sum, pswFiltOut[siSmp - siStage - 1], + pswCoef[siStage]); + } + + /* sum past states, if any */ + /* ----------------------- */ + + for (siStage = siSmp; siStage < NP; siStage++) + { + L_Sum = L_msu(L_Sum, pswState[siStage - siSmp], pswCoef[siStage]); + } + + /* scale output */ + /* ------------ */ + + L_Sum = L_shl(L_Sum, ASHIFT); + + /* save current output sample */ + /* -------------------------- */ + + pswFiltOut[siSmp] = extract_h(L_Sum); + } +} + +/*************************************************************************** + * + * FUNCTION NAME: lpcZsFir + * + * PURPOSE: + * The purpose of this function is to perform direct form fir filtering + * with zero state, assuming a NP order filter and given coefficients + * and non-zero input. + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter + * + * pswInput[0:S_LEN-1] + * + * input array of points to be filtered. + * pswInput[0] is the oldest point (first to be filtered) + * pswInput[siLen-1] is the last point filtered (newest) + * + * pswCoef[0:NP-1] + * + * array of direct form coefficients + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * OUTPUTS: + * + * pswFiltOut[0:S_LEN-1] + * + * the filtered output + * same format as pswInput, pswFiltOut[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * This routine is used in getNWCoefs(). See section 4.1.7. + * + * because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] += state[j]*coef[j] (state taken from in[]) + * rescale(out[i]) + * out[i] += in[i] + * + * REFERENCES: Sub-clause 4.1.7 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, fir, lpcFir, inversefilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set, i_dir_mod + * + *************************************************************************/ + +void lpcZsFir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswFiltOut[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Sum; + short int siStage, + siSmp; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* output 1st sample */ + /* ----------------- */ + + pswFiltOut[0] = pswInput[0]; + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_mac(LPC_ROUND, pswInput[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_mac(L_Sum, pswInput[siSmp - siStage - 1], + pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswInput[siSmp], 0x8000); + + /* save current output sample */ + /* -------------------------- */ + + pswFiltOut[siSmp] = extract_h(L_Sum); + } +} + +/*************************************************************************** + * + * FUNCTION NAME: lpcZsIir + * + * PURPOSE: + * + * The purpose of this function is to perform direct form IIR filtering + * with zero state, assuming a NP order filter and given coefficients + * and non-zero input. + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter + * + * pswInput[0:S_LEN-1] + * + * input array of points to be filtered + * pswInput[0] is the oldest point (first to be filtered) + * pswInput[siLen-1] is the last point filtered (newest) + * + * pswCoef[0:NP-1] + * array of direct form coefficients + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * OUTPUTS: + * + * pswFiltOut[0:S_LEN-1] + * + * the filtered output + * same format as pswInput, pswFiltOut[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * This routine is used in the subframe analysis process. It is + * called by sfrmAnalysis() and fnClosedLoop(). It is this function + * which performs the weighting of the excitation vectors. + * + * because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] -= state[j]*coef[j] (state taken from prior out[]) + * rescale(out[i]) + * out[i] += in[i] + * + * REFERENCES: Sub-clause 4.1.8.5 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, iir, synthesisfilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set + * + *************************************************************************/ + +void lpcZsIir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswFiltOut[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Sum; + short int siStage, + siSmp; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* output 1st sample */ + /* ----------------- */ + + pswFiltOut[0] = pswInput[0]; + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_msu(LPC_ROUND, pswFiltOut[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_msu(L_Sum, pswFiltOut[siSmp - siStage - 1], + pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswInput[siSmp], 0x8000); + + /* save current output sample */ + /* -------------------------- */ + + pswFiltOut[siSmp] = extract_h(L_Sum); + } +} + +/*************************************************************************** + * + * FUNCTION NAME: lpcZsIirP + * + * PURPOSE: + * + * The purpose of this function is to perform direct form iir filtering + * with zero state, assuming a NP order filter and given coefficients + * and input + * + * INPUTS: + * + * NP + * order of the lpc filter + * + * S_LEN + * number of samples to filter + * + * pswCommonIO[0:S_LEN-1] + * + * input array of points to be filtered + * pswCommonIO[0] is oldest point (first to be filtered) + * pswCommonIO[siLen-1] is last point filtered (newest) + * + * pswCoef[0:NP-1] + * array of direct form coefficients + * pswCoef[0] = coeff for delay n = -1 + * pswCoef[NP-1] = coeff for delay n = -NP + * + * ASHIFT + * number of shifts input A's have been shifted down by + * + * LPC_ROUND + * rounding constant + * + * OUTPUTS: + * + * pswCommonIO[0:S_LEN-1] + * + * the filtered output + * pswCommonIO[0] is oldest point + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * This function is called by geNWCoefs(). See section 4.1.7. + * + * because of the default sign of the coefficients the + * formula for the filter is : + * i=0, i < S_LEN + * out[i] = rounded(state[i]*coef[0]) + * j=1, j < NP + * out[i] += state[j]*coef[j] (state taken from prior out[]) + * rescale(out[i]) + * out[i] += in[i] + * + * REFERENCES: Sub-clause 4.1.7 of GSM Recomendation 06.20 + * + * KEYWORDS: lpc, directform, iir, synthesisfilter, lpcFilt + * KEYWORDS: dirForm, dir_mod, dir_clr, dir_neg, dir_set + * + *************************************************************************/ + +void lpcZsIirP(int16_t pswCommonIO[], int16_t pswCoef[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Sum; + short int siStage, + siSmp; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* filter remaining samples */ + /* ------------------------ */ + + for (siSmp = 1; siSmp < S_LEN; siSmp++) + { + + /* sum past outputs */ + /* ---------------- */ + /* 0th coef, with rounding */ + L_Sum = L_mac(LPC_ROUND, pswCommonIO[siSmp - 1], pswCoef[0]); + /* remaining coefs */ + for (siStage = 1; ((0 < (siSmp - siStage)) && siStage < NP); siStage++) + { + L_Sum = L_mac(L_Sum, pswCommonIO[siSmp - siStage - 1], + pswCoef[siStage]); + } + + /* add input to partial output */ + /* --------------------------- */ + + L_Sum = L_shl(L_Sum, ASHIFT); + L_Sum = L_msu(L_Sum, pswCommonIO[siSmp], 0x8000); + + /* save current output sample */ + /* -------------------------- */ + + pswCommonIO[siSmp] = extract_h(L_Sum); + } +} + +/************************************************************************** + * + * FUNCTION NAME: pitchPreFilt + * + * PURPOSE: + * + * Performs pitch pre-filter on excitation in speech decoder. + * + * INPUTS: + * + * pswExcite[0:39] + * + * Synthetic residual signal to be filtered, a subframe- + * length vector. + * + * ppsrPVecIntFilt[0:9][0:5] ([tap][phase]) + * + * Interpolation filter coefficients. + * + * ppsrSqtrP0[0:2][0:31] ([voicing level-1][gain code]) + * + * Sqrt(P0) look-up table, used to determine pitch + * pre-filtering coefficient. + * + * swRxGsp0 + * + * Coded value from gain quantizer, used to look up + * sqrt(P0). + * + * swRxLag + * + * Full-resolution lag value (fractional lag * + * oversampling factor), used to index pitch pre-filter + * state. + * + * swUvCode + * + * Coded voicing level, used to distinguish between + * voiced and unvoiced conditions, and to look up + * sqrt(P0). + * + * swSemiBeta + * + * The gain applied to the adaptive codebook excitation + * (long-term predictor excitation) limited to a maximum + * of 1.0, used to determine the pitch pre-filter + * coefficient. + * + * snsSqrtRs + * + * The estimate of the energy in the residual, used only + * for scaling. + * + * OUTPUTS: + * + * pswExciteOut[0:39] + * + * The output pitch pre-filtered excitation. + * + * pswPPreState[0:44] + * + * Contains the state of the pitch pre-filter + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * If the voicing mode for the frame is unvoiced, then the pitch pre- + * filter state is updated with the input excitation, and the input + * excitation is copied to the output. + * + * If voiced: first the energy in the input excitation is calculated. + * Then, the coefficient of the pitch pre-filter is obtained: + * + * PpfCoef = POST_EPSILON * min(beta, sqrt(P0)). + * + * Then, the pitch pre-filter is performed: + * + * ex_p(n) = ex(n) + PpfCoef * ex_p(n-L) + * + * The ex_p(n-L) sample is interpolated from the surrounding samples, + * even for integer values of L. + * + * Note: The coefficients of the interpolating filter are multiplied + * by PpfCoef, rather multiplying ex_p(n_L) after interpolation. + * + * Finally, the energy in the output excitation is calculated, and + * automatic gain control is applied to the output signal so that + * its energy matches the original. + * + * The pitch pre-filter is described in section 4.2.2. + * + * REFERENCES: Sub-clause 4.2.2 of GSM Recomendation 06.20 + * + * KEYWORDS: prefilter, pitch, pitchprefilter, excitation, residual + * + *************************************************************************/ + +static void pitchPreFilt(int16_t pswExcite[], + int16_t swRxGsp0, + int16_t swRxLag, int16_t swUvCode, + int16_t swSemiBeta, struct NormSw snsSqrtRs, + int16_t pswExciteOut[], + int16_t pswPPreState[]) +{ + +/*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| +*/ + +#define POST_EPSILON 0x2666 + +/*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| +*/ + + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_1, + L_OrigEnergy; + + int16_t swScale, + swSqrtP0, + swIntLag, + swRemain, + swEnergy, + pswInterpCoefs[P_INT_MACS]; + + short int i, + j; + + struct NormSw snsOrigEnergy; + + int16_t *pswPPreCurr = &pswPPreState[LTP_LEN]; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Initialization */ + /*----------------*/ + + swEnergy = 0; + + /* Check voicing level */ + /*---------------------*/ + + if (swUvCode == 0) + { + + /* Unvoiced: perform one subframe of delay on state, copy input to */ + /* state, copy input to output (if not same) */ + /*-----------------------------------------------------------------*/ + + for (i = 0; i < LTP_LEN - S_LEN; i++) + pswPPreState[i] = pswPPreState[i + S_LEN]; + + for (i = 0; i < S_LEN; i++) + pswPPreState[i + LTP_LEN - S_LEN] = pswExcite[i]; + + if (pswExciteOut != pswExcite) + { + + for (i = 0; i < S_LEN; i++) + pswExciteOut[i] = pswExcite[i]; + } + } + else + { + + /* Voiced: calculate energy in input, filter, calculate energy in */ + /* output, scale */ + /*----------------------------------------------------------------*/ + + /* Get energy in input excitation vector */ + /*---------------------------------------*/ + + swEnergy = add(negate(shl(snsSqrtRs.sh, 1)), 3); + + if (swEnergy > 0) + { + + /* High-energy residual: scale input vector during energy */ + /* calculation. The shift count + 1 of the energy of the */ + /* residual estimate is used as an estimate of the shift */ + /* count needed for the excitation energy */ + /*--------------------------------------------------------*/ + + + snsOrigEnergy.sh = g_corr1s(pswExcite, swEnergy, &L_OrigEnergy); + snsOrigEnergy.man = round(L_OrigEnergy); + + } + else + { + + /* set shift count to zero for AGC later */ + /*---------------------------------------*/ + + swEnergy = 0; + + /* Lower-energy residual: no overflow protection needed */ + /*------------------------------------------------------*/ + + L_OrigEnergy = 0; + for (i = 0; i < S_LEN; i++) + { + + L_OrigEnergy = L_mac(L_OrigEnergy, pswExcite[i], pswExcite[i]); + } + + snsOrigEnergy.sh = norm_l(L_OrigEnergy); + snsOrigEnergy.man = round(L_shl(L_OrigEnergy, snsOrigEnergy.sh)); + } + + /* Determine pitch pre-filter coefficient, and scale the appropriate */ + /* phase of the interpolating filter by it */ + /*-------------------------------------------------------------------*/ + + swSqrtP0 = ppsrSqrtP0[swUvCode - 1][swRxGsp0]; + + if (sub(swSqrtP0, swSemiBeta) > 0) + swScale = swSemiBeta; + else + swScale = swSqrtP0; + + swScale = mult_r(POST_EPSILON, swScale); + + get_ipjj(swRxLag, &swIntLag, &swRemain); + + for (i = 0; i < P_INT_MACS; i++) + pswInterpCoefs[i] = mult_r(ppsrPVecIntFilt[i][swRemain], swScale); + + /* Perform filter */ + /*----------------*/ + + for (i = 0; i < S_LEN; i++) + { + + L_1 = L_deposit_h(pswExcite[i]); + + for (j = 0; j < P_INT_MACS - 1; j++) + { + + L_1 = L_mac(L_1, pswPPreCurr[i - swIntLag - P_INT_MACS / 2 + j], + pswInterpCoefs[j]); + } + + pswPPreCurr[i] = mac_r(L_1, + pswPPreCurr[i - swIntLag + P_INT_MACS / 2 - 1], + pswInterpCoefs[P_INT_MACS - 1]); + } + + /* Get energy in filtered vector, determine automatic-gain-control */ + /* scale factor */ + /*-----------------------------------------------------------------*/ + + swScale = agcGain(pswPPreCurr, snsOrigEnergy, swEnergy); + + /* Scale filtered vector by AGC, put out. NOTE: AGC scale returned */ + /* by routine above is divided by two, hence the shift below */ + /*------------------------------------------------------------------*/ + + for (i = 0; i < S_LEN; i++) + { + + L_1 = L_mult(pswPPreCurr[i], swScale); + L_1 = L_shl(L_1, 1); + pswExciteOut[i] = round(L_1); + } + + /* Update pitch pre-filter state */ + /*-------------------------------*/ + + for (i = 0; i < LTP_LEN; i++) + pswPPreState[i] = pswPPreState[i + S_LEN]; + } +} + +/*************************************************************************** + * + * FUNCTION NAME: r0BasedEnergyShft + * + * PURPOSE: + * + * Given an R0 voicing level, find the number of shifts to be + * performed on the energy to ensure that the subframe energy does + * not overflow. example if energy can maximally take the value + * 4.0, then 2 shifts are required. + * + * INPUTS: + * + * swR0Index + * R0 codeword (0-0x1f) + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swShiftDownSignal + * + * number of right shifts to apply to energy (0..6) + * + * DESCRIPTION: + * + * Based on the R0, the average frame energy, we can get an + * upper bound on the energy any one subframe can take on. + * Using this upper bound we can calculate what right shift is + * needed to ensure an unsaturated output out of a subframe + * energy calculation (g_corr). + * + * REFERENCES: Sub-clause 4.1.9 and 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: spectral postfilter + * + *************************************************************************/ + +int16_t r0BasedEnergyShft(int16_t swR0Index) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swShiftDownSignal; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + if (sub(swR0Index, 26) <= 0) + { + if (sub(swR0Index, 23) <= 0) + { + if (sub(swR0Index, 21) <= 0) + swShiftDownSignal = 0; /* r0 [0, 21] */ + else + swShiftDownSignal = 1; /* r0 [22, 23] */ + } + else + { + if (sub(swR0Index, 24) <= 0) + swShiftDownSignal = 2; /* r0 [23, 24] */ + else + swShiftDownSignal = 3; /* r0 [24, 26] */ + } + } + else + { /* r0 index > 26 */ + if (sub(swR0Index, 28) <= 0) + { + swShiftDownSignal = 4; /* r0 [26, 28] */ + } + else + { + if (sub(swR0Index, 29) <= 0) + swShiftDownSignal = 5; /* r0 [28, 29] */ + else + swShiftDownSignal = 6; /* r0 [29, 31] */ + } + } + if (sub(swR0Index, 18) > 0) + swShiftDownSignal = add(swShiftDownSignal, 2); + + return (swShiftDownSignal); +} + +/*************************************************************************** + * + * FUNCTION NAME: rcToADp + * + * PURPOSE: + * + * This subroutine computes a vector of direct form LPC filter + * coefficients, given an input vector of reflection coefficients. + * Double precision is used internally, but 16 bit direct form + * filter coefficients are returned. + * + * INPUTS: + * + * NP + * order of the LPC filter (global constant) + * + * swAscale + * The multiplier which scales down the direct form + * filter coefficients. + * + * pswRc[0:NP-1] + * The input vector of reflection coefficients. + * + * OUTPUTS: + * + * pswA[0:NP-1] + * Array containing the scaled down direct form LPC + * filter coefficients. + * + * RETURN VALUE: + * + * siLimit + * 1 if limiting occured in computation, 0 otherwise. + * + * DESCRIPTION: + * + * This function performs the conversion from reflection coefficients + * to direct form LPC filter coefficients. The direct form coefficients + * are scaled by multiplication by swAscale. NP, the filter order is 10. + * The a's and rc's each have NP elements in them. Double precision + * calculations are used internally. + * + * The equations are: + * for i = 0 to NP-1{ + * + * a(i)(i) = rc(i) (scaling by swAscale occurs here) + * + * for j = 0 to i-1 + * a(i)(j) = a(i-1)(j) + rc(i)*a(i-1)(i-j-1) + * } + * + * See page 443, of + * "Digital Processing of Speech Signals" by L.R. Rabiner and R.W. + * Schafer; Prentice-Hall; Englewood Cliffs, NJ (USA). 1978. + * + * REFERENCES: Sub-clause 4.1.7 and 4.2.3 of GSM Recomendation 06.20 + * + * KEYWORDS: reflectioncoefficients, parcors, conversion, rctoadp, ks, as + * KEYWORDS: parcorcoefficients, lpc, flat, vectorquantization + * + *************************************************************************/ + +short rcToADp(int16_t swAscale, int16_t pswRc[], + int16_t pswA[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t pL_ASpace[NP], + pL_tmpSpace[NP], + L_temp, + *pL_A, + *pL_tmp, + *pL_swap; + + short int i, + j, /* loop counters */ + siLimit; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Initialize starting addresses for temporary buffers */ + /*-----------------------------------------------------*/ + + pL_A = pL_ASpace; + pL_tmp = pL_tmpSpace; + + /* Initialize the flag for checking if limiting has occured */ + /*----------------------------------------------------------*/ + + siLimit = 0; + + /* Compute direct form filter coefficients, pswA[0],...,pswA[9] */ + /*-------------------------------------------------------------------*/ + + for (i = 0; i < NP; i++) + { + + pL_tmp[i] = L_mult(swAscale, pswRc[i]); + for (j = 0; j <= i - 1; j++) + { + L_temp = L_mpy_ls(pL_A[i - j - 1], pswRc[i]); + pL_tmp[j] = L_add(L_temp, pL_A[j]); + siLimit |= isLwLimit(pL_tmp[j]); + } + if (i != NP - 1) + { + /* Swap swA and swTmp buffers */ + + pL_swap = pL_tmp; + pL_tmp = pL_A; + pL_A = pL_swap; + } + } + + for (i = 0; i < NP; i++) + { + pswA[i] = round(pL_tmp[i]); + siLimit |= isSwLimit(pswA[i]); + } + return (siLimit); +} + +/*************************************************************************** + * + * FUNCTION NAME: rcToCorrDpL + * + * PURPOSE: + * + * This subroutine computes an autocorrelation vector, given a vector + * of reflection coefficients as an input. Double precision calculations + * are used internally, and a double precision (int32_t) + * autocorrelation sequence is returned. + * + * INPUTS: + * + * NP + * LPC filter order passed in as a global constant. + * + * swAshift + * Number of right shifts to be applied to the + * direct form filter coefficients being computed + * as an intermediate step to generating the + * autocorrelation sequence. + * + * swAscale + * A multiplicative scale factor corresponding to + * swAshift; i.e. swAscale = 2 ^(-swAshift). + * + * pswRc[0:NP-1] + * An input vector of reflection coefficients. + * + * OUTPUTS: + * + * pL_R[0:NP] + * An output int32_t array containing the + * autocorrelation vector where + * pL_R[0] = 0x7fffffff; (i.e., ~1.0). + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * The algorithm used for computing the correlation sequence is + * described on page 232 of the book "Linear Prediction of Speech", + * by J.D. Markel and A.H. Gray, Jr.; Springer-Verlag, Berlin, + * Heidelberg, New York, 1976. + * + * REFERENCES: Sub_Clause 4.1.4 and 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: normalized autocorrelation, reflection coefficients + * KEYWORDS: conversion + * + **************************************************************************/ + +void rcToCorrDpL(int16_t swAshift, int16_t swAscale, + int16_t pswRc[], int32_t pL_R[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t pL_ASpace[NP], + pL_tmpSpace[NP], + L_temp, + L_sum, + *pL_A, + *pL_tmp, + *pL_swap; + + short int i, + j; /* loop control variables */ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Set R[0] = 0x7fffffff, (i.e., R[0] = 1.0) */ + /*-------------------------------------------*/ + + pL_R[0] = LW_MAX; + + /* Assign an address onto each of the two temporary buffers */ + /*----------------------------------------------------------*/ + + pL_A = pL_ASpace; + pL_tmp = pL_tmpSpace; + + /* Compute correlations R[1],...,R[10] */ + /*------------------------------------*/ + + for (i = 0; i < NP; i++) + { + + /* Compute, as an intermediate step, the filter coefficients for */ + /* for an i-th order direct form filter (pL_tmp[j],j=0,i) */ + /*---------------------------------------------------------------*/ + + pL_tmp[i] = L_mult(swAscale, pswRc[i]); + for (j = 0; j <= i - 1; j++) + { + L_temp = L_mpy_ls(pL_A[i - j - 1], pswRc[i]); + pL_tmp[j] = L_add(L_temp, pL_A[j]); + } + + /* Swap pL_A and pL_tmp buffers */ + /*------------------------------*/ + + pL_swap = pL_A; + pL_A = pL_tmp; + pL_tmp = pL_swap; + + /* Given the direct form filter coefficients for an i-th order filter */ + /* and the autocorrelation vector computed up to and including stage i */ + /* compute the autocorrelation coefficient R[i+1] */ + /*---------------------------------------------------------------------*/ + + L_temp = L_mpy_ll(pL_A[0], pL_R[i]); + L_sum = L_negate(L_temp); + + for (j = 1; j <= i; j++) + { + L_temp = L_mpy_ll(pL_A[j], pL_R[i - j]); + L_sum = L_sub(L_sum, L_temp); + } + pL_R[i + 1] = L_shl(L_sum, swAshift); + + } +} + +/*************************************************************************** + * + * FUNCTION NAME: res_eng + * + * PURPOSE: + * + * Calculates square root of subframe residual energy estimate: + * + * sqrt( R(0)(1-k1**2)...(1-k10**2) ) + * + * INPUTS: + * + * pswReflecCoefIn[0:9] + * + * Array of reflection coeffcients. + * + * swRq + * + * Subframe energy = sqrt(frame_energy * S_LEN/2**S_SH) + * (quantized). + * + * OUTPUTS: + * + * psnsSqrtRsOut + * + * (Pointer to) the output residual energy estimate. + * + * RETURN VALUE: + * + * The shift count of the normalized residual energy estimate, as int. + * + * DESCRIPTION: + * + * First, the canonic product of the (1-ki**2) terms is calculated + * (normalizations are done to maintain precision). Also, a factor of + * 2**S_SH is applied to the product to offset this same factor in the + * quantized square root of the subframe energy. + * + * Then the product is square-rooted, and multiplied by the quantized + * square root of the subframe energy. This combined product is put + * out as a normalized fraction and shift count (mantissa and exponent). + * + * REFERENCES: Sub-clause 4.1.7 and 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: residualenergy, res_eng, rs + * + *************************************************************************/ + +void res_eng(int16_t pswReflecCoefIn[], int16_t swRq, + struct NormSw *psnsSqrtRsOut) +{ +/*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| +*/ + +#define S_SH 6 /* ceiling(log2(S_LEN)) */ +#define MINUS_S_SH -S_SH + + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Product, + L_Shift, + L_SqrtResEng; + + int16_t swPartialProduct, + swPartialProductShift, + swTerm, + swShift, + swSqrtPP, + swSqrtPPShift, + swSqrtResEng, + swSqrtResEngShift; + + short int i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Form canonic product, maintain precision and shift count */ + /*----------------------------------------------------------*/ + + /* (Start off with unity product (actually -1), and shift offset) */ + /*----------------------------------------------------------------*/ + swPartialProduct = SW_MIN; + swPartialProductShift = MINUS_S_SH; + + for (i = 0; i < NP; i++) + { + + /* Get next (-1 + k**2) term, form partial canonic product */ + /*---------------------------------------------------------*/ + + + swTerm = mac_r(LW_MIN, pswReflecCoefIn[i], pswReflecCoefIn[i]); + + L_Product = L_mult(swTerm, swPartialProduct); + + /* Normalize partial product, round */ + /*----------------------------------*/ + + swShift = norm_s(extract_h(L_Product)); + swPartialProduct = round(L_shl(L_Product, swShift)); + swPartialProductShift = add(swPartialProductShift, swShift); + } + + /* Correct sign of product, take square root */ + /*-------------------------------------------*/ + + swPartialProduct = abs_s(swPartialProduct); + + swSqrtPP = sqroot(L_deposit_h(swPartialProduct)); + + L_Shift = L_shr(L_deposit_h(swPartialProductShift), 1); + + swSqrtPPShift = extract_h(L_Shift); + + if (extract_l(L_Shift) != 0) + { + + /* Odd exponent: shr above needs to be compensated by multiplying */ + /* mantissa by sqrt(0.5) */ + /*----------------------------------------------------------------*/ + + swSqrtPP = mult_r(swSqrtPP, SQRT_ONEHALF); + } + + /* Form final product, the residual energy estimate, and do final */ + /* normalization */ + /*----------------------------------------------------------------*/ + + L_SqrtResEng = L_mult(swRq, swSqrtPP); + + swShift = norm_l(L_SqrtResEng); + swSqrtResEng = round(L_shl(L_SqrtResEng, swShift)); + swSqrtResEngShift = add(swSqrtPPShift, swShift); + + /* Return */ + /*--------*/ + psnsSqrtRsOut->man = swSqrtResEng; + psnsSqrtRsOut->sh = swSqrtResEngShift; + + return; +} + +/*************************************************************************** + * + * FUNCTION NAME: rs_rr + * + * PURPOSE: + * + * Calculates sqrt(RS/R(x,x)) using floating point format, + * where RS is the approximate residual energy in a given + * subframe and R(x,x) is the power in each long term + * predictor vector or in each codevector. + * Used in the joint optimization of the gain and the long + * term predictor coefficient. + * + * INPUTS: + * + * pswExcitation[0:39] - excitation signal array + * snsSqrtRs - structure sqrt(RS) normalized with mantissa and shift + * + * OUTPUTS: + * + * snsSqrtRsRr - structure sqrt(RS/R(x,x)) with mantissa and shift + * + * RETURN VALUE: + * + * None + * + * DESCRIPTION: + * + * Implemented as sqrt(RS)/sqrt(R(x,x)) where both sqrts + * are stored normalized (0.5<=x<1.0) and the associated + * shift. See section 4.1.11.1 for details + * + * REFERENCES: Sub-clause 4.1.11.1 and 4.2.1 of GSM + * Recomendation 06.20 + * + * KEYWORDS: rs_rr, sqroot + * + *************************************************************************/ + +void rs_rr(int16_t pswExcitation[], struct NormSw snsSqrtRs, + struct NormSw *snsSqrtRsRr) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int32_t L_Temp; + int16_t swTemp, + swTemp2, + swEnergy, + swNormShift, + swShift; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + swEnergy = sub(shl(snsSqrtRs.sh, 1), 3); /* shift*2 + margin == + * energy. */ + + + if (swEnergy < 0) + { + + /* High-energy residual: scale input vector during energy */ + /* calculation. The shift count of the energy of the */ + /* residual estimate is used as an estimate of the shift */ + /* count needed for the excitation energy */ + /*--------------------------------------------------------*/ + + swNormShift = g_corr1s(pswExcitation, negate(swEnergy), &L_Temp); + + } + else + { + + /* Lower-energy residual: no overflow protection needed */ + /*------------------------------------------------------*/ + + swNormShift = g_corr1(pswExcitation, &L_Temp); + } + + /* Compute single precision square root of energy sqrt(R(x,x)) */ + /* ----------------------------------------------------------- */ + swTemp = sqroot(L_Temp); + + /* If odd no. of shifts compensate by sqrt(0.5) */ + /* -------------------------------------------- */ + if (swNormShift & 1) + { + + /* Decrement no. of shifts in accordance with sqrt(0.5) */ + /* ---------------------------------------------------- */ + swNormShift = sub(swNormShift, 1); + + /* sqrt(R(x,x) = sqrt(R(x,x)) * sqrt(0.5) */ + /* -------------------------------------- */ + L_Temp = L_mult(0x5a82, swTemp); + } + else + { + L_Temp = L_deposit_h(swTemp); + } + + /* Normalize again and update shifts */ + /* --------------------------------- */ + swShift = norm_l(L_Temp); + swNormShift = add(shr(swNormShift, 1), swShift); + L_Temp = L_shl(L_Temp, swShift); + + /* Shift sqrt(RS) to make sure less than divisor */ + /* --------------------------------------------- */ + swTemp = shr(snsSqrtRs.man, 1); + + /* Divide sqrt(RS)/sqrt(R(x,x)) */ + /* ---------------------------- */ + swTemp2 = divide_s(swTemp, round(L_Temp)); + + /* Calculate shift for division, compensate for shift before division */ + /* ------------------------------------------------------------------ */ + swNormShift = sub(snsSqrtRs.sh, swNormShift); + swNormShift = sub(swNormShift, 1); + + /* Normalize and get no. of shifts */ + /* ------------------------------- */ + swShift = norm_s(swTemp2); + snsSqrtRsRr->sh = add(swNormShift, swShift); + snsSqrtRsRr->man = shl(swTemp2, swShift); + +} + +/*************************************************************************** + * + * FUNCTION NAME: rs_rrNs + * + * PURPOSE: + * + * Calculates sqrt(RS/R(x,x)) using floating point format, + * where RS is the approximate residual energy in a given + * subframe and R(x,x) is the power in each long term + * predictor vector or in each codevector. + * + * Used in the joint optimization of the gain and the long + * term predictor coefficient. + * + * INPUTS: + * + * pswExcitation[0:39] - excitation signal array + * snsSqrtRs - structure sqrt(RS) normalized with mantissa and shift + * + * OUTPUTS: + * + * snsSqrtRsRr - structure sqrt(RS/R(x,x)) with mantissa and shift + * + * RETURN VALUE: + * + * None + * + * DESCRIPTION: + * + * Implemented as sqrt(RS)/sqrt(R(x,x)) where both sqrts + * are stored normalized (0.5<=x<1.0) and the associated + * shift. + * + * REFERENCES: Sub-clause 4.1.11.1 and 4.2.1 of GSM + * Recomendation 06.20 + * + * KEYWORDS: rs_rr, sqroot + * + *************************************************************************/ + +void rs_rrNs(int16_t pswExcitation[], struct NormSw snsSqrtRs, + struct NormSw *snsSqrtRsRr) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int32_t L_Temp; + int16_t swTemp, + swTemp2, + swNormShift, + swShift; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Lower-energy residual: no overflow protection needed */ + /*------------------------------------------------------*/ + + swNormShift = g_corr1(pswExcitation, &L_Temp); + + + /* Compute single precision square root of energy sqrt(R(x,x)) */ + /* ----------------------------------------------------------- */ + swTemp = sqroot(L_Temp); + + /* If odd no. of shifts compensate by sqrt(0.5) */ + /* -------------------------------------------- */ + if (swNormShift & 1) + { + + /* Decrement no. of shifts in accordance with sqrt(0.5) */ + /* ---------------------------------------------------- */ + swNormShift = sub(swNormShift, 1); + + /* sqrt(R(x,x) = sqrt(R(x,x)) * sqrt(0.5) */ + /* -------------------------------------- */ + L_Temp = L_mult(0x5a82, swTemp); + } + else + { + L_Temp = L_deposit_h(swTemp); + } + + /* Normalize again and update shifts */ + /* --------------------------------- */ + + swShift = norm_l(L_Temp); + swNormShift = add(shr(swNormShift, 1), swShift); + L_Temp = L_shl(L_Temp, swShift); + + /* Shift sqrt(RS) to make sure less than divisor */ + /* --------------------------------------------- */ + swTemp = shr(snsSqrtRs.man, 1); + + /* Divide sqrt(RS)/sqrt(R(x,x)) */ + /* ---------------------------- */ + swTemp2 = divide_s(swTemp, round(L_Temp)); + + /* Calculate shift for division, compensate for shift before division */ + /* ------------------------------------------------------------------ */ + swNormShift = sub(snsSqrtRs.sh, swNormShift); + swNormShift = sub(swNormShift, 1); + + /* Normalize and get no. of shifts */ + /* ------------------------------- */ + swShift = norm_s(swTemp2); + snsSqrtRsRr->sh = add(swNormShift, swShift); + snsSqrtRsRr->man = shl(swTemp2, swShift); + +} + + +/*************************************************************************** + * + * FUNCTION NAME: scaleExcite + * + * PURPOSE: + * + * Scale an arbitrary excitation vector (codevector or + * pitch vector) + * + * INPUTS: + * + * pswVect[0:39] - the unscaled vector. + * iGsp0Scale - an positive offset to compensate for the fact + * that GSP0 table is scaled down. + * swErrTerm - rather than a gain being passed in, (beta, gamma) + * it is calculated from this error term - either + * Gsp0[][][0] error term A or Gsp0[][][1] error + * term B. Beta is calculated from error term A, + * gamma from error term B. + * snsRS - the RS_xx appropriate to pswVect. + * + * OUTPUTS: + * + * pswScldVect[0:39] - the output, scaled excitation vector. + * + * RETURN VALUE: + * + * swGain - One of two things. Either a clamped value of 0x7fff if the + * gain's shift was > 0 or the rounded vector gain otherwise. + * + * DESCRIPTION: + * + * If gain > 1.0 then + * (do not shift gain up yet) + * partially scale vector element THEN shift and round save + * else + * shift gain correctly + * scale vector element and round save + * update state array + * + * REFERENCES: Sub-clause 4.1.10.2 and 4.2.1 of GSM + * Recomendation 06.20 + * + * KEYWORDS: excite_vl, sc_ex, excitevl, scaleexcite, codevector, p_vec, + * KEYWORDS: x_vec, pitchvector, gain, gsp0 + * + *************************************************************************/ + +int16_t scaleExcite(int16_t pswVect[], + int16_t swErrTerm, struct NormSw snsRS, + int16_t pswScldVect[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int32_t L_GainUs, + L_scaled, + L_Round_off; + int16_t swGain, + swGainUs, + swGainShift, + i, + swGainUsShft; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + + L_GainUs = L_mult(swErrTerm, snsRS.man); + swGainUsShft = norm_s(extract_h(L_GainUs)); + L_GainUs = L_shl(L_GainUs, swGainUsShft); + + swGainShift = add(swGainUsShft, snsRS.sh); + swGainShift = sub(swGainShift, GSP0_SCALE); + + + /* gain > 1.0 */ + /* ---------- */ + + if (swGainShift < 0) + { + swGainUs = round(L_GainUs); + + L_Round_off = L_shl((long) 32768, swGainShift); + + for (i = 0; i < S_LEN; i++) + { + L_scaled = L_mac(L_Round_off, swGainUs, pswVect[i]); + L_scaled = L_shr(L_scaled, swGainShift); + pswScldVect[i] = extract_h(L_scaled); + } + + if (swGainShift == 0) + swGain = swGainUs; + else + swGain = 0x7fff; + } + + /* gain < 1.0 */ + /* ---------- */ + + else + { + + /* shift down or not at all */ + /* ------------------------ */ + if (swGainShift > 0) + L_GainUs = L_shr(L_GainUs, swGainShift); + + /* the rounded actual vector gain */ + /* ------------------------------ */ + swGain = round(L_GainUs); + + /* now scale the vector (with rounding) */ + /* ------------------------------------ */ + + for (i = 0; i < S_LEN; i++) + { + L_scaled = L_mac((long) 32768, swGain, pswVect[i]); + pswScldVect[i] = extract_h(L_scaled); + } + } + return (swGain); +} + +/*************************************************************************** + * + * FUNCTION NAME: spectralPostFilter + * + * PURPOSE: + * + * Perform spectral post filter on the output of the + * synthesis filter. + * + * + * INPUT: + * + * S_LEN a global constant + * + * pswSPFIn[0:S_LEN-1] + * + * input to the routine. Unmodified + * pswSPFIn[0] is the oldest point (first to be filtered), + * pswSPFIn[iLen-1] is the last pointer filtered, + * the newest. + * + * pswNumCoef[0:NP-1],pswDenomCoef[0:NP-1] + * + * numerator and denominator + * direct form coeffs used by postfilter. + * Exactly like lpc coefficients in format. Shifted down + * by iAShift to ensure that they are < 1.0. + * + * gpswPostFiltStateNum[0:NP-1], gpswPostFiltStateDenom[0:NP-1] + * + * array of the filter state. + * Same format as coefficients: *praState = state of + * filter for delay n = -1 praState[NP] = state of + * filter for delay n = -NP These numbers are not + * shifted at all. These states are static to this + * file. + * + * OUTPUT: + * + * gpswPostFiltStateNum[0:NP-1], gpswPostFiltStateDenom[0:NP-1] + * + * See above for description. These are updated. + * + * pswSPFOut[0:S_LEN-1] + * + * same format as pswSPFIn, + * *pswSPFOut is oldest point. The filtered output. + * Note this routine can handle pswSPFOut = pswSPFIn. + * output can be the same as input. i.e. in place + * calculation. + * + * RETURN: + * + * none + * + * DESCRIPTION: + * + * find energy in input, + * perform the numerator fir + * perform the denominator iir + * perform the post emphasis + * find energy in signal, + * perform the agc using energy in and energy in signam after + * post emphasis signal + * + * The spectral postfilter is described in section 4.2.4. + * + * REFERENCES: Sub-clause 4.2.4 of GSM Recomendation 06.20 + * + * KEYWORDS: postfilter, emphasis, postemphasis, brightness, + * KEYWORDS: numerator, deminator, filtering, lpc, + * + *************************************************************************/ + +static void spectralPostFilter(int16_t pswSPFIn[], + int16_t pswNumCoef[], + int16_t pswDenomCoef[], int16_t pswSPFOut[]) +{ +/*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| +*/ + +#define AGC_COEF (int16_t)0x19a /* (1.0 - POST_AGC_COEF) + * 1.0-.9875 */ +#define POST_EMPHASIS (int16_t)0x199a /* 0.2 */ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + short int i; + + int32_t L_OrigEnergy, + L_runningGain, + L_Output; + + int16_t swAgcGain, + swRunningGain, + swTemp; + + struct NormSw snsOrigEnergy; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* calculate the energy in the input and save it */ + /*-----------------------------------------------*/ + + snsOrigEnergy.sh = g_corr1s(pswSPFIn, swEngyRShift, &L_OrigEnergy); + snsOrigEnergy.man = round(L_OrigEnergy); + + /* numerator of the postfilter */ + /*-----------------------------*/ + + lpcFir(pswSPFIn, pswNumCoef, gpswPostFiltStateNum, pswSPFOut); + + /* denominator of the postfilter */ + /*-------------------------------*/ + + lpcIir(pswSPFOut, pswDenomCoef, gpswPostFiltStateDenom, pswSPFOut); + + /* postemphasis section of postfilter */ + /*------------------------------------*/ + + for (i = 0; i < S_LEN; i++) + { + swTemp = msu_r(L_deposit_h(pswSPFOut[i]), swPostEmphasisState, + POST_EMPHASIS); + swPostEmphasisState = pswSPFOut[i]; + pswSPFOut[i] = swTemp; + } + + swAgcGain = agcGain(pswSPFOut, snsOrigEnergy, swEngyRShift); + + /* scale the speech vector */ + /*-----------------------------*/ + + swRunningGain = gswPostFiltAgcGain; + L_runningGain = L_deposit_h(gswPostFiltAgcGain); + for (i = 0; i < S_LEN; i++) + { + L_runningGain = L_msu(L_runningGain, swRunningGain, AGC_COEF); + L_runningGain = L_mac(L_runningGain, swAgcGain, AGC_COEF); + swRunningGain = extract_h(L_runningGain); + + /* now scale input with gain */ + + L_Output = L_mult(swRunningGain, pswSPFOut[i]); + pswSPFOut[i] = extract_h(L_shl(L_Output, 2)); + } + gswPostFiltAgcGain = swRunningGain; + +} + +/*************************************************************************** + * + * FUNCTION NAME: speechDecoder + * + * PURPOSE: + * The purpose of this function is to call all speech decoder + * subroutines. This is the top level routine for the speech + * decoder. + * + * INPUTS: + * + * pswParameters[0:21] + * + * pointer to this frame's parameters. See below for input + * data format. + * + * OUTPUTS: + * + * pswDecodedSpeechFrame[0:159] + * + * this frame's decoded 16 bit linear pcm frame + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * The sequence of events in the decoder, and therefore this routine + * follow a simple plan. First, the frame based parameters are + * decoded. Second, on a subframe basis, the subframe based + * parameters are decoded and the excitation is generated. Third, + * on a subframe basis, the combined and scaled excitation is + * passed through the synthesis filter, and then the pitch and + * spectral postfilters. + * + * The in-line comments for the routine speechDecoder, are very + * detailed. Here in a more consolidated form, are the main + * points. + * + * The R0 parameter is decoded using the lookup table + * psrR0DecTbl[]. The LPC codewords are looked up using lookupVQ(). + * The decoded parameters are reflection coefficients + * (pswFrmKs[]). + * + * The decoder does not use reflection coefficients directly. + * Instead it converts them to direct form coeficients. This is + * done using rcToADp(). If this conversion results in invalid + * results, the previous frames parameters are used. + * + * The direct form coeficients are used to derive the spectal + * postfilter's numerator and denominator coeficients. The + * denominators coefficients are widened, and the numerators + * coefficients are a spectrally smoothed version of the + * denominator. The smoothing is done with a_sst(). + * + * The frame based LPC coefficients are either used directly as the + * subframe coefficients, or are derived through interpolation. + * The subframe based coeffiecients are calculated in getSfrmLpc(). + * + * Based on voicing mode, the decoder will construct and scale the + * excitation in one of two ways. For the voiced mode the lag is + * decoded using lagDecode(). The fractional pitch LTP lookup is + * done by the function fp_ex(). In both voiced and unvoiced + * mode, the VSELP codewords are decoded into excitation vectors + * using b_con() and v_con(). + * + * rs_rr(), rs_rrNs(), and scaleExcite() are used to calculate + * the gamma's, codevector gains, as well as beta, the LTP vector + * gain. Description of this can be found in section 4.1.11. Once + * the vectors have been scaled and combined, the excitation is + * stored in the LTP history. + * + * The excitation, pswExcite[], passes through the pitch pre-filter + * (pitchPreFilt()). Then the harmonically enhanced excitation + * passes through the synthesis filter, lpcIir(), and finally the + * reconstructed speech passes through the spectral post-filter + * (spectalPostFilter()). The final output speech is passed back in + * the array pswDecodedSpeechFrame[]. + * + * INPUT DATA FORMAT: + * + * The format/content of the input parameters is the so called + * bit alloc format. + * + * voiced mode bit alloc format: + * ----------------------------- + * index number of bits parameter name + * 0 5 R0 + * 1 11 k1Tok3 + * 2 9 k4Tok6 + * 3 8 k7Tok10 + * 4 1 softInterpolation + * 5 2 voicingDecision + * 6 8 frameLag + * 7 9 code_1 + * 8 5 gsp0_1 + * 9 4 deltaLag_2 + * 10 9 code_2 + * 11 5 gsp0_2 + * 12 4 deltaLag_3 + * 13 9 code_3 + * 14 5 gsp0_3 + * 15 4 deltaLag_4 + * 16 9 code_4 + * 17 5 gsp0_4 + * + * 18 1 BFI + * 19 1 UFI + * 20 2 SID + * 21 1 TAF + * + * + * unvoiced mode bit alloc format: + * ------------------------------- + * + * index number of bits parameter name + * 0 5 R0 + * 1 11 k1Tok3 + * 2 9 k4Tok6 + * 3 8 k7Tok10 + * 4 1 softInterpolation + * 5 2 voicingDecision + * 6 7 code1_1 + * 7 7 code2_1 + * 8 5 gsp0_1 + * 9 7 code1_2 + * 10 7 code2_2 + * 11 5 gsp0_2 + * 12 7 code1_3 + * 13 7 code2_3 + * 14 5 gsp0_3 + * 15 7 code1_4 + * 16 7 code2_4 + * 17 5 gsp0_4 + * + * 18 1 BFI + * 19 1 UFI + * 20 2 SID + * 21 1 TAF + * + * + * REFERENCES: Sub_Clause 4.2 of GSM Recomendation 06.20 + * + * KEYWORDS: synthesis, speechdecoder, decoding + * KEYWORDS: codewords, lag, codevectors, gsp0 + * + *************************************************************************/ + +void speechDecoder(int16_t pswParameters[], + int16_t pswDecodedSpeechFrame[]) +{ + +/*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| +*/ + + static int16_t + *pswLtpStateOut = &pswLtpStateBaseDec[LTP_LEN], + pswSythAsSpace[NP * N_SUB], + pswPFNumAsSpace[NP * N_SUB], + pswPFDenomAsSpace[NP * N_SUB], + *ppswSynthAs[N_SUB] = { + &pswSythAsSpace[0], + &pswSythAsSpace[10], + &pswSythAsSpace[20], + &pswSythAsSpace[30], + }, + + *ppswPFNumAs[N_SUB] = { + &pswPFNumAsSpace[0], + &pswPFNumAsSpace[10], + &pswPFNumAsSpace[20], + &pswPFNumAsSpace[30], + }, + *ppswPFDenomAs[N_SUB] = { + &pswPFDenomAsSpace[0], + &pswPFDenomAsSpace[10], + &pswPFDenomAsSpace[20], + &pswPFDenomAsSpace[30], + }; + + static int16_tRom + psrSPFDenomWidenCf[NP] = { + 0x6000, 0x4800, 0x3600, 0x2880, 0x1E60, + 0x16C8, 0x1116, 0x0CD0, 0x099C, 0x0735, + }; + + + static int32_t L_RxPNSeed; /* DTX mode */ + static int16_t swRxDtxGsIndex; /* DTX mode */ + + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + short int i, + j, + siLagCode, + siGsp0Code, + psiVselpCw[2], + siVselpCw, + siNumBits, + siCodeBook; + + int16_t pswFrmKs[NP], + pswFrmAs[NP], + pswFrmPFNum[NP], + pswFrmPFDenom[NP], + pswPVec[S_LEN], + ppswVselpEx[2][S_LEN], + pswExcite[S_LEN], + pswPPFExcit[S_LEN], + pswSynthFiltOut[S_LEN], + swR0Index, + swLag, + swSemiBeta, + pswBitArray[MAXBITS]; + + struct NormSw psnsSqrtRs[N_SUB], + snsRs00, + snsRs11, + snsRs22; + + + int16_t swMutePermit, + swLevelMean, + swLevelMax, /* error concealment */ + swMuteFlag; /* error concealment */ + + + int16_t swTAF, + swSID, + swBfiDtx; /* DTX mode */ + int16_t swFrameType; /* DTX mode */ + + int32_t L_RxDTXGs; /* DTX mode */ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* -------------------------------------------------------------------- */ + /* do bad frame handling (error concealment) and comfort noise */ + /* insertion */ + /* -------------------------------------------------------------------- */ + + + /* This flag indicates whether muting is performed in the actual frame */ + /* ------------------------------------------------------------------- */ + swMuteFlag = 0; + + + /* This flag indicates whether muting is allowed in the actual frame */ + /* ----------------------------------------------------------------- */ + swMutePermit = 0; + + + /* frame classification */ + /* -------------------- */ + + swSID = pswParameters[20]; + swTAF = pswParameters[21]; + + swBfiDtx = pswParameters[18] | pswParameters[19]; /* BFI | UFI */ + + if ((swSID == 2) && (swBfiDtx == 0)) + swFrameType = VALIDSID; + else if ((swSID == 0) && (swBfiDtx == 0)) + swFrameType = GOODSPEECH; + else if ((swSID == 0) && (swBfiDtx != 0)) + swFrameType = UNUSABLE; + else + swFrameType = INVALIDSID; + + + /* update of decoder state */ + /* ----------------------- */ + + if (swDecoMode == SPEECH) + { + /* speech decoding mode */ + /* -------------------- */ + + if (swFrameType == VALIDSID) + swDecoMode = CNIFIRSTSID; + else if (swFrameType == INVALIDSID) + swDecoMode = CNIFIRSTSID; + else if (swFrameType == UNUSABLE) + swDecoMode = SPEECH; + else if (swFrameType == GOODSPEECH) + swDecoMode = SPEECH; + } + else + { + /* comfort noise insertion mode */ + /* ---------------------------- */ + + if (swFrameType == VALIDSID) + swDecoMode = CNICONT; + else if (swFrameType == INVALIDSID) + swDecoMode = CNICONT; + else if (swFrameType == UNUSABLE) + swDecoMode = CNIBFI; + else if (swFrameType == GOODSPEECH) + swDecoMode = SPEECH; + } + + + if (swDecoMode == SPEECH) + { + /* speech decoding mode */ + /* -------------------- */ + + /* Perform parameter concealment, depending on BFI (pswParameters[18]) */ + /* or UFI (pswParameters[19]) */ + /* ------------------------------------------------------------------- */ + para_conceal_speech_decoder(&pswParameters[18], + pswParameters, &swMutePermit); + + + /* copy the frame rate parameters */ + /* ------------------------------ */ + + swR0Index = pswParameters[0]; /* R0 Index */ + pswVq[0] = pswParameters[1]; /* LPC1 */ + pswVq[1] = pswParameters[2]; /* LPC2 */ + pswVq[2] = pswParameters[3]; /* LPC3 */ + swSi = pswParameters[4]; /* INT_LPC */ + swVoicingMode = pswParameters[5]; /* MODE */ + + + /* lookup R0 and VQ parameters */ + /* --------------------------- */ + + swR0Dec = psrR0DecTbl[swR0Index * 2]; /* R0 */ + lookupVq(pswVq, pswFrmKs); + + + /* save this frames GS values */ + /* -------------------------- */ + + for (i = 0; i < N_SUB; i++) + { + pL_RxGsHist[swRxGsHistPtr] = + ppLr_gsTable[swVoicingMode][pswParameters[(i * 3) + 8]]; + swRxGsHistPtr++; + if (swRxGsHistPtr > ((OVERHANG - 1) * N_SUB) - 1) + swRxGsHistPtr = 0; + } + + + /* DTX variables */ + /* ------------- */ + + swDtxBfiCnt = 0; + swDtxMuting = 0; + swRxDTXState = CNINTPER - 1; + + } + else + { + /* comfort noise insertion mode */ + /*----------------------------- */ + + /* copy the frame rate parameters */ + /* ------------------------------ */ + + swR0Index = pswParameters[0]; /* R0 Index */ + pswVq[0] = pswParameters[1]; /* LPC1 */ + pswVq[1] = pswParameters[2]; /* LPC2 */ + pswVq[2] = pswParameters[3]; /* LPC3 */ + swSi = 1; /* INT_LPC */ + swVoicingMode = 0; /* MODE */ + + + /* bad frame handling in comfort noise insertion mode */ + /* -------------------------------------------------- */ + + if (swDecoMode == CNIFIRSTSID) /* first SID frame */ + { + swDtxBfiCnt = 0; + swDtxMuting = 0; + swRxDTXState = CNINTPER - 1; + + if (swFrameType == VALIDSID) /* valid SID frame */ + { + swR0NewCN = psrR0DecTbl[swR0Index * 2]; + lookupVq(pswVq, pswFrmKs); + } + else if (swFrameType == INVALIDSID) /* invalid SID frame */ + { + swR0NewCN = psrR0DecTbl[swOldR0IndexDec * 2]; + swR0Index = swOldR0IndexDec; + for (i = 0; i < NP; i++) + pswFrmKs[i] = pswOldFrmKsDec[i]; + } + + } + else if (swDecoMode == CNICONT) /* SID frame detected, but */ + { /* not the first SID */ + swDtxBfiCnt = 0; + swDtxMuting = 0; + + if (swFrameType == VALIDSID) /* valid SID frame */ + { + swRxDTXState = 0; + swR0NewCN = psrR0DecTbl[swR0Index * 2]; + lookupVq(pswVq, pswFrmKs); + } + else if (swFrameType == INVALIDSID) /* invalid SID frame */ + { + if (swRxDTXState < (CNINTPER - 1)) + swRxDTXState = add(swRxDTXState, 1); + swR0Index = swOldR0IndexDec; + } + + } + else if (swDecoMode == CNIBFI) /* bad frame received in */ + { /* CNI mode */ + if (swRxDTXState < (CNINTPER - 1)) + swRxDTXState = add(swRxDTXState, 1); + swR0Index = swOldR0IndexDec; + + if (swDtxMuting == 1) + { + swOldR0IndexDec = sub(swOldR0IndexDec, 2); /* attenuate + * by 4 dB */ + if (swOldR0IndexDec < 0) + swOldR0IndexDec = 0; + + swR0Index = swOldR0IndexDec; + + swR0NewCN = psrR0DecTbl[swOldR0IndexDec * 2]; /* R0 */ + + } + + swDtxBfiCnt = add(swDtxBfiCnt, 1); + if ((swTAF == 1) && (swDtxBfiCnt >= (2 * CNINTPER + 1))) /* 25 */ + swDtxMuting = 1; + + } + + + if (swDecoMode == CNIFIRSTSID) + { + + /* the first SID frame is received */ + /* ------------------------------- */ + + /* initialize the decoders pn-generator */ + /* ------------------------------------ */ + + L_RxPNSeed = PN_INIT_SEED; + + + /* using the stored rx history, generate averaged GS */ + /* ------------------------------------------------- */ + + avgGsHistQntz(pL_RxGsHist, &L_RxDTXGs); + swRxDtxGsIndex = gsQuant(L_RxDTXGs, 0); + + } + + + /* Replace the "transmitted" subframe parameters with */ + /* synthetic ones */ + /* -------------------------------------------------- */ + + for (i = 0; i < 4; i++) + { + /* initialize the GSP0 parameter */ + pswParameters[(i * 3) + 8] = swRxDtxGsIndex; + + /* CODE1 */ + pswParameters[(i * 3) + 6] = getPnBits(7, &L_RxPNSeed); + /* CODE2 */ + pswParameters[(i * 3) + 7] = getPnBits(7, &L_RxPNSeed); + } + + + /* Interpolation of CN parameters */ + /* ------------------------------ */ + + rxInterpR0Lpc(pswOldFrmKsDec, pswFrmKs, swRxDTXState, + swDecoMode, swFrameType); + + } + + + /* ------------------- */ + /* do frame processing */ + /* ------------------- */ + + /* generate the direct form coefs */ + /* ------------------------------ */ + + if (!rcToADp(ASCALE, pswFrmKs, pswFrmAs)) + { + + /* widen direct form coefficients using the widening coefs */ + /* ------------------------------------------------------- */ + + for (i = 0; i < NP; i++) + { + pswFrmPFDenom[i] = mult_r(pswFrmAs[i], psrSPFDenomWidenCf[i]); + } + + a_sst(ASHIFT, ASCALE, pswFrmPFDenom, pswFrmPFNum); + } + else + { + + + for (i = 0; i < NP; i++) + { + pswFrmKs[i] = pswOldFrmKsDec[i]; + pswFrmAs[i] = pswOldFrmAsDec[i]; + pswFrmPFDenom[i] = pswOldFrmPFDenom[i]; + pswFrmPFNum[i] = pswOldFrmPFNum[i]; + } + } + + /* interpolate, or otherwise get sfrm reflection coefs */ + /* --------------------------------------------------- */ + + getSfrmLpc(swSi, swOldR0Dec, swR0Dec, pswOldFrmKsDec, pswOldFrmAsDec, + pswOldFrmPFNum, pswOldFrmPFDenom, pswFrmKs, pswFrmAs, + pswFrmPFNum, pswFrmPFDenom, psnsSqrtRs, ppswSynthAs, + ppswPFNumAs, ppswPFDenomAs); + + /* calculate shift for spectral postfilter */ + /* --------------------------------------- */ + + swEngyRShift = r0BasedEnergyShft(swR0Index); + + + /* ----------------------- */ + /* do sub-frame processing */ + /* ----------------------- */ + + for (giSfrmCnt = 0; giSfrmCnt < 4; giSfrmCnt++) + { + + /* copy this sub-frame's parameters */ + /* -------------------------------- */ + + if (sub(swVoicingMode, 0) == 0) + { /* unvoiced */ + psiVselpCw[0] = pswParameters[(giSfrmCnt * 3) + 6]; /* CODE_1 */ + psiVselpCw[1] = pswParameters[(giSfrmCnt * 3) + 7]; /* CODE_2 */ + siGsp0Code = pswParameters[(giSfrmCnt * 3) + 8]; /* GSP0 */ + } + else + { /* voiced */ + siLagCode = pswParameters[(giSfrmCnt * 3) + 6]; /* LAG */ + psiVselpCw[0] = pswParameters[(giSfrmCnt * 3) + 7]; /* CODE */ + siGsp0Code = pswParameters[(giSfrmCnt * 3) + 8]; /* GSP0 */ + } + + /* for voiced mode, reconstruct the pitch vector */ + /* --------------------------------------------- */ + + if (swVoicingMode) + { + + /* convert delta lag to lag and convert to fractional lag */ + /* ------------------------------------------------------ */ + + swLag = lagDecode(siLagCode); + + /* state followed by out */ + /* --------------------- */ + + fp_ex(swLag, pswLtpStateOut); + + /* extract a piece of pswLtpStateOut into newly named vector pswPVec */ + /* ----------------------------------------------------------------- */ + + for (i = 0; i < S_LEN; i++) + { + pswPVec[i] = pswLtpStateOut[i]; + } + } + + /* for unvoiced, do not reconstruct a pitch vector */ + /* ----------------------------------------------- */ + + else + { + swLag = 0; /* indicates invalid lag + * and unvoiced */ + } + + /* now work on the VSELP codebook excitation output */ + /* x_vec, x_a_vec here named ppswVselpEx[0] and [1] */ + /* ------------------------------------------------ */ + + if (swVoicingMode) + { /* voiced */ + + siNumBits = C_BITS_V; + siVselpCw = psiVselpCw[0]; + + b_con(siVselpCw, siNumBits, pswBitArray); + + v_con(pppsrVcdCodeVec[0][0], ppswVselpEx[0], pswBitArray, siNumBits); + } + + else + { /* unvoiced */ + + siNumBits = C_BITS_UV; + + for (siCodeBook = 0; siCodeBook < 2; siCodeBook++) + { + + siVselpCw = psiVselpCw[siCodeBook]; + + b_con(siVselpCw, siNumBits, (int16_t *) pswBitArray); + + v_con(pppsrUvCodeVec[siCodeBook][0], ppswVselpEx[siCodeBook], + pswBitArray, siNumBits); + } + } + + /* all excitation vectors have been created: ppswVselpEx and pswPVec */ + /* if voiced compute rs00 and rs11; if unvoiced cmpute rs11 and rs22 */ + /* ------------------------------------------------------------------ */ + + if (swLag) + { + rs_rr(pswPVec, psnsSqrtRs[giSfrmCnt], &snsRs00); + } + + rs_rrNs(ppswVselpEx[0], psnsSqrtRs[giSfrmCnt], &snsRs11); + + if (!swVoicingMode) + { + rs_rrNs(ppswVselpEx[1], psnsSqrtRs[giSfrmCnt], &snsRs22); + } + + /* now implement synthesis - combine the excitations */ + /* ------------------------------------------------- */ + + if (swVoicingMode) + { /* voiced */ + + /* scale pitch and codebook excitations and get beta */ + /* ------------------------------------------------- */ + swSemiBeta = scaleExcite(pswPVec, + pppsrGsp0[swVoicingMode][siGsp0Code][0], + snsRs00, pswPVec); + scaleExcite(ppswVselpEx[0], + pppsrGsp0[swVoicingMode][siGsp0Code][1], + snsRs11, ppswVselpEx[0]); + + /* combine the two scaled excitations */ + /* ---------------------------------- */ + for (i = 0; i < S_LEN; i++) + { + pswExcite[i] = add(pswPVec[i], ppswVselpEx[0][i]); + } + } + else + { /* unvoiced */ + + /* scale codebook excitations and set beta to 0 as not applicable */ + /* -------------------------------------------------------------- */ + swSemiBeta = 0; + scaleExcite(ppswVselpEx[0], + pppsrGsp0[swVoicingMode][siGsp0Code][0], + snsRs11, ppswVselpEx[0]); + scaleExcite(ppswVselpEx[1], + pppsrGsp0[swVoicingMode][siGsp0Code][1], + snsRs22, ppswVselpEx[1]); + + /* combine the two scaled excitations */ + /* ---------------------------------- */ + for (i = 0; i < S_LEN; i++) + { + pswExcite[i] = add(ppswVselpEx[1][i], ppswVselpEx[0][i]); + } + } + + /* now update the pitch state using the combined/scaled excitation */ + /* --------------------------------------------------------------- */ + + for (i = 0; i < LTP_LEN; i++) + { + pswLtpStateBaseDec[i] = pswLtpStateBaseDec[i + S_LEN]; + } + + /* add the current sub-frames data to the state */ + /* -------------------------------------------- */ + + for (i = -S_LEN, j = 0; j < S_LEN; i++, j++) + { + pswLtpStateOut[i] = pswExcite[j];/* add new frame at t = -S_LEN */ + } + + /* given the excitation perform pitch prefiltering */ + /* ----------------------------------------------- */ + + pitchPreFilt(pswExcite, siGsp0Code, swLag, + swVoicingMode, swSemiBeta, psnsSqrtRs[giSfrmCnt], + pswPPFExcit, pswPPreState); + + + /* Concealment on subframe signal level: */ + /* ------------------------------------- */ + level_estimator(0, &swLevelMean, &swLevelMax, + &pswDecodedSpeechFrame[giSfrmCnt * S_LEN]); + + signal_conceal_sub(pswPPFExcit, ppswSynthAs[giSfrmCnt], pswSynthFiltState, + &pswLtpStateOut[-S_LEN], &pswPPreState[LTP_LEN - S_LEN], + swLevelMean, swLevelMax, + pswParameters[19], swMuteFlagOld, + &swMuteFlag, swMutePermit); + + + /* synthesize the speech through the synthesis filter */ + /* -------------------------------------------------- */ + + lpcIir(pswPPFExcit, ppswSynthAs[giSfrmCnt], pswSynthFiltState, + pswSynthFiltOut); + + /* pass reconstructed speech through adaptive spectral postfilter */ + /* -------------------------------------------------------------- */ + + spectralPostFilter(pswSynthFiltOut, ppswPFNumAs[giSfrmCnt], + ppswPFDenomAs[giSfrmCnt], + &pswDecodedSpeechFrame[giSfrmCnt * S_LEN]); + + level_estimator(1, &swLevelMean, &swLevelMax, + &pswDecodedSpeechFrame[giSfrmCnt * S_LEN]); + + } + + /* Save muting information for next frame */ + /* -------------------------------------- */ + swMuteFlagOld = swMuteFlag; + + /* end of frame processing - save this frame's frame energy, */ + /* reflection coefs, direct form coefs, and post filter coefs */ + /* ---------------------------------------------------------- */ + + swOldR0Dec = swR0Dec; + swOldR0IndexDec = swR0Index; /* DTX mode */ + + for (i = 0; i < NP; i++) + { + pswOldFrmKsDec[i] = pswFrmKs[i]; + pswOldFrmAsDec[i] = pswFrmAs[i]; + pswOldFrmPFNum[i] = pswFrmPFNum[i]; + pswOldFrmPFDenom[i] = pswFrmPFDenom[i]; + } +} + + +/*************************************************************************** + * + * FUNCTION NAME: sqroot + * + * PURPOSE: + * + * The purpose of this function is to perform a single precision square + * root function on a int32_t + * + * INPUTS: + * + * L_SqrtIn + * input to square root function + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swSqrtOut + * output to square root function + * + * DESCRIPTION: + * + * Input assumed to be normalized + * + * The algorithm is based around a six term Taylor expansion : + * + * y^0.5 = (1+x)^0.5 + * ~= 1 + (x/2) - 0.5*((x/2)^2) + 0.5*((x/2)^3) + * - 0.625*((x/2)^4) + 0.875*((x/2)^5) + * + * Max error less than 0.08 % for normalized input ( 0.5 <= x < 1 ) + * + * REFERENCES: Sub-clause 4.1.4.1, 4.1.7, 4.1.11.1, 4.2.1, + * 4.2.2, 4.2.3 and 4.2.4 of GSM Recomendation 06.20 + * + * KEYWORDS: sqrt, squareroot, sqrt016 + * + *************************************************************************/ + +int16_t sqroot(int32_t L_SqrtIn) +{ + +/*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| +*/ + +#define PLUS_HALF 0x40000000L /* 0.5 */ +#define MINUS_ONE 0x80000000L /* -1 */ +#define TERM5_MULTIPLER 0x5000 /* 0.625 */ +#define TERM6_MULTIPLER 0x7000 /* 0.875 */ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Temp0, + L_Temp1; + + int16_t swTemp, + swTemp2, + swTemp3, + swTemp4, + swSqrtOut; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* determine 2nd term x/2 = (y-1)/2 */ + /* -------------------------------- */ + + L_Temp1 = L_shr(L_SqrtIn, 1); /* L_Temp1 = y/2 */ + L_Temp1 = L_sub(L_Temp1, PLUS_HALF); /* L_Temp1 = (y-1)/2 */ + swTemp = extract_h(L_Temp1); /* swTemp = x/2 */ + + /* add contribution of 2nd term */ + /* ---------------------------- */ + + L_Temp1 = L_sub(L_Temp1, MINUS_ONE); /* L_Temp1 = 1 + x/2 */ + + /* determine 3rd term */ + /* ------------------ */ + + L_Temp0 = L_msu(0L, swTemp, swTemp); /* L_Temp0 = -(x/2)^2 */ + swTemp2 = extract_h(L_Temp0); /* swTemp2 = -(x/2)^2 */ + L_Temp0 = L_shr(L_Temp0, 1); /* L_Temp0 = -0.5*(x/2)^2 */ + + /* add contribution of 3rd term */ + /* ---------------------------- */ + + L_Temp0 = L_add(L_Temp1, L_Temp0); /* L_Temp0 = 1 + x/2 - 0.5*(x/2)^2 */ + + /* determine 4rd term */ + /* ------------------ */ + + L_Temp1 = L_msu(0L, swTemp, swTemp2);/* L_Temp1 = (x/2)^3 */ + swTemp3 = extract_h(L_Temp1); /* swTemp3 = (x/2)^3 */ + L_Temp1 = L_shr(L_Temp1, 1); /* L_Temp1 = 0.5*(x/2)^3 */ + + /* add contribution of 4rd term */ + /* ---------------------------- */ + + /* L_Temp1 = 1 + x/2 - 0.5*(x/2)^2 + 0.5*(x/2)^3 */ + + L_Temp1 = L_add(L_Temp0, L_Temp1); + + /* determine partial 5th term */ + /* -------------------------- */ + + L_Temp0 = L_mult(swTemp, swTemp3); /* L_Temp0 = (x/2)^4 */ + swTemp4 = round(L_Temp0); /* swTemp4 = (x/2)^4 */ + + /* determine partial 6th term */ + /* -------------------------- */ + + L_Temp0 = L_msu(0L, swTemp2, swTemp3); /* L_Temp0 = (x/2)^5 */ + swTemp2 = round(L_Temp0); /* swTemp2 = (x/2)^5 */ + + /* determine 5th term and add its contribution */ + /* ------------------------------------------- */ + + /* L_Temp0 = -0.625*(x/2)^4 */ + + L_Temp0 = L_msu(0L, TERM5_MULTIPLER, swTemp4); + + /* L_Temp1 = 1 + x/2 - 0.5*(x/2)^2 + 0.5*(x/2)^3 - 0.625*(x/2)^4 */ + + L_Temp1 = L_add(L_Temp0, L_Temp1); + + /* determine 6th term and add its contribution */ + /* ------------------------------------------- */ + + /* swSqrtOut = 1 + x/2 - 0.5*(x/2)^2 + 0.5*(x/2)^3 */ + /* - 0.625*(x/2)^4 + 0.875*(x/2)^5 */ + + swSqrtOut = mac_r(L_Temp1, TERM6_MULTIPLER, swTemp2); + + /* return output */ + /* ------------- */ + + return (swSqrtOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: v_con + * + * PURPOSE: + * + * This subroutine constructs a codebook excitation + * vector from basis vectors + * + * INPUTS: + * + * pswBVects[0:siNumBVctrs*S_LEN-1] + * + * Array containing a set of basis vectors. + * + * pswBitArray[0:siNumBVctrs-1] + * + * Bit array dictating the polarity of the + * basis vectors in the output vector. + * Each element of the bit array is either -0.5 or +0.5 + * + * siNumBVctrs + * Number of bits in codeword + * + * OUTPUTS: + * + * pswOutVect[0:39] + * + * Array containing the contructed output vector + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * The array pswBitArray is used to multiply each of the siNumBVctrs + * basis vectors. The input pswBitArray[] is an array whose + * elements are +/-0.5. These multiply the VSELP basis vectors and + * when summed produce a VSELP codevector. b_con() is the function + * used to translate a VSELP codeword into pswBitArray[]. + * + * + * REFERENCES: Sub-clause 4.1.10 and 4.2.1 of GSM Recomendation 06.20 + * + * KEYWORDS: v_con, codeword, reconstruct, basis vector, excitation + * + *************************************************************************/ + +void v_con(int16_t pswBVects[], int16_t pswOutVect[], + int16_t pswBitArray[], short int siNumBVctrs) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Temp; + + short int siSampleCnt, + siCVectCnt; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Sample loop */ + /*--------------*/ + for (siSampleCnt = 0; siSampleCnt < S_LEN; siSampleCnt++) + { + + /* First element of output vector */ + L_Temp = L_mult(pswBitArray[0], pswBVects[0 * S_LEN + siSampleCnt]); + + /* Construct output vector */ + /*-------------------------*/ + for (siCVectCnt = 1; siCVectCnt < siNumBVctrs; siCVectCnt++) + { + L_Temp = L_mac(L_Temp, pswBitArray[siCVectCnt], + pswBVects[siCVectCnt * S_LEN + siSampleCnt]); + } + + /* store the output vector sample */ + /*--------------------------------*/ + L_Temp = L_shl(L_Temp, 1); + pswOutVect[siSampleCnt] = extract_h(L_Temp); + } +} diff --git a/src/libs/gsmhr/gsmhr_sp_dec.h b/src/libs/gsmhr/gsmhr_sp_dec.h new file mode 100644 index 00000000..2dfd730a --- /dev/null +++ b/src/libs/gsmhr/gsmhr_sp_dec.h @@ -0,0 +1,100 @@ +#ifndef __SP_DEC +#define __SP_DEC + +#include "typedefs.h" + +/*_________________________________________________________________________ + | | + | Function Prototypes | + |_________________________________________________________________________| +*/ + +void speechDecoder(int16_t pswParameters[], + int16_t pswDecodedSpeechFrame[]); + + void aFlatRcDp(int32_t *pL_R, int16_t *pswRc); + + void b_con(int16_t swCodeWord, short siNumBits, + int16_t pswVectOut[]); + + void fp_ex(int16_t swOrigLagIn, int16_t pswLTPState[]); + + int16_t g_corr1(int16_t *pswIn, int32_t *pL_out); + + int16_t g_corr1s(int16_t pswIn[], int16_t swEngyRShft, + int32_t *pL_out); + + void getSfrmLpc(short int siSoftInterpolation, + int16_t swPrevR0, int16_t swNewR0, + int16_t pswPrevFrmKs[], + int16_t pswPrevFrmAs[], + int16_t pswPrevFrmPFNum[], + int16_t pswPrevFrmPFDenom[], + int16_t pswNewFrmKs[], + int16_t pswNewFrmAs[], + int16_t pswNewFrmPFNum[], + int16_t pswNewFrmPFDenom[], + struct NormSw *psnsSqrtRs, + int16_t *ppswSynthAs[], + int16_t *ppswPFNumAs[], + int16_t *ppswPFDenomAs[]); + + void get_ipjj(int16_t swLagIn, + int16_t *pswIp, int16_t *pswJj); + + short int interpolateCheck(int16_t pswRefKs[], + int16_t pswRefCoefsA[], + int16_t pswOldCoefsA[], + int16_t pswNewCoefsA[], + int16_t swOldPer, + int16_t swNewPer, + int16_t swRq, + struct NormSw *psnsSqrtRsOut, + int16_t pswCoefOutA[]); + + void lpcFir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswState[], int16_t pswFiltOut[]); + + void lpcIir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswState[], int16_t pswFiltOut[]); + + void lpcIrZsIir(int16_t pswCoef[], int16_t pswFiltOut[]); + + void lpcZiIir(int16_t pswCoef[], int16_t pswState[], + int16_t pswFiltOut[]); + + void lpcZsFir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswFiltOut[]); + + void lpcZsIir(int16_t pswInput[], int16_t pswCoef[], + int16_t pswFiltOut[]); + + void lpcZsIirP(int16_t pswCommonIO[], int16_t pswCoef[]); + + int16_t r0BasedEnergyShft(int16_t swR0Index); + + short rcToADp(int16_t swAscale, int16_t pswRc[], + int16_t pswA[]); + + void rcToCorrDpL(int16_t swAshift, int16_t swAscale, + int16_t pswRc[], int32_t pL_R[]); + + void res_eng(int16_t pswReflecCoefIn[], int16_t swRq, + struct NormSw *psnsSqrtRsOut); + + void rs_rr(int16_t pswExcitation[], struct NormSw snsSqrtRs, + struct NormSw *snsSqrtRsRr); + + void rs_rrNs(int16_t pswExcitation[], struct NormSw snsSqrtRs, + struct NormSw *snsSqrtRsRr); + + int16_t scaleExcite(int16_t pswVect[], + int16_t swErrTerm, struct NormSw snsRS, + int16_t pswScldVect[]); + + int16_t sqroot(int32_t L_SqrtIn); + + void v_con(int16_t pswBVects[], int16_t pswOutVect[], + int16_t pswBitArray[], short int siNumBVctrs); + +#endif diff --git a/src/libs/gsmhr/gsmhr_sp_enc.c b/src/libs/gsmhr/gsmhr_sp_enc.c new file mode 100644 index 00000000..9ba99076 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_sp_enc.c @@ -0,0 +1,406 @@ +/*************************************************************************** + * + * File Name: sp_enc.c + * + * Purpose: Contains speech encoder function. Calls are made to the + * frame-based encoding functions (see sp_frm.c), and the subframe- + * based encoding function (see sp_sfrm.c) + * + * Functions in this file (only 1) + * speechEncoder() + * + **************************************************************************/ +/*_________________________________________________________________________ + | | + | Include Files | + |_________________________________________________________________________| +*/ + +#include "gsmhr_mathhalf.h" +#include "gsmhr_mathdp31.h" +#include "gsmhr_sp_rom.h" +#include "gsmhr_sp_dec.h" +#include "gsmhr_sp_frm.h" +#include "gsmhr_sp_sfrm.h" +#include "gsmhr_sp_enc.h" +#include "gsmhr_host.h" +#include "gsmhr_vad.h" + +/*_________________________________________________________________________ + | | + | Local Defines | + |_________________________________________________________________________| +*/ + +#define CG_INT_MACS 6 /* Number of Multiply-Accumulates in */ + /* one interpolation */ +#define ASCALE 0x0800 +#define LMAX 142 /* largest lag (integer sense) */ +#define LSMAX (LMAX+ CG_INT_MACS/2) /* Lag Search Array Length */ +#define NUM_CLOSED 3 /* Maximum number of lags searched */ + /* in closed loop. */ + +#define LPCSTARTINDEX 25 /* Where the LPC analysis window + * starts */ +#define INBUFFSZ LPCSTARTINDEX + A_LEN /* Input buffer size */ +#define NUMSTARTUPSMP INBUFFSZ - F_LEN /* Number of samples needed */ + /* at start up */ +#define NUMSTARTUPSMP_P1 INBUFFSZ - F_LEN + 1 +#define HPFSHIFT 1 /* no right shifts high pass shifts + * speech */ + +/*_________________________________________________________________________ + | | + | State variables (globals) | + |_________________________________________________________________________| +*/ + +int16_t swOldR0; +int16_t swOldR0Index; + +struct NormSw psnsWSfrmEngSpace[2 * N_SUB]; + +int16_t pswHPFXState[4]; +int16_t pswHPFYState[8]; +int16_t pswOldFrmKs[NP]; +int16_t pswOldFrmAs[NP]; +int16_t pswOldFrmSNWCoefs[NP]; +int16_t pswWgtSpeechSpace[F_LEN + LMAX + CG_INT_MACS / 2]; + +int16_t pswSpeech[INBUFFSZ]; /* input speech */ + +int16_t swPtch = 1; + +/*_________________________________________________________________________ + | | + | Global DTX variables | + |_________________________________________________________________________| +*/ + +int16_t swTxGsHistPtr = 0; + +int16_t pswCNVSCode1[N_SUB], + pswCNVSCode2[N_SUB], + pswCNGsp0Code[N_SUB], + pswCNLpc[3], + swCNR0; + + +extern int32_t pL_GsHist[]; +extern int32_tRom ppLr_gsTable[4][32]; + +/*************************************************************************** + * + * FUNCTION NAME: speechEncoder + * + * PURPOSE: + * + * Performs GSM half-rate speech encoding on frame basis (160 samples). + * + * INPUTS: + * + * pswSpeechIn[0:159] - input speech samples, 160 new samples per frame + * + * OUTPUTS: + * + * pswFrmCodes[0:19] - output parameters, 18 speech parameters plus + * VAD and SP flags + * + * RETURN VALUE: + * + * None + * + * IMPLEMENTATION: + * + * n/a + * + * REFERENCES: Sub-clause 4.1 of GSM Recomendation 06.20 + * + * KEYWORDS: speechcoder, analysis + * + *************************************************************************/ + +void speechEncoder(int16_t pswSpeechIn[], int16_t pswFrmCodes[]) +{ + +/*_________________________________________________________________________ + | | + | Static Variables | + |_________________________________________________________________________| +*/ + + /* 1st point in analysis window */ + static int16_t *pswLpcStart = &pswSpeech[LPCSTARTINDEX]; + + /* 1st point of new frame other than 1st */ + static int16_t *pswNewSpeech = &pswSpeech[NUMSTARTUPSMP]; + + /* sample 0 of weighted speech */ + static int16_t *pswWgtSpeech = &pswWgtSpeechSpace[LSMAX]; + + static struct NormSw *psnsWSfrmEng = &psnsWSfrmEngSpace[N_SUB]; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int iVoicing, /* bitAlloc */ + iR0, /* bitAlloc and aflat */ + piVq[3], /* bitAlloc */ + iSi, /* bitAlloc */ + piLagCode[N_SUB], /* bitAlloc */ + piVSCode1[N_SUB], /* bitAlloc */ + piVSCode2[N_SUB], /* bitAlloc */ + piGsp0Code[N_SUB]; /* bitAlloc */ + + short int siUVCode, + siSi, + i, + j; + + int16_t swR0, + pswLagCode[N_SUB], + pswVSCode1[N_SUB], + pswVSCode2[N_SUB], + pswGsp0Code[N_SUB], + *pswLagListPtr, + pswFrmKs[NP], + pswFrmAs[NP], + pswFrmSNWCoefs[NP], + pswLagList[N_SUB * NUM_CLOSED], + pswNumLagList[N_SUB], + pswPitchBuf[N_SUB], + pswHNWCoefBuf[N_SUB], + ppswSNWCoefAs[N_SUB][NP], + ppswSynthAs[N_SUB][NP]; + + int16_t swSP, + pswVadLags[4], /* VAD Parameters */ + swVadFlag; /* flag indicating voice activity + * detector state. 1 = speech or + * speech/signal present */ + struct NormSw + psnsSqrtRs[N_SUB]; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Speech frame processing */ + /* High pass filter the speech */ + /* ---------------------------- */ + + filt4_2nd(psrHPFCoefs, pswSpeechIn, + pswHPFXState, pswHPFYState, F_LEN, HPFSHIFT); + + /* copy high passed filtered speech into encoder's speech buff */ + /*-------------------------------------------------------------*/ + + for (i = 0; i < F_LEN; i++) + pswNewSpeech[i] = pswSpeechIn[i]; + + + + + /* Calculate and quantize LPC coefficients */ + /* --------------------------------------- */ + + aflat(pswLpcStart, &iR0, pswFrmKs, piVq, + swPtch, &swVadFlag, &swSP); + + + /* Lookup frame energy r0 */ + /* ---------------------- */ + + swR0 = psrR0DecTbl[iR0 * 2]; /* lookupR0 */ + + /* Generate the direct form coefs */ + /* ------------------------------ */ + + if (!rcToADp(ASCALE, pswFrmKs, pswFrmAs)) + { + + getNWCoefs(pswFrmAs, pswFrmSNWCoefs); + } + else + { + + for (i = 0; i < NP; i++) + { + pswFrmKs[i] = pswOldFrmKs[i]; + pswFrmAs[i] = pswOldFrmAs[i]; + pswFrmSNWCoefs[i] = pswOldFrmSNWCoefs[i]; + } + } + + /* Interpolate, or otherwise get sfrm reflection coefs */ + /* --------------------------------------------------- */ + + getSfrmLpcTx(swOldR0, swR0, + pswOldFrmKs, pswOldFrmAs, + pswOldFrmSNWCoefs, + pswFrmKs, pswFrmAs, + pswFrmSNWCoefs, + pswSpeech, + &siSi, + psnsSqrtRs, + ppswSynthAs, ppswSNWCoefAs); + + /* loose once bitAlloc done */ + iSi = siSi; + + /* Weight the entire speech frame */ + /* ------------------------------ */ + + weightSpeechFrame(pswSpeech, ppswSynthAs[0], ppswSNWCoefAs[0], + pswWgtSpeechSpace); + + /* Perform open-loop lag search, get harmonic-noise-weighting parameters */ + /* --------------------------------------------------------------------- */ + + openLoopLagSearch(&pswWgtSpeechSpace[LSMAX], + swOldR0Index, + (int16_t) iR0, + &siUVCode, + pswLagList, + pswNumLagList, + pswPitchBuf, + pswHNWCoefBuf, + &psnsWSfrmEng[0], + pswVadLags, + swSP); + + iVoicing = siUVCode; + + + /* Using open loop LTP data to calculate swPtch */ /* DTX mode */ + /* parameter */ /* DTX mode */ + /* -------------------------------------------- */ /* DTX mode */ + + periodicity_update(pswVadLags, &swPtch); /* DTX mode */ + + + /* Subframe processing loop */ + /* ------------------------ */ + + pswLagListPtr = pswLagList; + + for (giSfrmCnt = 0; giSfrmCnt < N_SUB; giSfrmCnt++) + { + + if (swSP == 0) /* DTX mode */ + { /* DTX mode */ + pswVSCode1[giSfrmCnt] = pswCNVSCode1[giSfrmCnt]; /* DTX mode */ + pswVSCode2[giSfrmCnt] = pswCNVSCode2[giSfrmCnt]; /* DTX mode */ + pswGsp0Code[giSfrmCnt] = pswCNGsp0Code[giSfrmCnt]; /* DTX mode */ + } /* DTX mode */ + + sfrmAnalysis(&pswWgtSpeech[giSfrmCnt * S_LEN], + siUVCode, + psnsSqrtRs[giSfrmCnt], + ppswSNWCoefAs[giSfrmCnt], + pswLagListPtr, + pswNumLagList[giSfrmCnt], + pswPitchBuf[giSfrmCnt], + pswHNWCoefBuf[giSfrmCnt], + &pswLagCode[giSfrmCnt], &pswVSCode1[giSfrmCnt], + &pswVSCode2[giSfrmCnt], &pswGsp0Code[giSfrmCnt], + swSP); + + pswLagListPtr = &pswLagListPtr[pswNumLagList[giSfrmCnt]]; + + } + + + /* copy comfort noise parameters, */ /* DTX mode */ + /* update GS history */ /* DTX mode */ + /* ------------------------------ */ /* DTX mode */ + + if (swSP == 0) /* DTX mode */ + { /* DTX mode */ + + /* copy comfort noise frame parameter */ /* DTX mode */ + /* ---------------------------------- */ /* DTX mode */ + + iR0 = swCNR0; /* quantized R0 index */ /* DTX mode */ + for (i=0; i < 3; i++) /* DTX mode */ + piVq[i] = pswCNLpc[i]; /* DTX mode */ + + } /* DTX mode */ + else /* DTX mode */ + { /* DTX mode */ + + /* if swSP != 0, then update the GS history */ /* DTX mode */ + /* -----------------------------------------*/ /* DTX mode */ + + for (i=0; i < N_SUB; i++){ /* DTX mode */ + pL_GsHist[swTxGsHistPtr] = /* DTX mode */ + ppLr_gsTable[siUVCode][pswGsp0Code[i]]; /* DTX mode */ + swTxGsHistPtr++; /* DTX mode */ + if (swTxGsHistPtr > ((OVERHANG-1)*N_SUB)-1) /* DTX mode */ + swTxGsHistPtr=0; /* DTX mode */ + } /* DTX mode */ + + } /* DTX mode */ + + + /* End of frame processing, update frame based parameters */ + /* ------------------------------------------------------ */ + + for (i = 0; i < N_SUB; i++) + { + piLagCode[i] = pswLagCode[i]; + piVSCode1[i] = pswVSCode1[i]; + piVSCode2[i] = pswVSCode2[i]; + piGsp0Code[i] = pswGsp0Code[i]; + } + + swOldR0Index = (int16_t) iR0; + swOldR0 = swR0; + + for (i = 0; i < NP; i++) + { + pswOldFrmKs[i] = pswFrmKs[i]; + pswOldFrmAs[i] = pswFrmAs[i]; + pswOldFrmSNWCoefs[i] = pswFrmSNWCoefs[i]; + } + + /* Insert SID Codeword */ /* DTX mode */ + /* ------------------- */ /* DTX mode */ + + if (swSP == 0) /* DTX mode */ + { /* DTX mode */ + iVoicing = 0x0003; /* 2 bits */ /* DTX mode */ + iSi = 0x0001; /* 1 bit */ /* DTX mode */ + for (i=0; i < N_SUB; i++) /* DTX mode */ + { /* DTX mode */ + piVSCode1[i] = 0x01ff; /* 9 bits */ /* DTX mode */ + piGsp0Code[i] = 0x001f; /* 5 bits */ /* DTX mode */ + } + piLagCode[0] = 0x00ff; /* 8 bits */ /* DTX mode */ + piLagCode[1] = 0x000f; /* 4 bits */ /* DTX mode */ + piLagCode[2] = 0x000f; /* 4 bits */ /* DTX mode */ + piLagCode[3] = 0x000f; /* 4 bits */ /* DTX mode */ + } /* DTX mode */ + + + /* Generate encoded parameter array */ + /* -------------------------------- */ + + fillBitAlloc(iVoicing, iR0, piVq, iSi, piLagCode, + piVSCode1, piVSCode2, + piGsp0Code, swVadFlag, swSP, pswFrmCodes); + + + /* delay the input speech by 1 frame */ + /*-----------------------------------*/ + + for (i = 0, j = F_LEN; j < INBUFFSZ; i++, j++) + { + pswSpeech[i] = pswSpeech[j]; + } +} diff --git a/src/libs/gsmhr/gsmhr_sp_enc.h b/src/libs/gsmhr/gsmhr_sp_enc.h new file mode 100644 index 00000000..db87b141 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_sp_enc.h @@ -0,0 +1,14 @@ +#ifndef __SP_ENC +#define __SP_ENC + +#include "typedefs.h" + +/*_________________________________________________________________________ + | | + | Function Prototypes | + |_________________________________________________________________________| +*/ + +void speechEncoder(int16_t pswSpeechIn[], int16_t pswFrmCodes[]); + +#endif diff --git a/src/libs/gsmhr/gsmhr_sp_frm.c b/src/libs/gsmhr/gsmhr_sp_frm.c new file mode 100644 index 00000000..04196dc4 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_sp_frm.c @@ -0,0 +1,5908 @@ +/*************************************************************************** + * + * File Name: sp_frm.c + * + * Purpose: Contains all functions for frame-based processing in the + * speech encoder. The frame-based processing yields the following: + * energy in the speech signal, LPC filter coefficients, perceptually- + * weighted filter coefficients (for H(z) and C(z)), perceptually- + * weighted speech, voicing level, and constrained adaptive-codebook + * (long-term predictor) choices. + * + * Below is a listing of all the functions appearing in the file. + * The functions are arranged according to their purpose. Under + * each heading, the ordering is hierarchical. + * + * High pass filtering: + * filt4_2nd() + * iir_d() + * + * AFLAT, vector quantization of LPC coefficients: + * aflat() + * aflatNewBarRecursionL() + * aflatRecursion() + * findBestInQuantList() + * getNextVec() + * initPBarVBarFullL() + * initPBarVBarL() + * setupPreQ() + * setupQuant() + * + * FLAT: derivation of the unquantized LPC coefficients: + * flat() + * cov32() + * r0Quant() + * + * + * Generation of LPC filters for each subframe: + * getSfrmLpcTx() + * compResidEnergy() + * + * Perceptual weighting: + * weightSpeechFrame() + * + * Generation of the noise weighting filter: + * getNWCoefs() + * + * Open loop lag search: + * openLoopLagSearch() + * bestDelta() + * maxCCOverGWithSign() + * getCCThreshold() + * fnExp2() + * fnLog2() + * pitchLags() + * CGInterp() + * CGInterpValid() + * findPeak() + * fnBest_CG() + * quantLag() + * + **************************************************************************/ + +/*_________________________________________________________________________ + | | + | Include Files | + |_________________________________________________________________________| +*/ + +#include "gsmhr_mathhalf.h" +#include "gsmhr_mathdp31.h" +#include "gsmhr_sp_rom.h" +#include "gsmhr_sp_dec.h" +#include "gsmhr_sp_frm.h" +#include "gsmhr_sp_sfrm.h" +#include "gsmhr_vad.h" +#include "gsmhr_dtx.h" + +/*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| +*/ + +#define ASCALE 0x0800 +#define ASHIFT 4 +#define CG_INT_MACS 6 +#define CG_TERMS (LSMAX - LSMIN + 1) +#define CVSHIFT 2 /* Number of right shifts to be + * applied to the normalized Phi + * array in cov32, also used in flat + * to shift down normalized F, B, C + * matrices. */ +#define C_FRAME_LEN (N_SUB * CG_TERMS) +#define DELTA_LEVELS 16 +#define G_FRAME_LEN (LSMAX + (N_SUB-1) * S_LEN - LSMIN + 1) +#define HIGH 1 +#define INV_OS_FCTR 0x1555 /* 1.0/6.0 */ +#define LAG_TABLE_LEN (1 << L_BITS) +#define LMAX 142 +#define LMAX_FR (LMAX * OS_FCTR) +#define LMIN 21 +#define LMIN_FR (LMIN * OS_FCTR) +#define LOW 0 +#define LPC_VQ_SEG 3 +#define LSMAX (LMAX + CG_INT_MACS/2) +#define LSMIN (LMIN - CG_INT_MACS/2) +#define LSP_MASK 0xffff +#define L_BITS 8 +#define L_ROUND (int32_t)0x8000 /* Preload accumulator value for + * rounding */ +#define NP_AFLAT 4 +#define NUM_CLOSED 3 +#define NUM_TRAJ_MAX 2 +#define ONE_EIGHTH 0x1000 +#define ONE_HALF 0x4000 +#define ONE_QUARTER 0x2000 +#define PEAK_VICINITY 3 +#define PGAIN_CLAMP 0x0021 /* 0.001 */ +#define PGAIN_SCALE 0x6000 /* 0.75 */ +#define PW_FRAC 0x3333 /* 0.4 */ +#define R0BITS 5 +#define RSHIFT 2 +#define S_SH 6 /* Shift offset for computing frame + * energy */ +#define UV_SCALE0 -0x2976 +#define UV_SCALE1 -0x46d3 +#define UV_SCALE2 -0x6676 +#define W_F_BUFF_LEN (F_LEN + LSMAX) +#define high(x) (shr(x,8) & 0x00ff) +#define low(x) x & 0x00ff /* This macro will return the low + * byte of a word */ +#define odd(x) (x & 0x0001) /* This macro will determine if an + * integer is odd */ + +/*_________________________________________________________________________ + | | + | State Variables (globals) | + |_________________________________________________________________________| +*/ + +int16_t pswAnalysisState[NP]; + +int16_t pswWStateNum[NP], + pswWStateDenom[NP]; + +/*_________________________________________________________________________ + | | + | Other External Variables | + |_________________________________________________________________________| +*/ + +static int16_tRom *psrTable; /* points to correct table of + * vectors */ +int iLimit; /* accessible to all in this file + * and to lpcCorrQntz() in dtx.c */ +static int iLow; /* the low element in this segment */ +static int iThree; /* boolean, is this a three element + * vector */ +static int iWordHalfPtr; /* points to the next byte */ +static int iWordPtr; /* points to the next word to be + * read */ + +extern int16_t pswCNVSCode1[], /* comfort noise parameters */ + pswCNVSCode2[], + pswCNGsp0Code[], + pswCNLpc[], + swCNR0; + +/*************************************************************************** + * + * FUNCTION NAME: aflat + * + * PURPOSE: Given a vector of high-pass filtered input speech samples + * (A_LEN samples), function aflat computes the NP unquantized + * reflection coefficients using the FLAT algorithm, searches + * the three segment Rc-VQ based on the AFLAT recursion, and + * outputs a quantized set of NP reflection coefficients, along + * with the three indices specifying the selected vectors + * from the Rc-VQ. The index of the quantized frame energy R0 + * is also output. + * + * + * INPUT: + * + * pswSpeechToLpc[0:A_LEN-1] + * A vector of high-pass filtered input speech, from + * which the unquantized reflection coefficients and + * the index of the quantized frame energy are + * computed. + * + * OUTPUTS: + * + * piR0Index[0:0] + * An index into a 5 bit table of quantized frame + * energies. + * + * pswFinalRc[0:NP-1] + * A quantized set of NP reflection coefficients. + * + * piVQCodewds[0:2] + * An array containing the indices of the 3 reflection + * coefficient vectors selected from the three segment + * Rc-VQ. + * + * swPtch + * Flag to indicate a periodic signal component + * + * pswVadFlag + * Voice activity decision flag + * = 1: voice activity + * = 0: no voice activity + * + * pswSP + * Speech flag + * = 1: encoder generates speech frames + * = 0: encoder generate SID frames + * + * + * RETURN: + * None. + * + * REFERENCE: Sub-clauses 4.1.3, 4.1.4, and 4.1.4.1 + * of GSM Recommendation 06.20 + * + * KEYWORDS: AFLAT,aflat,flat,vectorquantization, reflectioncoefficients + * + *************************************************************************/ + + void aflat(int16_t pswSpeechToLPC[], + int piR0Index[], + int16_t pswFinalRc[], + int piVQCodewds[], + int16_t swPtch, + int16_t *pswVadFlag, + int16_t *pswSP) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t pswPOldSpace[NP_AFLAT], + pswPNewSpace[NP_AFLAT], + pswVOldSpace[2 * NP_AFLAT - 1], + pswVNewSpace[2 * NP_AFLAT - 1], + *ppswPAddrs[2], + *ppswVAddrs[2], + *pswVBar, + pswPBar[NP_AFLAT], + pswVBarSpace[2 * NP_AFLAT - 1], + pswFlatsRc[NP], /* Unquantized Rc's computed by FLAT */ + pswRc[NP + 1]; /* Temp list for the converted RC's */ + int32_t pL_CorrelSeq[NP + 1], + *pL_VBarFull, + pL_PBarFull[NP], + pL_VBarFullSpace[2 * NP - 1]; + + int i, + iVec, + iSeg, + iCnt; /* Loop counter */ + struct QuantList quantList, /* A list of vectors */ + bestPql[4]; /* The four best vectors from the + * PreQ */ + struct QuantList bestQl[LPC_VQ_SEG + 1]; /* Best vectors for each of + * the three segments */ + int16_t swVadScalAuto; + int16_t pswVadRc[4]; + int32_t pL_VadAcf[9]; + + int32_t L_R0; /* Normalized R0 (use swRShifts to + * unnormalize). This is done prior + * to r0quant(). After this, its is + * a unnormalized number */ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Setup pointers temporary space */ + /*--------------------------------*/ + + pswVBar = pswVBarSpace + NP_AFLAT - 1; + pL_VBarFull = pL_VBarFullSpace + NP - 1; + ppswPAddrs[0] = pswPOldSpace; + ppswPAddrs[1] = pswPNewSpace; + ppswVAddrs[0] = pswVOldSpace + NP_AFLAT - 1; + ppswVAddrs[1] = pswVNewSpace + NP_AFLAT - 1; + + /* Given the input speech, compute the optimal reflection coefficients */ + /* using the FLAT algorithm. */ + /*---------------------------------------------------------------------*/ + + L_R0 = flat(pswSpeechToLPC, pswFlatsRc, piR0Index, pL_VadAcf, + &swVadScalAuto); + + /* Get unquantized reflection coefficients for VAD */ /* DTX mode */ + /* algorithm */ /* DTX mode */ + /* ----------------------------------------------- */ /* DTX mode */ + + for (i = 0; i < 4; i++) /* DTX mode */ + pswVadRc[i] = pswFlatsRc[i]; /* DTX mode */ + + + /* convert reflection coefficients to correlation */ /* DTX mode */ + /* sequence */ /* DTX mode */ + /* ---------------------------------------------- */ /* DTX mode */ + + rcToCorrDpL(ASHIFT, ASCALE, pswFlatsRc, pL_CorrelSeq); /* DTX mode */ + + + /* Make the voice activity detection. Only swVadFlag is */ /* DTX mode */ + /* modified. */ /* DTX mode */ + /* ---------------------------------------------------- */ /* DTX mode */ + + vad_algorithm(pL_VadAcf, swVadScalAuto, pswVadRc, swPtch, /* DTX mode */ + pswVadFlag); + + + /* if DTX mode off, then always voice activity */ /* DTX mode */ + /* ------------------------------------------- */ /* DTX mode */ + if (!giDTXon) *pswVadFlag = 1; /* DTX mode */ + + + /* determination of comfort noise parameters */ /* DTX mode */ + /* ----------------------------------------- */ /* DTX mode */ + + *pswSP = swComfortNoise(*pswVadFlag, /* DTX mode */ + L_R0, /* DTX mode */ + pL_CorrelSeq); /* DTX mode */ + + if (*pswSP == 0) /* DTX mode */ + { /* SID frame generation */ /* DTX mode */ + + /* use unquantized reflection coefficients in the */ /* DTX mode */ + /* encoder, when SID frames are generated */ /* DTX mode */ + /* ---------------------------------------------- */ /* DTX mode */ + + for (i = 0; i < NP; i++) /* DTX mode */ + pswFinalRc[i] = pswFlatsRc[i]; /* DTX mode */ + + } /* DTX mode */ + else /* DTX mode */ + { /* speech frame generation */ + + /* Set up pL_PBarFull and pL_VBarFull initial conditions, using the */ + /* autocorrelation sequence derived from the optimal reflection */ + /* coefficients computed by FLAT. The initial conditions are shifted */ + /* right by RSHIFT bits. These initial conditions, stored as */ + /* int32_ts, are used to initialize PBar and VBar arrays for the */ + /* next VQ segment. */ + /*--------------------------------------------------------------------*/ + + initPBarFullVBarFullL(pL_CorrelSeq, pL_PBarFull, pL_VBarFull); + + /* Set up initial PBar and VBar initial conditions, using pL_PBarFull */ + /* and pL_VBarFull arrays initialized above. These are the initial */ + /* PBar and VBar conditions to be used by the AFLAT recursion at the */ + /* 1-st Rc-VQ segment. */ + /*--------------------------------------------------------------------*/ + + initPBarVBarL(pL_PBarFull, pswPBar, pswVBar); + + for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++) + { + + /* initialize candidate list */ + /*---------------------------*/ + + quantList.iNum = psrPreQSz[iSeg - 1]; + quantList.iRCIndex = 0; + + /* do aflat for all vectors in the list */ + /*--------------------------------------*/ + + setupPreQ(iSeg, quantList.iRCIndex); /* set up vector ptrs */ + + for (iCnt = 0; iCnt < quantList.iNum; iCnt++) + { + /* get a vector */ + /*--------------*/ + + getNextVec(pswRc); + + /* clear the limiter flag */ + /*------------------------*/ + + iLimit = 0; + + /* find the error values for each vector */ + /*---------------------------------------*/ + + quantList.pswPredErr[iCnt] = + aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l], + pswPBar, pswVBar, + ppswPAddrs, ppswVAddrs, + psvqIndex[iSeg - 1].len); + + /* check the limiter flag */ + /*------------------------*/ + + if (iLimit) + { + quantList.pswPredErr[iCnt] = 0x7fff; /* set error to bad value */ + } + + } /* done list loop */ + + /* find 4 best prequantizer levels */ + /*---------------------------------*/ + + findBestInQuantList(quantList, 4, bestPql); + + for (iVec = 0; iVec < 4; iVec++) + { + + /* initialize quantizer list */ + /*---------------------------*/ + + quantList.iNum = psrQuantSz[iSeg - 1]; + quantList.iRCIndex = bestPql[iVec].iRCIndex * psrQuantSz[iSeg - 1]; + + setupQuant(iSeg, quantList.iRCIndex); /* set up vector ptrs */ + + /* do aflat recursion on each element of list */ + /*--------------------------------------------*/ + + for (iCnt = 0; iCnt < quantList.iNum; iCnt++) + { + + /* get a vector */ + /*--------------*/ + + getNextVec(pswRc); + + /* clear the limiter flag */ + /*------------------------*/ + + iLimit = 0; + + /* find the error values for each vector */ + /*---------------------------------------*/ + + quantList.pswPredErr[iCnt] = + aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l], + pswPBar, pswVBar, + ppswPAddrs, ppswVAddrs, + psvqIndex[iSeg - 1].len); + + /* check the limiter flag */ + /*------------------------*/ + + if (iLimit) + { + quantList.pswPredErr[iCnt] = 0x7fff; /* set error to the worst + * value */ + } + + } /* done list loop */ + + /* find best quantizer vector for this segment, and save it */ + /*----------------------------------------------------------*/ + + findBestInQuantList(quantList, 1, bestQl); + if (iVec == 0) + { + bestQl[iSeg] = bestQl[0]; + } + else + { + if (sub(bestQl[iSeg].pswPredErr[0], + bestQl[0].pswPredErr[0]) > 0) + { + bestQl[iSeg] = bestQl[0]; + } + } + } + + /* find the quantized reflection coefficients */ + /*--------------------------------------------*/ + + setupQuant(iSeg, bestQl[iSeg].iRCIndex); /* set up vector ptrs */ + getNextVec((int16_t *) (pswFinalRc - 1)); + + + /* Update pBarFull and vBarFull for the next Rc-VQ segment, and */ + /* update the pswPBar and pswVBar for the next Rc-VQ segment */ + /*--------------------------------------------------------------*/ + + if (iSeg < LPC_VQ_SEG) + { + + aflatNewBarRecursionL(&pswFinalRc[psvqIndex[iSeg - 1].l - 1], iSeg, + pL_PBarFull, pL_VBarFull, pswPBar, pswVBar); + + } + + } + + /* find the quantizer index (the values */ + /* to be output in the symbol file) */ + /*--------------------------------------*/ + + for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++) + { + piVQCodewds[iSeg - 1] = bestQl[iSeg].iRCIndex; + } + + } + +} + +/*************************************************************************** + * + * FUNCTION NAME: aflatNewBarRecursionL + * + * PURPOSE: Given the int32_t initial condition arrays, pL_PBarFull and + * pL_VBarFull, a reflection coefficient vector selected from + * the Rc-VQ at the current stage, and index of the current + * Rc-VQ stage, the AFLAT recursion is evaluated to obtain the + * updated initial conditions for the AFLAT recursion at the + * next Rc-VQ stage. At each lattice stage the pL_PBarFull and + * pL_VBarFull arrays are shifted to be RSHIFT down from full + * scale. Two sets of initial conditions are output: + * + * 1) pswPBar and pswVBar int16_t arrays are used at the + * next Rc-VQ segment as the AFLAT initial conditions + * for the Rc prequantizer and the Rc quantizer searches. + * 2) pL_PBarFull and pL_VBarFull arrays are output and serve + * as the initial conditions for the function call to + * aflatNewBarRecursionL at the next lattice stage. + * + * + * This is an implementation of equations 4.24 through + * 4.27. + * INPUTS: + * + * pswQntRc[0:NP_AFLAT-1] + * An input reflection coefficient vector selected from + * the Rc-VQ quantizer at the current stage. + * + * iSegment + * An input describing the current Vector quantizer + * quantizer segment (1, 2, or 3). + * + * RSHIFT The number of shifts down from full scale the + * pL_PBarFull and pL_VBarFull arrays are to be shifted + * at each lattice stage. RSHIFT is a global constant. + * + * pL_PBar[0:NP-1] + * A int32_t input array containing the P initial + * conditions for the full 10-th order LPC filter. + * The address of the 0-th element of pL_PBarFull + * is passed in when function aflatNewBarRecursionL + * is called. + * + * pL_VBar[-NP+1:NP-1] + * A int32_t input array containing the V initial + * conditions for the full 10-th order LPC filter. + * The address of the 0-th element of pL_VBarFull + * is passed in when function aflatNewBarRecursionL + * is called. + * + * OUTPUTS: + * + * pL_PBar[0:NP-1] + * A int32_t output array containing the updated P + * initial conditions for the full 10-th order LPC + * filter. + * + * pL_VBar[-NP+1:NP-1] + * A int32_t output array containing the updated V + * initial conditions for the full 10-th order LPC + * filter. + * + * pswPBar[0:NP_AFLAT-1] + * An output int16_t array containing the P initial + * conditions for the P-V AFLAT recursion for the next + * Rc-VQ segment. The address of the 0-th element of + * pswVBar is passed in. + * + * pswVBar[-NP_AFLAT+1:NP_AFLAT-1] + * The output int16_t array containing the V initial + * conditions for the P-V AFLAT recursion, for the next + * Rc-VQ segment. The address of the 0-th element of + * pswVBar is passed in. + * + * RETURN: + * None. + * + * REFERENCE: Sub-clause 4.1.4.1 GSM Recommendation 06.20 + * + *************************************************************************/ + +void aflatNewBarRecursionL(int16_t pswQntRc[], int iSegment, + int32_t pL_PBar[], int32_t pL_VBar[], + int16_t pswPBar[], int16_t pswVBar[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int32_t *pL_VOld, + *pL_VNew, + *pL_POld, + *pL_PNew, + *ppL_PAddrs[2], + *ppL_VAddrs[2], + pL_VOldSpace[2 * NP - 1], + pL_VNewSpace[2 * NP - 1], + pL_POldSpace[NP], + pL_PNewSpace[NP], + L_temp, + L_sum; + int16_t swQntRcSq, + swNShift; + short int i, + j, + bound; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + /* Copy the addresses of the input PBar and VBar arrays into */ + /* pL_POld and pL_VOld respectively. */ + /*------------------------------------------------------------*/ + + pL_POld = pL_PBar; + pL_VOld = pL_VBar; + + /* Point to PNew and VNew temporary arrays */ + /*-----------------------------------------*/ + + pL_PNew = pL_PNewSpace; + pL_VNew = pL_VNewSpace + NP - 1; + + /* Load the addresses of the temporary buffers into the address arrays. */ + /* The address arrays are used to swap PNew and POld (VNew and VOLd) */ + /* buffers to avoid copying of the buffer contents at the end of a */ + /* lattice filter stage. */ + /*----------------------------------------------------------------------*/ + + ppL_PAddrs[0] = pL_POldSpace; + ppL_PAddrs[1] = pL_PNewSpace; + ppL_VAddrs[0] = pL_VOldSpace + NP - 1; + ppL_VAddrs[1] = pL_VNewSpace + NP - 1; + + + /* Update AFLAT recursion initial conditions for searching the Rc vector */ + /* quantizer at the next VQ segment. */ + /*-------------------------------------------------------------------*/ + + for (j = 0; j < psvqIndex[iSegment - 1].len; j++) + { + bound = NP - psvqIndex[iSegment - 1].l - j - 1; + + /* Compute rc squared, used by the recursion at the j-th lattice stage. */ + /*---------------------------------------------------------------------*/ + + swQntRcSq = mult_r(pswQntRc[j], pswQntRc[j]); + + /* Calculate PNew(i) */ + /*-------------------*/ + + L_temp = L_mpy_ls(pL_VOld[0], pswQntRc[j]); + L_sum = L_add(L_temp, pL_POld[0]); + L_temp = L_mpy_ls(pL_POld[0], swQntRcSq); + L_sum = L_add(L_temp, L_sum); + L_temp = L_mpy_ls(pL_VOld[0], pswQntRc[j]); + L_temp = L_add(L_sum, L_temp); + + /* Compute the number of bits to shift left by to achieve */ + /* the nominal value of PNew[0] which is right shifted by */ + /* RSHIFT bits relative to full scale. */ + /*---------------------------------------------------------*/ + + swNShift = sub(norm_s(extract_h(L_temp)), RSHIFT); + + /* Rescale PNew[0] by shifting left by swNShift bits */ + /*---------------------------------------------------*/ + + pL_PNew[0] = L_shl(L_temp, swNShift); + + for (i = 1; i <= bound; i++) + { + L_temp = L_mpy_ls(pL_VOld[i], pswQntRc[j]); + L_sum = L_add(L_temp, pL_POld[i]); + L_temp = L_mpy_ls(pL_POld[i], swQntRcSq); + L_sum = L_add(L_temp, L_sum); + L_temp = L_mpy_ls(pL_VOld[-i], pswQntRc[j]); + L_temp = L_add(L_sum, L_temp); + pL_PNew[i] = L_shl(L_temp, swNShift); + } + + /* Calculate VNew(i) */ + /*-------------------*/ + + for (i = -bound; i < 0; i++) + { + L_temp = L_mpy_ls(pL_VOld[-i - 1], swQntRcSq); + L_sum = L_add(L_temp, pL_VOld[i + 1]); + L_temp = L_mpy_ls(pL_POld[-i - 1], pswQntRc[j]); + L_temp = L_shl(L_temp, 1); + L_temp = L_add(L_temp, L_sum); + pL_VNew[i] = L_shl(L_temp, swNShift); + } + for (i = 0; i <= bound; i++) + { + L_temp = L_mpy_ls(pL_VOld[-i - 1], swQntRcSq); + L_sum = L_add(L_temp, pL_VOld[i + 1]); + L_temp = L_mpy_ls(pL_POld[i + 1], pswQntRc[j]); + L_temp = L_shl(L_temp, 1); + L_temp = L_add(L_temp, L_sum); + pL_VNew[i] = L_shl(L_temp, swNShift); + } + + if (j < psvqIndex[iSegment - 1].len - 2) + { + + /* Swap POld and PNew buffers, using modulo addressing */ + /*-----------------------------------------------------*/ + + pL_POld = ppL_PAddrs[(j + 1) % 2]; + pL_PNew = ppL_PAddrs[j % 2]; + + /* Swap VOld and VNew buffers, using modulo addressing */ + /*-----------------------------------------------------*/ + + pL_VOld = ppL_VAddrs[(j + 1) % 2]; + pL_VNew = ppL_VAddrs[j % 2]; + } + else + { + if (j == psvqIndex[iSegment - 1].len - 2) + { + + /* Then recursion to be done for one more lattice stage */ + /*------------------------------------------------------*/ + + /* Copy address of PNew into POld */ + /*--------------------------------*/ + pL_POld = ppL_PAddrs[(j + 1) % 2]; + + /* Copy address of the input pL_PBar array into pswPNew; this will */ + /* cause the PNew array to overwrite the input pL_PBar array, thus */ + /* updating it at the final lattice stage of the current segment */ + /*-----------------------------------------------------------------*/ + + pL_PNew = pL_PBar; + + /* Copy address of VNew into VOld */ + /*--------------------------------*/ + + pL_VOld = ppL_VAddrs[(j + 1) % 2]; + + /* Copy address of the input pL_VBar array into pswVNew; this will */ + /* cause the VNew array to overwrite the input pL_VBar array, thus */ + /* updating it at the final lattice stage of the current segment */ + /*-----------------------------------------------------------------*/ + + pL_VNew = pL_VBar; + + } + } + } + + /* Update the pswPBar and pswVBar initial conditions for the AFLAT */ + /* Rc-VQ search at the next segment. */ + /*----------------------------------------------------------------------*/ + + bound = psvqIndex[iSegment].len - 1; + + for (i = 0; i <= bound; i++) + { + pswPBar[i] = round(pL_PBar[i]); + pswVBar[i] = round(pL_VBar[i]); + } + for (i = -bound; i < 0; i++) + { + pswVBar[i] = round(pL_VBar[i]); + } + + return; +} + +/*************************************************************************** + * + * FUNCTION NAME: aflatRecursion + * + * PURPOSE: Given the int16_t initial condition arrays, pswPBar and + * pswVBar, a reflection coefficient vector from the quantizer + * (or a prequantizer), and the order of the current Rc-VQ + * segment, function aflatRecursion computes and returns the + * residual error energy by evaluating the AFLAT recursion. + * + * This is an implementation of equations 4.18 to 4.23. + * INPUTS: + * + * pswQntRc[0:NP_AFLAT-1] + * An input reflection coefficient vector from the + * Rc-prequantizer or the Rc-VQ codebook. + * + * pswPBar[0:NP_AFLAT-1] + * The input int16_t array containing the P initial + * conditions for the P-V AFLAT recursion at the current + * Rc-VQ segment. The address of the 0-th element of + * pswVBar is passed in. + * + * pswVBar[-NP_AFLAT+1:NP_AFLAT-1] + * The input int16_t array containing the V initial + * conditions for the P-V AFLAT recursion, at the current + * Rc-VQ segment. The address of the 0-th element of + * pswVBar is passed in. + * + * *ppswPAddrs[0:1] + * An input array containing the address of temporary + * space P1 in its 0-th element, and the address of + * temporary space P2 in its 1-st element. Each of + * these addresses is alternately assigned onto + * pswPNew and pswPOld pointers using modulo + * arithmetic, so as to avoid copying the contents of + * pswPNew array into the pswPOld array at the end of + * each lattice stage of the AFLAT recursion. + * Temporary space P1 and P2 is allocated outside + * aflatRecursion by the calling function aflat. + * + * *ppswVAddrs[0:1] + * An input array containing the address of temporary + * space V1 in its 0-th element, and the address of + * temporary space V2 in its 1-st element. Each of + * these addresses is alternately assigned onto + * pswVNew and pswVOld pointers using modulo + * arithmetic, so as to avoid copying the contents of + * pswVNew array into the pswVOld array at the end of + * each lattice stage of the AFLAT recursion. + * Temporary space V1 and V2 is allocated outside + * aflatRecursion by the calling function aflat. + * + * swSegmentOrder + * This input short word describes the number of + * stages needed to compute the vector + * quantization of the given segment. + * + * OUTPUTS: + * None. + * + * RETURN: + * swRe The int16_t value of residual energy for the + * Rc vector, given the pswPBar and pswVBar initial + * conditions. + * + * REFERENCE: Sub-clause 4.1.4.1 GSM Recommendation 06.20 + * + *************************************************************************/ + +int16_t aflatRecursion(int16_t pswQntRc[], + int16_t pswPBar[], + int16_t pswVBar[], + int16_t *ppswPAddrs[], + int16_t *ppswVAddrs[], + int16_t swSegmentOrder) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t *pswPOld, + *pswPNew, + *pswVOld, + *pswVNew, + pswQntRcSqd[NP_AFLAT], + swRe; + int32_t L_sum; + short int i, + j, + bound; /* loop control variables */ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Point to PBar and VBar, the initial condition arrays for the AFLAT */ + /* recursion. */ + /*---------------------------------------------------------------------*/ + + pswPOld = pswPBar; + pswVOld = pswVBar; + + /* Point to PNew and VNew, the arrays into which updated values of P */ + /* and V functions will be written. */ + /*---------------------------------------------------------------------*/ + + pswPNew = ppswPAddrs[1]; + pswVNew = ppswVAddrs[1]; + + /* Compute the residual error energy due to the selected Rc vector */ + /* using the AFLAT recursion. */ + /*-----------------------------------------------------------------*/ + + /* Compute rc squared, used by the recursion */ + /*-------------------------------------------*/ + + for (j = 0; j < swSegmentOrder; j++) + { + pswQntRcSqd[j] = mult_r(pswQntRc[j], pswQntRc[j]); + } + + /* Compute the residual error energy due to the selected Rc vector */ + /* using the AFLAT recursion. */ + /*-----------------------------------------------------------------*/ + + for (j = 0; j < swSegmentOrder - 1; j++) + { + bound = swSegmentOrder - j - 2; + + /* Compute Psubj(i), for i = 0, bound */ + /*-------------------------------------*/ + + for (i = 0; i <= bound; i++) + { + L_sum = L_mac(L_ROUND, pswVOld[i], pswQntRc[j]); + L_sum = L_mac(L_sum, pswVOld[-i], pswQntRc[j]); + L_sum = L_mac(L_sum, pswPOld[i], pswQntRcSqd[j]); + L_sum = L_msu(L_sum, pswPOld[i], SW_MIN); + pswPNew[i] = extract_h(L_sum); + } + + /* Check if potential for limiting exists. */ + /*-----------------------------------------*/ + + if (sub(pswPNew[0], 0x4000) >= 0) + iLimit = 1; + + /* Compute the new Vsubj(i) */ + /*--------------------------*/ + + for (i = -bound; i < 0; i++) + { + L_sum = L_msu(L_ROUND, pswVOld[i + 1], SW_MIN); + L_sum = L_mac(L_sum, pswQntRcSqd[j], pswVOld[-i - 1]); + L_sum = L_mac(L_sum, pswQntRc[j], pswPOld[-i - 1]); + L_sum = L_mac(L_sum, pswQntRc[j], pswPOld[-i - 1]); + pswVNew[i] = extract_h(L_sum); + } + + for (i = 0; i <= bound; i++) + { + L_sum = L_msu(L_ROUND, pswVOld[i + 1], SW_MIN); + L_sum = L_mac(L_sum, pswQntRcSqd[j], pswVOld[-i - 1]); + L_sum = L_mac(L_sum, pswQntRc[j], pswPOld[i + 1]); + L_sum = L_mac(L_sum, pswQntRc[j], pswPOld[i + 1]); + pswVNew[i] = extract_h(L_sum); + } + + if (j < swSegmentOrder - 2) + { + + /* Swap POld and PNew buffers, using modulo addressing */ + /*-----------------------------------------------------*/ + + pswPOld = ppswPAddrs[(j + 1) % 2]; + pswPNew = ppswPAddrs[j % 2]; + + /* Swap VOld and VNew buffers, using modulo addressing */ + /*-----------------------------------------------------*/ + + pswVOld = ppswVAddrs[(j + 1) % 2]; + pswVNew = ppswVAddrs[j % 2]; + + } + } + + /* Computing Psubj(0) for the last lattice stage */ + /*-----------------------------------------------*/ + + j = swSegmentOrder - 1; + + L_sum = L_mac(L_ROUND, pswVNew[0], pswQntRc[j]); + L_sum = L_mac(L_sum, pswVNew[0], pswQntRc[j]); + L_sum = L_mac(L_sum, pswPNew[0], pswQntRcSqd[j]); + L_sum = L_msu(L_sum, pswPNew[0], SW_MIN); + swRe = extract_h(L_sum); + + /* Return the residual energy corresponding to the reflection */ + /* coefficient vector being evaluated. */ + /*--------------------------------------------------------------*/ + + return (swRe); /* residual error is returned */ + +} + +/*************************************************************************** + * + * FUNCTION NAME: bestDelta + * + * PURPOSE: + * + * This function finds the delta-codeable lag which maximizes CC/G. + * + * INPUTS: + * + * pswLagList[0:siNumLags-1] + * + * List of delta-codeable lags over which search is done. + * + * pswCSfrm[0:127] + * + * C(k) sequence, k integer. + * + * pswGSfrm[0:127] + * + * G(k) sequence, k integer. + * + * siNumLags + * + * Number of lags in contention. + * + * siSfrmIndex + * + * The index of the subframe to which the delta-code + * applies. + * + * + * OUTPUTS: + * + * pswLTraj[0:3] + * + * The winning lag is put into this array at + * pswLTraj[siSfrmIndex] + * + * pswCCTraj[0:3] + * + * The corresponding winning C**2 is put into this + * array at pswCCTraj[siSfrmIndex] + * + * pswGTraj[0:3] + * + * The corresponding winning G is put into this arrray + * at pswGTraj[siSfrmIndex] + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * REFERENCE: Sub-clause 4.1.8.3 of GSM Recommendation 06.20 + * + * KEYWORDS: + * + *************************************************************************/ + +void bestDelta(int16_t pswLagList[], + int16_t pswCSfrm[], + int16_t pswGSfrm[], + short int siNumLags, + short int siSfrmIndex, + int16_t pswLTraj[], + int16_t pswCCTraj[], + int16_t pswGTraj[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t pswCBuf[DELTA_LEVELS + CG_INT_MACS + 2], + pswGBuf[DELTA_LEVELS + CG_INT_MACS + 2], + pswCInterp[DELTA_LEVELS + 2], + pswGInterp[DELTA_LEVELS + 2], + *psw1, + *psw2, + swCmaxSqr, + swGmax, + swPeak; + short int siIPLo, + siRemLo, + siIPHi, + siRemHi, + siLoLag, + siHiLag, + siI; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* get bounds for integer C's and G's needed for interpolation */ + /* get integer and fractional portions of boundary lags */ + /* ----------------------------------------------------------- */ + + get_ipjj(pswLagList[0], &siIPLo, &siRemLo); + + get_ipjj(pswLagList[siNumLags - 1], &siIPHi, &siRemHi); + + /* get lag for first and last C and G required */ + /* ------------------------------------------- */ + + siLoLag = sub(siIPLo, CG_INT_MACS / 2 - 1); + + if (siRemHi != 0) + { + siHiLag = add(siIPHi, CG_INT_MACS / 2); + } + else + { + siHiLag = add(siIPHi, CG_INT_MACS / 2 - 1); + } + + /* transfer needed integer C's and G's to temp buffers */ + /* --------------------------------------------------- */ + + psw1 = pswCBuf; + psw2 = pswGBuf; + + if (siRemLo == 0) + { + + /* first lag in list is integer: don't care about first entries */ + /* (they will be paired with zero tap in interpolating filter) */ + /* ------------------------------------------------------------ */ + + psw1[0] = 0; + psw2[0] = 0; + psw1 = &psw1[1]; + psw2 = &psw2[1]; + } + + for (siI = siLoLag; siI <= siHiLag; siI++) + { + psw1[siI - siLoLag] = pswCSfrm[siI - LSMIN]; + psw2[siI - siLoLag] = pswGSfrm[siI - LSMIN]; + } + + if (siRemLo == 0) + { + /* make siLoLag correspond to first entry in temp buffers */ + /* ------------------------------------------------------ */ + siLoLag = sub(siLoLag, 1); + } + + /* interpolate to get C's and G's which correspond to lags in list */ + /* --------------------------------------------------------------- */ + + CGInterp(pswLagList, siNumLags, pswCBuf, pswGBuf, siLoLag, + pswCInterp, pswGInterp); + + /* find max C*C*sgn(C)/G */ + /* --------------------- */ + + swPeak = maxCCOverGWithSign(pswCInterp, pswGInterp, &swCmaxSqr, &swGmax, + siNumLags); + + /* store best lag and corresponding C*C and G */ + /* ------------------------------------------ */ + + pswLTraj[siSfrmIndex] = pswLagList[swPeak]; + pswCCTraj[siSfrmIndex] = swCmaxSqr; + pswGTraj[siSfrmIndex] = swGmax; + +} + + +/*************************************************************************** + * + * FUNCTION NAME: CGInterp + * + * PURPOSE: + * + * Given a list of fractional lags, a C(k) array, and a G(k) array + * (k integer), this function generates arrays of C's and G's + * corresponding to the list of fractional lags by interpolating the + * integer C(k) and G(k) arrays. + * + * INPUTS: + * + * pswLIn[0:siNum-1] + * + * List of valid lags + * + * siNum + * + * Length of output lists + * + * pswCIn[0:variable] + * + * C(k) sequence, k integer. The zero index corresponds + * to k = siLoIntLag. + * + * pswGIn[0:variable] + * + * G(k) sequence, k integer. The zero index corresponds + * to k = siLoIntLag. + * + * siLoIntLag + * + * Integer lag corresponding to the first entry in the + * C(k) and G(k) input arrays. + * + * ppsrCGIntFilt[0:5][0:5] + * + * The FIR interpolation filter for C's and G's. + * + * OUTPUTS: + * + * pswCOut[0:siNum-1] + * + * List of interpolated C's corresponding to pswLIn. + * + * pswGOut[0:siNum-1] + * + * List of interpolated G's corresponding to pswLIn + * + * RETURN VALUE: none + * + * DESCRIPTION: + * + * + * REFERENCE: Sub-clause 4.1.8.2, 4.1.8.3 of GSM Recommendation 06.20 + * + * KEYWORDS: lag, interpolateCG + * + *************************************************************************/ + +void CGInterp(int16_t pswLIn[], + short siNum, + int16_t pswCIn[], + int16_t pswGIn[], + short siLoIntLag, + int16_t pswCOut[], + int16_t pswGOut[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int16_t i, + swBig, + swLoIntLag; + int16_t swLagInt, + swTempRem, + swLagRem; + int32_t L_Temp, + L_Temp1, + L_Temp2; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + swLoIntLag = add(siLoIntLag, (CG_INT_MACS / 2) - 1); + + for (swBig = 0; swBig < siNum; swBig++) + { + + /* Separate integer and fractional portions of lag */ + /*-------------------------------------------------*/ + L_Temp = L_mult(pswLIn[swBig], INV_OS_FCTR); + swLagInt = extract_h(L_Temp); + + /* swLagRem = (OS_FCTR - pswLIn[iBig] % OS_FCTR)) */ + /*---------------------------------------------------*/ + swTempRem = extract_l(L_Temp); + swTempRem = shr(swTempRem, 1); + swLagRem = swTempRem & SW_MAX; + swLagRem = mult_r(swLagRem, OS_FCTR); + swLagRem = sub(OS_FCTR, swLagRem); + + /* Get interpolated C and G values */ + /*--------------------------*/ + + L_Temp1 = L_mac(32768, pswCIn[swLagInt - swLoIntLag], + ppsrCGIntFilt[0][swLagRem]); + L_Temp2 = L_mac(32768, pswGIn[swLagInt - swLoIntLag], + ppsrCGIntFilt[0][swLagRem]); + + for (i = 1; i <= CG_INT_MACS - 1; i++) + { + L_Temp1 = L_mac(L_Temp1, pswCIn[i + swLagInt - swLoIntLag], + ppsrCGIntFilt[i][swLagRem]); + L_Temp2 = L_mac(L_Temp2, pswGIn[i + swLagInt - swLoIntLag], + ppsrCGIntFilt[i][swLagRem]); + + } + pswCOut[swBig] = extract_h(L_Temp1); + pswGOut[swBig] = extract_h(L_Temp2); + } +} + +/*************************************************************************** + * + * FUNCTION NAME: CGInterpValid + * + * PURPOSE: + * + * The purpose of this function is to retrieve the valid (codeable) lags + * within one (exclusive) integer sample of the given integer lag, and + * interpolate the corresponding C's and G's from the integer arrays + * + * INPUTS: + * + * swFullResLag + * + * integer lag * OS_FCTR + * + * pswCIn[0:127] + * + * integer C sequence + * + * pswGIn[0:127] + * + * integer G sequence + * + * psrLagTbl[0:255] + * + * reference table of valid (codeable) lags + * + * + * OUTPUTS: + * + * pswLOut[0:*psiNum-1] + * + * list of valid lags within 1 of swFullResLag + * + * pswCOut[0:*psiNum-1] + * + * list of interpolated C's corresponding to pswLOut + * + * pswGOut[0:*psiNum-1] + * + * list of interpolated G's corresponding to pswLOut + * + * RETURN VALUE: + * + * siNum + * + * length of output lists + * + * DESCRIPTION: + * + * REFERENCE: Sub-clause 4.1.8.2, 4.1.9 of GSM Recommendation 06.20 + * + * KEYWORDS: CGInterpValid, cginterpvalid, CG_INT_VALID + * + *************************************************************************/ + +short CGInterpValid(int16_t swFullResLag, + int16_t pswCIn[], + int16_t pswGIn[], + int16_t pswLOut[], + int16_t pswCOut[], + int16_t pswGOut[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + short int siLowerBound, + siUpperBound, + siNum, + siI; + int16_t swLag; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Get lower and upper bounds for valid lags */ + /* within 1 (exclusive) integer lag of input lag */ + /* --------------------------------------------- */ + + swLag = sub(swFullResLag, OS_FCTR); + swLag = quantLag(swLag, &siLowerBound); + if (sub(swLag, swFullResLag) != 0) + { + siLowerBound = add(siLowerBound, 1); + } + + swLag = add(swFullResLag, OS_FCTR); + swLag = quantLag(swLag, &siUpperBound); + if (sub(swLag, swFullResLag) != 0) + { + siUpperBound = sub(siUpperBound, 1); + } + + /* Get list of full resolution lags whose */ + /* C's and G's will be interpolated */ + /* -------------------------------------- */ + + siNum = sub(siUpperBound, siLowerBound); + siNum = add(siNum, 1); + + for (siI = 0; siI < siNum; siI++) + { + pswLOut[siI] = psrLagTbl[siI + siLowerBound]; + } + + /* Interpolate C's and G's */ + /* ----------------------- */ + + CGInterp(pswLOut, siNum, pswCIn, pswGIn, LSMIN, pswCOut, + pswGOut); + + /* Return the length of the output lists */ + /* ------------------------------------- */ + + return (siNum); +} + +/*************************************************************************** + * + * FUNCTION NAME: compResidEnergy + * + * PURPOSE: + * + * Computes and compares the residual energy from interpolated and + * non-interpolated coefficients. From the difference determines + * the soft interpolation decision. + * + * INPUTS: + * + * pswSpeech[0:159] ( [0:F_LEN-1] ) + * + * Input speech frame (after high-pass filtering). + * + * ppswInterpCoef[0:3][0:9] ( [0:N_SUB-1][0:NP-1] ) + * + * Set of interpolated LPC direct-form coefficients for + * each subframe. + * + * pswPreviousCoef[0:9} ( [0:NP-1] ) + * + * Set of LPC direct-form coefficients corresponding to + * the previous frame + * + * pswCurrentCoef[0:9} ( [0:NP-1] ) + * + * Set of LPC direct-form coefficients corresponding to + * the current frame + * + * psnsSqrtRs[0:3] ( [0:N_SUB-1] ) + * + * Array of residual energy estimates for each subframe + * based on interpolated coefficients. Used for scaling. + * + * RETURN: + * + * Returned value indicates the coefficients to use for each subframe: + * One indicates interpolated coefficients are to be used, zero indicates + * un-interpolated coefficients are to be used. + * + * DESCRIPTION: + * + * + * REFERENCE: Sub-clause 4.1.6 of GSM Recommendation 06.20 + * + * Keywords: openlooplagsearch, openloop, lag, pitch + * + **************************************************************************/ + + + +short compResidEnergy(int16_t pswSpeech[], + int16_t ppswInterpCoef[][NP], + int16_t pswPreviousCoef[], + int16_t pswCurrentCoef[], + struct NormSw psnsSqrtRs[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + short i, + j, + siOverflowPossible, + siInterpDecision; + int16_t swMinShift, + swShiftFactor, + swSample, + *pswCoef; + int16_t pswTempState[NP]; + int16_t pswResidual[S_LEN]; + int32_t L_ResidualEng; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Find minimum shift count of the square-root of residual energy */ + /* estimates over the four subframes. According to this minimum, */ + /* find a shift count for the residual signal which will be used */ + /* to avoid overflow when the actual residual energies are */ + /* calculated over the frame */ + /*----------------------------------------------------------------*/ + + swMinShift = SW_MAX; + for (i = 0; i < N_SUB; i++) + { + + if (sub(psnsSqrtRs[i].sh, swMinShift) < 0 && psnsSqrtRs[i].man > 0) + swMinShift = psnsSqrtRs[i].sh; + } + + if (sub(swMinShift, 1) >= 0) + { + + siOverflowPossible = 0; + } + + else if (swMinShift == 0) + { + siOverflowPossible = 1; + swShiftFactor = ONE_HALF; + } + + else if (sub(swMinShift, -1) == 0) + { + siOverflowPossible = 1; + swShiftFactor = ONE_QUARTER; + } + + else + { + siOverflowPossible = 1; + swShiftFactor = ONE_EIGHTH; + } + + /* Copy analysis filter state into temporary buffer */ + /*--------------------------------------------------*/ + + for (i = 0; i < NP; i++) + pswTempState[i] = pswAnalysisState[i]; + + /* Send the speech frame, one subframe at a time, through the analysis */ + /* filter which is based on interpolated coefficients. After each */ + /* subframe, accumulate the energy in the residual signal, scaling to */ + /* avoid overflow if necessary. */ + /*---------------------------------------------------------------------*/ + + L_ResidualEng = 0; + + for (i = 0; i < N_SUB; i++) + { + + lpcFir(&pswSpeech[i * S_LEN], ppswInterpCoef[i], pswTempState, + pswResidual); + + if (siOverflowPossible) + { + + for (j = 0; j < S_LEN; j++) + { + + swSample = mult_r(swShiftFactor, pswResidual[j]); + L_ResidualEng = L_mac(L_ResidualEng, swSample, swSample); + } + } + + else + { + + for (j = 0; j < S_LEN; j++) + { + + L_ResidualEng = L_mac(L_ResidualEng, pswResidual[j], pswResidual[j]); + } + } + } + + /* Send the speech frame, one subframe at a time, through the analysis */ + /* filter which is based on un-interpolated coefficients. After each */ + /* subframe, subtract the energy in the residual signal from the */ + /* accumulated residual energy due to the interpolated coefficient */ + /* analysis filter, again scaling to avoid overflow if necessary. */ + /* Note that the analysis filter state is updated during these */ + /* filtering operations. */ + /*---------------------------------------------------------------------*/ + + for (i = 0; i < N_SUB; i++) + { + + switch (i) + { + + case 0: + + pswCoef = pswPreviousCoef; + break; + + case 1: + case 2: + case 3: + + pswCoef = pswCurrentCoef; + break; + } + + lpcFir(&pswSpeech[i * S_LEN], pswCoef, pswAnalysisState, + pswResidual); + + if (siOverflowPossible) + { + + for (j = 0; j < S_LEN; j++) + { + + swSample = mult_r(swShiftFactor, pswResidual[j]); + L_ResidualEng = L_msu(L_ResidualEng, swSample, swSample); + } + } + + else + { + + for (j = 0; j < S_LEN; j++) + { + + L_ResidualEng = L_msu(L_ResidualEng, pswResidual[j], pswResidual[j]); + } + } + } + + /* Make soft-interpolation decision based on the difference in residual */ + /* energies */ + /*----------------------------------------------------------------------*/ + + if (L_ResidualEng < 0) + siInterpDecision = 1; + + else + siInterpDecision = 0; + + return siInterpDecision; +} + +/*************************************************************************** + * + * FUNCTION NAME: cov32 + * + * PURPOSE: Calculates B, F, and C correlation matrices from which + * the reflection coefficients are computed using the FLAT + * algorithm. The Spectral Smoothing Technique (SST) is applied + * to the correlations. End point correction is employed + * in computing the correlations to minimize computation. + * + * INPUT: + * + * pswIn[0:169] + * A sampled speech vector used to compute + * correlations need for generating the optimal + * reflection coefficients via the FLAT algorithm. + * + * CVSHIFT The number of right shifts by which the normalized + * correlations are to be shifted down prior to being + * rounded into the int16_t output correlation arrays + * B, F, and C. + * + * pL_rFlatSstCoefs[NP] + * + * A table stored in Rom containing the spectral + * smoothing function coefficients. + * + * OUTPUTS: + * + * pppL_B[0:NP-1][0:NP-1][0:1] + * An output correlation array containing the backward + * correlations of the input signal. It is a square + * matrix symmetric about the diagonal. Only the upper + * right hand triangular region of this matrix is + * initialized, but two dimensional indexing is retained + * to enhance clarity. The third array dimension is used + * by function flat to swap the current and the past + * values of B array, eliminating the need to copy + * the updated B values onto the old B values at the + * end of a given lattice stage. The third dimension + * is similarily employed in arrays F and C. + * + * pppL_F[0:NP-1][0:NP-1][0:1] + * An output correlation array containing the forward + * correlations of the input signal. It is a square + * matrix symmetric about the diagonal. Only the upper + * right hand triangular region of this matrix is + * initialized. + * + * pppL_C[0:NP-1][0:NP-1][0:1] + * An output correlation array containing the cross + * correlations of the input signal. It is a square + * matrix which is not symmetric. All its elements + * are initialized, for the third dimension index = 0. + * + * pL_R0 Average normalized signal power over F_LEN + * samples, given by 0.5*(Phi(0,0)+Phi(NP,NP)), where + * Phi(0,0) and Phi(NP,NP) are normalized signal + * autocorrelations. The average unnormalized signal + * power over the frame is given by adjusting L_R0 by + * the shift count which is returned. pL_R0 along + * with the returned shift count are the inputs to + * the frame energy quantizer. + * + * int32_t pL_VadAcf[4] + * An array with the autocorrelation coefficients to be + * used by the VAD. + * + * int16_t *pswVadScalAuto + * Input scaling factor used by the VAD. + * + * RETURN: + * + * swNormPwr The shift count to be applied to pL_R0 for + * reconstructing the average unnormalized + * signal power over the frame. + * Negative shift count means that a left shift was + * applied to the correlations to achieve a normalized + * value of pL_R0. + * + * DESCRIPTION: + * + * + * The input energy of the signal is assumed unknown. It maximum + * can be F_LEN*0.5. The 0.5 factor accounts for scaling down of the + * input signal in the high-pass filter. Therefore the signal is + * shifted down by 3 shifts producing an energy reduction of 2^(2*3)=64. + * The resulting energy is then normalized. Based on the shift count, + * the correlations F, B, and C are computed using as few shifts as + * possible, so a precise result is attained. + * This is an implementation of equations: 2.1 through 2.11. + * + * REFERENCE: Sub-clause 4.1.3 of GSM Recommendation 06.20 + * + * keywords: energy, autocorrelation, correlation, cross-correlation + * keywords: spectral smoothing, SST, LPC, FLAT, flat + * + *************************************************************************/ + +int16_t cov32(int16_t pswIn[], + int32_t pppL_B[NP][NP][2], + int32_t pppL_F[NP][NP][2], + int32_t pppL_C[NP][NP][2], + int32_t *pL_R0, + int32_t pL_VadAcf[], + int16_t *pswVadScalAuto) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_max, + L_Pwr0, + L_Pwr, + L_temp, + pL_Phi[NP + 1]; + int16_t swTemp, + swNorm, + swNormSig, + swNormPwr, + pswInScale[A_LEN], + swPhiNorm; + short int i, + k, + kk, + n; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Calculate energy in the frame vector (160 samples) for each */ + /* of NP frame placements. The energy is reduced by 64. This is */ + /* accomplished by shifting the input right by 3 bits. An offset */ + /* of 0x117f0b is placed into the accumulator to account for */ + /* the worst case power gain due to the 3 LSB's of the input */ + /* signal which were right shifted. The worst case is that the */ + /* 3 LSB's were all set to 1 for each of the samples. Scaling of */ + /* the input by a half is assumed here. */ + /*---------------------------------------------------------------*/ + + L_max = 0; + for (L_Pwr = 0x117f0b, i = 0; i < F_LEN; i++) + { + swTemp = shr(pswIn[i], 3); + L_Pwr = L_mac(L_Pwr, swTemp, swTemp); + } + L_max |= L_Pwr; + + /* L_max tracks the maximum power over NP window placements */ + /*----------------------------------------------------------*/ + + for (i = 1; i <= NP; i++) + { + + /* Subtract the power due to 1-st sample from previous window + * placement. */ + /*-----------------------------------------------------------*/ + + swTemp = shr(pswIn[i - 1], 3); + L_Pwr = L_msu(L_Pwr, swTemp, swTemp); + + /* Add the power due to new sample at the current window placement. */ + /*------------------------------------------------------------------*/ + + swTemp = shr(pswIn[F_LEN + i - 1], 3); + L_Pwr = L_mac(L_Pwr, swTemp, swTemp); + + L_max |= L_Pwr; + + } + + /* Compute the shift count needed to achieve normalized value */ + /* of the correlations. */ + /*------------------------------------------------------------*/ + + swTemp = norm_l(L_max); + swNorm = sub(6, swTemp); + + if (swNorm >= 0) + { + + /* The input signal needs to be shifted down, to avoid limiting */ + /* so compute the shift count to be applied to the input. */ + /*--------------------------------------------------------------*/ + + swTemp = add(swNorm, 1); + swNormSig = shr(swTemp, 1); + swNormSig = add(swNormSig, 0x0001); + + } + else + { + /* No scaling down of the input is necessary */ + /*-------------------------------------------*/ + + swNormSig = 0; + + } + + /* Convert the scaling down, if any, which was done to the time signal */ + /* to the power domain, and save. */ + /*---------------------------------------------------------------------*/ + + swNormPwr = shl(swNormSig, 1); + + /* Buffer the input signal, scaling it down if needed. */ + /*-----------------------------------------------------*/ + + for (i = 0; i < A_LEN; i++) + { + pswInScale[i] = shr(pswIn[i], swNormSig); + } + + /* Compute from buffered (scaled) input signal the correlations */ + /* needed for the computing the reflection coefficients. */ + /*------------------------------------------------------------------*/ + + /* Compute correlation Phi(0,0) */ + /*------------------------------*/ + + L_Pwr = L_mult(pswInScale[NP], pswInScale[NP]); + for (n = 1; n < F_LEN; n++) + { + L_Pwr = L_mac(L_Pwr, pswInScale[NP + n], pswInScale[NP + n]); + } + pL_Phi[0] = L_Pwr; + + /* Get ACF[0] and input scaling factor for VAD algorithm */ + *pswVadScalAuto = swNormSig; + pL_VadAcf[0] = L_Pwr; + + /* Compute the remaining correlations along the diagonal which */ + /* starts at Phi(0,0). End-point correction is employed to */ + /* limit computation. */ + /*-------------------------------------------------------------*/ + + for (i = 1; i <= NP; i++) + { + + /* Compute the power in the last sample from the previous */ + /* window placement, and subtract it from correlation accumulated */ + /* at the previous window placement. */ + /*----------------------------------------------------------------*/ + + L_Pwr = L_msu(L_Pwr, pswInScale[NP + F_LEN - i], + pswInScale[NP + F_LEN - i]); + + /* Compute the power in the new sample for the current window */ + /* placement, and add it to L_Pwr to obtain the value of Phi(i,i). */ + /*------------------------------------------------------------------*/ + + L_Pwr = L_mac(L_Pwr, pswInScale[NP - i], pswInScale[NP - i]); + + pL_Phi[i] = L_Pwr; + + } + + /* Compute the shift count necessary to normalize the Phi array */ + /*---------------------------------------------------------------*/ + + L_max = 0; + for (i = 0; i <= NP; i++) + { + L_max |= pL_Phi[i]; + } + swPhiNorm = norm_l(L_max); + + /* Adjust the shift count to be returned to account for any scaling */ + /* down which might have been done to the input signal prior to */ + /* computing the correlations. */ + /*------------------------------------------------------------------*/ + + swNormPwr = sub(swNormPwr, swPhiNorm); + + /* Compute the average power over the frame; i.e., */ + /* 0.5*(Phi(0,0)+Phi(NP,NP)), given a normalized pL_Phi array. */ + /*-------------------------------------------------------------------*/ + + swTemp = sub(swPhiNorm, 1); + L_Pwr0 = L_shl(pL_Phi[0], swTemp); + L_Pwr = L_shl(pL_Phi[NP], swTemp); + *pL_R0 = L_add(L_Pwr, L_Pwr0); /* Copy power to output pointer */ + + /* Check if the average power is normalized; if not, shift left by 1 bit */ + /*-----------------------------------------------------------------------*/ + + if (!(*pL_R0 & 0x40000000)) + { + *pL_R0 = L_shl(*pL_R0, 1); /* normalize the average power */ + swNormPwr = sub(swNormPwr, 1); /* adjust the shift count */ + } + + /* Reduce the shift count needed to normalize the correlations */ + /* by CVSHIFT bits. */ + /*---------------------------------------------------------------*/ + + swNorm = sub(swPhiNorm, CVSHIFT); + + /* Initialize the F, B, and C output correlation arrays, using the */ + /* Phi correlations computed along the diagonal of symmetry. */ + /*-----------------------------------------------------------------*/ + + L_temp = L_shl(pL_Phi[0], swNorm); /* Normalize the result */ + + pppL_F[0][0][0] = L_temp; /* Write to output array */ + + for (i = 1; i <= NP - 1; i++) + { + + L_temp = L_shl(pL_Phi[i], swNorm); /* Normalize the result */ + + + pppL_F[i][i][0] = L_temp; /* Write to output array */ + pppL_B[i - 1][i - 1][0] = L_temp; /* Write to output array */ + pppL_C[i][i - 1][0] = L_temp; /* Write to output array */ + + } + + L_temp = L_shl(pL_Phi[NP], swNorm); /* Normalize the result */ + + pppL_B[NP - 1][NP - 1][0] = L_temp; /* Write to output array */ + + for (k = 1; k <= NP - 1; k++) + { + + /* Compute correlation Phi(0,k) */ + /*------------------------------*/ + + L_Pwr = L_mult(pswInScale[NP], pswInScale[NP - k]); + for (n = 1; n < F_LEN; n++) + { + L_Pwr = L_mac(L_Pwr, pswInScale[NP + n], pswInScale[NP + n - k]); + } + /* convert covariance values to ACF and store for VAD algorithm */ + if (k < 9) + { + pL_VadAcf[k] = L_Pwr; + for (kk = 0; kk < k; kk++) + { + pL_VadAcf[k] = L_msu(pL_VadAcf[k], pswInScale[NP + kk], + pswInScale[NP + kk - k]); + } + } + + L_temp = L_shl(L_Pwr, swNorm); /* Normalize the result */ + L_temp = L_mpy_ll(L_temp, pL_rFlatSstCoefs[k - 1]); /* Apply SST */ + + pppL_F[0][k][0] = L_temp; /* Write to output array */ + pppL_C[0][k - 1][0] = L_temp; /* Write to output array */ + + + /* Compute the remaining correlations along the diagonal which */ + /* starts at Phi(0,k). End-point correction is employed to */ + /* limit computation. */ + /*-------------------------------------------------------------*/ + + for (kk = k + 1, i = 1; kk <= NP - 1; kk++, i++) + { + + /* Compute the power in the last sample from the previous */ + /* window placement, and subtract it from correlation accumulated */ + /* at the previous window placement. */ + /*----------------------------------------------------------------*/ + + L_Pwr = L_msu(L_Pwr, pswInScale[NP + F_LEN - i], + pswInScale[NP + F_LEN - kk]); + + /* Compute the power in the new sample for the current window */ + /* placement, and add it to L_Pwr to obtain the value of Phi(i,kk). */ + /*------------------------------------------------------------------*/ + + L_Pwr = L_mac(L_Pwr, pswInScale[NP - i], pswInScale[NP - kk]); + + L_temp = L_shl(L_Pwr, swNorm); /* Normalize */ + L_temp = L_mpy_ll(L_temp, pL_rFlatSstCoefs[k - 1]); /* Apply SST */ + + pppL_F[i][kk][0] = L_temp; /* Write to output array */ + pppL_B[i - 1][kk - 1][0] = L_temp; /* Write to output array */ + pppL_C[i][kk - 1][0] = L_temp; /* Write to output array */ + pppL_C[kk][i - 1][0] = L_temp; /* Write to output array */ + + } + + /* Compute the power in the last sample from the previous */ + /* window placement, and subtract it from correlation accumulated */ + /* at the previous window placement. */ + /*----------------------------------------------------------------*/ + + L_Pwr = L_msu(L_Pwr, pswInScale[F_LEN + k], pswInScale[F_LEN]); + + /* Compute the power in the new sample for the current window */ + /* placement, and add it to L_Pwr to obtain the value of Phi(i,kk). */ + /*------------------------------------------------------------------*/ + + L_Pwr = L_mac(L_Pwr, pswInScale[k], pswInScale[0]); + + L_temp = L_shl(L_Pwr, swNorm); /* Normalize the result */ + L_temp = L_mpy_ll(L_temp, pL_rFlatSstCoefs[k - 1]); /* Apply SST */ + + pppL_B[NP - k - 1][NP - 1][0] = L_temp; /* Write to output array */ + pppL_C[NP - k][NP - 1][0] = L_temp;/* Write to output array */ + + } + + /* Compute correlation Phi(0,NP) */ + /*-------------------------------*/ + + L_Pwr = L_mult(pswInScale[NP], pswInScale[0]); + for (n = 1; n < F_LEN; n++) + { + L_Pwr = L_mac(L_Pwr, pswInScale[NP + n], pswInScale[n]); + } + + L_temp = L_shl(L_Pwr, swNorm); /* Normalize the result */ + L_temp = L_mpy_ll(L_temp, pL_rFlatSstCoefs[NP - 1]); /* Apply SST */ + + pppL_C[0][NP - 1][0] = L_temp; /* Write to output array */ + + return (swNormPwr); + +} + +/*************************************************************************** + * + * FUNCTION NAME: filt4_2nd + * + * PURPOSE: Implements a fourth order filter by cascading two second + * order sections. + * + * INPUTS: + * + * pswCoef[0:9] An array of two sets of filter coefficients. + * + * pswIn[0:159] An array of input samples to be filtered, filtered + * output samples written to the same array. + * + * pswXstate[0:3] An array containing x-state memory for two 2nd order + * filter sections. + * + * pswYstate[0:7] An array containing y-state memory for two 2nd order + * filter sections. + * + * npts Number of samples to filter (must be even). + * + * shifts number of shifts to be made on output y(n). + * + * OUTPUTS: + * + * pswIn[0:159] Output array containing the filtered input samples. + * + * RETURN: + * + * none. + * + * DESCRIPTION: + * + * data structure: + * + * Coeff array order: (b2,b1,b0,a2,a1)Section 1;(b2,b1,b0,a2,a1)Section 2 + * Xstate array order: (x(n-2),x(n-1))Section 1; (x(n-2),x(n-1))Section 2 + * Ystate array order: y(n-2)MSB,y(n-2)LSB,y(n-1)MSB,y(n-1)LSB Section 1 + * y(n-2)MSB,y(n-2)LSB,y(n-1)MSB,y(n-1)LSB Section 2 + * + * REFERENCE: Sub-clause 4.1.1 GSM Recommendation 06.20 + * + * KEYWORDS: highpass filter, hp, HP, filter + * + *************************************************************************/ + +void filt4_2nd(int16_t pswCoeff[], int16_t pswIn[], + int16_t pswXstate[], int16_t pswYstate[], + int npts, int shifts) +{ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Do first second order section */ + /*-------------------------------*/ + + iir_d(&pswCoeff[0],pswIn,&pswXstate[0],&pswYstate[0],npts,shifts,1,0); + + + /* Do second second order section */ + /*--------------------------------*/ + + iir_d(&pswCoeff[5],pswIn,&pswXstate[2],&pswYstate[4],npts,shifts,0,1); + +} + +/*************************************************************************** + * + * FUNCTION NAME: findBestInQuantList + * + * PURPOSE: + * Given a list of quantizer vectors and their associated prediction + * errors, search the list for the iNumVectOut vectors and output them + * as a new list. + * + * INPUTS: psqlInList, iNumVectOut + * + * OUTPUTS: psqlBestOutList + * + * RETURN VALUE: none + * + * DESCRIPTION: + * + * The AFLAT recursion yields prediction errors. This routine finds + * the lowest candidate is the AFLAT recursion outputs. + * + * + * KEYWORDS: best quantlist find + * + * REFERENCE: Sub-clause 4.1.4.1 GSM Recommendation 06.20 + * + *************************************************************************/ + +void findBestInQuantList(struct QuantList psqlInList, + int iNumVectOut, + struct QuantList psqlBestOutList[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int quantIndex, + bstIndex, + i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* initialize the best list */ + /* invalidate, ensure they will be dropped */ + for (bstIndex = 0; bstIndex < iNumVectOut; bstIndex++) + { + psqlBestOutList[bstIndex].iNum = 1; + psqlBestOutList[bstIndex].iRCIndex = psqlInList.iRCIndex; + psqlBestOutList[bstIndex].pswPredErr[0] = 0x7fff; + } + + /* best list elements replaced in the order: 0,1,2,3... challenger must + * be < (not <= ) current best */ + for (quantIndex = 0; quantIndex < psqlInList.iNum; quantIndex++) + { + bstIndex = 0; + while (sub(psqlInList.pswPredErr[quantIndex], + psqlBestOutList[bstIndex].pswPredErr[0]) >= 0 && + bstIndex < iNumVectOut) + { + bstIndex++; /* only increments to next upon + * failure to beat "best" */ + } + + if (bstIndex < iNumVectOut) + { /* a new value is found */ + /* now add challenger to best list at index bstIndex */ + for (i = iNumVectOut - 1; i > bstIndex; i--) + { + psqlBestOutList[i].pswPredErr[0] = + psqlBestOutList[i - 1].pswPredErr[0]; + psqlBestOutList[i].iRCIndex = + psqlBestOutList[i - 1].iRCIndex; + } + /* get new best value and place in list */ + psqlBestOutList[bstIndex].pswPredErr[0] = + psqlInList.pswPredErr[quantIndex]; + psqlBestOutList[bstIndex].iRCIndex = + psqlInList.iRCIndex + quantIndex; + } + } +} + +/*************************************************************************** + * + * FUNCTION NAME: findPeak + * + * PURPOSE: + * + * The purpose of this function is to return the lag + * that maximizes CC/G within +- PEAK_VICINITY of the + * input lag. The input lag is an integer lag, and + * the search for a peak is done on the surrounding + * integer lags. + * + * INPUTS: + * + * swSingleResLag + * + * Input integer lag, expressed as lag * OS_FCTR + * + * pswCIn[0:127] + * + * C(k) sequence, k an integer + * + * pswGIn[0:127] + * + * G(k) sequence, k an integer + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * Integer lag where peak was found, or zero if no peak was found. + * The lag is expressed as lag * OS_FCTR + * + * DESCRIPTION: + * + * This routine is called from pitchLags(), and is used to do the + * interpolating CC/G peak search. This is used in a number of + * places in pitchLags(). See description 5.3.1. + * + * REFERENCE: Sub-clause 4.1.8.2 of GSM Recommendation 06.20 + * + * KEYWORDS: + * + *************************************************************************/ + +int16_t findPeak(int16_t swSingleResLag, + int16_t pswCIn[], + int16_t pswGIn[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swCmaxSqr, + swGmax, + swFullResPeak; + short int siUpperBound, + siLowerBound, + siRange, + siPeak; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* get upper and lower bounds for integer lags for peak search */ + /* ----------------------------------------------------------- */ + + siUpperBound = add(swSingleResLag, PEAK_VICINITY + 1); + if (sub(siUpperBound, LMAX + 1) > 0) + { + siUpperBound = LMAX + 1; + } + + siLowerBound = sub(swSingleResLag, PEAK_VICINITY + 1); + if (sub(siLowerBound, LMIN - 1) < 0) + { + siLowerBound = LMIN - 1; + } + + siRange = sub(siUpperBound, siLowerBound); + siRange = add(siRange, 1); + + /* do peak search */ + /* -------------- */ + + swCmaxSqr = 0; + swGmax = 0x3f; + + siPeak = fnBest_CG(&pswCIn[siLowerBound - LSMIN], + &pswGIn[siLowerBound - LSMIN], &swCmaxSqr, &swGmax, + siRange); + + /* if no max found, flag no peak */ + /* ----------------------------- */ + + if (add(siPeak, 1) == 0) + { + swFullResPeak = 0; + } + + /* determine peak location */ + /* if at boundary, flag no peak */ + /* else return lag at peak */ + /* ---------------------------- */ + + else + { + siPeak = add(siPeak, siLowerBound); + + if ((sub(siPeak, siLowerBound) == 0) || + (sub(siPeak, siUpperBound) == 0)) + { + swFullResPeak = 0; + } + else + { + swFullResPeak = shr(extract_l(L_mult(siPeak, OS_FCTR)), 1); + } + } + return (swFullResPeak); +} + +/*************************************************************************** + * + * FUNCTION NAME: flat + * + * PURPOSE: Computes the unquantized reflection coefficients from the + * input speech using the FLAT algorithm. Also computes the + * frame energy, and the index of the element in the R0 + * quantization table which best represents the frame energy. + * Calls function cov32 which computes the F, B, and C + * correlation arrays, required by the FLAT algorithm to + * compute the reflection coefficients. + * + * INPUT: + * + * pswSpeechIn[0:169] + * A sampled speech vector used to compute + * correlations need for generating the optimal + * reflection coefficients via the FLAT algorithm. + * + * OUTPUTS: + * + * pswRc[NP] An array of unquantized reflection coefficients. + * + * *piR0Inx An index of the quantized frame energy value. + * + * int32_t pL_VadAcf[4] + * An array with the autocorrelation coefficients to be + * used by the VAD. Generated by cov16(), a daughter + * function of flat(). + * + * int16_t *pswVadScalAuto + * Input scaling factor used by the VAD. + * Generated by cov16(), a daughter function of flat(). + * function. + * + * RETURN: L_R0 normalized frame energy value, required in DTX + * mode. + * + * DESCRIPTION: + * + * An efficient Fixed point LAtice Technique (FLAT) is used to compute + * the reflection coefficients, given B, F, and C arrays returned by + * function cov32. B, F, and C are backward, forward, and cross + * correlations computed from the input speech. The correlations + * are spectrally smoothed in cov32. + * + * + * REFERENCE: Sub-clause 4.1.3 of GSM Recommendation 06.20 + * + * keywords: LPC, FLAT, reflection coefficients, covariance, correlation, + * keywords: spectrum, energy, R0, spectral smoothing, SST + * + *************************************************************************/ + +int32_t flat(int16_t pswSpeechIn[], + int16_t pswRc[], + int *piR0Inx, + int32_t pL_VadAcf[], + int16_t *pswVadScalAuto) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int16_t + swNum, + swDen, + swRcSq, + swSqrtOut, + swRShifts, + swShift, + swShift1; + int32_t + pppL_F[NP][NP][2], + pppL_B[NP][NP][2], + pppL_C[NP][NP][2], + L_Num, + L_TmpA, + L_TmpB, + L_temp, + L_sum, + L_R0, + L_Fik, + L_Bik, + L_Cik, + L_Cki; + short int i, + j, + k, + l, + j_0, + j_1; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Compute from the input speech the elements of the B, F, and C */ + /* arrays, which form the initial conditions for the FLAT algorithm. */ + /*-------------------------------------------------------------------*/ + + swRShifts = cov32(pswSpeechIn, pppL_B, pppL_F, pppL_C, &L_R0, + pL_VadAcf, pswVadScalAuto); + + /* Compute the intermediate quantities required by the R0 quantizer */ + /*------------------------------------------------------------------*/ + + if (L_R0 != 0) + { + swSqrtOut = sqroot(L_R0); /* If L_R0 > 0, compute sqrt */ + } + else + { + swSqrtOut = 0; /* L_R0 = 0, initialize sqrt(0) */ + } + + swRShifts = sub(S_SH + 2, swRShifts); + + /* If odd number of shifts compensate by sqrt(0.5) */ + /*-------------------------------------------------*/ + + if (swRShifts & 1) + { + L_temp = L_mult(swSqrtOut, 0x5a82); + } + else + { + L_temp = L_deposit_h(swSqrtOut); + } + swRShifts = shr(swRShifts, 1); + + if (swRShifts > 0) + { + L_temp = L_shr(L_temp, swRShifts); + } + else if (swRShifts < 0) + { + L_temp = 0; + } + + /* Given average energy L_temp, find the index in the R0 quantization */ + /* table which best represents it. */ + /*--------------------------------------------------------------------*/ + + *piR0Inx = r0Quant(L_temp); + + L_R0 = L_temp; /* save the unquantized R0 */ /* DTX mode */ + + /* Zero out the number of left-shifts to be applied to the */ + /* F, B, and C matrices. */ + /*----------------------------------------------------------*/ + + swShift = 0; + + /* Now compute the NP reflection coefficients */ + /*---------------------------------------------*/ + + for (j = 0; j < NP; j++) + { + + /* Initialize the modulo indices of the third dimension of arrays */ + /* F, B, and C, where indices j_0 and j_1 point to: */ + /* */ + /* j_0 = points to F, B, and C matrix values at stage j-0, which */ + /* is the current lattice stage. */ + /* j_1 = points to F, B, and C matrix values at stage j-1, which */ + /* is the previous lattice stage. */ + /* */ + /* Use of modulo address arithmetic permits to swap values of j_0 and */ + /* and j_1 at each lattice stage, thus eliminating the need to copy */ + /* the current elements of F, B, and C arrays, into the F, B, and C */ + /* arrays corresponding to the previous lattice stage, prior to */ + /* incrementing j, the index of the lattice filter stage. */ + /*--------------------------------------------------------------------*/ + + j_0 = (j + 1) % 2; + j_1 = j % 2; + + /* Get the numerator for computing the j-th reflection coefficient */ + /*-----------------------------------------------------------------*/ + + L_Num = L_add(L_shl(pppL_C[0][0][j_1], swShift), + L_shl(pppL_C[NP - j - 1][NP - j - 1][j_1], swShift)); + + /* Get the denominator for computing the j-th reflection coefficient */ + /*-------------------------------------------------------------------*/ + + L_temp = L_add(L_shl(pppL_F[0][0][j_1], swShift), + L_shl(pppL_B[0][0][j_1], swShift)); + L_TmpA = L_add(L_shl(pppL_F[NP - j - 1][NP - j - 1][j_1], swShift), + L_shl(pppL_B[NP - j - 1][NP - j - 1][j_1], swShift)); + L_sum = L_add(L_TmpA, L_temp); + L_sum = L_shr(L_sum, 1); + + /* Normalize the numerator and the denominator terms */ + /*---------------------------------------------------*/ + + swShift1 = norm_s(extract_h(L_sum)); + + L_sum = L_shl(L_sum, swShift1); + L_Num = L_shl(L_Num, swShift1); + + swNum = round(L_Num); + swDen = round(L_sum); + + if (swDen <= 0) + { + + /* Zero prediction error at the j-th lattice stage, zero */ + /* out remaining reflection coefficients and return. */ + /*-------------------------------------------------------*/ + + for (i = j; i < NP; i++) + { + pswRc[i] = 0; + } + + return (L_R0); + } + else + { + + /* Non-zero prediction error, check if the j-th reflection + * coefficient */ + /* about to be computed is stable. */ + /*-----------------------------------------------------------*/ + + if (sub(abs_s(swNum), swDen) >= 0) + { + + /* Reflection coefficient at j-th lattice stage unstable, so zero */ + /* out reflection coefficients for lattice stages i=j,...,NP-1, and */ + /* return. */ + /*-----------------------------------------------------------------*/ + + for (i = j; i < NP; i++) + { + pswRc[i] = 0; + } + + return (L_R0); + } + else + { + + /* j-th reflection coefficient is stable, compute it. */ + /*----------------------------------------------------*/ + + if (swNum < 0) + { + + swNum = negate(swNum); + pswRc[j] = divide_s(swNum, swDen); + + } + else + { + + pswRc[j] = divide_s(swNum, swDen); + pswRc[j] = negate(pswRc[j]); + + } /* j-th reflection coefficient + * sucessfully computed. */ + /*----------------------------------------------------*/ + + + } /* End of reflection coefficient + * stability test (and computation) */ + /*------------------------------------------------------------------*/ + + } /* End of non-zero prediction error + * case */ + /*----------------------------------------*/ + + + + /* If not at the last lattice stage, update F, B, and C arrays */ + /*-------------------------------------------------------------*/ + + if (j != NP - 1) + { + + /* Compute squared Rc[j] */ + /*-----------------------*/ + + swRcSq = mult_r(pswRc[j], pswRc[j]); + + i = 0; + k = 0; + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + + L_TmpA = L_add(L_Cik, L_Cik); + L_TmpA = L_mpy_ls(L_TmpA, pswRc[j]); + + /* Update the F array */ + /*--------------------*/ + + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + + L_temp = L_mpy_ls(L_Bik, swRcSq); + L_temp = L_add(L_temp, L_Fik); + pppL_F[i][k][j_0] = L_add(L_temp, L_TmpA); + + for (k = i + 1; k <= NP - j - 2; k++) + { + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + L_Cki = L_shl(pppL_C[k][i][j_1], swShift); + + L_TmpA = L_add(L_Cik, L_Cki); + L_TmpA = L_mpy_ls(L_TmpA, pswRc[j]); + + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + + L_TmpB = L_add(L_Bik, L_Fik); + L_TmpB = L_mpy_ls(L_TmpB, pswRc[j]); + + /* Update the F and C arrays */ + /*---------------------------------*/ + + L_temp = L_mpy_ls(L_Bik, swRcSq); + L_temp = L_add(L_temp, L_Fik); + pppL_F[i][k][j_0] = L_add(L_temp, L_TmpA); + + L_temp = L_mpy_ls(L_Cki, swRcSq); + L_temp = L_add(L_temp, L_Cik); + pppL_C[i][k - 1][j_0] = L_add(L_temp, L_TmpB); + + } + + k = NP - j - 1; + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + + L_TmpB = L_add(L_Bik, L_Fik); + L_TmpB = L_mpy_ls(L_TmpB, pswRc[j]); + + /* Update the C array */ + /*-----------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + L_Cki = L_shl(pppL_C[k][i][j_1], swShift); + + L_temp = L_mpy_ls(L_Cki, swRcSq); + L_temp = L_add(L_temp, L_Cik); + pppL_C[i][k - 1][j_0] = L_add(L_temp, L_TmpB); + + + for (i = 1; i <= NP - j - 2; i++) + { + + k = i; + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + + L_TmpA = L_add(L_Cik, L_Cik); + L_TmpA = L_mpy_ls(L_TmpA, pswRc[j]); + + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + + L_TmpB = L_add(L_Bik, L_Fik); + L_TmpB = L_mpy_ls(L_TmpB, pswRc[j]); + + /* Update F, B and C arrays */ + /*-----------------------------------*/ + + L_temp = L_mpy_ls(L_Bik, swRcSq); + L_temp = L_add(L_temp, L_Fik); + pppL_F[i][k][j_0] = L_add(L_temp, L_TmpA); + + L_temp = L_mpy_ls(L_Fik, swRcSq); + L_temp = L_add(L_temp, L_Bik); + pppL_B[i - 1][k - 1][j_0] = L_add(L_temp, L_TmpA); + + L_temp = L_mpy_ls(L_Cik, swRcSq); + L_temp = L_add(L_temp, L_Cik); + pppL_C[i][k - 1][j_0] = L_add(L_temp, L_TmpB); + + for (k = i + 1; k <= NP - j - 2; k++) + { + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + L_Cki = L_shl(pppL_C[k][i][j_1], swShift); + + L_TmpA = L_add(L_Cik, L_Cki); + L_TmpA = L_mpy_ls(L_TmpA, pswRc[j]); + + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + + L_TmpB = L_add(L_Bik, L_Fik); + L_TmpB = L_mpy_ls(L_TmpB, pswRc[j]); + + /* Update F, B and C arrays */ + /*-----------------------------------*/ + + L_temp = L_mpy_ls(L_Bik, swRcSq); + L_temp = L_add(L_temp, L_Fik); + pppL_F[i][k][j_0] = L_add(L_temp, L_TmpA); + + L_temp = L_mpy_ls(L_Fik, swRcSq); + L_temp = L_add(L_temp, L_Bik); + pppL_B[i - 1][k - 1][j_0] = L_add(L_temp, L_TmpA); + + L_temp = L_mpy_ls(L_Cki, swRcSq); + L_temp = L_add(L_temp, L_Cik); + pppL_C[i][k - 1][j_0] = L_add(L_temp, L_TmpB); + + L_temp = L_mpy_ls(L_Cik, swRcSq); + L_temp = L_add(L_temp, L_Cki); + pppL_C[k][i - 1][j_0] = L_add(L_temp, L_TmpB); + + } /* end of loop indexed by k */ + /*---------------------------*/ + + k = NP - j - 1; + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + L_Cki = L_shl(pppL_C[k][i][j_1], swShift); + + L_TmpA = L_add(L_Cik, L_Cki); + L_TmpA = L_mpy_ls(L_TmpA, pswRc[j]); + + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + + L_TmpB = L_add(L_Bik, L_Fik); + L_TmpB = L_mpy_ls(L_TmpB, pswRc[j]); + + /* Update B and C arrays */ + /*-----------------------------------*/ + + L_temp = L_mpy_ls(L_Fik, swRcSq); + L_temp = L_add(L_temp, L_Bik); + pppL_B[i - 1][k - 1][j_0] = L_add(L_temp, L_TmpA); + + L_temp = L_mpy_ls(L_Cki, swRcSq); + L_temp = L_add(L_temp, L_Cik); + pppL_C[i][k - 1][j_0] = L_add(L_temp, L_TmpB); + + } /* end of loop indexed by i */ + /*---------------------------*/ + + i = NP - j - 1; + for (k = i; k <= NP - j - 1; k++) + { + + /* Compute the common terms used by the FLAT recursion to reduce */ + /* computation. */ + /*---------------------------------------------------------------*/ + + L_Cik = L_shl(pppL_C[i][k][j_1], swShift); + + L_TmpA = L_add(L_Cik, L_Cik); + L_TmpA = L_mpy_ls(L_TmpA, pswRc[j]); + + /* Update B array */ + /*-----------------------------------*/ + + L_Bik = L_shl(pppL_B[i][k][j_1], swShift); + L_Fik = L_shl(pppL_F[i][k][j_1], swShift); + + L_temp = L_mpy_ls(L_Fik, swRcSq); + L_temp = L_add(L_temp, L_Bik); + pppL_B[i - 1][k - 1][j_0] = L_add(L_temp, L_TmpA); + + } /* end of loop indexed by k */ + /*-----------------------------------------------------------*/ + + /* OR the F and B matrix diagonals to find maximum for normalization */ + /*********************************************************************/ + + L_TmpA = 0; + for (l = 0; l <= NP - j - 2; l++) + { + L_TmpA |= pppL_F[l][l][j_0]; + L_TmpA |= pppL_B[l][l][j_0]; + } + /* Compute the shift count to be applied to F, B, and C arrays */ + /* at the next lattice stage. */ + /*-------------------------------------------------------------*/ + + if (L_TmpA > 0) + { + swShift = norm_l(L_TmpA); + swShift = sub(swShift, CVSHIFT); + } + else + { + swShift = 0; + } + + } /* End of update of F, B, and C + * arrays for the next lattice stage */ + /*----------------------------------------------------------------*/ + + } /* Finished computation of + * reflection coefficients */ + /*--------------------------------------------------------------*/ + + return (L_R0); + +} + +/************************************************************************** + * + * FUNCTION NAME: fnBest_CG + * + * PURPOSE: + * The purpose of this function is to determine the C:G pair from the + * input arrays which maximize C*C/G + * + * INPUTS: + * + * pswCframe[0:siNumPairs] + * + * pointer to start of the C frame vector + * + * pswGframe[0:siNumPairs] + * + * pointer to start of the G frame vector + * + * pswCmaxSqr + * + * threshold Cmax**2 or 0 if no threshold + * + * pswGmax + * + * threshold Gmax, must be > 0 + * + * siNumPairs + * + * number of C:G pairs to test + * + * OUTPUTS: + * + * pswCmaxSqr + * + * final Cmax**2 value + * + * pswGmax + * + * final Gmax value + * + * RETURN VALUE: + * + * siMaxLoc + * + * index of Cmax in the input C matrix or -1 if none + * + * DESCRIPTION: + * + * test the result of (C * C * Gmax) - (Cmax**2 * G) + * if the result is > 0 then a new max has been found + * the Cmax**2, Gmax and MaxLoc parameters are all updated accordingly. + * if no new max is found for all NumPairs then MaxLoc will retain its + * original value + * + * REFERENCE: Sub-clause 4.1.8.1, 4.1.8.2, and 4.1.8.3 of GSM + * Recommendation 06.20 + * + * KEYWORDS: C_Frame, G_Frame, Cmax, Gmax, DELTA_LAGS, PITCH_LAGS + * + +****************************************************************************/ + +short int fnBest_CG(int16_t pswCframe[], int16_t pswGframe[], + int16_t *pswCmaxSqr, int16_t *pswGmax, + short int siNumPairs) +{ + +/*_________________________________________________________________________ +| | +| Automatic Variables | +|___________________________________________________________________________| +*/ + + int32_t L_Temp2; + int16_t swCmaxSqr, + swGmax, + swTemp; + short int siLoopCnt, + siMaxLoc; + +/*_________________________________________________________________________ +| | +| Executable Code | +|___________________________________________________________________________| +*/ + + /* initialize */ + /* ---------- */ + + swCmaxSqr = *pswCmaxSqr; + swGmax = *pswGmax; + siMaxLoc = -1; + + for (siLoopCnt = 0; siLoopCnt < siNumPairs; siLoopCnt++) + { + + /* make sure both C and energy > 0 */ + /* ------------------------------- */ + + if ((pswGframe[siLoopCnt] > 0) && (pswCframe[siLoopCnt] > 0)) + { + + /* calculate (C * C) */ + /* ----------------- */ + + swTemp = mult_r(pswCframe[siLoopCnt], pswCframe[siLoopCnt]); + + /* calculate (C * C * Gmax) */ + /* ------------------------ */ + + L_Temp2 = L_mult(swTemp, swGmax); + + /* calculate (C * C * Gmax) - (Cmax**2 * G) */ + /* ----------------------------------------- */ + + L_Temp2 = L_msu(L_Temp2, swCmaxSqr, pswGframe[siLoopCnt]); + + /* if new max found, update it and its location */ + /* -------------------------------------------- */ + + if (L_Temp2 > 0) + { + swCmaxSqr = swTemp; /* Cmax**2 = current C * C */ + swGmax = pswGframe[siLoopCnt]; /* Gmax */ + siMaxLoc = siLoopCnt; /* max location = current (C) + * location */ + } + } + } + + /* set output */ + /* ---------- */ + + *pswCmaxSqr = swCmaxSqr; + *pswGmax = swGmax; + return (siMaxLoc); +} + +/*************************************************************************** + * + * FUNCTION NAME: fnExp2 + * + * PURPOSE: + * The purpose of this function is to implement a base two exponential + * 2**(32*x) by polynomial approximation + * + * + * INPUTS: + * + * L_Input + * + * unnormalized input exponent (input range constrained + * to be < 0; for input < -0.46 output is 0) + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swTemp4 + * + * exponential output + * + * DESCRIPTION: + * + * polynomial approximation is used for the generation of the exponential + * + * 2**(32*X) = 0.1713425*X*X + 0.6674432*X + 0.9979554 + * c2 c1 c0 + * + * REFERENCE: Sub-clause 4.1.8.2 of GSM Recommendation 06.20, eqn 3.9 + * + * KEYWORDS: EXP2, DELTA_LAGS + * + *************************************************************************/ + +int16_t fnExp2(int32_t L_Input) +{ + +/*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| +*/ + static int16_t pswPCoefE[3] = + { /* c2, c1, c0 */ + 0x15ef, 0x556f, 0x7fbd + }; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swTemp1, + swTemp2, + swTemp3, + swTemp4; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* initialize */ + /* ---------- */ + + swTemp3 = 0x0020; + + /* determine normlization shift count */ + /* ---------------------------------- */ + + swTemp1 = extract_h(L_Input); + L_Input = L_mult(swTemp1, swTemp3); + swTemp2 = extract_h(L_Input); + + /* determine un-normalized shift count */ + /* ----------------------------------- */ + + swTemp3 = -0x0001; + swTemp4 = sub(swTemp3, swTemp2); + + /* normalize input */ + /* --------------- */ + + L_Input = L_Input & LSP_MASK; + L_Input = L_add(L_Input, L_deposit_h(swTemp3)); + + L_Input = L_shr(L_Input, 1); + swTemp1 = extract_l(L_Input); + + /* calculate x*x*c2 */ + /* ---------------- */ + + swTemp2 = mult_r(swTemp1, swTemp1); + L_Input = L_mult(swTemp2, pswPCoefE[0]); + + /* calculate x*x*c2 + x*c1 */ + /* ----------------------- */ + + L_Input = L_mac(L_Input, swTemp1, pswPCoefE[1]); + + /* calculate x*x*c2 + x*c1 + c0 */ + /* --------------------------- */ + + L_Input = L_add(L_Input, L_deposit_h(pswPCoefE[2])); + + /* un-normalize exponent if its requires it */ + /* ---------------------------------------- */ + + if (swTemp4 > 0) + { + L_Input = L_shr(L_Input, swTemp4); + } + + /* return result */ + /* ------------- */ + + swTemp4 = extract_h(L_Input); + return (swTemp4); +} + +/*************************************************************************** + * + * FUNCTION NAME: fnLog2 + * + * PURPOSE: + * The purpose of this function is to take the log base 2 of input and + * divide by 32 and return; i.e. output = log2(input)/32 + * + * INPUTS: + * + * L_Input + * + * input + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * int16_t + * + * output + * + * DESCRIPTION: + * + * log2(x) = 4.0 * (-.3372223*x*x + .9981958*x -.6626105) + * c0 c1 c2 (includes sign) + * + * REFERENCE: Sub-clause 4.1.8.2 of GSM Recommendation 06.20, eqn 3.9 + * + * KEYWORDS: log, logarithm, logbase2, fnLog2 + * + *************************************************************************/ + +int16_t fnLog2(int32_t L_Input) +{ + +/*_________________________________________________________________________ + | | + | Static Variables | + |_________________________________________________________________________| +*/ + + static int16_t + swC0 = -0x2b2a, + swC1 = 0x7fc5, + swC2 = -0x54d0; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + short int siShiftCnt; + int16_t swInSqrd, + swIn; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* normalize input and store shifts required */ + /* ----------------------------------------- */ + + siShiftCnt = norm_l(L_Input); + L_Input = L_shl(L_Input, siShiftCnt); + siShiftCnt = add(siShiftCnt, 1); + siShiftCnt = negate(siShiftCnt); + + /* calculate x*x*c0 */ + /* ---------------- */ + + swIn = extract_h(L_Input); + swInSqrd = mult_r(swIn, swIn); + L_Input = L_mult(swInSqrd, swC0); + + /* add x*c1 */ + /* --------- */ + + L_Input = L_mac(L_Input, swIn, swC1); + + /* add c2 */ + /* ------ */ + + L_Input = L_add(L_Input, L_deposit_h(swC2)); + + /* apply *(4/32) */ + /* ------------- */ + + L_Input = L_shr(L_Input, 3); + L_Input = L_Input & 0x03ffffff; + siShiftCnt = shl(siShiftCnt, 10); + L_Input = L_add(L_Input, L_deposit_h(siShiftCnt)); + + /* return log */ + /* ---------- */ + + return (round(L_Input)); +} + +/*************************************************************************** + * + * FUNCTION NAME: getCCThreshold + * + * PURPOSE: + * The purpose of this function is to calculate a threshold for other + * correlations (subject to limits), given subframe energy (Rp0), + * correlation squared (CC), and energy of delayed sequence (G) + * + * INPUTS: + * + * swRp0 + * + * energy of the subframe + * + * swCC + * + * correlation (squared) of subframe and delayed sequence + * + * swG + * + * energy of delayed sequence + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swCCThreshold + * + * correlation (squared) threshold + * + * DESCRIPTION: + * + * CCt/0.5 = R - R(antilog(SCALE*log(max(CLAMP,(RG-CC)/RG)))) + * + * The threshold CCt is then applied with an understood value of Gt = 0.5 + * + * REFERENCE: Sub-clause 4.1.8.2 of GSM Recommendation 06.20, eqn 3.9 + * + * KEYWORDS: getCCThreshold, getccthreshold, GET_CSQ_THRES + * + *************************************************************************/ + +int16_t getCCThreshold(int16_t swRp0, + int16_t swCC, + int16_t swG) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swPGainClamp, + swPGainScale, + sw1; + int32_t L_1; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* load CLAMP and SCALE */ + /* -------------------- */ + + swPGainClamp = PGAIN_CLAMP; + swPGainScale = PGAIN_SCALE; + + /* calculate RG-CC */ + /* --------------- */ + + L_1 = L_mult(swRp0, swG); + sw1 = extract_h(L_1); + L_1 = L_sub(L_1, L_deposit_h(swCC)); + + /* if RG - CC > 0 do max(CLAMP, (RG-CC)/RG) */ + /* ---------------------------------------- */ + + if (L_1 > 0) + { + + sw1 = divide_s(extract_h(L_1), sw1); + + L_1 = L_deposit_h(sw1); + + if (sub(sw1, swPGainClamp) <= 0) + { + L_1 = L_deposit_h(swPGainClamp); + } + } + /* else max(CLAMP, (RG-CC)/RG) is CLAMP */ + /* ------------------------------------ */ + + else + { + L_1 = L_deposit_h(swPGainClamp); + } + + /* L_1 holds max(CLAMP, (RG-CC)/RG) */ + /* do antilog( SCALE * log( max() ) ) */ + /* ---------------------------------- */ + + sw1 = fnLog2(L_1); + + L_1 = L_mult(sw1, swPGainScale); + + sw1 = fnExp2(L_1); + + + /* do R - (R * antilog()) */ + /* ---------------------- */ + + L_1 = L_deposit_h(swRp0); + L_1 = L_msu(L_1, swRp0, sw1); + + /* apply Gt value */ + /* -------------- */ + + L_1 = L_shr(L_1, 1); + + return (extract_h(L_1)); +} + + +/*************************************************************************** + * + * FUNCTION NAME: getNWCoefs + * + * PURPOSE: + * + * Obtains best all-pole fit to various noise weighting + * filter combinations + * + * INPUTS: + * + * pswACoefs[0:9] - A(z) coefficient array + * psrNWCoefs[0:9] - filter smoothing coefficients + * + * OUTPUTS: + * + * pswHCoefs[0:9] - H(z) coefficient array + * + * RETURN VALUE: + * + * None + * + * DESCRIPTION: + * + * The function getNWCoefs() derives the spectral noise weighting + * coefficients W(z)and H(z). W(z) and H(z) actually consist of + * three filters in cascade. To avoid having such a complicated + * filter required for weighting, the filters are reduced to a + * single filter. + * + * This is accomplished by passing an impulse through the cascased + * filters. The impulse response of the filters is used to generate + * autocorrelation coefficients, which are then are transformed into + * a single direct form estimate of W(z) and H(z). This estimate is + * called HHat(z) in the documentation. + * + * + * REFERENCE: Sub-clause 4.1.7 of GSM Recommendation 06.20 + * + * KEYWORDS: spectral noise weighting, direct form coefficients + * KEYWORDS: getNWCoefs + * + *************************************************************************/ + +void getNWCoefs(int16_t pswACoefs[], + int16_t pswHCoefs[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t pswCoefTmp2[NP], + pswCoefTmp3[NP], + pswVecTmp[S_LEN], + pswVecTmp2[S_LEN], + pswTempRc[NP]; + int16_t swNormShift, + iLoopCnt, + iLoopCnt2; + int32_t pL_AutoCorTmp[NP + 1], + L_Temp; + short int siNum, + k; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Calculate smoothing parameters for all-zero filter */ + /* -------------------------------------------------- */ + + for (iLoopCnt = 0; iLoopCnt < NP; iLoopCnt++) + { + pswCoefTmp2[iLoopCnt] + = mult_r(psrNWCoefs[iLoopCnt], pswACoefs[iLoopCnt]); + } + + /* Calculate smoothing parameters for all-pole filter */ + /* -------------------------------------------------- */ + + for (iLoopCnt = 0; iLoopCnt < NP; iLoopCnt++) + { + pswCoefTmp3[iLoopCnt] = msu_r(0, psrNWCoefs[iLoopCnt + NP], + pswACoefs[iLoopCnt]); + } + + /* Get impulse response of 1st filter */ + /* Done by direct form IIR filter of order NP zero input response */ + /* -------------------------------------------------------------- */ + + lpcIrZsIir(pswACoefs, pswVecTmp2); + + /* Send impulse response of 1st filter through 2nd filter */ + /* All-zero filter (FIR) */ + /* ------------------------------------------------------ */ + + lpcZsFir(pswVecTmp2, pswCoefTmp2, pswVecTmp); + + /* Send impulse response of 2nd filter through 3rd filter */ + /* All-pole filter (IIR) */ + /* ------------------------------------------------------ */ + + lpcZsIirP(pswVecTmp, pswCoefTmp3); + + /* Calculate energy in impulse response */ + /* ------------------------------------ */ + + swNormShift = g_corr1(pswVecTmp, &L_Temp); + + pL_AutoCorTmp[0] = L_Temp; + + /* Calculate normalized autocorrelation function */ + /* --------------------------------------------- */ + + for (k = 1; k <= NP; k++) + { + + /* Calculate R(k), equation 2.31 */ + /* ----------------------------- */ + + L_Temp = L_mult(pswVecTmp[0], pswVecTmp[0 + k]); + + for (siNum = S_LEN - k, iLoopCnt2 = 1; iLoopCnt2 < siNum; iLoopCnt2++) + { + L_Temp = L_mac(L_Temp, pswVecTmp[iLoopCnt2], + pswVecTmp[iLoopCnt2 + k]); + } + + /* Normalize R(k) relative to R(0): */ + /* -------------------------------- */ + + pL_AutoCorTmp[k] = L_shl(L_Temp, swNormShift); + + } + + + /* Convert normalized autocorrelations to direct form coefficients */ + /* --------------------------------------------------------------- */ + + aFlatRcDp(pL_AutoCorTmp, pswTempRc); + rcToADp(ASCALE, pswTempRc, pswHCoefs); + +} + +/*************************************************************************** + * + * FUNCTION NAME: getNextVec + * + * PURPOSE: + * The purpose of this function is to get the next vector in the list. + * + * INPUTS: none + * + * OUTPUTS: pswRc + * + * RETURN VALUE: none + * + * DESCRIPTION: + * + * Both the quantizer and pre-quantizer are set concatenated 8 bit + * words. Each of these words represents a reflection coefficient. + * The 8 bit words, are actually indices into a reflection + * coefficient lookup table. Memory is organized in 16 bit words, so + * there are two reflection coefficients per ROM word. + * + * + * The full quantizer is subdivided into blocks. Each of the + * pre-quantizers vectors "points" to a full quantizer block. The + * vectors in a block, are comprised of either three or four + * elements. These are concatenated, without leaving any space + * between them. + * + * A block of full quantizer elements always begins on an even word. + * This may or may not leave a space depending on vector quantizer + * size. + * + * getNextVec(), serves to abstract this arcane data format. Its + * function is to simply get the next reflection coefficient vector + * in the list, be it a pre or full quantizer list. This involves + * figuring out whether to pick the low or the high part of the 16 + * bit ROM word. As well as transforming the 8 bit stored value + * into a fractional reflection coefficient. It also requires a + * setup routine to initialize iWordPtr and iWordHalfPtr, two + * variables global to this file. + * + * + * + * REFERENCE: Sub-clause 4.1.4.1 of GSM Recommendation 06.20 + * + * KEYWORDS: Quant quant vector quantizer + * + *************************************************************************/ + +void getNextVec(int16_t pswRc[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + i = iLow; + + if (iThree) + { + + if (iWordHalfPtr == HIGH) + { + pswRc[i++] = psrSQuant[high(psrTable[iWordPtr])]; + pswRc[i++] = psrSQuant[low(psrTable[iWordPtr++])]; + pswRc[i] = psrSQuant[high(psrTable[iWordPtr])]; + iWordHalfPtr = LOW; + } + else + { + pswRc[i++] = psrSQuant[low(psrTable[iWordPtr++])]; + pswRc[i++] = psrSQuant[high(psrTable[iWordPtr])]; + pswRc[i] = psrSQuant[low(psrTable[iWordPtr++])]; + iWordHalfPtr = HIGH; + } + + } + else + { + pswRc[i++] = psrSQuant[high(psrTable[iWordPtr])]; + pswRc[i++] = psrSQuant[low(psrTable[iWordPtr++])]; + pswRc[i++] = psrSQuant[high(psrTable[iWordPtr])]; + pswRc[i] = psrSQuant[low(psrTable[iWordPtr++])]; + } +} + +/*************************************************************************** + * + * FUNCTION NAME: getSfrmLpcTx + * + * PURPOSE: + * Given frame information from past and present frame, interpolate + * (or copy) the frame based lpc coefficients into subframe + * lpc coeffs, i.e. the ones which will be used by the subframe + * as opposed to those coded and transmitted. + * + * INPUT: + * swPrevR0,swNewR0 - Rq0 for the last frame and for this frame. + * These are the decoded values, not the codewords. + * + * Previous lpc coefficients from the previous FRAME: + * in all filters below array[0] is the t=-1 element array[NP-1] + * t=-NP element. + * pswPrevFrmKs[NP] - decoded version of the rc's tx'd last frame + * pswPrevFrmAs[NP] - the above K's converted to A's. i.e. direct + * form coefficients. + * pswPrevFrmSNWCoef[NP] - Coefficients for the Spectral Noise + * weighting filter from the previous frame + * + * pswHPFSppech - pointer to High Pass Filtered Input speech + * + * pswSoftInterp - a flag containing the soft interpolation + * decision. + * + * Current lpc coefficients from the current frame: + * pswNewFrmKs[NP],pswNewFrmAs[NP], + * pswNewFrmSNWCoef[NP] - Spectral Noise Weighting Coefficients + * for the current frame + * ppswSNWCoefAs[1][NP] - pointer into a matrix containing + * the interpolated and uninterpolated LP Coefficient + * values for the Spectral Noise Weighting Filter. + * + * OUTPUT: + * psnsSqrtRs[N_SUB] - a normalized number (struct NormSw) + * containing an estimate + * of RS for each subframe. (number and a shift) + * + * ppswSynthAs[N_SUM][NP] - filter coefficients used by the + * synthesis filter. + * + * DESCRIPTION: + * For interpolated subframes, the direct form coefficients + * are converted to reflection coeffiecients to check for + * filter stability. If unstable, the uninterpolated coef. + * are used for that subframe. + * + * + * REFERENCE: Sub-clause of 4.1.6 and 4.1.7 of GSM Recommendation + * 06.20 + * + * KEYWORDS: soft interpolation, int_lpc, interpolate, atorc, res_eng + * + *************************************************************************/ + + +void getSfrmLpcTx(int16_t swPrevR0, int16_t swNewR0, +/* last frm*/ + int16_t pswPrevFrmKs[], int16_t pswPrevFrmAs[], + int16_t pswPrevFrmSNWCoef[], +/* this frm*/ + int16_t pswNewFrmKs[], int16_t pswNewFrmAs[], + int16_t pswNewFrmSNWCoef[], + int16_t pswHPFSpeech[], +/* output */ + short *pswSoftInterp, + struct NormSw *psnsSqrtRs, + int16_t ppswSynthAs[][NP], int16_t ppswSNWCoefAs[][NP]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swSi; + int32_t L_Temp; + short int siSfrm, + siStable, + i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* perform interpolation - both for synth filter and noise wgt filt */ + /*------------------------------------------------------------------*/ + siSfrm = 0; + siStable = interpolateCheck(pswPrevFrmKs, pswPrevFrmAs, + pswPrevFrmAs, pswNewFrmAs, + psrOldCont[siSfrm], psrNewCont[siSfrm], + swPrevR0, + &psnsSqrtRs[siSfrm], + ppswSynthAs[siSfrm]); + if (siStable) + { + for (i = 0; i < NP; i++) + { + L_Temp = L_mult(pswNewFrmSNWCoef[i], psrNewCont[siSfrm]); + ppswSNWCoefAs[siSfrm][i] = mac_r(L_Temp, pswPrevFrmSNWCoef[i], + psrOldCont[siSfrm]); + } + } + else + { + + /* this subframe is unstable */ + /*---------------------------*/ + + for (i = 0; i < NP; i++) + { + ppswSNWCoefAs[siSfrm][i] = pswPrevFrmSNWCoef[i]; + } + + } + + /* interpolate subframes one and two */ + /*-----------------------------------*/ + + for (siSfrm = 1; siSfrm < N_SUB - 1; siSfrm++) + { + siStable = interpolateCheck(pswNewFrmKs, pswNewFrmAs, + pswPrevFrmAs, pswNewFrmAs, + psrOldCont[siSfrm], psrNewCont[siSfrm], + swNewR0, + &psnsSqrtRs[siSfrm], + ppswSynthAs[siSfrm]); + if (siStable) + { + for (i = 0; i < NP; i++) + { + L_Temp = L_mult(pswNewFrmSNWCoef[i], psrNewCont[siSfrm]); + ppswSNWCoefAs[siSfrm][i] = mac_r(L_Temp, pswPrevFrmSNWCoef[i], + psrOldCont[siSfrm]); + } + } + else + { + /* this sfrm has unstable filter coeffs, would like to interp but + * cant */ + /*--------------------------------------*/ + + for (i = 0; i < NP; i++) + { + ppswSNWCoefAs[siSfrm][i] = pswNewFrmSNWCoef[i]; + } + + } + } + + + /* the last subframe: never interpolate. */ + /*--------------------------------------*/ + + siSfrm = 3; + for (i = 0; i < NP; i++) + { + ppswSNWCoefAs[siSfrm][i] = pswNewFrmSNWCoef[i]; + ppswSynthAs[siSfrm][i] = pswNewFrmAs[i]; + } + + /* calculate the residual energy for the last subframe */ + /*-----------------------------------------------------*/ + + res_eng(pswNewFrmKs, swNewR0, &psnsSqrtRs[siSfrm]); + + + + /* done with interpolation, now compare the two sets of coefs. */ + /* make the decision whether to interpolate (1) or not (0) */ + /*---------------------------------------------------------------*/ + + swSi = compResidEnergy(pswHPFSpeech, + ppswSynthAs, pswPrevFrmAs, + pswNewFrmAs, psnsSqrtRs); + + if (swSi == 0) + { + + /* no interpolation done: copy the frame based data to output + * coeffiecient arrays */ + + siSfrm = 0; + for (i = 0; i < NP; i++) + { + ppswSNWCoefAs[siSfrm][i] = pswPrevFrmSNWCoef[i]; + ppswSynthAs[siSfrm][i] = pswPrevFrmAs[i]; + } + + /* get RS (energy in the residual) for subframe 0 */ + /*------------------------------------------------*/ + + res_eng(pswPrevFrmKs, swPrevR0, &psnsSqrtRs[siSfrm]); + + /* for subframe 1 and all subsequent sfrms, use lpc and R0 from new frm */ + /*---------------------------------------------------------------------*/ + + res_eng(pswNewFrmKs, swNewR0, &psnsSqrtRs[1]); + + for (siSfrm = 2; siSfrm < N_SUB; siSfrm++) + psnsSqrtRs[siSfrm] = psnsSqrtRs[1]; + + for (siSfrm = 1; siSfrm < N_SUB; siSfrm++) + { + for (i = 0; i < NP; i++) + { + ppswSNWCoefAs[siSfrm][i] = pswNewFrmSNWCoef[i]; + ppswSynthAs[siSfrm][i] = pswNewFrmAs[i]; + } + } + } + + *pswSoftInterp = swSi; +} + +/*************************************************************************** + * + * FUNCTION NAME: iir_d + * + * PURPOSE: Performs one second order iir section using double-precision. + * feedback,single precision xn and filter coefficients + * + * INPUTS: + * + * pswCoef[0:4] An array of filter coefficients. + * + * pswIn[0:159] An array of input samples to be filtered, filtered + * output samples written to the same array. + * + * pswXstate[0:1] An array containing x-state memory. + * + * pswYstate[0:3] An array containing y-state memory. + * + * npts Number of samples to filter (must be even). + * + * shifts number of shifts to be made on output y(n) before + * storing to y(n) states. + * + * swPreFirDownSh number of shifts apply to signal before the FIR. + * + * swFinalUpShift number of shifts apply to signal before outputting. + * + * OUTPUTS: + * + * pswIn[0:159] Output array containing the filtered input samples. + * + * RETURN: + * + * none. + * + * DESCRIPTION: + * + * Transfer function implemented: + * (b0 + b1*z-1 + b2*z-2)/(a0 - a1*z-1 - a2*z-2+ + * data structure: + * Coeff array order: b2,b1,b0,a2,a1 + * Xstate array order: x(n-2),x(n-1) + * Ystate array order: y(n-2)MSB,y(n-2)LSB,y(n-1)MSB,y(n-1)LSB + * + * There is no elaborate discussion of the filter, since it is + * trivial. + * + * The filter's cutoff frequency is 120 Hz. + * + * REFERENCE: Sub-clause 4.1.1 GSM Recommendation 06.20 + * + * KEYWORDS: highpass filter, hp, HP, filter + * + *************************************************************************/ + +void iir_d(int16_t pswCoeff[], int16_t pswIn[], int16_t pswXstate[], + int16_t pswYstate[], int npts, int shifts, + int16_t swPreFirDownSh, int16_t swFinalUpShift) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int loop_cnt; + int32_t L_sumA, + L_sumB; + int16_t swTemp, + pswYstate_0, + pswYstate_1, + pswYstate_2, + pswYstate_3, + pswXstate_0, + pswXstate_1, + swx0, + swx1; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* initialize the temporary state variables */ + /*------------------------------------------*/ + + pswYstate_0 = pswYstate[0]; + pswYstate_1 = pswYstate[1]; + pswYstate_2 = pswYstate[2]; + pswYstate_3 = pswYstate[3]; + + pswXstate_0 = pswXstate[0]; + pswXstate_1 = pswXstate[1]; + + for (loop_cnt = 0; loop_cnt < npts; loop_cnt += 2) + { + + swx0 = shr(pswIn[loop_cnt], swPreFirDownSh); + swx1 = shr(pswIn[loop_cnt + 1], swPreFirDownSh); + + L_sumB = L_mult(pswYstate_1, pswCoeff[3]); + L_sumB = L_mac(L_sumB, pswYstate_3, pswCoeff[4]); + L_sumB = L_shr(L_sumB, 14); + L_sumB = L_mac(L_sumB, pswYstate_0, pswCoeff[3]); + L_sumB = L_mac(L_sumB, pswYstate_2, pswCoeff[4]); + + + L_sumA = L_mac(L_sumB, pswCoeff[0], pswXstate_0); + L_sumA = L_mac(L_sumA, pswCoeff[1], pswXstate_1); + L_sumA = L_mac(L_sumA, pswCoeff[2], swx0); + + L_sumA = L_shl(L_sumA, shifts); + + pswXstate_0 = swx0; /* Update X state x(n-1) <- x(n) */ + + /* Update double precision Y state temporary variables */ + /*-----------------------------------------------------*/ + + pswYstate_0 = extract_h(L_sumA); + swTemp = extract_l(L_sumA); + swTemp = shr(swTemp, 2); + pswYstate_1 = 0x3fff & swTemp; + + /* Round, store output sample and increment to next input sample */ + /*---------------------------------------------------------------*/ + + pswIn[loop_cnt] = round(L_shl(L_sumA, swFinalUpShift)); + + L_sumB = L_mult(pswYstate_3, pswCoeff[3]); + L_sumB = L_mac(L_sumB, pswYstate_1, pswCoeff[4]); + L_sumB = L_shr(L_sumB, 14); + L_sumB = L_mac(L_sumB, pswYstate_2, pswCoeff[3]); + L_sumB = L_mac(L_sumB, pswYstate_0, pswCoeff[4]); + + + L_sumA = L_mac(L_sumB, pswCoeff[0], pswXstate_1); + L_sumA = L_mac(L_sumA, pswCoeff[1], pswXstate_0); + L_sumA = L_mac(L_sumA, pswCoeff[2], swx1); + + L_sumA = L_shl(L_sumA, shifts); + + pswXstate_1 = swx1; /* Update X state x(n-1) <- x(n) */ + + /* Update double precision Y state temporary variables */ + /*-----------------------------------------------------*/ + + pswYstate_2 = extract_h(L_sumA); + + swTemp = extract_l(L_sumA); + swTemp = shr(swTemp, 2); + pswYstate_3 = 0x3fff & swTemp; + + /* Round, store output sample and increment to next input sample */ + /*---------------------------------------------------------------*/ + + pswIn[loop_cnt + 1] = round(L_shl(L_sumA, swFinalUpShift)); + + } + + /* update the states for the next frame */ + /*--------------------------------------*/ + + pswYstate[0] = pswYstate_0; + pswYstate[1] = pswYstate_1; + pswYstate[2] = pswYstate_2; + pswYstate[3] = pswYstate_3; + + pswXstate[0] = pswXstate_0; + pswXstate[1] = pswXstate_1; + +} + +/*************************************************************************** + * + * FUNCTION NAME: initPBarVBarFullL + * + * PURPOSE: Given the int32_t normalized correlation sequence, function + * initPBarVBarL initializes the int32_t initial condition + * arrays pL_PBarFull and pL_VBarFull for a full 10-th order LPC + * filter. It also shifts down the pL_VBarFull and pL_PBarFull + * arrays by a global constant RSHIFT bits. The pL_PBarFull and + * pL_VBarFull arrays are used to set the initial int16_t + * P and V conditions which are used in the actual search of the + * Rc prequantizer and the Rc quantizer. + * + * This is an implementation of equations 4.14 and + * 4.15. + * + * INPUTS: + * + * pL_CorrelSeq[0:NP] + * A int32_t normalized autocorrelation array computed + * from unquantized reflection coefficients. + * + * RSHIFT The number of right shifts to be applied to the + * input correlations prior to initializing the elements + * of pL_PBarFull and pL_VBarFull output arrays. RSHIFT + * is a global constant. + * + * OUTPUTS: + * + * pL_PBarFull[0:NP-1] + * A int32_t output array containing the P initial + * conditions for the full 10-th order LPC filter. + * The address of the 0-th element of pL_PBarFull + * is passed in when function initPBarVBarFullL is + * called. + * + * pL_VBarFull[-NP+1:NP-1] + * A int32_t output array containing the V initial + * conditions for the full 10-th order LPC filter. + * The address of the 0-th element of pL_VBarFull is + * passed in when function initPBarVBarFullL is called. + * RETURN: + * none. + * + * REFERENCE: Sub-clause 4.1.4.1 GSM Recommendation 06.20 + * + *************************************************************************/ + +void initPBarFullVBarFullL(int32_t pL_CorrelSeq[], + int32_t pL_PBarFull[], + int32_t pL_VBarFull[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i, + bound; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Initialize the AFLAT recursion PBarFull and VBarFull 32 bit arrays */ + /* for a 10-th order LPC filter. */ + /*--------------------------------------------------------------------*/ + + bound = NP - 1; + + for (i = 0; i <= bound; i++) + { + pL_PBarFull[i] = L_shr(pL_CorrelSeq[i], RSHIFT); + } + + for (i = -bound; i < 0; i++) + { + pL_VBarFull[i] = pL_PBarFull[-i - 1]; + } + + for (i = 0; i < bound; i++) + { + pL_VBarFull[i] = pL_PBarFull[i + 1]; + } + + pL_VBarFull[bound] = L_shr(pL_CorrelSeq[bound + 1], RSHIFT); + +} + +/*************************************************************************** + * + * FUNCTION NAME: initPBarVBarL + * + * PURPOSE: Given the int32_t pL_PBarFull array, + * function initPBarVBarL initializes the int16_t initial + * condition arrays pswPBar and pswVBar for a 3-rd order LPC + * filter, since the order of the 1st Rc-VQ segment is 3. + * The pswPBar and pswVBar arrays are a int16_t subset + * of the initial condition array pL_PBarFull. + * pswPBar and pswVBar are the initial conditions for the AFLAT + * recursion at a given segment. The AFLAT recursion is used + * to evaluate the residual error due to an Rc vector selected + * from a prequantizer or a quantizer. + * + * This is an implementation of equation 4.18 and 4.19. + * + * INPUTS: + * + * pL_PBarFull[0:NP-1] + * A int32_t input array containing the P initial + * conditions for the full 10-th order LPC filter. + * The address of the 0-th element of pL_PBarFull + * is passed in when function initPBarVBarL is called. + * + * OUTPUTS: + * + * pswPBar[0:NP_AFLAT-1] + * The output int16_t array containing the P initial + * conditions for the P-V AFLAT recursion, set here + * for the Rc-VQ search at the 1st Rc-VQ segment. + * The address of the 0-th element of pswPBar is + * passed in when function initPBarVBarL is called. + * + * pswVBar[-NP_AFLAT+1:NP_AFLAT-1] + * The output int16_t array containing the V initial + * conditions for the P-V AFLAT recursion, set here + * for the Rc-VQ search at the 1st Rc-VQ segment. + * The address of the 0-th element of pswVBar is + * passed in when function initPBarVBarL is called. + * + * RETURN: + * + * none. + * + * REFERENCE: Sub-clause 4.1.4.1 GSM Recommendation 06.20 + * + * + *************************************************************************/ + +void initPBarVBarL(int32_t pL_PBarFull[], + int16_t pswPBar[], + int16_t pswVBar[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int bound, + i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Initialize the AFLAT recursion P and V 16 bit arrays for a 3-rd */ + /* order LPC filter corresponding to the 1-st reflection coefficient */ + /* VQ segment. The PBar and VBar arrays store the initial conditions */ + /* for the evaluating the residual error due to Rc vectors being */ + /* evaluated from the Rc-VQ codebook at the 1-st Rc-VQ segment. */ + /*--------------------------------------------------------------------*/ + bound = 2; + + for (i = 0; i <= bound; i++) + { + pswPBar[i] = round(pL_PBarFull[i]); + } + for (i = -bound; i < 0; i++) + { + pswVBar[i] = pswPBar[-i - 1]; + } + for (i = 0; i < bound; i++) + { + pswVBar[i] = pswPBar[i + 1]; + } + pswVBar[bound] = round(pL_PBarFull[bound + 1]); + +} + +/*************************************************************************** + * + * FUNCTION NAME: maxCCOverGWithSign + * + * PURPOSE: + * + * Finds lag which maximizes C^2/G ( C is allowed to be negative ). + * + * INPUTS: + * + * pswCIn[0:swNum-1] + * + * Array of C values + * + * pswGIn[0:swNum-1] + * + * Array of G values + * + * pswCCmax + * + * Initial value of CCmax + * + * pswGmax + * + * Initial value of Gmax + * + * swNum + * + * Number of lags to be searched + * + * OUTPUTS: + * + * pswCCmax + * + * Value of CCmax after search + * + * pswGmax + * + * Value of Gmax after search + * + * RETURN VALUE: + * + * maxCCGIndex - index for max C^2/G, defaults to zero if all G <= 0 + * + * DESCRIPTION: + * + * This routine is called from bestDelta(). The routine is a simple + * find the best in a list search. + * + * REFERENCE: Sub-clause 4.1.8.3 of GSM Recommendation 06.20 + * + * KEYWORDS: LTP correlation peak + * + *************************************************************************/ + +int16_t maxCCOverGWithSign(int16_t pswCIn[], + int16_t pswGIn[], + int16_t *pswCCMax, + int16_t *pswGMax, + int16_t swNum) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swCC, + i, + maxCCGIndex, + swCCMax, + swGMax; + int32_t L_Temp; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* initialize max c^2/g to be the initial trajectory */ + /*---------------------------------------------------*/ + + maxCCGIndex = 0; + swGMax = pswGIn[0]; + + if (pswCIn[0] < 0) + swCCMax = negate(mult_r(pswCIn[0], pswCIn[0])); + else + swCCMax = mult_r(pswCIn[0], pswCIn[0]); + + for (i = 1; i < swNum; i++) + { + + /* Imperfect interpolation can result in negative energies. */ + /* Check for this */ + /*----------------------------------------------------------*/ + + if (pswGIn[i] > 0) + { + + swCC = mult_r(pswCIn[i], pswCIn[i]); + + if (pswCIn[i] < 0) + swCC = negate(swCC); + + L_Temp = L_mult(swCC, swGMax); + L_Temp = L_msu(L_Temp, pswGIn[i], swCCMax); + + /* Check if C^2*Gmax - G*Cmax^2 > 0 */ + /* -------------------------------- */ + + if (L_Temp > 0) + { + swGMax = pswGIn[i]; + swCCMax = swCC; + maxCCGIndex = i; + } + } + } + *pswGMax = swGMax; + *pswCCMax = swCCMax; + + return (maxCCGIndex); +} /* end of maxCCOverGWithSign */ + +/*************************************************************************** + * + * FUNCTION NAME: openLoopLagSearch + * + * PURPOSE: + * + * Determines voicing level for the frame. If voiced, obtains list of + * lags to be searched in closed-loop lag search; and value of smoothed + * pitch and coefficient for harmonic-noise-weighting. + * + * INPUTS: + * + * pswWSpeech[-145:159] ( [-LSMAX:F_LEN-1] ) + * + * W(z) filtered speech frame, with some history. + * + * swPrevR0Index + * + * Index of R0 from the previous frame. + * + * swCurrR0Index + * + * Index of R0 for the current frame. + * + * psrLagTbl[0:255] + * + * Lag quantization table, in global ROM. + * + * ppsrCGIntFilt[0:5][0:5] ( [tap][phase] ) + * + * Interpolation smoothing filter for generating C(k) + * and G(k) terms, where k is fractional. Global ROM. + * + * swSP + * speech flag, required for DTX mode + * + * OUTPUTS: + * + * psiUVCode + * + * (Pointer to) the coded voicing level. + * + * pswLagList[0:?] + * + * Array of lags to use in the search of the adaptive + * codebook (long-term predictor). Length determined + * by pswNumLagList[]. + * + * pswNumLagList[0:3] ( [0:N_SUB-1] ) + * + * Array of number of lags to use in search of adaptive + * codebook (long-term predictor) for each subframe. + * + * pswPitchBuf[0:3] ( [0:N_SUB-1] ) + * + * Array of estimates of pitch, to be used in harmonic- + * noise-weighting. + * + * pswHNWCoefBuf[0:3] ( [0:N_SUB-1] ) + * + * Array of harmonic-noise-weighting coefficients. + * + * psnsWSfrmEng[-4:3] ( [-N_SUB:N_SUB-1] ) + * + * Array of energies of weighted speech (input speech + * sent through W(z) weighting filter), each stored as + * normalized fraction and shift count. The zero index + * corresponds to the first subframe of the current + * frame, so there is some history represented. The + * energies are used for scaling purposes only. + * + * pswVadLags[4] + * + * An array of int16_ts containing the best open + * loop LTP lags for the four subframes. + + * + * DESCRIPTION: + * + * Scaling is done on the input weighted speech, such that the C(k) and + * G(k) terms will all be representable. The amount of scaling is + * determined by the maximum energy of any subframe of weighted speech + * from the current frame or last frame. These energies are maintained + * in a buffer, and used for scaling when the excitation is determined + * later in the analysis. + * + * This function is the main calling program for the open loop lag + * search. + * + * REFERENCE: Sub-clauses 4.1.8.1-4.1.8.4 of GSM Recommendation 06.20 + * + * Keywords: openlooplagsearch, openloop, lag, pitch + * + **************************************************************************/ + + + +void openLoopLagSearch(int16_t pswWSpeech[], + int16_t swPrevR0Index, + int16_t swCurrR0Index, + int16_t *psiUVCode, + int16_t pswLagList[], + int16_t pswNumLagList[], + int16_t pswPitchBuf[], + int16_t pswHNWCoefBuf[], + struct NormSw psnsWSfrmEng[], + int16_t pswVadLags[], + int16_t swSP) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_WSfrmEng, + L_G, + L_C, + L_Voicing; + int16_t swBestPG, + swCCMax, + swGMax, + swCCDivG; + int16_t swTotalCCDivG, + swCC, + swG, + swRG; + short i, + j, + k, + siShift, + siIndex, + siTrajIndex, + siAnchorIndex; + short siNumPeaks, + siNumTrajToDo, + siPeakIndex, + siFIndex; + short siNumDelta, + siBIndex, + siBestTrajIndex = 0; + short siLowestSoFar, + siLagsSoFar, + si1, + si2, + si3; + struct NormSw snsMax; + + int16_t pswGFrame[G_FRAME_LEN]; + int16_t *ppswGSfrm[N_SUB]; + int16_t pswSfrmEng[N_SUB]; + int16_t pswCFrame[C_FRAME_LEN]; + int16_t *ppswCSfrm[N_SUB]; + int16_t pswLIntBuf[N_SUB]; + int16_t pswCCThresh[N_SUB]; + int16_t pswScaledWSpeechBuffer[W_F_BUFF_LEN]; + int16_t *pswScaledWSpeech; + int16_t ppswTrajLBuf[N_SUB * NUM_TRAJ_MAX][N_SUB]; + int16_t ppswTrajCCBuf[N_SUB * NUM_TRAJ_MAX][N_SUB]; + int16_t ppswTrajGBuf[N_SUB * NUM_TRAJ_MAX][N_SUB]; + int16_t pswLPeaks[2 * LMAX / LMIN]; + int16_t pswCPeaks[2 * LMAX / LMIN]; + int16_t pswGPeaks[2 * LMAX / LMIN]; + int16_t pswLArray[DELTA_LEVELS]; + + pswScaledWSpeech = pswScaledWSpeechBuffer + LSMAX; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Scale the weighted speech so that all correlations and energies */ + /* will be less than 1.0 in magnitude. The scale factor is */ + /* determined by the maximum energy of any subframe contained in */ + /* the weighted speech buffer */ + /*-----------------------------------------------------------------*/ + + /* Perform one frame of delay on the subframe energy array */ + /*---------------------------------------------------------*/ + + for (i = 0; i < N_SUB; i++) + psnsWSfrmEng[i - N_SUB] = psnsWSfrmEng[i]; + + /* Calculate the subframe energies of the current weighted speech frame. */ + /* Overflow protection is done based on the energy in the LPC analysis */ + /* window (previous or current) which is closest to the subframe. */ + /*----------------------------------------------------------------------*/ + + psnsWSfrmEng[0].sh = g_corr1s(&pswWSpeech[0], + r0BasedEnergyShft(swPrevR0Index), + &L_WSfrmEng); + psnsWSfrmEng[0].man = round(L_WSfrmEng); + + psnsWSfrmEng[1].sh = g_corr1s(&pswWSpeech[S_LEN], + r0BasedEnergyShft(swCurrR0Index), + &L_WSfrmEng); + psnsWSfrmEng[1].man = round(L_WSfrmEng); + + psnsWSfrmEng[2].sh = g_corr1s(&pswWSpeech[2 * S_LEN], + r0BasedEnergyShft(swCurrR0Index), + &L_WSfrmEng); + psnsWSfrmEng[2].man = round(L_WSfrmEng); + + psnsWSfrmEng[3].sh = g_corr1s(&pswWSpeech[3 * S_LEN], + r0BasedEnergyShft(swCurrR0Index), + &L_WSfrmEng); + psnsWSfrmEng[3].man = round(L_WSfrmEng); + + /* Find the maximum weighted speech subframe energy from all values */ + /* in the array (the array includes the previous frame's subframes, */ + /* and the current frame's subframes) */ + /*------------------------------------------------------------------*/ + + snsMax.man = 0; + snsMax.sh = 0; + for (i = -N_SUB; i < N_SUB; i++) + { + + if (psnsWSfrmEng[i].man > 0) + { + + if (snsMax.man == 0) + snsMax = psnsWSfrmEng[i]; + + if (sub(psnsWSfrmEng[i].sh, snsMax.sh) < 0) + snsMax = psnsWSfrmEng[i]; + + if (sub(psnsWSfrmEng[i].sh, snsMax.sh) == 0 && + sub(psnsWSfrmEng[i].man, snsMax.man) > 0) + snsMax = psnsWSfrmEng[i]; + } + } + + /* Now scale speech up or down, such that the maximum subframe */ + /* energy value will be in range [0.125, 0.25). This gives a */ + /* little room for other maxima, and interpolation filtering */ + /*-------------------------------------------------------------*/ + + siShift = sub(shr(snsMax.sh, 1), 1); + + for (i = 0; i < W_F_BUFF_LEN; i++) + pswScaledWSpeech[i - LSMAX] = shl(pswWSpeech[i - LSMAX], siShift); + + /* Calculate the G(k) (k an integer) terms for all subframes. (A note */ + /* on the organization of the G buffer: G(k) for a given subframe is */ + /* the energy in the weighted speech sequence of length S_LEN (40) */ + /* which begins k back from the beginning of the given subframe-- that */ + /* is, it begins at a lag of k. These sequences overlap from one */ + /* subframe to the next, so it is only necessary to compute and store */ + /* the unique energies. The unique energies are computed and stored */ + /* in this buffer, and pointers are assigned for each subframe to make */ + /* array indexing for each subframe easier. */ + /* */ + /* (Terms in the G buffer are in order of increasing k, so the energy */ + /* of the first sequence-- that is, the oldest sequence-- in the */ + /* weighted speech buffer appears at the end of the G buffer. */ + /* */ + /* (The subframe pointers are assigned so that they point to the first */ + /* k for their respective subframes, k = LSMIN.) */ + /*---------------------------------------------------------------------*/ + + L_G = 0; + for (i = -LSMAX; i < -LSMAX + S_LEN; i++) + L_G = L_mac(L_G, pswScaledWSpeech[i], pswScaledWSpeech[i]); + + pswGFrame[G_FRAME_LEN - 1] = extract_h(L_G); + + for (i = -LSMAX; i < G_FRAME_LEN - LSMAX - 1; i++) + { + + L_G = L_msu(L_G, pswScaledWSpeech[i], pswScaledWSpeech[i]); + L_G = L_mac(L_G, pswScaledWSpeech[i + S_LEN], + pswScaledWSpeech[i + S_LEN]); + pswGFrame[G_FRAME_LEN - LSMAX - 2 - i] = extract_h(L_G); + } + + ppswGSfrm[0] = pswGFrame + 3 * S_LEN; + ppswGSfrm[1] = pswGFrame + 2 * S_LEN; + ppswGSfrm[2] = pswGFrame + S_LEN; + ppswGSfrm[3] = pswGFrame; + + /* Copy the G(k) terms which also happen to be the subframe energies; */ + /* calculate the 4th subframe energy, which is not a G(k) */ + /*--------------------------------------------------------------------*/ + + pswSfrmEng[0] = pswGFrame[G_FRAME_LEN - 1 - LSMAX]; + pswSfrmEng[1] = pswGFrame[G_FRAME_LEN - 1 - LSMAX - S_LEN]; + pswSfrmEng[2] = pswGFrame[G_FRAME_LEN - 1 - LSMAX - 2 * S_LEN]; + + L_WSfrmEng = 0; + for (i = F_LEN - S_LEN; i < F_LEN; i++) + L_WSfrmEng = L_mac(L_WSfrmEng, pswScaledWSpeech[i], pswScaledWSpeech[i]); + + pswSfrmEng[3] = extract_h(L_WSfrmEng); + + /* Calculate the C(k) (k an integer) terms for all subframes. */ + /* (The C(k) terms are all unique, so there is no overlapping */ + /* as in the G buffer.) */ + /*------------------------------------------------------------*/ + + for (i = 0; i < N_SUB; i++) + { + + for (j = LSMIN; j <= LSMAX; j++) + { + + L_C = 0; + for (k = 0; k < S_LEN; k++) + { + + L_C = L_mac(L_C, pswScaledWSpeech[i * S_LEN + k], + pswScaledWSpeech[i * S_LEN - j + k]); + } + + pswCFrame[i * CG_TERMS + j - LSMIN] = extract_h(L_C); + } + } + + ppswCSfrm[0] = pswCFrame; + ppswCSfrm[1] = pswCFrame + CG_TERMS; + ppswCSfrm[2] = pswCFrame + 2 * CG_TERMS; + ppswCSfrm[3] = pswCFrame + 3 * CG_TERMS; + + /* For each subframe: find the max C(k)*C(k)/G(k) where C(k) > 0 and */ + /* k is integer; save the corresponding k; calculate the */ + /* threshold against which other peaks in the interpolated CC/G */ + /* sequence will be checked. Meanwhile, accumulate max CC/G over */ + /* the frame for the voiced/unvoiced determination. */ + /*-------------------------------------------------------------------*/ + + swBestPG = 0; + for (i = 0; i < N_SUB; i++) + { + + /* Find max CC/G (C > 0), store corresponding k */ + /*----------------------------------------------*/ + + swCCMax = 0; + swGMax = 0x003f; + siIndex = fnBest_CG(&ppswCSfrm[i][LMIN - LSMIN], + &ppswGSfrm[i][LMIN - LSMIN], + &swCCMax, &swGMax, + LMAX - LMIN + 1); + + if (siIndex == -1) + { + pswLIntBuf[i] = 0; + pswVadLags[i] = LMIN; /* store lag value for VAD algorithm */ + } + else + { + pswLIntBuf[i] = add(LMIN, (int16_t) siIndex); + pswVadLags[i] = pswLIntBuf[i]; /* store lag value for VAD algorithm */ + } + + if (pswLIntBuf[i] > 0) + { + + /* C > 0 was found: accumulate CC/G, get threshold */ + /*-------------------------------------------------*/ + + if (sub(swCCMax, swGMax) < 0) + swCCDivG = divide_s(swCCMax, swGMax); + else + swCCDivG = SW_MAX; + + swBestPG = add(swCCDivG, swBestPG); + + pswCCThresh[i] = getCCThreshold(pswSfrmEng[i], swCCMax, swGMax); + } + else + pswCCThresh[i] = 0; + } + + /* Make voiced/unvoiced decision */ + /*-------------------------------*/ + + L_Voicing = 0; + for (i = 0; i < N_SUB; i++) + L_Voicing = L_mac(L_Voicing, pswSfrmEng[i], UV_SCALE0); + + L_Voicing = L_add(L_Voicing, L_deposit_h(swBestPG)); + + if ( (L_Voicing <= 0) || (swSP == 0) ) + { + + /* Unvoiced: set return values to zero */ + /*-------------------------------------*/ + + for (i = 0; i < N_SUB; i++) + { + + pswNumLagList[i] = 0; + pswLagList[i] = 0; + pswPitchBuf[i] = 0; + pswHNWCoefBuf[i] = 0; + } + + *psiUVCode = 0; + } + else + { + + /* Voiced: get best delta-codeable lag trajectory; find pitch and */ + /* harmonic-noise-weighting coefficients for each subframe */ + /*----------------------------------------------------------------*/ + + siTrajIndex = 0; + swBestPG = SW_MIN; + for (siAnchorIndex = 0; siAnchorIndex < N_SUB; siAnchorIndex++) + { + + /* Call pitchLags: for the current subframe, find peaks in the */ + /* C(k)**2/G(k) (k fractional) function which exceed the */ + /* threshold set by the maximum C(k)**2/G(k) (k integer) */ + /* (also get the smoothed pitch and harmonic-noise-weighting */ + /* coefficient). */ + /* */ + /* If there is no C(k) > 0 (k integer), set the smoothed pitch */ + /* to its minimum value and set the harmonic-noise-weighting */ + /* coefficient to zero. */ + /*-------------------------------------------------------------*/ + + if (pswLIntBuf[siAnchorIndex] != 0) + { + + pitchLags(pswLIntBuf[siAnchorIndex], + ppswCSfrm[siAnchorIndex], + ppswGSfrm[siAnchorIndex], + pswCCThresh[siAnchorIndex], + pswLPeaks, + pswCPeaks, + pswGPeaks, + &siNumPeaks, + &pswPitchBuf[siAnchorIndex], + &pswHNWCoefBuf[siAnchorIndex]); + + siPeakIndex = 0; + } + else + { + + /* No C(k) > 0 (k integer): set pitch to min, coef to zero, */ + /* go to next subframe. */ + /*----------------------------------------------------------*/ + + pswPitchBuf[siAnchorIndex] = LMIN_FR; + pswHNWCoefBuf[siAnchorIndex] = 0; + continue; + } + + /* It is possible that by interpolating, the only positive */ + /* C(k) was made negative. Check for this here */ + /*---------------------------------------------------------*/ + + if (siNumPeaks == 0) + { + + pswPitchBuf[siAnchorIndex] = LMIN_FR; + pswHNWCoefBuf[siAnchorIndex] = 0; + continue; + } + + /* Peak(s) found in C**2/G function: find the best delta-codeable */ + /* trajectory through each peak (unless that peak has already */ + /* paritcipated in a trajectory) up to a total of NUM_TRAJ_MAX */ + /* peaks. After each trajectory is found, check to see if that */ + /* trajectory is the best one so far. */ + /*----------------------------------------------------------------*/ + + if (siNumPeaks > NUM_TRAJ_MAX) + siNumTrajToDo = NUM_TRAJ_MAX; + else + siNumTrajToDo = siNumPeaks; + + while (siNumTrajToDo) + { + + /* Check if this peak has already participated in a trajectory. */ + /* If so, skip it, decrement the number of trajectories yet to */ + /* be evaluated, and go on to the next best peak */ + /*--------------------------------------------------------------*/ + + si1 = 0; + for (i = 0; i < siTrajIndex; i++) + { + + if (sub(pswLPeaks[siPeakIndex], + ppswTrajLBuf[i][siAnchorIndex]) == 0) + si1 = 1; + } + + if (si1) + { + + siNumTrajToDo--; + if (siNumTrajToDo) + { + + siPeakIndex++; + continue; + } + else + break; + } + + /* The current peak is not in a previous trajectory: find */ + /* the best trajectory through it. */ + /* */ + /* First, store the lag, C**2, and G for the peak in the */ + /* trajectory storage buffer */ + /*--------------------------------------------------------*/ + + ppswTrajLBuf[siTrajIndex][siAnchorIndex] = pswLPeaks[siPeakIndex]; + ppswTrajGBuf[siTrajIndex][siAnchorIndex] = pswGPeaks[siPeakIndex]; + ppswTrajCCBuf[siTrajIndex][siAnchorIndex] = + mult_r(pswCPeaks[siPeakIndex], pswCPeaks[siPeakIndex]); + + /* Complete the part of the trajectory that extends forward */ + /* from the anchor subframe */ + /*----------------------------------------------------------*/ + + for (siFIndex = siAnchorIndex + 1; siFIndex < N_SUB; siFIndex++) + { + + /* Get array of lags which are delta-codeable */ + /* */ + /* First, get code for largest lag in array */ + /* (limit it) */ + /*--------------------------------------------*/ + + quantLag(ppswTrajLBuf[siTrajIndex][siFIndex - 1], + &si1); + si2 = add(si1, (DELTA_LEVELS / 2 - 1) - (NUM_CLOSED - 1)); + if (sub(si2, (1 << L_BITS) - 1) > 0) + si2 = (1 << L_BITS) - 1; + + /* Get code for smallest lag in array (limit it) */ + /*-----------------------------------------------*/ + + si3 = sub(si1, (DELTA_LEVELS / 2) - (NUM_CLOSED - 1)); + if (si3 < 0) + si3 = 0; + + /* Generate array of lags */ + /*------------------------*/ + + for (i = si3, j = 0; i <= si2; i++, j++) + pswLArray[j] = psrLagTbl[i]; + + siNumDelta = add(sub(si2, si3), 1); + + /* Search array of delta-codeable lags for one which maximizes */ + /* C**2/G */ + /*-------------------------------------------------------------*/ + + bestDelta(pswLArray, ppswCSfrm[siFIndex], ppswGSfrm[siFIndex], + siNumDelta, siFIndex, + ppswTrajLBuf[siTrajIndex], ppswTrajCCBuf[siTrajIndex], + ppswTrajGBuf[siTrajIndex]); + } + + /* Complete the part of the trajectory that extends backward */ + /* from the anchor subframe */ + /*-----------------------------------------------------------*/ + + for (siBIndex = siAnchorIndex - 1; siBIndex >= 0; siBIndex--) + { + + /* Get array of lags which are delta-codeable */ + /* */ + /* First, get code for largest lag in array */ + /* (limit it) */ + /*--------------------------------------------*/ + + quantLag(ppswTrajLBuf[siTrajIndex][siBIndex + 1], + &si1); + si2 = add(si1, (DELTA_LEVELS / 2) - (NUM_CLOSED - 1)); + if (sub(si2, (1 << L_BITS) - 1) > 0) + si2 = (1 << L_BITS) - 1; + + /* Get code for smallest lag in array (limit it) */ + /*-----------------------------------------------*/ + + si3 = sub(si1, (DELTA_LEVELS / 2 - 1) - (NUM_CLOSED - 1)); + if (si3 < 0) + si3 = 0; + + /* Generate array of lags */ + /*------------------------*/ + + for (i = si3, j = 0; i <= si2; i++, j++) + pswLArray[j] = psrLagTbl[i]; + + siNumDelta = add(sub(si2, si3), 1); + + /* Search array of delta-codeable lags for one which maximizes */ + /* C**2/G */ + /*-------------------------------------------------------------*/ + + bestDelta(pswLArray, ppswCSfrm[siBIndex], ppswGSfrm[siBIndex], + siNumDelta, siBIndex, + ppswTrajLBuf[siTrajIndex], ppswTrajCCBuf[siTrajIndex], + ppswTrajGBuf[siTrajIndex]); + } + + /* This trajectory done: check total C**2/G for this trajectory */ + /* against current best trajectory */ + /* */ + /* Get total C**2/G for this trajectory */ + /*--------------------------------------------------------------*/ + + swTotalCCDivG = 0; + for (i = 0; i < N_SUB; i++) + { + + swCC = ppswTrajCCBuf[siTrajIndex][i]; + swG = ppswTrajGBuf[siTrajIndex][i]; + + if (swG <= 0) + { + + /* Negative G (imperfect interpolation): do not include in */ + /* total */ + /*---------------------------------------------------------*/ + + swCCDivG = 0; + } + else if (sub(abs_s(swCC), swG) > 0) + { + + /* C**2/G > 0: limit quotient, add to total */ + /*------------------------------------------*/ + + if (swCC > 0) + swCCDivG = SW_MAX; + else + swCCDivG = SW_MIN; + + swTotalCCDivG = add(swTotalCCDivG, swCCDivG); + } + else + { + + /* accumulate C**2/G */ + /*-------------------*/ + + if (swCC < 0) + { + + swCCDivG = divide_s(negate(swCC), swG); + swTotalCCDivG = sub(swTotalCCDivG, swCCDivG); + } + else + { + + swCCDivG = divide_s(swCC, swG); + swTotalCCDivG = add(swTotalCCDivG, swCCDivG); + } + } + } + + /* Compare this trajectory with current best, update if better */ + /*-------------------------------------------------------------*/ + + if (sub(swTotalCCDivG, swBestPG) > 0) + { + + swBestPG = swTotalCCDivG; + siBestTrajIndex = siTrajIndex; + } + + /* Update trajectory index, peak index, decrement the number */ + /* of trajectories left to do. */ + /*-----------------------------------------------------------*/ + + siTrajIndex++; + siPeakIndex++; + siNumTrajToDo--; + } + } + + if (siTrajIndex == 0) + { + + /* No trajectories searched despite voiced designation: change */ + /* designation to unvoiced. */ + /*-------------------------------------------------------------*/ + + for (i = 0; i < N_SUB; i++) + { + + pswNumLagList[i] = 0; + pswLagList[i] = 0; + pswPitchBuf[i] = 0; + pswHNWCoefBuf[i] = 0; + } + + *psiUVCode = 0; + } + else + { + + /* Best trajectory determined: get voicing level, generate the */ + /* constrained list of lags to search in the adaptive codebook */ + /* for each subframe */ + /* */ + /* First, get voicing level */ + /*-------------------------------------------------------------*/ + + *psiUVCode = 3; + siLowestSoFar = 2; + for (i = 0; i < N_SUB; i++) + { + + /* Check this subframe against highest voicing threshold */ + /*-------------------------------------------------------*/ + + swCC = ppswTrajCCBuf[siBestTrajIndex][i]; + swG = ppswTrajGBuf[siBestTrajIndex][i]; + + swRG = mult_r(swG, pswSfrmEng[i]); + L_Voicing = L_deposit_h(swCC); + L_Voicing = L_mac(L_Voicing, swRG, UV_SCALE2); + + if (L_Voicing < 0) + { + + /* Voicing for this subframe failed to meet 2/3 threshold: */ + /* therefore, voicing level for entire frame can only be as */ + /* high as 2 */ + /*----------------------------------------------------------*/ + + *psiUVCode = siLowestSoFar; + + L_Voicing = L_deposit_h(swCC); + L_Voicing = L_mac(L_Voicing, swRG, UV_SCALE1); + + if (L_Voicing < 0) + { + + /* Voicing for this subframe failed to meet 1/2 threshold: */ + /* therefore, voicing level for entire frame can only be */ + /* as high as 1 */ + /*---------------------------------------------------------*/ + + *psiUVCode = siLowestSoFar = 1; + } + } + } + + /* Generate list of lags to be searched in closed-loop */ + /*-----------------------------------------------------*/ + + siLagsSoFar = 0; + for (i = 0; i < N_SUB; i++) + { + + quantLag(ppswTrajLBuf[siBestTrajIndex][i], &si1); + + si2 = add(si1, NUM_CLOSED / 2); + if (sub(si2, (1 << L_BITS) - 1) > 0) + si2 = (1 << L_BITS) - 1; + + si3 = sub(si1, NUM_CLOSED / 2); + if (si3 < 0) + si3 = 0; + + pswNumLagList[i] = add(sub(si2, si3), 1); + + for (j = siLagsSoFar; j < siLagsSoFar + pswNumLagList[i]; j++) + pswLagList[j] = psrLagTbl[si3++]; + + siLagsSoFar += pswNumLagList[i]; + } + } + } +} /* end of openLoopLagSearch */ + +/*************************************************************************** + * + * FUNCTION NAME: pitchLags + * + * PURPOSE: + * + * Locates peaks in the interpolated C(k)*C(k)/G(k) sequence for a + * subframe which exceed a given threshold. Also determines the + * fundamental pitch, and a harmonic-noise-weighting coefficient. + * + * INPUTS: + * + * swBestIntLag + * + * The integer lag for which CC/G is maximum. + * + * pswIntCs[0:127] + * + * The C(k) sequence for the subframe, with k an integer. + * + * pswIntGs[0:127] + * + * The G(k) sequence for the subframe, with k an integer. + * + * swCCThreshold + * + * The CC/G threshold which peaks must exceed (G is + * understood to be 0.5). + * + * psrLagTbl[0:255] + * + * The lag quantization table. + * + * + * OUTPUTS: + * + * pswLPeaksSorted[0:10(max)] + * + * List of fractional lags where CC/G peaks, highest + * peak first. + * + * pswCPeaksSorted[0:10(max)] + * + * List of C's where CC/G peaks. + * + * pswGPeaksSorted[0:10(max)] + * + * List of G's where CC/G peaks. + * + * psiNumSorted + * + * Number of peaks found. + * + * pswPitch + * + * The fundamental pitch for current subframe. + * + * pswHNWCoef + * + * The harmonic-noise-weighting coefficient for the + * current subframe. + * + * RETURN VALUE: + * + * None + * + * DESCRIPTION: + * + * + * REFERENCE: Sub-clauses 4.1.9, 4.1.8.2 of GSM Recommendation 06.20 + * + * KEYWORDS: pitchLags, pitchlags, PITCH_LAGS + * + *************************************************************************/ + +void pitchLags(int16_t swBestIntLag, + int16_t pswIntCs[], + int16_t pswIntGs[], + int16_t swCCThreshold, + int16_t pswLPeaksSorted[], + int16_t pswCPeaksSorted[], + int16_t pswGPeaksSorted[], + int16_t *psiNumSorted, + int16_t *pswPitch, + int16_t *pswHNWCoef) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t pswLBuf[2 * OS_FCTR - 1], + pswCBuf[2 * OS_FCTR - 1]; + int16_t pswGBuf[2 * OS_FCTR - 1], + pswLPeaks[2 * LMAX / LMIN]; + int16_t pswCPeaks[2 * LMAX / LMIN], + pswGPeaks[2 * LMAX / LMIN]; + short siLPeakIndex, + siCPeakIndex, + siGPeakIndex, + siPeakIndex; + short siSortedIndex, + siLPeaksSortedInit, + swWorkingLag; + int16_t swSubMult, + swFullResPeak, + swCPitch, + swGPitch, + swMult; + int16_t swMultInt, + sw1, + sw2, + si1, + si2; + int32_t L_1; + short siNum, + siUpperBound, + siLowerBound, + siSMFIndex; + short siNumPeaks, + siRepeat, + i, + j; + + static int16_tRom psrSubMultFactor[] = {0x0aab, /* 1.0/12.0 */ + 0x071c, /* 1.0/18.0 */ + 0x0555, /* 1.0/24.0 */ + 0x0444, /* 1.0/30.0 */ + 0x038e}; /* 1.0/36.0 */ + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Get array of valid lags within one integer lag of the best open-loop */ + /* integer lag; get the corresponding interpolated C and G arrays; */ + /* find the best among these; store the info corresponding to this peak */ + /* in the interpolated CC/G sequence */ + /*----------------------------------------------------------------------*/ + + sw1 = shr(extract_l(L_mult(swBestIntLag, OS_FCTR)), 1); + + siNum = CGInterpValid(sw1, pswIntCs, pswIntGs, + pswLBuf, pswCBuf, pswGBuf); + + sw1 = 0; + sw2 = 0x003f; + siPeakIndex = fnBest_CG(pswCBuf, pswGBuf, &sw1, &sw2, siNum); + if (siPeakIndex == -1) + { + + /* It is possible, although rare, that the interpolated sequence */ + /* will not have a peak where the original sequence did. */ + /* Indicate this on return */ + /*---------------------------------------------------------------*/ + + *psiNumSorted = 0; + return; + } + + siLPeakIndex = 0; + siCPeakIndex = 0; + siGPeakIndex = 0; + siSortedIndex = 0; + pswCPeaks[siCPeakIndex] = pswCBuf[siPeakIndex]; + siCPeakIndex = add(siCPeakIndex, 1); + pswLPeaks[siLPeakIndex] = pswLBuf[siPeakIndex]; + siLPeakIndex = add(siLPeakIndex, 1); + pswGPeaks[siGPeakIndex] = pswGBuf[siPeakIndex]; + siGPeakIndex = add(siGPeakIndex, 1); + + /* Find all peaks at submultiples of the first peak */ + /*--------------------------------------------------*/ + + siSMFIndex = 0; + swSubMult = mult_r(pswLPeaks[0], psrSubMultFactor[siSMFIndex++]); + + while (sub(swSubMult, LMIN) >= 0 && siSMFIndex <= 5) + { + + /* Check if there is peak in the integer CC/G sequence within */ + /* PEAK_VICINITY of the submultiple */ + /*------------------------------------------------------------*/ + + swFullResPeak = findPeak(swSubMult, pswIntCs, pswIntGs); + + if (swFullResPeak) + { + + /* Peak found at submultiple: interpolate to get C's and G's */ + /* corresponding to valid lags within one of the new found */ + /* peak; get best C**2/G from these; if it meets threshold, */ + /* store the info corresponding to this peak */ + /*-----------------------------------------------------------*/ + + siNum = CGInterpValid(swFullResPeak, pswIntCs, pswIntGs, + pswLBuf, pswCBuf, pswGBuf); + + sw1 = swCCThreshold; + sw2 = 0x4000; + siPeakIndex = fnBest_CG(pswCBuf, pswGBuf, &sw1, &sw2, siNum); + if (siPeakIndex != -1) + { + + pswCPeaks[siCPeakIndex] = pswCBuf[siPeakIndex]; + siCPeakIndex = add(siCPeakIndex, 1); + pswLPeaks[siLPeakIndex] = pswLBuf[siPeakIndex]; + siLPeakIndex = add(siLPeakIndex, 1); + pswGPeaks[siGPeakIndex] = pswGBuf[siPeakIndex]; + siGPeakIndex = add(siGPeakIndex, 1); + + } + } + + + if (siSMFIndex < 5) + { + + /* Get next submultiple */ + /*----------------------*/ + swSubMult = mult_r(pswLPeaks[0], psrSubMultFactor[siSMFIndex]); + + } + + siSMFIndex++; + } + + /* Get pitch from fundamental peak: first, build array of fractional */ + /* lags around which to search for peak. Note that these lags are */ + /* NOT restricted to those in the lag table, but may take any value */ + /* in the range LMIN_FR to LMAX_FR */ + /*-------------------------------------------------------------------*/ + + siUpperBound = add(pswLPeaks[siLPeakIndex - 1], OS_FCTR); + siUpperBound = sub(siUpperBound, 1); + if (sub(siUpperBound, LMAX_FR) > 0) + siUpperBound = LMAX_FR; + + siLowerBound = sub(pswLPeaks[siLPeakIndex - 1], OS_FCTR); + siLowerBound = add(siLowerBound, 1); + if (sub(siLowerBound, LMIN_FR) < 0) + siLowerBound = LMIN_FR; + for (i = siLowerBound, j = 0; i <= siUpperBound; i++, j++) + pswLBuf[j] = i; + + /* Second, find peak in the interpolated CC/G sequence. */ + /* The corresponding lag is the fundamental pitch. The */ + /* interpolated C(pitch) and G(pitch) values are stored */ + /* for later use in calculating the Harmonic-Noise- */ + /* Weighting coefficient */ + /*------------------------------------------------------*/ + + siNum = sub(siUpperBound, siLowerBound); + siNum = add(siNum, 1); + CGInterp(pswLBuf, siNum, pswIntCs, pswIntGs, LSMIN, + pswCBuf, pswGBuf); + sw1 = 0; + sw2 = 0x003f; + siPeakIndex = fnBest_CG(pswCBuf, pswGBuf, &sw1, &sw2, siNum); + if (siPeakIndex == -1) + { + swCPitch = 0; + *pswPitch = LMIN_FR; + swGPitch = 0x003f; + } + else + { + swCPitch = pswCBuf[siPeakIndex]; + *pswPitch = pswLBuf[siPeakIndex]; + swGPitch = pswGBuf[siPeakIndex]; + } + + /* Find all peaks which are multiples of fundamental pitch */ + /*---------------------------------------------------------*/ + + swMult = add(*pswPitch, *pswPitch); + swMultInt = mult_r(swMult, INV_OS_FCTR); + + while (sub(swMultInt, LMAX) <= 0) + { + + /* Check if there is peak in the integer CC/G sequence within */ + /* PEAK_VICINITY of the multiple */ + /*------------------------------------------------------------*/ + + swFullResPeak = findPeak(swMultInt, pswIntCs, pswIntGs); + + if (swFullResPeak) + { + + /* Peak found at multiple: interpolate to get C's and G's */ + /* corresponding to valid lags within one of the new found */ + /* peak; get best C**2/G from these; if it meets threshold, */ + /* store the info corresponding to this peak */ + /*-----------------------------------------------------------*/ + + siNum = CGInterpValid(swFullResPeak, pswIntCs, pswIntGs, + pswLBuf, pswCBuf, pswGBuf); + + sw1 = swCCThreshold; + sw2 = 0x4000; + siPeakIndex = fnBest_CG(pswCBuf, pswGBuf, &sw1, &sw2, siNum); + if (siPeakIndex != -1) + { + + pswCPeaks[siCPeakIndex] = pswCBuf[siPeakIndex]; + siCPeakIndex = add(siCPeakIndex, 1); + pswLPeaks[siLPeakIndex] = pswLBuf[siPeakIndex]; + siLPeakIndex = add(siLPeakIndex, 1); + pswGPeaks[siGPeakIndex] = pswGBuf[siPeakIndex]; + siGPeakIndex = add(siGPeakIndex, 1); + + } + } + + /* Get next multiple */ + /*-------------------*/ + + swMult = add(*pswPitch, swMult); + swMultInt = mult_r(swMult, INV_OS_FCTR); + } + + /* Get Harmonic-Noise-Weighting coefficient = 0.4 * C(pitch) / G(pitch) */ + /* Note: a factor of 0.5 is applied the the HNW coeffcient */ + /*----------------------------------------------------------------------*/ + + si2 = norm_s(swCPitch); + sw1 = shl(swCPitch, si2); + L_1 = L_mult(sw1, PW_FRAC); + + si1 = norm_s(swGPitch); + sw1 = shl(swGPitch, si1); + + sw2 = round(L_shr(L_1, 1)); + sw2 = divide_s(sw2, sw1); + + if (sub(si1, si2) > 0) + sw2 = shl(sw2, sub(si1, si2)); + + if (sub(si1, si2) < 0) + sw2 = shift_r(sw2, sub(si1, si2)); + + *pswHNWCoef = sw2; + + /* Sort peaks into output arrays, largest first */ + /*----------------------------------------------*/ + + siLPeaksSortedInit = siSortedIndex; + *psiNumSorted = 0; + siNumPeaks = siLPeakIndex; + for (i = 0; i < siNumPeaks; i++) + { + + sw1 = 0; + sw2 = 0x003f; + siPeakIndex = fnBest_CG(pswCPeaks, pswGPeaks, &sw1, &sw2, siNumPeaks); + + siRepeat = 0; + swWorkingLag = pswLPeaks[siPeakIndex]; + for (j = 0; j < *psiNumSorted; j++) + { + + if (sub(swWorkingLag, pswLPeaksSorted[j + siLPeaksSortedInit]) == 0) + siRepeat = 1; + } + + if (!siRepeat) + { + + pswLPeaksSorted[siSortedIndex] = swWorkingLag; + pswCPeaksSorted[siSortedIndex] = pswCPeaks[siPeakIndex]; + pswGPeaksSorted[siSortedIndex] = pswGPeaks[siPeakIndex]; + siSortedIndex = add(siSortedIndex, 1); + *psiNumSorted = add(*psiNumSorted, 1); + } + + pswCPeaks[siPeakIndex] = 0x0; + } +} /* end of pitchLags */ + + + +/*************************************************************************** + * + * FUNCTION NAME: quantLag + * + * PURPOSE: + * + * Quantizes a given fractional lag according to the provided table + * of allowable fractional lags. + * + * INPUTS: + * + * swRawLag + * + * Raw lag value: a fractional lag value*OS_FCTR. + * + * psrLagTbl[0:255] + * + * Fractional lag table. + * + * OUTPUTS: + * + * pswCode + * + * Index in lag table of the quantized lag-- that is, + * the coded value of the lag. + * + * RETURN VALUE: + * + * Quantized lag value. + * + * + * REFERENCE: Sub-clause 4.1.8.3 of GSM Recommendation 06.20 + * + * KEYWORDS: quantization, LTP, adaptive codebook + * + *************************************************************************/ + +int16_t quantLag(int16_t swRawLag, + int16_t *pswCode) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int16_t siOffset, + swIndex1, + swIndex2; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + swIndex1 = 0; + siOffset = shr(LAG_TABLE_LEN, 1); + swIndex2 = siOffset; + siOffset = shr(siOffset, 1); + + while (sub(swIndex2, swIndex1) != 0) + { + if (sub(swRawLag, psrLagTbl[swIndex2]) >= 0) + swIndex1 = swIndex2; + swIndex2 = add(swIndex1, siOffset); + siOffset = shr(siOffset, 1); + } + *pswCode = swIndex2; + + return (psrLagTbl[swIndex2]); + +} /* end of quantLag */ + +/*************************************************************************** + * + * FUNCTION NAME: r0Quant + * + * PURPOSE: + * + * Quantize the unquantized R(0). Returns r0 codeword (index). + * + * INPUTS: + * + * L_UnqntzdR0 + * The average frame energy R(0) + * + * OUTPUTS: none + * + * RETURN VALUE: + * + * A 16 bit number representing the codeword whose + * associated R(0) is closest to the input frame energy. + * + * DESCRIPTION: + * + * Returns r0 codeword (index) not the actual Rq(0). + * + * Level compare input with boundary value (the boundary + * above ,louder) of candidate r0Index i.e. + * lowerBnd[i] <= inputR(0) < upperBnd[i+1] + * + * The compare in the routine is: + * inputR(0) < upperBnd[i+1] if false return i as codeword + * + * REFERENCE: Sub-clause 4.1.3 of GSM Recommendation 06.20 + * + * + *************************************************************************/ + +int16_t r0Quant(int32_t L_UnqntzdR0) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t swR0Index, + swUnqntzdR0; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + swUnqntzdR0 = round(L_UnqntzdR0); + + for (swR0Index = 0; swR0Index < (1 << R0BITS) - 1; swR0Index++) + { + if (sub(swUnqntzdR0, psrR0DecTbl[2 * swR0Index + 1]) < 0) + { + return (swR0Index); + } + } + return ((1 << R0BITS) - 1); /* return the maximum */ +} + +/*************************************************************************** + * + * FUNCTION NAME: setupPreQ + * + * PURPOSE: + * The purpose of this function is to setup the internal pointers so that + * getNextVec knows where to start. + * + * INPUTS: iSeg, iVector + * + * OUTPUTS: None + * + * RETURN VALUE: none + * + * DESCRIPTION: + * + * REFERENCE: Sub-clause 4.1.4.1 of GSM Recommendation 06.20 + * + * KEYWORDS: vector quantizer preQ + * + *************************************************************************/ + +void setupPreQ(int iSeg, int iVector) +{ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + iLow = psvqIndex[iSeg - 1].l; + iThree = ((psvqIndex[iSeg - 1].h - iLow) == 2); + + switch (iSeg) + { + case 1: + { + psrTable = psrPreQ1; + iWordPtr = (iVector * 3) >> 1; + if (odd(iVector)) + iWordHalfPtr = LOW; + else + iWordHalfPtr = HIGH; + break; + } + + case 2: + { + psrTable = psrPreQ2; + iWordPtr = (iVector * 3) >> 1; + if (odd(iVector)) + iWordHalfPtr = LOW; + else + iWordHalfPtr = HIGH; + break; + } + + case 3: + { + psrTable = psrPreQ3; + iWordPtr = iVector * 2; + iWordHalfPtr = HIGH; + break; + } + } +} + +/*************************************************************************** + * + * FUNCTION NAME: setupQuant + * + * PURPOSE: + * The purpose of this function is to setup the internal pointers so that + * getNextVec knows where to start. + * + * + * INPUTS: iSeg, iVector + * + * OUTPUTS: None + * + * RETURN VALUE: none + * + * DESCRIPTION: + * + * REFERENCE: Sub-clause 4.1.4.1 of GSM Recommendation 06.20 + * + * KEYWORDS: vector quantizer Quant + * + *************************************************************************/ + +void setupQuant(int iSeg, int iVector) +{ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + iLow = psvqIndex[iSeg - 1].l; + iThree = ((psvqIndex[iSeg - 1].h - iLow) == 2); + + switch (iSeg) + { + case 1: + { + psrTable = psrQuant1; + iWordPtr = (iVector * 3) >> 1; + if (odd(iVector)) + iWordHalfPtr = LOW; + else + iWordHalfPtr = HIGH; + break; + } + + case 2: + { + psrTable = psrQuant2; + iWordPtr = (iVector * 3) >> 1; + if (odd(iVector)) + iWordHalfPtr = LOW; + else + iWordHalfPtr = HIGH; + break; + } + + case 3: + { + psrTable = psrQuant3; + iWordPtr = iVector * 2; + iWordHalfPtr = HIGH; + break; + } + } +} + +/*************************************************************************** + * + * FUNCTION NAME: weightSpeechFrame + * + * PURPOSE: + * + * The purpose of this function is to perform the spectral + * weighting filter (W(z)) of the input speech frame. + * + * INPUTS: + * + * pswSpeechFrm[0:F_LEN] + * + * high pass filtered input speech frame + * + * pswWNumSpace[0:NP*N_SUB] + * + * W(z) numerator coefficients + * + * pswWDenomSpace[0:NP*N_SUB] + * + * W(z) denominator coefficients + * + * pswWSpeechBuffBase[0:F_LEN+LMAX+CG_INT_MACS/2] + * + * previous W(z) filtered speech + * + * OUTPUTS: + * + * pswWSpeechBuffBase[0:F_LEN+LMAX+CG_INT_MACS/2] + * + * W(z) filtered speech frame + * + * RETURN VALUE: + * + * none + * + * DESCRIPTION: + * + * REFERENCE: Sub-clause 4.1.7 of GSM Recommendation 06.20 + * + * KEYWORDS: + * + *************************************************************************/ + +void weightSpeechFrame(int16_t pswSpeechFrm[], + int16_t pswWNumSpace[], + int16_t pswWDenomSpace[], + int16_t pswWSpeechBuffBase[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t pswScratch0[W_F_BUFF_LEN], + *pswWSpeechFrm; + short int siI; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Delay the weighted speech buffer by one frame */ + /* --------------------------------------------- */ + + for (siI = 0; siI < LSMAX; siI++) + { + pswWSpeechBuffBase[siI] = pswWSpeechBuffBase[siI + F_LEN]; + } + + /* pass speech frame through W(z) */ + /* ------------------------------ */ + + pswWSpeechFrm = pswWSpeechBuffBase + LSMAX; + + for (siI = 0; siI < N_SUB; siI++) + { + lpcFir(&pswSpeechFrm[siI * S_LEN], &pswWNumSpace[siI * NP], + pswWStateNum, &pswScratch0[siI * S_LEN]); + } + + for (siI = 0; siI < N_SUB; siI++) + { + lpcIir(&pswScratch0[siI * S_LEN], &pswWDenomSpace[siI * NP], + pswWStateDenom, &pswWSpeechFrm[siI * S_LEN]); + } +} diff --git a/src/libs/gsmhr/gsmhr_sp_frm.h b/src/libs/gsmhr/gsmhr_sp_frm.h new file mode 100644 index 00000000..2d353203 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_sp_frm.h @@ -0,0 +1,201 @@ +#ifndef __SP_FRM +#define __SP_FRM + +#include "gsmhr_typedefs.h" +#include "gsmhr_sp_rom.h" + + +struct QuantList +{ + /* structure which points to the beginning of a block of candidate vq + * vectors. It also stores the residual error for each vector. */ + int iNum; /* total number in list */ + int iRCIndex; /* an index to the first vector of the + * block */ + int16_t pswPredErr[PREQ1_NUM_OF_ROWS]; /* PREQ1 is the biggest block */ +}; + +/*_________________________________________________________________________ + | | + | Function Prototypes | + |_________________________________________________________________________| +*/ + +void iir_d(int16_t pswCoeff[], int16_t pswIn[], + int16_t pswXstate[], + int16_t pswYstate[], + int npts, int shifts, + int16_t swPreFirDownSh, + int16_t swFinalUpShift); + + + void filt4_2nd(int16_t pswCoeff[], + int16_t pswIn[], + int16_t pswXstate[], + int16_t pswYstate[], + int npts, + int shifts); + + void initPBarVBarL(int32_t pL_PBarFull[], + int16_t pswPBar[], + int16_t pswVBar[]); + + void initPBarFullVBarFullL(int32_t pL_CorrelSeq[], + int32_t pL_PBarFull[], + int32_t pL_VBarFull[]); + + int16_t aflatRecursion(int16_t pswQntRc[], + int16_t pswPBar[], + int16_t pswVBar[], + int16_t *ppswPAddrs[], + int16_t *ppswVAddrs[], + int16_t swSegmentOrder); + + void aflatNewBarRecursionL(int16_t pswQntRc[], + int iSegment, + int32_t pL_PBar[], + int32_t pL_VBar[], + int16_t pswPBar[], + int16_t pswVBar[]); + + + void setupPreQ(int iSeg, int iVector); + + void setupQuant(int iSeg, int iVector); + + void getNextVec(int16_t pswRc[]); + + void aflat(int16_t pswSpeechToLPC[], + int piR0Index[], + int16_t pswFinalRc[], + int piVQCodewds[], + int16_t swPtch, + int16_t *pswVadFlag, + int16_t *pswSP); + + + int16_t fnExp2(int32_t L_Input); + + int16_t fnLog2(int32_t L_Input); + + void weightSpeechFrame(int16_t pswSpeechFrm[], + int16_t pswWNumSpace[], + int16_t pswWDenomSpace[], + int16_t pswWSpeechBuffBase[]); + + void getSfrmLpcTx(int16_t swPrevR0, int16_t swNewR0, + int16_t pswPrevFrmKs[], + int16_t pswPrevFrmAs[], + int16_t pswPrevFrmSNWCoef[], + int16_t pswNewFrmKs[], + int16_t pswNewFrmAs[], + int16_t pswNewFrmSNWCoef[], + int16_t pswHPFSpeech[], + short *pswSoftInterp, + struct NormSw *psnsSqrtRs, + int16_t ppswSynthAs[][NP], + int16_t ppswSNWCoefAs[][NP]); + + short int fnBest_CG(int16_t pswCframe[], + int16_t pswGframe[], + int16_t *pswCmaxSqr, + int16_t *pswGmax, + short int siNumPairs); + + short compResidEnergy(int16_t pswSpeech[], + int16_t ppswInterpCoef[][NP], + int16_t pswPreviousCoef[], + int16_t pswCurrentCoef[], + struct NormSw psnsSqrtRs[]); + + int16_t r0Quant(int32_t L_UnqntzdR0); + + int16_t cov32(int16_t pswIn[], + int32_t pppL_B[NP][NP][2], + int32_t pppL_F[NP][NP][2], + int32_t pppL_C[NP][NP][2], + int32_t *pL_R0, + int32_t pL_VadAcf[], + int16_t *pswVadScalAuto); + + int32_t flat(int16_t pswSpeechIn[], + int16_t pswRc[], + int *piR0Inx, + int32_t pL_VadAcf[], + int16_t *pswVadScalAuto); + + + + void openLoopLagSearch(int16_t pswWSpeech[], + int16_t swPrevR0Index, + int16_t swCurrR0Index, + int16_t *psiUVCode, + int16_t pswLagList[], + int16_t pswNumLagList[], + int16_t pswPitchBuf[], + int16_t pswHNWCoefBuf[], + struct NormSw psnsWSfrmEng[], + int16_t pswVadLags[], + int16_t swSP); + + int16_t getCCThreshold(int16_t swRp0, + int16_t swCC, + int16_t swG); + + void pitchLags(int16_t swBestIntLag, + int16_t pswIntCs[], + int16_t pswIntGs[], + int16_t swCCThreshold, + int16_t pswLPeaksSorted[], + int16_t pswCPeaksSorted[], + int16_t pswGPeaksSorted[], + int16_t *psiNumSorted, + int16_t *pswPitch, + int16_t *pswHNWCoef); + + short CGInterpValid(int16_t swFullResLag, + int16_t pswCIn[], + int16_t pswGIn[], + int16_t pswLOut[], + int16_t pswCOut[], + int16_t pswGOut[]); + + void CGInterp(int16_t pswLIn[], + short siNum, + int16_t pswCIn[], + int16_t pswGIn[], + short siLoIntLag, + int16_t pswCOut[], + int16_t pswGOut[]); + + int16_t quantLag(int16_t swRawLag, + int16_t *psiCode); + + void findBestInQuantList(struct QuantList psqlInList, + int iNumVectOut, + struct QuantList psqlBestOutList[]); + + int16_t findPeak(int16_t swSingleResLag, + int16_t pswCIn[], + int16_t pswGIn[]); + + void bestDelta(int16_t pswLagList[], + int16_t pswCSfrm[], + int16_t pswGSfrm[], + short int siNumLags, + short int siSfrmIndex, + int16_t pswLTraj[], + int16_t pswCCTraj[], + int16_t pswGTraj[]); + + int16_t + maxCCOverGWithSign(int16_t pswCIn[], + int16_t pswGIn[], + int16_t *pswCCMax, + int16_t *pswGMax, + int16_t swNum); + + void getNWCoefs(int16_t pswACoefs[], + int16_t pswHCoefs[]); + +#endif diff --git a/src/libs/gsmhr/gsmhr_sp_rom.c b/src/libs/gsmhr/gsmhr_sp_rom.c new file mode 100644 index 00000000..7b566178 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_sp_rom.c @@ -0,0 +1,6592 @@ +/************************************************************************** + * + * File Name: sp_rom.c + * + * Purpose: Contains all globally available constant (ROM) data + * used by the speech codec: quantization tables, codebooks, etc. + * Some ROM is defined within the file where it is used. In those + * cases, the scope of the ROM variables is limited to the file + * + **************************************************************************/ +/*_________________________________________________________________________ + | | + | Include Files | + |_________________________________________________________________________| +*/ +//#include "gsmhr_mathhalf.h" +#include "gsmhr_sp_rom.h" + +/*_________________________________________________________________________ + | | + | Global Data | + | (scope is global to the entire program) | + |_________________________________________________________________________| +*/ + +/* gsp0 vector quantizer */ +/*-----------------------*/ + +/* THE GSP0 ERROR TERM VECTORS FOR 5 BITS FOLLOW + THE GSP0 TABLE WAS READ FROM THE FILES gsp0_1_*.qnt_97CQ_4 + ET VALUES WRITTEN WERE SCALED BY 4 */ + +int16_tRom pppsrGsp0 + [GSP0_NUM_OF_TABLES][GSP0_NUM][GSP0_VECTOR_SIZE] = +{ + { + + {33, 34, 0, 0, 0}, /* Table 1, Centroid # 1 */ + {58, 63, 0, 0, 0}, /* Table 1, Centroid # 2 */ + {85, 89, 0, 0, 0}, /* Table 1, Centroid # 3 */ + {139, 149, -1, -1, -1}, /* Table 1, Centroid # 4 */ + {233, 235, -3, -2, -2}, /* Table 1, Centroid # 5 */ + {313, 329, -6, -3, -3}, /* Table 1, Centroid # 6 */ + {440, 456, -12, -6, -6}, /* Table 1, Centroid # 7 */ + {703, 530, -23, -15, -9}, /* Table 1, Centroid # 8 */ + {892, 767, -42, -24, -18}, /* Table 1, Centroid # 9 */ + {963, 1329, -78, -28, -54}, /* Table 1, Centroid # 10 */ + {1447, 1165, -103, -64, -41}, /* Table 1, Centroid # 11 */ + {1894, 1362, -157, -109, -57}, /* Table 1, Centroid # 12 */ + {1639, 2194, -219, -82, -147}, /* Table 1, Centroid # 13 */ + {2120, 3211, -415, -137, -315}, /* Table 1, Centroid # 14 */ + {2994, 2147, -392, -274, -141}, /* Table 1, Centroid # 15 */ + {4132, 2566, -647, -521, -201}, /* Table 1, Centroid # 16 */ + {3040, 4009, -744, -282, -490}, /* Table 1, Centroid # 17 */ + {4012, 5316, -1302, -491, -862}, /* Table 1, Centroid # 18 */ + {5356, 3752, -1226, -875, -430}, /* Table 1, Centroid # 19 */ + {7068, 4287, -1850, -1525, -561}, /* Table 1, Centroid # 20 */ + {4927, 7072, -2127, -741, -1526}, /* Table 1, Centroid # 21 */ + {6996, 7304, -3118, -1493, -1628}, /* Table 1, Centroid # 22 */ + {9047, 6154, -3398, -2498, -1156}, /* Table 1, Centroid # 23 */ + {11747, 6009, -4309, -4211, -1102},/* Table 1, Centroid # 24 */ + {5144, 10368, -3255, -808, -3280}, /* Table 1, Centroid # 25 */ + {7677, 12151, -5693, -1798, -4506},/* Table 1, Centroid # 26 */ + {8796, 9286, -4986, -2361, -2632}, /* Table 1, Centroid # 27 */ + {11323, 9802, -6774, -3912, -2932},/* Table 1, Centroid # 28 */ + {10555, 15059, -9701, -3400, -6920}, /* Table 1, Centroid # 29 */ + {17566, 15641, -16769, -9417, -7465}, /* Table 1, Centroid # 30 */ + {13934, 9966, -8476, -5925, -3031},/* Table 1, Centroid # 31 */ + {17646, 8051, -8672, -9503, -1978},/* Table 1, Centroid # 32 */ + }, + { + {65, 62, 0, 0, 0}, /* Table 2, Centroid # 1 */ + {199, 174, -2, -1, -1}, /* Table 2, Centroid # 2 */ + {526, 613, -20, -8, -11}, /* Table 2, Centroid # 3 */ + {705, 1191, -51, -15, -43}, /* Table 2, Centroid # 4 */ + {1695, 1067, -110, -88, -35}, /* Table 2, Centroid # 5 */ + {2176, 1897, -252, -144, -110}, /* Table 2, Centroid # 6 */ + {848, 3038, -157, -22, -282}, /* Table 2, Centroid # 7 */ + {2105, 3693, -474, -135, -416}, /* Table 2, Centroid # 8 */ + {3483, 1605, -341, -370, -79}, /* Table 2, Centroid # 9 */ + {3552, 3236, -702, -385, -320}, /* Table 2, Centroid # 10 */ + {4869, 2028, -603, -723, -126}, /* Table 2, Centroid # 11 */ + {6296, 2220, -853, -1210, -150}, /* Table 2, Centroid # 12 */ + {1425, 5682, -494, -62, -985}, /* Table 2, Centroid # 13 */ + {3538, 5556, -1200, -382, -942}, /* Table 2, Centroid # 14 */ + {1468, 8528, -764, -66, -2219}, /* Table 2, Centroid # 15 */ + {4805, 8004, -2347, -705, -1955}, /* Table 2, Centroid # 16 */ + {5189, 4143, -1312, -822, -524}, /* Table 2, Centroid # 17 */ + {6409, 5573, -2180, -1254, -948}, /* Table 2, Centroid # 18 */ + {7493, 2955, -1351, -1713, -266}, /* Table 2, Centroid # 19 */ + {8902, 2344, -1274, -2418, -168}, /* Table 2, Centroid # 20 */ + {8212, 5266, -2639, -2058, -846}, /* Table 2, Centroid # 21 */ + {10190, 5396, -3356, -3169, -889}, /* Table 2, Centroid # 22 */ + {10556, 3007, -1938, -3401, -276}, /* Table 2, Centroid # 23 */ + {12517, 2934, -2242, -4781, -263}, /* Table 2, Centroid # 24 */ + {5383, 11357, -3731, -884, -3936}, /* Table 2, Centroid # 25 */ + {9432, 9038, -5203, -2715, -2493}, /* Table 2, Centroid # 26 */ + {7993, 17273, -8426, -1950, -9105},/* Table 2, Centroid # 27 */ + {16236, 12894, -12778, -8045, -5073}, /* Table 2, Centroid # 28 */ + {12832, 6896, -5401, -5025, -1451},/* Table 2, Centroid # 29 */ + {14842, 4024, -3645, -6723, -494}, /* Table 2, Centroid # 30 */ + {18013, 7332, -8062, -9902, -1641},/* Table 2, Centroid # 31 */ + {19019, 3737, -4338, -11039, -426},/* Table 2, Centroid # 32 */ + }, + { + {1004, 731, -45, -31, -16}, /* Table 3, Centroid # 1 */ + {1412, 1843, -159, -61, -104}, /* Table 3, Centroid # 2 */ + {2700, 1489, -245, -222, -68}, /* Table 3, Centroid # 3 */ + {2785, 2657, -452, -237, -215}, /* Table 3, Centroid # 4 */ + {4054, 1682, -416, -502, -86}, /* Table 3, Centroid # 5 */ + {4499, 2664, -732, -618, -217}, /* Table 3, Centroid # 6 */ + {5155, 1429, -450, -811, -62}, /* Table 3, Centroid # 7 */ + {6006, 1561, -572, -1101, -74}, /* Table 3, Centroid # 8 */ + {3421, 4218, -881, -357, -543}, /* Table 3, Centroid # 9 */ + {4313, 5518, -1452, -568, -929}, /* Table 3, Centroid # 10 */ + {5540, 3384, -1144, -937, -350}, /* Table 3, Centroid # 11 */ + {6832, 3531, -1472, -1424, -381}, /* Table 3, Centroid # 12 */ + {6382, 2333, -909, -1243, -166}, /* Table 3, Centroid # 13 */ + {7417, 1574, -713, -1679, -76}, /* Table 3, Centroid # 14 */ + {8037, 2688, -1319, -1971, -221}, /* Table 3, Centroid # 15 */ + {9014, 1637, -900, -2479, -82}, /* Table 3, Centroid # 16 */ + {6141, 6173, -2314, -1151, -1163}, /* Table 3, Centroid # 17 */ + {7883, 4573, -2201, -1896, -638}, /* Table 3, Centroid # 18 */ + {8608, 7132, -3747, -2261, -1552}, /* Table 3, Centroid # 19 */ + {10098, 4698, -2896, -3112, -674}, /* Table 3, Centroid # 20 */ + {9036, 3633, -2004, -2492, -403}, /* Table 3, Centroid # 21 */ + {9953, 2317, -1408, -3023, -164}, /* Table 3, Centroid # 22 */ + {11108, 3228, -2188, -3766, -318}, /* Table 3, Centroid # 23 */ + {11570, 1843, -1302, -4085, -104}, /* Table 3, Centroid # 24 */ + {11706, 6610, -4723, -4182, -1333},/* Table 3, Centroid # 25 */ + {13128, 4692, -3760, -5260, -672}, /* Table 3, Centroid # 26 */ + {12725, 2951, -2292, -4942, -266}, /* Table 3, Centroid # 27 */ + {14028, 2325, -1990, -6005, -165}, /* Table 3, Centroid # 28 */ + {16126, 7702, -7580, -7936, -1810},/* Table 3, Centroid # 29 */ + {15583, 4486, -4267, -7411, -614}, /* Table 3, Centroid # 30 */ + {16137, 2609, -2569, -7947, -208}, /* Table 3, Centroid # 31 */ + {19264, 3907, -4593, -11325, -466},/* Table 3, Centroid # 32 */ + }, + { + {1900, 1716, -199, -110, -90}, /* Table 4, Centroid # 1 */ + {2946, 979, -176, -265, -29}, /* Table 4, Centroid # 2 */ + {3683, 842, -189, -414, -22}, /* Table 4, Centroid # 3 */ + {4395, 1025, -275, -589, -32}, /* Table 4, Centroid # 4 */ + {3540, 2364, -511, -382, -171}, /* Table 4, Centroid # 5 */ + {5001, 1944, -594, -763, -115}, /* Table 4, Centroid # 6 */ + {5189, 852, -270, -822, -22}, /* Table 4, Centroid # 7 */ + {5862, 1050, -376, -1049, -34}, /* Table 4, Centroid # 8 */ + {5221, 2984, -951, -832, -272}, /* Table 4, Centroid # 9 */ + {6189, 3184, -1203, -1169, -309}, /* Table 4, Centroid # 10 */ + {6408, 1263, -494, -1253, -49}, /* Table 4, Centroid # 11 */ + {7032, 1044, -448, -1509, -33}, /* Table 4, Centroid # 12 */ + {6965, 2270, -965, -1481, -157}, /* Table 4, Centroid # 13 */ + {7875, 2276, -1094, -1893, -158}, /* Table 4, Centroid # 14 */ + {7691, 1181, -554, -1805, -43}, /* Table 4, Centroid # 15 */ + {8365, 944, -482, -2135, -27}, /* Table 4, Centroid # 16 */ + {7657, 4252, -1987, -1789, -552}, /* Table 4, Centroid # 17 */ + {8878, 2876, -1559, -2405, -253}, /* Table 4, Centroid # 18 */ + {8733, 1813, -966, -2328, -100}, /* Table 4, Centroid # 19 */ + {9279, 1167, -661, -2628, -42}, /* Table 4, Centroid # 20 */ + {9894, 3465, -2092, -2988, -366}, /* Table 4, Centroid # 21 */ + {10615, 2340, -1516, -3439, -167}, /* Table 4, Centroid # 22 */ + {10057, 1444, -886, -3087, -64}, /* Table 4, Centroid # 23 */ + {10975, 1209, -810, -3676, -45}, /* Table 4, Centroid # 24 */ + {11358, 4510, -3127, -3937, -621}, /* Table 4, Centroid # 25 */ + {12248, 2748, -2054, -4578, -230}, /* Table 4, Centroid # 26 */ + {11824, 1559, -1125, -4267, -74}, /* Table 4, Centroid # 27 */ + {12838, 1441, -1129, -5030, -63}, /* Table 4, Centroid # 28 */ + {13808, 3978, -3353, -5819, -483}, /* Table 4, Centroid # 29 */ + {14250, 1928, -1677, -6197, -113}, /* Table 4, Centroid # 30 */ + {16642, 3962, -4025, -8452, -479}, /* Table 4, Centroid # 31 */ + {16641, 1762, -1790, -8451, -95}, /* Table 4, Centroid # 32 */ + } +}; + + +/* unvoiced code vectors */ +/*-----------------------*/ + +int16_tRom pppsrUvCodeVec + [UVCODEVEC_NUM_OF_CODE_BOOKS][UVCODEVEC_NUM_OF_CODE_BITS][S_LEN] = +{ + { + { + 12, 11, -49, -53, 9, /* File# 1, Vec# 1, 1- 5 */ + -45, -19, -59, -88, 43, /* File# 1, Vec# 1, 6-10 */ + 2, -15, 17, -18, 30, /* File# 1, Vec# 1, 11-15 */ + 71, 19, 22, 30, 1, /* File# 1, Vec# 1, 16-20 */ + 38, 1, -17, -22, -34, /* File# 1, Vec# 1, 21-25 */ + 17, -21, -37, -45, -19, /* File# 1, Vec# 1, 26-30 */ + 23, 5, 40, 40, 14, /* File# 1, Vec# 1, 31-35 */ + 25, 21, 2, -12, 24 /* File# 1, Vec# 1, 36-40 */ + }, + { + 4, -31, 50, -3, -36, /* File# 1, Vec# 2, 1- 5 */ + 22, 28, 3, -18, -5, /* File# 1, Vec# 2, 6-10 */ + 0, 7, 77, 7, -54, /* File# 1, Vec# 2, 11-15 */ + 42, -29, -48, -11, -3, /* File# 1, Vec# 2, 16-20 */ + -18, -34, -4, -47, -61, /* File# 1, Vec# 2, 21-25 */ + 1, -26, -4, 13, -46, /* File# 1, Vec# 2, 26-30 */ + 7, -21, -24, 36, 22, /* File# 1, Vec# 2, 31-35 */ + 59, 38, 34, 62, 12 /* File# 1, Vec# 2, 36-40 */ + }, + { + -5, -17, -4, 7, 21, /* File# 1, Vec# 3, 1- 5 */ + 3, -60, -29, 8, 25, /* File# 1, Vec# 3, 6-10 */ + 58, 22, 23, 69, -25, /* File# 1, Vec# 3, 11-15 */ + -4, 15, -43, -32, -20, /* File# 1, Vec# 3, 16-20 */ + 26, -27, 27, 20, -5, /* File# 1, Vec# 3, 21-25 */ + -23, -31, 20, 39, -4, /* File# 1, Vec# 3, 26-30 */ + -69, 46, 52, -2, -12, /* File# 1, Vec# 3, 31-35 */ + 17, 24, -22, -14, -6 /* File# 1, Vec# 3, 36-40 */ + }, + { + -28, 28, 51, 24, -5, /* File# 1, Vec# 4, 1- 5 */ + 16, 8, -27, 24, 19, /* File# 1, Vec# 4, 6-10 */ + -61, 26, 15, -46, 17, /* File# 1, Vec# 4, 11-15 */ + -17, -22, 22, 48, 31, /* File# 1, Vec# 4, 16-20 */ + 36, 13, 20, 53, -36, /* File# 1, Vec# 4, 21-25 */ + -43, -29, -20, 3, -77, /* File# 1, Vec# 4, 26-30 */ + -40, 30, -12, -3, -24, /* File# 1, Vec# 4, 31-35 */ + -15, 45, -13, 1, 25 /* File# 1, Vec# 4, 36-40 */ + }, + { + -29, -5, -47, -65, -6, /* File# 1, Vec# 5, 1- 5 */ + 81, -13, 21, 45, 16, /* File# 1, Vec# 5, 6-10 */ + 30, 29, 76, -12, -14, /* File# 1, Vec# 5, 11-15 */ + 27, -24, -4, 44, -14, /* File# 1, Vec# 5, 16-20 */ + -43, 17, -39, -19, -9, /* File# 1, Vec# 5, 21-25 */ + -17, 13, -9, 35, 30, /* File# 1, Vec# 5, 26-30 */ + -20, 11, 10, 12, 20, /* File# 1, Vec# 5, 31-35 */ + -53, -55, 2, -21, 6 /* File# 1, Vec# 5, 36-40 */ + }, + { + 37, -22, -30, 35, -36, /* File# 1, Vec# 6, 1- 5 */ + -17, -18, 15, 5, -53, /* File# 1, Vec# 6, 6-10 */ + -18, 34, 61, 21, 58, /* File# 1, Vec# 6, 11-15 */ + 27, 40, 52, -5, -3, /* File# 1, Vec# 6, 16-20 */ + 24, 6, 14, -8, -43, /* File# 1, Vec# 6, 21-25 */ + 11, -48, -56, -8, 26, /* File# 1, Vec# 6, 26-30 */ + -35, -27, 21, -51, -65, /* File# 1, Vec# 6, 31-35 */ + 7, 11, 5, 3, -17 /* File# 1, Vec# 6, 36-40 */ + }, + { + -135, 34, -2, -72, -42, /* File# 1, Vec# 7, 1- 5 */ + 21, 40, 7, 26, -25, /* File# 1, Vec# 7, 6-10 */ + -11, 3, 8, 22, 11, /* File# 1, Vec# 7, 11-15 */ + 24, 22, 22, -19, 16, /* File# 1, Vec# 7, 16-20 */ + 34, 52, 48, -27, 21, /* File# 1, Vec# 7, 21-25 */ + 38, -1, 2, -5, -39, /* File# 1, Vec# 7, 26-30 */ + -12, 8, 10, -12, -14, /* File# 1, Vec# 7, 31-35 */ + 16, -8, -20, -18, -25 /* File# 1, Vec# 7, 36-40 */ + } + }, + { + { + -60, 5, 8, 52, 56, /* File# 2, Vec# 1, 1- 5 */ + -8, -44, 0, -28, -45, /* File# 2, Vec# 1, 6-10 */ + -36, -9, 12, 25, 54, /* File# 2, Vec# 1, 11-15 */ + 17, -59, 7, 35, -20, /* File# 2, Vec# 1, 16-20 */ + 34, -11, -31, -36, 14, /* File# 2, Vec# 1, 21-25 */ + -5, -46, 60, 27, -4, /* File# 2, Vec# 1, 26-30 */ + 28, 0, 16, 28, -8, /* File# 2, Vec# 1, 31-35 */ + -2, -54, 1, 16, -42 /* File# 2, Vec# 1, 36-40 */ + }, + { + -25, -29, 13, -18, 37, /* File# 2, Vec# 2, 1- 5 */ + -7, -60, -13, -3, -11, /* File# 2, Vec# 2, 6-10 */ + -24, 20, 8, -54, -18, /* File# 2, Vec# 2, 11-15 */ + 4, -24, -21, 14, 67, /* File# 2, Vec# 2, 16-20 */ + 52, -9, 43, 13, -9, /* File# 2, Vec# 2, 21-25 */ + 52, 5, -16, 33, 65, /* File# 2, Vec# 2, 26-30 */ + 17, -14, -14, -55, 66, /* File# 2, Vec# 2, 31-35 */ + 46, -17, -13, -15, -11 /* File# 2, Vec# 2, 36-40 */ + }, + { + -53, -22, -4, 20, 24, /* File# 2, Vec# 3, 1- 5 */ + -60, 18, 75, -7, -2, /* File# 2, Vec# 3, 6-10 */ + 22, -7, -30, -49, 5, /* File# 2, Vec# 3, 11-15 */ + 26, -6, -76, 19, 18, /* File# 2, Vec# 3, 16-20 */ + -13, 23, -18, -13, 7, /* File# 2, Vec# 3, 21-25 */ + -7, -35, -57, 10, 2, /* File# 2, Vec# 3, 26-30 */ + -41, 38, 32, -1, -4, /* File# 2, Vec# 3, 31-35 */ + -38, 8, 26, 40, 18 /* File# 2, Vec# 3, 36-40 */ + }, + { + -9, 5, 1, 24, 46, /* File# 2, Vec# 4, 1- 5 */ + -22, -21, 22, 69, 60, /* File# 2, Vec# 4, 6-10 */ + -55, -42, 27, -15, -17, /* File# 2, Vec# 4, 11-15 */ + -4, 48, 51, -12, 12, /* File# 2, Vec# 4, 16-20 */ + -47, 10, 41, -67, -14, /* File# 2, Vec# 4, 21-25 */ + -41, -8, 21, -25, 14, /* File# 2, Vec# 4, 26-30 */ + 1, -5, 27, 21, 41, /* File# 2, Vec# 4, 31-35 */ + 38, 7, 24, -4, -18 /* File# 2, Vec# 4, 36-40 */ + }, + { + 33, -39, 51, -27, 34, /* File# 2, Vec# 5, 1- 5 */ + -26, -79, 38, -23, -12, /* File# 2, Vec# 5, 6-10 */ + 26, 29, 20, -19, -28, /* File# 2, Vec# 5, 11-15 */ + -26, 2, 59, 5, -30, /* File# 2, Vec# 5, 16-20 */ + -6, 44, 29, -37, 37, /* File# 2, Vec# 5, 21-25 */ + 38, 18, -2, -29, -61, /* File# 2, Vec# 5, 26-30 */ + -41, -20, -49, 23, -14, /* File# 2, Vec# 5, 31-35 */ + -26, -8, -20, 10, 29 /* File# 2, Vec# 5, 36-40 */ + }, + { + 72, 92, 7, 14, 19, /* File# 2, Vec# 6, 1- 5 */ + -11, 34, 23, -8, 0, /* File# 2, Vec# 6, 6-10 */ + -27, -12, 11, -15, -32, /* File# 2, Vec# 6, 11-15 */ + 17, 10, 13, -64, -5, /* File# 2, Vec# 6, 16-20 */ + 35, 23, -21, -35, -21, /* File# 2, Vec# 6, 21-25 */ + -11, -15, -29, 61, -21, /* File# 2, Vec# 6, 26-30 */ + -10, 71, -20, 2, 36, /* File# 2, Vec# 6, 31-35 */ + -6, -52, -40, -11, -6 /* File# 2, Vec# 6, 36-40 */ + }, + { + -43, -45, 61, 38, 37, /* File# 2, Vec# 7, 1- 5 */ + 8, 55, -4, -8, 67, /* File# 2, Vec# 7, 6-10 */ + 25, 13, 16, 11, 0, /* File# 2, Vec# 7, 11-15 */ + 24, 31, 29, -1, -57, /* File# 2, Vec# 7, 16-20 */ + 44, 5, -66, 3, -10, /* File# 2, Vec# 7, 21-25 */ + -24, 24, -27, -24, 3, /* File# 2, Vec# 7, 26-30 */ + -36, -3, -26, -55, 24, /* File# 2, Vec# 7, 31-35 */ + 24, -43, 0, 5, -35 /* File# 2, Vec# 7, 36-40 */ + } + } +}; + + +/* voiced code vectors */ +/*---------------------*/ + +int16_tRom pppsrVcdCodeVec + [VCDCODEVEC_NUM_OF_CODE_BOOKS][VCDCODEVEC_NUM_OF_CODE_BITS][S_LEN] = +{ + { + { + 24, 13, -55, -51, -8, /* File# 1, Vec# 1, 1- 5 */ + -58, 2, -75, -70, 22, /* File# 1, Vec# 1, 6-10 */ + -4, -21, 19, -21, 23, /* File# 1, Vec# 1, 11-15 */ + 54, 16, 10, 32, 1, /* File# 1, Vec# 1, 16-20 */ + 30, 3, -15, -7, -42, /* File# 1, Vec# 1, 21-25 */ + -2, -22, -36, -20, -27, /* File# 1, Vec# 1, 26-30 */ + 12, 21, 46, 35, 31, /* File# 1, Vec# 1, 31-35 */ + 27, 3, 16, -9, 4 /* File# 1, Vec# 1, 36-40 */ + }, + { + -10, -53, 46, 10, -28, /* File# 1, Vec# 2, 1- 5 */ + 18, 19, 22, -17, -11, /* File# 1, Vec# 2, 6-10 */ + 6, 0, 58, 7, -37, /* File# 1, Vec# 2, 11-15 */ + 32, -24, -49, -7, -10, /* File# 1, Vec# 2, 16-20 */ + -25, -32, -3, -48, -41, /* File# 1, Vec# 2, 21-25 */ + -6, -24, -18, 18, -43, /* File# 1, Vec# 2, 26-30 */ + 9, -18, -15, 36, 28, /* File# 1, Vec# 2, 31-35 */ + 74, 58, 47, 49, 21 /* File# 1, Vec# 2, 36-40 */ + }, + { + -25, -1, 8, 20, 13, /* File# 1, Vec# 3, 1- 5 */ + -34, -52, -35, 23, 18, /* File# 1, Vec# 3, 6-10 */ + 70, 44, 25, 76, -20, /* File# 1, Vec# 3, 11-15 */ + 1, 6, -49, -18, -43, /* File# 1, Vec# 3, 16-20 */ + 27, -29, 32, 36, 3, /* File# 1, Vec# 3, 21-25 */ + -6, -34, 11, 37, -13, /* File# 1, Vec# 3, 26-30 */ + -50, 58, 32, 0, 12, /* File# 1, Vec# 3, 31-35 */ + 16, 16, -6, -20, -3 /* File# 1, Vec# 3, 36-40 */ + }, + { + -50, 38, 47, 43, 9, /* File# 1, Vec# 4, 1- 5 */ + 31, 1, -23, 25, 21, /* File# 1, Vec# 4, 6-10 */ + -38, 20, 7, -55, 7, /* File# 1, Vec# 4, 11-15 */ + -30, -8, 23, 44, 28, /* File# 1, Vec# 4, 16-20 */ + 44, 19, 26, 49, -32, /* File# 1, Vec# 4, 21-25 */ + -28, -51, -30, -11, -65, /* File# 1, Vec# 4, 26-30 */ + -44, 40, -9, 22, -1, /* File# 1, Vec# 4, 31-35 */ + -6, 44, -3, 7, 13 /* File# 1, Vec# 4, 36-40 */ + }, + { + -93, -25, -46, -35, 11, /* File# 1, Vec# 5, 1- 5 */ + 69, -8, 37, 45, 21, /* File# 1, Vec# 5, 6-10 */ + 42, 23, 64, -25, -10, /* File# 1, Vec# 5, 11-15 */ + 16, -19, 8, 41, -7, /* File# 1, Vec# 5, 16-20 */ + -32, 10, -45, -17, -20, /* File# 1, Vec# 5, 21-25 */ + -35, 25, -6, 16, 46, /* File# 1, Vec# 5, 26-30 */ + -1, 14, 10, 6, 4, /* File# 1, Vec# 5, 31-35 */ + -43, -29, -9, -14, -7 /* File# 1, Vec# 5, 36-40 */ + }, + { + 76, -13, -23, 33, -35, /* File# 1, Vec# 6, 1- 5 */ + 5, -19, 7, 18, -59, /* File# 1, Vec# 6, 6-10 */ + -15, 40, 76, 36, 57, /* File# 1, Vec# 6, 11-15 */ + 29, 38, 58, 2, 0, /* File# 1, Vec# 6, 16-20 */ + 16, 6, 9, -14, -25, /* File# 1, Vec# 6, 21-25 */ + 9, -49, -39, -5, 17, /* File# 1, Vec# 6, 26-30 */ + -33, -44, 9, -43, -32, /* File# 1, Vec# 6, 31-35 */ + -1, 13, 1, 9, -6 /* File# 1, Vec# 6, 36-40 */ + }, + { + -196, 16, -22, -35, -34, /* File# 1, Vec# 7, 1- 5 */ + 20, 30, 10, 19, -22, /* File# 1, Vec# 7, 6-10 */ + 2, -13, -4, 22, 14, /* File# 1, Vec# 7, 11-15 */ + 22, 20, 15, -15, 22, /* File# 1, Vec# 7, 16-20 */ + 29, 40, 43, -14, 30, /* File# 1, Vec# 7, 21-25 */ + 36, -8, -10, -19, -42, /* File# 1, Vec# 7, 26-30 */ + -12, -15, -9, -12, -12, /* File# 1, Vec# 7, 31-35 */ + 0, -9, -5, -11, -7 /* File# 1, Vec# 7, 36-40 */ + }, + { + -77, 48, 24, 65, 45, /* File# 1, Vec# 8, 1- 5 */ + -3, -38, 15, -29, -44, /* File# 1, Vec# 8, 6-10 */ + -47, 6, 2, 4, 63, /* File# 1, Vec# 8, 11-15 */ + 27, -26, 27, 47, -13, /* File# 1, Vec# 8, 16-20 */ + 17, -16, -23, -31, -3, /* File# 1, Vec# 8, 21-25 */ + -10, -33, 46, 18, 15, /* File# 1, Vec# 8, 26-30 */ + 43, 9, 25, 24, -26, /* File# 1, Vec# 8, 31-35 */ + -10, -46, -27, -13, -37 /* File# 1, Vec# 8, 36-40 */ + }, + { + -24, -56, 30, -9, 27, /* File# 1, Vec# 9, 1- 5 */ + -13, -56, -1, -24, -24, /* File# 1, Vec# 9, 6-10 */ + -38, -1, 10, -57, -21, /* File# 1, Vec# 9, 11-15 */ + -1, -34, -12, 29, 55, /* File# 1, Vec# 9, 16-20 */ + 42, -1, 44, 33, 2, /* File# 1, Vec# 9, 21-25 */ + 54, 11, -9, 55, 73, /* File# 1, Vec# 9, 26-30 */ + 13, -2, 3, -46, 52, /* File# 1, Vec# 9, 31-35 */ + 27, 1, 4, -4, -17 /* File# 1, Vec# 9, 36-40 */ + } + } +}; + + +/* vector quantizer tables */ +/*-------------------------*/ + +int16_tRom psrQuant1 + [QUANT1_NUM_OF_WORDS] = +{ + -5980, /* Vector 0, coef 1(232), 2(164) */ + 25056, /* Vector 0, coef 3( 97) Vector 1, + * Coef 1(224) */ + -22691, /* Vector 1, coef 2(167), 3( 93) */ + -7724, /* Vector 2, coef 1(225), 2(212) */ + 27102, /* Vector 2, coef 3(105) Vector 3, + * Coef 1(222) */ + -18323, /* Vector 3, coef 2(184), 3(109) */ + -8275, /* Vector 4, coef 1(223), 2(173) */ + 18136, /* Vector 4, coef 3( 70) Vector 5, + * Coef 1(216) */ + -13700, /* Vector 5, coef 2(202), 3(124) */ + -11073, /* Vector 6, coef 1(212), 2(191) */ + -27189, /* Vector 6, coef 3(149) Vector 7, + * Coef 1(203) */ + -21101, /* Vector 7, coef 2(173), 3(147) */ + -15434, /* Vector 8, coef 1(195), 2(182) */ + -31279, /* Vector 8, coef 3(133) Vector 9, + * Coef 1(209) */ + -22689, /* Vector 9, coef 2(167), 3( 95) */ + -12363, /* Vector 10, coef 1(207), 2(181) */ + 21448, /* Vector 10, coef 3( 83) Vector 11, + * Coef 1(200) */ + -21397, /* Vector 11, coef 2(172), 3(107) */ + -12572, /* Vector 12, coef 1(206), 2(228) */ + -22070, /* Vector 12, coef 3(169) Vector 13, + * Coef 1(202) */ + -5974, /* Vector 13, coef 2(232), 3(170) */ + -14112, /* Vector 14, coef 1(200), 2(224) */ + -25915, /* Vector 14, coef 3(154) Vector 15, + * Coef 1(197) */ + -6003, /* Vector 15, coef 2(232), 3(141) */ + -13613, /* Vector 16, coef 1(202), 2(211) */ + -29240, /* Vector 16, coef 3(141) Vector 17, + * Coef 1(200) */ + -10112, /* Vector 17, coef 2(216), 3(128) */ + -15142, /* Vector 18, coef 1(196), 2(218) */ + 31938, /* Vector 18, coef 3(124) Vector 19, + * Coef 1(194) */ + -12410, /* Vector 19, coef 2(207), 3(134) */ + -13114, /* Vector 20, coef 1(204), 2(198) */ + 30406, /* Vector 20, coef 3(118) Vector 21, + * Coef 1(198) */ + -15487, /* Vector 21, coef 2(195), 3(129) */ + -16186, /* Vector 22, coef 1(192), 2(198) */ + -31809, /* Vector 22, coef 3(131) Vector 23, + * Coef 1(191) */ + -17285, /* Vector 23, coef 2(188), 3(123) */ + -15419, /* Vector 24, coef 1(195), 2(197) */ + 28093, /* Vector 24, coef 3(109) Vector 25, + * Coef 1(189) */ + -19864, /* Vector 25, coef 2(178), 3(104) */ + -15396, /* Vector 26, coef 1(195), 2(220) */ + -24635, /* Vector 26, coef 3(159) Vector 27, + * Coef 1(197) */ + -12651, /* Vector 27, coef 2(206), 3(149) */ + -16421, /* Vector 28, coef 1(191), 2(219) */ + -21825, /* Vector 28, coef 3(170) Vector 29, + * Coef 1(191) */ + -7791, /* Vector 29, coef 2(225), 3(145) */ + -16956, /* Vector 30, coef 1(189), 2(196) */ + 23237, /* Vector 30, coef 3( 90) Vector 31, + * Coef 1(197) */ + -25725, /* Vector 31, coef 2(155), 3(131) */ + -17473, /* Vector 32, coef 1(187), 2(191) */ + 29630, /* Vector 32, coef 3(115) Vector 33, + * Coef 1(190) */ + -9829, /* Vector 33, coef 2(217), 3(155) */ + -16935, /* Vector 34, coef 1(189), 2(217) */ + -29000, /* Vector 34, coef 3(142) Vector 35, + * Coef 1(184) */ + -7789, /* Vector 35, coef 2(225), 3(147) */ + -18216, /* Vector 36, coef 1(184), 2(216) */ + -27975, /* Vector 36, coef 3(146) Vector 37, + * Coef 1(185) */ + -5732, /* Vector 37, coef 2(233), 3(156) */ + -18214, /* Vector 38, coef 1(184), 2(218) */ + -24388, /* Vector 38, coef 3(160) Vector 39, + * Coef 1(188) */ + -12122, /* Vector 39, coef 2(208), 3(166) */ + -17207, /* Vector 40, coef 1(188), 2(201) */ + -25675, /* Vector 40, coef 3(155) Vector 41, + * Coef 1(181) */ + -9054, /* Vector 41, coef 2(220), 3(162) */ + -19743, /* Vector 42, coef 1(178), 2(225) */ + -23118, /* Vector 42, coef 3(165) Vector 43, + * Coef 1(178) */ + -8809, /* Vector 43, coef 2(221), 3(151) */ + -20512, /* Vector 44, coef 1(175), 2(224) */ + -24644, /* Vector 44, coef 3(159) Vector 45, + * Coef 1(188) */ + -12400, /* Vector 45, coef 2(207), 3(144) */ + -17712, /* Vector 46, coef 1(186), 2(208) */ + -30792, /* Vector 46, coef 3(135) Vector 47, + * Coef 1(184) */ + -15224, /* Vector 47, coef 2(196), 3(136) */ + -19258, /* Vector 48, coef 1(180), 2(198) */ + -31564, /* Vector 48, coef 3(132) Vector 49, + * Coef 1(180) */ + -9845, /* Vector 49, coef 2(217), 3(139) */ + -20263, /* Vector 50, coef 1(176), 2(217) */ + -29518, /* Vector 50, coef 3(140) Vector 51, + * Coef 1(178) */ + -12929, /* Vector 51, coef 2(205), 3(127) */ + -20531, /* Vector 52, coef 1(175), 2(205) */ + -31814, /* Vector 52, coef 3(131) Vector 53, + * Coef 1(186) */ + -9355, /* Vector 53, coef 2(219), 3(117) */ + -18480, /* Vector 54, coef 1(183), 2(208) */ + 30131, /* Vector 54, coef 3(117) Vector 55, + * Coef 1(179) */ + -10383, /* Vector 55, coef 2(215), 3(113) */ + -17459, /* Vector 56, coef 1(187), 2(205) */ + -18246, /* Vector 56, coef 3(184) Vector 57, + * Coef 1(186) */ + -14416, /* Vector 57, coef 2(199), 3(176) */ + -19502, /* Vector 58, coef 1(179), 2(210) */ + -21581, /* Vector 58, coef 3(171) Vector 59, + * Coef 1(179) */ + -13909, /* Vector 59, coef 2(201), 3(171) */ + -18994, /* Vector 60, coef 1(181), 2(206) */ + -24905, /* Vector 60, coef 3(158) Vector 61, + * Coef 1(183) */ + -14443, /* Vector 61, coef 2(199), 3(149) */ + -19515, /* Vector 62, coef 1(179), 2(197) */ + -26437, /* Vector 62, coef 3(152) Vector 63, + * Coef 1(187) */ + -19835, /* Vector 63, coef 2(178), 3(133) */ + -20543, /* Vector 64, coef 1(175), 2(193) */ + 30890, /* Vector 64, coef 3(120) Vector 65, + * Coef 1(170) */ + -15250, /* Vector 65, coef 2(196), 3(110) */ + -20031, /* Vector 66, coef 1(177), 2(193) */ + -27219, /* Vector 66, coef 3(149) Vector 67, + * Coef 1(173) */ + -9822, /* Vector 67, coef 2(217), 3(162) */ + -21295, /* Vector 68, coef 1(172), 2(209) */ + -23893, /* Vector 68, coef 3(162) Vector 69, + * Coef 1(171) */ + -12373, /* Vector 69, coef 2(207), 3(171) */ + -22574, /* Vector 70, coef 1(167), 2(210) */ + -21337, /* Vector 70, coef 3(172) Vector 71, + * Coef 1(167) */ + -12133, /* Vector 71, coef 2(208), 3(155) */ + -23855, /* Vector 72, coef 1(162), 2(209) */ + -19800, /* Vector 72, coef 3(178) Vector 73, + * Coef 1(168) */ + -15203, /* Vector 73, coef 2(196), 3(157) */ + -23104, /* Vector 74, coef 1(165), 2(192) */ + -26452, /* Vector 74, coef 3(152) Vector 75, + * Coef 1(172) */ + -11884, /* Vector 75, coef 2(209), 3(148) */ + -21560, /* Vector 76, coef 1(171), 2(200) */ + -28751, /* Vector 76, coef 3(143) Vector 77, + * Coef 1(177) */ + -17781, /* Vector 77, coef 2(186), 3(139) */ + -21315, /* Vector 78, coef 1(172), 2(189) */ + -30038, /* Vector 78, coef 3(138) Vector 79, + * Coef 1(170) */ + -12415, /* Vector 79, coef 2(207), 3(129) */ + -22588, /* Vector 80, coef 1(167), 2(196) */ + 32420, /* Vector 80, coef 3(126) Vector 81, + * Coef 1(164) */ + -13177, /* Vector 81, coef 2(204), 3(135) */ + -24123, /* Vector 82, coef 1(161), 2(197) */ + -31056, /* Vector 82, coef 3(134) Vector 83, + * Coef 1(176) */ + -21620, /* Vector 83, coef 2(171), 3(140) */ + -22607, /* Vector 84, coef 1(167), 2(177) */ + -27221, /* Vector 84, coef 3(149) Vector 85, + * Coef 1(171) */ + -23137, /* Vector 85, coef 2(165), 3(159) */ + -22092, /* Vector 86, coef 1(169), 2(180) */ + -30810, /* Vector 86, coef 3(135) Vector 87, + * Coef 1(166) */ + -18816, /* Vector 87, coef 2(182), 3(128) */ + -19531, /* Vector 88, coef 1(179), 2(181) */ + -32602, /* Vector 88, coef 3(128) Vector 89, + * Coef 1(166) */ + -8046, /* Vector 89, coef 2(224), 3(146) */ + -24094, /* Vector 90, coef 1(161), 2(226) */ + -28254, /* Vector 90, coef 3(145) Vector 91, + * Coef 1(162) */ + -11878, /* Vector 91, coef 2(209), 3(154) */ + -24873, /* Vector 92, coef 1(158), 2(215) */ + -24931, /* Vector 92, coef 3(158) Vector 93, + * Coef 1(157) */ + -8315, /* Vector 93, coef 2(223), 3(133) */ + -22318, /* Vector 94, coef 1(168), 2(210) */ + 27555, /* Vector 94, coef 3(107) Vector 95, + * Coef 1(163) */ + -13201, /* Vector 95, coef 2(204), 3(111) */ + -18764, /* Vector 96, coef 1(182), 2(180) */ + 28848, /* Vector 96, coef 3(112) Vector 97, + * Coef 1(176) */ + -13975, /* Vector 97, coef 2(201), 3(105) */ + -21579, /* Vector 98, coef 1(171), 2(181) */ + 29348, /* Vector 98, coef 3(114) Vector 99, + * Coef 1(164) */ + -20371, /* Vector 99, coef 2(176), 3(109) */ + -23379, /* Vector 100, coef 1(164), 2(173) */ + -31583, /* Vector 100, coef 3(132) Vector + * 101, Coef 1(161) */ + -21381, /* Vector 101, coef 2(172), 3(123) */ + -18777, /* Vector 102, coef 1(182), 2(167) */ + -32080, /* Vector 102, coef 3(130) Vector + * 103, Coef 1(176) */ + -21382, /* Vector 103, coef 2(172), 3(122) */ + -17754, /* Vector 104, coef 1(186), 2(166) */ + 30898, /* Vector 104, coef 3(120) Vector + * 105, Coef 1(178) */ + -23697, /* Vector 105, coef 2(163), 3(111) */ + -20839, /* Vector 106, coef 1(174), 2(153) */ + 26034, /* Vector 106, coef 3(101) Vector + * 107, Coef 1(178) */ + -22436, /* Vector 107, coef 2(168), 3( 92) */ + -19020, /* Vector 108, coef 1(181), 2(180) */ + 20657, /* Vector 108, coef 3( 80) Vector + * 109, Coef 1(177) */ + -19125, /* Vector 109, coef 2(181), 3( 75) */ + -19525, /* Vector 110, coef 1(179), 2(187) */ + 27311, /* Vector 110, coef 3(106) Vector + * 111, Coef 1(175) */ + -20381, /* Vector 111, coef 2(176), 3( 99) */ + -22618, /* Vector 112, coef 1(167), 2(166) */ + 27812, /* Vector 112, coef 3(108) Vector + * 113, Coef 1(164) */ + -25246, /* Vector 113, coef 2(157), 3( 98) */ + -21598, /* Vector 114, coef 1(171), 2(162) */ + -30806, /* Vector 114, coef 3(135) Vector + * 115, Coef 1(170) */ + -27260, /* Vector 115, coef 2(149), 3(132) */ + -22109, /* Vector 116, coef 1(169), 2(163) */ + 31139, /* Vector 116, coef 3(121) Vector + * 117, Coef 1(163) */ + -25736, /* Vector 117, coef 2(155), 3(120) */ + -24671, /* Vector 118, coef 1(159), 2(161) */ + -32356, /* Vector 118, coef 3(129) Vector + * 119, Coef 1(156) */ + -24717, /* Vector 119, coef 2(159), 3(115) */ + -21870, /* Vector 120, coef 1(170), 2(146) */ + 29597, /* Vector 120, coef 3(115) Vector + * 121, Coef 1(157) */ + -28308, /* Vector 121, coef 2(145), 3(108) */ + -24695, /* Vector 122, coef 1(159), 2(137) */ + -31576, /* Vector 122, coef 3(132) Vector + * 123, Coef 1(168) */ + -19364, /* Vector 123, coef 2(180), 3( 92) */ + -25438, /* Vector 124, coef 1(156), 2(162) */ + 25250, /* Vector 124, coef 3( 98) Vector + * 125, Coef 1(162) */ + -18316, /* Vector 125, coef 2(184), 3(116) */ + -25172, /* Vector 126, coef 1(157), 2(172) */ + 28575, /* Vector 126, coef 3(111) Vector + * 127, Coef 1(159) */ + -19868, /* Vector 127, coef 2(178), 3(100) */ + -9361, /* Vector 128, coef 1(219), 2(111) */ + 16344, /* Vector 128, coef 3( 63) Vector + * 129, Coef 1(216) */ + -25510, /* Vector 129, coef 2(156), 3( 90) */ + -11889, /* Vector 130, coef 1(209), 2(143) */ + 20151, /* Vector 130, coef 3( 78) Vector + * 131, Coef 1(183) */ + -26768, /* Vector 131, coef 2(151), 3(112) */ + -23158, /* Vector 132, coef 1(165), 2(138) */ + 26316, /* Vector 132, coef 3(102) Vector + * 133, Coef 1(204) */ + 32120, /* Vector 133, coef 2(125), 3(120) */ + -17047, /* Vector 134, coef 1(189), 2(105) */ + 28596, /* Vector 134, coef 3(111) Vector + * 135, Coef 1(180) */ + 22908, /* Vector 135, coef 2( 89), 3(124) */ + -18617, /* Vector 136, coef 1(183), 2( 71) */ + 30431, /* Vector 136, coef 3(118) Vector + * 137, Coef 1(223) */ + 29029, /* Vector 137, coef 2(113), 3(101) */ + -13988, /* Vector 138, coef 1(201), 2( 92) */ + 22966, /* Vector 138, coef 3( 89) Vector + * 139, Coef 1(182) */ + 28514, /* Vector 139, coef 2(111), 3( 98) */ + -20898, /* Vector 140, coef 1(174), 2( 94) */ + 23493, /* Vector 140, coef 3( 91) Vector + * 141, Coef 1(197) */ + -28552, /* Vector 141, coef 2(144), 3(120) */ + -14958, /* Vector 142, coef 1(197), 2(146) */ + 25786, /* Vector 142, coef 3(100) Vector + * 143, Coef 1(186) */ + -31898, /* Vector 143, coef 2(131), 3(102) */ + -14725, /* Vector 144, coef 1(198), 2(123) */ + 23205, /* Vector 144, coef 3( 90) Vector + * 145, Coef 1(165) */ + -31843, /* Vector 145, coef 2(131), 3(157) */ + -21397, /* Vector 146, coef 1(172), 2(107) */ + -23115, /* Vector 146, coef 3(165) Vector + * 147, Coef 1(181) */ + 30855, /* Vector 147, coef 2(120), 3(135) */ + -24461, /* Vector 148, coef 1(160), 2(115) */ + -32612, /* Vector 148, coef 3(128) Vector + * 149, Coef 1(156) */ + -32647, /* Vector 149, coef 2(128), 3(121) */ + -29316, /* Vector 150, coef 1(141), 2(124) */ + -31330, /* Vector 150, coef 3(133) Vector + * 151, Coef 1(158) */ + 25740, /* Vector 151, coef 2(100), 3(140) */ + -28069, /* Vector 152, coef 1(146), 2( 91) */ + -31863, /* Vector 152, coef 3(131) Vector + * 153, Coef 1(137) */ + 27512, /* Vector 153, coef 2(107), 3(120) */ + -20354, /* Vector 154, coef 1(176), 2(126) */ + 31142, /* Vector 154, coef 3(121) Vector + * 155, Coef 1(166) */ + 29296, /* Vector 155, coef 2(114), 3(112) */ + -20606, /* Vector 156, coef 1(175), 2(130) */ + 25763, /* Vector 156, coef 3(100) Vector + * 157, Coef 1(163) */ + 29794, /* Vector 157, coef 2(116), 3( 98) */ + -26781, /* Vector 158, coef 1(151), 2( 99) */ + 29340, /* Vector 158, coef 3(114) Vector + * 159, Coef 1(156) */ + 23144, /* Vector 159, coef 2( 90), 3(104) */ + -16214, /* Vector 160, coef 1(192), 2(170) */ + 27334, /* Vector 160, coef 3(106) Vector + * 161, Coef 1(198) */ + -28846, /* Vector 161, coef 2(143), 3( 82) */ + -16251, /* Vector 162, coef 1(192), 2(133) */ + 18092, /* Vector 162, coef 3( 70) Vector + * 163, Coef 1(172) */ + 27212, /* Vector 163, coef 2(106), 3( 76) */ + 31572, /* Vector 164, coef 1(123), 2( 84) */ + 28050, /* Vector 164, coef 3(109) Vector + * 165, Coef 1(146) */ + 25184, /* Vector 165, coef 2( 98), 3( 96) */ + -26783, /* Vector 166, coef 1(151), 2( 97) */ + 21102, /* Vector 166, coef 3( 82) Vector + * 167, Coef 1(110) */ + 17765, /* Vector 167, coef 2( 69), 3(101) */ + 28473, /* Vector 168, coef 1(111), 2( 57) */ + 26502, /* Vector 168, coef 3(103) Vector + * 169, Coef 1(134) */ + 18264, /* Vector 169, coef 2( 71), 3( 88) */ + -31417, /* Vector 170, coef 1(133), 2( 71) */ + 17578, /* Vector 170, coef 3( 68) Vector + * 171, Coef 1(170) */ + 20558, /* Vector 171, coef 2( 80), 3( 78) */ + -16280, /* Vector 172, coef 1(192), 2(104) */ + 14727, /* Vector 172, coef 3( 57) Vector + * 173, Coef 1(135) */ + 11105, /* Vector 173, coef 2( 43), 3( 97) */ + -25554, /* Vector 174, coef 1(156), 2( 46) */ + 17859, /* Vector 174, coef 3( 69) Vector + * 175, Coef 1(195) */ + -18870, /* Vector 175, coef 2(182), 3( 74) */ + -17242, /* Vector 176, coef 1(188), 2(166) */ + 21943, /* Vector 176, coef 3( 85) Vector + * 177, Coef 1(183) */ + -26531, /* Vector 177, coef 2(152), 3( 93) */ + -20848, /* Vector 178, coef 1(174), 2(144) */ + 21677, /* Vector 178, coef 3( 84) Vector + * 179, Coef 1(173) */ + 32333, /* Vector 179, coef 2(126), 3( 77) */ + -20610, /* Vector 180, coef 1(175), 2(126) */ + 15288, /* Vector 180, coef 3( 59) Vector + * 181, Coef 1(184) */ + -24003, /* Vector 181, coef 2(162), 3( 61) */ + -21876, /* Vector 182, coef 1(170), 2(140) */ + 14235, /* Vector 182, coef 3( 55) Vector + * 183, Coef 1(155) */ + 31579, /* Vector 183, coef 2(123), 3( 91) */ + -24198, /* Vector 184, coef 1(161), 2(122) */ + 20891, /* Vector 184, coef 3( 81) Vector + * 185, Coef 1(155) */ + 30017, /* Vector 185, coef 2(117), 3( 65) */ + -30876, /* Vector 186, coef 1(135), 2(100) */ + 13949, /* Vector 186, coef 3( 54) Vector + * 187, Coef 1(125) */ + 25416, /* Vector 187, coef 2( 99), 3( 72) */ + 22097, /* Vector 188, coef 1( 86), 2( 81) */ + 18554, /* Vector 188, coef 3( 72) Vector + * 189, Coef 1(122) */ + 22866, /* Vector 189, coef 2( 89), 3( 82) */ + 31829, /* Vector 190, coef 1(124), 2( 85) */ + 18009, /* Vector 190, coef 3( 70) Vector + * 191, Coef 1( 89) */ + 10361, /* Vector 191, coef 2( 40), 3(121) */ + -31366, /* Vector 192, coef 1(133), 2(122) */ + 30579, /* Vector 192, coef 3(119) Vector + * 193, Coef 1(115) */ + 21641, /* Vector 193, coef 2( 84), 3(137) */ + 31080, /* Vector 194, coef 1(121), 2(104) */ + 28527, /* Vector 194, coef 3(111) Vector + * 195, Coef 1(111) */ + 22390, /* Vector 195, coef 2( 87), 3(118) */ + 25710, /* Vector 196, coef 1(100), 2(110) */ + -30132, /* Vector 196, coef 3(138) Vector + * 197, Coef 1( 76) */ + 26486, /* Vector 197, coef 2(103), 3(118) */ + 18280, /* Vector 198, coef 1( 71), 2(104) */ + 25914, /* Vector 198, coef 3(101) Vector + * 199, Coef 1( 58) */ + 25195, /* Vector 199, coef 2( 98), 3(107) */ + 21862, /* Vector 200, coef 1( 85), 2(102) */ + 26705, /* Vector 200, coef 3(104) Vector + * 201, Coef 1( 81) */ + 25186, /* Vector 201, coef 2( 98), 3( 98) */ + 18018, /* Vector 202, coef 1( 70), 2( 98) */ + 23104, /* Vector 202, coef 3( 90) Vector + * 203, Coef 1( 64) */ + 22366, /* Vector 203, coef 2( 87), 3( 94) */ + 19808, /* Vector 204, coef 1( 77), 2( 96) */ + -31928, /* Vector 204, coef 3(131) Vector + * 205, Coef 1( 72) */ + 21635, /* Vector 205, coef 2( 84), 3(131) */ + 15195, /* Vector 206, coef 1( 59), 2( 91) */ + 30781, /* Vector 206, coef 3(120) Vector + * 207, Coef 1( 61) */ + 20852, /* Vector 207, coef 2( 81), 3(116) */ + 22109, /* Vector 208, coef 1( 86), 2( 93) */ + 28754, /* Vector 208, coef 3(112) Vector + * 209, Coef 1( 82) */ + 22631, /* Vector 209, coef 2( 88), 3(103) */ + 18510, /* Vector 210, coef 1( 72), 2( 78) */ + 26704, /* Vector 210, coef 3(104) Vector + * 211, Coef 1( 80) */ + 19037, /* Vector 211, coef 2( 74), 3( 93) */ + -31637, /* Vector 212, coef 1(132), 2(107) */ + 25971, /* Vector 212, coef 3(101) Vector + * 213, Coef 1(115) */ + 24156, /* Vector 213, coef 2( 94), 3( 92) */ + 25180, /* Vector 214, coef 1( 98), 2( 92) */ + 22104, /* Vector 214, coef 3( 86) Vector + * 215, Coef 1( 88) */ + 21587, /* Vector 215, coef 2( 84), 3( 83) */ + 29812, /* Vector 216, coef 1(116), 2(116) */ + 31338, /* Vector 216, coef 3(122) Vector + * 217, Coef 1(106) */ + 26998, /* Vector 217, coef 2(105), 3(118) */ + 31609, /* Vector 218, coef 1(123), 2(121) */ + 26732, /* Vector 218, coef 3(104) Vector + * 219, Coef 1(108) */ + 28006, /* Vector 219, coef 2(109), 3(102) */ + 25192, /* Vector 220, coef 1( 98), 2(104) */ + 22624, /* Vector 220, coef 3( 88) Vector + * 221, Coef 1( 96) */ + 24669, /* Vector 221, coef 2( 96), 3( 93) */ + 22109, /* Vector 222, coef 1( 86), 2( 93) */ + 21064, /* Vector 222, coef 3( 82) Vector + * 223, Coef 1( 72) */ + 15988, /* Vector 223, coef 2( 62), 3(116) */ + -26486, /* Vector 224, coef 1(152), 2(138) */ + 24715, /* Vector 224, coef 3( 96) Vector + * 225, Coef 1(139) */ + -31895, /* Vector 225, coef 2(131), 3(105) */ + -28549, /* Vector 226, coef 1(144), 2(123) */ + 25732, /* Vector 226, coef 3(100) Vector + * 227, Coef 1(132) */ + 30810, /* Vector 227, coef 2(120), 3( 90) */ + -23917, /* Vector 228, coef 1(162), 2(147) */ + 21395, /* Vector 228, coef 3( 83) Vector + * 229, Coef 1(147) */ + -32690, /* Vector 229, coef 2(128), 3( 78) */ + -24437, /* Vector 230, coef 1(160), 2(139) */ + 16777, /* Vector 230, coef 3( 65) Vector + * 231, Coef 1(137) */ + 28733, /* Vector 231, coef 2(112), 3( 61) */ + 31610, /* Vector 232, coef 1(123), 2(122) */ + 21354, /* Vector 232, coef 3( 83) Vector + * 233, Coef 1(106) */ + 27217, /* Vector 233, coef 2(106), 3( 81) */ + 27500, /* Vector 234, coef 1(107), 2(108) */ + 18562, /* Vector 234, coef 3( 72) Vector + * 235, Coef 1(130) */ + 29517, /* Vector 235, coef 2(115), 3( 77) */ + 27748, /* Vector 236, coef 1(108), 2(100) */ + 19572, /* Vector 236, coef 3( 76) Vector + * 237, Coef 1(116) */ + 28226, /* Vector 237, coef 2(110), 3( 66) */ + 30824, /* Vector 238, coef 1(120), 2(104) */ + 16812, /* Vector 238, coef 3( 65) Vector + * 239, Coef 1(172) */ + -20397, /* Vector 239, coef 2(176), 3( 83) */ + -21056, /* Vector 240, coef 1(173), 2(192) */ + 19107, /* Vector 240, coef 3( 74) Vector + * 241, Coef 1(163) */ + -20396, /* Vector 241, coef 2(176), 3( 84) */ + -26473, /* Vector 242, coef 1(152), 2(151) */ + 22428, /* Vector 242, coef 3( 87) Vector + * 243, Coef 1(156) */ + -26036, /* Vector 243, coef 2(154), 3( 76) */ + -27243, /* Vector 244, coef 1(149), 2(149) */ + 18583, /* Vector 244, coef 3( 72) Vector + * 245, Coef 1(151) */ + -30398, /* Vector 245, coef 2(137), 3( 66) */ + -24418, /* Vector 246, coef 1(160), 2(158) */ + 13967, /* Vector 246, coef 3( 54) Vector + * 247, Coef 1(143) */ + -31173, /* Vector 247, coef 2(134), 3( 59) */ + -31366, /* Vector 248, coef 1(133), 2(122) */ + 13472, /* Vector 248, coef 3( 52) Vector + * 249, Coef 1(160) */ + -22478, /* Vector 249, coef 2(168), 3( 50) */ + -24400, /* Vector 250, coef 1(160), 2(176) */ + 11155, /* Vector 250, coef 3( 43) Vector + * 251, Coef 1(147) */ + -26308, /* Vector 251, coef 2(153), 3( 60) */ + -26977, /* Vector 252, coef 1(150), 2(159) */ + 12937, /* Vector 252, coef 3( 50) Vector + * 253, Coef 1(137) */ + -29876, /* Vector 253, coef 2(139), 3( 76) */ + -32644, /* Vector 254, coef 1(128), 2(124) */ + 18051, /* Vector 254, coef 3( 70) Vector + * 255, Coef 1(131) */ + 32567, /* Vector 255, coef 2(127), 3( 55) */ + -23642, /* Vector 256, coef 1(163), 2(166) */ + -28516, /* Vector 256, coef 3(144) Vector + * 257, Coef 1(156) */ + -11895, /* Vector 257, coef 2(209), 3(137) */ + -26147, /* Vector 258, coef 1(153), 2(221) */ + -29801, /* Vector 258, coef 3(139) Vector + * 259, Coef 1(151) */ + -11645, /* Vector 259, coef 2(210), 3(131) */ + -24632, /* Vector 260, coef 1(159), 2(200) */ + -23393, /* Vector 260, coef 3(164) Vector + * 261, Coef 1(159) */ + -14952, /* Vector 261, coef 2(197), 3(152) */ + -26161, /* Vector 262, coef 1(153), 2(207) */ + -25449, /* Vector 262, coef 3(156) Vector + * 263, Coef 1(151) */ + -13672, /* Vector 263, coef 2(202), 3(152) */ + -24391, /* Vector 264, coef 1(160), 2(185) */ + -25445, /* Vector 264, coef 3(156) Vector + * 265, Coef 1(155) */ + -16989, /* Vector 265, coef 2(189), 3(163) */ + -26692, /* Vector 266, coef 1(151), 2(188) */ + -25444, /* Vector 266, coef 3(156) Vector + * 267, Coef 1(156) */ + -20575, /* Vector 267, coef 2(175), 3(161) */ + -23875, /* Vector 268, coef 1(162), 2(189) */ + -28512, /* Vector 268, coef 3(144) Vector + * 269, Coef 1(160) */ + -18552, /* Vector 269, coef 2(183), 3(136) */ + -25661, /* Vector 270, coef 1(155), 2(195) */ + -29285, /* Vector 270, coef 3(141) Vector + * 271, Coef 1(155) */ + -18043, /* Vector 271, coef 2(185), 3(133) */ + -25673, /* Vector 272, coef 1(155), 2(183) */ + -28518, /* Vector 272, coef 3(144) Vector + * 273, Coef 1(154) */ + -21105, /* Vector 273, coef 2(173), 3(143) */ + -25682, /* Vector 274, coef 1(155), 2(174) */ + -31586, /* Vector 274, coef 3(132) Vector + * 275, Coef 1(158) */ + -15491, /* Vector 275, coef 2(195), 3(125) */ + -25918, /* Vector 276, coef 1(154), 2(194) */ + 31387, /* Vector 276, coef 3(122) Vector + * 277, Coef 1(155) */ + -18569, /* Vector 277, coef 2(183), 3(119) */ + -27201, /* Vector 278, coef 1(149), 2(191) */ + 30613, /* Vector 278, coef 3(119) Vector + * 279, Coef 1(149) */ + -8817, /* Vector 279, coef 2(221), 3(143) */ + -27441, /* Vector 280, coef 1(148), 2(207) */ + -29549, /* Vector 280, coef 3(140) Vector + * 281, Coef 1(147) */ + -13669, /* Vector 281, coef 2(202), 3(155) */ + -26941, /* Vector 282, coef 1(150), 2(195) */ + -29293, /* Vector 282, coef 3(141) Vector + * 283, Coef 1(147) */ + -18543, /* Vector 283, coef 2(183), 3(145) */ + -27465, /* Vector 284, coef 1(148), 2(183) */ + -31080, /* Vector 284, coef 3(134) Vector + * 285, Coef 1(152) */ + -24667, /* Vector 285, coef 2(159), 3(165) */ + -26156, /* Vector 286, coef 1(153), 2(212) */ + 27796, /* Vector 286, coef 3(108) Vector + * 287, Coef 1(148) */ + -14481, /* Vector 287, coef 2(199), 3(111) */ + -28202, /* Vector 288, coef 1(145), 2(214) */ + -29298, /* Vector 288, coef 3(141) Vector + * 289, Coef 1(142) */ + -11636, /* Vector 289, coef 2(210), 3(140) */ + -28460, /* Vector 290, coef 1(144), 2(212) */ + -23409, /* Vector 290, coef 3(164) Vector + * 291, Coef 1(143) */ + -10342, /* Vector 291, coef 2(215), 3(154) */ + -28472, /* Vector 292, coef 1(144), 2(200) */ + -27254, /* Vector 292, coef 3(149) Vector + * 293, Coef 1(138) */ + -8540, /* Vector 293, coef 2(222), 3(164) */ + -29996, /* Vector 294, coef 1(138), 2(212) */ + -27514, /* Vector 294, coef 3(148) Vector + * 295, Coef 1(134) */ + -9582, /* Vector 295, coef 2(218), 3(146) */ + -30774, /* Vector 296, coef 1(135), 2(202) */ + -29553, /* Vector 296, coef 3(140) Vector + * 297, Coef 1(143) */ + -15458, /* Vector 297, coef 2(195), 3(158) */ + -29247, /* Vector 298, coef 1(141), 2(193) */ + -28278, /* Vector 298, coef 3(145) Vector + * 299, Coef 1(138) */ + -16226, /* Vector 299, coef 2(192), 3(158) */ + -30789, /* Vector 300, coef 1(135), 2(187) */ + -26479, /* Vector 300, coef 3(152) Vector + * 301, Coef 1(145) */ + -12675, /* Vector 301, coef 2(206), 3(125) */ + -28729, /* Vector 302, coef 1(143), 2(199) */ + 32653, /* Vector 302, coef 3(127) Vector + * 303, Coef 1(141) */ + -9353, /* Vector 303, coef 2(219), 3(119) */ + -29998, /* Vector 304, coef 1(138), 2(210) */ + 31885, /* Vector 304, coef 3(124) Vector + * 305, Coef 1(141) */ + -16766, /* Vector 305, coef 2(190), 3(130) */ + -29250, /* Vector 306, coef 1(141), 2(190) */ + 29832, /* Vector 306, coef 3(116) Vector + * 307, Coef 1(136) */ + -16776, /* Vector 307, coef 2(190), 3(120) */ + -30022, /* Vector 308, coef 1(138), 2(186) */ + -30331, /* Vector 308, coef 3(137) Vector + * 309, Coef 1(133) */ + -18037, /* Vector 309, coef 2(185), 3(139) */ + -27969, /* Vector 310, coef 1(146), 2(191) */ + -30575, /* Vector 310, coef 3(136) Vector + * 311, Coef 1(145) */ + -20333, /* Vector 311, coef 2(176), 3(147) */ + -28493, /* Vector 312, coef 1(144), 2(179) */ + -31599, /* Vector 312, coef 3(132) Vector + * 313, Coef 1(145) */ + -9888, /* Vector 313, coef 2(217), 3( 96) */ + -28727, /* Vector 314, coef 1(143), 2(201) */ + 26753, /* Vector 314, coef 3(104) Vector + * 315, Coef 1(129) */ + -9071, /* Vector 315, coef 2(220), 3(145) */ + -32052, /* Vector 316, coef 1(130), 2(204) */ + -29814, /* Vector 316, coef 3(139) Vector + * 317, Coef 1(138) */ + -21334, /* Vector 317, coef 2(172), 3(170) */ + -30769, /* Vector 318, coef 1(135), 2(207) */ + 30339, /* Vector 318, coef 3(118) Vector + * 319, Coef 1(131) */ + -12935, /* Vector 319, coef 2(205), 3(121) */ + -26214, /* Vector 320, coef 1(153), 2(154) */ + -32620, /* Vector 320, coef 3(128) Vector + * 321, Coef 1(148) */ + -26256, /* Vector 321, coef 2(153), 3(112) */ + -28025, /* Vector 322, coef 1(146), 2(135) */ + 29334, /* Vector 322, coef 3(114) Vector + * 323, Coef 1(150) */ + -21884, /* Vector 323, coef 2(170), 3(132) */ + -27981, /* Vector 324, coef 1(146), 2(179) */ + 30596, /* Vector 324, coef 3(119) Vector + * 325, Coef 1(132) */ + -19082, /* Vector 325, coef 2(181), 3(118) */ + -30804, /* Vector 326, coef 1(135), 2(172) */ + -28542, /* Vector 326, coef 3(144) Vector + * 327, Coef 1(130) */ + -22133, /* Vector 327, coef 2(169), 3(139) */ + -32336, /* Vector 328, coef 1(129), 2(176) */ + -32112, /* Vector 328, coef 3(130) Vector + * 329, Coef 1(144) */ + -21369, /* Vector 329, coef 2(172), 3(135) */ + -29781, /* Vector 330, coef 1(139), 2(171) */ + -31336, /* Vector 330, coef 3(133) Vector + * 331, Coef 1(152) */ + -24432, /* Vector 331, coef 2(160), 3(144) */ + -28262, /* Vector 332, coef 1(145), 2(154) */ + -28533, /* Vector 332, coef 3(144) Vector + * 333, Coef 1(139) */ + -25466, /* Vector 333, coef 2(156), 3(134) */ + -28277, /* Vector 334, coef 1(145), 2(139) */ + -28282, /* Vector 334, coef 3(145) Vector + * 335, Coef 1(134) */ + -31086, /* Vector 335, coef 2(134), 3(146) */ + -32104, /* Vector 336, coef 1(130), 2(152) */ + -30313, /* Vector 336, coef 3(137) Vector + * 337, Coef 1(151) */ + -21895, /* Vector 337, coef 2(170), 3(121) */ + -27739, /* Vector 338, coef 1(147), 2(165) */ + 31118, /* Vector 338, coef 3(121) Vector + * 339, Coef 1(142) */ + -23173, /* Vector 339, coef 2(165), 3(123) */ + -29533, /* Vector 340, coef 1(140), 2(163) */ + 29073, /* Vector 340, coef 3(113) Vector + * 341, Coef 1(145) */ + -27011, /* Vector 341, coef 2(150), 3(125) */ + -29806, /* Vector 342, coef 1(139), 2(146) */ + 30603, /* Vector 342, coef 3(119) Vector + * 343, Coef 1(139) */ + -20099, /* Vector 343, coef 2(177), 3(125) */ + -30548, /* Vector 344, coef 1(136), 2(172) */ + 31110, /* Vector 344, coef 3(121) Vector + * 345, Coef 1(134) */ + -23679, /* Vector 345, coef 2(163), 3(129) */ + -32084, /* Vector 346, coef 1(130), 2(172) */ + 31868, /* Vector 346, coef 3(124) Vector + * 347, Coef 1(124) */ + -22394, /* Vector 347, coef 2(168), 3(134) */ + -31067, /* Vector 348, coef 1(134), 2(165) */ + 29063, /* Vector 348, coef 3(113) Vector + * 349, Coef 1(135) */ + -19860, /* Vector 349, coef 2(178), 3(108) */ + -31068, /* Vector 350, coef 1(134), 2(164) */ + -23941, /* Vector 350, coef 3(162) Vector + * 351, Coef 1(123) */ + -27734, /* Vector 351, coef 2(147), 3(170) */ + 32175, /* Vector 352, coef 1(125), 2(175) */ + 31357, /* Vector 352, coef 3(122) Vector + * 353, Coef 1(125) */ + -27518, /* Vector 353, coef 2(148), 3(130) */ + -31593, /* Vector 354, coef 1(132), 2(151) */ + 30592, /* Vector 354, coef 3(119) Vector + * 355, Coef 1(128) */ + -27536, /* Vector 355, coef 2(148), 3(112) */ + 32647, /* Vector 356, coef 1(127), 2(135) */ + 32636, /* Vector 356, coef 3(127) Vector + * 357, Coef 1(124) */ + -31627, /* Vector 357, coef 2(132), 3(117) */ + 29315, /* Vector 358, coef 1(114), 2(131) */ + 29057, /* Vector 358, coef 3(113) Vector + * 359, Coef 1(129) */ + -25220, /* Vector 359, coef 2(157), 3(124) */ + -32341, /* Vector 360, coef 1(129), 2(171) */ + 29566, /* Vector 360, coef 3(115) Vector + * 361, Coef 1(126) */ + -24202, /* Vector 361, coef 2(161), 3(118) */ + 31391, /* Vector 362, coef 1(122), 2(159) */ + 29047, /* Vector 362, coef 3(113) Vector + * 363, Coef 1(119) */ + -23934, /* Vector 363, coef 2(162), 3(130) */ + 29856, /* Vector 364, coef 1(116), 2(160) */ + 29807, /* Vector 364, coef 3(116) Vector + * 365, Coef 1(111) */ + -24721, /* Vector 365, coef 2(159), 3(111) */ + 28055, /* Vector 366, coef 1(109), 2(151) */ + 30849, /* Vector 366, coef 3(120) Vector + * 367, Coef 1(129) */ + -23959, /* Vector 367, coef 2(162), 3(105) */ + -32612, /* Vector 368, coef 1(128), 2(156) */ + 24696, /* Vector 368, coef 3( 96) Vector + * 369, Coef 1(120) */ + -27016, /* Vector 369, coef 2(150), 3(120) */ + 30607, /* Vector 370, coef 1(119), 2(143) */ + 29301, /* Vector 370, coef 3(114) Vector + * 371, Coef 1(117) */ + -26770, /* Vector 371, coef 2(151), 3(110) */ + 29072, /* Vector 372, coef 1(113), 2(144) */ + 27002, /* Vector 372, coef 3(105) Vector + * 373, Coef 1(122) */ + -25242, /* Vector 373, coef 2(157), 3(102) */ + 27536, /* Vector 374, coef 1(107), 2(144) */ + 25980, /* Vector 374, coef 3(101) Vector + * 375, Coef 1(124) */ + -22418, /* Vector 375, coef 2(168), 3(110) */ + 29084, /* Vector 376, coef 1(113), 2(156) */ + 25975, /* Vector 376, coef 3(101) Vector + * 377, Coef 1(119) */ + -27246, /* Vector 377, coef 2(149), 3(146) */ + 28818, /* Vector 378, coef 1(112), 2(146) */ + -29326, /* Vector 378, coef 3(141) Vector + * 379, Coef 1(114) */ + -28032, /* Vector 379, coef 2(146), 3(128) */ + 28299, /* Vector 380, coef 1(110), 2(139) */ + 31855, /* Vector 380, coef 3(124) Vector + * 381, Coef 1(111) */ + -32370, /* Vector 381, coef 2(129), 3(142) */ + -32117, /* Vector 382, coef 1(130), 2(139) */ + 25978, /* Vector 382, coef 3(101) Vector + * 383, Coef 1(122) */ + -29080, /* Vector 383, coef 2(142), 3(104) */ + 27029, /* Vector 384, coef 1(105), 2(149) */ + 29539, /* Vector 384, coef 3(115) Vector + * 385, Coef 1( 99) */ + -29600, /* Vector 385, coef 2(140), 3( 96) */ + 27813, /* Vector 386, coef 1(108), 2(165) */ + 30313, /* Vector 386, coef 3(118) Vector + * 387, Coef 1(105) */ + -23931, /* Vector 387, coef 2(162), 3(133) */ + 25753, /* Vector 388, coef 1(100), 2(153) */ + 32099, /* Vector 388, coef 3(125) Vector + * 389, Coef 1( 99) */ + -21640, /* Vector 389, coef 2(171), 3(120) */ + 24739, /* Vector 390, coef 1( 96), 2(163) */ + 31066, /* Vector 390, coef 3(121) Vector + * 391, Coef 1( 90) */ + -25483, /* Vector 391, coef 2(156), 3(117) */ + 25507, /* Vector 392, coef 1( 99), 2(163) */ + 28510, /* Vector 392, coef 3(111) Vector + * 393, Coef 1( 94) */ + -25492, /* Vector 393, coef 2(156), 3(108) */ + 23194, /* Vector 394, coef 1( 90), 2(154) */ + 27240, /* Vector 394, coef 3(106) Vector + * 395, Coef 1(104) */ + -24972, /* Vector 395, coef 2(158), 3(116) */ + 26525, /* Vector 396, coef 1(103), 2(157) */ + 27752, /* Vector 396, coef 3(108) Vector + * 397, Coef 1(104) */ + -26520, /* Vector 397, coef 2(152), 3(104) */ + 25234, /* Vector 398, coef 1( 98), 2(146) */ + 26465, /* Vector 398, coef 3(103) Vector + * 399, Coef 1( 97) */ + -27277, /* Vector 399, coef 2(149), 3(115) */ + 23440, /* Vector 400, coef 1( 91), 2(144) */ + 28507, /* Vector 400, coef 3(111) Vector + * 401, Coef 1( 91) */ + -28569, /* Vector 401, coef 2(144), 3(103) */ + 26529, /* Vector 402, coef 1(103), 2(161) */ + 25695, /* Vector 402, coef 3(100) Vector + * 403, Coef 1( 95) */ + -25503, /* Vector 403, coef 2(156), 3( 97) */ + 25245, /* Vector 404, coef 1( 98), 2(157) */ + 22617, /* Vector 404, coef 3( 88) Vector + * 405, Coef 1( 89) */ + -23698, /* Vector 405, coef 2(163), 3(110) */ + 28322, /* Vector 406, coef 1(110), 2(162) */ + 26474, /* Vector 406, coef 3(103) Vector + * 407, Coef 1(106) */ + -24994, /* Vector 407, coef 2(158), 3( 94) */ + 26264, /* Vector 408, coef 1(102), 2(152) */ + 22626, /* Vector 408, coef 3( 88) Vector + * 409, Coef 1( 98) */ + -27810, /* Vector 409, coef 2(147), 3( 94) */ + 28073, /* Vector 410, coef 1(109), 2(169) */ + 25450, /* Vector 410, coef 3( 99) Vector + * 411, Coef 1(106) */ + -22163, /* Vector 411, coef 2(169), 3(109) */ + 26023, /* Vector 412, coef 1(101), 2(167) */ + 25700, /* Vector 412, coef 3(100) Vector + * 413, Coef 1(100) */ + -20887, /* Vector 413, coef 2(174), 3(105) */ + 23959, /* Vector 414, coef 1( 93), 2(151) */ + 32341, /* Vector 414, coef 3(126) Vector + * 415, Coef 1( 85) */ + -28302, /* Vector 415, coef 2(145), 3(114) */ + 21910, /* Vector 416, coef 1( 85), 2(150) */ + 26710, /* Vector 416, coef 3(104) Vector + * 417, Coef 1( 86) */ + -29597, /* Vector 417, coef 2(140), 3( 99) */ + 23189, /* Vector 418, coef 1( 90), 2(149) */ + 21591, /* Vector 418, coef 3( 84) Vector + * 419, Coef 1( 87) */ + -27552, /* Vector 419, coef 2(148), 3( 96) */ + 21392, /* Vector 420, coef 1( 83), 2(144) */ + 23377, /* Vector 420, coef 3( 91) Vector + * 421, Coef 1( 81) */ + -29612, /* Vector 421, coef 2(140), 3( 84) */ + 21143, /* Vector 422, coef 1( 82), 2(151) */ + 28748, /* Vector 422, coef 3(112) Vector + * 423, Coef 1( 76) */ + -27542, /* Vector 423, coef 2(148), 3(106) */ + 19094, /* Vector 424, coef 1( 74), 2(150) */ + 25156, /* Vector 424, coef 3( 98) Vector + * 425, Coef 1( 68) */ + -28322, /* Vector 425, coef 2(145), 3( 94) */ + 19088, /* Vector 426, coef 1( 74), 2(144) */ + 30278, /* Vector 426, coef 3(118) Vector + * 427, Coef 1( 70) */ + -28307, /* Vector 427, coef 2(145), 3(109) */ + 16780, /* Vector 428, coef 1( 65), 2(140) */ + 28993, /* Vector 428, coef 3(113) Vector + * 429, Coef 1( 65) */ + -29338, /* Vector 429, coef 2(141), 3(102) */ + 15752, /* Vector 430, coef 1( 61), 2(136) */ + 25164, /* Vector 430, coef 3( 98) Vector + * 431, Coef 1( 76) */ + -28829, /* Vector 431, coef 2(143), 3( 99) */ + 18570, /* Vector 432, coef 1( 72), 2(138) */ + 23371, /* Vector 432, coef 3( 91) Vector + * 433, Coef 1( 75) */ + -28073, /* Vector 433, coef 2(146), 3( 87) */ + 16779, /* Vector 434, coef 1( 65), 2(139) */ + 21308, /* Vector 434, coef 3( 83) Vector + * 435, Coef 1( 60) */ + -31653, /* Vector 435, coef 2(132), 3( 91) */ + 15492, /* Vector 436, coef 1( 60), 2(132) */ + 21315, /* Vector 436, coef 3( 83) Vector + * 437, Coef 1( 67) */ + -32431, /* Vector 437, coef 2(129), 3( 81) */ + 23695, /* Vector 438, coef 1( 92), 2(143) */ + 22614, /* Vector 438, coef 3( 88) Vector + * 439, Coef 1( 86) */ + -30628, /* Vector 439, coef 2(136), 3( 92) */ + 20869, /* Vector 440, coef 1( 81), 2(133) */ + 22349, /* Vector 440, coef 3( 87) Vector + * 441, Coef 1( 77) */ + -29841, /* Vector 441, coef 2(139), 3(111) */ + 19846, /* Vector 442, coef 1( 77), 2(134) */ + 25670, /* Vector 442, coef 3(100) Vector + * 443, Coef 1( 70) */ + -31125, /* Vector 443, coef 2(134), 3(107) */ + 17284, /* Vector 444, coef 1( 67), 2(132) */ + 25673, /* Vector 444, coef 3(100) Vector + * 445, Coef 1( 73) */ + -32416, /* Vector 445, coef 2(129), 3( 96) */ + 17789, /* Vector 446, coef 1( 69), 2(125) */ + 23353, /* Vector 446, coef 3( 91) Vector + * 447, Coef 1( 57) */ + 32090, /* Vector 447, coef 2(125), 3( 90) */ + 31131, /* Vector 448, coef 1(121), 2(155) */ + 23923, /* Vector 448, coef 3( 93) Vector + * 449, Coef 1(115) */ + -26530, /* Vector 449, coef 2(152), 3( 94) */ + 28820, /* Vector 450, coef 1(112), 2(148) */ + 22667, /* Vector 450, coef 3( 88) Vector + * 451, Coef 1(139) */ + -13724, /* Vector 451, coef 2(202), 3(100) */ + -30527, /* Vector 452, coef 1(136), 2(193) */ + 24451, /* Vector 452, coef 3( 95) Vector + * 453, Coef 1(131) */ + -21399, /* Vector 453, coef 2(172), 3(105) */ + -31816, /* Vector 454, coef 1(131), 2(184) */ + 26240, /* Vector 454, coef 3(102) Vector + * 455, Coef 1(128) */ + -21408, /* Vector 455, coef 2(172), 3( 96) */ + -30770, /* Vector 456, coef 1(135), 2(206) */ + 23938, /* Vector 456, coef 3( 93) Vector + * 457, Coef 1(130) */ + -16805, /* Vector 457, coef 2(190), 3( 91) */ + -30780, /* Vector 458, coef 1(135), 2(196) */ + 19333, /* Vector 458, coef 3( 75) Vector + * 459, Coef 1(133) */ + -14522, /* Vector 459, coef 2(199), 3( 70) */ + 32705, /* Vector 460, coef 1(127), 2(193) */ + 21879, /* Vector 460, coef 3( 85) Vector + * 461, Coef 1(119) */ + -20397, /* Vector 461, coef 2(176), 3( 83) */ + 31414, /* Vector 462, coef 1(122), 2(182) */ + 18296, /* Vector 462, coef 3( 71) Vector + * 463, Coef 1(120) */ + -23705, /* Vector 463, coef 2(163), 3(103) */ + 31664, /* Vector 464, coef 1(123), 2(176) */ + 24952, /* Vector 464, coef 3( 97) Vector + * 465, Coef 1(120) */ + -22441, /* Vector 465, coef 2(168), 3( 87) */ + 28058, /* Vector 466, coef 1(109), 2(154) */ + 24434, /* Vector 466, coef 3( 95) Vector + * 467, Coef 1(114) */ + -22690, /* Vector 467, coef 2(167), 3( 94) */ + 29096, /* Vector 468, coef 1(113), 2(168) */ + 21869, /* Vector 468, coef 3( 85) Vector + * 469, Coef 1(109) */ + -26028, /* Vector 469, coef 2(154), 3( 84) */ + -32339, /* Vector 470, coef 1(129), 2(173) */ + 19328, /* Vector 470, coef 3( 75) Vector + * 471, Coef 1(128) */ + -17298, /* Vector 471, coef 2(188), 3(110) */ + 31922, /* Vector 472, coef 1(124), 2(178) */ + 28794, /* Vector 472, coef 3(112) Vector + * 473, Coef 1(122) */ + -19094, /* Vector 473, coef 2(181), 3(106) */ + 30384, /* Vector 474, coef 1(118), 2(176) */ + 25473, /* Vector 474, coef 3( 99) Vector + * 475, Coef 1(129) */ + -12961, /* Vector 475, coef 2(205), 3( 95) */ + -30286, /* Vector 476, coef 1(137), 2(178) */ + 23174, /* Vector 476, coef 3( 90) Vector + * 477, Coef 1(134) */ + -19115, /* Vector 477, coef 2(181), 3( 85) */ + 32679, /* Vector 478, coef 1(127), 2(167) */ + 22649, /* Vector 478, coef 3( 88) Vector + * 479, Coef 1(121) */ + -24493, /* Vector 479, coef 2(160), 3( 83) */ + 17023, /* Vector 480, coef 1( 66), 2(127) */ + 17465, /* Vector 480, coef 3( 68) Vector + * 481, Coef 1( 57) */ + 30533, /* Vector 481, coef 2(119), 3( 69) */ + 27029, /* Vector 482, coef 1(105), 2(149) */ + 19550, /* Vector 482, coef 3( 76) Vector + * 483, Coef 1( 94) */ + -28339, /* Vector 483, coef 2(145), 3( 77) */ + 22152, /* Vector 484, coef 1( 86), 2(136) */ + 19040, /* Vector 484, coef 3( 74) Vector + * 485, Coef 1( 96) */ + -29868, /* Vector 485, coef 2(139), 3( 84) */ + 22916, /* Vector 486, coef 1( 89), 2(132) */ + 20550, /* Vector 486, coef 3( 80) Vector + * 487, Coef 1( 70) */ + 31821, /* Vector 487, coef 2(124), 3( 77) */ + 25481, /* Vector 488, coef 1( 99), 2(137) */ + 18772, /* Vector 488, coef 3( 73) Vector + * 489, Coef 1( 84) */ + 32327, /* Vector 489, coef 2(126), 3( 71) */ + 20866, /* Vector 490, coef 1( 81), 2(130) */ + 16727, /* Vector 490, coef 3( 65) Vector + * 491, Coef 1( 87) */ + -31687, /* Vector 491, coef 2(132), 3( 57) */ + 27019, /* Vector 492, coef 1(105), 2(139) */ + 16227, /* Vector 492, coef 3( 63) Vector + * 493, Coef 1( 99) */ + -30664, /* Vector 493, coef 2(136), 3( 56) */ + 21370, /* Vector 494, coef 1( 83), 2(122) */ + 16220, /* Vector 494, coef 3( 63) Vector + * 495, Coef 1( 92) */ + 32307, /* Vector 495, coef 2(126), 3( 51) */ + 31126, /* Vector 496, coef 1(121), 2(150) */ + 20338, /* Vector 496, coef 3( 79) Vector + * 497, Coef 1(114) */ + -27828, /* Vector 497, coef 2(147), 3( 76) */ + 28556, /* Vector 498, coef 1(111), 2(140) */ + 17018, /* Vector 498, coef 3( 66) Vector + * 499, Coef 1(122) */ + -26311, /* Vector 499, coef 2(153), 3( 57) */ + 31896, /* Vector 500, coef 1(124), 2(152) */ + 11387, /* Vector 500, coef 3( 44) Vector + * 501, Coef 1(123) */ + -22971, /* Vector 501, coef 2(166), 3( 69) */ + 28310, /* Vector 502, coef 1(110), 2(150) */ + 18033, /* Vector 502, coef 3( 70) Vector + * 503, Coef 1(113) */ + -26820, /* Vector 503, coef 2(151), 3( 60) */ + -29504, /* Vector 504, coef 1(140), 2(192) */ + 16255, /* Vector 504, coef 3( 63) Vector + * 505, Coef 1(127) */ + -22736, /* Vector 505, coef 2(167), 3( 48) */ + -29236, /* Vector 506, coef 1(141), 2(204) */ + 14455, /* Vector 506, coef 3( 56) Vector + * 507, Coef 1(119) */ + -23758, /* Vector 507, coef 2(163), 3( 50) */ + 29346, /* Vector 508, coef 1(114), 2(162) */ + 17762, /* Vector 508, coef 3( 69) Vector + * 509, Coef 1( 98) */ + -28097, /* Vector 509, coef 2(146), 3( 63) */ + 25490, /* Vector 510, coef 1( 99), 2(146) */ + 13430, /* Vector 510, coef 3( 52) Vector + * 511, Coef 1(118) */ + -21968, /* Vector 511, coef 2(170), 3( 48) */ + -31811, /* Vector 512, coef 1(131), 2(189) */ + -32385, /* Vector 512, coef 3(129) Vector + * 513, Coef 1(127) */ + -17794, /* Vector 513, coef 2(186), 3(126) */ + 32473, /* Vector 514, coef 1(126), 2(217) */ + -26494, /* Vector 514, coef 3(152) Vector + * 515, Coef 1(130) */ + -13400, /* Vector 515, coef 2(203), 3(168) */ + 32208, /* Vector 516, coef 1(125), 2(208) */ + -22914, /* Vector 516, coef 3(166) Vector + * 517, Coef 1(126) */ + -13686, /* Vector 517, coef 2(202), 3(138) */ + 31947, /* Vector 518, coef 1(124), 2(203) */ + -26754, /* Vector 518, coef 3(151) Vector + * 519, Coef 1(126) */ + -17256, /* Vector 519, coef 2(188), 3(152) */ + 31447, /* Vector 520, coef 1(122), 2(215) */ + -28297, /* Vector 520, coef 3(145) Vector + * 521, Coef 1(119) */ + -10357, /* Vector 521, coef 2(215), 3(139) */ + 30671, /* Vector 522, coef 1(119), 2(207) */ + -23178, /* Vector 522, coef 3(165) Vector + * 523, Coef 1(118) */ + -13674, /* Vector 523, coef 2(202), 3(150) */ + 31683, /* Vector 524, coef 1(123), 2(195) */ + -30857, /* Vector 524, coef 3(135) Vector + * 525, Coef 1(119) */ + -14202, /* Vector 525, coef 2(200), 3(134) */ + 30908, /* Vector 526, coef 1(120), 2(188) */ + -21898, /* Vector 526, coef 3(170) Vector + * 527, Coef 1(118) */ + -19031, /* Vector 527, coef 2(181), 3(169) */ + 31665, /* Vector 528, coef 1(123), 2(177) */ + -26243, /* Vector 528, coef 3(153) Vector + * 529, Coef 1(125) */ + -23655, /* Vector 529, coef 2(163), 3(153) */ + 30125, /* Vector 530, coef 1(117), 2(173) */ + -28288, /* Vector 530, coef 3(145) Vector + * 531, Coef 1(128) */ + -18292, /* Vector 531, coef 2(184), 3(140) */ + 31667, /* Vector 532, coef 1(123), 2(179) */ + -29830, /* Vector 532, coef 3(139) Vector + * 533, Coef 1(122) */ + -18302, /* Vector 533, coef 2(184), 3(130) */ + 29882, /* Vector 534, coef 1(116), 2(186) */ + -29568, /* Vector 534, coef 3(140) Vector + * 535, Coef 1(128) */ + -9601, /* Vector 535, coef 2(218), 3(127) */ + 32215, /* Vector 536, coef 1(125), 2(215) */ + 30846, /* Vector 536, coef 3(120) Vector + * 537, Coef 1(126) */ + -15244, /* Vector 537, coef 2(196), 3(116) */ + 30676, /* Vector 538, coef 1(119), 2(212) */ + 31095, /* Vector 538, coef 3(121) Vector + * 539, Coef 1(119) */ + -9370, /* Vector 539, coef 2(219), 3(102) */ + 29405, /* Vector 540, coef 1(114), 2(221) */ + -31632, /* Vector 540, coef 3(132) Vector + * 541, Coef 1(112) */ + -10869, /* Vector 541, coef 2(213), 3(139) */ + 29129, /* Vector 542, coef 1(113), 2(201) */ + -28304, /* Vector 542, coef 3(145) Vector + * 543, Coef 1(112) */ + -15715, /* Vector 543, coef 2(194), 3(157) */ + 30635, /* Vector 544, coef 1(119), 2(171) */ + 30578, /* Vector 544, coef 3(119) Vector + * 545, Coef 1(114) */ + -22917, /* Vector 545, coef 2(166), 3(123) */ + 29364, /* Vector 546, coef 1(114), 2(180) */ + 31600, /* Vector 546, coef 3(123) Vector + * 547, Coef 1(112) */ + -20877, /* Vector 547, coef 2(174), 3(115) */ + 27819, /* Vector 548, coef 1(108), 2(171) */ + 31854, /* Vector 548, coef 3(124) Vector + * 549, Coef 1(110) */ + -23672, /* Vector 549, coef 2(163), 3(136) */ + 26288, /* Vector 550, coef 1(102), 2(176) */ + 31860, /* Vector 550, coef 3(124) Vector + * 551, Coef 1(116) */ + -22420, /* Vector 551, coef 2(168), 3(108) */ + 29893, /* Vector 552, coef 1(116), 2(197) */ + 32369, /* Vector 552, coef 3(126) Vector + * 553, Coef 1(113) */ + -16253, /* Vector 553, coef 2(192), 3(131) */ + 29350, /* Vector 554, coef 1(114), 2(166) */ + -28042, /* Vector 554, coef 3(146) Vector + * 555, Coef 1(118) */ + -20095, /* Vector 555, coef 2(177), 3(129) */ + 28854, /* Vector 556, coef 1(112), 2(182) */ + -29329, /* Vector 556, coef 3(141) Vector + * 557, Coef 1(111) */ + -19324, /* Vector 557, coef 2(180), 3(132) */ + 27571, /* Vector 558, coef 1(107), 2(179) */ + 32379, /* Vector 558, coef 3(126) Vector + * 559, Coef 1(123) */ + -14999, /* Vector 559, coef 2(197), 3(105) */ + 31172, /* Vector 560, coef 1(121), 2(196) */ + 30839, /* Vector 560, coef 3(120) Vector + * 561, Coef 1(119) */ + -17801, /* Vector 561, coef 2(186), 3(119) */ + 30650, /* Vector 562, coef 1(119), 2(186) */ + 26739, /* Vector 562, coef 3(104) Vector + * 563, Coef 1(115) */ + -18066, /* Vector 563, coef 2(185), 3(110) */ + 28849, /* Vector 564, coef 1(112), 2(177) */ + 26484, /* Vector 564, coef 3(103) Vector + * 565, Coef 1(116) */ + -15510, /* Vector 565, coef 2(195), 3(106) */ + 28861, /* Vector 566, coef 1(112), 2(189) */ + 25200, /* Vector 566, coef 3( 98) Vector + * 567, Coef 1(112) */ + -14226, /* Vector 567, coef 2(200), 3(110) */ + 28342, /* Vector 568, coef 1(110), 2(182) */ + 28009, /* Vector 568, coef 3(109) Vector + * 569, Coef 1(105) */ + -19604, /* Vector 569, coef 2(179), 3(108) */ + 29111, /* Vector 570, coef 1(113), 2(183) */ + 23406, /* Vector 570, coef 3( 91) Vector + * 571, Coef 1(110) */ + -16004, /* Vector 571, coef 2(193), 3(124) */ + 27581, /* Vector 572, coef 1(107), 2(189) */ + 30056, /* Vector 572, coef 3(117) Vector + * 573, Coef 1(104) */ + -16512, /* Vector 573, coef 2(191), 3(128) */ + 27847, /* Vector 574, coef 1(108), 2(199) */ + -28053, /* Vector 574, coef 3(146) Vector + * 575, Coef 1(107) */ + -15987, /* Vector 575, coef 2(193), 3(141) */ + 27844, /* Vector 576, coef 1(108), 2(196) */ + 27243, /* Vector 576, coef 3(106) Vector + * 577, Coef 1(107) */ + -16796, /* Vector 577, coef 2(190), 3(100) */ + 29143, /* Vector 578, coef 1(113), 2(215) */ + 29805, /* Vector 578, coef 3(116) Vector + * 579, Coef 1(109) */ + -12174, /* Vector 579, coef 2(208), 3(114) */ + 28127, /* Vector 580, coef 1(109), 2(223) */ + 32106, /* Vector 580, coef 3(125) Vector + * 581, Coef 1(106) */ + -7554, /* Vector 581, coef 2(226), 3(126) */ + 27343, /* Vector 582, coef 1(106), 2(207) */ + -32666, /* Vector 582, coef 3(128) Vector + * 583, Coef 1(102) */ + -10880, /* Vector 583, coef 2(213), 3(128) */ + 27608, /* Vector 584, coef 1(107), 2(216) */ + 28520, /* Vector 584, coef 3(111) Vector + * 585, Coef 1(104) */ + -11418, /* Vector 585, coef 2(211), 3(102) */ + 25817, /* Vector 586, coef 1(100), 2(217) */ + 29794, /* Vector 586, coef 3(116) Vector + * 587, Coef 1( 98) */ + -13449, /* Vector 587, coef 2(203), 3(119) */ + 26307, /* Vector 588, coef 1(102), 2(195) */ + 29026, /* Vector 588, coef 3(113) Vector + * 589, Coef 1( 98) */ + -16018, /* Vector 589, coef 2(193), 3(110) */ + 25037, /* Vector 590, coef 1( 97), 2(205) */ + 26464, /* Vector 590, coef 3(103) Vector + * 591, Coef 1( 96) */ + -13989, /* Vector 591, coef 2(201), 3( 91) */ + 26042, /* Vector 592, coef 1(101), 2(186) */ + 31076, /* Vector 592, coef 3(121) Vector + * 593, Coef 1(100) */ + -18831, /* Vector 593, coef 2(182), 3(113) */ + 24752, /* Vector 594, coef 1( 96), 2(176) */ + 27997, /* Vector 594, coef 3(109) Vector + * 595, Coef 1( 93) */ + -19848, /* Vector 595, coef 2(178), 3(120) */ + 24516, /* Vector 596, coef 1( 95), 2(196) */ + 30811, /* Vector 596, coef 3(120) Vector + * 597, Coef 1( 91) */ + -16780, /* Vector 597, coef 2(190), 3(116) */ + 23489, /* Vector 598, coef 1( 91), 2(193) */ + 27227, /* Vector 598, coef 3(106) Vector + * 599, Coef 1( 91) */ + -20629, /* Vector 599, coef 2(175), 3(107) */ + 25541, /* Vector 600, coef 1( 99), 2(197) */ + 22384, /* Vector 600, coef 3( 87) Vector + * 601, Coef 1(112) */ + -13481, /* Vector 601, coef 2(203), 3( 87) */ + 27338, /* Vector 602, coef 1(106), 2(202) */ + 22632, /* Vector 602, coef 3( 88) Vector + * 603, Coef 1(104) */ + -15513, /* Vector 603, coef 2(195), 3(103) */ + 25529, /* Vector 604, coef 1( 99), 2(185) */ + 24415, /* Vector 604, coef 3( 95) Vector + * 605, Coef 1( 95) */ + -17561, /* Vector 605, coef 2(187), 3(103) */ + 23990, /* Vector 606, coef 1( 93), 2(182) */ + 24679, /* Vector 606, coef 3( 96) Vector + * 607, Coef 1(103) */ + -11631, /* Vector 607, coef 2(210), 3(145) */ + 23486, /* Vector 608, coef 1( 91), 2(190) */ + 22363, /* Vector 608, coef 3( 87) Vector + * 609, Coef 1( 91) */ + -18859, /* Vector 609, coef 2(182), 3( 85) */ + 23222, /* Vector 610, coef 1( 90), 2(182) */ + 19798, /* Vector 610, coef 3( 77) Vector + * 611, Coef 1( 86) */ + -18849, /* Vector 611, coef 2(182), 3( 95) */ + 20402, /* Vector 612, coef 1( 79), 2(178) */ + 24399, /* Vector 612, coef 3( 95) Vector + * 613, Coef 1( 79) */ + -19625, /* Vector 613, coef 2(179), 3( 87) */ + 20145, /* Vector 614, coef 1( 78), 2(177) */ + 20303, /* Vector 614, coef 3( 79) Vector + * 615, Coef 1( 79) */ + -21672, /* Vector 615, coef 2(171), 3( 88) */ + 18597, /* Vector 616, coef 1( 72), 2(165) */ + 21831, /* Vector 616, coef 3( 85) Vector + * 617, Coef 1( 71) */ + -21677, /* Vector 617, coef 2(171), 3( 83) */ + 16806, /* Vector 618, coef 1( 65), 2(166) */ + 20033, /* Vector 618, coef 3( 78) Vector + * 619, Coef 1( 65) */ + -23983, /* Vector 619, coef 2(162), 3( 81) */ + 16799, /* Vector 620, coef 1( 65), 2(159) */ + 19260, /* Vector 620, coef 3( 75) Vector + * 621, Coef 1( 60) */ + -24252, /* Vector 621, coef 2(161), 3( 68) */ + 26822, /* Vector 622, coef 1(104), 2(198) */ + 18537, /* Vector 622, coef 3( 72) Vector + * 623, Coef 1(105) */ + -16066, /* Vector 623, coef 2(193), 3( 62) */ + 25272, /* Vector 624, coef 1( 98), 2(184) */ + 13654, /* Vector 624, coef 3( 53) Vector + * 625, Coef 1( 86) */ + -21694, /* Vector 625, coef 2(171), 3( 66) */ + 19876, /* Vector 626, coef 1( 77), 2(164) */ + 13925, /* Vector 626, coef 3( 54) Vector + * 627, Coef 1(101) */ + -12727, /* Vector 627, coef 2(206), 3( 73) */ + 25286, /* Vector 628, coef 1( 98), 2(198) */ + 15702, /* Vector 628, coef 3( 61) Vector + * 629, Coef 1( 86) */ + -18368, /* Vector 629, coef 2(184), 3( 64) */ + 21431, /* Vector 630, coef 1( 83), 2(183) */ + 13649, /* Vector 630, coef 3( 53) Vector + * 631, Coef 1( 81) */ + -20919, /* Vector 631, coef 2(174), 3( 73) */ + 19110, /* Vector 632, coef 1( 74), 2(166) */ + 17240, /* Vector 632, coef 3( 67) Vector + * 633, Coef 1( 88) */ + -19397, /* Vector 633, coef 2(180), 3( 59) */ + 22452, /* Vector 634, coef 1( 87), 2(180) */ + 11853, /* Vector 634, coef 3( 46) Vector + * 635, Coef 1( 77) */ + -23470, /* Vector 635, coef 2(164), 3( 82) */ + 17821, /* Vector 636, coef 1( 69), 2(157) */ + 20289, /* Vector 636, coef 3( 79) Vector + * 637, Coef 1( 65) */ + -27070, /* Vector 637, coef 2(150), 3( 66) */ + 19357, /* Vector 638, coef 1( 75), 2(157) */ + 9303, /* Vector 638, coef 3( 36) Vector + * 639, Coef 1( 87) */ + -16823, /* Vector 639, coef 2(190), 3( 73) */ + 20395, /* Vector 640, coef 1( 79), 2(171) */ + 25164, /* Vector 640, coef 3( 98) Vector + * 641, Coef 1( 76) */ + -19611, /* Vector 641, coef 2(179), 3(101) */ + 18603, /* Vector 642, coef 1( 72), 2(171) */ + 25411, /* Vector 642, coef 3( 99) Vector + * 643, Coef 1( 67) */ + -21667, /* Vector 643, coef 2(171), 3( 93) */ + 20646, /* Vector 644, coef 1( 80), 2(166) */ + 27466, /* Vector 644, coef 3(107) Vector + * 645, Coef 1( 74) */ + -24216, /* Vector 645, coef 2(161), 3(104) */ + 19361, /* Vector 646, coef 1( 75), 2(161) */ + 24902, /* Vector 646, coef 3( 97) Vector + * 647, Coef 1( 70) */ + -25252, /* Vector 647, coef 2(157), 3( 92) */ + 18340, /* Vector 648, coef 1( 71), 2(164) */ + 24896, /* Vector 648, coef 3( 97) Vector + * 649, Coef 1( 64) */ + -24226, /* Vector 649, coef 2(161), 3( 94) */ + 15771, /* Vector 650, coef 1( 61), 2(155) */ + 24893, /* Vector 650, coef 3( 97) Vector + * 651, Coef 1( 61) */ + -22427, /* Vector 651, coef 2(168), 3(101) */ + 15778, /* Vector 652, coef 1( 61), 2(162) */ + 26680, /* Vector 652, coef 3(104) Vector + * 653, Coef 1( 56) */ + -24476, /* Vector 653, coef 2(160), 3(100) */ + 13733, /* Vector 654, coef 1( 53), 2(165) */ + 25906, /* Vector 654, coef 3(101) Vector + * 655, Coef 1( 50) */ + -25499, /* Vector 655, coef 2(156), 3(101) */ + 15266, /* Vector 656, coef 1( 59), 2(162) */ + 23348, /* Vector 656, coef 3( 91) Vector + * 657, Coef 1( 52) */ + -25252, /* Vector 657, coef 2(157), 3( 92) */ + 13981, /* Vector 658, coef 1( 54), 2(157) */ + 21566, /* Vector 658, coef 3( 84) Vector + * 659, Coef 1( 62) */ + -27789, /* Vector 659, coef 2(147), 3(115) */ + 14997, /* Vector 660, coef 1( 58), 2(149) */ + 28485, /* Vector 660, coef 3(111) Vector + * 661, Coef 1( 69) */ + -26521, /* Vector 661, coef 2(152), 3(103) */ + 16541, /* Vector 662, coef 1( 64), 2(157) */ + 22337, /* Vector 662, coef 3( 87) Vector + * 663, Coef 1( 65) */ + -26250, /* Vector 663, coef 2(153), 3(118) */ + 17820, /* Vector 664, coef 1( 69), 2(156) */ + 28482, /* Vector 664, coef 3(111) Vector + * 665, Coef 1( 66) */ + -24211, /* Vector 665, coef 2(161), 3(109) */ + 16284, /* Vector 666, coef 1( 63), 2(156) */ + 26940, /* Vector 666, coef 3(105) Vector + * 667, Coef 1( 60) */ + -24205, /* Vector 667, coef 2(161), 3(115) */ + 14239, /* Vector 668, coef 1( 55), 2(159) */ + 28984, /* Vector 668, coef 3(113) Vector + * 669, Coef 1( 56) */ + -25747, /* Vector 669, coef 2(155), 3(109) */ + 12697, /* Vector 670, coef 1( 49), 2(153) */ + 28226, /* Vector 670, coef 3(110) Vector + * 671, Coef 1( 66) */ + -22669, /* Vector 671, coef 2(167), 3(115) */ + 13704, /* Vector 672, coef 1( 53), 2(136) */ + 25391, /* Vector 672, coef 3( 99) Vector + * 673, Coef 1( 47) */ + -31650, /* Vector 673, coef 2(132), 3( 94) */ + 12160, /* Vector 674, coef 1( 47), 2(128) */ + 22573, /* Vector 674, coef 3( 88) Vector + * 675, Coef 1( 45) */ + 32082, /* Vector 675, coef 2(125), 3( 82) */ + 12950, /* Vector 676, coef 1( 50), 2(150) */ + 18229, /* Vector 676, coef 3( 71) Vector + * 677, Coef 1( 53) */ + -26530, /* Vector 677, coef 2(152), 3( 94) */ + 11929, /* Vector 678, coef 1( 46), 2(153) */ + 20777, /* Vector 678, coef 3( 81) Vector + * 679, Coef 1( 41) */ + -26531, /* Vector 679, coef 2(152), 3( 93) */ + 10900, /* Vector 680, coef 1( 42), 2(148) */ + 22559, /* Vector 680, coef 3( 88) Vector + * 681, Coef 1( 31) */ + -28589, /* Vector 681, coef 2(144), 3( 83) */ + 14991, /* Vector 682, coef 1( 58), 2(143) */ + 27442, /* Vector 682, coef 3(107) Vector + * 683, Coef 1( 50) */ + -29848, /* Vector 683, coef 2(139), 3(104) */ + 13974, /* Vector 684, coef 1( 54), 2(150) */ + 26670, /* Vector 684, coef 3(104) Vector + * 685, Coef 1( 46) */ + -27547, /* Vector 685, coef 2(148), 3(101) */ + 10382, /* Vector 686, coef 1( 40), 2(142) */ + 26942, /* Vector 686, coef 3(105) Vector + * 687, Coef 1( 62) */ + -27546, /* Vector 687, coef 2(148), 3(102) */ + 16277, /* Vector 688, coef 1( 63), 2(149) */ + 24380, /* Vector 688, coef 3( 95) Vector + * 689, Coef 1( 60) */ + -27560, /* Vector 689, coef 2(148), 3( 88) */ + 13719, /* Vector 690, coef 1( 53), 2(151) */ + 21564, /* Vector 690, coef 3( 84) Vector + * 691, Coef 1( 60) */ + -27314, /* Vector 691, coef 2(149), 3( 78) */ + 12176, /* Vector 692, coef 1( 47), 2(144) */ + 20274, /* Vector 692, coef 3( 79) Vector + * 693, Coef 1( 50) */ + -28832, /* Vector 693, coef 2(143), 3( 96) */ + 10637, /* Vector 694, coef 1( 41), 2(141) */ + 23336, /* Vector 694, coef 3( 91) Vector + * 695, Coef 1( 40) */ + -30620, /* Vector 695, coef 2(136), 3(100) */ + 9092, /* Vector 696, coef 1( 35), 2(132) */ + 23612, /* Vector 696, coef 3( 92) Vector + * 697, Coef 1( 60) */ + -28840, /* Vector 697, coef 2(143), 3( 88) */ + 13193, /* Vector 698, coef 1( 51), 2(137) */ + 22575, /* Vector 698, coef 3( 88) Vector + * 699, Coef 1( 47) */ + -29615, /* Vector 699, coef 2(140), 3( 81) */ + 12425, /* Vector 700, coef 1( 48), 2(137) */ + 18241, /* Vector 700, coef 3( 71) Vector + * 701, Coef 1( 65) */ + -28085, /* Vector 701, coef 2(146), 3( 75) */ + 9620, /* Vector 702, coef 1( 37), 2(148) */ + 25888, /* Vector 702, coef 3(101) Vector + * 703, Coef 1( 32) */ + -29084, /* Vector 703, coef 2(142), 3(100) */ + 21665, /* Vector 704, coef 1( 84), 2(161) */ + 27983, /* Vector 704, coef 3(109) Vector + * 705, Coef 1( 79) */ + -25753, /* Vector 705, coef 2(155), 3(103) */ + 20371, /* Vector 706, coef 1( 79), 2(147) */ + 20585, /* Vector 706, coef 3( 80) Vector + * 707, Coef 1(105) */ + -18849, /* Vector 707, coef 2(182), 3( 95) */ + 26542, /* Vector 708, coef 1(103), 2(174) */ + 23399, /* Vector 708, coef 3( 91) Vector + * 709, Coef 1(103) */ + -21419, /* Vector 709, coef 2(172), 3( 85) */ + 22191, /* Vector 710, coef 1( 86), 2(175) */ + 25194, /* Vector 710, coef 3( 98) Vector + * 711, Coef 1(106) */ + -16561, /* Vector 711, coef 2(191), 3( 79) */ + 23973, /* Vector 712, coef 1( 93), 2(165) */ + 26209, /* Vector 712, coef 3(102) Vector + * 713, Coef 1( 97) */ + -21666, /* Vector 713, coef 2(171), 3( 94) */ + 23204, /* Vector 714, coef 1( 90), 2(164) */ + 22619, /* Vector 714, coef 3( 88) Vector + * 715, Coef 1( 91) */ + -21151, /* Vector 715, coef 2(173), 3( 97) */ + 21925, /* Vector 716, coef 1( 85), 2(165) */ + 24917, /* Vector 716, coef 3( 97) Vector + * 717, Coef 1( 85) */ + -21670, /* Vector 717, coef 2(171), 3( 90) */ + 21156, /* Vector 718, coef 1( 82), 2(164) */ + 22357, /* Vector 718, coef 3( 87) Vector + * 719, Coef 1( 85) */ + -25503, /* Vector 719, coef 2(156), 3( 97) */ + 21400, /* Vector 720, coef 1( 83), 2(152) */ + 23628, /* Vector 720, coef 3( 92) Vector + * 721, Coef 1( 76) */ + -25509, /* Vector 721, coef 2(156), 3( 91) */ + 18325, /* Vector 722, coef 1( 71), 2(149) */ + 21855, /* Vector 722, coef 3( 85) Vector + * 723, Coef 1( 95) */ + -20394, /* Vector 723, coef 2(176), 3( 86) */ + 23214, /* Vector 724, coef 1( 90), 2(174) */ + 20566, /* Vector 724, coef 3( 80) Vector + * 725, Coef 1( 86) */ + -23472, /* Vector 725, coef 2(164), 3( 80) */ + 21154, /* Vector 726, coef 1( 82), 2(162) */ + 18250, /* Vector 726, coef 3( 71) Vector + * 727, Coef 1( 74) */ + -25014, /* Vector 727, coef 2(158), 3( 74) */ + 19096, /* Vector 728, coef 1( 74), 2(152) */ + 20063, /* Vector 728, coef 3( 78) Vector + * 729, Coef 1( 95) */ + -21696, /* Vector 729, coef 2(171), 3( 64) */ + 22951, /* Vector 730, coef 1( 89), 2(167) */ + 13416, /* Vector 730, coef 3( 52) Vector + * 731, Coef 1(104) */ + -19376, /* Vector 731, coef 2(180), 3( 80) */ + 26031, /* Vector 732, coef 1(101), 2(175) */ + 18016, /* Vector 732, coef 3( 70) Vector + * 733, Coef 1( 96) */ + -23469, /* Vector 733, coef 2(164), 3( 83) */ + 22427, /* Vector 734, coef 1( 87), 2(155) */ + 21846, /* Vector 734, coef 3( 85) Vector + * 735, Coef 1( 86) */ + -25010, /* Vector 735, coef 2(158), 3( 78) */ + 20618, /* Vector 736, coef 1( 80), 2(138) */ + 19531, /* Vector 736, coef 3( 76) Vector + * 737, Coef 1( 75) */ + -29111, /* Vector 737, coef 2(142), 3( 73) */ + 16263, /* Vector 738, coef 1( 63), 2(135) */ + 19262, /* Vector 738, coef 3( 75) Vector + * 739, Coef 1( 62) */ + -31168, /* Vector 739, coef 2(134), 3( 64) */ + 16255, /* Vector 740, coef 1( 63), 2(127) */ + 19316, /* Vector 740, coef 3( 75) Vector + * 741, Coef 1(116) */ + -20925, /* Vector 741, coef 2(174), 3( 67) */ + 27561, /* Vector 742, coef 1(107), 2(169) */ + 22598, /* Vector 742, coef 3( 88) Vector + * 743, Coef 1( 70) */ + -28348, /* Vector 743, coef 2(145), 3( 68) */ + 16012, /* Vector 744, coef 1( 62), 2(140) */ + 15188, /* Vector 744, coef 3( 59) Vector + * 745, Coef 1( 84) */ + -24771, /* Vector 745, coef 2(159), 3( 61) */ + 31683, /* Vector 746, coef 1(123), 2(195) */ + 21876, /* Vector 746, coef 3( 85) Vector + * 747, Coef 1(116) */ + -18865, /* Vector 747, coef 2(182), 3( 79) */ + 29364, /* Vector 748, coef 1(114), 2(180) */ + 18294, /* Vector 748, coef 3( 71) Vector + * 749, Coef 1(118) */ + -13998, /* Vector 749, coef 2(201), 3( 82) */ + 29629, /* Vector 750, coef 1(115), 2(189) */ + 18004, /* Vector 750, coef 3( 70) Vector + * 751, Coef 1( 84) */ + -26040, /* Vector 751, coef 2(154), 3( 72) */ + 25252, /* Vector 752, coef 1( 98), 2(164) */ + 17491, /* Vector 752, coef 3( 68) Vector + * 753, Coef 1( 83) */ + -26818, /* Vector 753, coef 2(151), 3( 62) */ + 26022, /* Vector 754, coef 1(101), 2(166) */ + 14432, /* Vector 754, coef 3( 56) Vector + * 755, Coef 1( 96) */ + -23246, /* Vector 755, coef 2(165), 3( 50) */ + 26528, /* Vector 756, coef 1(103), 2(160) */ + 21095, /* Vector 756, coef 3( 82) Vector + * 757, Coef 1(103) */ + -25781, /* Vector 757, coef 2(155), 3( 75) */ + 26270, /* Vector 758, coef 1(102), 2(158) */ + 16743, /* Vector 758, coef 3( 65) Vector + * 759, Coef 1(103) */ + -25543, /* Vector 759, coef 2(156), 3( 57) */ + 24219, /* Vector 760, coef 1( 94), 2(155) */ + 19543, /* Vector 760, coef 3( 76) Vector + * 761, Coef 1( 87) */ + -27836, /* Vector 761, coef 2(147), 3( 68) */ + 20875, /* Vector 762, coef 1( 81), 2(139) */ + 16718, /* Vector 762, coef 3( 65) Vector + * 763, Coef 1( 78) */ + -30154, /* Vector 763, coef 2(138), 3( 54) */ + 30390, /* Vector 764, coef 1(118), 2(182) */ + 14443, /* Vector 764, coef 3( 56) Vector + * 765, Coef 1(107) */ + -23761, /* Vector 765, coef 2(163), 3( 47) */ + 21651, /* Vector 766, coef 1( 84), 2(147) */ + 13423, /* Vector 766, coef 3( 52) Vector + * 767, Coef 1(111) */ + -20949, /* Vector 767, coef 2(174), 3( 43) */ + 18842, /* Vector 768, coef 1( 73), 2(154) */ + -24767, /* Vector 768, coef 3(159) Vector + * 769, Coef 1( 65) */ + -24168, /* Vector 769, coef 2(161), 3(152) */ + 18065, /* Vector 770, coef 1( 70), 2(145) */ + -30909, /* Vector 770, coef 3(135) Vector + * 771, Coef 1( 67) */ + -27738, /* Vector 771, coef 2(147), 3(166) */ + 15262, /* Vector 772, coef 1( 59), 2(158) */ + -24002, /* Vector 772, coef 3(162) Vector + * 773, Coef 1( 62) */ + -30549, /* Vector 773, coef 2(136), 3(171) */ + 15494, /* Vector 774, coef 1( 60), 2(134) */ + -24513, /* Vector 774, coef 3(160) Vector + * 775, Coef 1( 63) */ + -26988, /* Vector 775, coef 2(150), 3(148) */ + 15247, /* Vector 776, coef 1( 59), 2(143) */ + -27850, /* Vector 776, coef 3(147) Vector + * 777, Coef 1( 54) */ + -26474, /* Vector 777, coef 2(152), 3(150) */ + 13459, /* Vector 778, coef 1( 52), 2(147) */ + -29375, /* Vector 778, coef 3(141) Vector + * 779, Coef 1( 65) */ + -26235, /* Vector 779, coef 2(153), 3(133) */ + 15257, /* Vector 780, coef 1( 59), 2(153) */ + -30153, /* Vector 780, coef 3(138) Vector + * 781, Coef 1( 55) */ + -26747, /* Vector 781, coef 2(151), 3(133) */ + 17042, /* Vector 782, coef 1( 66), 2(146) */ + 32572, /* Vector 782, coef 3(127) Vector + * 783, Coef 1( 60) */ + -28292, /* Vector 783, coef 2(145), 3(124) */ + 15497, /* Vector 784, coef 1( 60), 2(137) */ + 31799, /* Vector 784, coef 3(124) Vector + * 785, Coef 1( 55) */ + -30089, /* Vector 785, coef 2(138), 3(119) */ + 15755, /* Vector 786, coef 1( 61), 2(139) */ + -29896, /* Vector 786, coef 3(139) Vector + * 787, Coef 1( 56) */ + -30074, /* Vector 787, coef 2(138), 3(134) */ + 13197, /* Vector 788, coef 1( 51), 2(141) */ + -31944, /* Vector 788, coef 3(131) Vector + * 789, Coef 1( 56) */ + -24449, /* Vector 789, coef 2(160), 3(127) */ + 13978, /* Vector 790, coef 1( 54), 2(154) */ + 31537, /* Vector 790, coef 3(123) Vector + * 791, Coef 1( 49) */ + -25723, /* Vector 791, coef 2(155), 3(133) */ + 12170, /* Vector 792, coef 1( 47), 2(138) */ + -27319, /* Vector 792, coef 3(149) Vector + * 793, Coef 1( 73) */ + -30326, /* Vector 793, coef 2(137), 3(138) */ + 17031, /* Vector 794, coef 1( 66), 2(135) */ + -32709, /* Vector 794, coef 3(128) Vector + * 795, Coef 1( 59) */ + 32645, /* Vector 795, coef 2(127), 3(133) */ + 15772, /* Vector 796, coef 1( 61), 2(156) */ + 32055, /* Vector 796, coef 3(125) Vector + * 797, Coef 1( 55) */ + -24178, /* Vector 797, coef 2(161), 3(142) */ + 12444, /* Vector 798, coef 1( 48), 2(156) */ + -28114, /* Vector 798, coef 3(146) Vector + * 799, Coef 1( 46) */ + -27250, /* Vector 799, coef 2(149), 3(142) */ + 11664, /* Vector 800, coef 1( 45), 2(144) */ + 28200, /* Vector 800, coef 3(110) Vector + * 801, Coef 1( 40) */ + -30867, /* Vector 801, coef 2(135), 3(109) */ + 11659, /* Vector 802, coef 1( 45), 2(139) */ + -32203, /* Vector 802, coef 3(130) Vector + * 803, Coef 1( 53) */ + -28038, /* Vector 803, coef 2(146), 3(122) */ + 12687, /* Vector 804, coef 1( 49), 2(143) */ + 29998, /* Vector 804, coef 3(117) Vector + * 805, Coef 1( 46) */ + -30598, /* Vector 805, coef 2(136), 3(122) */ + 10884, /* Vector 806, coef 1( 42), 2(132) */ + 30253, /* Vector 806, coef 3(118) Vector + * 807, Coef 1( 45) */ + -26495, /* Vector 807, coef 2(152), 3(129) */ + 11929, /* Vector 808, coef 1( 46), 2(153) */ + 30501, /* Vector 808, coef 3(119) Vector + * 809, Coef 1( 37) */ + -26251, /* Vector 809, coef 2(153), 3(117) */ + 10399, /* Vector 810, coef 1( 40), 2(159) */ + 32290, /* Vector 810, coef 3(126) Vector + * 811, Coef 1( 34) */ + -25730, /* Vector 811, coef 2(155), 3(126) */ + 7323, /* Vector 812, coef 1( 28), 2(155) */ + 32027, /* Vector 812, coef 3(125) Vector + * 813, Coef 1( 27) */ + -25737, /* Vector 813, coef 2(155), 3(119) */ + 5525, /* Vector 814, coef 1( 21), 2(149) */ + 30503, /* Vector 814, coef 3(119) Vector + * 815, Coef 1( 39) */ + -30327, /* Vector 815, coef 2(137), 3(137) */ + 9358, /* Vector 816, coef 1( 36), 2(142) */ + -31969, /* Vector 816, coef 3(131) Vector + * 817, Coef 1( 31) */ + -30586, /* Vector 817, coef 2(136), 3(134) */ + 6032, /* Vector 818, coef 1( 23), 2(144) */ + -31211, /* Vector 818, coef 3(134) Vector + * 819, Coef 1( 21) */ + -31357, /* Vector 819, coef 2(133), 3(131) */ + 10643, /* Vector 820, coef 1( 41), 2(147) */ + 31782, /* Vector 820, coef 3(124) Vector + * 821, Coef 1( 38) */ + -28300, /* Vector 821, coef 2(145), 3(116) */ + 8594, /* Vector 822, coef 1( 33), 2(146) */ + 31515, /* Vector 822, coef 3(123) Vector + * 823, Coef 1( 27) */ + -28806, /* Vector 823, coef 2(143), 3(122) */ + 9352, /* Vector 824, coef 1( 36), 2(136) */ + 31004, /* Vector 824, coef 3(121) Vector + * 825, Coef 1( 28) */ + -32135, /* Vector 825, coef 2(130), 3(121) */ + 8587, /* Vector 826, coef 1( 33), 2(139) */ + 28955, /* Vector 826, coef 3(113) Vector + * 827, Coef 1( 27) */ + -29841, /* Vector 827, coef 2(139), 3(111) */ + 9622, /* Vector 828, coef 1( 37), 2(150) */ + 27930, /* Vector 828, coef 3(109) Vector + * 829, Coef 1( 26) */ + -26001, /* Vector 829, coef 2(154), 3(111) */ + 7571, /* Vector 830, coef 1( 29), 2(147) */ + 28185, /* Vector 830, coef 3(110) Vector + * 831, Coef 1( 25) */ + -27289, /* Vector 831, coef 2(149), 3(103) */ + 30040, /* Vector 832, coef 1(117), 2( 88) */ + -25811, /* Vector 832, coef 3(155) Vector + * 833, Coef 1( 45) */ + -30325, /* Vector 833, coef 2(137), 3(139) */ + 13704, /* Vector 834, coef 1( 53), 2(136) */ + -25802, /* Vector 834, coef 3(155) Vector + * 835, Coef 1( 54) */ + -32624, /* Vector 835, coef 2(128), 3(144) */ + 11898, /* Vector 836, coef 1( 46), 2(122) */ + -29142, /* Vector 836, coef 3(142) Vector + * 837, Coef 1( 42) */ + -32105, /* Vector 837, coef 2(130), 3(151) */ + 8830, /* Vector 838, coef 1( 34), 2(126) */ + -28640, /* Vector 838, coef 3(144) Vector + * 839, Coef 1( 32) */ + 31642, /* Vector 839, coef 2(123), 3(154) */ + 6017, /* Vector 840, coef 1( 23), 2(129) */ + -28122, /* Vector 840, coef 3(146) Vector + * 841, Coef 1( 38) */ + 28819, /* Vector 841, coef 2(112), 3(147) */ + 8553, /* Vector 842, coef 1( 33), 2(105) */ + -29403, /* Vector 842, coef 3(141) Vector + * 843, Coef 1( 37) */ + 29575, /* Vector 843, coef 2(115), 3(135) */ + 7031, /* Vector 844, coef 1( 27), 2(119) */ + -31161, /* Vector 844, coef 3(134) Vector + * 845, Coef 1( 71) */ + 30613, /* Vector 845, coef 2(119), 3(149) */ + 16753, /* Vector 846, coef 1( 65), 2(113) */ + -29896, /* Vector 846, coef 3(139) Vector + * 847, Coef 1( 56) */ + 29330, /* Vector 847, coef 2(114), 3(146) */ + 12651, /* Vector 848, coef 1( 49), 2(107) */ + -29655, /* Vector 848, coef 3(140) Vector + * 849, Coef 1( 41) */ + 27520, /* Vector 849, coef 2(107), 3(128) */ + 12131, /* Vector 850, coef 1( 47), 2( 99) */ + -31960, /* Vector 850, coef 3(131) Vector + * 851, Coef 1( 40) */ + 23935, /* Vector 851, coef 2( 93), 3(127) */ + 16482, /* Vector 852, coef 1( 64), 2( 98) */ + -23246, /* Vector 852, coef 3(165) Vector + * 853, Coef 1( 50) */ + 25238, /* Vector 853, coef 2( 98), 3(150) */ + 11868, /* Vector 854, coef 1( 46), 2( 92) */ + -29657, /* Vector 854, coef 3(140) Vector + * 855, Coef 1( 39) */ + 21392, /* Vector 855, coef 2( 83), 3(144) */ + 15943, /* Vector 856, coef 1( 62), 2( 71) */ + -30403, /* Vector 856, coef 3(137) Vector + * 857, Coef 1( 61) */ + 13715, /* Vector 857, coef 2( 53), 3(147) */ + 10111, /* Vector 858, coef 1( 39), 2(127) */ + -30940, /* Vector 858, coef 3(135) Vector + * 859, Coef 1( 36) */ + 31872, /* Vector 859, coef 2(124), 3(128) */ + 10368, /* Vector 860, coef 1( 40), 2(128) */ + -24027, /* Vector 860, coef 3(162) Vector + * 861, Coef 1( 37) */ + 28322, /* Vector 861, coef 2(110), 3(162) */ + 7786, /* Vector 862, coef 1( 30), 2(106) */ + -26076, /* Vector 862, coef 3(154) Vector + * 863, Coef 1( 36) */ + 22435, /* Vector 863, coef 2( 87), 3(163) */ + 16750, /* Vector 864, coef 1( 65), 2(110) */ + 27965, /* Vector 864, coef 3(109) Vector + * 865, Coef 1( 61) */ + -31122, /* Vector 865, coef 2(134), 3(110) */ + 13449, /* Vector 866, coef 1( 52), 2(137) */ + 28977, /* Vector 866, coef 3(113) Vector + * 867, Coef 1( 49) */ + -31891, /* Vector 867, coef 2(131), 3(109) */ + 8576, /* Vector 868, coef 1( 33), 2(128) */ + 27437, /* Vector 868, coef 3(107) Vector + * 869, Coef 1( 45) */ + 32616, /* Vector 869, coef 2(127), 3(104) */ + 11133, /* Vector 870, coef 1( 43), 2(125) */ + 24355, /* Vector 870, coef 3( 95) Vector + * 871, Coef 1( 35) */ + 30310, /* Vector 871, coef 2(118), 3(102) */ + 9846, /* Vector 872, coef 1( 38), 2(118) */ + 23608, /* Vector 872, coef 3( 92) Vector + * 873, Coef 1( 56) */ + 27263, /* Vector 873, coef 2(106), 3(127) */ + 15486, /* Vector 874, coef 1( 60), 2(126) */ + 31288, /* Vector 874, coef 3(122) Vector + * 875, Coef 1( 56) */ + 31861, /* Vector 875, coef 2(124), 3(117) */ + 13440, /* Vector 876, coef 1( 52), 2(128) */ + -32721, /* Vector 876, coef 3(128) Vector + * 877, Coef 1( 47) */ + 31362, /* Vector 877, coef 2(122), 3(130) */ + 11123, /* Vector 878, coef 1( 43), 2(115) */ + 32294, /* Vector 878, coef 3(126) Vector + * 879, Coef 1( 38) */ + 31605, /* Vector 879, coef 2(123), 3(117) */ + 8306, /* Vector 880, coef 1( 32), 2(114) */ + 29759, /* Vector 880, coef 3(116) Vector + * 881, Coef 1( 63) */ + 29820, /* Vector 881, coef 2(116), 3(124) */ + 14197, /* Vector 882, coef 1( 55), 2(117) */ + 31023, /* Vector 882, coef 3(121) Vector + * 883, Coef 1( 47) */ + 31349, /* Vector 883, coef 2(122), 3(117) */ + 12663, /* Vector 884, coef 1( 49), 2(119) */ + 27957, /* Vector 884, coef 3(109) Vector + * 885, Coef 1( 53) */ + 28020, /* Vector 885, coef 2(109), 3(116) */ + 11372, /* Vector 886, coef 1( 44), 2(108) */ + 29239, /* Vector 886, coef 3(114) Vector + * 887, Coef 1( 55) */ + 25717, /* Vector 887, coef 2(100), 3(117) */ + 10083, /* Vector 888, coef 1( 39), 2( 99) */ + 29500, /* Vector 888, coef 3(115) Vector + * 889, Coef 1( 60) */ + 30061, /* Vector 889, coef 2(117), 3(109) */ + 13940, /* Vector 890, coef 1( 54), 2(116) */ + 26417, /* Vector 890, coef 3(103) Vector + * 891, Coef 1( 49) */ + 27752, /* Vector 891, coef 2(108), 3(104) */ + 10090, /* Vector 892, coef 1( 39), 2(106) */ + 25402, /* Vector 892, coef 3( 99) Vector + * 893, Coef 1( 58) */ + 32618, /* Vector 893, coef 2(127), 3(106) */ + 14204, /* Vector 894, coef 1( 55), 2(124) */ + 25411, /* Vector 894, coef 3( 99) Vector + * 895, Coef 1( 67) */ + 31853, /* Vector 895, coef 2(124), 3(109) */ + 21613, /* Vector 896, coef 1( 84), 2(109) */ + -31144, /* Vector 896, coef 3(134) Vector + * 897, Coef 1( 88) */ + 28024, /* Vector 897, coef 2(109), 3(120) */ + 20343, /* Vector 898, coef 1( 79), 2(119) */ + 30278, /* Vector 898, coef 3(118) Vector + * 899, Coef 1( 70) */ + 30321, /* Vector 899, coef 2(118), 3(113) */ + 17773, /* Vector 900, coef 1( 69), 2(109) */ + 29804, /* Vector 900, coef 3(116) Vector + * 901, Coef 1(108) */ + 31340, /* Vector 901, coef 2(122), 3(108) */ + 19579, /* Vector 902, coef 1( 76), 2(123) */ + -31932, /* Vector 902, coef 3(131) Vector + * 903, Coef 1( 68) */ + 31617, /* Vector 903, coef 2(123), 3(129) */ + 18823, /* Vector 904, coef 1( 73), 2(135) */ + 30787, /* Vector 904, coef 3(120) Vector + * 905, Coef 1( 67) */ + -32140, /* Vector 905, coef 2(130), 3(116) */ + 25981, /* Vector 906, coef 1(101), 2(125) */ + -30359, /* Vector 906, coef 3(137) Vector + * 907, Coef 1(105) */ + 32380, /* Vector 907, coef 2(126), 3(124) */ + 23933, /* Vector 908, coef 1( 93), 2(125) */ + 31073, /* Vector 908, coef 3(121) Vector + * 909, Coef 1( 97) */ + -28793, /* Vector 909, coef 2(143), 3(135) */ + 25228, /* Vector 910, coef 1( 98), 2(140) */ + 31833, /* Vector 910, coef 3(124) Vector + * 911, Coef 1( 89) */ + -30087, /* Vector 911, coef 2(138), 3(121) */ + 21648, /* Vector 912, coef 1( 84), 2(144) */ + 32335, /* Vector 912, coef 3(126) Vector + * 913, Coef 1( 79) */ + -30080, /* Vector 913, coef 2(138), 3(128) */ + 21635, /* Vector 914, coef 1( 84), 2(131) */ + 32588, /* Vector 914, coef 3(127) Vector + * 915, Coef 1( 76) */ + 32631, /* Vector 915, coef 2(127), 3(119) */ + 20872, /* Vector 916, coef 1( 81), 2(136) */ + 27468, /* Vector 916, coef 3(107) Vector + * 917, Coef 1( 76) */ + -32658, /* Vector 917, coef 2(128), 3(110) */ + 19836, /* Vector 918, coef 1( 77), 2(124) */ + 26728, /* Vector 918, coef 3(104) Vector + * 919, Coef 1(104) */ + -29580, /* Vector 919, coef 2(140), 3(116) */ + 25740, /* Vector 920, coef 1(100), 2(140) */ + 27752, /* Vector 920, coef 3(108) Vector + * 921, Coef 1(104) */ + -31636, /* Vector 921, coef 2(132), 3(108) */ + 23686, /* Vector 922, coef 1( 92), 2(134) */ + 28759, /* Vector 922, coef 3(112) Vector + * 923, Coef 1( 87) */ + -32659, /* Vector 923, coef 2(128), 3(109) */ + 22661, /* Vector 924, coef 1( 88), 2(133) */ + 25693, /* Vector 924, coef 3(100) Vector + * 925, Coef 1( 93) */ + 30062, /* Vector 925, coef 2(117), 3(110) */ + 21620, /* Vector 926, coef 1( 84), 2(116) */ + 27475, /* Vector 926, coef 3(107) Vector + * 927, Coef 1( 83) */ + -29807, /* Vector 927, coef 2(139), 3(145) */ + 18543, /* Vector 928, coef 1( 72), 2(111) */ + 26676, /* Vector 928, coef 3(104) Vector + * 929, Coef 1( 52) */ + 25953, /* Vector 929, coef 2(101), 3( 97) */ + 25967, /* Vector 930, coef 1(101), 2(111) */ + 23656, /* Vector 930, coef 3( 92) Vector + * 931, Coef 1(104) */ + -29606, /* Vector 931, coef 2(140), 3( 90) */ + 26505, /* Vector 932, coef 1(103), 2(137) */ + 21581, /* Vector 932, coef 3( 84) Vector + * 933, Coef 1( 77) */ + 32596, /* Vector 933, coef 2(127), 3( 84) */ + 16756, /* Vector 934, coef 1( 65), 2(116) */ + 24122, /* Vector 934, coef 3( 94) Vector + * 935, Coef 1( 58) */ + 28762, /* Vector 935, coef 2(112), 3( 90) */ + 11631, /* Vector 936, coef 1( 45), 2(111) */ + 21046, /* Vector 936, coef 3( 82) Vector + * 937, Coef 1( 54) */ + 26451, /* Vector 937, coef 2(103), 3( 83) */ + 18297, /* Vector 938, coef 1( 71), 2(121) */ + 25141, /* Vector 938, coef 3( 98) Vector + * 939, Coef 1( 53) */ + 30294, /* Vector 939, coef 2(118), 3( 86) */ + 25726, /* Vector 940, coef 1(100), 2(126) */ + 26194, /* Vector 940, coef 3(102) Vector + * 941, Coef 1( 82) */ + 32606, /* Vector 941, coef 2(127), 3( 94) */ + 25476, /* Vector 942, coef 1( 99), 2(132) */ + 24413, /* Vector 942, coef 3( 95) Vector + * 943, Coef 1( 93) */ + 31837, /* Vector 943, coef 2(124), 3( 93) */ + 20855, /* Vector 944, coef 1( 81), 2(119) */ + 25167, /* Vector 944, coef 3( 98) Vector + * 945, Coef 1( 79) */ + 29529, /* Vector 945, coef 2(115), 3( 89) */ + 22654, /* Vector 946, coef 1( 88), 2(126) */ + 22618, /* Vector 946, coef 3( 88) Vector + * 947, Coef 1( 90) */ + 31824, /* Vector 947, coef 2(124), 3( 80) */ + 19318, /* Vector 948, coef 1( 75), 2(118) */ + 21059, /* Vector 948, coef 3( 82) Vector + * 949, Coef 1( 67) */ + 29512, /* Vector 949, coef 2(115), 3( 72) */ + 24434, /* Vector 950, coef 1( 95), 2(114) */ + 25684, /* Vector 950, coef 3(100) Vector + * 951, Coef 1( 84) */ + 28000, /* Vector 951, coef 2(109), 3( 96) */ + 19312, /* Vector 952, coef 1( 75), 2(112) */ + 24908, /* Vector 952, coef 3( 97) Vector + * 953, Coef 1( 76) */ + 27737, /* Vector 953, coef 2(108), 3( 89) */ + 22381, /* Vector 954, coef 1( 87), 2(109) */ + 22368, /* Vector 954, coef 3( 87) Vector + * 955, Coef 1( 96) */ + 30551, /* Vector 955, coef 2(119), 3( 87) */ + 22899, /* Vector 956, coef 1( 89), 2(115) */ + 20849, /* Vector 956, coef 3( 81) Vector + * 957, Coef 1(113) */ + -30367, /* Vector 957, coef 2(137), 3( 97) */ + 27261, /* Vector 958, coef 1(106), 2(125) */ + 23401, /* Vector 958, coef 3( 91) Vector + * 959, Coef 1(105) */ + -31918, /* Vector 959, coef 2(131), 3( 82) */ + -26696, /* Vector 960, coef 1(151), 2(184) */ + 28560, /* Vector 960, coef 3(111) Vector + * 961, Coef 1(144) */ + -18578, /* Vector 961, coef 2(183), 3(110) */ + -29263, /* Vector 962, coef 1(141), 2(177) */ + 27285, /* Vector 962, coef 3(106) Vector + * 963, Coef 1(149) */ + -23188, /* Vector 963, coef 2(165), 3(108) */ + -28516, /* Vector 964, coef 1(144), 2(156) */ + 26259, /* Vector 964, coef 3(102) Vector + * 965, Coef 1(147) */ + -21659, /* Vector 965, coef 2(171), 3(101) */ + -29279, /* Vector 966, coef 1(141), 2(161) */ + 24198, /* Vector 966, coef 3( 94) Vector + * 967, Coef 1(134) */ + -24981, /* Vector 967, coef 2(158), 3(107) */ + -30036, /* Vector 968, coef 1(138), 2(172) */ + 17832, /* Vector 968, coef 3( 69) Vector + * 969, Coef 1(168) */ + -11945, /* Vector 969, coef 2(209), 3( 87) */ + -24895, /* Vector 970, coef 1(158), 2(193) */ + 26522, /* Vector 970, coef 3(103) Vector + * 971, Coef 1(154) */ + -20130, /* Vector 971, coef 2(177), 3( 94) */ + -24913, /* Vector 972, coef 1(158), 2(175) */ + 19614, /* Vector 972, coef 3( 76) Vector + * 973, Coef 1(158) */ + -17591, /* Vector 973, coef 2(187), 3( 73) */ + -27229, /* Vector 974, coef 1(149), 2(163) */ + 21392, /* Vector 974, coef 3( 83) Vector + * 975, Coef 1(144) */ + -25527, /* Vector 975, coef 2(156), 3( 73) */ + -25151, /* Vector 976, coef 1(157), 2(193) */ + 18073, /* Vector 976, coef 3( 70) Vector + * 977, Coef 1(153) */ + -16305, /* Vector 977, coef 2(192), 3( 79) */ + -28506, /* Vector 978, coef 1(144), 2(166) */ + 19087, /* Vector 978, coef 3( 74) Vector + * 979, Coef 1(143) */ + -21432, /* Vector 979, coef 2(172), 3( 72) */ + -24877, /* Vector 980, coef 1(158), 2(211) */ + 27802, /* Vector 980, coef 3(108) Vector + * 981, Coef 1(154) */ + -14497, /* Vector 981, coef 2(199), 3( 95) */ + -27205, /* Vector 982, coef 1(149), 2(187) */ + 23954, /* Vector 982, coef 3( 93) Vector + * 983, Coef 1(146) */ + -16543, /* Vector 983, coef 2(191), 3( 97) */ + -27966, /* Vector 984, coef 1(146), 2(194) */ + 21132, /* Vector 984, coef 3( 82) Vector + * 985, Coef 1(140) */ + -18360, /* Vector 985, coef 2(184), 3( 72) */ + -29012, /* Vector 986, coef 1(142), 2(172) */ + 23689, /* Vector 986, coef 3( 92) Vector + * 987, Coef 1(137) */ + -22954, /* Vector 987, coef 2(166), 3( 86) */ + -32355, /* Vector 988, coef 1(129), 2(157) */ + 21642, /* Vector 988, coef 3( 84) Vector + * 989, Coef 1(138) */ + -27540, /* Vector 989, coef 2(148), 3(108) */ + -31080, /* Vector 990, coef 1(134), 2(152) */ + 23694, /* Vector 990, coef 3( 92) Vector + * 991, Coef 1(142) */ + -27555, /* Vector 991, coef 2(148), 3( 93) */ + 28018, /* Vector 992, coef 1(109), 2(114) */ + 20080, /* Vector 992, coef 3( 78) Vector + * 993, Coef 1(112) */ + -29880, /* Vector 993, coef 2(139), 3( 72) */ + -32615, /* Vector 994, coef 1(128), 2(153) */ + 15446, /* Vector 994, coef 3( 60) Vector + * 995, Coef 1( 86) */ + 26962, /* Vector 995, coef 2(105), 3( 82) */ + 24947, /* Vector 996, coef 1( 97), 2(115) */ + 19797, /* Vector 996, coef 3( 77) Vector + * 997, Coef 1( 85) */ + 27464, /* Vector 997, coef 2(107), 3( 72) */ + 27769, /* Vector 998, coef 1(108), 2(121) */ + 18795, /* Vector 998, coef 3( 73) Vector + * 999, Coef 1(107) */ + 31040, /* Vector 999, coef 2(121), 3( 64) */ + 25711, /* Vector 1000, coef 1(100), 2(111) */ + 18028, /* Vector 1000, coef 3( 70) Vector + * 1001, Coef 1(108) */ + 28991, /* Vector 1001, coef 2(113), 3( 63) */ + -32096, /* Vector 1002, coef 1(130), 2(160) */ + 19580, /* Vector 1002, coef 3( 76) Vector + * 1003, Coef 1(124) */ + -29351, /* Vector 1003, coef 2(141), 3( 89) */ + 29568, /* Vector 1004, coef 1(115), 2(128) */ + 24696, /* Vector 1004, coef 3( 96) Vector + * 1005, Coef 1(120) */ + -28071, /* Vector 1005, coef 2(146), 3( 89) */ + 29834, /* Vector 1006, coef 1(116), 2(138) */ + 21871, /* Vector 1006, coef 3( 85) Vector + * 1007, Coef 1(111) */ + -32181, /* Vector 1007, coef 2(130), 3( 75) */ + 23931, /* Vector 1008, coef 1( 93), 2(123) */ + 18782, /* Vector 1008, coef 3( 73) Vector + * 1009, Coef 1( 94) */ + 30789, /* Vector 1009, coef 2(120), 3( 69) */ + 27266, /* Vector 1010, coef 1(106), 2(130) */ + 15441, /* Vector 1010, coef 3( 60) Vector + * 1011, Coef 1( 81) */ + 28216, /* Vector 1011, coef 2(110), 3( 56) */ + -32124, /* Vector 1012, coef 1(130), 2(132) */ + 23681, /* Vector 1012, coef 3( 92) Vector + * 1013, Coef 1(129) */ + -30638, /* Vector 1013, coef 2(136), 3( 82) */ + 31363, /* Vector 1014, coef 1(122), 2(131) */ + 19846, /* Vector 1014, coef 3( 77) Vector + * 1015, Coef 1(134) */ + -30140, /* Vector 1015, coef 2(138), 3( 68) */ + -32366, /* Vector 1016, coef 1(129), 2(146) */ + 19322, /* Vector 1016, coef 3( 75) Vector + * 1017, Coef 1(122) */ + -29117, /* Vector 1017, coef 2(142), 3( 67) */ + -32626, /* Vector 1018, coef 1(128), 2(142) */ + 15236, /* Vector 1018, coef 3( 59) Vector + * 1019, Coef 1(132) */ + -26058, /* Vector 1019, coef 2(154), 3( 54) */ + -30574, /* Vector 1020, coef 1(136), 2(146) */ + 16251, /* Vector 1020, coef 3( 63) Vector + * 1021, Coef 1(123) */ + -32712, /* Vector 1021, coef 2(128), 3( 56) */ + -30057, /* Vector 1022, coef 1(138), 2(151) */ + 13200, /* Vector 1022, coef 3( 51) Vector + * 1023, Coef 1(144) */ + -25818, /* Vector 1023, coef 2(155), 3( 38) */ + 26266, /* Vector 1024, coef 1(102), 2(154) */ + -30353, /* Vector 1024, coef 3(137) Vector + * 1025, Coef 1(111) */ + -19040, /* Vector 1025, coef 2(181), 3(160) */ + 26812, /* Vector 1026, coef 1(104), 2(188) */ + -25241, /* Vector 1026, coef 3(157) Vector + * 1027, Coef 1(103) */ + -17776, /* Vector 1027, coef 2(186), 3(144) */ + 26291, /* Vector 1028, coef 1(102), 2(179) */ + -29854, /* Vector 1028, coef 3(139) Vector + * 1029, Coef 1( 98) */ + -13175, /* Vector 1029, coef 2(204), 3(137) */ + 25025, /* Vector 1030, coef 1( 97), 2(193) */ + -24480, /* Vector 1030, coef 3(160) Vector + * 1031, Coef 1( 96) */ + -17773, /* Vector 1031, coef 2(186), 3(147) */ + 25277, /* Vector 1032, coef 1( 98), 2(189) */ + -32161, /* Vector 1032, coef 3(130) Vector + * 1033, Coef 1( 95) */ + -18302, /* Vector 1033, coef 2(184), 3(130) */ + 23491, /* Vector 1034, coef 1( 91), 2(195) */ + -30119, /* Vector 1034, coef 3(138) Vector + * 1035, Coef 1( 89) */ + -18302, /* Vector 1035, coef 2(184), 3(130) */ + 28319, /* Vector 1036, coef 1(110), 2(159) */ + -23961, /* Vector 1036, coef 3(162) Vector + * 1037, Coef 1(103) */ + -21862, /* Vector 1037, coef 2(170), 3(154) */ + 25250, /* Vector 1038, coef 1( 98), 2(162) */ + -26279, /* Vector 1038, coef 3(153) Vector + * 1039, Coef 1( 89) */ + -15459, /* Vector 1039, coef 2(195), 3(157) */ + 22711, /* Vector 1040, coef 1( 88), 2(183) */ + -22446, /* Vector 1040, coef 3(168) Vector + * 1041, Coef 1( 82) */ + -13414, /* Vector 1041, coef 2(203), 3(154) */ + 21688, /* Vector 1042, coef 1( 84), 2(184) */ + -26529, /* Vector 1042, coef 3(152) Vector + * 1043, Coef 1( 95) */ + -24663, /* Vector 1043, coef 2(159), 3(169) */ + 23450, /* Vector 1044, coef 1( 91), 2(154) */ + -26276, /* Vector 1044, coef 3(153) Vector + * 1045, Coef 1( 92) */ + -30558, /* Vector 1045, coef 2(136), 3(162) */ + 20654, /* Vector 1046, coef 1( 80), 2(174) */ + -25762, /* Vector 1046, coef 3(155) Vector + * 1047, Coef 1( 94) */ + -21106, /* Vector 1047, coef 2(173), 3(142) */ + 23204, /* Vector 1048, coef 1( 90), 2(164) */ + -29093, /* Vector 1048, coef 3(142) Vector + * 1049, Coef 1( 91) */ + -21374, /* Vector 1049, coef 2(172), 3(130) */ + 21686, /* Vector 1050, coef 1( 84), 2(182) */ + -30115, /* Vector 1050, coef 3(138) Vector + * 1051, Coef 1( 93) */ + -11127, /* Vector 1051, coef 2(212), 3(137) */ + 22746, /* Vector 1052, coef 1( 88), 2(218) */ + -27814, /* Vector 1052, coef 3(147) Vector + * 1053, Coef 1( 90) */ + -12679, /* Vector 1053, coef 2(206), 3(121) */ + 22210, /* Vector 1054, coef 1( 86), 2(194) */ + -32174, /* Vector 1054, coef 3(130) Vector + * 1055, Coef 1( 82) */ + -13684, /* Vector 1055, coef 2(202), 3(140) */ + 19354, /* Vector 1056, coef 1( 75), 2(154) */ + 28505, /* Vector 1056, coef 3(111) Vector + * 1057, Coef 1( 89) */ + -21386, /* Vector 1057, coef 2(172), 3(118) */ + 21933, /* Vector 1058, coef 1( 85), 2(173) */ + 27725, /* Vector 1058, coef 3(108) Vector + * 1059, Coef 1( 77) */ + -19857, /* Vector 1059, coef 2(178), 3(111) */ + 19627, /* Vector 1060, coef 1( 76), 2(171) */ + 31048, /* Vector 1060, coef 3(121) Vector + * 1061, Coef 1( 72) */ + -21904, /* Vector 1061, coef 2(170), 3(112) */ + 22164, /* Vector 1062, coef 1( 86), 2(148) */ + -29361, /* Vector 1062, coef 3(141) Vector + * 1063, Coef 1( 79) */ + -27771, /* Vector 1063, coef 2(147), 3(133) */ + 18839, /* Vector 1064, coef 1( 73), 2(151) */ + -30141, /* Vector 1064, coef 3(138) Vector + * 1065, Coef 1( 67) */ + -24438, /* Vector 1065, coef 2(160), 3(138) */ + 20133, /* Vector 1066, coef 1( 78), 2(165) */ + -27055, /* Vector 1066, coef 3(150) Vector + * 1067, Coef 1( 81) */ + -23414, /* Vector 1067, coef 2(164), 3(138) */ + 19105, /* Vector 1068, coef 1( 74), 2(161) */ + -29611, /* Vector 1068, coef 3(140) Vector + * 1069, Coef 1( 85) */ + -22140, /* Vector 1069, coef 2(169), 3(132) */ + 20658, /* Vector 1070, coef 1( 80), 2(178) */ + -31661, /* Vector 1070, coef 3(132) Vector + * 1071, Coef 1( 83) */ + -20873, /* Vector 1071, coef 2(174), 3(119) */ + 20646, /* Vector 1072, coef 1( 80), 2(166) */ + 30297, /* Vector 1072, coef 3(118) Vector + * 1073, Coef 1( 89) */ + -23938, /* Vector 1073, coef 2(162), 3(126) */ + 21658, /* Vector 1074, coef 1( 84), 2(154) */ + 32595, /* Vector 1074, coef 3(127) Vector + * 1075, Coef 1( 83) */ + -24714, /* Vector 1075, coef 2(159), 3(118) */ + 19864, /* Vector 1076, coef 1( 77), 2(152) */ + 31054, /* Vector 1076, coef 3(121) Vector + * 1077, Coef 1( 78) */ + -24191, /* Vector 1077, coef 2(161), 3(129) */ + 18846, /* Vector 1078, coef 1( 73), 2(158) */ + 32070, /* Vector 1078, coef 3(125) Vector + * 1079, Coef 1( 70) */ + -25988, /* Vector 1079, coef 2(154), 3(124) */ + 19373, /* Vector 1080, coef 1( 75), 2(173) */ + -29625, /* Vector 1080, coef 3(140) Vector + * 1081, Coef 1( 71) */ + -19576, /* Vector 1081, coef 2(179), 3(136) */ + 18346, /* Vector 1082, coef 1( 71), 2(170) */ + -30651, /* Vector 1082, coef 3(136) Vector + * 1083, Coef 1( 69) */ + -22911, /* Vector 1083, coef 2(166), 3(129) */ + 16803, /* Vector 1084, coef 1( 65), 2(163) */ + 31563, /* Vector 1084, coef 3(123) Vector + * 1085, Coef 1( 75) */ + -23951, /* Vector 1085, coef 2(162), 3(113) */ + 19638, /* Vector 1086, coef 1( 76), 2(182) */ + 31812, /* Vector 1086, coef 3(124) Vector + * 1087, Coef 1( 68) */ + -20615, /* Vector 1087, coef 2(175), 3(121) */ + 19109, /* Vector 1088, coef 1( 74), 2(165) */ + -21947, /* Vector 1088, coef 3(170) Vector + * 1089, Coef 1( 69) */ + -22121, /* Vector 1089, coef 2(169), 3(151) */ + 16559, /* Vector 1090, coef 1( 64), 2(175) */ + -31929, /* Vector 1090, coef 3(131) Vector + * 1091, Coef 1( 71) */ + -14436, /* Vector 1091, coef 2(199), 3(156) */ + 18623, /* Vector 1092, coef 1( 72), 2(191) */ + -28092, /* Vector 1092, coef 3(146) Vector + * 1093, Coef 1( 68) */ + -12653, /* Vector 1093, coef 2(206), 3(147) */ + 16842, /* Vector 1094, coef 1( 65), 2(202) */ + -28606, /* Vector 1094, coef 3(144) Vector + * 1095, Coef 1( 66) */ + -15724, /* Vector 1095, coef 2(194), 3(148) */ + 16825, /* Vector 1096, coef 1( 65), 2(185) */ + -27836, /* Vector 1096, coef 3(147) Vector + * 1097, Coef 1( 68) */ + -18806, /* Vector 1097, coef 2(182), 3(138) */ + 16563, /* Vector 1098, coef 1( 64), 2(179) */ + -29889, /* Vector 1098, coef 3(139) Vector + * 1099, Coef 1( 63) */ + -17274, /* Vector 1099, coef 2(188), 3(134) */ + 15289, /* Vector 1100, coef 1( 59), 2(185) */ + -32192, /* Vector 1100, coef 3(130) Vector + * 1101, Coef 1( 64) */ + -15971, /* Vector 1101, coef 2(193), 3(157) */ + 15814, /* Vector 1102, coef 1( 61), 2(198) */ + -27330, /* Vector 1102, coef 3(149) Vector + * 1103, Coef 1( 62) */ + -18793, /* Vector 1103, coef 2(182), 3(151) */ + 15292, /* Vector 1104, coef 1( 59), 2(188) */ + -28098, /* Vector 1104, coef 3(146) Vector + * 1105, Coef 1( 62) */ + -17496, /* Vector 1105, coef 2(187), 3(168) */ + 15030, /* Vector 1106, coef 1( 58), 2(182) */ + -24008, /* Vector 1106, coef 3(162) Vector + * 1107, Coef 1( 56) */ + -16485, /* Vector 1107, coef 2(191), 3(155) */ + 14797, /* Vector 1108, coef 1( 57), 2(205) */ + -28617, /* Vector 1108, coef 3(144) Vector + * 1109, Coef 1( 55) */ + -13940, /* Vector 1109, coef 2(201), 3(140) */ + 13780, /* Vector 1110, coef 1( 53), 2(212) */ + -26829, /* Vector 1110, coef 3(151) Vector + * 1111, Coef 1( 51) */ + -13677, /* Vector 1111, coef 2(202), 3(147) */ + 14013, /* Vector 1112, coef 1( 54), 2(189) */ + -29634, /* Vector 1112, coef 3(140) Vector + * 1113, Coef 1( 62) */ + -20850, /* Vector 1113, coef 2(174), 3(142) */ + 14771, /* Vector 1114, coef 1( 57), 2(179) */ + -29641, /* Vector 1114, coef 3(140) Vector + * 1115, Coef 1( 55) */ + -16720, /* Vector 1115, coef 2(190), 3(176) */ + 13502, /* Vector 1116, coef 1( 52), 2(190) */ + -23233, /* Vector 1116, coef 3(165) Vector + * 1117, Coef 1( 63) */ + -13181, /* Vector 1117, coef 2(204), 3(131) */ + 15559, /* Vector 1118, coef 1( 60), 2(199) */ + -31175, /* Vector 1118, coef 3(134) Vector + * 1119, Coef 1( 57) */ + -15743, /* Vector 1119, coef 2(194), 3(129) */ + 12705, /* Vector 1120, coef 1( 49), 2(161) */ + 31286, /* Vector 1120, coef 3(122) Vector + * 1121, Coef 1( 54) */ + -19045, /* Vector 1121, coef 2(181), 3(155) */ + 13239, /* Vector 1122, coef 1( 51), 2(183) */ + -28366, /* Vector 1122, coef 3(145) Vector + * 1123, Coef 1( 50) */ + -15225, /* Vector 1123, coef 2(196), 3(135) */ + 12476, /* Vector 1124, coef 1( 48), 2(188) */ + -30662, /* Vector 1124, coef 3(136) Vector + * 1125, Coef 1( 58) */ + -22902, /* Vector 1125, coef 2(166), 3(138) */ + 15273, /* Vector 1126, coef 1( 59), 2(169) */ + -31691, /* Vector 1126, coef 3(132) Vector + * 1127, Coef 1( 53) */ + -22401, /* Vector 1127, coef 2(168), 3(127) */ + 13481, /* Vector 1128, coef 1( 52), 2(169) */ + -30672, /* Vector 1128, coef 3(136) Vector + * 1129, Coef 1( 48) */ + -23414, /* Vector 1129, coef 2(164), 3(138) */ + 13748, /* Vector 1130, coef 1( 53), 2(180) */ + -31437, /* Vector 1130, coef 3(133) Vector + * 1131, Coef 1( 51) */ + -18818, /* Vector 1131, coef 2(182), 3(126) */ + 12465, /* Vector 1132, coef 1( 48), 2(177) */ + -30930, /* Vector 1132, coef 3(135) Vector + * 1133, Coef 1( 46) */ + -20349, /* Vector 1133, coef 2(176), 3(131) */ + 12197, /* Vector 1134, coef 1( 47), 2(165) */ + -32213, /* Vector 1134, coef 3(130) Vector + * 1135, Coef 1( 43) */ + -23418, /* Vector 1135, coef 2(164), 3(134) */ + 11432, /* Vector 1136, coef 1( 44), 2(168) */ + 32046, /* Vector 1136, coef 3(125) Vector + * 1137, Coef 1( 46) */ + -15981, /* Vector 1137, coef 2(193), 3(147) */ + 11448, /* Vector 1138, coef 1( 44), 2(184) */ + -29142, /* Vector 1138, coef 3(142) Vector + * 1139, Coef 1( 42) */ + -19828, /* Vector 1139, coef 2(178), 3(140) */ + 10172, /* Vector 1140, coef 1( 39), 2(188) */ + -30933, /* Vector 1140, coef 3(135) Vector + * 1141, Coef 1( 43) */ + -18814, /* Vector 1141, coef 2(182), 3(130) */ + 10163, /* Vector 1142, coef 1( 39), 2(179) */ + -32472, /* Vector 1142, coef 3(129) Vector + * 1143, Coef 1( 40) */ + -21628, /* Vector 1143, coef 2(171), 3(132) */ + 12461, /* Vector 1144, coef 1( 48), 2(173) */ + 31529, /* Vector 1144, coef 3(123) Vector + * 1145, Coef 1( 41) */ + -20105, /* Vector 1145, coef 2(177), 3(119) */ + 13474, /* Vector 1146, coef 1( 52), 2(162) */ + -25808, /* Vector 1146, coef 3(155) Vector + * 1147, Coef 1( 48) */ + -21358, /* Vector 1147, coef 2(172), 3(146) */ + 11692, /* Vector 1148, coef 1( 45), 2(172) */ + -27082, /* Vector 1148, coef 3(150) Vector + * 1149, Coef 1( 54) */ + -16258, /* Vector 1149, coef 2(192), 3(126) */ + 12218, /* Vector 1150, coef 1( 47), 2(186) */ + 32299, /* Vector 1150, coef 3(126) Vector + * 1151, Coef 1( 43) */ + -17284, /* Vector 1151, coef 2(188), 3(124) */ + 22202, /* Vector 1152, coef 1( 86), 2(186) */ + 27217, /* Vector 1152, coef 3(106) Vector + * 1153, Coef 1( 81) */ + -18574, /* Vector 1153, coef 2(183), 3(114) */ + 19416, /* Vector 1154, coef 1( 75), 2(216) */ + -24759, /* Vector 1154, coef 3(159) Vector + * 1155, Coef 1( 73) */ + -11373, /* Vector 1155, coef 2(211), 3(147) */ + 18638, /* Vector 1156, coef 1( 72), 2(206) */ + 32583, /* Vector 1156, coef 3(127) Vector + * 1157, Coef 1( 71) */ + -14980, /* Vector 1157, coef 2(197), 3(124) */ + 17613, /* Vector 1158, coef 1( 68), 2(205) */ + -32169, /* Vector 1158, coef 3(130) Vector + * 1159, Coef 1( 87) */ + -8332, /* Vector 1159, coef 2(223), 3(116) */ + 21721, /* Vector 1160, coef 1( 84), 2(217) */ + 32088, /* Vector 1160, coef 3(125) Vector + * 1161, Coef 1( 88) */ + -14221, /* Vector 1161, coef 2(200), 3(115) */ + 21948, /* Vector 1162, coef 1( 85), 2(188) */ + 30805, /* Vector 1162, coef 3(120) Vector + * 1163, Coef 1( 85) */ + -12927, /* Vector 1163, coef 2(205), 3(129) */ + 20699, /* Vector 1164, coef 1( 80), 2(219) */ + 30797, /* Vector 1164, coef 3(120) Vector + * 1165, Coef 1( 77) */ + -9855, /* Vector 1165, coef 2(217), 3(129) */ + 20684, /* Vector 1166, coef 1( 80), 2(204) */ + -31665, /* Vector 1166, coef 3(132) Vector + * 1167, Coef 1( 79) */ + -14211, /* Vector 1167, coef 2(200), 3(125) */ + 19653, /* Vector 1168, coef 1( 76), 2(197) */ + -29878, /* Vector 1168, coef 3(139) Vector + * 1169, Coef 1( 74) */ + -16762, /* Vector 1169, coef 2(190), 3(134) */ + 21704, /* Vector 1170, coef 1( 84), 2(200) */ + 27472, /* Vector 1170, coef 3(107) Vector + * 1171, Coef 1( 80) */ + -14486, /* Vector 1171, coef 2(199), 3(106) */ + 20924, /* Vector 1172, coef 1( 81), 2(188) */ + 26958, /* Vector 1172, coef 3(105) Vector + * 1173, Coef 1( 78) */ + -16797, /* Vector 1173, coef 2(190), 3( 99) */ + 20413, /* Vector 1174, coef 1( 79), 2(189) */ + 31816, /* Vector 1174, coef 3(124) Vector + * 1175, Coef 1( 72) */ + -18569, /* Vector 1175, coef 2(183), 3(119) */ + 19658, /* Vector 1176, coef 1( 76), 2(202) */ + 28744, /* Vector 1176, coef 3(112) Vector + * 1177, Coef 1( 72) */ + -14228, /* Vector 1177, coef 2(200), 3(108) */ + 18880, /* Vector 1178, coef 1( 73), 2(192) */ + 25932, /* Vector 1178, coef 3(101) Vector + * 1179, Coef 1( 76) */ + -8341, /* Vector 1179, coef 2(223), 3(107) */ + 19169, /* Vector 1180, coef 1( 74), 2(225) */ + 28999, /* Vector 1180, coef 3(113) Vector + * 1181, Coef 1( 71) */ + -11416, /* Vector 1181, coef 2(211), 3(104) */ + 20690, /* Vector 1182, coef 1( 80), 2(210) */ + 25418, /* Vector 1182, coef 3( 99) Vector + * 1183, Coef 1( 74) */ + -11428, /* Vector 1183, coef 2(211), 3( 92) */ + 18355, /* Vector 1184, coef 1( 71), 2(179) */ + 26689, /* Vector 1184, coef 3(104) Vector + * 1185, Coef 1( 65) */ + -21398, /* Vector 1185, coef 2(172), 3(106) */ + 16042, /* Vector 1186, coef 1( 62), 2(170) */ + -32702, /* Vector 1186, coef 3(128) Vector + * 1187, Coef 1( 66) */ + -14977, /* Vector 1187, coef 2(197), 3(127) */ + 18360, /* Vector 1188, coef 1( 71), 2(184) */ + 28483, /* Vector 1188, coef 3(111) Vector + * 1189, Coef 1( 67) */ + -17564, /* Vector 1189, coef 2(187), 3(100) */ + 17089, /* Vector 1190, coef 1( 66), 2(193) */ + 26942, /* Vector 1190, coef 3(105) Vector + * 1191, Coef 1( 62) */ + -17814, /* Vector 1191, coef 2(186), 3(106) */ + 15803, /* Vector 1192, coef 1( 61), 2(187) */ + 24888, /* Vector 1192, coef 3( 97) Vector + * 1193, Coef 1( 56) */ + -19101, /* Vector 1193, coef 2(181), 3( 99) */ + 17595, /* Vector 1194, coef 1( 68), 2(187) */ + -32447, /* Vector 1194, coef 3(129) Vector + * 1195, Coef 1( 65) */ + -18308, /* Vector 1195, coef 2(184), 3(124) */ + 17597, /* Vector 1196, coef 1( 68), 2(189) */ + 28992, /* Vector 1196, coef 3(113) Vector + * 1197, Coef 1( 64) */ + -18318, /* Vector 1197, coef 2(184), 3(114) */ + 16066, /* Vector 1198, coef 1( 62), 2(194) */ + 30780, /* Vector 1198, coef 3(120) Vector + * 1199, Coef 1( 60) */ + -18055, /* Vector 1199, coef 2(185), 3(121) */ + 14519, /* Vector 1200, coef 1( 56), 2(183) */ + 30270, /* Vector 1200, coef 3(118) Vector + * 1201, Coef 1( 62) */ + -21388, /* Vector 1201, coef 2(172), 3(116) */ + 14761, /* Vector 1202, coef 1( 57), 2(169) */ + 28221, /* Vector 1202, coef 3(110) Vector + * 1203, Coef 1( 61) */ + -19861, /* Vector 1203, coef 2(178), 3(107) */ + 14514, /* Vector 1204, coef 1( 56), 2(178) */ + 28214, /* Vector 1204, coef 3(110) Vector + * 1205, Coef 1( 54) */ + -21398, /* Vector 1205, coef 2(172), 3(106) */ + 16067, /* Vector 1206, coef 1( 62), 2(195) */ + 26681, /* Vector 1206, coef 3(104) Vector + * 1207, Coef 1( 57) */ + -16528, /* Vector 1207, coef 2(191), 3(112) */ + 13757, /* Vector 1208, coef 1( 53), 2(189) */ + 29748, /* Vector 1208, coef 3(116) Vector + * 1209, Coef 1( 52) */ + -18833, /* Vector 1209, coef 2(182), 3(111) */ + 14267, /* Vector 1210, coef 1( 55), 2(187) */ + 25923, /* Vector 1210, coef 3(101) Vector + * 1211, Coef 1( 67) */ + -19360, /* Vector 1211, coef 2(180), 3( 96) */ + 14510, /* Vector 1212, coef 1( 56), 2(174) */ + 31028, /* Vector 1212, coef 3(121) Vector + * 1213, Coef 1( 52) */ + -21132, /* Vector 1213, coef 2(173), 3(116) */ + 17098, /* Vector 1214, coef 1( 66), 2(202) */ + 28995, /* Vector 1214, coef 3(113) Vector + * 1215, Coef 1( 67) */ + -15014, /* Vector 1215, coef 2(197), 3( 90) */ + 13753, /* Vector 1216, coef 1( 53), 2(185) */ + 23857, /* Vector 1216, coef 3( 93) Vector + * 1217, Coef 1( 49) */ + -19615, /* Vector 1217, coef 2(179), 3( 97) */ + 11698, /* Vector 1218, coef 1( 45), 2(178) */ + 23616, /* Vector 1218, coef 3( 92) Vector + * 1219, Coef 1( 64) */ + -19366, /* Vector 1219, coef 2(180), 3( 90) */ + 17326, /* Vector 1220, coef 1( 67), 2(174) */ + 22334, /* Vector 1220, coef 3( 87) Vector + * 1221, Coef 1( 62) */ + -21677, /* Vector 1221, coef 2(171), 3( 83) */ + 15015, /* Vector 1222, coef 1( 58), 2(167) */ + 23092, /* Vector 1222, coef 3( 90) Vector + * 1223, Coef 1( 52) */ + -23210, /* Vector 1223, coef 2(165), 3( 86) */ + 18111, /* Vector 1224, coef 1( 70), 2(191) */ + 22591, /* Vector 1224, coef 3( 88) Vector + * 1225, Coef 1( 63) */ + -17835, /* Vector 1225, coef 2(186), 3( 85) */ + 14771, /* Vector 1226, coef 1( 57), 2(179) */ + 22836, /* Vector 1226, coef 3( 89) Vector + * 1227, Coef 1( 52) */ + -19882, /* Vector 1227, coef 2(178), 3( 86) */ + 15288, /* Vector 1228, coef 1( 59), 2(184) */ + 19765, /* Vector 1228, coef 3( 77) Vector + * 1229, Coef 1( 53) */ + -19896, /* Vector 1229, coef 2(178), 3( 72) */ + 11950, /* Vector 1230, coef 1( 46), 2(174) */ + 20778, /* Vector 1230, coef 3( 81) Vector + * 1231, Coef 1( 42) */ + -21178, /* Vector 1231, coef 2(173), 3( 70) */ + 15278, /* Vector 1232, coef 1( 59), 2(174) */ + 25142, /* Vector 1232, coef 3( 98) Vector + * 1233, Coef 1( 54) */ + -21669, /* Vector 1233, coef 2(171), 3( 91) */ + 12974, /* Vector 1234, coef 1( 50), 2(174) */ + 24877, /* Vector 1234, coef 3( 97) Vector + * 1235, Coef 1( 45) */ + -21413, /* Vector 1235, coef 2(172), 3( 91) */ + 12198, /* Vector 1236, coef 1( 47), 2(166) */ + 24107, /* Vector 1236, coef 3( 94) Vector + * 1237, Coef 1( 43) */ + -22953, /* Vector 1237, coef 2(166), 3( 87) */ + 10655, /* Vector 1238, coef 1( 41), 2(159) */ + 22561, /* Vector 1238, coef 3( 88) Vector + * 1239, Coef 1( 33) */ + -25259, /* Vector 1239, coef 2(157), 3( 85) */ + 15793, /* Vector 1240, coef 1( 61), 2(177) */ + 21294, /* Vector 1240, coef 3( 83) Vector + * 1241, Coef 1( 46) */ + -22708, /* Vector 1241, coef 2(167), 3( 76) */ + 14245, /* Vector 1242, coef 1( 55), 2(165) */ + 19500, /* Vector 1242, coef 3( 76) Vector + * 1243, Coef 1( 44) */ + -25016, /* Vector 1243, coef 2(158), 3( 72) */ + 9371, /* Vector 1244, coef 1( 36), 2(155) */ + 15413, /* Vector 1244, coef 3( 60) Vector + * 1245, Coef 1( 53) */ + -18355, /* Vector 1245, coef 2(184), 3( 77) */ + 9644, /* Vector 1246, coef 1( 37), 2(172) */ + 23844, /* Vector 1246, coef 3( 93) Vector + * 1247, Coef 1( 36) */ + -22704, /* Vector 1247, coef 2(167), 3( 80) */ + 20153, /* Vector 1248, coef 1( 78), 2(185) */ + 24137, /* Vector 1248, coef 3( 94) Vector + * 1249, Coef 1( 73) */ + -19111, /* Vector 1249, coef 2(181), 3( 89) */ + 15023, /* Vector 1250, coef 1( 58), 2(175) */ + 19247, /* Vector 1250, coef 3( 75) Vector + * 1251, Coef 1( 47) */ + -22463, /* Vector 1251, coef 2(168), 3( 65) */ + 14504, /* Vector 1252, coef 1( 56), 2(168) */ + 16224, /* Vector 1252, coef 3( 63) Vector + * 1253, Coef 1( 96) */ + -10406, /* Vector 1253, coef 2(215), 3( 90) */ + 23249, /* Vector 1254, coef 1( 90), 2(209) */ + 24920, /* Vector 1254, coef 3( 97) Vector + * 1255, Coef 1( 88) */ + -15266, /* Vector 1255, coef 2(196), 3( 94) */ + 21693, /* Vector 1256, coef 1( 84), 2(189) */ + 22613, /* Vector 1256, coef 3( 88) Vector + * 1257, Coef 1( 85) */ + -13738, /* Vector 1257, coef 2(202), 3( 86) */ + 20928, /* Vector 1258, coef 1( 81), 2(192) */ + 20299, /* Vector 1258, coef 3( 79) Vector + * 1259, Coef 1( 75) */ + -16815, /* Vector 1259, coef 2(190), 3( 81) */ + 17847, /* Vector 1260, coef 1( 69), 2(183) */ + 18767, /* Vector 1260, coef 3( 73) Vector + * 1261, Coef 1( 79) */ + -18620, /* Vector 1261, coef 2(183), 3( 68) */ + 18355, /* Vector 1262, coef 1( 71), 2(179) */ + 18754, /* Vector 1262, coef 3( 73) Vector + * 1263, Coef 1( 66) */ + -21951, /* Vector 1263, coef 2(170), 3( 65) */ + 24013, /* Vector 1264, coef 1( 93), 2(205) */ + 16213, /* Vector 1264, coef 3( 63) Vector + * 1265, Coef 1( 85) */ + -16331, /* Vector 1265, coef 2(192), 3( 53) */ + 18613, /* Vector 1266, coef 1( 72), 2(181) */ + 15171, /* Vector 1266, coef 3( 59) Vector + * 1267, Coef 1( 67) */ + -21203, /* Vector 1267, coef 2(173), 3( 45) */ + 20689, /* Vector 1268, coef 1( 80), 2(209) */ + 20039, /* Vector 1268, coef 3( 78) Vector + * 1269, Coef 1( 71) */ + -15285, /* Vector 1269, coef 2(196), 3( 75) */ + 19138, /* Vector 1270, coef 1( 74), 2(194) */ + 16963, /* Vector 1270, coef 3( 66) Vector + * 1271, Coef 1( 67) */ + -16831, /* Vector 1271, coef 2(190), 3( 65) */ + 20931, /* Vector 1272, coef 1( 81), 2(195) */ + 16465, /* Vector 1272, coef 3( 64) Vector + * 1273, Coef 1( 81) */ + -14536, /* Vector 1273, coef 2(199), 3( 56) */ + 16565, /* Vector 1274, coef 1( 64), 2(181) */ + 15932, /* Vector 1274, coef 3( 62) Vector + * 1275, Coef 1( 60) */ + -20174, /* Vector 1275, coef 2(177), 3( 50) */ + 13488, /* Vector 1276, coef 1( 52), 2(176) */ + 15680, /* Vector 1276, coef 3( 61) Vector + * 1277, Coef 1( 64) */ + -16845, /* Vector 1277, coef 2(190), 3( 51) */ + 11948, /* Vector 1278, coef 1( 46), 2(172) */ + 9558, /* Vector 1278, coef 3( 37) Vector + * 1279, Coef 1( 86) */ + -9122, /* Vector 1279, coef 2(220), 3( 94) */ + 11206, /* Vector 1280, coef 1( 43), 2(198) */ + -28366, /* Vector 1280, coef 3(145) Vector + * 1281, Coef 1( 50) */ + -11909, /* Vector 1281, coef 2(209), 3(123) */ + 12241, /* Vector 1282, coef 1( 47), 2(209) */ + 31276, /* Vector 1282, coef 3(122) Vector + * 1283, Coef 1( 44) */ + -13965, /* Vector 1283, coef 2(201), 3(115) */ + 12760, /* Vector 1284, coef 1( 49), 2(216) */ + -29648, /* Vector 1284, coef 3(140) Vector + * 1285, Coef 1( 48) */ + -12663, /* Vector 1285, coef 2(206), 3(137) */ + 11992, /* Vector 1286, coef 1( 46), 2(216) */ + -31188, /* Vector 1286, coef 3(134) Vector + * 1287, Coef 1( 44) */ + -11896, /* Vector 1287, coef 2(209), 3(136) */ + 11975, /* Vector 1288, coef 1( 46), 2(199) */ + -32213, /* Vector 1288, coef 3(130) Vector + * 1289, Coef 1( 43) */ + -15230, /* Vector 1289, coef 2(196), 3(130) */ + 10958, /* Vector 1290, coef 1( 42), 2(206) */ + -30680, /* Vector 1290, coef 3(136) Vector + * 1291, Coef 1( 40) */ + -13181, /* Vector 1291, coef 2(204), 3(131) */ + 12767, /* Vector 1292, coef 1( 49), 2(223) */ + 31279, /* Vector 1292, coef 3(122) Vector + * 1293, Coef 1( 47) */ + -10122, /* Vector 1293, coef 2(216), 3(118) */ + 11743, /* Vector 1294, coef 1( 45), 2(223) */ + 30508, /* Vector 1294, coef 3(119) Vector + * 1295, Coef 1( 44) */ + -10377, /* Vector 1295, coef 2(215), 3(119) */ + 10959, /* Vector 1296, coef 1( 42), 2(207) */ + 28457, /* Vector 1296, coef 3(111) Vector + * 1297, Coef 1( 41) */ + -11148, /* Vector 1297, coef 2(212), 3(116) */ + 10191, /* Vector 1298, coef 1( 39), 2(207) */ + 28715, /* Vector 1298, coef 3(112) Vector + * 1299, Coef 1( 43) */ + -9600, /* Vector 1299, coef 2(218), 3(128) */ + 10455, /* Vector 1300, coef 1( 40), 2(215) */ + -32217, /* Vector 1300, coef 3(130) Vector + * 1301, Coef 1( 39) */ + -7810, /* Vector 1301, coef 2(225), 3(126) */ + 9949, /* Vector 1302, coef 1( 38), 2(221) */ + -31706, /* Vector 1302, coef 3(132) Vector + * 1303, Coef 1( 38) */ + -10375, /* Vector 1303, coef 2(215), 3(121) */ + 10698, /* Vector 1304, coef 1( 41), 2(202) */ + 31013, /* Vector 1304, coef 3(121) Vector + * 1305, Coef 1( 37) */ + -13437, /* Vector 1305, coef 2(203), 3(131) */ + 12493, /* Vector 1306, coef 1( 48), 2(205) */ + -26579, /* Vector 1306, coef 3(152) Vector + * 1307, Coef 1( 45) */ + -13157, /* Vector 1307, coef 2(204), 3(155) */ + 10713, /* Vector 1308, coef 1( 41), 2(217) */ + -27609, /* Vector 1308, coef 3(148) Vector + * 1309, Coef 1( 39) */ + -10353, /* Vector 1309, coef 2(215), 3(143) */ + 13518, /* Vector 1310, coef 1( 52), 2(206) */ + -31959, /* Vector 1310, coef 3(131) Vector + * 1311, Coef 1( 41) */ + -8337, /* Vector 1311, coef 2(223), 3(111) */ + 9928, /* Vector 1312, coef 1( 38), 2(200) */ + 30759, /* Vector 1312, coef 3(120) Vector + * 1313, Coef 1( 39) */ + -16001, /* Vector 1313, coef 2(193), 3(127) */ + 9153, /* Vector 1314, coef 1( 35), 2(193) */ + 31522, /* Vector 1314, coef 3(123) Vector + * 1315, Coef 1( 34) */ + -13181, /* Vector 1315, coef 2(204), 3(131) */ + 9154, /* Vector 1316, coef 1( 35), 2(194) */ + -31457, /* Vector 1316, coef 3(133) Vector + * 1317, Coef 1( 31) */ + -15741, /* Vector 1317, coef 2(194), 3(131) */ + 9419, /* Vector 1318, coef 1( 36), 2(203) */ + 31009, /* Vector 1318, coef 3(121) Vector + * 1319, Coef 1( 33) */ + -13705, /* Vector 1319, coef 2(202), 3(119) */ + 8388, /* Vector 1320, coef 1( 32), 2(196) */ + 31261, /* Vector 1320, coef 3(122) Vector + * 1321, Coef 1( 29) */ + -14468, /* Vector 1321, coef 2(199), 3(124) */ + 8380, /* Vector 1322, coef 1( 32), 2(188) */ + 31517, /* Vector 1322, coef 3(123) Vector + * 1323, Coef 1( 29) */ + -17284, /* Vector 1323, coef 2(188), 3(124) */ + 7105, /* Vector 1324, coef 1( 27), 2(193) */ + 31524, /* Vector 1324, coef 3(123) Vector + * 1325, Coef 1( 36) */ + -15509, /* Vector 1325, coef 2(195), 3(107) */ + 9155, /* Vector 1326, coef 1( 35), 2(195) */ + 29472, /* Vector 1326, coef 3(115) Vector + * 1327, Coef 1( 32) */ + -16786, /* Vector 1327, coef 2(190), 3(110) */ + 8387, /* Vector 1328, coef 1( 32), 2(195) */ + 27420, /* Vector 1328, coef 3(107) Vector + * 1329, Coef 1( 28) */ + -16280, /* Vector 1329, coef 2(192), 3(104) */ + 7107, /* Vector 1330, coef 1( 27), 2(195) */ + 28703, /* Vector 1330, coef 3(112) Vector + * 1331, Coef 1( 31) */ + -18061, /* Vector 1331, coef 2(185), 3(115) */ + 7354, /* Vector 1332, coef 1( 28), 2(186) */ + 29221, /* Vector 1332, coef 3(114) Vector + * 1333, Coef 1( 37) */ + -17794, /* Vector 1333, coef 2(186), 3(126) */ + 9142, /* Vector 1334, coef 1( 35), 2(182) */ + 32545, /* Vector 1334, coef 3(127) Vector + * 1335, Coef 1( 33) */ + -19849, /* Vector 1335, coef 2(178), 3(119) */ + 9914, /* Vector 1336, coef 1( 38), 2(186) */ + 29731, /* Vector 1336, coef 3(116) Vector + * 1337, Coef 1( 35) */ + -18061, /* Vector 1337, coef 2(185), 3(115) */ + 8884, /* Vector 1338, coef 1( 34), 2(180) */ + 27940, /* Vector 1338, coef 3(109) Vector + * 1339, Coef 1( 36) */ + -14236, /* Vector 1339, coef 2(200), 3(100) */ + 8900, /* Vector 1340, coef 1( 34), 2(196) */ + 24869, /* Vector 1340, coef 3( 97) Vector + * 1341, Coef 1( 37) */ + -12951, /* Vector 1341, coef 2(205), 3(105) */ + 8907, /* Vector 1342, coef 1( 34), 2(203) */ + 27934, /* Vector 1342, coef 3(109) Vector + * 1343, Coef 1( 30) */ + -13453, /* Vector 1343, coef 2(203), 3(115) */ + 12450, /* Vector 1344, coef 1( 48), 2(162) */ + 25899, /* Vector 1344, coef 3(101) Vector + * 1345, Coef 1( 43) */ + -24993, /* Vector 1345, coef 2(158), 3( 95) */ + 8343, /* Vector 1346, coef 1( 32), 2(151) */ + 23594, /* Vector 1346, coef 3( 92) Vector + * 1347, Coef 1( 42) */ + -24970, /* Vector 1347, coef 2(158), 3(118) */ + 9632, /* Vector 1348, coef 1( 37), 2(160) */ + 30760, /* Vector 1348, coef 3(120) Vector + * 1349, Coef 1( 40) */ + -22406, /* Vector 1349, coef 2(168), 3(122) */ + 12969, /* Vector 1350, coef 1( 50), 2(169) */ + 26667, /* Vector 1350, coef 3(104) Vector + * 1351, Coef 1( 43) */ + -20890, /* Vector 1351, coef 2(174), 3(102) */ + 9646, /* Vector 1352, coef 1( 37), 2(174) */ + 26157, /* Vector 1352, coef 3(102) Vector + * 1353, Coef 1( 45) */ + -21644, /* Vector 1353, coef 2(171), 3(116) */ + 13733, /* Vector 1354, coef 1( 53), 2(165) */ + 29232, /* Vector 1354, coef 3(114) Vector + * 1355, Coef 1( 48) */ + -23952, /* Vector 1355, coef 2(162), 3(112) */ + 11173, /* Vector 1356, coef 1( 43), 2(165) */ + 29222, /* Vector 1356, coef 3(114) Vector + * 1357, Coef 1( 38) */ + -24210, /* Vector 1357, coef 2(161), 3(110) */ + 12463, /* Vector 1358, coef 1( 48), 2(175) */ + 28197, /* Vector 1358, coef 3(110) Vector + * 1359, Coef 1( 37) */ + -20619, /* Vector 1359, coef 2(175), 3(117) */ + 10157, /* Vector 1360, coef 1( 39), 2(173) */ + 28450, /* Vector 1360, coef 3(111) Vector + * 1361, Coef 1( 34) */ + -21394, /* Vector 1361, coef 2(172), 3(110) */ + 9127, /* Vector 1362, coef 1( 35), 2(167) */ + 27166, /* Vector 1362, coef 3(106) Vector + * 1363, Coef 1( 30) */ + -22681, /* Vector 1363, coef 2(167), 3(103) */ + 11688, /* Vector 1364, coef 1( 45), 2(168) */ + 26407, /* Vector 1364, coef 3(103) Vector + * 1365, Coef 1( 39) */ + -22939, /* Vector 1365, coef 2(166), 3(101) */ + 10399, /* Vector 1366, coef 1( 40), 2(159) */ + 26659, /* Vector 1366, coef 3(104) Vector + * 1367, Coef 1( 35) */ + -24988, /* Vector 1367, coef 2(158), 3(100) */ + 9382, /* Vector 1368, coef 1( 36), 2(166) */ + 23835, /* Vector 1368, coef 3( 93) Vector + * 1369, Coef 1( 27) */ + -23458, /* Vector 1369, coef 2(164), 3( 94) */ + 7068, /* Vector 1370, coef 1( 27), 2(156) */ + 26647, /* Vector 1370, coef 3(104) Vector + * 1371, Coef 1( 23) */ + -25248, /* Vector 1371, coef 2(157), 3( 96) */ + 11162, /* Vector 1372, coef 1( 43), 2(154) */ + 27680, /* Vector 1372, coef 3(108) Vector + * 1373, Coef 1( 32) */ + -25487, /* Vector 1373, coef 2(156), 3(113) */ + 8869, /* Vector 1374, coef 1( 34), 2(165) */ + 29470, /* Vector 1374, coef 3(115) Vector + * 1375, Coef 1( 30) */ + -23440, /* Vector 1375, coef 2(164), 3(112) */ + 8871, /* Vector 1376, coef 1( 34), 2(167) */ + 31263, /* Vector 1376, coef 3(122) Vector + * 1377, Coef 1( 31) */ + -23169, /* Vector 1377, coef 2(165), 3(127) */ + 7861, /* Vector 1378, coef 1( 30), 2(181) */ + -31720, /* Vector 1378, coef 3(132) Vector + * 1379, Coef 1( 24) */ + -16260, /* Vector 1379, coef 2(192), 3(124) */ + 6836, /* Vector 1380, coef 1( 26), 2(180) */ + 28181, /* Vector 1380, coef 3(110) Vector + * 1381, Coef 1( 21) */ + -19346, /* Vector 1381, coef 2(180), 3(110) */ + 6330, /* Vector 1382, coef 1( 24), 2(186) */ + 29972, /* Vector 1382, coef 3(117) Vector + * 1383, Coef 1( 20) */ + -17801, /* Vector 1383, coef 2(186), 3(119) */ + 7855, /* Vector 1384, coef 1( 30), 2(175) */ + 29728, /* Vector 1384, coef 3(116) Vector + * 1385, Coef 1( 32) */ + -20609, /* Vector 1385, coef 2(175), 3(127) */ + 7084, /* Vector 1386, coef 1( 27), 2(172) */ + 32027, /* Vector 1386, coef 3(125) Vector + * 1387, Coef 1( 27) */ + -19332, /* Vector 1387, coef 2(180), 3(124) */ + 6321, /* Vector 1388, coef 1( 24), 2(177) */ + 31513, /* Vector 1388, coef 3(123) Vector + * 1389, Coef 1( 25) */ + -23950, /* Vector 1389, coef 2(162), 3(114) */ + 5539, /* Vector 1390, coef 1( 21), 2(163) */ + 27675, /* Vector 1390, coef 3(108) Vector + * 1391, Coef 1( 27) */ + -22921, /* Vector 1391, coef 2(166), 3(119) */ + 6051, /* Vector 1392, coef 1( 23), 2(163) */ + 31254, /* Vector 1392, coef 3(122) Vector + * 1393, Coef 1( 22) */ + -21386, /* Vector 1393, coef 2(172), 3(118) */ + 5039, /* Vector 1394, coef 1( 19), 2(175) */ + 30998, /* Vector 1394, coef 3(121) Vector + * 1395, Coef 1( 22) */ + -20090, /* Vector 1395, coef 2(177), 3(134) */ + 5289, /* Vector 1396, coef 1( 20), 2(169) */ + -31984, /* Vector 1396, coef 3(131) Vector + * 1397, Coef 1( 16) */ + -22401, /* Vector 1397, coef 2(168), 3(127) */ + 6585, /* Vector 1398, coef 1( 25), 2(185) */ + -31467, /* Vector 1398, coef 3(133) Vector + * 1399, Coef 1( 21) */ + -18816, /* Vector 1399, coef 2(182), 3(128) */ + 4792, /* Vector 1400, coef 1( 18), 2(184) */ + 32020, /* Vector 1400, coef 3(125) Vector + * 1401, Coef 1( 20) */ + -18037, /* Vector 1401, coef 2(185), 3(139) */ + 4530, /* Vector 1402, coef 1( 17), 2(178) */ + -30952, /* Vector 1402, coef 3(135) Vector + * 1403, Coef 1( 24) */ + -23677, /* Vector 1403, coef 2(163), 3(131) */ + 5023, /* Vector 1404, coef 1( 19), 2(159) */ + -31980, /* Vector 1404, coef 3(131) Vector + * 1405, Coef 1( 20) */ + -21617, /* Vector 1405, coef 2(171), 3(143) */ + 7084, /* Vector 1406, coef 1( 27), 2(172) */ + 28439, /* Vector 1406, coef 3(111) Vector + * 1407, Coef 1( 23) */ + -21400, /* Vector 1407, coef 2(172), 3(104) */ + 10690, /* Vector 1408, coef 1( 41), 2(194) */ + -29402, /* Vector 1408, coef 3(141) Vector + * 1409, Coef 1( 38) */ + -17518, /* Vector 1409, coef 2(187), 3(146) */ + 9146, /* Vector 1410, coef 1( 35), 2(186) */ + -29904, /* Vector 1410, coef 3(139) Vector + * 1411, Coef 1( 48) */ + -16988, /* Vector 1411, coef 2(189), 3(164) */ + 12463, /* Vector 1412, coef 1( 48), 2(175) */ + -24533, /* Vector 1412, coef 3(160) Vector + * 1413, Coef 1( 43) */ + -13149, /* Vector 1413, coef 2(204), 3(163) */ + 10447, /* Vector 1414, coef 1( 40), 2(207) */ + -24018, /* Vector 1414, coef 3(162) Vector + * 1415, Coef 1( 46) */ + -18509, /* Vector 1415, coef 2(183), 3(179) */ + 11192, /* Vector 1416, coef 1( 43), 2(184) */ + -21201, /* Vector 1416, coef 3(173) Vector + * 1417, Coef 1( 47) */ + -24153, /* Vector 1417, coef 2(161), 3(167) */ + 11424, /* Vector 1418, coef 1( 44), 2(160) */ + -24021, /* Vector 1418, coef 3(162) Vector + * 1419, Coef 1( 43) */ + -17766, /* Vector 1419, coef 2(186), 3(154) */ + 10678, /* Vector 1420, coef 1( 41), 2(182) */ + -25050, /* Vector 1420, coef 3(158) Vector + * 1421, Coef 1( 38) */ + -18020, /* Vector 1421, coef 2(185), 3(156) */ + 9142, /* Vector 1422, coef 1( 35), 2(182) */ + -25561, /* Vector 1422, coef 3(156) Vector + * 1423, Coef 1( 39) */ + -13417, /* Vector 1423, coef 2(203), 3(151) */ + 9673, /* Vector 1424, coef 1( 37), 2(201) */ + -27355, /* Vector 1424, coef 3(149) Vector + * 1425, Coef 1( 37) */ + -9837, /* Vector 1425, coef 2(217), 3(147) */ + 9175, /* Vector 1426, coef 1( 35), 2(215) */ + -26844, /* Vector 1426, coef 3(151) Vector + * 1427, Coef 1( 36) */ + -12915, /* Vector 1427, coef 2(205), 3(141) */ + 9929, /* Vector 1428, coef 1( 38), 2(201) */ + -23261, /* Vector 1428, coef 3(165) Vector + * 1429, Coef 1( 35) */ + -15445, /* Vector 1429, coef 2(195), 3(171) */ + 8910, /* Vector 1430, coef 1( 34), 2(206) */ + -23775, /* Vector 1430, coef 3(163) Vector + * 1431, Coef 1( 33) */ + -13155, /* Vector 1431, coef 2(204), 3(157) */ + 8378, /* Vector 1432, coef 1( 32), 2(186) */ + -24536, /* Vector 1432, coef 3(160) Vector + * 1433, Coef 1( 40) */ + -21610, /* Vector 1433, coef 2(171), 3(150) */ + 10149, /* Vector 1434, coef 1( 39), 2(165) */ + -24277, /* Vector 1434, coef 3(161) Vector + * 1435, Coef 1( 43) */ + -23363, /* Vector 1435, coef 2(164), 3(189) */ + 10665, /* Vector 1436, coef 1( 41), 2(169) */ + -21469, /* Vector 1436, coef 3(172) Vector + * 1437, Coef 1( 35) */ + -17736, /* Vector 1437, coef 2(186), 3(184) */ + 9134, /* Vector 1438, coef 1( 35), 2(174) */ + -21214, /* Vector 1438, coef 3(173) Vector + * 1439, Coef 1( 34) */ + -16236, /* Vector 1439, coef 2(192), 3(148) */ + 8593, /* Vector 1440, coef 1( 33), 2(145) */ + -29413, /* Vector 1440, coef 3(141) Vector + * 1441, Coef 1( 27) */ + -29041, /* Vector 1441, coef 2(142), 3(143) */ + 10645, /* Vector 1442, coef 1( 41), 2(149) */ + -27099, /* Vector 1442, coef 3(150) Vector + * 1443, Coef 1( 37) */ + -27237, /* Vector 1443, coef 2(149), 3(155) */ + 8847, /* Vector 1444, coef 1( 34), 2(143) */ + -27100, /* Vector 1444, coef 3(150) Vector + * 1445, Coef 1( 36) */ + -21632, /* Vector 1445, coef 2(171), 3(128) */ + 9392, /* Vector 1446, coef 1( 36), 2(176) */ + -29151, /* Vector 1446, coef 3(142) Vector + * 1447, Coef 1( 33) */ + -20336, /* Vector 1447, coef 2(176), 3(144) */ + 8883, /* Vector 1448, coef 1( 34), 2(179) */ + -30947, /* Vector 1448, coef 3(135) Vector + * 1449, Coef 1( 29) */ + -20847, /* Vector 1449, coef 2(174), 3(145) */ + 7089, /* Vector 1450, coef 1( 27), 2(177) */ + -30182, /* Vector 1450, coef 3(138) Vector + * 1451, Coef 1( 26) */ + -19055, /* Vector 1451, coef 2(181), 3(145) */ + 6827, /* Vector 1452, coef 1( 26), 2(171) */ + -30946, /* Vector 1452, coef 3(135) Vector + * 1453, Coef 1( 30) */ + -18274, /* Vector 1453, coef 2(184), 3(158) */ + 11426, /* Vector 1454, coef 1( 44), 2(162) */ + -27350, /* Vector 1454, coef 3(149) Vector + * 1455, Coef 1( 42) */ + -25717, /* Vector 1455, coef 2(155), 3(139) */ + 9881, /* Vector 1456, coef 1( 38), 2(153) */ + -30680, /* Vector 1456, coef 3(136) Vector + * 1457, Coef 1( 40) */ + -22641, /* Vector 1457, coef 2(167), 3(143) */ + 9638, /* Vector 1458, coef 1( 37), 2(166) */ + -26846, /* Vector 1458, coef 3(151) Vector + * 1459, Coef 1( 34) */ + -24430, /* Vector 1459, coef 2(160), 3(146) */ + 9123, /* Vector 1460, coef 1( 35), 2(163) */ + -24545, /* Vector 1460, coef 3(160) Vector + * 1461, Coef 1( 31) */ + -23138, /* Vector 1461, coef 2(165), 3(158) */ + 9635, /* Vector 1462, coef 1( 37), 2(163) */ + -31199, /* Vector 1462, coef 3(134) Vector + * 1463, Coef 1( 33) */ + -23417, /* Vector 1463, coef 2(164), 3(135) */ + 8346, /* Vector 1464, coef 1( 32), 2(154) */ + -30947, /* Vector 1464, coef 3(135) Vector + * 1465, Coef 1( 29) */ + -27002, /* Vector 1465, coef 2(150), 3(134) */ + 7842, /* Vector 1466, coef 1( 30), 2(162) */ + -28134, /* Vector 1466, coef 3(146) Vector + * 1467, Coef 1( 26) */ + -23923, /* Vector 1467, coef 2(162), 3(141) */ + 6811, /* Vector 1468, coef 1( 26), 2(155) */ + -27620, /* Vector 1468, coef 3(148) Vector + * 1469, Coef 1( 28) */ + -23674, /* Vector 1469, coef 2(163), 3(134) */ + 6042, /* Vector 1470, coef 1( 23), 2(154) */ + -31721, /* Vector 1470, coef 3(132) Vector + * 1471, Coef 1( 23) */ + -22381, /* Vector 1471, coef 2(168), 3(147) */ + 7821, /* Vector 1472, coef 1( 30), 2(141) */ + -27113, /* Vector 1472, coef 3(150) Vector + * 1473, Coef 1( 23) */ + -19311, /* Vector 1473, coef 2(180), 3(145) */ + 7332, /* Vector 1474, coef 1( 28), 2(164) */ + -25834, /* Vector 1474, coef 3(155) Vector + * 1475, Coef 1( 22) */ + -26478, /* Vector 1475, coef 2(152), 3(146) */ + 8359, /* Vector 1476, coef 1( 32), 2(167) */ + -17124, /* Vector 1476, coef 3(189) Vector + * 1477, Coef 1( 28) */ + -19011, /* Vector 1477, coef 2(181), 3(189) */ + 7852, /* Vector 1478, coef 1( 30), 2(172) */ + -21988, /* Vector 1478, coef 3(170) Vector + * 1479, Coef 1( 28) */ + -22864, /* Vector 1479, coef 2(166), 3(176) */ + 8598, /* Vector 1480, coef 1( 33), 2(150) */ + -23524, /* Vector 1480, coef 3(164) Vector + * 1481, Coef 1( 28) */ + -26720, /* Vector 1481, coef 2(151), 3(160) */ + 6811, /* Vector 1482, coef 1( 26), 2(155) */ + -21736, /* Vector 1482, coef 3(171) Vector + * 1483, Coef 1( 24) */ + -25177, /* Vector 1483, coef 2(157), 3(167) */ + 7052, /* Vector 1484, coef 1( 27), 2(140) */ + -25321, /* Vector 1484, coef 3(157) Vector + * 1485, Coef 1( 23) */ + -29277, /* Vector 1485, coef 2(141), 3(163) */ + 5793, /* Vector 1486, coef 1( 22), 2(161) */ + -24558, /* Vector 1486, coef 3(160) Vector + * 1487, Coef 1( 18) */ + -23395, /* Vector 1487, coef 2(164), 3(157) */ + 12167, /* Vector 1488, coef 1( 47), 2(135) */ + -22748, /* Vector 1488, coef 3(167) Vector + * 1489, Coef 1( 36) */ + -31313, /* Vector 1489, coef 2(133), 3(175) */ + 7812, /* Vector 1490, coef 1( 30), 2(132) */ + -21474, /* Vector 1490, coef 3(172) Vector + * 1491, Coef 1( 30) */ + 25775, /* Vector 1491, coef 2(100), 3(175) */ + 5806, /* Vector 1492, coef 1( 22), 2(174) */ + -18921, /* Vector 1492, coef 3(182) Vector + * 1493, Coef 1( 23) */ + -29243, /* Vector 1493, coef 2(141), 3(197) */ + 5251, /* Vector 1494, coef 1( 20), 2(131) */ + -14312, /* Vector 1494, coef 3(200) Vector + * 1495, Coef 1( 24) */ + -29002, /* Vector 1495, coef 2(142), 3(182) */ + 5761, /* Vector 1496, coef 1( 22), 2(129) */ + -21997, /* Vector 1496, coef 3(170) Vector + * 1497, Coef 1( 19) */ + -23373, /* Vector 1497, coef 2(164), 3(179) */ + 4260, /* Vector 1498, coef 1( 16), 2(164) */ + -20711, /* Vector 1498, coef 3(175) Vector + * 1499, Coef 1( 25) */ + -19043, /* Vector 1499, coef 2(181), 3(157) */ + 6574, /* Vector 1500, coef 1( 25), 2(174) */ + -24042, /* Vector 1500, coef 3(162) Vector + * 1501, Coef 1( 22) */ + -20581, /* Vector 1501, coef 2(175), 3(155) */ + 6077, /* Vector 1502, coef 1( 23), 2(189) */ + -19946, /* Vector 1502, coef 3(178) Vector + * 1503, Coef 1( 22) */ + -19540, /* Vector 1503, coef 2(179), 3(172) */ + 4516, /* Vector 1504, coef 1( 17), 2(164) */ + -28404, /* Vector 1504, coef 3(145) Vector + * 1505, Coef 1( 12) */ + -22631, /* Vector 1505, coef 2(167), 3(153) */ + 4796, /* Vector 1506, coef 1( 18), 2(188) */ + -16103, /* Vector 1506, coef 3(193) Vector + * 1507, Coef 1( 25) */ + -14936, /* Vector 1507, coef 2(197), 3(168) */ + 6088, /* Vector 1508, coef 1( 23), 2(200) */ + -23274, /* Vector 1508, coef 3(165) Vector + * 1509, Coef 1( 22) */ + -16485, /* Vector 1509, coef 2(191), 3(155) */ + 5307, /* Vector 1510, coef 1( 20), 2(187) */ + -27630, /* Vector 1510, coef 3(148) Vector + * 1511, Coef 1( 18) */ + -15722, /* Vector 1511, coef 2(194), 3(150) */ + 5307, /* Vector 1512, coef 1( 20), 2(187) */ + -24046, /* Vector 1512, coef 3(162) Vector + * 1513, Coef 1( 18) */ + -19805, /* Vector 1513, coef 2(178), 3(163) */ + 4537, /* Vector 1514, coef 1( 17), 2(185) */ + -26098, /* Vector 1514, coef 3(154) Vector + * 1515, Coef 1( 14) */ + -17769, /* Vector 1515, coef 2(186), 3(151) */ + 6342, /* Vector 1516, coef 1( 24), 2(198) */ + -19948, /* Vector 1516, coef 3(178) Vector + * 1517, Coef 1( 20) */ + -17492, /* Vector 1517, coef 2(187), 3(172) */ + 5582, /* Vector 1518, coef 1( 21), 2(206) */ + -22765, /* Vector 1518, coef 3(167) Vector + * 1519, Coef 1( 19) */ + -13141, /* Vector 1519, coef 2(204), 3(171) */ + 4818, /* Vector 1520, coef 1( 18), 2(210) */ + -23792, /* Vector 1520, coef 3(163) Vector + * 1521, Coef 1( 16) */ + -12380, /* Vector 1521, coef 2(207), 3(164) */ + 4820, /* Vector 1522, coef 1( 18), 2(212) */ + -19696, /* Vector 1522, coef 3(179) Vector + * 1523, Coef 1( 16) */ + -10063, /* Vector 1523, coef 2(216), 3(177) */ + 4038, /* Vector 1524, coef 1( 15), 2(198) */ + -16883, /* Vector 1524, coef 3(190) Vector + * 1525, Coef 1( 13) */ + -19521, /* Vector 1525, coef 2(179), 3(191) */ + 4288, /* Vector 1526, coef 1( 16), 2(192) */ + -21235, /* Vector 1526, coef 3(173) Vector + * 1527, Coef 1( 13) */ + -18773, /* Vector 1527, coef 2(182), 3(171) */ + 3277, /* Vector 1528, coef 1( 12), 2(205) */ + -23275, /* Vector 1528, coef 3(165) Vector + * 1529, Coef 1( 21) */ + -13160, /* Vector 1529, coef 2(204), 3(152) */ + 5071, /* Vector 1530, coef 1( 19), 2(207) */ + -27629, /* Vector 1530, coef 3(148) Vector + * 1531, Coef 1( 19) */ + -9575, /* Vector 1531, coef 2(218), 3(153) */ + 4830, /* Vector 1532, coef 1( 18), 2(222) */ + -25840, /* Vector 1532, coef 3(155) Vector + * 1533, Coef 1( 16) */ + -11112, /* Vector 1533, coef 2(212), 3(152) */ + 3800, /* Vector 1534, coef 1( 14), 2(216) */ + -24305, /* Vector 1534, coef 3(161) Vector + * 1535, Coef 1( 15) */ + -7269, /* Vector 1535, coef 2(227), 3(155) */ + 15302, /* Vector 1536, coef 1( 59), 2(198) */ + 30786, /* Vector 1536, coef 3(120) Vector + * 1537, Coef 1( 66) */ + -13468, /* Vector 1537, coef 2(203), 3(100) */ + 15302, /* Vector 1538, coef 1( 59), 2(198) */ + 27191, /* Vector 1538, coef 3(106) Vector + * 1539, Coef 1( 55) */ + -8844, /* Vector 1539, coef 2(221), 3(116) */ + 13782, /* Vector 1540, coef 1( 53), 2(214) */ + 28230, /* Vector 1540, coef 3(110) Vector + * 1541, Coef 1( 70) */ + -10124, /* Vector 1541, coef 2(216), 3(116) */ + 17364, /* Vector 1542, coef 1( 67), 2(212) */ + 29759, /* Vector 1542, coef 3(116) Vector + * 1543, Coef 1( 63) */ + -13709, /* Vector 1543, coef 2(202), 3(115) */ + 17114, /* Vector 1544, coef 1( 66), 2(218) */ + 23104, /* Vector 1544, coef 3( 90) Vector + * 1545, Coef 1( 64) */ + -9879, /* Vector 1545, coef 2(217), 3(105) */ + 16084, /* Vector 1546, coef 1( 62), 2(212) */ + 26687, /* Vector 1546, coef 3(104) Vector + * 1547, Coef 1( 63) */ + -12701, /* Vector 1547, coef 2(206), 3( 99) */ + 15056, /* Vector 1548, coef 1( 58), 2(208) */ + 24897, /* Vector 1548, coef 3( 97) Vector + * 1549, Coef 1( 65) */ + -11384, /* Vector 1549, coef 2(211), 3(136) */ + 15574, /* Vector 1550, coef 1( 60), 2(214) */ + -30401, /* Vector 1550, coef 3(137) Vector + * 1551, Coef 1( 63) */ + -10376, /* Vector 1551, coef 2(215), 3(120) */ + 15570, /* Vector 1552, coef 1( 60), 2(210) */ + 30267, /* Vector 1552, coef 3(118) Vector + * 1553, Coef 1( 59) */ + -9095, /* Vector 1553, coef 2(220), 3(121) */ + 14806, /* Vector 1554, coef 1( 57), 2(214) */ + 29242, /* Vector 1554, coef 3(114) Vector + * 1555, Coef 1( 58) */ + -11392, /* Vector 1555, coef 2(211), 3(128) */ + 14285, /* Vector 1556, coef 1( 55), 2(205) */ + 31798, /* Vector 1556, coef 3(124) Vector + * 1557, Coef 1( 54) */ + -10879, /* Vector 1557, coef 2(213), 3(129) */ + 15569, /* Vector 1558, coef 1( 60), 2(209) */ + 27705, /* Vector 1558, coef 3(108) Vector + * 1559, Coef 1( 57) */ + -12693, /* Vector 1559, coef 2(206), 3(107) */ + 14281, /* Vector 1560, coef 1( 55), 2(201) */ + 29751, /* Vector 1560, coef 3(116) Vector + * 1561, Coef 1( 55) */ + -14488, /* Vector 1561, coef 2(199), 3(104) */ + 16097, /* Vector 1562, coef 1( 62), 2(225) */ + 26684, /* Vector 1562, coef 3(104) Vector + * 1563, Coef 1( 60) */ + -9372, /* Vector 1563, coef 2(219), 3(100) */ + 15074, /* Vector 1564, coef 1( 58), 2(226) */ + 24888, /* Vector 1564, coef 3( 97) Vector + * 1565, Coef 1( 56) */ + -10654, /* Vector 1565, coef 2(214), 3( 98) */ + 16868, /* Vector 1566, coef 1( 65), 2(228) */ + 21053, /* Vector 1566, coef 3( 82) Vector + * 1567, Coef 1( 61) */ + -9900, /* Vector 1567, coef 2(217), 3( 84) */ + 14016, /* Vector 1568, coef 1( 54), 2(192) */ + 25650, /* Vector 1568, coef 3(100) Vector + * 1569, Coef 1( 50) */ + -18839, /* Vector 1569, coef 2(182), 3(105) */ + 11959, /* Vector 1570, coef 1( 46), 2(183) */ + 26408, /* Vector 1570, coef 3(103) Vector + * 1571, Coef 1( 40) */ + -19352, /* Vector 1571, coef 2(180), 3(104) */ + 12233, /* Vector 1572, coef 1( 47), 2(201) */ + 29480, /* Vector 1572, coef 3(115) Vector + * 1573, Coef 1( 40) */ + -14740, /* Vector 1573, coef 2(198), 3(108) */ + 11698, /* Vector 1574, coef 1( 45), 2(178) */ + 28214, /* Vector 1574, coef 3(110) Vector + * 1575, Coef 1( 54) */ + -13220, /* Vector 1575, coef 2(204), 3( 92) */ + 13510, /* Vector 1576, coef 1( 52), 2(198) */ + 32049, /* Vector 1576, coef 3(125) Vector + * 1577, Coef 1( 49) */ + -15748, /* Vector 1577, coef 2(194), 3(124) */ + 13515, /* Vector 1578, coef 1( 52), 2(203) */ + 29235, /* Vector 1578, coef 3(114) Vector + * 1579, Coef 1( 51) */ + -15004, /* Vector 1579, coef 2(197), 3(100) */ + 12735, /* Vector 1580, coef 1( 49), 2(191) */ + 27950, /* Vector 1580, coef 3(109) Vector + * 1581, Coef 1( 46) */ + -15767, /* Vector 1581, coef 2(194), 3(105) */ + 13259, /* Vector 1582, coef 1( 51), 2(203) */ + 27183, /* Vector 1582, coef 3(106) Vector + * 1583, Coef 1( 47) */ + -13979, /* Vector 1583, coef 2(201), 3(101) */ + 12488, /* Vector 1584, coef 1( 48), 2(200) */ + 23851, /* Vector 1584, coef 3( 93) Vector + * 1585, Coef 1( 43) */ + -15266, /* Vector 1585, coef 2(196), 3( 94) */ + 12735, /* Vector 1586, coef 1( 49), 2(191) */ + 24877, /* Vector 1586, coef 3( 97) Vector + * 1587, Coef 1( 45) */ + -17057, /* Vector 1587, coef 2(189), 3( 95) */ + 11961, /* Vector 1588, coef 1( 46), 2(185) */ + 29738, /* Vector 1588, coef 3(116) Vector + * 1589, Coef 1( 42) */ + -18574, /* Vector 1589, coef 2(183), 3(114) */ + 11458, /* Vector 1590, coef 1( 44), 2(194) */ + 29992, /* Vector 1590, coef 3(117) Vector + * 1591, Coef 1( 40) */ + -16013, /* Vector 1591, coef 2(193), 3(115) */ + 11197, /* Vector 1592, coef 1( 43), 2(189) */ + 26919, /* Vector 1592, coef 3(105) Vector + * 1593, Coef 1( 39) */ + -17046, /* Vector 1593, coef 2(189), 3(106) */ + 14279, /* Vector 1594, coef 1( 55), 2(199) */ + 23089, /* Vector 1594, coef 3( 90) Vector + * 1595, Coef 1( 49) */ + -16039, /* Vector 1595, coef 2(193), 3( 89) */ + 13244, /* Vector 1596, coef 1( 51), 2(188) */ + 22575, /* Vector 1596, coef 3( 88) Vector + * 1597, Coef 1( 47) */ + -15020, /* Vector 1597, coef 2(197), 3( 84) */ + 11209, /* Vector 1598, coef 1( 43), 2(201) */ + 27175, /* Vector 1598, coef 3(106) Vector + * 1599, Coef 1( 39) */ + -15521, /* Vector 1599, coef 2(195), 3( 95) */ + 17606, /* Vector 1600, coef 1( 68), 2(198) */ + 17467, /* Vector 1600, coef 3( 68) Vector + * 1601, Coef 1( 59) */ + -16828, /* Vector 1601, coef 2(190), 3( 68) */ + 17095, /* Vector 1602, coef 1( 66), 2(199) */ + 14911, /* Vector 1602, coef 3( 58) Vector + * 1603, Coef 1( 63) */ + -14802, /* Vector 1603, coef 2(198), 3( 46) */ + 14263, /* Vector 1604, coef 1( 55), 2(183) */ + 16201, /* Vector 1604, coef 3( 63) Vector + * 1605, Coef 1( 73) */ + -7320, /* Vector 1605, coef 2(227), 3(104) */ + 17885, /* Vector 1606, coef 1( 69), 2(221) */ + 24893, /* Vector 1606, coef 3( 97) Vector + * 1607, Coef 1( 61) */ + -12965, /* Vector 1607, coef 2(205), 3( 91) */ + 20439, /* Vector 1608, coef 1( 79), 2(215) */ + 20810, /* Vector 1608, coef 3( 81) Vector + * 1609, Coef 1( 74) */ + -12465, /* Vector 1609, coef 2(207), 3( 79) */ + 17872, /* Vector 1610, coef 1( 69), 2(208) */ + 21825, /* Vector 1610, coef 3( 85) Vector + * 1611, Coef 1( 65) */ + -15281, /* Vector 1611, coef 2(196), 3( 79) */ + 16068, /* Vector 1612, coef 1( 62), 2(196) */ + 23097, /* Vector 1612, coef 3( 90) Vector + * 1613, Coef 1( 57) */ + -16040, /* Vector 1613, coef 2(193), 3( 88) */ + 15037, /* Vector 1614, coef 1( 58), 2(189) */ + 21307, /* Vector 1614, coef 3( 83) Vector + * 1615, Coef 1( 59) */ + -15285, /* Vector 1615, coef 2(196), 3( 75) */ + 14017, /* Vector 1616, coef 1( 54), 2(193) */ + 17459, /* Vector 1616, coef 3( 68) Vector + * 1617, Coef 1( 51) */ + -17853, /* Vector 1617, coef 2(186), 3( 67) */ + 10673, /* Vector 1618, coef 1( 41), 2(177) */ + 16712, /* Vector 1618, coef 3( 65) Vector + * 1619, Coef 1( 72) */ + -8362, /* Vector 1619, coef 2(223), 3( 86) */ + 17361, /* Vector 1620, coef 1( 67), 2(209) */ + 19775, /* Vector 1620, coef 3( 77) Vector + * 1621, Coef 1( 63) */ + -11955, /* Vector 1621, coef 2(209), 3( 77) */ + 14794, /* Vector 1622, coef 1( 57), 2(202) */ + 17729, /* Vector 1622, coef 3( 69) Vector + * 1623, Coef 1( 65) */ + -10174, /* Vector 1623, coef 2(216), 3( 66) */ + 15827, /* Vector 1624, coef 1( 61), 2(211) */ + 13371, /* Vector 1624, coef 3( 52) Vector + * 1625, Coef 1( 59) */ + -14280, /* Vector 1625, coef 2(200), 3( 56) */ + 13764, /* Vector 1626, coef 1( 53), 2(196) */ + 11315, /* Vector 1626, coef 3( 44) Vector + * 1627, Coef 1( 51) */ + -14270, /* Vector 1627, coef 2(200), 3( 66) */ + 10940, /* Vector 1628, coef 1( 42), 2(188) */ + 16182, /* Vector 1628, coef 3( 63) Vector + * 1629, Coef 1( 54) */ + -15281, /* Vector 1629, coef 2(196), 3( 79) */ + 12737, /* Vector 1630, coef 1( 49), 2(193) */ + 19768, /* Vector 1630, coef 3( 77) Vector + * 1631, Coef 1( 56) */ + -12209, /* Vector 1631, coef 2(208), 3( 79) */ + 10686, /* Vector 1632, coef 1( 41), 2(190) */ + 23844, /* Vector 1632, coef 3( 93) Vector + * 1633, Coef 1( 36) */ + -17575, /* Vector 1633, coef 2(187), 3( 89) */ + 9656, /* Vector 1634, coef 1( 37), 2(184) */ + 26146, /* Vector 1634, coef 3(102) Vector + * 1635, Coef 1( 34) */ + -19100, /* Vector 1635, coef 2(181), 3(100) */ + 7859, /* Vector 1636, coef 1( 30), 2(179) */ + 27177, /* Vector 1636, coef 3(106) Vector + * 1637, Coef 1( 41) */ + -17335, /* Vector 1637, coef 2(188), 3( 73) */ + 8120, /* Vector 1638, coef 1( 31), 2(184) */ + 17444, /* Vector 1638, coef 3( 68) Vector + * 1639, Coef 1( 36) */ + -19149, /* Vector 1639, coef 2(181), 3( 51) */ + 12218, /* Vector 1640, coef 1( 47), 2(186) */ + 20780, /* Vector 1640, coef 3( 81) Vector + * 1641, Coef 1( 44) */ + -19373, /* Vector 1641, coef 2(180), 3( 83) */ + 10163, /* Vector 1642, coef 1( 39), 2(179) */ + 19243, /* Vector 1642, coef 3( 75) Vector + * 1643, Coef 1( 43) */ + -16049, /* Vector 1643, coef 2(193), 3( 79) */ + 9149, /* Vector 1644, coef 1( 35), 2(189) */ + 19753, /* Vector 1644, coef 3( 77) Vector + * 1645, Coef 1( 41) */ + -18089, /* Vector 1645, coef 2(185), 3( 87) */ + 9911, /* Vector 1646, coef 1( 38), 2(183) */ + 21022, /* Vector 1646, coef 3( 82) Vector + * 1647, Coef 1( 30) */ + -18857, /* Vector 1647, coef 2(182), 3( 87) */ + 6322, /* Vector 1648, coef 1( 24), 2(178) */ + 20266, /* Vector 1648, coef 3( 79) Vector + * 1649, Coef 1( 42) */ + -18593, /* Vector 1649, coef 2(183), 3( 95) */ + 9138, /* Vector 1650, coef 1( 35), 2(178) */ + 24093, /* Vector 1650, coef 3( 94) Vector + * 1651, Coef 1( 29) */ + -20895, /* Vector 1651, coef 2(174), 3( 97) */ + 9646, /* Vector 1652, coef 1( 37), 2(174) */ + 21789, /* Vector 1652, coef 3( 85) Vector + * 1653, Coef 1( 29) */ + -20652, /* Vector 1653, coef 2(175), 3( 84) */ + 7079, /* Vector 1654, coef 1( 27), 2(167) */ + 19491, /* Vector 1654, coef 3( 76) Vector + * 1655, Coef 1( 35) */ + -16540, /* Vector 1655, coef 2(191), 3(100) */ + 8125, /* Vector 1656, coef 1( 31), 2(189) */ + 24863, /* Vector 1656, coef 3( 97) Vector + * 1657, Coef 1( 31) */ + -18592, /* Vector 1657, coef 2(183), 3( 96) */ + 7094, /* Vector 1658, coef 1( 27), 2(182) */ + 25112, /* Vector 1658, coef 3( 98) Vector + * 1659, Coef 1( 24) */ + -17817, /* Vector 1659, coef 2(186), 3(103) */ + 5812, /* Vector 1660, coef 1( 22), 2(180) */ + 24082, /* Vector 1660, coef 3( 94) Vector + * 1661, Coef 1( 18) */ + -21413, /* Vector 1661, coef 2(172), 3( 91) */ + 8641, /* Vector 1662, coef 1( 33), 2(193) */ + 22040, /* Vector 1662, coef 3( 86) Vector + * 1663, Coef 1( 24) */ + -17579, /* Vector 1663, coef 2(187), 3( 85) */ + 13530, /* Vector 1664, coef 1( 52), 2(218) */ + 31538, /* Vector 1664, coef 3(123) Vector + * 1665, Coef 1( 50) */ + -10894, /* Vector 1665, coef 2(213), 3(114) */ + 11734, /* Vector 1666, coef 1( 45), 2(214) */ + 27703, /* Vector 1666, coef 3(108) Vector + * 1667, Coef 1( 55) */ + -8604, /* Vector 1667, coef 2(222), 3(100) */ + 13777, /* Vector 1668, coef 1( 53), 2(209) */ + 24371, /* Vector 1668, coef 3( 95) Vector + * 1669, Coef 1( 51) */ + -10654, /* Vector 1669, coef 2(214), 3( 98) */ + 12496, /* Vector 1670, coef 1( 48), 2(208) */ + 24117, /* Vector 1670, coef 3( 94) Vector + * 1671, Coef 1( 53) */ + -7837, /* Vector 1671, coef 2(225), 3( 99) */ + 13027, /* Vector 1672, coef 1( 50), 2(227) */ + 23601, /* Vector 1672, coef 3( 92) Vector + * 1673, Coef 1( 49) */ + -9109, /* Vector 1673, coef 2(220), 3(107) */ + 12248, /* Vector 1674, coef 1( 47), 2(216) */ + 25393, /* Vector 1674, coef 3( 99) Vector + * 1675, Coef 1( 49) */ + -9639, /* Vector 1675, coef 2(218), 3( 89) */ + 12251, /* Vector 1676, coef 1( 47), 2(219) */ + 22061, /* Vector 1676, coef 3( 86) Vector + * 1677, Coef 1( 45) */ + -11174, /* Vector 1677, coef 2(212), 3( 90) */ + 10959, /* Vector 1678, coef 1( 42), 2(207) */ + 23344, /* Vector 1678, coef 3( 91) Vector + * 1679, Coef 1( 48) */ + -11925, /* Vector 1679, coef 2(209), 3(107) */ + 11726, /* Vector 1680, coef 1( 45), 2(206) */ + 26153, /* Vector 1680, coef 3(102) Vector + * 1681, Coef 1( 41) */ + -13210, /* Vector 1681, coef 2(204), 3(102) */ + 11222, /* Vector 1682, coef 1( 43), 2(214) */ + 25639, /* Vector 1682, coef 3(100) Vector + * 1683, Coef 1( 39) */ + -11161, /* Vector 1683, coef 2(212), 3(103) */ + 10192, /* Vector 1684, coef 1( 39), 2(208) */ + 24618, /* Vector 1684, coef 3( 96) Vector + * 1685, Coef 1( 42) */ + -13986, /* Vector 1685, coef 2(201), 3( 94) */ + 13269, /* Vector 1686, coef 1( 51), 2(213) */ + 21295, /* Vector 1686, coef 3( 83) Vector + * 1687, Coef 1( 47) */ + -12973, /* Vector 1687, coef 2(205), 3( 83) */ + 11466, /* Vector 1688, coef 1( 44), 2(202) */ + 22059, /* Vector 1688, coef 3( 86) Vector + * 1689, Coef 1( 43) */ + -12207, /* Vector 1689, coef 2(208), 3( 81) */ + 14819, /* Vector 1690, coef 1( 57), 2(227) */ + 21813, /* Vector 1690, coef 3( 85) Vector + * 1691, Coef 1( 53) */ + -8876, /* Vector 1691, coef 2(221), 3( 84) */ + 13794, /* Vector 1692, coef 1( 53), 2(226) */ + 18737, /* Vector 1692, coef 3( 73) Vector + * 1693, Coef 1( 49) */ + -9911, /* Vector 1693, coef 2(217), 3( 73) */ + 12003, /* Vector 1694, coef 1( 46), 2(227) */ + 25644, /* Vector 1694, coef 3(100) Vector + * 1695, Coef 1( 44) */ + -8348, /* Vector 1695, coef 2(223), 3(100) */ + 12229, /* Vector 1696, coef 1( 47), 2(197) */ + 14888, /* Vector 1696, coef 3( 58) Vector + * 1697, Coef 1( 40) */ + -15547, /* Vector 1697, coef 2(195), 3( 69) */ + 9150, /* Vector 1698, coef 1( 35), 2(190) */ + 15656, /* Vector 1698, coef 3( 61) Vector + * 1699, Coef 1( 40) */ + -15281, /* Vector 1699, coef 2(196), 3( 79) */ + 9415, /* Vector 1700, coef 1( 36), 2(199) */ + 22588, /* Vector 1700, coef 3( 88) Vector + * 1701, Coef 1( 60) */ + -7856, /* Vector 1701, coef 2(225), 3( 80) */ + 15064, /* Vector 1702, coef 1( 58), 2(216) */ + 18483, /* Vector 1702, coef 3( 72) Vector + * 1703, Coef 1( 51) */ + -13492, /* Vector 1703, coef 2(203), 3( 76) */ + 13520, /* Vector 1704, coef 1( 52), 2(208) */ + 17966, /* Vector 1704, coef 3( 70) Vector + * 1705, Coef 1( 46) */ + -14009, /* Vector 1705, coef 2(201), 3( 71) */ + 14558, /* Vector 1706, coef 1( 56), 2(222) */ + 18483, /* Vector 1706, coef 3( 72) Vector + * 1707, Coef 1( 51) */ + -10938, /* Vector 1707, coef 2(213), 3( 70) */ + 13274, /* Vector 1708, coef 1( 51), 2(218) */ + 15406, /* Vector 1708, coef 3( 60) Vector + * 1709, Coef 1( 46) */ + -11984, /* Vector 1709, coef 2(209), 3( 48) */ + 15062, /* Vector 1710, coef 1( 58), 2(214) */ + 14383, /* Vector 1710, coef 3( 56) Vector + * 1711, Coef 1( 47) */ + -13510, /* Vector 1711, coef 2(203), 3( 58) */ + 12754, /* Vector 1712, coef 1( 49), 2(210) */ + 13349, /* Vector 1712, coef 3( 52) Vector + * 1713, Coef 1( 37) */ + -15312, /* Vector 1713, coef 2(196), 3( 48) */ + 10440, /* Vector 1714, coef 1( 40), 2(200) */ + 20771, /* Vector 1714, coef 3( 81) Vector + * 1715, Coef 1( 35) */ + -14258, /* Vector 1715, coef 2(200), 3( 78) */ + 8135, /* Vector 1716, coef 1( 31), 2(199) */ + 21038, /* Vector 1716, coef 3( 82) Vector + * 1717, Coef 1( 46) */ + -12218, /* Vector 1717, coef 2(208), 3( 70) */ + 10184, /* Vector 1718, coef 1( 39), 2(200) */ + 17706, /* Vector 1718, coef 3( 69) Vector + * 1719, Coef 1( 42) */ + -12993, /* Vector 1719, coef 2(205), 3( 63) */ + 8904, /* Vector 1720, coef 1( 34), 2(200) */ + 15395, /* Vector 1720, coef 3( 60) Vector + * 1721, Coef 1( 35) */ + -12986, /* Vector 1721, coef 2(205), 3( 70) */ + 7873, /* Vector 1722, coef 1( 30), 2(193) */ + 18196, /* Vector 1722, coef 3( 71) Vector + * 1723, Coef 1( 20) */ + -16565, /* Vector 1723, coef 2(191), 3( 75) */ + 11476, /* Vector 1724, coef 1( 44), 2(212) */ + 18474, /* Vector 1724, coef 3( 72) Vector + * 1725, Coef 1( 42) */ + -11199, /* Vector 1725, coef 2(212), 3( 65) */ + 11992, /* Vector 1726, coef 1( 46), 2(216) */ + 13605, /* Vector 1726, coef 3( 53) Vector + * 1727, Coef 1( 37) */ + -12487, /* Vector 1727, coef 2(207), 3( 57) */ + 9686, /* Vector 1728, coef 1( 37), 2(214) */ + 29219, /* Vector 1728, coef 3(114) Vector + * 1729, Coef 1( 35) */ + -11149, /* Vector 1729, coef 2(212), 3(115) */ + 8401, /* Vector 1730, coef 1( 32), 2(209) */ + 29219, /* Vector 1730, coef 3(114) Vector + * 1731, Coef 1( 35) */ + -7824, /* Vector 1731, coef 2(225), 3(112) */ + 8670, /* Vector 1732, coef 1( 33), 2(222) */ + 27681, /* Vector 1732, coef 3(108) Vector + * 1733, Coef 1( 33) */ + -8351, /* Vector 1733, coef 2(223), 3( 97) */ + 7900, /* Vector 1734, coef 1( 30), 2(220) */ + 25636, /* Vector 1734, coef 3(100) Vector + * 1735, Coef 1( 36) */ + -7297, /* Vector 1735, coef 2(227), 3(127) */ + 9179, /* Vector 1736, coef 1( 35), 2(219) */ + 32547, /* Vector 1736, coef 3(127) Vector + * 1737, Coef 1( 35) */ + -11137, /* Vector 1737, coef 2(212), 3(127) */ + 8408, /* Vector 1738, coef 1( 32), 2(216) */ + 32545, /* Vector 1738, coef 3(127) Vector + * 1739, Coef 1( 33) */ + -8841, /* Vector 1739, coef 2(221), 3(119) */ + 8154, /* Vector 1740, coef 1( 31), 2(218) */ + 28958, /* Vector 1740, coef 3(113) Vector + * 1741, Coef 1( 30) */ + -10884, /* Vector 1741, coef 2(213), 3(124) */ + 7378, /* Vector 1742, coef 1( 28), 2(210) */ + 32033, /* Vector 1742, coef 3(125) Vector + * 1743, Coef 1( 33) */ + -5775, /* Vector 1743, coef 2(233), 3(113) */ + 8423, /* Vector 1744, coef 1( 32), 2(231) */ + 29983, /* Vector 1744, coef 3(117) Vector + * 1745, Coef 1( 31) */ + -4239, /* Vector 1745, coef 2(239), 3(113) */ + 7658, /* Vector 1746, coef 1( 29), 2(234) */ + 29470, /* Vector 1746, coef 3(115) Vector + * 1747, Coef 1( 30) */ + -7065, /* Vector 1747, coef 2(228), 3(103) */ + 7904, /* Vector 1748, coef 1( 30), 2(224) */ + 30748, /* Vector 1748, coef 3(120) Vector + * 1749, Coef 1( 28) */ + -8332, /* Vector 1749, coef 2(223), 3(116) */ + 7136, /* Vector 1750, coef 1( 27), 2(224) */ + 32025, /* Vector 1750, coef 3(125) Vector + * 1751, Coef 1( 25) */ + -8584, /* Vector 1751, coef 2(222), 3(120) */ + 6613, /* Vector 1752, coef 1( 25), 2(213) */ + 31008, /* Vector 1752, coef 3(121) Vector + * 1753, Coef 1( 32) */ + -11159, /* Vector 1753, coef 2(212), 3(105) */ + 7893, /* Vector 1754, coef 1( 30), 2(213) */ + 26657, /* Vector 1754, coef 3(104) Vector + * 1755, Coef 1( 33) */ + -7282, /* Vector 1755, coef 2(227), 3(142) */ + 8163, /* Vector 1756, coef 1( 31), 2(227) */ + -31200, /* Vector 1756, coef 3(134) Vector + * 1757, Coef 1( 32) */ + -11129, /* Vector 1757, coef 2(212), 3(135) */ + 7653, /* Vector 1758, coef 1( 29), 2(229) */ + -30949, /* Vector 1758, coef 3(135) Vector + * 1759, Coef 1( 27) */ + -10130, /* Vector 1759, coef 2(216), 3(110) */ + 6080, /* Vector 1760, coef 1( 23), 2(192) */ + 27922, /* Vector 1760, coef 3(109) Vector + * 1761, Coef 1( 18) */ + -17297, /* Vector 1761, coef 2(188), 3(111) */ + 3769, /* Vector 1762, coef 1( 14), 2(185) */ + 29202, /* Vector 1762, coef 3(114) Vector + * 1763, Coef 1( 18) */ + -17822, /* Vector 1763, coef 2(186), 3( 98) */ + 7104, /* Vector 1764, coef 1( 27), 2(192) */ + 23831, /* Vector 1764, coef 3( 93) Vector + * 1765, Coef 1( 23) */ + -10893, /* Vector 1765, coef 2(213), 3(115) */ + 8396, /* Vector 1766, coef 1( 32), 2(204) */ + 26653, /* Vector 1766, coef 3(104) Vector + * 1767, Coef 1( 29) */ + -13977, /* Vector 1767, coef 2(201), 3(103) */ + 7120, /* Vector 1768, coef 1( 27), 2(208) */ + 26648, /* Vector 1768, coef 3(104) Vector + * 1769, Coef 1( 24) */ + -13209, /* Vector 1769, coef 2(204), 3(103) */ + 8652, /* Vector 1770, coef 1( 33), 2(204) */ + 24350, /* Vector 1770, coef 3( 95) Vector + * 1771, Coef 1( 30) */ + -14244, /* Vector 1771, coef 2(200), 3( 92) */ + 7113, /* Vector 1772, coef 1( 27), 2(201) */ + 22550, /* Vector 1772, coef 3( 88) Vector + * 1773, Coef 1( 22) */ + -15017, /* Vector 1773, coef 2(197), 3( 87) */ + 6854, /* Vector 1774, coef 1( 26), 2(198) */ + 25365, /* Vector 1774, coef 3( 99) Vector + * 1775, Coef 1( 21) */ + -15520, /* Vector 1775, coef 2(195), 3( 96) */ + 5323, /* Vector 1776, coef 1( 20), 2(203) */ + 24848, /* Vector 1776, coef 3( 97) Vector + * 1777, Coef 1( 16) */ + -15008, /* Vector 1777, coef 2(197), 3( 96) */ + 7113, /* Vector 1778, coef 1( 27), 2(201) */ + 29211, /* Vector 1778, coef 3(114) Vector + * 1779, Coef 1( 27) */ + -11917, /* Vector 1779, coef 2(209), 3(115) */ + 6093, /* Vector 1780, coef 1( 23), 2(205) */ + 29977, /* Vector 1780, coef 3(117) Vector + * 1781, Coef 1( 25) */ + -14215, /* Vector 1781, coef 2(200), 3(121) */ + 5570, /* Vector 1782, coef 1( 21), 2(194) */ + 30225, /* Vector 1782, coef 3(118) Vector + * 1783, Coef 1( 17) */ + -15753, /* Vector 1783, coef 2(194), 3(119) */ + 6090, /* Vector 1784, coef 1( 23), 2(202) */ + 28180, /* Vector 1784, coef 3(110) Vector + * 1785, Coef 1( 20) */ + -14228, /* Vector 1785, coef 2(200), 3(108) */ + 5072, /* Vector 1786, coef 1( 19), 2(208) */ + 28187, /* Vector 1786, coef 3(110) Vector + * 1787, Coef 1( 27) */ + -12452, /* Vector 1787, coef 2(207), 3( 92) */ + 6610, /* Vector 1788, coef 1( 25), 2(210) */ + 23577, /* Vector 1788, coef 3( 92) Vector + * 1789, Coef 1( 25) */ + -10130, /* Vector 1789, coef 2(216), 3(110) */ + 6102, /* Vector 1790, coef 1( 23), 2(214) */ + 26133, /* Vector 1790, coef 3(102) Vector + * 1791, Coef 1( 21) */ + -11160, /* Vector 1791, coef 2(212), 3(104) */ + 9421, /* Vector 1792, coef 1( 36), 2(205) */ + 24102, /* Vector 1792, coef 3( 94) Vector + * 1793, Coef 1( 38) */ + -12718, /* Vector 1793, coef 2(206), 3( 82) */ + 10205, /* Vector 1794, coef 1( 39), 2(221) */ + 27174, /* Vector 1794, coef 3(106) Vector + * 1795, Coef 1( 38) */ + -6555, /* Vector 1795, coef 2(230), 3(101) */ + 9442, /* Vector 1796, coef 1( 36), 2(226) */ + 25648, /* Vector 1796, coef 3(100) Vector + * 1797, Coef 1( 48) */ + -8116, /* Vector 1797, coef 2(224), 3( 76) */ + 11481, /* Vector 1798, coef 1( 44), 2(217) */ + 18736, /* Vector 1798, coef 3( 73) Vector + * 1799, Coef 1( 48) */ + -8387, /* Vector 1799, coef 2(223), 3( 61) */ + 11484, /* Vector 1800, coef 1( 44), 2(220) */ + 13350, /* Vector 1800, coef 3( 52) Vector + * 1801, Coef 1( 38) */ + -11201, /* Vector 1801, coef 2(212), 3( 63) */ + 11233, /* Vector 1802, coef 1( 43), 2(225) */ + 23081, /* Vector 1802, coef 3( 90) Vector + * 1803, Coef 1( 41) */ + -9633, /* Vector 1803, coef 2(218), 3( 95) */ + 11226, /* Vector 1804, coef 1( 43), 2(218) */ + 22312, /* Vector 1804, coef 3( 87) Vector + * 1805, Coef 1( 40) */ + -10925, /* Vector 1805, coef 2(213), 3( 83) */ + 9682, /* Vector 1806, coef 1( 37), 2(210) */ + 22818, /* Vector 1806, coef 3( 89) Vector + * 1807, Coef 1( 34) */ + -12459, /* Vector 1807, coef 2(207), 3( 85) */ + 10207, /* Vector 1808, coef 1( 39), 2(223) */ + 23334, /* Vector 1808, coef 3( 91) Vector + * 1809, Coef 1( 38) */ + -9900, /* Vector 1809, coef 2(217), 3( 84) */ + 9179, /* Vector 1810, coef 1( 35), 2(219) */ + 21796, /* Vector 1810, coef 3( 85) Vector + * 1811, Coef 1( 36) */ + -10653, /* Vector 1811, coef 2(214), 3( 99) */ + 8919, /* Vector 1812, coef 1( 34), 2(215) */ + 24607, /* Vector 1812, coef 3( 96) Vector + * 1813, Coef 1( 31) */ + -11428, /* Vector 1813, coef 2(211), 3( 92) */ + 12003, /* Vector 1814, coef 1( 46), 2(227) */ + 21548, /* Vector 1814, coef 3( 84) Vector + * 1815, Coef 1( 44) */ + -8121, /* Vector 1815, coef 2(224), 3( 71) */ + 11236, /* Vector 1816, coef 1( 43), 2(228) */ + 20007, /* Vector 1816, coef 3( 78) Vector + * 1817, Coef 1( 39) */ + -8629, /* Vector 1817, coef 2(222), 3( 75) */ + 11233, /* Vector 1818, coef 1( 43), 2(225) */ + 15657, /* Vector 1818, coef 3( 61) Vector + * 1819, Coef 1( 41) */ + -8651, /* Vector 1819, coef 2(222), 3( 53) */ + 10458, /* Vector 1820, coef 1( 40), 2(218) */ + 18211, /* Vector 1820, coef 3( 71) Vector + * 1821, Coef 1( 35) */ + -10681, /* Vector 1821, coef 2(214), 3( 71) */ + 9171, /* Vector 1822, coef 1( 35), 2(211) */ + 19495, /* Vector 1822, coef 3( 76) Vector + * 1823, Coef 1( 39) */ + -6829, /* Vector 1823, coef 2(229), 3( 83) */ + 7368, /* Vector 1824, coef 1( 28), 2(200) */ + 17693, /* Vector 1824, coef 3( 69) Vector + * 1825, Coef 1( 29) */ + -12993, /* Vector 1825, coef 2(205), 3( 63) */ + 8915, /* Vector 1826, coef 1( 34), 2(211) */ + 14109, /* Vector 1826, coef 3( 55) Vector + * 1827, Coef 1( 29) */ + -12503, /* Vector 1827, coef 2(207), 3( 41) */ + 8666, /* Vector 1828, coef 1( 33), 2(218) */ + 22050, /* Vector 1828, coef 3( 86) Vector + * 1829, Coef 1( 34) */ + -10434, /* Vector 1829, coef 2(215), 3( 62) */ + 7636, /* Vector 1830, coef 1( 29), 2(212) */ + 13864, /* Vector 1830, coef 3( 54) Vector + * 1831, Coef 1( 40) */ + -6847, /* Vector 1831, coef 2(229), 3( 65) */ + 9695, /* Vector 1832, coef 1( 37), 2(223) */ + 15653, /* Vector 1832, coef 3( 61) Vector + * 1833, Coef 1( 37) */ + -7630, /* Vector 1833, coef 2(226), 3( 50) */ + 7900, /* Vector 1834, coef 1( 30), 2(220) */ + 12321, /* Vector 1834, coef 3( 48) Vector + * 1835, Coef 1( 33) */ + -9915, /* Vector 1835, coef 2(217), 3( 69) */ + 7125, /* Vector 1836, coef 1( 27), 2(213) */ + 17949, /* Vector 1836, coef 3( 70) Vector + * 1837, Coef 1( 29) */ + -9667, /* Vector 1837, coef 2(218), 3( 61) */ + 6101, /* Vector 1838, coef 1( 23), 2(213) */ + 16159, /* Vector 1838, coef 3( 63) Vector + * 1839, Coef 1( 31) */ + -11959, /* Vector 1839, coef 2(209), 3( 73) */ + 8406, /* Vector 1840, coef 1( 32), 2(214) */ + 19995, /* Vector 1840, coef 3( 78) Vector + * 1841, Coef 1( 27) */ + -11694, /* Vector 1841, coef 2(210), 3( 82) */ + 6860, /* Vector 1842, coef 1( 26), 2(204) */ + 19988, /* Vector 1842, coef 3( 78) Vector + * 1843, Coef 1( 20) */ + -13492, /* Vector 1843, coef 2(203), 3( 76) */ + 7386, /* Vector 1844, coef 1( 28), 2(218) */ + 23573, /* Vector 1844, coef 3( 92) Vector + * 1845, Coef 1( 21) */ + -11686, /* Vector 1845, coef 2(210), 3( 90) */ + 6357, /* Vector 1846, coef 1( 24), 2(213) */ + 21014, /* Vector 1846, coef 3( 82) Vector + * 1847, Coef 1( 22) */ + -10675, /* Vector 1847, coef 2(214), 3( 77) */ + 4818, /* Vector 1848, coef 1( 18), 2(210) */ + 21776, /* Vector 1848, coef 3( 85) Vector + * 1849, Coef 1( 16) */ + -11957, /* Vector 1849, coef 2(209), 3( 75) */ + 9442, /* Vector 1850, coef 1( 36), 2(226) */ + 21796, /* Vector 1850, coef 3( 85) Vector + * 1851, Coef 1( 36) */ + -7861, /* Vector 1851, coef 2(225), 3( 75) */ + 8671, /* Vector 1852, coef 1( 33), 2(223) */ + 18975, /* Vector 1852, coef 3( 74) Vector + * 1853, Coef 1( 31) */ + -8875, /* Vector 1853, coef 2(221), 3( 85) */ + 7387, /* Vector 1854, coef 1( 28), 2(219) */ + 20005, /* Vector 1854, coef 3( 78) Vector + * 1855, Coef 1( 37) */ + -6590, /* Vector 1855, coef 2(230), 3( 66) */ + 7136, /* Vector 1856, coef 1( 27), 2(224) */ + 25627, /* Vector 1856, coef 3(100) Vector + * 1857, Coef 1( 27) */ + -6804, /* Vector 1857, coef 2(229), 3(108) */ + 6616, /* Vector 1858, coef 1( 25), 2(216) */ + 24355, /* Vector 1858, coef 3( 95) Vector + * 1859, Coef 1( 35) */ + -6311, /* Vector 1859, coef 2(231), 3( 89) */ + 8419, /* Vector 1860, coef 1( 32), 2(227) */ + 21539, /* Vector 1860, coef 3( 84) Vector + * 1861, Coef 1( 35) */ + -6072, /* Vector 1861, coef 2(232), 3( 72) */ + 8417, /* Vector 1862, coef 1( 32), 2(225) */ + 16924, /* Vector 1862, coef 3( 66) Vector + * 1863, Coef 1( 28) */ + -8129, /* Vector 1863, coef 2(224), 3( 63) */ + 8933, /* Vector 1864, coef 1( 34), 2(229) */ + 14368, /* Vector 1864, coef 3( 56) Vector + * 1865, Coef 1( 32) */ + -7376, /* Vector 1865, coef 2(227), 3( 48) */ + 7133, /* Vector 1866, coef 1( 27), 2(221) */ + 13334, /* Vector 1866, coef 3( 52) Vector + * 1867, Coef 1( 22) */ + -9418, /* Vector 1867, coef 2(219), 3( 54) */ + 8425, /* Vector 1868, coef 1( 32), 2(233) */ + 23325, /* Vector 1868, coef 3( 91) Vector + * 1869, Coef 1( 29) */ + -7080, /* Vector 1869, coef 2(228), 3( 88) */ + 7917, /* Vector 1870, coef 1( 30), 2(237) */ + 21788, /* Vector 1870, coef 3( 85) Vector + * 1871, Coef 1( 28) */ + -6051, /* Vector 1871, coef 2(232), 3( 93) */ + 6113, /* Vector 1872, coef 1( 23), 2(225) */ + 24601, /* Vector 1872, coef 3( 96) Vector + * 1873, Coef 1( 25) */ + -8870, /* Vector 1873, coef 2(221), 3( 90) */ + 5849, /* Vector 1874, coef 1( 22), 2(217) */ + 23318, /* Vector 1874, coef 3( 91) Vector + * 1875, Coef 1( 22) */ + -8366, /* Vector 1875, coef 2(223), 3( 82) */ + 8426, /* Vector 1876, coef 1( 32), 2(234) */ + 19487, /* Vector 1876, coef 3( 76) Vector + * 1877, Coef 1( 31) */ + -6331, /* Vector 1877, coef 2(231), 3( 69) */ + 8425, /* Vector 1878, coef 1( 32), 2(233) */ + 14619, /* Vector 1878, coef 3( 57) Vector + * 1879, Coef 1( 27) */ + -7372, /* Vector 1879, coef 2(227), 3( 52) */ + 7918, /* Vector 1880, coef 1( 30), 2(238) */ + 15900, /* Vector 1880, coef 3( 62) Vector + * 1881, Coef 1( 28) */ + -6086, /* Vector 1881, coef 2(232), 3( 58) */ + 7139, /* Vector 1882, coef 1( 27), 2(227) */ + 19736, /* Vector 1882, coef 3( 77) Vector + * 1883, Coef 1( 24) */ + -8627, /* Vector 1883, coef 2(222), 3( 77) */ + 6364, /* Vector 1884, coef 1( 24), 2(220) */ + 17940, /* Vector 1884, coef 3( 70) Vector + * 1885, Coef 1( 20) */ + -9911, /* Vector 1885, coef 2(217), 3( 73) */ + 6882, /* Vector 1886, coef 1( 26), 2(226) */ + 16408, /* Vector 1886, coef 3( 64) Vector + * 1887, Coef 1( 24) */ + -8342, /* Vector 1887, coef 2(223), 3(106) */ + 6631, /* Vector 1888, coef 1( 25), 2(231) */ + 28700, /* Vector 1888, coef 3(112) Vector + * 1889, Coef 1( 28) */ + -5554, /* Vector 1889, coef 2(234), 3( 78) */ + 6631, /* Vector 1890, coef 1( 25), 2(231) */ + 23061, /* Vector 1890, coef 3( 90) Vector + * 1891, Coef 1( 21) */ + -7846, /* Vector 1891, coef 2(225), 3( 90) */ + 5083, /* Vector 1892, coef 1( 19), 2(219) */ + 22032, /* Vector 1892, coef 3( 86) Vector + * 1893, Coef 1( 16) */ + -9127, /* Vector 1893, coef 2(220), 3( 89) */ + 7147, /* Vector 1894, coef 1( 27), 2(235) */ + 13082, /* Vector 1894, coef 3( 51) Vector + * 1895, Coef 1( 26) */ + -6099, /* Vector 1895, coef 2(232), 3( 45) */ + 5856, /* Vector 1896, coef 1( 22), 2(224) */ + 15125, /* Vector 1896, coef 3( 59) Vector + * 1897, Coef 1( 21) */ + -8635, /* Vector 1897, coef 2(222), 3( 69) */ + 4313, /* Vector 1898, coef 1( 16), 2(217) */ + 18713, /* Vector 1898, coef 3( 73) Vector + * 1899, Coef 1( 25) */ + -5049, /* Vector 1899, coef 2(236), 3( 71) */ + 6118, /* Vector 1900, coef 1( 23), 2(230) */ + 20247, /* Vector 1900, coef 3( 79) Vector + * 1901, Coef 1( 23) */ + -5293, /* Vector 1901, coef 2(235), 3( 83) */ + 5610, /* Vector 1902, coef 1( 21), 2(234) */ + 19734, /* Vector 1902, coef 3( 77) Vector + * 1903, Coef 1( 22) */ + -7352, /* Vector 1903, coef 2(227), 3( 72) */ + 5090, /* Vector 1904, coef 1( 19), 2(226) */ + 19731, /* Vector 1904, coef 3( 77) Vector + * 1905, Coef 1( 19) */ + -6583, /* Vector 1905, coef 2(230), 3( 73) */ + 4321, /* Vector 1906, coef 1( 16), 2(225) */ + 19483, /* Vector 1906, coef 3( 76) Vector + * 1907, Coef 1( 27) */ + -4552, /* Vector 1907, coef 2(238), 3( 56) */ + 6123, /* Vector 1908, coef 1( 23), 2(235) */ + 12055, /* Vector 1908, coef 3( 47) Vector + * 1909, Coef 1( 23) */ + -6340, /* Vector 1909, coef 2(231), 3( 60) */ + 5093, /* Vector 1910, coef 1( 19), 2(229) */ + 15381, /* Vector 1910, coef 3( 60) Vector + * 1911, Coef 1( 21) */ + -4543, /* Vector 1911, coef 2(238), 3( 65) */ + 4843, /* Vector 1912, coef 1( 18), 2(235) */ + 16660, /* Vector 1912, coef 3( 65) Vector + * 1913, Coef 1( 20) */ + -5330, /* Vector 1913, coef 2(235), 3( 46) */ + 4846, /* Vector 1914, coef 1( 18), 2(238) */ + 12567, /* Vector 1914, coef 3( 49) Vector + * 1915, Coef 1( 23) */ + -5537, /* Vector 1915, coef 2(234), 3( 95) */ + 5612, /* Vector 1916, coef 1( 21), 2(236) */ + 25619, /* Vector 1916, coef 3(100) Vector + * 1917, Coef 1( 19) */ + -6825, /* Vector 1917, coef 2(229), 3( 87) */ + 5361, /* Vector 1918, coef 1( 20), 2(241) */ + 21519, /* Vector 1918, coef 3( 84) Vector + * 1919, Coef 1( 15) */ + -5565, /* Vector 1919, coef 2(234), 3( 67) */ + 8651, /* Vector 1920, coef 1( 33), 2(203) */ + -29153, /* Vector 1920, coef 3(142) Vector + * 1921, Coef 1( 31) */ + -11866, /* Vector 1921, coef 2(209), 3(166) */ + 7882, /* Vector 1922, coef 1( 30), 2(202) */ + -22501, /* Vector 1922, coef 3(168) Vector + * 1923, Coef 1( 27) */ + -13394, /* Vector 1923, coef 2(203), 3(174) */ + 6860, /* Vector 1924, coef 1( 26), 2(204) */ + -23525, /* Vector 1924, coef 3(164) Vector + * 1925, Coef 1( 27) */ + -18023, /* Vector 1925, coef 2(185), 3(153) */ + 6336, /* Vector 1926, coef 1( 24), 2(192) */ + -26337, /* Vector 1926, coef 3(153) Vector + * 1927, Coef 1( 31) */ + -9323, /* Vector 1927, coef 2(219), 3(149) */ + 7899, /* Vector 1928, coef 1( 30), 2(219) */ + -28386, /* Vector 1928, coef 3(145) Vector + * 1929, Coef 1( 30) */ + -11385, /* Vector 1929, coef 2(211), 3(135) */ + 7133, /* Vector 1930, coef 1( 27), 2(221) */ + -29154, /* Vector 1930, coef 3(142) Vector + * 1931, Coef 1( 30) */ + -11881, /* Vector 1931, coef 2(209), 3(151) */ + 7383, /* Vector 1932, coef 1( 28), 2(215) */ + -26596, /* Vector 1932, coef 3(152) Vector + * 1933, Coef 1( 28) */ + -14184, /* Vector 1933, coef 2(200), 3(152) */ + 6857, /* Vector 1934, coef 1( 26), 2(201) */ + -27110, /* Vector 1934, coef 3(150) Vector + * 1935, Coef 1( 26) */ + -8553, /* Vector 1935, coef 2(222), 3(151) */ + 6369, /* Vector 1936, coef 1( 24), 2(225) */ + -27625, /* Vector 1936, coef 3(148) Vector + * 1937, Coef 1( 23) */ + -9825, /* Vector 1937, coef 2(217), 3(159) */ + 5855, /* Vector 1938, coef 1( 22), 2(223) */ + -26849, /* Vector 1938, coef 3(151) Vector + * 1939, Coef 1( 31) */ + -16491, /* Vector 1939, coef 2(191), 3(149) */ + 8123, /* Vector 1940, coef 1( 31), 2(187) */ + -29412, /* Vector 1940, coef 3(141) Vector + * 1941, Coef 1( 28) */ + -16758, /* Vector 1941, coef 2(190), 3(138) */ + 7882, /* Vector 1942, coef 1( 30), 2(202) */ + -29156, /* Vector 1942, coef 3(142) Vector + * 1943, Coef 1( 28) */ + -13945, /* Vector 1943, coef 2(201), 3(135) */ + 6856, /* Vector 1944, coef 1( 26), 2(200) */ + -32233, /* Vector 1944, coef 3(130) Vector + * 1945, Coef 1( 23) */ + -13438, /* Vector 1945, coef 2(203), 3(130) */ + 6857, /* Vector 1946, coef 1( 26), 2(201) */ + -29160, /* Vector 1946, coef 3(142) Vector + * 1947, Coef 1( 24) */ + -15730, /* Vector 1947, coef 2(194), 3(142) */ + 6872, /* Vector 1948, coef 1( 26), 2(216) */ + -31719, /* Vector 1948, coef 3(132) Vector + * 1949, Coef 1( 25) */ + -10869, /* Vector 1949, coef 2(213), 3(139) */ + 6360, /* Vector 1950, coef 1( 24), 2(216) */ + -31210, /* Vector 1950, coef 3(134) Vector + * 1951, Coef 1( 22) */ + -11122, /* Vector 1951, coef 2(212), 3(142) */ + 5822, /* Vector 1952, coef 1( 22), 2(190) */ + -31727, /* Vector 1952, coef 3(132) Vector + * 1953, Coef 1( 17) */ + -17269, /* Vector 1953, coef 2(188), 3(139) */ + 3261, /* Vector 1954, coef 1( 12), 2(189) */ + -31735, /* Vector 1954, coef 3(132) Vector + * 1955, Coef 1( 9) */ + -13401, /* Vector 1955, coef 2(203), 3(167) */ + 5575, /* Vector 1956, coef 1( 21), 2(199) */ + 31762, /* Vector 1956, coef 3(124) Vector + * 1957, Coef 1( 18) */ + -13193, /* Vector 1957, coef 2(204), 3(119) */ + 4041, /* Vector 1958, coef 1( 15), 2(201) */ + 30742, /* Vector 1958, coef 3(120) Vector + * 1959, Coef 1( 22) */ + -13430, /* Vector 1959, coef 2(203), 3(138) */ + 5317, /* Vector 1960, coef 1( 20), 2(197) */ + -29164, /* Vector 1960, coef 3(142) Vector + * 1961, Coef 1( 20) */ + -14715, /* Vector 1961, coef 2(198), 3(133) */ + 4809, /* Vector 1962, coef 1( 18), 2(201) */ + -30191, /* Vector 1962, coef 3(138) Vector + * 1963, Coef 1( 17) */ + -15743, /* Vector 1963, coef 2(194), 3(129) */ + 4039, /* Vector 1964, coef 1( 15), 2(199) */ + -31980, /* Vector 1964, coef 3(131) Vector + * 1965, Coef 1( 20) */ + -10615, /* Vector 1965, coef 2(214), 3(137) */ + 5088, /* Vector 1966, coef 1( 19), 2(224) */ + -29167, /* Vector 1966, coef 3(142) Vector + * 1967, Coef 1( 17) */ + -10100, /* Vector 1967, coef 2(216), 3(140) */ + 5584, /* Vector 1968, coef 1( 21), 2(208) */ + -32237, /* Vector 1968, coef 3(130) Vector + * 1969, Coef 1( 19) */ + -12419, /* Vector 1969, coef 2(207), 3(125) */ + 4307, /* Vector 1970, coef 1( 16), 2(211) */ + 31761, /* Vector 1970, coef 3(124) Vector + * 1971, Coef 1( 17) */ + -11643, /* Vector 1971, coef 2(210), 3(133) */ + 4311, /* Vector 1972, coef 1( 16), 2(215) */ + -31218, /* Vector 1972, coef 3(134) Vector + * 1973, Coef 1( 14) */ + -10620, /* Vector 1973, coef 2(214), 3(132) */ + 3023, /* Vector 1974, coef 1( 11), 2(207) */ + -32240, /* Vector 1974, coef 3(130) Vector + * 1975, Coef 1( 16) */ + -13428, /* Vector 1975, coef 2(203), 3(140) */ + 3786, /* Vector 1976, coef 1( 14), 2(202) */ + -29168, /* Vector 1976, coef 3(142) Vector + * 1977, Coef 1( 16) */ + -7795, /* Vector 1977, coef 2(225), 3(141) */ + 4058, /* Vector 1978, coef 1( 15), 2(218) */ + -29427, /* Vector 1978, coef 3(141) Vector + * 1979, Coef 1( 13) */ + -7278, /* Vector 1979, coef 2(227), 3(146) */ + 3536, /* Vector 1980, coef 1( 13), 2(208) */ + -26869, /* Vector 1980, coef 3(151) Vector + * 1981, Coef 1( 11) */ + -11885, /* Vector 1981, coef 2(209), 3(147) */ + 2783, /* Vector 1982, coef 1( 10), 2(223) */ + -28910, /* Vector 1982, coef 3(143) Vector + * 1983, Coef 1( 18) */ + -8831, /* Vector 1983, coef 2(221), 3(129) */ + 6103, /* Vector 1984, coef 1( 23), 2(215) */ + 31252, /* Vector 1984, coef 3(122) Vector + * 1985, Coef 1( 20) */ + -11148, /* Vector 1985, coef 2(212), 3(116) */ + 4561, /* Vector 1986, coef 1( 17), 2(209) */ + 28175, /* Vector 1986, coef 3(110) Vector + * 1987, Coef 1( 15) */ + -12689, /* Vector 1987, coef 2(206), 3(111) */ + 3276, /* Vector 1988, coef 1( 12), 2(204) */ + 27670, /* Vector 1988, coef 3(108) Vector + * 1989, Coef 1( 22) */ + -9086, /* Vector 1989, coef 2(220), 3(130) */ + 4823, /* Vector 1990, coef 1( 18), 2(215) */ + 31510, /* Vector 1990, coef 3(123) Vector + * 1991, Coef 1( 22) */ + -9111, /* Vector 1991, coef 2(220), 3(105) */ + 5078, /* Vector 1992, coef 1( 19), 2(214) */ + 26128, /* Vector 1992, coef 3(102) Vector + * 1993, Coef 1( 16) */ + -11165, /* Vector 1993, coef 2(212), 3( 99) */ + 5861, /* Vector 1994, coef 1( 22), 2(229) */ + 30484, /* Vector 1994, coef 3(119) Vector + * 1995, Coef 1( 20) */ + -8076, /* Vector 1995, coef 2(224), 3(116) */ + 5081, /* Vector 1996, coef 1( 19), 2(217) */ + 28945, /* Vector 1996, coef 3(113) Vector + * 1997, Coef 1( 17) */ + -9357, /* Vector 1997, coef 2(219), 3(115) */ + 4577, /* Vector 1998, coef 1( 17), 2(225) */ + 27151, /* Vector 1998, coef 3(106) Vector + * 1999, Coef 1( 15) */ + -7831, /* Vector 1999, coef 2(225), 3(105) */ + 4311, /* Vector 2000, coef 1( 16), 2(215) */ + 28685, /* Vector 2000, coef 3(112) Vector + * 2001, Coef 1( 13) */ + -10381, /* Vector 2001, coef 2(215), 3(115) */ + 5601, /* Vector 2002, coef 1( 21), 2(225) */ + 32530, /* Vector 2002, coef 3(127) Vector + * 2003, Coef 1( 18) */ + -5754, /* Vector 2003, coef 2(233), 3(134) */ + 4323, /* Vector 2004, coef 1( 16), 2(227) */ + -31982, /* Vector 2004, coef 3(131) Vector + * 2005, Coef 1( 18) */ + -7049, /* Vector 2005, coef 2(228), 3(119) */ + 4325, /* Vector 2006, coef 1( 16), 2(229) */ + 30480, /* Vector 2006, coef 3(119) Vector + * 2007, Coef 1( 16) */ + -6533, /* Vector 2007, coef 2(230), 3(123) */ + 4074, /* Vector 2008, coef 1( 15), 2(234) */ + 30480, /* Vector 2008, coef 3(119) Vector + * 2009, Coef 1( 16) */ + -9349, /* Vector 2009, coef 2(219), 3(123) */ + 4064, /* Vector 2010, coef 1( 15), 2(224) */ + 29710, /* Vector 2010, coef 3(116) Vector + * 2011, Coef 1( 14) */ + -7294, /* Vector 2011, coef 2(227), 3(130) */ + 3548, /* Vector 2012, coef 1( 13), 2(220) */ + 31757, /* Vector 2012, coef 3(124) Vector + * 2013, Coef 1( 13) */ + -6277, /* Vector 2013, coef 2(231), 3(123) */ + 3301, /* Vector 2014, coef 1( 12), 2(229) */ + -32236, /* Vector 2014, coef 3(130) Vector + * 2015, Coef 1( 20) */ + -7321, /* Vector 2015, coef 2(227), 3(103) */ + 5341, /* Vector 2016, coef 1( 20), 2(221) */ + 24849, /* Vector 2016, coef 3( 97) Vector + * 2017, Coef 1( 17) */ + -8609, /* Vector 2017, coef 2(222), 3( 95) */ + 3291, /* Vector 2018, coef 1( 12), 2(219) */ + 24072, /* Vector 2018, coef 3( 94) Vector + * 2019, Coef 1( 8) */ + -9588, /* Vector 2019, coef 2(218), 3(140) */ + 3304, /* Vector 2020, coef 1( 12), 2(232) */ + 29706, /* Vector 2020, coef 3(116) Vector + * 2021, Coef 1( 10) */ + -7809, /* Vector 2021, coef 2(225), 3(127) */ + 5094, /* Vector 2022, coef 1( 19), 2(230) */ + 24593, /* Vector 2022, coef 3( 96) Vector + * 2023, Coef 1( 17) */ + -6314, /* Vector 2023, coef 2(231), 3( 86) */ + 4586, /* Vector 2024, coef 1( 17), 2(234) */ + 24079, /* Vector 2024, coef 3( 94) Vector + * 2025, Coef 1( 15) */ + -6561, /* Vector 2025, coef 2(230), 3( 95) */ + 5098, /* Vector 2026, coef 1( 19), 2(234) */ + 27153, /* Vector 2026, coef 3(106) Vector + * 2027, Coef 1( 17) */ + -5780, /* Vector 2027, coef 2(233), 3(108) */ + 4593, /* Vector 2028, coef 1( 17), 2(241) */ + 25360, /* Vector 2028, coef 3( 99) Vector + * 2029, Coef 1( 16) */ + -4506, /* Vector 2029, coef 2(238), 3(102) */ + 4329, /* Vector 2030, coef 1( 16), 2(233) */ + 28687, /* Vector 2030, coef 3(112) Vector + * 2031, Coef 1( 15) */ + -5268, /* Vector 2031, coef 2(235), 3(108) */ + 3562, /* Vector 2032, coef 1( 13), 2(234) */ + 26891, /* Vector 2032, coef 3(105) Vector + * 2033, Coef 1( 11) */ + -5524, /* Vector 2033, coef 2(234), 3(108) */ + 4850, /* Vector 2034, coef 1( 18), 2(242) */ + 18193, /* Vector 2034, coef 3( 71) Vector + * 2035, Coef 1( 17) */ + -5298, /* Vector 2035, coef 2(235), 3( 78) */ + 4594, /* Vector 2036, coef 1( 17), 2(242) */ + 22032, /* Vector 2036, coef 3( 86) Vector + * 2037, Coef 1( 16) */ + -3252, /* Vector 2037, coef 2(243), 3( 76) */ + 4335, /* Vector 2038, coef 1( 16), 2(239) */ + 23823, /* Vector 2038, coef 3( 93) Vector + * 2039, Coef 1( 15) */ + -4007, /* Vector 2039, coef 2(240), 3( 89) */ + 4337, /* Vector 2040, coef 1( 16), 2(241) */ + 13839, /* Vector 2040, coef 3( 54) Vector + * 2041, Coef 1( 15) */ + -3268, /* Vector 2041, coef 2(243), 3( 60) */ + 3571, /* Vector 2042, coef 1( 13), 2(243) */ + 15628, /* Vector 2042, coef 3( 61) Vector + * 2043, Coef 1( 12) */ + -3772, /* Vector 2043, coef 2(241), 3( 68) */ + 3821, /* Vector 2044, coef 1( 14), 2(237) */ + 19981, /* Vector 2044, coef 3( 78) Vector + * 2045, Coef 1( 13) */ + -6058, /* Vector 2045, coef 2(232), 3( 86) */ + 3312, /* Vector 2046, coef 1( 12), 2(240) */ + 21515, /* Vector 2046, coef 3( 84) Vector + * 2047, Coef 1( 11) */ + -4772 /* Vector 2047, coef 2(237), 3( 92) */ +}; + +int16_tRom psrQuant2[QUANT2_NUM_OF_WORDS] = +{ + -15195, /* Vector 0, coef 1(196), 2(165) */ + -24371, /* Vector 0, coef 3(160) Vector 1, + * Coef 1(205) */ + -26463, /* Vector 1, coef 2(152), 3(161) */ + -15723, /* Vector 2, coef 1(194), 2(149) */ + -24381, /* Vector 2, coef 3(160) Vector 3, + * Coef 1(195) */ + -28524, /* Vector 3, coef 2(144), 3(148) */ + -12896, /* Vector 4, coef 1(205), 2(160) */ + -28224, /* Vector 4, coef 3(145) Vector 5, + * Coef 1(192) */ + -25457, /* Vector 5, coef 2(156), 3(143) */ + -15453, /* Vector 6, coef 1(195), 2(163) */ + 32712, /* Vector 6, coef 3(127) Vector 7, + * Coef 1(200) */ + -28494, /* Vector 7, coef 2(144), 3(178) */ + -14965, /* Vector 8, coef 1(197), 2(139) */ + -22574, /* Vector 8, coef 3(167) Vector 9, + * Coef 1(210) */ + -30310, /* Vector 9, coef 2(137), 3(154) */ + -16503, /* Vector 10, coef 1(191), 2(137) */ + -24111, /* Vector 10, coef 3(161) Vector 11, + * Coef 1(209) */ + -28027, /* Vector 11, coef 2(146), 3(133) */ + -18030, /* Vector 12, coef 1(185), 2(146) */ + -24905, /* Vector 12, coef 3(158) Vector 13, + * Coef 1(183) */ + -25189, /* Vector 13, coef 2(157), 3(155) */ + -20583, /* Vector 14, coef 1(175), 2(153) */ + -26445, /* Vector 14, coef 3(152) Vector 15, + * Coef 1(179) */ + -25209, /* Vector 15, coef 2(157), 3(135) */ + -18032, /* Vector 16, coef 1(185), 2(144) */ + -28992, /* Vector 16, coef 3(142) Vector 17, + * Coef 1(192) */ + -28289, /* Vector 17, coef 2(145), 3(127) */ + -17020, /* Vector 18, coef 1(189), 2(132) */ + -24646, /* Vector 18, coef 3(159) Vector 19, + * Coef 1(186) */ + -30058, /* Vector 19, coef 2(138), 3(150) */ + -18301, /* Vector 20, coef 1(184), 2(131) */ + -27961, /* Vector 20, coef 3(146) Vector 21, + * Coef 1(199) */ + -30070, /* Vector 21, coef 2(138), 3(138) */ + -15487, /* Vector 22, coef 1(195), 2(129) */ + -30278, /* Vector 22, coef 3(137) Vector 23, + * Coef 1(186) */ + -31354, /* Vector 23, coef 2(133), 3(134) */ + -18563, /* Vector 24, coef 1(183), 2(125) */ + -31821, /* Vector 24, coef 3(131) Vector 25, + * Coef 1(179) */ + -28543, /* Vector 25, coef 2(144), 3(129) */ + -16771, /* Vector 26, coef 1(190), 2(125) */ + -26695, /* Vector 26, coef 3(151) Vector 27, + * Coef 1(185) */ + 31376, /* Vector 27, coef 2(122), 3(144) */ + -20091, /* Vector 28, coef 1(177), 2(133) */ + -28243, /* Vector 28, coef 3(145) Vector 29, + * Coef 1(173) */ + -32374, /* Vector 29, coef 2(129), 3(138) */ + -19572, /* Vector 30, coef 1(179), 2(140) */ + -24912, /* Vector 30, coef 3(158) Vector 31, + * Coef 1(176) */ + -28525, /* Vector 31, coef 2(144), 3(147) */ + -14952, /* Vector 32, coef 1(197), 2(152) */ + 27829, /* Vector 32, coef 3(108) Vector 33, + * Coef 1(181) */ + -25753, /* Vector 33, coef 2(155), 3(103) */ + -19319, /* Vector 34, coef 1(180), 2(137) */ + 27823, /* Vector 34, coef 3(108) Vector 35, + * Coef 1(175) */ + -31399, /* Vector 35, coef 2(133), 3( 89) */ + -16009, /* Vector 36, coef 1(193), 2(119) */ + -32046, /* Vector 36, coef 3(130) Vector 37, + * Coef 1(210) */ + -32639, /* Vector 37, coef 2(128), 3(129) */ + -13433, /* Vector 38, coef 1(203), 2(135) */ + 30656, /* Vector 38, coef 3(119) Vector 39, + * Coef 1(192) */ + -32394, /* Vector 39, coef 2(129), 3(118) */ + -13710, /* Vector 40, coef 1(202), 2(114) */ + 31424, /* Vector 40, coef 3(122) Vector 41, + * Coef 1(192) */ + 26745, /* Vector 41, coef 2(104), 3(121) */ + -12160, /* Vector 42, coef 1(208), 2(128) */ + 27075, /* Vector 42, coef 3(105) Vector 43, + * Coef 1(195) */ + 30562, /* Vector 43, coef 2(119), 3( 98) */ + -12955, /* Vector 44, coef 1(205), 2(101) */ + 28092, /* Vector 44, coef 3(109) Vector 45, + * Coef 1(188) */ + 25450, /* Vector 45, coef 2( 99), 3(106) */ + -18057, /* Vector 46, coef 1(185), 2(119) */ + 30385, /* Vector 46, coef 3(118) Vector 47, + * Coef 1(177) */ + 30572, /* Vector 47, coef 2(119), 3(108) */ + -21135, /* Vector 48, coef 1(173), 2(113) */ + 31655, /* Vector 48, coef 3(123) Vector 49, + * Coef 1(167) */ + 26981, /* Vector 49, coef 2(105), 3(101) */ + -20609, /* Vector 50, coef 1(175), 2(127) */ + 31652, /* Vector 50, coef 3(123) Vector 51, + * Coef 1(164) */ + -30345, /* Vector 51, coef 2(137), 3(119) */ + -23169, /* Vector 52, coef 1(165), 2(127) */ + 28819, /* Vector 52, coef 3(112) Vector 53, + * Coef 1(147) */ + -30865, /* Vector 53, coef 2(135), 3(111) */ + -27781, /* Vector 54, coef 1(147), 2(123) */ + 25765, /* Vector 54, coef 3(100) Vector 55, + * Coef 1(165) */ + 32129, /* Vector 55, coef 2(125), 3(129) */ + -23434, /* Vector 56, coef 1(164), 2(118) */ + 31393, /* Vector 56, coef 3(122) Vector 57, + * Coef 1(161) */ + 29060, /* Vector 57, coef 2(113), 3(132) */ + -25747, /* Vector 58, coef 1(155), 2(109) */ + 32408, /* Vector 58, coef 3(126) Vector 59, + * Coef 1(152) */ + 30582, /* Vector 59, coef 2(119), 3(118) */ + -24979, /* Vector 60, coef 1(158), 2(109) */ + 29092, /* Vector 60, coef 3(113) Vector 61, + * Coef 1(164) */ + 31371, /* Vector 61, coef 2(122), 3(139) */ + -25735, /* Vector 62, coef 1(155), 2(121) */ + -32366, /* Vector 62, coef 3(129) Vector 63, + * Coef 1(146) */ + 32635, /* Vector 63, coef 2(127), 3(123) */ + -14206, /* Vector 64, coef 1(200), 2(130) */ + -27180, /* Vector 64, coef 3(149) Vector 65, + * Coef 1(212) */ + 28811, /* Vector 65, coef 2(112), 3(139) */ + -14463, /* Vector 66, coef 1(199), 2(129) */ + -23358, /* Vector 66, coef 3(164) Vector 67, + * Coef 1(194) */ + 31390, /* Vector 67, coef 2(122), 3(158) */ + -12167, /* Vector 68, coef 1(208), 2(121) */ + -23608, /* Vector 68, coef 3(163) Vector 69, + * Coef 1(200) */ + 29083, /* Vector 69, coef 2(113), 3(155) */ + -14217, /* Vector 70, coef 1(200), 2(119) */ + -28736, /* Vector 70, coef 3(143) Vector 71, + * Coef 1(192) */ + 29071, /* Vector 71, coef 2(113), 3(143) */ + -15497, /* Vector 72, coef 1(195), 2(119) */ + -19261, /* Vector 72, coef 3(180) Vector 73, + * Coef 1(195) */ + 29609, /* Vector 73, coef 2(115), 3(169) */ + -16020, /* Vector 74, coef 1(193), 2(108) */ + -18756, /* Vector 74, coef 3(182) Vector 75, + * Coef 1(188) */ + 29602, /* Vector 75, coef 2(115), 3(162) */ + -17556, /* Vector 76, coef 1(187), 2(108) */ + -25392, /* Vector 76, coef 3(156) Vector 77, + * Coef 1(208) */ + 25505, /* Vector 77, coef 2( 99), 3(161) */ + -18571, /* Vector 78, coef 1(183), 2(117) */ + -26439, /* Vector 78, coef 3(152) Vector 79, + * Coef 1(185) */ + 31910, /* Vector 79, coef 2(124), 3(166) */ + -12448, /* Vector 80, coef 1(207), 2( 96) */ + -31546, /* Vector 80, coef 3(132) Vector 81, + * Coef 1(198) */ + 24471, /* Vector 81, coef 2( 95), 3(151) */ + -15771, /* Vector 82, coef 1(194), 2(101) */ + -22855, /* Vector 82, coef 3(166) Vector 83, + * Coef 1(185) */ + 25246, /* Vector 83, coef 2( 98), 3(158) */ + -13235, /* Vector 84, coef 1(204), 2( 77) */ + -24131, /* Vector 84, coef 3(161) Vector 85, + * Coef 1(189) */ + 20390, /* Vector 85, coef 2( 79), 3(166) */ + -18857, /* Vector 86, coef 1(182), 2( 87) */ + -25931, /* Vector 86, coef 3(154) Vector 87, + * Coef 1(181) */ + 18581, /* Vector 87, coef 2( 72), 3(149) */ + -20397, /* Vector 88, coef 1(176), 2( 83) */ + -20822, /* Vector 88, coef 3(174) Vector 89, + * Coef 1(170) */ + 20888, /* Vector 89, coef 2( 81), 3(152) */ + -20128, /* Vector 90, coef 1(177), 2( 96) */ + -26942, /* Vector 90, coef 3(150) Vector 91, + * Coef 1(194) */ + 26507, /* Vector 91, coef 2(103), 3(139) */ + -17826, /* Vector 92, coef 1(186), 2( 94) */ + -30010, /* Vector 92, coef 3(138) Vector 93, + * Coef 1(198) */ + 21130, /* Vector 93, coef 2( 82), 3(138) */ + -16299, /* Vector 94, coef 1(192), 2( 85) */ + 31665, /* Vector 94, coef 3(123) Vector 95, + * Coef 1(177) */ + 21382, /* Vector 95, coef 2( 83), 3(134) */ + -18062, /* Vector 96, coef 1(185), 2(114) */ + -31053, /* Vector 96, coef 3(134) Vector 97, + * Coef 1(179) */ + 29057, /* Vector 97, coef 2(113), 3(129) */ + -21144, /* Vector 98, coef 1(173), 2(104) */ + -26191, /* Vector 98, coef 3(153) Vector 99, + * Coef 1(177) */ + 28818, /* Vector 99, coef 2(112), 3(146) */ + -18326, /* Vector 100, coef 1(184), 2(106) */ + -28496, /* Vector 100, coef 3(144) Vector + * 101, Coef 1(176) */ + 27020, /* Vector 101, coef 2(105), 3(140) */ + -21923, /* Vector 102, coef 1(170), 2( 93) */ + -28758, /* Vector 102, coef 3(143) Vector + * 103, Coef 1(170) */ + 29331, /* Vector 103, coef 2(114), 3(147) */ + -23185, /* Vector 104, coef 1(165), 2(111) */ + -27741, /* Vector 104, coef 3(147) Vector + * 105, Coef 1(163) */ + 27789, /* Vector 105, coef 2(108), 3(141) */ + -21394, /* Vector 106, coef 1(172), 2(110) */ + -30039, /* Vector 106, coef 3(138) Vector + * 107, Coef 1(169) */ + 26756, /* Vector 107, coef 2(104), 3(132) */ + -18844, /* Vector 108, coef 1(182), 2(100) */ + 32679, /* Vector 108, coef 3(127) Vector + * 109, Coef 1(167) */ + 25746, /* Vector 109, coef 2(100), 3(146) */ + -20359, /* Vector 110, coef 1(176), 2(121) */ + -29525, /* Vector 110, coef 3(140) Vector + * 111, Coef 1(171) */ + 30343, /* Vector 111, coef 2(118), 3(135) */ + -20632, /* Vector 112, coef 1(175), 2(104) */ + 29353, /* Vector 112, coef 3(114) Vector + * 113, Coef 1(169) */ + 17301, /* Vector 113, coef 2( 67), 3(149) */ + -24218, /* Vector 114, coef 1(161), 2(102) */ + -30562, /* Vector 114, coef 3(136) Vector + * 115, Coef 1(158) */ + 25218, /* Vector 115, coef 2( 98), 3(130) */ + -20643, /* Vector 116, coef 1(175), 2( 93) */ + 32434, /* Vector 116, coef 3(126) Vector + * 117, Coef 1(178) */ + 20342, /* Vector 117, coef 2( 79), 3(118) */ + -24228, /* Vector 118, coef 1(161), 2( 92) */ + -28761, /* Vector 118, coef 3(143) Vector + * 119, Coef 1(167) */ + 22661, /* Vector 119, coef 2( 88), 3(133) */ + -24497, /* Vector 120, coef 1(160), 2( 79) */ + -30809, /* Vector 120, coef 3(135) Vector + * 121, Coef 1(167) */ + 26492, /* Vector 121, coef 2(103), 3(124) */ + -23199, /* Vector 122, coef 1(165), 2( 97) */ + 29859, /* Vector 122, coef 3(116) Vector + * 123, Coef 1(163) */ + 22652, /* Vector 123, coef 2( 88), 3(124) */ + -24492, /* Vector 124, coef 1(160), 2( 84) */ + 28567, /* Vector 124, coef 3(111) Vector + * 125, Coef 1(151) */ + 23174, /* Vector 125, coef 2( 90), 3(134) */ + -28086, /* Vector 126, coef 1(146), 2( 74) */ + -31338, /* Vector 126, coef 3(133) Vector + * 127, Coef 1(150) */ + 22650, /* Vector 127, coef 2( 88), 3(122) */ + -14973, /* Vector 128, coef 1(197), 2(131) */ + -18498, /* Vector 128, coef 3(183) Vector + * 129, Coef 1(190) */ + 31664, /* Vector 129, coef 2(123), 3(176) */ + -18291, /* Vector 130, coef 1(184), 2(141) */ + -19021, /* Vector 130, coef 3(181) Vector + * 131, Coef 1(179) */ + -30281, /* Vector 131, coef 2(137), 3(183) */ + -17784, /* Vector 132, coef 1(186), 2(136) */ + -20557, /* Vector 132, coef 3(175) Vector + * 133, Coef 1(179) */ + -31565, /* Vector 133, coef 2(132), 3(179) */ + -21116, /* Vector 134, coef 1(173), 2(132) */ + -20295, /* Vector 134, coef 3(176) Vector + * 135, Coef 1(185) */ + -31041, /* Vector 135, coef 2(134), 3(191) */ + -19844, /* Vector 136, coef 1(178), 2(124) */ + -16454, /* Vector 136, coef 3(191) Vector + * 137, Coef 1(186) */ + -32340, /* Vector 137, coef 2(129), 3(172) */ + -19334, /* Vector 138, coef 1(180), 2(122) */ + -20300, /* Vector 138, coef 3(176) Vector + * 139, Coef 1(180) */ + -30808, /* Vector 139, coef 2(135), 3(168) */ + -21126, /* Vector 140, coef 1(173), 2(122) */ + -19276, /* Vector 140, coef 3(180) Vector + * 141, Coef 1(180) */ + -29271, /* Vector 141, coef 2(141), 3(169) */ + -20861, /* Vector 142, coef 1(174), 2(131) */ + -14164, /* Vector 142, coef 3(200) Vector + * 143, Coef 1(172) */ + 32700, /* Vector 143, coef 2(127), 3(188) */ + -20872, /* Vector 144, coef 1(174), 2(120) */ + -26443, /* Vector 144, coef 3(152) Vector + * 145, Coef 1(181) */ + 31134, /* Vector 145, coef 2(121), 3(158) */ + -20877, /* Vector 146, coef 1(174), 2(115) */ + -24907, /* Vector 146, coef 3(158) Vector + * 147, Coef 1(181) */ + -31585, /* Vector 147, coef 2(132), 3(159) */ + -21113, /* Vector 148, coef 1(173), 2(135) */ + -23381, /* Vector 148, coef 3(164) Vector + * 149, Coef 1(171) */ + -32351, /* Vector 149, coef 2(129), 3(161) */ + -20096, /* Vector 150, coef 1(177), 2(128) */ + -25427, /* Vector 150, coef 3(156) Vector + * 151, Coef 1(173) */ + 32661, /* Vector 151, coef 2(127), 3(149) */ + -22405, /* Vector 152, coef 1(168), 2(123) */ + -25177, /* Vector 152, coef 3(157) Vector + * 153, Coef 1(167) */ + 30869, /* Vector 153, coef 2(120), 3(149) */ + -22912, /* Vector 154, coef 1(166), 2(128) */ + -28756, /* Vector 154, coef 3(143) Vector + * 155, Coef 1(172) */ + 32683, /* Vector 155, coef 2(127), 3(171) */ + -21895, /* Vector 156, coef 1(170), 2(121) */ + -22621, /* Vector 156, coef 3(167) Vector + * 157, Coef 1(163) */ + 32168, /* Vector 157, coef 2(125), 3(168) */ + -21879, /* Vector 158, coef 1(170), 2(137) */ + -25947, /* Vector 158, coef 3(154) Vector + * 159, Coef 1(165) */ + -32103, /* Vector 159, coef 2(130), 3(153) */ + -18583, /* Vector 160, coef 1(183), 2(105) */ + -21325, /* Vector 160, coef 3(172) Vector + * 161, Coef 1(179) */ + 27554, /* Vector 161, coef 2(107), 3(162) */ + -18848, /* Vector 162, coef 1(182), 2( 96) */ + -18511, /* Vector 162, coef 3(183) Vector + * 163, Coef 1(177) */ + 30631, /* Vector 163, coef 2(119), 3(167) */ + -18313, /* Vector 164, coef 1(184), 2(119) */ + -16207, /* Vector 164, coef 3(192) Vector + * 165, Coef 1(177) */ + 29887, /* Vector 165, coef 2(116), 3(191) */ + -18317, /* Vector 166, coef 1(184), 2(115) */ + -20047, /* Vector 166, coef 3(177) Vector + * 167, Coef 1(177) */ + 28590, /* Vector 167, coef 2(111), 3(174) */ + -18835, /* Vector 168, coef 1(182), 2(109) */ + -16209, /* Vector 168, coef 3(192) Vector + * 169, Coef 1(175) */ + 26818, /* Vector 169, coef 2(104), 3(194) */ + -21144, /* Vector 170, coef 1(173), 2(104) */ + -19796, /* Vector 170, coef 3(178) Vector + * 171, Coef 1(172) */ + 29617, /* Vector 171, coef 2(115), 3(177) */ + -21649, /* Vector 172, coef 1(171), 2(111) */ + -22614, /* Vector 172, coef 3(167) Vector + * 173, Coef 1(170) */ + 28098, /* Vector 173, coef 2(109), 3(194) */ + -23705, /* Vector 174, coef 1(163), 2(103) */ + -16471, /* Vector 174, coef 3(191) Vector + * 175, Coef 1(169) */ + 29372, /* Vector 175, coef 2(114), 3(188) */ + -20642, /* Vector 176, coef 1(175), 2( 94) */ + -22105, /* Vector 176, coef 3(169) Vector + * 177, Coef 1(167) */ + 24249, /* Vector 177, coef 2( 94), 3(185) */ + -23208, /* Vector 178, coef 1(165), 2( 88) */ + -21594, /* Vector 178, coef 3(171) Vector + * 179, Coef 1(166) */ + 18602, /* Vector 179, coef 2( 72), 3(170) */ + -22938, /* Vector 180, coef 1(166), 2(102) */ + -20322, /* Vector 180, coef 3(176) Vector + * 181, Coef 1(158) */ + 24510, /* Vector 181, coef 2( 95), 3(190) */ + -24999, /* Vector 182, coef 1(158), 2( 89) */ + -20317, /* Vector 182, coef 3(176) Vector + * 183, Coef 1(163) */ + 26797, /* Vector 183, coef 2(104), 3(173) */ + -25761, /* Vector 184, coef 1(155), 2( 95) */ + -22615, /* Vector 184, coef 3(167) Vector + * 185, Coef 1(169) */ + 25764, /* Vector 185, coef 2(100), 3(164) */ + -23713, /* Vector 186, coef 1(163), 2( 95) */ + -24408, /* Vector 186, coef 3(160) Vector + * 187, Coef 1(168) */ + 22941, /* Vector 187, coef 2( 89), 3(157) */ + -24749, /* Vector 188, coef 1(159), 2( 83) */ + -26463, /* Vector 188, coef 3(152) Vector + * 189, Coef 1(161) */ + 20407, /* Vector 189, coef 2( 79), 3(183) */ + -25787, /* Vector 190, coef 1(155), 2( 69) */ + -20325, /* Vector 190, coef 3(176) Vector + * 191, Coef 1(155) */ + 20643, /* Vector 191, coef 2( 80), 3(163) */ + -23441, /* Vector 192, coef 1(164), 2(111) */ + -21848, /* Vector 192, coef 3(170) Vector + * 193, Coef 1(168) */ + 27808, /* Vector 193, coef 2(108), 3(160) */ + -23698, /* Vector 194, coef 1(163), 2(110) */ + -24925, /* Vector 194, coef 3(158) Vector + * 195, Coef 1(163) */ + 26779, /* Vector 195, coef 2(104), 3(155) */ + -25496, /* Vector 196, coef 1(156), 2(104) */ + -21602, /* Vector 196, coef 3(171) Vector + * 197, Coef 1(158) */ + 31139, /* Vector 197, coef 2(121), 3(163) */ + -22923, /* Vector 198, coef 1(166), 2(117) */ + -23902, /* Vector 198, coef 3(162) Vector + * 199, Coef 1(162) */ + 29851, /* Vector 199, coef 2(116), 3(155) */ + -24709, /* Vector 200, coef 1(159), 2(123) */ + -25188, /* Vector 200, coef 3(157) Vector + * 201, Coef 1(156) */ + 30361, /* Vector 201, coef 2(118), 3(153) */ + -24971, /* Vector 202, coef 1(158), 2(117) */ + -22115, /* Vector 202, coef 3(169) Vector + * 203, Coef 1(157) */ + 28579, /* Vector 203, coef 2(111), 3(163) */ + -26508, /* Vector 204, coef 1(152), 2(116) */ + -24425, /* Vector 204, coef 3(160) Vector + * 205, Coef 1(151) */ + 27555, /* Vector 205, coef 2(107), 3(163) */ + -25233, /* Vector 206, coef 1(157), 2(111) */ + -26724, /* Vector 206, coef 3(151) Vector + * 207, Coef 1(156) */ + 26525, /* Vector 207, coef 2(103), 3(157) */ + -27023, /* Vector 208, coef 1(150), 2(113) */ + -26223, /* Vector 208, coef 3(153) Vector + * 209, Coef 1(145) */ + 26785, /* Vector 209, coef 2(104), 3(161) */ + -27289, /* Vector 210, coef 1(149), 2(103) */ + -25971, /* Vector 210, coef 3(154) Vector + * 211, Coef 1(141) */ + 25238, /* Vector 211, coef 2( 98), 3(150) */ + -24717, /* Vector 212, coef 1(159), 2(115) */ + -29033, /* Vector 212, coef 3(142) Vector + * 213, Coef 1(151) */ + 27795, /* Vector 213, coef 2(108), 3(147) */ + -26766, /* Vector 214, coef 1(151), 2(114) */ + -29797, /* Vector 214, coef 3(139) Vector + * 215, Coef 1(155) */ + 27531, /* Vector 215, coef 2(107), 3(139) */ + -27799, /* Vector 216, coef 1(147), 2(105) */ + -29281, /* Vector 216, coef 3(141) Vector + * 217, Coef 1(159) */ + 26259, /* Vector 217, coef 2(102), 3(147) */ + -25760, /* Vector 218, coef 1(155), 2( 96) */ + -26475, /* Vector 218, coef 3(152) Vector + * 219, Coef 1(149) */ + 24467, /* Vector 219, coef 2( 95), 3(147) */ + -26270, /* Vector 220, coef 1(153), 2( 98) */ + -29804, /* Vector 220, coef 3(139) Vector + * 221, Coef 1(148) */ + 21905, /* Vector 221, coef 2( 85), 3(145) */ + -28821, /* Vector 222, coef 1(143), 2(107) */ + -27246, /* Vector 222, coef 3(149) Vector + * 223, Coef 1(146) */ + 27525, /* Vector 223, coef 2(107), 3(133) */ + -27300, /* Vector 224, coef 1(149), 2( 92) */ + -24174, /* Vector 224, coef 3(161) Vector + * 225, Coef 1(146) */ + 19357, /* Vector 225, coef 2( 75), 3(157) */ + -26270, /* Vector 226, coef 1(153), 2( 98) */ + -18542, /* Vector 226, coef 3(183) Vector + * 227, Coef 1(146) */ + 25534, /* Vector 227, coef 2( 99), 3(190) */ + -27813, /* Vector 228, coef 1(147), 2( 91) */ + -19562, /* Vector 228, coef 3(179) Vector + * 229, Coef 1(150) */ + 23236, /* Vector 229, coef 2( 90), 3(196) */ + -27570, /* Vector 230, coef 1(148), 2( 78) */ + -18031, /* Vector 230, coef 3(185) Vector + * 231, Coef 1(145) */ + 21168, /* Vector 231, coef 2( 82), 3(176) */ + -30129, /* Vector 232, coef 1(138), 2( 79) */ + -21102, /* Vector 232, coef 3(173) Vector + * 233, Coef 1(146) */ + 25514, /* Vector 233, coef 2( 99), 3(170) */ + -29600, /* Vector 234, coef 1(140), 2( 96) */ + -23410, /* Vector 234, coef 3(164) Vector + * 235, Coef 1(142) */ + 22941, /* Vector 235, coef 2( 89), 3(157) */ + -30888, /* Vector 236, coef 1(135), 2( 88) */ + -21376, /* Vector 236, coef 3(172) Vector + * 237, Coef 1(128) */ + 19109, /* Vector 237, coef 2( 74), 3(165) */ + -29345, /* Vector 238, coef 1(141), 2( 95) */ + -15739, /* Vector 238, coef 3(194) Vector + * 239, Coef 1(133) */ + 22463, /* Vector 239, coef 2( 87), 3(191) */ + -28565, /* Vector 240, coef 1(144), 2(107) */ + 30605, /* Vector 240, coef 3(119) Vector + * 241, Coef 1(141) */ + 25707, /* Vector 241, coef 2(100), 3(107) */ + -30123, /* Vector 242, coef 1(138), 2( 85) */ + -27262, /* Vector 242, coef 3(149) Vector + * 243, Coef 1(130) */ + 21395, /* Vector 243, coef 2( 83), 3(147) */ + -30611, /* Vector 244, coef 1(136), 2(109) */ + -28280, /* Vector 244, coef 3(145) Vector + * 245, Coef 1(136) */ + 25997, /* Vector 245, coef 2(101), 3(141) */ + -32671, /* Vector 246, coef 1(128), 2( 97) */ + -28552, /* Vector 246, coef 3(144) Vector + * 247, Coef 1(120) */ + 23944, /* Vector 247, coef 2( 93), 3(136) */ + -28317, /* Vector 248, coef 1(145), 2( 99) */ + 32647, /* Vector 248, coef 3(127) Vector + * 249, Coef 1(135) */ + 27523, /* Vector 249, coef 2(107), 3(131) */ + -32667, /* Vector 250, coef 1(128), 2(101) */ + 31375, /* Vector 250, coef 3(122) Vector + * 251, Coef 1(143) */ + 24458, /* Vector 251, coef 2( 95), 3(138) */ + -30374, /* Vector 252, coef 1(137), 2( 90) */ + -31093, /* Vector 252, coef 3(134) Vector + * 253, Coef 1(139) */ + 21113, /* Vector 253, coef 2( 82), 3(121) */ + 32620, /* Vector 254, coef 1(127), 2(108) */ + -30609, /* Vector 254, coef 3(136) Vector + * 255, Coef 1(111) */ + 24182, /* Vector 255, coef 2( 94), 3(118) */ + -14939, /* Vector 256, coef 1(197), 2(165) */ + -20545, /* Vector 256, coef 3(175) Vector + * 257, Coef 1(191) */ + -25933, /* Vector 257, coef 2(154), 3(179) */ + -19049, /* Vector 258, coef 1(181), 2(151) */ + -22085, /* Vector 258, coef 3(169) Vector + * 259, Coef 1(187) */ + -28481, /* Vector 259, coef 2(144), 3(191) */ + -19548, /* Vector 260, coef 1(179), 2(164) */ + -17488, /* Vector 260, coef 3(187) Vector + * 261, Coef 1(176) */ + -25160, /* Vector 261, coef 2(157), 3(184) */ + -19560, /* Vector 262, coef 1(179), 2(152) */ + -15444, /* Vector 262, coef 3(195) Vector + * 263, Coef 1(172) */ + -27207, /* Vector 263, coef 2(149), 3(185) */ + -20058, /* Vector 264, coef 1(177), 2(166) */ + -23120, /* Vector 264, coef 3(165) Vector + * 265, Coef 1(176) */ + -25176, /* Vector 265, coef 2(157), 3(168) */ + -21864, /* Vector 266, coef 1(170), 2(152) */ + -20552, /* Vector 266, coef 3(175) Vector + * 267, Coef 1(184) */ + -27986, /* Vector 267, coef 2(146), 3(174) */ + -20333, /* Vector 268, coef 1(176), 2(147) */ + -23378, /* Vector 268, coef 3(164) Vector + * 269, Coef 1(174) */ + -29006, /* Vector 269, coef 2(142), 3(178) */ + -23902, /* Vector 270, coef 1(162), 2(162) */ + -16993, /* Vector 270, coef 3(189) Vector + * 271, Coef 1(159) */ + -25166, /* Vector 271, coef 2(157), 3(178) */ + -19024, /* Vector 272, coef 1(181), 2(176) */ + -27987, /* Vector 272, coef 3(146) Vector + * 273, Coef 1(173) */ + -22132, /* Vector 273, coef 2(169), 3(140) */ + -23624, /* Vector 274, coef 1(163), 2(184) */ + -27741, /* Vector 274, coef 3(147) Vector + * 275, Coef 1(163) */ + -22898, /* Vector 275, coef 2(166), 3(142) */ + -19531, /* Vector 276, coef 1(179), 2(181) */ + 32172, /* Vector 276, coef 3(125) Vector + * 277, Coef 1(172) */ + -20306, /* Vector 277, coef 2(176), 3(174) */ + -23890, /* Vector 278, coef 1(162), 2(174) */ + -22375, /* Vector 278, coef 3(168) Vector + * 279, Coef 1(153) */ + -19034, /* Vector 279, coef 2(181), 3(166) */ + -25945, /* Vector 280, coef 1(154), 2(167) */ + -23642, /* Vector 280, coef 3(163) Vector + * 281, Coef 1(166) */ + -23393, /* Vector 281, coef 2(164), 3(159) */ + -23654, /* Vector 282, coef 1(163), 2(154) */ + -25703, /* Vector 282, coef 3(155) Vector + * 283, Coef 1(153) */ + -23911, /* Vector 283, coef 2(162), 3(153) */ + -28749, /* Vector 284, coef 1(143), 2(179) */ + -26219, /* Vector 284, coef 3(153) Vector + * 285, Coef 1(149) */ + -21116, /* Vector 285, coef 2(173), 3(132) */ + -26709, /* Vector 286, coef 1(151), 2(171) */ + -18027, /* Vector 286, coef 3(185) Vector + * 287, Coef 1(149) */ + -22866, /* Vector 287, coef 2(166), 3(174) */ + -20340, /* Vector 288, coef 1(176), 2(140) */ + -15956, /* Vector 288, coef 3(193) Vector + * 289, Coef 1(172) */ + -31045, /* Vector 289, coef 2(134), 3(187) */ + -22127, /* Vector 290, coef 1(169), 2(145) */ + -21336, /* Vector 290, coef 3(172) Vector + * 291, Coef 1(168) */ + -27962, /* Vector 291, coef 2(146), 3(198) */ + -22642, /* Vector 292, coef 1(167), 2(142) */ + -17498, /* Vector 292, coef 3(187) Vector + * 293, Coef 1(166) */ + -30268, /* Vector 293, coef 2(137), 3(196) */ + -24694, /* Vector 294, coef 1(159), 2(138) */ + -18009, /* Vector 294, coef 3(185) Vector + * 295, Coef 1(167) */ + -30291, /* Vector 295, coef 2(137), 3(173) */ + -23420, /* Vector 296, coef 1(164), 2(132) */ + -19299, /* Vector 296, coef 3(180) Vector + * 297, Coef 1(157) */ + -30775, /* Vector 297, coef 2(135), 3(201) */ + -26744, /* Vector 298, coef 1(151), 2(136) */ + -16988, /* Vector 298, coef 3(189) Vector + * 299, Coef 1(164) */ + -31809, /* Vector 299, coef 2(131), 3(191) */ + -24683, /* Vector 300, coef 1(159), 2(149) */ + -15455, /* Vector 300, coef 3(195) Vector + * 301, Coef 1(161) */ + -28231, /* Vector 301, coef 2(145), 3(185) */ + -25453, /* Vector 302, coef 1(156), 2(147) */ + -20078, /* Vector 302, coef 3(177) Vector + * 303, Coef 1(146) */ + -31290, /* Vector 303, coef 2(133), 3(198) */ + -25463, /* Vector 304, coef 1(156), 2(137) */ + -20586, /* Vector 304, coef 3(175) Vector + * 305, Coef 1(150) */ + -31830, /* Vector 305, coef 2(131), 3(170) */ + -28285, /* Vector 306, coef 1(145), 2(131) */ + -20082, /* Vector 306, coef 3(177) Vector + * 307, Coef 1(142) */ + -31577, /* Vector 307, coef 2(132), 3(167) */ + -24426, /* Vector 308, coef 1(160), 2(150) */ + -22881, /* Vector 308, coef 3(166) Vector + * 309, Coef 1(159) */ + -29274, /* Vector 309, coef 2(141), 3(166) */ + -25714, /* Vector 310, coef 1(155), 2(142) */ + -24669, /* Vector 310, coef 3(159) Vector + * 311, Coef 1(163) */ + -30812, /* Vector 311, coef 2(135), 3(164) */ + -24702, /* Vector 312, coef 1(159), 2(130) */ + -23908, /* Vector 312, coef 3(162) Vector + * 313, Coef 1(156) */ + -31331, /* Vector 313, coef 2(133), 3(157) */ + -28014, /* Vector 314, coef 1(146), 2(146) */ + -26220, /* Vector 314, coef 3(153) Vector + * 315, Coef 1(148) */ + -30306, /* Vector 315, coef 2(137), 3(158) */ + -25984, /* Vector 316, coef 1(154), 2(128) */ + -22119, /* Vector 316, coef 3(169) Vector + * 317, Coef 1(153) */ + 32162, /* Vector 317, coef 2(125), 3(162) */ + -27776, /* Vector 318, coef 1(147), 2(128) */ + -24170, /* Vector 318, coef 3(161) Vector + * 319, Coef 1(150) */ + -29266, /* Vector 319, coef 2(141), 3(174) */ + -20335, /* Vector 320, coef 1(176), 2(145) */ + 30637, /* Vector 320, coef 3(119) Vector + * 321, Coef 1(173) */ + -31102, /* Vector 321, coef 2(134), 3(130) */ + -22384, /* Vector 322, coef 1(168), 2(144) */ + -24670, /* Vector 322, coef 3(159) Vector + * 323, Coef 1(162) */ + -30057, /* Vector 323, coef 2(138), 3(151) */ + -21848, /* Vector 324, coef 1(170), 2(168) */ + 28832, /* Vector 324, coef 3(112) Vector + * 325, Coef 1(160) */ + -25217, /* Vector 325, coef 2(157), 3(127) */ + -26471, /* Vector 326, coef 1(152), 2(153) */ + -27750, /* Vector 326, coef 3(147) Vector + * 327, Coef 1(154) */ + -29290, /* Vector 327, coef 2(141), 3(150) */ + -22889, /* Vector 328, coef 1(166), 2(151) */ + -30804, /* Vector 328, coef 3(135) Vector + * 329, Coef 1(172) */ + -29301, /* Vector 329, coef 2(141), 3(139) */ + -22904, /* Vector 330, coef 1(166), 2(136) */ + -28769, /* Vector 330, coef 3(143) Vector + * 331, Coef 1(159) */ + -31350, /* Vector 331, coef 2(133), 3(138) */ + -23404, /* Vector 332, coef 1(164), 2(148) */ + -27745, /* Vector 332, coef 3(147) Vector + * 333, Coef 1(159) */ + -28787, /* Vector 333, coef 2(143), 3(141) */ + -23669, /* Vector 334, coef 1(163), 2(139) */ + -32100, /* Vector 334, coef 3(130) Vector + * 335, Coef 1(156) */ + -31613, /* Vector 335, coef 2(132), 3(131) */ + -25195, /* Vector 336, coef 1(157), 2(149) */ + 29582, /* Vector 336, coef 3(115) Vector + * 337, Coef 1(142) */ + -29803, /* Vector 337, coef 2(139), 3(149) */ + -26990, /* Vector 338, coef 1(150), 2(146) */ + -29034, /* Vector 338, coef 3(142) Vector + * 339, Coef 1(150) */ + -28027, /* Vector 339, coef 2(146), 3(133) */ + -26742, /* Vector 340, coef 1(151), 2(138) */ + 31880, /* Vector 340, coef 3(124) Vector + * 341, Coef 1(136) */ + -22888, /* Vector 341, coef 2(166), 3(152) */ + -28257, /* Vector 342, coef 1(145), 2(159) */ + -29818, /* Vector 342, coef 3(139) Vector + * 343, Coef 1(134) */ + -25212, /* Vector 343, coef 2(157), 3(132) */ + -30058, /* Vector 344, coef 1(138), 2(150) */ + -28022, /* Vector 344, coef 3(146) Vector + * 345, Coef 1(138) */ + -29302, /* Vector 345, coef 2(141), 3(138) */ + -27998, /* Vector 346, coef 1(146), 2(162) */ + 30856, /* Vector 346, coef 3(120) Vector + * 347, Coef 1(136) */ + -22932, /* Vector 347, coef 2(166), 3(108) */ + 32149, /* Vector 348, coef 1(125), 2(149) */ + 29323, /* Vector 348, coef 3(114) Vector + * 349, Coef 1(139) */ + -28546, /* Vector 349, coef 2(144), 3(126) */ + -30586, /* Vector 350, coef 1(136), 2(134) */ + 32636, /* Vector 350, coef 3(127) Vector + * 351, Coef 1(124) */ + -19824, /* Vector 351, coef 2(178), 3(144) */ + -24966, /* Vector 352, coef 1(158), 2(122) */ + -30560, /* Vector 352, coef 3(136) Vector + * 353, Coef 1(160) */ + 31123, /* Vector 353, coef 2(121), 3(147) */ + -26250, /* Vector 354, coef 1(153), 2(118) */ + -28265, /* Vector 354, coef 3(145) Vector + * 355, Coef 1(151) */ + -32359, /* Vector 355, coef 2(129), 3(153) */ + -27515, /* Vector 356, coef 1(148), 2(133) */ + -27762, /* Vector 356, coef 3(147) Vector + * 357, Coef 1(142) */ + -32104, /* Vector 357, coef 2(130), 3(152) */ + -24449, /* Vector 358, coef 1(160), 2(127) */ + -27237, /* Vector 358, coef 3(149) Vector + * 359, Coef 1(155) */ + -31855, /* Vector 359, coef 2(131), 3(145) */ + -26755, /* Vector 360, coef 1(151), 2(125) */ + -29031, /* Vector 360, coef 3(142) Vector + * 361, Coef 1(153) */ + 31899, /* Vector 361, coef 2(124), 3(155) */ + -27526, /* Vector 362, coef 1(148), 2(122) */ + -26475, /* Vector 362, coef 3(152) Vector + * 363, Coef 1(149) */ + -30323, /* Vector 363, coef 2(137), 3(141) */ + -28028, /* Vector 364, coef 1(146), 2(132) */ + -31092, /* Vector 364, coef 3(134) Vector + * 365, Coef 1(140) */ + -31860, /* Vector 365, coef 2(131), 3(140) */ + -28037, /* Vector 366, coef 1(146), 2(123) */ + -30318, /* Vector 366, coef 3(137) Vector + * 367, Coef 1(146) */ + 30083, /* Vector 367, coef 2(117), 3(131) */ + -30081, /* Vector 368, coef 1(138), 2(127) */ + -27521, /* Vector 368, coef 3(148) Vector + * 369, Coef 1(127) */ + -32391, /* Vector 369, coef 2(129), 3(121) */ + 30072, /* Vector 370, coef 1(117), 2(120) */ + 29582, /* Vector 370, coef 3(115) Vector + * 371, Coef 1(142) */ + 29583, /* Vector 371, coef 2(115), 3(143) */ + -31362, /* Vector 372, coef 1(133), 2(126) */ + -30837, /* Vector 372, coef 3(135) Vector + * 373, Coef 1(139) */ + 30851, /* Vector 373, coef 2(120), 3(131) */ + -31627, /* Vector 374, coef 1(132), 2(117) */ + 31614, /* Vector 374, coef 3(123) Vector + * 375, Coef 1(126) */ + 32406, /* Vector 375, coef 2(126), 3(150) */ + -32122, /* Vector 376, coef 1(130), 2(134) */ + -29838, /* Vector 376, coef 3(139) Vector + * 377, Coef 1(114) */ + -32380, /* Vector 377, coef 2(129), 3(132) */ + -30599, /* Vector 378, coef 1(136), 2(121) */ + -28026, /* Vector 378, coef 3(146) Vector + * 379, Coef 1(134) */ + 29837, /* Vector 379, coef 2(116), 3(141) */ + -32651, /* Vector 380, coef 1(128), 2(117) */ + -29576, /* Vector 380, coef 3(140) Vector + * 381, Coef 1(120) */ + 30858, /* Vector 381, coef 2(120), 3(138) */ + 30063, /* Vector 382, coef 1(117), 2(111) */ + -32133, /* Vector 382, coef 3(130) Vector + * 383, Coef 1(123) */ + 29847, /* Vector 383, coef 2(116), 3(151) */ + -23180, /* Vector 384, coef 1(165), 2(116) */ + -20321, /* Vector 384, coef 3(176) Vector + * 385, Coef 1(159) */ + -32337, /* Vector 385, coef 2(129), 3(175) */ + -25471, /* Vector 386, coef 1(156), 2(129) */ + -15210, /* Vector 386, coef 3(196) Vector + * 387, Coef 1(150) */ + -32324, /* Vector 387, coef 2(129), 3(188) */ + -22917, /* Vector 388, coef 1(166), 2(123) */ + -15707, /* Vector 388, coef 3(194) Vector + * 389, Coef 1(165) */ + 31925, /* Vector 389, coef 2(124), 3(181) */ + -24194, /* Vector 390, coef 1(161), 2(126) */ + -17766, /* Vector 390, coef 3(186) Vector + * 391, Coef 1(154) */ + 31925, /* Vector 391, coef 2(124), 3(181) */ + -26249, /* Vector 392, coef 1(153), 2(119) */ + -20822, /* Vector 392, coef 3(174) Vector + * 393, Coef 1(170) */ + 30405, /* Vector 393, coef 2(118), 3(197) */ + -23697, /* Vector 394, coef 1(163), 2(111) */ + -15971, /* Vector 394, coef 3(193) Vector + * 395, Coef 1(157) */ + 27831, /* Vector 395, coef 2(108), 3(183) */ + -24203, /* Vector 396, coef 1(161), 2(117) */ + -17509, /* Vector 396, coef 3(187) Vector + * 397, Coef 1(155) */ + 29879, /* Vector 397, coef 2(116), 3(183) */ + -24455, /* Vector 398, coef 1(160), 2(121) */ + -14182, /* Vector 398, coef 3(200) Vector + * 399, Coef 1(154) */ + 31173, /* Vector 399, coef 2(121), 3(197) */ + -28561, /* Vector 400, coef 1(144), 2(111) */ + -25967, /* Vector 400, coef 3(154) Vector + * 401, Coef 1(145) */ + 30357, /* Vector 401, coef 2(118), 3(149) */ + -27271, /* Vector 402, coef 1(149), 2(121) */ + -22125, /* Vector 402, coef 3(169) Vector + * 403, Coef 1(147) */ + 30625, /* Vector 403, coef 2(119), 3(161) */ + -29570, /* Vector 404, coef 1(140), 2(126) */ + -24178, /* Vector 404, coef 3(161) Vector + * 405, Coef 1(142) */ + 30885, /* Vector 405, coef 2(120), 3(165) */ + -29578, /* Vector 406, coef 1(140), 2(118) */ + -25710, /* Vector 406, coef 3(155) Vector + * 407, Coef 1(146) */ + 28841, /* Vector 407, coef 2(112), 3(169) */ + -29073, /* Vector 408, coef 1(142), 2(111) */ + -24181, /* Vector 408, coef 3(161) Vector + * 409, Coef 1(139) */ + 27048, /* Vector 409, coef 2(105), 3(168) */ + -30613, /* Vector 410, coef 1(136), 2(107) */ + -24441, /* Vector 410, coef 3(160) Vector + * 411, Coef 1(135) */ + 29347, /* Vector 411, coef 2(114), 3(163) */ + -31626, /* Vector 412, coef 1(132), 2(118) */ + -26230, /* Vector 412, coef 3(153) Vector + * 413, Coef 1(138) */ + 28844, /* Vector 413, coef 2(112), 3(172) */ + -30083, /* Vector 414, coef 1(138), 2(125) */ + -21371, /* Vector 414, coef 3(172) Vector + * 415, Coef 1(133) */ + 31143, /* Vector 415, coef 2(121), 3(167) */ + -26007, /* Vector 416, coef 1(154), 2(105) */ + -15208, /* Vector 416, coef 3(196) Vector + * 417, Coef 1(152) */ + 28845, /* Vector 417, coef 2(112), 3(173) */ + -27287, /* Vector 418, coef 1(149), 2(105) */ + -20075, /* Vector 418, coef 3(177) Vector + * 419, Coef 1(149) */ + 30404, /* Vector 419, coef 2(118), 3(196) */ + -27532, /* Vector 420, coef 1(148), 2(116) */ + -18542, /* Vector 420, coef 3(183) Vector + * 421, Coef 1(146) */ + 31420, /* Vector 421, coef 2(122), 3(188) */ + -28548, /* Vector 422, coef 1(144), 2(124) */ + -19573, /* Vector 422, coef 3(179) Vector + * 423, Coef 1(139) */ + 30130, /* Vector 423, coef 2(117), 3(178) */ + -26255, /* Vector 424, coef 1(153), 2(113) */ + -14958, /* Vector 424, coef 3(197) Vector + * 425, Coef 1(146) */ + 27589, /* Vector 425, coef 2(107), 3(197) */ + -28562, /* Vector 426, coef 1(144), 2(110) */ + -17780, /* Vector 426, coef 3(186) Vector + * 427, Coef 1(140) */ + 26550, /* Vector 427, coef 2(103), 3(182) */ + -29068, /* Vector 428, coef 1(142), 2(116) */ + -14714, /* Vector 428, coef 3(198) Vector + * 429, Coef 1(134) */ + 29634, /* Vector 429, coef 2(115), 3(194) */ + -32152, /* Vector 430, coef 1(130), 2(104) */ + -15988, /* Vector 430, coef 3(193) Vector + * 431, Coef 1(140) */ + 32197, /* Vector 431, coef 2(125), 3(197) */ + 30797, /* Vector 432, coef 1(120), 2( 77) */ + -26745, /* Vector 432, coef 3(151) Vector + * 433, Coef 1(135) */ + 26011, /* Vector 433, coef 2(101), 3(155) */ + -32163, /* Vector 434, coef 1(130), 2( 93) */ + -25213, /* Vector 434, coef 3(157) Vector + * 435, Coef 1(131) */ + 27804, /* Vector 435, coef 2(108), 3(156) */ + 32362, /* Vector 436, coef 1(126), 2(106) */ + -27003, /* Vector 436, coef 3(150) Vector + * 437, Coef 1(133) */ + 24753, /* Vector 437, coef 2( 96), 3(177) */ + 32088, /* Vector 438, coef 1(125), 2( 88) */ + -20860, /* Vector 438, coef 3(174) Vector + * 439, Coef 1(132) */ + 28595, /* Vector 439, coef 2(111), 3(179) */ + -32409, /* Vector 440, coef 1(129), 2(103) */ + -21638, /* Vector 440, coef 3(171) Vector + * 441, Coef 1(122) */ + 24508, /* Vector 441, coef 2( 95), 3(188) */ + 29539, /* Vector 442, coef 1(115), 2( 99) */ + -17555, /* Vector 442, coef 3(187) Vector + * 443, Coef 1(109) */ + 21420, /* Vector 443, coef 2( 83), 3(172) */ + 31340, /* Vector 444, coef 1(122), 2(108) */ + -23689, /* Vector 444, coef 3(163) Vector + * 445, Coef 1(119) */ + 24997, /* Vector 445, coef 2( 97), 3(165) */ + 29792, /* Vector 446, coef 1(116), 2( 96) */ + -25744, /* Vector 446, coef 3(155) Vector + * 447, Coef 1(112) */ + 22421, /* Vector 447, coef 2( 87), 3(149) */ + -26472, /* Vector 448, coef 1(152), 2(152) */ + -23919, /* Vector 448, coef 3(162) Vector + * 449, Coef 1(145) */ + -28252, /* Vector 449, coef 2(145), 3(164) */ + -30071, /* Vector 450, coef 1(138), 2(137) */ + -24689, /* Vector 450, coef 3(159) Vector + * 451, Coef 1(143) */ + -24898, /* Vector 451, coef 2(158), 3(190) */ + -27750, /* Vector 452, coef 1(147), 2(154) */ + -20331, /* Vector 452, coef 3(176) Vector + * 453, Coef 1(149) */ + -27456, /* Vector 453, coef 2(148), 3(192) */ + -29043, /* Vector 454, coef 1(142), 2(141) */ + -16498, /* Vector 454, coef 3(191) Vector + * 455, Coef 1(142) */ + -28239, /* Vector 455, coef 2(145), 3(177) */ + -31347, /* Vector 456, coef 1(133), 2(141) */ + -20086, /* Vector 456, coef 3(177) Vector + * 457, Coef 1(138) */ + -30294, /* Vector 457, coef 2(137), 3(170) */ + -31059, /* Vector 458, coef 1(134), 2(173) */ + -19070, /* Vector 458, coef 3(181) Vector + * 459, Coef 1(130) */ + -24395, /* Vector 459, coef 2(160), 3(181) */ + -29540, /* Vector 460, coef 1(140), 2(156) */ + -23414, /* Vector 460, coef 3(164) Vector + * 461, Coef 1(138) */ + -31816, /* Vector 461, coef 2(131), 3(184) */ + -30827, /* Vector 462, coef 1(135), 2(149) */ + -16001, /* Vector 462, coef 3(193) Vector + * 463, Coef 1(127) */ + -29000, /* Vector 463, coef 2(142), 3(184) */ + 32662, /* Vector 464, coef 1(127), 2(150) */ + -29323, /* Vector 464, coef 3(141) Vector + * 465, Coef 1(117) */ + -28027, /* Vector 465, coef 2(146), 3(133) */ + -32376, /* Vector 466, coef 1(129), 2(136) */ + -25723, /* Vector 466, coef 3(155) Vector + * 467, Coef 1(133) */ + -30061, /* Vector 467, coef 2(138), 3(147) */ + 31108, /* Vector 468, coef 1(121), 2(132) */ + -28797, /* Vector 468, coef 3(143) Vector + * 469, Coef 1(131) */ + -27742, /* Vector 469, coef 2(147), 3(162) */ + 32412, /* Vector 470, coef 1(126), 2(156) */ + -25735, /* Vector 470, coef 3(155) Vector + * 471, Coef 1(121) */ + -28523, /* Vector 471, coef 2(144), 3(149) */ + 30366, /* Vector 472, coef 1(118), 2(158) */ + -19854, /* Vector 472, coef 3(178) Vector + * 473, Coef 1(114) */ + -25181, /* Vector 473, coef 2(157), 3(163) */ + 26774, /* Vector 474, coef 1(104), 2(150) */ + -20110, /* Vector 474, coef 3(177) Vector + * 475, Coef 1(114) */ + -22133, /* Vector 475, coef 2(169), 3(139) */ + 25759, /* Vector 476, coef 1(100), 2(159) */ + -29838, /* Vector 476, coef 3(139) Vector + * 477, Coef 1(114) */ + -29256, /* Vector 477, coef 2(141), 3(184) */ + 30091, /* Vector 478, coef 1(117), 2(139) */ + -24211, /* Vector 478, coef 3(161) Vector + * 479, Coef 1(109) */ + -30824, /* Vector 479, coef 2(135), 3(152) */ + -31873, /* Vector 480, coef 1(131), 2(127) */ + -24962, /* Vector 480, coef 3(158) Vector + * 481, Coef 1(126) */ + 29104, /* Vector 481, coef 2(113), 3(176) */ + 29806, /* Vector 482, coef 1(116), 2(110) */ + -21373, /* Vector 482, coef 3(172) Vector + * 483, Coef 1(131) */ + -31831, /* Vector 483, coef 2(131), 3(169) */ + 32136, /* Vector 484, coef 1(125), 2(136) */ + -22151, /* Vector 484, coef 3(169) Vector + * 485, Coef 1(121) */ + -32093, /* Vector 485, coef 2(130), 3(163) */ + -31622, /* Vector 486, coef 1(132), 2(122) */ + -18299, /* Vector 486, coef 3(184) Vector + * 487, Coef 1(133) */ + -31291, /* Vector 487, coef 2(133), 3(197) */ + 31871, /* Vector 488, coef 1(124), 2(127) */ + -18049, /* Vector 488, coef 3(185) Vector + * 489, Coef 1(127) */ + 30402, /* Vector 489, coef 2(118), 3(194) */ + 30066, /* Vector 490, coef 1(117), 2(114) */ + -16513, /* Vector 490, coef 3(191) Vector + * 491, Coef 1(127) */ + 31661, /* Vector 491, coef 2(123), 3(173) */ + 32629, /* Vector 492, coef 1(127), 2(117) */ + -23943, /* Vector 492, coef 3(162) Vector + * 493, Coef 1(121) */ + 31401, /* Vector 493, coef 2(122), 3(169) */ + 30328, /* Vector 494, coef 1(118), 2(120) */ + -24972, /* Vector 494, coef 3(158) Vector + * 495, Coef 1(116) */ + 32704, /* Vector 495, coef 2(127), 3(192) */ + 25967, /* Vector 496, coef 1(101), 2(111) */ + -31891, /* Vector 496, coef 3(131) Vector + * 497, Coef 1(109) */ + 26786, /* Vector 497, coef 2(104), 3(162) */ + 26459, /* Vector 498, coef 1(103), 2( 91) */ + -29601, /* Vector 498, coef 3(140) Vector + * 499, Coef 1( 95) */ + -27230, /* Vector 499, coef 2(149), 3(162) */ + 23943, /* Vector 500, coef 1( 93), 2(135) */ + -29068, /* Vector 500, coef 3(142) Vector + * 501, Coef 1(116) */ + 27538, /* Vector 501, coef 2(107), 3(146) */ + 28546, /* Vector 502, coef 1(111), 2(130) */ + -21908, /* Vector 502, coef 3(170) Vector + * 503, Coef 1(108) */ + 30132, /* Vector 503, coef 2(117), 3(180) */ + 26727, /* Vector 504, coef 1(104), 2(103) */ + -18849, /* Vector 504, coef 3(182) Vector + * 505, Coef 1( 95) */ + 26795, /* Vector 505, coef 2(104), 3(171) */ + 28537, /* Vector 506, coef 1(111), 2(121) */ + -26007, /* Vector 506, coef 3(154) Vector + * 507, Coef 1(105) */ + 29329, /* Vector 507, coef 2(114), 3(145) */ + 25984, /* Vector 508, coef 1(101), 2(128) */ + -19116, /* Vector 508, coef 3(181) Vector + * 509, Coef 1( 84) */ + -31577, /* Vector 509, coef 2(132), 3(167) */ + 25463, /* Vector 510, coef 1( 99), 2(119) */ + -24489, /* Vector 510, coef 3(160) Vector + * 511, Coef 1( 87) */ + 27538 /* Vector 511, coef 2(107), 3(146) */ +}; + +int16_tRom psrQuant3[QUANT3_NUM_OF_WORDS] = +{ + -26192, /* Vector 0, coef 1(153), 2(176) */ + -32358, /* Vector 0, coef 3(129), 4(154) */ + -27991, /* Vector 1, coef 1(146), 2(169) */ + 31890, /* Vector 1, coef 3(124), 4(146) */ + -27731, /* Vector 2, coef 1(147), 2(173) */ + 30625, /* Vector 2, coef 3(119), 4(161) */ + -28246, /* Vector 3, coef 1(145), 2(170) */ + 29078, /* Vector 3, coef 3(113), 4(150) */ + -28501, /* Vector 4, coef 1(144), 2(171) */ + -31610, /* Vector 4, coef 3(132), 4(134) */ + -30302, /* Vector 5, coef 1(137), 2(162) */ + 30347, /* Vector 5, coef 3(118), 4(139) */ + -25161, /* Vector 6, coef 1(157), 2(183) */ + 29326, /* Vector 6, coef 3(114), 4(142) */ + -26959, /* Vector 7, coef 1(150), 2(177) */ + 27784, /* Vector 7, coef 3(108), 4(136) */ + -27468, /* Vector 8, coef 1(148), 2(180) */ + 26514, /* Vector 8, coef 3(103), 4(146) */ + -30561, /* Vector 9, coef 1(136), 2(159) */ + 29088, /* Vector 9, coef 3(113), 4(160) */ + -28484, /* Vector 10, coef 1(144), 2(188) */ + 31120, /* Vector 10, coef 3(121), 4(144) */ + -29789, /* Vector 11, coef 1(139), 2(163) */ + -30559, /* Vector 11, coef 3(136), 4(161) */ + -30302, /* Vector 12, coef 1(137), 2(162) */ + -32361, /* Vector 12, coef 3(129), 4(151) */ + -30548, /* Vector 13, coef 1(136), 2(172) */ + 31646, /* Vector 13, coef 3(123), 4(158) */ + -25687, /* Vector 14, coef 1(155), 2(169) */ + 29589, /* Vector 14, coef 3(115), 4(149) */ + -29286, /* Vector 15, coef 1(141), 2(154) */ + 30359, /* Vector 15, coef 3(118), 4(151) */ + -31069, /* Vector 16, coef 1(134), 2(163) */ + -32127, /* Vector 16, coef 3(130), 4(129) */ + -31074, /* Vector 17, coef 1(134), 2(158) */ + 29819, /* Vector 17, coef 3(116), 4(123) */ + -29016, /* Vector 18, coef 1(142), 2(168) */ + 23178, /* Vector 18, coef 3( 90), 4(138) */ + -30027, /* Vector 19, coef 1(138), 2(181) */ + 30600, /* Vector 19, coef 3(119), 4(136) */ + -28995, /* Vector 20, coef 1(142), 2(189) */ + 27787, /* Vector 20, coef 3(108), 4(139) */ + -31305, /* Vector 21, coef 1(133), 2(183) */ + 27527, /* Vector 21, coef 3(107), 4(135) */ + -31049, /* Vector 22, coef 1(134), 2(183) */ + 29808, /* Vector 22, coef 3(116), 4(112) */ + 32171, /* Vector 23, coef 1(125), 2(171) */ + 26486, /* Vector 23, coef 3(103), 4(118) */ + -30295, /* Vector 24, coef 1(137), 2(169) */ + 27026, /* Vector 24, coef 3(105), 4(146) */ + -32096, /* Vector 25, coef 1(130), 2(160) */ + 27014, /* Vector 25, coef 3(105), 4(134) */ + 32677, /* Vector 26, coef 1(127), 2(165) */ + 24203, /* Vector 26, coef 3( 94), 4(139) */ + 31132, /* Vector 27, coef 1(121), 2(156) */ + 22399, /* Vector 27, coef 3( 87), 4(127) */ + -26968, /* Vector 28, coef 1(150), 2(168) */ + 26231, /* Vector 28, coef 3(102), 4(119) */ + -30302, /* Vector 29, coef 1(137), 2(162) */ + 24437, /* Vector 29, coef 3( 95), 4(117) */ + 31391, /* Vector 30, coef 1(122), 2(159) */ + 28304, /* Vector 30, coef 3(110), 4(144) */ + 31400, /* Vector 31, coef 1(122), 2(168) */ + 30599, /* Vector 31, coef 3(119), 4(135) */ + -31076, /* Vector 32, coef 1(134), 2(156) */ + 27796, /* Vector 32, coef 3(108), 4(148) */ + -31335, /* Vector 33, coef 1(133), 2(153) */ + 32672, /* Vector 33, coef 3(127), 4(160) */ + 32153, /* Vector 34, coef 1(125), 2(153) */ + 31896, /* Vector 34, coef 3(124), 4(152) */ + -31853, /* Vector 35, coef 1(131), 2(147) */ + 30613, /* Vector 35, coef 3(119), 4(149) */ + 31892, /* Vector 36, coef 1(124), 2(148) */ + 29840, /* Vector 36, coef 3(116), 4(144) */ + -32100, /* Vector 37, coef 1(130), 2(156) */ + 32654, /* Vector 37, coef 3(127), 4(142) */ + -32616, /* Vector 38, coef 1(128), 2(152) */ + 29576, /* Vector 38, coef 3(115), 4(136) */ + 32140, /* Vector 39, coef 1(125), 2(140) */ + 31375, /* Vector 39, coef 3(122), 4(143) */ + 32408, /* Vector 40, coef 1(126), 2(152) */ + 30369, /* Vector 40, coef 3(118), 4(161) */ + 31890, /* Vector 41, coef 1(124), 2(146) */ + 28062, /* Vector 41, coef 3(109), 4(158) */ + 31373, /* Vector 42, coef 1(122), 2(141) */ + 30619, /* Vector 42, coef 3(119), 4(155) */ + 31129, /* Vector 43, coef 1(121), 2(153) */ + 28826, /* Vector 43, coef 3(112), 4(154) */ + 32390, /* Vector 44, coef 1(126), 2(134) */ + 27555, /* Vector 44, coef 3(107), 4(163) */ + 32159, /* Vector 45, coef 1(125), 2(159) */ + 30099, /* Vector 45, coef 3(117), 4(147) */ + 30362, /* Vector 46, coef 1(118), 2(154) */ + 32674, /* Vector 46, coef 3(127), 4(162) */ + -32103, /* Vector 47, coef 1(130), 2(153) */ + -28774, /* Vector 47, coef 3(143), 4(154) */ + 32660, /* Vector 48, coef 1(127), 2(148) */ + 22937, /* Vector 48, coef 3( 89), 4(153) */ + 30599, /* Vector 49, coef 1(119), 2(135) */ + 22164, /* Vector 49, coef 3( 86), 4(148) */ + 29847, /* Vector 50, coef 1(116), 2(151) */ + 24465, /* Vector 50, coef 3( 95), 4(145) */ + 27534, /* Vector 51, coef 1(107), 2(142) */ + 21905, /* Vector 51, coef 3( 85), 4(145) */ + 30859, /* Vector 52, coef 1(120), 2(139) */ + 27788, /* Vector 52, coef 3(108), 4(140) */ + 28803, /* Vector 53, coef 1(112), 2(131) */ + 26763, /* Vector 53, coef 3(104), 4(139) */ + 30092, /* Vector 54, coef 1(117), 2(140) */ + 29333, /* Vector 54, coef 3(114), 4(149) */ + 28295, /* Vector 55, coef 1(110), 2(135) */ + 29081, /* Vector 55, coef 3(113), 4(153) */ + 28545, /* Vector 56, coef 1(111), 2(129) */ + 26786, /* Vector 56, coef 3(104), 4(162) */ + 29843, /* Vector 57, coef 1(116), 2(147) */ + 27283, /* Vector 57, coef 3(106), 4(147) */ + 26249, /* Vector 58, coef 1(102), 2(137) */ + 26261, /* Vector 58, coef 3(102), 4(149) */ + 24707, /* Vector 59, coef 1( 96), 2(131) */ + 29600, /* Vector 59, coef 3(115), 4(160) */ + 31618, /* Vector 60, coef 1(123), 2(130) */ + 26772, /* Vector 60, coef 3(104), 4(148) */ + 27790, /* Vector 61, coef 1(108), 2(142) */ + 27778, /* Vector 61, coef 3(108), 4(130) */ + 31880, /* Vector 62, coef 1(124), 2(136) */ + 27518, /* Vector 62, coef 3(107), 4(126) */ + 27022, /* Vector 63, coef 1(105), 2(142) */ + 29840, /* Vector 63, coef 3(116), 4(144) */ + -23384, /* Vector 64, coef 1(164), 2(168) */ + 31896, /* Vector 64, coef 3(124), 4(152) */ + -25701, /* Vector 65, coef 1(155), 2(155) */ + 31373, /* Vector 65, coef 3(122), 4(141) */ + -27495, /* Vector 66, coef 1(148), 2(153) */ + 29317, /* Vector 66, coef 3(114), 4(133) */ + -23127, /* Vector 67, coef 1(165), 2(169) */ + 27534, /* Vector 67, coef 3(107), 4(142) */ + -25176, /* Vector 68, coef 1(157), 2(168) */ + 24974, /* Vector 68, coef 3( 97), 4(142) */ + -27231, /* Vector 69, coef 1(149), 2(161) */ + 27285, /* Vector 69, coef 3(106), 4(149) */ + -23917, /* Vector 70, coef 1(162), 2(147) */ + 22157, /* Vector 70, coef 3( 86), 4(141) */ + -26979, /* Vector 71, coef 1(150), 2(157) */ + 30625, /* Vector 71, coef 3(119), 4(161) */ + -27245, /* Vector 72, coef 1(149), 2(147) */ + 28569, /* Vector 72, coef 3(111), 4(153) */ + -30062, /* Vector 73, coef 1(138), 2(146) */ + 29580, /* Vector 73, coef 3(115), 4(140) */ + -22890, /* Vector 74, coef 1(166), 2(150) */ + 28565, /* Vector 74, coef 3(111), 4(149) */ + -24436, /* Vector 75, coef 1(160), 2(140) */ + 27277, /* Vector 75, coef 3(106), 4(141) */ + -27509, /* Vector 76, coef 1(148), 2(139) */ + 28814, /* Vector 76, coef 3(112), 4(142) */ + -26725, /* Vector 77, coef 1(151), 2(155) */ + -30573, /* Vector 77, coef 3(136), 4(147) */ + -25961, /* Vector 78, coef 1(154), 2(151) */ + -31877, /* Vector 78, coef 3(131), 4(123) */ + -26739, /* Vector 79, coef 1(151), 2(141) */ + 30071, /* Vector 79, coef 3(117), 4(119) */ + -30829, /* Vector 80, coef 1(135), 2(147) */ + 26777, /* Vector 80, coef 3(104), 4(153) */ + -32626, /* Vector 81, coef 1(128), 2(142) */ + 25999, /* Vector 81, coef 3(101), 4(143) */ + -28775, /* Vector 82, coef 1(143), 2(153) */ + 25992, /* Vector 82, coef 3(101), 4(136) */ + -26988, /* Vector 83, coef 1(150), 2(148) */ + 22913, /* Vector 83, coef 3( 89), 4(129) */ + -28007, /* Vector 84, coef 1(146), 2(153) */ + 21903, /* Vector 84, coef 3( 85), 4(143) */ + -30575, /* Vector 85, coef 1(136), 2(145) */ + 21132, /* Vector 85, coef 3( 82), 4(140) */ + -31594, /* Vector 86, coef 1(132), 2(150) */ + 24707, /* Vector 86, coef 3( 96), 4(131) */ + -31851, /* Vector 87, coef 1(131), 2(149) */ + 21629, /* Vector 87, coef 3( 84), 4(125) */ + -30068, /* Vector 88, coef 1(138), 2(140) */ + 27542, /* Vector 88, coef 3(107), 4(150) */ + -31604, /* Vector 89, coef 1(132), 2(140) */ + 28807, /* Vector 89, coef 3(112), 4(135) */ + -31358, /* Vector 90, coef 1(133), 2(130) */ + 24708, /* Vector 90, coef 3( 96), 4(132) */ + -27509, /* Vector 91, coef 1(148), 2(139) */ + 25240, /* Vector 91, coef 3( 98), 4(152) */ + -28542, /* Vector 92, coef 1(144), 2(130) */ + 21907, /* Vector 92, coef 3( 85), 4(147) */ + -30328, /* Vector 93, coef 1(137), 2(136) */ + 21915, /* Vector 93, coef 3( 85), 4(155) */ + -31872, /* Vector 94, coef 1(131), 2(128) */ + 21907, /* Vector 94, coef 3( 85), 4(147) */ + -31092, /* Vector 95, coef 1(134), 2(140) */ + 28271, /* Vector 95, coef 3(110), 4(111) */ + -30846, /* Vector 96, coef 1(135), 2(130) */ + 27787, /* Vector 96, coef 3(108), 4(139) */ + -28028, /* Vector 97, coef 1(146), 2(132) */ + 27522, /* Vector 97, coef 3(107), 4(130) */ + -26494, /* Vector 98, coef 1(152), 2(130) */ + 32399, /* Vector 98, coef 3(126), 4(143) */ + -28809, /* Vector 99, coef 1(143), 2(119) */ + 30350, /* Vector 99, coef 3(118), 4(142) */ + -28047, /* Vector 100, coef 1(146), 2(113) */ + 32382, /* Vector 100, coef 3(126), 4(126) */ + -30860, /* Vector 101, coef 1(135), 2(116) */ + 28546, /* Vector 101, coef 3(111), 4(130) */ + -24456, /* Vector 102, coef 1(160), 2(120) */ + 25747, /* Vector 102, coef 3(100), 4(147) */ + -27019, /* Vector 103, coef 1(150), 2(117) */ + 22680, /* Vector 103, coef 3( 88), 4(152) */ + -29831, /* Vector 104, coef 1(139), 2(121) */ + 26776, /* Vector 104, coef 3(104), 4(152) */ + -31633, /* Vector 105, coef 1(132), 2(111) */ + 23964, /* Vector 105, coef 3( 93), 4(156) */ + -28818, /* Vector 106, coef 1(143), 2(110) */ + 31384, /* Vector 106, coef 3(122), 4(152) */ + -28829, /* Vector 107, coef 1(143), 2( 99) */ + 28053, /* Vector 107, coef 3(109), 4(149) */ + -30841, /* Vector 108, coef 1(135), 2(135) */ + 30365, /* Vector 108, coef 3(118), 4(157) */ + -32382, /* Vector 109, coef 1(129), 2(130) */ + 29587, /* Vector 109, coef 3(115), 4(147) */ + -31875, /* Vector 110, coef 1(131), 2(125) */ + 32660, /* Vector 110, coef 3(127), 4(148) */ + 32628, /* Vector 111, coef 1(127), 2(116) */ + 30862, /* Vector 111, coef 3(120), 4(142) */ + 27002, /* Vector 112, coef 1(105), 2(122) */ + 25753, /* Vector 112, coef 3(100), 4(153) */ + 31356, /* Vector 113, coef 1(122), 2(124) */ + 23711, /* Vector 113, coef 3( 92), 4(159) */ + 31606, /* Vector 114, coef 1(123), 2(118) */ + 24978, /* Vector 114, coef 3( 97), 4(146) */ + 32361, /* Vector 115, coef 1(126), 2(105) */ + 30369, /* Vector 115, coef 3(118), 4(161) */ + 31844, /* Vector 116, coef 1(124), 2(100) */ + 29333, /* Vector 116, coef 3(114), 4(149) */ + 30588, /* Vector 117, coef 1(119), 2(124) */ + 29838, /* Vector 117, coef 3(116), 4(142) */ + 30324, /* Vector 118, coef 1(118), 2(116) */ + 28294, /* Vector 118, coef 3(110), 4(134) */ + 30081, /* Vector 119, coef 1(117), 2(129) */ + 30870, /* Vector 119, coef 3(120), 4(150) */ + 32121, /* Vector 120, coef 1(125), 2(121) */ + 29598, /* Vector 120, coef 3(115), 4(158) */ + 29297, /* Vector 121, coef 1(114), 2(113) */ + 26785, /* Vector 121, coef 3(104), 4(161) */ + 28029, /* Vector 122, coef 1(109), 2(125) */ + 32672, /* Vector 122, coef 3(127), 4(160) */ + 25720, /* Vector 123, coef 1(100), 2(120) */ + 30616, /* Vector 123, coef 3(119), 4(152) */ + 28784, /* Vector 124, coef 1(112), 2(112) */ + 30359, /* Vector 124, coef 3(118), 4(151) */ + 26733, /* Vector 125, coef 1(104), 2(109) */ + 28305, /* Vector 125, coef 3(110), 4(145) */ + 26988, /* Vector 126, coef 1(105), 2(108) */ + -31083, /* Vector 126, coef 3(134), 4(149) */ + 27774, /* Vector 127, coef 1(108), 2(126) */ + 31370, /* Vector 127, coef 3(122), 4(138) */ + -32092, /* Vector 128, coef 1(130), 2(164) */ + 31128, /* Vector 128, coef 3(121), 4(152) */ + -30794, /* Vector 129, coef 1(135), 2(182) */ + -31079, /* Vector 129, coef 3(134), 4(153) */ + -32336, /* Vector 130, coef 1(129), 2(176) */ + -32370, /* Vector 130, coef 3(129), 4(142) */ + -32575, /* Vector 131, coef 1(128), 2(193) */ + -32631, /* Vector 131, coef 3(128), 4(137) */ + 31932, /* Vector 132, coef 1(124), 2(188) */ + 29069, /* Vector 132, coef 3(113), 4(141) */ + -31561, /* Vector 133, coef 1(132), 2(183) */ + 30364, /* Vector 133, coef 3(118), 4(156) */ + 32427, /* Vector 134, coef 1(126), 2(171) */ + 29590, /* Vector 134, coef 3(115), 4(150) */ + 30141, /* Vector 135, coef 1(117), 2(189) */ + -31342, /* Vector 135, coef 3(133), 4(146) */ + 29874, /* Vector 136, coef 1(116), 2(178) */ + 32406, /* Vector 136, coef 3(126), 4(150) */ + 27327, /* Vector 137, coef 1(106), 2(191) */ + -31858, /* Vector 137, coef 3(131), 4(142) */ + 29877, /* Vector 138, coef 1(116), 2(181) */ + 31872, /* Vector 138, coef 3(124), 4(128) */ + 31654, /* Vector 139, coef 1(123), 2(166) */ + -29297, /* Vector 139, coef 3(141), 4(143) */ + 31654, /* Vector 140, coef 1(123), 2(166) */ + -30813, /* Vector 140, coef 3(135), 4(163) */ + 30369, /* Vector 141, coef 1(118), 2(161) */ + -31077, /* Vector 141, coef 3(134), 4(155) */ + 30881, /* Vector 142, coef 1(120), 2(161) */ + 32147, /* Vector 142, coef 3(125), 4(147) */ + 27820, /* Vector 143, coef 1(108), 2(172) */ + -29032, /* Vector 143, coef 3(142), 4(152) */ + 32159, /* Vector 144, coef 1(125), 2(159) */ + -31889, /* Vector 144, coef 3(131), 4(111) */ + 29849, /* Vector 145, coef 1(116), 2(153) */ + 28785, /* Vector 145, coef 3(112), 4(113) */ + 31896, /* Vector 146, coef 1(124), 2(152) */ + 32135, /* Vector 146, coef 3(125), 4(135) */ + 31892, /* Vector 147, coef 1(124), 2(148) */ + 27775, /* Vector 147, coef 3(108), 4(127) */ + 27821, /* Vector 148, coef 1(108), 2(173) */ + 29557, /* Vector 148, coef 3(115), 4(117) */ + 28840, /* Vector 149, coef 1(112), 2(168) */ + 27017, /* Vector 149, coef 3(105), 4(137) */ + 26270, /* Vector 150, coef 1(102), 2(158) */ + 25731, /* Vector 150, coef 3(100), 4(131) */ + 30623, /* Vector 151, coef 1(119), 2(159) */ + -31352, /* Vector 151, coef 3(133), 4(136) */ + 28582, /* Vector 152, coef 1(111), 2(166) */ + -30079, /* Vector 152, coef 3(138), 4(129) */ + 27801, /* Vector 153, coef 1(108), 2(153) */ + -31622, /* Vector 153, coef 3(132), 4(122) */ + 29327, /* Vector 154, coef 1(114), 2(143) */ + -28299, /* Vector 154, coef 3(145), 4(117) */ + 29600, /* Vector 155, coef 1(115), 2(160) */ + 30337, /* Vector 155, coef 3(118), 4(129) */ + 29848, /* Vector 156, coef 1(116), 2(152) */ + 28552, /* Vector 156, coef 3(111), 4(136) */ + 27291, /* Vector 157, coef 1(106), 2(155) */ + 32392, /* Vector 157, coef 3(126), 4(136) */ + 30864, /* Vector 158, coef 1(120), 2(144) */ + 31871, /* Vector 158, coef 3(124), 4(127) */ + 29574, /* Vector 159, coef 1(115), 2(134) */ + 30331, /* Vector 159, coef 3(118), 4(123) */ + 29326, /* Vector 160, coef 1(114), 2(142) */ + 30373, /* Vector 160, coef 3(118), 4(165) */ + 27538, /* Vector 161, coef 1(107), 2(146) */ + 27553, /* Vector 161, coef 3(107), 4(161) */ + 27566, /* Vector 162, coef 1(107), 2(174) */ + 31119, /* Vector 162, coef 3(121), 4(143) */ + 29336, /* Vector 163, coef 1(114), 2(152) */ + 31388, /* Vector 163, coef 3(122), 4(156) */ + 29342, /* Vector 164, coef 1(114), 2(158) */ + 31632, /* Vector 164, coef 3(123), 4(144) */ + 29845, /* Vector 165, coef 1(116), 2(149) */ + 31379, /* Vector 165, coef 3(122), 4(147) */ + 30630, /* Vector 166, coef 1(119), 2(166) */ + 31391, /* Vector 166, coef 3(122), 4(159) */ + 29859, /* Vector 167, coef 1(116), 2(163) */ + 28314, /* Vector 167, coef 3(110), 4(154) */ + 28058, /* Vector 168, coef 1(109), 2(154) */ + 30359, /* Vector 168, coef 3(118), 4(151) */ + 27288, /* Vector 169, coef 1(106), 2(152) */ + 28560, /* Vector 169, coef 3(111), 4(144) */ + 26788, /* Vector 170, coef 1(104), 2(164) */ + 31388, /* Vector 170, coef 3(122), 4(156) */ + 25249, /* Vector 171, coef 1( 98), 2(161) */ + 29074, /* Vector 171, coef 3(113), 4(146) */ + 25511, /* Vector 172, coef 1( 99), 2(167) */ + -29540, /* Vector 172, coef 3(140), 4(156) */ + 26782, /* Vector 173, coef 1(104), 2(158) */ + -31088, /* Vector 173, coef 3(134), 4(144) */ + 26777, /* Vector 174, coef 1(104), 2(153) */ + -32093, /* Vector 174, coef 3(130), 4(163) */ + 27538, /* Vector 175, coef 1(107), 2(146) */ + 31126, /* Vector 175, coef 3(121), 4(150) */ + 25242, /* Vector 176, coef 1( 98), 2(154) */ + 30850, /* Vector 176, coef 3(120), 4(130) */ + 23434, /* Vector 177, coef 1( 91), 2(138) */ + 30335, /* Vector 177, coef 3(118), 4(127) */ + 24982, /* Vector 178, coef 1( 97), 2(150) */ + 28572, /* Vector 178, coef 3(111), 4(156) */ + 23183, /* Vector 179, coef 1( 90), 2(143) */ + 27791, /* Vector 179, coef 3(108), 4(143) */ + 24728, /* Vector 180, coef 1( 96), 2(152) */ + -32115, /* Vector 180, coef 3(130), 4(141) */ + 25009, /* Vector 181, coef 1( 97), 2(177) */ + -30841, /* Vector 181, coef 3(135), 4(135) */ + 24230, /* Vector 182, coef 1( 94), 2(166) */ + -32389, /* Vector 182, coef 3(129), 4(123) */ + 23720, /* Vector 183, coef 1( 92), 2(168) */ + 31885, /* Vector 183, coef 3(124), 4(141) */ + 21663, /* Vector 184, coef 1( 84), 2(159) */ + 30090, /* Vector 184, coef 3(117), 4(138) */ + 24978, /* Vector 185, coef 1( 97), 2(146) */ + 32668, /* Vector 185, coef 3(127), 4(156) */ + 23450, /* Vector 186, coef 1( 91), 2(154) */ + 32153, /* Vector 186, coef 3(125), 4(153) */ + 22926, /* Vector 187, coef 1( 89), 2(142) */ + 31126, /* Vector 187, coef 3(121), 4(150) */ + 22432, /* Vector 188, coef 1( 87), 2(160) */ + -29809, /* Vector 188, coef 3(139), 4(143) */ + 21143, /* Vector 189, coef 1( 82), 2(151) */ + -30078, /* Vector 189, coef 3(138), 4(130) */ + 20885, /* Vector 190, coef 1( 81), 2(149) */ + -31343, /* Vector 190, coef 3(133), 4(145) */ + 19344, /* Vector 191, coef 1( 75), 2(144) */ + 32394, /* Vector 191, coef 3(126), 4(138) */ + -29301, /* Vector 192, coef 1(141), 2(139) */ + -32102, /* Vector 192, coef 3(130), 4(154) */ + -30839, /* Vector 193, coef 1(135), 2(137) */ + 32145, /* Vector 193, coef 3(125), 4(145) */ + 32663, /* Vector 194, coef 1(127), 2(151) */ + -29057, /* Vector 194, coef 3(142), 4(127) */ + -32631, /* Vector 195, coef 1(128), 2(137) */ + -30602, /* Vector 195, coef 3(136), 4(118) */ + -29292, /* Vector 196, coef 1(141), 2(148) */ + -30074, /* Vector 196, coef 3(138), 4(134) */ + -29803, /* Vector 197, coef 1(139), 2(149) */ + -32627, /* Vector 197, coef 3(128), 4(141) */ + -30064, /* Vector 198, coef 1(138), 2(144) */ + 32131, /* Vector 198, coef 3(125), 4(131) */ + -30834, /* Vector 199, coef 1(135), 2(142) */ + 31608, /* Vector 199, coef 3(123), 4(120) */ + -32370, /* Vector 200, coef 1(129), 2(142) */ + -31863, /* Vector 200, coef 3(131), 4(137) */ + -32631, /* Vector 201, coef 1(128), 2(137) */ + 32132, /* Vector 201, coef 3(125), 4(132) */ + -30078, /* Vector 202, coef 1(138), 2(130) */ + 31877, /* Vector 202, coef 3(124), 4(133) */ + -32642, /* Vector 203, coef 1(128), 2(126) */ + 31103, /* Vector 203, coef 3(121), 4(127) */ + 31101, /* Vector 204, coef 1(121), 2(125) */ + 27507, /* Vector 204, coef 3(107), 4(115) */ + -29816, /* Vector 205, coef 1(139), 2(136) */ + -27509, /* Vector 205, coef 3(148), 4(139) */ + -29563, /* Vector 206, coef 1(140), 2(133) */ + -30592, /* Vector 206, coef 3(136), 4(128) */ + 32657, /* Vector 207, coef 1(127), 2(145) */ + -30061, /* Vector 207, coef 3(138), 4(147) */ + -32126, /* Vector 208, coef 1(130), 2(130) */ + -30070, /* Vector 208, coef 3(138), 4(138) */ + -32645, /* Vector 209, coef 1(128), 2(123) */ + -31611, /* Vector 209, coef 3(132), 4(133) */ + -30600, /* Vector 210, coef 1(136), 2(120) */ + -26506, /* Vector 210, coef 3(152), 4(118) */ + 30310, /* Vector 211, coef 1(118), 2(102) */ + -25216, /* Vector 211, coef 3(157), 4(128) */ + 30328, /* Vector 212, coef 1(118), 2(120) */ + -29310, /* Vector 212, coef 3(141), 4(130) */ + 29550, /* Vector 213, coef 1(115), 2(110) */ + -31618, /* Vector 213, coef 3(132), 4(126) */ + -30603, /* Vector 214, coef 1(136), 2(117) */ + -27501, /* Vector 214, coef 3(148), 4(147) */ + -32401, /* Vector 215, coef 1(129), 2(111) */ + -30834, /* Vector 215, coef 3(135), 4(142) */ + -30881, /* Vector 216, coef 1(135), 2( 95) */ + -29045, /* Vector 216, coef 3(142), 4(139) */ + 32096, /* Vector 217, coef 1(125), 2( 96) */ + -32632, /* Vector 217, coef 3(128), 4(136) */ + 30064, /* Vector 218, coef 1(117), 2(112) */ + -29031, /* Vector 218, coef 3(142), 4(153) */ + 29539, /* Vector 219, coef 1(115), 2( 99) */ + -31852, /* Vector 219, coef 3(131), 4(148) */ + 29567, /* Vector 220, coef 1(115), 2(127) */ + -32636, /* Vector 220, coef 3(128), 4(132) */ + 29314, /* Vector 221, coef 1(114), 2(130) */ + -25726, /* Vector 221, coef 3(155), 4(130) */ + 27512, /* Vector 222, coef 1(107), 2(120) */ + -24714, /* Vector 222, coef 3(159), 4(118) */ + 29053, /* Vector 223, coef 1(113), 2(125) */ + -31088, /* Vector 223, coef 3(134), 4(144) */ + 30598, /* Vector 224, coef 1(119), 2(134) */ + 30346, /* Vector 224, coef 3(118), 4(138) */ + 25993, /* Vector 225, coef 1(101), 2(137) */ + 32159, /* Vector 225, coef 3(125), 4(159) */ + 25221, /* Vector 226, coef 1( 98), 2(133) */ + 29841, /* Vector 226, coef 3(116), 4(145) */ + 31623, /* Vector 227, coef 1(123), 2(135) */ + 32672, /* Vector 227, coef 3(127), 4(160) */ + 29072, /* Vector 228, coef 1(113), 2(144) */ + 30857, /* Vector 228, coef 3(120), 4(137) */ + 30869, /* Vector 229, coef 1(120), 2(149) */ + -31854, /* Vector 229, coef 3(131), 4(146) */ + 29841, /* Vector 230, coef 1(116), 2(145) */ + -31862, /* Vector 230, coef 3(131), 4(138) */ + 32137, /* Vector 231, coef 1(125), 2(137) */ + -30318, /* Vector 231, coef 3(137), 4(146) */ + 31365, /* Vector 232, coef 1(122), 2(133) */ + -32369, /* Vector 232, coef 3(129), 4(143) */ + 30344, /* Vector 233, coef 1(118), 2(136) */ + -30844, /* Vector 233, coef 3(135), 4(132) */ + 29330, /* Vector 234, coef 1(114), 2(146) */ + -30563, /* Vector 234, coef 3(136), 4(157) */ + 28556, /* Vector 235, coef 1(111), 2(140) */ + 32665, /* Vector 235, coef 3(127), 4(153) */ + 28554, /* Vector 236, coef 1(111), 2(138) */ + -32368, /* Vector 236, coef 3(129), 4(144) */ + 26759, /* Vector 237, coef 1(104), 2(135) */ + 32141, /* Vector 237, coef 3(125), 4(141) */ + 29076, /* Vector 238, coef 1(113), 2(148) */ + -27763, /* Vector 238, coef 3(147), 4(141) */ + 29570, /* Vector 239, coef 1(115), 2(130) */ + -28777, /* Vector 239, coef 3(143), 4(151) */ + 22143, /* Vector 240, coef 1( 86), 2(127) */ + 29588, /* Vector 240, coef 3(115), 4(148) */ + 28038, /* Vector 241, coef 1(109), 2(134) */ + -31625, /* Vector 241, coef 3(132), 4(119) */ + 24717, /* Vector 242, coef 1( 96), 2(141) */ + -32634, /* Vector 242, coef 3(128), 4(134) */ + 25447, /* Vector 243, coef 1( 99), 2(103) */ + -31349, /* Vector 243, coef 3(133), 4(139) */ + 25979, /* Vector 244, coef 1(101), 2(123) */ + 30084, /* Vector 244, coef 3(117), 4(132) */ + 27275, /* Vector 245, coef 1(106), 2(139) */ + -29559, /* Vector 245, coef 3(140), 4(137) */ + 24724, /* Vector 246, coef 1( 96), 2(148) */ + -28027, /* Vector 246, coef 3(146), 4(133) */ + 24202, /* Vector 247, coef 1( 94), 2(138) */ + -29063, /* Vector 247, coef 3(142), 4(121) */ + 23929, /* Vector 248, coef 1( 93), 2(121) */ + -26230, /* Vector 248, coef 3(153), 4(138) */ + 24437, /* Vector 249, coef 1( 95), 2(117) */ + -29059, /* Vector 249, coef 3(142), 4(125) */ + 26490, /* Vector 250, coef 1(103), 2(122) */ + -28786, /* Vector 250, coef 3(143), 4(142) */ + 24693, /* Vector 251, coef 1( 96), 2(117) */ + -31602, /* Vector 251, coef 3(132), 4(142) */ + 24971, /* Vector 252, coef 1( 97), 2(139) */ + -29802, /* Vector 252, coef 3(139), 4(150) */ + 22405, /* Vector 253, coef 1( 87), 2(133) */ + -31337, /* Vector 253, coef 3(133), 4(151) */ + 22917, /* Vector 254, coef 1( 89), 2(133) */ + -30072, /* Vector 254, coef 3(138), 4(136) */ + 20861, /* Vector 255, coef 1( 81), 2(125) */ + -30842 /* Vector 255, coef 3(135), 4(134) */ +}; + + +/* lpc pre-quantizer */ +/*-------------------*/ + +int16_tRom psrPreQ1[PREQ1_NUM_OF_WORDS] = +{ + -13624, /* Vector 0, coef 1(202), 2(200) */ + -31561, /* Vector 0, coef 3(132) Vector 1, + * Coef 1(183) */ + -11886, /* Vector 1, coef 2(209), 3(146) */ + -22329, /* Vector 2, coef 1(168), 2(199) */ + -28759, /* Vector 2, coef 3(143) Vector 3, + * Coef 1(169) */ + -22416, /* Vector 3, coef 2(168), 3(112) */ + -20112, /* Vector 4, coef 1(177), 2(112) */ + 28822, /* Vector 4, coef 3(112) Vector 5, + * Coef 1(150) */ + 24392, /* Vector 5, coef 2( 95), 3( 72) */ + 21340, /* Vector 6, coef 1( 83), 2( 92) */ + 26761, /* Vector 6, coef 3(104) Vector 7, + * Coef 1(137) */ + 32323, /* Vector 7, coef 2(126), 3( 67) */ + -25919, /* Vector 8, coef 1(154), 2(193) */ + -29300, /* Vector 8, coef 3(141) Vector 9, + * Coef 1(140) */ + -14455, /* Vector 9, coef 2(199), 3(137) */ + -29788, /* Vector 10, coef 1(139), 2(164) */ + -32648, /* Vector 10, coef 3(128) Vector 11, + * Coef 1(120) */ + -26510, /* Vector 11, coef 2(152), 3(114) */ + 25500, /* Vector 12, coef 1( 99), 2(156) */ + 27209, /* Vector 12, coef 3(106) Vector 13, + * Coef 1( 73) */ + -30113, /* Vector 13, coef 2(138), 3( 95) */ + 31917, /* Vector 14, coef 1(124), 2(173) */ + 22884, /* Vector 14, coef 3( 89) Vector 15, + * Coef 1(100) */ + -29633, /* Vector 15, coef 2(140), 3( 63) */ + 31429, /* Vector 16, coef 1(122), 2(197) */ + -29072, /* Vector 16, coef 3(142) Vector 17, + * Coef 1(112) */ + -18827, /* Vector 17, coef 2(182), 3(117) */ + 26052, /* Vector 18, coef 1(101), 2(196) */ + 26961, /* Vector 18, coef 3(105) Vector 19, + * Coef 1( 81) */ + -21177, /* Vector 19, coef 2(173), 3( 71) */ + 16031, /* Vector 20, coef 1( 62), 2(159) */ + 25903, /* Vector 20, coef 3(101) Vector 21, + * Coef 1( 47) */ + -29092, /* Vector 21, coef 2(142), 3( 92) */ + 22691, /* Vector 22, coef 1( 88), 2(163) */ + 21594, /* Vector 22, coef 3( 84) Vector 23, + * Coef 1( 90) */ + -26817, /* Vector 23, coef 2(151), 3( 63) */ + 14738, /* Vector 24, coef 1( 57), 2(146) */ + -30686, /* Vector 24, coef 3(136) Vector 25, + * Coef 1( 34) */ + -28552, /* Vector 25, coef 2(144), 3(120) */ + 10352, /* Vector 26, coef 1( 40), 2(112) */ + -28111, /* Vector 26, coef 3(146) Vector 27, + * Coef 1( 49) */ + 30576, /* Vector 27, coef 2(119), 3(112) */ + 21631, /* Vector 28, coef 1( 84), 2(127) */ + 29521, /* Vector 28, coef 3(115) Vector 29, + * Coef 1( 81) */ + 30041, /* Vector 29, coef 2(117), 3( 89) */ + -27988, /* Vector 30, coef 1(146), 2(172) */ + 22897, /* Vector 30, coef 3( 89) Vector 31, + * Coef 1(113) */ + 32583, /* Vector 31, coef 2(127), 3( 71) */ + 23991, /* Vector 32, coef 1( 93), 2(183) */ + -28340, /* Vector 32, coef 3(145) Vector 33, + * Coef 1( 76) */ + -23428, /* Vector 33, coef 2(164), 3(124) */ + 15550, /* Vector 34, coef 1( 60), 2(190) */ + -28626, /* Vector 34, coef 3(144) Vector 35, + * Coef 1( 46) */ + -20091, /* Vector 35, coef 2(177), 3(133) */ + 19913, /* Vector 36, coef 1( 77), 2(201) */ + 29757, /* Vector 36, coef 3(116) Vector 37, + * Coef 1( 61) */ + -18579, /* Vector 37, coef 2(183), 3(109) */ + 13228, /* Vector 38, coef 1( 51), 2(172) */ + 21831, /* Vector 38, coef 3( 85) Vector 39, + * Coef 1( 71) */ + -18366, /* Vector 39, coef 2(184), 3( 66) */ + 11219, /* Vector 40, coef 1( 43), 2(211) */ + 32289, /* Vector 40, coef 3(126) Vector 41, + * Coef 1( 33) */ + -16012, /* Vector 41, coef 2(193), 3(116) */ + 9892, /* Vector 42, coef 1( 38), 2(164) */ + 27415, /* Vector 42, coef 3(107) Vector 43, + * Coef 1( 23) */ + -20612, /* Vector 43, coef 2(175), 3(124) */ + 9919, /* Vector 44, coef 1( 38), 2(191) */ + -24801, /* Vector 44, coef 3(159) Vector 45, + * Coef 1( 31) */ + -23921, /* Vector 45, coef 2(162), 3(143) */ + 6302, /* Vector 46, coef 1( 24), 2(158) */ + -22510, /* Vector 46, coef 3(168) Vector 47, + * Coef 1( 18) */ + -14174, /* Vector 47, coef 2(200), 3(162) */ + 15572, /* Vector 48, coef 1( 60), 2(212) */ + 27438, /* Vector 48, coef 3(107) Vector 49, + * Coef 1( 46) */ + -16281, /* Vector 49, coef 2(192), 3(103) */ + 15046, /* Vector 50, coef 1( 58), 2(198) */ + 17698, /* Vector 50, coef 3( 69) Vector 51, + * Coef 1( 34) */ + -18601, /* Vector 51, coef 2(183), 3( 87) */ + 12246, /* Vector 52, coef 1( 47), 2(214) */ + 23595, /* Vector 52, coef 3( 92) Vector 53, + * Coef 1( 43) */ + -13248, /* Vector 53, coef 2(204), 3( 64) */ + 8157, /* Vector 54, coef 1( 31), 2(221) */ + 29463, /* Vector 54, coef 3(115) Vector 55, + * Coef 1( 23) */ + -13721, /* Vector 55, coef 2(202), 3(103) */ + 10458, /* Vector 56, coef 1( 40), 2(218) */ + 19998, /* Vector 56, coef 3( 78) Vector 57, + * Coef 1( 30) */ + -10173, /* Vector 57, coef 2(216), 3( 67) */ + 7395, /* Vector 58, coef 1( 28), 2(227) */ + 18453, /* Vector 58, coef 3( 72) Vector 59, + * Coef 1( 21) */ + -6332, /* Vector 59, coef 2(231), 3( 68) */ + 6862, /* Vector 60, coef 1( 26), 2(206) */ + -28399, /* Vector 60, coef 3(145) Vector 61, + * Coef 1( 17) */ + -12154, /* Vector 61, coef 2(208), 3(134) */ + 4575, /* Vector 62, coef 1( 17), 2(223) */ + 29455, /* Vector 62, coef 3(115) Vector 63, + * Coef 1( 15) */ + -5029 /* Vector 63, coef 2(236), 3( 91) */ +}; + +int16_tRom psrPreQ2[PREQ2_NUM_OF_WORDS] = +{ + -14954, /* Vector 0, coef 1(197), 2(150) */ + -26695, /* Vector 0, coef 3(151) Vector 1, + * Coef 1(185) */ + -31091, /* Vector 1, coef 2(134), 3(141) */ + -15239, /* Vector 2, coef 1(196), 2(121) */ + 29089, /* Vector 2, coef 3(113) Vector 3, + * Coef 1(161) */ + 31099, /* Vector 3, coef 2(121), 3(123) */ + -14987, /* Vector 4, coef 1(197), 2(117) */ + -25155, /* Vector 4, coef 3(157) Vector 5, + * Coef 1(189) */ + 23445, /* Vector 5, coef 2( 91), 3(149) */ + -20883, /* Vector 6, coef 1(174), 2(109) */ + -29788, /* Vector 6, coef 3(139) Vector 7, + * Coef 1(164) */ + 23424, /* Vector 7, coef 2( 91), 3(128) */ + -18813, /* Vector 8, coef 1(182), 2(131) */ + -19541, /* Vector 8, coef 3(179) Vector 9, + * Coef 1(171) */ + 32412, /* Vector 9, coef 2(126), 3(156) */ + -20114, /* Vector 10, coef 1(177), 2(110) */ + -19805, /* Vector 10, coef 3(178) Vector 11, + * Coef 1(163) */ + 23464, /* Vector 11, coef 2( 91), 3(168) */ + -24719, /* Vector 12, coef 1(159), 2(113) */ + -24682, /* Vector 12, coef 3(159) Vector 13, + * Coef 1(150) */ + 27026, /* Vector 13, coef 2(105), 3(146) */ + -28839, /* Vector 14, coef 1(143), 2( 89) */ + -20857, /* Vector 14, coef 3(174) Vector 15, + * Coef 1(135) */ + 25479, /* Vector 15, coef 2( 99), 3(135) */ + -19558, /* Vector 16, coef 1(179), 2(154) */ + -20062, /* Vector 16, coef 3(177) Vector 17, + * Coef 1(162) */ + -22120, /* Vector 17, coef 2(169), 3(152) */ + -23669, /* Vector 18, coef 1(163), 2(139) */ + -18023, /* Vector 18, coef 3(185) Vector 19, + * Coef 1(153) */ + -30813, /* Vector 19, coef 2(135), 3(163) */ + -23666, /* Vector 20, coef 1(163), 2(142) */ + -29810, /* Vector 20, coef 3(139) Vector 21, + * Coef 1(142) */ + -27514, /* Vector 21, coef 2(148), 3(134) */ + -27010, /* Vector 22, coef 1(150), 2(126) */ + -28797, /* Vector 22, coef 3(143) Vector 23, + * Coef 1(131) */ + 31371, /* Vector 23, coef 2(122), 3(139) */ + -24711, /* Vector 24, coef 1(159), 2(121) */ + -18292, /* Vector 24, coef 3(184) Vector 25, + * Coef 1(140) */ + 29857, /* Vector 25, coef 2(116), 3(161) */ + -28558, /* Vector 26, coef 1(144), 2(114) */ + -18051, /* Vector 26, coef 3(185) Vector 27, + * Coef 1(125) */ + 25508, /* Vector 27, coef 2( 99), 3(164) */ + -29550, /* Vector 28, coef 1(140), 2(146) */ + -20871, /* Vector 28, coef 3(174) Vector 29, + * Coef 1(121) */ + -28262, /* Vector 29, coef 2(145), 3(154) */ + 32123, /* Vector 30, coef 1(125), 2(123) */ + -21144, /* Vector 30, coef 3(173) Vector 31, + * Coef 1(104) */ + 30111 /* Vector 31, coef 2(117), 3(159) */ +}; + +int16_tRom psrPreQ3[PREQ3_NUM_OF_WORDS] = +{ + -28246, /* Vector 0, coef 1(145), 2(170) */ + 30356, /* Vector 0, coef 3(118), 4(148) */ + -31320, /* Vector 1, coef 1(133), 2(168) */ + 27523, /* Vector 1, coef 3(107), 4(131) */ + 32405, /* Vector 2, coef 1(126), 2(149) */ + 30613, /* Vector 2, coef 3(119), 4(149) */ + 29066, /* Vector 3, coef 1(113), 2(138) */ + 27281, /* Vector 3, coef 3(106), 4(145) */ + -26216, /* Vector 4, coef 1(153), 2(152) */ + 28557, /* Vector 4, coef 3(111), 4(141) */ + -30322, /* Vector 5, coef 1(137), 2(142) */ + 24972, /* Vector 5, coef 3( 97), 4(140) */ + -29576, /* Vector 6, coef 1(140), 2(120) */ + 29072, /* Vector 6, coef 3(113), 4(144) */ + 29301, /* Vector 7, coef 1(114), 2(117) */ + 29589, /* Vector 7, coef 3(115), 4(149) */ + 31407, /* Vector 8, coef 1(122), 2(175) */ + -32622, /* Vector 8, coef 3(128), 4(146) */ + 29594, /* Vector 9, coef 1(115), 2(154) */ + 31359, /* Vector 9, coef 3(122), 4(127) */ + 28060, /* Vector 10, coef 1(109), 2(156) */ + 30870, /* Vector 10, coef 3(120), 4(150) */ + 23193, /* Vector 11, coef 1( 90), 2(153) */ + 32141, /* Vector 11, coef 3(125), 4(141) */ + -31349, /* Vector 12, coef 1(133), 2(139) */ + -32379, /* Vector 12, coef 3(129), 4(133) */ + 31093, /* Vector 13, coef 1(121), 2(117) */ + -29817, /* Vector 13, coef 3(139), 4(135) */ + 29323, /* Vector 14, coef 1(114), 2(139) */ + -32369, /* Vector 14, coef 3(129), 4(143) */ + 24450, /* Vector 15, coef 1( 95), 2(130) */ + -30584 /* Vector 15, coef 3(136), 4(136) */ +}; + + +/* size of the vq subset in the kth segment */ +/*------------------------------------------*/ + +int16_tRom psrQuantSz[QUANT_NUM_OF_TABLES] = +{ + 1 << (QUANT1_NUM_OF_BITS - PREQ1_NUM_OF_BITS), + 1 << (QUANT2_NUM_OF_BITS - PREQ2_NUM_OF_BITS), + 1 << (QUANT3_NUM_OF_BITS - PREQ3_NUM_OF_BITS) +}; + + +/* pre-quantizer size */ +/*--------------------*/ + +int16_tRom psrPreQSz[QUANT_NUM_OF_TABLES] = +{ + 1 << PREQ1_NUM_OF_BITS, + 1 << PREQ2_NUM_OF_BITS, + 1 << PREQ3_NUM_OF_BITS +}; + + +/* reflection coeff scalar quantizer */ +/*-----------------------------------*/ + +int16_tRom psrSQuant[SQUANT_NUM_OF_ROWS] = +{ + -32766, -32758, -32746, -32729, + -32707, -32680, -32648, -32611, + -32570, -32523, -32472, -32416, + -32355, -32289, -32219, -32143, + -32063, -31978, -31888, -31794, + -31694, -31590, -31481, -31368, + -31250, -31127, -30999, -30867, + -30731, -30589, -30443, -30293, + -30138, -29978, -29814, -29646, + -29473, -29296, -29114, -28928, + -28738, -28543, -28344, -28141, + -27934, -27723, -27507, -27287, + -27063, -26836, -26604, -26368, + -26128, -25884, -25637, -25386, + -25130, -24871, -24609, -24342, + -24072, -23799, -23522, -23241, + -22957, -22670, -22379, -22084, + -21787, -21486, -21182, -20875, + -20564, -20251, -19935, -19615, + -19293, -18968, -18640, -18309, + -17975, -17639, -17300, -16959, + -16615, -16268, -15919, -15568, + -15214, -14859, -14500, -14140, + -13778, -13413, -13047, -12678, + -12308, -11936, -11562, -11186, + -10809, -10430, -10050, -9668, + -9284, -8899, -8513, -8126, + -7737, -7347, -6956, -6565, + -6172, -5778, -5383, -4988, + -4591, -4194, -3797, -3399, + -3000, -2601, -2201, -1802, + -1402, -1001, -601, -200, + 200, 601, 1001, 1402, + 1802, 2201, 2601, 3000, + 3399, 3797, 4194, 4591, + 4988, 5383, 5778, 6172, + 6565, 6956, 7347, 7737, + 8126, 8513, 8899, 9284, + 9668, 10050, 10430, 10809, + 11186, 11562, 11936, 12308, + 12678, 13047, 13413, 13778, + 14140, 14500, 14859, 15214, + 15568, 15919, 16268, 16615, + 16959, 17300, 17639, 17975, + 18309, 18640, 18968, 19293, + 19615, 19935, 20251, 20564, + 20875, 21182, 21486, 21787, + 22084, 22379, 22670, 22957, + 23241, 23522, 23799, 24072, + 24342, 24609, 24871, 25130, + 25386, 25637, 25884, 26128, + 26368, 26604, 26836, 27063, + 27287, 27507, 27723, 27934, + 28141, 28344, 28543, 28738, + 28928, 29114, 29296, 29473, + 29646, 29814, 29978, 30138, + 30293, 30443, 30589, 30731, + 30867, 30999, 31127, 31250, + 31368, 31481, 31590, 31694, + 31794, 31888, 31978, 32063, + 32143, 32219, 32289, 32355, + 32416, 32472, 32523, 32570, + 32611, 32648, 32680, 32707, + 32729, 32746, 32758, 32766 +}; + + +/* index structure for LPC Vector Quantizer */ +/*------------------------------------------*/ + +struct IsubLHn psvqIndex[QUANT_NUM_OF_TABLES] = +{ + {1, 3, 3}, /* Table 1 - low, high, length */ + {4, 6, 3}, /* Table 2 - low, high, length */ + {7, 10, 4} /* Table 3 - low, high, length */ +}; + + +/* square root of p0 table */ +/*-------------------------*/ + +int16_tRom ppsrSqrtP0[SQRTP0_NUM_OF_MODES][SQRTP0_NUM_OF_ROWS] = +{ + { + 23853, 24682, 21337, 16698, + 27731, 24699, 8804, 16227, + 29760, 24223, 30248, 30903, + 7969, 17600, 5559, 16866, + 25609, 24727, 30483, 31688, + 27583, 28959, 31514, 31903, + 14035, 23660, 13761, 25661, + 28863, 31627, 30350, 32153 + }, + { + 26490, 19929, 28693, 23708, + 30266, 28196, 31577, 31714, + 20642, 20179, 27963, 29109, + 30776, 32054, 31076, 32241, + 23111, 28343, 25233, 29710, + 30403, 31915, 31466, 32360, + 28533, 30856, 31921, 32327, + 29569, 31489, 32348, 32114 + }, + { + 24318, 31095, 31943, 31912, + 27251, 30541, 32336, 32254, + 28448, 29139, 32149, 32413, + 31155, 31480, 32388, 32561, + 28647, 31172, 32084, 32512, + 30927, 32000, 32435, 32571, + 30455, 31973, 32487, 32564, + 31487, 32472, 31877, 32586 + } +}; + + +/* interpolation filter used for C and G */ +/*---------------------------------------*/ + +int16_tRom ppsrCGIntFilt[CGINTFILT_MACS][OS_FCTR] = +{ + {0, 126, 0, -299, -778, -1381}, + {-1980, -2375, -2326, -1596, 0, 2535}, + {5936, 9968, 14254, 18322, 21678, 23889}, + {24661, 23889, 21678, 18322, 14254, 9968}, + {5936, 2535, 0, -1596, -2326, -2375}, + {-1980, -1381, -778, -299, 0, 126} +}; + + +/* interpolation filter used pitch */ +/*---------------------------------*/ + +int16_tRom ppsrPVecIntFilt[PVECINTFILT_MACS][OS_FCTR] = +{ + {0, 183, 249, 251, 149, -67}, + {-368, -681, -897, -904, -622, -38}, + {762, 1595, 2214, 2360, 1842, 611}, + {-1186, -3195, -4898, -5708, -5089, -2696}, + {1515, 7239, 13835, 20424, 26040, 29814}, + {31144, 29814, 26040, 20424, 13835, 7239}, + {1515, -2696, -5089, -5708, -4898, -3195}, + {-1186, 611, 1842, 2360, 2214, 1595}, + {762, -38, -622, -904, -897, -681}, + {-368, -67, 149, 251, 249, 183} +}; + + +/* fractional pitch lag table lag*OS_FCTR */ +/*----------------------------------------*/ + +int16_tRom psrLagTbl[LAGTBL_NUM_OF_ROWS] = +{ + 126, 128, 130, 132, 134, 136, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 212, + 214, 216, 218, 220, 222, 224, 226, 228, + 230, 232, 234, 236, 238, 240, 242, 244, + 246, 248, 250, 252, 254, 256, 258, 260, + 262, 264, 266, 268, 270, 272, 274, 276, + 278, 280, 282, 284, 286, 288, 290, 292, + 294, 296, 298, 300, 303, 306, 309, 312, + 315, 318, 321, 324, 327, 330, 333, 336, + 339, 342, 345, 348, 351, 354, 357, 360, + 363, 366, 369, 372, 375, 378, 381, 384, + 387, 390, 393, 396, 399, 402, 405, 408, + 411, 414, 417, 420, 423, 426, 429, 432, + 435, 438, 441, 444, 447, 450, 453, 456, + 459, 462, 465, 468, 471, 474, 477, 480, + 483, 486, 489, 492, 495, 498, 501, 504, + 507, 510, 513, 516, 519, 522, 525, 528, + 531, 534, 537, 540, 546, 552, 558, 564, + 570, 576, 582, 588, 594, 600, 606, 612, + 618, 624, 630, 636, 642, 648, 654, 660, + 666, 672, 678, 684, 690, 696, 702, 708, + 714, 720, 726, 732, 738, 744, 750, 756, + 762, 768, 774, 780, 786, 792, 798, 804, + 810, 816, 822, 828, 834, 840, 846, 852 +}; + + +/* R0 decision value table defines range (not the levels themselves */ +/*------------------------------------------------------------------*/ + +int16_tRom psrR0DecTbl[R0DECTBL_NUM_OF_ROWS] = +{ + 6, 7, 8, 9, 10, 12, 13, 15, + 16, 18, 21, 23, 26, 29, 33, 37, + 41, 46, 52, 58, 65, 73, 82, 92, + 103, 115, 130, 145, 163, 183, 205, 230, + 258, 290, 325, 365, 410, 460, 516, 579, + 649, 728, 817, 917, 1029, 1154, 1295, 1453, + 1631, 1830, 2053, 2303, 2584, 2900, 3254, 3651, + 4096, 4596, 5157, 5786, 6492, 7284, 8173 +}; + +/* high pass filter coefficients */ +/*-------------------------------*/ + +int16_tRom psrHPFCoefs[HPFCOEFS_NUM_OF_CODES] = +{ + 10979, -21954, 10979, -14071, 30347, + 10979, -21936, 10979, -15385, 31632 +}; + + +/* spectral smoothing coefficients */ +/*---------------------------------*/ + +int16_tRom psrNWCoefs[NWCOEFS_NUM_OF_CODES] = +{ + 30474, 28341, 26357, 24512, 22796, + 21201, 19717, 18336, 17053, 15859, + 22938, 16056, 11239, 7868, 5507, + 3855, 2699, 1889, 1322, 926 +}; + + +/* spectral smoothing coefficients for FLAT */ +/*------------------------------------------*/ + +int32_tRom pL_rFlatSstCoefs[FLATSSTCOEFS_NUM_OF_CODES] = +{ + 2145262551, 2138972761, 2129579484, 2118274784, 2106083684, + 2093615080, 2081026796, 2068156528, 2054704628, 2040382328 +}; + +int16_tRom psrOldCont[4] = { + 0x599a, /* 0.70 */ + 0x30a4, /* 0.38 */ + 0x0a3d, /* 0.08 */ + 0x0000, /* 0.00 */ +}; + +int16_tRom psrNewCont[4] = { + 0x2666, /* 0.30 */ + 0x4f5c, /* 0.62 */ + 0x75c3, /* 0.92 */ + 0x7fff, /* 1.00 */ +}; diff --git a/src/libs/gsmhr/gsmhr_sp_rom.h b/src/libs/gsmhr/gsmhr_sp_rom.h new file mode 100644 index 00000000..00632281 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_sp_rom.h @@ -0,0 +1,193 @@ +/*************************************************************************** + * + * Purpose: Define the structure of the Global Constants + * + **************************************************************************/ + +#ifndef ___ROM +#define ___ROM + +#include "gsmhr_typedefs.h" +//#include "gsmhr_mathhalf.h" +//#include "gsmhr_mathdp31.h" + +/*_________________________________________________________________________ + | | + | Data Types | + |_________________________________________________________________________| +*/ + +/* gsp0 vector quantizer */ +/*-----------------------*/ +#define GSP0_NUM_OF_TABLES 4 +#define GSP0_NUM 32 +#define GSP0_VECTOR_SIZE 5 + +extern int16_tRom pppsrGsp0 + [GSP0_NUM_OF_TABLES][GSP0_NUM][GSP0_VECTOR_SIZE]; + + +/* unvoiced code vectors */ +/*-----------------------*/ +#define UVCODEVEC_NUM_OF_CODE_BOOKS 2 +#define UVCODEVEC_NUM_OF_CODE_BITS 7 + +extern int16_tRom pppsrUvCodeVec + [UVCODEVEC_NUM_OF_CODE_BOOKS][UVCODEVEC_NUM_OF_CODE_BITS][S_LEN]; + + +/* voiced code vectors */ +/*---------------------*/ +#define VCDCODEVEC_NUM_OF_CODE_BOOKS 1 +#define VCDCODEVEC_NUM_OF_CODE_BITS 9 + +extern int16_tRom pppsrVcdCodeVec + [VCDCODEVEC_NUM_OF_CODE_BOOKS][VCDCODEVEC_NUM_OF_CODE_BITS][S_LEN]; + + +/* vector quantizer tables */ +/*-------------------------*/ +#define QUANT_NUM_OF_TABLES 3 + +#define QUANT1_NUM_OF_BITS 11 +#define QUANT1_NUM_OF_ROWS (1 << QUANT1_NUM_OF_BITS) +#define QUANT1_NUM_OF_STAGES 3 +#define QUANT1_NUM_OF_WORDS (QUANT1_NUM_OF_ROWS*QUANT1_NUM_OF_STAGES/2) + +#define QUANT2_NUM_OF_BITS 9 +#define QUANT2_NUM_OF_ROWS (1 << QUANT2_NUM_OF_BITS) +#define QUANT2_NUM_OF_STAGES 3 +#define QUANT2_NUM_OF_WORDS (QUANT2_NUM_OF_ROWS*QUANT2_NUM_OF_STAGES/2) + +#define QUANT3_NUM_OF_BITS 8 +#define QUANT3_NUM_OF_ROWS (1 << QUANT3_NUM_OF_BITS) +#define QUANT3_NUM_OF_STAGES 4 +#define QUANT3_NUM_OF_WORDS (QUANT3_NUM_OF_ROWS*QUANT3_NUM_OF_STAGES/2) + +extern int16_tRom psrQuant1[QUANT1_NUM_OF_WORDS]; + +extern int16_tRom psrQuant2[QUANT2_NUM_OF_WORDS]; + +extern int16_tRom psrQuant3[QUANT3_NUM_OF_WORDS]; + + +/* lpc pre-quantizer */ +/*-------------------*/ +#define PREQ1_NUM_OF_BITS 6 +#define PREQ1_NUM_OF_ROWS (1 << PREQ1_NUM_OF_BITS) +#define PREQ1_NUM_OF_STAGES 3 +#define PREQ1_NUM_OF_WORDS (PREQ1_NUM_OF_ROWS*PREQ1_NUM_OF_STAGES/2) + +#define PREQ2_NUM_OF_BITS 5 +#define PREQ2_NUM_OF_ROWS (1 << PREQ2_NUM_OF_BITS) +#define PREQ2_NUM_OF_STAGES 3 +#define PREQ2_NUM_OF_WORDS (PREQ2_NUM_OF_ROWS*PREQ2_NUM_OF_STAGES/2) + +#define PREQ3_NUM_OF_BITS 4 +#define PREQ3_NUM_OF_ROWS (1 << PREQ3_NUM_OF_BITS) +#define PREQ3_NUM_OF_STAGES 4 +#define PREQ3_NUM_OF_WORDS (PREQ3_NUM_OF_ROWS*PREQ3_NUM_OF_STAGES/2) + +extern int16_tRom psrPreQ1[PREQ1_NUM_OF_WORDS]; + +extern int16_tRom psrPreQ2[PREQ2_NUM_OF_WORDS]; + +extern int16_tRom psrPreQ3[PREQ3_NUM_OF_WORDS]; + + +/* size of the vq subset in the kth segment */ +/*------------------------------------------*/ +extern int16_tRom psrQuantSz[QUANT_NUM_OF_TABLES]; + + +/* pre-quantizer size */ +/*--------------------*/ +extern int16_tRom psrPreQSz[QUANT_NUM_OF_TABLES]; + + +/* reflection coeff scalar quantizer */ +/*-----------------------------------*/ +#define SQUANT_NUM_OF_BITS 8 +#define SQUANT_NUM_OF_ROWS (1 << SQUANT_NUM_OF_BITS) + +extern int16_tRom psrSQuant[SQUANT_NUM_OF_ROWS]; + + +/* index structure for LPC Vector Quantizer */ +/*------------------------------------------*/ +struct IsubLHn +{ /* index structure for LPC Vector + * Quantizer */ + int16_tRom l; /* lowest index index range + * from 1..NP */ + int16_tRom h; /* highest index */ + int16_tRom len; /* h-l+1 */ +}; + + +extern struct IsubLHn psvqIndex[QUANT_NUM_OF_TABLES]; + + +/* square root of p0 table */ +/*-------------------------*/ +#define SQRTP0_NUM_OF_BITS 5 +#define SQRTP0_NUM_OF_ROWS (1 << SQRTP0_NUM_OF_BITS) +#define SQRTP0_NUM_OF_MODES 3 + +extern int16_tRom ppsrSqrtP0[SQRTP0_NUM_OF_MODES][SQRTP0_NUM_OF_ROWS]; + + +/* interpolation filter used for C and G */ +/*---------------------------------------*/ +#define CGINTFILT_MACS 6 + +extern int16_tRom ppsrCGIntFilt[CGINTFILT_MACS][OS_FCTR]; + + +/* interpolation filter used pitch */ +/*---------------------------------*/ +#define PVECINTFILT_MACS 10 + +extern int16_tRom ppsrPVecIntFilt[PVECINTFILT_MACS][OS_FCTR]; + + +/* fractional pitch lag table lag*OS_FCTR */ +/*----------------------------------------*/ +#define LAGTBL_NUM_OF_ROWS 256 + +extern int16_tRom psrLagTbl[LAGTBL_NUM_OF_ROWS]; + + +/* R0 decision value table defines range (not the levels themselves */ +/*------------------------------------------------------------------*/ + +#define R0DECTBL_NUM_OF_R0BITS 5 +#define R0DECTBL_NUM_OF_ROWS ((1 << R0DECTBL_NUM_OF_R0BITS)*2 - 1) + +extern int16_tRom psrR0DecTbl[R0DECTBL_NUM_OF_ROWS]; + + +/* high pass filter coefficients */ +/*-------------------------------*/ +#define HPFCOEFS_NUM_OF_CODES 10 + +extern int16_tRom psrHPFCoefs[HPFCOEFS_NUM_OF_CODES]; + + +/* spectral smoothing coefficients */ +/*---------------------------------*/ +#define NWCOEFS_NUM_OF_CODES 20 + +extern int16_tRom psrNWCoefs[NWCOEFS_NUM_OF_CODES]; + + +/* spectral smoothing coefficients for FLAT */ +/*------------------------------------------*/ +#define FLATSSTCOEFS_NUM_OF_CODES 10 + +extern int32_tRom pL_rFlatSstCoefs[FLATSSTCOEFS_NUM_OF_CODES]; + +extern int16_tRom psrOldCont[4]; +extern int16_tRom psrNewCont[4]; + +#endif diff --git a/src/libs/gsmhr/gsmhr_sp_sfrm.c b/src/libs/gsmhr/gsmhr_sp_sfrm.c new file mode 100644 index 00000000..bc3cedab --- /dev/null +++ b/src/libs/gsmhr/gsmhr_sp_sfrm.c @@ -0,0 +1,2360 @@ +/*************************************************************************** + * + * File Name: sp_sfrm.c + * + * Purpose: Contains all functions for subframe based processing in the + * speech encoder. Subframe based processing determines the synthetic + * LPC excitation signal, which is composed of the adaptive codebook + * (long-term predictor) vector (in voiced modes), the vector-sum + * codebook vector (two of these in unvoiced mode), and the vector- + * quantized gains applied to these vectors. + * + * Below is a listing of all the functions appearing in the file. + * The functions are arranged according to their purpose. Under + * each heading, the ordering is hierarchical. + * + * sfrmAnalysis + * decorr + * closedLoopLagSearch + * hnwFilt + * g_quant_vl + * g_corr2 + * gainTweak + * v_srch + * + * + ***************************************************************************/ +/*_________________________________________________________________________ + | | + | Include Files | + |_________________________________________________________________________| +*/ + +#include +#include "gsmhr_mathhalf.h" +#include "gsmhr_sp_rom.h" +#include "gsmhr_sp_dec.h" +#include "gsmhr_sp_frm.h" +#include "gsmhr_sp_sfrm.h" + +/*_________________________________________________________________________ + | | + | Local Defines | + |_________________________________________________________________________| +*/ + +#define CG_INT_MACS 6 +#define C_BITS_UV 7 +#define C_BITS_UV_1 C_BITS_UV-1 +#define C_BITS_V 9 +#define C_BITS_V_1 C_BITS_V-1 +#define DELTA_LEVELS 16 +#define GSP0_NUM 32 +#define GSP0_VECTOR_SIZE 5 +#define GTWEAKMAX 0x5A82 /* sqrt(2)/2 */ +#define LMAX 142 +#define LSMAX (LMAX + CG_INT_MACS/2) +#define HNW_BUFF_LEN LSMAX +#define LSP_MASK 0xffff +#define LTP_LEN 147 /* maximum ltp lag */ +#define MAX_CANDIDATE 6 /* maximum number of lag candidates */ + + +/*_________________________________________________________________________ + | | + | State variables (globals) | + |_________________________________________________________________________| +*/ + +int16_t pswLtpStateBase[LTP_LEN + S_LEN]; +int16_t pswHState[NP]; +int16_t pswHNWState[HNW_BUFF_LEN]; + +/*************************************************************************** + * + * FUNCTION NAME: closedLoopLagSearch + * + * PURPOSE: + * + * Performs the closed loop search of a list of candidate lags to + * determine the best fractional lag. + * + * INPUTS: + * + * pswLagList[0:iNumLags] - list of candidate lags + * iNumLags - number of candidate lags in LagList + * pswLtpState[0:5] - array of past excitations (LTP state) + * pswHCoefs[0:9] - coefficient array of spectral weighting filter + * pswPVect[0:39] - speech sub frame data + * + * OUTPUTS: + * + * pswLag - pointer to put best lag from list of candidates + * *pswLtpShift - Number of shifts applied to weighted LTP vector. + * + * RETURN VALUE: + * + * siLagCode - code corresponding to the best lag + * + * IMPLEMENTATION: + * + * Generate excitation vectors for all candidate lags. Find the candidate + * lag that maximizes C**2/G using the calculated excitation. + * + * DESCRIPTION: + * + * The function closedLoopLagSearch() searches a very small subset of the + * available LTP lags. The lags to be searched are defined by the open + * loop lag search. This information is passed in as a list of + * oversampled lag values. These values are translated into LTP + * vectors extracted from the LTP history. + * + * GSM document 06.20's b sub L prime variable is called + * ppswTVect[L][n] in the C code. The document's variable p(n) is + * named pswPVect[] in the C code. + * + * The function performs a simple maximization of the cross correlation + * of the weighted LTP vector and the weighted speech vector divided + * by the autocorrelation of the weighted LTP vector. The function is + * encumbered slightly by the necessity of scaling. + * + * REFERENCE: Sub-clause 4.1.8.5 of GSM Recommendation 06.20 + * + * KEYWORDS: closed loop, LTP lag search, adaptive codebook search + * + **************************************************************************/ + +int closedLoopLagSearch(int16_t pswLagList[], int iNumLags, + int16_t pswLtpState[], int16_t pswHCoefs[], + int16_t pswPVect[], + int16_t *pswLag, int16_t *pswLtpShift) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Energy, + L_ccNorm, + L_cgNorm, + L_CrossCorr; + int32_t pL_CCBuf[MAX_CANDIDATE], + pL_CGBuf[MAX_CANDIDATE]; + int16_t swCCMax, + swCCShiftCnt, + swCGShiftCnt, + swGMax, + swLTPEnergy, + swSampleA, + pswCCBuf[MAX_CANDIDATE], + pswCGBuf[MAX_CANDIDATE], + ppswTVect[N_SUB][S_LEN]; + int16_t i, + j, + siLagOffset, + siLagCode; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + + *pswLtpShift = 0; /* Energy in weighted ltp vector = + * [0..0x7ff] */ + for (i = 0; i < iNumLags; i++) + { + + /* Construct the excitation vector for lag i */ + /* ----------------------------------------- */ + + fp_ex(pswLagList[i], &pswLtpState[LTP_LEN]); + + /* Perform all pole filtering */ + /* -------------------------- */ + + lpcZsIir(&pswLtpState[LTP_LEN], pswHCoefs, ppswTVect[i]); + } + + /* scale the pitch vector s.t. its energy is strictly */ + /* less than 1.0 */ + /*----------------------------------------------------*/ + + swSampleA = shr(ppswTVect[0][0], 2); + L_Energy = L_mac(0x001dff4cL, swSampleA, swSampleA); + for (j = 1; j < S_LEN; j++) + { + swSampleA = shr(ppswTVect[0][j], 2); + L_Energy = L_mac(L_Energy, swSampleA, swSampleA); + } + + /* add in the energy of the first sample of the subsequent lags */ + /*--------------------------------------------------------------*/ + + for (i = 1; i < iNumLags; i++) + { + swSampleA = shr(ppswTVect[i][0], 2); + L_Energy = L_mac(L_Energy, swSampleA, swSampleA); + } + + /* An upper bound on the weighted pitch vectors energy */ + /*-----------------------------------------------------*/ + + swLTPEnergy = round(L_Energy); + + if (sub(swLTPEnergy, 0x07ff) > 0) + { /* E = (0x7ff.. 0x7fff] */ + if (sub(swLTPEnergy, 0x1fff) > 0) + { + *pswLtpShift = 2; /* E = (0x1fff..0x7fff] */ + } + else + { + *pswLtpShift = 1; /* E = (0x7ff.. 0x1fff] */ + } + + } + + for (i = 0; i < iNumLags; i++) + { + + /* shift all vectors down s.t. the largest is has energy < 1.0 */ + /*-------------------------------------------------------------*/ + + for (j = 0; j < S_LEN; j++) + ppswTVect[i][j] = shr(ppswTVect[i][j], *pswLtpShift); + + /* Calculate the energy of the subframe */ + /* ------------------------------------ */ + + L_Energy = L_mult(ppswTVect[i][0], ppswTVect[i][0]); + for (j = 1; j < S_LEN; j++) + L_Energy = L_mac(L_Energy, ppswTVect[i][j], ppswTVect[i][j]); + + pL_CGBuf[i] = L_Energy; + + /* Cross correlate the normalized speech frame and the filtered + * subframe */ + /* --------------------------------------------------------------------- + * */ + + L_CrossCorr = L_mult(ppswTVect[i][0], pswPVect[0]); + for (j = 1; j < S_LEN; j++) + L_CrossCorr = L_mac(L_CrossCorr, ppswTVect[i][j], pswPVect[j]); + + pL_CCBuf[i] = L_CrossCorr; + + } + + /* find the shift count associated with the largest CC and G */ + /* ---------------------------------------------------------- */ + L_ccNorm = L_abs(pL_CCBuf[0]); + L_cgNorm = pL_CGBuf[0]; + + for (i = 1; i < iNumLags; i++) + { + L_ccNorm |= L_abs(pL_CCBuf[i]); + L_cgNorm |= pL_CGBuf[i]; + } + + swCCShiftCnt = norm_l(L_ccNorm); + swCGShiftCnt = norm_l(L_cgNorm); + + for (i = 0; i < iNumLags; i++) + { + pswCCBuf[i] = round(L_shl(pL_CCBuf[i], swCCShiftCnt)); + pswCGBuf[i] = round(L_shl(pL_CGBuf[i], swCGShiftCnt)); + } + + /* Maximize C**2/G */ + /* --------------- */ + siLagOffset = maxCCOverGWithSign(pswCCBuf, pswCGBuf, + &swCCMax, &swGMax, + iNumLags); + + /* Determine the offset of the max value into CC buffer */ + /* ---------------------------------------------------- */ + *pswLag = pswLagList[siLagOffset]; + + /* Store Lag Code for best lag result */ + /* ---------------------------------- */ + quantLag(*pswLag, &siLagCode); + + return (siLagCode); +} + +/***************************************************************************** + * + * FUNCTION NAME: decorr + * + * PURPOSE: Decorrelates(orthogonalizes) a set of vectors from a given + * vector. + * + * + * INPUTS: iNumVects - number of vectors to decorrelate + * pswGivenVect[0..39] - array of given vectors + * pswVects[0..359] (voice) [0..279] (unvoiced) - array of + * contiguous vectors to be decorrelated + * OUTPUTS: pswVects[0..359] (voice) [0..279] (unvoiced) - output vectors + * are written back over input vectors + * + * RETURN VALUE: none + * + * IMPLEMENTATION: + * + * REFERENCE: Sub-clause 4.1.10.1 of GSM Recommendation 06.20 + * + * KEYWORDS: decorrelate, codewords, codevectors, orthogonalize, encoder + * + ****************************************************************************/ + +void decorr(int iNumVects, int16_t pswGivenVect[], + int16_t pswVects[]) +{ + +/*___________________________________________________________________________ + | | + | Automatic Variables | + |___________________________________________________________________________| +*/ + int i, + iLoopCnt; + int16_t swNorm_energy, + swTemp; + int16_t swEShift, + swCShift, + swShiftSum, + swQShift; + int32_t L_Energy, + L_Temp1, + L_Temp2, + L_Accum; + +/*___________________________________________________________________________ + | | + | Executable Code | + |___________________________________________________________________________| + */ + + /* Compute normalized energy in given vector */ + /*-------------------------------------------*/ + swEShift = g_corr1(pswGivenVect, &L_Energy); + swNorm_energy = extract_h(L_Energy); + + if (swNorm_energy == 0) + { + return; + } + + /* Decorrelate vectors */ + /*---------------------*/ + + for (iLoopCnt = 0; iLoopCnt < iNumVects; iLoopCnt++) + { + + swCShift = g_corr2(pswGivenVect, &pswVects[iLoopCnt * S_LEN], + &L_Temp1); + L_Temp2 = L_Temp1; + L_Temp1 = L_abs(L_Temp1); + swCShift = sub(swCShift, 1); + swShiftSum = sub(swCShift, swEShift); + L_Temp1 = L_shr(L_Temp1, 1); + swTemp = divide_s(round(L_Temp1), swNorm_energy); + + if (L_Temp2 > 0) + swTemp = negate(swTemp); + + swQShift = norm_s(swTemp); + swTemp = shl(swTemp, swQShift); + swQShift = add(swShiftSum, swQShift); + + if (swQShift > 0) + { + swTemp = shift_r(swTemp, negate(swQShift)); + swQShift = 0; + } + else + swQShift = negate(swQShift); + + for (i = 0; i < S_LEN; i++) + { + L_Accum = L_msu(0x00008000L, pswVects[i + iLoopCnt * S_LEN], SW_MIN); + pswVects[iLoopCnt * S_LEN + i] = extract_h(L_mac(L_Accum, swTemp, + shl(pswGivenVect[i], swQShift))); + } + } +} + +/*************************************************************************** + * + * FUNCTION NAME: g_corr2 + * + * PURPOSE: Calculates correlation between subframe vectors. + * + * + * INPUT: + * + * pswIn[0:39] + * A subframe vector. + * + * pswIn2[0:39] + * A subframe vector. + * + * + * OUTPUT: + * + * *pL_out + * A int32_t containing the normalized correlation + * between the input vectors. + * + * RETURN: + * + * swOut + * Number of right shifts which the accumulator was + * shifted to normalize it. Negative number implies + * a left shift, and therefore an energy larger than + * 1.0. + * + * REFERENCE: Sub-clauses 4.1.10.1 and 4.1.11.1 of GSM + * Recommendation 06.20 + * + * keywords: energy, autocorrelation, correlation, g_corr2 + * + * + **************************************************************************/ + +int16_t g_corr2(int16_t *pswIn, int16_t *pswIn2, + int32_t *pL_out) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_sum; + int16_t swEngyLShft; + int i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Calculate energy in subframe vector (40 samples) */ + /*--------------------------------------------------*/ + + L_sum = L_mult(pswIn[0], pswIn2[0]); + for (i = 1; i < S_LEN; i++) + { + L_sum = L_mac(L_sum, pswIn[i], pswIn2[i]); + } + + + + if (L_sum != 0) + { + + /* Normalize the energy in the output int32_t */ + /*---------------------------------------------*/ + + swEngyLShft = norm_l(L_sum); + *pL_out = L_shl(L_sum, swEngyLShft); /* normalize output + * int32_t */ + } + else + { + + /* Special case: energy is zero */ + /*------------------------------*/ + + *pL_out = L_sum; + swEngyLShft = 0; + } + + return (swEngyLShft); +} + +/*************************************************************************** + * + * FUNCTION NAME: g_quant_vl + * + * PURPOSE: + * + * Joint quantization of excitation gains. + * GS represents the subframe energy relative to the frame energy. + * P0 represents the relative contribution of the first exctitation + * source to the total excitation. + * + * INPUTS: + * + * swUVCode - voicing level (Mode 0-3) + * pswWInput[0:39] - weighted input p(n) (used in mode 0-3) + * swWIShift - weighted input shift factor (right shift, 0,1, or 2) + * pswWLTPVec[0:39] - weighted pitch excitation vector (used in mode 1-3) + * pswWVSVec1[0:39] - weighted 1st v-s codevector (used in mode 0-3) + * pswWVSVec2[0:39] - weighted 2nd v-s codevector (used in mode 0) + * snsRs00 - square root of RS/pitch excitation energy (used in mode 1-3) + * snsRs11 - square root of RS/1st v-s codevector energy + * (used in mode 0-3) + * snsRs22 - square root of RS/2nd v-s codevector energy (used in mode 0) + * + * pppsrGsp0[0:3][0:31][0:4] - lookup table + * + * OUTPUTS: + * + * None + * + * RETURN VALUE: + * + * siCode - output quantized gain code (5 bits) + * + * IMPLEMENTATION: + * + * Calculates first the parameters required for error equation 7.21: + * + * Rcc(k,j) k = 0,1, j=k,1 + * Rx(k) k = 0,1 + * RS + * Rpc(k) k = 0,1 + * a,b,c,d,e + * + * The constant terms in equation 7.21 are stored in ROM instead of GS + * and P0. There is one vector quantizer for each voicing state. + * + * REFERENCE: Sub-clause 4.1.11 and 4.1.11.1 of GSM Recommendation 06.20 + * + * KEYWORDS: gain quantization, energy domain transforms, p0, gs + * + **************************************************************************/ + +int16_t g_quant_vl(int16_t swUVCode, + int16_t pswWInput[], int16_t swWIShift, + int16_t pswWLTPVec[], + int16_t pswWVSVec1[], int16_t pswWVSVec2[], + struct NormSw snsRs00, struct NormSw snsRs11, + struct NormSw snsRs22) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Temp, + L_Temp2; + int16_t swShift; + struct NormSw ErrorTerm[6]; + int16_t i, + siCode, + siNormShift, + siNormMin; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Test voicing level, mode 0-3 */ + /* ---------------------------- */ + + if (swUVCode == 0) + { + + /* Unvoiced */ + /* -------- */ + + /* Compute cross correlation Rpc(0) */ + /* -------------------------------- */ + + + ErrorTerm[0].sh = g_corr2(pswWInput, pswWVSVec1, &L_Temp); + ErrorTerm[0].man = round(L_Temp); + + /* Compute cross correlation Rpc(1) */ + /* -------------------------------- */ + + ErrorTerm[1].sh = g_corr2(pswWInput, pswWVSVec2, &L_Temp); + ErrorTerm[1].man = round(L_Temp); + + /* Compute cross correlation Rcc(0,1) */ + /* ---------------------------------- */ + + + ErrorTerm[2].sh = g_corr2(pswWVSVec1, pswWVSVec2, &L_Temp); + ErrorTerm[2].man = round(L_Temp); + + /* Compute correlation Rcc(0,0) */ + /* ---------------------------- */ + + ErrorTerm[3].sh = g_corr1(pswWVSVec1, &L_Temp); + ErrorTerm[3].man = round(L_Temp); + + /* Compute correlation Rcc(1,1) */ + /* ---------------------------- */ + + ErrorTerm[4].sh = g_corr1(pswWVSVec2, &L_Temp); + ErrorTerm[4].man = round(L_Temp); + + /* Compute correlation Rpp */ + /* ----------------------- */ + + ErrorTerm[5].sh = g_corr1(pswWInput, &L_Temp); + ErrorTerm[5].man = round(L_Temp); + + /* Compute gain tweak factor, adjusts A and B error coefs */ + /* ------------------------------------------------------ */ + gainTweak(&ErrorTerm[0]); + + /* Compute error coefficient A, equation 5.22 */ + /* ------------------------------------------ */ + + L_Temp = L_mult(ErrorTerm[0].man, snsRs11.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[0].sh = add(ErrorTerm[0].sh, swShift); + ErrorTerm[0].man = round(L_shl(L_Temp, swShift)); + ErrorTerm[0].sh = add(ErrorTerm[0].sh, snsRs11.sh); + siNormMin = ErrorTerm[0].sh; + + /* Compute error coefficient B, equation 5.23 */ + /* ------------------------------------------ */ + + L_Temp = L_mult(ErrorTerm[1].man, snsRs22.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[1].sh = add(ErrorTerm[1].sh, swShift); + ErrorTerm[1].man = round(L_shl(L_Temp, swShift)); + ErrorTerm[1].sh = add(ErrorTerm[1].sh, snsRs22.sh); + if (sub(ErrorTerm[1].sh, siNormMin) < 0) + siNormMin = ErrorTerm[1].sh; + + /* Compute error coefficient C, equation 5.24 */ + /* ------------------------------------------ */ + + L_Temp = L_mult(ErrorTerm[2].man, snsRs11.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[2].sh = add(ErrorTerm[2].sh, swShift); + ErrorTerm[2].man = round(L_shl(L_Temp, swShift)); + L_Temp = L_mult(ErrorTerm[2].man, snsRs22.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[2].sh = add(ErrorTerm[2].sh, swShift); + ErrorTerm[2].man = round(L_shl(L_Temp, swShift)); + ErrorTerm[2].sh = add(ErrorTerm[2].sh, snsRs11.sh); + ErrorTerm[2].sh = add(ErrorTerm[2].sh, snsRs22.sh); + ErrorTerm[2].sh = add(ErrorTerm[2].sh, swWIShift); + if (sub(ErrorTerm[2].sh, siNormMin) < 0) + siNormMin = ErrorTerm[2].sh; + + /* Compute error coefficient D, equation 5.25 */ + /* ------------------------------------------ */ + + L_Temp = L_mult(ErrorTerm[3].man, snsRs11.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[3].sh = add(ErrorTerm[3].sh, swShift); + ErrorTerm[3].man = round(L_shl(L_Temp, swShift)); + L_Temp = L_mult(ErrorTerm[3].man, snsRs11.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[3].sh = add(ErrorTerm[3].sh, swShift); + ErrorTerm[3].man = round(L_shl(L_Temp, swShift)); + ErrorTerm[3].sh = add(ErrorTerm[3].sh, snsRs11.sh); + ErrorTerm[3].sh = add(ErrorTerm[3].sh, snsRs11.sh); + ErrorTerm[3].sh = add(ErrorTerm[3].sh, swWIShift); + + if (sub(ErrorTerm[3].sh, siNormMin) < 0) + siNormMin = ErrorTerm[3].sh; + + /* Compute error coefficient E, equation 5.26 */ + /* ------------------------------------------ */ + + L_Temp = L_mult(ErrorTerm[4].man, snsRs22.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[4].sh = add(ErrorTerm[4].sh, swShift); + ErrorTerm[4].man = round(L_shl(L_Temp, swShift)); + L_Temp = L_mult(ErrorTerm[4].man, snsRs22.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[4].sh = add(ErrorTerm[4].sh, swShift); + ErrorTerm[4].man = round(L_shl(L_Temp, swShift)); + ErrorTerm[4].sh = add(ErrorTerm[4].sh, snsRs22.sh); + ErrorTerm[4].sh = add(ErrorTerm[4].sh, snsRs22.sh); + ErrorTerm[4].sh = add(ErrorTerm[4].sh, swWIShift); + + if (sub(ErrorTerm[4].sh, siNormMin) < 0) + siNormMin = ErrorTerm[4].sh; + + } + + else + { /* Voicing level */ + + /* Voiced */ + /* ------ */ + + /* Compute cross correlation Rpc(0) */ + /* -------------------------------- */ + + + ErrorTerm[0].sh = g_corr2(pswWInput, pswWLTPVec, &L_Temp); + ErrorTerm[0].man = round(L_Temp); + + /* Compute cross correlation Rpc(1) */ + /* -------------------------------- */ + + + ErrorTerm[1].sh = g_corr2(pswWInput, pswWVSVec1, &L_Temp); + ErrorTerm[1].man = round(L_Temp); + + /* Compute cross correlation Rcc(0,1) */ + /* ---------------------------------- */ + + + ErrorTerm[2].sh = g_corr2(pswWLTPVec, pswWVSVec1, &L_Temp); + ErrorTerm[2].man = round(L_Temp); + + /* Compute correlation Rcc(0,0) */ + /* ---------------------------- */ + + ErrorTerm[3].sh = g_corr1(pswWLTPVec, &L_Temp); + ErrorTerm[3].man = round(L_Temp); + + /* Compute correlation Rcc(1,1) */ + /* ---------------------------- */ + + ErrorTerm[4].sh = g_corr1(pswWVSVec1, &L_Temp); + ErrorTerm[4].man = round(L_Temp); + + /* Compute correlation Rpp */ + /* ----------------------- */ + + ErrorTerm[5].sh = g_corr1(pswWInput, &L_Temp); + ErrorTerm[5].man = round(L_Temp); + + /* Compute gain tweak factor, adjusts A and B error coefs */ + /* ------------------------------------------------------ */ + + gainTweak(&ErrorTerm[0]); + + /* Compute error coefficient A, equation 5.22 */ + /* ------------------------------------------ */ + + L_Temp = L_mult(ErrorTerm[0].man, snsRs00.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[0].sh = add(ErrorTerm[0].sh, swShift); + ErrorTerm[0].man = round(L_shl(L_Temp, swShift)); + ErrorTerm[0].sh = add(ErrorTerm[0].sh, snsRs00.sh); + siNormMin = ErrorTerm[0].sh; + + /* Compute error coefficient B, equation 5.23 */ + /* ------------------------------------------ */ + + L_Temp = L_mult(ErrorTerm[1].man, snsRs11.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[1].sh = add(ErrorTerm[1].sh, swShift); + ErrorTerm[1].man = round(L_shl(L_Temp, swShift)); + ErrorTerm[1].sh = add(ErrorTerm[1].sh, snsRs11.sh); + if (sub(ErrorTerm[1].sh, siNormMin) < 0) + siNormMin = ErrorTerm[1].sh; + + /* Compute error coefficient C, equation 5.24 */ + /* ------------------------------------------ */ + + L_Temp = L_mult(ErrorTerm[2].man, snsRs00.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[2].sh = add(ErrorTerm[2].sh, swShift); + ErrorTerm[2].man = round(L_shl(L_Temp, swShift)); + L_Temp = L_mult(ErrorTerm[2].man, snsRs11.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[2].sh = add(ErrorTerm[2].sh, swShift); + ErrorTerm[2].man = round(L_shl(L_Temp, swShift)); + ErrorTerm[2].sh = add(ErrorTerm[2].sh, snsRs00.sh); + ErrorTerm[2].sh = add(ErrorTerm[2].sh, snsRs11.sh); + ErrorTerm[2].sh = add(ErrorTerm[2].sh, swWIShift); + if (sub(ErrorTerm[2].sh, siNormMin) < 0) + siNormMin = ErrorTerm[2].sh; + + /* Compute error coefficient D, equation 5.25 */ + /* ------------------------------------------ */ + + L_Temp = L_mult(ErrorTerm[3].man, snsRs00.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[3].sh = add(ErrorTerm[3].sh, swShift); + ErrorTerm[3].man = round(L_shl(L_Temp, swShift)); + L_Temp = L_mult(ErrorTerm[3].man, snsRs00.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[3].sh = add(ErrorTerm[3].sh, swShift); + ErrorTerm[3].man = round(L_shl(L_Temp, swShift)); + ErrorTerm[3].sh = add(ErrorTerm[3].sh, snsRs00.sh); + ErrorTerm[3].sh = add(ErrorTerm[3].sh, snsRs00.sh); + ErrorTerm[3].sh = add(ErrorTerm[3].sh, swWIShift); + if (sub(ErrorTerm[3].sh, siNormMin) < 0) + siNormMin = ErrorTerm[3].sh; + + /* Compute error coefficient E, equation 5.26 */ + /* ------------------------------------------ */ + + L_Temp = L_mult(ErrorTerm[4].man, snsRs11.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[4].sh = add(ErrorTerm[4].sh, swShift); + ErrorTerm[4].man = round(L_shl(L_Temp, swShift)); + L_Temp = L_mult(ErrorTerm[4].man, snsRs11.man); + swShift = norm_s(extract_h(L_Temp)); + ErrorTerm[4].sh = add(ErrorTerm[4].sh, swShift); + ErrorTerm[4].man = round(L_shl(L_Temp, swShift)); + ErrorTerm[4].sh = add(ErrorTerm[4].sh, snsRs11.sh); + ErrorTerm[4].sh = add(ErrorTerm[4].sh, snsRs11.sh); + ErrorTerm[4].sh = add(ErrorTerm[4].sh, swWIShift); + if (sub(ErrorTerm[4].sh, siNormMin) < 0) + siNormMin = ErrorTerm[4].sh; + + } /* Voicing level */ + + + + /* Normalize all error coefficients to same shift count */ + /* ---------------------------------------------------- */ + + for (i = 0; i < GSP0_VECTOR_SIZE; i++) + { + L_Temp = L_deposit_h(ErrorTerm[i].man); + siNormShift = sub(ErrorTerm[i].sh, siNormMin); + if (siNormShift > 0) + L_Temp = L_shr(L_Temp, siNormShift); + ErrorTerm[i].man = round(L_Temp); + } + + + /* Codebook search, find max of error equation 5.21 */ + /* ------------------------------------------------ */ + + L_Temp2 = 0x80000000; + + for (i = 0; i < GSP0_NUM; i++) + { + + L_Temp = L_mult(pppsrGsp0[swUVCode][i][0], ErrorTerm[0].man); + L_Temp = L_mac(L_Temp, pppsrGsp0[swUVCode][i][1], ErrorTerm[1].man); + L_Temp = L_mac(L_Temp, pppsrGsp0[swUVCode][i][2], ErrorTerm[2].man); + L_Temp = L_mac(L_Temp, pppsrGsp0[swUVCode][i][3], ErrorTerm[3].man); + L_Temp = L_mac(L_Temp, pppsrGsp0[swUVCode][i][4], ErrorTerm[4].man); + if (L_sub(L_Temp2, L_Temp) < 0) + { + L_Temp2 = L_Temp; + siCode = i; /* Save best code */ + } + } + return (siCode); +} + +/*************************************************************************** + * + * FUNCTION NAME: gainTweak + * + * PURPOSE: + * + * Calculates gain bias factor, limits it, and + * applies it to A and B error coefficients. + * + * INPUTS: + * + * psErrorTerm[0:5] - array (6) of error coefficients in floating + * point format + * + * OUTPUTS: + * + * psErrorTerm[0:5] - array of gain adjusted A and B error coefficients + * + * RETURN VALUE: + * + * None + * + * IMPLEMENTATION: + * + * The gain tweak is: + * + * Rpp*Rcc(0,0)*Rcc(1,1) - Rpp*Rcc(0,1)*Rcc(0,1) + *sqrt(---------------------------------------------------------------------) + * Rcc(0,0)*Rpc(1)*Rpc(1)-2*Rcc(0,1)*Rpc(0)*Rpc(1)+Rcc(1,1)*Rpc(0)*Rpc(0) + * + * REFERENCE: Sub-clause 4.1.11.1 of GSM Recommendation 06.20 + * + * KEYWORDS: gain tweak, g_quant_vl + * + **************************************************************************/ + +void gainTweak(struct NormSw *psErrorTerm) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_Temp; + int16_t swTemp, + swNum, + swDenom, + swGainTweak, + swShift; + struct NormSw terms[5]; + int16_t i, + siNormShift, + siNorm; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* Calculate third order terms in the gain tweak factor, while + * maintaining the largest exponent */ + /* ---------------------------------------------------- */ + + /* Compute Rpp*Rcc(0,0)*Rcc(1,1) */ + /* ----------------------------- */ + + L_Temp = L_mult(psErrorTerm[3].man, psErrorTerm[5].man); + swShift = norm_s(extract_h(L_Temp)); + terms[0].sh = add(psErrorTerm[3].sh, swShift); + terms[0].man = round(L_shl(L_Temp, swShift)); + L_Temp = L_mult(terms[0].man, psErrorTerm[4].man); + swShift = norm_s(extract_h(L_Temp)); + terms[0].sh = add(terms[0].sh, swShift); + terms[0].man = round(L_shl(L_Temp, swShift)); + terms[0].sh = add(terms[0].sh, psErrorTerm[4].sh); + terms[0].sh = add(terms[0].sh, psErrorTerm[5].sh); + /* Init. siNorm */ + siNorm = terms[0].sh; + + /* Compute Rpp*Rcc(0,1)*Rcc(0,1) */ + /* ----------------------------- */ + + L_Temp = L_mult(psErrorTerm[2].man, psErrorTerm[2].man); + swShift = norm_s(extract_h(L_Temp)); + terms[1].sh = add(psErrorTerm[2].sh, swShift); + terms[1].man = round(L_shl(L_Temp, swShift)); + L_Temp = L_mult(terms[1].man, psErrorTerm[5].man); + swShift = norm_s(extract_h(L_Temp)); + terms[1].sh = add(terms[1].sh, swShift); + terms[1].man = round(L_shl(L_Temp, swShift)); + terms[1].sh = add(terms[1].sh, psErrorTerm[2].sh); + terms[1].sh = add(terms[1].sh, psErrorTerm[5].sh); + if (sub(terms[1].sh, siNorm) < 0) + siNorm = terms[1].sh; + + /* Compute Rcc(0,0)*Rpc(1)*Rpc(1) */ + /* ------------------------------ */ + + L_Temp = L_mult(psErrorTerm[1].man, psErrorTerm[1].man); + swShift = norm_s(extract_h(L_Temp)); + terms[2].sh = add(psErrorTerm[1].sh, swShift); + terms[2].man = round(L_shl(L_Temp, swShift)); + L_Temp = L_mult(terms[2].man, psErrorTerm[3].man); + swShift = norm_s(extract_h(L_Temp)); + terms[2].sh = add(terms[2].sh, swShift); + terms[2].man = round(L_shl(L_Temp, swShift)); + terms[2].sh = add(terms[2].sh, psErrorTerm[1].sh); + terms[2].sh = add(terms[2].sh, psErrorTerm[3].sh); + if (sub(terms[2].sh, siNorm) < 0) + siNorm = terms[2].sh; + + /* Compute 2*Rcc(0,1)*Rpc(0)*Rpc(1) */ + /* -------------------------------- */ + + L_Temp = L_mult(psErrorTerm[0].man, psErrorTerm[1].man); + swShift = norm_s(extract_h(L_Temp)); + terms[3].sh = add(psErrorTerm[0].sh, swShift); + terms[3].man = round(L_shl(L_Temp, swShift)); + L_Temp = L_mult(terms[3].man, psErrorTerm[2].man); + swShift = norm_s(extract_h(L_Temp)); + terms[3].sh = add(terms[3].sh, swShift); + terms[3].man = round(L_shl(L_Temp, swShift)); + terms[3].sh = add(terms[3].sh, psErrorTerm[1].sh); + terms[3].sh = add(terms[3].sh, psErrorTerm[2].sh); + terms[3].sh = sub(terms[3].sh, 1); /* Multiply by 2 */ + if (sub(terms[3].sh, siNorm) < 0) + siNorm = terms[3].sh; + + /* Compute Rcc(1,1)*Rpc(0)*Rpc(0) */ + /* ------------------------------ */ + + L_Temp = L_mult(psErrorTerm[0].man, psErrorTerm[4].man); + swShift = norm_s(extract_h(L_Temp)); + terms[4].sh = add(psErrorTerm[0].sh, swShift); + terms[4].man = round(L_shl(L_Temp, swShift)); + L_Temp = L_mult(terms[4].man, psErrorTerm[0].man); + swShift = norm_s(extract_h(L_Temp)); + terms[4].sh = add(terms[4].sh, swShift); + terms[4].man = round(L_shl(L_Temp, swShift)); + terms[4].sh = add(terms[4].sh, psErrorTerm[0].sh); + terms[4].sh = add(terms[4].sh, psErrorTerm[4].sh); + if (sub(terms[4].sh, siNorm) < 0) + siNorm = terms[4].sh; + + /* Normalize all terms to same shift count */ + /* --------------------------------------- */ + + for (i = 0; i < 5; i++) + { + L_Temp = L_deposit_h(terms[i].man); + siNormShift = sub(terms[i].sh, siNorm); + if (siNormShift > 0) + { + L_Temp = L_shr(L_Temp, siNormShift); + } + terms[i].man = round(L_Temp); + } + + /* Calculate numerator */ + /* ------------------- */ + + /* Rpp*Rcc(0,0)*Rcc(1,1) - Rpp*Rcc(0,1)*Rcc(0,1) */ + /* --------------------------------------------- */ + + swNum = sub(terms[0].man, terms[1].man); + + /* Skip gain tweak if numerator =< 0 */ + /* --------------------------------- */ + + if (swNum <= 0) + return; + + /* Calculate denominator */ + /* --------------------- */ + + /* Rcc(0,0)*Rpc(1)*Rpc(1)-2*Rcc(0,1)*Rpc(0)*Rpc(1)+Rcc(1,1)*Rpc(0)*Rpc(0) */ + /*----------------------------------------------------------------------*/ + + swDenom = sub(terms[2].man, terms[3].man); + swDenom = add(swDenom, terms[4].man); + + /* Skip gain tweak if denominator =< 0 */ + /* ----------------------------------- */ + + if (swDenom <= 0) + return; + + /* Compare numerator to denominator, skip if tweak =< 1 */ + /* ---------------------------------------------------- */ + + swTemp = sub(swNum, swDenom); + if (swTemp <= 0) + return; + + /* Normalize and do divide */ + /* ----------------------- */ + + swShift = norm_s(swNum); + siNormShift = sub(swShift, 1); /* Multiply by 2 */ + swNum = shl(swNum, swShift); + swNum = shr(swNum, 1); + swShift = norm_s(swDenom); + siNormShift = sub(siNormShift, swShift); + swDenom = shl(swDenom, swShift); + swTemp = divide_s(swNum, swDenom); + swShift = norm_s(swTemp); + siNormShift = add(siNormShift, swShift); + L_Temp = L_shl(L_deposit_h(swTemp), swShift); + + /* Calculate square root */ + /* --------------------- */ + + swTemp = sqroot(L_Temp); + + /* If odd no. of shifts compensate by sqrt(0.5) */ + /* -------------------------------------------- */ + + if (siNormShift & 1) + { + L_Temp = L_mult(0x5a82, swTemp); + siNormShift = sub(siNormShift, 1); + } + else + L_Temp = L_deposit_h(swTemp); + siNormShift = shr(siNormShift, 1); + swShift = norm_s(extract_h(L_Temp)); + siNormShift = add(siNormShift, swShift); + swGainTweak = round(L_shl(L_Temp, swShift)); + + /* If exponent > -1, skip gain tweak */ + /* --------------------------------- */ + + if (add(1, siNormShift) > 0) + return; + + /* If exponent < -1, limit gain tweak to GTWEAKMAX */ + /* ----------------------------------------------- */ + + if (add(1, siNormShift) < 0) + swGainTweak = GTWEAKMAX; + else + { + + /* If exponent = -1, compare to GTWEAKMAX */ + /* -------------------------------------- */ + + if (sub(GTWEAKMAX, swGainTweak) < 0) + swGainTweak = GTWEAKMAX; + } + + /* Multiply gain tweak factor on A and B error terms */ + /* ------------------------------------------------- */ + + L_Temp = L_mult(swGainTweak, psErrorTerm[0].man); + swShift = norm_s(extract_h(L_Temp)); + psErrorTerm[0].sh = add(psErrorTerm[0].sh, swShift); + psErrorTerm[0].sh = sub(psErrorTerm[0].sh, 1); + psErrorTerm[0].man = round(L_shl(L_Temp, swShift)); + + L_Temp = L_mult(swGainTweak, psErrorTerm[1].man); + swShift = norm_s(extract_h(L_Temp)); + psErrorTerm[1].sh = add(psErrorTerm[1].sh, swShift); + psErrorTerm[1].sh = sub(psErrorTerm[1].sh, 1); + psErrorTerm[1].man = round(L_shl(L_Temp, swShift)); + +} + +/*************************************************************************** + * + * FUNCTION NAME: hnwFilt + * + * PURPOSE: + * Performs the filtering operation for harmonic noise weighting. + * + * INPUTS: + * pswInSample[0:39] - array of input speech signal, + * pswInSample points to the "oldest" sample of the + * current subframe to be hnw filtered, S_LEN samples + * will be stored in this array, this data is not + * explicitly modified. + * + * pswState[0:183] - array of state of samples, the most + * recent sample is the tail of the state buffer, + * used only for full- state filtering, this data is + * not modified + * pswInCoef[0:5] - array of unmodified filter coefficients + * iStateOffset - address offset from a sample in the subframe back + * to the oldest element of the state used in the interpolating + * filter for that sample. Although the subframe samples and + * state information can come from different buffers, this + * offset represents the case in which the state and sample + * information are in the same buffer + * swZeroState - indicate if the interpolating filter should be + * "zero-state" filtering or "full-state" filtering: + * 0 ==> zero-state filtering + * !0 ==> full-state filtering + * iNumSamples - the number of samples that are to be filtered, + * required to be less than or equal to S_LEN in order to + * correctly match speech samples with sample states for the + * filtering procedure + * + * OUTPUTS: + * pswOutSample[0:39] - array of output filtered speech signal, + * pswOutSample points to the "oldest" sample location, S_LEN + * filtered samples will be stored at the buffer associated with + * this array, can implicitly overwrite input samples with + * with filtered samples by setting pswOutSample = pswInSample + * + * RETURN VALUE: + * none + * + * IMPLEMENTATION: + * The harmonic noise weighting filter is implemented in reverse + * temporal order, from most recent input sample backwards through + * the input sample array. The procedure follows the equation: + * x(n) = x(n) - PW_COEF*x(n - lag) + * where the PW_COEF is the pitch weighting for the current + * subframe and lag is the full-resolution lag for the current + * subframe. x(n - lag) is found by implementing a CG_INT_MACS- + * order FIR interpolating filter + * + * Harmonic noise weighting is discussed in secion 5.5. + * + * REFERENCE: Sub-clause 4.1.9 of GSM Recommendation 06.20 + * + * KEYWORDS: T_SUB, LAG, HNW_FILT, PW_COEF, CG_INT_MACS, S_LEN, LSMAX + * + **************************************************************************/ + +void hnwFilt(int16_t pswInSample[], + int16_t pswOutSample[], + int16_t pswState[], + int16_t pswInCoef[], + int iStateOffset, + int16_t swZeroState, + int iNumSamples) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + int32_t L_temp; + int i, + j; + + int iStatIndx = S_LEN - 1 + iStateOffset; + int iStatIndx1 = S_LEN + iStateOffset; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + if (swZeroState == 0) + { + + /* zero state response assumes input and output arrays are the same */ + /*------------------------------------------------------------------*/ + + for (i = 0; i < iNumSamples; i++) + { + + /* get input with rounding */ + /*-------------------------*/ + L_temp = L_mac((long) 16384, pswInSample[S_LEN - i - 1], 0x4000); + + for (j = 5; (j >= 0) && (iStatIndx - i + j >= 0); j--) + /* evaluate taps 1 - 6 that point to input */ + /*-----------------------------------------*/ + L_temp = L_mac(L_temp, pswInSample[iStatIndx - i + j], pswInCoef[j]); + + pswOutSample[S_LEN - 1 - i] = extract_h(L_shl(L_temp, 1)); + } + } + else + { + for (i = 0; i < iNumSamples; i++) + { + + /* get input with rounding */ + /*-------------------------*/ + L_temp = L_mac((long) 16384, pswInSample[S_LEN - i - 1], 0x4000); + + for (j = 5; (j >= 0) && (iStatIndx - i + j >= 0); j--) + /* evaluate taps 1 - 6 that point to input */ + /*-----------------------------------------*/ + L_temp = L_mac(L_temp, pswInSample[iStatIndx - i + j], pswInCoef[j]); + + for (; (j >= 0); j--) + /* evaluate taps 1 - 6 that point to state */ + /*----------------------------------------*/ + L_temp = L_mac(L_temp, pswState[iStatIndx1 - i + j], pswInCoef[j]); + + pswOutSample[S_LEN - 1 - i] = extract_h(L_shl(L_temp, 1)); + } + } + +} + +/*************************************************************************** + * + * FUNCTION NAME: sfrmAnalysis + * + * PURPOSE: + * + * Determines the synthetic excitation for a subframe. + * + * INPUTS: + * + * pswWSpeech + * Input weighted speech vector to be matched. + * + * swVoicingMode + * + * Voicing mode 0,1,2 or 3. 0 is unvoiced. A + * frame parameter. + * + * snsSqrtRs + * + * Normalized estimate of the excitation energy + * + * pswHCoefs + * + * Coefficientss used in weighted synthesis filter, + * H(z), (a negated version is used). pswHCoefs[0] + * is t=-1 tap, pswHCoefs[9] is t=-10 tap. + * + * pswLagList + * + * List of lags to be searched in the long-term + * predictor, determined by the open-loop lag search. + * + * siNumLags + * + * Number of lags in pswLagList. + * + * swPitch + * + * Fundamental pitch value to be used in harmonic- + * noise-weighting, actualPitch*OS_FCTR. + * + * swHNWCoef + * Coefficient of the harmonic-noise-weighting filter. + * + * ppsrCGIntFilt[0:5][0:5] + * + * polyphase interpolation filter, + * ppsrCGIntFilt[iTap][iPhase], OS_FCTR phases, + * CG_INT_MACS taps per phase. Used to construct + * sequences delayed by fractional lags for Harmonic- + * Noise-Weighting. + * + * pppsrUvCodeVec[0:1][0:6][0:39] + * + * unvoiced codebooks: + * pppsrUvCodeVec[codeBook][vectorNumber][time] + * + * pppsrVcdCodeVec[0][0:8][0:39] + * + * voiced codebook: + * pppsrVcdCodeVect[codebook(=0)][vectorNumber][time] + * + * swSP + * speech flag (DTX mode) + * + * OUTPUTS: + * + * psiLagCode + * + * Lag code: frame- or delta-, or zero if unvoiced. + * + * psiVSCode1 + * + * First vector-sum codebook code. + * + * psiVSCode2 + * + * Second vector-sum codebook code, or zero if voiced. + * + * psiGsp0Code + * + * Gain quantizer code. + * + * DESCRIPTION: + * + * sfrmAnalysis() is the calling function for the subframe analysis + * functions. All subframe based processing is done by it and its + * daughter functions. All functions in this file are called by + * sfrmAnalysis() or one of its daughter functions. As can be seen + * above, this routine will select the LTP lag, the VSELP + * codevector(s) and the GSP0 codeword. It is called by + * speechEncoder(). + * + * The subframe processing can follow one of two paths depending on + * whether the frame is voiced or unvoiced. These two paths are now + * described. + * + * First the zero input response of H(z) is calculated (lpcZiIir()); + * then subtracted from the weighted speech (W(z)). The outcome, p(n) + * or pswWSVec[], will be the vector matched by the first excitation + * vector (either adaptive or first VSELP codevector). The p(n) + * vector is scaled to prevent overflow. + * + * If the frame is voiced, the closed loop lag search (closedLoop()) + * is performed. An adaptive codevector lag is selected. Using the + * open loop "pitch" value, the harmonic noise weighting + * coefficients are obtained. The adaptive codevector is + * reconstructed (fp_ex()), and weighted through the (zero state) + * spectral (lpcZsIir()) and harmonic noise weighting filters + * (hnwFilt()). + * + * The basis vectors are also filtered through the weighting + * filters. If the frame is unvoiced, there is no spectral noise + * weighting. + * + * If voiced the VSELP basis vectors are decorrelated (decorr()) + * from the selected adaptive (LTP) codevector, and the VSELP + * codevector search is initiated (v_srch()). + * + * If unvoiced, the first VSELP codevector search is performed + * (without any decorrelation). After a vector from the first VSELP + * codebook has been selected, the second set of basis vectors are + * decorrelated from the selected vector. + * + * Once all the excitation vectors have been selected, the gain + * quantizer is called, g_quant_vl(). + * + * Finally, once all subframe parameters have been found, the + * selected excitation is scaled according to GSP0 (scaleExcite()), + * and the composite excitation is entered into the long term + * predictor history. The final excitation is also used to update + * H(z) and C(z). + * + * REFERENCE: Sub-clauses 4.1.8.5, 4.1.9 - 4.1.12 of GSM + * Recommendation 06.20 + * + * Keywords: codewords, lag, codevectors, gsp0, decoding, analysis, t_sub + * + **************************************************************************/ + +void sfrmAnalysis(int16_t *pswWSpeech, + int16_t swVoicingMode, + struct NormSw snsSqrtRs, + int16_t *pswHCoefs, + int16_t *pswLagList, + short siNumLags, + int16_t swPitch, + int16_t swHNWCoef, + short *psiLagCode, + short *psiVSCode1, + short *psiVSCode2, + short *psiGsp0Code, + int16_t swSP) +{ + +/*_________________________________________________________________________ + | | + | Static Variables | + |_________________________________________________________________________| +*/ + + static short siPrevLagCode; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + short i, + j, + siCode, + siIntPitch, + siRemainder; + short siHnwOffset, + siHnwNum, + siNumBasisVecs; + + int16_t swLag, + swPnEnergy, + swPnShift, + swSampleA; + int16_t swLtpShift; + + int32_t L_PnEnergy; + + struct NormSw snsRs00, + snsRs11, + snsRs22; + + int16_t pswWSVec[S_LEN], + pswTempVec[S_LEN]; + int16_t pswPVec[S_LEN], + pswWPVec[S_LEN]; + int16_t ppswVselpEx[2][S_LEN], + ppswWVselpEx[2][S_LEN]; + int16_t pswWBasisVecs[9 * S_LEN], + pswBitArray[9]; + int16_t pswHNWCoefs[CG_INT_MACS]; + + int16_t *pswLtpStateOut; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + pswLtpStateOut = pswLtpStateBase + LTP_LEN; + + if (swSP == 1) /* DTX mode */ + { /* DTX mode */ + + /* if not in CNI mode */ + /*--------------------*/ + + /* Get the zero-input response of H(z) */ + /*-------------------------------------*/ + + lpcZiIir(pswHCoefs, pswHState, pswTempVec); + + /* Subtract the zero-input response of H(z) from W(z)-weighted speech. */ + /* The result is the vector to match for the adaptive codebook (long- */ + /* term-predictor) search in voiced modes, or the vector to match for */ + /* all synthetic excitation searches in unvoiced mode. */ + /*---------------------------------------------------------------------*/ + + for (i = 0; i < S_LEN; i++) + { + + pswWSVec[i] = sub(pswWSpeech[i], pswTempVec[i]); + } + + /* scale the weighted speech vector (p[n]) s.t. its energy is strictly */ + /* less than 1.0 */ + /*---------------------------------------------------------------------*/ + + swSampleA = shr(pswWSVec[0], 2); + L_PnEnergy = L_mac(0x001dff4cL, swSampleA, swSampleA); + for (i = 1; i < S_LEN; i++) + { + swSampleA = shr(pswWSVec[i], 2); /* reduces energy by 16 */ + L_PnEnergy = L_mac(L_PnEnergy, swSampleA, swSampleA); + } + + swPnEnergy = round(L_PnEnergy); + + if (sub(swPnEnergy, 0x7ff) <= 0) + { /* E = [0..0x7ff] */ + + swPnShift = 0; + + } + else + { + + if (sub(swPnEnergy, 0x1fff) <= 0) + { /* E = (0x7ff.. 0x1fff] */ + swPnShift = 1; + + } + else + { + + swPnShift = 2; /* E = (0x1fff..0x7fff] */ + + } + } + + /* shift pswWSVect down by the shift factor */ + /*------------------------------------------*/ + + for (i = 0; i < S_LEN; i++) + pswWSVec[i] = shr(pswWSVec[i], swPnShift); + + + if (swVoicingMode > 0) + { + + /* Do restricted adaptive codebook (long-term-predictor) search: */ + /* the search is restricted to the lags passed in from the */ + /* open-loop lag search */ + /*---------------------------------------------------------------*/ + + siCode = closedLoopLagSearch(pswLagList, siNumLags, + pswLtpStateBase, pswHCoefs, pswWSVec, + &swLag, &swLtpShift); + + /* Construct frame-lag code if this is the first subframe, */ + /* or delta-lag code if it is not the first subframe */ + /*---------------------------------------------------------*/ + + if (swVoicingMode > 0) + { + + if (giSfrmCnt == 0) + { + siPrevLagCode = siCode; + *psiLagCode = siCode; + } + else + { + + *psiLagCode = add(sub(siCode, siPrevLagCode), DELTA_LEVELS / 2); + siPrevLagCode = siCode; + } + } + + /* From the value of the fundamental pitch obtained in the open-loop */ + /* lag search, get the correct phase of the interpolating filter, */ + /* and scale the coefficients by the Harmonic-Noise-Weighting */ + /* coefficient. The result is the interpolating coefficients scaled */ + /* by the HNW coefficient. These will be used in all C(z) filtering */ + /*-------------------------------------------------------------------*/ + + get_ipjj(swPitch, &siIntPitch, &siRemainder); + + for (i = 0; i < CG_INT_MACS; i++) + { + + pswHNWCoefs[i] = mult_r(negate(ppsrCGIntFilt[i][siRemainder]), + swHNWCoef); + } + + /* Calculate a few values which will speed up C(z) filtering: */ + /* "HnwOffset" is the distance in samples from the input sample of */ + /* the C(z) filter to the first sample tapped by the interpolating */ + /* filter. "HnwNum" is the number of samples which need to be */ + /* filtered by C(z) in the zero-state case. */ + /*-----------------------------------------------------------------*/ + + siHnwOffset = sub(-CG_INT_MACS / 2, siIntPitch); + siHnwNum = sub(S_LEN + CG_INT_MACS / 2 - 1, siIntPitch); + + /* Perform C(z) filter on W(z)-weighted speech, get zero-input */ + /* response of H(z)C(z) combo, subtract zero-input response */ + /* of H(z)C(z) from W(z)C(z)-weighted speech. The result is */ + /* the vector to match for the rest of the synthetic */ + /* excitation searches in the voiced modes */ + /*-------------------------------------------------------------*/ + + hnwFilt(pswWSpeech, pswWSVec, &pswWSpeech[-1], pswHNWCoefs, + siHnwOffset, 1, S_LEN); + + hnwFilt(pswTempVec, pswTempVec, &pswHNWState[HNW_BUFF_LEN - 1], + pswHNWCoefs, siHnwOffset, 1, S_LEN); + + for (i = 0; i < S_LEN; i++) + { + + pswWSVec[i] = shr(sub(pswWSVec[i], pswTempVec[i]), swPnShift); + + } + + /* Recontruct adaptive codebook (long-term-predictor) vector, */ + /* weight it through H(z) and C(z), each with zero state */ + /*------------------------------------------------------------*/ + + fp_ex(swLag, pswLtpStateOut); + + for (i = 0; i < S_LEN; i++) + pswPVec[i] = pswLtpStateOut[i]; + + lpcZsIir(pswPVec, pswHCoefs, pswWPVec); + + if (siHnwNum > 0) + { + hnwFilt(pswWPVec, pswWPVec, NULL, pswHNWCoefs, siHnwOffset, + 0, siHnwNum); + } + for (i = 0; i < S_LEN; i++) + { + pswPVec[i] = shr(pswPVec[i], swLtpShift); + pswWPVec[i] = shr(pswWPVec[i], swLtpShift); + } + + } + else + { + + /* Unvoiced mode: clear all voiced variables */ + /*-------------------------------------------*/ + + swLag = 0; + *psiLagCode = 0; + siHnwNum = 0; + } + + /* "NumBasisVecs" will be the number of basis vectors in */ + /* the vector-sum codebook(s) */ + /*-------------------------------------------------------*/ + + if (swVoicingMode > 0) + siNumBasisVecs = C_BITS_V; + + else + siNumBasisVecs = C_BITS_UV; + + /* Filter the basis vectors through H(z) with zero state, and if */ + /* voiced, through C(z) with zero state */ + /*----------------------------------------------------------------*/ + + for (i = 0; i < siNumBasisVecs; i++) + { + + if (swVoicingMode > 0) + { + + lpcZsIir((int16_t *) pppsrVcdCodeVec[0][i], pswHCoefs, + &pswWBasisVecs[i * S_LEN]); + } + else + { + + lpcZsIir((int16_t *) pppsrUvCodeVec[0][i], pswHCoefs, + &pswWBasisVecs[i * S_LEN]); + } + + if (siHnwNum > 0) + { + + hnwFilt(&pswWBasisVecs[i * S_LEN], &pswWBasisVecs[i * S_LEN], + NULL, pswHNWCoefs, siHnwOffset, 0, siHnwNum); + } + } + + /* If voiced, make the H(z)C(z)-weighted basis vectors orthogonal to */ + /* the H(z)C(z)-weighted adaptive codebook vector */ + /*-------------------------------------------------------------------*/ + + if (swVoicingMode > 0) + decorr(siNumBasisVecs, pswWPVec, pswWBasisVecs); + + /* Do the vector-sum codebook search on the H(z)C(z)-weighted, */ + /* orthogonalized basis vectors */ + /*-------------------------------------------------------------*/ + + *psiVSCode1 = v_srch(pswWSVec, pswWBasisVecs, siNumBasisVecs); + + /* Construct the chosen vector-sum codebook vector from basis vectors */ + /*--------------------------------------------------------------------*/ + + b_con(*psiVSCode1, siNumBasisVecs, pswBitArray); + + if (swVoicingMode > 0) + v_con((int16_t *) pppsrVcdCodeVec[0][0], ppswVselpEx[0], pswBitArray, + siNumBasisVecs); + + else + v_con((int16_t *) pppsrUvCodeVec[0][0], ppswVselpEx[0], pswBitArray, + siNumBasisVecs); + + if (swVoicingMode == 0) + { + + /* Construct the H(z)-weighted 1st-codebook vector */ + /*-------------------------------------------------*/ + + v_con(pswWBasisVecs, ppswWVselpEx[0], pswBitArray, siNumBasisVecs); + + /* Filter the 2nd basis vector set through H(z) with zero state */ + /*--------------------------------------------------------------*/ + + for (i = 0; i < siNumBasisVecs; i++) + { + + lpcZsIir((int16_t *) pppsrUvCodeVec[1][i], pswHCoefs, + &pswWBasisVecs[i * S_LEN]); + } + + /* Make the 2nd set of H(z)-weighted basis vectors orthogonal to the */ + /* H(z)-weighted 1st-codebook vector */ + /*-------------------------------------------------------------------*/ + + decorr(siNumBasisVecs, ppswWVselpEx[0], pswWBasisVecs); + + /* Do the vector-sum codebook search on the H(z)-weighted, */ + /* orthogonalized, 2nd basis vector set */ + /*---------------------------------------------------------*/ + + *psiVSCode2 = v_srch(pswWSVec, pswWBasisVecs, siNumBasisVecs); + + /* Construct the chosen vector-sum codebook vector from the 2nd set */ + /* of basis vectors */ + /*------------------------------------------------------------------*/ + + b_con(*psiVSCode2, siNumBasisVecs, pswBitArray); + + v_con((int16_t *) pppsrUvCodeVec[1][0], ppswVselpEx[1], pswBitArray, + siNumBasisVecs); + } + + else + *psiVSCode2 = 0; + + /* Filter the 1st-codebook vector through H(z) (also through C(z) */ + /* if appropriate) */ + /*----------------------------------------------------------------*/ + + lpcZsIir(ppswVselpEx[0], pswHCoefs, ppswWVselpEx[0]); + + if (siHnwNum > 0) + { + hnwFilt(ppswWVselpEx[0], ppswWVselpEx[0], NULL, pswHNWCoefs, + siHnwOffset, 0, siHnwNum); + } + + if (swVoicingMode == 0) + { + + /* Filter the 2nd-codebook vector through H(z) */ + /*---------------------------------------------*/ + + lpcZsIir(ppswVselpEx[1], pswHCoefs, ppswWVselpEx[1]); + } + + /* Get the square-root of the ratio of residual energy to */ + /* excitation vector energy for each of the excitation sources */ + /*-------------------------------------------------------------*/ + + if (swVoicingMode > 0) + { + + rs_rrNs(pswPVec, snsSqrtRs, &snsRs00); + } + + rs_rrNs(ppswVselpEx[0], snsSqrtRs, &snsRs11); + + if (swVoicingMode == 0) + { + + rs_rrNs(ppswVselpEx[1], snsSqrtRs, &snsRs22); + } + + /* Determine the vector-quantized gains for each of the excitations */ + /*------------------------------------------------------------------*/ + + *psiGsp0Code = g_quant_vl(swVoicingMode, pswWSVec, swPnShift, + pswWPVec, + ppswWVselpEx[0], ppswWVselpEx[1], snsRs00, + snsRs11, snsRs22); + + } /* DTX mode */ + else /* DTX mode */ + { /* DTX mode */ + + /* swSP == 0, currently in comfort noise insertion mode */ /* DTX mode */ + /*------------------------------------------------------*/ /* DTX mode */ + + /* generate the random codevector */ /* DTX mode */ + siNumBasisVecs = C_BITS_UV; /* DTX mode */ + + /* build codevector 1 */ /* DTX mode */ + + b_con(*psiVSCode1, siNumBasisVecs, pswBitArray); /* DTX mode */ + v_con((int16_t *) pppsrUvCodeVec[0][0], ppswVselpEx[0], /* DTX mode */ + pswBitArray, siNumBasisVecs); /* DTX mode */ + + /* build codevector 2 */ /* DTX mode */ + + b_con(*psiVSCode2, siNumBasisVecs, pswBitArray); /* DTX mode */ + v_con((int16_t *) pppsrUvCodeVec[1][0], ppswVselpEx[1], /* DTX mode */ + pswBitArray, siNumBasisVecs); /* DTX mode */ + + + /* get rs_rr for the two vectors */ /* DTX mode */ + rs_rrNs(ppswVselpEx[0], snsSqrtRs, &snsRs11); /* DTX mode */ + rs_rrNs(ppswVselpEx[1], snsSqrtRs, &snsRs22); /* DTX mode */ + + } /* DTX mode */ + + + /* Scale the excitations, each by its gain, and add them. Put the */ + /* result at the end of the adaptive codebook (long-term-predictor */ + /* state) */ + /*-----------------------------------------------------------------*/ + + if (swVoicingMode == 0) + { + + /* unvoiced */ + /* -------- */ + + scaleExcite(ppswVselpEx[0], + pppsrGsp0[swVoicingMode][*psiGsp0Code][0], + snsRs11, ppswVselpEx[0]); + scaleExcite(ppswVselpEx[1], + pppsrGsp0[swVoicingMode][*psiGsp0Code][1], + snsRs22, ppswVselpEx[1]); + + /* now combine the two scaled excitations */ + /* -------------------------------------- */ + for (i = 0; i < S_LEN; i++) + pswTempVec[i] = add(ppswVselpEx[0][i], ppswVselpEx[1][i]); + } + + else + { + + /* voiced */ + /* ------ */ + + scaleExcite(pswPVec, + pppsrGsp0[swVoicingMode][*psiGsp0Code][0], + snsRs00, pswPVec); + scaleExcite(ppswVselpEx[0], + pppsrGsp0[swVoicingMode][*psiGsp0Code][1], + snsRs11, ppswVselpEx[0]); + + /* now combine the two scaled excitations */ + /* -------------------------------------- */ + for (i = 0; i < S_LEN; i++) + pswTempVec[i] = add(pswPVec[i], ppswVselpEx[0][i]); + } + + /* Update the long-term-predictor state using the synthetic excitation */ + /*---------------------------------------------------------------------*/ + + for (i = -LTP_LEN; i < -S_LEN; i++) + pswLtpStateOut[i] = pswLtpStateOut[i + S_LEN]; + + for (i = -S_LEN, j = 0; j < S_LEN; i++, j++) + pswLtpStateOut[i] = pswTempVec[j]; + + /* Filter the synthetic excitation through the weighting filters, */ + /* H(z) and C(z), only to update filter states (Note that C(z) */ + /* state may be updated without filtering, since it is an FIR) */ + /* */ + /* First, perform one subframe's worth of delay on C(z) state */ + /*----------------------------------------------------------------*/ + + for (i = 0; i < HNW_BUFF_LEN - S_LEN; i++) + pswHNWState[i] = pswHNWState[i + S_LEN]; + + /* Second, perform H(z) filter on excitation, output goes into */ + /* C(z) state */ + /*-------------------------------------------------------------*/ + + lpcIir(pswTempVec, pswHCoefs, pswHState, + &pswHNWState[HNW_BUFF_LEN - S_LEN]); + +} /* end of sfrmAnalysis() */ + +/*************************************************************************** + * + * FUNCTION NAME: v_srch + * + * PURPOSE: + * The purpose of this function is search a vector-sum codebook for the + * optimal vector + * + * INPUTS: + * + * pswWInput[0:S_LEN] + * + * the weighted input speech frame, with the zero-input + * response of H(z) subtracted + * + * pswWBasisVecs[0:S_LEN*siNumBasis] + * + * weighted, decorrelated vector-sum codebook basis + * vectors + * + * siNumBasis + * + * number of basis vectors + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * sw1 + * + * output code + * + * REFERENCE: Sub-clause 4.1.10.2 of GSM Recommendation 06.20 + * + * KEYWORDS: v_srch, codebook, search + * + **************************************************************************/ + +int16_t v_srch(int16_t pswWInput[], int16_t pswWBasisVecs[], + short int siNumBasis) +{ + +/*_________________________________________________________________________ + | | + | Local Constants | + |_________________________________________________________________________| +*/ + +#define V_ARRAY_SIZE ( 1 << (C_BITS_V-1) ) - 1 +#define UN_ARRAY_SIZE ( 1 << (C_BITS_UV-1) ) - 1 +#define MINUS_HALF -0x4000 + +/*_________________________________________________________________________ + | | + | Local Static Variables | + |_________________________________________________________________________| +*/ + static int16_t + pswUpdateIndexV[V_ARRAY_SIZE] = + { + 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x1b, 0x00, 0x09, + 0x48, 0x5a, 0x00, 0x51, 0x48, 0x24, 0x00, 0x09, 0x48, 0x12, + 0x00, 0x51, 0x48, 0x63, 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, + 0x48, 0x2d, 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x1b, + 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, 0x48, 0x6c, 0x00, 0x09, + 0x48, 0x12, 0x00, 0x51, 0x48, 0x63, 0x00, 0x09, 0x48, 0x5a, + 0x00, 0x51, 0x48, 0x36, 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, + 0x48, 0x1b, 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, 0x48, 0x24, + 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x63, 0x00, 0x09, + 0x48, 0x5a, 0x00, 0x51, 0x48, 0x75, 0x00, 0x09, 0x48, 0x12, + 0x00, 0x51, 0x48, 0x1b, 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, + 0x48, 0x6c, 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x63, + 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, 0x48, 0x3f, 0x00, 0x09, + 0x48, 0x12, 0x00, 0x51, 0x48, 0x1b, 0x00, 0x09, 0x48, 0x5a, + 0x00, 0x51, 0x48, 0x24, 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, + 0x48, 0x63, 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, 0x48, 0x2d, + 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x1b, 0x00, 0x09, + 0x48, 0x5a, 0x00, 0x51, 0x48, 0x6c, 0x00, 0x09, 0x48, 0x12, + 0x00, 0x51, 0x48, 0x63, 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, + 0x48, 0x7e, 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x1b, + 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, 0x48, 0x24, 0x00, 0x09, + 0x48, 0x12, 0x00, 0x51, 0x48, 0x63, 0x00, 0x09, 0x48, 0x5a, + 0x00, 0x51, 0x48, 0x75, 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, + 0x48, 0x1b, 0x00, 0x09, 0x48, 0x5a, 0x00, 0x51, 0x48, 0x6c, + 0x00, 0x09, 0x48, 0x12, 0x00, 0x51, 0x48, 0x63, 0x00, 0x09, + 0x48, 0x5a, 0x00, 0x51, 0x48, + }, + pswBitIndexV[V_ARRAY_SIZE] = + { + 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, + 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, 0x01, 0x02, 0x01, 0x03, + 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, + 0x01, 0x06, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, + 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, 0x01, 0x02, + 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, + 0x01, 0x02, 0x01, 0x07, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, + 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, + 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, + 0x01, 0x03, 0x01, 0x02, 0x01, 0x06, 0x01, 0x02, 0x01, 0x03, + 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, + 0x01, 0x05, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, + 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 0x01, 0x02, + 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, + 0x01, 0x02, 0x01, 0x05, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, + 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x06, + 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, + 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, 0x01, 0x02, 0x01, 0x03, + 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, + 0x01, 0x07, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, + 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, 0x01, 0x02, + 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, + 0x01, 0x02, 0x01, 0x06, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, + 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, + 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, + 0x01, 0x03, 0x01, 0x02, 0x01, + }, + pswModNextBitV[C_BITS_V] = + { + 1, 2, 3, 4, 5, 6, 7, 0, 1, + }, + pswUpdateIndexUn[UN_ARRAY_SIZE] = + { + 0x00, 0x07, 0x2a, 0x0e, 0x00, 0x31, 0x2a, 0x15, 0x00, 0x07, + 0x2a, 0x38, 0x00, 0x31, 0x2a, 0x1c, 0x00, 0x07, 0x2a, 0x0e, + 0x00, 0x31, 0x2a, 0x3f, 0x00, 0x07, 0x2a, 0x38, 0x00, 0x31, + 0x2a, 0x23, 0x00, 0x07, 0x2a, 0x0e, 0x00, 0x31, 0x2a, 0x15, + 0x00, 0x07, 0x2a, 0x38, 0x00, 0x31, 0x2a, 0x46, 0x00, 0x07, + 0x2a, 0x0e, 0x00, 0x31, 0x2a, 0x3f, 0x00, 0x07, 0x2a, 0x38, + 0x00, 0x31, 0x2a, + }, + pswBitIndexUn[UN_ARRAY_SIZE] = + { + 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, + 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, 0x01, 0x02, 0x01, 0x03, + 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, + 0x01, 0x00, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, + 0x01, 0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x05, 0x01, 0x02, + 0x01, 0x03, 0x01, 0x02, 0x01, 0x04, 0x01, 0x02, 0x01, 0x03, + 0x01, 0x02, 0x01, + }, + pswModNextBitUV[C_BITS_UV] = + { + 1, 2, 3, 4, 5, 0, 1, + }; + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t **pppswDubD[C_BITS_V - 1], + *ppswD[C_BITS_V - 1], + pswCGUpdates[2 * C_BITS_V * (C_BITS_V - 1)], + pswDSpace[2 * C_BITS_V * (C_BITS_V - 1)], + *ppswDPSpace[C_BITS_V * (C_BITS_V - 1)], + pswBits[C_BITS_V - 1], + *pswUpdatePtr, + *pswUIndex, + *pswBIndex, + *pswModNextBit, + *psw0, + *psw1, + *psw2, + swC0, + swG0, + swCC, + swG, + swCCMax, + swGMax, + sw1; + int32_t pL_R[C_BITS_V], + L_R, + L_MaxC, + L_C0, + L_D, + L_G0, + L_C, + L_G, + L_1; + short int siI, + siJ, + siK, + siEBits, + siShiftCnt, + siBitIndex, + siBest, + siMask; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /* initialize variables based on voicing mode */ + /* ------------------------------------------ */ + + if (sub(siNumBasis, C_BITS_V) == 0) + { + siEBits = C_BITS_V_1; + pswUIndex = pswUpdateIndexV; + pswBIndex = pswBitIndexV; + pswModNextBit = pswModNextBitV; + } + else + { + siEBits = C_BITS_UV_1; + pswUIndex = pswUpdateIndexUn; + pswBIndex = pswBitIndexUn; + pswModNextBit = pswModNextBitUV; + } + + /* initialize pointers */ + /* ------------------- */ + + for (siI = 0; siI < siNumBasis - 1; siI++) + { + + pppswDubD[siI] = &ppswDPSpace[siI * siNumBasis]; + + for (siJ = 0; siJ < siNumBasis; siJ++) + { + ppswDPSpace[(siI * siNumBasis) + siJ] = + &pswDSpace[(siI * siNumBasis * 2) + (siJ * 2)]; + } + ppswD[siI] = &pswDSpace[siI * siNumBasis]; + } + + /* compute correlations (Rm) between given vector and basis vectors, */ + /* store in double precision; maintain max C for later scaling of Rm's */ + /* ------------------------------------------------------------------- */ + + L_MaxC = 0L; + + for (siI = 0; siI < siNumBasis; siI++) + { + + L_R = L_mult(pswWBasisVecs[siI * S_LEN], pswWInput[0]); + + for (siJ = 1; siJ < S_LEN; siJ++) + { + L_R = L_mac(L_R, pswWBasisVecs[siJ + (siI * S_LEN)], pswWInput[siJ]); + } + pL_R[siI] = L_R; + L_R = L_abs(L_R); + L_MaxC = L_add(L_R, L_MaxC); + } + + /* normalize max C to get scaling shift count */ + /* scale Rm's and calculate C(0) */ + /* ------------------------------------------ */ + + /* max abs(C) after scale is <= 0.5 */ + siShiftCnt = add(-1, norm_l(L_MaxC)); + + L_C0 = 0L; + + for (siI = 0; siI < siNumBasis; siI++) + { + + L_R = L_shl(pL_R[siI], siShiftCnt); + + L_C0 = L_sub(L_C0, L_R); + + pL_R[siI] = L_shl(L_R, 1); + + } + swC0 = extract_h(L_C0); + + /* compute correlations (Dmj, for m != j) between the basis vectors */ + /* store in double precision */ + /* ---------------------------------------------------------------- */ + + for (siI = 0; siI < siNumBasis - 1; siI++) + { + + for (siJ = siI + 1; siJ < siNumBasis; siJ++) + { + + L_D = L_mult(pswWBasisVecs[siI * S_LEN], pswWBasisVecs[siJ * S_LEN]); + + for (siK = 1; siK < S_LEN; siK++) + { + L_D = L_mac(L_D, pswWBasisVecs[siK + (siI * S_LEN)], + pswWBasisVecs[siK + (siJ * S_LEN)]); + } + pppswDubD[siI][siJ][0] = extract_h(L_D); + pppswDubD[siI][siJ][1] = extract_l(L_D); + } + } + + /* compute the sum of the Djj's (to be used for scaling the Dmj's and */ + /* for computing G(0)); normalize it, get shift count for scaling Dmj's */ + /* -------------------------------------------------------------------- */ + + psw1 = pswWBasisVecs; + + L_G0 = L_mult(psw1[0], psw1[0]); + + for (siI = 1; siI < siNumBasis * S_LEN; siI++) + { + L_G0 = L_mac(L_G0, psw1[siI], psw1[siI]); + } + + siShiftCnt = add(-4, norm_l(L_G0)); + + L_G0 = L_shl(L_G0, siShiftCnt); + + /* scale Dmj's and compute G(0) */ + /* ---------------------------- */ + + for (siI = 0; siI < siNumBasis - 1; siI++) + { + + for (siJ = siI + 1; siJ < siNumBasis; siJ++) + { + + L_D = L_deposit_h(pppswDubD[siI][siJ][0]); + L_D = L_add(L_D, (LSP_MASK & L_deposit_l(pppswDubD[siI][siJ][1]))); + + L_D = L_shl(L_D, siShiftCnt); + + L_D = L_shl(L_D, 1); + + L_G0 = L_add(L_D, L_G0); + + L_D = L_shl(L_D, 1); + + ppswD[siI][siJ] = round(L_D); + } + } + + swG0 = extract_h(L_G0); + + /* build array of update values for codebook search */ + /* ------------------------------------------------ */ + + for (siI = 0; siI < siEBits; siI++) + { + pswCGUpdates[siI * (siEBits + 1)] = round(pL_R[siI]); + } + psw0 = &pswCGUpdates[siEBits]; + psw1 = &pswCGUpdates[1]; + psw2 = &pswCGUpdates[2 * siEBits]; + + for (siI = 0; siI < siEBits - 1; siI++) + { + + for (siJ = siI + 1; siJ < siEBits; siJ++) + { + + L_1 = L_deposit_h(ppswD[siI][siJ]); + L_1 = L_shl(L_1, 1); + psw1[siJ - 1 + (siI * siEBits)] = extract_h(L_1); + psw2[siI + (siEBits * (siJ - 1))] = extract_h(L_1); + } + psw0[siI * (siEBits + 1)] = negate(ppswD[siI][siEBits]); + } + + psw0[siI * (siEBits + 1)] = negate(ppswD[siEBits - 1][siEBits]); + + /* copy to negative side of array */ + /* ------------------------------ */ + + psw0 = &pswCGUpdates[(siEBits + 1) * siEBits]; + + for (siI = 0; siI < (siEBits + 1) * siEBits; siI++) + { + psw0[siI] = negate(pswCGUpdates[siI]); + } + + /* initialize array of bits (magnitude = 0.5) */ + /* ------------------------------------------ */ + + for (siI = 0; siI < siEBits; siI++) + { + pswBits[siI] = MINUS_HALF; + } + + /* initialize and do codebook search */ + /* --------------------------------- */ + + swGMax = swG0; + swCCMax = mult_r(swC0, swC0); + L_C = L_deposit_h(swC0); + L_G = L_deposit_h(swG0); + siBest = 0; + + for (siI = 0; siI < (1 << siEBits) - 1; siI++) + { + + pswUpdatePtr = &pswCGUpdates[pswUIndex[siI]]; + + siBitIndex = pswBIndex[siI]; + + L_C = L_msu(L_C, pswUpdatePtr[0], 0x8000); + + for (siJ = 0; siJ < siEBits - 1; siJ++) + { + L_G = L_mac(L_G, pswUpdatePtr[siJ + 1], pswBits[siBitIndex]); + siBitIndex = pswModNextBit[siBitIndex]; + } + L_G = L_msu(L_G, pswUpdatePtr[siJ + 1], 0x8000); + + pswBits[siBitIndex] = negate(pswBits[siBitIndex]); + + sw1 = extract_h(L_C); + swCC = mult_r(sw1, sw1); + + swG = extract_h(L_G); + L_1 = L_mult(swG, swCCMax); + + L_1 = L_msu(L_1, swGMax, swCC); + + if (L_1 < 0) + { + swCCMax = swCC; + swGMax = swG; + siBest = add(siI, 1); + } + } + + /* generate code for positive correlation; */ + /* compute correlation, if negative, invert code */ + /* --------------------------------------------- */ + + sw1 = siBest ^ (shr(siBest, 1)); + + siMask = 0x1; + L_1 = 0L; + + for (siI = 0; siI < siNumBasis; siI++) + { + + if ((sw1 & siMask) == 0) + { + L_1 = L_sub(L_1, pL_R[siI]); + } + else + { + L_1 = L_add(L_1, pL_R[siI]); + } + + siMask = shl(siMask, 1); + } + + if (L_1 < 0) + { + sw1 = sw1 ^ (sub(shl(1, siNumBasis), 1)); + } + + /* return code */ + /* ----------- */ + + return (sw1); +} diff --git a/src/libs/gsmhr/gsmhr_sp_sfrm.h b/src/libs/gsmhr/gsmhr_sp_sfrm.h new file mode 100644 index 00000000..ce293a6d --- /dev/null +++ b/src/libs/gsmhr/gsmhr_sp_sfrm.h @@ -0,0 +1,65 @@ +#ifndef __SP_SFRM +#define __SP_SFRM + +#include "gsmfr_typedefs.h" + +/*_________________________________________________________________________ + | | + | Function Prototypes | + |_________________________________________________________________________| +*/ + +int16_t g_corr2(int16_t *pswIn, int16_t *pswIn2, + int32_t *pL_out); + +int closedLoopLagSearch(int16_t pswLagList[], + int iNumLags, + int16_t pswLtpState[], + int16_t pswHCoefs[], + int16_t pswPVect[], + int16_t *pswLag, + int16_t *pswLtpShift); + + void decorr(int iNumVects, + int16_t pswGivenVect[], + int16_t pswVects[]); + + int16_t g_quant_vl(int16_t swUVCode, + int16_t pswWInput[], + int16_t swWIShift, + int16_t pswWLTPVec[], + int16_t pswWVSVec1[], + int16_t pswWVSVec2[], + struct NormSw snsRs00, + struct NormSw snsRs11, + struct NormSw snsRs22); + + void gainTweak(struct NormSw *psErrorTerm); + + void hnwFilt(int16_t pswInSample[], + int16_t pswOutSample[], + int16_t pswState[], + int16_t pswInCoef[], + int iStateOffset, + int16_t swZeroState, + int iNumSamples); + + void sfrmAnalysis(int16_t *pswWSpeech, + int16_t swVoicingMode, + struct NormSw snsSqrtRs, + int16_t *pswHCoefs, + int16_t *pswLagList, + short siNumLags, + int16_t swPitch, + int16_t swHNWCoef, + short *psiLagCode, + short *psiVSCode1, + short *psiVSCode2, + short *psiGsp0Code, + int16_t swSP); + + int16_t v_srch(int16_t pswWInput[], + int16_t pswWBasisVecs[], + short int siNumBasis); + +#endif diff --git a/src/libs/gsmhr/gsmhr_typedefs.h b/src/libs/gsmhr/gsmhr_typedefs.h new file mode 100644 index 00000000..53c4c5e6 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_typedefs.h @@ -0,0 +1,63 @@ +/******************************************************************* + * + * typedef statements of types used in all half-rate GSM routines + * + ******************************************************************/ + +#ifndef __GSM_HR_TYPEDEFS +#define __GSM_HR_TYPEDEFS + +#define DATE "August 8, 1996 " +#define VERSION "Version 4.2 " + +#define LW_SIGN (long)0x80000000 /* sign bit */ +#define LW_MIN (long)0x80000000 +#define LW_MAX (long)0x7fffffff + +#define SW_SIGN (short)0x8000 /* sign bit for int16_t type */ +#define SW_MIN (short)0x8000 /* smallest Ram */ +#define SW_MAX (short)0x7fff /* largest Ram */ + +#include + +/* Definition of Types * + ***********************/ + + /* 32 bit "accumulator" (L_*) */ + /* 16 bit "register" (sw*) */ +typedef short int int16_tRom; /* 16 bit ROM data (sr*) */ +typedef long int int32_tRom; /* 32 bit ROM data (L_r*) */ + +struct NormSw +{ /* normalized int16_t fractional + * number snr.man precedes snr.sh (the + * shift count)i */ + int16_t man; /* "mantissa" stored in 16 bit + * location */ + int16_t sh; /* the shift count, stored in 16 bit + * location */ +}; + +/* Global constants * + ********************/ + +#define NP 10 /* order of the lpc filter */ +#define N_SUB 4 /* number of subframes */ +#define F_LEN 160 /* number of samples in a frame */ +#define S_LEN 40 /* number of samples in a subframe */ +#define A_LEN 170 /* LPC analysis length */ +#define OS_FCTR 6 /* maximum LTP lag oversampling + * factor */ + +#define OVERHANG 8 /* vad parameter */ +#define strStr strStr16 + +/* global variables */ +/********************/ + +extern int giFrmCnt; /* 0,1,2,3,4..... */ +extern int giSfrmCnt; /* 0,1,2,3 */ + +extern int giDTXon; /* DTX Mode on/off */ + +#endif diff --git a/src/libs/gsmhr/gsmhr_utils.c b/src/libs/gsmhr/gsmhr_utils.c new file mode 100644 index 00000000..b35aa3c0 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_utils.c @@ -0,0 +1,1106 @@ +/*___________________________________________________________________________ + | | + | | + | Residual Error Insertion Device | + | | + | | + | File : REID.C | + | | + | Date : February 03, 1995 | + | | + | Version: 4.1 | + | | + | | + | Description: | + | ------------ | + | This routine transforms the output file format of the GSM Half | + | Rate Encoder module consisting of: | + | * 18 speech parameters (see GSM TS 06.20) | + | * 1 speech flag SP (see GSM TS 06.41) | + | * 1 voice activity flag VAD (see GSM TS 06.42) | + | | + | to the input file format of the GSM Half Rate Decoder module | + | requiring: | + | * 18 speech parameters (see GSM TS 06.20) | + | * 1 channel condition flag BFI (see GSM TS 06.21, 05.05) | + | * 1 channel condition flag UFI (see GSM TS 06.21, 05.05) | + | * 1 SID flag (2 bits) (see GSM TS 06.41, 05.05) | + | * 1 time alignment flag TAF (see GSM TS 06.41) | + | | + | Between SID updates the speech parameters are replaced by random | + | values simulating an interrupted transmission on the air interface | + | | + | The actual implementation only supports error free transmission (EP0)| + | | + | The shell for the future use of error patterns (residual error | + | pattern insertion) is already included. If necessary, byte swapping | + | is performed on the input speech parameters so that they are always | + | represented internally in PC byte order (assuming that the byte | + | order of the input file is compatible with the machine on which the | + | program is run). However, byte swapping is not done on the flag | + | words (input: SP and VAD, output: BFI, UFI, SID, and TAF). Thus, | + | the residual error pattern insertion code may be written to handle | + | the speech parameter words on a byte basis, but the flag words must | + | always be handled on a word basis. | + |___________________________________________________________________________| +*/ +/*___________________________________________________________________________ + | | + | Creation: 19.12.94 | + | | + | Changes: | + | 22.12.94: Removal of BCI flag, instead: determination of SID flag | + | 12.01.95: SID update period = 12 (instead of 24) | + | 13.01.95: When in CNI mode, the parameters between SID updates are | + | random values. This simulates the interrupted transmission| + | 03.02.95: int32_t main( int32_t...) replaced by int main(int ...),| + | initial value of swTAFCnt set to 1 | + |___________________________________________________________________________| +*/ + +/*___________________________________________________________________________ + | | + | Include-Files | + |___________________________________________________________________________| +*/ +#include +#include +#include +#include + +#ifdef VAX +# define OPEN_WI "wb","mrs=512","rfm=fix","ctx=stm" +# define OPEN_RI "rb","mrs=512","rfm=fix","ctx=stm" +# define OPEN_WB "wb","mrs=512","rfm=fix","ctx=stm" +# define OPEN_RB "rb","mrs=2","rfm=fix","ctx=stm" +# define OPEN_WT "w","mrs=256","rat=cr","rfm=var" +# define OPEN_RT "r","mrs=256","rat=cr","rfm=var" +#else +# define OPEN_WB "wb" +# define OPEN_RB "rb" +# define OPEN_WI "wb" +# define OPEN_RI "rb" +# define OPEN_WT "wt" +# define OPEN_RT "rt" +#endif + +#define LW_SIGN (long)0x80000000 /* sign bit */ +#define LW_MIN (long)0x80000000 +#define LW_MAX (long)0x7fffffff +#define SW_MIN (short)0x8000 /* smallest Ram */ +#define SW_MAX (short)0x7fff /* largest Ram */ + +typedef char Byte; +typedef long int int32_t; /* 32 bit "accumulator" (L_*) */ +typedef short int int16_t; /* 16 bit "register" (sw*) */ + +/*___________________________________________________________________________ + | | + | local Functions | + |___________________________________________________________________________| +*/ +static int32_t error_free( FILE *infile, FILE *outfile); +static void SwapBytes( int16_t buffer[], int32_t len ); +static int32_t ByteOrder( void ); +static size_t ReadInputFile( int16_t buffer[], FILE *fp ); +static size_t WriteOutputFile( int16_t buffer[], FILE *fp ); +static int32_t EncoderInterface( FILE *infile, int16_t swInPara[] ); +static int16_t swSidDetection(int16_t pswParameters[], + int16_t pswErrorFlag[]); +static void RandomParameters(int16_t pswParameters[]); +static int16_t getPnBits(int16_t iBits, int32_t *pL_PNSeed); +FILE *OpenBinfile( char *name, char *mode ); +int32_t Strincmp( const char *s, const char *t, size_t max ); +int32_t Stricmp( const char *s, const char *t ); + +int32_t L_shr(int32_t L_var1, int16_t var2); /* 2 ops */ +int32_t L_shl(int32_t L_var1, int16_t var2); /* 2 ops */ +int16_t shr(int16_t var1, int16_t var2); /* 1 ops */ +int16_t shl(int16_t var1, int16_t var2); /* 1 ops */ + +/*___________________________________________________________________________ + | | + | Subroutines | + |___________________________________________________________________________| +*/ +static int32_t error_free( FILE *infile, FILE *outfile) +{ + +#define SPEECH 1 +#define CNIFIRSTSID 2 +#define CNICONT 3 +#define VALIDSID 11 +#define GOODSPEECH 33 + + static int16_t swDecoMode = {SPEECH}; + static int16_t swTAFCnt = {1}; + int16_t swInPara[20], i, swFrameType; + int16_t swOutPara[22],pswErrorFlag[3]; + + if( EncoderInterface( infile, swInPara )) return( 1 ); + + /* Copy input parameters to output parameters (error free transmission) */ + /* -------------------------------------------------------------------- */ + for (i=0;i<18;i++) + swOutPara[i] = swInPara[i]; + + /* Set channel status flags (error free transmission) */ + /* -------------------------------------------------- */ + swOutPara[18] = 0; /* BFI flag */ + swOutPara[19] = 0; /* UFI flag */ + + /* Evaluate SID flag */ + /* ----------------- */ + pswErrorFlag[0] = 0; /* BFI flag */ + pswErrorFlag[1] = 0; /* UFI flag */ + pswErrorFlag[2] = 0; /* BCI flag */ + swOutPara[20] = swSidDetection(swOutPara, pswErrorFlag); + + + /* Evaluate TAF flag */ + /* ----------------- */ + if (swTAFCnt == 0) swOutPara[21] = 1; + else swOutPara[21] = 0; + swTAFCnt = (swTAFCnt + 1) % 12; + + + /* Frame classification: */ + /* Since the transmission is error free, the received frames are either */ + /* valid speech or valid SID frames */ + /* -------------------------------------------------------------------- */ + if ( swOutPara[20] == 2) swFrameType = VALIDSID; + else if ( swOutPara[20] == 0) swFrameType = GOODSPEECH; + else { + printf( "Error in SID detection\n" ); + return( 1 ); + } + + /* Update of decoder state */ + /* ----------------------- */ + if (swDecoMode == SPEECH) { + if (swFrameType == VALIDSID) swDecoMode = CNIFIRSTSID; + else if (swFrameType == GOODSPEECH) swDecoMode = SPEECH; + } + else { /* comfort noise insertion mode */ + if (swFrameType == VALIDSID) swDecoMode = CNICONT; + else if (swFrameType == GOODSPEECH) swDecoMode = SPEECH; + } + + + /* Replace parameters by random data if in CNICONT-mode and TAF=0 */ + /* -------------------------------------------------------------- */ + if ((swDecoMode == CNICONT) && (swOutPara[21] == 0)){ + RandomParameters(swOutPara); + /* Set flags such, that an "unusable frame" is produced */ + swOutPara[18] = 1; /* BFI flag */ + swOutPara[19] = 1; /* UFI flag */ + swOutPara[20] = 0; /* SID flag */ + } + + + + if( outfile ) { + if( WriteOutputFile( swOutPara, outfile )) { + printf( "Error writing File\n" ); + return( 1 ); + } + } + return( 0 ); +} + +static int32_t EncoderInterface( FILE *infile, int16_t swInPara[] ) +{ + size_t i = 0; + + i = ReadInputFile( swInPara, infile ); + + return(( i == 0 ) ? 1 : 0 ); +} + +static size_t ReadInputFile( int16_t buffer[], FILE *fp ) +{ + size_t i; + + i = fread( buffer, sizeof( int16_t ), 20, fp ); + SwapBytes( buffer, 18 ); + return( i ); +} + +static size_t WriteOutputFile( int16_t buffer[], FILE *fp ) +{ + size_t i; + + SwapBytes( buffer, 18 ); + i = fwrite( buffer, sizeof( int16_t ), 22, fp ); + return( ( i == 22 ) ? 0 : 1 ); +} + + +static void SwapBytes( int16_t buffer[], int32_t len ) +{ + Byte *pc, tmp; + int32_t i; + + if( !ByteOrder()) + return; + pc = (Byte *)buffer; + for( i = 0; i < len; i++ ) { + tmp = pc[0]; + pc[0] = pc[1]; + pc[1] = tmp; + pc += 2; + } +} + +static int32_t ByteOrder( void ) +{ + int16_t si; + Byte *pc; + + si = 0x1234; + pc = (Byte *)&si; + if (pc[1] == 0x12 && pc[0] == 0x34 ) + return( 0 ); + if (pc[0] == 0x12 && pc[1] == 0x34 ) + return( 1 ); + printf( "Error in ByteOrder: %X, %X\n", (int)pc[0], (int)pc[1] ); + exit( 1 ); + return( 2 ); +} + +FILE *OpenBinfile( char *name, char *mode ) +{ + FILE *fp; + + if( toupper( *mode ) == 'W' ) { /* Write access */ + if(( fp = fopen( name, OPEN_WB )) == NULL ) { + printf( "Can't open output file '%s'\n", name ); + exit( 1 ); + } + } else { /* Read access */ + if(( fp = fopen( name, OPEN_RB )) == NULL ) { + printf( "Can't open file '%s'\n", name ); + exit( 1 ); + } + } + return( fp ); +} + +int32_t Strincmp( const char *s, const char *t, size_t max ) +{ + for( ; max > 1; ++s, ++t, --max ) { + if( toupper( *s ) != toupper( *t )) + break; + if( *s == '\0' ) + return( 0 ); + } + return( toupper( *s ) - toupper( *t )); +} + +int32_t Stricmp( const char *s, const char *t ) +{ + for(; toupper( *s ) == toupper( *t ); ++s, ++t ) { + if( *s == '\0' ) + return( 0 ); + } + return( toupper( *s ) - toupper( *t )); +} + +/************************************************************************* + * + * FUNCTION NAME: getPnBits + * + * PURPOSE: + * + * Generate iBits pseudo-random bits using *pL_PNSeed as the + * pn-generators seed. + * + * INPUTS: + * + * iBits - integer indicating how many random bits to return. + * range [0,15], 0 yields 1 bit output + * + * *pL_PNSeed - 32 bit seed (changed by function) + * + * OUTPUTS: + * + * *pL_PNSeed - 32 bit seed, modified. + * + * RETURN VALUE: + * + * random bits in iBits LSB's. + * + * + * IMPLEMENTATION: + * + * implementation of x**31 + x**3 + 1 == PN_XOR_REG | PN_XOR_ADD a + * PN sequence generator using int32_ts generating a 2**31 -1 + * length pn-sequence. + * + *************************************************************************/ + +static int16_t getPnBits(int16_t iBits, int32_t *pL_PNSeed){ + +#define PN_XOR_REG (int32_t)0x00000005L +#define PN_XOR_ADD (int32_t)0x40000000L + + int16_t swPnBits=0; + int32_t L_Taps,L_FeedBack; + int16_t i; + + for (i=0; i < iBits; i++){ + + /* update the state */ + /********************/ + + L_Taps = *pL_PNSeed & PN_XOR_REG; + L_FeedBack = L_Taps; /* Xor tap bits to yield feedback bit */ + L_Taps = L_shr(L_Taps,1); + + while(L_Taps){ + L_FeedBack = L_FeedBack ^ L_Taps; + L_Taps = L_shr(L_Taps,1); + } + + /* LSB of L_FeedBack is next MSB of PN register */ + + *pL_PNSeed = L_shr(*pL_PNSeed,1); + if (L_FeedBack & 1) + *pL_PNSeed = *pL_PNSeed | PN_XOR_ADD; + + /* State update complete. + Get the output bit from the state, add/or it into output */ + + swPnBits = shl(swPnBits,1); + swPnBits = swPnBits | (*pL_PNSeed & 1); + + } + return(swPnBits); +} + + +/*************************************************************************** + * + * FUNCTION NAME: L_shl + * + * PURPOSE: + * + * Arithmetic shift left (or right). + * Arithmetically shift the input left by var2. If var2 is + * negative then an arithmetic shift right (L_shr) of L_var1 by + * -var2 is performed. + * + * INPUTS: + * + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * + * IMPLEMENTATION: + * + * Arithmetically shift the 32 bit input left by var2. This + * operation maintains the sign of the input number. If var2 is + * negative then an arithmetic shift right (L_shr) of L_var1 by + * -var2 is performed. See description of L_shr for details. + * + * Equivalent to the Full-Rate GSM ">> n" operation. Note that + * ANSI-C does not guarantee operation of the C ">>" or "<<" + * operator for negative numbers. + * + * KEYWORDS: shift, arithmetic shift left, + * + *************************************************************************/ + +int32_t L_shl(int32_t L_var1, int16_t var2) +{ + + int32_t L_Mask, + L_Out; + int i, + iOverflow = 0; + + if (var2 == 0 || L_var1 == 0) + { + L_Out = L_var1; + } + else if (var2 < 0) + { + if (var2 <= -31) + { + if (L_var1 > 0) + L_Out = 0; + else + L_Out = 0xffffffffL; + } + else + L_Out = L_shr(L_var1, -var2); + } + else + { + + if (var2 >= 31) + iOverflow = 1; + + else + { + + if (L_var1 < 0) + L_Mask = LW_SIGN; /* sign bit mask */ + else + L_Mask = 0x0; + L_Out = L_var1; + for (i = 0; i < var2 && !iOverflow; i++) + { + /* check the sign bit */ + L_Out = (L_Out & 0x7fffffffL) << 1; + if ((L_Mask ^ L_Out) & LW_SIGN) + iOverflow = 1; + } + } + + if (iOverflow) + { + /* saturate */ + if (L_var1 > 0) + L_Out = LW_MAX; + else + L_Out = LW_MIN; + } + } + + return (L_Out); +} + +/*************************************************************************** + * + * FUNCTION NAME: L_shr + * + * PURPOSE: + * + * Arithmetic shift right (or left). + * Arithmetically shift the input right by var2. If var2 is + * negative then an arithmetic shift left (shl) of var1 by + * -var2 is performed. + * + * INPUTS: + * + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * L_var1 + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * L_Out + * 32 bit long signed integer (int32_t) whose value + * falls in the range + * 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * + * IMPLEMENTATION: + * + * Arithmetically shift the input right by var2. This + * operation maintains the sign of the input number. If var2 is + * negative then an arithmetic shift left (shl) of L_var1 by + * -var2 is performed. See description of L_shl for details. + * + * The input is a 32 bit number, as is the output. + * + * Equivalent to the Full-Rate GSM ">> n" operation. Note that + * ANSI-C does not guarantee operation of the C ">>" or "<<" + * operator for negative numbers. + * + * KEYWORDS: shift, arithmetic shift right, + * + *************************************************************************/ + +int32_t L_shr(int32_t L_var1, int16_t var2) +{ + + int32_t L_Mask, + L_Out; + + if (var2 == 0 || L_var1 == 0) + { + L_Out = L_var1; + } + else if (var2 < 0) + { + /* perform a left shift */ + /*----------------------*/ + if (var2 <= -31) + { + /* saturate */ + if (L_var1 > 0) + L_Out = LW_MAX; + else + L_Out = LW_MIN; + } + else + L_Out = L_shl(L_var1, -var2); + } + else + { + + if (var2 >= 31) + { + if (L_var1 > 0) + L_Out = 0; + else + L_Out = 0xffffffffL; + } + else + { + L_Mask = 0; + + if (L_var1 < 0) + { + L_Mask = ~L_Mask << (32 - var2); + } + + L_var1 >>= var2; + L_Out = L_Mask | L_var1; + } + } + return (L_Out); +} + + +/*************************************************************************** + * + * FUNCTION NAME: shl + * + * PURPOSE: + * + * Arithmetically shift the input left by var2. + * + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * If Arithmetically shift the input left by var2. If var2 is + * negative then an arithmetic shift right (shr) of var1 by + * -var2 is performed. See description of shr for details. + * When an arithmetic shift left is performed the var2 LS bits + * are zero filled. + * + * The only exception is if the left shift causes an overflow + * or underflow. In this case the LS bits are not modified. + * The number returned is 0x8000 in the case of an underflow or + * 0x7fff in the case of an overflow. + * + * The shl is equivalent to the Full-Rate GSM "<< n" operation. + * Note that ANSI-C does not guarantee operation of the C ">>" + * or "<<" operator for negative numbers - it is not specified + * whether this shift is an arithmetic or logical shift. + * + * KEYWORDS: asl, arithmetic shift left, shift + * + *************************************************************************/ + +int16_t shl(int16_t var1, int16_t var2) +{ + int16_t swOut; + int32_t L_Out; + + if (var2 == 0 || var1 == 0) + { + swOut = var1; + } + else if (var2 < 0) + { + + /* perform a right shift */ + /*-----------------------*/ + + if (var2 <= -15) + { + if (var1 < 0) + swOut = (int16_t) 0xffff; + else + swOut = 0x0; + } + else + swOut = shr(var1, -var2); + + } + else + { + /* var2 > 0 */ + if (var2 >= 15) + { + /* saturate */ + if (var1 > 0) + swOut = SW_MAX; + else + swOut = SW_MIN; + } + else + { + + L_Out = (int32_t) var1 *(1 << var2); + + swOut = (int16_t) L_Out; /* copy low portion to swOut, + * overflow could have hpnd */ + if (swOut != L_Out) + { + /* overflow */ + if (var1 > 0) + swOut = SW_MAX; /* saturate */ + else + swOut = SW_MIN; /* saturate */ + } + } + } + return (swOut); +} + +/*************************************************************************** + * + * FUNCTION NAME: shr + * + * PURPOSE: + * + * Arithmetic shift right (or left). + * Arithmetically shift the input right by var2. If var2 is + * negative then an arithmetic shift left (shl) of var1 by + * -var2 is performed. + * + * INPUTS: + * + * var1 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. + * var2 + * 16 bit short signed integer (int16_t) whose value + * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. + * + * OUTPUTS: + * + * none + * + * RETURN VALUE: + * + * swOut + * 16 bit short signed integer (int16_t) whose value + * falls in the range + * 0xffff 8000 <= swOut <= 0x0000 7fff. + * + * IMPLEMENTATION: + * + * Arithmetically shift the input right by var2. This + * operation maintains the sign of the input number. If var2 is + * negative then an arithmetic shift left (shl) of var1 by + * -var2 is performed. See description of shl for details. + * + * Equivalent to the Full-Rate GSM ">> n" operation. Note that + * ANSI-C does not guarantee operation of the C ">>" or "<<" + * operator for negative numbers. + * + * KEYWORDS: shift, arithmetic shift right, + * + *************************************************************************/ + +int16_t shr(int16_t var1, int16_t var2) +{ + + int16_t swMask, + swOut; + + if (var2 == 0 || var1 == 0) + swOut = var1; + + else if (var2 < 0) + { + /* perform an arithmetic left shift */ + /*----------------------------------*/ + if (var2 <= -15) + { + /* saturate */ + if (var1 > 0) + swOut = SW_MAX; + else + swOut = SW_MIN; + } + else + swOut = shl(var1, -var2); + } + + else + { + + /* positive shift count */ + /*----------------------*/ + + if (var2 >= 15) + { + if (var1 < 0) + swOut = (int16_t) 0xffff; + else + swOut = 0x0; + } + else + { + /* take care of sign extension */ + /*-----------------------------*/ + + swMask = 0; + if (var1 < 0) + { + swMask = ~swMask << (16 - var2); + } + + var1 >>= var2; + swOut = swMask | var1; + + } + } + return (swOut); +} + +/*___________________________________________________________________________ + | | + | This subroutine calculates the 'SID flag' | + | | + | Input: pswParameters[18] | + | input parameters of the speech decoder | + | | + | pswErrorFlag[3] | + | error flags, generated by channel decoder | + | | + | Return Value: | + | 0: speech frame detected | + | 1: most likely SID frame received | + | 2: SID frame detected | + | | + |___________________________________________________________________________| + | | + | History: | + | | + | 12-Oct-1994: Bug removed: error corrected in case of a mode (unvoiced/| + | voiced) mismatch, if a SID frame was received as an | + | unvoiced frame | + |___________________________________________________________________________| +*/ + +static int16_t swSidDetection(int16_t pswParameters[], + int16_t pswErrorFlag[]) +{ + static int16_t ppswIBit[2][18] = { + 5, 11,9,8, 1, 2, 7,7,5, 7,7,5, 7,7,5, 7,7,5, /* unvoiced */ + 5, 11,9,8, 1, 2, 8,9,5, 4,9,5, 4,9,5, 4,9,5}; /* voiced */ + + static int16_t ppswCL1pCL2[2][18] = { + 0x0001, /* R0 */ /* unvoiced */ + 0x00ef, /* LPC1 */ + 0x003e, /* LPC2 */ + 0x007f, /* LPC3 */ + 0x0001, /* INT LPC */ + 0x0003, /* Mode */ + 0x001f, /* Code1_1 */ + 0x0072, /* Code2_1 */ + 0x0012, /* GSP0_1 */ + 0x003f, /* Code1_2 */ + 0x007f, /* Code2_2 */ + 0x0008, /* GSP0_2 */ + 0x007f, /* Code1_3 */ + 0x007f, /* Code2_3 */ + 0x0008, /* GSP0_3 */ + 0x007f, /* Code1_4 */ + 0x007f, /* Code2_4 */ + 0x000c, /* GSP0_4 */ + + 0x0000, /* R0 */ /* voiced */ + 0x0000, /* LPC1 */ + 0x0000, /* LPC2 */ + 0x0000, /* LPC3 */ + 0x0001, /* INT LPC */ + 0x0003, /* Mode */ + 0x00ff, /* Lag_1 */ + 0x01ff, /* Code_1 */ + 0x001f, /* GSP0_1 */ + 0x000f, /* Lag_2 */ + 0x01ff, /* Code_2 */ + 0x001f, /* GSP0_2 */ + 0x000f, /* Lag_3 */ + 0x01ff, /* Code_3 */ + 0x001f, /* GSP0_3 */ + 0x000f, /* Lag_4 */ + 0x01ff, /* Code_4 */ + 0x001f}; /* GSP0_4 */ + + static int16_t ppswCL2[2][18] = { + 0x0000, /* R0 */ /* unvoiced */ + 0x0000, /* LPC1 */ + 0x0000, /* LPC2 */ + 0x0000, /* LPC3 */ + 0x0000, /* INT LPC */ + 0x0000, /* Mode */ + 0x0000, /* Code1_1 */ + 0x0000, /* Code2_1 */ + 0x0000, /* GSP0_1 */ + 0x0000, /* Code1_2 */ + 0x0000, /* Code2_2 */ + 0x0000, /* GSP0_2 */ + 0x0000, /* Code1_3 */ + 0x0007, /* Code2_3 */ /* 3 bits */ + 0x0000, /* GSP0_3 */ + 0x007f, /* Code1_4 */ /* 7 bits */ + 0x007f, /* Code2_4 */ /* 7 bits */ + 0x0000, /* GSP0_4 */ + + 0x0000, /* R0 */ /* voiced */ + 0x0000, /* LPC1 */ + 0x0000, /* LPC2 */ + 0x0000, /* LPC3 */ + 0x0000, /* INT LPC */ + 0x0000, /* Mode */ + 0x0000, /* Lag_1 */ + 0x0000, /* Code_1 */ + 0x0000, /* GSP0_1 */ + 0x0000, /* Lag_2 */ + 0x0000, /* Code_2 */ + 0x0000, /* GSP0_2 */ + 0x0000, /* Lag_3 */ + 0x00ff, /* Code_3 */ /* 8 bits */ + 0x0000, /* GSP0_3 */ + 0x0000, /* Lag_4 */ + 0x01ff, /* Code_4 */ /* 9 bits */ + 0x0000}; /* GSP0_4 */ + + static int first = 1; + + int16_t swMode, swBitMask; + int16_t swSidN1, swSidN2, swSidN1pN2; + int16_t swSid ; + + short siI, siII; + + + if (first) + { + /* Force Sid codewords to be represented */ + /* internally in PC byte order */ + /* ------------------------------------- */ + + SwapBytes(ppswCL1pCL2[0], 18); + SwapBytes(ppswCL1pCL2[1], 18); + SwapBytes(ppswCL2[0], 18); + SwapBytes(ppswCL2[1], 18); + + first = 0; + } + + + /* count transmission errors within the SID codeword */ + /* count number of bits equal '0' within the SID codeword */ + /* ------------------------------------------------------ */ + + if (pswParameters[5] == 0) + swMode = 0; + else + swMode = 1; + + + swSidN1pN2 = 0; /* N1 + N2 */ + swSidN2 = 0; + swSidN1 = 0; + + for (siI = 0; siI < 18; siI++) { + swBitMask = 0x0001; + SwapBytes(&swBitMask, 1); /* force swBitMask to PC byte order */ + for (siII = 0; siII < ppswIBit[swMode][siI]; siII++) { + if ( (pswParameters[siI] & swBitMask) == 0 ) { + if ( (ppswCL1pCL2[swMode][siI] & swBitMask) != 0 ) swSidN1pN2++; + if ( (ppswCL2[swMode][siI] & swBitMask) != 0 ) swSidN2++; + } + SwapBytes(&swBitMask, 1); /* return swBitMask to native byte order */ + swBitMask = swBitMask << 1; + SwapBytes(&swBitMask, 1); /* force swBitMask to PC byte order */ + } + } + + swSidN1 = swSidN1pN2 - swSidN2; + + + /* frame classification */ + /* -------------------- */ + + if (pswErrorFlag[2]) { + + if (swSidN1 < 3) + swSid = 2; + else if (swSidN1pN2 < 16) + swSid = 1; + else + swSid = 0; + + if ( (swSidN1pN2 >= 16) && (swSidN1pN2 <= 25) ) { + pswErrorFlag[0] = 1; + } + + } + else { + + if (swSidN1 < 3) + swSid = 2; + else if (swSidN1pN2 < 11) + swSid = 1; + else + swSid = 0; + + } + + + /* in case of a mode mismatch */ + /*----------------------------*/ + + if ( (swSid == 2) && (swMode == 0) ) swSid = 1; + + return(swSid); + +} + + +/*___________________________________________________________________________ + | | + | This subroutine sets the 18 speech parameters to random values | + | | + | Input: pswParameters[18] | + | input parameters of the speech decoder | + | | + |___________________________________________________________________________| +*/ + +static void RandomParameters(int16_t pswParameters[]) +{ + static int16_t ppswIBit[2][18] = { + 5, 11,9,8, 1, 2, 7,7,5, 7,7,5, 7,7,5, 7,7,5, /* unvoiced */ + 5, 11,9,8, 1, 2, 8,9,5, 4,9,5, 4,9,5, 4,9,5}; /* voiced */ + + static int32_t L_PNSeed=(int32_t)0x1091988L; + int16_t i,ind; + + /* Determine mode bit */ + /* ------------------ */ + pswParameters[5] = getPnBits(2, &L_PNSeed); + + /* Switch bit allocation accordingly */ + /* --------------------------------- */ + ind = 0; + if (pswParameters[5] > 0) ind = 1; + + for (i=0; i < 5; i++){ + pswParameters[i] = getPnBits(ppswIBit[ind][i], &L_PNSeed); + } + for (i=6; i < 18; i++){ + pswParameters[i] = getPnBits(ppswIBit[ind][i], &L_PNSeed); + } + + /* force random parameters to PC byte order */ + /* ---------------------------------------- */ + + SwapBytes(pswParameters, 18); +} + +/*___________________________________________________________________________ + | | + | Main - Program | + | | + |___________________________________________________________________________| +*/ +int main( int argc, char *argv[] ) +{ + FILE *infile, *outfile; + int16_t errpat, i = 0; + + if( argc < 4 || argc > 4 ) { + fprintf( stderr, "\tUsage: REID input output EPx \n" ); + fprintf( stderr, "\tEPx: EP0\n" ); + fprintf( stderr, "\t EP1 (not implemented)\n" ); + fprintf( stderr, "\t EP2 (not implemented)\n" ); + fprintf( stderr, "\t EP3 (not implemented)\n" ); + return( 1 ); + } + + + if( !Strincmp( argv[3], "ep", 2 )) + errpat = atoi( &argv[3][2] ); + + printf( " _____________________________________________\n" ); + printf( " | |\n" ); + printf( " | Residual Error Insertion Device |\n" ); + printf( " | for |\n" ); + printf( " | GSM Half-Rate Codec Simulation |\n" ); + printf( " | |\n" ); + printf( " |_____________________________________________|\n\n" ); + + printf( " Input File : %s\n", argv[1] ); + printf( " Output File : %s\n", argv[2] ); + if( errpat ){ + printf( " Error Pattern : EP%d (not implemented)\n", errpat); + return (1); + } + else + printf( " Error Pattern : EP%d (error free)\n", errpat ); + printf( "\n" ); + + infile = OpenBinfile( argv[1], "r" ); + outfile = OpenBinfile( argv[2], "w" ); + + + if (errpat == 0) { + for (i=0;i<6000;i++) + if( error_free( infile, outfile)) break; + } + /*else + for (i=0;i<6000;i++) + if( residual_error_pattern( infile, outfile)) break; + EP1-3 not implemented */ + + fclose( infile ); + fclose( outfile ); + + printf( " %d Frame%s processed \n\n", i,( i != 1 ) ? "s" : "" ); + return( 0 ); +} diff --git a/src/libs/gsmhr/gsmhr_vad.c b/src/libs/gsmhr/gsmhr_vad.c new file mode 100644 index 00000000..7a48d110 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_vad.c @@ -0,0 +1,1363 @@ +/**************************************************************************** + * + * TITLE: Half-Rate GSM Voice Activity Detector (VAD) Modules + * + * VERSION: 1.2 + * + * REFERENCE: Recommendation GSM 06.42 + * + ***************************************************************************/ + +/*_________________________________________________________________________ + | | + | Include Files | + |_________________________________________________________________________| +*/ + +#include "typedefs.h" +#include "mathhalf.h" +#include "mathdp31.h" +#include "vad.h" + + +/*_________________________________________________________________________ + | | + | Local Defines | + |_________________________________________________________________________| +*/ + +/*** Floating point representations of constants pth, plev and margin ***/ + +#define M_PTH 26250 +#define E_PTH 18 +#define M_PLEV 17500 +#define E_PLEV 20 +#define M_MARGIN 27343 +#define E_MARGIN 27 + +/*_________________________________________________________________________ + | | + | Static Variables | + |_________________________________________________________________________| +*/ + +static Shortword + pswRvad[9], + swNormRvad, + swPt_sacf, + swPt_sav0, + swE_thvad, + swM_thvad, + swAdaptCount, + swBurstCount, + swHangCount, + swOldLagCount, + swVeryOldLagCount, + swOldLag; + +static Longword + pL_sacf[27], + pL_sav0[36], + L_lastdm; + +/**************************************************************************** + * + * FUNCTION: vad_reset + * + * VERSION: 1.2 + * + * PURPOSE: Resets VAD static variables to their initial value. + * + ***************************************************************************/ + +void vad_reset(void) + +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + pswRvad[0] = 24576; + swNormRvad = 7; + swPt_sacf = 0; + swPt_sav0 = 0; + L_lastdm = 0; + swE_thvad = 21; + swM_thvad = 21875; + swAdaptCount = 0; + swBurstCount = 0; + swHangCount = -1; + swOldLagCount = 0; + swVeryOldLagCount = 0; + swOldLag = 21; + + for (i = 1; i < 9; i++) + pswRvad[i] = 0; + for (i = 0; i < 27; i++) + pL_sacf[i] = 0; + for (i = 0; i < 36; i++) + pL_sav0[i] = 0; + +} + +/**************************************************************************** + * + * FUNCTION: vad_algorithm + * + * VERSION: 1.2 + * + * PURPOSE: Returns a decision as to whether the current frame being + * processed by the speech encoder contains speech or not. + * + * INPUTS: pL_acf[0..8] autocorrelation of input signal frame + * swScaleAcf L_acf scaling factor + * pswRc[0..3] speech encoder reflection coefficients + * swPtch flag to indicate a periodic signal component + * + * OUTPUTS: pswVadFlag vad decision + * + ***************************************************************************/ + +void vad_algorithm(Longword pL_acf[9], + Shortword swScaleAcf, + Shortword pswRc[4], + Shortword swPtch, + Shortword *pswVadFlag) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + Longword + pL_av0[9], + pL_av1[9]; + + Shortword + swM_acf0, + swE_acf0, + pswRav1[9], + swNormRav1, + swM_pvad, + swE_pvad, + swStat, + swTone, + swVvad; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + energy_computation + ( + pL_acf, swScaleAcf, + pswRvad, swNormRvad, + &swM_pvad, &swE_pvad, + &swM_acf0, &swE_acf0 + ); + + average_acf + ( + pL_acf, swScaleAcf, + pL_av0, pL_av1 + ); + + predictor_values + ( + pL_av1, + pswRav1, + &swNormRav1 + ); + + spectral_comparison + ( + pswRav1, swNormRav1, + pL_av0, + &swStat + ); + + tone_detection + ( + pswRc, + &swTone + ); + + threshold_adaptation + ( + swStat, swPtch, swTone, + pswRav1, swNormRav1, + swM_pvad, swE_pvad, + swM_acf0, swE_acf0, + pswRvad, &swNormRvad, + &swM_thvad, &swE_thvad + ); + + vad_decision + ( + swM_pvad, swE_pvad, + swM_thvad, swE_thvad, + &swVvad + ); + + vad_hangover + ( + swVvad, + pswVadFlag + ); + +} + +/**************************************************************************** + * + * FUNCTION: energy_computation + * + * VERSION: 1.2 + * + * PURPOSE: Computes the input and residual energies of the adaptive + * filter in a floating point representation. + * + * INPUTS: pL_acf[0..8] autocorrelation of input signal frame + * swScaleAcf L_acf scaling factor + * pswRvad[0..8] autocorrelated adaptive filter coefficients + * swNormRvad rvad scaling factor + * + * OUTPUTS: pswM_pvad mantissa of filtered signal energy + * pswE_pvad exponent of filtered signal energy + * pswM_acf0 mantissa of signal frame energy + * pswE_acf0 exponent of signal frame energy + * + ***************************************************************************/ + +void energy_computation(Longword pL_acf[], + Shortword swScaleAcf, + Shortword pswRvad[], + Shortword swNormRvad, + Shortword *pswM_pvad, + Shortword *pswE_pvad, + Shortword *pswM_acf0, + Shortword *pswE_acf0) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + Longword + L_temp; + + Shortword + pswSacf[9], + swNormAcf, + swNormProd, + swShift; + + int + i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** Test if acf[0] is zero ***/ + + if (pL_acf[0] == 0) + { + *pswE_pvad = -0x8000; + *pswM_pvad = 0; + *pswE_acf0 = -0x8000; + *pswM_acf0 = 0; + return; + } + + + /*** Re-normalisation of L_acf[0..8] ***/ + + swNormAcf = norm_l(pL_acf[0]); + swShift = sub(swNormAcf, 3); + + for (i = 0; i <= 8; i++) + pswSacf[i] = extract_h(L_shl(pL_acf[i], swShift)); + + + /*** Computation of e_acf0 and m_acf0 ***/ + + *pswE_acf0 = add(32, shl(swScaleAcf, 1)); + *pswE_acf0 = sub(*pswE_acf0, swNormAcf); + *pswM_acf0 = shl(pswSacf[0], 3); + + + /*** Computation of e_pvad and m_pvad ***/ + + *pswE_pvad = add(*pswE_acf0, 14); + *pswE_pvad = sub(*pswE_pvad, swNormRvad); + + L_temp = 0; + + for (i = 1; i <= 8; i++) + L_temp = L_mac(L_temp, pswSacf[i], pswRvad[i]); + + L_temp = L_add(L_temp, L_shr(L_mult(pswSacf[0], pswRvad[0]), 1)); + + if (L_temp <= 0) + L_temp = 1; + + swNormProd = norm_l(L_temp); + *pswE_pvad = sub(*pswE_pvad, swNormProd); + *pswM_pvad = extract_h(L_shl(L_temp, swNormProd)); + +} + +/**************************************************************************** + * + * FUNCTION: average_acf + * + * VERSION: 1.2 + * + * PURPOSE: Computes the arrays L_av0 [0..8] and L_av1 [0..8]. + * + * INPUTS: pL_acf[0..8] autocorrelation of input signal frame + * swScaleAcf L_acf scaling factor + * + * OUTPUTS: pL_av0[0..8] ACF averaged over last four frames + * pL_av1[0..8] ACF averaged over previous four frames + * + ***************************************************************************/ + +void average_acf(Longword pL_acf[], + Shortword swScaleAcf, + Longword pL_av0[], + Longword pL_av1[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + Longword L_temp; + + Shortword swScale; + + int i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** computation of the scaleing factor ***/ + + swScale = sub(10, shl(swScaleAcf, 1)); + + + /*** Computation of the arrays L_av0 and L_av1 ***/ + + for (i = 0; i <= 8; i++) + { + L_temp = L_shr(pL_acf[i], swScale); + pL_av0[i] = L_add(pL_sacf[i], L_temp); + pL_av0[i] = L_add(pL_sacf[i + 9], pL_av0[i]); + pL_av0[i] = L_add(pL_sacf[i + 18], pL_av0[i]); + pL_sacf[swPt_sacf + i] = L_temp; + pL_av1[i] = pL_sav0[swPt_sav0 + i]; + pL_sav0[swPt_sav0 + i] = pL_av0[i]; + } + + + /*** Update the array pointers ***/ + + if (swPt_sacf == 18) + swPt_sacf = 0; + else + swPt_sacf = add(swPt_sacf, 9); + + if (swPt_sav0 == 27) + swPt_sav0 = 0; + else + swPt_sav0 = add(swPt_sav0, 9); + +} + +/**************************************************************************** + * + * FUNCTION: predictor_values + * + * VERSION: 1.2 + * + * PURPOSE: Computes the array rav [0..8] needed for the spectral + * comparison and the threshold adaptation. + * + * INPUTS: pL_av1 [0..8] ACF averaged over previous four frames + * + * OUTPUTS: pswRav1 [0..8] ACF obtained from L_av1 + * pswNormRav1 r_av1 scaling factor + * + ***************************************************************************/ + +void predictor_values(Longword pL_av1[], + Shortword pswRav1[], + Shortword *pswNormRav1) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + Shortword + pswVpar[8], + pswAav1[9]; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + schur_recursion(pL_av1, pswVpar); + step_up(8, pswVpar, pswAav1); + compute_rav1(pswAav1, pswRav1, pswNormRav1); + +} + +/**************************************************************************** + * + * FUNCTION: schur_recursion + * + * VERSION: 1.2 + * + * PURPOSE: Uses the Schur recursion to compute adaptive filter + * reflection coefficients from an autorrelation function. + * + * INPUTS: pL_av1[0..8] autocorrelation function + * + * OUTPUTS: pswVpar[0..7] reflection coefficients + * + ***************************************************************************/ + +void schur_recursion(Longword pL_av1[], + Shortword pswVpar[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + Shortword + pswAcf[9], + pswPp[9], + pswKk[9], + swTemp; + + int i, + k, + m, + n; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** Schur recursion with 16-bit arithmetic ***/ + + if (pL_av1[0] == 0) + { + for (i = 0; i < 8; i++) + pswVpar[i] = 0; + return; + } + + swTemp = norm_l(pL_av1[0]); + + for (k = 0; k <= 8; k++) + pswAcf[k] = extract_h(L_shl(pL_av1[k], swTemp)); + + + /*** Initialise array pp[..] and kk[..] for the recursion: ***/ + + for (i = 1; i <= 7; i++) + pswKk[9 - i] = pswAcf[i]; + + for (i = 0; i <= 8; i++) + pswPp[i] = pswAcf[i]; + + + /*** Compute Parcor coefficients: ***/ + + for (n = 0; n < 8; n++) + { + if (pswPp[0] < abs_s(pswPp[1])) + { + for (i = n; i < 8; i++) + pswVpar[i] = 0; + return; + } + pswVpar[n] = divide_s(abs_s(pswPp[1]), pswPp[0]); + + if (pswPp[1] > 0) + pswVpar[n] = negate(pswVpar[n]); + if (n == 7) + return; + + + /*** Schur recursion: ***/ + + pswPp[0] = add(pswPp[0], mult_r(pswPp[1], pswVpar[n])); + + for (m = 1; m <= (7 - n); m++) + { + pswPp[m] = add(pswPp[1 + m], mult_r(pswKk[9 - m], pswVpar[n])); + pswKk[9 - m] = add(pswKk[9 - m], mult_r(pswPp[1 + m], pswVpar[n])); + } + } + +} + +/**************************************************************************** + * + * FUNCTION: step_up + * + * VERSION: 1.2 + * + * PURPOSE: Computes the transversal filter coefficients from the + * reflection coefficients. + * + * INPUTS: swNp filter order (2..8) + * pswVpar[0..np-1] reflection coefficients + * + * OUTPUTS: pswAav1[0..np] transversal filter coefficients + * + ***************************************************************************/ + +void step_up(Shortword swNp, + Shortword pswVpar[], + Shortword pswAav1[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + Longword + pL_coef[9], + pL_work[9]; + + Shortword + swTemp; + + int + i, + m; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** Initialisation of the step-up recursion ***/ + + pL_coef[0] = L_shl(0x4000L, 15); + pL_coef[1] = L_shl(L_deposit_l(pswVpar[0]), 14); + + + /*** Loop on the LPC analysis order: ***/ + + for (m = 2; m <= swNp; m++) + { + for (i = 1; i < m; i++) + { + swTemp = extract_h(pL_coef[m - i]); + pL_work[i] = L_mac(pL_coef[i], pswVpar[m - 1], swTemp); + } + for (i = 1; i < m; i++) + pL_coef[i] = pL_work[i]; + pL_coef[m] = L_shl(L_deposit_l(pswVpar[m - 1]), 14); + } + + + /*** Keep the aav1[0..swNp] in 15 bits for the following subclause ***/ + + for (i = 0; i <= swNp; i++) + pswAav1[i] = extract_h(L_shr(pL_coef[i], 3)); + +} + +/**************************************************************************** + * + * FUNCTION: compute_rav1 + * + * VERSION: 1.2 + * + * PURPOSE: Computes the autocorrelation function of the adaptive + * filter coefficients. + * + * INPUTS: pswAav1[0..8] adaptive filter coefficients + * + * OUTPUTS: pswRav1[0..8] ACF of aav1 + * pswNormRav1 r_av1 scaling factor + * + ***************************************************************************/ + +void compute_rav1(Shortword pswAav1[], + Shortword pswRav1[], + Shortword *pswNormRav1) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + Longword + pL_work[9]; + + int + i, + k; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** Computation of the rav1[0..8] ***/ + + for (i = 0; i <= 8; i++) + { + pL_work[i] = 0; + + for (k = 0; k <= 8 - i; k++) + pL_work[i] = L_mac(pL_work[i], pswAav1[k], pswAav1[k + i]); + } + + if (pL_work[0] == 0) + *pswNormRav1 = 0; + else + *pswNormRav1 = norm_l(pL_work[0]); + + for (i = 0; i <= 8; i++) + pswRav1[i] = extract_h(L_shl(pL_work[i], *pswNormRav1)); + +} + +/**************************************************************************** + * + * FUNCTION: spectral_comparison + * + * VERSION: 1.2 + * + * PURPOSE: Computes the stat flag needed for the threshold + * adaptation decision. + * + * INPUTS: pswRav1[0..8] ACF obtained from L_av1 + * swNormRav1 rav1 scaling factor + * pL_av0[0..8] ACF averaged over last four frames + * + * OUTPUTS: pswStat flag to indicate spectral stationarity + * + ***************************************************************************/ + +void spectral_comparison(Shortword pswRav1[], + Shortword swNormRav1, + Longword pL_av0[], + Shortword *pswStat) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + Longword + L_dm, + L_sump, + L_temp; + + Shortword + pswSav0[9], + swShift, + swDivShift, + swTemp; + + int + i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** Re-normalise L_av0[0..8] ***/ + + if (pL_av0[0] == 0) + { + for (i = 0; i <= 8; i++) + pswSav0[i] = 4095; + } + else + { + swShift = sub(norm_l(pL_av0[0]), 3); + for (i = 0; i <= 8; i++) + pswSav0[i] = extract_h(L_shl(pL_av0[i], swShift)); + } + + /*** compute partial sum of dm ***/ + + L_sump = 0; + + for (i = 1; i <= 8; i++) + L_sump = L_mac(L_sump, pswRav1[i], pswSav0[i]); + + /*** compute the division of the partial sum by sav0[0] ***/ + + if (L_sump < 0) + L_temp = L_negate(L_sump); + else + L_temp = L_sump; + + if (L_temp == 0) + { + L_dm = 0; + swShift = 0; + } + else + { + pswSav0[0] = shl(pswSav0[0], 3); + swShift = norm_l(L_temp); + swTemp = extract_h(L_shl(L_temp, swShift)); + + if (pswSav0[0] >= swTemp) + { + swDivShift = 0; + swTemp = divide_s(swTemp, pswSav0[0]); + } + else + { + swDivShift = 1; + swTemp = sub(swTemp, pswSav0[0]); + swTemp = divide_s(swTemp, pswSav0[0]); + } + + if (swDivShift == 1) + L_dm = 0x8000L; + else + L_dm = 0; + + L_dm = L_shl((L_add(L_dm, L_deposit_l(swTemp))), 1); + + if (L_sump < 0) + L_dm = L_sub(0L, L_dm); + } + + + /*** Re-normalisation and final computation of L_dm ***/ + + L_dm = L_shl(L_dm, 14); + L_dm = L_shr(L_dm, swShift); + L_dm = L_add(L_dm, L_shl(L_deposit_l(pswRav1[0]), 11)); + L_dm = L_shr(L_dm, swNormRav1); + + + /*** Compute the difference and save L_dm ***/ + + L_temp = L_sub(L_dm, L_lastdm); + L_lastdm = L_dm; + + if (L_temp < 0L) + L_temp = L_negate(L_temp); + + + /*** Evaluation of the state flag ***/ + + L_temp = L_sub(L_temp, 4456L); + + if (L_temp < 0) + *pswStat = 1; + else + *pswStat = 0; + +} + +/**************************************************************************** + * + * FUNCTION: tone_detection + * + * VERSION: 1.2 + * + * PURPOSE: Computes the tone flag needed for the threshold + * adaptation decision. + * + * INPUTS: pswRc[0..3] reflection coefficients calculated in the + * speech encoder short term predictor + * + * OUTPUTS: pswTone flag to indicate a periodic signal component + * + ***************************************************************************/ + +void tone_detection(Shortword pswRc[4], + Shortword *pswTone) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + Longword + L_num, + L_den, + L_temp; + + Shortword + swTemp, + swPredErr, + pswA[3]; + + int + i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + *pswTone = 0; + + + /*** Calculate filter coefficients ***/ + + step_up(2, pswRc, pswA); + + + /*** Calculate ( a[1] * a[1] ) ***/ + + swTemp = shl(pswA[1], 3); + L_den = L_mult(swTemp, swTemp); + + + /*** Calculate ( 4*a[2] - a[1]*a[1] ) ***/ + + L_temp = L_shl(L_deposit_h(pswA[2]), 3); + L_num = L_sub(L_temp, L_den); + + + /*** Check if pole frequency is less than 385 Hz ***/ + + if (L_num <= 0) + return; + + if (pswA[1] < 0) + { + swTemp = extract_h(L_den); + L_temp = L_msu(L_num, swTemp, 3189); + + if (L_temp < 0) + return; + } + + + /*** Calculate normalised prediction error ***/ + + swPredErr = 0x7fff; + + for (i = 0; i < 4; i++) + { + swTemp = mult(pswRc[i], pswRc[i]); + swTemp = sub(32767, swTemp); + swPredErr = mult(swPredErr, swTemp); + } + + + /*** Test if prediction error is smaller than threshold ***/ + + swTemp = sub(swPredErr, 1464); + + if (swTemp < 0) + *pswTone = 1; + +} + +/**************************************************************************** + * + * FUNCTION: threshold_adaptation + * + * VERSION: 1.2 + * + * PURPOSE: Evaluates the secondary VAD decision. If speech is not + * present then the noise model rvad and adaptive threshold + * thvad are updated. + * + * INPUTS: swStat flag to indicate spectral stationarity + * swPtch flag to indicate a periodic signal component + * swTone flag to indicate a tone signal component + * pswRav1[0..8] ACF obtained from l_av1 + * swNormRav1 r_av1 scaling factor + * swM_pvad mantissa of filtered signal energy + * swE_pvad exponent of filtered signal energy + * swM_acf0 mantissa of signal frame energy + * swE_acf0 exponent of signal frame energy + * + * OUTPUTS: pswRvad[0..8] autocorrelated adaptive filter coefficients + * pswNormRvad rvad scaling factor + * pswM_thvad mantissa of decision threshold + * pswE_thvad exponent of decision threshold + * + ***************************************************************************/ + +void threshold_adaptation(Shortword swStat, + Shortword swPtch, + Shortword swTone, + Shortword pswRav1[], + Shortword swNormRav1, + Shortword swM_pvad, + Shortword swE_pvad, + Shortword swM_acf0, + Shortword swE_acf0, + Shortword pswRvad[], + Shortword *pswNormRvad, + Shortword *pswM_thvad, + Shortword *pswE_thvad) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + Longword + L_temp; + + Shortword + swTemp, + swComp, + swComp2, + swM_temp, + swE_temp; + + int + i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + swComp = 0; + + /*** Test if acf0 < pth; if yes set thvad to plev ***/ + + if (swE_acf0 < E_PTH) + swComp = 1; + if ((swE_acf0 == E_PTH) && (swM_acf0 < M_PTH)) + swComp = 1; + + if (swComp == 1) + { + *pswE_thvad = E_PLEV; + *pswM_thvad = M_PLEV; + + return; + } + + + /*** Test if an adaption is required ***/ + + if (swPtch == 1) + swComp = 1; + if (swStat == 0) + swComp = 1; + if (swTone == 1) + swComp = 1; + + if (swComp == 1) + { + swAdaptCount = 0; + return; + } + + + /*** Increment adaptcount ***/ + + swAdaptCount = add(swAdaptCount, 1); + if (swAdaptCount <= 8) + return; + + + /*** computation of thvad-(thvad/dec) ***/ + + *pswM_thvad = sub(*pswM_thvad, shr(*pswM_thvad, 5)); + + if (*pswM_thvad < 0x4000) + { + *pswM_thvad = shl(*pswM_thvad, 1); + *pswE_thvad = sub(*pswE_thvad, 1); + } + + + /*** computation of pvad*fac ***/ + + L_temp = L_mult(swM_pvad, 20889); + L_temp = L_shr(L_temp, 15); + swE_temp = add(swE_pvad, 1); + + if (L_temp > 0x7fffL) + { + L_temp = L_shr(L_temp, 1); + swE_temp = add(swE_temp, 1); + } + swM_temp = extract_l(L_temp); + + + /*** test if thvad < pavd*fac ***/ + + if (*pswE_thvad < swE_temp) + swComp = 1; + + if ((*pswE_thvad == swE_temp) && (*pswM_thvad < swM_temp)) + swComp = 1; + + + /*** compute minimum(thvad+(thvad/inc), pvad*fac) when comp = 1 ***/ + + if (swComp == 1) + { + + /*** compute thvad + (thvad/inc) ***/ + + L_temp = L_add(L_deposit_l(*pswM_thvad),L_deposit_l(shr(*pswM_thvad, 4))); + + if (L_temp > 0x7fffL) + { + *pswM_thvad = extract_l(L_shr(L_temp, 1)); + *pswE_thvad = add(*pswE_thvad, 1); + } + else + *pswM_thvad = extract_l(L_temp); + + swComp2 = 0; + + if (swE_temp < *pswE_thvad) + swComp2 = 1; + + if ((swE_temp == *pswE_thvad) && (swM_temp < *pswM_thvad)) + swComp2 = 1; + + if (swComp2 == 1) + { + *pswE_thvad = swE_temp; + *pswM_thvad = swM_temp; + } + } + + + /*** compute pvad + margin ***/ + + if (swE_pvad == E_MARGIN) + { + L_temp = L_add(L_deposit_l(swM_pvad), L_deposit_l(M_MARGIN)); + swM_temp = extract_l(L_shr(L_temp, 1)); + swE_temp = add(swE_pvad, 1); + } + else + { + if (swE_pvad > E_MARGIN) + { + swTemp = sub(swE_pvad, E_MARGIN); + swTemp = shr(M_MARGIN, swTemp); + L_temp = L_add(L_deposit_l(swM_pvad), L_deposit_l(swTemp)); + + if (L_temp > 0x7fffL) + { + swE_temp = add(swE_pvad, 1); + swM_temp = extract_l(L_shr(L_temp, 1)); + } + else + { + swE_temp = swE_pvad; + swM_temp = extract_l(L_temp); + } + } + else + { + swTemp = sub(E_MARGIN, swE_pvad); + swTemp = shr(swM_pvad, swTemp); + L_temp = L_add(L_deposit_l(M_MARGIN), L_deposit_l(swTemp)); + + if (L_temp > 0x7fffL) + { + swE_temp = add(E_MARGIN, 1); + swM_temp = extract_l(L_shr(L_temp, 1)); + } + else + { + swE_temp = E_MARGIN; + swM_temp = extract_l(L_temp); + } + } + } + + /*** Test if thvad > pvad + margin ***/ + + swComp = 0; + + if (*pswE_thvad > swE_temp) + swComp = 1; + + if ((*pswE_thvad == swE_temp) && (*pswM_thvad > swM_temp)) + swComp = 1; + + if (swComp == 1) + { + *pswE_thvad = swE_temp; + *pswM_thvad = swM_temp; + } + + /*** Normalise and retain rvad[0..8] in memory ***/ + + *pswNormRvad = swNormRav1; + + for (i = 0; i <= 8; i++) + pswRvad[i] = pswRav1[i]; + + /*** Set adaptcount to adp + 1 ***/ + + swAdaptCount = 9; + +} + +/**************************************************************************** + * + * FUNCTION: vad_decision + * + * VERSION: 1.2 + * + * PURPOSE: Computes the VAD decision based on the comparison of the + * floating point representations of pvad and thvad. + * + * INPUTS: swM_pvad mantissa of filtered signal energy + * swE_pvad exponent of filtered signal energy + * swM_thvad mantissa of decision threshold + * swE_thvad exponent of decision threshold + * + * OUTPUTS: pswVvad vad decision before hangover is added + * + ***************************************************************************/ + +void vad_decision(Shortword swM_pvad, + Shortword swE_pvad, + Shortword swM_thvad, + Shortword swE_thvad, + Shortword *pswVvad) +{ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + *pswVvad = 0; + + if (swE_pvad > swE_thvad) + *pswVvad = 1; + if ((swE_pvad == swE_thvad) && (swM_pvad > swM_thvad)) + *pswVvad = 1; + +} + +/**************************************************************************** + * + * FUNCTION: vad_hangover + * + * VERSION: 1.2 + * + * PURPOSE: Computes the final VAD decision for the current frame + * being processed. + * + * INPUTS: swVvad vad decision before hangover is added + * + * OUTPUTS: pswVadFlag vad decision after hangover is added + * + ***************************************************************************/ + +void vad_hangover(Shortword swVvad, + Shortword *pswVadFlag) +{ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + if (swVvad == 1) + swBurstCount = add(swBurstCount, 1); + else + swBurstCount = 0; + + if (swBurstCount >= 3) + { + swHangCount = 5; + swBurstCount = 3; + } + + *pswVadFlag = swVvad; + + if (swHangCount >= 0) + { + *pswVadFlag = 1; + swHangCount = sub(swHangCount, 1); + } + +} + +/**************************************************************************** + * + * FUNCTION: periodicity_update + * + * VERSION: 1.2 + * + * PURPOSE: Computes the ptch flag needed for the threshold + * adaptation decision for the next frame. + * + * INPUTS: pswLags[0..3] speech encoder long term predictor lags + * + * OUTPUTS: pswPtch Boolean voiced / unvoiced decision + * + ***************************************************************************/ + +void periodicity_update(Shortword pswLags[4], + Shortword *pswPtch) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + Shortword + swMinLag, + swMaxLag, + swSmallLag, + swLagCount, + swTemp; + + int + i, + j; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** Run loop for No. of sub-segments in the frame ***/ + + swLagCount = 0; + + for (i = 0; i <= 3; i++) + { + /*** Search the maximum and minimum of consecutive lags ***/ + + if (swOldLag > pswLags[i]) + { + swMinLag = pswLags[i]; + swMaxLag = swOldLag; + } + else + { + swMinLag = swOldLag; + swMaxLag = pswLags[i]; + } + + + /*** Compute smallag (modulo operation not defined) ***/ + + swSmallLag = swMaxLag; + + for (j = 0; j <= 2; j++) + { + if (swSmallLag >= swMinLag) + swSmallLag = sub(swSmallLag, swMinLag); + } + + + /*** Minimum of smallag and minlag - smallag ***/ + + swTemp = sub(swMinLag, swSmallLag); + + if (swTemp < swSmallLag) + swSmallLag = swTemp; + + if (swSmallLag < 2) + swLagCount = add(swLagCount, 1); + + + /*** Save the current LTP lag ***/ + + swOldLag = pswLags[i]; + } + + + /*** Update the veryoldlagcount and oldlagcount ***/ + + swVeryOldLagCount = swOldLagCount; + swOldLagCount = swLagCount; + + + /*** Make ptch decision ready for next frame ***/ + + swTemp = add(swOldLagCount, swVeryOldLagCount); + + if (swTemp >= 7) + *pswPtch = 1; + else + *pswPtch = 0; + +} diff --git a/src/libs/gsmhr/gsmhr_vad.cpp b/src/libs/gsmhr/gsmhr_vad.cpp new file mode 100644 index 00000000..78e94f49 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_vad.cpp @@ -0,0 +1,1331 @@ +/**************************************************************************** + * + * TITLE: Half-Rate GSM Voice Activity Detector (VAD) Modules + * + * VERSION: 1.2 + * + * REFERENCE: Recommendation GSM 06.42 + * + ***************************************************************************/ + +/*_________________________________________________________________________ + | | + | Include Files | + |_________________________________________________________________________| +*/ + +#include "gsmhr_typedefs.h" +#include "gsmhr_mathhalf.h" +#include "gsmhr_mathdp31.h" +#include "gsmhr_vad.h" + + +/*_________________________________________________________________________ + | | + | Local Defines | + |_________________________________________________________________________| +*/ + +/*** Floating point representations of constants pth, plev and margin ***/ + +#define M_PTH 26250 +#define E_PTH 18 +#define M_PLEV 17500 +#define E_PLEV 20 +#define M_MARGIN 27343 +#define E_MARGIN 27 + +/*_________________________________________________________________________ + | | + | Static Variables | + |_________________________________________________________________________| +*/ + +/**************************************************************************** + * + * FUNCTION: vad_reset + * + * VERSION: 1.2 + * + * PURPOSE: Resets VAD static variables to their initial value. + * + ***************************************************************************/ + +void GsmHrVad::vad_reset(void) +{ + + int i; + + pswRvad[0] = 24576; + swNormRvad = 7; + swPt_sacf = 0; + swPt_sav0 = 0; + L_lastdm = 0; + swE_thvad = 21; + swM_thvad = 21875; + swAdaptCount = 0; + swBurstCount = 0; + swHangCount = -1; + swOldLagCount = 0; + swVeryOldLagCount = 0; + swOldLag = 21; + + for (i = 1; i < 9; i++) + pswRvad[i] = 0; + for (i = 0; i < 27; i++) + pL_sacf[i] = 0; + for (i = 0; i < 36; i++) + pL_sav0[i] = 0; + +} + +/**************************************************************************** + * + * FUNCTION: vad_algorithm + * + * VERSION: 1.2 + * + * PURPOSE: Returns a decision as to whether the current frame being + * processed by the speech encoder contains speech or not. + * + * INPUTS: pL_acf[0..8] autocorrelation of input signal frame + * swScaleAcf L_acf scaling factor + * pswRc[0..3] speech encoder reflection coefficients + * swPtch flag to indicate a periodic signal component + * + * OUTPUTS: pswVadFlag vad decision + * + ***************************************************************************/ + +void GsmHrVad::algorithm(int32_t pL_acf[9], + int16_t swScaleAcf, + int16_t pswRc[4], + int16_t swPtch, + int16_t *pswVadFlag) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t + pL_av0[9], + pL_av1[9]; + + int16_t + swM_acf0, + swE_acf0, + pswRav1[9], + swNormRav1, + swM_pvad, + swE_pvad, + swStat, + swTone, + swVvad; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + energy_computation + ( + pL_acf, swScaleAcf, + pswRvad, swNormRvad, + &swM_pvad, &swE_pvad, + &swM_acf0, &swE_acf0 + ); + + average_acf + ( + pL_acf, swScaleAcf, + pL_av0, pL_av1 + ); + + predictor_values + ( + pL_av1, + pswRav1, + &swNormRav1 + ); + + spectral_comparison + ( + pswRav1, swNormRav1, + pL_av0, + &swStat + ); + + tone_detection + ( + pswRc, + &swTone + ); + + threshold_adaptation + ( + swStat, swPtch, swTone, + pswRav1, swNormRav1, + swM_pvad, swE_pvad, + swM_acf0, swE_acf0, + pswRvad, &swNormRvad, + &swM_thvad, &swE_thvad + ); + + vad_decision + ( + swM_pvad, swE_pvad, + swM_thvad, swE_thvad, + &swVvad + ); + + vad_hangover + ( + swVvad, + pswVadFlag + ); + +} + +/**************************************************************************** + * + * FUNCTION: energy_computation + * + * VERSION: 1.2 + * + * PURPOSE: Computes the input and residual energies of the adaptive + * filter in a floating point representation. + * + * INPUTS: pL_acf[0..8] autocorrelation of input signal frame + * swScaleAcf L_acf scaling factor + * pswRvad[0..8] autocorrelated adaptive filter coefficients + * swNormRvad rvad scaling factor + * + * OUTPUTS: pswM_pvad mantissa of filtered signal energy + * pswE_pvad exponent of filtered signal energy + * pswM_acf0 mantissa of signal frame energy + * pswE_acf0 exponent of signal frame energy + * + ***************************************************************************/ + +void GsmHrVad::energy_computation(int32_t pL_acf[], + int16_t swScaleAcf, + int16_t pswRvad[], + int16_t swNormRvad, + int16_t *pswM_pvad, + int16_t *pswE_pvad, + int16_t *pswM_acf0, + int16_t *pswE_acf0) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t + L_temp; + + int16_t + pswSacf[9], + swNormAcf, + swNormProd, + swShift; + + int + i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** Test if acf[0] is zero ***/ + + if (pL_acf[0] == 0) + { + *pswE_pvad = -0x8000; + *pswM_pvad = 0; + *pswE_acf0 = -0x8000; + *pswM_acf0 = 0; + return; + } + + + /*** Re-normalisation of L_acf[0..8] ***/ + + swNormAcf = norm_l(pL_acf[0]); + swShift = sub(swNormAcf, 3); + + for (i = 0; i <= 8; i++) + pswSacf[i] = extract_h(L_shl(pL_acf[i], swShift)); + + + /*** Computation of e_acf0 and m_acf0 ***/ + + *pswE_acf0 = add(32, shl(swScaleAcf, 1)); + *pswE_acf0 = sub(*pswE_acf0, swNormAcf); + *pswM_acf0 = shl(pswSacf[0], 3); + + + /*** Computation of e_pvad and m_pvad ***/ + + *pswE_pvad = add(*pswE_acf0, 14); + *pswE_pvad = sub(*pswE_pvad, swNormRvad); + + L_temp = 0; + + for (i = 1; i <= 8; i++) + L_temp = L_mac(L_temp, pswSacf[i], pswRvad[i]); + + L_temp = L_add(L_temp, L_shr(L_mult(pswSacf[0], pswRvad[0]), 1)); + + if (L_temp <= 0) + L_temp = 1; + + swNormProd = norm_l(L_temp); + *pswE_pvad = sub(*pswE_pvad, swNormProd); + *pswM_pvad = extract_h(L_shl(L_temp, swNormProd)); + +} + +/**************************************************************************** + * + * FUNCTION: average_acf + * + * VERSION: 1.2 + * + * PURPOSE: Computes the arrays L_av0 [0..8] and L_av1 [0..8]. + * + * INPUTS: pL_acf[0..8] autocorrelation of input signal frame + * swScaleAcf L_acf scaling factor + * + * OUTPUTS: pL_av0[0..8] ACF averaged over last four frames + * pL_av1[0..8] ACF averaged over previous four frames + * + ***************************************************************************/ + +void GsmHrVad::average_acf(int32_t pL_acf[], + int16_t swScaleAcf, + int32_t pL_av0[], + int32_t pL_av1[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t L_temp; + + int16_t swScale; + + int i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** computation of the scaleing factor ***/ + + swScale = sub(10, shl(swScaleAcf, 1)); + + + /*** Computation of the arrays L_av0 and L_av1 ***/ + + for (i = 0; i <= 8; i++) + { + L_temp = L_shr(pL_acf[i], swScale); + pL_av0[i] = L_add(pL_sacf[i], L_temp); + pL_av0[i] = L_add(pL_sacf[i + 9], pL_av0[i]); + pL_av0[i] = L_add(pL_sacf[i + 18], pL_av0[i]); + pL_sacf[swPt_sacf + i] = L_temp; + pL_av1[i] = pL_sav0[swPt_sav0 + i]; + pL_sav0[swPt_sav0 + i] = pL_av0[i]; + } + + + /*** Update the array pointers ***/ + + if (swPt_sacf == 18) + swPt_sacf = 0; + else + swPt_sacf = add(swPt_sacf, 9); + + if (swPt_sav0 == 27) + swPt_sav0 = 0; + else + swPt_sav0 = add(swPt_sav0, 9); + +} + +/**************************************************************************** + * + * FUNCTION: predictor_values + * + * VERSION: 1.2 + * + * PURPOSE: Computes the array rav [0..8] needed for the spectral + * comparison and the threshold adaptation. + * + * INPUTS: pL_av1 [0..8] ACF averaged over previous four frames + * + * OUTPUTS: pswRav1 [0..8] ACF obtained from L_av1 + * pswNormRav1 r_av1 scaling factor + * + ***************************************************************************/ + +void GsmHrVad::predictor_values(int32_t pL_av1[], + int16_t pswRav1[], + int16_t *pswNormRav1) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t + pswVpar[8], + pswAav1[9]; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + schur_recursion(pL_av1, pswVpar); + step_up(8, pswVpar, pswAav1); + compute_rav1(pswAav1, pswRav1, pswNormRav1); + +} + +/**************************************************************************** + * + * FUNCTION: schur_recursion + * + * VERSION: 1.2 + * + * PURPOSE: Uses the Schur recursion to compute adaptive filter + * reflection coefficients from an autorrelation function. + * + * INPUTS: pL_av1[0..8] autocorrelation function + * + * OUTPUTS: pswVpar[0..7] reflection coefficients + * + ***************************************************************************/ + +void GsmHrVad::schur_recursion(int32_t pL_av1[], + int16_t pswVpar[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t + pswAcf[9], + pswPp[9], + pswKk[9], + swTemp; + + int i, + k, + m, + n; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** Schur recursion with 16-bit arithmetic ***/ + + if (pL_av1[0] == 0) + { + for (i = 0; i < 8; i++) + pswVpar[i] = 0; + return; + } + + swTemp = norm_l(pL_av1[0]); + + for (k = 0; k <= 8; k++) + pswAcf[k] = extract_h(L_shl(pL_av1[k], swTemp)); + + + /*** Initialise array pp[..] and kk[..] for the recursion: ***/ + + for (i = 1; i <= 7; i++) + pswKk[9 - i] = pswAcf[i]; + + for (i = 0; i <= 8; i++) + pswPp[i] = pswAcf[i]; + + + /*** Compute Parcor coefficients: ***/ + + for (n = 0; n < 8; n++) + { + if (pswPp[0] < abs_s(pswPp[1])) + { + for (i = n; i < 8; i++) + pswVpar[i] = 0; + return; + } + pswVpar[n] = divide_s(abs_s(pswPp[1]), pswPp[0]); + + if (pswPp[1] > 0) + pswVpar[n] = negate(pswVpar[n]); + if (n == 7) + return; + + + /*** Schur recursion: ***/ + + pswPp[0] = add(pswPp[0], mult_r(pswPp[1], pswVpar[n])); + + for (m = 1; m <= (7 - n); m++) + { + pswPp[m] = add(pswPp[1 + m], mult_r(pswKk[9 - m], pswVpar[n])); + pswKk[9 - m] = add(pswKk[9 - m], mult_r(pswPp[1 + m], pswVpar[n])); + } + } + +} + +/**************************************************************************** + * + * FUNCTION: step_up + * + * VERSION: 1.2 + * + * PURPOSE: Computes the transversal filter coefficients from the + * reflection coefficients. + * + * INPUTS: swNp filter order (2..8) + * pswVpar[0..np-1] reflection coefficients + * + * OUTPUTS: pswAav1[0..np] transversal filter coefficients + * + ***************************************************************************/ + +void GsmHrVad::step_up(int16_t swNp, + int16_t pswVpar[], + int16_t pswAav1[]) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t + pL_coef[9], + pL_work[9]; + + int16_t + swTemp; + + int + i, + m; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** Initialisation of the step-up recursion ***/ + + pL_coef[0] = L_shl(0x4000L, 15); + pL_coef[1] = L_shl(L_deposit_l(pswVpar[0]), 14); + + + /*** Loop on the LPC analysis order: ***/ + + for (m = 2; m <= swNp; m++) + { + for (i = 1; i < m; i++) + { + swTemp = extract_h(pL_coef[m - i]); + pL_work[i] = L_mac(pL_coef[i], pswVpar[m - 1], swTemp); + } + for (i = 1; i < m; i++) + pL_coef[i] = pL_work[i]; + pL_coef[m] = L_shl(L_deposit_l(pswVpar[m - 1]), 14); + } + + + /*** Keep the aav1[0..swNp] in 15 bits for the following subclause ***/ + + for (i = 0; i <= swNp; i++) + pswAav1[i] = extract_h(L_shr(pL_coef[i], 3)); + +} + +/**************************************************************************** + * + * FUNCTION: compute_rav1 + * + * VERSION: 1.2 + * + * PURPOSE: Computes the autocorrelation function of the adaptive + * filter coefficients. + * + * INPUTS: pswAav1[0..8] adaptive filter coefficients + * + * OUTPUTS: pswRav1[0..8] ACF of aav1 + * pswNormRav1 r_av1 scaling factor + * + ***************************************************************************/ + +void GsmHrVad::compute_rav1(int16_t pswAav1[], + int16_t pswRav1[], + int16_t *pswNormRav1) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t + pL_work[9]; + + int + i, + k; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** Computation of the rav1[0..8] ***/ + + for (i = 0; i <= 8; i++) + { + pL_work[i] = 0; + + for (k = 0; k <= 8 - i; k++) + pL_work[i] = L_mac(pL_work[i], pswAav1[k], pswAav1[k + i]); + } + + if (pL_work[0] == 0) + *pswNormRav1 = 0; + else + *pswNormRav1 = norm_l(pL_work[0]); + + for (i = 0; i <= 8; i++) + pswRav1[i] = extract_h(L_shl(pL_work[i], *pswNormRav1)); + +} + +/**************************************************************************** + * + * FUNCTION: spectral_comparison + * + * VERSION: 1.2 + * + * PURPOSE: Computes the stat flag needed for the threshold + * adaptation decision. + * + * INPUTS: pswRav1[0..8] ACF obtained from L_av1 + * swNormRav1 rav1 scaling factor + * pL_av0[0..8] ACF averaged over last four frames + * + * OUTPUTS: pswStat flag to indicate spectral stationarity + * + ***************************************************************************/ + +void GsmHrVad::spectral_comparison(int16_t pswRav1[], + int16_t swNormRav1, + int32_t pL_av0[], + int16_t *pswStat) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t + L_dm, + L_sump, + L_temp; + + int16_t + pswSav0[9], + swShift, + swDivShift, + swTemp; + + int + i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** Re-normalise L_av0[0..8] ***/ + + if (pL_av0[0] == 0) + { + for (i = 0; i <= 8; i++) + pswSav0[i] = 4095; + } + else + { + swShift = sub(norm_l(pL_av0[0]), 3); + for (i = 0; i <= 8; i++) + pswSav0[i] = extract_h(L_shl(pL_av0[i], swShift)); + } + + /*** compute partial sum of dm ***/ + + L_sump = 0; + + for (i = 1; i <= 8; i++) + L_sump = L_mac(L_sump, pswRav1[i], pswSav0[i]); + + /*** compute the division of the partial sum by sav0[0] ***/ + + if (L_sump < 0) + L_temp = L_negate(L_sump); + else + L_temp = L_sump; + + if (L_temp == 0) + { + L_dm = 0; + swShift = 0; + } + else + { + pswSav0[0] = shl(pswSav0[0], 3); + swShift = norm_l(L_temp); + swTemp = extract_h(L_shl(L_temp, swShift)); + + if (pswSav0[0] >= swTemp) + { + swDivShift = 0; + swTemp = divide_s(swTemp, pswSav0[0]); + } + else + { + swDivShift = 1; + swTemp = sub(swTemp, pswSav0[0]); + swTemp = divide_s(swTemp, pswSav0[0]); + } + + if (swDivShift == 1) + L_dm = 0x8000L; + else + L_dm = 0; + + L_dm = L_shl((L_add(L_dm, L_deposit_l(swTemp))), 1); + + if (L_sump < 0) + L_dm = L_sub(0L, L_dm); + } + + + /*** Re-normalisation and final computation of L_dm ***/ + + L_dm = L_shl(L_dm, 14); + L_dm = L_shr(L_dm, swShift); + L_dm = L_add(L_dm, L_shl(L_deposit_l(pswRav1[0]), 11)); + L_dm = L_shr(L_dm, swNormRav1); + + + /*** Compute the difference and save L_dm ***/ + + L_temp = L_sub(L_dm, L_lastdm); + L_lastdm = L_dm; + + if (L_temp < 0L) + L_temp = L_negate(L_temp); + + + /*** Evaluation of the state flag ***/ + + L_temp = L_sub(L_temp, 4456L); + + if (L_temp < 0) + *pswStat = 1; + else + *pswStat = 0; + +} + +/**************************************************************************** + * + * FUNCTION: tone_detection + * + * VERSION: 1.2 + * + * PURPOSE: Computes the tone flag needed for the threshold + * adaptation decision. + * + * INPUTS: pswRc[0..3] reflection coefficients calculated in the + * speech encoder short term predictor + * + * OUTPUTS: pswTone flag to indicate a periodic signal component + * + ***************************************************************************/ + +void GsmHrVad::tone_detection(int16_t pswRc[4], + int16_t *pswTone) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t + L_num, + L_den, + L_temp; + + int16_t + swTemp, + swPredErr, + pswA[3]; + + int + i; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + *pswTone = 0; + + + /*** Calculate filter coefficients ***/ + + step_up(2, pswRc, pswA); + + + /*** Calculate ( a[1] * a[1] ) ***/ + + swTemp = shl(pswA[1], 3); + L_den = L_mult(swTemp, swTemp); + + + /*** Calculate ( 4*a[2] - a[1]*a[1] ) ***/ + + L_temp = L_shl(L_deposit_h(pswA[2]), 3); + L_num = L_sub(L_temp, L_den); + + + /*** Check if pole frequency is less than 385 Hz ***/ + + if (L_num <= 0) + return; + + if (pswA[1] < 0) + { + swTemp = extract_h(L_den); + L_temp = L_msu(L_num, swTemp, 3189); + + if (L_temp < 0) + return; + } + + + /*** Calculate normalised prediction error ***/ + + swPredErr = 0x7fff; + + for (i = 0; i < 4; i++) + { + swTemp = mult(pswRc[i], pswRc[i]); + swTemp = sub(32767, swTemp); + swPredErr = mult(swPredErr, swTemp); + } + + + /*** Test if prediction error is smaller than threshold ***/ + + swTemp = sub(swPredErr, 1464); + + if (swTemp < 0) + *pswTone = 1; + +} + +/**************************************************************************** + * + * FUNCTION: threshold_adaptation + * + * VERSION: 1.2 + * + * PURPOSE: Evaluates the secondary VAD decision. If speech is not + * present then the noise model rvad and adaptive threshold + * thvad are updated. + * + * INPUTS: swStat flag to indicate spectral stationarity + * swPtch flag to indicate a periodic signal component + * swTone flag to indicate a tone signal component + * pswRav1[0..8] ACF obtained from l_av1 + * swNormRav1 r_av1 scaling factor + * swM_pvad mantissa of filtered signal energy + * swE_pvad exponent of filtered signal energy + * swM_acf0 mantissa of signal frame energy + * swE_acf0 exponent of signal frame energy + * + * OUTPUTS: pswRvad[0..8] autocorrelated adaptive filter coefficients + * pswNormRvad rvad scaling factor + * pswM_thvad mantissa of decision threshold + * pswE_thvad exponent of decision threshold + * + ***************************************************************************/ + +void GsmHrVad::threshold_adaptation(int16_t swStat, + int16_t swPtch, + int16_t swTone, + int16_t pswRav1[], + int16_t swNormRav1, + int16_t swM_pvad, + int16_t swE_pvad, + int16_t swM_acf0, + int16_t swE_acf0, + int16_t pswRvad[], + int16_t *pswNormRvad, + int16_t *pswM_thvad, + int16_t *pswE_thvad) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int32_t + L_temp; + + int16_t + swTemp, + swComp, + swComp2, + swM_temp, + swE_temp; + + int + i; + + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + swComp = 0; + + /*** Test if acf0 < pth; if yes set thvad to plev ***/ + + if (swE_acf0 < E_PTH) + swComp = 1; + if ((swE_acf0 == E_PTH) && (swM_acf0 < M_PTH)) + swComp = 1; + + if (swComp == 1) + { + *pswE_thvad = E_PLEV; + *pswM_thvad = M_PLEV; + + return; + } + + + /*** Test if an adaption is required ***/ + + if (swPtch == 1) + swComp = 1; + if (swStat == 0) + swComp = 1; + if (swTone == 1) + swComp = 1; + + if (swComp == 1) + { + swAdaptCount = 0; + return; + } + + + /*** Increment adaptcount ***/ + + swAdaptCount = add(swAdaptCount, 1); + if (swAdaptCount <= 8) + return; + + + /*** computation of thvad-(thvad/dec) ***/ + + *pswM_thvad = sub(*pswM_thvad, shr(*pswM_thvad, 5)); + + if (*pswM_thvad < 0x4000) + { + *pswM_thvad = shl(*pswM_thvad, 1); + *pswE_thvad = sub(*pswE_thvad, 1); + } + + + /*** computation of pvad*fac ***/ + + L_temp = L_mult(swM_pvad, 20889); + L_temp = L_shr(L_temp, 15); + swE_temp = add(swE_pvad, 1); + + if (L_temp > 0x7fffL) + { + L_temp = L_shr(L_temp, 1); + swE_temp = add(swE_temp, 1); + } + swM_temp = extract_l(L_temp); + + + /*** test if thvad < pavd*fac ***/ + + if (*pswE_thvad < swE_temp) + swComp = 1; + + if ((*pswE_thvad == swE_temp) && (*pswM_thvad < swM_temp)) + swComp = 1; + + + /*** compute minimum(thvad+(thvad/inc), pvad*fac) when comp = 1 ***/ + + if (swComp == 1) + { + + /*** compute thvad + (thvad/inc) ***/ + + L_temp = L_add(L_deposit_l(*pswM_thvad),L_deposit_l(shr(*pswM_thvad, 4))); + + if (L_temp > 0x7fffL) + { + *pswM_thvad = extract_l(L_shr(L_temp, 1)); + *pswE_thvad = add(*pswE_thvad, 1); + } + else + *pswM_thvad = extract_l(L_temp); + + swComp2 = 0; + + if (swE_temp < *pswE_thvad) + swComp2 = 1; + + if ((swE_temp == *pswE_thvad) && (swM_temp < *pswM_thvad)) + swComp2 = 1; + + if (swComp2 == 1) + { + *pswE_thvad = swE_temp; + *pswM_thvad = swM_temp; + } + } + + + /*** compute pvad + margin ***/ + + if (swE_pvad == E_MARGIN) + { + L_temp = L_add(L_deposit_l(swM_pvad), L_deposit_l(M_MARGIN)); + swM_temp = extract_l(L_shr(L_temp, 1)); + swE_temp = add(swE_pvad, 1); + } + else + { + if (swE_pvad > E_MARGIN) + { + swTemp = sub(swE_pvad, E_MARGIN); + swTemp = shr(M_MARGIN, swTemp); + L_temp = L_add(L_deposit_l(swM_pvad), L_deposit_l(swTemp)); + + if (L_temp > 0x7fffL) + { + swE_temp = add(swE_pvad, 1); + swM_temp = extract_l(L_shr(L_temp, 1)); + } + else + { + swE_temp = swE_pvad; + swM_temp = extract_l(L_temp); + } + } + else + { + swTemp = sub(E_MARGIN, swE_pvad); + swTemp = shr(swM_pvad, swTemp); + L_temp = L_add(L_deposit_l(M_MARGIN), L_deposit_l(swTemp)); + + if (L_temp > 0x7fffL) + { + swE_temp = add(E_MARGIN, 1); + swM_temp = extract_l(L_shr(L_temp, 1)); + } + else + { + swE_temp = E_MARGIN; + swM_temp = extract_l(L_temp); + } + } + } + + /*** Test if thvad > pvad + margin ***/ + + swComp = 0; + + if (*pswE_thvad > swE_temp) + swComp = 1; + + if ((*pswE_thvad == swE_temp) && (*pswM_thvad > swM_temp)) + swComp = 1; + + if (swComp == 1) + { + *pswE_thvad = swE_temp; + *pswM_thvad = swM_temp; + } + + /*** Normalise and retain rvad[0..8] in memory ***/ + + *pswNormRvad = swNormRav1; + + for (i = 0; i <= 8; i++) + pswRvad[i] = pswRav1[i]; + + /*** Set adaptcount to adp + 1 ***/ + + swAdaptCount = 9; + +} + +/**************************************************************************** + * + * FUNCTION: vad_decision + * + * VERSION: 1.2 + * + * PURPOSE: Computes the VAD decision based on the comparison of the + * floating point representations of pvad and thvad. + * + * INPUTS: swM_pvad mantissa of filtered signal energy + * swE_pvad exponent of filtered signal energy + * swM_thvad mantissa of decision threshold + * swE_thvad exponent of decision threshold + * + * OUTPUTS: pswVvad vad decision before hangover is added + * + ***************************************************************************/ + +void GsmHrVad::vad_decision(int16_t swM_pvad, + int16_t swE_pvad, + int16_t swM_thvad, + int16_t swE_thvad, + int16_t *pswVvad) +{ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + *pswVvad = 0; + + if (swE_pvad > swE_thvad) + *pswVvad = 1; + if ((swE_pvad == swE_thvad) && (swM_pvad > swM_thvad)) + *pswVvad = 1; + +} + +/**************************************************************************** + * + * FUNCTION: vad_hangover + * + * VERSION: 1.2 + * + * PURPOSE: Computes the final VAD decision for the current frame + * being processed. + * + * INPUTS: swVvad vad decision before hangover is added + * + * OUTPUTS: pswVadFlag vad decision after hangover is added + * + ***************************************************************************/ + +void vad_hangover(int16_t swVvad, + int16_t *pswVadFlag) +{ + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + if (swVvad == 1) + swBurstCount = add(swBurstCount, 1); + else + swBurstCount = 0; + + if (swBurstCount >= 3) + { + swHangCount = 5; + swBurstCount = 3; + } + + *pswVadFlag = swVvad; + + if (swHangCount >= 0) + { + *pswVadFlag = 1; + swHangCount = sub(swHangCount, 1); + } + +} + +/**************************************************************************** + * + * FUNCTION: periodicity_update + * + * VERSION: 1.2 + * + * PURPOSE: Computes the ptch flag needed for the threshold + * adaptation decision for the next frame. + * + * INPUTS: pswLags[0..3] speech encoder long term predictor lags + * + * OUTPUTS: pswPtch Boolean voiced / unvoiced decision + * + ***************************************************************************/ + +void GsmHrVad::periodicity_update(int16_t pswLags[4], + int16_t *pswPtch) +{ + +/*_________________________________________________________________________ + | | + | Automatic Variables | + |_________________________________________________________________________| +*/ + + int16_t + swMinLag, + swMaxLag, + swSmallLag, + swLagCount, + swTemp; + + int + i, + j; + +/*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| +*/ + + /*** Run loop for No. of sub-segments in the frame ***/ + + swLagCount = 0; + + for (i = 0; i <= 3; i++) + { + /*** Search the maximum and minimum of consecutive lags ***/ + + if (swOldLag > pswLags[i]) + { + swMinLag = pswLags[i]; + swMaxLag = swOldLag; + } + else + { + swMinLag = swOldLag; + swMaxLag = pswLags[i]; + } + + + /*** Compute smallag (modulo operation not defined) ***/ + + swSmallLag = swMaxLag; + + for (j = 0; j <= 2; j++) + { + if (swSmallLag >= swMinLag) + swSmallLag = sub(swSmallLag, swMinLag); + } + + + /*** Minimum of smallag and minlag - smallag ***/ + + swTemp = sub(swMinLag, swSmallLag); + + if (swTemp < swSmallLag) + swSmallLag = swTemp; + + if (swSmallLag < 2) + swLagCount = add(swLagCount, 1); + + + /*** Save the current LTP lag ***/ + + swOldLag = pswLags[i]; + } + + + /*** Update the veryoldlagcount and oldlagcount ***/ + + swVeryOldLagCount = swOldLagCount; + swOldLagCount = swLagCount; + + + /*** Make ptch decision ready for next frame ***/ + + swTemp = add(swOldLagCount, swVeryOldLagCount); + + if (swTemp >= 7) + *pswPtch = 1; + else + *pswPtch = 0; + +} diff --git a/src/libs/gsmhr/gsmhr_vad.h b/src/libs/gsmhr/gsmhr_vad.h new file mode 100644 index 00000000..851684e6 --- /dev/null +++ b/src/libs/gsmhr/gsmhr_vad.h @@ -0,0 +1,125 @@ +#ifndef __VAD +#define __VAD + +#include "typedefs.h" + + +/*_________________________________________________________________________ + | | + | Function Prototypes | + |_________________________________________________________________________| +*/ + +void vad_reset(void); + +void vad_algorithm + ( + int32_t pL_acf[9], + int16_t swScaleAcf, + int16_t pswRc[4], + int16_t swPtch, + int16_t *pswVadFlag +); + +void energy_computation + ( + int32_t pL_acf[], + int16_t swScaleAcf, + int16_t pswRvad[], + int16_t swNormRvad, + int16_t *pswM_pvad, + int16_t *pswE_pvad, + int16_t *pswM_acf0, + int16_t *pswE_acf0 +); + + +void average_acf + ( + int32_t pL_acf[], + int16_t swScaleAcf, + int32_t pL_av0[], + int32_t pL_av1[] +); + +void predictor_values + ( + int32_t pL_av1[], + int16_t pswRav1[], + int16_t *pswNormRav1 +); + +void schur_recursion + ( + int32_t pL_av1[], + int16_t pswVpar[] +); + +void step_up + ( + int16_t swNp, + int16_t pswVpar[], + int16_t pswAav1[] +); + +void compute_rav1 + ( + int16_t pswAav1[], + int16_t pswRav1[], + int16_t *pswNormRav1 +); + +void spectral_comparison + ( + int16_t pswRav1[], + int16_t swNormRav1, + int32_t pL_av0[], + int16_t *pswStat +); + +void tone_detection + ( + int16_t pswRc[4], + int16_t *pswTone +); + + +void threshold_adaptation + ( + int16_t swStat, + int16_t swPtch, + int16_t swTone, + int16_t pswRav1[], + int16_t swNormRav1, + int16_t swM_pvad, + int16_t swE_pvad, + int16_t swM_acf0, + int16_t swE_acf0, + int16_t pswRvad[], + int16_t *pswNormRvad, + int16_t *pswM_thvad, + int16_t *pswE_thvad +); + +void vad_decision + ( + int16_t swM_pvad, + int16_t swE_pvad, + int16_t swM_thvad, + int16_t swE_thvad, + int16_t *pswVvad +); + +void vad_hangover + ( + int16_t swVvad, + int16_t *pswVadFlag +); + +void periodicity_update + ( + int16_t pswLags[4], + int16_t *pswPtch +); + +#endif diff --git a/src/libs/ice/CMakeLists.txt b/src/libs/ice/CMakeLists.txt new file mode 100644 index 00000000..462db4e7 --- /dev/null +++ b/src/libs/ice/CMakeLists.txt @@ -0,0 +1,35 @@ +project (ice_stack) + +# Rely on C++ 11 +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +set (ICE_STACK_SOURCES ICEAddress.cpp + ICEAuthTransaction.cpp + ICEBinding.cpp + ICEBox.cpp + ICEBoxImpl.cpp + ICEByteBuffer.cpp + ICECandidate.cpp + ICECandidatePair.cpp + ICECheckList.cpp + ICECRC32.cpp + ICEError.cpp + ICELog.cpp + ICEMD5.cpp + ICENetworkHelper.cpp + ICEPacketTimer.cpp + ICEPlatform.cpp + ICERelaying.cpp + ICESession.cpp + ICESHA1.cpp + ICEStream.cpp + ICEStunAttributes.cpp + ICEStunConfig.cpp + ICEStunMessage.cpp + ICEStunTransaction.cpp + ICESync.cpp + ICETime.cpp + ICETransactionList.cpp) + +add_library(ice_stack ${ICE_STACK_SOURCES}) diff --git a/src/libs/ice/ICEAction.h b/src/libs/ice/ICEAction.h new file mode 100644 index 00000000..f488cc61 --- /dev/null +++ b/src/libs/ice/ICEAction.h @@ -0,0 +1,42 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_ACTION__H +#define __ICE_ACTION__H + +#include "ICESmartPtr.h" +#include "ICECandidatePair.h" + +namespace ice +{ + class Transaction; + struct Stream; + class Logger; + struct StackConfig; + + class Action + { + protected: + Stream& mStream; + StackConfig& mConfig; + + public: + Action(Stream& stream, StackConfig& config) + :mStream(stream), mConfig(config) + { + } + + virtual ~Action() + { + } + + virtual void finished(Transaction& transaction) = 0; + }; + + typedef SmartPtr PAction; + +} + +#endif \ No newline at end of file diff --git a/src/libs/ice/ICEAddress.cpp b/src/libs/ice/ICEAddress.cpp new file mode 100644 index 00000000..499f44e3 --- /dev/null +++ b/src/libs/ice/ICEAddress.cpp @@ -0,0 +1,782 @@ +/* Copyright(C) 2007-2018 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#if defined(__MINGW32__) +# include + +# define WINVER WindowsVista +# define _WIN32_WINDOWS WindowsVista +# define _WIN32_WINNT WindowsVista +#endif + +#include "ICEPlatform.h" +#include "ICEAddress.h" +#include "ICEError.h" +#include +#include + +#if defined(TARGET_WIN) +# include +# include +# include +#else +# include +# if defined(TARGET_LINUX) || defined(TARGET_ANDROID) +# include +# endif +#endif + +std::ostream& operator << (std::ostream& s, const ice::NetworkAddress& addr) +{ + s << addr.toStdString().c_str(); + return s; +} + +#ifdef TARGET_WIN +std::wostream& operator << (std::wostream& s, const ice::NetworkAddress& addr) +{ + s << addr.toStdWString(); + return s; +} +#endif + +using namespace ice; + +NetworkAddress NetworkAddress::LoopbackAddress4("127.0.0.1", 1000); +#ifdef TARGET_WIN +static in_addr6 la6 = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1 }; +#else +static in6_addr la6 = { { { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1 } } }; +#endif +NetworkAddress NetworkAddress::LoopbackAddress6(la6, 1000); + + +NetworkAddress NetworkAddress::parse(const std::string& s) +{ + NetworkAddress result; + result.mInitialized = !s.empty(); + if (result.mInitialized) + { + // Relayed or not + result.mRelayed = s.find("relayed ") != std::string::npos; + std::string::size_type ip4Pos = s.find("IPv4"), ip6Pos = s.find("IPv6"); + + if (ip4Pos == std::string::npos && ip6Pos == std::string::npos) + { + // Parse usual IP[:port] pair + std::string::size_type cp = s.find(":"); + if (cp == std::string::npos) + result.setIp(cp); + else + { + result.setIp(s.substr(0, cp)); + result.setPort(atoi(s.substr(cp + 1).c_str())); + } + } + else + { + // Family + result.mAddr4.sin_family = ip4Pos != std::string::npos ? AF_INET : AF_INET6; + + // IP:port + std::string::size_type familyPos = ip4Pos != std::string::npos ? ip4Pos : ip6Pos; + std::string addr = s.substr(familyPos + 5); + + // Find IP substring and port + std::string::size_type colonPos = addr.find_last_of(":"); + if (colonPos != std::string::npos) + { + int port = atoi(addr.substr(colonPos+1).c_str()); + result.setPort(port); + result.setIp(addr.substr(0, colonPos)); + } + } + } + return result; +} + +// NetworkAddress NetworkAddress::LoopbackAddress6("0:0:0:0:0:0:0:1", 1000); + +NetworkAddress::NetworkAddress() + :mInitialized(false), mRelayed(false) +{ + memset(&mAddr6, 0, sizeof(mAddr6)); + mAddr4.sin_family = AF_INET; +} + +NetworkAddress::NetworkAddress(int stunType) + :mInitialized(false), mRelayed(false) +{ + memset(&mAddr6, 0, sizeof(mAddr6)); + setStunType(stunType); +} + +NetworkAddress::NetworkAddress(const in6_addr& addr6, unsigned short port) +:mInitialized(true), mRelayed(false) +{ + memset(&mAddr6, 0, sizeof(mAddr6)); + mAddr4.sin_family = AF_INET6; + mAddr6.sin6_addr = addr6; + mAddr6.sin6_port = htons(port); +} + +NetworkAddress::NetworkAddress(const in_addr& addr4, unsigned short port) +:mInitialized(true), mRelayed(false) +{ + memset(&mAddr6, 0, sizeof(mAddr6)); + mAddr4.sin_family = AF_INET; + mAddr4.sin_addr = addr4; + mAddr4.sin_port = htons(port); +} + +unsigned char NetworkAddress::stunType() const +{ + assert(mInitialized); + switch (mAddr4.sin_family) + { + case AF_INET: + return 1; + + case AF_INET6: + return 2; + + default: + assert(0); + } + return -1; +} + +void NetworkAddress::setStunType(unsigned char st) +{ + switch (st) + { + case 1: + mAddr4.sin_family = AF_INET; + break; + + case 2: + mAddr6.sin6_family = AF_INET6; + break; + + default: + assert(0); + } +} + +NetworkAddress::NetworkAddress(const std::string& ip, unsigned short port) +:mInitialized(true), mRelayed(false) +{ + memset(&mAddr6, 0, sizeof(mAddr6)); + setIp(ip); + if (mAddr4.sin_family == AF_INET || mAddr4.sin_family == AF_INET6) + setPort(port); +} + +NetworkAddress::NetworkAddress(const char *ip, unsigned short port) + :mInitialized(true), mRelayed(false) +{ + memset(&mAddr6, 0, sizeof(mAddr6)); + setIp(ip); + if (mAddr4.sin_family == AF_INET || mAddr4.sin_family == AF_INET6) + setPort(port); +} + +NetworkAddress::NetworkAddress(const sockaddr& addr, unsigned addrLen) +:mInitialized(true), mRelayed(false) +{ + switch (addr.sa_family) + { + case AF_INET6: + memset(&mAddr6, 0, sizeof(mAddr6)); + memcpy(&mAddr6, &addr, addrLen); + break; + + case AF_INET: + memset(&mAddr4, 0, sizeof(mAddr4)); + memcpy(&mAddr4, &addr, addrLen); + break; + } +} + +NetworkAddress::NetworkAddress(const NetworkAddress& src) +:mInitialized(src.mInitialized), mRelayed(src.mRelayed) +{ + memset(&mAddr6, 0, sizeof(mAddr6)); + if (src.mAddr4.sin_family == AF_INET) + memcpy(&mAddr4, &src.mAddr4, sizeof mAddr4); + else + memcpy(&mAddr6, &src.mAddr6, sizeof mAddr6); +} + +NetworkAddress::~NetworkAddress() +{ +} + +int NetworkAddress::family() const +{ + assert(mInitialized == true); + + return this->mAddr4.sin_family; +} + +sockaddr* NetworkAddress::genericsockaddr() const +{ + assert(mInitialized == true); + switch (mAddr4.sin_family) + { + case AF_INET: + return (sockaddr*)&mAddr4; + + case AF_INET6: + return (sockaddr*)&mAddr6; + + default: + assert(0); + } + return NULL; +} + +unsigned NetworkAddress::sockaddrLen() const +{ + assert(mInitialized == true); + switch (mAddr4.sin_family) + { + case AF_INET: + return sizeof(mAddr4); + + case AF_INET6: + return sizeof(mAddr6); + + default: + assert(0); + } + return 0; +} + +sockaddr_in* NetworkAddress::sockaddr4() const +{ + assert(mInitialized == true); + switch (mAddr4.sin_family) + { + case AF_INET: + return (sockaddr_in*)&mAddr4; + + default: + assert(0); + } + return NULL; +} + +sockaddr_in6* NetworkAddress::sockaddr6() const +{ + assert(mInitialized == true); + switch (mAddr4.sin_family) + { + case AF_INET6: + return (sockaddr_in6*)&mAddr6; + + default: + assert(0); + } + return NULL; +} + +void NetworkAddress::setIp(NetworkAddress ipOnly) +{ + // Save port + mAddr4.sin_family = ipOnly.genericsockaddr()->sa_family; + + switch (ipOnly.family()) + { + case AF_INET: + memcpy(&mAddr4.sin_addr, &ipOnly.sockaddr4()->sin_addr, 4); + break; + + case AF_INET6: + memcpy(&mAddr4.sin_addr, &ipOnly.sockaddr6()->sin6_addr, 16); + break; + + default: + assert(0); + } +} + +void NetworkAddress::setIp(const std::string& ip) +{ +#ifdef TARGET_WIN + int addrSize = sizeof(mAddr6); +#endif + + if (inet_addr(ip.c_str()) != INADDR_NONE) + { + mAddr4.sin_family = AF_INET; + mAddr4.sin_addr.s_addr = inet_addr(ip.c_str()); + if (mAddr4.sin_port) + mInitialized = true; + } + else + { + mAddr6.sin6_family = AF_INET6; +#ifdef TARGET_WIN + if (WSAStringToAddressA((char*)ip.c_str(), AF_INET6, NULL, (sockaddr*)&mAddr6, &addrSize) != 0) +#else + std::string ip2; + if (ip.find('[') == 0 && ip.find(']') == ip.length()-1) + ip2 = ip.substr(1, ip.length()-2); + else + ip2 = ip; + + if (!inet_pton(AF_INET6, ip2.c_str(), &mAddr6.sin6_addr)) +#endif + { + mInitialized = false; + return; + } + + mAddr6.sin6_family = AF_INET6; + if (mAddr6.sin6_port) + mInitialized = true; + } + +} + +void NetworkAddress::setIp(unsigned long ip) +{ + mAddr4.sin_family = AF_INET; + mAddr4.sin_addr.s_addr = ip; + + if (mAddr4.sin_port) + mInitialized = true; +} + +void NetworkAddress::setIp(const in_addr& ip) +{ + //memset(&mAddr4, 0, sizeof mAddr4); + mAddr4.sin_family = AF_INET; + mAddr4.sin_addr = ip; +} + +void NetworkAddress::setIp(const in6_addr& ip) +{ + mAddr6.sin6_family = AF_INET6; + mAddr6.sin6_addr = ip; +} +// 10.0.0.0 - 10.255.255.255 +// 172.16.0.0 - 172.31.255.255 +// 192.168.0.0 - 192.168.255.255 + +bool NetworkAddress::isSameLAN(const NetworkAddress& a1, const NetworkAddress& a2) +{ + if (a1.family() != a2.family()) + return false; + if (a1.family() == AF_INET) + { + sockaddr_in* s1 = a1.sockaddr4(); + sockaddr_in* s2 = a2.sockaddr4(); +#ifdef TARGET_WIN + unsigned b1_0 = (s1->sin_addr.S_un.S_addr >> 0) & 0xFF; + unsigned b1_1 = (s1->sin_addr.S_un.S_addr >> 8) & 0xFF; + unsigned b2_0 = (s2->sin_addr.S_un.S_addr >> 0) & 0xFF; + unsigned b2_1 = (s2->sin_addr.S_un.S_addr >> 8) & 0xFF; +#else + unsigned b1_0 = (s1->sin_addr.s_addr >> 0) & 0xFF; + unsigned b1_1 = (s1->sin_addr.s_addr >> 8) & 0xFF; + unsigned b2_0 = (s2->sin_addr.s_addr >> 0) & 0xFF; + unsigned b2_1 = (s2->sin_addr.s_addr >> 8) & 0xFF; + + if (b1_0 == b2_0 && b1_0 == 192 && + b1_1 == b2_1 && b1_1 == 168) + return true; + + if (b1_0 == b2_0 && b1_0 == 10) + return true; + + if (b1_0 == b2_0 && b1_0 == 172 && + b1_1 == b2_1 && (b1_1 < 32)) + return true; + +#endif + } + return false; +} + +void NetworkAddress::setPort(unsigned short port) +{ + switch(mAddr4.sin_family) + { + case AF_INET: + mAddr4.sin_port = htons(port); + mInitialized = true; + break; + + case AF_INET6: + mAddr6.sin6_port = htons(port); + mInitialized = true; + break; + + default: + assert(0); + } +} + +std::string NetworkAddress::ip() const +{ + assert(mInitialized == true); + + char resultbuf[128], ip6[128]; resultbuf[0] = 0; + +#ifdef TARGET_WIN + DWORD resultsize = sizeof(resultbuf); +#endif + + switch (mAddr4.sin_family) + { + case AF_INET: + return inet_ntoa(mAddr4.sin_addr); + + case AF_INET6: +#if defined(TARGET_WIN) + InetNtopA(AF_INET6, (PVOID)&mAddr6.sin6_addr, resultbuf, sizeof(resultbuf)); +#else + inet_ntop(AF_INET6, &mAddr6.sin6_addr, resultbuf, sizeof(resultbuf)); +#endif + sprintf(ip6, "[%s]", resultbuf); + return ip6; + + default: + return ""; + } + return ""; +} + +unsigned char* NetworkAddress::ipBytes() const +{ + switch (family()) + { + case AF_INET: +#ifdef TARGET_WIN + return (unsigned char*)&mAddr4.sin_addr.S_un.S_un_b; +#else + return (unsigned char*)&mAddr4.sin_addr.s_addr; +#endif + case AF_INET6: +#ifdef TARGET_WIN + return (unsigned char*)mAddr6.sin6_addr.u.Byte; +#elif defined(TARGET_OSX) || defined(TARGET_IOS) + return (unsigned char*)&mAddr6.sin6_addr.__u6_addr.__u6_addr8; +#elif defined(TARGET_LINUX) + return (unsigned char*)&mAddr6.sin6_addr.__in6_u.__u6_addr8; +#elif defined(TARGET_ANDROID) + return (unsigned char*)&mAddr6.sin6_addr.in6_u.u6_addr8; +#endif + } + assert(0); + return nullptr; // to avoid compiler warning +} + +unsigned short NetworkAddress::port() const +{ + assert(mInitialized == true); + + return ntohs(mAddr4.sin_port); +} + +std::string NetworkAddress::toStdString() const +{ + if (!mInitialized) + return ""; + + char temp[128]; + sprintf(temp, "%s%s %s:%u", mRelayed ? "relayed " : "", this->mAddr4.sin_family == AF_INET ? "IPv4" : "IPv6", ip().c_str(), (unsigned int)port()); + + return temp; +} +#ifdef WIN32 +std::wstring NetworkAddress::toStdWString() const +{ + if (!mInitialized) + return L""; + + wchar_t temp[128]; + swprintf(temp, L"%s%s %S:%u", mRelayed ? L"relayed " : L"", this->mAddr4.sin_family == AF_INET ? L"IPv4" : L"IPv6", ip().c_str(), (unsigned int)port()); + + return temp; +} +#endif + +static const unsigned char localhost6[] = + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + +bool NetworkAddress::isLoopback() const +{ + switch (mAddr4.sin_family) + { + case AF_INET: + return (mAddr4.sin_addr.s_addr == htonl(INADDR_LOOPBACK)); + + case AF_INET6: + return memcmp(localhost6, &mAddr6.sin6_addr, sizeof mAddr6.sin6_addr) == 0; + + default: + assert(0); + } + return false; +} + +bool NetworkAddress::isIp(const std::string& str) +{ + if (inet_addr(str.c_str()) != INADDR_NONE) + return true; + const char* address = str.c_str(); + std::string temp; + if (str.find('[') == 0 && str.find(']') == str.length()-1) + { + temp = str.substr(1, str.length()-2); + address = temp.c_str(); + } + sockaddr_in6 addr6; + addr6.sin6_family = AF_INET6; + +#ifdef _WIN32 + int addrSize = sizeof(addr6); + if (WSAStringToAddressA((char*)address, AF_INET6, NULL, (sockaddr*)&addr6, &addrSize) != 0) +#else + if (!inet_pton(AF_INET6, address, &addr6)) +#endif + return false; + return true; +} + +bool NetworkAddress::isLAN() const +{ + assert(mInitialized); + + switch (mAddr4.sin_family) + { + case AF_INET: + { + unsigned char b1 = mAddr4.sin_addr.s_addr & 0xFF; + unsigned char b2 = (mAddr4.sin_addr.s_addr >> 8) & 0xFF; + if (b1 == 192 && b2 == 168) + return true; + if (b1 == 10) + return true; + if (b1 == 172 && (b2 >= 16 && b2 <= 31)) + return true; + + // Link local addresses are not routable so report them here + if (b1 == 169 && b2 == 254) + return true; + + return false; + + } + + case AF_INET6: + return false; + + default: + assert(0); + } + return false; +} + +bool NetworkAddress::isLinkLocal() const +{ + assert(mInitialized); + + switch (mAddr4.sin_family) + { + case AF_INET: + { + unsigned char b1 = mAddr4.sin_addr.s_addr & 0xFF; + unsigned char b2 = (mAddr4.sin_addr.s_addr >> 8) & 0xFF; + + // Link local addresses are not routable so report them here + if (b1 == 169 && b2 == 254) + return true; + + //if (b1 == 100 && (b2 >= 64 && b2 <= 127)) + // return true; + + return false; + + } + + case AF_INET6: +#ifdef WIN32 + return (mAddr6.sin6_addr.u.Byte[0] == 0xFE && mAddr6.sin6_addr.u.Byte[1] == 0x80); +#else + return IN6_IS_ADDR_LINKLOCAL(&mAddr6.sin6_addr); +#endif + default: + assert(0); + } + return false; +} + +void NetworkAddress::clear() +{ + memset(&mAddr6, 0, sizeof(mAddr6)); + mInitialized = false; +} + +bool NetworkAddress::isEmpty() const +{ + return !mInitialized; +} + +bool NetworkAddress::isZero() const +{ + if (!mInitialized) + return false; + switch (mAddr4.sin_family) + { + case AF_INET: + return mAddr4.sin_addr.s_addr == 0; + + case AF_INET6: +#ifdef WIN32 + return !mAddr6.sin6_addr.u.Word[0] && !mAddr6.sin6_addr.u.Word[1] && + !mAddr6.sin6_addr.u.Word[2] && !mAddr6.sin6_addr.u.Word[3] && + !mAddr6.sin6_addr.u.Word[4] && !mAddr6.sin6_addr.u.Word[5] && + !mAddr6.sin6_addr.u.Word[6] && !mAddr6.sin6_addr.u.Word[7]; +#else + return IN6_IS_ADDR_UNSPECIFIED(&mAddr6.sin6_addr); +#endif + } + return false; +} + +bool NetworkAddress::isV4() const +{ + return family() == AF_INET; +} + +bool NetworkAddress::isV6() const +{ + return family() == AF_INET6; +} + +bool NetworkAddress::operator == (const NetworkAddress& rhs) const +{ + return NetworkAddress::isSame(*this, rhs); +} + +bool NetworkAddress::operator != (const NetworkAddress& rhs) const +{ + return !NetworkAddress::isSame(*this, rhs); +} + +bool NetworkAddress::operator < (const NetworkAddress& rhs) const +{ + if (family() != rhs.family()) + return family() < rhs.family(); + + if (port() != rhs.port()) + return port() < rhs.port(); + + switch (family()) + { + case AF_INET: + return memcmp(sockaddr4(), rhs.sockaddr4(), sizeof(sockaddr_in)) < 0; + + case AF_INET6: + return memcmp(sockaddr6(), rhs.sockaddr6(), sizeof(sockaddr_in6)) < 0; + } + + return false; +} + +bool NetworkAddress::operator > (const NetworkAddress& rhs) const +{ + if (family() != rhs.family()) + return family() > rhs.family(); + + if (port() != rhs.port()) + return port() > rhs.port(); + + switch (family()) + { + case AF_INET: + return memcmp(sockaddr4(), rhs.sockaddr4(), sizeof(sockaddr_in)) > 0; + + case AF_INET6: + return memcmp(sockaddr6(), rhs.sockaddr6(), sizeof(sockaddr_in6)) > 0; + } + + return false; +} + +bool NetworkAddress::isPublic() const +{ + return !isLAN() && !isLinkLocal() && !isLoopback() && !isEmpty(); +} + +void NetworkAddress::setRelayed(bool relayed) +{ + mRelayed = relayed; +} +bool NetworkAddress::relayed() const +{ + return mRelayed; +} + +bool NetworkAddress::hasHost(const std::vector& hosts) +{ + for (unsigned i=0; i +#include +#include + +namespace ice +{ + class NetworkAddress + { + public: + static NetworkAddress LoopbackAddress4; + static NetworkAddress LoopbackAddress6; + static bool isSameLAN(const NetworkAddress& a1, const NetworkAddress& a2); + static bool isIp(const std::string& str); + static NetworkAddress parse(const std::string& s); + + NetworkAddress(); + NetworkAddress(int stunType); + NetworkAddress(const std::string& ip, unsigned short port); + NetworkAddress(const char* ip, unsigned short port); + NetworkAddress(const in6_addr& ip, unsigned short port); + NetworkAddress(const in_addr& ip, unsigned short port); + NetworkAddress(const sockaddr& addr, unsigned addrLen); + NetworkAddress(const NetworkAddress& src); + ~NetworkAddress(); + + // Returns AF_INET or AF_INET6 + int family() const; + + unsigned char stunType() const; + void setStunType(unsigned char st); + + sockaddr* genericsockaddr() const; + sockaddr_in* sockaddr4() const; + sockaddr_in6* sockaddr6() const; + unsigned sockaddrLen() const; + void setIp(const std::string& ip); + void setIp(unsigned long ip); + void setIp(const in_addr& ip); + void setIp(const in6_addr& ip); + void setIp(NetworkAddress ipOnly); + + void setPort(unsigned short port); + std::string ip() const; + unsigned char* ipBytes() const; + + unsigned short port() const; + std::string toStdString() const; +#ifdef WIN32 + std::wstring toStdWString() const; +#endif + bool isLoopback() const; + bool isLAN() const; + bool isLinkLocal() const; + bool isPublic() const; + bool isEmpty() const; + bool isZero() const; + bool isV4() const; + bool isV6() const; + + void clear(); + + void setRelayed(bool relayed); + bool relayed() const; + bool hasHost(const std::vector& hosts); + + static bool isSameHost(const NetworkAddress& a1, const NetworkAddress& a2); + + static bool isSame(const NetworkAddress& a1, const NetworkAddress& a2); + + bool operator == (const NetworkAddress& rhs) const; + bool operator != (const NetworkAddress& rhs) const; + bool operator < (const NetworkAddress& rhs) const; + bool operator > (const NetworkAddress& rhs) const; + protected: + union + { + sockaddr_in6 mAddr6; + sockaddr_in mAddr4; + }; + bool mRelayed; + bool mInitialized; + }; + +} + +std::ostream& operator << (std::ostream& s, const ice::NetworkAddress& addr); +#ifdef WIN32 +std::wostream& operator << (std::wostream& s, const ice::NetworkAddress& addr); +#endif + +#endif diff --git a/src/libs/ice/ICEAuthTransaction.cpp b/src/libs/ice/ICEAuthTransaction.cpp new file mode 100644 index 00000000..8c002405 --- /dev/null +++ b/src/libs/ice/ICEAuthTransaction.cpp @@ -0,0 +1,251 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEAuthTransaction.h" +#include "ICEStunAttributes.h" +#include "ICEMD5.h" +#include "ICELog.h" + +using namespace ice; + +#define LOG_SUBSYSTEM "ICE" + +AuthTransaction::AuthTransaction() +:Transaction(), mActive(false), mComposed(false), mConformsToKeepaliveSchedule(true), +mCredentialsEncoded(false) +{ +} + +AuthTransaction::~AuthTransaction() +{ +} + +void AuthTransaction::init() +{ + mConformsToKeepaliveSchedule = false; + if (mRealm.size() && mNonce.size()) + buildAuthenticatedMsg(); + else + { + SmartPtr msg(new StunMessage()); + msg->setTransactionId(mTransactionID); + setInitialRequest(*msg); + mComposed = false; + mOutgoingMsgQueue.push_back(msg); + } +} + +void AuthTransaction::buildAuthenticatedMsg() +{ + // Setup key for MessageIntegrity + std::string key = mUsername + ":" + mRealm + ":" + mPassword; + md5Bin(key.c_str(), key.size(), mKey); + + // Create new authenticated message + SmartPtr newMsg( new StunMessage() ); + + // Optional - generate new transaction ID + // mTransactionID = StunMessage::TransactionID::GenerateNew(); + + newMsg->setTransactionId( mTransactionID ); + + // Add USERNAME + newMsg->usernameAttr().setValue( mUsername ); + newMsg->realmAttr().setValue( mRealm ); + newMsg->nonceAttr().setValue( mNonce ); + + // Adjust message + setAuthenticatedRequest( *newMsg ); + + // Ensure MessageIntegrity exists + newMsg->messageIntegrityAttr().setValue( NULL ); + + // Enqueue msg + mComposed = false; + + mOutgoingMsgQueue.clear(); + mOutgoingMsgQueue.push_back( newMsg ); +} + +bool AuthTransaction::processData(StunMessage& msg, NetworkAddress& address) +{ + if (msg.transactionId() != mTransactionID) + return false; + + // Check for 401 error code + if (msg.hasAttribute(StunAttribute::ErrorCode)) + { + ErrorCode& ec = msg.errorCodeAttr(); + + // Get realm value - it must be long term credentials + if (ec.errorCode() == 401 && (!mCredentialsEncoded || !mLongTerm)) + { + if (!msg.hasAttribute(StunAttribute::Realm) || !msg.hasAttribute(StunAttribute::Nonce)) + return false; + + Realm& realm = msg.realmAttr(); + + // Extract realm and nonce + mRealm = realm.value(); + mNonce = msg.nonceAttr().value(); + + // Change transaction id + if (mLongTerm) + { + mCredentialsEncoded = true; + generateId(); + } + ICELogDebug(<< "Server requested long term credentials for realm " << mRealm); + buildAuthenticatedMsg(); + } + else + if (ec.errorCode() == 438 && (msg.hasAttribute(StunAttribute::Realm) || msg.hasAttribute(StunAttribute::Nonce))) + { + if (msg.hasAttribute(StunAttribute::Realm)) + mRealm = msg.realmAttr().value(); + if (msg.hasAttribute(StunAttribute::Nonce)) + mNonce = msg.nonceAttr().value(); + + ICELogDebug(<< "Returned error 438, using new nonce"); + if (msg.hasAttribute(StunAttribute::Realm) && msg.hasAttribute(StunAttribute::Nonce)) + { + if (mLongTerm) + { + mCredentialsEncoded = true; + generateId(); + } + } + buildAuthenticatedMsg(); + } + else + { + mErrorCode = ec.errorCode(); + mErrorResponse = ec.errorPhrase(); + mState = Transaction::Failed; + processError(); + + ICELogCritical(<<"Stack ID " << mStackID << ". Got error code " << mErrorCode << " for STUN transaction. Error message: " << ec.errorPhrase()); + } + } + else + if (msg.messageClass() == StunMessage::ErrorClass) + { + mErrorCode = 0; + mState = Transaction::Failed; + processError(); + ICELogCritical(<<"Stack ID " << mStackID << ". Got ErrorClass response."); + } + else + { + ICELogDebug(<< "Process STUN success message"); + processSuccessMessage(msg, address); + mState = Transaction::Success; + } + + return true; +} + +ByteBuffer* AuthTransaction::generateData(bool force) +{ + if (!mActive) + { + init(); + mActive = true; + } + + if (!mComposed) + { + // Restart retransmission timer as new message will be built + mRTOTimer.stop(); + mRTOTimer.start(); + + // Get message from outgoing queue + if (!mOutgoingMsgQueue.empty()) + { + // Clear buffer for raw data + mOutgoingData.clear(); + + // Encode next message + StunMessage& msg = *mOutgoingMsgQueue.front(); + + //ICELogDebug(<< "Stack ID " << mStackID << ". Build message " << msg.GetTransactionID().ToString() << " from transaction " << this->GetComment()); + + if (mShortTerm) + msg.buildPacket(mOutgoingData, mPassword); + else + msg.buildPacket(mOutgoingData, std::string((char*)mKey, 16)); + + // Remove encoded message from msg queue + mOutgoingMsgQueue.pop_front(); + } + else + ICELogDebug(<< "No outgoing message in queue"); + + mComposed = true; + } + + return Transaction::generateData(force); +} + +int AuthTransaction::errorCode() +{ + return mErrorCode; +} + +std::string AuthTransaction::errorResponse() +{ + return mErrorResponse; +} + +void AuthTransaction::restart() +{ + // Clear outgoing data + mOutgoingData.clear(); + mOutgoingMsgQueue.clear(); + + mState = Transaction::Running; + + // Mark "message is not built yet" + mComposed = false; + + // Mark "first request is not sent yet" + mActive = false; + + // Reset retransmission timer + mRTOTimer.stop(); + mRTOTimer.start(); + mCredentialsEncoded = false; + mConformsToKeepaliveSchedule = true; +} + +bool AuthTransaction::hasToRunNow() +{ + bool result = Transaction::hasToRunNow(); + if (!result && keepalive()) + { + result |= mState == /*TransactionState::*/Running && !mConformsToKeepaliveSchedule; + } + return result; +} + +std::string AuthTransaction::realm() const +{ + return mRealm; +} + +void AuthTransaction::setRealm(std::string realm) +{ + mRealm = realm; +} + +std::string AuthTransaction::nonce() const +{ + return mNonce; +} + +void AuthTransaction::setNonce(std::string nonce) +{ + mNonce = nonce; +} diff --git a/src/libs/ice/ICEAuthTransaction.h b/src/libs/ice/ICEAuthTransaction.h new file mode 100644 index 00000000..a9778e27 --- /dev/null +++ b/src/libs/ice/ICEAuthTransaction.h @@ -0,0 +1,59 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __AUTH_TRANSACTION_H +#define __AUTH_TRANSACTION_H + +#include "ICEPlatform.h" +#include "ICEStunTransaction.h" + +namespace ice { + +class AuthTransaction: public Transaction +{ +public: + AuthTransaction(); + virtual ~AuthTransaction(); + + // Creates initial request, calls SetInitialRequest. This method is called once from GenerateData. + void init(); + + virtual void setInitialRequest(StunMessage& msg) = 0; + virtual void setAuthenticatedRequest(StunMessage& msg) = 0; + virtual void processSuccessMessage(StunMessage& msg, NetworkAddress& sourceAddress) = 0; + virtual void processError() {}; + + virtual bool processData(StunMessage& msg, NetworkAddress& address); + virtual ByteBuffer* generateData(bool force = false); + + int errorCode(); + std::string errorResponse(); + virtual void restart(); + virtual bool hasToRunNow(); + + std::string realm() const; + void setRealm(std::string realm); + + std::string nonce() const; + void setNonce(std::string nonce); + +protected: + bool mActive; + bool mComposed; + int mErrorCode; + std::string mErrorResponse; + std::deque > mOutgoingMsgQueue; + unsigned char mKey[16]; + bool mConformsToKeepaliveSchedule; + std::string mRealm; + std::string mNonce; + bool mCredentialsEncoded; + + void buildAuthenticatedMsg(); +}; + +} // end of namespace + +#endif \ No newline at end of file diff --git a/src/libs/ice/ICEBinding.cpp b/src/libs/ice/ICEBinding.cpp new file mode 100644 index 00000000..b4b64eb3 --- /dev/null +++ b/src/libs/ice/ICEBinding.cpp @@ -0,0 +1,520 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEBinding.h" +#include "ICEStunAttributes.h" +#include "ICETime.h" +#include "ICELog.h" +#include + +using namespace ice; +#define LOG_SUBSYSTEM "ICE" + +//----------------------- AuthClientBinding ----------------- + +ConnectivityCheck::ConnectivityCheck() +{ + setComment("ConnectivityCheck"); + mErrorCode = 0; +} + +ConnectivityCheck::~ConnectivityCheck() +{ +} + +ByteBuffer* ConnectivityCheck::generateData(bool force) +{ + if (!mComposed) + { + StunMessage msg; + msg.setMessageClass(StunMessage::RequestClass); + msg.setMessageType(StunMessage::Binding); + msg.setTransactionId(mTransactionID); + + if (mUseCandidate) + msg.setAttribute(new ICEUseCandidate()); + + // Use message integrity attribute + mMessageIntegrity = true; + + // Use fingerprint attribute + mFingerprint = true; + + if (mEnablePriority) + msg.icePriorityAttr().setPriority(mPriority); + + // Copy comment to message object + msg.setComment(mComment); + + enqueueMessage(msg); + + mComposed = true; + } + + return Transaction::generateData(force); +} + +void ConnectivityCheck::confirmTransaction(NetworkAddress& mapped) +{ + // Save resolved address&ip + mMappedAddress = mapped; + + // Mark transaction as succeeded + mState = Transaction::Success; + + // Save source IP and port + mResponseAddress = mapped; +} + +bool ConnectivityCheck::processData(StunMessage& msg, NetworkAddress& address) +{ +#ifdef ICE_TEST_VERYAGGRESSIVE + return false; +#endif + + // Check if it is response + if (msg.messageClass() != StunMessage::ErrorClass && + msg.messageClass() != StunMessage::SuccessClass) + return false; + + if (msg.transactionId() != mTransactionID) + return false; + + // Validate againgst password used to encrypt + if (!msg.validatePacket(mPassword)) + return false; + + // Check for ErrorCode attribute + if (msg.hasAttribute(StunAttribute::ErrorCode)) + { + ErrorCode& ec = dynamic_cast(msg.attribute(StunAttribute::ErrorCode)); + + //save error code and response + mErrorCode = ec.errorCode(); + mErrorResponse = ec.errorPhrase(); + + //mark transaction as failed + mState = Transaction::Failed; + + return true; + } + + //check if received empty ErrorClass response for poor servers + if (msg.messageClass() == StunMessage::ErrorClass) + { + //mark transaction as failed + mState = Transaction::Failed; + + return true; + } + + //check for mapped address attribute + if (msg.hasAttribute(StunAttribute::MappedAddress)) + { + // Save resolved address&ip + mMappedAddress = msg.mappedAddressAttr().address(); + + // Mark transaction as succeeded + mState = Transaction::Success; + + // Save source IP and port + mResponseAddress = address; + } + + //check for xor'ed mapped address attribute + if (msg.hasAttribute(StunAttribute::XorMappedAddress)) + { + // Save resolved IP and port + mMappedAddress = msg.xorMappedAddressAttr().address(); + + // Mark transaction as succeeded + mState = Transaction::Success; + + // Save source IP and port + mResponseAddress = address; + } + + return true; +} + +NetworkAddress& ConnectivityCheck::mappedAddress() +{ + return mMappedAddress; +} +NetworkAddress& ConnectivityCheck::responseAddress() +{ + return mResponseAddress; +} +void ConnectivityCheck::addUseCandidate() +{ + mUseCandidate = true; +} +int ConnectivityCheck::errorCode() +{ + return mErrorCode; +} +int ConnectivityCheck::resultError() +{ + return mErrorCode; +} +NetworkAddress& ConnectivityCheck::resultSource() +{ + return mResponseAddress; +} +Transaction::State ConnectivityCheck::resultState() +{ + return state(); +} +NetworkAddress& ConnectivityCheck::resultLocal() +{ + return mMappedAddress; +} +void ConnectivityCheck::useCandidate() +{ + addUseCandidate(); +} +unsigned ConnectivityCheck::resultPriority() +{ + return priorityValue(); +} +//---------------------------- ClientBindingTransaction ---------------------------- + +ClientBinding::ClientBinding() +:Transaction(), mErrorCode(0), mUseCandidate(false) +{ + setComment("ClientBinding"); +} + +ClientBinding::~ClientBinding() +{ +} + +int ClientBinding::errorCode() +{ + return mErrorCode; +} + +std::string ClientBinding::errorResponse() +{ + return mErrorResponse; +} + +NetworkAddress& ClientBinding::mappedAddress() +{ + return mMappedAddress; +} + +NetworkAddress& ClientBinding::responseAddress() +{ + return mResponseAddress; +} + +bool ClientBinding::processData(StunMessage& msg, NetworkAddress& address) +{ + // Check if it is response + if (msg.messageClass() != StunMessage::ErrorClass && + msg.messageClass() != StunMessage::SuccessClass) + return false; + + if (msg.transactionId() != this->mTransactionID) + return false; + + // Check for ErrorCode attribute + if (msg.hasAttribute(StunAttribute::ErrorCode)) + { + // Save error code and response + mErrorCode = msg.errorCodeAttr().errorCode(); + mErrorResponse = msg.errorCodeAttr().errorPhrase(); + + // Mark transaction as failed + mState = Transaction::Failed; + + return true; + } + + // Check if received empty ErrorClass response for poor servers + if (msg.messageClass() == StunMessage::ErrorClass) + { + // Mark transaction as failed + mState = Transaction::Failed; + + return true; + } + + // Check for mapped address attribute + if (msg.hasAttribute(StunAttribute::MappedAddress)) + { + // Save resolved address&ip + mMappedAddress = msg.mappedAddressAttr().address(); + + // mMark transaction as succeeded + mState = Transaction::Success; + + // Save source IP and port + mResponseAddress = address; + } + + //check for xor'ed mapped address attribute + if (msg.hasAttribute(StunAttribute::XorMappedAddress)) + { + // Save resolved IP and port + mMappedAddress = msg.xorMappedAddressAttr().address(); + + // Mark transaction as succeeded + mState = Transaction::Success; + + // Save source IP and port + mResponseAddress = address; + } + + return true; +} + +ByteBuffer* ClientBinding::generateData(bool force) +{ + if (!mComposed) + { + StunMessage msg; + msg.setMessageType(ice::StunMessage::Binding); + msg.setMessageClass(ice::StunMessage::RequestClass); + msg.setTransactionId(mTransactionID); + + if (mUseCandidate) + msg.setAttribute(new ICEUseCandidate()); + + // Copy comment to message object + msg.setComment(mComment); + + enqueueMessage(msg); + + mComposed = true; + } + + return Transaction::generateData(force); +} + +void ClientBinding::addUseCandidate() +{ + mUseCandidate = true; +} + + +//------------------------------ ServerBindingTransaction --------------------------- +ServerBinding::ServerBinding() +{ + setComment("ServerBinding"); + + mGenerate400 = false; + mGenerate487 = false; + mRole = 0; +} + +ServerBinding::~ServerBinding() +{ +} +void ServerBinding::setLocalTieBreaker(std::string tieBreaker) +{ + mLocalTieBreaker = tieBreaker; +} + +bool ServerBinding::processData(StunMessage& msg, NetworkAddress& address) +{ + if (msg.messageType() != StunMessage::Binding || msg.messageClass() != StunMessage::RequestClass) + return false; + ICELogDebug(<< "Received Binding request from " << address.toStdString().c_str()); + + // Save visible address + mSourceAddress = address; + + // Save transaction ID + mTransactionID = msg.transactionId(); + + // Save Priority value + if (msg.hasAttribute(StunAttribute::ICEPriority)) + { + mEnablePriority = true; + mPriority = msg.icePriorityAttr().priority(); + } + + // Save UseCandidate flag + mUseCandidate = msg.hasAttribute(StunAttribute::ICEUseCandidate); + + // Check if auth credentials are needed + mGenerate400 = false; //do not send 400 response by default + mGenerate487 = false; + + if (!msg.hasAttribute(StunAttribute::Username) || !msg.hasAttribute(StunAttribute::MessageIntegrity)) + { + ICELogCritical(<< "There is no Username or MessageIntegrity attributes in Binding required. Error 400 will be generated."); + // Send 400 error + mGenerate400 = true; + + return true; + } + + // Check for role + if (msg.hasAttribute(StunAttribute::ControlledAttr)) + { + mRemoteTieBreaker = msg.iceControlledAttr().tieBreaker(); + mRole = 1; // Session::Controlled; + } + else + if (msg.hasAttribute(StunAttribute::ControllingAttr)) + { + mRemoteTieBreaker = msg.iceControllingAttr().tieBreaker(); + mRole = 2;// Session::Controlling; + } + + return true; +} + + +ByteBuffer* ServerBinding::generateData(bool force) +{ + // Restart timer + mRTOTimer.stop(); + mRTOTimer.start(); + + // See if remote password / username are set + if (mPassword.empty() || mUsername.empty()) + return NULL; + + StunMessage msg; + + // Set transaction ID the same as processed incoming message + msg.setTransactionId(mTransactionID); + msg.setMessageType(StunMessage::Binding); + + if (mGenerate400) + { + // Generate bad request error + msg.setMessageClass(StunMessage::ErrorClass); + + msg.errorCodeAttr().setErrorCode(400); + msg.errorCodeAttr().setErrorPhrase("Bad request"); + } + else + if (mGenerate487) + { + // Generate 487 error + msg.setMessageClass(StunMessage::ErrorClass); + msg.errorCodeAttr().setErrorCode(487); + msg.errorCodeAttr().setErrorPhrase("Role conflict"); + } + else + { + msg.setMessageClass(StunMessage::SuccessClass); + + msg.mappedAddressAttr().address() = mSourceAddress; + msg.xorMappedAddressAttr().address() = mSourceAddress; + } + + // Build message + + // Clear outgoing buffer + mOutgoingData.clear(); + + // Check if message should be secured by message integrity + //std::string password; + if (!mGenerate400 && !mGenerate487) + { + // Do not create username attribute here - response does not need it + // msg.usernameAttr().setValue(mUsername); + + //ICELogCritical(<< "Using password " << mPassword); + + // Add message integrity attribute + msg.setAttribute(new MessageIntegrity()); + + if (mFingerprint) + msg.setAttribute(new Fingerprint()); + + // Add ICE-CONTROLLED attribute if needed + if (mEnableControlled) + msg.iceControlledAttr().setTieBreaker(mLocalTieBreaker); + + // Add ICE-CONTROLLING attribute if needed + if (mEnableControlling) + msg.iceControllingAttr().setTieBreaker(mLocalTieBreaker); + + // Add ICE-PRIORITY attribute if needed + if (mEnablePriority) + msg.icePriorityAttr().setPriority(mPriority); + } + + // Build packet + msg.buildPacket(mOutgoingData, mPassword); + + // Copy comment + msg.setComment(mComment); + + mComposed = true; + + return new ByteBuffer(mOutgoingData); +} + +bool ServerBinding::hasUseCandidate() +{ + return mUseCandidate; +} + +bool ServerBinding::gotRequest() +{ + return !mGenerate400 && !mGenerate487; +} + +int ServerBinding::role() +{ + return mRole; +} + +void ServerBinding::generate487() +{ + mGenerate487 = true; +} + +std::string ServerBinding::remoteTieBreaker() +{ + return mRemoteTieBreaker; +} + +void ServerBinding::restart() +{ +} + +//-------------------- BindingIndication --------------- +BindingIndication::BindingIndication(unsigned int interval) +:mInterval(interval) +{ + setComment("BindingIndication"); +} + +BindingIndication::~BindingIndication() +{ +} + +bool BindingIndication::processData(StunMessage& msg, NetworkAddress& address) +{ + return (msg.messageClass() == StunMessage::IndicationClass && + msg.messageType() == StunMessage::Binding); +} + + +ByteBuffer* BindingIndication::generateData(bool force) +{ + if (!mComposed) + { + StunMessage msg; + msg.setMessageClass(StunMessage::IndicationClass); + msg.setMessageType(StunMessage::Binding); + msg.setTransactionId(mTransactionID); + msg.setComment(mComment); + enqueueMessage(msg); + mComposed = true; + } + + return Transaction::generateData(force); +} + diff --git a/src/libs/ice/ICEBinding.h b/src/libs/ice/ICEBinding.h new file mode 100644 index 00000000..5ea7272b --- /dev/null +++ b/src/libs/ice/ICEBinding.h @@ -0,0 +1,131 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_BINDING_H +#define __ICE_BINDING_H + +#include "ICEStunTransaction.h" +#include "ICEAuthTransaction.h" +#include "ICEAddress.h" + +namespace ice +{ + class CheckResult + { + public: + virtual Transaction::State resultState() = 0; + virtual int resultError() = 0; + virtual NetworkAddress& resultSource() = 0; + virtual NetworkAddress& resultLocal() = 0; + virtual void useCandidate() = 0; + virtual unsigned resultPriority() = 0; + }; + + class ConnectivityCheck: public Transaction, public CheckResult + { + public: + ConnectivityCheck(); + virtual ~ConnectivityCheck(); + + ByteBuffer* generateData(bool force = false); + bool processData(StunMessage& msg, NetworkAddress& sourceAddress); + + NetworkAddress& mappedAddress(); //returns result from succesful transaction + NetworkAddress& responseAddress(); //returns responses source address + int errorCode(); + void addUseCandidate(); + void confirmTransaction(NetworkAddress& mapped); + + // CheckResult interface + int resultError(); + NetworkAddress& resultSource(); + NetworkAddress& resultLocal(); + State resultState(); + void useCandidate(); + unsigned resultPriority(); + protected: + NetworkAddress mResponseAddress; + NetworkAddress mMappedAddress; + bool mUseCandidate; + int mErrorCode; + std::string mErrorResponse; + }; + + class ClientBinding: public Transaction + { + public: + ClientBinding(); + virtual ~ClientBinding(); + + int errorCode(); //returns error code from failed transaction + std::string errorResponse(); //returns error msg from failed transaction + NetworkAddress& mappedAddress(); //returns result from succesful transaction + NetworkAddress& responseAddress(); //returns responses source address + + bool processData(StunMessage& msg, NetworkAddress& address); + ByteBuffer* generateData(bool force = false); + void addUseCandidate(); + + protected: + int mErrorCode; + NetworkAddress mMappedAddress; + std::string mErrorResponse; + NetworkAddress mResponseAddress; + bool mUseCandidate; + }; + + class ServerBinding: public Transaction + { + public: + ServerBinding(); + virtual ~ServerBinding(); + void setLocalTieBreaker(std::string tieBreaker); + + bool processData(StunMessage& msg, NetworkAddress& address); + ByteBuffer* generateData(bool force = false); + void restart(); + + // Checks if incoming request has UseCandidate attribute + bool hasUseCandidate(); + + // Checks if processed StunMessage was authenticated ok + bool gotRequest(); + + // Gets the role from processed message. It can be Controlled or Controlling or None. + int role(); + + // Instructs transaction to response with 487 code + void generate487(); + + // Returns received tie breaker + std::string remoteTieBreaker(); + + protected: + NetworkAddress mSourceAddress; + bool mUseCandidate; + bool mGenerate400; + bool mGenerate487; + int mRole; + std::string mLocalTieBreaker; + std::string mRemoteTieBreaker; + }; + + + class BindingIndication: public Transaction + { + public: + BindingIndication(unsigned int interval); + virtual ~BindingIndication(); + + bool processData(StunMessage& msg, NetworkAddress& address); + ByteBuffer* generateData(bool force = false); + + protected: + unsigned mTimestamp; + unsigned mInterval; + }; +} + +#endif \ No newline at end of file diff --git a/src/libs/ice/ICEBox.cpp b/src/libs/ice/ICEBox.cpp new file mode 100644 index 00000000..1da3cda6 --- /dev/null +++ b/src/libs/ice/ICEBox.cpp @@ -0,0 +1,60 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEBox.h" +#include "ICEBoxImpl.h" +#include + +using namespace ice; + +Stack::~Stack() +{ +} + +void Stack::initialize() +{ +} + +void Stack::finalize() +{ + ; +} + +Stack* Stack::makeICEBox(const ServerConfig& config) +{ + return new StackImpl(config); +} + +bool Stack::isDataIndication(ByteBuffer& source, ByteBuffer* plain) +{ + return Session::isDataIndication(source, plain); +} + +bool Stack::isStun(ByteBuffer& source) +{ + return Session::isStun(source); +} + +bool Stack::isRtp(ByteBuffer& data) +{ + return Session::isRtp(data); +} + +bool Stack::isChannelData(ByteBuffer& data, TurnPrefix prefix) +{ + return Session::isChannelData(data, prefix); +} + +ByteBuffer Stack::makeChannelData(TurnPrefix prefix, const void* data, unsigned datasize) +{ + ByteBuffer result; + result.resize(4 + datasize); + BufferWriter writer(result); + writer.writeUShort(prefix); + writer.writeUShort(datasize); + writer.writeBuffer(data, datasize); + + return result; +} diff --git a/src/libs/ice/ICEBox.h b/src/libs/ice/ICEBox.h new file mode 100644 index 00000000..4b37710a --- /dev/null +++ b/src/libs/ice/ICEBox.h @@ -0,0 +1,251 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __NAT_ICE_H +#define __NAT_ICE_H + +#include +#include + +#include "ICESync.h" +#include "ICEEvent.h" +#include "ICEAddress.h" +#include "ICEByteBuffer.h" +#include "ICECandidate.h" + +#define ICE_TIMEOUT 8000 +#define ICE_CHECK_INTERVAL 20 + +#define ICE_RTP_ID 1 +#define ICE_RTCP_ID 2 + +namespace ice +{ + + // Structure to describe used STUN/TURN configuration + struct ServerConfig + { + std::vector mServerList4, mServerList6; // List of STUN/TURN servers for IPv4 and IPv6 protocols + bool mUseIPv4; // Marks if IPv4 should be used when gathering candidates + bool mUseIPv6; // Marks if IPv6 should be used when gathering candidates + std::string mHost; // Target host to get default IP interface; usually it is public IP address + bool mRelay; // Marks if TURN is to be used instead STUN + unsigned int mTimeout; // Timeout value in milliseconds + unsigned int mPeriod; // Transmission interval + std::string mUsername; // User name for TURN server [optional] + std::string mPassword; // Password for TURN server [optional] + + ServerConfig() + :mUseIPv4(true), mUseIPv6(true), mRelay(false), mTimeout(ICE_TIMEOUT), mPeriod(ICE_CHECK_INTERVAL) + { + } + + ~ServerConfig() + {} + }; + + enum IceState + { + IceNone = 0, // Stack non active now + IceGathering = 1, // Stack gathering candidates now + IceGathered = 2, // Stack gathered candidates + IceChecking = 3, // Stack runs connectivity checks now + IceCheckSuccess = 4, // Connectivity checks were successful + IceFailed = 5, // Connectivity checks or gathering failed + IceTimeout = 6 // Timeout + }; + + + enum AgentRole + { + RoleControlled = 1, + RoleControlling = 2 + }; + + // ICE stack + class Stack + { + public: + static void initialize(); + static void finalize(); + + static Stack* makeICEBox(const ServerConfig& config); + + // Service methods to check incoming packets + static bool isDataIndication(ByteBuffer& source, ByteBuffer* plain); + static bool isStun(ByteBuffer& source); + static bool isRtp(ByteBuffer& data); + static bool isChannelData(ByteBuffer& data, TurnPrefix prefix); + + static ByteBuffer makeChannelData(TurnPrefix prefix, const void* data, unsigned datasize); + + /*! Sets ICE event handler pointer in stack. + * @param handler Pointer to ICE event handler instance. + * @param tag Custom user tag. */ + virtual void setEventHandler(StageHandler* handler, void* tag) = 0; + + /*! Adds new stream to ICE stack object. + * @return ID of created stream. + */ + virtual int addStream() = 0; + + /*! Adds new component (socket) to media stream. + * @param portNumber specifies used local port number for the socket. + * @returns component ID. This ID is unique only for specified stream. Two components in different streams can have the same */ + virtual int addComponent(int streamID, void* tag, unsigned short port4, unsigned short port6) = 0; + + /*! Removes media stream from ICE stack object. */ + virtual void removeStream(int streamID) = 0; + + virtual bool hasStream(int streamId) = 0; + virtual bool hasComponent(int streamId, int componentId) = 0; + virtual void setComponentPort(int streamId, int componentId, unsigned short port4, unsigned short port6) = 0; + + virtual void setRole(AgentRole role) = 0; + virtual AgentRole role() = 0; + + /*! Processes incoming data. + * @param streamID ICE stream ID + * @param componentID ICE component ID + * @param sourceIP IP of remote peer + * @param port number of remote peer + * @param sourceBuffer pointer to incoming data buffer + * @param sourceSize size of incoming data (in bytes) + */ + virtual bool processIncomingData(int stream, int component, ByteBuffer& incomingData) = 0; + + /*! Generates outgoing data for sending. + * @param response marks if the returned packet is response packet to remote peer's request + * @param streamID ICE stream ID + * @param componentID ICE component ID + * @param destIP Character buffer to write destination IP address in textual form + * @param destPort Destination port number. + * @param dataBuffer Pointer to output buffer. It must be big enough to include at least 1500 bytes - it is biggest UDP datagram in this library. + */ + virtual PByteBuffer generateOutgoingData(bool& response, int& stream, int& component, void*& tag) = 0; + + /*! Searches stream&component IDs by used local port and socket family. */ + virtual bool findStreamAndComponent(int family, unsigned short port, int* stream, int* component) = 0; + + /*! Starts to gather local candidates. */ + virtual void gatherCandidates() = 0; + + /*! Starts ICE connectivity checks. */ + virtual void checkConnectivity() = 0; + + /*! Checks if gathering is finished. */ + virtual IceState state() = 0; + + /*! Creates common part of SDP. It includes ice-full attribute and ufrag/pwd pair. + * @param common Common part of SDP. */ + virtual void createSdp(std::vector& common) = 0; + + /*! Returns default address for specified stream/component ID. + * @param ip Default IP address. + * @param port Default port number. */ + virtual NetworkAddress defaultAddress(int streamID, int componentID) = 0; + + /*! Returns candidate list for specified stream/component ID. + * @param streamID Stream ID. + * @param componentID Component ID. + * @param candidateList Output vector of local candidates. */ + virtual void fillCandidateList(int streamID, int componentID, std::vector& candidateList) = 0; + + /*! Process ICE offer text for specified stream. + * @param streamIndex ICE stream index. + * @param candidateList Input vector of strings - it holds candidate list. + * @param defaultIP Default IP for component ID 0. + * @param defaultPort Default port number for component ID 0. + * @return Returns true if processing(parsing) was ok, otherwise method returns false. */ + virtual bool processSdpOffer(int streamIndex, std::vector& candidateList, + const std::string& defaultIP, unsigned short defaultPort, bool deleteRelayed) = 0; + + virtual NetworkAddress getRemoteRelayedCandidate(int stream, int component) = 0; + virtual NetworkAddress getRemoteReflexiveCandidate(int stream, int component) = 0; + + /*! Notifies stack about ICE password of remote peer. + * @param pwd ICE password. */ + virtual void setRemotePassword(const std::string& pwd, int streamId = -1) = 0; + virtual std::string remotePassword(int streamId = -1) const = 0; + + /*! Notifies stack about ICE ufrag of remote peer. + * @param ufrag ICE ufrag credential. */ + virtual void setRemoteUfrag(const std::string& ufrag, int streamId = -1) = 0; + virtual std::string remoteUfrag(int streamId = -1) const = 0; + + /*! Returns local ICE password. + * @return ICE password. */ + virtual std::string localPassword() const = 0; + + /*! Returns local ICE ufrag. + * @return ICE ufrag credential. */ + virtual std::string localUfrag() const = 0; + + /*! Checks if the specified value is ICE session's TURN prefix value. + * @return Returns true if parameter is TURN prefix value, false otherwise. */ + virtual bool hasTurnPrefix(unsigned short prefix) = 0; + + /*! Gets the discovered during connectivity checks remote party's address. + * @return Remote party's address */ + virtual NetworkAddress remoteAddress(int stream, int component) = 0; + virtual NetworkAddress localAddress(int stream, int component) = 0; + + /*! Seeks for conclude pair. + */ + virtual bool findConcludePair(int stream, Candidate& local, Candidate& remote) = 0; + + /*! Checks if remote candidate list contains specified address. + * @return True if address is found in remote candidate list, false otherwise. */ + virtual bool candidateListContains(int stream, const std::string& remoteIP, unsigned short remotePort) = 0; + + // Dumps current state of stack to output + virtual void dump(std::ostream& output) = 0; + + // Returns if ICE session must be restarted after new offer. + virtual bool mustRestart() = 0; + + // Clears all connectivity checks and reset state of session to None. It does not delete streams and components. + virtual void clear() = 0; + + // Prepares stack to restart - clears remote candidate list, cancels existing connectivity checks, resets turn allocation counter + virtual void clearForRestart(bool localNetworkChanged) = 0; + + // Stops all connectivity & gathering checks. + virtual void stopChecks() = 0; + + // Refreshes local password and ufrag values. Useful when connectivity checks must be restarted. + virtual void refreshPwdUfrag() = 0; + + // Binds channel and return channel prefix + virtual TurnPrefix bindChannel(int stream, int component, const NetworkAddress& target, ChannelBoundCallback* cb) = 0; + virtual bool isChannelBindingFailed(int stream, int component, TurnPrefix prefix) = 0; + + virtual void installPermissions(int stream, int component, const NetworkAddress& address, InstallPermissionsCallback* cb) = 0; + + // Starts freeing of TURN allocations + virtual void freeAllocation(int stream, int component, DeleteAllocationCallback* cb) = 0; + + // Checks if there are active allocations on TURN server + virtual bool hasAllocations() = 0; + + // Checks if any of stream has set error code and return it + virtual int errorCode() = 0; + + // Returns the list of candidates from remote peer + virtual std::vector* remoteCandidates(int stream) = 0; + + // Returns chosen stun server address during last candidate gathering + virtual NetworkAddress activeStunServer(int stream) const = 0; + + virtual void setup(const ServerConfig& config) = 0; + virtual bool isRelayHost(const NetworkAddress& remote) = 0; + virtual bool isRelayAddress(const NetworkAddress& remote) = 0; + + virtual ~Stack(); + }; + +} //end of namespace + +#endif diff --git a/src/libs/ice/ICEBoxImpl.cpp b/src/libs/ice/ICEBoxImpl.cpp new file mode 100644 index 00000000..fdbde6ec --- /dev/null +++ b/src/libs/ice/ICEBoxImpl.cpp @@ -0,0 +1,445 @@ +/* Copyright(C) 2007-2017 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEBoxImpl.h" +#include "ICELog.h" +//#include "TargetConditionals.h" + +#define LOG_SUBSYSTEM "ICE" + +using namespace ice; + +StackImpl::StackImpl(const ServerConfig& config) +:mConfig(config), mEventHandler(NULL), mEventTag(NULL), mTimeout(false), mActionTimestamp(0) +{ + setup(config); +} + +StackImpl::~StackImpl() +{ +} + +void StackImpl::setEventHandler(StageHandler* handler, void* tag) +{ + mEventHandler = handler; + mEventTag = tag; +} + +int StackImpl::addStream() +{ + return mSession.addStream(); +} + +int StackImpl::addComponent(int streamID, void* tag, unsigned short port4, unsigned short port6) +{ + return mSession.addComponent(streamID, tag, port4, port6); +} + +void StackImpl::removeStream(int streamID) +{ + mSession.removeStream(streamID); +} + +bool StackImpl::findStreamAndComponent(int family, unsigned short port, int* stream, int* component) +{ + return mSession.findStreamAndComponent(family, port, stream, component); +} + +bool StackImpl::hasStream(int streamId) +{ + return mSession.hasStream(streamId); +} + +bool StackImpl::hasComponent(int streamId, int componentId) +{ + return mSession.hasComponent(streamId, componentId); +} + +void StackImpl::setComponentPort(int streamId, int componentId, unsigned short port4, unsigned short port6) +{ + mSession.setComponentPort(streamId, componentId, port4, port6); +} + + +void StackImpl::setRole(AgentRole role) +{ + mSession.setRole(role); +} + +AgentRole StackImpl::role() +{ + return mSession.role(); +} + +bool StackImpl::processIncomingData(int stream, int component, ByteBuffer& incomingData) +{ +#if defined(ICE_EMULATE_SYMMETRIC_NAT) //&& (TARGET_IPHONE_SIMULATOR) + if (!isRelayHost(incomingData.remoteAddress())) + { + ICELogDebug(<<"Discard packet as symmetric NAT is emulating now"); + return false; + } +#endif + + if (incomingData.remoteAddress().isEmpty()) + { + ICELogDebug(<< "Incoming packet; remote address is unknown"); + incomingData.setRemoteAddress(NetworkAddress::LoopbackAddress4); + } + else + { + ICELogDebug(<< "Incoming packet from " << incomingData.remoteAddress().toStdString()); + } + // Save previous ICE stack state + int icestate = state(); + + incomingData.setComponent(component); + bool result = mSession.processData(incomingData, stream, component); + + // Run handlers + if (result && mEventHandler) + { + int newicestate = state(); + if (icestate < IceCheckSuccess && newicestate >= IceCheckSuccess) + { + // Connectivity check finished + if (newicestate == IceCheckSuccess) + mEventHandler->onSuccess(this, mEventTag); + else + mEventHandler->onFailed(this, mEventTag); + } + else + if (icestate < IceGathered && newicestate >= IceGathered) + { + // Candidates are gathered + mEventHandler->onGathered(this, mEventTag); + } + } + + return result; +} + +PByteBuffer StackImpl::generateOutgoingData(bool& response, int& stream, int& component, void*& tag) +{ + // Get current timestamp + unsigned timestamp = ICETimeHelper::timestamp(); + + // Find amount of spent time + unsigned spent = ICETimeHelper::findDelta(mActionTimestamp, timestamp); + + // Check for timeout + if (mConfig.mTimeout && spent > mConfig.mTimeout) + { + ice::RunningState sessionState = mSession.state(); + + bool timeout = sessionState == ice::ConnCheck || sessionState == ice::CandidateGathering; + + if (!mTimeout && timeout) + { + // Mark stack as timeouted + mTimeout = true; + ICELogInfo(<< "Timeout detected."); + + if (sessionState == ice::CandidateGathering) + mSession.cancelAllocations(); + + // Find default address amongst host candidates + mSession.chooseDefaults(); + + if (mEventHandler) + { + if (sessionState == ice::ConnCheck) + { + // Session should not be cleared here - the CT uses direct path for connectivity checks and relayed if checks are failed. Relayed allocations will not be refreshed in such case + mEventHandler->onFailed(this, this->mEventTag); + } + else + mEventHandler->onGathered(this, this->mEventTag); + } + } + + if (timeout) + { + // Check if keepalive transactions are scheduled + if (!mSession.hasAllocations()) + return PByteBuffer(); + } + } + + // No timeout, proceed... + PByteBuffer result = mSession.getDataToSend(response, stream, component, tag); + if (result) + ICELogInfo(<< "Sending: " << result->comment() << " to " << result->remoteAddress().toStdString() << ". Data: \r\n" << result->hexstring()); + + return result; +} + +void StackImpl::gatherCandidates() +{ + mActionTimestamp = ICETimeHelper::timestamp(); + mSession.gatherCandidates(); + + // If there is no STUN server set or IP6 only interfaces - the candidate gathering can finish without network I/O + if (mSession.state() == CreatingSDP && mEventHandler) + mEventHandler->onGathered(this, mEventTag); +} + +void StackImpl::checkConnectivity() +{ + // Connectivity check can work if candidate gathering timeout-ed yet - it relies on host candidates only in this case + // So timeout flag is reset + mTimeout = false; + mActionTimestamp = ICETimeHelper::timestamp(); + mSession.checkConnectivity(); +} + +void StackImpl::stopChecks() +{ + mTimeout = false; + mActionTimestamp = 0; + mSession.stopChecks(); +} + +IceState StackImpl::state() +{ + if (mTimeout) + return IceTimeout; + + switch (mSession.state()) + { + case ice::None: return IceNone; + case ice::CandidateGathering: return IceGathering; + case ice::CreatingSDP: return IceGathered; + case ice::ConnCheck: return IceChecking; + case ice::Failed: return IceFailed; + case ice::Success: return IceCheckSuccess; + default: + break; + } + + assert(0); + return IceNone; // to avoid compiler warning +} + +void StackImpl::createSdp(std::vector& commonPart) +{ + mSession.createSdp(commonPart); +} + +NetworkAddress StackImpl::defaultAddress(int stream, int component) +{ + return mSession.defaultAddress(stream, component); +} + +void StackImpl::fillCandidateList(int streamID, int componentID, std::vector& candidateList) +{ + mSession.fillCandidateList(streamID, componentID, candidateList); +} + +bool StackImpl::processSdpOffer(int streamIndex, std::vector& candidateList, + const std::string& defaultIP, unsigned short defaultPort, bool deleteRelayed) +{ + return mSession.processSdpOffer(streamIndex, candidateList, defaultIP, defaultPort, deleteRelayed); +} + +NetworkAddress StackImpl::getRemoteRelayedCandidate(int stream, int component) +{ + return mSession.getRemoteRelayedCandidate(stream, component); +} + +NetworkAddress StackImpl::getRemoteReflexiveCandidate(int stream, int component) +{ + return mSession.getRemoteReflexiveCandidate(stream, component); +} + + +void StackImpl::setRemotePassword(const std::string& pwd, int streamId) +{ + mSession.setRemotePassword(pwd, streamId); +} + +std::string StackImpl::remotePassword(int streamId) const +{ + return mSession.remotePassword(streamId); +} + +void StackImpl::setRemoteUfrag(const std::string& ufrag, int streamId) +{ + mSession.setRemoteUfrag(ufrag, streamId); +} + +std::string StackImpl::remoteUfrag(int streamId) const +{ + return mSession.remoteUfrag(streamId); +} + +std::string StackImpl::localPassword() const +{ + return mSession.mLocalPwd; +} + +std::string StackImpl::localUfrag() const +{ + return mSession.mLocalUfrag; +} + +bool StackImpl::hasTurnPrefix(unsigned short prefix) +{ + return mSession.hasTurnPrefix((TurnPrefix)prefix); +} + +NetworkAddress StackImpl::remoteAddress(int stream, int component) +{ + return mSession.remoteAddress(stream, component); +} + +NetworkAddress StackImpl::localAddress(int stream, int component) +{ + return mSession.localAddress(stream, component); +} + +bool StackImpl::findConcludePair(int stream, Candidate& local, Candidate& remote) +{ + // Find nominated pair in stream + return mSession.findConcludePair(stream, local, remote); +} + +bool StackImpl::candidateListContains(int stream, const std::string& remoteIP, unsigned short remotePort) +{ + return mSession.mStreamMap[stream]->candidateListContains(remoteIP, remotePort); +} + +void StackImpl::dump(std::ostream& output) +{ + mSession.dump(output); +} + +bool StackImpl::mustRestart() +{ + return mSession.mustRestart(); +} + +void StackImpl::clear() +{ + mSession.clear(); + mActionTimestamp = 0; + mTimeout = false; +} + +void StackImpl::clearForRestart(bool localNetworkChanged) +{ + mSession.clearForRestart(localNetworkChanged); + mActionTimestamp = 0; + mTimeout = false; +} + +void StackImpl::refreshPwdUfrag() +{ + mSession.refreshPwdUfrag(); +} + +TurnPrefix StackImpl::bindChannel(int stream, int component, const ice::NetworkAddress &target, ChannelBoundCallback* cb) +{ + return mSession.bindChannel(stream, component, target, cb); +} + +bool StackImpl::isChannelBindingFailed(int stream, int component, TurnPrefix prefix) +{ + return mSession.isChannelBindingFailed(stream, component, prefix); +} + +void StackImpl::installPermissions(int stream, int component, const NetworkAddress &address, InstallPermissionsCallback* cb) +{ + mSession.installPermissions(stream, component, address, cb); +} + +void StackImpl::freeAllocation(int stream, int component, DeleteAllocationCallback* cb) +{ + mSession.freeAllocation(stream, component, cb); +} + +bool StackImpl::hasAllocations() +{ + return mSession.hasAllocations(); +} + +int StackImpl::errorCode() +{ + return mSession.errorCode(); +} + +std::vector* StackImpl::remoteCandidates(int stream) +{ + return mSession.remoteCandidates(stream); +} + +NetworkAddress StackImpl::activeStunServer(int stream) const +{ + return mSession.activeStunServer(stream); +} + +void StackImpl::setup(const ServerConfig& config) +{ + mConfig = config; + mSession.mConfig.mServerList4 = config.mServerList4; + mSession.mConfig.mServerList6 = config.mServerList6; + + // Set initial STUN/TURN server IP for case if there will no gathering candidates & selecting fastest server. + if (mSession.mConfig.mServerList4.size()) + mSession.mConfig.mServerAddr4 = mSession.mConfig.mServerList4.front(); + if (mSession.mConfig.mServerList6.size()) + mSession.mConfig.mServerAddr6 = mSession.mConfig.mServerList6.front(); + mSession.mConfig.mUseIPv4 = config.mUseIPv4; + mSession.mConfig.mUseIPv6 = config.mUseIPv6; + + if (mConfig.mRelay) + { + mSession.mConfig.mTurnPassword = config.mPassword; + mSession.mConfig.mTurnUsername = config.mUsername; + + mSession.mConfig.mUseTURN = true; + mSession.mConfig.mUseSTUN = false; + } + else + { + mSession.mConfig.mUseTURN = false; + mSession.mConfig.mUseSTUN = true; + } + mSession.mConfig.mTimeout = config.mTimeout; + + mSession.setup(mSession.mConfig); +} + +bool StackImpl::isRelayHost(const NetworkAddress& remote) +{ + for (unsigned i=0; i& commonPart) override; + NetworkAddress defaultAddress(int streamID, int componentID) override; + void fillCandidateList(int streamID, int componentID, std::vector& candidateList) override; + + bool processSdpOffer(int streamIndex, std::vector& candidateList, + const std::string& defaultIP, unsigned short defaultPort, bool deleteRelayed) override; + NetworkAddress getRemoteRelayedCandidate(int stream, int component) override; + NetworkAddress getRemoteReflexiveCandidate(int stream, int component) override; + + void setRemotePassword(const std::string& pwd, int streamId = -1) override; + std::string remotePassword(int streamId = -1) const override; + void setRemoteUfrag(const std::string& ufrag, int streamId = -1) override; + std::string remoteUfrag(int streamId = -1) const override; + + std::string localPassword() const override; + std::string localUfrag() const override; + bool hasTurnPrefix(unsigned short prefix) override; + NetworkAddress remoteAddress(int stream, int component) override; + NetworkAddress localAddress(int stream, int component) override; + bool findConcludePair(int stream, Candidate& local, Candidate& remote) override; + bool candidateListContains(int stream, const std::string& remoteIP, unsigned short remotePort) override; + void dump(std::ostream& output) override; + bool mustRestart() override; + void clear() override; + void clearForRestart(bool localNetworkChanged) override; + void refreshPwdUfrag() override; + + // Channel binding + TurnPrefix bindChannel(int stream, int component, const NetworkAddress& target, ChannelBoundCallback* cb) override; + bool isChannelBindingFailed(int stream, int component, TurnPrefix prefix) override; + + // Permissions + void installPermissions(int stream, int component, const NetworkAddress& address, InstallPermissionsCallback* cb) override; + + // Allocations + void freeAllocation(int stream, int component, DeleteAllocationCallback* cb) override; + bool hasAllocations() override; + + + int errorCode() override; + std::vector* + remoteCandidates(int stream) override; + NetworkAddress activeStunServer(int stream) const override; + void setup(const ServerConfig& config) override; + bool isRelayHost(const NetworkAddress& remote) override; + bool isRelayAddress(const NetworkAddress& remote) override; + }; +} //end of namespace + +#endif diff --git a/src/libs/ice/ICEByteBuffer.cpp b/src/libs/ice/ICEByteBuffer.cpp new file mode 100644 index 00000000..f8ac74ab --- /dev/null +++ b/src/libs/ice/ICEByteBuffer.cpp @@ -0,0 +1,560 @@ +/* Copyright(C) 2007-2018 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#define NOMINMAX + +#include "ICEPlatform.h" +#include "ICEByteBuffer.h" +#include "ICEError.h" +#include +#include + +using namespace ice; +ByteBuffer::ByteBuffer() +{ + initEmpty(); + mData.reserve(512); +} + +ByteBuffer::ByteBuffer(size_t initialCapacity) +{ + initEmpty(); + mData.reserve(initialCapacity); +} + +ByteBuffer::ByteBuffer(const ByteBuffer& src) +:mData(src.mData), mComponent(src.mComponent), mTag(nullptr), + mRelayed(src.mRelayed), mCopyBehavior(src.mCopyBehavior), + mDataPtr(src.mDataPtr), mDataSize(src.mDataSize) +{ + if (mCopyBehavior == CopyBehavior::CopyMemory && mData.size()) + mDataPtr = &mData[0]; +} + +ByteBuffer::ByteBuffer(const void* packetPtr, size_t packetSize, CopyBehavior behavior) +:mComponent(-1), mTag(nullptr), mRelayed(false), mCopyBehavior(behavior), mDataPtr(nullptr), mDataSize(packetSize) +{ + switch (behavior) + { + case CopyBehavior::CopyMemory: + mData.resize(packetSize); + memcpy(&mData[0], packetPtr, packetSize); + mDataPtr = &mData[0]; + break; + + case CopyBehavior::UseExternal: + mDataPtr = (uint8_t*)packetPtr; + break; + + default: + break; + } +} + +ByteBuffer::~ByteBuffer() +{ + if (mCopyBehavior == CopyBehavior::CopyMemory) + memset(mDataPtr, 0, mDataSize); +} + +ByteBuffer& ByteBuffer::operator = (const ByteBuffer& src) +{ + mRelayed = src.mRelayed; + mComment = src.mComment; + mComponent = src.mComponent; + mRemoteAddress = src.mRemoteAddress; + mTag = src.mTag; + + if (src.mCopyBehavior == CopyBehavior::CopyMemory) + { + mData = src.mData; + mCopyBehavior = CopyBehavior::CopyMemory; + syncPointer(); + + } + else + { + mDataPtr = src.mDataPtr; + mDataSize = src.mDataSize; + mCopyBehavior = CopyBehavior::UseExternal; + } + + return *this; +} + +void ByteBuffer::clear() +{ + mData.resize(0); + mDataSize = 0; + mDataPtr = nullptr; +} + +size_t ByteBuffer::size() const +{ + return mDataSize; +} + +const uint8_t* ByteBuffer::data() const +{ + return (const uint8_t*)mDataPtr; +} + +uint8_t* ByteBuffer::mutableData() +{ + return mDataPtr; +} + +NetworkAddress& ByteBuffer::remoteAddress() +{ + return mRemoteAddress; +} + +void ByteBuffer::setRemoteAddress(const NetworkAddress& addr) +{ + mRemoteAddress = addr; +} + +void ByteBuffer::setComment(std::string comment) +{ + mComment = comment; +} + +std::string ByteBuffer::comment() +{ + return mComment; +} + +std::string ByteBuffer::hexstring() +{ + std::string result; + result.resize(mDataSize * 2, (char)0xCC); + for (std::vector::size_type index = 0; index < mDataSize; index++) + { + char value[3]; + sprintf(value, "%02X", (unsigned char)mDataPtr[index]); + result[index*2] = value[0]; + result[index*2+1] = value[1]; + } + return result; +} + +void ByteBuffer::reserve(size_t capacity) +{ + mData.reserve(capacity); + syncPointer(); +} + +void ByteBuffer::insertTurnPrefix(unsigned short prefix) +{ + assert(mCopyBehavior == CopyBehavior::CopyMemory); + + mData.insert(mData.begin(), 2, 32); + unsigned short nprefix = htons(prefix); + mData[0] = nprefix & 0xFF; + mData[1] = (nprefix & 0xFF00) >> 8; + syncPointer(); +} + +int ByteBuffer::component() +{ + return mComponent; +} + +void ByteBuffer::setComponent(int component) +{ + mComponent = component; +} + +void ByteBuffer::truncate(size_t newsize) +{ + assert (mCopyBehavior == CopyBehavior::CopyMemory); + + mData.erase(mData.begin() + newsize, mData.end()); + syncPointer(); +} + +void ByteBuffer::erase(size_t p, size_t l) +{ + assert (mCopyBehavior == CopyBehavior::CopyMemory); + + mData.erase(mData.begin()+p, mData.begin()+p+l); + syncPointer(); +} + +void ByteBuffer::resize(size_t newsize) +{ + assert (mCopyBehavior == CopyBehavior::CopyMemory); + + std::vector::size_type sz = mData.size(); + mData.resize(newsize); + if (newsize > sz) + memset(&mData[sz], 0, newsize - sz); + + syncPointer(); +} + +void ByteBuffer::appendBuffer(const void *data, size_t size) +{ + assert (mCopyBehavior == CopyBehavior::CopyMemory); + + size_t len = mData.size(); + mData.resize(len + size); + memmove(mData.data() + len, data, size); + syncPointer(); +} + +void* ByteBuffer::tag() +{ + return mTag; +} + +void ByteBuffer::setTag(void* tag) +{ + mTag = tag; +} + +bool ByteBuffer::relayed() +{ + return mRelayed; +} + +void ByteBuffer::setRelayed(bool value) +{ + mRelayed = value; +} + +void ByteBuffer::initEmpty() +{ + mDataPtr = nullptr; + mDataSize = 0; + mCopyBehavior = CopyBehavior::CopyMemory; + mRelayed = false; + mComponent = -1; + mTag = nullptr; +} + +void ByteBuffer::syncPointer() +{ + mDataPtr = mData.empty() ? nullptr : &mData[0]; + mDataSize = mData.size(); +} + +uint8_t ByteBuffer::operator[](int index) const +{ + return mDataPtr[index]; +} + +uint8_t& ByteBuffer::operator[](int index) +{ + return mDataPtr[index]; +} + +// ----------------- BitReader ------------------- +BitReader::BitReader(const ByteBuffer &buffer) + :mStream(buffer.data()), mStreamLen(buffer.size()), mStreamOffset(0), mCurrentBit(0) +{ + init(); +} + +BitReader::BitReader(const void *input, size_t bytes) + :mStream((const uint8_t*)input), mStreamLen(bytes), mStreamOffset(0), mCurrentBit(0) +{ + init(); +} + +void BitReader::init() +{ + mStreamOffset = mStreamLen << 3; + mCurrentPosition = 0;//mStreamOffset - 1; + mCurrentBit = 0; +} + +BitReader::~BitReader() +{} + +// Check for valid position +uint8_t BitReader::readBit() +{ + uint8_t value = 0x00; + if (mCurrentPosition < mStreamOffset) + { + // Read single BIT + size_t currentByte = mCurrentPosition >> 3; + uint8_t currentBit = (uint8_t)(mCurrentPosition % 8); + value = ((uint8_t)(mStream[currentByte] << currentBit) >> 7); + mCurrentPosition = std::max((size_t)0, std::min(mStreamOffset-1, mCurrentPosition+1)); + } + + return value; +} + +uint32_t BitReader::readBits(size_t nrOfBits) +{ + assert (nrOfBits <= 32); + + uint32_t result = 0; + BitWriter bw(&result); + for (int i=0; i<(int)nrOfBits; i++) + bw.writeBit(readBit()); + + return result; +} + +size_t BitReader::readBits(void *output, size_t nrOfBits) +{ + // Check how much bits available + nrOfBits = std::min(nrOfBits, mStreamOffset - mCurrentPosition); + + BitWriter bw(output); + for (int i=0; i<(int)nrOfBits; i++) + bw.writeBit(readBit()); + + return nrOfBits; +} + +size_t BitReader::count() const +{ + return mStreamOffset; +} + +size_t BitReader::position() const +{ + return mCurrentPosition; +} + +// ----------------- BitWriter ------------------- +BitWriter::BitWriter(ByteBuffer &buffer) + :mStream(buffer.mutableData()), mStreamLen(0), mStreamOffset(0), mCurrentBit(0) +{ + init(); +} + +BitWriter::BitWriter(void *output) + :mStream((uint8_t*)output), mStreamLen(0), mStreamOffset(0), mCurrentBit(0) +{ + init(); +} + +void BitWriter::init() +{ + mStreamOffset = mStreamLen << 3; + mCurrentPosition = 0;//mStreamOffset - 1; + mCurrentBit = 0; +} + +BitWriter::~BitWriter() +{} + +BitWriter& BitWriter::writeBit(int bit) +{ + bit = bit ? 1 : 0; + + // Check for current bit offset + if ((mCurrentBit % 8) == 0) + { + // Write new zero byte to the end of stream + mCurrentBit = 0; + mStreamLen++; + mStream[mStreamLen-1] = 0; + } + + // Write single BIT + mStream[mStreamLen-1] <<= 1; + mStream[mStreamLen-1] |= bit; + mStreamOffset++; + mCurrentPosition = mStreamOffset - 1; + mCurrentBit++; + + return *this; +} + +size_t BitWriter::count() const +{ + return mStreamOffset; +} + +// ----------------- BufferReader ---------------- +BufferReader::BufferReader(const ByteBuffer &buffer) + :mData(buffer.data()), mSize(buffer.size()), mIndex(0) +{} + +BufferReader::BufferReader(const void *input, size_t bytes) + :mData((const uint8_t*)input), mSize(bytes), mIndex(0) +{} + + +uint32_t BufferReader::readUInt() +{ + uint32_t nresult = 0; + readBuffer(&nresult, 4); + + return ntohl(nresult); +} + +uint32_t BufferReader::readNativeUInt() +{ + uint32_t nresult = 0; + readBuffer(&nresult, 4); + + return nresult; +} + +uint16_t BufferReader::readUShort() +{ + uint16_t result = 0; + readBuffer(&result, 2); + + return ntohs(result); +} + +uint16_t BufferReader::readNativeUShort() +{ + uint16_t result = 0; + readBuffer(&result, 2); + + return result; +} + +uint8_t BufferReader::readUChar() +{ + uint8_t result = 0; + readBuffer(&result, 1); + + return result; +} + +NetworkAddress BufferReader::readIp(int family) +{ + if (family == AF_INET) + { + sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = 0; + readBuffer(&addr.sin_addr.s_addr, 4); + + return NetworkAddress((sockaddr&)addr, sizeof(addr)); + } + else + if (family == AF_INET6) + { + sockaddr_in6 addr; + memset(&addr, 0, sizeof(addr)); + addr.sin6_family = AF_INET6; + addr.sin6_port = 0; + readBuffer(&addr.sin6_addr, 16); + + return NetworkAddress((sockaddr&)addr, sizeof(addr)); + } + return NetworkAddress(); +} + +size_t BufferReader::readBuffer(void* dataPtr, size_t dataSize) +{ + if (dataSize > 0) + { + size_t available = mSize - mIndex; + if (available < dataSize) + dataSize = available; + if (NULL != dataPtr) + memcpy(dataPtr, mData + mIndex, dataSize); + + mIndex += dataSize; + return dataSize; + } + return 0; +} + +size_t BufferReader::readBuffer(ByteBuffer& bb, size_t dataSize) +{ + if (dataSize > 0) + { + // Find how much data are available in fact + size_t available = mSize - mIndex; + if (available < dataSize) + dataSize = available; + + // Extend byte buffer + size_t startIndex = bb.size(); + bb.resize(bb.size() + dataSize); + memcpy(bb.mutableData() + startIndex, mData + mIndex, dataSize); + mIndex += dataSize; + return dataSize; + } + return 0; +} + +size_t BufferReader::count() const +{ + return mIndex; +} + +// -------------- BufferWriter ---------------------- +BufferWriter::BufferWriter(ByteBuffer &buffer) + :mData(buffer.mutableData()), mIndex(0) +{} + +BufferWriter::BufferWriter(void *output) + :mData((uint8_t*)output), mIndex(0) +{} + + +void BufferWriter::writeUInt(uint32_t value) +{ + // Convert to network order bytes + uint32_t nvalue = htonl(value); + + writeBuffer(&nvalue, 4); +} + + +void BufferWriter::writeUShort(uint16_t value) +{ + uint16_t nvalue = htons(value); + writeBuffer(&nvalue, 2); +} + +void BufferWriter::writeUChar(uint8_t value) +{ + writeBuffer(&value, 1); +} + +void BufferWriter::writeIp(const NetworkAddress& ip) +{ + switch (ip.stunType()) + { + case 1/*IPv4*/: + writeBuffer(&ip.sockaddr4()->sin_addr, 4); + break; + + case 2/*IPv6*/: + writeBuffer(&ip.sockaddr6()->sin6_addr, 16); + break; + + default: + assert(0); + } +} + +void BufferWriter::writeBuffer(const void* dataPtr, size_t dataSize) +{ + memmove(mData + mIndex, dataPtr, dataSize); + mIndex += dataSize; +} + +void BufferWriter::rewind() +{ + mIndex = 0; +} + +void BufferWriter::skip(int count) +{ + mIndex += count; +} + +size_t BufferWriter::offset() const +{ + return mIndex; +} diff --git a/src/libs/ice/ICEByteBuffer.h b/src/libs/ice/ICEByteBuffer.h new file mode 100644 index 00000000..2c219b2b --- /dev/null +++ b/src/libs/ice/ICEByteBuffer.h @@ -0,0 +1,187 @@ +/* Copyright(C) 2007-2016 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_BYTE_BUFFER_H +#define __ICE_BYTE_BUFFER_H + +#include "ICEPlatform.h" +#include "ICETypes.h" + +#include +#include +#include +#include "ICETypes.h" +#include "ICEAddress.h" + +namespace ice +{ + class ByteBuffer + { + public: + enum class CopyBehavior + { + CopyMemory, + UseExternal + }; + + ByteBuffer(); + ByteBuffer(size_t initialCapacity); + ByteBuffer(const ByteBuffer& src); + ByteBuffer(const void* packetPtr, size_t packetSize, CopyBehavior behavior = CopyBehavior::CopyMemory); + ~ByteBuffer(); + + ByteBuffer& operator = (const ByteBuffer& src); + + void clear(); + + size_t size() const; + const uint8_t* data() const; + uint8_t* mutableData(); + + NetworkAddress& remoteAddress(); + void setRemoteAddress(const NetworkAddress& addr); + int component(); + void setComponent(int component); + void setComment(std::string comment); + std::string comment(); + std::string hexstring(); + + void reserve(size_t capacity); + void insertTurnPrefix(unsigned short prefix); + void truncate(size_t newsize); + void erase(size_t p, size_t l); + void resize(size_t newsize); + void appendBuffer(const void* data, size_t size); + void* tag(); + void setTag(void* tag); + void trim(); + bool relayed(); + void setRelayed(bool value); + void syncPointer(); + + uint8_t operator[](int index) const; + uint8_t& operator[](int index); + + + protected: + std::vector mData; // Internal storage + uint8_t* mDataPtr; // Pointer to internal storage or external data + uint32_t mDataSize; // Used only for mCopyBehavior == UseExternal + NetworkAddress mRemoteAddress; // Associates buffer with IP address + int mComponent; // Associates buffer with component ID + std::string mComment; // Comment's for this buffer - useful in debugging + void* mTag; // User tag + bool mRelayed; // Marks if buffer was received via relay + CopyBehavior mCopyBehavior; // Determines if buffer manages internal or external data + + void initEmpty(); + int bitsInBuffer(uint8_t bufferMask); + }; + + + typedef std::shared_ptr PByteBuffer; + + class BitReader + { + protected: + const uint8_t* mStream; + size_t mStreamLen; + size_t mStreamOffset; + size_t mCurrentPosition; + size_t mCurrentBit; + + void init(); + + public: + BitReader(const void* input, size_t bytes); + BitReader(const ByteBuffer& buffer); + ~BitReader(); + + uint8_t readBit(); + uint32_t readBits(size_t nrOfBits); + size_t readBits(void* output, size_t nrOfBits); + + size_t count() const; + size_t position() const; + }; + + class BitWriter + { + protected: + uint8_t* mStream; + size_t mStreamLen; + size_t mStreamOffset; + size_t mCurrentPosition; + size_t mCurrentBit; + + void init(); + public: + BitWriter(void* output); + BitWriter(ByteBuffer& buffer); + ~BitWriter(); + + // Bit must be 0 or 1 + BitWriter& writeBit(int bit); + size_t count() const; + }; + + class BufferReader + { + protected: + const uint8_t* mData; + size_t mSize; + size_t mIndex; + + public: + BufferReader(const void* input, size_t bytes); + BufferReader(const ByteBuffer& buffer); + + // This methods reads uint32_t from stream and converts network byte order to host byte order. + uint32_t readUInt(); + + // This method reads uint32_t from stream. No conversion between byte orders. + uint32_t readNativeUInt(); + + // This method reads uint16_t from stream and converts network byte order to host byte order. + uint16_t readUShort(); + + // This method reads uint16_t. No conversion between byte orders. + uint16_t readNativeUShort(); + uint8_t readUChar(); + + // Reads in_addr or in6_addr from stream and wraps it to NetworkAddress + NetworkAddress readIp(int family); + + // Reads to plain memory buffer + size_t readBuffer(void* dataPtr, size_t dataSize); + + // Read directly to byte buffer. New data will be appended to byte buffer + size_t readBuffer(ByteBuffer& bb, size_t dataSize); + + size_t count() const; + }; + + class BufferWriter + { + protected: + uint8_t* mData; + size_t mIndex; + + public: + BufferWriter(void* output); + BufferWriter(ByteBuffer& buffer); + + void writeUInt(uint32_t value); + void writeUShort(uint16_t value); + void writeUChar(uint8_t value); + void writeIp(const NetworkAddress& ip); + void writeBuffer(const void* dataPtr, size_t dataSize); + void rewind(); + void skip(int count); + + size_t offset() const; + }; +} +#endif diff --git a/src/libs/ice/ICECRC32.cpp b/src/libs/ice/ICECRC32.cpp new file mode 100644 index 00000000..74e6dcb1 --- /dev/null +++ b/src/libs/ice/ICECRC32.cpp @@ -0,0 +1,177 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _CCRC32_CPP +#define _CCRC32_CPP + +#include +#include +#include "ICECRC32.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +using namespace ice; + +CRC32::CRC32(void) +{ + this->initialize(); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +CRC32::~CRC32(void) +{ + //No destructor code. +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + This function initializes "CRC Lookup Table". You only need to call it once to + initalize the table before using any of the other CRC32 calculation functions. +*/ + +void CRC32::initialize(void) +{ + //0x04C11DB7 is the official polynomial used by PKZip, WinZip and Ethernet. + unsigned long ulPolynomial = 0x04C11DB7; + + //memset(&this->ulTable, 0, sizeof(this->ulTable)); + + // 256 values representing ASCII character codes. + for(int iCodes = 0; iCodes <= 0xFF; iCodes++) + { + this->ulTable[iCodes] = this->reflect(iCodes, 8) << 24; + + for(int iPos = 0; iPos < 8; iPos++) + { + this->ulTable[iCodes] = (this->ulTable[iCodes] << 1) + ^ ((this->ulTable[iCodes] & (1 << 31)) ? ulPolynomial : 0); + } + + this->ulTable[iCodes] = this->reflect(this->ulTable[iCodes], 32); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + Reflection is a requirement for the official CRC-32 standard. + You can create CRCs without it, but they won't conform to the standard. +*/ + +unsigned long CRC32::reflect(unsigned long ulReflect, const char cChar) +{ + unsigned long ulValue = 0; + + // Swap bit 0 for bit 7, bit 1 For bit 6, etc.... + for(int iPos = 1; iPos < (cChar + 1); iPos++) + { + if(ulReflect & 1) + { + ulValue |= (1 << (cChar - iPos)); + } + ulReflect >>= 1; + } + + return ulValue; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + Calculates the CRC32 by looping through each of the bytes in sData. + + Note: For Example usage example, see FileCRC(). +*/ + +void CRC32::partialCrc(unsigned long *ulCRC, const unsigned char *sData, unsigned long ulDataLength) +{ + while(ulDataLength--) + { + //If your compiler complains about the following line, try changing each + // occurrence of *ulCRC with "((unsigned long)*ulCRC)" or "*(unsigned long *)ulCRC". + + *(unsigned long *)ulCRC = + ((*(unsigned long *)ulCRC) >> 8) ^ this->ulTable[((*(unsigned long *)ulCRC) & 0xFF) ^ *sData++]; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + Returns the calculated CRC32 (through ulOutCRC) for the given string. +*/ + +void CRC32::fullCrc(const unsigned char *sData, unsigned long ulDataLength, unsigned long *ulOutCRC) +{ + *(unsigned long *)ulOutCRC = 0xffffffff; //Initilaize the CRC. + this->partialCrc(ulOutCRC, sData, ulDataLength); + *(unsigned long *)ulOutCRC ^= 0xffffffff; //Finalize the CRC. +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + Returns the calculated CRC23 for the given string. +*/ + +unsigned long CRC32::fullCrc(const unsigned char *sData, unsigned long ulDataLength) +{ + unsigned long ulCRC = 0xffffffff; //Initilaize the CRC. + this->partialCrc(&ulCRC, sData, ulDataLength); + return(ulCRC ^ 0xffffffff); //Finalize the CRC and return. +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + Calculates the CRC32 of a file using the a user defined buffer. + + Note: The buffer size DOES NOT affect the resulting CRC, + it has been provided for performance purposes only. +*/ + +bool CRC32::fileCrc(const char *sFileName, unsigned long *ulOutCRC, unsigned long ulBufferSize) +{ + *(unsigned long *)ulOutCRC = 0xffffffff; //Initilaize the CRC. + + FILE *fSource = NULL; + unsigned char *sBuf = NULL; + int iBytesRead = 0; + + if((fSource = fopen(sFileName, "rb")) == NULL) + { + return false; //Failed to open file for read access. + } + + if(!(sBuf = (unsigned char *)malloc(ulBufferSize))) //Allocate memory for file buffering. + { + fclose(fSource); + return false; //Out of memory. + } + + while((iBytesRead = fread(sBuf, sizeof(char), ulBufferSize, fSource))) + { + this->partialCrc(ulOutCRC, sBuf, iBytesRead); + } + + free(sBuf); + fclose(fSource); + + *(unsigned long *)ulOutCRC ^= 0xffffffff; //Finalize the CRC. + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + Calculates the CRC32 of a file using the a default buffer size of 1MB. + + Note: The buffer size DOES NOT affect the resulting CRC, + it has been provided for performance purposes only. +*/ + +bool CRC32::fileCrc(const char *sFileName, unsigned long *ulOutCRC) +{ + return this->fileCrc(sFileName, ulOutCRC, 1048576); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#endif diff --git a/src/libs/ice/ICECRC32.h b/src/libs/ice/ICECRC32.h new file mode 100644 index 00000000..94eb96b7 --- /dev/null +++ b/src/libs/ice/ICECRC32.h @@ -0,0 +1,32 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_CRC32_H +#define __ICE_CRC32_H +namespace ice +{ + class CRC32 + { + public: + CRC32(void); + ~CRC32(void); + + void initialize(void); + + bool fileCrc(const char *sFileName, unsigned long *ulOutCRC); + bool fileCrc(const char *sFileName, unsigned long *ulOutCRC, unsigned long ulBufferSize); + + unsigned long fullCrc(const unsigned char *sData, unsigned long ulDataLength); + void fullCrc(const unsigned char *sData, unsigned long ulLength, unsigned long *ulOutCRC); + + void partialCrc(unsigned long *ulCRC, const unsigned char *sData, unsigned long ulDataLength); + + private: + unsigned long reflect(unsigned long ulReflect, const char cChar); + unsigned long ulTable[256]; // CRC lookup table array. + }; +} + +#endif \ No newline at end of file diff --git a/src/libs/ice/ICECandidate.cpp b/src/libs/ice/ICECandidate.cpp new file mode 100644 index 00000000..a4b37763 --- /dev/null +++ b/src/libs/ice/ICECandidate.cpp @@ -0,0 +1,188 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICECandidate.h" +#include "ICEError.h" +#include "ICELog.h" +#include +#include + +#define LOG_SUBSYSTEM "ICE" + +using namespace ice; + +void Candidate::setLocalAndExternalAddresses(std::string& ip, unsigned short portNumber) +{ + mLocalAddr.setIp(ip); + mLocalAddr.setPort(portNumber); + mExternalAddr.setIp(ip); + mExternalAddr.setPort(portNumber); +} + +void Candidate::setLocalAndExternalAddresses(NetworkAddress& addr) +{ + mLocalAddr = addr; + mExternalAddr = addr; +} + +void Candidate::setLocalAndExternalAddresses(NetworkAddress &addr, unsigned short altPort) +{ + mLocalAddr = addr; + mExternalAddr = addr; + mLocalAddr.setPort(altPort); + mExternalAddr.setPort(altPort); +} + +void Candidate::computePriority(int* typepreflist) +{ + mPriority = (typepreflist[mType] << 24) + (mInterfacePriority << 8) + (256 - mComponentId); +} + +void Candidate::computeFoundation() +{ + sprintf(mFoundation, "%u", unsigned((mType << 24) + inet_addr(mLocalAddr.ip().c_str()))); +} + +const char* Candidate::type() +{ + switch (mType) + { + case Candidate::Host: + return "host"; + + case Candidate::ServerReflexive: + return "srflx"; + + case Candidate::ServerRelayed: + return "relay"; + + case Candidate::PeerReflexive: + return "prflx"; + + default: + ICELogCritical(<< "Bad candidate type, reverted to Host."); + return "host"; + } +} + +std::string Candidate::createSdp() +{ + char buffer[512]; + + unsigned port = (unsigned)mExternalAddr.port(); + +#define SDP_CANDIDATE_FORMAT "%s %u %s %u %s %u typ %s" + + sprintf(buffer, SDP_CANDIDATE_FORMAT, strlen(mFoundation) ? mFoundation : "16777000" , mComponentId, "UDP", mPriority, mExternalAddr.ip().c_str(), port, type()); + + if (mType != Candidate::Host) + { + char relattr[64]; + sprintf(relattr, " raddr %s rport %u", mLocalAddr.ip().c_str(), (unsigned int)mLocalAddr.port()); + strcat(buffer, relattr); + } + + return buffer; +} + +Candidate Candidate::parseSdp(const char* sdp) +{ + Candidate result(Candidate::Host); + + char protocol[32], externalIP[128], candtype[32], raddr[64]; + unsigned int remoteport = 0; + + unsigned int externalPort = 0; + + // Look for "typ" string + const char* formatstring; + if (strstr(sdp, "typ")) + formatstring = "%s %u %s %u %s %u typ %s raddr %s rport %u"; + else + formatstring = "%s %u %s %u %s %u %s raddr %s rport %u"; + int wasread = sscanf(sdp, formatstring, &result.mFoundation, &result.mComponentId, protocol, + &result.mPriority, externalIP, &externalPort, candtype, raddr, &remoteport); + + if (wasread >= 7) + { + // Save external address + result.mExternalAddr.setIp( externalIP ); + result.mExternalAddr.setPort( externalPort ); + + result.mLocalAddr = result.mExternalAddr; + + // Check the protocol (UDP4/6 is supported only) +#ifdef _WIN32 + _strupr(protocol); _strupr(candtype); +#else + strupr(protocol); strupr(candtype); +#endif + if (strcmp(protocol, "UDP") != 0) + throw Exception(UDP_SUPPORTED_ONLY); + + // Save candidate type + result.mType = typeFromString(candtype); + } + + return result; +} + +Candidate::Type Candidate::typeFromString(const char* candtype) +{ + if (!strcmp(candtype, "HOST")) + return Candidate::Host; + else + if (!strcmp(candtype, "SRFLX")) + return Candidate::ServerReflexive; + else + if (!strcmp(candtype, "PRFLX")) + return Candidate::PeerReflexive; + else + if (!strcmp(candtype, "RELAY")) + return Candidate::ServerRelayed; + else + { + ICELogCritical(<< "Bad candidate type in parser. Reverted to Host"); + return Candidate::Host; + } +} + + +bool Candidate::equal(Candidate& cand1, Candidate& cand2) +{ + if (cand1.mType != cand2.mType) + return false; + switch (cand1.mType) + { + case Candidate::Host: + return (cand1.mLocalAddr == cand2.mLocalAddr); + + case Candidate::ServerReflexive: + case Candidate::PeerReflexive: + case Candidate::ServerRelayed: + return (cand1.mExternalAddr == cand2.mExternalAddr); + + } + + ICELogCritical(<< "Bad candidate type, comparing as Host"); + return cand1.mLocalAddr == cand2.mLocalAddr; +} + +bool Candidate::operator == (const Candidate& rhs) const +{ + bool relayed1 = mType == ServerRelayed, relayed2 = rhs.mType == ServerRelayed; + + return relayed1 == relayed2 && mLocalAddr == rhs.mLocalAddr && mExternalAddr == rhs.mExternalAddr; +} + +void Candidate::dump(std::ostream& output) +{ + output << Logger::TabPrefix<< Logger::TabPrefix << createSdp().c_str() << std::endl; +} + +int Candidate::component() +{ + return mComponentId; +} \ No newline at end of file diff --git a/src/libs/ice/ICECandidate.h b/src/libs/ice/ICECandidate.h new file mode 100644 index 00000000..293b4d11 --- /dev/null +++ b/src/libs/ice/ICECandidate.h @@ -0,0 +1,113 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_CANDIDATE_H +#define __ICE_CANDIDATE_H + +#include "ICEPlatform.h" +#include "ICESmartPtr.h" +#include "ICEAddress.h" + +#include + +namespace ice +{ + struct Candidate + { + enum Type + { + Host = 0, + ServerReflexive = 1, + PeerReflexive = 2, + ServerRelayed = 3 + }; + + // Type of candidate - host, server reflexive/relayes or peer reflexive + Type mType; + + // External address + NetworkAddress mExternalAddr; + + // The component ID in ICE session + int mComponentId; + + // Mark the gathered candidate + bool mReady; + + // Mark the failed candidate - gathering is failed + bool mFailed; + + // The candidate priority + unsigned int mPriority; + + // Candidate's foundation + char mFoundation[33]; + + // Interface priority + unsigned int mInterfacePriority; + + // Local used address + NetworkAddress mLocalAddr; + + Candidate() + :mType(Host), mComponentId(0), mReady(false), mFailed(false), mPriority(0), + mInterfacePriority(0) + { + memset(mFoundation, 0, sizeof mFoundation); + } + + /* Constructor. + * @param _type Type of candidate - host, reflexive or relayed. + * @param componentID ID of component where candidate is used. + * @param portNumber Local port number. + * @param ipAddress Local IP address. + * @param interfacePriority Priority of specified interface. + * @param startTimeout Start time for STUN/TURN checks. */ + Candidate(Type _type) + : mType(_type), mComponentId(0), mReady(false), mFailed(false), mPriority(0), + mInterfacePriority(0) + { + // Check if type is "host" - the candidate is ready in this case + if (_type == Host) + mReady = true; + memset(mFoundation, 0, sizeof mFoundation); + } + + ~Candidate() + {} + + // Sets local and external address simultaneously + void setLocalAndExternalAddresses(std::string& ip, unsigned short portNumber); + void setLocalAndExternalAddresses(NetworkAddress& addr); + void setLocalAndExternalAddresses(NetworkAddress &addr, unsigned short altPort); + + // Returns type of candidate as string - 'host', 'reflexive' or 'relayed' + const char* type(); + + // Computes priority value basing on members and type priority list + void computePriority(int* typepreflist); + + // Updates foundation value depending on members + void computeFoundation(); + + // Returns SDP line for this candidate + std::string createSdp(); + + // Creates ICECandidate instance based on SDP line + static Candidate parseSdp(const char* sdp); + + // Returns candidate type basing on string type representation + static Type typeFromString(const char* candtype); + + // Compares if two candidates are equal + static bool equal(Candidate& cand1, Candidate& cand2); + + bool operator == (const Candidate& rhs) const; + void dump(std::ostream& output); + int component(); + }; + +}; +#endif diff --git a/src/libs/ice/ICECandidatePair.cpp b/src/libs/ice/ICECandidatePair.cpp new file mode 100644 index 00000000..a1f32d58 --- /dev/null +++ b/src/libs/ice/ICECandidatePair.cpp @@ -0,0 +1,223 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEPlatform.h" +#include "ICECandidatePair.h" +#include "ICEBinding.h" +#include "ICERelaying.h" +#include "ICELog.h" +#include + +using namespace ice; +#define LOG_SUBSYSTEM "ICE" +CandidatePair::CandidatePair() +:mPriority(0), mState(CandidatePair::Frozen), mControlledIndex(0), mControllingIndex(1), +mNomination(Nomination_None), mRole(Regular), mTransaction(NULL) +{ + memset(mFoundation, 0, sizeof mFoundation); +} + +CandidatePair::CandidatePair(const CandidatePair& src) +:mPriority(src.mPriority), mState(src.mState), mControlledIndex(src.mControlledIndex), +mControllingIndex(src.mControllingIndex), mNomination(src.mNomination), +mRole(src.mRole), mTransaction(src.mTransaction) +{ + mCandidate[0] = src.mCandidate[0]; + mCandidate[1] = src.mCandidate[1]; + memcpy(mFoundation, src.mFoundation, sizeof mFoundation); +} + +CandidatePair& CandidatePair::operator = (const CandidatePair& src) +{ + mPriority = src.mPriority; + mState = src.mState; + memcpy(mFoundation, src.mFoundation, sizeof mFoundation); + mControlledIndex = src.mControlledIndex; + mControllingIndex = src.mControllingIndex; + mNomination = src.mNomination; + mTransaction = src.mTransaction; + mRole = src.mRole; + mCandidate[0] = src.mCandidate[0]; + mCandidate[1] = src.mCandidate[1]; + return *this; +} + +CandidatePair::~CandidatePair() +{ +} + +const char* CandidatePair::stateToString(State s) +{ + switch (s) + { + case Waiting: return "Waiting"; + case InProgress: return "InProgress"; + case Succeeded: return "Succeeded"; + case Failed: return "Failed"; + case Frozen: return "Frozen"; + } + return "UNEXPECTED"; +} + +const char* CandidatePair::nominationToString(ice::CandidatePair::Nomination n) +{ + switch (n) + { + case Nomination_None: return "nomination:none"; + case Nomination_Started: return "nomination:started"; + case Nomination_Finished: return "nomination:finished"; + } + return "nomination:bad"; +} + +void CandidatePair::updatePriority() +{ + unsigned int G = mCandidate[mControllingIndex].mPriority; + unsigned int D = mCandidate[mControlledIndex].mPriority; + // As RFC says... + mPriority = 0xFFFFFFFF * MINVALUE(G, D) + 2*MAXVALUE(G,D) + ((G>D)?1:0); + + // ICELogDebug(<< "G=" << G << ", D=" << D << ", priority=" << mPriority); +} + +void CandidatePair::updateFoundation() +{ + // Get a combination of controlling and controlled foundations + strcpy(mFoundation, mCandidate[mControlledIndex].mFoundation); + strcat(mFoundation, mCandidate[mControlledIndex].mFoundation); +} + +bool CandidatePair::operator == (const CandidatePair& rhs) const +{ + return this->mCandidate[0] == rhs.mCandidate[0] && this->mCandidate[1] == rhs.mCandidate[1]; +} + +const char* CandidatePair::roleToString(Role r) +{ + switch (r) + { + case Regular: return "regular"; + case Triggered: return "triggered"; + case Valid: return "valid"; + case None: return "none"; + } + return "UNEXPECTED"; +} + +std::string CandidatePair::toStdString() +{ + char result[256]; + + sprintf(result, "(%s%s) %s %s -> %s %s ", roleToString(mRole), nominationToString(mNomination), + mCandidate[0].type(), mCandidate[0].mLocalAddr.toStdString().c_str(), mCandidate[1].type(), + mCandidate[1].mExternalAddr.toStdString().c_str()); + + return result; +} + +bool CandidatePair::isLanOnly() const +{ + return first().mLocalAddr.isLAN() && + second().mExternalAddr.isLAN(); +} + +CandidatePair::Role CandidatePair::role() const +{ + return mRole; +}; + +void CandidatePair::setRole(Role role) +{ + mRole = role; +} + +CandidatePair::Nomination CandidatePair::nomination() const +{ + return mNomination; +} + +void CandidatePair::setNomination(ice::CandidatePair::Nomination n) +{ + mNomination = n; +} + +const char* CandidatePair::foundation() const +{ + return mFoundation; +}; + +void CandidatePair::setFoundation(const char* foundation) +{ + strcpy(mFoundation, foundation); +} + +CandidatePair::State CandidatePair::state() const +{ + return mState; +} + +void CandidatePair::setState(CandidatePair::State state) +{ + mState = state; +} + +int64_t CandidatePair::priority() const +{ + return mPriority; +} + +void CandidatePair::setPriority(int64_t priority) +{ + mPriority = priority; +} + +Candidate& CandidatePair::first() +{ + return mCandidate[0]; +} + +const Candidate& CandidatePair::first() const +{ + return mCandidate[0]; +} + +Candidate& CandidatePair::second() +{ + return mCandidate[1]; +} + +const Candidate& CandidatePair::second() const +{ + return mCandidate[1]; +} +unsigned CandidatePair::controlledIndex() +{ + return mControlledIndex; +} + +void CandidatePair::setControlledIndex(unsigned index) +{ + mControlledIndex = index; +} + +unsigned CandidatePair::controllingIndex() +{ + return mControllingIndex; +} + +void CandidatePair::setControllingIndex(unsigned index) +{ + mControllingIndex = index; +} + +void* CandidatePair::transaction() +{ + return mTransaction; +} + +void CandidatePair::setTransaction(void* t) +{ + mTransaction = t; +} diff --git a/src/libs/ice/ICECandidatePair.h b/src/libs/ice/ICECandidatePair.h new file mode 100644 index 00000000..0fdff4ae --- /dev/null +++ b/src/libs/ice/ICECandidatePair.h @@ -0,0 +1,113 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_CANDIDATE_PAIR_H +#define __ICE_CANDIDATE_PAIR_H + +#include "ICEPlatform.h" +#include "ICECandidate.h" +#include "ICEByteBuffer.h" +#include "ICESmartPtr.h" + +namespace ice +{ + class CandidatePair + { + public: + /// Possible pair states + enum State + { + Waiting = 0, + InProgress, + Succeeded, + Failed, + Frozen + }; + + enum Role + { + None = 0, + Regular = 1, + Triggered = 2, + Valid = 3 + }; + + enum Nomination + { + Nomination_None, + Nomination_Started, + Nomination_Finished + }; + + static const char* stateToString(State s); + static const char* nominationToString(Nomination n); + + + protected: + /// Local and remote candidates. First (zero index) is local candidate, second (index one) is remote candidate + Candidate mCandidate[2]; + + /// Pair's priority, computed in UpdatePriority() method + int64_t mPriority; + + /// Pair's state + State mState; + + /// Index of controlled candidate in mCandidate array + int mControlledIndex; + + /// Index of controlling candidate in mCandidate array + int mControllingIndex; + + /// Combination of controlled and controlling candidates foundations, computed in UpdateFoundation() method. + char mFoundation[65]; + + /// Marks nominated pair + Nomination mNomination; + + /// Mark pair role - regular, triggered, valid, nominated + Role mRole; + void* mTransaction; + + static const char* roleToString(Role r); + + public: + CandidatePair(); + CandidatePair(const CandidatePair& src); + ~CandidatePair(); + + Candidate& first(); + const Candidate& first() const; + Candidate& second(); + const Candidate& second() const; + + int64_t priority() const; + void setPriority(int64_t priority); + State state() const; + void setState(State state); + const char* foundation() const; + void setFoundation(const char* foundation); + Role role() const; + void setRole(Role role); + Nomination nomination() const; + void setNomination(Nomination n); + unsigned controlledIndex(); + void setControlledIndex(unsigned index); + unsigned controllingIndex(); + void setControllingIndex(unsigned index); + void updatePriority(); + void updateFoundation(); + std::string toStdString(); + bool isLanOnly() const; + + void* transaction(); + void setTransaction(void* t); + CandidatePair& operator = (const CandidatePair& rhs); + bool operator == (const CandidatePair& rhs) const; + }; + + typedef std::shared_ptr PCandidatePair; +} +#endif diff --git a/src/libs/ice/ICECheckList.cpp b/src/libs/ice/ICECheckList.cpp new file mode 100644 index 00000000..ac30fcb0 --- /dev/null +++ b/src/libs/ice/ICECheckList.cpp @@ -0,0 +1,436 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEPlatform.h" +#include "ICECheckList.h" +#include "ICENetworkHelper.h" +#include "ICELog.h" + +#include +#include +#include +#include + +using namespace ice; +#define LOG_SUBSYSTEM "ICE" + +const char* CheckList::stateToString(int state) +{ + switch (state) + { + case Running: return "Running"; + case Completed: return "Completed"; + case Failed: return "Failed"; + } + return "Undefined"; +} +CheckList::CheckList() +:mState(CheckList::Running) +{ +} + +CheckList::State CheckList::state() +{ + return mState; +} + +void CheckList::setState(CheckList::State state) +{ + mState = state; +} + +CheckList::PairList& CheckList::pairlist() +{ + return mPairList; +} + +static bool ComparePairByPriority(const PCandidatePair& pair1, const PCandidatePair& pair2) +{ + return pair1->priority() > pair2->priority(); +} + +void CheckList::pruneDuplicates() +{ + // Remove duplicates + for (PairList::iterator pairIter = mPairList.begin(); pairIter != mPairList.end(); pairIter++) + { + PCandidatePair& pair = *pairIter; + + // Get the iterator to next element + PairList::iterator nextPairIter = pairIter; std::advance(nextPairIter, 1); + + // Iterate next elements to find duplicates + while (nextPairIter != mPairList.end()) + { + PCandidatePair& nextPair = *nextPairIter; + + bool sameType = pair->first().mLocalAddr.family() == nextPair->second().mLocalAddr.family(); + bool sameAddress = pair->second().mExternalAddr == nextPair->second().mExternalAddr; + bool relayed1 = pair->first().mType == Candidate::ServerRelayed; + bool relayed2 = nextPair->first().mType == Candidate::ServerRelayed; + bool sameRelayed = relayed1 == relayed2; +#ifdef ICE_SMART_PRUNE_CHECKLIST + if (sameType && sameAddress && sameRelayed) +#else + if (equalCandidates && sameAddress && sameRelayed) +#endif + nextPairIter = mPairList.erase(nextPairIter); + else + nextPairIter++; + } + } + +} + +void CheckList::prune(int /*checkLimit*/) +{ + // Sort list by priority + std::sort(mPairList.begin(), mPairList.end(), ComparePairByPriority); + + // Replace server reflexive candidates with bases + for (unsigned ci=0; cifirst().mType == Candidate::ServerReflexive) + pair->first().mType = Candidate::Host; + } + + /* +#ifdef _WIN32 + Win32Preprocess(); +#endif + */ + + pruneDuplicates(); + + // Erase all relayed checks to LAN candidates + PairList::iterator pairIter = mPairList.begin(); + while (pairIter != mPairList.end()) + { + PCandidatePair& pair = *pairIter; + if (pair->first().mType == Candidate::ServerRelayed && !pair->second().mExternalAddr.isPublic()) + pairIter = mPairList.erase(pairIter); + else + pairIter++; + } + +#ifndef ICE_LOOPBACK_SUPPORT + pairIter = mPairList.begin(); + while (pairIter != mPairList.end()) + { + PCandidatePair& pair = *pairIter; + if (pair->second().mExternalAddr.isLoopback()) + pairIter = mPairList.erase(pairIter); + else + pairIter++; + } +#endif + +#ifdef ICE_SKIP_LINKLOCAL + pairIter = mPairList.begin(); + while (pairIter != mPairList.end()) + { + PCandidatePair& pair = *pairIter; + if (pair->second().mExternalAddr.isLinkLocal()) + pairIter = mPairList.erase(pairIter); + else + pairIter++; + } +#endif + pruneDuplicates(); + +#ifdef ICE_POSTPONE_RELAYEDCHECKS + postponeRelayed(); +#endif + + // Put all LAN checks before other. + // Therefore it should be priorities sorting should be enough. + // But in answer's SDP remote peer can put external IP to the top of the list + // It can cause its promote to the top of list of connectivity checks + std::sort(mPairList.begin(), mPairList.end(), [](const PCandidatePair& p1, const PCandidatePair& p2) -> bool + { + return p1->isLanOnly() && !p2->isLanOnly(); + }); + + // Cut all checks that are behind the limit + if (mPairList.size() > ICE_CONNCHECK_LIMIT) + { + ICELogDebug(<<"Cut extra connection checks. The total number of checks should not exceed " << ICE_CONNCHECK_LIMIT); + PairList::iterator bcIter = mPairList.begin(); + std::advance(bcIter, ICE_CONNCHECK_LIMIT); + mPairList.erase(bcIter, mPairList.end()); + } +} + +void CheckList::win32Preprocess() +{ + for (unsigned i=0; itoStdString()); + + if (pair->first().mType == Candidate::Host) + { + // Get best source interface for remote candidate + NetworkAddress bestInterface = NetworkHelper::instance().sourceInterface(pair->second().mExternalAddr); + + // Replace IP address to found + if (!bestInterface.isEmpty()) + pair->first().mLocalAddr.setIp(bestInterface.ip()); + else + ICELogDebug(<<"Failed to find source interface for remote candidate"); + } + } +} + +PCandidatePair CheckList::findEqualPair(CandidatePair& _pair, ComparisionType ct) +{ + for (PCandidatePair& p: mPairList) + { + if (p->role() != CandidatePair::None) + { + switch (ct) + { + case CT_TreatHostAsUniform: + if (p->first().mType == Candidate::Host && _pair.first().mType == Candidate::Host && p->second() == _pair.second()) + return p; + if (p->first().mLocalAddr == _pair.first().mLocalAddr && p->first().mType == Candidate::Host && p->second() == _pair.second() && _pair.first().mType != Candidate::ServerRelayed) + return p; + if (_pair == *p) + return p; + + break; + + case CT_Strict: + if (_pair == *p) + return p; + break; + } + } + } + + return PCandidatePair(); +} + +unsigned CheckList::add(CandidatePair& p) +{ + mPairList.push_back(PCandidatePair(new CandidatePair(p))); + + // Sort list by priority + std::sort(mPairList.begin(), mPairList.end(), ComparePairByPriority); + + return (unsigned)mPairList.size(); +} + +unsigned CheckList::count() +{ + return (unsigned)mPairList.size(); +} +std::string CheckList::toStdString() +{ + std::string dump = ""; + for (size_t i=0; itoStdString(); + dump += "\n"; + } + + return dump; +} + +PCandidatePair& CheckList::operator[] (size_t index) +{ + return mPairList[index]; +} + +PCandidatePair CheckList::findNominatedPair(int component) +{ + for (PCandidatePair& p: mPairList) + { + if (p->first().component() == component && + p->role() != CandidatePair::None && + p->nomination() == CandidatePair::Nomination_Finished) + return p; + } + return PCandidatePair(); +} + +PCandidatePair CheckList::findValidPair(int component) +{ + for (PCandidatePair& p: mPairList) + { + if (p->first().component() == component && + p->role() == CandidatePair::Valid) + return p; + } + return PCandidatePair(); +} + +PCandidatePair CheckList::findBestValidPair(int componentId) +{ + PairList found; + std::copy_if(mPairList.begin(), mPairList.end(), std::back_inserter(found), + [componentId](const PCandidatePair& p) -> bool + { + return (p->first().component() == componentId && + p->role() == CandidatePair::Valid && + p->first().mExternalAddr.isLAN() && + p->second().mExternalAddr.isLAN()); + }); + + if (found.size()) + return found.front(); + + return findValidPair(componentId); +} + +PCandidatePair CheckList::findHighestNominatedPair(int component) +{ +#ifdef ICE_POSTPONE_RELAYEDCHECKS + PairList found; + for (PCandidatePair& p: mPairList) + { + if (p->first().component() == component && + p->role() != CandidatePair::None && + p->nomination() == CandidatePair::Nomination_Finished && + p->first().mType != Candidate::ServerRelayed && + p->second().mType != Candidate::ServerRelayed) + found.push_back( p ); + } + + if (found.size()) + { + PCandidatePair& f0 = found.front(); + for (PCandidatePair& p: mPairList) + if (p == f0) + return p; + } +#endif + int64_t priority = -1; + PCandidatePair result; + + std::ostringstream oss; + oss << "Looking for highest nominated pair in list:"; + for (PCandidatePair& p: mPairList) + { + oss << "\n " << p->toStdString().c_str() << ", priority " << p->priority(); + + if (p->first().component() == component && + p->role() != CandidatePair::None && + p->nomination() == CandidatePair::Nomination_Finished && + p->priority() > priority ) + { + result = p; + priority = p->priority(); + } + } + + // ICELogDebug( << oss.str() ); + + if (result) + { + ICELogDebug(<< "Result is " << result->toStdString()); + } + else + { + // ICELogDebug(<< "No nominated pair"); + } + return result; +} + +void CheckList::removePairs(CandidatePair::State state, int component) +{ + for (unsigned i=0; ifirst().component() == component && + p->role() != CandidatePair::None && + p->nomination() == CandidatePair::Nomination_Finished && + p->priority() < priority ) + { + result = p; + priority = p->priority(); + } + } + + return result; +} + +void CheckList::updatePairPriorities() +{ + for (unsigned i=0; iupdatePriority(); +} + +void CheckList::clear() +{ + mState = Running; + mPairList.clear(); +} + +void CheckList::dump(std::ostream& output) +{ + output << Logger::TabPrefix << Logger::TabPrefix << "State: " << CheckList::stateToString(mState) << std::endl; + for (unsigned i=0; irole() != CandidatePair::None) + output << Logger::TabPrefix << Logger::TabPrefix << mPairList[i]->toStdString().c_str() << std::endl; +} + +unsigned CheckList::countOfValidPairs() +{ + unsigned result = 0; + for (unsigned i=0; irole() >= CandidatePair::Valid) + result++; + return result; +} + +void CheckList::postponeRelayed() +{ + PairList relayed, relayedTarget; + + PairList::iterator pairIter = mPairList.begin(); + while ( pairIter != mPairList.end() ) + { + PCandidatePair& p = *pairIter; + if (p->first().mType == Candidate::ServerRelayed) + { + relayed.push_back(p); + pairIter = mPairList.erase( pairIter ); + } + else + if (p->second().mType == Candidate::ServerRelayed) + { + relayedTarget.push_back(p); + pairIter = mPairList.erase( pairIter ); + } + else + pairIter++; + } + + for (pairIter = relayedTarget.begin(); pairIter != relayedTarget.end(); pairIter++) + mPairList.push_back(*pairIter); + + for (pairIter = relayed.begin(); pairIter != relayed.end(); pairIter++) + mPairList.push_back(*pairIter); +} diff --git a/src/libs/ice/ICECheckList.h b/src/libs/ice/ICECheckList.h new file mode 100644 index 00000000..9e30c5b0 --- /dev/null +++ b/src/libs/ice/ICECheckList.h @@ -0,0 +1,102 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_CHECK_LIST_H +#define __ICE_CHECK_LIST_H + +#include "ICEPlatform.h" +#include "ICECandidatePair.h" +#include "ICESmartPtr.h" +#include + +namespace ice +{ + class CheckList + { + public: + enum State + { + Running = 0, + Completed, + Failed + }; + static const char* stateToString(int state); + typedef std::vector PairList; + + protected: + /// Check list state + State mState; + + /// Vector of pairs + PairList mPairList; + + void pruneDuplicates(); + void postponeRelayed(); + + public: + CheckList(); + + State state(); + void setState(State state); + PairList& pairlist(); + + /// Sorts check list, prunes from duplicate pairs and cuts to checkLimit number of elements. + void prune(int checkLimit); + + /// Replaces local host candidates IP addresses with best source interface. + void win32Preprocess(); + + /// Finds&returns smart pointer to pair + enum ComparisionType + { + CT_TreatHostAsUniform, + CT_Strict + }; + PCandidatePair findEqualPair(CandidatePair& p, ComparisionType ct); + + /// Add&sort + unsigned add(CandidatePair& p); + + /// Returns number of pairs in list + unsigned count(); + + /// Returns items of list + //ICECandidatePair operator[] (size_t index) const; + PCandidatePair& operator[] (size_t index); + + /// Dumps check list to string + std::string toStdString(); + + /// Updates state of list based on items state + void updateState(); + + /// Find first nominated pair for specified component ID + PCandidatePair findNominatedPair(int componentID); + + /// Finds valid pair for specified component ID. It is used for valid lists only. + PCandidatePair findValidPair(int componentID); + + /// Finds best valid pair for specified component ID. 'Best' means to prefer 1) LAN addresses 2) reflexive addresses 3)relayed addresses is low priority + PCandidatePair findBestValidPair(int componentId); + + /// Finds nominated pair with highest priority and specified component ID + PCandidatePair findHighestNominatedPair(int componentID); + + /// Finds nominated pair with highest priority and specified component ID + PCandidatePair findLowestNominatedPair(int componentID); + + /// Removes from list pairs with specified state and component ID. + void removePairs(CandidatePair::State state, int componentID); + + /// Recomputes pair priorities + void updatePairPriorities(); + + void clear(); + void dump(std::ostream& output); + unsigned countOfValidPairs(); + }; + +} +#endif diff --git a/src/libs/ice/ICEError.cpp b/src/libs/ice/ICEError.cpp new file mode 100644 index 00000000..5722c08f --- /dev/null +++ b/src/libs/ice/ICEError.cpp @@ -0,0 +1,84 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEError.h" + +using namespace ice; + +std::string ErrorInfo::errorMsg(int errorCode) +{ + switch (errorCode) + { + case 403: return "(Forbidden): The request was valid, but cannot be performed due \ + to administrative or similar restrictions."; + + case 437: return "(Allocation Mismatch): A request was received by the server that \ + requires an allocation to be in place, but there is none, or a \ + request was received which requires no allocation, but there is \ + one."; + + case 441: return "(Wrong Credentials): The credentials in the (non-Allocate) \ + request, though otherwise acceptable to the server, do not match \ + those used to create the allocation."; + + case 442: return "(Unsupported Transport Protocol): The Allocate request asked the \ + server to use a transport protocol between the server and the peer \ + that the server does not support. NOTE: This does NOT refer to \ + the transport protocol used in the 5-tuple."; + + case 486: return "(Allocation Quota Reached): No more allocations using this \ + username can be created at the present time."; + + case 508: return "(Insufficient Capacity): The server is unable to carry out the \ + request due to some capacity limit being reached. In an Allocate \ + response, this could be due to the server having no more relayed \ + transport addresses available right now, or having none with the \ + requested properties, or the one that corresponds to the specified \ + reservation token is not available."; + } + + return "Unknown error."; + +} + +Exception::Exception(int errorCode, std::string errorMsg) +:mErrorCode(errorCode), mSubcode(0), mErrorMsg(errorMsg) +{ +} + +Exception::Exception(int code) + :mErrorCode(code), mSubcode(0) +{ +} + +Exception::Exception(int code, int subcode) + :mErrorCode(code), mSubcode(subcode) +{ + +} + +Exception::Exception(const Exception& src) +:mErrorCode(src.mErrorCode), mErrorMsg(src.mErrorMsg) +{ +} + +Exception::~Exception() +{ +} + +int Exception::code() +{ + return mErrorCode; +} + +int Exception::subcode() +{ + return mSubcode; +} + +std::string Exception::message() +{ + return mErrorMsg; +} diff --git a/src/libs/ice/ICEError.h b/src/libs/ice/ICEError.h new file mode 100644 index 00000000..d2c008e3 --- /dev/null +++ b/src/libs/ice/ICEError.h @@ -0,0 +1,57 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_ERROR_H +#define __ICE_ERROR_H + +#include + +namespace ice +{ + + class ErrorInfo + { + public: + static std::string errorMsg(int errorCode); + + }; + + enum + { + GETIFADDRS_FAILED = 1, + WRONG_CANDIDATE_TYPE, + UDP_SUPPORTED_ONLY, + NOT_ENOUGH_DATA, + CANNOT_FIND_INTERFACES, + NO_PRIORITY_ATTRIBUTE, + CANNOT_FIND_ATTRIBUTE, + UNKNOWN_ATTRIBUTE, + WRONG_IP_ADDRESS + }; + + class Exception + { + public: + + Exception(int code, std::string msg); + Exception(int code); + Exception(int code, int subcode); + + Exception(const Exception& src); + ~Exception(); + + int code(); + int subcode(); + std::string message(); + + protected: + int mErrorCode; + int mSubcode; + std::string mErrorMsg; + }; + +} + +#endif diff --git a/src/libs/ice/ICEEvent.h b/src/libs/ice/ICEEvent.h new file mode 100644 index 00000000..1c69c58d --- /dev/null +++ b/src/libs/ice/ICEEvent.h @@ -0,0 +1,62 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_EVENT_H +#define __ICE_EVENT_H + +namespace ice +{ + class Stack; + + class StageHandler + { + public: + // Fires when candidates are gathered + virtual void onGathered(Stack* stack, void* tag) = 0; + + // Fires when connectivity checks finished ok + virtual void onSuccess(Stack* stack, void* tag) = 0; + + // Fires when connectivity checks failed (timeout usually) + virtual void onFailed(Stack* stack, void* tag) = 0; + }; + + class ChannelBoundCallback + { + public: + virtual ~ChannelBoundCallback() {} + virtual void onChannelBound(int /*stream*/, int /*component*/, int /*error*/) {} + }; + + class InstallPermissionsCallback + { + public: + virtual ~InstallPermissionsCallback() {} + virtual void onPermissionsInstalled(int /*stream*/, int /*component*/, int /*error*/) {} + }; + + class DeletePermissionsCallback + { + public: + virtual ~DeletePermissionsCallback() {} + virtual void onPermissionsDeleted(int /*stream*/, int /*component*/, int /*error*/) {} + }; + + class DeleteAllocationCallback + { + public: + virtual ~DeleteAllocationCallback() {} + virtual void onAllocationDeleted(int /*stream*/, int /*component*/, int /*error*/) {} + }; + + class RefreshAllocationCallback + { + public: + virtual ~RefreshAllocationCallback(); + virtual void onAllocationRefreshed(int /*stream*/, int /*component*/, int /*error*/) {} + }; +} + +#endif diff --git a/src/libs/ice/ICEHMAC.cpp b/src/libs/ice/ICEHMAC.cpp new file mode 100644 index 00000000..acffaea1 --- /dev/null +++ b/src/libs/ice/ICEHMAC.cpp @@ -0,0 +1,65 @@ +//****************************************************************************** +//* HMAC_SHA1.cpp : Implementation of HMAC SHA1 algorithm +//* Comfort to RFC 2104 +//* +//****************************************************************************** + +#include +#include +#include "ICEHMAC.h" +#include "ICESHA1.h" + +void ICEHMAC::GetDigest(unsigned char *text, int text_len, unsigned char *key, int key_len, unsigned char *digest) +{ + memset(SHA1_Key, 0, SHA1_BLOCK_SIZE); + + /* repeated 64 times for values in ipad and opad */ + memset(m_ipad, 0x36, sizeof(m_ipad)); + memset(m_opad, 0x5c, sizeof(m_opad)); + + /* STEP 1 */ + if (key_len > SHA1_DIGEST_LENGTH) + { + ICESHA1::Reset(); + ICESHA1::Update((UINT_8 *)key, key_len); + ICESHA1::Final(); + + ICESHA1::GetHash((UINT_8 *)SHA1_Key); + } + else + memcpy(SHA1_Key, key, key_len); + + /* STEP 2 */ + for (int i=0; i +*/ + +#ifndef __ICE_HMAC_H +#define __ICE_HMAC_H + +#include "ICESHA1.h" + +class ICEHMAC: public ICESHA1 +{ +private: + unsigned char m_ipad[64]; + unsigned char m_opad[64]; + + unsigned char * szReport ; + unsigned char * SHA1_Key ; + unsigned char * AppendBuf1 ; + unsigned char * AppendBuf2 ; + + +public: + enum { + SHA1_DIGEST_LENGTH = 20, + SHA1_BLOCK_SIZE = 64, + HMAC_BUF_LEN = 4096 + } ; + + ICEHMAC() + :szReport(new unsigned char[HMAC_BUF_LEN]), + AppendBuf1(new unsigned char[HMAC_BUF_LEN]), + AppendBuf2(new unsigned char[HMAC_BUF_LEN]), + SHA1_Key(new unsigned char[HMAC_BUF_LEN]) + { + } + + ~ICEHMAC() + { + delete[] szReport ; + delete[] AppendBuf1 ; + delete[] AppendBuf2 ; + delete[] SHA1_Key ; + } + + void GetDigest(unsigned char *text, int text_len, unsigned char* key, int key_len, unsigned char *digest); +}; + + +#endif /* __HMAC_SHA1_H__ */ diff --git a/src/libs/ice/ICEIosSupport.h b/src/libs/ice/ICEIosSupport.h new file mode 100644 index 00000000..3616674d --- /dev/null +++ b/src/libs/ice/ICEIosSupport.h @@ -0,0 +1,18 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_IOS_SUPPORT_H +#define __ICE_IOS_SUPPORT_H + +#include +#include "ICEAddress.h" + +namespace ice +{ + int getIosIp(int networkType, int family, char* adress); + int fillIosInterfaceList(int family, int networkType, std::vector& output); +} + +#endif \ No newline at end of file diff --git a/src/libs/ice/ICEIosSupport.mm b/src/libs/ice/ICEIosSupport.mm new file mode 100644 index 00000000..a87fc9c1 --- /dev/null +++ b/src/libs/ice/ICEIosSupport.mm @@ -0,0 +1,224 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEIosSupport.h" +#include "ICENetworkHelper.h" +#include +#include +#include +#include +#import + +#import +#include "TargetConditionals.h" +#include "ICEAddress.h" +#include "ICELog.h" +#include "ICENetworkHelper.h" + +#define LOG_SUBSYSTEM "ICE" + +namespace ice +{ + + typedef enum { + ConnectionTypeUnknown, + ConnectionTypeNone, + ConnectionType3G, + ConnectionTypeWiFi + } ConnectionType; + + + ConnectionType FindConnectionType(int family) + { + SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, family == AF_INET ? "8.8.8.8" : "2001:4860:4860::8888"); + SCNetworkReachabilityFlags flags; + BOOL success = SCNetworkReachabilityGetFlags(reachability, &flags); + CFRelease(reachability); + if (!success) { + return ConnectionTypeUnknown; + } + BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0); + BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0); + BOOL isNetworkReachable = (isReachable && !needsConnection); + + if (!isNetworkReachable) { + return ConnectionTypeNone; + } else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) { + return ConnectionType3G; + } else { + return ConnectionTypeWiFi; + } + } + +int fillIosInterfaceList(int family, int networkType, std::vector& output) +{ + if (networkType == NetworkHelper::NetworkType_None) + { + switch (FindConnectionType(family)) + { + case ConnectionTypeNone: + return 0; + + case ConnectionType3G: + networkType = NetworkHelper::NetworkType_3G; + break; + + case ConnectionTypeWiFi: + networkType = NetworkHelper::NetworkType_WiFi; + break; + + default: + break; + } + } + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + struct ifaddrs *interfaces = NULL; + struct ifaddrs *temp_addr = NULL; + + // retrieve the current interfaces - returns 0 on success + if(!getifaddrs(&interfaces)) + { + // Loop through linked list of interfaces + for (temp_addr = interfaces; temp_addr != NULL; temp_addr = temp_addr->ifa_next) + { + sa_family_t sa_type = temp_addr->ifa_addr->sa_family; + + if (sa_type == family) + { + NSString* name = [NSString stringWithUTF8String: temp_addr->ifa_name]; + + if (networkType != NetworkHelper::NetworkType_None) + { + bool wifi = [name rangeOfString: @"en"].location == 0; + bool cell = [name rangeOfString: @"pdp_ip"].location == 0; + /*bool vpn = [name rangeOfString: @"tun"].location == 0 || [name rangeOfString: @"tap"].location == 0;*/ + + switch (networkType) + { + case NetworkHelper::NetworkType_3G: + if (wifi) // Skip wifi addresses here. Use cell and vpn addresses here. + continue; + break; + + case NetworkHelper::NetworkType_WiFi: + if (cell) // Skip cell addresses here. Use other addresses - wifi and vpn. + continue; + break; + + default: + break; + } + } + + ice::NetworkAddress addr; + if (sa_type == AF_INET6) + addr = ice::NetworkAddress(((sockaddr_in6*)temp_addr->ifa_addr)->sin6_addr, 1000); + else + addr = ice::NetworkAddress(((sockaddr_in*)temp_addr->ifa_addr)->sin_addr, 1000); + + //ICELogDebug(<< "Found: " << addr.toStdString()); + + if (!addr.isLoopback() && !addr.isLinkLocal()) + output.push_back(addr); + } + + } + // Free memory + freeifaddrs(interfaces); + } + + [pool release]; + return 0; +} + +int getIosIp(int networkType, int family, char* address) +{ + assert(address); + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + struct ifaddrs *interfaces = NULL; + struct ifaddrs *temp_addr = NULL; + NSString *wifiAddress = nil; + NSString *cellAddress = nil; + + // retrieve the current interfaces - returns 0 on success + if(!getifaddrs(&interfaces)) + { + // Loop through linked list of interfaces + temp_addr = interfaces; + while(temp_addr != NULL) + { + sa_family_t sa_type = temp_addr->ifa_addr->sa_family; + + if (sa_type == family) + { + NSString* name = [NSString stringWithUTF8String: temp_addr->ifa_name]; + char buffer[128]; + if (sa_type == AF_INET6) + inet_ntop(AF_INET6, &((sockaddr_in6*)temp_addr->ifa_addr)->sin6_addr, buffer, sizeof(buffer)); + else + inet_ntop(AF_INET, &((sockaddr_in*)temp_addr->ifa_addr)->sin_addr, buffer, sizeof(buffer)); + + NSString* addr = [NSString stringWithUTF8String: buffer]; + + if([name rangeOfString: @"en"].location == 0) + { + // Interface is the wifi connection on the iPhone + wifiAddress = addr; + } + else + if([name isEqualToString: @"pdp_ip0"]) + { + // Interface is the cell connection on the iPhone + cellAddress = addr; + } + else + if ([name rangeOfString: @"tun"].location == 0 || [name rangeOfString: @"tap"].location == 0) + { + wifiAddress = addr; + } + } + temp_addr = temp_addr->ifa_next; + } + // Free memory + freeifaddrs(interfaces); + } + + NSString* currentAddr = nil; + switch (networkType) + { + case ice::NetworkHelper::NetworkType_None: + currentAddr = wifiAddress ? wifiAddress : cellAddress; + break; + + case ice::NetworkHelper::NetworkType_WiFi: + currentAddr = wifiAddress; + break; + + case ice::NetworkHelper::NetworkType_3G: + currentAddr = cellAddress; + break; + } + + if (currentAddr) + strcpy(address, [currentAddr UTF8String]); + else + if (wifiAddress) + strcpy(address, [wifiAddress UTF8String]); + else + if (cellAddress) + strcpy(address, [cellAddress UTF8String]); + else + strcpy(address, "127.0.0.1"); + + [pool release]; + + return 0; +} + +} diff --git a/src/libs/ice/ICELog.cpp b/src/libs/ice/ICELog.cpp new file mode 100644 index 00000000..eb21b2de --- /dev/null +++ b/src/libs/ice/ICELog.cpp @@ -0,0 +1,251 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICELog.h" +#include "ICETime.h" +#include "ICESync.h" +#include +#include +#include +#include +#if defined(__ANDROID_API__) +# include +#endif + +using namespace ice; + +ice::Logger ice::GLogger; +const char* ice::Logger::TabPrefix = " "; + +Logger::Logger() +:mStream(nullptr) +{ + mFile = nullptr; + mUseDebugWindow = false; + mDelegate = nullptr; + mLevel = LL_DEBUG; +} + +Logger::~Logger() +{ + //LogGuard l(mGuard); + if (mFile) + { + fclose(mFile); + mFile = NULL; + } +} + +void +Logger::useDebugWindow(bool enable) +{ + LogGuard l(mGuard); + + mUseDebugWindow = enable; +} + +void +Logger::useFile(const char* filepath) +{ + LogGuard l(mGuard); + + mLogPath = filepath ? filepath : ""; + if (mLogPath.empty()) + return; + + FILE* f = fopen(filepath, "at"); + if (f) + { + if (mFile) + fclose(mFile); + mFile = f; + } + + if (f) + { + fprintf(f, "New log chunk starts here.\n"); + fflush(f); + } +} + +void +Logger::useNull() +{ + LogGuard l(mGuard); + + mUseDebugWindow = false; + if (mFile) + { + fflush(mFile); + fclose(mFile); + mFile = NULL; + } + + mDelegate = NULL; +} + +void Logger::closeFile() +{ + LogGuard l(mGuard); + if (mFile) + { + fflush(mFile); + fclose(mFile); + mFile = nullptr; + } +} + +void Logger::openFile() +{ + LogGuard l(mGuard); + if (mLogPath.empty()) + return; + + remove(mLogPath.c_str()); + useFile(mLogPath.c_str()); +} + + +void Logger::useDelegate(LogHandler* delegate_) +{ + mDelegate = delegate_; +} + +LogGuard& Logger::mutex() +{ + return mGuard; +} + +LogLevel Logger::level() +{ + return mLevel; +} + +void Logger::setLevel(LogLevel level) +{ + mLevel = level; +} + +void Logger::beginLine(LogLevel level, const char* filename, int linenumber, const char* subsystem) +{ + mMsgLevel = level; + mStream = new std::ostringstream(); + +#ifdef WIN32 + const char* filenamestart = strrchr(filename, '\\'); +#else + const char* filenamestart = strrchr(filename, '/'); +#endif + if (!filenamestart) + filenamestart = filename; + else + filenamestart++; + + mFilename = filenamestart; + mLine = linenumber; + mSubsystem = subsystem; + + //*mStream << std::setw(8) << ICETimeHelper::timestamp() << " | " << std::setw(8) << ThreadInfo::currentThread() << " | " << std::setw(30) << filenamestart << " | " << std::setw(4) << linenumber << " | " << std::setw(12) << subsystem << " | "; +} + +void +Logger::endLine() +{ + *mStream << std::endl; + *mStream << std::flush; + mStream->flush(); + + std::ostringstream result; + result << std::setw(8) << ICETimeHelper::timestamp() << " | " << std::setw(8) << ThreadInfo::currentThread() << " | " << std::setw(30) << mFilename.c_str() << " | " << std::setw(4) << mLine << " | " << std::setw(12) << mSubsystem.c_str() << " | " << mStream->str().c_str(); + + std::string t = result.str(); + if (mUseDebugWindow) +#ifdef TARGET_WIN + OutputDebugStringA(t.c_str()); +#elif defined(TARGET_ANDROID) + if (t.size() > 512) + { + std::string cut = t; cut.erase(480); // Erase tail of string + cut += "\r\n... [cut]"; + __android_log_print(ANDROID_LOG_INFO, "VoipAgent", "%s", cut.c_str()); + } + else { + __android_log_print(ANDROID_LOG_INFO, "VoipAgent", "%s", t.c_str()); + } +#else + std::cerr << result.str() << std::endl << std::flush; +#endif + if (mFile) + { + fprintf(mFile, "%s", result.str().c_str()); + fflush(mFile); + } + if (mDelegate) + mDelegate->onIceLog(mMsgLevel, mFilename, mLine, mSubsystem, mStream->str()); + + delete mStream; mStream = NULL; +} + +Logger& +Logger::operator << (const char* data) +{ + *mStream << data; + + return *this; +} + +Logger& +Logger::operator << (const wchar_t* data) +{ + *mStream << data; + + return *this; +} + +Logger& +Logger::operator << (const int data) +{ + *mStream << data; + + return *this; +} + +Logger& +Logger::operator << (const float data) +{ + *mStream << data; + + return *this; +} + +Logger& +Logger::operator<<(const int64_t data) +{ + *mStream << data; + return *this; +} + +Logger& +Logger::operator<<(const unsigned int data) +{ + *mStream << data; + return *this; +} + + +Logger& +Logger::operator<<(const uint64_t data) +{ + *mStream << data; + return *this; +} + + +Logger& +Logger::operator << (const std::string& data) +{ + *mStream << data.c_str(); + return *this; +} diff --git a/src/libs/ice/ICELog.h b/src/libs/ice/ICELog.h new file mode 100644 index 00000000..92302f21 --- /dev/null +++ b/src/libs/ice/ICELog.h @@ -0,0 +1,163 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_LOG_H +#define __ICE_LOG_H + +#include +#include + +#ifdef _WIN32 +# include +# include +#endif + +#include "ICEPlatform.h" +#include "ICETypes.h" +#include "ICEEvent.h" + +namespace ice +{ + // Defines log levels + enum LogLevel + { + LL_NONE = -1, + LL_CRITICAL = 0, + LL_INFO = 1, + LL_DEBUG = 2, + LL_MEDIA = 3 + }; + + class LogHandler + { + public: + virtual void onIceLog(LogLevel level, const std::string& filename, int line, const std::string& subsystem, const std::string& msg) = 0; + }; + +#ifdef _WIN32 + class LogGuard + { + public: + LogGuard() { ::InitializeCriticalSection(&mCS); } + ~LogGuard() { ::DeleteCriticalSection(&mCS); } + void Lock() { ::EnterCriticalSection(&mCS); } + void Unlock() { ::LeaveCriticalSection(&mCS); } + + protected: + CRITICAL_SECTION mCS; + }; + + class LogLock + { + public: + LogLock(LogGuard& g) :mGuard(g) { mGuard.Lock(); } + ~LogLock() { mGuard.Unlock(); } + + protected: + LogGuard& mGuard; + }; +#else + class LogGuard + { + public: + LogGuard() { ::pthread_mutex_init(&mMutex, NULL); } + ~LogGuard() { ::pthread_mutex_destroy(&mMutex); } + void Lock() { ::pthread_mutex_lock(&mMutex); } + void Unlock() { ::pthread_mutex_unlock(&mMutex); } + + protected: + pthread_mutex_t mMutex; + }; + + class LogLock + { + public: + LogLock(LogGuard& g) :mGuard(g) { mGuard.Lock(); } + ~LogLock() { mGuard.Unlock(); } + + protected: + LogGuard& mGuard; + }; + +#endif + + class Logger + { + public: + static const char* TabPrefix; + + Logger(); + ~Logger(); + + void useDebugWindow(bool enable); + void useFile(const char* filepath); + void useDelegate(LogHandler* delegate_); + void useNull(); + void closeFile(); + void openFile(); + + LogGuard& mutex(); + LogLevel level(); + void setLevel(LogLevel level); + void beginLine(LogLevel level, const char* filename, int linenumber, const char* subsystem); + void endLine(); + + Logger& operator << (const char* data); + Logger& operator << (const wchar_t* data); + Logger& operator << (const int data); + Logger& operator << (const float data); + Logger& operator << (const std::string& data); + Logger& operator << (const int64_t data); + Logger& operator << (const unsigned int data); + Logger& operator << (const uint64_t data); + + protected: + LogGuard mGuard; + FILE* mFile; + std::string mLogPath; + + bool mUseDebugWindow; + LogHandler* mDelegate; + LogLevel mLevel; + std::ostringstream* mStream; + + LogLevel mMsgLevel; + std::string mFilename; + int mLine; + std::string mSubsystem; + }; + + +extern Logger GLogger; + + +#define ICELog(level_, subsystem_, args_)\ + {do\ + {\ + if (GLogger.level() >= level_)\ + {\ + LogLock l(GLogger.mutex());\ + GLogger.beginLine(level_, __FILE__, __LINE__, subsystem_);\ + GLogger args_;\ + GLogger.endLine();\ + }\ + } while (false);} + +#define ICELogCritical(args_) ICELog(LL_CRITICAL, LOG_SUBSYSTEM, args_) +#define ICELogInfo(args_) ICELog(LL_INFO, LOG_SUBSYSTEM, args_) +#define ICELogDebug(args_) ICELog(LL_DEBUG, LOG_SUBSYSTEM, args_) +#define ICELogMedia(args_) ICELog(LL_MEDIA, LOG_SUBSYSTEM, args_) + + +/* +#define ICELogCritical(args_) +#define ICELogInfo(args_) +#define ICELogDebug(args_) +#define ICELogMedia(args_) +*/ + +} //end of namespace + +#endif diff --git a/src/libs/ice/ICEMD5.cpp b/src/libs/ice/ICEMD5.cpp new file mode 100644 index 00000000..8a1f4bc1 --- /dev/null +++ b/src/libs/ice/ICEMD5.cpp @@ -0,0 +1,305 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEMD5.h" + +using namespace ice; + +#ifdef USE_CRYPTOPP + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "../CryptoPP/md5.h" +using namespace CryptoPP; + +void ice::md5Bin(const void* inputData, size_t inputSize, void* digest) +{ + Weak::MD5 md5; + md5.Update((const byte*)inputData, inputSize); + + md5.Final((byte*)digest); +} + +#elif defined(USE_OPENSSL) + +#ifdef USE_FIPS +typedef unsigned int MD5_u32plus; + +typedef struct { + MD5_u32plus lo, hi; + MD5_u32plus a, b, c, d; + unsigned char buffer[64]; + MD5_u32plus block[16]; +} MD5_CTX; + +#include + +/* + * The basic MD5 functions. + * + * F and G are optimized compared to their RFC 1321 definitions for + * architectures that lack an AND-NOT instruction, just like in Colin Plumb's + * implementation. + */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) + +/* + * The MD5 transformation for all four rounds. + */ +#define STEP(f, a, b, c, d, x, t, s) \ +(a) += f((b), (c), (d)) + (x) + (t); \ +(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ +(a) += (b); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + * + * The check for little-endian architectures that tolerate unaligned + * memory accesses is just an optimization. Nothing will break if it + * doesn't work. + */ +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define SET(n) \ +(*(MD5_u32plus *)&ptr[(n) * 4]) +#define GET(n) \ +SET(n) +#else +#define SET(n) \ +(ctx->block[(n)] = \ +(MD5_u32plus)ptr[(n) * 4] | \ +((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ +((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ +((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) +#define GET(n) \ +(ctx->block[(n)]) +#endif + +/* + * This processes one or more 64-byte data blocks, but does NOT update + * the bit counters. There are no alignment requirements. + */ +static void *body(MD5_CTX *ctx, void *data, unsigned long size) +{ + unsigned char *ptr; + MD5_u32plus a, b, c, d; + MD5_u32plus saved_a, saved_b, saved_c, saved_d; + + ptr = (unsigned char*)data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + + /* Round 1 */ + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) + + /* Round 2 */ + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) + + /* Round 3 */ + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) + STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) + STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) + STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) + STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) + STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) + STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) + STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) + STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) + + /* Round 4 */ + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while (size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + return ptr; +} + +void MD5_Init(MD5_CTX *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + + ctx->lo = 0; + ctx->hi = 0; +} + +void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) +{ + MD5_u32plus saved_lo; + unsigned long used, free; + + saved_lo = ctx->lo; + if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) + ctx->hi++; + ctx->hi += size >> 29; + + used = saved_lo & 0x3f; + + if (used) { + free = 64 - used; + + if (size < free) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, free); + data = (unsigned char *)data + free; + size -= free; + body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = body(ctx, data, size & ~(unsigned long)0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + +void MD5_Final(unsigned char *result, MD5_CTX *ctx) +{ + unsigned long used, free; + + used = ctx->lo & 0x3f; + + ctx->buffer[used++] = 0x80; + + free = 64 - used; + + if (free < 8) { + memset(&ctx->buffer[used], 0, free); + body(ctx, ctx->buffer, 64); + used = 0; + free = 64; + } + + memset(&ctx->buffer[used], 0, free - 8); + + ctx->lo <<= 3; + ctx->buffer[56] = ctx->lo; + ctx->buffer[57] = ctx->lo >> 8; + ctx->buffer[58] = ctx->lo >> 16; + ctx->buffer[59] = ctx->lo >> 24; + ctx->buffer[60] = ctx->hi; + ctx->buffer[61] = ctx->hi >> 8; + ctx->buffer[62] = ctx->hi >> 16; + ctx->buffer[63] = ctx->hi >> 24; + + body(ctx, ctx->buffer, 64); + + result[0] = ctx->a; + result[1] = ctx->a >> 8; + result[2] = ctx->a >> 16; + result[3] = ctx->a >> 24; + result[4] = ctx->b; + result[5] = ctx->b >> 8; + result[6] = ctx->b >> 16; + result[7] = ctx->b >> 24; + result[8] = ctx->c; + result[9] = ctx->c >> 8; + result[10] = ctx->c >> 16; + result[11] = ctx->c >> 24; + result[12] = ctx->d; + result[13] = ctx->d >> 8; + result[14] = ctx->d >> 16; + result[15] = ctx->d >> 24; + + memset(ctx, 0, sizeof(*ctx)); +} + +#else +#include +#endif + +void ice::md5Bin(const void* inputData, size_t inputSize, void* digest) +{ + MD5_CTX md5; + MD5_Init(&md5); +#ifdef USE_FIPS + MD5_Update(&md5, (void*)inputData, inputSize); +#else + MD5_Update(&md5, (const unsigned char*)inputData, inputSize); +#endif + MD5_Final((unsigned char*)digest, &md5); +} + +#endif diff --git a/src/libs/ice/ICEMD5.h b/src/libs/ice/ICEMD5.h new file mode 100644 index 00000000..5704161a --- /dev/null +++ b/src/libs/ice/ICEMD5.h @@ -0,0 +1,15 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_MD5_H +#define __ICE_MD5_H + +#include + +namespace ice +{ + extern void md5Bin(const void* inputData, size_t inputSize, void* digest ); +} +#endif \ No newline at end of file diff --git a/src/libs/ice/ICENetworkHelper.cpp b/src/libs/ice/ICENetworkHelper.cpp new file mode 100644 index 00000000..2fd29183 --- /dev/null +++ b/src/libs/ice/ICENetworkHelper.cpp @@ -0,0 +1,484 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICENetworkHelper.h" +#include "ICEPlatform.h" +#include "ICELog.h" +#include +#include +#include +#include +#include + +#ifdef TARGET_WIN +# include +# if defined(WINDOWS_RT) +# include "ICEWinRtSupport.h" +# endif +#else +#if defined(TARGET_IOS) +# include "ICEIosSupport.h" +#endif +# include +# if defined(TARGET_ANDROID) || defined(TARGET_LINUX) +# include +# endif +#endif + +#include "ICEError.h" +using namespace ice; + +#define LOG_SUBSYSTEM "ICE" + +#if defined(TARGET_WIN) && !defined(WINDOWS_RT) +class IPHlpApi +{ +public: + HMODULE mHandle; + DWORD (WINAPI *pGetBestInterfaceEx) (struct sockaddr* pDestAddr, PDWORD pdwBestIfIndex); + DWORD (WINAPI *pGetBestInterface) (IPAddr dwDestAddr, PDWORD pdwBestIfIndex); + ULONG (WINAPI *pGetAdaptersAddresses) (ULONG Family, ULONG Flags, PVOID Reserved, PIP_ADAPTER_ADDRESSES AdapterAddresses, PULONG SizePointer); + + void ResolveProc(const char* name, FARPROC& proc) + { + proc = GetProcAddress(mHandle, name); + } + +public: + IPHlpApi() + { + pGetBestInterfaceEx = NULL; + pGetBestInterface = NULL; + pGetAdaptersAddresses = NULL; + mHandle = ::LoadLibraryW(L"iphlpapi.dll"); + if (mHandle) + { + ResolveProc("GetBestInterfaceEx", (FARPROC&)pGetBestInterfaceEx); + ResolveProc("GetBestInterface", (FARPROC&)pGetBestInterface); + ResolveProc("GetAdaptersAddresses", (FARPROC&)pGetAdaptersAddresses); + } + } + + ~IPHlpApi() + { + if (mHandle) + FreeLibrary(mHandle); + } + +}; +IPHlpApi IPHelper; +#endif + +NetworkHelper::NetworkHelper() +{ + reload(NetworkType_None); +} + +NetworkHelper::~NetworkHelper() +{ +} + +void NetworkHelper::reload(int networkType) +{ + Lock l(mInstanceGuard); + + // Get list of interfaces +#if defined(TARGET_WIN) && !defined(WINDOWS_RT) + mInterfaceList.clear(); + mIP2IndexList.clear(); + + DWORD dwRet, dwSize; + DWORD flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER; + IP_ADAPTER_ADDRESSES* ipAdapters = NULL; + dwRet = IPHelper.pGetAdaptersAddresses(AF_INET, flags, NULL, NULL, &dwSize); + if (dwRet == ERROR_BUFFER_OVERFLOW) + { + ipAdapters = (IP_ADAPTER_ADDRESSES*)malloc(dwSize); + if (!ipAdapters) + return; + + dwRet = IPHelper.pGetAdaptersAddresses(AF_INET, flags, NULL, ipAdapters, &dwSize); + if (dwRet != ERROR_SUCCESS) + { + free(ipAdapters); + throw Exception(CANNOT_FIND_INTERFACES); + } + processAdaptersList(ipAdapters); + free(ipAdapters); + } + +#ifdef ICE_IPV6SUPPORT + dwRet = IPHelper.pGetAdaptersAddresses(AF_INET6, flags, NULL, NULL, &dwSize); + if (dwRet == ERROR_BUFFER_OVERFLOW) + { + ipAdapters = (IP_ADAPTER_ADDRESSES*)malloc(dwSize); + if (!ipAdapters) + return; + + dwRet = IPHelper.pGetAdaptersAddresses(AF_INET6, flags, NULL, ipAdapters, &dwSize); + if (dwRet != ERROR_SUCCESS) + { + free(ipAdapters); + throw NetworkAddress(CANNOT_FIND_INTERFACES); + } + processAdaptersList(ipAdapters); + free(ipAdapters); + } +#endif + + for (unsigned i=0; iifa_addr->sa_family) + { + case AF_INET: + // just for debug + // printf("%s", inet_ntoa(reinterpret_cast(current->ifa_addr)->sin_addr)); + addr.setIp(reinterpret_cast(current->ifa_addr)->sin_addr); +#ifndef ICE_LOOPBACK_SUPPORT + handleIt = !addr.isLoopback(); +#endif +#ifdef ICE_SKIP_LINKLOCAL + handleIt &= !addr.isLinkLocal(); +#endif + if (handleIt) + mIPList.push_back(addr); + break; + +#ifdef ICE_IPV6SUPPORT + case AF_INET6: + addr.setIp(reinterpret_cast(current->ifa_addr)->sin6_addr); +#ifndef ICE_LOOPBACK_SUPPORT + if (!addr.isLoopback()) +#endif + mIPList.push_back(addr); + break; +#endif + } + current = current->ifa_next; + } + freeifaddrs(il); + } +#endif +#endif +} + +#if defined(TARGET_WIN) && !defined(WINDOWS_RT) +void NetworkHelper::processAdaptersList(IP_ADAPTER_ADDRESSES* addresses) +{ + IP_ADAPTER_ADDRESSES *AI; + int i; + for (i = 0, AI = addresses; AI != NULL; AI = AI->Next, i++) + { + for (PIP_ADAPTER_UNICAST_ADDRESS unicast = AI->FirstUnicastAddress; unicast; unicast = unicast->Next) + { +#ifdef ICE_IPV6SUPPORT + if (unicast->Address.lpSockaddr->sa_family != AF_INET && unicast->Address.lpSockaddr->sa_family != AF_INET6) + continue; +#else + if (unicast->Address.lpSockaddr->sa_family != AF_INET) + continue; +#endif + IP2Index rec; + rec.mIP = NetworkAddress(*unicast->Address.lpSockaddr, unicast->Address.iSockaddrLength); + rec.mIndex = AI->IfIndex; + mIP2IndexList.push_back(rec); + } + } +} + +#endif + +Mutex& NetworkHelper::guard() +{ + return mInstanceGuard; +} + +std::vector& NetworkHelper::interfaceList() +{ +#if defined(TARGET_WIN) && !defined(WINDOWS_RT) + return mInterfaceList; +#else + return mIPList; +#endif +} + + + +NetworkAddress NetworkHelper::sourceInterface(const NetworkAddress& remoteIP) +{ + //Lock l(mInstanceGuard); + + if (remoteIP.isLoopback()) + return remoteIP.family() == AF_INET ? NetworkAddress::LoopbackAddress4 : NetworkAddress::LoopbackAddress6; + +#if defined(TARGET_WIN) && !defined(WINDOWS_RT) + if (IPHelper.pGetBestInterfaceEx) + { + DWORD index = 0; + DWORD rescode = IPHelper.pGetBestInterfaceEx(remoteIP.genericsockaddr(), &index); + if (rescode == NO_ERROR) + return ipInterfaceByIndex(index); + } + else + if (IPHelper.pGetBestInterface) + { + DWORD index = 0; + DWORD rescode = IPHelper.pGetBestInterface(remoteIP.sockaddr4()->sin_addr.S_un.S_addr, &index); + if (rescode == NO_ERROR) + return ipInterfaceByIndex(index); + } + #ifdef ICE_LOOPBACK_SUPPORT + return NetworkAddress::LoopbackAddress4; + #else + return remoteIP; + #endif + +#elif defined(WINDOWS_RT) + std::vector& il = interfaceList(); + if (il.size()) + return il.front(); + else + return NetworkAddress(); +#else + if (remoteIP.isLoopback()) + return remoteIP; + +/*#if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) + // There is only one interface - return it + std::vector& il = interfaceList(); + if (il.size()) + { + if (!il.front().isZero()) + return il.front(); + } + +#endif*/ + + // Here magic goes. + // 1) Check if remoteIP is IP4 or IP6 + // 2) Check if it is LAN or loopback or internet address + // 3) For LAN address - try to find interface from the same network + // For Loopback address - return loopback address + // For internet address - find default interface + + //printf("remote ip %s\n", remoteIP.GetIP().c_str()); + if (remoteIP.isLAN()) + { + for (unsigned i=0; i +#include + +#ifdef _WIN32 +# include +# include +#else +# include +#endif + +namespace ice +{ + + class NetworkHelper + { + public: + NetworkHelper(); + ~NetworkHelper(); + + enum + { + NetworkType_None, + NetworkType_WiFi, + NetworkType_3G + }; + + Mutex& guard(); + + /* Returns list of IP4 interfaces installed in system. */ + std::vector& interfaceList(); + + bool hasIPv4() const; + bool hasIPv6() const; + + /* Finds source interface for specified remote address. */ + NetworkAddress sourceInterface(const NetworkAddress& remoteIP); + + void reload(int networkType); + + static NetworkHelper& instance(); + static void destroyInstance(); + + static void NetworkToHost(const in6_addr& addr6, uint32_t* output); + static void HostToNetwork(const uint32_t* input, in6_addr& output); + + protected: +#ifdef _WIN32 + struct IP2Index + { + NetworkAddress mIP; + DWORD mIndex; + }; + std::vector mIP2IndexList; + std::vector mInterfaceList; + + void processAdaptersList(IP_ADAPTER_ADDRESSES* addresses); + NetworkAddress ipInterfaceByIndex(int index); +#else + std::vector mIPList; +#endif + static NetworkHelper* mInstance; + static Mutex mGuard; + Mutex mInstanceGuard; + }; + +}; + +#endif diff --git a/src/libs/ice/ICEPacketTimer.cpp b/src/libs/ice/ICEPacketTimer.cpp new file mode 100644 index 00000000..797598aa --- /dev/null +++ b/src/libs/ice/ICEPacketTimer.cpp @@ -0,0 +1,94 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEPlatform.h" +#include "ICEPacketTimer.h" +#include "ICETime.h" + +using namespace ice; +PacketScheduler::PacketScheduler() +{ + mTimestamp = 0; + mAttemptCounter = 0; + mInitialRTO = 100; + mLastRTO = 100; +} + +PacketScheduler::~PacketScheduler() +{ +} + +void PacketScheduler::setInitialRTO(int value) +{ + mInitialRTO = value; +} + +int PacketScheduler::initialRTO() +{ + return mInitialRTO; +} + +void PacketScheduler::start() +{ + mLastRTO = mInitialRTO; + mAttemptCounter = 0; + mTimestamp = 0;//ICETimeHelper::timestamp(); +} + +void PacketScheduler::stop() +{ + ; +} + +bool PacketScheduler::isTimeToRetransmit() +{ + if (!mTimestamp) + { + mTimestamp = ICETimeHelper::timestamp(); + return true; + } + + unsigned currentTime = ICETimeHelper::timestamp(); + unsigned delta = ICETimeHelper::findDelta(mTimestamp, currentTime); + + return delta >= mLastRTO; +} + +/// Instructs timer that attempt made +void PacketScheduler::attemptMade() +{ + // Increase attempt counter + mAttemptCounter++; + + // Save new timestamp + mTimestamp = ICETimeHelper::timestamp(); + + // Increase mLastRTO +#ifndef ICE_SIMPLE_SCHEDULE + mLastRTO *= 2; +#endif +} + +/// Checks if attempt limit reached +bool PacketScheduler::isAttemptLimitReached() +{ + return mAttemptCounter >= ICE_TRANSACTION_RTO_LIMIT; +} + +/// Checks if timeout happens +bool PacketScheduler::isTimeout() +{ + // Are attempts to send finished? + if (!isAttemptLimitReached()) + return false; + + // Get current time + unsigned int currentTime = ICETimeHelper::timestamp(); + + // Get difference between current time and last send attempt + unsigned int delta = ICETimeHelper::findDelta(mTimestamp, currentTime); + + return delta > mLastRTO * 16; +} diff --git a/src/libs/ice/ICEPacketTimer.h b/src/libs/ice/ICEPacketTimer.h new file mode 100644 index 00000000..5fa1c0af --- /dev/null +++ b/src/libs/ice/ICEPacketTimer.h @@ -0,0 +1,43 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_PACKET_TIMER_H +#define __ICE_PACKET_TIMER_H + +namespace ice +{ + +class PacketScheduler +{ +public: + PacketScheduler(); + ~PacketScheduler(); + + void setInitialRTO(int value); + int initialRTO(); + + void start(); + void stop(); + bool isTimeToRetransmit(); + + /// Instructs timer that attempt made + void attemptMade(); + + /// Checks if attempt limit reached + bool isAttemptLimitReached(); + + /// Checks if timeout happens + bool isTimeout(); + +protected: + unsigned int mTimestamp; + unsigned int mAttemptCounter; + unsigned int mInitialRTO; + unsigned int mLastRTO; +}; + +} //end of namespace + +#endif \ No newline at end of file diff --git a/src/libs/ice/ICEPlatform.cpp b/src/libs/ice/ICEPlatform.cpp new file mode 100644 index 00000000..7f885c3f --- /dev/null +++ b/src/libs/ice/ICEPlatform.cpp @@ -0,0 +1,22 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEPlatform.h" + +#ifndef WIN32 +#include +char* strupr(char* buffer) +{ + char* result = buffer; + + while (*buffer) + { + *buffer = toupper(*buffer); + buffer++; + } + + return result; +} +#endif diff --git a/src/libs/ice/ICEPlatform.h b/src/libs/ice/ICEPlatform.h new file mode 100644 index 00000000..c4757c73 --- /dev/null +++ b/src/libs/ice/ICEPlatform.h @@ -0,0 +1,119 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_PLATFORM_H +#define __ICE_PLATFORM_H + +#define NoIndex 0xFFFFFFFF + +enum AddressFamily +{ + IPv4 = 1, + IPv6 = 2 +}; + +#ifdef _WIN32 +# include +# include +# include +# include +# define MINVALUE(X,Y) (((X)<(Y)) ? (X) : (Y)) +# define MAXVALUE(X,Y) (((X)>(Y)) ? (X) : (Y)) +#else +# include +# include +# include +# include +# include +# include +# include +# include +# define MINVALUE(X,Y) (((X)<(Y)) ? (X) : (Y)) +# define MAXVALUE(X,Y) (((X)>(Y)) ? (X) : (Y)) + +#ifndef SOCKET +typedef int SOCKET; +#endif + +extern char* strupr(char*); + +#ifndef INVALID_SOCKET +# define INVALID_SOCKET -1 +#endif + +#endif + +// TURN channel prefix +typedef unsigned short TurnPrefix; + + +// Limit of candidates per SIP offer/answer +#define ICE_CANDIDATE_LIMIT 64 + +// Limit of connection checks +#define ICE_CONNCHECK_LIMIT 100 + +// Connection checks timer interval (in milliseconds) +#define ICE_SCHEDULE_TIMER_INTERVAL 5 + +#define ICE_PERMISSIONS_REFRESH_INTERVAL 240 + +// Turns on OutputDebugString() logging +#define ICE_REALTIME_LOG + +// Enables keep-alive packets. It MUST be defined! There is only 1 reason to undefine it - debugging. +#define ICE_ENABLE_KEEPALIVE + +#define ICE_SKIP_LINKLOCAL +#define ICE_SKIP_RELAYED_CHECKS + +//#define ICE_IPV6_SUPPORT +//#define ICE_LOOPBACK_SUPPORT + +//#define ICE_DISABLE_KEEP + +// Makes check list shorter. Most checks are triggered in this case. +#define ICE_SMART_PRUNE_CHECKLIST + +// Simulates symmetric NAT behavior - stack rejects all data coming not from specified STUN/TURN servers. +//#define ICE_EMULATE_SYMMETRIC_NAT + +// Publishes more reflexive candidates than was gathered. +// The virtual candidates will have port number +1 +2 +3 ... +ICE_VIRTUAL_CANDIDATES +// +#define ICE_VIRTUAL_CANDIDATES (0) + +// Use simple model to schedule connectivity checks +//#define ICE_SIMPLE_SCHEDULE + +// Limit of packet retransmission during ice checks +#define ICE_TRANSACTION_RTO_LIMIT (10) + +#define ICE_POSTPONE_RELAYEDCHECKS + +// #define ICE_AGGRESSIVE +// Use aggressive nomination + treat requests as confirmations +// #define ICE_VERYAGGRESSIVE + +// Define to emulate network problem +//#define ICE_TEST_VERYAGGRESSIVE + +// Use this define to avoid gathering reflexive/relayed candidates for public IP address +//#define ICE_REST_ON_PUBLICIP + +// #define ICE_DONT_CANCEL_CHECKS_ON_SUCCESS + +// Defines the waiting time to accumulate valid pairs to choose best of them later. Can be zero. +#define ICE_NOMINATION_WAIT_INTERVAL (50) + +#define MAX_CLIENTCHANNELBIND_ATTEMPTS (1) + +#define ICE_CACHE_REALM_NONCE + +// Should be 1100 in normal conditions. 1000000 is for debugging +#define ICE_TIMEOUT_VALUE 1100 + + +#endif diff --git a/src/libs/ice/ICERelaying.cpp b/src/libs/ice/ICERelaying.cpp new file mode 100644 index 00000000..3101679c --- /dev/null +++ b/src/libs/ice/ICERelaying.cpp @@ -0,0 +1,417 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICERelaying.h" +#include "ICEStunAttributes.h" +#include "ICETime.h" +#include "ICEMD5.h" +#include "ICELog.h" +#include "ICEStream.h" + +using namespace ice; + +#define LOG_SUBSYSTEM "ICE" +// ------------------ ClientAllocate ----------------- + +ClientAllocate::ClientAllocate(unsigned int lifetime) +:AuthTransaction(), mLifetime(lifetime), mWireFamily(AF_INET), mAllocFamily(AF_INET) +{ + assert(lifetime > 60 || !lifetime); + setComment("ClientAllocate"); + addLongTermCredentials(true); +} + +ClientAllocate::~ClientAllocate() +{ +} + +NetworkAddress& ClientAllocate::relayedAddress() +{ + return mRelayedAddr; +} + +NetworkAddress& ClientAllocate::reflexiveAddress() +{ + return mReflexiveAddr; +} + +NetworkAddress& ClientAllocate::responseAddress() +{ + return mResponseAddr; +} + +void ClientAllocate::setInitialRequest(StunMessage& msg) +{ + if (keepalive()) + { + // Build refresh request + msg.setMessageType(ice::StunMessage::Refresh); + msg.setMessageClass(StunMessage::RequestClass); + } + else + { + // Build allocate request + msg.setMessageClass(StunMessage::RequestClass); + msg.setMessageType(StunMessage::Allocate); + + // Add UDP transport attribute (RequestedTransport is UDP by default) + msg.setAttribute(new RequestedTransport()); + + // Add request family attribute + if (mAllocFamily != mWireFamily) + msg.setAttribute(new RequestedAddressFamily(mAllocFamily == AF_INET ? IPv4 : IPv6)); + } +} + +void ClientAllocate::setAuthenticatedRequest(StunMessage& msg) +{ + if (keepalive()) + { + // Build refresh request + msg.setMessageType(ice::StunMessage::Refresh); + msg.setMessageClass(StunMessage::RequestClass); + msg.lifetimeAttr().setLifetime(mLifetime); + } + else + { + msg.setMessageClass(StunMessage::RequestClass); + msg.setMessageType(StunMessage::Allocate); + + // Add UDP transport attribute + msg.setAttribute(new RequestedTransport()); + + // Add LIFETIME + msg.lifetimeAttr().setLifetime(mLifetime); + + // Add request family attribute + if (mAllocFamily != mWireFamily) + msg.setAttribute(new RequestedAddressFamily(mAllocFamily == AF_INET ? IPv4 : IPv6)); + } +} + +void ClientAllocate::processSuccessMessage(StunMessage& msg, NetworkAddress& sourceAddress) +{ + if (msg.hasAttribute(StunAttribute::XorMappedAddress)) + mReflexiveAddr = msg.xorMappedAddressAttr().address(); + + if (msg.hasAttribute(StunAttribute::XorRelayedAddress)) + mRelayedAddr = msg.xorRelayedAddressAttr().address(); + + if (msg.hasAttribute(StunAttribute::Lifetime)) + mLifetime = msg.lifetimeAttr().lifetime(); + + mResponseAddr = sourceAddress; + ICELogDebug(<< "Allocated for " << (int)mLifetime << " seconds."); +} + +int ClientAllocate::lifetime() +{ + return mLifetime; +} + +void ClientAllocate::setWireFamily(int family) +{ + mWireFamily = family; +} + +int ClientAllocate::getWireFamily() const +{ + return mWireFamily; +} + +void ClientAllocate::setAllocFamily(int family) +{ + mAllocFamily = family; +} + +int ClientAllocate::getAllocFamily() const +{ + return mAllocFamily; +} + + +//------------------- ClientRefresh ------------------------------- +ClientRefresh::ClientRefresh(unsigned int lifetime, Stream* stream, ClientAllocate* allocate) +:AuthTransaction(), mLifetime(lifetime), mStream(stream) +{ + assert(stream); + setComment("ClientRefresh"); + addLongTermCredentials(true); + + // Copy data from Allocate transaction + if (allocate) + { + setDestination( allocate->destination() ); + setPassword( stream->mConfig.mTurnPassword ); + setUsername( stream->mConfig.mTurnUsername ); + setComponent( allocate->component() ); +#ifdef ICE_CACHE_REALM_NONCE + setRealm( allocate->realm() ); + setNonce( allocate->nonce() ); +#endif + mRelayed = allocate->relayedAddress(); + mReflexive = allocate->reflexiveAddress(); + } +} + +ClientRefresh::~ClientRefresh() +{ +} + +void ClientRefresh::setInitialRequest(StunMessage& msg) +{ + ICELogDebug(<< "Prepare to run ClientRefresh on TURN server with lifetime " << mLifetime); + msg.setMessageType(ice::StunMessage::Refresh); + msg.setMessageClass(ice::StunMessage::RequestClass); +} + +void ClientRefresh::setAuthenticatedRequest(StunMessage& msg) +{ + msg.setMessageType(StunMessage::Refresh); + msg.setMessageClass(StunMessage::RequestClass); + msg.lifetimeAttr().setLifetime(mLifetime); +} + +void ClientRefresh::processSuccessMessage(StunMessage& /*msg*/, NetworkAddress& /*sourceAddress*/) +{ + if (mLifetime) + { + ICELogDebug(<< "TURN allocation refreshed for " << (int)mLifetime << " seconds."); + } + else + { + if (mStream) + { + if (mStream->mTurnAllocated > 0) + mStream->mTurnAllocated--; + } + ICELogDebug(<< "TURN allocation is deleted."); + } +} + +void ClientRefresh::processError() +{ + if (mStream) + { + if (!mLifetime) + { + if (mStream->mTurnAllocated > 0) + mStream->mTurnAllocated--; + ICELogCritical(<< "TURN allocation is not deleted due to error " << errorCode() << " " << errorResponse()); + } + else + ICELogDebug(<< "ClientRefresh failed due to error " << errorCode() << " " << errorResponse()); + } +} + +NetworkAddress ClientRefresh::relayedAddress() +{ + return mRelayed; +} + +NetworkAddress ClientRefresh::reflexiveAddress() +{ + return mReflexive; +} + +//------------------- ClientChannelBind ---------------------------- + +static TurnPrefix GPrefix = 0; +static Mutex GPrefixGuard; +static TurnPrefix obtainNewPrefix() +{ + Lock l(GPrefixGuard); + + // Generate initial value if needed + if (!GPrefix) + GPrefix = (rand() % (0x7FFE - 0x4000)) + 0x4000; + + // Avoid logical overflow + if (GPrefix == 0x7FFE) + GPrefix = 0x4000; + + return ++GPrefix; +} + +ClientChannelBind::ClientChannelBind(const NetworkAddress& address) +:AuthTransaction(), mPeerAddress(address) +{ + setComment( "ClientChannelBind" ); + // Compute prefix + mChannelPrefix = obtainNewPrefix(); + ICELogInfo(<< "Channel prefix for TURN channel bind is " << mChannelPrefix); + addLongTermCredentials(true); +} + +ClientChannelBind::~ClientChannelBind() +{ +} + +void ClientChannelBind::setInitialRequest(StunMessage& msg) +{ + msg.setMessageClass(StunMessage::RequestClass); + msg.setMessageType(StunMessage::ChannelBind); + + msg.channelNumberAttr().setChannelNumber(mChannelPrefix); + msg.xorPeerAddressAttr().address() = mPeerAddress; +} + +void ClientChannelBind::setAuthenticatedRequest(StunMessage& msg) +{ + setInitialRequest(msg); +} + +unsigned short ClientChannelBind::channelPrefix() +{ + return mChannelPrefix; +} + +bool ClientChannelBind::processData(StunMessage& msg, NetworkAddress& address) +{ + return AuthTransaction::processData(msg, address); +} + +void ClientChannelBind::processSuccessMessage(StunMessage& msg, NetworkAddress& sourceAddress) +{ + ICELogDebug(<< mPeerAddress.toStdString() << " is bound to " << mChannelPrefix); + // Make this transaction keepalive + setKeepalive( true ); + setType( KeepAlive ); + setInterval( ICE_PERMISSIONS_REFRESH_INTERVAL ); + setTimestamp( ICETimeHelper::timestamp() ); +} + +void ClientChannelBind::processError() +{ + ICELogCritical(<< "Failed to bind channel with error " << errorCode()); +} + +NetworkAddress ClientChannelBind::peerAddress() +{ + return mPeerAddress; +} +//----------------- ClientCreatePermission ------------------------ + +ClientCreatePermission::ClientCreatePermission() +:AuthTransaction() +{ + setComment("ClientCreatePermission"); + addLongTermCredentials(true); +} + +ClientCreatePermission::~ClientCreatePermission() +{ + ; +} + +void ClientCreatePermission::addIpAddress(const NetworkAddress& ip) +{ + // Skip loopback / empty / LAN / IPv6 addresses addresses + if (!ip.isLoopback() && !ip.isEmpty() && !ip.isLAN() && ip.family() == AF_INET) + { + for (unsigned i=0; iaddress() = mIPAddressList[i]; + msg.addAttribute(xpa); + } +} + +void +ClientCreatePermission::setAuthenticatedRequest(StunMessage& msg) +{ + setInitialRequest(msg); +} + +ClientCreatePermission::IpList& ClientCreatePermission::ipList() +{ + return mIPAddressList; +} + +// ------------------ SendIndication ---------------------------------- +SendIndication::SendIndication() +{ +} + +SendIndication::~SendIndication() +{ +} + +void SendIndication::setTarget(NetworkAddress& addr) +{ + mTarget = addr; +} + +NetworkAddress& SendIndication::target() +{ + return mTarget; +} + +void SendIndication::setPlainData(ByteBuffer& plain) +{ + mPlainData = plain; +} + +ByteBuffer& SendIndication::plainData() +{ + return mPlainData; +} + +ByteBuffer* SendIndication::buildPacket() +{ + StunMessage m; + m.setMessageClass(StunMessage::IndicationClass); + m.setMessageType(StunMessage::Send); + + XorPeerAddress* xpa = new XorPeerAddress(); + xpa->address() = mTarget; + + DataAttribute* da = new DataAttribute(); + da->setData(mPlainData); + + m.setAttribute(xpa); + m.setAttribute(da); + + ByteBuffer* result = new ByteBuffer(); + m.buildPacket(*result, ""); + + return result; +} + +ByteBuffer* SendIndication::buildPacket(NetworkAddress& target, ByteBuffer& data, NetworkAddress& relay, int component) +{ + SendIndication si; + si.setTarget( target ); + si.setPlainData( data ); + + ByteBuffer* result = si.buildPacket(); + result->setComponent( component ); + result->setRemoteAddress( relay ); + + return result; +} diff --git a/src/libs/ice/ICERelaying.h b/src/libs/ice/ICERelaying.h new file mode 100644 index 00000000..061b2018 --- /dev/null +++ b/src/libs/ice/ICERelaying.h @@ -0,0 +1,136 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_RELAYING_H +#define __ICE_RELAYING_H + +#include "ICEStunTransaction.h" +#include "ICEAddress.h" +#include "ICEAuthTransaction.h" +#include "ICEBinding.h" + +namespace ice +{ + const int ChannelBindTimeout = 10 * 60 * 1000; + const int PermissionTimeout = 5 * 60 * 1000; + + // This class encapsulates TURN Allocate transaction + // Usage: create instance, set password and login, generate data. + // pass incoming data while GetState() != StunTransaction::Failed or Success + + class ClientAllocate: public AuthTransaction + { + public: + ClientAllocate(unsigned int lifetime); + virtual ~ClientAllocate(); + + NetworkAddress& relayedAddress(); + NetworkAddress& reflexiveAddress(); + NetworkAddress& responseAddress(); + int lifetime(); + void setWireFamily(int family); + int getWireFamily() const; + void setAllocFamily(int family); + int getAllocFamily() const; + + virtual void setInitialRequest(StunMessage& msg); + virtual void setAuthenticatedRequest(StunMessage& msg); + virtual void processSuccessMessage(StunMessage& msg, NetworkAddress& sourceAddress); + + protected: + NetworkAddress mRelayedAddr; + NetworkAddress mReflexiveAddr; + NetworkAddress mResponseAddr; + unsigned int mLifetime; + int mWireFamily; + int mAllocFamily; + }; + + class ClientChannelBind: public AuthTransaction + { + public: + ClientChannelBind(const NetworkAddress& peerAddress); + virtual ~ClientChannelBind(); + + /*Channel prefix must be 0x4000 through 0x7FFF: These values are the allowed channel + numbers (16,383 possible values) + */ + unsigned short channelPrefix(); + + void setInitialRequest(StunMessage& msg); + void setAuthenticatedRequest(StunMessage& msg); + void processSuccessMessage(StunMessage& msg, NetworkAddress& sourceAddress); + bool processData(StunMessage& msg, NetworkAddress& address); + void processError(); + NetworkAddress peerAddress(); + + protected: + unsigned short mChannelPrefix; + NetworkAddress mPeerAddress; + }; + + class ClientCreatePermission: public AuthTransaction + { + public: + typedef std::vector IpList; + + ClientCreatePermission(); + virtual ~ClientCreatePermission(); + + void addIpAddress(const NetworkAddress& ip); + + virtual void setInitialRequest(StunMessage& msg); + virtual void setAuthenticatedRequest(StunMessage& msg); + virtual void processSuccessMessage(StunMessage& msg, NetworkAddress& sourceAddress); + + IpList& ipList(); + + protected: + IpList mIPAddressList; + }; + + struct Stream; + class ClientRefresh: public AuthTransaction + { + public: + ClientRefresh(unsigned int lifetime, Stream* stream, ClientAllocate* allocate = NULL); + virtual ~ClientRefresh(); + + virtual void setInitialRequest(StunMessage& msg); + virtual void setAuthenticatedRequest(StunMessage& msg); + virtual void processSuccessMessage(StunMessage& msg, NetworkAddress& sourceAddress); + virtual void processError(); + unsigned int lifetime() { return mLifetime; } + NetworkAddress relayedAddress(); + NetworkAddress reflexiveAddress(); + + protected: + unsigned int mLifetime; + Stream* mStream; + NetworkAddress mRelayed, mReflexive; + }; + + class SendIndication + { + public: + SendIndication(); + ~SendIndication(); + + void setTarget(NetworkAddress& addr); + NetworkAddress& target(); + void setPlainData(ByteBuffer& plain); + ByteBuffer& plainData(); + + ByteBuffer* buildPacket(); + + static ByteBuffer* buildPacket(NetworkAddress& target, ByteBuffer& data, NetworkAddress& relay, int component); + + protected: + NetworkAddress mTarget; + ByteBuffer mPlainData; + }; + +} +#endif \ No newline at end of file diff --git a/src/libs/ice/ICEReliableTransport.cpp b/src/libs/ice/ICEReliableTransport.cpp new file mode 100644 index 00000000..752e6ef0 --- /dev/null +++ b/src/libs/ice/ICEReliableTransport.cpp @@ -0,0 +1,446 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEReliableTransport.h" +#include "ICETypes.h" +#include +using namespace ICEImpl; + +//------------------- ReliableTransport::Packet -------------------------- +ReliableTransport::Packet::Packet() +{ + mType = AppData; + mSeqno = 0; + mAppSeqno = 0; +} + +ReliableTransport::Packet::~Packet() +{ +} + +bool +ReliableTransport::Packet::parse(const void* dataptr, int datasize, Encryption* encryption) +{ + assert(encryption != NULL); + assert(dataptr != NULL); + assert(datasize != 0); + + // 1) Check if packet has mEncryption->GetBlockSize() bytes boundary + if (datasize % encryption->blockSize()) + return false; + + // 2) Save data + mData.enqueueBuffer(dataptr, datasize); + + // 2) Decrypt it using mEncryption provider + encryption->decrypt(mData.mutableData(), mData.size()); + + // 3) Check CRC from first 4 bytes (it is for little endian only) + unsigned crc = mData.dequeueUInt(); + if (crc != encryption->crc(mData.data(), mData.size())) + return false; + + // 4) Check next byte for signature + unsigned char signature = mData.dequeueUChar(); + if (signature != RTSignature) + return false; + + // 5) Next 2 bits are type of packet - AppData, Confirmation, Request or Ack + unsigned short ts = mData.dequeueUShort(); + + mType = (Packet::Type)((ts & 0xC000) >> 14); + + // 6) Next 14 bits are real size of packet + unsigned short realsize = ts & 0x3FFF; + + // 7) Seqno + mSeqno = mData.dequeueUShort(); + + // 7) Check if we deal with AppData + if (mType == AppData) + mAppSeqno = mData.dequeueUShort(); + + // 8) Truncate app data to real size + mData.truncate(realsize); + return true; +} + +void +ReliableTransport::Packet::build(const void* dataptr, int datasize, Encryption* encryption) +{ + assert(encryption && dataptr && datasize); + + mData.clear(); + + // Reserve place for CRC + mData.enqueueUInt(0); + + // Signature + mData.enqueueUChar(RTSignature); + + // Real size and type of packet + unsigned short ts = (unsigned short)datasize; + ts |= mType << 14; + + // Enqueue real size and type of packet + mData.enqueueUShort(ts); + + // Enqueue sequence number + mData.enqueueUShort(mSeqno); + + // Enqueue application sequence number if needed + if (mType == Packet::AppData) + mData.enqueueUShort(mAppSeqno); + + // Enqueue payload data + mData.enqueueBuffer(dataptr, datasize); + + // Padding with zero bytes + int tail = mData.size() % encryption->blockSize(); + if (tail) + { + for (int i=0; i < encryption->blockSize() - tail; i++) + mData.enqueueUChar(0); + } + + // Get CRC on packet + unsigned crc = encryption->crc((const char*)mData.data() + 4, mData.size() - 4); + + crc = htonl(crc); //It is here as corresponding DequeueUInt does ntohl + memcpy(mData.mutableData(), &crc, 4); + + // Encrypt + encryption->encrypt(mData.mutableData(), mData.size()); +} + +void ReliableTransport::Packet::setType(Type packetType) +{ + mType = packetType; +} + +ReliableTransport::Packet::Type ReliableTransport::Packet::type() +{ + return mType; +} + +void ReliableTransport::Packet::setSeqno(unsigned short seqno) +{ + mSeqno = seqno; +} + +unsigned short ReliableTransport::Packet::seqno() +{ + return mSeqno; +} + +void ReliableTransport::Packet::setAppSeqno(unsigned short seqno) +{ + mAppSeqno = seqno; +} + +unsigned short ReliableTransport::Packet::appSeqno() +{ + return mAppSeqno; +} + +ICEByteBuffer& ReliableTransport::Packet::data() +{ + return mData; +} +//-------------------- ReliableTransport -------------------- + +ReliableTransport::ReliableTransport() +{ + mEncryption = NULL; + mSeqno = 0; +} + +ReliableTransport::~ReliableTransport() +{ +} + +void ReliableTransport::setMaxDatagram(int size) +{ + mMaxDatagramSize = size; +} + + +int ReliableTransport::maxDatagram() +{ + return mMaxDatagramSize; +} + +bool ReliableTransport::processIncoming(const void* dataptr, int datasize) +{ + Packet* p = new Packet(); + if (p->parse(dataptr, datasize, mEncryption)) + { + switch (p->type()) + { + case Packet::AppData: + processAppData(p); + break; + + case Packet::Confirmation: + processConfirmation(p); + break; + + case Packet::Ack: + processAck(p); + break; + + case Packet::Request: + processRequest(p); + break; + } + + return true; + } + else + { + delete p; + return false; + } +} + +void +ReliableTransport::queueOutgoing(const void *dataPtr, int dataSize) +{ + // Split enqueued data to datagrams using mMaxDatagramSize value. + // Do not forget about service bytes - seqno, appseqno, CRC, signature... + int payloadsize = this->mMaxDatagramSize - (2 /*CRC*/ + 1 /* signature */ + 2 /* type and size */); + + // Find packet count + int packetcount = dataSize / payloadsize; + if (dataSize % payloadsize) + packetcount++; + + // Case input pointer + const char* dataIn = (const char*)dataPtr; + + // Split data to packets + for (int i=0; isetSeqno(mSeqno++); + p->setAppSeqno(i); + if (i == packetcount-1 && dataSize % payloadsize) + p->build(dataIn + i * payloadsize, dataSize % payloadsize, mEncryption); + else + p->build(dataIn + i * payloadsize, payloadsize, mEncryption); + + mOutgoingData.push_back(p); + } +} + +void +ReliableTransport::processAck(Packet* p) +{ + // Ack received for confirmation + int count = p->data().dequeueUShort(); + for (int i=0; idata().dequeueUShort(); + + // Find corresponding confirmation packet and remove it + removePacket(seqno); + } + + delete p; +} + +void +ReliableTransport::processConfirmation(Packet* p) +{ + int count = p->data().dequeueUShort(); + for (int i=0; idata().dequeueUShort(); + + // Find corresponding AppData packet and remove it + removePacket(seqno); + } + + // Create Ack packet + mOutgoingData.push_back(makeAckPacket(p->seqno())); + + delete p; +} + +void +ReliableTransport::processRequest(Packet* p) +{ + int count = p->data().dequeueUShort(); + for (int i=0; idata().dequeueUShort(); + + // Find specified by seqno packet and move to top of list + prioritizePacket(seqno); + } + + delete p; +} + +void +ReliableTransport::processAppData(Packet* p) +{ + // 1) Add seqno to confirmation list + mConfirmationData.push_back(p->seqno()); + + // 2) Check if confirmation list if big enough to transmit confirmation packet + if (mConfirmationData.size() >= (unsigned)MaxConfirmationQueue) + { + mOutgoingData.push_back(makeConfirmationPacket(mConfirmationData)); + mConfirmationData.clear(); + } + + // 3) Move packet to mIncomingAppData with optional packet assembling + mIncomingAppData.push_back(p); +} + +void +ReliableTransport::removePacket(Packet::Seqno seqno) +{ + PacketList::iterator pit = mOutgoingData.begin(); + while (pit != mOutgoingData.end()) + { + Packet* p = *pit; + + if (p->seqno() == seqno) + { + pit = mOutgoingData.erase(pit); + delete p; + } + else + pit++; + } +} + +void +ReliableTransport::prioritizePacket(Packet::Seqno seqno) +{ + PacketList::iterator pit = mOutgoingData.begin(); + while (pit != mOutgoingData.end()) + { + Packet* p = *pit; + + if (p->seqno() == seqno) + { + // Remove pointer from old index + pit = mOutgoingData.erase(pit); + + // Insert at beginning of queue + mOutgoingData.insert(mOutgoingData.begin(), p); + + // Exit from loop + break; + } + else + pit++; + } +} + +ReliableTransport::Packet* +ReliableTransport::makeAckPacket(Packet::Seqno seqno) +{ + // Create packet + Packet* p = new Packet(); + + // Set type + p->setType(Packet::Ack); + + // Convert seqno number to network byte order + unsigned short value = htons(seqno); + + // Build packet + p->build(&value, sizeof(value), mEncryption); + + // Return packet + return p; +} + +ReliableTransport::Packet* +ReliableTransport::makeConfirmationPacket(std::vector seqnovector) +{ + // Convert seqno values to network byte order + std::vector value; + for (unsigned i=0; isetType(Packet::Ack); + + // Build packet + p->build(&value[0], value.size() * sizeof(Packet::Seqno), mEncryption); + + // Return packet + return p; +} + + +bool +ReliableTransport::hasAppData() +{ + return !mIncomingAppData.empty(); +} + +unsigned ReliableTransport::appData(void* ptr) +{ + if (mIncomingAppData.empty()) + return 0; + + Packet& p = *mIncomingAppData.front(); + unsigned length = p.data().size(); + if (!ptr) + return length; + + memcpy(ptr, p.data().data(), length); + mIncomingAppData.erase(mIncomingAppData.begin()); + return length; +} + +bool +ReliableTransport::hasPacketToSend() +{ + return !mOutgoingData.empty(); +} + +void +ReliableTransport::getPacketToSend(void* outputptr, int& outputsize) +{ + if (mOutgoingData.empty()) + { + outputsize = 0; + } + else + { + if (!outputptr) + { + outputsize = mOutgoingData.front()->data().size(); + } + else + { + Packet& p = *mOutgoingData.front(); + + unsigned tocopy = MINVALUE((int)outputsize, (int)p.data().size()); + memcpy(outputptr, p.data().data(), p.data().size()); + outputsize = tocopy; + + mOutgoingData.erase(mOutgoingData.begin()); + } + } +} + +void ReliableTransport::setEncryption(ICEImpl::ReliableTransport::Encryption *encryption) +{ + mEncryption = encryption; +} diff --git a/src/libs/ice/ICEReliableTransport.h b/src/libs/ice/ICEReliableTransport.h new file mode 100644 index 00000000..bd1fdbf0 --- /dev/null +++ b/src/libs/ice/ICEReliableTransport.h @@ -0,0 +1,168 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __RELIABLE_TRANSPORT_H +#define __RELIABLE_TRANSPORT_H + +#include "ICEPlatform.h" + +#include +#include +#include "ICEByteBuffer.h" + + +namespace ICEImpl { + + // ReliableTransport is protocol stack to provide reliable transport over UDP protocol. It remains packet based protocol, not stream. + // But it guarantees integrity and order of packets. + class ReliableTransport + { + public: + // ReliableTransport encryption interface + class Encryption + { + public: + // Returns block size for encryption algorythm + virtual int blockSize() = 0; + + // Encrypts dataPtr buffer inplace. dataSize must be odd to GetBlockSize() returned value. + virtual void encrypt(void* dataPtr, int dataSize) = 0; + + // Decrypts dataPtr buffer inplace. dataSize must be odd to GetBlockSize() returned value. + virtual void decrypt(void* dataPtr, int dataSize) = 0; + + // Calculates CRC + virtual unsigned crc(const void* dataptr, int datasize) = 0; + }; + + // Signature byte value + static const int RTSignature = 123; + + // Maximal count of confirmation items + static const int MaxConfirmationQueue = 50; + + ReliableTransport(); + ~ReliableTransport(); + + // Sets maximal datagram size. This value must be odd to Encryption::GetBlockSize() returned value. + void setMaxDatagram(int size); + + // Returns maximal datagram size + int maxDatagram(); + + // Sets encryption interface + void setEncryption(Encryption* encryption); + + // Returns current encryption interface. Default is NULL. + Encryption* encryption(); + + // Process incoming UDP packet. Returns true if packet is recognized. Otherwise it returns false. + bool processIncoming(const void* dataPtr, int dataSize); + + // Enqueue outgoing packet + void queueOutgoing(const void* dataPtr, int dataSize); + + // Checks if there are incoming application data + bool hasAppData(); + + // Returns incoming application data. ptr may be NULL - in this case method will return packet size. + unsigned appData(void* ptr); + + // Checks if there are raw packet(s) to send + bool hasPacketToSend(); + + // Returns raw packet data to send. + void getPacketToSend(void* outputPtr, int& outputSize); + + protected: + + class Packet + { + public: + enum Type + { + Request = 0, + Confirmation = 1, + Ack = 2, + AppData = 3 + }; + + typedef unsigned short Seqno; + typedef unsigned short AppSeqno; + + Packet(); + ~Packet(); + + bool parse(const void* dataptr, int datasize, Encryption* encryption); + void build(const void* dataptr, int datasize, Encryption* encryption); + void setType(Type packetType); + Type type(); + void setSeqno(Seqno seqno); + Seqno seqno(); + void setAppSeqno(AppSeqno seqno); + AppSeqno appSeqno(); + ByteBuffer& data(); + + protected: + Type mType; + Seqno mSeqno; + AppSeqno mAppSeqno; + ByteBuffer mData; + }; + + // List of UDP packets + typedef std::vector PacketList; + + // Incoming UDP packets + PacketList mIncomingData; + + // Outgoing UDP packets + PacketList mOutgoingData; + + // Used encryption provider + Encryption* mEncryption; + + // Maximal datagram size + int mMaxDatagramSize; + + // Vector of packet numbers to confirm + std::vector mConfirmationData; + + // Vector of packet numbers to ack + std::vector mAckData; + + // Incoming decrypted application data packets + PacketList mIncomingAppData; + + // Seqno generator + Packet::Seqno mSeqno; + + // Process incoming Ack packets + void processAck(Packet* p); + + // Process confirmation packets + void processConfirmation(Packet* p); + + // Process requests packets + void processRequest(Packet* p); + + // Process app. data + void processAppData(Packet* p); + + // Remove packet from outgoing queue + void removePacket(Packet::Seqno seqno); + + // Prioritizes packet with specified seqno + void prioritizePacket(Packet::Seqno seqno); + + // Creates Ack packet for specified seqno index + Packet* makeAckPacket(Packet::Seqno seqno); + + // Creates Confirm packet for specified seqno indexes + Packet* makeConfirmationPacket(std::vector seqnovector); + }; +} // end of namespace ICEImpl + +#endif diff --git a/src/libs/ice/ICESHA1.cpp b/src/libs/ice/ICESHA1.cpp new file mode 100644 index 00000000..cf625465 --- /dev/null +++ b/src/libs/ice/ICESHA1.cpp @@ -0,0 +1,31 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICESHA1.h" + +#ifdef USE_CRYPTOPP + +#include "../CryptoPP/hmac.h" +#include "../CryptoPP/sha.h" + +void hmacSha1Digest(const void* inputData, size_t inputSize, void* outputData, const void* key, size_t keySize) +{ + CryptoPP::HMAC mac((const byte*)key, keySize); + + mac.Update((const byte*)inputData, inputSize); + mac.Final((byte*)outputData); +} + +#elif defined(USE_OPENSSL) + +#include + +void hmacSha1Digest(const void* inputData, size_t inputSize, void* outputData, const void* key, size_t keySize) +{ + unsigned outputSize = 0; + HMAC(EVP_sha1(), key, keySize, (const unsigned char*)inputData, inputSize, (unsigned char*)outputData, &outputSize); +} + +#endif \ No newline at end of file diff --git a/src/libs/ice/ICESHA1.h b/src/libs/ice/ICESHA1.h new file mode 100644 index 00000000..458d0e52 --- /dev/null +++ b/src/libs/ice/ICESHA1.h @@ -0,0 +1,13 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_SHA1_H +#define __ICE_SHA1_H + +#include + +extern void hmacSha1Digest(const void* inputData, size_t inputSize, void* outputData, const void* key, size_t keySize); + +#endif diff --git a/src/libs/ice/ICESession.cpp b/src/libs/ice/ICESession.cpp new file mode 100644 index 00000000..6aba301a --- /dev/null +++ b/src/libs/ice/ICESession.cpp @@ -0,0 +1,893 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEPlatform.h" +#include "ICESession.h" +#include "ICENetworkHelper.h" +#include "ICEAction.h" +#include "ICESmartPtr.h" +#include "ICEBinding.h" +#include "ICERelaying.h" +#include "ICEAddress.h" +#include "ICEStream.h" +#include "ICELog.h" +#include "ICEStunAttributes.h" + +#include +#ifdef TARGET_WIN +#include +#endif + +#include +#include +#include +#include +#include + +using namespace ice; + + +#define LOG_SUBSYSTEM "ICE" + + +Session::Session() +{ + //No activity yet + mState = None; + + //start interval for STUN messages + mStartInterval = 20; + + mLocalPortNumber = 0; + refreshPwdUfrag(); + + //default role is Controlled + mRole = RoleControlled; + + mTieBreaker = " "; + for (size_t i=0; i<8; i++) + mTieBreaker[i] = rand() & 0xFF; + + mFoundationGenerator = 0xFFFFFFFF; + mMustRestart = false; +} + +Session::~Session() +{ +} + +void Session::setup(StackConfig& config) +{ + if (!config.mUseSTUN && !config.mUseTURN) + throw std::logic_error("ICE is configured to not use STUN and not use TURN."); + if (config.mUseSTUN && config.mUseTURN) + throw std::logic_error("ICE is configured to use both STUN and TURN."); + + // Save the configuration + mConfig = config; + + std::map::iterator streamIter; + for (streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + streamIter->second->setConfig(config); +} + +int Session::addStream() +{ + Lock lock(mGuard); + + ICEStreamPtr s(new Stream()); + s->setAgentRole(mRole); + s->setConfig(mConfig); + s->mTieBreaker = mTieBreaker; + s->setLocalPwd(mLocalPwd); + s->setLocalUfrag(mLocalUfrag); + s->mId = mStreamMap.size(); + mStreamMap[s->mId] = s; + + ICELogInfo(<< "New stream " << s->mId << " is add."); + + return s->mId; +} + +int Session::addComponent(int streamID, void* tag, unsigned short port4, unsigned short port6) +{ + Lock lock(mGuard); + + if (mStreamMap.find(streamID) == mStreamMap.end()) + { + ICELogCritical(<< "Cannot find stream " << streamID << " to add new component."); + return -1; + } + + // Get reference to stream + Stream& stream = *mStreamMap[streamID]; + + // Assign new ID to component + int componentID = stream.addComponent(tag, port4, port6); + + ICELogInfo( << "New component " << componentID << " is add to stream " << streamID << "."); + + return componentID; +} + +void Session::removeStream(int streamID) +{ + Lock lock(mGuard); + + std::map::iterator streamIter = mStreamMap.find(streamID); + if (streamIter != mStreamMap.end()) + mStreamMap.erase(streamIter); +} + +bool Session::findStreamAndComponent(int family, unsigned short port, int* stream, int* component) +{ + Lock lock(mGuard); + + // Iterate streams + ICEStreamMap::iterator sit; + for (sit = mStreamMap.begin(); sit != mStreamMap.end(); ++sit) + { + if (sit->second->hasPortNumber(family, port, component)) + { + *stream = sit->first; + return true; + } + } + + return false; +} + +bool Session::hasStream(int streamId) +{ + Lock l(mGuard); + return mStreamMap.find(streamId) != mStreamMap.end(); +} + +bool Session::hasComponent(int streamId, int componentId) +{ + Lock l(mGuard); + ICEStreamMap::const_iterator streamIter = mStreamMap.find(streamId); + if (streamIter == mStreamMap.end()) + return false; + if (!streamIter->second) + return false; + + return streamIter->second->mComponentMap.find(componentId) != streamIter->second->mComponentMap.end(); +} + +void Session::setComponentPort(int streamId, int componentId, unsigned short port4, unsigned short port6) +{ + Lock l(mGuard); + if (hasComponent(streamId, componentId)) + { + mStreamMap[streamId]->mComponentMap[componentId].mPort4 = port4; + mStreamMap[streamId]->mComponentMap[componentId].mPort6 = port6; + } +} + + +void Session::gatherCandidates() +{ + //protect instance + Lock lock(mGuard); + + //parse the STUN/TURN server IP address + //mConfig.mSTUNServerAddr.GetSockaddr((sockaddr&)mSTUNServerAddr); + //mConfig.mTURNServerAddr.GetSockaddr((sockaddr&)mTURNServerAddr); + + //as RFC says... + //if (mConfig.mUseTURN) + // mSTUNServerAddr = mTURNServerAddr; + + // Define the list of used IP interfaces + std::vector hostip; + + // Get list of IP interfaces + // std::vector& ipList = NetworkHelper::Instance().GetInterfaceList(); + + // Iterate all streams and instructs them to gather candidates + std::map::iterator streamIter; + int finished = 0; + for (streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + { + streamIter->second->gatherCandidates(); + if (streamIter->second->mState > CandidateGathering) + finished++; + } + + // Set session state as "candidate gathering" or "creating sdp" - depending on stream state + if ((size_t)finished == mStreamMap.size()) + mState = CreatingSDP; + else + mState = CandidateGathering; +} + + + +bool Session::processData(ByteBuffer& buffer, int streamID, int component) +{ + Lock lock(mGuard); + + // Attempt to parse + StunMessage msg; + if (!msg.parsePacket(buffer)) + return false; + + ICELogDebug( << "Received STUN packet from " << buffer.remoteAddress().toStdString().c_str() << ". Data: " << buffer.hexstring()); + + // Old&new states + int oldstate = None, newstate = None; + + // Find stream responsible for this buffer + if (mStreamMap.find(streamID) == mStreamMap.end()) + return false; + + // Get pointer to stream + ICEStreamPtr streamPtr = mStreamMap[streamID]; + if (!streamPtr) + return false; + + Stream& stream = *streamPtr; + oldstate = stream.mState; + /*bool result = */stream.processData(msg, buffer, component); + newstate = stream.mState; + + if (newstate != oldstate) + { + // State is changed. Maybe full session state is changed too? + int failedcount = 0, successcount = 0; + + switch (newstate) + { + case CreatingSDP: + + // Check if all streams gathered candidates or failed + for (ICEStreamMap::iterator si=mStreamMap.begin(); si != mStreamMap.end(); ++si) + { + if (!si->second) + continue; + + Stream& stream = *si->second; + if (stream.mState == CreatingSDP) + successcount++; + else + if (stream.mState == Failed) + failedcount++; + } + + if (failedcount == (int)mStreamMap.size()) + mState = Failed; + else + mState = CreatingSDP; + + break; + + case Success: + case Failed: + // Check if all streams a success or failed + for (ICEStreamMap::iterator si=mStreamMap.begin(); si != mStreamMap.end(); ++si) + { + if (!si->second) + continue; + + Stream& stream = *si->second; + if (stream.mState == Success) + successcount++; + else + if (stream.mState == Failed) + failedcount++; + } + + if (failedcount == (int)mStreamMap.size()) + mState = Failed; + else + mState = Success; + + break; + + } + } + return true; +} + +PByteBuffer Session::getDataToSend(bool& response, int& stream, int& component, void*&tag) +{ + // Protect instance + Lock lock(mGuard); + + PByteBuffer result; + + // Iterate streams to update their states (maybe timeout occured since last call of getDataToSend()) + ICEStreamMap::iterator streamIter; + for (streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + if (streamIter->second) + streamIter->second->isTimeout(); + + for (streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + { + if (streamIter->second) + result = streamIter->second->getDataToSend(response, component, tag); + if (result) + { + stream = streamIter->first; + return result; + } + } + return result; +} + +bool Session::active() +{ + //protect instance + Lock lock(mGuard); + + return (mState != None); +} + +void Session::createSdp(std::vector& common) +{ + common.push_back("a=ice-full"); + common.push_back("a=ice-pwd:" + localPwd()); + common.push_back("a=ice-ufrag:" + localUfrag()); +} + +void Session::createSdp(int streamID, std::vector& defaultIP, + std::vector& defaultPort, std::vector& candidateList) +{ + ICEStreamMap::iterator streamIter = mStreamMap.find(streamID); + if (streamIter != mStreamMap.end()) + streamIter->second->createOfferSdp(defaultIP, defaultPort, candidateList); +} + + +bool Session::findCandidate(std::vector&cv, Candidate::Type _type, + const std::string& baseIP, int componentID, Candidate& result) +{ + for (unsigned int i=0; isecond; + if (s) + { + if (streamId == -1 || streamIter->first == streamId) + s->setRemotePwd(pwd); + } + } + +} + +std::string Session::remotePassword(int streamId) const +{ + if (streamId == -1) + return mRemotePwd; + ICEStreamMap::const_iterator streamIter = mStreamMap.find(streamId); + if (streamIter == mStreamMap.end()) + return std::string(); + if (!streamIter->second) + return std::string(); + + return streamIter->second->mRemotePwd; +} + +void Session::setRemoteUfrag(const std::string& ufrag, int streamId) +{ + mMustRestart |= ufrag != mRemoteUfrag; + mRemoteUfrag = ufrag; + + // Set it to streams + for (ICEStreamMap::iterator streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); streamIter++) + { + ICEStreamPtr s = streamIter->second; + if (s) + { + if (streamId == -1 || streamIter->first == streamId) + s->setRemoteUfrag(ufrag); + } + } +} + +std::string Session::remoteUfrag(int streamId) const +{ + if (streamId == -1) + return mRemoteUfrag; + ICEStreamMap::const_iterator streamIter = mStreamMap.find(streamId); + if (streamIter == mStreamMap.end()) + return std::string(); + if (!streamIter->second) + return std::string(); + + return streamIter->second->mRemoteUfrag; +} + +bool Session::processSdpOffer(int streamIndex, std::vector& candidateList, + const std::string& defaultIP, unsigned short defaultPort, bool deleteRelayed) +{ + ICEStreamMap::iterator streamIter = mStreamMap.find(streamIndex); + if (streamIter != mStreamMap.end()) + return streamIter->second->processSdpOffer(candidateList, defaultIP, defaultPort, deleteRelayed); + + return false; +} + +NetworkAddress Session::getRemoteRelayedCandidate(int stream, int component) +{ + ICEStreamMap::iterator streamIter = mStreamMap.find(stream); + if (streamIter != mStreamMap.end()) + return streamIter->second->remoteRelayedAddress(component); + + return NetworkAddress(); +} + +NetworkAddress Session::getRemoteReflexiveCandidate(int stream, int component) +{ + ICEStreamMap::iterator streamIter = mStreamMap.find(stream); + if (streamIter != mStreamMap.end()) + return streamIter->second->remoteReflexiveAddress(component); + + return NetworkAddress(); +} + +NetworkAddress Session::defaultAddress(int streamID, int componentID) +{ + ICEStreamMap::iterator streamIter = mStreamMap.find(streamID); + if (streamIter != mStreamMap.end()) + return streamIter->second->defaultAddress(componentID); + return NetworkAddress(); +} + +void Session::fillCandidateList(int streamID, int componentID, std::vector& candidateList) +{ + ICEStreamMap::iterator streamIter = mStreamMap.find(streamID); + if (streamIter != mStreamMap.end()) + streamIter->second->candidateList(componentID, candidateList); +} + +void Session::checkConnectivity() +{ + ICELogInfo( << "Starting connectivity checks."); + + // Check current session state to ensure is did not run connectivity checks already + if (mState == ConnCheck || mState == Success) + return; + + // Make current state "connection checking now" + mState = ConnCheck; + + std::map::iterator streamIter; + for (streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); streamIter++) + { + streamIter->second->setRemotePwd(mRemotePwd); + streamIter->second->setRemoteUfrag(mRemoteUfrag); + streamIter->second->startChecks(); + } + + // Set session state to "connection checks" + mState = ConnCheck; + + /* + Checks are generated only by full implementations. Lite + implementations MUST skip the steps described in this section. + + An agent performs ordinary checks and triggered checks. The + generation of both checks is governed by a timer which fires + periodically for each media stream. The agent maintains a FIFO + queue, called the triggered check queue, which contains candidate + pairs for which checks are to be sent at the next available + + opportunity. When the timer fires, the agent removes the top pair + from triggered check queue, performs a connectivity check on that + pair, and sets the state of the candidate pair to In-Progress. If + there are no pairs in the triggered check queue, an ordinary check is + sent. + + Once the agent has computed the check lists as described in + Section 5.7, it sets a timer for each active check list. The timer + fires every Ta*N seconds, where N is the number of active check lists + (initially, there is only one active check list). Implementations + MAY set the timer to fire less frequently than this. Implementations + SHOULD take care to spread out these timers so that they do not fire + at the same time for each media stream. Ta and the retransmit timer + RTO are computed as described in Section 16. Multiplying by N allows + this aggregate check throughput to be split between all active check + lists. The first timer fires immediately, so that the agent performs + a connectivity check the moment the offer/answer exchange has been + done, followed by the next check Ta seconds later (since there is + only one active check list). + + When the timer fires, and there is no triggered check to be sent, the + agent MUST choose an ordinary check as follows: + + o Find the highest priority pair in that check list that is in the + Waiting state. + + o If there is such a pair: + + * Send a STUN check from the local candidate of that pair to the + remote candidate of that pair. The procedures for forming the + STUN request for this purpose are described in Section 7.1.1. + + * Set the state of the candidate pair to In-Progress. + + o If there is no such pair: + + * Find the highest priority pair in that check list that is in + the Frozen state. + + * If there is such a pair: + + + Unfreeze the pair. + + + Perform a check for that pair, causing its state to + transition to In-Progress. + + * If there is no such pair: + + + Terminate the timer for that check list. + + To compute the message integrity for the check, the agent uses the + remote username fragment and password learned from the SDP from its + peer. The local username fragment is known directly by the agent for + its own candidate. + */ + +} + +void Session::setRole(AgentRole role) +{ + mRole = role; + + std::map::iterator streamIter; + for (streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + streamIter->second->setAgentRole(role); +} + +AgentRole Session::role() +{ + return mRole; +} + + +void Session::clear() +{ + refreshPwdUfrag(); + mState = None; + std::map::iterator streamIter; + for (streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + streamIter->second->clear(); + mTurnPrefixMap.clear(); +} + +void Session::clearForRestart(bool localNetworkChanged) +{ + refreshPwdUfrag(); + mState = ice::None; + ICEStreamMap::iterator streamIter; + for (streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + streamIter->second->clearForRestart(localNetworkChanged); +} + +void Session::stopChecks() +{ + ICELogInfo(<< "Stop connectivity checks"); + + ICEStreamMap::iterator streamIter; + for (streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + streamIter->second->stopChecks(); + + if (mState < Failed) + mState = Failed; +} + +void Session::cancelAllocations() +{ + for (auto stream: mStreamMap) + stream.second->cancelAllocations(); +} + +bool Session::finished() +{ + return (mState == Failed || mState == Success); +} + +NetworkAddress Session::remoteAddress(int streamID, int componentID) +{ + ICEStreamMap::iterator streamIter = mStreamMap.find(streamID); + if (streamIter != mStreamMap.end()) + return streamIter->second->remoteAddress(componentID); + + return NetworkAddress(); +} + +NetworkAddress Session::localAddress(int streamID, int componentID) +{ + ICEStreamMap::iterator streamIter = mStreamMap.find(streamID); + if (streamIter != mStreamMap.end()) + return streamIter->second->localAddress(componentID); + + return NetworkAddress(); +} + +NetworkAddress Session::reflexiveAddress(int streamID, int componentID) +{ + Lock l(mGuard); + ICEStreamMap::iterator streamIter = mStreamMap.find(streamID); + if (streamIter != mStreamMap.end()) + return streamIter->second->reflexiveAddress(componentID); + + return NetworkAddress(); +} + +NetworkAddress Session::relayedAddress(int streamID, int componentID) +{ + Lock l(mGuard); + ICEStreamMap::iterator streamIter = mStreamMap.find(streamID); + if (streamIter != mStreamMap.end()) + return streamIter->second->relayedAddress(componentID); + + return NetworkAddress(); +} + +bool Session::hasTurnPrefix(TurnPrefix prefix) +{ + Lock l(mGuard); + TurnPrefixMap::iterator mit = mTurnPrefixMap.find(prefix); + return mit != mTurnPrefixMap.end(); +} + +void Session::chooseDefaults() +{ + Lock l(mGuard); + + ICEStreamMap::iterator streamIter; + for (streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + streamIter->second->Handle_CD(); +} + +void Session::dump(std::ostream& output) +{ + Lock l(mGuard); + + ICEStreamMap::iterator streamIter; + for (streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + streamIter->second->dump(output); +} + +bool Session::findConcludePair(int stream, Candidate& local, Candidate& remote) +{ + Lock l(mGuard); + + ICEStreamMap::iterator streamIter = mStreamMap.find(stream); + if (streamIter != mStreamMap.end()) + return streamIter->second->findConcludePair(local, remote); + return false; +} + +bool Session::mustRestart() const +{ + return mMustRestart; +} + +void Session::refreshPwdUfrag() +{ + mLocalPwd = Session::createPassword(); + mLocalUfrag = Session::createUfrag(); + + // Update all streams + for (ICEStreamMap::iterator streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + { + if (streamIter->second) + { + streamIter->second->setLocalPwd(mLocalPwd); + streamIter->second->setLocalUfrag(mLocalUfrag); + } + } +} + +void Session::freeAllocation(int stream, int component, DeleteAllocationCallback* cb) +{ + Lock l(mGuard); + + ICEStreamMap::iterator streamIter = mStreamMap.find(stream); + if (streamIter != mStreamMap.end()) + streamIter->second->freeAllocation(component, cb); +} + +bool Session::hasAllocations() +{ + int allocated = 0; + Lock l(mGuard); + + ICEStreamMap::iterator streamIter = mStreamMap.begin(); + for (;streamIter != mStreamMap.end(); ++streamIter) + if (streamIter->second) + allocated += streamIter->second->mTurnAllocated; + + return allocated > 0; +} + +bool Session::isDataIndication(ByteBuffer& source, ByteBuffer* plain) +{ + StunMessage msg; + if (!msg.parsePacket(source)) + return false; + + if (msg.hasAttribute(StunAttribute::Data) && msg.hasAttribute(StunAttribute::XorPeerAddress)) + { + // It is Data indication packet + DataAttribute& d = dynamic_cast(msg.attribute(StunAttribute::Data)); + XorPeerAddress& xpa = dynamic_cast(msg.attribute(StunAttribute::XorPeerAddress)); + + if (plain) + { + *plain = d.data(); + NetworkAddress remoteAddress = xpa.address(); + remoteAddress.setRelayed(true); + plain->setRemoteAddress(remoteAddress); + plain->setRelayed(true); + } + return true; + } + else + return false; +} + +bool Session::isStun(ByteBuffer& source) +{ + if (source.size() < 8) + return false; + + const unsigned* magic = (const unsigned*)source.data(); + return (ntohl(magic[1]) == 0x2112A442); +} + + +int Session::errorCode() +{ + Lock l(mGuard); + ICEStreamMap::const_iterator streamIter = mStreamMap.begin(); + for (;streamIter != mStreamMap.end(); ++streamIter) + if (streamIter->second->mState == /*RunningState::*/Failed) + return streamIter->second->mErrorCode; + return 0; +} + +TurnPrefix Session::bindChannel(int stream, int component, const NetworkAddress& target, ChannelBoundCallback* cb) +{ + Lock l(mGuard); + ICELogInfo(<< "Bind channel " << stream << "/" << component << " to " << target.toStdString()); + + ICEStreamMap::iterator streamIter = mStreamMap.find(stream); + if (streamIter != mStreamMap.end()) + return streamIter->second->bindChannel(target, component, cb); + + return 0; // Channel numbers are in range [0x4000...0x7FFF] +} + +bool Session::isChannelBindingFailed(int stream, int component, TurnPrefix prefix) +{ + Lock l(mGuard); + ICEStreamMap::iterator streamIter = mStreamMap.begin(); + if (streamIter != mStreamMap.end()) + if (streamIter->second) + return streamIter->second->isChannelBindingFailed(component, prefix); + + return false; +} + +void Session::installPermissions(int stream, int component, const NetworkAddress &address, InstallPermissionsCallback* cb) +{ + Lock l(mGuard); + ICELogInfo(<< "Install permissions " << stream << "/" << component << " for " << address.toStdString()); + + ICEStreamMap::iterator streamIter = mStreamMap.begin(); + if (streamIter != mStreamMap.end()) + streamIter->second->installPermissions(component, address, cb); +} + +bool Session::isRtp(ByteBuffer& source) +{ + if (!source.size()) + return false; + unsigned char b = *(const unsigned char*)source.data(); + return (b & 0xC0) == 0x80; +} + +bool Session::isChannelData(ByteBuffer& source, TurnPrefix prefix) +{ + if (source.size() < 4) + return false; + + if (!prefix) + { + unsigned char b = *(const unsigned char*)source.data(); + return (b & 0xC0) == 0x40; + } + else + { + unsigned short pp = ntohs(*(const unsigned short*)source.data()); + return pp == prefix; + } +} + +Stream::CandidateVector* Session::remoteCandidates(int stream) +{ + ICEStreamMap::iterator iter = mStreamMap.find(stream); + if (iter != mStreamMap.end()) + return &iter->second->mRemoteCandidate; + else + return NULL; +} + +NetworkAddress Session::activeStunServer(int stream) const +{ + ICEStreamMap::const_iterator iter = mStreamMap.find(stream); + if (iter != mStreamMap.end()) + return iter->second->mConfig.mServerAddr4; + else + return NetworkAddress(); +} diff --git a/src/libs/ice/ICESession.h b/src/libs/ice/ICESession.h new file mode 100644 index 00000000..05f5f149 --- /dev/null +++ b/src/libs/ice/ICESession.h @@ -0,0 +1,221 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_SESSION_H +#define __ICE_SESSION_H + +#include +#include +#include + +#include "ICEStunConfig.h" +#include "ICECandidate.h" +#include "ICEStunMessage.h" +#include "ICEBinding.h" +#include "ICERelaying.h" +#include "ICESync.h" +#include "ICECheckList.h" +#include "ICETime.h" +#include "ICESmartPtr.h" +#include "ICEStream.h" + +namespace ice { + + // ICE session context + struct Session + { + public: + Mutex mGuard; // Mutex to protect this instance + typedef std::map ICEStreamMap; + ICEStreamMap mStreamMap; // Streams + RunningState mState; // State of session + StackConfig mConfig; // Configuration + + size_t mStartInterval; /// Start interval + unsigned short mLocalPortNumber; /// Local port number + std::string mLocalPwd, + mLocalUfrag, + mRemotePwd, + mRemoteUfrag; + + NetworkAddress mRemoteDefaultAddr; /// Remote default address + AgentRole mRole; /// Marks if agent is Controlled or Controlling + std::string mTieBreaker; /// Tie breaker + unsigned int mFoundationGenerator; /// Foundation value generator. Used when foundation of remote candidate is not available. + bool mCanTransmit; /// Marks if transmission can start + bool mMustReInvite; /// Must reINVITE + TurnPrefixMap mTurnPrefixMap; /// Map of established relays + bool mMustRestart; /// Marks if session has to restart + + /*! Default constructor. */ + Session(); + + /*! Destructor. */ + ~Session(); + + /*! Adjusts session to work with specified component number and specified local port number. */ + void setup(StackConfig& config); + + /*! Checks if ICE session is started. */ + bool active(); + + /*! Initiates candidate gathering. Setup() must be called before. */ + void gatherCandidates(); + + /*! Processing incoming data. + * @return True if data were processed, false otherwise (too old response or not STUN data at all). */ + bool processData(ByteBuffer& buffer, int stream, int component); + + /*! Checks if there is any data to send. + * @return True if more data to send are available, false if all available data are returned in current call. */ + PByteBuffer getDataToSend(bool& response, int& stream, int& component, void*&tag); + + + /*! Handles incoming data in gathering candidate stage. + * @return True if data was handled, false otherwise (too old response or not STUN data at all. */ + bool Handle_CG_In(StunMessage& msg, NetworkAddress& address); + + /*! Handle eliminate redudand stage. */ + void Handle_ER(); + + // Compute foundations + void Handle_CF(); + + // Starting keep alive timers + void Handle_SKA(); + + // Prioritize candidates + void Handle_PC(); + + // Choosing default candidate + void chooseDefaults(); + + // Creation of common SDP strings + void createSdp(std::vector& common); + + // Creation of component SDP strings + void createSdp(int streamID, std::vector& defaultIP, + std::vector& defaultPort, std::vector& candidateList); + + bool findCandidate(std::vector&cv, Candidate::Type _type, + const std::string& baseIP, int componentID, Candidate& result); + + RunningState state(); + + std::string localUfrag(); + std::string localPwd(); + + /*! Process ICE offer text. It does not mean SIP offer. No, this method applies to initial ICE candidate list and other information in both SIP offer and answer packets. */ + bool processSdpOffer(int streamIndex, std::vector& candidateList, + const std::string& defaultIP, unsigned short defaultPort, bool deleteRelayed); + NetworkAddress getRemoteRelayedCandidate(int stream, int component); + NetworkAddress getRemoteReflexiveCandidate(int stream, int component); + + NetworkAddress defaultAddress(int streamID, int componentID); + void fillCandidateList(int streamID, int componentID, std::vector& candidateList); + + /*! Seeks in candidate list for candidate with specified IP and port. */ + bool candidateListContains(std::string remoteIP, unsigned short remotePort); + + /*! Marks agent as Controlled or Controlling role. */ + void setRole(AgentRole role); + + /*! Gets current role. */ + AgentRole role(); + + /*! Binds channel to prefix */ + TurnPrefix bindChannel(int stream, int component, const NetworkAddress& target, ChannelBoundCallback* cb); + bool isChannelBindingFailed(int stream, int component, TurnPrefix prefix); + + void installPermissions(int stream, int component, const NetworkAddress &address, InstallPermissionsCallback* cb); + + /*! Enqueues CreatePermisssion transaction with zero lifetime - it removes permission. */ + void deletePermission(int stream, int component, DeletePermissionsCallback* cb); + + // Enqueues ClientAllocate with zero lifetime + void freeAllocation(int stream, int component, DeleteAllocationCallback* cb); + + // Returns if there were any TURN allocations from this stack + bool hasAllocations(); + + static bool isDataIndication(ByteBuffer& source, ByteBuffer* plain); + static bool isStun(ByteBuffer& source); + static bool isRtp(ByteBuffer& source); + static bool isChannelData(ByteBuffer& source, TurnPrefix prefix); + + /*! Starts connectivity checks. */ + void checkConnectivity(); + + // Clears state of session and streams; does not delete streams or components. Stops all connectivity checks. Candidates must be gathered again. + void clear(); + + void clearForRestart(bool localNetworkChanged); + + // Returns true if state of session is Success or Failed + bool finished(); + + // Stop connectivity checks and gathering requests. + void stopChecks(); + + // Cancel allocation requests. Called when timeout is detected and allocation should be cancelled. + // Allocation transaction and session can have different timeout values - so this method is neccessary + void cancelAllocations(); + + /*! Returns concluding addresses . */ + NetworkAddress remoteAddress(int streamID, int componentID); + NetworkAddress localAddress(int streamID, int componentID); + + /*! Searches for local server reflexive candidate with specified component ID and returns its external address. */ + NetworkAddress reflexiveAddress(int streamID, int componentID); + + /*! Searches for local server relayed candidate with specified component ID and returns its external address. */ + NetworkAddress relayedAddress(int streamID, int componentID); + + /*! Checks if argument is used TURN prefix in one of the TURN bound channels. */ + bool hasTurnPrefix(TurnPrefix prefix); + + /*! Adds stream to session. Returns stream index. */ + int addStream(); + + /*! Adds component to stream. + * @param streamIndex Stream index. + * @param tag Tag associated with component. + * @return Created component record index. */ + int addComponent(int streamID, void *tag, unsigned short port4, unsigned short port6); + + /* Removes stream with specified ID. All stream's components are removed too. */ + void removeStream(int streamID); + + /* Searches the stream&component ID basing on socket family (AF_INET or AF_INET6) and local port number. */ + bool findStreamAndComponent(int family, unsigned short port, int* stream, int* component); + + bool hasStream(int streamId); + bool hasComponent(int streamId, int componentId); + void setComponentPort(int streamId, int componentId, unsigned short port4, unsigned short port6); + + /*! Generates new ICE ufrag string. */ + static std::string createUfrag(); + + /*! Generates new ICE pwd string. */ + static std::string createPassword(); + + void setRemotePassword(const std::string& pwd, int streamId = -1); + std::string remotePassword(int streamId = -1) const; + void setRemoteUfrag(const std::string& ufrag, int streamId = -1); + std::string remoteUfrag(int streamId = -1) const; + + void refreshPwdUfrag(); + + void dump(std::ostream& output); + bool mustRestart() const; + bool findConcludePair(int stream, Candidate& local, Candidate& remote); + int errorCode(); + Stream::CandidateVector* remoteCandidates(int stream); + + NetworkAddress activeStunServer(int stream) const; + }; +}; + +#endif diff --git a/src/libs/ice/ICESmartCount.h b/src/libs/ice/ICESmartCount.h new file mode 100644 index 00000000..b40efd4d --- /dev/null +++ b/src/libs/ice/ICESmartCount.h @@ -0,0 +1,396 @@ +// Based on resiprocate's implementation of smart pointer, which is based on boost implementation +// Its license is smth close to BSD + +#ifndef __ICE_SMART_COUNT_H +#define __ICE_SMART_COUNT_H + +// Note: This implementation is a modified version of shared_count from +// Boost.org +// + +#include // std::auto_ptr, std::allocator +#include // std::less +#include // std::exception +#include // std::bad_alloc +#include // std::type_info in get_deleter +#include // std::size_t +#include "ICESync.h" + +namespace ice +{ + +#ifdef __BORLANDC__ +# pragma warn -8026 // Functions with excep. spec. are not expanded inline +# pragma warn -8027 // Functions containing try are not expanded inline +#endif + +// verify that types are complete for increased safety +template inline void checked_delete(T * x) +{ + // intentionally complex - simplification causes regressions + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete x; +}; + +template struct checked_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + // resip:: disables ADL + checked_delete(x); + } +}; + +// The standard library that comes with Borland C++ 5.5.1 +// defines std::exception and its members as having C calling +// convention (-pc). When the definition of bad_weak_ptr +// is compiled with -ps, the compiler issues an error. +// Hence, the temporary #pragma option -pc below. The version +// check is deliberately conservative. +#if defined(__BORLANDC__) && __BORLANDC__ == 0x551 +# pragma option push -pc +#endif + +class bad_weak_ptr: public std::exception +{ +public: + + virtual char const * what() const throw() + { + return "resip::bad_weak_ptr"; + } +}; + +#if defined(__BORLANDC__) && __BORLANDC__ == 0x551 +# pragma option pop +#endif + +class sp_counted_base +{ +private: + +public: + + sp_counted_base(): use_count_(1), weak_count_(1) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + virtual void dispose() = 0; // nothrow + + // destruct() is called when weak_count_ drops to zero. + virtual void destruct() // nothrow + { + delete this; + } + + virtual void * get_deleter(std::type_info const & ti) = 0; + + void add_ref_copy() + { + Lock lock(mMutex); (void)lock; + ++use_count_; + //GenericLog(Subsystem::SIP, resip::Log::Info, << "********* SharedCount::add_ref_copy: " << use_count_); + } + + void add_ref_lock() + { + Lock lock(mMutex); (void)lock; + // if(use_count_ == 0) throw(resip::bad_weak_ptr()); + if (use_count_ == 0) throw bad_weak_ptr(); + ++use_count_; + //GenericLog(Subsystem::SIP, resip::Log::Info, << "********* SharedCount::add_ref_lock: " << use_count_); + } + + void release() // nothrow + { + { + Lock lock(mMutex); (void)lock; + long new_use_count = --use_count_; + //GenericLog(Subsystem::SIP, resip::Log::Info, << "********* SharedCount::release: " << use_count_); + + if(new_use_count != 0) return; + } + + dispose(); + weak_release(); + } + + void weak_add_ref() // nothrow + { + Lock lock(mMutex); (void)lock; + ++weak_count_; + } + + void weak_release() // nothrow + { + long new_weak_count; + + { + Lock lock(mMutex); (void)lock; + new_weak_count = --weak_count_; + } + + if(new_weak_count == 0) + { + destruct(); + } + } + + long use_count() const // nothrow + { + Lock lock(mMutex); (void)lock; + return use_count_; + } + +private: + + sp_counted_base(sp_counted_base const &); + sp_counted_base & operator= (sp_counted_base const &); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + + mutable Mutex mMutex; +}; + +// +// Borland's Codeguard trips up over the -Vx- option here: +// +#ifdef __CODEGUARD__ +# pragma option push -Vx- +#endif + +template class sp_counted_base_impl: public sp_counted_base +{ +private: + + P ptr; // copy constructor must not throw + D del; // copy constructor must not throw + + sp_counted_base_impl(sp_counted_base_impl const &); + sp_counted_base_impl & operator= (sp_counted_base_impl const &); + + typedef sp_counted_base_impl this_type; + +public: + + // pre: initial_use_count <= initial_weak_count, d(p) must not throw + sp_counted_base_impl(P p, D d): ptr(p), del(d) + { + } + + virtual void dispose() // nothrow + { + del(ptr); + } + + virtual void * get_deleter(std::type_info const & ti) + { + return ti == typeid(D)? &del: 0; + } + + void * operator new(size_t) + { + return std::allocator().allocate(1, static_cast(0)); + } + + void operator delete(void * p) + { + std::allocator().deallocate(static_cast(p), 1); + } + +}; + +class shared_count +{ +private: + + sp_counted_base * pi_; + +public: + + shared_count(): pi_(0) // nothrow + { + } + + template shared_count(P p, D d): pi_(0) + { + try + { + pi_ = new sp_counted_base_impl(p, d); + } + catch(...) + { + d(p); // delete p + throw; + } + } + + // auto_ptr is special cased to provide the strong guarantee + template + explicit shared_count(std::auto_ptr & r): pi_(new sp_counted_base_impl< Y *, checked_deleter >(r.get(), checked_deleter())) + { + r.release(); + } + + ~shared_count() // nothrow + { + if(pi_ != 0) pi_->release(); + } + + shared_count(shared_count const & r): pi_(r.pi_) // nothrow + { + if(pi_ != 0) pi_->add_ref_copy(); + } + + shared_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + if(tmp != 0) tmp->add_ref_copy(); + if(pi_ != 0) pi_->release(); + pi_ = tmp; + + return *this; + } + + void swap(shared_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + bool unique() const // nothrow + { + return use_count() == 1; + } + + friend inline bool operator==(shared_count const & a, shared_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(shared_count const & a, shared_count const & b) + { + return std::less()(a.pi_, b.pi_); + } + + void * get_deleter(std::type_info const & ti) const + { + return pi_? pi_->get_deleter(ti): 0; + } +}; + +#ifdef __CODEGUARD__ +# pragma option pop +#endif + + +#ifdef __BORLANDC__ +# pragma warn .8027 // Functions containing try are not expanded inline +# pragma warn .8026 // Functions with excep. spec. are not expanded inline +#endif + + +} + +#endif + +// Note: This implementation is a modified version of shared_count from +// Boost.org +// + +/* ==================================================================== + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * ==================================================================== + */ + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/ice/ICESmartPtr.h b/src/libs/ice/ICESmartPtr.h new file mode 100644 index 00000000..5d23e08c --- /dev/null +++ b/src/libs/ice/ICESmartPtr.h @@ -0,0 +1,382 @@ +// Based on resiprocate's implementation of smart pointer, which is based on boost implementation +// Its license is smth close to BSD + +#ifndef __ICE_SMART_PTR_H +#define __ICE_SMART_PTR_H + +#ifndef USE_NATIVE_SMARTPTR + +#include "ICESmartCount.h" +#include // for std::auto_ptr +#include // for std::swap +#include // for std::less +#include // for std::bad_cast +#include // for std::basic_ostream +#include + +namespace ice +{ + + +template class enable_shared_from_this; + +struct static_cast_tag {}; +struct const_cast_tag {}; +struct dynamic_cast_tag {}; +struct polymorphic_cast_tag {}; + +template struct SmartPtr_traits +{ + typedef T & reference; +}; + +template<> struct SmartPtr_traits +{ + typedef void reference; +}; + +template<> struct SmartPtr_traits +{ + typedef void reference; +}; + +template<> struct SmartPtr_traits +{ + typedef void reference; +}; + +template<> struct SmartPtr_traits +{ + typedef void reference; +}; + +// enable_shared_from_this support + +template void sp_enable_shared_from_this( shared_count const & pn, enable_shared_from_this const * pe, Y const * px ) +{ + if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast(px), pn); +} + +inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... ) +{ +} + +// +// SmartPtr +// +// Reference counted copy semantics. +// The object pointed to is deleted when the last SmartPtr pointing to it +// is destroyed or reset. +// + +template class SmartPtr +{ +private: + + // Borland 5.5.1 specific workaround + typedef SmartPtr this_type; + +public: + + typedef T element_type; + typedef T value_type; + typedef T * pointer; + typedef typename SmartPtr_traits::reference reference; + + SmartPtr(): px(0), pn() // never throws in 1.30+ + { + } + + template + explicit SmartPtr(Y * p): px(p), pn(p, checked_deleter()) // Y must be complete + { + sp_enable_shared_from_this( pn, p, p ); + } + + // + // Requirements: D's copy constructor must not throw + // + // SmartPtr will release p by calling d(p) + // + + template SmartPtr(Y * p, D d): px(p), pn(p, d) + { + sp_enable_shared_from_this( pn, p, p ); + } + +// generated copy constructor, assignment, destructor are fine... + +// except that Borland C++ has a bug, and g++ with -Wsynth warns +#if defined(__BORLANDC__) || defined(__GNUC__) + SmartPtr & operator=(SmartPtr const & r) // never throws + { + px = r.px; + pn = r.pn; // shared_count::op= doesn't throw + return *this; + } +#endif + + template + SmartPtr(SmartPtr const & r): px(r.px), pn(r.pn) // never throws + { + } + + template + SmartPtr(SmartPtr const & r, static_cast_tag): px(static_cast(r.px)), pn(r.pn) + { + } + + template + SmartPtr(SmartPtr const & r, const_cast_tag): px(const_cast(r.px)), pn(r.pn) + { + } + + template + SmartPtr(SmartPtr const & r, dynamic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) + { + if(px == 0) // need to allocate new counter -- the cast failed + { + pn = /*resip::*/shared_count(); + } + } + + template + SmartPtr(SmartPtr const & r, polymorphic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) + { + if(px == 0) + { + throw std::bad_cast(); + } + } + + template + explicit SmartPtr(std::auto_ptr & r): px(r.get()), pn() + { + Y * tmp = r.get(); + pn = shared_count(r); + sp_enable_shared_from_this( pn, tmp, tmp ); + } + + template + SmartPtr & operator=(SmartPtr const & r) // never throws + { + px = r.px; + pn = r.pn; // shared_count::op= doesn't throw + return *this; + } + + template + SmartPtr & operator=(std::auto_ptr & r) + { + this_type(r).swap(*this); + return *this; + } + + void reset() // never throws in 1.30+ + { + this_type().swap(*this); + } + + template void reset(Y * p) // Y must be complete + { + assert(p == 0 || p != px); // catch self-reset errors + this_type(p).swap(*this); + } + + template void reset(Y * p, D d) + { + this_type(p, d).swap(*this); + } + + reference operator* () const // never throws + { + assert(px != 0); + return *px; + } + + T * operator-> () const // never throws + { + //assert(px != 0); + return px; + } + + T * get() const // never throws + { + return px; + } + + // implicit conversion to "bool" +#if defined(__SUNPRO_CC) // BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) + operator bool () const + { + return px != 0; + } +#elif defined(__MWERKS__) // BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) + typedef T * (this_type::*unspecified_bool_type)() const; + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::get; + } +#else + typedef T * this_type::*unspecified_bool_type; + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::px; + } +#endif + + // operator! is redundant, but some compilers need it + bool operator! () const // never throws + { + return px == 0; + } + + bool unique() const // never throws + { + return pn.unique(); + } + + long use_count() const // never throws + { + return pn.use_count(); + } + + void swap(SmartPtr & other) // never throws + { + std::swap(px, other.px); + pn.swap(other.pn); + } + + template bool _internal_less(SmartPtr const & rhs) const + { + return pn < rhs.pn; + } + + void * _internal_get_deleter(std::type_info const & ti) const + { + return pn.get_deleter(ti); + } + +// Tasteless as this may seem, making all members public allows member templates +// to work in the absence of member template friends. (Matthew Langston) + +private: + + template friend class SmartPtr; + + T * px; // contained pointer + shared_count pn; // reference counter + +}; // SmartPtr + +template inline bool operator==(SmartPtr const & a, SmartPtr const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(SmartPtr const & a, SmartPtr const & b) +{ + return a.get() != b.get(); +} + +#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 + +// Resolve the ambiguity between our op!= and the one in rel_ops + +template inline bool operator!=(SmartPtr const & a, SmartPtr const & b) +{ + return a.get() != b.get(); +} + +#endif + +template inline bool operator<(SmartPtr const & a, SmartPtr const & b) +{ + return a._internal_less(b); +} + +template inline void swap(SmartPtr & a, SmartPtr & b) +{ + a.swap(b); +} + +template SmartPtr static_pointer_cast(SmartPtr const & r) +{ + return SmartPtr(r, static_cast_tag()); +} + +template SmartPtr const_pointer_cast(SmartPtr const & r) +{ + return SmartPtr(r, const_cast_tag()); +} + +template SmartPtr dynamic_pointer_cast(SmartPtr const & r) +{ + return SmartPtr(r, dynamic_cast_tag()); +} + +// shared_*_cast names are deprecated. Use *_pointer_cast instead. + +template SmartPtr shared_static_cast(SmartPtr const & r) +{ + return SmartPtr(r, static_cast_tag()); +} + +template SmartPtr shared_dynamic_cast(SmartPtr const & r) +{ + return SmartPtr(r, dynamic_cast_tag()); +} + +template SmartPtr shared_polymorphic_cast(SmartPtr const & r) +{ + return SmartPtr(r, polymorphic_cast_tag()); +} + +template SmartPtr shared_polymorphic_downcast(SmartPtr const & r) +{ + assert(dynamic_cast(r.get()) == r.get()); + return shared_static_cast(r); +} + +template inline T * get_pointer(SmartPtr const & p) +{ + return p.get(); +} + +// operator<< +#if defined(__GNUC__) && (__GNUC__ < 3) +template std::ostream & operator<< (std::ostream & os, SmartPtr const & p) +{ + os << p.get(); + return os; +} +#else +template std::basic_ostream & operator<< (std::basic_ostream & os, SmartPtr const & p) +{ + os << p.get(); + return os; +} +#endif + +// get_deleter (experimental) +#if (defined(__GNUC__) && (__GNUC__ < 3)) || (defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238)) +// g++ 2.9x doesn't allow static_cast(void *) +// apparently EDG 2.38 also doesn't accept it +template D * get_deleter(SmartPtr const & p) +{ + void const * q = p._internal_get_deleter(typeid(D)); + return const_cast(static_cast(q)); +} +#else +template D * get_deleter(SmartPtr const & p) +{ + return static_cast(p._internal_get_deleter(typeid(D))); +} +#endif + +} + +#endif + +#endif + diff --git a/src/libs/ice/ICESocket.h b/src/libs/ice/ICESocket.h new file mode 100644 index 00000000..bc8447ff --- /dev/null +++ b/src/libs/ice/ICESocket.h @@ -0,0 +1,32 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_SOCKET_H +#define __ICE_SOCKET_H + +#include "ICEPlatform.h" +#include "ICETypes.h" +#include + +namespace ice { + +struct ICESocket +{ + std::string mHostIP; + unsigned short mPort; + SOCKET mHandle; + unsigned int mPriority; + + ICESocket() + :mPort(0), mHandle(INVALID_SOCKET), mPriority(0) + {} + + ~ICESocket() + {} +}; + +}; + +#endif diff --git a/src/libs/ice/ICEStream.cpp b/src/libs/ice/ICEStream.cpp new file mode 100644 index 00000000..acfc626b --- /dev/null +++ b/src/libs/ice/ICEStream.cpp @@ -0,0 +1,2895 @@ +/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEStream.h" +#include "ICENetworkHelper.h" +#include "ICEBinding.h" +#include "ICERelaying.h" +#include "ICELog.h" +#include "ICESync.h" +#include "ICESession.h" + +#include +#include +#include + +using namespace ice; + +#define LOG_SUBSYSTEM "ICE" + +const char* ice::RunningStateToString(RunningState state) +{ + switch(state) + { + case None: return "None"; + case CandidateGathering: return "CandidateGathering"; + case EliminateRedudand: return "EliminateRedudand"; + case ComputingFoundations: return "ComputingFoundations"; + case StartingKeepAlives: return "StartingKeepAlives"; + case PrioritizingCandidates: return "PrioritizingCandidates"; + case ChoosingDefault: return "ChoosingDefault"; + case CreatingSDP: return "CreatingSDP"; + case ConnCheck: return "ConnCheck"; + case Failed: return "Failed"; + case Success: return "Success"; + } + return "Undefined"; +} + + + +#pragma region BindingAction + +// This class is intended to bring client binding results with candidates +class BindingAction: public Action +{ +public: + BindingAction(Stream& stream, StackConfig& config) + :Action(stream, config) + { + } + + virtual void finished(Transaction& st) + { + // Declare possible keepalive binding transaction + ClientBinding* kaBinding = NULL; + + // Cast finished transaction to ClientBinding + ClientBinding& cb = dynamic_cast(st); + + // Iterate local candidate to update values + for (unsigned i=0; isetStackId(mStream.mStackId); + + // Set destination address + kaBinding->setDestination(cb.transportType() == IPv4 ? mConfig.mServerAddr4 : mConfig.mServerAddr6); + + // Set source component port number + kaBinding->setComponent(st.component()); + kaBinding->setKeepalive(true); + kaBinding->setInterval(mConfig.mKeepAliveInterval); + mStream.mActiveChecks.addRegular(kaBinding); +#endif + } + else + { + ICELogCritical( << "Stack ID " << st.stackId() << ". Failed to gather reflexive candidate."); + mStream.mErrorCode = cb.errorCode(); + } + } +}; + +#pragma endregion + +#pragma region RelayingAction + +class RelayingAction: public Action +{ +protected: + bool mAutoreleaseAllocation; + +public: + RelayingAction(Stream& stream, StackConfig& config) + :Action(stream, config), mAutoreleaseAllocation(false) + { + } + + void autoreleaseAllocation() + { + mAutoreleaseAllocation = true; + } + + virtual void finished(Transaction& transaction) + { + ClientAllocate& ca = dynamic_cast(transaction); + + // Increase counter of finished Allocate requests + mStream.mFailoverRequestsFinished++; + ICELogDebug(<< "Increase failover gathering finished requests counter to " << mStream.mFailoverRequestsFinished); + + // Check if this Allocation must be freed ASAP + if (mAutoreleaseAllocation) + { + if (ca.state() == Transaction::Success) + { + ICELogInfo(<< "Has to free this allocation as it is not needed due to failover scheme"); + // Increase counter of turn allocation for stream. It will be decreased again in ClientRefresh::processSuccessMessage + mStream.mTurnAllocated++; + + // Send deallocation message + ClientRefresh* allocation = new ClientRefresh(0, &mStream, &ca); + allocation->setKeepalive(false); + allocation->setDestination(ca.destination()); + mStream.mActiveChecks.addRegular(allocation); + } + return; + } + + // Save latest credentials from server + if (ca.realm().size() && ca.nonce().size()) + { + mStream.mCachedRealm = ca.realm(); + mStream.mCachedNonce = ca.nonce(); + } + + // Update local candidates + for (unsigned i=0; isetInterval(5); + //cf->setInterval( ca.lifetime() / 2); + cf->setKeepalive( true ); + cf->setType( Transaction::KeepAlive ); + cf->setDestination(ca.destination()); + + // Defer transaction run to interval() value + cf->setTimestamp( ICETimeHelper::timestamp() ); + + // Increase counter of TURN allocations + mStream.mTurnAllocated++; + + // Associate Refresh transaction with retransmission timer + mStream.mActiveChecks.addRegular(cf); +#endif + } + else + { + ICELogCritical( << "Stack ID " << transaction.stackId() << ". Failed to gather reflexive/relayed addresses."); + bool ressurected = false; + // Check if single server is used and error code is 437 - in this case attempt to recover old Allocation will be made + if (mStream.mConfig.mServerList4.size() < 2 && ca.errorCode() == 437) + { + if (true == (ressurected = mStream.ressurectAllocation(transaction.component()))) + { + // Increase counter of TURN allocations + mStream.mTurnAllocated++; + + ICELogCritical(<< "Stack ID " << transaction.stackId() << ". Ressurected old Refresh transaction. Error will not be raized."); + } + } + + if (!ressurected) + mStream.mErrorCode = ca.errorCode(); + + // There is no any further processing here - result of transaction will be handled later + } + } +}; +#pragma endregion + +#pragma region CheckPairAction +class CheckPairAction: public Action +{ + friend struct Stream; +public: + CheckPairAction(Stream& stream, StackConfig& config, PCandidatePair& p) + :Action(stream, config), mPair(p), mNomination(false), mAgentRole(stream.mAgentRole) + { + } + + virtual ~CheckPairAction() + { + } + + virtual void finished(Transaction& transaction) + { + CheckResult& cr = dynamic_cast(transaction); + + //ConnectivityCheck& cb = dynamic_cast(transaction); + + bool success = false; + if (cr.resultState() == Transaction::Failed) + { + // Handle role conflict + if (cr.resultError() == 487) + { + // Change session role + if (mAgentRole == RoleControlling) + mStream.mAgentRole = RoleControlled; + else + mStream.mAgentRole = RoleControlling; + + transaction.restart(); + return; + } + } + else + success = true; + + // A check is considered to be a success if all of the following are + // true: + //- the STUN transaction generated a success response + success &= cr.resultState() == Transaction::Success; + + if (success && mNomination && + mPair->nomination() != CandidatePair::Nomination_Finished) + { + ICELogInfo(<< "Received response for nominated request"); + + // Add keep-alive check + mStream.addKeepAliveCheck(*mPair); + + // Nomination is finished for this pair + mPair->setNomination(CandidatePair::Nomination_Finished); + + // Ensure RTCP component is unfrozen + mStream.unfreeze(mPair->foundation()); + + // Maybe processing for component is finished? + mStream.checkNominated(); + + return; + } + + // Reset transaction tag for checked pair + mPair->setTransaction(NULL); + + ICELogInfo ( << "Stack ID " << transaction.stackId() << ". Check " << mPair->toStdString() << " is " << (success ? "ok" : "failed") << "."); + + //- the source IP address and port of the response equals the + // destination IP address and port that the Binding Request was sent + // to + if (success) + success &= (cr.resultSource() == mPair->second().mExternalAddr); + + //- the destination IP address and port of the response match the + // source IP address and port that the Binding Request was sent from + mPair->setState(success ? CandidatePair::Succeeded : CandidatePair::Failed); + + if (success) + { + std::string foundation = mPair->foundation(); + mStream.dumpLocalCandidateList(); + unsigned li = mStream.findLocalCandidate( cr.resultLocal() ); + ICELogDebug( << "Looking for " << cr.resultLocal().toStdString() << " in local candidate list. Result index is " << int(li) ); + if ( li == NoIndex ) + { + // Add peer reflexive candidate + ICELogInfo(<< "Add peer reflexive candidate " << cr.resultLocal().toStdString()); + + // Its type is equal to peer reflexive. + Candidate cand(Candidate::PeerReflexive); + cand.mExternalAddr = cr.resultLocal(); + + // Its base is set equal to the local candidate of the candidate pair from which the STUN check was sent. + cand.mLocalAddr = mPair->first().mLocalAddr; + + // Its priority is set equal to the value of the PRIORITY attribute in the Binding Request. + cand.mPriority = cr.resultPriority(); + + // Its foundation is selected as described in Section 4.1.1. + cand.computeFoundation(); + + // This peer reflexive candidate is then added to the list of local + // candidates for the media stream + mStream.mLocalCandidate.push_back(cand); + + // The agent constructs a candidate pair whose local candidate equals + // the mapped address of the response, and whose remote candidate equals + // the destination address to which the request was sent. + CandidatePair _pair; + + // Use created local peer reflexive candidate + _pair.first() = cand; + + // Create new remote candidate + Candidate& newRemoteCand = _pair.second(); + newRemoteCand.mLocalAddr = cr.resultSource(); + newRemoteCand.mExternalAddr = cr.resultSource(); + newRemoteCand.mPriority = cr.resultPriority(); + newRemoteCand.computeFoundation(); + + _pair.updateFoundation(); + _pair.updatePriority(); + _pair.setRole(CandidatePair::Valid); + mStream.checkList().add(_pair); + + // Ensure reference to original ICECandidatePair is valid yet + ICELogInfo( << "Stack ID " << transaction.stackId() << ". Created peer reflexive candidate and corresponding pair " << _pair.toStdString() << " in valid list."); + } + else + { + ICELogInfo( << "Stack ID " << transaction.stackId() << ". Pair " << mPair->toStdString() <<" is add to valid list."); + mPair->setRole(CandidatePair::Valid); // And this pair is valid now + } + + // Now - unfreeze all pairs from the same queue and same foundation + mStream.unfreeze(foundation.c_str()); + mPair->setTransaction(&transaction); + + // Start regular nomination + if (mStream.mAgentRole == RoleControlling && !mNomination) + { + Component& component = mStream.mComponentMap[transaction.component()]; + + // If remote address is not LAN - maybe it should be delayed to give chance + // to finish LAN -> LAN checks before. + // ICE_NOMINATION_WAIT_INTERVAL is responsible for this + if (!mPair->second().mExternalAddr.isLAN() && ICE_NOMINATION_WAIT_INTERVAL != 0 && mStream.mState != Success) + { + // Check if + if (!component.mNominationWaitIntervalStartTime) + { + component.mNominationWaitIntervalStartTime = ICETimeHelper::timestamp(); + return; + } + else + { + unsigned currentTime = ICETimeHelper::timestamp(); + if (ICETimeHelper::findDelta(component.mNominationWaitIntervalStartTime, currentTime) >= ICE_NOMINATION_WAIT_INTERVAL) + mNomination = true; // Start nomination + } + } + else + mNomination = true; + + if (mNomination && mStream.mState != Success) + { + component.mNominationWaitIntervalStartTime = 0; // Stop nomination interval timer + mStream.nominatePair(mPair); + } + } + } + else + mPair->setState(CandidatePair::Failed); + } + + PCandidatePair& getPair() + { + return mPair; + } + + void setNomination(bool value) + { + mNomination = value; + } + + bool nomination() const + { + return mNomination; + } + +protected: + PCandidatePair mPair; /// Pair + bool mNomination; /// Nomination request flag + int mAgentRole; +}; + +#pragma endregion + +#pragma region ICEInstallPermissions + +//This class is intended to bring client binding results with candidates +class ICEInstallPermissionsAction: public Action +{ +protected: + InstallPermissionsCallback* mCallback; + +public: + ICEInstallPermissionsAction(Stream& stream, StackConfig& config, InstallPermissionsCallback* cb) + :Action(stream, config), mCallback(cb) + { + } + + ~ICEInstallPermissionsAction() + { + delete mCallback; + } + + virtual void finished(Transaction& st) + { + ClientCreatePermission& ccp = dynamic_cast(st); + int code = 0; + + if (st.state() == Transaction::Success) + { + ClientCreatePermission::IpList al = ccp.ipList(); + std::string iptext; + for (unsigned i=0; i(st); + code = auth.errorCode() ? auth.errorCode() : -1; + } + if (mCallback) + mCallback->onPermissionsInstalled(mStream.mId, st.component(), code); + } +}; + +#pragma endregion +static long GStackID = 0; + +Stream::Stream() +{ + mErrorCode = 0; + mState = None; + mFoundationGenerator = 0xFFFFFFFF; + mAgentRole = RoleControlling; + mDefaultIPChanged = false; + mCanTransmit = false; + + mStackId = Atomic::increment(&GStackID); + mTurnAllocated = 0; + mFailoverRequestsFinished = 0; + mFailoverIdGenerator = 0; +} + +Stream::~Stream() +{ +} + +void Stream::setConfig(StackConfig& config) +{ + mCachedNonce.clear(); + mCachedRealm.clear(); + mConfig = config; +} + +int Stream::addComponent(void* tag, unsigned short port4, unsigned short port6) +{ + int componentID = mComponentMap.size() + 1; + + Component& c = mComponentMap[componentID]; + c.mTag = tag; + c.mPort4 = port4; + c.mPort6 = port6; + + return componentID; +} +void Stream::setAgentRole(AgentRole role) +{ + mAgentRole = role; +} + +void Stream::setLocalPwd(const std::string& pwd) +{ + mLocalPwd = pwd; +} + +void Stream::setLocalUfrag(const std::string& ufrag) +{ + mLocalUfrag = ufrag; +} + +void Stream::setRemotePwd(const std::string& pwd) +{ + mRemotePwd = pwd; +} + +void Stream::setRemoteUfrag(const std::string& ufrag) +{ + mRemoteUfrag = ufrag; +} + +void Stream::setTieBreaker(const std::string& tieBreaker) +{ + mTieBreaker = tieBreaker; +} + +void Stream::gatherCandidates() +{ + ICELogInfo (<<"Stack ID " << mStackId << ". Attempt to gather candidates. Use IPv4 = " << mConfig.mUseIPv4 << ", IPv6 = " << mConfig.mUseIPv6); + mState = CandidateGathering; + mErrorCode = 0; + mFailoverRequestsFinished = 0; + mLocalCandidate.clear(); + mDefaultCandidate.clear(); + + // Get list of available IP interfaces + Lock l(NetworkHelper::instance().guard()); + std::vector& interfaceList = NetworkHelper::instance().interfaceList(); + for (auto& addr: interfaceList) + ICELogDebug(<< " " << addr.toStdString()); + + // See if there is public IP address + // Iterate components + + int numberOfActions = 0; + + ComponentMap::iterator componentIter; + for (componentIter = mComponentMap.begin(); componentIter != mComponentMap.end(); ++componentIter) + { + ICELogDebug(<< "Checking ICE component " << componentIter->first); + BindingAction* bindingAction = nullptr; + RelayingAction *relayingAction = nullptr, /**getIp6Action = nullptr,*/ *getIp4Action = nullptr; + + // Clear binding results as new allocation will exists anyway + removeBindingResult(componentIter->first); + + // Iterate available IP interfaces i.e. local IP addresses + for (unsigned interfaceIndex = 0; interfaceIndex < interfaceList.size(); interfaceIndex++) + { + NetworkAddress& ipInterface = interfaceList[interfaceIndex]; + if (ipInterface.isLoopback() || ipInterface.isLinkLocal() || ipInterface.isZero()) + continue; + + ICELogInfo(<< "Checking interface " << ipInterface.toStdString()); + + // Find local port number for this + int port = ipInterface.family() == AF_INET ? componentIter->second.mPort4 : + componentIter->second.mPort6; + + // Define host candidate + Candidate host(Candidate::Host); + if ((ipInterface.family() == AF_INET && mConfig.mUseIPv4) || + (ipInterface.family() == AF_INET6 && mConfig.mUseIPv6)) + { + host.setLocalAndExternalAddresses(ipInterface, + ipInterface.family() == AF_INET6 ? componentIter->second.mPort6 : componentIter->second.mPort4); + host.mComponentId = componentIter->first; + host.mInterfacePriority = 0; + // Gathering of host candidate is finished + host.mReady = true; // Gathering finished + host.mFailed = false; // With success + + mLocalCandidate.push_back(host); + } + + // Check if IPv4 reflexive address is needed. + // It can be gathered with IPv4 relaying request also + bool needReflexiveAddr = mConfig.mUseIPv4 && mConfig.mServerList4.size() > 0; + + // Check if IPv4 relayed address is needed + bool needRelayingAddr = + mConfig.mUseIPv4 && mConfig.mServerList4.size() > 0 && mConfig.mUseTURN; + + // Check if 6-to-4 relaying is required + bool needIPv6ToIPv4 = !mConfig.mUseIPv4 && mConfig.mUseIPv6 && + !mConfig.mServerAddr6.isEmpty() && !mConfig.mServerAddr6.isZero() && mConfig.mUseProtocolRelay; + + // Check if 4-to-6 relaying is required + /*bool needIPv4ToIPv6 = mConfig.mUseIPv4 && mConfig.mUseIPv6 && + mConfig.mServerList4.size() > 0 && mConfig.mUseProtocolRelay; + */ + + // Prepare candidate instances. + Candidate reflexive(Candidate::ServerReflexive); + Candidate relayed(Candidate::ServerRelayed); + + // Save initial local&external IP and port number + relayed.setLocalAndExternalAddresses( ipInterface, port ); + reflexive.setLocalAndExternalAddresses( ipInterface, port ); + + // Assign component ID + relayed.mComponentId = reflexive.mComponentId = componentIter->first; + + // Put interface priority as zero - there is no configuration option for it yet + relayed.mInterfacePriority = reflexive.mInterfacePriority = 0; + + bool restOnPublic = false; +#ifdef ICE_REST_ON_PUBLICIP + if ( ipInterface.isPublic() && ipInterface.type() == AF_INET ) + restOnPublic = true; +#endif + + // See if there we need reflexive candidate yet + if (mConfig.mUseSTUN && !restOnPublic && !bindingAction && + needReflexiveAddr && ipInterface.family() == AF_INET) + { + ICELogInfo(<< "Request reflexive address"); + // Add candidate to list + mLocalCandidate.push_back(reflexive); + + // Bind transaction to candidate + if (!bindingAction) + bindingAction = new BindingAction(*this, mConfig); + } + + if (mConfig.mUseTURN && !restOnPublic && !relayingAction && needRelayingAddr) + { + ICELogInfo(<< "Request relayed address"); + // Add relayed candidate to list + mLocalCandidate.push_back(relayed); + + // Add reflexive candidate to list + mLocalCandidate.push_back(reflexive); + + // Bind allocation to reflexive candidate + if (!relayingAction) + relayingAction = new RelayingAction(*this, mConfig); + } + + if (!getIp4Action && needIPv6ToIPv4 && ipInterface.family() == AF_INET6) + { + ICELogInfo(<< "Requesting IPv6 to IPv4 relay."); + Candidate c(Candidate::ServerRelayed); + c.setLocalAndExternalAddresses(ipInterface, port); + c.mInterfacePriority = 0; + c.mComponentId = componentIter->first; + mLocalCandidate.push_back(relayed); + getIp4Action = new RelayingAction(*this, mConfig); + } + + /* + if (!getIp6Action && needIPv4ToIPv6 && ipInterface.type() == AF_INET) + { + ICELogInfo(<< "Requesting IPv4 to IPv6 relay."); + Candidate c(Candidate::ServerRelayed); + c.setLocalAndExternalAddresses(ipInterface, port); + c.mInterfacePriority = 0; + c.mComponentId = componentIter->first; + mLocalCandidate.push_back(relayed); + getIp6Action = new RelayingAction(*this, mConfig); + } + */ + } + + if (bindingAction) + { + bind(mConfig.mServerAddr4, PAction(bindingAction), false/*it is gathering!*/, componentIter->first, mConfig.mServerList4.empty() ? FailoverOff : FailoverOn); + numberOfActions++; + } + if (relayingAction) + { + ICELogDebug(<< "Request relayed candidate IPv4 <-> IPv4."); + AllocateOptions options; + options.mActionOnFinish = PAction(relayingAction); + options.mComponent = componentIter->first; + options.mFailoverOption = mConfig.mServerList4.empty() ? FailoverOff : FailoverOn; + options.mServerAddress = mConfig.mServerAddr4; + allocate(options); + numberOfActions++; + } + + if (getIp4Action) + { + ICELogDebug(<< "Request relayed candidate IPv6 <-> IPv4."); + AllocateOptions options; + options.mActionOnFinish = PAction(getIp4Action); + options.mComponent = componentIter->first; + options.mFailoverOption = mConfig.mServerList6.empty() ? FailoverOff : FailoverOn; + options.mServerAddress = mConfig.mServerAddr6; + options.mWireFamily = AF_INET6; + options.mAllocFamily = AF_INET; + // Ask TURN server to allocation IPv4 address via IPv6 address + allocate(options); + numberOfActions++; + } + + // SDK does not use IPv4 to IPv6 relaying for now. Reverse direction has to be used instead. + /* + if (getIp6Action) + { + AllocateOptions options; + options.mActionOnFinish = PAction(getIp6Action); + options.mComponent = componentIter->first; + options.mAllocFamily = AF_INET6; + options.mWireFamily = AF_INET; + options.mServerAddress = mConfig.mServerAddr4; + options.mFailoverOption = mConfig.mServerList4.empty() ? FailoverOff : FailoverOn; + // Ask TURN server to allocate IPv6 address via IPv4 socket + allocate(options); + numberOfActions++; + }*/ + + } + + if (!numberOfActions) + { + mState = EliminateRedudand; + processStateChain(); + } +} + +CheckList& Stream::checkList() +{ + return mCheckList; +} + + +void Stream::allocate(const AllocateOptions& options) +{ + assert(options.mComponent != -1); + + if (options.mFailoverOption == FailoverOn) + { + // If failover scheme is required - spread requests to few servers + std::vector& servers = options.mWireFamily == AF_INET ? mConfig.mServerList4 : mConfig.mServerList6; + int failoverId = ++mFailoverIdGenerator; + for (std::vector::iterator addrIter = servers.begin(); addrIter != servers.end(); addrIter++) + { + AllocateOptions options2(options); + options2.mServerAddress = *addrIter; + options2.mFailoverId = failoverId; + options2.mFailoverOption = FailoverOff; + allocate(options2); + } + } + else + { + ClientAllocate* allocation = new ClientAllocate(mConfig.mTurnLifetime); + allocation->setStackId(mStackId); + allocation->setWireFamily(options.mWireFamily); + allocation->setAllocFamily(options.mAllocFamily); + allocation->setDestination(options.mServerAddress); + allocation->setComponent(options.mComponent); + allocation->setFailoverId(options.mFailoverId); + + // Use auth for TURN server + allocation->setPassword(mConfig.mTurnPassword); + allocation->setUsername(mConfig.mTurnUsername); + + // Associate it with action + allocation->setAction(options.mActionOnFinish); + + mActiveChecks.addRegular(allocation); + } +} + +void Stream::bind(const NetworkAddress& dest, PAction action, bool /*auth*/, int component, Failover f) +{ + assert(component != -1); + + if (f == FailoverOn) + { + for (std::vector::iterator addrIter = mConfig.mServerList4.begin(); addrIter != mConfig.mServerList4.end(); addrIter++) + { + bind(*addrIter, action, false, component, FailoverOff); + } + } + else + { + ClientBinding* binding = new ClientBinding(); + binding->setStackId(mStackId); + binding->setDestination(dest); + binding->setComponent(component); + + // Associate it with action + binding->setAction(action); + + mActiveChecks.addRegular(binding); + } +} + + +bool Stream::hasPortNumber(int family, unsigned short portNumber, int* component) +{ + ComponentMap::iterator componentIterator; + for (componentIterator = mComponentMap.begin(); componentIterator != mComponentMap.end(); ++componentIterator) + { + if ((family == AF_INET && componentIterator->second.mPort4 == portNumber) || + (family == AF_INET6 && componentIterator->second.mPort6 == portNumber)) + { + if (component) + *component = componentIterator->first; + return true; + } + } + + return false; +} + +unsigned Stream::findRemoteCandidate(const NetworkAddress& addr, int componentID) +{ + for (size_t i=0; i(p.transaction()))) + { + ICELogInfo(<< "Transaction for pair " << p.toStdString() << " is cancelled"); + mActiveChecks.erase((Transaction*)p.transaction()); + } +} + +class EraseBindingAndRelaying: public TransactionCondition +{ +public: + bool check(Transaction* t) const + { + ClientRefresh* c = dynamic_cast(t); + if (c) + { + if (!c->lifetime()) + return false; + } + + if ((Transaction::Binding | Transaction::Relaying) & t->type()) + return true; + + return false; + } +}; + +class KeepDeallocationRequest: public TransactionCondition +{ +public: + bool check(Transaction* t) const + { + ClientRefresh* c = dynamic_cast(t); + if (c) + { + if (!c->lifetime()) + return false; + } + return true; + } +}; + + +void Stream::cancelAllocations() +{ + mActiveChecks.erase(KeepDeallocationRequest()); +} + +void Stream::handleBindingRequest(ServerBinding& binding, ByteBuffer& buffer, int component) +{ + if (mComponentMap.find(component) == mComponentMap.end()) + return; + + // If the source transport address of the request does not match any + // existing remote candidates, it represents a new peer reflexive remote + // candidate. This candidate is constructed as follows: + unsigned candidateIndex = findRemoteCandidate(buffer.remoteAddress(), component); + if (candidateIndex == NoIndex) + { + ICELogInfo(<< "Stack ID " << mStackId << ". Remote candidate with address " << buffer.remoteAddress().toStdString() << " is not found so creating peer reflexive candidate."); + + // Construct candidate + Candidate newRemoteCand(Candidate::PeerReflexive); + + // Set priority from request's priority attribute + newRemoteCand.mPriority = binding.priorityValue(); + + // Set address + newRemoteCand.setLocalAndExternalAddresses(buffer.remoteAddress()); + + // The foundation of the candidate is set to an arbitrary value, + // different from the foundation for all other remote candidates. If + // any subsequent offer/answer exchanges contain this peer reflexive + // candidate in the SDP, it will signal the actual foundation for the + // candidate. + sprintf(newRemoteCand.mFoundation, "%u", --mFoundationGenerator); + + // The component ID of this candidate is set to the component ID for + // the local candidate to which the request was sent. + newRemoteCand.mComponentId = component; + + // This candidate is added to the list of remote candidates. However, + // the agent does not pair this candidate with any local candidates. + mRemoteCandidate.push_back(newRemoteCand); + + candidateIndex = (unsigned)mRemoteCandidate.size()-1; + } + + // Next, the agent constructs a pair whose local candidate is equal to + // the transport address on which the STUN request was received, and a + // remote candidate equal to the source transport address where the + // request came from (which may be peer-reflexive remote candidate that + // was just learned). + CandidatePair _pair; + + // Find local transport address (IP) + NetworkAddress interfaceIP; + if (buffer.relayed()) + { + // Find relayed ip:port for given component + for (unsigned i=0; isetNomination(CandidatePair::Nomination_Finished); + + ICELogInfo(<< "Stack ID " << mStackId << ". Pair " << existingPair->toStdString() + << " already exists in check list. Its state is " + << CandidatePair::stateToString(existingPair->state())); + + if (mConfig.mTreatRequestAsConfirmation) + { + if (existingPair->transaction()) + { + ConnectivityCheck* cc = dynamic_cast((Transaction*)existingPair->transaction()); + if (cc) + { + if (!cc->removed()) + cc->confirmTransaction(buffer.remoteAddress()); + } + } + } + + // There can be one of several outcomes: + // If the state of that pair is Waiting or Frozen, a check for + // that pair is enqueued into the triggered check queue if not + // already present. + switch (existingPair->state()) + { + case CandidatePair::Frozen: + case CandidatePair::Waiting: + existingPair->setRole(CandidatePair::Triggered); + existingPair->setState(CandidatePair::Waiting); + break; + + case CandidatePair::InProgress: + // If the state of that pair is In-Progress, the agent cancels the + // in-progress transaction. Cancellation means that the agent + // will not retransmit the request, will not treat the lack of + // response to be a failure, but will wait the duration of the + // transaction timeout for a response. In addition, the agent + // MUST create a new connectivity check for that pair + // (representing a new STUN Binding Request transaction) by + // enqueuing the pair in the triggered check queue. The state of + // the pair is then changed to Waiting. + if (existingPair->role() == CandidatePair::Regular) + { + cancelCheck(*existingPair); + existingPair->setState(CandidatePair::Waiting); + existingPair->setRole(CandidatePair::Triggered); + + // Re-run new check in prioritized list + Transaction* t = createCheckRequest(existingPair); + if (buffer.relayed()) + { + t->setComment("Check from " + existingPair->first().mExternalAddr.toStdString() + + " to " + existingPair->second().mExternalAddr.toStdString()); + t->setRelayed(true); + } + existingPair->setTransaction(t); + mActiveChecks.addPrioritized(t); + } + break; + + case CandidatePair::Failed: + // If the state of the pair is Failed, it is changed to Waiting + // and the agent MUST create a new connectivity check for that + // pair (representing a new STUN Binding Request transaction), by + // enqueuing the pair in the triggered check queue. + existingPair->setState(CandidatePair::Waiting); + existingPair->setRole(CandidatePair::Triggered); + break; + + case CandidatePair::Succeeded: + //existingPair.setNominated(); + break; + } + } + else + { + // If the pair is not already on the check list: + // The pair is inserted into the check list based on its priority + + // Its state is set to Waiting + _pair.setState(CandidatePair::Waiting); + _pair.setRole(CandidatePair::Triggered); + ICELogInfo(<< "Stack ID " << mStackId << ". Adding pair " << _pair.toStdString() << " to triggered check list"); + mCheckList.add(_pair); + ICELogInfo(<< "Resulting check list is \r\n" << mCheckList.toStdString()); + } +} + +bool Stream::processData(StunMessage& msg, ByteBuffer& buffer, int component) +{ + bool result = true; + + // Depending on the state call the handler + if (mState < CreatingSDP) + { + result = handleCgIn(msg, buffer.remoteAddress()); + if (result) + processStateChain(); + return result; + } + else + if (mState >= ConnCheck) + { + if (handleConnChecksIn(msg, buffer.remoteAddress())) + { + ICELogDebug(<< "Found response for transaction from " << buffer.remoteAddress().toStdString()); + checkNominated(); + return true; + } + } + else + if (handleConnChecksIn(msg, buffer.remoteAddress())) + return true; + + + // Check if source address&request belongs to TURN server - so it is relayed candidate in action + if (buffer.remoteAddress() == mConfig.mServerAddr4) + { + if (buffer.size() < 4) + return false; + + TurnPrefix prefix = *reinterpret_cast(buffer.data()); + + // For requests being received on a relayed candidate, the source + // transport address used for STUN processing (namely, generation of the + // XOR-MAPPED-ADDRESS attribute) is the transport address as seen by the + // TURN server. That source transport address will be present in the + // REMOTE-ADDRESS attribute of a Data Indication message, if the Binding + // Request was delivered through a Data Indication (a TURN server + // delivers packets encapsulated in a Data Indication when no active + // destination is set). If the Binding Request was not encapsulated in + // a Data Indication, that source address is equal to the current active + // destination for the TURN session. + + //check channel binding prefix + if (mTurnPrefixMap.find(prefix) != mTurnPrefixMap.end()) + { + NetworkAddress& sourceAddr = mTurnPrefixMap[prefix]; + buffer.setRemoteAddress(sourceAddr); + buffer.erase(0, 4); + buffer.setRelayed(true); + } + } + + handleIncomingRequest(msg, buffer, component); + + if (mCheckList.state() == CheckList::Failed) + mState = Failed; + else + checkNominated(); + + return result; +} + + +bool Stream::handleCgIn(StunMessage& msg, NetworkAddress& address) +{ + if (!mActiveChecks.processIncoming(msg, address)) + return false; + if (mLocalCandidate.empty()) + return true; + + // Check if failover and relaying is used + if (mConfig.mUseTURN && !mConfig.mServerList4.empty()) + { + int successCounter = 0, failedCounter = 0; + for (size_t i=0; i= mLocalCandidate.size()) + { + // Shift to next state + ICELogInfo(<< "All candidates succeeded, shift to EliminateRedudand"); + mState = EliminateRedudand; + } + else + { + // See if all gathering requests are performed. + if ((size_t)mFailoverRequestsFinished == mConfig.mServerList4.size() * mComponentMap.size()) + { + ICELogInfo(<< "All failover gathering requests finished, shift to Failed"); + mState = Failed; + } + } + } + else + { + // Look if all gathering checks are finished + bool finished = true; + + for (size_t i=0; i c2.mExternalAddr.port()) + return true; + else + if (c1.mExternalAddr.port() < c2.mExternalAddr.port()) + return false; + + if (c1.mExternalAddr.ip() > c2.mExternalAddr.ip()) + return true; + else + return false; +} + +bool RedudandCand( const ice::Candidate& c1, const ice::Candidate& c2) +{ + return c1.mExternalAddr == c2.mExternalAddr; +} + +void Stream::Handle_ER() +{ + // Remove failed candidates (without STUN/TURN responses) + mLocalCandidate.erase(std::remove_if(mLocalCandidate.begin(), mLocalCandidate.end(), + FailedCand), mLocalCandidate.end()); + + // Sort candidates by priority + unsigned int cand_per_component = unsigned(( mLocalCandidate.size() ) / mComponentMap.size()); + for (unsigned int i=0; icomputeFoundation(); + + mState = StartingKeepAlives; +} + +void Stream::Handle_SKA() +{ +#ifdef ICE_ENABLE_KEEPALIVE + //TODO: replace successful transactions to keep alive state +#endif + + mState = PrioritizingCandidates; +} + +bool PriorityGreater(const Candidate& c1, const Candidate& c2) +{ + return c1.mPriority > c2.mPriority; +} + +void Stream::Handle_PC() +{ + for (size_t i = 0; i < mLocalCandidate.size(); ++i) + mLocalCandidate[i].computePriority(mConfig.mTypePreferenceList); + + // Find the candidates range for each component ID + ComponentMap::iterator componentIter = mComponentMap.begin(); + for (; componentIter != mComponentMap.end(); componentIter++) + { + // Find range start + size_t minIndex = 0xFFFFFFFF, maxIndex = 0; + + for (CandidateVector::size_type i = 0; i < mLocalCandidate.size(); i++) + { + if (mLocalCandidate[i].mComponentId == (int)componentIter->first) + { + // Wow, we have found first candidate with the specified componentID + minIndex = i; + + break; + } + } + + // Find range max + for (int i = (int)mLocalCandidate.size()-1; i >=0; i--) + { + if (mLocalCandidate[i].mComponentId == componentIter->first) + { + // Wow, we have found first candidate with the specified componentID + maxIndex = i; + + break; + } + } + + if (minIndex == 0xFFFFFFFF) + return; + + CandidateVector::iterator bit = mLocalCandidate.begin() + minIndex; + CandidateVector::iterator fit; + if (maxIndex == mLocalCandidate.size()-1) + fit = mLocalCandidate.end(); + else + fit = mLocalCandidate.begin() + maxIndex + 1; + + std::sort(bit, fit, PriorityGreater); + } + + mState = ChoosingDefault; +} + +void Stream::Handle_CD() +{ + mDefaultCandidate.clear(); + ComponentMap::iterator componentIter = mComponentMap.begin(); + for (; componentIter != mComponentMap.end(); componentIter++) + mDefaultCandidate[componentIter->first] = findDefaultCandidate(componentIter->first); + + if (mDefaultCandidate.empty()) + throw std::logic_error("Cannot find default candidate."); + + mState = CreatingSDP; +} + +Candidate Stream::findDefaultCandidate(int componentID) +{ + // Extract all candidates for specified component to separate vector + CandidateVector candidateList; + for (size_t i=0; isetComment("Response for connectivity check request."); + + // Set destination address + // If request has come via relayed candidate - send it back using SendIndication + if (buffer.relayed()) + { + ByteBuffer* si = SendIndication::buildPacket( buffer.remoteAddress(), *responseBuffer, mConfig.mServerAddr4, buffer.component() ); + delete responseBuffer; responseBuffer = si; + responseBuffer->setComment( "SI for CC response to " + buffer.remoteAddress().toStdString() ); + } + else + responseBuffer->setRemoteAddress( buffer.remoteAddress() ); + + // Set component port number + responseBuffer->setComponent(buffer.component()); + + // Send response immediately + mResponseQueue.push_back(responseBuffer); + } + } + } +} + +void Stream::checkNominated(int component) +{ + // If there are no nominated pairs in the valid list for a media + // stream and the state of the check list is Running, ICE processing + // continues. + if (mCheckList.state() != CheckList::Running) + return; + + // Attempt to find nominated pair + unsigned i; + for (i=0; inomination() != CandidatePair::Nomination_Finished || mCheckList[i]->state() != CandidatePair::Succeeded); i++) + ; + + if (i == mCheckList.count()) + return; + + // If there is at least one nominated pair in the valid list for a + // media stream and the state of the check list is Running: + + // The agent MUST remove all Waiting and Frozen pairs in the check + // list and triggered check queue for the same component as the + // nominated pairs for that media stream + mCheckList.removePairs(CandidatePair::Frozen, component); + mCheckList.removePairs(CandidatePair::Waiting, component); + +#ifndef ICE_DONT_CANCEL_CHECKS_ON_SUCCESS + // If an In-Progress pair in the check list is for the same + // component as a nominated pair, the agent SHOULD cease + // retransmissions for its check if its pair priority is lower + // than the lowest priority nominated pair for that component. + PCandidatePair lowestPair = mCheckList.findLowestNominatedPair(component); + if (lowestPair) + { + int64_t lowestPriority = lowestPair->priority(); + + for (unsigned i=0; isecond.mNominationWaitIntervalStartTime && mAgentRole == RoleControlling) + { + PCandidatePair validPair = mCheckList.findBestValidPair(componentIter->first); + if (validPair) + { + unsigned currentTime = ICETimeHelper::timestamp(); + if (ICETimeHelper::findDelta(componentIter->second.mNominationWaitIntervalStartTime, currentTime) >= ICE_NOMINATION_WAIT_INTERVAL) + nominatePair(validPair); + } + } + } + } + + if (mNominationWaitStartTime && mCheckList.countOfValidPairs() && mAgentRole == RoleControlling) + { + unsigned currentTime = ICETimeHelper::timestamp(); + if (ICETimeHelper::findDelta(mNominationWaitStartTime, currentTime) >= ICE_NOMINATION_WAIT_INTERVAL) + { + // Iterate components + for (auto componentIter = mComponentMap.begin(); componentIter != mComponentMap.end(); ++componentIter) + { + PCandidatePair validPair = mCheckList.findBestValidPair(componentIter->first); + if (validPair) + nominatePair(validPair); + } + } + } + + // Process all components + ComponentMap::iterator componentIter = mComponentMap.begin(); + for (; componentIter != mComponentMap.end(); componentIter++) + checkNominated(componentIter->first); + + // Once there is at least one nominated pair in the valid list for + // every component of at least one media stream and the state of the + // check list is Running: + + // The agent MUST change the state of processing for its check + // list for that media stream to Completed. + + bool found = true; + componentIter = mComponentMap.begin(); + for (; componentIter != mComponentMap.end(); componentIter++) + found &= mCheckList.findNominatedPair(componentIter->first).get() != nullptr; + + if (found && mCheckList.state() == CheckList::Running) + { + mCheckList.setState(CheckList::Completed); + + // Create vector of default + std::map defaultCandList; + componentIter = mComponentMap.begin(); + for (; componentIter != mComponentMap.end(); componentIter++) + { + int componentId = componentIter->first; + PCandidatePair highestPair = mCheckList.findHighestNominatedPair(componentId); + if (highestPair) + { + defaultCandList[componentId] = Candidate(highestPair->first()); + + // Compare with existing default IP list + if (!Candidate::equal(defaultCandList[componentId], mDefaultCandidate[componentId])) + mDefaultIPChanged = true; + } + } + + mDefaultCandidate = defaultCandList; + mCanTransmit = true; + } + + // Once the state of each check list is Completed: + //ICELogDebug(<< "Stack ID " << mStackID << ". Check list state is " << mCheckList.stateToString(mCheckList.state())); + if (mCheckList.state() == CheckList::Completed) + { + // The agent sets the state of ICE processing overall to + // completed. + if (mState != Success && mState > CandidateGathering) + { + ICELogCritical( << "Stack ID " << mStackId << ". Check list is completed, so session is succeeded."); + mState = Success; + } + } + else + if (mCheckList.state() == CheckList::Failed) + { + // If the state of the check list is Failed, ICE has not been able to + // complete for this media stream. The correct behavior depends on + // the state of the check lists for other media streams: + + // If all check lists are Failed, ICE processing overall is + // considered to be in the Failed state, and the agent SHOULD + // consider the session a failure, SHOULD NOT restart ICE, and the + // controlling agent SHOULD terminate the entire session. + if (mState != Failed && mState > CandidateGathering) + { + ICELogCritical(<< "Stack ID " << mStackId << ". Check list is failed, so session is failed too."); + mState = Failed; + } + clearChecks(); + //TODO: + //If at least one of the check lists for other media streams is + //Completed, the controlling agent SHOULD remove the failed media + //stream from the session in its updated offer. + + //If none of the check lists for other media streams are + //Completed, but at least one is Running, the agent SHOULD let + //ICE continue. + } +} + +bool Stream::handleRoleConflict(ServerBinding& binding) +{ + ICELogCritical( << "Stack ID " << mStackId << ". Detected role conflict. Local role is " << + (mAgentRole == RoleControlled ? "Controlled" : "Controlling") << ", remote role is " << + (binding.role() == RoleControlled ? "Controlled" : "Controlling") << "."); + + // Compare tie breakers + int compareResult = memcmp(mTieBreaker.c_str(), binding.remoteTieBreaker().c_str(), 8); + + if (mAgentRole == RoleControlling) + { + // So remove + if (compareResult >= 0) + { + // Queue 487 error to remote peer + binding.generate487(); + return true; + } + else + mAgentRole = RoleControlled; + } + else + { + if (compareResult < 0) + { + // Enqueue 487 error to remote peer + binding.generate487(); + return true; + } + else + mAgentRole = RoleControlling; + } + + // Recompute pair priorities for all stream's queues and triggered check queue + mCheckList.updatePairPriorities(); + + return false; +} + +void Stream::createOfferSdp(std::vector& defaultIP, std::vector& defaultPort, + std::vector& candidateList) +{ + // Iterator all components + ComponentMap::iterator componentIter = mComponentMap.begin(); + for (; componentIter != mComponentMap.end(); componentIter++) + { + // Find default IP for this component + defaultIP.push_back(mDefaultCandidate[componentIter->first].mExternalAddr.ip()); + defaultPort.push_back(mDefaultCandidate[componentIter->first].mExternalAddr.port()); + + for (unsigned candidateCounter=0; candidateCounterfirst) + { + candidateList.push_back(cand.createSdp()); +#ifdef ICE_VIRTUAL_CANDIDATES + if (cand.mType == Candidate::ServerReflexive || cand.mType == Candidate::PeerReflexive) + { + for (int i=0; i= componentID) + return mDefaultCandidate[componentID].mExternalAddr; + + if (mComponentMap.find(componentID) != mComponentMap.end()) + { + NetworkAddress result = NetworkHelper::instance().sourceInterface(NetworkAddress(mConfig.mTargetIP, 1)); + result.setPort(mComponentMap[componentID].mPort4); + return result; + } + return NetworkAddress(); +} + +void Stream::candidateList(int componentID, std::vector& candidateList) +{ + for (unsigned i=0; icomponent(); + tag = mComponentMap[component].mTag; + + return result; +} + +Transaction* Stream::runCheckList(CandidatePair::Role r, CandidatePair::State state) +{ + Transaction* result = NULL; + for (unsigned i=0; irole() != r || p->transaction()) + continue; + + if (p->state() == state) + { + ICELogInfo(<<"Creating check request for " << p->toStdString()); + + // Create binding request + result = createCheckRequest(p); + + // Mark candidate pair as InProgress + p->setTransaction(result); + p->setState(CandidatePair::InProgress); + } + } + return result; +} + +ByteBuffer* Stream::handleConnChecksOut() +{ + // Update stream state + checkNominated(); + + // Loop while we have time to send packets + if (mScheduleTimer.isTimeToSend()) + { + // Declare pointer to created check request + Transaction* request = NULL; + + // Check for triggered request + //ICELogInfo(<<"Create checks for triggered waiting pairs for list " << std::endl << mCheckList.toStdString()); + request = runCheckList(CandidatePair::Triggered, CandidatePair::Waiting); + if (request) + mActiveChecks.addPrioritized(request); + else + { + request = runCheckList(CandidatePair::Regular, CandidatePair::Waiting); + if (request) + mActiveChecks.addRegular(request); + else + { + // Find Frozen check with highest priority and lowest componentID in check list + request = runCheckList(CandidatePair::Regular, CandidatePair::Frozen); + if (request) + mActiveChecks.addRegular(request); + } + } + + } + + // ICELogDebug(<< "Looking for transaction to send"); + // Loop while active transaction is not found + Transaction* t; int attemptCounter = 0; + do + { + attemptCounter++; + t = mActiveChecks.getNextTransaction(); + if (!t) + continue; + // This code forces keepalive transaction to its intervals + if (!t->hasToRunNow()) + t = NULL; + } + while (!t && attemptCounter < mActiveChecks.count()); + + if (!t) + return NULL; + + ByteBuffer* buffer = t->generateData(); + if (!buffer) + return NULL; + + // Self test + /*StunMessage msg; + msg.parsePacket(*buffer); + std::ostringstream oss; + msg.dump(oss); + ICELogDebug(<< "Self test result: " << oss.str()); + */ + ICELogInfo(<< "Generating packet for " << (t->relayed() ? "relayed " : "") << t->comment() << " to " << t->destination().toStdString()); + if (t->relayed()) + { + ByteBuffer* si = SendIndication::buildPacket(t->destination(), *buffer, mConfig.mServerAddr4, t->component()); + si->setComment("Relayed: " + buffer->comment()); + delete buffer; buffer = si; + } + + assert(!buffer->remoteAddress().isEmpty()); + return buffer; +} + + +Transaction* Stream::createCheckRequest(PCandidatePair& p) +{ + // Get reference to checked pair + + // Create transaction - depending on candidates it can be regular ConnectivityCheck or RelayedConnectivityCheck + ConnectivityCheck* cc = new ConnectivityCheck(); + + cc->setRelayed( p->first().mType == Candidate::ServerRelayed ); + cc->setStackId( mStackId ); + cc->setComponent( p->first().mComponentId ); + + // Add PRIORITY attribute + unsigned int peerReflexivePriority = 0xFFFFFF * mConfig.mTypePreferenceList[Candidate::PeerReflexive] + + (p->first().mInterfacePriority << 8) + (256 - p->first().mComponentId); + + cc->addPriority( peerReflexivePriority ); + + cc->addFingerprint( true ); + cc->setDestination( p->second().mExternalAddr ); + cc->setComment( p->toStdString() ); + + // Add CONTROLLED or CONTROLLING attribute + switch (mAgentRole) + { + case RoleControlled: + cc->addControlledRole(mTieBreaker); + break; + + case RoleControlling: + cc->addControllingRole(mTieBreaker); + break; + + default: + assert(0); + } + + // Enable short term credentials + cc->addShortTermCredentials(true); + + // Set right username and password + cc->setUsername(mRemoteUfrag + ":" + mLocalUfrag); + cc->setPassword(mRemotePwd); + + // Add action + cc->setAction(PAction(new CheckPairAction(*this, mConfig, p))); + + // Do not forget about aggressive nomination + if (mConfig.mAggressiveNomination) + cc->addUseCandidate(); + + ICELogInfo( << "Stack ID " << mStackId << ". Created " << (cc->relayed() ? "RCC" : "CC") << " for " << p->toStdString() << " and destination " << cc->destination().toStdString() << "."); + + return cc; +} + +TurnPrefix Stream::findTurnPrefixByAddress(NetworkAddress& peerAddress) +{ + TurnPrefixMap::iterator tpit = mTurnPrefixMap.begin(); + for (; tpit != mTurnPrefixMap.end(); ++tpit) + { + NetworkAddress& addr = tpit->second; + if (addr == peerAddress) + return tpit->first; + } + + return 0; +} + +class KeepAliveCheckCondition: public TransactionCondition +{ +protected: + NetworkAddress mTarget; + int mComponentId; + +public: + KeepAliveCheckCondition(const NetworkAddress& address, int componentId) + :mTarget(address), mComponentId(componentId) + { + + } + + bool check(Transaction* t) const + { + BindingIndication* bi = dynamic_cast(t); + if (!bi) + return false; + if (!bi->keepalive()) + return false; + + return (t->component() == mComponentId && t->destination() == mTarget); + } +}; + +void Stream::addKeepAliveCheck(CandidatePair& _pair) +{ +#ifdef ICE_ENABLE_KEEPALIVE + // Ensure it is new keepalive check + if (mActiveChecks.exists(KeepAliveCheckCondition(_pair.second().mExternalAddr, _pair.first().mComponentId))) + return; + + // Create binding indication transaction + BindingIndication* bi = new BindingIndication(mConfig.mKeepAliveInterval); + bi->setStackId(mStackId); + bi->setKeepalive(true); + bi->setInterval(mConfig.mKeepAliveInterval); + + // Restart transaction on finish + //bi->setUserObject(new CandidatePair(_pair)); + + // Do not forget to comment transaction + bi->setComment("Keepalive check for " + _pair.toStdString()); + + // Set destination + bi->setDestination(_pair.second().mExternalAddr); + + // Set component port + bi->setComponent(_pair.first().mComponentId); + + // Put transaction to container + mActiveChecks.addRegular(bi); +#endif +} + +bool Stream::processSdpOffer( std::vector& candidateList, std::string defaultIP, unsigned short defaultPort, bool deleteRelayed) +{ + if (candidateList.empty()) + { + // Anyway we may need TURN permissions installed + if (mState >= CreatingSDP && mConfig.mUseTURN) + { + ICELogDebug(<< "Installing permissions for default address " << defaultIP << ":" << defaultPort); + installPermissions(-1, NetworkAddress(defaultIP, defaultPort)); + } + return false; + } + + // Save remote candidate list + std::set availComponents; + + for (size_t i=0; ifirst) != availComponents.end()) + validComponentMap[componentIter->first] = componentIter->second; + else + { + // Do not deallocate turn candidate here - side effect can be bad + } + } + mComponentMap = validComponentMap; + + // Ensure there is at least one component + if (mComponentMap.empty()) + { + ICELogCritical(<< "SDP offer is not valid; it has no components"); + return false; + } + + // Check if candidate list includes default IP:pair + bool result = candidateListContains(defaultIP, defaultPort); + + // Delete relayed candidates if needed + if (deleteRelayed) + { + mRemoteRelayedCandidate.clear(); + CandidateVector::iterator candIter = mRemoteCandidate.begin(); + while (candIter != mRemoteCandidate.end()) + { + if (candIter->mType == Candidate::ServerRelayed) + { + mRemoteRelayedCandidate.push_back(*candIter); + candIter = mRemoteCandidate.erase(candIter); + } + else + candIter++; + } + } + + return result; +} + +bool Stream::candidateListContains(const std::string& remoteIP, unsigned short remotePort) +{ + NetworkAddress remote; + remote.setIp(remoteIP.c_str()); + remote.setPort(remotePort); + + for (size_t i=0; ifirst || !local.mReady ) + continue; + + for (unsigned remoteIndex=0; remoteIndex(t); + if (c) + return false; + ClientChannelBind* ccb = dynamic_cast(t); + if (ccb) + return false; + ClientCreatePermission* ccp = dynamic_cast(t); + if (ccp) + return false; + + // Send indication is not listed here; it is sent directly without transaction list proxy. + return true; + } +}; + +void Stream::stopChecks() +{ + // Clear generated check list + mCheckList.clear(); + + // Delete corresponding transactions + mActiveChecks.erase(DeleteChecksAndGathers()); + + // Avoid responding to remote peer's transactions + if (mState < Failed) + mState = Failed; +} + + + +void Stream::clear() +{ + ICELogDebug(<< "Clear ICE stream"); + mState = None; + + // Clear connectivity checks list + mCheckList.clear(); + + // Delete all transactions except possible deallocation requests + mActiveChecks.erase(KeepDeallocationRequest()); + + // Remote candidates are not needed anymore + mRemoteCandidate.clear(); + mRemoteRelayedCandidate.clear(); + mDefaultCandidate.clear(); + mComponentLimit.clear(); + mTurnPrefixMap.clear(); + mScheduleTimer.stop(); + mTurnAllocated = 0; + mDefaultIPChanged = false; + for (ComponentMap::iterator componentIter = mComponentMap.begin(); componentIter != mComponentMap.end(); componentIter++) + componentIter->second.mNominationWaitIntervalStartTime = 0; + mNominationWaitStartTime = 0; + mFailoverRequestsFinished = 0; +} + +class DeleteConnChecks: public TransactionCondition +{ +public: + bool check(Transaction* t) const + { + return (dynamic_cast(t) != NULL); + } +}; + +class DeleteChannelBindingRequests: public TransactionCondition +{ +public: + bool check(Transaction* t) const + { + return (dynamic_cast(t) != NULL); + } +}; + +class DeleteClientRefreshes: public TransactionCondition +{ +public: + bool check(Transaction* t) const + { + return (dynamic_cast(t) != NULL); + } +}; + +class DeleteCreatePermissions: public TransactionCondition +{ +public: + bool check(Transaction* t) const + { + return (dynamic_cast(t) != NULL); + } +}; + +class DeleteClientBindings: public TransactionCondition +{ +public: + bool check(Transaction* t) const + { + return dynamic_cast(t) != NULL; + } +}; + +class DeleteClientAllocations: public TransactionCondition +{ +public: + bool check(Transaction* t) const + { + return dynamic_cast(t) != NULL; + } +}; + +void Stream::clearForRestart(bool localNetworkChanged) +{ + ICELogDebug(<< "Clear ice stream before restart"); + mState = None; + mCheckList.clear(); + mRemoteCandidate.clear(); + mRemoteRelayedCandidate.clear(); + mTurnAllocated = 0; + + // Here deleting transactions common for remote or local peer changing networks + + // Existing connectivity checks must be removed - there is no sense in result from them + mActiveChecks.erase(DeleteConnChecks()); + + // Existing channel binding requests are useless now - new ones should be sent - with new IP:port (when remote peer changes) or after creation new socket(s) (when local peer changes) + mActiveChecks.erase(DeleteChannelBindingRequests()); + + // And there is no sense in old TURN permissions + mActiveChecks.erase(DeleteCreatePermissions()); + + if (localNetworkChanged) + { + // No sense to refresh current TURN allocation - old socket is lost, there is no way to send from the same ip:port pair exactly + mActiveChecks.erase(DeleteClientRefreshes()); + + // Maybe new candidates were gathering when network changed - so remove old ClientBinding requests + mActiveChecks.erase(DeleteClientBindings()); + + // The same about TURN allocations - delete allocation requests. + mActiveChecks.erase(DeleteClientAllocations()); + } +} + +void Stream::restart() +{ + mErrorCode = 0; + if (mState > CreatingSDP) + mState = ConnCheck; + else + mState = None; + + mCheckList.clear(); +} + +NetworkAddress Stream::remoteAddress(int componentID) +{ + NetworkAddress result; + PCandidatePair highestPair = mCheckList.findHighestNominatedPair(componentID); + if (highestPair) + { + result = highestPair->second().mExternalAddr; + result.setRelayed(highestPair->first().mType == Candidate::ServerRelayed); + } + + return result; +} + +NetworkAddress Stream::localAddress(int component) +{ + PCandidatePair highestPair = mCheckList.findHighestNominatedPair(component); + if (highestPair) + return highestPair->first().mExternalAddr; + else + return NetworkAddress(); +} + +class FreeAllocationAction: public Action +{ +protected: + DeleteAllocationCallback* mCallback; +public: + FreeAllocationAction(Stream& stream, StackConfig& config, DeleteAllocationCallback* cb) + :Action(stream, config), mCallback(cb) + { + + } + ~FreeAllocationAction() + { + delete mCallback; + } + + void finished(Transaction& transaction) + { + AuthTransaction& auth = dynamic_cast(transaction); + int code = auth.state() == Transaction::Failed ? (auth.errorCode() ? auth.errorCode() : -1) : 0; + + if (mCallback) + mCallback->onAllocationDeleted(mStream.mId, transaction.component(), code); + } +}; + +void Stream::freeAllocation(int component, DeleteAllocationCallback* cb) +{ + // Clear bindings + removeBindingResult(component); + + if (component == -1) + { + ComponentMap::iterator compIter; + for (compIter = mComponentMap.begin(); compIter != mComponentMap.end(); ++compIter) + freeAllocation(compIter->first, cb); + } + else + { + ClientRefresh* allocation = new ClientRefresh(0, this); + allocation->setStackId( mStackId ); + allocation->setDestination( (mConfig.mServerAddr4.isZero() || mConfig.mServerAddr4.isEmpty()) ? mConfig.mServerAddr6 : mConfig.mServerAddr4); + allocation->setPassword( mConfig.mTurnPassword ); + allocation->setUsername( mConfig.mTurnUsername ); + allocation->setComponent( component ); + allocation->setKeepalive( false ); +#ifdef ICE_CACHE_REALM_NONCE + allocation->setRealm( mCachedRealm ); + allocation->setNonce( mCachedNonce ); +#endif + // Associate it with action + allocation->setAction(PAction(new FreeAllocationAction(*this, mConfig, cb))); + + mActiveChecks.addRegular(allocation); + } +} + +class ChannelBindResultAction: public Action +{ +protected: + ChannelBoundCallback* mCallback; + +public: + ChannelBindResultAction(Stream& stream, StackConfig& config, ChannelBoundCallback* cb) + :Action(stream, config), mCallback(cb) + {} + + ~ChannelBindResultAction() + { + delete mCallback; + } + + void finished(Transaction& transaction) + { + ClientChannelBind& cb = dynamic_cast(transaction); + Stream::BoundChannel channel; + channel.mComponentId = cb.component(); + channel.mPrefix = cb.channelPrefix(); + channel.mPeerAddress = cb.peerAddress(); + channel.mResultCode = 0; + + if (cb.state() == Transaction::Failed) + channel.mResultCode = cb.errorCode() ? cb.errorCode() : -1; + + ICELogDebug(<< "Saving TURN channel binding result " << channel.mPrefix << " to " << channel.mPeerAddress.toStdString()); + mStream.mBoundChannelList.push_back(channel); + if (mCallback) + mCallback->onChannelBound(mStream.mId, cb.component(), channel.mResultCode); + } +}; + +TurnPrefix Stream::bindChannel(const NetworkAddress& peerAddress, int component, ChannelBoundCallback* cb) +{ + ICELogInfo(<< "Bind TURN channel for " << peerAddress.toStdString() << " for component " << component); + + // Check if the request binding is done already + BoundChannelList::iterator channelIter = mBoundChannelList.begin(); + for (;channelIter != mBoundChannelList.end(); ++channelIter) + { + if (channelIter->mComponentId == component && channelIter->mPeerAddress == peerAddress) + { + if (!channelIter->mResultCode) + { + ICELogInfo(<< "Already bound to prefix " << channelIter->mPrefix); + return channelIter->mPrefix; + } + } + } + + ChannelBindResultAction* action = new ChannelBindResultAction(*this, mConfig, cb); + + // Create transaction + ClientChannelBind* ccb = new ClientChannelBind( peerAddress ); + ccb->setStackId( mStackId ); + + ccb->setUsername( mConfig.mTurnUsername ); + ccb->setPassword( mConfig.mTurnPassword ); + ccb->setDestination( mConfig.mUseIPv6 && !mConfig.mUseIPv4 ? mConfig.mServerAddr6 : mConfig.mServerAddr4 ); + ccb->setComponent( component ); +#ifdef ICE_CACHE_REALM_NONCE + ccb->setRealm( mCachedRealm ); + ccb->setNonce( mCachedNonce ); +#endif + ccb->setAction(PAction(action)); + mActiveChecks.addRegular(ccb); + + return ccb->channelPrefix(); +} + +bool Stream::isChannelBindingFailed(int component, TurnPrefix prefix) +{ + BoundChannelList::iterator channelIter = mBoundChannelList.begin(); + for (; channelIter != mBoundChannelList.end(); ++channelIter) + if (channelIter->mComponentId == component && channelIter->mPrefix == prefix) + return channelIter->mResultCode != 0; + + return false; +} + +void Stream::removeBindingResult(int component) +{ + // Clear related channel bindings + Stream::BoundChannelList::iterator channelIter = mBoundChannelList.begin(); + while (channelIter != mBoundChannelList.end()) + { + if (channelIter->mComponentId == component) + { + ICELogDebug(<< "Clearing TURN channel binding " << channelIter->mPrefix << " for " << channelIter->mPeerAddress.toStdString()); + channelIter = mBoundChannelList.erase(channelIter); + } + else + channelIter++; + } +} + + +NetworkAddress Stream::reflexiveAddress(int componentID) +{ + for (size_t i=0; ifirst && component != -1) + continue; + + ClientCreatePermission* ccp = new ClientCreatePermission(); + + ccp->setComment( "CreatePermissions request" ); + ccp->setStackId( mStackId ); + ccp->setDestination( (mConfig.mServerAddr4.isEmpty() || mConfig.mServerAddr4.isZero()) ? mConfig.mServerAddr6 : mConfig.mServerAddr4 ); + ccp->setUsername( mConfig.mTurnUsername ); + ccp->setPassword( mConfig.mTurnPassword ); + +#ifdef ICE_CACHE_REALM_NONCE + ccp->setRealm( mCachedRealm ); + ccp->setNonce( mCachedNonce ); +#endif + ccp->setAction( PAction(new ICEInstallPermissionsAction(*this, mConfig, cb)) ); + + // Get remote candidates for given component + if (addr.isEmpty()) + { + for (auto candIter = mRemoteCandidate.begin(); candIter != mRemoteCandidate.end(); candIter++) + if (candIter->mComponentId == cmip->first && candIter->mExternalAddr.isPublic()) + ccp->addIpAddress(candIter->mExternalAddr); + for (auto candIter = mRemoteRelayedCandidate.begin(); candIter != mRemoteRelayedCandidate.end(); candIter++) + if (candIter->mComponentId == cmip->first) + ccp->addIpAddress(candIter->mExternalAddr); + } + else + ccp->addIpAddress(addr); + ccp->setComponent(cmip->first); + + // Enqueue transaction + mActiveChecks.addPrioritized(ccp); + requestCounter++; + } + ICELogDebug(<< "Created " << requestCounter << " CreatePermission requests"); +} + +void Stream::dump(std::ostream& output) +{ + output << Logger::TabPrefix << "State: " << RunningStateToString(mState) << std::endl; + output << Logger::TabPrefix << "Local candidates: " << std::endl; + for (unsigned i=0; ifirst(); + remote = validPair->second(); + return true; +} + +int Stream::findComponentIdByPort(unsigned short port, int family) +{ + ComponentMap::iterator it = mComponentMap.begin(); + for (;it != mComponentMap.end();it++) + if (family == AF_INET) + { + if (it->second.mPort4 == port) + return it->first; + } + else + { + if (it->second.mPort6 == port) + return it->first; + } + + return -1; +} + +void Stream::clearChecks() +{ + switch (mState) + { + case Success: + mCheckList.clear(); + mActiveChecks.erase(EraseBindingAndRelaying()); + break; + + case Failed: + mCheckList.clear(); + mActiveChecks.erase(KeepDeallocationRequest()); + break; + + default: + break; + } +} + +void Stream::dumpLocalCandidateList() +{ + std::ostringstream oss; + oss << "Local candidate list:" << std::endl; + for (unsigned i=0; iremoved()) + return false; + if (!t->action()) + return false; + if (t == mValidTransaction) + return false; + if (t->component() != mComponent) + return false; + if (t->failoverId() != mFailoverId) + return false; + + // Special case for Allocate + RelayingAction* relayingAction = dynamic_cast(t->action().get()); + bool binding = dynamic_cast(t->action().get()) != NULL; + + if (relayingAction) + relayingAction->autoreleaseAllocation(); + + return binding; + } +}; + +void Stream::removeGatherRequests(int component, int failoverId, Transaction* validOne) +{ + mActiveChecks.erase(GatheringCondition(component, failoverId, validOne)); +} + +void Stream::nominatePair(PCandidatePair &p) +{ + // Check if pair is already nominated + if (p->nomination() != p->Nomination_None) + return; + + if (!p->transaction()) + { + // It can be newly created candidate pair + PCandidatePair equalPair = mCheckList.findEqualPair(*p, CheckList::CT_Strict); + if (equalPair) + createCheckRequest(equalPair); + } + + Transaction* t = reinterpret_cast(p->transaction()); + if (!t) + { + ICELogCritical(<< "Logical error in nomination procedure."); + return; + } + + CheckResult* cr = dynamic_cast(t); + + p->setNomination(CandidatePair::Nomination_Started); + + // Restart binding transaction + t->restart(); + + + // "upgrade" binding transaction to include USE-CANDIDATE attribute + cr->useCandidate(); + + // Push log records + t->setComment("Nominated request for " + p->toStdString()); + ICELogInfo (<< "Stack ID " << t->stackId() << ". Generated nominated candidate request for pair " << p->toStdString()); + + // Prioritize restarted transaction + mActiveChecks.prioritize(t); + + // Mark transaction's action as nomination + CheckPairAction* cp = dynamic_cast(t->action().get()); + if (cp) + cp->setNomination(true); +} + +class OldAllocationCondition: public TransactionCondition +{ +protected: + int mComponent; +public: + OldAllocationCondition(int component) + :mComponent(component) + {} + + bool check(Transaction* t) const + { + if (!t->removed()) + return false; + ClientRefresh* cf = dynamic_cast(t); + if (!cf) + return false; + return true; + } +}; +bool Stream::ressurectAllocation(int component) +{ + std::vector allocations; + mActiveChecks.copyMatching(OldAllocationCondition(component), allocations); + if (allocations.empty()) + return false; + // Find most recent allocation + unsigned current = ICETimeHelper::timestamp(); + unsigned delta = 0xFFFFFFFF; + Transaction* chosen = NULL; + for (size_t index=0; indextimestamp() < delta) + { + chosen = t; + delta = current - t->timestamp(); + } + } + + if (!chosen) + return false; + + ClientRefresh* cf = dynamic_cast(chosen); + if (!cf) + return false; // Just extra check + cf->setRemoved(false); + + // Update local candidates + for (unsigned i=0; ireflexiveAddress(); + else + if (c.mType == Candidate::ServerRelayed) + c.mExternalAddr = cf->relayedAddress(); + } + } + return true; +} diff --git a/src/libs/ice/ICEStream.h b/src/libs/ice/ICEStream.h new file mode 100644 index 00000000..58ebe85c --- /dev/null +++ b/src/libs/ice/ICEStream.h @@ -0,0 +1,367 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_STREAM_H +#define __ICE_STREAM_H + +#include +#include + +#include "ICEBox.h" +#include "ICECandidate.h" +#include "ICEStunConfig.h" +#include "ICEAction.h" +#include "ICEStunTransaction.h" +#include "ICECheckList.h" +#include "ICEBinding.h" +#include "ICETime.h" +#include "ICETransactionList.h" +#include "ICERelaying.h" + +namespace ice +{ + enum Failover + { + FailoverOn = 1, + FailoverOff = 2 + }; + + // Session state + enum RunningState + { + None = 0, + CandidateGathering, + EliminateRedudand, + ComputingFoundations, + StartingKeepAlives, + PrioritizingCandidates, + ChoosingDefault, + CreatingSDP, + ConnCheck, + Failed, + Success + }; + + extern const char* RunningStateToString(RunningState state); + + // Smart pointer to ICE stream type + typedef SmartPtr ICEStreamPtr; + + + // Map of used channel TURN prefixes as key and corresponding address as value + typedef std::map TurnPrefixMap; + + struct Component + { + void* mTag; + unsigned short mPort4; + unsigned short mPort6; + unsigned mNominationWaitIntervalStartTime; + Component() + :mTag(NULL), mPort4(0), mPort6(0), mNominationWaitIntervalStartTime(0) + {} + + ~Component() + { + } + }; + + typedef std::map ComponentMap; + + // Represents single ICE stream with single or multiple components (sockets) + struct Stream + { + // Stream id + int mId; + + // Stack ID. Used for debugging purposes. + int mStackId; + + // Map of component ID -> user tag + ComponentMap mComponentMap; + + // List of local candidates and list of remote candidates + typedef std::vector CandidateVector; + CandidateVector mLocalCandidate, mRemoteCandidate, mRemoteRelayedCandidate; + + // Check list + CheckList mCheckList; + + // Logger + Logger* mLogger; + + // Foundation generator value to provide foundation value for peer reflexive candidates + unsigned int mFoundationGenerator; + + // Active STUN transactions. This vector includes connectivity check transactions and gather candidates transactions. + // Keepalive transactions are stored in mKeepAliveList + TransactionList mActiveChecks; + + // ICE agent role + AgentRole mAgentRole; + + // Map of established relay channels + TurnPrefixMap mTurnPrefixMap; + + // Current state of media stream + RunningState mState; + + // Used configuration + StackConfig mConfig; + + // Helper vector used to prioritize candidates + std::vector mComponentLimit; + + // Default candidate list - one per each component + std::map mDefaultCandidate; + + // Local password/ufrag + std::string mLocalPwd; + std::string mLocalUfrag; + + // Remote password/ufrag + std::string mRemotePwd; + std::string mRemoteUfrag; + + // Marks if selected during connectivity checks default IP list differs from used to generate offer + bool mDefaultIPChanged; + + // Marks if checks was ok for this stream and each component has valid nominated pair + bool mCanTransmit; + + std::vector mResponseQueue; + // Tie breaker + std::string mTieBreaker; + + // Timer to schedule connection checks (CC) + ICEScheduleTimer mScheduleTimer; + + // Counter of TURN allocations + int mTurnAllocated; + + // Last error code during gathering/checks + int mErrorCode; + + // Cached realm and nonce for used TURN server + std::string mCachedRealm, mCachedNonce; + + // Timestamp of nomination waiting timer. Used to accumulate valid pairs and chose the "best" of them. + unsigned mNominationWaitStartTime; + + // Number of finished failover gathering requests + int mFailoverRequestsFinished; + + // Failover ID generator. Failover transactions which share the same goal share the same ID. + int mFailoverIdGenerator; + + struct BoundChannel + { + int mComponentId; + TurnPrefix mPrefix; + NetworkAddress mPeerAddress; + int mResultCode; + }; + typedef std::vector BoundChannelList; + BoundChannelList mBoundChannelList; + + // Create Allocate transaction and associate with passed action + struct AllocateOptions + { + NetworkAddress mServerAddress; + PAction mActionOnFinish; + int mComponent = 0; + Failover mFailoverOption = FailoverOn; + int mWireFamily = AF_INET; + int mAllocFamily = AF_INET; + int mFailoverId = 0; + }; + void allocate(const AllocateOptions& options); + + // Create Bind transaction and associate with passed action + void bind(const NetworkAddress& addr, PAction action, bool auth, int component, Failover failover); + + // Searches for local candidate with specified address + unsigned findLocalCandidate(const NetworkAddress& addr); + + // Cancels found transaction. + void cancelCheck(CandidatePair& p); + + // Cancels allocations + void cancelAllocations(); + + // Searches for remote candidate with specified remote address and corresponding to local port number + unsigned findRemoteCandidate(const NetworkAddress& addr, int componentID); + + // Process incoming binding request + void handleBindingRequest(ServerBinding& binding, ByteBuffer& buffer, int component); + + // Handles incoming data in gathering candidate stage. + bool handleCgIn(StunMessage& msg, NetworkAddress& address); + + // Handle eliminate redudand stage + void Handle_ER(); + + // Compute foundations + void Handle_CF(); + + // Starting keep alive timers + void Handle_SKA(); + + // Prioritize candidates + void Handle_PC(); + + // Choosing default candidate + void Handle_CD(); + + // Handles keepalive messages + //bool handleKeepAlivesIn(StunMessage& msg, NetworkAddress& address); + + // Handles incoming messages in connectivity checks stage + // This method uses Handle_KA_In to perform keepalive handling + bool handleConnChecksIn(StunMessage& msg, NetworkAddress& address); + + // Handle incoming Bind request + void handleIncomingRequest(StunMessage& msg, ByteBuffer& buffer, int component); + + // Chooses default candidate for specified component ID + Candidate findDefaultCandidate(int componentID); + + //Performs 8.1.2. Updating States + void checkNominated(int componentID); + void checkNominated(); + bool handleRoleConflict(ServerBinding& binding); + + //Checks active transactions (keepalive and ordinary) for timeouts + void isTimeout(); + + // Checks for next byte buffer for sending + ByteBuffer* handleConnChecksOut(); + + // Creates connectivity check request for specified pair. + Transaction* createCheckRequest(PCandidatePair& p); + + // Checks for TURN channel prefix by specified peer's address. + // Returns zero prefix if it is not found. + TurnPrefix findTurnPrefixByAddress(NetworkAddress& peerAddress); + + // Create candidate pair in check list. + void createCheckList(); + + // Starts connectivity checks - calls Create_CheckList to create check list + starts retransmission timer + void startChecks(); + + // Stops connectivity checks and gathering requests + void stopChecks(); + + // Initiates ChannelBind transaction to TURN server. + TurnPrefix bindChannel(const NetworkAddress& peerAddress, int component, ChannelBoundCallback* cb = NULL); + bool isChannelBindingFailed(int component, TurnPrefix prefix); + void removeBindingResult(int component); + + // Attempts to free allocation. + void freeAllocation(int component, DeleteAllocationCallback* cb = NULL); + + // Searches for local server reflexive candidate with specified component ID and returns its external address. + NetworkAddress reflexiveAddress(int componentID); + + /*! Searches for local server relayed candidate with specified component ID and returns its external address. */ + NetworkAddress relayedAddress(int componentID); + + // Searches for remote server relayed candidate with specified component + NetworkAddress remoteRelayedAddress(int component); + + // Searches for remote server reflexive candidate with specified component + NetworkAddress remoteReflexiveAddress(int component); + + + Stream(); + ~Stream(); + + // Sets config + void setConfig(StackConfig& config); + + // Sets ICE agent role - Controlled or Controlling + void setAgentRole(AgentRole role); + + // Sets local password + void setLocalPwd(const std::string& pwd); + + // Sets local ufrag + void setLocalUfrag(const std::string& ufrag); + + // Sets remote password + void setRemotePwd(const std::string& pwd); + + // Sets remote ufrag + void setRemoteUfrag(const std::string& ufrag); + + // Sets tie breaker + void setTieBreaker(const std::string& tieBreaker); + + // Adds new component to stream + int addComponent(void* tag, unsigned short port4, unsigned short port6); + + // Gathers candidates for stream + void gatherCandidates(); + + // Returns reference to check list + CheckList& checkList(); + + // Check is stream owns specified port number + bool hasPortNumber(int family, unsigned short portNumber, int* component = NULL); + + // Processes incoming data + bool processData(StunMessage& msg, ByteBuffer& buffer, int component); + + void createOfferSdp(std::vector& defaultIP, std::vector& defaultPort, + std::vector& candidateList); + + NetworkAddress defaultAddress(int componentID); + void candidateList(int componentID, std::vector& candidateList); + + PByteBuffer getDataToSend(bool& response, int& component, void*&tag); + + // Constructs new keepalive transaction and adds to mKeepAlives + void addKeepAliveCheck(CandidatePair& p); + + // Processes SDP offer, adding remote candidates from it + bool processSdpOffer(std::vector& candidateList, std::string defaultIP, unsigned short defaultPort, bool deleteRelayed); + + // Checks if remote candidate list contains specified address + bool candidateListContains(const std::string& remoteIP, unsigned short remotePort); + + // Restarts stream's connectivity checks + void restart(); + + // Clears the stack; resets state to None. The free allocation requests are left in the queue + void clear(); + + // Deletes existing connectivity checks and resets turn allocation counters + void clearForRestart(bool localNetworkChanged); + + // Returns resolved address of remote party identified by its componmentID + NetworkAddress remoteAddress(int component); + NetworkAddress localAddress(int component); + + void installPermissions(int component = -1, const NetworkAddress& addr = NetworkAddress(), InstallPermissionsCallback* cb = NULL); + void dump(std::ostream& output); + bool findConcludePair(Candidate& local, Candidate& remote); + int findComponentIdByPort(unsigned short port, int family); + Transaction* runCheckList(CandidatePair::Role role, CandidatePair::State state); + void deleteTransactionAt(unsigned index); + void clearChecks(); + + void dumpLocalCandidateList(); + void processStateChain(); + + // Disables (removes) active transactions responsible for gathering candidates - binding & allocating + void removeGatherRequests(int component, int failoverId, Transaction* validOne); + void unfreeze(const char* foundation); + void nominatePair(PCandidatePair& p); + bool ressurectAllocation(int component); + }; +} + +#endif diff --git a/src/libs/ice/ICEStunAttributes.cpp b/src/libs/ice/ICEStunAttributes.cpp new file mode 100644 index 00000000..3e25b205 --- /dev/null +++ b/src/libs/ice/ICEStunAttributes.cpp @@ -0,0 +1,956 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEPlatform.h" +#include "ICEStunAttributes.h" +#include "ICENetworkHelper.h" +#include +using namespace ice; + + + +// --- MappedAddress --- +MappedAddress::MappedAddress() +{ +} + +MappedAddress::~MappedAddress() +{ +} + +int MappedAddress::type() const +{ + return StunAttribute::MappedAddress; +} + +NetworkAddress& MappedAddress::address() +{ + return mAddress; +} + +void MappedAddress::buildPacket(BufferWriter& writer) +{ + writer.writeUChar(0); + writer.writeUChar(mAddress.stunType()); + writer.writeUShort(mAddress.port()); + + switch (mAddress.stunType()) + { + case IPv4: + writer.writeBuffer(&mAddress.sockaddr4()->sin_addr, 4); + break; + + case IPv6: + writer.writeBuffer(&mAddress.sockaddr6()->sin6_addr, 16); + break; + + default: + assert(0); + } +} + +bool MappedAddress::parsePacket(BufferReader& reader) +{ + // Dequeue zero byte and ignore it + /*uint8_t zeroByte = */reader.readUChar(); + + // Dequeue family + mAddress.setStunType(reader.readUChar()); + + // Dequeue port + mAddress.setPort(reader.readUShort()); + + // Deqeueue IP + mAddress.setIp(reader.readIp(mAddress.stunType() == IPv4 ? AF_INET : AF_INET6)); + + return true; +} + +void MappedAddress::dump(std::ostream& output) +{ + output << "MappedAddress " << mAddress.toStdString(); +} + + +//----------- XorMappedAddress --------------- +XorMappedAddress::XorMappedAddress() +{} + +XorMappedAddress::~XorMappedAddress() +{} + +int XorMappedAddress::type() const +{ + return StunAttribute::XorMappedAddress; +} + + +void XorMappedAddress::buildPacket(BufferWriter& writer) +{ + // Queue zero byte + writer.writeUChar(0); + + // Queue family + writer.writeUChar(mAddress.stunType()); + + // Xor&queue port + uint16_t port = mAddress.port() ^ 0x2112; + writer.writeUShort(port); + + // Xor&queue ip + unsigned int ip4 = 0; + uint32_t ip6[4]; + switch (mAddress.stunType()) + { + case IPv4: + ip4 = mAddress.sockaddr4()->sin_addr.s_addr; //this gets ip in network byte order + ip4 = ntohl(ip4); // get host byte order + ip4 ^= 0x2112A442; + writer.writeUInt(ip4); // It will convert again to network byte order + break; + + case IPv6: + // Get copy of address in network byte order + memcpy(&ip6, &mAddress.sockaddr6()->sin6_addr, 16); + + for (int i=0; i<3; i++) + ip6[i] ^= htonl(0x2112A442); + + writer.writeBuffer(ip6, 16); + break; + } + +} + +bool XorMappedAddress::parsePacket(BufferReader& reader) +{ + // Dequeue zero byte and ignore it + reader.readUChar(); + + // Dequeue family + mAddress.setStunType(reader.readUChar()); + + // Dequeue port + mAddress.setPort(reader.readUShort() ^ 0x2112); + + // Deqeueue IP + unsigned int ip4; + union + { + uint32_t ip6[4]; + in6_addr addr6; + } v6; + + switch (mAddress.stunType()) + { + case IPv4: + ip4 = htonl(reader.readUInt() ^ 0x2112A442); + mAddress.setIp(ip4); + break; + + case IPv6: + reader.readBuffer(v6.ip6, 16); + // XOR buffer + for (int i=0; i<3; i++) + v6.ip6[i] ^= htonl(0x2112A442); + mAddress.setIp(v6.addr6); + break; + + default: + assert(0); + } + + return true; +} + +void XorMappedAddress::dump(std::ostream &output) +{ + output << "XorMappedAddress " << mAddress.toStdString(); +} + +//------------ StringAttr ----------------------- +StringAttr::StringAttr() +{ +} +StringAttr::~StringAttr() +{ +} + +int StringAttr::type() const +{ + return StunAttribute::UnknownAttributes; +} + +std::string StringAttr::value() const +{ + return mValue; +} + +void StringAttr::setValue(const std::string& value) +{ + mValue = value; +} + +void StringAttr::buildPacket(BufferWriter& writer) +{ + if (!mValue.empty()) + writer.writeBuffer(mValue.c_str(), mValue.length()); +} + +bool StringAttr::parsePacket(BufferReader& reader) +{ + char temp[1024]; memset(temp, 0, sizeof temp); + reader.readBuffer(temp, sizeof temp); + mValue = temp; + + return true; +} + +void StringAttr::dump(std::ostream& output) +{ + output << "StringAttr " << mValue; +} + +//----------- Username --------------------------------- +Username::Username() +{} + +Username::~Username() +{} + +int Username::type() const +{ + return StunAttribute::Username; +} + +void Username::dump(std::ostream &output) +{ + output << "Username " << value(); +} + +//----------- MessageIntegrity ------------------------- +MessageIntegrity::MessageIntegrity() +{ + memset(mValue, 0, sizeof(mValue)); +} +MessageIntegrity::~MessageIntegrity() +{ +} + +int MessageIntegrity::type() const +{ + return StunAttribute::MessageIntegrity; +} + +void MessageIntegrity::setValue(const void* data) +{ + if (data) + memcpy(mValue, data, 20); +} + +const void* MessageIntegrity::value() const +{ + return mValue; +} + +void MessageIntegrity::buildPacket(BufferWriter& stream) +{ + stream.writeBuffer(mValue, 20); +} + +bool MessageIntegrity::parsePacket(BufferReader& stream) +{ + try + { + stream.readBuffer(mValue, 20); + } + catch(...) + { + return false; + } + + return true; +} + +void MessageIntegrity::dump(std::ostream &output) +{ + ByteBuffer buffer(mValue, 20); + output << "MessageIntegrity " << buffer.hexstring(); +} + +//--------------- Fingerprint ---------------- +Fingerprint::Fingerprint() +{ + mCRC32 = 0; +} + +Fingerprint::~Fingerprint() +{ +} + +int Fingerprint::type() const +{ + return StunAttribute::Fingerprint; +} + +void Fingerprint::setCrc32(unsigned int crc) +{ + mCRC32 = crc; +} + +unsigned int Fingerprint::crc32() const +{ + return mCRC32; +} + +void Fingerprint::buildPacket(BufferWriter& stream) +{ + stream.writeUInt(mCRC32); +} + +bool Fingerprint::parsePacket(BufferReader& stream) +{ + try + { + mCRC32 = stream.readUInt(); + } + catch(...) + { + return false; + } + + return true; +} + +void Fingerprint::dump(std::ostream &output) +{ + output << "Fingerprint " << mCRC32; +} + +//---------------- ErrorCode --------------- +ErrorCode::ErrorCode() +{ + mErrorCode = 0; +} + +ErrorCode::~ErrorCode() +{ +} + +int ErrorCode::type() const +{ + return StunAttribute::ErrorCode; +} + +void ErrorCode::setErrorCode(int errorCode) +{ + mErrorCode = errorCode; +} + +int ErrorCode::errorCode() const +{ + return mErrorCode; +} + +void ErrorCode::setErrorPhrase(const std::string& phrase) +{ + mErrorPhrase = phrase; +} + +std::string ErrorCode::errorPhrase() const +{ + return mErrorPhrase; +} + +void ErrorCode::buildPacket(BufferWriter& stream) +{ + stream.writeUShort(0); + + uint8_t b = 0; + // Get hundreds digit + int digit = mErrorCode / 100; + b = (digit & 4 ? 1 : 0) << 2; + b |= (digit & 2 ? 1 : 0) << 1; + b |= (digit & 1 ? 1 : 0); + stream.writeUChar(b); + + stream.writeUChar(mErrorCode % 100); + + if (!mErrorPhrase.empty()) + stream.writeBuffer(mErrorPhrase.c_str(), mErrorPhrase.length()); +} + +bool ErrorCode::parsePacket(BufferReader& stream) +{ + try + { + stream.readUShort(); + unsigned char _class = stream.readUChar(); + unsigned char _number = stream.readUChar(); + + mErrorCode = _class * 100 + _number; + char temp[1024]; memset(temp, 0, sizeof temp); + stream.readBuffer(temp, sizeof temp); + mErrorPhrase = std::string(temp); + } + catch(...) + { + return false; + } + + return true; +} + +void ErrorCode::dump(std::ostream &output) +{ + output << "ErrorCode " << mErrorCode << " " << mErrorPhrase; +} + +//----------------- Realm ------------------------ +Realm::Realm() +{} + +Realm::~Realm() +{} + +int Realm::type() const +{ + return StunAttribute::Realm; +} + +void Realm::dump(std::ostream &output) +{ + output << "Realm " << value(); +} + +//----------------- Nonce ------------------------ +Nonce::Nonce() +{} + +Nonce::~Nonce() +{} + +int Nonce::type() const +{ + return StunAttribute::Nonce; +} + +void Nonce::dump(std::ostream &output) +{ + output << "Nonce " << value(); +} + +//----------------- Server ----------------------- +Server::Server() +{} + +Server::~Server() +{} + +int Server::type() const +{ + return StunAttribute::Server; +} + +void Server::dump(std::ostream &output) +{ + output << "Server " << value(); +} + +//----------------- AlternateServer -------------- +AlternateServer::AlternateServer() +{} + +AlternateServer::~AlternateServer() +{} + +int AlternateServer::type() const +{ + return StunAttribute::AlternateServer; +} + +void AlternateServer::dump(std::ostream &output) +{ + output << "AlternateServer " << address().toStdString(); +} + +//----------------- UnknownAttributes ------------ +UnknownAttributes::UnknownAttributes() +{ +} + +UnknownAttributes::~UnknownAttributes() +{ +} + +int UnknownAttributes::type() const +{ + return StunAttribute::UnknownAttributes; +} + +void UnknownAttributes::buildPacket(BufferWriter& stream) +{ + char zeroBytes[8]; memset(zeroBytes, 0, sizeof(zeroBytes)); + stream.writeBuffer(zeroBytes, sizeof(zeroBytes)); +} + +bool UnknownAttributes::parsePacket(BufferReader& stream) +{ + try + { + char zeroBytes[8]; memset(zeroBytes, 0, sizeof(zeroBytes)); + stream.readBuffer(zeroBytes, sizeof(zeroBytes)); + } + catch(...) + { + return false; + } + + return true; +} + +void UnknownAttributes::dump(std::ostream &output) +{ + output << "UnknownAttributes"; +} + +//---------------- ChannelNumber ---------------- +ChannelNumber::ChannelNumber() +:mChannelNumber(0) +{ +} + +ChannelNumber::~ChannelNumber() +{ +} + +int ChannelNumber::type() const +{ + return StunAttribute::ChannelNumber; +} + +void ChannelNumber::setChannelNumber(unsigned short value) +{ + mChannelNumber = value; +} + +unsigned short ChannelNumber::channelNumber() const +{ + return mChannelNumber; +} + +void ChannelNumber::buildPacket(BufferWriter& stream) +{ + stream.writeUShort(mChannelNumber); + stream.writeUChar(0); + stream.writeUChar(0); +} + +bool ChannelNumber::parsePacket(BufferReader& stream) +{ + try + { + mChannelNumber = stream.readUShort(); + stream.readUChar(); + stream.readUChar(); + } + catch(...) + { + return false; + } + + return true; +} + +void ChannelNumber::dump(std::ostream &output) +{ + output << "ChannelNumber " << mChannelNumber; +} + +//--------------------------------- Lifetime ----------------------- +Lifetime::Lifetime() +:mLifetime(0) +{ +} + +Lifetime::~Lifetime() +{ +} + +int Lifetime::type() const +{ + return StunAttribute::Lifetime; +} + +void Lifetime::setLifetime(unsigned int value) +{ + mLifetime = value; +} + +unsigned int Lifetime::lifetime() const +{ + return mLifetime; +} + +void Lifetime::buildPacket(BufferWriter& stream) +{ + stream.writeUInt(mLifetime); +} + +bool Lifetime::parsePacket(BufferReader& stream) +{ + try + { + mLifetime = stream.readUInt(); + } + catch(...) + { + return false; + } + + return true; +} + +void Lifetime::dump(std::ostream &output) +{ + output << "Lifetime " << mLifetime; +} + +//----------------------- DataAttribute ---------------------- + +DataAttribute::DataAttribute() +{ +} + +DataAttribute::~DataAttribute() +{ +} + +int DataAttribute::type() const +{ + return StunAttribute::Data; +} + +void DataAttribute::setData(ByteBuffer& buffer) +{ + mData = buffer; +} + +ByteBuffer DataAttribute::data() const +{ + return mData; +} + +void DataAttribute::buildPacket(BufferWriter& stream) +{ + stream.writeBuffer(mData.data(), mData.size()); +} + +bool DataAttribute::parsePacket(BufferReader& stream) +{ + mData.resize(1024); + mData.resize(stream.readBuffer(mData.mutableData(), mData.size())); + return true; +} + +void DataAttribute::dump(std::ostream &output) +{ + output << "DataAttribute " << mData.hexstring(); +} + +//---------------------- XorRelayedTransport ------------------------- +XorRelayedAddress::XorRelayedAddress() +{} + +XorRelayedAddress::~XorRelayedAddress() +{} + +int XorRelayedAddress::type() const +{ + return StunAttribute::XorRelayedAddress; +} + +void XorRelayedAddress::dump(std::ostream &output) +{ + output << "XorRelayedAddress " << address().toStdString(); +} + +//---------------------- RequestedTransport --------------------------- +RequestedTransport::RequestedTransport() +:mRequestedTransport(UDP) +{ +} + +RequestedTransport::~RequestedTransport() +{ +} + +int RequestedTransport::type() const +{ + return StunAttribute::RequestedTransport; +} + +void RequestedTransport::setRequestedTransport(RequestedTransport::TransportType value) +{ + mRequestedTransport = value; +} + +unsigned char RequestedTransport::requestedTransport() const +{ + return mRequestedTransport; +} + +void RequestedTransport::buildPacket(BufferWriter& stream) +{ + stream.writeUChar(mRequestedTransport); + stream.writeUChar(0); + stream.writeUChar(0); + stream.writeUChar(0); +} + +bool RequestedTransport::parsePacket(BufferReader& stream) +{ + try + { + mRequestedTransport = stream.readUChar(); + stream.readUChar(); + stream.readUChar(); + stream.readUChar(); + } + catch(...) + { + return false; + } + + return true; +} + +void RequestedTransport::dump(std::ostream &output) +{ + output << "RequestedTransport " << mRequestedTransport; +} + +//--------------------------------- Controlled ----------------------- +ControlledAttr::ControlledAttr() +{ +} + +ControlledAttr::~ControlledAttr() +{ +} + +int ControlledAttr::type() const +{ + return StunAttribute::ControlledAttr; +} + +std::string ControlledAttr::tieBreaker() const +{ + return std::string((const char*)mTieBreaker, 8); +} + +void ControlledAttr::setTieBreaker(const std::string& tieBreaker) +{ + assert(tieBreaker.length() == 8); + + memcpy(mTieBreaker, tieBreaker.c_str(), 8); +} + +void ControlledAttr::buildPacket(BufferWriter& stream) +{ + stream.writeBuffer(mTieBreaker, 8); +} + +bool ControlledAttr::parsePacket(BufferReader& stream) +{ + try + { + stream.readBuffer(mTieBreaker, 8); + } + catch(...) + { + return false; + } + + return true; +} + +void ControlledAttr::dump(std::ostream &output) +{ + ByteBuffer b(mTieBreaker, 8); + output << "ControlledAttr " << b.hexstring(); +} + +//------------------- ControllingAttr -------------- +ControllingAttr::ControllingAttr() +{ + memset(mTieBreaker, 0, sizeof(mTieBreaker)); +} + +ControllingAttr::~ControllingAttr() +{ +} + +int ControllingAttr::type() const +{ + return StunAttribute::ControllingAttr; +} + +std::string ControllingAttr::tieBreaker() const +{ + return std::string((const char*)mTieBreaker, 8); +} + +void ControllingAttr::setTieBreaker(const std::string& tieBreaker) +{ + memcpy(mTieBreaker, tieBreaker.c_str(), 8); +} + +void ControllingAttr::buildPacket(BufferWriter& stream) +{ + stream.writeBuffer(mTieBreaker, 8); +} + +bool ControllingAttr::parsePacket(BufferReader& stream) +{ + try + { + stream.readBuffer(mTieBreaker, 8); + } + catch(...) + { + return false; + } + + return true; +} + +void ControllingAttr::dump(std::ostream &output) +{ + ByteBuffer b(mTieBreaker, 8); + output << "ControllingAttr " << b.hexstring(); +} + +//----------- ICEPriority --------------- +ICEPriority::ICEPriority() +{ + mPriority = 0; +} + +ICEPriority::~ICEPriority() +{ +} + +int ICEPriority::type() const +{ + return StunAttribute::ICEPriority; +} + +unsigned int ICEPriority::priority() const +{ + return mPriority; +} + +void ICEPriority::setPriority(unsigned int priority) +{ + mPriority = priority; +} + +void ICEPriority::buildPacket(BufferWriter& stream) +{ + stream.writeUInt(mPriority); +} + +bool ICEPriority::parsePacket(BufferReader& stream) +{ + try + { + mPriority = stream.readUInt(); + } + catch(...) + { + return false; + } + + return true; +} + +void ICEPriority::dump(std::ostream &output) +{ + output << "ICEPriority " << mPriority; +} + +//------------------ USE-CANDIDATE ----------------------- +ICEUseCandidate::ICEUseCandidate() +{ +} + +ICEUseCandidate::~ICEUseCandidate() +{ +} + +int ICEUseCandidate::type() const +{ + return StunAttribute::ICEUseCandidate; +} + +void ICEUseCandidate::buildPacket(BufferWriter& /*buffer*/) +{ +} + +bool ICEUseCandidate::parsePacket(BufferReader& /*buffer*/) +{ + return true; +} + +void ICEUseCandidate::dump(std::ostream &output) +{ + output << "ICEUseCandidate"; +} +// ------------- REQUESTED-ADDRESS-FAMILY ------------- +RequestedAddressFamily::RequestedAddressFamily() +:mAddressFamily(IPv4) +{} + +RequestedAddressFamily::RequestedAddressFamily(AddressFamily family) + :mAddressFamily(family) +{} + +RequestedAddressFamily::~RequestedAddressFamily() +{} + +int RequestedAddressFamily::type() const +{ + return StunAttribute::RequestedAddressFamily; +} + +AddressFamily RequestedAddressFamily::family() const +{ + return mAddressFamily; +} + +void RequestedAddressFamily::buildPacket(BufferWriter& stream) +{ + stream.writeUChar(mAddressFamily); + stream.writeUChar(0); stream.writeUChar(0); stream.writeUChar(0); +} + +bool RequestedAddressFamily::parsePacket(BufferReader& stream) +{ + try + { + mAddressFamily = (AddressFamily)stream.readUChar(); + } + catch(...) + { + return false; + } + return true; +} + +void RequestedAddressFamily::dump(std::ostream &output) +{ + output << "RequestedAddressFamily " << (mAddressFamily == IPv4 ? "IPv4" : "IPv6"); +} diff --git a/src/libs/ice/ICEStunAttributes.h b/src/libs/ice/ICEStunAttributes.h new file mode 100644 index 00000000..e363ae2b --- /dev/null +++ b/src/libs/ice/ICEStunAttributes.h @@ -0,0 +1,363 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_STUN_ATTRIBUTES_H +#define __ICE_STUN_ATTRIBUTES_H + +#include "ICEStunMessage.h" +#include + +namespace ice +{ + class MappedAddress: public StunAttribute + { + public: + MappedAddress(); + virtual ~MappedAddress(); + + virtual int type() const override; + NetworkAddress& address(); + virtual void buildPacket(BufferWriter& buffer) override; + virtual bool parsePacket(BufferReader& buffer) override; + virtual void dump(std::ostream& output) override; + + protected: + NetworkAddress mAddress; + }; + + class XorMappedAddress: public MappedAddress + { + public: + XorMappedAddress(); + virtual ~XorMappedAddress(); + virtual int type() const override; + + virtual void buildPacket(BufferWriter& writer) override; + virtual bool parsePacket(BufferReader& reader) override; + virtual void dump(std::ostream& output) override; + }; + + class StringAttr: public StunAttribute + { + public: + StringAttr(); + virtual ~StringAttr(); + + virtual int type() const override; + std::string value() const; + void setValue(const std::string& value); + + virtual void buildPacket(BufferWriter& writer) override; + virtual bool parsePacket(BufferReader& reader) override; + virtual void dump(std::ostream& output) override; + + protected: + std::string mValue; + }; + + class Username: public StringAttr + { + public: + Username(); + ~Username(); + int type() const; + void dump(std::ostream& output); + }; + + class MessageIntegrity: public StunAttribute + { + public: + MessageIntegrity(); + ~MessageIntegrity(); + + int type() const override; + void setValue(const void* data); + const void* value() const; + + void buildPacket(BufferWriter& stream) override; + bool parsePacket(BufferReader& stream) override; + void dump(std::ostream& output) override; + + protected: + unsigned char mValue[20]; + }; + + class Fingerprint: public StunAttribute + { + public: + Fingerprint(); + ~Fingerprint(); + + int type() const override; + void setCrc32(unsigned int crc); + unsigned int crc32() const; + + void buildPacket(BufferWriter& stream) override; + bool parsePacket(BufferReader& stream) override; + void dump(std::ostream& output) override; + + protected: + unsigned int mCRC32; + }; + + class ErrorCode: public StunAttribute + { + public: + ErrorCode(); + ~ErrorCode(); + + virtual int type() const override; + void setErrorCode(int errorCode); + int errorCode() const; + + void setErrorPhrase(const std::string& phrase); + std::string errorPhrase() const; + + void buildPacket(BufferWriter& stream) override; + bool parsePacket(BufferReader& stream) override; + void dump(std::ostream& output) override; + + protected: + int mErrorCode; + std::string mErrorPhrase; + }; + + class Realm: public StringAttr + { + public: + Realm(); + ~Realm(); + int type() const override; + void dump(std::ostream& output) override; + }; + + class Nonce: public StringAttr + { + public: + Nonce(); + ~Nonce(); + + int type() const override; + void dump(std::ostream& output) override; + }; + + class UnknownAttributes: public StunAttribute + { + public: + UnknownAttributes(); + ~UnknownAttributes(); + + int type() const override; + void buildPacket(BufferWriter& stream) override; + bool parsePacket(BufferReader& stream) override; + void dump(std::ostream& output) override; + }; + + class Server: public StringAttr + { + public: + Server(); + ~Server(); + int type() const override; + void dump(std::ostream& output) override; + }; + + class AlternateServer: public MappedAddress + { + public: + AlternateServer(); + ~AlternateServer(); + int type() const override; + void dump(std::ostream& output) override; + }; + + + class ChannelNumber: public StunAttribute + { + public: + ChannelNumber(); + ~ChannelNumber(); + + int type() const override; + void setChannelNumber(unsigned short value); + unsigned short channelNumber() const; + + void buildPacket(BufferWriter& stream) override; + bool parsePacket(BufferReader& stream) override; + void dump(std::ostream& output) override; + protected: + unsigned short mChannelNumber; + }; + + class Lifetime: public StunAttribute + { + public: + Lifetime(); + ~Lifetime(); + + int type() const override; + void setLifetime(unsigned int value); + unsigned int lifetime() const; + + void buildPacket(BufferWriter& writer) override; + bool parsePacket(BufferReader& reader) override; + void dump(std::ostream& output) override; + protected: + unsigned int mLifetime; + }; + + class XorPeerAddress: public XorMappedAddress + { + public: + int type() const override + { + return StunAttribute::XorPeerAddress; + } + }; + + class DataAttribute: public StunAttribute + { + public: + DataAttribute(); + virtual ~DataAttribute(); + + int type() const override; + void setData(ByteBuffer& buffer); + ByteBuffer data() const; + + void buildPacket(BufferWriter& stream) override; + bool parsePacket(BufferReader& stream) override; + void dump(std::ostream &output) override; + + protected: + ByteBuffer mData; + }; + + class XorRelayedAddress: public XorMappedAddress + { + public: + XorRelayedAddress(); + ~XorRelayedAddress(); + int type() const override; + void dump(std::ostream& output) override; + }; + + class RequestedTransport: public StunAttribute + { + public: + RequestedTransport(); + virtual ~RequestedTransport(); + + enum TransportType + { + UDP = 17 + }; + + int type() const override; + void setRequestedTransport(TransportType value); + unsigned char requestedTransport() const; + + void buildPacket(BufferWriter& stream) override; + bool parsePacket(BufferReader& stream) override; + void dump(std::ostream& output) override; + protected: + unsigned char mRequestedTransport; //always 17! + }; + + class ReservedToken: public StunAttribute + { + public: + ReservedToken(); + ~ReservedToken(); + + int type() const override; + void setToken(const std::string& token); + std::string token() const; + + void buildPacket(BufferWriter& buffer) override; + bool parsePacket(BufferReader& buffer) override; + void dump(std::ostream& output) override; + protected: + std::string mToken; + }; + + class ControlledAttr: public StunAttribute + { + public: + ControlledAttr(); + ~ControlledAttr(); + + int type() const override; + + std::string tieBreaker() const; + void setTieBreaker(const std::string& tieBreaker); + void buildPacket(BufferWriter& stream) override; + bool parsePacket(BufferReader& stream) override; + void dump(std::ostream& output) override; + protected: + unsigned char mTieBreaker[8]; + }; + + class ControllingAttr: public StunAttribute + { + public: + ControllingAttr(); + ~ControllingAttr(); + + int type() const override; + std::string tieBreaker() const; + void setTieBreaker(const std::string& tieBreaker); + + void buildPacket(BufferWriter& stream) override; + bool parsePacket(BufferReader& stream) override; + void dump(std::ostream& output) override; + protected: + unsigned char mTieBreaker[8]; + }; + + class ICEPriority: public StunAttribute + { + public: + ICEPriority(); + ~ICEPriority(); + + int type() const override; + unsigned int priority() const; + void setPriority(unsigned int priority); + void buildPacket(BufferWriter& stream) override; + bool parsePacket(BufferReader& stream) override; + void dump(std::ostream& output) override; + protected: + unsigned int mPriority; + }; + + class ICEUseCandidate: public StunAttribute + { + public: + ICEUseCandidate(); + virtual ~ICEUseCandidate(); + int type() const override; + void buildPacket(BufferWriter& stream) override; + bool parsePacket(BufferReader& stream) override; + void dump(std::ostream& output) override; + }; + + class RequestedAddressFamily: public StunAttribute + { + public: + RequestedAddressFamily(); + RequestedAddressFamily(AddressFamily family); + ~RequestedAddressFamily(); + + int type() const override; + AddressFamily family() const; + void buildPacket(BufferWriter& stream) override; + bool parsePacket(BufferReader& stream) override; + void dump(std::ostream& output) override; + protected: + AddressFamily mAddressFamily; + }; +} +#endif diff --git a/src/libs/ice/ICEStunConfig.cpp b/src/libs/ice/ICEStunConfig.cpp new file mode 100644 index 00000000..29190e14 --- /dev/null +++ b/src/libs/ice/ICEStunConfig.cpp @@ -0,0 +1,50 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEStunConfig.h" + +using namespace ice; + +std::string StackConfig::mDefaultIpTarget = ICE_FALLBACK_IP_ADDR; + +StackConfig::StackConfig() +:mUseTURN(false), mTimeout(DEFAULT_STUN_FINISH_TIMEOUT), mPeriod(DEFAULT_STUN_RETRANSMIT_TIMEOUT), +mUseSTUN(true), mUseIPv4(true), mUseIPv6(true) +{ +#ifdef ICE_AGGRESSIVE + mAggressiveNomination = true; + mTreatRequestAsConfirmation = false; +#endif + +#ifdef ICE_VERYAGGRESSIVE + mAggressiveNomination = true; + mTreatRequestAsConfirmation = true; +#else + mAggressiveNomination = false; + mTreatRequestAsConfirmation = false; +#endif + mInitialRTO = 100; + mKeepAliveInterval = 5000; + mServerAddr4.setPort( 3478 ); + mServerAddr6.setPort( 3478 ); + mTurnLifetime = 300; + mUseProtocolRelay = true;// false; + +#ifdef TEST_RELAYING + mTypePreferenceList[Candidate::Host] = 0; + mTypePreferenceList[Candidate::ServerReflexive] = 110; + mTypePreferenceList[Candidate::PeerReflexive] = 100; + mTypePreferenceList[Candidate::ServerRelayed] = 126; +#else + mTypePreferenceList[Candidate::Host] = 126; + mTypePreferenceList[Candidate::ServerReflexive] = 100; + mTypePreferenceList[Candidate::PeerReflexive] = 110; + mTypePreferenceList[Candidate::ServerRelayed] = 0; +#endif + mTargetIP = mDefaultIpTarget; +} + +StackConfig::~StackConfig() +{} diff --git a/src/libs/ice/ICEStunConfig.h b/src/libs/ice/ICEStunConfig.h new file mode 100644 index 00000000..a5873328 --- /dev/null +++ b/src/libs/ice/ICEStunConfig.h @@ -0,0 +1,86 @@ +/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_STUN_CONFIG_H +#define __ICE_STUN_CONFIG_H + + +#include "ICEPlatform.h" +#include "ICECandidate.h" + +#include +#include + +namespace ice { + +#define DEFAULT_STUN_RETRANSMIT_TIMEOUT 790000 +#define DEFAULT_STUN_FINISH_TIMEOUT 790000 +#define ICE_FALLBACK_IP_ADDR "8.8.8.8" +// #define TEST_RELAYING + + struct StackConfig + { + // The IP of STUN server + std::vector mServerList4, + mServerList6; + NetworkAddress mServerAddr4, + mServerAddr6; + + // Use IPv4 when gathering candidates + bool mUseIPv4; + + // Use IPv6 when gathering candidates + bool mUseIPv6; + + // Should we use relying (TURN)? + bool mUseTURN; + + // Should we use IPv4 <--> IPv6 bypassing via relaying ? + bool mUseProtocolRelay; + + // The timeout for STUN transaction + unsigned int mTimeout; + + // The RTO + unsigned int mPeriod; + + // Marks if STUN use is disalbed + bool mUseSTUN; + + // Sets the possible peer IP for ICE session + std::string mTargetIP; + + // The type preference list for ICE session + int mTypePreferenceList[4]; + + // The initial RTO value + int mInitialRTO; + + // Interval for keepalive checks + int mKeepAliveInterval; + + std::string mTurnUsername, + mTurnPassword; + + // TURN lifetime + int mTurnLifetime; + + // Enable/disable aggressive nomination + bool mAggressiveNomination; + + // Treats requests as confirmation for connectivity checks sent in reverse direction if the corresponding pair already exists + // It violates RFC. It can be needed in poor networks. + bool mTreatRequestAsConfirmation; + + // Default IP target if mTargetIP is not set + static std::string mDefaultIpTarget; + + StackConfig(); + ~StackConfig(); + }; + +}; + +#endif diff --git a/src/libs/ice/ICEStunMessage.cpp b/src/libs/ice/ICEStunMessage.cpp new file mode 100644 index 00000000..45ffe715 --- /dev/null +++ b/src/libs/ice/ICEStunMessage.cpp @@ -0,0 +1,852 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEPlatform.h" +#include "ICEStunMessage.h" +#include "ICECRC32.h" +#include "ICESHA1.h" +#include "ICEStunAttributes.h" +#include "ICEError.h" +#include "ICELog.h" + +#include +#include +#include + +#ifndef _WIN32 +# include +# include +# include +#endif + +#define STUN_HEADER_SIZE 20 +#define HMAC_DIGEST_SIZE 20 +#define LOG_SUBSYSTEM "ICE" + +using namespace ice; + +bool StunMessage::TransactionID::operator == (const StunMessage::TransactionID& rhs) +{ + return memcmp(mValue, rhs.mValue, 12) == 0; +} + +bool StunMessage::TransactionID::operator != (const TransactionID& rhs) +{ + return memcmp(mValue, rhs.mValue, 12) != 0; +} + +StunMessage::TransactionID::TransactionID() +{ + for (int i=0; i<12; i++) + mValue[i] = rand() & 0xFF; + + //memset(mValue, 0, 12); +} + +std::string StunMessage::TransactionID::toStdString() +{ + char hex[3]; + std::string result; + for (size_t i=0; i<12; i++) + { + sprintf(hex, "%2x", mValue[i]); + result += hex; + } + + return result; +} + +StunMessage::TransactionID StunMessage::TransactionID::generateNew() +{ + TransactionID result; + for (size_t i=0; i<12; i++) + result.mValue[i] = (unsigned char)rand(); + + return result; +} + +//--------------------------- StunAttribute ---------------------- +StunAttribute::StunAttribute() +{ + mLength = 0; + mType = 0; + mDataOffset = 0; +} + +StunAttribute::~StunAttribute() +{ +} + +void StunAttribute::setDataOffset(size_t offset) +{ + mDataOffset = offset; +} + +size_t StunAttribute::dataOffset() const +{ + return mDataOffset; +} + +//---------------------------- StunMessage ----------------------- +StunMessage::StunMessage() +:mMagicCookie(0x2112A442) +{ + +} + +StunMessage::~StunMessage() +{ + // Iterate map to delete all attributes + for (AttributeMap::iterator ait=mAttrMap.begin(); ait != mAttrMap.end(); ++ait) + delete ait->second; +} + +std::string StunMessage::comment() +{ + return mComment; +} + +void StunMessage::setComment(std::string comment) +{ + mComment = comment; +} + + +void StunMessage::setMessageType(Type type) +{ + mType = type; +} + + +StunMessage::Type StunMessage::messageType() +{ + return mType; +} + +void StunMessage::setMessageClass(Class value) +{ + mClass = value; +} + +StunMessage::Class StunMessage::messageClass() +{ + return mClass; +} + +unsigned int StunMessage::magicCookie() +{ + return mMagicCookie; +} + +bool StunMessage::isMagicCookieValid() +{ + return mMagicCookie == 0x2112A442; +} + +void StunMessage::setTransactionId(TransactionID id) +{ + mTransactionID = id; +} + +StunMessage::TransactionID StunMessage::transactionId() +{ + return mTransactionID; +} + +static void EmbedAttrBuffer(StunAttribute& attr, BufferWriter& writer) +{ + ByteBuffer attrBuffer; attrBuffer.resize(512); + BufferWriter attrWriter(attrBuffer); + attr.buildPacket(attrWriter); + attrBuffer.resize(attrWriter.offset()); + + // Enqueue attribute type + writer.writeUShort(attr.type()); + + // Enqueue length + writer.writeUShort(attrBuffer.size()); + + // Save data offset in generated buffer + attr.setDataOffset(writer.offset() + 2); // 2 is for first 16 bits written by bitstream + + // Enqueue attribute's value + if (attrBuffer.size() > 0) + writer.writeBuffer(attrBuffer.data(), attrBuffer.size()); + + if (attrBuffer.size() & 0x3) + { + size_t paddingLength = 4 - (attrBuffer.size() & 0x3); + char paddingBytes[4] = { 0, 0, 0, 0 }; + writer.writeBuffer(paddingBytes, paddingLength); + } +} + +void StunMessage::buildPacket(ByteBuffer& buffer, const std::string& password) +{ + // Make enough space for packet + buffer.resize(1024); + + // Write bits + BitWriter bitstream(buffer); + + bitstream.writeBit(0) + .writeBit(0); + + unsigned int msgtype = mType & 0xFFF; + unsigned int msgclass = mClass & 0x3; + + // Enqueue last 5 bits of mtype + for (size_t i=0; i<5; i++) + bitstream.writeBit(bit(msgtype, 11 - i)); + + // Enqueue last bit of msgclass + bitstream.writeBit(bit(msgclass, 1)); + + // Enqueue 3 bits of msgtype + for (size_t i=0; i<3; i++) + bitstream.writeBit(bit(msgtype, 6 - i)); + + // Enqueue first bit of msgclass + bitstream.writeBit(bit(msgclass, 0)); + + // Enqueue 4 bits of msgtype + for (size_t i=0; i<4; i++) + bitstream.writeBit(bit(msgtype, 3-i)); + + // Enqueue 2 bytes of length - now it is zero + BufferWriter stream(buffer.mutableData() + bitstream.count() / 8); + stream.writeUShort(0); + + // Enqueue magic cookie value + unsigned int cookie = htonl(mMagicCookie); + stream.writeBuffer(&cookie, 4); + + // Enqueue transaction ID + //memset(mTransactionID.mValue, 0, sizeof(mTransactionID.mValue)); // For debugging only + stream.writeBuffer(mTransactionID.mValue, 12); + + // Iterate attributes + AttributeMap::iterator attrIter; + for (attrIter = mAttrMap.begin(); attrIter != mAttrMap.end(); ++attrIter) + { + StunAttribute& attr = *attrIter->second; + + // Check if it is MessageIntegrity or Fingerprint - they comes last and skip them for now + if (attr.type() == StunAttribute::MessageIntegrity || attr.type() == StunAttribute::Fingerprint) + continue; + + EmbedAttrBuffer(attr, stream); + } + + // Append MessageIntegrity attribute if exists + AttributeMap::iterator miIter = mAttrMap.find(StunAttribute::MessageIntegrity); + if ( miIter != mAttrMap.end()) + { + EmbedAttrBuffer(*miIter->second, stream); + } + + int lengthWithoutFingerprint = stream.offset() + 2; + + // Append Fingerprint attribute if exists + AttributeMap::iterator fpIter = mAttrMap.find(StunAttribute::Fingerprint); + if (fpIter != mAttrMap.end()) + { + EmbedAttrBuffer(*fpIter->second, stream); + } + + // Check for message integrity attribute + miIter = mAttrMap.find(StunAttribute::MessageIntegrity); + if (miIter != mAttrMap.end()) + { + // Update length in header + *((unsigned short*)buffer.mutableData() + 1) = htons(lengthWithoutFingerprint - STUN_HEADER_SIZE); + + // Prepare HMAC digest buffer + unsigned char digest[HMAC_DIGEST_SIZE]; + + // Get data offset for output digest + size_t dataOffset = miIter->second->dataOffset(); + + // Get digest + hmacSha1Digest(buffer.data(), dataOffset - 4, digest, password.c_str(), password.length()); + + // Copy digest to proper place + memcpy((unsigned char*)buffer.data() + dataOffset, digest, HMAC_DIGEST_SIZE); + } + + // Resize resulting buffer + buffer.resize(stream.offset() + 2); + + // Put length in header + *((unsigned short*)buffer.mutableData() + 1) = htons(buffer.size() - STUN_HEADER_SIZE); + + // Check for fingerprint attribute + fpIter = mAttrMap.find(StunAttribute::Fingerprint); + if (fpIter != mAttrMap.end()) + { + // Get data offset for fingeprint attribute + size_t dataOffset = fpIter->second->dataOffset(); + + // Find CRC32 + CRC32 crc32; + unsigned int crc = crc32.fullCrc((unsigned char*)buffer.data(), dataOffset - 4); + + // Update attribute value with CRC32 value + memcpy((unsigned char*)buffer.data() + dataOffset, &crc, 4); + } + +} + +#include "ICEStunAttributes.h" + +bool StunMessage::parsePacket(ByteBuffer& buffer) +{ + // Save incoming packet + mPacket2Parse = buffer; + + // Clear attribute list + mAttrMap.clear(); + + BufferReader stream(buffer); + + uint8_t firstByte = stream.readUChar(); + uint8_t secondByte = stream.readUChar(); + + if (firstByte & ~0x3F) + { + return false; + } + + int c1 = firstByte & 0x1; + int m11 = firstByte & 0x20 ? 1 : 0; + int m10 = firstByte & 0x10 ? 1 : 0; + int m9 = firstByte & 0x8 ? 1 : 0; + int m8 = firstByte & 0x4 ? 1 : 0; + int m7 = firstByte & 0x2 ? 1 : 0; + + int m6 = secondByte & 0x80 ? 1 : 0; + int m5 = secondByte & 0x40 ? 1 : 0; + int m4 = secondByte & 0x20 ? 1 : 0; + int c0 = secondByte & 0x10 ? 1 : 0; + int m3 = secondByte & 0x8 ? 1 : 0; + int m2 = secondByte & 0x4 ? 1 : 0; + int m1 = secondByte & 0x2 ? 1 : 0; + int m0 = secondByte & 0x1 ? 1 : 0; + + mType = (StunMessage::Type)((m11 << 11) + (m10 << 10) + (m9 << 9) + (m8 << 8) + (m7 << 7) + (m6 << 6) + (m5 << 5) + (m4 << 4) + (m3 << 3) + (m2 << 2) + (m1 << 1) + m0); + mClass = (StunMessage::Class) ((c1 << 1) + c0); + + unsigned short length = stream.readUShort(); + if (length & 0x3) + { + return false; + } + + // Dequeue magic cookie + mMagicCookie = stream.readUInt(); + if (!isMagicCookieValid()) + return false; + + // Dequeue transaction id + char id[12]; + stream.readBuffer(id, 12); + + memcpy(mTransactionID.mValue, id, 12); + + // Dequeue attributes + while (stream.count() < buffer.size()) + { + int attrType = stream.readUShort(); + StunAttribute* attr = NULL; + switch (attrType) + { + case StunAttribute::Data: + attr = new DataAttribute(); + break; + + case StunAttribute::MappedAddress: + attr = new MappedAddress(); + break; + + case StunAttribute::XorMappedAddress: + attr = new XorMappedAddress(); + break; + + case StunAttribute::ErrorCode: + attr = new ErrorCode(); + break; + + case StunAttribute::AlternateServer: + attr = new AlternateServer(); + break; + + case StunAttribute::UnknownAttributes: + attr = new UnknownAttributes(); + break; + + case StunAttribute::Fingerprint: + attr = new Fingerprint(); + break; + + case StunAttribute::MessageIntegrity: + attr = new MessageIntegrity(); + break; + + case StunAttribute::Nonce: + attr = new Nonce(); + break; + + case StunAttribute::Realm: + attr = new Realm(); + break; + + case StunAttribute::Server: + attr = new Server(); + break; + + case StunAttribute::Username: + attr = new Username(); + break; + + case StunAttribute::ICEPriority: + attr = new ICEPriority(); + break; + + case StunAttribute::ControlledAttr: + attr = new ControlledAttr(); + break; + + case StunAttribute::ControllingAttr: + attr = new ControllingAttr(); + break; + + case StunAttribute::ICEUseCandidate: + attr = new ICEUseCandidate(); + break; + + case StunAttribute::XorRelayedAddress: + attr = new XorRelayedAddress(); + break; + + case StunAttribute::XorPeerAddress: + attr = new XorPeerAddress(); + break; + + case StunAttribute::Lifetime: + attr = new Lifetime(); + break; + + case StunAttribute::RequestedTransport: + attr = new RequestedTransport(); + break; + + case StunAttribute::RequestedAddressFamily: + attr = new RequestedAddressFamily(); + break; + + default: + attr = NULL; + } + + // Get attribute value length + int attrLen = stream.readUShort(); + + unsigned int dataOffset = stream.count(); + + // Get attribute buffer + ByteBuffer attrBuffer; + if (attrLen > 0) + { + attrBuffer.resize(attrLen); + stream.readBuffer(attrBuffer.mutableData(), attrLen); + } + + // Skip padding bytes + if (attrLen & 0x3) + { + size_t paddingLength = 4 - (attrLen & 0x3); + char paddingBytes[4]; + stream.readBuffer(paddingBytes, paddingLength); + } + + // Parse attribute value + if (attr) + { + // Parse attribute + BufferReader attrReader(attrBuffer); + if (!attr->parsePacket(attrReader)) + return false; + + // Set data offset + attr->setDataOffset(dataOffset); + + // Add attribute + addAttribute(attr); + } + } + return true; +} + +bool StunMessage::validatePacket(std::string key) +{ + // Iterate attributes + if (hasAttribute(StunAttribute::MessageIntegrity)) + { + // Get HMAC digest + MessageIntegrity& mi = dynamic_cast(attribute(StunAttribute::MessageIntegrity)); + + unsigned char digest[HMAC_DIGEST_SIZE]; + + // Reset length to length of packet without Fingerprint + unsigned short* lengthPtr = ((unsigned short*)mPacket2Parse.mutableData() + 1); + + // Save old value - it is for backup purposes only. So there is no call to ntohs(). + unsigned short len = *lengthPtr; + + // Set fake length including MessageIntegrity attribute but excluding any attributes behind of it and excluding STUN header size + *lengthPtr = htons(mi.dataOffset() + HMAC_DIGEST_SIZE - STUN_HEADER_SIZE); + + // Find HMAC-SHA1 again + hmacSha1Digest(mPacket2Parse.data(), mi.dataOffset() - 4, digest, key.c_str(), key.size()); + + // And restore old value + *lengthPtr = len; + + if (memcmp(mi.value(), digest, HMAC_DIGEST_SIZE) != 0) + { + ICELogCritical(<< "Bad MessageIntegrity in STUN message"); + return false; + } + } + + /* + if (hasAttribute(StunAttribute::Fingerprint)) + { + // Get fingerpring attribute + Fingerprint& fp = dynamic_cast(attribute(StunAttribute::Fingerprint)); + + // Find CRC32 + CRC32 crcObj; + unsigned long crcValue = crcObj.fullCrc((const unsigned char*)mPacket2Parse.data(), fp.dataOffset() - 4); + + // Compare with saved one + if (crcValue != fp.crc32()) + { + ICELogCritical(<< "Bad CRC32 value in STUN message"); + return false; + } + }*/ + + return true; +} + +inline char StunMessage::bit(unsigned int value, size_t index) +{ + unsigned int mask = (1 << index); + + return value & mask ? 1 : 0; +} + +inline void StunMessage::setBit(unsigned int& result, size_t index, char value) +{ + unsigned int mask = (1 << index); + if (value != 0) + result |= mask; + else + result &= ~mask; +} + +void StunMessage::addAttribute(StunAttribute* attr) +{ + assert(NULL != attr); + mAttrMap.insert(std::pair(attr->type(), attr)); +} + +void StunMessage::setAttribute(StunAttribute *attr) +{ + assert(NULL != attr); + + AttributeMap::iterator attrIter = mAttrMap.find(attr->type()); + if (attrIter != mAttrMap.end()) + { + delete attrIter->second; + attrIter->second = attr; + } + else + mAttrMap.insert(std::pair(attr->type(), attr)); +} + +bool StunMessage::hasAttribute(int attrType) const +{ + return (mAttrMap.find(attrType) != mAttrMap.end()); +} + + +StunAttribute& StunMessage::attribute(int attrType) +{ + AttributeMap::iterator attrIter = mAttrMap.find(attrType); + if (attrIter != mAttrMap.end()) + return *attrIter->second; + + throw Exception(CANNOT_FIND_ATTRIBUTE, attrType); +} + +const StunAttribute& +StunMessage::operator [] (int attribute) const +{ + AttributeMap::iterator attrIter = mAttrMap.find(attribute); + if (attrIter != mAttrMap.end()) + return *attrIter->second; + + throw Exception(CANNOT_FIND_ATTRIBUTE, attribute); +} + +StunAttribute& +StunMessage::operator[] (int attribute) +{ + AttributeMap::iterator attrIter = mAttrMap.find(attribute); + if (attrIter != mAttrMap.end()) + return *attrIter->second; + + // Create attribute + StunAttribute* attr = NULL; + + switch (attribute) + { + case StunAttribute::MappedAddress: + attr = new MappedAddress(); + break; + + case StunAttribute::XorMappedAddress: + attr = new XorMappedAddress(); + break; + + case StunAttribute::ErrorCode: + attr = new ErrorCode(); + break; + + case StunAttribute::AlternateServer: + attr = new AlternateServer(); + break; + + case StunAttribute::UnknownAttributes: + attr = new UnknownAttributes(); + break; + + case StunAttribute::Fingerprint: + attr = new Fingerprint(); + break; + + case StunAttribute::MessageIntegrity: + attr = new MessageIntegrity(); + break; + + case StunAttribute::Nonce: + attr = new Nonce(); + break; + + case StunAttribute::Realm: + attr = new Realm(); + break; + + case StunAttribute::Server: + attr = new Server(); + break; + + case StunAttribute::Username: + attr = new Username(); + break; + + case StunAttribute::ICEPriority: + attr = new ICEPriority(); + break; + + case StunAttribute::ControlledAttr: + attr = new ControlledAttr(); + break; + + case StunAttribute::ControllingAttr: + attr = new ControllingAttr(); + break; + + case StunAttribute::ICEUseCandidate: + attr = new ICEUseCandidate(); + break; + + case StunAttribute::XorRelayedAddress: + attr = new XorRelayedAddress(); + break; + + case StunAttribute::Lifetime: + attr = new Lifetime(); + break; + + default: + attr = NULL; + } + + if (!attr) + throw Exception(UNKNOWN_ATTRIBUTE, attribute); + + mAttrMap.insert(std::pair(attribute, attr)); + return *attr; +} + +Username& +StunMessage::usernameAttr() +{ + StunMessage& self = *this; + return dynamic_cast(self[StunAttribute::Username]); +} + +Realm& +StunMessage::realmAttr() +{ + StunMessage& self = *this; + return dynamic_cast(self[StunAttribute::Realm]); +} + +ErrorCode& +StunMessage::errorCodeAttr() +{ + StunMessage& self = *this; + return dynamic_cast(self[StunAttribute::ErrorCode]); +} + +Nonce& +StunMessage::nonceAttr() +{ + StunMessage& self = *this; + return dynamic_cast(self[StunAttribute::Nonce]); +} + +MessageIntegrity& +StunMessage::messageIntegrityAttr() +{ + StunMessage& self = *this; + return dynamic_cast(self[StunAttribute::MessageIntegrity]); +} + +MappedAddress& +StunMessage::mappedAddressAttr() +{ + StunMessage& self = *this; + return dynamic_cast(self[StunAttribute::MappedAddress]); +} + +XorMappedAddress& +StunMessage::xorMappedAddressAttr() +{ + StunMessage& self = *this; + return dynamic_cast(self[StunAttribute::XorMappedAddress]); +} + +ControlledAttr& +StunMessage::iceControlledAttr() +{ + StunMessage& self = *this; + return dynamic_cast(self[StunAttribute::ControlledAttr]); +} + +ControllingAttr& +StunMessage::iceControllingAttr() +{ + StunMessage& self = *this; + return dynamic_cast(self[StunAttribute::ControllingAttr]); +} + +ICEPriority& +StunMessage::icePriorityAttr() +{ + StunMessage& self = *this; + return dynamic_cast(self[StunAttribute::ICEPriority]); +} + +Lifetime& +StunMessage::lifetimeAttr() +{ + StunMessage& self = *this; + return dynamic_cast(self[StunAttribute::Lifetime]); +} + +XorRelayedAddress& +StunMessage::xorRelayedAddressAttr() +{ + StunMessage& self = *this; + return dynamic_cast(self[StunAttribute::XorRelayedAddress]); +} + +ChannelNumber& +StunMessage::channelNumberAttr() +{ + StunMessage& self = *this; + if (!self.hasAttribute(StunAttribute::ChannelNumber)) + self.addAttribute(new ChannelNumber()); + + return dynamic_cast(self[StunAttribute::ChannelNumber]); +} + +XorPeerAddress& +StunMessage::xorPeerAddressAttr() +{ + StunMessage& self = *this; + if (!self.hasAttribute(StunAttribute::XorPeerAddress)) + self.addAttribute(new XorPeerAddress()); + return dynamic_cast(self[StunAttribute::XorPeerAddress]); +} + +class CompareAttributesByOffsetFunctor +{ +public: + bool operator () (const StunAttribute* attr1, const StunAttribute* attr2) + { + return attr1->dataOffset() < attr2->dataOffset(); + } +}; + +void StunMessage::dump(std::ostream& output) +{ + switch (messageClass()) + { + case RequestClass: output << "Request"; break; + case IndicationClass: output << "Indication"; break; + case SuccessClass: output << "Success"; break; + case ErrorClass: output << "Error"; break; + default: + output << "Invalid"; + break; + } + + output << " / "; + switch (messageType()) + { + case Binding: output << "Binding"; break; + case Allocate: output << "Allocate"; break; + case Refresh: output << "Refresh"; break; + case Send: output << "Send"; break; + case Data: output << "Data"; break; + case CreatePermission: output << "CreatePermission"; break; + case ChannelBind: output << "ChannelBind"; break; + default: + output << "Invalid"; + break; + } + + output << std::endl; + + // Sort attribytes by data offset + std::vector attrList; + for (AttributeMap::iterator attrIter = mAttrMap.begin(); attrIter != mAttrMap.end(); attrIter++) + attrList.push_back(attrIter->second); + + std::sort(attrList.begin(), attrList.end(), CompareAttributesByOffsetFunctor()); + + for (unsigned i=0; idataOffset() <<": "; + attrList[i]->dump(output); + output << std::endl; + } +} diff --git a/src/libs/ice/ICEStunMessage.h b/src/libs/ice/ICEStunMessage.h new file mode 100644 index 00000000..0f66f75d --- /dev/null +++ b/src/libs/ice/ICEStunMessage.h @@ -0,0 +1,200 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_STUN_MESSAGE_H +#define __ICE_STUN_MESSAGE_H + +#include +#include +#include "ICEByteBuffer.h" + +namespace ice +{ + class StunAttribute + { + public: + enum Type + { + NotExist = 0, + MappedAddress = 1, + Username = 6, + MessageIntegrity = 8, + ErrorCode = 9, + UnknownAttributes = 10, + Realm = 20, + Nonce = 21, + XorMappedAddress = 32, + Server = 0x8022, + AlternateServer = 0x8023, + Fingerprint = 0x8028, + + // TURN + ChannelNumber = 0x0c, + Lifetime = 0x0d, + XorPeerAddress = 0x12, + Data = 0x13, + XorRelayedAddress = 0x16, + RequestedAddressFamily = 0x17, + RequestedTransport = 0x19, + ReservedToken = 0x22, + + // ICE + ControlledAttr = 0x8029, + ControllingAttr = 0x802a, + ICEPriority = 0x0024, + ICEUseCandidate = 0x0025 + }; + + StunAttribute(); + virtual ~StunAttribute(); + + virtual int type() const = 0; + virtual void buildPacket(BufferWriter& writer) = 0; + virtual bool parsePacket(BufferReader& reader) = 0; + + void setDataOffset(size_t offset); + size_t dataOffset() const; + virtual void dump(std::ostream& output) = 0; + + protected: + int mType; + int mLength; + size_t mDataOffset; + }; + + + class Username; + class Realm; + class Nonce; + class ErrorCode; + class MessageIntegrity; + class MappedAddress; + class XorMappedAddress; + class ControlledAttr; + class ControllingAttr; + class ICEPriority; + class Lifetime; + class XorRelayedAddress; + class ChannelNumber; + class XorPeerAddress; + + class StunMessage + { + public: + struct TransactionID + { + unsigned char mValue[12]; + + bool operator == (const TransactionID& rhs); + bool operator != (const TransactionID& rhs); + + TransactionID(); + std::string toStdString(); + + static TransactionID generateNew(); + }; + + enum Class + { + RequestClass = 0, //0b00, + IndicationClass = 1, //0b01, + SuccessClass = 2, //0b10, + ErrorClass = 3 //0b11 + }; + + enum Type + { + Binding = 1, + Allocate = 3, + Refresh = 4, + Send = 6, + Data = 7, + CreatePermission = 8, + ChannelBind = 9 + }; + + StunMessage(); + virtual ~StunMessage(); + + std::string comment(); + void setComment(std::string comment); + + void setMessageType(Type type); + Type messageType(); + + void setMessageClass(Class value); + Class messageClass(); + + unsigned int magicCookie(); + bool isMagicCookieValid(); + + void setTransactionId(TransactionID id); + TransactionID transactionId(); + + // Builds STUN packet using specified password (if MessageIntegrity attribute is add before) + void buildPacket(ByteBuffer& buffer, const std::string& password); + + // Parses STUN packet but do not validates it + bool parsePacket(ByteBuffer& buffer); + + // Validate parsed packet. Must be called right after ParsePacket() method. + // Returns true if validated ok, false otherwise. + bool validatePacket(std::string key); + + // Adds attribute to STUN message. If attribute of the same type exists - new one will be add. + void addAttribute(StunAttribute* attr); + + // Sets attribute to STUN message. If attribute of the same type exists - it will be overwritten. + void setAttribute(StunAttribute* attr); + + // Checks if there is specified attribute + bool hasAttribute(int attrType) const; + + // Gets reference to attribute object + StunAttribute& attribute(int attrType); + + const StunAttribute& operator [] (int attribute) const; + StunAttribute& operator[] (int attribute); + + Username& usernameAttr(); + Realm& realmAttr(); + ErrorCode& errorCodeAttr(); + Nonce& nonceAttr(); + MessageIntegrity& messageIntegrityAttr(); + MappedAddress& mappedAddressAttr(); + XorMappedAddress& xorMappedAddressAttr(); + ControlledAttr& iceControlledAttr(); + ControllingAttr& iceControllingAttr(); + ICEPriority& icePriorityAttr(); + Lifetime& lifetimeAttr(); + XorRelayedAddress& xorRelayedAddressAttr(); + ChannelNumber& channelNumberAttr(); + XorPeerAddress& xorPeerAddressAttr(); + + void dump(std::ostream& output); + + protected: + unsigned int mMagicCookie; // STUN magic cookie predefined value + Type mType; // Type of STUN message + Class mClass; // Class of STUN message + TransactionID mTransactionID; // Transaction ID of STUN message + + typedef std::multimap AttributeMap; + + mutable AttributeMap mAttrMap; // Attribute list + ByteBuffer mPacket2Parse; // Incoming packet + ByteBuffer mPacket2Send; // Outgoing packet + + std::string mComment; // Comment for this message + + //Helper method to get bit with specified index from 'value' parameter. + inline char bit(unsigned int value, size_t index); + + //Helper method to set bit in specified 'result' parameter + inline void setBit(unsigned int& result, size_t index, char value); + }; +} + +#endif diff --git a/src/libs/ice/ICEStunTransaction.cpp b/src/libs/ice/ICEStunTransaction.cpp new file mode 100644 index 00000000..9d939e20 --- /dev/null +++ b/src/libs/ice/ICEStunTransaction.cpp @@ -0,0 +1,493 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICEPlatform.h" +#include "ICEStunTransaction.h" +#include "ICEStunAttributes.h" +#include "ICELog.h" +#include "ICEError.h" +#include "ICEAction.h" +#include "ICETime.h" + +#ifndef _WIN32 +# include +#endif + +using namespace ice; +#define LOG_SUBSYSTEM "ICE" + +const char* Transaction::stateToString(State state) +{ + switch (state) + { + case Running: return "Running"; + case Failed: return "Failed"; + case Success: return "Success"; + } + return "Undefined"; +} + +Transaction::Transaction() +{ + mTransportType = IPv4; + + // There is no default ICE stack + mStackID = 0; + + // There is no default logger + mLog = NULL; + + // Packet is not composed in constructor + mComposed = false; + + // Initial state of transaction - "Running" + mState = Transaction::Running; + + // Reset user data + mTag = 0; + + // Do not use message integrity attribute by default + mMessageIntegrity = false; + + // Do not use fingerprint attribute by default + mFingerprint = false; + + // Do not use long term credentials by default + mLongTerm = false; + + // Do not use short term credentials by default + mShortTerm = false; + + // Create new transaction ID + generateId(); + + // CONTROLLING attribute is not used by default + mEnableControlling = false; + + // CONTROLLED attribute is not used by default + mEnableControlled = false; + + // PRIORITY attribute is not used by default + mEnablePriority = false; + mPriority = 0; + + // Transaction is not cancelled + mCancelled = false; + + // Transaction is not relayed by default + mRelayed = false; + + // Component port is not set by default + mComponent = 0; + + mKeepalive = false; + mInterval = 0; + mUserObject = NULL; + mType = None; + mRemoved = false; + mFailoverId = 0; +} + +Transaction::~Transaction() +{ +} + +void Transaction::generateId() +{ + for (size_t i=0; i<12; i++) + mTransactionID.mValue[i] = rand(); +} +void Transaction::setStackId(int id) +{ + mStackID = id; +} + +int Transaction::stackId() +{ + return mStackID; +} + +void Transaction::setTransportType(int _type) +{ + assert(_type == IPv4 || _type == IPv6); + mTransportType = _type; +} + +int Transaction::transportType() +{ + return mTransportType; +} + +std::string Transaction::toStdString() +{ + std::ostringstream output; + output << "State: " << Transaction::stateToString(mState) << ", "; + output << "Transport: " << (mTransportType == IPv4 ? "IPv4" : "IPv6") << ", "; + output << (mCancelled ? "Cancelled, " : ""); + output << "Destination: " << mDestination.toStdString().c_str() << ", "; + output << "Comment: " << mComment.c_str(); + + return output.str(); +} + +void Transaction::setTag(unsigned int tag) +{ + mTag = tag; +} + +unsigned Transaction::tag() +{ + return mTag; +} + +void Transaction::enqueueMessage(ice::StunMessage& msg) +{ + // Clear outgoing buffer + mOutgoingData.clear(); + + // Check if message should be secured by message integrity + std::string password = mPassword; + if (true == mMessageIntegrity) + { + // Ensure credentials are enabled + assert(mLongTerm || mShortTerm); + + // Create username attribute + Username* attr = new Username(); + + // Set username value + if (mLongTerm || mShortTerm) + attr->setValue(mUsername); + + // Add username attribute itself + msg.setAttribute(attr); + + // Add message integrity attribute + msg.setAttribute(new MessageIntegrity()); + } + + if (mFingerprint) + msg.setAttribute(new Fingerprint()); + + // Add ICE-CONTROLLED attribute if needed + if (mEnableControlled) + { + assert(mTieBreaker.length() == 8); + + ControlledAttr* attr = new ControlledAttr(); + attr->setTieBreaker(mTieBreaker); + msg.setAttribute(attr); + } + + // Add ICE-CONTROLLING attribute if needed + if (mEnableControlling) + { + assert(mTieBreaker.length() == 8); + + ControllingAttr* attr = new ControllingAttr(); + attr->setTieBreaker(mTieBreaker); + msg.setAttribute(attr); + } + + // Add ICE-PRIORITY attribute if needed + if (mEnablePriority) + { + ICEPriority* attr = new ICEPriority(); + attr->setPriority(mPriority); + msg.setAttribute(attr); + } + + msg.buildPacket(mOutgoingData, password); +} + +ByteBuffer* Transaction::generateData(bool force) +{ + if (mCancelled) + return NULL; + + // Check if there is any outgoing data + if (mOutgoingData.size() == 0) + return NULL; + + // Check if there is timeout for next transmission attempt + if (mRTOTimer.isTimeout() && !force) + { + ICELogCritical(<< "Transaction " << mComment << " timeouted."); + return NULL; + } + + // Check if transmission was made too much times - client should not send billions of packets. + if (mRTOTimer.isAttemptLimitReached() && !force) + return NULL; + + // Check if time to retransmit now + if (mRTOTimer.isTimeToRetransmit() || force) + { + mRTOTimer.attemptMade(); + + // Copy outgoing data + ByteBuffer* buffer = new ByteBuffer(mOutgoingData); + + buffer->setComment(mComment); + buffer->setRemoteAddress(destination()); + buffer->setComponent(component()); + buffer->setComment(comment()); + buffer->setTag(this); + return buffer; + } + else + { + } + return NULL; +} + +void Transaction::restart() +{ + mComposed = false; + mState = Transaction::Running; + mOutgoingData.clear(); + mRemoved = false; + mRTOTimer.stop(); + mRTOTimer.start(); +} + +bool Transaction::isTimeout() +{ + if (mRTOTimer.isTimeout()) + { + mState = Failed; + return true; + } + else + return false; +} + +void Transaction::addMessageIntegrity(bool enable) +{ + mMessageIntegrity = enable; +} + +void Transaction::addFingerprint(bool enable) +{ + mFingerprint = enable; +} + +void Transaction::addShortTermCredentials(bool enable) +{ + this->mShortTerm = enable; +} + +void Transaction::addLongTermCredentials(bool enable) +{ + this->mLongTerm = enable; +} + +void Transaction::addControllingRole(const std::string& tieBreaker) +{ + mEnableControlling = true; + mTieBreaker = tieBreaker; +} + +void Transaction::addControlledRole(const std::string& tieBreaker) +{ + mEnableControlled = true; + mTieBreaker = tieBreaker; +} + +void Transaction::addPriority(unsigned int priority) +{ + mEnablePriority = true; + mPriority = priority; +} + +unsigned int Transaction::priorityValue() +{ + if (!mEnablePriority) + throw Exception(NO_PRIORITY_ATTRIBUTE); + + return mPriority; +} + + +void Transaction::setUsername(const std::string& username) +{ + mUsername = username; +} + +void Transaction::setPassword(const std::string& password) +{ + mPassword = password; +} + +Transaction::State Transaction::state() const +{ + return mState; +} + +void Transaction::setAction(PAction action) +{ + mAction = action; +} + +PAction Transaction::action() const +{ + return mAction; +} + +void Transaction::cancel() +{ + mCancelled = true; +} + +bool Transaction::isCancelled() const +{ + return mCancelled; +} + +void Transaction::setComment(const std::string& comment) +{ + mComment = comment; +} + +std::string Transaction::comment() const +{ + return mComment; +} + +void Transaction::setDestination(const NetworkAddress& addr) +{ + mDestination = addr; +} + +void Transaction::setComponent(int component) +{ + mComponent = component; +} + +int Transaction::component() +{ + return mComponent; +} + +NetworkAddress& Transaction::destination() +{ + return mDestination; +} + +bool Transaction::relayed() +{ + return mRelayed; +} + +void Transaction::setRelayed(bool relayed) +{ + mRelayed = relayed; +} + +bool Transaction::keepalive() +{ + return mKeepalive; +} + +void Transaction::setKeepalive(bool keepalive) +{ + mKeepalive = keepalive; +} + +unsigned Transaction::interval() +{ + return mInterval; +} + +void Transaction::setInterval(unsigned interval) +{ + mInterval = interval; +} + +void* Transaction::userObject() +{ + return mUserObject; +} + +void Transaction::setUserObject(void* obj) +{ + mUserObject = obj; +} + +Transaction::Type Transaction::type() +{ + return mType; +} + +void Transaction::setType(Transaction::Type t) +{ + mType = t; +} + +bool Transaction::removed() +{ + return mRemoved; +} + +void Transaction::setRemoved(bool removed) +{ + if (!mRemoved && removed) + ICELogDebug(<< "Transaction " << mComment << " removed."); + + mRemoved = removed; +} + +unsigned Transaction::timestamp() +{ + return mTimestamp; +} + +void Transaction::setTimestamp(unsigned timestamp) +{ + mTimestamp = timestamp; +} + +StunMessage::TransactionID Transaction::transactionId() +{ + return mTransactionID; +} + +bool Transaction::hasToRunNow() +{ + if (!mKeepalive) + return true; + + //bool cf = (mComment == "ClientRefresh"); + + unsigned current = ICETimeHelper::timestamp(); + /*if (cf) + { + ICELogDebug(<< "ClientRefresh interval: " << ICETimeHelper::findDelta(timestamp(), current) << ", interval " << interval()*1000); + }*/ + + if (timestamp()) + { + if (ICETimeHelper::findDelta(timestamp(), current) < interval() * 1000) + return false; + + setTimestamp(current); + return true; + } + else + { + setTimestamp(current); + return false; + } +} + +void Transaction::setFailoverId(int failoverId) +{ + mFailoverId = failoverId; +} + +int Transaction::failoverId() const +{ + return mFailoverId; +} diff --git a/src/libs/ice/ICEStunTransaction.h b/src/libs/ice/ICEStunTransaction.h new file mode 100644 index 00000000..4c60ea26 --- /dev/null +++ b/src/libs/ice/ICEStunTransaction.h @@ -0,0 +1,245 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_STUN_TRANSACTION_H +#define __ICE_STUN_TRANSACTION_H + +#include +#include + +#include "ICEStunMessage.h" +#include "ICEPacketTimer.h" +#include "ICESmartPtr.h" +#include "ICECandidatePair.h" +#include "ICEAction.h" + +namespace ice +{ + class Logger; + + class Transaction + { + public: + enum Type + { + Binding = 1, + Relaying = 2, + KeepAlive = 4, + All = 7, + None = 8, + }; + + enum State + { + Running = 0, //Transaction is running now + Failed = 1, //Transaction is failed + Success = 2 //Transaction is succeeded + }; + static const char* stateToString(State state); + + Transaction(); + virtual ~Transaction(); + + void generateId(); + + // Returns if transaction is relayed and must be sent to TURN server instead its regular destination + bool relayed(); + + // Marks if transaction works through relay + void setRelayed(bool relayed); + + // Attempts to generate outgoing data. + // It is time-sensitive method - it can return empty pointer if there is not time to send data to network. + virtual ByteBuffer* + generateData(bool force = false); + + // Process incoming STUN message with source address + virtual bool processData(StunMessage& msg, NetworkAddress& address) = 0; + + // Attempts to restart transaction + virtual void restart(); + + // Checks if transaction is timeouted. + bool isTimeout(); + + // Adds MESSAGE-INTEGRITY attribute to outgoing messages + void addMessageIntegrity(bool enable); + + // Adds FINGERPRINT attribute to outgoing messages + void addFingerprint(bool enable); + + // Enables shortterm credentials on this transaction + void addShortTermCredentials(bool enable); + + // Enables longterm credentials on this transaction + void addLongTermCredentials(bool enable); + + // Adds CONTROLLING attribute with specified tie breaker value + void addControllingRole(const std::string& tieBreaker); + + // Adds CONTROLLED attribute with specified tie breaker value + void addControlledRole(const std::string& tieBreaker); + + // Adds PRIORITY attribute with specified value + void addPriority(unsigned int priority); + + // Returns received PRIORITY attribute + unsigned int priorityValue(); + + void setUsername(const std::string& username); + void setPassword(const std::string& password); + + // Sets associated tag value + void setTag(unsigned int tag); + unsigned int tag(); + + // Returns transaction state - Succeeded, Failed, Running + State state() const; + + // Associates action to be performed on finish + void setAction(PAction action); + PAction action() const; + + // Ceases all outgoing transmission for this transaction + void cancel(); + bool isCancelled() const; + + void setComment(const std::string& comment); + std::string comment() const; + + void setDestination(const NetworkAddress& addr); + NetworkAddress& destination(); + + void setComponent(int component); + int component(); + + void setStackId(int id); + int stackId(); + + void setTransportType(int _type); + int transportType(); + + bool keepalive(); + void setKeepalive(bool keepalive); + + // Interval for keepalive transactions in seconds + unsigned interval(); + void setInterval(unsigned interval); + + unsigned timestamp(); + void setTimestamp(unsigned timestamp); + + void* userObject(); + void setUserObject(void* obj); + + Type type(); + void setType(Type t); + + bool removed(); + void setRemoved(bool removed); + + virtual bool hasToRunNow(); + + StunMessage::TransactionID transactionId(); + + std::string toStdString(); + + void setFailoverId(int failoverId); + int failoverId() const; + + protected: + + // Logger + Logger* mLog; + + // Retransmission timer + PacketScheduler mRTOTimer; + + // Marks if transaction is cancelled + bool mCancelled; + + // Marks if packet was created + bool mComposed; + + // Long-term credentials + std::string mUsername; + std::string mPassword; + + // Marks if long term credentials must be used + bool mLongTerm; + + // Marks if short term credentials must be used + bool mShortTerm; + + // Marks if CONTROLLING attribute must be used + bool mEnableControlling; + + // Marks if CONTROLLED attribute must be used + bool mEnableControlled; + + // Marks if PRIORITY attribute must be used + bool mEnablePriority; + + // Priority value + unsigned int mPriority; + + // Tie breaker value for CONTROLLING&CONTROLLED attributes + std::string mTieBreaker; + + // Transaction ID + StunMessage::TransactionID mTransactionID; + + // Buffer to hold raw outgoing data + ByteBuffer mOutgoingData; + + // Marks if fingerprint attribute must be used for outgoing messages + bool mFingerprint; + + // Marks if message integrity attribyte must be used for outgoing messages + bool mMessageIntegrity; + + // Tag associated with transaction + unsigned int mTag; + + // Transaction state - Running, Failed or Success + State mState; + + // Action that must be run on transaction finish + PAction mAction; + + // Comment that describes this transaction + std::string mComment; + + // Destination address + NetworkAddress mDestination; + + // Relayed flag + bool mRelayed; + + // Source component's ID + int mComponent; + + // Used ICE stack ID. This member is used for debugging purpose. + int mStackID; + int mTransportType; + + bool mKeepalive; + unsigned mInterval; + void* mUserObject; + Type mType; + bool mRemoved; + int mFailoverId; + + // Timestamp when transaction runs in last time. Default is zero. + unsigned mTimestamp; + + // Updates msg with auth. data (MessageDigest + Fingerprint) + fills mOutgoingData + void enqueueMessage(ice::StunMessage& msg); + + + }; +} + +#endif diff --git a/src/libs/ice/ICESync.cpp b/src/libs/ice/ICESync.cpp new file mode 100644 index 00000000..3a179925 --- /dev/null +++ b/src/libs/ice/ICESync.cpp @@ -0,0 +1,99 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICESync.h" + +using namespace ice; + +Mutex::Mutex() +{ +#ifdef _WIN32 + InitializeCriticalSection(&mSection); +#else + pthread_mutexattr_init(&mAttr); + pthread_mutexattr_settype(&mAttr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mMutex, &mAttr); +#endif +} + +Mutex::~Mutex() +{ +#ifdef _WIN32 + DeleteCriticalSection(&mSection); +#else + pthread_mutex_destroy(&mMutex); + pthread_mutexattr_destroy(&mAttr); +#endif +} + +void Mutex::lock() +{ +#ifdef _WIN32 + EnterCriticalSection(&mSection); +#else + pthread_mutex_lock(&mMutex); +#endif +} + +void Mutex::unlock() +{ +#ifdef _WIN32 + LeaveCriticalSection(&mSection); +#else + pthread_mutex_unlock(&mMutex); +#endif +} + + +Lock::Lock(Mutex &mutex) +:mMutex(mutex) +{ + mMutex.lock(); +} + +Lock::~Lock() +{ + mMutex.unlock(); +} + +#ifndef _WIN32 +static pthread_mutex_t DoGuard = PTHREAD_MUTEX_INITIALIZER ; +#endif + +long Atomic::increment(long *value) +{ +#ifdef _WIN32 + return ::InterlockedIncrement((LONG*)value); +#else + pthread_mutex_lock(&DoGuard); + (void)*value++; + long result = *value; + pthread_mutex_unlock(&DoGuard); + return result; +#endif +} + +long Atomic::decrement(long *value) +{ +#ifdef _WIN32 + return ::InterlockedDecrement((LONG*)value); +#else + pthread_mutex_lock(&DoGuard); + (void)*value--; + long result = *value; + pthread_mutex_unlock(&DoGuard); + return result; +#endif +} + + +void* ThreadInfo::currentThread() +{ +#ifdef _WIN32 + return (void*)::GetCurrentThreadId(); +#else + return (void*)(::pthread_self()); +#endif +} diff --git a/src/libs/ice/ICESync.h b/src/libs/ice/ICESync.h new file mode 100644 index 00000000..a6563aa3 --- /dev/null +++ b/src/libs/ice/ICESync.h @@ -0,0 +1,62 @@ +/* Copyright(C) 2007-2017 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_SYNC_H +#define __ICE_SYNC_H + +#ifdef _WIN32 +# include +# include +#else +# include +#endif + +namespace ice +{ + + +class Mutex +{ +public: + Mutex(); + ~Mutex(); + void lock(); + void unlock(); + +protected: +#ifdef _WIN32 + CRITICAL_SECTION mSection; +#else + pthread_mutexattr_t mAttr; + pthread_mutex_t mMutex; +#endif +}; + +class Lock +{ +public: + Lock(Mutex& mutex); + ~Lock(); + +protected: + Mutex& mMutex; +}; + +class Atomic +{ +public: + static long increment(long* value); + static long decrement(long* value); +}; + +class ThreadInfo +{ +public: + static void* currentThread(); +}; + +} + +#endif diff --git a/src/libs/ice/ICETime.cpp b/src/libs/ice/ICETime.cpp new file mode 100644 index 00000000..0eda1f5e --- /dev/null +++ b/src/libs/ice/ICETime.cpp @@ -0,0 +1,232 @@ +/* Copyright(C) 2007-2017 Voipobjects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifdef _WIN32 +# include +# include +#else +# include +# include +# include +# include +#endif + +#include "ICEPlatform.h" + +#include "ICETime.h" +using namespace ice; + + +#ifdef _WIN32 +static unsigned GetMilliseconds() +{ + return ::GetTickCount(); +} +#else +static int ClocksPerSec = (int)sysconf(_SC_CLK_TCK); +static tms GlobalStartTimeStruct; +static clock_t GlobalStartTime = times(&GlobalStartTimeStruct); +static unsigned GetMilliseconds() +{ + tms t; + clock_t result = times(&t) - GlobalStartTime; + float ticksPerMilliseconds = ClocksPerSec / 1000.0; + return unsigned( result / ticksPerMilliseconds ); +} +#endif + +TimeoutDetector::TimeoutDetector() + :mTimestamp(0), mAttempt(0) +{ +} + +TimeoutDetector::~TimeoutDetector() +{ +} + +void TimeoutDetector::start() +{ + mTimestamp = ::GetMilliseconds(); +} + +void TimeoutDetector::stop() +{ +} + +void TimeoutDetector::reset() +{ + mAttempt = 0; +} + +bool TimeoutDetector::isTimeToRetransmit() +{ + static time_t RetransmissionIntervalArray[] = { 100, 200, 200, 200, 200, 200 }; + + //get current time + time_t current = ::GetMilliseconds(); + + //find the delta + time_t delta = current - mTimestamp; + + //find a wait interval for the mAttempt value + time_t referenceInterval = 0; + + size_t arrayLength = sizeof(RetransmissionIntervalArray) / sizeof(RetransmissionIntervalArray[0]); + + if (mAttempt < arrayLength ) + referenceInterval = RetransmissionIntervalArray[mAttempt]; + else + referenceInterval = RetransmissionIntervalArray[arrayLength-1]; + + if (delta >= referenceInterval) + return true; + + return false; +} + +void TimeoutDetector::nextAttempt() +{ + mAttempt++; + mTimestamp = ::GetMilliseconds(); +} + +bool TimeoutDetector::isTimeout() +{ + // Get current time + time_t current = ::GetMilliseconds(); + + // Find the delta + time_t delta = current - mTimestamp; + + return delta > ICE_TIMEOUT_VALUE; +} + + +ICEStartTimer::ICEStartTimer() + :mTimestamp(0), mInterval(0), mEnabled(false) +{ +} + +ICEStartTimer::~ICEStartTimer() +{ +} + +void ICEStartTimer::start(unsigned interval) +{ + mInterval = interval; + mTimestamp = ::GetMilliseconds(); + mEnabled = true; +} + +void ICEStartTimer::stop() +{ + mEnabled = false; +} + +bool ICEStartTimer::isTimeToBegin() +{ + if (!mEnabled) + return false; + + unsigned t = ::GetMilliseconds(); + unsigned delta = 0; + + if (t < 0x7FFFFFFF && mTimestamp > 0x7FFFFFFF) + delta = 0xFFFFFFFF - mTimestamp + t; + else + delta = t - mTimestamp; + + return delta >= mInterval; +} + +ICEScheduleTimer::ICEScheduleTimer() +:mEnabled(false), mTimestamp(0), mTail(0), mInterval(0) +{ +} + +ICEScheduleTimer::~ICEScheduleTimer() +{ +} + +void ICEScheduleTimer::start(int interval) +{ + mEnabled = true; + mInterval = interval; + mTail = 1; // First check is immediate! + mTimestamp = ICETimeHelper::timestamp(); +} + +bool ICEScheduleTimer::isTimeToSend() +{ + if (!mEnabled) + return false; + +#ifdef ICE_SIMPLE_SCHEDULE + unsigned current = ICETimeHelper::timestamp(); + unsigned delta = ICETimeHelper::findDelta(mTimestamp, current); + + return delta > mInterval; +#else + // Check if there are already scheduled checks + if (mTail > 0) + { + mTail--; + return true; + } + + unsigned current = ICETimeHelper::timestamp(); + unsigned delta = ICETimeHelper::findDelta(mTimestamp, current); + + if (delta > (unsigned)mInterval) + { + mTail += delta / mInterval; + mTimestamp = current - delta % mInterval; + } + + if (mTail > 0) + { + mTail--; + return true; + } + + return false; +#endif +} + +void ICEScheduleTimer::stop() +{ + mEnabled = false; +} + +int ICEScheduleTimer::remaining() +{ + unsigned delta = ICETimeHelper::findDelta(mTimestamp, ICETimeHelper::timestamp()); +#ifdef ICE_SIMPLE_SCHEDULE + return (delta >= mInterval) ? 0 : mInterval - delta; +#else + return ((int)delta + mTail >= mInterval) ? 0 : mInterval - delta - mTail; +#endif +} + +int ICEScheduleTimer::interval() const +{ + return mInterval; +} + +void ICEScheduleTimer::setInterval(int interval) +{ + mTail = 0; + mInterval = interval; +} + +unsigned int ICETimeHelper::timestamp() +{ + return ::GetMilliseconds(); +} + +unsigned int ICETimeHelper::findDelta(unsigned int oldTS, unsigned int newTS) +{ + return (oldTS > 0x7FFFFFFF && newTS < 0x7FFFFFFF) ? 0xFFFFFFFF - oldTS + newTS : newTS - oldTS; +} diff --git a/src/libs/ice/ICETime.h b/src/libs/ice/ICETime.h new file mode 100644 index 00000000..687dacb2 --- /dev/null +++ b/src/libs/ice/ICETime.h @@ -0,0 +1,113 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_TIME_H +#define __ICE_TIME_H + +#include "ICEPlatform.h" +#include "ICETypes.h" +#ifndef _WIN32 +# include +# include +#endif + +namespace ice { + + class TimeoutDetector + { + public: + TimeoutDetector(); + ~TimeoutDetector(); + + void start(); + void stop(); + + /*! Resets the countdown. */ + void reset(); + + /*! Checks if it is a time to retransmit non-answered packet + * @return true if time to retransmit packet, false if not. */ + bool isTimeToRetransmit(); + + /*! Notifies timer about retransmission. */ + void nextAttempt(); + + /*! Checks if it is a time to mark the transaction timeouted. + * @return true if transaction is timeouted, false if not. */ + bool isTimeout(); + protected: + + /// Time tracking member + time_t mTimestamp; + + /// Retransmission attempt counter + size_t mAttempt; + }; + + class ICEStartTimer + { + public: + ICEStartTimer(); + ~ICEStartTimer(); + + void start(unsigned interval); + bool isTimeToBegin(); + void stop(); + + protected: + unsigned mTimestamp; + unsigned mInterval; + bool mEnabled; + }; + + /*! Class intendend to schedule connectivity checks. It is simple timer which returns true from IsTimeToSend() every interval milliseconds. */ + class ICEScheduleTimer + { + public: + /*! Default constructor. */ + ICEScheduleTimer(); + + /*! Destructor. */ + ~ICEScheduleTimer(); + + /*! Start timer with interval in milliseconds. */ + void start(int interval); + + /*! Check if it is a time to send next check. This method must be called in while (IsTimeToSend()) {} loop - + * as multiple checks can be scheduled for elapsed time interval. */ + bool isTimeToSend(); + + /*! Stops timer. */ + void stop(); + + /*! Returns remaining time in milliseconds. */ + int remaining(); + + /*! Returns interval time in milliseconds. */ + int interval() const; + + /*! Sets new interval time in milliseconds. Can be called on active timer, will reschedule timeout event. */ + void setInterval(int interval); + + protected: + bool mEnabled; /// Marks if timer is started + unsigned mTimestamp; /// Last timestamp + int mTail; /// How much checks was scheduled for elapsed time interval. + int mInterval; /// Timer interval + }; + + class ICETimeHelper + { + public: + static unsigned timestamp(); + static unsigned findDelta(unsigned oldTimestamp, unsigned int newTimestamp); + }; + +}; + + + + +#endif diff --git a/src/libs/ice/ICETransactionList.cpp b/src/libs/ice/ICETransactionList.cpp new file mode 100644 index 00000000..c89da54b --- /dev/null +++ b/src/libs/ice/ICETransactionList.cpp @@ -0,0 +1,288 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ICETransactionList.h" +#include "ICEAction.h" +#include "ICELog.h" + +using namespace ice; + +#define LOG_SUBSYSTEM "ICE" + +TransactionList::TransactionList() +:mRegularIndex(0), mPrioritizedIndex(0) +{ + mRegularList.reserve(1024); + mPrioritizedList.reserve(1024); +} + +TransactionList::~TransactionList() +{ + for (unsigned i=0; iremoved()) + continue; + + finished = t->state() == Transaction::Success || t->state() == Transaction::Failed; + if (!finished) + { + if (t->processData(msg, address)) + { + finished = t->state() == Transaction::Success || t->state() == Transaction::Failed; + if (finished && t->action()) + t->action()->finished(*t); + + // Previous action could restart transaction - so check transaction state again + finished = t->state() == Transaction::Success || t->state() == Transaction::Failed; + + if (finished) + { + if (t->keepalive()) + t->restart(); + else + t->setRemoved(true); + } + return true; + } + } + } + return false; +} + +bool TransactionList::processIncoming(StunMessage& msg, NetworkAddress& address) +{ + if (processIncoming(mRegularList, msg, address)) + return true; + if (processIncoming(mPrioritizedList, msg, address)) + return true; + + return false; +} + +bool TransactionList::checkTimeout(List& l) +{ + // Iterate checks + unsigned index; + for (index=0; indexstate() == Transaction::Running) + { + // Is transaction timeouted? + if (t->isTimeout()) + { + ICELogDebug(<< "Transaction " << t->comment() << " timeouted"); + if (t->action()) + t->action()->finished(*t); + + if (t->keepalive()) + t->restart(); + else + t->setRemoved(true); + return true; + } + } + } + return false; +} + +bool TransactionList::checkTimeout() +{ + if (checkTimeout(mPrioritizedList)) + return true; + if (checkTimeout(mRegularList)) + return true; + + return false; +} + +void TransactionList::addRegular(Transaction* p) +{ + List::iterator regularIter = std::find(mRegularList.begin(), mRegularList.end(), p); + List::iterator prioritizedIter = std::find(mPrioritizedList.begin(), mPrioritizedList.end(), p); + + if (regularIter == mRegularList.end() && prioritizedIter == mPrioritizedList.end()) + mRegularList.push_back(p); +} + +void TransactionList::erase(Transaction* p) +{ + List::iterator it = std::find(mRegularList.begin(), mRegularList.end(), p); + if (it != mRegularList.end()) + p->setRemoved(true); + else + { + it = std::find(mPrioritizedList.begin(), mPrioritizedList.end(), p); + if (it != mPrioritizedList.end()) + p->setRemoved(true); + } +} + +void TransactionList::erase(const TransactionCondition& cond) +{ + List::iterator iter; + for (iter = mRegularList.begin();iter != mRegularList.end(); iter++) + { + if (cond.check(*iter)) + (*iter)->setRemoved(true); + } + + for (iter = mPrioritizedList.begin(); iter != mPrioritizedList.end(); iter++) + { + if (cond.check(*iter)) + (*iter)->setRemoved(true); + } +} + +void TransactionList::eraseMatching(unsigned types) +{ + List::iterator iter; + for (iter = mRegularList.begin();iter != mRegularList.end(); iter++) + { + if (types && (*iter)->type()) + (*iter)->setRemoved(true); + } + + for (iter = mPrioritizedList.begin(); iter != mPrioritizedList.end(); iter++) + { + if (types && (*iter)->type()) + (*iter)->setRemoved(true); + } +} + +int TransactionList::copyMatching(const TransactionCondition& condition, std::vector& result) +{ + List::iterator iter; + int counter = (int)result.size(); + for (iter = mRegularList.begin();iter != mRegularList.end(); iter++) + { + if (condition.check(*iter)) + result.push_back(*iter); + } + + for (iter = mPrioritizedList.begin(); iter != mPrioritizedList.end(); iter++) + { + if (condition.check(*iter)) + result.push_back(*iter); + } + + return (int)result.size() - counter; +} + +void TransactionList::prioritize(Transaction* p) +{ + // Check if this transaction is prioritized already + List::iterator iter = std::find(mPrioritizedList.begin(), mPrioritizedList.end(), p); + if (iter != mPrioritizedList.end()) + return; + + // Check if the transaction is in regular list + iter = std::find(mRegularList.begin(), mRegularList.end(), p); + if (iter == mRegularList.end()) + return; + + // Remove the transaction from regular list + mRegularList.erase(iter); + + // And move to priority list + mPrioritizedList.push_back(p); +} + +Transaction* TransactionList::getNextTransaction() +{ + while (mPrioritizedIndex < mPrioritizedList.size() && mPrioritizedList[mPrioritizedIndex]->removed()) + mPrioritizedIndex++; + if (mPrioritizedIndex < mPrioritizedList.size()) + return mPrioritizedList[mPrioritizedIndex++]; + + while (mRegularIndex < mRegularList.size() && mRegularList[mRegularIndex]->removed()) + mRegularIndex++; + if (mRegularIndex < mRegularList.size()) + return mRegularList[mRegularIndex++]; + + mPrioritizedIndex = 0; + mRegularIndex = 0; + + while (mPrioritizedIndex < mPrioritizedList.size() && mPrioritizedList[mPrioritizedIndex]->removed()) + mPrioritizedIndex++; + if (mPrioritizedIndex < mPrioritizedList.size()) + return mPrioritizedList[mPrioritizedIndex++]; + + while (mRegularIndex < mRegularList.size() && mRegularList[mRegularIndex]->removed()) + mRegularIndex++; + if (mRegularIndex < mRegularList.size()) + return mRegularList[mRegularIndex++]; + + return NULL; +} + +void TransactionList::addPrioritized(Transaction* p) +{ + List::iterator regularIter = std::find(mRegularList.begin(), mRegularList.end(), p); + List::iterator prioritizedIter = std::find(mPrioritizedList.begin(), mPrioritizedList.end(), p); + + if (regularIter != mRegularList.end()) + mRegularList.erase(regularIter); + + if (prioritizedIter == mPrioritizedList.end()) + mPrioritizedList.push_back(p); +} + +int TransactionList::count() +{ + return (int)mRegularList.size() + (int)mPrioritizedList.size(); +} + +void TransactionList::clear() +{ + mRegularList.clear(); + mPrioritizedList.clear(); +} + +bool TransactionList::exists(Transaction* t) +{ + List::iterator regularIter = std::find(mRegularList.begin(), mRegularList.end(), t); + List::iterator prioritizedIter = std::find(mPrioritizedList.begin(), mPrioritizedList.end(), t); + + bool removed = true; + + if (regularIter != mRegularList.end()) + removed &= (*regularIter)->removed(); + + if (prioritizedIter != mPrioritizedList.end()) + removed &= (*prioritizedIter)->removed(); + + return !removed; +} + +bool TransactionList::exists(const TransactionCondition& condition) +{ + int counter = 0; + List::iterator iter; + for (iter = mRegularList.begin();iter != mRegularList.end(); iter++) + { + if (condition.check(*iter)) + counter++; + } + + for (iter = mPrioritizedList.begin(); iter != mPrioritizedList.end(); iter++) + { + if (condition.check(*iter)) + counter++; + } + return counter > 0; +} diff --git a/src/libs/ice/ICETransactionList.h b/src/libs/ice/ICETransactionList.h new file mode 100644 index 00000000..d713d671 --- /dev/null +++ b/src/libs/ice/ICETransactionList.h @@ -0,0 +1,50 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_TRANSACTION_LIST_H +#define __ICE_TRANSACTION_LIST_H + +#include +#include "ICEStunTransaction.h" + +namespace ice +{ + class TransactionCondition + { + public: + virtual bool check(Transaction* t) const = 0; + }; + + class TransactionList + { + protected: + typedef std::vector List; + List mRegularList, mPrioritizedList; + unsigned mRegularIndex, mPrioritizedIndex; + + bool processIncoming(List& l, StunMessage& msg, NetworkAddress& address); + bool checkTimeout(List& l); + public: + TransactionList(); + ~TransactionList(); + + bool processIncoming(StunMessage& msg, NetworkAddress& address); + bool checkTimeout(); + void addRegular(Transaction* p); + void addPrioritized(Transaction* p); + void prioritize(Transaction* p); + void erase(Transaction* p); + void erase(const TransactionCondition& condition); + void eraseMatching(unsigned types); + int copyMatching(const TransactionCondition& condition, std::vector& result); + Transaction* getNextTransaction(); + int count(); + void clear(); + bool exists(Transaction* t); + bool exists(const TransactionCondition& condition); + }; +} + +#endif \ No newline at end of file diff --git a/src/libs/ice/ICETypes.h b/src/libs/ice/ICETypes.h new file mode 100644 index 00000000..fe5e00e6 --- /dev/null +++ b/src/libs/ice/ICETypes.h @@ -0,0 +1,16 @@ +/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ICE_TYPES_H +#define __ICE_TYPES_H + +#include + + //#define INVALID_SOCKET (-1) +# ifndef SOCKET +# define SOCKET int +# endif + +#endif diff --git a/src/libs/ice/License.txt b/src/libs/ice/License.txt new file mode 100644 index 00000000..f4bbcd20 --- /dev/null +++ b/src/libs/ice/License.txt @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. \ No newline at end of file diff --git a/src/libs/ice/ice_vs2013.vcxproj b/src/libs/ice/ice_vs2013.vcxproj new file mode 100644 index 00000000..04957b56 --- /dev/null +++ b/src/libs/ice/ice_vs2013.vcxproj @@ -0,0 +1,154 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + ice + {5E483901-D5B2-40EE-B9ED-35F8D64AC04E} + ICEImpl + Win32Proj + + + + StaticLibrary + v120_xp + Unicode + false + + + StaticLibrary + v120_xp + Unicode + + + + + + + + + + + + + <_ProjectFileVersion>12.0.21005.1 + + + $(Configuration)\ + $(Configuration)\ + + + $(Configuration)\ + $(Configuration)\ + + + + Disabled + ../openssl/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;USE_OPENSSL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + false + + Level3 + EditAndContinue + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + MinSpace + true + ../openssl/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;USE_OPENSSL;%(PreprocessorDefinitions) + MultiThreadedDLL + true + false + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libs/ice/ice_vs2013.vcxproj.filters b/src/libs/ice/ice_vs2013.vcxproj.filters new file mode 100644 index 00000000..aa5c4a39 --- /dev/null +++ b/src/libs/ice/ice_vs2013.vcxproj.filters @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/libs/ice/ice_vs2013.vcxproj.user b/src/libs/ice/ice_vs2013.vcxproj.user new file mode 100644 index 00000000..abe8dd89 --- /dev/null +++ b/src/libs/ice/ice_vs2013.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/libs/jrtplib/CMakeLists.txt b/src/libs/jrtplib/CMakeLists.txt new file mode 100644 index 00000000..4bfcf4aa --- /dev/null +++ b/src/libs/jrtplib/CMakeLists.txt @@ -0,0 +1,175 @@ +cmake_minimum_required(VERSION 2.6) + +project(jrtplib) +set(VERSION 3.9.1) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") + +set (_DEFAULT_LIBRARY_INSTALL_DIR lib) +if (EXISTS "${CMAKE_INSTALL_PREFIX}/lib32/" AND CMAKE_SIZEOF_VOID_P EQUAL 4) + set (_DEFAULT_LIBRARY_INSTALL_DIR lib32) +elseif (EXISTS "${CMAKE_INSTALL_PREFIX}/lib64/" AND CMAKE_SIZEOF_VOID_P EQUAL 8) + set (_DEFAULT_LIBRARY_INSTALL_DIR lib64) +endif () + +set(LIBRARY_INSTALL_DIR "${_DEFAULT_LIBRARY_INSTALL_DIR}" CACHE PATH "Library installation directory") +if(NOT IS_ABSOLUTE "${LIBRARY_INSTALL_DIR}") + set(LIBRARY_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${LIBRARY_INSTALL_DIR}") +endif() + +include(CheckCXXCompilerFlag) +include(CheckIncludeFile) +include(CheckIncludeFileCXX) +include(CheckCXXSourceCompiles) +include(TestBigEndian) +include(${PROJECT_SOURCE_DIR}/cmake/Macros.cmake) + +find_package(JThread) + +set(JRTPLIB_LINK_LIBS "") +set(JRTPLIB_INTERNAL_INCLUDES "") +set(JRTPLIB_EXTERNAL_INCLUDES "") + +add_additional_stuff(JRTPLIB_EXTERNAL_INCLUDES JRTPLIB_LINK_LIBS) + +jrtplib_support_option("Support SDES PRIV items" JRTPLIB_SUPPORT_SDESPRIV RTP_SUPPORT_SDESPRIV ON "// No support for SDES PRIV items") +jrtplib_support_option("Support the probation mechanism for a new source" JRTPLIB_SUPPORT_PROBATION RTP_SUPPORT_PROBATION ON "// Do not wait for a number of consecutive packets to validate source") +jrtplib_support_option("Support sending RTCP APP packets" JRTPLIB_SUPPORT_SENDAPP RTP_SUPPORT_SENDAPP ON "// No direct support for sending RTCP APP packets") +jrtplib_support_option("Support sending unknown RTCP packets" JRTPLIB_SUPPORT_RTCPUNKNOWN RTP_SUPPORT_RTCPUNKNOWN OFF "// No support for sending unknown RTCP packets") +jrtplib_support_option("Support memory management mechanism" JRTPLIB_SUPPORT_MEMORYMGMT RTP_SUPPORT_MEMORYMANAGEMENT ON "// No memory management support") + +jrtplib_include_test(sys/filio.h RTP_HAVE_SYS_FILIO "// Don't have ") +jrtplib_include_test(sys/sockio.h RTP_HAVE_SYS_SOCKIO "// Don't have ") +jrtplib_include_test(ifaddrs.h RTP_SUPPORT_IFADDRS "// No ifaddrs support") + +if (JTHREAD_FOUND) + set(V "ON") +else (JTHREAD_FOUND) + set(V "OFF") +endif (JTHREAD_FOUND) + +option(JTHREAD_ENABLED "Thread support" ${V}) +if (JTHREAD_ENABLED) + set (RTP_SUPPORT_THREAD "#define RTP_SUPPORT_THREAD") + if (JTHREAD_FOUND) + save_paths(JRTPLIB_EXTERNAL_INCLUDES "${JTHREAD_INCLUDE_DIRS}") + save_paths(JRTPLIB_LINK_LIBS "${JTHREAD_LIBRARIES}") + endif(JTHREAD_FOUND) +else (JTHREAD_ENABLED) + set (RTP_SUPPORT_THREAD "// No support for JThread was enabled") +endif (JTHREAD_ENABLED) + +if (CMAKE_CROSSCOMPILING) + option (JRTPLIB_USE_BIGENDIAN "Target platform is big endian" ON) + if (JRTPLIB_USE_BIGENDIAN) + set(RTP_ENDIAN "#define RTP_BIG_ENDIAN") + else (JRTPLIB_USE_BIGENDIAN) + set(RTP_ENDIAN "// Little endian system") + endif (JRTPLIB_USE_BIGENDIAN) +else (CMAKE_CROSSCOMPILING) + test_big_endian(JRTPLIB_BIGENDIAN) + if (JRTPLIB_BIGENDIAN) + set(RTP_ENDIAN "#define RTP_BIG_ENDIAN") + else (JRTPLIB_BIGENDIAN) + set(RTP_ENDIAN "// Little endian system") + endif (JRTPLIB_BIGENDIAN) +endif (CMAKE_CROSSCOMPILING) + +jrtplib_test_feature(socklentest RTP_SOCKLENTYPE_UINT TRUE "// socklen_t is 'int'") +jrtplib_test_feature(ipv4mcasttest RTP_SUPPORT_IPV4MULTICAST FALSE "// No IPv4 multicasting support") +jrtplib_test_feature(salentest RTP_HAVE_SOCKADDR_LEN FALSE "// No sa_len member in struct sockaddr") +jrtplib_test_feature(getloginrtest RTP_SUPPORT_GETLOGINR FALSE "// Not using getlogin_r") +jrtplib_test_feature(ipv6test RTP_SUPPORT_IPV6 FALSE "// No IPv6 support") +jrtplib_test_feature(ipv6mcasttest RTP_SUPPORT_IPV6MULTICAST FALSE "// No IPv6 multicasting support") + +check_cxx_source_compiles("#include \n#include \nint main(void) { size_t a = 0 ; size_t b = a; uint32_t x = 0; uint32_t y = x; return 0; }" JRTPLIB_STDINT) +if (JRTPLIB_STDINT) + set(RTP_INTTYPE_HEADERS "#include \n#include ") +else (JRTPLIB_STDINT) + check_cxx_source_compiles("#include \n#include \nint main(void) { uint32_t x = 0; uint32_t y = x; return 0; }" JRTPLIB_INTTYPES) + if (JRTPLIB_INTTYPES) + set(RTP_INTTYPE_HEADERS "#include \n#include \n") + else (JRTPLIB_INTTYPES) + if (NOT UNIX AND WIN32) + set(RTP_INTTYPE_HEADERS "#include \"rtptypes_win.h\"") + else (NOT UNIX AND WIN32) + set(RTP_INTTYPE_HEADERS "#error Could not find header files that define types like 'uint32_t'. Please edit the file ${PROJECT_BINARY_DIR}/src/rtptypes_unix.h and make sure that the following types are defined: int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t") + message("\n\nError: Could not find header files that define types like 'uint32_t'.\nPlease edit the file ${PROJECT_BINARY_DIR}/src/rtptypes_unix.h\nand make sure that the following types are defined: \nint8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t\n\n") + endif (NOT UNIX AND WIN32) + endif (JRTPLIB_INTTYPES) +endif (JRTPLIB_STDINT) + +if (NOT UNIX AND WIN32) + set(RTP_WINSOCK_HEADERS "#if defined(WIN32) || defined(_WIN32_WCE)\n #include \n #include \n#ifndef _WIN32_WCE\n #include \n#endif // _WIN32_WCE\n#endif // WIN32 || _WIN32_WCE\n") +endif (NOT UNIX AND WIN32) + +if (NOT UNIX) + set(JRTPLIB_COMPILE_STATIC ON CACHE BOOL "Flag indicating if a static library should be built, or a dynamic one") + list(APPEND JRTPLIB_LINK_LIBS "ws2_32") +endif (NOT UNIX) + +if (UNIX OR JRTPLIB_COMPILE_STATIC) + set(JRTPLIB_IMPORT "") + set(JRTPLIB_EXPORT "") +else (UNIX OR JRTPLIB_COMPILE_STATIC) + set(JRTPLIB_IMPORT "__declspec(dllimport)") + set(JRTPLIB_EXPORT "__declspec(dllexport)") +endif (UNIX OR JRTPLIB_COMPILE_STATIC) + +configure_file("${PROJECT_SOURCE_DIR}/src/rtptypes.h.in" "${PROJECT_BINARY_DIR}/src/rtptypes.h") +configure_file("${PROJECT_SOURCE_DIR}/src/rtpconfig.h.in" "${PROJECT_BINARY_DIR}/src/rtpconfig.h") + +save_paths(JRTPLIB_INTERNAL_INCLUDES "${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/src") + +add_subdirectory(src) +add_subdirectory(examples) + +if (UNIX) + get_target_property(JRTPLIB_LOCAL_LIBRARY_NAME jrtplib-shared LOCATION) + get_filename_component(JRTPLIB_LIBNAME "${JRTPLIB_LOCAL_LIBRARY_NAME}" NAME) + set(JRTPLIB_LIBS "${LIBRARY_INSTALL_DIR}/${JRTPLIB_LIBNAME}") +else (UNIX) + if (JRTPLIB_COMPILE_STATIC) + get_target_property(JRTPLIB_LOCAL_LIBRARY_NAME jrtplib-static RELEASE_LOCATION) + get_filename_component(JRTPLIB_LIBNAME_RELEASE "${JRTPLIB_LOCAL_LIBRARY_NAME}" NAME_WE) + get_target_property(JRTPLIB_LOCAL_LIBRARY_NAME jrtplib-static DEBUG_LOCATION) + get_filename_component(JRTPLIB_LIBNAME_DEBUG "${JRTPLIB_LOCAL_LIBRARY_NAME}" NAME_WE) + else (JRTPLIB_COMPILE_STATIC) + get_target_property(JRTPLIB_LOCAL_LIBRARY_NAME jrtplib-shared RELEASE_LOCATION) + get_filename_component(JRTPLIB_LIBNAME_RELEASE "${JRTPLIB_LOCAL_LIBRARY_NAME}" NAME_WE) + get_target_property(JRTPLIB_LOCAL_LIBRARY_NAME jrtplib-shared DEBUG_LOCATION) + get_filename_component(JRTPLIB_LIBNAME_DEBUG "${JRTPLIB_LOCAL_LIBRARY_NAME}" NAME_WE) + endif (JRTPLIB_COMPILE_STATIC) + set(JRTPLIB_LIBS optimized "${LIBRARY_INSTALL_DIR}/${JRTPLIB_LIBNAME_RELEASE}.lib" + debug "${LIBRARY_INSTALL_DIR}/${JRTPLIB_LIBNAME_DEBUG}.lib") +endif (UNIX) + +set(JRTPLIB_INCDIRS ${JRTPLIB_EXTERNAL_INCLUDES} ${CMAKE_INSTALL_PREFIX}/include) +set(JRTPLIB_LIBS ${JRTPLIB_LIBS} ${JRTPLIB_LINK_LIBS}) +remove_empty(JRTPLIB_INCDIRS) +list(REMOVE_DUPLICATES JRTPLIB_INCDIRS) +remove_empty(JRTPLIB_LIBS) + +foreach(ARG ${JRTPLIB_LIBS}) + set(JRTPLIB_LIBS_CMAKECONFIG "${JRTPLIB_LIBS_CMAKECONFIG} \"${ARG}\"") +endforeach() +foreach(ARG ${JRTPLIB_INCDIRS}) + set(JRTPLIB_INCDIRS_CMAKECONFIG "${JRTPLIB_INCDIRS_CMAKECONFIG} \"${ARG}\"") +endforeach() + +configure_file("${PROJECT_SOURCE_DIR}/cmake/JRTPLIBConfig.cmake.in" "${PROJECT_BINARY_DIR}/cmake/JRTPLIBConfig.cmake") +install(FILES "${PROJECT_BINARY_DIR}/cmake/JRTPLIBConfig.cmake" DESTINATION ${LIBRARY_INSTALL_DIR}/cmake/JRTPLIB) + +if (UNIX) + foreach(ARG ${JRTPLIB_LIBS}) + set(JRTPLIB_LIBS_PKGCONFIG "${JRTPLIB_LIBS_PKGCONFIG} ${ARG}") + endforeach() + foreach(ARG ${JRTPLIB_INCDIRS}) + set(JRTPLIB_INCDIRS_PKGCONFIG "${JRTPLIB_INCDIRS_PKGCONFIG} -I${ARG}") + endforeach() + + configure_file(${PROJECT_SOURCE_DIR}/pkgconfig/jrtplib.pc.in ${PROJECT_BINARY_DIR}/pkgconfig/jrtplib.pc) + install(FILES ${PROJECT_BINARY_DIR}/pkgconfig/jrtplib.pc DESTINATION ${LIBRARY_INSTALL_DIR}/pkgconfig) +endif (UNIX) + + diff --git a/src/libs/jrtplib/ChangeLog b/src/libs/jrtplib/ChangeLog new file mode 100644 index 00000000..43661686 --- /dev/null +++ b/src/libs/jrtplib/ChangeLog @@ -0,0 +1,354 @@ + November 8, 2011 + + + JRTPLIB ChangeLog + + ----------- + + 3.9.1 (November 2011) + * Fixed a bug in the CMake configuration: was unable to handle + path names with spaces. + * Fixed bug in rtcpsdespacket.h: end namespace curly bracket + was in wrong place. + * In an MS-Windows environment you can now choose to build a + DLL instead of a static library. + + 3.9.0 (July 2011) + * Switched to CMake build system. + * Added the RTPByteAddress class, which can be used to describe + a host/port combination in a very general way. + * Added the RTPExternalTransmitter class which can be used if + one would like to use a transmission mechanism other than + the UDP based transmitters. + * Placed everything in namespace 'jrtplib'. + + 3.8.2 (February 2011) + * Fixed bug in RTPRandomRand48. The uint16_t version used a + & 0xff instead of & 0xffff. Thanks to Alexey Kumkov + (crazykum@ukr.net) for bringing this to my attention. + + 3.8.1 (October 2010) + * Initialization of the RTPRandomRandS class didn't work as + intended, causing the fall-back class RTPRandomRand48 always + being used on the Win32 platform. + + 3.8.0 (September 2010) + * Fixed bug in RTPSources implementation. An incorrect + 'GotoNextElement' call was replaced by a 'GotoPreviousElement' + call. + * Added functionality to send unknown RTCP packets. Patch + was supplied by Tom Harper (d.thomas.harper@gmail.com) + * Fixed bug in INF_GetEstimatedTimestampUnit (possibility of + division by zero). Thanks to Gilson Yi (gilson.yi@gmail.com) + for bringing this to my attention. + * Added some code to allow a specific SSRC to be used. + * Fixed bug in jitter calculation code. Thanks to Uwe Andersen + (uandersen@mayah.com) for bringing this to my attention. + * Added OnPollThreadStart and OnPollThreadStop to RTPSession. + Thanks to Daniele Barzotti (daniele.barzotti@eurocomtel.com) + for suggesting this. + * Added method to RTPSessionParams to force a specific CNAME. + Thanks to Lars Rohwedder (L.Rohwedder@mocotec.de) for the + suggestion. + * Removed old RTPRandom code and made RTPRandom an abstract + interface. Added a /dev/urandom implementation, a rand_s + implementation and a rand48 implementation. By default, + /dev/urandom and rand_s are tried, and rand48 is used as a + fall-back mechanism. + + 3.7.1 (May 2007) + * Fixed bug in the CurrentTime implementation (Win32/WinCE version). + Thanks to Dani Baeyens (dani@warp.es) and Eric Johnson + (EJohnson@pelco.com) for helping me solve this problem. + + 3.7.0 (January 2007) + * Send and receive socket buffer sizes can now be set in the + transmission parameters. Thanks to Dmitry Shandyba + (Dmitry.Shandyba@materialise.kiev.ua) for suggesting this. + * Changed a 'htons' call to a 'ntohs' call in ShouldAcceptData + in both the IPv4 and IPv6 transmitters. + * Fixed bug in RTPIPv6Destination. Thanks to Yi-Huan Chan + (yhchan@csie.nctu.edu.tw) and Franco Sinhori + (francosinhori@gmail.com) for bringing this to my attention. + + 3.6.0 (June 2006) + * Added a constructor to the RTCPCompoundPacket class to be able + to parse a compound packet out of a byte array (and not only + out of an RTPRawPacket instance). + * Added a method to RTPSession to send RTCP APP packets. Thanks + to Herman Bastiaens (herman.bastiaens@student.uhasselt.be) + for supplying the patch. + * Fixed Win32 rand_s bug. Thanks to Jeremy Noring + (jnoring@wilife.com) for supplying the patch. + * Removed the GetNumRTPPacketsSent and GetNumRTCPPacketsSent + functions in the transmitter. The counts were only used to + check if packets had been sent. Now, a flag in RTPSession is + used for this purpose. + * Added memory management support. + * Added a member function to RTPSession which allows passing an + RTPTransmitter instance. + * The instances in the destination lists now store struct + sockaddr variables. This makes sending data to each destination + more efficient. + + 3.5.2 (March 2006) + * Fixed bug in the random number functions which are used with + MS Visual Studio 2005. Thanks to Jun Ohasi (jun@jnb.odn.ne.jp) + for bringing the incorrect use of rand_s to my attention. + * Changed types like u_int32_t to types like uint32_t in the + documentation. + + 3.5.1 (March 2006) + * Fixed bug in RTCP scheduler. Due to -= operation on an RTPTime + instance, an incredibly large scheduling interval could be + calculated. + + 3.5.0 (March 2006) + * Now, the define RTP_SNPRINTF is used instead of snprintf, + _snprintf or _snprintf_s. + * In the RTPSources member function MultipleTimeouts, I neglected + to call the OnRemoveSource virtual function. Thanks to Adam Love + (alove@exceptionalinnovation.com) for bringing this to my attention. + * Added a OnSendRTCPCompoundPacket member function to the RTPSession + class. Useful for inspecting outgoing data. + * Modified the templates somewhat. Should cause less compiler problems + this way. Thanks tot Chris Hamilton (chamilton@cs.dal.ca) for + providing this solution. + * On Win32, if possible the functions rand_s and srand_s are now used. + + 3.4.0 (January 2006) + * Changed u_int32_t like types to uint32_t like types. Thanks to + Panagiotis Issaris (takis.issaris@uhasselt.be) for informing me + that these are C99 compliant. + * Changed sprintf functions to safer snprintf functions. Thanks to + Panagiotis Issaris (takis.issaris@uhasselt.be) for pointing this + out. + * Fixed bug in RTPSources (counters were not reset when the source + table was cleared). Thanks to Justin Matthews (jmatthewsr@yahoo.com) + for pointing this out. + * Fixed bug in RTPHashTable and RTPKeyHashTable. Thanks to + Tom Pijsel (tom.pijsel@twelvecubes.com) for bringing this to my + attention. + * Fixed bug in example3.cpp + + 3.3.0 (October 2005) + * Now it is possible to use a user-defined transmission component. + * Added GStreamer transmission component written by Philippe Khalaf + (burger@speedy.org). + + 3.2.1 (September 2005) + * The library wouldn't compile when probation support was disabled. + Thanks to Herman Bastiaens (herman.bastiaens@student.luc.ac.be) for + bringing this to my attention. + * When parsed from an RTPRawPacket, the receive time is also stored + in the RTPPacket instance. + + 3.2.0 (September 2005) + * Modified the routine in the RTPSession class which creates the + CNAME. Aparently on some systems, the 'getlogin' call returns + null. As an alternative, the library uses getenv("LOGNAME"). + Thanks to Mark Schiffmann (schima@neumann-elektronik.com) for + mentioning this to me. + * Added a OnBYEPacket method to the RTPSession class. Thanks to + Sigrid Thijs (sthijs@androme.be) for suggesting this. + * When probation support is enabled, a probation type can be selected + when the session is created. Supported types are "No probation", + "Use probation, but store packets" and "Use probation and discard + packets received in probation mode". Thanks to Chris Flerackers + (cflerackers@androme.be) for suggesting this feature. + * Added a parameter to WaitForIncomingData which indicates if + data is available when the function returns. Based on a suggestion + by Uwe Andersen (uandersen@mayah.com). + * Now using getifaddrs (if possible) to obtain our own IP addresses + (both in IPv4 version and IPv6 version). + * IPv6 code in Win32 version now works, but Visual Studio 2005 beta + has to be used. Thanks to Yi-Huan Chan (yhchan@csie.nctu.edu.tw) + for contributing some code. + * Added Win32 code for GetLocalIPList_Interfaces (both IPv4 and IPv6). + Thanks to Ivan Makushkin (camry@pisem.net) for pointing out how + this could be done. + * Added an option to use a SR packet when sending a BYE message. + Previously, a RR packet was always used, even if a session is + actually an active sender of data. Thanks to Uwe Andersen + (uandersen@mayah.com) for bringing this to my attention. + * Fixed bug in CNAME creation. + * Added WinCE support. Thanks to Maarten Daniels + (maarten.daniels@uhasselt.be) for supplying patches. + * Changed the CurrentTime implementation for the MS-Windows version. + Thanks to Maarten Daniels (maarten.daniels@uhasselt.be) and Chris + Flerackers (cflerackers@androme.be). + + 3.1.0 (October 2004) + * Added a callback OnPollThreadStep which is called at the end of + each loop of the poll thread + * Added the examples subdirectory to the package + * Fixed bug in rtpudpv4transmitter.cpp and rtpudpv6transmitter.cpp + which caused an infinite loop in LeaveAllMulticastGroups. Thanks + to Stijn Agten (stijn.agten@luc.ac.be) for pointing this out. + * Added a function GetTransmissionInfo to the RTPTransmitter class + (and subclasses). The function will return some additional + information about the transmitter, like local IP addresses and + socket descriptors. + + 3.0.2 (September 2004) + * Bugfix in rtpinternalsourcedata.cpp. The bug caused a crash when + duplicate packets were received. Thanks to Dominique Prunier + (dominique.prunier@micromedia-int.com) for informing me about + this. + + 3.0.1 (September 2004) + * Bugfix in rtpudpv4transmitter.cpp and rtpudpv6transmitter.cpp in + method SetReceiveMode + * Removed unused 'acceptownpackets' variable from + rtpudpv4transmitter.cpp and rtpudpv6transmitter.cpp + * Added a 'Dump' function (for debugging) in RTPUDPv4Transmitter + and RTPUDPv6Transmitter + * Now using JThread 1.1.0 + + 3.0.0 (August 2004) + * Complete rewrite of the library to provide better extensibility + and compliance with RFC 3550 + * Changes from the 2.x series: + - The 2.x series was created with the idea that the user + would only need to use the RTPSession class which meant + that the other classes were not very useful by themselves. + This version on the other hand, aims to provide many + useful components to aid the user in building RTP capable + applications. + - In this version, the code which is specific for the + underlying protocol by which RTP packets are transported, + is bundled in a class which inherits its interface from a + class called RTPTransmitter. This makes it easy for + different underlying protocols to be supported. Currently + there is support for UDP over IPv4 and UDP over IPv6. + + 2.9 (July 2004) + * Fixed bug in rtpsrclist.cpp. Thanks to Lukasz Bobowiec + (bobowiec@icslab.agh.edu.pl) + * Added function in RTPSourceData which returns the IP address + * Changed the random routines. Thanks to Jaap Keuter + (jaap.keuter@xs4all.nl) + * Made the shared library link against libstdc++ if possible. + Thanks to Anatoly Yakovenko (aeyakovenko@yahoo.com) for the + suggestion. + + 2.8 (January 2004) + * Added code to avoid a crash when receiving a malformed packet + * Fixed a memory leak (forgot to free memory when a malformed + packet was discarded) + * Changed debug routines for memory tracking + + 2.7b (November 2003) + * Only added --enable-fpic and --enable-fPIC to the configure script + + 2.7 (December 2002) + * Fixed important bug in rtpsources.cpp. This bug could cause + source information to get lost and could create a memory leak. + * Improved support for AIX in multicasting code (uses _AIX define). + Thanks to Klaus Matuschek (klaus.matuschek@infonova.com) + * Fixed possible buffer overrun in rtpcontributingsources.cpp + + 2.6 (January 2002) + * This release only contains some minor changes + * An 'install' target was added to the Makefile + * Some newlines were added add the end of certain files to avoid + compiler warnings + * Improved the jitter calculations somewhat + + 2.5 (December 2000) + * Added the possibility for the user to receive the raw RTCP packets. + * Fixed a bug in RTPContributingSources::CreateLocalCNAME(). In this + routine, the wrong length was passed to 'gethostname'. Thanks to + Sergey V.Shpital (sergey@page.net.ru) for bringing this to my + attention. + * Added a routine to set the Type of Service (ToS) field of the + outgoing packets (both RTP and RTCP). Thank to Philippe Cardon + (philippe.cardon@bt.com) for writing this code. + * Fixed a bug in the 'packets lost' calculation. Thank to Domingo + Cuevas Jr. (dcj@onebox.com) for helping me find this bug. + * Fixed a bug in the sequence number and jitter calculation: when + packets were received out of order, the sequence numbers and + jitter got messed up. Many thanks to Mohammad Tawsheeq Russool + (m.russool@eim.surrey.ac.uk) for helping me track down these + bugs. + * Added the possibility to set the timestamp unit for a particular + source. Previously, it was assumed that their timestamp unit + was the same as that of the local session. + + 2.4 (July 2000) + * Fixed a bug which caused all CSRS's except one to be incorrect. + * Added RTP header extension support (for both sending and receiving). + * Added some things (which should have been there already) to + RTPPacket. + * Adjusted the way in which the login name is retrieved on unix-like + systems. First I used a call to 'getlogin', but apparently this + function messes with timers through the use of 'alarm' calls (at + least on Linux). Now, I use a combination of 'geteuid' and + 'getpwuid' to obtain the necessary information. This does not + have that problem and is a lot cleaner since it doesn't depend + on login info (utmp) like 'getlogin'. Thanks to Roberto Jung Drebes + (drebes@inf.ufrgs.br) for pointing out the timer-problem. + * Made a LaTeX version of the manual and tutorial. Looks a lot nicer. + * Made it possible for the user to specify the local IP address + instead of letting the library figure it out itself. + * Fixed a bug which caused the 'fraction lost' in a RR packet to be + zero all the time. Thanks to Domingo Cuevas Jr. (dcj@onebox.com) for + pointing this out. + * Rewrote the RTCP packet sending routines. Now, they are much cleaner + and much more understandable :) + * Added better support for RTCP 'APP' packets. You can now both send + and receive APP packets. + + 2.3 (April 2000) + * The routine which creates and sends RTCP packets is now a bit faster. + * Added a sample that demonstrates the round-trip time function. + * Added functions to RTPSourceData: now the time when the last RR or + SR report was received can be retrieved. Also, the round trip time + can be retrieved: this is calculated as suggested in RFC 1889. + * Fixed a bug: the LSR value was not calculated correctly, now it is + (or should be ;-) ) + * Instead of specifying defines on the command line, they are now + defined in a config file. The unix version of this file is created + by the configure script. + * Added a member to RTPPacket which I had forgotten (the payload type, + which is obviously important :-) ). + * The library should now be able to work on a VxWorks platform. Thanks + to Dave Osborne (dosborne@argoneng.com) for his help. + * Added a tutorial and a small example application. + * Added some debugging routines (RTPDebug class) to check for memory + leaks. It turned out that there weren't any, so I'm pretty pleased ;) + * I've added a 'configure' script to make compilation a bit easier + across different platforms. Thanks to Qi Han (qh1c4@mizzou.edu) for + helping me to improve the support for the Solaris platform. Also + many thanks to Dario Maggiorini (dario@netdev.usr.dsi.unimi.it) for + helping me test the script on several platforms. + * Added multicasting support. + * A bug in rtpsourcedata.cpp was pointed out and fixed by Ramon Clout + (ramonc@win.tue.nl). Many thanks for this, Ramon. + + 2.2 (February 2000) + * Extra support for Sun and HP. Thanks to Henry Lau (hlau@nuera.com) + and Justin Matthews (jmatthews@nuera.com) for this information. + * The 'Poll' routine in rtpconnection.cpp has been altered. Now, the + routine should work even if there's that ioctl bug (previously, this + bug was only taken into consideration on a Windows platform). + Thanks to Justin Matthews (jmatthews@nuera.com) for his bugreport. + * Added some routines to RTPSession to get the local IP address and the + port number of the sending socket. + * 'install' rule added to the makefile. + * Added the define 'RTP_SOCKLENTYPE_UINT'. See README.TXT for more + information about this. + + 2.1 (December 1999) + * First release of jrtplib. + * Added member functions of RTPSession to retrieve the used sockets. + * Made the destination list faster by using a hash table. + + 2.0 (August 1999) + * First decent implementation of RTP. Entirely rewritten since 1.0. + + 1.0 (August 1999) + * First implementation of RTP. There were a lot of things that weren't + quite right and the organisation of the classes was quite nasty. + However, I learned a lot about RTP making this version, and so it + allowed me to make a good start on version 2.0. diff --git a/src/libs/jrtplib/Doxyfile b/src/libs/jrtplib/Doxyfile new file mode 100644 index 00000000..bb146946 --- /dev/null +++ b/src/libs/jrtplib/Doxyfile @@ -0,0 +1,1688 @@ +# Doxyfile 1.7.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = JRTPLIB + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 3.9.1 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description for a project that appears at the top of each page and should give viewer a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = NO + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = NO + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = YES + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even if there is only one candidate or it is obvious which candidate to choose by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src/ doc/ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = doc/ + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = documentation + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +#HTML_STYLESHEET = doc/jrtplib.css + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [0,1..20]) +# that doxygen will group on one line in the generated HTML documentation. +# Note that a value of 0 will completely suppress the enum values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = NO + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = RTP_SUPPORT_IPV4MULTICAST \ + RTP_SUPPORT_THREAD \ + RTP_SUPPORT_SDESPRIV \ + RTP_SUPPORT_PROBATION \ + RTP_SUPPORT_IPV6 \ + RTP_SUPPORT_IPV6MULTICAST \ + RTP_SUPPORT_SENDAPP \ + RTP_SUPPORT_MEMORYMANAGEMENT \ + RTP_SUPPORT_RTCPUNKNOWN + + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, svg, gif or svg. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/src/libs/jrtplib/LICENSE.MIT b/src/libs/jrtplib/LICENSE.MIT new file mode 100644 index 00000000..c55f0707 --- /dev/null +++ b/src/libs/jrtplib/LICENSE.MIT @@ -0,0 +1,19 @@ + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + diff --git a/src/libs/jrtplib/README.TXT b/src/libs/jrtplib/README.TXT new file mode 100644 index 00000000..2a8d6512 --- /dev/null +++ b/src/libs/jrtplib/README.TXT @@ -0,0 +1,22 @@ +======================================================================== + STATIC LIBRARY : jrtplib Project Overview +======================================================================== + +AppWizard has created this jrtplib library project for you. + +No source files were created as part of your project. + + +jrtplib.vcproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/src/libs/jrtplib/TODO b/src/libs/jrtplib/TODO new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/jrtplib/cmake/FindJThread.cmake b/src/libs/jrtplib/cmake/FindJThread.cmake new file mode 100644 index 00000000..466f06a7 --- /dev/null +++ b/src/libs/jrtplib/cmake/FindJThread.cmake @@ -0,0 +1,37 @@ + +find_package(JThread QUIET NO_MODULE) + +if (NOT JTHREAD_FOUND) # Config file could not be found + find_path(JTHREAD_INCLUDE_DIR jthread/jthread.h) + + set(JTHREAD_INCLUDE_DIRS ${JTHREAD_INCLUDE_DIR}) + + if (UNIX) + find_library(JTHREAD_LIBRARY jthread) + if (JTHREAD_LIBRARY) + set(JTHREAD_LIBRARIES ${JTHREAD_LIBRARY}) + find_library(JTHREAD_PTHREAD_LIB pthread) + if (JTHREAD_PTHREAD_LIB) + set(JTHREAD_LIBRARIES ${JTHREAD_LIBRARY} ${JTHREAD_PTHREAD_LIB}) + endif(JTHREAD_PTHREAD_LIB) + endif (JTHREAD_LIBRARY) + else (UNIX) + find_library(JTHREAD_LIB_RELEASE jthread) + find_library(JTHREAD_LIB_DEBUG jthread_d) + + if (JTHREAD_LIB_RELEASE OR JTHREAD_LIB_DEBUG) + set(JTHREAD_LIBRARIES "") + if (JTHREAD_LIB_RELEASE) + set(JTHREAD_LIBRARIES ${JTHREAD_LIBRARIES} optimized ${JTHREAD_LIB_RELEASE}) + endif (JTHREAD_LIB_RELEASE) + if (JTHREAD_LIB_DEBUG) + set(JTHREAD_LIBRARIES ${JTHREAD_LIBRARIES} debug ${JTHREAD_LIB_DEBUG}) + endif (JTHREAD_LIB_DEBUG) + endif (JTHREAD_LIB_RELEASE OR JTHREAD_LIB_DEBUG) + endif(UNIX) +endif (NOT JTHREAD_FOUND) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(JThread DEFAULT_MSG JTHREAD_INCLUDE_DIRS JTHREAD_LIBRARIES) + diff --git a/src/libs/jrtplib/cmake/JRTPLIBConfig.cmake.in b/src/libs/jrtplib/cmake/JRTPLIBConfig.cmake.in new file mode 100644 index 00000000..65914757 --- /dev/null +++ b/src/libs/jrtplib/cmake/JRTPLIBConfig.cmake.in @@ -0,0 +1,7 @@ + +set(JRTPLIB_FOUND 1) + +set(JRTPLIB_INCLUDE_DIRS ${JRTPLIB_INCDIRS_CMAKECONFIG}) + +set(JRTPLIB_LIBRARIES ${JRTPLIB_LIBS_CMAKECONFIG}) + diff --git a/src/libs/jrtplib/cmake/Macros.cmake b/src/libs/jrtplib/cmake/Macros.cmake new file mode 100644 index 00000000..3307a618 --- /dev/null +++ b/src/libs/jrtplib/cmake/Macros.cmake @@ -0,0 +1,104 @@ +macro(jrtplib_support_option DESCRIPTION OPTIONNAME DEFINENAME DEFAULTVALUE EMPTYVALUE) + option(${OPTIONNAME} ${DESCRIPTION} ${DEFAULTVALUE}) + if (${OPTIONNAME}) + set(${DEFINENAME} "#define ${DEFINENAME}") + else (${OPTIONNAME}) + set(${DEFINENAME} "${EMPTYVALUE}") + endif (${OPTIONNAME}) +endmacro(jrtplib_support_option) + +macro(jrtplib_include_test INCFILE DEFINENAME EMPTYVALUE) + check_include_file_cxx(${INCFILE} jrtplib_include_test_${DEFINENAME}) + if (jrtplib_include_test_${DEFINENAME}) + set(${DEFINENAME} "#define ${DEFINENAME}") + else (jrtplib_include_test_${DEFINENAME}) + set(${DEFINENAME} "${EMPTYVALUE}") + endif (jrtplib_include_test_${DEFINENAME}) +endmacro(jrtplib_include_test) + +macro (jrtplib_test_feature FILENAME DEFINENAME INVERT EMPTYVALUE) + if (NOT DEFINED ${FILENAME}_RESULT) + try_compile(${FILENAME}_RESULT "${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/tools/${FILENAME}.cpp" + OUTPUT_VARIABLE OUTVAR) + message(STATUS "Compiling ${FILENAME}.cpp") + set(BLA ${INVERT}) + if (NOT BLA) + if (${FILENAME}_RESULT) + set(${DEFINENAME} "#define ${DEFINENAME}" CACHE INTERNAL "setting ${DEFINENAME} in rtpconfig.h") + message(STATUS "Compiling ${FILENAME}.cpp worked - setting ${DEFINENAME} in rtpconfig.h") + else (${FILENAME}_RESULT) + set(${DEFINENAME} "${EMPTYVALUE}" CACHE INTERNAL "") + message(STATUS "Compiling ${FILENAME}.cpp failed - no action necessary") + endif (${FILENAME}_RESULT) + else (NOT BLA) + if (NOT ${FILENAME}_RESULT) + set(${DEFINENAME} "#define ${DEFINENAME}" CACHE INTERNAL "setting ${DEFINENAME} in rtpconfig.h") + message(STATUS "Compiling ${FILENAME}.cpp failed - setting ${DEFINENAME} in rtpconfig.h") + else (NOT ${FILENAME}_RESULT) + set(${DEFINENAME} "${EMPTYVALUE}" CACHE INTERNAL "") + message(STATUS "Compiling ${FILENAME}.cpp worked - no action necessary") + endif (NOT ${FILENAME}_RESULT) + endif (NOT BLA) + endif (NOT DEFINED ${FILENAME}_RESULT) +endmacro (jrtplib_test_feature) + +macro(save_paths VARNAME) + set (BLA "${ARGN}") + foreach(i IN LISTS BLA) + set (BLA2 "${i}") + if (BLA2) + list(APPEND ${VARNAME} "${i}") + endif (BLA2) + endforeach(i) + list(LENGTH ${VARNAME} BLA) + if (BLA GREATER 0) + list(REMOVE_DUPLICATES ${VARNAME}) + endif (BLA GREATER 0) +endmacro(save_paths) + +macro(remove_empty VARNAME) + set (remove_empty_NEWLIST "") + foreach(i IN LISTS ${VARNAME}) + set (BLA2 "${i}") + if (BLA2) + list(APPEND remove_empty_NEWLIST "${i}") + endif (BLA2) + endforeach(i) + set(${VARNAME} "${remove_empty_NEWLIST}") +endmacro(remove_empty) + +macro(apply_include_paths VARNAME) + set (BLA "${VARNAME}") + foreach(i IN LISTS BLA) + set (BLA2 "${i}") + if (BLA2) + include_directories("${i}") + endif (BLA2) + endforeach(i) +endmacro(apply_include_paths) + +macro(add_additional_stuff INCVAR LIBVAR) + set(ADDITIONAL_INCLUDE_DIRS "" CACHE STRING "Additional include directories") + if (UNIX AND NOT WIN32) + set(ADDITIONAL_LIBRARIES "" CACHE STRING "Additional libraries to link against") + else (UNIX AND NOT WIN32) + set(ADDITIONAL_GENERAL_LIBRARIES "" CACHE STRING "Additional libraries to link against in both debug and release modes") + set(ADDITIONAL_RELEASE_LIBRARIES "" CACHE STRING "Additional libraries to link against in release mode") + set(ADDITIONAL_DEBUG_LIBRARIES "" CACHE STRING "Additional libraries to link against in debug mode") + + set(ADDITIONAL_LIBRARIES "${ADDITIONAL_GENERAL_LIBRARIES}") + + foreach(l IN LISTS ADDITIONAL_RELEASE_LIBRARIES) + list(APPEND ADDITIONAL_LIBRARIES optimized) + list(APPEND ADDITIONAL_LIBRARIES "${l}") + endforeach(l) + foreach(l IN LISTS ADDITIONAL_DEBUG_LIBRARIES) + list(APPEND ADDITIONAL_LIBRARIES debug) + list(APPEND ADDITIONAL_LIBRARIES "${l}") + endforeach(l) + endif (UNIX AND NOT WIN32) + + save_paths(${INCVAR} "${ADDITIONAL_INCLUDE_DIRS}") + save_paths(${LIBVAR} "${ADDITIONAL_LIBRARIES}") +endmacro(add_additional_stuff) + diff --git a/src/libs/jrtplib/doc/jrtplib.h b/src/libs/jrtplib/doc/jrtplib.h new file mode 100644 index 00000000..2b60c910 --- /dev/null +++ b/src/libs/jrtplib/doc/jrtplib.h @@ -0,0 +1,351 @@ +/**\mainpage JRTPLIB + * + * \author Jori Liesenborgs + * \author Developed at the The Expertise Centre for Digital Media (EDM), a research + * institute of the Hasselt University + * + * \section ack Acknowledgment + * + * I would like thank the people at the Expertise Centre for Digital Media + * for giving me the opportunity to create this rewrite of the library. + * + * \section intro Introduction + * + * This document describes JRTPLIB, an object-oriented + * library written in C++ which aims to help developers in using the + * Real-time Transport Protocol (RTP) as described in RFC 3550. + * + * The library makes it possible for the user to send and receive data + * using RTP, without worrying about SSRC collisions, scheduling and + * transmitting RTCP data etc. The user only needs to provide the library + * with the payload data to be sent and the library gives the user access + * to incoming RTP and RTCP data. + * + * \subsection idea Design idea + * + * The library provides several classes which can be helpful in + * creating RTP applications. Most users will probably only need the + * RTPSession class for building an application. This class + * provides the necessary functions for sending RTP data and handles + * the RTCP part internally. + * + * \subsection changes Changes from version 2.x + * + * One of the most important changes is probably the fact that this + * version is based on RFC 3550 and the 2.x versions were based upon + * RFC 1889 which is now obsolete. + * + * Also, the 2.x series was created with the idea that the user would + * only need to use the RTPSession class which meant that the + * other classes were not very useful by themselves. This version on + * the other hand, aims to provide many useful components to aid the + * user in building RTP capable applications. + * + * In this version, the code which is specific for the underlying + * protocol by which RTP packets are transported, is bundled in + * a class which inherits its interface from a class called + * RTPTransmitter. This makes it easy for different underlying + * protocols to be supported. Currently there is support for UDP over + * IPv4 and UDP over IPv6. + * + * For applications such as a mixer or translator using the + * RTPSession class will not be a good solution. Other components can + * be used for this purpose: a transmission component, an SSRC table, + * an RTCP scheduler etc. Using these, it should be much easier to + * build all kinds of applications. + * \section copyright Copyright license + * + * The library code uses the following copyright license: + * + * \code + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * \endcode + * + * There are two reasons for using this license. First, since this is the + * license of the 2.x series, it only seemed natural that this rewrite + * would contain the same license. Second, since the RTP protocol is + * deliberately incomplete RTP profiles can, for example, define additional + * header fields. The best way to deal with this is to adapt the library + * code itself and that's why I like to keep the license as free as + * possible. + * + * \section starting Getting started with the RTPSession class + * + * All classes and functions are part of the \c jrtplib namespace, so to + * simplify the code a bit, we'll declare that we're using this namespace: + * \code + * using namespace jrtplib; + * \endcode + * To use RTP, you'll have to create an RTPSession object. The constructor + * accepts two parameter, an instance of an RTPRandom object, and an instance + * of an RTPMemoryManager object. For now, we'll keep it simple and use the + * default settings, so this is our code so far: + * + * \code + * RTPSession session; + * \endcode + * + * To actually create the session, you'll have to call the Create member + * function which takes three arguments: the first one is of type RTPSessionParams + * and specifies the general options for the session. One parameter of this class + * must be set explicitly, otherwise the session will not be created successfully. + * This parameter is the timestamp unit of the data you intend to send and + * can be calculated by dividing a certain time interval (in seconds) by the + * number of samples in that interval. So, assuming that we'll send 8000 Hz + * voice data, we can use this code: + * + * \code + * RTPSessionParams sessionparams; + * + * sessionparams.SetOwnTimestampUnit(1.0/8000.0); + * \endcode + * + * The other session parameters will probably depend on the actual RTP profile + * you intend to work with. + * + * The second argument of the Create function is a pointer to an RTPTransmissionParams + * instance and describes the parameters for the transmission component. The third + * parameter selects the type of transmission component which will be used. By default, + * an UDP over IPv4 transmitter is used, and for this particular transmitter, the + * transmission parameters should be of type RTPUDPv4TransmissionParams. Assuming + * that we want our RTP portbase to be 8000, we can do the following: + * + * \code + * RTPUDPv4TransmissionParams transparams; + * + * transparams.SetPortbase(8000); + * \endcode + * + * Now, we're ready to call the Create member function of RTPSession. The return + * value is stored in the integer \c status so we can check if something went + * wrong. If this value is negative, it indicates that some error occurred. + * A description of what this error code means can be retrieved by calling + * RTPGetErrorString: + * + * \code + * int status = session.Create(sessionparams,&transparams); + * if (status < 0) + * { + * std::cerr << RTPGetErrorString(status) << std::endl; + * exit(-1); + * } + * \endcode + * + * If the session was created with success, this is probably a good point + * to specify to which destinations RTP and RTCP data should be sent. This is + * done by a call to the RTPSession member function AddDestination. This + * function takes an argument of type RTPAddress. This is an abstract + * class and for the UDP over IPv4 transmitter the actual class to be + * used is RTPIPv4Address. Suppose that we want to send our data to a + * process running on the same host at port 9000, we can do the following: + * + * \code + * uint8_t localip[]={127,0,0,1}; + * RTPIPv4Address addr(localip,9000); + * + * status = session.AddDestination(addr); + * if (status < 0) + * { + * std::cerr << RTPGetErrorString(status) << std::endl; + * exit(-1); + * } + * \endcode + * + * If the library was compiled with JThread support, incoming data is + * processed in the background. If JThread support was not enabled at + * compile time or if you specified in the session parameters that no + * poll thread should be used, you'll have to call the RTPSession + * member function Poll regularly to process incoming data and to send + * RTCP data when necessary. For now, let's assume that we're working + * with the poll thread enabled. + * + * Lets suppose that for a duration of one minute, we want to send + * packets containing 20 ms (or 160 samples) of silence and we want + * to indicate when a packet from someone else has been received. Also + * suppose we have L8 data as defined in RFC 3551 and want to use + * payload type 96. First, we'll set some default values: + * + * \code + * session.SetDefaultPayloadType(96); + * session.SetDefaultMark(false); + * session.SetDefaultTimestampIncrement(160); + * \endcode + * + * Next, we'll create the buffer which contains 160 silence samples + * and create an RTPTime instance which indicates 20 ms or 0.020 seconds. + * We'll also store the current time so we'll know when one minute has + * passed. + * + * \code + * uint8_t silencebuffer[160]; + * + * for (int i = 0 ; i < 160 ; i++) + * silencebuffer[i] = 128; + * + * RTPTime delay(0.020); + * RTPTime starttime = RTPTime::CurrentTime(); + * \endcode + * + * Next, the main loop will be shown. In this loop, a packet containing + * 160 bytes of payload data will be sent. Then, data handling can + * take place but this part is described later in the text. Finally, + * we'll wait 20 ms and check if sixty seconds have passed: + * + * \code + * bool done = false; + * while (!done) + * { + * status = session.SendPacket(silencebuffer,160); + * if (status < 0) + * { + * std::cerr << RTPGetErrorString(status) << std::endl; + * exit(-1); + * } + * + * // + * // Inspect incoming data here + * // + * + * RTPTime::Wait(delay); + * + * RTPTime t = RTPTime::CurrentTime(); + * t -= starttime; + * if (t > RTPTime(60.0)) + * done = true; + * } + * \endcode + * + * Information about participants in the session, packet retrieval + * etc, has to be done between calls to the RTPSession member + * functions BeginDataAccess and EndDataAccess. This ensures that the + * background thread doesn't try to change the same data you're trying + * to access. We'll iterate over the participants using the + * GotoFirstSource and GotoNextSource member functions. Packets from + * the currently selected participant can be retrieved using the + * GetNextPacket member function which returns a pointer to an + * instance of the RTPPacket class. When you don't need the packet + * anymore, it has to be deleted. The processing of incoming data will + * then be as follows: + * + * \code + * session.BeginDataAccess(); + * if (session.GotoFirstSource()) + * { + * do + * { + * RTPPacket *packet; + * while ((packet = session.GetNextPacket()) != 0) + * { + * std::cout << "Got packet with extended sequence number " + * << packet->GetExtendedSequenceNumber() + * << " from SSRC " << packet->GetSSRC() + * << std::endl; + * session.DeletePacket(packet); + * } + * } while (session.GotoNextSource()); + * } + * session.EndDataAccess(); + * \endcode + * + * Information about the currently selected source can be obtained + * by using the GetCurrentSourceInfo member function of the RTPSession class. + * This function returns a pointer to an instance of RTPSourceData which + * contains all information about that source: sender reports from that + * source, receiver reports, SDES info etc. + * + * When the main loop is finished, we'll send a BYE packet to inform other + * participants of our departure and clean up the RTPSession class. Also, + * we want to wait at most 10 seconds for the BYE packet to be sent, + * otherwise we'll just leave the session without sending a BYE packet. + * + * \code + * delay = RTPTime(10.0); + * session.BYEDestroy(delay,"Time's up",9); + * \endcode + * + * The complete code of the program is given in \c example2.cpp. + * + * \section errors Error codes + * + * Unless specified otherwise, functions with a return type \c int + * will return a negative value when an error occurred and zero or a + * positive value upon success. A description of the error code can + * be obtained by using the RTPGetErrorString function, declared + * in rtperrors.h + * + * \section memory Memory management + * + * You can write you own memory manager by deriving a class from RTPMemoryManager. + * The following example shows a very basic implementation. + * + * \code + * class MyMemoryManager : public RTPMemoryManager + * { + * public: + * MyMemoryManager() { } + * ~MyMemoryManager() { } + * + * void *AllocateBuffer(size_t numbytes, int memtype) + * { + * return malloc(numbytes); + * } + * + * void FreeBuffer(void *p) + * { + * free(p); + * } + * }; + * \endcode + * + * In the constructor of RTPSession, you can specify that you would like to use + * this memory manager: + * + * \code + * MyMemoryManager mgr; + * RTPSession session(0, &mgr); + * \endcode + * + * Now, all memory allocation and deallocation will be done using the AllocateBuffer + * and FreeBuffer implementations of \c mgr. + * + * The second parameter of the RTPMemoryManager::AllocateBuffer member function + * indicates what the purpose is of this memory block. This allows you to handle + * different kinds of data in different ways. + * + * With the introduction of the memory management system, the RTPSession class was + * extended with member function RTPSession::DeletePacket and RTPSession::DeleteTransmissionInfo. + * These functions should be used to deallocate RTPPacket instances and RTPTransmissionInfo + * instances respectively. + * + * \section contact Contact + * + * If you have any questions, remarks or requests about the library or + * if you think you've discovered a bug, you can contact me at + * \c jori(\c dot)\c liesenborgs(\c at)\c gmail(\c dot)\c com + * + * The home page of the library is + * http://research.edm.uhasselt.be/jori/jrtplib/jrtplib.html + * + * There is also a mailing list for the library. To subscribe to the list, + * send an e-mail to \c jrtplib-subscribe(\c at)\c edm(\c dot)\c uhasselt(\c dot)\c be + * and you'll receive further instructions. + */ + diff --git a/src/libs/jrtplib/examples/.dummy b/src/libs/jrtplib/examples/.dummy new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/jrtplib/examples/CMakeLists.txt b/src/libs/jrtplib/examples/CMakeLists.txt new file mode 100644 index 00000000..6ebbd0fd --- /dev/null +++ b/src/libs/jrtplib/examples/CMakeLists.txt @@ -0,0 +1,12 @@ +apply_include_paths("${JRTPLIB_INTERNAL_INCLUDES}") +apply_include_paths("${JRTPLIB_EXTERNAL_INCLUDES}") + +foreach(IDX 1 2 3 4 5) + add_executable(example${IDX} example${IDX}.cpp) + if (UNIX OR JRTPLIB_COMPILE_STATIC) + target_link_libraries(example${IDX} jrtplib-static) + else () + target_link_libraries(example${IDX} jrtplib-shared) + endif () +endforeach(IDX) + diff --git a/src/libs/jrtplib/examples/example1.cpp b/src/libs/jrtplib/examples/example1.cpp new file mode 100644 index 00000000..b1a0eeb0 --- /dev/null +++ b/src/libs/jrtplib/examples/example1.cpp @@ -0,0 +1,150 @@ +/* + Here's a small IPv4 example: it asks for a portbase and a destination and + starts sending packets to that destination. +*/ + +#include "rtpsession.h" +#include "rtpudpv4transmitter.h" +#include "rtpipv4address.h" +#include "rtpsessionparams.h" +#include "rtperrors.h" +#ifndef WIN32 + #include + #include +#else + #include +#endif // WIN32 +#include +#include +#include +#include + +using namespace jrtplib; + +// +// This function checks if there was a RTP error. If so, it displays an error +// message and exists. +// + +void checkerror(int rtperr) +{ + if (rtperr < 0) + { + std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl; + exit(-1); + } +} + +// +// The main routine +// + +int main(void) +{ +#ifdef WIN32 + WSADATA dat; + WSAStartup(MAKEWORD(2,2),&dat); +#endif // WIN32 + + RTPSession sess; + uint16_t portbase,destport; + uint32_t destip; + std::string ipstr; + int status,i,num; + + // First, we'll ask for the necessary information + + std::cout << "Enter local portbase:" << std::endl; + std::cin >> portbase; + std::cout << std::endl; + + std::cout << "Enter the destination IP address" << std::endl; + std::cin >> ipstr; + destip = inet_addr(ipstr.c_str()); + if (destip == INADDR_NONE) + { + std::cerr << "Bad IP address specified" << std::endl; + return -1; + } + + // The inet_addr function returns a value in network byte order, but + // we need the IP address in host byte order, so we use a call to + // ntohl + destip = ntohl(destip); + + std::cout << "Enter the destination port" << std::endl; + std::cin >> destport; + + std::cout << std::endl; + std::cout << "Number of packets you wish to be sent:" << std::endl; + std::cin >> num; + + // Now, we'll create a RTP session, set the destination, send some + // packets and poll for incoming data. + + RTPUDPv4TransmissionParams transparams; + RTPSessionParams sessparams; + + // IMPORTANT: The local timestamp unit MUST be set, otherwise + // RTCP Sender Report info will be calculated wrong + // In this case, we'll be sending 10 samples each second, so we'll + // put the timestamp unit to (1.0/10.0) + sessparams.SetOwnTimestampUnit(1.0/10.0); + + sessparams.SetAcceptOwnPackets(true); + transparams.SetPortbase(portbase); + status = sess.Create(sessparams,&transparams); + checkerror(status); + + RTPIPv4Address addr(destip,destport); + + status = sess.AddDestination(addr); + checkerror(status); + + for (i = 1 ; i <= num ; i++) + { + printf("\nSending packet %d/%d\n",i,num); + + // send the packet + status = sess.SendPacket((void *)"1234567890",10,0,false,10); + checkerror(status); + + sess.BeginDataAccess(); + + // check incoming packets + if (sess.GotoFirstSourceWithData()) + { + do + { + RTPPacket *pack; + + while ((pack = sess.GetNextPacket()) != NULL) + { + // You can examine the data here + printf("Got packet !\n"); + + // we don't longer need the packet, so + // we'll delete it + sess.DeletePacket(pack); + } + } while (sess.GotoNextSourceWithData()); + } + + sess.EndDataAccess(); + +#ifndef RTP_SUPPORT_THREAD + status = sess.Poll(); + checkerror(status); +#endif // RTP_SUPPORT_THREAD + + RTPTime::Wait(RTPTime(1,0)); + } + + sess.BYEDestroy(RTPTime(10,0),0,0); + +#ifdef WIN32 + WSACleanup(); +#endif // WIN32 + return 0; +} + diff --git a/src/libs/jrtplib/examples/example2.cpp b/src/libs/jrtplib/examples/example2.cpp new file mode 100644 index 00000000..b8a7fbb5 --- /dev/null +++ b/src/libs/jrtplib/examples/example2.cpp @@ -0,0 +1,101 @@ +#include "rtpsession.h" +#include "rtpsessionparams.h" +#include "rtpudpv4transmitter.h" +#include "rtpipv4address.h" +#include "rtptimeutilities.h" +#include "rtppacket.h" +#include +#include + +using namespace jrtplib; + +int main(void) +{ +#ifdef WIN32 + WSADATA dat; + WSAStartup(MAKEWORD(2,2),&dat); +#endif // WIN32 + + RTPSession session; + + RTPSessionParams sessionparams; + sessionparams.SetOwnTimestampUnit(1.0/8000.0); + + RTPUDPv4TransmissionParams transparams; + transparams.SetPortbase(8000); + + int status = session.Create(sessionparams,&transparams); + if (status < 0) + { + std::cerr << RTPGetErrorString(status) << std::endl; + exit(-1); + } + + uint8_t localip[]={127,0,0,1}; + RTPIPv4Address addr(localip,9000); + + status = session.AddDestination(addr); + if (status < 0) + { + std::cerr << RTPGetErrorString(status) << std::endl; + exit(-1); + } + + session.SetDefaultPayloadType(96); + session.SetDefaultMark(false); + session.SetDefaultTimestampIncrement(160); + + uint8_t silencebuffer[160]; + for (int i = 0 ; i < 160 ; i++) + silencebuffer[i] = 128; + + RTPTime delay(0.020); + RTPTime starttime = RTPTime::CurrentTime(); + + bool done = false; + while (!done) + { + status = session.SendPacket(silencebuffer,160); + if (status < 0) + { + std::cerr << RTPGetErrorString(status) << std::endl; + exit(-1); + } + + session.BeginDataAccess(); + if (session.GotoFirstSource()) + { + do + { + RTPPacket *packet; + + while ((packet = session.GetNextPacket()) != 0) + { + std::cout << "Got packet with " + << "extended sequence number " + << packet->GetExtendedSequenceNumber() + << " from SSRC " << packet->GetSSRC() + << std::endl; + session.DeletePacket(packet); + } + } while (session.GotoNextSource()); + } + session.EndDataAccess(); + + RTPTime::Wait(delay); + + RTPTime t = RTPTime::CurrentTime(); + t -= starttime; + if (t > RTPTime(60.0)) + done = true; + } + + delay = RTPTime(10.0); + session.BYEDestroy(delay,"Time's up",9); + +#ifdef WIN32 + WSACleanup(); +#endif // WIN32 + return 0; +} + diff --git a/src/libs/jrtplib/examples/example3.cpp b/src/libs/jrtplib/examples/example3.cpp new file mode 100644 index 00000000..b5061edd --- /dev/null +++ b/src/libs/jrtplib/examples/example3.cpp @@ -0,0 +1,225 @@ +/* + This IPv4 example listens for incoming packets and automatically adds destinations + for new sources. +*/ + +#include "rtpsession.h" +#include "rtppacket.h" +#include "rtpudpv4transmitter.h" +#include "rtpipv4address.h" +#include "rtpsessionparams.h" +#include "rtperrors.h" +#ifndef WIN32 + #include + #include +#else + #include +#endif // WIN32 +#include "rtpsourcedata.h" +#include +#include +#include +#include + +using namespace jrtplib; + +// +// This function checks if there was a RTP error. If so, it displays an error +// message and exists. +// + +void checkerror(int rtperr) +{ + if (rtperr < 0) + { + std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl; + exit(-1); + } +} + +// +// The new class routine +// + +class MyRTPSession : public RTPSession +{ +protected: + void OnNewSource(RTPSourceData *dat) + { + if (dat->IsOwnSSRC()) + return; + + uint32_t ip; + uint16_t port; + + if (dat->GetRTPDataAddress() != 0) + { + const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTPDataAddress()); + ip = addr->GetIP(); + port = addr->GetPort(); + } + else if (dat->GetRTCPDataAddress() != 0) + { + const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTCPDataAddress()); + ip = addr->GetIP(); + port = addr->GetPort()-1; + } + else + return; + + RTPIPv4Address dest(ip,port); + AddDestination(dest); + + struct in_addr inaddr; + inaddr.s_addr = htonl(ip); + std::cout << "Adding destination " << std::string(inet_ntoa(inaddr)) << ":" << port << std::endl; + } + + void OnBYEPacket(RTPSourceData *dat) + { + if (dat->IsOwnSSRC()) + return; + + uint32_t ip; + uint16_t port; + + if (dat->GetRTPDataAddress() != 0) + { + const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTPDataAddress()); + ip = addr->GetIP(); + port = addr->GetPort(); + } + else if (dat->GetRTCPDataAddress() != 0) + { + const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTCPDataAddress()); + ip = addr->GetIP(); + port = addr->GetPort()-1; + } + else + return; + + RTPIPv4Address dest(ip,port); + DeleteDestination(dest); + + struct in_addr inaddr; + inaddr.s_addr = htonl(ip); + std::cout << "Deleting destination " << std::string(inet_ntoa(inaddr)) << ":" << port << std::endl; + } + + void OnRemoveSource(RTPSourceData *dat) + { + if (dat->IsOwnSSRC()) + return; + if (dat->ReceivedBYE()) + return; + + uint32_t ip; + uint16_t port; + + if (dat->GetRTPDataAddress() != 0) + { + const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTPDataAddress()); + ip = addr->GetIP(); + port = addr->GetPort(); + } + else if (dat->GetRTCPDataAddress() != 0) + { + const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTCPDataAddress()); + ip = addr->GetIP(); + port = addr->GetPort()-1; + } + else + return; + + RTPIPv4Address dest(ip,port); + DeleteDestination(dest); + + struct in_addr inaddr; + inaddr.s_addr = htonl(ip); + std::cout << "Deleting destination " << std::string(inet_ntoa(inaddr)) << ":" << port << std::endl; + } +}; + +// +// The main routine +// + +int main(void) +{ +#ifdef WIN32 + WSADATA dat; + WSAStartup(MAKEWORD(2,2),&dat); +#endif // WIN32 + + MyRTPSession sess; + uint16_t portbase; + std::string ipstr; + int status,i,num; + + // First, we'll ask for the necessary information + + std::cout << "Enter local portbase:" << std::endl; + std::cin >> portbase; + std::cout << std::endl; + + std::cout << std::endl; + std::cout << "Number of seconds you wish to wait:" << std::endl; + std::cin >> num; + + // Now, we'll create a RTP session, set the destination + // and poll for incoming data. + + RTPUDPv4TransmissionParams transparams; + RTPSessionParams sessparams; + + // IMPORTANT: The local timestamp unit MUST be set, otherwise + // RTCP Sender Report info will be calculated wrong + // In this case, we'll be just use 8000 samples per second. + sessparams.SetOwnTimestampUnit(1.0/8000.0); + + sessparams.SetAcceptOwnPackets(true); + transparams.SetPortbase(portbase); + status = sess.Create(sessparams,&transparams); + checkerror(status); + + for (i = 1 ; i <= num ; i++) + { + sess.BeginDataAccess(); + + // check incoming packets + if (sess.GotoFirstSourceWithData()) + { + do + { + RTPPacket *pack; + + while ((pack = sess.GetNextPacket()) != NULL) + { + // You can examine the data here + printf("Got packet !\n"); + + // we don't longer need the packet, so + // we'll delete it + sess.DeletePacket(pack); + } + } while (sess.GotoNextSourceWithData()); + } + + sess.EndDataAccess(); + +#ifndef RTP_SUPPORT_THREAD + status = sess.Poll(); + checkerror(status); +#endif // RTP_SUPPORT_THREAD + + RTPTime::Wait(RTPTime(1,0)); + } + + sess.BYEDestroy(RTPTime(10,0),0,0); + +#ifdef WIN32 + WSACleanup(); +#endif // WIN32 + return 0; +} + diff --git a/src/libs/jrtplib/examples/example4.cpp b/src/libs/jrtplib/examples/example4.cpp new file mode 100644 index 00000000..a078270c --- /dev/null +++ b/src/libs/jrtplib/examples/example4.cpp @@ -0,0 +1,146 @@ +/* + This IPv4 example uses the background thread itself to process all packets. + You can use example one to send data to the session that's created in this + example. +*/ + +#include "rtpsession.h" +#include "rtppacket.h" +#include "rtpudpv4transmitter.h" +#include "rtpipv4address.h" +#include "rtpsessionparams.h" +#include "rtperrors.h" +#ifndef WIN32 + #include + #include +#else + #include +#endif // WIN32 +#include "rtpsourcedata.h" +#include +#include +#include +#include + +using namespace jrtplib; + +#ifdef RTP_SUPPORT_THREAD + +// +// This function checks if there was a RTP error. If so, it displays an error +// message and exists. +// + +void checkerror(int rtperr) +{ + if (rtperr < 0) + { + std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl; + exit(-1); + } +} + +// +// The new class routine +// + +class MyRTPSession : public RTPSession +{ +protected: + void OnPollThreadStep(); + void ProcessRTPPacket(const RTPSourceData &srcdat,const RTPPacket &rtppack); +}; + +void MyRTPSession::OnPollThreadStep() +{ + BeginDataAccess(); + + // check incoming packets + if (GotoFirstSourceWithData()) + { + do + { + RTPPacket *pack; + RTPSourceData *srcdat; + + srcdat = GetCurrentSourceInfo(); + + while ((pack = GetNextPacket()) != NULL) + { + ProcessRTPPacket(*srcdat,*pack); + DeletePacket(pack); + } + } while (GotoNextSourceWithData()); + } + + EndDataAccess(); +} + +void MyRTPSession::ProcessRTPPacket(const RTPSourceData &srcdat,const RTPPacket &rtppack) +{ + // You can inspect the packet and the source's info here + std::cout << "Got packet " << rtppack.GetExtendedSequenceNumber() << " from SSRC " << srcdat.GetSSRC() << std::endl; +} + +// +// The main routine +// + +int main(void) +{ +#ifdef WIN32 + WSADATA dat; + WSAStartup(MAKEWORD(2,2),&dat); +#endif // WIN32 + + MyRTPSession sess; + uint16_t portbase; + std::string ipstr; + int status,num; + + // First, we'll ask for the necessary information + + std::cout << "Enter local portbase:" << std::endl; + std::cin >> portbase; + std::cout << std::endl; + + std::cout << std::endl; + std::cout << "Number of seconds you wish to wait:" << std::endl; + std::cin >> num; + + // Now, we'll create a RTP session, set the destination + // and poll for incoming data. + + RTPUDPv4TransmissionParams transparams; + RTPSessionParams sessparams; + + // IMPORTANT: The local timestamp unit MUST be set, otherwise + // RTCP Sender Report info will be calculated wrong + // In this case, we'll be just use 8000 samples per second. + sessparams.SetOwnTimestampUnit(1.0/8000.0); + + transparams.SetPortbase(portbase); + status = sess.Create(sessparams,&transparams); + checkerror(status); + + // Wait a number of seconds + RTPTime::Wait(RTPTime(num,0)); + + sess.BYEDestroy(RTPTime(10,0),0,0); + +#ifdef WIN32 + WSACleanup(); +#endif // WIN32 + return 0; +} + +#else + +int main(void) +{ + std::cerr << "Thread support is required for this example" << std::endl; + return 0; +} + +#endif // RTP_SUPPORT_THREAD + diff --git a/src/libs/jrtplib/examples/example5.cpp b/src/libs/jrtplib/examples/example5.cpp new file mode 100644 index 00000000..d0097720 --- /dev/null +++ b/src/libs/jrtplib/examples/example5.cpp @@ -0,0 +1,227 @@ +/* + This is a modified version of example1.cpp to illustrate the use of a memory + manager. +*/ + +#include "rtpsession.h" +#include "rtppacket.h" +#include "rtpudpv4transmitter.h" +#include "rtpipv4address.h" +#include "rtpsessionparams.h" +#include "rtperrors.h" +#include "rtpmemorymanager.h" +#ifndef WIN32 + #include + #include +#else + #include +#endif // WIN32 +#include +#include +#include +#include + +using namespace jrtplib; + +// +// This function checks if there was a RTP error. If so, it displays an error +// message and exists. +// + +void checkerror(int rtperr) +{ + if (rtperr < 0) + { + std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl; + exit(-1); + } +} + +// +// The main routine +// + +#ifdef RTP_SUPPORT_THREAD + +using namespace jthread; + +class MyMemoryManager : public RTPMemoryManager +{ +public: + MyMemoryManager() + { + mutex.Init(); + alloccount = 0; + freecount = 0; + } + ~MyMemoryManager() + { + std::cout << "alloc: " << alloccount << " free: " << freecount << std::endl; + } + void *AllocateBuffer(size_t numbytes, int memtype) + { + mutex.Lock(); + void *buf = malloc(numbytes); + std::cout << "Allocated " << numbytes << " bytes at location " << buf << " (memtype = " << memtype << ")" << std::endl; + alloccount++; + mutex.Unlock(); + return buf; + } + + void FreeBuffer(void *p) + { + mutex.Lock(); + std::cout << "Freeing block " << p << std::endl; + freecount++; + free(p); + mutex.Unlock(); + } +private: + int alloccount,freecount; + JMutex mutex; +}; + +#else + +class MyMemoryManager : public RTPMemoryManager +{ +public: + MyMemoryManager() + { + alloccount = 0; + freecount = 0; + } + ~MyMemoryManager() + { + std::cout << "alloc: " << alloccount << " free: " << freecount << std::endl; + } + void *AllocateBuffer(size_t numbytes, int memtype) + { + void *buf = malloc(numbytes); + std::cout << "Allocated " << numbytes << " bytes at location " << buf << " (memtype = " << memtype << ")" << std::endl; + alloccount++; + return buf; + } + + void FreeBuffer(void *p) + { + std::cout << "Freeing block " << p << std::endl; + freecount++; + free(p); + } +private: + int alloccount,freecount; +}; + +#endif // RTP_SUPPORT_THREAD + +int main(void) +{ +#ifdef WIN32 + WSADATA dat; + WSAStartup(MAKEWORD(2,2),&dat); +#endif // WIN32 + + MyMemoryManager mgr; + RTPSession sess(0, &mgr); + uint16_t portbase,destport; + uint32_t destip; + std::string ipstr; + int status,i,num; + + // First, we'll ask for the necessary information + + std::cout << "Enter local portbase:" << std::endl; + std::cin >> portbase; + std::cout << std::endl; + + std::cout << "Enter the destination IP address" << std::endl; + std::cin >> ipstr; + destip = inet_addr(ipstr.c_str()); + if (destip == INADDR_NONE) + { + std::cerr << "Bad IP address specified" << std::endl; + return -1; + } + + // The inet_addr function returns a value in network byte order, but + // we need the IP address in host byte order, so we use a call to + // ntohl + destip = ntohl(destip); + + std::cout << "Enter the destination port" << std::endl; + std::cin >> destport; + + std::cout << std::endl; + std::cout << "Number of packets you wish to be sent:" << std::endl; + std::cin >> num; + + // Now, we'll create a RTP session, set the destination, send some + // packets and poll for incoming data. + + RTPUDPv4TransmissionParams transparams; + RTPSessionParams sessparams; + + // IMPORTANT: The local timestamp unit MUST be set, otherwise + // RTCP Sender Report info will be calculated wrong + // In this case, we'll be sending 10 samples each second, so we'll + // put the timestamp unit to (1.0/10.0) + sessparams.SetOwnTimestampUnit(1.0/10.0); + + sessparams.SetAcceptOwnPackets(true); + transparams.SetPortbase(portbase); + status = sess.Create(sessparams,&transparams); + checkerror(status); + + RTPIPv4Address addr(destip,destport); + + status = sess.AddDestination(addr); + checkerror(status); + + for (i = 1 ; i <= num ; i++) + { + printf("\nSending packet %d/%d\n",i,num); + + // send the packet + status = sess.SendPacket((void *)"1234567890",10,0,false,10); + checkerror(status); + + sess.BeginDataAccess(); + + // check incoming packets + if (sess.GotoFirstSourceWithData()) + { + do + { + RTPPacket *pack; + + while ((pack = sess.GetNextPacket()) != NULL) + { + // You can examine the data here + printf("Got packet !\n"); + + // we don't longer need the packet, so + // we'll delete it + sess.DeletePacket(pack); + } + } while (sess.GotoNextSourceWithData()); + } + + sess.EndDataAccess(); + +#ifndef RTP_SUPPORT_THREAD + status = sess.Poll(); + checkerror(status); +#endif // RTP_SUPPORT_THREAD + + RTPTime::Wait(RTPTime(1,0)); + } + + sess.BYEDestroy(RTPTime(10,0),0,0); + +#ifdef WIN32 + WSACleanup(); +#endif // WIN32 + return 0; +} + diff --git a/src/libs/jrtplib/jrtplib.vcproj b/src/libs/jrtplib/jrtplib.vcproj new file mode 100644 index 00000000..916a21bf --- /dev/null +++ b/src/libs/jrtplib/jrtplib.vcproj @@ -0,0 +1,488 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/jrtplib/jrtplib.vcxproj b/src/libs/jrtplib/jrtplib.vcxproj new file mode 100644 index 00000000..1d61e18e --- /dev/null +++ b/src/libs/jrtplib/jrtplib.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {D39837A7-419F-4751-A090-429F4D3B0038} + jrtplib + Win32Proj + + + + StaticLibrary + v120_xp + Unicode + true + + + StaticLibrary + v120_xp + Unicode + + + + + + + + + + + + + <_ProjectFileVersion>12.0.21005.1 + + + $(Configuration)\ + $(Configuration)\ + + + $(Configuration)\ + $(Configuration)\ + + + + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + false + + Level3 + EditAndContinue + + + + + MaxSpeed + true + false + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDLL + true + false + + Level3 + ProgramDatabase + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libs/jrtplib/jrtplib.vcxproj.user b/src/libs/jrtplib/jrtplib.vcxproj.user new file mode 100644 index 00000000..abe8dd89 --- /dev/null +++ b/src/libs/jrtplib/jrtplib.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/libs/jrtplib/pkgconfig/jrtplib.pc.in b/src/libs/jrtplib/pkgconfig/jrtplib.pc.in new file mode 100644 index 00000000..8f2d6ce6 --- /dev/null +++ b/src/libs/jrtplib/pkgconfig/jrtplib.pc.in @@ -0,0 +1,6 @@ +Name: Jrtplib +Description: A full featured RTP library +Requires: +Version: ${VERSION} +Libs: ${JRTPLIB_LIBS_PKGCONFIG} +Cflags: ${JRTPLIB_INCDIRS_PKGCONFIG} diff --git a/src/libs/jrtplib/src/CMakeLists.txt b/src/libs/jrtplib/src/CMakeLists.txt new file mode 100644 index 00000000..f1a07338 --- /dev/null +++ b/src/libs/jrtplib/src/CMakeLists.txt @@ -0,0 +1,93 @@ +add_definitions(-DJRTPLIB_COMPILING) + +set (JRTPLIB_HEADERS + rtcpapppacket.h + rtcpbyepacket.h + rtcpcompoundpacket.h + rtcpcompoundpacketbuilder.h + rtcppacket.h + rtcppacketbuilder.h + rtcprrpacket.h + rtcpscheduler.h + rtcpsdesinfo.h + rtcpsdespacket.h + rtcpsrpacket.h + rtcpunknownpacket.h + rtpaddress.h + rtpcollisionlist.h + ${PROJECT_BINARY_DIR}/src/rtpconfig.h + rtpdebug.h + rtpdefines.h + rtperrors.h + rtphashtable.h + rtpinternalsourcedata.h + rtpipv4address.h + rtpipv4destination.h + rtpipv6address.h + rtpipv6destination.h + rtpkeyhashtable.h + rtplibraryversion.h + rtpmemorymanager.h + rtpmemoryobject.h + rtppacket.h + rtppacketbuilder.h + rtppollthread.h + rtprandom.h + rtprandomrand48.h + rtprandomrands.h + rtprandomurandom.h + rtprawpacket.h + rtpsession.h + rtpsessionparams.h + rtpsessionsources.h + rtpsourcedata.h + rtpsources.h + rtpstructs.h + rtptimeutilities.h + rtptransmitter.h + rtptypes_win.h + ${PROJECT_BINARY_DIR}/src/rtptypes.h + rtpudpv4transmitter.h + rtpudpv6transmitter.h + rtpbyteaddress.h + rtpexternaltransmitter.h) + +set(JRTPLIB_SOURCES + rtcpapppacket.cpp + rtcpbyepacket.cpp + rtcpcompoundpacket.cpp + rtcpcompoundpacketbuilder.cpp + rtcppacket.cpp + rtcppacketbuilder.cpp + rtcprrpacket.cpp + rtcpscheduler.cpp + rtcpsdesinfo.cpp + rtcpsdespacket.cpp + rtcpsrpacket.cpp + rtpcollisionlist.cpp + rtpdebug.cpp + rtperrors.cpp + rtpinternalsourcedata.cpp + rtpipv4address.cpp + rtpipv6address.cpp + rtplibraryversion.cpp + rtppacket.cpp + rtppacketbuilder.cpp + rtppollthread.cpp + rtprandom.cpp + rtprandomrand48.cpp + rtprandomrands.cpp + rtprandomurandom.cpp + rtpsession.cpp + rtpsessionparams.cpp + rtpsessionsources.cpp + rtpsourcedata.cpp + rtpsources.cpp + rtptimeutilities.cpp + rtpudpv4transmitter.cpp + rtpudpv6transmitter.cpp + rtpbyteaddress.cpp + rtpexternaltransmitter.cpp) + +add_library(jrtplib STATIC ${JRTPLIB_SOURCES}) + diff --git a/src/libs/jrtplib/src/errcodecommand b/src/libs/jrtplib/src/errcodecommand new file mode 100644 index 00000000..d944d2dc --- /dev/null +++ b/src/libs/jrtplib/src/errcodecommand @@ -0,0 +1,2 @@ +#!/bin/bash +for i in `cat rtperrors.h | cut -f 2 -d " " | cut -f 1 |grep -e "^ERR"`; do echo $i ; BLA=`grep $i *.cpp *.h|cut -f 1 -d ":"|sort|uniq`; if [ "BLA$BLA" != BLA ] ; then for j in $BLA ; do if [ $j != "rtperrors.h" ] ; then echo -e "\t$j" ; fi ; done ; fi ;done diff --git a/src/libs/jrtplib/src/extratransmitters/rtpfaketransmitter.cpp b/src/libs/jrtplib/src/extratransmitters/rtpfaketransmitter.cpp new file mode 100644 index 00000000..b35c5017 --- /dev/null +++ b/src/libs/jrtplib/src/extratransmitters/rtpfaketransmitter.cpp @@ -0,0 +1,1726 @@ +/* + + This class allows for jrtp to process packets without sending them out + anywhere. + The incoming messages are handed in to jrtp through the TransmissionParams + and can be retreived from jrtp through the normal polling mecanisms. + The outgoing RTP/RTCP packets are given to jrtp through the normal + session->SendPacket() and those packets are handed back out to the + client through a callback function (packet_ready_cb). + + example usage : Allows for integration of RTP into gstreamer. + + THIS HAS NOT BEEN TESTED WITH THREADS SO DON'T TRY + + Copyright (c) 2005 Philippe Khalaf + + This file is a part of JRTPLIB + Copyright (c) 1999-2004 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the "Expertisecentrum Digitale Media" + (http://www.edm.luc.ac.be), a research center of the "Limburgs Universitair + Centrum" (http://www.luc.ac.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpfaketransmitter.h" + +#include "rtprawpacket.h" +#include "rtpipv4address.h" +#include "rtptimeutilities.h" +#include + +#include +#include +#include +#include +#include + +#ifdef RTP_HAVE_SYS_FILIO +#include +#endif // RTP_HAVE_SYS_FILIO + +#define RTPIOCTL ioctl + +#ifdef RTPDEBUG + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +#define RTPFAKETRANS_MAXPACKSIZE 65535 +#define RTPFAKETRANS_IFREQBUFSIZE 8192 + +//#define RTPFAKETRANS_IS_MCASTADDR(x) (((x)&0xF0000000) == 0xE0000000) + +/*#define RTPFAKETRANS_MCASTMEMBERSHIP(socket,type,mcastip,status) {\ + struct ip_mreq mreq;\ + \ + mreq.imr_multiaddr.s_addr = htonl(mcastip);\ + mreq.imr_interface.s_addr = htonl(bindIP);\ + status = setsockopt(socket,IPPROTO_IP,type,(const char *)&mreq,sizeof(struct ip_mreq));\ + }*/ +#ifdef RTP_SUPPORT_THREAD + #define MAINMUTEX_LOCK { if (threadsafe) mainmutex.Lock(); } + #define MAINMUTEX_UNLOCK { if (threadsafe) mainmutex.Unlock(); } + #define WAITMUTEX_LOCK { if (threadsafe) waitmutex.Lock(); } + #define WAITMUTEX_UNLOCK { if (threadsafe) waitmutex.Unlock(); } +#else + #define MAINMUTEX_LOCK + #define MAINMUTEX_UNLOCK + #define WAITMUTEX_LOCK + #define WAITMUTEX_UNLOCK +#endif // RTP_SUPPORT_THREAD + +namespace jrtplib +{ + +RTPFakeTransmitter::RTPFakeTransmitter(RTPMemoryManager *mgr ) : RTPTransmitter(mgr), destinations(mgr,RTPMEM_TYPE_CLASS_DESTINATIONLISTHASHELEMENT),acceptignoreinfo(mgr,RTPMEM_TYPE_CLASS_ACCEPTIGNOREHASHELEMENT) +{ + created = false; + init = false; +} + +RTPFakeTransmitter::~RTPFakeTransmitter() +{ + Destroy(); +} + +int RTPFakeTransmitter::Init(bool tsafe) +{ + if (init) + return ERR_RTP_FAKETRANS_ALREADYINIT; + + // bomb out if trying to use threads + if (tsafe) + return ERR_RTP_NOTHREADSUPPORT; + +#ifdef RTP_SUPPORT_THREAD + threadsafe = tsafe; + if (threadsafe) + { + int status; + + status = mainmutex.Init(); + if (status < 0) + return ERR_RTP_FAKETRANS_CANTINITMUTEX; + status = waitmutex.Init(); + if (status < 0) + return ERR_RTP_FAKETRANS_CANTINITMUTEX; + } +#else + if (tsafe) + return ERR_RTP_NOTHREADSUPPORT; +#endif // RTP_SUPPORT_THREAD + + init = true; + return 0; +} + +int RTPFakeTransmitter::Create(size_t maximumpacketsize,const RTPTransmissionParams *transparams) +{ +// struct sockaddr_in addr; +// int status; + + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_ALREADYCREATED; + } + + // Obtain transmission parameters + + if (transparams == 0) + params = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) RTPFakeTransmissionParams; + else + { + if (transparams->GetTransmissionProtocol() != RTPTransmitter::UserDefinedProto) + return ERR_RTP_FAKETRANS_ILLEGALPARAMETERS; + params = (RTPFakeTransmissionParams *)transparams; + } + + // Check if portbase is even + //if (params->GetPortbase()%2 != 0) + //{ + // MAINMUTEX_UNLOCK + // return ERR_RTP_FAKETRANS_PORTBASENOTEVEN; + //} + + // Try to obtain local IP addresses + + localIPs = params->GetLocalIPList(); + if (localIPs.empty()) // User did not provide list of local IP addresses, calculate them + { + int status; + + if ((status = CreateLocalIPList()) < 0) + { + MAINMUTEX_UNLOCK + return status; + } +#ifdef RTPDEBUG + std::cout << "Found these local IP addresses:" << std::endl; + + std::list::const_iterator it; + + for (it = localIPs.begin() ; it != localIPs.end() ; it++) + { + RTPIPv4Address a(*it); + + std::cout << a.GetAddressString() << std::endl; + } +#endif // RTPDEBUG + } + +//#ifdef RTP_SUPPORT_IPV4MULTICAST +// if (SetMulticastTTL(params->GetMulticastTTL())) +// supportsmulticasting = true; +// else +// supportsmulticasting = false; +//#else // no multicast support enabled + supportsmulticasting = false; +//#endif // RTP_SUPPORT_IPV4MULTICAST + + if (maximumpacketsize > RTPFAKETRANS_MAXPACKSIZE) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_SPECIFIEDSIZETOOBIG; + } + + maxpacksize = maximumpacketsize; + portbase = params->GetPortbase(); + multicastTTL = params->GetMulticastTTL(); + receivemode = RTPTransmitter::AcceptAll; + + localhostname = 0; + localhostnamelength = 0; + + waitingfordata = false; + created = true; + + MAINMUTEX_UNLOCK + return 0; +} + +void RTPFakeTransmitter::Destroy() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK; + return; + } + + if (localhostname) + { + RTPDeleteByteArray(localhostname,GetMemoryManager()); + localhostname = 0; + localhostnamelength = 0; + } + + destinations.Clear(); +#ifdef RTP_SUPPORT_IPV4MULTICAST +// multicastgroups.Clear(); +#endif // RTP_SUPPORT_IPV4MULTICAST + FlushPackets(); + ClearAcceptIgnoreInfo(); + localIPs.clear(); + created = false; + RTPDelete(params,GetMemoryManager()); + + MAINMUTEX_UNLOCK +} + +RTPTransmissionInfo *RTPFakeTransmitter::GetTransmissionInfo() +{ + if (!init) + return 0; + + MAINMUTEX_LOCK + RTPTransmissionInfo *tinf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPTRANSMISSIONINFO) RTPFakeTransmissionInfo(localIPs, params); + MAINMUTEX_UNLOCK + return tinf; +} + +void RTPFakeTransmitter::DeleteTransmissionInfo(RTPTransmissionInfo *inf) +{ + if (!init) + return; + RTPDelete(inf,GetMemoryManager()); +} + +int RTPFakeTransmitter::GetLocalHostName(uint8_t *buffer,size_t *bufferlength) +{ + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + + if (localhostname == 0) + { + if (localIPs.empty()) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOLOCALIPS; + } + + std::list::const_iterator it; + std::list hostnames; + + for (it = localIPs.begin() ; it != localIPs.end() ; it++) + { + struct hostent *he; + uint8_t addr[4]; + uint32_t ip = (*it); + + addr[0] = (uint8_t)((ip>>24)&0xFF); + addr[1] = (uint8_t)((ip>>16)&0xFF); + addr[2] = (uint8_t)((ip>>8)&0xFF); + addr[3] = (uint8_t)(ip&0xFF); + he = gethostbyaddr((char *)addr,4,AF_INET); + if (he != 0) + { + std::string hname = std::string(he->h_name); + hostnames.push_back(hname); + } + } + + bool found = false; + + if (!hostnames.empty()) // try to select the most appropriate hostname + { + std::list::const_iterator it; + + for (it = hostnames.begin() ; !found && it != hostnames.end() ; it++) + { + if ((*it).find('.') != std::string::npos) + { + found = true; + localhostnamelength = (*it).length(); + localhostname = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) uint8_t [localhostnamelength+1]; + if (localhostname == 0) + { + MAINMUTEX_UNLOCK + return ERR_RTP_OUTOFMEM; + } + memcpy(localhostname,(*it).c_str(),localhostnamelength); + localhostname[localhostnamelength] = 0; + } + } + } + + if (!found) // use an IP address + { + uint32_t ip; + int len; + char str[16]; + + it = localIPs.begin(); + ip = (*it); + + snprintf(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF)); + len = strlen(str); + + localhostnamelength = len; + localhostname = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) uint8_t [localhostnamelength + 1]; + if (localhostname == 0) + { + MAINMUTEX_UNLOCK + return ERR_RTP_OUTOFMEM; + } + memcpy(localhostname,str,localhostnamelength); + localhostname[localhostnamelength] = 0; + } + } + + if ((*bufferlength) < localhostnamelength) + { + *bufferlength = localhostnamelength; // tell the application the required size of the buffer + MAINMUTEX_UNLOCK + return ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL; + } + + memcpy(buffer,localhostname,localhostnamelength); + *bufferlength = localhostnamelength; + + MAINMUTEX_UNLOCK + return 0; +} + +bool RTPFakeTransmitter::ComesFromThisTransmitter(const RTPAddress *addr) +{ + if (!init) + return false; + + if (addr == 0) + return false; + + MAINMUTEX_LOCK + + bool v; + + if (created && addr->GetAddressType() == RTPAddress::IPv4Address) + { + const RTPIPv4Address *addr2 = (const RTPIPv4Address *)addr; + bool found = false; + std::list::const_iterator it; + + it = localIPs.begin(); + while (!found && it != localIPs.end()) + { + if (addr2->GetIP() == *it) + found = true; + else + ++it; + } + + if (!found) + v = false; + else + { + if (addr2->GetPort() == params->GetPortbase()) // check for RTP port + v = true; + else if (addr2->GetPort() == (params->GetPortbase()+1)) // check for RTCP port + v = true; + else + v = false; + } + } + else + v = false; + + MAINMUTEX_UNLOCK + return v; +} + +int RTPFakeTransmitter::Poll() +{ + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + int status; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + status = FakePoll(); // poll RTP socket + params->SetCurrentData(NULL); + MAINMUTEX_UNLOCK + return status; +} + +int RTPFakeTransmitter::WaitForIncomingData(const RTPTime &delay,bool *dataavailable) +{ +/* if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + + fd_set fdset; + struct timeval tv; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (waitingfordata) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_ALREADYWAITING; + } + + FD_ZERO(&fdset); + FD_SET(rtpsock,&fdset); + FD_SET(rtcpsock,&fdset); + FD_SET(abortdesc[0],&fdset); + tv.tv_sec = delay.GetSeconds(); + tv.tv_usec = delay.GetMicroSeconds(); + + waitingfordata = true; + + WAITMUTEX_LOCK + MAINMUTEX_UNLOCK + + if (select(FD_SETSIZE,&fdset,0,0,&tv) < 0) + { + MAINMUTEX_LOCK + waitingfordata = false; + MAINMUTEX_UNLOCK + WAITMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_ERRORINSELECT; + } + + MAINMUTEX_LOCK + waitingfordata = false; + if (!created) // destroy called + { + MAINMUTEX_UNLOCK; + WAITMUTEX_UNLOCK + return 0; + } + + // if aborted, read from abort buffer + if (FD_ISSET(abortdesc[0],&fdset)) + { +#ifdef WIN32 + char buf[1]; + + recv(abortdesc[0],buf,1,0); +#else + unsigned char buf[1]; + + read(abortdesc[0],buf,1); +#endif // WIN32 + } + + MAINMUTEX_UNLOCK + WAITMUTEX_UNLOCK + return 0;*/ + return ERR_RTP_FAKETRANS_WAITNOTIMPLEMENTED; +} + +int RTPFakeTransmitter::AbortWait() +{ +/* if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (!waitingfordata) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTWAITING; + } + + AbortWaitInternal(); + + MAINMUTEX_UNLOCK + return 0;*/ + return 0; +} + +int RTPFakeTransmitter::SendRTPData(const void *data,size_t len) +{ + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (len > maxpacksize) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_SPECIFIEDSIZETOOBIG; + } + + + destinations.GotoFirstElement(); + // send to each destination + while (destinations.HasCurrentElement()) + { + (*params->GetPacketReadyCB())(params->GetPacketReadyCBData(), (uint8_t*)data, len, + destinations.GetCurrentElement().GetIP_NBO(), + destinations.GetCurrentElement().GetRTPPort_NBO(), + 1); + destinations.GotoNextElement(); + } + + MAINMUTEX_UNLOCK + return 0; +} + +int RTPFakeTransmitter::SendRTCPData(const void *data,size_t len) +{ + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (len > maxpacksize) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_SPECIFIEDSIZETOOBIG; + } + + destinations.GotoFirstElement(); + // send to each destination + while (destinations.HasCurrentElement()) + { + (*params->GetPacketReadyCB())(params->GetPacketReadyCBData(), (uint8_t*)data, len, + destinations.GetCurrentElement().GetIP_NBO(), + destinations.GetCurrentElement().GetRTCPPort_NBO(), + 0); + destinations.GotoNextElement(); + } + + MAINMUTEX_UNLOCK + return 0; +} + +int RTPFakeTransmitter::AddDestination(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_INVALIDADDRESSTYPE; + } + + RTPIPv4Address &address = (RTPIPv4Address &)addr; + RTPIPv4Destination dest(address.GetIP(),address.GetPort()); + int status = destinations.AddElement(dest); + + MAINMUTEX_UNLOCK + return status; +} + +int RTPFakeTransmitter::DeleteDestination(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_INVALIDADDRESSTYPE; + } + + RTPIPv4Address &address = (RTPIPv4Address &)addr; + RTPIPv4Destination dest(address.GetIP(),address.GetPort()); + int status = destinations.DeleteElement(dest); + + MAINMUTEX_UNLOCK + return status; +} + +void RTPFakeTransmitter::ClearDestinations() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (created) + destinations.Clear(); + MAINMUTEX_UNLOCK +} + +bool RTPFakeTransmitter::SupportsMulticasting() +{ + if (!init) + return false; + + MAINMUTEX_LOCK + + bool v; + + if (!created) + v = false; + else + v = supportsmulticasting; + + MAINMUTEX_UNLOCK + return v; +} + +#ifdef RTP_SUPPORT_IPV4MULTICAST + +int RTPFakeTransmitter::JoinMulticastGroup(const RTPAddress &addr) +{ +// hrrm wonder how will manage to get multicast info thru to the UDPSINK +/* if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_INVALIDADDRESSTYPE; + } + + const RTPIPv4Address &address = (const RTPIPv4Address &)addr; + uint32_t mcastIP = address.GetIP(); + + if (!RTPFakeTRANS_IS_MCASTADDR(mcastIP)) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTAMULTICASTADDRESS; + } + + status = multicastgroups.AddElement(mcastIP); + if (status >= 0) + { + RTPFakeTRANS_MCASTMEMBERSHIP(rtpsock,IP_ADD_MEMBERSHIP,mcastIP,status); + if (status != 0) + { + multicastgroups.DeleteElement(mcastIP); + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_COULDNTJOINMULTICASTGROUP; + } + RTPFakeTRANS_MCASTMEMBERSHIP(rtcpsock,IP_ADD_MEMBERSHIP,mcastIP,status); + if (status != 0) + { + RTPFakeTRANS_MCASTMEMBERSHIP(rtpsock,IP_DROP_MEMBERSHIP,mcastIP,status); + multicastgroups.DeleteElement(mcastIP); + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_COULDNTJOINMULTICASTGROUP; + } + } + MAINMUTEX_UNLOCK + return status;*/ + return ERR_RTP_FAKETRANS_NOMULTICASTSUPPORT; +} + +int RTPFakeTransmitter::LeaveMulticastGroup(const RTPAddress &addr) +{ + /* + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_INVALIDADDRESSTYPE; + } + + const RTPIPv4Address &address = (const RTPIPv4Address &)addr; + uint32_t mcastIP = address.GetIP(); + + if (!RTPFakeTRANS_IS_MCASTADDR(mcastIP)) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTAMULTICASTADDRESS; + } + + status = multicastgroups.DeleteElement(mcastIP); + if (status >= 0) + { + RTPFakeTRANS_MCASTMEMBERSHIP(rtpsock,IP_DROP_MEMBERSHIP,mcastIP,status); + RTPFakeTRANS_MCASTMEMBERSHIP(rtcpsock,IP_DROP_MEMBERSHIP,mcastIP,status); + status = 0; + } + + MAINMUTEX_UNLOCK + return status; + */ + return ERR_RTP_FAKETRANS_NOMULTICASTSUPPORT; +} + +void RTPFakeTransmitter::LeaveAllMulticastGroups() +{ +/* if (!init) + return; + + MAINMUTEX_LOCK + if (created) + { + multicastgroups.GotoFirstElement(); + while (multicastgroups.HasCurrentElement()) + { + uint32_t mcastIP; + int status = 0; + + mcastIP = multicastgroups.GetCurrentElement(); + RTPFakeTRANS_MCASTMEMBERSHIP(rtpsock,IP_DROP_MEMBERSHIP,mcastIP,status); + RTPFakeTRANS_MCASTMEMBERSHIP(rtcpsock,IP_DROP_MEMBERSHIP,mcastIP,status); + multicastgroups.GotoNextElement(); + } + multicastgroups.Clear(); + } + MAINMUTEX_UNLOCK*/ +} + +#else // no multicast support + +int RTPFakeTransmitter::JoinMulticastGroup(const RTPAddress &addr) +{ + return ERR_RTP_FAKETRANS_NOMULTICASTSUPPORT; +} + +int RTPFakeTransmitter::LeaveMulticastGroup(const RTPAddress &addr) +{ + return ERR_RTP_FAKETRANS_NOMULTICASTSUPPORT; +} + +void RTPFakeTransmitter::LeaveAllMulticastGroups() +{ +} + +#endif // RTP_SUPPORT_IPV4MULTICAST + +int RTPFakeTransmitter::SetReceiveMode(RTPTransmitter::ReceiveMode m) +{ + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (m != receivemode) + { + receivemode = m; + acceptignoreinfo.Clear(); + } + MAINMUTEX_UNLOCK + return 0; +} + +int RTPFakeTransmitter::AddToIgnoreList(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_INVALIDADDRESSTYPE; + } + if (receivemode != RTPTransmitter::IgnoreSome) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_DIFFERENTRECEIVEMODE; + } + + const RTPIPv4Address &address = (const RTPIPv4Address &)addr; + status = ProcessAddAcceptIgnoreEntry(address.GetIP(),address.GetPort()); + + MAINMUTEX_UNLOCK + return status; +} + +int RTPFakeTransmitter::DeleteFromIgnoreList(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_INVALIDADDRESSTYPE; + } + if (receivemode != RTPTransmitter::IgnoreSome) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_DIFFERENTRECEIVEMODE; + } + + const RTPIPv4Address &address = (const RTPIPv4Address &)addr; + status = ProcessDeleteAcceptIgnoreEntry(address.GetIP(),address.GetPort()); + + MAINMUTEX_UNLOCK + return status; +} + +void RTPFakeTransmitter::ClearIgnoreList() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (created && receivemode == RTPTransmitter::IgnoreSome) + ClearAcceptIgnoreInfo(); + MAINMUTEX_UNLOCK +} + +int RTPFakeTransmitter::AddToAcceptList(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_INVALIDADDRESSTYPE; + } + if (receivemode != RTPTransmitter::AcceptSome) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_DIFFERENTRECEIVEMODE; + } + + const RTPIPv4Address &address = (const RTPIPv4Address &)addr; + status = ProcessAddAcceptIgnoreEntry(address.GetIP(),address.GetPort()); + + MAINMUTEX_UNLOCK + return status; +} + +int RTPFakeTransmitter::DeleteFromAcceptList(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_INVALIDADDRESSTYPE; + } + if (receivemode != RTPTransmitter::AcceptSome) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_DIFFERENTRECEIVEMODE; + } + + const RTPIPv4Address &address = (const RTPIPv4Address &)addr; + status = ProcessDeleteAcceptIgnoreEntry(address.GetIP(),address.GetPort()); + + MAINMUTEX_UNLOCK + return status; +} + +void RTPFakeTransmitter::ClearAcceptList() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (created && receivemode == RTPTransmitter::AcceptSome) + ClearAcceptIgnoreInfo(); + MAINMUTEX_UNLOCK +} + +int RTPFakeTransmitter::SetMaximumPacketSize(size_t s) +{ + if (!init) + return ERR_RTP_FAKETRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_NOTCREATED; + } + if (s > RTPFAKETRANS_MAXPACKSIZE) + { + MAINMUTEX_UNLOCK + return ERR_RTP_FAKETRANS_SPECIFIEDSIZETOOBIG; + } + maxpacksize = s; + MAINMUTEX_UNLOCK + return 0; +} + +bool RTPFakeTransmitter::NewDataAvailable() +{ + if (!init) + return false; + + MAINMUTEX_LOCK + + bool v; + + if (!created) + v = false; + else + { + if (rawpacketlist.empty()) + v = false; + else + v = true; + } + + MAINMUTEX_UNLOCK + return v; +} + +RTPRawPacket *RTPFakeTransmitter::GetNextPacket() +{ + if (!init) + return 0; + + MAINMUTEX_LOCK + + RTPRawPacket *p; + + if (!created) + { + MAINMUTEX_UNLOCK + return 0; + } + if (rawpacketlist.empty()) + { + MAINMUTEX_UNLOCK + return 0; + } + + p = *(rawpacketlist.begin()); + rawpacketlist.pop_front(); + + MAINMUTEX_UNLOCK + return p; +} + +// Here the private functions start... + +#ifdef RTP_SUPPORT_IPV4MULTICAST +bool RTPFakeTransmitter::SetMulticastTTL(uint8_t ttl) +{ +/* int ttl2,status; + + ttl2 = (int)ttl; + status = setsockopt(rtpsock,IPPROTO_IP,IP_MULTICAST_TTL,(const char *)&ttl2,sizeof(int)); + if (status != 0) + return false; + status = setsockopt(rtcpsock,IPPROTO_IP,IP_MULTICAST_TTL,(const char *)&ttl2,sizeof(int)); + if (status != 0) + return false; + return true;*/ + return true; +} +#endif // RTP_SUPPORT_IPV4MULTICAST + +void RTPFakeTransmitter::FlushPackets() +{ + std::list::const_iterator it; + + for (it = rawpacketlist.begin() ; it != rawpacketlist.end() ; ++it) + RTPDelete(*it,GetMemoryManager()); + rawpacketlist.clear(); +} + +int RTPFakeTransmitter::FakePoll() +{ + uint8_t *data = NULL; + int data_len = 0; + uint32_t sourceaddr; + uint16_t sourceport; + bool rtp; + bool acceptdata; + + RTPTime curtime = RTPTime::CurrentTime(); + + data = params->GetCurrentData(); + data_len = params->GetCurrentDataLen(); + rtp = params->GetCurrentDataType(); + sourceaddr = params->GetCurrentDataAddr(); + sourceport = params->GetCurrentDataPort(); + // lets make sure we got something + if (data == NULL || data_len <= 0) + { + return 0; + } + + // let's make a RTPIPv4Address + RTPIPv4Address *addr = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPADDRESS) RTPIPv4Address(sourceaddr, sourceport); + if (addr == 0) + { + return ERR_RTP_OUTOFMEM; + } + + // ok we got the src addr, now this should be the actual packet + uint8_t *datacopy; + datacopy = RTPNew(GetMemoryManager(),(rtp)?RTPMEM_TYPE_BUFFER_RECEIVEDRTPPACKET:RTPMEM_TYPE_BUFFER_RECEIVEDRTCPPACKET) uint8_t[data_len]; + if (datacopy == 0) + { + RTPDelete(addr,GetMemoryManager()); + return ERR_RTP_OUTOFMEM; + } + memcpy(datacopy, data, data_len); + + // got data, process it + if (receivemode == RTPTransmitter::AcceptAll) + acceptdata = true; + else + acceptdata = ShouldAcceptData(addr->GetIP(),addr->GetPort()); + + if (acceptdata) + { + // adding packet to queue + RTPRawPacket *pack; + + pack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPRAWPACKET) RTPRawPacket(datacopy,data_len,addr,curtime,rtp,GetMemoryManager()); + + if (pack == 0) + { + RTPDelete(addr,GetMemoryManager()); + return ERR_RTP_OUTOFMEM; + } + rawpacketlist.push_back(pack); + } + return 0; +} + +int RTPFakeTransmitter::ProcessAddAcceptIgnoreEntry(uint32_t ip,uint16_t port) +{ + acceptignoreinfo.GotoElement(ip); + if (acceptignoreinfo.HasCurrentElement()) // An entry for this IP address already exists + { + PortInfo *portinf = acceptignoreinfo.GetCurrentElement(); + + if (port == 0) // select all ports + { + portinf->all = true; + portinf->portlist.clear(); + } + else if (!portinf->all) + { + std::list::const_iterator it,begin,end; + + begin = portinf->portlist.begin(); + end = portinf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == port) // already in list + return 0; + } + portinf->portlist.push_front(port); + } + } + else // got to create an entry for this IP address + { + PortInfo *portinf; + int status; + + portinf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_ACCEPTIGNOREPORTINFO) PortInfo(); + if (port == 0) // select all ports + portinf->all = true; + else + portinf->portlist.push_front(port); + + status = acceptignoreinfo.AddElement(ip,portinf); + if (status < 0) + { + RTPDelete(portinf,GetMemoryManager()); + return status; + } + } + + return 0; +} + +void RTPFakeTransmitter::ClearAcceptIgnoreInfo() +{ + acceptignoreinfo.GotoFirstElement(); + while (acceptignoreinfo.HasCurrentElement()) + { + PortInfo *inf; + + inf = acceptignoreinfo.GetCurrentElement(); + RTPDelete(inf,GetMemoryManager()); + acceptignoreinfo.GotoNextElement(); + } + acceptignoreinfo.Clear(); +} + +int RTPFakeTransmitter::ProcessDeleteAcceptIgnoreEntry(uint32_t ip,uint16_t port) +{ + acceptignoreinfo.GotoElement(ip); + if (!acceptignoreinfo.HasCurrentElement()) + return ERR_RTP_FAKETRANS_NOSUCHENTRY; + + PortInfo *inf; + + inf = acceptignoreinfo.GetCurrentElement(); + if (port == 0) // delete all entries + { + inf->all = false; + inf->portlist.clear(); + } + else // a specific port was selected + { + if (inf->all) // currently, all ports are selected. Add the one to remove to the list + { + // we have to check if the list doesn't contain the port already + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == port) // already in list: this means we already deleted the entry + return ERR_RTP_FAKETRANS_NOSUCHENTRY; + } + inf->portlist.push_front(port); + } + else // check if we can find the port in the list + { + std::list::iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; ++it) + { + if (*it == port) // found it! + { + inf->portlist.erase(it); + return 0; + } + } + // didn't find it + return ERR_RTP_FAKETRANS_NOSUCHENTRY; + } + } + return 0; +} + +bool RTPFakeTransmitter::ShouldAcceptData(uint32_t srcip,uint16_t srcport) +{ + if (receivemode == RTPTransmitter::AcceptSome) + { + PortInfo *inf; + + acceptignoreinfo.GotoElement(srcip); + if (!acceptignoreinfo.HasCurrentElement()) + return false; + + inf = acceptignoreinfo.GetCurrentElement(); + if (!inf->all) // only accept the ones in the list + { + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == srcport) + return true; + } + return false; + } + else // accept all, except the ones in the list + { + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == srcport) + return false; + } + return true; + } + } + else // IgnoreSome + { + PortInfo *inf; + + acceptignoreinfo.GotoElement(srcip); + if (!acceptignoreinfo.HasCurrentElement()) + return true; + + inf = acceptignoreinfo.GetCurrentElement(); + if (!inf->all) // ignore the ports in the list + { + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == srcport) + return false; + } + return true; + } + else // ignore all, except the ones in the list + { + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == srcport) + return true; + } + return false; + } + } + return true; +} + +#ifdef WIN32 + +int RTPFakeTransmitter::CreateAbortDescriptors() +{ + // no need for these no more +/* + SOCKET listensock; + int size; + struct sockaddr_in addr; + + listensock = socket(PF_INET,SOCK_STREAM,0); + if (listensock == RTPSOCKERR) + return ERR_RTP_FAKETRANS_CANTCREATEABORTDESCRIPTORS; + + memset(&addr,0,sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + if (bind(listensock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) + { + RTPCLOSE(listensock); + return ERR_RTP_FAKETRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in)); + size = sizeof(struct sockaddr_in); + if (getsockname(listensock,(struct sockaddr*)&addr,&size) != 0) + { + RTPCLOSE(listensock); + return ERR_RTP_FAKETRANS_CANTCREATEABORTDESCRIPTORS; + } + + unsigned short connectport = ntohs(addr.sin_port); + + abortdesc[0] = socket(PF_INET,SOCK_STREAM,0); + if (abortdesc[0] == RTPSOCKERR) + { + RTPCLOSE(listensock); + return ERR_RTP_FAKETRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + if (bind(abortdesc[0],(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_FAKETRANS_CANTCREATEABORTDESCRIPTORS; + } + + if (listen(listensock,1) != 0) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_FAKETRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = htons(connectport); + + if (connect(abortdesc[0],(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_FAKETRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in)); + size = sizeof(struct sockaddr_in); + abortdesc[1] = accept(listensock,(struct sockaddr *)&addr,&size); + if (abortdesc[1] == RTPSOCKERR) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_FAKETRANS_CANTCREATEABORTDESCRIPTORS; + } + + // okay, got the connection, close the listening socket + + RTPCLOSE(listensock); + return 0;*/ +} + +void RTPFakeTransmitter::DestroyAbortDescriptors() +{ +// RTPCLOSE(abortdesc[0]); +// RTPCLOSE(abortdesc[1]); +} + +#else // in a non winsock environment we can use pipes + +int RTPFakeTransmitter::CreateAbortDescriptors() +{ +// if (pipe(abortdesc) < 0) +// return ERR_RTP_FAKETRANS_CANTCREATEPIPE; +// return 0; + return 0; +} + +void RTPFakeTransmitter::DestroyAbortDescriptors() +{ +// close(abortdesc[0]); +// close(abortdesc[1]); +} + +#endif // WIN32 + +int RTPFakeTransmitter::CreateLocalIPList() +{ + // first try to obtain the list from the network interface info + + if (!GetLocalIPList_Interfaces()) + { + // If this fails, we'll have to depend on DNS info + GetLocalIPList_DNS(); + } + AddLoopbackAddress(); + return 0; +} + +//#ifdef WIN32 + +bool RTPFakeTransmitter::GetLocalIPList_Interfaces() +{ + // REMINDER: got to find out how to do this + return false; +} +/* +#else // use ioctl + +bool RTPFakeTransmitter::GetLocalIPList_Interfaces() +{ + int status; + char buffer[RTPFakeTRANS_IFREQBUFSIZE]; + struct ifconf ifc; + struct ifreq *ifr; + struct sockaddr *sa; + char *startptr,*endptr; + int remlen; + + ifc.ifc_len = RTPFakeTRANS_IFREQBUFSIZE; + ifc.ifc_buf = buffer; + status = ioctl(rtpsock,SIOCGIFCONF,&ifc); + if (status < 0) + return false; + + startptr = (char *)ifc.ifc_req; + endptr = startptr + ifc.ifc_len; + remlen = ifc.ifc_len; + while((startptr < endptr) && remlen >= (int)sizeof(struct ifreq)) + { + ifr = (struct ifreq *)startptr; + sa = &(ifr->ifr_addr); +#ifdef RTP_HAVE_SOCKADDR_LEN + if (sa->sa_len <= sizeof(struct sockaddr)) + { + if (sa->sa_len == sizeof(struct sockaddr_in) && sa->sa_family == PF_INET) + { + uint32_t ip; + struct sockaddr_in *addr = (struct sockaddr_in *)sa; + + ip = ntohl(addr->sin_addr.s_addr); + localIPs.push_back(ip); + } + remlen -= sizeof(struct ifreq); + startptr += sizeof(struct ifreq); + } + else + { + int l = sa->sa_len-sizeof(struct sockaddr)+sizeof(struct ifreq); + + remlen -= l; + startptr += l; + } +#else // don't have sa_len in struct sockaddr + if (sa->sa_family == PF_INET) + { + uint32_t ip; + struct sockaddr_in *addr = (struct sockaddr_in *)sa; + + ip = ntohl(addr->sin_addr.s_addr); + localIPs.push_back(ip); + } + remlen -= sizeof(struct ifreq); + startptr += sizeof(struct ifreq); + +#endif // RTP_HAVE_SOCKADDR_LEN + } + + if (localIPs.empty()) + return false; + return true; +} + +#endif // WIN32 +*/ +void RTPFakeTransmitter::GetLocalIPList_DNS() +{ + struct hostent *he; + char name[1024]; + uint32_t ip; + bool done; + int i,j; + + gethostname(name,1023); + name[1023] = 0; + he = gethostbyname(name); + if (he == 0) + return; + + ip = 0; + i = 0; + done = false; + while (!done) + { + if (he->h_addr_list[i] == NULL) + done = true; + else + { + ip = 0; + for (j = 0 ; j < 4 ; j++) + ip |= ((uint32_t)((unsigned char)he->h_addr_list[i][j])<<((3-j)*8)); + localIPs.push_back(ip); + i++; + } + } +} + +void RTPFakeTransmitter::AbortWaitInternal() +{ +/*#ifdef WIN32 + send(abortdesc[1],"*",1,0); +#else + write(abortdesc[1],"*",1); +#endif // WIN32*/ +} + +void RTPFakeTransmitter::AddLoopbackAddress() +{ + uint32_t loopbackaddr = (((uint32_t)127)<<24)|((uint32_t)1); + std::list::const_iterator it; + bool found = false; + + for (it = localIPs.begin() ; !found && it != localIPs.end() ; it++) + { + if (*it == loopbackaddr) + found = true; + } + + if (!found) + localIPs.push_back(loopbackaddr); +} + +#ifdef RTPDEBUG +void RTPFakeTransmitter::Dump() +{ + if (!init) + std::cout << "Not initialized" << std::endl; + else + { + MAINMUTEX_LOCK + + if (!created) + std::cout << "Not created" << std::endl; + else + { + char str[16]; + uint32_t ip; + std::list::const_iterator it; + + std::cout << "Portbase: " << params->GetPortbase() << std::endl; + std::cout << "Local IP addresses:" << std::endl; + for (it = localIPs.begin() ; it != localIPs.end() ; it++) + { + ip = (*it); + snprintf(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF)); + std::cout << " " << str << std::endl; + } +// std::cout << "Multicast TTL: " << (int)multicastTTL << std::endl; + std::cout << "Receive mode: "; + switch (receivemode) + { + case RTPTransmitter::AcceptAll: + std::cout << "Accept all"; + break; + case RTPTransmitter::AcceptSome: + std::cout << "Accept some"; + break; + case RTPTransmitter::IgnoreSome: + std::cout << "Ignore some"; + } + std::cout << std::endl; + if (receivemode != RTPTransmitter::AcceptAll) + { + acceptignoreinfo.GotoFirstElement(); + while(acceptignoreinfo.HasCurrentElement()) + { + ip = acceptignoreinfo.GetCurrentKey(); + snprintf(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF)); + PortInfo *pinfo = acceptignoreinfo.GetCurrentElement(); + std::cout << " " << str << ": "; + if (pinfo->all) + { + std::cout << "All ports"; + if (!pinfo->portlist.empty()) + std::cout << ", except "; + } + + std::list::const_iterator it; + + for (it = pinfo->portlist.begin() ; it != pinfo->portlist.end() ; ) + { + std::cout << (*it); + it++; + if (it != pinfo->portlist.end()) + std::cout << ", "; + } + std::cout << std::endl; + } + } + + std::cout << "Local host name: "; + if (localhostname == 0) + std::cout << "Not set"; + else + std::cout << localhostname; + std::cout << std::endl; + + std::cout << "List of destinations: "; + destinations.GotoFirstElement(); + if (destinations.HasCurrentElement()) + { + std::cout << std::endl; + do + { + std::cout << " " << destinations.GetCurrentElement().GetDestinationString() << std::endl; + destinations.GotoNextElement(); + } while (destinations.HasCurrentElement()); + } + else + std::cout << "Empty" << std::endl; + + std::cout << "Supports multicasting: " << ((supportsmulticasting)?"Yes":"No") << std::endl; +#ifdef RTP_SUPPORT_IPV4MULTICAST +/* std::cout << "List of multicast groups: "; + multicastgroups.GotoFirstElement(); + if (multicastgroups.HasCurrentElement()) + { + std::cout << std::endl; + do + { + ip = multicastgroups.GetCurrentElement(); + snprintf(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF)); + std::cout << " " << str << std::endl; + multicastgroups.GotoNextElement(); + } while (multicastgroups.HasCurrentElement()); + } + else + std::cout << "Empty" << std::endl;*/ +#endif // RTP_SUPPORT_IPV4MULTICAST + + std::cout << "Number of raw packets in queue: " << rawpacketlist.size() << std::endl; + std::cout << "Maximum allowed packet size: " << maxpacksize << std::endl; + } + + MAINMUTEX_UNLOCK + } +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/extratransmitters/rtpfaketransmitter.h b/src/libs/jrtplib/src/extratransmitters/rtpfaketransmitter.h new file mode 100644 index 00000000..a953f059 --- /dev/null +++ b/src/libs/jrtplib/src/extratransmitters/rtpfaketransmitter.h @@ -0,0 +1,247 @@ +/* + + This class allows for jrtp to process packets without sending them out + anywhere. + The incoming messages are handed in to jrtp through the TransmissionParams + and can be retreived from jrtp through the normal polling mecanisms. + The outgoing RTP/RTCP packets are given to jrtp through the normal + session->SendPacket() and those packets are handed back out to the + client through a callback function (packet_ready_cb). + + example usage : Allows for integration of RTP into gstreamer. + + Copyright (c) 2005 Philippe Khalaf + + This file is a part of JRTPLIB + Copyright (c) 1999-2004 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the "Expertisecentrum Digitale Media" + (http://www.edm.luc.ac.be), a research center of the "Limburgs Universitair + Centrum" (http://www.luc.ac.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#ifndef RTPFAKETRANSMITTER_H + +#define RTPFAKETRANSMITTER_H + +#include "rtpconfig.h" + +#include "rtptransmitter.h" +#include "rtpipv4destination.h" +#include "rtphashtable.h" +#include "rtpkeyhashtable.h" +#include + +#ifdef RTP_SUPPORT_THREAD + #include +#endif // RTP_SUPPORT_THREAD + +#define RTPFAKETRANS_HASHSIZE 8317 +#define RTPFAKETRANS_DEFAULTPORTBASE 5000 + +namespace jrtplib +{ + +// Definition of a callback that is called when a packet is ready for sending +// params (*data, data_len, dest_addr, dest_port, rtp [1 if rtp, 0 if rtcp]) +typedef void(*packet_ready_cb)(void*, uint8_t*, uint16_t, uint32_t, uint16_t, int rtp); + +class RTPFakeTransmissionParams : public RTPTransmissionParams +{ +public: + RTPFakeTransmissionParams():RTPTransmissionParams(RTPTransmitter::UserDefinedProto) { portbase = RTPFAKETRANS_DEFAULTPORTBASE; bindIP = 0; multicastTTL = 1; currentdata = NULL;} + void SetBindIP(uint32_t ip) { bindIP = ip; } + void SetPortbase(uint16_t pbase) { portbase = pbase; } + void SetMulticastTTL(uint8_t mcastTTL) { multicastTTL = mcastTTL; } + void SetLocalIPList(std::list &iplist) { localIPs = iplist; } + void ClearLocalIPList() { localIPs.clear(); } + void SetCurrentData(uint8_t *data) { currentdata = data; } + void SetCurrentDataLen(uint16_t len) { currentdatalen = len; } + void SetCurrentDataAddr(uint32_t addr) { currentdataaddr = addr; } + void SetCurrentDataPort(uint16_t port) { currentdataport = port; } + void SetCurrentDataType(bool type) { currentdatatype = type; } + void SetPacketReadyCB(packet_ready_cb cb) { packetreadycb = cb; }; + void SetPacketReadyCBData(void *data) { packetreadycbdata = data; }; + uint32_t GetBindIP() const { return bindIP; } + uint16_t GetPortbase() const { return portbase; } + uint8_t GetMulticastTTL() const { return multicastTTL; } + const std::list &GetLocalIPList() const { return localIPs; } + uint8_t* GetCurrentData() const { return currentdata; } + uint16_t GetCurrentDataLen() const { return currentdatalen; } + uint32_t GetCurrentDataAddr() const { return currentdataaddr; } + uint16_t GetCurrentDataPort() const { return currentdataport; } + bool GetCurrentDataType() const { return currentdatatype; } + packet_ready_cb GetPacketReadyCB() const { return packetreadycb; } + void* GetPacketReadyCBData() const { return packetreadycbdata; } +private: + uint16_t portbase; + uint32_t bindIP; + std::list localIPs; + uint8_t multicastTTL; + uint8_t* currentdata; + uint16_t currentdatalen; + uint32_t currentdataaddr; + uint16_t currentdataport; + bool currentdatatype; + packet_ready_cb packetreadycb; + void *packetreadycbdata; +}; + +class RTPFakeTransmissionInfo : public RTPTransmissionInfo +{ +public: + RTPFakeTransmissionInfo(std::list iplist, + RTPFakeTransmissionParams *transparams) : + RTPTransmissionInfo(RTPTransmitter::UserDefinedProto) + { localIPlist = iplist; params = transparams; } + + ~RTPFakeTransmissionInfo() { } + std::list GetLocalIPList() const { return localIPlist; } + RTPFakeTransmissionParams* GetTransParams() { return params; } +private: + std::list localIPlist; + RTPFakeTransmissionParams *params; +}; + +class RTPFakeTrans_GetHashIndex_IPv4Dest +{ +public: + static int GetIndex(const RTPIPv4Destination &d) { return d.GetIP()%RTPFAKETRANS_HASHSIZE; } +}; + +class RTPFakeTrans_GetHashIndex_uint32_t +{ +public: + static int GetIndex(const uint32_t &k) { return k%RTPFAKETRANS_HASHSIZE; } +}; + +#define RTPFAKETRANS_HEADERSIZE (20+8) + +class RTPFakeTransmitter : public RTPTransmitter +{ +public: + RTPFakeTransmitter(RTPMemoryManager *mgr); + ~RTPFakeTransmitter(); + + int Init(bool treadsafe); + int Create(size_t maxpacksize,const RTPTransmissionParams *transparams); + void Destroy(); + RTPTransmissionInfo *GetTransmissionInfo(); + void DeleteTransmissionInfo(RTPTransmissionInfo *inf); + + int GetLocalHostName(uint8_t *buffer,size_t *bufferlength); + bool ComesFromThisTransmitter(const RTPAddress *addr); + size_t GetHeaderOverhead() { return RTPFAKETRANS_HEADERSIZE; } + + int Poll(); + int WaitForIncomingData(const RTPTime &delay,bool *dataavailable = 0); + int AbortWait(); + + int SendRTPData(const void *data,size_t len); + int SendRTCPData(const void *data,size_t len); + + int AddDestination(const RTPAddress &addr); + int DeleteDestination(const RTPAddress &addr); + void ClearDestinations(); + + bool SupportsMulticasting(); + int JoinMulticastGroup(const RTPAddress &addr); + int LeaveMulticastGroup(const RTPAddress &addr); + void LeaveAllMulticastGroups(); + + int SetReceiveMode(RTPTransmitter::ReceiveMode m); + int AddToIgnoreList(const RTPAddress &addr); + int DeleteFromIgnoreList(const RTPAddress &addr); + void ClearIgnoreList(); + int AddToAcceptList(const RTPAddress &addr); + int DeleteFromAcceptList(const RTPAddress &addr); + void ClearAcceptList(); + int SetMaximumPacketSize(size_t s); + + bool NewDataAvailable(); + RTPRawPacket *GetNextPacket(); +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG +private: + int CreateLocalIPList(); + bool GetLocalIPList_Interfaces(); + void GetLocalIPList_DNS(); + void AddLoopbackAddress(); + void FlushPackets(); + int FakePoll(); + int ProcessAddAcceptIgnoreEntry(uint32_t ip,uint16_t port); + int ProcessDeleteAcceptIgnoreEntry(uint32_t ip,uint16_t port); +#ifdef RTP_SUPPORT_IPV4MULTICAST + bool SetMulticastTTL(uint8_t ttl); +#endif // RTP_SUPPORT_IPV4MULTICAST + bool ShouldAcceptData(uint32_t srcip,uint16_t srcport); + void ClearAcceptIgnoreInfo(); + + RTPFakeTransmissionParams *params; + bool init; + bool created; + bool waitingfordata; + std::list localIPs; + uint16_t portbase; + uint8_t multicastTTL; + RTPTransmitter::ReceiveMode receivemode; + + uint8_t *localhostname; + size_t localhostnamelength; + + RTPHashTable destinations; +#ifdef RTP_SUPPORT_IPV4MULTICAST +// RTPHashTable multicastgroups; +#endif // RTP_SUPPORT_IPV4MULTICAST + std::list rawpacketlist; + + bool supportsmulticasting; + size_t maxpacksize; + + class PortInfo + { + public: + PortInfo() { all = false; } + + bool all; + std::list portlist; + }; + + RTPKeyHashTable acceptignoreinfo; + + int CreateAbortDescriptors(); + void DestroyAbortDescriptors(); + void AbortWaitInternal(); +#ifdef RTP_SUPPORT_THREAD + jthread::JMutex mainmutex,waitmutex; + int threadsafe; +#endif // RTP_SUPPORT_THREAD +}; + +} // end namespace + +#endif // RTPFAKETRANSMITTER_H + diff --git a/src/libs/jrtplib/src/rtcpapppacket.cpp b/src/libs/jrtplib/src/rtcpapppacket.cpp new file mode 100644 index 00000000..1fd922e9 --- /dev/null +++ b/src/libs/jrtplib/src/rtcpapppacket.cpp @@ -0,0 +1,93 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtcpapppacket.h" +#ifdef RTPDEBUG + #include + #include + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTCPAPPPacket::RTCPAPPPacket(uint8_t *data,size_t datalength) + : RTCPPacket(APP,data,datalength) +{ + knownformat = false; + + RTCPCommonHeader *hdr; + size_t len = datalength; + + hdr = (RTCPCommonHeader *)data; + if (hdr->padding) + { + uint8_t padcount = data[datalength-1]; + if ((padcount & 0x03) != 0) // not a multiple of four! (see rfc 3550 p 37) + return; + if (((size_t)padcount) >= len) + return; + len -= (size_t)padcount; + } + + if (len < (sizeof(RTCPCommonHeader)+sizeof(uint32_t)*2)) + return; + len -= (sizeof(RTCPCommonHeader)+sizeof(uint32_t)*2); + appdatalen = len; + knownformat = true; +} + +#ifdef RTPDEBUG +void RTCPAPPPacket::Dump() +{ + RTCPPacket::Dump(); + if (!IsKnownFormat()) + { + std::cout << " Unknown format!" << std::endl; + } + else + { + std::cout << " SSRC: " << GetSSRC() << std::endl; + + char str[5]; + memcpy(str,GetName(),4); + str[4] = 0; + std::cout << " Name: " << std::string(str).c_str() << std::endl; + std::cout << " Length: " << GetAPPDataLength() << std::endl; + } +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtcpapppacket.h b/src/libs/jrtplib/src/rtcpapppacket.h new file mode 100644 index 00000000..eaf0ee49 --- /dev/null +++ b/src/libs/jrtplib/src/rtcpapppacket.h @@ -0,0 +1,132 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtcpapppacket.h + */ + +#ifndef RTCPAPPPACKET_H + +#define RTCPAPPPACKET_H + +#include "rtpconfig.h" +#include "rtcppacket.h" +#include "rtpstructs.h" +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + #include +#endif // WIN32 + +namespace jrtplib +{ + +class RTCPCompoundPacket; + +/** Describes an RTCP APP packet. */ +class JRTPLIB_IMPORTEXPORT RTCPAPPPacket : public RTCPPacket +{ +public: + /** Creates an instance based on the data in \c data with length \c datalen. + * Creates an instance based on the data in \c data with length \c datalen. Since the \c data pointer + * is referenced inside the class (no copy of the data is made) one must make sure that the memory it + * points to is valid as long as the class instance exists. + */ + RTCPAPPPacket(uint8_t *data,size_t datalen); + ~RTCPAPPPacket() { } + + /** Returns the subtype contained in the APP packet. */ + uint8_t GetSubType() const; + + /** Returns the SSRC of the source which sent this packet. */ + uint32_t GetSSRC() const; + + /** Returns the name contained in the APP packet. + * Returns the name contained in the APP packet. This alway consists of four bytes and is not NULL-terminated. + */ + uint8_t *GetName(); + + /** Returns a pointer to the actual data. */ + uint8_t *GetAPPData(); + + /** Returns the length of the actual data. */ + size_t GetAPPDataLength() const; +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG +private: + size_t appdatalen; +}; + +inline uint8_t RTCPAPPPacket::GetSubType() const +{ + if (!knownformat) + return 0; + RTCPCommonHeader *hdr = (RTCPCommonHeader *)data; + return hdr->count; +} + +inline uint32_t RTCPAPPPacket::GetSSRC() const +{ + if (!knownformat) + return 0; + + uint32_t *ssrc = (uint32_t *)(data+sizeof(RTCPCommonHeader)); + return ntohl(*ssrc); +} + +inline uint8_t *RTCPAPPPacket::GetName() +{ + if (!knownformat) + return 0; + + return (data+sizeof(RTCPCommonHeader)+sizeof(uint32_t)); +} + +inline uint8_t *RTCPAPPPacket::GetAPPData() +{ + if (!knownformat) + return 0; + if (appdatalen == 0) + return 0; + return (data+sizeof(RTCPCommonHeader)+sizeof(uint32_t)*2); +} + +inline size_t RTCPAPPPacket::GetAPPDataLength() const +{ + if (!knownformat) + return 0; + return appdatalen; +} + +} // end namespace + +#endif // RTCPAPPPACKET_H + diff --git a/src/libs/jrtplib/src/rtcpbyepacket.cpp b/src/libs/jrtplib/src/rtcpbyepacket.cpp new file mode 100644 index 00000000..8a319d9c --- /dev/null +++ b/src/libs/jrtplib/src/rtcpbyepacket.cpp @@ -0,0 +1,104 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtcpbyepacket.h" +#ifdef RTPDEBUG + #include + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTCPBYEPacket::RTCPBYEPacket(uint8_t *data,size_t datalength) + : RTCPPacket(BYE,data,datalength) +{ + knownformat = false; + reasonoffset = 0; + + RTCPCommonHeader *hdr; + size_t len = datalength; + + hdr = (RTCPCommonHeader *)data; + if (hdr->padding) + { + uint8_t padcount = data[datalength-1]; + if ((padcount & 0x03) != 0) // not a multiple of four! (see rfc 3550 p 37) + return; + if (((size_t)padcount) >= len) + return; + len -= (size_t)padcount; + } + + size_t ssrclen = ((size_t)(hdr->count))*sizeof(uint32_t) + sizeof(RTCPCommonHeader); + if (ssrclen > len) + return; + if (ssrclen < len) // there's probably a reason for leaving + { + uint8_t *reasonlength = (data+ssrclen); + size_t reaslen = (size_t)(*reasonlength); + if (reaslen > (len-ssrclen-1)) + return; + reasonoffset = ssrclen; + } + knownformat = true; +} + +#ifdef RTPDEBUG +void RTCPBYEPacket::Dump() +{ + RTCPPacket::Dump(); + if (!IsKnownFormat()) + { + std::cout << " Unknown format" << std::endl; + return; + } + + int num = GetSSRCCount(); + int i; + + for (i = 0 ; i < num ; i++) + std::cout << " SSRC: " << GetSSRC(i) << std::endl; + if (HasReasonForLeaving()) + { + char str[1024]; + memcpy(str,GetReasonData(),GetReasonLength()); + str[GetReasonLength()] = 0; + std::cout << " Reason: " << str << std::endl; + } +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtcpbyepacket.h b/src/libs/jrtplib/src/rtcpbyepacket.h new file mode 100644 index 00000000..5cd02996 --- /dev/null +++ b/src/libs/jrtplib/src/rtcpbyepacket.h @@ -0,0 +1,140 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtcpbyepacket.h + */ + +#ifndef RTCPBYEPACKET_H + +#define RTCPBYEPACKET_H + +#include "rtpconfig.h" +#include "rtcppacket.h" +#include "rtpstructs.h" +#if ! (defined(WIN32) || defined (_WIN32_WCE)) + #include +#endif // WIN32 + +namespace jrtplib +{ + +class RTCPCompoundPacket; + +/** Describes an RTCP BYE packet. */ +class JRTPLIB_IMPORTEXPORT RTCPBYEPacket : public RTCPPacket +{ +public: + /** Creates an instance based on the data in \c data with length \c datalen. + * Creates an instance based on the data in \c data with length \c datalen. Since the \c data pointer + * is referenced inside the class (no copy of the data is made) one must make sure that the memory it + * points to is valid as long as the class instance exists. + */ + RTCPBYEPacket(uint8_t *data,size_t datalen); + ~RTCPBYEPacket() { } + + /** Returns the number of SSRC identifiers present in this BYE packet. */ + int GetSSRCCount() const; + + /** Returns the SSRC described by \c index which may have a value from 0 to GetSSRCCount()-1 + * (note that no check is performed to see if \c index is valid). + */ + uint32_t GetSSRC(int index) const; // note: no check is performed to see if index is valid! + + /** Returns true if the BYE packet contains a reason for leaving. */ + bool HasReasonForLeaving() const; + + /** Returns the length of the string which describes why the source(s) left. */ + size_t GetReasonLength() const; + + /** Returns the actual reason for leaving data. */ + uint8_t *GetReasonData(); + +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG +private: + size_t reasonoffset; +}; + +inline int RTCPBYEPacket::GetSSRCCount() const +{ + if (!knownformat) + return 0; + + RTCPCommonHeader *hdr = (RTCPCommonHeader *)data; + return (int)(hdr->count); +} + +inline uint32_t RTCPBYEPacket::GetSSRC(int index) const +{ + if (!knownformat) + return 0; + uint32_t *ssrc = (uint32_t *)(data+sizeof(RTCPCommonHeader)+sizeof(uint32_t)*index); + return ntohl(*ssrc); +} + +inline bool RTCPBYEPacket::HasReasonForLeaving() const +{ + if (!knownformat) + return false; + if (reasonoffset == 0) + return false; + return true; +} + +inline size_t RTCPBYEPacket::GetReasonLength() const +{ + if (!knownformat) + return 0; + if (reasonoffset == 0) + return 0; + uint8_t *reasonlen = (data+reasonoffset); + return (size_t)(*reasonlen); +} + +inline uint8_t *RTCPBYEPacket::GetReasonData() +{ + if (!knownformat) + return 0; + if (reasonoffset == 0) + return 0; + uint8_t *reasonlen = (data+reasonoffset); + if ((*reasonlen) == 0) + return 0; + return (data+reasonoffset+1); +} + +} // end namespace + +#endif // RTCPBYEPACKET_H + diff --git a/src/libs/jrtplib/src/rtcpcompoundpacket.cpp b/src/libs/jrtplib/src/rtcpcompoundpacket.cpp new file mode 100644 index 00000000..1477fc0f --- /dev/null +++ b/src/libs/jrtplib/src/rtcpcompoundpacket.cpp @@ -0,0 +1,232 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtcpcompoundpacket.h" +#include "rtprawpacket.h" +#include "rtperrors.h" +#include "rtpstructs.h" +#include "rtpdefines.h" +#include "rtcpsrpacket.h" +#include "rtcprrpacket.h" +#include "rtcpsdespacket.h" +#include "rtcpbyepacket.h" +#include "rtcpapppacket.h" +#include "rtcpunknownpacket.h" +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + #include +#endif // WIN32 + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTCPCompoundPacket::RTCPCompoundPacket(RTPRawPacket &rawpack, RTPMemoryManager *mgr) : RTPMemoryObject(mgr) +{ + compoundpacket = 0; + compoundpacketlength = 0; + error = 0; + + if (rawpack.IsRTP()) + { + error = ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; + return; + } + + uint8_t *data = rawpack.GetData(); + size_t datalen = rawpack.GetDataLength(); + + error = ParseData(data,datalen); + if (error < 0) + return; + + compoundpacket = rawpack.GetData(); + compoundpacketlength = rawpack.GetDataLength(); + deletepacket = true; + + rawpack.ZeroData(); + + rtcppackit = rtcppacklist.begin(); +} + +RTCPCompoundPacket::RTCPCompoundPacket(uint8_t *packet, size_t packetlen, bool deletedata, RTPMemoryManager *mgr) : RTPMemoryObject(mgr) +{ + compoundpacket = 0; + compoundpacketlength = 0; + + error = ParseData(packet,packetlen); + if (error < 0) + return; + + compoundpacket = packet; + compoundpacketlength = packetlen; + deletepacket = deletedata; + + rtcppackit = rtcppacklist.begin(); +} + +RTCPCompoundPacket::RTCPCompoundPacket(RTPMemoryManager *mgr) : RTPMemoryObject(mgr) +{ + compoundpacket = 0; + compoundpacketlength = 0; + error = 0; + deletepacket = true; +} + +int RTCPCompoundPacket::ParseData(uint8_t *data, size_t datalen) +{ + bool first; + + if (datalen < sizeof(RTCPCommonHeader)) + return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; + + first = true; + + do + { + RTCPCommonHeader *rtcphdr; + size_t length; + + rtcphdr = (RTCPCommonHeader *)data; + if (rtcphdr->version != RTP_VERSION) // check version + { + ClearPacketList(); + return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; + } + if (first) + { + // Check if first packet is SR or RR + + first = false; + if ( ! (rtcphdr->packettype == RTP_RTCPTYPE_SR || rtcphdr->packettype == RTP_RTCPTYPE_RR)) + { + ClearPacketList(); + return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; + } + } + + length = (size_t)ntohs(rtcphdr->length); + length++; + length *= sizeof(uint32_t); + + if (length > datalen) // invalid length field + { + ClearPacketList(); + return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; + } + + if (rtcphdr->padding) + { + // check if it's the last packet + if (length != datalen) + { + ClearPacketList(); + return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; + } + } + + RTCPPacket *p; + + switch (rtcphdr->packettype) + { + case RTP_RTCPTYPE_SR: + p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPSRPACKET) RTCPSRPacket(data,length); + break; + case RTP_RTCPTYPE_RR: + p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPRRPACKET) RTCPRRPacket(data,length); + break; + case RTP_RTCPTYPE_SDES: + p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPSDESPACKET) RTCPSDESPacket(data,length); + break; + case RTP_RTCPTYPE_BYE: + p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPBYEPACKET) RTCPBYEPacket(data,length); + break; + case RTP_RTCPTYPE_APP: + p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPAPPPACKET) RTCPAPPPacket(data,length); + break; + default: + p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPUNKNOWNPACKET) RTCPUnknownPacket(data,length); + } + + if (p == 0) + { + ClearPacketList(); + return ERR_RTP_OUTOFMEM; + } + + rtcppacklist.push_back(p); + + datalen -= length; + data += length; + } while (datalen >= (size_t)sizeof(RTCPCommonHeader)); + + if (datalen != 0) // some remaining bytes + { + ClearPacketList(); + return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET; + } + return 0; +} + +RTCPCompoundPacket::~RTCPCompoundPacket() +{ + ClearPacketList(); + if (compoundpacket && deletepacket) + RTPDeleteByteArray(compoundpacket,GetMemoryManager()); +} + + +void RTCPCompoundPacket::ClearPacketList() +{ + std::list::const_iterator it; + + for (it = rtcppacklist.begin() ; it != rtcppacklist.end() ; it++) + RTPDelete(*it,GetMemoryManager()); + rtcppacklist.clear(); + rtcppackit = rtcppacklist.begin(); +} + +#ifdef RTPDEBUG +void RTCPCompoundPacket::Dump() +{ + std::list::const_iterator it; + for (it = rtcppacklist.begin() ; it != rtcppacklist.end() ; it++) + { + RTCPPacket *p = *it; + + p->Dump(); + } +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtcpcompoundpacket.h b/src/libs/jrtplib/src/rtcpcompoundpacket.h new file mode 100644 index 00000000..9625e71b --- /dev/null +++ b/src/libs/jrtplib/src/rtcpcompoundpacket.h @@ -0,0 +1,111 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtcpcompoundpacket.h + */ + +#ifndef RTCPCOMPOUNDPACKET_H + +#define RTCPCOMPOUNDPACKET_H + +#include "rtpconfig.h" +#include "rtptypes.h" +#include "rtpmemoryobject.h" +#include + +namespace jrtplib +{ + +class RTPRawPacket; +class RTCPPacket; + +/** Represents an RTCP compound packet. */ +class JRTPLIB_IMPORTEXPORT RTCPCompoundPacket : public RTPMemoryObject +{ +public: + /** Creates an RTCPCompoundPacket instance from the data in \c rawpack, installing a memory manager if specified. */ + RTCPCompoundPacket(RTPRawPacket &rawpack, RTPMemoryManager *memmgr = 0); + + /** Creates an RTCPCompoundPacket instance from the data in \c packet}, with size \c len. + * Creates an RTCPCompoundPacket instance from the data in \c packet}, with size \c len. The \c deletedata + * flag specifies if the data in \c packet should be deleted when the compound packet is destroyed. If + * specified, a memory manager will be installed. + */ + RTCPCompoundPacket(uint8_t *packet, size_t len, bool deletedata = true, RTPMemoryManager *memmgr = 0); +protected: + RTCPCompoundPacket(RTPMemoryManager *memmgr); // this is for the compoundpacket builder +public: + virtual ~RTCPCompoundPacket(); + + /** Checks if the RTCP compound packet was created successfully. + * If the raw packet data in the constructor could not be parsed, this function returns the error code of + * what went wrong. If the packet had an invalid format, the return value is \c ERR_RTP_RTCPCOMPOUND_INVALIDPACKET. + */ + int GetCreationError() { return error; } + + /** Returns a pointer to the data of the entire RTCP compound packet. */ + const uint8_t *GetCompoundPacketData() { return compoundpacket; } + + /** Returns the size of the entire RTCP compound packet. */ + size_t GetCompoundPacketLength() { return compoundpacketlength; } + + /** Starts the iteration over the individual RTCP packets in the RTCP compound packet. */ + void GotoFirstPacket() { rtcppackit = rtcppacklist.begin(); } + + /** Returns a pointer to the next individual RTCP packet. + * Returns a pointer to the next individual RTCP packet. Note that no \c delete call may be done + * on the RTCPPacket instance which is returned. + */ + RTCPPacket *GetNextPacket() { if (rtcppackit == rtcppacklist.end()) return 0; RTCPPacket *p = *rtcppackit; rtcppackit++; return p; } + +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG +protected: + void ClearPacketList(); + int ParseData(uint8_t *packet, size_t len); + + int error; + + const uint8_t *compoundpacket; + size_t compoundpacketlength; + bool deletepacket; + + std::list rtcppacklist; + std::list::const_iterator rtcppackit; +}; + +} // end namespace + +#endif // RTCPCOMPOUNDPACKET_H + diff --git a/src/libs/jrtplib/src/rtcpcompoundpacketbuilder.cpp b/src/libs/jrtplib/src/rtcpcompoundpacketbuilder.cpp new file mode 100644 index 00000000..b890d0ab --- /dev/null +++ b/src/libs/jrtplib/src/rtcpcompoundpacketbuilder.cpp @@ -0,0 +1,813 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtcpcompoundpacketbuilder.h" +#include "rtcpsrpacket.h" +#include "rtcprrpacket.h" +#include "rtcpsdespacket.h" +#include "rtcpbyepacket.h" +#include "rtcpapppacket.h" +#ifdef RTP_SUPPORT_RTCPUNKNOWN + #include "rtcpunknownpacket.h" +#endif // RTP_SUPPORT_RTCPUNKNOWN +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + #include + #include +#endif // WIN32 + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTCPCompoundPacketBuilder::RTCPCompoundPacketBuilder(RTPMemoryManager *mgr) : RTCPCompoundPacket(mgr), report(mgr), sdes(mgr) +{ + byesize = 0; + appsize = 0; +#ifdef RTP_SUPPORT_RTCPUNKNOWN + unknownsize = 0; +#endif // RTP_SUPPORT_RTCPUNKNOWN + maximumpacketsize = 0; + buffer = 0; + external = false; + arebuilding = false; +} + +RTCPCompoundPacketBuilder::~RTCPCompoundPacketBuilder() +{ + if (external) + compoundpacket = 0; // make sure RTCPCompoundPacket doesn't delete the external buffer + ClearBuildBuffers(); +} + +void RTCPCompoundPacketBuilder::ClearBuildBuffers() +{ + report.Clear(); + sdes.Clear(); + + std::list::const_iterator it; + for (it = byepackets.begin() ; it != byepackets.end() ; it++) + { + if ((*it).packetdata) + RTPDeleteByteArray((*it).packetdata,GetMemoryManager()); + } + for (it = apppackets.begin() ; it != apppackets.end() ; it++) + { + if ((*it).packetdata) + RTPDeleteByteArray((*it).packetdata,GetMemoryManager()); + } +#ifdef RTP_SUPPORT_RTCPUNKNOWN + for (it = unknownpackets.begin() ; it != unknownpackets.end() ; it++) + { + if ((*it).packetdata) + RTPDeleteByteArray((*it).packetdata,GetMemoryManager()); + } +#endif // RTP_SUPPORT_RTCPUNKNOWN + + byepackets.clear(); + apppackets.clear(); +#ifdef RTP_SUPPORT_RTCPUNKNOWN + unknownpackets.clear(); +#endif // RTP_SUPPORT_RTCPUNKNOWN + byesize = 0; + appsize = 0; +#ifdef RTP_SUPPORT_RTCPUNKNOWN + unknownsize = 0; +#endif // RTP_SUPPORT_RTCPUNKNOWN +} + +int RTCPCompoundPacketBuilder::InitBuild(size_t maxpacketsize) +{ + if (arebuilding) + return ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILDING; + if (compoundpacket) + return ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILT; + + if (maxpacketsize < RTP_MINPACKETSIZE) + return ERR_RTP_RTCPCOMPPACKBUILDER_MAXPACKETSIZETOOSMALL; + + maximumpacketsize = maxpacketsize; + buffer = 0; + external = false; + byesize = 0; + appsize = 0; +#ifdef RTP_SUPPORT_RTCPUNKNOWN + unknownsize = 0; +#endif // RTP_SUPPORT_RTCPUNKNOWN + + arebuilding = true; + return 0; +} + +int RTCPCompoundPacketBuilder::InitBuild(void *externalbuffer,size_t buffersize) +{ + if (arebuilding) + return ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILDING; + if (compoundpacket) + return ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILT; + + if (buffersize < RTP_MINPACKETSIZE) + return ERR_RTP_RTCPCOMPPACKBUILDER_BUFFERSIZETOOSMALL; + + maximumpacketsize = buffersize; + buffer = (uint8_t *)externalbuffer; + external = true; + byesize = 0; + appsize = 0; +#ifdef RTP_SUPPORT_RTCPUNKNOWN + unknownsize = 0; +#endif // RTP_SUPPORT_RTCPUNKNOWN + + arebuilding = true; + return 0; +} + +int RTCPCompoundPacketBuilder::StartSenderReport(uint32_t senderssrc,const RTPNTPTime &ntptimestamp,uint32_t rtptimestamp, + uint32_t packetcount,uint32_t octetcount) +{ + if (!arebuilding) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; + + if (report.headerlength != 0) + return ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYGOTREPORT; + +#ifndef RTP_SUPPORT_RTCPUNKNOWN + size_t totalsize = byesize+appsize+sdes.NeededBytes(); +#else + size_t totalsize = byesize+appsize+unknownsize+sdes.NeededBytes(); +#endif // RTP_SUPPORT_RTCPUNKNOWN + size_t sizeleft = maximumpacketsize-totalsize; + size_t neededsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t)+sizeof(RTCPSenderReport); + + if (neededsize > sizeleft) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; + + // fill in some things + + report.headerlength = sizeof(uint32_t)+sizeof(RTCPSenderReport); + report.isSR = true; + + uint32_t *ssrc = (uint32_t *)report.headerdata; + *ssrc = htonl(senderssrc); + + RTCPSenderReport *sr = (RTCPSenderReport *)(report.headerdata + sizeof(uint32_t)); + sr->ntptime_msw = htonl(ntptimestamp.GetMSW()); + sr->ntptime_lsw = htonl(ntptimestamp.GetLSW()); + sr->rtptimestamp = htonl(rtptimestamp); + sr->packetcount = htonl(packetcount); + sr->octetcount = htonl(octetcount); + + return 0; +} + +int RTCPCompoundPacketBuilder::StartReceiverReport(uint32_t senderssrc) +{ + if (!arebuilding) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; + if (report.headerlength != 0) + return ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYGOTREPORT; + +#ifndef RTP_SUPPORT_RTCPUNKNOWN + size_t totalsize = byesize+appsize+sdes.NeededBytes(); +#else + size_t totalsize = byesize+appsize+unknownsize+sdes.NeededBytes(); +#endif // RTP_SUPPORT_RTCPUNKNOWN + size_t sizeleft = maximumpacketsize-totalsize; + size_t neededsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t); + + if (neededsize > sizeleft) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; + + // fill in some things + + report.headerlength = sizeof(uint32_t); + report.isSR = false; + + uint32_t *ssrc = (uint32_t *)report.headerdata; + *ssrc = htonl(senderssrc); + + return 0; +} + +int RTCPCompoundPacketBuilder::AddReportBlock(uint32_t ssrc,uint8_t fractionlost,int32_t packetslost,uint32_t exthighestseq, + uint32_t jitter,uint32_t lsr,uint32_t dlsr) +{ + if (!arebuilding) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; + if (report.headerlength == 0) + return ERR_RTP_RTCPCOMPPACKBUILDER_REPORTNOTSTARTED; + +#ifndef RTP_SUPPORT_RTCPUNKNOWN + size_t totalothersize = byesize+appsize+sdes.NeededBytes(); +#else + size_t totalothersize = byesize+appsize+unknownsize+sdes.NeededBytes(); +#endif // RTP_SUPPORT_RTCPUNKNOWN + size_t reportsizewithextrablock = report.NeededBytesWithExtraReportBlock(); + + if ((totalothersize+reportsizewithextrablock) > maximumpacketsize) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; + + uint8_t *buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPRECEIVERREPORT) uint8_t[sizeof(RTCPReceiverReport)]; + if (buf == 0) + return ERR_RTP_OUTOFMEM; + + RTCPReceiverReport *rr = (RTCPReceiverReport *)buf; + uint32_t *packlost = (uint32_t *)&packetslost; + uint32_t packlost2 = (*packlost); + + rr->ssrc = htonl(ssrc); + rr->fractionlost = fractionlost; + rr->packetslost[2] = (uint8_t)(packlost2&0xFF); + rr->packetslost[1] = (uint8_t)((packlost2>>8)&0xFF); + rr->packetslost[0] = (uint8_t)((packlost2>>16)&0xFF); + rr->exthighseqnr = htonl(exthighestseq); + rr->jitter = htonl(jitter); + rr->lsr = htonl(lsr); + rr->dlsr = htonl(dlsr); + + report.reportblocks.push_back(Buffer(buf,sizeof(RTCPReceiverReport))); + return 0; +} + +int RTCPCompoundPacketBuilder::AddSDESSource(uint32_t ssrc) +{ + if (!arebuilding) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; + +#ifndef RTP_SUPPORT_RTCPUNKNOWN + size_t totalotherbytes = byesize+appsize+report.NeededBytes(); +#else + size_t totalotherbytes = byesize+appsize+unknownsize+report.NeededBytes(); +#endif // RTP_SUPPORT_RTCPUNKNOWN + size_t sdessizewithextrasource = sdes.NeededBytesWithExtraSource(); + + if ((totalotherbytes + sdessizewithextrasource) > maximumpacketsize) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; + + int status; + + if ((status = sdes.AddSSRC(ssrc)) < 0) + return status; + return 0; +} + +int RTCPCompoundPacketBuilder::AddSDESNormalItem(RTCPSDESPacket::ItemType t,const void *itemdata,uint8_t itemlength) +{ + if (!arebuilding) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; + if (sdes.sdessources.empty()) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE; + + uint8_t itemid; + + switch(t) + { + case RTCPSDESPacket::CNAME: + itemid = RTCP_SDES_ID_CNAME; + break; + case RTCPSDESPacket::NAME: + itemid = RTCP_SDES_ID_NAME; + break; + case RTCPSDESPacket::EMAIL: + itemid = RTCP_SDES_ID_EMAIL; + break; + case RTCPSDESPacket::PHONE: + itemid = RTCP_SDES_ID_PHONE; + break; + case RTCPSDESPacket::LOC: + itemid = RTCP_SDES_ID_LOCATION; + break; + case RTCPSDESPacket::TOOL: + itemid = RTCP_SDES_ID_TOOL; + break; + case RTCPSDESPacket::NOTE: + itemid = RTCP_SDES_ID_NOTE; + break; + default: + return ERR_RTP_RTCPCOMPPACKBUILDER_INVALIDITEMTYPE; + } + +#ifndef RTP_SUPPORT_RTCPUNKNOWN + size_t totalotherbytes = byesize+appsize+report.NeededBytes(); +#else + size_t totalotherbytes = byesize+appsize+unknownsize+report.NeededBytes(); +#endif // RTP_SUPPORT_RTCPUNKNOWN + size_t sdessizewithextraitem = sdes.NeededBytesWithExtraItem(itemlength); + + if ((sdessizewithextraitem+totalotherbytes) > maximumpacketsize) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; + + uint8_t *buf; + size_t len; + + buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPSDESBLOCK) uint8_t[sizeof(RTCPSDESHeader)+(size_t)itemlength]; + if (buf == 0) + return ERR_RTP_OUTOFMEM; + len = sizeof(RTCPSDESHeader)+(size_t)itemlength; + + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(buf); + + sdeshdr->sdesid = itemid; + sdeshdr->length = itemlength; + if (itemlength != 0) + memcpy((buf + sizeof(RTCPSDESHeader)),itemdata,(size_t)itemlength); + + sdes.AddItem(buf,len); + return 0; +} + +#ifdef RTP_SUPPORT_SDESPRIV +int RTCPCompoundPacketBuilder::AddSDESPrivateItem(const void *prefixdata,uint8_t prefixlength,const void *valuedata, + uint8_t valuelength) +{ + if (!arebuilding) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; + if (sdes.sdessources.empty()) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE; + + size_t itemlength = ((size_t)prefixlength)+1+((size_t)valuelength); + if (itemlength > 255) + return ERR_RTP_RTCPCOMPPACKBUILDER_TOTALITEMLENGTHTOOBIG; + +#ifndef RTP_SUPPORT_RTCPUNKNOWN + size_t totalotherbytes = byesize+appsize+report.NeededBytes(); +#else + size_t totalotherbytes = byesize+appsize+unknownsize+report.NeededBytes(); +#endif // RTP_SUPPORT_RTCPUNKNOWN + size_t sdessizewithextraitem = sdes.NeededBytesWithExtraItem(itemlength); + + if ((sdessizewithextraitem+totalotherbytes) > maximumpacketsize) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; + + uint8_t *buf; + size_t len; + + buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPSDESBLOCK) uint8_t[sizeof(RTCPSDESHeader)+itemlength]; + if (buf == 0) + return ERR_RTP_OUTOFMEM; + len = sizeof(RTCPSDESHeader)+(size_t)itemlength; + + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(buf); + + sdeshdr->sdesid = RTCP_SDES_ID_PRIVATE; + sdeshdr->length = itemlength; + + buf[sizeof(RTCPSDESHeader)] = prefixlength; + if (prefixlength != 0) + memcpy((buf+sizeof(RTCPSDESHeader)+1),prefixdata,(size_t)prefixlength); + if (valuelength != 0) + memcpy((buf+sizeof(RTCPSDESHeader)+1+(size_t)prefixlength),valuedata,(size_t)valuelength); + + sdes.AddItem(buf,len); + return 0; +} +#endif // RTP_SUPPORT_SDESPRIV + +int RTCPCompoundPacketBuilder::AddBYEPacket(uint32_t *ssrcs,uint8_t numssrcs,const void *reasondata,uint8_t reasonlength) +{ + if (!arebuilding) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; + + if (numssrcs > 31) + return ERR_RTP_RTCPCOMPPACKBUILDER_TOOMANYSSRCS; + + size_t packsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t)*((size_t)numssrcs); + size_t zerobytes = 0; + + if (reasonlength > 0) + { + packsize += 1; // 1 byte for the length; + packsize += (size_t)reasonlength; + + size_t r = (packsize&0x03); + if (r != 0) + { + zerobytes = 4-r; + packsize += zerobytes; + } + } + +#ifndef RTP_SUPPORT_RTCPUNKNOWN + size_t totalotherbytes = appsize+byesize+sdes.NeededBytes()+report.NeededBytes(); +#else + size_t totalotherbytes = appsize+unknownsize+byesize+sdes.NeededBytes()+report.NeededBytes(); +#endif // RTP_SUPPORT_RTCPUNKNOWN + + if ((totalotherbytes + packsize) > maximumpacketsize) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; + + uint8_t *buf; + size_t numwords; + + buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPBYEPACKET) uint8_t[packsize]; + if (buf == 0) + return ERR_RTP_OUTOFMEM; + + RTCPCommonHeader *hdr = (RTCPCommonHeader *)buf; + + hdr->version = 2; + hdr->padding = 0; + hdr->count = numssrcs; + + numwords = packsize/sizeof(uint32_t); + hdr->length = htons((uint16_t)(numwords-1)); + hdr->packettype = RTP_RTCPTYPE_BYE; + + uint32_t *sources = (uint32_t *)(buf+sizeof(RTCPCommonHeader)); + uint8_t srcindex; + + for (srcindex = 0 ; srcindex < numssrcs ; srcindex++) + sources[srcindex] = htonl(ssrcs[srcindex]); + + if (reasonlength != 0) + { + size_t offset = sizeof(RTCPCommonHeader)+((size_t)numssrcs)*sizeof(uint32_t); + + buf[offset] = reasonlength; + memcpy((buf+offset+1),reasondata,(size_t)reasonlength); + for (size_t i = 0 ; i < zerobytes ; i++) + buf[packsize-1-i] = 0; + } + + byepackets.push_back(Buffer(buf,packsize)); + byesize += packsize; + + return 0; +} + +int RTCPCompoundPacketBuilder::AddAPPPacket(uint8_t subtype,uint32_t ssrc,const uint8_t name[4],const void *appdata,size_t appdatalen) +{ + if (!arebuilding) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; + if (subtype > 31) + return ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALSUBTYPE; + if ((appdatalen%4) != 0) + return ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALAPPDATALENGTH; + + size_t appdatawords = appdatalen/4; + + if ((appdatawords+2) > 65535) + return ERR_RTP_RTCPCOMPPACKBUILDER_APPDATALENTOOBIG; + + size_t packsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t)*2+appdatalen; +#ifndef RTP_SUPPORT_RTCPUNKNOWN + size_t totalotherbytes = appsize+byesize+sdes.NeededBytes()+report.NeededBytes(); +#else + size_t totalotherbytes = appsize+unknownsize+byesize+sdes.NeededBytes()+report.NeededBytes(); +#endif // RTP_SUPPORT_RTCPUNKNOWN + + if ((totalotherbytes + packsize) > maximumpacketsize) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; + + uint8_t *buf; + + buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPAPPPACKET) uint8_t[packsize]; + if (buf == 0) + return ERR_RTP_OUTOFMEM; + + RTCPCommonHeader *hdr = (RTCPCommonHeader *)buf; + + hdr->version = 2; + hdr->padding = 0; + hdr->count = subtype; + + hdr->length = htons((uint16_t)(appdatawords+2)); + hdr->packettype = RTP_RTCPTYPE_APP; + + uint32_t *source = (uint32_t *)(buf+sizeof(RTCPCommonHeader)); + *source = htonl(ssrc); + + buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+0] = name[0]; + buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+1] = name[1]; + buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+2] = name[2]; + buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+3] = name[3]; + + if (appdatalen > 0) + memcpy((buf+sizeof(RTCPCommonHeader)+sizeof(uint32_t)*2),appdata,appdatalen); + + apppackets.push_back(Buffer(buf,packsize)); + appsize += packsize; + + return 0; +} + +#ifdef RTP_SUPPORT_RTCPUNKNOWN + +int RTCPCompoundPacketBuilder::AddUnknownPacket(uint8_t payload_type, uint8_t subtype, uint32_t ssrc, const void *data, size_t len) +{ + if (!arebuilding) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; + + size_t datawords = len/4; + + if ((datawords+2) > 65535) + return ERR_RTP_RTCPCOMPPACKBUILDER_APPDATALENTOOBIG; + + size_t packsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t)+len; + size_t totalotherbytes = appsize+unknownsize+byesize+sdes.NeededBytes()+report.NeededBytes(); + + if ((totalotherbytes + packsize) > maximumpacketsize) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; + + uint8_t *buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPUNKNOWNPACKET) uint8_t[packsize]; + if (buf == 0) + return ERR_RTP_OUTOFMEM; + + RTCPCommonHeader *hdr = (RTCPCommonHeader *)buf; + + hdr->version = 2; + hdr->padding = 0; + hdr->count = subtype; + hdr->length = htons((uint16_t)(datawords+1)); + hdr->packettype = payload_type; + + uint32_t *source = (uint32_t *)(buf+sizeof(RTCPCommonHeader)); + *source = htonl(ssrc); + + if (len > 0) + memcpy((buf+sizeof(RTCPCommonHeader)+sizeof(uint32_t)),data,len); + + unknownpackets.push_back(Buffer(buf,packsize)); + unknownsize += packsize; + + return 0; +} + +#endif // RTP_SUPPORT_RTCPUNKNOWN + +int RTCPCompoundPacketBuilder::EndBuild() +{ + if (!arebuilding) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; + if (report.headerlength == 0) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOREPORTPRESENT; + + uint8_t *buf; + size_t len; + +#ifndef RTP_SUPPORT_RTCPUNKNOWN + len = appsize+byesize+report.NeededBytes()+sdes.NeededBytes(); +#else + len = appsize+unknownsize+byesize+report.NeededBytes()+sdes.NeededBytes(); +#endif // RTP_SUPPORT_RTCPUNKNOWN + + if (!external) + { + buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPCOMPOUNDPACKET) uint8_t[len]; + if (buf == 0) + return ERR_RTP_OUTOFMEM; + } + else + buf = buffer; + + uint8_t *curbuf = buf; + RTCPPacket *p; + + // first, we'll add all report info + + { + bool firstpacket = true; + bool done = false; + std::list::const_iterator it = report.reportblocks.begin(); + do + { + RTCPCommonHeader *hdr = (RTCPCommonHeader *)curbuf; + size_t offset; + + hdr->version = 2; + hdr->padding = 0; + + if (firstpacket && report.isSR) + { + hdr->packettype = RTP_RTCPTYPE_SR; + memcpy((curbuf+sizeof(RTCPCommonHeader)),report.headerdata,report.headerlength); + offset = sizeof(RTCPCommonHeader)+report.headerlength; + } + else + { + hdr->packettype = RTP_RTCPTYPE_RR; + memcpy((curbuf+sizeof(RTCPCommonHeader)),report.headerdata,sizeof(uint32_t)); + offset = sizeof(RTCPCommonHeader)+sizeof(uint32_t); + } + firstpacket = false; + + uint8_t count = 0; + + while (it != report.reportblocks.end() && count < 31) + { + memcpy(curbuf+offset,(*it).packetdata,(*it).packetlength); + offset += (*it).packetlength; + count++; + it++; + } + + size_t numwords = offset/sizeof(uint32_t); + + hdr->length = htons((uint16_t)(numwords-1)); + hdr->count = count; + + // add entry in parent's list + if (hdr->packettype == RTP_RTCPTYPE_SR) + p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPSRPACKET) RTCPSRPacket(curbuf,offset); + else + p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPRRPACKET) RTCPRRPacket(curbuf,offset); + if (p == 0) + { + if (!external) + RTPDeleteByteArray(buf,GetMemoryManager()); + ClearPacketList(); + return ERR_RTP_OUTOFMEM; + } + rtcppacklist.push_back(p); + + curbuf += offset; + if (it == report.reportblocks.end()) + done = true; + } while (!done); + } + + // then, we'll add the sdes info + + if (!sdes.sdessources.empty()) + { + bool done = false; + std::list::const_iterator sourceit = sdes.sdessources.begin(); + + do + { + RTCPCommonHeader *hdr = (RTCPCommonHeader *)curbuf; + size_t offset = sizeof(RTCPCommonHeader); + + hdr->version = 2; + hdr->padding = 0; + hdr->packettype = RTP_RTCPTYPE_SDES; + + uint8_t sourcecount = 0; + + while (sourceit != sdes.sdessources.end() && sourcecount < 31) + { + uint32_t *ssrc = (uint32_t *)(curbuf+offset); + *ssrc = htonl((*sourceit)->ssrc); + offset += sizeof(uint32_t); + + std::list::const_iterator itemit,itemend; + + itemit = (*sourceit)->items.begin(); + itemend = (*sourceit)->items.end(); + while (itemit != itemend) + { + memcpy(curbuf+offset,(*itemit).packetdata,(*itemit).packetlength); + offset += (*itemit).packetlength; + itemit++; + } + + curbuf[offset] = 0; // end of item list; + offset++; + + size_t r = offset&0x03; + if (r != 0) // align to 32 bit boundary + { + size_t num = 4-r; + size_t i; + + for (i = 0 ; i < num ; i++) + curbuf[offset+i] = 0; + offset += num; + } + + sourceit++; + sourcecount++; + } + + size_t numwords = offset/4; + + hdr->count = sourcecount; + hdr->length = htons((uint16_t)(numwords-1)); + + p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPSDESPACKET) RTCPSDESPacket(curbuf,offset); + if (p == 0) + { + if (!external) + RTPDeleteByteArray(buf,GetMemoryManager()); + ClearPacketList(); + return ERR_RTP_OUTOFMEM; + } + rtcppacklist.push_back(p); + + curbuf += offset; + if (sourceit == sdes.sdessources.end()) + done = true; + } while (!done); + } + + // adding the app data + + { + std::list::const_iterator it; + + for (it = apppackets.begin() ; it != apppackets.end() ; it++) + { + memcpy(curbuf,(*it).packetdata,(*it).packetlength); + + p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPAPPPACKET) RTCPAPPPacket(curbuf,(*it).packetlength); + if (p == 0) + { + if (!external) + RTPDeleteByteArray(buf,GetMemoryManager()); + ClearPacketList(); + return ERR_RTP_OUTOFMEM; + } + rtcppacklist.push_back(p); + + curbuf += (*it).packetlength; + } + } + +#ifdef RTP_SUPPORT_RTCPUNKNOWN + + // adding the unknown data + + { + std::list::const_iterator it; + + for (it = unknownpackets.begin() ; it != unknownpackets.end() ; it++) + { + memcpy(curbuf,(*it).packetdata,(*it).packetlength); + + p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPUNKNOWNPACKET) RTCPUnknownPacket(curbuf,(*it).packetlength); + if (p == 0) + { + if (!external) + RTPDeleteByteArray(buf,GetMemoryManager()); + ClearPacketList(); + return ERR_RTP_OUTOFMEM; + } + rtcppacklist.push_back(p); + + curbuf += (*it).packetlength; + } + } + +#endif // RTP_SUPPORT_RTCPUNKNOWN + + // adding bye packets + + { + std::list::const_iterator it; + + for (it = byepackets.begin() ; it != byepackets.end() ; it++) + { + memcpy(curbuf,(*it).packetdata,(*it).packetlength); + + p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPBYEPACKET) RTCPBYEPacket(curbuf,(*it).packetlength); + if (p == 0) + { + if (!external) + RTPDeleteByteArray(buf,GetMemoryManager()); + ClearPacketList(); + return ERR_RTP_OUTOFMEM; + } + rtcppacklist.push_back(p); + + curbuf += (*it).packetlength; + } + } + + compoundpacket = buf; + compoundpacketlength = len; + arebuilding = false; + ClearBuildBuffers(); + return 0; +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtcpcompoundpacketbuilder.h b/src/libs/jrtplib/src/rtcpcompoundpacketbuilder.h new file mode 100644 index 00000000..010ede02 --- /dev/null +++ b/src/libs/jrtplib/src/rtcpcompoundpacketbuilder.h @@ -0,0 +1,400 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtcpcompoundpacketbuilder.h + */ + +#ifndef RTCPCOMPOUNDPACKETBUILDER_H + +#define RTCPCOMPOUNDPACKETBUILDER_H + +#include "rtpconfig.h" +#include "rtcpcompoundpacket.h" +#include "rtptimeutilities.h" +#include "rtcpsdespacket.h" +#include "rtperrors.h" +#include + +namespace jrtplib +{ + +class RTPMemoryManager; + +/** This class can be used to construct an RTCP compound packet. + * The RTCPCompoundPacketBuilder class can be used to construct an RTCP compound packet. It inherits the member + * functions of RTCPCompoundPacket which can be used to access the information in the compound packet once it has + * been built successfully. The member functions described below return \c ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT + * if the action would cause the maximum allowed size to be exceeded. + */ +class JRTPLIB_IMPORTEXPORT RTCPCompoundPacketBuilder : public RTCPCompoundPacket +{ +public: + /** Constructs an RTCPCompoundPacketBuilder instance, optionally installing a memory manager. */ + RTCPCompoundPacketBuilder(RTPMemoryManager *memmgr = 0); + ~RTCPCompoundPacketBuilder(); + + /** Starts building an RTCP compound packet with maximum size \c maxpacketsize. + * Starts building an RTCP compound packet with maximum size \c maxpacketsize. New memory will be allocated + * to store the packet. + */ + int InitBuild(size_t maxpacketsize); + + /** Starts building a RTCP compound packet. + * Starts building a RTCP compound packet. Data will be stored in \c externalbuffer which + * can contain \c buffersize bytes. + */ + int InitBuild(void *externalbuffer,size_t buffersize); + + /** Adds a sender report to the compound packet. + * Tells the packet builder that the packet should start with a sender report which will contain + * the sender information specified by this function's arguments. Once the sender report is started, + * report blocks can be added using the AddReportBlock function. + */ + int StartSenderReport(uint32_t senderssrc,const RTPNTPTime &ntptimestamp,uint32_t rtptimestamp, + uint32_t packetcount,uint32_t octetcount); + + /** Adds a receiver report to the compound packet. + * Tells the packet builder that the packet should start with a receiver report which will contain + * he sender SSRC \c senderssrc. Once the sender report is started, report blocks can be added using the + * AddReportBlock function. + */ + int StartReceiverReport(uint32_t senderssrc); + + /** Adds the report block information specified by the function's arguments. + * Adds the report block information specified by the function's arguments. If more than 31 report blocks + * are added, the builder will automatically use a new RTCP receiver report packet. + */ + int AddReportBlock(uint32_t ssrc,uint8_t fractionlost,int32_t packetslost,uint32_t exthighestseq, + uint32_t jitter,uint32_t lsr,uint32_t dlsr); + + /** Starts an SDES chunk for participant \c ssrc. */ + int AddSDESSource(uint32_t ssrc); + + /** Adds a normal (non-private) SDES item of type \c t to the current SDES chunk. + * Adds a normal (non-private) SDES item of type \c t to the current SDES chunk. The item's value + * will have length \c itemlength and will contain the data \c itemdata. + */ + int AddSDESNormalItem(RTCPSDESPacket::ItemType t,const void *itemdata,uint8_t itemlength); +#ifdef RTP_SUPPORT_SDESPRIV + /** Adds an SDES PRIV item described by the function's arguments to the current SDES chunk. */ + int AddSDESPrivateItem(const void *prefixdata,uint8_t prefixlength,const void *valuedata, + uint8_t valuelength); +#endif // RTP_SUPPORT_SDESPRIV + + /** Adds a BYE packet to the compound packet. + * Adds a BYE packet to the compound packet. It will contain \c numssrcs source identifiers specified in + * \c ssrcs and will indicate as reason for leaving the string of length \c reasonlength + * containing data \c reasondata. + */ + int AddBYEPacket(uint32_t *ssrcs,uint8_t numssrcs,const void *reasondata,uint8_t reasonlength); + + /** Adds the APP packet specified by the arguments to the compound packet. + * Adds the APP packet specified by the arguments to the compound packet. Note that \c appdatalen has to be + * a multiple of four. + */ + int AddAPPPacket(uint8_t subtype,uint32_t ssrc,const uint8_t name[4],const void *appdata,size_t appdatalen); + + /** Finishes building the compound packet. + * Finishes building the compound packet. If successful, the RTCPCompoundPacket member functions + * can be used to access the RTCP packet data. + */ + int EndBuild(); + +#ifdef RTP_SUPPORT_RTCPUNKNOWN + /** Adds the RTCP packet specified by the arguments to the compound packet. + * Adds the RTCP packet specified by the arguments to the compound packet. + */ + int AddUnknownPacket(uint8_t payload_type, uint8_t subtype, uint32_t ssrc, const void *data, size_t len); +#endif // RTP_SUPPORT_RTCPUNKNOWN +private: + class Buffer + { + public: + Buffer():packetdata(0),packetlength(0) { } + Buffer(uint8_t *data,size_t len):packetdata(data),packetlength(len) { } + + uint8_t *packetdata; + size_t packetlength; + }; + + class Report : public RTPMemoryObject + { + public: + Report(RTPMemoryManager *mgr) : RTPMemoryObject(mgr) + { + headerdata = (uint8_t *)headerdata32; + isSR = false; + headerlength = 0; + } + ~Report() { Clear(); } + + void Clear() + { + std::list::const_iterator it; + for (it = reportblocks.begin() ; it != reportblocks.end() ; it++) + { + if ((*it).packetdata) + RTPDeleteByteArray((*it).packetdata,GetMemoryManager()); + } + reportblocks.clear(); + isSR = false; + headerlength = 0; + } + + size_t NeededBytes() + { + size_t x,n,d,r; + n = reportblocks.size(); + if (n == 0) + { + if (headerlength == 0) + return 0; + x = sizeof(RTCPCommonHeader)+headerlength; + } + else + { + x = n*sizeof(RTCPReceiverReport); + d = n/31; // max 31 reportblocks per report + r = n%31; + if (r != 0) + d++; + x += d*(sizeof(RTCPCommonHeader)+sizeof(uint32_t)); /* header and SSRC */ + if (isSR) + x += sizeof(RTCPSenderReport); + } + return x; + } + + size_t NeededBytesWithExtraReportBlock() + { + size_t x,n,d,r; + n = reportblocks.size() + 1; // +1 for the extra block + x = n*sizeof(RTCPReceiverReport); + d = n/31; // max 31 reportblocks per report + r = n%31; + if (r != 0) + d++; + x += d*(sizeof(RTCPCommonHeader)+sizeof(uint32_t)); /* header and SSRC */ + if (isSR) + x += sizeof(RTCPSenderReport); + return x; + } + + bool isSR; + + uint8_t *headerdata; + uint32_t headerdata32[(sizeof(uint32_t)+sizeof(RTCPSenderReport))/sizeof(uint32_t)]; // either for ssrc and sender info or just ssrc + size_t headerlength; + std::list reportblocks; + }; + + class SDESSource : public RTPMemoryObject + { + public: + SDESSource(uint32_t s,RTPMemoryManager *mgr) : RTPMemoryObject(mgr),ssrc(s),totalitemsize(0) { } + ~SDESSource() + { + std::list::const_iterator it; + for (it = items.begin() ; it != items.end() ; it++) + { + if ((*it).packetdata) + RTPDeleteByteArray((*it).packetdata,GetMemoryManager()); + } + items.clear(); + } + + size_t NeededBytes() + { + size_t x,r; + x = totalitemsize + 1; // +1 for the 0 byte which terminates the item list + r = x%sizeof(uint32_t); + if (r != 0) + x += (sizeof(uint32_t)-r); // make sure it ends on a 32 bit boundary + x += sizeof(uint32_t); // for ssrc + return x; + } + + size_t NeededBytesWithExtraItem(uint8_t itemdatalength) + { + size_t x,r; + x = totalitemsize + sizeof(RTCPSDESHeader) + (size_t)itemdatalength + 1; + r = x%sizeof(uint32_t); + if (r != 0) + x += (sizeof(uint32_t)-r); // make sure it ends on a 32 bit boundary + x += sizeof(uint32_t); // for ssrc + return x; + } + + void AddItem(uint8_t *buf,size_t len) + { + Buffer b(buf,len); + totalitemsize += len; + items.push_back(b); + } + + uint32_t ssrc; + std::list items; + private: + size_t totalitemsize; + }; + + class SDES : public RTPMemoryObject + { + public: + SDES(RTPMemoryManager *mgr) : RTPMemoryObject(mgr) { sdesit = sdessources.end(); } + ~SDES() { Clear(); } + + void Clear() + { + std::list::const_iterator it; + + for (it = sdessources.begin() ; it != sdessources.end() ; it++) + RTPDelete(*it,GetMemoryManager()); + sdessources.clear(); + } + + int AddSSRC(uint32_t ssrc) + { + SDESSource *s = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_SDESSOURCE) SDESSource(ssrc,GetMemoryManager()); + if (s == 0) + return ERR_RTP_OUTOFMEM; + sdessources.push_back(s); + sdesit = sdessources.end(); + sdesit--; + return 0; + } + + int AddItem(uint8_t *buf,size_t len) + { + if (sdessources.empty()) + return ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE; + (*sdesit)->AddItem(buf,len); + return 0; + } + + size_t NeededBytes() + { + std::list::const_iterator it; + size_t x = 0; + size_t n,d,r; + + if (sdessources.empty()) + return 0; + + for (it = sdessources.begin() ; it != sdessources.end() ; it++) + x += (*it)->NeededBytes(); + n = sdessources.size(); + d = n/31; + r = n%31; + if (r != 0) + d++; + x += d*sizeof(RTCPCommonHeader); + return x; + } + + size_t NeededBytesWithExtraItem(uint8_t itemdatalength) + { + std::list::const_iterator it; + size_t x = 0; + size_t n,d,r; + + if (sdessources.empty()) + return 0; + + for (it = sdessources.begin() ; it != sdesit ; it++) + x += (*it)->NeededBytes(); + x += (*sdesit)->NeededBytesWithExtraItem(itemdatalength); + n = sdessources.size(); + d = n/31; + r = n%31; + if (r != 0) + d++; + x += d*sizeof(RTCPCommonHeader); + return x; + } + + size_t NeededBytesWithExtraSource() + { + std::list::const_iterator it; + size_t x = 0; + size_t n,d,r; + + if (sdessources.empty()) + return 0; + + for (it = sdessources.begin() ; it != sdessources.end() ; it++) + x += (*it)->NeededBytes(); + + // for the extra source we'll need at least 8 bytes (ssrc and four 0 bytes) + x += sizeof(uint32_t)*2; + + n = sdessources.size() + 1; // also, the number of sources will increase + d = n/31; + r = n%31; + if (r != 0) + d++; + x += d*sizeof(RTCPCommonHeader); + return x; + } + + std::list sdessources; + private: + std::list::const_iterator sdesit; + }; + + size_t maximumpacketsize; + uint8_t *buffer; + bool external; + bool arebuilding; + + Report report; + SDES sdes; + + std::list byepackets; + size_t byesize; + + std::list apppackets; + size_t appsize; + +#ifdef RTP_SUPPORT_RTCPUNKNOWN + std::list unknownpackets; + size_t unknownsize; +#endif // RTP_SUPPORT_RTCPUNKNOWN + + void ClearBuildBuffers(); +}; + +} // end namespace + +#endif // RTCPCOMPOUNDPACKETBUILDER_H + diff --git a/src/libs/jrtplib/src/rtcppacket.cpp b/src/libs/jrtplib/src/rtcppacket.cpp new file mode 100644 index 00000000..eb011347 --- /dev/null +++ b/src/libs/jrtplib/src/rtcppacket.cpp @@ -0,0 +1,76 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtcppacket.h" +#ifdef RTPDEBUG + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +#ifdef RTPDEBUG + +namespace jrtplib +{ + +void RTCPPacket::Dump() +{ + switch(packettype) + { + case SR: + std::cout << "RTCP Sender Report "; + break; + case RR: + std::cout << "RTCP Receiver Report "; + break; + case SDES: + std::cout << "RTCP Source Description "; + break; + case APP: + std::cout << "RTCP APP Packet "; + break; + case BYE: + std::cout << "RTCP Bye Packet "; + break; + case Unknown: + std::cout << "Unknown RTCP Packet "; + break; + default: + std::cout << "ERROR: Invalid packet type!" << std::endl; + } + std::cout << "Length: " << datalen; + std::cout << std::endl; +} + +} // end namespace + +#endif // RTPDEBUG diff --git a/src/libs/jrtplib/src/rtcppacket.h b/src/libs/jrtplib/src/rtcppacket.h new file mode 100644 index 00000000..178e6300 --- /dev/null +++ b/src/libs/jrtplib/src/rtcppacket.h @@ -0,0 +1,94 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtcppacket.h + */ + +#ifndef RTCPPACKET_H + +#define RTCPPACKET_H + +#include "rtpconfig.h" +#include "rtptypes.h" + +namespace jrtplib +{ + +class RTCPCompoundPacket; + +/** Base class for specific types of RTCP packets. */ +class JRTPLIB_IMPORTEXPORT RTCPPacket +{ +public: + /** Identifies the specific kind of RTCP packet. */ + enum PacketType + { + SR, /**< An RTCP sender report. */ + RR, /**< An RTCP receiver report. */ + SDES, /**< An RTCP source description packet. */ + BYE, /**< An RTCP bye packet. */ + APP, /**< An RTCP packet containing application specific data. */ + Unknown /**< The type of RTCP packet was not recognized. */ + }; +protected: + RTCPPacket(PacketType t,uint8_t *d,size_t dlen) : data(d),datalen(dlen),packettype(t) { knownformat = false; } +public: + virtual ~RTCPPacket() { } + + /** Returns \c true if the subclass was able to interpret the data and \c false otherwise. */ + bool IsKnownFormat() const { return knownformat; } + + /** Returns the actual packet type which the subclass implements. */ + PacketType GetPacketType() const { return packettype; } + + /** Returns a pointer to the data of this RTCP packet. */ + uint8_t *GetPacketData() { return data; } + + /** Returns the length of this RTCP packet. */ + size_t GetPacketLength() const { return datalen; } + +#ifdef RTPDEBUG + virtual void Dump(); +#endif // RTPDEBUG +protected: + uint8_t *data; + size_t datalen; + bool knownformat; +private: + const PacketType packettype; +}; + +} // end namespace + +#endif // RTCPPACKET_H + diff --git a/src/libs/jrtplib/src/rtcppacketbuilder.cpp b/src/libs/jrtplib/src/rtcppacketbuilder.cpp new file mode 100644 index 00000000..ac265a19 --- /dev/null +++ b/src/libs/jrtplib/src/rtcppacketbuilder.cpp @@ -0,0 +1,741 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtcppacketbuilder.h" +#include "rtpsources.h" +#include "rtppacketbuilder.h" +#include "rtcpscheduler.h" +#include "rtpsourcedata.h" +#include "rtcpcompoundpacketbuilder.h" +#include "rtpmemorymanager.h" + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTCPPacketBuilder::RTCPPacketBuilder(RTPSources &s,RTPPacketBuilder &pb,RTPMemoryManager *mgr) + : RTPMemoryObject(mgr),sources(s),rtppacketbuilder(pb),prevbuildtime(0,0),transmissiondelay(0,0),ownsdesinfo(mgr) +{ + init = false; +#if (defined(WIN32) || defined(_WIN32_WCE)) + timeinit.Dummy(); +#endif // WIN32 || _WIN32_WCE +} + +RTCPPacketBuilder::~RTCPPacketBuilder() +{ + Destroy(); +} + +int RTCPPacketBuilder::Init(size_t maxpacksize,double tsunit,const void *cname,size_t cnamelen) +{ + if (init) + return ERR_RTP_RTCPPACKETBUILDER_ALREADYINIT; + if (maxpacksize < RTP_MINPACKETSIZE) + return ERR_RTP_RTCPPACKETBUILDER_ILLEGALMAXPACKSIZE; + if (tsunit < 0.0) + return ERR_RTP_RTCPPACKETBUILDER_ILLEGALTIMESTAMPUNIT; + + if (cnamelen>255) + cnamelen = 255; + + maxpacketsize = maxpacksize; + timestampunit = tsunit; + + int status; + + if ((status = ownsdesinfo.SetCNAME((const uint8_t *)cname,cnamelen)) < 0) + return status; + + ClearAllSourceFlags(); + + interval_name = -1; + interval_email = -1; + interval_location = -1; + interval_phone = -1; + interval_tool = -1; + interval_note = -1; + + sdesbuildcount = 0; + transmissiondelay = RTPTime(0,0); + + firstpacket = true; + processingsdes = false; + init = true; + return 0; +} + +void RTCPPacketBuilder::Destroy() +{ + if (!init) + return; + ownsdesinfo.Clear(); + init = false; +} + +int RTCPPacketBuilder::BuildNextPacket(RTCPCompoundPacket **pack) +{ + if (!init) + return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; + + RTCPCompoundPacketBuilder *rtcpcomppack; + int status; + bool sender = false; + RTPSourceData *srcdat; + + *pack = 0; + + rtcpcomppack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPCOMPOUNDPACKETBUILDER) RTCPCompoundPacketBuilder(GetMemoryManager()); + if (rtcpcomppack == 0) + return ERR_RTP_OUTOFMEM; + + if ((status = rtcpcomppack->InitBuild(maxpacketsize)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + if ((srcdat = sources.GetOwnSourceInfo()) != 0) + { + if (srcdat->IsSender()) + sender = true; + } + + uint32_t ssrc = rtppacketbuilder.GetSSRC(); + RTPTime curtime = RTPTime::CurrentTime(); + + if (sender) + { + RTPTime rtppacktime = rtppacketbuilder.GetPacketTime(); + uint32_t rtppacktimestamp = rtppacketbuilder.GetPacketTimestamp(); + uint32_t packcount = rtppacketbuilder.GetPacketCount(); + uint32_t octetcount = rtppacketbuilder.GetPayloadOctetCount(); + RTPTime diff = curtime; + diff -= rtppacktime; + diff += transmissiondelay; // the sample being sampled at this very instant will need a larger timestamp + + uint32_t tsdiff = (uint32_t)((diff.GetDouble()/timestampunit)+0.5); + uint32_t rtptimestamp = rtppacktimestamp+tsdiff; + RTPNTPTime ntptimestamp = curtime.GetNTPTime(); + + if ((status = rtcpcomppack->StartSenderReport(ssrc,ntptimestamp,rtptimestamp,packcount,octetcount)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; + return status; + } + } + else + { + if ((status = rtcpcomppack->StartReceiverReport(ssrc)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; + return status; + } + } + + uint8_t *owncname; + size_t owncnamelen; + + owncname = ownsdesinfo.GetCNAME(&owncnamelen); + + if ((status = rtcpcomppack->AddSDESSource(ssrc)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; + return status; + } + if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::CNAME,owncname,owncnamelen)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; + return status; + } + + if (!processingsdes) + { + int added,skipped; + bool full,atendoflist; + + if ((status = FillInReportBlocks(rtcpcomppack,curtime,sources.GetTotalCount(),&full,&added,&skipped,&atendoflist)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + if (full && added == 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; + } + + if (!full) + { + processingsdes = true; + sdesbuildcount++; + + ClearAllSourceFlags(); + + doname = false; + doemail = false; + doloc = false; + dophone = false; + dotool = false; + donote = false; + if (interval_name > 0 && ((sdesbuildcount%interval_name) == 0)) doname = true; + if (interval_email > 0 && ((sdesbuildcount%interval_email) == 0)) doemail = true; + if (interval_location > 0 && ((sdesbuildcount%interval_location) == 0)) doloc = true; + if (interval_phone > 0 && ((sdesbuildcount%interval_phone) == 0)) dophone = true; + if (interval_tool > 0 && ((sdesbuildcount%interval_tool) == 0)) dotool = true; + if (interval_note > 0 && ((sdesbuildcount%interval_note) == 0)) donote = true; + + bool processedall; + int itemcount; + + if ((status = FillInSDES(rtcpcomppack,&full,&processedall,&itemcount)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + if (processedall) + { + processingsdes = false; + ClearAllSDESFlags(); + if (!full && skipped > 0) + { + // if the packet isn't full and we skipped some + // sources that we already got in a previous packet, + // we can add some of them now + + bool atendoflist; + + if ((status = FillInReportBlocks(rtcpcomppack,curtime,skipped,&full,&added,&skipped,&atendoflist)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + } + } + } + } + else // previous sdes processing wasn't finished + { + bool processedall; + int itemcount; + bool full; + + if ((status = FillInSDES(rtcpcomppack,&full,&processedall,&itemcount)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + if (itemcount == 0) // Big problem: packet size is too small to let any progress happen + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; + } + + if (processedall) + { + processingsdes = false; + ClearAllSDESFlags(); + if (!full) + { + // if the packet isn't full and we skipped some + // we can add some report blocks + + int added,skipped; + bool atendoflist; + + if ((status = FillInReportBlocks(rtcpcomppack,curtime,sources.GetTotalCount(),&full,&added,&skipped,&atendoflist)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + if (atendoflist) // filled in all possible sources + ClearAllSourceFlags(); + } + } + } + + if ((status = rtcpcomppack->EndBuild()) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + *pack = rtcpcomppack; + firstpacket = false; + prevbuildtime = curtime; + return 0; +} + +void RTCPPacketBuilder::ClearAllSourceFlags() +{ + if (sources.GotoFirstSource()) + { + do + { + RTPSourceData *srcdat = sources.GetCurrentSourceInfo(); + srcdat->SetProcessedInRTCP(false); + } while (sources.GotoNextSource()); + } +} + +int RTCPPacketBuilder::FillInReportBlocks(RTCPCompoundPacketBuilder *rtcpcomppack,const RTPTime &curtime,int maxcount,bool *full,int *added,int *skipped,bool *atendoflist) +{ + RTPSourceData *srcdat; + int addedcount = 0; + int skippedcount = 0; + bool done = false; + bool filled = false; + bool atend = false; + int status; + + if (sources.GotoFirstSource()) + { + do + { + bool shouldprocess = false; + + srcdat = sources.GetCurrentSourceInfo(); + if (!srcdat->IsOwnSSRC()) // don't send to ourselves + { + if (!srcdat->IsCSRC()) // p 35: no reports should go to CSRCs + { + if (srcdat->INF_HasSentData()) // if this isn't true, INF_GetLastRTPPacketTime() won't make any sense + { + if (firstpacket) + shouldprocess = true; + else + { + // p 35: only if rtp packets were received since the last RTP packet, a report block + // should be added + + RTPTime lastrtptime = srcdat->INF_GetLastRTPPacketTime(); + + if (lastrtptime > prevbuildtime) + shouldprocess = true; + } + } + } + } + + if (shouldprocess) + { + if (srcdat->IsProcessedInRTCP()) // already covered this one + { + skippedcount++; + } + else + { + uint32_t rr_ssrc = srcdat->GetSSRC(); + uint32_t num = srcdat->INF_GetNumPacketsReceivedInInterval(); + uint32_t prevseq = srcdat->INF_GetSavedExtendedSequenceNumber(); + uint32_t curseq = srcdat->INF_GetExtendedHighestSequenceNumber(); + uint32_t expected = curseq-prevseq; + uint8_t fraclost; + + if (expected < num) // got duplicates + fraclost = 0; + else + { + double lost = (double)(expected-num); + double frac = lost/((double)expected); + fraclost = (uint8_t)(frac*256.0); + } + + expected = curseq-srcdat->INF_GetBaseSequenceNumber(); + num = srcdat->INF_GetNumPacketsReceived(); + + uint32_t diff = expected-num; + int32_t *packlost = (int32_t *)&diff; + + uint32_t jitter = srcdat->INF_GetJitter(); + uint32_t lsr; + uint32_t dlsr; + + if (!srcdat->SR_HasInfo()) + { + lsr = 0; + dlsr = 0; + } + else + { + RTPNTPTime srtime = srcdat->SR_GetNTPTimestamp(); + uint32_t m = (srtime.GetMSW()&0xFFFF); + uint32_t l = ((srtime.GetLSW()>>16)&0xFFFF); + lsr = ((m<<16)|l); + + RTPTime diff = curtime; + diff -= srcdat->SR_GetReceiveTime(); + double diff2 = diff.GetDouble(); + diff2 *= 65536.0; + dlsr = (uint32_t)diff2; + } + + status = rtcpcomppack->AddReportBlock(rr_ssrc,fraclost,*packlost,curseq,jitter,lsr,dlsr); + if (status < 0) + { + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + { + done = true; + filled = true; + } + else + return status; + } + else + { + addedcount++; + if (addedcount >= maxcount) + { + done = true; + if (!sources.GotoNextSource()) + atend = true; + } + srcdat->INF_StartNewInterval(); + srcdat->SetProcessedInRTCP(true); + } + } + } + + if (!done) + { + if (!sources.GotoNextSource()) + { + atend = true; + done = true; + } + } + + } while (!done); + } + + *added = addedcount; + *skipped = skippedcount; + *full = filled; + + if (!atend) // search for available sources + { + bool shouldprocess = false; + + do + { + srcdat = sources.GetCurrentSourceInfo(); + if (!srcdat->IsOwnSSRC()) // don't send to ourselves + { + if (!srcdat->IsCSRC()) // p 35: no reports should go to CSRCs + { + if (srcdat->INF_HasSentData()) // if this isn't true, INF_GetLastRTPPacketTime() won't make any sense + { + if (firstpacket) + shouldprocess = true; + else + { + // p 35: only if rtp packets were received since the last RTP packet, a report block + // should be added + + RTPTime lastrtptime = srcdat->INF_GetLastRTPPacketTime(); + + if (lastrtptime > prevbuildtime) + shouldprocess = true; + } + } + } + } + + if (shouldprocess) + { + if (srcdat->IsProcessedInRTCP()) + shouldprocess = false; + } + + if (!shouldprocess) + { + if (!sources.GotoNextSource()) + atend = true; + } + + } while (!atend && !shouldprocess); + } + + *atendoflist = atend; + return 0; +} + +int RTCPPacketBuilder::FillInSDES(RTCPCompoundPacketBuilder *rtcpcomppack,bool *full,bool *processedall,int *added) +{ + int status; + uint8_t *data; + size_t datalen; + + *full = false; + *processedall = false; + *added = 0; + + // We don't need to add a SSRC for our own data, this is still set + // from adding the CNAME + if (doname) + { + if (!ownsdesinfo.ProcessedName()) + { + data = ownsdesinfo.GetName(&datalen); + if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::NAME,data,datalen)) < 0) + { + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + { + *full = true; + return 0; + } + } + (*added)++; + ownsdesinfo.SetProcessedName(true); + } + } + if (doemail) + { + if (!ownsdesinfo.ProcessedEMail()) + { + data = ownsdesinfo.GetEMail(&datalen); + if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::EMAIL,data,datalen)) < 0) + { + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + { + *full = true; + return 0; + } + } + (*added)++; + ownsdesinfo.SetProcessedEMail(true); + } + } + if (doloc) + { + if (!ownsdesinfo.ProcessedLocation()) + { + data = ownsdesinfo.GetLocation(&datalen); + if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::LOC,data,datalen)) < 0) + { + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + { + *full = true; + return 0; + } + } + (*added)++; + ownsdesinfo.SetProcessedLocation(true); + } + } + if (dophone) + { + if (!ownsdesinfo.ProcessedPhone()) + { + data = ownsdesinfo.GetPhone(&datalen); + if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::PHONE,data,datalen)) < 0) + { + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + { + *full = true; + return 0; + } + } + (*added)++; + ownsdesinfo.SetProcessedPhone(true); + } + } + if (dotool) + { + if (!ownsdesinfo.ProcessedTool()) + { + data = ownsdesinfo.GetTool(&datalen); + if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::TOOL,data,datalen)) < 0) + { + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + { + *full = true; + return 0; + } + } + (*added)++; + ownsdesinfo.SetProcessedTool(true); + } + } + if (donote) + { + if (!ownsdesinfo.ProcessedNote()) + { + data = ownsdesinfo.GetNote(&datalen); + if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::NOTE,data,datalen)) < 0) + { + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + { + *full = true; + return 0; + } + } + (*added)++; + ownsdesinfo.SetProcessedNote(true); + } + } + + *processedall = true; + return 0; +} + +void RTCPPacketBuilder::ClearAllSDESFlags() +{ + ownsdesinfo.ClearFlags(); +} + +int RTCPPacketBuilder::BuildBYEPacket(RTCPCompoundPacket **pack,const void *reason,size_t reasonlength,bool useSRifpossible) +{ + if (!init) + return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; + + RTCPCompoundPacketBuilder *rtcpcomppack; + int status; + + if (reasonlength > 255) + reasonlength = 255; + + *pack = 0; + + rtcpcomppack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPCOMPOUNDPACKETBUILDER) RTCPCompoundPacketBuilder(GetMemoryManager()); + if (rtcpcomppack == 0) + return ERR_RTP_OUTOFMEM; + + if ((status = rtcpcomppack->InitBuild(maxpacketsize)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + uint32_t ssrc = rtppacketbuilder.GetSSRC(); + bool useSR = false; + + if (useSRifpossible) + { + RTPSourceData *srcdat; + + if ((srcdat = sources.GetOwnSourceInfo()) != 0) + { + if (srcdat->IsSender()) + useSR = true; + } + } + + if (useSR) + { + RTPTime curtime = RTPTime::CurrentTime(); + RTPTime rtppacktime = rtppacketbuilder.GetPacketTime(); + uint32_t rtppacktimestamp = rtppacketbuilder.GetPacketTimestamp(); + uint32_t packcount = rtppacketbuilder.GetPacketCount(); + uint32_t octetcount = rtppacketbuilder.GetPayloadOctetCount(); + RTPTime diff = curtime; + diff -= rtppacktime; + + uint32_t tsdiff = (uint32_t)((diff.GetDouble()/timestampunit)+0.5); + uint32_t rtptimestamp = rtppacktimestamp+tsdiff; + RTPNTPTime ntptimestamp = curtime.GetNTPTime(); + + if ((status = rtcpcomppack->StartSenderReport(ssrc,ntptimestamp,rtptimestamp,packcount,octetcount)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; + return status; + } + } + else + { + if ((status = rtcpcomppack->StartReceiverReport(ssrc)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; + return status; + } + } + + uint8_t *owncname; + size_t owncnamelen; + + owncname = ownsdesinfo.GetCNAME(&owncnamelen); + + if ((status = rtcpcomppack->AddSDESSource(ssrc)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; + return status; + } + if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::CNAME,owncname,owncnamelen)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; + return status; + } + + uint32_t ssrcs[1]; + + ssrcs[0] = ssrc; + + if ((status = rtcpcomppack->AddBYEPacket(ssrcs,1,(const uint8_t *)reason,reasonlength)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) + return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; + return status; + } + + if ((status = rtcpcomppack->EndBuild()) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + *pack = rtcpcomppack; + return 0; +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtcppacketbuilder.h b/src/libs/jrtplib/src/rtcppacketbuilder.h new file mode 100644 index 00000000..0a665034 --- /dev/null +++ b/src/libs/jrtplib/src/rtcppacketbuilder.h @@ -0,0 +1,229 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtcppacketbuilder.h + */ + +#ifndef RTCPPACKETBUILDER_H + +#define RTCPPACKETBUILDER_H + +#include "rtpconfig.h" +#include "rtptypes.h" +#include "rtperrors.h" +#include "rtcpsdesinfo.h" +#include "rtptimeutilities.h" +#include "rtpmemoryobject.h" + +namespace jrtplib +{ + +class RTPSources; +class RTPPacketBuilder; +class RTCPScheduler; +class RTCPCompoundPacket; +class RTCPCompoundPacketBuilder; + +/** This class can be used to build RTCP compound packets, on a higher level than the RTCPCompoundPacketBuilder. + * The class RTCPPacketBuilder can be used to build RTCP compound packets. This class is more high-level + * than the RTCPCompoundPacketBuilder class: it uses the information of an RTPPacketBuilder instance and of + * an RTPSources instance to automatically generate the next compound packet which should be sent. It also + * provides functions to determine when SDES items other than the CNAME item should be sent. + */ +class JRTPLIB_IMPORTEXPORT RTCPPacketBuilder : public RTPMemoryObject +{ +public: + /** Creates an RTCPPacketBuilder instance. + * Creates an instance which will use the source table \c sources and the RTP packet builder + * \c rtppackbuilder to determine the information for the next RTCP compound packet. Optionally, + * the memory manager \c mgr can be installed. + */ + RTCPPacketBuilder(RTPSources &sources,RTPPacketBuilder &rtppackbuilder, RTPMemoryManager *mgr = 0); + ~RTCPPacketBuilder(); + + /** Initializes the builder. + * Initializes the builder to use the maximum allowed packet size \c maxpacksize, timestamp unit + * \c timestampunit and the SDES CNAME item specified by \c cname with length \c cnamelen. + * The timestamp unit is defined as a time interval divided by the timestamp interval corresponding to + * that interval: for 8000 Hz audio this would be 1/8000. + */ + int Init(size_t maxpacksize,double timestampunit,const void *cname,size_t cnamelen); + + /** Cleans up the builder. */ + void Destroy(); + + /** Sets the timestamp unit to be used to \c tsunit. + * Sets the timestamp unit to be used to \c tsunit. The timestamp unit is defined as a time interval + * divided by the timestamp interval corresponding to that interval: for 8000 Hz audio this would + * be 1/8000. + */ + int SetTimestampUnit(double tsunit) { if (!init) return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; if (tsunit < 0) return ERR_RTP_RTCPPACKETBUILDER_ILLEGALTIMESTAMPUNIT; timestampunit = tsunit; return 0; } + + /** Sets the maximum size allowed size of an RTCP compound packet to \c maxpacksize. */ + int SetMaximumPacketSize(size_t maxpacksize) { if (!init) return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; if (maxpacksize < RTP_MINPACKETSIZE) return ERR_RTP_RTCPPACKETBUILDER_ILLEGALMAXPACKSIZE; maxpacketsize = maxpacksize; return 0; } + + /** This function allows you to inform RTCP packet builder about the delay between sampling the first + * sample of a packet and sending the packet. + * This function allows you to inform RTCP packet builder about the delay between sampling the first + * sample of a packet and sending the packet. This delay is taken into account when calculating the + * relation between RTP timestamp and wallclock time, used for inter-media synchronization. + */ + int SetPreTransmissionDelay(const RTPTime &delay) { if (!init) return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; transmissiondelay = delay; return 0; } + + /** Builds the next RTCP compound packet which should be sent and stores it in \c pack. */ + int BuildNextPacket(RTCPCompoundPacket **pack); + + /** Builds a BYE packet with reason for leaving specified by \c reason and length \c reasonlength. + * Builds a BYE packet with reason for leaving specified by \c reason and length \c reasonlength. If + * \c useSRifpossible is set to \c true, the RTCP compound packet will start with a sender report if + * allowed. Otherwise, a receiver report is used. + */ + int BuildBYEPacket(RTCPCompoundPacket **pack,const void *reason,size_t reasonlength,bool useSRifpossible = true); + + /** Sets the RTCP interval for the SDES name item. + * After all possible sources in the source table have been processed, the class will check if other + * SDES items need to be sent. If \c count is zero or negative, nothing will happen. If \c count + * is positive, an SDES name item will be added after the sources in the source table have been + * processed \c count times. + */ + void SetNameInterval(int count) { if (!init) return; interval_name = count; } + + /** Sets the RTCP interval for the SDES e-mail item. + * After all possible sources in the source table have been processed, the class will check if other + * SDES items need to be sent. If \c count is zero or negative, nothing will happen. If \c count + * is positive, an SDES e-mail item will be added after the sources in the source table have been + * processed \c count times. + */ + void SetEMailInterval(int count) { if (!init) return; interval_email = count; } + + /** Sets the RTCP interval for the SDES location item. + * After all possible sources in the source table have been processed, the class will check if other + * SDES items need to be sent. If \c count is zero or negative, nothing will happen. If \c count + * is positive, an SDES location item will be added after the sources in the source table have been + * processed \c count times. + */ + void SetLocationInterval(int count) { if (!init) return; interval_location = count; } + + /** Sets the RTCP interval for the SDES phone item. + * After all possible sources in the source table have been processed, the class will check if other + * SDES items need to be sent. If \c count is zero or negative, nothing will happen. If \c count + * is positive, an SDES phone item will be added after the sources in the source table have been + * processed \c count times. + */ + void SetPhoneInterval(int count) { if (!init) return; interval_phone = count; } + + /** Sets the RTCP interval for the SDES tool item. + * After all possible sources in the source table have been processed, the class will check if other + * SDES items need to be sent. If \c count is zero or negative, nothing will happen. If \c count + * is positive, an SDES tool item will be added after the sources in the source table have been + * processed \c count times. + */ + void SetToolInterval(int count) { if (!init) return; interval_tool = count; } + + /** Sets the RTCP interval for the SDES note item. + * After all possible sources in the source table have been processed, the class will check if other + * SDES items need to be sent. If \c count is zero or negative, nothing will happen. If \c count + * is positive, an SDES note item will be added after the sources in the source table have been + * processed \c count times. + */ + void SetNoteInterval(int count) { if (!init) return; interval_note = count; } + + /** Sets the SDES name item for the local participant to the value \c s with length \c len. */ + int SetLocalName(const void *s,size_t len) { if (!init) return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; return ownsdesinfo.SetName((const uint8_t *)s,len); } + + /** Sets the SDES e-mail item for the local participant to the value \c s with length \c len. */ + int SetLocalEMail(const void *s,size_t len) { if (!init) return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; return ownsdesinfo.SetEMail((const uint8_t *)s,len); } + + /** Sets the SDES location item for the local participant to the value \c s with length \c len. */ + int SetLocalLocation(const void *s,size_t len) { if (!init) return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; return ownsdesinfo.SetLocation((const uint8_t *)s,len); } + + /** Sets the SDES phone item for the local participant to the value \c s with length \c len. */ + int SetLocalPhone(const void *s,size_t len) { if (!init) return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; return ownsdesinfo.SetPhone((const uint8_t *)s,len); } + + /** Sets the SDES tool item for the local participant to the value \c s with length \c len. */ + int SetLocalTool(const void *s,size_t len) { if (!init) return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; return ownsdesinfo.SetTool((const uint8_t *)s,len); } + + /** Sets the SDES note item for the local participant to the value \c s with length \c len. */ + int SetLocalNote(const void *s,size_t len) { if (!init) return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; return ownsdesinfo.SetNote((const uint8_t *)s,len); } + + /** Returns the own CNAME item with length \c len */ + uint8_t *GetLocalCNAME(size_t *len) const { if (!init) return 0; return ownsdesinfo.GetCNAME(len); } +private: + void ClearAllSourceFlags(); + int FillInReportBlocks(RTCPCompoundPacketBuilder *pack,const RTPTime &curtime,int maxcount,bool *full,int *added,int *skipped,bool *atendoflist); + int FillInSDES(RTCPCompoundPacketBuilder *pack,bool *full,bool *processedall,int *added); + void ClearAllSDESFlags(); + + RTPSources &sources; + RTPPacketBuilder &rtppacketbuilder; + + bool init; + size_t maxpacketsize; + double timestampunit; + bool firstpacket; + RTPTime prevbuildtime,transmissiondelay; + + class RTCPSDESInfoInternal : public RTCPSDESInfo + { + public: + RTCPSDESInfoInternal(RTPMemoryManager *mgr) : RTCPSDESInfo(mgr) { ClearFlags(); } + void ClearFlags() { pname = false; pemail = false; plocation = false; pphone = false; ptool = false; pnote = false; } + bool ProcessedName() const { return pname; } + bool ProcessedEMail() const { return pemail; } + bool ProcessedLocation() const { return plocation; } + bool ProcessedPhone() const { return pphone; } + bool ProcessedTool() const { return ptool; } + bool ProcessedNote() const { return pnote; } + void SetProcessedName(bool v) { pname = v; } + void SetProcessedEMail(bool v) { pemail = v; } + void SetProcessedLocation(bool v) { plocation = v; } + void SetProcessedPhone(bool v) { pphone = v; } + void SetProcessedTool(bool v) { ptool = v; } + void SetProcessedNote(bool v) { pnote = v; } + private: + bool pname,pemail,plocation,pphone,ptool,pnote; + }; + + RTCPSDESInfoInternal ownsdesinfo; + int interval_name,interval_email,interval_location; + int interval_phone,interval_tool,interval_note; + bool doname,doemail,doloc,dophone,dotool,donote; + bool processingsdes; + + int sdesbuildcount; +}; + +} // end namespace + +#endif // RTCPPACKETBUILDER_H + diff --git a/src/libs/jrtplib/src/rtcprrpacket.cpp b/src/libs/jrtplib/src/rtcprrpacket.cpp new file mode 100644 index 00000000..44687ea3 --- /dev/null +++ b/src/libs/jrtplib/src/rtcprrpacket.cpp @@ -0,0 +1,100 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtcprrpacket.h" +#ifdef RTPDEBUG + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTCPRRPacket::RTCPRRPacket(uint8_t *data,size_t datalength) + : RTCPPacket(RR,data,datalength) +{ + knownformat = false; + + RTCPCommonHeader *hdr; + size_t len = datalength; + size_t expectedlength; + + hdr = (RTCPCommonHeader *)data; + if (hdr->padding) + { + uint8_t padcount = data[datalength-1]; + if ((padcount & 0x03) != 0) // not a multiple of four! (see rfc 3550 p 37) + return; + if (((size_t)padcount) >= len) + return; + len -= (size_t)padcount; + } + + expectedlength = sizeof(RTCPCommonHeader)+sizeof(uint32_t); + expectedlength += sizeof(RTCPReceiverReport)*((int)hdr->count); + + if (expectedlength != len) + return; + + knownformat = true; +} + +#ifdef RTPDEBUG +void RTCPRRPacket::Dump() +{ + RTCPPacket::Dump(); + if (!IsKnownFormat()) + std::cout << " Unknown format" << std::endl; + else + { + int num = GetReceptionReportCount(); + int i; + + std::cout << " SSRC of sender: " << GetSenderSSRC() << std::endl; + for (i = 0 ; i < num ; i++) + { + std::cout << " Report block " << i << std::endl; + std::cout << " SSRC: " << GetSSRC(i) << std::endl; + std::cout << " Fraction lost: " << (uint32_t)GetFractionLost(i) << std::endl; + std::cout << " Packets lost: " << GetLostPacketCount(i) << std::endl; + std::cout << " Seq. nr.: " << GetExtendedHighestSequenceNumber(i) << std::endl; + std::cout << " Jitter: " << GetJitter(i) << std::endl; + std::cout << " LSR: " << GetLSR(i) << std::endl; + std::cout << " DLSR: " << GetDLSR(i) << std::endl; + } + } +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtcprrpacket.h b/src/libs/jrtplib/src/rtcprrpacket.h new file mode 100644 index 00000000..059182b7 --- /dev/null +++ b/src/libs/jrtplib/src/rtcprrpacket.h @@ -0,0 +1,206 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtcprrpacket.h + */ + +#ifndef RTCPRRPACKET_H + +#define RTCPRRPACKET_H + +#include "rtpconfig.h" +#include "rtcppacket.h" +#include "rtpstructs.h" +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + #include +#endif // WIN32 + +namespace jrtplib +{ + +class RTCPCompoundPacket; + +/** Describes an RTCP receiver report packet. */ +class JRTPLIB_IMPORTEXPORT RTCPRRPacket : public RTCPPacket +{ +public: + /** Creates an instance based on the data in \c data with length \c datalen. + * Creates an instance based on the data in \c data with length \c datalen. Since the \c data pointer + * is referenced inside the class (no copy of the data is made) one must make sure that the memory it points + * to is valid as long as the class instance exists. + */ + RTCPRRPacket(uint8_t *data,size_t datalen); + ~RTCPRRPacket() { } + + /** Returns the SSRC of the participant who sent this packet. */ + uint32_t GetSenderSSRC() const; + + /** Returns the number of reception report blocks present in this packet. */ + int GetReceptionReportCount() const; + + /** Returns the SSRC of the reception report block described by \c index which may have a value + * from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + uint32_t GetSSRC(int index) const; + + /** Returns the `fraction lost' field of the reception report described by \c index which may have + * a value from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + uint8_t GetFractionLost(int index) const; + + /** Returns the number of lost packets in the reception report block described by \c index which may have + * a value from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + int32_t GetLostPacketCount(int index) const; + + /** Returns the extended highest sequence number of the reception report block described by \c index which may have + * a value from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + uint32_t GetExtendedHighestSequenceNumber(int index) const; + + /** Returns the jitter field of the reception report block described by \c index which may have + * a value from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + uint32_t GetJitter(int index) const; + + /** Returns the LSR field of the reception report block described by \c index which may have + * a value from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + uint32_t GetLSR(int index) const; + + /** Returns the DLSR field of the reception report block described by \c index which may have + * a value from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + uint32_t GetDLSR(int index) const; + + +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG +private: + RTCPReceiverReport *GotoReport(int index) const; +}; + +inline uint32_t RTCPRRPacket::GetSenderSSRC() const +{ + if (!knownformat) + return 0; + + uint32_t *ssrcptr = (uint32_t *)(data+sizeof(RTCPCommonHeader)); + return ntohl(*ssrcptr); +} +inline int RTCPRRPacket::GetReceptionReportCount() const +{ + if (!knownformat) + return 0; + RTCPCommonHeader *hdr = (RTCPCommonHeader *)data; + return ((int)hdr->count); +} + +inline RTCPReceiverReport *RTCPRRPacket::GotoReport(int index) const +{ + RTCPReceiverReport *r = (RTCPReceiverReport *)(data+sizeof(RTCPCommonHeader)+sizeof(uint32_t)+index*sizeof(RTCPReceiverReport)); + return r; +} + +inline uint32_t RTCPRRPacket::GetSSRC(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + return ntohl(r->ssrc); +} + +inline uint8_t RTCPRRPacket::GetFractionLost(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + return r->fractionlost; +} + +inline int32_t RTCPRRPacket::GetLostPacketCount(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + uint32_t count = ((uint32_t)r->packetslost[2])|(((uint32_t)r->packetslost[1])<<8)|(((uint32_t)r->packetslost[0])<<16); + if ((count&0x00800000) != 0) // test for negative number + count |= 0xFF000000; + int32_t *count2 = (int32_t *)(&count); + return (*count2); +} + +inline uint32_t RTCPRRPacket::GetExtendedHighestSequenceNumber(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + return ntohl(r->exthighseqnr); +} + +inline uint32_t RTCPRRPacket::GetJitter(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + return ntohl(r->jitter); +} + +inline uint32_t RTCPRRPacket::GetLSR(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + return ntohl(r->lsr); +} + +inline uint32_t RTCPRRPacket::GetDLSR(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + return ntohl(r->dlsr); +} + +} // end namespace + +#endif // RTCPRRPACKET_H + diff --git a/src/libs/jrtplib/src/rtcpscheduler.cpp b/src/libs/jrtplib/src/rtcpscheduler.cpp new file mode 100644 index 00000000..a4c4073a --- /dev/null +++ b/src/libs/jrtplib/src/rtcpscheduler.cpp @@ -0,0 +1,423 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtcpscheduler.h" +#include "rtpsources.h" +#include "rtpdefines.h" +#include "rtcppacket.h" +#include "rtppacket.h" +#include "rtcpcompoundpacket.h" +#include "rtpsourcedata.h" + +#include "rtpdebug.h" + +#define RTCPSCHED_MININTERVAL 1.0 + +namespace jrtplib +{ + +RTCPSchedulerParams::RTCPSchedulerParams() : mininterval(RTCP_DEFAULTMININTERVAL) +{ + bandwidth = 1000; // TODO What is a good value here? + senderfraction = RTCP_DEFAULTSENDERFRACTION; + usehalfatstartup = RTCP_DEFAULTHALFATSTARTUP; + immediatebye = RTCP_DEFAULTIMMEDIATEBYE; +#if (defined(WIN32) || defined(_WIN32_WCE)) + timeinit.Dummy(); +#endif // WIN32 || _WIN32_WCE +} + +RTCPSchedulerParams::~RTCPSchedulerParams() +{ +} + +int RTCPSchedulerParams::SetRTCPBandwidth(double bw) +{ + if (bw < 0.0) + return ERR_RTP_SCHEDPARAMS_INVALIDBANDWIDTH; + bandwidth = bw; + return 0; +} + +int RTCPSchedulerParams::SetSenderBandwidthFraction(double fraction) +{ + if (fraction < 0.0 || fraction > 1.0) + return ERR_RTP_SCHEDPARAMS_BADFRACTION; + senderfraction = fraction; + return 0; +} + +int RTCPSchedulerParams::SetMinimumTransmissionInterval(const RTPTime &t) +{ + double t2 = t.GetDouble(); + + if (t2 < RTCPSCHED_MININTERVAL) + return ERR_RTP_SCHEDPARAMS_BADMINIMUMINTERVAL; + + mininterval = t; + return 0; +} + +RTCPScheduler::RTCPScheduler(RTPSources &s, RTPRandom &r) : rtprand(r),sources(s),nextrtcptime(0,0),prevrtcptime(0,0) +{ + Reset(); + + //std::cout << (void *)(&rtprand) << std::endl; +} + +RTCPScheduler::~RTCPScheduler() +{ +} + +void RTCPScheduler::Reset() +{ + headeroverhead = 0; // user has to set this to an appropriate value + hassentrtcp = false; + firstcall = true; + avgrtcppacksize = 1000; // TODO: what is a good value for this? + byescheduled = false; + sendbyenow = false; +} + +void RTCPScheduler::AnalyseIncoming(RTCPCompoundPacket &rtcpcomppack) +{ + bool isbye = false; + RTCPPacket *p; + + rtcpcomppack.GotoFirstPacket(); + while (!isbye && ((p = rtcpcomppack.GetNextPacket()) != 0)) + { + if (p->GetPacketType() == RTCPPacket::BYE) + isbye = true; + } + + if (!isbye) + { + size_t packsize = headeroverhead+rtcpcomppack.GetCompoundPacketLength(); + avgrtcppacksize = (size_t)((1.0/16.0)*((double)packsize)+(15.0/16.0)*((double)avgrtcppacksize)); + } + else + { + if (byescheduled) + { + size_t packsize = headeroverhead+rtcpcomppack.GetCompoundPacketLength(); + avgbyepacketsize = (size_t)((1.0/16.0)*((double)packsize)+(15.0/16.0)*((double)avgbyepacketsize)); + byemembers++; + } + } +} + +void RTCPScheduler::AnalyseOutgoing(RTCPCompoundPacket &rtcpcomppack) +{ + bool isbye = false; + RTCPPacket *p; + + rtcpcomppack.GotoFirstPacket(); + while (!isbye && ((p = rtcpcomppack.GetNextPacket()) != 0)) + { + if (p->GetPacketType() == RTCPPacket::BYE) + isbye = true; + } + + if (!isbye) + { + size_t packsize = headeroverhead+rtcpcomppack.GetCompoundPacketLength(); + avgrtcppacksize = (size_t)((1.0/16.0)*((double)packsize)+(15.0/16.0)*((double)avgrtcppacksize)); + } + + hassentrtcp = true; +} + +RTPTime RTCPScheduler::GetTransmissionDelay() +{ + if (firstcall) + { + firstcall = false; + prevrtcptime = RTPTime::CurrentTime(); + pmembers = sources.GetActiveMemberCount(); + CalculateNextRTCPTime(); + } + + RTPTime curtime = RTPTime::CurrentTime(); + + if (curtime > nextrtcptime) // packet should be sent + return RTPTime(0,0); + + RTPTime diff = nextrtcptime; + diff -= curtime; + + return diff; +} + +bool RTCPScheduler::IsTime() +{ + if (firstcall) + { + firstcall = false; + prevrtcptime = RTPTime::CurrentTime(); + pmembers = sources.GetActiveMemberCount(); + CalculateNextRTCPTime(); + return false; + } + + RTPTime currenttime = RTPTime::CurrentTime(); + +// // TODO: for debugging +// double diff = nextrtcptime.GetDouble() - currenttime.GetDouble(); +// +// std::cout << "Delay till next RTCP interval: " << diff << std::endl; + + if (currenttime < nextrtcptime) // timer has not yet expired + return false; + + RTPTime checktime(0,0); + + if (!byescheduled) + { + bool aresender = false; + RTPSourceData *srcdat; + + if ((srcdat = sources.GetOwnSourceInfo()) != 0) + aresender = srcdat->IsSender(); + + checktime = CalculateTransmissionInterval(aresender); + } + else + checktime = CalculateBYETransmissionInterval(); + +// std::cout << "Calculated checktime: " << checktime.GetDouble() << std::endl; + + checktime += prevrtcptime; + + if (checktime <= currenttime) // Okay + { + byescheduled = false; + prevrtcptime = currenttime; + pmembers = sources.GetActiveMemberCount(); + CalculateNextRTCPTime(); + return true; + } + +// std::cout << "New delay: " << nextrtcptime.GetDouble() - currenttime.GetDouble() << std::endl; + + nextrtcptime = checktime; + pmembers = sources.GetActiveMemberCount(); + + return false; +} + +void RTCPScheduler::CalculateNextRTCPTime() +{ + bool aresender = false; + RTPSourceData *srcdat; + + if ((srcdat = sources.GetOwnSourceInfo()) != 0) + aresender = srcdat->IsSender(); + + nextrtcptime = RTPTime::CurrentTime(); + nextrtcptime += CalculateTransmissionInterval(aresender); +} + +RTPTime RTCPScheduler::CalculateDeterministicInterval(bool sender /* = false */) +{ + int numsenders = sources.GetSenderCount(); + int numtotal = sources.GetActiveMemberCount(); + +// std::cout << "CalculateDeterministicInterval" << std::endl; +// std::cout << " numsenders: " << numsenders << std::endl; +// std::cout << " numtotal: " << numtotal << std::endl; + + // Try to avoid division by zero: + if (numtotal == 0) + numtotal++; + + double sfraction = ((double)numsenders)/((double)numtotal); + double C,n; + + if (sfraction <= schedparams.GetSenderBandwidthFraction()) + { + if (sender) + { + C = ((double)avgrtcppacksize)/(schedparams.GetSenderBandwidthFraction()*schedparams.GetRTCPBandwidth()); + n = (double)numsenders; + } + else + { + C = ((double)avgrtcppacksize)/((1.0-schedparams.GetSenderBandwidthFraction())*schedparams.GetRTCPBandwidth()); + n = (double)(numtotal-numsenders); + } + } + else + { + C = ((double)avgrtcppacksize)/schedparams.GetRTCPBandwidth(); + n = (double)numtotal; + } + + RTPTime Tmin = schedparams.GetMinimumTransmissionInterval(); + double tmin = Tmin.GetDouble(); + + if (!hassentrtcp && schedparams.GetUseHalfAtStartup()) + tmin /= 2.0; + + double ntimesC = n*C; + double Td = (tmin>ntimesC)?tmin:ntimesC; + + // TODO: for debugging +// std::cout << " Td: " << Td << std::endl; + + return RTPTime(Td); +} + +RTPTime RTCPScheduler::CalculateTransmissionInterval(bool sender) +{ + RTPTime Td = CalculateDeterministicInterval(sender); + double td,mul,T; + +// std::cout << "CalculateTransmissionInterval" << std::endl; + + td = Td.GetDouble(); + mul = rtprand.GetRandomDouble()+0.5; // gives random value between 0.5 and 1.5 + T = (td*mul)/1.21828; // see RFC 3550 p 30 + +// std::cout << " Td: " << td << std::endl; +// std::cout << " mul: " << mul << std::endl; +// std::cout << " T: " << T << std::endl; + + return RTPTime(T); +} + +void RTCPScheduler::PerformReverseReconsideration() +{ + if (firstcall) + return; + + double diff1,diff2; + int members = sources.GetActiveMemberCount(); + + RTPTime tc = RTPTime::CurrentTime(); + RTPTime tn_min_tc = nextrtcptime; + + if (tn_min_tc > tc) + tn_min_tc -= tc; + else + tn_min_tc = RTPTime(0,0); + +// std::cout << "+tn_min_tc0 " << nextrtcptime.GetDouble()-tc.GetDouble() << std::endl; +// std::cout << "-tn_min_tc0 " << -nextrtcptime.GetDouble()+tc.GetDouble() << std::endl; +// std::cout << "tn_min_tc " << tn_min_tc.GetDouble() << std::endl; + + RTPTime tc_min_tp = tc; + + if (tc_min_tp > prevrtcptime) + tc_min_tp -= prevrtcptime; + else + tc_min_tp = 0; + + if (pmembers == 0) // avoid division by zero + pmembers++; + + diff1 = (((double)members)/((double)pmembers))*tn_min_tc.GetDouble(); + diff2 = (((double)members)/((double)pmembers))*tc_min_tp.GetDouble(); + + nextrtcptime = tc; + prevrtcptime = tc; + nextrtcptime += RTPTime(diff1); + prevrtcptime -= RTPTime(diff2); + + pmembers = members; +} + +void RTCPScheduler::ScheduleBYEPacket(size_t packetsize) +{ + if (byescheduled) + return; + + if (firstcall) + { + firstcall = false; + pmembers = sources.GetActiveMemberCount(); + } + + byescheduled = true; + avgbyepacketsize = packetsize+headeroverhead; + + // For now, we will always use the BYE backoff algorithm as described in rfc 3550 p 33 + + byemembers = 1; + pbyemembers = 1; + + if (schedparams.GetRequestImmediateBYE() && sources.GetActiveMemberCount() < 50) // p 34 (top) + sendbyenow = true; + else + sendbyenow = false; + + prevrtcptime = RTPTime::CurrentTime(); + nextrtcptime = prevrtcptime; + nextrtcptime += CalculateBYETransmissionInterval(); +} + +void RTCPScheduler::ActiveMemberDecrease() +{ + if (sources.GetActiveMemberCount() < pmembers) + PerformReverseReconsideration(); +} + +RTPTime RTCPScheduler::CalculateBYETransmissionInterval() +{ + if (!byescheduled) + return RTPTime(0,0); + + if (sendbyenow) + return RTPTime(0,0); + + double C,n; + + C = ((double)avgbyepacketsize)/((1.0-schedparams.GetSenderBandwidthFraction())*schedparams.GetRTCPBandwidth()); + n = (double)byemembers; + + RTPTime Tmin = schedparams.GetMinimumTransmissionInterval(); + double tmin = Tmin.GetDouble(); + + if (schedparams.GetUseHalfAtStartup()) + tmin /= 2.0; + + double ntimesC = n*C; + double Td = (tmin>ntimesC)?tmin:ntimesC; + + double mul = rtprand.GetRandomDouble()+0.5; // gives random value between 0.5 and 1.5 + double T = (Td*mul)/1.21828; // see RFC 3550 p 30 + + return RTPTime(T); +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtcpscheduler.h b/src/libs/jrtplib/src/rtcpscheduler.h new file mode 100644 index 00000000..04e8f84c --- /dev/null +++ b/src/libs/jrtplib/src/rtcpscheduler.h @@ -0,0 +1,189 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtcpscheduler.h + */ + +#ifndef RTCPSCHEDULER_H + +#define RTCPSCHEDULER_H + +#include "rtpconfig.h" +#include "rtptimeutilities.h" +#include "rtprandom.h" + +namespace jrtplib +{ + +class RTCPCompoundPacket; +class RTPPacket; +class RTPSources; + +/** Describes parameters used by the RTCPScheduler class. */ +class JRTPLIB_IMPORTEXPORT RTCPSchedulerParams +{ +public: + RTCPSchedulerParams(); + ~RTCPSchedulerParams(); + + /** Sets the RTCP bandwidth to be used to \c bw (in bytes per second). */ + int SetRTCPBandwidth(double bw); + + /** Returns the used RTCP bandwidth in bytes per second (default is 1000). */ + double GetRTCPBandwidth() const { return bandwidth; } + + /** Sets the fraction of the RTCP bandwidth reserved for senders to \c fraction. */ + int SetSenderBandwidthFraction(double fraction); + + /** Returns the fraction of the RTCP bandwidth reserved for senders (default is 25%). */ + double GetSenderBandwidthFraction() const { return senderfraction; } + + /** Sets the minimum (deterministic) interval between RTCP compound packets to \c t. */ + int SetMinimumTransmissionInterval(const RTPTime &t); + + /** Returns the minimum RTCP transmission interval (default is 5 seconds). */ + RTPTime GetMinimumTransmissionInterval() const { return mininterval; } + + /** If \c usehalf is \c true, only use half the minimum interval before sending the first RTCP compound packet. */ + void SetUseHalfAtStartup(bool usehalf) { usehalfatstartup = usehalf; } + + /** Returns \c true if only half the minimum interval should be used before sending the first RTCP compound packet + * (defualt is \c true). + */ + bool GetUseHalfAtStartup() const { return usehalfatstartup; } + + /** If \c v is \c true, the scheduler will schedule a BYE packet to be sent immediately if allowed. */ + void SetRequestImmediateBYE(bool v) { immediatebye = v; } + + /** Returns if the scheduler will schedule a BYE packet to be sent immediately if allowed + * (default is \c true). + */ + bool GetRequestImmediateBYE() const { return immediatebye; } +private: + double bandwidth; + double senderfraction; + RTPTime mininterval; + bool usehalfatstartup; + bool immediatebye; +}; + +/** This class determines when RTCP compound packets should be sent. */ +class JRTPLIB_IMPORTEXPORT RTCPScheduler +{ +public: + /** Creates an instance which will use the source table RTPSources to determine when RTCP compound + * packets should be scheduled. + * Creates an instance which will use the source table RTPSources to determine when RTCP compound + * packets should be scheduled. Note that for correct operation the \c sources instance should have information + * about the own SSRC (added by RTPSources::CreateOwnSSRC). You must also supply a random number + * generator \c rtprand which will be used for adding randomness to the RTCP intervals. + */ + RTCPScheduler(RTPSources &sources, RTPRandom &rtprand); + ~RTCPScheduler(); + + /** Resets the scheduler. */ + void Reset(); + + /** Sets the scheduler parameters to be used to \c params. */ + void SetParameters(const RTCPSchedulerParams ¶ms) { schedparams = params; } + + /** Returns the currently used scheduler parameters. */ + RTCPSchedulerParams GetParameters() const { return schedparams; } + + /** Sets the header overhead from underlying protocols (for example UDP and IP) to \c numbytes. */ + void SetHeaderOverhead(size_t numbytes) { headeroverhead = numbytes; } + + /** Returns the currently used header overhead. */ + size_t GetHeaderOverhead() const { return headeroverhead; } + + /** For each incoming RTCP compound packet, this function has to be called for the scheduler to work correctly. */ + void AnalyseIncoming(RTCPCompoundPacket &rtcpcomppack); + + /** For each outgoing RTCP compound packet, this function has to be called for the scheduler to work correctly. */ + void AnalyseOutgoing(RTCPCompoundPacket &rtcpcomppack); + + /** This function has to be called each time a member times out or sends a BYE packet. */ + void ActiveMemberDecrease(); + + /** Asks the scheduler to schedule an RTCP compound packet containing a BYE packetl; the compound packet + * has size \c packetsize. + */ + void ScheduleBYEPacket(size_t packetsize); + + /** Returns the delay after which an RTCP compound will possibly have to be sent. + * Returns the delay after which an RTCP compound will possibly have to be sent. The IsTime member function + * should be called afterwards to make sure that it actually is time to send an RTCP compound packet. + */ + RTPTime GetTransmissionDelay(); + + /** This function returns \c true if it's time to send an RTCP compound packet and \c false otherwise. + * This function returns \c true if it's time to send an RTCP compound packet and \c false otherwise. + * If the function returns \c true, it will also have calculated the next time at which a packet should + * be sent, so if it is called again right away, it will return \c false. + */ + bool IsTime(); + + /** Calculates the deterministic interval at this time. + * Calculates the deterministic interval at this time. This is used - in combination with a certain multiplier - + * to time out members, senders etc. + */ + RTPTime CalculateDeterministicInterval(bool sender = false); +private: + void CalculateNextRTCPTime(); + void PerformReverseReconsideration(); + RTPTime CalculateBYETransmissionInterval(); + RTPTime CalculateTransmissionInterval(bool sender); + + RTPSources &sources; + RTCPSchedulerParams schedparams; + size_t headeroverhead; + size_t avgrtcppacksize; + bool hassentrtcp; + bool firstcall; + RTPTime nextrtcptime; + RTPTime prevrtcptime; + int pmembers; + + // for BYE packet scheduling + bool byescheduled; + int byemembers,pbyemembers; + size_t avgbyepacketsize; + bool sendbyenow; + + RTPRandom &rtprand; +}; + +} // end namespace + +#endif // RTCPSCHEDULER_H + diff --git a/src/libs/jrtplib/src/rtcpsdesinfo.cpp b/src/libs/jrtplib/src/rtcpsdesinfo.cpp new file mode 100644 index 00000000..dbd99718 --- /dev/null +++ b/src/libs/jrtplib/src/rtcpsdesinfo.cpp @@ -0,0 +1,182 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtcpsdesinfo.h" + +#include "rtpdebug.h" + +namespace jrtplib +{ + +void RTCPSDESInfo::Clear() +{ +#ifdef RTP_SUPPORT_SDESPRIV + std::list::const_iterator it; + + for (it = privitems.begin() ; it != privitems.end() ; ++it) + RTPDelete(*it,GetMemoryManager()); + privitems.clear(); +#endif // RTP_SUPPORT_SDESPRIV +} + +#ifdef RTP_SUPPORT_SDESPRIV +int RTCPSDESInfo::SetPrivateValue(const uint8_t *prefix,size_t prefixlen,const uint8_t *value,size_t valuelen) +{ + std::list::const_iterator it; + bool found; + + found = false; + it = privitems.begin(); + while (!found && it != privitems.end()) + { + uint8_t *p; + size_t l; + + p = (*it)->GetPrefix(&l); + if (l == prefixlen) + { + if (l <= 0) + found = true; + else if (memcmp(prefix,p,l) == 0) + found = true; + else + ++it; + } + else + ++it; + } + + SDESPrivateItem *item; + + if (found) // replace the value for this entry + item = *it; + else // no entry for this prefix found... add it + { + if (privitems.size() >= RTP_MAXPRIVITEMS) // too many items present, just ignore it + return ERR_RTP_SDES_MAXPRIVITEMS; + + int status; + + item = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_SDESPRIVATEITEM) SDESPrivateItem(GetMemoryManager()); + if (item == 0) + return ERR_RTP_OUTOFMEM; + if ((status = item->SetPrefix(prefix,prefixlen)) < 0) + { + RTPDelete(item,GetMemoryManager()); + return status; + } + privitems.push_front(item); + } + return item->SetInfo(value,valuelen); +} + +int RTCPSDESInfo::DeletePrivatePrefix(const uint8_t *prefix,size_t prefixlen) +{ + std::list::iterator it; + bool found; + + found = false; + it = privitems.begin(); + while (!found && it != privitems.end()) + { + uint8_t *p; + size_t l; + + p = (*it)->GetPrefix(&l); + if (l == prefixlen) + { + if (l <= 0) + found = true; + else if (memcmp(prefix,p,l) == 0) + found = true; + else + ++it; + } + else + ++it; + } + if (!found) + return ERR_RTP_SDES_PREFIXNOTFOUND; + + RTPDelete(*it,GetMemoryManager()); + privitems.erase(it); + return 0; +} + +void RTCPSDESInfo::GotoFirstPrivateValue() +{ + curitem = privitems.begin(); +} + +bool RTCPSDESInfo::GetNextPrivateValue(uint8_t **prefix,size_t *prefixlen,uint8_t **value,size_t *valuelen) +{ + if (curitem == privitems.end()) + return false; + *prefix = (*curitem)->GetPrefix(prefixlen); + *value = (*curitem)->GetInfo(valuelen); + ++curitem; + return true; +} + +bool RTCPSDESInfo::GetPrivateValue(const uint8_t *prefix,size_t prefixlen,uint8_t **value,size_t *valuelen) const +{ + std::list::const_iterator it; + bool found; + + found = false; + it = privitems.begin(); + while (!found && it != privitems.end()) + { + uint8_t *p; + size_t l; + + p = (*it)->GetPrefix(&l); + if (l == prefixlen) + { + if (l <= 0) + found = true; + else if (memcmp(prefix,p,l) == 0) + found = true; + else + ++it; + } + else + ++it; + } + if (found) + *value = (*it)->GetInfo(valuelen); + return found; +} +#endif // RTP_SUPPORT_SDESPRIV + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtcpsdesinfo.h b/src/libs/jrtplib/src/rtcpsdesinfo.h new file mode 100644 index 00000000..91b20ba5 --- /dev/null +++ b/src/libs/jrtplib/src/rtcpsdesinfo.h @@ -0,0 +1,220 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtcpsdesinfo.h + */ + +#ifndef RTCPSDESINFO_H + +#define RTCPSDESINFO_H + +#include "rtpconfig.h" +#include "rtperrors.h" +#include "rtpdefines.h" +#include "rtptypes.h" +#include "rtpmemoryobject.h" +#include +#include + +namespace jrtplib +{ + +/** The class RTCPSDESInfo is a container for RTCP SDES information. */ +class JRTPLIB_IMPORTEXPORT RTCPSDESInfo : public RTPMemoryObject +{ +public: + /** Constructs an instance, optionally installing a memory manager. */ + RTCPSDESInfo(RTPMemoryManager *mgr = 0) : RTPMemoryObject(mgr) { for (int i = 0 ; i < RTCP_SDES_NUMITEMS_NONPRIVATE ; i++) nonprivateitems[i].SetMemoryManager(mgr); } + virtual ~RTCPSDESInfo() { Clear(); } + + /** Clears all SDES information. */ + void Clear(); + + /** Sets the SDES CNAME item to \c s with length \c l. */ + int SetCNAME(const uint8_t *s,size_t l) { return SetNonPrivateItem(RTCP_SDES_ID_CNAME-1,s,l); } + + /** Sets the SDES name item to \c s with length \c l. */ + int SetName(const uint8_t *s,size_t l) { return SetNonPrivateItem(RTCP_SDES_ID_NAME-1,s,l); } + + /** Sets the SDES e-mail item to \c s with length \c l. */ + int SetEMail(const uint8_t *s,size_t l) { return SetNonPrivateItem(RTCP_SDES_ID_EMAIL-1,s,l); } + + /** Sets the SDES phone item to \c s with length \c l. */ + int SetPhone(const uint8_t *s,size_t l) { return SetNonPrivateItem(RTCP_SDES_ID_PHONE-1,s,l); } + + /** Sets the SDES location item to \c s with length \c l. */ + int SetLocation(const uint8_t *s,size_t l) { return SetNonPrivateItem(RTCP_SDES_ID_LOCATION-1,s,l); } + + /** Sets the SDES tool item to \c s with length \c l. */ + int SetTool(const uint8_t *s,size_t l) { return SetNonPrivateItem(RTCP_SDES_ID_TOOL-1,s,l); } + + /** Sets the SDES note item to \c s with length \c l. */ + int SetNote(const uint8_t *s,size_t l) { return SetNonPrivateItem(RTCP_SDES_ID_NOTE-1,s,l); } + +#ifdef RTP_SUPPORT_SDESPRIV + /** Sets the entry for the prefix string specified by \c prefix with length \c prefixlen to contain + * the value string specified by \c value with length \c valuelen (if the maximum allowed + * number of prefixes was reached, the error code \c ERR_RTP_SDES_MAXPRIVITEMS is returned. + */ + int SetPrivateValue(const uint8_t *prefix,size_t prefixlen,const uint8_t *value,size_t valuelen); + + /** Deletes the entry for the prefix specified by \c s with length \c len. */ + int DeletePrivatePrefix(const uint8_t *s,size_t len); +#endif // RTP_SUPPORT_SDESPRIV + + /** Returns the SDES CNAME item and stores its length in \c len. */ + uint8_t *GetCNAME(size_t *len) const { return GetNonPrivateItem(RTCP_SDES_ID_CNAME-1,len); } + + /** Returns the SDES name item and stores its length in \c len. */ + uint8_t *GetName(size_t *len) const { return GetNonPrivateItem(RTCP_SDES_ID_NAME-1,len); } + + /** Returns the SDES e-mail item and stores its length in \c len. */ + uint8_t *GetEMail(size_t *len) const { return GetNonPrivateItem(RTCP_SDES_ID_EMAIL-1,len); } + + /** Returns the SDES phone item and stores its length in \c len. */ + uint8_t *GetPhone(size_t *len) const { return GetNonPrivateItem(RTCP_SDES_ID_PHONE-1,len); } + + /** Returns the SDES location item and stores its length in \c len. */ + uint8_t *GetLocation(size_t *len) const { return GetNonPrivateItem(RTCP_SDES_ID_LOCATION-1,len); } + + /** Returns the SDES tool item and stores its length in \c len. */ + uint8_t *GetTool(size_t *len) const { return GetNonPrivateItem(RTCP_SDES_ID_TOOL-1,len); } + + /** Returns the SDES note item and stores its length in \c len. */ + uint8_t *GetNote(size_t *len) const { return GetNonPrivateItem(RTCP_SDES_ID_NOTE-1,len); } +#ifdef RTP_SUPPORT_SDESPRIV + /** Starts the iteration over the stored SDES private item prefixes and their associated values. */ + void GotoFirstPrivateValue(); + + /** Returns SDES priv item information. + * If available, returns \c true and stores the next SDES + * private item prefix in \c prefix and its length in + * \c prefixlen. The associated value and its length are + * then stored in \c value and \c valuelen. Otherwise, + * it returns \c false. + */ + bool GetNextPrivateValue(uint8_t **prefix,size_t *prefixlen,uint8_t **value,size_t *valuelen); + + /** Returns SDES priv item information. + * Looks for the entry which corresponds to the SDES private + * item prefix \c prefix with length \c prefixlen. If found, + * the function returns \c true and stores the associated + * value and its length in \c value and \c valuelen + * respectively. + */ + bool GetPrivateValue(const uint8_t *prefix,size_t prefixlen,uint8_t **value,size_t *valuelen) const; +#endif // RTP_SUPPORT_SDESPRIV +private: + int SetNonPrivateItem(int itemno,const uint8_t *s,size_t l) { if (l > RTCP_SDES_MAXITEMLENGTH) return ERR_RTP_SDES_LENGTHTOOBIG; return nonprivateitems[itemno].SetInfo(s,l); } + uint8_t *GetNonPrivateItem(int itemno,size_t *len) const { return nonprivateitems[itemno].GetInfo(len); } + + class SDESItem : public RTPMemoryObject + { + public: + SDESItem(RTPMemoryManager *mgr = 0) : RTPMemoryObject(mgr) + { + str = 0; + length = 0; + } + void SetMemoryManager(RTPMemoryManager *mgr) + { + RTPMemoryObject::SetMemoryManager(mgr); + } + ~SDESItem() + { + if (str) + RTPDeleteByteArray(str,GetMemoryManager()); + } + uint8_t *GetInfo(size_t *len) const { *len = length; return str; } + int SetInfo(const uint8_t *s,size_t len) { return SetString(&str,&length,s,len); } + protected: + int SetString(uint8_t **dest,size_t *destlen,const uint8_t *s,size_t len) + { + if (len <= 0) + { + if (*dest) + RTPDeleteByteArray((*dest),GetMemoryManager()); + *dest = 0; + *destlen = 0; + } + else + { + len = (len>RTCP_SDES_MAXITEMLENGTH)?RTCP_SDES_MAXITEMLENGTH:len; + uint8_t *str2 = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_SDESITEM) uint8_t[len]; + if (str2 == 0) + return ERR_RTP_OUTOFMEM; + memcpy(str2,s,len); + *destlen = len; + if (*dest) + RTPDeleteByteArray((*dest),GetMemoryManager()); + *dest = str2; + } + return 0; + } + private: + uint8_t *str; + size_t length; + }; + + SDESItem nonprivateitems[RTCP_SDES_NUMITEMS_NONPRIVATE]; + +#ifdef RTP_SUPPORT_SDESPRIV + class SDESPrivateItem : public SDESItem + { + public: + SDESPrivateItem(RTPMemoryManager *mgr) : SDESItem(mgr) + { + prefixlen = 0; + prefix = 0; + } + ~SDESPrivateItem() + { + if (prefix) + RTPDeleteByteArray(prefix,GetMemoryManager()); + } + uint8_t *GetPrefix(size_t *len) const { *len = prefixlen; return prefix; } + int SetPrefix(const uint8_t *s,size_t len) { return SetString(&prefix,&prefixlen,s,len); } + private: + uint8_t *prefix; + size_t prefixlen; + }; + + std::list privitems; + std::list::const_iterator curitem; +#endif // RTP_SUPPORT_SDESPRIV +}; + +} // end namespace + +#endif // RTCPSDESINFO_H + diff --git a/src/libs/jrtplib/src/rtcpsdespacket.cpp b/src/libs/jrtplib/src/rtcpsdespacket.cpp new file mode 100644 index 00000000..1b90e6a7 --- /dev/null +++ b/src/libs/jrtplib/src/rtcpsdespacket.cpp @@ -0,0 +1,236 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtcpsdespacket.h" +#ifdef RTPDEBUG + #include + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTCPSDESPacket::RTCPSDESPacket(uint8_t *data,size_t datalength) + : RTCPPacket(SDES,data,datalength) +{ + knownformat = false; + currentchunk = 0; + itemoffset = 0; + curchunknum = 0; + + RTCPCommonHeader *hdr = (RTCPCommonHeader *)data; + size_t len = datalength; + + if (hdr->padding) + { + uint8_t padcount = data[datalength-1]; + if ((padcount & 0x03) != 0) // not a multiple of four! (see rfc 3550 p 37) + return; + if (((size_t)padcount) >= len) + return; + len -= (size_t)padcount; + } + + if (hdr->count == 0) + { + if (len != sizeof(RTCPCommonHeader)) + return; + } + else + { + int ssrccount = (int)(hdr->count); + uint8_t *chunk; + int chunkoffset; + + if (len < sizeof(RTCPCommonHeader)) + return; + + len -= sizeof(RTCPCommonHeader); + chunk = data+sizeof(RTCPCommonHeader); + + while ((ssrccount > 0) && (len > 0)) + { + chunkoffset = 0; + + if (len < (sizeof(uint32_t)*2)) // chunk must contain at least a SSRC identifier + return; // and a (possibly empty) item + + len -= sizeof(uint32_t); + chunkoffset = sizeof(uint32_t); + + bool done = false; + while (!done) + { + if (len < 1) // at least a zero byte (end of item list) should be there + return; + + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(chunk+chunkoffset); + if (sdeshdr->sdesid == 0) // end of item list + { + len--; + chunkoffset++; + + size_t r = (chunkoffset&0x03); + if (r != 0) + { + size_t addoffset = 4-r; + + if (addoffset > len) + return; + len -= addoffset; + chunkoffset += addoffset; + } + done = true; + } + else + { + if (len < sizeof(RTCPSDESHeader)) + return; + + len -= sizeof(RTCPSDESHeader); + chunkoffset += sizeof(RTCPSDESHeader); + + size_t itemlen = (size_t)(sdeshdr->length); + if (itemlen > len) + return; + + len -= itemlen; + chunkoffset += itemlen; + } + } + + ssrccount--; + chunk += chunkoffset; + } + + // check for remaining bytes + if (len > 0) + return; + if (ssrccount > 0) + return; + } + + knownformat = true; +} + +#ifdef RTPDEBUG +void RTCPSDESPacket::Dump() +{ + RTCPPacket::Dump(); + if (!IsKnownFormat()) + { + std::cout << " Unknown format" << std::endl; + return; + } + if (!GotoFirstChunk()) + { + std::cout << " No chunks present" << std::endl; + return; + } + + do + { + std::cout << " SDES Chunk for SSRC: " << GetChunkSSRC() << std::endl; + if (!GotoFirstItem()) + std::cout << " No items found" << std::endl; + else + { + do + { + std::cout << " "; + switch (GetItemType()) + { + case None: + std::cout << "None "; + break; + case CNAME: + std::cout << "CNAME "; + break; + case NAME: + std::cout << "NAME "; + break; + case EMAIL: + std::cout << "EMAIL "; + break; + case PHONE: + std::cout << "PHONE "; + break; + case LOC: + std::cout << "LOC "; + break; + case TOOL: + std::cout << "TOOL "; + break; + case NOTE: + std::cout << "NOTE "; + break; + case PRIV: + std::cout << "PRIV "; + break; + case Unknown: + default: + std::cout << "Unknown "; + } + + std::cout << "Length: " << GetItemLength() << std::endl; + + if (GetItemType() != PRIV) + { + char str[1024]; + memcpy(str,GetItemData(),GetItemLength()); + str[GetItemLength()] = 0; + std::cout << " Value: " << str << std::endl; + } +#ifdef RTP_SUPPORT_SDESPRIV + else // PRIV item + { + char str[1024]; + memcpy(str,GetPRIVPrefixData(),GetPRIVPrefixLength()); + str[GetPRIVPrefixLength()] = 0; + std::cout << " Prefix: " << str << std::endl; + std::cout << " Length: " << GetPRIVPrefixLength() << std::endl; + memcpy(str,GetPRIVValueData(),GetPRIVValueLength()); + str[GetPRIVValueLength()] = 0; + std::cout << " Value: " << str << std::endl; + std::cout << " Length: " << GetPRIVValueLength() << std::endl; + } +#endif // RTP_SUPPORT_SDESPRIV + } while (GotoNextItem()); + } + } while (GotoNextChunk()); +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtcpsdespacket.h b/src/libs/jrtplib/src/rtcpsdespacket.h new file mode 100644 index 00000000..da0aaf82 --- /dev/null +++ b/src/libs/jrtplib/src/rtcpsdespacket.h @@ -0,0 +1,386 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtcpsdespacket.h + */ + +#ifndef RTCPSDESPACKET_H + +#define RTCPSDESPACKET_H + +#include "rtpconfig.h" +#include "rtcppacket.h" +#include "rtpstructs.h" +#include "rtpdefines.h" +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + #include +#endif // WIN32 + +namespace jrtplib +{ + + class RTCPCompoundPacket; + +/** Describes an RTCP source description packet. */ +class JRTPLIB_IMPORTEXPORT RTCPSDESPacket : public RTCPPacket +{ +public: + /** Identifies the type of an SDES item. */ + enum ItemType + { + None, /**< Used when the iteration over the items has finished. */ + CNAME, /**< Used for a CNAME (canonical name) item. */ + NAME, /**< Used for a NAME item. */ + EMAIL, /**< Used for an EMAIL item. */ + PHONE, /**< Used for a PHONE item. */ + LOC, /**< Used for a LOC (location) item. */ + TOOL, /**< Used for a TOOL item. */ + NOTE, /**< Used for a NOTE item. */ + PRIV, /**< Used for a PRIV item. */ + Unknown /**< Used when there is an item present, but the type is not recognized. */ + }; + + /** Creates an instance based on the data in \c data with length \c datalen. + * Creates an instance based on the data in \c data with length \c datalen. Since the \c data pointer + * is referenced inside the class (no copy of the data is made) one must make sure that the memory it + * points to is valid as long as the class instance exists. + */ + RTCPSDESPacket(uint8_t *data,size_t datalen); + ~RTCPSDESPacket() { } + + /** Returns the number of SDES chunks in the SDES packet. + * Returns the number of SDES chunks in the SDES packet. Each chunk has its own SSRC identifier. + */ + int GetChunkCount() const; + + /** Starts the iteration over the chunks. + * Starts the iteration. If no SDES chunks are present, the function returns \c false. Otherwise, + * it returns \c true and sets the current chunk to be the first chunk. + */ + bool GotoFirstChunk(); + + /** Sets the current chunk to the next available chunk. + * Sets the current chunk to the next available chunk. If no next chunk is present, this function returns + * \c false, otherwise it returns \c true. + */ + bool GotoNextChunk(); + + /** Returns the SSRC identifier of the current chunk. */ + uint32_t GetChunkSSRC() const; + + /** Starts the iteration over the SDES items in the current chunk. + * Starts the iteration over the SDES items in the current chunk. If no SDES items are + * present, the function returns \c false. Otherwise, the function sets the current item + * to be the first one and returns \c true. + */ + bool GotoFirstItem(); + + /** Advances the iteration to the next item in the current chunk. + * If there's another item in the chunk, the current item is set to be the next one and the function + * returns \c true. Otherwise, the function returns \c false. + */ + bool GotoNextItem(); + + /** Returns the SDES item type of the current item in the current chunk. */ + ItemType GetItemType() const; + + /** Returns the item length of the current item in the current chunk. */ + size_t GetItemLength() const; + + /** Returns the item data of the current item in the current chunk. */ + uint8_t *GetItemData(); + +#ifdef RTP_SUPPORT_SDESPRIV + /** If the current item is an SDES PRIV item, this function returns the length of the + * prefix string of the private item. + */ + size_t GetPRIVPrefixLength() const; + + /** If the current item is an SDES PRIV item, this function returns actual data of the + * prefix string. + */ + uint8_t *GetPRIVPrefixData(); + + /** If the current item is an SDES PRIV item, this function returns the length of the + * value string of the private item. + */ + size_t GetPRIVValueLength() const; + + /** If the current item is an SDES PRIV item, this function returns actual value data of the + * private item. + */ + uint8_t *GetPRIVValueData(); +#endif // RTP_SUPPORT_SDESPRIV + +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG +private: + uint8_t *currentchunk; + int curchunknum; + size_t itemoffset; +}; + +inline int RTCPSDESPacket::GetChunkCount() const +{ + if (!knownformat) + return 0; + RTCPCommonHeader *hdr = (RTCPCommonHeader *)data; + return ((int)hdr->count); +} + +inline bool RTCPSDESPacket::GotoFirstChunk() +{ + if (GetChunkCount() == 0) + { + currentchunk = 0; + return false; + } + currentchunk = data+sizeof(RTCPCommonHeader); + curchunknum = 1; + itemoffset = sizeof(uint32_t); + return true; +} + +inline bool RTCPSDESPacket::GotoNextChunk() +{ + if (!knownformat) + return false; + if (currentchunk == 0) + return false; + if (curchunknum == GetChunkCount()) + return false; + + size_t offset = sizeof(uint32_t); + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(currentchunk+sizeof(uint32_t)); + + while (sdeshdr->sdesid != 0) + { + offset += sizeof(RTCPSDESHeader); + offset += (size_t)(sdeshdr->length); + sdeshdr = (RTCPSDESHeader *)(currentchunk+offset); + } + offset++; // for the zero byte + if ((offset&0x03) != 0) + offset += (4-(offset&0x03)); + currentchunk += offset; + curchunknum++; + itemoffset = sizeof(uint32_t); + return true; +} + +inline uint32_t RTCPSDESPacket::GetChunkSSRC() const +{ + if (!knownformat) + return 0; + if (currentchunk == 0) + return 0; + uint32_t *ssrc = (uint32_t *)currentchunk; + return ntohl(*ssrc); +} + +inline bool RTCPSDESPacket::GotoFirstItem() +{ + if (!knownformat) + return false; + if (currentchunk == 0) + return false; + itemoffset = sizeof(uint32_t); + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(currentchunk+itemoffset); + if (sdeshdr->sdesid == 0) + return false; + return true; +} + +inline bool RTCPSDESPacket::GotoNextItem() +{ + if (!knownformat) + return false; + if (currentchunk == 0) + return false; + + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(currentchunk+itemoffset); + if (sdeshdr->sdesid == 0) + return false; + + size_t offset = itemoffset; + offset += sizeof(RTCPSDESHeader); + offset += (size_t)(sdeshdr->length); + sdeshdr = (RTCPSDESHeader *)(currentchunk+offset); + if (sdeshdr->sdesid == 0) + return false; + itemoffset = offset; + return true; +} + +inline RTCPSDESPacket::ItemType RTCPSDESPacket::GetItemType() const +{ + if (!knownformat) + return None; + if (currentchunk == 0) + return None; + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(currentchunk+itemoffset); + switch (sdeshdr->sdesid) + { + case 0: + return None; + case RTCP_SDES_ID_CNAME: + return CNAME; + case RTCP_SDES_ID_NAME: + return NAME; + case RTCP_SDES_ID_EMAIL: + return EMAIL; + case RTCP_SDES_ID_PHONE: + return PHONE; + case RTCP_SDES_ID_LOCATION: + return LOC; + case RTCP_SDES_ID_TOOL: + return TOOL; + case RTCP_SDES_ID_NOTE: + return NOTE; + case RTCP_SDES_ID_PRIVATE: + return PRIV; + default: + return Unknown; + } + return Unknown; +} + +inline size_t RTCPSDESPacket::GetItemLength() const +{ + if (!knownformat) + return None; + if (currentchunk == 0) + return None; + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(currentchunk+itemoffset); + if (sdeshdr->sdesid == 0) + return 0; + return (size_t)(sdeshdr->length); +} + +inline uint8_t *RTCPSDESPacket::GetItemData() +{ + if (!knownformat) + return 0; + if (currentchunk == 0) + return 0; + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(currentchunk+itemoffset); + if (sdeshdr->sdesid == 0) + return 0; + return (currentchunk+itemoffset+sizeof(RTCPSDESHeader)); +} + +#ifdef RTP_SUPPORT_SDESPRIV +inline size_t RTCPSDESPacket::GetPRIVPrefixLength() const +{ + if (!knownformat) + return 0; + if (currentchunk == 0) + return 0; + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(currentchunk+itemoffset); + if (sdeshdr->sdesid != RTCP_SDES_ID_PRIVATE) + return 0; + if (sdeshdr->length == 0) + return 0; + uint8_t *preflen = currentchunk+itemoffset+sizeof(RTCPSDESHeader); + size_t prefixlength = (size_t)(*preflen); + if (prefixlength > (size_t)((sdeshdr->length)-1)) + return 0; + return prefixlength; +} + +inline uint8_t *RTCPSDESPacket::GetPRIVPrefixData() +{ + if (!knownformat) + return 0; + if (currentchunk == 0) + return 0; + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(currentchunk+itemoffset); + if (sdeshdr->sdesid != RTCP_SDES_ID_PRIVATE) + return 0; + if (sdeshdr->length == 0) + return 0; + uint8_t *preflen = currentchunk+itemoffset+sizeof(RTCPSDESHeader); + size_t prefixlength = (size_t)(*preflen); + if (prefixlength > (size_t)((sdeshdr->length)-1)) + return 0; + if (prefixlength == 0) + return 0; + return (currentchunk+itemoffset+sizeof(RTCPSDESHeader)+1); +} + +inline size_t RTCPSDESPacket::GetPRIVValueLength() const +{ + if (!knownformat) + return 0; + if (currentchunk == 0) + return 0; + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(currentchunk+itemoffset); + if (sdeshdr->sdesid != RTCP_SDES_ID_PRIVATE) + return 0; + if (sdeshdr->length == 0) + return 0; + uint8_t *preflen = currentchunk+itemoffset+sizeof(RTCPSDESHeader); + size_t prefixlength = (size_t)(*preflen); + if (prefixlength > (size_t)((sdeshdr->length)-1)) + return 0; + return ((size_t)(sdeshdr->length))-prefixlength-1; +} + +inline uint8_t *RTCPSDESPacket::GetPRIVValueData() +{ + if (!knownformat) + return 0; + if (currentchunk == 0) + return 0; + RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(currentchunk+itemoffset); + if (sdeshdr->sdesid != RTCP_SDES_ID_PRIVATE) + return 0; + if (sdeshdr->length == 0) + return 0; + uint8_t *preflen = currentchunk+itemoffset+sizeof(RTCPSDESHeader); + size_t prefixlength = (size_t)(*preflen); + if (prefixlength > (size_t)((sdeshdr->length)-1)) + return 0; + size_t valuelen = ((size_t)(sdeshdr->length))-prefixlength-1; + if (valuelen == 0) + return 0; + return (currentchunk+itemoffset+sizeof(RTCPSDESHeader)+1+prefixlength); +} + +#endif // RTP_SUPPORT_SDESPRIV + +} // end namespace + +#endif // RTCPSDESPACKET_H + diff --git a/src/libs/jrtplib/src/rtcpsrpacket.cpp b/src/libs/jrtplib/src/rtcpsrpacket.cpp new file mode 100644 index 00000000..c6e74407 --- /dev/null +++ b/src/libs/jrtplib/src/rtcpsrpacket.cpp @@ -0,0 +1,106 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtcpsrpacket.h" +#ifdef RTPDEBUG + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTCPSRPacket::RTCPSRPacket(uint8_t *data,size_t datalength) + : RTCPPacket(SR,data,datalength) +{ + knownformat = false; + + RTCPCommonHeader *hdr; + size_t len = datalength; + size_t expectedlength; + + hdr = (RTCPCommonHeader *)data; + if (hdr->padding) + { + uint8_t padcount = data[datalength-1]; + if ((padcount & 0x03) != 0) // not a multiple of four! (see rfc 3550 p 37) + return; + if (((size_t)padcount) >= len) + return; + len -= (size_t)padcount; + } + + expectedlength = sizeof(RTCPCommonHeader)+sizeof(uint32_t)+sizeof(RTCPSenderReport); + expectedlength += sizeof(RTCPReceiverReport)*((int)hdr->count); + + if (expectedlength != len) + return; + + knownformat = true; +} + +#ifdef RTPDEBUG +void RTCPSRPacket::Dump() +{ + RTCPPacket::Dump(); + if (!IsKnownFormat()) + std::cout << " Unknown format" << std::endl; + else + { + int num = GetReceptionReportCount(); + int i; + RTPNTPTime t = GetNTPTimestamp(); + + std::cout << " SSRC of sender: " << GetSenderSSRC() << std::endl; + std::cout << " Sender info:" << std::endl; + std::cout << " NTP timestamp: " << t.GetMSW() << ":" << t.GetLSW() << std::endl; + std::cout << " RTP timestamp: " << GetRTPTimestamp() << std::endl; + std::cout << " Packet count: " << GetSenderPacketCount() << std::endl; + std::cout << " Octet count: " << GetSenderOctetCount() << std::endl; + for (i = 0 ; i < num ; i++) + { + std::cout << " Report block " << i << std::endl; + std::cout << " SSRC: " << GetSSRC(i) << std::endl; + std::cout << " Fraction lost: " << (uint32_t)GetFractionLost(i) << std::endl; + std::cout << " Packets lost: " << GetLostPacketCount(i) << std::endl; + std::cout << " Seq. nr.: " << GetExtendedHighestSequenceNumber(i) << std::endl; + std::cout << " Jitter: " << GetJitter(i) << std::endl; + std::cout << " LSR: " << GetLSR(i) << std::endl; + std::cout << " DLSR: " << GetDLSR(i) << std::endl; + } + } +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtcpsrpacket.h b/src/libs/jrtplib/src/rtcpsrpacket.h new file mode 100644 index 00000000..4e0c1429 --- /dev/null +++ b/src/libs/jrtplib/src/rtcpsrpacket.h @@ -0,0 +1,252 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtcpsrpacket.h + */ + +#ifndef RTCPSRPACKET_H + +#define RTCPSRPACKET_H + +#include "rtpconfig.h" +#include "rtcppacket.h" +#include "rtptimeutilities.h" +#include "rtpstructs.h" +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + #include +#endif // WIN32 + +namespace jrtplib +{ + +class RTCPCompoundPacket; + +/** Describes an RTCP sender report packet. */ +class JRTPLIB_IMPORTEXPORT RTCPSRPacket : public RTCPPacket +{ +public: + /** Creates an instance based on the data in \c data with length \c datalen. + * Creates an instance based on the data in \c data with length \c datalen. Since the \c data pointer + * is referenced inside the class (no copy of the data is made) one must make sure that the memory it + * points to is valid as long as the class instance exists. + */ + RTCPSRPacket(uint8_t *data,size_t datalength); + ~RTCPSRPacket() { } + + /** Returns the SSRC of the participant who sent this packet. */ + uint32_t GetSenderSSRC() const; + + /** Returns the NTP timestamp contained in the sender report. */ + RTPNTPTime GetNTPTimestamp() const; + + /** Returns the RTP timestamp contained in the sender report. */ + uint32_t GetRTPTimestamp() const; + + /** Returns the sender's packet count contained in the sender report. */ + uint32_t GetSenderPacketCount() const; + + /** Returns the sender's octet count contained in the sender report. */ + uint32_t GetSenderOctetCount() const; + + /** Returns the number of reception report blocks present in this packet. */ + int GetReceptionReportCount() const; + + /** Returns the SSRC of the reception report block described by \c index which may have a value + * from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + uint32_t GetSSRC(int index) const; + + /** Returns the `fraction lost' field of the reception report described by \c index which may have + * a value from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + uint8_t GetFractionLost(int index) const; + + /** Returns the number of lost packets in the reception report block described by \c index which may have + * a value from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + int32_t GetLostPacketCount(int index) const; + + /** Returns the extended highest sequence number of the reception report block described by \c index which may have + * a value from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + uint32_t GetExtendedHighestSequenceNumber(int index) const; + + /** Returns the jitter field of the reception report block described by \c index which may have + * a value from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + uint32_t GetJitter(int index) const; + + /** Returns the LSR field of the reception report block described by \c index which may have + * a value from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + uint32_t GetLSR(int index) const; + + /** Returns the DLSR field of the reception report block described by \c index which may have + * a value from 0 to GetReceptionReportCount()-1 (note that no check is performed to see if \c index is + * valid). + */ + uint32_t GetDLSR(int index) const; + +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG +private: + RTCPReceiverReport *GotoReport(int index) const; +}; + +inline uint32_t RTCPSRPacket::GetSenderSSRC() const +{ + if (!knownformat) + return 0; + + uint32_t *ssrcptr = (uint32_t *)(data+sizeof(RTCPCommonHeader)); + return ntohl(*ssrcptr); +} + +inline RTPNTPTime RTCPSRPacket::GetNTPTimestamp() const +{ + if (!knownformat) + return RTPNTPTime(0,0); + + RTCPSenderReport *sr = (RTCPSenderReport *)(data+sizeof(RTCPCommonHeader)+sizeof(uint32_t)); + return RTPNTPTime(ntohl(sr->ntptime_msw),ntohl(sr->ntptime_lsw)); +} + +inline uint32_t RTCPSRPacket::GetRTPTimestamp() const +{ + if (!knownformat) + return 0; + RTCPSenderReport *sr = (RTCPSenderReport *)(data+sizeof(RTCPCommonHeader)+sizeof(uint32_t)); + return ntohl(sr->rtptimestamp); +} + +inline uint32_t RTCPSRPacket::GetSenderPacketCount() const +{ + if (!knownformat) + return 0; + RTCPSenderReport *sr = (RTCPSenderReport *)(data+sizeof(RTCPCommonHeader)+sizeof(uint32_t)); + return ntohl(sr->packetcount); +} + +inline uint32_t RTCPSRPacket::GetSenderOctetCount() const +{ + if (!knownformat) + return 0; + RTCPSenderReport *sr = (RTCPSenderReport *)(data+sizeof(RTCPCommonHeader)+sizeof(uint32_t)); + return ntohl(sr->octetcount); +} + +inline int RTCPSRPacket::GetReceptionReportCount() const +{ + if (!knownformat) + return 0; + RTCPCommonHeader *hdr = (RTCPCommonHeader *)data; + return ((int)hdr->count); +} + +inline RTCPReceiverReport *RTCPSRPacket::GotoReport(int index) const +{ + RTCPReceiverReport *r = (RTCPReceiverReport *)(data+sizeof(RTCPCommonHeader)+sizeof(uint32_t)+sizeof(RTCPSenderReport)+index*sizeof(RTCPReceiverReport)); + return r; +} + +inline uint32_t RTCPSRPacket::GetSSRC(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + return ntohl(r->ssrc); +} + +inline uint8_t RTCPSRPacket::GetFractionLost(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + return r->fractionlost; +} + +inline int32_t RTCPSRPacket::GetLostPacketCount(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + uint32_t count = ((uint32_t)r->packetslost[2])|(((uint32_t)r->packetslost[1])<<8)|(((uint32_t)r->packetslost[0])<<16); + if ((count&0x00800000) != 0) // test for negative number + count |= 0xFF000000; + int32_t *count2 = (int32_t *)(&count); + return (*count2); +} + +inline uint32_t RTCPSRPacket::GetExtendedHighestSequenceNumber(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + return ntohl(r->exthighseqnr); +} + +inline uint32_t RTCPSRPacket::GetJitter(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + return ntohl(r->jitter); +} + +inline uint32_t RTCPSRPacket::GetLSR(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + return ntohl(r->lsr); +} + +inline uint32_t RTCPSRPacket::GetDLSR(int index) const +{ + if (!knownformat) + return 0; + RTCPReceiverReport *r = GotoReport(index); + return ntohl(r->dlsr); +} + +} // end namespace + +#endif // RTCPSRPACKET_H + diff --git a/src/libs/jrtplib/src/rtcpunknownpacket.h b/src/libs/jrtplib/src/rtcpunknownpacket.h new file mode 100644 index 00000000..69952c88 --- /dev/null +++ b/src/libs/jrtplib/src/rtcpunknownpacket.h @@ -0,0 +1,73 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtcpunknownpacket.h + */ + +#ifndef RTCPUNKNOWNPACKET_H + +#define RTCPUNKNOWNPACKET_H + +#include "rtpconfig.h" +#include "rtcppacket.h" + +namespace jrtplib +{ + +class RTCPCompoundPacket; + +/** Describes an RTCP packet of unknown type. + * Describes an RTCP packet of unknown type. This class doesn't have any extra member functions besides + * the ones it inherited. Note that since an unknown packet type doesn't have any format to check + * against, the IsKnownFormat function will trivially return \c true. + */ +class JRTPLIB_IMPORTEXPORT RTCPUnknownPacket : public RTCPPacket +{ +public: + /** Creates an instance based on the data in \c data with length \c datalen. + * Creates an instance based on the data in \c data with length \c datalen. Since the \c data pointer + * is referenced inside the class (no copy of the data is made) one must make sure that the memory it + * points to is valid as long as the class instance exists. + */ + RTCPUnknownPacket(uint8_t *data,size_t datalen) : RTCPPacket(Unknown,data,datalen) + { + // Since we don't expect a format, we'll trivially put knownformat = true + knownformat = true; + } + ~RTCPUnknownPacket() { } +}; + +} // end namespace + +#endif // RTCPUNKNOWNPACKET_H + diff --git a/src/libs/jrtplib/src/rtpaddress.h b/src/libs/jrtplib/src/rtpaddress.h new file mode 100644 index 00000000..0cef0113 --- /dev/null +++ b/src/libs/jrtplib/src/rtpaddress.h @@ -0,0 +1,99 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpaddress.h + */ + +#ifndef RTPADDRESS_H + +#define RTPADDRESS_H + +#include "rtpconfig.h" +#include + +namespace jrtplib +{ + +class RTPMemoryManager; + +/** This class is an abstract class which is used to specify destinations, multicast groups etc. */ +class JRTPLIB_IMPORTEXPORT RTPAddress +{ +public: + /** Identifies the actual implementation being used. */ + enum AddressType + { + IPv4Address, /**< Used by the UDP over IPv4 transmitter. */ + IPv6Address, /**< Used by the UDP over IPv6 transmitter. */ + ByteAddress, /**< A very general type of address, consisting of a port number and a number of bytes representing the host address. */ + UserDefinedAddress /**< Can be useful for a user-defined transmitter. */ + }; + + /** Returns the type of address the actual implementation represents. */ + AddressType GetAddressType() const { return addresstype; } + + /** Creates a copy of the RTPAddress instance. + * Creates a copy of the RTPAddress instance. If \c mgr is not NULL, the + * corresponding memory manager will be used to allocate the memory for the address + * copy. + */ + virtual RTPAddress *CreateCopy(RTPMemoryManager *mgr) const = 0; + + /** Checks if the address \c addr is the same address as the one this instance represents. + * Checks if the address \c addr is the same address as the one this instance represents. + * Implementations must be able to handle a NULL argument. + */ + virtual bool IsSameAddress(const RTPAddress *addr) const = 0; + + /** Checks if the address \c addr represents the same host as this instance. + * Checks if the address \c addr represents the same host as this instance. Implementations + * must be able to handle a NULL argument. + */ + virtual bool IsFromSameHost(const RTPAddress *addr) const = 0; + +#ifdef RTPDEBUG + virtual std::string GetAddressString() const = 0; +#endif // RTPDEBUG + + virtual ~RTPAddress() { } +protected: + // only allow subclasses to be created + RTPAddress(const AddressType t) : addresstype(t) { } +private: + const AddressType addresstype; +}; + +} // end namespace + +#endif // RTPADDRESS_H + diff --git a/src/libs/jrtplib/src/rtpbyteaddress.cpp b/src/libs/jrtplib/src/rtpbyteaddress.cpp new file mode 100644 index 00000000..2251a942 --- /dev/null +++ b/src/libs/jrtplib/src/rtpbyteaddress.cpp @@ -0,0 +1,105 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpbyteaddress.h" +#include "rtpmemorymanager.h" +#ifdef RTPDEBUG + #include "rtpdefines.h" + #include +#endif // RTPDEBUG + +namespace jrtplib +{ + +bool RTPByteAddress::IsSameAddress(const RTPAddress *addr) const +{ + if (addr == 0) + return false; + if (addr->GetAddressType() != ByteAddress) + return false; + + const RTPByteAddress *addr2 = (const RTPByteAddress *)addr; + + if (addr2->addresslength != addresslength) + return false; + if (addresslength == 0 || (memcmp(hostaddress, addr2->hostaddress, addresslength) == 0)) + { + if (port == addr2->port) + return true; + } + return false; +} + +bool RTPByteAddress::IsFromSameHost(const RTPAddress *addr) const +{ + if (addr == 0) + return false; + if (addr->GetAddressType() != ByteAddress) + return false; + + const RTPByteAddress *addr2 = (const RTPByteAddress *)addr; + + if (addr2->addresslength != addresslength) + return false; + if (addresslength == 0 || (memcmp(hostaddress, addr2->hostaddress, addresslength) == 0)) + return true; + return false; +} + +RTPAddress *RTPByteAddress::CreateCopy(RTPMemoryManager *mgr) const +{ + RTPByteAddress *a = RTPNew(mgr, RTPMEM_TYPE_CLASS_RTPADDRESS) RTPByteAddress(hostaddress, addresslength, port); + return a; +} + +#ifdef RTPDEBUG +std::string RTPByteAddress::GetAddressString() const +{ + char str[16]; + std::string s; + + for (int i = 0 ; i < addresslength ; i++) + { + RTP_SNPRINTF(str, 16, "%02X", (int)hostaddress[i]); + s += std::string(str); + } + s += std::string(":"); + + RTP_SNPRINTF(str, 16, "%d",(int)port); + s += std::string(str); + + return s; +} + +#endif // RTPDEBUG + +} // end namespace diff --git a/src/libs/jrtplib/src/rtpbyteaddress.h b/src/libs/jrtplib/src/rtpbyteaddress.h new file mode 100644 index 00000000..53353a5e --- /dev/null +++ b/src/libs/jrtplib/src/rtpbyteaddress.h @@ -0,0 +1,93 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpbyteaddress.h + */ + +#ifndef RTPBYTEADDRESS_H + +#define RTPBYTEADDRESS_H + +#include "rtpconfig.h" +#include "rtpaddress.h" +#include "rtptypes.h" +#include + +#define RTPBYTEADDRESS_MAXLENGTH 128 + +namespace jrtplib +{ + +class RTPMemoryManager; + +/** A very general kind of address consisting of a port number and a number of bytes describing the host address. + * A very general kind of address, consisting of a port number and a number of bytes describing the host address. + */ +class JRTPLIB_IMPORTEXPORT RTPByteAddress : public RTPAddress +{ +public: + /** Creates an instance of the class using \c addrlen bytes of \c hostaddress as host identification, + * and using \c port as the port number. */ + RTPByteAddress(const uint8_t hostaddress[RTPBYTEADDRESS_MAXLENGTH], size_t addrlen, uint16_t port = 0) : RTPAddress(ByteAddress) { if (addrlen > RTPBYTEADDRESS_MAXLENGTH) addrlen = RTPBYTEADDRESS_MAXLENGTH; memcpy(RTPByteAddress::hostaddress, hostaddress, addrlen); RTPByteAddress::addresslength = addrlen; RTPByteAddress::port = port; } + + /** Sets the host address to the first \c addrlen bytes of \c hostaddress. */ + void SetHostAddress(const uint8_t hostaddress[RTPBYTEADDRESS_MAXLENGTH], size_t addrlen) { if (addrlen > RTPBYTEADDRESS_MAXLENGTH) addrlen = RTPBYTEADDRESS_MAXLENGTH; memcpy(RTPByteAddress::hostaddress, hostaddress, addrlen); RTPByteAddress::addresslength = addrlen; } + + /** Sets the port number to \c port. */ + void SetPort(uint16_t port) { RTPByteAddress::port = port; } + + /** Returns a pointer to the stored host address. */ + const uint8_t *GetHostAddress() const { return hostaddress; } + + /** Returns the length in bytes of the stored host address. */ + size_t GetHostAddressLength() const { return addresslength; } + + /** Returns the port number stored in this instance. */ + uint16_t GetPort() const { return port; } + + RTPAddress *CreateCopy(RTPMemoryManager *mgr) const; + bool IsSameAddress(const RTPAddress *addr) const; + bool IsFromSameHost(const RTPAddress *addr) const; +#ifdef RTPDEBUG + std::string GetAddressString() const; +#endif // RTPDEBUG +private: + uint8_t hostaddress[RTPBYTEADDRESS_MAXLENGTH]; + size_t addresslength; + uint16_t port; +}; + +} // end namespace + +#endif // RTPBYTEADDRESS_H + diff --git a/src/libs/jrtplib/src/rtpcollisionlist.cpp b/src/libs/jrtplib/src/rtpcollisionlist.cpp new file mode 100644 index 00000000..cd8e1908 --- /dev/null +++ b/src/libs/jrtplib/src/rtpcollisionlist.cpp @@ -0,0 +1,130 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpcollisionlist.h" +#include "rtperrors.h" +#include "rtpmemorymanager.h" +#ifdef RTPDEBUG + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTPCollisionList::RTPCollisionList(RTPMemoryManager *mgr) : RTPMemoryObject(mgr) +{ +#if (defined(WIN32) || defined(_WIN32_WCE)) + timeinit.Dummy(); +#endif // WIN32 || _WIN32_WCE +} + +void RTPCollisionList::Clear() +{ + std::list::iterator it; + + for (it = addresslist.begin() ; it != addresslist.end() ; it++) + RTPDelete((*it).addr,GetMemoryManager()); + addresslist.clear(); +} + +int RTPCollisionList::UpdateAddress(const RTPAddress *addr,const RTPTime &receivetime,bool *created) +{ + if (addr == 0) + return ERR_RTP_COLLISIONLIST_BADADDRESS; + + std::list::iterator it; + + for (it = addresslist.begin() ; it != addresslist.end() ; it++) + { + if (((*it).addr)->IsSameAddress(addr)) + { + (*it).recvtime = receivetime; + *created = false; + return 0; + } + } + + RTPAddress *newaddr = addr->CreateCopy(GetMemoryManager()); + if (newaddr == 0) + return ERR_RTP_OUTOFMEM; + + addresslist.push_back(AddressAndTime(newaddr,receivetime)); + *created = true; + return 0; +} + +bool RTPCollisionList::HasAddress(const RTPAddress *addr) const +{ + std::list::const_iterator it; + + for (it = addresslist.begin() ; it != addresslist.end() ; it++) + { + if (((*it).addr)->IsSameAddress(addr)) + return true; + } + + return false; +} + +void RTPCollisionList::Timeout(const RTPTime ¤ttime,const RTPTime &timeoutdelay) +{ + std::list::iterator it; + RTPTime checktime = currenttime; + checktime -= timeoutdelay; + + it = addresslist.begin(); + while(it != addresslist.end()) + { + if ((*it).recvtime < checktime) // timeout + { + RTPDelete((*it).addr,GetMemoryManager()); + it = addresslist.erase(it); + } + else + it++; + } +} + +#ifdef RTPDEBUG +void RTPCollisionList::Dump() +{ + std::list::const_iterator it; + + for (it = addresslist.begin() ; it != addresslist.end() ; it++) + std::cout << "Address: " << ((*it).addr)->GetAddressString() << "\tTime: " << (*it).recvtime.GetSeconds() << std::endl; +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtpcollisionlist.h b/src/libs/jrtplib/src/rtpcollisionlist.h new file mode 100644 index 00000000..812b2973 --- /dev/null +++ b/src/libs/jrtplib/src/rtpcollisionlist.h @@ -0,0 +1,95 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpcollisionlist.h + */ + +#ifndef RTPCOLLISIONLIST_H + +#define RTPCOLLISIONLIST_H + +#include "rtpconfig.h" +#include "rtpaddress.h" +#include "rtptimeutilities.h" +#include "rtpmemoryobject.h" +#include + +namespace jrtplib +{ + +class RTPAddress; + +/** This class represents a list of addresses from which SSRC collisions were detected. */ +class JRTPLIB_IMPORTEXPORT RTPCollisionList : public RTPMemoryObject +{ +public: + /** Constructs an instance, optionally installing a memory manager. */ + RTPCollisionList(RTPMemoryManager *mgr = 0); + ~RTPCollisionList() { Clear(); } + + /** Clears the list of addresses. */ + void Clear(); + + /** Updates the entry for address \c addr to indicate that a collision was detected at time \c receivetime. + * Updates the entry for address \c addr to indicate that a collision was detected at time \c receivetime. + * If the entry did not exist yet, the flag \c created is set to \c true, otherwise it is set to \c false. + */ + int UpdateAddress(const RTPAddress *addr,const RTPTime &receivetime,bool *created); + + /** Returns \c true} if the address \c addr appears in the list. */ + bool HasAddress(const RTPAddress *addr) const; + + /** Assuming that the current time is given by \c currenttime, this function times out entries which + * haven't been updated in the previous time interval specified by \c timeoutdelay. + */ + void Timeout(const RTPTime ¤ttime,const RTPTime &timeoutdelay); +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG +private: + class AddressAndTime + { + public: + AddressAndTime(RTPAddress *a,const RTPTime &t) : addr(a),recvtime(t) { } + + RTPAddress *addr; + RTPTime recvtime; + }; + + std::list addresslist; +}; + +} // end namespace + +#endif // RTPCOLLISIONLIST_H + diff --git a/src/libs/jrtplib/src/rtpconfig.h b/src/libs/jrtplib/src/rtpconfig.h new file mode 100644 index 00000000..8cab2918 --- /dev/null +++ b/src/libs/jrtplib/src/rtpconfig.h @@ -0,0 +1,76 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#ifndef RTPCONFIG_UNIX_H + +#define RTPCONFIG_UNIX_H + +#define JRTPLIB_IMPORT +#define JRTPLIB_EXPORT +#define JRTPLIB_IMPORTEXPORT + +//${RTP_HAVE_SYS_FILIO} + +//${RTP_HAVE_SYS_SOCKIO} + +//${RTP_ENDIAN} + +//${RTP_SOCKLENTYPE_UINT} + +//${RTP_HAVE_SOCKADDR_LEN} + +//${RTP_SUPPORT_IPV4MULTICAST} + +//${RTP_SUPPORT_THREAD} + +//${RTP_SUPPORT_SDESPRIV} + +//${RTP_SUPPORT_PROBATION} + +//${RTP_SUPPORT_GETLOGINR} + +#define RTP_SUPPORT_IPV6 + +//${RTP_SUPPORT_IPV6MULTICAST} + +//${RTP_SUPPORT_IFADDRS} + +#define RTP_SUPPORT_SENDAPP + +//${RTP_SUPPORT_MEMORYMANAGEMENT} + +#define RTP_SUPPORT_RTCPUNKNOWN + +#define RTP_DISABLE_INTERRUPT + +#endif // RTPCONFIG_UNIX_H + diff --git a/src/libs/jrtplib/src/rtpdebug.cpp b/src/libs/jrtplib/src/rtpdebug.cpp new file mode 100644 index 00000000..3496df6b --- /dev/null +++ b/src/libs/jrtplib/src/rtpdebug.cpp @@ -0,0 +1,178 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpconfig.h" + +#ifdef RTPDEBUG + +#include "rtptypes.h" +#include +#include +#include + +struct MemoryInfo +{ + void *ptr; + size_t size; + int lineno; + char *filename; + + MemoryInfo *next; +}; + +class MemoryTracker +{ +public: + MemoryTracker() { firstblock = NULL; } + ~MemoryTracker() + { + MemoryInfo *tmp; + int count = 0; + + printf("Checking for memory leaks...\n");fflush(stdout); + while(firstblock) + { + count++; + printf("Unfreed block %p of %d bytes (file '%s', line %d)\n",firstblock->ptr,(int)firstblock->size,firstblock->filename,firstblock->lineno);; + + tmp = firstblock->next; + + free(firstblock->ptr); + if (firstblock->filename) + free(firstblock->filename); + free(firstblock); + firstblock = tmp; + } + if (count == 0) + printf("No memory leaks found\n"); + else + printf("%d leaks found\n",count); + } + + MemoryInfo *firstblock; +}; + +static MemoryTracker memtrack; + +void *donew(size_t s,char filename[],int line) +{ + void *p; + MemoryInfo *meminf; + + p = malloc(s); + meminf = (MemoryInfo *)malloc(sizeof(MemoryInfo)); + + meminf->ptr = p; + meminf->size = s; + meminf->lineno = line; + meminf->filename = (char *)malloc(strlen(filename)+1); + strcpy(meminf->filename,filename); + meminf->next = memtrack.firstblock; + + memtrack.firstblock = meminf; + + return p; +} + +void dodelete(void *p) +{ + MemoryInfo *tmp,*tmpprev; + bool found; + + tmpprev = NULL; + tmp = memtrack.firstblock; + found = false; + while (tmp != NULL && !found) + { + if (tmp->ptr == p) + found = true; + else + { + tmpprev = tmp; + tmp = tmp->next; + } + } + if (!found) + { + printf("Couldn't free block %p!\n",p); + fflush(stdout); + } + else + { + MemoryInfo *n; + + fflush(stdout); + n = tmp->next; + free(tmp->ptr); + if (tmp->filename) + free(tmp->filename); + free(tmp); + + if (tmpprev) + tmpprev->next = n; + else + memtrack.firstblock = n; + } +} + +void *operator new(size_t s) +{ + return donew(s,"UNKNOWN FILE",0); +} + +void *operator new[](size_t s) +{ + return donew(s,"UNKNOWN FILE",0); +} + +void *operator new(size_t s,char filename[],int line) +{ + return donew(s,filename,line); +} + +void *operator new[](size_t s,char filename[],int line) +{ + return donew(s,filename,line); +} + +void operator delete(void *p) +{ + dodelete(p); +} + +void operator delete[](void *p) +{ + dodelete(p); +} + +#endif // RTPDEBUG + diff --git a/src/libs/jrtplib/src/rtpdebug.h b/src/libs/jrtplib/src/rtpdebug.h new file mode 100644 index 00000000..a0c7078f --- /dev/null +++ b/src/libs/jrtplib/src/rtpdebug.h @@ -0,0 +1,52 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#ifndef RTPDEBUG_H + +#define RTPDEBUG_H + +#include "rtpconfig.h" + +#ifdef RTPDEBUG + #include "rtptypes.h" + + void *operator new(size_t s,char filename[],int line); +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + void *operator new[](size_t s,char filename[],int line); + #define new new (__FILE__,__LINE__) +#else + #define new new (__FILE__,__LINE__) +#endif // WIN32 +#endif // RTPDEBUG + +#endif // RTPDEBUG_H + diff --git a/src/libs/jrtplib/src/rtpdefines.h b/src/libs/jrtplib/src/rtpdefines.h new file mode 100644 index 00000000..826311b7 --- /dev/null +++ b/src/libs/jrtplib/src/rtpdefines.h @@ -0,0 +1,86 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#ifndef RTPDEFINES_H + +#define RTPDEFINES_H + +#define RTP_VERSION 2 +#define RTP_MAXCSRCS 15 +#define RTP_MINPACKETSIZE 600 +#define RTP_DEFAULTPACKETSIZE 1400 +#define RTP_PROBATIONCOUNT 2 +#define RTP_MAXPRIVITEMS 256 +#define RTP_SENDERTIMEOUTMULTIPLIER 2 +#define RTP_BYETIMEOUTMULTIPLIER 1 +#define RTP_MEMBERTIMEOUTMULTIPLIER 5 +#define RTP_COLLISIONTIMEOUTMULTIPLIER 10 +#define RTP_NOTETTIMEOUTMULTIPLIER 25 +#define RTP_DEFAULTSESSIONBANDWIDTH 10000.0 + +#define RTP_RTCPTYPE_SR 200 +#define RTP_RTCPTYPE_RR 201 +#define RTP_RTCPTYPE_SDES 202 +#define RTP_RTCPTYPE_BYE 203 +#define RTP_RTCPTYPE_APP 204 + +#define RTCP_SDES_ID_CNAME 1 +#define RTCP_SDES_ID_NAME 2 +#define RTCP_SDES_ID_EMAIL 3 +#define RTCP_SDES_ID_PHONE 4 +#define RTCP_SDES_ID_LOCATION 5 +#define RTCP_SDES_ID_TOOL 6 +#define RTCP_SDES_ID_NOTE 7 +#define RTCP_SDES_ID_PRIVATE 8 +#define RTCP_SDES_NUMITEMS_NONPRIVATE 7 +#define RTCP_SDES_MAXITEMLENGTH 255 + +#define RTCP_BYE_MAXREASONLENGTH 255 +#define RTCP_DEFAULTMININTERVAL 5.0 +#define RTCP_DEFAULTBANDWIDTHFRACTION 0.05 +#define RTCP_DEFAULTSENDERFRACTION 0.25 +#define RTCP_DEFAULTHALFATSTARTUP true +#define RTCP_DEFAULTIMMEDIATEBYE true +#define RTCP_DEFAULTSRBYE true + +#if (defined(WIN32) || defined(_WIN32_WCE)) + #if (!defined(_WIN32_WCE)) && (defined(_MSC_VER) && _MSC_VER >= 1400 ) + #define RTP_SNPRINTF _snprintf_s + #else + #define RTP_SNPRINTF _snprintf + #endif +#else + #define RTP_SNPRINTF snprintf +#endif // WIN32 || _WIN32_WCE + +#endif // RTPDEFINES_H + diff --git a/src/libs/jrtplib/src/rtperrors.cpp b/src/libs/jrtplib/src/rtperrors.cpp new file mode 100644 index 00000000..5d3e05b7 --- /dev/null +++ b/src/libs/jrtplib/src/rtperrors.cpp @@ -0,0 +1,257 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtperrors.h" +#include "rtpdefines.h" +#include + +#include "rtpdebug.h" + +namespace jrtplib +{ + +struct RTPErrorInfo +{ + int code; + const char *description; +}; + +static RTPErrorInfo ErrorDescriptions[]= +{ + { ERR_RTP_OUTOFMEM,"Out of memory" }, + { ERR_RTP_NOTHREADSUPPORT, "No JThread support was compiled in"}, + { ERR_RTP_COLLISIONLIST_BADADDRESS, "Passed invalid address (null) to collision list"}, + { ERR_RTP_HASHTABLE_ELEMENTALREADYEXISTS, "Element already exists in hash table"}, + { ERR_RTP_HASHTABLE_ELEMENTNOTFOUND, "Element not found in hash table"}, + { ERR_RTP_HASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX, "Function returned an illegal hash index"}, + { ERR_RTP_HASHTABLE_NOCURRENTELEMENT, "No current element selected in hash table"}, + { ERR_RTP_KEYHASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX, "Function returned an illegal hash index"}, + { ERR_RTP_KEYHASHTABLE_KEYALREADYEXISTS, "Key value already exists in key hash table"}, + { ERR_RTP_KEYHASHTABLE_KEYNOTFOUND, "Key value not found in key hash table"}, + { ERR_RTP_KEYHASHTABLE_NOCURRENTELEMENT, "No current element selected in key hash table"}, + { ERR_RTP_PACKBUILD_ALREADYINIT, "RTP packet builder is already initialized"}, + { ERR_RTP_PACKBUILD_CSRCALREADYINLIST, "The specified CSRC is already in the RTP packet builder's CSRC list"}, + { ERR_RTP_PACKBUILD_CSRCLISTFULL, "The RTP packet builder's CSRC list already contains 15 entries"}, + { ERR_RTP_PACKBUILD_CSRCNOTINLIST, "The specified CSRC was not found in the RTP packet builder's CSRC list"}, + { ERR_RTP_PACKBUILD_DEFAULTMARKNOTSET, "The RTP packet builder's default mark flag is not set"}, + { ERR_RTP_PACKBUILD_DEFAULTPAYLOADTYPENOTSET, "The RTP packet builder's default payload type is not set"}, + { ERR_RTP_PACKBUILD_DEFAULTTSINCNOTSET, "The RTP packet builder's default timestamp increment is not set"}, + { ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE, "The specified maximum packet size for the RTP packet builder is invalid"}, + { ERR_RTP_PACKBUILD_NOTINIT, "The RTP packet builder is not initialized"}, + { ERR_RTP_PACKET_BADPAYLOADTYPE, "Invalid payload type"}, + { ERR_RTP_PACKET_DATAEXCEEDSMAXSIZE, "Tried to create an RTP packet which whould exceed the specified maximum packet size"}, + { ERR_RTP_PACKET_EXTERNALBUFFERNULL, "Illegal value (null) passed as external buffer for the RTP packet"}, + { ERR_RTP_PACKET_ILLEGALBUFFERSIZE, "Illegal buffer size specified for the RTP packet"}, + { ERR_RTP_PACKET_INVALIDPACKET, "Invalid RTP packet format"}, + { ERR_RTP_PACKET_TOOMANYCSRCS, "More than 15 CSRCs specified for the RTP packet"}, + { ERR_RTP_POLLTHREAD_ALREADYRUNNING, "Poll thread is already running"}, + { ERR_RTP_POLLTHREAD_CANTINITMUTEX, "Can't initialize a mutex for the poll thread"}, + { ERR_RTP_POLLTHREAD_CANTSTARTTHREAD, "Can't start the poll thread"}, + { ERR_RTP_RTCPCOMPOUND_INVALIDPACKET, "Invalid RTCP compound packet format"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILDING, "Already building this RTCP compound packet"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILT, "This RTCP compound packet is already built"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYGOTREPORT, "There's already a SR or RR in this RTCP compound packet"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_APPDATALENTOOBIG, "The specified APP data length for the RTCP compound packet is too big"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_BUFFERSIZETOOSMALL, "The specified buffer size for the RTCP comound packet is too small"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALAPPDATALENGTH, "The APP data length must be a multiple of four"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALSUBTYPE, "The APP packet subtype must be smaller than 32"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_INVALIDITEMTYPE, "Invalid SDES item type specified for the RTCP compound packet"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_MAXPACKETSIZETOOSMALL, "The specified maximum packet size for the RTCP compound packet is too small"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE, "Tried to add an SDES item to the RTCP compound packet when no SSRC was present"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_NOREPORTPRESENT, "An RTCP compound packet must contain a SR or RR"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING, "The RTCP compound packet builder is not initialized"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT, "Adding this data would exceed the specified maximum RTCP compound packet size"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_REPORTNOTSTARTED, "Tried to add a report block to the RTCP compound packet when no SR or RR was started"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_TOOMANYSSRCS, "Only 31 SSRCs will fit into a BYE packet for the RTCP compound packet"}, + { ERR_RTP_RTCPCOMPPACKBUILDER_TOTALITEMLENGTHTOOBIG, "The total data for the SDES PRIV item exceeds the maximum size (255 bytes) of an SDES item"}, + { ERR_RTP_RTCPPACKETBUILDER_ALREADYINIT, "The RTCP packet builder is already initialized"}, + { ERR_RTP_RTCPPACKETBUILDER_ILLEGALMAXPACKSIZE, "The specified maximum packet size for the RTCP packet builder is too small"}, + { ERR_RTP_RTCPPACKETBUILDER_ILLEGALTIMESTAMPUNIT, "Speficied an illegal timestamp unit for the the RTCP packet builder"}, + { ERR_RTP_RTCPPACKETBUILDER_NOTINIT, "The RTCP packet builder was not initialized"}, + { ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON, "The RTCP compound packet filled sooner than expected"}, + { ERR_RTP_SCHEDPARAMS_BADFRACTION, "Illegal sender bandwidth fraction specified"}, + { ERR_RTP_SCHEDPARAMS_BADMINIMUMINTERVAL, "The minimum RTCP interval specified for the scheduler is too small"}, + { ERR_RTP_SCHEDPARAMS_INVALIDBANDWIDTH, "Invalid RTCP bandwidth specified for the RTCP scheduler"}, + { ERR_RTP_SDES_LENGTHTOOBIG, "Specified size for the SDES item exceeds 255 bytes"}, + { ERR_RTP_SDES_PREFIXNOTFOUND, "The specified SDES PRIV prefix was not found"}, + { ERR_RTP_SESSION_ALREADYCREATED, "The session is already created"}, + { ERR_RTP_SESSION_CANTGETLOGINNAME, "Can't retrieve login name"}, + { ERR_RTP_SESSION_CANTINITMUTEX, "A mutex for the RTP session couldn't be initialized"}, + { ERR_RTP_SESSION_MAXPACKETSIZETOOSMALL, "The maximum packet size specified for the RTP session is too small"}, + { ERR_RTP_SESSION_NOTCREATED, "The RTP session was not created"}, + { ERR_RTP_SESSION_UNSUPPORTEDTRANSMISSIONPROTOCOL, "The requested transmission protocol for the RTP session is not supported"}, + { ERR_RTP_SESSION_USINGPOLLTHREAD, "This function is not available when using the RTP poll thread feature"}, + { ERR_RTP_SESSION_USERDEFINEDTRANSMITTERNULL, "A user-defined transmitter was requested but the supplied transmitter component is NULL"}, + { ERR_RTP_SOURCES_ALREADYHAVEOWNSSRC, "Only one source can be marked as own SSRC in the source table"}, + { ERR_RTP_SOURCES_DONTHAVEOWNSSRC, "No source was marked as own SSRC in the source table"}, + { ERR_RTP_SOURCES_ILLEGALSDESTYPE, "Illegal SDES type specified for processing into the source table"}, + { ERR_RTP_SOURCES_SSRCEXISTS, "Can't create own SSRC because this SSRC identifier is already in the source table"}, + { ERR_RTP_UDPV4TRANS_ALREADYCREATED, "The transmitter was already created"}, + { ERR_RTP_UDPV4TRANS_ALREADYINIT, "The transmitter was already initialize"}, + { ERR_RTP_UDPV4TRANS_ALREADYWAITING, "The transmitter is already waiting for incoming data"}, + { ERR_RTP_UDPV4TRANS_CANTBINDRTCPSOCKET, "The 'bind' call for the RTCP socket failed"}, + { ERR_RTP_UDPV4TRANS_CANTBINDRTPSOCKET, "The 'bind' call for the RTP socket failed"}, + { ERR_RTP_UDPV4TRANS_CANTCALCULATELOCALIP, "The local IP addresses could not be determined"}, + { ERR_RTP_UDPV4TRANS_CANTCREATEABORTDESCRIPTORS, "Couldn't create the sockets used to abort waiting for incoming data"}, + { ERR_RTP_UDPV4TRANS_CANTCREATEPIPE, "Couldn't create the pipe used to abort waiting for incoming data"}, + { ERR_RTP_UDPV4TRANS_CANTCREATESOCKET, "Couldn't create the RTP or RTCP socket"}, + { ERR_RTP_UDPV4TRANS_CANTINITMUTEX, "Failed to initialize a mutex used by the transmitter"}, + { ERR_RTP_UDPV4TRANS_CANTSETRTCPRECEIVEBUF, "Couldn't set the receive buffer size for the RTCP socket"}, + { ERR_RTP_UDPV4TRANS_CANTSETRTCPTRANSMITBUF, "Couldn't set the transmission buffer size for the RTCP socket"}, + { ERR_RTP_UDPV4TRANS_CANTSETRTPRECEIVEBUF, "Couldn't set the receive buffer size for the RTP socket"}, + { ERR_RTP_UDPV4TRANS_CANTSETRTPTRANSMITBUF, "Couldn't set the transmission buffer size for the RTP socket"}, + { ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP, "Unable to join the specified multicast group"}, + { ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE, "The function called doens't match the current receive mode"}, + { ERR_RTP_UDPV4TRANS_ERRORINSELECT, "Error in the transmitter's 'select' call"}, + { ERR_RTP_UDPV4TRANS_ILLEGALPARAMETERS, "Illegal parameters type passed to the transmitter"}, + { ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE, "Specified address type isn't compatible with this transmitter"}, + { ERR_RTP_UDPV4TRANS_NOLOCALIPS, "Couldn't determine the local host name since the local IP list is empty"}, + { ERR_RTP_UDPV4TRANS_NOMULTICASTSUPPORT, "Multicast support is not available"}, + { ERR_RTP_UDPV4TRANS_NOSUCHENTRY, "Specified entry could not be found"}, + { ERR_RTP_UDPV4TRANS_NOTAMULTICASTADDRESS, "The specified address is not a multicast address"}, + { ERR_RTP_UDPV4TRANS_NOTCREATED, "The 'Create' call for this transmitter has not been called"}, + { ERR_RTP_UDPV4TRANS_NOTINIT, "The 'Init' call for this transmitter has not been called"}, + { ERR_RTP_UDPV4TRANS_NOTWAITING, "The transmitter is not waiting for incoming data"}, + { ERR_RTP_UDPV4TRANS_PORTBASENOTEVEN, "The specified port base is not an even number"}, + { ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG, "The maximum packet size is too big for this transmitter"}, + { ERR_RTP_UDPV6TRANS_ALREADYCREATED, "The transmitter was already created"}, + { ERR_RTP_UDPV6TRANS_ALREADYINIT, "The transmitter was already initialize"}, + { ERR_RTP_UDPV6TRANS_ALREADYWAITING, "The transmitter is already waiting for incoming data"}, + { ERR_RTP_UDPV6TRANS_CANTBINDRTCPSOCKET, "The 'bind' call for the RTCP socket failed"}, + { ERR_RTP_UDPV6TRANS_CANTBINDRTPSOCKET, "The 'bind' call for the RTP socket failed"}, + { ERR_RTP_UDPV6TRANS_CANTCALCULATELOCALIP, "The local IP addresses could not be determined"}, + { ERR_RTP_UDPV6TRANS_CANTCREATEABORTDESCRIPTORS, "Couldn't create the sockets used to abort waiting for incoming data"}, + { ERR_RTP_UDPV6TRANS_CANTCREATEPIPE, "Couldn't create the pipe used to abort waiting for incoming data"}, + { ERR_RTP_UDPV6TRANS_CANTCREATESOCKET, "Couldn't create the RTP or RTCP socket"}, + { ERR_RTP_UDPV6TRANS_CANTINITMUTEX, "Failed to initialize a mutex used by the transmitter"}, + { ERR_RTP_UDPV6TRANS_CANTSETRTCPRECEIVEBUF, "Couldn't set the receive buffer size for the RTCP socket"}, + { ERR_RTP_UDPV6TRANS_CANTSETRTCPTRANSMITBUF, "Couldn't set the transmission buffer size for the RTCP socket"}, + { ERR_RTP_UDPV6TRANS_CANTSETRTPRECEIVEBUF, "Couldn't set the receive buffer size for the RTP socket"}, + { ERR_RTP_UDPV6TRANS_CANTSETRTPTRANSMITBUF, "Couldn't set the transmission buffer size for the RTP socket"}, + { ERR_RTP_UDPV6TRANS_COULDNTJOINMULTICASTGROUP, "Unable to join the specified multicast group"}, + { ERR_RTP_UDPV6TRANS_DIFFERENTRECEIVEMODE, "The function called doens't match the current receive mode"}, + { ERR_RTP_UDPV6TRANS_ERRORINSELECT, "Error in the transmitter's 'select' call"}, + { ERR_RTP_UDPV6TRANS_ILLEGALPARAMETERS, "Illegal parameters type passed to the transmitter"}, + { ERR_RTP_UDPV6TRANS_INVALIDADDRESSTYPE, "Specified address type isn't compatible with this transmitter"}, + { ERR_RTP_UDPV6TRANS_NOLOCALIPS, "Couldn't determine the local host name since the local IP list is empty"}, + { ERR_RTP_UDPV6TRANS_NOMULTICASTSUPPORT, "Multicast support is not available"}, + { ERR_RTP_UDPV6TRANS_NOSUCHENTRY, "Specified entry could not be found"}, + { ERR_RTP_UDPV6TRANS_NOTAMULTICASTADDRESS, "The specified address is not a multicast address"}, + { ERR_RTP_UDPV6TRANS_NOTCREATED, "The 'Create' call for this transmitter has not been called"}, + { ERR_RTP_UDPV6TRANS_NOTINIT, "The 'Init' call for this transmitter has not been called"}, + { ERR_RTP_UDPV6TRANS_NOTWAITING, "The transmitter is not waiting for incoming data"}, + { ERR_RTP_UDPV6TRANS_PORTBASENOTEVEN, "The specified port base is not an even number"}, + { ERR_RTP_UDPV6TRANS_SPECIFIEDSIZETOOBIG, "The maximum packet size is too big for this transmitter"}, + { ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL,"The hostname is larger than the specified buffer size"}, + { ERR_RTP_SDES_MAXPRIVITEMS,"The maximum number of SDES private item prefixes was reached"}, + { ERR_RTP_INTERNALSOURCEDATA_INVALIDPROBATIONTYPE,"An invalid probation type was specified"}, + { ERR_RTP_FAKETRANS_ALREADYCREATED, "The transmitter was already created"}, + { ERR_RTP_FAKETRANS_ALREADYINIT, "The transmitter was already initialize"}, + { ERR_RTP_FAKETRANS_ALREADYWAITING, "The transmitter is already waiting for incoming data"}, + { ERR_RTP_FAKETRANS_CANTBINDRTCPSOCKET, "The 'bind' call for the RTCP socket failed"}, + { ERR_RTP_FAKETRANS_CANTBINDRTPSOCKET, "The 'bind' call for the RTP socket failed"}, + { ERR_RTP_FAKETRANS_CANTCALCULATELOCALIP, "The local IP addresses could not be determined"}, + { ERR_RTP_FAKETRANS_CANTCREATEABORTDESCRIPTORS, "Couldn't create the sockets used to abort waiting for incoming data"}, + { ERR_RTP_FAKETRANS_CANTCREATEPIPE, "Couldn't create the pipe used to abort waiting for incoming data"}, + { ERR_RTP_FAKETRANS_CANTCREATESOCKET, "Couldn't create the RTP or RTCP socket"}, + { ERR_RTP_FAKETRANS_CANTINITMUTEX, "Failed to initialize a mutex used by the transmitter"}, + { ERR_RTP_FAKETRANS_CANTSETRTCPRECEIVEBUF, "Couldn't set the receive buffer size for the RTCP socket"}, + { ERR_RTP_FAKETRANS_CANTSETRTCPTRANSMITBUF, "Couldn't set the transmission buffer size for the RTCP socket"}, + { ERR_RTP_FAKETRANS_CANTSETRTPRECEIVEBUF, "Couldn't set the receive buffer size for the RTP socket"}, + { ERR_RTP_FAKETRANS_CANTSETRTPTRANSMITBUF, "Couldn't set the transmission buffer size for the RTP socket"}, + { ERR_RTP_FAKETRANS_COULDNTJOINMULTICASTGROUP, "Unable to join the specified multicast group"}, + { ERR_RTP_FAKETRANS_DIFFERENTRECEIVEMODE, "The function called doens't match the current receive mode"}, + { ERR_RTP_FAKETRANS_ERRORINSELECT, "Error in the transmitter's 'select' call"}, + { ERR_RTP_FAKETRANS_ILLEGALPARAMETERS, "Illegal parameters type passed to the transmitter"}, + { ERR_RTP_FAKETRANS_INVALIDADDRESSTYPE, "Specified address type isn't compatible with this transmitter"}, + { ERR_RTP_FAKETRANS_NOLOCALIPS, "Couldn't determine the local host name since the local IP list is empty"}, + { ERR_RTP_FAKETRANS_NOMULTICASTSUPPORT, "Multicast support is not available"}, + { ERR_RTP_FAKETRANS_NOSUCHENTRY, "Specified entry could not be found"}, + { ERR_RTP_FAKETRANS_NOTAMULTICASTADDRESS, "The specified address is not a multicast address"}, + { ERR_RTP_FAKETRANS_NOTCREATED, "The 'Create' call for this transmitter has not been called"}, + { ERR_RTP_FAKETRANS_NOTINIT, "The 'Init' call for this transmitter has not been called"}, + { ERR_RTP_FAKETRANS_NOTWAITING, "The transmitter is not waiting for incoming data"}, + { ERR_RTP_FAKETRANS_PORTBASENOTEVEN, "The specified port base is not an even number"}, + { ERR_RTP_FAKETRANS_SPECIFIEDSIZETOOBIG, "The maximum packet size is too big for this transmitter"}, + { ERR_RTP_FAKETRANS_INVALIDEVENT, "Expecting UNKNOWN_EVENT to set source address but got another type of event"}, + { ERR_RTP_FAKETRANS_SRCADDRNOTSET, "Got packet but src address information was not set, returning"}, + { ERR_RTP_FAKETRANS_NOTNETBUFFER, "Received buffer is not a GstNetBuffer"}, + { ERR_RTP_FAKETRANS_WAITNOTIMPLEMENTED, "The WaitForIncomingData is not implemented in the Gst transmitter"}, + { ERR_RTP_RTPRANDOMURANDOM_CANTOPEN, "Unable to open /dev/urandom for reading"}, + { ERR_RTP_RTPRANDOMURANDOM_ALREADYOPEN, "The device /dev/urandom was already opened"}, + { ERR_RTP_RTPRANDOMRANDS_NOTSUPPORTED, "The rand_s call is not supported on this platform"}, + { ERR_RTP_EXTERNALTRANS_ALREADYCREATED, "The external transmission component was already created"}, + { ERR_RTP_EXTERNALTRANS_ALREADYINIT, "The external transmission component was already initialized"}, + { ERR_RTP_EXTERNALTRANS_ALREADYWAITING, "The external transmission component is already waiting for incoming data"}, + { ERR_RTP_EXTERNALTRANS_BADRECEIVEMODE, "The external transmission component only supports accepting all incoming packets"}, + { ERR_RTP_EXTERNALTRANS_CANTCREATEABORTDESCRIPTORS, "The external transmitter was unable to create it's internal abort descriptors"}, + { ERR_RTP_EXTERNALTRANS_CANTCREATEPIPE, "The external transmitter was unable to create a pipe"}, + { ERR_RTP_EXTERNALTRANS_CANTINITMUTEX, "The external transmitter was unable to initialize a required mutex"}, + { ERR_RTP_EXTERNALTRANS_ERRORINSELECT, "An error in the external transmitter's 'select' call occurred"}, + { ERR_RTP_EXTERNALTRANS_ILLEGALPARAMETERS, "Only parameters of type RTPExternalTransmissionParams can be passed to the external transmission component"}, + { ERR_RTP_EXTERNALTRANS_NOACCEPTLIST, "The external transmitter does not have an accept list"}, + { ERR_RTP_EXTERNALTRANS_NODESTINATIONSSUPPORTED, "The external transmitter does not have a destination list"}, + { ERR_RTP_EXTERNALTRANS_NOIGNORELIST, "The external transmitter does not have an ignore list"}, + { ERR_RTP_EXTERNALTRANS_NOMULTICASTSUPPORT, "The external transmitter does not support the multicast functions"}, + { ERR_RTP_EXTERNALTRANS_NOSENDER, "No sender has been set for this external transmitter"}, + { ERR_RTP_EXTERNALTRANS_NOTCREATED, "The external transmitter has not been created yet"}, + { ERR_RTP_EXTERNALTRANS_NOTINIT, "The external transmitter has not been initialized yet"}, + { ERR_RTP_EXTERNALTRANS_NOTWAITING, "The external transmitter is not currently waiting for incoming data"}, + { ERR_RTP_EXTERNALTRANS_SENDERROR, "The external transmitter was unable to actually send the data"}, + { ERR_RTP_EXTERNALTRANS_SPECIFIEDSIZETOOBIG, "The specified data size exceeds the maximum amount that has been set"}, + { 0,0 } +}; + +std::string RTPGetErrorString(int errcode) +{ + int i; + + if (errcode >= 0) + return std::string("No error"); + + i = 0; + while (ErrorDescriptions[i].code != 0) + { + if (ErrorDescriptions[i].code == errcode) + return std::string(ErrorDescriptions[i].description); + i++; + } + + char str[16]; + + RTP_SNPRINTF(str,16,"(%d)",errcode); + + return std::string("Unknown error code") + std::string(str); +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtperrors.h b/src/libs/jrtplib/src/rtperrors.h new file mode 100644 index 00000000..c0b6994d --- /dev/null +++ b/src/libs/jrtplib/src/rtperrors.h @@ -0,0 +1,236 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtperrors.h + */ + +#ifndef RTPERRORS_H + +#define RTPERRORS_H + +#include "rtpconfig.h" +#include + +namespace jrtplib +{ + +/** Returns a string describing the error code \c errcode. */ +std::string JRTPLIB_IMPORTEXPORT RTPGetErrorString(int errcode); + +} // end namespace + +#define ERR_RTP_OUTOFMEM -1 +#define ERR_RTP_NOTHREADSUPPORT -2 +#define ERR_RTP_COLLISIONLIST_BADADDRESS -3 +#define ERR_RTP_HASHTABLE_ELEMENTALREADYEXISTS -4 +#define ERR_RTP_HASHTABLE_ELEMENTNOTFOUND -5 +#define ERR_RTP_HASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX -6 +#define ERR_RTP_HASHTABLE_NOCURRENTELEMENT -7 +#define ERR_RTP_KEYHASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX -8 +#define ERR_RTP_KEYHASHTABLE_KEYALREADYEXISTS -9 +#define ERR_RTP_KEYHASHTABLE_KEYNOTFOUND -10 +#define ERR_RTP_KEYHASHTABLE_NOCURRENTELEMENT -11 +#define ERR_RTP_PACKBUILD_ALREADYINIT -12 +#define ERR_RTP_PACKBUILD_CSRCALREADYINLIST -13 +#define ERR_RTP_PACKBUILD_CSRCLISTFULL -14 +#define ERR_RTP_PACKBUILD_CSRCNOTINLIST -15 +#define ERR_RTP_PACKBUILD_DEFAULTMARKNOTSET -16 +#define ERR_RTP_PACKBUILD_DEFAULTPAYLOADTYPENOTSET -17 +#define ERR_RTP_PACKBUILD_DEFAULTTSINCNOTSET -18 +#define ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE -19 +#define ERR_RTP_PACKBUILD_NOTINIT -20 +#define ERR_RTP_PACKET_BADPAYLOADTYPE -21 +#define ERR_RTP_PACKET_DATAEXCEEDSMAXSIZE -22 +#define ERR_RTP_PACKET_EXTERNALBUFFERNULL -23 +#define ERR_RTP_PACKET_ILLEGALBUFFERSIZE -24 +#define ERR_RTP_PACKET_INVALIDPACKET -25 +#define ERR_RTP_PACKET_TOOMANYCSRCS -26 +#define ERR_RTP_POLLTHREAD_ALREADYRUNNING -27 +#define ERR_RTP_POLLTHREAD_CANTINITMUTEX -28 +#define ERR_RTP_POLLTHREAD_CANTSTARTTHREAD -29 +#define ERR_RTP_RTCPCOMPOUND_INVALIDPACKET -30 +#define ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILDING -31 +#define ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILT -32 +#define ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYGOTREPORT -33 +#define ERR_RTP_RTCPCOMPPACKBUILDER_APPDATALENTOOBIG -34 +#define ERR_RTP_RTCPCOMPPACKBUILDER_BUFFERSIZETOOSMALL -35 +#define ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALAPPDATALENGTH -36 +#define ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALSUBTYPE -37 +#define ERR_RTP_RTCPCOMPPACKBUILDER_INVALIDITEMTYPE -38 +#define ERR_RTP_RTCPCOMPPACKBUILDER_MAXPACKETSIZETOOSMALL -39 +#define ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE -40 +#define ERR_RTP_RTCPCOMPPACKBUILDER_NOREPORTPRESENT -41 +#define ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING -42 +#define ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT -43 +#define ERR_RTP_RTCPCOMPPACKBUILDER_REPORTNOTSTARTED -44 +#define ERR_RTP_RTCPCOMPPACKBUILDER_TOOMANYSSRCS -45 +#define ERR_RTP_RTCPCOMPPACKBUILDER_TOTALITEMLENGTHTOOBIG -46 +#define ERR_RTP_RTCPPACKETBUILDER_ALREADYINIT -47 +#define ERR_RTP_RTCPPACKETBUILDER_ILLEGALMAXPACKSIZE -48 +#define ERR_RTP_RTCPPACKETBUILDER_ILLEGALTIMESTAMPUNIT -49 +#define ERR_RTP_RTCPPACKETBUILDER_NOTINIT -50 +#define ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON -51 +#define ERR_RTP_SCHEDPARAMS_BADFRACTION -52 +#define ERR_RTP_SCHEDPARAMS_BADMINIMUMINTERVAL -53 +#define ERR_RTP_SCHEDPARAMS_INVALIDBANDWIDTH -54 +#define ERR_RTP_SDES_LENGTHTOOBIG -55 +#define ERR_RTP_SDES_MAXPRIVITEMS -56 +#define ERR_RTP_SDES_PREFIXNOTFOUND -57 +#define ERR_RTP_SESSION_ALREADYCREATED -58 +#define ERR_RTP_SESSION_CANTGETLOGINNAME -59 +#define ERR_RTP_SESSION_CANTINITMUTEX -60 +#define ERR_RTP_SESSION_MAXPACKETSIZETOOSMALL -61 +#define ERR_RTP_SESSION_NOTCREATED -62 +#define ERR_RTP_SESSION_UNSUPPORTEDTRANSMISSIONPROTOCOL -63 +#define ERR_RTP_SESSION_USINGPOLLTHREAD -64 +#define ERR_RTP_SOURCES_ALREADYHAVEOWNSSRC -65 +#define ERR_RTP_SOURCES_DONTHAVEOWNSSRC -66 +#define ERR_RTP_SOURCES_ILLEGALSDESTYPE -67 +#define ERR_RTP_SOURCES_SSRCEXISTS -68 +#define ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL -69 +#define ERR_RTP_UDPV4TRANS_ALREADYCREATED -70 +#define ERR_RTP_UDPV4TRANS_ALREADYINIT -71 +#define ERR_RTP_UDPV4TRANS_ALREADYWAITING -72 +#define ERR_RTP_UDPV4TRANS_CANTBINDRTCPSOCKET -73 +#define ERR_RTP_UDPV4TRANS_CANTBINDRTPSOCKET -74 +#define ERR_RTP_UDPV4TRANS_CANTCALCULATELOCALIP -75 +#define ERR_RTP_UDPV4TRANS_CANTCREATEABORTDESCRIPTORS -76 +#define ERR_RTP_UDPV4TRANS_CANTCREATEPIPE -77 +#define ERR_RTP_UDPV4TRANS_CANTCREATESOCKET -78 +#define ERR_RTP_UDPV4TRANS_CANTINITMUTEX -79 +#define ERR_RTP_UDPV4TRANS_CANTSETRTCPRECEIVEBUF -80 +#define ERR_RTP_UDPV4TRANS_CANTSETRTCPTRANSMITBUF -81 +#define ERR_RTP_UDPV4TRANS_CANTSETRTPRECEIVEBUF -82 +#define ERR_RTP_UDPV4TRANS_CANTSETRTPTRANSMITBUF -83 +#define ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP -84 +#define ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE -85 +#define ERR_RTP_UDPV4TRANS_ERRORINSELECT -86 +#define ERR_RTP_UDPV4TRANS_ILLEGALPARAMETERS -87 +#define ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE -88 +#define ERR_RTP_UDPV4TRANS_NOLOCALIPS -89 +#define ERR_RTP_UDPV4TRANS_NOMULTICASTSUPPORT -90 +#define ERR_RTP_UDPV4TRANS_NOSUCHENTRY -91 +#define ERR_RTP_UDPV4TRANS_NOTAMULTICASTADDRESS -92 +#define ERR_RTP_UDPV4TRANS_NOTCREATED -93 +#define ERR_RTP_UDPV4TRANS_NOTINIT -94 +#define ERR_RTP_UDPV4TRANS_NOTWAITING -95 +#define ERR_RTP_UDPV4TRANS_PORTBASENOTEVEN -96 +#define ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG -97 +#define ERR_RTP_UDPV6TRANS_ALREADYCREATED -98 +#define ERR_RTP_UDPV6TRANS_ALREADYINIT -99 +#define ERR_RTP_UDPV6TRANS_ALREADYWAITING -100 +#define ERR_RTP_UDPV6TRANS_CANTBINDRTCPSOCKET -101 +#define ERR_RTP_UDPV6TRANS_CANTBINDRTPSOCKET -102 +#define ERR_RTP_UDPV6TRANS_CANTCALCULATELOCALIP -103 +#define ERR_RTP_UDPV6TRANS_CANTCREATEABORTDESCRIPTORS -104 +#define ERR_RTP_UDPV6TRANS_CANTCREATEPIPE -105 +#define ERR_RTP_UDPV6TRANS_CANTCREATESOCKET -106 +#define ERR_RTP_UDPV6TRANS_CANTINITMUTEX -107 +#define ERR_RTP_UDPV6TRANS_CANTSETRTCPRECEIVEBUF -108 +#define ERR_RTP_UDPV6TRANS_CANTSETRTCPTRANSMITBUF -109 +#define ERR_RTP_UDPV6TRANS_CANTSETRTPRECEIVEBUF -110 +#define ERR_RTP_UDPV6TRANS_CANTSETRTPTRANSMITBUF -111 +#define ERR_RTP_UDPV6TRANS_COULDNTJOINMULTICASTGROUP -112 +#define ERR_RTP_UDPV6TRANS_DIFFERENTRECEIVEMODE -113 +#define ERR_RTP_UDPV6TRANS_ERRORINSELECT -114 +#define ERR_RTP_UDPV6TRANS_ILLEGALPARAMETERS -115 +#define ERR_RTP_UDPV6TRANS_INVALIDADDRESSTYPE -116 +#define ERR_RTP_UDPV6TRANS_NOLOCALIPS -117 +#define ERR_RTP_UDPV6TRANS_NOMULTICASTSUPPORT -118 +#define ERR_RTP_UDPV6TRANS_NOSUCHENTRY -119 +#define ERR_RTP_UDPV6TRANS_NOTAMULTICASTADDRESS -120 +#define ERR_RTP_UDPV6TRANS_NOTCREATED -121 +#define ERR_RTP_UDPV6TRANS_NOTINIT -122 +#define ERR_RTP_UDPV6TRANS_NOTWAITING -123 +#define ERR_RTP_UDPV6TRANS_PORTBASENOTEVEN -124 +#define ERR_RTP_UDPV6TRANS_SPECIFIEDSIZETOOBIG -125 +#define ERR_RTP_INTERNALSOURCEDATA_INVALIDPROBATIONTYPE -126 +#define ERR_RTP_SESSION_USERDEFINEDTRANSMITTERNULL -127 +#define ERR_RTP_FAKETRANS_ALREADYCREATED -128 +#define ERR_RTP_FAKETRANS_ALREADYINIT -129 +#define ERR_RTP_FAKETRANS_ALREADYWAITING -130 +#define ERR_RTP_FAKETRANS_CANTBINDRTCPSOCKET -131 +#define ERR_RTP_FAKETRANS_CANTBINDRTPSOCKET -132 +#define ERR_RTP_FAKETRANS_CANTCALCULATELOCALIP -133 +#define ERR_RTP_FAKETRANS_CANTCREATEABORTDESCRIPTORS -134 +#define ERR_RTP_FAKETRANS_CANTCREATEPIPE -135 +#define ERR_RTP_FAKETRANS_CANTCREATESOCKET -136 +#define ERR_RTP_FAKETRANS_CANTINITMUTEX -137 +#define ERR_RTP_FAKETRANS_CANTSETRTCPRECEIVEBUF -138 +#define ERR_RTP_FAKETRANS_CANTSETRTCPTRANSMITBUF -139 +#define ERR_RTP_FAKETRANS_CANTSETRTPRECEIVEBUF -140 +#define ERR_RTP_FAKETRANS_CANTSETRTPTRANSMITBUF -141 +#define ERR_RTP_FAKETRANS_COULDNTJOINMULTICASTGROUP -142 +#define ERR_RTP_FAKETRANS_DIFFERENTRECEIVEMODE -143 +#define ERR_RTP_FAKETRANS_ERRORINSELECT -144 +#define ERR_RTP_FAKETRANS_ILLEGALPARAMETERS -145 +#define ERR_RTP_FAKETRANS_INVALIDADDRESSTYPE -146 +#define ERR_RTP_FAKETRANS_NOLOCALIPS -147 +#define ERR_RTP_FAKETRANS_NOMULTICASTSUPPORT -148 +#define ERR_RTP_FAKETRANS_NOSUCHENTRY -149 +#define ERR_RTP_FAKETRANS_NOTAMULTICASTADDRESS -150 +#define ERR_RTP_FAKETRANS_NOTCREATED -151 +#define ERR_RTP_FAKETRANS_NOTINIT -152 +#define ERR_RTP_FAKETRANS_NOTWAITING -153 +#define ERR_RTP_FAKETRANS_PORTBASENOTEVEN -154 +#define ERR_RTP_FAKETRANS_SPECIFIEDSIZETOOBIG -155 +#define ERR_RTP_FAKETRANS_INVALIDEVENT -156 +#define ERR_RTP_FAKETRANS_SRCADDRNOTSET -157 +#define ERR_RTP_FAKETRANS_NOTNETBUFFER -158 +#define ERR_RTP_FAKETRANS_WAITNOTIMPLEMENTED -159 +#define ERR_RTP_RTPRANDOMURANDOM_CANTOPEN -160 +#define ERR_RTP_RTPRANDOMURANDOM_ALREADYOPEN -161 +#define ERR_RTP_RTPRANDOMRANDS_NOTSUPPORTED -162 + +#define ERR_RTP_EXTERNALTRANS_ALREADYCREATED -163 +#define ERR_RTP_EXTERNALTRANS_ALREADYINIT -164 +#define ERR_RTP_EXTERNALTRANS_ALREADYWAITING -165 +#define ERR_RTP_EXTERNALTRANS_BADRECEIVEMODE -166 +#define ERR_RTP_EXTERNALTRANS_CANTCREATEABORTDESCRIPTORS -167 +#define ERR_RTP_EXTERNALTRANS_CANTCREATEPIPE -168 +#define ERR_RTP_EXTERNALTRANS_CANTINITMUTEX -169 +#define ERR_RTP_EXTERNALTRANS_ERRORINSELECT -170 +#define ERR_RTP_EXTERNALTRANS_ILLEGALPARAMETERS -171 +#define ERR_RTP_EXTERNALTRANS_NOACCEPTLIST -172 +#define ERR_RTP_EXTERNALTRANS_NODESTINATIONSSUPPORTED -173 +#define ERR_RTP_EXTERNALTRANS_NOIGNORELIST -174 +#define ERR_RTP_EXTERNALTRANS_NOMULTICASTSUPPORT -175 +#define ERR_RTP_EXTERNALTRANS_NOSENDER -176 +#define ERR_RTP_EXTERNALTRANS_NOTCREATED -177 +#define ERR_RTP_EXTERNALTRANS_NOTINIT -178 +#define ERR_RTP_EXTERNALTRANS_NOTWAITING -179 +#define ERR_RTP_EXTERNALTRANS_SENDERROR -180 +#define ERR_RTP_EXTERNALTRANS_SPECIFIEDSIZETOOBIG -181 + +#endif // RTPERRORS_H + diff --git a/src/libs/jrtplib/src/rtpexternaltransmitter.cpp b/src/libs/jrtplib/src/rtpexternaltransmitter.cpp new file mode 100644 index 00000000..7ad42a09 --- /dev/null +++ b/src/libs/jrtplib/src/rtpexternaltransmitter.cpp @@ -0,0 +1,929 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpexternaltransmitter.h" +#include "rtprawpacket.h" +#include "rtptimeutilities.h" +#include "rtpdefines.h" +#include "rtperrors.h" +#include +#include + +#ifdef RTPDEBUG + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +#include + +#if (defined(WIN32) || defined(_WIN32_WCE)) + #define RTPSOCKERR INVALID_SOCKET + #define RTPCLOSE(x) closesocket(x) + #define RTPSOCKLENTYPE int + #define RTPIOCTL ioctlsocket +#else // not Win32 + #include + #include + #include + #include + #include + #include + #include + #include + + #ifdef RTP_HAVE_SYS_FILIO + #include + #endif // RTP_HAVE_SYS_FILIO + #ifdef RTP_HAVE_SYS_SOCKIO + #include + #endif // RTP_HAVE_SYS_SOCKIO + #ifdef RTP_SUPPORT_IFADDRS + #include + #endif // RTP_SUPPORT_IFADDRS + + #define RTPSOCKERR -1 + #define RTPCLOSE(x) close(x) + + #ifdef RTP_SOCKLENTYPE_UINT + #define RTPSOCKLENTYPE unsigned int + #else + #define RTPSOCKLENTYPE int + #endif // RTP_SOCKLENTYPE_UINT + + #define RTPIOCTL ioctl +#endif // WIN32 + +#ifdef RTP_SUPPORT_THREAD + #define MAINMUTEX_LOCK { if (threadsafe) mainmutex.Lock(); } + #define MAINMUTEX_UNLOCK { if (threadsafe) mainmutex.Unlock(); } + #define WAITMUTEX_LOCK { if (threadsafe) waitmutex.Lock(); } + #define WAITMUTEX_UNLOCK { if (threadsafe) waitmutex.Unlock(); } +#else + #define MAINMUTEX_LOCK + #define MAINMUTEX_UNLOCK + #define WAITMUTEX_LOCK + #define WAITMUTEX_UNLOCK +#endif // RTP_SUPPORT_THREAD + +namespace jrtplib +{ + +RTPExternalTransmitter::RTPExternalTransmitter(RTPMemoryManager *mgr) : RTPTransmitter(mgr), packetinjector((RTPExternalTransmitter *)this) +{ + created = false; + init = false; +#if (defined(WIN32) || defined(_WIN32_WCE)) + timeinit.Dummy(); +#endif // WIN32 || _WIN32_WCE +} + +RTPExternalTransmitter::~RTPExternalTransmitter() +{ + Destroy(); +} + +int RTPExternalTransmitter::Init(bool tsafe) +{ + if (init) + return ERR_RTP_EXTERNALTRANS_ALREADYINIT; + +#ifdef RTP_SUPPORT_THREAD + threadsafe = tsafe; + if (threadsafe) + { + int status; + + status = mainmutex.Init(); + if (status < 0) + return ERR_RTP_EXTERNALTRANS_CANTINITMUTEX; + status = waitmutex.Init(); + if (status < 0) + return ERR_RTP_EXTERNALTRANS_CANTINITMUTEX; + } +#else + if (tsafe) + return ERR_RTP_NOTHREADSUPPORT; +#endif // RTP_SUPPORT_THREAD + + init = true; + return 0; +} + +int RTPExternalTransmitter::Create(size_t maximumpacketsize,const RTPTransmissionParams *transparams) +{ + const RTPExternalTransmissionParams *params; + int status; + + if (!init) + return ERR_RTP_EXTERNALTRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_ALREADYCREATED; + } + + // Obtain transmission parameters + + if (transparams == 0) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_ILLEGALPARAMETERS; + } + if (transparams->GetTransmissionProtocol() != RTPTransmitter::ExternalProto) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_ILLEGALPARAMETERS; + } + + params = (const RTPExternalTransmissionParams *)transparams; + + if ((status = CreateAbortDescriptors()) < 0) + { + MAINMUTEX_UNLOCK + return status; + } + + maxpacksize = maximumpacketsize; + sender = params->GetSender(); + headersize = params->GetAdditionalHeaderSize(); + + localhostname = 0; + localhostnamelength = 0; + + waitingfordata = false; + created = true; + MAINMUTEX_UNLOCK + return 0; +} + +void RTPExternalTransmitter::Destroy() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK; + return; + } + + if (localhostname) + { + RTPDeleteByteArray(localhostname,GetMemoryManager()); + localhostname = 0; + localhostnamelength = 0; + } + + FlushPackets(); + created = false; + + if (waitingfordata) + { + AbortWaitInternal(); + DestroyAbortDescriptors(); + MAINMUTEX_UNLOCK + WAITMUTEX_LOCK // to make sure that the WaitForIncomingData function ended + WAITMUTEX_UNLOCK + } + else + DestroyAbortDescriptors(); + + MAINMUTEX_UNLOCK +} + +RTPTransmissionInfo *RTPExternalTransmitter::GetTransmissionInfo() +{ + if (!init) + return 0; + + MAINMUTEX_LOCK + RTPTransmissionInfo *tinf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPTRANSMISSIONINFO) RTPExternalTransmissionInfo(&packetinjector); + MAINMUTEX_UNLOCK + return tinf; +} + +void RTPExternalTransmitter::DeleteTransmissionInfo(RTPTransmissionInfo *i) +{ + if (!init) + return; + + RTPDelete(i, GetMemoryManager()); +} + +int RTPExternalTransmitter::GetLocalHostName(uint8_t *buffer,size_t *bufferlength) +{ + if (!init) + return ERR_RTP_EXTERNALTRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_NOTCREATED; + } + + if (localhostname == 0) + { + // We'll just use 'gethostname' for simplicity + + char name[1024]; + + if (gethostname(name,1023) != 0) + strcpy(name, "localhost"); // failsafe + else + name[1023] = 0; // ensure null-termination + + localhostnamelength = strlen(name); + localhostname = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) uint8_t [localhostnamelength+1]; + + memcpy(localhostname, name, localhostnamelength); + localhostname[localhostnamelength] = 0; + } + + if ((*bufferlength) < localhostnamelength) + { + *bufferlength = localhostnamelength; // tell the application the required size of the buffer + MAINMUTEX_UNLOCK + return ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL; + } + + memcpy(buffer,localhostname,localhostnamelength); + *bufferlength = localhostnamelength; + + MAINMUTEX_UNLOCK + return 0; +} + +bool RTPExternalTransmitter::ComesFromThisTransmitter(const RTPAddress *addr) +{ + MAINMUTEX_LOCK + bool value = false; + if (sender) + value = sender->ComesFromThisSender(addr); + MAINMUTEX_UNLOCK + return value; +} + +int RTPExternalTransmitter::Poll() +{ + return 0; +} + +int RTPExternalTransmitter::WaitForIncomingData(const RTPTime &delay,bool *dataavailable) +{ + if (!init) + return ERR_RTP_EXTERNALTRANS_NOTINIT; + + MAINMUTEX_LOCK + + fd_set fdset; + struct timeval tv; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_NOTCREATED; + } + if (waitingfordata) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_ALREADYWAITING; + } + + FD_ZERO(&fdset); + FD_SET(abortdesc[0],&fdset); + tv.tv_sec = delay.GetSeconds(); + tv.tv_usec = delay.GetMicroSeconds(); + + waitingfordata = true; + + if (!rawpacketlist.empty()) + { + if (dataavailable != 0) + *dataavailable = true; + waitingfordata = false; + MAINMUTEX_UNLOCK + return 0; + } + + WAITMUTEX_LOCK + MAINMUTEX_UNLOCK + + if (select(FD_SETSIZE,&fdset,0,0,&tv) < 0) + { + MAINMUTEX_LOCK + waitingfordata = false; + MAINMUTEX_UNLOCK + WAITMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_ERRORINSELECT; + } + + MAINMUTEX_LOCK + waitingfordata = false; + if (!created) // destroy called + { + MAINMUTEX_UNLOCK; + WAITMUTEX_UNLOCK + return 0; + } + + // if aborted, read from abort buffer + if (FD_ISSET(abortdesc[0],&fdset)) + { +#define BUFLEN 256 +#if (defined(WIN32) || defined(_WIN32_WCE)) + char buf[BUFLEN]; + unsigned long len, len2; +#else + size_t len, len2; + unsigned char buf[BUFLEN]; +#endif // WIN32 + + len = 0; + RTPIOCTL(abortdesc[0],FIONREAD,&len); + + while (len > 0) + { + len2 = len; + if (len2 > BUFLEN) + len2 = BUFLEN; + +#if (defined(WIN32) || defined(_WIN32_WCE)) + recv(abortdesc[0],buf,len2,0); +#else + if (read(abortdesc[0],buf,len2)) { } // To get rid of __wur related compiler warnings +#endif // WIN32 + len -= len2; + } + } + + if (dataavailable != 0) + { + if (rawpacketlist.empty()) + *dataavailable = false; + else + *dataavailable = true; + } + + MAINMUTEX_UNLOCK + WAITMUTEX_UNLOCK + return 0; +} + +int RTPExternalTransmitter::AbortWait() +{ + if (!init) + return ERR_RTP_EXTERNALTRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_NOTCREATED; + } + if (!waitingfordata) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_NOTWAITING; + } + + AbortWaitInternal(); + + MAINMUTEX_UNLOCK + return 0; +} + +int RTPExternalTransmitter::SendRTPData(const void *data,size_t len) +{ + if (!init) + return ERR_RTP_EXTERNALTRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_NOTCREATED; + } + if (len > maxpacksize) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_SPECIFIEDSIZETOOBIG; + } + + if (!sender) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_NOSENDER; + } + + MAINMUTEX_UNLOCK + + if (!sender->SendRTP(data, len)) + return ERR_RTP_EXTERNALTRANS_SENDERROR; + + return 0; +} + +int RTPExternalTransmitter::SendRTCPData(const void *data,size_t len) +{ + if (!init) + return ERR_RTP_EXTERNALTRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_NOTCREATED; + } + if (len > maxpacksize) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_SPECIFIEDSIZETOOBIG; + } + + if (!sender) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_NOSENDER; + } + MAINMUTEX_UNLOCK + + if (!sender->SendRTCP(data, len)) + return ERR_RTP_EXTERNALTRANS_SENDERROR; + + return 0; +} + +int RTPExternalTransmitter::AddDestination(const RTPAddress &addr) +{ + return ERR_RTP_EXTERNALTRANS_NODESTINATIONSSUPPORTED; +} + +int RTPExternalTransmitter::DeleteDestination(const RTPAddress &addr) +{ + return ERR_RTP_EXTERNALTRANS_NODESTINATIONSSUPPORTED; +} + +void RTPExternalTransmitter::ClearDestinations() +{ +} + +bool RTPExternalTransmitter::SupportsMulticasting() +{ + return false; +} + +int RTPExternalTransmitter::JoinMulticastGroup(const RTPAddress &addr) +{ + return ERR_RTP_EXTERNALTRANS_NOMULTICASTSUPPORT; +} + +int RTPExternalTransmitter::LeaveMulticastGroup(const RTPAddress &addr) +{ + return ERR_RTP_EXTERNALTRANS_NOMULTICASTSUPPORT; +} + +void RTPExternalTransmitter::LeaveAllMulticastGroups() +{ +} + +int RTPExternalTransmitter::SetReceiveMode(RTPTransmitter::ReceiveMode m) +{ + if (!init) + return ERR_RTP_EXTERNALTRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_NOTCREATED; + } + if (m != RTPTransmitter::AcceptAll) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_BADRECEIVEMODE; + } + MAINMUTEX_UNLOCK + return 0; +} + +int RTPExternalTransmitter::AddToIgnoreList(const RTPAddress &addr) +{ + return ERR_RTP_EXTERNALTRANS_NOIGNORELIST; +} + +int RTPExternalTransmitter::DeleteFromIgnoreList(const RTPAddress &addr) +{ + return ERR_RTP_EXTERNALTRANS_NOIGNORELIST; +} + +void RTPExternalTransmitter::ClearIgnoreList() +{ +} + +int RTPExternalTransmitter::AddToAcceptList(const RTPAddress &addr) +{ + return ERR_RTP_EXTERNALTRANS_NOACCEPTLIST; +} + +int RTPExternalTransmitter::DeleteFromAcceptList(const RTPAddress &addr) +{ + return ERR_RTP_EXTERNALTRANS_NOACCEPTLIST; +} + +void RTPExternalTransmitter::ClearAcceptList() +{ +} + +int RTPExternalTransmitter::SetMaximumPacketSize(size_t s) +{ + if (!init) + return ERR_RTP_EXTERNALTRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_EXTERNALTRANS_NOTCREATED; + } + maxpacksize = s; + MAINMUTEX_UNLOCK + return 0; +} + +bool RTPExternalTransmitter::NewDataAvailable() +{ + if (!init) + return false; + + MAINMUTEX_LOCK + + bool v; + + if (!created) + v = false; + else + { + if (rawpacketlist.empty()) + v = false; + else + v = true; + } + + MAINMUTEX_UNLOCK + return v; +} + +RTPRawPacket *RTPExternalTransmitter::GetNextPacket() +{ + if (!init) + return 0; + + MAINMUTEX_LOCK + + RTPRawPacket *p; + + if (!created) + { + MAINMUTEX_UNLOCK + return 0; + } + if (rawpacketlist.empty()) + { + MAINMUTEX_UNLOCK + return 0; + } + + p = *(rawpacketlist.begin()); + rawpacketlist.pop_front(); + + MAINMUTEX_UNLOCK + return p; +} + +// Here the private functions start... + +void RTPExternalTransmitter::FlushPackets() +{ + std::list::const_iterator it; + + for (it = rawpacketlist.begin() ; it != rawpacketlist.end() ; ++it) + RTPDelete(*it,GetMemoryManager()); + rawpacketlist.clear(); +} + +#if (defined(WIN32) || defined(_WIN32_WCE)) + +int RTPExternalTransmitter::CreateAbortDescriptors() +{ + SOCKET listensock; + int size; + struct sockaddr_in addr; + + listensock = socket(PF_INET,SOCK_STREAM,0); + if (listensock == RTPSOCKERR) + return ERR_RTP_EXTERNALTRANS_CANTCREATEABORTDESCRIPTORS; + + memset(&addr,0,sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + if (bind(listensock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) + { + RTPCLOSE(listensock); + return ERR_RTP_EXTERNALTRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in)); + size = sizeof(struct sockaddr_in); + if (getsockname(listensock,(struct sockaddr*)&addr,&size) != 0) + { + RTPCLOSE(listensock); + return ERR_RTP_EXTERNALTRANS_CANTCREATEABORTDESCRIPTORS; + } + + unsigned short connectport = ntohs(addr.sin_port); + + abortdesc[0] = socket(PF_INET,SOCK_STREAM,0); + if (abortdesc[0] == RTPSOCKERR) + { + RTPCLOSE(listensock); + return ERR_RTP_EXTERNALTRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + if (bind(abortdesc[0],(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_EXTERNALTRANS_CANTCREATEABORTDESCRIPTORS; + } + + if (listen(listensock,1) != 0) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_EXTERNALTRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = htons(connectport); + + if (connect(abortdesc[0],(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_EXTERNALTRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in)); + size = sizeof(struct sockaddr_in); + abortdesc[1] = accept(listensock,(struct sockaddr *)&addr,&size); + if (abortdesc[1] == RTPSOCKERR) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_EXTERNALTRANS_CANTCREATEABORTDESCRIPTORS; + } + + // okay, got the connection, close the listening socket + + RTPCLOSE(listensock); + return 0; +} + +void RTPExternalTransmitter::DestroyAbortDescriptors() +{ + RTPCLOSE(abortdesc[0]); + RTPCLOSE(abortdesc[1]); +} + +#else // in a non winsock environment we can use pipes + +int RTPExternalTransmitter::CreateAbortDescriptors() +{ +#ifndef RTP_DISABLE_INTERRUPT + if (pipe(abortdesc) < 0) + return ERR_RTP_EXTERNALTRANS_CANTCREATEPIPE; +#endif + return 0; +} + +void RTPExternalTransmitter::DestroyAbortDescriptors() +{ +#ifndef RTP_DISABLE_INTERRUPT + close(abortdesc[0]); + close(abortdesc[1]); +#endif +} + +#endif // WIN32 + +void RTPExternalTransmitter::AbortWaitInternal() +{ +#if (defined(WIN32) || defined(_WIN32_WCE)) + send(abortdesc[1],"*",1,0); +#else + //if (write(abortdesc[1],"*",1)) + { + // To get rid of __wur related compiler warnings + } +#endif // WIN32 +} + +void RTPExternalTransmitter::InjectRTP(const void *data, size_t len, const RTPAddress &a) +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return; + } + + RTPAddress *addr = a.CreateCopy(GetMemoryManager()); + if (addr == 0) + return; + + uint8_t *datacopy; + + datacopy = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RECEIVEDRTPPACKET) uint8_t[len]; + if (datacopy == 0) + { + RTPDelete(addr,GetMemoryManager()); + return; + } + memcpy(datacopy, data, len); + + RTPTime curtime = RTPTime::CurrentTime(); + RTPRawPacket *pack; + + pack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPRAWPACKET) RTPRawPacket(datacopy,len,addr,curtime,true,GetMemoryManager()); + if (pack == 0) + { + RTPDelete(addr,GetMemoryManager()); + RTPDeleteByteArray(localhostname,GetMemoryManager()); + return; + } + rawpacketlist.push_back(pack); + AbortWaitInternal(); + + MAINMUTEX_UNLOCK +} + +void RTPExternalTransmitter::InjectRTCP(const void *data, size_t len, const RTPAddress &a) +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return; + } + + RTPAddress *addr = a.CreateCopy(GetMemoryManager()); + if (addr == 0) + return; + + uint8_t *datacopy; + + datacopy = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RECEIVEDRTCPPACKET) uint8_t[len]; + if (datacopy == 0) + { + RTPDelete(addr,GetMemoryManager()); + return; + } + memcpy(datacopy, data, len); + + RTPTime curtime = RTPTime::CurrentTime(); + RTPRawPacket *pack; + + pack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPRAWPACKET) RTPRawPacket(datacopy,len,addr,curtime,false,GetMemoryManager()); + if (pack == 0) + { + RTPDelete(addr,GetMemoryManager()); + RTPDeleteByteArray(localhostname,GetMemoryManager()); + return; + } + rawpacketlist.push_back(pack); + AbortWaitInternal(); + + MAINMUTEX_UNLOCK +} + +void RTPExternalTransmitter::InjectRTPorRTCP(const void *data, size_t len, const RTPAddress &a) +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return; + } + + RTPAddress *addr = a.CreateCopy(GetMemoryManager()); + if (addr == 0) + return; + + uint8_t *datacopy; + bool rtp = true; + + if (len >= 2) + { + const uint8_t *pData = (const uint8_t *)data; + if (pData[1] >= 200 && pData[1] <= 204) + rtp = false; + } + + datacopy = RTPNew(GetMemoryManager(),(rtp)?RTPMEM_TYPE_BUFFER_RECEIVEDRTPPACKET:RTPMEM_TYPE_BUFFER_RECEIVEDRTCPPACKET) uint8_t[len]; + if (datacopy == 0) + { + RTPDelete(addr,GetMemoryManager()); + return; + } + memcpy(datacopy, data, len); + + RTPTime curtime = RTPTime::CurrentTime(); + RTPRawPacket *pack; + + pack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPRAWPACKET) RTPRawPacket(datacopy,len,addr,curtime,rtp,GetMemoryManager()); + if (pack == 0) + { + RTPDelete(addr,GetMemoryManager()); + RTPDeleteByteArray(localhostname,GetMemoryManager()); + return; + } + rawpacketlist.push_back(pack); + AbortWaitInternal(); + + MAINMUTEX_UNLOCK + +} + +#ifdef RTPDEBUG +void RTPExternalTransmitter::Dump() +{ + if (!init) + std::cout << "Not initialized" << std::endl; + else + { + MAINMUTEX_LOCK + + if (!created) + std::cout << "Not created" << std::endl; + else + { + std::cout << "Number of raw packets in queue: " << rawpacketlist.size() << std::endl; + std::cout << "Maximum allowed packet size: " << maxpacksize << std::endl; + } + + MAINMUTEX_UNLOCK + } +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtpexternaltransmitter.h b/src/libs/jrtplib/src/rtpexternaltransmitter.h new file mode 100644 index 00000000..8db73a84 --- /dev/null +++ b/src/libs/jrtplib/src/rtpexternaltransmitter.h @@ -0,0 +1,240 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpexternaltransmitter.h + */ + +#ifndef RTPEXTERNALTRANSMITTER_H + +#define RTPEXTERNALTRANSMITTER_H + +#include "rtpconfig.h" +#include "rtptransmitter.h" +#include + +#ifdef RTP_SUPPORT_THREAD + #include +#endif // RTP_SUPPORT_THREAD + +namespace jrtplib +{ + +class RTPExternalTransmitter; + +/** Base class to specify a mechanism to transmit RTP packets outside of this library. + * Base class to specify a mechanism to transmit RTP packets outside of this library. When + * you want to use your own mechanism to transmit RTP packets, you need to specify that + * you'll be using the external transmission component, and derive a class from this base + * class. An instance should then be specified in the RTPExternalTransmissionParams object, + * so that the transmitter will call the \c SendRTP, \c SendRTCP and \c ComesFromThisSender + * methods of this instance when needed. + */ +class JRTPLIB_IMPORTEXPORT RTPExternalSender +{ +public: + RTPExternalSender() { } + virtual ~RTPExternalSender() { } + + /** This member function will be called when RTP data needs to be transmitted. */ + virtual bool SendRTP(const void *data, size_t len) = 0; + + /** This member function will be called when an RTCP packet needs to be transmitted. */ + virtual bool SendRTCP(const void *data, size_t len) = 0; + + /** Used to identify if an RTPAddress instance originated from this sender (to be able to detect own packets). */ + virtual bool ComesFromThisSender(const RTPAddress *a) = 0; +}; + +/** Interface to inject incoming RTP and RTCP packets into the library. + * Interface to inject incoming RTP and RTCP packets into the library. When you have your own + * mechanism to receive incoming RTP/RTCP data, you'll need to pass these packets to the library. + * By first retrieving the RTPExternalTransmissionInfo instance for the external transmitter you'll + * be using, you can obtain the associated RTPExternalPacketInjecter instance. By calling it's + * member functions, you can then inject RTP or RTCP data into the library for further processing. + */ +class JRTPLIB_IMPORTEXPORT RTPExternalPacketInjecter +{ +public: + RTPExternalPacketInjecter(RTPExternalTransmitter *trans) { transmitter = trans; } + ~RTPExternalPacketInjecter() { } + + /** This function can be called to insert an RTP packet into the transmission component. */ + void InjectRTP(const void *data, size_t len, const RTPAddress &a); + + /** This function can be called to insert an RTCP packet into the transmission component. */ + void InjectRTCP(const void *data, size_t len, const RTPAddress &a); + + /** Use this function to inject an RTP or RTCP packet and the transmitter will try to figure out which type of packet it is. */ + void InjectRTPorRTCP(const void *data, size_t len, const RTPAddress &a); +private: + RTPExternalTransmitter *transmitter; +}; + +/** Parameters to initialize a transmitter of type RTPExternalTransmitter. */ +class JRTPLIB_IMPORTEXPORT RTPExternalTransmissionParams : public RTPTransmissionParams +{ +public: + /** Using this constructor you can specify which RTPExternalSender object you'll be using + * and how much the additional header overhead for each packet will be. */ + RTPExternalTransmissionParams(RTPExternalSender *s, int headeroverhead):RTPTransmissionParams(RTPTransmitter::ExternalProto) { sender = s; headersize = headeroverhead; } + + RTPExternalSender *GetSender() const { return sender; } + int GetAdditionalHeaderSize() const { return headersize; } +private: + RTPExternalSender *sender; + int headersize; +}; + +/** Additional information about the external transmission component. */ +class JRTPLIB_IMPORTEXPORT RTPExternalTransmissionInfo : public RTPTransmissionInfo +{ +public: + RTPExternalTransmissionInfo(RTPExternalPacketInjecter *p) : RTPTransmissionInfo(RTPTransmitter::ExternalProto) { packetinjector = p; } + + /** Tells you which RTPExternalPacketInjecter you need to use to pass RTP or RTCP + * data on to the transmission component. */ + RTPExternalPacketInjecter *GetPacketInjector() const { return packetinjector; } +private: + RTPExternalPacketInjecter *packetinjector; +}; + +/** A transmission component which will use user specified functions to transmit the data and + * which will expose functions to inject received RTP or RTCP data into this component. + * A transmission component which will use user specified functions to transmit the data and + * which will expose functions to inject received RTP or RTCP data into this component. Use + * a class derived from RTPExternalSender to specify the functions which need to be used for + * sending the data. Obtain the RTPExternalTransmissionInfo object associated with this + * transmitter to obtain the functions needed to pass RTP/RTCP packets on to the transmitter. + */ +class JRTPLIB_IMPORTEXPORT RTPExternalTransmitter : public RTPTransmitter +{ +public: + RTPExternalTransmitter(RTPMemoryManager *mgr); + ~RTPExternalTransmitter(); + + int Init(bool treadsafe); + int Create(size_t maxpacksize, const RTPTransmissionParams *transparams); + void Destroy(); + RTPTransmissionInfo *GetTransmissionInfo(); + void DeleteTransmissionInfo(RTPTransmissionInfo *inf); + + int GetLocalHostName(uint8_t *buffer,size_t *bufferlength); + bool ComesFromThisTransmitter(const RTPAddress *addr); + size_t GetHeaderOverhead() { return headersize; } + + int Poll(); + int WaitForIncomingData(const RTPTime &delay,bool *dataavailable = 0); + int AbortWait(); + + int SendRTPData(const void *data,size_t len); + int SendRTCPData(const void *data,size_t len); + + int AddDestination(const RTPAddress &addr); + int DeleteDestination(const RTPAddress &addr); + void ClearDestinations(); + + bool SupportsMulticasting(); + int JoinMulticastGroup(const RTPAddress &addr); + int LeaveMulticastGroup(const RTPAddress &addr); + void LeaveAllMulticastGroups(); + + int SetReceiveMode(RTPTransmitter::ReceiveMode m); + int AddToIgnoreList(const RTPAddress &addr); + int DeleteFromIgnoreList(const RTPAddress &addr); + void ClearIgnoreList(); + int AddToAcceptList(const RTPAddress &addr); + int DeleteFromAcceptList(const RTPAddress &addr); + void ClearAcceptList(); + int SetMaximumPacketSize(size_t s); + + bool NewDataAvailable(); + RTPRawPacket *GetNextPacket(); +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG + + void InjectRTP(const void *data, size_t len, const RTPAddress &a); + void InjectRTCP(const void *data, size_t len, const RTPAddress &a); + void InjectRTPorRTCP(const void *data, size_t len, const RTPAddress &a); +private: + void FlushPackets(); + + bool init; + bool created; + bool waitingfordata; + RTPExternalSender *sender; + RTPExternalPacketInjecter packetinjector; + + std::list rawpacketlist; + + uint8_t *localhostname; + size_t localhostnamelength; + + size_t maxpacksize; + int headersize; + + // notification descriptors for AbortWait (0 is for reading, 1 for writing) +#if (defined(WIN32) || defined(_WIN32_WCE)) + SOCKET abortdesc[2]; +#else + int abortdesc[2]; +#endif // WIN32 + int CreateAbortDescriptors(); + void DestroyAbortDescriptors(); + void AbortWaitInternal(); +#ifdef RTP_SUPPORT_THREAD + jthread::JMutex mainmutex,waitmutex; + int threadsafe; +#endif // RTP_SUPPORT_THREAD +}; + +inline void RTPExternalPacketInjecter::InjectRTP(const void *data, size_t len, const RTPAddress &a) +{ + transmitter->InjectRTP(data, len, a); +} + +inline void RTPExternalPacketInjecter::InjectRTCP(const void *data, size_t len, const RTPAddress &a) +{ + transmitter->InjectRTCP(data, len, a); +} + +inline void RTPExternalPacketInjecter::InjectRTPorRTCP(const void *data, size_t len, const RTPAddress &a) +{ + transmitter->InjectRTPorRTCP(data, len, a); +} + +} // end namespace + +#endif // RTPTCPSOCKETTRANSMITTER_H + + diff --git a/src/libs/jrtplib/src/rtphashtable.h b/src/libs/jrtplib/src/rtphashtable.h new file mode 100644 index 00000000..1f867b1a --- /dev/null +++ b/src/libs/jrtplib/src/rtphashtable.h @@ -0,0 +1,342 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#ifndef RTPHASHTABLE_H + +#define RTPHASHTABLE_H + +/** + * \file rtphashtable.h + */ + +#include "rtperrors.h" +#include "rtpmemoryobject.h" + +#ifdef RTPDEBUG +#include +#endif // RTPDEBUG + +namespace jrtplib +{ + +//template +template +class RTPHashTable : public RTPMemoryObject +{ +public: + RTPHashTable(RTPMemoryManager *mgr = 0, int memtype = RTPMEM_TYPE_OTHER); + ~RTPHashTable() { Clear(); } + + void GotoFirstElement() { curhashelem = firsthashelem; } + void GotoLastElement() { curhashelem = lasthashelem; } + bool HasCurrentElement() { return (curhashelem == 0)?false:true; } + int DeleteCurrentElement(); + Element &GetCurrentElement() { return curhashelem->GetElement(); } + int GotoElement(const Element &e); + bool HasElement(const Element &e); + void GotoNextElement(); + void GotoPreviousElement(); + void Clear(); + + int AddElement(const Element &elem); + int DeleteElement(const Element &elem); + +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG +private: + class HashElement + { + public: + HashElement(const Element &e,int index):element(e) { hashprev = 0; hashnext = 0; listnext = 0; listprev = 0; hashindex = index; } + int GetHashIndex() { return hashindex; } + Element &GetElement() { return element; } +#ifdef RTPDEBUG + void Dump() { std::cout << "\tHash index " << hashindex << " | Element " << element << std::endl; } +#endif // RTPDEBUG + private: + int hashindex; + Element element; + public: + HashElement *hashprev,*hashnext; + HashElement *listprev,*listnext; + }; + + HashElement *table[hashsize]; + HashElement *firsthashelem,*lasthashelem; + HashElement *curhashelem; +#ifdef RTP_SUPPORT_MEMORYMANAGEMENT + int memorytype; +#endif // RTP_SUPPORT_MEMORYMANAGEMENT +}; + +template +inline RTPHashTable::RTPHashTable(RTPMemoryManager *mgr,int memtype) : RTPMemoryObject(mgr) +{ + for (int i = 0 ; i < hashsize ; i++) + table[i] = 0; + firsthashelem = 0; + lasthashelem = 0; +#ifdef RTP_SUPPORT_MEMORYMANAGEMENT + memorytype = memtype; +#endif // RTP_SUPPORT_MEMORYMANAGEMENT +} + +template +inline int RTPHashTable::DeleteCurrentElement() +{ + if (curhashelem) + { + HashElement *tmp1,*tmp2; + int index; + + // First, relink elements in current hash bucket + + index = curhashelem->GetHashIndex(); + tmp1 = curhashelem->hashprev; + tmp2 = curhashelem->hashnext; + if (tmp1 == 0) // no previous element in hash bucket + { + table[index] = tmp2; + if (tmp2 != 0) + tmp2->hashprev = 0; + } + else // there is a previous element in the hash bucket + { + tmp1->hashnext = tmp2; + if (tmp2 != 0) + tmp2->hashprev = tmp1; + } + + // Relink elements in list + + tmp1 = curhashelem->listprev; + tmp2 = curhashelem->listnext; + if (tmp1 == 0) // curhashelem is first in list + { + firsthashelem = tmp2; + if (tmp2 != 0) + tmp2->listprev = 0; + else // curhashelem is also last in list + lasthashelem = 0; + } + else + { + tmp1->listnext = tmp2; + if (tmp2 != 0) + tmp2->listprev = tmp1; + else // curhashelem is last in list + lasthashelem = tmp1; + } + + // finally, with everything being relinked, we can delete curhashelem + RTPDelete(curhashelem,GetMemoryManager()); + curhashelem = tmp2; // Set to next element in the list + } + else + return ERR_RTP_HASHTABLE_NOCURRENTELEMENT; + return 0; +} + +template +inline int RTPHashTable::GotoElement(const Element &e) +{ + int index; + bool found; + + index = GetIndex::GetIndex(e); + if (index >= hashsize) + return ERR_RTP_HASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX; + + curhashelem = table[index]; + found = false; + while(!found && curhashelem != 0) + { + if (curhashelem->GetElement() == e) + found = true; + else + curhashelem = curhashelem->hashnext; + } + if (!found) + return ERR_RTP_HASHTABLE_ELEMENTNOTFOUND; + return 0; +} + +template +inline bool RTPHashTable::HasElement(const Element &e) +{ + int index; + bool found; + HashElement *tmp; + + index = GetIndex::GetIndex(e); + if (index >= hashsize) + return false; + + tmp = table[index]; + found = false; + while(!found && tmp != 0) + { + if (tmp->GetElement() == e) + found = true; + else + tmp = tmp->hashnext; + } + return found; +} + +template +inline void RTPHashTable::GotoNextElement() +{ + if (curhashelem) + curhashelem = curhashelem->listnext; +} + +template +inline void RTPHashTable::GotoPreviousElement() +{ + if (curhashelem) + curhashelem = curhashelem->listprev; +} + +template +inline void RTPHashTable::Clear() +{ + HashElement *tmp1,*tmp2; + + for (int i = 0 ; i < hashsize ; i++) + table[i] = 0; + + tmp1 = firsthashelem; + while (tmp1 != 0) + { + tmp2 = tmp1->listnext; + RTPDelete(tmp1,GetMemoryManager()); + tmp1 = tmp2; + } + firsthashelem = 0; + lasthashelem = 0; +} + +template +inline int RTPHashTable::AddElement(const Element &elem) +{ + int index; + bool found; + HashElement *e,*newelem; + + index = GetIndex::GetIndex(elem); + if (index >= hashsize) + return ERR_RTP_HASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX; + + e = table[index]; + found = false; + while(!found && e != 0) + { + if (e->GetElement() == elem) + found = true; + else + e = e->hashnext; + } + if (found) + return ERR_RTP_HASHTABLE_ELEMENTALREADYEXISTS; + + // Okay, the key doesn't exist, so we can add the new element in the hash table + + newelem = RTPNew(GetMemoryManager(),memorytype) HashElement(elem,index); + if (newelem == 0) + return ERR_RTP_OUTOFMEM; + + e = table[index]; + table[index] = newelem; + newelem->hashnext = e; + if (e != 0) + e->hashprev = newelem; + + // Now, we still got to add it to the linked list + + if (firsthashelem == 0) + { + firsthashelem = newelem; + lasthashelem = newelem; + } + else // there already are some elements in the list + { + lasthashelem->listnext = newelem; + newelem->listprev = lasthashelem; + lasthashelem = newelem; + } + return 0; +} + +template +inline int RTPHashTable::DeleteElement(const Element &elem) +{ + int status; + + status = GotoElement(elem); + if (status < 0) + return status; + return DeleteCurrentElement(); +} + +#ifdef RTPDEBUG +template +inline void RTPHashTable::Dump() +{ + HashElement *e; + + std::cout << "DUMPING TABLE CONTENTS:" << std::endl; + for (int i = 0 ; i < hashsize ; i++) + { + e = table[i]; + while (e != 0) + { + e->Dump(); + e = e->hashnext; + } + } + + std::cout << "DUMPING LIST CONTENTS:" << std::endl; + e = firsthashelem; + while (e != 0) + { + e->Dump(); + e = e->listnext; + } +} +#endif // RTPDEBUG + +} // end namespace + +#endif // RTPHASHTABLE_H + diff --git a/src/libs/jrtplib/src/rtpinternalsourcedata.cpp b/src/libs/jrtplib/src/rtpinternalsourcedata.cpp new file mode 100644 index 00000000..78d18c21 --- /dev/null +++ b/src/libs/jrtplib/src/rtpinternalsourcedata.cpp @@ -0,0 +1,287 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpinternalsourcedata.h" +#include "rtppacket.h" +#include + +#include "rtpdebug.h" + +#define RTPINTERNALSOURCEDATA_MAXPROBATIONPACKETS 32 + +namespace jrtplib +{ + +RTPInternalSourceData::RTPInternalSourceData(uint32_t ssrc,RTPSources::ProbationType probtype,RTPMemoryManager *mgr):RTPSourceData(ssrc,mgr) +{ +#ifdef RTP_SUPPORT_PROBATION + probationtype = probtype; +#endif // RTP_SUPPORT_PROBATION +} + +RTPInternalSourceData::~RTPInternalSourceData() +{ +} + +// The following function should delete rtppack if necessary +int RTPInternalSourceData::ProcessRTPPacket(RTPPacket *rtppack,const RTPTime &receivetime,bool *stored) +{ + bool accept,onprobation,applyprobation; + double tsunit; + + *stored = false; + + if (timestampunit < 0) + tsunit = INF_GetEstimatedTimestampUnit(); + else + tsunit = timestampunit; + +#ifdef RTP_SUPPORT_PROBATION + if (validated) // If the source is our own process, we can already be validated. No + applyprobation = false; // probation should be applied in that case. + else + { + if (probationtype == RTPSources::NoProbation) + applyprobation = false; + else + applyprobation = true; + } +#else + applyprobation = false; +#endif // RTP_SUPPORT_PROBATION + + stats.ProcessPacket(rtppack,receivetime,tsunit,ownssrc,&accept,applyprobation,&onprobation); + +#ifdef RTP_SUPPORT_PROBATION + switch (probationtype) + { + case RTPSources::ProbationStore: + if (!(onprobation || accept)) + return 0; + if (accept) + validated = true; + break; + case RTPSources::ProbationDiscard: + case RTPSources::NoProbation: + if (!accept) + return 0; + validated = true; + break; + default: + return ERR_RTP_INTERNALSOURCEDATA_INVALIDPROBATIONTYPE; + } +#else + if (!accept) + return 0; + validated = true; +#endif // RTP_SUPPORT_PROBATION; + + if (validated && !ownssrc) // for own ssrc these variables depend on the outgoing packets, not on the incoming + issender = true; + + // Now, we can place the packet in the queue + + if (packetlist.empty()) + { + *stored = true; + packetlist.push_back(rtppack); + return 0; + } + + if (!validated) // still on probation + { + // Make sure that we don't buffer too much packets to avoid wasting memory + // on a bad source. Delete the packet in the queue with the lowest sequence + // number. + if (packetlist.size() == RTPINTERNALSOURCEDATA_MAXPROBATIONPACKETS) + { + RTPPacket *p = *(packetlist.begin()); + packetlist.pop_front(); + RTPDelete(p,GetMemoryManager()); + } + } + + // find the right position to insert the packet + + std::list::iterator it,start; + bool done = false; + uint32_t newseqnr = rtppack->GetExtendedSequenceNumber(); + + it = packetlist.end(); + --it; + start = packetlist.begin(); + + while (!done) + { + RTPPacket *p; + uint32_t seqnr; + + p = *it; + seqnr = p->GetExtendedSequenceNumber(); + if (seqnr > newseqnr) + { + if (it != start) + --it; + else // we're at the start of the list + { + *stored = true; + done = true; + packetlist.push_front(rtppack); + } + } + else if (seqnr < newseqnr) // insert after this packet + { + ++it; + packetlist.insert(it,rtppack); + done = true; + *stored = true; + } + else // they're equal !! Drop packet + { + done = true; + } + } + + return 0; +} + +int RTPInternalSourceData::ProcessSDESItem(uint8_t sdesid,const uint8_t *data,size_t itemlen,const RTPTime &receivetime,bool *cnamecollis) +{ + *cnamecollis = false; + + stats.SetLastMessageTime(receivetime); + + switch(sdesid) + { + case RTCP_SDES_ID_CNAME: + { + size_t curlen; + uint8_t *oldcname; + + // NOTE: we're going to make sure that the CNAME is only set once. + oldcname = SDESinf.GetCNAME(&curlen); + if (curlen == 0) + { + // if CNAME is set, the source is validated + SDESinf.SetCNAME(data,itemlen); + validated = true; + } + else // check if this CNAME is equal to the one that is already present + { + if (curlen != itemlen) + *cnamecollis = true; + else + { + if (memcmp(data,oldcname,itemlen) != 0) + *cnamecollis = true; + } + } + } + break; + case RTCP_SDES_ID_NAME: + { + uint8_t *oldname; + size_t oldlen; + + oldname = SDESinf.GetName(&oldlen); + if (oldlen == 0) // Name not set + return SDESinf.SetName(data,itemlen); + } + break; + case RTCP_SDES_ID_EMAIL: + { + uint8_t *oldemail; + size_t oldlen; + + oldemail = SDESinf.GetEMail(&oldlen); + if (oldlen == 0) + return SDESinf.SetEMail(data,itemlen); + } + break; + case RTCP_SDES_ID_PHONE: + return SDESinf.SetPhone(data,itemlen); + case RTCP_SDES_ID_LOCATION: + return SDESinf.SetLocation(data,itemlen); + case RTCP_SDES_ID_TOOL: + { + uint8_t *oldtool; + size_t oldlen; + + oldtool = SDESinf.GetTool(&oldlen); + if (oldlen == 0) + return SDESinf.SetTool(data,itemlen); + } + break; + case RTCP_SDES_ID_NOTE: + stats.SetLastNoteTime(receivetime); + return SDESinf.SetNote(data,itemlen); + } + return 0; +} + +#ifdef RTP_SUPPORT_SDESPRIV + +int RTPInternalSourceData::ProcessPrivateSDESItem(const uint8_t *prefix,size_t prefixlen,const uint8_t *value,size_t valuelen,const RTPTime &receivetime) +{ + int status; + + stats.SetLastMessageTime(receivetime); + status = SDESinf.SetPrivateValue(prefix,prefixlen,value,valuelen); + if (status == ERR_RTP_SDES_MAXPRIVITEMS) + return 0; // don't stop processing just because the number of items is full + return status; +} + +#endif // RTP_SUPPORT_SDESPRIV + +int RTPInternalSourceData::ProcessBYEPacket(const uint8_t *reason,size_t reasonlen,const RTPTime &receivetime) +{ + if (byereason) + { + RTPDeleteByteArray(byereason,GetMemoryManager()); + byereason = 0; + byereasonlen = 0; + } + + byetime = receivetime; + byereason = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPBYEREASON) uint8_t[reasonlen]; + if (byereason == 0) + return ERR_RTP_OUTOFMEM; + memcpy(byereason,reason,reasonlen); + byereasonlen = reasonlen; + receivedbye = true; + stats.SetLastMessageTime(receivetime); + return 0; +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtpinternalsourcedata.h b/src/libs/jrtplib/src/rtpinternalsourcedata.h new file mode 100644 index 00000000..d5d17a54 --- /dev/null +++ b/src/libs/jrtplib/src/rtpinternalsourcedata.h @@ -0,0 +1,135 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpinternalsourcedata.h + */ + +#ifndef RTPINTERNALSOURCEDATA_H + +#define RTPINTERNALSOURCEDATA_H + +#include "rtpconfig.h" +#include "rtpsourcedata.h" +#include "rtpaddress.h" +#include "rtptimeutilities.h" +#include "rtpsources.h" + +namespace jrtplib +{ + +class JRTPLIB_IMPORTEXPORT RTPInternalSourceData : public RTPSourceData +{ +public: + RTPInternalSourceData(uint32_t ssrc, RTPSources::ProbationType probtype, RTPMemoryManager *mgr = 0); + ~RTPInternalSourceData(); + + int ProcessRTPPacket(RTPPacket *rtppack,const RTPTime &receivetime,bool *stored); + void ProcessSenderInfo(const RTPNTPTime &ntptime,uint32_t rtptime,uint32_t packetcount, + uint32_t octetcount,const RTPTime &receivetime) { SRprevinf = SRinf; SRinf.Set(ntptime,rtptime,packetcount,octetcount,receivetime); stats.SetLastMessageTime(receivetime); } + void ProcessReportBlock(uint8_t fractionlost,int32_t lostpackets,uint32_t exthighseqnr, + uint32_t jitter,uint32_t lsr,uint32_t dlsr, + const RTPTime &receivetime) { RRprevinf = RRinf; RRinf.Set(fractionlost,lostpackets,exthighseqnr,jitter,lsr,dlsr,receivetime); stats.SetLastMessageTime(receivetime); } + void UpdateMessageTime(const RTPTime &receivetime) { stats.SetLastMessageTime(receivetime); } + int ProcessSDESItem(uint8_t sdesid,const uint8_t *data,size_t itemlen,const RTPTime &receivetime,bool *cnamecollis); +#ifdef RTP_SUPPORT_SDESPRIV + int ProcessPrivateSDESItem(const uint8_t *prefix,size_t prefixlen,const uint8_t *value,size_t valuelen,const RTPTime &receivetime); +#endif // RTP_SUPPORT_SDESPRIV + int ProcessBYEPacket(const uint8_t *reason,size_t reasonlen,const RTPTime &receivetime); + + int SetRTPDataAddress(const RTPAddress *a); + int SetRTCPDataAddress(const RTPAddress *a); + + void ClearSenderFlag() { issender = false; } + void SentRTPPacket() { if (!ownssrc) return; RTPTime t = RTPTime::CurrentTime(); issender = true; stats.SetLastRTPPacketTime(t); stats.SetLastMessageTime(t); } + void SetOwnSSRC() { ownssrc = true; validated = true; } + void SetCSRC() { validated = true; iscsrc = true; } + void ClearNote() { SDESinf.SetNote(0,0); } + +#ifdef RTP_SUPPORT_PROBATION +private: + RTPSources::ProbationType probationtype; +#endif // RTP_SUPPORT_PROBATION +}; + +inline int RTPInternalSourceData::SetRTPDataAddress(const RTPAddress *a) +{ + if (a == 0) + { + if (rtpaddr) + { + RTPDelete(rtpaddr,GetMemoryManager()); + rtpaddr = 0; + } + } + else + { + RTPAddress *newaddr = a->CreateCopy(GetMemoryManager()); + if (newaddr == 0) + return ERR_RTP_OUTOFMEM; + + if (rtpaddr && a != rtpaddr) + RTPDelete(rtpaddr,GetMemoryManager()); + rtpaddr = newaddr; + } + isrtpaddrset = true; + return 0; +} + +inline int RTPInternalSourceData::SetRTCPDataAddress(const RTPAddress *a) +{ + if (a == 0) + { + if (rtcpaddr) + { + RTPDelete(rtcpaddr,GetMemoryManager()); + rtcpaddr = 0; + } + } + else + { + RTPAddress *newaddr = a->CreateCopy(GetMemoryManager()); + if (newaddr == 0) + return ERR_RTP_OUTOFMEM; + + if (rtcpaddr && a != rtcpaddr) + RTPDelete(rtcpaddr,GetMemoryManager()); + rtcpaddr = newaddr; + } + isrtcpaddrset = true; + return 0; +} + +} // end namespace + +#endif // RTPINTERNALSOURCEDATA_H + diff --git a/src/libs/jrtplib/src/rtpipv4address.cpp b/src/libs/jrtplib/src/rtpipv4address.cpp new file mode 100644 index 00000000..af04f165 --- /dev/null +++ b/src/libs/jrtplib/src/rtpipv4address.cpp @@ -0,0 +1,111 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpipv4address.h" +#include "rtpmemorymanager.h" +#ifdef RTPDEBUG + #include "rtpdefines.h" + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTPIPv4Address::RTPIPv4Address(uint32_t ip, uint16_t port) + :RTPAddress(IPv4Address) +{ + RTPIPv4Address::ip = ip; + RTPIPv4Address::port = port; +} + +RTPIPv4Address::RTPIPv4Address(const uint8_t ip[4],uint16_t port) + :RTPAddress(IPv4Address) +{ + RTPIPv4Address::ip = (uint32_t)ip[3]; + RTPIPv4Address::ip |= (((uint32_t)ip[2])<<8); + RTPIPv4Address::ip |= (((uint32_t)ip[1])<<16); + RTPIPv4Address::ip |= (((uint32_t)ip[0])<<24); + RTPIPv4Address::port = port; +} + +RTPIPv4Address::~RTPIPv4Address() +{ + +} + +bool RTPIPv4Address::IsSameAddress(const RTPAddress *addr) const +{ + if (addr == 0) + return false; + if (addr->GetAddressType() != IPv4Address) + return false; + + const RTPIPv4Address *addr2 = (const RTPIPv4Address *)addr; + if (addr2->GetIP() == ip && addr2->GetPort() == port) + return true; + return false; +} + +bool RTPIPv4Address::IsFromSameHost(const RTPAddress *addr) const +{ + if (addr == 0) + return false; + if (addr->GetAddressType() != IPv4Address) + return false; + + const RTPIPv4Address *addr2 = (const RTPIPv4Address *)addr; + if (addr2->GetIP() == ip) + return true; + return false; +} + +RTPAddress *RTPIPv4Address::CreateCopy(RTPMemoryManager *mgr) const +{ + RTPIPv4Address *a = RTPNew(mgr,RTPMEM_TYPE_CLASS_RTPADDRESS) RTPIPv4Address(ip,port); + return a; +} + +#ifdef RTPDEBUG +std::string RTPIPv4Address::GetAddressString() const +{ + char str[24]; + + RTP_SNPRINTF(str,24,"%d.%d.%d.%d:%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF), + (int)(ip&0xFF),(int)port); + return std::string(str); +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtpipv4address.h b/src/libs/jrtplib/src/rtpipv4address.h new file mode 100644 index 00000000..b61f49fd --- /dev/null +++ b/src/libs/jrtplib/src/rtpipv4address.h @@ -0,0 +1,95 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpipv4address.h + */ + +#ifndef RTPIPV4ADDRESS_H + +#define RTPIPV4ADDRESS_H + +#include "rtpconfig.h" +#include "rtpaddress.h" +#include "rtptypes.h" + +namespace jrtplib +{ + +class RTPMemoryManager; + +/** Represents an IPv4 IP address and port. + * This class is used by the UDP over IPv4 transmission component. + * When an RTPIPv4Address is used in one of the multicast functions of the transmitter, the port + * number is ignored. When an instance is used in one of the accept or ignore functions of the + * transmitter, a zero port number represents all ports for the specified IP address. + */ +class JRTPLIB_IMPORTEXPORT RTPIPv4Address : public RTPAddress +{ +public: + /** Creates an instance with IP address \c ip and port number \c port (both are interpreted in host byte order). */ + RTPIPv4Address(uint32_t ip = 0, uint16_t port = 0); + + /** Creates an instance with IP address \c ip and port number \c port (\c port is interpreted in host byte order). */ + RTPIPv4Address(const uint8_t ip[4],uint16_t port = 0); + ~RTPIPv4Address(); + + /** Sets the IP address for this instance to \c ip which is assumed to be in host byte order. */ + void SetIP(uint32_t ip) { RTPIPv4Address::ip = ip; } + + /** Sets the IP address of this instance to \c ip. */ + void SetIP(const uint8_t ip[4]) { RTPIPv4Address::ip = (uint32_t)ip[3]; RTPIPv4Address::ip |= (((uint32_t)ip[2])<<8); RTPIPv4Address::ip |= (((uint32_t)ip[1])<<16); RTPIPv4Address::ip |= (((uint32_t)ip[0])<<24); } + + /** Sets the port number for this instance to \c port which is interpreted in host byte order. */ + void SetPort(uint16_t port) { RTPIPv4Address::port = port; } + + /** Returns the IP address contained in this instance in host byte order. */ + uint32_t GetIP() const { return ip; } + + /** Returns the port number of this instance in host byte order. */ + uint16_t GetPort() const { return port; } + + RTPAddress *CreateCopy(RTPMemoryManager *mgr) const; + bool IsSameAddress(const RTPAddress *addr) const; + bool IsFromSameHost(const RTPAddress *addr) const; +#ifdef RTPDEBUG + std::string GetAddressString() const; +#endif // RTPDEBUG +private: + uint32_t ip; + uint16_t port; +}; + +} // end namespace + +#endif // RTPIPV4ADDRESS_H + diff --git a/src/libs/jrtplib/src/rtpipv4destination.h b/src/libs/jrtplib/src/rtpipv4destination.h new file mode 100644 index 00000000..6b0ad5ad --- /dev/null +++ b/src/libs/jrtplib/src/rtpipv4destination.h @@ -0,0 +1,113 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpipv4destination.h + */ + +#ifndef RTPIPV4DESTINATION_H + +#define RTPIPV4DESTINATION_H + +#include "rtpconfig.h" +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + #include + #include + #include +#endif // WIN32 +#ifdef RTPDEBUG + #include "rtpdefines.h" + #include + #include +#endif // RTPDEBUG +#include + +namespace jrtplib +{ + +class JRTPLIB_IMPORTEXPORT RTPIPv4Destination +{ +public: + RTPIPv4Destination(uint32_t ip,uint16_t rtpportbase) + { + memset(&rtpaddr,0,sizeof(struct sockaddr_in)); + memset(&rtcpaddr,0,sizeof(struct sockaddr_in)); + + rtpaddr.sin_family = AF_INET; + rtpaddr.sin_port = htons(rtpportbase); + rtpaddr.sin_addr.s_addr = htonl(ip); + + rtcpaddr.sin_family = AF_INET; + rtcpaddr.sin_port = htons(rtpportbase+1); + rtcpaddr.sin_addr.s_addr = htonl(ip); + + RTPIPv4Destination::ip = ip; + } + + bool operator==(const RTPIPv4Destination &src) const + { + if (rtpaddr.sin_addr.s_addr == src.rtpaddr.sin_addr.s_addr && rtpaddr.sin_port == src.rtpaddr.sin_port) + return true; + return false; + } + uint32_t GetIP() const { return ip; } + // nbo = network byte order + uint32_t GetIP_NBO() const { return rtpaddr.sin_addr.s_addr; } + uint16_t GetRTPPort_NBO() const { return rtpaddr.sin_port; } + uint16_t GetRTCPPort_NBO() const { return rtcpaddr.sin_port; } + const struct sockaddr_in *GetRTPSockAddr() const { return &rtpaddr; } + const struct sockaddr_in *GetRTCPSockAddr() const { return &rtcpaddr; } +#ifdef RTPDEBUG + std::string GetDestinationString() const; +#endif // RTPDEBUG +private: + uint32_t ip; + struct sockaddr_in rtpaddr; + struct sockaddr_in rtcpaddr; +}; + +#ifdef RTPDEBUG +inline std::string RTPIPv4Destination::GetDestinationString() const +{ + char str[24]; + uint32_t ip = GetIP(); + uint16_t portbase = ntohs(GetRTPPort_NBO()); + + RTP_SNPRINTF(str,24,"%d.%d.%d.%d:%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF),(int)(portbase)); + return std::string(str); +} +#endif // RTPDEBUG + +} // end namespace + +#endif // RTPIPV4DESTINATION_H + diff --git a/src/libs/jrtplib/src/rtpipv6address.cpp b/src/libs/jrtplib/src/rtpipv6address.cpp new file mode 100644 index 00000000..9c0844ba --- /dev/null +++ b/src/libs/jrtplib/src/rtpipv6address.cpp @@ -0,0 +1,113 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpipv6address.h" +#include "rtpmemorymanager.h" + +#ifdef RTP_SUPPORT_IPV6 + +#ifdef RTPDEBUG + #include "rtpdefines.h" + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTPAddress *RTPIPv6Address::CreateCopy(RTPMemoryManager *mgr) const +{ + RTPIPv6Address *newaddr = RTPNew(mgr,RTPMEM_TYPE_CLASS_RTPADDRESS) RTPIPv6Address(ip,port); + return newaddr; +} + +bool RTPIPv6Address::IsSameAddress(const RTPAddress *addr) const +{ + if (addr == 0) + return false; + if (addr->GetAddressType() != RTPAddress::IPv6Address) + return false; + + const RTPIPv6Address *addr2 = (const RTPIPv6Address *)addr; + const uint8_t *ip2 = addr2->ip.s6_addr; + + if (port != addr2->port) + return false; + + for (int i = 0 ; i < 16 ; i++) + { + if (ip.s6_addr[i] != ip2[i]) + return false; + } + return true; +} + +bool RTPIPv6Address::IsFromSameHost(const RTPAddress *addr) const +{ + if (addr == 0) + return false; + if (addr->GetAddressType() != RTPAddress::IPv6Address) + return false; + + const RTPIPv6Address *addr2 = (const RTPIPv6Address *)addr; + const uint8_t *ip2 = addr2->ip.s6_addr; + for (int i = 0 ; i < 16 ; i++) + { + if (ip.s6_addr[i] != ip2[i]) + return false; + } + return true; +} + +#ifdef RTPDEBUG +std::string RTPIPv6Address::GetAddressString() const +{ + char str[48]; + uint16_t ip16[8]; + int i,j; + + for (i = 0,j = 0 ; j < 8 ; j++,i += 2) + { + ip16[j] = (((uint16_t)ip.s6_addr[i])<<8); + ip16[j] |= ((uint16_t)ip.s6_addr[i+1]); + } + + RTP_SNPRINTF(str,48,"%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X/%d",(int)ip16[0],(int)ip16[1],(int)ip16[2],(int)ip16[3],(int)ip16[4],(int)ip16[5],(int)ip16[6],(int)ip16[7],(int)port); + return std::string(str); +} +#endif // RTPDEBUG + +} // end namespace + +#endif // RTP_SUPPORT_IPV6 + diff --git a/src/libs/jrtplib/src/rtpipv6address.h b/src/libs/jrtplib/src/rtpipv6address.h new file mode 100644 index 00000000..dfbbbb5e --- /dev/null +++ b/src/libs/jrtplib/src/rtpipv6address.h @@ -0,0 +1,110 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpipv6address.h + */ + +#ifndef RTPIPV6ADDRESS_H + +#define RTPIPV6ADDRESS_H + +#include "rtpconfig.h" + +#ifdef RTP_SUPPORT_IPV6 + +#include "rtpaddress.h" +#include "rtptypes.h" +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + #include +#endif // WIN32 + +namespace jrtplib +{ + +/** Represents an IPv6 IP address and port. + * This class is used by the UDP over IPv4 transmission component. + * When an RTPIPv6Address is used in one of the multicast functions of the + * transmitter, the port number is ignored. When an instance is used in one of + * the accept or ignore functions of the transmitter, a zero port number represents + * all ports for the specified IP address. + */ +class JRTPLIB_IMPORTEXPORT RTPIPv6Address : public RTPAddress +{ +public: + /** Creates an instance with IP address and port number set to zero. */ + RTPIPv6Address():RTPAddress(IPv6Address) { for (int i = 0 ; i < 16 ; i++) ip.s6_addr[i] = 0; port = 0; } + + /** Creates an instance with IP address \c ip and port number \c port (the port number is assumed to be in + * host byte order). */ + RTPIPv6Address(const uint8_t ip[16],uint16_t port = 0):RTPAddress(IPv6Address) { SetIP(ip); RTPIPv6Address::port = port; } + + /** Creates an instance with IP address \c ip and port number \c port (the port number is assumed to be in + * host byte order). */ + RTPIPv6Address(in6_addr ip,uint16_t port = 0):RTPAddress(IPv6Address) { RTPIPv6Address::ip = ip; RTPIPv6Address::port = port; } + ~RTPIPv6Address() { } + + /** Sets the IP address for this instance to \c ip. */ + void SetIP(in6_addr ip) { RTPIPv6Address::ip = ip; } + + /** Sets the IP address for this instance to \c ip. */ + void SetIP(const uint8_t ip[16]) { for (int i = 0 ; i < 16 ; i++) RTPIPv6Address::ip.s6_addr[i] = ip[i]; } + + /** Sets the port number for this instance to \c port, which is interpreted in host byte order. */ + void SetPort(uint16_t port) { RTPIPv6Address::port = port; } + + /** Copies the IP address of this instance in \c ip. */ + void GetIP(uint8_t ip[16]) const { for (int i = 0 ; i < 16 ; i++) ip[i] = RTPIPv6Address::ip.s6_addr[i]; } + + /** Returns the IP address of this instance. */ + in6_addr GetIP() const { return ip; } + + /** Returns the port number contained in this instance in host byte order. */ + uint16_t GetPort() const { return port; } + + RTPAddress *CreateCopy(RTPMemoryManager *mgr) const; + bool IsSameAddress(const RTPAddress *addr) const; + bool IsFromSameHost(const RTPAddress *addr) const; +#ifdef RTPDEBUG + std::string GetAddressString() const; +#endif // RTPDEBUG +private: + in6_addr ip; + uint16_t port; +}; + +} // end namespace + +#endif // RTP_SUPPORT_IPV6 + +#endif // RTPIPV6ADDRESS_H + diff --git a/src/libs/jrtplib/src/rtpipv6destination.h b/src/libs/jrtplib/src/rtpipv6destination.h new file mode 100644 index 00000000..3b322fa2 --- /dev/null +++ b/src/libs/jrtplib/src/rtpipv6destination.h @@ -0,0 +1,114 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpipv6destination.h + */ + +#ifndef RTPIPV6DESTINATION_H + +#define RTPIPV6DESTINATION_H + +#include "rtpconfig.h" + +#ifdef RTP_SUPPORT_IPV6 + +#include "rtptypes.h" +#include +#ifndef WIN32 + #include + #include + #include +#endif // WIN32 +#ifdef RTPDEBUG + #include "rtpdefines.h" + #include + #include +#endif // RTPDEBUG + +namespace jrtplib +{ + +class JRTPLIB_IMPORTEXPORT RTPIPv6Destination +{ +public: + RTPIPv6Destination(in6_addr ip,uint16_t portbase) + { + memset(&rtpaddr,0,sizeof(struct sockaddr_in6)); + memset(&rtcpaddr,0,sizeof(struct sockaddr_in6)); + rtpaddr.sin6_family = AF_INET6; + rtpaddr.sin6_port = htons(portbase); + rtpaddr.sin6_addr = ip; + rtcpaddr.sin6_family = AF_INET6; + rtcpaddr.sin6_port = htons(portbase+1); + rtcpaddr.sin6_addr = ip; + } + in6_addr GetIP() const { return rtpaddr.sin6_addr; } + bool operator==(const RTPIPv6Destination &src) const + { + if (rtpaddr.sin6_port == src.rtpaddr.sin6_port && (memcmp(&(src.rtpaddr.sin6_addr),&(rtpaddr.sin6_addr),sizeof(in6_addr)) == 0)) + return true; + return false; + } + const struct sockaddr_in6 *GetRTPSockAddr() const { return &rtpaddr; } + const struct sockaddr_in6 *GetRTCPSockAddr() const { return &rtcpaddr; } +#ifdef RTPDEBUG + std::string GetDestinationString() const; +#endif // RTPDEBUG +private: + struct sockaddr_in6 rtpaddr; + struct sockaddr_in6 rtcpaddr; +}; + +#ifdef RTPDEBUG +inline std::string RTPIPv6Destination::GetDestinationString() const +{ + uint16_t ip16[8]; + char str[48]; + uint16_t portbase = ntohs(rtpaddr.sin6_port); + int i,j; + for (i = 0,j = 0 ; j < 8 ; j++,i += 2) + { + ip16[j] = (((uint16_t)rtpaddr.sin6_addr.s6_addr[i])<<8); + ip16[j] |= ((uint16_t)rtpaddr.sin6_addr.s6_addr[i+1]); + } + RTP_SNPRINTF(str,48,"%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X/%d",(int)ip16[0],(int)ip16[1],(int)ip16[2],(int)ip16[3],(int)ip16[4],(int)ip16[5],(int)ip16[6],(int)ip16[7],(int)portbase); + return std::string(str); +} +#endif // RTPDEBUG + +} // end namespace + +#endif // RTP_SUPPORT_IPV6 + +#endif // RTPIPV6DESTINATION_H + diff --git a/src/libs/jrtplib/src/rtpkeyhashtable.h b/src/libs/jrtplib/src/rtpkeyhashtable.h new file mode 100644 index 00000000..1d334a9f --- /dev/null +++ b/src/libs/jrtplib/src/rtpkeyhashtable.h @@ -0,0 +1,344 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpkeyhashtable.h + */ + +#ifndef RTPKEYHASHTABLE_H + +#define RTPKEYHASHTABLE_H + +#include "rtpconfig.h" +#include "rtperrors.h" +#include "rtpmemoryobject.h" + +#ifdef RTPDEBUG +#include +#endif // RTPDEBUG + +namespace jrtplib +{ + +template +class RTPKeyHashTable : public RTPMemoryObject +{ +public: + RTPKeyHashTable(RTPMemoryManager *mgr = 0,int memtype = RTPMEM_TYPE_OTHER); + ~RTPKeyHashTable() { Clear(); } + + void GotoFirstElement() { curhashelem = firsthashelem; } + void GotoLastElement() { curhashelem = lasthashelem; } + bool HasCurrentElement() { return (curhashelem == 0)?false:true; } + int DeleteCurrentElement(); + Element &GetCurrentElement() { return curhashelem->GetElement(); } + Key &GetCurrentKey() { return curhashelem->GetKey(); } + int GotoElement(const Key &k); + bool HasElement(const Key &k); + void GotoNextElement(); + void GotoPreviousElement(); + void Clear(); + + int AddElement(const Key &k,const Element &elem); + int DeleteElement(const Key &k); + +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG +private: + class HashElement + { + public: + HashElement(const Key &k,const Element &e,int index):key(k),element(e) { hashprev = 0; hashnext = 0; listnext = 0; listprev = 0; hashindex = index; } + int GetHashIndex() { return hashindex; } + Key &GetKey() { return key; } + Element &GetElement() { return element; } +#ifdef RTPDEBUG + void Dump() { std::cout << "\tHash index " << hashindex << " | Key " << key << " | Element " << element << std::endl; } +#endif // RTPDEBUG + private: + int hashindex; + Key key; + Element element; + public: + HashElement *hashprev,*hashnext; + HashElement *listprev,*listnext; + }; + + HashElement *table[hashsize]; + HashElement *firsthashelem,*lasthashelem; + HashElement *curhashelem; +#ifdef RTP_SUPPORT_MEMORYMANAGEMENT + int memorytype; +#endif // RTP_SUPPORT_MEMORYMANAGEMENT +}; + +template +inline RTPKeyHashTable::RTPKeyHashTable(RTPMemoryManager *mgr,int memtype) : RTPMemoryObject(mgr) +{ + for (int i = 0 ; i < hashsize ; i++) + table[i] = 0; + firsthashelem = 0; + lasthashelem = 0; +#ifdef RTP_SUPPORT_MEMORYMANAGEMENT + memorytype = memtype; +#endif // RTP_SUPPORT_MEMORYMANAGEMENT +} + +template +inline int RTPKeyHashTable::DeleteCurrentElement() +{ + if (curhashelem) + { + HashElement *tmp1,*tmp2; + int index; + + // First, relink elements in current hash bucket + + index = curhashelem->GetHashIndex(); + tmp1 = curhashelem->hashprev; + tmp2 = curhashelem->hashnext; + if (tmp1 == 0) // no previous element in hash bucket + { + table[index] = tmp2; + if (tmp2 != 0) + tmp2->hashprev = 0; + } + else // there is a previous element in the hash bucket + { + tmp1->hashnext = tmp2; + if (tmp2 != 0) + tmp2->hashprev = tmp1; + } + + // Relink elements in list + + tmp1 = curhashelem->listprev; + tmp2 = curhashelem->listnext; + if (tmp1 == 0) // curhashelem is first in list + { + firsthashelem = tmp2; + if (tmp2 != 0) + tmp2->listprev = 0; + else // curhashelem is also last in list + lasthashelem = 0; + } + else + { + tmp1->listnext = tmp2; + if (tmp2 != 0) + tmp2->listprev = tmp1; + else // curhashelem is last in list + lasthashelem = tmp1; + } + + // finally, with everything being relinked, we can delete curhashelem + RTPDelete(curhashelem,GetMemoryManager()); + curhashelem = tmp2; // Set to next element in list + } + else + return ERR_RTP_KEYHASHTABLE_NOCURRENTELEMENT; + return 0; +} + +template +inline int RTPKeyHashTable::GotoElement(const Key &k) +{ + int index; + bool found; + + index = GetIndex::GetIndex(k); + if (index >= hashsize) + return ERR_RTP_KEYHASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX; + + curhashelem = table[index]; + found = false; + while(!found && curhashelem != 0) + { + if (curhashelem->GetKey() == k) + found = true; + else + curhashelem = curhashelem->hashnext; + } + if (!found) + return ERR_RTP_KEYHASHTABLE_KEYNOTFOUND; + return 0; +} + +template +inline bool RTPKeyHashTable::HasElement(const Key &k) +{ + int index; + bool found; + HashElement *tmp; + + index = GetIndex::GetIndex(k); + if (index >= hashsize) + return false; + + tmp = table[index]; + found = false; + while(!found && tmp != 0) + { + if (tmp->GetKey() == k) + found = true; + else + tmp = tmp->hashnext; + } + return found; +} + +template +inline void RTPKeyHashTable::GotoNextElement() +{ + if (curhashelem) + curhashelem = curhashelem->listnext; +} + +template +inline void RTPKeyHashTable::GotoPreviousElement() +{ + if (curhashelem) + curhashelem = curhashelem->listprev; +} + +template +inline void RTPKeyHashTable::Clear() +{ + HashElement *tmp1,*tmp2; + + for (int i = 0 ; i < hashsize ; i++) + table[i] = 0; + + tmp1 = firsthashelem; + while (tmp1 != 0) + { + tmp2 = tmp1->listnext; + RTPDelete(tmp1,GetMemoryManager()); + tmp1 = tmp2; + } + firsthashelem = 0; + lasthashelem = 0; +} + +template +inline int RTPKeyHashTable::AddElement(const Key &k,const Element &elem) +{ + int index; + bool found; + HashElement *e,*newelem; + + index = GetIndex::GetIndex(k); + if (index >= hashsize) + return ERR_RTP_KEYHASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX; + + e = table[index]; + found = false; + while(!found && e != 0) + { + if (e->GetKey() == k) + found = true; + else + e = e->hashnext; + } + if (found) + return ERR_RTP_KEYHASHTABLE_KEYALREADYEXISTS; + + // Okay, the key doesn't exist, so we can add the new element in the hash table + + newelem = RTPNew(GetMemoryManager(),memorytype) HashElement(k,elem,index); + if (newelem == 0) + return ERR_RTP_OUTOFMEM; + + e = table[index]; + table[index] = newelem; + newelem->hashnext = e; + if (e != 0) + e->hashprev = newelem; + + // Now, we still got to add it to the linked list + + if (firsthashelem == 0) + { + firsthashelem = newelem; + lasthashelem = newelem; + } + else // there already are some elements in the list + { + lasthashelem->listnext = newelem; + newelem->listprev = lasthashelem; + lasthashelem = newelem; + } + return 0; +} + +template +inline int RTPKeyHashTable::DeleteElement(const Key &k) +{ + int status; + + status = GotoElement(k); + if (status < 0) + return status; + return DeleteCurrentElement(); +} + +#ifdef RTPDEBUG +template +inline void RTPKeyHashTable::Dump() +{ + HashElement *e; + + std::cout << "DUMPING TABLE CONTENTS:" << std::endl; + for (int i = 0 ; i < hashsize ; i++) + { + e = table[i]; + while (e != 0) + { + e->Dump(); + e = e->hashnext; + } + } + + std::cout << "DUMPING LIST CONTENTS:" << std::endl; + e = firsthashelem; + while (e != 0) + { + e->Dump(); + e = e->listnext; + } +} +#endif // RTPDEBUG + +} // end namespace + +#endif // RTPKEYHASHTABLE_H diff --git a/src/libs/jrtplib/src/rtplibraryversion.cpp b/src/libs/jrtplib/src/rtplibraryversion.cpp new file mode 100644 index 00000000..beb4e6ba --- /dev/null +++ b/src/libs/jrtplib/src/rtplibraryversion.cpp @@ -0,0 +1,55 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtplibraryversion.h" +#include "rtpdefines.h" +#include + +namespace jrtplib +{ + +RTPLibraryVersion RTPLibraryVersion::GetVersion() +{ + return RTPLibraryVersion(3,9,1); +} + +std::string RTPLibraryVersion::GetVersionString() const +{ + char str[16]; + + RTP_SNPRINTF(str,16,"%d.%d.%d",majornr,minornr,debugnr); + + return std::string(str); +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtplibraryversion.h b/src/libs/jrtplib/src/rtplibraryversion.h new file mode 100644 index 00000000..635261ef --- /dev/null +++ b/src/libs/jrtplib/src/rtplibraryversion.h @@ -0,0 +1,77 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtplibraryversion.h + */ + +#ifndef RTPLIBRARYVERSION_H + +#define RTPLIBRARYVERSION_H + +#include "rtpconfig.h" +#include +#include + +namespace jrtplib +{ + +/** + * Used to provide information about the version of the library. + */ +class JRTPLIB_IMPORTEXPORT RTPLibraryVersion +{ +public: + /** Returns an instance of RTPLibraryVersion describing the version of the library. */ + static RTPLibraryVersion GetVersion(); +private: + RTPLibraryVersion(int major,int minor,int debug) { majornr = major; minornr = minor; debugnr = debug; } +public: + /** Returns the major version number. */ + int GetMajorNumber() const { return majornr; } + + /** Returns the minor version number. */ + int GetMinorNumber() const { return minornr; } + + /** Returns the debug version number. */ + int GetDebugNumber() const { return debugnr; } + + /** Returns a string describing the library version. */ + std::string GetVersionString() const; +private: + int debugnr,minornr,majornr; +}; + +} // end namespace + +#endif // RTPLIBRARYVERSION_H + diff --git a/src/libs/jrtplib/src/rtpmemorymanager.h b/src/libs/jrtplib/src/rtpmemorymanager.h new file mode 100644 index 00000000..33843957 --- /dev/null +++ b/src/libs/jrtplib/src/rtpmemorymanager.h @@ -0,0 +1,257 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpmemorymanager.h + */ + +#ifndef RTPMEMORYMANAGER_H + +#define RTPMEMORYMANAGER_H + +#include "rtpconfig.h" +#include "rtptypes.h" + +/** Used to indicate a general kind of memory block. */ +#define RTPMEM_TYPE_OTHER 0 + +/** Buffer to store an incoming RTP packet. */ +#define RTPMEM_TYPE_BUFFER_RECEIVEDRTPPACKET 1 + +/** Buffer to store an incoming RTCP packet. */ +#define RTPMEM_TYPE_BUFFER_RECEIVEDRTCPPACKET 2 + +/** Buffer to store an RTCP APP packet. */ +#define RTPMEM_TYPE_BUFFER_RTCPAPPPACKET 3 + +/** Buffer to store an RTCP BYE packet. */ +#define RTPMEM_TYPE_BUFFER_RTCPBYEPACKET 4 + +/** Buffer to store a BYE reason. */ +#define RTPMEM_TYPE_BUFFER_RTCPBYEREASON 5 + +/** Buffer to store an RTCP compound packet. */ +#define RTPMEM_TYPE_BUFFER_RTCPCOMPOUNDPACKET 6 + +/** Buffer to store an SDES block. */ +#define RTPMEM_TYPE_BUFFER_RTCPSDESBLOCK 7 + +/** Buffer to store an RTP packet. */ +#define RTPMEM_TYPE_BUFFER_RTPPACKET 8 + +/** Buffer used by an RTPPacketBuilder instance. */ +#define RTPMEM_TYPE_BUFFER_RTPPACKETBUILDERBUFFER 9 + +/** Buffer to store an SDES item. */ +#define RTPMEM_TYPE_BUFFER_SDESITEM 10 + +/** Hash element used in the accept/ignore table. */ +#define RTPMEM_TYPE_CLASS_ACCEPTIGNOREHASHELEMENT 11 + +/** Buffer to store a PortInfo instance, used by the UDP over IPv4 and IPv6 transmitters. */ +#define RTPMEM_TYPE_CLASS_ACCEPTIGNOREPORTINFO 12 + +/** Buffer to store a HashElement instance for the destination hash table. */ +#define RTPMEM_TYPE_CLASS_DESTINATIONLISTHASHELEMENT 13 + +/** Buffer to store a HashElement instance for the multicast hash table. */ +#define RTPMEM_TYPE_CLASS_MULTICASTHASHELEMENT 14 + +/** Buffer to store an instance of RTCPAPPPacket. */ +#define RTPMEM_TYPE_CLASS_RTCPAPPPACKET 15 + +/** Buffer to store an instance of RTCPBYEPacket. */ +#define RTPMEM_TYPE_CLASS_RTCPBYEPACKET 16 + +/** Buffer to store an instance of RTCPCompoundPacketBuilder. */ +#define RTPMEM_TYPE_CLASS_RTCPCOMPOUNDPACKETBUILDER 17 + +/** Buffer to store an RTCPReceiverReport instance. */ +#define RTPMEM_TYPE_CLASS_RTCPRECEIVERREPORT 18 + +/** Buffer to store an instance of RTCPRRPacket. */ +#define RTPMEM_TYPE_CLASS_RTCPRRPACKET 19 + +/** Buffer to store an instance of RTCPSDESPacket. */ +#define RTPMEM_TYPE_CLASS_RTCPSDESPACKET 20 + +/** Buffer to store an instance of RTCPSRPacket. */ +#define RTPMEM_TYPE_CLASS_RTCPSRPACKET 21 + +/** Buffer to store an instance of RTCPUnknownPacket. */ +#define RTPMEM_TYPE_CLASS_RTCPUNKNOWNPACKET 22 + +/** Buffer to store an instance of an RTPAddress derived class. */ +#define RTPMEM_TYPE_CLASS_RTPADDRESS 23 + +/** Buffer to store an instance of RTPInternalSourceData. */ +#define RTPMEM_TYPE_CLASS_RTPINTERNALSOURCEDATA 24 + +/** Buffer to store an RTPPacket instance. */ +#define RTPMEM_TYPE_CLASS_RTPPACKET 25 + +/** Buffer to store an RTPPollThread instance. */ +#define RTPMEM_TYPE_CLASS_RTPPOLLTHREAD 26 + +/** Buffer to store an RTPRawPacket instance. */ +#define RTPMEM_TYPE_CLASS_RTPRAWPACKET 27 + +/** Buffer to store an RTPTransmissionInfo derived class. */ +#define RTPMEM_TYPE_CLASS_RTPTRANSMISSIONINFO 28 + +/** Buffer to store an RTPTransmitter derived class. */ +#define RTPMEM_TYPE_CLASS_RTPTRANSMITTER 29 + +/** Buffer to store an SDESPrivateItem instance. */ +#define RTPMEM_TYPE_CLASS_SDESPRIVATEITEM 30 + +/** Buffer to store an SDESSource instance. */ +#define RTPMEM_TYPE_CLASS_SDESSOURCE 31 + +/** Buffer to store a HashElement instance for the source table. */ +#define RTPMEM_TYPE_CLASS_SOURCETABLEHASHELEMENT 32 + +namespace jrtplib +{ + +/** A memory manager. */ +class JRTPLIB_IMPORTEXPORT RTPMemoryManager +{ +public: + RTPMemoryManager() { } + virtual ~RTPMemoryManager() { } + + /** Called to allocate \c numbytes of memory. + * Called to allocate \c numbytes of memory. The \c memtype parameter + * indicates what the purpose of the memory block is. Relevant values + * can be found in rtpmemorymanager.h . Note that the types starting with + * \c RTPMEM_TYPE_CLASS indicate fixed size buffers and that types starting + * with \c RTPMEM_TYPE_BUFFER indicate variable size buffers. + */ + virtual void *AllocateBuffer(size_t numbytes, int memtype) = 0; + + /** Frees the previously allocated memory block \c buffer */ + virtual void FreeBuffer(void *buffer) = 0; +}; + +} // end namespace + +#ifdef RTP_SUPPORT_MEMORYMANAGEMENT + +#include + +inline void *operator new(size_t numbytes, jrtplib::RTPMemoryManager *mgr, int memtype) +{ + if (mgr == 0) + return operator new(numbytes); + return mgr->AllocateBuffer(numbytes,memtype); +} + +inline void operator delete(void *buffer, jrtplib::RTPMemoryManager *mgr, int memtype) +{ + if (mgr == 0) + operator delete(buffer); + else + mgr->FreeBuffer(buffer); +} + +#if defined(WIN32) || defined(_WIN32_WCE) +#if _MSC_VER >= 1300 +inline void *operator new[](size_t numbytes, jrtplib::RTPMemoryManager *mgr, int memtype) +{ + if (mgr == 0) + return operator new[](numbytes); + return mgr->AllocateBuffer(numbytes,memtype); +} + +inline void operator delete[](void *buffer, jrtplib::RTPMemoryManager *mgr, int memtype) +{ + if (mgr == 0) + operator delete[](buffer); + else + mgr->FreeBuffer(buffer); +} +#endif // _MSC_VER >= 1300 +#else +inline void *operator new[](size_t numbytes, jrtplib::RTPMemoryManager *mgr, int memtype) +{ + if (mgr == 0) + return operator new[](numbytes); + return mgr->AllocateBuffer(numbytes,memtype); +} + +inline void operator delete[](void *buffer, jrtplib::RTPMemoryManager *mgr, int memtype) +{ + if (mgr == 0) + operator delete[](buffer); + else + mgr->FreeBuffer(buffer); +} +#endif // WIN32 || _WIN32_WCE + +namespace jrtplib +{ + +inline void RTPDeleteByteArray(uint8_t *buf, RTPMemoryManager *mgr) +{ + if (mgr == 0) + delete [] buf; + else + mgr->FreeBuffer(buf); +} + +template +inline void RTPDelete(ClassName *obj, RTPMemoryManager *mgr) +{ + if (mgr == 0) + delete obj; + else + { + obj->~ClassName(); + mgr->FreeBuffer(obj); + } +} + +} // end namespace + +#define RTPNew(a,b) new(a,b) + +#else + +#define RTPNew(a,b) new +#define RTPDelete(a,b) delete a +#define RTPDeleteByteArray(a,b) delete [] a; + +#endif // RTP_SUPPORT_MEMORYMANAGEMENT + +#endif // RTPMEMORYMANAGER_H + diff --git a/src/libs/jrtplib/src/rtpmemoryobject.h b/src/libs/jrtplib/src/rtpmemoryobject.h new file mode 100644 index 00000000..96c69c59 --- /dev/null +++ b/src/libs/jrtplib/src/rtpmemoryobject.h @@ -0,0 +1,74 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpmemoryobject.h + */ + +#ifndef RTPMEMORYOBJECT_H + +#define RTPMEMORYOBJECT_H + +#include "rtpconfig.h" +#include "rtpmemorymanager.h" + +namespace jrtplib +{ + +class JRTPLIB_IMPORTEXPORT RTPMemoryObject +{ +protected: +#ifdef RTP_SUPPORT_MEMORYMANAGEMENT + RTPMemoryObject(RTPMemoryManager *memmgr) : mgr(memmgr) { } +#else + RTPMemoryObject(RTPMemoryManager * /*memmgr*/) { } +#endif // RTP_SUPPORT_MEMORYMANAGEMENT + virtual ~RTPMemoryObject() { } + +#ifdef RTP_SUPPORT_MEMORYMANAGEMENT + RTPMemoryManager *GetMemoryManager() const { return mgr; } + void SetMemoryManager(RTPMemoryManager *m) { mgr = m; } +#else + RTPMemoryManager *GetMemoryManager() const { return 0; } + void SetMemoryManager(RTPMemoryManager * /*m*/) { } +#endif // RTP_SUPPORT_MEMORYMANAGEMENT + +#ifdef RTP_SUPPORT_MEMORYMANAGEMENT +private: + RTPMemoryManager *mgr; +#endif // RTP_SUPPORT_MEMORYMANAGEMENT +}; + +} // end namespace + +#endif // RTPMEMORYOBJECT_H + diff --git a/src/libs/jrtplib/src/rtppacket.cpp b/src/libs/jrtplib/src/rtppacket.cpp new file mode 100644 index 00000000..90ca24d5 --- /dev/null +++ b/src/libs/jrtplib/src/rtppacket.cpp @@ -0,0 +1,358 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtppacket.h" +#include "rtpstructs.h" +#include "rtpdefines.h" +#include "rtperrors.h" +#include "rtprawpacket.h" +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + #include + #include +#endif // WIN32 + +#ifdef RTPDEBUG + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +namespace jrtplib +{ + +void RTPPacket::Clear() +{ + hasextension = false; + hasmarker = false; + numcsrcs = 0; + payloadtype = 0; + extseqnr = 0; + timestamp = 0; + ssrc = 0; + packet = 0; + payload = 0; + packetlength = 0; + payloadlength = 0; + extid = 0; + extension = 0; + extensionlength = 0; + error = 0; + externalbuffer = false; +} + +RTPPacket::RTPPacket(RTPRawPacket &rawpack,RTPMemoryManager *mgr) : RTPMemoryObject(mgr),receivetime(rawpack.GetReceiveTime()) +{ + Clear(); + error = ParseRawPacket(rawpack); +} + +RTPPacket::RTPPacket(uint8_t payloadtype,const void *payloaddata,size_t payloadlen,uint16_t seqnr, + uint32_t timestamp,uint32_t ssrc,bool gotmarker,uint8_t numcsrcs,const uint32_t *csrcs, + bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, + size_t maxpacksize, RTPMemoryManager *mgr) : RTPMemoryObject(mgr),receivetime(0,0) +{ + Clear(); + error = BuildPacket(payloadtype,payloaddata,payloadlen,seqnr,timestamp,ssrc,gotmarker,numcsrcs, + csrcs,gotextension,extensionid,extensionlen_numwords,extensiondata,0,maxpacksize); +} + +RTPPacket::RTPPacket(uint8_t payloadtype,const void *payloaddata,size_t payloadlen,uint16_t seqnr, + uint32_t timestamp,uint32_t ssrc,bool gotmarker,uint8_t numcsrcs,const uint32_t *csrcs, + bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, + void *buffer,size_t buffersize, RTPMemoryManager *mgr) : RTPMemoryObject(mgr),receivetime(0,0) +{ + Clear(); + if (buffer == 0) + error = ERR_RTP_PACKET_EXTERNALBUFFERNULL; + else if (buffersize <= 0) + error = ERR_RTP_PACKET_ILLEGALBUFFERSIZE; + else + error = BuildPacket(payloadtype,payloaddata,payloadlen,seqnr,timestamp,ssrc,gotmarker,numcsrcs, + csrcs,gotextension,extensionid,extensionlen_numwords,extensiondata,buffer,buffersize); +} + +RTPPacket::~RTPPacket() +{ + if (packet && !externalbuffer) + { + RTPDeleteByteArray(packet,GetMemoryManager()); + } +} + +int RTPPacket::ParseRawPacket(RTPRawPacket &rawpack) +{ + uint8_t *packetbytes; + size_t packetlen; + uint8_t payloadtype; + RTPHeader *rtpheader; + bool marker; + int csrccount; + bool hasextension; + int payloadoffset,payloadlength; + int numpadbytes; + RTPExtensionHeader *rtpextheader; + uint16_t exthdrlen; + + if (!rawpack.IsRTP()) // If we didn't receive it on the RTP port, we'll ignore it + return ERR_RTP_PACKET_INVALIDPACKET; + + // The length should be at least the size of the RTP header + packetlen = rawpack.GetDataLength(); + if (packetlen < sizeof(RTPHeader)) + return ERR_RTP_PACKET_INVALIDPACKET; + + packetbytes = (uint8_t *)rawpack.GetData(); + rtpheader = (RTPHeader *)packetbytes; + + // The version number should be correct + if (rtpheader->version != RTP_VERSION) + return ERR_RTP_PACKET_INVALIDPACKET; + + // We'll check if this is possibly a RTCP packet. For this to be possible + // the marker bit and payload type combined should be either an SR or RR + // identifier + marker = (rtpheader->marker == 0)?false:true; + payloadtype = rtpheader->payloadtype; + if (marker) + { + if (payloadtype == (RTP_RTCPTYPE_SR & 127)) // don't check high bit (this was the marker!!) + return ERR_RTP_PACKET_INVALIDPACKET; + if (payloadtype == (RTP_RTCPTYPE_RR & 127)) + return ERR_RTP_PACKET_INVALIDPACKET; + } + + csrccount = rtpheader->csrccount; + payloadoffset = sizeof(RTPHeader)+(int)(csrccount*sizeof(uint32_t)); + + if (rtpheader->padding) // adjust payload length to take padding into account + { + numpadbytes = (int)packetbytes[packetlen-1]; // last byte contains number of padding bytes + if (numpadbytes <= 0) + return ERR_RTP_PACKET_INVALIDPACKET; + } + else + numpadbytes = 0; + + hasextension = (rtpheader->extension == 0)?false:true; + if (hasextension) // got header extension + { + rtpextheader = (RTPExtensionHeader *)(packetbytes+payloadoffset); + payloadoffset += sizeof(RTPExtensionHeader); + exthdrlen = ntohs(rtpextheader->length); + payloadoffset += ((int)exthdrlen)*sizeof(uint32_t); + } + else + { + rtpextheader = 0; + exthdrlen = 0; + } + + payloadlength = packetlen-numpadbytes-payloadoffset; + if (payloadlength < 0) + return ERR_RTP_PACKET_INVALIDPACKET; + + // Now, we've got a valid packet, so we can create a new instance of RTPPacket + // and fill in the members + + RTPPacket::hasextension = hasextension; + if (hasextension) + { + RTPPacket::extid = ntohs(rtpextheader->extid); + RTPPacket::extensionlength = ((int)ntohs(rtpextheader->length))*sizeof(uint32_t); + RTPPacket::extension = ((uint8_t *)rtpextheader)+sizeof(RTPExtensionHeader); + } + + RTPPacket::hasmarker = marker; + RTPPacket::numcsrcs = csrccount; + RTPPacket::payloadtype = payloadtype; + + // Note: we don't fill in the EXTENDED sequence number here, since we + // don't have information about the source here. We just fill in the low + // 16 bits + RTPPacket::extseqnr = (uint32_t)ntohs(rtpheader->sequencenumber); + + RTPPacket::timestamp = ntohl(rtpheader->timestamp); + RTPPacket::ssrc = ntohl(rtpheader->ssrc); + RTPPacket::packet = packetbytes; + RTPPacket::payload = packetbytes+payloadoffset; + RTPPacket::packetlength = packetlen; + RTPPacket::payloadlength = payloadlength; + + // We'll zero the data of the raw packet, since we're using it here now! + rawpack.ZeroData(); + + return 0; +} + +uint32_t RTPPacket::GetCSRC(int num) const +{ + if (num >= numcsrcs) + return 0; + + uint8_t *csrcpos; + uint32_t *csrcval_nbo; + uint32_t csrcval_hbo; + + csrcpos = packet+sizeof(RTPHeader)+num*sizeof(uint32_t); + csrcval_nbo = (uint32_t *)csrcpos; + csrcval_hbo = ntohl(*csrcval_nbo); + return csrcval_hbo; +} + +int RTPPacket::BuildPacket(uint8_t payloadtype,const void *payloaddata,size_t payloadlen,uint16_t seqnr, + uint32_t timestamp,uint32_t ssrc,bool gotmarker,uint8_t numcsrcs,const uint32_t *csrcs, + bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, + void *buffer,size_t maxsize) +{ + if (numcsrcs > RTP_MAXCSRCS) + return ERR_RTP_PACKET_TOOMANYCSRCS; + + if (payloadtype > 127) // high bit should not be used + return ERR_RTP_PACKET_BADPAYLOADTYPE; + if (payloadtype == 72 || payloadtype == 73) // could cause confusion with rtcp types + return ERR_RTP_PACKET_BADPAYLOADTYPE; + + packetlength = sizeof(RTPHeader); + packetlength += sizeof(uint32_t)*((size_t)numcsrcs); + if (gotextension) + { + packetlength += sizeof(RTPExtensionHeader); + packetlength += sizeof(uint32_t)*((size_t)extensionlen_numwords); + } + packetlength += payloadlen; + + if (maxsize > 0 && packetlength > maxsize) + { + packetlength = 0; + return ERR_RTP_PACKET_DATAEXCEEDSMAXSIZE; + } + + // Ok, now we'll just fill in... + + RTPHeader *rtphdr; + + if (buffer == 0) + { + packet = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTPPACKET) uint8_t [packetlength]; + if (packet == 0) + { + packetlength = 0; + return ERR_RTP_OUTOFMEM; + } + externalbuffer = false; + } + else + { + packet = (uint8_t *)buffer; + externalbuffer = true; + } + + RTPPacket::hasmarker = gotmarker; + RTPPacket::hasextension = gotextension; + RTPPacket::numcsrcs = numcsrcs; + RTPPacket::payloadtype = payloadtype; + RTPPacket::extseqnr = (uint32_t)seqnr; + RTPPacket::timestamp = timestamp; + RTPPacket::ssrc = ssrc; + RTPPacket::payloadlength = payloadlen; + RTPPacket::extid = extensionid; + RTPPacket::extensionlength = ((size_t)extensionlen_numwords)*sizeof(uint32_t); + + rtphdr = (RTPHeader *)packet; + rtphdr->version = RTP_VERSION; + rtphdr->padding = 0; + if (gotmarker) + rtphdr->marker = 1; + else + rtphdr->marker = 0; + if (gotextension) + rtphdr->extension = 1; + else + rtphdr->extension = 0; + rtphdr->csrccount = numcsrcs; + rtphdr->payloadtype = payloadtype&127; // make sure high bit isn't set + rtphdr->sequencenumber = htons(seqnr); + rtphdr->timestamp = htonl(timestamp); + rtphdr->ssrc = htonl(ssrc); + + uint32_t *curcsrc; + int i; + + curcsrc = (uint32_t *)(packet+sizeof(RTPHeader)); + for (i = 0 ; i < numcsrcs ; i++,curcsrc++) + *curcsrc = htonl(csrcs[i]); + + payload = packet+sizeof(RTPHeader)+((size_t)numcsrcs)*sizeof(uint32_t); + if (gotextension) + { + RTPExtensionHeader *rtpexthdr = (RTPExtensionHeader *)payload; + + rtpexthdr->extid = htons(extensionid); + rtpexthdr->length = htons((uint16_t)extensionlen_numwords); + + payload += sizeof(RTPExtensionHeader); + memcpy(payload,extensiondata,RTPPacket::extensionlength); + + payload += RTPPacket::extensionlength; + } + memcpy(payload,payloaddata,payloadlen); + return 0; +} + +#ifdef RTPDEBUG +void RTPPacket::Dump() +{ + int i; + + printf("Payload type: %d\n",(int)GetPayloadType()); + printf("Extended sequence number: 0x%08x\n",GetExtendedSequenceNumber()); + printf("Timestamp: 0x%08x\n",GetTimestamp()); + printf("SSRC: 0x%08x\n",GetSSRC()); + printf("Marker: %s\n",HasMarker()?"yes":"no"); + printf("CSRC count: %d\n",GetCSRCCount()); + for (i = 0 ; i < GetCSRCCount() ; i++) + printf(" CSRC[%02d]: 0x%08x\n",i,GetCSRC(i)); + printf("Payload: %s\n",GetPayloadData()); + printf("Payload length: %d\n",GetPayloadLength()); + printf("Packet length: %d\n",GetPacketLength()); + printf("Extension: %s\n",HasExtension()?"yes":"no"); + if (HasExtension()) + { + printf(" Extension ID: 0x%04x\n",GetExtensionID()); + printf(" Extension data: %s\n",GetExtensionData()); + printf(" Extension length: %d\n",GetExtensionLength()); + } +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtppacket.h b/src/libs/jrtplib/src/rtppacket.h new file mode 100644 index 00000000..74060b20 --- /dev/null +++ b/src/libs/jrtplib/src/rtppacket.h @@ -0,0 +1,184 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtppacket.h + */ + +#ifndef RTPPACKET_H + +#define RTPPACKET_H + +#include "rtpconfig.h" +#include "rtptypes.h" +#include "rtptimeutilities.h" +#include "rtpmemoryobject.h" + +namespace jrtplib +{ + +class RTPRawPacket; + +/** Represents an RTP Packet. + * The RTPPacket class can be used to parse a RTPRawPacket instance if it represents RTP data. + * The class can also be used to create a new RTP packet according to the parameters specified by + * the user. + */ +class JRTPLIB_IMPORTEXPORT RTPPacket : public RTPMemoryObject +{ +public: + /** Creates an RTPPacket instance based upon the data in \c rawpack, optionally installing a memory manager. + * Creates an RTPPacket instance based upon the data in \c rawpack, optionally installing a memory manager. + * If successful, the data is moved from the raw packet to the RTPPacket instance. + */ + RTPPacket(RTPRawPacket &rawpack,RTPMemoryManager *mgr = 0); + + /** Creates a new buffer for an RTP packet and fills in the fields according to the specified parameters. + * Creates a new buffer for an RTP packet and fills in the fields according to the specified parameters. + * If \c maxpacksize is not equal to zero, an error is generated if the total packet size would exceed + * \c maxpacksize. The arguments of the constructor are self-explanatory. Note that the size of a header + * extension is specified in a number of 32-bit words. A memory manager can be installed. + */ + RTPPacket(uint8_t payloadtype,const void *payloaddata,size_t payloadlen,uint16_t seqnr, + uint32_t timestamp,uint32_t ssrc,bool gotmarker,uint8_t numcsrcs,const uint32_t *csrcs, + bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, + size_t maxpacksize, RTPMemoryManager *mgr = 0); + + /** This constructor is similar to the other constructor, but here data is stored in an external buffer + * \c buffer with size \c buffersize. */ + RTPPacket(uint8_t payloadtype,const void *payloaddata,size_t payloadlen,uint16_t seqnr, + uint32_t timestamp,uint32_t ssrc,bool gotmarker,uint8_t numcsrcs,const uint32_t *csrcs, + bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, + void *buffer,size_t buffersize,RTPMemoryManager *mgr = 0); + + virtual ~RTPPacket(); + + /** If an error occurred in one of the constructors, this function returns the error code. */ + int GetCreationError() const { return error; } + + /** Returns \c true if the RTP packet has a header extension and \c false otherwise. */ + bool HasExtension() const { return hasextension; } + + /** Returns \c true if the marker bit was set and \c false otherwise. */ + bool HasMarker() const { return hasmarker; } + + /** Returns the number of CSRCs contained in this packet. */ + int GetCSRCCount() const { return numcsrcs; } + + /** Returns a specific CSRC identifier. + * Returns a specific CSRC identifier. The parameter \c num can go from 0 to GetCSRCCount()-1. + */ + uint32_t GetCSRC(int num) const; + + /** Returns the payload type of the packet. */ + uint8_t GetPayloadType() const { return payloadtype; } + + /** Returns the extended sequence number of the packet. + * Returns the extended sequence number of the packet. When the packet is just received, + * only the low $16$ bits will be set. The high 16 bits can be filled in later. + */ + uint32_t GetExtendedSequenceNumber() const { return extseqnr; } + + /** Returns the sequence number of this packet. */ + uint16_t GetSequenceNumber() const { return (uint16_t)(extseqnr&0x0000FFFF); } + + /** Sets the extended sequence number of this packet to \c seq. */ + void SetExtendedSequenceNumber(uint32_t seq) { extseqnr = seq; } + + /** Returns the timestamp of this packet. */ + uint32_t GetTimestamp() const { return timestamp; } + + /** Returns the SSRC identifier stored in this packet. */ + uint32_t GetSSRC() const { return ssrc; } + + /** Returns a pointer to the data of the entire packet. */ + uint8_t *GetPacketData() const { return packet; } + + /** Returns a pointer to the actual payload data. */ + uint8_t *GetPayloadData() const { return payload; } + + /** Returns the length of the entire packet. */ + size_t GetPacketLength() const { return packetlength; } + + /** Returns the payload length. */ + size_t GetPayloadLength() const { return payloadlength; } + void SetPayloadLength(size_t l) { payloadlength = l; } + + /** If a header extension is present, this function returns the extension identifier. */ + uint16_t GetExtensionID() const { return extid; } + + /** Returns the length of the header extension data. */ + uint8_t *GetExtensionData() const { return extension; } + + /** Returns the length of the header extension data. */ + size_t GetExtensionLength() const { return extensionlength; } +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG + + /** Returns the time at which this packet was received. + * When an RTPPacket instance is created from an RTPRawPacket instance, the raw packet's + * reception time is stored in the RTPPacket instance. This function then retrieves that + * time. + */ + RTPTime GetReceiveTime() const { return receivetime; } +private: + void Clear(); + int ParseRawPacket(RTPRawPacket &rawpack); + int BuildPacket(uint8_t payloadtype,const void *payloaddata,size_t payloadlen,uint16_t seqnr, + uint32_t timestamp,uint32_t ssrc,bool gotmarker,uint8_t numcsrcs,const uint32_t *csrcs, + bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, + void *buffer,size_t maxsize); + + int error; + + bool hasextension,hasmarker; + int numcsrcs; + + uint8_t payloadtype; + uint32_t extseqnr,timestamp,ssrc; + uint8_t *packet,*payload; + size_t packetlength,payloadlength; + + uint16_t extid; + uint8_t *extension; + size_t extensionlength; + + bool externalbuffer; + + RTPTime receivetime; +}; + +} // end namespace + +#endif // RTPPACKET_H + diff --git a/src/libs/jrtplib/src/rtppacketbuilder.cpp b/src/libs/jrtplib/src/rtppacketbuilder.cpp new file mode 100644 index 00000000..d72d2b62 --- /dev/null +++ b/src/libs/jrtplib/src/rtppacketbuilder.cpp @@ -0,0 +1,274 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtppacketbuilder.h" +#include "rtperrors.h" +#include "rtppacket.h" +#include "rtpsources.h" +#include +#include +#ifdef RTPDEBUG + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTPPacketBuilder::RTPPacketBuilder(RTPRandom &r,RTPMemoryManager *mgr) : RTPMemoryObject(mgr),rtprnd(r),lastwallclocktime(0,0) +{ + init = false; +#if (defined(WIN32) || defined(_WIN32_WCE)) + timeinit.Dummy(); +#endif // WIN32 || _WIN32_WCE + + //std::cout << (void *)(&rtprnd) << std::endl; +} + +RTPPacketBuilder::~RTPPacketBuilder() +{ + Destroy(); +} + +int RTPPacketBuilder::Init(size_t max) +{ + if (init) + return ERR_RTP_PACKBUILD_ALREADYINIT; + if (max <= 0) + return ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE; + + maxpacksize = max; + buffer = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTPPACKETBUILDERBUFFER) uint8_t [max]; + if (buffer == 0) + return ERR_RTP_OUTOFMEM; + packetlength = 0; + + CreateNewSSRC(); + + deftsset = false; + defptset = false; + defmarkset = false; + + numcsrcs = 0; + + init = true; + return 0; +} + +void RTPPacketBuilder::Destroy() +{ + if (!init) + return; + RTPDeleteByteArray(buffer,GetMemoryManager()); + init = false; +} + +int RTPPacketBuilder::SetMaximumPacketSize(size_t max) +{ + uint8_t *newbuf; + + if (max <= 0) + return ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE; + newbuf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTPPACKETBUILDERBUFFER) uint8_t[max]; + if (newbuf == 0) + return ERR_RTP_OUTOFMEM; + + RTPDeleteByteArray(buffer,GetMemoryManager()); + buffer = newbuf; + maxpacksize = max; + return 0; +} + +int RTPPacketBuilder::AddCSRC(uint32_t csrc) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + if (numcsrcs >= RTP_MAXCSRCS) + return ERR_RTP_PACKBUILD_CSRCLISTFULL; + + int i; + + for (i = 0 ; i < numcsrcs ; i++) + { + if (csrcs[i] == csrc) + return ERR_RTP_PACKBUILD_CSRCALREADYINLIST; + } + csrcs[numcsrcs] = csrc; + numcsrcs++; + return 0; +} + +int RTPPacketBuilder::DeleteCSRC(uint32_t csrc) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + + int i = 0; + bool found = false; + + while (!found && i < numcsrcs) + { + if (csrcs[i] == csrc) + found = true; + else + i++; + } + + if (!found) + return ERR_RTP_PACKBUILD_CSRCNOTINLIST; + + // move the last csrc in the place of the deleted one + numcsrcs--; + if (numcsrcs > 0 && numcsrcs != i) + csrcs[i] = csrcs[numcsrcs]; + return 0; +} + +void RTPPacketBuilder::ClearCSRCList() +{ + if (!init) + return; + numcsrcs = 0; +} + +uint32_t RTPPacketBuilder::CreateNewSSRC() +{ + ssrc = rtprnd.GetRandom32(); + timestamp = rtprnd.GetRandom32(); + seqnr = rtprnd.GetRandom16() / 2; + + // p 38: the count SHOULD be reset if the sender changes its SSRC identifier + numpayloadbytes = 0; + numpackets = 0; + return ssrc; +} + +uint32_t RTPPacketBuilder::CreateNewSSRC(RTPSources &sources) +{ + bool found; + + do + { + ssrc = rtprnd.GetRandom32(); + found = sources.GotEntry(ssrc); + } while (found); + + timestamp = rtprnd.GetRandom32(); + seqnr = rtprnd.GetRandom16() / 2; + + // p 38: the count SHOULD be reset if the sender changes its SSRC identifier + numpayloadbytes = 0; + numpackets = 0; + return ssrc; +} + +int RTPPacketBuilder::BuildPacket(const void *data,size_t len) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + if (!defptset) + return ERR_RTP_PACKBUILD_DEFAULTPAYLOADTYPENOTSET; + if (!defmarkset) + return ERR_RTP_PACKBUILD_DEFAULTMARKNOTSET; + if (!deftsset) + return ERR_RTP_PACKBUILD_DEFAULTTSINCNOTSET; + return PrivateBuildPacket(data,len,defaultpayloadtype,defaultmark,defaulttimestampinc,false); +} + +int RTPPacketBuilder::BuildPacket(const void *data,size_t len, + uint8_t pt,bool mark,uint32_t timestampinc) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + return PrivateBuildPacket(data,len,pt,mark,timestampinc,false); +} + +int RTPPacketBuilder::BuildPacketEx(const void *data,size_t len, + uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + if (!defptset) + return ERR_RTP_PACKBUILD_DEFAULTPAYLOADTYPENOTSET; + if (!defmarkset) + return ERR_RTP_PACKBUILD_DEFAULTMARKNOTSET; + if (!deftsset) + return ERR_RTP_PACKBUILD_DEFAULTTSINCNOTSET; + return PrivateBuildPacket(data,len,defaultpayloadtype,defaultmark,defaulttimestampinc,true,hdrextID,hdrextdata,numhdrextwords); +} + +int RTPPacketBuilder::BuildPacketEx(const void *data,size_t len, + uint8_t pt,bool mark,uint32_t timestampinc, + uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + return PrivateBuildPacket(data,len,pt,mark,timestampinc,true,hdrextID,hdrextdata,numhdrextwords); + +} + +int RTPPacketBuilder::PrivateBuildPacket(const void *data,size_t len, + uint8_t pt,bool mark,uint32_t timestampinc,bool gotextension, + uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords) +{ + RTPPacket p(pt,data,len,seqnr,timestamp,ssrc,mark,numcsrcs,csrcs,gotextension,hdrextID, + (uint16_t)numhdrextwords,hdrextdata,buffer,maxpacksize,GetMemoryManager()); + int status = p.GetCreationError(); + + if (status < 0) + return status; + packetlength = p.GetPacketLength(); + + if (numpackets == 0) // first packet + { + lastwallclocktime = RTPTime::CurrentTime(); + lastrtptimestamp = timestamp; + prevrtptimestamp = timestamp; + } + else if (timestamp != prevrtptimestamp) + { + lastwallclocktime = RTPTime::CurrentTime(); + lastrtptimestamp = timestamp; + prevrtptimestamp = timestamp; + } + + numpayloadbytes += (uint32_t)p.GetPayloadLength(); + numpackets++; + timestamp += timestampinc; + seqnr++; + + return 0; +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtppacketbuilder.h b/src/libs/jrtplib/src/rtppacketbuilder.h new file mode 100644 index 00000000..dd06faf3 --- /dev/null +++ b/src/libs/jrtplib/src/rtppacketbuilder.h @@ -0,0 +1,274 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtppacketbuilder.h + */ + +#ifndef RTPPACKETBUILDER_H + +#define RTPPACKETBUILDER_H + +#include "rtpconfig.h" +#include "rtperrors.h" +#include "rtpdefines.h" +#include "rtprandom.h" +#include "rtptimeutilities.h" +#include "rtptypes.h" +#include "rtpmemoryobject.h" + +namespace jrtplib +{ + +class RTPSources; + +/** This class can be used to build RTP packets and is a bit more high-level than the RTPPacket + * class: it generates an SSRC identifier, keeps track of timestamp and sequence number etc. + */ +class JRTPLIB_IMPORTEXPORT RTPPacketBuilder : public RTPMemoryObject +{ +public: + /** Constructs an instance which will use \c rtprand for generating random numbers + * (used to initialize the SSRC value and sequence number), optionally installing a memory manager. + **/ + RTPPacketBuilder(RTPRandom &rtprand, RTPMemoryManager *mgr = 0); + ~RTPPacketBuilder(); + + /** Initializes the builder to only allow packets with a size below \c maxpacksize. */ + int Init(size_t maxpacksize); + + /** Cleans up the builder. */ + void Destroy(); + + /** Returns the number of packets which have been created with the current SSRC identifier. */ + uint32_t GetPacketCount() { if (!init) return 0; return numpackets; } + + /** Returns the number of payload octets which have been generated with this SSRC identifier. */ + uint32_t GetPayloadOctetCount() { if (!init) return 0; return numpayloadbytes; } + + /** Sets the maximum allowed packet size to \c maxpacksize. */ + int SetMaximumPacketSize(size_t maxpacksize); + + /** Adds a CSRC to the CSRC list which will be stored in the RTP packets. */ + int AddCSRC(uint32_t csrc); + + /** Deletes a CSRC from the list which will be stored in the RTP packets. */ + int DeleteCSRC(uint32_t csrc); + + /** Clears the CSRC list. */ + void ClearCSRCList(); + + /** Builds a packet with payload \c data and payload length \c len. + * Builds a packet with payload \c data and payload length \c len. The payload type, marker + * and timestamp increment used will be those that have been set using the \c SetDefault + * functions below. + */ + int BuildPacket(const void *data,size_t len); + + /** Builds a packet with payload \c data and payload length \c len. + * Builds a packet with payload \c data and payload length \c len. The payload type will be + * set to \c pt, the marker bit to \c mark and after building this packet, the timestamp will + * be incremented with \c timestamp. + */ + int BuildPacket(const void *data,size_t len, + uint8_t pt,bool mark,uint32_t timestampinc); + + /** Builds a packet with payload \c data and payload length \c len. + * Builds a packet with payload \c data and payload length \c len. The payload type, marker + * and timestamp increment used will be those that have been set using the \c SetDefault + * functions below. This packet will also contain an RTP header extension with identifier + * \c hdrextID and data \c hdrextdata. The length of the header extension data is given by + * \c numhdrextwords which expresses the length in a number of 32-bit words. + */ + int BuildPacketEx(const void *data,size_t len, + uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords); + + /** Builds a packet with payload \c data and payload length \c len. + * Builds a packet with payload \c data and payload length \c len. The payload type will be set + * to \c pt, the marker bit to \c mark and after building this packet, the timestamp will + * be incremented with \c timestamp. This packet will also contain an RTP header extension + * with identifier \c hdrextID and data \c hdrextdata. The length of the header extension + * data is given by \c numhdrextwords which expresses the length in a number of 32-bit words. + */ + int BuildPacketEx(const void *data,size_t len, + uint8_t pt,bool mark,uint32_t timestampinc, + uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords); + + /** Returns a pointer to the last built RTP packet data. */ + uint8_t *GetPacket() { if (!init) return 0; return buffer; } + + /** Returns the size of the last built RTP packet. */ + size_t GetPacketLength() { if (!init) return 0; return packetlength; } + + /** Sets the default payload type to \c pt. */ + int SetDefaultPayloadType(uint8_t pt); + + /** Sets the default marker bit to \c m. */ + int SetDefaultMark(bool m); + + /** Sets the default timestamp increment to \c timestampinc. */ + int SetDefaultTimestampIncrement(uint32_t timestampinc); + + /** This function increments the timestamp with the amount given by \c inc. + * This function increments the timestamp with the amount given by \c inc. This can be useful + * if, for example, a packet was not sent because it contained only silence. Then, this function + * should be called to increment the timestamp with the appropriate amount so that the next packets + * will still be played at the correct time at other hosts. + */ + int IncrementTimestamp(uint32_t inc); + + /** This function increments the timestamp with the amount given set by the SetDefaultTimestampIncrement + * member function. + * This function increments the timestamp with the amount given set by the SetDefaultTimestampIncrement + * member function. This can be useful if, for example, a packet was not sent because it contained only silence. + * Then, this function should be called to increment the timestamp with the appropriate amount so that the next + * packets will still be played at the correct time at other hosts. + */ + int IncrementTimestampDefault(); + + /** Creates a new SSRC to be used in generated packets. + * Creates a new SSRC to be used in generated packets. This will also generate new timestamp and + * sequence number offsets. + */ + uint32_t CreateNewSSRC(); + + /** Creates a new SSRC to be used in generated packets. + * Creates a new SSRC to be used in generated packets. This will also generate new timestamp and + * sequence number offsets. The source table \c sources is used to make sure that the chosen SSRC + * isn't used by another participant yet. + */ + uint32_t CreateNewSSRC(RTPSources &sources); + + /** Returns the current SSRC identifier. */ + uint32_t GetSSRC() const { if (!init) return 0; return ssrc; } + + /** Returns the current RTP timestamp. */ + uint32_t GetTimestamp() const { if (!init) return 0; return timestamp; } + + /** Returns the current sequence number. */ + uint16_t GetSequenceNumber() const { if (!init) return 0; return seqnr; } + + /** Returns the time at which a packet was generated. + * Returns the time at which a packet was generated. This is not necessarily the time at which + * the last RTP packet was generated: if the timestamp increment was zero, the time is not updated. + */ + RTPTime GetPacketTime() const { if (!init) return RTPTime(0,0); return lastwallclocktime; } + + /** Returns the RTP timestamp which corresponds to the time returned by the previous function. */ + uint32_t GetPacketTimestamp() const { if (!init) return 0; return lastrtptimestamp; } + + /** Sets a specific SSRC to be used. + * Sets a specific SSRC to be used. Does not create a new timestamp offset or sequence number + * offset. Does not reset the packet count or byte count. Think twice before using this! + */ + void AdjustSSRC(uint32_t s) { ssrc = s; } +private: + int PrivateBuildPacket(const void *data,size_t len, + uint8_t pt,bool mark,uint32_t timestampinc,bool gotextension, + uint16_t hdrextID = 0,const void *hdrextdata = 0,size_t numhdrextwords = 0); + + RTPRandom &rtprnd; + size_t maxpacksize; + uint8_t *buffer; + size_t packetlength; + + uint32_t numpayloadbytes; + uint32_t numpackets; + bool init; + + uint32_t ssrc; + uint32_t timestamp; + uint16_t seqnr; + + uint32_t defaulttimestampinc; + uint8_t defaultpayloadtype; + bool defaultmark; + + bool deftsset,defptset,defmarkset; + + uint32_t csrcs[RTP_MAXCSRCS]; + int numcsrcs; + + RTPTime lastwallclocktime; + uint32_t lastrtptimestamp; + uint32_t prevrtptimestamp; +}; + +inline int RTPPacketBuilder::SetDefaultPayloadType(uint8_t pt) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + defptset = true; + defaultpayloadtype = pt; + return 0; +} + +inline int RTPPacketBuilder::SetDefaultMark(bool m) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + defmarkset = true; + defaultmark = m; + return 0; +} + +inline int RTPPacketBuilder::SetDefaultTimestampIncrement(uint32_t timestampinc) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + deftsset = true; + defaulttimestampinc = timestampinc; + return 0; +} + +inline int RTPPacketBuilder::IncrementTimestamp(uint32_t inc) +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + timestamp += inc; + return 0; +} + +inline int RTPPacketBuilder::IncrementTimestampDefault() +{ + if (!init) + return ERR_RTP_PACKBUILD_NOTINIT; + if (!deftsset) + return ERR_RTP_PACKBUILD_DEFAULTTSINCNOTSET; + timestamp += defaulttimestampinc; + return 0; +} + +} // end namespace + +#endif // RTPPACKETBUILDER_H + diff --git a/src/libs/jrtplib/src/rtppollthread.cpp b/src/libs/jrtplib/src/rtppollthread.cpp new file mode 100644 index 00000000..a9650d19 --- /dev/null +++ b/src/libs/jrtplib/src/rtppollthread.cpp @@ -0,0 +1,180 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtppollthread.h" + +#ifdef RTP_SUPPORT_THREAD + +#include "rtpsession.h" +#include "rtcpscheduler.h" +#include "rtperrors.h" +#include "rtprawpacket.h" +#include + +#ifndef _WIN32_WCE + #include +#endif // _WIN32_WCE + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTPPollThread::RTPPollThread(RTPSession &session,RTCPScheduler &sched):rtpsession(session),rtcpsched(sched) +{ + stop = false; + transmitter = 0; +#if (defined(WIN32) || defined(_WIN32_WCE)) + timeinit.Dummy(); +#endif // WIN32 || _WIN32_WCE +} + +RTPPollThread::~RTPPollThread() +{ + Stop(); +} + +int RTPPollThread::Start(RTPTransmitter *trans) +{ + if (JThread::IsRunning()) + return ERR_RTP_POLLTHREAD_ALREADYRUNNING; + + transmitter = trans; + if (!stopmutex.IsInitialized()) + { + if (stopmutex.Init() < 0) + return ERR_RTP_POLLTHREAD_CANTINITMUTEX; + } + stop = false; + if (JThread::Start() < 0) + return ERR_RTP_POLLTHREAD_CANTSTARTTHREAD; + return 0; +} + +void RTPPollThread::Stop() +{ + if (!IsRunning()) + return; + + stopmutex.Lock(); + stop = true; + stopmutex.Unlock(); + + if (transmitter) + transmitter->AbortWait(); + + RTPTime thetime = RTPTime::CurrentTime(); + bool done = false; + + while (JThread::IsRunning() && !done) + { + // wait max 5 sec + RTPTime curtime = RTPTime::CurrentTime(); + if ((curtime.GetDouble()-thetime.GetDouble()) > 5.0) + done = true; + RTPTime::Wait(RTPTime(0,10000)); + } + + if (JThread::IsRunning()) + { +#ifndef _WIN32_WCE + std::cerr << "RTPPollThread: Warning! Having to kill thread!" << std::endl; +#endif // _WIN32_WCE + JThread::Kill(); + } + stop = false; + transmitter = 0; +} + +void *RTPPollThread::Thread() +{ + JThread::ThreadStarted(); + + bool stopthread; + + stopmutex.Lock(); + stopthread = stop; + stopmutex.Unlock(); + + rtpsession.OnPollThreadStart(stopthread); + + while (!stopthread) + { + int status; + + rtpsession.schedmutex.Lock(); + rtpsession.sourcesmutex.Lock(); + + RTPTime rtcpdelay = rtcpsched.GetTransmissionDelay(); + + rtpsession.sourcesmutex.Unlock(); + rtpsession.schedmutex.Unlock(); + + if ((status = transmitter->WaitForIncomingData(rtcpdelay)) < 0) + { + stopthread = true; + rtpsession.OnPollThreadError(status); + } + else + { + if ((status = transmitter->Poll()) < 0) + { + stopthread = true; + rtpsession.OnPollThreadError(status); + } + else + { + if ((status = rtpsession.ProcessPolledData()) < 0) + { + stopthread = true; + rtpsession.OnPollThreadError(status); + } + else + { + rtpsession.OnPollThreadStep(); + stopmutex.Lock(); + stopthread = stop; + stopmutex.Unlock(); + } + } + } + } + + rtpsession.OnPollThreadStop(); + + return 0; +} + +} // end namespace + +#endif // RTP_SUPPORT_THREAD + diff --git a/src/libs/jrtplib/src/rtppollthread.h b/src/libs/jrtplib/src/rtppollthread.h new file mode 100644 index 00000000..ac681306 --- /dev/null +++ b/src/libs/jrtplib/src/rtppollthread.h @@ -0,0 +1,79 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtppollthread.h + */ + +#ifndef RTPPOLLTHREAD_H + +#define RTPPOLLTHREAD_H + +#include "rtpconfig.h" + +#ifdef RTP_SUPPORT_THREAD + +#include "rtptransmitter.h" + +#include +#include +#include + +namespace jrtplib +{ + +class RTPSession; +class RTCPScheduler; + +class JRTPLIB_IMPORTEXPORT RTPPollThread : private jthread::JThread +{ +public: + RTPPollThread(RTPSession &session,RTCPScheduler &rtcpsched); + ~RTPPollThread(); + int Start(RTPTransmitter *trans); + void Stop(); +private: + void *Thread(); + + bool stop; + jthread::JMutex stopmutex; + RTPTransmitter *transmitter; + + RTPSession &rtpsession; + RTCPScheduler &rtcpsched; +}; + +} // end namespace + +#endif // RTP_SUPPORT_THREAD + +#endif // RTPPOLLTHREAD_H diff --git a/src/libs/jrtplib/src/rtprandom.cpp b/src/libs/jrtplib/src/rtprandom.cpp new file mode 100644 index 00000000..79eaf0fa --- /dev/null +++ b/src/libs/jrtplib/src/rtprandom.cpp @@ -0,0 +1,86 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#if defined(WIN32) && !defined(_WIN32_WCE) + #define _CRT_RAND_S +#endif // WIN32 || _WIN32_WCE + +#include "rtprandom.h" +#include +#ifndef WIN32 + #include +#else + #ifndef _WIN32_WCE + #include + #else + #include + #include + #endif // _WIN32_WINCE + #include +#endif // WIN32 + +#include "rtpdebug.h" + +namespace jrtplib +{ + +uint32_t RTPRandom::PickSeed() +{ + uint32_t x; +#if defined(WIN32) || defined(_WIN32_WINCE) +#ifndef _WIN32_WCE + x = (uint32_t)_getpid(); + x += (uint32_t)time(0); + x += (uint32_t)clock(); +#else + x = (uint32_t)GetCurrentProcessId(); + + FILETIME ft; + SYSTEMTIME st; + + GetSystemTime(&st); + SystemTimeToFileTime(&st,&ft); + + x += ft.dwLowDateTime; +#endif // _WIN32_WCE + x ^= (uint32_t)((uint8_t *)this - (uint8_t *)0); +#else + x = (uint32_t)getpid(); + x += (uint32_t)time(0); + x += (uint32_t)clock(); + x ^= (uint32_t)((uint8_t *)this - (uint8_t *)0); +#endif + return x; +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtprandom.h b/src/libs/jrtplib/src/rtprandom.h new file mode 100644 index 00000000..e3917ce7 --- /dev/null +++ b/src/libs/jrtplib/src/rtprandom.h @@ -0,0 +1,76 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtprandom.h + */ + +#ifndef RTPRANDOM_H + +#define RTPRANDOM_H + +#include "rtpconfig.h" +#include "rtptypes.h" +#include + +#define RTPRANDOM_2POWMIN63 1.08420217248550443400745280086994171142578125e-19 + +namespace jrtplib +{ + +/** Interface for generating random numbers. */ +class JRTPLIB_IMPORTEXPORT RTPRandom +{ +public: + RTPRandom() { } + virtual ~RTPRandom() { } + + /** Returns a random eight bit value. */ + virtual uint8_t GetRandom8() = 0; + + /** Returns a random sixteen bit value. */ + virtual uint16_t GetRandom16() = 0; + + /** Returns a random thirty-two bit value. */ + virtual uint32_t GetRandom32() = 0; + + /** Returns a random number between $0.0$ and $1.0$. */ + virtual double GetRandomDouble() = 0; + + /** Can be used by subclasses to generate a seed for a random number generator. */ + uint32_t PickSeed(); +}; + +} // end namespace + +#endif // RTPRANDOM_H + diff --git a/src/libs/jrtplib/src/rtprandomrand48.cpp b/src/libs/jrtplib/src/rtprandomrand48.cpp new file mode 100644 index 00000000..05750151 --- /dev/null +++ b/src/libs/jrtplib/src/rtprandomrand48.cpp @@ -0,0 +1,125 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtprandomrand48.h" + +namespace jrtplib +{ + +RTPRandomRand48::RTPRandomRand48() +{ + SetSeed(PickSeed()); +} + +RTPRandomRand48::RTPRandomRand48(uint32_t seed) +{ + SetSeed(seed); +} + +RTPRandomRand48::~RTPRandomRand48() +{ +} + +void RTPRandomRand48::SetSeed(uint32_t seed) +{ +#ifdef RTP_SUPPORT_THREAD + mutex.Init(); // TODO: check error! +#endif // RTP_SUPPORT_THREAD + +#if (defined(WIN32) || defined(_WIN32_WCE)) && defined(_MSC_VER) && _MSC_VER <= 1200 + state = ((uint64_t)seed) << 16 | 0x330Eui64; +#else + state = ((uint64_t)seed) << 16 | 0x330EULL; +#endif +} + +uint8_t RTPRandomRand48::GetRandom8() +{ + uint32_t x = ((GetRandom32() >> 24)&0xff); + + return (uint8_t)x; +} + +uint16_t RTPRandomRand48::GetRandom16() +{ + uint32_t x = ((GetRandom32() >> 16)&0xffff); + + return (uint16_t)x; +} + +uint32_t RTPRandomRand48::GetRandom32() +{ +#ifdef RTP_SUPPORT_THREAD + mutex.Lock(); +#endif // RTP_SUPPORT_THREAD + +#if (defined(WIN32) || defined(_WIN32_WCE)) && defined(_MSC_VER) && _MSC_VER <= 1200 + state = ((0x5DEECE66Dui64*state) + 0xBui64)&0x0000ffffffffffffui64; + + uint32_t x = (uint32_t)((state>>16)&0xffffffffui64); +#else + state = ((0x5DEECE66DULL*state) + 0xBULL)&0x0000ffffffffffffULL; + + uint32_t x = (uint32_t)((state>>16)&0xffffffffULL); +#endif + +#ifdef RTP_SUPPORT_THREAD + mutex.Unlock(); +#endif // RTP_SUPPORT_THREAD + return x; +} + +double RTPRandomRand48::GetRandomDouble() +{ +#ifdef RTP_SUPPORT_THREAD + mutex.Lock(); +#endif // RTP_SUPPORT_THREAD + +#if (defined(WIN32) || defined(_WIN32_WCE)) && defined(_MSC_VER) && _MSC_VER <= 1200 + state = ((0x5DEECE66Dui64*state) + 0xBui64)&0x0000ffffffffffffui64; + + int64_t x = (int64_t)state; +#else + state = ((0x5DEECE66DULL*state) + 0xBULL)&0x0000ffffffffffffULL; + + int64_t x = (int64_t)state; +#endif + +#ifdef RTP_SUPPORT_THREAD + mutex.Unlock(); +#endif // RTP_SUPPORT_THREAD + double y = 3.552713678800500929355621337890625e-15 * (double)x; + return y; +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtprandomrand48.h b/src/libs/jrtplib/src/rtprandomrand48.h new file mode 100644 index 00000000..5916af4f --- /dev/null +++ b/src/libs/jrtplib/src/rtprandomrand48.h @@ -0,0 +1,75 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtprandomrand48.h + */ + +#ifndef RTPRANDOMRAND48_H + +#define RTPRANDOMRAND48_H + +#include "rtpconfig.h" +#include "rtprandom.h" +#ifdef RTP_SUPPORT_THREAD + #include +#endif // RTP_SUPPORT_THREAD +#include + +namespace jrtplib +{ + +/** A random number generator using the algorithm of the rand48 set of functions. */ +class JRTPLIB_IMPORTEXPORT RTPRandomRand48 : public RTPRandom +{ +public: + RTPRandomRand48(); + RTPRandomRand48(uint32_t seed); + ~RTPRandomRand48(); + + uint8_t GetRandom8(); + uint16_t GetRandom16(); + uint32_t GetRandom32(); + double GetRandomDouble(); +private: + void SetSeed(uint32_t seed); + +#ifdef RTP_SUPPORT_THREAD + jthread::JMutex mutex; +#endif // RTP_SUPPORT_THREAD + uint64_t state; +}; + +} // end namespace + +#endif // RTPRANDOMRAND48_H + diff --git a/src/libs/jrtplib/src/rtprandomrands.cpp b/src/libs/jrtplib/src/rtprandomrands.cpp new file mode 100644 index 00000000..6477964c --- /dev/null +++ b/src/libs/jrtplib/src/rtprandomrands.cpp @@ -0,0 +1,200 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#if defined(WIN32) && !defined(_WIN32_WCE) + #define _CRT_RAND_S +#endif // WIN32 || _WIN32_WCE + +#include "rtprandomrands.h" +#include "rtperrors.h" + +#if (defined(WIN32) && !defined(_WIN32_WCE)) && (defined(_MSC_VER) && _MSC_VER >= 1400 ) + #include + #include + // If compiling on VC 8 or later for full Windows, we'll attempt to use rand_s, + // which generates better random numbers. However, its only supported on Windows XP, + // Windows Server 2003, and later, so we'll do a run-time check to see if we can + // use it (it won't work on Windows 2000 SP4 for example). + #define RTP_SUPPORT_RANDS +#endif + +#include "rtpdebug.h" + +namespace jrtplib +{ + +#ifndef RTP_SUPPORT_RANDS + +RTPRandomRandS::RTPRandomRandS() +{ + initialized = false; +} + +RTPRandomRandS::~RTPRandomRandS() +{ +} + +int RTPRandomRandS::Init() +{ + return ERR_RTP_RTPRANDOMRANDS_NOTSUPPORTED; +} + +uint8_t RTPRandomRandS::GetRandom8() +{ + return 0; +} + +uint16_t RTPRandomRandS::GetRandom16() +{ + return 0; +} + +uint32_t RTPRandomRandS::GetRandom32() +{ + return 0; +} + +double RTPRandomRandS::GetRandomDouble() +{ + return 0; +} + +#else + +RTPRandomRandS::RTPRandomRandS() +{ + initialized = false; +} + +RTPRandomRandS::~RTPRandomRandS() +{ +} + +int RTPRandomRandS::Init() +{ + if (initialized) // doesn't matter then + return 0; + + HMODULE hAdvApi32 = LoadLibrary(TEXT("ADVAPI32.DLL")); + if(hAdvApi32 != NULL) + { + if(NULL != GetProcAddress( hAdvApi32, "SystemFunction036" )) // RtlGenRandom + { + initialized = true; + } + FreeLibrary(hAdvApi32); + hAdvApi32 = NULL; + } + + if (!initialized) + return ERR_RTP_RTPRANDOMRANDS_NOTSUPPORTED; + return 0; +} + +// rand_s gives a number between 0 and UINT_MAX. We'll assume that UINT_MAX is at least 8 bits + +uint8_t RTPRandomRandS::GetRandom8() +{ + if (!initialized) + return 0; + + unsigned int r; + + rand_s(&r); + + return (uint8_t)(r&0xff); +} + +uint16_t RTPRandomRandS::GetRandom16() +{ + if (!initialized) + return 0; + + unsigned int r; + int shift = 0; + uint16_t x = 0; + + for (int i = 0 ; i < 2 ; i++, shift += 8) + { + rand_s(&r); + + x ^= ((uint16_t)r << shift); + } + + return x; +} + +uint32_t RTPRandomRandS::GetRandom32() +{ + if (!initialized) + return 0; + + unsigned int r; + int shift = 0; + uint32_t x = 0; + + for (int i = 0 ; i < 4 ; i++, shift += 8) + { + rand_s(&r); + + x ^= ((uint32_t)r << shift); + } + + return x; +} + +double RTPRandomRandS::GetRandomDouble() +{ + if (!initialized) + return 0; + + unsigned int r; + int shift = 0; + uint64_t x = 0; + + for (int i = 0 ; i < 8 ; i++, shift += 8) + { + rand_s(&r); + + x ^= ((uint64_t)r << shift); + } + + x &= 0x7fffffffffffffffULL; + + int64_t x2 = (int64_t)x; + return RTPRANDOM_2POWMIN63*(double)x2; +} + +#endif // RTP_SUPPORT_RANDS + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtprandomrands.h b/src/libs/jrtplib/src/rtprandomrands.h new file mode 100644 index 00000000..442d6c86 --- /dev/null +++ b/src/libs/jrtplib/src/rtprandomrands.h @@ -0,0 +1,70 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtprandomrands.h + */ + +#ifndef RTPRANDOMRANDS_H + +#define RTPRANDOMRANDS_H + +#include "rtpconfig.h" +#include "rtprandom.h" + +namespace jrtplib +{ + +/** A random number generator which tries to use the \c rand_s function on the + * Win32 platform. + */ +class JRTPLIB_IMPORTEXPORT RTPRandomRandS : public RTPRandom +{ +public: + RTPRandomRandS(); + ~RTPRandomRandS(); + + /** Initialize the random number generator. */ + int Init(); + + uint8_t GetRandom8(); + uint16_t GetRandom16(); + uint32_t GetRandom32(); + double GetRandomDouble(); +private: + bool initialized; +}; + +} // end namespace + +#endif // RTPRANDOMRANDS_H + diff --git a/src/libs/jrtplib/src/rtprandomurandom.cpp b/src/libs/jrtplib/src/rtprandomurandom.cpp new file mode 100644 index 00000000..df0d214b --- /dev/null +++ b/src/libs/jrtplib/src/rtprandomurandom.cpp @@ -0,0 +1,123 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtprandomurandom.h" +#include "rtperrors.h" + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTPRandomURandom::RTPRandomURandom() +{ + device = 0; +} + +RTPRandomURandom::~RTPRandomURandom() +{ + if (device) + fclose(device); +} + +int RTPRandomURandom::Init() +{ + if (device) + return ERR_RTP_RTPRANDOMURANDOM_ALREADYOPEN; + + device = fopen("/dev/urandom","rb"); + if (device == 0) + return ERR_RTP_RTPRANDOMURANDOM_CANTOPEN; + + return 0; +} + +uint8_t RTPRandomURandom::GetRandom8() +{ + if (!device) + return 0; + + uint8_t value; + + fread(&value, sizeof(uint8_t), 1, device); + + return value; +} + +uint16_t RTPRandomURandom::GetRandom16() +{ + if (!device) + return 0; + + uint16_t value; + + fread(&value, sizeof(uint16_t), 1, device); + + return value; +} + +uint32_t RTPRandomURandom::GetRandom32() +{ + if (!device) + return 0; + + uint32_t value; + + fread(&value, sizeof(uint32_t), 1, device); + + return value; +} + +double RTPRandomURandom::GetRandomDouble() +{ + if (!device) + return 0; + + uint64_t value; + + fread(&value, sizeof(uint64_t), 1, device); + +#if (defined(WIN32) || defined(_WIN32_WCE)) && defined(_MSC_VER) && _MSC_VER <= 1200 + value &= 0x7fffffffffffffffui64; +#else + value &= 0x7fffffffffffffffULL; +#endif + + int64_t value2 = (int64_t)value; + double x = RTPRANDOM_2POWMIN63*(double)value2; + + return x; + +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtprandomurandom.h b/src/libs/jrtplib/src/rtprandomurandom.h new file mode 100644 index 00000000..65b27913 --- /dev/null +++ b/src/libs/jrtplib/src/rtprandomurandom.h @@ -0,0 +1,68 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtprandomurandom.h + */ + +#ifndef RTPRANDOMURANDOM_H + +#define RTPRANDOMURANDOM_H + +#include "rtpconfig.h" +#include "rtprandom.h" +#include + +namespace jrtplib +{ + +/** A random number generator which uses bytes delivered by the /dev/urandom device. */ +class JRTPLIB_IMPORTEXPORT RTPRandomURandom : public RTPRandom +{ +public: + RTPRandomURandom(); + ~RTPRandomURandom(); + + /** Initialize the random number generator. */ + int Init(); + + uint8_t GetRandom8(); + uint16_t GetRandom16(); + uint32_t GetRandom32(); + double GetRandomDouble(); +private: + FILE *device; +}; + +} // end namespace + +#endif // RTPRANDOMURANDOM_H diff --git a/src/libs/jrtplib/src/rtprawpacket.h b/src/libs/jrtplib/src/rtprawpacket.h new file mode 100644 index 00000000..d97558d7 --- /dev/null +++ b/src/libs/jrtplib/src/rtprawpacket.h @@ -0,0 +1,114 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtprawpacket.h + */ + +#ifndef RTPRAWPACKET_H + +#define RTPRAWPACKET_H + +#include "rtpconfig.h" +#include "rtptimeutilities.h" +#include "rtpaddress.h" +#include "rtptypes.h" +#include "rtpmemoryobject.h" + +namespace jrtplib +{ + +/** This class is used by the transmission component to store the incoming RTP and RTCP data in. */ +class JRTPLIB_IMPORTEXPORT RTPRawPacket : public RTPMemoryObject +{ +public: + /** Creates an instance which stores data from \c data with length \c datalen. + * Creates an instance which stores data from \c data with length \c datalen. Only the pointer + * to the data is stored, no actual copy is made! The address from which this packet originated + * is set to \c address and the time at which the packet was received is set to \c recvtime. + * The flag which indicates whether this data is RTP or RTCP data is set to \c rtp. A memory + * manager can be installed as well. + */ + RTPRawPacket(uint8_t *data,size_t datalen,RTPAddress *address,RTPTime &recvtime,bool rtp,RTPMemoryManager *mgr = 0); + ~RTPRawPacket(); + + /** Returns the pointer to the data which is contained in this packet. */ + uint8_t *GetData() { return packetdata; } + + /** Returns the length of the packet described by this instance. */ + size_t GetDataLength() const { return packetdatalength; } + + /** Returns the time at which this packet was received. */ + RTPTime GetReceiveTime() const { return receivetime; } + + /** Returns the address stored in this packet. */ + const RTPAddress *GetSenderAddress() const { return senderaddress; } + + /** Returns \c true if this data is RTP data, \c false if it is RTCP data. */ + bool IsRTP() const { return isrtp; } + + /** Sets the pointer to the data stored in this packet to zero. + * Sets the pointer to the data stored in this packet to zero. This will prevent + * a \c delete call for the actual data when the destructor of RTPRawPacket is called. + * This function is used by the RTPPacket and RTCPCompoundPacket classes to obtain + * the packet data (without having to copy it) and to make sure the data isn't deleted + * when the destructor of RTPRawPacket is called. + */ + void ZeroData() { packetdata = 0; packetdatalength = 0; } +private: + uint8_t *packetdata; + size_t packetdatalength; + RTPTime receivetime; + RTPAddress *senderaddress; + bool isrtp; +}; + +inline RTPRawPacket::RTPRawPacket(uint8_t *data,size_t datalen,RTPAddress *address,RTPTime &recvtime,bool rtp,RTPMemoryManager *mgr):RTPMemoryObject(mgr),receivetime(recvtime) +{ + packetdata = data; + packetdatalength = datalen; + senderaddress = address; + isrtp = rtp; +} + +inline RTPRawPacket::~RTPRawPacket() +{ + if (packetdata) + RTPDeleteByteArray(packetdata,GetMemoryManager()); + if (senderaddress) + RTPDelete(senderaddress,GetMemoryManager()); +} + +} // end namespace + +#endif // RTPRAWPACKET_H + diff --git a/src/libs/jrtplib/src/rtpsession.cpp b/src/libs/jrtplib/src/rtpsession.cpp new file mode 100644 index 00000000..c0296b28 --- /dev/null +++ b/src/libs/jrtplib/src/rtpsession.cpp @@ -0,0 +1,1659 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpsession.h" +#include "rtperrors.h" +#include "rtppollthread.h" +#include "rtpudpv4transmitter.h" +#include "rtpudpv6transmitter.h" +#include "rtpexternaltransmitter.h" +#include "rtpsessionparams.h" +#include "rtpdefines.h" +#include "rtprawpacket.h" +#include "rtppacket.h" +#include "rtptimeutilities.h" +#include "rtpmemorymanager.h" +#include "rtprandomrand48.h" +#include "rtprandomrands.h" +#include "rtprandomurandom.h" +#ifdef RTP_SUPPORT_SENDAPP + #include "rtcpcompoundpacket.h" +#endif // RTP_SUPPORT_SENDAPP +#ifndef WIN32 + #include + #include +#else + #include +#endif // WIN32 + +#ifdef RTPDEBUG + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +#ifdef RTP_SUPPORT_THREAD + #define SOURCES_LOCK { if (usingpollthread) sourcesmutex.Lock(); } + #define SOURCES_UNLOCK { if (usingpollthread) sourcesmutex.Unlock(); } + #define BUILDER_LOCK { if (usingpollthread) buildermutex.Lock(); } + #define BUILDER_UNLOCK { if (usingpollthread) buildermutex.Unlock(); } + #define SCHED_LOCK { if (usingpollthread) schedmutex.Lock(); } + #define SCHED_UNLOCK { if (usingpollthread) schedmutex.Unlock(); } + #define PACKSENT_LOCK { if (usingpollthread) packsentmutex.Lock(); } + #define PACKSENT_UNLOCK { if (usingpollthread) packsentmutex.Unlock(); } +#else + #define SOURCES_LOCK + #define SOURCES_UNLOCK + #define BUILDER_LOCK + #define BUILDER_UNLOCK + #define SCHED_LOCK + #define SCHED_UNLOCK + #define PACKSENT_LOCK + #define PACKSENT_UNLOCK +#endif // RTP_SUPPORT_THREAD + +namespace jrtplib +{ + +RTPSession::RTPSession(RTPRandom *r,RTPMemoryManager *mgr) + : RTPMemoryObject(mgr),sources(*this,mgr),rtprnd(GetRandomNumberGenerator(r)),packetbuilder(*rtprnd,mgr),rtcpsched(sources,*rtprnd), + rtcpbuilder(sources,packetbuilder,mgr),collisionlist(mgr) +{ + created = false; +#if (defined(WIN32) || defined(_WIN32_WCE)) + timeinit.Dummy(); +#endif // WIN32 || _WIN32_WCE + + //std::cout << (void *)(rtprnd) << std::endl; +} + +RTPSession::~RTPSession() +{ + Destroy(); + + if (deletertprnd) + delete rtprnd; +} + +int RTPSession::Create(const RTPSessionParams &sessparams,const RTPTransmissionParams *transparams /* = 0 */, + RTPTransmitter::TransmissionProtocol protocol) +{ + int status; + + if (created) + return ERR_RTP_SESSION_ALREADYCREATED; + + usingpollthread = sessparams.IsUsingPollThread(); + useSR_BYEifpossible = sessparams.GetSenderReportForBYE(); + sentpackets = false; + + // Check max packet size + + if ((maxpacksize = sessparams.GetMaximumPacketSize()) < RTP_MINPACKETSIZE) + return ERR_RTP_SESSION_MAXPACKETSIZETOOSMALL; + + // Initialize the transmission component + + rtptrans = 0; + switch(protocol) + { + case RTPTransmitter::IPv4UDPProto: + rtptrans = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPTRANSMITTER) RTPUDPv4Transmitter(GetMemoryManager()); + break; +#ifdef RTP_SUPPORT_IPV6 + case RTPTransmitter::IPv6UDPProto: + rtptrans = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPTRANSMITTER) RTPUDPv6Transmitter(GetMemoryManager()); + break; +#endif // RTP_SUPPORT_IPV6 + case RTPTransmitter::ExternalProto: + rtptrans = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPTRANSMITTER) RTPExternalTransmitter(GetMemoryManager()); + break; + case RTPTransmitter::UserDefinedProto: + rtptrans = NewUserDefinedTransmitter(); + if (rtptrans == 0) + return ERR_RTP_SESSION_USERDEFINEDTRANSMITTERNULL; + break; + default: + return ERR_RTP_SESSION_UNSUPPORTEDTRANSMISSIONPROTOCOL; + } + + if (rtptrans == 0) + return ERR_RTP_OUTOFMEM; + if ((status = rtptrans->Init(usingpollthread)) < 0) + { + RTPDelete(rtptrans,GetMemoryManager()); + return status; + } + if ((status = rtptrans->Create(maxpacksize,transparams)) < 0) + { + RTPDelete(rtptrans,GetMemoryManager()); + return status; + } + + deletetransmitter = true; + return InternalCreate(sessparams); +} + +int RTPSession::Create(const RTPSessionParams &sessparams,RTPTransmitter *transmitter) +{ + int status; + + if (created) + return ERR_RTP_SESSION_ALREADYCREATED; + + usingpollthread = sessparams.IsUsingPollThread(); + useSR_BYEifpossible = sessparams.GetSenderReportForBYE(); + sentpackets = false; + + // Check max packet size + + if ((maxpacksize = sessparams.GetMaximumPacketSize()) < RTP_MINPACKETSIZE) + return ERR_RTP_SESSION_MAXPACKETSIZETOOSMALL; + + rtptrans = transmitter; + + if ((status = rtptrans->SetMaximumPacketSize(maxpacksize)) < 0) + return status; + + deletetransmitter = false; + return InternalCreate(sessparams); +} + +int RTPSession::InternalCreate(const RTPSessionParams &sessparams) +{ + int status; + + // Initialize packet builder + + if ((status = packetbuilder.Init(maxpacksize)) < 0) + { + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + return status; + } + + if (sessparams.GetUsePredefinedSSRC()) + packetbuilder.AdjustSSRC(sessparams.GetPredefinedSSRC()); + +#ifdef RTP_SUPPORT_PROBATION + + // Set probation type + sources.SetProbationType(sessparams.GetProbationType()); + +#endif // RTP_SUPPORT_PROBATION + + // Add our own ssrc to the source table + + if ((status = sources.CreateOwnSSRC(packetbuilder.GetSSRC())) < 0) + { + packetbuilder.Destroy(); + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + return status; + } + + // Set the initial receive mode + + if ((status = rtptrans->SetReceiveMode(sessparams.GetReceiveMode())) < 0) + { + packetbuilder.Destroy(); + sources.Clear(); + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + return status; + } + + // Init the RTCP packet builder + + double timestampunit = sessparams.GetOwnTimestampUnit(); + uint8_t buf[1024]; + size_t buflen = 1024; + std::string forcedcname = sessparams.GetCNAME(); + + if (forcedcname.length() == 0) + { + if ((status = CreateCNAME(buf,&buflen,sessparams.GetResolveLocalHostname())) < 0) + { + packetbuilder.Destroy(); + sources.Clear(); + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + return status; + } + } + else + { + strncpy((char *)buf, forcedcname.c_str(), buflen); + buf[buflen-1] = 0; + buflen = strlen((char *)buf); + } + + if ((status = rtcpbuilder.Init(maxpacksize,timestampunit,buf,buflen)) < 0) + { + packetbuilder.Destroy(); + sources.Clear(); + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + return status; + } + + // Set scheduler parameters + + rtcpsched.Reset(); + rtcpsched.SetHeaderOverhead(rtptrans->GetHeaderOverhead()); + + RTCPSchedulerParams schedparams; + + sessionbandwidth = sessparams.GetSessionBandwidth(); + controlfragment = sessparams.GetControlTrafficFraction(); + + if ((status = schedparams.SetRTCPBandwidth(sessionbandwidth*controlfragment)) < 0) + { + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + packetbuilder.Destroy(); + sources.Clear(); + rtcpbuilder.Destroy(); + return status; + } + if ((status = schedparams.SetSenderBandwidthFraction(sessparams.GetSenderControlBandwidthFraction())) < 0) + { + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + packetbuilder.Destroy(); + sources.Clear(); + rtcpbuilder.Destroy(); + return status; + } + if ((status = schedparams.SetMinimumTransmissionInterval(sessparams.GetMinimumRTCPTransmissionInterval())) < 0) + { + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + packetbuilder.Destroy(); + sources.Clear(); + rtcpbuilder.Destroy(); + return status; + } + schedparams.SetUseHalfAtStartup(sessparams.GetUseHalfRTCPIntervalAtStartup()); + schedparams.SetRequestImmediateBYE(sessparams.GetRequestImmediateBYE()); + + rtcpsched.SetParameters(schedparams); + + // copy other parameters + + acceptownpackets = sessparams.AcceptOwnPackets(); + membermultiplier = sessparams.GetSourceTimeoutMultiplier(); + sendermultiplier = sessparams.GetSenderTimeoutMultiplier(); + byemultiplier = sessparams.GetBYETimeoutMultiplier(); + collisionmultiplier = sessparams.GetCollisionTimeoutMultiplier(); + notemultiplier = sessparams.GetNoteTimeoutMultiplier(); + + // Do thread stuff if necessary + +#ifdef RTP_SUPPORT_THREAD + pollthread = 0; + if (usingpollthread) + { + if (!sourcesmutex.IsInitialized()) + { + if (sourcesmutex.Init() < 0) + { + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + packetbuilder.Destroy(); + sources.Clear(); + rtcpbuilder.Destroy(); + return ERR_RTP_SESSION_CANTINITMUTEX; + } + } + if (!buildermutex.IsInitialized()) + { + if (buildermutex.Init() < 0) + { + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + packetbuilder.Destroy(); + sources.Clear(); + rtcpbuilder.Destroy(); + return ERR_RTP_SESSION_CANTINITMUTEX; + } + } + if (!schedmutex.IsInitialized()) + { + if (schedmutex.Init() < 0) + { + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + packetbuilder.Destroy(); + sources.Clear(); + rtcpbuilder.Destroy(); + return ERR_RTP_SESSION_CANTINITMUTEX; + } + } + if (!packsentmutex.IsInitialized()) + { + if (packsentmutex.Init() < 0) + { + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + packetbuilder.Destroy(); + sources.Clear(); + rtcpbuilder.Destroy(); + return ERR_RTP_SESSION_CANTINITMUTEX; + } + } + + pollthread = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPPOLLTHREAD) RTPPollThread(*this,rtcpsched); + if (pollthread == 0) + { + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + packetbuilder.Destroy(); + sources.Clear(); + rtcpbuilder.Destroy(); + return ERR_RTP_OUTOFMEM; + } + if ((status = pollthread->Start(rtptrans)) < 0) + { + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + RTPDelete(pollthread,GetMemoryManager()); + packetbuilder.Destroy(); + sources.Clear(); + rtcpbuilder.Destroy(); + return status; + } + } +#endif // RTP_SUPPORT_THREAD + + created = true; + return 0; +} + + +void RTPSession::Destroy() +{ + if (!created) + return; + +#ifdef RTP_SUPPORT_THREAD + if (pollthread) + RTPDelete(pollthread,GetMemoryManager()); +#endif // RTP_SUPPORT_THREAD + + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + packetbuilder.Destroy(); + rtcpbuilder.Destroy(); + rtcpsched.Reset(); + collisionlist.Clear(); + sources.Clear(); + + std::list::const_iterator it; + + for (it = byepackets.begin() ; it != byepackets.end() ; it++) + RTPDelete(*it,GetMemoryManager()); + byepackets.clear(); + + created = false; +} + +void RTPSession::BYEDestroy(const RTPTime &maxwaittime,const void *reason,size_t reasonlength) +{ + if (!created) + return; + + // first, stop the thread so we have full control over all components + +#ifdef RTP_SUPPORT_THREAD + if (pollthread) + RTPDelete(pollthread,GetMemoryManager()); +#endif // RTP_SUPPORT_THREAD + + RTPTime stoptime = RTPTime::CurrentTime(); + stoptime += maxwaittime; + + // add bye packet to the list if we've sent data + + RTCPCompoundPacket *pack; + + if (sentpackets) + { + int status; + + reasonlength = (reasonlength>RTCP_BYE_MAXREASONLENGTH)?RTCP_BYE_MAXREASONLENGTH:reasonlength; + status = rtcpbuilder.BuildBYEPacket(&pack,reason,reasonlength,useSR_BYEifpossible); + if (status >= 0) + { + byepackets.push_back(pack); + + if (byepackets.size() == 1) + rtcpsched.ScheduleBYEPacket(pack->GetCompoundPacketLength()); + } + } + + if (!byepackets.empty()) + { + bool done = false; + + while (!done) + { + RTPTime curtime = RTPTime::CurrentTime(); + + if (curtime >= stoptime) + done = true; + + if (rtcpsched.IsTime()) + { + pack = *(byepackets.begin()); + byepackets.pop_front(); + + rtptrans->SendRTCPData(pack->GetCompoundPacketData(),pack->GetCompoundPacketLength()); + + OnSendRTCPCompoundPacket(pack); // we'll place this after the actual send to avoid tampering + + RTPDelete(pack,GetMemoryManager()); + if (!byepackets.empty()) // more bye packets to send, schedule them + rtcpsched.ScheduleBYEPacket((*(byepackets.begin()))->GetCompoundPacketLength()); + else + done = true; + } + if (!done) + RTPTime::Wait(RTPTime(0,100000)); + } + } + + if (deletetransmitter) + RTPDelete(rtptrans,GetMemoryManager()); + packetbuilder.Destroy(); + rtcpbuilder.Destroy(); + rtcpsched.Reset(); + collisionlist.Clear(); + sources.Clear(); + + // clear rest of bye packets + std::list::const_iterator it; + + for (it = byepackets.begin() ; it != byepackets.end() ; it++) + RTPDelete(*it,GetMemoryManager()); + byepackets.clear(); + + created = false; +} + + +bool RTPSession::IsActive() +{ + return created; +} + +uint32_t RTPSession::GetLocalSSRC() +{ + if (!created) + return 0; + + uint32_t ssrc; + + BUILDER_LOCK + ssrc = packetbuilder.GetSSRC(); + BUILDER_UNLOCK + return ssrc; +} + +int RTPSession::AddDestination(const RTPAddress &addr) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + return rtptrans->AddDestination(addr); +} + +int RTPSession::DeleteDestination(const RTPAddress &addr) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + return rtptrans->DeleteDestination(addr); +} + +void RTPSession::ClearDestinations() +{ + if (!created) + return; + rtptrans->ClearDestinations(); +} + +bool RTPSession::SupportsMulticasting() +{ + if (!created) + return false; + return rtptrans->SupportsMulticasting(); +} + +int RTPSession::JoinMulticastGroup(const RTPAddress &addr) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + return rtptrans->JoinMulticastGroup(addr); +} + +int RTPSession::LeaveMulticastGroup(const RTPAddress &addr) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + return rtptrans->LeaveMulticastGroup(addr); +} + +void RTPSession::LeaveAllMulticastGroups() +{ + if (!created) + return; + rtptrans->LeaveAllMulticastGroups(); +} + +int RTPSession::SendPacket(const void *data,size_t len) +{ + int status; + + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + BUILDER_LOCK + if ((status = packetbuilder.BuildPacket(data,len)) < 0) + { + BUILDER_UNLOCK + return status; + } + if ((status = rtptrans->SendRTPData(packetbuilder.GetPacket(),packetbuilder.GetPacketLength())) < 0) + { + BUILDER_UNLOCK + return status; + } + BUILDER_UNLOCK + + SOURCES_LOCK + sources.SentRTPPacket(); + SOURCES_UNLOCK + PACKSENT_LOCK + sentpackets = true; + PACKSENT_UNLOCK + return 0; +} + +int RTPSession::SendPacket(const void *data,size_t len, + uint8_t pt,bool mark,uint32_t timestampinc) +{ + int status; + + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + BUILDER_LOCK + if ((status = packetbuilder.BuildPacket(data,len,pt,mark,timestampinc)) < 0) + { + BUILDER_UNLOCK + return status; + } + if ((status = rtptrans->SendRTPData(packetbuilder.GetPacket(),packetbuilder.GetPacketLength())) < 0) + { + BUILDER_UNLOCK + return status; + } + BUILDER_UNLOCK + + SOURCES_LOCK + sources.SentRTPPacket(); + SOURCES_UNLOCK + PACKSENT_LOCK + sentpackets = true; + PACKSENT_UNLOCK + return 0; +} + +int RTPSession::SendPacketEx(const void *data,size_t len, + uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords) +{ + int status; + + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + BUILDER_LOCK + if ((status = packetbuilder.BuildPacketEx(data,len,hdrextID,hdrextdata,numhdrextwords)) < 0) + { + BUILDER_UNLOCK + return status; + } + if ((status = rtptrans->SendRTPData(packetbuilder.GetPacket(),packetbuilder.GetPacketLength())) < 0) + { + BUILDER_UNLOCK + return status; + } + BUILDER_UNLOCK + + SOURCES_LOCK + sources.SentRTPPacket(); + SOURCES_UNLOCK + PACKSENT_LOCK + sentpackets = true; + PACKSENT_UNLOCK + return 0; +} + +int RTPSession::SendPacketEx(const void *data,size_t len, + uint8_t pt,bool mark,uint32_t timestampinc, + uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords) +{ + int status; + + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + BUILDER_LOCK + if ((status = packetbuilder.BuildPacketEx(data,len,pt,mark,timestampinc,hdrextID,hdrextdata,numhdrextwords)) < 0) + { + BUILDER_UNLOCK + return status; + } + if ((status = rtptrans->SendRTPData(packetbuilder.GetPacket(),packetbuilder.GetPacketLength())) < 0) + { + BUILDER_UNLOCK + return status; + } + BUILDER_UNLOCK + + SOURCES_LOCK + sources.SentRTPPacket(); + SOURCES_UNLOCK + PACKSENT_LOCK + sentpackets = true; + PACKSENT_UNLOCK + return 0; +} + +#ifdef RTP_SUPPORT_SENDAPP + +int RTPSession::SendRTCPAPPPacket(uint8_t subtype, const uint8_t name[4], const void *appdata, size_t appdatalen) +{ + int status; + + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + BUILDER_LOCK + uint32_t ssrc = packetbuilder.GetSSRC(); + BUILDER_UNLOCK + + RTCPCompoundPacketBuilder pb(GetMemoryManager()); + + status = pb.InitBuild(maxpacksize); + + if(status < 0) + return status; + + //first packet in an rtcp compound packet should always be SR or RR + if((status = pb.StartReceiverReport(ssrc)) < 0) + return status; + + //add SDES packet with CNAME item + if ((status = pb.AddSDESSource(ssrc)) < 0) + return status; + + BUILDER_LOCK + size_t owncnamelen = 0; + uint8_t *owncname = rtcpbuilder.GetLocalCNAME(&owncnamelen); + + if ((status = pb.AddSDESNormalItem(RTCPSDESPacket::CNAME,owncname,owncnamelen)) < 0) + { + BUILDER_UNLOCK + return status; + } + BUILDER_UNLOCK + + //add our application specific packet + if((status = pb.AddAPPPacket(subtype, ssrc, name, appdata, appdatalen)) < 0) + return status; + + if((status = pb.EndBuild()) < 0) + return status; + + //send packet + status = rtptrans->SendRTCPData(pb.GetCompoundPacketData(),pb.GetCompoundPacketLength()); + if(status < 0) + return status; + + PACKSENT_LOCK + sentpackets = true; + PACKSENT_UNLOCK + + return pb.GetCompoundPacketLength(); +} + +#endif // RTP_SUPPORT_SENDAPP + +#ifdef RTP_SUPPORT_RTCPUNKNOWN + +int RTPSession::SendUnknownPacket(bool sr, uint8_t payload_type, uint8_t subtype, const void *data, size_t len) +{ + int status; + + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + BUILDER_LOCK + uint32_t ssrc = packetbuilder.GetSSRC(); + BUILDER_UNLOCK + + RTCPCompoundPacketBuilder* rtcpcomppack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPCOMPOUNDPACKETBUILDER) RTCPCompoundPacketBuilder(GetMemoryManager()); + if (rtcpcomppack == 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return ERR_RTP_OUTOFMEM; + } + + status = rtcpcomppack->InitBuild(maxpacksize); + if(status < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + if (sr) + { + // setup for the rtcp + RTPTime rtppacktime = packetbuilder.GetPacketTime(); + uint32_t rtppacktimestamp = packetbuilder.GetPacketTimestamp(); + uint32_t packcount = packetbuilder.GetPacketCount(); + uint32_t octetcount = packetbuilder.GetPayloadOctetCount(); + RTPTime curtime = RTPTime::CurrentTime(); + RTPTime diff = curtime; + diff -= rtppacktime; + diff += 1; // add transmission delay or RTPTime(0,0); + + double timestampunit = 90000; + + uint32_t tsdiff = (uint32_t)((diff.GetDouble()/timestampunit)+0.5); + uint32_t rtptimestamp = rtppacktimestamp+tsdiff; + RTPNTPTime ntptimestamp = curtime.GetNTPTime(); + + //first packet in an rtcp compound packet should always be SR or RR + if((status = rtcpcomppack->StartSenderReport(ssrc,ntptimestamp,rtptimestamp,packcount,octetcount)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + } + else + { + //first packet in an rtcp compound packet should always be SR or RR + if((status = rtcpcomppack->StartReceiverReport(ssrc)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + } + + //add SDES packet with CNAME item + if ((status = rtcpcomppack->AddSDESSource(ssrc)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + BUILDER_LOCK + size_t owncnamelen = 0; + uint8_t *owncname = rtcpbuilder.GetLocalCNAME(&owncnamelen); + + if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::CNAME,owncname,owncnamelen)) < 0) + { + BUILDER_UNLOCK + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + BUILDER_UNLOCK + + //add our packet + if((status = rtcpcomppack->AddUnknownPacket(payload_type, subtype, ssrc, data, len)) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + if((status = rtcpcomppack->EndBuild()) < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + //send packet + status = rtptrans->SendRTCPData(rtcpcomppack->GetCompoundPacketData(), + rtcpcomppack->GetCompoundPacketLength()); + if(status < 0) + { + RTPDelete(rtcpcomppack,GetMemoryManager()); + return status; + } + + PACKSENT_LOCK + sentpackets = true; + PACKSENT_UNLOCK + + OnSendRTCPCompoundPacket(rtcpcomppack); // we'll place this after the actual send to avoid tampering + + int retlen = rtcpcomppack->GetCompoundPacketLength(); + + RTPDelete(rtcpcomppack,GetMemoryManager()); + return retlen; +} + +#endif // RTP_SUPPORT_RTCPUNKNOWN + +int RTPSession::SetDefaultPayloadType(uint8_t pt) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + + BUILDER_LOCK + status = packetbuilder.SetDefaultPayloadType(pt); + BUILDER_UNLOCK + return status; +} + +int RTPSession::SetDefaultMark(bool m) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + + BUILDER_LOCK + status = packetbuilder.SetDefaultMark(m); + BUILDER_UNLOCK + return status; +} + +int RTPSession::SetDefaultTimestampIncrement(uint32_t timestampinc) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + + BUILDER_LOCK + status = packetbuilder.SetDefaultTimestampIncrement(timestampinc); + BUILDER_UNLOCK + return status; +} + +int RTPSession::IncrementTimestamp(uint32_t inc) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + + BUILDER_LOCK + status = packetbuilder.IncrementTimestamp(inc); + BUILDER_UNLOCK + return status; +} + +int RTPSession::IncrementTimestampDefault() +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + + BUILDER_LOCK + status = packetbuilder.IncrementTimestampDefault(); + BUILDER_UNLOCK + return status; +} + +int RTPSession::SetPreTransmissionDelay(const RTPTime &delay) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + + BUILDER_LOCK + status = rtcpbuilder.SetPreTransmissionDelay(delay); + BUILDER_UNLOCK + return status; +} + +RTPTransmissionInfo *RTPSession::GetTransmissionInfo() +{ + if (!created) + return 0; + return rtptrans->GetTransmissionInfo(); +} + +void RTPSession::DeleteTransmissionInfo(RTPTransmissionInfo *inf) +{ + if (!created) + return; + rtptrans->DeleteTransmissionInfo(inf); +} + +int RTPSession::Poll() +{ + int status; + + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + if (usingpollthread) + return ERR_RTP_SESSION_USINGPOLLTHREAD; + if ((status = rtptrans->Poll()) < 0) + return status; + return ProcessPolledData(); +} + +int RTPSession::WaitForIncomingData(const RTPTime &delay,bool *dataavailable) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + if (usingpollthread) + return ERR_RTP_SESSION_USINGPOLLTHREAD; + return rtptrans->WaitForIncomingData(delay,dataavailable); +} + +int RTPSession::AbortWait() +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + if (usingpollthread) + return ERR_RTP_SESSION_USINGPOLLTHREAD; + return rtptrans->AbortWait(); +} + +RTPTime RTPSession::GetRTCPDelay() +{ + if (!created) + return RTPTime(0,0); + if (usingpollthread) + return RTPTime(0,0); + + SOURCES_LOCK + SCHED_LOCK + RTPTime t = rtcpsched.GetTransmissionDelay(); + SCHED_UNLOCK + SOURCES_UNLOCK + return t; +} + +int RTPSession::BeginDataAccess() +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + SOURCES_LOCK + return 0; +} + +bool RTPSession::GotoFirstSource() +{ + if (!created) + return false; + return sources.GotoFirstSource(); +} + +bool RTPSession::GotoNextSource() +{ + if (!created) + return false; + return sources.GotoNextSource(); +} + +bool RTPSession::GotoPreviousSource() +{ + if (!created) + return false; + return sources.GotoPreviousSource(); +} + +bool RTPSession::GotoFirstSourceWithData() +{ + if (!created) + return false; + return sources.GotoFirstSourceWithData(); +} + +bool RTPSession::GotoNextSourceWithData() +{ + if (!created) + return false; + return sources.GotoNextSourceWithData(); +} + +bool RTPSession::GotoPreviousSourceWithData() +{ + if (!created) + return false; + return sources.GotoPreviousSourceWithData(); +} + +RTPSourceData *RTPSession::GetCurrentSourceInfo() +{ + if (!created) + return 0; + return sources.GetCurrentSourceInfo(); +} + +RTPSourceData *RTPSession::GetSourceInfo(uint32_t ssrc) +{ + if (!created) + return 0; + return sources.GetSourceInfo(ssrc); +} + +RTPPacket *RTPSession::GetNextPacket() +{ + if (!created) + return 0; + return sources.GetNextPacket(); +} + +void RTPSession::DeletePacket(RTPPacket *p) +{ + RTPDelete(p,GetMemoryManager()); +} + +int RTPSession::EndDataAccess() +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + SOURCES_UNLOCK + return 0; +} + +int RTPSession::SetReceiveMode(RTPTransmitter::ReceiveMode m) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + return rtptrans->SetReceiveMode(m); +} + +int RTPSession::AddToIgnoreList(const RTPAddress &addr) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + return rtptrans->AddToIgnoreList(addr); +} + +int RTPSession::DeleteFromIgnoreList(const RTPAddress &addr) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + return rtptrans->DeleteFromIgnoreList(addr); +} + +void RTPSession::ClearIgnoreList() +{ + if (!created) + return; + rtptrans->ClearIgnoreList(); +} + +int RTPSession::AddToAcceptList(const RTPAddress &addr) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + return rtptrans->AddToAcceptList(addr); +} + +int RTPSession::DeleteFromAcceptList(const RTPAddress &addr) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + return rtptrans->DeleteFromAcceptList(addr); +} + +void RTPSession::ClearAcceptList() +{ + if (!created) + return; + rtptrans->ClearAcceptList(); +} + +int RTPSession::SetMaximumPacketSize(size_t s) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + if (s < RTP_MINPACKETSIZE) + return ERR_RTP_SESSION_MAXPACKETSIZETOOSMALL; + + int status; + + if ((status = rtptrans->SetMaximumPacketSize(s)) < 0) + return status; + + BUILDER_LOCK + if ((status = packetbuilder.SetMaximumPacketSize(s)) < 0) + { + BUILDER_UNLOCK + // restore previous max packet size + rtptrans->SetMaximumPacketSize(maxpacksize); + return status; + } + if ((status = rtcpbuilder.SetMaximumPacketSize(s)) < 0) + { + // restore previous max packet size + packetbuilder.SetMaximumPacketSize(maxpacksize); + BUILDER_UNLOCK + rtptrans->SetMaximumPacketSize(maxpacksize); + return status; + } + BUILDER_UNLOCK + maxpacksize = s; + return 0; +} + +int RTPSession::SetSessionBandwidth(double bw) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + SCHED_LOCK + RTCPSchedulerParams p = rtcpsched.GetParameters(); + status = p.SetRTCPBandwidth(bw*controlfragment); + if (status >= 0) + { + rtcpsched.SetParameters(p); + sessionbandwidth = bw; + } + SCHED_UNLOCK + return status; +} + +int RTPSession::SetTimestampUnit(double u) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + + BUILDER_LOCK + status = rtcpbuilder.SetTimestampUnit(u); + BUILDER_UNLOCK + return status; +} + +void RTPSession::SetNameInterval(int count) +{ + if (!created) + return; + BUILDER_LOCK + rtcpbuilder.SetNameInterval(count); + BUILDER_UNLOCK +} + +void RTPSession::SetEMailInterval(int count) +{ + if (!created) + return; + BUILDER_LOCK + rtcpbuilder.SetEMailInterval(count); + BUILDER_UNLOCK +} + +void RTPSession::SetLocationInterval(int count) +{ + if (!created) + return; + BUILDER_LOCK + rtcpbuilder.SetLocationInterval(count); + BUILDER_UNLOCK +} + +void RTPSession::SetPhoneInterval(int count) +{ + if (!created) + return; + BUILDER_LOCK + rtcpbuilder.SetPhoneInterval(count); + BUILDER_UNLOCK +} + +void RTPSession::SetToolInterval(int count) +{ + if (!created) + return; + BUILDER_LOCK + rtcpbuilder.SetToolInterval(count); + BUILDER_UNLOCK +} + +void RTPSession::SetNoteInterval(int count) +{ + if (!created) + return; + BUILDER_LOCK + rtcpbuilder.SetNoteInterval(count); + BUILDER_UNLOCK +} + +int RTPSession::SetLocalName(const void *s,size_t len) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + BUILDER_LOCK + status = rtcpbuilder.SetLocalName(s,len); + BUILDER_UNLOCK + return status; +} + +int RTPSession::SetLocalEMail(const void *s,size_t len) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + BUILDER_LOCK + status = rtcpbuilder.SetLocalEMail(s,len); + BUILDER_UNLOCK + return status; +} + +int RTPSession::SetLocalLocation(const void *s,size_t len) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + BUILDER_LOCK + status = rtcpbuilder.SetLocalLocation(s,len); + BUILDER_UNLOCK + return status; +} + +int RTPSession::SetLocalPhone(const void *s,size_t len) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + BUILDER_LOCK + status = rtcpbuilder.SetLocalPhone(s,len); + BUILDER_UNLOCK + return status; +} + +int RTPSession::SetLocalTool(const void *s,size_t len) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + BUILDER_LOCK + status = rtcpbuilder.SetLocalTool(s,len); + BUILDER_UNLOCK + return status; +} + +int RTPSession::SetLocalNote(const void *s,size_t len) +{ + if (!created) + return ERR_RTP_SESSION_NOTCREATED; + + int status; + BUILDER_LOCK + status = rtcpbuilder.SetLocalNote(s,len); + BUILDER_UNLOCK + return status; +} + +int RTPSession::ProcessPolledData() +{ + RTPRawPacket *rawpack; + int status; + + SOURCES_LOCK + while ((rawpack = rtptrans->GetNextPacket()) != 0) + { + sources.ClearOwnCollisionFlag(); + + // since our sources instance also uses the scheduler (analysis of incoming packets) + // we'll lock it + SCHED_LOCK + if ((status = sources.ProcessRawPacket(rawpack,rtptrans,acceptownpackets)) < 0) + { + SCHED_UNLOCK + SOURCES_UNLOCK + RTPDelete(rawpack,GetMemoryManager()); + return status; + } + SCHED_UNLOCK + + if (sources.DetectedOwnCollision()) // collision handling! + { + bool created; + + if ((status = collisionlist.UpdateAddress(rawpack->GetSenderAddress(),rawpack->GetReceiveTime(),&created)) < 0) + { + SOURCES_UNLOCK + RTPDelete(rawpack,GetMemoryManager()); + return status; + } + + if (created) // first time we've encountered this address, send bye packet and + { // change our own SSRC + PACKSENT_LOCK + bool hassentpackets = sentpackets; + PACKSENT_UNLOCK + + if (hassentpackets) + { + // Only send BYE packet if we've actually sent data using this + // SSRC + + RTCPCompoundPacket *rtcpcomppack; + + BUILDER_LOCK + if ((status = rtcpbuilder.BuildBYEPacket(&rtcpcomppack,0,0,useSR_BYEifpossible)) < 0) + { + BUILDER_UNLOCK + SOURCES_UNLOCK + RTPDelete(rawpack,GetMemoryManager()); + return status; + } + BUILDER_UNLOCK + + byepackets.push_back(rtcpcomppack); + if (byepackets.size() == 1) // was the first packet, schedule a BYE packet (otherwise there's already one scheduled) + { + SCHED_LOCK + rtcpsched.ScheduleBYEPacket(rtcpcomppack->GetCompoundPacketLength()); + SCHED_UNLOCK + } + } + // bye packet is built and scheduled, now change our SSRC + // and reset the packet count in the transmitter + + BUILDER_LOCK + uint32_t newssrc = packetbuilder.CreateNewSSRC(sources); + BUILDER_UNLOCK + + PACKSENT_LOCK + sentpackets = false; + PACKSENT_UNLOCK + + // remove old entry in source table and add new one + + if ((status = sources.DeleteOwnSSRC()) < 0) + { + SOURCES_UNLOCK + RTPDelete(rawpack,GetMemoryManager()); + return status; + } + if ((status = sources.CreateOwnSSRC(newssrc)) < 0) + { + SOURCES_UNLOCK + RTPDelete(rawpack,GetMemoryManager()); + return status; + } + } + } + RTPDelete(rawpack,GetMemoryManager()); + } + + SCHED_LOCK + RTPTime d = rtcpsched.CalculateDeterministicInterval(false); + SCHED_UNLOCK + + RTPTime t = RTPTime::CurrentTime(); + double Td = d.GetDouble(); + RTPTime sendertimeout = RTPTime(Td*sendermultiplier); + RTPTime generaltimeout = RTPTime(Td*membermultiplier); + RTPTime byetimeout = RTPTime(Td*byemultiplier); + RTPTime colltimeout = RTPTime(Td*collisionmultiplier); + RTPTime notetimeout = RTPTime(Td*notemultiplier); + + sources.MultipleTimeouts(t,sendertimeout,byetimeout,generaltimeout,notetimeout); + collisionlist.Timeout(t,colltimeout); + + // We'll check if it's time for RTCP stuff + + SCHED_LOCK + bool istime = rtcpsched.IsTime(); + SCHED_UNLOCK + + if (istime) + { + RTCPCompoundPacket *pack; + + // we'll check if there's a bye packet to send, or just a normal packet + + if (byepackets.empty()) + { + BUILDER_LOCK + if ((status = rtcpbuilder.BuildNextPacket(&pack)) < 0) + { + BUILDER_UNLOCK + SOURCES_UNLOCK + return status; + } + BUILDER_UNLOCK + if ((status = rtptrans->SendRTCPData(pack->GetCompoundPacketData(),pack->GetCompoundPacketLength())) < 0) + { + SOURCES_UNLOCK + RTPDelete(pack,GetMemoryManager()); + return status; + } + + PACKSENT_LOCK + sentpackets = true; + PACKSENT_UNLOCK + + OnSendRTCPCompoundPacket(pack); // we'll place this after the actual send to avoid tampering + } + else + { + pack = *(byepackets.begin()); + byepackets.pop_front(); + + if ((status = rtptrans->SendRTCPData(pack->GetCompoundPacketData(),pack->GetCompoundPacketLength())) < 0) + { + SOURCES_UNLOCK + RTPDelete(pack,GetMemoryManager()); + return status; + } + + PACKSENT_LOCK + sentpackets = true; + PACKSENT_UNLOCK + + OnSendRTCPCompoundPacket(pack); // we'll place this after the actual send to avoid tampering + + if (!byepackets.empty()) // more bye packets to send, schedule them + { + SCHED_LOCK + rtcpsched.ScheduleBYEPacket((*(byepackets.begin()))->GetCompoundPacketLength()); + SCHED_UNLOCK + } + } + + SCHED_LOCK + rtcpsched.AnalyseOutgoing(*pack); + SCHED_UNLOCK + + RTPDelete(pack,GetMemoryManager()); + } + SOURCES_UNLOCK + return 0; +} + +int RTPSession::CreateCNAME(uint8_t *buffer,size_t *bufferlength,bool resolve) +{ +#ifndef WIN32 + bool gotlogin = true; +#ifdef RTP_SUPPORT_GETLOGINR + buffer[0] = 0; + if (getlogin_r((char *)buffer,*bufferlength) != 0) + gotlogin = false; + else + { + if (buffer[0] == 0) + gotlogin = false; + } + + if (!gotlogin) // try regular getlogin + { + char *loginname = getlogin(); + if (loginname == 0) + gotlogin = false; + else + strncpy((char *)buffer,loginname,*bufferlength); + } +#else + char *loginname = getlogin(); + if (loginname == 0) + gotlogin = false; + else + strncpy((char *)buffer,loginname,*bufferlength); +#endif // RTP_SUPPORT_GETLOGINR + if (!gotlogin) + { + char *logname = getenv("LOGNAME"); + if (logname == 0) + return ERR_RTP_SESSION_CANTGETLOGINNAME; + strncpy((char *)buffer,logname,*bufferlength); + } +#else // Win32 version + +#ifndef _WIN32_WCE + DWORD len = *bufferlength; + if (!GetUserName((LPTSTR)buffer,&len)) +#if (defined(_MSC_VER) && _MSC_VER >= 1400 ) // Check if we can use the secure strncpy_s + strncpy_s((char *)buffer,*bufferlength,"unknown",_TRUNCATE); +#else + strncpy((char *)buffer,"unknown",*bufferlength); +#endif // Less secure version + +#else + strncpy((char *)buffer,"unknown",*bufferlength); +#endif // _WIN32_WCE + +#endif // WIN32 + buffer[*bufferlength-1] = 0; + + size_t offset = strlen((const char *)buffer); + if (offset < (*bufferlength-1)) + buffer[offset] = (uint8_t)'@'; + offset++; + + size_t buflen2 = *bufferlength-offset; + int status; + + if (resolve) + { + if ((status = rtptrans->GetLocalHostName(buffer+offset,&buflen2)) < 0) + return status; + *bufferlength = buflen2+offset; + } + else + { + char hostname[1024]; + +#if defined(WIN32) && !defined(_WIN32_WCE) && (defined(_MSC_VER) && _MSC_VER >= 1400 ) // Check if we can use the secure strncpy_s + strncpy_s(hostname,1024,"localhost",_TRUNCATE); // just in case gethostname fails +#else + strncpy(hostname,"localhost",1024); // just in case gethostname fails +#endif + gethostname(hostname,1024); +#if defined(WIN32) && !defined(_WIN32_WCE) && (defined(_MSC_VER) && _MSC_VER >= 1400 ) // Check if we can use the secure strncpy_s + strncpy_s((char *)(buffer+offset),buflen2,hostname,_TRUNCATE); +#else + strncpy((char *)(buffer+offset),hostname,buflen2); +#endif + *bufferlength = offset+strlen(hostname); + } + if (*bufferlength > RTCP_SDES_MAXITEMLENGTH) + *bufferlength = RTCP_SDES_MAXITEMLENGTH; + return 0; +} + +RTPRandom *RTPSession::GetRandomNumberGenerator(RTPRandom *r) +{ + RTPRandom *rnew = 0; + + if (r == 0) + { +#if defined(WIN32) || defined(_WIN32_WCE) + RTPRandomRandS *rnew2 = new RTPRandomRandS(); +#else + RTPRandomURandom *rnew2 = new RTPRandomURandom(); +#endif // WIN32 || _WIN32_WCE + + if (rnew2->Init() < 0) // fall back to rand48 + { + delete rnew2; + rnew = new RTPRandomRand48(); + } + else + rnew = rnew2; + + deletertprnd = true; + } + else + { + rnew = r; + deletertprnd = false; + } + + return rnew; +} + +#ifdef RTPDEBUG +void RTPSession::DumpSources() +{ + BeginDataAccess(); + std::cout << "----------------------------------------------------------------" << std::endl; + sources.Dump(); + EndDataAccess(); +} + +void RTPSession::DumpTransmitter() +{ + if (created) + rtptrans->Dump(); +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtpsession.h b/src/libs/jrtplib/src/rtpsession.h new file mode 100644 index 00000000..df846098 --- /dev/null +++ b/src/libs/jrtplib/src/rtpsession.h @@ -0,0 +1,580 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpsession.h + */ + +#ifndef RTPSESSION_H + +#define RTPSESSION_H + +#include "rtpconfig.h" +#include "rtplibraryversion.h" +#include "rtppacketbuilder.h" +#include "rtpsessionsources.h" +#include "rtptransmitter.h" +#include "rtpcollisionlist.h" +#include "rtcpscheduler.h" +#include "rtcppacketbuilder.h" +#include "rtptimeutilities.h" +#include "rtcpcompoundpacketbuilder.h" +#include "rtpmemoryobject.h" +#include + +#ifdef RTP_SUPPORT_THREAD + #include +#endif // RTP_SUPPORT_THREAD + +namespace jrtplib +{ + +class RTPTransmitter; +class RTPSessionParams; +class RTPTransmissionParams; +class RTPAddress; +class RTPSourceData; +class RTPPacket; +class RTPPollThread; +class RTPTransmissionInfo; +class RTCPCompoundPacket; +class RTCPPacket; +class RTCPAPPPacket; + +/** High level class for using RTP. + * For most RTP based applications, the RTPSession class will probably be the one to use. It handles + * the RTCP part completely internally, so the user can focus on sending and receiving the actual data. + * \note The RTPSession class is not meant to be thread safe. The user should use some kind of locking + * mechanism to prevent different threads from using the same RTPSession instance. + */ +class JRTPLIB_IMPORTEXPORT RTPSession : public RTPMemoryObject +{ +public: + /** Constructs an RTPSession instance, optionally using a specific instance of a random + * number generator, and optionally installing a memory manager. + * Constructs an RTPSession instance, optionally using a specific instance of a random + * number generator, and optionally installing a memory manager. If no random number generator + * is specified, the RTPSession object will try to use either a RTPRandomURandom or + * RTPRandomRandS instance. If neither is available on the current platform, a RTPRandomRand48 + * instance will be used instead. By specifying a random number generator yourself, it is + * possible to use the same generator in several RTPSession instances. + */ + RTPSession(RTPRandom *rnd = 0, RTPMemoryManager *mgr = 0); + virtual ~RTPSession(); + + /** Creates an RTP session. + * This function creates an RTP session with parameters \c sessparams, which will use a transmitter + * corresponding to \c proto. Parameters for this transmitter can be specified as well. If \c + * proto is of type RTPTransmitter::UserDefinedProto, the NewUserDefinedTransmitter function must + * be implemented. + */ + int Create(const RTPSessionParams &sessparams,const RTPTransmissionParams *transparams = 0, RTPTransmitter::TransmissionProtocol proto = RTPTransmitter::IPv4UDPProto); + + /** Creates an RTP session using \c transmitter as transmission component. + * This function creates an RTP session with parameters \c sessparams, which will use the + * transmission component \c transmitter. Initialization and destruction of the transmitter + * will not be done by the RTPSession class if this Create function is used. This function + * can be useful if you which to reuse the transmission component in another RTPSession + * instance, once the original RTPSession isn't using the transmitter anymore. + */ + int Create(const RTPSessionParams &sessparams,RTPTransmitter *transmitter); + + /** Leaves the session without sending a BYE packet. */ + void Destroy(); + + /** Sends a BYE packet and leaves the session. + * Sends a BYE packet and leaves the session. At most a time \c maxwaittime will be waited to + * send the BYE packet. If this time expires, the session will be left without sending a BYE packet. + * The BYE packet will contain as reason for leaving \c reason with length \c reasonlength. + */ + void BYEDestroy(const RTPTime &maxwaittime,const void *reason,size_t reasonlength); + + /** Returns whether the session has been created or not. */ + bool IsActive(); + + /** Returns our own SSRC. */ + uint32_t GetLocalSSRC(); + + /** Adds \c addr to the list of destinations. */ + int AddDestination(const RTPAddress &addr); + + /** Deletes \c addr from the list of destinations. */ + int DeleteDestination(const RTPAddress &addr); + + /** Clears the list of destinations. */ + void ClearDestinations(); + + /** Returns \c true if multicasting is supported. */ + bool SupportsMulticasting(); + + /** Joins the multicast group specified by \c addr. */ + int JoinMulticastGroup(const RTPAddress &addr); + + /** Leaves the multicast group specified by \c addr. */ + int LeaveMulticastGroup(const RTPAddress &addr); + + /** Leaves all multicast groups. */ + void LeaveAllMulticastGroups(); + + /** Sends the RTP packet with payload \c data which has length \c len. + * Sends the RTP packet with payload \c data which has length \c len. + * The used payload type, marker and timestamp increment will be those that have been set + * using the \c SetDefault member functions. + */ + int SendPacket(const void *data,size_t len); + + /** Sends the RTP packet with payload \c data which has length \c len. + * It will use payload type \c pt, marker \c mark and after the packet has been built, the + * timestamp will be incremented by \c timestampinc. + */ + int SendPacket(const void *data,size_t len, + uint8_t pt,bool mark,uint32_t timestampinc); + + /** Sends the RTP packet with payload \c data which has length \c len. + * The packet will contain a header extension with identifier \c hdrextID and containing data + * \c hdrextdata. The length of this data is given by \c numhdrextwords and is specified in a + * number of 32-bit words. The used payload type, marker and timestamp increment will be those that + * have been set using the \c SetDefault member functions. + */ + int SendPacketEx(const void *data,size_t len, + uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords); + + /** Sends the RTP packet with payload \c data which has length \c len. + * It will use payload type \c pt, marker \c mark and after the packet has been built, the + * timestamp will be incremented by \c timestampinc. The packet will contain a header + * extension with identifier \c hdrextID and containing data \c hdrextdata. The length + * of this data is given by \c numhdrextwords and is specified in a number of 32-bit words. + */ + int SendPacketEx(const void *data,size_t len, + uint8_t pt,bool mark,uint32_t timestampinc, + uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords); +#ifdef RTP_SUPPORT_SENDAPP + /** If sending of RTCP APP packets was enabled at compile time, this function creates a compound packet + * containing an RTCP APP packet and sends it immediately. + * If sending of RTCP APP packets was enabled at compile time, this function creates a compound packet + * containing an RTCP APP packet and sends it immediately. If successful, the function returns the number + * of bytes in the RTCP compound packet. Note that this immediate sending is not compliant with the RTP + * specification, so use with care. + */ + int SendRTCPAPPPacket(uint8_t subtype, const uint8_t name[4], const void *appdata, size_t appdatalen); +#endif // RTP_SUPPORT_SENDAPP + +#ifdef RTP_SUPPORT_RTCPUNKNOWN + /** Tries to send an Unknown packet immediately. + * Tries to send an Unknown packet immediately. If successful, the function returns the number + * of bytes in the RTCP compound packet. Note that this immediate sending is not compliant with the RTP + * specification, so use with care. Can send message along with a receiver report or a sender report + */ + int SendUnknownPacket(bool sr, uint8_t payload_type, uint8_t subtype, const void *data, size_t len); +#endif // RTP_SUPPORT_RTCPUNKNOWN + /** Sets the default payload type for RTP packets to \c pt. */ + int SetDefaultPayloadType(uint8_t pt); + + /** Sets the default marker for RTP packets to \c m. */ + int SetDefaultMark(bool m); + + /** Sets the default value to increment the timestamp with to \c timestampinc. */ + int SetDefaultTimestampIncrement(uint32_t timestampinc); + + /** This function increments the timestamp with the amount given by \c inc. + * This function increments the timestamp with the amount given by \c inc. This can be useful + * if, for example, a packet was not sent because it contained only silence. Then, this function + * should be called to increment the timestamp with the appropriate amount so that the next packets + * will still be played at the correct time at other hosts. + */ + int IncrementTimestamp(uint32_t inc); + + /** This function increments the timestamp with the amount given set by the SetDefaultTimestampIncrement + * member function. + * This function increments the timestamp with the amount given set by the SetDefaultTimestampIncrement + * member function. This can be useful if, for example, a packet was not sent because it contained only silence. + * Then, this function should be called to increment the timestamp with the appropriate amount so that the next + * packets will still be played at the correct time at other hosts. + */ + int IncrementTimestampDefault(); + + /** This function allows you to inform the library about the delay between sampling the first + * sample of a packet and sending the packet. + * This function allows you to inform the library about the delay between sampling the first + * sample of a packet and sending the packet. This delay is taken into account when calculating the + * relation between RTP timestamp and wallclock time, used for inter-media synchronization. + */ + int SetPreTransmissionDelay(const RTPTime &delay); + + /** This function returns an instance of a subclass of RTPTransmissionInfo which will give some + * additional information about the transmitter (a list of local IP addresses for example). + * This function returns an instance of a subclass of RTPTransmissionInfo which will give some + * additional information about the transmitter (a list of local IP addresses for example). The user + * has to free the returned instance when it is no longer needed, preferably using the DeleteTransmissionInfo + * function. + */ + RTPTransmissionInfo *GetTransmissionInfo(); + + /** Frees the memory used by the transmission information \c inf. */ + void DeleteTransmissionInfo(RTPTransmissionInfo *inf); + + /** If you're not using the poll thread, this function must be called regularly to process incoming data + * and to send RTCP data when necessary. + */ + int Poll(); + + /** Waits at most a time \c delay until incoming data has been detected. + * Waits at most a time \c delay until incoming data has been detected. Only works when you're not + * using the poll thread. If \c dataavailable is not \c NULL, it should be set to \c true if data + * was actually read and to \c false otherwise. + */ + int WaitForIncomingData(const RTPTime &delay,bool *dataavailable = 0); + + /** If the previous function has been called, this one aborts the waiting (only works when you're not + * using the poll thread). + */ + int AbortWait(); + + /** Returns the time interval after which an RTCP compound packet may have to be sent (only works when + * you're not using the poll thread. + */ + RTPTime GetRTCPDelay(); + + /** The following member functions (till EndDataAccess}) need to be accessed between a call + * to BeginDataAccess and EndDataAccess. + * The BeginDataAccess function makes sure that the poll thread won't access the source table + * at the same time that you're using it. When the EndDataAccess is called, the lock on the + * source table is freed again. + */ + int BeginDataAccess(); + + /** Starts the iteration over the participants by going to the first member in the table. + * Starts the iteration over the participants by going to the first member in the table. + * If a member was found, the function returns \c true, otherwise it returns \c false. + */ + bool GotoFirstSource(); + + /** Sets the current source to be the next source in the table. + * Sets the current source to be the next source in the table. If we're already at the last + * source, the function returns \c false, otherwise it returns \c true. + */ + bool GotoNextSource(); + + /** Sets the current source to be the previous source in the table. + * Sets the current source to be the previous source in the table. If we're at the first source, + * the function returns \c false, otherwise it returns \c true. + */ + bool GotoPreviousSource(); + + /** Sets the current source to be the first source in the table which has RTPPacket instances + * that we haven't extracted yet. + * Sets the current source to be the first source in the table which has RTPPacket instances + * that we haven't extracted yet. If no such member was found, the function returns \c false, + * otherwise it returns \c true. + */ + bool GotoFirstSourceWithData(); + + /** Sets the current source to be the next source in the table which has RTPPacket instances + * that we haven't extracted yet. + * Sets the current source to be the next source in the table which has RTPPacket instances + * that we haven't extracted yet. If no such member was found, the function returns \c false, + * otherwise it returns \c true. + */ + bool GotoNextSourceWithData(); + + /** Sets the current source to be the previous source in the table which has RTPPacket + * instances that we haven't extracted yet. + * Sets the current source to be the previous source in the table which has RTPPacket + * instances that we haven't extracted yet. If no such member was found, the function returns \c false, + * otherwise it returns \c true. + */ + bool GotoPreviousSourceWithData(); + + /** Returns the \c RTPSourceData instance for the currently selected participant. */ + RTPSourceData *GetCurrentSourceInfo(); + + /** Returns the \c RTPSourceData instance for the participant identified by \c ssrc, + * or NULL if no such entry exists. + */ + RTPSourceData *GetSourceInfo(uint32_t ssrc); + + /** Extracts the next packet from the received packets queue of the current participant, + * or NULL if no more packets are available. + * Extracts the next packet from the received packets queue of the current participant, + * or NULL if no more packets are available. When the packet is no longer needed, its + * memory should be freed using the DeletePacket member function. + */ + RTPPacket *GetNextPacket(); + + /** Frees the memory used by \c p. */ + void DeletePacket(RTPPacket *p); + + /** See BeginDataAccess. */ + int EndDataAccess(); + + /** Sets the receive mode to \c m. + * Sets the receive mode to \c m. Note that when the receive mode is changed, the list of + * addresses to be ignored ot accepted will be cleared. + */ + int SetReceiveMode(RTPTransmitter::ReceiveMode m); + + /** Adds \c addr to the list of addresses to ignore. */ + int AddToIgnoreList(const RTPAddress &addr); + + /** Deletes \c addr from the list of addresses to ignore. */ + int DeleteFromIgnoreList(const RTPAddress &addr); + + /** Clears the list of addresses to ignore. */ + void ClearIgnoreList(); + + /** Adds \c addr to the list of addresses to accept. */ + int AddToAcceptList(const RTPAddress &addr); + + /** Deletes \c addr from the list of addresses to accept. */ + int DeleteFromAcceptList(const RTPAddress &addr); + + /** Clears the list of addresses to accept. */ + void ClearAcceptList(); + + /** Sets the maximum allowed packet size to \c s. */ + int SetMaximumPacketSize(size_t s); + + /** Sets the session bandwidth to \c bw, which is specified in bytes per second. */ + int SetSessionBandwidth(double bw); + + /** Sets the timestamp unit for our own data. + * Sets the timestamp unit for our own data. The timestamp unit is defined as a time interval in + * seconds divided by the corresponding timestamp interval. For example, for 8000 Hz audio, the + * timestamp unit would typically be 1/8000. Since this value is initially set to an illegal value, + * the user must set this to an allowed value to be able to create a session. + */ + int SetTimestampUnit(double u); + + /** Sets the RTCP interval for the SDES name item. + * After all possible sources in the source table have been processed, the class will check if other + * SDES items need to be sent. If \c count is zero or negative, nothing will happen. If \c count + * is positive, an SDES name item will be added after the sources in the source table have been + * processed \c count times. + */ + void SetNameInterval(int count); + + /** Sets the RTCP interval for the SDES e-mail item. + * After all possible sources in the source table have been processed, the class will check if other + * SDES items need to be sent. If \c count is zero or negative, nothing will happen. If \c count + * is positive, an SDES e-mail item will be added after the sources in the source table have been + * processed \c count times. + */ + void SetEMailInterval(int count); + + /** Sets the RTCP interval for the SDES location item. + * After all possible sources in the source table have been processed, the class will check if other + * SDES items need to be sent. If \c count is zero or negative, nothing will happen. If \c count + * is positive, an SDES location item will be added after the sources in the source table have been + * processed \c count times. + */ + void SetLocationInterval(int count); + + /** Sets the RTCP interval for the SDES phone item. + * After all possible sources in the source table have been processed, the class will check if other + * SDES items need to be sent. If \c count is zero or negative, nothing will happen. If \c count + * is positive, an SDES phone item will be added after the sources in the source table have been + * processed \c count times. + */ + void SetPhoneInterval(int count); + + /** Sets the RTCP interval for the SDES tool item. + * After all possible sources in the source table have been processed, the class will check if other + * SDES items need to be sent. If \c count is zero or negative, nothing will happen. If \c count + * is positive, an SDES tool item will be added after the sources in the source table have been + * processed \c count times. + */ + void SetToolInterval(int count); + + /** Sets the RTCP interval for the SDES note item. + * After all possible sources in the source table have been processed, the class will check if other + * SDES items need to be sent. If \c count is zero or negative, nothing will happen. If \c count + * is positive, an SDES note item will be added after the sources in the source table have been + * processed \c count times. + */ + void SetNoteInterval(int count); + + /** Sets the SDES name item for the local participant to the value \c s with length \c len. */ + int SetLocalName(const void *s,size_t len); + + /** Sets the SDES e-mail item for the local participant to the value \c s with length \c len. */ + int SetLocalEMail(const void *s,size_t len); + + /** Sets the SDES location item for the local participant to the value \c s with length \c len. */ + int SetLocalLocation(const void *s,size_t len); + + /** Sets the SDES phone item for the local participant to the value \c s with length \c len. */ + int SetLocalPhone(const void *s,size_t len); + + /** Sets the SDES tool item for the local participant to the value \c s with length \c len. */ + int SetLocalTool(const void *s,size_t len); + + /** Sets the SDES note item for the local participant to the value \c s with length \c len. */ + int SetLocalNote(const void *s,size_t len); + +#ifdef RTPDEBUG + void DumpSources(); + void DumpTransmitter(); +#endif // RTPDEBUG +protected: + /** Allocate a user defined transmitter. + * In case you specified in the Create function that you want to use a + * user defined transmitter, you should override this function. The RTPTransmitter + * instance returned by this function will then be used to send and receive RTP and + * RTCP packets. Note that when the session is destroyed, this RTPTransmitter + * instance will be destroyed as well. + */ + virtual RTPTransmitter *NewUserDefinedTransmitter() { return 0; } + + /** Is called when an incoming RTP packet is about to be processed. */ + virtual void OnRTPPacket(RTPPacket *pack,const RTPTime &receivetime, + const RTPAddress *senderaddress) { } + + /** Is called when an incoming RTCP packet is about to be processed. */ + virtual void OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime, + const RTPAddress *senderaddress) { } + + /** Is called when an SSRC collision was detected. + * Is called when an SSRC collision was detected. The instance \c srcdat is the one present in + * the table, the address \c senderaddress is the one that collided with one of the addresses + * and \c isrtp indicates against which address of \c srcdat the check failed. + */ + virtual void OnSSRCCollision(RTPSourceData *srcdat,const RTPAddress *senderaddress,bool isrtp) { } + + /** Is called when another CNAME was received than the one already present for source \c srcdat. */ + virtual void OnCNAMECollision(RTPSourceData *srcdat,const RTPAddress *senderaddress, + const uint8_t *cname,size_t cnamelength) { } + + /** Is called when a new entry \c srcdat is added to the source table. */ + virtual void OnNewSource(RTPSourceData *srcdat) { } + + /** Is called when the entry \c srcdat is about to be deleted from the source table. */ + virtual void OnRemoveSource(RTPSourceData *srcdat) { } + + /** Is called when participant \c srcdat is timed out. */ + virtual void OnTimeout(RTPSourceData *srcdat) { } + + /** Is called when participant \c srcdat is timed after having sent a BYE packet. */ + virtual void OnBYETimeout(RTPSourceData *srcdat) { } + + /** Is called when an RTCP APP packet \c apppacket has been received at time \c receivetime + * from address \c senderaddress. + */ + virtual void OnAPPPacket(RTCPAPPPacket *apppacket,const RTPTime &receivetime, + const RTPAddress *senderaddress) { } + + /** Is called when an unknown RTCP packet type was detected. */ + virtual void OnUnknownPacketType(RTCPPacket *rtcppack,const RTPTime &receivetime, + const RTPAddress *senderaddress) { } + + /** Is called when an unknown packet format for a known packet type was detected. */ + virtual void OnUnknownPacketFormat(RTCPPacket *rtcppack,const RTPTime &receivetime, + const RTPAddress *senderaddress) { } + + /** Is called when the SDES NOTE item for source \c srcdat has been timed out. */ + virtual void OnNoteTimeout(RTPSourceData *srcdat) { } + + /** Is called when a BYE packet has been processed for source \c srcdat. */ + virtual void OnBYEPacket(RTPSourceData *srcdat) { } + + /** Is called when an RTCP compound packet has just been sent (useful to inspect outgoing RTCP data). */ + virtual void OnSendRTCPCompoundPacket(RTCPCompoundPacket *pack) { } +#ifdef RTP_SUPPORT_THREAD + /** Is called when error \c errcode was detected in the poll thread. */ + virtual void OnPollThreadError(int errcode) { } + + /** Is called each time the poll thread loops. + * Is called each time the poll thread loops. This happens when incoming data was + * detected or when it's time to send an RTCP compound packet. + */ + virtual void OnPollThreadStep() { } + + /** Is called when the poll thread is started. + * Is called when the poll thread is started. This happens just before entering the + * thread main loop. + * \param stop This can be used to stop the thread immediately without entering the loop. + */ + virtual void OnPollThreadStart(bool &stop) { } + + /** Is called when the poll thread is going to stop. + * Is called when the poll thread is going to stop. This happens just before termitating the thread. + */ + virtual void OnPollThreadStop() { } + +#endif // RTP_SUPPORT_THREAD +private: + int InternalCreate(const RTPSessionParams &sessparams); + int CreateCNAME(uint8_t *buffer,size_t *bufferlength,bool resolve); + int ProcessPolledData(); + int ProcessRTCPCompoundPacket(RTCPCompoundPacket &rtcpcomppack,RTPRawPacket *pack); + RTPRandom *GetRandomNumberGenerator(RTPRandom *r); + + RTPRandom *rtprnd; + bool deletertprnd; + + RTPTransmitter *rtptrans; + bool created; + bool deletetransmitter; + bool usingpollthread; + bool acceptownpackets; + bool useSR_BYEifpossible; + size_t maxpacksize; + double sessionbandwidth; + double controlfragment; + double sendermultiplier; + double byemultiplier; + double membermultiplier; + double collisionmultiplier; + double notemultiplier; + bool sentpackets; + + RTPSessionSources sources; + RTPPacketBuilder packetbuilder; + RTCPScheduler rtcpsched; + RTCPPacketBuilder rtcpbuilder; + RTPCollisionList collisionlist; + + std::list byepackets; + +#ifdef RTP_SUPPORT_THREAD + RTPPollThread *pollthread; + jthread::JMutex sourcesmutex,buildermutex,schedmutex,packsentmutex; + + friend class RTPPollThread; +#endif // RTP_SUPPORT_THREAD + friend class RTPSessionSources; + friend class RTCPSessionPacketBuilder; +}; + +} // end namespace + +#endif // RTPSESSION_H + diff --git a/src/libs/jrtplib/src/rtpsessionparams.cpp b/src/libs/jrtplib/src/rtpsessionparams.cpp new file mode 100644 index 00000000..db6584f6 --- /dev/null +++ b/src/libs/jrtplib/src/rtpsessionparams.cpp @@ -0,0 +1,88 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpconfig.h" +#include "rtpsessionparams.h" +#include "rtpdefines.h" +#include "rtperrors.h" + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTPSessionParams::RTPSessionParams() : mininterval(0,0) +{ +#ifdef RTP_SUPPORT_THREAD + usepollthread = true; +#else + usepollthread = false; +#endif // RTP_SUPPORT_THREAD + maxpacksize = RTP_DEFAULTPACKETSIZE; + receivemode = RTPTransmitter::AcceptAll; + acceptown = false; + owntsunit = -1; // The user will have to set it to the correct value himself + resolvehostname = false; +#ifdef RTP_SUPPORT_PROBATION + probationtype = RTPSources::ProbationStore; +#endif // RTP_SUPPORT_PROBATION + + mininterval = RTPTime(RTCP_DEFAULTMININTERVAL); + sessionbandwidth = RTP_DEFAULTSESSIONBANDWIDTH; + controlfrac = RTCP_DEFAULTBANDWIDTHFRACTION; + senderfrac = RTCP_DEFAULTSENDERFRACTION; + usehalfatstartup = RTCP_DEFAULTHALFATSTARTUP; + immediatebye = RTCP_DEFAULTIMMEDIATEBYE; + SR_BYE = RTCP_DEFAULTSRBYE; + + sendermultiplier = RTP_SENDERTIMEOUTMULTIPLIER; + generaltimeoutmultiplier = RTP_MEMBERTIMEOUTMULTIPLIER; + byetimeoutmultiplier = RTP_BYETIMEOUTMULTIPLIER; + collisionmultiplier = RTP_COLLISIONTIMEOUTMULTIPLIER; + notemultiplier = RTP_NOTETTIMEOUTMULTIPLIER; + + usepredefinedssrc = false; + predefinedssrc = 0; +} + +int RTPSessionParams::SetUsePollThread(bool usethread) +{ +#ifndef RTP_SUPPORT_THREAD + return ERR_RTP_NOTHREADSUPPORT; +#else + usepollthread = usethread; + return 0; +#endif // RTP_SUPPORT_THREAD +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtpsessionparams.h b/src/libs/jrtplib/src/rtpsessionparams.h new file mode 100644 index 00000000..6aa8a715 --- /dev/null +++ b/src/libs/jrtplib/src/rtpsessionparams.h @@ -0,0 +1,248 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpsessionparams.h + */ + +#ifndef RTPSESSIONPARAMS_H + +#define RTPSESSIONPARAMS_H + +#include "rtpconfig.h" +#include "rtptypes.h" +#include "rtptransmitter.h" +#include "rtptimeutilities.h" +#include "rtpsources.h" + +namespace jrtplib +{ + +/** Describes the parameters for to be used by an RTPSession instance. + * Describes the parameters for to be used by an RTPSession instance. Note that the own timestamp + * unit must be set to a valid number, otherwise the session can't be created. + */ +class JRTPLIB_IMPORTEXPORT RTPSessionParams +{ +public: + RTPSessionParams(); + + /** If \c usethread is \c true, the session will use a poll thread to automatically process incoming + * data and to send RTCP packets when necessary. + */ + int SetUsePollThread(bool usethread); + + /** Returns whether the session should use a poll thread or not (default is \c true). */ + bool IsUsingPollThread() const { return usepollthread; } + + /** Sets the maximum allowed packet size for the session. */ + void SetMaximumPacketSize(size_t max) { maxpacksize = max; } + + /** Returns the maximum allowed packet size (default is 1400 bytes). */ + size_t GetMaximumPacketSize() const { return maxpacksize; } + + /** If the argument is \c true, the session should accept its own packets and store + * them accordingly in the source table. + */ + void SetAcceptOwnPackets(bool accept) { acceptown = accept; } + + /** Returns \c true if the session should accept its own packets (default is \c false). */ + bool AcceptOwnPackets() const { return acceptown; } + + /** Sets the receive mode to be used by the session. */ + void SetReceiveMode(RTPTransmitter::ReceiveMode recvmode) { receivemode = recvmode; } + + /** Sets the receive mode to be used by the session (default is: accept all packets). */ + RTPTransmitter::ReceiveMode GetReceiveMode() const { return receivemode; } + + /** Sets the timestamp unit for our own data. + * Sets the timestamp unit for our own data. The timestamp unit is defined as a time interval in + * seconds divided by the corresponding timestamp interval. For example, for 8000 Hz audio, the + * timestamp unit would typically be 1/8000. Since this value is initially set to an illegal value, + * the user must set this to an allowed value to be able to create a session. + */ + void SetOwnTimestampUnit(double tsunit) { owntsunit = tsunit; } + + /** Returns the currently set timestamp unit. */ + double GetOwnTimestampUnit() const { return owntsunit; } + + /** Sets a flag indicating if a DNS lookup should be done to determine our hostname (to construct a CNAME item). + * If \c v is set to \c true, the session will ask the transmitter to find a host name based upon the IP + * addresses in its list of local IP addresses. If set to \c false, a call to \c gethostname or something + * similar will be used to find the local hostname. Note that the first method might take some time. + */ + void SetResolveLocalHostname(bool v) { resolvehostname = v; } + + /** Returns whether the local hostname should be determined from the transmitter's list of local IP addresses + * or not (default is \c false). + */ + bool GetResolveLocalHostname() const { return resolvehostname; } +#ifdef RTP_SUPPORT_PROBATION + /** If probation support is enabled, this function sets the probation type to be used. */ + void SetProbationType(RTPSources::ProbationType probtype) { probationtype = probtype; } + + /** Returns the probation type which will be used (default is RTPSources::ProbationStore). */ + RTPSources::ProbationType GetProbationType() const { return probationtype; } +#endif // RTP_SUPPORT_PROBATION + + /** Sets the session bandwidth in bytes per second. */ + void SetSessionBandwidth(double sessbw) { sessionbandwidth = sessbw; } + + /** Returns the session bandwidth in bytes per second (default is 10000 bytes per second). */ + double GetSessionBandwidth() const { return sessionbandwidth; } + + /** Sets the fraction of the session bandwidth to be used for control traffic. */ + void SetControlTrafficFraction(double frac) { controlfrac = frac; } + + /** Returns the fraction of the session bandwidth that will be used for control traffic (default is 5%). */ + double GetControlTrafficFraction() const { return controlfrac; } + + /** Sets the minimum fraction of the control traffic that will be used by senders. */ + void SetSenderControlBandwidthFraction(double frac) { senderfrac = frac; } + + /** Returns the minimum fraction of the control traffic that will be used by senders (default is 25%). */ + double GetSenderControlBandwidthFraction() const { return senderfrac; } + + /** Set the minimal time interval between sending RTCP packets. */ + void SetMinimumRTCPTransmissionInterval(const RTPTime &t) { mininterval = t; } + + /** Returns the minimal time interval between sending RTCP packets (default is 5 seconds). */ + RTPTime GetMinimumRTCPTransmissionInterval() const { return mininterval; } + + /** If \c usehalf is set to \c true, the session will only wait half of the calculated RTCP + * interval before sending its first RTCP packet. + */ + void SetUseHalfRTCPIntervalAtStartup(bool usehalf) { usehalfatstartup = usehalf; } + + /** Returns whether the session will only wait half of the calculated RTCP interval before sending its + * first RTCP packet or not (default is \c true). + */ + bool GetUseHalfRTCPIntervalAtStartup() const { return usehalfatstartup; } + + /** If \c v is \c true, the session will send a BYE packet immediately if this is allowed. */ + void SetRequestImmediateBYE(bool v) { immediatebye = v; } + + /** Returns whether the session should send a BYE packet immediately (if allowed) or not (default is \c true). */ + bool GetRequestImmediateBYE() const { return immediatebye; } + + /** When sending a BYE packet, this indicates whether it will be part of an RTCP compound packet + * that begins with a sender report (if allowed) or a receiver report. + */ + void SetSenderReportForBYE(bool v) { SR_BYE = v; } + + /** Returns \c true if a BYE packet will be sent in an RTCP compound packet which starts with a + * sender report; if a receiver report will be used, the function returns \c false (default is \c true). + */ + bool GetSenderReportForBYE() const { return SR_BYE; } + + /** Sets the multiplier to be used when timing out senders. */ + void SetSenderTimeoutMultiplier(double m) { sendermultiplier = m; } + + /** Returns the multiplier to be used when timing out senders (default is 2). */ + double GetSenderTimeoutMultiplier() const { return sendermultiplier; } + + /** Sets the multiplier to be used when timing out members. */ + void SetSourceTimeoutMultiplier(double m) { generaltimeoutmultiplier = m; } + + /** Returns the multiplier to be used when timing out members (default is 5). */ + double GetSourceTimeoutMultiplier() const { return generaltimeoutmultiplier; } + + /** Sets the multiplier to be used when timing out a member after it has sent a BYE packet. */ + void SetBYETimeoutMultiplier(double m) { byetimeoutmultiplier = m; } + + /** Returns the multiplier to be used when timing out a member after it has sent a BYE packet (default is 1). */ + double GetBYETimeoutMultiplier() const { return byetimeoutmultiplier; } + + /** Sets the multiplier to be used when timing out entries in the collision table. */ + void SetCollisionTimeoutMultiplier(double m) { collisionmultiplier = m; } + + /** Returns the multiplier to be used when timing out entries in the collision table (default is 10). */ + double GetCollisionTimeoutMultiplier() const { return collisionmultiplier; } + + /** Sets the multiplier to be used when timing out SDES NOTE information. */ + void SetNoteTimeoutMultiplier(double m) { notemultiplier = m; } + + /** Returns the multiplier to be used when timing out SDES NOTE information (default is 25). */ + double GetNoteTimeoutMultiplier() const { return notemultiplier; } + + /** Sets a flag which indicates if a predefined SSRC identifier should be used. */ + void SetUsePredefinedSSRC(bool f) { usepredefinedssrc = f; } + + /** Returns a flag indicating if a predefined SSRC should be used. */ + bool GetUsePredefinedSSRC() const { return usepredefinedssrc; } + + /** Sets the SSRC which will be used if RTPSessionParams::GetUsePredefinedSSRC returns true. */ + void SetPredefinedSSRC(uint32_t ssrc) { predefinedssrc = ssrc; } + + /** Returns the SSRC which will be used if RTPSessionParams::GetUsePredefinedSSRC returns true. */ + uint32_t GetPredefinedSSRC() const { return predefinedssrc; } + + /** Forces this string to be used as the CNAME identifier. */ + void SetCNAME(const std::string &s) { cname = s; } + + /** Returns the currently set CNAME, is blank when this will be generated automatically (the default). */ + std::string GetCNAME() const { return cname; } +private: + bool acceptown; + bool usepollthread; + size_t maxpacksize; + double owntsunit; + RTPTransmitter::ReceiveMode receivemode; + bool resolvehostname; +#ifdef RTP_SUPPORT_PROBATION + RTPSources::ProbationType probationtype; +#endif // RTP_SUPPORT_PROBATION + + double sessionbandwidth; + double controlfrac; + double senderfrac; + RTPTime mininterval; + bool usehalfatstartup; + bool immediatebye; + bool SR_BYE; + + double sendermultiplier; + double generaltimeoutmultiplier; + double byetimeoutmultiplier; + double collisionmultiplier; + double notemultiplier; + + bool usepredefinedssrc; + uint32_t predefinedssrc; + + std::string cname; +}; + +} // end namespace + +#endif // RTPSESSIONPARAMS_H + diff --git a/src/libs/jrtplib/src/rtpsessionsources.cpp b/src/libs/jrtplib/src/rtpsessionsources.cpp new file mode 100644 index 00000000..10f540a0 --- /dev/null +++ b/src/libs/jrtplib/src/rtpsessionsources.cpp @@ -0,0 +1,114 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpsessionsources.h" +#include "rtpsession.h" +#include "rtpsourcedata.h" + +#include "rtpdebug.h" + +namespace jrtplib +{ + +void RTPSessionSources::OnRTPPacket(RTPPacket *pack,const RTPTime &receivetime,const RTPAddress *senderaddress) +{ + rtpsession.OnRTPPacket(pack,receivetime,senderaddress); +} + +void RTPSessionSources::OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime,const RTPAddress *senderaddress) +{ + if (senderaddress != 0) // don't analyse own RTCP packets again (they're already analysed on their way out) + rtpsession.rtcpsched.AnalyseIncoming(*pack); + rtpsession.OnRTCPCompoundPacket(pack,receivetime,senderaddress); +} + +void RTPSessionSources::OnSSRCCollision(RTPSourceData *srcdat,const RTPAddress *senderaddress,bool isrtp) +{ + if (srcdat->IsOwnSSRC()) + owncollision = true; + rtpsession.OnSSRCCollision(srcdat,senderaddress,isrtp); +} + +void RTPSessionSources::OnCNAMECollision(RTPSourceData *srcdat,const RTPAddress *senderaddress,const uint8_t *cname,size_t cnamelength) +{ + rtpsession.OnCNAMECollision(srcdat,senderaddress,cname,cnamelength); +} + +void RTPSessionSources::OnNewSource(RTPSourceData *srcdat) +{ + rtpsession.OnNewSource(srcdat); +} + +void RTPSessionSources::OnRemoveSource(RTPSourceData *srcdat) +{ + rtpsession.OnRemoveSource(srcdat); +} + +void RTPSessionSources::OnTimeout(RTPSourceData *srcdat) +{ + rtpsession.rtcpsched.ActiveMemberDecrease(); + rtpsession.OnTimeout(srcdat); +} + +void RTPSessionSources::OnBYETimeout(RTPSourceData *srcdat) +{ + rtpsession.OnBYETimeout(srcdat); +} + +void RTPSessionSources::OnBYEPacket(RTPSourceData *srcdat) +{ + rtpsession.rtcpsched.ActiveMemberDecrease(); + rtpsession.OnBYEPacket(srcdat); +} + +void RTPSessionSources::OnAPPPacket(RTCPAPPPacket *apppacket,const RTPTime &receivetime,const RTPAddress *senderaddress) +{ + rtpsession.OnAPPPacket(apppacket,receivetime,senderaddress); +} + +void RTPSessionSources::OnUnknownPacketType(RTCPPacket *rtcppack,const RTPTime &receivetime, const RTPAddress *senderaddress) +{ + rtpsession.OnUnknownPacketType(rtcppack,receivetime,senderaddress); +} + +void RTPSessionSources::OnUnknownPacketFormat(RTCPPacket *rtcppack,const RTPTime &receivetime,const RTPAddress *senderaddress) +{ + rtpsession.OnUnknownPacketFormat(rtcppack,receivetime,senderaddress); +} + +void RTPSessionSources::OnNoteTimeout(RTPSourceData *srcdat) +{ + rtpsession.OnNoteTimeout(srcdat); +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtpsessionsources.h b/src/libs/jrtplib/src/rtpsessionsources.h new file mode 100644 index 00000000..2eb931e2 --- /dev/null +++ b/src/libs/jrtplib/src/rtpsessionsources.h @@ -0,0 +1,84 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpsessionsources.h + */ + +#ifndef RTPSESSIONSOURCES_H + +#define RTPSESSIONSOURCES_H + +#include "rtpconfig.h" +#include "rtpsources.h" + +namespace jrtplib +{ + +class RTPSession; + +class JRTPLIB_IMPORTEXPORT RTPSessionSources : public RTPSources +{ +public: + RTPSessionSources(RTPSession &sess,RTPMemoryManager *mgr) : RTPSources(RTPSources::ProbationStore,mgr),rtpsession(sess) + { owncollision = false; } + ~RTPSessionSources() { } + void ClearOwnCollisionFlag() { owncollision = false; } + bool DetectedOwnCollision() const { return owncollision; } +private: + void OnRTPPacket(RTPPacket *pack,const RTPTime &receivetime, + const RTPAddress *senderaddress); + void OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime, + const RTPAddress *senderaddress); + void OnSSRCCollision(RTPSourceData *srcdat,const RTPAddress *senderaddress,bool isrtp); + void OnCNAMECollision(RTPSourceData *srcdat,const RTPAddress *senderaddress, + const uint8_t *cname,size_t cnamelength); + void OnNewSource(RTPSourceData *srcdat); + void OnRemoveSource(RTPSourceData *srcdat); + void OnTimeout(RTPSourceData *srcdat); + void OnBYETimeout(RTPSourceData *srcdat); + void OnBYEPacket(RTPSourceData *srcdat); + void OnAPPPacket(RTCPAPPPacket *apppacket,const RTPTime &receivetime, + const RTPAddress *senderaddress); + void OnUnknownPacketType(RTCPPacket *rtcppack,const RTPTime &receivetime, + const RTPAddress *senderaddress); + void OnUnknownPacketFormat(RTCPPacket *rtcppack,const RTPTime &receivetime, + const RTPAddress *senderaddress); + void OnNoteTimeout(RTPSourceData *srcdat); + + RTPSession &rtpsession; + bool owncollision; +}; + +} // end namespace + +#endif // RTPSESSIONSOURCES_H diff --git a/src/libs/jrtplib/src/rtpsourcedata.cpp b/src/libs/jrtplib/src/rtpsourcedata.cpp new file mode 100644 index 00000000..bdf59f60 --- /dev/null +++ b/src/libs/jrtplib/src/rtpsourcedata.cpp @@ -0,0 +1,500 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpsourcedata.h" +#include "rtpdefines.h" +#include "rtpaddress.h" +#include "rtpmemorymanager.h" +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + #include +#endif // WIN32 + +#ifdef RTPDEBUG + #include + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +#define ACCEPTPACKETCODE \ + *accept = true; \ + \ + sentdata = true; \ + packetsreceived++; \ + numnewpackets++; \ + \ + if (pack->GetExtendedSequenceNumber() == 0) \ + { \ + baseseqnr = 0x0000FFFF; \ + numcycles = 0x00010000; \ + } \ + else \ + baseseqnr = pack->GetExtendedSequenceNumber() - 1; \ + \ + exthighseqnr = baseseqnr + 1; \ + prevpacktime = receivetime; \ + prevexthighseqnr = baseseqnr; \ + savedextseqnr = baseseqnr; \ + \ + pack->SetExtendedSequenceNumber(exthighseqnr); \ + \ + prevtimestamp = pack->GetTimestamp(); \ + lastmsgtime = prevpacktime; \ + if (!ownpacket) /* for own packet, this value is set on an outgoing packet */ \ + lastrtptime = prevpacktime; + +namespace jrtplib +{ + +void RTPSourceStats::ProcessPacket(RTPPacket *pack,const RTPTime &receivetime,double tsunit, + bool ownpacket,bool *accept,bool applyprobation,bool *onprobation) +{ + // Note that the sequence number in the RTP packet is still just the + // 16 bit number contained in the RTP header + + *onprobation = false; + + if (!sentdata) // no valid packets received yet + { +#ifdef RTP_SUPPORT_PROBATION + if (applyprobation) + { + bool acceptpack = false; + + if (probation) + { + uint16_t pseq; + uint32_t pseq2; + + pseq = prevseqnr; + pseq++; + pseq2 = (uint32_t)pseq; + if (pseq2 == pack->GetExtendedSequenceNumber()) // ok, its the next expected packet + { + prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber(); + probation--; + if (probation == 0) // probation over + acceptpack = true; + else + *onprobation = true; + } + else // not next packet + { + probation = RTP_PROBATIONCOUNT; + prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber(); + *onprobation = true; + } + } + else // first packet received with this SSRC ID, start probation + { + probation = RTP_PROBATIONCOUNT; + prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber(); + *onprobation = true; + } + + if (acceptpack) + { + ACCEPTPACKETCODE + } + else + { + *accept = false; + lastmsgtime = receivetime; + } + } + else // No probation + { + ACCEPTPACKETCODE + } +#else // No compiled-in probation support + + ACCEPTPACKETCODE + +#endif // RTP_SUPPORT_PROBATION + } + else // already got packets + { + uint16_t maxseq16; + uint32_t extseqnr; + + // Adjust max extended sequence number and set extende seq nr of packet + + *accept = true; + packetsreceived++; + numnewpackets++; + + maxseq16 = (uint16_t)(exthighseqnr&0x0000FFFF); + if (pack->GetExtendedSequenceNumber() >= maxseq16) + { + extseqnr = numcycles+pack->GetExtendedSequenceNumber(); + exthighseqnr = extseqnr; + } + else + { + uint16_t dif1,dif2; + + dif1 = ((uint16_t)pack->GetExtendedSequenceNumber()); + dif1 -= maxseq16; + dif2 = maxseq16; + dif2 -= ((uint16_t)pack->GetExtendedSequenceNumber()); + if (dif1 < dif2) + { + numcycles += 0x00010000; + extseqnr = numcycles+pack->GetExtendedSequenceNumber(); + exthighseqnr = extseqnr; + } + else + extseqnr = numcycles+pack->GetExtendedSequenceNumber(); + } + + pack->SetExtendedSequenceNumber(extseqnr); + + // Calculate jitter + + if (tsunit > 0) + { +#if 0 + RTPTime curtime = receivetime; + double diffts1,diffts2,diff; + + curtime -= prevpacktime; + diffts1 = curtime.GetDouble()/tsunit; + diffts2 = (double)pack->GetTimestamp() - (double)prevtimestamp; + diff = diffts1 - diffts2; + if (diff < 0) + diff = -diff; + diff -= djitter; + diff /= 16.0; + djitter += diff; + jitter = (uint32_t)djitter; +#else +RTPTime curtime = receivetime; +double diffts1,diffts2,diff; +uint32_t curts = pack->GetTimestamp(); + +curtime -= prevpacktime; +diffts1 = curtime.GetDouble()/tsunit; + +if (curts > prevtimestamp) +{ + uint32_t unsigneddiff = curts - prevtimestamp; + + if (unsigneddiff < 0x10000000) // okay, curts realy is larger than prevtimestamp + diffts2 = (double)unsigneddiff; + else + { + // wraparound occurred and curts is actually smaller than prevtimestamp + + unsigneddiff = -unsigneddiff; // to get the actual difference (in absolute value) + diffts2 = -((double)unsigneddiff); + } +} +else if (curts < prevtimestamp) +{ + uint32_t unsigneddiff = prevtimestamp - curts; + + if (unsigneddiff < 0x10000000) // okay, curts really is smaller than prevtimestamp + diffts2 = -((double)unsigneddiff); // negative since we actually need curts-prevtimestamp + else + { + // wraparound occurred and curts is actually larger than prevtimestamp + + unsigneddiff = -unsigneddiff; // to get the actual difference (in absolute value) + diffts2 = (double)unsigneddiff; + } +} +else + diffts2 = 0; + +diff = diffts1 - diffts2; +if (diff < 0) + diff = -diff; +diff -= djitter; +diff /= 16.0; +djitter += diff; +jitter = (uint32_t)djitter; +#endif + } + else + { + djitter = 0; + jitter = 0; + } + + prevpacktime = receivetime; + prevtimestamp = pack->GetTimestamp(); + lastmsgtime = prevpacktime; + if (!ownpacket) // for own packet, this value is set on an outgoing packet + lastrtptime = prevpacktime; + } +} + +RTPSourceData::RTPSourceData(uint32_t s, RTPMemoryManager *mgr) : RTPMemoryObject(mgr),SDESinf(mgr),byetime(0,0) +{ + ssrc = s; + issender = false; + iscsrc = false; + timestampunit = -1; + receivedbye = false; + byereason = 0; + byereasonlen = 0; + rtpaddr = 0; + rtcpaddr = 0; + ownssrc = false; + validated = false; + processedinrtcp = false; + isrtpaddrset = false; + isrtcpaddrset = false; +} + +RTPSourceData::~RTPSourceData() +{ + FlushPackets(); + if (byereason) + RTPDeleteByteArray(byereason,GetMemoryManager()); + if (rtpaddr) + RTPDelete(rtpaddr,GetMemoryManager()); + if (rtcpaddr) + RTPDelete(rtcpaddr,GetMemoryManager()); +} + +double RTPSourceData::INF_GetEstimatedTimestampUnit() const +{ + if (!SRprevinf.HasInfo()) + return -1.0; + + RTPTime t1 = RTPTime(SRinf.GetNTPTimestamp()); + RTPTime t2 = RTPTime(SRprevinf.GetNTPTimestamp()); + if ((t1.GetSeconds() == 0 && t1.GetMicroSeconds() == 0) || + (t2.GetSeconds() == 0 && t2.GetMicroSeconds() == 0)) // one of the times couldn't be calculated + return -1.0; + + if (t1 <= t2) + return -1.0; + + t1 -= t2; // get the time difference + + uint32_t tsdiff = SRinf.GetRTPTimestamp()-SRprevinf.GetRTPTimestamp(); + + return (t1.GetDouble()/((double)tsdiff)); +} + +RTPTime RTPSourceData::INF_GetRoundtripTime() const +{ + if (!RRinf.HasInfo()) + return RTPTime(0,0); + if (RRinf.GetDelaySinceLastSR() == 0 && RRinf.GetLastSRTimestamp() == 0) + return RTPTime(0,0); + + RTPNTPTime recvtime = RRinf.GetReceiveTime().GetNTPTime(); + uint32_t rtt = ((recvtime.GetMSW()&0xFFFF)<<16)|((recvtime.GetLSW()>>16)&0xFFFF); + rtt -= RRinf.GetLastSRTimestamp(); + rtt -= RRinf.GetDelaySinceLastSR(); + + double drtt = (((double)rtt)/65536.0); + return RTPTime(drtt); +} + +#ifdef RTPDEBUG +void RTPSourceData::Dump() +{ + std::cout << "Source data for SSRC: " << ssrc << std::endl; + std::cout << " Active: " << ((IsActive())?"Yes":"No") << std::endl; + std::cout << " Sender: " << ((issender)?"Yes":"No") << std::endl; + std::cout << " CSRC: " << ((iscsrc)?"Yes":"No") << std::endl; + std::cout << " Received bye: " << ((receivedbye)?"Yes":"No") << std::endl; + std::cout << " ProcessedInRTCP: " << ((processedinrtcp)?"Yes":"No") << std::endl; + std::cout << " Timestamp unit: " << timestampunit << std::endl; + std::cout << " RTP address: "; + if (!isrtpaddrset) + std::cout << "Not set" << std::endl; + else + { + if (rtpaddr == 0) + std::cout << "Own session" << std::endl; + else + std::cout << rtpaddr->GetAddressString() << std::endl; + } + std::cout << " RTCP address: "; + if (!isrtcpaddrset) + std::cout << "Not set" << std::endl; + else + { + if (rtcpaddr == 0) + std::cout << "Own session" << std::endl; + else + std::cout << rtcpaddr->GetAddressString() << std::endl; + } + if (SRinf.HasInfo()) + { + if (!SRprevinf.HasInfo()) + { + std::cout << " SR Info:" << std::endl; + std::cout << " NTP timestamp: " << SRinf.GetNTPTimestamp().GetMSW() << ":" << SRinf.GetNTPTimestamp().GetLSW() << std::endl; + std::cout << " RTP timestamp: " << SRinf.GetRTPTimestamp() << std::endl; + std::cout << " Packet count: " << SRinf.GetPacketCount() << std::endl; + std::cout << " Octet count: " << SRinf.GetByteCount() << std::endl; + std::cout << " Receive time: " << SRinf.GetReceiveTime().GetSeconds() << std::endl; + } + else + { + std::cout << " SR Info:" << std::endl; + std::cout << " NTP timestamp: " << SRinf.GetNTPTimestamp().GetMSW() << ":" << SRinf.GetNTPTimestamp().GetLSW() + << " (" << SRprevinf.GetNTPTimestamp().GetMSW() << ":" << SRprevinf.GetNTPTimestamp().GetLSW() << ")" << std::endl; + std::cout << " RTP timestamp: " << SRinf.GetRTPTimestamp() + << " (" << SRprevinf.GetRTPTimestamp() << ")" << std::endl; + std::cout << " Packet count: " << SRinf.GetPacketCount() + << " (" << SRprevinf.GetPacketCount() << ")" << std::endl; + std::cout << " Octet count: " << SRinf.GetByteCount() + << " (" << SRprevinf.GetByteCount() <<")" << std::endl; + std::cout << " Receive time: " << SRinf.GetReceiveTime().GetSeconds() + << " (" << SRprevinf.GetReceiveTime().GetSeconds() << ")" << std::endl; + } + } + if (RRinf.HasInfo()) + { + if (!RRprevinf.HasInfo()) + { + std::cout << " RR Info:" << std::endl; + std::cout << " Fraction lost: " << RRinf.GetFractionLost() << std::endl; + std::cout << " Packets lost: " << RRinf.GetPacketsLost() << std::endl; + std::cout << " Ext.High.Seq: " << RRinf.GetExtendedHighestSequenceNumber() << std::endl; + std::cout << " Jitter: " << RRinf.GetJitter() << std::endl; + std::cout << " LSR: " << RRinf.GetLastSRTimestamp() << std::endl; + std::cout << " DLSR: " << RRinf.GetDelaySinceLastSR() << std::endl; + std::cout << " Receive time: " << RRinf.GetReceiveTime().GetSeconds() << std::endl; + } + else + { + std::cout << " RR Info:" << std::endl; + std::cout << " Fraction lost: " << RRinf.GetFractionLost() + << " (" << RRprevinf.GetFractionLost() << ")" << std::endl; + std::cout << " Packets lost: " << RRinf.GetPacketsLost() + << " (" << RRprevinf.GetPacketsLost() << ")" << std::endl; + std::cout << " Ext.High.Seq: " << RRinf.GetExtendedHighestSequenceNumber() + << " (" << RRprevinf.GetExtendedHighestSequenceNumber() << ")" << std::endl; + std::cout << " Jitter: " << RRinf.GetJitter() + << " (" << RRprevinf.GetJitter() << ")" << std::endl; + std::cout << " LSR: " << RRinf.GetLastSRTimestamp() + << " (" << RRprevinf.GetLastSRTimestamp() << ")" << std::endl; + std::cout << " DLSR: " << RRinf.GetDelaySinceLastSR() + << " (" << RRprevinf.GetDelaySinceLastSR() << ")" << std::endl; + std::cout << " Receive time: " << RRinf.GetReceiveTime().GetSeconds() + << " (" << RRprevinf.GetReceiveTime().GetSeconds() <<")" << std::endl; + } + } + std::cout << " Stats:" << std::endl; + std::cout << " Sent data: " << ((stats.HasSentData())?"Yes":"No") << std::endl; + std::cout << " Packets received: " << stats.GetNumPacketsReceived() << std::endl; + std::cout << " Seq. base: " << stats.GetBaseSequenceNumber() << std::endl; + std::cout << " Ext.High.Seq: " << stats.GetExtendedHighestSequenceNumber() << std::endl; + std::cout << " Jitter: " << stats.GetJitter() << std::endl; + std::cout << " New packets: " << stats.GetNumPacketsReceivedInInterval() << std::endl; + std::cout << " Saved seq. nr.: " << stats.GetSavedExtendedSequenceNumber() << std::endl; + std::cout << " RTT: " << INF_GetRoundtripTime().GetDouble() << " seconds" << std::endl; + if (INF_GetEstimatedTimestampUnit() > 0) + std::cout << " Estimated: " << (1.0/INF_GetEstimatedTimestampUnit()) << " samples per second" << std::endl; + std::cout << " SDES Info:" << std::endl; + + size_t len; + char str[1024]; + uint8_t *val; + + if ((val = SDESinf.GetCNAME(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " CNAME: " << std::string(str) << std::endl; + } + if ((val = SDESinf.GetName(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " Name: " << std::string(str) << std::endl; + } + if ((val = SDESinf.GetEMail(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " EMail: " << std::string(str) << std::endl; + } + if ((val = SDESinf.GetPhone(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " phone: " << std::string(str) << std::endl; + } + if ((val = SDESinf.GetLocation(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " Location: " << std::string(str) << std::endl; + } + if ((val = SDESinf.GetTool(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " Tool: " << std::string(str) << std::endl; + } + if ((val = SDESinf.GetNote(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " Note: " << std::string(str) << std::endl; + } +#ifdef RTP_SUPPORT_SDESPRIV + SDESinf.GotoFirstPrivateValue(); + uint8_t *pref; + size_t preflen; + while (SDESinf.GetNextPrivateValue(&pref,&preflen,&val,&len)) + { + char prefstr[1024]; + memcpy(prefstr,pref,preflen); + memcpy(str,val,len); + prefstr[preflen] = 0; + str[len] = 0; + std::cout << " Private: " << std::string(prefstr) << ":" << std::string(str) << std::endl; + } +#endif // RTP_SUPPORT_SDESPRIV + if (byereason) + { + memcpy(str,byereason,byereasonlen); + str[byereasonlen] = 0; + std::cout << " BYE Reason: " << std::string(str) << std::endl; + } +} + +#endif // RTPDEBUG + +} // end namespace + + diff --git a/src/libs/jrtplib/src/rtpsourcedata.h b/src/libs/jrtplib/src/rtpsourcedata.h new file mode 100644 index 00000000..b12c5f76 --- /dev/null +++ b/src/libs/jrtplib/src/rtpsourcedata.h @@ -0,0 +1,480 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpsourcedata.h + */ + +#ifndef RTPSOURCEDATA_H + +#define RTPSOURCEDATA_H + +#include "rtpconfig.h" +#include "rtptimeutilities.h" +#include "rtppacket.h" +#include "rtcpsdesinfo.h" +#include "rtptypes.h" +#include "rtpsources.h" +#include "rtpmemoryobject.h" +#include + +namespace jrtplib +{ + +class RTPAddress; + +class JRTPLIB_IMPORTEXPORT RTCPSenderReportInfo +{ +public: + RTCPSenderReportInfo():ntptimestamp(0,0),receivetime(0,0) { hasinfo = false; rtptimestamp = 0; packetcount = 0; bytecount = 0; } + void Set(const RTPNTPTime &ntptime,uint32_t rtptime,uint32_t pcount, + uint32_t bcount,const RTPTime &rcvtime) { ntptimestamp = ntptime; rtptimestamp = rtptime; packetcount = pcount; bytecount = bcount; receivetime = rcvtime; hasinfo = true; } + + bool HasInfo() const { return hasinfo; } + RTPNTPTime GetNTPTimestamp() const { return ntptimestamp; } + uint32_t GetRTPTimestamp() const { return rtptimestamp; } + uint32_t GetPacketCount() const { return packetcount; } + uint32_t GetByteCount() const { return bytecount; } + RTPTime GetReceiveTime() const { return receivetime; } +private: + bool hasinfo; + RTPNTPTime ntptimestamp; + uint32_t rtptimestamp; + uint32_t packetcount; + uint32_t bytecount; + RTPTime receivetime; +}; + +class JRTPLIB_IMPORTEXPORT RTCPReceiverReportInfo +{ +public: + RTCPReceiverReportInfo():receivetime(0,0) { hasinfo = false; fractionlost = 0; packetslost = 0; exthighseqnr = 0; jitter = 0; lsr = 0; dlsr = 0; } + void Set(uint8_t fraclost,int32_t plost,uint32_t exthigh, + uint32_t jit,uint32_t l,uint32_t dl,const RTPTime &rcvtime) { fractionlost = ((double)fraclost)/256.0; packetslost = plost; exthighseqnr = exthigh; jitter = jit; lsr = l; dlsr = dl; receivetime = rcvtime; hasinfo = true; } + + bool HasInfo() const { return hasinfo; } + double GetFractionLost() const { return fractionlost; } + int32_t GetPacketsLost() const { return packetslost; } + uint32_t GetExtendedHighestSequenceNumber() const { return exthighseqnr; } + uint32_t GetJitter() const { return jitter; } + uint32_t GetLastSRTimestamp() const { return lsr; } + uint32_t GetDelaySinceLastSR() const { return dlsr; } + RTPTime GetReceiveTime() const { return receivetime; } +private: + bool hasinfo; + double fractionlost; + int32_t packetslost; + uint32_t exthighseqnr; + uint32_t jitter; + uint32_t lsr; + uint32_t dlsr; + RTPTime receivetime; +}; + +class JRTPLIB_IMPORTEXPORT RTPSourceStats +{ +public: + RTPSourceStats(); + void ProcessPacket(RTPPacket *pack,const RTPTime &receivetime,double tsunit,bool ownpacket,bool *accept,bool applyprobation,bool *onprobation); + + bool HasSentData() const { return sentdata; } + uint32_t GetNumPacketsReceived() const { return packetsreceived; } + uint32_t GetBaseSequenceNumber() const { return baseseqnr; } + uint32_t GetExtendedHighestSequenceNumber() const { return exthighseqnr; } + uint32_t GetJitter() const { return jitter; } + void ResetJitter() { jitter = 0; } + int32_t GetNumPacketsReceivedInInterval() const { return numnewpackets; } + uint32_t GetSavedExtendedSequenceNumber() const { return savedextseqnr; } + void StartNewInterval() { numnewpackets = 0; savedextseqnr = exthighseqnr; } + + void SetLastMessageTime(const RTPTime &t) { lastmsgtime = t; } + RTPTime GetLastMessageTime() const { return lastmsgtime; } + void SetLastRTPPacketTime(const RTPTime &t) { lastrtptime = t; } + RTPTime GetLastRTPPacketTime() const { return lastrtptime; } + + void SetLastNoteTime(const RTPTime &t) { lastnotetime = t; } + RTPTime GetLastNoteTime() const { return lastnotetime; } +private: + bool sentdata; + uint32_t packetsreceived; + uint32_t numcycles; // shifted left 16 bits + uint32_t baseseqnr; + uint32_t exthighseqnr,prevexthighseqnr; + uint32_t jitter,prevtimestamp; + double djitter; + RTPTime prevpacktime; + RTPTime lastmsgtime; + RTPTime lastrtptime; + RTPTime lastnotetime; + uint32_t numnewpackets; + uint32_t savedextseqnr; +#ifdef RTP_SUPPORT_PROBATION + uint16_t prevseqnr; + int probation; + RTPSources::ProbationType probationtype; +#endif // RTP_SUPPORT_PROBATION +}; + +inline RTPSourceStats::RTPSourceStats():prevpacktime(0,0),lastmsgtime(0,0),lastrtptime(0,0),lastnotetime(0,0) +{ + sentdata = false; + packetsreceived = 0; + baseseqnr = 0; + exthighseqnr = 0; + prevexthighseqnr = 0; + jitter = 0; + numcycles = 0; + numnewpackets = 0; + prevtimestamp = 0; + djitter = 0; + savedextseqnr = 0; +#ifdef RTP_SUPPORT_PROBATION + probation = 0; + prevseqnr = 0; +#endif // RTP_SUPPORT_PROBATION +} + +/** Describes an entry in the RTPSources source table. */ +class JRTPLIB_IMPORTEXPORT RTPSourceData : public RTPMemoryObject +{ +protected: + RTPSourceData(uint32_t ssrc, RTPMemoryManager *mgr = 0); + virtual ~RTPSourceData(); +public: + /** Extracts the first packet of this participants RTP packet queue. */ + RTPPacket *GetNextPacket(); + + /** Clears the participant's RTP packet list. */ + void FlushPackets(); + + /** Returns \c true if there are RTP packets which can be extracted. */ + bool HasData() const { if (!validated) return false; return packetlist.empty()?false:true; } + + /** Returns the SSRC identifier for this member. */ + uint32_t GetSSRC() const { return ssrc; } + + /** Returns \c true if the participant was added using the RTPSources member function CreateOwnSSRC and + * returns \c false otherwise. + */ + bool IsOwnSSRC() const { return ownssrc; } + + /** Returns \c true if the source identifier is actually a CSRC from an RTP packet. */ + bool IsCSRC() const { return iscsrc; } + + /** Returns \c true if this member is marked as a sender and \c false if not. */ + bool IsSender() const { return issender; } + + /** Returns \c true if the participant is validated, which is the case if a number of + * consecutive RTP packets have been received or if a CNAME item has been received for + * this participant. + */ + bool IsValidated() const { return validated; } + + /** Returns \c true if the source was validated and had not yet sent a BYE packet. */ + bool IsActive() const { if (!validated) return false; if (receivedbye) return false; return true; } + + /** This function is used by the RTCPPacketBuilder class to mark whether this participant's + * information has been processed in a report block or not. + */ + void SetProcessedInRTCP(bool v) { processedinrtcp = v; } + + /** This function is used by the RTCPPacketBuilder class and returns whether this participant + * has been processed in a report block or not. + */ + bool IsProcessedInRTCP() const { return processedinrtcp; } + + /** Returns \c true if the address from which this participant's RTP packets originate has + * already been set. + */ + bool IsRTPAddressSet() const { return isrtpaddrset; } + + /** Returns \c true if the address from which this participant's RTCP packets originate has + * already been set. + */ + bool IsRTCPAddressSet() const { return isrtcpaddrset; } + + /** Returns the address from which this participant's RTP packets originate. + * Returns the address from which this participant's RTP packets originate. If the address has + * been set and the returned value is NULL, this indicates that it originated from the local + * participant. + */ + const RTPAddress *GetRTPDataAddress() const { return rtpaddr; } + + /** Returns the address from which this participant's RTCP packets originate. + * Returns the address from which this participant's RTCP packets originate. If the address has + * been set and the returned value is NULL, this indicates that it originated from the local + * participant. + */ + const RTPAddress *GetRTCPDataAddress() const { return rtcpaddr; } + + /** Returns \c true if we received a BYE message for this participant and \c false otherwise. */ + bool ReceivedBYE() const { return receivedbye; } + + /** Returns the reason for leaving contained in the BYE packet of this participant. + * Returns the reason for leaving contained in the BYE packet of this participant. The length of + * the reason is stored in \c len. + */ + uint8_t *GetBYEReason(size_t *len) const { *len = byereasonlen; return byereason; } + + /** Returns the time at which the BYE packet was received. */ + RTPTime GetBYETime() const { return byetime; } + + /** Sets the value for the timestamp unit to be used in jitter calculations for data received from this participant. + * Sets the value for the timestamp unit to be used in jitter calculations for data received from this participant. + * If not set, the library uses an approximation for the timestamp unit which is calculated from two consecutive + * RTCP sender reports. The timestamp unit is defined as a time interval divided by the corresponding timestamp + * interval. For 8000 Hz audio this would be 1/8000. For video, often a timestamp unit of 1/90000 is used. + */ + void SetTimestampUnit(double tsu) { timestampunit = tsu; } + + /** Returns the timestamp unit used for this participant. */ + double GetTimestampUnit() const { return timestampunit; } + + /** Returns \c true if an RTCP sender report has been received from this participant. */ + bool SR_HasInfo() const { return SRinf.HasInfo(); } + + /** Returns the NTP timestamp contained in the last sender report. */ + RTPNTPTime SR_GetNTPTimestamp() const { return SRinf.GetNTPTimestamp(); } + + /** Returns the RTP timestamp contained in the last sender report. */ + uint32_t SR_GetRTPTimestamp() const { return SRinf.GetRTPTimestamp(); } + + /** Returns the packet count contained in the last sender report. */ + uint32_t SR_GetPacketCount() const { return SRinf.GetPacketCount(); } + + /** Returns the octet count contained in the last sender report. */ + uint32_t SR_GetByteCount() const { return SRinf.GetByteCount(); } + + /** Returns the time at which the last sender report was received. */ + RTPTime SR_GetReceiveTime() const { return SRinf.GetReceiveTime(); } + + /** Returns \c true if more than one RTCP sender report has been received. */ + bool SR_Prev_HasInfo() const { return SRprevinf.HasInfo(); } + + /** Returns the NTP timestamp contained in the second to last sender report. */ + RTPNTPTime SR_Prev_GetNTPTimestamp() const { return SRprevinf.GetNTPTimestamp(); } + + /** Returns the RTP timestamp contained in the second to last sender report. */ + uint32_t SR_Prev_GetRTPTimestamp() const { return SRprevinf.GetRTPTimestamp(); } + + /** Returns the packet count contained in the second to last sender report. */ + uint32_t SR_Prev_GetPacketCount() const { return SRprevinf.GetPacketCount(); } + + /** Returns the octet count contained in the second to last sender report. */ + uint32_t SR_Prev_GetByteCount() const { return SRprevinf.GetByteCount(); } + + /** Returns the time at which the second to last sender report was received. */ + RTPTime SR_Prev_GetReceiveTime() const { return SRprevinf.GetReceiveTime(); } + + /** Returns \c true if this participant sent a receiver report with information about the reception of our data. */ + bool RR_HasInfo() const { return RRinf.HasInfo(); } + + /** Returns the fraction lost value from the last report. */ + double RR_GetFractionLost() const { return RRinf.GetFractionLost(); } + + /** Returns the number of lost packets contained in the last report. */ + int32_t RR_GetPacketsLost() const { return RRinf.GetPacketsLost(); } + + /** Returns the extended highest sequence number contained in the last report. */ + uint32_t RR_GetExtendedHighestSequenceNumber() const { return RRinf.GetExtendedHighestSequenceNumber(); } + + /** Returns the jitter value from the last report. */ + uint32_t RR_GetJitter() const { return RRinf.GetJitter(); } + + /** Returns the LSR value from the last report. */ + uint32_t RR_GetLastSRTimestamp() const { return RRinf.GetLastSRTimestamp(); } + + /** Returns the DLSR value from the last report. */ + uint32_t RR_GetDelaySinceLastSR() const { return RRinf.GetDelaySinceLastSR(); } + + /** Returns the time at which the last report was received. */ + RTPTime RR_GetReceiveTime() const { return RRinf.GetReceiveTime(); } + + /** Returns \c true if this participant sent more than one receiver report with information + * about the reception of our data. + */ + bool RR_Prev_HasInfo() const { return RRprevinf.HasInfo(); } + + /** Returns the fraction lost value from the second to last report. */ + double RR_Prev_GetFractionLost() const { return RRprevinf.GetFractionLost(); } + + /** Returns the number of lost packets contained in the second to last report. */ + int32_t RR_Prev_GetPacketsLost() const { return RRprevinf.GetPacketsLost(); } + + /** Returns the extended highest sequence number contained in the second to last report. */ + uint32_t RR_Prev_GetExtendedHighestSequenceNumber() const { return RRprevinf.GetExtendedHighestSequenceNumber(); } + + /** Returns the jitter value from the second to last report. */ + uint32_t RR_Prev_GetJitter() const { return RRprevinf.GetJitter(); } + + /** Returns the LSR value from the second to last report. */ + uint32_t RR_Prev_GetLastSRTimestamp() const { return RRprevinf.GetLastSRTimestamp(); } + + /** Returns the DLSR value from the second to last report. */ + uint32_t RR_Prev_GetDelaySinceLastSR() const { return RRprevinf.GetDelaySinceLastSR(); } + + /** Returns the time at which the second to last report was received. */ + RTPTime RR_Prev_GetReceiveTime() const { return RRprevinf.GetReceiveTime(); } + + /** Returns \c true if validated RTP packets have been received from this participant. */ + bool INF_HasSentData() const { return stats.HasSentData(); } + + /** Returns the total number of received packets from this participant. */ + int32_t INF_GetNumPacketsReceived() const { return stats.GetNumPacketsReceived(); } + + /** Returns the base sequence number of this participant. */ + uint32_t INF_GetBaseSequenceNumber() const { return stats.GetBaseSequenceNumber(); } + + /** Returns the extended highest sequence number received from this participant. */ + uint32_t INF_GetExtendedHighestSequenceNumber() const { return stats.GetExtendedHighestSequenceNumber(); } + + /** Returns the current jitter value for this participant. */ + uint32_t INF_GetJitter() const { return stats.GetJitter(); } + + /** Returns the time at which something was last heard from this member. */ + RTPTime INF_GetLastMessageTime() const { return stats.GetLastMessageTime(); } + + /** Returns the time at which the last RTP packet was received. */ + RTPTime INF_GetLastRTPPacketTime() const { return stats.GetLastRTPPacketTime(); } + + /** Returns the estimated timestamp unit, calculated from two consecutive sender reports. */ + double INF_GetEstimatedTimestampUnit() const; + + /** Returns the number of packets received since a new interval was started with INF_StartNewInterval. */ + uint32_t INF_GetNumPacketsReceivedInInterval() const { return stats.GetNumPacketsReceivedInInterval(); } + + /** Returns the extended sequence number which was stored by the INF_StartNewInterval call. */ + uint32_t INF_GetSavedExtendedSequenceNumber() const { return stats.GetSavedExtendedSequenceNumber(); } + + /** Starts a new interval to count received packets in; this also stores the current extended highest sequence + * number to be able to calculate the packet loss during the interval. + */ + void INF_StartNewInterval() { stats.StartNewInterval(); } + + /** Estimates the round trip time by using the LSR and DLSR info from the last receiver report. */ + RTPTime INF_GetRoundtripTime() const; + + /** Returns the time at which the last SDES NOTE item was received. */ + RTPTime INF_GetLastSDESNoteTime() const { return stats.GetLastNoteTime(); } + + /** Returns a pointer to the SDES CNAME item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetCNAME(size_t *len) const { return SDESinf.GetCNAME(len); } + + /** Returns a pointer to the SDES name item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetName(size_t *len) const { return SDESinf.GetName(len); } + + /** Returns a pointer to the SDES e-mail item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetEMail(size_t *len) const { return SDESinf.GetEMail(len); } + + /** Returns a pointer to the SDES phone item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetPhone(size_t *len) const { return SDESinf.GetPhone(len); } + + /** Returns a pointer to the SDES location item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetLocation(size_t *len) const { return SDESinf.GetLocation(len); } + + /** Returns a pointer to the SDES tool item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetTool(size_t *len) const { return SDESinf.GetTool(len); } + + /** Returns a pointer to the SDES note item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetNote(size_t *len) const { return SDESinf.GetNote(len); } + +#ifdef RTP_SUPPORT_SDESPRIV + /** Starts the iteration over the stored SDES private item prefixes and their associated values. */ + void SDES_GotoFirstPrivateValue() { SDESinf.GotoFirstPrivateValue(); } + + /** If available, returns \c true and stores the next SDES private item prefix in \c prefix and its length in + * \c prefixlen; the associated value and its length are then stored in \c value and \c valuelen. + */ + bool SDES_GetNextPrivateValue(uint8_t **prefix,size_t *prefixlen,uint8_t **value,size_t *valuelen) { return SDESinf.GetNextPrivateValue(prefix,prefixlen,value,valuelen); } + + /** Looks for the entry which corresponds to the SDES private item prefix \c prefix with length + * \c prefixlen; if found, the function returns \c true and stores the associated value and + * its length in \c value and \c valuelen respectively. + */ + bool SDES_GetPrivateValue(uint8_t *prefix,size_t prefixlen,uint8_t **value,size_t *valuelen) const { return SDESinf.GetPrivateValue(prefix,prefixlen,value,valuelen); } +#endif // RTP_SUPPORT_SDESPRIV + +#ifdef RTPDEBUG + virtual void Dump(); +#endif // RTPDEBUG +protected: + std::list packetlist; + + uint32_t ssrc; + bool ownssrc; + bool iscsrc; + double timestampunit; + bool receivedbye; + bool validated; + bool processedinrtcp; + bool issender; + + RTCPSenderReportInfo SRinf,SRprevinf; + RTCPReceiverReportInfo RRinf,RRprevinf; + RTPSourceStats stats; + RTCPSDESInfo SDESinf; + + bool isrtpaddrset,isrtcpaddrset; + RTPAddress *rtpaddr,*rtcpaddr; + + RTPTime byetime; + uint8_t *byereason; + size_t byereasonlen; +}; + +inline RTPPacket *RTPSourceData::GetNextPacket() +{ + if (!validated) + return 0; + + RTPPacket *p; + + if (packetlist.empty()) + return 0; + p = *(packetlist.begin()); + packetlist.pop_front(); + return p; +} + +inline void RTPSourceData::FlushPackets() +{ + std::list::const_iterator it; + + for (it = packetlist.begin() ; it != packetlist.end() ; ++it) + RTPDelete(*it,GetMemoryManager()); + packetlist.clear(); +} + +} // end namespace + +#endif // RTPSOURCEDATA_H + diff --git a/src/libs/jrtplib/src/rtpsources.cpp b/src/libs/jrtplib/src/rtpsources.cpp new file mode 100644 index 00000000..d8e7bbd7 --- /dev/null +++ b/src/libs/jrtplib/src/rtpsources.cpp @@ -0,0 +1,1418 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpsources.h" +#include "rtperrors.h" +#include "rtprawpacket.h" +#include "rtpinternalsourcedata.h" +#include "rtptimeutilities.h" +#include "rtpdefines.h" +#include "rtcpcompoundpacket.h" +#include "rtcppacket.h" +#include "rtcpapppacket.h" +#include "rtcpbyepacket.h" +#include "rtcpsdespacket.h" +#include "rtcpsrpacket.h" +#include "rtcprrpacket.h" +#include "rtptransmitter.h" + +#ifdef RTPDEBUG + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +namespace jrtplib +{ + +RTPSources::RTPSources(ProbationType probtype,RTPMemoryManager *mgr) : RTPMemoryObject(mgr),sourcelist(mgr,RTPMEM_TYPE_CLASS_SOURCETABLEHASHELEMENT) +{ + totalcount = 0; + sendercount = 0; + activecount = 0; + owndata = 0; +#ifdef RTP_SUPPORT_PROBATION + probationtype = probtype; +#endif // RTP_SUPPORT_PROBATION +} + +RTPSources::~RTPSources() +{ + Clear(); +} + +void RTPSources::Clear() +{ + ClearSourceList(); +} + +void RTPSources::ClearSourceList() +{ + sourcelist.GotoFirstElement(); + while (sourcelist.HasCurrentElement()) + { + RTPInternalSourceData *sourcedata; + + sourcedata = sourcelist.GetCurrentElement(); + RTPDelete(sourcedata,GetMemoryManager()); + sourcelist.GotoNextElement(); + } + sourcelist.Clear(); + owndata = 0; + totalcount = 0; + sendercount = 0; + activecount = 0; +} + +int RTPSources::CreateOwnSSRC(uint32_t ssrc) +{ + if (owndata != 0) + return ERR_RTP_SOURCES_ALREADYHAVEOWNSSRC; + if (GotEntry(ssrc)) + return ERR_RTP_SOURCES_SSRCEXISTS; + + int status; + bool created; + + status = ObtainSourceDataInstance(ssrc,&owndata,&created); + if (status < 0) + { + owndata = 0; // just to make sure + return status; + } + owndata->SetOwnSSRC(); + owndata->SetRTPDataAddress(0); + owndata->SetRTCPDataAddress(0); + + // we've created a validated ssrc, so we should increase activecount + activecount++; + + OnNewSource(owndata); + return 0; +} + +int RTPSources::DeleteOwnSSRC() +{ + if (owndata == 0) + return ERR_RTP_SOURCES_DONTHAVEOWNSSRC; + + uint32_t ssrc = owndata->GetSSRC(); + + sourcelist.GotoElement(ssrc); + sourcelist.DeleteCurrentElement(); + + totalcount--; + if (owndata->IsSender()) + sendercount--; + if (owndata->IsActive()) + activecount--; + + OnRemoveSource(owndata); + + RTPDelete(owndata,GetMemoryManager()); + owndata = 0; + return 0; +} + +void RTPSources::SentRTPPacket() +{ + if (owndata == 0) + return; + + bool prevsender = owndata->IsSender(); + + owndata->SentRTPPacket(); + if (!prevsender && owndata->IsSender()) + sendercount++; +} + +int RTPSources::ProcessRawPacket(RTPRawPacket *rawpack,RTPTransmitter *rtptrans,bool acceptownpackets) +{ + RTPTransmitter *transmitters[1]; + int num; + + transmitters[0] = rtptrans; + if (rtptrans == 0) + num = 0; + else + num = 1; + return ProcessRawPacket(rawpack,transmitters,num,acceptownpackets); +} + +int RTPSources::ProcessRawPacket(RTPRawPacket *rawpack,RTPTransmitter *rtptrans[],int numtrans,bool acceptownpackets) +{ + int status; + + if (rawpack->IsRTP()) // RTP packet + { + RTPPacket *rtppack; + + // First, we'll see if the packet can be parsed + rtppack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPPACKET) RTPPacket(*rawpack,GetMemoryManager()); + if (rtppack == 0) + return ERR_RTP_OUTOFMEM; + if ((status = rtppack->GetCreationError()) < 0) + { + if (status == ERR_RTP_PACKET_INVALIDPACKET) + { + RTPDelete(rtppack,GetMemoryManager()); + rtppack = 0; + } + else + { + RTPDelete(rtppack,GetMemoryManager()); + return status; + } + } + + // Check if the packet was valid + if (rtppack != 0) + { + bool stored = false; + bool ownpacket = false; + int i; + const RTPAddress *senderaddress = rawpack->GetSenderAddress(); + + for (i = 0 ; !ownpacket && i < numtrans ; i++) + { + if (rtptrans[i]->ComesFromThisTransmitter(senderaddress)) + ownpacket = true; + } + + // Check if the packet is our own. + if (ownpacket) + { + // Now it depends on the user's preference + // what to do with this packet: + if (acceptownpackets) + { + // sender addres for own packets has to be NULL! + if ((status = ProcessRTPPacket(rtppack,rawpack->GetReceiveTime(),0,&stored)) < 0) + { + if (!stored) + RTPDelete(rtppack,GetMemoryManager()); + return status; + } + } + } + else + { + if ((status = ProcessRTPPacket(rtppack,rawpack->GetReceiveTime(),senderaddress,&stored)) < 0) + { + if (!stored) + RTPDelete(rtppack,GetMemoryManager()); + return status; + } + } + if (!stored) + RTPDelete(rtppack,GetMemoryManager()); + } + } + else // RTCP packet + { + RTCPCompoundPacket rtcpcomppack(*rawpack,GetMemoryManager()); + bool valid = false; + + if ((status = rtcpcomppack.GetCreationError()) < 0) + { + if (status != ERR_RTP_RTCPCOMPOUND_INVALIDPACKET) + return status; + } + else + valid = true; + + + if (valid) + { + bool ownpacket = false; + int i; + const RTPAddress *senderaddress = rawpack->GetSenderAddress(); + + for (i = 0 ; !ownpacket && i < numtrans ; i++) + { + if (rtptrans[i]->ComesFromThisTransmitter(senderaddress)) + ownpacket = true; + } + + // First check if it's a packet of this session. + if (ownpacket) + { + if (acceptownpackets) + { + // sender address for own packets has to be NULL + status = ProcessRTCPCompoundPacket(&rtcpcomppack,rawpack->GetReceiveTime(),0); + if (status < 0) + return status; + } + } + else // not our own packet + { + status = ProcessRTCPCompoundPacket(&rtcpcomppack,rawpack->GetReceiveTime(),rawpack->GetSenderAddress()); + if (status < 0) + return status; + } + } + } + + return 0; +} + +int RTPSources::ProcessRTPPacket(RTPPacket *rtppack,const RTPTime &receivetime,const RTPAddress *senderaddress,bool *stored) +{ + uint32_t ssrc; + RTPInternalSourceData *srcdat; + int status; + bool created; + + OnRTPPacket(rtppack,receivetime,senderaddress); + + *stored = false; + + ssrc = rtppack->GetSSRC(); + if ((status = ObtainSourceDataInstance(ssrc,&srcdat,&created)) < 0) + return status; + + if (created) + { + if ((status = srcdat->SetRTPDataAddress(senderaddress)) < 0) + return status; + } + else // got a previously existing source + { + //if (CheckCollision(srcdat,senderaddress,true)) + // return 0; // ignore packet on collision + } + + bool prevsender = srcdat->IsSender(); + bool prevactive = srcdat->IsActive(); + + // The packet comes from a valid source, we can process it further now + // The following function should delete rtppack itself if something goes + // wrong + if ((status = srcdat->ProcessRTPPacket(rtppack,receivetime,stored)) < 0) + return status; + + if (!prevsender && srcdat->IsSender()) + sendercount++; + if (!prevactive && srcdat->IsActive()) + activecount++; + + if (created) + OnNewSource(srcdat); + + if (srcdat->IsValidated()) // process the CSRCs + { + RTPInternalSourceData *csrcdat; + bool createdcsrc; + + int num = rtppack->GetCSRCCount(); + int i; + + for (i = 0 ; i < num ; i++) + { + if ((status = ObtainSourceDataInstance(rtppack->GetCSRC(i),&csrcdat,&createdcsrc)) < 0) + return status; + if (createdcsrc) + { + csrcdat->SetCSRC(); + if (csrcdat->IsActive()) + activecount++; + OnNewSource(csrcdat); + } + else // already found an entry, possibly because of RTCP data + { + if (!CheckCollision(csrcdat,senderaddress,true)) + csrcdat->SetCSRC(); + } + } + } + + return 0; +} + +int RTPSources::ProcessRTCPCompoundPacket(RTCPCompoundPacket *rtcpcomppack,const RTPTime &receivetime,const RTPAddress *senderaddress) +{ + RTCPPacket *rtcppack; + int status; + bool gotownssrc = ((owndata == 0)?false:true); + uint32_t ownssrc = ((owndata != 0)?owndata->GetSSRC():0); + + OnRTCPCompoundPacket(rtcpcomppack,receivetime,senderaddress); + + rtcpcomppack->GotoFirstPacket(); + while ((rtcppack = rtcpcomppack->GetNextPacket()) != 0) + { + if (rtcppack->IsKnownFormat()) + { + switch (rtcppack->GetPacketType()) + { + case RTCPPacket::SR: + { + RTCPSRPacket *p = (RTCPSRPacket *)rtcppack; + uint32_t senderssrc = p->GetSenderSSRC(); + + status = ProcessRTCPSenderInfo(senderssrc,p->GetNTPTimestamp(),p->GetRTPTimestamp(), + p->GetSenderPacketCount(),p->GetSenderOctetCount(), + receivetime,senderaddress); + if (status < 0) + return status; + + bool gotinfo = false; + if (gotownssrc) + { + int i; + int num = p->GetReceptionReportCount(); + for (i = 0 ; i < num ; i++) + { + if (p->GetSSRC(i) == ownssrc) // data is meant for us + { + gotinfo = true; + status = ProcessRTCPReportBlock(senderssrc,p->GetFractionLost(i),p->GetLostPacketCount(i), + p->GetExtendedHighestSequenceNumber(i),p->GetJitter(i),p->GetLSR(i), + p->GetDLSR(i),receivetime,senderaddress); + if (status < 0) + return status; + } + } + } + if (!gotinfo) + { + status = UpdateReceiveTime(senderssrc,receivetime,senderaddress); + if (status < 0) + return status; + } + } + break; + case RTCPPacket::RR: + { + RTCPRRPacket *p = (RTCPRRPacket *)rtcppack; + uint32_t senderssrc = p->GetSenderSSRC(); + + bool gotinfo = false; + + if (gotownssrc) + { + int i; + int num = p->GetReceptionReportCount(); + for (i = 0 ; i < num ; i++) + { + if (p->GetSSRC(i) == ownssrc) + { + gotinfo = true; + status = ProcessRTCPReportBlock(senderssrc,p->GetFractionLost(i),p->GetLostPacketCount(i), + p->GetExtendedHighestSequenceNumber(i),p->GetJitter(i),p->GetLSR(i), + p->GetDLSR(i),receivetime,senderaddress); + if (status < 0) + return status; + } + } + } + if (!gotinfo) + { + status = UpdateReceiveTime(senderssrc,receivetime,senderaddress); + if (status < 0) + return status; + } + } + break; + case RTCPPacket::SDES: + { + RTCPSDESPacket *p = (RTCPSDESPacket *)rtcppack; + + if (p->GotoFirstChunk()) + { + do + { + uint32_t sdesssrc = p->GetChunkSSRC(); + bool updated = false; + if (p->GotoFirstItem()) + { + do + { + RTCPSDESPacket::ItemType t; + + if ((t = p->GetItemType()) != RTCPSDESPacket::PRIV) + { + updated = true; + status = ProcessSDESNormalItem(sdesssrc,t,p->GetItemLength(),p->GetItemData(),receivetime,senderaddress); + if (status < 0) + return status; + } +#ifdef RTP_SUPPORT_SDESPRIV + else + { + updated = true; + status = ProcessSDESPrivateItem(sdesssrc,p->GetPRIVPrefixLength(),p->GetPRIVPrefixData(),p->GetPRIVValueLength(), + p->GetPRIVValueData(),receivetime,senderaddress); + if (status < 0) + return status; + } +#endif // RTP_SUPPORT_SDESPRIV + } while (p->GotoNextItem()); + } + if (!updated) + { + status = UpdateReceiveTime(sdesssrc,receivetime,senderaddress); + if (status < 0) + return status; + } + } while (p->GotoNextChunk()); + } + } + break; + case RTCPPacket::BYE: + { + RTCPBYEPacket *p = (RTCPBYEPacket *)rtcppack; + int i; + int num = p->GetSSRCCount(); + + for (i = 0 ; i < num ; i++) + { + uint32_t byessrc = p->GetSSRC(i); + status = ProcessBYE(byessrc,p->GetReasonLength(),p->GetReasonData(),receivetime,senderaddress); + if (status < 0) + return status; + } + } + break; + case RTCPPacket::APP: + { + RTCPAPPPacket *p = (RTCPAPPPacket *)rtcppack; + + OnAPPPacket(p,receivetime,senderaddress); + } + break; + case RTCPPacket::Unknown: + default: + { + OnUnknownPacketType(rtcppack,receivetime,senderaddress); + } + break; + } + } + else + { + OnUnknownPacketFormat(rtcppack,receivetime,senderaddress); + } + } + + return 0; +} + +bool RTPSources::GotoFirstSource() +{ + sourcelist.GotoFirstElement(); + if (sourcelist.HasCurrentElement()) + return true; + return false; +} + +bool RTPSources::GotoNextSource() +{ + sourcelist.GotoNextElement(); + if (sourcelist.HasCurrentElement()) + return true; + return false; +} + +bool RTPSources::GotoPreviousSource() +{ + sourcelist.GotoPreviousElement(); + if (sourcelist.HasCurrentElement()) + return true; + return false; +} + +bool RTPSources::GotoFirstSourceWithData() +{ + bool found = false; + + sourcelist.GotoFirstElement(); + while (!found && sourcelist.HasCurrentElement()) + { + RTPInternalSourceData *srcdat; + + srcdat = sourcelist.GetCurrentElement(); + if (srcdat->HasData()) + found = true; + else + sourcelist.GotoNextElement(); + } + + return found; +} + +bool RTPSources::GotoNextSourceWithData() +{ + bool found = false; + + sourcelist.GotoNextElement(); + while (!found && sourcelist.HasCurrentElement()) + { + RTPInternalSourceData *srcdat; + + srcdat = sourcelist.GetCurrentElement(); + if (srcdat->HasData()) + found = true; + else + sourcelist.GotoNextElement(); + } + + return found; +} + +bool RTPSources::GotoPreviousSourceWithData() +{ + bool found = false; + + sourcelist.GotoPreviousElement(); + while (!found && sourcelist.HasCurrentElement()) + { + RTPInternalSourceData *srcdat; + + srcdat = sourcelist.GetCurrentElement(); + if (srcdat->HasData()) + found = true; + else + sourcelist.GotoPreviousElement(); + } + + return found; +} + +RTPSourceData *RTPSources::GetCurrentSourceInfo() +{ + if (!sourcelist.HasCurrentElement()) + return 0; + return sourcelist.GetCurrentElement(); +} + +RTPSourceData *RTPSources::GetSourceInfo(uint32_t ssrc) +{ + if (sourcelist.GotoElement(ssrc) < 0) + return 0; + if (!sourcelist.HasCurrentElement()) + return 0; + return sourcelist.GetCurrentElement(); +} + +bool RTPSources::GotEntry(uint32_t ssrc) +{ + return sourcelist.HasElement(ssrc); +} + +RTPPacket *RTPSources::GetNextPacket() +{ + if (!sourcelist.HasCurrentElement()) + return 0; + + RTPInternalSourceData *srcdat = sourcelist.GetCurrentElement(); + RTPPacket *pack = srcdat->GetNextPacket(); + return pack; +} + +int RTPSources::ProcessRTCPSenderInfo(uint32_t ssrc,const RTPNTPTime &ntptime,uint32_t rtptime, + uint32_t packetcount,uint32_t octetcount,const RTPTime &receivetime, + const RTPAddress *senderaddress) +{ + RTPInternalSourceData *srcdat; + bool created; + int status; + + status = GetRTCPSourceData(ssrc,senderaddress,&srcdat,&created); + if (status < 0) + return status; + if (srcdat == 0) + return 0; + + srcdat->ProcessSenderInfo(ntptime,rtptime,packetcount,octetcount,receivetime); + + // Call the callback + if (created) + OnNewSource(srcdat); + + return 0; +} + +int RTPSources::ProcessRTCPReportBlock(uint32_t ssrc,uint8_t fractionlost,int32_t lostpackets, + uint32_t exthighseqnr,uint32_t jitter,uint32_t lsr, + uint32_t dlsr,const RTPTime &receivetime,const RTPAddress *senderaddress) +{ + RTPInternalSourceData *srcdat; + bool created; + int status; + + status = GetRTCPSourceData(ssrc,senderaddress,&srcdat,&created); + if (status < 0) + return status; + if (srcdat == 0) + return 0; + + srcdat->ProcessReportBlock(fractionlost,lostpackets,exthighseqnr,jitter,lsr,dlsr,receivetime); + + // Call the callback + if (created) + OnNewSource(srcdat); + + return 0; +} + +int RTPSources::ProcessSDESNormalItem(uint32_t ssrc,RTCPSDESPacket::ItemType t,size_t itemlength, + const void *itemdata,const RTPTime &receivetime,const RTPAddress *senderaddress) +{ + RTPInternalSourceData *srcdat; + bool created,cnamecollis; + int status; + uint8_t sdesid; + bool prevactive; + + switch(t) + { + case RTCPSDESPacket::CNAME: + sdesid = RTCP_SDES_ID_CNAME; + break; + case RTCPSDESPacket::NAME: + sdesid = RTCP_SDES_ID_NAME; + break; + case RTCPSDESPacket::EMAIL: + sdesid = RTCP_SDES_ID_EMAIL; + break; + case RTCPSDESPacket::PHONE: + sdesid = RTCP_SDES_ID_PHONE; + break; + case RTCPSDESPacket::LOC: + sdesid = RTCP_SDES_ID_LOCATION; + break; + case RTCPSDESPacket::TOOL: + sdesid = RTCP_SDES_ID_TOOL; + break; + case RTCPSDESPacket::NOTE: + sdesid = RTCP_SDES_ID_NOTE; + break; + default: + return ERR_RTP_SOURCES_ILLEGALSDESTYPE; + } + + status = GetRTCPSourceData(ssrc,senderaddress,&srcdat,&created); + if (status < 0) + return status; + if (srcdat == 0) + return 0; + + prevactive = srcdat->IsActive(); + status = srcdat->ProcessSDESItem(sdesid,(const uint8_t *)itemdata,itemlength,receivetime,&cnamecollis); + if (!prevactive && srcdat->IsActive()) + activecount++; + + // Call the callback + if (created) + OnNewSource(srcdat); + if (cnamecollis) + OnCNAMECollision(srcdat,senderaddress,(const uint8_t *)itemdata,itemlength); + + return status; +} + +#ifdef RTP_SUPPORT_SDESPRIV +int RTPSources::ProcessSDESPrivateItem(uint32_t ssrc,size_t prefixlen,const void *prefixdata, + size_t valuelen,const void *valuedata,const RTPTime &receivetime, + const RTPAddress *senderaddress) +{ + RTPInternalSourceData *srcdat; + bool created; + int status; + + status = GetRTCPSourceData(ssrc,senderaddress,&srcdat,&created); + if (status < 0) + return status; + if (srcdat == 0) + return 0; + + status = srcdat->ProcessPrivateSDESItem((const uint8_t *)prefixdata,prefixlen,(const uint8_t *)valuedata,valuelen,receivetime); + // Call the callback + if (created) + OnNewSource(srcdat); + return status; +} +#endif //RTP_SUPPORT_SDESPRIV + +int RTPSources::ProcessBYE(uint32_t ssrc,size_t reasonlength,const void *reasondata, + const RTPTime &receivetime,const RTPAddress *senderaddress) +{ + RTPInternalSourceData *srcdat; + bool created; + int status; + bool prevactive; + + status = GetRTCPSourceData(ssrc,senderaddress,&srcdat,&created); + if (status < 0) + return status; + if (srcdat == 0) + return 0; + + // we'll ignore BYE packets for our own ssrc + if (srcdat == owndata) + return 0; + + prevactive = srcdat->IsActive(); + srcdat->ProcessBYEPacket((const uint8_t *)reasondata,reasonlength,receivetime); + if (prevactive && !srcdat->IsActive()) + activecount--; + + // Call the callback + if (created) + OnNewSource(srcdat); + OnBYEPacket(srcdat); + return 0; +} + +int RTPSources::ObtainSourceDataInstance(uint32_t ssrc,RTPInternalSourceData **srcdat,bool *created) +{ + RTPInternalSourceData *srcdat2; + int status; + + if (sourcelist.GotoElement(ssrc) < 0) // No entry for this source + { +#ifdef RTP_SUPPORT_PROBATION + srcdat2 = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPINTERNALSOURCEDATA) RTPInternalSourceData(ssrc,probationtype,GetMemoryManager()); +#else + srcdat2 = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPINTERNALSOURCEDATA) RTPInternalSourceData(ssrc,RTPSources::NoProbation,GetMemoryManager()); +#endif // RTP_SUPPORT_PROBATION + if (srcdat2 == 0) + return ERR_RTP_OUTOFMEM; + if ((status = sourcelist.AddElement(ssrc,srcdat2)) < 0) + { + RTPDelete(srcdat2,GetMemoryManager()); + return status; + } + *srcdat = srcdat2; + *created = true; + totalcount++; + } + else + { + *srcdat = sourcelist.GetCurrentElement(); + *created = false; + } + return 0; +} + + +int RTPSources::GetRTCPSourceData(uint32_t ssrc,const RTPAddress *senderaddress, + RTPInternalSourceData **srcdat2,bool *newsource) +{ + int status; + bool created; + RTPInternalSourceData *srcdat; + + *srcdat2 = 0; + + if ((status = ObtainSourceDataInstance(ssrc,&srcdat,&created)) < 0) + return status; + + if (created) + { + if ((status = srcdat->SetRTCPDataAddress(senderaddress)) < 0) + return status; + } + else // got a previously existing source + { + //if (CheckCollision(srcdat,senderaddress,false)) + // return 0; // ignore packet on collision + } + + *srcdat2 = srcdat; + *newsource = created; + + return 0; +} + +int RTPSources::UpdateReceiveTime(uint32_t ssrc,const RTPTime &receivetime,const RTPAddress *senderaddress) +{ + RTPInternalSourceData *srcdat; + bool created; + int status; + + status = GetRTCPSourceData(ssrc,senderaddress,&srcdat,&created); + if (status < 0) + return status; + if (srcdat == 0) + return 0; + + // We got valid SSRC info + srcdat->UpdateMessageTime(receivetime); + + // Call the callback + if (created) + OnNewSource(srcdat); + + return 0; +} + +void RTPSources::Timeout(const RTPTime &curtime,const RTPTime &timeoutdelay) +{ + int newtotalcount = 0; + int newsendercount = 0; + int newactivecount = 0; + RTPTime checktime = curtime; + checktime -= timeoutdelay; + + sourcelist.GotoFirstElement(); + while (sourcelist.HasCurrentElement()) + { + RTPInternalSourceData *srcdat = sourcelist.GetCurrentElement(); + RTPTime lastmsgtime = srcdat->INF_GetLastMessageTime(); + + // we don't want to time out ourselves + if ((srcdat != owndata) && (lastmsgtime < checktime)) // timeout + { + + totalcount--; + if (srcdat->IsSender()) + sendercount--; + if (srcdat->IsActive()) + activecount--; + + sourcelist.DeleteCurrentElement(); + + OnTimeout(srcdat); + OnRemoveSource(srcdat); + RTPDelete(srcdat,GetMemoryManager()); + } + else + { + newtotalcount++; + if (srcdat->IsSender()) + newsendercount++; + if (srcdat->IsActive()) + newactivecount++; + sourcelist.GotoNextElement(); + } + } + +#ifdef RTPDEBUG + if (newtotalcount != totalcount) + { + std::cout << "New total count " << newtotalcount << " doesnt match old total count " << totalcount << std::endl; + SafeCountTotal(); + } + if (newsendercount != sendercount) + { + std::cout << "New sender count " << newsendercount << " doesnt match old sender count " << sendercount << std::endl; + SafeCountSenders(); + } + if (newactivecount != activecount) + { + std::cout << "New active count " << newactivecount << " doesnt match old active count " << activecount << std::endl; + SafeCountActive(); + } +#endif // RTPDEBUG + + totalcount = newtotalcount; // just to play it safe + sendercount = newsendercount; + activecount = newactivecount; +} + +void RTPSources::SenderTimeout(const RTPTime &curtime,const RTPTime &timeoutdelay) +{ + int newtotalcount = 0; + int newsendercount = 0; + int newactivecount = 0; + RTPTime checktime = curtime; + checktime -= timeoutdelay; + + sourcelist.GotoFirstElement(); + while (sourcelist.HasCurrentElement()) + { + RTPInternalSourceData *srcdat = sourcelist.GetCurrentElement(); + + newtotalcount++; + if (srcdat->IsActive()) + newactivecount++; + + if (srcdat->IsSender()) + { + RTPTime lastrtppacktime = srcdat->INF_GetLastRTPPacketTime(); + + if (lastrtppacktime < checktime) // timeout + { + srcdat->ClearSenderFlag(); + sendercount--; + } + else + newsendercount++; + } + sourcelist.GotoNextElement(); + } + +#ifdef RTPDEBUG + if (newtotalcount != totalcount) + { + std::cout << "New total count " << newtotalcount << " doesnt match old total count " << totalcount << std::endl; + SafeCountTotal(); + } + if (newsendercount != sendercount) + { + std::cout << "New sender count " << newsendercount << " doesnt match old sender count " << sendercount << std::endl; + SafeCountSenders(); + } + if (newactivecount != activecount) + { + std::cout << "New active count " << newactivecount << " doesnt match old active count " << activecount << std::endl; + SafeCountActive(); + } +#endif // RTPDEBUG + + totalcount = newtotalcount; // just to play it safe + sendercount = newsendercount; + activecount = newactivecount; +} + +void RTPSources::BYETimeout(const RTPTime &curtime,const RTPTime &timeoutdelay) +{ + int newtotalcount = 0; + int newsendercount = 0; + int newactivecount = 0; + RTPTime checktime = curtime; + checktime -= timeoutdelay; + + sourcelist.GotoFirstElement(); + while (sourcelist.HasCurrentElement()) + { + RTPInternalSourceData *srcdat = sourcelist.GetCurrentElement(); + + if (srcdat->ReceivedBYE()) + { + RTPTime byetime = srcdat->GetBYETime(); + + if ((srcdat != owndata) && (checktime > byetime)) + { + totalcount--; + if (srcdat->IsSender()) + sendercount--; + if (srcdat->IsActive()) + activecount--; + sourcelist.DeleteCurrentElement(); + OnBYETimeout(srcdat); + OnRemoveSource(srcdat); + RTPDelete(srcdat,GetMemoryManager()); + } + else + { + newtotalcount++; + if (srcdat->IsSender()) + newsendercount++; + if (srcdat->IsActive()) + newactivecount++; + sourcelist.GotoNextElement(); + } + } + else + { + newtotalcount++; + if (srcdat->IsSender()) + newsendercount++; + if (srcdat->IsActive()) + newactivecount++; + sourcelist.GotoNextElement(); + } + } + +#ifdef RTPDEBUG + if (newtotalcount != totalcount) + { + std::cout << "New total count " << newtotalcount << " doesnt match old total count " << totalcount << std::endl; + SafeCountTotal(); + } + if (newsendercount != sendercount) + { + std::cout << "New sender count " << newsendercount << " doesnt match old sender count " << sendercount << std::endl; + SafeCountSenders(); + } + if (newactivecount != activecount) + { + std::cout << "New active count " << newactivecount << " doesnt match old active count " << activecount << std::endl; + SafeCountActive(); + } +#endif // RTPDEBUG + + totalcount = newtotalcount; // just to play it safe + sendercount = newsendercount; + activecount = newactivecount; +} + +void RTPSources::NoteTimeout(const RTPTime &curtime,const RTPTime &timeoutdelay) +{ + int newtotalcount = 0; + int newsendercount = 0; + int newactivecount = 0; + RTPTime checktime = curtime; + checktime -= timeoutdelay; + + sourcelist.GotoFirstElement(); + while (sourcelist.HasCurrentElement()) + { + RTPInternalSourceData *srcdat = sourcelist.GetCurrentElement(); + uint8_t *note; + size_t notelen; + + note = srcdat->SDES_GetNote(¬elen); + if (notelen != 0) // Note has been set + { + RTPTime notetime = srcdat->INF_GetLastSDESNoteTime(); + + if (checktime > notetime) + { + srcdat->ClearNote(); + OnNoteTimeout(srcdat); + } + } + + newtotalcount++; + if (srcdat->IsSender()) + newsendercount++; + if (srcdat->IsActive()) + newactivecount++; + sourcelist.GotoNextElement(); + } + +#ifdef RTPDEBUG + if (newtotalcount != totalcount) + { + std::cout << "New total count " << newtotalcount << " doesnt match old total count " << totalcount << std::endl; + SafeCountTotal(); + } + if (newsendercount != sendercount) + { + std::cout << "New sender count " << newsendercount << " doesnt match old sender count " << sendercount << std::endl; + SafeCountSenders(); + } + if (newactivecount != activecount) + { + std::cout << "New active count " << newactivecount << " doesnt match old active count " << activecount << std::endl; + SafeCountActive(); + } +#endif // RTPDEBUG + + totalcount = newtotalcount; // just to play it safe + sendercount = newsendercount; + activecount = newactivecount; + +} + +void RTPSources::MultipleTimeouts(const RTPTime &curtime,const RTPTime &sendertimeout,const RTPTime &byetimeout,const RTPTime &generaltimeout,const RTPTime ¬etimeout) +{ + int newtotalcount = 0; + int newsendercount = 0; + int newactivecount = 0; + RTPTime senderchecktime = curtime; + RTPTime byechecktime = curtime; + RTPTime generaltchecktime = curtime; + RTPTime notechecktime = curtime; + senderchecktime -= sendertimeout; + byechecktime -= byetimeout; + generaltchecktime -= generaltimeout; + notechecktime -= notetimeout; + + sourcelist.GotoFirstElement(); + while (sourcelist.HasCurrentElement()) + { + RTPInternalSourceData *srcdat = sourcelist.GetCurrentElement(); + bool deleted,issender,isactive; + bool byetimeout,normaltimeout,notetimeout; + uint8_t *note; + size_t notelen; + + issender = srcdat->IsSender(); + isactive = srcdat->IsActive(); + deleted = false; + byetimeout = false; + normaltimeout = false; + notetimeout = false; + + note = srcdat->SDES_GetNote(¬elen); + if (notelen != 0) // Note has been set + { + RTPTime notetime = srcdat->INF_GetLastSDESNoteTime(); + + if (notechecktime > notetime) + { + notetimeout = true; + srcdat->ClearNote(); + } + } + + if (srcdat->ReceivedBYE()) + { + RTPTime byetime = srcdat->GetBYETime(); + + if ((srcdat != owndata) && (byechecktime > byetime)) + { + sourcelist.DeleteCurrentElement(); + deleted = true; + byetimeout = true; + } + } + + if (!deleted) + { + RTPTime lastmsgtime = srcdat->INF_GetLastMessageTime(); + + if ((srcdat != owndata) && (lastmsgtime < generaltchecktime)) + { + sourcelist.DeleteCurrentElement(); + deleted = true; + normaltimeout = true; + } + } + + if (!deleted) + { + newtotalcount++; + + if (issender) + { + RTPTime lastrtppacktime = srcdat->INF_GetLastRTPPacketTime(); + + if (lastrtppacktime < senderchecktime) + { + srcdat->ClearSenderFlag(); + sendercount--; + } + else + newsendercount++; + } + + if (isactive) + newactivecount++; + + if (notetimeout) + OnNoteTimeout(srcdat); + + sourcelist.GotoNextElement(); + } + else // deleted entry + { + if (issender) + sendercount--; + if (isactive) + activecount--; + totalcount--; + + if (byetimeout) + OnBYETimeout(srcdat); + if (normaltimeout) + OnTimeout(srcdat); + OnRemoveSource(srcdat); + RTPDelete(srcdat,GetMemoryManager()); + } + } + +#ifdef RTPDEBUG + if (newtotalcount != totalcount) + { + SafeCountTotal(); + std::cout << "New total count " << newtotalcount << " doesnt match old total count " << totalcount << std::endl; + } + if (newsendercount != sendercount) + { + SafeCountSenders(); + std::cout << "New sender count " << newsendercount << " doesnt match old sender count " << sendercount << std::endl; + } + if (newactivecount != activecount) + { + std::cout << "New active count " << newactivecount << " doesnt match old active count " << activecount << std::endl; + SafeCountActive(); + } +#endif // RTPDEBUG + + totalcount = newtotalcount; // just to play it safe + sendercount = newsendercount; + activecount = newactivecount; +} + +#ifdef RTPDEBUG +void RTPSources::Dump() +{ + std::cout << "Total count: " << totalcount << std::endl; + std::cout << "Sender count: " << sendercount << std::endl; + std::cout << "Active count: " << activecount << std::endl; + if (GotoFirstSource()) + { + do + { + RTPSourceData *s; + s = GetCurrentSourceInfo(); + s->Dump(); + std::cout << std::endl; + } while (GotoNextSource()); + } +} + +void RTPSources::SafeCountTotal() +{ + int count = 0; + + if (GotoFirstSource()) + { + do + { + count++; + } while (GotoNextSource()); + } + std::cout << "Actual total count: " << count << std::endl; +} + +void RTPSources::SafeCountSenders() +{ + int count = 0; + + if (GotoFirstSource()) + { + do + { + RTPSourceData *s; + s = GetCurrentSourceInfo(); + if (s->IsSender()) + count++; + } while (GotoNextSource()); + } + std::cout << "Actual sender count: " << count << std::endl; +} + +void RTPSources::SafeCountActive() +{ + int count = 0; + + if (GotoFirstSource()) + { + do + { + RTPSourceData *s; + s = GetCurrentSourceInfo(); + if (s->IsActive()) + count++; + } while (GotoNextSource()); + } + std::cout << "Actual active count: " << count << std::endl; +} + +#endif // RTPDEBUG + +bool RTPSources::CheckCollision(RTPInternalSourceData *srcdat,const RTPAddress *senderaddress,bool isrtp) +{ + bool isset,otherisset; + const RTPAddress *addr,*otheraddr; + + if (isrtp) + { + isset = srcdat->IsRTPAddressSet(); + addr = srcdat->GetRTPDataAddress(); + otherisset = srcdat->IsRTCPAddressSet(); + otheraddr = srcdat->GetRTCPDataAddress(); + } + else + { + isset = srcdat->IsRTCPAddressSet(); + addr = srcdat->GetRTCPDataAddress(); + otherisset = srcdat->IsRTPAddressSet(); + otheraddr = srcdat->GetRTPDataAddress(); + } + + if (!isset) + { + if (otherisset) // got other address, can check if it comes from same host + { + if (otheraddr == 0) // other came from our own session + { + if (senderaddress != 0) + { + OnSSRCCollision(srcdat,senderaddress,isrtp); + return true; + } + + // Ok, store it + + if (isrtp) + srcdat->SetRTPDataAddress(senderaddress); + else + srcdat->SetRTCPDataAddress(senderaddress); + } + else + { + if (!otheraddr->IsFromSameHost(senderaddress)) + { + OnSSRCCollision(srcdat,senderaddress,isrtp); + return true; + } + + // Ok, comes from same host, store the address + + if (isrtp) + srcdat->SetRTPDataAddress(senderaddress); + else + srcdat->SetRTCPDataAddress(senderaddress); + } + } + else // no other address, store this one + { + if (isrtp) + srcdat->SetRTPDataAddress(senderaddress); + else + srcdat->SetRTCPDataAddress(senderaddress); + } + } + else // already got an address + { + if (addr == 0) + { + if (senderaddress != 0) + { + OnSSRCCollision(srcdat,senderaddress,isrtp); + return true; + } + } + else + { + /*if (!addr->IsSameAddress(senderaddress)) + { + OnSSRCCollision(srcdat,senderaddress,isrtp); + return true; + }*/ + } + } + + return false; +} + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtpsources.h b/src/libs/jrtplib/src/rtpsources.h new file mode 100644 index 00000000..efbcb002 --- /dev/null +++ b/src/libs/jrtplib/src/rtpsources.h @@ -0,0 +1,365 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpsources.h + */ + +#ifndef RTPSOURCES_H + +#define RTPSOURCES_H + +#include "rtpconfig.h" +#include "rtpkeyhashtable.h" +#include "rtcpsdespacket.h" +#include "rtptypes.h" +#include "rtpmemoryobject.h" + +#define RTPSOURCES_HASHSIZE 8317 + +namespace jrtplib +{ + +class JRTPLIB_IMPORTEXPORT RTPSources_GetHashIndex +{ +public: + static int GetIndex(const uint32_t &ssrc) { return ssrc%RTPSOURCES_HASHSIZE; } +}; + +class RTPNTPTime; +class RTPTransmitter; +class RTCPAPPPacket; +class RTPInternalSourceData; +class RTPRawPacket; +class RTPPacket; +class RTPTime; +class RTPAddress; +class RTPSourceData; + +/** Represents a table in which information about the participating sources is kept. + * Represents a table in which information about the participating sources is kept. The class has member + * functions to process RTP and RTCP data and to iterate over the participants. Note that a NULL address + * is used to identify packets from our own session. The class also provides some overridable functions + * which can be used to catch certain events (new SSRC, SSRC collision, ...). + */ +class JRTPLIB_IMPORTEXPORT RTPSources : public RTPMemoryObject +{ +public: + /** Type of probation to use for new sources. */ + enum ProbationType + { + NoProbation, /**< Don't use the probation algorithm; accept RTP packets immediately. */ + ProbationDiscard, /**< Discard incoming RTP packets originating from a source that's on probation. */ + ProbationStore /**< Store incoming RTP packet from a source that's on probation for later retrieval. */ + }; + + /** In the constructor you can select the probation type you'd like to use and also a memory manager. */ + RTPSources(ProbationType = ProbationStore,RTPMemoryManager *mgr = 0); + virtual ~RTPSources(); + + /** Clears the source table. */ + void Clear(); +#ifdef RTP_SUPPORT_PROBATION + /** Changes the current probation type. */ + void SetProbationType(ProbationType probtype) { probationtype = probtype; } +#endif // RTP_SUPPORT_PROBATION + + /** Creates an entry for our own SSRC identifier. */ + int CreateOwnSSRC(uint32_t ssrc); + + /** Deletes the entry for our own SSRC identifier. */ + int DeleteOwnSSRC(); + + /** This function should be called if our own session has sent an RTP packet. + * This function should be called if our own session has sent an RTP packet. + * For our own SSRC entry, the sender flag is updated based upon outgoing packets instead of incoming packets. + */ + void SentRTPPacket(); + + /** Processes a raw packet \c rawpack. + * Processes a raw packet \c rawpack. The instance \c trans will be used to check if this + * packet is one of our own packets. The flag \c acceptownpackets indicates whether own packets should be + * accepted or ignored. + */ + int ProcessRawPacket(RTPRawPacket *rawpack,RTPTransmitter *trans,bool acceptownpackets); + + /** Processes a raw packet \c rawpack. + * Processes a raw packet \c rawpack. Every transmitter in the array \c trans of length \c numtrans + * is used to check if the packet is from our own session. The flag \c acceptownpackets indicates + * whether own packets should be accepted or ignored. + */ + int ProcessRawPacket(RTPRawPacket *rawpack,RTPTransmitter *trans[],int numtrans,bool acceptownpackets); + + /** Processes an RTPPacket instance \c rtppack which was received at time \c receivetime and + * which originated from \c senderaddres. + * Processes an RTPPacket instance \c rtppack which was received at time \c receivetime and + * which originated from \c senderaddres. The \c senderaddress parameter must be NULL if + * the packet was sent by the local participant. The flag \c stored indicates whether the packet + * was stored in the table or not. If so, the \c rtppack instance may not be deleted. + */ + int ProcessRTPPacket(RTPPacket *rtppack,const RTPTime &receivetime,const RTPAddress *senderaddress,bool *stored); + + /** Processes the RTCP compound packet \c rtcpcomppack which was received at time \c receivetime from \c senderaddress. + * Processes the RTCP compound packet \c rtcpcomppack which was received at time \c receivetime from \c senderaddress. + * The \c senderaddress parameter must be NULL if the packet was sent by the local participant. + */ + int ProcessRTCPCompoundPacket(RTCPCompoundPacket *rtcpcomppack,const RTPTime &receivetime, + const RTPAddress *senderaddress); + + /** Process the sender information of SSRC \c ssrc into the source table. + * Process the sender information of SSRC \c ssrc into the source table. The information was received + * at time \c receivetime from address \c senderaddress. The \c senderaddress} parameter must be NULL + * if the packet was sent by the local participant. + */ + int ProcessRTCPSenderInfo(uint32_t ssrc,const RTPNTPTime &ntptime,uint32_t rtptime, + uint32_t packetcount,uint32_t octetcount,const RTPTime &receivetime, + const RTPAddress *senderaddress); + + /** Processes the report block information which was sent by participant \c ssrc into the source table. + * Processes the report block information which was sent by participant \c ssrc into the source table. + * The information was received at time \c receivetime from address \c senderaddress The \c senderaddress + * parameter must be NULL if the packet was sent by the local participant. + */ + int ProcessRTCPReportBlock(uint32_t ssrc,uint8_t fractionlost,int32_t lostpackets, + uint32_t exthighseqnr,uint32_t jitter,uint32_t lsr, + uint32_t dlsr,const RTPTime &receivetime,const RTPAddress *senderaddress); + + /** Processes the non-private SDES item from source \c ssrc into the source table. + * Processes the non-private SDES item from source \c ssrc into the source table. The information was + * received at time \c receivetime from address \c senderaddress. The \c senderaddress parameter must + * be NULL if the packet was sent by the local participant. + */ + int ProcessSDESNormalItem(uint32_t ssrc,RTCPSDESPacket::ItemType t,size_t itemlength, + const void *itemdata,const RTPTime &receivetime,const RTPAddress *senderaddress); +#ifdef RTP_SUPPORT_SDESPRIV + /** Processes the SDES private item from source \c ssrc into the source table. + * Processes the SDES private item from source \c ssrc into the source table. The information was + * received at time \c receivetime from address \c senderaddress. The \c senderaddress + * parameter must be NULL if the packet was sent by the local participant. + */ + int ProcessSDESPrivateItem(uint32_t ssrc,size_t prefixlen,const void *prefixdata, + size_t valuelen,const void *valuedata,const RTPTime &receivetime, + const RTPAddress *senderaddress); +#endif //RTP_SUPPORT_SDESPRIV + /** Processes the BYE message for SSRC \c ssrc. + * Processes the BYE message for SSRC \c ssrc. The information was received at time \c receivetime from + * address \c senderaddress. The \c senderaddress parameter must be NULL if the packet was sent by the + * local participant. + */ + int ProcessBYE(uint32_t ssrc,size_t reasonlength,const void *reasondata,const RTPTime &receivetime, + const RTPAddress *senderaddress); + + /** If we heard from source \c ssrc, but no actual data was added to the source table (for example, if + * no report block was meant for us), this function can e used to indicate that something was received from + * this source. + * If we heard from source \c ssrc, but no actual data was added to the source table (for example, if + * no report block was meant for us), this function can e used to indicate that something was received from + * this source. This will prevent a premature timeout for this participant. The message was received at time + * \c receivetime from address \c senderaddress. The \c senderaddress parameter must be NULL if the + * packet was sent by the local participant. + */ + int UpdateReceiveTime(uint32_t ssrc,const RTPTime &receivetime,const RTPAddress *senderaddress); + + /** Starts the iteration over the participants by going to the first member in the table. + * Starts the iteration over the participants by going to the first member in the table. + * If a member was found, the function returns \c true, otherwise it returns \c false. + */ + bool GotoFirstSource(); + + /** Sets the current source to be the next source in the table. + * Sets the current source to be the next source in the table. If we're already at the last source, + * the function returns \c false, otherwise it returns \c true. + */ + bool GotoNextSource(); + + /** Sets the current source to be the previous source in the table. + * Sets the current source to be the previous source in the table. If we're at the first source, + * the function returns \c false, otherwise it returns \c true. + */ + bool GotoPreviousSource(); + + /** Sets the current source to be the first source in the table which has RTPPacket instances + * that we haven't extracted yet. + * Sets the current source to be the first source in the table which has RTPPacket instances + * that we haven't extracted yet. If no such member was found, the function returns \c false, + * otherwise it returns \c true. + */ + bool GotoFirstSourceWithData(); + + /** Sets the current source to be the next source in the table which has RTPPacket instances that + * we haven't extracted yet. + * Sets the current source to be the next source in the table which has RTPPacket instances that + * we haven't extracted yet. If no such member was found, the function returns \c false, + * otherwise it returns \c true. + */ + bool GotoNextSourceWithData(); + + /** Sets the current source to be the previous source in the table which has RTPPacket instances + * that we haven't extracted yet. + * Sets the current source to be the previous source in the table which has RTPPacket instances + * that we haven't extracted yet. If no such member was found, the function returns \c false, + * otherwise it returns \c true. + */ + bool GotoPreviousSourceWithData(); + + /** Returns the RTPSourceData instance for the currently selected participant. */ + RTPSourceData *GetCurrentSourceInfo(); + + /** Returns the RTPSourceData instance for the participant identified by \c ssrc, or + * NULL if no such entry exists. + */ + RTPSourceData *GetSourceInfo(uint32_t ssrc); + + /** Extracts the next packet from the received packets queue of the current participant. */ + RTPPacket *GetNextPacket(); + + /** Returns \c true if an entry for participant \c ssrc exists and \c false otherwise. */ + bool GotEntry(uint32_t ssrc); + + /** If present, it returns the RTPSourceData instance of the entry which was created by CreateOwnSSRC. */ + RTPSourceData *GetOwnSourceInfo() { return (RTPSourceData *)owndata; } + + /** Assuming that the current time is \c curtime, time out the members from whom we haven't heard + * during the previous time interval \c timeoutdelay. + */ + void Timeout(const RTPTime &curtime,const RTPTime &timeoutdelay); + + /** Assuming that the current time is \c curtime, remove the sender flag for senders from whom we haven't + * received any RTP packets during the previous time interval \c timeoutdelay. + */ + void SenderTimeout(const RTPTime &curtime,const RTPTime &timeoutdelay); + + /** Assuming that the current time is \c curtime, remove the members who sent a BYE packet more than + * the time interval \c timeoutdelay ago. + */ + void BYETimeout(const RTPTime &curtime,const RTPTime &timeoutdelay); + + /** Assuming that the current time is \c curtime, clear the SDES NOTE items which haven't been updated + * during the previous time interval \c timeoutdelay. + */ + void NoteTimeout(const RTPTime &curtime,const RTPTime &timeoutdelay); + + /** Combines the functions SenderTimeout, BYETimeout, Timeout and NoteTimeout. + * Combines the functions SenderTimeout, BYETimeout, Timeout and NoteTimeout. This is more efficient + * than calling all four functions since only one iteration is needed in this function. + */ + void MultipleTimeouts(const RTPTime &curtime,const RTPTime &sendertimeout, + const RTPTime &byetimeout,const RTPTime &generaltimeout, + const RTPTime ¬etimeout); + + /** Returns the number of participants which are marked as a sender. */ + int GetSenderCount() const { return sendercount; } + + /** Returns the total number of entries in the source table. */ + int GetTotalCount() const { return totalcount; } + + /** Returns the number of members which have been validated and which haven't sent a BYE packet yet. */ + int GetActiveMemberCount() const { return activecount; } +#ifdef RTPDEBUG + void Dump(); + void SafeCountTotal(); + void SafeCountSenders(); + void SafeCountActive(); +#endif // RTPDEBUG +protected: + /** Is called when an RTP packet is about to be processed. */ + virtual void OnRTPPacket(RTPPacket * /*pack*/,const RTPTime &/*receivetime*/, const RTPAddress * /*senderaddress*/) { } + + /** Is called when an RTCP compound packet is about to be processed. */ + virtual void OnRTCPCompoundPacket(RTCPCompoundPacket * /*pack*/,const RTPTime & /*receivetime*/, + const RTPAddress * /*senderaddress*/) { } + + /** Is called when an SSRC collision was detected. + * Is called when an SSRC collision was detected. The instance \c srcdat is the one present in + * the table, the address \c senderaddress is the one that collided with one of the addresses + * and \c isrtp indicates against which address of \c srcdat the check failed. + */ + virtual void OnSSRCCollision(RTPSourceData * /*srcdat*/,const RTPAddress * /*senderaddress*/,bool /*isrtp*/) { } + + /** Is called when another CNAME was received than the one already present for source \c srcdat. */ + virtual void OnCNAMECollision(RTPSourceData * /*srcdat*/,const RTPAddress * /*senderaddress*/, + const uint8_t * /*cname*/,size_t /*cnamelength*/) { } + + /** Is called when a new entry \c srcdat is added to the source table. */ + virtual void OnNewSource(RTPSourceData * /*srcdat*/) { } + + /** Is called when the entry \c srcdat is about to be deleted from the source table. */ + virtual void OnRemoveSource(RTPSourceData * /*srcdat*/) { } + + /** Is called when participant \c srcdat is timed out. */ + virtual void OnTimeout(RTPSourceData * /*srcdat*/) { } + + /** Is called when participant \c srcdat is timed after having sent a BYE packet. */ + virtual void OnBYETimeout(RTPSourceData * /*srcdat*/) { } + + /** Is called when a BYE packet has been processed for source \c srcdat. */ + virtual void OnBYEPacket(RTPSourceData * /*srcdat*/) { } + + /** Is called when an RTCP APP packet \c apppacket has been received at time \c receivetime + * from address \c senderaddress. + */ + virtual void OnAPPPacket(RTCPAPPPacket * /*apppacket*/,const RTPTime &/*receivetime*/, + const RTPAddress * /*senderaddress*/) { } + + /** Is called when an unknown RTCP packet type was detected. */ + virtual void OnUnknownPacketType(RTCPPacket * /*rtcppack*/,const RTPTime &/*receivetime*/, + const RTPAddress * /*senderaddress*/) { } + + /** Is called when an unknown packet format for a known packet type was detected. */ + virtual void OnUnknownPacketFormat(RTCPPacket * /*rtcppack*/,const RTPTime &/*receivetime*/, + const RTPAddress * /*senderaddress*/) { } + + /** Is called when the SDES NOTE item for source \c srcdat has been timed out. */ + virtual void OnNoteTimeout(RTPSourceData * /*srcdat*/) { } +private: + void ClearSourceList(); + int ObtainSourceDataInstance(uint32_t ssrc,RTPInternalSourceData **srcdat,bool *created); + int GetRTCPSourceData(uint32_t ssrc,const RTPAddress *senderaddress,RTPInternalSourceData **srcdat,bool *newsource); + bool CheckCollision(RTPInternalSourceData *srcdat,const RTPAddress *senderaddress,bool isrtp); + + RTPKeyHashTable sourcelist; + + int sendercount; + int totalcount; + int activecount; + +#ifdef RTP_SUPPORT_PROBATION + ProbationType probationtype; +#endif // RTP_SUPPORT_PROBATION + + RTPInternalSourceData *owndata; +}; + +} // end namespace + +#endif // RTPSOURCES_H + diff --git a/src/libs/jrtplib/src/rtpstructs.h b/src/libs/jrtplib/src/rtpstructs.h new file mode 100644 index 00000000..bc222c13 --- /dev/null +++ b/src/libs/jrtplib/src/rtpstructs.h @@ -0,0 +1,128 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpstructs.h + */ + +#ifndef RTPSTRUCTS_H + +#define RTPSTRUCTS_H + +#include "rtpconfig.h" +#include "rtptypes.h" + +namespace jrtplib +{ + +struct RTPHeader +{ +#ifdef RTP_BIG_ENDIAN + uint8_t version:2; + uint8_t padding:1; + uint8_t extension:1; + uint8_t csrccount:4; + + uint8_t marker:1; + uint8_t payloadtype:7; +#else // little endian + uint8_t csrccount:4; + uint8_t extension:1; + uint8_t padding:1; + uint8_t version:2; + + uint8_t payloadtype:7; + uint8_t marker:1; +#endif // RTP_BIG_ENDIAN + + uint16_t sequencenumber; + uint32_t timestamp; + uint32_t ssrc; +}; + +struct RTPExtensionHeader +{ + uint16_t extid; + uint16_t length; +}; + +struct RTPSourceIdentifier +{ + uint32_t ssrc; +}; + +struct RTCPCommonHeader +{ +#ifdef RTP_BIG_ENDIAN + uint8_t version:2; + uint8_t padding:1; + uint8_t count:5; +#else // little endian + uint8_t count:5; + uint8_t padding:1; + uint8_t version:2; +#endif // RTP_BIG_ENDIAN + + uint8_t packettype; + uint16_t length; +}; + +struct RTCPSenderReport +{ + uint32_t ntptime_msw; + uint32_t ntptime_lsw; + uint32_t rtptimestamp; + uint32_t packetcount; + uint32_t octetcount; +}; + +struct RTCPReceiverReport +{ + uint32_t ssrc; // Identifies about which SSRC's data this report is... + uint8_t fractionlost; + uint8_t packetslost[3]; + uint32_t exthighseqnr; + uint32_t jitter; + uint32_t lsr; + uint32_t dlsr; +}; + +struct RTCPSDESHeader +{ + uint8_t sdesid; + uint8_t length; +}; + +} // end namespace + +#endif // RTPSTRUCTS + diff --git a/src/libs/jrtplib/src/rtptimeutilities.cpp b/src/libs/jrtplib/src/rtptimeutilities.cpp new file mode 100644 index 00000000..d0e2ac47 --- /dev/null +++ b/src/libs/jrtplib/src/rtptimeutilities.cpp @@ -0,0 +1,57 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#if (defined(WIN32) || defined(_WIN32_WCE)) + +#include "rtptimeutilities.h" +#ifdef RTPDEBUG + #include +#endif // RTPDEBUG + +namespace jrtplib +{ + +RTPTimeInitializer::RTPTimeInitializer() +{ +#ifdef RTPDEBUG + std::cout << "RTPTimeInitializer: Initializing RTPTime::CurrentTime()" << std::endl; +#endif // RTPDEBUG + RTPTime curtime = RTPTime::CurrentTime(); + dummy = -1; +} + +RTPTimeInitializer timeinit; + +} // end namespace + +#endif // WIN32 || _WIN32_WCE + diff --git a/src/libs/jrtplib/src/rtptimeutilities.h b/src/libs/jrtplib/src/rtptimeutilities.h new file mode 100644 index 00000000..4330f713 --- /dev/null +++ b/src/libs/jrtplib/src/rtptimeutilities.h @@ -0,0 +1,327 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtptimeutilities.h + */ + +#ifndef RTPTIMEUTILITIES_H + +#define RTPTIMEUTILITIES_H + +#include "rtpconfig.h" +#include "rtptypes.h" +#ifndef WIN32 + #include + #include +#else + #ifndef _WIN32_WCE + #include + #endif // _WIN32_WINCE +#endif // WIN32 + +#define RTP_NTPTIMEOFFSET 2208988800UL + +namespace jrtplib +{ + +/** + * This is a simple wrapper for the most significant word (MSW) and least + * significant word (LSW) of an NTP timestamp. + */ +class JRTPLIB_IMPORTEXPORT RTPNTPTime +{ +public: + /** This constructor creates and instance with MSW \c m and LSW \c l. */ + RTPNTPTime(uint32_t m,uint32_t l) { msw = m ; lsw = l; } + + /** Returns the most significant word. */ + uint32_t GetMSW() const { return msw; } + + /** Returns the least significant word. */ + uint32_t GetLSW() const { return lsw; } +private: + uint32_t msw,lsw; +}; + +/** This class is used to specify wallclock time, delay intervals etc. + * This class is used to specify wallclock time, delay intervals etc. + * It stores a number of seconds and a number of microseconds. + */ +class JRTPLIB_IMPORTEXPORT RTPTime +{ +public: + /** Returns an RTPTime instance representing the current wallclock time. + * Returns an RTPTime instance representing the current wallclock time. This is expressed + * as a number of seconds since 00:00:00 UTC, January 1, 1970. + */ + static RTPTime CurrentTime(); + + /** This function waits the amount of time specified in \c delay. */ + static void Wait(const RTPTime &delay); + + /** Creates an RTPTime instance representing \c t, which is expressed in units of seconds. */ + RTPTime(double t); + + /** Creates an instance that corresponds to \c ntptime. + * Creates an instance that corresponds to \c ntptime. If + * the conversion cannot be made, both the seconds and the + * microseconds are set to zero. + */ + RTPTime(RTPNTPTime ntptime); + + /** Creates an instance corresponding to \c seconds and \c microseconds. */ + RTPTime(uint32_t seconds, uint32_t microseconds) { sec = seconds; microsec = microseconds; } + + /** Returns the number of seconds stored in this instance. */ + uint32_t GetSeconds() const { return sec; } + + /** Returns the number of microseconds stored in this instance. */ + uint32_t GetMicroSeconds() const { return microsec; } + + /** Returns the time stored in this instance, expressed in units of seconds. */ + double GetDouble() const { return (((double)sec)+(((double)microsec)/1000000.0)); } + + /** Returns the NTP time corresponding to the time stored in this instance. */ + RTPNTPTime GetNTPTime() const; + + RTPTime &operator-=(const RTPTime &t); + RTPTime &operator+=(const RTPTime &t); + bool operator<(const RTPTime &t) const; + bool operator>(const RTPTime &t) const; + bool operator<=(const RTPTime &t) const; + bool operator>=(const RTPTime &t) const; +private: +#if (defined(WIN32) || defined(_WIN32_WCE)) + static inline unsigned __int64 CalculateMicroseconds(unsigned __int64 performancecount,unsigned __int64 performancefrequency); +#endif // WIN32 || _WIN32_WCE + + uint32_t sec,microsec; +}; + +inline RTPTime::RTPTime(double t) +{ + sec = (uint32_t)t; + + double t2 = t-((double)sec); + t2 *= 1000000.0; + microsec = (uint32_t)t2; +} + +inline RTPTime::RTPTime(RTPNTPTime ntptime) +{ + if (ntptime.GetMSW() < RTP_NTPTIMEOFFSET) + { + sec = 0; + microsec = 0; + } + else + { + sec = ntptime.GetMSW() - RTP_NTPTIMEOFFSET; + + double x = (double)ntptime.GetLSW(); + x /= (65536.0*65536.0); + x *= 1000000.0; + microsec = (uint32_t)x; + } +} + +#if (defined(WIN32) || defined(_WIN32_WCE)) + +inline unsigned __int64 RTPTime::CalculateMicroseconds(unsigned __int64 performancecount,unsigned __int64 performancefrequency) +{ + unsigned __int64 f = performancefrequency; + unsigned __int64 a = performancecount; + unsigned __int64 b = a/f; + unsigned __int64 c = a%f; // a = b*f+c => (a*1000000)/f = b*1000000+(c*1000000)/f + + return b*1000000ULL+(c*1000000ULL)/f; +} + +inline RTPTime RTPTime::CurrentTime() +{ + static int inited = 0; + static unsigned __int64 microseconds, initmicroseconds; + static LARGE_INTEGER performancefrequency; + + unsigned __int64 emulate_microseconds, microdiff; + SYSTEMTIME systemtime; + FILETIME filetime; + + LARGE_INTEGER performancecount; + + QueryPerformanceCounter(&performancecount); + + if(!inited){ + inited = 1; + QueryPerformanceFrequency(&performancefrequency); + GetSystemTime(&systemtime); + SystemTimeToFileTime(&systemtime,&filetime); + microseconds = ( ((unsigned __int64)(filetime.dwHighDateTime) << 32) + + (unsigned __int64)(filetime.dwLowDateTime) ) / 10ULL; + microseconds-= 11644473600000000ULL; // EPOCH + initmicroseconds = CalculateMicroseconds(performancecount.QuadPart, performancefrequency.QuadPart); + } + + emulate_microseconds = CalculateMicroseconds(performancecount.QuadPart, performancefrequency.QuadPart); + + microdiff = emulate_microseconds - initmicroseconds; + + return RTPTime((uint32_t)((microseconds + microdiff) / 1000000ULL), + ((uint32_t)((microseconds + microdiff) % 1000000ULL))); +} + +inline void RTPTime::Wait(const RTPTime &delay) +{ + DWORD t; + + t = ((DWORD)delay.GetSeconds())*1000+(((DWORD)delay.GetMicroSeconds())/1000); + Sleep(t); +} + +class JRTPLIB_IMPORTEXPORT RTPTimeInitializer +{ +public: + RTPTimeInitializer(); + void Dummy() { dummy++; } +private: + int dummy; +}; + +extern RTPTimeInitializer timeinit; + +#else // unix style + +inline RTPTime RTPTime::CurrentTime() +{ + struct timeval tv; + + gettimeofday(&tv,0); + return RTPTime((uint32_t)tv.tv_sec,(uint32_t)tv.tv_usec); +} + +inline void RTPTime::Wait(const RTPTime &delay) +{ + struct timespec req,rem; + + req.tv_sec = (time_t)delay.sec; + req.tv_nsec = ((long)delay.microsec)*1000; + nanosleep(&req,&rem); +} + +#endif // WIN32 + +inline RTPTime &RTPTime::operator-=(const RTPTime &t) +{ + sec -= t.sec; + if (t.microsec > microsec) + { + sec--; + microsec += 1000000; + } + microsec -= t.microsec; + return *this; +} + +inline RTPTime &RTPTime::operator+=(const RTPTime &t) +{ + sec += t.sec; + microsec += t.microsec; + if (microsec >= 1000000) + { + sec++; + microsec -= 1000000; + } + return *this; +} + +inline RTPNTPTime RTPTime::GetNTPTime() const +{ + uint32_t msw = sec+RTP_NTPTIMEOFFSET; + uint32_t lsw; + double x; + + x = microsec/1000000.0; + x *= (65536.0*65536.0); + lsw = (uint32_t)x; + + return RTPNTPTime(msw,lsw); +} + +inline bool RTPTime::operator<(const RTPTime &t) const +{ + if (sec < t.sec) + return true; + if (sec > t.sec) + return false; + if (microsec < t.microsec) + return true; + return false; +} + +inline bool RTPTime::operator>(const RTPTime &t) const +{ + if (sec > t.sec) + return true; + if (sec < t.sec) + return false; + if (microsec > t.microsec) + return true; + return false; +} + +inline bool RTPTime::operator<=(const RTPTime &t) const +{ + if (sec < t.sec) + return true; + if (sec > t.sec) + return false; + if (microsec <= t.microsec) + return true; + return false; +} + +inline bool RTPTime::operator>=(const RTPTime &t) const +{ + if (sec > t.sec) + return true; + if (sec < t.sec) + return false; + if (microsec >= t.microsec) + return true; + return false; +} + +} // end namespace + +#endif // RTPTIMEUTILITIES_H + diff --git a/src/libs/jrtplib/src/rtptransmitter.h b/src/libs/jrtplib/src/rtptransmitter.h new file mode 100644 index 00000000..e46205d4 --- /dev/null +++ b/src/libs/jrtplib/src/rtptransmitter.h @@ -0,0 +1,261 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtptransmitter.h + */ + +#ifndef RTPTRANSMITTER_H + +#define RTPTRANSMITTER_H + +#include "rtpconfig.h" +#include "rtptypes.h" +#include "rtpmemoryobject.h" + +namespace jrtplib +{ + +class RTPRawPacket; +class RTPAddress; +class RTPTransmissionParams; +class RTPTime; +class RTPTransmissionInfo; + +/** Abstract class from which actual transmission components should be derived. + * Abstract class from which actual transmission components should be derived. + * The abstract class RTPTransmitter specifies the interface for + * actual transmission components. Currently, three implementations exist: + * an UDP over IPv4 transmitter, an UDP over IPv6 transmitter and a transmitter + * which can be used to use an external transmission mechanism. + */ +class JRTPLIB_IMPORTEXPORT RTPTransmitter : public RTPMemoryObject +{ +public: + /** Used to identify a specific transmitter. + * If UserDefinedProto is used in the RTPSession::Create function, the RTPSession + * virtual member function NewUserDefinedTransmitter will be called to create + * a transmission component. + */ + enum TransmissionProtocol + { + IPv4UDPProto, /**< Specifies the internal UDP over IPv4 transmitter. */ + IPv6UDPProto, /**< Specifies the internal UDP over IPv6 transmitter. */ + ExternalProto, /**< Specifies the transmitter which can send packets using an external mechanism, and which can have received packets injected into it - see RTPExternalTransmitter for additional information. */ + UserDefinedProto /**< Specifies a user defined, external transmitter. */ + }; + + /** Three kind of receive modes can be specified. */ + enum ReceiveMode + { + AcceptAll, /**< All incoming data is accepted, no matter where it originated from. */ + AcceptSome, /**< Only data coming from specific sources will be accepted. */ + IgnoreSome /**< All incoming data is accepted, except for data coming from a specific set of sources. */ + }; +protected: + /** Constructor in which you can specify a memory manager to use. */ + RTPTransmitter(RTPMemoryManager *mgr) : RTPMemoryObject(mgr) { } +public: + virtual ~RTPTransmitter() { } + + /** This function must be called before the transmission component can be used. + * This function must be called before the transmission component can be used. Depending on + * the value of \c threadsafe, the component will be created for thread-safe usage or not. + */ + virtual int Init(bool threadsafe) = 0; + + /** Prepares the component to be used. + * Prepares the component to be used. The parameter \c maxpacksize specifies the maximum size + * a packet can have: if the packet is larger it will not be transmitted. The \c transparams + * parameter specifies a pointer to an RTPTransmissionParams instance. This is also an abstract + * class and each actual component will define its own parameters by inheriting a class + * from RTPTransmissionParams. If \c transparams is NULL, the default transmission parameters + * for the component will be used. + */ + virtual int Create(size_t maxpacksize,const RTPTransmissionParams *transparams) = 0; + + /** By calling this function, buffers are cleared and the component cannot be used anymore. + * By calling this function, buffers are cleared and the component cannot be used anymore. + * Only when the Create function is called again can the component be used again. */ + virtual void Destroy() = 0; + + /** Returns additional information about the transmitter. + * This function returns an instance of a subclass of RTPTransmissionInfo which will give + * some additional information about the transmitter (a list of local IP addresses for example). + * Currently, either an instance of RTPUDPv4TransmissionInfo or RTPUDPv6TransmissionInfo is + * returned, depending on the type of the transmitter. The user has to deallocate the returned + * instance when it is no longer needed, which can be done using RTPTransmitter::DeleteTransmissionInfo. + */ + virtual RTPTransmissionInfo *GetTransmissionInfo() = 0; + + /** Deallocates the information returned by RTPTransmitter::GetTransmissionInfo . + * Deallocates the information returned by RTPTransmitter::GetTransmissionInfo . + */ + virtual void DeleteTransmissionInfo(RTPTransmissionInfo *inf) = 0; + + /** Looks up the local host name. + * Looks up the local host name based upon internal information about the local host's + * addresses. This function might take some time since a DNS query might be done. \c bufferlength + * should initially contain the number of bytes that may be stored in \c buffer. If the function + * succeeds, \c bufferlength is set to the number of bytes stored in \c buffer. Note that the data + * in \c buffer is not NULL-terminated. If the function fails because the buffer isn't large enough, + * it returns \c ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL and stores the number of bytes needed in + * \c bufferlength. + */ + virtual int GetLocalHostName(uint8_t *buffer,size_t *bufferlength) = 0; + + /** Returns \c true if the address specified by \c addr is one of the addresses of the transmitter. */ + virtual bool ComesFromThisTransmitter(const RTPAddress *addr) = 0; + + /** Returns the amount of bytes that will be added to the RTP packet by the underlying layers (excluding + * the link layer). */ + virtual size_t GetHeaderOverhead() = 0; + + /** Checks for incoming data and stores it. */ + virtual int Poll() = 0; + + /** Waits until incoming data is detected. + * Waits at most a time \c delay until incoming data has been detected. If \c dataavailable is not NULL, + * it should be set to \c true if data was actually read and to \c false otherwise. + */ + virtual int WaitForIncomingData(const RTPTime &delay,bool *dataavailable = 0) = 0; + + /** If the previous function has been called, this one aborts the waiting. */ + virtual int AbortWait() = 0; + + /** Send a packet with length \c len containing \c data to all RTP addresses of the current destination list. */ + virtual int SendRTPData(const void *data,size_t len) = 0; + + /** Send a packet with length \c len containing \c data to all RTCP addresses of the current destination list. */ + virtual int SendRTCPData(const void *data,size_t len) = 0; + + /** Adds the address specified by \c addr to the list of destinations. */ + virtual int AddDestination(const RTPAddress &addr) = 0; + + /** Deletes the address specified by \c addr from the list of destinations. */ + virtual int DeleteDestination(const RTPAddress &addr) = 0; + + /** Clears the list of destinations. */ + virtual void ClearDestinations() = 0; + + /** Returns \c true if the transmission component supports multicasting. */ + virtual bool SupportsMulticasting() = 0; + + /** Joins the multicast group specified by \c addr. */ + virtual int JoinMulticastGroup(const RTPAddress &addr) = 0; + + /** Leaves the multicast group specified by \c addr. */ + virtual int LeaveMulticastGroup(const RTPAddress &addr) = 0; + + /** Leaves all the multicast groups that have been joined. */ + virtual void LeaveAllMulticastGroups() = 0; + + /** Sets the receive mode. + * Sets the receive mode to \c m, which is one of the following: RTPTransmitter::AcceptAll, + * RTPTransmitter::AcceptSome or RTPTransmitter::IgnoreSome. Note that if the receive + * mode is changed, all information about the addresses to ignore to accept is lost. + */ + virtual int SetReceiveMode(RTPTransmitter::ReceiveMode m) = 0; + + /** Adds \c addr to the list of addresses to ignore. */ + virtual int AddToIgnoreList(const RTPAddress &addr) = 0; + + /** Deletes \c addr from the list of addresses to accept. */ + virtual int DeleteFromIgnoreList(const RTPAddress &addr)= 0; + + /** Clears the list of addresses to ignore. */ + virtual void ClearIgnoreList() = 0; + + /** Adds \c addr to the list of addresses to accept. */ + virtual int AddToAcceptList(const RTPAddress &addr) = 0; + + /** Deletes \c addr from the list of addresses to accept. */ + virtual int DeleteFromAcceptList(const RTPAddress &addr) = 0; + + /** Clears the list of addresses to accept. */ + virtual void ClearAcceptList() = 0; + + /** Sets the maximum packet size which the transmitter should allow to \c s. */ + virtual int SetMaximumPacketSize(size_t s) = 0; + + /** Returns \c true if packets can be obtained using the GetNextPacket member function. */ + virtual bool NewDataAvailable() = 0; + + /** Returns the raw data of a received RTP packet (received during the Poll function) + * in an RTPRawPacket instance. */ + virtual RTPRawPacket *GetNextPacket() = 0; +#ifdef RTPDEBUG + virtual void Dump() = 0; +#endif // RTPDEBUG +}; + +/** Base class for transmission parameters. + * This class is an abstract class which will have a specific implementation for a + * specific kind of transmission component. All actual implementations inherit the + * GetTransmissionProtocol function which identifies the component type for which + * these parameters are valid. + */ +class JRTPLIB_IMPORTEXPORT RTPTransmissionParams +{ +protected: + RTPTransmissionParams(RTPTransmitter::TransmissionProtocol p) { protocol = p; } +public: + virtual ~RTPTransmissionParams() { } + + /** Returns the transmitter type for which these parameters are valid. */ + RTPTransmitter::TransmissionProtocol GetTransmissionProtocol() const { return protocol; } +private: + RTPTransmitter::TransmissionProtocol protocol; +}; + +/** Base class for additional information about the transmitter. + * This class is an abstract class which will have a specific implementation for a + * specific kind of transmission component. All actual implementations inherit the + * GetTransmissionProtocol function which identifies the component type for which + * these parameters are valid. + */ +class JRTPLIB_IMPORTEXPORT RTPTransmissionInfo +{ +protected: + RTPTransmissionInfo(RTPTransmitter::TransmissionProtocol p) { protocol = p; } +public: + virtual ~RTPTransmissionInfo() { } + /** Returns the transmitter type for which these parameters are valid. */ + RTPTransmitter::TransmissionProtocol GetTransmissionProtocol() const { return protocol; } +private: + RTPTransmitter::TransmissionProtocol protocol; +}; + +} // end namespace + +#endif // RTPTRANSMITTER_H + diff --git a/src/libs/jrtplib/src/rtptypes.h b/src/libs/jrtplib/src/rtptypes.h new file mode 100644 index 00000000..7d77f7b4 --- /dev/null +++ b/src/libs/jrtplib/src/rtptypes.h @@ -0,0 +1,37 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + #include "rtptypes_unix.h" +#else + #include "rtptypes_win.h" +#endif // WIN32 diff --git a/src/libs/jrtplib/src/rtptypes.h.in b/src/libs/jrtplib/src/rtptypes.h.in new file mode 100644 index 00000000..a565e45d --- /dev/null +++ b/src/libs/jrtplib/src/rtptypes.h.in @@ -0,0 +1,2 @@ +${RTP_WINSOCK_HEADERS} +${RTP_INTTYPE_HEADERS} diff --git a/src/libs/jrtplib/src/rtptypes_unix.h b/src/libs/jrtplib/src/rtptypes_unix.h new file mode 100644 index 00000000..6a4e2f9e --- /dev/null +++ b/src/libs/jrtplib/src/rtptypes_unix.h @@ -0,0 +1,2 @@ +#include +#include diff --git a/src/libs/jrtplib/src/rtptypes_win.h b/src/libs/jrtplib/src/rtptypes_win.h new file mode 100644 index 00000000..edef0004 --- /dev/null +++ b/src/libs/jrtplib/src/rtptypes_win.h @@ -0,0 +1,62 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#ifndef RTPTYPES_H + +#define RTPTYPES_H + +#ifndef _WIN32_WCE + #include + #include + #include +#else + #include + #include +#endif // _WIN32_WCE + +#ifndef INTTYPES_DEFINED + +#define INTTYPES_DEFINED + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned int uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; + +#endif // INTTYPES_DEFINED + +#endif // RTPTYPES_H + diff --git a/src/libs/jrtplib/src/rtpudpv4transmitter.cpp b/src/libs/jrtplib/src/rtpudpv4transmitter.cpp new file mode 100644 index 00000000..c22d3331 --- /dev/null +++ b/src/libs/jrtplib/src/rtpudpv4transmitter.cpp @@ -0,0 +1,1962 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpudpv4transmitter.h" +#include "rtprawpacket.h" +#include "rtpipv4address.h" +#include "rtptimeutilities.h" +#include "rtpdefines.h" +#include +#if (defined(WIN32) || defined(_WIN32_WCE)) + #define RTPSOCKERR INVALID_SOCKET + #define RTPCLOSE(x) closesocket(x) + #define RTPSOCKLENTYPE int + #define RTPIOCTL ioctlsocket +#else // not Win32 + #include + #include + #include + #include + #include + #include + #include + #include + + #ifdef RTP_HAVE_SYS_FILIO + #include + #endif // RTP_HAVE_SYS_FILIO + #ifdef RTP_HAVE_SYS_SOCKIO + #include + #endif // RTP_HAVE_SYS_SOCKIO + #ifdef RTP_SUPPORT_IFADDRS + #include + #endif // RTP_SUPPORT_IFADDRS + + #define RTPSOCKERR -1 + #define RTPCLOSE(x) close(x) + + #ifdef RTP_SOCKLENTYPE_UINT + #define RTPSOCKLENTYPE unsigned int + #else + #define RTPSOCKLENTYPE int + #endif // RTP_SOCKLENTYPE_UINT + + #define RTPIOCTL ioctl +#endif // WIN32 +#ifdef RTPDEBUG + #include +#endif // RTPDEBUG + +#include "rtpdebug.h" + +#include + +#define RTPUDPV4TRANS_MAXPACKSIZE 65535 +#define RTPUDPV4TRANS_IFREQBUFSIZE 8192 + +#define RTPUDPV4TRANS_IS_MCASTADDR(x) (((x)&0xF0000000) == 0xE0000000) + +#define RTPUDPV4TRANS_MCASTMEMBERSHIP(socket,type,mcastip,status) {\ + struct ip_mreq mreq;\ + \ + mreq.imr_multiaddr.s_addr = htonl(mcastip);\ + mreq.imr_interface.s_addr = htonl(mcastifaceIP);\ + status = setsockopt(socket,IPPROTO_IP,type,(const char *)&mreq,sizeof(struct ip_mreq));\ + } +#ifdef RTP_SUPPORT_THREAD + #define MAINMUTEX_LOCK { if (threadsafe) mainmutex.Lock(); } + #define MAINMUTEX_UNLOCK { if (threadsafe) mainmutex.Unlock(); } + #define WAITMUTEX_LOCK { if (threadsafe) waitmutex.Lock(); } + #define WAITMUTEX_UNLOCK { if (threadsafe) waitmutex.Unlock(); } +#else + #define MAINMUTEX_LOCK + #define MAINMUTEX_UNLOCK + #define WAITMUTEX_LOCK + #define WAITMUTEX_UNLOCK +#endif // RTP_SUPPORT_THREAD + +namespace jrtplib +{ + +RTPUDPv4Transmitter::RTPUDPv4Transmitter(RTPMemoryManager *mgr) : RTPTransmitter(mgr),destinations(mgr,RTPMEM_TYPE_CLASS_DESTINATIONLISTHASHELEMENT), +#ifdef RTP_SUPPORT_IPV4MULTICAST + multicastgroups(mgr,RTPMEM_TYPE_CLASS_MULTICASTHASHELEMENT), +#endif // RTP_SUPPORT_IPV4MULTICAST + acceptignoreinfo(mgr,RTPMEM_TYPE_CLASS_ACCEPTIGNOREHASHELEMENT) +{ + created = false; + init = false; +#if (defined(WIN32) || defined(_WIN32_WCE)) + timeinit.Dummy(); +#endif // WIN32 || _WIN32_WCE +} + +RTPUDPv4Transmitter::~RTPUDPv4Transmitter() +{ + Destroy(); +} + +int RTPUDPv4Transmitter::Init(bool tsafe) +{ + if (init) + return ERR_RTP_UDPV4TRANS_ALREADYINIT; + +#ifdef RTP_SUPPORT_THREAD + threadsafe = tsafe; + if (threadsafe) + { + int status; + + status = mainmutex.Init(); + if (status < 0) + return ERR_RTP_UDPV4TRANS_CANTINITMUTEX; + status = waitmutex.Init(); + if (status < 0) + return ERR_RTP_UDPV4TRANS_CANTINITMUTEX; + } +#else + if (tsafe) + return ERR_RTP_NOTHREADSUPPORT; +#endif // RTP_SUPPORT_THREAD + + init = true; + return 0; +} + +int RTPUDPv4Transmitter::Create(size_t maximumpacketsize,const RTPTransmissionParams *transparams) +{ + const RTPUDPv4TransmissionParams *params,defaultparams; + struct sockaddr_in addr; + RTPSOCKLENTYPE size; + int status; + + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_ALREADYCREATED; + } + + // Obtain transmission parameters + + if (transparams == 0) + params = &defaultparams; + else + { + if (transparams->GetTransmissionProtocol() != RTPTransmitter::IPv4UDPProto) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_ILLEGALPARAMETERS; + } + params = (const RTPUDPv4TransmissionParams *)transparams; + } + + // Check if portbase is even + if (params->GetPortbase()%2 != 0) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_PORTBASENOTEVEN; + } + + // create sockets + + rtpsock = socket(PF_INET,SOCK_DGRAM,0); + if (rtpsock == RTPSOCKERR) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET; + } + rtcpsock = socket(PF_INET,SOCK_DGRAM,0); + if (rtcpsock == RTPSOCKERR) + { + RTPCLOSE(rtpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET; + } + + // set socket buffer sizes + + size = params->GetRTPReceiveBuffer(); + if (setsockopt(rtpsock,SOL_SOCKET,SO_RCVBUF,(const char *)&size,sizeof(int)) != 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_CANTSETRTPRECEIVEBUF; + } + size = params->GetRTPSendBuffer(); + if (setsockopt(rtpsock,SOL_SOCKET,SO_SNDBUF,(const char *)&size,sizeof(int)) != 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_CANTSETRTPTRANSMITBUF; + } + size = params->GetRTCPReceiveBuffer(); + if (setsockopt(rtcpsock,SOL_SOCKET,SO_RCVBUF,(const char *)&size,sizeof(int)) != 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_CANTSETRTCPRECEIVEBUF; + } + size = params->GetRTCPSendBuffer(); + if (setsockopt(rtcpsock,SOL_SOCKET,SO_SNDBUF,(const char *)&size,sizeof(int)) != 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_CANTSETRTCPTRANSMITBUF; + } + + // bind sockets + + bindIP = params->GetBindIP(); + mcastifaceIP = params->GetMulticastInterfaceIP(); + + memset(&addr,0,sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(params->GetPortbase()); + addr.sin_addr.s_addr = htonl(bindIP); + if (bind(rtpsock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_CANTBINDRTPSOCKET; + } + memset(&addr,0,sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(params->GetPortbase()+1); + addr.sin_addr.s_addr = htonl(bindIP); + if (bind(rtcpsock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_CANTBINDRTCPSOCKET; + } + + // Try to obtain local IP addresses + + localIPs = params->GetLocalIPList(); + if (localIPs.empty()) // User did not provide list of local IP addresses, calculate them + { + int status; + + if ((status = CreateLocalIPList()) < 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return status; + } +#ifdef RTPDEBUG + std::cout << "Found these local IP addresses:" << std::endl; + + std::list::const_iterator it; + + for (it = localIPs.begin() ; it != localIPs.end() ; it++) + { + RTPIPv4Address a(*it); + + std::cout << a.GetAddressString() << std::endl; + } +#endif // RTPDEBUG + } + +#ifdef RTP_SUPPORT_IPV4MULTICAST + if (SetMulticastTTL(params->GetMulticastTTL())) + supportsmulticasting = true; + else + supportsmulticasting = false; +#else // no multicast support enabled + supportsmulticasting = false; +#endif // RTP_SUPPORT_IPV4MULTICAST + + if ((status = CreateAbortDescriptors()) < 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return status; + } + + if (maximumpacketsize > RTPUDPV4TRANS_MAXPACKSIZE) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + DestroyAbortDescriptors(); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG; + } + + maxpacksize = maximumpacketsize; + portbase = params->GetPortbase(); + multicastTTL = params->GetMulticastTTL(); + receivemode = RTPTransmitter::AcceptAll; + + localhostname = 0; + localhostnamelength = 0; + + waitingfordata = false; + created = true; + MAINMUTEX_UNLOCK + return 0; +} + +void RTPUDPv4Transmitter::Destroy() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK; + return; + } + + if (localhostname) + { + RTPDeleteByteArray(localhostname,GetMemoryManager()); + localhostname = 0; + localhostnamelength = 0; + } + + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + destinations.Clear(); +#ifdef RTP_SUPPORT_IPV4MULTICAST + multicastgroups.Clear(); +#endif // RTP_SUPPORT_IPV4MULTICAST + FlushPackets(); + ClearAcceptIgnoreInfo(); + localIPs.clear(); + created = false; + + if (waitingfordata) + { + AbortWaitInternal(); + DestroyAbortDescriptors(); + MAINMUTEX_UNLOCK + WAITMUTEX_LOCK // to make sure that the WaitForIncomingData function ended + WAITMUTEX_UNLOCK + } + else + DestroyAbortDescriptors(); + + MAINMUTEX_UNLOCK +} + +RTPTransmissionInfo *RTPUDPv4Transmitter::GetTransmissionInfo() +{ + if (!init) + return 0; + + MAINMUTEX_LOCK + RTPTransmissionInfo *tinf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPTRANSMISSIONINFO) RTPUDPv4TransmissionInfo(localIPs,rtpsock,rtcpsock); + MAINMUTEX_UNLOCK + return tinf; +} + +void RTPUDPv4Transmitter::DeleteTransmissionInfo(RTPTransmissionInfo *i) +{ + if (!init) + return; + + RTPDelete(i, GetMemoryManager()); +} + +int RTPUDPv4Transmitter::GetLocalHostName(uint8_t *buffer,size_t *bufferlength) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + + if (localhostname == 0) + { + if (localIPs.empty()) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOLOCALIPS; + } + + std::list::const_iterator it; + std::list hostnames; + + for (it = localIPs.begin() ; it != localIPs.end() ; it++) + { + bool founddouble = false; + bool foundentry = true; + + while (!founddouble && foundentry) + { + struct hostent *he; + uint8_t addr[4]; + uint32_t ip = (*it); + + addr[0] = (uint8_t)((ip>>24)&0xFF); + addr[1] = (uint8_t)((ip>>16)&0xFF); + addr[2] = (uint8_t)((ip>>8)&0xFF); + addr[3] = (uint8_t)(ip&0xFF); + he = gethostbyaddr((char *)addr,4,AF_INET); + if (he != 0) + { + std::string hname = std::string(he->h_name); + std::list::const_iterator it; + + for (it = hostnames.begin() ; !founddouble && it != hostnames.end() ; it++) + if ((*it) == hname) + founddouble = true; + + if (!founddouble) + hostnames.push_back(hname); + + int i = 0; + while (!founddouble && he->h_aliases[i] != 0) + { + std::string hname = std::string(he->h_aliases[i]); + + for (it = hostnames.begin() ; !founddouble && it != hostnames.end() ; it++) + if ((*it) == hname) + founddouble = true; + + if (!founddouble) + { + hostnames.push_back(hname); + i++; + } + } + } + else + foundentry = false; + } + } + + bool found = false; + + if (!hostnames.empty()) // try to select the most appropriate hostname + { + std::list::const_iterator it; + + hostnames.sort(); + for (it = hostnames.begin() ; !found && it != hostnames.end() ; it++) + { + if ((*it).find('.') != std::string::npos) + { + found = true; + localhostnamelength = (*it).length(); + localhostname = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) uint8_t [localhostnamelength+1]; + if (localhostname == 0) + { + MAINMUTEX_UNLOCK + return ERR_RTP_OUTOFMEM; + } + memcpy(localhostname,(*it).c_str(),localhostnamelength); + localhostname[localhostnamelength] = 0; + } + } + } + + if (!found) // use an IP address + { + uint32_t ip; + int len; + char str[16]; + + it = localIPs.begin(); + ip = (*it); + + RTP_SNPRINTF(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF)); + len = strlen(str); + + localhostnamelength = len; + localhostname = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) uint8_t [localhostnamelength + 1]; + if (localhostname == 0) + { + MAINMUTEX_UNLOCK + return ERR_RTP_OUTOFMEM; + } + memcpy(localhostname,str,localhostnamelength); + localhostname[localhostnamelength] = 0; + } + } + + if ((*bufferlength) < localhostnamelength) + { + *bufferlength = localhostnamelength; // tell the application the required size of the buffer + MAINMUTEX_UNLOCK + return ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL; + } + + memcpy(buffer,localhostname,localhostnamelength); + *bufferlength = localhostnamelength; + + MAINMUTEX_UNLOCK + return 0; +} + +bool RTPUDPv4Transmitter::ComesFromThisTransmitter(const RTPAddress *addr) +{ + if (!init) + return false; + + if (addr == 0) + return false; + + MAINMUTEX_LOCK + + bool v; + + if (created && addr->GetAddressType() == RTPAddress::IPv4Address) + { + const RTPIPv4Address *addr2 = (const RTPIPv4Address *)addr; + bool found = false; + std::list::const_iterator it; + + it = localIPs.begin(); + while (!found && it != localIPs.end()) + { + if (addr2->GetIP() == *it) + found = true; + else + ++it; + } + + if (!found) + v = false; + else + { + if (addr2->GetPort() == portbase) // check for RTP port + v = true; + else if (addr2->GetPort() == (portbase+1)) // check for RTCP port + v = true; + else + v = false; + } + } + else + v = false; + + MAINMUTEX_UNLOCK + return v; +} + +int RTPUDPv4Transmitter::Poll() +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + int status; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + status = PollSocket(true); // poll RTP socket + if (status >= 0) + status = PollSocket(false); // poll RTCP socket + MAINMUTEX_UNLOCK + return status; +} + + +int RTPUDPv4Transmitter::WaitForIncomingData(const RTPTime &delay,bool *dataavailable) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + + fd_set fdset; + struct timeval tv; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (waitingfordata) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_ALREADYWAITING; + } + + FD_ZERO(&fdset); + FD_SET(rtpsock,&fdset); + FD_SET(rtcpsock,&fdset); +#ifndef RTP_DISABLE_INTERRUPT + FD_SET(abortdesc[0],&fdset); +#endif + tv.tv_sec = delay.GetSeconds(); + tv.tv_usec = delay.GetMicroSeconds(); + + waitingfordata = true; + + WAITMUTEX_LOCK + MAINMUTEX_UNLOCK + + if (select(FD_SETSIZE,&fdset,0,0,&tv) < 0) + { + MAINMUTEX_LOCK + waitingfordata = false; + MAINMUTEX_UNLOCK + WAITMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_ERRORINSELECT; + } + + MAINMUTEX_LOCK + waitingfordata = false; + if (!created) // destroy called + { + MAINMUTEX_UNLOCK; + WAITMUTEX_UNLOCK + return 0; + } + +#ifndef RTP_DISABLE_INTERRUPT + // if aborted, read from abort buffer + if (FD_ISSET(abortdesc[0],&fdset)) + { +#if (defined(WIN32) || defined(_WIN32_WCE)) + char buf[1]; + + recv(abortdesc[0],buf,1,0); +#else + unsigned char buf[1]; + + if (read(abortdesc[0],buf,1)) + { + // To get rid of __wur related compiler warnings + } +#endif // WIN32 + } +#endif + + if (dataavailable != 0) + { + if (FD_ISSET(rtpsock,&fdset) || FD_ISSET(rtcpsock,&fdset)) + *dataavailable = true; + else + *dataavailable = false; + } + + MAINMUTEX_UNLOCK + WAITMUTEX_UNLOCK + return 0; +} + +int RTPUDPv4Transmitter::AbortWait() +{ +#ifndef RTP_DISABLE_INTERRUPT + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (!waitingfordata) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTWAITING; + } + + AbortWaitInternal(); + + MAINMUTEX_UNLOCK +#endif + return 0; +} + +int RTPUDPv4Transmitter::SendRTPData(const void *data,size_t len) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (len > maxpacksize) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG; + } + + destinations.GotoFirstElement(); + while (destinations.HasCurrentElement()) + { + sendto(rtpsock,(const char *)data,len,0,(const struct sockaddr *)destinations.GetCurrentElement().GetRTPSockAddr(),sizeof(struct sockaddr_in)); + destinations.GotoNextElement(); + } + + MAINMUTEX_UNLOCK + return 0; +} + +int RTPUDPv4Transmitter::SendRTCPData(const void *data,size_t len) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (len > maxpacksize) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG; + } + + destinations.GotoFirstElement(); + while (destinations.HasCurrentElement()) + { + sendto(rtcpsock,(const char *)data,len,0,(const struct sockaddr *)destinations.GetCurrentElement().GetRTCPSockAddr(),sizeof(struct sockaddr_in)); + destinations.GotoNextElement(); + } + + MAINMUTEX_UNLOCK + return 0; +} + +int RTPUDPv4Transmitter::AddDestination(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; + } + + RTPIPv4Address &address = (RTPIPv4Address &)addr; + RTPIPv4Destination dest(address.GetIP(),address.GetPort()); + int status = destinations.AddElement(dest); + + MAINMUTEX_UNLOCK + return status; +} + +int RTPUDPv4Transmitter::DeleteDestination(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; + } + + RTPIPv4Address &address = (RTPIPv4Address &)addr; + RTPIPv4Destination dest(address.GetIP(),address.GetPort()); + int status = destinations.DeleteElement(dest); + + MAINMUTEX_UNLOCK + return status; +} + +void RTPUDPv4Transmitter::ClearDestinations() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (created) + destinations.Clear(); + MAINMUTEX_UNLOCK +} + +bool RTPUDPv4Transmitter::SupportsMulticasting() +{ + if (!init) + return false; + + MAINMUTEX_LOCK + + bool v; + + if (!created) + v = false; + else + v = supportsmulticasting; + + MAINMUTEX_UNLOCK + return v; +} + +#ifdef RTP_SUPPORT_IPV4MULTICAST + +int RTPUDPv4Transmitter::JoinMulticastGroup(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; + } + + const RTPIPv4Address &address = (const RTPIPv4Address &)addr; + uint32_t mcastIP = address.GetIP(); + + if (!RTPUDPV4TRANS_IS_MCASTADDR(mcastIP)) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTAMULTICASTADDRESS; + } + + status = multicastgroups.AddElement(mcastIP); + if (status >= 0) + { + RTPUDPV4TRANS_MCASTMEMBERSHIP(rtpsock,IP_ADD_MEMBERSHIP,mcastIP,status); + if (status != 0) + { + multicastgroups.DeleteElement(mcastIP); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP; + } + RTPUDPV4TRANS_MCASTMEMBERSHIP(rtcpsock,IP_ADD_MEMBERSHIP,mcastIP,status); + if (status != 0) + { + RTPUDPV4TRANS_MCASTMEMBERSHIP(rtpsock,IP_DROP_MEMBERSHIP,mcastIP,status); + multicastgroups.DeleteElement(mcastIP); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP; + } + } + MAINMUTEX_UNLOCK + return status; +} + +int RTPUDPv4Transmitter::LeaveMulticastGroup(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; + } + + const RTPIPv4Address &address = (const RTPIPv4Address &)addr; + uint32_t mcastIP = address.GetIP(); + + if (!RTPUDPV4TRANS_IS_MCASTADDR(mcastIP)) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTAMULTICASTADDRESS; + } + + status = multicastgroups.DeleteElement(mcastIP); + if (status >= 0) + { + RTPUDPV4TRANS_MCASTMEMBERSHIP(rtpsock,IP_DROP_MEMBERSHIP,mcastIP,status); + RTPUDPV4TRANS_MCASTMEMBERSHIP(rtcpsock,IP_DROP_MEMBERSHIP,mcastIP,status); + status = 0; + } + + MAINMUTEX_UNLOCK + return status; +} + +void RTPUDPv4Transmitter::LeaveAllMulticastGroups() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (created) + { + multicastgroups.GotoFirstElement(); + while (multicastgroups.HasCurrentElement()) + { + uint32_t mcastIP; + int status = 0; + + mcastIP = multicastgroups.GetCurrentElement(); + RTPUDPV4TRANS_MCASTMEMBERSHIP(rtpsock,IP_DROP_MEMBERSHIP,mcastIP,status); + RTPUDPV4TRANS_MCASTMEMBERSHIP(rtcpsock,IP_DROP_MEMBERSHIP,mcastIP,status); + multicastgroups.GotoNextElement(); + } + multicastgroups.Clear(); + } + MAINMUTEX_UNLOCK +} + +#else // no multicast support + +int RTPUDPv4Transmitter::JoinMulticastGroup(const RTPAddress &addr) +{ + return ERR_RTP_UDPV4TRANS_NOMULTICASTSUPPORT; +} + +int RTPUDPv4Transmitter::LeaveMulticastGroup(const RTPAddress &addr) +{ + return ERR_RTP_UDPV4TRANS_NOMULTICASTSUPPORT; +} + +void RTPUDPv4Transmitter::LeaveAllMulticastGroups() +{ +} + +#endif // RTP_SUPPORT_IPV4MULTICAST + +int RTPUDPv4Transmitter::SetReceiveMode(RTPTransmitter::ReceiveMode m) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (m != receivemode) + { + receivemode = m; + acceptignoreinfo.Clear(); + } + MAINMUTEX_UNLOCK + return 0; +} + +int RTPUDPv4Transmitter::AddToIgnoreList(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; + } + if (receivemode != RTPTransmitter::IgnoreSome) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE; + } + + const RTPIPv4Address &address = (const RTPIPv4Address &)addr; + status = ProcessAddAcceptIgnoreEntry(address.GetIP(),address.GetPort()); + + MAINMUTEX_UNLOCK + return status; +} + +int RTPUDPv4Transmitter::DeleteFromIgnoreList(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; + } + if (receivemode != RTPTransmitter::IgnoreSome) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE; + } + + const RTPIPv4Address &address = (const RTPIPv4Address &)addr; + status = ProcessDeleteAcceptIgnoreEntry(address.GetIP(),address.GetPort()); + + MAINMUTEX_UNLOCK + return status; +} + +void RTPUDPv4Transmitter::ClearIgnoreList() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (created && receivemode == RTPTransmitter::IgnoreSome) + ClearAcceptIgnoreInfo(); + MAINMUTEX_UNLOCK +} + +int RTPUDPv4Transmitter::AddToAcceptList(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; + } + if (receivemode != RTPTransmitter::AcceptSome) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE; + } + + const RTPIPv4Address &address = (const RTPIPv4Address &)addr; + status = ProcessAddAcceptIgnoreEntry(address.GetIP(),address.GetPort()); + + MAINMUTEX_UNLOCK + return status; +} + +int RTPUDPv4Transmitter::DeleteFromAcceptList(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv4Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; + } + if (receivemode != RTPTransmitter::AcceptSome) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE; + } + + const RTPIPv4Address &address = (const RTPIPv4Address &)addr; + status = ProcessDeleteAcceptIgnoreEntry(address.GetIP(),address.GetPort()); + + MAINMUTEX_UNLOCK + return status; +} + +void RTPUDPv4Transmitter::ClearAcceptList() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (created && receivemode == RTPTransmitter::AcceptSome) + ClearAcceptIgnoreInfo(); + MAINMUTEX_UNLOCK +} + +int RTPUDPv4Transmitter::SetMaximumPacketSize(size_t s) +{ + if (!init) + return ERR_RTP_UDPV4TRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_NOTCREATED; + } + if (s > RTPUDPV4TRANS_MAXPACKSIZE) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG; + } + maxpacksize = s; + MAINMUTEX_UNLOCK + return 0; +} + +bool RTPUDPv4Transmitter::NewDataAvailable() +{ + if (!init) + return false; + + MAINMUTEX_LOCK + + bool v; + + if (!created) + v = false; + else + { + if (rawpacketlist.empty()) + v = false; + else + v = true; + } + + MAINMUTEX_UNLOCK + return v; +} + +RTPRawPacket *RTPUDPv4Transmitter::GetNextPacket() +{ + if (!init) + return 0; + + MAINMUTEX_LOCK + + RTPRawPacket *p; + + if (!created) + { + MAINMUTEX_UNLOCK + return 0; + } + if (rawpacketlist.empty()) + { + MAINMUTEX_UNLOCK + return 0; + } + + p = *(rawpacketlist.begin()); + rawpacketlist.pop_front(); + + MAINMUTEX_UNLOCK + return p; +} + +// Here the private functions start... + +#ifdef RTP_SUPPORT_IPV4MULTICAST +bool RTPUDPv4Transmitter::SetMulticastTTL(uint8_t ttl) +{ + int ttl2,status; + + ttl2 = (int)ttl; + status = setsockopt(rtpsock,IPPROTO_IP,IP_MULTICAST_TTL,(const char *)&ttl2,sizeof(int)); + if (status != 0) + return false; + status = setsockopt(rtcpsock,IPPROTO_IP,IP_MULTICAST_TTL,(const char *)&ttl2,sizeof(int)); + if (status != 0) + return false; + return true; +} +#endif // RTP_SUPPORT_IPV4MULTICAST + +void RTPUDPv4Transmitter::FlushPackets() +{ + std::list::const_iterator it; + + for (it = rawpacketlist.begin() ; it != rawpacketlist.end() ; ++it) + RTPDelete(*it,GetMemoryManager()); + rawpacketlist.clear(); +} + +int RTPUDPv4Transmitter::PollSocket(bool rtp) +{ + RTPSOCKLENTYPE fromlen; + int recvlen; + char packetbuffer[RTPUDPV4TRANS_MAXPACKSIZE]; +#if (defined(WIN32) || defined(_WIN32_WCE)) + SOCKET sock; + unsigned long len; +#else + size_t len; + int sock; +#endif // WIN32 + struct sockaddr_in srcaddr; + + if (rtp) + sock = rtpsock; + else + sock = rtcpsock; + + len = 0; + RTPIOCTL(sock,FIONREAD,&len); + if (len <= 0) + return 0; + + while (len > 0) + { + RTPTime curtime = RTPTime::CurrentTime(); + fromlen = sizeof(struct sockaddr_in); + recvlen = recvfrom(sock,packetbuffer,RTPUDPV4TRANS_MAXPACKSIZE,0,(struct sockaddr *)&srcaddr,(socklen_t*)&fromlen); + if (recvlen > 0) + { + bool acceptdata; + + // got data, process it + if (receivemode == RTPTransmitter::AcceptAll) + acceptdata = true; + else + acceptdata = ShouldAcceptData(ntohl(srcaddr.sin_addr.s_addr),ntohs(srcaddr.sin_port)); + + if (acceptdata) + { + RTPRawPacket *pack; + RTPIPv4Address *addr; + uint8_t *datacopy; + + addr = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPADDRESS) RTPIPv4Address(ntohl(srcaddr.sin_addr.s_addr),ntohs(srcaddr.sin_port)); + if (addr == 0) + return ERR_RTP_OUTOFMEM; + datacopy = RTPNew(GetMemoryManager(),(rtp)?RTPMEM_TYPE_BUFFER_RECEIVEDRTPPACKET:RTPMEM_TYPE_BUFFER_RECEIVEDRTCPPACKET) uint8_t[recvlen]; + if (datacopy == 0) + { + RTPDelete(addr,GetMemoryManager()); + return ERR_RTP_OUTOFMEM; + } + memcpy(datacopy,packetbuffer,recvlen); + + pack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPRAWPACKET) RTPRawPacket(datacopy,recvlen,addr,curtime,rtp,GetMemoryManager()); + if (pack == 0) + { + RTPDelete(addr,GetMemoryManager()); + RTPDeleteByteArray(datacopy,GetMemoryManager()); + return ERR_RTP_OUTOFMEM; + } + rawpacketlist.push_back(pack); + } + } + len = 0; + RTPIOCTL(sock,FIONREAD,&len); + } + return 0; +} + +int RTPUDPv4Transmitter::ProcessAddAcceptIgnoreEntry(uint32_t ip,uint16_t port) +{ + acceptignoreinfo.GotoElement(ip); + if (acceptignoreinfo.HasCurrentElement()) // An entry for this IP address already exists + { + PortInfo *portinf = acceptignoreinfo.GetCurrentElement(); + + if (port == 0) // select all ports + { + portinf->all = true; + portinf->portlist.clear(); + } + else if (!portinf->all) + { + std::list::const_iterator it,begin,end; + + begin = portinf->portlist.begin(); + end = portinf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == port) // already in list + return 0; + } + portinf->portlist.push_front(port); + } + } + else // got to create an entry for this IP address + { + PortInfo *portinf; + int status; + + portinf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_ACCEPTIGNOREPORTINFO) PortInfo(); + if (port == 0) // select all ports + portinf->all = true; + else + portinf->portlist.push_front(port); + + status = acceptignoreinfo.AddElement(ip,portinf); + if (status < 0) + { + RTPDelete(portinf,GetMemoryManager()); + return status; + } + } + + return 0; +} + +void RTPUDPv4Transmitter::ClearAcceptIgnoreInfo() +{ + acceptignoreinfo.GotoFirstElement(); + while (acceptignoreinfo.HasCurrentElement()) + { + PortInfo *inf; + + inf = acceptignoreinfo.GetCurrentElement(); + RTPDelete(inf,GetMemoryManager()); + acceptignoreinfo.GotoNextElement(); + } + acceptignoreinfo.Clear(); +} + +int RTPUDPv4Transmitter::ProcessDeleteAcceptIgnoreEntry(uint32_t ip,uint16_t port) +{ + acceptignoreinfo.GotoElement(ip); + if (!acceptignoreinfo.HasCurrentElement()) + return ERR_RTP_UDPV4TRANS_NOSUCHENTRY; + + PortInfo *inf; + + inf = acceptignoreinfo.GetCurrentElement(); + if (port == 0) // delete all entries + { + inf->all = false; + inf->portlist.clear(); + } + else // a specific port was selected + { + if (inf->all) // currently, all ports are selected. Add the one to remove to the list + { + // we have to check if the list doesn't contain the port already + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == port) // already in list: this means we already deleted the entry + return ERR_RTP_UDPV4TRANS_NOSUCHENTRY; + } + inf->portlist.push_front(port); + } + else // check if we can find the port in the list + { + std::list::iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; ++it) + { + if (*it == port) // found it! + { + inf->portlist.erase(it); + return 0; + } + } + // didn't find it + return ERR_RTP_UDPV4TRANS_NOSUCHENTRY; + } + } + return 0; +} + +bool RTPUDPv4Transmitter::ShouldAcceptData(uint32_t srcip,uint16_t srcport) +{ + if (receivemode == RTPTransmitter::AcceptSome) + { + PortInfo *inf; + + acceptignoreinfo.GotoElement(srcip); + if (!acceptignoreinfo.HasCurrentElement()) + return false; + + inf = acceptignoreinfo.GetCurrentElement(); + if (!inf->all) // only accept the ones in the list + { + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == srcport) + return true; + } + return false; + } + else // accept all, except the ones in the list + { + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == srcport) + return false; + } + return true; + } + } + else // IgnoreSome + { + PortInfo *inf; + + acceptignoreinfo.GotoElement(srcip); + if (!acceptignoreinfo.HasCurrentElement()) + return true; + + inf = acceptignoreinfo.GetCurrentElement(); + if (!inf->all) // ignore the ports in the list + { + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == srcport) + return false; + } + return true; + } + else // ignore all, except the ones in the list + { + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == srcport) + return true; + } + return false; + } + } + return true; +} + +#if (defined(WIN32) || defined(_WIN32_WCE)) + +int RTPUDPv4Transmitter::CreateAbortDescriptors() +{ +#ifndef RTP_DISABLE_INTERRUPT + SOCKET listensock; + int size; + struct sockaddr_in addr; + + listensock = socket(PF_INET,SOCK_STREAM,0); + if (listensock == RTPSOCKERR) + return ERR_RTP_UDPV4TRANS_CANTCREATEABORTDESCRIPTORS; + + memset(&addr,0,sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + if (bind(listensock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) + { + RTPCLOSE(listensock); + return ERR_RTP_UDPV4TRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in)); + size = sizeof(struct sockaddr_in); + if (getsockname(listensock,(struct sockaddr*)&addr,&size) != 0) + { + RTPCLOSE(listensock); + return ERR_RTP_UDPV4TRANS_CANTCREATEABORTDESCRIPTORS; + } + + unsigned short connectport = ntohs(addr.sin_port); + + abortdesc[0] = socket(PF_INET,SOCK_STREAM,0); + if (abortdesc[0] == RTPSOCKERR) + { + RTPCLOSE(listensock); + return ERR_RTP_UDPV4TRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + if (bind(abortdesc[0],(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_UDPV4TRANS_CANTCREATEABORTDESCRIPTORS; + } + + if (listen(listensock,1) != 0) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_UDPV4TRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = htons(connectport); + + if (connect(abortdesc[0],(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_UDPV4TRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in)); + size = sizeof(struct sockaddr_in); + abortdesc[1] = accept(listensock,(struct sockaddr *)&addr,&size); + if (abortdesc[1] == RTPSOCKERR) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_UDPV4TRANS_CANTCREATEABORTDESCRIPTORS; + } + + // okay, got the connection, close the listening socket + + RTPCLOSE(listensock); +#endif + return 0; +} + +void RTPUDPv4Transmitter::DestroyAbortDescriptors() +{ +#ifndef RTP_DISABLE_INTERRUPT + RTPCLOSE(abortdesc[0]); + RTPCLOSE(abortdesc[1]); +#endif +} + +#else // in a non winsock environment we can use pipes + +int RTPUDPv4Transmitter::CreateAbortDescriptors() +{ +#ifndef RTP_DISABLE_INTERRUPT + if (pipe(abortdesc) < 0) + return ERR_RTP_UDPV4TRANS_CANTCREATEPIPE; +#endif + return 0; +} + +void RTPUDPv4Transmitter::DestroyAbortDescriptors() +{ + close(abortdesc[0]); + close(abortdesc[1]); +} + +#endif // WIN32 + +int RTPUDPv4Transmitter::CreateLocalIPList() +{ + // first try to obtain the list from the network interface info + + if (!GetLocalIPList_Interfaces()) + { + // If this fails, we'll have to depend on DNS info + GetLocalIPList_DNS(); + } + AddLoopbackAddress(); + return 0; +} + +#if (defined(WIN32) || defined(_WIN32_WCE)) + +bool RTPUDPv4Transmitter::GetLocalIPList_Interfaces() +{ + unsigned char buffer[RTPUDPV4TRANS_IFREQBUFSIZE]; + DWORD outputsize; + DWORD numaddresses,i; + SOCKET_ADDRESS_LIST *addrlist; + + if (WSAIoctl(rtpsock,SIO_ADDRESS_LIST_QUERY,NULL,0,&buffer,RTPUDPV4TRANS_IFREQBUFSIZE,&outputsize,NULL,NULL)) + return false; + + addrlist = (SOCKET_ADDRESS_LIST *)buffer; + numaddresses = addrlist->iAddressCount; + for (i = 0 ; i < numaddresses ; i++) + { + SOCKET_ADDRESS *sockaddr = &(addrlist->Address[i]); + if (sockaddr->iSockaddrLength == sizeof(struct sockaddr_in)) // IPv4 address + { + struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr->lpSockaddr; + + localIPs.push_back(ntohl(addr->sin_addr.s_addr)); + } + } + + if (localIPs.empty()) + return false; + + return true; +} + +#else // use either getifaddrs or ioctl + +#ifdef RTP_SUPPORT_IFADDRS + +bool RTPUDPv4Transmitter::GetLocalIPList_Interfaces() +{ + struct ifaddrs *addrs,*tmp; + + getifaddrs(&addrs); + tmp = addrs; + + while (tmp != 0) + { + if (tmp->ifa_addr != 0 && tmp->ifa_addr->sa_family == AF_INET) + { + struct sockaddr_in *inaddr = (struct sockaddr_in *)tmp->ifa_addr; + localIPs.push_back(ntohl(inaddr->sin_addr.s_addr)); + } + tmp = tmp->ifa_next; + } + + freeifaddrs(addrs); + + if (localIPs.empty()) + return false; + return true; +} + +#else // user ioctl + +bool RTPUDPv4Transmitter::GetLocalIPList_Interfaces() +{ + int status; + char buffer[RTPUDPV4TRANS_IFREQBUFSIZE]; + struct ifconf ifc; + struct ifreq *ifr; + struct sockaddr *sa; + char *startptr,*endptr; + int remlen; + + ifc.ifc_len = RTPUDPV4TRANS_IFREQBUFSIZE; + ifc.ifc_buf = buffer; + status = ioctl(rtpsock,SIOCGIFCONF,&ifc); + if (status < 0) + return false; + + startptr = (char *)ifc.ifc_req; + endptr = startptr + ifc.ifc_len; + remlen = ifc.ifc_len; + while((startptr < endptr) && remlen >= (int)sizeof(struct ifreq)) + { + ifr = (struct ifreq *)startptr; + sa = &(ifr->ifr_addr); +#ifdef RTP_HAVE_SOCKADDR_LEN + if (sa->sa_len <= sizeof(struct sockaddr)) + { + if (sa->sa_len == sizeof(struct sockaddr_in) && sa->sa_family == PF_INET) + { + uint32_t ip; + struct sockaddr_in *addr = (struct sockaddr_in *)sa; + + ip = ntohl(addr->sin_addr.s_addr); + localIPs.push_back(ip); + } + remlen -= sizeof(struct ifreq); + startptr += sizeof(struct ifreq); + } + else + { + int l = sa->sa_len-sizeof(struct sockaddr)+sizeof(struct ifreq); + + remlen -= l; + startptr += l; + } +#else // don't have sa_len in struct sockaddr + if (sa->sa_family == PF_INET) + { + uint32_t ip; + struct sockaddr_in *addr = (struct sockaddr_in *)sa; + + ip = ntohl(addr->sin_addr.s_addr); + localIPs.push_back(ip); + } + remlen -= sizeof(struct ifreq); + startptr += sizeof(struct ifreq); + +#endif // RTP_HAVE_SOCKADDR_LEN + } + + if (localIPs.empty()) + return false; + return true; +} + +#endif // RTP_SUPPORT_IFADDRS + +#endif // WIN32 + +void RTPUDPv4Transmitter::GetLocalIPList_DNS() +{ + struct hostent *he; + char name[1024]; + uint32_t ip; + bool done; + int i,j; + + gethostname(name,1023); + name[1023] = 0; + he = gethostbyname(name); + if (he == 0) + return; + + ip = 0; + i = 0; + done = false; + while (!done) + { + if (he->h_addr_list[i] == NULL) + done = true; + else + { + ip = 0; + for (j = 0 ; j < 4 ; j++) + ip |= ((uint32_t)((unsigned char)he->h_addr_list[i][j])<<((3-j)*8)); + localIPs.push_back(ip); + i++; + } + } +} + +void RTPUDPv4Transmitter::AbortWaitInternal() +{ +#ifndef RTP_DISABLE_INTERRUPT +#if (defined(WIN32) || defined(_WIN32_WCE)) + send(abortdesc[1],"*",1,0); +#else + if (write(abortdesc[1],"*",1)) + { + // To get rid of __wur related compiler warnings + } +#endif // WIN32 +#endif // RTP_DISABLE_INTERRUPT +} + +void RTPUDPv4Transmitter::AddLoopbackAddress() +{ + uint32_t loopbackaddr = (((uint32_t)127)<<24)|((uint32_t)1); + std::list::const_iterator it; + bool found = false; + + for (it = localIPs.begin() ; !found && it != localIPs.end() ; it++) + { + if (*it == loopbackaddr) + found = true; + } + + if (!found) + localIPs.push_back(loopbackaddr); +} + +#ifdef RTPDEBUG +void RTPUDPv4Transmitter::Dump() +{ + if (!init) + std::cout << "Not initialized" << std::endl; + else + { + MAINMUTEX_LOCK + + if (!created) + std::cout << "Not created" << std::endl; + else + { + char str[16]; + uint32_t ip; + std::list::const_iterator it; + + std::cout << "Portbase: " << portbase << std::endl; + std::cout << "RTP socket descriptor: " << rtpsock << std::endl; + std::cout << "RTCP socket descriptor: " << rtcpsock << std::endl; + ip = bindIP; + RTP_SNPRINTF(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF)); + std::cout << "Bind IP address: " << str << std::endl; + ip = mcastifaceIP; + RTP_SNPRINTF(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF)); + std::cout << "Multicast interface IP address: " << str << std::endl; + std::cout << "Local IP addresses:" << std::endl; + for (it = localIPs.begin() ; it != localIPs.end() ; it++) + { + ip = (*it); + RTP_SNPRINTF(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF)); + std::cout << " " << str << std::endl; + } + std::cout << "Multicast TTL: " << (int)multicastTTL << std::endl; + std::cout << "Receive mode: "; + switch (receivemode) + { + case RTPTransmitter::AcceptAll: + std::cout << "Accept all"; + break; + case RTPTransmitter::AcceptSome: + std::cout << "Accept some"; + break; + case RTPTransmitter::IgnoreSome: + std::cout << "Ignore some"; + } + std::cout << std::endl; + if (receivemode != RTPTransmitter::AcceptAll) + { + acceptignoreinfo.GotoFirstElement(); + while(acceptignoreinfo.HasCurrentElement()) + { + ip = acceptignoreinfo.GetCurrentKey(); + RTP_SNPRINTF(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF)); + PortInfo *pinfo = acceptignoreinfo.GetCurrentElement(); + std::cout << " " << str << ": "; + if (pinfo->all) + { + std::cout << "All ports"; + if (!pinfo->portlist.empty()) + std::cout << ", except "; + } + + std::list::const_iterator it; + + for (it = pinfo->portlist.begin() ; it != pinfo->portlist.end() ; ) + { + std::cout << (*it); + it++; + if (it != pinfo->portlist.end()) + std::cout << ", "; + } + std::cout << std::endl; + } + } + + std::cout << "Local host name: "; + if (localhostname == 0) + std::cout << "Not set"; + else + std::cout << localhostname; + std::cout << std::endl; + + std::cout << "List of destinations: "; + destinations.GotoFirstElement(); + if (destinations.HasCurrentElement()) + { + std::cout << std::endl; + do + { + std::cout << " " << destinations.GetCurrentElement().GetDestinationString() << std::endl; + destinations.GotoNextElement(); + } while (destinations.HasCurrentElement()); + } + else + std::cout << "Empty" << std::endl; + + std::cout << "Supports multicasting: " << ((supportsmulticasting)?"Yes":"No") << std::endl; +#ifdef RTP_SUPPORT_IPV4MULTICAST + std::cout << "List of multicast groups: "; + multicastgroups.GotoFirstElement(); + if (multicastgroups.HasCurrentElement()) + { + std::cout << std::endl; + do + { + ip = multicastgroups.GetCurrentElement(); + RTP_SNPRINTF(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF)); + std::cout << " " << str << std::endl; + multicastgroups.GotoNextElement(); + } while (multicastgroups.HasCurrentElement()); + } + else + std::cout << "Empty" << std::endl; +#endif // RTP_SUPPORT_IPV4MULTICAST + + std::cout << "Number of raw packets in queue: " << rawpacketlist.size() << std::endl; + std::cout << "Maximum allowed packet size: " << maxpacksize << std::endl; + } + + MAINMUTEX_UNLOCK + } +} +#endif // RTPDEBUG + +} // end namespace + diff --git a/src/libs/jrtplib/src/rtpudpv4transmitter.h b/src/libs/jrtplib/src/rtpudpv4transmitter.h new file mode 100644 index 00000000..23a8e34f --- /dev/null +++ b/src/libs/jrtplib/src/rtpudpv4transmitter.h @@ -0,0 +1,308 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpudpv4transmitter.h + */ + +#ifndef RTPUDPV4TRANSMITTER_H + +#define RTPUDPV4TRANSMITTER_H + +#include "rtpconfig.h" +#include "rtptransmitter.h" +#include "rtpipv4destination.h" +#include "rtphashtable.h" +#include "rtpkeyhashtable.h" +#include + +#ifdef RTP_SUPPORT_THREAD + #include +#endif // RTP_SUPPORT_THREAD + +#define RTPUDPV4TRANS_HASHSIZE 8317 +#define RTPUDPV4TRANS_DEFAULTPORTBASE 5000 + +#define RTPUDPV4TRANS_RTPRECEIVEBUFFER 32768 +#define RTPUDPV4TRANS_RTCPRECEIVEBUFFER 32768 +#define RTPUDPV4TRANS_RTPTRANSMITBUFFER 32768 +#define RTPUDPV4TRANS_RTCPTRANSMITBUFFER 32768 + +namespace jrtplib +{ + +/** Parameters for the UDP over IPv4 transmitter. */ +class JRTPLIB_IMPORTEXPORT RTPUDPv4TransmissionParams : public RTPTransmissionParams +{ +public: + RTPUDPv4TransmissionParams():RTPTransmissionParams(RTPTransmitter::IPv4UDPProto) { portbase = RTPUDPV4TRANS_DEFAULTPORTBASE; bindIP = 0; multicastTTL = 1; mcastifaceIP = 0; rtpsendbuf = RTPUDPV4TRANS_RTPTRANSMITBUFFER; rtprecvbuf= RTPUDPV4TRANS_RTPRECEIVEBUFFER; rtcpsendbuf = RTPUDPV4TRANS_RTCPTRANSMITBUFFER; rtcprecvbuf = RTPUDPV4TRANS_RTCPRECEIVEBUFFER; } + + /** Sets the IP address which is used to bind the sockets to \c ip. */ + void SetBindIP(uint32_t ip) { bindIP = ip; } + + /** Sets the multicast interface IP address. */ + void SetMulticastInterfaceIP(uint32_t ip) { mcastifaceIP = ip; } + + /** Sets the RTP portbase to \c pbase. This has to be an even number. */ + void SetPortbase(uint16_t pbase) { portbase = pbase; } + + /** Sets the multicast TTL to be used to \c mcastTTL. */ + void SetMulticastTTL(uint8_t mcastTTL) { multicastTTL = mcastTTL; } + + /** Passes a list of IP addresses which will be used as the local IP addresses. */ + void SetLocalIPList(std::list &iplist) { localIPs = iplist; } + + /** Clears the list of local IP addresses. + * Clears the list of local IP addresses. An empty list will make the transmission + * component itself determine the local IP addresses. + */ + void ClearLocalIPList() { localIPs.clear(); } + + /** Returns the IP address which will be used to bind the sockets. */ + uint32_t GetBindIP() const { return bindIP; } + + /** Returns the multicast interface IP address. */ + uint32_t GetMulticastInterfaceIP() const { return mcastifaceIP; } + + /** Returns the RTP portbase which will be used (default is 5000). */ + uint16_t GetPortbase() const { return portbase; } + + /** Returns the multicast TTL which will be used (default is 1). */ + uint8_t GetMulticastTTL() const { return multicastTTL; } + + /** Returns the list of local IP addresses. */ + const std::list &GetLocalIPList() const { return localIPs; } + + /** Sets the RTP socket's send buffer size. */ + void SetRTPSendBuffer(int s) { rtpsendbuf = s; } + + /** Sets the RTP socket's receive buffer size. */ + void SetRTPReceiveBuffer(int s) { rtprecvbuf = s; } + + /** Sets the RTCP socket's send buffer size. */ + void SetRTCPSendBuffer(int s) { rtcpsendbuf = s; } + + /** Sets the RTCP socket's receive buffer size. */ + void SetRTCPReceiveBuffer(int s) { rtcprecvbuf = s; } + + /** Returns the RTP socket's send buffer size. */ + int GetRTPSendBuffer() const { return rtpsendbuf; } + + /** Returns the RTP socket's receive buffer size. */ + int GetRTPReceiveBuffer() const { return rtprecvbuf; } + + /** Returns the RTCP socket's send buffer size. */ + int GetRTCPSendBuffer() const { return rtcpsendbuf; } + + /** Returns the RTCP socket's receive buffer size. */ + int GetRTCPReceiveBuffer() const { return rtcprecvbuf; } +private: + uint16_t portbase; + uint32_t bindIP, mcastifaceIP; + std::list localIPs; + uint8_t multicastTTL; + int rtpsendbuf, rtprecvbuf; + int rtcpsendbuf, rtcprecvbuf; +}; + +/** Additional information about the UDP over IPv4 transmitter. */ +class JRTPLIB_IMPORTEXPORT RTPUDPv4TransmissionInfo : public RTPTransmissionInfo +{ +public: +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + RTPUDPv4TransmissionInfo(std::list iplist,int rtpsock,int rtcpsock) : RTPTransmissionInfo(RTPTransmitter::IPv4UDPProto) +#else + RTPUDPv4TransmissionInfo(std::list iplist,SOCKET rtpsock,SOCKET rtcpsock) : RTPTransmissionInfo(RTPTransmitter::IPv4UDPProto) +#endif // WIN32 + { localIPlist = iplist; rtpsocket = rtpsock; rtcpsocket = rtcpsock; } + + ~RTPUDPv4TransmissionInfo() { } + + /** Returns the list of IPv4 addresses the transmitter considers to be the local IP addresses. */ + std::list GetLocalIPList() const { return localIPlist; } +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + /** Returns the socket descriptor used for receiving and transmitting RTP packets. */ + int GetRTPSocket() const { return rtpsocket; } + + /** Returns the socket descriptor used for receiving and transmitting RTCP packets. */ + int GetRTCPSocket() const { return rtcpsocket; } +#else + SOCKET GetRTPSocket() const { return rtpsocket; } + SOCKET GetRTCPSocket() const { return rtcpsocket; } +#endif // WIN32 +private: + std::list localIPlist; +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + int rtpsocket,rtcpsocket; +#else + SOCKET rtpsocket,rtcpsocket; +#endif // WIN32 +}; + +class JRTPLIB_IMPORTEXPORT RTPUDPv4Trans_GetHashIndex_IPv4Dest +{ +public: + static int GetIndex(const RTPIPv4Destination &d) { return d.GetIP()%RTPUDPV4TRANS_HASHSIZE; } +}; + +class JRTPLIB_IMPORTEXPORT RTPUDPv4Trans_GetHashIndex_uint32_t +{ +public: + static int GetIndex(const uint32_t &k) { return k%RTPUDPV4TRANS_HASHSIZE; } +}; + +#define RTPUDPV4TRANS_HEADERSIZE (20+8) + +/** An UDP over IPv4 transmission component. + * This class inherits the RTPTransmitter interface and implements a transmission component + * which uses UDP over IPv4 to send and receive RTP and RTCP data. The component's parameters + * are described by the class RTPUDPv4TransmissionParams. The functions which have an RTPAddress + * argument require an argument of RTPIPv4Address. The GetTransmissionInfo member function + * returns an instance of type RTPUDPv4TransmissionInfo. + */ +class JRTPLIB_IMPORTEXPORT RTPUDPv4Transmitter : public RTPTransmitter +{ +public: + RTPUDPv4Transmitter(RTPMemoryManager *mgr); + ~RTPUDPv4Transmitter(); + + int Init(bool treadsafe); + int Create(size_t maxpacksize,const RTPTransmissionParams *transparams); + void Destroy(); + RTPTransmissionInfo *GetTransmissionInfo(); + void DeleteTransmissionInfo(RTPTransmissionInfo *inf); + + int GetLocalHostName(uint8_t *buffer,size_t *bufferlength); + bool ComesFromThisTransmitter(const RTPAddress *addr); + size_t GetHeaderOverhead() { return RTPUDPV4TRANS_HEADERSIZE; } + + int Poll(); + int WaitForIncomingData(const RTPTime &delay,bool *dataavailable = 0); + int AbortWait(); + + int SendRTPData(const void *data,size_t len); + int SendRTCPData(const void *data,size_t len); + + int AddDestination(const RTPAddress &addr); + int DeleteDestination(const RTPAddress &addr); + void ClearDestinations(); + + bool SupportsMulticasting(); + int JoinMulticastGroup(const RTPAddress &addr); + int LeaveMulticastGroup(const RTPAddress &addr); + void LeaveAllMulticastGroups(); + + int SetReceiveMode(RTPTransmitter::ReceiveMode m); + int AddToIgnoreList(const RTPAddress &addr); + int DeleteFromIgnoreList(const RTPAddress &addr); + void ClearIgnoreList(); + int AddToAcceptList(const RTPAddress &addr); + int DeleteFromAcceptList(const RTPAddress &addr); + void ClearAcceptList(); + int SetMaximumPacketSize(size_t s); + + bool NewDataAvailable(); + RTPRawPacket *GetNextPacket(); +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG +private: + int CreateLocalIPList(); + bool GetLocalIPList_Interfaces(); + void GetLocalIPList_DNS(); + void AddLoopbackAddress(); + void FlushPackets(); + int PollSocket(bool rtp); + int ProcessAddAcceptIgnoreEntry(uint32_t ip,uint16_t port); + int ProcessDeleteAcceptIgnoreEntry(uint32_t ip,uint16_t port); +#ifdef RTP_SUPPORT_IPV4MULTICAST + bool SetMulticastTTL(uint8_t ttl); +#endif // RTP_SUPPORT_IPV4MULTICAST + bool ShouldAcceptData(uint32_t srcip,uint16_t srcport); + void ClearAcceptIgnoreInfo(); + + bool init; + bool created; + bool waitingfordata; +#if (defined(WIN32) || defined(_WIN32_WCE)) + SOCKET rtpsock,rtcpsock; +#else // not using winsock + int rtpsock,rtcpsock; +#endif // WIN32 + uint32_t bindIP, mcastifaceIP; + std::list localIPs; + uint16_t portbase; + uint8_t multicastTTL; + RTPTransmitter::ReceiveMode receivemode; + + uint8_t *localhostname; + size_t localhostnamelength; + + RTPHashTable destinations; +#ifdef RTP_SUPPORT_IPV4MULTICAST + RTPHashTable multicastgroups; +#endif // RTP_SUPPORT_IPV4MULTICAST + std::list rawpacketlist; + + bool supportsmulticasting; + size_t maxpacksize; + + class PortInfo + { + public: + PortInfo() { all = false; } + + bool all; + std::list portlist; + }; + + RTPKeyHashTable acceptignoreinfo; + + // notification descriptors for AbortWait (0 is for reading, 1 for writing) +#if (defined(WIN32) || defined(_WIN32_WCE)) + SOCKET abortdesc[2]; +#else + int abortdesc[2]; +#endif // WIN32 + int CreateAbortDescriptors(); + void DestroyAbortDescriptors(); + void AbortWaitInternal(); +#ifdef RTP_SUPPORT_THREAD + jthread::JMutex mainmutex,waitmutex; + int threadsafe; +#endif // RTP_SUPPORT_THREAD +}; + +} // end namespace + +#endif // RTPUDPV4TRANSMITTER_H + diff --git a/src/libs/jrtplib/src/rtpudpv6transmitter.cpp b/src/libs/jrtplib/src/rtpudpv6transmitter.cpp new file mode 100644 index 00000000..c5b70ec6 --- /dev/null +++ b/src/libs/jrtplib/src/rtpudpv6transmitter.cpp @@ -0,0 +1,1924 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +#include "rtpudpv6transmitter.h" + +#ifdef RTP_SUPPORT_IPV6 + +#include "rtprawpacket.h" +#include "rtpipv6address.h" +#include "rtptimeutilities.h" +#include "rtpdefines.h" +#include +#if (defined(WIN32) || defined(_WIN32_WCE)) + #define RTPSOCKERR INVALID_SOCKET + #define RTPCLOSE(x) closesocket(x) + #define RTPSOCKLENTYPE int + #define RTPIOCTL ioctlsocket +#else // not Win32 + #include + #include + #include + #include + #include + #include + #include + #include + + #ifdef RTP_HAVE_SYS_FILIO + #include + #endif // RTP_HAVE_SYS_FILIO + #ifdef RTP_HAVE_SYS_SOCKIO + #include + #endif // RTP_HAVE_SYS_SOCKIO + #ifdef RTP_SUPPORT_IFADDRS + #include + #endif // RTP_SUPPORT_IFADDRS + + + #define RTPSOCKERR -1 + #define RTPCLOSE(x) close(x) + + #ifdef RTP_SOCKLENTYPE_UINT + #define RTPSOCKLENTYPE unsigned int + #else + #define RTPSOCKLENTYPE int + #endif // RTP_SOCKLENTYPE_UINT + + #define RTPIOCTL ioctl +#endif // WIN32 + +#include "rtpdebug.h" + +#define RTPUDPV6TRANS_MAXPACKSIZE 65535 +#define RTPUDPV6TRANS_IFREQBUFSIZE 8192 + +#define RTPUDPV6TRANS_IS_MCASTADDR(x) (x.s6_addr[0] == 0xFF) + +#define RTPUDPV6TRANS_MCASTMEMBERSHIP(socket,type,mcastip,status) {\ + struct ipv6_mreq mreq;\ + \ + mreq.ipv6mr_multiaddr = mcastip;\ + mreq.ipv6mr_interface = mcastifidx;\ + status = setsockopt(socket,IPPROTO_IPV6,type,(const char *)&mreq,sizeof(struct ipv6_mreq));\ + } +#ifdef RTP_SUPPORT_THREAD + #define MAINMUTEX_LOCK { if (threadsafe) mainmutex.Lock(); } + #define MAINMUTEX_UNLOCK { if (threadsafe) mainmutex.Unlock(); } + #define WAITMUTEX_LOCK { if (threadsafe) waitmutex.Lock(); } + #define WAITMUTEX_UNLOCK { if (threadsafe) waitmutex.Unlock(); } +#else + #define MAINMUTEX_LOCK + #define MAINMUTEX_UNLOCK + #define WAITMUTEX_LOCK + #define WAITMUTEX_UNLOCK +#endif // RTP_SUPPORT_THREAD + +inline bool operator==(const in6_addr &ip1,const in6_addr &ip2) +{ + if (memcmp(&ip1,&ip2,sizeof(in6_addr)) == 0) + return true; + return false; +} + +namespace jrtplib +{ + +RTPUDPv6Transmitter::RTPUDPv6Transmitter(RTPMemoryManager *mgr) : RTPTransmitter(mgr), + destinations(GetMemoryManager(),RTPMEM_TYPE_CLASS_DESTINATIONLISTHASHELEMENT), + //multicastgroups(GetMemoryManager(),RTPMEM_TYPE_CLASS_MULTICASTHASHELEMENT), + acceptignoreinfo(GetMemoryManager(),RTPMEM_TYPE_CLASS_ACCEPTIGNOREHASHELEMENT) +{ + created = false; + init = false; +#if (defined(WIN32) || defined(_WIN32_WCE)) + timeinit.Dummy(); +#endif // WIN32 || _WIN32_WCE +} + +RTPUDPv6Transmitter::~RTPUDPv6Transmitter() +{ + Destroy(); +} + +int RTPUDPv6Transmitter::Init(bool tsafe) +{ + if (init) + return ERR_RTP_UDPV6TRANS_ALREADYINIT; + +#ifdef RTP_SUPPORT_THREAD + threadsafe = tsafe; + if (threadsafe) + { + int status; + + status = mainmutex.Init(); + if (status < 0) + return ERR_RTP_UDPV6TRANS_CANTINITMUTEX; + status = waitmutex.Init(); + if (status < 0) + return ERR_RTP_UDPV6TRANS_CANTINITMUTEX; + } +#else + if (tsafe) + return ERR_RTP_NOTHREADSUPPORT; +#endif // RTP_SUPPORT_THREAD + + init = true; + return 0; +} + +int RTPUDPv6Transmitter::Create(size_t maximumpacketsize,const RTPTransmissionParams *transparams) +{ + const RTPUDPv6TransmissionParams *params,defaultparams; + struct sockaddr_in6 addr; + RTPSOCKLENTYPE size; + int status; + + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_ALREADYCREATED; + } + + // Obtain transmission parameters + + if (transparams == 0) + params = &defaultparams; + else + { + if (transparams->GetTransmissionProtocol() != RTPTransmitter::IPv6UDPProto) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_ILLEGALPARAMETERS; + } + params = (const RTPUDPv6TransmissionParams *)transparams; + } + + // Check if portbase is even + if (params->GetPortbase()%2 != 0) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_PORTBASENOTEVEN; + } + + // create sockets + + rtpsock = socket(PF_INET6,SOCK_DGRAM,0); + if (rtpsock == RTPSOCKERR) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_CANTCREATESOCKET; + } + rtcpsock = socket(PF_INET6,SOCK_DGRAM,0); + if (rtcpsock == RTPSOCKERR) + { + RTPCLOSE(rtpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_CANTCREATESOCKET; + } + + // set socket buffer sizes + + size = params->GetRTPReceiveBuffer(); + if (setsockopt(rtpsock,SOL_SOCKET,SO_RCVBUF,(const char *)&size,sizeof(int)) != 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_CANTSETRTPRECEIVEBUF; + } + size = params->GetRTPSendBuffer(); + if (setsockopt(rtpsock,SOL_SOCKET,SO_SNDBUF,(const char *)&size,sizeof(int)) != 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_CANTSETRTPTRANSMITBUF; + } + size = params->GetRTCPReceiveBuffer(); + if (setsockopt(rtcpsock,SOL_SOCKET,SO_RCVBUF,(const char *)&size,sizeof(int)) != 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_CANTSETRTCPRECEIVEBUF; + } + size = params->GetRTCPSendBuffer(); + if (setsockopt(rtcpsock,SOL_SOCKET,SO_SNDBUF,(const char *)&size,sizeof(int)) != 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_CANTSETRTCPTRANSMITBUF; + } + + // bind sockets + + bindIP = params->GetBindIP(); + mcastifidx = params->GetMulticastInterfaceIndex(); + + memset(&addr,0,sizeof(struct sockaddr_in6)); + addr.sin6_family = AF_INET6; + addr.sin6_port = htons(params->GetPortbase()); + addr.sin6_addr = bindIP; + if (bind(rtpsock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in6)) != 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_CANTBINDRTPSOCKET; + } + memset(&addr,0,sizeof(struct sockaddr_in6)); + addr.sin6_family = AF_INET6; + addr.sin6_port = htons(params->GetPortbase()+1); + addr.sin6_addr = bindIP; + if (bind(rtcpsock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in6)) != 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_CANTBINDRTCPSOCKET; + } + + // Try to obtain local IP addresses + + localIPs = params->GetLocalIPList(); + if (localIPs.empty()) // User did not provide list of local IP addresses, calculate them + { + int status; + + if ((status = CreateLocalIPList()) < 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return status; + } + +#ifdef RTPDEBUG + std::cout << "Found these local IP addresses:" << std::endl; + + std::list::const_iterator it; + + for (it = localIPs.begin() ; it != localIPs.end() ; it++) + { + RTPIPv6Address a(*it); + + std::cout << a.GetAddressString() << std::endl; + } +#endif // RTPDEBUG + } + +#ifdef RTP_SUPPORT_IPV6MULTICAST + if (SetMulticastTTL(params->GetMulticastTTL())) + supportsmulticasting = true; + else + supportsmulticasting = false; +#else // no multicast support enabled + supportsmulticasting = false; +#endif // RTP_SUPPORT_IPV6MULTICAST + + if ((status = CreateAbortDescriptors()) < 0) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + MAINMUTEX_UNLOCK + return status; + } + + if (maximumpacketsize > RTPUDPV6TRANS_MAXPACKSIZE) + { + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + DestroyAbortDescriptors(); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_SPECIFIEDSIZETOOBIG; + } + + maxpacksize = maximumpacketsize; + portbase = params->GetPortbase(); + multicastTTL = params->GetMulticastTTL(); + receivemode = RTPTransmitter::AcceptAll; + + localhostname = 0; + localhostnamelength = 0; + + waitingfordata = false; + created = true; + MAINMUTEX_UNLOCK + return 0; +} + +void RTPUDPv6Transmitter::Destroy() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK; + return; + } + + if (localhostname) + { + RTPDeleteByteArray(localhostname,GetMemoryManager()); + localhostname = 0; + localhostnamelength = 0; + } + + RTPCLOSE(rtpsock); + RTPCLOSE(rtcpsock); + destinations.Clear(); +#ifdef RTP_SUPPORT_IPV6MULTICAST + multicastgroups.Clear(); +#endif // RTP_SUPPORT_IPV6MULTICAST + FlushPackets(); + ClearAcceptIgnoreInfo(); + localIPs.clear(); + created = false; + + if (waitingfordata) + { + AbortWaitInternal(); + DestroyAbortDescriptors(); + MAINMUTEX_UNLOCK + WAITMUTEX_LOCK // to make sure that the WaitForIncomingData function ended + WAITMUTEX_UNLOCK + } + else + DestroyAbortDescriptors(); + + MAINMUTEX_UNLOCK +} + +RTPTransmissionInfo *RTPUDPv6Transmitter::GetTransmissionInfo() +{ + if (!init) + return 0; + + MAINMUTEX_LOCK + RTPTransmissionInfo *tinf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPTRANSMISSIONINFO) RTPUDPv6TransmissionInfo(localIPs,rtpsock,rtcpsock); + MAINMUTEX_UNLOCK + return tinf; +} + +void RTPUDPv6Transmitter::DeleteTransmissionInfo(RTPTransmissionInfo *i) +{ + if (!init) + return; + + RTPDelete(i, GetMemoryManager()); +} + +int RTPUDPv6Transmitter::GetLocalHostName(uint8_t *buffer,size_t *bufferlength) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + + if (localhostname == 0) + { + if (localIPs.empty()) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOLOCALIPS; + } + + std::list::const_iterator it; + std::list hostnames; + + for (it = localIPs.begin() ; it != localIPs.end() ; it++) + { + bool founddouble = false; + bool foundentry = true; + + while (!founddouble && foundentry) + { + struct hostent *he; + in6_addr ip = (*it); + + he = gethostbyaddr((char *)&ip,sizeof(in6_addr),AF_INET6); + if (he != 0) + { + std::string hname = std::string(he->h_name); + std::list::const_iterator it; + + for (it = hostnames.begin() ; !founddouble && it != hostnames.end() ; it++) + if ((*it) == hname) + founddouble = true; + + if (!founddouble) + hostnames.push_back(hname); + + int i = 0; + while (!founddouble && he->h_aliases[i] != 0) + { + std::string hname = std::string(he->h_aliases[i]); + + for (it = hostnames.begin() ; !founddouble && it != hostnames.end() ; it++) + if ((*it) == hname) + founddouble = true; + + if (!founddouble) + { + hostnames.push_back(hname); + i++; + } + } + } + else + foundentry = false; + } + } + + bool found = false; + + if (!hostnames.empty()) // try to select the most appropriate hostname + { + std::list::const_iterator it; + + hostnames.sort(); + for (it = hostnames.begin() ; !found && it != hostnames.end() ; it++) + { + if ((*it).find('.') != std::string::npos) + { + found = true; + localhostnamelength = (*it).length(); + localhostname = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) uint8_t [localhostnamelength+1]; + if (localhostname == 0) + { + MAINMUTEX_UNLOCK + return ERR_RTP_OUTOFMEM; + } + memcpy(localhostname,(*it).c_str(),localhostnamelength); + localhostname[localhostnamelength] = 0; + } + } + } + + if (!found) // use an IP address + { + in6_addr ip; + int len; + char str[48]; + uint16_t ip16[8]; + int i,j; + + it = localIPs.begin(); + ip = (*it); + + for (i = 0,j = 0 ; j < 8 ; j++,i += 2) + { + ip16[j] = (((uint16_t)ip.s6_addr[i])<<8); + ip16[j] |= ((uint16_t)ip.s6_addr[i+1]); + } + + RTP_SNPRINTF(str,48,"%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X",(int)ip16[0],(int)ip16[1],(int)ip16[2],(int)ip16[3],(int)ip16[4],(int)ip16[5],(int)ip16[6],(int)ip16[7]); + len = strlen(str); + + localhostnamelength = len; + localhostname = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) uint8_t [localhostnamelength+1]; + if (localhostname == 0) + { + MAINMUTEX_UNLOCK + return ERR_RTP_OUTOFMEM; + } + memcpy(localhostname,str,localhostnamelength); + localhostname[localhostnamelength] = 0; + } + } + + if ((*bufferlength) < localhostnamelength) + { + *bufferlength = localhostnamelength; // tell the application the required size of the buffer + MAINMUTEX_UNLOCK + return ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL; + } + + memcpy(buffer,localhostname,localhostnamelength); + *bufferlength = localhostnamelength; + + MAINMUTEX_UNLOCK + return 0; +} + +bool RTPUDPv6Transmitter::ComesFromThisTransmitter(const RTPAddress *addr) +{ + if (!init) + return false; + + if (addr == 0) + return false; + + MAINMUTEX_LOCK + + bool v; + + if (created && addr->GetAddressType() == RTPAddress::IPv6Address) + { + const RTPIPv6Address *addr2 = (const RTPIPv6Address *)addr; + bool found = false; + std::list::const_iterator it; + + it = localIPs.begin(); + while (!found && it != localIPs.end()) + { + in6_addr itip = *it; + in6_addr addrip = addr2->GetIP(); + if (memcmp(&addrip,&itip,sizeof(in6_addr)) == 0) + found = true; + else + ++it; + } + + if (!found) + v = false; + else + { + if (addr2->GetPort() == portbase) // check for RTP port + v = true; + else if (addr2->GetPort() == (portbase+1)) // check for RTCP port + v = true; + else + v = false; + } + } + else + v = false; + + MAINMUTEX_UNLOCK + return v; +} + +int RTPUDPv6Transmitter::Poll() +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + int status; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + status = PollSocket(true); // poll RTP socket + if (status >= 0) + status = PollSocket(false); // poll RTCP socket + MAINMUTEX_UNLOCK + return status; +} + + +int RTPUDPv6Transmitter::WaitForIncomingData(const RTPTime &delay,bool *dataavailable) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + + fd_set fdset; + struct timeval tv; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (waitingfordata) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_ALREADYWAITING; + } + + FD_ZERO(&fdset); + FD_SET(rtpsock,&fdset); + FD_SET(rtcpsock,&fdset); +#ifndef RTP_DISABLE_INTERRUPT + FD_SET(abortdesc[0],&fdset); +#endif + tv.tv_sec = delay.GetSeconds(); + tv.tv_usec = delay.GetMicroSeconds(); + + waitingfordata = true; + + WAITMUTEX_LOCK + MAINMUTEX_UNLOCK + + if (select(FD_SETSIZE,&fdset,0,0,&tv) < 0) + { + MAINMUTEX_LOCK + waitingfordata = false; + MAINMUTEX_UNLOCK + WAITMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_ERRORINSELECT; + } + + MAINMUTEX_LOCK + waitingfordata = false; + if (!created) // destroy called + { + MAINMUTEX_UNLOCK; + WAITMUTEX_UNLOCK + return 0; + } + + // if aborted, read from abort buffer +#ifndef RTP_DISABLE_INTERRUPT + if (FD_ISSET(abortdesc[0],&fdset)) + { +#if (defined(WIN32) || defined(_WIN32_WCE)) + char buf[1]; + + recv(abortdesc[0],buf,1,0); +#else + unsigned char buf[1]; + + if (read(abortdesc[0],buf,1)) + { + // To get rid of __wur related compiler warnings + } +#endif // WIN32 + } +#endif + + if (dataavailable != 0) + { + if (FD_ISSET(rtpsock,&fdset) || FD_ISSET(rtcpsock,&fdset)) + *dataavailable = true; + else + *dataavailable = false; + } + + MAINMUTEX_UNLOCK + WAITMUTEX_UNLOCK + return 0; +} + +int RTPUDPv6Transmitter::AbortWait() +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (!waitingfordata) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTWAITING; + } + + AbortWaitInternal(); + + MAINMUTEX_UNLOCK + return 0; +} + +int RTPUDPv6Transmitter::SendRTPData(const void *data,size_t len) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (len > maxpacksize) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_SPECIFIEDSIZETOOBIG; + } + + destinations.GotoFirstElement(); + while (destinations.HasCurrentElement()) + { + sendto(rtpsock,(const char *)data,len,0,(const struct sockaddr *)destinations.GetCurrentElement().GetRTPSockAddr(),sizeof(struct sockaddr_in6)); + destinations.GotoNextElement(); + } + + MAINMUTEX_UNLOCK + return 0; +} + +int RTPUDPv6Transmitter::SendRTCPData(const void *data,size_t len) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (len > maxpacksize) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_SPECIFIEDSIZETOOBIG; + } + + destinations.GotoFirstElement(); + while (destinations.HasCurrentElement()) + { + sendto(rtcpsock,(const char *)data,len,0,(const struct sockaddr *)destinations.GetCurrentElement().GetRTCPSockAddr(),sizeof(struct sockaddr_in6)); + destinations.GotoNextElement(); + } + + MAINMUTEX_UNLOCK + return 0; +} + +int RTPUDPv6Transmitter::AddDestination(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv6Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_INVALIDADDRESSTYPE; + } + + RTPIPv6Address &address = (RTPIPv6Address &)addr; + RTPIPv6Destination dest(address.GetIP(),address.GetPort()); + int status = destinations.AddElement(dest); + + MAINMUTEX_UNLOCK + return status; +} + +int RTPUDPv6Transmitter::DeleteDestination(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv6Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_INVALIDADDRESSTYPE; + } + + RTPIPv6Address &address = (RTPIPv6Address &)addr; + RTPIPv6Destination dest(address.GetIP(),address.GetPort()); + int status = destinations.DeleteElement(dest); + + MAINMUTEX_UNLOCK + return status; +} + +void RTPUDPv6Transmitter::ClearDestinations() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (created) + destinations.Clear(); + MAINMUTEX_UNLOCK +} + +bool RTPUDPv6Transmitter::SupportsMulticasting() +{ + if (!init) + return false; + + MAINMUTEX_LOCK + + bool v; + + if (!created) + v = false; + else + v = supportsmulticasting; + + MAINMUTEX_UNLOCK + return v; +} + +#ifdef RTP_SUPPORT_IPV6MULTICAST + +int RTPUDPv6Transmitter::JoinMulticastGroup(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv6Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_INVALIDADDRESSTYPE; + } + + const RTPIPv6Address &address = (const RTPIPv6Address &)addr; + in6_addr mcastIP = address.GetIP(); + + if (!RTPUDPV6TRANS_IS_MCASTADDR(mcastIP)) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTAMULTICASTADDRESS; + } + + status = multicastgroups.AddElement(mcastIP); + if (status >= 0) + { + RTPUDPV6TRANS_MCASTMEMBERSHIP(rtpsock,IPV6_JOIN_GROUP,mcastIP,status); + if (status != 0) + { + multicastgroups.DeleteElement(mcastIP); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_COULDNTJOINMULTICASTGROUP; + } + RTPUDPV6TRANS_MCASTMEMBERSHIP(rtcpsock,IPV6_JOIN_GROUP,mcastIP,status); + if (status != 0) + { + RTPUDPV6TRANS_MCASTMEMBERSHIP(rtpsock,IPV6_LEAVE_GROUP,mcastIP,status); + multicastgroups.DeleteElement(mcastIP); + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_COULDNTJOINMULTICASTGROUP; + } + } + MAINMUTEX_UNLOCK + return status; +} + +int RTPUDPv6Transmitter::LeaveMulticastGroup(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv6Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_INVALIDADDRESSTYPE; + } + + const RTPIPv6Address &address = (const RTPIPv6Address &)addr; + in6_addr mcastIP = address.GetIP(); + + if (!RTPUDPV6TRANS_IS_MCASTADDR(mcastIP)) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTAMULTICASTADDRESS; + } + + status = multicastgroups.DeleteElement(mcastIP); + if (status >= 0) + { + RTPUDPV6TRANS_MCASTMEMBERSHIP(rtpsock,IPV6_LEAVE_GROUP,mcastIP,status); + RTPUDPV6TRANS_MCASTMEMBERSHIP(rtcpsock,IPV6_LEAVE_GROUP,mcastIP,status); + status = 0; + } + + MAINMUTEX_UNLOCK + return status; +} + +void RTPUDPv6Transmitter::LeaveAllMulticastGroups() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (created) + { + multicastgroups.GotoFirstElement(); + while (multicastgroups.HasCurrentElement()) + { + in6_addr mcastIP; + int status = 0; + + mcastIP = multicastgroups.GetCurrentElement(); + RTPUDPV6TRANS_MCASTMEMBERSHIP(rtpsock,IPV6_LEAVE_GROUP,mcastIP,status); + RTPUDPV6TRANS_MCASTMEMBERSHIP(rtcpsock,IPV6_LEAVE_GROUP,mcastIP,status); + multicastgroups.GotoNextElement(); + } + multicastgroups.Clear(); + } + MAINMUTEX_UNLOCK +} + +#else // no multicast support + +int RTPUDPv6Transmitter::JoinMulticastGroup(const RTPAddress &addr) +{ + return ERR_RTP_UDPV6TRANS_NOMULTICASTSUPPORT; +} + +int RTPUDPv6Transmitter::LeaveMulticastGroup(const RTPAddress &addr) +{ + return ERR_RTP_UDPV6TRANS_NOMULTICASTSUPPORT; +} + +void RTPUDPv6Transmitter::LeaveAllMulticastGroups() +{ +} + +#endif // RTP_SUPPORT_IPV6MULTICAST + +int RTPUDPv6Transmitter::SetReceiveMode(RTPTransmitter::ReceiveMode m) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (m != receivemode) + { + receivemode = m; + acceptignoreinfo.Clear(); + } + MAINMUTEX_UNLOCK + return 0; +} + +int RTPUDPv6Transmitter::AddToIgnoreList(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv6Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_INVALIDADDRESSTYPE; + } + if (receivemode != RTPTransmitter::IgnoreSome) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_DIFFERENTRECEIVEMODE; + } + + const RTPIPv6Address &address = (const RTPIPv6Address &)addr; + status = ProcessAddAcceptIgnoreEntry(address.GetIP(),address.GetPort()); + + MAINMUTEX_UNLOCK + return status; +} + +int RTPUDPv6Transmitter::DeleteFromIgnoreList(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv6Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_INVALIDADDRESSTYPE; + } + if (receivemode != RTPTransmitter::IgnoreSome) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_DIFFERENTRECEIVEMODE; + } + + const RTPIPv6Address &address = (const RTPIPv6Address &)addr; + status = ProcessDeleteAcceptIgnoreEntry(address.GetIP(),address.GetPort()); + + MAINMUTEX_UNLOCK + return status; +} + +void RTPUDPv6Transmitter::ClearIgnoreList() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (created && receivemode == RTPTransmitter::IgnoreSome) + ClearAcceptIgnoreInfo(); + MAINMUTEX_UNLOCK +} + +int RTPUDPv6Transmitter::AddToAcceptList(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv6Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_INVALIDADDRESSTYPE; + } + if (receivemode != RTPTransmitter::AcceptSome) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_DIFFERENTRECEIVEMODE; + } + + const RTPIPv6Address &address = (const RTPIPv6Address &)addr; + status = ProcessAddAcceptIgnoreEntry(address.GetIP(),address.GetPort()); + + MAINMUTEX_UNLOCK + return status; +} + +int RTPUDPv6Transmitter::DeleteFromAcceptList(const RTPAddress &addr) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + + int status; + + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (addr.GetAddressType() != RTPAddress::IPv6Address) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_INVALIDADDRESSTYPE; + } + if (receivemode != RTPTransmitter::AcceptSome) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_DIFFERENTRECEIVEMODE; + } + + const RTPIPv6Address &address = (const RTPIPv6Address &)addr; + status = ProcessDeleteAcceptIgnoreEntry(address.GetIP(),address.GetPort()); + + MAINMUTEX_UNLOCK + return status; +} + +void RTPUDPv6Transmitter::ClearAcceptList() +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (created && receivemode == RTPTransmitter::AcceptSome) + ClearAcceptIgnoreInfo(); + MAINMUTEX_UNLOCK +} + +int RTPUDPv6Transmitter::SetMaximumPacketSize(size_t s) +{ + if (!init) + return ERR_RTP_UDPV6TRANS_NOTINIT; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_NOTCREATED; + } + if (s > RTPUDPV6TRANS_MAXPACKSIZE) + { + MAINMUTEX_UNLOCK + return ERR_RTP_UDPV6TRANS_SPECIFIEDSIZETOOBIG; + } + maxpacksize = s; + MAINMUTEX_UNLOCK + return 0; +} + +bool RTPUDPv6Transmitter::NewDataAvailable() +{ + if (!init) + return false; + + MAINMUTEX_LOCK + + bool v; + + if (!created) + v = false; + else + { + if (rawpacketlist.empty()) + v = false; + else + v = true; + } + + MAINMUTEX_UNLOCK + return v; +} + +RTPRawPacket *RTPUDPv6Transmitter::GetNextPacket() +{ + if (!init) + return 0; + + MAINMUTEX_LOCK + + RTPRawPacket *p; + + if (!created) + { + MAINMUTEX_UNLOCK + return 0; + } + if (rawpacketlist.empty()) + { + MAINMUTEX_UNLOCK + return 0; + } + + p = *(rawpacketlist.begin()); + rawpacketlist.pop_front(); + + MAINMUTEX_UNLOCK + return p; +} + +// Here the private functions start... + + +#ifdef RTP_SUPPORT_IPV6MULTICAST +bool RTPUDPv6Transmitter::SetMulticastTTL(uint8_t ttl) +{ + int ttl2,status; + + ttl2 = (int)ttl; + status = setsockopt(rtpsock,IPPROTO_IPV6,IPV6_MULTICAST_HOPS,(const char *)&ttl2,sizeof(int)); + if (status != 0) + return false; + status = setsockopt(rtcpsock,IPPROTO_IPV6,IPV6_MULTICAST_HOPS,(const char *)&ttl2,sizeof(int)); + if (status != 0) + return false; + return true; +} +#endif // RTP_SUPPORT_IPV6MULTICAST + + +void RTPUDPv6Transmitter::FlushPackets() +{ + std::list::const_iterator it; + + for (it = rawpacketlist.begin() ; it != rawpacketlist.end() ; ++it) + RTPDelete(*it,GetMemoryManager()); + rawpacketlist.clear(); +} + +int RTPUDPv6Transmitter::PollSocket(bool rtp) +{ + RTPSOCKLENTYPE fromlen; + int recvlen; + char packetbuffer[RTPUDPV6TRANS_MAXPACKSIZE]; +#if (defined(WIN32) || defined(_WIN32_WCE)) + SOCKET sock; + unsigned long len; +#else + size_t len; + int sock; +#endif // WIN32 + struct sockaddr_in6 srcaddr; + + if (rtp) + sock = rtpsock; + else + sock = rtcpsock; + + len = 0; + RTPIOCTL(sock,FIONREAD,&len); + if (len <= 0) + return 0; + + while (len > 0) + { + RTPTime curtime = RTPTime::CurrentTime(); + fromlen = sizeof(struct sockaddr_in6); + recvlen = recvfrom(sock,packetbuffer,RTPUDPV6TRANS_MAXPACKSIZE,0,(struct sockaddr *)&srcaddr,(socklen_t*)&fromlen); + if (recvlen > 0) + { + bool acceptdata; + + // got data, process it + if (receivemode == RTPTransmitter::AcceptAll) + acceptdata = true; + else + acceptdata = ShouldAcceptData(srcaddr.sin6_addr,ntohs(srcaddr.sin6_port)); + + if (acceptdata) + { + RTPRawPacket *pack; + RTPIPv6Address *addr; + uint8_t *datacopy; + + addr = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPADDRESS) RTPIPv6Address(srcaddr.sin6_addr,ntohs(srcaddr.sin6_port)); + if (addr == 0) + return ERR_RTP_OUTOFMEM; + datacopy = RTPNew(GetMemoryManager(),(rtp)?RTPMEM_TYPE_BUFFER_RECEIVEDRTPPACKET:RTPMEM_TYPE_BUFFER_RECEIVEDRTCPPACKET) uint8_t[recvlen]; + if (datacopy == 0) + { + RTPDelete(addr,GetMemoryManager()); + return ERR_RTP_OUTOFMEM; + } + memcpy(datacopy,packetbuffer,recvlen); + + pack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPRAWPACKET) RTPRawPacket(datacopy,recvlen,addr,curtime,rtp,GetMemoryManager()); + if (pack == 0) + { + RTPDelete(addr,GetMemoryManager()); + RTPDeleteByteArray(datacopy,GetMemoryManager()); + return ERR_RTP_OUTOFMEM; + } + rawpacketlist.push_back(pack); + } + } + len = 0; + RTPIOCTL(sock,FIONREAD,&len); + } + return 0; +} + +int RTPUDPv6Transmitter::ProcessAddAcceptIgnoreEntry(in6_addr ip,uint16_t port) +{ + acceptignoreinfo.GotoElement(ip); + if (acceptignoreinfo.HasCurrentElement()) // An entry for this IP address already exists + { + PortInfo *portinf = acceptignoreinfo.GetCurrentElement(); + + if (port == 0) // select all ports + { + portinf->all = true; + portinf->portlist.clear(); + } + else if (!portinf->all) + { + std::list::const_iterator it,begin,end; + + begin = portinf->portlist.begin(); + end = portinf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == port) // already in list + return 0; + } + portinf->portlist.push_front(port); + } + } + else // got to create an entry for this IP address + { + PortInfo *portinf; + int status; + + portinf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_ACCEPTIGNOREPORTINFO) PortInfo(); + if (port == 0) // select all ports + portinf->all = true; + else + portinf->portlist.push_front(port); + + status = acceptignoreinfo.AddElement(ip,portinf); + if (status < 0) + { + RTPDelete(portinf,GetMemoryManager()); + return status; + } + } + return 0; +} + +void RTPUDPv6Transmitter::ClearAcceptIgnoreInfo() +{ + acceptignoreinfo.GotoFirstElement(); + while (acceptignoreinfo.HasCurrentElement()) + { + PortInfo *inf; + + inf = acceptignoreinfo.GetCurrentElement(); + RTPDelete(inf,GetMemoryManager()); + acceptignoreinfo.GotoNextElement(); + } + acceptignoreinfo.Clear(); +} + +int RTPUDPv6Transmitter::ProcessDeleteAcceptIgnoreEntry(in6_addr ip,uint16_t port) +{ + acceptignoreinfo.GotoElement(ip); + if (!acceptignoreinfo.HasCurrentElement()) + return ERR_RTP_UDPV6TRANS_NOSUCHENTRY; + + PortInfo *inf; + + inf = acceptignoreinfo.GetCurrentElement(); + if (port == 0) // delete all entries + { + inf->all = false; + inf->portlist.clear(); + } + else // a specific port was selected + { + if (inf->all) // currently, all ports are selected. Add the one to remove to the list + { + // we have to check if the list doesn't contain the port already + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == port) // already in list: this means we already deleted the entry + return ERR_RTP_UDPV6TRANS_NOSUCHENTRY; + } + inf->portlist.push_front(port); + } + else // check if we can find the port in the list + { + std::list::iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; ++it) + { + if (*it == port) // found it! + { + inf->portlist.erase(it); + return 0; + } + } + // didn't find it + return ERR_RTP_UDPV6TRANS_NOSUCHENTRY; + } + } + return 0; +} + +bool RTPUDPv6Transmitter::ShouldAcceptData(in6_addr srcip,uint16_t srcport) +{ + if (receivemode == RTPTransmitter::AcceptSome) + { + PortInfo *inf; + + acceptignoreinfo.GotoElement(srcip); + if (!acceptignoreinfo.HasCurrentElement()) + return false; + + inf = acceptignoreinfo.GetCurrentElement(); + if (!inf->all) // only accept the ones in the list + { + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == srcport) + return true; + } + return false; + } + else // accept all, except the ones in the list + { + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == srcport) + return false; + } + return true; + } + } + else // IgnoreSome + { + PortInfo *inf; + + acceptignoreinfo.GotoElement(srcip); + if (!acceptignoreinfo.HasCurrentElement()) + return true; + + inf = acceptignoreinfo.GetCurrentElement(); + if (!inf->all) // ignore the ports in the list + { + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == srcport) + return false; + } + return true; + } + else // ignore all, except the ones in the list + { + std::list::const_iterator it,begin,end; + + begin = inf->portlist.begin(); + end = inf->portlist.end(); + for (it = begin ; it != end ; it++) + { + if (*it == srcport) + return true; + } + return false; + } + } + return true; +} + +#if (defined(WIN32) || defined(_WIN32_WCE)) + +int RTPUDPv6Transmitter::CreateAbortDescriptors() +{ +#ifndef RTP_DISABLE_INTERRUPT + SOCKET listensock; + int size; + struct sockaddr_in6 addr; + + listensock = socket(PF_INET6,SOCK_STREAM,0); + if (listensock == RTPSOCKERR) + return ERR_RTP_UDPV6TRANS_CANTCREATEABORTDESCRIPTORS; + + memset(&addr,0,sizeof(struct sockaddr_in6)); + addr.sin6_family = AF_INET6; + if (bind(listensock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in6)) != 0) + { + RTPCLOSE(listensock); + return ERR_RTP_UDPV6TRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in6)); + size = sizeof(struct sockaddr_in6); + if (getsockname(listensock,(struct sockaddr*)&addr,&size) != 0) + { + RTPCLOSE(listensock); + return ERR_RTP_UDPV6TRANS_CANTCREATEABORTDESCRIPTORS; + } + + unsigned short connectport = ntohs(addr.sin6_port); + + abortdesc[0] = socket(PF_INET6,SOCK_STREAM,0); + if (abortdesc[0] == RTPSOCKERR) + { + RTPCLOSE(listensock); + return ERR_RTP_UDPV6TRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in6)); + addr.sin6_family = AF_INET6; + if (bind(abortdesc[0],(struct sockaddr *)&addr,sizeof(struct sockaddr_in6)) != 0) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_UDPV6TRANS_CANTCREATEABORTDESCRIPTORS; + } + + if (listen(listensock,1) != 0) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_UDPV6TRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in6)); + addr.sin6_family = AF_INET6; + addr.sin6_addr = in6addr_loopback; + addr.sin6_port = htons(connectport); + + if (connect(abortdesc[0],(struct sockaddr *)&addr,sizeof(struct sockaddr_in6)) != 0) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_UDPV6TRANS_CANTCREATEABORTDESCRIPTORS; + } + + memset(&addr,0,sizeof(struct sockaddr_in6)); + size = sizeof(struct sockaddr_in6); + abortdesc[1] = accept(listensock,(struct sockaddr *)&addr,&size); + if (abortdesc[1] == RTPSOCKERR) + { + RTPCLOSE(listensock); + RTPCLOSE(abortdesc[0]); + return ERR_RTP_UDPV6TRANS_CANTCREATEABORTDESCRIPTORS; + } + + // okay, got the connection, close the listening socket + + RTPCLOSE(listensock); +#endif + + return 0; +} + +void RTPUDPv6Transmitter::DestroyAbortDescriptors() +{ +#ifndef RTP_DISABLE_INTERRUPT + RTPCLOSE(abortdesc[0]); + RTPCLOSE(abortdesc[1]); +#endif +} + +#else // in a non winsock environment we can use pipes + +int RTPUDPv6Transmitter::CreateAbortDescriptors() +{ +#ifndef RTP_DISABLE_INTERRUPT + if (pipe(abortdesc) < 0) + return ERR_RTP_UDPV6TRANS_CANTCREATEPIPE; +#endif + return 0; +} + +void RTPUDPv6Transmitter::DestroyAbortDescriptors() +{ +#ifndef RTP_DISABLE_INTERRUPT + close(abortdesc[0]); + close(abortdesc[1]); +#endif +} + +#endif // WIN32 + +int RTPUDPv6Transmitter::CreateLocalIPList() +{ + // first try to obtain the list from the network interface info + + if (!GetLocalIPList_Interfaces()) + { + // If this fails, we'll have to depend on DNS info + GetLocalIPList_DNS(); + } + AddLoopbackAddress(); + return 0; +} + +#if (defined(WIN32) || defined(_WIN32_WCE)) + +bool RTPUDPv6Transmitter::GetLocalIPList_Interfaces() +{ + unsigned char buffer[RTPUDPV6TRANS_IFREQBUFSIZE]; + DWORD outputsize; + DWORD numaddresses,i; + SOCKET_ADDRESS_LIST *addrlist; + + if (WSAIoctl(rtpsock,SIO_ADDRESS_LIST_QUERY,NULL,0,&buffer,RTPUDPV6TRANS_IFREQBUFSIZE,&outputsize,NULL,NULL)) + return false; + + addrlist = (SOCKET_ADDRESS_LIST *)buffer; + numaddresses = addrlist->iAddressCount; + for (i = 0 ; i < numaddresses ; i++) + { + SOCKET_ADDRESS *sockaddr = &(addrlist->Address[i]); + if (sockaddr->iSockaddrLength == sizeof(struct sockaddr_in6)) // IPv6 address + { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)sockaddr->lpSockaddr; + + localIPs.push_back(addr->sin6_addr); + } + } + + if (localIPs.empty()) + return false; + return true; +} + +#else + +#ifdef RTP_SUPPORT_IFADDRS + +bool RTPUDPv6Transmitter::GetLocalIPList_Interfaces() +{ + struct ifaddrs *addrs,*tmp; + + getifaddrs(&addrs); + tmp = addrs; + + while (tmp != 0) + { + if (tmp->ifa_addr != 0 && tmp->ifa_addr->sa_family == AF_INET6) + { + struct sockaddr_in6 *inaddr = (struct sockaddr_in6 *)tmp->ifa_addr; + localIPs.push_back(inaddr->sin6_addr); + } + tmp = tmp->ifa_next; + } + + freeifaddrs(addrs); + + if (localIPs.empty()) + return false; + return true; +} + +#else + +bool RTPUDPv6Transmitter::GetLocalIPList_Interfaces() +{ + return false; +} + +#endif // RTP_SUPPORT_IFADDRS + +#endif // WIN32 + +void RTPUDPv6Transmitter::GetLocalIPList_DNS() +{ + int status; + char name[1024]; + + gethostname(name,1023); + name[1023] = 0; + + struct addrinfo hints; + struct addrinfo *res,*tmp; + + memset(&hints,0,sizeof(struct addrinfo)); + hints.ai_family = AF_INET6; + hints.ai_socktype = 0; + hints.ai_protocol = 0; + + if ((status = getaddrinfo(name,0,&hints,&res)) != 0) + return; + + tmp = res; + while (tmp != 0) + { + if (tmp->ai_family == AF_INET6) + { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(tmp->ai_addr); + localIPs.push_back(addr->sin6_addr); + } + tmp = tmp->ai_next; + } + + freeaddrinfo(res); +} + + +void RTPUDPv6Transmitter::AbortWaitInternal() +{ +#ifndef RTP_DISABLE_INTERRUPT +#if (defined(WIN32) || defined(_WIN32_WCE)) + send(abortdesc[1],"*",1,0); +#else + if (write(abortdesc[1],"*",1)) + { + // To get rid of __wur related compiler warnings + } +#endif // WIN32 +#endif +} + + +void RTPUDPv6Transmitter::AddLoopbackAddress() +{ + std::list::const_iterator it; + bool found = false; + + for (it = localIPs.begin() ; !found && it != localIPs.end() ; it++) + { + if ((*it) == in6addr_loopback) + found = true; + } + + if (!found) + localIPs.push_back(in6addr_loopback); +} + +#ifdef RTPDEBUG +void RTPUDPv6Transmitter::Dump() +{ + if (!init) + std::cout << "Not initialized" << std::endl; + else + { + MAINMUTEX_LOCK + + if (!created) + std::cout << "Not created" << std::endl; + else + { + char str[48]; + in6_addr ip; + uint16_t ip16[8]; + std::list::const_iterator it; + int i,j; + + std::cout << "Portbase: " << portbase << std::endl; + std::cout << "RTP socket descriptor: " << rtpsock << std::endl; + std::cout << "RTCP socket descriptor: " << rtcpsock << std::endl; + ip = bindIP; + for (i = 0,j = 0 ; j < 8 ; j++,i += 2) { ip16[j] = (((uint16_t)ip.s6_addr[i])<<8); ip16[j] |= ((uint16_t)ip.s6_addr[i+1]); } + RTP_SNPRINTF(str,48,"%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X",(int)ip16[0],(int)ip16[1],(int)ip16[2],(int)ip16[3],(int)ip16[4],(int)ip16[5],(int)ip16[6],(int)ip16[7]); + std::cout << "Bind IP address: " << str << std::endl; + std::cout << "Multicast interface index: " << mcastifidx << std::endl; + std::cout << "Local IP addresses:" << std::endl; + for (it = localIPs.begin() ; it != localIPs.end() ; it++) + { + ip = (*it); + for (i = 0,j = 0 ; j < 8 ; j++,i += 2) { ip16[j] = (((uint16_t)ip.s6_addr[i])<<8); ip16[j] |= ((uint16_t)ip.s6_addr[i+1]); } + RTP_SNPRINTF(str,48,"%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X",(int)ip16[0],(int)ip16[1],(int)ip16[2],(int)ip16[3],(int)ip16[4],(int)ip16[5],(int)ip16[6],(int)ip16[7]); + std::cout << " " << str << std::endl; + } + std::cout << "Multicast TTL: " << (int)multicastTTL << std::endl; + std::cout << "Receive mode: "; + switch (receivemode) + { + case RTPTransmitter::AcceptAll: + std::cout << "Accept all"; + break; + case RTPTransmitter::AcceptSome: + std::cout << "Accept some"; + break; + case RTPTransmitter::IgnoreSome: + std::cout << "Ignore some"; + } + std::cout << std::endl; + if (receivemode != RTPTransmitter::AcceptAll) + { + acceptignoreinfo.GotoFirstElement(); + while(acceptignoreinfo.HasCurrentElement()) + { + ip = acceptignoreinfo.GetCurrentKey(); + for (i = 0,j = 0 ; j < 8 ; j++,i += 2) { ip16[j] = (((uint16_t)ip.s6_addr[i])<<8); ip16[j] |= ((uint16_t)ip.s6_addr[i+1]); } + RTP_SNPRINTF(str,48,"%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X",(int)ip16[0],(int)ip16[1],(int)ip16[2],(int)ip16[3],(int)ip16[4],(int)ip16[5],(int)ip16[6],(int)ip16[7]); + PortInfo *pinfo = acceptignoreinfo.GetCurrentElement(); + std::cout << " " << str << ": "; + if (pinfo->all) + { + std::cout << "All ports"; + if (!pinfo->portlist.empty()) + std::cout << ", except "; + } + + std::list::const_iterator it; + + for (it = pinfo->portlist.begin() ; it != pinfo->portlist.end() ; ) + { + std::cout << (*it); + it++; + if (it != pinfo->portlist.end()) + std::cout << ", "; + } + std::cout << std::endl; + } + } + + std::cout << "Local host name: "; + if (localhostname == 0) + std::cout << "Not set"; + else + std::cout << localhostname; + std::cout << std::endl; + + std::cout << "List of destinations: "; + destinations.GotoFirstElement(); + if (destinations.HasCurrentElement()) + { + std::cout << std::endl; + do + { + std::cout << " " << destinations.GetCurrentElement().GetDestinationString() << std::endl; + destinations.GotoNextElement(); + } while (destinations.HasCurrentElement()); + } + else + std::cout << "Empty" << std::endl; + + std::cout << "Supports multicasting: " << ((supportsmulticasting)?"Yes":"No") << std::endl; +#ifdef RTP_SUPPORT_IPV6MULTICAST + std::cout << "List of multicast groups: "; + multicastgroups.GotoFirstElement(); + if (multicastgroups.HasCurrentElement()) + { + std::cout << std::endl; + do + { + ip = multicastgroups.GetCurrentElement(); + for (i = 0,j = 0 ; j < 8 ; j++,i += 2) { ip16[j] = (((uint16_t)ip.s6_addr[i])<<8); ip16[j] |= ((uint16_t)ip.s6_addr[i+1]); } + RTP_SNPRINTF(str,48,"%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X",(int)ip16[0],(int)ip16[1],(int)ip16[2],(int)ip16[3],(int)ip16[4],(int)ip16[5],(int)ip16[6],(int)ip16[7]); + std::cout << " " << str << std::endl; + multicastgroups.GotoNextElement(); + } while (multicastgroups.HasCurrentElement()); + } + else + std::cout << "Empty" << std::endl; +#endif // RTP_SUPPORT_IPV6MULTICAST + + std::cout << "Number of raw packets in queue: " << rawpacketlist.size() << std::endl; + std::cout << "Maximum allowed packet size: " << maxpacksize << std::endl; + } + + MAINMUTEX_UNLOCK + } + +} +#endif // RTPDEBUG + +} // end namespace + +#endif // RTP_SUPPORT_IPV6 + diff --git a/src/libs/jrtplib/src/rtpudpv6transmitter.h b/src/libs/jrtplib/src/rtpudpv6transmitter.h new file mode 100644 index 00000000..21bb7ad2 --- /dev/null +++ b/src/libs/jrtplib/src/rtpudpv6transmitter.h @@ -0,0 +1,319 @@ +/* + + This file is a part of JRTPLIB + Copyright (c) 1999-2011 Jori Liesenborgs + + Contact: jori.liesenborgs@gmail.com + + This library was developed at the Expertise Centre for Digital Media + (http://www.edm.uhasselt.be), a research center of the Hasselt University + (http://www.uhasselt.be). The library is based upon work done for + my thesis at the School for Knowledge Technology (Belgium/The Netherlands). + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +*/ + +/** + * \file rtpudpv6transmitter.h + */ + +#ifndef RTPUDPV6TRANSMITTER_H + +#define RTPUDPV6TRANSMITTER_H + +#include "rtpconfig.h" + +#ifdef RTP_SUPPORT_IPV6 + +#include "rtptransmitter.h" +#include "rtpipv6destination.h" +#include "rtphashtable.h" +#include "rtpkeyhashtable.h" +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + #include +#endif // WIN32 +#include +#include + +#ifdef RTP_SUPPORT_THREAD + #include +#endif // RTP_SUPPORT_THREAD + +#define RTPUDPV6TRANS_HASHSIZE 8317 +#define RTPUDPV6TRANS_DEFAULTPORTBASE 5000 + +#define RTPUDPV6TRANS_RTPRECEIVEBUFFER 32768 +#define RTPUDPV6TRANS_RTCPRECEIVEBUFFER 32768 +#define RTPUDPV6TRANS_RTPTRANSMITBUFFER 32768 +#define RTPUDPV6TRANS_RTCPTRANSMITBUFFER 32768 + +namespace jrtplib +{ + +/** Parameters for the UDP over IPv6 transmitter. */ +class JRTPLIB_IMPORTEXPORT RTPUDPv6TransmissionParams : public RTPTransmissionParams +{ +public: + RTPUDPv6TransmissionParams():RTPTransmissionParams(RTPTransmitter::IPv6UDPProto) { portbase = RTPUDPV6TRANS_DEFAULTPORTBASE; for (int i = 0 ; i < 16 ; i++) bindIP.s6_addr[i] = 0; multicastTTL = 1; mcastifidx = 0; rtpsendbuf = RTPUDPV6TRANS_RTPTRANSMITBUFFER; rtprecvbuf= RTPUDPV6TRANS_RTPRECEIVEBUFFER; rtcpsendbuf = RTPUDPV6TRANS_RTCPTRANSMITBUFFER; rtcprecvbuf = RTPUDPV6TRANS_RTCPRECEIVEBUFFER; } + + /** Sets the IP address which is used to bind the sockets to \c ip. */ + void SetBindIP(in6_addr ip) { bindIP = ip; } + + /** Sets the multicast interface index. */ + void SetMulticastInterfaceIndex(unsigned int idx) { mcastifidx = idx; } + + /** Sets the RTP portbase to \c pbase. This has to be an even number. */ + void SetPortbase(uint16_t pbase) { portbase = pbase; } + + /** Sets the multicast TTL to be used to \c mcastTTL. */ + void SetMulticastTTL(uint8_t mcastTTL) { multicastTTL = mcastTTL; } + + /** Passes a list of IP addresses which will be used as the local IP addresses. */ + void SetLocalIPList(std::list &iplist) { localIPs = iplist; } + + /** Clears the list of local IP addresses. + * Clears the list of local IP addresses. An empty list will make the transmission component + * itself determine the local IP addresses. + */ + void ClearLocalIPList() { localIPs.clear(); } + + /** Returns the IP address which will be used to bind the sockets. */ + in6_addr GetBindIP() const { return bindIP; } + + /** Returns the multicast interface index. */ + unsigned int GetMulticastInterfaceIndex() const { return mcastifidx; } + + /** Returns the RTP portbase which will be used (default is 5000). */ + uint16_t GetPortbase() const { return portbase; } + + /** Returns the multicast TTL which will be used (default is 1). */ + uint8_t GetMulticastTTL() const { return multicastTTL; } + + /** Returns the list of local IP addresses. */ + const std::list &GetLocalIPList() const { return localIPs; } + + /** Sets the RTP socket's send buffer size. */ + void SetRTPSendBuffer(int s) { rtpsendbuf = s; } + + /** Sets the RTP socket's receive buffer size. */ + void SetRTPReceiveBuffer(int s) { rtprecvbuf = s; } + + /** Sets the RTCP socket's send buffer size. */ + void SetRTCPSendBuffer(int s) { rtcpsendbuf = s; } + + /** Sets the RTCP socket's receive buffer size. */ + void SetRTCPReceiveBuffer(int s) { rtcprecvbuf = s; } + + /** Returns the RTP socket's send buffer size. */ + int GetRTPSendBuffer() const { return rtpsendbuf; } + + /** Returns the RTP socket's receive buffer size. */ + int GetRTPReceiveBuffer() const { return rtprecvbuf; } + + /** Returns the RTCP socket's send buffer size. */ + int GetRTCPSendBuffer() const { return rtcpsendbuf; } + + /** Returns the RTCP socket's receive buffer size. */ + int GetRTCPReceiveBuffer() const { return rtcprecvbuf; } +private: + uint16_t portbase; + in6_addr bindIP; + unsigned int mcastifidx; + std::list localIPs; + uint8_t multicastTTL; + int rtpsendbuf, rtprecvbuf; + int rtcpsendbuf, rtcprecvbuf; +}; + +/** Additional information about the UDP over IPv6 transmitter. */ +class JRTPLIB_IMPORTEXPORT RTPUDPv6TransmissionInfo : public RTPTransmissionInfo +{ +public: +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + RTPUDPv6TransmissionInfo(std::list iplist,int rtpsock,int rtcpsock) : RTPTransmissionInfo(RTPTransmitter::IPv6UDPProto) +#else + RTPUDPv6TransmissionInfo(std::list iplist,SOCKET rtpsock,SOCKET rtcpsock) : RTPTransmissionInfo(RTPTransmitter::IPv6UDPProto) +#endif // WIN32 + { localIPlist = iplist; rtpsocket = rtpsock; rtcpsocket = rtcpsock; } + + ~RTPUDPv6TransmissionInfo() { } + + /** Returns the list of IPv6 addresses the transmitter considers to be the local IP addresses. */ + std::list GetLocalIPList() const { return localIPlist; } +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + /** Returns the socket descriptor used for receiving and transmitting RTP packets. */ + int GetRTPSocket() const { return rtpsocket; } + + /** Returns the socket descriptor used for receiving and transmitting RTCP packets. */ + int GetRTCPSocket() const { return rtcpsocket; } +#else + SOCKET GetRTPSocket() const { return rtpsocket; } + SOCKET GetRTCPSocket() const { return rtcpsocket; } +#endif // WIN32 +private: + std::list localIPlist; +#if ! (defined(WIN32) || defined(_WIN32_WCE)) + int rtpsocket,rtcpsocket; +#else + SOCKET rtpsocket,rtcpsocket; +#endif // WIN32 +}; + +class JRTPLIB_IMPORTEXPORT RTPUDPv6Trans_GetHashIndex_IPv6Dest +{ +public: + static int GetIndex(const RTPIPv6Destination &d) { in6_addr ip = d.GetIP(); return ((((uint32_t)ip.s6_addr[12])<<24)|(((uint32_t)ip.s6_addr[13])<<16)|(((uint32_t)ip.s6_addr[14])<<8)|((uint32_t)ip.s6_addr[15]))%RTPUDPV6TRANS_HASHSIZE; } +}; + +class JRTPLIB_IMPORTEXPORT RTPUDPv6Trans_GetHashIndex_in6_addr +{ +public: + static int GetIndex(const in6_addr &ip) { return ((((uint32_t)ip.s6_addr[12])<<24)|(((uint32_t)ip.s6_addr[13])<<16)|(((uint32_t)ip.s6_addr[14])<<8)|((uint32_t)ip.s6_addr[15]))%RTPUDPV6TRANS_HASHSIZE; } +}; + +#define RTPUDPV6TRANS_HEADERSIZE (40+8) + +/** An UDP over IPv6 transmitter. + * This class inherits the RTPTransmitter interface and implements a transmission component + * which uses UDP over IPv6 to send and receive RTP and RTCP data. The component's parameters + * are described by the class RTPUDPv6TransmissionParams. The functions which have an RTPAddress + * argument require an argument of RTPIPv6Address. The GetTransmissionInfo member function + * returns an instance of type RTPUDPv6TransmissionInfo. + */ +class JRTPLIB_IMPORTEXPORT RTPUDPv6Transmitter : public RTPTransmitter +{ +public: + RTPUDPv6Transmitter(RTPMemoryManager *mgr); + ~RTPUDPv6Transmitter(); + + int Init(bool treadsafe); + int Create(size_t maxpacksize,const RTPTransmissionParams *transparams); + void Destroy(); + RTPTransmissionInfo *GetTransmissionInfo(); + void DeleteTransmissionInfo(RTPTransmissionInfo *inf); + + int GetLocalHostName(uint8_t *buffer,size_t *bufferlength); + bool ComesFromThisTransmitter(const RTPAddress *addr); + size_t GetHeaderOverhead() { return RTPUDPV6TRANS_HEADERSIZE; } + + int Poll(); + int WaitForIncomingData(const RTPTime &delay,bool *dataavailable = 0); + int AbortWait(); + + int SendRTPData(const void *data,size_t len); + int SendRTCPData(const void *data,size_t len); + + int AddDestination(const RTPAddress &addr); + int DeleteDestination(const RTPAddress &addr); + void ClearDestinations(); + + bool SupportsMulticasting(); + int JoinMulticastGroup(const RTPAddress &addr); + int LeaveMulticastGroup(const RTPAddress &addr); + void LeaveAllMulticastGroups(); + + int SetReceiveMode(RTPTransmitter::ReceiveMode m); + int AddToIgnoreList(const RTPAddress &addr); + int DeleteFromIgnoreList(const RTPAddress &addr); + void ClearIgnoreList(); + int AddToAcceptList(const RTPAddress &addr); + int DeleteFromAcceptList(const RTPAddress &addr); + void ClearAcceptList(); + int SetMaximumPacketSize(size_t s); + + bool NewDataAvailable(); + RTPRawPacket *GetNextPacket(); +#ifdef RTPDEBUG + void Dump(); +#endif // RTPDEBUG +private: + int CreateLocalIPList(); + bool GetLocalIPList_Interfaces(); + void GetLocalIPList_DNS(); + void AddLoopbackAddress(); + void FlushPackets(); + int PollSocket(bool rtp); + int ProcessAddAcceptIgnoreEntry(in6_addr ip,uint16_t port); + int ProcessDeleteAcceptIgnoreEntry(in6_addr ip,uint16_t port); +#ifdef RTP_SUPPORT_IPV6MULTICAST + bool SetMulticastTTL(uint8_t ttl); +#endif // RTP_SUPPORT_IPV6MULTICAST + bool ShouldAcceptData(in6_addr srcip,uint16_t srcport); + void ClearAcceptIgnoreInfo(); + + bool init; + bool created; + bool waitingfordata; +#if (defined(WIN32) || defined(_WIN32_WCE)) + SOCKET rtpsock,rtcpsock; +#else // not using winsock + int rtpsock,rtcpsock; +#endif // WIN32 + in6_addr bindIP; + unsigned int mcastifidx; + std::list localIPs; + uint16_t portbase; + uint8_t multicastTTL; + RTPTransmitter::ReceiveMode receivemode; + + uint8_t *localhostname; + size_t localhostnamelength; + + RTPHashTable destinations; +#ifdef RTP_SUPPORT_IPV6MULTICAST + RTPHashTable multicastgroups; +#endif // RTP_SUPPORT_IPV6MULTICAST + std::list rawpacketlist; + + bool supportsmulticasting; + size_t maxpacksize; + + class PortInfo + { + public: + PortInfo() { all = false; } + + bool all; + std::list portlist; + }; + + RTPKeyHashTable acceptignoreinfo; + + // notification descriptors for AbortWait (0 is for reading, 1 for writing) +#if (defined(WIN32) || defined(_WIN32_WCE)) + SOCKET abortdesc[2]; +#else + int abortdesc[2]; +#endif // WIN32 + int CreateAbortDescriptors(); + void DestroyAbortDescriptors(); + void AbortWaitInternal(); +#ifdef RTP_SUPPORT_THREAD + jthread::JMutex mainmutex,waitmutex; + int threadsafe; +#endif // RTP_SUPPORT_THREAD +}; + +} // end namespace + +#endif // RTP_SUPPORT_IPV6 + +#endif // RTPUDPV6TRANSMITTER_H + diff --git a/src/libs/jrtplib/tools/getloginrtest.cpp b/src/libs/jrtplib/tools/getloginrtest.cpp new file mode 100644 index 00000000..31bb831b --- /dev/null +++ b/src/libs/jrtplib/tools/getloginrtest.cpp @@ -0,0 +1,9 @@ +#include + +int main(void) +{ + char buf[256]; + getlogin_r(buf,256); + return 0; +} + diff --git a/src/libs/jrtplib/tools/gettypes.cpp b/src/libs/jrtplib/tools/gettypes.cpp new file mode 100644 index 00000000..971f9037 --- /dev/null +++ b/src/libs/jrtplib/tools/gettypes.cpp @@ -0,0 +1,50 @@ +#include + +int main(void) +{ + printf("#ifndef RTPTYPES_H\n\n"); + printf("#define RTPTYPES_H\n\n"); + printf("#include \n\n"); + + if (sizeof(char) == 1) + { + printf("typedef char int8_t;\n"); + printf("typedef unsigned char uint8_t;\n\n"); + } + else + return -1; + + if (sizeof(short) == 2) + { + printf("typedef short int16_t;\n"); + printf("typedef unsigned short uint16_t;\n\n"); + } + else + return -1; + + if (sizeof(int) == 4) + { + printf("typedef int int32_t;\n"); + printf("typedef unsigned int uint32_t;\n\n"); + } + else if (sizeof(long) == 4) + { + printf("typedef long int32_t;\n"); + printf("typedef unsigned long uint32_t;\n\n"); + } + else + return -1; + + if (sizeof(long long) == 8) + { + printf("typedef long long int64_t;\n"); + printf("typedef unsigned long long uint64_t;\n\n"); + } + else + return -1; + + printf("#endif // RTPTYPES_H\n"); + + return 0; +} + diff --git a/src/libs/jrtplib/tools/ipv4mcasttest.cpp b/src/libs/jrtplib/tools/ipv4mcasttest.cpp new file mode 100644 index 00000000..4c419232 --- /dev/null +++ b/src/libs/jrtplib/tools/ipv4mcasttest.cpp @@ -0,0 +1,21 @@ +#if defined(WIN32) || defined(_WIN32_WCE) + #include + #include + #ifndef _WIN32_WCE + #include + #endif // !_WIN32_WCE +#else + #include + #include + #include +#endif // WIN32 || _WIN32_WCE + +int main(void) +{ + int testval; + struct ip_mreq mreq,mreq2; + mreq = mreq2; // avoid 'unused variable' + testval = IP_MULTICAST_TTL; + testval = IP_ADD_MEMBERSHIP; + return 0; +} diff --git a/src/libs/jrtplib/tools/ipv6mcasttest.cpp b/src/libs/jrtplib/tools/ipv6mcasttest.cpp new file mode 100644 index 00000000..00434acc --- /dev/null +++ b/src/libs/jrtplib/tools/ipv6mcasttest.cpp @@ -0,0 +1,23 @@ +#if defined(WIN32) || defined(_WIN32_WCE) + #include + #include + #ifndef _WIN32_WCE + #include + #endif // !_WIN32_WCE +#else + #include + #include + #include +#endif // WIN32 || _WIN32_WCE + +int main(void) +{ + int testval; + struct ipv6_mreq mreq,mreq2; + mreq = mreq2; // avoid 'unused variable' + testval = IPV6_MULTICAST_HOPS; + testval = IPV6_JOIN_GROUP; + testval = IPV6_LEAVE_GROUP; + return 0; +} + diff --git a/src/libs/jrtplib/tools/ipv6test.cpp b/src/libs/jrtplib/tools/ipv6test.cpp new file mode 100644 index 00000000..e339ce7e --- /dev/null +++ b/src/libs/jrtplib/tools/ipv6test.cpp @@ -0,0 +1,21 @@ +#if defined(WIN32) || defined(_WIN32_WCE) + #include + #include + #ifndef _WIN32_WCE + #include + #endif // !_WIN32_WCE +#else + #include + #include + #include +#endif // WIN32 || _WIN32_WCE + +int main(void) +{ + struct sockaddr_in6 addr; + + addr.sin6_family = PF_INET6; + + return 0; +} + diff --git a/src/libs/jrtplib/tools/salentest.cpp b/src/libs/jrtplib/tools/salentest.cpp new file mode 100644 index 00000000..d4216c74 --- /dev/null +++ b/src/libs/jrtplib/tools/salentest.cpp @@ -0,0 +1,20 @@ +#if defined(WIN32) || defined(_WIN32_WCE) + #include + #include + #ifndef _WIN32_WCE + #include + #endif // !_WIN32_WCE +#else + #include + #include + #include +#endif // WIN32 || _WIN32_WCE + +int main(void) +{ + struct sockaddr sa; + sa.sa_len = 0; + + return 0; +} + diff --git a/src/libs/jrtplib/tools/socklentest.cpp b/src/libs/jrtplib/tools/socklentest.cpp new file mode 100644 index 00000000..7333335e --- /dev/null +++ b/src/libs/jrtplib/tools/socklentest.cpp @@ -0,0 +1,22 @@ +#if defined(WIN32) || defined(_WIN32_WCE) + #include + #include + #ifndef _WIN32_WCE + #include + #endif // !_WIN32_WCE +#else + #include + #include + #include +#endif // WIN32 || _WIN32_WCE + +int main(void) +{ + int param; + int sock = 0; + struct sockaddr addr; + + getsockname(sock,&addr,¶m); + + return 0; +} diff --git a/src/libs/libg729/CMakeLists.txt b/src/libs/libg729/CMakeLists.txt new file mode 100644 index 00000000..e2818b95 --- /dev/null +++ b/src/libs/libg729/CMakeLists.txt @@ -0,0 +1,37 @@ +project (g729) + +# Rely on C++ 11 +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +set (G729_SOURCES + g729_acelp_ca.cpp + g729_basic_op.cpp + g729_cod_ld8a.cpp + g729_cor_func.cpp + g729_de_acelp.cpp + g729_dec_gain.cpp + g729_dec_lag3.cpp + g729_dec_ld8a.cpp + g729_dspfunc.cpp + g729_filter.cpp + g729_gainpred.cpp + g729_lpc_729.cpp + g729_lpcfunc.cpp + g729_lspdec.cpp + g729_lspgetq.cpp + g729_oper_32b.cpp + g729_pitch_a.cpp + g729_postfilt.cpp + g729_post_pro.cpp + g729_p_parity.cpp + g729_pred_lt3.cpp + g729_pre_proc.cpp + g729_gain.cpp + g729_lsp.cpp + g729_tab_ld8a.cpp + g729_taming.cpp + g729_util.cpp +) + +add_library(g729_codec ${G729_SOURCES}) diff --git a/src/libs/libg729/acelp_ca.c b/src/libs/libg729/acelp_ca.c new file mode 100644 index 00000000..e340ca32 --- /dev/null +++ b/src/libs/libg729/acelp_ca.c @@ -0,0 +1,991 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*---------------------------------------------------------------------------* + * Function ACELP_Code_A() * + * ~~~~~~~~~~~~~~~~~~~~~~~~ * + * Find Algebraic codebook for G.729A * + *--------------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" + +/* Constants defined in ld8a.h */ +/* L_SUBFR -> Lenght of subframe. */ +/* NB_POS -> Number of positions for each pulse. */ +/* STEP -> Step betweem position of the same pulse. */ +/* MSIZE -> Size of vectors for cross-correlation between two pulses. */ + + +/* local routines definition */ + +void Cor_h (Word16 * H, /* (i) Q12 :Impulse response of filters */ + Word16 * rr /* (o) :Correlations of H[] */ +); +Word16 D4i40_17_fast ( /*(o) : Index of pulses positions. */ + Word16 dn[], /* (i) : Correlations between h[] and Xn[]. */ + Word16 * rr, /* (i) : Correlations of impulse response h[]. */ + Word16 h[], /* (i) Q12: Impulse response of filters. */ + Word16 cod[], /* (o) Q13: Selected algebraic codeword. */ + Word16 y[], /* (o) Q12: Filtered algebraic codeword. */ + Word16 * sign /* (o) : Signs of 4 pulses. */ + ); + + /*-----------------------------------------------------------------* + * Main ACELP function. * + *-----------------------------------------------------------------*/ + +Word16 +ACELP_Code_A ( /* (o) :index of pulses positions */ + Word16 x[], /* (i) :Target vector */ + Word16 h[], /* (i) Q12 :Inpulse response of filters */ + Word16 T0, /* (i) :Pitch lag */ + Word16 pitch_sharp, /* (i) Q14 :Last quantized pitch gain */ + Word16 code[], /* (o) Q13 :Innovative codebook */ + Word16 y[], /* (o) Q12 :Filtered innovative codebook */ + Word16 * sign /* (o) :Signs of 4 pulses */ + ) +{ + Word16 i, index, sharp; + Word16 Dn[L_SUBFR]; + Word16 rr[DIM_RR]; + + /*-----------------------------------------------------------------* + * Include fixed-gain pitch contribution into impulse resp. h[] * + * Find correlations of h[] needed for the codebook search. * + *-----------------------------------------------------------------*/ + + sharp = shl (pitch_sharp, 1); /* From Q14 to Q15 */ + if (T0 < L_SUBFR) + for (i = T0; i < L_SUBFR; i++) /* h[i] += pitch_sharp*h[i-T0] */ + h[i] = add (h[i], mult (h[i - T0], sharp)); + + Cor_h (h, rr); + + /*-----------------------------------------------------------------* + * Compute correlation of target vector with impulse response. * + *-----------------------------------------------------------------*/ + + Cor_h_X (h, x, Dn); + + /*-----------------------------------------------------------------* + * Find innovative codebook. * + *-----------------------------------------------------------------*/ + + index = D4i40_17_fast (Dn, rr, h, code, y, sign); + + /*-----------------------------------------------------------------* + * Compute innovation vector gain. * + * Include fixed-gain pitch contribution into code[]. * + *-----------------------------------------------------------------*/ + + if (T0 < L_SUBFR) + for (i = T0; i < L_SUBFR; i++) /* code[i] += pitch_sharp*code[i-T0] */ + code[i] = add (code[i], mult (code[i - T0], sharp)); + + return index; +} + + + +/*--------------------------------------------------------------------------* + * Function Cor_h() * + * ~~~~~~~~~~~~~~~~~ * + * Compute correlations of h[] needed for the codebook search. * + *--------------------------------------------------------------------------*/ + +void +Cor_h (Word16 * H, /* (i) Q12 :Impulse response of filters */ + Word16 * rr /* (o) :Correlations of H[] */ + ) +{ + Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4; + Word16 *rri0i1, *rri0i2, *rri0i3, *rri0i4; + Word16 *rri1i2, *rri1i3, *rri1i4; + Word16 *rri2i3, *rri2i4; + + Word16 *p0, *p1, *p2, *p3, *p4; + + Word16 *ptr_hd, *ptr_hf, *ptr_h1, *ptr_h2; + Word32 cor; + Word16 i, k, ldec, l_fin_sup, l_fin_inf; + Word16 h[L_SUBFR]; + + /* Scaling h[] for maximum precision */ + + cor = 0; + for (i = 0; i < L_SUBFR; i++) + cor = L_mac (cor, H[i], H[i]); + + if (sub (extract_h (cor), 32000) > 0) { + for (i = 0; i < L_SUBFR; i++) { + h[i] = shr (H[i], 1); + } + } + else { + k = norm_l (cor); + k = shr (k, 1); + + for (i = 0; i < L_SUBFR; i++) { + h[i] = shl (H[i], k); + } + } + + + + /*------------------------------------------------------------* + * Compute rri0i0[], rri1i1[], rri2i2[], rri3i3 and rri4i4[] * + *------------------------------------------------------------*/ + /* Init pointers */ + rri0i0 = rr; + rri1i1 = rri0i0 + NB_POS; + rri2i2 = rri1i1 + NB_POS; + rri3i3 = rri2i2 + NB_POS; + rri4i4 = rri3i3 + NB_POS; + rri0i1 = rri4i4 + NB_POS; + rri0i2 = rri0i1 + MSIZE; + rri0i3 = rri0i2 + MSIZE; + rri0i4 = rri0i3 + MSIZE; + rri1i2 = rri0i4 + MSIZE; + rri1i3 = rri1i2 + MSIZE; + rri1i4 = rri1i3 + MSIZE; + rri2i3 = rri1i4 + MSIZE; + rri2i4 = rri2i3 + MSIZE; + + p0 = rri0i0 + NB_POS - 1; /* Init pointers to last position of rrixix[] */ + p1 = rri1i1 + NB_POS - 1; + p2 = rri2i2 + NB_POS - 1; + p3 = rri3i3 + NB_POS - 1; + p4 = rri4i4 + NB_POS - 1; + + ptr_h1 = h; + cor = 0; + for (i = 0; i < NB_POS; i++) { + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p4-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p3-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p2-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p1-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p0-- = extract_h (cor); + } + + /*-----------------------------------------------------------------* + * Compute elements of: rri2i3[], rri1i2[], rri0i1[] and rri0i4[] * + *-----------------------------------------------------------------*/ + + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + ldec = NB_POS + 1; + + ptr_hd = h; + ptr_hf = ptr_hd + 1; + + for (k = 0; k < NB_POS; k++) { + + p3 = rri2i3 + l_fin_sup; + p2 = rri1i2 + l_fin_sup; + p1 = rri0i1 + l_fin_sup; + p0 = rri0i4 + l_fin_inf; + + cor = 0; + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + + /*---------------------------------------------------------------------* + * Compute elements of: rri2i4[], rri1i3[], rri0i2[], rri1i4[], rri0i3 * + *---------------------------------------------------------------------*/ + + ptr_hd = h; + ptr_hf = ptr_hd + 2; + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + for (k = 0; k < NB_POS; k++) { + + p4 = rri2i4 + l_fin_sup; + p3 = rri1i3 + l_fin_sup; + p2 = rri0i2 + l_fin_sup; + p1 = rri1i4 + l_fin_inf; + p0 = rri0i3 + l_fin_inf; + + cor = 0; + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p4 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p4 -= ldec; + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p4 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + + /*----------------------------------------------------------------------* + * Compute elements of: rri1i4[], rri0i3[], rri2i4[], rri1i3[], rri0i2 * + *----------------------------------------------------------------------*/ + + ptr_hd = h; + ptr_hf = ptr_hd + 3; + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + for (k = 0; k < NB_POS; k++) { + + p4 = rri1i4 + l_fin_sup; + p3 = rri0i3 + l_fin_sup; + p2 = rri2i4 + l_fin_inf; + p1 = rri1i3 + l_fin_inf; + p0 = rri0i2 + l_fin_inf; + + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + cor = 0; + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p4 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p4 -= ldec; + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p4 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + + /*----------------------------------------------------------------------* + * Compute elements of: rri0i4[], rri2i3[], rri1i2[], rri0i1[] * + *----------------------------------------------------------------------*/ + + ptr_hd = h; + ptr_hf = ptr_hd + 4; + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + for (k = 0; k < NB_POS; k++) { + + p3 = rri0i4 + l_fin_sup; + p2 = rri2i3 + l_fin_inf; + p1 = rri1i2 + l_fin_inf; + p0 = rri0i1 + l_fin_inf; + + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + cor = 0; + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + return; +} + + + +/*------------------------------------------------------------------------* + * Function D4i40_17_fast() * + * ~~~~~~~~~ * + * Algebraic codebook for ITU 8kb/s. * + * -> 17 bits; 4 pulses in a frame of 40 samples * + * * + *------------------------------------------------------------------------* + * The code length is 40, containing 4 nonzero pulses i0, i1, i2, i3. * + * Each pulses can have 8 possible positions (positive or negative) * + * except i3 that have 16 possible positions. * + * * + * i0 (+-1) : 0, 5, 10, 15, 20, 25, 30, 35 * + * i1 (+-1) : 1, 6, 11, 16, 21, 26, 31, 36 * + * i2 (+-1) : 2, 7, 12, 17, 22, 27, 32, 37 * + * i3 (+-1) : 3, 8, 13, 18, 23, 28, 33, 38 * + * 4, 9, 14, 19, 24, 29, 34, 39 * + *------------------------------------------------------------------------*/ + +Word16 +D4i40_17_fast ( /*(o) : Index of pulses positions. */ + Word16 dn[], /* (i) : Correlations between h[] and Xn[]. */ + Word16 rr[], /* (i) : Correlations of impulse response h[]. */ + Word16 h[], /* (i) Q12: Impulse response of filters. */ + Word16 cod[], /* (o) Q13: Selected algebraic codeword. */ + Word16 y[], /* (o) Q12: Filtered algebraic codeword. */ + Word16 * sign /* (o) : Signs of 4 pulses. */ + ) +{ + Word16 i0, i1, i2, i3, ip0, ip1, ip2, ip3; + Word16 i, j, ix, iy, track, trk, max; + Word16 prev_i0, i1_offset; + Word16 psk, ps, ps0, ps1, ps2, sq, sq2; + Word16 alpk, alp, alp_16; + Word32 s, alp0, alp1, alp2; + Word16 *p0, *p1, *p2, *p3, *p4; + Word16 sign_dn[L_SUBFR], sign_dn_inv[L_SUBFR], *psign; + Word16 tmp_vect[NB_POS]; + Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4; + Word16 *rri0i1, *rri0i2, *rri0i3, *rri0i4; + Word16 *rri1i2, *rri1i3, *rri1i4; + Word16 *rri2i3, *rri2i4; + + Word16 *ptr_rri0i3_i4; + Word16 *ptr_rri1i3_i4; + Word16 *ptr_rri2i3_i4; + Word16 *ptr_rri3i3_i4; + + /* Init pointers */ + rri0i0 = rr; + rri1i1 = rri0i0 + NB_POS; + rri2i2 = rri1i1 + NB_POS; + rri3i3 = rri2i2 + NB_POS; + rri4i4 = rri3i3 + NB_POS; + rri0i1 = rri4i4 + NB_POS; + rri0i2 = rri0i1 + MSIZE; + rri0i3 = rri0i2 + MSIZE; + rri0i4 = rri0i3 + MSIZE; + rri1i2 = rri0i4 + MSIZE; + rri1i3 = rri1i2 + MSIZE; + rri1i4 = rri1i3 + MSIZE; + rri2i3 = rri1i4 + MSIZE; + rri2i4 = rri2i3 + MSIZE; + + /*-----------------------------------------------------------------------* + * Chose the sign of the impulse. * + *-----------------------------------------------------------------------*/ + + for (i = 0; i < L_SUBFR; i++) { + if (dn[i] >= 0) { + sign_dn[i] = MAX_16; + sign_dn_inv[i] = MIN_16; + } + else { + sign_dn[i] = MIN_16; + sign_dn_inv[i] = MAX_16; + dn[i] = negate (dn[i]); + } + } + + /*-------------------------------------------------------------------* + * Modification of rrixiy[] to take signs into account. * + *-------------------------------------------------------------------*/ + + p0 = rri0i1; + p1 = rri0i2; + p2 = rri0i3; + p3 = rri0i4; + + for (i0 = 0; i0 < L_SUBFR; i0 += STEP) { + psign = sign_dn; + if (psign[i0] < 0) + psign = sign_dn_inv; + + for (i1 = 1; i1 < L_SUBFR; i1 += STEP) { + *p0 = mult (*p0, psign[i1]); p0++; + *p1 = mult (*p1, psign[i1 + 1]); p1++; + *p2 = mult (*p2, psign[i1 + 2]); p2++; + *p3 = mult (*p3, psign[i1 + 3]); p3++; + } + } + + p0 = rri1i2; + p1 = rri1i3; + p2 = rri1i4; + + for (i1 = 1; i1 < L_SUBFR; i1 += STEP) { + psign = sign_dn; + if (psign[i1] < 0) + psign = sign_dn_inv; + + for (i2 = 2; i2 < L_SUBFR; i2 += STEP) { + *p0 = mult (*p0, psign[i2]); p0++; + *p1 = mult (*p1, psign[i2 + 1]); p1++; + *p2 = mult (*p2, psign[i2 + 2]); p2++; + } + } + + p0 = rri2i3; + p1 = rri2i4; + + for (i2 = 2; i2 < L_SUBFR; i2 += STEP) { + psign = sign_dn; + if (psign[i2] < 0) + psign = sign_dn_inv; + + for (i3 = 3; i3 < L_SUBFR; i3 += STEP) { + *p0 = mult (*p0, psign[i3]); p0++; + *p1 = mult (*p1, psign[i3 + 1]); p1++; + } + } + + + /*-------------------------------------------------------------------* + * Search the optimum positions of the four pulses which maximize * + * square(correlation) / energy * + *-------------------------------------------------------------------*/ + + psk = -1; + alpk = 1; + + ptr_rri0i3_i4 = rri0i3; + ptr_rri1i3_i4 = rri1i3; + ptr_rri2i3_i4 = rri2i3; + ptr_rri3i3_i4 = rri3i3; + + /* Initializations only to remove warning from some compilers */ + + ip0 = 0; + ip1 = 1; + ip2 = 2; + ip3 = 3; + ix = 0; + iy = 0; + ps = 0; + + /* search 2 times: track 3 and 4 */ + for (track = 3, trk = 0; track < 5; track++, trk++) { + /*------------------------------------------------------------------* + * depth first search 3, phase A: track 2 and 3/4. * + *------------------------------------------------------------------*/ + + sq = -1; + alp = 1; + + /* i0 loop: 2 positions in track 2 */ + + prev_i0 = -1; + + for (i = 0; i < 2; i++) { + max = -1; + /* search "dn[]" maximum position in track 2 */ + for (j = 2; j < L_SUBFR; j += STEP) { + if ((sub (dn[j], max) > 0) && (sub (prev_i0, j) != 0)) { + max = dn[j]; + i0 = j; + } + } + prev_i0 = i0; + + j = mult (i0, 6554); /* j = i0/5 */ + p0 = rri2i2 + j; + + ps1 = dn[i0]; + alp1 = L_mult (*p0, _1_4); + + /* i1 loop: 8 positions in track 2 */ + + p0 = ptr_rri2i3_i4 + shl (j, 3); + p1 = ptr_rri3i3_i4; + + for (i1 = track; i1 < L_SUBFR; i1 += STEP) { + ps2 = add (ps1, dn[i1]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */ + alp2 = L_mac (alp1, *p0++, _1_2); + alp2 = L_mac (alp2, *p1++, _1_4); + + sq2 = mult (ps2, ps2); + alp_16 = wround (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + if (s > 0) { + sq = sq2; + ps = ps2; + alp = alp_16; + ix = i0; + iy = i1; + } + } + } + + i0 = ix; + i1 = iy; + i1_offset = shl (mult (i1, 6554), 3); /* j = 8*(i1/5) */ + + /*------------------------------------------------------------------* + * depth first search 3, phase B: track 0 and 1. * + *------------------------------------------------------------------*/ + + ps0 = ps; + alp0 = L_mult (alp, _1_4); + + sq = -1; + alp = 1; + + /* build vector for next loop to decrease complexity */ + + p0 = rri1i2 + mult (i0, 6554); + p1 = ptr_rri1i3_i4 + mult (i1, 6554); + p2 = rri1i1; + p3 = tmp_vect; + + for (i3 = 1; i3 < L_SUBFR; i3 += STEP) { + /* rrv[i3] = rr[i3][i3] + rr[i0][i3] + rr[i1][i3]; */ + s = L_mult (*p0, _1_4); + p0 += NB_POS; + s = L_mac (s, *p1, _1_4); + p1 += NB_POS; + s = L_mac (s, *p2++, _1_8); + *p3++ = wround (s); + } + + /* i2 loop: 8 positions in track 0 */ + + p0 = rri0i2 + mult (i0, 6554); + p1 = ptr_rri0i3_i4 + mult (i1, 6554); + p2 = rri0i0; + p3 = rri0i1; + + for (i2 = 0; i2 < L_SUBFR; i2 += STEP) { + ps1 = add (ps0, dn[i2]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */ + alp1 = L_mac (alp0, *p0, _1_8); + p0 += NB_POS; + alp1 = L_mac (alp1, *p1, _1_8); + p1 += NB_POS; + alp1 = L_mac (alp1, *p2++, _1_16); + + /* i3 loop: 8 positions in track 1 */ + + p4 = tmp_vect; + + for (i3 = 1; i3 < L_SUBFR; i3 += STEP) { + ps2 = add (ps1, dn[i3]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */ + alp2 = L_mac (alp1, *p3++, _1_8); + alp2 = L_mac (alp2, *p4++, _1_2); + + sq2 = mult (ps2, ps2); + alp_16 = wround (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + if (s > 0) { + sq = sq2; + alp = alp_16; + ix = i2; + iy = i3; + } + } + } + + /*----------------------------------------------------------------* + * depth first search 3: compare codevector with the best case. * + *----------------------------------------------------------------*/ + + s = L_msu (L_mult (alpk, sq), psk, alp); + if (s > 0) { + psk = sq; + alpk = alp; + ip2 = i0; + ip3 = i1; + ip0 = ix; + ip1 = iy; + } + + /*------------------------------------------------------------------* + * depth first search 4, phase A: track 3 and 0. * + *------------------------------------------------------------------*/ + + sq = -1; + alp = 1; + + /* i0 loop: 2 positions in track 3/4 */ + + prev_i0 = -1; + + for (i = 0; i < 2; i++) { + max = -1; + /* search "dn[]" maximum position in track 3/4 */ + for (j = track; j < L_SUBFR; j += STEP) { + if ((sub (dn[j], max) > 0) && (sub (prev_i0, j) != 0)) { + max = dn[j]; + i0 = j; + } + } + prev_i0 = i0; + + j = mult (i0, 6554); /* j = i0/5 */ + p0 = ptr_rri3i3_i4 + j; + + ps1 = dn[i0]; + alp1 = L_mult (*p0, _1_4); + + /* i1 loop: 8 positions in track 0 */ + + p0 = ptr_rri0i3_i4 + j; + p1 = rri0i0; + + for (i1 = 0; i1 < L_SUBFR; i1 += STEP) { + ps2 = add (ps1, dn[i1]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */ + alp2 = L_mac (alp1, *p0, _1_2); + p0 += NB_POS; + alp2 = L_mac (alp2, *p1++, _1_4); + + sq2 = mult (ps2, ps2); + alp_16 = wround (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + if (s > 0) { + sq = sq2; + ps = ps2; + alp = alp_16; + ix = i0; + iy = i1; + } + } + } + + i0 = ix; + i1 = iy; + i1_offset = shl (mult (i1, 6554), 3); /* j = 8*(i1/5) */ + + /*------------------------------------------------------------------* + * depth first search 4, phase B: track 1 and 2. * + *------------------------------------------------------------------*/ + + ps0 = ps; + alp0 = L_mult (alp, _1_4); + + sq = -1; + alp = 1; + + /* build vector for next loop to decrease complexity */ + + p0 = ptr_rri2i3_i4 + mult (i0, 6554); + p1 = rri0i2 + i1_offset; + p2 = rri2i2; + p3 = tmp_vect; + + for (i3 = 2; i3 < L_SUBFR; i3 += STEP) { + /* rrv[i3] = rr[i3][i3] + rr[i0][i3] + rr[i1][i3]; */ + s = L_mult (*p0, _1_4); + p0 += NB_POS; + s = L_mac (s, *p1++, _1_4); + s = L_mac (s, *p2++, _1_8); + *p3++ = wround (s); + } + + /* i2 loop: 8 positions in track 1 */ + + p0 = ptr_rri1i3_i4 + mult (i0, 6554); + p1 = rri0i1 + i1_offset; + p2 = rri1i1; + p3 = rri1i2; + + for (i2 = 1; i2 < L_SUBFR; i2 += STEP) { + ps1 = add (ps0, dn[i2]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */ + alp1 = L_mac (alp0, *p0, _1_8); + p0 += NB_POS; + alp1 = L_mac (alp1, *p1++, _1_8); + alp1 = L_mac (alp1, *p2++, _1_16); + + /* i3 loop: 8 positions in track 2 */ + + p4 = tmp_vect; + + for (i3 = 2; i3 < L_SUBFR; i3 += STEP) { + ps2 = add (ps1, dn[i3]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */ + alp2 = L_mac (alp1, *p3++, _1_8); + alp2 = L_mac (alp2, *p4++, _1_2); + + sq2 = mult (ps2, ps2); + alp_16 = wround (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + if (s > 0) { + sq = sq2; + alp = alp_16; + ix = i2; + iy = i3; + } + } + } + + /*----------------------------------------------------------------* + * depth first search 1: compare codevector with the best case. * + *----------------------------------------------------------------*/ + + s = L_msu (L_mult (alpk, sq), psk, alp); + if (s > 0) { + psk = sq; + alpk = alp; + ip3 = i0; + ip0 = i1; + ip1 = ix; + ip2 = iy; + } + + ptr_rri0i3_i4 = rri0i4; + ptr_rri1i3_i4 = rri1i4; + ptr_rri2i3_i4 = rri2i4; + ptr_rri3i3_i4 = rri4i4; + + } + + + /* Set the sign of impulses */ + + i0 = sign_dn[ip0]; + i1 = sign_dn[ip1]; + i2 = sign_dn[ip2]; + i3 = sign_dn[ip3]; + + /* Find the codeword corresponding to the selected positions */ + + + for (i = 0; i < L_SUBFR; i++) { + cod[i] = 0; + } + + cod[ip0] = shr (i0, 2); /* From Q15 to Q13 */ + cod[ip1] = shr (i1, 2); + cod[ip2] = shr (i2, 2); + cod[ip3] = shr (i3, 2); + + /* find the filtered codeword */ + + for (i = 0; i < ip0; i++) + y[i] = 0; + + if (i0 > 0) + for (i = ip0, j = 0; i < L_SUBFR; i++, j++) + y[i] = h[j]; + else + for (i = ip0, j = 0; i < L_SUBFR; i++, j++) + y[i] = negate (h[j]); + + if (i1 > 0) + for (i = ip1, j = 0; i < L_SUBFR; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip1, j = 0; i < L_SUBFR; i++, j++) + y[i] = sub (y[i], h[j]); + + if (i2 > 0) + for (i = ip2, j = 0; i < L_SUBFR; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip2, j = 0; i < L_SUBFR; i++, j++) + y[i] = sub (y[i], h[j]); + + if (i3 > 0) + for (i = ip3, j = 0; i < L_SUBFR; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip3, j = 0; i < L_SUBFR; i++, j++) + y[i] = sub (y[i], h[j]); + + /* find codebook index; 17-bit address */ + + i = 0; + if (i0 > 0) + i = add (i, 1); + if (i1 > 0) + i = add (i, 2); + if (i2 > 0) + i = add (i, 4); + if (i3 > 0) + i = add (i, 8); + *sign = i; + + ip0 = mult (ip0, 6554); /* ip0/5 */ + ip1 = mult (ip1, 6554); /* ip1/5 */ + ip2 = mult (ip2, 6554); /* ip2/5 */ + i = mult (ip3, 6554); /* ip3/5 */ + j = add (i, shl (i, 2)); /* j = i*5 */ + j = sub (ip3, add (j, 3)); /* j= ip3%5 -3 */ + ip3 = add (shl (i, 1), j); + + i = add (ip0, shl (ip1, 3)); + i = add (i, shl (ip2, 6)); + i = add (i, shl (ip3, 9)); + + return i; +} diff --git a/src/libs/libg729/basic_op.c b/src/libs/libg729/basic_op.c new file mode 100644 index 00000000..54c128ab --- /dev/null +++ b/src/libs/libg729/basic_op.c @@ -0,0 +1,2013 @@ + +/* + * + * Basics operators. + * +*/ + +/* + * + * Include-Files + * +*/ + +#include +#include +#include "typedef.h" +#include "basic_op.h" + + +/* + * + * Function Name : sature + * + * Purpose : + * + * Limit the 32 bit input to the range of a 16 bit word. + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +sature (Word32 L_var1) +{ + Word16 var_out; + + if (L_var1 > 0X00007fffL) { + var_out = MAX_16; + } + else if (L_var1 < (Word32) 0xffff8000L) { + var_out = MIN_16; + } + else { + var_out = extract_l (L_var1); + } + + return (var_out); +} + + +/* + * + * Function Name : sature + * + * Purpose : + * + * Limit the 32 bit input to the range of a 16 bit word. + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +sature_o (Word32 L_var1, Flag *Overflow) +{ + Word16 var_out; + + if (L_var1 > 0X00007fffL) { + *Overflow = 1; + var_out = MAX_16; + } + else if (L_var1 < (Word32) 0xffff8000L) { + *Overflow = 1; + var_out = MIN_16; + } + else { + *Overflow = 0; + var_out = extract_l (L_var1); + } + + return (var_out); +} + +/* + * + * Function Name : add + * + * Purpose : + * + * Performs the addition (var1+var2) with overflow control and saturation; + * the 16 bit result is set at +32767 when overflow occurs or at -32768 + * when underflow occurs. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +add (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_somme; + + L_somme = (Word32) var1 + var2; + var_out = sature (L_somme); + return (var_out); +} + +/* + * + * Function Name : sub + * + * Purpose : + * + * Performs the subtraction (var1+var2) with overflow control and satu- + * ration; the 16 bit result is set at +32767 when overflow occurs or at + * -32768 when underflow occurs. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +sub (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_diff; + + L_diff = (Word32) var1 - var2; + var_out = sature (L_diff); + return (var_out); +} + +/* + * + * Function Name : add_o + * + * Purpose : + * + * Performs the addition (var1+var2) with overflow control and saturation; + * the 16 bit result is set at +32767 when overflow occurs or at -32768 + * when underflow occurs. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +add_o (Word16 var1, Word16 var2, Flag *Overflow) +{ + Word16 var_out; + Word32 L_somme; + + L_somme = (Word32) var1 + var2; + var_out = sature_o (L_somme, Overflow); + return (var_out); +} + +/* + * + * Function Name : sub_o + * + * Purpose : + * + * Performs the subtraction (var1+var2) with overflow control and satu- + * ration; the 16 bit result is set at +32767 when overflow occurs or at + * -32768 when underflow occurs. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +sub_o (Word16 var1, Word16 var2, Flag *Overflow) +{ + Word16 var_out; + Word32 L_diff; + + L_diff = (Word32) var1 - var2; + var_out = sature_o (L_diff, Overflow); + return (var_out); +} + +/* + * + * Function Name : abs_s + * + * Purpose : + * + * Absolute value of var1; abs_s(-32768) = 32767. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +abs_s (Word16 var1) +{ + Word16 var_out; + + if (var1 == (Word16) 0X8000) { + var_out = MAX_16; + } + else { + if (var1 < 0) { + var_out = -var1; + } + else { + var_out = var1; + } + } + return (var_out); +} + +/* + * + * Function Name : shl + * + * Purpose : + * + * Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill + * the var2 LSB of the result. If var2 is negative, arithmetically shift + * var1 right by -var2 with sign extension. Saturate the result in case of + * underflows or overflows. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +shl (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 resultat; + + if (var2 < 0) { + var_out = shr (var1, -var2); + } + else { + resultat = (Word32) var1 *((Word32) 1 << var2); + if ((var2 > 15 && var1 != 0) + || (resultat != (Word32) ((Word16) resultat))) { + var_out = (var1 > 0) ? MAX_16 : MIN_16; + } + else { + var_out = extract_l (resultat); + } + } + return (var_out); +} + +/* + * + * Function Name : shr + * + * Purpose : + * + * Arithmetically shift the 16 bit input var1 right var2 positions with + * sign extension. If var2 is negative, arithmetically shift var1 left by + * -var2 with sign extension. Saturate the result in case of underflows or + * overflows. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +shr (Word16 var1, Word16 var2) +{ + Word16 var_out; + + if (var2 < 0) { + var_out = shl (var1, -var2); + } + else { + if (var2 >= 15) { + var_out = (var1 < 0) ? (Word16) (-1) : (Word16) 0; + } + else { + if (var1 < 0) { + var_out = ~((~var1) >> var2); + } + else { + var_out = var1 >> var2; + } + } + } + + return (var_out); +} + +/* + * + * Function Name : mult + * + * Purpose : + * + * Performs the multiplication of var1 by var2 and gives a 16 bit result + * which is scaled i.e.: + * mult(var1,var2) = shr((var1 times var2),15) and + * mult(-32768,-32768) = 32767. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +mult (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_produit; + + L_produit = (Word32) var1 *(Word32) var2; + + L_produit = (L_produit & (Word32) 0xffff8000L) >> 15; + + if (L_produit & (Word32) 0x00010000L) + L_produit = L_produit | (Word32) 0xffff0000L; + + var_out = sature (L_produit); + return (var_out); +} + + +/* + * + * Function Name : L_mult + * + * Purpose : + * + * L_mult is the 32 bit result of the multiplication of var1 times var2 + * with one shift left i.e.: + * L_mult(var1,var2) = shl((var1 times var2),1) and + * L_mult(-32768,-32768) = 2147483647. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_mult (Word16 var1, Word16 var2) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 *(Word32) var2; + if (L_var_out != (Word32) 0x40000000L) { + L_var_out *= 2; + } + else { + L_var_out = MAX_32; + } + + return (L_var_out); +} + +/* + * + * Function Name : L_mult_o + * + * Purpose : + * + * L_mult is the 32 bit result of the multiplication of var1 times var2 + * with one shift left i.e.: + * L_mult(var1,var2) = shl((var1 times var2),1) and + * L_mult(-32768,-32768) = 2147483647. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_mult_o (Word16 var1, Word16 var2, Flag *Overflow) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 *(Word32) var2; + if (L_var_out != (Word32) 0x40000000L) { + L_var_out *= 2; + } + else { + *Overflow = 1; + L_var_out = MAX_32; + } + + return (L_var_out); +} + +/* + * + * Function Name : negate + * + * Purpose : + * + * Negate var1 with saturation, saturate in the case where input is -32768: + * negate(var1) = sub(0,var1). + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +negate (Word16 var1) +{ + Word16 var_out; + + var_out = (var1 == MIN_16) ? MAX_16 : -var1; + return (var_out); +} + + +/* + * + * Function Name : extract_h + * + * Purpose : + * + * Return the 16 MSB of L_var1. + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32 ) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +extract_h (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) (L_var1 >> 16); + return (var_out); +} + +/* + * + * Function Name : extract_l + * + * Purpose : + * + * Return the 16 LSB of L_var1. + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32 ) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +extract_l (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) L_var1; + return (var_out); +} + + +/* + * + * Function Name : wround + * + * Purpose : + * + * Round the lower 16 bits of the 32 bit input number into its MS 16 bits + * with saturation. Shift the resulting bits right by 16 and return the 16 + * bit number: + * wround(L_var1) = extract_h(L_add(L_var1,32768)) + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32 ) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +wround (Word32 L_var1) +{ + Word16 var_out; + Word32 L_arrondi; + + L_arrondi = L_add (L_var1, (Word32) 0x00008000); + var_out = extract_h (L_arrondi); + return (var_out); +} + +/* + * + * Function Name : wround_o + * + * Purpose : + * + * Round the lower 16 bits of the 32 bit input number into its MS 16 bits + * with saturation. Shift the resulting bits right by 16 and return the 16 + * bit number: + * wround(L_var1) = extract_h(L_add(L_var1,32768)) + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32 ) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +wround_o (Word32 L_var1, Flag *Overflow) +{ + Word16 var_out; + Word32 L_arrondi; + + L_arrondi = L_add_o (L_var1, (Word32) 0x00008000, Overflow); + var_out = extract_h (L_arrondi); + return (var_out); +} + + +/* + * + * Function Name : L_mac + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Add the 32 bit + * result to L_var3 with saturation, return a 32 bit result: + * L_mac(L_var3,var1,var2) = L_add(L_var3,(L_mult(var1,var2)). + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_mac (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult (var1, var2); + L_var_out = L_add (L_var3, L_produit); + return (L_var_out); +} + + +/* + * + * Function Name : L_mac_o + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Add the 32 bit + * result to L_var3 with saturation, return a 32 bit result: + * L_mac(L_var3,var1,var2) = L_add(L_var3,(L_mult(var1,var2)). + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_mac_o (Word32 L_var3, Word16 var1, Word16 var2, Flag* Overflow) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult_o (var1, var2, Overflow); + L_var_out = L_add_o (L_var3, L_produit, Overflow); + return (L_var_out); +} + +/* + * + * Function Name : L_msu + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Subtract the 32 + * bit result to L_var3 with saturation, return a 32 bit result: + * L_msu(L_var3,var1,var2) = L_sub(L_var3,(L_mult(var1,var2)). + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_msu (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult (var1, var2); + L_var_out = L_sub (L_var3, L_produit); + return (L_var_out); +} + +/* + * + * Function Name : L_msu_o + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Subtract the 32 + * bit result to L_var3 with saturation, return a 32 bit result: + * L_msu(L_var3,var1,var2) = L_sub(L_var3,(L_mult(var1,var2)). + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_msu_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult_o (var1, var2, Overflow); + L_var_out = L_sub_o (L_var3, L_produit, Overflow); + return (L_var_out); +} + +/* + * + * Function Name : L_add + * + * Purpose : + * + * 32 bits addition of the two 32 bits variables (L_var1+L_var2) with + * overflow control and saturation; the result is set at +214783647 when + * overflow occurs or at -214783648 when underflow occurs. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * L_var2 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_add (Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + + L_var_out = L_var1 + L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) == 0) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_sub + * + * Purpose : + * + * 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with + * overflow control and saturation; the result is set at +214783647 when + * overflow occurs or at -214783648 when underflow occurs. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * L_var2 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_sub (Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + + L_var_out = L_var1 - L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) != 0) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_add_o + * + * Purpose : + * + * 32 bits addition of the two 32 bits variables (L_var1+L_var2) with + * overflow control and saturation; the result is set at +214783647 when + * overflow occurs or at -214783648 when underflow occurs. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * L_var2 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_add_o (Word32 L_var1, Word32 L_var2, Flag *Overflow) +{ + Word32 L_var_out; + + L_var_out = L_var1 + L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) == 0) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32; + *Overflow = 1; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_sub_o + * + * Purpose : + * + * 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with + * overflow control and saturation; the result is set at +214783647 when + * overflow occurs or at -214783648 when underflow occurs. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * L_var2 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_sub_o (Word32 L_var1, Word32 L_var2, Flag *Overflow) +{ + Word32 L_var_out; + + L_var_out = L_var1 - L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) != 0) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; + *Overflow = 1; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_negate + * + * Purpose : + * + * Negate the 32 bit variable L_var1 with saturation; saturate in the case + * where input is -2147483648 (0x8000 0000). + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_negate (Word32 L_var1) +{ + Word32 L_var_out; + + L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1; + return (L_var_out); +} + +/* + * + * Function Name : mult_r + * + * Purpose : + * + * Same as mult with rounding, i.e.: + * mult_r(var1,var2) = shr(((var1*var2) + 16384),15) and + * mult_r(-32768,-32768) = 32767. + * + * Complexity weight : 2 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +mult_r (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_produit_arr; + + L_produit_arr = (Word32) var1 *(Word32) var2; /* product */ + L_produit_arr += (Word32) 0x00004000; /* round */ + L_produit_arr &= (Word32) 0xffff8000L; + L_produit_arr >>= 15; /* shift */ + + if (L_produit_arr & (Word32) 0x00010000L) { /* sign extend when necessary */ + L_produit_arr |= (Word32) 0xffff0000L; + } + + var_out = sature (L_produit_arr); + return (var_out); +} + +/* + * + * Function Name : L_shl + * + * Purpose : + * + * Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero + * fill the var2 LSB of the result. If var2 is negative, L_var1 right by + * -var2 arithmetically shift with sign extension. Saturate the result in + * case of underflows or overflows. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_shl (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + /* initialization used only to suppress Microsoft Visual C++ warnings */ + L_var_out = 0L; + + if (var2 <= 0) { + L_var_out = L_shr (L_var1, -var2); + } + else { + for (; var2 > 0; var2--) { + if (L_var1 > (Word32) 0X3fffffffL) { + L_var_out = MAX_32; + break; + } + else { + if (L_var1 < (Word32) 0xc0000000L) { + L_var_out = MIN_32; + break; + } + } + L_var1 *= 2; + L_var_out = L_var1; + } + } + return (L_var_out); +} + + +/* + * + * Function Name : L_shl_o + * + * Purpose : + * + * Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero + * fill the var2 LSB of the result. If var2 is negative, L_var1 right by + * -var2 arithmetically shift with sign extension. Saturate the result in + * case of underflows or overflows. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_shl_o (Word32 L_var1, Word16 var2, Flag *Overflow) +{ + Word32 L_var_out; + + /* initialization used only to suppress Microsoft Visual C++ warnings */ + L_var_out = 0L; + + if (var2 <= 0) { + L_var_out = L_shr (L_var1, -var2); + } + else { + for (; var2 > 0; var2--) { + if (L_var1 > (Word32) 0X3fffffffL) { + *Overflow = 1; + L_var_out = MAX_32; + break; + } + else { + if (L_var1 < (Word32) 0xc0000000L) { + *Overflow = 1; + L_var_out = MIN_32; + break; + } + } + L_var1 *= 2; + L_var_out = L_var1; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_shr + * + * Purpose : + * + * Arithmetically shift the 32 bit input L_var1 right var2 positions with + * sign extension. If var2 is negative, arithmetically shift L_var1 left + * by -var2 and zero fill the var2 LSB of the result. Saturate the result + * in case of underflows or overflows. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_shr (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + if (var2 < 0) { + L_var_out = L_shl (L_var1, -var2); + } + else { + if (var2 >= 31) { + L_var_out = (L_var1 < 0L) ? -1 : 0; + } + else { + if (L_var1 < 0) { + L_var_out = ~((~L_var1) >> var2); + } + else { + L_var_out = L_var1 >> var2; + } + } + } + return (L_var_out); +} + +/* + * + * Function Name : shr_r + * + * Purpose : + * + * Same as shr(var1,var2) but with rounding. Saturate the result in case of + * underflows or overflows : + * If var2 is greater than zero : + * shr_r(var1,var2) = shr(add(var1,2**(var2-1)),var2) + * If var2 is less than zero : + * shr_r(var1,var2) = shr(var1,var2). + * + * Complexity weight : 2 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +shr_r (Word16 var1, Word16 var2) +{ + Word16 var_out; + + if (var2 > 15) { + var_out = 0; + } + else { + var_out = shr (var1, var2); + + if (var2 > 0) { + if ((var1 & ((Word16) 1 << (var2 - 1))) != 0) { + var_out++; + } + } + } + return (var_out); +} + +/* + * + * Function Name : mac_r + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Add the 32 bit + * result to L_var3 with saturation. Round the LS 16 bits of the result + * into the MS 16 bits with saturation and shift the result right by 16. + * Return a 16 bit result. + * mac_r(L_var3,var1,var2) = wround(L_mac(Lvar3,var1,var2)) + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. + * +*/ + +Word16 +mac_r (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word16 var_out; + + L_var3 = L_mac (L_var3, var1, var2); + L_var3 = L_add (L_var3, (Word32) 0x00008000); + var_out = extract_h (L_var3); + return (var_out); +} + + +/* + * + * Function Name : msu_r + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Subtract the 32 + * bit result to L_var3 with saturation. Round the LS 16 bits of the res- + * ult into the MS 16 bits with saturation and shift the result right by + * 16. Return a 16 bit result. + * msu_r(L_var3,var1,var2) = wround(L_msu(Lvar3,var1,var2)) + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. + * +*/ + +Word16 +msu_r (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word16 var_out; + + L_var3 = L_msu (L_var3, var1, var2); + L_var3 = L_add (L_var3, (Word32) 0x00008000); + var_out = extract_h (L_var3); + return (var_out); +} + + + +/* + * + * Function Name : L_deposit_h + * + * Purpose : + * + * Deposit the 16 bit var1 into the 16 MS bits of the 32 bit output. The + * 16 LS bits of the output are zeroed. + * + * Complexity weight : 2 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var_out <= 0x7fff 0000. + * +*/ + +Word32 +L_deposit_h (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 << 16; + return (L_var_out); +} + +/* + * + * Function Name : L_deposit_l + * + * Purpose : + * + * Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The + * 16 MS bits of the output are sign extended. + * + * Complexity weight : 2 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0xFFFF 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word32 +L_deposit_l (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1; + return (L_var_out); +} + +/* + * + * Function Name : L_shr_r + * + * Purpose : + * + * Same as L_shr(L_var1,var2)but with rounding. Saturate the result in case + * of underflows or overflows : + * If var2 is greater than zero : + * L_shr_r(var1,var2) = L_shr(L_add(L_var1,2**(var2-1)),var2) + * If var2 is less than zero : + * L_shr_r(var1,var2) = L_shr(L_var1,var2). + * + * Complexity weight : 3 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var1 <= 0x7fff ffff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_shr_r (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + if (var2 > 31) { + L_var_out = 0; + } + else { + L_var_out = L_shr (L_var1, var2); + if (var2 > 0) { + if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0) { + L_var_out++; + } + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_abs + * + * Purpose : + * + * Absolute value of L_var1; Saturate in case where the input is + * -214783648 + * + * Complexity weight : 3 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_abs (Word32 L_var1) +{ + Word32 L_var_out; + + if (L_var1 == MIN_32) { + L_var_out = MAX_32; + } + else { + if (L_var1 < 0) { + L_var_out = -L_var1; + } + else { + L_var_out = L_var1; + } + } + + return (L_var_out); +} + +/* + * + * Function Name : norm_s + * + * Purpose : + * + * Produces the number of left shift needed to normalize the 16 bit varia- + * ble var1 for positive values on the interval with minimum of 16384 and + * maximum of 32767, and for negative values on the interval with minimum + * of -32768 and maximum of -16384; in order to normalize the result, the + * following operation must be done : + * norm_var1 = shl(var1,norm_s(var1)). + * + * Complexity weight : 15 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x0000 000f. + * +*/ + +Word16 +norm_s (Word16 var1) +{ + Word16 var_out; + + if (var1 == 0) { + var_out = 0; + } + else { + if (var1 == (Word16) 0xffff) { + var_out = 15; + } + else { + if (var1 < 0) { + var1 = ~var1; + } + + for (var_out = 0; var1 < 0x4000; var_out++) { + var1 <<= 1; + } + } + } + + return (var_out); +} + + +/* + * + * Function Name : div_s + * + * Purpose : + * + * Produces a result which is the fractional integer division of var1 by + * var2; var1 and var2 must be positive and var2 must be greater or equal + * to var1; the result is positive (leading bit equal to 0) and truncated + * to 16 bits. + * If var1 = var2 then div(var1,var2) = 32767. + * + * Complexity weight : 18 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var1 <= var2 and var2 != 0. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : var1 <= var2 <= 0x0000 7fff and var2 != 0. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x0000 7fff. + * It's a Q15 value (point between b15 and b14). + * +*/ + +Word16 +div_s (Word16 var1, Word16 var2) +{ + Word16 var_out = 0; + Word16 iteration; + Word32 L_num; + Word32 L_denom; + + if ((var1 > var2) || (var1 < 0) || (var2 < 0)) { + printf ("Division Error var1=%d var2=%d\n", var1, var2); + exit (0); + } + + if (var2 == 0) { + printf ("Division by 0, Fatal error \n"); + exit (0); + } + + if (var1 == 0) { + var_out = 0; + } + else { + if (var1 == var2) { + var_out = MAX_16; + } + else { + L_num = L_deposit_l (var1); + L_denom = L_deposit_l (var2); + + for (iteration = 0; iteration < 15; iteration++) { + var_out <<= 1; + L_num <<= 1; + + if (L_num >= L_denom) { + L_num = L_sub (L_num, L_denom); + var_out = add (var_out, 1); + } + } + } + } + + return (var_out); +} + + +/* + * + * Function Name : norm_l + * + * Purpose : + * + * Produces the number of left shift needed to normalize the 32 bit varia- + * ble l_var1 for positive values on the interval with minimum of + * 1073741824 and maximum of 2147483647, and for negative values on the in- + * terval with minimum of -2147483648 and maximum of -1073741824; in order + * to normalize the result, the following operation must be done : + * norm_L_var1 = L_shl(L_var1,norm_l(L_var1)). + * + * Complexity weight : 30 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x0000 001f. + * +*/ + +Word16 +norm_l (Word32 L_var1) +{ + Word16 var_out; + + if (L_var1 == 0) { + var_out = 0; + } + else { + if (L_var1 == (Word32) 0xffffffffL) { + var_out = 31; + } + else { + if (L_var1 < 0) { + L_var1 = ~L_var1; + } + + for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++) { + L_var1 <<= 1; + } + } + } + + return (var_out); +} diff --git a/src/libs/libg729/cor_func.c b/src/libs/libg729/cor_func.c new file mode 100644 index 00000000..1346493a --- /dev/null +++ b/src/libs/libg729/cor_func.c @@ -0,0 +1,139 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/* Functions Corr_xy2() and Cor_h_x() */ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" + +/*---------------------------------------------------------------------------* + * Function corr_xy2() * + * ~~~~~~~~~~~~~~~~~~~ * + * Find the correlations between the target xn[], the filtered adaptive * + * codebook excitation y1[], and the filtered 1st codebook innovation y2[]. * + * g_coeff[2]:exp_g_coeff[2] = * + * g_coeff[3]:exp_g_coeff[3] = -2 * + * g_coeff[4]:exp_g_coeff[4] = 2 * + *---------------------------------------------------------------------------*/ + +void +Corr_xy2 (Word16 xn[], /* (i) Q0 :Target vector. */ + Word16 y1[], /* (i) Q0 :Adaptive codebook. */ + Word16 y2[], /* (i) Q12 :Filtered innovative vector. */ + Word16 g_coeff[], /* (o) Q[exp]:Correlations between xn,y1,y2 */ + Word16 exp_g_coeff[] /* (o) :Q-format of g_coeff[] */ + ) +{ + Word16 i, exp; + Word16 exp_y2y2, exp_xny2, exp_y1y2; + Word16 y2y2, xny2, y1y2; + Word32 L_acc; + Word16 scaled_y2[L_SUBFR]; /* Q9 */ + + /*------------------------------------------------------------------* + * Scale down y2[] from Q12 to Q9 to avoid overflow * + *------------------------------------------------------------------*/ + for (i = 0; i < L_SUBFR; i++) { + scaled_y2[i] = shr (y2[i], 3); + } + + /* Compute scalar product */ + L_acc = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_SUBFR; i++) + L_acc = L_mac (L_acc, scaled_y2[i], scaled_y2[i]); /* L_acc:Q19 */ + + exp = norm_l (L_acc); + y2y2 = wround (L_shl (L_acc, exp)); + exp_y2y2 = add (exp, 19 - 16); /* Q[19+exp-16] */ + + g_coeff[2] = y2y2; + exp_g_coeff[2] = exp_y2y2; + + /* Compute scalar product */ + L_acc = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_SUBFR; i++) + L_acc = L_mac (L_acc, xn[i], scaled_y2[i]); /* L_acc:Q10 */ + + exp = norm_l (L_acc); + xny2 = wround (L_shl (L_acc, exp)); + exp_xny2 = add (exp, 10 - 16); /* Q[10+exp-16] */ + + g_coeff[3] = negate (xny2); + exp_g_coeff[3] = sub (exp_xny2, 1); /* -2 */ + + /* Compute scalar product */ + L_acc = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_SUBFR; i++) + L_acc = L_mac (L_acc, y1[i], scaled_y2[i]); /* L_acc:Q10 */ + + exp = norm_l (L_acc); + y1y2 = wround (L_shl (L_acc, exp)); + exp_y1y2 = add (exp, 10 - 16); /* Q[10+exp-16] */ + + g_coeff[4] = y1y2; + exp_g_coeff[4] = sub (exp_y1y2, 1);; /* 2 */ + + return; +} + + +/*--------------------------------------------------------------------------* + * Function Cor_h_X() * + * ~~~~~~~~~~~~~~~~~~~ * + * Compute correlations of input response h[] with the target vector X[]. * + *--------------------------------------------------------------------------*/ + +void +Cor_h_X (Word16 h[], /* (i) Q12 :Impulse response of filters */ + Word16 X[], /* (i) :Target vector */ + Word16 D[] + /* (o) :Correlations between h[] and D[] */ + /* Normalized to 13 bits */ + ) +{ + Word16 i, j; + Word32 s, max, L_temp; + Word32 y32[L_SUBFR]; + + /* first keep the result on 32 bits and find absolute maximum */ + + max = 0; + + for (i = 0; i < L_SUBFR; i++) { + s = 0; + for (j = i; j < L_SUBFR; j++) + s = L_mac (s, X[j], h[j - i]); + + y32[i] = s; + + s = L_abs (s); + L_temp = L_sub (s, max); + if (L_temp > 0L) { + max = s; + } + } + + /* Find the number of right shifts to do on y32[] */ + /* so that maximum is on 13 bits */ + + j = norm_l (max); + if (sub (j, 16) > 0) { + j = 16; + } + + j = sub (18, j); + + for (i = 0; i < L_SUBFR; i++) { + D[i] = extract_l (L_shr (y32[i], j)); + } + + return; + +} diff --git a/src/libs/libg729/de_acelp.c b/src/libs/libg729/de_acelp.c new file mode 100644 index 00000000..3fa230cd --- /dev/null +++ b/src/libs/libg729/de_acelp.c @@ -0,0 +1,73 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-----------------------------------------------------------* + * Function Decod_ACELP() * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * Algebraic codebook decoder. * + *----------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" + +void +Decod_ACELP (Word16 sign, /* (i) : signs of 4 pulses. */ + Word16 index, /* (i) : Positions of the 4 pulses. */ + Word16 cod[] /* (o) Q13 : algebraic (fixed) codebook excitation */ + ) +{ + Word16 i, j; + Word16 pos[4]; + + + /* Decode the positions */ + + i = index & (Word16) 7; + pos[0] = add (i, shl (i, 2)); /* pos0 =i*5 */ + + index = shr (index, 3); + i = index & (Word16) 7; + i = add (i, shl (i, 2)); /* pos1 =i*5+1 */ + pos[1] = add (i, 1); + + index = shr (index, 3); + i = index & (Word16) 7; + i = add (i, shl (i, 2)); /* pos2 =i*5+1 */ + pos[2] = add (i, 2); + + index = shr (index, 3); + j = index & (Word16) 1; + index = shr (index, 1); + i = index & (Word16) 7; + i = add (i, shl (i, 2)); /* pos3 =i*5+3+j */ + i = add (i, 3); + pos[3] = add (i, j); + + /* decode the signs and build the codeword */ + + for (i = 0; i < L_SUBFR; i++) { + cod[i] = 0; + } + + for (j = 0; j < 4; j++) { + + i = sign & (Word16) 1; + sign = shr (sign, 1); + + if (i != 0) { + cod[pos[j]] = 8191; /* Q13 +1.0 */ + } + else { + cod[pos[j]] = -8192; /* Q13 -1.0 */ + } + } + + return; +} diff --git a/src/libs/libg729/dec_gain.c b/src/libs/libg729/dec_gain.c new file mode 100644 index 00000000..1a9dec81 --- /dev/null +++ b/src/libs/libg729/dec_gain.c @@ -0,0 +1,109 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" +#include "tab_ld8a.h" + +/*---------------------------------------------------------------------------* + * Function Dec_gain * + * ~~~~~~~~~~~~~~~~~~ * + * Decode the pitch and codebook gains * + * * + *---------------------------------------------------------------------------* + * input arguments: * + * * + * index :Quantization index * + * code[] :Innovative code vector * + * L_subfr :Subframe size * + * bfi :Bad frame indicator * + * * + * output arguments: * + * * + * gain_pit :Quantized pitch gain * + * gain_cod :Quantized codebook gain * + * * + *---------------------------------------------------------------------------*/ +void +Dec_gain (DecState *decoder, + Word16 index, /* (i) :Index of quantization. */ + Word16 code[], /* (i) Q13 :Innovative vector. */ + Word16 L_subfr, /* (i) :Subframe length. */ + Word16 bfi, /* (i) :Bad frame indicator */ + Word16 * gain_pit, /* (o) Q14 :Pitch gain. */ + Word16 * gain_cod /* (o) Q1 :Code gain. */ + ) +{ + Word16 index1, index2, tmp; + Word16 gcode0, exp_gcode0; + Word32 L_gbk12, L_acc, L_accb; + void Gain_predict (Word16 past_qua_en[], Word16 code[], Word16 L_subfr, + Word16 * gcode0, Word16 * exp_gcode0); + void Gain_update (Word16 past_qua_en[], Word32 L_gbk12); + void Gain_update_erasure (Word16 past_qua_en[]); + + /* Gain predictor, Past quantized energies = -14.0 in Q10 */ + + + + /*-------------- Case of erasure. ---------------*/ + + if (bfi != 0) { + *gain_pit = mult (*gain_pit, 29491); /* *0.9 in Q15 */ + if (sub (*gain_pit, 29491) > 0) + *gain_pit = 29491; + *gain_cod = mult (*gain_cod, 32111); /* *0.98 in Q15 */ + + /*----------------------------------------------* + * update table of past quantized energies * + * (frame erasure) * + *----------------------------------------------*/ + Gain_update_erasure (decoder->past_qua_en); + + return; + } + + /*-------------- Decode pitch gain ---------------*/ + + index1 = imap1[shr (index, NCODE2_B)]; + index2 = imap2[index & (NCODE2 - 1)]; + *gain_pit = add (gbk1[index1][0], gbk2[index2][0]); + + /*-------------- Decode codebook gain ---------------*/ + + /*---------------------------------------------------* + *- energy due to innovation -* + *- predicted energy -* + *- predicted codebook gain => gcode0[exp_gcode0] -* + *---------------------------------------------------*/ + + Gain_predict (decoder->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0); + + /*-----------------------------------------------------------------* + * *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; * + *-----------------------------------------------------------------*/ + + L_acc = L_deposit_l (gbk1[index1][1]); + L_accb = L_deposit_l (gbk2[index2][1]); + L_gbk12 = L_add (L_acc, L_accb); /* Q13 */ + tmp = extract_l (L_shr (L_gbk12, 1)); /* Q12 */ + L_acc = L_mult (tmp, gcode0); /* Q[exp_gcode0+12+1] */ + + L_acc = L_shl (L_acc, add (negate (exp_gcode0), (-12 - 1 + 1 + 16))); + *gain_cod = extract_h (L_acc); /* Q1 */ + + /*----------------------------------------------* + * update table of past quantized energies * + *----------------------------------------------*/ + Gain_update (decoder->past_qua_en, L_gbk12); + + return; + +} diff --git a/src/libs/libg729/dec_lag3.c b/src/libs/libg729/dec_lag3.c new file mode 100644 index 00000000..196dd5f0 --- /dev/null +++ b/src/libs/libg729/dec_lag3.c @@ -0,0 +1,79 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------------------------* + * Function Dec_lag3 * + * ~~~~~~~~ * + * Decoding of fractional pitch lag with 1/3 resolution. * + * See "Enc_lag3.c" for more details about the encoding procedure. * + *------------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" + +void +Dec_lag3 (Word16 index, /* input : received pitch index */ + Word16 pit_min, /* input : minimum pitch lag */ + Word16 pit_max, /* input : maximum pitch lag */ + Word16 i_subfr, /* input : subframe flag */ + Word16 * T0, /* output: integer part of pitch lag */ + Word16 * T0_frac /* output: fractional part of pitch lag */ + ) +{ + Word16 i; + Word16 T0_min, T0_max; + + if (i_subfr == 0) { /* if 1st subframe */ + if (sub (index, 197) < 0) { + /* *T0 = (index+2)/3 + 19 */ + + *T0 = add (mult (add (index, 2), 10923), 19); + + /* *T0_frac = index - *T0*3 + 58 */ + + i = add (add (*T0, *T0), *T0); + *T0_frac = add (sub (index, i), 58); + } + else { + *T0 = sub (index, 112); + *T0_frac = 0; + } + + } + + else { /* second subframe */ + + /* find T0_min and T0_max for 2nd subframe */ + + T0_min = sub (*T0, 5); + if (sub (T0_min, pit_min) < 0) { + T0_min = pit_min; + } + + T0_max = add (T0_min, 9); + if (sub (T0_max, pit_max) > 0) { + T0_max = pit_max; + T0_min = sub (T0_max, 9); + } + + /* i = (index+2)/3 - 1 */ + /* *T0 = i + t0_min; */ + + i = sub (mult (add (index, 2), 10923), 1); + *T0 = add (i, T0_min); + + /* t0_frac = index - 2 - i*3; */ + + i = add (add (i, i), i); + *T0_frac = sub (sub (index, 2), i); + } + + return; +} diff --git a/src/libs/libg729/dspfunc.c b/src/libs/libg729/dspfunc.c new file mode 100644 index 00000000..f84f1b13 --- /dev/null +++ b/src/libs/libg729/dspfunc.c @@ -0,0 +1,182 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "typedef.h" +#include "basic_op.h" + +#include "ld8a.h" +#include "tab_ld8a.h" + +/*___________________________________________________________________________ + | | + | Function Name : Pow2() | + | | + | L_x = pow(2.0, exponent.fraction) | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The function Pow2(L_x) is approximated by a table and linear | + | interpolation. | + | | + | 1- i = bit10-b15 of fraction, 0 <= i <= 31 | + | 2- a = bit0-b9 of fraction | + | 3- L_x = tabpow[i]<<16 - (tabpow[i] - tabpow[i+1]) * a * 2 | + | 4- L_x = L_x >> (30-exponent) (with rounding) | + |___________________________________________________________________________| +*/ + + +Word32 +Pow2 ( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */ + Word16 exponent, /* (i) Q0 : Integer part. (range: 0<=val<=30) */ + Word16 fraction /* (i) Q15 : Fractional part. (range: 0.0<=val<1.0) */ + ) +{ + Word16 exp, i, a, tmp; + Word32 L_x; + + L_x = L_mult (fraction, 32); /* L_x = fraction<<6 */ + i = extract_h (L_x); /* Extract b10-b15 of fraction */ + L_x = L_shr (L_x, 1); + a = extract_l (L_x); /* Extract b0-b9 of fraction */ + a = a & (Word16) 0x7fff; + + L_x = L_deposit_h (tabpow[i]); /* tabpow[i] << 16 */ + tmp = sub (tabpow[i], tabpow[i + 1]); /* tabpow[i] - tabpow[i+1] */ + L_x = L_msu (L_x, tmp, a); /* L_x -= tmp*a*2 */ + + exp = sub (30, exponent); + L_x = L_shr_r (L_x, exp); + + return (L_x); +} + +/*___________________________________________________________________________ + | | + | Function Name : Log2() | + | | + | Compute log2(L_x). | + | L_x is positive. | + | | + | if L_x is negative or zero, result is 0. | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The function Log2(L_x) is approximated by a table and linear | + | interpolation. | + | | + | 1- Normalization of L_x. | + | 2- exponent = 30-exponent | + | 3- i = bit25-b31 of L_x, 32 <= i <= 63 ->because of normalization. | + | 4- a = bit10-b24 | + | 5- i -=32 | + | 6- fraction = tablog[i]<<16 - (tablog[i] - tablog[i+1]) * a * 2 | + |___________________________________________________________________________| +*/ + +void +Log2 (Word32 L_x, /* (i) Q0 : input value */ + Word16 * exponent, /* (o) Q0 : Integer part of Log2. (range: 0<=val<=30) */ + Word16 * fraction /* (o) Q15: Fractional part of Log2. (range: 0<=val<1) */ + ) +{ + Word16 exp, i, a, tmp; + Word32 L_y; + + if (L_x <= (Word32) 0) { + *exponent = 0; + *fraction = 0; + return; + } + + exp = norm_l (L_x); + L_x = L_shl (L_x, exp); /* L_x is normalized */ + + *exponent = sub (30, exp); + + L_x = L_shr (L_x, 9); + i = extract_h (L_x); /* Extract b25-b31 */ + L_x = L_shr (L_x, 1); + a = extract_l (L_x); /* Extract b10-b24 of fraction */ + a = a & (Word16) 0x7fff; + + i = sub (i, 32); + + L_y = L_deposit_h (tablog[i]); /* tablog[i] << 16 */ + tmp = sub (tablog[i], tablog[i + 1]); /* tablog[i] - tablog[i+1] */ + L_y = L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */ + + *fraction = extract_h (L_y); + + return; +} + +/*___________________________________________________________________________ + | | + | Function Name : Inv_sqrt | + | | + | Compute 1/sqrt(L_x). | + | L_x is positive. | + | | + | if L_x is negative or zero, result is 1 (3fff ffff). | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The function 1/sqrt(L_x) is approximated by a table and linear | + | interpolation. | + | | + | 1- Normalization of L_x. | + | 2- If (30-exponent) is even then shift right once. | + | 3- exponent = (30-exponent)/2 +1 | + | 4- i = bit25-b31 of L_x, 16 <= i <= 63 ->because of normalization. | + | 5- a = bit10-b24 | + | 6- i -=16 | + | 7- L_y = tabsqr[i]<<16 - (tabsqr[i] - tabsqr[i+1]) * a * 2 | + | 8- L_y >>= exponent | + |___________________________________________________________________________| +*/ + + +Word32 +Inv_sqrt ( /* (o) Q30 : output value (range: 0<=val<1) */ + Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ + ) +{ + Word16 exp, i, a, tmp; + Word32 L_y; + + if (L_x <= (Word32) 0) + return ((Word32) 0x3fffffffL); + + exp = norm_l (L_x); + L_x = L_shl (L_x, exp); /* L_x is normalize */ + + exp = sub (30, exp); + if ((exp & 1) == 0) /* If exponent even -> shift right */ + L_x = L_shr (L_x, 1); + + exp = shr (exp, 1); + exp = add (exp, 1); + + L_x = L_shr (L_x, 9); + i = extract_h (L_x); /* Extract b25-b31 */ + L_x = L_shr (L_x, 1); + a = extract_l (L_x); /* Extract b10-b24 */ + a = a & (Word16) 0x7fff; + + i = sub (i, 16); + + L_y = L_deposit_h (tabsqr[i]); /* tabsqr[i] << 16 */ + tmp = sub (tabsqr[i], tabsqr[i + 1]); /* tabsqr[i] - tabsqr[i+1]) */ + L_y = L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */ + + L_y = L_shr (L_y, exp); /* denormalization */ + + return (L_y); +} diff --git a/src/libs/libg729/g729_acelp_ca.cpp b/src/libs/libg729/g729_acelp_ca.cpp new file mode 100644 index 00000000..cfe91421 --- /dev/null +++ b/src/libs/libg729/g729_acelp_ca.cpp @@ -0,0 +1,991 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*---------------------------------------------------------------------------* + * Function ACELP_Code_A() * + * ~~~~~~~~~~~~~~~~~~~~~~~~ * + * Find Algebraic codebook for G.729A * + *--------------------------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" + +/* Constants defined in ld8a.h */ +/* L_SUBFR -> Lenght of subframe. */ +/* NB_POS -> Number of positions for each pulse. */ +/* STEP -> Step betweem position of the same pulse. */ +/* MSIZE -> Size of vectors for cross-correlation between two pulses. */ + + +/* local routines definition */ + +void Cor_h (Word16 * H, /* (i) Q12 :Impulse response of filters */ + Word16 * rr /* (o) :Correlations of H[] */ +); +Word16 D4i40_17_fast ( /*(o) : Index of pulses positions. */ + Word16 dn[], /* (i) : Correlations between h[] and Xn[]. */ + Word16 * rr, /* (i) : Correlations of impulse response h[]. */ + Word16 h[], /* (i) Q12: Impulse response of filters. */ + Word16 cod[], /* (o) Q13: Selected algebraic codeword. */ + Word16 y[], /* (o) Q12: Filtered algebraic codeword. */ + Word16 * sign /* (o) : Signs of 4 pulses. */ + ); + + /*-----------------------------------------------------------------* + * Main ACELP function. * + *-----------------------------------------------------------------*/ + +Word16 +ACELP_Code_A ( /* (o) :index of pulses positions */ + Word16 x[], /* (i) :Target vector */ + Word16 h[], /* (i) Q12 :Inpulse response of filters */ + Word16 T0, /* (i) :Pitch lag */ + Word16 pitch_sharp, /* (i) Q14 :Last quantized pitch gain */ + Word16 code[], /* (o) Q13 :Innovative codebook */ + Word16 y[], /* (o) Q12 :Filtered innovative codebook */ + Word16 * sign /* (o) :Signs of 4 pulses */ + ) +{ + Word16 i, index, sharp; + Word16 Dn[L_SUBFR]; + Word16 rr[DIM_RR]; + + /*-----------------------------------------------------------------* + * Include fixed-gain pitch contribution into impulse resp. h[] * + * Find correlations of h[] needed for the codebook search. * + *-----------------------------------------------------------------*/ + + sharp = shl (pitch_sharp, 1); /* From Q14 to Q15 */ + if (T0 < L_SUBFR) + for (i = T0; i < L_SUBFR; i++) /* h[i] += pitch_sharp*h[i-T0] */ + h[i] = add (h[i], mult (h[i - T0], sharp)); + + Cor_h (h, rr); + + /*-----------------------------------------------------------------* + * Compute correlation of target vector with impulse response. * + *-----------------------------------------------------------------*/ + + Cor_h_X (h, x, Dn); + + /*-----------------------------------------------------------------* + * Find innovative codebook. * + *-----------------------------------------------------------------*/ + + index = D4i40_17_fast (Dn, rr, h, code, y, sign); + + /*-----------------------------------------------------------------* + * Compute innovation vector gain. * + * Include fixed-gain pitch contribution into code[]. * + *-----------------------------------------------------------------*/ + + if (T0 < L_SUBFR) + for (i = T0; i < L_SUBFR; i++) /* code[i] += pitch_sharp*code[i-T0] */ + code[i] = add (code[i], mult (code[i - T0], sharp)); + + return index; +} + + + +/*--------------------------------------------------------------------------* + * Function Cor_h() * + * ~~~~~~~~~~~~~~~~~ * + * Compute correlations of h[] needed for the codebook search. * + *--------------------------------------------------------------------------*/ + +void +Cor_h (Word16 * H, /* (i) Q12 :Impulse response of filters */ + Word16 * rr /* (o) :Correlations of H[] */ + ) +{ + Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4; + Word16 *rri0i1, *rri0i2, *rri0i3, *rri0i4; + Word16 *rri1i2, *rri1i3, *rri1i4; + Word16 *rri2i3, *rri2i4; + + Word16 *p0, *p1, *p2, *p3, *p4; + + Word16 *ptr_hd, *ptr_hf, *ptr_h1, *ptr_h2; + Word32 cor; + Word16 i, k, ldec, l_fin_sup, l_fin_inf; + Word16 h[L_SUBFR]; + + /* Scaling h[] for maximum precision */ + + cor = 0; + for (i = 0; i < L_SUBFR; i++) + cor = L_mac (cor, H[i], H[i]); + + if (sub (extract_h (cor), 32000) > 0) { + for (i = 0; i < L_SUBFR; i++) { + h[i] = shr (H[i], 1); + } + } + else { + k = norm_l (cor); + k = shr (k, 1); + + for (i = 0; i < L_SUBFR; i++) { + h[i] = shl (H[i], k); + } + } + + + + /*------------------------------------------------------------* + * Compute rri0i0[], rri1i1[], rri2i2[], rri3i3 and rri4i4[] * + *------------------------------------------------------------*/ + /* Init pointers */ + rri0i0 = rr; + rri1i1 = rri0i0 + NB_POS; + rri2i2 = rri1i1 + NB_POS; + rri3i3 = rri2i2 + NB_POS; + rri4i4 = rri3i3 + NB_POS; + rri0i1 = rri4i4 + NB_POS; + rri0i2 = rri0i1 + MSIZE; + rri0i3 = rri0i2 + MSIZE; + rri0i4 = rri0i3 + MSIZE; + rri1i2 = rri0i4 + MSIZE; + rri1i3 = rri1i2 + MSIZE; + rri1i4 = rri1i3 + MSIZE; + rri2i3 = rri1i4 + MSIZE; + rri2i4 = rri2i3 + MSIZE; + + p0 = rri0i0 + NB_POS - 1; /* Init pointers to last position of rrixix[] */ + p1 = rri1i1 + NB_POS - 1; + p2 = rri2i2 + NB_POS - 1; + p3 = rri3i3 + NB_POS - 1; + p4 = rri4i4 + NB_POS - 1; + + ptr_h1 = h; + cor = 0; + for (i = 0; i < NB_POS; i++) { + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p4-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p3-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p2-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p1-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p0-- = extract_h (cor); + } + + /*-----------------------------------------------------------------* + * Compute elements of: rri2i3[], rri1i2[], rri0i1[] and rri0i4[] * + *-----------------------------------------------------------------*/ + + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + ldec = NB_POS + 1; + + ptr_hd = h; + ptr_hf = ptr_hd + 1; + + for (k = 0; k < NB_POS; k++) { + + p3 = rri2i3 + l_fin_sup; + p2 = rri1i2 + l_fin_sup; + p1 = rri0i1 + l_fin_sup; + p0 = rri0i4 + l_fin_inf; + + cor = 0; + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + + /*---------------------------------------------------------------------* + * Compute elements of: rri2i4[], rri1i3[], rri0i2[], rri1i4[], rri0i3 * + *---------------------------------------------------------------------*/ + + ptr_hd = h; + ptr_hf = ptr_hd + 2; + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + for (k = 0; k < NB_POS; k++) { + + p4 = rri2i4 + l_fin_sup; + p3 = rri1i3 + l_fin_sup; + p2 = rri0i2 + l_fin_sup; + p1 = rri1i4 + l_fin_inf; + p0 = rri0i3 + l_fin_inf; + + cor = 0; + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p4 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p4 -= ldec; + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p4 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + + /*----------------------------------------------------------------------* + * Compute elements of: rri1i4[], rri0i3[], rri2i4[], rri1i3[], rri0i2 * + *----------------------------------------------------------------------*/ + + ptr_hd = h; + ptr_hf = ptr_hd + 3; + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + for (k = 0; k < NB_POS; k++) { + + p4 = rri1i4 + l_fin_sup; + p3 = rri0i3 + l_fin_sup; + p2 = rri2i4 + l_fin_inf; + p1 = rri1i3 + l_fin_inf; + p0 = rri0i2 + l_fin_inf; + + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + cor = 0; + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p4 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p4 -= ldec; + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p4 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + + /*----------------------------------------------------------------------* + * Compute elements of: rri0i4[], rri2i3[], rri1i2[], rri0i1[] * + *----------------------------------------------------------------------*/ + + ptr_hd = h; + ptr_hf = ptr_hd + 4; + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + for (k = 0; k < NB_POS; k++) { + + p3 = rri0i4 + l_fin_sup; + p2 = rri2i3 + l_fin_inf; + p1 = rri1i2 + l_fin_inf; + p0 = rri0i1 + l_fin_inf; + + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + cor = 0; + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + return; +} + + + +/*------------------------------------------------------------------------* + * Function D4i40_17_fast() * + * ~~~~~~~~~ * + * Algebraic codebook for ITU 8kb/s. * + * -> 17 bits; 4 pulses in a frame of 40 samples * + * * + *------------------------------------------------------------------------* + * The code length is 40, containing 4 nonzero pulses i0, i1, i2, i3. * + * Each pulses can have 8 possible positions (positive or negative) * + * except i3 that have 16 possible positions. * + * * + * i0 (+-1) : 0, 5, 10, 15, 20, 25, 30, 35 * + * i1 (+-1) : 1, 6, 11, 16, 21, 26, 31, 36 * + * i2 (+-1) : 2, 7, 12, 17, 22, 27, 32, 37 * + * i3 (+-1) : 3, 8, 13, 18, 23, 28, 33, 38 * + * 4, 9, 14, 19, 24, 29, 34, 39 * + *------------------------------------------------------------------------*/ + +Word16 +D4i40_17_fast ( /*(o) : Index of pulses positions. */ + Word16 dn[], /* (i) : Correlations between h[] and Xn[]. */ + Word16 rr[], /* (i) : Correlations of impulse response h[]. */ + Word16 h[], /* (i) Q12: Impulse response of filters. */ + Word16 cod[], /* (o) Q13: Selected algebraic codeword. */ + Word16 y[], /* (o) Q12: Filtered algebraic codeword. */ + Word16 * sign /* (o) : Signs of 4 pulses. */ + ) +{ + Word16 i0, i1, i2, i3, ip0, ip1, ip2, ip3; + Word16 i, j, ix, iy, track, trk, max; + Word16 prev_i0, i1_offset; + Word16 psk, ps, ps0, ps1, ps2, sq, sq2; + Word16 alpk, alp, alp_16; + Word32 s, alp0, alp1, alp2; + Word16 *p0, *p1, *p2, *p3, *p4; + Word16 sign_dn[L_SUBFR], sign_dn_inv[L_SUBFR], *psign; + Word16 tmp_vect[NB_POS]; + Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4; + Word16 *rri0i1, *rri0i2, *rri0i3, *rri0i4; + Word16 *rri1i2, *rri1i3, *rri1i4; + Word16 *rri2i3, *rri2i4; + + Word16 *ptr_rri0i3_i4; + Word16 *ptr_rri1i3_i4; + Word16 *ptr_rri2i3_i4; + Word16 *ptr_rri3i3_i4; + + /* Init pointers */ + rri0i0 = rr; + rri1i1 = rri0i0 + NB_POS; + rri2i2 = rri1i1 + NB_POS; + rri3i3 = rri2i2 + NB_POS; + rri4i4 = rri3i3 + NB_POS; + rri0i1 = rri4i4 + NB_POS; + rri0i2 = rri0i1 + MSIZE; + rri0i3 = rri0i2 + MSIZE; + rri0i4 = rri0i3 + MSIZE; + rri1i2 = rri0i4 + MSIZE; + rri1i3 = rri1i2 + MSIZE; + rri1i4 = rri1i3 + MSIZE; + rri2i3 = rri1i4 + MSIZE; + rri2i4 = rri2i3 + MSIZE; + + /*-----------------------------------------------------------------------* + * Chose the sign of the impulse. * + *-----------------------------------------------------------------------*/ + + for (i = 0; i < L_SUBFR; i++) { + if (dn[i] >= 0) { + sign_dn[i] = MAX_16; + sign_dn_inv[i] = MIN_16; + } + else { + sign_dn[i] = MIN_16; + sign_dn_inv[i] = MAX_16; + dn[i] = negate (dn[i]); + } + } + + /*-------------------------------------------------------------------* + * Modification of rrixiy[] to take signs into account. * + *-------------------------------------------------------------------*/ + + p0 = rri0i1; + p1 = rri0i2; + p2 = rri0i3; + p3 = rri0i4; + + for (i0 = 0; i0 < L_SUBFR; i0 += STEP) { + psign = sign_dn; + if (psign[i0] < 0) + psign = sign_dn_inv; + + for (i1 = 1; i1 < L_SUBFR; i1 += STEP) { + *p0 = mult (*p0, psign[i1]); p0++; + *p1 = mult (*p1, psign[i1 + 1]); p1++; + *p2 = mult (*p2, psign[i1 + 2]); p2++; + *p3 = mult (*p3, psign[i1 + 3]); p3++; + } + } + + p0 = rri1i2; + p1 = rri1i3; + p2 = rri1i4; + + for (i1 = 1; i1 < L_SUBFR; i1 += STEP) { + psign = sign_dn; + if (psign[i1] < 0) + psign = sign_dn_inv; + + for (i2 = 2; i2 < L_SUBFR; i2 += STEP) { + *p0 = mult (*p0, psign[i2]); p0++; + *p1 = mult (*p1, psign[i2 + 1]); p1++; + *p2 = mult (*p2, psign[i2 + 2]); p2++; + } + } + + p0 = rri2i3; + p1 = rri2i4; + + for (i2 = 2; i2 < L_SUBFR; i2 += STEP) { + psign = sign_dn; + if (psign[i2] < 0) + psign = sign_dn_inv; + + for (i3 = 3; i3 < L_SUBFR; i3 += STEP) { + *p0 = mult (*p0, psign[i3]); p0++; + *p1 = mult (*p1, psign[i3 + 1]); p1++; + } + } + + + /*-------------------------------------------------------------------* + * Search the optimum positions of the four pulses which maximize * + * square(correlation) / energy * + *-------------------------------------------------------------------*/ + + psk = -1; + alpk = 1; + + ptr_rri0i3_i4 = rri0i3; + ptr_rri1i3_i4 = rri1i3; + ptr_rri2i3_i4 = rri2i3; + ptr_rri3i3_i4 = rri3i3; + + /* Initializations only to remove warning from some compilers */ + + ip0 = 0; + ip1 = 1; + ip2 = 2; + ip3 = 3; + ix = 0; + iy = 0; + ps = 0; + + /* search 2 times: track 3 and 4 */ + for (track = 3, trk = 0; track < 5; track++, trk++) { + /*------------------------------------------------------------------* + * depth first search 3, phase A: track 2 and 3/4. * + *------------------------------------------------------------------*/ + + sq = -1; + alp = 1; + + /* i0 loop: 2 positions in track 2 */ + + prev_i0 = -1; + + for (i = 0; i < 2; i++) { + max = -1; + /* search "dn[]" maximum position in track 2 */ + for (j = 2; j < L_SUBFR; j += STEP) { + if ((sub (dn[j], max) > 0) && (sub (prev_i0, j) != 0)) { + max = dn[j]; + i0 = j; + } + } + prev_i0 = i0; + + j = mult (i0, 6554); /* j = i0/5 */ + p0 = rri2i2 + j; + + ps1 = dn[i0]; + alp1 = L_mult (*p0, _1_4); + + /* i1 loop: 8 positions in track 2 */ + + p0 = ptr_rri2i3_i4 + shl (j, 3); + p1 = ptr_rri3i3_i4; + + for (i1 = track; i1 < L_SUBFR; i1 += STEP) { + ps2 = add (ps1, dn[i1]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */ + alp2 = L_mac (alp1, *p0++, _1_2); + alp2 = L_mac (alp2, *p1++, _1_4); + + sq2 = mult (ps2, ps2); + alp_16 = wround (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + if (s > 0) { + sq = sq2; + ps = ps2; + alp = alp_16; + ix = i0; + iy = i1; + } + } + } + + i0 = ix; + i1 = iy; + i1_offset = shl (mult (i1, 6554), 3); /* j = 8*(i1/5) */ + + /*------------------------------------------------------------------* + * depth first search 3, phase B: track 0 and 1. * + *------------------------------------------------------------------*/ + + ps0 = ps; + alp0 = L_mult (alp, _1_4); + + sq = -1; + alp = 1; + + /* build vector for next loop to decrease complexity */ + + p0 = rri1i2 + mult (i0, 6554); + p1 = ptr_rri1i3_i4 + mult (i1, 6554); + p2 = rri1i1; + p3 = tmp_vect; + + for (i3 = 1; i3 < L_SUBFR; i3 += STEP) { + /* rrv[i3] = rr[i3][i3] + rr[i0][i3] + rr[i1][i3]; */ + s = L_mult (*p0, _1_4); + p0 += NB_POS; + s = L_mac (s, *p1, _1_4); + p1 += NB_POS; + s = L_mac (s, *p2++, _1_8); + *p3++ = wround (s); + } + + /* i2 loop: 8 positions in track 0 */ + + p0 = rri0i2 + mult (i0, 6554); + p1 = ptr_rri0i3_i4 + mult (i1, 6554); + p2 = rri0i0; + p3 = rri0i1; + + for (i2 = 0; i2 < L_SUBFR; i2 += STEP) { + ps1 = add (ps0, dn[i2]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */ + alp1 = L_mac (alp0, *p0, _1_8); + p0 += NB_POS; + alp1 = L_mac (alp1, *p1, _1_8); + p1 += NB_POS; + alp1 = L_mac (alp1, *p2++, _1_16); + + /* i3 loop: 8 positions in track 1 */ + + p4 = tmp_vect; + + for (i3 = 1; i3 < L_SUBFR; i3 += STEP) { + ps2 = add (ps1, dn[i3]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */ + alp2 = L_mac (alp1, *p3++, _1_8); + alp2 = L_mac (alp2, *p4++, _1_2); + + sq2 = mult (ps2, ps2); + alp_16 = wround (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + if (s > 0) { + sq = sq2; + alp = alp_16; + ix = i2; + iy = i3; + } + } + } + + /*----------------------------------------------------------------* + * depth first search 3: compare codevector with the best case. * + *----------------------------------------------------------------*/ + + s = L_msu (L_mult (alpk, sq), psk, alp); + if (s > 0) { + psk = sq; + alpk = alp; + ip2 = i0; + ip3 = i1; + ip0 = ix; + ip1 = iy; + } + + /*------------------------------------------------------------------* + * depth first search 4, phase A: track 3 and 0. * + *------------------------------------------------------------------*/ + + sq = -1; + alp = 1; + + /* i0 loop: 2 positions in track 3/4 */ + + prev_i0 = -1; + + for (i = 0; i < 2; i++) { + max = -1; + /* search "dn[]" maximum position in track 3/4 */ + for (j = track; j < L_SUBFR; j += STEP) { + if ((sub (dn[j], max) > 0) && (sub (prev_i0, j) != 0)) { + max = dn[j]; + i0 = j; + } + } + prev_i0 = i0; + + j = mult (i0, 6554); /* j = i0/5 */ + p0 = ptr_rri3i3_i4 + j; + + ps1 = dn[i0]; + alp1 = L_mult (*p0, _1_4); + + /* i1 loop: 8 positions in track 0 */ + + p0 = ptr_rri0i3_i4 + j; + p1 = rri0i0; + + for (i1 = 0; i1 < L_SUBFR; i1 += STEP) { + ps2 = add (ps1, dn[i1]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */ + alp2 = L_mac (alp1, *p0, _1_2); + p0 += NB_POS; + alp2 = L_mac (alp2, *p1++, _1_4); + + sq2 = mult (ps2, ps2); + alp_16 = wround (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + if (s > 0) { + sq = sq2; + ps = ps2; + alp = alp_16; + ix = i0; + iy = i1; + } + } + } + + i0 = ix; + i1 = iy; + i1_offset = shl (mult (i1, 6554), 3); /* j = 8*(i1/5) */ + + /*------------------------------------------------------------------* + * depth first search 4, phase B: track 1 and 2. * + *------------------------------------------------------------------*/ + + ps0 = ps; + alp0 = L_mult (alp, _1_4); + + sq = -1; + alp = 1; + + /* build vector for next loop to decrease complexity */ + + p0 = ptr_rri2i3_i4 + mult (i0, 6554); + p1 = rri0i2 + i1_offset; + p2 = rri2i2; + p3 = tmp_vect; + + for (i3 = 2; i3 < L_SUBFR; i3 += STEP) { + /* rrv[i3] = rr[i3][i3] + rr[i0][i3] + rr[i1][i3]; */ + s = L_mult (*p0, _1_4); + p0 += NB_POS; + s = L_mac (s, *p1++, _1_4); + s = L_mac (s, *p2++, _1_8); + *p3++ = wround (s); + } + + /* i2 loop: 8 positions in track 1 */ + + p0 = ptr_rri1i3_i4 + mult (i0, 6554); + p1 = rri0i1 + i1_offset; + p2 = rri1i1; + p3 = rri1i2; + + for (i2 = 1; i2 < L_SUBFR; i2 += STEP) { + ps1 = add (ps0, dn[i2]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */ + alp1 = L_mac (alp0, *p0, _1_8); + p0 += NB_POS; + alp1 = L_mac (alp1, *p1++, _1_8); + alp1 = L_mac (alp1, *p2++, _1_16); + + /* i3 loop: 8 positions in track 2 */ + + p4 = tmp_vect; + + for (i3 = 2; i3 < L_SUBFR; i3 += STEP) { + ps2 = add (ps1, dn[i3]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */ + alp2 = L_mac (alp1, *p3++, _1_8); + alp2 = L_mac (alp2, *p4++, _1_2); + + sq2 = mult (ps2, ps2); + alp_16 = wround (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + if (s > 0) { + sq = sq2; + alp = alp_16; + ix = i2; + iy = i3; + } + } + } + + /*----------------------------------------------------------------* + * depth first search 1: compare codevector with the best case. * + *----------------------------------------------------------------*/ + + s = L_msu (L_mult (alpk, sq), psk, alp); + if (s > 0) { + psk = sq; + alpk = alp; + ip3 = i0; + ip0 = i1; + ip1 = ix; + ip2 = iy; + } + + ptr_rri0i3_i4 = rri0i4; + ptr_rri1i3_i4 = rri1i4; + ptr_rri2i3_i4 = rri2i4; + ptr_rri3i3_i4 = rri4i4; + + } + + + /* Set the sign of impulses */ + + i0 = sign_dn[ip0]; + i1 = sign_dn[ip1]; + i2 = sign_dn[ip2]; + i3 = sign_dn[ip3]; + + /* Find the codeword corresponding to the selected positions */ + + + for (i = 0; i < L_SUBFR; i++) { + cod[i] = 0; + } + + cod[ip0] = shr (i0, 2); /* From Q15 to Q13 */ + cod[ip1] = shr (i1, 2); + cod[ip2] = shr (i2, 2); + cod[ip3] = shr (i3, 2); + + /* find the filtered codeword */ + + for (i = 0; i < ip0; i++) + y[i] = 0; + + if (i0 > 0) + for (i = ip0, j = 0; i < L_SUBFR; i++, j++) + y[i] = h[j]; + else + for (i = ip0, j = 0; i < L_SUBFR; i++, j++) + y[i] = negate (h[j]); + + if (i1 > 0) + for (i = ip1, j = 0; i < L_SUBFR; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip1, j = 0; i < L_SUBFR; i++, j++) + y[i] = sub (y[i], h[j]); + + if (i2 > 0) + for (i = ip2, j = 0; i < L_SUBFR; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip2, j = 0; i < L_SUBFR; i++, j++) + y[i] = sub (y[i], h[j]); + + if (i3 > 0) + for (i = ip3, j = 0; i < L_SUBFR; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip3, j = 0; i < L_SUBFR; i++, j++) + y[i] = sub (y[i], h[j]); + + /* find codebook index; 17-bit address */ + + i = 0; + if (i0 > 0) + i = add (i, 1); + if (i1 > 0) + i = add (i, 2); + if (i2 > 0) + i = add (i, 4); + if (i3 > 0) + i = add (i, 8); + *sign = i; + + ip0 = mult (ip0, 6554); /* ip0/5 */ + ip1 = mult (ip1, 6554); /* ip1/5 */ + ip2 = mult (ip2, 6554); /* ip2/5 */ + i = mult (ip3, 6554); /* ip3/5 */ + j = add (i, shl (i, 2)); /* j = i*5 */ + j = sub (ip3, add (j, 3)); /* j= ip3%5 -3 */ + ip3 = add (shl (i, 1), j); + + i = add (ip0, shl (ip1, 3)); + i = add (i, shl (ip2, 6)); + i = add (i, shl (ip3, 9)); + + return i; +} diff --git a/src/libs/libg729/g729_basic_op.cpp b/src/libs/libg729/g729_basic_op.cpp new file mode 100644 index 00000000..d15b1aa8 --- /dev/null +++ b/src/libs/libg729/g729_basic_op.cpp @@ -0,0 +1,2013 @@ + +/* + * + * Basics operators. + * +*/ + +/* + * + * Include-Files + * +*/ + +#include +#include +#include "g729_typedef.h" +#include "g729_basic_op.h" + + +/* + * + * Function Name : sature + * + * Purpose : + * + * Limit the 32 bit input to the range of a 16 bit word. + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +sature (Word32 L_var1) +{ + Word16 var_out; + + if (L_var1 > 0X00007fffL) { + var_out = MAX_16; + } + else if (L_var1 < (Word32) 0xffff8000L) { + var_out = MIN_16; + } + else { + var_out = extract_l (L_var1); + } + + return (var_out); +} + + +/* + * + * Function Name : sature + * + * Purpose : + * + * Limit the 32 bit input to the range of a 16 bit word. + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +sature_o (Word32 L_var1, Flag *Overflow) +{ + Word16 var_out; + + if (L_var1 > 0X00007fffL) { + *Overflow = 1; + var_out = MAX_16; + } + else if (L_var1 < (Word32) 0xffff8000L) { + *Overflow = 1; + var_out = MIN_16; + } + else { + *Overflow = 0; + var_out = extract_l (L_var1); + } + + return (var_out); +} + +/* + * + * Function Name : add + * + * Purpose : + * + * Performs the addition (var1+var2) with overflow control and saturation; + * the 16 bit result is set at +32767 when overflow occurs or at -32768 + * when underflow occurs. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +add (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_somme; + + L_somme = (Word32) var1 + var2; + var_out = sature (L_somme); + return (var_out); +} + +/* + * + * Function Name : sub + * + * Purpose : + * + * Performs the subtraction (var1+var2) with overflow control and satu- + * ration; the 16 bit result is set at +32767 when overflow occurs or at + * -32768 when underflow occurs. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +sub (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_diff; + + L_diff = (Word32) var1 - var2; + var_out = sature (L_diff); + return (var_out); +} + +/* + * + * Function Name : add_o + * + * Purpose : + * + * Performs the addition (var1+var2) with overflow control and saturation; + * the 16 bit result is set at +32767 when overflow occurs or at -32768 + * when underflow occurs. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +add_o (Word16 var1, Word16 var2, Flag *Overflow) +{ + Word16 var_out; + Word32 L_somme; + + L_somme = (Word32) var1 + var2; + var_out = sature_o (L_somme, Overflow); + return (var_out); +} + +/* + * + * Function Name : sub_o + * + * Purpose : + * + * Performs the subtraction (var1+var2) with overflow control and satu- + * ration; the 16 bit result is set at +32767 when overflow occurs or at + * -32768 when underflow occurs. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +sub_o (Word16 var1, Word16 var2, Flag *Overflow) +{ + Word16 var_out; + Word32 L_diff; + + L_diff = (Word32) var1 - var2; + var_out = sature_o (L_diff, Overflow); + return (var_out); +} + +/* + * + * Function Name : abs_s + * + * Purpose : + * + * Absolute value of var1; abs_s(-32768) = 32767. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +abs_s (Word16 var1) +{ + Word16 var_out; + + if (var1 == (Word16) 0X8000) { + var_out = MAX_16; + } + else { + if (var1 < 0) { + var_out = -var1; + } + else { + var_out = var1; + } + } + return (var_out); +} + +/* + * + * Function Name : shl + * + * Purpose : + * + * Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill + * the var2 LSB of the result. If var2 is negative, arithmetically shift + * var1 right by -var2 with sign extension. Saturate the result in case of + * underflows or overflows. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +shl (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 resultat; + + if (var2 < 0) { + var_out = shr (var1, -var2); + } + else { + resultat = (Word32) var1 *((Word32) 1 << var2); + if ((var2 > 15 && var1 != 0) + || (resultat != (Word32) ((Word16) resultat))) { + var_out = (var1 > 0) ? MAX_16 : MIN_16; + } + else { + var_out = extract_l (resultat); + } + } + return (var_out); +} + +/* + * + * Function Name : shr + * + * Purpose : + * + * Arithmetically shift the 16 bit input var1 right var2 positions with + * sign extension. If var2 is negative, arithmetically shift var1 left by + * -var2 with sign extension. Saturate the result in case of underflows or + * overflows. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +shr (Word16 var1, Word16 var2) +{ + Word16 var_out; + + if (var2 < 0) { + var_out = shl (var1, -var2); + } + else { + if (var2 >= 15) { + var_out = (var1 < 0) ? (Word16) (-1) : (Word16) 0; + } + else { + if (var1 < 0) { + var_out = ~((~var1) >> var2); + } + else { + var_out = var1 >> var2; + } + } + } + + return (var_out); +} + +/* + * + * Function Name : mult + * + * Purpose : + * + * Performs the multiplication of var1 by var2 and gives a 16 bit result + * which is scaled i.e.: + * mult(var1,var2) = shr((var1 times var2),15) and + * mult(-32768,-32768) = 32767. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +mult (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_produit; + + L_produit = (Word32) var1 *(Word32) var2; + + L_produit = (L_produit & (Word32) 0xffff8000L) >> 15; + + if (L_produit & (Word32) 0x00010000L) + L_produit = L_produit | (Word32) 0xffff0000L; + + var_out = sature (L_produit); + return (var_out); +} + + +/* + * + * Function Name : L_mult + * + * Purpose : + * + * L_mult is the 32 bit result of the multiplication of var1 times var2 + * with one shift left i.e.: + * L_mult(var1,var2) = shl((var1 times var2),1) and + * L_mult(-32768,-32768) = 2147483647. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_mult (Word16 var1, Word16 var2) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 *(Word32) var2; + if (L_var_out != (Word32) 0x40000000L) { + L_var_out *= 2; + } + else { + L_var_out = MAX_32; + } + + return (L_var_out); +} + +/* + * + * Function Name : L_mult_o + * + * Purpose : + * + * L_mult is the 32 bit result of the multiplication of var1 times var2 + * with one shift left i.e.: + * L_mult(var1,var2) = shl((var1 times var2),1) and + * L_mult(-32768,-32768) = 2147483647. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_mult_o (Word16 var1, Word16 var2, Flag *Overflow) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 *(Word32) var2; + if (L_var_out != (Word32) 0x40000000L) { + L_var_out *= 2; + } + else { + *Overflow = 1; + L_var_out = MAX_32; + } + + return (L_var_out); +} + +/* + * + * Function Name : negate + * + * Purpose : + * + * Negate var1 with saturation, saturate in the case where input is -32768: + * negate(var1) = sub(0,var1). + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +negate (Word16 var1) +{ + Word16 var_out; + + var_out = (var1 == MIN_16) ? MAX_16 : -var1; + return (var_out); +} + + +/* + * + * Function Name : extract_h + * + * Purpose : + * + * Return the 16 MSB of L_var1. + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32 ) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +extract_h (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) (L_var1 >> 16); + return (var_out); +} + +/* + * + * Function Name : extract_l + * + * Purpose : + * + * Return the 16 LSB of L_var1. + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32 ) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +extract_l (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) L_var1; + return (var_out); +} + + +/* + * + * Function Name : wround + * + * Purpose : + * + * Round the lower 16 bits of the 32 bit input number into its MS 16 bits + * with saturation. Shift the resulting bits right by 16 and return the 16 + * bit number: + * wround(L_var1) = extract_h(L_add(L_var1,32768)) + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32 ) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +wround (Word32 L_var1) +{ + Word16 var_out; + Word32 L_arrondi; + + L_arrondi = L_add (L_var1, (Word32) 0x00008000); + var_out = extract_h (L_arrondi); + return (var_out); +} + +/* + * + * Function Name : wround_o + * + * Purpose : + * + * Round the lower 16 bits of the 32 bit input number into its MS 16 bits + * with saturation. Shift the resulting bits right by 16 and return the 16 + * bit number: + * wround(L_var1) = extract_h(L_add(L_var1,32768)) + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32 ) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +wround_o (Word32 L_var1, Flag *Overflow) +{ + Word16 var_out; + Word32 L_arrondi; + + L_arrondi = L_add_o (L_var1, (Word32) 0x00008000, Overflow); + var_out = extract_h (L_arrondi); + return (var_out); +} + + +/* + * + * Function Name : L_mac + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Add the 32 bit + * result to L_var3 with saturation, return a 32 bit result: + * L_mac(L_var3,var1,var2) = L_add(L_var3,(L_mult(var1,var2)). + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_mac (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult (var1, var2); + L_var_out = L_add (L_var3, L_produit); + return (L_var_out); +} + + +/* + * + * Function Name : L_mac_o + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Add the 32 bit + * result to L_var3 with saturation, return a 32 bit result: + * L_mac(L_var3,var1,var2) = L_add(L_var3,(L_mult(var1,var2)). + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_mac_o (Word32 L_var3, Word16 var1, Word16 var2, Flag* Overflow) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult_o (var1, var2, Overflow); + L_var_out = L_add_o (L_var3, L_produit, Overflow); + return (L_var_out); +} + +/* + * + * Function Name : L_msu + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Subtract the 32 + * bit result to L_var3 with saturation, return a 32 bit result: + * L_msu(L_var3,var1,var2) = L_sub(L_var3,(L_mult(var1,var2)). + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_msu (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult (var1, var2); + L_var_out = L_sub (L_var3, L_produit); + return (L_var_out); +} + +/* + * + * Function Name : L_msu_o + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Subtract the 32 + * bit result to L_var3 with saturation, return a 32 bit result: + * L_msu(L_var3,var1,var2) = L_sub(L_var3,(L_mult(var1,var2)). + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_msu_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult_o (var1, var2, Overflow); + L_var_out = L_sub_o (L_var3, L_produit, Overflow); + return (L_var_out); +} + +/* + * + * Function Name : L_add + * + * Purpose : + * + * 32 bits addition of the two 32 bits variables (L_var1+L_var2) with + * overflow control and saturation; the result is set at +214783647 when + * overflow occurs or at -214783648 when underflow occurs. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * L_var2 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_add (Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + + L_var_out = L_var1 + L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) == 0) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_sub + * + * Purpose : + * + * 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with + * overflow control and saturation; the result is set at +214783647 when + * overflow occurs or at -214783648 when underflow occurs. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * L_var2 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_sub (Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + + L_var_out = L_var1 - L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) != 0) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_add_o + * + * Purpose : + * + * 32 bits addition of the two 32 bits variables (L_var1+L_var2) with + * overflow control and saturation; the result is set at +214783647 when + * overflow occurs or at -214783648 when underflow occurs. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * L_var2 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_add_o (Word32 L_var1, Word32 L_var2, Flag *Overflow) +{ + Word32 L_var_out; + + L_var_out = L_var1 + L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) == 0) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32; + *Overflow = 1; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_sub_o + * + * Purpose : + * + * 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with + * overflow control and saturation; the result is set at +214783647 when + * overflow occurs or at -214783648 when underflow occurs. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * L_var2 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_sub_o (Word32 L_var1, Word32 L_var2, Flag *Overflow) +{ + Word32 L_var_out; + + L_var_out = L_var1 - L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) != 0) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; + *Overflow = 1; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_negate + * + * Purpose : + * + * Negate the 32 bit variable L_var1 with saturation; saturate in the case + * where input is -2147483648 (0x8000 0000). + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_negate (Word32 L_var1) +{ + Word32 L_var_out; + + L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1; + return (L_var_out); +} + +/* + * + * Function Name : mult_r + * + * Purpose : + * + * Same as mult with rounding, i.e.: + * mult_r(var1,var2) = shr(((var1*var2) + 16384),15) and + * mult_r(-32768,-32768) = 32767. + * + * Complexity weight : 2 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +mult_r (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_produit_arr; + + L_produit_arr = (Word32) var1 *(Word32) var2; /* product */ + L_produit_arr += (Word32) 0x00004000; /* round */ + L_produit_arr &= (Word32) 0xffff8000L; + L_produit_arr >>= 15; /* shift */ + + if (L_produit_arr & (Word32) 0x00010000L) { /* sign extend when necessary */ + L_produit_arr |= (Word32) 0xffff0000L; + } + + var_out = sature (L_produit_arr); + return (var_out); +} + +/* + * + * Function Name : L_shl + * + * Purpose : + * + * Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero + * fill the var2 LSB of the result. If var2 is negative, L_var1 right by + * -var2 arithmetically shift with sign extension. Saturate the result in + * case of underflows or overflows. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_shl (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + /* initialization used only to suppress Microsoft Visual C++ warnings */ + L_var_out = 0L; + + if (var2 <= 0) { + L_var_out = L_shr (L_var1, -var2); + } + else { + for (; var2 > 0; var2--) { + if (L_var1 > (Word32) 0X3fffffffL) { + L_var_out = MAX_32; + break; + } + else { + if (L_var1 < (Word32) 0xc0000000L) { + L_var_out = MIN_32; + break; + } + } + L_var1 *= 2; + L_var_out = L_var1; + } + } + return (L_var_out); +} + + +/* + * + * Function Name : L_shl_o + * + * Purpose : + * + * Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero + * fill the var2 LSB of the result. If var2 is negative, L_var1 right by + * -var2 arithmetically shift with sign extension. Saturate the result in + * case of underflows or overflows. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_shl_o (Word32 L_var1, Word16 var2, Flag *Overflow) +{ + Word32 L_var_out; + + /* initialization used only to suppress Microsoft Visual C++ warnings */ + L_var_out = 0L; + + if (var2 <= 0) { + L_var_out = L_shr (L_var1, -var2); + } + else { + for (; var2 > 0; var2--) { + if (L_var1 > (Word32) 0X3fffffffL) { + *Overflow = 1; + L_var_out = MAX_32; + break; + } + else { + if (L_var1 < (Word32) 0xc0000000L) { + *Overflow = 1; + L_var_out = MIN_32; + break; + } + } + L_var1 *= 2; + L_var_out = L_var1; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_shr + * + * Purpose : + * + * Arithmetically shift the 32 bit input L_var1 right var2 positions with + * sign extension. If var2 is negative, arithmetically shift L_var1 left + * by -var2 and zero fill the var2 LSB of the result. Saturate the result + * in case of underflows or overflows. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_shr (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + if (var2 < 0) { + L_var_out = L_shl (L_var1, -var2); + } + else { + if (var2 >= 31) { + L_var_out = (L_var1 < 0L) ? -1 : 0; + } + else { + if (L_var1 < 0) { + L_var_out = ~((~L_var1) >> var2); + } + else { + L_var_out = L_var1 >> var2; + } + } + } + return (L_var_out); +} + +/* + * + * Function Name : shr_r + * + * Purpose : + * + * Same as shr(var1,var2) but with rounding. Saturate the result in case of + * underflows or overflows : + * If var2 is greater than zero : + * shr_r(var1,var2) = shr(add(var1,2**(var2-1)),var2) + * If var2 is less than zero : + * shr_r(var1,var2) = shr(var1,var2). + * + * Complexity weight : 2 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +shr_r (Word16 var1, Word16 var2) +{ + Word16 var_out; + + if (var2 > 15) { + var_out = 0; + } + else { + var_out = shr (var1, var2); + + if (var2 > 0) { + if ((var1 & ((Word16) 1 << (var2 - 1))) != 0) { + var_out++; + } + } + } + return (var_out); +} + +/* + * + * Function Name : mac_r + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Add the 32 bit + * result to L_var3 with saturation. Round the LS 16 bits of the result + * into the MS 16 bits with saturation and shift the result right by 16. + * Return a 16 bit result. + * mac_r(L_var3,var1,var2) = wround(L_mac(Lvar3,var1,var2)) + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. + * +*/ + +Word16 +mac_r (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word16 var_out; + + L_var3 = L_mac (L_var3, var1, var2); + L_var3 = L_add (L_var3, (Word32) 0x00008000); + var_out = extract_h (L_var3); + return (var_out); +} + + +/* + * + * Function Name : msu_r + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Subtract the 32 + * bit result to L_var3 with saturation. Round the LS 16 bits of the res- + * ult into the MS 16 bits with saturation and shift the result right by + * 16. Return a 16 bit result. + * msu_r(L_var3,var1,var2) = wround(L_msu(Lvar3,var1,var2)) + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. + * +*/ + +Word16 +msu_r (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word16 var_out; + + L_var3 = L_msu (L_var3, var1, var2); + L_var3 = L_add (L_var3, (Word32) 0x00008000); + var_out = extract_h (L_var3); + return (var_out); +} + + + +/* + * + * Function Name : L_deposit_h + * + * Purpose : + * + * Deposit the 16 bit var1 into the 16 MS bits of the 32 bit output. The + * 16 LS bits of the output are zeroed. + * + * Complexity weight : 2 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var_out <= 0x7fff 0000. + * +*/ + +Word32 +L_deposit_h (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 << 16; + return (L_var_out); +} + +/* + * + * Function Name : L_deposit_l + * + * Purpose : + * + * Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The + * 16 MS bits of the output are sign extended. + * + * Complexity weight : 2 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0xFFFF 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word32 +L_deposit_l (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1; + return (L_var_out); +} + +/* + * + * Function Name : L_shr_r + * + * Purpose : + * + * Same as L_shr(L_var1,var2)but with rounding. Saturate the result in case + * of underflows or overflows : + * If var2 is greater than zero : + * L_shr_r(var1,var2) = L_shr(L_add(L_var1,2**(var2-1)),var2) + * If var2 is less than zero : + * L_shr_r(var1,var2) = L_shr(L_var1,var2). + * + * Complexity weight : 3 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var1 <= 0x7fff ffff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_shr_r (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + if (var2 > 31) { + L_var_out = 0; + } + else { + L_var_out = L_shr (L_var1, var2); + if (var2 > 0) { + if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0) { + L_var_out++; + } + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_abs + * + * Purpose : + * + * Absolute value of L_var1; Saturate in case where the input is + * -214783648 + * + * Complexity weight : 3 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_abs (Word32 L_var1) +{ + Word32 L_var_out; + + if (L_var1 == MIN_32) { + L_var_out = MAX_32; + } + else { + if (L_var1 < 0) { + L_var_out = -L_var1; + } + else { + L_var_out = L_var1; + } + } + + return (L_var_out); +} + +/* + * + * Function Name : norm_s + * + * Purpose : + * + * Produces the number of left shift needed to normalize the 16 bit varia- + * ble var1 for positive values on the interval with minimum of 16384 and + * maximum of 32767, and for negative values on the interval with minimum + * of -32768 and maximum of -16384; in order to normalize the result, the + * following operation must be done : + * norm_var1 = shl(var1,norm_s(var1)). + * + * Complexity weight : 15 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x0000 000f. + * +*/ + +Word16 +norm_s (Word16 var1) +{ + Word16 var_out; + + if (var1 == 0) { + var_out = 0; + } + else { + if (var1 == (Word16) 0xffff) { + var_out = 15; + } + else { + if (var1 < 0) { + var1 = ~var1; + } + + for (var_out = 0; var1 < 0x4000; var_out++) { + var1 <<= 1; + } + } + } + + return (var_out); +} + + +/* + * + * Function Name : div_s + * + * Purpose : + * + * Produces a result which is the fractional integer division of var1 by + * var2; var1 and var2 must be positive and var2 must be greater or equal + * to var1; the result is positive (leading bit equal to 0) and truncated + * to 16 bits. + * If var1 = var2 then div(var1,var2) = 32767. + * + * Complexity weight : 18 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var1 <= var2 and var2 != 0. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : var1 <= var2 <= 0x0000 7fff and var2 != 0. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x0000 7fff. + * It's a Q15 value (point between b15 and b14). + * +*/ + +Word16 +div_s (Word16 var1, Word16 var2) +{ + Word16 var_out = 0; + Word16 iteration; + Word32 L_num; + Word32 L_denom; + + if ((var1 > var2) || (var1 < 0) || (var2 < 0)) { + printf ("Division Error var1=%d var2=%d\n", var1, var2); + exit (0); + } + + if (var2 == 0) { + printf ("Division by 0, Fatal error \n"); + exit (0); + } + + if (var1 == 0) { + var_out = 0; + } + else { + if (var1 == var2) { + var_out = MAX_16; + } + else { + L_num = L_deposit_l (var1); + L_denom = L_deposit_l (var2); + + for (iteration = 0; iteration < 15; iteration++) { + var_out <<= 1; + L_num <<= 1; + + if (L_num >= L_denom) { + L_num = L_sub (L_num, L_denom); + var_out = add (var_out, 1); + } + } + } + } + + return (var_out); +} + + +/* + * + * Function Name : norm_l + * + * Purpose : + * + * Produces the number of left shift needed to normalize the 32 bit varia- + * ble l_var1 for positive values on the interval with minimum of + * 1073741824 and maximum of 2147483647, and for negative values on the in- + * terval with minimum of -2147483648 and maximum of -1073741824; in order + * to normalize the result, the following operation must be done : + * norm_L_var1 = L_shl(L_var1,norm_l(L_var1)). + * + * Complexity weight : 30 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x0000 001f. + * +*/ + +Word16 +norm_l (Word32 L_var1) +{ + Word16 var_out; + + if (L_var1 == 0) { + var_out = 0; + } + else { + if (L_var1 == (Word32) 0xffffffffL) { + var_out = 31; + } + else { + if (L_var1 < 0) { + L_var1 = ~L_var1; + } + + for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++) { + L_var1 <<= 1; + } + } + } + + return (var_out); +} diff --git a/src/libs/libg729/g729_basic_op.h b/src/libs/libg729/g729_basic_op.h new file mode 100644 index 00000000..47238113 --- /dev/null +++ b/src/libs/libg729/g729_basic_op.h @@ -0,0 +1,46 @@ +#define MAX_32 (Word32)0x7fffffffL +#define MIN_32 (Word32)0x80000000L + +#define MAX_16 (Word16)0x7fff +#define MIN_16 (Word16)0x8000 + +Word16 sature (Word32 L_var1); /* Limit to 16 bits, 1 */ +Word16 sature_o (Word32 L_var1, Flag *Overflow); /* Limit to 16 bits, 1 */ +Word16 add (Word16 var1, Word16 var2); /* Short add, 1 */ +Word16 sub (Word16 var1, Word16 var2); /* Short sub, 1 */ +Word16 add_o (Word16 var1, Word16 var2, Flag *Overflow); /* Short add, 1 */ +Word16 sub_o (Word16 var1, Word16 var2, Flag *Overflow); /* Short sub, 1 */ +Word16 abs_s (Word16 var1); /* Short abs, 1 */ +Word16 shl (Word16 var1, Word16 var2); /* Short shift left, 1 */ +Word16 shr (Word16 var1, Word16 var2); /* Short shift right, 1 */ +Word16 mult (Word16 var1, Word16 var2); /* Short mult, 1 */ +Word32 L_mult (Word16 var1, Word16 var2); /* Long mult, 1 */ +Word32 L_mult_o (Word16 var1, Word16 var2, Flag *Overflow); /* Long mult, 1 */ +Word16 negate (Word16 var1); /* Short negate, 1 */ +Word16 extract_h (Word32 L_var1); /* Extract high, 1 */ +Word16 extract_l (Word32 L_var1); /* Extract low, 1 */ +Word16 wround (Word32 L_var1); /* Round, 1 */ +Word16 wround_o (Word32 L_var1, Flag *Overflow); /* Round, 1 */ +Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2); /* Mac, 1 */ +Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2); /* Msu, 1 */ +Word32 L_mac_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow); /* Mac, 1 */ +Word32 L_msu_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow); /* Msu, 1 */ +Word32 L_add (Word32 L_var1, Word32 L_var2); /* Long add, 2 */ +Word32 L_sub (Word32 L_var1, Word32 L_var2); /* Long sub, 2 */ +Word32 L_add_o (Word32 L_var1, Word32 L_var2, Flag *Overflow); /* Long add, 2 */ +Word32 L_sub_o (Word32 L_var1, Word32 L_var2, Flag *Overflow); /* Long sub, 2 */ +Word32 L_negate (Word32 L_var1); /* Long negate, 2 */ +Word16 mult_r (Word16 var1, Word16 var2); /* Mult with round, 2 */ +Word32 L_shl (Word32 L_var1, Word16 var2); /* Long shift left, 2 */ +Word32 L_shl_o (Word32 L_var1, Word16 var2, Flag *Overflow); /* Long shift left, 2 */ +Word32 L_shr (Word32 L_var1, Word16 var2); /* Long shift right, 2 */ +Word16 shr_r (Word16 var1, Word16 var2); /* Shift right with round, 2 */ +Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2); /* Mac with rounding, 2 */ +Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2); /* Msu with rounding, 2 */ +Word32 L_deposit_h (Word16 var1); /* 16 bit var1 -> MSB, 2 */ +Word32 L_deposit_l (Word16 var1); /* 16 bit var1 -> LSB, 2 */ +Word32 L_shr_r (Word32 L_var1, Word16 var2); /* Long shift right with round, 3 */ +Word32 L_abs (Word32 L_var1); /* Long abs, 3 */ +Word16 norm_s (Word16 var1); /* Short norm, 15 */ +Word16 div_s (Word16 var1, Word16 var2); /* Short division, 18 */ +Word16 norm_l (Word32 L_var1); /* Long norm, 30 */ diff --git a/src/libs/libg729/g729_cod_ld8a.cpp b/src/libs/libg729/g729_cod_ld8a.cpp new file mode 100644 index 00000000..eeb98332 --- /dev/null +++ b/src/libs/libg729/g729_cod_ld8a.cpp @@ -0,0 +1,430 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-----------------------------------------------------------------* + * Functions Coder_ld8a and Init_Coder_ld8a * + * ~~~~~~~~~~ ~~~~~~~~~~~~~~~ * + * * + * Init_Coder_ld8a(void); * + * * + * ->Initialization of variables for the coder section. * + * * + * * + * Coder_ld8a(Word16 ana[]); * + * * + * ->Main coder function. * + * * + * * + * Input: * + * * + * 80 speech data should have beee copy to vector new_speech[]. * + * This vector is global and is declared in this function. * + * * + * Ouputs: * + * * + * ana[] ->analysis parameters. * + * * + *-----------------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" +#include "g729_util.h" +#include "g729_lsp.h" +#include "g729_taming.h" +#include "g729_gain.h" + +/*-----------------------------------------------------------* + * Coder constant parameters (defined in "ld8a.h") * + *-----------------------------------------------------------* + * L_WINDOW : LPC analysis window size. * + * L_NEXT : Samples of next frame needed for autocor. * + * L_FRAME : Frame size. * + * L_SUBFR : Sub-frame size. * + * M : LPC order. * + * MP1 : LPC order+1 * + * L_TOTAL : Total size of speech buffer. * + * PIT_MIN : Minimum pitch lag. * + * PIT_MAX : Maximum pitch lag. * + * L_INTERPOL : Length of filter for interpolation * + *-----------------------------------------------------------*/ + +/*-----------------------------------------------------------------* + * Function Init_Coder_ld8a * + * ~~~~~~~~~~~~~~~ * + * * + * Init_Coder_ld8a(void); * + * * + * ->Initialization of variables for the coder section. * + * - initialize pointers to speech buffer * + * - initialize pointers * + * - set vectors to zero * + * * + *-----------------------------------------------------------------*/ + +CodState* +Init_Coder_ld8a (void) +{ + CodState *coder; + + coder = (CodState *) malloc (sizeof (CodState)); + + /*----------------------------------------------------------------------* + * Initialize pointers to speech vector. * + * * + * * + * |--------------------|-------------|-------------|------------| * + * previous speech sf1 sf2 L_NEXT * + * * + * <---------------- Total speech vector (L_TOTAL) -----------> * + * <---------------- LPC analysis window (L_WINDOW) -----------> * + * | <-- present frame (L_FRAME) --> * + * old_speech | <-- new speech (L_FRAME) --> * + * p_window | | * + * speech | * + * new_speech * + *-----------------------------------------------------------------------*/ + + coder->new_speech = coder->old_speech + L_TOTAL - L_FRAME; /* New speech */ + coder->speech = coder->new_speech - L_NEXT; /* Present frame */ + coder->p_window = coder->old_speech + L_TOTAL - L_WINDOW; /* For LPC window */ + + /* Initialize pointers */ + + coder->wsp = coder->old_wsp + PIT_MAX; + coder->exc = coder->old_exc + PIT_MAX + L_INTERPOL; + + /* Static vectors to zero */ + + Set_zero (coder->old_speech, L_TOTAL); + Set_zero (coder->old_exc, PIT_MAX + L_INTERPOL); + Set_zero (coder->old_wsp, PIT_MAX); + Set_zero (coder->mem_w, M10); + Set_zero (coder->mem_w0, M10); + Set_zero (coder->mem_zero, M10); + coder->sharp = SHARPMIN; + + /* Initialize lsp_old_q[] */ + Copy (lsp_old_init, coder->lsp_old, M10); + Copy (lsp_old_init, coder->lsp_old_q, M10); + + Lsp_encw_reset (coder); + Init_exc_err (coder); + + Copy (past_qua_en_init, coder->past_qua_en, 4); + + Set_zero (coder->old_A, M10 + 1); + coder->old_A [0] = 4096; + Set_zero (coder->old_rc, 2); + + return coder; +} + +/*-----------------------------------------------------------------* + * Functions Coder_ld8a * + * ~~~~~~~~~~ * + * Coder_ld8a(Word16 ana[]); * + * * + * ->Main coder function. * + * * + * * + * Input: * + * * + * 80 speech data should have beee copy to vector new_speech[]. * + * This vector is global and is declared in this function. * + * * + * Ouputs: * + * * + * ana[] ->analysis parameters. * + * * + *-----------------------------------------------------------------*/ + +void +Coder_ld8a (CodState *coder, Word16 ana[]) +{ + + /* LPC analysis */ + + Word16 Aq_t[(MP1) * 2]; /* A(z) quantized for the 2 subframes */ + Word16 Ap_t[(MP1) * 2]; /* A(z/gamma) for the 2 subframes */ + Word16 *Aq, *Ap; /* Pointer on Aq_t and Ap_t */ + + /* Other vectors */ + + Word16 h1[L_SUBFR]; /* Impulse response h1[] */ + Word16 xn[L_SUBFR]; /* Target vector for pitch search */ + Word16 xn2[L_SUBFR]; /* Target vector for codebook search */ + Word16 code[L_SUBFR]; /* Fixed codebook excitation */ + Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */ + Word16 y2[L_SUBFR]; /* Filtered fixed codebook excitation */ + Word16 g_coeff[4]; /* Correlations between xn & y1 */ + + Word16 g_coeff_cs[5]; + Word16 exp_g_coeff_cs[5]; /* Correlations between xn, y1, & y2 + , -2, + , -2, 2 */ + + /* Scalars */ + + Word16 i, j, k, i_subfr; + Word16 T_op, T0, T0_min, T0_max, T0_frac; + Word16 gain_pit, gain_code, index; + Word16 temp, taming; + Word32 L_temp; + +/*------------------------------------------------------------------------* + * - Perform LPC analysis: * + * * autocorrelation + lag windowing * + * * Levinson-durbin algorithm to find a[] * + * * convert a[] to lsp[] * + * * quantize and code the LSPs * + * * find the interpolated LSPs and convert to a[] for the 2 * + * subframes (both quantized and unquantized) * + *------------------------------------------------------------------------*/ + { + /* Temporary vectors */ + Word16 r_l[MP1], r_h[MP1]; /* Autocorrelations low and hi */ + Word16 rc[M10]; /* Reflection coefficients. */ + Word16 lsp_new[M10], lsp_new_q[M10]; /* LSPs at 2th subframe */ + + /* LP analysis */ + + Autocorr (coder->p_window, M10, r_h, r_l); /* Autocorrelations */ + Lag_window (M10, r_h, r_l); /* Lag windowing */ + Levinson (coder, r_h, r_l, Ap_t, rc); /* Levinson Durbin */ + Az_lsp (Ap_t, lsp_new, coder->lsp_old); /* From A(z) to lsp */ + + /* LSP quantization */ + + Qua_lsp (coder, lsp_new, lsp_new_q, ana); + ana += 2; /* Advance analysis parameters pointer */ + + /*--------------------------------------------------------------------* + * Find interpolated LPC parameters in all subframes * + * The interpolated parameters are in array Aq_t[]. * + *--------------------------------------------------------------------*/ + + Int_qlpc (coder->lsp_old_q, lsp_new_q, Aq_t); + + /* Compute A(z/gamma) */ + + Weight_Az (&Aq_t[0], GAMMA1, M10, &Ap_t[0]); + Weight_Az (&Aq_t[MP1], GAMMA1, M10, &Ap_t[MP1]); + + /* update the LSPs for the next frame */ + + Copy (lsp_new, coder->lsp_old, M10); + Copy (lsp_new_q, coder->lsp_old_q, M10); + } + + /*----------------------------------------------------------------------* + * - Find the weighted input speech w_sp[] for the whole speech frame * + * - Find the open-loop pitch delay * + *----------------------------------------------------------------------*/ + + Residu (&Aq_t[0], &coder->speech[0], &coder->exc[0], L_SUBFR); + Residu (&Aq_t[MP1], &coder->speech[L_SUBFR], &coder->exc[L_SUBFR], L_SUBFR); + + { + Word16 Ap1[MP1]; + + Ap = Ap_t; + Ap1[0] = 4096; + for (i = 1; i <= M10; i++) /* Ap1[i] = Ap[i] - 0.7 * Ap[i-1]; */ + Ap1[i] = sub (Ap[i], mult (Ap[i - 1], 22938)); + Syn_filt (Ap1, &coder->exc[0], &coder->wsp[0], L_SUBFR, coder->mem_w, 1, NULL); + + Ap += MP1; + for (i = 1; i <= M10; i++) /* Ap1[i] = Ap[i] - 0.7 * Ap[i-1]; */ + Ap1[i] = sub (Ap[i], mult (Ap[i - 1], 22938)); + Syn_filt (Ap1, &coder->exc[L_SUBFR], &coder->wsp[L_SUBFR], L_SUBFR, coder->mem_w, 1, NULL); + } + + /* Find open loop pitch lag */ + + T_op = Pitch_ol_fast (coder->wsp, PIT_MAX, L_FRAME); + + /* Range for closed loop pitch search in 1st subframe */ + + T0_min = sub (T_op, 3); + if (sub (T0_min, PIT_MIN) < 0) { + T0_min = PIT_MIN; + } + + T0_max = add (T0_min, 6); + if (sub (T0_max, PIT_MAX) > 0) { + T0_max = PIT_MAX; + T0_min = sub (T0_max, 6); + } + + + /*------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * To find the pitch and innovation parameters. The subframe size is * + * L_SUBFR and the loop is repeated 2 times. * + * - find the weighted LPC coefficients * + * - find the LPC residual signal res[] * + * - compute the target signal for pitch search * + * - compute impulse response of weighted synthesis filter (h1[]) * + * - find the closed-loop pitch parameters * + * - encode the pitch delay * + * - find target vector for codebook search * + * - codebook search * + * - VQ of pitch and codebook gains * + * - update states of weighting filter * + *------------------------------------------------------------------------*/ + + Aq = Aq_t; /* pointer to interpolated quantized LPC parameters */ + Ap = Ap_t; /* pointer to weighted LPC coefficients */ + + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { + + /*---------------------------------------------------------------* + * Compute impulse response, h1[], of weighted synthesis filter * + *---------------------------------------------------------------*/ + + h1[0] = 4096; + Set_zero (&h1[1], L_SUBFR - 1); + Syn_filt (Ap, h1, h1, L_SUBFR, &h1[1], 0, NULL); + + /*----------------------------------------------------------------------* + * Find the target vector for pitch search: * + *----------------------------------------------------------------------*/ + + Syn_filt (Ap, &coder->exc[i_subfr], xn, L_SUBFR, coder->mem_w0, 0, NULL); + + /*---------------------------------------------------------------------* + * Closed-loop fractional pitch search * + *---------------------------------------------------------------------*/ + + T0 = Pitch_fr3_fast (&coder->exc[i_subfr], xn, h1, L_SUBFR, T0_min, T0_max, + i_subfr, &T0_frac); + + index = + Enc_lag3 (T0, T0_frac, &T0_min, &T0_max, PIT_MIN, PIT_MAX, i_subfr); + + *ana++ = index; + + if (i_subfr == 0) { + *ana++ = Parity_Pitch (index); + } + + /*-----------------------------------------------------------------* + * - find filtered pitch exc * + * - compute pitch gain and limit between 0 and 1.2 * + * - update target vector for codebook search * + *-----------------------------------------------------------------*/ + + Syn_filt (Ap, &coder->exc[i_subfr], y1, L_SUBFR, coder->mem_zero, 0, NULL); + + gain_pit = G_pitch (xn, y1, g_coeff, L_SUBFR); + + /* clip pitch gain if taming is necessary */ + + taming = test_err (coder, T0, T0_frac); + + if (taming == 1) { + if (sub (gain_pit, GPCLIP) > 0) { + gain_pit = GPCLIP; + } + } + + /* xn2[i] = xn[i] - y1[i] * gain_pit */ + + for (i = 0; i < L_SUBFR; i++) { + L_temp = L_mult (y1[i], gain_pit); + L_temp = L_shl (L_temp, 1); /* gain_pit in Q14 */ + xn2[i] = sub (xn[i], extract_h (L_temp)); + } + + + /*-----------------------------------------------------* + * - Innovative codebook search. * + *-----------------------------------------------------*/ + + index = ACELP_Code_A (xn2, h1, T0, coder->sharp, code, y2, &i); + + *ana++ = index; /* Positions index */ + *ana++ = i; /* Signs index */ + + + /*-----------------------------------------------------* + * - Quantization of gains. * + *-----------------------------------------------------*/ + + g_coeff_cs[0] = g_coeff[0]; /* */ + exp_g_coeff_cs[0] = negate (g_coeff[1]); /* Q-Format:XXX -> JPN */ + g_coeff_cs[1] = negate (g_coeff[2]); /* (xn,y1) -> -2 */ + exp_g_coeff_cs[1] = negate (add (g_coeff[3], 1)); /* Q-Format:XXX -> JPN */ + + Corr_xy2 (xn, y1, y2, g_coeff_cs, exp_g_coeff_cs); /* Q0 Q0 Q12 ^Qx ^Q0 */ + /* g_coeff_cs[3]:exp_g_coeff_cs[3] = */ + /* g_coeff_cs[4]:exp_g_coeff_cs[4] = -2 */ + /* g_coeff_cs[5]:exp_g_coeff_cs[5] = 2 */ + + *ana++ = Qua_gain (coder, code, g_coeff_cs, exp_g_coeff_cs, + L_SUBFR, &gain_pit, &gain_code, taming); + + + /*------------------------------------------------------------* + * - Update pitch sharpening "sharp" with quantized gain_pit * + *------------------------------------------------------------*/ + + coder->sharp = gain_pit; + if (sub (coder->sharp, SHARPMAX) > 0) { + coder->sharp = SHARPMAX; + } + if (sub (coder->sharp, SHARPMIN) < 0) { + coder->sharp = SHARPMIN; + } + + /*------------------------------------------------------* + * - Find the total excitation * + * - update filters memories for finding the target * + * vector in the next subframe * + *------------------------------------------------------*/ + + for (i = 0; i < L_SUBFR; i++) { + /* exc[i] = gain_pit*exc[i] + gain_code*code[i]; */ + /* exc[i] in Q0 gain_pit in Q14 */ + /* code[i] in Q13 gain_cod in Q1 */ + + L_temp = L_mult (coder->exc[i + i_subfr], gain_pit); + L_temp = L_mac (L_temp, code[i], gain_code); + L_temp = L_shl (L_temp, 1); + coder->exc[i + i_subfr] = wround (L_temp); + } + + update_exc_err (coder, gain_pit, T0); + + for (i = L_SUBFR - M10, j = 0; i < L_SUBFR; i++, j++) { + temp = extract_h (L_shl (L_mult (y1[i], gain_pit), 1)); + k = extract_h (L_shl (L_mult (y2[i], gain_code), 2)); + coder->mem_w0[j] = sub (xn[i], add (temp, k)); + } + + Aq += MP1; /* interpolated LPC parameters for next subframe */ + Ap += MP1; + + } + + /*--------------------------------------------------* + * Update signal for next frame. * + * -> shift to the left by L_FRAME: * + * speech[], wsp[] and exc[] * + *--------------------------------------------------*/ + + Copy (&coder->old_speech[L_FRAME], &coder->old_speech[0], L_TOTAL - L_FRAME); + Copy (&coder->old_wsp[L_FRAME], &coder->old_wsp[0], PIT_MAX); + Copy (&coder->old_exc[L_FRAME], &coder->old_exc[0], PIT_MAX + L_INTERPOL); + + return; +} diff --git a/src/libs/libg729/g729_cor_func.cpp b/src/libs/libg729/g729_cor_func.cpp new file mode 100644 index 00000000..be2e78af --- /dev/null +++ b/src/libs/libg729/g729_cor_func.cpp @@ -0,0 +1,139 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/* Functions Corr_xy2() and Cor_h_x() */ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" + +/*---------------------------------------------------------------------------* + * Function corr_xy2() * + * ~~~~~~~~~~~~~~~~~~~ * + * Find the correlations between the target xn[], the filtered adaptive * + * codebook excitation y1[], and the filtered 1st codebook innovation y2[]. * + * g_coeff[2]:exp_g_coeff[2] = * + * g_coeff[3]:exp_g_coeff[3] = -2 * + * g_coeff[4]:exp_g_coeff[4] = 2 * + *---------------------------------------------------------------------------*/ + +void +Corr_xy2 (Word16 xn[], /* (i) Q0 :Target vector. */ + Word16 y1[], /* (i) Q0 :Adaptive codebook. */ + Word16 y2[], /* (i) Q12 :Filtered innovative vector. */ + Word16 g_coeff[], /* (o) Q[exp]:Correlations between xn,y1,y2 */ + Word16 exp_g_coeff[] /* (o) :Q-format of g_coeff[] */ + ) +{ + Word16 i, exp; + Word16 exp_y2y2, exp_xny2, exp_y1y2; + Word16 y2y2, xny2, y1y2; + Word32 L_acc; + Word16 scaled_y2[L_SUBFR]; /* Q9 */ + + /*------------------------------------------------------------------* + * Scale down y2[] from Q12 to Q9 to avoid overflow * + *------------------------------------------------------------------*/ + for (i = 0; i < L_SUBFR; i++) { + scaled_y2[i] = shr (y2[i], 3); + } + + /* Compute scalar product */ + L_acc = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_SUBFR; i++) + L_acc = L_mac (L_acc, scaled_y2[i], scaled_y2[i]); /* L_acc:Q19 */ + + exp = norm_l (L_acc); + y2y2 = wround (L_shl (L_acc, exp)); + exp_y2y2 = add (exp, 19 - 16); /* Q[19+exp-16] */ + + g_coeff[2] = y2y2; + exp_g_coeff[2] = exp_y2y2; + + /* Compute scalar product */ + L_acc = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_SUBFR; i++) + L_acc = L_mac (L_acc, xn[i], scaled_y2[i]); /* L_acc:Q10 */ + + exp = norm_l (L_acc); + xny2 = wround (L_shl (L_acc, exp)); + exp_xny2 = add (exp, 10 - 16); /* Q[10+exp-16] */ + + g_coeff[3] = negate (xny2); + exp_g_coeff[3] = sub (exp_xny2, 1); /* -2 */ + + /* Compute scalar product */ + L_acc = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_SUBFR; i++) + L_acc = L_mac (L_acc, y1[i], scaled_y2[i]); /* L_acc:Q10 */ + + exp = norm_l (L_acc); + y1y2 = wround (L_shl (L_acc, exp)); + exp_y1y2 = add (exp, 10 - 16); /* Q[10+exp-16] */ + + g_coeff[4] = y1y2; + exp_g_coeff[4] = sub (exp_y1y2, 1);; /* 2 */ + + return; +} + + +/*--------------------------------------------------------------------------* + * Function Cor_h_X() * + * ~~~~~~~~~~~~~~~~~~~ * + * Compute correlations of input response h[] with the target vector X[]. * + *--------------------------------------------------------------------------*/ + +void +Cor_h_X (Word16 h[], /* (i) Q12 :Impulse response of filters */ + Word16 X[], /* (i) :Target vector */ + Word16 D[] + /* (o) :Correlations between h[] and D[] */ + /* Normalized to 13 bits */ + ) +{ + Word16 i, j; + Word32 s, max, L_temp; + Word32 y32[L_SUBFR]; + + /* first keep the result on 32 bits and find absolute maximum */ + + max = 0; + + for (i = 0; i < L_SUBFR; i++) { + s = 0; + for (j = i; j < L_SUBFR; j++) + s = L_mac (s, X[j], h[j - i]); + + y32[i] = s; + + s = L_abs (s); + L_temp = L_sub (s, max); + if (L_temp > 0L) { + max = s; + } + } + + /* Find the number of right shifts to do on y32[] */ + /* so that maximum is on 13 bits */ + + j = norm_l (max); + if (sub (j, 16) > 0) { + j = 16; + } + + j = sub (18, j); + + for (i = 0; i < L_SUBFR; i++) { + D[i] = extract_l (L_shr (y32[i], j)); + } + + return; + +} diff --git a/src/libs/libg729/g729_de_acelp.cpp b/src/libs/libg729/g729_de_acelp.cpp new file mode 100644 index 00000000..c9138fea --- /dev/null +++ b/src/libs/libg729/g729_de_acelp.cpp @@ -0,0 +1,73 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-----------------------------------------------------------* + * Function Decod_ACELP() * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * Algebraic codebook decoder. * + *----------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" + +void +Decod_ACELP (Word16 sign, /* (i) : signs of 4 pulses. */ + Word16 index, /* (i) : Positions of the 4 pulses. */ + Word16 cod[] /* (o) Q13 : algebraic (fixed) codebook excitation */ + ) +{ + Word16 i, j; + Word16 pos[4]; + + + /* Decode the positions */ + + i = index & (Word16) 7; + pos[0] = add (i, shl (i, 2)); /* pos0 =i*5 */ + + index = shr (index, 3); + i = index & (Word16) 7; + i = add (i, shl (i, 2)); /* pos1 =i*5+1 */ + pos[1] = add (i, 1); + + index = shr (index, 3); + i = index & (Word16) 7; + i = add (i, shl (i, 2)); /* pos2 =i*5+1 */ + pos[2] = add (i, 2); + + index = shr (index, 3); + j = index & (Word16) 1; + index = shr (index, 1); + i = index & (Word16) 7; + i = add (i, shl (i, 2)); /* pos3 =i*5+3+j */ + i = add (i, 3); + pos[3] = add (i, j); + + /* decode the signs and build the codeword */ + + for (i = 0; i < L_SUBFR; i++) { + cod[i] = 0; + } + + for (j = 0; j < 4; j++) { + + i = sign & (Word16) 1; + sign = shr (sign, 1); + + if (i != 0) { + cod[pos[j]] = 8191; /* Q13 +1.0 */ + } + else { + cod[pos[j]] = -8192; /* Q13 -1.0 */ + } + } + + return; +} diff --git a/src/libs/libg729/g729_dec_gain.cpp b/src/libs/libg729/g729_dec_gain.cpp new file mode 100644 index 00000000..6d65c0e1 --- /dev/null +++ b/src/libs/libg729/g729_dec_gain.cpp @@ -0,0 +1,109 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" + +/*---------------------------------------------------------------------------* + * Function Dec_gain * + * ~~~~~~~~~~~~~~~~~~ * + * Decode the pitch and codebook gains * + * * + *---------------------------------------------------------------------------* + * input arguments: * + * * + * index :Quantization index * + * code[] :Innovative code vector * + * L_subfr :Subframe size * + * bfi :Bad frame indicator * + * * + * output arguments: * + * * + * gain_pit :Quantized pitch gain * + * gain_cod :Quantized codebook gain * + * * + *---------------------------------------------------------------------------*/ +void +Dec_gain (DecState *decoder, + Word16 index, /* (i) :Index of quantization. */ + Word16 code[], /* (i) Q13 :Innovative vector. */ + Word16 L_subfr, /* (i) :Subframe length. */ + Word16 bfi, /* (i) :Bad frame indicator */ + Word16 * gain_pit, /* (o) Q14 :Pitch gain. */ + Word16 * gain_cod /* (o) Q1 :Code gain. */ + ) +{ + Word16 index1, index2, tmp; + Word16 gcode0, exp_gcode0; + Word32 L_gbk12, L_acc, L_accb; + void Gain_predict (Word16 past_qua_en[], Word16 code[], Word16 L_subfr, + Word16 * gcode0, Word16 * exp_gcode0); + void Gain_update (Word16 past_qua_en[], Word32 L_gbk12); + void Gain_update_erasure (Word16 past_qua_en[]); + + /* Gain predictor, Past quantized energies = -14.0 in Q10 */ + + + + /*-------------- Case of erasure. ---------------*/ + + if (bfi != 0) { + *gain_pit = mult (*gain_pit, 29491); /* *0.9 in Q15 */ + if (sub (*gain_pit, 29491) > 0) + *gain_pit = 29491; + *gain_cod = mult (*gain_cod, 32111); /* *0.98 in Q15 */ + + /*----------------------------------------------* + * update table of past quantized energies * + * (frame erasure) * + *----------------------------------------------*/ + Gain_update_erasure (decoder->past_qua_en); + + return; + } + + /*-------------- Decode pitch gain ---------------*/ + + index1 = imap1[shr (index, NCODE2_B)]; + index2 = imap2[index & (NCODE2 - 1)]; + *gain_pit = add (gbk1[index1][0], gbk2[index2][0]); + + /*-------------- Decode codebook gain ---------------*/ + + /*---------------------------------------------------* + *- energy due to innovation -* + *- predicted energy -* + *- predicted codebook gain => gcode0[exp_gcode0] -* + *---------------------------------------------------*/ + + Gain_predict (decoder->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0); + + /*-----------------------------------------------------------------* + * *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; * + *-----------------------------------------------------------------*/ + + L_acc = L_deposit_l (gbk1[index1][1]); + L_accb = L_deposit_l (gbk2[index2][1]); + L_gbk12 = L_add (L_acc, L_accb); /* Q13 */ + tmp = extract_l (L_shr (L_gbk12, 1)); /* Q12 */ + L_acc = L_mult (tmp, gcode0); /* Q[exp_gcode0+12+1] */ + + L_acc = L_shl (L_acc, add (negate (exp_gcode0), (-12 - 1 + 1 + 16))); + *gain_cod = extract_h (L_acc); /* Q1 */ + + /*----------------------------------------------* + * update table of past quantized energies * + *----------------------------------------------*/ + Gain_update (decoder->past_qua_en, L_gbk12); + + return; + +} diff --git a/src/libs/libg729/g729_dec_gain.h b/src/libs/libg729/g729_dec_gain.h new file mode 100644 index 00000000..2c61cf90 --- /dev/null +++ b/src/libs/libg729/g729_dec_gain.h @@ -0,0 +1,18 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + + +void Dec_gain (DecState *decoder, + Word16 index, /* (i) : Index of quantization. */ + Word16 code[], /* (i) Q13 : Innovative vector. */ + Word16 L_subfr, /* (i) : Subframe length. */ + Word16 bfi, /* (i) : Bad frame indicator */ + Word16 * gain_pit, /* (o) Q14 : Pitch gain. */ + Word16 * gain_cod /* (o) Q1 : Code gain. */ + ); diff --git a/src/libs/libg729/g729_dec_lag3.cpp b/src/libs/libg729/g729_dec_lag3.cpp new file mode 100644 index 00000000..185683f2 --- /dev/null +++ b/src/libs/libg729/g729_dec_lag3.cpp @@ -0,0 +1,79 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------------------------* + * Function Dec_lag3 * + * ~~~~~~~~ * + * Decoding of fractional pitch lag with 1/3 resolution. * + * See "Enc_lag3.c" for more details about the encoding procedure. * + *------------------------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" + +void +Dec_lag3 (Word16 index, /* input : received pitch index */ + Word16 pit_min, /* input : minimum pitch lag */ + Word16 pit_max, /* input : maximum pitch lag */ + Word16 i_subfr, /* input : subframe flag */ + Word16 * T0, /* output: integer part of pitch lag */ + Word16 * T0_frac /* output: fractional part of pitch lag */ + ) +{ + Word16 i; + Word16 T0_min, T0_max; + + if (i_subfr == 0) { /* if 1st subframe */ + if (sub (index, 197) < 0) { + /* *T0 = (index+2)/3 + 19 */ + + *T0 = add (mult (add (index, 2), 10923), 19); + + /* *T0_frac = index - *T0*3 + 58 */ + + i = add (add (*T0, *T0), *T0); + *T0_frac = add (sub (index, i), 58); + } + else { + *T0 = sub (index, 112); + *T0_frac = 0; + } + + } + + else { /* second subframe */ + + /* find T0_min and T0_max for 2nd subframe */ + + T0_min = sub (*T0, 5); + if (sub (T0_min, pit_min) < 0) { + T0_min = pit_min; + } + + T0_max = add (T0_min, 9); + if (sub (T0_max, pit_max) > 0) { + T0_max = pit_max; + T0_min = sub (T0_max, 9); + } + + /* i = (index+2)/3 - 1 */ + /* *T0 = i + t0_min; */ + + i = sub (mult (add (index, 2), 10923), 1); + *T0 = add (i, T0_min); + + /* t0_frac = index - 2 - i*3; */ + + i = add (add (i, i), i); + *T0_frac = sub (sub (index, 2), i); + } + + return; +} diff --git a/src/libs/libg729/g729_dec_ld8a.cpp b/src/libs/libg729/g729_dec_ld8a.cpp new file mode 100644 index 00000000..94bd4652 --- /dev/null +++ b/src/libs/libg729/g729_dec_ld8a.cpp @@ -0,0 +1,271 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-----------------------------------------------------------------* + * Functions Init_Decod_ld8a and Decod_ld8a * + *-----------------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" +#include "g729_lspdec.h" +#include "g729_util.h" +#include "g729_dec_gain.h" + +/*---------------------------------------------------------------* + * Decoder constant parameters (defined in "ld8a.h") * + *---------------------------------------------------------------* + * L_FRAME : Frame size. * + * L_SUBFR : Sub-frame size. * + * M : LPC order. * + * MP1 : LPC order+1 * + * PIT_MIN : Minimum pitch lag. * + * PIT_MAX : Maximum pitch lag. * + * L_INTERPOL : Length of filter for interpolation * + * PRM_SIZE : Size of vector containing analysis parameters * + *---------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------* + * Function Init_Decod_ld8a * + * ~~~~~~~~~~~~~~~ * + * * + * ->Initialization of variables for the decoder section. * + * * + *-----------------------------------------------------------------*/ + +DecState * +Init_Decod_ld8a (void) +{ + DecState *decoder; + + decoder = (DecState*) malloc (sizeof (DecState)); + + /* Initialize pointers */ + + decoder->exc = decoder->old_exc + PIT_MAX + L_INTERPOL; + + /* Static vectors to zero */ + + Set_zero (decoder->old_exc, PIT_MAX + L_INTERPOL); + Set_zero (decoder->mem_syn, M10); + + Copy (lsp_old_init, decoder->lsp_old, M10); + + decoder->sharp = SHARPMIN; + decoder->old_T0 = 60; + decoder->gain_code = 0; + decoder->gain_pitch = 0; + + Lsp_decw_reset (decoder); + + decoder->bad_lsf = 0; + Set_zero (decoder->Az_dec, MP1 * 2); + Set_zero (decoder->synth_buf, L_FRAME + M10); + Set_zero (decoder->T2, 2); + + Copy (past_qua_en_init, decoder->past_qua_en, 4); + + decoder->seed = 21845; + + return decoder; +} + +/*-----------------------------------------------------------------* + * Function Decod_ld8a * + * ~~~~~~~~~~ * + * ->Main decoder routine. * + * * + *-----------------------------------------------------------------*/ + +void +Decod_ld8a (DecState *decoder, + Word16 parm[], /* (i) : vector of synthesis parameters + parm[0] = bad frame indicator (bfi) */ + Word16 synth[], /* (o) : synthesis speech */ + Word16 A_t[], /* (o) : decoded LP filter in 2 subframes */ + Word16 * T2, /* (o) : decoded pitch lag in 2 subframes */ + Word16 * bad_lsf) +{ + Flag Overflow; + Word16 *Az; /* Pointer on A_t */ + Word16 lsp_new[M10]; /* LSPs */ + Word16 code[L_SUBFR]; /* ACELP codevector */ + + /* Scalars */ + + Word16 i, j, i_subfr; + Word16 T0, T0_frac, index; + Word16 bfi; + Word32 L_temp; + + Word16 bad_pitch; /* bad pitch indicator */ + + /* Test bad frame indicator (bfi) */ + + bfi = *parm++; + + /* Decode the LSPs */ + + D_lsp (decoder, parm, lsp_new, add (bfi, *bad_lsf)); + parm += 2; + + /* + Note: "bad_lsf" is introduce in case the standard is used with + channel protection. + */ + + /* Interpolation of LPC for the 2 subframes */ + + Int_qlpc (decoder->lsp_old, lsp_new, A_t); + + /* update the LSFs for the next frame */ + + Copy (lsp_new, decoder->lsp_old, M10); + +/*------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * + * times * + * - decode the pitch delay * + * - decode algebraic code * + * - decode pitch and codebook gains * + * - find the excitation and compute synthesis speech * + *------------------------------------------------------------------------*/ + + Az = A_t; /* pointer to interpolated LPC parameters */ + + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { + + index = *parm++; /* pitch index */ + + if (i_subfr == 0) { + i = *parm++; /* get parity check result */ + bad_pitch = add (bfi, i); + if (bad_pitch == 0) { + Dec_lag3 (index, PIT_MIN, PIT_MAX, i_subfr, &T0, &T0_frac); + decoder->old_T0 = T0; + } + else { /* Bad frame, or parity error */ + + T0 = decoder->old_T0; + T0_frac = 0; + decoder->old_T0 = add (decoder->old_T0, 1); + if (sub (decoder->old_T0, PIT_MAX) > 0) { + decoder->old_T0 = PIT_MAX; + } + } + } + else { /* second subframe */ + + if (bfi == 0) { + Dec_lag3 (index, PIT_MIN, PIT_MAX, i_subfr, &T0, &T0_frac); + decoder->old_T0 = T0; + } + else { + T0 = decoder->old_T0; + T0_frac = 0; + decoder->old_T0 = add (decoder->old_T0, 1); + if (sub (decoder->old_T0, PIT_MAX) > 0) { + decoder->old_T0 = PIT_MAX; + } + } + } + *T2++ = T0; + + /*-------------------------------------------------* + * - Find the adaptive codebook vector. * + *-------------------------------------------------*/ + + Pred_lt_3 (&decoder->exc[i_subfr], T0, T0_frac, L_SUBFR); + + /*-------------------------------------------------------* + * - Decode innovative codebook. * + * - Add the fixed-gain pitch contribution to code[]. * + *-------------------------------------------------------*/ + + if (bfi != 0) { /* Bad frame */ + + parm[0] = Random_16 (&decoder->seed) & (Word16) 0x1fff; /* 13 bits random */ + parm[1] = Random_16 (&decoder->seed) & (Word16) 0x000f; /* 4 bits random */ + } + Decod_ACELP (parm[1], parm[0], code); + parm += 2; + + j = shl (decoder->sharp, 1); /* From Q14 to Q15 */ + if (sub (T0, L_SUBFR) < 0) { + for (i = T0; i < L_SUBFR; i++) { + code[i] = add (code[i], mult (code[i - T0], j)); + } + } + + /*-------------------------------------------------* + * - Decode pitch and codebook gains. * + *-------------------------------------------------*/ + + index = *parm++; /* index of energy VQ */ + + Dec_gain (decoder, index, code, L_SUBFR, bfi, &decoder->gain_pitch, &decoder->gain_code); + + /*-------------------------------------------------------------* + * - Update pitch sharpening "sharp" with quantized gain_pitch * + *-------------------------------------------------------------*/ + + decoder->sharp = decoder->gain_pitch; + if (sub (decoder->sharp, SHARPMAX) > 0) { + decoder->sharp = SHARPMAX; + } + if (sub (decoder->sharp, SHARPMIN) < 0) { + decoder->sharp = SHARPMIN; + } + + /*-------------------------------------------------------* + * - Find the total excitation. * + * - Find synthesis speech corresponding to exc[]. * + *-------------------------------------------------------*/ + + for (i = 0; i < L_SUBFR; i++) { + /* exc[i] = gain_pitch*exc[i] + gain_code*code[i]; */ + /* exc[i] in Q0 gain_pitch in Q14 */ + /* code[i] in Q13 gain_codeode in Q1 */ + + L_temp = L_mult (decoder->exc[i + i_subfr], decoder->gain_pitch); + L_temp = L_mac (L_temp, code[i], decoder->gain_code); + L_temp = L_shl (L_temp, 1); + decoder->exc[i + i_subfr] = wround (L_temp); + } + + Overflow = 0; + Syn_filt (Az, &decoder->exc[i_subfr], &synth[i_subfr], L_SUBFR, decoder->mem_syn, 0, &Overflow); + if (Overflow != 0) { + /* In case of overflow in the synthesis */ + /* -> Scale down vector exc[] and redo synthesis */ + + for (i = 0; i < PIT_MAX + L_INTERPOL + L_FRAME; i++) + decoder->old_exc[i] = shr (decoder->old_exc[i], 2); + + Syn_filt (Az, &decoder->exc[i_subfr], &synth[i_subfr], L_SUBFR, decoder->mem_syn, 1, NULL); + } + else + Copy (&synth[i_subfr + L_SUBFR - M10], decoder->mem_syn, M10); + + Az += MP1; /* interpolated LPC parameters for next subframe */ + } + + /*--------------------------------------------------* + * Update signal for next frame. * + * -> shift to the left by L_FRAME exc[] * + *--------------------------------------------------*/ + + Copy (&decoder->old_exc[L_FRAME], &decoder->old_exc[0], PIT_MAX + L_INTERPOL); + + return; +} diff --git a/src/libs/libg729/g729_dspfunc.cpp b/src/libs/libg729/g729_dspfunc.cpp new file mode 100644 index 00000000..363ab97b --- /dev/null +++ b/src/libs/libg729/g729_dspfunc.cpp @@ -0,0 +1,182 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" + +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" + +/*___________________________________________________________________________ + | | + | Function Name : Pow2() | + | | + | L_x = pow(2.0, exponent.fraction) | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The function Pow2(L_x) is approximated by a table and linear | + | interpolation. | + | | + | 1- i = bit10-b15 of fraction, 0 <= i <= 31 | + | 2- a = bit0-b9 of fraction | + | 3- L_x = tabpow[i]<<16 - (tabpow[i] - tabpow[i+1]) * a * 2 | + | 4- L_x = L_x >> (30-exponent) (with rounding) | + |___________________________________________________________________________| +*/ + + +Word32 +Pow2 ( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */ + Word16 exponent, /* (i) Q0 : Integer part. (range: 0<=val<=30) */ + Word16 fraction /* (i) Q15 : Fractional part. (range: 0.0<=val<1.0) */ + ) +{ + Word16 exp, i, a, tmp; + Word32 L_x; + + L_x = L_mult (fraction, 32); /* L_x = fraction<<6 */ + i = extract_h (L_x); /* Extract b10-b15 of fraction */ + L_x = L_shr (L_x, 1); + a = extract_l (L_x); /* Extract b0-b9 of fraction */ + a = a & (Word16) 0x7fff; + + L_x = L_deposit_h (tabpow[i]); /* tabpow[i] << 16 */ + tmp = sub (tabpow[i], tabpow[i + 1]); /* tabpow[i] - tabpow[i+1] */ + L_x = L_msu (L_x, tmp, a); /* L_x -= tmp*a*2 */ + + exp = sub (30, exponent); + L_x = L_shr_r (L_x, exp); + + return (L_x); +} + +/*___________________________________________________________________________ + | | + | Function Name : Log2() | + | | + | Compute log2(L_x). | + | L_x is positive. | + | | + | if L_x is negative or zero, result is 0. | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The function Log2(L_x) is approximated by a table and linear | + | interpolation. | + | | + | 1- Normalization of L_x. | + | 2- exponent = 30-exponent | + | 3- i = bit25-b31 of L_x, 32 <= i <= 63 ->because of normalization. | + | 4- a = bit10-b24 | + | 5- i -=32 | + | 6- fraction = tablog[i]<<16 - (tablog[i] - tablog[i+1]) * a * 2 | + |___________________________________________________________________________| +*/ + +void +Log2 (Word32 L_x, /* (i) Q0 : input value */ + Word16 * exponent, /* (o) Q0 : Integer part of Log2. (range: 0<=val<=30) */ + Word16 * fraction /* (o) Q15: Fractional part of Log2. (range: 0<=val<1) */ + ) +{ + Word16 exp, i, a, tmp; + Word32 L_y; + + if (L_x <= (Word32) 0) { + *exponent = 0; + *fraction = 0; + return; + } + + exp = norm_l (L_x); + L_x = L_shl (L_x, exp); /* L_x is normalized */ + + *exponent = sub (30, exp); + + L_x = L_shr (L_x, 9); + i = extract_h (L_x); /* Extract b25-b31 */ + L_x = L_shr (L_x, 1); + a = extract_l (L_x); /* Extract b10-b24 of fraction */ + a = a & (Word16) 0x7fff; + + i = sub (i, 32); + + L_y = L_deposit_h (tablog[i]); /* tablog[i] << 16 */ + tmp = sub (tablog[i], tablog[i + 1]); /* tablog[i] - tablog[i+1] */ + L_y = L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */ + + *fraction = extract_h (L_y); + + return; +} + +/*___________________________________________________________________________ + | | + | Function Name : Inv_sqrt | + | | + | Compute 1/sqrt(L_x). | + | L_x is positive. | + | | + | if L_x is negative or zero, result is 1 (3fff ffff). | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The function 1/sqrt(L_x) is approximated by a table and linear | + | interpolation. | + | | + | 1- Normalization of L_x. | + | 2- If (30-exponent) is even then shift right once. | + | 3- exponent = (30-exponent)/2 +1 | + | 4- i = bit25-b31 of L_x, 16 <= i <= 63 ->because of normalization. | + | 5- a = bit10-b24 | + | 6- i -=16 | + | 7- L_y = tabsqr[i]<<16 - (tabsqr[i] - tabsqr[i+1]) * a * 2 | + | 8- L_y >>= exponent | + |___________________________________________________________________________| +*/ + + +Word32 +Inv_sqrt ( /* (o) Q30 : output value (range: 0<=val<1) */ + Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ + ) +{ + Word16 exp, i, a, tmp; + Word32 L_y; + + if (L_x <= (Word32) 0) + return ((Word32) 0x3fffffffL); + + exp = norm_l (L_x); + L_x = L_shl (L_x, exp); /* L_x is normalize */ + + exp = sub (30, exp); + if ((exp & 1) == 0) /* If exponent even -> shift right */ + L_x = L_shr (L_x, 1); + + exp = shr (exp, 1); + exp = add (exp, 1); + + L_x = L_shr (L_x, 9); + i = extract_h (L_x); /* Extract b25-b31 */ + L_x = L_shr (L_x, 1); + a = extract_l (L_x); /* Extract b10-b24 */ + a = a & (Word16) 0x7fff; + + i = sub (i, 16); + + L_y = L_deposit_h (tabsqr[i]); /* tabsqr[i] << 16 */ + tmp = sub (tabsqr[i], tabsqr[i + 1]); /* tabsqr[i] - tabsqr[i+1]) */ + L_y = L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */ + + L_y = L_shr (L_y, exp); /* denormalization */ + + return (L_y); +} diff --git a/src/libs/libg729/g729_filter.cpp b/src/libs/libg729/g729_filter.cpp new file mode 100644 index 00000000..7cd135a8 --- /dev/null +++ b/src/libs/libg729/g729_filter.cpp @@ -0,0 +1,128 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------------------------------------------* + * Function Convolve: * + * ~~~~~~~~~ * + *-------------------------------------------------------------------* + * Perform the convolution between two vectors x[] and h[] and * + * write the result in the vector y[]. * + * All vectors are of length N. * + *-------------------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" + +void +Convolve (Word16 x[], /* (i) : input vector */ + Word16 h[], /* (i) Q12 : impulse response */ + Word16 y[], /* (o) : output vector */ + Word16 L /* (i) : vector size */ + ) +{ + Word16 i, n; + Word32 s; + + for (n = 0; n < L; n++) { + s = 0; + for (i = 0; i <= n; i++) + s = L_mac (s, x[i], h[n - i]); + + s = L_shl (s, 3); /* h is in Q12 and saturation */ + y[n] = extract_h (s); + } + + return; +} + +/*-----------------------------------------------------* + * procedure Syn_filt: * + * ~~~~~~~~ * + * Do the synthesis filtering 1/A(z). * + *-----------------------------------------------------*/ + + +void +Syn_filt (Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients (m=10) */ + Word16 x[], /* (i) : input signal */ + Word16 y[], /* (o) : output signal */ + Word16 lg, /* (i) : size of filtering */ + Word16 mem[], /* (i/o) : memory associated with this filtering. */ + Word16 update, /* (i) : 0=no update, 1=update of memory. */ + Flag *Overflow + ) +{ + Flag Over = 0; + Word16 i, j; + Word32 s; + Word16 tmp[100]; /* This is usually done by memory allocation (lg+M) */ + Word16 *yy; + + /* Copy mem[] to yy[] */ + + yy = tmp; + + for (i = 0; i < M10; i++) { + *yy++ = mem[i]; + } + + /* Do the filtering. */ + + for (i = 0; i < lg; i++) { + s = L_mult_o (x[i], a[0], &Over); + for (j = 1; j <= M10; j++) + s = L_msu_o (s, a[j], yy[-j], &Over); + + s = L_shl_o (s, 3, &Over); + *yy++ = wround_o (s, &Over); + } + + for (i = 0; i < lg; i++) { + y[i] = tmp[i + M10]; + } + + /* Update of memory if update==1 */ + + if (update != 0) + for (i = 0; i < M10; i++) { + mem[i] = y[lg - M10 + i]; + } + + if (Overflow != NULL) + *Overflow = Over; + + return; +} + +/*-----------------------------------------------------------------------* + * procedure Residu: * + * ~~~~~~ * + * Compute the LPC residual by filtering the input speech through A(z) * + *-----------------------------------------------------------------------*/ + +void Residu (Word16 a[], /* (i) Q12 : prediction coefficients */ + Word16 x[], /* (i) : speech (values x[-m..-1] are needed */ + Word16 y[], /* (o) : residual signal */ + Word16 lg /* (i) : size of filtering */ + ) +{ + Word16 i, j; + Word32 s; + + for (i = 0; i < lg; i++) { + s = L_mult (x[i], a[0]); + for (j = 1; j <= M10; j++) + s = L_mac (s, a[j], x[i - j]); + + s = L_shl (s, 3); + y[i] = wround (s); + } + return; +} diff --git a/src/libs/libg729/g729_gain.cpp b/src/libs/libg729/g729_gain.cpp new file mode 100644 index 00000000..87ca3ac4 --- /dev/null +++ b/src/libs/libg729/g729_gain.cpp @@ -0,0 +1,443 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_oper_32b.h" + +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" +#include "g729_taming.h" + +void Gbk_presel (Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */ + /* (i) [1] Q2 : unquantized code gain */ + Word16 * cand1, /* (o) : index of best 1st stage vector */ + Word16 * cand2, /* (o) : index of best 2nd stage vector */ + Word16 gcode0 /* (i) Q4 : presearch for gain codebook */ + ); + + +/*---------------------------------------------------------------------------* + * Function Qua_gain * + * ~~~~~~~~~~~~~~~~~~ * + * Inputs: * + * code[] :Innovative codebook. * + * g_coeff[] :Correlations compute for pitch. * + * L_subfr :Subframe length. * + * * + * Outputs: * + * gain_pit :Quantized pitch gain. * + * gain_cod :Quantized code gain. * + * * + * Return: * + * Index of quantization. * + * * + *--------------------------------------------------------------------------*/ +Word16 +Qua_gain (CodState *coder, + Word16 code[], /* (i) Q13 :Innovative vector. */ + Word16 g_coeff[], /* (i) :Correlations -2 */ + /* , -2, 2 */ + Word16 exp_coeff[], /* (i) :Q-Format g_coeff[] */ + Word16 L_subfr, /* (i) :Subframe length. */ + Word16 * gain_pit, /* (o) Q14 :Pitch gain. */ + Word16 * gain_cod, /* (o) Q1 :Code gain. */ + Word16 tameflag /* (i) : set to 1 if taming is needed */ + ) +{ + Word16 i, j, index1, index2; + Word16 cand1, cand2; + Word16 exp, gcode0, exp_gcode0, gcode0_org, e_min; + Word16 nume, denom, inv_denom; + Word16 exp1, exp2, exp_nume, exp_denom, exp_inv_denom, sft, tmp; + Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod; + Word16 coeff[5], coeff_lsf[5]; + Word16 exp_min[5]; + Word32 L_gbk12; + Word32 L_tmp, L_dist_min, L_temp, L_tmp1, L_tmp2, L_acc, L_accb; + Word16 best_gain[2]; + + /* Gain predictor, Past quantized energies = -14.0 in Q10 */ + + + /*---------------------------------------------------* + *- energy due to innovation -* + *- predicted energy -* + *- predicted codebook gain => gcode0[exp_gcode0] -* + *---------------------------------------------------*/ + + Gain_predict (coder->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0); + + /*-----------------------------------------------------------------* + * pre-selection * + *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * calculate best gain * + * * + * tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; * + * best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; * + * best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; * + * gbk_presel(best_gain,&cand1,&cand2,gcode0) ; * + * * + *-----------------------------------------------------------------*/ + + /*-----------------------------------------------------------------* + * tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; * + *-----------------------------------------------------------------*/ + L_tmp1 = L_mult (g_coeff[0], g_coeff[2]); + exp1 = add (add (exp_coeff[0], exp_coeff[2]), 1 - 2); + L_tmp2 = L_mult (g_coeff[4], g_coeff[4]); + exp2 = add (add (exp_coeff[4], exp_coeff[4]), 1); + + if (sub (exp1, exp2) > 0) { + L_tmp = L_sub (L_shr (L_tmp1, sub (exp1, exp2)), L_tmp2); + exp = exp2; + } + else { + L_tmp = L_sub (L_tmp1, L_shr (L_tmp2, sub (exp2, exp1))); + exp = exp1; + } + sft = norm_l (L_tmp); + denom = extract_h (L_shl (L_tmp, sft)); + exp_denom = sub (add (exp, sft), 16); + + inv_denom = div_s (16384, denom); + inv_denom = negate (inv_denom); + exp_inv_denom = sub (14 + 15, exp_denom); + + /*-----------------------------------------------------------------* + * best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; * + *-----------------------------------------------------------------*/ + L_tmp1 = L_mult (g_coeff[2], g_coeff[1]); + exp1 = add (exp_coeff[2], exp_coeff[1]); + L_tmp2 = L_mult (g_coeff[3], g_coeff[4]); + exp2 = add (add (exp_coeff[3], exp_coeff[4]), 1); + + if (sub (exp1, exp2) > 0) { + L_tmp = + L_sub (L_shr (L_tmp1, add (sub (exp1, exp2), 1)), L_shr (L_tmp2, 1)); + exp = sub (exp2, 1); + } + else { + L_tmp = + L_sub (L_shr (L_tmp1, 1), L_shr (L_tmp2, add (sub (exp2, exp1), 1))); + exp = sub (exp1, 1); + } + sft = norm_l (L_tmp); + nume = extract_h (L_shl (L_tmp, sft)); + exp_nume = sub (add (exp, sft), 16); + + sft = sub (add (exp_nume, exp_inv_denom), (9 + 16 - 1)); + L_acc = L_shr (L_mult (nume, inv_denom), sft); + best_gain[0] = extract_h (L_acc); /*-- best_gain[0]:Q9 --*/ + + if (tameflag == 1) { + if (sub (best_gain[0], GPCLIP2) > 0) + best_gain[0] = GPCLIP2; + } + + /*-----------------------------------------------------------------* + * best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; * + *-----------------------------------------------------------------*/ + L_tmp1 = L_mult (g_coeff[0], g_coeff[3]); + exp1 = add (exp_coeff[0], exp_coeff[3]); + L_tmp2 = L_mult (g_coeff[1], g_coeff[4]); + exp2 = add (add (exp_coeff[1], exp_coeff[4]), 1); + + if (sub (exp1, exp2) > 0) { + L_tmp = + L_sub (L_shr (L_tmp1, add (sub (exp1, exp2), 1)), L_shr (L_tmp2, 1)); + exp = sub (exp2, 1); + } + else { + L_tmp = + L_sub (L_shr (L_tmp1, 1), L_shr (L_tmp2, add (sub (exp2, exp1), 1))); + exp = sub (exp1, 1); + } + sft = norm_l (L_tmp); + nume = extract_h (L_shl (L_tmp, sft)); + exp_nume = sub (add (exp, sft), 16); + + sft = sub (add (exp_nume, exp_inv_denom), (2 + 16 - 1)); + L_acc = L_shr (L_mult (nume, inv_denom), sft); + best_gain[1] = extract_h (L_acc); /*-- best_gain[1]:Q2 --*/ + + /*--- Change Q-format of gcode0 ( Q[exp_gcode0] -> Q4 ) ---*/ + if (sub (exp_gcode0, 4) >= 0) { + gcode0_org = shr (gcode0, sub (exp_gcode0, 4)); + } + else { + L_acc = L_deposit_l (gcode0); + L_acc = L_shl (L_acc, sub ((4 + 16), exp_gcode0)); + gcode0_org = extract_h (L_acc); /*-- gcode0_org:Q4 --*/ + } + + /*----------------------------------------------* + * - presearch for gain codebook - * + *----------------------------------------------*/ + + Gbk_presel (best_gain, &cand1, &cand2, gcode0_org); + +/*---------------------------------------------------------------------------* + * * + * Find the best quantizer. * + * * + * dist_min = MAX_32; * + * for ( i=0 ; ipast_qua_en, L_gbk12); + + return (add (map1[index1] * (Word16) NCODE2, map2[index2])); + +} + +/*---------------------------------------------------------------------------* + * Function Gbk_presel * + * ~~~~~~~~~~~~~~~~~~~ * + * - presearch for gain codebook - * + *---------------------------------------------------------------------------*/ +void +Gbk_presel (Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */ + /* (i) [1] Q2 : unquantized code gain */ + Word16 * cand1, /* (o) : index of best 1st stage vector */ + Word16 * cand2, /* (o) : index of best 2nd stage vector */ + Word16 gcode0 /* (i) Q4 : presearch for gain codebook */ + ) +{ + Word16 acc_h; + Word16 sft_x, sft_y; + Word32 L_acc, L_preg, L_cfbg, L_tmp, L_tmp_x, L_tmp_y; + Word32 L_temp; + + /*--------------------------------------------------------------------------* + x = (best_gain[1]-(coef[0][0]*best_gain[0]+coef[1][1])*gcode0) * inv_coef; + *--------------------------------------------------------------------------*/ + L_cfbg = L_mult (coef[0][0], best_gain[0]); /* L_cfbg:Q20 -> !!y */ + L_acc = L_shr (L_coef[1][1], 15); /* L_acc:Q20 */ + L_acc = L_add (L_cfbg, L_acc); + acc_h = extract_h (L_acc); /* acc_h:Q4 */ + L_preg = L_mult (acc_h, gcode0); /* L_preg:Q9 */ + L_acc = L_shl (L_deposit_l (best_gain[1]), 7); /* L_acc:Q9 */ + L_acc = L_sub (L_acc, L_preg); + acc_h = extract_h (L_shl (L_acc, 2)); /* L_acc_h:Q[-5] */ + L_tmp_x = L_mult (acc_h, INV_COEF); /* L_tmp_x:Q15 */ + + /*--------------------------------------------------------------------------* + y = (coef[1][0]*(-coef[0][1]+best_gain[0]*coef[0][0])*gcode0 + -coef[0][0]*best_gain[1]) * inv_coef; + *--------------------------------------------------------------------------*/ + L_acc = L_shr (L_coef[0][1], 10); /* L_acc:Q20 */ + L_acc = L_sub (L_cfbg, L_acc); /* !!x -> L_cfbg:Q20 */ + acc_h = extract_h (L_acc); /* acc_h:Q4 */ + acc_h = mult (acc_h, gcode0); /* acc_h:Q[-7] */ + L_tmp = L_mult (acc_h, coef[1][0]); /* L_tmp:Q10 */ + + L_preg = L_mult (coef[0][0], best_gain[1]); /* L_preg:Q13 */ + L_acc = L_sub (L_tmp, L_shr (L_preg, 3)); /* L_acc:Q10 */ + + acc_h = extract_h (L_shl (L_acc, 2)); /* acc_h:Q[-4] */ + L_tmp_y = L_mult (acc_h, INV_COEF); /* L_tmp_y:Q16 */ + + sft_y = (14 + 4 + 1) - 16; /* (Q[thr1]+Q[gcode0]+1)-Q[L_tmp_y] */ + sft_x = (15 + 4 + 1) - 15; /* (Q[thr2]+Q[gcode0]+1)-Q[L_tmp_x] */ + + if (gcode0 > 0) { + /*-- pre select codebook #1 --*/ + *cand1 = 0; + do { + L_temp = L_sub (L_tmp_y, L_shr (L_mult (thr1[*cand1], gcode0), sft_y)); + if (L_temp > 0L) { + (*cand1) = add (*cand1, 1); + } + else + break; + } while (sub ((*cand1), (NCODE1 - NCAN1)) < 0); + /*-- pre select codebook #2 --*/ + *cand2 = 0; + do { + L_temp = L_sub (L_tmp_x, L_shr (L_mult (thr2[*cand2], gcode0), sft_x)); + if (L_temp > 0L) { + (*cand2) = add (*cand2, 1); + } + else + break; + } while (sub ((*cand2), (NCODE2 - NCAN2)) < 0); + } + else { + /*-- pre select codebook #1 --*/ + *cand1 = 0; + do { + L_temp = L_sub (L_tmp_y, L_shr (L_mult (thr1[*cand1], gcode0), sft_y)); + if (L_temp < 0L) { + (*cand1) = add (*cand1, 1); + } + else + break; + } while (sub ((*cand1), (NCODE1 - NCAN1))); + /*-- pre select codebook #2 --*/ + *cand2 = 0; + do { + L_temp = L_sub (L_tmp_x, L_shr (L_mult (thr2[*cand2], gcode0), sft_x)); + if (L_temp < 0L) { + (*cand2) = add (*cand2, 1); + } + else + break; + } while (sub ((*cand2), (NCODE2 - NCAN2))); + } + + return; +} diff --git a/src/libs/libg729/g729_gain.h b/src/libs/libg729/g729_gain.h new file mode 100644 index 00000000..56f518b1 --- /dev/null +++ b/src/libs/libg729/g729_gain.h @@ -0,0 +1,23 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*--------------------------------------------------------------------------* + * gain VQ functions. * + *--------------------------------------------------------------------------*/ + +Word16 Qua_gain (CodState *coder, + Word16 code[], /* (i) Q13 : Innovative vector. */ + Word16 g_coeff[], /* (i) : Correlations -2 */ + /* , -2, 2 */ + Word16 exp_coeff[], /* (i) : Q-Format g_coeff[] */ + Word16 L_subfr, /* (i) : Subframe length. */ + Word16 * gain_pit, /* (o) Q14 : Pitch gain. */ + Word16 * gain_cod, /* (o) Q1 : Code gain. */ + Word16 tameflag /* (i) : flag set to 1 if taming is needed */ + ); diff --git a/src/libs/libg729/g729_gainpred.cpp b/src/libs/libg729/g729_gainpred.cpp new file mode 100644 index 00000000..a7c4da25 --- /dev/null +++ b/src/libs/libg729/g729_gainpred.cpp @@ -0,0 +1,159 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*---------------------------------------------------------------------------* + * Gain_predict() : make gcode0(exp_gcode0) * + * Gain_update() : update table of past quantized energies. * + * Gain_update_erasure() : update table of past quantized energies. * + * (frame erasure) * + * This function is used both Coder and Decoder. * + *---------------------------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" +#include "g729_oper_32b.h" + +/*---------------------------------------------------------------------------* + * Function Gain_predict * + * ~~~~~~~~~~~~~~~~~~~~~~ * + * MA prediction is performed on the innovation energy (in dB with mean * + * removed). * + *---------------------------------------------------------------------------*/ +void +Gain_predict (Word16 past_qua_en[], /* (i) Q10 :Past quantized energies */ + Word16 code[], /* (i) Q13 :Innovative vector. */ + Word16 L_subfr, /* (i) :Subframe length. */ + Word16 * gcode0, /* (o) Qxx :Predicted codebook gain */ + Word16 * exp_gcode0 /* (o) :Q-Format(gcode0) */ + ) +{ + Word16 i, exp, frac; + Word32 L_tmp; + + /*-------------------------------* + * Energy coming from code * + *-------------------------------*/ + + L_tmp = 0; + for (i = 0; i < L_subfr; i++) + L_tmp = L_mac (L_tmp, code[i], code[i]); + + /*-----------------------------------------------------------------* + * Compute: means_ener - 10log10(ener_code/ L_sufr) * + * Note: mean_ener change from 36 dB to 30 dB because input/2 * + * * + * = 30.0 - 10 log10( ener_code / lcode) + 10log10(2^27) * + * !!ener_code in Q27!! * + * = 30.0 - 3.0103 * log2(ener_code) + 10log10(40) + 10log10(2^27) * + * = 30.0 - 3.0103 * log2(ener_code) + 16.02 + 81.278 * + * = 127.298 - 3.0103 * log2(ener_code) * + *-----------------------------------------------------------------*/ + + Log2 (L_tmp, &exp, &frac); /* Q27->Q0 ^Q0 ^Q15 */ + L_tmp = Mpy_32_16 (exp, frac, -24660); /* Q0 Q15 Q13 -> ^Q14 */ + /* hi:Q0+Q13+1 */ + /* lo:Q15+Q13-15+1 */ + /* -24660[Q13]=-3.0103 */ + L_tmp = L_mac (L_tmp, 32588, 32); /* 32588*32[Q14]=127.298 */ + + /*-----------------------------------------------------------------* + * Compute gcode0. * + * = Sum(i=0,3) g729_pred[i]*past_qua_en[i] - ener_code + mean_ener * + *-----------------------------------------------------------------*/ + + L_tmp = L_shl (L_tmp, 10); /* From Q14 to Q24 */ + for (i = 0; i < 4; i++) + L_tmp = L_mac (L_tmp, g729_pred[i], past_qua_en[i]); /* Q13*Q10 ->Q24 */ + + *gcode0 = extract_h (L_tmp); /* From Q24 to Q8 */ + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) * + * = pow(2, 3.3219*gcode0/20) * + * = pow(2, 0.166*gcode0) * + *-----------------------------------------------------------------*/ + + L_tmp = L_mult (*gcode0, 5439); /* *0.166 in Q15, result in Q24 */ + L_tmp = L_shr (L_tmp, 8); /* From Q24 to Q16 */ + L_Extract (L_tmp, &exp, &frac); /* Extract exponent of gcode0 */ + + *gcode0 = extract_l (Pow2 (14, frac)); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16768 < Pow2() <= 32767 */ + *exp_gcode0 = sub (14, exp); +} + + +/*---------------------------------------------------------------------------* + * Function Gain_update * + * ~~~~~~~~~~~~~~~~~~~~~~ * + * update table of past quantized energies * + *---------------------------------------------------------------------------*/ +void +Gain_update (Word16 past_qua_en[], /* (io) Q10 :Past quantized energies */ + Word32 L_gbk12 /* (i) Q13 : gbk1[indice1][1]+gbk2[indice2][1] */ + ) +{ + Word16 i, tmp; + Word16 exp, frac; + Word32 L_acc; + + for (i = 3; i > 0; i--) { + past_qua_en[i] = past_qua_en[i - 1]; /* Q10 */ + } + /*----------------------------------------------------------------------* + * -- past_qua_en[0] = 20*log10(gbk1[index1][1]+gbk2[index2][1]); -- * + * 2 * 10 log10( gbk1[index1][1]+gbk2[index2][1] ) * + * = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] ) * + * = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] ) * + * 24660:Q12(6.0205) * + *----------------------------------------------------------------------*/ + + Log2 (L_gbk12, &exp, &frac); /* L_gbk12:Q13 */ + L_acc = L_Comp (sub (exp, 13), frac); /* L_acc:Q16 */ + tmp = extract_h (L_shl (L_acc, 13)); /* tmp:Q13 */ + past_qua_en[0] = mult (tmp, 24660); /* past_qua_en[]:Q10 */ +} + + +/*---------------------------------------------------------------------------* + * Function Gain_update_erasure * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * update table of past quantized energies (frame erasure) * + *---------------------------------------------------------------------------* + * av_pred_en = 0.0; * + * for (i = 0; i < 4; i++) * + * av_pred_en += past_qua_en[i]; * + * av_pred_en = av_pred_en*0.25 - 4.0; * + * if (av_pred_en < -14.0) av_pred_en = -14.0; * + *---------------------------------------------------------------------------*/ +void +Gain_update_erasure (Word16 past_qua_en[] /* (i) Q10 :Past quantized energies */ + ) +{ + Word16 i, av_pred_en; + Word32 L_tmp; + + L_tmp = 0; /* Q10 */ + for (i = 0; i < 4; i++) + L_tmp = L_add (L_tmp, L_deposit_l (past_qua_en[i])); + av_pred_en = extract_l (L_shr (L_tmp, 2)); + av_pred_en = sub (av_pred_en, 4096); /* Q10 */ + + if (sub (av_pred_en, -14336) < 0) { + av_pred_en = -14336; /* 14336:14[Q10] */ + } + + for (i = 3; i > 0; i--) { + past_qua_en[i] = past_qua_en[i - 1]; + } + past_qua_en[0] = av_pred_en; +} diff --git a/src/libs/libg729/g729_ld8a.h b/src/libs/libg729/g729_ld8a.h new file mode 100644 index 00000000..f2800b1f --- /dev/null +++ b/src/libs/libg729/g729_ld8a.h @@ -0,0 +1,474 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ +#ifndef _G729_LD8A_H +#define _G729_LD8A_H + +#include +#include + +typedef struct _CodState CodState; +typedef struct _DecState DecState; + +/*---------------------------------------------------------------* + * LD8A.H * + * ~~~~~~ * + * Function prototypes and constants use for G.729A 8kb/s coder. * + * * + *---------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------* + * Codec constant parameters (coder, decoder, and postfilter) * + *--------------------------------------------------------------------------*/ + +#define L_TOTAL 240 /* Total size of speech buffer. */ +#define L_WINDOW 240 /* Window size in LP analysis. */ +#define L_NEXT 40 /* Lookahead in LP analysis. */ +#define L_FRAME 80 /* Frame size. */ +#define L_SUBFR 40 /* Subframe size. */ +#define M10 (10) /* Order of LP filter. */ +#define MP1 (M10+1) /* Order of LP filter + 1 */ +#define PIT_MIN 20 /* Minimum pitch lag. */ +#define PIT_MAX 143 /* Maximum pitch lag. */ +#define L_INTERPOL (10+1) /* Length of filter for interpolation. */ +#define GAMMA1 24576 /* Bandwitdh factor = 0.75 in Q15 */ + +#define PRM_SIZE 11 /* Size of vector of analysis parameters. */ +#define SERIAL_SIZE (80+2) /* bfi+ number of speech bits */ + +#define SHARPMAX 13017 /* Maximum value of pitch sharpening 0.8 Q14 */ +#define SHARPMIN 3277 /* Minimum value of pitch sharpening 0.2 Q14 */ + + +/*-------------------------------* + * Mathematic functions. * + *-------------------------------*/ + +extern Word32 Inv_sqrt ( /* (o) Q30 : output value (range: 0<=val<1) */ + Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ + ); + +extern void Log2 (Word32 L_x, /* (i) Q0 : input value */ + Word16 * exponent, /* (o) Q0 : Integer part of Log2. (range: 0<=val<=30) */ + Word16 * fraction /* (o) Q15: Fractionnal part of Log2. (range: 0<=val<1) */ + ); + +Word32 Pow2 ( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */ + Word16 exponent, /* (i) Q0 : Integer part. (range: 0<=val<=30) */ + Word16 fraction /* (i) Q15 : Fractionnal part. (range: 0.0<=val<1.0) */ + ); + +/*-------------------------------* + * Pre and post-process. * + *-------------------------------*/ + +extern void Init_Post_Process (DecState *decoder); + +extern void Post_Process (DecState *decoder, + Word16 signal[], /* Input/output signal */ + Word16 lg /* Length of signal */ + ); + +/*-------------------------------* + * LPC analysis and filtering. * + *-------------------------------*/ + +void Autocorr (Word16 x[], /* (i) : Input signal */ + Word16 m, /* (i) : LPC order */ + Word16 r_h[], /* (o) : Autocorrelations (msb) */ + Word16 r_l[] /* (o) : Autocorrelations (lsb) */ + ); + +void Lag_window (Word16 m, /* (i) : LPC order */ + Word16 r_h[], /* (i/o) : Autocorrelations (msb) */ + Word16 r_l[] /* (i/o) : Autocorrelations (lsb) */ + ); + +void Levinson (CodState *coder, + Word16 Rh[], /* (i) : Rh[m+1] Vector of autocorrelations (msb) */ + Word16 Rl[], /* (i) : Rl[m+1] Vector of autocorrelations (lsb) */ + Word16 A[], /* (o) Q12 : A[m] LPC coefficients (m = 10) */ + Word16 rc[] /* (o) Q15 : rc[M] Relection coefficients. */ + ); + +void Az_lsp (Word16 a[], /* (i) Q12 : predictor coefficients */ + Word16 lsp[], /* (o) Q15 : line spectral pairs */ + Word16 old_lsp[] /* (i) : old lsp[] (in case not found 10 roots) */ + ); + +void Lsp_Az (Word16 lsp[], /* (i) Q15 : line spectral frequencies */ + Word16 a[] /* (o) Q12 : predictor coefficients (order = 10) */ + ); + +void Lsf_lsp (Word16 lsf[], /* (i) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */ + Word16 lsp[], /* (o) Q15 : lsp[m] (range: -1<=val<1) */ + Word16 m /* (i) : LPC order */ + ); + +void Lsp_lsf (Word16 lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */ + Word16 lsf[], /* (o) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */ + Word16 m /* (i) : LPC order */ + ); + +void Int_qlpc (Word16 lsp_old[], /* input : LSP vector of past frame */ + Word16 lsp_new[], /* input : LSP vector of present frame */ + Word16 Az[] /* output: interpolated Az() for the 2 subframes */ + ); + +void Weight_Az (Word16 a[], /* (i) Q12 : a[m+1] LPC coefficients */ + Word16 gamma, /* (i) Q15 : Spectral expansion factor. */ + Word16 m, /* (i) : LPC order. */ + Word16 ap[] /* (o) Q12 : Spectral expanded LPC coefficients */ + ); + +void Residu (Word16 a[], /* (i) Q12 : prediction coefficients */ + Word16 x[], /* (i) : speech (values x[-m..-1] are needed (m=10) */ + Word16 y[], /* (o) : residual signal */ + Word16 lg /* (i) : size of filtering */ + ); + +void Syn_filt (Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients (m=10) */ + Word16 x[], /* (i) : input signal */ + Word16 y[], /* (o) : output signal */ + Word16 lg, /* (i) : size of filtering */ + Word16 mem[], /* (i/o) : memory associated with this filtering. */ + Word16 update, /* (i) : 0=no update, 1=update of memory. */ + Flag *Overflow + ); + +void Convolve (Word16 x[], /* (i) : input vector */ + Word16 h[], /* (i) Q12 : impulse response */ + Word16 y[], /* (o) : output vector */ + Word16 L /* (i) : vector size */ + ); + +/*--------------------------------------------------------------------------* + * LTP constant parameters * + *--------------------------------------------------------------------------*/ + +#define UP_SAMP 3 +#define L_INTER10 10 +#define FIR_SIZE_SYN (UP_SAMP*L_INTER10+1) + +/*-----------------------* + * Pitch functions. * + *-----------------------*/ + +Word16 Pitch_ol_fast ( /* output: open loop pitch lag */ + Word16 signal[], /* input : signal used to compute the open loop pitch */ + /* signal[-pit_max] to signal[-1] should be known */ + Word16 pit_max, /* input : maximum pitch lag */ + Word16 L_frame /* input : length of frame to compute pitch */ + ); + +Word16 Pitch_fr3_fast ( /* (o) : pitch period. */ + Word16 exc[], /* (i) : excitation buffer */ + Word16 xn[], /* (i) : target vector */ + Word16 h[], /* (i) Q12 : impulse response of filters. */ + Word16 L_subfr, /* (i) : Length of subframe */ + Word16 t0_min, /* (i) : minimum value in the searched range. */ + Word16 t0_max, /* (i) : maximum value in the searched range. */ + Word16 i_subfr, /* (i) : indicator for first subframe. */ + Word16 * pit_frac /* (o) : chosen fraction. */ + ); + +Word16 G_pitch ( /* (o) Q14 : Gain of pitch lag saturated to 1.2 */ + Word16 xn[], /* (i) : Pitch target. */ + Word16 y1[], /* (i) : Filtered adaptive codebook. */ + Word16 g_coeff[], /* (i) : Correlations need for gain quantization. */ + Word16 L_subfr /* (i) : Length of subframe. */ + ); + +Word16 Enc_lag3 ( /* output: Return index of encoding */ + Word16 T0, /* input : Pitch delay */ + Word16 T0_frac, /* input : Fractional pitch delay */ + Word16 * T0_min, /* in/out: Minimum search delay */ + Word16 * T0_max, /* in/out: Maximum search delay */ + Word16 pit_min, /* input : Minimum pitch delay */ + Word16 pit_max, /* input : Maximum pitch delay */ + Word16 pit_flag /* input : Flag for 1st subframe */ + ); + +void Dec_lag3 ( /* output: return integer pitch lag */ + Word16 index, /* input : received pitch index */ + Word16 pit_min, /* input : minimum pitch lag */ + Word16 pit_max, /* input : maximum pitch lag */ + Word16 i_subfr, /* input : subframe flag */ + Word16 * T0, /* output: integer part of pitch lag */ + Word16 * T0_frac /* output: fractional part of pitch lag */ + ); + +Word16 Interpol_3 ( /* (o) : interpolated value */ + Word16 * x, /* (i) : input vector */ + Word16 frac /* (i) : fraction */ + ); + +void Pred_lt_3 (Word16 exc[], /* in/out: excitation buffer */ + Word16 T0, /* input : integer pitch lag */ + Word16 frac, /* input : fraction of lag */ + Word16 L_subfr /* input : subframe size */ + ); + +extern Word16 Parity_Pitch ( /* output: parity bit (XOR of 6 MSB bits) */ + Word16 pitch_index /* input : index for which parity to compute */ + ); + +extern Word16 Check_Parity_Pitch ( /* output: 0 = no error, 1= error */ + Word16 pitch_index, /* input : index of parameter */ + Word16 parity /* input : parity bit */ + ); + +extern void Cor_h_X (Word16 h[], /* (i) Q12 :Impulse response of filters */ + Word16 X[], /* (i) :Target vector */ + Word16 D[] + /* (o) :Correlations between h[] and D[] */ + /* Normalized to 13 bits */ + ); + +/*-----------------------* + * Innovative codebook. * + *-----------------------*/ + +#define DIM_RR 616 /* size of correlation matrix */ +#define NB_POS 8 /* Number of positions for each pulse */ +#define STEP 5 /* Step betweem position of the same pulse. */ +#define MSIZE 64 /* Size of vectors for cross-correlation between 2 pulses */ + +/* The following constants are Q15 fractions. + These fractions is used to keep maximum precision on "alp" sum */ + +#define _1_2 (Word16)(16384) +#define _1_4 (Word16)( 8192) +#define _1_8 (Word16)( 4096) +#define _1_16 (Word16)( 2048) + +Word16 ACELP_Code_A ( /* (o) :index of pulses positions */ + Word16 x[], /* (i) :Target vector */ + Word16 h[], /* (i) Q12 :Inpulse response of filters */ + Word16 T0, /* (i) :Pitch lag */ + Word16 pitch_sharp, /* (i) Q14 :Last quantized pitch gain */ + Word16 code[], /* (o) Q13 :Innovative codebook */ + Word16 y[], /* (o) Q12 :Filtered innovative codebook */ + Word16 * sign /* (o) :Signs of 4 pulses */ + ); + +void Decod_ACELP (Word16 sign, /* (i) : signs of 4 pulses. */ + Word16 index, /* (i) : Positions of the 4 pulses. */ + Word16 cod[] /* (o) Q13 : algebraic (fixed) codebook excitation */ + ); + +/*--------------------------------------------------------------------------* + * LSP constant parameters * + *--------------------------------------------------------------------------*/ + +#define NC 5 /* NC = M/2 */ +#define MA_NP 4 /* MA prediction order for LSP */ +#define MODE 2 /* number of modes for MA prediction */ +#define NC0_B 7 /* number of first stage bits */ +#define NC1_B 5 /* number of second stage bits */ +#define NC0 (1< mantissa in Q31 plus exponent | + | A[i] Q27 +- 15.999.. | + | | + | The additions are performed in 32 bit. For the summation used | + | to calculate the K[i], we multiply numbers in Q31 by numbers | + | in Q27, with the result of the multiplications in Q27, | + | resulting in a dynamic of +- 16. This is sufficient to avoid | + | overflow, since the final result of the summation is | + | necessarily < 1.0 as both the K[i] and Alpha are | + | theoretically < 1.0. | + |___________________________________________________________________________| +*/ + + +/* Last A(z) for case of unstable filter */ + +void +Levinson (CodState *coder, + Word16 Rh[], /* (i) : Rh[M+1] Vector of autocorrelations (msb) */ + Word16 Rl[], /* (i) : Rl[M+1] Vector of autocorrelations (lsb) */ + Word16 A[], /* (o) Q12 : A[M] LPC coefficients (m = 10) */ + Word16 rc[] /* (o) Q15 : rc[M] Reflection coefficients. */ + ) +{ + Word16 i, j; + Word16 hi, lo; + Word16 Kh, Kl; /* reflection coefficient; hi and lo */ + Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */ + Word16 Ah[M10 + 1], Al[M10 + 1]; /* LPC coef. in double prec. */ + Word16 Anh[M10 + 1], Anl[M10 + 1]; /* LPC coef.for next iteration in double prec. */ + Word32 t0, t1, t2; /* temporary variable */ + + +/* K = A[1] = -R[1] / R[0] */ + + t1 = L_Comp (Rh[1], Rl[1]); /* R[1] in Q31 */ + t2 = L_abs (t1); /* abs R[1] */ + t0 = Div_32 (t2, Rh[0], Rl[0]); /* R[1]/R[0] in Q31 */ + if (t1 > 0) + t0 = L_negate (t0); /* -R[1]/R[0] */ + L_Extract (t0, &Kh, &Kl); /* K in DPF */ + rc[0] = Kh; + t0 = L_shr (t0, 4); /* A[1] in Q27 */ + L_Extract (t0, &Ah[1], &Al[1]); /* A[1] in DPF */ + +/* Alpha = R[0] * (1-K**2) */ + + t0 = Mpy_32 (Kh, Kl, Kh, Kl); /* K*K in Q31 */ + t0 = L_abs (t0); /* Some case <0 !! */ + t0 = L_sub ((Word32) 0x7fffffffL, t0); /* 1 - K*K in Q31 */ + L_Extract (t0, &hi, &lo); /* DPF format */ + t0 = Mpy_32 (Rh[0], Rl[0], hi, lo); /* Alpha in Q31 */ + +/* Normalize Alpha */ + + alp_exp = norm_l (t0); + t0 = L_shl (t0, alp_exp); + L_Extract (t0, &alp_h, &alp_l); /* DPF format */ + +/*--------------------------------------* + * ITERATIONS I=2 to M * + *--------------------------------------*/ + + for (i = 2; i <= M10; i++) { + + /* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] */ + + t0 = 0; + for (j = 1; j < i; j++) + t0 = L_add (t0, Mpy_32 (Rh[j], Rl[j], Ah[i - j], Al[i - j])); + + t0 = L_shl (t0, 4); /* result in Q27 -> convert to Q31 */ + /* No overflow possible */ + t1 = L_Comp (Rh[i], Rl[i]); + t0 = L_add (t0, t1); /* add R[i] in Q31 */ + + /* K = -t0 / Alpha */ + + t1 = L_abs (t0); + t2 = Div_32 (t1, alp_h, alp_l); /* abs(t0)/Alpha */ + if (t0 > 0) + t2 = L_negate (t2); /* K =-t0/Alpha */ + t2 = L_shl (t2, alp_exp); /* denormalize; compare to Alpha */ + L_Extract (t2, &Kh, &Kl); /* K in DPF */ + rc[i - 1] = Kh; + + /* Test for unstable filter. If unstable keep old A(z) */ + + if (sub (abs_s (Kh), 32750) > 0) { + for (j = 0; j <= M10; j++) { + A[j] = coder->old_A[j]; + } + rc[0] = coder->old_rc[0]; /* only two rc coefficients are needed */ + rc[1] = coder->old_rc[1]; + return; + } + + /*------------------------------------------* + * Compute new LPC coeff. -> An[i] * + * An[j]= A[j] + K*A[i-j] , j=1 to i-1 * + * An[i]= K * + *------------------------------------------*/ + + + for (j = 1; j < i; j++) { + t0 = Mpy_32 (Kh, Kl, Ah[i - j], Al[i - j]); + t0 = L_add (t0, L_Comp (Ah[j], Al[j])); + L_Extract (t0, &Anh[j], &Anl[j]); + } + t2 = L_shr (t2, 4); /* t2 = K in Q31 ->convert to Q27 */ + L_Extract (t2, &Anh[i], &Anl[i]); /* An[i] in Q27 */ + + /* Alpha = Alpha * (1-K**2) */ + + t0 = Mpy_32 (Kh, Kl, Kh, Kl); /* K*K in Q31 */ + t0 = L_abs (t0); /* Some case <0 !! */ + t0 = L_sub ((Word32) 0x7fffffffL, t0); /* 1 - K*K in Q31 */ + L_Extract (t0, &hi, &lo); /* DPF format */ + t0 = Mpy_32 (alp_h, alp_l, hi, lo); /* Alpha in Q31 */ + + /* Normalize Alpha */ + + j = norm_l (t0); + t0 = L_shl (t0, j); + L_Extract (t0, &alp_h, &alp_l); /* DPF format */ + alp_exp = add (alp_exp, j); /* Add normalization to alp_exp */ + + /* A[j] = An[j] */ + + for (j = 1; j <= i; j++) { + Ah[j] = Anh[j]; + Al[j] = Anl[j]; + } + } + + /* Truncate A[i] in Q27 to Q12 with rounding */ + + A[0] = 4096; + for (i = 1; i <= M10; i++) { + t0 = L_Comp (Ah[i], Al[i]); + coder->old_A[i] = A[i] = wround (L_shl (t0, 1)); + } + coder->old_rc[0] = rc[0]; + coder->old_rc[1] = rc[1]; + + return; +} + + + +/*-------------------------------------------------------------* + * procedure Az_lsp: * + * ~~~~~~ * + * Compute the LSPs from the LPC coefficients (order=10) * + *-------------------------------------------------------------*/ + +Word16 Chebps_11 (Word16 x, Word16 f[], Word16 n); +Word16 Chebps_10 (Word16 x, Word16 f[], Word16 n); + +void +Az_lsp (Word16 a[], /* (i) Q12 : predictor coefficients */ + Word16 lsp[], /* (o) Q15 : line spectral pairs */ + Word16 old_lsp[] /* (i) : old lsp[] (in case not found 10 roots) */ + ) +{ + Flag Overflow; + Word16 i, j, nf, ip; + Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint; + Word16 x, y, sign, exp; + Word16 *coef; + Word16 f1[M10 / 2 + 1], f2[M10 / 2 + 1]; + Word32 t0, L_temp; + Flag ovf_coef; + Word16 (*pChebps) (Word16 x, Word16 f[], Word16 n); + +/*-------------------------------------------------------------* + * find the sum and diff. pol. F1(z) and F2(z) * + * F1(z) <--- F1(z)/(1+z**-1) & F2(z) <--- F2(z)/(1-z**-1) * + * * + * f1[0] = 1.0; * + * f2[0] = 1.0; * + * * + * for (i = 0; i< NC; i++) * + * { * + * f1[i+1] = a[i+1] + a[M-i] - f1[i] ; * + * f2[i+1] = a[i+1] - a[M-i] + f2[i] ; * + * } * + *-------------------------------------------------------------*/ + + ovf_coef = 0; + pChebps = Chebps_11; + + f1[0] = 2048; /* f1[0] = 1.0 is in Q11 */ + f2[0] = 2048; /* f2[0] = 1.0 is in Q11 */ + + for (i = 0; i < NC; i++) { + Overflow = 0; + t0 = L_mult_o (a[i + 1], 16384, &Overflow); /* x = (a[i+1] + a[M-i]) >> 1 */ + t0 = L_mac_o (t0, a[M10 - i], 16384, &Overflow); /* -> From Q12 to Q11 */ + x = extract_h (t0); + if (Overflow) { + ovf_coef = 1; + } + + Overflow = 0; + f1[i + 1] = sub_o (x, f1[i], &Overflow); /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */ + if (Overflow) { + ovf_coef = 1; + } + + Overflow = 0; + t0 = L_mult_o (a[i + 1], 16384, &Overflow); /* x = (a[i+1] - a[M-i]) >> 1 */ + t0 = L_msu_o (t0, a[M10 - i], 16384, &Overflow); /* -> From Q12 to Q11 */ + x = extract_h (t0); + if (Overflow) { + ovf_coef = 1; + } + + Overflow = 0; + f2[i + 1] = add_o (x, f2[i], &Overflow); /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */ + if (Overflow) { + ovf_coef = 1; + } + } + + if (ovf_coef) { + /*printf("===== OVF ovf_coef =====\n"); */ + + pChebps = Chebps_10; + + f1[0] = 1024; /* f1[0] = 1.0 is in Q10 */ + f2[0] = 1024; /* f2[0] = 1.0 is in Q10 */ + + for (i = 0; i < NC; i++) { + t0 = L_mult (a[i + 1], 8192); /* x = (a[i+1] + a[M-i]) >> 1 */ + t0 = L_mac (t0, a[M10 - i], 8192); /* -> From Q11 to Q10 */ + x = extract_h (t0); + f1[i + 1] = sub (x, f1[i]); /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */ + + t0 = L_mult (a[i + 1], 8192); /* x = (a[i+1] - a[M-i]) >> 1 */ + t0 = L_msu (t0, a[M10 - i], 8192); /* -> From Q11 to Q10 */ + x = extract_h (t0); + f2[i + 1] = add (x, f2[i]); /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */ + } + } + +/*-------------------------------------------------------------* + * find the LSPs using the Chebichev pol. evaluation * + *-------------------------------------------------------------*/ + + nf = 0; /* number of found frequencies */ + ip = 0; /* indicator for f1 or f2 */ + + coef = f1; + + xlow = grid[0]; + ylow = (*pChebps) (xlow, coef, NC); + + j = 0; + while ((nf < M10) && (j < GRID_POINTS)) { + j = add (j, 1); + xhigh = xlow; + yhigh = ylow; + xlow = grid[j]; + ylow = (*pChebps) (xlow, coef, NC); + + L_temp = L_mult (ylow, yhigh); + if (L_temp <= (Word32) 0) { + + /* divide 2 times the interval */ + + for (i = 0; i < 2; i++) { + xmid = add (shr (xlow, 1), shr (xhigh, 1)); /* xmid = (xlow + xhigh)/2 */ + + ymid = (*pChebps) (xmid, coef, NC); + + L_temp = L_mult (ylow, ymid); + if (L_temp <= (Word32) 0) { + yhigh = ymid; + xhigh = xmid; + } + else { + ylow = ymid; + xlow = xmid; + } + } + + /*-------------------------------------------------------------* + * Linear interpolation * + * xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow); * + *-------------------------------------------------------------*/ + + x = sub (xhigh, xlow); + y = sub (yhigh, ylow); + + if (y == 0) { + xint = xlow; + } + else { + sign = y; + y = abs_s (y); + exp = norm_s (y); + y = shl (y, exp); + y = div_s ((Word16) 16383, y); + t0 = L_mult (x, y); + t0 = L_shr (t0, sub (20, exp)); + y = extract_l (t0); /* y= (xhigh-xlow)/(yhigh-ylow) in Q11 */ + + if (sign < 0) + y = negate (y); + + t0 = L_mult (ylow, y); /* result in Q26 */ + t0 = L_shr (t0, 11); /* result in Q15 */ + xint = sub (xlow, extract_l (t0)); /* xint = xlow - ylow*y */ + } + + lsp[nf] = xint; + xlow = xint; + nf = add (nf, 1); + + if (ip == 0) { + ip = 1; + coef = f2; + } + else { + ip = 0; + coef = f1; + } + ylow = (*pChebps) (xlow, coef, NC); + + } + } + + /* Check if M roots found */ + + if (sub (nf, M10) < 0) { + for (i = 0; i < M10; i++) { + lsp[i] = old_lsp[i]; + } + + /* printf("\n !!Not 10 roots found in Az_lsp()!!!\n"); */ + } + + return; +} + +/*--------------------------------------------------------------* + * function Chebps_11, Chebps_10: * + * ~~~~~~~~~~~~~~~~~~~~ * + * Evaluates the Chebichev polynomial series * + *--------------------------------------------------------------* + * * + * The polynomial order is * + * n = M/2 (M is the prediction order) * + * The polynomial is given by * + * C(x) = T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2 * + * Arguments: * + * x: input value of evaluation; x = cos(frequency) in Q15 * + * f[]: coefficients of the pol. * + * in Q11(Chebps_11), in Q10(Chebps_10) * + * n: order of the pol. * + * * + * The value of C(x) is returned. (Saturated to +-1.99 in Q14) * + * * + *--------------------------------------------------------------*/ +Word16 +Chebps_11 (Word16 x, Word16 f[], Word16 n) +{ + Word16 i, cheb; + Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l; + Word32 t0; + + /* Note: All computation are done in Q24. */ + + b2_h = 256; /* b2 = 1.0 in Q24 DPF */ + b2_l = 0; + + t0 = L_mult (x, 512); /* 2*x in Q24 */ + t0 = L_mac (t0, f[1], 4096); /* + f[1] in Q24 */ + L_Extract (t0, &b1_h, &b1_l); /* b1 = 2*x + f[1] */ + + for (i = 2; i < n; i++) { + t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = 2.0*x*b1 */ + t0 = L_shl (t0, 1); + t0 = L_mac (t0, b2_h, (Word16) - 32768L); /* t0 = 2.0*x*b1 - b2 */ + t0 = L_msu (t0, b2_l, 1); + t0 = L_mac (t0, f[i], 4096); /* t0 = 2.0*x*b1 - b2 + f[i]; */ + + L_Extract (t0, &b0_h, &b0_l); /* b0 = 2.0*x*b1 - b2 + f[i]; */ + + b2_l = b1_l; /* b2 = b1; */ + b2_h = b1_h; + b1_l = b0_l; /* b1 = b0; */ + b1_h = b0_h; + } + + t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = x*b1; */ + t0 = L_mac (t0, b2_h, (Word16) - 32768L); /* t0 = x*b1 - b2 */ + t0 = L_msu (t0, b2_l, 1); + t0 = L_mac (t0, f[i], 2048); /* t0 = x*b1 - b2 + f[i]/2 */ + + t0 = L_shl (t0, 6); /* Q24 to Q30 with saturation */ + cheb = extract_h (t0); /* Result in Q14 */ + + + return (cheb); +} + + +Word16 +Chebps_10 (Word16 x, Word16 f[], Word16 n) +{ + Word16 i, cheb; + Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l; + Word32 t0; + + /* Note: All computation are done in Q23. */ + + b2_h = 128; /* b2 = 1.0 in Q23 DPF */ + b2_l = 0; + + t0 = L_mult (x, 256); /* 2*x in Q23 */ + t0 = L_mac (t0, f[1], 4096); /* + f[1] in Q23 */ + L_Extract (t0, &b1_h, &b1_l); /* b1 = 2*x + f[1] */ + + for (i = 2; i < n; i++) { + t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = 2.0*x*b1 */ + t0 = L_shl (t0, 1); + t0 = L_mac (t0, b2_h, (Word16) - 32768L); /* t0 = 2.0*x*b1 - b2 */ + t0 = L_msu (t0, b2_l, 1); + t0 = L_mac (t0, f[i], 4096); /* t0 = 2.0*x*b1 - b2 + f[i]; */ + + L_Extract (t0, &b0_h, &b0_l); /* b0 = 2.0*x*b1 - b2 + f[i]; */ + + b2_l = b1_l; /* b2 = b1; */ + b2_h = b1_h; + b1_l = b0_l; /* b1 = b0; */ + b1_h = b0_h; + } + + t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = x*b1; */ + t0 = L_mac (t0, b2_h, (Word16) - 32768L); /* t0 = x*b1 - b2 */ + t0 = L_msu (t0, b2_l, 1); + t0 = L_mac (t0, f[i], 2048); /* t0 = x*b1 - b2 + f[i]/2 */ + + t0 = L_shl (t0, 7); /* Q23 to Q30 with saturation */ + cheb = extract_h (t0); /* Result in Q14 */ + + + return (cheb); +} diff --git a/src/libs/libg729/g729_lpcfunc.cpp b/src/libs/libg729/g729_lpcfunc.cpp new file mode 100644 index 00000000..e5f72bc6 --- /dev/null +++ b/src/libs/libg729/g729_lpcfunc.cpp @@ -0,0 +1,300 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------------------------------------* + * Procedure Lsp_Az: * + * ~~~~~~ * + * Compute the LPC coefficients from lsp (order=10) * + *-------------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_oper_32b.h" + +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" + +/* local function */ + +void Get_lsp_pol (Word16 * lsp, Word32 * f); + +void +Lsp_Az (Word16 lsp[], /* (i) Q15 : line spectral frequencies */ + Word16 a[] /* (o) Q12 : predictor coefficients (order = 10) */ + ) +{ + Word16 i, j; + Word32 f1[6], f2[6]; + Word32 t0; + + Get_lsp_pol (&lsp[0], f1); + Get_lsp_pol (&lsp[1], f2); + + for (i = 5; i > 0; i--) { + f1[i] = L_add (f1[i], f1[i - 1]); /* f1[i] += f1[i-1]; */ + f2[i] = L_sub (f2[i], f2[i - 1]); /* f2[i] -= f2[i-1]; */ + } + + a[0] = 4096; + for (i = 1, j = 10; i <= 5; i++, j--) { + t0 = L_add (f1[i], f2[i]); /* f1[i] + f2[i] */ + a[i] = extract_l (L_shr_r (t0, 13)); /* from Q24 to Q12 and * 0.5 */ + + t0 = L_sub (f1[i], f2[i]); /* f1[i] - f2[i] */ + a[j] = extract_l (L_shr_r (t0, 13)); /* from Q24 to Q12 and * 0.5 */ + + } + + return; +} + +/*-----------------------------------------------------------* + * procedure Get_lsp_pol: * + * ~~~~~~~~~~~ * + * Find the polynomial F1(z) or F2(z) from the LSPs * + *-----------------------------------------------------------* + * * + * Parameters: * + * lsp[] : line spectral freq. (cosine domain) in Q15 * + * f[] : the coefficients of F1 or F2 in Q24 * + *-----------------------------------------------------------*/ + +void +Get_lsp_pol (Word16 * lsp, Word32 * f) +{ + Word16 i, j, hi, lo; + Word32 t0; + + /* All computation in Q24 */ + + *f = L_mult (4096, 2048); /* f[0] = 1.0; in Q24 */ + f++; + *f = L_msu ((Word32) 0, *lsp, 512); /* f[1] = -2.0 * lsp[0]; in Q24 */ + + f++; + lsp += 2; /* Advance lsp pointer */ + + for (i = 2; i <= 5; i++) { + *f = f[-2]; + + for (j = 1; j < i; j++, f--) { + L_Extract (f[-1], &hi, &lo); + t0 = Mpy_32_16 (hi, lo, *lsp); /* t0 = f[-1] * lsp */ + t0 = L_shl (t0, 1); + *f = L_add (*f, f[-2]); /* *f += f[-2] */ + *f = L_sub (*f, t0); /* *f -= t0 */ + } + *f = L_msu (*f, *lsp, 512); /* *f -= lsp<<9 */ + f += i; /* Advance f pointer */ + lsp += 2; /* Advance lsp pointer */ + } + + return; +} + +/*___________________________________________________________________________ + | | + | Functions : Lsp_lsf and Lsf_lsp | + | | + | Lsp_lsf Transformation lsp to lsf | + | Lsf_lsp Transformation lsf to lsp | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The transformation from lsp[i] to lsf[i] and lsf[i] to lsp[i] are | + | approximated by a look-up table and interpolation. | + |___________________________________________________________________________| +*/ + + +void +Lsf_lsp (Word16 lsf[], /* (i) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */ + Word16 lsp[], /* (o) Q15 : lsp[m] (range: -1<=val<1) */ + Word16 m /* (i) : LPC order */ + ) +{ + Word16 i, ind, offset; + Word32 L_tmp; + + for (i = 0; i < m; i++) { + ind = shr (lsf[i], 8); /* ind = b8-b15 of lsf[i] */ + offset = lsf[i] & (Word16) 0x00ff; /* offset = b0-b7 of lsf[i] */ + + /* lsp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 256 */ + + L_tmp = L_mult (sub (table[ind + 1], table[ind]), offset); + lsp[i] = add (table[ind], extract_l (L_shr (L_tmp, 9))); + } + return; +} + + +void +Lsp_lsf (Word16 lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */ + Word16 lsf[], /* (o) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */ + Word16 m /* (i) : LPC order */ + ) +{ + Word16 i, ind, tmp; + Word32 L_tmp; + + ind = 63; /* begin at end of table -1 */ + + for (i = m - (Word16) 1; i >= 0; i--) { + /* find value in table that is just greater than lsp[i] */ + while (sub (table[ind], lsp[i]) < 0) { + ind = sub (ind, 1); + } + + /* acos(lsp[i])= ind*256 + ( ( lsp[i]-table[ind] ) * slope[ind] )/4096 */ + + L_tmp = L_mult (sub (lsp[i], table[ind]), slope[ind]); + tmp = wround (L_shl (L_tmp, 3)); /*(lsp[i]-table[ind])*slope[ind])>>12 */ + lsf[i] = add (tmp, shl (ind, 8)); + } + return; +} + +/*___________________________________________________________________________ + | | + | Functions : Lsp_lsf and Lsf_lsp | + | | + | Lsp_lsf Transformation lsp to lsf | + | Lsf_lsp Transformation lsf to lsp | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The transformation from lsp[i] to lsf[i] and lsf[i] to lsp[i] are | + | approximated by a look-up table and interpolation. | + |___________________________________________________________________________| +*/ + +void +Lsf_lsp2 (Word16 lsf[], /* (i) Q13 : lsf[m] (range: 0.0<=val 0) { + ind = 63; /* 0 <= ind <= 63 */ + } + + /* lsp[i] = table2[ind]+ (slope_cos[ind]*offset >> 12) */ + + L_tmp = L_mult (slope_cos[ind], offset); /* L_tmp in Q28 */ + lsp[i] = add (table2[ind], extract_l (L_shr (L_tmp, 13))); + + } + return; +} + + + +void +Lsp_lsf2 (Word16 lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */ + Word16 lsf[], /* (o) Q13 : lsf[m] (range: 0.0<=val= 0; i--) { + /* find value in table2 that is just greater than lsp[i] */ + while (sub (table2[ind], lsp[i]) < 0) { + ind = sub (ind, 1); + if (ind <= 0) + break; + } + + offset = sub (lsp[i], table2[ind]); + + /* acos(lsp[i])= ind*512 + (slope_acos[ind]*offset >> 11) */ + + L_tmp = L_mult (slope_acos[ind], offset); /* L_tmp in Q28 */ + freq = add (shl (ind, 9), extract_l (L_shr (L_tmp, 12))); + lsf[i] = mult (freq, 25736); /* 25736: 2.0*PI in Q12 */ + + } + return; +} + +/*-------------------------------------------------------------* + * procedure Weight_Az * + * ~~~~~~~~~ * + * Weighting of LPC coefficients. * + * ap[i] = a[i] * (gamma ** i) * + * * + *-------------------------------------------------------------*/ + + +void +Weight_Az (Word16 a[], /* (i) Q12 : a[m+1] LPC coefficients */ + Word16 gamma, /* (i) Q15 : Spectral expansion factor. */ + Word16 m, /* (i) : LPC order. */ + Word16 ap[] /* (o) Q12 : Spectral expanded LPC coefficients */ + ) +{ + Word16 i, fac; + + ap[0] = a[0]; + fac = gamma; + for (i = 1; i < m; i++) { + ap[i] = wround (L_mult (a[i], fac)); + fac = wround (L_mult (fac, gamma)); + } + ap[m] = wround (L_mult (a[m], fac)); + + return; +} + +/*----------------------------------------------------------------------* + * Function Int_qlpc() * + * ~~~~~~~~~~~~~~~~~~~ * + * Interpolation of the LPC parameters. * + *----------------------------------------------------------------------*/ + +/* Interpolation of the quantized LSP's */ + +void +Int_qlpc (Word16 lsp_old[], /* input : LSP vector of past frame */ + Word16 lsp_new[], /* input : LSP vector of present frame */ + Word16 Az[] /* output: interpolated Az() for the 2 subframes */ + ) +{ + Word16 i; + Word16 lsp[M10]; + + /* lsp[i] = lsp_new[i] * 0.5 + lsp_old[i] * 0.5 */ + + for (i = 0; i < M10; i++) { + lsp[i] = add (shr (lsp_new[i], 1), shr (lsp_old[i], 1)); + } + + Lsp_Az (lsp, Az); /* Subframe 1 */ + + Lsp_Az (lsp_new, &Az[MP1]); /* Subframe 2 */ + + return; +} diff --git a/src/libs/libg729/g729_lpcfunc.h b/src/libs/libg729/g729_lpcfunc.h new file mode 100644 index 00000000..60a2bc37 --- /dev/null +++ b/src/libs/libg729/g729_lpcfunc.h @@ -0,0 +1,18 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +void Lsf_lsp2 (Word16 lsf[], /* (i) Q13 : lsf[m] (range: 0.0<=valfreq_prev[i][0], M10); +} + + +void +Lsp_qua_cs (CodState *coder, + Word16 flsp_in[M10], /* (i) Q13 : Original LSP parameters */ + Word16 lspq_out[M10], /* (o) Q13 : Quantized LSP parameters */ + Word16 * code /* (o) : codes of the selected LSP */ + ) +{ + Word16 wegt[M10]; /* Q11->normalized : weighting coefficients */ + + Get_wegt (flsp_in, wegt); + + Relspwed (flsp_in, wegt, lspq_out, lspcb1, lspcb2, fg, + coder->freq_prev, fg_sum, fg_sum_inv, code); +} + +void +Relspwed (Word16 lsp[], /* (i) Q13 : unquantized LSP parameters */ + Word16 wegt[], /* (i) norm: weighting coefficients */ + Word16 lspq[], /* (o) Q13 : quantized LSP parameters */ + Word16 lspcb1[][M10], /* (i) Q13 : first stage LSP codebook */ + Word16 lspcb2[][M10], /* (i) Q13 : Second stage LSP codebook */ + Word16 fg[MODE][MA_NP][M10], /* (i) Q15 : MA prediction coefficients */ + Word16 freq_prev[MA_NP][M10], /* (i) Q13 : previous LSP vector */ + Word16 fg_sum[MODE][M10], /* (i) Q15 : present MA prediction coef. */ + Word16 fg_sum_inv[MODE][M10], /* (i) Q12 : inverse coef. */ + Word16 code_ana[] /* (o) : codes of the selected LSP */ + ) +{ + Word16 mode, j; + Word16 index, mode_index; + Word16 cand[MODE], cand_cur; + Word16 tindex1[MODE], tindex2[MODE]; + Word32 L_tdist[MODE]; /* Q26 */ + Word16 rbuf[M10]; /* Q13 */ + Word16 buf[M10]; /* Q13 */ + + for (mode = 0; mode < MODE; mode++) { + Lsp_prev_extract (lsp, rbuf, fg[mode], freq_prev, fg_sum_inv[mode]); + + Lsp_pre_select (rbuf, lspcb1, &cand_cur); + cand[mode] = cand_cur; + + Lsp_select_1 (rbuf, lspcb1[cand_cur], wegt, lspcb2, &index); + + tindex1[mode] = index; + + for (j = 0; j < NC; j++) + buf[j] = add (lspcb1[cand_cur][j], lspcb2[index][j]); + + Lsp_expand_1 (buf, GAP1); + + Lsp_select_2 (rbuf, lspcb1[cand_cur], wegt, lspcb2, &index); + + tindex2[mode] = index; + + for (j = NC; j < M10; j++) + buf[j] = add (lspcb1[cand_cur][j], lspcb2[index][j]); + + Lsp_expand_2 (buf, GAP1); + + Lsp_expand_1_2 (buf, GAP2); + + Lsp_get_tdist (wegt, buf, &L_tdist[mode], rbuf, fg_sum[mode]); + } + + Lsp_last_select (L_tdist, &mode_index); + + code_ana[0] = shl (mode_index, NC0_B) | cand[mode_index]; + code_ana[1] = shl (tindex1[mode_index], NC1_B) | tindex2[mode_index]; + + Lsp_get_quant (lspcb1, lspcb2, cand[mode_index], + tindex1[mode_index], tindex2[mode_index], + fg[mode_index], freq_prev, lspq, fg_sum[mode_index]); + + return; +} + + +void +Lsp_pre_select (Word16 rbuf[], /* (i) Q13 : target vetor */ + Word16 lspcb1[][M10], /* (i) Q13 : first stage LSP codebook */ + Word16 * cand /* (o) : selected code */ + ) +{ + Word16 i, j; + Word16 tmp; /* Q13 */ + Word32 L_dmin; /* Q26 */ + Word32 L_tmp; /* Q26 */ + Word32 L_temp; + + /* avoid the worst case. (all over flow) */ + + *cand = 0; + L_dmin = MAX_32; + for (i = 0; i < NC0; i++) { + L_tmp = 0; + for (j = 0; j < M10; j++) { + tmp = sub (rbuf[j], lspcb1[i][j]); + L_tmp = L_mac (L_tmp, tmp, tmp); + } + + L_temp = L_sub (L_tmp, L_dmin); + if (L_temp < 0L) { + L_dmin = L_tmp; + *cand = i; + } + } + return; +} + + + +void +Lsp_select_1 (Word16 rbuf[], /* (i) Q13 : target vector */ + Word16 lspcb1[], /* (i) Q13 : first stage lsp codebook */ + Word16 wegt[], /* (i) norm: weighting coefficients */ + Word16 lspcb2[][M10], /* (i) Q13 : second stage lsp codebook */ + Word16 * index /* (o) : selected codebook index */ + ) +{ + Word16 j, k1; + Word16 buf[M10]; /* Q13 */ + Word32 L_dist; /* Q26 */ + Word32 L_dmin; /* Q26 */ + Word16 tmp, tmp2; /* Q13 */ + Word32 L_temp; + + for (j = 0; j < NC; j++) + buf[j] = sub (rbuf[j], lspcb1[j]); + + /* avoid the worst case. (all over flow) */ + *index = 0; + L_dmin = MAX_32; + for (k1 = 0; k1 < NC1; k1++) { + L_dist = 0; + for (j = 0; j < NC; j++) { + tmp = sub (buf[j], lspcb2[k1][j]); + tmp2 = mult (wegt[j], tmp); + L_dist = L_mac (L_dist, tmp2, tmp); + } + + L_temp = L_sub (L_dist, L_dmin); + if (L_temp < 0L) { + L_dmin = L_dist; + *index = k1; + } + } + return; +} + + + +void +Lsp_select_2 (Word16 rbuf[], /* (i) Q13 : target vector */ + Word16 lspcb1[], /* (i) Q13 : first stage lsp codebook */ + Word16 wegt[], /* (i) norm: weighting coef. */ + Word16 lspcb2[][M10], /* (i) Q13 : second stage lsp codebook */ + Word16 * index /* (o) : selected codebook index */ + ) +{ + Word16 j, k1; + Word16 buf[M10]; /* Q13 */ + Word32 L_dist; /* Q26 */ + Word32 L_dmin; /* Q26 */ + Word16 tmp, tmp2; /* Q13 */ + Word32 L_temp; + + for (j = NC; j < M10; j++) + buf[j] = sub (rbuf[j], lspcb1[j]); + + /* avoid the worst case. (all over flow) */ + *index = 0; + L_dmin = MAX_32; + for (k1 = 0; k1 < NC1; k1++) { + L_dist = 0; + for (j = NC; j < M10; j++) { + tmp = sub (buf[j], lspcb2[k1][j]); + tmp2 = mult (wegt[j], tmp); + L_dist = L_mac (L_dist, tmp2, tmp); + } + + L_temp = L_sub (L_dist, L_dmin); + if (L_temp < 0L) { + L_dmin = L_dist; + *index = k1; + } + } + return; +} + + + +void +Lsp_get_tdist (Word16 wegt[], /* (i) norm: weight coef. */ + Word16 buf[], /* (i) Q13 : candidate LSP vector */ + Word32 * L_tdist, /* (o) Q27 : distortion */ + Word16 rbuf[], /* (i) Q13 : target vector */ + Word16 fg_sum[] /* (i) Q15 : present MA prediction coef. */ + ) +{ + Word16 j; + Word16 tmp, tmp2; /* Q13 */ + Word32 L_acc; /* Q25 */ + + *L_tdist = 0; + for (j = 0; j < M10; j++) { + /* tmp = (buf - rbuf)*fg_sum */ + tmp = sub (buf[j], rbuf[j]); + tmp = mult (tmp, fg_sum[j]); + + /* *L_tdist += wegt * tmp * tmp */ + L_acc = L_mult (wegt[j], tmp); + tmp2 = extract_h (L_shl (L_acc, 4)); + *L_tdist = L_mac (*L_tdist, tmp2, tmp); + } + + return; +} + + + +void +Lsp_last_select (Word32 L_tdist[], /* (i) Q27 : distortion */ + Word16 * mode_index /* (o) : the selected mode */ + ) +{ + Word32 L_temp; + *mode_index = 0; + L_temp = L_sub (L_tdist[1], L_tdist[0]); + if (L_temp < 0L) { + *mode_index = 1; + } + return; +} + +void +Get_wegt (Word16 flsp[], /* (i) Q13 : M LSP parameters */ + Word16 wegt[] /* (o) Q11->norm : M weighting coefficients */ + ) +{ + Word16 i; + Word16 tmp; + Word32 L_acc; + Word16 sft; + Word16 buf[M10]; /* in Q13 */ + + + buf[0] = sub (flsp[1], (PI04 + 8192)); /* 8192:1.0(Q13) */ + + for (i = 1; i < M10 - 1; i++) { + tmp = sub (flsp[i + 1], flsp[i - 1]); + buf[i] = sub (tmp, 8192); + } + + buf[M10 - 1] = sub ((PI92 - 8192), flsp[M10 - 2]); + + /* */ + for (i = 0; i < M10; i++) { + if (buf[i] > 0) { + wegt[i] = 2048; /* 2048:1.0(Q11) */ + } + else { + L_acc = L_mult (buf[i], buf[i]); /* L_acc in Q27 */ + tmp = extract_h (L_shl (L_acc, 2)); /* tmp in Q13 */ + + L_acc = L_mult (tmp, CONST10); /* L_acc in Q25 */ + tmp = extract_h (L_shl (L_acc, 2)); /* tmp in Q11 */ + + wegt[i] = add (tmp, 2048); /* wegt in Q11 */ + } + } + + /* */ + L_acc = L_mult (wegt[4], CONST12); /* L_acc in Q26 */ + wegt[4] = extract_h (L_shl (L_acc, 1)); /* wegt in Q11 */ + + L_acc = L_mult (wegt[5], CONST12); /* L_acc in Q26 */ + wegt[5] = extract_h (L_shl (L_acc, 1)); /* wegt in Q11 */ + + /* wegt: Q11 -> normalized */ + tmp = 0; + for (i = 0; i < M10; i++) { + if (sub (wegt[i], tmp) > 0) { + tmp = wegt[i]; + } + } + + sft = norm_s (tmp); + for (i = 0; i < M10; i++) { + wegt[i] = shl (wegt[i], sft); /* wegt in Q(11+sft) */ + } + + return; +} diff --git a/src/libs/libg729/g729_lsp.h b/src/libs/libg729/g729_lsp.h new file mode 100644 index 00000000..81b0cf28 --- /dev/null +++ b/src/libs/libg729/g729_lsp.h @@ -0,0 +1,67 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------* + * LSP VQ functions. * + *-------------------------------*/ + +void Lsp_qua_cs (CodState *coder, + Word16 flsp_in[M10], /* Q13 */ + Word16 lspq_out[M10], /* Q13 */ + Word16 * code); + +void Lsp_get_tdist (Word16 wegt[], /* normalized */ + Word16 buf[], /* Q13 */ + Word32 * L_tdist, /* Q27 */ + Word16 rbuf[], /* Q13 */ + Word16 fg_sum[] /* Q15 */ + ); + +void Lsp_last_select (Word32 L_tdist[], /* Q27 */ + Word16 * mode_index); + +void Lsp_pre_select (Word16 rbuf[], /* Q13 */ + Word16 lspcb1[][M10], /* Q13 */ + Word16 * cand); + +void Lsp_select_1 (Word16 rbuf[], /* Q13 */ + Word16 lspcb1[], /* Q13 */ + Word16 wegt[], /* normalized */ + Word16 lspcb2[][M10], /* Q13 */ + Word16 * index); + +void Lsp_select_2 (Word16 rbuf[], /* Q13 */ + Word16 lspcb1[], /* Q13 */ + Word16 wegt[], /* normalized */ + Word16 lspcb2[][M10], /* Q13 */ + Word16 * index); + +void Relspwed (Word16 lsp[], /* Q13 */ + Word16 wegt[], /* normalized */ + Word16 lspq[], /* Q13 */ + Word16 lspcb1[][M10], /* Q13 */ + Word16 lspcb2[][M10], /* Q13 */ + Word16 fg[MODE][MA_NP][M10], /* Q15 */ + Word16 freq_prev[MA_NP][M10], /* Q13 */ + Word16 fg_sum[MODE][M10], /* Q15 */ + Word16 fg_sum_inv[MODE][M10], /* Q12 */ + Word16 code_ana[] + ); + +void Qua_lsp (CodState *coder, + Word16 lsp[], /* (i) Q15 : Unquantized LSP */ + Word16 lsp_q[], /* (o) Q15 : Quantized LSP */ + Word16 ana[] /* (o) : indexes */ + ); + +void Get_wegt (Word16 flsp[], /* Q13 */ + Word16 wegt[] /* Q11 -> normalized */ + ); + +void Lsp_encw_reset (CodState *coder); diff --git a/src/libs/libg729/g729_lspdec.cpp b/src/libs/libg729/g729_lspdec.cpp new file mode 100644 index 00000000..5c540b38 --- /dev/null +++ b/src/libs/libg729/g729_lspdec.cpp @@ -0,0 +1,110 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "g729_typedef.h" +#include "g729_ld8a.h" +#include "g729_basic_op.h" +#include "g729_tab_ld8a.h" +#include "g729_util.h" +#include "g729_lspgetq.h" +#include "g729_lpcfunc.h" + + +/*---------------------------------------------------------------------------- + * Lsp_decw_reset - set the previous LSP vectors + *---------------------------------------------------------------------------- + */ +void +Lsp_decw_reset (DecState *decoder) +{ + Word16 i; + + for (i = 0; i < MA_NP; i++) + Copy (&freq_prev_reset[0], &decoder->freq_prev[i][0], M10); + + decoder->prev_ma = 0; + + Copy (freq_prev_reset, decoder->prev_lsp, M10); +} + + + +/*---------------------------------------------------------------------------- + * Lsp_iqua_cs - LSP main quantization routine + *---------------------------------------------------------------------------- + */ +void +Lsp_iqua_cs (DecState *decoder, + Word16 prm[], /* (i) : indexes of the selected LSP */ + Word16 lsp_q[], /* (o) Q13 : Quantized LSP parameters */ + Word16 erase /* (i) : frame erase information */ + ) +{ + Word16 mode_index; + Word16 code0; + Word16 code1; + Word16 code2; + Word16 buf[M10]; /* Q13 */ + + if (erase == 0) { /* Not frame erasure */ + mode_index = shr (prm[0], NC0_B) & (Word16) 1; + code0 = prm[0] & (Word16) (NC0 - 1); + code1 = shr (prm[1], NC1_B) & (Word16) (NC1 - 1); + code2 = prm[1] & (Word16) (NC1 - 1); + + /* compose quantized LSP (lsp_q) from indexes */ + + Lsp_get_quant (lspcb1, lspcb2, code0, code1, code2, + fg[mode_index], decoder->freq_prev, lsp_q, fg_sum[mode_index]); + + /* save parameters to use in case of the frame erased situation */ + + Copy (lsp_q, decoder->prev_lsp, M10); + decoder->prev_ma = mode_index; + } + else { /* Frame erased */ + /* use revious LSP */ + + Copy (decoder->prev_lsp, lsp_q, M10); + + /* update freq_prev */ + + Lsp_prev_extract (decoder->prev_lsp, buf, + fg[decoder->prev_ma], decoder->freq_prev, fg_sum_inv[decoder->prev_ma]); + Lsp_prev_update (buf, decoder->freq_prev); + } + + return; +} + + + +/*-------------------------------------------------------------------* + * Function D_lsp: * + * ~~~~~~ * + *-------------------------------------------------------------------*/ + +void +D_lsp (DecState *decoder, + Word16 prm[], /* (i) : indexes of the selected LSP */ + Word16 lsp_q[], /* (o) Q15 : Quantized LSP parameters */ + Word16 erase /* (i) : frame erase information */ + ) +{ + Word16 lsf_q[M10]; /* domain 0.0<= lsf_q +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" +#include "g729_util.h" +#include "g729_lspgetq.h" + + +void +Lsp_get_quant (Word16 lspcb1[][M10], /* (i) Q13 : first stage LSP codebook */ + Word16 lspcb2[][M10], /* (i) Q13 : Second stage LSP codebook */ + Word16 code0, /* (i) : selected code of first stage */ + Word16 code1, /* (i) : selected code of second stage */ + Word16 code2, /* (i) : selected code of second stage */ + Word16 fg[][M10], /* (i) Q15 : MA prediction coef. */ + Word16 freq_prev[][M10], /* (i) Q13 : previous LSP vector */ + Word16 lspq[], /* (o) Q13 : quantized LSP parameters */ + Word16 fg_sum[] /* (i) Q15 : present MA prediction coef. */ + ) +{ + Word16 j; + Word16 buf[M10]; /* Q13 */ + + + for (j = 0; j < NC; j++) + buf[j] = add (lspcb1[code0][j], lspcb2[code1][j]); + + for (j = NC; j < M10; j++) + buf[j] = add (lspcb1[code0][j], lspcb2[code2][j]); + + Lsp_expand_1_2 (buf, GAP1); + Lsp_expand_1_2 (buf, GAP2); + + Lsp_prev_compose (buf, lspq, fg, freq_prev, fg_sum); + + Lsp_prev_update (buf, freq_prev); + + Lsp_stability (lspq); + + return; +} + + +void +Lsp_expand_1 (Word16 buf[], /* (i/o) Q13 : LSP vectors */ + Word16 gap /* (i) Q13 : gap */ + ) +{ + Word16 j, tmp; + Word16 diff; /* Q13 */ + + for (j = 1; j < NC; j++) { + diff = sub (buf[j - 1], buf[j]); + tmp = shr (add (diff, gap), 1); + + if (tmp > 0) { + buf[j - 1] = sub (buf[j - 1], tmp); + buf[j] = add (buf[j], tmp); + } + } + return; +} + + +void +Lsp_expand_2 (Word16 buf[], /* (i/o) Q13 : LSP vectors */ + Word16 gap /* (i) Q13 : gap */ + ) +{ + Word16 j, tmp; + Word16 diff; /* Q13 */ + + for (j = NC; j < M10; j++) { + diff = sub (buf[j - 1], buf[j]); + tmp = shr (add (diff, gap), 1); + + if (tmp > 0) { + buf[j - 1] = sub (buf[j - 1], tmp); + buf[j] = add (buf[j], tmp); + } + } + return; +} + + +void +Lsp_expand_1_2 (Word16 buf[], /* (i/o) Q13 : LSP vectors */ + Word16 gap /* (i) Q13 : gap */ + ) +{ + Word16 j, tmp; + Word16 diff; /* Q13 */ + + for (j = 1; j < M10; j++) { + diff = sub (buf[j - 1], buf[j]); + tmp = shr (add (diff, gap), 1); + + if (tmp > 0) { + buf[j - 1] = sub (buf[j - 1], tmp); + buf[j] = add (buf[j], tmp); + } + } + return; +} + + +/* + Functions which use previous LSP parameter (freq_prev). +*/ + + +/* + compose LSP parameter from elementary LSP with previous LSP. +*/ +void +Lsp_prev_compose (Word16 lsp_ele[], /* (i) Q13 : LSP vectors */ + Word16 lsp[], /* (o) Q13 : quantized LSP parameters */ + Word16 fg[][M10], /* (i) Q15 : MA prediction coef. */ + Word16 freq_prev[][M10], /* (i) Q13 : previous LSP vector */ + Word16 fg_sum[] /* (i) Q15 : present MA prediction coef. */ + ) +{ + Word16 j, k; + Word32 L_acc; /* Q29 */ + + for (j = 0; j < M10; j++) { + L_acc = L_mult (lsp_ele[j], fg_sum[j]); + for (k = 0; k < MA_NP; k++) + L_acc = L_mac (L_acc, freq_prev[k][j], fg[k][j]); + + lsp[j] = extract_h (L_acc); + } + return; +} + + +/* + extract elementary LSP from composed LSP with previous LSP +*/ +void +Lsp_prev_extract (Word16 lsp[M10], /* (i) Q13 : unquantized LSP parameters */ + Word16 lsp_ele[M10], /* (o) Q13 : target vector */ + Word16 fg[MA_NP][M10], /* (i) Q15 : MA prediction coef. */ + Word16 freq_prev[MA_NP][M10], /* (i) Q13 : previous LSP vector */ + Word16 fg_sum_inv[M10] /* (i) Q12 : inverse previous LSP vector */ + ) +{ + Word16 j, k; + Word32 L_temp; /* Q19 */ + Word16 temp; /* Q13 */ + + + for (j = 0; j < M10; j++) { + L_temp = L_deposit_h (lsp[j]); + for (k = 0; k < MA_NP; k++) + L_temp = L_msu (L_temp, freq_prev[k][j], fg[k][j]); + + temp = extract_h (L_temp); + L_temp = L_mult (temp, fg_sum_inv[j]); + lsp_ele[j] = extract_h (L_shl (L_temp, 3)); + + } + return; +} + + +/* + update previous LSP parameter +*/ +void +Lsp_prev_update (Word16 lsp_ele[M10], /* (i) Q13 : LSP vectors */ + Word16 freq_prev[MA_NP][M10] /* (i/o) Q13 : previous LSP vectors */ + ) +{ + Word16 k; + + for (k = MA_NP - 1; k > 0; k--) + Copy (freq_prev[k - 1], freq_prev[k], M10); + + Copy (lsp_ele, freq_prev[0], M10); + return; +} + +void +Lsp_stability (Word16 buf[] /* (i/o) Q13 : quantized LSP parameters */ + ) +{ + Word16 j; + Word16 tmp; + Word32 L_diff; + Word32 L_acc, L_accb; + + for (j = 0; j < M10 - 1; j++) { + L_acc = L_deposit_l (buf[j + 1]); + L_accb = L_deposit_l (buf[j]); + L_diff = L_sub (L_acc, L_accb); + + if (L_diff < 0L) { + /* exchange buf[j]<->buf[j+1] */ + tmp = buf[j + 1]; + buf[j + 1] = buf[j]; + buf[j] = tmp; + } + } + + + if (sub (buf[0], L_LIMIT) < 0) { + buf[0] = L_LIMIT; + printf ("lsp_stability warning Low \n"); + } + for (j = 0; j < M10 - 1; j++) { + L_acc = L_deposit_l (buf[j + 1]); + L_accb = L_deposit_l (buf[j]); + L_diff = L_sub (L_acc, L_accb); + + if (L_sub (L_diff, GAP3) < 0L) { + buf[j + 1] = add (buf[j], GAP3); + } + } + + if (sub (buf[M10 - 1], M_LIMIT) > 0) { + buf[M10 - 1] = M_LIMIT; + printf ("lsp_stability warning High \n"); + } + return; +} diff --git a/src/libs/libg729/g729_lspgetq.h b/src/libs/libg729/g729_lspgetq.h new file mode 100644 index 00000000..46b54fde --- /dev/null +++ b/src/libs/libg729/g729_lspgetq.h @@ -0,0 +1,50 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +void Lsp_get_quant (Word16 lspcb1[][M10], /* Q13 */ + Word16 lspcb2[][M10], /* Q13 */ + Word16 code0, Word16 code1, Word16 code2, Word16 fg[][M10], /* Q15 */ + Word16 freq_prev[][M10], /* Q13 */ + Word16 lspq[], /* Q13 */ + Word16 fg_sum[] /* Q15 */ + ); + +void Lsp_expand_1 (Word16 buf[], /* Q13 */ + Word16 gap /* Q13 */ + ); + +void Lsp_expand_2 (Word16 buf[], /* Q13 */ + Word16 gap /* Q13 */ + ); + +void Lsp_expand_1_2 (Word16 buf[], /* Q13 */ + Word16 gap /* Q13 */ + ); + +void Lsp_stability (Word16 buf[] /* Q13 */ + ); + +void Lsp_prev_compose (Word16 lsp_ele[], /* Q13 */ + Word16 lsp[], /* Q13 */ + Word16 fg[][M10], /* Q15 */ + Word16 freq_prev[][M10], /* Q13 */ + Word16 fg_sum[] /* Q15 */ + ); + +void Lsp_prev_extract (Word16 lsp[M10], /* Q13 */ + Word16 lsp_ele[M10], /* Q13 */ + Word16 fg[MA_NP][M10], /* Q15 */ + Word16 freq_prev[MA_NP][M10], /* Q13 */ + Word16 fg_sum_inv[M10] /* Q12 */ + ); + +void Lsp_prev_update (Word16 lsp_ele[M10], /* Q13 */ + Word16 freq_prev[MA_NP][M10] /* Q13 */ + ); + diff --git a/src/libs/libg729/g729_oper_32b.cpp b/src/libs/libg729/g729_oper_32b.cpp new file mode 100644 index 00000000..9230466b --- /dev/null +++ b/src/libs/libg729/g729_oper_32b.cpp @@ -0,0 +1,228 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_oper_32b.h" + +/*___________________________________________________________________________ + | | + | This file contains operations in double precision. | + | These operations are not standard double precision operations. | + | They are used where single precision is not enough but the full 32 bits | + | precision is not necessary. For example, the function Div_32() has a | + | 24 bits precision which is enough for our purposes. | + | | + | The double precision numbers use a special representation: | + | | + | L_32 = hi<<16 + lo<<1 | + | | + | L_32 is a 32 bit integer. | + | hi and lo are 16 bit signed integers. | + | As the low part also contains the sign, this allows fast multiplication. | + | | + | 0x8000 0000 <= L_32 <= 0x7fff fffe. | + | | + | We will use DPF (Double Precision Format )in this file to specify | + | this special format. | + |___________________________________________________________________________| +*/ + +/*___________________________________________________________________________ + | | + | Function L_Extract() | + | | + | Extract from a 32 bit integer two 16 bit DPF. | + | | + | Arguments: | + | | + | L_32 : 32 bit integer. | + | 0x8000 0000 <= L_32 <= 0x7fff ffff. | + | hi : b16 to b31 of L_32 | + | lo : (L_32 - hi<<16)>>1 | + |___________________________________________________________________________| +*/ + +void +L_Extract (Word32 L_32, Word16 * hi, Word16 * lo) +{ + *hi = extract_h (L_32); + *lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384)); /* lo = L_32>>1 */ + return; +} + +/*___________________________________________________________________________ + | | + | Function L_Comp() | + | | + | Compose from two 16 bit DPF a 32 bit integer. | + | | + | L_32 = hi<<16 + lo<<1 | + | | + | Arguments: | + | | + | hi msb | + | lo lsf (with sign) | + | | + | Return Value : | + | | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_32 <= 0x7fff fff0. | + | | + |___________________________________________________________________________| +*/ + +Word32 +L_Comp (Word16 hi, Word16 lo) +{ + Word32 L_32; + + L_32 = L_deposit_h (hi); + return (L_mac (L_32, lo, 1)); /* = hi<<16 + lo<<1 */ +} + +/*___________________________________________________________________________ + | Function Mpy_32() | + | | + | Multiply two 32 bit integers (DPF). The result is divided by 2**31 | + | | + | L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 | + | | + | This operation can also be viewed as the multiplication of two Q31 | + | number and the result is also in Q31. | + | | + | Arguments: | + | | + | hi1 hi part of first number | + | lo1 lo part of first number | + | hi2 hi part of second number | + | lo2 lo part of second number | + | | + |___________________________________________________________________________| +*/ + +Word32 +Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2) +{ + Word32 L_32; + + L_32 = L_mult (hi1, hi2); + L_32 = L_mac (L_32, mult (hi1, lo2), 1); + L_32 = L_mac (L_32, mult (lo1, hi2), 1); + + return (L_32); +} + +/*___________________________________________________________________________ + | Function Mpy_32_16() | + | | + | Multiply a 16 bit integer by a 32 bit (DPF). The result is divided | + | by 2**15 | + | | + | This operation can also be viewed as the multiplication of a Q31 | + | number by a Q15 number, the result is in Q31. | + | | + | L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 | + | | + | Arguments: | + | | + | hi hi part of 32 bit number. | + | lo lo part of 32 bit number. | + | n 16 bit number. | + | | + |___________________________________________________________________________| +*/ + +Word32 +Mpy_32_16 (Word16 hi, Word16 lo, Word16 n) +{ + Word32 L_32; + + L_32 = L_mult (hi, n); + L_32 = L_mac (L_32, mult (lo, n), 1); + + return (L_32); +} + +/*___________________________________________________________________________ + | | + | Function Name : Div_32 | + | | + | Purpose : | + | Fractional integer division of two 32 bit numbers. | + | L_num / L_denom. | + | L_num and L_denom must be positive and L_num < L_denom. | + | L_denom = denom_hi<<16 + denom_lo<<1 | + | denom_hi is a normalize number. | + | The result is in Q30. | + | | + | Inputs : | + | | + | L_num | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x0000 0000 < L_num < L_denom | + | | + | L_denom = denom_hi<<16 + denom_lo<<1 (DPF) | + | | + | denom_hi | + | 16 bit positive normalized integer whose value falls in the | + | range : 0x4000 < hi < 0x7fff | + | denom_lo | + | 16 bit positive integer whose value falls in the | + | range : 0 < lo < 0x7fff | + | | + | Return Value : | + | | + | L_div | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x0000 0000 <= L_div <= 0x7fff ffff. | + | It's a Q31 value | + | | + | Algorithm: | + | | + | - find = 1/L_denom. | + | First approximation: approx = 1 / denom_hi | + | 1/L_denom = approx * (2.0 - L_denom * approx ) | + | | + | - result = L_num * (1/L_denom) | + |___________________________________________________________________________| +*/ + +Word32 +Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo) +{ + Word16 approx, hi, lo, n_hi, n_lo; + Word32 L_32; + + + /* First approximation: 1 / L_denom = 1/denom_hi */ + + approx = div_s ((Word16) 0x3fff, denom_hi); /* result in Q14 */ + /* Note: 3fff = 0.5 in Q15 */ + + /* 1/L_denom = approx * (2.0 - L_denom * approx) */ + + L_32 = Mpy_32_16 (denom_hi, denom_lo, approx); /* result in Q30 */ + + + L_32 = L_sub ((Word32) 0x7fffffffL, L_32); /* result in Q30 */ + + L_Extract (L_32, &hi, &lo); + + L_32 = Mpy_32_16 (hi, lo, approx); /* = 1/L_denom in Q29 */ + + /* L_num * (1/L_denom) */ + + L_Extract (L_32, &hi, &lo); + L_Extract (L_num, &n_hi, &n_lo); + L_32 = Mpy_32 (n_hi, n_lo, hi, lo); /* result in Q29 */ + L_32 = L_shl (L_32, 2); /* From Q29 to Q31 */ + + return (L_32); +} diff --git a/src/libs/libg729/g729_oper_32b.h b/src/libs/libg729/g729_oper_32b.h new file mode 100644 index 00000000..3a52bd40 --- /dev/null +++ b/src/libs/libg729/g729_oper_32b.h @@ -0,0 +1,16 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/* Double precision operations */ + +void L_Extract (Word32 L_32, Word16 * hi, Word16 * lo); +Word32 L_Comp (Word16 hi, Word16 lo); +Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2); +Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n); +Word32 Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo); diff --git a/src/libs/libg729/g729_p_parity.cpp b/src/libs/libg729/g729_p_parity.cpp new file mode 100644 index 00000000..7faa1356 --- /dev/null +++ b/src/libs/libg729/g729_p_parity.cpp @@ -0,0 +1,63 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------* + * Parity_pitch - compute parity bit for first 6 MSBs * + *------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" + +Word16 +Parity_Pitch ( /* output: parity bit (XOR of 6 MSB bits) */ + Word16 pitch_index /* input : index for which parity to compute */ + ) +{ + Word16 temp, sum, i, bit; + + temp = shr (pitch_index, 1); + + sum = 1; + for (i = 0; i <= 5; i++) { + temp = shr (temp, 1); + bit = temp & (Word16) 1; + sum = add (sum, bit); + } + sum = sum & (Word16) 1; + + + return sum; +} + +/*--------------------------------------------------------------------* + * check_parity_pitch - check parity of index with transmitted parity * + *--------------------------------------------------------------------*/ + +Word16 +Check_Parity_Pitch ( /* output: 0 = no error, 1= error */ + Word16 pitch_index, /* input : index of parameter */ + Word16 parity /* input : parity bit */ + ) +{ + Word16 temp, sum, i, bit; + + temp = shr (pitch_index, 1); + + sum = 1; + for (i = 0; i <= 5; i++) { + temp = shr (temp, 1); + bit = temp & (Word16) 1; + sum = add (sum, bit); + } + sum = add (sum, parity); + sum = sum & (Word16) 1; + + return sum; +} diff --git a/src/libs/libg729/g729_pitch_a.cpp b/src/libs/libg729/g729_pitch_a.cpp new file mode 100644 index 00000000..04e82f7b --- /dev/null +++ b/src/libs/libg729/g729_pitch_a.cpp @@ -0,0 +1,570 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*---------------------------------------------------------------------------* + * Pitch related functions * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + *---------------------------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_oper_32b.h" +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" +#include "g729_util.h" + +/*---------------------------------------------------------------------------* + * Function Pitch_ol_fast * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * Compute the open loop pitch lag. (fast version) * + * * + *---------------------------------------------------------------------------*/ + + +Word16 +Pitch_ol_fast ( /* output: open loop pitch lag */ + Word16 signal[], /* input : signal used to compute the open loop pitch */ + /* signal[-pit_max] to signal[-1] should be known */ + Word16 pit_max, /* input : maximum pitch lag */ + Word16 L_frame /* input : length of frame to compute pitch */ + ) +{ + Flag Overflow; + Word16 i, j; + Word16 max1, max2, max3; + Word16 max_h, max_l, ener_h, ener_l; + Word16 T1, T2, T3; + Word16 *p, *p1; + Word32 max, sum, L_temp; + + /* Scaled signal */ + + Word16 scaled_signal[L_FRAME + PIT_MAX]; + Word16 *scal_sig; + + scal_sig = &scaled_signal[pit_max]; + + /*--------------------------------------------------------* + * Verification for risk of overflow. * + *--------------------------------------------------------*/ + + Overflow = 0; + sum = 0; + + for (i = -pit_max; i < L_frame; i += 2) + sum = L_mac_o (sum, signal[i], signal[i], &Overflow); + + /*--------------------------------------------------------* + * Scaling of input signal. * + * * + * if Overflow -> scal_sig[i] = signal[i]>>3 * + * else if sum < 1^20 -> scal_sig[i] = signal[i]<<3 * + * else -> scal_sig[i] = signal[i] * + *--------------------------------------------------------*/ + + if (Overflow == 1) { + for (i = -pit_max; i < L_frame; i++) { + scal_sig[i] = shr (signal[i], 3); + } + } + else { + L_temp = L_sub (sum, (Word32) 1048576L); + if (L_temp < (Word32) 0) { /* if (sum < 2^20) */ + for (i = -pit_max; i < L_frame; i++) { + scal_sig[i] = shl (signal[i], 3); + } + } + else { + for (i = -pit_max; i < L_frame; i++) { + scal_sig[i] = signal[i]; + } + } + } + + /*--------------------------------------------------------------------* + * The pitch lag search is divided in three sections. * + * Each section cannot have a pitch multiple. * + * We find a maximum for each section. * + * We compare the maxima of each section by favoring small lag. * + * * + * First section: lag delay = 20 to 39 * + * Second section: lag delay = 40 to 79 * + * Third section: lag delay = 80 to 143 * + *--------------------------------------------------------------------*/ + + /* First section */ + + max = MIN_32; + T1 = 20; /* Only to remove warning from some compilers */ + for (i = 20; i < 40; i++) { + p = scal_sig; + p1 = &scal_sig[-i]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T1 = i; + } + } + + /* compute energy of maximum */ + + sum = 1; /* to avoid division by zero */ + p = &scal_sig[-T1]; + for (i = 0; i < L_frame; i += 2, p += 2) + sum = L_mac (sum, *p, *p); + + /* max1 = max/sqrt(energy) */ + /* This result will always be on 16 bits !! */ + + sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */ + L_Extract (max, &max_h, &max_l); + L_Extract (sum, &ener_h, &ener_l); + sum = Mpy_32 (max_h, max_l, ener_h, ener_l); + max1 = extract_l (sum); + + /* Second section */ + + max = MIN_32; + T2 = 40; /* Only to remove warning from some compilers */ + for (i = 40; i < 80; i++) { + p = scal_sig; + p1 = &scal_sig[-i]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T2 = i; + } + } + + /* compute energy of maximum */ + + sum = 1; /* to avoid division by zero */ + p = &scal_sig[-T2]; + for (i = 0; i < L_frame; i += 2, p += 2) + sum = L_mac (sum, *p, *p); + + /* max2 = max/sqrt(energy) */ + /* This result will always be on 16 bits !! */ + + sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */ + L_Extract (max, &max_h, &max_l); + L_Extract (sum, &ener_h, &ener_l); + sum = Mpy_32 (max_h, max_l, ener_h, ener_l); + max2 = extract_l (sum); + + /* Third section */ + + max = MIN_32; + T3 = 80; /* Only to remove warning from some compilers */ + for (i = 80; i < 143; i += 2) { + p = scal_sig; + p1 = &scal_sig[-i]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T3 = i; + } + } + + /* Test around max3 */ + + i = T3; + p = scal_sig; + p1 = &scal_sig[-(i + 1)]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T3 = i + (Word16) 1; + } + + p = scal_sig; + p1 = &scal_sig[-(i - 1)]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T3 = i - (Word16) 1; + } + + /* compute energy of maximum */ + + sum = 1; /* to avoid division by zero */ + p = &scal_sig[-T3]; + for (i = 0; i < L_frame; i += 2, p += 2) + sum = L_mac (sum, *p, *p); + + /* max1 = max/sqrt(energy) */ + /* This result will always be on 16 bits !! */ + + sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */ + L_Extract (max, &max_h, &max_l); + L_Extract (sum, &ener_h, &ener_l); + sum = Mpy_32 (max_h, max_l, ener_h, ener_l); + max3 = extract_l (sum); + + /*-----------------------* + * Test for multiple. * + *-----------------------*/ + + /* if( abs(T2*2 - T3) < 5) */ + /* max2 += max3 * 0.25; */ + + i = sub (shl (T2, 1), T3); + j = sub (abs_s (i), 5); + if (j < 0) + max2 = add (max2, shr (max3, 2)); + + /* if( abs(T2*3 - T3) < 7) */ + /* max2 += max3 * 0.25; */ + + i = add (i, T2); + j = sub (abs_s (i), 7); + if (j < 0) + max2 = add (max2, shr (max3, 2)); + + /* if( abs(T1*2 - T2) < 5) */ + /* max1 += max2 * 0.20; */ + + i = sub (shl (T1, 1), T2); + j = sub (abs_s (i), 5); + if (j < 0) + max1 = add (max1, mult (max2, 6554)); + + /* if( abs(T1*3 - T2) < 7) */ + /* max1 += max2 * 0.20; */ + + i = add (i, T1); + j = sub (abs_s (i), 7); + if (j < 0) + max1 = add (max1, mult (max2, 6554)); + + /*--------------------------------------------------------------------* + * Compare the 3 sections maxima. * + *--------------------------------------------------------------------*/ + + if (sub (max1, max2) < 0) { + max1 = max2; + T1 = T2; + } + if (sub (max1, max3) < 0) { + T1 = T3; + } + + return T1; +} + + + + +/*--------------------------------------------------------------------------* + * Function Dot_Product() * + * ~~~~~~~~~~~~~~~~~~~~~~ * + *--------------------------------------------------------------------------*/ + +Word32 +Dot_Product ( /* (o) :Result of scalar product. */ + Word16 x[], /* (i) :First vector. */ + Word16 y[], /* (i) :Second vector. */ + Word16 lg /* (i) :Number of point. */ + ) +{ + Word16 i; + Word32 sum; + + sum = 0; + for (i = 0; i < lg; i++) + sum = L_mac (sum, x[i], y[i]); + + return sum; +} + +/*--------------------------------------------------------------------------* + * Function Pitch_fr3_fast() * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * Fast version of the pitch close loop. * + *--------------------------------------------------------------------------*/ + +Word16 +Pitch_fr3_fast ( /* (o) : pitch period. */ + Word16 exc[], /* (i) : excitation buffer */ + Word16 xn[], /* (i) : target vector */ + Word16 h[], /* (i) Q12 : impulse response of filters. */ + Word16 L_subfr, /* (i) : Length of subframe */ + Word16 t0_min, /* (i) : minimum value in the searched range. */ + Word16 t0_max, /* (i) : maximum value in the searched range. */ + Word16 i_subfr, /* (i) : indicator for first subframe. */ + Word16 * pit_frac /* (o) : chosen fraction. */ + ) +{ + Word16 t, t0; + Word16 Dn[L_SUBFR]; + Word16 exc_tmp[L_SUBFR]; + Word32 max, corr, L_temp; + + /*-----------------------------------------------------------------* + * Compute correlation of target vector with impulse response. * + *-----------------------------------------------------------------*/ + + Cor_h_X (h, xn, Dn); + + /*-----------------------------------------------------------------* + * Find maximum integer delay. * + *-----------------------------------------------------------------*/ + + max = MIN_32; + t0 = t0_min; /* Only to remove warning from some compilers */ + + for (t = t0_min; t <= t0_max; t++) { + corr = Dot_Product (Dn, &exc[-t], L_subfr); + L_temp = L_sub (corr, max); + if (L_temp > 0) { + max = corr; + t0 = t; + } + } + + /*-----------------------------------------------------------------* + * Test fractions. * + *-----------------------------------------------------------------*/ + + /* Fraction 0 */ + + Pred_lt_3 (exc, t0, 0, L_subfr); + max = Dot_Product (Dn, exc, L_subfr); + *pit_frac = 0; + + /* If first subframe and lag > 84 do not search fractional pitch */ + + if ((i_subfr == 0) && (sub (t0, 84) > 0)) + return t0; + + Copy (exc, exc_tmp, L_subfr); + + /* Fraction -1/3 */ + + Pred_lt_3 (exc, t0, -1, L_subfr); + corr = Dot_Product (Dn, exc, L_subfr); + L_temp = L_sub (corr, max); + if (L_temp > 0) { + max = corr; + *pit_frac = -1; + Copy (exc, exc_tmp, L_subfr); + } + + /* Fraction +1/3 */ + + Pred_lt_3 (exc, t0, 1, L_subfr); + corr = Dot_Product (Dn, exc, L_subfr); + L_temp = L_sub (corr, max); + if (L_temp > 0) { + max = corr; + *pit_frac = 1; + } + else + Copy (exc_tmp, exc, L_subfr); + + return t0; +} + + +/*---------------------------------------------------------------------* + * Function G_pitch: * + * ~~~~~~~~ * + *---------------------------------------------------------------------* + * Compute correlations and to use in gains quantizer. * + * Also compute the gain of pitch. Result in Q14 * + * if (gain < 0) gain =0 * + * if (gain >1.2) gain =1.2 * + *---------------------------------------------------------------------*/ + + +Word16 +G_pitch ( /* (o) Q14 : Gain of pitch lag saturated to 1.2 */ + Word16 xn[], /* (i) : Pitch target. */ + Word16 y1[], /* (i) : Filtered adaptive codebook. */ + Word16 g_coeff[], /* (i) : Correlations need for gain quantization. */ + Word16 L_subfr /* (i) : Length of subframe. */ + ) +{ + Flag Overflow; + Word16 i; + Word16 xy, yy, exp_xy, exp_yy, gain; + Word32 s; + + Word16 scaled_y1[L_SUBFR]; + + /* divide "y1[]" by 4 to avoid overflow */ + + for (i = 0; i < L_subfr; i++) + scaled_y1[i] = shr (y1[i], 2); + + /* Compute scalar product */ + + Overflow = 0; + s = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_subfr; i++) + s = L_mac_o (s, y1[i], y1[i], &Overflow); + + if (Overflow == 0) { + exp_yy = norm_l (s); + yy = wround (L_shl (s, exp_yy)); + } + else { + s = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_subfr; i++) + s = L_mac (s, scaled_y1[i], scaled_y1[i]); + exp_yy = norm_l (s); + yy = wround (L_shl (s, exp_yy)); + exp_yy = sub (exp_yy, 4); + } + + /* Compute scalar product */ + + Overflow = 0; + s = 0; + for (i = 0; i < L_subfr; i++) + s = L_mac_o (s, xn[i], y1[i], &Overflow); + + if (Overflow == 0) { + exp_xy = norm_l (s); + xy = wround (L_shl (s, exp_xy)); + } + else { + s = 0; + for (i = 0; i < L_subfr; i++) + s = L_mac (s, xn[i], scaled_y1[i]); + exp_xy = norm_l (s); + xy = wround (L_shl (s, exp_xy)); + exp_xy = sub (exp_xy, 2); + } + + g_coeff[0] = yy; + g_coeff[1] = sub (15, exp_yy); + g_coeff[2] = xy; + g_coeff[3] = sub (15, exp_xy); + + /* If (xy <= 0) gain = 0 */ + + + if (xy <= 0) { + g_coeff[3] = -15; /* Force exp_xy to -15 = (15-30) */ + return ((Word16) 0); + } + + /* compute gain = xy/yy */ + + xy = shr (xy, 1); /* Be sure xy < yy */ + gain = div_s (xy, yy); + + i = sub (exp_xy, exp_yy); + gain = shr (gain, i); /* saturation if > 1.99 in Q14 */ + + /* if(gain >1.2) gain = 1.2 in Q14 */ + + if (sub (gain, 19661) > 0) { + gain = 19661; + } + + + return (gain); +} + + + +/*----------------------------------------------------------------------* + * Function Enc_lag3 * + * ~~~~~~~~ * + * Encoding of fractional pitch lag with 1/3 resolution. * + *----------------------------------------------------------------------* + * The pitch range for the first subframe is divided as follows: * + * 19 1/3 to 84 2/3 resolution 1/3 * + * 85 to 143 resolution 1 * + * * + * The period in the first subframe is encoded with 8 bits. * + * For the range with fractions: * + * index = (T-19)*3 + frac - 1; where T=[19..85] and frac=[-1,0,1] * + * and for the integer only range * + * index = (T - 85) + 197; where T=[86..143] * + *----------------------------------------------------------------------* + * For the second subframe a resolution of 1/3 is always used, and the * + * search range is relative to the lag in the first subframe. * + * If t0 is the lag in the first subframe then * + * t_min=t0-5 and t_max=t0+4 and the range is given by * + * t_min - 2/3 to t_max + 2/3 * + * * + * The period in the 2nd subframe is encoded with 5 bits: * + * index = (T-(t_min-1))*3 + frac - 1; where T[t_min-1 .. t_max+1] * + *----------------------------------------------------------------------*/ + + +Word16 +Enc_lag3 ( /* output: Return index of encoding */ + Word16 T0, /* input : Pitch delay */ + Word16 T0_frac, /* input : Fractional pitch delay */ + Word16 * T0_min, /* in/out: Minimum search delay */ + Word16 * T0_max, /* in/out: Maximum search delay */ + Word16 pit_min, /* input : Minimum pitch delay */ + Word16 pit_max, /* input : Maximum pitch delay */ + Word16 pit_flag /* input : Flag for 1st subframe */ + ) +{ + Word16 index, i; + + if (pit_flag == 0) { /* if 1st subframe */ + /* encode pitch delay (with fraction) */ + + if (sub (T0, 85) <= 0) { + /* index = t0*3 - 58 + t0_frac */ + i = add (add (T0, T0), T0); + index = add (sub (i, 58), T0_frac); + } + else { + index = add (T0, 112); + } + + /* find T0_min and T0_max for second subframe */ + + *T0_min = sub (T0, 5); + if (sub (*T0_min, pit_min) < 0) { + *T0_min = pit_min; + } + + *T0_max = add (*T0_min, 9); + if (sub (*T0_max, pit_max) > 0) { + *T0_max = pit_max; + *T0_min = sub (*T0_max, 9); + } + } + else { /* if second subframe */ + + + /* i = t0 - t0_min; */ + /* index = i*3 + 2 + t0_frac; */ + i = sub (T0, *T0_min); + i = add (add (i, i), i); + index = add (add (i, 2), T0_frac); + } + + + return index; +} diff --git a/src/libs/libg729/g729_post_pro.cpp b/src/libs/libg729/g729_post_pro.cpp new file mode 100644 index 00000000..76608f81 --- /dev/null +++ b/src/libs/libg729/g729_post_pro.cpp @@ -0,0 +1,84 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------------------------* + * Function Post_Process() * + * * + * Post-processing of output speech. * + * - 2nd order high pass filter with cut off frequency at 100 Hz. * + * - Multiplication by two of output speech with saturation. * + *-----------------------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_oper_32b.h" + +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" + +/*------------------------------------------------------------------------* + * 2nd order high pass filter with cut off frequency at 100 Hz. * + * Designed with SPPACK efi command -40 dB att, 0.25 ri. * + * * + * Algorithm: * + * * + * y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] * + * + a[1]*y[i-1] + a[2]*y[i-2]; * + * * + * b[3] = {0.93980581E+00, -0.18795834E+01, 0.93980581E+00}; * + * a[3] = {0.10000000E+01, 0.19330735E+01, -0.93589199E+00}; * + *-----------------------------------------------------------------------*/ + + +/* Initialization of values */ + +void +Init_Post_Process (DecState *decoder) +{ + decoder->y2_hi = 0; + decoder->y2_lo = 0; + decoder->y1_hi = 0; + decoder->y1_lo = 0; + decoder->x0 = 0; + decoder->x1 = 0; +} + + +void +Post_Process (DecState *decoder, + Word16 signal[], /* input/output signal */ + Word16 lg) +{ /* length of signal */ + Word16 i, x2; + Word32 L_tmp; + + for (i = 0; i < lg; i++) { + x2 = decoder->x1; + decoder->x1 = decoder->x0; + decoder->x0 = signal[i]; + + /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */ + /* + a[1]*y[i-1] + a[2] * y[i-2]; */ + + L_tmp = Mpy_32_16 (decoder->y1_hi, decoder->y1_lo, a100[1]); + L_tmp = L_add (L_tmp, Mpy_32_16 (decoder->y2_hi, decoder->y2_lo, a100[2])); + L_tmp = L_mac (L_tmp, decoder->x0, b100[0]); + L_tmp = L_mac (L_tmp, decoder->x1, b100[1]); + L_tmp = L_mac (L_tmp, x2, b100[2]); + L_tmp = L_shl (L_tmp, 2); /* Q29 --> Q31 (Q13 --> Q15) */ + + /* Multiplication by two of output speech with saturation. */ + signal[i] = wround (L_shl (L_tmp, 1)); + + decoder->y2_hi = decoder->y1_hi; + decoder->y2_lo = decoder->y1_lo; + L_Extract (L_tmp, &decoder->y1_hi, &decoder->y1_lo); + } + return; +} diff --git a/src/libs/libg729/g729_postfilt.cpp b/src/libs/libg729/g729_postfilt.cpp new file mode 100644 index 00000000..3fcf3a5a --- /dev/null +++ b/src/libs/libg729/g729_postfilt.cpp @@ -0,0 +1,441 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------------------------* + * POSTFILTER.C * + *------------------------------------------------------------------------* + * Performs adaptive postfiltering on the synthesis speech * + * This file contains all functions related to the post filter. * + *------------------------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" +#include "g729_oper_32b.h" +#include "g729_util.h" + +/*---------------------------------------------------------------* + * Postfilter constant parameters (defined in "ld8a.h") * + *---------------------------------------------------------------* + * L_FRAME : Frame size. * + * L_SUBFR : Sub-frame size. * + * M : LPC order. * + * MP1 : LPC order+1 * + * PIT_MAX : Maximum pitch lag. * + * GAMMA2_PST : Formant postfiltering factor (numerator) * + * GAMMA1_PST : Formant postfiltering factor (denominator) * + * GAMMAP : Harmonic postfiltering factor * + * MU : Factor for tilt compensation filter * + * AGC_FAC : Factor for automatic gain control * + *---------------------------------------------------------------*/ + + +/*------------------------------------------------------------* + * vectors * + *------------------------------------------------------------*/ + +/* inverse filtered synthesis (with A(z/GAMMA2_PST)) */ + +/*---------------------------------------------------------------* + * Procedure Init_Post_Filter: * + * ~~~~~~~~~~~~~~~~ * + * Initializes the postfilter parameters: * + *---------------------------------------------------------------*/ + +void +Init_Post_Filter (DecState *decoder) +{ + decoder->res2 = decoder->res2_buf + PIT_MAX; + decoder->scal_res2 = decoder->scal_res2_buf + PIT_MAX; + + Set_zero (decoder->mem_syn_pst, M10); + Set_zero (decoder->res2_buf, PIT_MAX + L_SUBFR); + Set_zero (decoder->scal_res2_buf, PIT_MAX + L_SUBFR); + + decoder->mem_pre = 0; + decoder->past_gain = 4096; + return; +} + + + + +/*------------------------------------------------------------------------* + * Procedure Post_Filter: * + * ~~~~~~~~~~~ * + *------------------------------------------------------------------------* + * The postfiltering process is described as follows: * + * * + * - inverse filtering of syn[] through A(z/GAMMA2_PST) to get res2[] * + * - use res2[] to compute pitch parameters * + * - perform pitch postfiltering * + * - tilt compensation filtering; 1 - MU*k*z^-1 * + * - synthesis filtering through 1/A(z/GAMMA1_PST) * + * - adaptive gain control * + *------------------------------------------------------------------------*/ + + + +void +Post_Filter (DecState *decoder, + Word16 * syn, /* in/out: synthesis speech (postfiltered is output) */ + Word16 * Az_4, /* input : interpolated LPC parameters in all subframes */ + Word16 * T /* input : decoded pitch lags in all subframes */ + ) +{ + /*-------------------------------------------------------------------* + * Declaration of parameters * + *-------------------------------------------------------------------*/ + + Word16 res2_pst[L_SUBFR]; /* res2[] after pitch postfiltering */ + Word16 syn_pst[L_FRAME]; /* post filtered synthesis speech */ + + Word16 Ap3[MP1], Ap4[MP1]; /* bandwidth expanded LP parameters */ + + Word16 *Az; /* pointer to Az_4: */ + /* LPC parameters in each subframe */ + Word16 t0_max, t0_min; /* closed-loop pitch search range */ + Word16 i_subfr; /* index for beginning of subframe */ + + Word16 h[L_H]; + + Word16 i, j; + Word16 temp1, temp2; + Word32 L_tmp; + + /*-----------------------------------------------------* + * Post filtering * + *-----------------------------------------------------*/ + + Az = Az_4; + + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { + /* Find pitch range t0_min - t0_max */ + + t0_min = sub (*T++, 3); + t0_max = add (t0_min, 6); + if (sub (t0_max, PIT_MAX) > 0) { + t0_max = PIT_MAX; + t0_min = sub (t0_max, 6); + } + + /* Find weighted filter coefficients Ap3[] and ap[4] */ + + Weight_Az (Az, GAMMA2_PST, M10, Ap3); + Weight_Az (Az, GAMMA1_PST, M10, Ap4); + + /* filtering of synthesis speech by A(z/GAMMA2_PST) to find res2[] */ + + Residu (Ap3, &syn[i_subfr], decoder->res2, L_SUBFR); + + /* scaling of "res2[]" to avoid energy overflow */ + + for (j = 0; j < L_SUBFR; j++) { + decoder->scal_res2[j] = shr (decoder->res2[j], 2); + } + + /* pitch postfiltering */ + + pit_pst_filt (decoder->res2, decoder->scal_res2, t0_min, t0_max, L_SUBFR, res2_pst); + + /* tilt compensation filter */ + + /* impulse response of A(z/GAMMA2_PST)/A(z/GAMMA1_PST) */ + + Copy (Ap3, h, M10 + 1); + Set_zero (&h[M10 + 1], L_H - M10 - 1); + Syn_filt (Ap4, h, h, L_H, &h[M10 + 1], 0, NULL); + + /* 1st correlation of h[] */ + + L_tmp = L_mult (h[0], h[0]); + for (i = 1; i < L_H; i++) + L_tmp = L_mac (L_tmp, h[i], h[i]); + temp1 = extract_h (L_tmp); + + L_tmp = L_mult (h[0], h[1]); + for (i = 1; i < L_H - 1; i++) + L_tmp = L_mac (L_tmp, h[i], h[i + 1]); + temp2 = extract_h (L_tmp); + + if (temp2 <= 0) { + temp2 = 0; + } + else { + temp2 = mult (temp2, MU); + temp2 = div_s (temp2, temp1); + } + + preemphasis (decoder, res2_pst, temp2, L_SUBFR); + + /* filtering through 1/A(z/GAMMA1_PST) */ + + Syn_filt (Ap4, res2_pst, &syn_pst[i_subfr], L_SUBFR, decoder->mem_syn_pst, 1, NULL); + + /* scale output to input */ + + agc (decoder, &syn[i_subfr], &syn_pst[i_subfr], L_SUBFR); + + /* update res2[] buffer; shift by L_SUBFR */ + + Copy (&decoder->res2[L_SUBFR - PIT_MAX], &decoder->res2[-PIT_MAX], PIT_MAX); + Copy (&decoder->scal_res2[L_SUBFR - PIT_MAX], &decoder->scal_res2[-PIT_MAX], PIT_MAX); + + Az += MP1; + } + + /* update syn[] buffer */ + + Copy (&syn[L_FRAME - M10], &syn[-M10], M10); + + /* overwrite synthesis speech by postfiltered synthesis speech */ + + Copy (syn_pst, syn, L_FRAME); + + return; +} + + + + +/*---------------------------------------------------------------------------* + * procedure pitch_pst_filt * + * ~~~~~~~~~~~~~~~~~~~~~~~~ * + * Find the pitch period around the transmitted pitch and perform * + * harmonic postfiltering. * + * Filtering through (1 + g z^-T) / (1+g) ; g = min(pit_gain*gammap, 1) * + *--------------------------------------------------------------------------*/ + +void +pit_pst_filt (Word16 * signal, /* (i) : input signal */ + Word16 * scal_sig, /* (i) : input signal (scaled, divided by 4) */ + Word16 t0_min, /* (i) : minimum value in the searched range */ + Word16 t0_max, /* (i) : maximum value in the searched range */ + Word16 L_subfr, /* (i) : size of filtering */ + Word16 * signal_pst /* (o) : harmonically postfiltered signal */ + ) +{ + Word16 i, j, t0; + Word16 g0, gain, cmax, en, en0; + Word16 *p, *p1, *deb_sig; + Word32 corr, cor_max, ener, ener0, temp; + Word32 L_temp; + +/*---------------------------------------------------------------------------* + * Compute the correlations for all delays * + * and select the delay which maximizes the correlation * + *---------------------------------------------------------------------------*/ + + deb_sig = &scal_sig[-t0_min]; + cor_max = MIN_32; + t0 = t0_min; /* Only to remove warning from some compilers */ + for (i = t0_min; i <= t0_max; i++) { + corr = 0; + p = scal_sig; + p1 = deb_sig; + for (j = 0; j < L_subfr; j++) + corr = L_mac (corr, *p++, *p1++); + + L_temp = L_sub (corr, cor_max); + if (L_temp > (Word32) 0) { + cor_max = corr; + t0 = i; + } + deb_sig--; + } + + /* Compute the energy of the signal delayed by t0 */ + + ener = 1; + p = scal_sig - t0; + for (i = 0; i < L_subfr; i++, p++) + ener = L_mac (ener, *p, *p); + + /* Compute the signal energy in the present subframe */ + + ener0 = 1; + p = scal_sig; + for (i = 0; i < L_subfr; i++, p++) + ener0 = L_mac (ener0, *p, *p); + + if (cor_max < 0) { + cor_max = 0; + } + + /* scale "cor_max", "ener" and "ener0" on 16 bits */ + + temp = cor_max; + if (ener > temp) { + temp = ener; + } + if (ener0 > temp) { + temp = ener0; + } + j = norm_l (temp); + cmax = wround (L_shl (cor_max, j)); + en = wround (L_shl (ener, j)); + en0 = wround (L_shl (ener0, j)); + + /* prediction gain (dB)= -10 log(1-cor_max*cor_max/(ener*ener0)) */ + + /* temp = (cor_max * cor_max) - (0.5 * ener * ener0) */ + temp = L_mult (cmax, cmax); + temp = L_sub (temp, L_shr (L_mult (en, en0), 1)); + + if (temp < (Word32) 0) { /* if prediction gain < 3 dB *//* switch off pitch postfilter */ + for (i = 0; i < L_subfr; i++) + signal_pst[i] = signal[i]; + return; + } + + if (sub (cmax, en) > 0) { /* if pitch gain > 1 */ + g0 = INV_GAMMAP; + gain = GAMMAP_2; + } + else { + cmax = shr (mult (cmax, GAMMAP), 1); /* cmax(Q14) = cmax(Q15) * GAMMAP */ + en = shr (en, 1); /* Q14 */ + i = add (cmax, en); + if (i > 0) { + gain = div_s (cmax, i); /* gain(Q15) = cor_max/(cor_max+ener) */ + g0 = sub (32767, gain); /* g0(Q15) = 1 - gain */ + } + else { + g0 = 32767; + gain = 0; + } + } + + + for (i = 0; i < L_subfr; i++) { + /* signal_pst[i] = g0*signal[i] + gain*signal[i-t0]; */ + + signal_pst[i] = add (mult (g0, signal[i]), mult (gain, signal[i - t0])); + + } + + return; +} + + +/*---------------------------------------------------------------------* + * routine preemphasis() * + * ~~~~~~~~~~~~~~~~~~~~~ * + * Preemphasis: filtering through 1 - g z^-1 * + *---------------------------------------------------------------------*/ + +void +preemphasis (DecState *decoder, + Word16 * signal, /* (i/o) : input signal overwritten by the output */ + Word16 g, /* (i) Q15 : preemphasis coefficient */ + Word16 L /* (i) : size of filtering */ + ) +{ + Word16 *p1, *p2, temp, i; + + p1 = signal + L - 1; + p2 = p1 - 1; + temp = *p1; + + for (i = 0; i <= L - 2; i++) { + *p1 = sub (*p1, mult (g, *p2)); p1--; p2--; + } + + *p1 = sub (*p1, mult (g, decoder->mem_pre)); + + decoder->mem_pre = temp; + + return; +} + + + +/*----------------------------------------------------------------------* + * routine agc() * + * ~~~~~~~~~~~~~ * + * Scale the postfilter output on a subframe basis by automatic control * + * of the subframe gain. * + * gain[n] = AGC_FAC * gain[n-1] + (1 - AGC_FAC) g_in/g_out * + *----------------------------------------------------------------------*/ + +void +agc (DecState *decoder, + Word16 * sig_in, /* (i) : postfilter input signal */ + Word16 * sig_out, /* (i/o) : postfilter output signal */ + Word16 l_trm /* (i) : subframe size */ + ) +{ + Word16 i, exp; + Word16 gain_in, gain_out, g0, gain; /* Q12 */ + Word32 s; + + Word16 signal[L_SUBFR]; + + /* calculate gain_out with exponent */ + + for (i = 0; i < l_trm; i++) + signal[i] = shr (sig_out[i], 2); + + s = 0; + for (i = 0; i < l_trm; i++) + s = L_mac (s, signal[i], signal[i]); + + if (s == 0) { + decoder->past_gain = 0; + return; + } + exp = sub (norm_l (s), 1); + gain_out = wround (L_shl (s, exp)); + + /* calculate gain_in with exponent */ + + for (i = 0; i < l_trm; i++) + signal[i] = shr (sig_in[i], 2); + + s = 0; + for (i = 0; i < l_trm; i++) + s = L_mac (s, signal[i], signal[i]); + + if (s == 0) { + g0 = 0; + } + else { + i = norm_l (s); + gain_in = wround (L_shl (s, i)); + exp = sub (exp, i); + + /*---------------------------------------------------* + * g0(Q12) = (1-AGC_FAC) * sqrt(gain_in/gain_out); * + *---------------------------------------------------*/ + + s = L_deposit_l (div_s (gain_out, gain_in)); /* Q15 */ + s = L_shl (s, 7); /* s(Q22) = gain_out / gain_in */ + s = L_shr (s, exp); /* Q22, add exponent */ + + /* i(Q12) = s(Q19) = 1 / sqrt(s(Q22)) */ + s = Inv_sqrt (s); /* Q19 */ + i = wround (L_shl (s, 9)); /* Q12 */ + + /* g0(Q12) = i(Q12) * (1-AGC_FAC)(Q15) */ + g0 = mult (i, AGC_FAC1); /* Q12 */ + } + + /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */ + /* sig_out(n) = gain(n) sig_out(n) */ + + gain = decoder->past_gain; + for (i = 0; i < l_trm; i++) { + gain = mult (gain, AGC_FAC); + gain = add (gain, g0); + sig_out[i] = extract_h (L_shl (L_mult (sig_out[i], gain), 3)); + } + decoder->past_gain = gain; + + return; +} diff --git a/src/libs/libg729/g729_pre_proc.cpp b/src/libs/libg729/g729_pre_proc.cpp new file mode 100644 index 00000000..8d4c0ca4 --- /dev/null +++ b/src/libs/libg729/g729_pre_proc.cpp @@ -0,0 +1,85 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------------------------* + * Function Pre_Process() * + * * + * Preprocessing of input speech. * + * - 2nd order high pass filter with cut off frequency at 140 Hz. * + * - Divide input by two. * + *-----------------------------------------------------------------------*/ + + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_oper_32b.h" + +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" + + +/*------------------------------------------------------------------------* + * 2nd order high pass filter with cut off frequency at 140 Hz. * + * Designed with SPPACK efi command -40 dB att, 0.25 ri. * + * * + * Algorithm: * + * * + * y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b[2]*x[i-2]/2 * + * + a[1]*y[i-1] + a[2]*y[i-2]; * + * * + * b[3] = {0.92727435E+00, -0.18544941E+01, 0.92727435E+00}; * + * a[3] = {0.10000000E+01, 0.19059465E+01, -0.91140240E+00}; * + * * + * Input are divided by two in the filtering process. * + *-----------------------------------------------------------------------*/ + + +/* Initialization of values */ + +void Init_Pre_Process (CodState *coder) +{ + coder->y2_hi = 0; + coder->y2_lo = 0; + coder->y1_hi = 0; + coder->y1_lo = 0; + coder->x0 = 0; + coder->x1 = 0; +} + + +void +Pre_Process (CodState *coder, + Word16 signal[], /* input/output signal */ + Word16 lg) +{ /* length of signal */ + Word16 i, x2; + Word32 L_tmp; + + for (i = 0; i < lg; i++) { + x2 = coder->x1; + coder->x1 = coder->x0; + coder->x0 = signal[i]; + + /* y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2 */ + /* + a[1]*y[i-1] + a[2] * y[i-2]; */ + + L_tmp = Mpy_32_16 (coder->y1_hi, coder->y1_lo, a140[1]); + L_tmp = L_add (L_tmp, Mpy_32_16 (coder->y2_hi, coder->y2_lo, a140[2])); + L_tmp = L_mac (L_tmp, coder->x0, b140[0]); + L_tmp = L_mac (L_tmp, coder->x1, b140[1]); + L_tmp = L_mac (L_tmp, x2, b140[2]); + L_tmp = L_shl (L_tmp, 3); /* Q28 --> Q31 (Q12 --> Q15) */ + signal[i] = wround (L_tmp); + + coder->y2_hi = coder->y1_hi; + coder->y2_lo = coder->y1_lo; + L_Extract (L_tmp, &coder->y1_hi, &coder->y1_lo); + } + return; +} diff --git a/src/libs/libg729/g729_pre_proc.h b/src/libs/libg729/g729_pre_proc.h new file mode 100644 index 00000000..b2f72332 --- /dev/null +++ b/src/libs/libg729/g729_pre_proc.h @@ -0,0 +1,19 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ +#ifndef _G729_PRE_PROC_H +#define _G729_PRE_PROC_H + +extern void Init_Pre_Process (CodState *coder); + +extern void Pre_Process (CodState *coder, + Word16 signal[], /* Input/output signal */ + Word16 lg /* Length of signal */ ); + + +#endif diff --git a/src/libs/libg729/g729_pred_lt3.cpp b/src/libs/libg729/g729_pred_lt3.cpp new file mode 100644 index 00000000..5e29e865 --- /dev/null +++ b/src/libs/libg729/g729_pred_lt3.cpp @@ -0,0 +1,61 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------------------------------------------* + * Function Pred_lt_3() * + * ~~~~~~~~~~~ * + *-------------------------------------------------------------------* + * Compute the result of long term prediction with fractional * + * interpolation of resolution 1/3. * + * * + * On return exc[0..L_subfr-1] contains the interpolated signal * + * (adaptive codebook excitation) * + *-------------------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" + +void +Pred_lt_3 (Word16 exc[], /* in/out: excitation buffer */ + Word16 T0, /* input : integer pitch lag */ + Word16 frac, /* input : fraction of lag */ + Word16 L_subfr /* input : subframe size */ + ) +{ + Word16 i, j, k; + Word16 *x0, *x1, *x2, *c1, *c2; + Word32 s; + + x0 = &exc[-T0]; + + frac = negate (frac); + if (frac < 0) { + frac = add (frac, UP_SAMP); + x0--; + } + + for (j = 0; j < L_subfr; j++) { + x1 = x0++; + x2 = x0; + c1 = &inter_3l[frac]; + c2 = &inter_3l[sub (UP_SAMP, frac)]; + + s = 0; + for (i = 0, k = 0; i < L_INTER10; i++, k += UP_SAMP) { + s = L_mac (s, x1[-i], c1[k]); + s = L_mac (s, x2[i], c2[k]); + } + + exc[j] = wround (s); + } + + return; +} diff --git a/src/libs/libg729/g729_tab_ld8a.cpp b/src/libs/libg729/g729_tab_ld8a.cpp new file mode 100644 index 00000000..19352e93 --- /dev/null +++ b/src/libs/libg729/g729_tab_ld8a.cpp @@ -0,0 +1,786 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + + +/* This file contains all the tables used by the G.729A codec */ + +#include "g729_typedef.h" +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" + +/* Hamming_cos window for LPC analysis. */ +/* Create with function ham_cos(window,200,40) */ + +Word16 hamwindow[L_WINDOW] = { + 2621, 2623, 2629, 2638, 2651, 2668, 2689, 2713, 2741, 2772, + 2808, 2847, 2890, 2936, 2986, 3040, 3097, 3158, 3223, 3291, + 3363, 3438, 3517, 3599, 3685, 3774, 3867, 3963, 4063, 4166, + 4272, 4382, 4495, 4611, 4731, 4853, 4979, 5108, 5240, 5376, + 5514, 5655, 5800, 5947, 6097, 6250, 6406, 6565, 6726, 6890, + 7057, 7227, 7399, 7573, 7750, 7930, 8112, 8296, 8483, 8672, + 8863, 9057, 9252, 9450, 9650, 9852, 10055, 10261, 10468, 10677, + 10888, 11101, 11315, 11531, 11748, 11967, 12187, 12409, 12632, 12856, + 13082, 13308, 13536, 13764, 13994, 14225, 14456, 14688, 14921, 15155, + 15389, 15624, 15859, 16095, 16331, 16568, 16805, 17042, 17279, 17516, + 17754, 17991, 18228, 18465, 18702, 18939, 19175, 19411, 19647, 19882, + 20117, 20350, 20584, 20816, 21048, 21279, 21509, 21738, 21967, 22194, + 22420, 22644, 22868, 23090, 23311, 23531, 23749, 23965, 24181, 24394, + 24606, 24816, 25024, 25231, 25435, 25638, 25839, 26037, 26234, 26428, + 26621, 26811, 26999, 27184, 27368, 27548, 27727, 27903, 28076, 28247, + 28415, 28581, 28743, 28903, 29061, 29215, 29367, 29515, 29661, 29804, + 29944, 30081, 30214, 30345, 30472, 30597, 30718, 30836, 30950, 31062, + 31170, 31274, 31376, 31474, 31568, 31659, 31747, 31831, 31911, 31988, + 32062, 32132, 32198, 32261, 32320, 32376, 32428, 32476, 32521, 32561, + 32599, 32632, 32662, 32688, 32711, 32729, 32744, 32755, 32763, 32767, + 32767, 32741, 32665, 32537, 32359, 32129, 31850, 31521, 31143, 30716, + 30242, 29720, 29151, 28538, 27879, 27177, 26433, 25647, 24821, 23957, + 23055, 22117, 21145, 20139, 19102, 18036, 16941, 15820, 14674, 13505, + 12315, 11106, 9879, 8637, 7381, 6114, 4838, 3554, 2264, 971 +}; + + +/*-----------------------------------------------------* + | Table of lag_window for autocorrelation. | + | noise floor = 1.0001 = (0.9999 on r[1] ..r[10]) | + | Bandwidth expansion = 60 Hz | + | | + | Special double precision format. See "oper_32b.c" | + | | + | lag_wind[0] = 1.00000000 (not stored) | + | lag_wind[1] = 0.99879038 | + | lag_wind[2] = 0.99546897 | + | lag_wind[3] = 0.98995781 | + | lag_wind[4] = 0.98229337 | + | lag_wind[5] = 0.97252619 | + | lag_wind[6] = 0.96072036 | + | lag_wind[7] = 0.94695264 | + | lag_wind[8] = 0.93131179 | + | lag_wind[9] = 0.91389757 | + | lag_wind[10]= 0.89481968 | + -----------------------------------------------------*/ + +Word16 lag_h[M10] = { + 32728, + 32619, + 32438, + 32187, + 31867, + 31480, + 31029, + 30517, + 29946, + 29321 +}; + +Word16 lag_l[M10] = { + 11904, + 17280, + 30720, + 25856, + 24192, + 28992, + 24384, + 7360, + 19520, + 14784 +}; + + +/*-----------------------------------------------------* + | Tables for function Lsf_lsp() and Lsp_lsf() | + -----------------------------------------------------*/ + +/* table of cos(x) in Q15 */ + +Word16 table[65] = { + 32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853, + 30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279, + 23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010, + 12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608, + 0, -1608, -3212, -4808, -6393, -7962, -9512, -11039, + -12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006, + -23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622, + -30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729, + -32768L +}; + +/* slope in Q12 used to compute y = acos(x) */ + +Word16 slope[64] = { + -26887, -8812, -5323, -3813, -2979, -2444, -2081, -1811, + -1608, -1450, -1322, -1219, -1132, -1059, -998, -946, + -901, -861, -827, -797, -772, -750, -730, -713, + -699, -687, -677, -668, -662, -657, -654, -652, + -652, -654, -657, -662, -668, -677, -687, -699, + -713, -730, -750, -772, -797, -827, -861, -901, + -946, -998, -1059, -1132, -1219, -1322, -1450, -1608, + -1811, -2081, -2444, -2979, -3813, -5323, -8812, -26887 +}; + + +/*-----------------------------------------------------* + | Tables for function Lsf_lsp() and Lsp_lsf() | + -----------------------------------------------------*/ + +/* table of cos(x) in Q15 */ + +Word16 table2[64] = { + 32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853, + 30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279, + 23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010, + 12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608, + 0, -1608, -3212, -4808, -6393, -7962, -9512, -11039, + -12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006, + -23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622, + -30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729 +}; + +/* slope in Q19 used to compute y = cos(x) */ + +Word16 slope_cos[64] = { + -632, -1893, -3150, -4399, -5638, -6863, -8072, -9261, + -10428, -11570, -12684, -13767, -14817, -15832, -16808, -17744, + -18637, -19486, -20287, -21039, -21741, -22390, -22986, -23526, + -24009, -24435, -24801, -25108, -25354, -25540, -25664, -25726, + -25726, -25664, -25540, -25354, -25108, -24801, -24435, -24009, + -23526, -22986, -22390, -21741, -21039, -20287, -19486, -18637, + -17744, -16808, -15832, -14817, -13767, -12684, -11570, -10428, + -9261, -8072, -6863, -5638, -4399, -3150, -1893, -632 +}; + +/* slope in Q12 used to compute y = acos(x) */ + +Word16 slope_acos[64] = { + -26887, -8812, -5323, -3813, -2979, -2444, -2081, -1811, + -1608, -1450, -1322, -1219, -1132, -1059, -998, -946, + -901, -861, -827, -797, -772, -750, -730, -713, + -699, -687, -677, -668, -662, -657, -654, -652, + -652, -654, -657, -662, -668, -677, -687, -699, + -713, -730, -750, -772, -797, -827, -861, -901, + -946, -998, -1059, -1132, -1219, -1322, -1450, -1608, + -1811, -2081, -2444, -2979, -3813, -5323, -8812, -26887 +}; + +/* lsp code book <../f7s55m1.v2> */ + +Word16 lspcb1[NC0][M10] = { /* Q13 */ + {1486, 2168, 3751, 9074, 12134, 13944, 17983, 19173, 21190, 21820} + , + {1730, 2640, 3450, 4870, 6126, 7876, 15644, 17817, 20294, 21902} + , + {1568, 2256, 3088, 4874, 11063, 13393, 18307, 19293, 21109, 21741} + , + {1733, 2512, 3357, 4708, 6977, 10296, 17024, 17956, 19145, 20350} + , + {1744, 2436, 3308, 8731, 10432, 12007, 15614, 16639, 21359, 21913} + , + {1786, 2369, 3372, 4521, 6795, 12963, 17674, 18988, 20855, 21640} + , + {1631, 2433, 3361, 6328, 10709, 12013, 13277, 13904, 19441, 21088} + , + {1489, 2364, 3291, 6250, 9227, 10403, 13843, 15278, 17721, 21451} + , + {1869, 2533, 3475, 4365, 9152, 14513, 15908, 17022, 20611, 21411} + , + {2070, 3025, 4333, 5854, 7805, 9231, 10597, 16047, 20109, 21834} + , + {1910, 2673, 3419, 4261, 11168, 15111, 16577, 17591, 19310, 20265} + , + {1141, 1815, 2624, 4623, 6495, 9588, 13968, 16428, 19351, 21286} + , + {2192, 3171, 4707, 5808, 10904, 12500, 14162, 15664, 21124, 21789} + , + {1286, 1907, 2548, 3453, 9574, 11964, 15978, 17344, 19691, 22495} + , + {1921, 2720, 4604, 6684, 11503, 12992, 14350, 15262, 16997, 20791} + , + {2052, 2759, 3897, 5246, 6638, 10267, 15834, 16814, 18149, 21675} + , + {1798, 2497, 5617, 11449, 13189, 14711, 17050, 18195, 20307, 21182} + , + {1009, 1647, 2889, 5709, 9541, 12354, 15231, 18494, 20966, 22033} + , + {3016, 3794, 5406, 7469, 12488, 13984, 15328, 16334, 19952, 20791} + , + {2203, 3040, 3796, 5442, 11987, 13512, 14931, 16370, 17856, 18803} + , + {2912, 4292, 7988, 9572, 11562, 13244, 14556, 16529, 20004, 21073} + , + {2861, 3607, 5923, 7034, 9234, 12054, 13729, 18056, 20262, 20974} + , + {3069, 4311, 5967, 7367, 11482, 12699, 14309, 16233, 18333, 19172} + , + {2434, 3661, 4866, 5798, 10383, 11722, 13049, 15668, 18862, 19831} + , + {2020, 2605, 3860, 9241, 13275, 14644, 16010, 17099, 19268, 20251} + , + {1877, 2809, 3590, 4707, 11056, 12441, 15622, 17168, 18761, 19907} + , + {2107, 2873, 3673, 5799, 13579, 14687, 15938, 17077, 18890, 19831} + , + {1612, 2284, 2944, 3572, 8219, 13959, 15924, 17239, 18592, 20117} + , + {2420, 3156, 6542, 10215, 12061, 13534, 15305, 16452, 18717, 19880} + , + {1667, 2612, 3534, 5237, 10513, 11696, 12940, 16798, 18058, 19378} + , + {2388, 3017, 4839, 9333, 11413, 12730, 15024, 16248, 17449, 18677} + , + {1875, 2786, 4231, 6320, 8694, 10149, 11785, 17013, 18608, 19960} + , + {679, 1411, 4654, 8006, 11446, 13249, 15763, 18127, 20361, 21567} + , + {1838, 2596, 3578, 4608, 5650, 11274, 14355, 15886, 20579, 21754} + , + {1303, 1955, 2395, 3322, 12023, 13764, 15883, 18077, 20180, 21232} + , + {1438, 2102, 2663, 3462, 8328, 10362, 13763, 17248, 19732, 22344} + , + {860, 1904, 6098, 7775, 9815, 12007, 14821, 16709, 19787, 21132} + , + {1673, 2723, 3704, 6125, 7668, 9447, 13683, 14443, 20538, 21731} + , + {1246, 1849, 2902, 4508, 7221, 12710, 14835, 16314, 19335, 22720} + , + {1525, 2260, 3862, 5659, 7342, 11748, 13370, 14442, 18044, 21334} + , + {1196, 1846, 3104, 7063, 10972, 12905, 14814, 17037, 19922, 22636} + , + {2147, 3106, 4475, 6511, 8227, 9765, 10984, 12161, 18971, 21300} + , + {1585, 2405, 2994, 4036, 11481, 13177, 14519, 15431, 19967, 21275} + , + {1778, 2688, 3614, 4680, 9465, 11064, 12473, 16320, 19742, 20800} + , + {1862, 2586, 3492, 6719, 11708, 13012, 14364, 16128, 19610, 20425} + , + {1395, 2156, 2669, 3386, 10607, 12125, 13614, 16705, 18976, 21367} + , + {1444, 2117, 3286, 6233, 9423, 12981, 14998, 15853, 17188, 21857} + , + {2004, 2895, 3783, 4897, 6168, 7297, 12609, 16445, 19297, 21465} + , + {1495, 2863, 6360, 8100, 11399, 14271, 15902, 17711, 20479, 22061} + , + {2484, 3114, 5718, 7097, 8400, 12616, 14073, 14847, 20535, 21396} + , + {2424, 3277, 5296, 6284, 11290, 12903, 16022, 17508, 19333, 20283} + , + {2565, 3778, 5360, 6989, 8782, 10428, 14390, 15742, 17770, 21734} + , + {2727, 3384, 6613, 9254, 10542, 12236, 14651, 15687, 20074, 21102} + , + {1916, 2953, 6274, 8088, 9710, 10925, 12392, 16434, 20010, 21183} + , + {3384, 4366, 5349, 7667, 11180, 12605, 13921, 15324, 19901, 20754} + , + {3075, 4283, 5951, 7619, 9604, 11010, 12384, 14006, 20658, 21497} + , + {1751, 2455, 5147, 9966, 11621, 13176, 14739, 16470, 20788, 21756} + , + {1442, 2188, 3330, 6813, 8929, 12135, 14476, 15306, 19635, 20544} + , + {2294, 2895, 4070, 8035, 12233, 13416, 14762, 17367, 18952, 19688} + , + {1937, 2659, 4602, 6697, 9071, 12863, 14197, 15230, 16047, 18877} + , + {2071, 2663, 4216, 9445, 10887, 12292, 13949, 14909, 19236, 20341} + , + {1740, 2491, 3488, 8138, 9656, 11153, 13206, 14688, 20896, 21907} + , + {2199, 2881, 4675, 8527, 10051, 11408, 14435, 15463, 17190, 20597} + , + {1943, 2988, 4177, 6039, 7478, 8536, 14181, 15551, 17622, 21579} + , + {1825, 3175, 7062, 9818, 12824, 15450, 18330, 19856, 21830, 22412} + , + {2464, 3046, 4822, 5977, 7696, 15398, 16730, 17646, 20588, 21320} + , + {2550, 3393, 5305, 6920, 10235, 14083, 18143, 19195, 20681, 21336} + , + {3003, 3799, 5321, 6437, 7919, 11643, 15810, 16846, 18119, 18980} + , + {3455, 4157, 6838, 8199, 9877, 12314, 15905, 16826, 19949, 20892} + , + {3052, 3769, 4891, 5810, 6977, 10126, 14788, 15990, 19773, 20904} + , + {3671, 4356, 5827, 6997, 8460, 12084, 14154, 14939, 19247, 20423} + , + {2716, 3684, 5246, 6686, 8463, 10001, 12394, 14131, 16150, 19776} + , + {1945, 2638, 4130, 7995, 14338, 15576, 17057, 18206, 20225, 20997} + , + {2304, 2928, 4122, 4824, 5640, 13139, 15825, 16938, 20108, 21054} + , + {1800, 2516, 3350, 5219, 13406, 15948, 17618, 18540, 20531, 21252} + , + {1436, 2224, 2753, 4546, 9657, 11245, 15177, 16317, 17489, 19135} + , + {2319, 2899, 4980, 6936, 8404, 13489, 15554, 16281, 20270, 20911} + , + {2187, 2919, 4610, 5875, 7390, 12556, 14033, 16794, 20998, 21769} + , + {2235, 2923, 5121, 6259, 8099, 13589, 15340, 16340, 17927, 20159} + , + {1765, 2638, 3751, 5730, 7883, 10108, 13633, 15419, 16808, 18574} + , + {3460, 5741, 9596, 11742, 14413, 16080, 18173, 19090, 20845, 21601} + , + {3735, 4426, 6199, 7363, 9250, 14489, 16035, 17026, 19873, 20876} + , + {3521, 4778, 6887, 8680, 12717, 14322, 15950, 18050, 20166, 21145} + , + {2141, 2968, 6865, 8051, 10010, 13159, 14813, 15861, 17528, 18655} + , + {4148, 6128, 9028, 10871, 12686, 14005, 15976, 17208, 19587, 20595} + , + {4403, 5367, 6634, 8371, 10163, 11599, 14963, 16331, 17982, 18768} + , + {4091, 5386, 6852, 8770, 11563, 13290, 15728, 16930, 19056, 20102} + , + {2746, 3625, 5299, 7504, 10262, 11432, 13172, 15490, 16875, 17514} + , + {2248, 3556, 8539, 10590, 12665, 14696, 16515, 17824, 20268, 21247} + , + {1279, 1960, 3920, 7793, 10153, 14753, 16646, 18139, 20679, 21466} + , + {2440, 3475, 6737, 8654, 12190, 14588, 17119, 17925, 19110, 19979} + , + {1879, 2514, 4497, 7572, 10017, 14948, 16141, 16897, 18397, 19376} + , + {2804, 3688, 7490, 10086, 11218, 12711, 16307, 17470, 20077, 21126} + , + {2023, 2682, 3873, 8268, 10255, 11645, 15187, 17102, 18965, 19788} + , + {2823, 3605, 5815, 8595, 10085, 11469, 16568, 17462, 18754, 19876} + , + {2851, 3681, 5280, 7648, 9173, 10338, 14961, 16148, 17559, 18474} + , + {1348, 2645, 5826, 8785, 10620, 12831, 16255, 18319, 21133, 22586} + , + {2141, 3036, 4293, 6082, 7593, 10629, 17158, 18033, 21466, 22084} + , + {1608, 2375, 3384, 6878, 9970, 11227, 16928, 17650, 20185, 21120} + , + {2774, 3616, 5014, 6557, 7788, 8959, 17068, 18302, 19537, 20542} + , + {1934, 4813, 6204, 7212, 8979, 11665, 15989, 17811, 20426, 21703} + , + {2288, 3507, 5037, 6841, 8278, 9638, 15066, 16481, 21653, 22214} + , + {2951, 3771, 4878, 7578, 9016, 10298, 14490, 15242, 20223, 20990} + , + {3256, 4791, 6601, 7521, 8644, 9707, 13398, 16078, 19102, 20249} + , + {1827, 2614, 3486, 6039, 12149, 13823, 16191, 17282, 21423, 22041} + , + {1000, 1704, 3002, 6335, 8471, 10500, 14878, 16979, 20026, 22427} + , + {1646, 2286, 3109, 7245, 11493, 12791, 16824, 17667, 18981, 20222} + , + {1708, 2501, 3315, 6737, 8729, 9924, 16089, 17097, 18374, 19917} + , + {2623, 3510, 4478, 5645, 9862, 11115, 15219, 18067, 19583, 20382} + , + {2518, 3434, 4728, 6388, 8082, 9285, 13162, 18383, 19819, 20552} + , + {1726, 2383, 4090, 6303, 7805, 12845, 14612, 17608, 19269, 20181} + , + {2860, 3735, 4838, 6044, 7254, 8402, 14031, 16381, 18037, 19410} + , + {4247, 5993, 7952, 9792, 12342, 14653, 17527, 18774, 20831, 21699} + , + {3502, 4051, 5680, 6805, 8146, 11945, 16649, 17444, 20390, 21564} + , + {3151, 4893, 5899, 7198, 11418, 13073, 15124, 17673, 20520, 21861} + , + {3960, 4848, 5926, 7259, 8811, 10529, 15661, 16560, 18196, 20183} + , + {4499, 6604, 8036, 9251, 10804, 12627, 15880, 17512, 20020, 21046} + , + {4251, 5541, 6654, 8318, 9900, 11686, 15100, 17093, 20572, 21687} + , + {3769, 5327, 7865, 9360, 10684, 11818, 13660, 15366, 18733, 19882} + , + {3083, 3969, 6248, 8121, 9798, 10994, 12393, 13686, 17888, 19105} + , + {2731, 4670, 7063, 9201, 11346, 13735, 16875, 18797, 20787, 22360} + , + {1187, 2227, 4737, 7214, 9622, 12633, 15404, 17968, 20262, 23533} + , + {1911, 2477, 3915, 10098, 11616, 12955, 16223, 17138, 19270, 20729} + , + {1764, 2519, 3887, 6944, 9150, 12590, 16258, 16984, 17924, 18435} + , + {1400, 3674, 7131, 8718, 10688, 12508, 15708, 17711, 19720, 21068} + , + {2322, 3073, 4287, 8108, 9407, 10628, 15862, 16693, 19714, 21474} + , + {2630, 3339, 4758, 8360, 10274, 11333, 12880, 17374, 19221, 19936} + , + {1721, 2577, 5553, 7195, 8651, 10686, 15069, 16953, 18703, 19929} +}; + + +Word16 lspcb2[NC1][M10] = { /* Q13 */ + {-435, -815, -742, 1033, -518, 582, -1201, 829, 86, 385} + , + {-833, -891, 463, -8, -1251, 1450, 72, -231, 864, 661} + , + {-1021, 231, -306, 321, -220, -163, -526, -754, -1633, 267} + , + {57, -198, -339, -33, -1468, 573, 796, -169, -631, 816} + , + {171, -350, 294, 1660, 453, 519, 291, 159, -640, -1296} + , + {-701, -842, -58, 950, 892, 1549, 715, 527, -714, -193} + , + {584, 31, -289, 356, -333, -457, 612, -283, -1381, -741} + , + {-109, -808, 231, 77, -87, -344, 1341, 1087, -654, -569} + , + {-859, 1236, 550, 854, 714, -543, -1752, -195, -98, -276} + , + {-877, -954, -1248, -299, 212, -235, -728, 949, 1517, 895} + , + {-77, 344, -620, 763, 413, 502, -362, -960, -483, 1386} + , + {-314, -307, -256, -1260, -429, 450, -466, -108, 1010, 2223} + , + {711, 693, 521, 650, 1305, -28, -378, 744, -1005, 240} + , + {-112, -271, -500, 946, 1733, 271, -15, 909, -259, 1688} + , + {575, -10, -468, -199, 1101, -1011, 581, -53, -747, 878} + , + {145, -285, -1280, -398, 36, -498, -1377, 18, -444, 1483} + , + {-1133, -835, 1350, 1284, -95, 1015, -222, 443, 372, -354} + , + {-1459, -1237, 416, -213, 466, 669, 659, 1640, 932, 534} + , + {-15, 66, 468, 1019, -748, 1385, -182, -907, -721, -262} + , + {-338, 148, 1445, 75, -760, 569, 1247, 337, 416, -121} + , + {389, 239, 1568, 981, 113, 369, -1003, -507, -587, -904} + , + {-312, -98, 949, 31, 1104, 72, -141, 1465, 63, -785} + , + {1127, 584, 835, 277, -1159, 208, 301, -882, 117, -404} + , + {539, -114, 856, -493, 223, -912, 623, -76, 276, -440} + , + {2197, 2337, 1268, 670, 304, -267, -525, 140, 882, -139} + , + {-1596, 550, 801, -456, -56, -697, 865, 1060, 413, 446} + , + {1154, 593, -77, 1237, -31, 581, -1037, -895, 669, 297} + , + {397, 558, 203, -797, -919, 3, 692, -292, 1050, 782} + , + {334, 1475, 632, -80, 48, -1061, -484, 362, -597, -852} + , + {-545, -330, -429, -680, 1133, -1182, -744, 1340, 262, 63} + , + {1320, 827, -398, -576, 341, -774, -483, -1247, -70, 98} + , + {-163, 674, -11, -886, 531, -1125, -265, -242, 724, 934} +}; +Word16 fg[2][MA_NP][M10] = { /* Q15 */ + { + {8421, 9109, 9175, 8965, 9034, 9057, 8765, 8775, 9106, 8673} + , + {7018, 7189, 7638, 7307, 7444, 7379, 7038, 6956, 6930, 6868} + , + {5472, 4990, 5134, 5177, 5246, 5141, 5206, 5095, 4830, 5147} + , + {4056, 3031, 2614, 3024, 2916, 2713, 3309, 3237, 2857, 3473} + } + , + { + {7733, 7880, 8188, 8175, 8247, 8490, 8637, 8601, 8359, 7569} + , + {4210, 3031, 2552, 3473, 3876, 3853, 4184, 4154, 3909, 3968} + , + {3214, 1930, 1313, 2143, 2493, 2385, 2755, 2706, 2542, 2919} + , + {3024, 1592, 940, 1631, 1723, 1579, 2034, 2084, 1913, 2601} + } +}; +Word16 fg_sum[2][M10] = { /* Q15 */ + {7798, 8447, 8205, 8293, 8126, 8477, 8447, 8703, 9043, 8604} + , + {14585, 18333, 19772, 17344, 16426, 16459, 15155, 15220, 16043, 15708} +}; +Word16 fg_sum_inv[2][M10] = { /* Q12 */ + {17210, 15888, 16357, 16183, 16516, 15833, 15888, 15421, 14840, 15597} + , + {9202, 7320, 6788, 7738, 8170, 8154, 8856, 8818, 8366, 8544} +}; + +/*-------------------------------------------------------------* + * Table for az_lsf() * + * * + * Vector grid[] is in Q15 * + * * + * grid[0] = 1.0; * + * grid[grid_points+1] = -1.0; * + * for (i = 1; i < grid_points; i++) * + * grid[i] = cos((6.283185307*i)/(2.0*grid_points)); * + * * + *-------------------------------------------------------------*/ + +/* Version 51 points */ +Word16 grid[GRID_POINTS + 1] = { + 32760, 32703, 32509, 32187, 31738, 31164, + 30466, 29649, 28714, 27666, 26509, 25248, + 23886, 22431, 20887, 19260, 17557, 15786, + 13951, 12062, 10125, 8149, 6140, 4106, + 2057, 0, -2057, -4106, -6140, -8149, + -10125, -12062, -13951, -15786, -17557, -19260, + -20887, -22431, -23886, -25248, -26509, -27666, + -28714, -29649, -30466, -31164, -31738, -32187, + -32509, -32703, -32760 +}; + +/*-----------------------------------------------------* + | Tables for pitch related routines . | + -----------------------------------------------------*/ + +/* 1/3 resolution interpolation filter (-3 dB at 3600 Hz) in Q15 */ + +Word16 inter_3l[FIR_SIZE_SYN] = { + 29443, + 25207, 14701, 3143, + -4402, -5850, -2783, + 1211, 3130, 2259, + 0, -1652, -1666, + -464, 756, 1099, + 550, -245, -634, + -451, 0, 308, + 296, 78, -120, + -165, -79, 34, + 91, 70, 0 +}; + + /*Coefficients in floating point + + 0.898517, + 0.769271, 0.448635, 0.095915, + -0.134333, -0.178528, -0.084919, + 0.036952, 0.095533, 0.068936, + -0.000000, -0.050404, -0.050835, + -0.014169, 0.023083, 0.033543, + 0.016774, -0.007466, -0.019340, + -0.013755, 0.000000, 0.009400, + 0.009029, 0.002381, -0.003658, + -0.005027, -0.002405, 0.001050, + 0.002780, 0.002145, 0.000000}; + */ + +/*-----------------------------------------------------* + | Tables for gain related routines . | + -----------------------------------------------------*/ + +/* MA gain prediction coeff ={0.68, 0.58, 0.34, 0.19} in Q13 */ +Word16 g729_pred[4] = { 5571, 4751, 2785, 1556 }; + + +Word16 gbk1[NCODE1][2] = { +/* Q14 Q13 */ + {1, 1516} + , + {1551, 2425} + , + {1831, 5022} + , + {57, 5404} + , + {1921, 9291} + , + {3242, 9949} + , + {356, 14756} + , + {2678, 27162} +}; + +Word16 gbk2[NCODE2][2] = { +/* Q14 Q13 */ + {826, 2005} + , + {1994, 0} + , + {5142, 592} + , + {6160, 2395} + , + {8091, 4861} + , + {9120, 525} + , + {10573, 2966} + , + {11569, 1196} + , + {13260, 3256} + , + {14194, 1630} + , + {15132, 4914} + , + {15161, 14276} + , + {15434, 237} + , + {16112, 3392} + , + {17299, 1861} + , + {18973, 5935} +}; + +Word16 map1[NCODE1] = { + 5, 1, 4, 7, 3, 0, 6, 2 +}; + +Word16 map2[NCODE2] = { + 4, 6, 0, 2, 12, 14, 8, 10, 15, 11, 9, 13, 7, 3, 1, 5 +}; + +/* [0][0] [0][1] [1][0] [1][1] */ +/* Q10 Q14 Q16 Q19 */ +Word16 coef[2][2] = { + {31881, 26416} + , + {31548, 27816} +}; + +/* [0][0] [0][1] [1][0] [1][1] */ +/* Q26 Q30 Q32 Q35 */ +Word32 L_coef[2][2] = { + {2089405952L, 1731217536L} + , + {2067549984L, 1822990272L} +}; + +Word16 thr1[NCODE1 - NCAN1] = { /* Q14 */ + 10808, + 12374, + 19778, + 32567 +}; +Word16 thr2[NCODE2 - NCAN2] = { /* Q15 */ + 14087, + 16188, + 20274, + 21321, + 23525, + 25232, + 27873, + 30542 +}; +Word16 imap1[NCODE1] = { + 5, 1, 7, 4, 2, 0, 6, 3 +}; + +Word16 imap2[NCODE2] = { + 2, 14, 3, 13, 0, 15, 1, 12, 6, 10, 7, 9, 4, 11, 5, 8 +}; + +/*-----------------------------------------------------* + | Tables for routines post_pro() & pre_proc(). | + -----------------------------------------------------*/ + +/* filter coefficients (fc = 100 Hz) */ + +Word16 b100[3] = { 7699, -15398, 7699 }; /* Q13 */ +Word16 a100[3] = { 8192, 15836, -7667 }; /* Q13 */ + +/* filter coefficients (fc = 140 Hz, coeff. b[] is divided by 2) */ + +Word16 b140[3] = { 1899, -3798, 1899 }; /* 1/2 in Q12 */ +Word16 a140[3] = { 4096, 7807, -3733 }; /* Q12 */ + +/*-----------------------------------------------------* + | Tables for routine bits(). | + -----------------------------------------------------*/ + + +Word16 bitsno[PRM_SIZE] = { 1 + NC0_B, /* MA + 1st stage */ + NC1_B * 2, /* 2nd stage */ + 8, 1, 13, 4, 7, /* first subframe */ + 5, 13, 4, 7 +}; /* second subframe */ + + +/*-----------------------------------------------------* + | Table for routine Pow2(). | + -----------------------------------------------------*/ + +Word16 tabpow[33] = { + 16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911, + 20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726, + 25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706, + 31379, 32066, 32767 +}; + +/*-----------------------------------------------------* + | Table for routine Log2(). | + -----------------------------------------------------*/ + +Word16 tablog[33] = { + 0, 1455, 2866, 4236, 5568, 6863, 8124, 9352, 10549, 11716, + 12855, 13967, 15054, 16117, 17156, 18172, 19167, 20142, 21097, 22033, + 22951, 23852, 24735, 25603, 26455, 27291, 28113, 28922, 29716, 30497, + 31266, 32023, 32767 +}; + +/*-----------------------------------------------------* + | Table for routine Inv_sqrt(). | + -----------------------------------------------------*/ + +Word16 tabsqr[49] = { + + 32767, 31790, 30894, 30070, 29309, 28602, 27945, 27330, 26755, 26214, + 25705, 25225, 24770, 24339, 23930, 23541, 23170, 22817, 22479, 22155, + 21845, 21548, 21263, 20988, 20724, 20470, 20225, 19988, 19760, 19539, + 19326, 19119, 18919, 18725, 18536, 18354, 18176, 18004, 17837, 17674, + 17515, 17361, 17211, 17064, 16921, 16782, 16646, 16514, 16384 +}; + +/*-----------------------------------------------------* + | Table for taming procedure test_err. | + -----------------------------------------------------*/ + +Word16 tab_zone[PIT_MAX + L_INTERPOL - 1] = { + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 +}; + +Word16 lsp_old_init[M10] = +{ + 30000, 26000, 21000, 15000, 8000, 0, -8000, -15000, -21000, -26000 +}; + +Word16 freq_prev_reset[M10] = { /* Q13:previous LSP vector(init) */ + 2339, 4679, 7018, 9358, 11698, 14037, 16377, 18717, 21056, 23396 +}; /* PI*(float)(j+1)/(float)(M+1) */ + +Word16 past_qua_en_init [4] = { -14336, -14336, -14336, -14336 }; + + + diff --git a/src/libs/libg729/g729_tab_ld8a.h b/src/libs/libg729/g729_tab_ld8a.h new file mode 100644 index 00000000..295c1cef --- /dev/null +++ b/src/libs/libg729/g729_tab_ld8a.h @@ -0,0 +1,48 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +extern Word16 hamwindow[L_WINDOW]; +extern Word16 lag_h[M10]; +extern Word16 lag_l[M10]; +extern Word16 table[65]; +extern Word16 slope[64]; +extern Word16 table2[64]; +extern Word16 slope_cos[64]; +extern Word16 slope_acos[64]; +extern Word16 lspcb1[NC0][M10]; +extern Word16 lspcb2[NC1][M10]; +extern Word16 fg[2][MA_NP][M10]; +extern Word16 fg_sum[2][M10]; +extern Word16 fg_sum_inv[2][M10]; +extern Word16 grid[GRID_POINTS + 1]; +extern Word16 inter_3l[FIR_SIZE_SYN]; +extern Word16 g729_pred[4]; +extern Word16 gbk1[NCODE1][2]; +extern Word16 gbk2[NCODE2][2]; +extern Word16 map1[NCODE1]; +extern Word16 map2[NCODE2]; +extern Word16 coef[2][2]; +extern Word32 L_coef[2][2]; +extern Word16 thr1[NCODE1 - NCAN1]; +extern Word16 thr2[NCODE2 - NCAN2]; +extern Word16 imap1[NCODE1]; +extern Word16 imap2[NCODE2]; +extern Word16 b100[3]; +extern Word16 a100[3]; +extern Word16 b140[3]; +extern Word16 a140[3]; +extern Word16 bitsno[PRM_SIZE]; +extern Word16 tabpow[33]; +extern Word16 tablog[33]; +extern Word16 tabsqr[49]; +extern Word16 tab_zone[PIT_MAX + L_INTERPOL - 1]; +extern Word16 lsp_old_init [M10]; +extern Word16 freq_prev_reset[M10]; +extern Word16 past_qua_en_init[4]; + diff --git a/src/libs/libg729/g729_taming.cpp b/src/libs/libg729/g729_taming.cpp new file mode 100644 index 00000000..a737914e --- /dev/null +++ b/src/libs/libg729/g729_taming.cpp @@ -0,0 +1,139 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/************************************************************************** + * Taming functions. * + **************************************************************************/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_oper_32b.h" +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" +#include "g729_taming.h" + +void +Init_exc_err (CodState *coder) +{ + Word16 i; + for (i = 0; i < 4; i++) + coder->L_exc_err[i] = 0x00004000L; /* Q14 */ +} + +/************************************************************************** + * routine test_err - computes the accumulated potential error in the * + * adaptive codebook contribution * + **************************************************************************/ + +Word16 +test_err (/* (o) flag set to 1 if taming is necessary */ + CodState *coder, + Word16 T0, /* (i) integer part of pitch delay */ + Word16 T0_frac /* (i) fractional part of pitch delay */ + ) +{ + Word16 i, t1, zone1, zone2, flag; + Word32 L_maxloc, L_acc; + + if (T0_frac > 0) { + t1 = add (T0, 1); + } + else { + t1 = T0; + } + + i = sub (t1, (L_SUBFR + L_INTER10)); + if (i < 0) { + i = 0; + } + zone1 = tab_zone[i]; + + i = add (t1, (L_INTER10 - 2)); + zone2 = tab_zone[i]; + + L_maxloc = -1L; + flag = 0; + for (i = zone2; i >= zone1; i--) { + L_acc = L_sub (coder->L_exc_err[i], L_maxloc); + if (L_acc > 0L) { + L_maxloc = coder->L_exc_err[i]; + } + } + L_acc = L_sub (L_maxloc, L_THRESH_ERR); + if (L_acc > 0L) { + flag = 1; + } + + return (flag); +} + +/************************************************************************** + *routine update_exc_err - maintains the memory used to compute the error * + * function due to an adaptive codebook mismatch between encoder and * + * decoder * + **************************************************************************/ + +void +update_exc_err (CodState *coder, + Word16 gain_pit, /* (i) pitch gain */ + Word16 T0 /* (i) integer part of pitch delay */ + ) +{ + + Word16 i, zone1, zone2, n; + Word32 L_worst, L_temp, L_acc; + Word16 hi, lo; + + L_worst = -1L; + n = sub (T0, L_SUBFR); + + if (n < 0) { + L_Extract (coder->L_exc_err[0], &hi, &lo); + L_temp = Mpy_32_16 (hi, lo, gain_pit); + L_temp = L_shl (L_temp, 1); + L_temp = L_add (0x00004000L, L_temp); + L_acc = L_sub (L_temp, L_worst); + if (L_acc > 0L) { + L_worst = L_temp; + } + L_Extract (L_temp, &hi, &lo); + L_temp = Mpy_32_16 (hi, lo, gain_pit); + L_temp = L_shl (L_temp, 1); + L_temp = L_add (0x00004000L, L_temp); + L_acc = L_sub (L_temp, L_worst); + if (L_acc > 0L) { + L_worst = L_temp; + } + } + + else { + + zone1 = tab_zone[n]; + + i = sub (T0, 1); + zone2 = tab_zone[i]; + + for (i = zone1; i <= zone2; i++) { + L_Extract (coder->L_exc_err[i], &hi, &lo); + L_temp = Mpy_32_16 (hi, lo, gain_pit); + L_temp = L_shl (L_temp, 1); + L_temp = L_add (0x00004000L, L_temp); + L_acc = L_sub (L_temp, L_worst); + if (L_acc > 0L) + L_worst = L_temp; + } + } + + for (i = 3; i >= 1; i--) { + coder->L_exc_err[i] = coder->L_exc_err[i - 1]; + } + coder->L_exc_err[0] = L_worst; + + return; +} diff --git a/src/libs/libg729/g729_taming.h b/src/libs/libg729/g729_taming.h new file mode 100644 index 00000000..b132dc6d --- /dev/null +++ b/src/libs/libg729/g729_taming.h @@ -0,0 +1,22 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*--------------------------------------------------------------------------* + * Constants and prototypes for taming procedure. * + *--------------------------------------------------------------------------*/ + +#define GPCLIP 15564 /* Maximum pitch gain if taming is needed Q14 */ +#define GPCLIP2 481 /* Maximum pitch gain if taming is needed Q9 */ +#define GP0999 16383 /* Maximum pitch gain if taming is needed */ +#define L_THRESH_ERR 983040000L /* Error threshold taming 16384. * 60000. */ + +void Init_exc_err (CodState *coder); +void update_exc_err (CodState *coder, Word16 gain_pit, Word16 t0); +Word16 test_err (CodState *coder, Word16 t0, Word16 t0_frac); + diff --git a/src/libs/libg729/g729_typedef.h b/src/libs/libg729/g729_typedef.h new file mode 100644 index 00000000..af45e06a --- /dev/null +++ b/src/libs/libg729/g729_typedef.h @@ -0,0 +1,16 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/* + Types definitions +*/ + +typedef short Word16; +typedef int Word32; +typedef int Flag; diff --git a/src/libs/libg729/g729_util.cpp b/src/libs/libg729/g729_util.cpp new file mode 100644 index 00000000..48ede32b --- /dev/null +++ b/src/libs/libg729/g729_util.cpp @@ -0,0 +1,145 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------------------------------------------* + * Function Set zero() * + * ~~~~~~~~~~ * + * Set vector x[] to zero * + *-------------------------------------------------------------------*/ + +#include "g729_typedef.h" +#include "g729_basic_op.h" +#include "g729_ld8a.h" +#include "g729_tab_ld8a.h" + +void +Set_zero (Word16 x[], Word16 L) +{ + Word16 i; + + for (i = 0; i < L; i++) + x[i] = 0; + + return; +} + +/*-------------------------------------------------------------------* + * Function Copy: * + * ~~~~~ * + * Copy vector x[] to y[] * + *-------------------------------------------------------------------*/ + +void +Copy (Word16 x[], Word16 y[], Word16 L) +{ + Word16 i; + + for (i = 0; i < L; i++) + y[i] = x[i]; + + return; +} + +/* Random generator */ + +Word16 +Random_16 (Word16* seed) +{ + /* seed = seed*31821 + 13849; */ + *seed = extract_l (L_add (L_shr (L_mult (*seed, 31821), 1), 13849L)); + + return (*seed); +} + + +/*---------------------------------------------------------------------------- + * Store_Param - converts encoder parameter vector into frame + * Restore_Params - converts serial received frame to encoder parameter vector + * + * The transmitted parameters are: + * + * LPC: 1st codebook 7+1 bit + * 2nd codebook 5+5 bit + * + * 1st subframe: + * pitch period 8 bit + * parity check on 1st period 1 bit + * codebook index1 (positions) 13 bit + * codebook index2 (signs) 4 bit + * pitch and codebook gains 4+3 bit + * + * 2nd subframe: + * pitch period (relative) 5 bit + * codebook index1 (positions) 13 bit + * codebook index2 (signs) 4 bit + * pitch and codebook gains 4+3 bit + *---------------------------------------------------------------------------- + */ + + +void +Store_Params(Word16 * parm, void *to) +{ + int i, j; + unsigned char mask, *to_b; + Word16 value, val_mask; + + to_b = (unsigned char *)to; + mask = 0x80; + for (i = 0; i < PRM_SIZE; i++) { + value = parm[i]; + val_mask = 1 << (bitsno[i] - 1); + for (j = 0; j < bitsno[i]; j++) { + + if (value & val_mask) + *to_b |= mask; + else + *to_b &= ~mask; + + value = value << 1; + mask = mask >> 1; + + if (mask == 0) { + mask = 0x80; + to_b++; + } + } + } + return; +} + +void Restore_Params(const void *from, Word16 * parm) +{ + int i, j; + unsigned char mask, *from_b; + Word16 value; + + mask = 0x80; + from_b = (unsigned char *)from; + + for (i = 0; i < PRM_SIZE; i++) { + value = 0; + for (j = 0; j < bitsno[i]; j++) { + + value = value << 1; + + if (mask & (*from_b)) + value += 1; + + mask = mask >> 1; + if (mask == 0) { + mask = 0x80; + from_b++; + } + } + parm[i] = value; + } + return; +} + diff --git a/src/libs/libg729/g729_util.h b/src/libs/libg729/g729_util.h new file mode 100644 index 00000000..a89536b9 --- /dev/null +++ b/src/libs/libg729/g729_util.h @@ -0,0 +1,22 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*--------------------------------------------------------------------------* + * Prototypes for auxiliary functions. * + *--------------------------------------------------------------------------*/ + +void Copy (Word16 x[], Word16 y[], Word16 L); + +void Set_zero (Word16 x[], Word16 L); + +Word16 Random_16 (Word16 *seed); + +void Store_Params(Word16 * parm, void *to); + +void Restore_Params(const void *from, Word16 * parm); diff --git a/src/libs/libg729/gainpred.c b/src/libs/libg729/gainpred.c new file mode 100644 index 00000000..8d8943a4 --- /dev/null +++ b/src/libs/libg729/gainpred.c @@ -0,0 +1,159 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*---------------------------------------------------------------------------* + * Gain_predict() : make gcode0(exp_gcode0) * + * Gain_update() : update table of past quantized energies. * + * Gain_update_erasure() : update table of past quantized energies. * + * (frame erasure) * + * This function is used both Coder and Decoder. * + *---------------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" +#include "tab_ld8a.h" +#include "oper_32b.h" + +/*---------------------------------------------------------------------------* + * Function Gain_predict * + * ~~~~~~~~~~~~~~~~~~~~~~ * + * MA prediction is performed on the innovation energy (in dB with mean * + * removed). * + *---------------------------------------------------------------------------*/ +void +Gain_predict (Word16 past_qua_en[], /* (i) Q10 :Past quantized energies */ + Word16 code[], /* (i) Q13 :Innovative vector. */ + Word16 L_subfr, /* (i) :Subframe length. */ + Word16 * gcode0, /* (o) Qxx :Predicted codebook gain */ + Word16 * exp_gcode0 /* (o) :Q-Format(gcode0) */ + ) +{ + Word16 i, exp, frac; + Word32 L_tmp; + + /*-------------------------------* + * Energy coming from code * + *-------------------------------*/ + + L_tmp = 0; + for (i = 0; i < L_subfr; i++) + L_tmp = L_mac (L_tmp, code[i], code[i]); + + /*-----------------------------------------------------------------* + * Compute: means_ener - 10log10(ener_code/ L_sufr) * + * Note: mean_ener change from 36 dB to 30 dB because input/2 * + * * + * = 30.0 - 10 log10( ener_code / lcode) + 10log10(2^27) * + * !!ener_code in Q27!! * + * = 30.0 - 3.0103 * log2(ener_code) + 10log10(40) + 10log10(2^27) * + * = 30.0 - 3.0103 * log2(ener_code) + 16.02 + 81.278 * + * = 127.298 - 3.0103 * log2(ener_code) * + *-----------------------------------------------------------------*/ + + Log2 (L_tmp, &exp, &frac); /* Q27->Q0 ^Q0 ^Q15 */ + L_tmp = Mpy_32_16 (exp, frac, -24660); /* Q0 Q15 Q13 -> ^Q14 */ + /* hi:Q0+Q13+1 */ + /* lo:Q15+Q13-15+1 */ + /* -24660[Q13]=-3.0103 */ + L_tmp = L_mac (L_tmp, 32588, 32); /* 32588*32[Q14]=127.298 */ + + /*-----------------------------------------------------------------* + * Compute gcode0. * + * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener * + *-----------------------------------------------------------------*/ + + L_tmp = L_shl (L_tmp, 10); /* From Q14 to Q24 */ + for (i = 0; i < 4; i++) + L_tmp = L_mac (L_tmp, pred[i], past_qua_en[i]); /* Q13*Q10 ->Q24 */ + + *gcode0 = extract_h (L_tmp); /* From Q24 to Q8 */ + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) * + * = pow(2, 3.3219*gcode0/20) * + * = pow(2, 0.166*gcode0) * + *-----------------------------------------------------------------*/ + + L_tmp = L_mult (*gcode0, 5439); /* *0.166 in Q15, result in Q24 */ + L_tmp = L_shr (L_tmp, 8); /* From Q24 to Q16 */ + L_Extract (L_tmp, &exp, &frac); /* Extract exponent of gcode0 */ + + *gcode0 = extract_l (Pow2 (14, frac)); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16768 < Pow2() <= 32767 */ + *exp_gcode0 = sub (14, exp); +} + + +/*---------------------------------------------------------------------------* + * Function Gain_update * + * ~~~~~~~~~~~~~~~~~~~~~~ * + * update table of past quantized energies * + *---------------------------------------------------------------------------*/ +void +Gain_update (Word16 past_qua_en[], /* (io) Q10 :Past quantized energies */ + Word32 L_gbk12 /* (i) Q13 : gbk1[indice1][1]+gbk2[indice2][1] */ + ) +{ + Word16 i, tmp; + Word16 exp, frac; + Word32 L_acc; + + for (i = 3; i > 0; i--) { + past_qua_en[i] = past_qua_en[i - 1]; /* Q10 */ + } + /*----------------------------------------------------------------------* + * -- past_qua_en[0] = 20*log10(gbk1[index1][1]+gbk2[index2][1]); -- * + * 2 * 10 log10( gbk1[index1][1]+gbk2[index2][1] ) * + * = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] ) * + * = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] ) * + * 24660:Q12(6.0205) * + *----------------------------------------------------------------------*/ + + Log2 (L_gbk12, &exp, &frac); /* L_gbk12:Q13 */ + L_acc = L_Comp (sub (exp, 13), frac); /* L_acc:Q16 */ + tmp = extract_h (L_shl (L_acc, 13)); /* tmp:Q13 */ + past_qua_en[0] = mult (tmp, 24660); /* past_qua_en[]:Q10 */ +} + + +/*---------------------------------------------------------------------------* + * Function Gain_update_erasure * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * update table of past quantized energies (frame erasure) * + *---------------------------------------------------------------------------* + * av_pred_en = 0.0; * + * for (i = 0; i < 4; i++) * + * av_pred_en += past_qua_en[i]; * + * av_pred_en = av_pred_en*0.25 - 4.0; * + * if (av_pred_en < -14.0) av_pred_en = -14.0; * + *---------------------------------------------------------------------------*/ +void +Gain_update_erasure (Word16 past_qua_en[] /* (i) Q10 :Past quantized energies */ + ) +{ + Word16 i, av_pred_en; + Word32 L_tmp; + + L_tmp = 0; /* Q10 */ + for (i = 0; i < 4; i++) + L_tmp = L_add (L_tmp, L_deposit_l (past_qua_en[i])); + av_pred_en = extract_l (L_shr (L_tmp, 2)); + av_pred_en = sub (av_pred_en, 4096); /* Q10 */ + + if (sub (av_pred_en, -14336) < 0) { + av_pred_en = -14336; /* 14336:14[Q10] */ + } + + for (i = 3; i > 0; i--) { + past_qua_en[i] = past_qua_en[i - 1]; + } + past_qua_en[0] = av_pred_en; +} diff --git a/src/libs/libg729/oper_32b.c b/src/libs/libg729/oper_32b.c new file mode 100644 index 00000000..48e29ef1 --- /dev/null +++ b/src/libs/libg729/oper_32b.c @@ -0,0 +1,228 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" + +/*___________________________________________________________________________ + | | + | This file contains operations in double precision. | + | These operations are not standard double precision operations. | + | They are used where single precision is not enough but the full 32 bits | + | precision is not necessary. For example, the function Div_32() has a | + | 24 bits precision which is enough for our purposes. | + | | + | The double precision numbers use a special representation: | + | | + | L_32 = hi<<16 + lo<<1 | + | | + | L_32 is a 32 bit integer. | + | hi and lo are 16 bit signed integers. | + | As the low part also contains the sign, this allows fast multiplication. | + | | + | 0x8000 0000 <= L_32 <= 0x7fff fffe. | + | | + | We will use DPF (Double Precision Format )in this file to specify | + | this special format. | + |___________________________________________________________________________| +*/ + +/*___________________________________________________________________________ + | | + | Function L_Extract() | + | | + | Extract from a 32 bit integer two 16 bit DPF. | + | | + | Arguments: | + | | + | L_32 : 32 bit integer. | + | 0x8000 0000 <= L_32 <= 0x7fff ffff. | + | hi : b16 to b31 of L_32 | + | lo : (L_32 - hi<<16)>>1 | + |___________________________________________________________________________| +*/ + +void +L_Extract (Word32 L_32, Word16 * hi, Word16 * lo) +{ + *hi = extract_h (L_32); + *lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384)); /* lo = L_32>>1 */ + return; +} + +/*___________________________________________________________________________ + | | + | Function L_Comp() | + | | + | Compose from two 16 bit DPF a 32 bit integer. | + | | + | L_32 = hi<<16 + lo<<1 | + | | + | Arguments: | + | | + | hi msb | + | lo lsf (with sign) | + | | + | Return Value : | + | | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_32 <= 0x7fff fff0. | + | | + |___________________________________________________________________________| +*/ + +Word32 +L_Comp (Word16 hi, Word16 lo) +{ + Word32 L_32; + + L_32 = L_deposit_h (hi); + return (L_mac (L_32, lo, 1)); /* = hi<<16 + lo<<1 */ +} + +/*___________________________________________________________________________ + | Function Mpy_32() | + | | + | Multiply two 32 bit integers (DPF). The result is divided by 2**31 | + | | + | L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 | + | | + | This operation can also be viewed as the multiplication of two Q31 | + | number and the result is also in Q31. | + | | + | Arguments: | + | | + | hi1 hi part of first number | + | lo1 lo part of first number | + | hi2 hi part of second number | + | lo2 lo part of second number | + | | + |___________________________________________________________________________| +*/ + +Word32 +Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2) +{ + Word32 L_32; + + L_32 = L_mult (hi1, hi2); + L_32 = L_mac (L_32, mult (hi1, lo2), 1); + L_32 = L_mac (L_32, mult (lo1, hi2), 1); + + return (L_32); +} + +/*___________________________________________________________________________ + | Function Mpy_32_16() | + | | + | Multiply a 16 bit integer by a 32 bit (DPF). The result is divided | + | by 2**15 | + | | + | This operation can also be viewed as the multiplication of a Q31 | + | number by a Q15 number, the result is in Q31. | + | | + | L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 | + | | + | Arguments: | + | | + | hi hi part of 32 bit number. | + | lo lo part of 32 bit number. | + | n 16 bit number. | + | | + |___________________________________________________________________________| +*/ + +Word32 +Mpy_32_16 (Word16 hi, Word16 lo, Word16 n) +{ + Word32 L_32; + + L_32 = L_mult (hi, n); + L_32 = L_mac (L_32, mult (lo, n), 1); + + return (L_32); +} + +/*___________________________________________________________________________ + | | + | Function Name : Div_32 | + | | + | Purpose : | + | Fractional integer division of two 32 bit numbers. | + | L_num / L_denom. | + | L_num and L_denom must be positive and L_num < L_denom. | + | L_denom = denom_hi<<16 + denom_lo<<1 | + | denom_hi is a normalize number. | + | The result is in Q30. | + | | + | Inputs : | + | | + | L_num | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x0000 0000 < L_num < L_denom | + | | + | L_denom = denom_hi<<16 + denom_lo<<1 (DPF) | + | | + | denom_hi | + | 16 bit positive normalized integer whose value falls in the | + | range : 0x4000 < hi < 0x7fff | + | denom_lo | + | 16 bit positive integer whose value falls in the | + | range : 0 < lo < 0x7fff | + | | + | Return Value : | + | | + | L_div | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x0000 0000 <= L_div <= 0x7fff ffff. | + | It's a Q31 value | + | | + | Algorithm: | + | | + | - find = 1/L_denom. | + | First approximation: approx = 1 / denom_hi | + | 1/L_denom = approx * (2.0 - L_denom * approx ) | + | | + | - result = L_num * (1/L_denom) | + |___________________________________________________________________________| +*/ + +Word32 +Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo) +{ + Word16 approx, hi, lo, n_hi, n_lo; + Word32 L_32; + + + /* First approximation: 1 / L_denom = 1/denom_hi */ + + approx = div_s ((Word16) 0x3fff, denom_hi); /* result in Q14 */ + /* Note: 3fff = 0.5 in Q15 */ + + /* 1/L_denom = approx * (2.0 - L_denom * approx) */ + + L_32 = Mpy_32_16 (denom_hi, denom_lo, approx); /* result in Q30 */ + + + L_32 = L_sub ((Word32) 0x7fffffffL, L_32); /* result in Q30 */ + + L_Extract (L_32, &hi, &lo); + + L_32 = Mpy_32_16 (hi, lo, approx); /* = 1/L_denom in Q29 */ + + /* L_num * (1/L_denom) */ + + L_Extract (L_32, &hi, &lo); + L_Extract (L_num, &n_hi, &n_lo); + L_32 = Mpy_32 (n_hi, n_lo, hi, lo); /* result in Q29 */ + L_32 = L_shl (L_32, 2); /* From Q29 to Q31 */ + + return (L_32); +} diff --git a/src/libs/libg729/p_parity.c b/src/libs/libg729/p_parity.c new file mode 100644 index 00000000..34a963af --- /dev/null +++ b/src/libs/libg729/p_parity.c @@ -0,0 +1,63 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------* + * Parity_pitch - compute parity bit for first 6 MSBs * + *------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" + +Word16 +Parity_Pitch ( /* output: parity bit (XOR of 6 MSB bits) */ + Word16 pitch_index /* input : index for which parity to compute */ + ) +{ + Word16 temp, sum, i, bit; + + temp = shr (pitch_index, 1); + + sum = 1; + for (i = 0; i <= 5; i++) { + temp = shr (temp, 1); + bit = temp & (Word16) 1; + sum = add (sum, bit); + } + sum = sum & (Word16) 1; + + + return sum; +} + +/*--------------------------------------------------------------------* + * check_parity_pitch - check parity of index with transmitted parity * + *--------------------------------------------------------------------*/ + +Word16 +Check_Parity_Pitch ( /* output: 0 = no error, 1= error */ + Word16 pitch_index, /* input : index of parameter */ + Word16 parity /* input : parity bit */ + ) +{ + Word16 temp, sum, i, bit; + + temp = shr (pitch_index, 1); + + sum = 1; + for (i = 0; i <= 5; i++) { + temp = shr (temp, 1); + bit = temp & (Word16) 1; + sum = add (sum, bit); + } + sum = add (sum, parity); + sum = sum & (Word16) 1; + + return sum; +} diff --git a/src/libs/libg729/pitch_a.c b/src/libs/libg729/pitch_a.c new file mode 100644 index 00000000..fc59209c --- /dev/null +++ b/src/libs/libg729/pitch_a.c @@ -0,0 +1,570 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*---------------------------------------------------------------------------* + * Pitch related functions * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + *---------------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" +#include "ld8a.h" +#include "tab_ld8a.h" +#include "util.h" + +/*---------------------------------------------------------------------------* + * Function Pitch_ol_fast * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * Compute the open loop pitch lag. (fast version) * + * * + *---------------------------------------------------------------------------*/ + + +Word16 +Pitch_ol_fast ( /* output: open loop pitch lag */ + Word16 signal[], /* input : signal used to compute the open loop pitch */ + /* signal[-pit_max] to signal[-1] should be known */ + Word16 pit_max, /* input : maximum pitch lag */ + Word16 L_frame /* input : length of frame to compute pitch */ + ) +{ + Flag Overflow; + Word16 i, j; + Word16 max1, max2, max3; + Word16 max_h, max_l, ener_h, ener_l; + Word16 T1, T2, T3; + Word16 *p, *p1; + Word32 max, sum, L_temp; + + /* Scaled signal */ + + Word16 scaled_signal[L_FRAME + PIT_MAX]; + Word16 *scal_sig; + + scal_sig = &scaled_signal[pit_max]; + + /*--------------------------------------------------------* + * Verification for risk of overflow. * + *--------------------------------------------------------*/ + + Overflow = 0; + sum = 0; + + for (i = -pit_max; i < L_frame; i += 2) + sum = L_mac_o (sum, signal[i], signal[i], &Overflow); + + /*--------------------------------------------------------* + * Scaling of input signal. * + * * + * if Overflow -> scal_sig[i] = signal[i]>>3 * + * else if sum < 1^20 -> scal_sig[i] = signal[i]<<3 * + * else -> scal_sig[i] = signal[i] * + *--------------------------------------------------------*/ + + if (Overflow == 1) { + for (i = -pit_max; i < L_frame; i++) { + scal_sig[i] = shr (signal[i], 3); + } + } + else { + L_temp = L_sub (sum, (Word32) 1048576L); + if (L_temp < (Word32) 0) { /* if (sum < 2^20) */ + for (i = -pit_max; i < L_frame; i++) { + scal_sig[i] = shl (signal[i], 3); + } + } + else { + for (i = -pit_max; i < L_frame; i++) { + scal_sig[i] = signal[i]; + } + } + } + + /*--------------------------------------------------------------------* + * The pitch lag search is divided in three sections. * + * Each section cannot have a pitch multiple. * + * We find a maximum for each section. * + * We compare the maxima of each section by favoring small lag. * + * * + * First section: lag delay = 20 to 39 * + * Second section: lag delay = 40 to 79 * + * Third section: lag delay = 80 to 143 * + *--------------------------------------------------------------------*/ + + /* First section */ + + max = MIN_32; + T1 = 20; /* Only to remove warning from some compilers */ + for (i = 20; i < 40; i++) { + p = scal_sig; + p1 = &scal_sig[-i]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T1 = i; + } + } + + /* compute energy of maximum */ + + sum = 1; /* to avoid division by zero */ + p = &scal_sig[-T1]; + for (i = 0; i < L_frame; i += 2, p += 2) + sum = L_mac (sum, *p, *p); + + /* max1 = max/sqrt(energy) */ + /* This result will always be on 16 bits !! */ + + sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */ + L_Extract (max, &max_h, &max_l); + L_Extract (sum, &ener_h, &ener_l); + sum = Mpy_32 (max_h, max_l, ener_h, ener_l); + max1 = extract_l (sum); + + /* Second section */ + + max = MIN_32; + T2 = 40; /* Only to remove warning from some compilers */ + for (i = 40; i < 80; i++) { + p = scal_sig; + p1 = &scal_sig[-i]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T2 = i; + } + } + + /* compute energy of maximum */ + + sum = 1; /* to avoid division by zero */ + p = &scal_sig[-T2]; + for (i = 0; i < L_frame; i += 2, p += 2) + sum = L_mac (sum, *p, *p); + + /* max2 = max/sqrt(energy) */ + /* This result will always be on 16 bits !! */ + + sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */ + L_Extract (max, &max_h, &max_l); + L_Extract (sum, &ener_h, &ener_l); + sum = Mpy_32 (max_h, max_l, ener_h, ener_l); + max2 = extract_l (sum); + + /* Third section */ + + max = MIN_32; + T3 = 80; /* Only to remove warning from some compilers */ + for (i = 80; i < 143; i += 2) { + p = scal_sig; + p1 = &scal_sig[-i]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T3 = i; + } + } + + /* Test around max3 */ + + i = T3; + p = scal_sig; + p1 = &scal_sig[-(i + 1)]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T3 = i + (Word16) 1; + } + + p = scal_sig; + p1 = &scal_sig[-(i - 1)]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T3 = i - (Word16) 1; + } + + /* compute energy of maximum */ + + sum = 1; /* to avoid division by zero */ + p = &scal_sig[-T3]; + for (i = 0; i < L_frame; i += 2, p += 2) + sum = L_mac (sum, *p, *p); + + /* max1 = max/sqrt(energy) */ + /* This result will always be on 16 bits !! */ + + sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */ + L_Extract (max, &max_h, &max_l); + L_Extract (sum, &ener_h, &ener_l); + sum = Mpy_32 (max_h, max_l, ener_h, ener_l); + max3 = extract_l (sum); + + /*-----------------------* + * Test for multiple. * + *-----------------------*/ + + /* if( abs(T2*2 - T3) < 5) */ + /* max2 += max3 * 0.25; */ + + i = sub (shl (T2, 1), T3); + j = sub (abs_s (i), 5); + if (j < 0) + max2 = add (max2, shr (max3, 2)); + + /* if( abs(T2*3 - T3) < 7) */ + /* max2 += max3 * 0.25; */ + + i = add (i, T2); + j = sub (abs_s (i), 7); + if (j < 0) + max2 = add (max2, shr (max3, 2)); + + /* if( abs(T1*2 - T2) < 5) */ + /* max1 += max2 * 0.20; */ + + i = sub (shl (T1, 1), T2); + j = sub (abs_s (i), 5); + if (j < 0) + max1 = add (max1, mult (max2, 6554)); + + /* if( abs(T1*3 - T2) < 7) */ + /* max1 += max2 * 0.20; */ + + i = add (i, T1); + j = sub (abs_s (i), 7); + if (j < 0) + max1 = add (max1, mult (max2, 6554)); + + /*--------------------------------------------------------------------* + * Compare the 3 sections maxima. * + *--------------------------------------------------------------------*/ + + if (sub (max1, max2) < 0) { + max1 = max2; + T1 = T2; + } + if (sub (max1, max3) < 0) { + T1 = T3; + } + + return T1; +} + + + + +/*--------------------------------------------------------------------------* + * Function Dot_Product() * + * ~~~~~~~~~~~~~~~~~~~~~~ * + *--------------------------------------------------------------------------*/ + +Word32 +Dot_Product ( /* (o) :Result of scalar product. */ + Word16 x[], /* (i) :First vector. */ + Word16 y[], /* (i) :Second vector. */ + Word16 lg /* (i) :Number of point. */ + ) +{ + Word16 i; + Word32 sum; + + sum = 0; + for (i = 0; i < lg; i++) + sum = L_mac (sum, x[i], y[i]); + + return sum; +} + +/*--------------------------------------------------------------------------* + * Function Pitch_fr3_fast() * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * Fast version of the pitch close loop. * + *--------------------------------------------------------------------------*/ + +Word16 +Pitch_fr3_fast ( /* (o) : pitch period. */ + Word16 exc[], /* (i) : excitation buffer */ + Word16 xn[], /* (i) : target vector */ + Word16 h[], /* (i) Q12 : impulse response of filters. */ + Word16 L_subfr, /* (i) : Length of subframe */ + Word16 t0_min, /* (i) : minimum value in the searched range. */ + Word16 t0_max, /* (i) : maximum value in the searched range. */ + Word16 i_subfr, /* (i) : indicator for first subframe. */ + Word16 * pit_frac /* (o) : chosen fraction. */ + ) +{ + Word16 t, t0; + Word16 Dn[L_SUBFR]; + Word16 exc_tmp[L_SUBFR]; + Word32 max, corr, L_temp; + + /*-----------------------------------------------------------------* + * Compute correlation of target vector with impulse response. * + *-----------------------------------------------------------------*/ + + Cor_h_X (h, xn, Dn); + + /*-----------------------------------------------------------------* + * Find maximum integer delay. * + *-----------------------------------------------------------------*/ + + max = MIN_32; + t0 = t0_min; /* Only to remove warning from some compilers */ + + for (t = t0_min; t <= t0_max; t++) { + corr = Dot_Product (Dn, &exc[-t], L_subfr); + L_temp = L_sub (corr, max); + if (L_temp > 0) { + max = corr; + t0 = t; + } + } + + /*-----------------------------------------------------------------* + * Test fractions. * + *-----------------------------------------------------------------*/ + + /* Fraction 0 */ + + Pred_lt_3 (exc, t0, 0, L_subfr); + max = Dot_Product (Dn, exc, L_subfr); + *pit_frac = 0; + + /* If first subframe and lag > 84 do not search fractional pitch */ + + if ((i_subfr == 0) && (sub (t0, 84) > 0)) + return t0; + + Copy (exc, exc_tmp, L_subfr); + + /* Fraction -1/3 */ + + Pred_lt_3 (exc, t0, -1, L_subfr); + corr = Dot_Product (Dn, exc, L_subfr); + L_temp = L_sub (corr, max); + if (L_temp > 0) { + max = corr; + *pit_frac = -1; + Copy (exc, exc_tmp, L_subfr); + } + + /* Fraction +1/3 */ + + Pred_lt_3 (exc, t0, 1, L_subfr); + corr = Dot_Product (Dn, exc, L_subfr); + L_temp = L_sub (corr, max); + if (L_temp > 0) { + max = corr; + *pit_frac = 1; + } + else + Copy (exc_tmp, exc, L_subfr); + + return t0; +} + + +/*---------------------------------------------------------------------* + * Function G_pitch: * + * ~~~~~~~~ * + *---------------------------------------------------------------------* + * Compute correlations and to use in gains quantizer. * + * Also compute the gain of pitch. Result in Q14 * + * if (gain < 0) gain =0 * + * if (gain >1.2) gain =1.2 * + *---------------------------------------------------------------------*/ + + +Word16 +G_pitch ( /* (o) Q14 : Gain of pitch lag saturated to 1.2 */ + Word16 xn[], /* (i) : Pitch target. */ + Word16 y1[], /* (i) : Filtered adaptive codebook. */ + Word16 g_coeff[], /* (i) : Correlations need for gain quantization. */ + Word16 L_subfr /* (i) : Length of subframe. */ + ) +{ + Flag Overflow; + Word16 i; + Word16 xy, yy, exp_xy, exp_yy, gain; + Word32 s; + + Word16 scaled_y1[L_SUBFR]; + + /* divide "y1[]" by 4 to avoid overflow */ + + for (i = 0; i < L_subfr; i++) + scaled_y1[i] = shr (y1[i], 2); + + /* Compute scalar product */ + + Overflow = 0; + s = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_subfr; i++) + s = L_mac_o (s, y1[i], y1[i], &Overflow); + + if (Overflow == 0) { + exp_yy = norm_l (s); + yy = wround (L_shl (s, exp_yy)); + } + else { + s = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_subfr; i++) + s = L_mac (s, scaled_y1[i], scaled_y1[i]); + exp_yy = norm_l (s); + yy = wround (L_shl (s, exp_yy)); + exp_yy = sub (exp_yy, 4); + } + + /* Compute scalar product */ + + Overflow = 0; + s = 0; + for (i = 0; i < L_subfr; i++) + s = L_mac_o (s, xn[i], y1[i], &Overflow); + + if (Overflow == 0) { + exp_xy = norm_l (s); + xy = wround (L_shl (s, exp_xy)); + } + else { + s = 0; + for (i = 0; i < L_subfr; i++) + s = L_mac (s, xn[i], scaled_y1[i]); + exp_xy = norm_l (s); + xy = wround (L_shl (s, exp_xy)); + exp_xy = sub (exp_xy, 2); + } + + g_coeff[0] = yy; + g_coeff[1] = sub (15, exp_yy); + g_coeff[2] = xy; + g_coeff[3] = sub (15, exp_xy); + + /* If (xy <= 0) gain = 0 */ + + + if (xy <= 0) { + g_coeff[3] = -15; /* Force exp_xy to -15 = (15-30) */ + return ((Word16) 0); + } + + /* compute gain = xy/yy */ + + xy = shr (xy, 1); /* Be sure xy < yy */ + gain = div_s (xy, yy); + + i = sub (exp_xy, exp_yy); + gain = shr (gain, i); /* saturation if > 1.99 in Q14 */ + + /* if(gain >1.2) gain = 1.2 in Q14 */ + + if (sub (gain, 19661) > 0) { + gain = 19661; + } + + + return (gain); +} + + + +/*----------------------------------------------------------------------* + * Function Enc_lag3 * + * ~~~~~~~~ * + * Encoding of fractional pitch lag with 1/3 resolution. * + *----------------------------------------------------------------------* + * The pitch range for the first subframe is divided as follows: * + * 19 1/3 to 84 2/3 resolution 1/3 * + * 85 to 143 resolution 1 * + * * + * The period in the first subframe is encoded with 8 bits. * + * For the range with fractions: * + * index = (T-19)*3 + frac - 1; where T=[19..85] and frac=[-1,0,1] * + * and for the integer only range * + * index = (T - 85) + 197; where T=[86..143] * + *----------------------------------------------------------------------* + * For the second subframe a resolution of 1/3 is always used, and the * + * search range is relative to the lag in the first subframe. * + * If t0 is the lag in the first subframe then * + * t_min=t0-5 and t_max=t0+4 and the range is given by * + * t_min - 2/3 to t_max + 2/3 * + * * + * The period in the 2nd subframe is encoded with 5 bits: * + * index = (T-(t_min-1))*3 + frac - 1; where T[t_min-1 .. t_max+1] * + *----------------------------------------------------------------------*/ + + +Word16 +Enc_lag3 ( /* output: Return index of encoding */ + Word16 T0, /* input : Pitch delay */ + Word16 T0_frac, /* input : Fractional pitch delay */ + Word16 * T0_min, /* in/out: Minimum search delay */ + Word16 * T0_max, /* in/out: Maximum search delay */ + Word16 pit_min, /* input : Minimum pitch delay */ + Word16 pit_max, /* input : Maximum pitch delay */ + Word16 pit_flag /* input : Flag for 1st subframe */ + ) +{ + Word16 index, i; + + if (pit_flag == 0) { /* if 1st subframe */ + /* encode pitch delay (with fraction) */ + + if (sub (T0, 85) <= 0) { + /* index = t0*3 - 58 + t0_frac */ + i = add (add (T0, T0), T0); + index = add (sub (i, 58), T0_frac); + } + else { + index = add (T0, 112); + } + + /* find T0_min and T0_max for second subframe */ + + *T0_min = sub (T0, 5); + if (sub (*T0_min, pit_min) < 0) { + *T0_min = pit_min; + } + + *T0_max = add (*T0_min, 9); + if (sub (*T0_max, pit_max) > 0) { + *T0_max = pit_max; + *T0_min = sub (*T0_max, 9); + } + } + else { /* if second subframe */ + + + /* i = t0 - t0_min; */ + /* index = i*3 + 2 + t0_frac; */ + i = sub (T0, *T0_min); + i = add (add (i, i), i); + index = add (add (i, 2), T0_frac); + } + + + return index; +} diff --git a/src/libs/libg729/post_pro.c b/src/libs/libg729/post_pro.c new file mode 100644 index 00000000..40b53efd --- /dev/null +++ b/src/libs/libg729/post_pro.c @@ -0,0 +1,84 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------------------------* + * Function Post_Process() * + * * + * Post-processing of output speech. * + * - 2nd order high pass filter with cut off frequency at 100 Hz. * + * - Multiplication by two of output speech with saturation. * + *-----------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" + +#include "ld8a.h" +#include "tab_ld8a.h" + +/*------------------------------------------------------------------------* + * 2nd order high pass filter with cut off frequency at 100 Hz. * + * Designed with SPPACK efi command -40 dB att, 0.25 ri. * + * * + * Algorithm: * + * * + * y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] * + * + a[1]*y[i-1] + a[2]*y[i-2]; * + * * + * b[3] = {0.93980581E+00, -0.18795834E+01, 0.93980581E+00}; * + * a[3] = {0.10000000E+01, 0.19330735E+01, -0.93589199E+00}; * + *-----------------------------------------------------------------------*/ + + +/* Initialization of values */ + +void +Init_Post_Process (DecState *decoder) +{ + decoder->y2_hi = 0; + decoder->y2_lo = 0; + decoder->y1_hi = 0; + decoder->y1_lo = 0; + decoder->x0 = 0; + decoder->x1 = 0; +} + + +void +Post_Process (DecState *decoder, + Word16 signal[], /* input/output signal */ + Word16 lg) +{ /* length of signal */ + Word16 i, x2; + Word32 L_tmp; + + for (i = 0; i < lg; i++) { + x2 = decoder->x1; + decoder->x1 = decoder->x0; + decoder->x0 = signal[i]; + + /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */ + /* + a[1]*y[i-1] + a[2] * y[i-2]; */ + + L_tmp = Mpy_32_16 (decoder->y1_hi, decoder->y1_lo, a100[1]); + L_tmp = L_add (L_tmp, Mpy_32_16 (decoder->y2_hi, decoder->y2_lo, a100[2])); + L_tmp = L_mac (L_tmp, decoder->x0, b100[0]); + L_tmp = L_mac (L_tmp, decoder->x1, b100[1]); + L_tmp = L_mac (L_tmp, x2, b100[2]); + L_tmp = L_shl (L_tmp, 2); /* Q29 --> Q31 (Q13 --> Q15) */ + + /* Multiplication by two of output speech with saturation. */ + signal[i] = wround (L_shl (L_tmp, 1)); + + decoder->y2_hi = decoder->y1_hi; + decoder->y2_lo = decoder->y1_lo; + L_Extract (L_tmp, &decoder->y1_hi, &decoder->y1_lo); + } + return; +} diff --git a/src/libs/libg729/pre_proc.c b/src/libs/libg729/pre_proc.c new file mode 100644 index 00000000..001a9b01 --- /dev/null +++ b/src/libs/libg729/pre_proc.c @@ -0,0 +1,85 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------------------------* + * Function Pre_Process() * + * * + * Preprocessing of input speech. * + * - 2nd order high pass filter with cut off frequency at 140 Hz. * + * - Divide input by two. * + *-----------------------------------------------------------------------*/ + + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" + +#include "ld8a.h" +#include "tab_ld8a.h" + + +/*------------------------------------------------------------------------* + * 2nd order high pass filter with cut off frequency at 140 Hz. * + * Designed with SPPACK efi command -40 dB att, 0.25 ri. * + * * + * Algorithm: * + * * + * y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b[2]*x[i-2]/2 * + * + a[1]*y[i-1] + a[2]*y[i-2]; * + * * + * b[3] = {0.92727435E+00, -0.18544941E+01, 0.92727435E+00}; * + * a[3] = {0.10000000E+01, 0.19059465E+01, -0.91140240E+00}; * + * * + * Input are divided by two in the filtering process. * + *-----------------------------------------------------------------------*/ + + +/* Initialization of values */ + +void Init_Pre_Process (CodState *coder) +{ + coder->y2_hi = 0; + coder->y2_lo = 0; + coder->y1_hi = 0; + coder->y1_lo = 0; + coder->x0 = 0; + coder->x1 = 0; +} + + +void +Pre_Process (CodState *coder, + Word16 signal[], /* input/output signal */ + Word16 lg) +{ /* length of signal */ + Word16 i, x2; + Word32 L_tmp; + + for (i = 0; i < lg; i++) { + x2 = coder->x1; + coder->x1 = coder->x0; + coder->x0 = signal[i]; + + /* y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2 */ + /* + a[1]*y[i-1] + a[2] * y[i-2]; */ + + L_tmp = Mpy_32_16 (coder->y1_hi, coder->y1_lo, a140[1]); + L_tmp = L_add (L_tmp, Mpy_32_16 (coder->y2_hi, coder->y2_lo, a140[2])); + L_tmp = L_mac (L_tmp, coder->x0, b140[0]); + L_tmp = L_mac (L_tmp, coder->x1, b140[1]); + L_tmp = L_mac (L_tmp, x2, b140[2]); + L_tmp = L_shl (L_tmp, 3); /* Q28 --> Q31 (Q12 --> Q15) */ + signal[i] = wround (L_tmp); + + coder->y2_hi = coder->y1_hi; + coder->y2_lo = coder->y1_lo; + L_Extract (L_tmp, &coder->y1_hi, &coder->y1_lo); + } + return; +} diff --git a/src/libs/libg729/pred_lt3.c b/src/libs/libg729/pred_lt3.c new file mode 100644 index 00000000..2a0706fe --- /dev/null +++ b/src/libs/libg729/pred_lt3.c @@ -0,0 +1,61 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------------------------------------------* + * Function Pred_lt_3() * + * ~~~~~~~~~~~ * + *-------------------------------------------------------------------* + * Compute the result of long term prediction with fractional * + * interpolation of resolution 1/3. * + * * + * On return exc[0..L_subfr-1] contains the interpolated signal * + * (adaptive codebook excitation) * + *-------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" +#include "tab_ld8a.h" + +void +Pred_lt_3 (Word16 exc[], /* in/out: excitation buffer */ + Word16 T0, /* input : integer pitch lag */ + Word16 frac, /* input : fraction of lag */ + Word16 L_subfr /* input : subframe size */ + ) +{ + Word16 i, j, k; + Word16 *x0, *x1, *x2, *c1, *c2; + Word32 s; + + x0 = &exc[-T0]; + + frac = negate (frac); + if (frac < 0) { + frac = add (frac, UP_SAMP); + x0--; + } + + for (j = 0; j < L_subfr; j++) { + x1 = x0++; + x2 = x0; + c1 = &inter_3l[frac]; + c2 = &inter_3l[sub (UP_SAMP, frac)]; + + s = 0; + for (i = 0, k = 0; i < L_INTER10; i++, k += UP_SAMP) { + s = L_mac (s, x1[-i], c1[k]); + s = L_mac (s, x2[i], c2[k]); + } + + exc[j] = wround (s); + } + + return; +} diff --git a/src/libs/libg729/qua_gain.c b/src/libs/libg729/qua_gain.c new file mode 100644 index 00000000..0488aacd --- /dev/null +++ b/src/libs/libg729/qua_gain.c @@ -0,0 +1,443 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" + +#include "ld8a.h" +#include "tab_ld8a.h" +#include "taming.h" + +void Gbk_presel (Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */ + /* (i) [1] Q2 : unquantized code gain */ + Word16 * cand1, /* (o) : index of best 1st stage vector */ + Word16 * cand2, /* (o) : index of best 2nd stage vector */ + Word16 gcode0 /* (i) Q4 : presearch for gain codebook */ + ); + + +/*---------------------------------------------------------------------------* + * Function Qua_gain * + * ~~~~~~~~~~~~~~~~~~ * + * Inputs: * + * code[] :Innovative codebook. * + * g_coeff[] :Correlations compute for pitch. * + * L_subfr :Subframe length. * + * * + * Outputs: * + * gain_pit :Quantized pitch gain. * + * gain_cod :Quantized code gain. * + * * + * Return: * + * Index of quantization. * + * * + *--------------------------------------------------------------------------*/ +Word16 +Qua_gain (CodState *coder, + Word16 code[], /* (i) Q13 :Innovative vector. */ + Word16 g_coeff[], /* (i) :Correlations -2 */ + /* , -2, 2 */ + Word16 exp_coeff[], /* (i) :Q-Format g_coeff[] */ + Word16 L_subfr, /* (i) :Subframe length. */ + Word16 * gain_pit, /* (o) Q14 :Pitch gain. */ + Word16 * gain_cod, /* (o) Q1 :Code gain. */ + Word16 tameflag /* (i) : set to 1 if taming is needed */ + ) +{ + Word16 i, j, index1, index2; + Word16 cand1, cand2; + Word16 exp, gcode0, exp_gcode0, gcode0_org, e_min; + Word16 nume, denom, inv_denom; + Word16 exp1, exp2, exp_nume, exp_denom, exp_inv_denom, sft, tmp; + Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod; + Word16 coeff[5], coeff_lsf[5]; + Word16 exp_min[5]; + Word32 L_gbk12; + Word32 L_tmp, L_dist_min, L_temp, L_tmp1, L_tmp2, L_acc, L_accb; + Word16 best_gain[2]; + + /* Gain predictor, Past quantized energies = -14.0 in Q10 */ + + + /*---------------------------------------------------* + *- energy due to innovation -* + *- predicted energy -* + *- predicted codebook gain => gcode0[exp_gcode0] -* + *---------------------------------------------------*/ + + Gain_predict (coder->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0); + + /*-----------------------------------------------------------------* + * pre-selection * + *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * calculate best gain * + * * + * tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; * + * best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; * + * best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; * + * gbk_presel(best_gain,&cand1,&cand2,gcode0) ; * + * * + *-----------------------------------------------------------------*/ + + /*-----------------------------------------------------------------* + * tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; * + *-----------------------------------------------------------------*/ + L_tmp1 = L_mult (g_coeff[0], g_coeff[2]); + exp1 = add (add (exp_coeff[0], exp_coeff[2]), 1 - 2); + L_tmp2 = L_mult (g_coeff[4], g_coeff[4]); + exp2 = add (add (exp_coeff[4], exp_coeff[4]), 1); + + if (sub (exp1, exp2) > 0) { + L_tmp = L_sub (L_shr (L_tmp1, sub (exp1, exp2)), L_tmp2); + exp = exp2; + } + else { + L_tmp = L_sub (L_tmp1, L_shr (L_tmp2, sub (exp2, exp1))); + exp = exp1; + } + sft = norm_l (L_tmp); + denom = extract_h (L_shl (L_tmp, sft)); + exp_denom = sub (add (exp, sft), 16); + + inv_denom = div_s (16384, denom); + inv_denom = negate (inv_denom); + exp_inv_denom = sub (14 + 15, exp_denom); + + /*-----------------------------------------------------------------* + * best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; * + *-----------------------------------------------------------------*/ + L_tmp1 = L_mult (g_coeff[2], g_coeff[1]); + exp1 = add (exp_coeff[2], exp_coeff[1]); + L_tmp2 = L_mult (g_coeff[3], g_coeff[4]); + exp2 = add (add (exp_coeff[3], exp_coeff[4]), 1); + + if (sub (exp1, exp2) > 0) { + L_tmp = + L_sub (L_shr (L_tmp1, add (sub (exp1, exp2), 1)), L_shr (L_tmp2, 1)); + exp = sub (exp2, 1); + } + else { + L_tmp = + L_sub (L_shr (L_tmp1, 1), L_shr (L_tmp2, add (sub (exp2, exp1), 1))); + exp = sub (exp1, 1); + } + sft = norm_l (L_tmp); + nume = extract_h (L_shl (L_tmp, sft)); + exp_nume = sub (add (exp, sft), 16); + + sft = sub (add (exp_nume, exp_inv_denom), (9 + 16 - 1)); + L_acc = L_shr (L_mult (nume, inv_denom), sft); + best_gain[0] = extract_h (L_acc); /*-- best_gain[0]:Q9 --*/ + + if (tameflag == 1) { + if (sub (best_gain[0], GPCLIP2) > 0) + best_gain[0] = GPCLIP2; + } + + /*-----------------------------------------------------------------* + * best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; * + *-----------------------------------------------------------------*/ + L_tmp1 = L_mult (g_coeff[0], g_coeff[3]); + exp1 = add (exp_coeff[0], exp_coeff[3]); + L_tmp2 = L_mult (g_coeff[1], g_coeff[4]); + exp2 = add (add (exp_coeff[1], exp_coeff[4]), 1); + + if (sub (exp1, exp2) > 0) { + L_tmp = + L_sub (L_shr (L_tmp1, add (sub (exp1, exp2), 1)), L_shr (L_tmp2, 1)); + exp = sub (exp2, 1); + } + else { + L_tmp = + L_sub (L_shr (L_tmp1, 1), L_shr (L_tmp2, add (sub (exp2, exp1), 1))); + exp = sub (exp1, 1); + } + sft = norm_l (L_tmp); + nume = extract_h (L_shl (L_tmp, sft)); + exp_nume = sub (add (exp, sft), 16); + + sft = sub (add (exp_nume, exp_inv_denom), (2 + 16 - 1)); + L_acc = L_shr (L_mult (nume, inv_denom), sft); + best_gain[1] = extract_h (L_acc); /*-- best_gain[1]:Q2 --*/ + + /*--- Change Q-format of gcode0 ( Q[exp_gcode0] -> Q4 ) ---*/ + if (sub (exp_gcode0, 4) >= 0) { + gcode0_org = shr (gcode0, sub (exp_gcode0, 4)); + } + else { + L_acc = L_deposit_l (gcode0); + L_acc = L_shl (L_acc, sub ((4 + 16), exp_gcode0)); + gcode0_org = extract_h (L_acc); /*-- gcode0_org:Q4 --*/ + } + + /*----------------------------------------------* + * - presearch for gain codebook - * + *----------------------------------------------*/ + + Gbk_presel (best_gain, &cand1, &cand2, gcode0_org); + +/*---------------------------------------------------------------------------* + * * + * Find the best quantizer. * + * * + * dist_min = MAX_32; * + * for ( i=0 ; ipast_qua_en, L_gbk12); + + return (add (map1[index1] * (Word16) NCODE2, map2[index2])); + +} + +/*---------------------------------------------------------------------------* + * Function Gbk_presel * + * ~~~~~~~~~~~~~~~~~~~ * + * - presearch for gain codebook - * + *---------------------------------------------------------------------------*/ +void +Gbk_presel (Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */ + /* (i) [1] Q2 : unquantized code gain */ + Word16 * cand1, /* (o) : index of best 1st stage vector */ + Word16 * cand2, /* (o) : index of best 2nd stage vector */ + Word16 gcode0 /* (i) Q4 : presearch for gain codebook */ + ) +{ + Word16 acc_h; + Word16 sft_x, sft_y; + Word32 L_acc, L_preg, L_cfbg, L_tmp, L_tmp_x, L_tmp_y; + Word32 L_temp; + + /*--------------------------------------------------------------------------* + x = (best_gain[1]-(coef[0][0]*best_gain[0]+coef[1][1])*gcode0) * inv_coef; + *--------------------------------------------------------------------------*/ + L_cfbg = L_mult (coef[0][0], best_gain[0]); /* L_cfbg:Q20 -> !!y */ + L_acc = L_shr (L_coef[1][1], 15); /* L_acc:Q20 */ + L_acc = L_add (L_cfbg, L_acc); + acc_h = extract_h (L_acc); /* acc_h:Q4 */ + L_preg = L_mult (acc_h, gcode0); /* L_preg:Q9 */ + L_acc = L_shl (L_deposit_l (best_gain[1]), 7); /* L_acc:Q9 */ + L_acc = L_sub (L_acc, L_preg); + acc_h = extract_h (L_shl (L_acc, 2)); /* L_acc_h:Q[-5] */ + L_tmp_x = L_mult (acc_h, INV_COEF); /* L_tmp_x:Q15 */ + + /*--------------------------------------------------------------------------* + y = (coef[1][0]*(-coef[0][1]+best_gain[0]*coef[0][0])*gcode0 + -coef[0][0]*best_gain[1]) * inv_coef; + *--------------------------------------------------------------------------*/ + L_acc = L_shr (L_coef[0][1], 10); /* L_acc:Q20 */ + L_acc = L_sub (L_cfbg, L_acc); /* !!x -> L_cfbg:Q20 */ + acc_h = extract_h (L_acc); /* acc_h:Q4 */ + acc_h = mult (acc_h, gcode0); /* acc_h:Q[-7] */ + L_tmp = L_mult (acc_h, coef[1][0]); /* L_tmp:Q10 */ + + L_preg = L_mult (coef[0][0], best_gain[1]); /* L_preg:Q13 */ + L_acc = L_sub (L_tmp, L_shr (L_preg, 3)); /* L_acc:Q10 */ + + acc_h = extract_h (L_shl (L_acc, 2)); /* acc_h:Q[-4] */ + L_tmp_y = L_mult (acc_h, INV_COEF); /* L_tmp_y:Q16 */ + + sft_y = (14 + 4 + 1) - 16; /* (Q[thr1]+Q[gcode0]+1)-Q[L_tmp_y] */ + sft_x = (15 + 4 + 1) - 15; /* (Q[thr2]+Q[gcode0]+1)-Q[L_tmp_x] */ + + if (gcode0 > 0) { + /*-- pre select codebook #1 --*/ + *cand1 = 0; + do { + L_temp = L_sub (L_tmp_y, L_shr (L_mult (thr1[*cand1], gcode0), sft_y)); + if (L_temp > 0L) { + (*cand1) = add (*cand1, 1); + } + else + break; + } while (sub ((*cand1), (NCODE1 - NCAN1)) < 0); + /*-- pre select codebook #2 --*/ + *cand2 = 0; + do { + L_temp = L_sub (L_tmp_x, L_shr (L_mult (thr2[*cand2], gcode0), sft_x)); + if (L_temp > 0L) { + (*cand2) = add (*cand2, 1); + } + else + break; + } while (sub ((*cand2), (NCODE2 - NCAN2)) < 0); + } + else { + /*-- pre select codebook #1 --*/ + *cand1 = 0; + do { + L_temp = L_sub (L_tmp_y, L_shr (L_mult (thr1[*cand1], gcode0), sft_y)); + if (L_temp < 0L) { + (*cand1) = add (*cand1, 1); + } + else + break; + } while (sub ((*cand1), (NCODE1 - NCAN1))); + /*-- pre select codebook #2 --*/ + *cand2 = 0; + do { + L_temp = L_sub (L_tmp_x, L_shr (L_mult (thr2[*cand2], gcode0), sft_x)); + if (L_temp < 0L) { + (*cand2) = add (*cand2, 1); + } + else + break; + } while (sub ((*cand2), (NCODE2 - NCAN2))); + } + + return; +} diff --git a/src/libs/libg729/taming.c b/src/libs/libg729/taming.c new file mode 100644 index 00000000..5853b944 --- /dev/null +++ b/src/libs/libg729/taming.c @@ -0,0 +1,139 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/************************************************************************** + * Taming functions. * + **************************************************************************/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" +#include "ld8a.h" +#include "tab_ld8a.h" +#include "taming.h" + +void +Init_exc_err (CodState *coder) +{ + Word16 i; + for (i = 0; i < 4; i++) + coder->L_exc_err[i] = 0x00004000L; /* Q14 */ +} + +/************************************************************************** + * routine test_err - computes the accumulated potential error in the * + * adaptive codebook contribution * + **************************************************************************/ + +Word16 +test_err (/* (o) flag set to 1 if taming is necessary */ + CodState *coder, + Word16 T0, /* (i) integer part of pitch delay */ + Word16 T0_frac /* (i) fractional part of pitch delay */ + ) +{ + Word16 i, t1, zone1, zone2, flag; + Word32 L_maxloc, L_acc; + + if (T0_frac > 0) { + t1 = add (T0, 1); + } + else { + t1 = T0; + } + + i = sub (t1, (L_SUBFR + L_INTER10)); + if (i < 0) { + i = 0; + } + zone1 = tab_zone[i]; + + i = add (t1, (L_INTER10 - 2)); + zone2 = tab_zone[i]; + + L_maxloc = -1L; + flag = 0; + for (i = zone2; i >= zone1; i--) { + L_acc = L_sub (coder->L_exc_err[i], L_maxloc); + if (L_acc > 0L) { + L_maxloc = coder->L_exc_err[i]; + } + } + L_acc = L_sub (L_maxloc, L_THRESH_ERR); + if (L_acc > 0L) { + flag = 1; + } + + return (flag); +} + +/************************************************************************** + *routine update_exc_err - maintains the memory used to compute the error * + * function due to an adaptive codebook mismatch between encoder and * + * decoder * + **************************************************************************/ + +void +update_exc_err (CodState *coder, + Word16 gain_pit, /* (i) pitch gain */ + Word16 T0 /* (i) integer part of pitch delay */ + ) +{ + + Word16 i, zone1, zone2, n; + Word32 L_worst, L_temp, L_acc; + Word16 hi, lo; + + L_worst = -1L; + n = sub (T0, L_SUBFR); + + if (n < 0) { + L_Extract (coder->L_exc_err[0], &hi, &lo); + L_temp = Mpy_32_16 (hi, lo, gain_pit); + L_temp = L_shl (L_temp, 1); + L_temp = L_add (0x00004000L, L_temp); + L_acc = L_sub (L_temp, L_worst); + if (L_acc > 0L) { + L_worst = L_temp; + } + L_Extract (L_temp, &hi, &lo); + L_temp = Mpy_32_16 (hi, lo, gain_pit); + L_temp = L_shl (L_temp, 1); + L_temp = L_add (0x00004000L, L_temp); + L_acc = L_sub (L_temp, L_worst); + if (L_acc > 0L) { + L_worst = L_temp; + } + } + + else { + + zone1 = tab_zone[n]; + + i = sub (T0, 1); + zone2 = tab_zone[i]; + + for (i = zone1; i <= zone2; i++) { + L_Extract (coder->L_exc_err[i], &hi, &lo); + L_temp = Mpy_32_16 (hi, lo, gain_pit); + L_temp = L_shl (L_temp, 1); + L_temp = L_add (0x00004000L, L_temp); + L_acc = L_sub (L_temp, L_worst); + if (L_acc > 0L) + L_worst = L_temp; + } + } + + for (i = 3; i >= 1; i--) { + coder->L_exc_err[i] = coder->L_exc_err[i - 1]; + } + coder->L_exc_err[0] = L_worst; + + return; +} diff --git a/src/libs/libg729/util.c b/src/libs/libg729/util.c new file mode 100644 index 00000000..14a5ee03 --- /dev/null +++ b/src/libs/libg729/util.c @@ -0,0 +1,145 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------------------------------------------* + * Function Set zero() * + * ~~~~~~~~~~ * + * Set vector x[] to zero * + *-------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" +#include "tab_ld8a.h" + +void +Set_zero (Word16 x[], Word16 L) +{ + Word16 i; + + for (i = 0; i < L; i++) + x[i] = 0; + + return; +} + +/*-------------------------------------------------------------------* + * Function Copy: * + * ~~~~~ * + * Copy vector x[] to y[] * + *-------------------------------------------------------------------*/ + +void +Copy (Word16 x[], Word16 y[], Word16 L) +{ + Word16 i; + + for (i = 0; i < L; i++) + y[i] = x[i]; + + return; +} + +/* Random generator */ + +Word16 +Random_16 (Word16* seed) +{ + /* seed = seed*31821 + 13849; */ + *seed = extract_l (L_add (L_shr (L_mult (*seed, 31821), 1), 13849L)); + + return (*seed); +} + + +/*---------------------------------------------------------------------------- + * Store_Param - converts encoder parameter vector into frame + * Restore_Params - converts serial received frame to encoder parameter vector + * + * The transmitted parameters are: + * + * LPC: 1st codebook 7+1 bit + * 2nd codebook 5+5 bit + * + * 1st subframe: + * pitch period 8 bit + * parity check on 1st period 1 bit + * codebook index1 (positions) 13 bit + * codebook index2 (signs) 4 bit + * pitch and codebook gains 4+3 bit + * + * 2nd subframe: + * pitch period (relative) 5 bit + * codebook index1 (positions) 13 bit + * codebook index2 (signs) 4 bit + * pitch and codebook gains 4+3 bit + *---------------------------------------------------------------------------- + */ + + +void +Store_Params(Word16 * parm, void *to) +{ + int i, j; + unsigned char mask, *to_b; + Word16 value, val_mask; + + to_b = (unsigned char *)to; + mask = 0x80; + for (i = 0; i < PRM_SIZE; i++) { + value = parm[i]; + val_mask = 1 << (bitsno[i] - 1); + for (j = 0; j < bitsno[i]; j++) { + + if (value & val_mask) + *to_b |= mask; + else + *to_b &= ~mask; + + value = value << 1; + mask = mask >> 1; + + if (mask == 0) { + mask = 0x80; + to_b++; + } + } + } + return; +} + +void Restore_Params(const void *from, Word16 * parm) +{ + int i, j; + unsigned char mask, *from_b; + Word16 value; + + mask = 0x80; + from_b = (unsigned char *)from; + + for (i = 0; i < PRM_SIZE; i++) { + value = 0; + for (j = 0; j < bitsno[i]; j++) { + + value = value << 1; + + if (mask & (*from_b)) + value += 1; + + mask = mask >> 1; + if (mask == 0) { + mask = 0x80; + from_b++; + } + } + parm[i] = value; + } + return; +} + diff --git a/src/libs/libgsm/CMakeLists.txt b/src/libs/libgsm/CMakeLists.txt new file mode 100644 index 00000000..97295d6c --- /dev/null +++ b/src/libs/libgsm/CMakeLists.txt @@ -0,0 +1,24 @@ +project (gsm_codec) + +# Rely on C++ 11 +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +set (GSM_SOURCES + gsm_add.c + gsm_code.c + gsm_decode_helper.c + gsm_create.c + gsm_decode.c + gsm_destroy.c + gsm_encode.c + gsm_lpc.c + gsm_option.c + gsm_long_term.c + gsm_rpe.c + gsm_short_term.c + gsm_table.c + gsm_preprocess.c +) + +add_library(gsm_codec ${GSM_SOURCES}) diff --git a/src/libs/libgsm/COPYRIGHT b/src/libs/libgsm/COPYRIGHT new file mode 100644 index 00000000..504978b1 --- /dev/null +++ b/src/libs/libgsm/COPYRIGHT @@ -0,0 +1,16 @@ +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +Any use of this software is permitted provided that this notice is not +removed and that neither the authors nor the Technische Universitaet Berlin +are deemed to have made any representations as to the suitability of this +software for any purpose nor are held responsible for any defects of +this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + +As a matter of courtesy, the authors request to be informed about uses +this software has found, about bugs in this software, and about any +improvements that may be of general interest. + +Berlin, 28.11.1994 +Jutta Degener +Carsten Bormann diff --git a/src/libs/libgsm/PART_OF_TOAST b/src/libs/libgsm/PART_OF_TOAST new file mode 100644 index 00000000..70f2f031 --- /dev/null +++ b/src/libs/libgsm/PART_OF_TOAST @@ -0,0 +1,6 @@ + +This library is part of the toast software. You can +get the complete package at: + +http://kbs.cs.tu-berlin.de/~jutta/toast.html + diff --git a/src/libs/libgsm/README b/src/libs/libgsm/README new file mode 100644 index 00000000..ebb1f16e --- /dev/null +++ b/src/libs/libgsm/README @@ -0,0 +1,37 @@ + +GSM 06.10 13 kbit/s RPE/LTP speech compression available +-------------------------------------------------------- + +The Communications and Operating Systems Research Group (KBS) at the +Technische Universitaet Berlin is currently working on a set of +UNIX-based tools for computer-mediated telecooperation that will be +made freely available. + +As part of this effort we are publishing an implementation of the +European GSM 06.10 provisional standard for full-rate speech +transcoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse +excitation/long term prediction) coding at 13 kbit/s. + +GSM 06.10 compresses frames of 160 13-bit samples (8 kHz sampling +rate, i.e. a frame rate of 50 Hz) into 260 bits; for compatibility +with typical UNIX applications, our implementation turns frames of 160 +16-bit linear samples into 33-byte frames (1650 Bytes/s). +The quality of the algorithm is good enough for reliable speaker +recognition; even music often survives transcoding in recognizable +form (given the bandwidth limitations of 8 kHz sampling rate). + +The interfaces offered are a front end modelled after compress(1), and +a library API. Compression and decompression run faster than realtime +on most SPARCstations. The implementation has been verified against the +ETSI standard test patterns. + +Jutta Degener (jutta@cs.tu-berlin.de) +Carsten Bormann (cabo@cs.tu-berlin.de) + +Communications and Operating Systems Research Group, TU Berlin +Fax: +49.30.31425156, Phone: +49.30.31424315 + +-- +Copyright 1992 by Jutta Degener and Carsten Bormann, Technische +Universitaet Berlin. See the accompanying file "COPYRIGHT" for +details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. diff --git a/src/libs/libgsm/gsm.h b/src/libs/libgsm/gsm.h new file mode 100644 index 00000000..8c5c7df5 --- /dev/null +++ b/src/libs/libgsm/gsm.h @@ -0,0 +1,74 @@ +/* + * gsm.h + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#ifndef GSM_H +#define GSM_H + +#ifdef __cplusplus +# define NeedFunctionPrototypes 1 +#endif + +#if __STDC__ +# define NeedFunctionPrototypes 1 +#endif + +#ifdef _NO_PROTO +# undef NeedFunctionPrototypes +#endif + +#ifdef NeedFunctionPrototypes +# include /* for FILE * */ +#endif + +#undef GSM_P +#if NeedFunctionPrototypes +# define GSM_P( protos ) protos +#else +# define GSM_P( protos ) ( /* protos */ ) +#endif + +/* + * Interface + */ + +typedef struct gsm_state * gsm; +typedef short gsm_signal; /* signed 16 bit */ +typedef unsigned char gsm_byte; +typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */ + +#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */ + +#define GSM_PATCHLEVEL 10 +#define GSM_MINOR 0 +#define GSM_MAJOR 1 + +#define GSM_OPT_VERBOSE 1 +#define GSM_OPT_FAST 2 +#define GSM_OPT_LTP_CUT 3 +#define GSM_OPT_WAV49 4 +#define GSM_OPT_FRAME_INDEX 5 +#define GSM_OPT_FRAME_CHAIN 6 + +extern gsm gsm_create GSM_P((void)); +extern void gsm_destroy GSM_P((gsm)); + +extern int gsm_print GSM_P((FILE *, gsm, gsm_byte *)); +extern int gsm_option GSM_P((gsm, int, int *)); + +extern void gsm_encode GSM_P((gsm, gsm_signal *, gsm_byte *)); +extern int gsm_decode GSM_P((gsm, gsm_byte *, gsm_signal *)); + +extern int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *)); +extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *)); + +#undef GSM_P + +#define WAV49 + +#endif /* GSM_H */ diff --git a/src/libs/libgsm/gsm_add.c b/src/libs/libgsm/gsm_add.c new file mode 100644 index 00000000..a74efd7f --- /dev/null +++ b/src/libs/libgsm/gsm_add.c @@ -0,0 +1,236 @@ +/* + * add.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +/* + * See private.h for the more commonly used macro versions. + */ + +#include +#include + +#include "gsm_private.h" +#include "gsm.h" +#include "gsm_proto.h" + +#define saturate(x) \ + ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) + +word gsm_add P2((a,b), word a, word b) +{ + longword sum = (longword)a + (longword)b; + return (word) saturate(sum); +} + +word gsm_sub P2((a,b), word a, word b) +{ + longword diff = (longword)a - (longword)b; + return (word) saturate(diff); +} + +word gsm_mult P2((a,b), word a, word b) +{ + if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD; + else return SASR( (longword)a * (longword)b, 15 ); +} + +word gsm_mult_r P2((a,b), word a, word b) +{ + if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD; + else { + longword prod = (longword)a * (longword)b + 16384; + prod >>= 15; + return prod & 0xFFFF; + } +} + +word gsm_abs P1((a), word a) +{ + return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a; +} + +longword gsm_L_mult P2((a,b),word a, word b) +{ + assert( a != MIN_WORD || b != MIN_WORD ); + return ((longword)a * (longword)b) << 1; +} + +longword gsm_L_add P2((a,b), longword a, longword b) +{ + if (a < 0) { + if (b >= 0) return a + b; + else { + ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1); + return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2; + } + } + else if (b <= 0) return a + b; + else { + ulongword A = (ulongword)a + (ulongword)b; + return A > MAX_LONGWORD ? MAX_LONGWORD : A; + } +} + +longword gsm_L_sub P2((a,b), longword a, longword b) +{ + if (a >= 0) { + if (b >= 0) return a - b; + else { + /* a>=0, b<0 */ + + ulongword A = (ulongword)a + -(b + 1); + return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1); + } + } + else if (b <= 0) return a - b; + else { + /* a<0, b>0 */ + + ulongword A = (ulongword)-(a + 1) + b; + return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1; + } +} + +static unsigned char const bitoff[ 256 ] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +word gsm_norm P1((a), longword a ) +/* + * the number of left shifts needed to normalize the 32 bit + * variable L_var1 for positive values on the interval + * + * with minimum of + * minimum of 1073741824 (01000000000000000000000000000000) and + * maximum of 2147483647 (01111111111111111111111111111111) + * + * + * and for negative values on the interval with + * minimum of -2147483648 (-10000000000000000000000000000000) and + * maximum of -1073741824 ( -1000000000000000000000000000000). + * + * in order to normalize the result, the following + * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 ); + * + * (That's 'ffs', only from the left, not the right..) + */ +{ + assert(a != 0); + + if (a < 0) { + if (a <= -1073741824) return 0; + a = ~a; + } + + return a & 0xffff0000 + ? ( a & 0xff000000 + ? -1 + bitoff[ 0xFF & (a >> 24) ] + : 7 + bitoff[ 0xFF & (a >> 16) ] ) + : ( a & 0xff00 + ? 15 + bitoff[ 0xFF & (a >> 8) ] + : 23 + bitoff[ 0xFF & a ] ); +} + +longword gsm_L_asl P2((a,n), longword a, int n) +{ + if (n >= 32) return 0; + if (n <= -32) return -(a < 0); + if (n < 0) return gsm_L_asr(a, -n); + return a << n; +} + +word gsm_asl P2((a,n), word a, int n) +{ + if (n >= 16) return 0; + if (n <= -16) return -(a < 0); + if (n < 0) return gsm_asr(a, -n); + return a << n; +} + +longword gsm_L_asr P2((a,n), longword a, int n) +{ + if (n >= 32) return -(a < 0); + if (n <= -32) return 0; + if (n < 0) return a << -n; + +# ifdef SASR + return a >> n; +# else + if (a >= 0) return a >> n; + else return -(longword)( -(ulongword)a >> n ); +# endif +} + +word gsm_asr P2((a,n), word a, int n) +{ + if (n >= 16) return -(a < 0); + if (n <= -16) return 0; + if (n < 0) return a << -n; + +# ifdef SASR + return a >> n; +# else + if (a >= 0) return a >> n; + else return -(word)( -(uword)a >> n ); +# endif +} + +/* + * (From p. 46, end of section 4.2.5) + * + * NOTE: The following lines gives [sic] one correct implementation + * of the div(num, denum) arithmetic operation. Compute div + * which is the integer division of num by denum: with denum + * >= num > 0 + */ + +word gsm_div P2((num,denum), word num, word denum) +{ + longword L_num = num; + longword L_denum = denum; + word div = 0; + int k = 15; + + /* The parameter num sometimes becomes zero. + * Although this is explicitly guarded against in 4.2.5, + * we assume that the result should then be zero as well. + */ + + /* assert(num != 0); */ + + assert(num >= 0 && denum >= num); + if (num == 0) + return 0; + + while (k--) { + div <<= 1; + L_num <<= 1; + + if (L_num >= L_denum) { + L_num -= L_denum; + div++; + } + } + + return div; +} diff --git a/src/libs/libgsm/gsm_code.c b/src/libs/libgsm/gsm_code.c new file mode 100644 index 00000000..c6d9b009 --- /dev/null +++ b/src/libs/libgsm/gsm_code.c @@ -0,0 +1,103 @@ +/* + * code.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#include "config.h" + + +#ifdef HAS_STDLIB_H +#include +#else +#include "gsm_proto.h" +// TODO: error C2371: 'memcpy' : redefinition; different basic types +// extern char * memcpy P((char *, char *, int)); +#endif + +#include "gsm_private.h" +#include "gsm.h" +#include "gsm_proto.h" + +#include + +/* + * 4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER + */ + +void Gsm_Coder P8((S,s,LARc,Nc,bc,Mc,xmaxc,xMc), + + struct gsm_state * S, + + word * s, /* [0..159] samples IN */ + +/* + * The RPE-LTD coder works on a frame by frame basis. The length of + * the frame is equal to 160 samples. Some computations are done + * once per frame to produce at the output of the coder the + * LARc[1..8] parameters which are the coded LAR coefficients and + * also to realize the inverse filtering operation for the entire + * frame (160 samples of signal d[0..159]). These parts produce at + * the output of the coder: + */ + + word * LARc, /* [0..7] LAR coefficients OUT */ + +/* + * Procedure 4.2.11 to 4.2.18 are to be executed four times per + * frame. That means once for each sub-segment RPE-LTP analysis of + * 40 samples. These parts produce at the output of the coder: + */ + + word * Nc, /* [0..3] LTP lag OUT */ + word * bc, /* [0..3] coded LTP gain OUT */ + word * Mc, /* [0..3] RPE grid selection OUT */ + word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ + word * xMc /* [13*4] normalized RPE samples OUT */ +) +{ + int k; + word * dp = S->dp0 + 120; /* [ -120...-1 ] */ + word * dpp = dp; /* [ 0...39 ] */ + + static word e[50]; + + word so[160]; + + Gsm_Preprocess (S, s, so); + Gsm_LPC_Analysis (S, so, LARc); + Gsm_Short_Term_Analysis_Filter (S, LARc, so); + + for (k = 0; k <= 3; k++, xMc += 13) { + + Gsm_Long_Term_Predictor ( S, + so+k*40, /* d [0..39] IN */ + dp, /* dp [-120..-1] IN */ + e + 5, /* e [0..39] OUT */ + dpp, /* dpp [0..39] OUT */ + Nc++, + bc++); + + Gsm_RPE_Encoding ( S, + e + 5, /* e ][0..39][ IN/OUT */ + xmaxc++, Mc++, xMc ); + /* + * Gsm_Update_of_reconstructed_short_time_residual_signal + * ( dpp, e + 5, dp ); + */ + + { register int i; + register longword ltmp; + for (i = 0; i <= 39; i++) + dp[ i ] = (word) GSM_ADD( e[5 + i], dpp[i] ); + } + dp += 40; + dpp += 40; + + } + (void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160), + 120 * sizeof(*S->dp0) ); +} diff --git a/src/libs/libgsm/gsm_config.h b/src/libs/libgsm/gsm_config.h new file mode 100644 index 00000000..d40fedfa --- /dev/null +++ b/src/libs/libgsm/gsm_config.h @@ -0,0 +1,45 @@ +/* + * config.h + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#ifndef CONFIG_H +#define CONFIG_H + +/*efine SIGHANDLER_T int /* signal handlers are void */ +/*efine HAS_SYSV_SIGNAL 1 /* sigs not blocked/reset? */ + +#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */ +/*efine HAS_LIMITS_H 1 /* /usr/include/limits.h */ +#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */ +/*efine HAS_ERRNO_DECL 1 /* errno.h declares errno */ + +#define HAS_FSTAT 1 /* fstat syscall */ +#define HAS_FCHMOD 1 /* fchmod syscall */ +#define HAS_CHMOD 1 /* chmod syscall */ +#define HAS_FCHOWN 1 /* fchown syscall */ +#define HAS_CHOWN 1 /* chown syscall */ +/*efine HAS__FSETMODE 1 /* _fsetmode -- set file mode */ + +#define HAS_STRING_H 1 /* /usr/include/string.h */ +/*efine HAS_STRINGS_H 1 /* /usr/include/strings.h */ + +#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */ +#define HAS_UTIME 1 /* POSIX utime(path, times) */ +/*efine HAS_UTIMES 1 /* use utimes() syscall instead */ +#define HAS_UTIME_H 1 /* UTIME header file */ +/*efine HAS_UTIMBUF 1 /* struct utimbuf */ +/*efine HAS_UTIMEUSEC 1 /* microseconds in utimbuf? */ + + + + + +//#define HAS_MALLOC_H 1 /* TODO: */ + + +#endif /* CONFIG_H */ diff --git a/src/libs/libgsm/gsm_create.c b/src/libs/libgsm/gsm_create.c new file mode 100644 index 00000000..01205e67 --- /dev/null +++ b/src/libs/libgsm/gsm_create.c @@ -0,0 +1,50 @@ +/* + * gsm_create.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#include "config.h" + +#ifdef HAS_STRING_H +#include +#else +# include "gsm_proto.h" +//TODO: error C2371: 'memset' : redefinition; different basic types +// extern char * memset P((char *, int, int)); +#endif + +#ifdef HAS_STDLIB_H +# include +#else + +//# ifdef HAS_MALLOC_H +//# include +//# else +// extern char * malloc(); +//# endif +#endif + +#include +#include +#include + +#include "gsm.h" +#include "gsm_private.h" +#include "gsm_proto.h" + +gsm gsm_create P0() +{ + gsm r; + + r = (gsm)malloc(sizeof(struct gsm_state)); + if (!r) return r; + + memset((char *)r, 0, sizeof(*r)); + r->nrp = 40; + + return r; +} diff --git a/src/libs/libgsm/gsm_decode.c b/src/libs/libgsm/gsm_decode.c new file mode 100644 index 00000000..bff43ac3 --- /dev/null +++ b/src/libs/libgsm/gsm_decode.c @@ -0,0 +1,362 @@ +/* + * gsm_decode.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#include "gsm_private.h" + +#include "gsm.h" +#include "gsm_proto.h" + +int gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target) +{ + word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; + +#ifdef WAV49 + if (s->wav_fmt) { + + uword sr = 0; + + s->frame_index = !s->frame_index; + if (s->frame_index) { + + sr = *c++; + LARc[0] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 2; + LARc[1] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 4; + LARc[2] = sr & 0x1f; sr >>= 5; + LARc[3] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 2; + LARc[4] = sr & 0xf; sr >>= 4; + LARc[5] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; /* 5 */ + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[0] = sr & 0x7f; sr >>= 7; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[0] = sr & 0x3f; sr >>= 6; + xmc[0] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[1] = sr & 0x7; sr >>= 3; + xmc[2] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + xmc[5] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 10 */ + xmc[6] = sr & 0x7; sr >>= 3; + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[9] = sr & 0x7; sr >>= 3; + xmc[10] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[1] = sr & 0x7f; sr >>= 7; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[1] = sr & 0x3f; sr >>= 6; + xmc[13] = sr & 0x7; sr >>= 3; + sr = *c++; /* 15 */ + xmc[14] = sr & 0x7; sr >>= 3; + xmc[15] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + xmc[18] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[19] = sr & 0x7; sr >>= 3; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[22] = sr & 0x7; sr >>= 3; + xmc[23] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; /* 20 */ + Nc[2] = sr & 0x7f; sr >>= 7; + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[2] = sr & 0x3f; sr >>= 6; + xmc[26] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[27] = sr & 0x7; sr >>= 3; + xmc[28] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + xmc[31] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[32] = sr & 0x7; sr >>= 3; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + sr = *c++; /* 25 */ + xmc[35] = sr & 0x7; sr >>= 3; + xmc[36] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[3] = sr & 0x7f; sr >>= 7; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[3] = sr & 0x3f; sr >>= 6; + xmc[39] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[40] = sr & 0x7; sr >>= 3; + xmc[41] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 30 */ + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + xmc[44] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[45] = sr & 0x7; sr >>= 3; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[48] = sr & 0x7; sr >>= 3; + xmc[49] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + + s->frame_chain = sr & 0xf; + } + else { + sr = s->frame_chain; + sr |= (uword)*c++ << 4; /* 1 */ + LARc[0] = sr & 0x3f; sr >>= 6; + LARc[1] = sr & 0x3f; sr >>= 6; + sr = *c++; + LARc[2] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 3; + LARc[3] = sr & 0x1f; sr >>= 5; + LARc[4] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; + LARc[5] = sr & 0xf; sr >>= 4; + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr = *c++; /* 5 */ + Nc[0] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[0] = sr & 0x3f; sr >>= 6; + xmc[0] = sr & 0x7; sr >>= 3; + xmc[1] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[2] = sr & 0x7; sr >>= 3; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[5] = sr & 0x7; sr >>= 3; + xmc[6] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 10 */ + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + xmc[9] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[10] = sr & 0x7; sr >>= 3; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[1] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[1] = sr & 0x3f; sr >>= 6; + xmc[13] = sr & 0x7; sr >>= 3; + xmc[14] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 15 */ + xmc[15] = sr & 0x7; sr >>= 3; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[18] = sr & 0x7; sr >>= 3; + xmc[19] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + xmc[22] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[23] = sr & 0x7; sr >>= 3; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[2] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; /* 20 */ + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[2] = sr & 0x3f; sr >>= 6; + xmc[26] = sr & 0x7; sr >>= 3; + xmc[27] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[28] = sr & 0x7; sr >>= 3; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[31] = sr & 0x7; sr >>= 3; + xmc[32] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + xmc[35] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 25 */ + xmc[36] = sr & 0x7; sr >>= 3; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[3] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[3] = sr & 0x3f; sr >>= 6; + xmc[39] = sr & 0x7; sr >>= 3; + xmc[40] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[41] = sr & 0x7; sr >>= 3; + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + sr = *c++; /* 30 */ + xmc[44] = sr & 0x7; sr >>= 3; + xmc[45] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + xmc[48] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[49] = sr & 0x7; sr >>= 3; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + } + } + else +#endif + { + /* GSM_MAGIC = (*c >> 4) & 0xF; */ + + if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; + + LARc[0] = (*c++ & 0xF) << 2; /* 1 */ + LARc[0] |= (*c >> 6) & 0x3; + LARc[1] = *c++ & 0x3F; + LARc[2] = (*c >> 3) & 0x1F; + LARc[3] = (*c++ & 0x7) << 2; + LARc[3] |= (*c >> 6) & 0x3; + LARc[4] = (*c >> 2) & 0xF; + LARc[5] = (*c++ & 0x3) << 2; + LARc[5] |= (*c >> 6) & 0x3; + LARc[6] = (*c >> 3) & 0x7; + LARc[7] = *c++ & 0x7; + Nc[0] = (*c >> 1) & 0x7F; + bc[0] = (*c++ & 0x1) << 1; + bc[0] |= (*c >> 7) & 0x1; + Mc[0] = (*c >> 5) & 0x3; + xmaxc[0] = (*c++ & 0x1F) << 1; + xmaxc[0] |= (*c >> 7) & 0x1; + xmc[0] = (*c >> 4) & 0x7; + xmc[1] = (*c >> 1) & 0x7; + xmc[2] = (*c++ & 0x1) << 2; + xmc[2] |= (*c >> 6) & 0x3; + xmc[3] = (*c >> 3) & 0x7; + xmc[4] = *c++ & 0x7; + xmc[5] = (*c >> 5) & 0x7; + xmc[6] = (*c >> 2) & 0x7; + xmc[7] = (*c++ & 0x3) << 1; /* 10 */ + xmc[7] |= (*c >> 7) & 0x1; + xmc[8] = (*c >> 4) & 0x7; + xmc[9] = (*c >> 1) & 0x7; + xmc[10] = (*c++ & 0x1) << 2; + xmc[10] |= (*c >> 6) & 0x3; + xmc[11] = (*c >> 3) & 0x7; + xmc[12] = *c++ & 0x7; + Nc[1] = (*c >> 1) & 0x7F; + bc[1] = (*c++ & 0x1) << 1; + bc[1] |= (*c >> 7) & 0x1; + Mc[1] = (*c >> 5) & 0x3; + xmaxc[1] = (*c++ & 0x1F) << 1; + xmaxc[1] |= (*c >> 7) & 0x1; + xmc[13] = (*c >> 4) & 0x7; + xmc[14] = (*c >> 1) & 0x7; + xmc[15] = (*c++ & 0x1) << 2; + xmc[15] |= (*c >> 6) & 0x3; + xmc[16] = (*c >> 3) & 0x7; + xmc[17] = *c++ & 0x7; + xmc[18] = (*c >> 5) & 0x7; + xmc[19] = (*c >> 2) & 0x7; + xmc[20] = (*c++ & 0x3) << 1; + xmc[20] |= (*c >> 7) & 0x1; + xmc[21] = (*c >> 4) & 0x7; + xmc[22] = (*c >> 1) & 0x7; + xmc[23] = (*c++ & 0x1) << 2; + xmc[23] |= (*c >> 6) & 0x3; + xmc[24] = (*c >> 3) & 0x7; + xmc[25] = *c++ & 0x7; + Nc[2] = (*c >> 1) & 0x7F; + bc[2] = (*c++ & 0x1) << 1; /* 20 */ + bc[2] |= (*c >> 7) & 0x1; + Mc[2] = (*c >> 5) & 0x3; + xmaxc[2] = (*c++ & 0x1F) << 1; + xmaxc[2] |= (*c >> 7) & 0x1; + xmc[26] = (*c >> 4) & 0x7; + xmc[27] = (*c >> 1) & 0x7; + xmc[28] = (*c++ & 0x1) << 2; + xmc[28] |= (*c >> 6) & 0x3; + xmc[29] = (*c >> 3) & 0x7; + xmc[30] = *c++ & 0x7; + xmc[31] = (*c >> 5) & 0x7; + xmc[32] = (*c >> 2) & 0x7; + xmc[33] = (*c++ & 0x3) << 1; + xmc[33] |= (*c >> 7) & 0x1; + xmc[34] = (*c >> 4) & 0x7; + xmc[35] = (*c >> 1) & 0x7; + xmc[36] = (*c++ & 0x1) << 2; + xmc[36] |= (*c >> 6) & 0x3; + xmc[37] = (*c >> 3) & 0x7; + xmc[38] = *c++ & 0x7; + Nc[3] = (*c >> 1) & 0x7F; + bc[3] = (*c++ & 0x1) << 1; + bc[3] |= (*c >> 7) & 0x1; + Mc[3] = (*c >> 5) & 0x3; + xmaxc[3] = (*c++ & 0x1F) << 1; + xmaxc[3] |= (*c >> 7) & 0x1; + xmc[39] = (*c >> 4) & 0x7; + xmc[40] = (*c >> 1) & 0x7; + xmc[41] = (*c++ & 0x1) << 2; + xmc[41] |= (*c >> 6) & 0x3; + xmc[42] = (*c >> 3) & 0x7; + xmc[43] = *c++ & 0x7; /* 30 */ + xmc[44] = (*c >> 5) & 0x7; + xmc[45] = (*c >> 2) & 0x7; + xmc[46] = (*c++ & 0x3) << 1; + xmc[46] |= (*c >> 7) & 0x1; + xmc[47] = (*c >> 4) & 0x7; + xmc[48] = (*c >> 1) & 0x7; + xmc[49] = (*c++ & 0x1) << 2; + xmc[49] |= (*c >> 6) & 0x3; + xmc[50] = (*c >> 3) & 0x7; + xmc[51] = *c & 0x7; /* 33 */ + } + + Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target); + + return 0; +} diff --git a/src/libs/libgsm/gsm_decode_helper.c b/src/libs/libgsm/gsm_decode_helper.c new file mode 100644 index 00000000..87525295 --- /dev/null +++ b/src/libs/libgsm/gsm_decode_helper.c @@ -0,0 +1,64 @@ +/* + * decode.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#include + +#include "gsm_private.h" +#include "gsm.h" +#include "gsm_proto.h" + +/* + * 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER + */ + +static void Postprocessing P2((S,s), + struct gsm_state * S, + register word * s) +{ + register int k; + register word msr = S->msr; + register longword ltmp; /* for GSM_ADD */ + register word tmp; + + for (k = 160; k--; s++) { + tmp = GSM_MULT_R( msr, 28180 ); + msr = (word) GSM_ADD(*s, tmp); /* Deemphasis */ + *s = GSM_ADD(msr, msr) & 0xFFF8; /* Truncation & Upscaling */ + } + S->msr = msr; +} + +void Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s), + struct gsm_state * S, + + word * LARcr, /* [0..7] IN */ + + word * Ncr, /* [0..3] IN */ + word * bcr, /* [0..3] IN */ + word * Mcr, /* [0..3] IN */ + word * xmaxcr, /* [0..3] IN */ + word * xMcr, /* [0..13*4] IN */ + + word * s) /* [0..159] OUT */ +{ + int j, k; + word erp[40], wt[160]; + word * drp = S->dp0 + 120; + + for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) { + + Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp ); + Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp ); + + for (k = 0; k <= 39; k++) wt[ j * 40 + k ] = drp[ k ]; + } + + Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s ); + Postprocessing(S, s); +} diff --git a/src/libs/libgsm/gsm_destroy.c b/src/libs/libgsm/gsm_destroy.c new file mode 100644 index 00000000..fb73a587 --- /dev/null +++ b/src/libs/libgsm/gsm_destroy.c @@ -0,0 +1,27 @@ +/* + * gsm_destroy.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#include "gsm.h" +#include "gsm_config.h" +#include "gsm_proto.h" + +#ifdef HAS_STDLIB_H +# include +#else +# ifdef HAS_MALLOC_H +# include +# else + extern void free(); +# endif +#endif + +void gsm_destroy P1((S), gsm S) +{ + if (S) free((char *)S); +} diff --git a/src/libs/libgsm/gsm_encode.c b/src/libs/libgsm/gsm_encode.c new file mode 100644 index 00000000..230b4245 --- /dev/null +++ b/src/libs/libgsm/gsm_encode.c @@ -0,0 +1,452 @@ +/* + * gsm_encode.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#include "gsm_private.h" +#include "gsm.h" +#include "gsm_proto.h" + +void gsm_encode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c) +{ + word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; + + Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc); + + + /* variable size + + GSM_MAGIC 4 + + LARc[0] 6 + LARc[1] 6 + LARc[2] 5 + LARc[3] 5 + LARc[4] 4 + LARc[5] 4 + LARc[6] 3 + LARc[7] 3 + + Nc[0] 7 + bc[0] 2 + Mc[0] 2 + xmaxc[0] 6 + xmc[0] 3 + xmc[1] 3 + xmc[2] 3 + xmc[3] 3 + xmc[4] 3 + xmc[5] 3 + xmc[6] 3 + xmc[7] 3 + xmc[8] 3 + xmc[9] 3 + xmc[10] 3 + xmc[11] 3 + xmc[12] 3 + + Nc[1] 7 + bc[1] 2 + Mc[1] 2 + xmaxc[1] 6 + xmc[13] 3 + xmc[14] 3 + xmc[15] 3 + xmc[16] 3 + xmc[17] 3 + xmc[18] 3 + xmc[19] 3 + xmc[20] 3 + xmc[21] 3 + xmc[22] 3 + xmc[23] 3 + xmc[24] 3 + xmc[25] 3 + + Nc[2] 7 + bc[2] 2 + Mc[2] 2 + xmaxc[2] 6 + xmc[26] 3 + xmc[27] 3 + xmc[28] 3 + xmc[29] 3 + xmc[30] 3 + xmc[31] 3 + xmc[32] 3 + xmc[33] 3 + xmc[34] 3 + xmc[35] 3 + xmc[36] 3 + xmc[37] 3 + xmc[38] 3 + + Nc[3] 7 + bc[3] 2 + Mc[3] 2 + xmaxc[3] 6 + xmc[39] 3 + xmc[40] 3 + xmc[41] 3 + xmc[42] 3 + xmc[43] 3 + xmc[44] 3 + xmc[45] 3 + xmc[46] 3 + xmc[47] 3 + xmc[48] 3 + xmc[49] 3 + xmc[50] 3 + xmc[51] 3 + */ + +#ifdef WAV49 + + if (s->wav_fmt) { + s->frame_index = !s->frame_index; + if (s->frame_index) { + + uword sr; + + sr = 0; + sr = sr >> 6 | LARc[0] << 10; + sr = sr >> 6 | LARc[1] << 10; + *c++ = sr >> 4; + sr = sr >> 5 | LARc[2] << 11; + *c++ = sr >> 7; + sr = sr >> 5 | LARc[3] << 11; + sr = sr >> 4 | LARc[4] << 12; + *c++ = sr >> 6; + sr = sr >> 4 | LARc[5] << 12; + sr = sr >> 3 | LARc[6] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | LARc[7] << 13; + sr = sr >> 7 | Nc[0] << 9; + *c++ = sr >> 5; + sr = sr >> 2 | bc[0] << 14; + sr = sr >> 2 | Mc[0] << 14; + sr = sr >> 6 | xmaxc[0] << 10; + *c++ = sr >> 3; + sr = sr >> 3 | xmc[0] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[1] << 13; + sr = sr >> 3 | xmc[2] << 13; + sr = sr >> 3 | xmc[3] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[4] << 13; + sr = sr >> 3 | xmc[5] << 13; + sr = sr >> 3 | xmc[6] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[7] << 13; + sr = sr >> 3 | xmc[8] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[9] << 13; + sr = sr >> 3 | xmc[10] << 13; + sr = sr >> 3 | xmc[11] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[12] << 13; + sr = sr >> 7 | Nc[1] << 9; + *c++ = sr >> 5; + sr = sr >> 2 | bc[1] << 14; + sr = sr >> 2 | Mc[1] << 14; + sr = sr >> 6 | xmaxc[1] << 10; + *c++ = sr >> 3; + sr = sr >> 3 | xmc[13] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[14] << 13; + sr = sr >> 3 | xmc[15] << 13; + sr = sr >> 3 | xmc[16] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[17] << 13; + sr = sr >> 3 | xmc[18] << 13; + sr = sr >> 3 | xmc[19] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[20] << 13; + sr = sr >> 3 | xmc[21] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[22] << 13; + sr = sr >> 3 | xmc[23] << 13; + sr = sr >> 3 | xmc[24] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[25] << 13; + sr = sr >> 7 | Nc[2] << 9; + *c++ = sr >> 5; + sr = sr >> 2 | bc[2] << 14; + sr = sr >> 2 | Mc[2] << 14; + sr = sr >> 6 | xmaxc[2] << 10; + *c++ = sr >> 3; + sr = sr >> 3 | xmc[26] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[27] << 13; + sr = sr >> 3 | xmc[28] << 13; + sr = sr >> 3 | xmc[29] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[30] << 13; + sr = sr >> 3 | xmc[31] << 13; + sr = sr >> 3 | xmc[32] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[33] << 13; + sr = sr >> 3 | xmc[34] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[35] << 13; + sr = sr >> 3 | xmc[36] << 13; + sr = sr >> 3 | xmc[37] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[38] << 13; + sr = sr >> 7 | Nc[3] << 9; + *c++ = sr >> 5; + sr = sr >> 2 | bc[3] << 14; + sr = sr >> 2 | Mc[3] << 14; + sr = sr >> 6 | xmaxc[3] << 10; + *c++ = sr >> 3; + sr = sr >> 3 | xmc[39] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[40] << 13; + sr = sr >> 3 | xmc[41] << 13; + sr = sr >> 3 | xmc[42] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[43] << 13; + sr = sr >> 3 | xmc[44] << 13; + sr = sr >> 3 | xmc[45] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[46] << 13; + sr = sr >> 3 | xmc[47] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[48] << 13; + sr = sr >> 3 | xmc[49] << 13; + sr = sr >> 3 | xmc[50] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[51] << 13; + sr = sr >> 4; + *c = sr >> 8; + s->frame_chain = *c; + } + else { + uword sr; + + sr = 0; + sr = sr >> 4 | s->frame_chain << 12; + sr = sr >> 6 | LARc[0] << 10; + *c++ = sr >> 6; + sr = sr >> 6 | LARc[1] << 10; + *c++ = sr >> 8; + sr = sr >> 5 | LARc[2] << 11; + sr = sr >> 5 | LARc[3] << 11; + *c++ = sr >> 6; + sr = sr >> 4 | LARc[4] << 12; + sr = sr >> 4 | LARc[5] << 12; + *c++ = sr >> 6; + sr = sr >> 3 | LARc[6] << 13; + sr = sr >> 3 | LARc[7] << 13; + *c++ = sr >> 8; + sr = sr >> 7 | Nc[0] << 9; + sr = sr >> 2 | bc[0] << 14; + *c++ = sr >> 7; + sr = sr >> 2 | Mc[0] << 14; + sr = sr >> 6 | xmaxc[0] << 10; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[0] << 13; + sr = sr >> 3 | xmc[1] << 13; + sr = sr >> 3 | xmc[2] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[3] << 13; + sr = sr >> 3 | xmc[4] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[5] << 13; + sr = sr >> 3 | xmc[6] << 13; + sr = sr >> 3 | xmc[7] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[8] << 13; + sr = sr >> 3 | xmc[9] << 13; + sr = sr >> 3 | xmc[10] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[11] << 13; + sr = sr >> 3 | xmc[12] << 13; + *c++ = sr >> 8; + sr = sr >> 7 | Nc[1] << 9; + sr = sr >> 2 | bc[1] << 14; + *c++ = sr >> 7; + sr = sr >> 2 | Mc[1] << 14; + sr = sr >> 6 | xmaxc[1] << 10; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[13] << 13; + sr = sr >> 3 | xmc[14] << 13; + sr = sr >> 3 | xmc[15] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[16] << 13; + sr = sr >> 3 | xmc[17] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[18] << 13; + sr = sr >> 3 | xmc[19] << 13; + sr = sr >> 3 | xmc[20] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[21] << 13; + sr = sr >> 3 | xmc[22] << 13; + sr = sr >> 3 | xmc[23] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[24] << 13; + sr = sr >> 3 | xmc[25] << 13; + *c++ = sr >> 8; + sr = sr >> 7 | Nc[2] << 9; + sr = sr >> 2 | bc[2] << 14; + *c++ = sr >> 7; + sr = sr >> 2 | Mc[2] << 14; + sr = sr >> 6 | xmaxc[2] << 10; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[26] << 13; + sr = sr >> 3 | xmc[27] << 13; + sr = sr >> 3 | xmc[28] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[29] << 13; + sr = sr >> 3 | xmc[30] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[31] << 13; + sr = sr >> 3 | xmc[32] << 13; + sr = sr >> 3 | xmc[33] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[34] << 13; + sr = sr >> 3 | xmc[35] << 13; + sr = sr >> 3 | xmc[36] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[37] << 13; + sr = sr >> 3 | xmc[38] << 13; + *c++ = sr >> 8; + sr = sr >> 7 | Nc[3] << 9; + sr = sr >> 2 | bc[3] << 14; + *c++ = sr >> 7; + sr = sr >> 2 | Mc[3] << 14; + sr = sr >> 6 | xmaxc[3] << 10; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[39] << 13; + sr = sr >> 3 | xmc[40] << 13; + sr = sr >> 3 | xmc[41] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[42] << 13; + sr = sr >> 3 | xmc[43] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[44] << 13; + sr = sr >> 3 | xmc[45] << 13; + sr = sr >> 3 | xmc[46] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[47] << 13; + sr = sr >> 3 | xmc[48] << 13; + sr = sr >> 3 | xmc[49] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[50] << 13; + sr = sr >> 3 | xmc[51] << 13; + *c++ = sr >> 8; + } + } + + else + +#endif /* WAV49 */ + { + + *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */ + | ((LARc[0] >> 2) & 0xF); + *c++ = ((LARc[0] & 0x3) << 6) + | (LARc[1] & 0x3F); + *c++ = ((LARc[2] & 0x1F) << 3) + | ((LARc[3] >> 2) & 0x7); + *c++ = ((LARc[3] & 0x3) << 6) + | ((LARc[4] & 0xF) << 2) + | ((LARc[5] >> 2) & 0x3); + *c++ = ((LARc[5] & 0x3) << 6) + | ((LARc[6] & 0x7) << 3) + | (LARc[7] & 0x7); + *c++ = ((Nc[0] & 0x7F) << 1) + | ((bc[0] >> 1) & 0x1); + *c++ = ((bc[0] & 0x1) << 7) + | ((Mc[0] & 0x3) << 5) + | ((xmaxc[0] >> 1) & 0x1F); + *c++ = ((xmaxc[0] & 0x1) << 7) + | ((xmc[0] & 0x7) << 4) + | ((xmc[1] & 0x7) << 1) + | ((xmc[2] >> 2) & 0x1); + *c++ = ((xmc[2] & 0x3) << 6) + | ((xmc[3] & 0x7) << 3) + | (xmc[4] & 0x7); + *c++ = ((xmc[5] & 0x7) << 5) /* 10 */ + | ((xmc[6] & 0x7) << 2) + | ((xmc[7] >> 1) & 0x3); + *c++ = ((xmc[7] & 0x1) << 7) + | ((xmc[8] & 0x7) << 4) + | ((xmc[9] & 0x7) << 1) + | ((xmc[10] >> 2) & 0x1); + *c++ = ((xmc[10] & 0x3) << 6) + | ((xmc[11] & 0x7) << 3) + | (xmc[12] & 0x7); + *c++ = ((Nc[1] & 0x7F) << 1) + | ((bc[1] >> 1) & 0x1); + *c++ = ((bc[1] & 0x1) << 7) + | ((Mc[1] & 0x3) << 5) + | ((xmaxc[1] >> 1) & 0x1F); + *c++ = ((xmaxc[1] & 0x1) << 7) + | ((xmc[13] & 0x7) << 4) + | ((xmc[14] & 0x7) << 1) + | ((xmc[15] >> 2) & 0x1); + *c++ = ((xmc[15] & 0x3) << 6) + | ((xmc[16] & 0x7) << 3) + | (xmc[17] & 0x7); + *c++ = ((xmc[18] & 0x7) << 5) + | ((xmc[19] & 0x7) << 2) + | ((xmc[20] >> 1) & 0x3); + *c++ = ((xmc[20] & 0x1) << 7) + | ((xmc[21] & 0x7) << 4) + | ((xmc[22] & 0x7) << 1) + | ((xmc[23] >> 2) & 0x1); + *c++ = ((xmc[23] & 0x3) << 6) + | ((xmc[24] & 0x7) << 3) + | (xmc[25] & 0x7); + *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */ + | ((bc[2] >> 1) & 0x1); + *c++ = ((bc[2] & 0x1) << 7) + | ((Mc[2] & 0x3) << 5) + | ((xmaxc[2] >> 1) & 0x1F); + *c++ = ((xmaxc[2] & 0x1) << 7) + | ((xmc[26] & 0x7) << 4) + | ((xmc[27] & 0x7) << 1) + | ((xmc[28] >> 2) & 0x1); + *c++ = ((xmc[28] & 0x3) << 6) + | ((xmc[29] & 0x7) << 3) + | (xmc[30] & 0x7); + *c++ = ((xmc[31] & 0x7) << 5) + | ((xmc[32] & 0x7) << 2) + | ((xmc[33] >> 1) & 0x3); + *c++ = ((xmc[33] & 0x1) << 7) + | ((xmc[34] & 0x7) << 4) + | ((xmc[35] & 0x7) << 1) + | ((xmc[36] >> 2) & 0x1); + *c++ = ((xmc[36] & 0x3) << 6) + | ((xmc[37] & 0x7) << 3) + | (xmc[38] & 0x7); + *c++ = ((Nc[3] & 0x7F) << 1) + | ((bc[3] >> 1) & 0x1); + *c++ = ((bc[3] & 0x1) << 7) + | ((Mc[3] & 0x3) << 5) + | ((xmaxc[3] >> 1) & 0x1F); + *c++ = ((xmaxc[3] & 0x1) << 7) + | ((xmc[39] & 0x7) << 4) + | ((xmc[40] & 0x7) << 1) + | ((xmc[41] >> 2) & 0x1); + *c++ = ((xmc[41] & 0x3) << 6) /* 30 */ + | ((xmc[42] & 0x7) << 3) + | (xmc[43] & 0x7); + *c++ = ((xmc[44] & 0x7) << 5) + | ((xmc[45] & 0x7) << 2) + | ((xmc[46] >> 1) & 0x3); + *c++ = ((xmc[46] & 0x1) << 7) + | ((xmc[47] & 0x7) << 4) + | ((xmc[48] & 0x7) << 1) + | ((xmc[49] >> 2) & 0x1); + *c++ = ((xmc[49] & 0x3) << 6) + | ((xmc[50] & 0x7) << 3) + | (xmc[51] & 0x7); + + } +} diff --git a/src/libs/libgsm/gsm_long_term.c b/src/libs/libgsm/gsm_long_term.c new file mode 100644 index 00000000..078e4b9f --- /dev/null +++ b/src/libs/libgsm/gsm_long_term.c @@ -0,0 +1,950 @@ +/* + * long_term.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#include +#include + +#include "gsm_private.h" + +#include "gsm.h" +#include "gsm_proto.h" + +/* + * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION + */ + + +/* + * This module computes the LTP gain (bc) and the LTP lag (Nc) + * for the long term analysis filter. This is done by calculating a + * maximum of the cross-correlation function between the current + * sub-segment short term residual signal d[0..39] (output of + * the short term analysis filter; for simplification the index + * of this array begins at 0 and ends at 39 for each sub-segment of the + * RPE-LTP analysis) and the previous reconstructed short term + * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be + * performed to avoid overflow. + */ + + /* The next procedure exists in six versions. First two integer + * version (if USE_FLOAT_MUL is not defined); then four floating + * point versions, twice with proper scaling (USE_FLOAT_MUL defined), + * once without (USE_FLOAT_MUL and FAST defined, and fast run-time + * option used). Every pair has first a Cut version (see the -C + * option to toast or the LTP_CUT option to gsm_option()), then the + * uncut one. (For a detailed explanation of why this is altogether + * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered + * Harmful''.) + */ + +#ifndef USE_FLOAT_MUL + +#ifdef LTP_CUT + +static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), + + struct gsm_state * st, + + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + word wt[40]; + + longword L_result; + longword L_max, L_power; + word R, S, dmax, scal, best_k; + word ltp_cut; + + register word temp, wt_k; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) { + dmax = temp; + best_k = k; + } + } + temp = 0; + if (dmax == 0) scal = 0; + else { + assert(dmax > 0); + temp = gsm_norm( (longword)dmax << 16 ); + } + if (temp > 6) scal = 0; + else scal = 6 - temp; + assert(scal >= 0); + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + wt_k = SASR(d[best_k], scal); + + for (lambda = 40; lambda <= 120; lambda++) { + L_result = (longword)wt_k * dp[best_k - lambda]; + if (L_result > L_max) { + Nc = lambda; + L_max = L_result; + } + } + *Nc_out = Nc; + L_max <<= 1; + + /* Rescaling of L_max + */ + assert(scal <= 100 && scal >= -100); + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + assert( Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; + *bc_out = bc; +} + +#endif /* LTP_CUT */ + +static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + word wt[40]; + + longword L_max, L_power; + word R, S, dmax, scal; + register word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax == 0) scal = 0; + else { + assert(dmax > 0); + temp = gsm_norm( (longword)dmax << 16 ); + } + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + assert(scal >= 0); + + /* Initialization of a working array wt + */ + + for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal ); + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda++) { + +# undef STEP +# define STEP(k) (longword)wt[k] * dp[k - lambda] + + register longword L_result; + + L_result = STEP(0) ; L_result += STEP(1) ; + L_result += STEP(2) ; L_result += STEP(3) ; + L_result += STEP(4) ; L_result += STEP(5) ; + L_result += STEP(6) ; L_result += STEP(7) ; + L_result += STEP(8) ; L_result += STEP(9) ; + L_result += STEP(10) ; L_result += STEP(11) ; + L_result += STEP(12) ; L_result += STEP(13) ; + L_result += STEP(14) ; L_result += STEP(15) ; + L_result += STEP(16) ; L_result += STEP(17) ; + L_result += STEP(18) ; L_result += STEP(19) ; + L_result += STEP(20) ; L_result += STEP(21) ; + L_result += STEP(22) ; L_result += STEP(23) ; + L_result += STEP(24) ; L_result += STEP(25) ; + L_result += STEP(26) ; L_result += STEP(27) ; + L_result += STEP(28) ; L_result += STEP(29) ; + L_result += STEP(30) ; L_result += STEP(31) ; + L_result += STEP(32) ; L_result += STEP(33) ; + L_result += STEP(34) ; L_result += STEP(35) ; + L_result += STEP(36) ; L_result += STEP(37) ; + L_result += STEP(38) ; L_result += STEP(39) ; + + if (L_result > L_max) { + + Nc = lambda; + L_max = L_result; + } + } + + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + assert(scal <= 100 && scal >= -100); + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + assert( Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; + *bc_out = bc; +} + +#else /* USE_FLOAT_MUL */ + +#ifdef LTP_CUT + +static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), + struct gsm_state * st, /* IN */ + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + word ltp_cut; + + float wt_float[40]; + float dp_float_base[120], * dp_float = dp_float_base + 120; + + longword L_max, L_power; + word R, S, dmax, scal; + register word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax == 0) scal = 0; + else { + assert(dmax > 0); + temp = gsm_norm( (longword)dmax << 16 ); + } + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + assert(scal >= 0); + ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100; + + + /* Initialization of a working array wt + */ + + for (k = 0; k < 40; k++) { + register word w = SASR( d[k], scal ); + if (w < 0 ? w > -ltp_cut : w < ltp_cut) { + wt_float[k] = 0.0; + } + else { + wt_float[k] = w; + } + } + for (k = -120; k < 0; k++) dp_float[k] = dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda += 9) { + + /* Calculate L_result for l = lambda .. lambda + 9. + */ + register float *lp = dp_float - lambda; + + register float W; + register float a = lp[-8], b = lp[-7], c = lp[-6], + d = lp[-5], e = lp[-4], f = lp[-3], + g = lp[-2], h = lp[-1]; + register float E; + register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, + S5 = 0, S6 = 0, S7 = 0, S8 = 0; + +# undef STEP +# define STEP(K, a, b, c, d, e, f, g, h) \ + if ((W = wt_float[K]) != 0.0) { \ + E = W * a; S8 += E; \ + E = W * b; S7 += E; \ + E = W * c; S6 += E; \ + E = W * d; S5 += E; \ + E = W * e; S4 += E; \ + E = W * f; S3 += E; \ + E = W * g; S2 += E; \ + E = W * h; S1 += E; \ + a = lp[K]; \ + E = W * a; S0 += E; } else (a = lp[K]) + +# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) +# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) +# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) +# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) +# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) +# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) +# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) +# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) + + STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); + STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); + + STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); + STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); + + STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); + STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); + + STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); + STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); + + STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); + STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); + + if (S0 > L_max) { L_max = S0; Nc = lambda; } + if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } + if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } + if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } + if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } + if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } + if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } + if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } + if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } + + } + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + assert(scal <= 100 && scal >= -100); + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + assert( Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; + *bc_out = bc; +} + +#endif /* LTP_CUT */ + +static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + + float wt_float[40]; + float dp_float_base[120], * dp_float = dp_float_base + 120; + + longword L_max, L_power; + word R, S, dmax, scal; + register word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax == 0) scal = 0; + else { + assert(dmax > 0); + temp = gsm_norm( (longword)dmax << 16 ); + } + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + assert(scal >= 0); + + /* Initialization of a working array wt + */ + + for (k = 0; k < 40; k++) wt_float[k] = SASR( d[k], scal ); + for (k = -120; k < 0; k++) dp_float[k] = dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda += 9) { + + /* Calculate L_result for l = lambda .. lambda + 9. + */ + register float *lp = dp_float - lambda; + + register float W; + register float a = lp[-8], b = lp[-7], c = lp[-6], + d = lp[-5], e = lp[-4], f = lp[-3], + g = lp[-2], h = lp[-1]; + register float E; + register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, + S5 = 0, S6 = 0, S7 = 0, S8 = 0; + +# undef STEP +# define STEP(K, a, b, c, d, e, f, g, h) \ + W = wt_float[K]; \ + E = W * a; S8 += E; \ + E = W * b; S7 += E; \ + E = W * c; S6 += E; \ + E = W * d; S5 += E; \ + E = W * e; S4 += E; \ + E = W * f; S3 += E; \ + E = W * g; S2 += E; \ + E = W * h; S1 += E; \ + a = lp[K]; \ + E = W * a; S0 += E + +# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) +# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) +# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) +# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) +# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) +# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) +# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) +# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) + + STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); + STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); + + STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); + STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); + + STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); + STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); + + STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); + STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); + + STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); + STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); + + if (S0 > L_max) { L_max = S0; Nc = lambda; } + if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } + if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } + if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } + if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } + if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } + if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } + if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } + if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } + } + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + assert(scal <= 100 && scal >= -100); + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + assert( Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; + *bc_out = bc; +} + +#ifdef FAST +#ifdef LTP_CUT + +static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st, + d,dp,bc_out,Nc_out), + struct gsm_state * st, /* IN */ + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + register float wt_float; + word Nc, bc; + word wt_max, best_k, ltp_cut; + + float dp_float_base[120], * dp_float = dp_float_base + 120; + + register float L_result, L_max, L_power; + + wt_max = 0; + + for (k = 0; k < 40; ++k) { + if ( d[k] > wt_max) wt_max = d[best_k = k]; + else if (-d[k] > wt_max) wt_max = -d[best_k = k]; + } + + assert(wt_max >= 0); + wt_float = (float)wt_max; + + for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda++) { + L_result = wt_float * dp_float[best_k - lambda]; + if (L_result > L_max) { + Nc = lambda; + L_max = L_result; + } + } + + *Nc_out = Nc; + if (L_max <= 0.) { + *bc_out = 0; + return; + } + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + dp_float -= Nc; + L_power = 0; + for (k = 0; k < 40; ++k) { + register float f = dp_float[k]; + L_power += f * f; + } + + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + /* Coding of the LTP gain + * Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + lambda = L_max / L_power * 32768.; + for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; + *bc_out = bc; +} + +#endif /* LTP_CUT */ + +static void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + + float wt_float[40]; + float dp_float_base[120], * dp_float = dp_float_base + 120; + + register float L_max, L_power; + + for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k]; + for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda += 9) { + + /* Calculate L_result for l = lambda .. lambda + 9. + */ + register float *lp = dp_float - lambda; + + register float W; + register float a = lp[-8], b = lp[-7], c = lp[-6], + d = lp[-5], e = lp[-4], f = lp[-3], + g = lp[-2], h = lp[-1]; + register float E; + register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, + S5 = 0, S6 = 0, S7 = 0, S8 = 0; + +# undef STEP +# define STEP(K, a, b, c, d, e, f, g, h) \ + W = wt_float[K]; \ + E = W * a; S8 += E; \ + E = W * b; S7 += E; \ + E = W * c; S6 += E; \ + E = W * d; S5 += E; \ + E = W * e; S4 += E; \ + E = W * f; S3 += E; \ + E = W * g; S2 += E; \ + E = W * h; S1 += E; \ + a = lp[K]; \ + E = W * a; S0 += E + +# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) +# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) +# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) +# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) +# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) +# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) +# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) +# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) + + STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); + STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); + + STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); + STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); + + STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); + STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); + + STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); + STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); + + STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); + STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); + + if (S0 > L_max) { L_max = S0; Nc = lambda; } + if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } + if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } + if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } + if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } + if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } + if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } + if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } + if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } + } + *Nc_out = Nc; + + if (L_max <= 0.) { + *bc_out = 0; + return; + } + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + dp_float -= Nc; + L_power = 0; + for (k = 0; k < 40; ++k) { + register float f = dp_float[k]; + L_power += f * f; + } + + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + /* Coding of the LTP gain + * Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + lambda = L_max / L_power * 32768.; + for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; + *bc_out = bc; +} + +#endif /* FAST */ +#endif /* USE_FLOAT_MUL */ + + +/* 4.2.12 */ + +static void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e), + word bc, /* IN */ + word Nc, /* IN */ + register word * dp, /* previous d [-120..-1] IN */ + register word * d, /* d [0..39] IN */ + register word * dpp, /* estimate [0..39] OUT */ + register word * e /* long term res. signal [0..39] OUT */ +) +/* + * In this part, we have to decode the bc parameter to compute + * the samples of the estimate dpp[0..39]. The decoding of bc needs the + * use of table 4.3b. The long term residual signal e[0..39] + * is then calculated to be fed to the RPE encoding section. + */ +{ + register int k; + register longword ltmp; + +# undef STEP +# define STEP(BP) \ + for (k = 0; k <= 39; k++) { \ + dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \ + e[k] = (word) GSM_SUB( d[k], dpp[k] ); \ + } + + switch (bc) { + case 0: STEP( 3277 ); break; + case 1: STEP( 11469 ); break; + case 2: STEP( 21299 ); break; + case 3: STEP( 32767 ); break; + } +} + +void Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc), /* 4x for 160 samples */ + + struct gsm_state * S, + + word * d, /* [0..39] residual signal IN */ + word * dp, /* [-120..-1] d' IN */ + + word * e, /* [0..39] OUT */ + word * dpp, /* [0..39] OUT */ + word * Nc, /* correlation lag OUT */ + word * bc /* gain factor OUT */ +) +{ + assert( d ); assert( dp ); assert( e ); + assert( dpp); assert( Nc ); assert( bc ); + +#if defined(FAST) && defined(USE_FLOAT_MUL) + if (S->fast) +#if defined (LTP_CUT) + if (S->ltp_cut) + Cut_Fast_Calculation_of_the_LTP_parameters(S, + d, dp, bc, Nc); + else +#endif /* LTP_CUT */ + Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc ); + else +#endif /* FAST & USE_FLOAT_MUL */ +#ifdef LTP_CUT + if (S->ltp_cut) + Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc); + else +#endif + Calculation_of_the_LTP_parameters(d, dp, bc, Nc); + + Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e ); +} + +/* 4.3.2 */ +void Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp), + struct gsm_state * S, + + word Ncr, + word bcr, + register word * erp, /* [0..39] IN */ + register word * drp /* [-120..-1] IN, [-120..40] OUT */ +) +/* + * This procedure uses the bcr and Ncr parameter to realize the + * long term synthesis filtering. The decoding of bcr needs + * table 4.3b. + */ +{ + register longword ltmp; /* for ADD */ + register int k; + word brp, drpp, Nr; + + /* Check the limits of Nr. + */ + Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr; + S->nrp = Nr; + assert(Nr >= 40 && Nr <= 120); + + /* Decoding of the LTP gain bcr + */ + brp = gsm_QLB[ bcr ]; + + /* Computation of the reconstructed short term residual + * signal drp[0..39] + */ + assert(brp != MIN_WORD); + + for (k = 0; k <= 39; k++) { + drpp = GSM_MULT_R( brp, drp[ k - Nr ] ); + drp[k] = (word) GSM_ADD( erp[k], drpp ); + } + + /* + * Update of the reconstructed short term residual signal + * drp[ -1..-120 ] + */ + + for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ]; +} diff --git a/src/libs/libgsm/gsm_lpc.c b/src/libs/libgsm/gsm_lpc.c new file mode 100644 index 00000000..d659b5a1 --- /dev/null +++ b/src/libs/libgsm/gsm_lpc.c @@ -0,0 +1,342 @@ +/* + * gsm_lpc.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#include +#include + +#include "gsm_private.h" + +#include "gsm.h" +#include "gsm_proto.h" + +#undef P + +/* + * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION + */ + +/* 4.2.4 */ + + +static void Autocorrelation P2((s, L_ACF), + word * s, /* [0..159] IN/OUT */ + longword * L_ACF) /* [0..8] OUT */ +/* + * The goal is to compute the array L_ACF[k]. The signal s[i] must + * be scaled in order to avoid an overflow situation. + */ +{ + register int k, i; + + word temp, smax, scalauto; + +#ifdef USE_FLOAT_MUL + float float_s[160]; +#endif + + /* Dynamic scaling of the array s[0..159] + */ + + /* Search for the maximum. + */ + smax = 0; + for (k = 0; k <= 159; k++) { + temp = GSM_ABS( s[k] ); + if (temp > smax) smax = temp; + } + + /* Computation of the scaling factor. + */ + if (smax == 0) scalauto = 0; + else { + assert(smax > 0); + scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */ + } + + /* Scaling of the array s[0...159] + */ + + if (scalauto > 0) { + +# ifdef USE_FLOAT_MUL +# define SCALE(n) \ + case n: for (k = 0; k <= 159; k++) \ + float_s[k] = (float) \ + (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\ + break; +# else +# define SCALE(n) \ + case n: for (k = 0; k <= 159; k++) \ + s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\ + break; +# endif /* USE_FLOAT_MUL */ + + switch (scalauto) { + SCALE(1) + SCALE(2) + SCALE(3) + SCALE(4) + } +# undef SCALE + } +# ifdef USE_FLOAT_MUL + else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k]; +# endif + + /* Compute the L_ACF[..]. + */ + { +# ifdef USE_FLOAT_MUL + register float * sp = float_s; + register float sl = *sp; + +# define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]); +# else + word * sp = s; + word sl = *sp; + +# define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]); +# endif + +# define NEXTI sl = *++sp + + + for (k = 9; k--; L_ACF[k] = 0) ; + + STEP (0); + NEXTI; + STEP(0); STEP(1); + NEXTI; + STEP(0); STEP(1); STEP(2); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); + + for (i = 8; i <= 159; i++) { + + NEXTI; + + STEP(0); + STEP(1); STEP(2); STEP(3); STEP(4); + STEP(5); STEP(6); STEP(7); STEP(8); + } + + for (k = 9; k--; L_ACF[k] <<= 1) ; + + } + /* Rescaling of the array s[0..159] + */ + if (scalauto > 0) { + assert(scalauto <= 4); + for (k = 160; k--; *s++ <<= scalauto) ; + } +} + +#if defined(USE_FLOAT_MUL) && defined(FAST) + +static void Fast_Autocorrelation P2((s, L_ACF), + word * s, /* [0..159] IN/OUT */ + longword * L_ACF) /* [0..8] OUT */ +{ + register int k, i; + float f_L_ACF[9]; + float scale; + + float s_f[160]; + register float *sf = s_f; + + for (i = 0; i < 160; ++i) sf[i] = s[i]; + for (k = 0; k <= 8; k++) { + register float L_temp2 = 0; + register float *sfl = sf - k; + for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i]; + f_L_ACF[k] = L_temp2; + } + scale = MAX_LONGWORD / f_L_ACF[0]; + + for (k = 0; k <= 8; k++) { + L_ACF[k] = f_L_ACF[k] * scale; + } +} +#endif /* defined (USE_FLOAT_MUL) && defined (FAST) */ + +/* 4.2.5 */ + +static void Reflection_coefficients P2( (L_ACF, r), + longword * L_ACF, /* 0...8 IN */ + register word * r /* 0...7 OUT */ +) +{ + register int i, m, n; + register word temp; + register longword ltmp; + word ACF[9]; /* 0..8 */ + word P[ 9]; /* 0..8 */ + word K[ 9]; /* 2..8 */ + + /* Schur recursion with 16 bits arithmetic. + */ + + if (L_ACF[0] == 0) { + for (i = 8; i--; *r++ = 0) ; + return; + } + + assert( L_ACF[0] != 0 ); + temp = gsm_norm( L_ACF[0] ); + + assert(temp >= 0 && temp < 32); + + /* ? overflow ? */ + for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 ); + + /* Initialize array P[..] and K[..] for the recursion. + */ + + for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ]; + for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ]; + + /* Compute reflection coefficients + */ + for (n = 1; n <= 8; n++, r++) { + + temp = P[1]; + temp = GSM_ABS(temp); + if (P[0] < temp) { + for (i = n; i <= 8; i++) *r++ = 0; + return; + } + + *r = gsm_div( temp, P[0] ); + + assert(*r >= 0); + if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */ + assert (*r != MIN_WORD); + if (n == 8) return; + + /* Schur recursion + */ + temp = GSM_MULT_R( P[1], *r ); + P[0] = (word) GSM_ADD( P[0], temp ); + + for (m = 1; m <= 8 - n; m++) { + temp = GSM_MULT_R( K[ m ], *r ); + P[m] = (word) GSM_ADD( P[ m+1 ], temp ); + + temp = GSM_MULT_R( P[ m+1 ], *r ); + K[m] = (word) GSM_ADD( K[ m ], temp ); + } + } +} + +/* 4.2.6 */ + +static void Transformation_to_Log_Area_Ratios P1((r), + register word * r /* 0..7 IN/OUT */ +) +/* + * The following scaling for r[..] and LAR[..] has been used: + * + * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. + * LAR[..] = integer( real_LAR[..] * 16384 ); + * with -1.625 <= real_LAR <= 1.625 + */ +{ + register word temp; + register int i; + + + /* Computation of the LAR[0..7] from the r[0..7] + */ + for (i = 1; i <= 8; i++, r++) { + + temp = *r; + temp = GSM_ABS(temp); + assert(temp >= 0); + + if (temp < 22118) { + temp >>= 1; + } else if (temp < 31130) { + assert( temp >= 11059 ); + temp -= 11059; + } else { + assert( temp >= 26112 ); + temp -= 26112; + temp <<= 2; + } + + *r = *r < 0 ? -temp : temp; + assert( *r != MIN_WORD ); + } +} + +/* 4.2.7 */ + +static void Quantization_and_coding P1((LAR), + register word * LAR /* [0..7] IN/OUT */ +) +{ + register word temp; + longword ltmp; + + + /* This procedure needs four tables; the following equations + * give the optimum scaling for the constants: + * + * A[0..7] = integer( real_A[0..7] * 1024 ) + * B[0..7] = integer( real_B[0..7] * 512 ) + * MAC[0..7] = maximum of the LARc[0..7] + * MIC[0..7] = minimum of the LARc[0..7] + */ + +# undef STEP +# define STEP( A, B, MAC, MIC ) \ + temp = GSM_MULT( A, *LAR ); \ + temp = (word) GSM_ADD( temp, B ); \ + temp = (word) GSM_ADD( temp, 256 ); \ + temp = SASR( temp, 9 ); \ + *LAR = temp>MAC ? MAC - MIC : (tempfast) Fast_Autocorrelation (s, L_ACF ); + else +#endif + Autocorrelation (s, L_ACF ); + Reflection_coefficients (L_ACF, LARc ); + Transformation_to_Log_Area_Ratios (LARc); + Quantization_and_coding (LARc); +} diff --git a/src/libs/libgsm/gsm_option.c b/src/libs/libgsm/gsm_option.c new file mode 100644 index 00000000..a9d81cf2 --- /dev/null +++ b/src/libs/libgsm/gsm_option.c @@ -0,0 +1,70 @@ +/* + * gsm_option.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#include "gsm_private.h" + +#include "gsm.h" +#include "gsm_proto.h" + +int gsm_option P3((r, opt, val), gsm r, int opt, int * val) +{ + int result = -1; + + switch (opt) { + case GSM_OPT_LTP_CUT: +#ifdef LTP_CUT + result = r->ltp_cut; + if (val) r->ltp_cut = *val; +#endif + break; + + case GSM_OPT_VERBOSE: +#ifndef NDEBUG + result = r->verbose; + if (val) r->verbose = *val; +#endif + break; + + case GSM_OPT_FAST: + +#if defined(FAST) && defined(USE_FLOAT_MUL) + result = r->fast; + if (val) r->fast = !!*val; +#endif + break; + + case GSM_OPT_FRAME_CHAIN: + +#ifdef WAV49 + result = r->frame_chain; + if (val) r->frame_chain = *val; +#endif + break; + + case GSM_OPT_FRAME_INDEX: + +#ifdef WAV49 + result = r->frame_index; + if (val) r->frame_index = *val; +#endif + break; + + case GSM_OPT_WAV49: + +#ifdef WAV49 + result = r->wav_fmt; + if (val) r->wav_fmt = !!*val; +#endif + break; + + default: + break; + } + return result; +} diff --git a/src/libs/libgsm/gsm_preprocess.c b/src/libs/libgsm/gsm_preprocess.c new file mode 100644 index 00000000..29c7e4df --- /dev/null +++ b/src/libs/libgsm/gsm_preprocess.c @@ -0,0 +1,114 @@ +/* + * preprocess.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#include +#include + +#include "gsm_private.h" + +#include "gsm.h" +#include "gsm_proto.h" + +/* 4.2.0 .. 4.2.3 PREPROCESSING SECTION + * + * After A-law to linear conversion (or directly from the + * Ato D converter) the following scaling is assumed for + * input to the RPE-LTP algorithm: + * + * in: 0.1.....................12 + * S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.* + * + * Where S is the sign bit, v a valid bit, and * a "don't care" bit. + * The original signal is called sop[..] + * + * out: 0.1................... 12 + * S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0 + */ + + +void Gsm_Preprocess P3((S, s, so), + struct gsm_state * S, + word * s, + word * so ) /* [0..159] IN/OUT */ +{ + + word z1 = S->z1; + longword L_z2 = S->L_z2; + word mp = S->mp; + + word s1; + longword L_s2; + + longword L_temp; + + word msp, lsp; + word SO; + + longword ltmp; /* for ADD */ + ulongword utmp; /* for L_ADD */ + + register int k = 160; + + while (k--) { + + /* 4.2.1 Downscaling of the input signal + */ + SO = SASR( *s, 3 ) << 2; + s++; + + assert (SO >= -0x4000); /* downscaled by */ + assert (SO <= 0x3FFC); /* previous routine. */ + + + /* 4.2.2 Offset compensation + * + * This part implements a high-pass filter and requires extended + * arithmetic precision for the recursive part of this filter. + * The input of this procedure is the array so[0...159] and the + * output the array sof[ 0...159 ]. + */ + /* Compute the non-recursive part + */ + + s1 = SO - z1; /* s1 = gsm_sub( *so, z1 ); */ + z1 = SO; + + assert(s1 != MIN_WORD); + + /* Compute the recursive part + */ + L_s2 = s1; + L_s2 <<= 15; + + /* Execution of a 31 bv 16 bits multiplication + */ + + msp = SASR( L_z2, 15 ); + lsp = (word) (L_z2-((longword)msp<<15)); /* gsm_L_sub(L_z2,(msp<<15)); */ + + L_s2 += GSM_MULT_R( lsp, 32735 ); + L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/ + L_z2 = GSM_L_ADD( L_temp, L_s2 ); + + /* Compute sof[k] with rounding + */ + L_temp = GSM_L_ADD( L_z2, 16384 ); + + /* 4.2.3 Preemphasis + */ + + msp = GSM_MULT_R( mp, -28180 ); + mp = SASR( L_temp, 15 ); + *so++ = (word) GSM_ADD( mp, msp ); + } + + S->z1 = z1; + S->L_z2 = L_z2; + S->mp = mp; +} diff --git a/src/libs/libgsm/gsm_private.h b/src/libs/libgsm/gsm_private.h new file mode 100644 index 00000000..a7e6f0f8 --- /dev/null +++ b/src/libs/libgsm/gsm_private.h @@ -0,0 +1,269 @@ +/* + * private.h + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#ifndef PRIVATE_H +#define PRIVATE_H + +typedef short word; /* 16 bit signed int */ +typedef long longword; /* 32 bit signed int */ + +typedef unsigned short uword; /* unsigned word */ +typedef unsigned long ulongword; /* unsigned longword */ + +struct gsm_state { + + word dp0[ 280 ]; + + word z1; /* preprocessing.c, Offset_com. */ + longword L_z2; /* Offset_com. */ + int mp; /* Preemphasis */ + + word u[8]; /* short_term_aly_filter.c */ + word LARpp[2][8]; /* */ + word j; /* */ + + word ltp_cut; /* long_term.c, LTP crosscorr. */ + word nrp; /* 40 */ /* long_term.c, synthesis */ + word v[9]; /* short_term.c, synthesis */ + word msr; /* decoder.c, Postprocessing */ + + char verbose; /* only used if !NDEBUG */ + char fast; /* only used if FAST */ + + char wav_fmt; /* only used if WAV49 defined */ + unsigned char frame_index; /* odd/even chaining */ + unsigned char frame_chain; /* half-byte to carry forward */ +}; + + +#define MIN_WORD (-32767 - 1) +#define MAX_WORD 32767 + +#define MIN_LONGWORD (-2147483647 - 1) +#define MAX_LONGWORD 2147483647 + +#ifdef SASR /* flag: >> is a signed arithmetic shift right */ +#undef SASR +#define SASR(x, by) ((x) >> (by)) +#else +#define SASR(x, by) ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by)))) +#endif /* SASR */ + +#include "gsm_proto.h" + +/* + * Prototypes from add.c + */ +extern word gsm_mult P((word a, word b)); +extern longword gsm_L_mult P((word a, word b)); +extern word gsm_mult_r P((word a, word b)); + +extern word gsm_div P((word num, word denum)); + +extern word gsm_add P(( word a, word b )); +extern longword gsm_L_add P(( longword a, longword b )); + +extern word gsm_sub P((word a, word b)); +extern longword gsm_L_sub P((longword a, longword b)); + +extern word gsm_abs P((word a)); + +extern word gsm_norm P(( longword a )); + +extern longword gsm_L_asl P((longword a, int n)); +extern word gsm_asl P((word a, int n)); + +extern longword gsm_L_asr P((longword a, int n)); +extern word gsm_asr P((word a, int n)); + +/* + * Inlined functions from add.h + */ + +/* + * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *) \ + * (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15)) + */ +#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \ + (SASR( ((longword)(a) * (longword)(b) + 16384), 15 )) + +# define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \ + (SASR( ((longword)(a) * (longword)(b)), 15 )) + +# define GSM_L_MULT(a, b) /* word a, word b */ \ + (((longword)(a) * (longword)(b)) << 1) + +# define GSM_L_ADD(a, b) \ + ( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \ + : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \ + >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \ + : ((b) <= 0 ? (a) + (b) \ + : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \ + ? MAX_LONGWORD : utmp)) + +/* + * # define GSM_ADD(a, b) \ + * ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \ + * ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + */ +/* Nonportable, but faster: */ + +#define GSM_ADD(a, b) \ + ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \ + MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp) + +# define GSM_SUB(a, b) \ + ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \ + ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + +# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a)) + +/* Use these if necessary: + +# define GSM_MULT_R(a, b) gsm_mult_r(a, b) +# define GSM_MULT(a, b) gsm_mult(a, b) +# define GSM_L_MULT(a, b) gsm_L_mult(a, b) + +# define GSM_L_ADD(a, b) gsm_L_add(a, b) +# define GSM_ADD(a, b) gsm_add(a, b) +# define GSM_SUB(a, b) gsm_sub(a, b) + +# define GSM_ABS(a) gsm_abs(a) + +*/ + +/* + * More prototypes from implementations.. + */ +extern void Gsm_Coder P(( + struct gsm_state * S, + word * s, /* [0..159] samples IN */ + word * LARc, /* [0..7] LAR coefficients OUT */ + word * Nc, /* [0..3] LTP lag OUT */ + word * bc, /* [0..3] coded LTP gain OUT */ + word * Mc, /* [0..3] RPE grid selection OUT */ + word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ + word * xMc /* [13*4] normalized RPE samples OUT */)); + +extern void Gsm_Long_Term_Predictor P(( /* 4x for 160 samples */ + struct gsm_state * S, + word * d, /* [0..39] residual signal IN */ + word * dp, /* [-120..-1] d' IN */ + word * e, /* [0..40] OUT */ + word * dpp, /* [0..40] OUT */ + word * Nc, /* correlation lag OUT */ + word * bc /* gain factor OUT */)); + +extern void Gsm_LPC_Analysis P(( + struct gsm_state * S, + word * s, /* 0..159 signals IN/OUT */ + word * LARc)); /* 0..7 LARc's OUT */ + +extern void Gsm_Preprocess P(( + struct gsm_state * S, + word * s, word * so)); + +extern void Gsm_Encoding P(( + struct gsm_state * S, + word * e, + word * ep, + word * xmaxc, + word * Mc, + word * xMc)); + +extern void Gsm_Short_Term_Analysis_Filter P(( + struct gsm_state * S, + word * LARc, /* coded log area ratio [0..7] IN */ + word * d /* st res. signal [0..159] IN/OUT */)); + +extern void Gsm_Decoder P(( + struct gsm_state * S, + word * LARcr, /* [0..7] IN */ + word * Ncr, /* [0..3] IN */ + word * bcr, /* [0..3] IN */ + word * Mcr, /* [0..3] IN */ + word * xmaxcr, /* [0..3] IN */ + word * xMcr, /* [0..13*4] IN */ + word * s)); /* [0..159] OUT */ + +extern void Gsm_Decoding P(( + struct gsm_state * S, + word xmaxcr, + word Mcr, + word * xMcr, /* [0..12] IN */ + word * erp)); /* [0..39] OUT */ + +extern void Gsm_Long_Term_Synthesis_Filtering P(( + struct gsm_state* S, + word Ncr, + word bcr, + word * erp, /* [0..39] IN */ + word * drp)); /* [-120..-1] IN, [0..40] OUT */ + +void Gsm_RPE_Decoding P(( + struct gsm_state *S, + word xmaxcr, + word Mcr, + word * xMcr, /* [0..12], 3 bits IN */ + word * erp)); /* [0..39] OUT */ + +void Gsm_RPE_Encoding P(( + struct gsm_state * S, + word * e, /* -5..-1][0..39][40..44 IN/OUT */ + word * xmaxc, /* OUT */ + word * Mc, /* OUT */ + word * xMc)); /* [0..12] OUT */ + +extern void Gsm_Short_Term_Synthesis_Filter P(( + struct gsm_state * S, + word * LARcr, /* log area ratios [0..7] IN */ + word * drp, /* received d [0...39] IN */ + word * s)); /* signal s [0..159] OUT */ + +extern void Gsm_Update_of_reconstructed_short_time_residual_signal P(( + word * dpp, /* [0...39] IN */ + word * ep, /* [0...39] IN */ + word * dp)); /* [-120...-1] IN/OUT */ + +/* + * Tables from table.c + */ +#ifndef GSM_TABLE_C + +extern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8]; +extern word gsm_INVA[8]; +extern word gsm_DLB[4], gsm_QLB[4]; +extern word gsm_H[11]; +extern word gsm_NRFAC[8]; +extern word gsm_FAC[8]; + +#endif /* GSM_TABLE_C */ + +/* + * Debugging + */ +#ifdef NDEBUG + +# define gsm_debug_words(a, b, c, d) /* nil */ +# define gsm_debug_longwords(a, b, c, d) /* nil */ +# define gsm_debug_word(a, b) /* nil */ +# define gsm_debug_longword(a, b) /* nil */ + +#else /* !NDEBUG => DEBUG */ + + extern void gsm_debug_words P((char * name, int, int, word *)); + extern void gsm_debug_longwords P((char * name, int, int, longword *)); + extern void gsm_debug_longword P((char * name, longword)); + extern void gsm_debug_word P((char * name, word)); + +#endif /* !NDEBUG */ + +#include "gsm_unproto.h" + +#endif /* PRIVATE_H */ diff --git a/src/libs/libgsm/gsm_proto.h b/src/libs/libgsm/gsm_proto.h new file mode 100644 index 00000000..7858c4e9 --- /dev/null +++ b/src/libs/libgsm/gsm_proto.h @@ -0,0 +1,66 @@ +/* + * proto.h + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#ifndef PROTO_H +#define PROTO_H + +#if __cplusplus +# define NeedFunctionPrototypes 1 +#endif + +#if __STDC__ +# define NeedFunctionPrototypes 1 +#endif + +#ifdef _NO_PROTO +# undef NeedFunctionPrototypes +#endif + +#undef P /* gnu stdio.h actually defines this... */ +#undef P0 +#undef P1 +#undef P2 +#undef P3 +#undef P4 +#undef P5 +#undef P6 +#undef P7 +#undef P8 + +#if NeedFunctionPrototypes + +# define P( protos ) protos + +# define P0() (void) +# define P1(x, a) (a) +# define P2(x, a, b) (a, b) +# define P3(x, a, b, c) (a, b, c) +# define P4(x, a, b, c, d) (a, b, c, d) +# define P5(x, a, b, c, d, e) (a, b, c, d, e) +# define P6(x, a, b, c, d, e, f) (a, b, c, d, e, f) +# define P7(x, a, b, c, d, e, f, g) (a, b, c, d, e, f, g) +# define P8(x, a, b, c, d, e, f, g, h) (a, b, c, d, e, f, g, h) + +#else /* !NeedFunctionPrototypes */ + +# define P( protos ) ( /* protos */ ) + +# define P0() () +# define P1(x, a) x a; +# define P2(x, a, b) x a; b; +# define P3(x, a, b, c) x a; b; c; +# define P4(x, a, b, c, d) x a; b; c; d; +# define P5(x, a, b, c, d, e) x a; b; c; d; e; +# define P6(x, a, b, c, d, e, f) x a; b; c; d; e; f; +# define P7(x, a, b, c, d, e, f, g) x a; b; c; d; e; f; g; +# define P8(x, a, b, c, d, e, f, g, h) x a; b; c; d; e; f; g; h; + +#endif /* !NeedFunctionPrototypes */ + +#endif /* PROTO_H */ diff --git a/src/libs/libgsm/gsm_rpe.c b/src/libs/libgsm/gsm_rpe.c new file mode 100644 index 00000000..501b8974 --- /dev/null +++ b/src/libs/libgsm/gsm_rpe.c @@ -0,0 +1,489 @@ +/* + * rpe.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#include +#include + +#include "gsm_private.h" + +#include "gsm.h" +#include "gsm_proto.h" + +/* 4.2.13 .. 4.2.17 RPE ENCODING SECTION + */ + +/* 4.2.13 */ + +static void Weighting_filter P2((e, x), + register word * e, /* signal [-5..0.39.44] IN */ + word * x /* signal [0..39] OUT */ +) +/* + * The coefficients of the weighting filter are stored in a table + * (see table 4.4). The following scaling is used: + * + * H[0..10] = integer( real_H[ 0..10] * 8192 ); + */ +{ + /* word wt[ 50 ]; */ + + register longword L_result; + register int k /* , i */ ; + + /* Initialization of a temporary working array wt[0...49] + */ + + /* for (k = 0; k <= 4; k++) wt[k] = 0; + * for (k = 5; k <= 44; k++) wt[k] = *e++; + * for (k = 45; k <= 49; k++) wt[k] = 0; + * + * (e[-5..-1] and e[40..44] are allocated by the caller, + * are initially zero and are not written anywhere.) + */ + e -= 5; + + /* Compute the signal x[0..39] + */ + for (k = 0; k <= 39; k++) { + + L_result = 8192 >> 1; + + /* for (i = 0; i <= 10; i++) { + * L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] ); + * L_result = GSM_L_ADD( L_result, L_temp ); + * } + */ + +#undef STEP +#define STEP( i, H ) (e[ k + i ] * (longword)H) + + /* Every one of these multiplications is done twice -- + * but I don't see an elegant way to optimize this. + * Do you? + */ + +#ifdef STUPID_COMPILER + L_result += STEP( 0, -134 ) ; + L_result += STEP( 1, -374 ) ; + /* + STEP( 2, 0 ) */ + L_result += STEP( 3, 2054 ) ; + L_result += STEP( 4, 5741 ) ; + L_result += STEP( 5, 8192 ) ; + L_result += STEP( 6, 5741 ) ; + L_result += STEP( 7, 2054 ) ; + /* + STEP( 8, 0 ) */ + L_result += STEP( 9, -374 ) ; + L_result += STEP( 10, -134 ) ; +#else + L_result += + STEP( 0, -134 ) + + STEP( 1, -374 ) + /* + STEP( 2, 0 ) */ + + STEP( 3, 2054 ) + + STEP( 4, 5741 ) + + STEP( 5, 8192 ) + + STEP( 6, 5741 ) + + STEP( 7, 2054 ) + /* + STEP( 8, 0 ) */ + + STEP( 9, -374 ) + + STEP(10, -134 ) + ; +#endif + + /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *) + * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *) + * + * x[k] = SASR( L_result, 16 ); + */ + + /* 2 adds vs. >>16 => 14, minus one shift to compensate for + * those we lost when replacing L_MULT by '*'. + */ + + L_result = SASR( L_result, 13 ); + x[k] = (word) (( L_result < MIN_WORD ? MIN_WORD + : (L_result > MAX_WORD ? MAX_WORD : L_result ))); + } +} + +/* 4.2.14 */ + +static void RPE_grid_selection P3((x,xM,Mc_out), + word * x, /* [0..39] IN */ + word * xM, /* [0..12] OUT */ + word * Mc_out /* OUT */ +) +/* + * The signal x[0..39] is used to select the RPE grid which is + * represented by Mc. + */ +{ + /* register word temp1; */ + register int /* m, */ i; + register longword L_result, L_temp; + longword EM; /* xxx should be L_EM? */ + word Mc; + + longword L_common_0_3; + + EM = 0; + Mc = 0; + + /* for (m = 0; m <= 3; m++) { + * L_result = 0; + * + * + * for (i = 0; i <= 12; i++) { + * + * temp1 = SASR( x[m + 3*i], 2 ); + * + * assert(temp1 != MIN_WORD); + * + * L_temp = GSM_L_MULT( temp1, temp1 ); + * L_result = GSM_L_ADD( L_temp, L_result ); + * } + * + * if (L_result > EM) { + * Mc = m; + * EM = L_result; + * } + * } + */ + +#undef STEP +#define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \ + L_result += L_temp * L_temp; + + /* common part of 0 and 3 */ + + L_result = 0; + STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 ); + STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 ); + STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12); + L_common_0_3 = L_result; + + /* i = 0 */ + + STEP( 0, 0 ); + L_result <<= 1; /* implicit in L_MULT */ + EM = L_result; + + /* i = 1 */ + + L_result = 0; + STEP( 1, 0 ); + STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 ); + STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 ); + STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12); + L_result <<= 1; + if (L_result > EM) { + Mc = 1; + EM = L_result; + } + + /* i = 2 */ + + L_result = 0; + STEP( 2, 0 ); + STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 ); + STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 ); + STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12); + L_result <<= 1; + if (L_result > EM) { + Mc = 2; + EM = L_result; + } + + /* i = 3 */ + + L_result = L_common_0_3; + STEP( 3, 12 ); + L_result <<= 1; + if (L_result > EM) { + Mc = 3; + EM = L_result; + } + + /**/ + + /* Down-sampling by a factor 3 to get the selected xM[0..12] + * RPE sequence. + */ + for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i]; + *Mc_out = Mc; +} + +/* 4.12.15 */ + +static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out), + word xmaxc, /* IN */ + word * exp_out, /* OUT */ + word * mant_out ) /* OUT */ +{ + word exp, mant; + + /* Compute exponent and mantissa of the decoded version of xmaxc + */ + + exp = 0; + if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1; + mant = xmaxc - (exp << 3); + + if (mant == 0) { + exp = -4; + mant = 7; + } + else { + while (mant <= 7) { + mant = mant << 1 | 1; + exp--; + } + mant -= 8; + } + + assert( exp >= -4 && exp <= 6 ); + assert( mant >= 0 && mant <= 7 ); + + *exp_out = exp; + *mant_out = mant; +} + +static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out), + word * xM, /* [0..12] IN */ + + word * xMc, /* [0..12] OUT */ + word * mant_out, /* OUT */ + word * exp_out, /* OUT */ + word * xmaxc_out /* OUT */ +) +{ + int i, itest; + + word xmax, xmaxc, temp, temp1, temp2; + word exp, mant; + + + /* Find the maximum absolute value xmax of xM[0..12]. + */ + + xmax = 0; + for (i = 0; i <= 12; i++) { + temp = xM[i]; + temp = GSM_ABS(temp); + if (temp > xmax) xmax = temp; + } + + /* Qantizing and coding of xmax to get xmaxc. + */ + + exp = 0; + temp = SASR( xmax, 9 ); + itest = 0; + + for (i = 0; i <= 5; i++) { + + itest |= (temp <= 0); + temp = SASR( temp, 1 ); + + assert(exp <= 5); + if (itest == 0) exp++; /* exp = add (exp, 1) */ + } + + assert(exp <= 6 && exp >= 0); + temp = exp + 5; + + assert(temp <= 11 && temp >= 0); + xmaxc = gsm_add( SASR(xmax, temp), exp << 3 ); + + /* Quantizing and coding of the xM[0..12] RPE sequence + * to get the xMc[0..12] + */ + + APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); + + /* This computation uses the fact that the decoded version of xmaxc + * can be calculated by using the exponent and the mantissa part of + * xmaxc (logarithmic table). + * So, this method avoids any division and uses only a scaling + * of the RPE samples by a function of the exponent. A direct + * multiplication by the inverse of the mantissa (NRFAC[0..7] + * found in table 4.5) gives the 3 bit coded version xMc[0..12] + * of the RPE samples. + */ + + + /* Direct computation of xMc[0..12] using table 4.5 + */ + + assert( exp <= 4096 && exp >= -4096); + assert( mant >= 0 && mant <= 7 ); + + temp1 = 6 - exp; /* normalization by the exponent */ + temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */ + + for (i = 0; i <= 12; i++) { + + assert(temp1 >= 0 && temp1 < 16); + + temp = xM[i] << temp1; + temp = GSM_MULT( temp, temp2 ); + temp = SASR(temp, 12); + xMc[i] = temp + 4; /* see note below */ + } + + /* NOTE: This equation is used to make all the xMc[i] positive. + */ + + *mant_out = mant; + *exp_out = exp; + *xmaxc_out = xmaxc; +} + +/* 4.2.16 */ + +static void APCM_inverse_quantization P4((xMc,mant,exp,xMp), + register word * xMc, /* [0..12] IN */ + word mant, + word exp, + register word * xMp) /* [0..12] OUT */ +/* + * This part is for decoding the RPE sequence of coded xMc[0..12] + * samples to obtain the xMp[0..12] array. Table 4.6 is used to get + * the mantissa of xmaxc (FAC[0..7]). + */ +{ + int i; + word temp, temp1, temp2, temp3; + longword ltmp; + + assert( mant >= 0 && mant <= 7 ); + + temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */ + temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */ + temp3 = gsm_asl( 1, gsm_sub( temp2, 1 )); + + for (i = 13; i--;) { + + assert( *xMc <= 7 && *xMc >= 0 ); /* 3 bit unsigned */ + + /* temp = gsm_sub( *xMc++ << 1, 7 ); */ + temp = (*xMc++ << 1) - 7; /* restore sign */ + assert( temp <= 7 && temp >= -7 ); /* 4 bit signed */ + + temp <<= 12; /* 16 bit signed */ + temp = GSM_MULT_R( temp1, temp ); + temp = (word) GSM_ADD( temp, temp3 ); + *xMp++ = gsm_asr( temp, temp2 ); + } +} + +/* 4.2.17 */ + +static void RPE_grid_positioning P3((Mc,xMp,ep), + word Mc, /* grid position IN */ + register word * xMp, /* [0..12] IN */ + register word * ep /* [0..39] OUT */ +) +/* + * This procedure computes the reconstructed long term residual signal + * ep[0..39] for the LTP analysis filter. The inputs are the Mc + * which is the grid position selection and the xMp[0..12] decoded + * RPE samples which are upsampled by a factor of 3 by inserting zero + * values. + */ +{ + int i = 13; + + assert(0 <= Mc && Mc <= 3); + + switch (Mc) { + case 3: *ep++ = 0; + case 2: do { + *ep++ = 0; + case 1: *ep++ = 0; + case 0: *ep++ = *xMp++; + } while (--i); + } + while (++Mc < 4) *ep++ = 0; + + /* + + int i, k; + for (k = 0; k <= 39; k++) ep[k] = 0; + for (i = 0; i <= 12; i++) { + ep[ Mc + (3*i) ] = xMp[i]; + } + */ +} + +/* 4.2.18 */ + +/* This procedure adds the reconstructed long term residual signal + * ep[0..39] to the estimated signal dpp[0..39] from the long term + * analysis filter to compute the reconstructed short term residual + * signal dp[-40..-1]; also the reconstructed short term residual + * array dp[-120..-41] is updated. + */ + +#if 0 /* Has been inlined in code.c */ +void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp), + word * dpp, /* [0...39] IN */ + word * ep, /* [0...39] IN */ + word * dp) /* [-120...-1] IN/OUT */ +{ + int k; + + for (k = 0; k <= 79; k++) + dp[ -120 + k ] = dp[ -80 + k ]; + + for (k = 0; k <= 39; k++) + dp[ -40 + k ] = gsm_add( ep[k], dpp[k] ); +} +#endif /* Has been inlined in code.c */ + +void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc), + + struct gsm_state * S, + + word * e, /* -5..-1][0..39][40..44 IN/OUT */ + word * xmaxc, /* OUT */ + word * Mc, /* OUT */ + word * xMc) /* [0..12] OUT */ +{ + word x[40]; + word xM[13], xMp[13]; + word mant, exp; + + Weighting_filter(e, x); + RPE_grid_selection(x, xM, Mc); + + APCM_quantization( xM, xMc, &mant, &exp, xmaxc); + APCM_inverse_quantization( xMc, mant, exp, xMp); + + RPE_grid_positioning( *Mc, xMp, e ); + +} + +void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp), + struct gsm_state * S, + + word xmaxcr, + word Mcr, + word * xMcr, /* [0..12], 3 bits IN */ + word * erp /* [0..39] OUT */ +) +{ + word exp, mant; + word xMp[ 13 ]; + + APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant ); + APCM_inverse_quantization( xMcr, mant, exp, xMp ); + RPE_grid_positioning( Mcr, xMp, erp ); + +} diff --git a/src/libs/libgsm/gsm_short_term.c b/src/libs/libgsm/gsm_short_term.c new file mode 100644 index 00000000..7571a087 --- /dev/null +++ b/src/libs/libgsm/gsm_short_term.c @@ -0,0 +1,430 @@ +/* + * short_term.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#include +#include + +#include "gsm_private.h" + +#include "gsm.h" +#include "gsm_proto.h" + +/* + * SHORT TERM ANALYSIS FILTERING SECTION + */ + +/* 4.2.8 */ + +static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp), + word * LARc, /* coded log area ratio [0..7] IN */ + word * LARpp) /* out: decoded .. */ +{ + register word temp1 /* , temp2 */; + register long ltmp; /* for GSM_ADD */ + + /* This procedure requires for efficient implementation + * two tables. + * + * INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) + * MIC[1..8] = minimum value of the LARc[1..8] + */ + + /* Compute the LARpp[1..8] + */ + + /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) { + * + * temp1 = GSM_ADD( *LARc, *MIC ) << 10; + * temp2 = *B << 1; + * temp1 = GSM_SUB( temp1, temp2 ); + * + * assert(*INVA != MIN_WORD); + * + * temp1 = GSM_MULT_R( *INVA, temp1 ); + * *LARpp = GSM_ADD( temp1, temp1 ); + * } + */ + +#undef STEP +#define STEP( B, MIC, INVA ) \ + temp1 = (word) GSM_ADD( *LARc++, MIC ) << 10; \ + temp1 = (word) GSM_SUB( temp1, B << 1 ); \ + temp1 = GSM_MULT_R( INVA, temp1 ); \ + *LARpp++ = (word) GSM_ADD( temp1, temp1 ); + + STEP( 0, -32, 13107 ); + STEP( 0, -32, 13107 ); + STEP( 2048, -16, 13107 ); + STEP( -2560, -16, 13107 ); + + STEP( 94, -8, 19223 ); + STEP( -1792, -8, 17476 ); + STEP( -341, -4, 31454 ); + STEP( -1144, -4, 29708 ); + + /* NOTE: the addition of *MIC is used to restore + * the sign of *LARc. + */ +} + +/* 4.2.9 */ +/* Computation of the quantized reflection coefficients + */ + +/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] + */ + +/* + * Within each frame of 160 analyzed speech samples the short term + * analysis and synthesis filters operate with four different sets of + * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) + * and the actual set of decoded LARs (LARpp(j)) + * + * (Initial value: LARpp(j-1)[1..8] = 0.) + */ + +static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp), + register word * LARpp_j_1, + register word * LARpp_j, + register word * LARp) +{ + register int i; + register longword ltmp; + + for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) { + *LARp = (word) GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); + *LARp = (word) GSM_ADD( *LARp, SASR( *LARpp_j_1, 1)); + } +} + +static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp), + register word * LARpp_j_1, + register word * LARpp_j, + register word * LARp) +{ + register int i; + register longword ltmp; + for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { + *LARp = (word) GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 )); + } +} + +static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp), + register word * LARpp_j_1, + register word * LARpp_j, + register word * LARp) +{ + register int i; + register longword ltmp; + + for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { + *LARp = (word) GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); + *LARp = (word) GSM_ADD( *LARp, SASR( *LARpp_j, 1 )); + } +} + + +static void Coefficients_40_159 P2((LARpp_j, LARp), + register word * LARpp_j, + register word * LARp) +{ + register int i; + + for (i = 1; i <= 8; i++, LARp++, LARpp_j++) + *LARp = *LARpp_j; +} + +/* 4.2.9.2 */ + +static void LARp_to_rp P1((LARp), + register word * LARp) /* [0..7] IN/OUT */ +/* + * The input of this procedure is the interpolated LARp[0..7] array. + * The reflection coefficients, rp[i], are used in the analysis + * filter and in the synthesis filter. + */ +{ + register int i; + register word temp; + register longword ltmp; + + for (i = 1; i <= 8; i++, LARp++) { + + /* temp = GSM_ABS( *LARp ); + * + * if (temp < 11059) temp <<= 1; + * else if (temp < 20070) temp += 11059; + * else temp = GSM_ADD( temp >> 2, 26112 ); + * + * *LARp = *LARp < 0 ? -temp : temp; + */ + + if (*LARp < 0) { + temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp); + *LARp = - ((temp < 11059) ? temp << 1 + : ((temp < 20070) ? temp + 11059 + : (word) GSM_ADD( temp >> 2, 26112 ))); + } else { + temp = *LARp; + *LARp = (temp < 11059) ? temp << 1 + : ((temp < 20070) ? temp + 11059 + : (word) GSM_ADD( temp >> 2, 26112 )); + } + } +} + + +/* 4.2.10 */ +static void Short_term_analysis_filtering P4((S,rp,k_n,s), + struct gsm_state * S, + register word * rp, /* [0..7] IN */ + register int k_n, /* k_end - k_start */ + register word * s /* [0..n-1] IN/OUT */ +) +/* + * This procedure computes the short term residual signal d[..] to be fed + * to the RPE-LTP loop from the s[..] signal and from the local rp[..] + * array (quantized reflection coefficients). As the call of this + * procedure can be done in many ways (see the interpolation of the LAR + * coefficient), it is assumed that the computation begins with index + * k_start (for arrays d[..] and s[..]) and stops with index k_end + * (k_start and k_end are defined in 4.2.9.1). This procedure also + * needs to keep the array u[0..7] in memory for each call. + */ +{ + register word * u = S->u; + register int i; + register word di, zzz, ui, sav, rpi; + register longword ltmp; + + for (; k_n--; s++) { + + di = sav = *s; + + for (i = 0; i < 8; i++) { /* YYY */ + + ui = u[i]; + rpi = rp[i]; + u[i] = sav; + + zzz = GSM_MULT_R(rpi, di); + sav = (word) GSM_ADD( ui, zzz); + + zzz = GSM_MULT_R(rpi, ui); + di = (word) GSM_ADD( di, zzz ); + } + + *s = di; + } +} + +#if defined(USE_FLOAT_MUL) && defined(FAST) + +static void Fast_Short_term_analysis_filtering P4((S,rp,k_n,s), + struct gsm_state * S, + register word * rp, /* [0..7] IN */ + register int k_n, /* k_end - k_start */ + register word * s /* [0..n-1] IN/OUT */ +) +{ + register word * u = S->u; + register int i; + + float uf[8], + rpf[8]; + + register float scalef = 3.0517578125e-5; + register float sav, di, temp; + + for (i = 0; i < 8; ++i) { + uf[i] = u[i]; + rpf[i] = rp[i] * scalef; + } + for (; k_n--; s++) { + sav = di = *s; + for (i = 0; i < 8; ++i) { + register float rpfi = rpf[i]; + register float ufi = uf[i]; + + uf[i] = sav; + temp = rpfi * di + ufi; + di += rpfi * ufi; + sav = temp; + } + *s = di; + } + for (i = 0; i < 8; ++i) u[i] = uf[i]; +} +#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */ + +static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), + struct gsm_state * S, + register word * rrp, /* [0..7] IN */ + register int k, /* k_end - k_start */ + register word * wt, /* [0..k-1] IN */ + register word * sr /* [0..k-1] OUT */ +) +{ + register word * v = S->v; + register int i; + register word sri, tmp1, tmp2; + register longword ltmp; /* for GSM_ADD & GSM_SUB */ + + while (k--) { + sri = *wt++; + for (i = 8; i--;) { + + /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) ); + */ + tmp1 = rrp[i]; + tmp2 = v[i]; + tmp2 = ( tmp1 == MIN_WORD && tmp2 == MIN_WORD + ? MAX_WORD + : 0x0FFFF & (( (longword)tmp1 * (longword)tmp2 + + 16384) >> 15)) ; + + sri = (word) GSM_SUB( sri, tmp2 ); + + /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) ); + */ + tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD + ? MAX_WORD + : 0x0FFFF & (( (longword)tmp1 * (longword)sri + + 16384) >> 15)) ; + + v[i+1] = (word) GSM_ADD( v[i], tmp1); + } + *sr++ = v[0] = sri; + } +} + + +#if defined(FAST) && defined(USE_FLOAT_MUL) + +static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), + struct gsm_state * S, + register word * rrp, /* [0..7] IN */ + register int k, /* k_end - k_start */ + register word * wt, /* [0..k-1] IN */ + register word * sr /* [0..k-1] OUT */ +) +{ + register word * v = S->v; + register int i; + + float va[9], rrpa[8]; + register float scalef = 3.0517578125e-5, temp; + + for (i = 0; i < 8; ++i) { + va[i] = v[i]; + rrpa[i] = (float)rrp[i] * scalef; + } + while (k--) { + register float sri = *wt++; + for (i = 8; i--;) { + sri -= rrpa[i] * va[i]; + if (sri < -32768.) sri = -32768.; + else if (sri > 32767.) sri = 32767.; + + temp = va[i] + rrpa[i] * sri; + if (temp < -32768.) temp = -32768.; + else if (temp > 32767.) temp = 32767.; + va[i+1] = temp; + } + *sr++ = va[0] = sri; + } + for (i = 0; i < 9; ++i) v[i] = va[i]; +} + +#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */ + +void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s), + + struct gsm_state * S, + + word * LARc, /* coded log area ratio [0..7] IN */ + word * s /* signal [0..159] IN/OUT */ +) +{ + word * LARpp_j = S->LARpp[ S->j ]; + word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ]; + + word LARp[8]; + +#undef FILTER +#if defined(FAST) && defined(USE_FLOAT_MUL) +# define FILTER (* (S->fast \ + ? Fast_Short_term_analysis_filtering \ + : Short_term_analysis_filtering )) + +#else +# define FILTER Short_term_analysis_filtering +#endif + + Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j ); + + Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); + LARp_to_rp( LARp ); + FILTER( S, LARp, 13, s); + + Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 14, s + 13); + + Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 13, s + 27); + + Coefficients_40_159( LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 120, s + 40); +} + +void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s), + struct gsm_state * S, + + word * LARcr, /* received log area ratios [0..7] IN */ + word * wt, /* received d [0..159] IN */ + + word * s /* signal s [0..159] OUT */ +) +{ + word * LARpp_j = S->LARpp[ S->j ]; + word * LARpp_j_1 = S->LARpp[ S->j ^=1 ]; + + word LARp[8]; + +#undef FILTER +#if defined(FAST) && defined(USE_FLOAT_MUL) + +# define FILTER (* (S->fast \ + ? Fast_Short_term_synthesis_filtering \ + : Short_term_synthesis_filtering )) +#else +# define FILTER Short_term_synthesis_filtering +#endif + + Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j ); + + Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); + LARp_to_rp( LARp ); + FILTER( S, LARp, 13, wt, s ); + + Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 14, wt + 13, s + 13 ); + + Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 13, wt + 27, s + 27 ); + + Coefficients_40_159( LARpp_j, LARp ); + LARp_to_rp( LARp ); + FILTER(S, LARp, 120, wt + 40, s + 40); +} diff --git a/src/libs/libgsm/gsm_table.c b/src/libs/libgsm/gsm_table.c new file mode 100644 index 00000000..740c5013 --- /dev/null +++ b/src/libs/libgsm/gsm_table.c @@ -0,0 +1,64 @@ +/* + * table.c + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +/* Most of these tables are inlined at their point of use. + */ + +/* 4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP + * CODER AND DECODER + * + * (Most of them inlined, so watch out.) + */ + +#define GSM_TABLE_C +#include "gsm_private.h" +#include "gsm.h" + +/* Table 4.1 Quantization of the Log.-Area Ratios + */ +/* i 1 2 3 4 5 6 7 8 */ +word gsm_A[8] = {20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036}; +word gsm_B[8] = { 0, 0, 2048, -2560, 94, -1792, -341, -1144}; +word gsm_MIC[8] = { -32, -32, -16, -16, -8, -8, -4, -4 }; +word gsm_MAC[8] = { 31, 31, 15, 15, 7, 7, 3, 3 }; + + +/* Table 4.2 Tabulation of 1/A[1..8] + */ +word gsm_INVA[8]={ 13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708 }; + + +/* Table 4.3a Decision level of the LTP gain quantizer + */ +/* bc 0 1 2 3 */ +word gsm_DLB[4] = { 6554, 16384, 26214, 32767 }; + + +/* Table 4.3b Quantization levels of the LTP gain quantizer + */ +/* bc 0 1 2 3 */ +word gsm_QLB[4] = { 3277, 11469, 21299, 32767 }; + + +/* Table 4.4 Coefficients of the weighting filter + */ +/* i 0 1 2 3 4 5 6 7 8 9 10 */ +word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 }; + + +/* Table 4.5 Normalized inverse mantissa used to compute xM/xmax + */ +/* i 0 1 2 3 4 5 6 7 */ +word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; + + +/* Table 4.6 Normalized direct mantissa used to compute xM/xmax + */ +/* i 0 1 2 3 4 5 6 7 */ +word gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; diff --git a/src/libs/libgsm/gsm_unproto.h b/src/libs/libgsm/gsm_unproto.h new file mode 100644 index 00000000..3cdb71c2 --- /dev/null +++ b/src/libs/libgsm/gsm_unproto.h @@ -0,0 +1,24 @@ +/* + * unproto.h + * + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#ifdef PROTO_H /* sic */ +#undef PROTO_H + +#undef P +#undef P0 +#undef P1 +#undef P2 +#undef P3 +#undef P4 +#undef P5 +#undef P6 +#undef P7 +#undef P8 + +#endif /* PROTO_H */ diff --git a/src/libs/opencore-amr/AUTHORS b/src/libs/opencore-amr/AUTHORS new file mode 100644 index 00000000..a195537d --- /dev/null +++ b/src/libs/opencore-amr/AUTHORS @@ -0,0 +1 @@ +See README. diff --git a/src/libs/opencore-amr/COPYING b/src/libs/opencore-amr/COPYING new file mode 100644 index 00000000..5ec4bf01 --- /dev/null +++ b/src/libs/opencore-amr/COPYING @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the +copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other +entities that control, are controlled by, or are under common control with +that entity. For the purposes of this definition, "control" means (i) the +power, direct or indirect, to cause the direction or management of such +entity, whether by contract or otherwise, or (ii) ownership of fifty +percent (50%) or more of the outstanding shares, or (iii) beneficial +ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation source, +and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation +or translation of a Source form, including but not limited to compiled +object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice that +is included in or attached to the work (an example is provided in the +Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial +revisions, annotations, elaborations, or other modifications represent, as +a whole, an original work of authorship. For the purposes of this License, +Derivative Works shall not include works that remain separable from, or +merely link (or bind by name) to the interfaces of, the Work and Derivative +Works thereof. + +"Contribution" shall mean any work of authorship, including the original +version of the Work and any modifications or additions to that Work or +Derivative Works thereof, that is intentionally submitted to Licensor for +inclusion in the Work by the copyright owner or by an individual or Legal +Entity authorized to submit on behalf of the copyright owner. For the +purposes of this definition, "submitted" means any form of electronic, +verbal, or written communication sent to the Licensor or its +representatives, including but not limited to communication on electronic +mailing lists, source code control systems, and issue tracking systems that +are managed by, or on behalf of, the Licensor for the purpose of discussing +and improving the Work, but excluding communication that is conspicuously +marked or otherwise designated in writing by the copyright owner as "Not a +Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on +behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this +License, each Contributor hereby grants to You a perpetual, worldwide, +non-exclusive, no-charge, royalty-free, irrevocable copyright license to +reproduce, prepare Derivative Works of, publicly display, publicly perform, +sublicense, and distribute the Work and such Derivative Works in Source or +Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this +License, each Contributor hereby grants to You a perpetual, worldwide, +non-exclusive, no-charge, royalty-free, irrevocable (except as stated in +this section) patent license to make, have made, use, offer to sell, sell, +import, and otherwise transfer the Work, where such license applies only to +those patent claims licensable by such Contributor that are necessarily +infringed by their Contribution(s) alone or by combination of their +Contribution(s) with the Work to which such Contribution(s) was submitted. +If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or +contributory patent infringement, then any patent licenses granted to You +under this License for that Work shall terminate as of the date such +litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or +Derivative Works thereof in any medium, with or without modifications, and +in Source or Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works a +copy of this License; and + + 2. You must cause any modified files to carry prominent notices stating +that You changed the files; and + + 3. You must retain, in the Source form of any Derivative Works that You +distribute, all copyright, patent, trademark, and attribution notices from +the Source form of the Work, excluding those notices that do not pertain to +any part of the Derivative Works; and + + 4. If the Work includes a "NOTICE" text file as part of its +distribution, then any Derivative Works that You distribute must include a +readable copy of the attribution notices contained within such NOTICE file, +excluding those notices that do not pertain to any part of the Derivative +Works, in at least one of the following places: within a NOTICE text file +distributed as part of the Derivative Works; within the Source form or +documentation, if provided along with the Derivative Works; or, within a +display generated by the Derivative Works, if and wherever such third-party +notices normally appear. The contents of the NOTICE file are for +informational purposes only and do not modify the License. You may add Your +own attribution notices within Derivative Works that You distribute, +alongside or as an addendum to the NOTICE text from the Work, provided that +such additional attribution notices cannot be construed as modifying the +License. + +You may add Your own copyright statement to Your modifications and may +provide additional or different license terms and conditions for use, +reproduction, or distribution of Your modifications, or for any such +Derivative Works as a whole, provided Your use, reproduction, and +distribution of the Work otherwise complies with the conditions stated in +this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any +Contribution intentionally submitted for inclusion in the Work by You to +the Licensor shall be under the terms and conditions of this License, +without any additional terms or conditions. Notwithstanding the above, +nothing herein shall supersede or modify the terms of any separate license +agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, except +as required for reasonable and customary use in describing the origin of +the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to +in writing, Licensor provides the Work (and each Contributor provides its +Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied, including, without limitation, any +warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or +FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for +determining the appropriateness of using or redistributing the Work and +assume any risks associated with Your exercise of permissions under this +License. + +8. Limitation of Liability. In no event and under no legal theory, whether +in tort (including negligence), contract, or otherwise, unless required by +applicable law (such as deliberate and grossly negligent acts) or agreed to +in writing, shall any Contributor be liable to You for damages, including +any direct, indirect, special, incidental, or consequential damages of any +character arising as a result of this License or out of the use or +inability to use the Work (including but not limited to damages for loss of +goodwill, work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses), even if such Contributor has been +advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the +Work or Derivative Works thereof, You may choose to offer, and charge a fee +for, acceptance of support, warranty, indemnity, or other liability +obligations and/or rights consistent with this License. However, in +accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if +You agree to indemnify, defend, and hold each Contributor harmless for any +liability incurred by, or claims asserted against, such Contributor by +reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included +on the same "printed page" as the copyright notice for easier +identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); you may + not use this file except in compliance with the License. You may obtain a + copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable + law or agreed to in writing, software distributed under the License is + distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. diff --git a/src/libs/opencore-amr/ChangeLog b/src/libs/opencore-amr/ChangeLog new file mode 100644 index 00000000..6acf6621 --- /dev/null +++ b/src/libs/opencore-amr/ChangeLog @@ -0,0 +1,22 @@ +0.1.3 + - Adjusted libtool flags for building DLLs for windows + - Update to the latest upstream opencore source + - Updated and improved example applications + - Add options for enabling the arm inline assembly + - Add options for disabling the encoder or decoder in the amrnb library + - Avoid dependencies on libstdc++ if building the source as C + - Hide internal symbols in shared libraries + - Minor tweaks + - Remove old static makefiles and corresponding build scripts + +0.1.2 + - Fixed AMR-NB encoding on 64-bit architectures + - Switch to using automake/autoconf/libtool + - Update to the latest upstream opencore source as of September 1, 2009 + +0.1.1 + - Rename the libraries from libamr* to libopencore-amr* + - Fix a bunch of compiler warnings + +0.1.0 + - Start of opencore-amr project. diff --git a/src/libs/opencore-amr/Debug/libopencore-amr-nb.lib b/src/libs/opencore-amr/Debug/libopencore-amr-nb.lib new file mode 100644 index 00000000..06a19991 Binary files /dev/null and b/src/libs/opencore-amr/Debug/libopencore-amr-nb.lib differ diff --git a/src/libs/opencore-amr/INSTALL b/src/libs/opencore-amr/INSTALL new file mode 100644 index 00000000..a1e89e18 --- /dev/null +++ b/src/libs/opencore-amr/INSTALL @@ -0,0 +1,370 @@ +Installation Instructions +************************* + +Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, +Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/src/libs/opencore-amr/LICENSE b/src/libs/opencore-amr/LICENSE new file mode 100644 index 00000000..5ec4bf01 --- /dev/null +++ b/src/libs/opencore-amr/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the +copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other +entities that control, are controlled by, or are under common control with +that entity. For the purposes of this definition, "control" means (i) the +power, direct or indirect, to cause the direction or management of such +entity, whether by contract or otherwise, or (ii) ownership of fifty +percent (50%) or more of the outstanding shares, or (iii) beneficial +ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation source, +and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation +or translation of a Source form, including but not limited to compiled +object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice that +is included in or attached to the work (an example is provided in the +Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial +revisions, annotations, elaborations, or other modifications represent, as +a whole, an original work of authorship. For the purposes of this License, +Derivative Works shall not include works that remain separable from, or +merely link (or bind by name) to the interfaces of, the Work and Derivative +Works thereof. + +"Contribution" shall mean any work of authorship, including the original +version of the Work and any modifications or additions to that Work or +Derivative Works thereof, that is intentionally submitted to Licensor for +inclusion in the Work by the copyright owner or by an individual or Legal +Entity authorized to submit on behalf of the copyright owner. For the +purposes of this definition, "submitted" means any form of electronic, +verbal, or written communication sent to the Licensor or its +representatives, including but not limited to communication on electronic +mailing lists, source code control systems, and issue tracking systems that +are managed by, or on behalf of, the Licensor for the purpose of discussing +and improving the Work, but excluding communication that is conspicuously +marked or otherwise designated in writing by the copyright owner as "Not a +Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on +behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this +License, each Contributor hereby grants to You a perpetual, worldwide, +non-exclusive, no-charge, royalty-free, irrevocable copyright license to +reproduce, prepare Derivative Works of, publicly display, publicly perform, +sublicense, and distribute the Work and such Derivative Works in Source or +Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this +License, each Contributor hereby grants to You a perpetual, worldwide, +non-exclusive, no-charge, royalty-free, irrevocable (except as stated in +this section) patent license to make, have made, use, offer to sell, sell, +import, and otherwise transfer the Work, where such license applies only to +those patent claims licensable by such Contributor that are necessarily +infringed by their Contribution(s) alone or by combination of their +Contribution(s) with the Work to which such Contribution(s) was submitted. +If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or +contributory patent infringement, then any patent licenses granted to You +under this License for that Work shall terminate as of the date such +litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or +Derivative Works thereof in any medium, with or without modifications, and +in Source or Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works a +copy of this License; and + + 2. You must cause any modified files to carry prominent notices stating +that You changed the files; and + + 3. You must retain, in the Source form of any Derivative Works that You +distribute, all copyright, patent, trademark, and attribution notices from +the Source form of the Work, excluding those notices that do not pertain to +any part of the Derivative Works; and + + 4. If the Work includes a "NOTICE" text file as part of its +distribution, then any Derivative Works that You distribute must include a +readable copy of the attribution notices contained within such NOTICE file, +excluding those notices that do not pertain to any part of the Derivative +Works, in at least one of the following places: within a NOTICE text file +distributed as part of the Derivative Works; within the Source form or +documentation, if provided along with the Derivative Works; or, within a +display generated by the Derivative Works, if and wherever such third-party +notices normally appear. The contents of the NOTICE file are for +informational purposes only and do not modify the License. You may add Your +own attribution notices within Derivative Works that You distribute, +alongside or as an addendum to the NOTICE text from the Work, provided that +such additional attribution notices cannot be construed as modifying the +License. + +You may add Your own copyright statement to Your modifications and may +provide additional or different license terms and conditions for use, +reproduction, or distribution of Your modifications, or for any such +Derivative Works as a whole, provided Your use, reproduction, and +distribution of the Work otherwise complies with the conditions stated in +this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any +Contribution intentionally submitted for inclusion in the Work by You to +the Licensor shall be under the terms and conditions of this License, +without any additional terms or conditions. Notwithstanding the above, +nothing herein shall supersede or modify the terms of any separate license +agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, except +as required for reasonable and customary use in describing the origin of +the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to +in writing, Licensor provides the Work (and each Contributor provides its +Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied, including, without limitation, any +warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or +FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for +determining the appropriateness of using or redistributing the Work and +assume any risks associated with Your exercise of permissions under this +License. + +8. Limitation of Liability. In no event and under no legal theory, whether +in tort (including negligence), contract, or otherwise, unless required by +applicable law (such as deliberate and grossly negligent acts) or agreed to +in writing, shall any Contributor be liable to You for damages, including +any direct, indirect, special, incidental, or consequential damages of any +character arising as a result of this License or out of the use or +inability to use the Work (including but not limited to damages for loss of +goodwill, work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses), even if such Contributor has been +advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the +Work or Derivative Works thereof, You may choose to offer, and charge a fee +for, acceptance of support, warranty, indemnity, or other liability +obligations and/or rights consistent with this License. However, in +accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if +You agree to indemnify, defend, and hold each Contributor harmless for any +liability incurred by, or claims asserted against, such Contributor by +reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included +on the same "printed page" as the copyright notice for easier +identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); you may + not use this file except in compliance with the License. You may obtain a + copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable + law or agreed to in writing, software distributed under the License is + distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. diff --git a/src/libs/opencore-amr/Makefile.am b/src/libs/opencore-amr/Makefile.am new file mode 100644 index 00000000..f8eee3ff --- /dev/null +++ b/src/libs/opencore-amr/Makefile.am @@ -0,0 +1,36 @@ +SUBDIRS = amrnb amrwb +if EXAMPLES + SUBDIRS += test +endif + +ACLOCAL_AMFLAGS = -I m4 + +noinst_HEADERS = oscl/oscl_base.h oscl/oscl_mem.h oscl/oscl_base_macros.h + +EXTRA_DIST = $(top_srcdir)/LICENSE \ + $(top_srcdir)/opencore/README \ + $(top_srcdir)/opencore/NOTICE opencore/ChangeLog \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/patent_disclaimer.txt \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/common/dec/include \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/common/dec/build \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/common/dec/Android.mk \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/Android.mk \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/build \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/*.cpp \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/Android.mk \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/build \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/include \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/*.cpp \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/*.h \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/Android.mk \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/build \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/include \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/*.cpp \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/*.h \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/Android.mk \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/build \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/include \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/*.cpp \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/*.h + diff --git a/src/libs/opencore-amr/Makefile.in b/src/libs/opencore-amr/Makefile.in new file mode 100644 index 00000000..68b87153 --- /dev/null +++ b/src/libs/opencore-amr/Makefile.in @@ -0,0 +1,789 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@EXAMPLES_TRUE@am__append_1 = test +subdir = . +DIST_COMMON = README $(am__configure_deps) $(noinst_HEADERS) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/config.h.in $(top_srcdir)/configure AUTHORS COPYING \ + ChangeLog INSTALL NEWS config.guess config.sub depcomp \ + install-sh ltmain.sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +HEADERS = $(noinst_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = amrnb amrwb test +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENCORE_AMRNB_VERSION = @OPENCORE_AMRNB_VERSION@ +OPENCORE_AMRWB_VERSION = @OPENCORE_AMRWB_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = amrnb amrwb $(am__append_1) +ACLOCAL_AMFLAGS = -I m4 +noinst_HEADERS = oscl/oscl_base.h oscl/oscl_mem.h oscl/oscl_base_macros.h +EXTRA_DIST = $(top_srcdir)/LICENSE \ + $(top_srcdir)/opencore/README \ + $(top_srcdir)/opencore/NOTICE opencore/ChangeLog \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/patent_disclaimer.txt \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/common/dec/include \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/common/dec/build \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/common/dec/Android.mk \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/Android.mk \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/build \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/*.cpp \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/Android.mk \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/build \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/include \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/*.cpp \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/*.h \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/Android.mk \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/build \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/include \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/*.cpp \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/*.h \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/Android.mk \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/build \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/include \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/*.cpp \ + $(top_srcdir)/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/*.h + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(HEADERS) config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ + dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ dist-xz \ + dist-zip distcheck distclean distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-recursive uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/opencore-amr/NEWS b/src/libs/opencore-amr/NEWS new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/opencore-amr/README b/src/libs/opencore-amr/README new file mode 100644 index 00000000..8241bdfb --- /dev/null +++ b/src/libs/opencore-amr/README @@ -0,0 +1,11 @@ +OpenCORE Adaptive Multi Rate (AMR) speech codec library implementation. + +This library contains an implementation of the 3GPP TS 26.073 specification for +the Adaptive Multi Rate (AMR) speech codec and an implementation for the +3GPP TS 26.173 specification for the Adaptive Multi-Rate - Wideband (AMR-WB) +speech decoder. The implementation is derived from the OpenCORE framework, part +of the Google Android project. + +This library is Licensed under the Apache License, Version 2.0. A copy me be +found in the file 'LICENSE' and at +http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/src/libs/opencore-amr/aclocal.m4 b/src/libs/opencore-amr/aclocal.m4 new file mode 100644 index 00000000..8ea794fe --- /dev/null +++ b/src/libs/opencore-amr/aclocal.m4 @@ -0,0 +1,1092 @@ +# generated automatically by aclocal 1.11.3 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.3], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.3])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, +# 2010, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008, +# 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless `enable' is passed literally. +# For symmetry, `disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], +[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2009, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# (`yes' being less verbose, `no' or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], +[ --enable-silent-rules less verbose build output (undo: `make V=1') + --disable-silent-rules verbose build output (undo: `make V=0')]) +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few `make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using `$V' instead of `$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) diff --git a/src/libs/opencore-amr/amrnb/Makefile.am b/src/libs/opencore-amr/amrnb/Makefile.am new file mode 100644 index 00000000..1b42bd51 --- /dev/null +++ b/src/libs/opencore-amr/amrnb/Makefile.am @@ -0,0 +1,224 @@ +# Just set OC_BASE to the opencore root, or set AMR_BASE directly to +# a detached gsm_amr directory +OC_BASE = $(top_srcdir)/opencore +AMR_BASE = $(OC_BASE)/codecs_v2/audio/gsm_amr + +DEC_DIR = $(AMR_BASE)/amr_nb/dec +ENC_DIR = $(AMR_BASE)/amr_nb/enc +COMMON_DIR = $(AMR_BASE)/amr_nb/common +DEC_SRC_DIR = $(DEC_DIR)/src +ENC_SRC_DIR = $(ENC_DIR)/src +COMMON_SRC_DIR = $(COMMON_DIR)/src +OSCL = $(top_srcdir)/oscl + +AM_CFLAGS = -I$(OSCL) -I$(DEC_SRC_DIR) -I$(COMMON_DIR)/include \ + -I$(DEC_DIR)/include -I$(AMR_BASE)/common/dec/include -I$(ENC_SRC_DIR) + +if GCC_ARMV5 + AM_CFLAGS += -DPV_CPU_ARCH_VERSION=5 -DPV_COMPILER=1 +endif + +if COMPILE_AS_C + AM_CFLAGS += -x c -std=c99 + libopencore_amrnb_la_LINK = $(LINK) $(libopencore_amrnb_la_LDFLAGS) + # Mention a dummy pure C file to trigger generation of the $(LINK) variable + nodist_EXTRA_libopencore_amrnb_la_SOURCES = dummy.c +else + libopencore_amrnb_la_LINK = $(CXXLINK) $(libopencore_amrnb_la_LDFLAGS) +endif + +AM_CXXFLAGS = $(AM_CFLAGS) + +amrnbincludedir = $(includedir)/opencore-amrnb +amrnbinclude_HEADERS = + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = opencore-amrnb.pc + +lib_LTLIBRARIES = libopencore-amrnb.la + +libopencore_amrnb_la_LDFLAGS = -version-info @OPENCORE_AMRNB_VERSION@ -no-undefined -export-symbols $(top_srcdir)/amrnb/opencore-amrnb.sym +EXTRA_DIST = $(top_srcdir)/amrnb/opencore-amrnb.sym + +# Our sources to include. There are certain sources we exclude and they are +# $(DEC_SRC_DIR)/decoder_gsm_amr.cpp +# $(DEC_SRC_DIR)/pvgsmamrdecoder.cpp +# $(ENC_SRC_DIR)/gsmamr_encoder_wrapper.cpp +# $(COMMON_SRC_DIR)/bits2prm.cpp +# $(COMMON_SRC_DIR)/copy.cpp +# $(COMMON_SRC_DIR)/div_32.cpp +# $(COMMON_SRC_DIR)/l_abs.cpp +# $(COMMON_SRC_DIR)/r_fft.cpp +# $(COMMON_SRC_DIR)/vad1.cpp +# $(COMMON_SRC_DIR)/vad2.cpp +libopencore_amrnb_la_SOURCES = \ + wrapper.cpp + +if AMRNB_DECODER + libopencore_amrnb_la_SOURCES += \ + $(DEC_SRC_DIR)/agc.cpp \ + $(DEC_SRC_DIR)/amrdecode.cpp \ + $(DEC_SRC_DIR)/a_refl.cpp \ + $(DEC_SRC_DIR)/b_cn_cod.cpp \ + $(DEC_SRC_DIR)/bgnscd.cpp \ + $(DEC_SRC_DIR)/c_g_aver.cpp \ + $(DEC_SRC_DIR)/d1035pf.cpp \ + $(DEC_SRC_DIR)/d2_11pf.cpp \ + $(DEC_SRC_DIR)/d2_9pf.cpp \ + $(DEC_SRC_DIR)/d3_14pf.cpp \ + $(DEC_SRC_DIR)/d4_17pf.cpp \ + $(DEC_SRC_DIR)/d8_31pf.cpp \ + $(DEC_SRC_DIR)/dec_amr.cpp \ + $(DEC_SRC_DIR)/dec_gain.cpp \ + $(DEC_SRC_DIR)/dec_input_format_tab.cpp \ + $(DEC_SRC_DIR)/dec_lag3.cpp \ + $(DEC_SRC_DIR)/dec_lag6.cpp \ + $(DEC_SRC_DIR)/d_gain_c.cpp \ + $(DEC_SRC_DIR)/d_gain_p.cpp \ + $(DEC_SRC_DIR)/d_plsf_3.cpp \ + $(DEC_SRC_DIR)/d_plsf_5.cpp \ + $(DEC_SRC_DIR)/d_plsf.cpp \ + $(DEC_SRC_DIR)/dtx_dec.cpp \ + $(DEC_SRC_DIR)/ec_gains.cpp \ + $(DEC_SRC_DIR)/ex_ctrl.cpp \ + $(DEC_SRC_DIR)/if2_to_ets.cpp \ + $(DEC_SRC_DIR)/int_lsf.cpp \ + $(DEC_SRC_DIR)/lsp_avg.cpp \ + $(DEC_SRC_DIR)/ph_disp.cpp \ + $(DEC_SRC_DIR)/post_pro.cpp \ + $(DEC_SRC_DIR)/preemph.cpp \ + $(DEC_SRC_DIR)/pstfilt.cpp \ + $(DEC_SRC_DIR)/qgain475_tab.cpp \ + $(DEC_SRC_DIR)/sp_dec.cpp \ + $(DEC_SRC_DIR)/wmf_to_ets.cpp + amrnbinclude_HEADERS += interf_dec.h +else + AM_CFLAGS += -DDISABLE_AMRNB_DECODER +endif + +if AMRNB_ENCODER + libopencore_amrnb_la_SOURCES += \ + $(ENC_SRC_DIR)/amrencode.cpp \ + $(ENC_SRC_DIR)/autocorr.cpp \ + $(ENC_SRC_DIR)/c1035pf.cpp \ + $(ENC_SRC_DIR)/c2_11pf.cpp \ + $(ENC_SRC_DIR)/c2_9pf.cpp \ + $(ENC_SRC_DIR)/c3_14pf.cpp \ + $(ENC_SRC_DIR)/c4_17pf.cpp \ + $(ENC_SRC_DIR)/c8_31pf.cpp \ + $(ENC_SRC_DIR)/calc_cor.cpp \ + $(ENC_SRC_DIR)/calc_en.cpp \ + $(ENC_SRC_DIR)/cbsearch.cpp \ + $(ENC_SRC_DIR)/cl_ltp.cpp \ + $(ENC_SRC_DIR)/cod_amr.cpp \ + $(ENC_SRC_DIR)/convolve.cpp \ + $(ENC_SRC_DIR)/cor_h.cpp \ + $(ENC_SRC_DIR)/cor_h_x2.cpp \ + $(ENC_SRC_DIR)/cor_h_x.cpp \ + $(ENC_SRC_DIR)/corrwght_tab.cpp \ + $(ENC_SRC_DIR)/div_32.cpp \ + $(ENC_SRC_DIR)/dtx_enc.cpp \ + $(ENC_SRC_DIR)/enc_lag3.cpp \ + $(ENC_SRC_DIR)/enc_lag6.cpp \ + $(ENC_SRC_DIR)/enc_output_format_tab.cpp \ + $(ENC_SRC_DIR)/ets_to_if2.cpp \ + $(ENC_SRC_DIR)/ets_to_wmf.cpp \ + $(ENC_SRC_DIR)/g_adapt.cpp \ + $(ENC_SRC_DIR)/gain_q.cpp \ + $(ENC_SRC_DIR)/g_code.cpp \ + $(ENC_SRC_DIR)/g_pitch.cpp \ + $(ENC_SRC_DIR)/hp_max.cpp \ + $(ENC_SRC_DIR)/inter_36.cpp \ + $(ENC_SRC_DIR)/inter_36_tab.cpp \ + $(ENC_SRC_DIR)/l_abs.cpp \ + $(ENC_SRC_DIR)/lag_wind.cpp \ + $(ENC_SRC_DIR)/lag_wind_tab.cpp \ + $(ENC_SRC_DIR)/l_comp.cpp \ + $(ENC_SRC_DIR)/levinson.cpp \ + $(ENC_SRC_DIR)/l_extract.cpp \ + $(ENC_SRC_DIR)/lflg_upd.cpp \ + $(ENC_SRC_DIR)/l_negate.cpp \ + $(ENC_SRC_DIR)/lpc.cpp \ + $(ENC_SRC_DIR)/ol_ltp.cpp \ + $(ENC_SRC_DIR)/pitch_fr.cpp \ + $(ENC_SRC_DIR)/pitch_ol.cpp \ + $(ENC_SRC_DIR)/p_ol_wgh.cpp \ + $(ENC_SRC_DIR)/pre_big.cpp \ + $(ENC_SRC_DIR)/pre_proc.cpp \ + $(ENC_SRC_DIR)/prm2bits.cpp \ + $(ENC_SRC_DIR)/qgain475.cpp \ + $(ENC_SRC_DIR)/qgain795.cpp \ + $(ENC_SRC_DIR)/q_gain_c.cpp \ + $(ENC_SRC_DIR)/q_gain_p.cpp \ + $(ENC_SRC_DIR)/qua_gain.cpp \ + $(ENC_SRC_DIR)/s10_8pf.cpp \ + $(ENC_SRC_DIR)/set_sign.cpp \ + $(ENC_SRC_DIR)/sid_sync.cpp \ + $(ENC_SRC_DIR)/sp_enc.cpp \ + $(ENC_SRC_DIR)/spreproc.cpp \ + $(ENC_SRC_DIR)/spstproc.cpp \ + $(ENC_SRC_DIR)/ton_stab.cpp \ + $(ENC_SRC_DIR)/vad1.cpp + amrnbinclude_HEADERS += interf_enc.h +else + AM_CFLAGS += -DDISABLE_AMRNB_ENCODER +endif + +libopencore_amrnb_la_SOURCES += \ + $(COMMON_SRC_DIR)/add.cpp \ + $(COMMON_SRC_DIR)/az_lsp.cpp \ + $(COMMON_SRC_DIR)/bitno_tab.cpp \ + $(COMMON_SRC_DIR)/bitreorder_tab.cpp \ + $(COMMON_SRC_DIR)/c2_9pf_tab.cpp \ + $(COMMON_SRC_DIR)/div_s.cpp \ + $(COMMON_SRC_DIR)/extract_h.cpp \ + $(COMMON_SRC_DIR)/extract_l.cpp \ + $(COMMON_SRC_DIR)/gains_tbl.cpp \ + $(COMMON_SRC_DIR)/gc_pred.cpp \ + $(COMMON_SRC_DIR)/get_const_tbls.cpp \ + $(COMMON_SRC_DIR)/gmed_n.cpp \ + $(COMMON_SRC_DIR)/gray_tbl.cpp \ + $(COMMON_SRC_DIR)/grid_tbl.cpp \ + $(COMMON_SRC_DIR)/int_lpc.cpp \ + $(COMMON_SRC_DIR)/inv_sqrt.cpp \ + $(COMMON_SRC_DIR)/inv_sqrt_tbl.cpp \ + $(COMMON_SRC_DIR)/l_deposit_h.cpp \ + $(COMMON_SRC_DIR)/l_deposit_l.cpp \ + $(COMMON_SRC_DIR)/log2.cpp \ + $(COMMON_SRC_DIR)/log2_norm.cpp \ + $(COMMON_SRC_DIR)/log2_tbl.cpp \ + $(COMMON_SRC_DIR)/lsfwt.cpp \ + $(COMMON_SRC_DIR)/l_shr_r.cpp \ + $(COMMON_SRC_DIR)/lsp_az.cpp \ + $(COMMON_SRC_DIR)/lsp.cpp \ + $(COMMON_SRC_DIR)/lsp_lsf.cpp \ + $(COMMON_SRC_DIR)/lsp_lsf_tbl.cpp \ + $(COMMON_SRC_DIR)/lsp_tab.cpp \ + $(COMMON_SRC_DIR)/mult_r.cpp \ + $(COMMON_SRC_DIR)/negate.cpp \ + $(COMMON_SRC_DIR)/norm_l.cpp \ + $(COMMON_SRC_DIR)/norm_s.cpp \ + $(COMMON_SRC_DIR)/overflow_tbl.cpp \ + $(COMMON_SRC_DIR)/ph_disp_tab.cpp \ + $(COMMON_SRC_DIR)/pow2.cpp \ + $(COMMON_SRC_DIR)/pow2_tbl.cpp \ + $(COMMON_SRC_DIR)/pred_lt.cpp \ + $(COMMON_SRC_DIR)/q_plsf_3.cpp \ + $(COMMON_SRC_DIR)/q_plsf_3_tbl.cpp \ + $(COMMON_SRC_DIR)/q_plsf_5.cpp \ + $(COMMON_SRC_DIR)/q_plsf_5_tbl.cpp \ + $(COMMON_SRC_DIR)/q_plsf.cpp \ + $(COMMON_SRC_DIR)/qua_gain_tbl.cpp \ + $(COMMON_SRC_DIR)/reorder.cpp \ + $(COMMON_SRC_DIR)/residu.cpp \ + $(COMMON_SRC_DIR)/round.cpp \ + $(COMMON_SRC_DIR)/set_zero.cpp \ + $(COMMON_SRC_DIR)/shr.cpp \ + $(COMMON_SRC_DIR)/shr_r.cpp \ + $(COMMON_SRC_DIR)/sqrt_l.cpp \ + $(COMMON_SRC_DIR)/sqrt_l_tbl.cpp \ + $(COMMON_SRC_DIR)/sub.cpp \ + $(COMMON_SRC_DIR)/syn_filt.cpp \ + $(COMMON_SRC_DIR)/weight_a.cpp \ + $(COMMON_SRC_DIR)/window_tab.cpp + diff --git a/src/libs/opencore-amr/amrnb/Makefile.in b/src/libs/opencore-amr/amrnb/Makefile.in new file mode 100644 index 00000000..b8eba754 --- /dev/null +++ b/src/libs/opencore-amr/amrnb/Makefile.in @@ -0,0 +1,2171 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@GCC_ARMV5_TRUE@am__append_1 = -DPV_CPU_ARCH_VERSION=5 -DPV_COMPILER=1 +@COMPILE_AS_C_TRUE@am__append_2 = -x c -std=c99 +@AMRNB_DECODER_TRUE@am__append_3 = \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/agc.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/amrdecode.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/a_refl.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/b_cn_cod.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/bgnscd.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/c_g_aver.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/d1035pf.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/d2_11pf.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/d2_9pf.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/d3_14pf.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/d4_17pf.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/d8_31pf.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/dec_amr.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/dec_gain.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/dec_input_format_tab.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/dec_lag3.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/dec_lag6.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/d_gain_c.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/d_gain_p.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/d_plsf_3.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/d_plsf_5.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/d_plsf.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/dtx_dec.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/ec_gains.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/ex_ctrl.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/if2_to_ets.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/int_lsf.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/lsp_avg.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/ph_disp.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/post_pro.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/preemph.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/pstfilt.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/qgain475_tab.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/sp_dec.cpp \ +@AMRNB_DECODER_TRUE@ $(DEC_SRC_DIR)/wmf_to_ets.cpp + +@AMRNB_DECODER_TRUE@am__append_4 = interf_dec.h +@AMRNB_DECODER_FALSE@am__append_5 = -DDISABLE_AMRNB_DECODER +@AMRNB_ENCODER_TRUE@am__append_6 = \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/amrencode.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/autocorr.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/c1035pf.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/c2_11pf.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/c2_9pf.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/c3_14pf.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/c4_17pf.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/c8_31pf.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/calc_cor.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/calc_en.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/cbsearch.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/cl_ltp.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/cod_amr.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/convolve.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/cor_h.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/cor_h_x2.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/cor_h_x.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/corrwght_tab.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/div_32.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/dtx_enc.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/enc_lag3.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/enc_lag6.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/enc_output_format_tab.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/ets_to_if2.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/ets_to_wmf.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/g_adapt.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/gain_q.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/g_code.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/g_pitch.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/hp_max.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/inter_36.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/inter_36_tab.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/l_abs.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/lag_wind.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/lag_wind_tab.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/l_comp.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/levinson.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/l_extract.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/lflg_upd.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/l_negate.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/lpc.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/ol_ltp.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/pitch_fr.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/pitch_ol.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/p_ol_wgh.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/pre_big.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/pre_proc.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/prm2bits.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/qgain475.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/qgain795.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/q_gain_c.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/q_gain_p.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/qua_gain.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/s10_8pf.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/set_sign.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/sid_sync.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/sp_enc.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/spreproc.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/spstproc.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/ton_stab.cpp \ +@AMRNB_ENCODER_TRUE@ $(ENC_SRC_DIR)/vad1.cpp + +@AMRNB_ENCODER_TRUE@am__append_7 = interf_enc.h +@AMRNB_ENCODER_FALSE@am__append_8 = -DDISABLE_AMRNB_ENCODER +subdir = amrnb +DIST_COMMON = $(am__amrnbinclude_HEADERS_DIST) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/opencore-amrnb.pc.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = opencore-amrnb.pc +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ + "$(DESTDIR)$(amrnbincludedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libopencore_amrnb_la_LIBADD = +am__libopencore_amrnb_la_SOURCES_DIST = wrapper.cpp \ + $(DEC_SRC_DIR)/agc.cpp $(DEC_SRC_DIR)/amrdecode.cpp \ + $(DEC_SRC_DIR)/a_refl.cpp $(DEC_SRC_DIR)/b_cn_cod.cpp \ + $(DEC_SRC_DIR)/bgnscd.cpp $(DEC_SRC_DIR)/c_g_aver.cpp \ + $(DEC_SRC_DIR)/d1035pf.cpp $(DEC_SRC_DIR)/d2_11pf.cpp \ + $(DEC_SRC_DIR)/d2_9pf.cpp $(DEC_SRC_DIR)/d3_14pf.cpp \ + $(DEC_SRC_DIR)/d4_17pf.cpp $(DEC_SRC_DIR)/d8_31pf.cpp \ + $(DEC_SRC_DIR)/dec_amr.cpp $(DEC_SRC_DIR)/dec_gain.cpp \ + $(DEC_SRC_DIR)/dec_input_format_tab.cpp \ + $(DEC_SRC_DIR)/dec_lag3.cpp $(DEC_SRC_DIR)/dec_lag6.cpp \ + $(DEC_SRC_DIR)/d_gain_c.cpp $(DEC_SRC_DIR)/d_gain_p.cpp \ + $(DEC_SRC_DIR)/d_plsf_3.cpp $(DEC_SRC_DIR)/d_plsf_5.cpp \ + $(DEC_SRC_DIR)/d_plsf.cpp $(DEC_SRC_DIR)/dtx_dec.cpp \ + $(DEC_SRC_DIR)/ec_gains.cpp $(DEC_SRC_DIR)/ex_ctrl.cpp \ + $(DEC_SRC_DIR)/if2_to_ets.cpp $(DEC_SRC_DIR)/int_lsf.cpp \ + $(DEC_SRC_DIR)/lsp_avg.cpp $(DEC_SRC_DIR)/ph_disp.cpp \ + $(DEC_SRC_DIR)/post_pro.cpp $(DEC_SRC_DIR)/preemph.cpp \ + $(DEC_SRC_DIR)/pstfilt.cpp $(DEC_SRC_DIR)/qgain475_tab.cpp \ + $(DEC_SRC_DIR)/sp_dec.cpp $(DEC_SRC_DIR)/wmf_to_ets.cpp \ + $(ENC_SRC_DIR)/amrencode.cpp $(ENC_SRC_DIR)/autocorr.cpp \ + $(ENC_SRC_DIR)/c1035pf.cpp $(ENC_SRC_DIR)/c2_11pf.cpp \ + $(ENC_SRC_DIR)/c2_9pf.cpp $(ENC_SRC_DIR)/c3_14pf.cpp \ + $(ENC_SRC_DIR)/c4_17pf.cpp $(ENC_SRC_DIR)/c8_31pf.cpp \ + $(ENC_SRC_DIR)/calc_cor.cpp $(ENC_SRC_DIR)/calc_en.cpp \ + $(ENC_SRC_DIR)/cbsearch.cpp $(ENC_SRC_DIR)/cl_ltp.cpp \ + $(ENC_SRC_DIR)/cod_amr.cpp $(ENC_SRC_DIR)/convolve.cpp \ + $(ENC_SRC_DIR)/cor_h.cpp $(ENC_SRC_DIR)/cor_h_x2.cpp \ + $(ENC_SRC_DIR)/cor_h_x.cpp $(ENC_SRC_DIR)/corrwght_tab.cpp \ + $(ENC_SRC_DIR)/div_32.cpp $(ENC_SRC_DIR)/dtx_enc.cpp \ + $(ENC_SRC_DIR)/enc_lag3.cpp $(ENC_SRC_DIR)/enc_lag6.cpp \ + $(ENC_SRC_DIR)/enc_output_format_tab.cpp \ + $(ENC_SRC_DIR)/ets_to_if2.cpp $(ENC_SRC_DIR)/ets_to_wmf.cpp \ + $(ENC_SRC_DIR)/g_adapt.cpp $(ENC_SRC_DIR)/gain_q.cpp \ + $(ENC_SRC_DIR)/g_code.cpp $(ENC_SRC_DIR)/g_pitch.cpp \ + $(ENC_SRC_DIR)/hp_max.cpp $(ENC_SRC_DIR)/inter_36.cpp \ + $(ENC_SRC_DIR)/inter_36_tab.cpp $(ENC_SRC_DIR)/l_abs.cpp \ + $(ENC_SRC_DIR)/lag_wind.cpp $(ENC_SRC_DIR)/lag_wind_tab.cpp \ + $(ENC_SRC_DIR)/l_comp.cpp $(ENC_SRC_DIR)/levinson.cpp \ + $(ENC_SRC_DIR)/l_extract.cpp $(ENC_SRC_DIR)/lflg_upd.cpp \ + $(ENC_SRC_DIR)/l_negate.cpp $(ENC_SRC_DIR)/lpc.cpp \ + $(ENC_SRC_DIR)/ol_ltp.cpp $(ENC_SRC_DIR)/pitch_fr.cpp \ + $(ENC_SRC_DIR)/pitch_ol.cpp $(ENC_SRC_DIR)/p_ol_wgh.cpp \ + $(ENC_SRC_DIR)/pre_big.cpp $(ENC_SRC_DIR)/pre_proc.cpp \ + $(ENC_SRC_DIR)/prm2bits.cpp $(ENC_SRC_DIR)/qgain475.cpp \ + $(ENC_SRC_DIR)/qgain795.cpp $(ENC_SRC_DIR)/q_gain_c.cpp \ + $(ENC_SRC_DIR)/q_gain_p.cpp $(ENC_SRC_DIR)/qua_gain.cpp \ + $(ENC_SRC_DIR)/s10_8pf.cpp $(ENC_SRC_DIR)/set_sign.cpp \ + $(ENC_SRC_DIR)/sid_sync.cpp $(ENC_SRC_DIR)/sp_enc.cpp \ + $(ENC_SRC_DIR)/spreproc.cpp $(ENC_SRC_DIR)/spstproc.cpp \ + $(ENC_SRC_DIR)/ton_stab.cpp $(ENC_SRC_DIR)/vad1.cpp \ + $(COMMON_SRC_DIR)/add.cpp $(COMMON_SRC_DIR)/az_lsp.cpp \ + $(COMMON_SRC_DIR)/bitno_tab.cpp \ + $(COMMON_SRC_DIR)/bitreorder_tab.cpp \ + $(COMMON_SRC_DIR)/c2_9pf_tab.cpp $(COMMON_SRC_DIR)/div_s.cpp \ + $(COMMON_SRC_DIR)/extract_h.cpp \ + $(COMMON_SRC_DIR)/extract_l.cpp \ + $(COMMON_SRC_DIR)/gains_tbl.cpp $(COMMON_SRC_DIR)/gc_pred.cpp \ + $(COMMON_SRC_DIR)/get_const_tbls.cpp \ + $(COMMON_SRC_DIR)/gmed_n.cpp $(COMMON_SRC_DIR)/gray_tbl.cpp \ + $(COMMON_SRC_DIR)/grid_tbl.cpp $(COMMON_SRC_DIR)/int_lpc.cpp \ + $(COMMON_SRC_DIR)/inv_sqrt.cpp \ + $(COMMON_SRC_DIR)/inv_sqrt_tbl.cpp \ + $(COMMON_SRC_DIR)/l_deposit_h.cpp \ + $(COMMON_SRC_DIR)/l_deposit_l.cpp $(COMMON_SRC_DIR)/log2.cpp \ + $(COMMON_SRC_DIR)/log2_norm.cpp $(COMMON_SRC_DIR)/log2_tbl.cpp \ + $(COMMON_SRC_DIR)/lsfwt.cpp $(COMMON_SRC_DIR)/l_shr_r.cpp \ + $(COMMON_SRC_DIR)/lsp_az.cpp $(COMMON_SRC_DIR)/lsp.cpp \ + $(COMMON_SRC_DIR)/lsp_lsf.cpp \ + $(COMMON_SRC_DIR)/lsp_lsf_tbl.cpp \ + $(COMMON_SRC_DIR)/lsp_tab.cpp $(COMMON_SRC_DIR)/mult_r.cpp \ + $(COMMON_SRC_DIR)/negate.cpp $(COMMON_SRC_DIR)/norm_l.cpp \ + $(COMMON_SRC_DIR)/norm_s.cpp \ + $(COMMON_SRC_DIR)/overflow_tbl.cpp \ + $(COMMON_SRC_DIR)/ph_disp_tab.cpp $(COMMON_SRC_DIR)/pow2.cpp \ + $(COMMON_SRC_DIR)/pow2_tbl.cpp $(COMMON_SRC_DIR)/pred_lt.cpp \ + $(COMMON_SRC_DIR)/q_plsf_3.cpp \ + $(COMMON_SRC_DIR)/q_plsf_3_tbl.cpp \ + $(COMMON_SRC_DIR)/q_plsf_5.cpp \ + $(COMMON_SRC_DIR)/q_plsf_5_tbl.cpp \ + $(COMMON_SRC_DIR)/q_plsf.cpp \ + $(COMMON_SRC_DIR)/qua_gain_tbl.cpp \ + $(COMMON_SRC_DIR)/reorder.cpp $(COMMON_SRC_DIR)/residu.cpp \ + $(COMMON_SRC_DIR)/round.cpp $(COMMON_SRC_DIR)/set_zero.cpp \ + $(COMMON_SRC_DIR)/shr.cpp $(COMMON_SRC_DIR)/shr_r.cpp \ + $(COMMON_SRC_DIR)/sqrt_l.cpp $(COMMON_SRC_DIR)/sqrt_l_tbl.cpp \ + $(COMMON_SRC_DIR)/sub.cpp $(COMMON_SRC_DIR)/syn_filt.cpp \ + $(COMMON_SRC_DIR)/weight_a.cpp \ + $(COMMON_SRC_DIR)/window_tab.cpp +@AMRNB_DECODER_TRUE@am__objects_1 = agc.lo amrdecode.lo a_refl.lo \ +@AMRNB_DECODER_TRUE@ b_cn_cod.lo bgnscd.lo c_g_aver.lo \ +@AMRNB_DECODER_TRUE@ d1035pf.lo d2_11pf.lo d2_9pf.lo d3_14pf.lo \ +@AMRNB_DECODER_TRUE@ d4_17pf.lo d8_31pf.lo dec_amr.lo \ +@AMRNB_DECODER_TRUE@ dec_gain.lo dec_input_format_tab.lo \ +@AMRNB_DECODER_TRUE@ dec_lag3.lo dec_lag6.lo d_gain_c.lo \ +@AMRNB_DECODER_TRUE@ d_gain_p.lo d_plsf_3.lo d_plsf_5.lo \ +@AMRNB_DECODER_TRUE@ d_plsf.lo dtx_dec.lo ec_gains.lo \ +@AMRNB_DECODER_TRUE@ ex_ctrl.lo if2_to_ets.lo int_lsf.lo \ +@AMRNB_DECODER_TRUE@ lsp_avg.lo ph_disp.lo post_pro.lo \ +@AMRNB_DECODER_TRUE@ preemph.lo pstfilt.lo qgain475_tab.lo \ +@AMRNB_DECODER_TRUE@ sp_dec.lo wmf_to_ets.lo +@AMRNB_ENCODER_TRUE@am__objects_2 = amrencode.lo autocorr.lo \ +@AMRNB_ENCODER_TRUE@ c1035pf.lo c2_11pf.lo c2_9pf.lo c3_14pf.lo \ +@AMRNB_ENCODER_TRUE@ c4_17pf.lo c8_31pf.lo calc_cor.lo \ +@AMRNB_ENCODER_TRUE@ calc_en.lo cbsearch.lo cl_ltp.lo \ +@AMRNB_ENCODER_TRUE@ cod_amr.lo convolve.lo cor_h.lo \ +@AMRNB_ENCODER_TRUE@ cor_h_x2.lo cor_h_x.lo corrwght_tab.lo \ +@AMRNB_ENCODER_TRUE@ div_32.lo dtx_enc.lo enc_lag3.lo \ +@AMRNB_ENCODER_TRUE@ enc_lag6.lo enc_output_format_tab.lo \ +@AMRNB_ENCODER_TRUE@ ets_to_if2.lo ets_to_wmf.lo g_adapt.lo \ +@AMRNB_ENCODER_TRUE@ gain_q.lo g_code.lo g_pitch.lo hp_max.lo \ +@AMRNB_ENCODER_TRUE@ inter_36.lo inter_36_tab.lo l_abs.lo \ +@AMRNB_ENCODER_TRUE@ lag_wind.lo lag_wind_tab.lo l_comp.lo \ +@AMRNB_ENCODER_TRUE@ levinson.lo l_extract.lo lflg_upd.lo \ +@AMRNB_ENCODER_TRUE@ l_negate.lo lpc.lo ol_ltp.lo pitch_fr.lo \ +@AMRNB_ENCODER_TRUE@ pitch_ol.lo p_ol_wgh.lo pre_big.lo \ +@AMRNB_ENCODER_TRUE@ pre_proc.lo prm2bits.lo qgain475.lo \ +@AMRNB_ENCODER_TRUE@ qgain795.lo q_gain_c.lo q_gain_p.lo \ +@AMRNB_ENCODER_TRUE@ qua_gain.lo s10_8pf.lo set_sign.lo \ +@AMRNB_ENCODER_TRUE@ sid_sync.lo sp_enc.lo spreproc.lo \ +@AMRNB_ENCODER_TRUE@ spstproc.lo ton_stab.lo vad1.lo +am_libopencore_amrnb_la_OBJECTS = wrapper.lo $(am__objects_1) \ + $(am__objects_2) add.lo az_lsp.lo bitno_tab.lo \ + bitreorder_tab.lo c2_9pf_tab.lo div_s.lo extract_h.lo \ + extract_l.lo gains_tbl.lo gc_pred.lo get_const_tbls.lo \ + gmed_n.lo gray_tbl.lo grid_tbl.lo int_lpc.lo inv_sqrt.lo \ + inv_sqrt_tbl.lo l_deposit_h.lo l_deposit_l.lo log2.lo \ + log2_norm.lo log2_tbl.lo lsfwt.lo l_shr_r.lo lsp_az.lo lsp.lo \ + lsp_lsf.lo lsp_lsf_tbl.lo lsp_tab.lo mult_r.lo negate.lo \ + norm_l.lo norm_s.lo overflow_tbl.lo ph_disp_tab.lo pow2.lo \ + pow2_tbl.lo pred_lt.lo q_plsf_3.lo q_plsf_3_tbl.lo q_plsf_5.lo \ + q_plsf_5_tbl.lo q_plsf.lo qua_gain_tbl.lo reorder.lo residu.lo \ + round.lo set_zero.lo shr.lo shr_r.lo sqrt_l.lo sqrt_l_tbl.lo \ + sub.lo syn_filt.lo weight_a.lo window_tab.lo +libopencore_amrnb_la_OBJECTS = $(am_libopencore_amrnb_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libopencore_amrnb_la_SOURCES) \ + $(nodist_EXTRA_libopencore_amrnb_la_SOURCES) +DIST_SOURCES = $(am__libopencore_amrnb_la_SOURCES_DIST) +DATA = $(pkgconfig_DATA) +am__amrnbinclude_HEADERS_DIST = interf_dec.h interf_enc.h +HEADERS = $(amrnbinclude_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENCORE_AMRNB_VERSION = @OPENCORE_AMRNB_VERSION@ +OPENCORE_AMRWB_VERSION = @OPENCORE_AMRWB_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Just set OC_BASE to the opencore root, or set AMR_BASE directly to +# a detached gsm_amr directory +OC_BASE = $(top_srcdir)/opencore +AMR_BASE = $(OC_BASE)/codecs_v2/audio/gsm_amr +DEC_DIR = $(AMR_BASE)/amr_nb/dec +ENC_DIR = $(AMR_BASE)/amr_nb/enc +COMMON_DIR = $(AMR_BASE)/amr_nb/common +DEC_SRC_DIR = $(DEC_DIR)/src +ENC_SRC_DIR = $(ENC_DIR)/src +COMMON_SRC_DIR = $(COMMON_DIR)/src +OSCL = $(top_srcdir)/oscl +AM_CFLAGS = -I$(OSCL) -I$(DEC_SRC_DIR) -I$(COMMON_DIR)/include \ + -I$(DEC_DIR)/include -I$(AMR_BASE)/common/dec/include \ + -I$(ENC_SRC_DIR) $(am__append_1) $(am__append_2) \ + $(am__append_5) $(am__append_8) +@COMPILE_AS_C_FALSE@libopencore_amrnb_la_LINK = $(CXXLINK) $(libopencore_amrnb_la_LDFLAGS) +@COMPILE_AS_C_TRUE@libopencore_amrnb_la_LINK = $(LINK) $(libopencore_amrnb_la_LDFLAGS) +@COMPILE_AS_C_TRUE@nodist_EXTRA_libopencore_amrnb_la_SOURCES = dummy.c +AM_CXXFLAGS = $(AM_CFLAGS) +amrnbincludedir = $(includedir)/opencore-amrnb +amrnbinclude_HEADERS = $(am__append_4) $(am__append_7) +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = opencore-amrnb.pc +lib_LTLIBRARIES = libopencore-amrnb.la +libopencore_amrnb_la_LDFLAGS = -version-info @OPENCORE_AMRNB_VERSION@ -no-undefined -export-symbols $(top_srcdir)/amrnb/opencore-amrnb.sym +EXTRA_DIST = $(top_srcdir)/amrnb/opencore-amrnb.sym + +# Our sources to include. There are certain sources we exclude and they are +# $(DEC_SRC_DIR)/decoder_gsm_amr.cpp +# $(DEC_SRC_DIR)/pvgsmamrdecoder.cpp +# $(ENC_SRC_DIR)/gsmamr_encoder_wrapper.cpp +# $(COMMON_SRC_DIR)/bits2prm.cpp +# $(COMMON_SRC_DIR)/copy.cpp +# $(COMMON_SRC_DIR)/div_32.cpp +# $(COMMON_SRC_DIR)/l_abs.cpp +# $(COMMON_SRC_DIR)/r_fft.cpp +# $(COMMON_SRC_DIR)/vad1.cpp +# $(COMMON_SRC_DIR)/vad2.cpp +libopencore_amrnb_la_SOURCES = wrapper.cpp $(am__append_3) \ + $(am__append_6) $(COMMON_SRC_DIR)/add.cpp \ + $(COMMON_SRC_DIR)/az_lsp.cpp $(COMMON_SRC_DIR)/bitno_tab.cpp \ + $(COMMON_SRC_DIR)/bitreorder_tab.cpp \ + $(COMMON_SRC_DIR)/c2_9pf_tab.cpp $(COMMON_SRC_DIR)/div_s.cpp \ + $(COMMON_SRC_DIR)/extract_h.cpp \ + $(COMMON_SRC_DIR)/extract_l.cpp \ + $(COMMON_SRC_DIR)/gains_tbl.cpp $(COMMON_SRC_DIR)/gc_pred.cpp \ + $(COMMON_SRC_DIR)/get_const_tbls.cpp \ + $(COMMON_SRC_DIR)/gmed_n.cpp $(COMMON_SRC_DIR)/gray_tbl.cpp \ + $(COMMON_SRC_DIR)/grid_tbl.cpp $(COMMON_SRC_DIR)/int_lpc.cpp \ + $(COMMON_SRC_DIR)/inv_sqrt.cpp \ + $(COMMON_SRC_DIR)/inv_sqrt_tbl.cpp \ + $(COMMON_SRC_DIR)/l_deposit_h.cpp \ + $(COMMON_SRC_DIR)/l_deposit_l.cpp $(COMMON_SRC_DIR)/log2.cpp \ + $(COMMON_SRC_DIR)/log2_norm.cpp $(COMMON_SRC_DIR)/log2_tbl.cpp \ + $(COMMON_SRC_DIR)/lsfwt.cpp $(COMMON_SRC_DIR)/l_shr_r.cpp \ + $(COMMON_SRC_DIR)/lsp_az.cpp $(COMMON_SRC_DIR)/lsp.cpp \ + $(COMMON_SRC_DIR)/lsp_lsf.cpp \ + $(COMMON_SRC_DIR)/lsp_lsf_tbl.cpp \ + $(COMMON_SRC_DIR)/lsp_tab.cpp $(COMMON_SRC_DIR)/mult_r.cpp \ + $(COMMON_SRC_DIR)/negate.cpp $(COMMON_SRC_DIR)/norm_l.cpp \ + $(COMMON_SRC_DIR)/norm_s.cpp \ + $(COMMON_SRC_DIR)/overflow_tbl.cpp \ + $(COMMON_SRC_DIR)/ph_disp_tab.cpp $(COMMON_SRC_DIR)/pow2.cpp \ + $(COMMON_SRC_DIR)/pow2_tbl.cpp $(COMMON_SRC_DIR)/pred_lt.cpp \ + $(COMMON_SRC_DIR)/q_plsf_3.cpp \ + $(COMMON_SRC_DIR)/q_plsf_3_tbl.cpp \ + $(COMMON_SRC_DIR)/q_plsf_5.cpp \ + $(COMMON_SRC_DIR)/q_plsf_5_tbl.cpp \ + $(COMMON_SRC_DIR)/q_plsf.cpp \ + $(COMMON_SRC_DIR)/qua_gain_tbl.cpp \ + $(COMMON_SRC_DIR)/reorder.cpp $(COMMON_SRC_DIR)/residu.cpp \ + $(COMMON_SRC_DIR)/round.cpp $(COMMON_SRC_DIR)/set_zero.cpp \ + $(COMMON_SRC_DIR)/shr.cpp $(COMMON_SRC_DIR)/shr_r.cpp \ + $(COMMON_SRC_DIR)/sqrt_l.cpp $(COMMON_SRC_DIR)/sqrt_l_tbl.cpp \ + $(COMMON_SRC_DIR)/sub.cpp $(COMMON_SRC_DIR)/syn_filt.cpp \ + $(COMMON_SRC_DIR)/weight_a.cpp \ + $(COMMON_SRC_DIR)/window_tab.cpp +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cpp .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu amrnb/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu amrnb/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +opencore-amrnb.pc: $(top_builddir)/config.status $(srcdir)/opencore-amrnb.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libopencore-amrnb.la: $(libopencore_amrnb_la_OBJECTS) $(libopencore_amrnb_la_DEPENDENCIES) $(EXTRA_libopencore_amrnb_la_DEPENDENCIES) + $(AM_V_GEN)$(libopencore_amrnb_la_LINK) -rpath $(libdir) $(libopencore_amrnb_la_OBJECTS) $(libopencore_amrnb_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_refl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amrdecode.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amrencode.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autocorr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/az_lsp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/b_cn_cod.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgnscd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitno_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitreorder_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c1035pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c2_11pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c2_9pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c2_9pf_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c3_14pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c4_17pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c8_31pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_g_aver.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/calc_cor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/calc_en.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cbsearch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cl_ltp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cod_amr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convolve.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cor_h.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cor_h_x.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cor_h_x2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corrwght_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d1035pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d2_11pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d2_9pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d3_14pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d4_17pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d8_31pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_gain_c.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_gain_p.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_plsf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_plsf_3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_plsf_5.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dec_amr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dec_gain.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dec_input_format_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dec_lag3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dec_lag6.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div_32.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div_s.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtx_dec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtx_enc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec_gains.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enc_lag3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enc_lag6.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enc_output_format_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ets_to_if2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ets_to_wmf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ex_ctrl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_h.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_l.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g_adapt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g_code.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g_pitch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gain_q.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gains_tbl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gc_pred.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_const_tbls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmed_n.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gray_tbl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grid_tbl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hp_max.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/if2_to_ets.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/int_lpc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/int_lsf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inter_36.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inter_36_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inv_sqrt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inv_sqrt_tbl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_abs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_comp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_deposit_h.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_deposit_l.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_extract.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_negate.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l_shr_r.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lag_wind.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lag_wind_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/levinson.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lflg_upd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log2_norm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log2_tbl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsfwt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsp_avg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsp_az.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsp_lsf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsp_lsf_tbl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsp_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mult_r.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/negate.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/norm_l.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/norm_s.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ol_ltp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/overflow_tbl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p_ol_wgh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ph_disp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ph_disp_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pitch_fr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pitch_ol.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/post_pro.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow2_tbl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_big.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_proc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pred_lt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/preemph.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prm2bits.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pstfilt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q_gain_c.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q_gain_p.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q_plsf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q_plsf_3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q_plsf_3_tbl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q_plsf_5.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q_plsf_5_tbl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgain475.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgain475_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qgain795.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qua_gain.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qua_gain_tbl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reorder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/residu.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/round.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s10_8pf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_sign.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_zero.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shr_r.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sid_sync.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sp_dec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sp_enc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spreproc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spstproc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqrt_l.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqrt_l_tbl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sub.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syn_filt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ton_stab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vad1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/weight_a.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wmf_to_ets.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapper.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +agc.lo: $(DEC_SRC_DIR)/agc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT agc.lo -MD -MP -MF $(DEPDIR)/agc.Tpo -c -o agc.lo `test -f '$(DEC_SRC_DIR)/agc.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/agc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/agc.Tpo $(DEPDIR)/agc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/agc.cpp' object='agc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o agc.lo `test -f '$(DEC_SRC_DIR)/agc.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/agc.cpp + +amrdecode.lo: $(DEC_SRC_DIR)/amrdecode.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT amrdecode.lo -MD -MP -MF $(DEPDIR)/amrdecode.Tpo -c -o amrdecode.lo `test -f '$(DEC_SRC_DIR)/amrdecode.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/amrdecode.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/amrdecode.Tpo $(DEPDIR)/amrdecode.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/amrdecode.cpp' object='amrdecode.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o amrdecode.lo `test -f '$(DEC_SRC_DIR)/amrdecode.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/amrdecode.cpp + +a_refl.lo: $(DEC_SRC_DIR)/a_refl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT a_refl.lo -MD -MP -MF $(DEPDIR)/a_refl.Tpo -c -o a_refl.lo `test -f '$(DEC_SRC_DIR)/a_refl.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/a_refl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/a_refl.Tpo $(DEPDIR)/a_refl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/a_refl.cpp' object='a_refl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o a_refl.lo `test -f '$(DEC_SRC_DIR)/a_refl.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/a_refl.cpp + +b_cn_cod.lo: $(DEC_SRC_DIR)/b_cn_cod.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT b_cn_cod.lo -MD -MP -MF $(DEPDIR)/b_cn_cod.Tpo -c -o b_cn_cod.lo `test -f '$(DEC_SRC_DIR)/b_cn_cod.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/b_cn_cod.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/b_cn_cod.Tpo $(DEPDIR)/b_cn_cod.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/b_cn_cod.cpp' object='b_cn_cod.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o b_cn_cod.lo `test -f '$(DEC_SRC_DIR)/b_cn_cod.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/b_cn_cod.cpp + +bgnscd.lo: $(DEC_SRC_DIR)/bgnscd.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT bgnscd.lo -MD -MP -MF $(DEPDIR)/bgnscd.Tpo -c -o bgnscd.lo `test -f '$(DEC_SRC_DIR)/bgnscd.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/bgnscd.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bgnscd.Tpo $(DEPDIR)/bgnscd.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/bgnscd.cpp' object='bgnscd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bgnscd.lo `test -f '$(DEC_SRC_DIR)/bgnscd.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/bgnscd.cpp + +c_g_aver.lo: $(DEC_SRC_DIR)/c_g_aver.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT c_g_aver.lo -MD -MP -MF $(DEPDIR)/c_g_aver.Tpo -c -o c_g_aver.lo `test -f '$(DEC_SRC_DIR)/c_g_aver.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/c_g_aver.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/c_g_aver.Tpo $(DEPDIR)/c_g_aver.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/c_g_aver.cpp' object='c_g_aver.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o c_g_aver.lo `test -f '$(DEC_SRC_DIR)/c_g_aver.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/c_g_aver.cpp + +d1035pf.lo: $(DEC_SRC_DIR)/d1035pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT d1035pf.lo -MD -MP -MF $(DEPDIR)/d1035pf.Tpo -c -o d1035pf.lo `test -f '$(DEC_SRC_DIR)/d1035pf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d1035pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/d1035pf.Tpo $(DEPDIR)/d1035pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/d1035pf.cpp' object='d1035pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o d1035pf.lo `test -f '$(DEC_SRC_DIR)/d1035pf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d1035pf.cpp + +d2_11pf.lo: $(DEC_SRC_DIR)/d2_11pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT d2_11pf.lo -MD -MP -MF $(DEPDIR)/d2_11pf.Tpo -c -o d2_11pf.lo `test -f '$(DEC_SRC_DIR)/d2_11pf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d2_11pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/d2_11pf.Tpo $(DEPDIR)/d2_11pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/d2_11pf.cpp' object='d2_11pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o d2_11pf.lo `test -f '$(DEC_SRC_DIR)/d2_11pf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d2_11pf.cpp + +d2_9pf.lo: $(DEC_SRC_DIR)/d2_9pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT d2_9pf.lo -MD -MP -MF $(DEPDIR)/d2_9pf.Tpo -c -o d2_9pf.lo `test -f '$(DEC_SRC_DIR)/d2_9pf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d2_9pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/d2_9pf.Tpo $(DEPDIR)/d2_9pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/d2_9pf.cpp' object='d2_9pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o d2_9pf.lo `test -f '$(DEC_SRC_DIR)/d2_9pf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d2_9pf.cpp + +d3_14pf.lo: $(DEC_SRC_DIR)/d3_14pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT d3_14pf.lo -MD -MP -MF $(DEPDIR)/d3_14pf.Tpo -c -o d3_14pf.lo `test -f '$(DEC_SRC_DIR)/d3_14pf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d3_14pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/d3_14pf.Tpo $(DEPDIR)/d3_14pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/d3_14pf.cpp' object='d3_14pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o d3_14pf.lo `test -f '$(DEC_SRC_DIR)/d3_14pf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d3_14pf.cpp + +d4_17pf.lo: $(DEC_SRC_DIR)/d4_17pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT d4_17pf.lo -MD -MP -MF $(DEPDIR)/d4_17pf.Tpo -c -o d4_17pf.lo `test -f '$(DEC_SRC_DIR)/d4_17pf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d4_17pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/d4_17pf.Tpo $(DEPDIR)/d4_17pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/d4_17pf.cpp' object='d4_17pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o d4_17pf.lo `test -f '$(DEC_SRC_DIR)/d4_17pf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d4_17pf.cpp + +d8_31pf.lo: $(DEC_SRC_DIR)/d8_31pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT d8_31pf.lo -MD -MP -MF $(DEPDIR)/d8_31pf.Tpo -c -o d8_31pf.lo `test -f '$(DEC_SRC_DIR)/d8_31pf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d8_31pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/d8_31pf.Tpo $(DEPDIR)/d8_31pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/d8_31pf.cpp' object='d8_31pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o d8_31pf.lo `test -f '$(DEC_SRC_DIR)/d8_31pf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d8_31pf.cpp + +dec_amr.lo: $(DEC_SRC_DIR)/dec_amr.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dec_amr.lo -MD -MP -MF $(DEPDIR)/dec_amr.Tpo -c -o dec_amr.lo `test -f '$(DEC_SRC_DIR)/dec_amr.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_amr.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dec_amr.Tpo $(DEPDIR)/dec_amr.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/dec_amr.cpp' object='dec_amr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dec_amr.lo `test -f '$(DEC_SRC_DIR)/dec_amr.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_amr.cpp + +dec_gain.lo: $(DEC_SRC_DIR)/dec_gain.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dec_gain.lo -MD -MP -MF $(DEPDIR)/dec_gain.Tpo -c -o dec_gain.lo `test -f '$(DEC_SRC_DIR)/dec_gain.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_gain.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dec_gain.Tpo $(DEPDIR)/dec_gain.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/dec_gain.cpp' object='dec_gain.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dec_gain.lo `test -f '$(DEC_SRC_DIR)/dec_gain.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_gain.cpp + +dec_input_format_tab.lo: $(DEC_SRC_DIR)/dec_input_format_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dec_input_format_tab.lo -MD -MP -MF $(DEPDIR)/dec_input_format_tab.Tpo -c -o dec_input_format_tab.lo `test -f '$(DEC_SRC_DIR)/dec_input_format_tab.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_input_format_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dec_input_format_tab.Tpo $(DEPDIR)/dec_input_format_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/dec_input_format_tab.cpp' object='dec_input_format_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dec_input_format_tab.lo `test -f '$(DEC_SRC_DIR)/dec_input_format_tab.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_input_format_tab.cpp + +dec_lag3.lo: $(DEC_SRC_DIR)/dec_lag3.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dec_lag3.lo -MD -MP -MF $(DEPDIR)/dec_lag3.Tpo -c -o dec_lag3.lo `test -f '$(DEC_SRC_DIR)/dec_lag3.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_lag3.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dec_lag3.Tpo $(DEPDIR)/dec_lag3.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/dec_lag3.cpp' object='dec_lag3.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dec_lag3.lo `test -f '$(DEC_SRC_DIR)/dec_lag3.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_lag3.cpp + +dec_lag6.lo: $(DEC_SRC_DIR)/dec_lag6.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dec_lag6.lo -MD -MP -MF $(DEPDIR)/dec_lag6.Tpo -c -o dec_lag6.lo `test -f '$(DEC_SRC_DIR)/dec_lag6.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_lag6.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dec_lag6.Tpo $(DEPDIR)/dec_lag6.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/dec_lag6.cpp' object='dec_lag6.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dec_lag6.lo `test -f '$(DEC_SRC_DIR)/dec_lag6.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_lag6.cpp + +d_gain_c.lo: $(DEC_SRC_DIR)/d_gain_c.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT d_gain_c.lo -MD -MP -MF $(DEPDIR)/d_gain_c.Tpo -c -o d_gain_c.lo `test -f '$(DEC_SRC_DIR)/d_gain_c.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d_gain_c.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/d_gain_c.Tpo $(DEPDIR)/d_gain_c.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/d_gain_c.cpp' object='d_gain_c.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o d_gain_c.lo `test -f '$(DEC_SRC_DIR)/d_gain_c.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d_gain_c.cpp + +d_gain_p.lo: $(DEC_SRC_DIR)/d_gain_p.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT d_gain_p.lo -MD -MP -MF $(DEPDIR)/d_gain_p.Tpo -c -o d_gain_p.lo `test -f '$(DEC_SRC_DIR)/d_gain_p.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d_gain_p.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/d_gain_p.Tpo $(DEPDIR)/d_gain_p.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/d_gain_p.cpp' object='d_gain_p.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o d_gain_p.lo `test -f '$(DEC_SRC_DIR)/d_gain_p.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d_gain_p.cpp + +d_plsf_3.lo: $(DEC_SRC_DIR)/d_plsf_3.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT d_plsf_3.lo -MD -MP -MF $(DEPDIR)/d_plsf_3.Tpo -c -o d_plsf_3.lo `test -f '$(DEC_SRC_DIR)/d_plsf_3.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d_plsf_3.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/d_plsf_3.Tpo $(DEPDIR)/d_plsf_3.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/d_plsf_3.cpp' object='d_plsf_3.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o d_plsf_3.lo `test -f '$(DEC_SRC_DIR)/d_plsf_3.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d_plsf_3.cpp + +d_plsf_5.lo: $(DEC_SRC_DIR)/d_plsf_5.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT d_plsf_5.lo -MD -MP -MF $(DEPDIR)/d_plsf_5.Tpo -c -o d_plsf_5.lo `test -f '$(DEC_SRC_DIR)/d_plsf_5.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d_plsf_5.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/d_plsf_5.Tpo $(DEPDIR)/d_plsf_5.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/d_plsf_5.cpp' object='d_plsf_5.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o d_plsf_5.lo `test -f '$(DEC_SRC_DIR)/d_plsf_5.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d_plsf_5.cpp + +d_plsf.lo: $(DEC_SRC_DIR)/d_plsf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT d_plsf.lo -MD -MP -MF $(DEPDIR)/d_plsf.Tpo -c -o d_plsf.lo `test -f '$(DEC_SRC_DIR)/d_plsf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d_plsf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/d_plsf.Tpo $(DEPDIR)/d_plsf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/d_plsf.cpp' object='d_plsf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o d_plsf.lo `test -f '$(DEC_SRC_DIR)/d_plsf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/d_plsf.cpp + +dtx_dec.lo: $(DEC_SRC_DIR)/dtx_dec.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dtx_dec.lo -MD -MP -MF $(DEPDIR)/dtx_dec.Tpo -c -o dtx_dec.lo `test -f '$(DEC_SRC_DIR)/dtx_dec.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dtx_dec.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dtx_dec.Tpo $(DEPDIR)/dtx_dec.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/dtx_dec.cpp' object='dtx_dec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dtx_dec.lo `test -f '$(DEC_SRC_DIR)/dtx_dec.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dtx_dec.cpp + +ec_gains.lo: $(DEC_SRC_DIR)/ec_gains.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ec_gains.lo -MD -MP -MF $(DEPDIR)/ec_gains.Tpo -c -o ec_gains.lo `test -f '$(DEC_SRC_DIR)/ec_gains.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/ec_gains.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ec_gains.Tpo $(DEPDIR)/ec_gains.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/ec_gains.cpp' object='ec_gains.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ec_gains.lo `test -f '$(DEC_SRC_DIR)/ec_gains.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/ec_gains.cpp + +ex_ctrl.lo: $(DEC_SRC_DIR)/ex_ctrl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ex_ctrl.lo -MD -MP -MF $(DEPDIR)/ex_ctrl.Tpo -c -o ex_ctrl.lo `test -f '$(DEC_SRC_DIR)/ex_ctrl.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/ex_ctrl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ex_ctrl.Tpo $(DEPDIR)/ex_ctrl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/ex_ctrl.cpp' object='ex_ctrl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ex_ctrl.lo `test -f '$(DEC_SRC_DIR)/ex_ctrl.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/ex_ctrl.cpp + +if2_to_ets.lo: $(DEC_SRC_DIR)/if2_to_ets.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT if2_to_ets.lo -MD -MP -MF $(DEPDIR)/if2_to_ets.Tpo -c -o if2_to_ets.lo `test -f '$(DEC_SRC_DIR)/if2_to_ets.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/if2_to_ets.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/if2_to_ets.Tpo $(DEPDIR)/if2_to_ets.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/if2_to_ets.cpp' object='if2_to_ets.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o if2_to_ets.lo `test -f '$(DEC_SRC_DIR)/if2_to_ets.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/if2_to_ets.cpp + +int_lsf.lo: $(DEC_SRC_DIR)/int_lsf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT int_lsf.lo -MD -MP -MF $(DEPDIR)/int_lsf.Tpo -c -o int_lsf.lo `test -f '$(DEC_SRC_DIR)/int_lsf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/int_lsf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/int_lsf.Tpo $(DEPDIR)/int_lsf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/int_lsf.cpp' object='int_lsf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o int_lsf.lo `test -f '$(DEC_SRC_DIR)/int_lsf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/int_lsf.cpp + +lsp_avg.lo: $(DEC_SRC_DIR)/lsp_avg.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lsp_avg.lo -MD -MP -MF $(DEPDIR)/lsp_avg.Tpo -c -o lsp_avg.lo `test -f '$(DEC_SRC_DIR)/lsp_avg.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/lsp_avg.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lsp_avg.Tpo $(DEPDIR)/lsp_avg.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/lsp_avg.cpp' object='lsp_avg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lsp_avg.lo `test -f '$(DEC_SRC_DIR)/lsp_avg.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/lsp_avg.cpp + +ph_disp.lo: $(DEC_SRC_DIR)/ph_disp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ph_disp.lo -MD -MP -MF $(DEPDIR)/ph_disp.Tpo -c -o ph_disp.lo `test -f '$(DEC_SRC_DIR)/ph_disp.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/ph_disp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ph_disp.Tpo $(DEPDIR)/ph_disp.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/ph_disp.cpp' object='ph_disp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ph_disp.lo `test -f '$(DEC_SRC_DIR)/ph_disp.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/ph_disp.cpp + +post_pro.lo: $(DEC_SRC_DIR)/post_pro.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT post_pro.lo -MD -MP -MF $(DEPDIR)/post_pro.Tpo -c -o post_pro.lo `test -f '$(DEC_SRC_DIR)/post_pro.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/post_pro.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/post_pro.Tpo $(DEPDIR)/post_pro.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/post_pro.cpp' object='post_pro.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o post_pro.lo `test -f '$(DEC_SRC_DIR)/post_pro.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/post_pro.cpp + +preemph.lo: $(DEC_SRC_DIR)/preemph.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT preemph.lo -MD -MP -MF $(DEPDIR)/preemph.Tpo -c -o preemph.lo `test -f '$(DEC_SRC_DIR)/preemph.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/preemph.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/preemph.Tpo $(DEPDIR)/preemph.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/preemph.cpp' object='preemph.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o preemph.lo `test -f '$(DEC_SRC_DIR)/preemph.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/preemph.cpp + +pstfilt.lo: $(DEC_SRC_DIR)/pstfilt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pstfilt.lo -MD -MP -MF $(DEPDIR)/pstfilt.Tpo -c -o pstfilt.lo `test -f '$(DEC_SRC_DIR)/pstfilt.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/pstfilt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pstfilt.Tpo $(DEPDIR)/pstfilt.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/pstfilt.cpp' object='pstfilt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pstfilt.lo `test -f '$(DEC_SRC_DIR)/pstfilt.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/pstfilt.cpp + +qgain475_tab.lo: $(DEC_SRC_DIR)/qgain475_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT qgain475_tab.lo -MD -MP -MF $(DEPDIR)/qgain475_tab.Tpo -c -o qgain475_tab.lo `test -f '$(DEC_SRC_DIR)/qgain475_tab.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/qgain475_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qgain475_tab.Tpo $(DEPDIR)/qgain475_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/qgain475_tab.cpp' object='qgain475_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o qgain475_tab.lo `test -f '$(DEC_SRC_DIR)/qgain475_tab.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/qgain475_tab.cpp + +sp_dec.lo: $(DEC_SRC_DIR)/sp_dec.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sp_dec.lo -MD -MP -MF $(DEPDIR)/sp_dec.Tpo -c -o sp_dec.lo `test -f '$(DEC_SRC_DIR)/sp_dec.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/sp_dec.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sp_dec.Tpo $(DEPDIR)/sp_dec.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/sp_dec.cpp' object='sp_dec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sp_dec.lo `test -f '$(DEC_SRC_DIR)/sp_dec.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/sp_dec.cpp + +wmf_to_ets.lo: $(DEC_SRC_DIR)/wmf_to_ets.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wmf_to_ets.lo -MD -MP -MF $(DEPDIR)/wmf_to_ets.Tpo -c -o wmf_to_ets.lo `test -f '$(DEC_SRC_DIR)/wmf_to_ets.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/wmf_to_ets.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/wmf_to_ets.Tpo $(DEPDIR)/wmf_to_ets.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/wmf_to_ets.cpp' object='wmf_to_ets.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wmf_to_ets.lo `test -f '$(DEC_SRC_DIR)/wmf_to_ets.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/wmf_to_ets.cpp + +amrencode.lo: $(ENC_SRC_DIR)/amrencode.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT amrencode.lo -MD -MP -MF $(DEPDIR)/amrencode.Tpo -c -o amrencode.lo `test -f '$(ENC_SRC_DIR)/amrencode.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/amrencode.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/amrencode.Tpo $(DEPDIR)/amrencode.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/amrencode.cpp' object='amrencode.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o amrencode.lo `test -f '$(ENC_SRC_DIR)/amrencode.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/amrencode.cpp + +autocorr.lo: $(ENC_SRC_DIR)/autocorr.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT autocorr.lo -MD -MP -MF $(DEPDIR)/autocorr.Tpo -c -o autocorr.lo `test -f '$(ENC_SRC_DIR)/autocorr.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/autocorr.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/autocorr.Tpo $(DEPDIR)/autocorr.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/autocorr.cpp' object='autocorr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o autocorr.lo `test -f '$(ENC_SRC_DIR)/autocorr.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/autocorr.cpp + +c1035pf.lo: $(ENC_SRC_DIR)/c1035pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT c1035pf.lo -MD -MP -MF $(DEPDIR)/c1035pf.Tpo -c -o c1035pf.lo `test -f '$(ENC_SRC_DIR)/c1035pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/c1035pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/c1035pf.Tpo $(DEPDIR)/c1035pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/c1035pf.cpp' object='c1035pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o c1035pf.lo `test -f '$(ENC_SRC_DIR)/c1035pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/c1035pf.cpp + +c2_11pf.lo: $(ENC_SRC_DIR)/c2_11pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT c2_11pf.lo -MD -MP -MF $(DEPDIR)/c2_11pf.Tpo -c -o c2_11pf.lo `test -f '$(ENC_SRC_DIR)/c2_11pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/c2_11pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/c2_11pf.Tpo $(DEPDIR)/c2_11pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/c2_11pf.cpp' object='c2_11pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o c2_11pf.lo `test -f '$(ENC_SRC_DIR)/c2_11pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/c2_11pf.cpp + +c2_9pf.lo: $(ENC_SRC_DIR)/c2_9pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT c2_9pf.lo -MD -MP -MF $(DEPDIR)/c2_9pf.Tpo -c -o c2_9pf.lo `test -f '$(ENC_SRC_DIR)/c2_9pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/c2_9pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/c2_9pf.Tpo $(DEPDIR)/c2_9pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/c2_9pf.cpp' object='c2_9pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o c2_9pf.lo `test -f '$(ENC_SRC_DIR)/c2_9pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/c2_9pf.cpp + +c3_14pf.lo: $(ENC_SRC_DIR)/c3_14pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT c3_14pf.lo -MD -MP -MF $(DEPDIR)/c3_14pf.Tpo -c -o c3_14pf.lo `test -f '$(ENC_SRC_DIR)/c3_14pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/c3_14pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/c3_14pf.Tpo $(DEPDIR)/c3_14pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/c3_14pf.cpp' object='c3_14pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o c3_14pf.lo `test -f '$(ENC_SRC_DIR)/c3_14pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/c3_14pf.cpp + +c4_17pf.lo: $(ENC_SRC_DIR)/c4_17pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT c4_17pf.lo -MD -MP -MF $(DEPDIR)/c4_17pf.Tpo -c -o c4_17pf.lo `test -f '$(ENC_SRC_DIR)/c4_17pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/c4_17pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/c4_17pf.Tpo $(DEPDIR)/c4_17pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/c4_17pf.cpp' object='c4_17pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o c4_17pf.lo `test -f '$(ENC_SRC_DIR)/c4_17pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/c4_17pf.cpp + +c8_31pf.lo: $(ENC_SRC_DIR)/c8_31pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT c8_31pf.lo -MD -MP -MF $(DEPDIR)/c8_31pf.Tpo -c -o c8_31pf.lo `test -f '$(ENC_SRC_DIR)/c8_31pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/c8_31pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/c8_31pf.Tpo $(DEPDIR)/c8_31pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/c8_31pf.cpp' object='c8_31pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o c8_31pf.lo `test -f '$(ENC_SRC_DIR)/c8_31pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/c8_31pf.cpp + +calc_cor.lo: $(ENC_SRC_DIR)/calc_cor.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT calc_cor.lo -MD -MP -MF $(DEPDIR)/calc_cor.Tpo -c -o calc_cor.lo `test -f '$(ENC_SRC_DIR)/calc_cor.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/calc_cor.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/calc_cor.Tpo $(DEPDIR)/calc_cor.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/calc_cor.cpp' object='calc_cor.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o calc_cor.lo `test -f '$(ENC_SRC_DIR)/calc_cor.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/calc_cor.cpp + +calc_en.lo: $(ENC_SRC_DIR)/calc_en.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT calc_en.lo -MD -MP -MF $(DEPDIR)/calc_en.Tpo -c -o calc_en.lo `test -f '$(ENC_SRC_DIR)/calc_en.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/calc_en.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/calc_en.Tpo $(DEPDIR)/calc_en.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/calc_en.cpp' object='calc_en.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o calc_en.lo `test -f '$(ENC_SRC_DIR)/calc_en.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/calc_en.cpp + +cbsearch.lo: $(ENC_SRC_DIR)/cbsearch.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cbsearch.lo -MD -MP -MF $(DEPDIR)/cbsearch.Tpo -c -o cbsearch.lo `test -f '$(ENC_SRC_DIR)/cbsearch.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/cbsearch.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cbsearch.Tpo $(DEPDIR)/cbsearch.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/cbsearch.cpp' object='cbsearch.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cbsearch.lo `test -f '$(ENC_SRC_DIR)/cbsearch.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/cbsearch.cpp + +cl_ltp.lo: $(ENC_SRC_DIR)/cl_ltp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cl_ltp.lo -MD -MP -MF $(DEPDIR)/cl_ltp.Tpo -c -o cl_ltp.lo `test -f '$(ENC_SRC_DIR)/cl_ltp.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/cl_ltp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cl_ltp.Tpo $(DEPDIR)/cl_ltp.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/cl_ltp.cpp' object='cl_ltp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cl_ltp.lo `test -f '$(ENC_SRC_DIR)/cl_ltp.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/cl_ltp.cpp + +cod_amr.lo: $(ENC_SRC_DIR)/cod_amr.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cod_amr.lo -MD -MP -MF $(DEPDIR)/cod_amr.Tpo -c -o cod_amr.lo `test -f '$(ENC_SRC_DIR)/cod_amr.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/cod_amr.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cod_amr.Tpo $(DEPDIR)/cod_amr.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/cod_amr.cpp' object='cod_amr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cod_amr.lo `test -f '$(ENC_SRC_DIR)/cod_amr.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/cod_amr.cpp + +convolve.lo: $(ENC_SRC_DIR)/convolve.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT convolve.lo -MD -MP -MF $(DEPDIR)/convolve.Tpo -c -o convolve.lo `test -f '$(ENC_SRC_DIR)/convolve.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/convolve.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/convolve.Tpo $(DEPDIR)/convolve.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/convolve.cpp' object='convolve.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o convolve.lo `test -f '$(ENC_SRC_DIR)/convolve.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/convolve.cpp + +cor_h.lo: $(ENC_SRC_DIR)/cor_h.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cor_h.lo -MD -MP -MF $(DEPDIR)/cor_h.Tpo -c -o cor_h.lo `test -f '$(ENC_SRC_DIR)/cor_h.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/cor_h.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cor_h.Tpo $(DEPDIR)/cor_h.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/cor_h.cpp' object='cor_h.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cor_h.lo `test -f '$(ENC_SRC_DIR)/cor_h.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/cor_h.cpp + +cor_h_x2.lo: $(ENC_SRC_DIR)/cor_h_x2.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cor_h_x2.lo -MD -MP -MF $(DEPDIR)/cor_h_x2.Tpo -c -o cor_h_x2.lo `test -f '$(ENC_SRC_DIR)/cor_h_x2.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/cor_h_x2.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cor_h_x2.Tpo $(DEPDIR)/cor_h_x2.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/cor_h_x2.cpp' object='cor_h_x2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cor_h_x2.lo `test -f '$(ENC_SRC_DIR)/cor_h_x2.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/cor_h_x2.cpp + +cor_h_x.lo: $(ENC_SRC_DIR)/cor_h_x.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cor_h_x.lo -MD -MP -MF $(DEPDIR)/cor_h_x.Tpo -c -o cor_h_x.lo `test -f '$(ENC_SRC_DIR)/cor_h_x.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/cor_h_x.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cor_h_x.Tpo $(DEPDIR)/cor_h_x.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/cor_h_x.cpp' object='cor_h_x.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cor_h_x.lo `test -f '$(ENC_SRC_DIR)/cor_h_x.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/cor_h_x.cpp + +corrwght_tab.lo: $(ENC_SRC_DIR)/corrwght_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT corrwght_tab.lo -MD -MP -MF $(DEPDIR)/corrwght_tab.Tpo -c -o corrwght_tab.lo `test -f '$(ENC_SRC_DIR)/corrwght_tab.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/corrwght_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corrwght_tab.Tpo $(DEPDIR)/corrwght_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/corrwght_tab.cpp' object='corrwght_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o corrwght_tab.lo `test -f '$(ENC_SRC_DIR)/corrwght_tab.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/corrwght_tab.cpp + +div_32.lo: $(ENC_SRC_DIR)/div_32.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT div_32.lo -MD -MP -MF $(DEPDIR)/div_32.Tpo -c -o div_32.lo `test -f '$(ENC_SRC_DIR)/div_32.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/div_32.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/div_32.Tpo $(DEPDIR)/div_32.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/div_32.cpp' object='div_32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o div_32.lo `test -f '$(ENC_SRC_DIR)/div_32.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/div_32.cpp + +dtx_enc.lo: $(ENC_SRC_DIR)/dtx_enc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dtx_enc.lo -MD -MP -MF $(DEPDIR)/dtx_enc.Tpo -c -o dtx_enc.lo `test -f '$(ENC_SRC_DIR)/dtx_enc.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/dtx_enc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dtx_enc.Tpo $(DEPDIR)/dtx_enc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/dtx_enc.cpp' object='dtx_enc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dtx_enc.lo `test -f '$(ENC_SRC_DIR)/dtx_enc.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/dtx_enc.cpp + +enc_lag3.lo: $(ENC_SRC_DIR)/enc_lag3.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT enc_lag3.lo -MD -MP -MF $(DEPDIR)/enc_lag3.Tpo -c -o enc_lag3.lo `test -f '$(ENC_SRC_DIR)/enc_lag3.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/enc_lag3.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enc_lag3.Tpo $(DEPDIR)/enc_lag3.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/enc_lag3.cpp' object='enc_lag3.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o enc_lag3.lo `test -f '$(ENC_SRC_DIR)/enc_lag3.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/enc_lag3.cpp + +enc_lag6.lo: $(ENC_SRC_DIR)/enc_lag6.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT enc_lag6.lo -MD -MP -MF $(DEPDIR)/enc_lag6.Tpo -c -o enc_lag6.lo `test -f '$(ENC_SRC_DIR)/enc_lag6.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/enc_lag6.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enc_lag6.Tpo $(DEPDIR)/enc_lag6.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/enc_lag6.cpp' object='enc_lag6.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o enc_lag6.lo `test -f '$(ENC_SRC_DIR)/enc_lag6.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/enc_lag6.cpp + +enc_output_format_tab.lo: $(ENC_SRC_DIR)/enc_output_format_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT enc_output_format_tab.lo -MD -MP -MF $(DEPDIR)/enc_output_format_tab.Tpo -c -o enc_output_format_tab.lo `test -f '$(ENC_SRC_DIR)/enc_output_format_tab.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/enc_output_format_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enc_output_format_tab.Tpo $(DEPDIR)/enc_output_format_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/enc_output_format_tab.cpp' object='enc_output_format_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o enc_output_format_tab.lo `test -f '$(ENC_SRC_DIR)/enc_output_format_tab.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/enc_output_format_tab.cpp + +ets_to_if2.lo: $(ENC_SRC_DIR)/ets_to_if2.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ets_to_if2.lo -MD -MP -MF $(DEPDIR)/ets_to_if2.Tpo -c -o ets_to_if2.lo `test -f '$(ENC_SRC_DIR)/ets_to_if2.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/ets_to_if2.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ets_to_if2.Tpo $(DEPDIR)/ets_to_if2.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/ets_to_if2.cpp' object='ets_to_if2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ets_to_if2.lo `test -f '$(ENC_SRC_DIR)/ets_to_if2.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/ets_to_if2.cpp + +ets_to_wmf.lo: $(ENC_SRC_DIR)/ets_to_wmf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ets_to_wmf.lo -MD -MP -MF $(DEPDIR)/ets_to_wmf.Tpo -c -o ets_to_wmf.lo `test -f '$(ENC_SRC_DIR)/ets_to_wmf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/ets_to_wmf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ets_to_wmf.Tpo $(DEPDIR)/ets_to_wmf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/ets_to_wmf.cpp' object='ets_to_wmf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ets_to_wmf.lo `test -f '$(ENC_SRC_DIR)/ets_to_wmf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/ets_to_wmf.cpp + +g_adapt.lo: $(ENC_SRC_DIR)/g_adapt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT g_adapt.lo -MD -MP -MF $(DEPDIR)/g_adapt.Tpo -c -o g_adapt.lo `test -f '$(ENC_SRC_DIR)/g_adapt.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/g_adapt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/g_adapt.Tpo $(DEPDIR)/g_adapt.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/g_adapt.cpp' object='g_adapt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o g_adapt.lo `test -f '$(ENC_SRC_DIR)/g_adapt.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/g_adapt.cpp + +gain_q.lo: $(ENC_SRC_DIR)/gain_q.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gain_q.lo -MD -MP -MF $(DEPDIR)/gain_q.Tpo -c -o gain_q.lo `test -f '$(ENC_SRC_DIR)/gain_q.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/gain_q.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gain_q.Tpo $(DEPDIR)/gain_q.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/gain_q.cpp' object='gain_q.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gain_q.lo `test -f '$(ENC_SRC_DIR)/gain_q.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/gain_q.cpp + +g_code.lo: $(ENC_SRC_DIR)/g_code.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT g_code.lo -MD -MP -MF $(DEPDIR)/g_code.Tpo -c -o g_code.lo `test -f '$(ENC_SRC_DIR)/g_code.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/g_code.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/g_code.Tpo $(DEPDIR)/g_code.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/g_code.cpp' object='g_code.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o g_code.lo `test -f '$(ENC_SRC_DIR)/g_code.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/g_code.cpp + +g_pitch.lo: $(ENC_SRC_DIR)/g_pitch.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT g_pitch.lo -MD -MP -MF $(DEPDIR)/g_pitch.Tpo -c -o g_pitch.lo `test -f '$(ENC_SRC_DIR)/g_pitch.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/g_pitch.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/g_pitch.Tpo $(DEPDIR)/g_pitch.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/g_pitch.cpp' object='g_pitch.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o g_pitch.lo `test -f '$(ENC_SRC_DIR)/g_pitch.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/g_pitch.cpp + +hp_max.lo: $(ENC_SRC_DIR)/hp_max.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hp_max.lo -MD -MP -MF $(DEPDIR)/hp_max.Tpo -c -o hp_max.lo `test -f '$(ENC_SRC_DIR)/hp_max.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/hp_max.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hp_max.Tpo $(DEPDIR)/hp_max.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/hp_max.cpp' object='hp_max.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hp_max.lo `test -f '$(ENC_SRC_DIR)/hp_max.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/hp_max.cpp + +inter_36.lo: $(ENC_SRC_DIR)/inter_36.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT inter_36.lo -MD -MP -MF $(DEPDIR)/inter_36.Tpo -c -o inter_36.lo `test -f '$(ENC_SRC_DIR)/inter_36.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/inter_36.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/inter_36.Tpo $(DEPDIR)/inter_36.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/inter_36.cpp' object='inter_36.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o inter_36.lo `test -f '$(ENC_SRC_DIR)/inter_36.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/inter_36.cpp + +inter_36_tab.lo: $(ENC_SRC_DIR)/inter_36_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT inter_36_tab.lo -MD -MP -MF $(DEPDIR)/inter_36_tab.Tpo -c -o inter_36_tab.lo `test -f '$(ENC_SRC_DIR)/inter_36_tab.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/inter_36_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/inter_36_tab.Tpo $(DEPDIR)/inter_36_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/inter_36_tab.cpp' object='inter_36_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o inter_36_tab.lo `test -f '$(ENC_SRC_DIR)/inter_36_tab.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/inter_36_tab.cpp + +l_abs.lo: $(ENC_SRC_DIR)/l_abs.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT l_abs.lo -MD -MP -MF $(DEPDIR)/l_abs.Tpo -c -o l_abs.lo `test -f '$(ENC_SRC_DIR)/l_abs.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/l_abs.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/l_abs.Tpo $(DEPDIR)/l_abs.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/l_abs.cpp' object='l_abs.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o l_abs.lo `test -f '$(ENC_SRC_DIR)/l_abs.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/l_abs.cpp + +lag_wind.lo: $(ENC_SRC_DIR)/lag_wind.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lag_wind.lo -MD -MP -MF $(DEPDIR)/lag_wind.Tpo -c -o lag_wind.lo `test -f '$(ENC_SRC_DIR)/lag_wind.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/lag_wind.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lag_wind.Tpo $(DEPDIR)/lag_wind.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/lag_wind.cpp' object='lag_wind.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lag_wind.lo `test -f '$(ENC_SRC_DIR)/lag_wind.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/lag_wind.cpp + +lag_wind_tab.lo: $(ENC_SRC_DIR)/lag_wind_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lag_wind_tab.lo -MD -MP -MF $(DEPDIR)/lag_wind_tab.Tpo -c -o lag_wind_tab.lo `test -f '$(ENC_SRC_DIR)/lag_wind_tab.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/lag_wind_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lag_wind_tab.Tpo $(DEPDIR)/lag_wind_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/lag_wind_tab.cpp' object='lag_wind_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lag_wind_tab.lo `test -f '$(ENC_SRC_DIR)/lag_wind_tab.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/lag_wind_tab.cpp + +l_comp.lo: $(ENC_SRC_DIR)/l_comp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT l_comp.lo -MD -MP -MF $(DEPDIR)/l_comp.Tpo -c -o l_comp.lo `test -f '$(ENC_SRC_DIR)/l_comp.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/l_comp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/l_comp.Tpo $(DEPDIR)/l_comp.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/l_comp.cpp' object='l_comp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o l_comp.lo `test -f '$(ENC_SRC_DIR)/l_comp.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/l_comp.cpp + +levinson.lo: $(ENC_SRC_DIR)/levinson.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT levinson.lo -MD -MP -MF $(DEPDIR)/levinson.Tpo -c -o levinson.lo `test -f '$(ENC_SRC_DIR)/levinson.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/levinson.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/levinson.Tpo $(DEPDIR)/levinson.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/levinson.cpp' object='levinson.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o levinson.lo `test -f '$(ENC_SRC_DIR)/levinson.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/levinson.cpp + +l_extract.lo: $(ENC_SRC_DIR)/l_extract.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT l_extract.lo -MD -MP -MF $(DEPDIR)/l_extract.Tpo -c -o l_extract.lo `test -f '$(ENC_SRC_DIR)/l_extract.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/l_extract.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/l_extract.Tpo $(DEPDIR)/l_extract.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/l_extract.cpp' object='l_extract.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o l_extract.lo `test -f '$(ENC_SRC_DIR)/l_extract.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/l_extract.cpp + +lflg_upd.lo: $(ENC_SRC_DIR)/lflg_upd.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lflg_upd.lo -MD -MP -MF $(DEPDIR)/lflg_upd.Tpo -c -o lflg_upd.lo `test -f '$(ENC_SRC_DIR)/lflg_upd.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/lflg_upd.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lflg_upd.Tpo $(DEPDIR)/lflg_upd.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/lflg_upd.cpp' object='lflg_upd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lflg_upd.lo `test -f '$(ENC_SRC_DIR)/lflg_upd.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/lflg_upd.cpp + +l_negate.lo: $(ENC_SRC_DIR)/l_negate.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT l_negate.lo -MD -MP -MF $(DEPDIR)/l_negate.Tpo -c -o l_negate.lo `test -f '$(ENC_SRC_DIR)/l_negate.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/l_negate.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/l_negate.Tpo $(DEPDIR)/l_negate.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/l_negate.cpp' object='l_negate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o l_negate.lo `test -f '$(ENC_SRC_DIR)/l_negate.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/l_negate.cpp + +lpc.lo: $(ENC_SRC_DIR)/lpc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lpc.lo -MD -MP -MF $(DEPDIR)/lpc.Tpo -c -o lpc.lo `test -f '$(ENC_SRC_DIR)/lpc.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/lpc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lpc.Tpo $(DEPDIR)/lpc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/lpc.cpp' object='lpc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lpc.lo `test -f '$(ENC_SRC_DIR)/lpc.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/lpc.cpp + +ol_ltp.lo: $(ENC_SRC_DIR)/ol_ltp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ol_ltp.lo -MD -MP -MF $(DEPDIR)/ol_ltp.Tpo -c -o ol_ltp.lo `test -f '$(ENC_SRC_DIR)/ol_ltp.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/ol_ltp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ol_ltp.Tpo $(DEPDIR)/ol_ltp.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/ol_ltp.cpp' object='ol_ltp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ol_ltp.lo `test -f '$(ENC_SRC_DIR)/ol_ltp.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/ol_ltp.cpp + +pitch_fr.lo: $(ENC_SRC_DIR)/pitch_fr.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pitch_fr.lo -MD -MP -MF $(DEPDIR)/pitch_fr.Tpo -c -o pitch_fr.lo `test -f '$(ENC_SRC_DIR)/pitch_fr.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/pitch_fr.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pitch_fr.Tpo $(DEPDIR)/pitch_fr.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/pitch_fr.cpp' object='pitch_fr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pitch_fr.lo `test -f '$(ENC_SRC_DIR)/pitch_fr.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/pitch_fr.cpp + +pitch_ol.lo: $(ENC_SRC_DIR)/pitch_ol.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pitch_ol.lo -MD -MP -MF $(DEPDIR)/pitch_ol.Tpo -c -o pitch_ol.lo `test -f '$(ENC_SRC_DIR)/pitch_ol.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/pitch_ol.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pitch_ol.Tpo $(DEPDIR)/pitch_ol.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/pitch_ol.cpp' object='pitch_ol.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pitch_ol.lo `test -f '$(ENC_SRC_DIR)/pitch_ol.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/pitch_ol.cpp + +p_ol_wgh.lo: $(ENC_SRC_DIR)/p_ol_wgh.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT p_ol_wgh.lo -MD -MP -MF $(DEPDIR)/p_ol_wgh.Tpo -c -o p_ol_wgh.lo `test -f '$(ENC_SRC_DIR)/p_ol_wgh.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/p_ol_wgh.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/p_ol_wgh.Tpo $(DEPDIR)/p_ol_wgh.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/p_ol_wgh.cpp' object='p_ol_wgh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o p_ol_wgh.lo `test -f '$(ENC_SRC_DIR)/p_ol_wgh.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/p_ol_wgh.cpp + +pre_big.lo: $(ENC_SRC_DIR)/pre_big.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pre_big.lo -MD -MP -MF $(DEPDIR)/pre_big.Tpo -c -o pre_big.lo `test -f '$(ENC_SRC_DIR)/pre_big.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/pre_big.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pre_big.Tpo $(DEPDIR)/pre_big.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/pre_big.cpp' object='pre_big.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pre_big.lo `test -f '$(ENC_SRC_DIR)/pre_big.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/pre_big.cpp + +pre_proc.lo: $(ENC_SRC_DIR)/pre_proc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pre_proc.lo -MD -MP -MF $(DEPDIR)/pre_proc.Tpo -c -o pre_proc.lo `test -f '$(ENC_SRC_DIR)/pre_proc.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/pre_proc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pre_proc.Tpo $(DEPDIR)/pre_proc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/pre_proc.cpp' object='pre_proc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pre_proc.lo `test -f '$(ENC_SRC_DIR)/pre_proc.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/pre_proc.cpp + +prm2bits.lo: $(ENC_SRC_DIR)/prm2bits.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT prm2bits.lo -MD -MP -MF $(DEPDIR)/prm2bits.Tpo -c -o prm2bits.lo `test -f '$(ENC_SRC_DIR)/prm2bits.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/prm2bits.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/prm2bits.Tpo $(DEPDIR)/prm2bits.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/prm2bits.cpp' object='prm2bits.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o prm2bits.lo `test -f '$(ENC_SRC_DIR)/prm2bits.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/prm2bits.cpp + +qgain475.lo: $(ENC_SRC_DIR)/qgain475.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT qgain475.lo -MD -MP -MF $(DEPDIR)/qgain475.Tpo -c -o qgain475.lo `test -f '$(ENC_SRC_DIR)/qgain475.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/qgain475.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qgain475.Tpo $(DEPDIR)/qgain475.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/qgain475.cpp' object='qgain475.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o qgain475.lo `test -f '$(ENC_SRC_DIR)/qgain475.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/qgain475.cpp + +qgain795.lo: $(ENC_SRC_DIR)/qgain795.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT qgain795.lo -MD -MP -MF $(DEPDIR)/qgain795.Tpo -c -o qgain795.lo `test -f '$(ENC_SRC_DIR)/qgain795.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/qgain795.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qgain795.Tpo $(DEPDIR)/qgain795.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/qgain795.cpp' object='qgain795.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o qgain795.lo `test -f '$(ENC_SRC_DIR)/qgain795.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/qgain795.cpp + +q_gain_c.lo: $(ENC_SRC_DIR)/q_gain_c.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT q_gain_c.lo -MD -MP -MF $(DEPDIR)/q_gain_c.Tpo -c -o q_gain_c.lo `test -f '$(ENC_SRC_DIR)/q_gain_c.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/q_gain_c.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/q_gain_c.Tpo $(DEPDIR)/q_gain_c.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/q_gain_c.cpp' object='q_gain_c.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o q_gain_c.lo `test -f '$(ENC_SRC_DIR)/q_gain_c.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/q_gain_c.cpp + +q_gain_p.lo: $(ENC_SRC_DIR)/q_gain_p.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT q_gain_p.lo -MD -MP -MF $(DEPDIR)/q_gain_p.Tpo -c -o q_gain_p.lo `test -f '$(ENC_SRC_DIR)/q_gain_p.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/q_gain_p.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/q_gain_p.Tpo $(DEPDIR)/q_gain_p.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/q_gain_p.cpp' object='q_gain_p.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o q_gain_p.lo `test -f '$(ENC_SRC_DIR)/q_gain_p.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/q_gain_p.cpp + +qua_gain.lo: $(ENC_SRC_DIR)/qua_gain.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT qua_gain.lo -MD -MP -MF $(DEPDIR)/qua_gain.Tpo -c -o qua_gain.lo `test -f '$(ENC_SRC_DIR)/qua_gain.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/qua_gain.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qua_gain.Tpo $(DEPDIR)/qua_gain.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/qua_gain.cpp' object='qua_gain.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o qua_gain.lo `test -f '$(ENC_SRC_DIR)/qua_gain.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/qua_gain.cpp + +s10_8pf.lo: $(ENC_SRC_DIR)/s10_8pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT s10_8pf.lo -MD -MP -MF $(DEPDIR)/s10_8pf.Tpo -c -o s10_8pf.lo `test -f '$(ENC_SRC_DIR)/s10_8pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/s10_8pf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/s10_8pf.Tpo $(DEPDIR)/s10_8pf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/s10_8pf.cpp' object='s10_8pf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o s10_8pf.lo `test -f '$(ENC_SRC_DIR)/s10_8pf.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/s10_8pf.cpp + +set_sign.lo: $(ENC_SRC_DIR)/set_sign.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT set_sign.lo -MD -MP -MF $(DEPDIR)/set_sign.Tpo -c -o set_sign.lo `test -f '$(ENC_SRC_DIR)/set_sign.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/set_sign.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/set_sign.Tpo $(DEPDIR)/set_sign.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/set_sign.cpp' object='set_sign.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o set_sign.lo `test -f '$(ENC_SRC_DIR)/set_sign.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/set_sign.cpp + +sid_sync.lo: $(ENC_SRC_DIR)/sid_sync.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sid_sync.lo -MD -MP -MF $(DEPDIR)/sid_sync.Tpo -c -o sid_sync.lo `test -f '$(ENC_SRC_DIR)/sid_sync.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/sid_sync.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sid_sync.Tpo $(DEPDIR)/sid_sync.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/sid_sync.cpp' object='sid_sync.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sid_sync.lo `test -f '$(ENC_SRC_DIR)/sid_sync.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/sid_sync.cpp + +sp_enc.lo: $(ENC_SRC_DIR)/sp_enc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sp_enc.lo -MD -MP -MF $(DEPDIR)/sp_enc.Tpo -c -o sp_enc.lo `test -f '$(ENC_SRC_DIR)/sp_enc.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/sp_enc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sp_enc.Tpo $(DEPDIR)/sp_enc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/sp_enc.cpp' object='sp_enc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sp_enc.lo `test -f '$(ENC_SRC_DIR)/sp_enc.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/sp_enc.cpp + +spreproc.lo: $(ENC_SRC_DIR)/spreproc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT spreproc.lo -MD -MP -MF $(DEPDIR)/spreproc.Tpo -c -o spreproc.lo `test -f '$(ENC_SRC_DIR)/spreproc.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/spreproc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/spreproc.Tpo $(DEPDIR)/spreproc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/spreproc.cpp' object='spreproc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o spreproc.lo `test -f '$(ENC_SRC_DIR)/spreproc.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/spreproc.cpp + +spstproc.lo: $(ENC_SRC_DIR)/spstproc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT spstproc.lo -MD -MP -MF $(DEPDIR)/spstproc.Tpo -c -o spstproc.lo `test -f '$(ENC_SRC_DIR)/spstproc.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/spstproc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/spstproc.Tpo $(DEPDIR)/spstproc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/spstproc.cpp' object='spstproc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o spstproc.lo `test -f '$(ENC_SRC_DIR)/spstproc.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/spstproc.cpp + +ton_stab.lo: $(ENC_SRC_DIR)/ton_stab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ton_stab.lo -MD -MP -MF $(DEPDIR)/ton_stab.Tpo -c -o ton_stab.lo `test -f '$(ENC_SRC_DIR)/ton_stab.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/ton_stab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ton_stab.Tpo $(DEPDIR)/ton_stab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/ton_stab.cpp' object='ton_stab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ton_stab.lo `test -f '$(ENC_SRC_DIR)/ton_stab.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/ton_stab.cpp + +vad1.lo: $(ENC_SRC_DIR)/vad1.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vad1.lo -MD -MP -MF $(DEPDIR)/vad1.Tpo -c -o vad1.lo `test -f '$(ENC_SRC_DIR)/vad1.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/vad1.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vad1.Tpo $(DEPDIR)/vad1.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(ENC_SRC_DIR)/vad1.cpp' object='vad1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vad1.lo `test -f '$(ENC_SRC_DIR)/vad1.cpp' || echo '$(srcdir)/'`$(ENC_SRC_DIR)/vad1.cpp + +add.lo: $(COMMON_SRC_DIR)/add.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT add.lo -MD -MP -MF $(DEPDIR)/add.Tpo -c -o add.lo `test -f '$(COMMON_SRC_DIR)/add.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/add.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/add.Tpo $(DEPDIR)/add.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/add.cpp' object='add.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o add.lo `test -f '$(COMMON_SRC_DIR)/add.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/add.cpp + +az_lsp.lo: $(COMMON_SRC_DIR)/az_lsp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT az_lsp.lo -MD -MP -MF $(DEPDIR)/az_lsp.Tpo -c -o az_lsp.lo `test -f '$(COMMON_SRC_DIR)/az_lsp.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/az_lsp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/az_lsp.Tpo $(DEPDIR)/az_lsp.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/az_lsp.cpp' object='az_lsp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o az_lsp.lo `test -f '$(COMMON_SRC_DIR)/az_lsp.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/az_lsp.cpp + +bitno_tab.lo: $(COMMON_SRC_DIR)/bitno_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT bitno_tab.lo -MD -MP -MF $(DEPDIR)/bitno_tab.Tpo -c -o bitno_tab.lo `test -f '$(COMMON_SRC_DIR)/bitno_tab.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/bitno_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bitno_tab.Tpo $(DEPDIR)/bitno_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/bitno_tab.cpp' object='bitno_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bitno_tab.lo `test -f '$(COMMON_SRC_DIR)/bitno_tab.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/bitno_tab.cpp + +bitreorder_tab.lo: $(COMMON_SRC_DIR)/bitreorder_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT bitreorder_tab.lo -MD -MP -MF $(DEPDIR)/bitreorder_tab.Tpo -c -o bitreorder_tab.lo `test -f '$(COMMON_SRC_DIR)/bitreorder_tab.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/bitreorder_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bitreorder_tab.Tpo $(DEPDIR)/bitreorder_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/bitreorder_tab.cpp' object='bitreorder_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bitreorder_tab.lo `test -f '$(COMMON_SRC_DIR)/bitreorder_tab.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/bitreorder_tab.cpp + +c2_9pf_tab.lo: $(COMMON_SRC_DIR)/c2_9pf_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT c2_9pf_tab.lo -MD -MP -MF $(DEPDIR)/c2_9pf_tab.Tpo -c -o c2_9pf_tab.lo `test -f '$(COMMON_SRC_DIR)/c2_9pf_tab.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/c2_9pf_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/c2_9pf_tab.Tpo $(DEPDIR)/c2_9pf_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/c2_9pf_tab.cpp' object='c2_9pf_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o c2_9pf_tab.lo `test -f '$(COMMON_SRC_DIR)/c2_9pf_tab.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/c2_9pf_tab.cpp + +div_s.lo: $(COMMON_SRC_DIR)/div_s.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT div_s.lo -MD -MP -MF $(DEPDIR)/div_s.Tpo -c -o div_s.lo `test -f '$(COMMON_SRC_DIR)/div_s.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/div_s.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/div_s.Tpo $(DEPDIR)/div_s.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/div_s.cpp' object='div_s.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o div_s.lo `test -f '$(COMMON_SRC_DIR)/div_s.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/div_s.cpp + +extract_h.lo: $(COMMON_SRC_DIR)/extract_h.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extract_h.lo -MD -MP -MF $(DEPDIR)/extract_h.Tpo -c -o extract_h.lo `test -f '$(COMMON_SRC_DIR)/extract_h.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/extract_h.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_h.Tpo $(DEPDIR)/extract_h.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/extract_h.cpp' object='extract_h.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o extract_h.lo `test -f '$(COMMON_SRC_DIR)/extract_h.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/extract_h.cpp + +extract_l.lo: $(COMMON_SRC_DIR)/extract_l.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extract_l.lo -MD -MP -MF $(DEPDIR)/extract_l.Tpo -c -o extract_l.lo `test -f '$(COMMON_SRC_DIR)/extract_l.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/extract_l.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_l.Tpo $(DEPDIR)/extract_l.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/extract_l.cpp' object='extract_l.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o extract_l.lo `test -f '$(COMMON_SRC_DIR)/extract_l.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/extract_l.cpp + +gains_tbl.lo: $(COMMON_SRC_DIR)/gains_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gains_tbl.lo -MD -MP -MF $(DEPDIR)/gains_tbl.Tpo -c -o gains_tbl.lo `test -f '$(COMMON_SRC_DIR)/gains_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/gains_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gains_tbl.Tpo $(DEPDIR)/gains_tbl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/gains_tbl.cpp' object='gains_tbl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gains_tbl.lo `test -f '$(COMMON_SRC_DIR)/gains_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/gains_tbl.cpp + +gc_pred.lo: $(COMMON_SRC_DIR)/gc_pred.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gc_pred.lo -MD -MP -MF $(DEPDIR)/gc_pred.Tpo -c -o gc_pred.lo `test -f '$(COMMON_SRC_DIR)/gc_pred.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/gc_pred.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gc_pred.Tpo $(DEPDIR)/gc_pred.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/gc_pred.cpp' object='gc_pred.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gc_pred.lo `test -f '$(COMMON_SRC_DIR)/gc_pred.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/gc_pred.cpp + +get_const_tbls.lo: $(COMMON_SRC_DIR)/get_const_tbls.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT get_const_tbls.lo -MD -MP -MF $(DEPDIR)/get_const_tbls.Tpo -c -o get_const_tbls.lo `test -f '$(COMMON_SRC_DIR)/get_const_tbls.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/get_const_tbls.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/get_const_tbls.Tpo $(DEPDIR)/get_const_tbls.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/get_const_tbls.cpp' object='get_const_tbls.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o get_const_tbls.lo `test -f '$(COMMON_SRC_DIR)/get_const_tbls.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/get_const_tbls.cpp + +gmed_n.lo: $(COMMON_SRC_DIR)/gmed_n.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gmed_n.lo -MD -MP -MF $(DEPDIR)/gmed_n.Tpo -c -o gmed_n.lo `test -f '$(COMMON_SRC_DIR)/gmed_n.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/gmed_n.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gmed_n.Tpo $(DEPDIR)/gmed_n.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/gmed_n.cpp' object='gmed_n.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gmed_n.lo `test -f '$(COMMON_SRC_DIR)/gmed_n.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/gmed_n.cpp + +gray_tbl.lo: $(COMMON_SRC_DIR)/gray_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gray_tbl.lo -MD -MP -MF $(DEPDIR)/gray_tbl.Tpo -c -o gray_tbl.lo `test -f '$(COMMON_SRC_DIR)/gray_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/gray_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gray_tbl.Tpo $(DEPDIR)/gray_tbl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/gray_tbl.cpp' object='gray_tbl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gray_tbl.lo `test -f '$(COMMON_SRC_DIR)/gray_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/gray_tbl.cpp + +grid_tbl.lo: $(COMMON_SRC_DIR)/grid_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT grid_tbl.lo -MD -MP -MF $(DEPDIR)/grid_tbl.Tpo -c -o grid_tbl.lo `test -f '$(COMMON_SRC_DIR)/grid_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/grid_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/grid_tbl.Tpo $(DEPDIR)/grid_tbl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/grid_tbl.cpp' object='grid_tbl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o grid_tbl.lo `test -f '$(COMMON_SRC_DIR)/grid_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/grid_tbl.cpp + +int_lpc.lo: $(COMMON_SRC_DIR)/int_lpc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT int_lpc.lo -MD -MP -MF $(DEPDIR)/int_lpc.Tpo -c -o int_lpc.lo `test -f '$(COMMON_SRC_DIR)/int_lpc.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/int_lpc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/int_lpc.Tpo $(DEPDIR)/int_lpc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/int_lpc.cpp' object='int_lpc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o int_lpc.lo `test -f '$(COMMON_SRC_DIR)/int_lpc.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/int_lpc.cpp + +inv_sqrt.lo: $(COMMON_SRC_DIR)/inv_sqrt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT inv_sqrt.lo -MD -MP -MF $(DEPDIR)/inv_sqrt.Tpo -c -o inv_sqrt.lo `test -f '$(COMMON_SRC_DIR)/inv_sqrt.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/inv_sqrt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/inv_sqrt.Tpo $(DEPDIR)/inv_sqrt.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/inv_sqrt.cpp' object='inv_sqrt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o inv_sqrt.lo `test -f '$(COMMON_SRC_DIR)/inv_sqrt.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/inv_sqrt.cpp + +inv_sqrt_tbl.lo: $(COMMON_SRC_DIR)/inv_sqrt_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT inv_sqrt_tbl.lo -MD -MP -MF $(DEPDIR)/inv_sqrt_tbl.Tpo -c -o inv_sqrt_tbl.lo `test -f '$(COMMON_SRC_DIR)/inv_sqrt_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/inv_sqrt_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/inv_sqrt_tbl.Tpo $(DEPDIR)/inv_sqrt_tbl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/inv_sqrt_tbl.cpp' object='inv_sqrt_tbl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o inv_sqrt_tbl.lo `test -f '$(COMMON_SRC_DIR)/inv_sqrt_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/inv_sqrt_tbl.cpp + +l_deposit_h.lo: $(COMMON_SRC_DIR)/l_deposit_h.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT l_deposit_h.lo -MD -MP -MF $(DEPDIR)/l_deposit_h.Tpo -c -o l_deposit_h.lo `test -f '$(COMMON_SRC_DIR)/l_deposit_h.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/l_deposit_h.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/l_deposit_h.Tpo $(DEPDIR)/l_deposit_h.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/l_deposit_h.cpp' object='l_deposit_h.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o l_deposit_h.lo `test -f '$(COMMON_SRC_DIR)/l_deposit_h.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/l_deposit_h.cpp + +l_deposit_l.lo: $(COMMON_SRC_DIR)/l_deposit_l.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT l_deposit_l.lo -MD -MP -MF $(DEPDIR)/l_deposit_l.Tpo -c -o l_deposit_l.lo `test -f '$(COMMON_SRC_DIR)/l_deposit_l.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/l_deposit_l.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/l_deposit_l.Tpo $(DEPDIR)/l_deposit_l.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/l_deposit_l.cpp' object='l_deposit_l.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o l_deposit_l.lo `test -f '$(COMMON_SRC_DIR)/l_deposit_l.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/l_deposit_l.cpp + +log2.lo: $(COMMON_SRC_DIR)/log2.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT log2.lo -MD -MP -MF $(DEPDIR)/log2.Tpo -c -o log2.lo `test -f '$(COMMON_SRC_DIR)/log2.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/log2.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/log2.Tpo $(DEPDIR)/log2.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/log2.cpp' object='log2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o log2.lo `test -f '$(COMMON_SRC_DIR)/log2.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/log2.cpp + +log2_norm.lo: $(COMMON_SRC_DIR)/log2_norm.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT log2_norm.lo -MD -MP -MF $(DEPDIR)/log2_norm.Tpo -c -o log2_norm.lo `test -f '$(COMMON_SRC_DIR)/log2_norm.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/log2_norm.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/log2_norm.Tpo $(DEPDIR)/log2_norm.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/log2_norm.cpp' object='log2_norm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o log2_norm.lo `test -f '$(COMMON_SRC_DIR)/log2_norm.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/log2_norm.cpp + +log2_tbl.lo: $(COMMON_SRC_DIR)/log2_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT log2_tbl.lo -MD -MP -MF $(DEPDIR)/log2_tbl.Tpo -c -o log2_tbl.lo `test -f '$(COMMON_SRC_DIR)/log2_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/log2_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/log2_tbl.Tpo $(DEPDIR)/log2_tbl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/log2_tbl.cpp' object='log2_tbl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o log2_tbl.lo `test -f '$(COMMON_SRC_DIR)/log2_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/log2_tbl.cpp + +lsfwt.lo: $(COMMON_SRC_DIR)/lsfwt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lsfwt.lo -MD -MP -MF $(DEPDIR)/lsfwt.Tpo -c -o lsfwt.lo `test -f '$(COMMON_SRC_DIR)/lsfwt.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/lsfwt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lsfwt.Tpo $(DEPDIR)/lsfwt.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/lsfwt.cpp' object='lsfwt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lsfwt.lo `test -f '$(COMMON_SRC_DIR)/lsfwt.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/lsfwt.cpp + +l_shr_r.lo: $(COMMON_SRC_DIR)/l_shr_r.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT l_shr_r.lo -MD -MP -MF $(DEPDIR)/l_shr_r.Tpo -c -o l_shr_r.lo `test -f '$(COMMON_SRC_DIR)/l_shr_r.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/l_shr_r.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/l_shr_r.Tpo $(DEPDIR)/l_shr_r.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/l_shr_r.cpp' object='l_shr_r.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o l_shr_r.lo `test -f '$(COMMON_SRC_DIR)/l_shr_r.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/l_shr_r.cpp + +lsp_az.lo: $(COMMON_SRC_DIR)/lsp_az.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lsp_az.lo -MD -MP -MF $(DEPDIR)/lsp_az.Tpo -c -o lsp_az.lo `test -f '$(COMMON_SRC_DIR)/lsp_az.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/lsp_az.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lsp_az.Tpo $(DEPDIR)/lsp_az.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/lsp_az.cpp' object='lsp_az.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lsp_az.lo `test -f '$(COMMON_SRC_DIR)/lsp_az.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/lsp_az.cpp + +lsp.lo: $(COMMON_SRC_DIR)/lsp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lsp.lo -MD -MP -MF $(DEPDIR)/lsp.Tpo -c -o lsp.lo `test -f '$(COMMON_SRC_DIR)/lsp.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/lsp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lsp.Tpo $(DEPDIR)/lsp.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/lsp.cpp' object='lsp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lsp.lo `test -f '$(COMMON_SRC_DIR)/lsp.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/lsp.cpp + +lsp_lsf.lo: $(COMMON_SRC_DIR)/lsp_lsf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lsp_lsf.lo -MD -MP -MF $(DEPDIR)/lsp_lsf.Tpo -c -o lsp_lsf.lo `test -f '$(COMMON_SRC_DIR)/lsp_lsf.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/lsp_lsf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lsp_lsf.Tpo $(DEPDIR)/lsp_lsf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/lsp_lsf.cpp' object='lsp_lsf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lsp_lsf.lo `test -f '$(COMMON_SRC_DIR)/lsp_lsf.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/lsp_lsf.cpp + +lsp_lsf_tbl.lo: $(COMMON_SRC_DIR)/lsp_lsf_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lsp_lsf_tbl.lo -MD -MP -MF $(DEPDIR)/lsp_lsf_tbl.Tpo -c -o lsp_lsf_tbl.lo `test -f '$(COMMON_SRC_DIR)/lsp_lsf_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/lsp_lsf_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lsp_lsf_tbl.Tpo $(DEPDIR)/lsp_lsf_tbl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/lsp_lsf_tbl.cpp' object='lsp_lsf_tbl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lsp_lsf_tbl.lo `test -f '$(COMMON_SRC_DIR)/lsp_lsf_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/lsp_lsf_tbl.cpp + +lsp_tab.lo: $(COMMON_SRC_DIR)/lsp_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lsp_tab.lo -MD -MP -MF $(DEPDIR)/lsp_tab.Tpo -c -o lsp_tab.lo `test -f '$(COMMON_SRC_DIR)/lsp_tab.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/lsp_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lsp_tab.Tpo $(DEPDIR)/lsp_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/lsp_tab.cpp' object='lsp_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lsp_tab.lo `test -f '$(COMMON_SRC_DIR)/lsp_tab.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/lsp_tab.cpp + +mult_r.lo: $(COMMON_SRC_DIR)/mult_r.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT mult_r.lo -MD -MP -MF $(DEPDIR)/mult_r.Tpo -c -o mult_r.lo `test -f '$(COMMON_SRC_DIR)/mult_r.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/mult_r.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mult_r.Tpo $(DEPDIR)/mult_r.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/mult_r.cpp' object='mult_r.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o mult_r.lo `test -f '$(COMMON_SRC_DIR)/mult_r.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/mult_r.cpp + +negate.lo: $(COMMON_SRC_DIR)/negate.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT negate.lo -MD -MP -MF $(DEPDIR)/negate.Tpo -c -o negate.lo `test -f '$(COMMON_SRC_DIR)/negate.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/negate.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/negate.Tpo $(DEPDIR)/negate.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/negate.cpp' object='negate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o negate.lo `test -f '$(COMMON_SRC_DIR)/negate.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/negate.cpp + +norm_l.lo: $(COMMON_SRC_DIR)/norm_l.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT norm_l.lo -MD -MP -MF $(DEPDIR)/norm_l.Tpo -c -o norm_l.lo `test -f '$(COMMON_SRC_DIR)/norm_l.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/norm_l.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/norm_l.Tpo $(DEPDIR)/norm_l.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/norm_l.cpp' object='norm_l.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o norm_l.lo `test -f '$(COMMON_SRC_DIR)/norm_l.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/norm_l.cpp + +norm_s.lo: $(COMMON_SRC_DIR)/norm_s.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT norm_s.lo -MD -MP -MF $(DEPDIR)/norm_s.Tpo -c -o norm_s.lo `test -f '$(COMMON_SRC_DIR)/norm_s.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/norm_s.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/norm_s.Tpo $(DEPDIR)/norm_s.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/norm_s.cpp' object='norm_s.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o norm_s.lo `test -f '$(COMMON_SRC_DIR)/norm_s.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/norm_s.cpp + +overflow_tbl.lo: $(COMMON_SRC_DIR)/overflow_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT overflow_tbl.lo -MD -MP -MF $(DEPDIR)/overflow_tbl.Tpo -c -o overflow_tbl.lo `test -f '$(COMMON_SRC_DIR)/overflow_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/overflow_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/overflow_tbl.Tpo $(DEPDIR)/overflow_tbl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/overflow_tbl.cpp' object='overflow_tbl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o overflow_tbl.lo `test -f '$(COMMON_SRC_DIR)/overflow_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/overflow_tbl.cpp + +ph_disp_tab.lo: $(COMMON_SRC_DIR)/ph_disp_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ph_disp_tab.lo -MD -MP -MF $(DEPDIR)/ph_disp_tab.Tpo -c -o ph_disp_tab.lo `test -f '$(COMMON_SRC_DIR)/ph_disp_tab.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/ph_disp_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ph_disp_tab.Tpo $(DEPDIR)/ph_disp_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/ph_disp_tab.cpp' object='ph_disp_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ph_disp_tab.lo `test -f '$(COMMON_SRC_DIR)/ph_disp_tab.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/ph_disp_tab.cpp + +pow2.lo: $(COMMON_SRC_DIR)/pow2.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pow2.lo -MD -MP -MF $(DEPDIR)/pow2.Tpo -c -o pow2.lo `test -f '$(COMMON_SRC_DIR)/pow2.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/pow2.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pow2.Tpo $(DEPDIR)/pow2.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/pow2.cpp' object='pow2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pow2.lo `test -f '$(COMMON_SRC_DIR)/pow2.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/pow2.cpp + +pow2_tbl.lo: $(COMMON_SRC_DIR)/pow2_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pow2_tbl.lo -MD -MP -MF $(DEPDIR)/pow2_tbl.Tpo -c -o pow2_tbl.lo `test -f '$(COMMON_SRC_DIR)/pow2_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/pow2_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pow2_tbl.Tpo $(DEPDIR)/pow2_tbl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/pow2_tbl.cpp' object='pow2_tbl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pow2_tbl.lo `test -f '$(COMMON_SRC_DIR)/pow2_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/pow2_tbl.cpp + +pred_lt.lo: $(COMMON_SRC_DIR)/pred_lt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pred_lt.lo -MD -MP -MF $(DEPDIR)/pred_lt.Tpo -c -o pred_lt.lo `test -f '$(COMMON_SRC_DIR)/pred_lt.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/pred_lt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pred_lt.Tpo $(DEPDIR)/pred_lt.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/pred_lt.cpp' object='pred_lt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pred_lt.lo `test -f '$(COMMON_SRC_DIR)/pred_lt.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/pred_lt.cpp + +q_plsf_3.lo: $(COMMON_SRC_DIR)/q_plsf_3.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT q_plsf_3.lo -MD -MP -MF $(DEPDIR)/q_plsf_3.Tpo -c -o q_plsf_3.lo `test -f '$(COMMON_SRC_DIR)/q_plsf_3.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/q_plsf_3.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/q_plsf_3.Tpo $(DEPDIR)/q_plsf_3.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/q_plsf_3.cpp' object='q_plsf_3.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o q_plsf_3.lo `test -f '$(COMMON_SRC_DIR)/q_plsf_3.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/q_plsf_3.cpp + +q_plsf_3_tbl.lo: $(COMMON_SRC_DIR)/q_plsf_3_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT q_plsf_3_tbl.lo -MD -MP -MF $(DEPDIR)/q_plsf_3_tbl.Tpo -c -o q_plsf_3_tbl.lo `test -f '$(COMMON_SRC_DIR)/q_plsf_3_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/q_plsf_3_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/q_plsf_3_tbl.Tpo $(DEPDIR)/q_plsf_3_tbl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/q_plsf_3_tbl.cpp' object='q_plsf_3_tbl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o q_plsf_3_tbl.lo `test -f '$(COMMON_SRC_DIR)/q_plsf_3_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/q_plsf_3_tbl.cpp + +q_plsf_5.lo: $(COMMON_SRC_DIR)/q_plsf_5.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT q_plsf_5.lo -MD -MP -MF $(DEPDIR)/q_plsf_5.Tpo -c -o q_plsf_5.lo `test -f '$(COMMON_SRC_DIR)/q_plsf_5.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/q_plsf_5.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/q_plsf_5.Tpo $(DEPDIR)/q_plsf_5.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/q_plsf_5.cpp' object='q_plsf_5.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o q_plsf_5.lo `test -f '$(COMMON_SRC_DIR)/q_plsf_5.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/q_plsf_5.cpp + +q_plsf_5_tbl.lo: $(COMMON_SRC_DIR)/q_plsf_5_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT q_plsf_5_tbl.lo -MD -MP -MF $(DEPDIR)/q_plsf_5_tbl.Tpo -c -o q_plsf_5_tbl.lo `test -f '$(COMMON_SRC_DIR)/q_plsf_5_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/q_plsf_5_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/q_plsf_5_tbl.Tpo $(DEPDIR)/q_plsf_5_tbl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/q_plsf_5_tbl.cpp' object='q_plsf_5_tbl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o q_plsf_5_tbl.lo `test -f '$(COMMON_SRC_DIR)/q_plsf_5_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/q_plsf_5_tbl.cpp + +q_plsf.lo: $(COMMON_SRC_DIR)/q_plsf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT q_plsf.lo -MD -MP -MF $(DEPDIR)/q_plsf.Tpo -c -o q_plsf.lo `test -f '$(COMMON_SRC_DIR)/q_plsf.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/q_plsf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/q_plsf.Tpo $(DEPDIR)/q_plsf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/q_plsf.cpp' object='q_plsf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o q_plsf.lo `test -f '$(COMMON_SRC_DIR)/q_plsf.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/q_plsf.cpp + +qua_gain_tbl.lo: $(COMMON_SRC_DIR)/qua_gain_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT qua_gain_tbl.lo -MD -MP -MF $(DEPDIR)/qua_gain_tbl.Tpo -c -o qua_gain_tbl.lo `test -f '$(COMMON_SRC_DIR)/qua_gain_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/qua_gain_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qua_gain_tbl.Tpo $(DEPDIR)/qua_gain_tbl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/qua_gain_tbl.cpp' object='qua_gain_tbl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o qua_gain_tbl.lo `test -f '$(COMMON_SRC_DIR)/qua_gain_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/qua_gain_tbl.cpp + +reorder.lo: $(COMMON_SRC_DIR)/reorder.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT reorder.lo -MD -MP -MF $(DEPDIR)/reorder.Tpo -c -o reorder.lo `test -f '$(COMMON_SRC_DIR)/reorder.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/reorder.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/reorder.Tpo $(DEPDIR)/reorder.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/reorder.cpp' object='reorder.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o reorder.lo `test -f '$(COMMON_SRC_DIR)/reorder.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/reorder.cpp + +residu.lo: $(COMMON_SRC_DIR)/residu.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT residu.lo -MD -MP -MF $(DEPDIR)/residu.Tpo -c -o residu.lo `test -f '$(COMMON_SRC_DIR)/residu.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/residu.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/residu.Tpo $(DEPDIR)/residu.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/residu.cpp' object='residu.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o residu.lo `test -f '$(COMMON_SRC_DIR)/residu.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/residu.cpp + +round.lo: $(COMMON_SRC_DIR)/round.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT round.lo -MD -MP -MF $(DEPDIR)/round.Tpo -c -o round.lo `test -f '$(COMMON_SRC_DIR)/round.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/round.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/round.Tpo $(DEPDIR)/round.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/round.cpp' object='round.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o round.lo `test -f '$(COMMON_SRC_DIR)/round.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/round.cpp + +set_zero.lo: $(COMMON_SRC_DIR)/set_zero.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT set_zero.lo -MD -MP -MF $(DEPDIR)/set_zero.Tpo -c -o set_zero.lo `test -f '$(COMMON_SRC_DIR)/set_zero.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/set_zero.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/set_zero.Tpo $(DEPDIR)/set_zero.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/set_zero.cpp' object='set_zero.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o set_zero.lo `test -f '$(COMMON_SRC_DIR)/set_zero.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/set_zero.cpp + +shr.lo: $(COMMON_SRC_DIR)/shr.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT shr.lo -MD -MP -MF $(DEPDIR)/shr.Tpo -c -o shr.lo `test -f '$(COMMON_SRC_DIR)/shr.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/shr.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/shr.Tpo $(DEPDIR)/shr.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/shr.cpp' object='shr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o shr.lo `test -f '$(COMMON_SRC_DIR)/shr.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/shr.cpp + +shr_r.lo: $(COMMON_SRC_DIR)/shr_r.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT shr_r.lo -MD -MP -MF $(DEPDIR)/shr_r.Tpo -c -o shr_r.lo `test -f '$(COMMON_SRC_DIR)/shr_r.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/shr_r.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/shr_r.Tpo $(DEPDIR)/shr_r.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/shr_r.cpp' object='shr_r.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o shr_r.lo `test -f '$(COMMON_SRC_DIR)/shr_r.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/shr_r.cpp + +sqrt_l.lo: $(COMMON_SRC_DIR)/sqrt_l.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sqrt_l.lo -MD -MP -MF $(DEPDIR)/sqrt_l.Tpo -c -o sqrt_l.lo `test -f '$(COMMON_SRC_DIR)/sqrt_l.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/sqrt_l.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sqrt_l.Tpo $(DEPDIR)/sqrt_l.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/sqrt_l.cpp' object='sqrt_l.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sqrt_l.lo `test -f '$(COMMON_SRC_DIR)/sqrt_l.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/sqrt_l.cpp + +sqrt_l_tbl.lo: $(COMMON_SRC_DIR)/sqrt_l_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sqrt_l_tbl.lo -MD -MP -MF $(DEPDIR)/sqrt_l_tbl.Tpo -c -o sqrt_l_tbl.lo `test -f '$(COMMON_SRC_DIR)/sqrt_l_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/sqrt_l_tbl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sqrt_l_tbl.Tpo $(DEPDIR)/sqrt_l_tbl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/sqrt_l_tbl.cpp' object='sqrt_l_tbl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sqrt_l_tbl.lo `test -f '$(COMMON_SRC_DIR)/sqrt_l_tbl.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/sqrt_l_tbl.cpp + +sub.lo: $(COMMON_SRC_DIR)/sub.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sub.lo -MD -MP -MF $(DEPDIR)/sub.Tpo -c -o sub.lo `test -f '$(COMMON_SRC_DIR)/sub.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/sub.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sub.Tpo $(DEPDIR)/sub.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/sub.cpp' object='sub.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sub.lo `test -f '$(COMMON_SRC_DIR)/sub.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/sub.cpp + +syn_filt.lo: $(COMMON_SRC_DIR)/syn_filt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT syn_filt.lo -MD -MP -MF $(DEPDIR)/syn_filt.Tpo -c -o syn_filt.lo `test -f '$(COMMON_SRC_DIR)/syn_filt.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/syn_filt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/syn_filt.Tpo $(DEPDIR)/syn_filt.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/syn_filt.cpp' object='syn_filt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o syn_filt.lo `test -f '$(COMMON_SRC_DIR)/syn_filt.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/syn_filt.cpp + +weight_a.lo: $(COMMON_SRC_DIR)/weight_a.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT weight_a.lo -MD -MP -MF $(DEPDIR)/weight_a.Tpo -c -o weight_a.lo `test -f '$(COMMON_SRC_DIR)/weight_a.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/weight_a.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/weight_a.Tpo $(DEPDIR)/weight_a.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/weight_a.cpp' object='weight_a.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o weight_a.lo `test -f '$(COMMON_SRC_DIR)/weight_a.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/weight_a.cpp + +window_tab.lo: $(COMMON_SRC_DIR)/window_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT window_tab.lo -MD -MP -MF $(DEPDIR)/window_tab.Tpo -c -o window_tab.lo `test -f '$(COMMON_SRC_DIR)/window_tab.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/window_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/window_tab.Tpo $(DEPDIR)/window_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(COMMON_SRC_DIR)/window_tab.cpp' object='window_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o window_tab.lo `test -f '$(COMMON_SRC_DIR)/window_tab.cpp' || echo '$(srcdir)/'`$(COMMON_SRC_DIR)/window_tab.cpp + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) +install-amrnbincludeHEADERS: $(amrnbinclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(amrnbincludedir)" || $(MKDIR_P) "$(DESTDIR)$(amrnbincludedir)" + @list='$(amrnbinclude_HEADERS)'; test -n "$(amrnbincludedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(amrnbincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(amrnbincludedir)" || exit $$?; \ + done + +uninstall-amrnbincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(amrnbinclude_HEADERS)'; test -n "$(amrnbincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(amrnbincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(amrnbincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-amrnbincludeHEADERS install-pkgconfigDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-amrnbincludeHEADERS uninstall-libLTLIBRARIES \ + uninstall-pkgconfigDATA + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-amrnbincludeHEADERS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-amrnbincludeHEADERS uninstall-libLTLIBRARIES \ + uninstall-pkgconfigDATA + +@COMPILE_AS_C_TRUE@ # Mention a dummy pure C file to trigger generation of the $(LINK) variable + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/opencore-amr/amrnb/interf_dec.h b/src/libs/opencore-amr/amrnb/interf_dec.h new file mode 100644 index 00000000..ae2c98ac --- /dev/null +++ b/src/libs/opencore-amr/amrnb/interf_dec.h @@ -0,0 +1,38 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#ifndef OPENCORE_AMRNB_INTERF_DEC_H +#define OPENCORE_AMRNB_INTERF_DEC_H + +#ifdef __cplusplus +extern "C" { +#endif + +void* Decoder_Interface_init(void); +//void Decoder_Interface_init(void* state); + +void Decoder_Interface_exit(void* state); +void Decoder_Interface_Decode(void* state, + const unsigned char* in, + short* out, int bfi); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/amrnb/interf_enc.h b/src/libs/opencore-amr/amrnb/interf_enc.h new file mode 100644 index 00000000..66b29631 --- /dev/null +++ b/src/libs/opencore-amr/amrnb/interf_enc.h @@ -0,0 +1,61 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#ifndef OPENCORE_AMRNB_INTERF_ENC_H +#define OPENCORE_AMRNB_INTERF_ENC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef AMRNB_WRAPPER_INTERNAL +/* Copied from enc/src/gsmamr_enc.h */ +enum Mode { + MR475 = 0,/* 4.75 kbps */ + MR515, /* 5.15 kbps */ + MR59, /* 5.90 kbps */ + MR67, /* 6.70 kbps */ + MR74, /* 7.40 kbps */ + MR795, /* 7.95 kbps */ + MR102, /* 10.2 kbps */ + MR122, /* 12.2 kbps */ + MRDTX, /* DTX */ + N_MODES /* Not Used */ +}; +#endif + +struct encoder_state { + void* encCtx; + void* pidSyncCtx; +}; + +void* Encoder_Interface_init(int dtx); + +//WORK +//void Encoder_Interface_init(void* state,int dtx); + +void Encoder_Interface_exit(void* state); +int Encoder_Interface_Encode(void* state, enum Mode mode, + const short* speech, + unsigned char* out, int forceSpeech); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/amrnb/opencore-amrnb.pc.in b/src/libs/opencore-amr/amrnb/opencore-amrnb.pc.in new file mode 100644 index 00000000..b199fcad --- /dev/null +++ b/src/libs/opencore-amr/amrnb/opencore-amrnb.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: OpenCORE AMR-NB +Description: Adaptive Multi-Rate speech codec library +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lopencore-amrnb +Cflags: -I${includedir} diff --git a/src/libs/opencore-amr/amrnb/opencore-amrnb.sym b/src/libs/opencore-amr/amrnb/opencore-amrnb.sym new file mode 100644 index 00000000..25bc1c72 --- /dev/null +++ b/src/libs/opencore-amr/amrnb/opencore-amrnb.sym @@ -0,0 +1,6 @@ +Decoder_Interface_init +Decoder_Interface_exit +Decoder_Interface_Decode +Encoder_Interface_init +Encoder_Interface_exit +Encoder_Interface_Encode diff --git a/src/libs/opencore-amr/amrnb/wrapper.cpp b/src/libs/opencore-amr/amrnb/wrapper.cpp new file mode 100644 index 00000000..92cdc674 --- /dev/null +++ b/src/libs/opencore-amr/amrnb/wrapper.cpp @@ -0,0 +1,105 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#define AMRNB_WRAPPER_INTERNAL +#include +#include +#include +#include "interf_dec.h" +#include "interf_enc.h" +#include + +#ifndef DISABLE_AMRNB_DECODER + + +//default +void* Decoder_Interface_init(void) { + void* ptr = NULL; + GSMInitDecode(&ptr, (int8*)"Decoder"); + return ptr; +} +/* +//fixed error +void Decoder_Interface_init(void* state) { + void* ptr = NULL; + GSMInitDecode(state, (int8*)"Decoder"); + return ptr; +} +*/ +void Decoder_Interface_exit(void* state) { + GSMDecodeFrameExit(&state); +} + +void Decoder_Interface_Decode(void* state, const unsigned char* in, short* out, int bfi) { + unsigned char type = (in[0] >> 3) & 0x0f; + in++; + AMRDecode(state, (enum Frame_Type_3GPP) type, (UWord8*) in, out, MIME_IETF); +} +#endif + +#ifndef DISABLE_AMRNB_ENCODER + + +void* Encoder_Interface_init(int dtx) { + struct encoder_state* state = (struct encoder_state*) malloc(sizeof(struct encoder_state)); + AMREncodeInit(&state->encCtx, &state->pidSyncCtx, dtx); + return state; +} + +/* +void Encoder_Interface_init(void * encInst,int dtx) { + //int dtx=1; + struct encoder_state* state = (struct encoder_state*)encInst;// malloc(sizeof(struct encoder_state)); + AMREncodeInit(&state->encCtx, &state->pidSyncCtx, dtx); + //return state; +} +*/ +void Encoder_Interface_exit(void* s) { + struct encoder_state* state = (struct encoder_state*) s; + AMREncodeExit(&state->encCtx, &state->pidSyncCtx); + free(state); +} + +int Encoder_Interface_Encode(void* s, enum Mode mode, + const short* speech, unsigned char* out, + int forceSpeech) { + struct encoder_state* state = (struct encoder_state*) s; + enum Frame_Type_3GPP frame_type = (enum Frame_Type_3GPP) mode; + + /** + Word16 AMREncode( + void *pEncState, void *pSidSyncState, + enum Mode 3gp_frame_type, + Word16 *pEncInput, + UWord8 *pEncOutput, + + enum Frame_Type_3GPP *p3gpp_frame_type, + Word16 output_format +) + */ + int ret = AMREncode(state->encCtx, state->pidSyncCtx, + mode, + (Word16*) speech, + out, + &frame_type, + AMR_TX_IETF); + out[0] |= 0x04; + return ret; +} +#endif + diff --git a/src/libs/opencore-amr/amrwb/Makefile.am b/src/libs/opencore-amr/amrwb/Makefile.am new file mode 100644 index 00000000..a6cc33c7 --- /dev/null +++ b/src/libs/opencore-amr/amrwb/Makefile.am @@ -0,0 +1,82 @@ +# Just set OC_BASE to the opencore root, or set AMR_BASE directly to +# a detached gsm_amr directory +OC_BASE = $(top_srcdir)/opencore +AMR_BASE = $(OC_BASE)/codecs_v2/audio/gsm_amr + +DEC_DIR = $(AMR_BASE)/amr_wb/dec +DEC_SRC_DIR = $(DEC_DIR)/src +OSCL = $(top_srcdir)/oscl + +AM_CFLAGS = -I$(OSCL) -I$(DEC_SRC_DIR) -I$(DEC_DIR)/include \ + -I$(AMR_BASE)/common/dec/include + +if GCC_ARMV5 + AM_CFLAGS += -DPV_CPU_ARCH_VERSION=5 -DPV_COMPILER=1 +endif + +if COMPILE_AS_C + AM_CFLAGS += -x c -std=c99 + libopencore_amrwb_la_LINK = $(LINK) $(libopencore_amrwb_la_LDFLAGS) + # Mention a dummy pure C file to trigger generation of the $(LINK) variable + nodist_EXTRA_libopencore_amrwb_la_SOURCES = dummy.c +else + libopencore_amrwb_la_LINK = $(CXXLINK) $(libopencore_amrwb_la_LDFLAGS) +endif + +AM_CXXFLAGS = $(AM_CFLAGS) + +amrwbincludedir = $(includedir)/opencore-amrwb +amrwbinclude_HEADERS = dec_if.h if_rom.h + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = opencore-amrwb.pc + +lib_LTLIBRARIES = libopencore-amrwb.la + +libopencore_amrwb_la_LDFLAGS = -version-info @OPENCORE_AMRWB_VERSION@ -no-undefined -export-symbols $(top_srcdir)/amrwb/opencore-amrwb.sym +EXTRA_DIST = $(top_srcdir)/amrwb/opencore-amrwb.sym + +# Our sources to include. There are certain sources we exclude and they are +# $(DEC_SRC_DIR)/decoder_amr_wb.cpp +libopencore_amrwb_la_SOURCES = \ + wrapper.cpp \ + $(DEC_SRC_DIR)/agc2_amr_wb.cpp \ + $(DEC_SRC_DIR)/band_pass_6k_7k.cpp \ + $(DEC_SRC_DIR)/dec_acelp_2p_in_64.cpp \ + $(DEC_SRC_DIR)/dec_acelp_4p_in_64.cpp \ + $(DEC_SRC_DIR)/dec_alg_codebook.cpp \ + $(DEC_SRC_DIR)/dec_gain2_amr_wb.cpp \ + $(DEC_SRC_DIR)/deemphasis_32.cpp \ + $(DEC_SRC_DIR)/dtx_decoder_amr_wb.cpp \ + $(DEC_SRC_DIR)/get_amr_wb_bits.cpp \ + $(DEC_SRC_DIR)/highpass_400hz_at_12k8.cpp \ + $(DEC_SRC_DIR)/highpass_50hz_at_12k8.cpp \ + $(DEC_SRC_DIR)/homing_amr_wb_dec.cpp \ + $(DEC_SRC_DIR)/interpolate_isp.cpp \ + $(DEC_SRC_DIR)/isf_extrapolation.cpp \ + $(DEC_SRC_DIR)/isp_az.cpp \ + $(DEC_SRC_DIR)/isp_isf.cpp \ + $(DEC_SRC_DIR)/lagconceal.cpp \ + $(DEC_SRC_DIR)/low_pass_filt_7k.cpp \ + $(DEC_SRC_DIR)/median5.cpp \ + $(DEC_SRC_DIR)/mime_io.cpp \ + $(DEC_SRC_DIR)/noise_gen_amrwb.cpp \ + $(DEC_SRC_DIR)/normalize_amr_wb.cpp \ + $(DEC_SRC_DIR)/oversamp_12k8_to_16k.cpp \ + $(DEC_SRC_DIR)/phase_dispersion.cpp \ + $(DEC_SRC_DIR)/pit_shrp.cpp \ + $(DEC_SRC_DIR)/pred_lt4.cpp \ + $(DEC_SRC_DIR)/preemph_amrwb_dec.cpp \ + $(DEC_SRC_DIR)/pvamrwbdecoder.cpp \ + $(DEC_SRC_DIR)/pvamrwb_math_op.cpp \ + $(DEC_SRC_DIR)/q_gain2_tab.cpp \ + $(DEC_SRC_DIR)/qisf_ns.cpp \ + $(DEC_SRC_DIR)/qisf_ns_tab.cpp \ + $(DEC_SRC_DIR)/qpisf_2s.cpp \ + $(DEC_SRC_DIR)/qpisf_2s_tab.cpp \ + $(DEC_SRC_DIR)/scale_signal.cpp \ + $(DEC_SRC_DIR)/synthesis_amr_wb.cpp \ + $(DEC_SRC_DIR)/voice_factor.cpp \ + $(DEC_SRC_DIR)/wb_syn_filt.cpp \ + $(DEC_SRC_DIR)/weight_amrwb_lpc.cpp + diff --git a/src/libs/opencore-amr/amrwb/Makefile.in b/src/libs/opencore-amr/amrwb/Makefile.in new file mode 100644 index 00000000..00482b73 --- /dev/null +++ b/src/libs/opencore-amr/amrwb/Makefile.in @@ -0,0 +1,1032 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@GCC_ARMV5_TRUE@am__append_1 = -DPV_CPU_ARCH_VERSION=5 -DPV_COMPILER=1 +@COMPILE_AS_C_TRUE@am__append_2 = -x c -std=c99 +subdir = amrwb +DIST_COMMON = $(amrwbinclude_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/opencore-amrwb.pc.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = opencore-amrwb.pc +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ + "$(DESTDIR)$(amrwbincludedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libopencore_amrwb_la_LIBADD = +am_libopencore_amrwb_la_OBJECTS = wrapper.lo agc2_amr_wb.lo \ + band_pass_6k_7k.lo dec_acelp_2p_in_64.lo dec_acelp_4p_in_64.lo \ + dec_alg_codebook.lo dec_gain2_amr_wb.lo deemphasis_32.lo \ + dtx_decoder_amr_wb.lo get_amr_wb_bits.lo \ + highpass_400hz_at_12k8.lo highpass_50hz_at_12k8.lo \ + homing_amr_wb_dec.lo interpolate_isp.lo isf_extrapolation.lo \ + isp_az.lo isp_isf.lo lagconceal.lo low_pass_filt_7k.lo \ + median5.lo mime_io.lo noise_gen_amrwb.lo normalize_amr_wb.lo \ + oversamp_12k8_to_16k.lo phase_dispersion.lo pit_shrp.lo \ + pred_lt4.lo preemph_amrwb_dec.lo pvamrwbdecoder.lo \ + pvamrwb_math_op.lo q_gain2_tab.lo qisf_ns.lo qisf_ns_tab.lo \ + qpisf_2s.lo qpisf_2s_tab.lo scale_signal.lo \ + synthesis_amr_wb.lo voice_factor.lo wb_syn_filt.lo \ + weight_amrwb_lpc.lo +libopencore_amrwb_la_OBJECTS = $(am_libopencore_amrwb_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libopencore_amrwb_la_SOURCES) \ + $(nodist_EXTRA_libopencore_amrwb_la_SOURCES) +DIST_SOURCES = $(libopencore_amrwb_la_SOURCES) +DATA = $(pkgconfig_DATA) +HEADERS = $(amrwbinclude_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENCORE_AMRNB_VERSION = @OPENCORE_AMRNB_VERSION@ +OPENCORE_AMRWB_VERSION = @OPENCORE_AMRWB_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Just set OC_BASE to the opencore root, or set AMR_BASE directly to +# a detached gsm_amr directory +OC_BASE = $(top_srcdir)/opencore +AMR_BASE = $(OC_BASE)/codecs_v2/audio/gsm_amr +DEC_DIR = $(AMR_BASE)/amr_wb/dec +DEC_SRC_DIR = $(DEC_DIR)/src +OSCL = $(top_srcdir)/oscl +AM_CFLAGS = -I$(OSCL) -I$(DEC_SRC_DIR) -I$(DEC_DIR)/include \ + -I$(AMR_BASE)/common/dec/include $(am__append_1) \ + $(am__append_2) +@COMPILE_AS_C_FALSE@libopencore_amrwb_la_LINK = $(CXXLINK) $(libopencore_amrwb_la_LDFLAGS) +@COMPILE_AS_C_TRUE@libopencore_amrwb_la_LINK = $(LINK) $(libopencore_amrwb_la_LDFLAGS) +@COMPILE_AS_C_TRUE@nodist_EXTRA_libopencore_amrwb_la_SOURCES = dummy.c +AM_CXXFLAGS = $(AM_CFLAGS) +amrwbincludedir = $(includedir)/opencore-amrwb +amrwbinclude_HEADERS = dec_if.h if_rom.h +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = opencore-amrwb.pc +lib_LTLIBRARIES = libopencore-amrwb.la +libopencore_amrwb_la_LDFLAGS = -version-info @OPENCORE_AMRWB_VERSION@ -no-undefined -export-symbols $(top_srcdir)/amrwb/opencore-amrwb.sym +EXTRA_DIST = $(top_srcdir)/amrwb/opencore-amrwb.sym + +# Our sources to include. There are certain sources we exclude and they are +# $(DEC_SRC_DIR)/decoder_amr_wb.cpp +libopencore_amrwb_la_SOURCES = \ + wrapper.cpp \ + $(DEC_SRC_DIR)/agc2_amr_wb.cpp \ + $(DEC_SRC_DIR)/band_pass_6k_7k.cpp \ + $(DEC_SRC_DIR)/dec_acelp_2p_in_64.cpp \ + $(DEC_SRC_DIR)/dec_acelp_4p_in_64.cpp \ + $(DEC_SRC_DIR)/dec_alg_codebook.cpp \ + $(DEC_SRC_DIR)/dec_gain2_amr_wb.cpp \ + $(DEC_SRC_DIR)/deemphasis_32.cpp \ + $(DEC_SRC_DIR)/dtx_decoder_amr_wb.cpp \ + $(DEC_SRC_DIR)/get_amr_wb_bits.cpp \ + $(DEC_SRC_DIR)/highpass_400hz_at_12k8.cpp \ + $(DEC_SRC_DIR)/highpass_50hz_at_12k8.cpp \ + $(DEC_SRC_DIR)/homing_amr_wb_dec.cpp \ + $(DEC_SRC_DIR)/interpolate_isp.cpp \ + $(DEC_SRC_DIR)/isf_extrapolation.cpp \ + $(DEC_SRC_DIR)/isp_az.cpp \ + $(DEC_SRC_DIR)/isp_isf.cpp \ + $(DEC_SRC_DIR)/lagconceal.cpp \ + $(DEC_SRC_DIR)/low_pass_filt_7k.cpp \ + $(DEC_SRC_DIR)/median5.cpp \ + $(DEC_SRC_DIR)/mime_io.cpp \ + $(DEC_SRC_DIR)/noise_gen_amrwb.cpp \ + $(DEC_SRC_DIR)/normalize_amr_wb.cpp \ + $(DEC_SRC_DIR)/oversamp_12k8_to_16k.cpp \ + $(DEC_SRC_DIR)/phase_dispersion.cpp \ + $(DEC_SRC_DIR)/pit_shrp.cpp \ + $(DEC_SRC_DIR)/pred_lt4.cpp \ + $(DEC_SRC_DIR)/preemph_amrwb_dec.cpp \ + $(DEC_SRC_DIR)/pvamrwbdecoder.cpp \ + $(DEC_SRC_DIR)/pvamrwb_math_op.cpp \ + $(DEC_SRC_DIR)/q_gain2_tab.cpp \ + $(DEC_SRC_DIR)/qisf_ns.cpp \ + $(DEC_SRC_DIR)/qisf_ns_tab.cpp \ + $(DEC_SRC_DIR)/qpisf_2s.cpp \ + $(DEC_SRC_DIR)/qpisf_2s_tab.cpp \ + $(DEC_SRC_DIR)/scale_signal.cpp \ + $(DEC_SRC_DIR)/synthesis_amr_wb.cpp \ + $(DEC_SRC_DIR)/voice_factor.cpp \ + $(DEC_SRC_DIR)/wb_syn_filt.cpp \ + $(DEC_SRC_DIR)/weight_amrwb_lpc.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cpp .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu amrwb/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu amrwb/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +opencore-amrwb.pc: $(top_builddir)/config.status $(srcdir)/opencore-amrwb.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libopencore-amrwb.la: $(libopencore_amrwb_la_OBJECTS) $(libopencore_amrwb_la_DEPENDENCIES) $(EXTRA_libopencore_amrwb_la_DEPENDENCIES) + $(AM_V_GEN)$(libopencore_amrwb_la_LINK) -rpath $(libdir) $(libopencore_amrwb_la_OBJECTS) $(libopencore_amrwb_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agc2_amr_wb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/band_pass_6k_7k.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dec_acelp_2p_in_64.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dec_acelp_4p_in_64.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dec_alg_codebook.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dec_gain2_amr_wb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deemphasis_32.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtx_decoder_amr_wb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_amr_wb_bits.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/highpass_400hz_at_12k8.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/highpass_50hz_at_12k8.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/homing_amr_wb_dec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interpolate_isp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isf_extrapolation.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isp_az.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isp_isf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lagconceal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/low_pass_filt_7k.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/median5.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mime_io.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/noise_gen_amrwb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/normalize_amr_wb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oversamp_12k8_to_16k.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/phase_dispersion.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pit_shrp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pred_lt4.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/preemph_amrwb_dec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pvamrwb_math_op.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pvamrwbdecoder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q_gain2_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qisf_ns.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qisf_ns_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qpisf_2s.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qpisf_2s_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scale_signal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/synthesis_amr_wb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/voice_factor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wb_syn_filt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/weight_amrwb_lpc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapper.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +agc2_amr_wb.lo: $(DEC_SRC_DIR)/agc2_amr_wb.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT agc2_amr_wb.lo -MD -MP -MF $(DEPDIR)/agc2_amr_wb.Tpo -c -o agc2_amr_wb.lo `test -f '$(DEC_SRC_DIR)/agc2_amr_wb.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/agc2_amr_wb.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/agc2_amr_wb.Tpo $(DEPDIR)/agc2_amr_wb.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/agc2_amr_wb.cpp' object='agc2_amr_wb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o agc2_amr_wb.lo `test -f '$(DEC_SRC_DIR)/agc2_amr_wb.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/agc2_amr_wb.cpp + +band_pass_6k_7k.lo: $(DEC_SRC_DIR)/band_pass_6k_7k.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT band_pass_6k_7k.lo -MD -MP -MF $(DEPDIR)/band_pass_6k_7k.Tpo -c -o band_pass_6k_7k.lo `test -f '$(DEC_SRC_DIR)/band_pass_6k_7k.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/band_pass_6k_7k.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/band_pass_6k_7k.Tpo $(DEPDIR)/band_pass_6k_7k.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/band_pass_6k_7k.cpp' object='band_pass_6k_7k.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o band_pass_6k_7k.lo `test -f '$(DEC_SRC_DIR)/band_pass_6k_7k.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/band_pass_6k_7k.cpp + +dec_acelp_2p_in_64.lo: $(DEC_SRC_DIR)/dec_acelp_2p_in_64.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dec_acelp_2p_in_64.lo -MD -MP -MF $(DEPDIR)/dec_acelp_2p_in_64.Tpo -c -o dec_acelp_2p_in_64.lo `test -f '$(DEC_SRC_DIR)/dec_acelp_2p_in_64.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_acelp_2p_in_64.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dec_acelp_2p_in_64.Tpo $(DEPDIR)/dec_acelp_2p_in_64.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/dec_acelp_2p_in_64.cpp' object='dec_acelp_2p_in_64.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dec_acelp_2p_in_64.lo `test -f '$(DEC_SRC_DIR)/dec_acelp_2p_in_64.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_acelp_2p_in_64.cpp + +dec_acelp_4p_in_64.lo: $(DEC_SRC_DIR)/dec_acelp_4p_in_64.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dec_acelp_4p_in_64.lo -MD -MP -MF $(DEPDIR)/dec_acelp_4p_in_64.Tpo -c -o dec_acelp_4p_in_64.lo `test -f '$(DEC_SRC_DIR)/dec_acelp_4p_in_64.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_acelp_4p_in_64.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dec_acelp_4p_in_64.Tpo $(DEPDIR)/dec_acelp_4p_in_64.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/dec_acelp_4p_in_64.cpp' object='dec_acelp_4p_in_64.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dec_acelp_4p_in_64.lo `test -f '$(DEC_SRC_DIR)/dec_acelp_4p_in_64.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_acelp_4p_in_64.cpp + +dec_alg_codebook.lo: $(DEC_SRC_DIR)/dec_alg_codebook.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dec_alg_codebook.lo -MD -MP -MF $(DEPDIR)/dec_alg_codebook.Tpo -c -o dec_alg_codebook.lo `test -f '$(DEC_SRC_DIR)/dec_alg_codebook.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_alg_codebook.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dec_alg_codebook.Tpo $(DEPDIR)/dec_alg_codebook.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/dec_alg_codebook.cpp' object='dec_alg_codebook.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dec_alg_codebook.lo `test -f '$(DEC_SRC_DIR)/dec_alg_codebook.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_alg_codebook.cpp + +dec_gain2_amr_wb.lo: $(DEC_SRC_DIR)/dec_gain2_amr_wb.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dec_gain2_amr_wb.lo -MD -MP -MF $(DEPDIR)/dec_gain2_amr_wb.Tpo -c -o dec_gain2_amr_wb.lo `test -f '$(DEC_SRC_DIR)/dec_gain2_amr_wb.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_gain2_amr_wb.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dec_gain2_amr_wb.Tpo $(DEPDIR)/dec_gain2_amr_wb.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/dec_gain2_amr_wb.cpp' object='dec_gain2_amr_wb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dec_gain2_amr_wb.lo `test -f '$(DEC_SRC_DIR)/dec_gain2_amr_wb.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dec_gain2_amr_wb.cpp + +deemphasis_32.lo: $(DEC_SRC_DIR)/deemphasis_32.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT deemphasis_32.lo -MD -MP -MF $(DEPDIR)/deemphasis_32.Tpo -c -o deemphasis_32.lo `test -f '$(DEC_SRC_DIR)/deemphasis_32.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/deemphasis_32.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/deemphasis_32.Tpo $(DEPDIR)/deemphasis_32.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/deemphasis_32.cpp' object='deemphasis_32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o deemphasis_32.lo `test -f '$(DEC_SRC_DIR)/deemphasis_32.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/deemphasis_32.cpp + +dtx_decoder_amr_wb.lo: $(DEC_SRC_DIR)/dtx_decoder_amr_wb.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dtx_decoder_amr_wb.lo -MD -MP -MF $(DEPDIR)/dtx_decoder_amr_wb.Tpo -c -o dtx_decoder_amr_wb.lo `test -f '$(DEC_SRC_DIR)/dtx_decoder_amr_wb.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dtx_decoder_amr_wb.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dtx_decoder_amr_wb.Tpo $(DEPDIR)/dtx_decoder_amr_wb.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/dtx_decoder_amr_wb.cpp' object='dtx_decoder_amr_wb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dtx_decoder_amr_wb.lo `test -f '$(DEC_SRC_DIR)/dtx_decoder_amr_wb.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/dtx_decoder_amr_wb.cpp + +get_amr_wb_bits.lo: $(DEC_SRC_DIR)/get_amr_wb_bits.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT get_amr_wb_bits.lo -MD -MP -MF $(DEPDIR)/get_amr_wb_bits.Tpo -c -o get_amr_wb_bits.lo `test -f '$(DEC_SRC_DIR)/get_amr_wb_bits.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/get_amr_wb_bits.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/get_amr_wb_bits.Tpo $(DEPDIR)/get_amr_wb_bits.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/get_amr_wb_bits.cpp' object='get_amr_wb_bits.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o get_amr_wb_bits.lo `test -f '$(DEC_SRC_DIR)/get_amr_wb_bits.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/get_amr_wb_bits.cpp + +highpass_400hz_at_12k8.lo: $(DEC_SRC_DIR)/highpass_400hz_at_12k8.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT highpass_400hz_at_12k8.lo -MD -MP -MF $(DEPDIR)/highpass_400hz_at_12k8.Tpo -c -o highpass_400hz_at_12k8.lo `test -f '$(DEC_SRC_DIR)/highpass_400hz_at_12k8.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/highpass_400hz_at_12k8.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/highpass_400hz_at_12k8.Tpo $(DEPDIR)/highpass_400hz_at_12k8.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/highpass_400hz_at_12k8.cpp' object='highpass_400hz_at_12k8.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o highpass_400hz_at_12k8.lo `test -f '$(DEC_SRC_DIR)/highpass_400hz_at_12k8.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/highpass_400hz_at_12k8.cpp + +highpass_50hz_at_12k8.lo: $(DEC_SRC_DIR)/highpass_50hz_at_12k8.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT highpass_50hz_at_12k8.lo -MD -MP -MF $(DEPDIR)/highpass_50hz_at_12k8.Tpo -c -o highpass_50hz_at_12k8.lo `test -f '$(DEC_SRC_DIR)/highpass_50hz_at_12k8.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/highpass_50hz_at_12k8.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/highpass_50hz_at_12k8.Tpo $(DEPDIR)/highpass_50hz_at_12k8.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/highpass_50hz_at_12k8.cpp' object='highpass_50hz_at_12k8.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o highpass_50hz_at_12k8.lo `test -f '$(DEC_SRC_DIR)/highpass_50hz_at_12k8.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/highpass_50hz_at_12k8.cpp + +homing_amr_wb_dec.lo: $(DEC_SRC_DIR)/homing_amr_wb_dec.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT homing_amr_wb_dec.lo -MD -MP -MF $(DEPDIR)/homing_amr_wb_dec.Tpo -c -o homing_amr_wb_dec.lo `test -f '$(DEC_SRC_DIR)/homing_amr_wb_dec.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/homing_amr_wb_dec.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/homing_amr_wb_dec.Tpo $(DEPDIR)/homing_amr_wb_dec.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/homing_amr_wb_dec.cpp' object='homing_amr_wb_dec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o homing_amr_wb_dec.lo `test -f '$(DEC_SRC_DIR)/homing_amr_wb_dec.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/homing_amr_wb_dec.cpp + +interpolate_isp.lo: $(DEC_SRC_DIR)/interpolate_isp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT interpolate_isp.lo -MD -MP -MF $(DEPDIR)/interpolate_isp.Tpo -c -o interpolate_isp.lo `test -f '$(DEC_SRC_DIR)/interpolate_isp.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/interpolate_isp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/interpolate_isp.Tpo $(DEPDIR)/interpolate_isp.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/interpolate_isp.cpp' object='interpolate_isp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o interpolate_isp.lo `test -f '$(DEC_SRC_DIR)/interpolate_isp.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/interpolate_isp.cpp + +isf_extrapolation.lo: $(DEC_SRC_DIR)/isf_extrapolation.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT isf_extrapolation.lo -MD -MP -MF $(DEPDIR)/isf_extrapolation.Tpo -c -o isf_extrapolation.lo `test -f '$(DEC_SRC_DIR)/isf_extrapolation.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/isf_extrapolation.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isf_extrapolation.Tpo $(DEPDIR)/isf_extrapolation.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/isf_extrapolation.cpp' object='isf_extrapolation.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o isf_extrapolation.lo `test -f '$(DEC_SRC_DIR)/isf_extrapolation.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/isf_extrapolation.cpp + +isp_az.lo: $(DEC_SRC_DIR)/isp_az.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT isp_az.lo -MD -MP -MF $(DEPDIR)/isp_az.Tpo -c -o isp_az.lo `test -f '$(DEC_SRC_DIR)/isp_az.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/isp_az.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isp_az.Tpo $(DEPDIR)/isp_az.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/isp_az.cpp' object='isp_az.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o isp_az.lo `test -f '$(DEC_SRC_DIR)/isp_az.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/isp_az.cpp + +isp_isf.lo: $(DEC_SRC_DIR)/isp_isf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT isp_isf.lo -MD -MP -MF $(DEPDIR)/isp_isf.Tpo -c -o isp_isf.lo `test -f '$(DEC_SRC_DIR)/isp_isf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/isp_isf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isp_isf.Tpo $(DEPDIR)/isp_isf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/isp_isf.cpp' object='isp_isf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o isp_isf.lo `test -f '$(DEC_SRC_DIR)/isp_isf.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/isp_isf.cpp + +lagconceal.lo: $(DEC_SRC_DIR)/lagconceal.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lagconceal.lo -MD -MP -MF $(DEPDIR)/lagconceal.Tpo -c -o lagconceal.lo `test -f '$(DEC_SRC_DIR)/lagconceal.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/lagconceal.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lagconceal.Tpo $(DEPDIR)/lagconceal.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/lagconceal.cpp' object='lagconceal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lagconceal.lo `test -f '$(DEC_SRC_DIR)/lagconceal.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/lagconceal.cpp + +low_pass_filt_7k.lo: $(DEC_SRC_DIR)/low_pass_filt_7k.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT low_pass_filt_7k.lo -MD -MP -MF $(DEPDIR)/low_pass_filt_7k.Tpo -c -o low_pass_filt_7k.lo `test -f '$(DEC_SRC_DIR)/low_pass_filt_7k.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/low_pass_filt_7k.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/low_pass_filt_7k.Tpo $(DEPDIR)/low_pass_filt_7k.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/low_pass_filt_7k.cpp' object='low_pass_filt_7k.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o low_pass_filt_7k.lo `test -f '$(DEC_SRC_DIR)/low_pass_filt_7k.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/low_pass_filt_7k.cpp + +median5.lo: $(DEC_SRC_DIR)/median5.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT median5.lo -MD -MP -MF $(DEPDIR)/median5.Tpo -c -o median5.lo `test -f '$(DEC_SRC_DIR)/median5.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/median5.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/median5.Tpo $(DEPDIR)/median5.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/median5.cpp' object='median5.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o median5.lo `test -f '$(DEC_SRC_DIR)/median5.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/median5.cpp + +mime_io.lo: $(DEC_SRC_DIR)/mime_io.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT mime_io.lo -MD -MP -MF $(DEPDIR)/mime_io.Tpo -c -o mime_io.lo `test -f '$(DEC_SRC_DIR)/mime_io.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/mime_io.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mime_io.Tpo $(DEPDIR)/mime_io.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/mime_io.cpp' object='mime_io.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o mime_io.lo `test -f '$(DEC_SRC_DIR)/mime_io.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/mime_io.cpp + +noise_gen_amrwb.lo: $(DEC_SRC_DIR)/noise_gen_amrwb.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT noise_gen_amrwb.lo -MD -MP -MF $(DEPDIR)/noise_gen_amrwb.Tpo -c -o noise_gen_amrwb.lo `test -f '$(DEC_SRC_DIR)/noise_gen_amrwb.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/noise_gen_amrwb.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/noise_gen_amrwb.Tpo $(DEPDIR)/noise_gen_amrwb.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/noise_gen_amrwb.cpp' object='noise_gen_amrwb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o noise_gen_amrwb.lo `test -f '$(DEC_SRC_DIR)/noise_gen_amrwb.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/noise_gen_amrwb.cpp + +normalize_amr_wb.lo: $(DEC_SRC_DIR)/normalize_amr_wb.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT normalize_amr_wb.lo -MD -MP -MF $(DEPDIR)/normalize_amr_wb.Tpo -c -o normalize_amr_wb.lo `test -f '$(DEC_SRC_DIR)/normalize_amr_wb.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/normalize_amr_wb.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/normalize_amr_wb.Tpo $(DEPDIR)/normalize_amr_wb.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/normalize_amr_wb.cpp' object='normalize_amr_wb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o normalize_amr_wb.lo `test -f '$(DEC_SRC_DIR)/normalize_amr_wb.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/normalize_amr_wb.cpp + +oversamp_12k8_to_16k.lo: $(DEC_SRC_DIR)/oversamp_12k8_to_16k.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT oversamp_12k8_to_16k.lo -MD -MP -MF $(DEPDIR)/oversamp_12k8_to_16k.Tpo -c -o oversamp_12k8_to_16k.lo `test -f '$(DEC_SRC_DIR)/oversamp_12k8_to_16k.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/oversamp_12k8_to_16k.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/oversamp_12k8_to_16k.Tpo $(DEPDIR)/oversamp_12k8_to_16k.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/oversamp_12k8_to_16k.cpp' object='oversamp_12k8_to_16k.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o oversamp_12k8_to_16k.lo `test -f '$(DEC_SRC_DIR)/oversamp_12k8_to_16k.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/oversamp_12k8_to_16k.cpp + +phase_dispersion.lo: $(DEC_SRC_DIR)/phase_dispersion.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT phase_dispersion.lo -MD -MP -MF $(DEPDIR)/phase_dispersion.Tpo -c -o phase_dispersion.lo `test -f '$(DEC_SRC_DIR)/phase_dispersion.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/phase_dispersion.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/phase_dispersion.Tpo $(DEPDIR)/phase_dispersion.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/phase_dispersion.cpp' object='phase_dispersion.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o phase_dispersion.lo `test -f '$(DEC_SRC_DIR)/phase_dispersion.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/phase_dispersion.cpp + +pit_shrp.lo: $(DEC_SRC_DIR)/pit_shrp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pit_shrp.lo -MD -MP -MF $(DEPDIR)/pit_shrp.Tpo -c -o pit_shrp.lo `test -f '$(DEC_SRC_DIR)/pit_shrp.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/pit_shrp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pit_shrp.Tpo $(DEPDIR)/pit_shrp.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/pit_shrp.cpp' object='pit_shrp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pit_shrp.lo `test -f '$(DEC_SRC_DIR)/pit_shrp.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/pit_shrp.cpp + +pred_lt4.lo: $(DEC_SRC_DIR)/pred_lt4.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pred_lt4.lo -MD -MP -MF $(DEPDIR)/pred_lt4.Tpo -c -o pred_lt4.lo `test -f '$(DEC_SRC_DIR)/pred_lt4.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/pred_lt4.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pred_lt4.Tpo $(DEPDIR)/pred_lt4.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/pred_lt4.cpp' object='pred_lt4.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pred_lt4.lo `test -f '$(DEC_SRC_DIR)/pred_lt4.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/pred_lt4.cpp + +preemph_amrwb_dec.lo: $(DEC_SRC_DIR)/preemph_amrwb_dec.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT preemph_amrwb_dec.lo -MD -MP -MF $(DEPDIR)/preemph_amrwb_dec.Tpo -c -o preemph_amrwb_dec.lo `test -f '$(DEC_SRC_DIR)/preemph_amrwb_dec.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/preemph_amrwb_dec.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/preemph_amrwb_dec.Tpo $(DEPDIR)/preemph_amrwb_dec.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/preemph_amrwb_dec.cpp' object='preemph_amrwb_dec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o preemph_amrwb_dec.lo `test -f '$(DEC_SRC_DIR)/preemph_amrwb_dec.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/preemph_amrwb_dec.cpp + +pvamrwbdecoder.lo: $(DEC_SRC_DIR)/pvamrwbdecoder.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pvamrwbdecoder.lo -MD -MP -MF $(DEPDIR)/pvamrwbdecoder.Tpo -c -o pvamrwbdecoder.lo `test -f '$(DEC_SRC_DIR)/pvamrwbdecoder.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/pvamrwbdecoder.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pvamrwbdecoder.Tpo $(DEPDIR)/pvamrwbdecoder.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/pvamrwbdecoder.cpp' object='pvamrwbdecoder.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pvamrwbdecoder.lo `test -f '$(DEC_SRC_DIR)/pvamrwbdecoder.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/pvamrwbdecoder.cpp + +pvamrwb_math_op.lo: $(DEC_SRC_DIR)/pvamrwb_math_op.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pvamrwb_math_op.lo -MD -MP -MF $(DEPDIR)/pvamrwb_math_op.Tpo -c -o pvamrwb_math_op.lo `test -f '$(DEC_SRC_DIR)/pvamrwb_math_op.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/pvamrwb_math_op.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pvamrwb_math_op.Tpo $(DEPDIR)/pvamrwb_math_op.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/pvamrwb_math_op.cpp' object='pvamrwb_math_op.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pvamrwb_math_op.lo `test -f '$(DEC_SRC_DIR)/pvamrwb_math_op.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/pvamrwb_math_op.cpp + +q_gain2_tab.lo: $(DEC_SRC_DIR)/q_gain2_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT q_gain2_tab.lo -MD -MP -MF $(DEPDIR)/q_gain2_tab.Tpo -c -o q_gain2_tab.lo `test -f '$(DEC_SRC_DIR)/q_gain2_tab.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/q_gain2_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/q_gain2_tab.Tpo $(DEPDIR)/q_gain2_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/q_gain2_tab.cpp' object='q_gain2_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o q_gain2_tab.lo `test -f '$(DEC_SRC_DIR)/q_gain2_tab.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/q_gain2_tab.cpp + +qisf_ns.lo: $(DEC_SRC_DIR)/qisf_ns.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT qisf_ns.lo -MD -MP -MF $(DEPDIR)/qisf_ns.Tpo -c -o qisf_ns.lo `test -f '$(DEC_SRC_DIR)/qisf_ns.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/qisf_ns.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qisf_ns.Tpo $(DEPDIR)/qisf_ns.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/qisf_ns.cpp' object='qisf_ns.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o qisf_ns.lo `test -f '$(DEC_SRC_DIR)/qisf_ns.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/qisf_ns.cpp + +qisf_ns_tab.lo: $(DEC_SRC_DIR)/qisf_ns_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT qisf_ns_tab.lo -MD -MP -MF $(DEPDIR)/qisf_ns_tab.Tpo -c -o qisf_ns_tab.lo `test -f '$(DEC_SRC_DIR)/qisf_ns_tab.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/qisf_ns_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qisf_ns_tab.Tpo $(DEPDIR)/qisf_ns_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/qisf_ns_tab.cpp' object='qisf_ns_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o qisf_ns_tab.lo `test -f '$(DEC_SRC_DIR)/qisf_ns_tab.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/qisf_ns_tab.cpp + +qpisf_2s.lo: $(DEC_SRC_DIR)/qpisf_2s.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT qpisf_2s.lo -MD -MP -MF $(DEPDIR)/qpisf_2s.Tpo -c -o qpisf_2s.lo `test -f '$(DEC_SRC_DIR)/qpisf_2s.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/qpisf_2s.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qpisf_2s.Tpo $(DEPDIR)/qpisf_2s.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/qpisf_2s.cpp' object='qpisf_2s.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o qpisf_2s.lo `test -f '$(DEC_SRC_DIR)/qpisf_2s.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/qpisf_2s.cpp + +qpisf_2s_tab.lo: $(DEC_SRC_DIR)/qpisf_2s_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT qpisf_2s_tab.lo -MD -MP -MF $(DEPDIR)/qpisf_2s_tab.Tpo -c -o qpisf_2s_tab.lo `test -f '$(DEC_SRC_DIR)/qpisf_2s_tab.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/qpisf_2s_tab.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qpisf_2s_tab.Tpo $(DEPDIR)/qpisf_2s_tab.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/qpisf_2s_tab.cpp' object='qpisf_2s_tab.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o qpisf_2s_tab.lo `test -f '$(DEC_SRC_DIR)/qpisf_2s_tab.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/qpisf_2s_tab.cpp + +scale_signal.lo: $(DEC_SRC_DIR)/scale_signal.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT scale_signal.lo -MD -MP -MF $(DEPDIR)/scale_signal.Tpo -c -o scale_signal.lo `test -f '$(DEC_SRC_DIR)/scale_signal.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/scale_signal.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/scale_signal.Tpo $(DEPDIR)/scale_signal.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/scale_signal.cpp' object='scale_signal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o scale_signal.lo `test -f '$(DEC_SRC_DIR)/scale_signal.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/scale_signal.cpp + +synthesis_amr_wb.lo: $(DEC_SRC_DIR)/synthesis_amr_wb.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT synthesis_amr_wb.lo -MD -MP -MF $(DEPDIR)/synthesis_amr_wb.Tpo -c -o synthesis_amr_wb.lo `test -f '$(DEC_SRC_DIR)/synthesis_amr_wb.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/synthesis_amr_wb.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/synthesis_amr_wb.Tpo $(DEPDIR)/synthesis_amr_wb.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/synthesis_amr_wb.cpp' object='synthesis_amr_wb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o synthesis_amr_wb.lo `test -f '$(DEC_SRC_DIR)/synthesis_amr_wb.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/synthesis_amr_wb.cpp + +voice_factor.lo: $(DEC_SRC_DIR)/voice_factor.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT voice_factor.lo -MD -MP -MF $(DEPDIR)/voice_factor.Tpo -c -o voice_factor.lo `test -f '$(DEC_SRC_DIR)/voice_factor.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/voice_factor.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/voice_factor.Tpo $(DEPDIR)/voice_factor.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/voice_factor.cpp' object='voice_factor.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o voice_factor.lo `test -f '$(DEC_SRC_DIR)/voice_factor.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/voice_factor.cpp + +wb_syn_filt.lo: $(DEC_SRC_DIR)/wb_syn_filt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wb_syn_filt.lo -MD -MP -MF $(DEPDIR)/wb_syn_filt.Tpo -c -o wb_syn_filt.lo `test -f '$(DEC_SRC_DIR)/wb_syn_filt.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/wb_syn_filt.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/wb_syn_filt.Tpo $(DEPDIR)/wb_syn_filt.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/wb_syn_filt.cpp' object='wb_syn_filt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wb_syn_filt.lo `test -f '$(DEC_SRC_DIR)/wb_syn_filt.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/wb_syn_filt.cpp + +weight_amrwb_lpc.lo: $(DEC_SRC_DIR)/weight_amrwb_lpc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT weight_amrwb_lpc.lo -MD -MP -MF $(DEPDIR)/weight_amrwb_lpc.Tpo -c -o weight_amrwb_lpc.lo `test -f '$(DEC_SRC_DIR)/weight_amrwb_lpc.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/weight_amrwb_lpc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/weight_amrwb_lpc.Tpo $(DEPDIR)/weight_amrwb_lpc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(DEC_SRC_DIR)/weight_amrwb_lpc.cpp' object='weight_amrwb_lpc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o weight_amrwb_lpc.lo `test -f '$(DEC_SRC_DIR)/weight_amrwb_lpc.cpp' || echo '$(srcdir)/'`$(DEC_SRC_DIR)/weight_amrwb_lpc.cpp + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) +install-amrwbincludeHEADERS: $(amrwbinclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(amrwbincludedir)" || $(MKDIR_P) "$(DESTDIR)$(amrwbincludedir)" + @list='$(amrwbinclude_HEADERS)'; test -n "$(amrwbincludedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(amrwbincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(amrwbincludedir)" || exit $$?; \ + done + +uninstall-amrwbincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(amrwbinclude_HEADERS)'; test -n "$(amrwbincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(amrwbincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(amrwbincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-amrwbincludeHEADERS install-pkgconfigDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-amrwbincludeHEADERS uninstall-libLTLIBRARIES \ + uninstall-pkgconfigDATA + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-amrwbincludeHEADERS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-amrwbincludeHEADERS uninstall-libLTLIBRARIES \ + uninstall-pkgconfigDATA + +@COMPILE_AS_C_TRUE@ # Mention a dummy pure C file to trigger generation of the $(LINK) variable + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/opencore-amr/amrwb/dec_if.h b/src/libs/opencore-amr/amrwb/dec_if.h new file mode 100644 index 00000000..56acdaaf --- /dev/null +++ b/src/libs/opencore-amr/amrwb/dec_if.h @@ -0,0 +1,36 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#ifndef OPENCORE_AMRWB_DEC_IF_H +#define OPENCORE_AMRWB_DEC_IF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define _good_frame 0 + +void* D_IF_init(void); +void D_IF_decode(void* state, const unsigned char* bits, short* synth, int bfi); +void D_IF_exit(void* state); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/amrwb/if_rom.h b/src/libs/opencore-amr/amrwb/if_rom.h new file mode 100644 index 00000000..8977e03a --- /dev/null +++ b/src/libs/opencore-amr/amrwb/if_rom.h @@ -0,0 +1,33 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#ifndef OPENCORE_AMRWB_IF_ROM_H +#define OPENCORE_AMRWB_IF_ROM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +typedef int16_t Word16; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/amrwb/opencore-amrwb.pc.in b/src/libs/opencore-amr/amrwb/opencore-amrwb.pc.in new file mode 100644 index 00000000..b4eb9933 --- /dev/null +++ b/src/libs/opencore-amr/amrwb/opencore-amrwb.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: OpenCORE AMR-WB +Description: Adaptive Multi-Rate Wideband speech codec library +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lopencore-amrwb +Cflags: -I${includedir} diff --git a/src/libs/opencore-amr/amrwb/opencore-amrwb.sym b/src/libs/opencore-amr/amrwb/opencore-amrwb.sym new file mode 100644 index 00000000..9a1cfcb5 --- /dev/null +++ b/src/libs/opencore-amr/amrwb/opencore-amrwb.sym @@ -0,0 +1,3 @@ +D_IF_init +D_IF_decode +D_IF_exit diff --git a/src/libs/opencore-amr/amrwb/wrapper.cpp b/src/libs/opencore-amr/amrwb/wrapper.cpp new file mode 100644 index 00000000..dd282811 --- /dev/null +++ b/src/libs/opencore-amr/amrwb/wrapper.cpp @@ -0,0 +1,128 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#include "dec_if.h" +#include +#include +#include +#include +#include +#include + +/* This is basically a C rewrite of decode_amr_wb.cpp */ + +struct state { + void *st; /* State structure */ + unsigned char *pt_st; + int16 *ScratchMem; + + uint8* iInputBuf; + int16* iInputSampleBuf; + int16* iOutputBuf; + + uint8 quality; + int16 mode; + int16 mode_old; + int16 frame_type; + + int16 reset_flag; + int16 reset_flag_old; + int16 status; + RX_State rx_state; +}; + +void* D_IF_init(void) { + struct state* state = (struct state*) malloc(sizeof(struct state)); + memset(state, 0, sizeof(*state)); + + state->iInputSampleBuf = (int16*) malloc(sizeof(int16)*KAMRWB_NB_BITS_MAX); + state->reset_flag = 0; + state->reset_flag_old = 1; + state->mode_old = 0; + state->rx_state.prev_ft = RX_SPEECH_GOOD; + state->rx_state.prev_mode = 0; + state->pt_st = (unsigned char*) malloc(pvDecoder_AmrWbMemRequirements()); + + pvDecoder_AmrWb_Init(&state->st, state->pt_st, &state->ScratchMem); + return state; +} + +void D_IF_exit(void* s) { + struct state* state = (struct state*) s; + free(state->pt_st); + free(state->iInputSampleBuf); + free(state); +} + +void D_IF_decode(void* s, const unsigned char* in, short* out, int bfi) { + struct state* state = (struct state*) s; + + state->mode = (in[0] >> 3) & 0x0f; + in++; + + state->quality = 1; /* ? */ + mime_unsorting((uint8*) in, state->iInputSampleBuf, &state->frame_type, &state->mode, state->quality, &state->rx_state); + + if ((state->frame_type == RX_NO_DATA) | (state->frame_type == RX_SPEECH_LOST)) { + state->mode = state->mode_old; + state->reset_flag = 0; + } else { + state->mode_old = state->mode; + + /* if homed: check if this frame is another homing frame */ + if (state->reset_flag_old == 1) { + /* only check until end of first subframe */ + state->reset_flag = pvDecoder_AmrWb_homing_frame_test_first(state->iInputSampleBuf, state->mode); + } + } + + /* produce encoder homing frame if homed & input=decoder homing frame */ + if ((state->reset_flag != 0) && (state->reset_flag_old != 0)) { + /* set homing sequence ( no need to decode anything */ + + for (int16 i = 0; i < AMR_WB_PCM_FRAME; i++) { + out[i] = EHF_MASK; + } + } else { + int16 frameLength; + state->status = pvDecoder_AmrWb(state->mode, + state->iInputSampleBuf, + out, + &frameLength, + state->st, + state->frame_type, + state->ScratchMem); + } + + for (int16 i = 0; i < AMR_WB_PCM_FRAME; i++) { /* Delete the 2 LSBs (14-bit output) */ + out[i] &= 0xfffC; + } + + /* if not homed: check whether current frame is a homing frame */ + if (state->reset_flag_old == 0) { + /* check whole frame */ + state->reset_flag = pvDecoder_AmrWb_homing_frame_test(state->iInputSampleBuf, state->mode); + } + /* reset decoder if current frame is a homing frame */ + if (state->reset_flag != 0) { + pvDecoder_AmrWb_Reset(state->st, 1); + } + state->reset_flag_old = state->reset_flag; + +} + diff --git a/src/libs/opencore-amr/config.guess b/src/libs/opencore-amr/config.guess new file mode 100644 index 00000000..d622a44e --- /dev/null +++ b/src/libs/opencore-amr/config.guess @@ -0,0 +1,1530 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-02-10' + +# This file 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 2 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 . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/libs/opencore-amr/config.h.in b/src/libs/opencore-amr/config.h.in new file mode 100644 index 00000000..a365bfe7 --- /dev/null +++ b/src/libs/opencore-amr/config.h.in @@ -0,0 +1,134 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if stdbool.h conforms to C99. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define for Solaris 2.5.1 so the uint32_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT32_T + +/* Define for Solaris 2.5.1 so the uint64_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT64_T + +/* Define for Solaris 2.5.1 so the uint8_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT8_T + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to the type of a signed integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#undef int16_t + +/* Define to the type of a signed integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef int32_t + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef int64_t + +/* Define to the type of a signed integer type of width exactly 8 bits if such + a type exists and the standard includes do not define it. */ +#undef int8_t + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#undef uint16_t + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef uint32_t + +/* Define to the type of an unsigned integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef uint64_t + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ +#undef uint8_t diff --git a/src/libs/opencore-amr/config.sub b/src/libs/opencore-amr/config.sub new file mode 100644 index 00000000..c894da45 --- /dev/null +++ b/src/libs/opencore-amr/config.sub @@ -0,0 +1,1773 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-02-10' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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 2 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 . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/libs/opencore-amr/configure b/src/libs/opencore-amr/configure new file mode 100755 index 00000000..ddde0cf1 --- /dev/null +++ b/src/libs/opencore-amr/configure @@ -0,0 +1,18525 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for opencore-amr 0.1.3. +# +# Report bugs to . +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: http://sourceforge.net/projects/opencore-amr/ about +$0: your system, including any error possibly output before +$0: this message. Then install a modern shell, or manually +$0: run the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='opencore-amr' +PACKAGE_TARNAME='opencore-amr' +PACKAGE_VERSION='0.1.3' +PACKAGE_STRING='opencore-amr 0.1.3' +PACKAGE_BUGREPORT='http://sourceforge.net/projects/opencore-amr/' +PACKAGE_URL='' + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +OPENCORE_AMRWB_VERSION +OPENCORE_AMRNB_VERSION +LIBOBJS +LIBTOOL_DEPS +CXXCPP +CPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +LIBTOOL +LN_S +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +ac_ct_CC +CFLAGS +CC +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CXX +CPPFLAGS +LDFLAGS +CXXFLAGS +CXX +EXAMPLES_FALSE +EXAMPLES_TRUE +AMRNB_DECODER_FALSE +AMRNB_DECODER_TRUE +AMRNB_ENCODER_FALSE +AMRNB_ENCODER_TRUE +GCC_ARMV5_FALSE +GCC_ARMV5_TRUE +COMPILE_AS_C_FALSE +COMPILE_AS_C_TRUE +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_maintainer_mode +enable_compile_c +enable_gcc_armv5 +enable_amrnb_encoder +enable_amrnb_decoder +enable_examples +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +' + ac_precious_vars='build_alias +host_alias +target_alias +CXX +CXXFLAGS +LDFLAGS +LIBS +CPPFLAGS +CCC +CC +CFLAGS +CPP +CXXCPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures opencore-amr 0.1.3 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/opencore-amr] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of opencore-amr 0.1.3:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: `make V=1') + --disable-silent-rules verbose build output (undo: `make V=0') + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + --enable-compile-c enable compiling as C program (default is yes) + --enable-gcc-armv5 enable GCC specific ARMv5 assembler (default is no) + --enable-amrnb-encoder enable AMR-NB encoder (default is yes) + --enable-amrnb-decoder enable AMR-NB decoder (default is yes) + --enable-examples enable example encoding/decoding programs (default + is no) + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + +Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CC C compiler command + CFLAGS C compiler flags + CPP C preprocessor + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +opencore-amr configure 0.1.3 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------------------------------------ ## +## Report this to http://sourceforge.net/projects/opencore-amr/ ## +## ------------------------------------------------------------ ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_find_intX_t LINENO BITS VAR +# ----------------------------------- +# Finds a signed integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_intX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 +$as_echo_n "checking for int$2_t... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in int$2_t 'int' 'long int' \ + 'long long int' 'short int' 'signed char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) + < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + case $ac_type in #( + int$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_intX_t + +# ac_fn_c_find_uintX_t LINENO BITS VAR +# ------------------------------------ +# Finds an unsigned integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_uintX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 +$as_echo_n "checking for uint$2_t... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ + 'unsigned long long int' 'unsigned short int' 'unsigned char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + case $ac_type in #( + uint$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_uintX_t +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by opencore-amr $as_me 0.1.3, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_aux_dir= +for ac_dir in . "$srcdir"/.; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in . \"$srcdir\"/." "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='opencore-amr' + VERSION='0.1.3' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a ustar tar archive" >&5 +$as_echo_n "checking how to create a ustar tar archive... " >&6; } +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar plaintar pax cpio none' +_am_tools=${am_cv_prog_tar_ustar-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + { echo "$as_me:$LINENO: $_am_tar --version" >&5 + ($_am_tar --version) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && break + done + am__tar="$_am_tar --format=ustar -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=ustar -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x ustar -w "$$tardir"' + am__tar_='pax -L -x ustar -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H ustar -L' + am__tar_='find "$tardir" -print | cpio -o -H ustar -L' + am__untar='cpio -i -H ustar -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_ustar}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5 + (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + rm -rf conftest.dir + if test -s conftest.tar; then + { echo "$as_me:$LINENO: $am__untar &5 + ($am__untar &5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +if ${am_cv_prog_tar_ustar+:} false; then : + $as_echo_n "(cached) " >&6 +else + am_cv_prog_tar_ustar=$_am_tool +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_ustar" >&5 +$as_echo "$am_cv_prog_tar_ustar" >&6; } + + + + + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +ac_config_headers="$ac_config_headers config.h" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + +# Cross compiling support +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +# Various options for configure +# Check whether --enable-compile-c was given. +if test "${enable_compile_c+set}" = set; then : + enableval=$enable_compile_c; compile_as_c=$enableval +else + compile_as_c=yes +fi + +# Check whether --enable-gcc-armv5 was given. +if test "${enable_gcc_armv5+set}" = set; then : + enableval=$enable_gcc_armv5; gcc_armv5=$enableval +else + gcc_armv5=no +fi + +# Check whether --enable-amrnb-encoder was given. +if test "${enable_amrnb_encoder+set}" = set; then : + enableval=$enable_amrnb_encoder; amrnb_encoder=$enableval +else + amrnb_encoder=yes +fi + +# Check whether --enable-amrnb-decoder was given. +if test "${enable_amrnb_decoder+set}" = set; then : + enableval=$enable_amrnb_decoder; amrnb_decoder=$enableval +else + amrnb_decoder=yes +fi + +# Check whether --enable-examples was given. +if test "${enable_examples+set}" = set; then : + enableval=$enable_examples; examples=$enableval +else + examples=no +fi + + +# Automake conditionals to set + if test x$compile_as_c = xyes; then + COMPILE_AS_C_TRUE= + COMPILE_AS_C_FALSE='#' +else + COMPILE_AS_C_TRUE='#' + COMPILE_AS_C_FALSE= +fi + + if test x$gcc_armv5 = xyes; then + GCC_ARMV5_TRUE= + GCC_ARMV5_FALSE='#' +else + GCC_ARMV5_TRUE='#' + GCC_ARMV5_FALSE= +fi + + if test x$amrnb_encoder = xyes; then + AMRNB_ENCODER_TRUE= + AMRNB_ENCODER_FALSE='#' +else + AMRNB_ENCODER_TRUE='#' + AMRNB_ENCODER_FALSE= +fi + + if test x$amrnb_decoder = xyes; then + AMRNB_DECODER_TRUE= + AMRNB_DECODER_FALSE='#' +else + AMRNB_DECODER_TRUE='#' + AMRNB_DECODER_FALSE= +fi + + if test x$examples = xyes; then + EXAMPLES_TRUE= + EXAMPLES_FALSE='#' +else + EXAMPLES_TRUE='#' + EXAMPLES_FALSE= +fi + + +# Checks for programs. +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 +$as_echo_n "checking whether the C++ compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C++ compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 +$as_echo_n "checking for C++ compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + + +# Setup for libtool +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.2' +macro_revision='1.3337' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + + +# Checks for libraries. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lm" >&5 +$as_echo_n "checking for main in -lm... " >&6; } +if ${ac_cv_lib_m_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_m_main=yes +else + ac_cv_lib_m_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_main" >&5 +$as_echo "$ac_cv_lib_m_main" >&6; } +if test "x$ac_cv_lib_m_main" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF + + LIBS="-lm $LIBS" + +fi + + +# Checks for header files. +for ac_header in stdint.h stdlib.h string.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 +$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } +if ${ac_cv_header_stdbool_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifndef bool + "error: bool is not defined" +#endif +#ifndef false + "error: false is not defined" +#endif +#if false + "error: false is not 0" +#endif +#ifndef true + "error: true is not defined" +#endif +#if true != 1 + "error: true is not 1" +#endif +#ifndef __bool_true_false_are_defined + "error: __bool_true_false_are_defined is not defined" +#endif + + struct s { _Bool s: 1; _Bool t; } s; + + char a[true == 1 ? 1 : -1]; + char b[false == 0 ? 1 : -1]; + char c[__bool_true_false_are_defined == 1 ? 1 : -1]; + char d[(bool) 0.5 == true ? 1 : -1]; + /* See body of main program for 'e'. */ + char f[(_Bool) 0.0 == false ? 1 : -1]; + char g[true]; + char h[sizeof (_Bool)]; + char i[sizeof s.t]; + enum { j = false, k = true, l = false * true, m = true * 256 }; + /* The following fails for + HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ + _Bool n[m]; + char o[sizeof n == m * sizeof n[0] ? 1 : -1]; + char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; + /* Catch a bug in an HP-UX C compiler. See + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + */ + _Bool q = true; + _Bool *pq = &q; + +int +main () +{ + + bool e = &s; + *pq |= q; + *pq |= ! q; + /* Refer to every declared value, to avoid compiler optimizations. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + + !m + !n + !o + !p + !q + !pq); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdbool_h=yes +else + ac_cv_header_stdbool_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 +$as_echo "$ac_cv_header_stdbool_h" >&6; } +ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" +if test "x$ac_cv_type__Bool" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE__BOOL 1 +_ACEOF + + +fi + +if test $ac_cv_header_stdbool_h = yes; then + +$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t" +case $ac_cv_c_int16_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int16_t $ac_cv_c_int16_t +_ACEOF +;; +esac + +ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t" +case $ac_cv_c_int32_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int32_t $ac_cv_c_int32_t +_ACEOF +;; +esac + +ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t" +case $ac_cv_c_int64_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int64_t $ac_cv_c_int64_t +_ACEOF +;; +esac + +ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t" +case $ac_cv_c_int8_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int8_t $ac_cv_c_int8_t +_ACEOF +;; +esac + +ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t" +case $ac_cv_c_uint16_t in #( + no|yes) ;; #( + *) + + +cat >>confdefs.h <<_ACEOF +#define uint16_t $ac_cv_c_uint16_t +_ACEOF +;; + esac + +ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" +case $ac_cv_c_uint32_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT32_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint32_t $ac_cv_c_uint32_t +_ACEOF +;; + esac + +ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t" +case $ac_cv_c_uint64_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT64_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint64_t $ac_cv_c_uint64_t +_ACEOF +;; + esac + +ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t" +case $ac_cv_c_uint8_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT8_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint8_t $ac_cv_c_uint8_t +_ACEOF +;; + esac + + +# Checks for library functions. +for ac_header in stdlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" +if test "x$ac_cv_header_stdlib_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STDLIB_H 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 +$as_echo_n "checking for GNU libc compatible malloc... " >&6; } +if ${ac_cv_func_malloc_0_nonnull+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_malloc_0_nonnull=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined STDC_HEADERS || defined HAVE_STDLIB_H +# include +#else +char *malloc (); +#endif + +int +main () +{ +return ! malloc (0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_malloc_0_nonnull=yes +else + ac_cv_func_malloc_0_nonnull=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5 +$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } +if test $ac_cv_func_malloc_0_nonnull = yes; then : + +$as_echo "#define HAVE_MALLOC 1" >>confdefs.h + +else + $as_echo "#define HAVE_MALLOC 0" >>confdefs.h + + case " $LIBOBJS " in + *" malloc.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS malloc.$ac_objext" + ;; +esac + + +$as_echo "#define malloc rpl_malloc" >>confdefs.h + +fi + + +for ac_func in memset +do : + ac_fn_c_check_func "$LINENO" "memset" "ac_cv_func_memset" +if test "x$ac_cv_func_memset" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MEMSET 1 +_ACEOF + +fi +done + + +# OpenCORE AMR soname version to use +# goes by ‘current[:revision[:age]]’ with the soname ending up as +# current.age.revision. +OPENCORE_AMRNB_VERSION=0:3:0 +OPENCORE_AMRWB_VERSION=0:3:0 + + + +ac_config_files="$ac_config_files Makefile amrnb/Makefile amrwb/Makefile test/Makefile amrnb/opencore-amrnb.pc amrwb/opencore-amrwb.pc" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${COMPILE_AS_C_TRUE}" && test -z "${COMPILE_AS_C_FALSE}"; then + as_fn_error $? "conditional \"COMPILE_AS_C\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GCC_ARMV5_TRUE}" && test -z "${GCC_ARMV5_FALSE}"; then + as_fn_error $? "conditional \"GCC_ARMV5\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMRNB_ENCODER_TRUE}" && test -z "${AMRNB_ENCODER_FALSE}"; then + as_fn_error $? "conditional \"AMRNB_ENCODER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMRNB_DECODER_TRUE}" && test -z "${AMRNB_DECODER_FALSE}"; then + as_fn_error $? "conditional \"AMRNB_DECODER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${EXAMPLES_TRUE}" && test -z "${EXAMPLES_FALSE}"; then + as_fn_error $? "conditional \"EXAMPLES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by opencore-amr $as_me 0.1.3, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +opencore-amr config.status 0.1.3 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "amrnb/Makefile") CONFIG_FILES="$CONFIG_FILES amrnb/Makefile" ;; + "amrwb/Makefile") CONFIG_FILES="$CONFIG_FILES amrwb/Makefile" ;; + "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; + "amrnb/opencore-amrnb.pc") CONFIG_FILES="$CONFIG_FILES amrnb/opencore-amrnb.pc" ;; + "amrwb/opencore-amrwb.pc") CONFIG_FILES="$CONFIG_FILES amrwb/opencore-amrwb.pc" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/src/libs/opencore-amr/configure.ac b/src/libs/opencore-amr/configure.ac new file mode 100644 index 00000000..8b0f504e --- /dev/null +++ b/src/libs/opencore-amr/configure.ac @@ -0,0 +1,93 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_INIT([opencore-amr], [0.1.3], [http://sourceforge.net/projects/opencore-amr/]) +AC_CONFIG_AUX_DIR(.) +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE([tar-ustar]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +AC_CONFIG_HEADERS([config.h]) +AM_MAINTAINER_MODE + +# Cross compiling support +AC_CANONICAL_BUILD +AC_CANONICAL_HOST + +# Various options for configure +AC_ARG_ENABLE([compile-c], + [AS_HELP_STRING([--enable-compile-c], + [enable compiling as C program (default is yes)])], + [compile_as_c=$enableval], + [compile_as_c=yes]) +AC_ARG_ENABLE([gcc-armv5], + [AS_HELP_STRING([--enable-gcc-armv5], + [enable GCC specific ARMv5 assembler (default is no)])], + [gcc_armv5=$enableval], [gcc_armv5=no]) +AC_ARG_ENABLE([amrnb-encoder], + [AS_HELP_STRING([--enable-amrnb-encoder], + [enable AMR-NB encoder (default is yes)])], + [amrnb_encoder=$enableval], [amrnb_encoder=yes]) +AC_ARG_ENABLE([amrnb-decoder], + [AS_HELP_STRING([--enable-amrnb-decoder], + [enable AMR-NB decoder (default is yes)])], + [amrnb_decoder=$enableval], [amrnb_decoder=yes]) +AC_ARG_ENABLE([examples], + [AS_HELP_STRING([--enable-examples], + [enable example encoding/decoding programs (default is no)])], + [examples=$enableval], [examples=no]) + +# Automake conditionals to set +AM_CONDITIONAL(COMPILE_AS_C, test x$compile_as_c = xyes) +AM_CONDITIONAL(GCC_ARMV5, test x$gcc_armv5 = xyes) +AM_CONDITIONAL(AMRNB_ENCODER, test x$amrnb_encoder = xyes) +AM_CONDITIONAL(AMRNB_DECODER, test x$amrnb_decoder = xyes) +AM_CONDITIONAL(EXAMPLES, test x$examples = xyes) + +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET + +# Setup for libtool +AC_PROG_LIBTOOL +AC_SUBST(LIBTOOL_DEPS) + +# Checks for libraries. +AC_CHECK_LIB([m], [main]) + +# Checks for header files. +AC_CHECK_HEADERS([stdint.h stdlib.h string.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_INLINE +AC_TYPE_INT16_T +AC_TYPE_INT32_T +AC_TYPE_INT64_T +AC_TYPE_INT8_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T +AC_TYPE_UINT8_T + +# Checks for library functions. +AC_FUNC_MALLOC +AC_CHECK_FUNCS([memset]) + +# OpenCORE AMR soname version to use +# goes by ‘current[:revision[:age]]’ with the soname ending up as +# current.age.revision. +OPENCORE_AMRNB_VERSION=0:3:0 +OPENCORE_AMRWB_VERSION=0:3:0 +AC_SUBST(OPENCORE_AMRNB_VERSION) +AC_SUBST(OPENCORE_AMRWB_VERSION) + +AC_CONFIG_FILES([Makefile + amrnb/Makefile + amrwb/Makefile + test/Makefile + amrnb/opencore-amrnb.pc + amrwb/opencore-amrwb.pc]) +AC_OUTPUT diff --git a/src/libs/opencore-amr/depcomp b/src/libs/opencore-amr/depcomp new file mode 100644 index 00000000..bd0ac089 --- /dev/null +++ b/src/libs/opencore-amr/depcomp @@ -0,0 +1,688 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2011-12-04.11; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +# 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 2, 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 . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test "$stat" = 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/ \1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/ / + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/src/libs/opencore-amr/install-sh b/src/libs/opencore-amr/install-sh new file mode 100644 index 00000000..a9244eb0 --- /dev/null +++ b/src/libs/opencore-amr/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-01-19.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for `test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/src/libs/opencore-amr/ltmain.sh b/src/libs/opencore-amr/ltmain.sh new file mode 100644 index 00000000..c7d06c3c --- /dev/null +++ b/src/libs/opencore-amr/ltmain.sh @@ -0,0 +1,9661 @@ + +# libtool (GNU libtool) 2.4.2 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --no-warn don't display warning messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . +# GNU libtool home page: . +# General help using GNU software: . + +PROGRAM=libtool +PACKAGE=libtool +VERSION="2.4.2 Debian-2.4.2-1" +TIMESTAMP="" +package_revision=1.3337 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $opt_debug + + $SED -n '/(C)/!b go + :more + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + +# func_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_warning=: +opt_verbose=: +opt_silent=false +opt_verbose=false + + +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do + opt="$1" + shift + case $opt in + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) + opt_silent=false +func_append preserve_args " $opt" + ;; + --no-warning|--no-warn) + opt_warning=false +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" + shift + ;; + + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + + # Separate optargs to long options: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; + esac + done + + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$absdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type \`$version_type'" + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Remove ${wl} instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + func_resolve_sysroot "$deplib" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$opt_mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/src/libs/opencore-amr/m4/libtool.m4 b/src/libs/opencore-amr/m4/libtool.m4 new file mode 100644 index 00000000..828104cf --- /dev/null +++ b/src/libs/opencore-amr/m4/libtool.m4 @@ -0,0 +1,8001 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/src/libs/opencore-amr/m4/ltoptions.m4 b/src/libs/opencore-amr/m4/ltoptions.m4 new file mode 100644 index 00000000..5d9acd8e --- /dev/null +++ b/src/libs/opencore-amr/m4/ltoptions.m4 @@ -0,0 +1,384 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/src/libs/opencore-amr/m4/ltsugar.m4 b/src/libs/opencore-amr/m4/ltsugar.m4 new file mode 100644 index 00000000..9000a057 --- /dev/null +++ b/src/libs/opencore-amr/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/src/libs/opencore-amr/m4/ltversion.m4 b/src/libs/opencore-amr/m4/ltversion.m4 new file mode 100644 index 00000000..07a8602d --- /dev/null +++ b/src/libs/opencore-amr/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3337 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.2' +macro_revision='1.3337' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/src/libs/opencore-amr/m4/lt~obsolete.m4 b/src/libs/opencore-amr/m4/lt~obsolete.m4 new file mode 100644 index 00000000..c573da90 --- /dev/null +++ b/src/libs/opencore-amr/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/src/libs/opencore-amr/missing b/src/libs/opencore-amr/missing new file mode 100644 index 00000000..86a8fc31 --- /dev/null +++ b/src/libs/opencore-amr/missing @@ -0,0 +1,331 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2012-01-06.13; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# 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 2, 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 . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/src/libs/opencore-amr/opencore-amr-nb.sln b/src/libs/opencore-amr/opencore-amr-nb.sln new file mode 100644 index 00000000..70dcae89 --- /dev/null +++ b/src/libs/opencore-amr/opencore-amr-nb.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libopencore-amr-nb", "opencore-amr-nb.vcxproj", "{3480045B-45D9-48B5-BEFA-1B7A75652606}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3480045B-45D9-48B5-BEFA-1B7A75652606}.Debug|x86.ActiveCfg = Debug|Win32 + {3480045B-45D9-48B5-BEFA-1B7A75652606}.Debug|x86.Build.0 = Debug|Win32 + {3480045B-45D9-48B5-BEFA-1B7A75652606}.Release|x86.ActiveCfg = Release|Win32 + {3480045B-45D9-48B5-BEFA-1B7A75652606}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/opencore-amr/opencore-amr-nb.vcproj b/src/libs/opencore-amr/opencore-amr-nb.vcproj new file mode 100644 index 00000000..61b838fa --- /dev/null +++ b/src/libs/opencore-amr/opencore-amr-nb.vcproj @@ -0,0 +1,1492 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/opencore-amr/opencore-amr-nb.vcxproj b/src/libs/opencore-amr/opencore-amr-nb.vcxproj new file mode 100644 index 00000000..188ee601 --- /dev/null +++ b/src/libs/opencore-amr/opencore-amr-nb.vcxproj @@ -0,0 +1,413 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + libopencore-amr-nb + {3480045B-45D9-48B5-BEFA-1B7A75652606} + opencoreamrnb + Win32Proj + + + + DynamicLibrary + v140 + Unicode + true + + + StaticLibrary + v140 + Unicode + + + + + + + + + + + + + <_ProjectFileVersion>14.0.23107.0 + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + + + + Full + opencore\codecs_v2\audio\gsm_amr\common\dec\include;opencore\codecs_v2\audio\gsm_amr\amr_nb\common\include;opencore\codecs_v2\audio\gsm_amr\amr_nb\dec\src;opencore\codecs_v2\audio\gsm_amr\amr_nb\dec\include;opencore\codecs_v2\audio\gsm_amr\amr_nb\enc\src;opencore\codecs_v2\audio\gsm_amr\amr_nb\enc\include;oscl;%(AdditionalIncludeDirectories) + WIN32;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + + Level3 + + + + + + MaxSpeed + true + Size + opencore\codecs_v2\audio\gsm_amr\common\dec\include;opencore\codecs_v2\audio\gsm_amr\amr_nb\common\include;opencore\codecs_v2\audio\gsm_amr\amr_nb\dec\src;opencore\codecs_v2\audio\gsm_amr\amr_nb\dec\include;opencore\codecs_v2\audio\gsm_amr\amr_nb\enc\src;opencore\codecs_v2\audio\gsm_amr\amr_nb\enc\include;oscl;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libs/opencore-amr/opencore-amr-nb.vcxproj.filters b/src/libs/opencore-amr/opencore-amr-nb.vcxproj.filters new file mode 100644 index 00000000..403ae5eb --- /dev/null +++ b/src/libs/opencore-amr/opencore-amr-nb.vcxproj.filters @@ -0,0 +1,1011 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {87f25e6e-58a8-46be-8508-6ceac49905c5} + + + {47af1a32-d39f-457b-827c-3867b2783661} + + + {f1921e5e-f831-4f10-8b47-9c554d624689} + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {98d8ba93-b6d5-4942-9c17-ecceb01214a4} + + + {e0046d61-c95c-4b56-8b40-2e6a08901c02} + + + {85f3c922-8bb8-4449-b478-171877536d5e} + + + {0254d84b-abde-47d9-8f86-db51fc79a3c0} + + + {ca5f3b48-b9de-415f-a09e-947965f2963e} + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\common + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files + + + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\decode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Source Files\encode + + + Header Files + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\common + + + Header Files\encode + + + Header Files\decode + + + Header Files\decode + + + Header Files\interface + + + Header Files\interface + + + Header Files\oscl + + + Header Files\oscl + + + Header Files\oscl + + + Header Files\oscl + + + Header Files\oscl + + + Header Files\oscl + + + + + + \ No newline at end of file diff --git a/src/libs/opencore-amr/opencore/ChangeLog b/src/libs/opencore-amr/opencore/ChangeLog new file mode 100644 index 00000000..4558f967 --- /dev/null +++ b/src/libs/opencore-amr/opencore/ChangeLog @@ -0,0 +1,1328 @@ +=============================================================================== +2010-06-25 OpenCORE 2.50 + +New Features +- Mediascanner-albumart support +- Add new player engine test case for HTTP streaming transfer mode +- Adding BGR support for CC16 in codecs +- Provide a runtime setting to prioritize SW codecs over HW codecs in the case +of thumbnail retrieval. +- Addition of DLNA specific 'byte-seek' support for Pause/Resume and Seek cases. +- Player engine test configuration modifications +- Add profiling capability to OMX AVC/MPEG4/AAC encoder components. +- Add support for the PSSH Atom to the mp4 composer, as specified in the +Protected Interoperable File Format (PIFF) Specification +- Timestamp smoothing for incoming audio timestamps +- Add support for the boxes 'enca', 'encv', 'enct', 'sinf' and 'frma' to the +mp4 composer +- Add SetParameter as an extension command to Android MediaPlayer +- Adding support of forward playback with rendering only I-frames +- Modify the mp4 composer to verify the existence of entries in the mfra box +before rendering it. +- Updates to DRM interfaces and test cases +- Initialize iSkipToIDR to false for OMX AVC decoder. +- Gapless and playlist support for MP4, MP3, and WMA +- Framework support for MPEG-2 FF Parser +- Changes at the PE Node and mp4 parser node to support PDL random position of +fragmented clips with out-of-band mfra information +- Allowing scrubbing inside playerengine +- MP4 Parser/composer mods to improve metadata support +- Graceful degradation phase 1 (Key-frame-only mode in case of many late frames) +- Makefile feature to build static aggregate +- Add support for building against Android eclair +- Add integration support for 3rd party audio library +- AAC lib - Add new message that signals back change of Mode (new PCE) +- Allow reconfig of MIOs for playlist scenarios +- Android makefile segment separation / refactoring +- Addition of new event PVMFInfoSourceFormatUpdated +- Support for AAC multichannel contents to be partially decoded (output +only 2 channels). +- Implement PVMFOMXEncNode::GetProfileAndLevel() to query for the final +profile/level after intialize. +- Add support for changing bit rate/frame rate/intra refresh rate to OMXEncNode. +- Allow local.mk file for applications to define steps for running target +- Support for m4b file format +- New ARM macros in build make system. +- Add a target in module level unit test to display the list of available +targets +- Support M4V bitstream with short header mode. +- Support the PIFF Enhancements in the mp4 parser library +- Metadata updates for mp3 parser +- Added an utility function to set RTSP proxy server information +(https://review.source.android.com/#change,14369) +- Build changes to support a restricted Main Profile AVC decoder optimized for +ARMv6 +- Adding scaling support for YUV422toYUV420. +- When initialization error occurs to one of the selected tracks, allow the +playback of remaining tracks without a complete shut down. +- Add progressive playback support in MP4 movie fragment playback +- Add stdout from engine unit test output to junit xml logs +- Large File Support in MP4 PDL and PPB +- Added the test cases in PVME and FMU for protected test content +- New Common Parser Node for AMR and WAV + +Improvements +- H264 raw support for PVMI MIO file input / output +- Retrieve "duration" metadata in mediascanner through metadataretriever +- Fix for compiler warnings in mediaoutputnode and player engine test app. +- Base node should add itself to Scheduler only in a valid Created state. +- Codesize reduction for FMU +- Implemented additional APIs in CPM plugin. +- AAC lib - Enable redundant PCE syntax element on a raw bitstream +- Add metadata support for aac, amr, awb and wav files. +- Change logger levels to appropriate values in android video mio and jb node +for certain log statements +- H264 raw support for PVMI MIO file input / output +- Add Extended Atom types to the mp4 composer +- Add test for receiving data in 2way engine unit tests. +- Remove unused KVPs from engine and codecs +- Changes made to API of a CPM plugin. +- OMXConfigParser is modified to differentiate VC1 component from WMV component +so that WMV7 and WMV8 get rejected by VC1 component. +- OMX Encoder node needs to save SPS/PPS for its possible query in the case of +H264_RAW format +- If the encoder node marks the frame as keyframe, there is no need to sniff +the bitstream +- Update source duration for video playlists +- Build OMX wrappers in thumb mode in Android +- Add a new 2way engine unit test. +- Port File Output node to new base node interface design. +- Removal of 2way VideoParser Node +- Copyright date in OpenCORE source code should reflect the last time the file +was modified +- Deprecate support for platforms without native 64-bit functionality. +- Modify media layer node to use the base node framework +- Add full metadata support for OMX MPEG4/H263 decoders - +profile/level/post-processing +- Replace numeric values in code with enum +- Add command line configurable timeout for pvplayer_engine_test +- Some CML2 rules related to so_name can create errors with "n" symbol used as +module name +- Watchdog timer to monitor start of data reception +- Update the priority of some log messages +- Use parseID3Tag for aac files +- Node commands should succeed if the node is already in the resultant state in +the base node. +- Miscellaneous DRM-related modifications +- Modify jitter buffer node to use the base node framework +- Refactor Media Output node +- Remove linker warnings w.r.t. libopencore_player and libopencore_net_support +- PVMFMediaClock takes care of device latency. Remove the device latency +processing in AMIO. +- Port PVMP4FFComposerNode with the new Node Interface +- Port Protocol Engine node to new node design +- Refactor Media Output node to use new node interface +- Changes to a DRM utility +- Deprecate (and defunct) support for non-OMX nodes and builds +- Introduce authoring clock for recording AV sync +- Allow a single MIO to act as both compressed and uncompressed for the author +engine +- Separating registration of ClockStateObserver and the latency in +PVMFMediaClock +- Add API in PVMp4H263EncExtensionInterface to set H.263 GOB header interval +- New constructor and parse method overloads for node interface implementation +- OMX call error handling +- Handle end of track event in player engine testcase for I-frame mode playback +- Add RTSP return error code to the PVMF status return code +- Remove PVMFDummyFileOutputNode +- Clear the playback intent in PVME to avoid incorrect consumption of rights +- Based on most recent Khronos clarifications - partially consumed buffers are +not allowed in OMX +- Modify socket node to use the base node framework +- Adding support for RTSPT tests for new server +- Addition of Large File Support in MP4 Parser Library +- Dynamically calculate omx encoder output buffer sizes instead of hard-coding +the size +- Cleanup of 2way engine code. +- Add warning logger message in the NegotiateComponentParameters functions for +2-way +- Update OMX test app to test creation/destruction of the same component +multiple times in a row (especially useful for dynamic loading) +- Remove dependency of fileoutputnode on pvPlayer SDK +- cleanup of old Keys from MIOs +- Remove API QueryUUID from all interfaces +- Remove usage of USE_CML2_CONFIG since all the builds have been converted to +CML2 +- Change MPEG4 encoder OMX component to generate VOL header before getting +any input frames. +- Fix gcc 4.4.1 compiler warnings +- Remove unnecessary makefile templates from OpenCORE +- Support for raw compressed headers in track meta data +- Add a 2way engine unit test for when buffers are provided by MIO. +- Remove dependency on oscl string from oscl_uuid. +- Cleanup of 2way engine code. +- NDEBUG and OSCL_RELEASE_BUILD macro consolidation +- Use GetEventExtensionInterface to pass indication details from pv2way +- Bypass pasp atom box in mp4 parser +(https://review.source.android.com/#change,12330) +- CPM cleanup +- Add mp3 track support in mp4 parser +(https://review.source.android.com/#change,12329) +- Separate variable XCFLAGS to hold C-compiler flags +- Use openssl crypto library within pvcrypto +- Process the config data in the omx decoder components even if there are no +output buffers available +- Add support for multichannel aac clips with no channel distribution +information +- Add test duration to junit-like XML log output from test framework +- Makefile update for new module +- Change component library name in makefile +- Move amr and avc common libraries from opencore_common into omx_sharedlibrary +- Move libpvmioaviwavfileinput.a libavifileparser.a out of libopencore_common.so +- Deprecate GetMetadataKeys, GetNodeMetadataKeys, GetNumMetadataKeys, and +ReleaseNodeMetadataKeys APIs. +- Improvement in an internal build and the export of some additional methods +- Move amr_common and avc_common lib to libomx_sharedlibrary.so +- Print out time taken to complete each OMX test case. +- Check for INTRA frames in the MPPTYPE box when the H263 frames are using the +extended PTYPE header +- Introduce new KVP string +- Improve the check for GLOBAL_CPU_ARCH_VERSION in codecs lib makefile to make +it scalable to higher version of ARM architecture. +- Move ResetData() function in android surface output inside Reset() +- Improve buffer negotiation with 3rd party omx components, as it will let +them have the final say in the number of buffers. +- Set release level logging to 1 for all platforms +- Sending position status update before SetPlaybackRange command completion. +- Improving the current logic in player engine for video scrubbing +- Improve color conversion unit test +- Remove unnecessary check in PEUT PS and SS testcases for the number of +buffering complete events. +- Improved error reporting in DRM plugin. +- Added player test cases for DRM +- Changes to deal with use-cases when sdcard/phone memory gets full while +recording +- Reset PaddingFrameInfo in MP3 parser after retrieving frame data +- Cleaned up DRM plugin interface +- PEUT for shoutcast shall check playback session to verify if it is valid +shoutcast session. +- Modify AVCConfigParser to handle multiple SPSs/PPSs, AUD and SEI NALs. +- Add profile and channel metadata support in AAC and AMR parsers +- Modified CPM plugin data structure +- Modify AVCConfigParser to handle multiple SPSs/PPSs, AUD and SEI NALs. +- Fix for repositioning large offsets during MP4 PS +- Add more metadata support in MP3 Parser and ID3 Parcom + +Bugs Fixed +- Unit test fixes for CPM plugin +- Improved handling of some MP4 Poison clips +- Modify MP4 parser to not send EOS if duration available from content is 0 +- Fix for deadlock between player engine and OMX component threads caused by a +mismatched queue depth and number of new output AVC buffers during port +reconfiguration +- Player hangs on normal playback under certain test conditions +- Adjust the AVC decoder to handle non-compliant bitstreams which have a +non-zero frame_num for IDRs +- Failure in InitNextValidClipInPlaylist( ) should report a command failure. +- Change to support additional argument in constructor of base node interface +implementation +- Initialization of display width and display height in the mp4 parser node +- Reset PaddingFrameInfo in MP3 parser after retrieving frame data +- Handle PVMFErrProcessing condition in case wrong URL is specified in PS or +shoutcast +- New CommonParserPort needs to derive from +PvmiCapabilityAndConfigPortFormatImpl +- Fix for proper handling of MP4 clips with invalid edit list atoms +- Audio timestamp was not initialized properly for LATM case. +- Fix for test PEUT 425 by making sure that the state transition in the test +code from STATE_UPDATEDATASOURCE to STATE_GETMETADATAVALUESLIST is serialized. +- Separate clock for rendering MIOs for 2way lipsync +- This work fixes infinite loop when OMX InitDecoder fails +- MP4 recognizer has been modified to further check the brand information +inside "ftyp" atom and not declare OMA2 DCF files as mp4. +- If the AVC decoder reports an error in the last frame of a sequence, the +OpenMAX component does not flush the decoder's output +- MP3 http playback reports error for low bitrate connection. +- Fix for running a test number multiple times in makefile target for running +parallel player engine tests +- Fixed OMX base dec node to handle 0 sample size and updated FMU to retrieve +metadata for new file extension +- MediaOutputNode module unit test failure +- Add dependency of librt to Android x86 builds +- Data type inconsistency in code of OMX test app +- Wrong thumbnails retrieved for Mp4 contents +- Incorrect time stamps with B frames in H264 high profile +- Conditionally support -Wno-psabi compiler flag for Android simulator +- For AVC clips with more number of SPS/PPS than the number of buffers +allocated, the node returns error and the clip cannot be played. +- Specific test mp3 content cannot be played on streaming with HTTP Progressive +protocol +- Inconsistent Keep-Alive timer during RTSP streaming +- Adding the missing Metadata functionality in the omx audio dec node. +- Memory leak in 2way proxy adapter +- Use clock_gettime(MONOTONIC) instead of gettimeofday() on linux platform to +have a consistent clock +- Fix for playback progress not being reported correctly for sessions in which +the duration is not known upfront. +- MP3 duration is not calculated when there is a CPM plugin +- Seek on Mp3 PS for contents without having any XING or VBRI headers results +in No-op +- Add support of "YUV 420 Semi Planer" in Encoder Node. +- Completely eliminate logging from omx proxy and omx component unless +explicitly enabled +- Fix for hang in player engine test case 862 +- Issue with seek sample number when repositioning near the beginning of a +recorded file. +- Disable setting OMX_Video_ControlRateMax to OmxComponent +- Unreleased array causing memory leaks in mp4 parser node +- MP3 parser does not recover from invalid frame embedded on mp3 stream +- Disabling outgoing skew indication messages +- AVC Sample entry not parsed correctly for picture parameter set +- Fix Assert failure in player engine TC 941 +- Fix memory leak in Android extension media player APIs +- Add OMX AVC support to 2way +- Set pre-defined VOL header for PV2Way +- Logic to detect end of track for Mp4 FF having moof atoms need to modified +- Fix get_ISO8601_str_time api on certain platforms +- parseMP4() in mediascanner.cpp couldn't detect unknown type correctly. +- RTSP streaming start time always start from zero +- Failure in PlayerEngine Unit testcase +- EOS Timestamp is invalid from mp3 source node +- Support for multiple frames in a single data block of AAC ADTS parser +- Check for NULL ptr access in CPV324m2Way::HandleNodeErrorEvent +- Fix seek failure when seek to almost end of one mp4 content +- Protocol engine node download auto resume algorithm simplification +- Conditionally convert compiler warnings to errors in android folder +- Fix for possible race condition in FMU's thumbnail retrieval +- PS/MP3 unable to set start playback time when duration is unknown +- Fix for out-of-bound array access in m4v config parser function. +- Fix for thumbnail retrieval when using file handle in Android +- Remove unnecessary code from android logger config +- Bug for Size limitation in case of streaming +- Change ParseM4VFSI to be more lenient to profile/level error and add SPL4a +and SPL5 support to m4vencoder. +- Set/GetDataSinkFormatType +- Thumbnail loading take much more time in all video content +- memory access violation occurs -3g2 content containing moof atom +- OMX Decoder Node Scheduling may be affected due to node refactoring change +- Close the MetadataDriver semaphore to prevent an assert. +- Fix an RTSP tunneling url problem +- Choppy audio after pausing and resuming 2way call +- EOS message being overwritten by BOS in the mediaoutputnode +- Do not access iTimestampVec.back() if the vector is empty. +- 2way's h223LCtest and h223test are failing. +- Use config parser information to configure OMX AAC component. Still expect to +get Port settings changed event in case of implicit AAC+ +- Calling UpdateDataSource before calling AddDataSource() could result in a +crash +- Allow SDKINFO Header to use environment variables if set +- Fix 2way unit test assertion failure. +- Fix socket communication scenario for 2way +- Out of bounds access during CPM Register Content for MP4 and MP3 clips +- Fix MP3 gapless playback EOC message iFramesToFollowEOC calculation +- Removed OsclThread::EnableKill, added OsclThread::CanTerminate +- Delaying the release of a source node until after the engine command completes +- PVMFInfoStartOfData and PVMFInfoEndOfData events need to be serialized at the +mediaoutputnode during clip transition +- Ensure that PVOMXRegistry calls OsclSharedLibrary LoadLib and Close only once. +- Fix player engine test cases 48 and 49 +- Datasource being removed prematurely +- Change some of the time related variables in M4venc and AmrEnc OMX component +from uint32 to OMX_TICKS or int64. +- Fix for incorrect display dimensions under certain conditions. +- Add a new testcase for Pause - Skip - Resume +- Use Wno-psabi flag when building against eclair SDK +- In OMX decoder node - In case of an invalid input NAL or empty input +message, input OMX buffer needs to be released +- Music app crashes and gallery application is not present on android-2.1_r1 +emulator +- Bug in ColorConvert lib (RGB16 to yuv420 conversion) +- Memory access violation occurs +- Player engine changes to add a log line and remove regular decoder node +reference +- Incoming user input messages are not passed to application +- Check semaphore before closing +- Timed Text file playback issue +- Fix pv_config_selected.mk in opencore_value_add for 2way changes. +- Add stub definitions to fix korg master branch build for newly declared +functions +- MP4 Fileformat Edit List storing offset in wrong timescale. +- AAC lib - colored noise produced when decoding file with clipped levels +- ReleaseMetadataValues resulting in a hang when called without GetMetadataKeys +- Update the thread safe queue to handle events from multiple threads +- Fix MP4 source node metadata retrieval for playlist +- Fix PEUT TC 400-455 playlist input file path +- Make audio MIOs for gapless tests active so that samples are not dropped for +being late +- Fix problem with using external buffers for OMX encoder for 2way. +- Check if CPM object exists before creating one in MP4 parser node +- PVME unable to retrieve metadata for DRM protected content +- Cleanup 2way local.mk +- OMX audio dec node should process multiple BOS (BOC/EOC) messages correctly +in case of LATM format +- Multiplexed data gets corrupted when is there is no data in logical channel +- Prevent redundant oscl file cache writeupdate calls when closing file +- OSCL SetSize() implementation +- Changed logfile appenders to take boolean flag indicating whether or not +(default) to flush after every write. Add 'fsync' to linux oscl file +implementation +- Fix broken build due to pvmedia_io_fileoutput +- Move implementation of some 2-way methods from header file into C file +- Player engine not using the source node capconfig interface for all engine +capconfig calls +- Fix for TC 21 on MP3 clips +- TC 414 (FullPlaylistPauseSkipToNextTrackResumeTest) failing with full logging +turned ON +- Handling for packets received after RTSP PLAY response with timestamps less +than the advertised rtpbase +- Modify the AMR Enc OMX component to take timestamp from the OMX client and +remove logic to detect gaps or overlaps. +- Sometimes cancelall command is not executed on all the data sinks in +cancellation process by the engine. +- AAC lib - Fix for random crash under certain test condition +- Additional changes in the AAC lib to support redundant PCE +- Memory leaks when using PVMP4FF_USE_EXTN_UDTA mode in MP4 Composer library +- If the ERecognizerStart command is canceled, do not queue a ERecognizerClose. +- Fix issue where an RTSP server returns a start NPT that is non-zero despite +the application's request for a zero NPT +- MP4 parser node fixes for retrieving key-value pairs without a track index in +the input string +- Re-issue commands in 2way engine to be run later. +- correct rtpinfo was not used while deciding ts +- OMX Decoder Node Scheduling may be affected due to node refactoring change +- Duration was not converted to millisec timescale properly +- Remove unneeded dependency on header files in mediaoutputnode +- Linux oscl time converts time differrently depending on whether or not zulu +is set +- Add check to prevent engine clock from starting if engine is not in started +state +- Protect oscl file native seek and read operations on the same file handle +- A flag needs to be initialized correctly for decoder node codec config data +not to be affected by inserting a pause command +- Fix for eAAC clips seek resulting in wrong speed +- AAC lib - Audio artifacts when decoding clip with continue saturated levels +- Missing metadata key "writer" in metadatadriver.cpp +- TARGET_ARCH_VERSION missing from Config.mk +- AAC-lib Compiler bug on Android build creates the wrong assembly code +- Disconnect-Seek mode support for pause/resume +- Fix for MP3 parser returning incorrect value for bitrate key +- When outgoing user input message is deleted, VT crashes +- Fixing media scanner inappropriate removal of media files +(https://review.source.android.com/#change,14161) +- Change to return engine state as prepared (not started) if the engine +has moved into auto_pause after prepare state, without being started. +- Updating out-of-order packets handling logic +- Added support to handle multiple 'elst' entries in MP4 FF. That improved AV +sync while playing the content which has multiple edit list. +- Remove empty OSCL source files and add comment to empty 2way makefile +- This record fixed a streaming module unit test problem +- PVME test crashes while running .mp4 files +- Oscl file cache read error for large block sizes +- Update the mp3ffparser node to handle the cancel command in init. +- Null-terminate the string sent as part of PVMFInfoSourceFormatUpdated event +- PV_CFLAGS set to wrong value in Config.mk +- OMX unit test modifications +- AAC recognizer - fails by qualifying valid extension-less MP3 clip as AAC +- Fix parsing of certain HTTP URLs. +- Initialize _currentPlaybackSampleTimestamp to zero in +SampleTableAtom::resetTrackByTime() +- Use threadsafe callback AO in camera input MIO to reschedule the AO +- Modified PVME to handle the failures from SetSourceInitializationData in +SourceNode +- Check EOS buffer flag if in the middle of partial frame assembly in omx +component +- Fix for AAC silence insertion for the mono case and the AAC+ case +- Disable filewriter thread in composer node +- test_adts_x.pcm +- Peeking samples from an mp4 fragmented files may return wrong information +- Fixed timestamp conversion for B-frames. +- Fix live RTSP streaming issue +- MP4 Source node doesnt resets FirstValidClip's index after Stop/Reset +- OMX AVCDec output buffer calculation for cropped output could be smaller than +required. Hence, the buffer calculation part must be modified. +- Fix an assert involving iStride and iSliceHeight in omx video decoder node +- A 64-bit overflow when computing energy levels was incorrectly saturated with +a 32-bit max., instead of a 64-bit max in the AAC decoder +- Fix live RTSP streaming issue +- Passing the call ReleaseNodeMetadataValues from the source node to the CPM +plugin. +- Add robustness to AAC SBR with silence insertion. +- Fix BOS and EOS timestamps for MP3 +- Fix player engine playlist unit test 414 +- Change implementation of XML escape() for memory leak analysis +- Improvements at the Download Manager, PE Node and mp4 parser in order to +accomodate new Progressive Streaming protocols. +- Incorrect duration for AAC ADIF file +- Call failure when two TCS are received +- Allow repositioning in mp4 files without stss atoms +- Update the description of setParametersSync API +- Fix multiple repositioning usecases with MP3 gapless playlists +- Audio distortion heard in AMR-NB audio clip +- AAC multichannel decoder robustness improvement to prevent crash. +- Export GetRemoteCodecCapability method for 2-way +- Fix logical error in error handling +- Corrected intialization of ParserObject and ClipIndex for Metadata parsing in +MP3FF. +- resolve player engine test RELEASE Linux build compilation errors on gcc 4.3 +- Recognizer fails to recognize file but file is larger than minimum needed. +- Improvements at the Download Manager, Protocol Engine node in order to +accomodate new Progressive Streaming protocols +- Error events from the audio thread are not handled correctly +- OSCL Unicode to UTF8 modification +- Fix deadlock in mp3 parser and node for mp3 files that are smaller than the +minimum desired for recognition +- Fix parsing of certain RTSP URLs. +- VT TC-58 failure +- OsclMemPoolResizableAllocator does not allocate memory in a circular way, +causes fragmentation. +- Fix out-of-bounds array index issue in 2way-stack. +- Changed bitmask in oscl_UTF8ToUnicode function so sign extension with 32-bit +wchars is handled properly. +- cleanup of old Keys from MIOs +- Fixed memory leak on file trackfragmentatom.cpp +- Corrected SkipMediaTS calculation and FrameDuration for Backward playback +- Node shall not set async flag for sync command on CPM. +- Follow-on RIO-7292 to fix PV_CPU_ARCH_VERSION value in Android.mk files. +- Handle PVMFInfoErrorHandlingComplete info events in the FMU +- Fixed track fragment atom parsing to allow UUID atom +- BaseNode shall use the logger tag supplied by node and enable complete node +logging. +- Incorrect handling of INSUFFICIENT_DATA error when parsing mp4 movie fragment +clip +- Fixed bug in player engine error-handling code. +- Media Output Node sync margins are not being set for video tracks + + +=============================================================================== +2009-12-08 OpenCORE 2.07 + +New Features +- Support 3GPP fast content switch +- Player engine changes and new interfaces for gapless playback +- Player unit test additions +- Add KVP mechanism to set max/min UDP port number +- Support PE node feature selection for static builds +- SetFSIParam( ) extension interface is implemented. It was previously stubbed +out. FSI (VOL header or SPS/PPS) is sent to the encoder as preferred encoding +parameters. +- Introduce ASM and condition support for arm in tool generated project files. +- GetActualAACConfig - add mime type as input to process properly RFC 3016 type +streams +- Updates to player engine and media output node for gapless playback +- Implement support for I-frame request in OMX encoder node +- Add support for AAC Dual Mono +- Add a new KVP to control audio output in trickplay mode. +- CPM changes and new player engine unit test cases. +- Add Track ID as input parameter to the addTrack mp4 composer API + +Improvements +- Added pvlogger_empty_layout.h as an optional logger output string format that +appends nothing to the output string. +- Code cleanup in MP4 decoder vop code +- AAC lib - improve ADTS searching capabilities - needed for applications not +using aac parser +- Change to use audio output buffer size calculation to be based on time as in +the OMX audio dec node rather than based on a fixed number of samples as in the +OMX components default. +- Handle more non-standard OMX component state transition errors +- Removal of 2way VideoParser Node +- Update MediaIONodeRepositionDuringPreparedTest test case to run till EOS +- Improve FillBufferDoneProcessing and ParseAVCFullFrameIntoNALs in OMX encoder +nodes +- Add support for linking against eclair-specific libraries +- Adding a new api to turn silence insertion logic on or off (engine->omx +decoder node->omx audio component). +- Introduce -Wno-psabi into android makefiles +- Modify logging in PVME Test so that it's consistent with the other logging +- Cleanup in the android folder (logging, whitespace, etc) +- Changes in android folder to sync-up with eclair changes +- Removed unused code oscl_mempool_allocator.h/.cpp +- Include pvlogger library in oscl build +- Updating run_ae_test make target for logging +- Minor bug fix to support movie fragments MP4 files with empty sample +description tables and common PE Node code refactoring + +Bugs Fixed +- Video and timer gets stuck on repositioning while the audio continues +- A/V Sync Issue on Simple playback and timer goes beyond the limit with Video +playback only (Audio Stops) +- Fix for redundant rule to copy getactualaacconfig.h +- MP4 file parser and parser node modified to support a very large value of +timescale +- Improvements in AAC file parser for ADTS recognition +- Code cleanup in pvmf_node_interface +- Failures in Java-based mediaframework unit test cases. +- Fix for failure on resumption from long pauses during RTSP streaming. +- Remove an extra call of ResetData from ThreadLogoff in AndroidSurfaceOutput +- Mp4 composer node File writer hang issue +- Typo in the OMX node log statements +- Uninitialized variable iPlayElementIndex of structure PVPPlaybackPosition +causing repositioning problems +- In AAC and AMR parser nodes, UsageComplete should be called only when the +content is protected +- MP4 parser node returning the same command twice +- Hang in Player engine when cancel called in prepare +- Use clock_gettime(MONOTONIC) instead of gettimeofday() on linux platform to +have a consistent clock +- In PVPlayerEngine::DoVerifyAndSetPlayerParameter, hard-coded enum value is +wrong +- OMX encoder node bug in processing SPS PPS for components that produce NAL +start codes +- Classes with virtual methods should have virtual destructors too +- Fix for crash in AAC Decoder unit test app +- Map key 'track-info/track-number' to 'tracknumber' for Android MediaScanner +to recognize the key. +- MP3 FF parser should not pass the Xing/LAME header frame to dec node +- AMR file parser improvements +- Removed parsing support for WMF AMR tracks from MP4 file parser. +- Improvements in OMX test application +- Fix crash in 2way stack unit test +- Change in oscl statfs to accomodate blank paths +- Add Error handling at buffer memory allocation error +- Fix rebuffering after PVMFInfoBufferingComplete at mp4 PPB +- AVC configuration modifications +- Using sample duration in addition to timestamp for syncronization +- FMU video MIO does not set video subformat type correctly +- Fix uninitialized memory in 2way engine unit tests +- Updated PVPlayerEngine::ReleaseMetadataValues to properly handle clip index +argument +- Fix for running a test number multiple times in makefile target for running +parallel player engine tests +- OMX Encoder node returns failure if OMX components returns Failure for +"OMX_IndexConfigCommonRotate" parameter +- Remove tests not applicable for OpenCORE +- MediaScanner has some API calls which are missing the interface +- Cap lower bound player engine watchdog timer duration to default value +- Enable File-writer for Mp4 composer node +- Early and Late Sync Margins changed for better AV Sync + + +=============================================================================== +2009-11-08 OpenCORE 2.06 + +New Features +- Add support for the PLS playlist file format for use with Shoutcast +- Adding code to benchmark encoding/decoding operation in the OMX component +- Add support for junit-like XML log output to test framework +- AAC utility getaacaudioinfo - add support for adts clips parsing +- Add support in playerdriver for RTSP streaming based on an input SDP file. +- Player engine unit test needs to support a list of test case ranges +- Add support for authoring btrt atom in mp4 composer to record bitrate +information. +- Unit test logger option unification +- Add SetDuration capability and new command status code in the base node +- Add build macro for turning compiler warnings into errors in Android.mk files +- New color conversion library suite for YUV420 to YUV422 conversion; supports +basic conversion as well as 90 and 270 degree rotation +- Add communication between OMXEncNode and Composer node for MaxBitRate and +DecodingBufferDB +- Support PVMF_MIME_H264_RAW where decoder config info is not always available +before the actual decoding start +- Support for YUV422 to OMX encoder components (M4V and AVC) +- Enable track selection helper to choose the OMX component used for each track +- Changes in PlayerEngine, FMU, and source nodes to allow retrieval of +thumbnails for protected content +- Gapless audio support at the file format and source node level + +Improvements +- Change the default behavior of the local makefiles to flag compiler warnings +as errors and provide a new flag to disable it +- AMR-NB modifications from AOSP +https://review.source.android.com/10904 +https://review.source.android.com/10905 +https://review.source.android.com/10906 +- Eliminate memcopies of output buffers in omx components (where possible) +- Move helper functions ( MoveCmdToCurrentQueue and MoveCmdToCancelQueue ) to +base node +- Add logic to the OMX encoder to choose another component if one fails +- Update the logic in the encoder node when choosing an OMX encoder +- Track selection metadata ("track-info/selected") needs to be added in AAC/AMR + and MP3 nodes +- Code size reduction +- Ignore pause and seek for live streaming +- New player engine test content +- Add API to 2Way engine to support selection of codecs and their preference +order +- Port OMXBaseNode, OMXVideoNode and OMXAudioNode to new Node Interface +- Build system support for ARM_GCC_V4 from AOSP +https://review.source.android.com/9668 +- Add ID3V2 metadata support in mp4 parser libary defined by 3GPP Rel 7. Move +all metadata related operations from MP4 PN to library +- Variable _mp4ErrorCode to UNSUPPORTED_FILE_TYPE for any brand type in +mpeg4file.cpp should not be set +- Encoder nodes should be added only for uncompressed MIO in 2way engine +- PV OMX component returns invalid supported profile/level pair +- Removing memory leaks in MDBS +- Create Generic 2Way Pause/Resume unit test +- Add insert_element() and clear() methods to OSCL linked list +- Update Player developers guide for CancelCommand and CancelAllCommands error +return values +- Remove a check in sliding_window_process to make avc decoder tolerate an +error condition and continue decoding +- Remove YUV buffer alignment calculations from the OMX decoder node. This is +currently done in the OMX components +- Add the ability to report info and error events from the author MIOs +- Modifying current command queue and cancel command queue to a single command +in the base node +- Refactor RTSP client engine node for cleaner interfacing with streaming +manager node +- Adding support for configuring the number of output buffers as a part of +dynamic port reconfiguration in omx test app +- Refactor MP3FFParserNode to use the base node implementation +- Refactor DownloadManager Node to use the base node implementation +- Refactor MP4 FF Parser Node to use the base node implementation +- Add CallNativeSetSize() API for OSCL File +- Change H.263 encoding default GOB header interval to 0 + +Bugs Fixed +- Track IDs are huge in particular mp4 clip causing crash +- Source node's handling of CPM cmds in Reset is incorrect +- [PDL] Download resume doesn't work if server response doesn't include the +Content-Length header. +- Android_camera_input.cpp method statusUpdate returns unhandled exception +- Hardcoded values in mp4a atom in the composer. (2030968) +- Download manager node uses shoutcast support by default +- atom 'meta' is not skipped +- Video playback is distorted (not normal) during playback for somes clips +- Need the ability to disable CPM in source nodes +- Crash in OsclTimer +- Nodes getting schedule extra number of times +- Update Android MIO to use authoring clock to achieve better AV sync in +encoding +- Implementation of trick play support +- Modify player engine's QueryInterface implementation +- Not able to play InValidId3Tags.mp3 content +- Fixes for building OpenCORE on android-x86 +- Streaming Manager node modification to make feature specific plugins +dynamically loadable +- Memory leak in video telephony engine +- OsclMemPoolResizableAllocator has been modified to take into account the +size specified via setMaxSzForNewMemPoolBuffer while expanding the mempool +- OMX AMR component fixed to support 3 Role strings properly +- Crash in video telephony engine +- PVAuthor Developer's Guide has been updated to clarify 3GP vs MP4 file +authoring +- RTSP amr-nb streaming can not start playback, need to seek then playback +start +- Fix the issues in Table of Contents implementation in Mp3 Parser +- Hang in one accepted/negotiated format 2way engine unit test +- Fix a problem where a node based on the base node implementation was not +getting resheduled to process the next command when multiple commands +(RequestPort in this case) were queued. +- PVMFRecognizer improvements, including multi-pass recognition etc. +- Send correct YUV format to the VMIO instead of PVMF_MIME_FORMAT_UNKNOWN +- By default, use current system time as creation & modification date in MP4 +composer node +- Audio issue in RTSP streaming caused by AMR decoder problem. +- Fix an issue where PVPlayerEngine::Prepare() never completes. If server +sends OPTIONS request to the PVPlayer, PVPlayer does not send SETUP request +to the server and PVPlayerEngine::Prepare() never completes +- Fix for reading from files using a file descriptor with an non-zero offset +- Fix potential crash during streaming session with multiple frames per packet +- Minor refactoring of integer datatype use +- Fix issue where an incorrect VOL header for MPEG4 video content results in +no video playback +- Add an extra condition for the multi-line check in an HTTP response header +- Move inlined code from header to cpp file for pvmf_event_handling +- Update the omx decoder node to reject a component if +iOMXComponentUsesFullAVCFrames is false +- Crash in video telephony engine cleanup +- Report a more appropriate failure status via the author engine when +underlying node commands fails +- Fix the fileoutput MIO to take into account the 422 UYVY format +- Fix for opening shared asset file handles multiple times +- Fileformat parser changes to support some specific mp4 content +- Limit the max size of album art to 3MB +- Changes in sending the Buffering Status +- Adding support for authoring moof clips for live sessions in mp4 composer +library +- PVPlayer crashes when trying to do Progressive Streaming of a specific +MP4 Clip +- Incorrect mime string comparision in pv2way datapath +- Fix for memory leak in mp4 local playback at GetMetaDataValue +- Implement HandleExtensionAPICommands for OMXDecNode +- Change OMX enc node Reset() to return success even OMX comp GetState() +fails or returns bad states +- Treat OMX_EventError with OMX_ErrorInvalidState as if OMX client get an +OMX_EventCmdComplete indicating state transition failure +- Add CTOR in RepositionRequestStruct to init the members +- Fix for testcase 805 with local content +- Logging in PVME Test not working properly for threaded mode +- Thumbnail extraction when no sample present in stss atom +- MP3 frames may have different sampling rate or number of channels. So, +in the omx mp3 component, logic has been added to ensure that only decoding of +consistent frames is sent as output and silence will replace mismatched frames +- Content truncated while seeking specific YouTube clip +- Player Engine should not fail playback if the Source node does not support +Playback control interface +- Cleanup test input and output filenames used in 2way tests +- Error in video display while playing minimum size content (48*48) +- Valgrind error fixes +- Fix a bug in SPS length calculation +- PVME doesn't retrieve metadata properly if file has an invalid extension +- Wrong sequence numbers from video parser node +- Using RTCP SR reports to perform AV sync once, if server does not provide +rtp-info in PLAY response. +- Mp3 parsernode should pass source context to CPM plugins + + +=============================================================================== +2009-08-06 OpenCORE 2.05 + +New Features +- Helper function to retrieve extended messages from command responses. +- Support for eAAC+ encode in the pvAuthor engine. +- Add conversion operations to OSCL_String classes. +- RTSPT support (3GPP streaming over TCP). To test, replace "rtsp" with "rtspt" +in the control URL (in source URL or SDP file). It is assumed that the user has +access to a server with TCP streaming capability. +- PV Metadata Engine (ME). This engine is targeted at applications that want +to retrieve metadata for any given clip in a generic manner. Typically, a lot +of these applications would like to scan large batches of content. Since ME +is mainly targeted at apps like mediascanner, where speed is the most important +factor, thumbnail extraction is not supported. For applications that do want +to extract thumbnails in a generic manner along with the metadata, PV's +FrameAndMetadata Utility (FMU) is recommended instead. +- 2way Lip-Sync unit test cases. + +Improvements +- A new base node implementation is introduced for the purpose of + refactoring and consolidating common logic in the nodes. The changes + will improve maintainability and make it easier to create new nodes. + Further documentation will be released in the future providing guidelines + for authoring nodes. +- The following existing nodes were refactored to utilize the base node + implementation mentioned above: AAC, AMR, and WAV parser nodes. +- Replace CodecSpecifier with PVMFFormatType. +- Move EventHandlerProcessing method to PVMFOMXBaseDecNode class. +- Change method type from "protected" to "private" in OMX derived classes +(videodec node and audiodec node). +- Adding robustness to avcdecoder to verify PPS and SPS parameters. +- Display status of every test case after it finishes in 2way unit test app. +- Add support to H.245 version 10. +- OMX node - Implement interleaved NAL sizes (to replace NAL start codes) in +omx buffers carrying AVC frames. +- AMR-WB contributions to enable building in "C": +https://review.source.android.com/10014 +https://review.source.android.com/10015 +https://review.source.android.com/10016 +https://review.source.android.com/10017 +https://review.source.android.com/10018 +- AMR-NB contributions to enable building in "C": +https://review.source.android.com/10297 +https://review.source.android.com/10301 +https://review.source.android.com/10302 +https://review.source.android.com/10303 +- Update OsclFileStats to track total time taken instead of only the +maximum time per operation. +- Rename OMX master core methods to avoid linking conflicts. +- Pass key MOUT_VIDEO_SUBFORMAT_KEY to the video MIO of FMU. +- Remove Direct Render Mode from mp4 composer library. +- AMR-NB and AMR-WB inline assembly is being re-enabled after a bug +in the QEMU assembly translation has been fixed. +- Modification of MIOs to take all configuration parameters at once. +- Move OMX input and output buffer ctrl structure away from data buffers. +- Enable byte-stream (H264-RAW) format decoding in OMX dec node. +- PVMFInfoTrackDisable information event should be report to java application. +- Retrieve the PLATFORM version at run time for the Android UserAgent string. +- OMX audio and video dec nodes need to be able to handle PortSettingsChanged +event with argument OMX_ALL. +- PVMFMediaClock latency handling improvement. +- AAC decoder creates artifacts when decoding clip. +- Modify MP4 composer node to do sample adds to mp4 composer lib in a separate +thread. +- Add support for VIDEO_ENCODER_H264 in authordriver. +- Author major brand "3gp5" if 3gp clip has TIMED-TEXT track. +- No interleaving of mp4 files for just one track. +https://review.source.android.com/10510 +- Return non-zero code when we detect a memory leak during unit tests. +- Add "3g2a", "3g2b" and "3g2c" as compatible branch in all content authored +by PvAuthor SDK. +- Add support for OMX_COLOR_FormatYCbYCr. +- Remove unneeded libraries being linked against individual shared libraries. +- Exclude empty directories and unncessary build files from OpenCORE. +- In OMX base node, turn the InputBufCtrlStruct from a struct into a class +- Updates to pvmf_return_codes.pdf, pvplayer_developers_guide.pdf, +omx_decoder_test_app_guide.pdf, and omx_encoder_test_app_guide.pdf. + +Bugs Fixed +- Repositioning takes a long time for YouTube videos after a few +repositions. +- Crash in CPVH223Multiplex::Stop(). +- PlayerEngine cannot finish a playback session after repeated pause +and resume near EndOfStream. +- Allow file path to be passed to the pvPlayer SDK on Android. +- Add a new constructor for the AVCSampleEntry to be used when parsing the +encv atom +https://review.source.android.com/9683 +- MP3 DurationCalcAO logic needs to moved to a place during Prepare and not +Init. +- Change PV_GET_ROW definition in M4V decoder. +- Player Engine unit test TC 55 and 56 has memory leaks +- Crash in authordriver if InitializeForThread fails. +- Crash in playerdriver if InitializeForThread fails. +- Potential memory leak in OMX encoder node. +- Memory leaks in AAC file parser node & lib +- FindFirst returns wrong element type when find a directory in android +- Intermittent timeouts on 2way unit tests +- Incorrect DeBlocking logic +- AVC Clip Specific Issue: (Play till EOS) OR (Reposition to near EOS) The +video gets stuck at near EOS +- iTunes genre is not parsed correctly +- Youtube : AV sync is lost after a seek when playing youtube contents +- Crash after recording one minute of Video when duration is specified +- Tracknumber metadata key string should be consistent through out all nodes +- Possible race condition in singleton lock in omx_init +- CPV2WayDatapath::GetPortFormatType() selects least preferred type +- AAC OMX decoder component needs to process whole audio config buffer +- Modify MP3Parser to make seek to 0 a special case and do not use XING header +for calculating file offset +- AAC Decoder should not try decode any AAC+ clip whose final sampling freq +is > 48 KHz. Should default to AAC in these cases. +- Update OMX encoder node to calculate the correct output buffer size in case +the encoder has multiple roles. +- OMX Encoder MPEG4 unit test fix +- Setting AMR_NB bitrate to GSM_AMR_4_75 will fail prepare. +- AuthorEngine should return Success incase Stop is called in +PVAE_STATE_INITIALIZED state. +- OMX M4V encoding drops the first I-frame +- VIDEO_INTERLEAVE_BUFFER_SIZE is too short for some buffers when encoding +D1 resolutions +- Occasional audio glitch in MP3 parser during repositioning +- OMX tests for AMR give seg fault on android +- pvPlayer sends incorrect HTTP Range header +http://code.google.com/p/android/issues/detail?id=3031 +- PDL/PS - Fix the Mp4 Parser node to pass the correct timestamp to PE node +in RequestResumeNotification during Underflow condition +- H.245 TerminalCapabilitySet (TCS) and MasterSlaveDetermination (MSD) +requests must be sent before any other H.245 messages. +- Logic to set iKeepDroppingMsgsUntilMarkerBit to false in AMR RTSP streaming +- 2way tests hanging when run in Android emulator +- Sound Recorder: Incorrect Duration of clip sometimes observed when sdcard is +full +- Memory leak in PV2WayMIO +- Playerengine needs to be updated to return success even if there are no keys +for GetMetadataValue +- Correct the Android RTSP UserAgent string +- Author Engine : Don't access the queue element without checking its queue +size +- If SSRC is not provided in setup response, then pvplayer cleint doesn't send +firewall packets to the server +- GetMetadataValues returns invalid number of entries +- Modify AUT to parse authored files and validate the files as much as possible +- Eliminate media layer node in case of RTSP streaming +- AAC timestamps provided to OMX component may be wrong +- Clean up warnings and some negotiate parameter changes from omx dec & enc +test apps +- Fix valgrind issue reported with android simulator in omx base node +- Add more supported rate control types in pv_video_encnode_extension.h +- Memory leak in player engine test case 807 +- Addressed compiler warnings in PVME +- nBufferAlignment of OMX_PARAM_PORTDEFINITIONTYPE is initialized to negative +value when playing clip on android using qcom decoders +- MP3 parser crash +- pvplayer_engine_test is detecting 'rtspt_test.sdp' as a url instead a local +file +- Count of command line arguments being read in PVME Test App is incorrect +- Player engine test case 1307 fails when run with a mp4 file containing 3GPP +timed text track +- PVMFInfoDataReady event being sent to the engine after the unit test calls +stop +- PlayerEngine doesn't free reference to PVMFDataSourceNodeRegistryInitInterface +- Combine the AMR if statement in pv_omxmastercore.cpp +- Player Engine unit test case 154 fails on execution +- Author Engine unit test cases 101-105 fail +- Add new return code PVMFErrContentInvalidForProgressivePlayback for a +NOT_PROGRESSIVE_STREAMABLE content +- Add USE (AL2, AL3) to 2way test files +- H223 2way test not being run +- Avoid calling CCYUV422toYUV420::New() for each thumbnail +- Author engine unit test case 101 fails +- Ignore encoding flaw, which generates aspec_ratio of value 0 in file +codecs_v2\video\m4v_h263\dec\src +- Memory leaks in pvmf_mio_fileinput.cpp and performance improvement in mp4 +composer node +- Do not cancel Init() immediately in case of 3gpp streaming +- Transferring MP3 with invalid ID2 tags crashes mediaScanner + + +=============================================================================== +2009-05-17 OpenCORE 2.04 + +New Features +- Create external download datastream An external download datastream is +introduced to allow for an external entity to pass a datastream interface +to the player SDK. The external entity is responsible for doing the actual +download of the media data. Full support in Android is not complete until +playerdriver changes and more unit testing is done. +- Fixed cache option in Oscl_File +Adding an option to configure the Oscl file cache to use one or more fixed +caches in addition to the movable cache. +- Modify author engine to contain a notion of "authoring clock" +Author engine has the option to pass an "authoring clock" to media input +components so that they can use this to sync audio and video timestamps. +Author engine has been modified to own a PVMFMediaClock. Author engine +provides a pointer to its to data source node (media input node typically) +at the end of author engine Init cycle, using PVMF_AUTHORING_CLOCK_KEY. +No media input component changes were done. All media input components +used in author engine unit test currently operate from a file and have no +need for such a clock, but some device media input components can make use +of the clock if needed in the future, since author engine will pass the +clock pointer all the time to data sources. +- Shoutcast (of MP3) support +Shoutcast support of MP3 and internet radio streaming is added. +- Enable AAC PDL Support +More robust support of PDL of AAC content, including underflow handling. +- Add support for 3GPP2 speech (EVRC, QCELP etc) in MP4 FF library +Support for the 3GPP2 speech codecs is added at the file format library +level. No 3GPP2 speech codecs are added. +- OpenMAX encoder and decoder unit test suite +- Use external filehandle in Android +- Introduce new macro to android makefiles to enable 2way + +Improvements +- Add support for "all" metadata key in CPM plugins. This feature provides + a single key to request that all available metadata be returned. +- Add support for OMX_ColorFormatCbYCrY +- OMX video dec node now sets the codec parameters (width/height etc.) in the + output port of the omx component. +- A loadable module for the OMA1 passthru CPM plugin now exists. It serves + as an example for creating a loadable CPM plugin. +- Compressed testcases have been added in Authior Engine unit tests to + author 3gp file from AVC and M4V and AAC bitstreams +- Added checks to verify that the PCM output of the mp3 frame will not exceed + the output buffer size, so the mp3 decoder / OMX component is nore robust. +- Removed unnecessary "ComponentGetRolesOfComponent" methods from OMX + components. +- Restored "/x-pvmf/ff-mux/mp4" MIME Type in Author engine. +- Modified the Initial AVC buffers so that the image that appears initially + is black (not green/pink) if I-frame is missing. +- Fixed the IFrameInterval setting in the OpenMAX video encoder node. +- Added the ability to pass a peer PvmiCapabilityAndConfig interface to + the Media I/O (MIO) components using the Capability Exchange. The purpose + is to allow the MIO components to set and get parameters (i.e., drive the + process) rather than on relying on the media output node to do it. +- Added checks to the OMX components to verify that the buffer size + (in allocate/use buffer) (nAllocLen) is adequate (i.e. >= than nBufferSize) +- Updated OMX components so that standard component roles can be queried as + well as set. +- AMR-NB common library modified to mark the proper symbol exports and moved + some functions to encoder and decoder libraries instead of common. +- Updated h264 decoder to take advantage of the fact that there will be no + in-band SPS/PPS NALs for the mime Video dec node prevents in-band SPS/PPS + for the format PVMF_MIME_H264_VIDEO_MP4 +- Add macro for enabling build of pv test engine executables in Android +- Remove 12-bit, 24-bit, and 32-bit routines from Android libraries +- Modified OMX timestamps to be in in microseconds rather than milliseconds + as specified in the OMX spec 1.1.2. +- Improvements and workarounds for non-compliant OMX components +- Replace OPEN_FILE_ONCE_PER_TRACK macro with member variable +aOpenFileOncePerTrack in mp4ffparser lib +- 2way: send data fragment by fragment from parser side +- Added a new function to convert PVMFStatus to human friendly strings +- Implement logic to choose correct OMX component when decoding streaming +H264 +- OMX dec nodes should report error and not even call config parser if +config data is missing (but is required by the format) +- Update playerdriver.cpp to send "disable-firewall-packets" KVP key based +on system Android property + +Bugs Fixed +- Moov atom is not being written into .3gp file if Author driver does not + close file handle. +- omx mp4 component in no-marker-bit mode crashes when playing a certain clip +- Error handling incase of input other then 8K AMR +- Add PVReleaseInterface method to OMX shared library interfaces + (components + main) +- pull sdcard while recording causes media server to crash +- Changes to buffering status notifications while streaming +- OMX nodes should not send repositioning request to OMX component until + config data has been processed by OMX components +- Crash in the author SDK as part of engine Reset +- If SSRC is not provided in setup response, then pvplayer client doesn't + send firewall packets to the server +- PVAuthorEngineNodeUtility::NodeCommandCompleted does not check whether + iCmdQueue is empty +- AMR Local Playback -> FF to EOS when repeat song is on will cause a force + crash +- some source nodes will put same timestamp for DataTS in old stream id + and DiscardTS +- Change pv omx encoder node to default iOMXComponentNeedsNALStartCodes to + false and do sanity check +- When reconfig happen,SinkNode should send reconfig notification with + FormatSpecificInfo to MIO +- Race condition - If port settings event and node stop command arrive + simultaneously - omx component may fail port flush command +- Mp3FFParserNode: Memory leak in Duration Calculator +- Playback clock starts even before PlayerEngine Start( ) is issued +- Clip plays beyond EOS. Fixed setting of the actual normal play time (NPT) + when repositioning. +- Modified OSCL and player driver handling of external file handles in the + player. +- MP3 PS - Repositioning is not working properly +- MP3 Parser needs to validate consecutive mp3 headers before parsing starts +- Crash in MIO component due to setPeer(NULL) is not called +- Improvements and robustness in thumbnail generation from normal and + corrupted clips +- Improvements in stability of Author Engine Unit tests when using OMX + encoder node +- Modify OSCL Mempool to assert when a buffer is deallocated back to + mempool twice in a row +- Fix a possible race condition in omx proxy threads. +- H263 decoder (OMX version) needs to remove the DEFAULT width-height + initialization +- Oscl file cache assert when reading binary file in text mode +- AAC and MP3 decoders have ARMv4 incorrect defines on normalization routines. + (see https://review.source.android.com/Gerrit#change,9668) +- AMR component roles do not distinguish between AMR_NB and AMR_WB +- OSCL shared library avoid dlopen() leaking in case of failure(dlsym() fails) +- Mp3 Clip hangs for some time when repositioned near to the end +- PV_atof will return a value that is larger than it should be if the input +string has a CR at the end +- Sequence number rollover in RTP info param during prolonged RTSP streaming + + +=============================================================================== +2009-03-31 OpenCORE 2.03 + +Improvements +- Enable OpenCORE on master - part 2 + +=============================================================================== +2009-03-10 OpenCORE 2.02 + +******** + There is minor version number nomenclature change where the + minor version is now two digits. So the previous releases + in the new nomenclature are 2.00 (2.0) and 2.01 (2.1). The + new release is 2.02, which is a minor version increment beyond + the previous release. +******** + +New Features +- AMR-WB support added to the OMX encoder node so that it can utilize + an OMX AMR-WB encoder component if it is part of the OMX core. +- Buffer allocator mechanism allowing the Media I/O components to + supply buffers to the OMX decoders. This method is especially useful + as an alternative way to allocate video buffers. Details can be + found in the new document "Guide to Supplying Decoder Buffers from + the MIO Component" in the file mio_decoder_buffer_allocation_guide.pdf + in the top-level doc directory. + +Improvements +- Resolution of Valgrind and static analysis warnings in player and author +- Improvements in support for .mov files in MP4 FF Parser(relaxed some checks). +- Modified OMX encoder node to allow setting the AMR bitrate + based on an extension interface value. +- Fix inconsistencies in OSCL find method related to inclusion of the + directory name with the filename. +- Improvement in PVMFInfoErrorHandlingComplete in the player datapath +- Refactor of the Protocol Engine node to support a plugin architecture. + This improves extensibility of the module for new features in the future. +- Introduce QueryInterfaceSync in PVMFNodeInterface and "all" metadata key +- AMR NB and WB have conflicting meaning for frame_type and mode elements +- Change the default settings related to caching for Oscl_File when + using PVFile within the fileformat parsers. +- Replace test.mp4 with interop clip +- Update of tests for support for progressive download of AMR +- OMX Khronos header files (Omx_Core.h, Omx_Component.h) capitalization + changed to match that from the Khronos (previously they were all lowercase). + +Bugs Fixed +- Memory leak when running GCF TC212 (2way-related) +- MediaClockConverter divided by zero caused by timescale 0 +- MP4 composer node destructor memory corruption fixed. +- Fix for intermittent crash in player engine TC 105 +- OMX dec node did not reset all the internal state during + Reset processing. + + +=============================================================================== +2009-02-26 OpenCORE 2.1 (2.01) + +New Features +* OpenMAX Codec-related: + - Introduced the OMXConfigParser API to help in determining + which OpenMAX components can support the input bitstream. + It is used to narrow the list of candidate OpenMAX components + to be used for playback. See the OpenMAX Core Integration Guide + document in the doc directory for more information. + - Added OMX AAC encoder support in the OMX encoder. + - Modified to use separate component roles for AMR-NB and AMR-WB as + described in the OpenMAX IL spec version 1.1.2. + - Added support for a new buffer format for H.264/AVC decode and + encode to allow passing multiple NALs in a single buffer. + The format uses OMX_OTHER_EXTRADATA structure defined in + section 4.2.33 of the OpenMAX IL spec version 1.1.2 to pass + NAL lengths. See the OpenMAX Core Integration Guide document + in the doc directory for more information. +* Author-related: + - Added support for authoring files with AAC audio. + - Added support for authoring AMR-WB audio to MP4/3GP files and + IETF storage format. + - Added support for writing to an open file descriptor as an option + instead of simply providing a filename. The file descriptor + option is useful for cases where another process needs to open + the file because of permissions. +* Added large file support in OSCL (i.e., 64-bit file size/offset + support) to handle files greater than 2 GiB on filesystems that + support it. +* Added rotation support in the 32-bit color-conversion class. + +Improvements +* Removed dynamically loaded modules from the prelink map to avoid + clutter and to make both the prelink map and loadable modules + easier to manage. There may be an issue if a single instance of + a process tries to load libraries not in the prelink map more than + 256 times + (See http://code.google.com/p/android/issues/detail?id=2042). +* Update to the MP3 Decoder to fix security issue (oCERT_2009-002, + CVE-2009-0475) +* Renamed the OSCL config directory linux_nj to android to match the + platform name. Replaced all references of nj with android in the + codebase. +* General security improvements found from static analysis in the + following areas: + - Buffer and type overruns and underruns + - Null pointer references +* Refactored the jitter buffer node into a more modular architecture + for better support of different streaming use-cases and protocols. +* Fixed an issue in the MP3 decoder when decoding for very of long + durations (over 2 GiB of data). +* General improvements found during 3GPP packet-switched streaming + interoperability testing. +* General improvements and resolution of issues found from module + level and engine (player, author, 2-way) level unit testing. + +New APIs / Behaviors +* Added support in the player engine to cancel a single pending + command using the CancelCommand API. See the player engine API + document for details. +* Renumbered the author test cases to avoid issues with + preprocessor conditionals changing the test numbers based on + settings. Now the test numbers shouldn't change. +* In the case of 3rd party OMX components that support multiple roles, + returns an error if the component cannot set the role parameter +* OMX components need to explicitly set nPortIndex parameter for + all appropriate parameters +* Added fix for buffering percentage notification in streaming + scenario (see https://review.source.android.com/Gerrit#change,8699) +* Updated omx shared library build configuration to separate component + registration from component build +* Added methods in baselibs to serialize and deserialize the UTF-16, + UTF-16LE, UTF-16BE strings +* Removed the iUseCPMPluginRegistry flag from the source data that was + previously used to enable the content policy manager. + Since the CPM pluginsare dynamically loaded, the flag is not + needed and was removed. See the playerdriver.cpp for details + of the change. + + +=============================================================================== +2009-01-26 OpenCORE 2.0 (2.00) + +New Features +- Consolidation of the clock logic into a common clock object + (PVMFMediaClock). More details will be provided in a + Tech note at a later time. +- Refactor MP4 Composer library +- omx component refactoring (Introducing base omx component class) +- OMX Encoder Support +- Check URIs for illegal characters and run escaping algorithm if any + are found. +- Support for 3GPP AssetInfo Metadata in Author SDK +- MP3 Dynamic TOC Construction +- Modify MPEG4/H.263 node/library to support arbitrary Decoder + Configuration Information (DCI) +- backward playback support for MP4 +- Refactoring Colorconversion from mpeg4 encoder and adding support + for YUV420SemiPlanar +- Refactor streaming manager node into feature specifc plugins +- Thread Safe Player Engine APIs and Thread Safe queue +- Adding capability to turn off AC prediction and change + IntraDCVlcThreshold for MPEG4 encoder library +- Dynamically populate recognizer registry +- add 2way support for OpenCORE +- Combine OMX audio dec node and Video Dec node +- OMX MasterCore +- Apply new RGB to YUV color conversion libraries to OMX encoder + components +- Use loadable modules in CPM +- Adding support for YUV420Semiplanar to avc encoder, m4v encoder and + author +- introduce dynamic loading of individual omx components + +Improvements +- Removal of all compiler warnings reported by Android compiler + Exception: unit test app code +- Module-level unit test fixes +- Various Valgrind errors and fixes +- Various Codesonar warnings and fixes +- various security audit and fixes +- various memory leak fixes +- various crash, hang fixes for specific test content or test cases +- Re-work Oscl Scheduler semaphore & lock +- Author Engine Error Handling Robustness +- Player Engine Error Handling Robustness +- Add capability of assembling partial frames and inserting NAL start + codes to OMX node +- The media I/O component configuration process needs to be improved. +- Fundamental change in behavior of repositioning during 3GPP + streaming +- Improvements to the PV FrameMetadataUtility [FMU] +- mp3 parser - duration calculation by walking file in background +- IOT merges from 2-way team +- Longevity issues with live streaming +- Local Playback MP3 file does not display attached art work +- Issues with Oscl Leave, Panic, and Assert +- Modify allocators to not leave in case of an alloc failure, but + instead have them return OsclErrNoMemory +- Conversion of strcmp and strstr usage to strncmp for non null + terminated Strings +- Change Oscl memory auditing from TLS-based to Singleton-based +- Buffer status report in a periodical manner to improve the app + awareness about how engine is running in low bandwidth for PDL/PS +- AVC Encoder Improved Rate Control +- State Transition: Remove implicit ThreadLogoff() from Nodes +- Include aac recognizer for Android +- Audit MP4 parser against new iTunes spec +- Replace PVMFSMSharedBufferAllocWithReSize allocator with + OsclMemPoolResizableAllocator +- Player Engine registry re-work + +New KVPs / APIs / API behaviors +- Change Download Manager Stop Command to Stop Download +- Add a KVP to configure jitter buffer inactivity run time from the + app +- OSCL Critical Error Handling +- Adding kvp in SM node to set rtsp_timeout timer in rtsp engine node +- Get rid of "getTrackOTIType" API in parser lib and switch mp4 parser + node to use "getTrackMIMEType". +- Adding capability to turn off AC prediction and change + IntraDCVlcThreshold for MPEG4 encoder library +- Deprecate PVMFCPMPluginLocalSyncAccessInterface +- Introduce new API in Engine to Release MetaData Values +- Use of PVMF format types in player registries +- Introduce new kvp key to set jitter buffer size +- Add a new meta data key to Mp3ParserNode to support channel mode + retrieval +- Support for taking in video bitrate and other params from a config + file, for uncompressed AVI test cases. +- Deprecate TLS-based memory audit +- Use KVP "nodedataqueuing_timeout" instead of compile time tuneable + "SYNC_POINT_DIFF_THRESHOLD" +- Please apply "mode=" for "x-pvmf/net/user-agent;valtype=char*" key. +- Change libpv*.so to libopencore_*.so +- Singleton and lock/unlock mechanism needed for OMX master core + globals +- In case of 3rd party OMX components that support multiple roles - + input dec format and output enc format needs to be specified +- OMX Core plugin code (for 3rd party omx cores integration) + +Known Issues +- Had to temporarily remove the doc directory because of conflicts + with Gerrit and PDF files. These will be uploaded again now that + Gerrit is updated. +- Additional documentation will be released as soon as possible. +- The OpenMAX encoder node is configuring the OpenMAX component with + the wrong format for AMR. It is using + OMX_AUDIO_AMRFrameFormatRTPPayload when it should be + OMX_AUDIO_AMRFrameFormatFSF. +- The OpenMAX encoder node is not handling Reset correctly in all + cases. + +=============================================================================== +2008-10-21 OpenCORE 1.0 (1.00) + +OpenCORE 1.0 is the initial contribution to AOSP. It has both release-1.0 +and android-1.0 tags. diff --git a/src/libs/opencore-amr/opencore/NOTICE b/src/libs/opencore-amr/opencore/NOTICE new file mode 100644 index 00000000..9d5d01c9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/NOTICE @@ -0,0 +1,269 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +Portions of the PacketVideo supplied code contain contributions which may be +covered by the following copyright statements: + + +/* ------------------------------------------------------------------- * + * MPEG-4 Simple Profile Video Decoder + * ------------------------------------------------------------------- * + * + * This software module was originally developed and/or edited by + * + * Paulo Nunes (IST / ACTS-MoMuSyS) + * Robert Danielsen (Telenor / ACTS-MoMuSyS) + * Luis Ducla-Soares (IST / ACTS-MoMuSys). + * Cor Quist (KPN / ACTS-MoMuSys). + * Minhua Zhou (HHI / ACTS-MoMuSys). + * + * in the course of development of the MPEG-4 Video (ISO/IEC 14496-2) standard. + * This software module is an implementation of a part of one or more MPEG-4 + * Video (ISO/IEC 14496-2) tools as specified by the MPEG-4 Video (ISO/IEC + * 14496-2) standard. + * + * ISO/IEC gives users of the MPEG-4 Video (ISO/IEC 14496-2) standard free + * license to this software module or modifications thereof for use in hardware + * or software products claiming conformance to the MPEG-4 Video (ISO/IEC + * 14496-2) standard. + * + * Those intending to use this software module in hardware or software products + * are advised that its use may infringe existing patents. The original + * developer of this software module and his/her company, the subsequent + * editors and their companies, and ISO/IEC have no liability for use of this + * software module or modifications thereof in an implementation. Copyright is + * not released for non MPEG-4 Video (ISO/IEC 14496-2) Standard conforming + * products. + * + * ACTS-MoMuSys partners retain full right to use the code for his/her own + * purpose, assign or donate the code to a third party and to inhibit third + * parties from using the code for non MPEG-4 Video (ISO/IEC 14496-2) Standard + * conforming products. This copyright notice must be included in all copies or + * derivative works. + * + * Copyright (c) 1996, 1997 + * + *****************************************************************************/ + + + +/**************************************************************************** + +SC 29 Software Copyright Licencing Disclaimer: + +This software module was originally developed by + Coding Technologies + +and edited by + - + +in the course of development of the ISO/IEC 13818-7 and ISO/IEC 14496-3 +standards for reference purposes and its performance may not have been +optimized. This software module is an implementation of one or more tools as +specified by the ISO/IEC 13818-7 and ISO/IEC 14496-3 standards. +ISO/IEC gives users free license to this software module or modifications +thereof for use in products claiming conformance to audiovisual and +image-coding related ITU Recommendations and/or ISO/IEC International +Standards. ISO/IEC gives users the same free license to this software module or +modifications thereof for research purposes and further ISO/IEC standardisation. +Those intending to use this software module in products are advised that its +use may infringe existing patents. ISO/IEC have no liability for use of this +software module or modifications thereof. Copyright is not released for +products that do not conform to audiovisual and image-coding related ITU +Recommendations and/or ISO/IEC International Standards. +The original developer retains full right to modify and use the code for its +own purpose, assign or donate the code to a third party and to inhibit third +parties from using the code for products that do not conform to audiovisual and +image-coding related ITU Recommendations and/or ISO/IEC International Standards. +This copyright notice must be included in all copies or derivative works. +Copyright (c) ISO/IEC 2003. + +*******************************************************************************/ + + +/************************************************************************** + +This software module was originally developed by + +Mikko Suonio (Nokia) + +in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard +ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an +implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools +as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives +users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this +software module or modifications thereof for use in hardware or +software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio +standards. Those intending to use this software module in hardware or +software products are advised that this use may infringe existing +patents. The original developer of this software module and his/her +company, the subsequent editors and their companies, and ISO/IEC have +no liability for use of this software module or modifications thereof +in an implementation. Copyright is not released for non MPEG-2 +NBC/MPEG-4 Audio conforming products. The original developer retains +full right to use the code for his/her own purpose, assign or donate +the code to a third party and to inhibit third party from using the +code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This +copyright notice must be included in all copies or derivative works. + +Copyright (c) 1997. + +***************************************************************************/ + + +/************************************************************************** + +This software module was originally developed by +Nokia in the course of development of the MPEG-2 AAC/MPEG-4 +Audio standard ISO/IEC13818-7, 14496-1, 2 and 3. +This software module is an implementation of a part +of one or more MPEG-2 AAC/MPEG-4 Audio tools as specified by the +MPEG-2 aac/MPEG-4 Audio standard. ISO/IEC gives users of the +MPEG-2aac/MPEG-4 Audio standards free license to this software module +or modifications thereof for use in hardware or software products +claiming conformance to the MPEG-2 aac/MPEG-4 Audio standards. Those +intending to use this software module in hardware or software products +are advised that this use may infringe existing patents. The original +developer of this software module, the subsequent +editors and their companies, and ISO/IEC have no liability for use of +this software module or modifications thereof in an +implementation. Copyright is not released for non MPEG-2 aac/MPEG-4 +Audio conforming products. The original developer retains full right to +use the code for the developer's own purpose, assign or donate the code to a +third party and to inhibit third party from using the code for non +MPEG-2 aac/MPEG-4 Audio conforming products. This copyright notice +must be included in all copies or derivative works. +Copyright (c)1997. + +***************************************************************************/ + + +------------------------------------------------------------------------------ + +MPEG-2 NBC Audio Decoder + "This software module was originally developed by AT&T, Dolby + Laboratories, Fraunhofer Gesellschaft IIS in the course of development + of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and + 3. This software module is an implementation of a part of one or more + MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 + Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio + standards free license to this software module or modifications thereof + for use in hardware or software products claiming conformance to the + MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software + module in hardware or software products are advised that this use may + infringe existing patents. The original developer of this software + module and his/her company, the subsequent editors and their companies, + and ISO/IEC have no liability for use of this software module or + modifications thereof in an implementation. Copyright is not released + for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original + developer retains full right to use the code for his/her own purpose, + assign or donate the code to a third party and to inhibit third party + from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. + This copyright notice must be included in all copies or derivative + works." + Copyright(c)1996. + +------------------------------------------------------------------------------ + + +/* + * snprintf.c - a portable implementation of snprintf + * + * AUTHOR + * Mark Martinec , April 1999. + * + * Copyright 1999, Mark Martinec. All rights reserved. + * + * TERMS AND CONDITIONS + * This program is free software; you can redistribute it and/or modify + * it under the terms of the "Frontier Artistic License" which comes + * with this Kit. + * + * 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 Frontier Artistic License for more details. + * + * + */ + +The "Frontier Artistic License" may be found at + http://www.spinwardstars.com/frontier/fal.html + + +/*---------------------------------------------------------------------------*/ + +/* + * Copyright (c) 2005 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/*---------------------------------------------------------------------------*/ + +/**@@@+++@@@@****************************************************************** +** +** Microsoft Windows Media +** Copyright (C) Microsoft Corporation. All rights reserved. +** +***@@@---@@@@****************************************************************** +*/ + + +------------------------------------------------------------------------------- +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +------------------------------------------------------------------------------- + + +------------------------------------------------------------------------------- +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +------------------------------------------------------------------------------- + diff --git a/src/libs/opencore-amr/opencore/README b/src/libs/opencore-amr/opencore/README new file mode 100644 index 00000000..d63d0f95 --- /dev/null +++ b/src/libs/opencore-amr/opencore/README @@ -0,0 +1,60 @@ + Welcome to OpenCORE + + http://www.opencore.net/ + +OpenCORE is the multimedia framework of Android originally contributed by +PacketVideo. It provides an extensible framework for multimedia rendering and +authoring and video telephony (3G-324M). + +The following an overview of the directory structure which includes a list of +the top-level directories along with a brief note describing the contents. + +__ + |-- android [Contains the components the interface OpenCORE with + | other parts of Android] + |-- baselibs [Contains basic libraries for data containers, MIME string + | handling, messaging across thread boundaries, etc] + |-- build_config [Contains top-level build files used to build the libraries + | outside of Android] + |-- codecs_v2 [Contains the implementations of PV's audio and video + | codecs as well as the OpenMax IL interface layer] + |-- doc [Contains the documentation required to interface with + | OpenCORE] + |-- engines [Contains the implementation of the player and author + | engines as well as a utility for metadata] + |-- extern_libs_v2 [Contains 3rd-party libraries used by OpenCORE. + | Currently this directory contains header files + | defining the Khronos OpenMax IL interface] + |-- extern_tools_v2 [Contains 3rd-party tools used to build OpenCORE + | indpendently of the Android build system] + |-- fileformats [Contains the libraries for parsing a variety of + | fileformats including mp4/3gp,mp3,wav,aac] + |-- modules [Contains build files for aggregating low-level libraries] + |-- nodes [Contains the OpenCORE framework "nodes", which is + | the abstraction used to implement independent multimedia + | processing units that can be connected in a flow graph] + |-- oscl [This is the Operating System Compatibility Layer which + | provides the mapping OS APIs as well as some basic + | data structures and utilities] + |-- protocols [Contains parsers and composers for a variety of network + | protocols such as HTTP, RTP/RTCP, RTSP, and SDP] + |-- pvmi [Contains fundamental definitions that make up OpenCORE. + | The directory name is an abbreviation of PacketVideo + | Multimedia Infrastructure] + |-- tools_v2 [Contains tools used to build the libraries outside of Android] + +Within each library, the following directory structure, with a few exceptions, +is implemented to organize the files: + +__ + |-- build + |-- make <- makefile to build outside of Android is here + |-- doc <- directory for any documentation specific to this lib + |-- include <- header files that are part of the external interface go here + |-- src <- source and internal header files of the library + |-- test <- test code (follows a similar structure) + |-- build + |-- make + |-- include + |-- src + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/Android.mk b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/Android.mk new file mode 100644 index 00000000..d978dbe2 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/Android.mk @@ -0,0 +1,76 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + src/add.cpp \ + src/az_lsp.cpp \ + src/bitno_tab.cpp \ + src/bitreorder_tab.cpp \ + src/c2_9pf_tab.cpp \ + src/div_s.cpp \ + src/gains_tbl.cpp \ + src/gc_pred.cpp \ + src/get_const_tbls.cpp \ + src/gmed_n.cpp \ + src/grid_tbl.cpp \ + src/gray_tbl.cpp \ + src/int_lpc.cpp \ + src/inv_sqrt.cpp \ + src/inv_sqrt_tbl.cpp \ + src/l_shr_r.cpp \ + src/log2.cpp \ + src/log2_norm.cpp \ + src/log2_tbl.cpp \ + src/lsfwt.cpp \ + src/lsp.cpp \ + src/lsp_az.cpp \ + src/lsp_lsf.cpp \ + src/lsp_lsf_tbl.cpp \ + src/lsp_tab.cpp \ + src/mult_r.cpp \ + src/norm_l.cpp \ + src/norm_s.cpp \ + src/overflow_tbl.cpp \ + src/ph_disp_tab.cpp \ + src/pow2.cpp \ + src/pow2_tbl.cpp \ + src/pred_lt.cpp \ + src/q_plsf.cpp \ + src/q_plsf_3.cpp \ + src/q_plsf_3_tbl.cpp \ + src/q_plsf_5.cpp \ + src/q_plsf_5_tbl.cpp \ + src/qua_gain_tbl.cpp \ + src/reorder.cpp \ + src/residu.cpp \ + src/round.cpp \ + src/shr.cpp \ + src/shr_r.cpp \ + src/sqrt_l.cpp \ + src/sqrt_l_tbl.cpp \ + src/sub.cpp \ + src/syn_filt.cpp \ + src/weight_a.cpp \ + src/window_tab.cpp + + +LOCAL_MODULE := libpv_amr_nb_common_lib + +LOCAL_CFLAGS := $(PV_CFLAGS) +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := + +LOCAL_SHARED_LIBRARIES := + +LOCAL_C_INCLUDES := \ + $(PV_TOP)/codecs_v2/audio/gsm_amr/amr_nb/common/src \ + $(PV_TOP)/codecs_v2/audio/gsm_amr/amr_nb/common/include \ + $(PV_INCLUDES) + +LOCAL_COPY_HEADERS_TO := $(PV_COPY_HEADERS_TO) + +LOCAL_COPY_HEADERS := \ + + +include $(BUILD_STATIC_LIBRARY) diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/build/make/local.mk b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/build/make/local.mk new file mode 100644 index 00000000..92b3f5ec --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/build/make/local.mk @@ -0,0 +1,68 @@ +# Get the current local path as the first operation +LOCAL_PATH := $(call get_makefile_dir) + +# Clear out the variables used in the local makefiles +include $(MK)/clear.mk + +TARGET := pv_amr_nb_common_lib + + +OPTIMIZE_FOR_PERFORMANCE_OVER_SIZE := true + +SRCDIR := ../../src +INCSRCDIR := ../../include + +SRCS := add.cpp \ + az_lsp.cpp \ + bitno_tab.cpp \ + bitreorder_tab.cpp \ + c2_9pf_tab.cpp \ + div_s.cpp \ + gains_tbl.cpp \ + gc_pred.cpp \ + get_const_tbls.cpp \ + gmed_n.cpp \ + grid_tbl.cpp \ + gray_tbl.cpp \ + int_lpc.cpp \ + inv_sqrt.cpp \ + inv_sqrt_tbl.cpp \ + l_shr_r.cpp \ + log2.cpp \ + log2_norm.cpp \ + log2_tbl.cpp \ + lsfwt.cpp \ + lsp.cpp \ + lsp_az.cpp \ + lsp_lsf.cpp \ + lsp_lsf_tbl.cpp \ + lsp_tab.cpp \ + mult_r.cpp \ + norm_l.cpp \ + norm_s.cpp \ + overflow_tbl.cpp \ + ph_disp_tab.cpp \ + pow2.cpp \ + pow2_tbl.cpp \ + pred_lt.cpp \ + q_plsf.cpp \ + q_plsf_3.cpp \ + q_plsf_3_tbl.cpp \ + q_plsf_5.cpp \ + q_plsf_5_tbl.cpp \ + qua_gain_tbl.cpp \ + reorder.cpp \ + residu.cpp \ + round.cpp \ + shr.cpp \ + shr_r.cpp \ + sqrt_l.cpp \ + sqrt_l_tbl.cpp \ + sub.cpp \ + syn_filt.cpp \ + weight_a.cpp \ + window_tab.cpp + +include $(MK)/library.mk + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/abs_s.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/abs_s.h new file mode 100644 index 00000000..04e383aa --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/abs_s.h @@ -0,0 +1,101 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: abs_s.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the abs_s function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef ABS_S_H +#define ABS_S_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 abs_s(Word16 var1); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* ABS_S_H */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/add.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/add.h new file mode 100644 index 00000000..3c65b43e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/add.h @@ -0,0 +1,98 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: add.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the add function. + +------------------------------------------------------------------------------ +*/ + +#ifndef ADD_H +#define ADD_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF Word16 add_16(Word16 var1, Word16 var2, Flag *pOverflow); + OSCL_IMPORT_REF Word16 add(Word16 var1, Word16 var2, Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _ADD_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/az_lsp.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/az_lsp.h new file mode 100644 index 00000000..cd2e91fe --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/az_lsp.h @@ -0,0 +1,105 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: az_lsp.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the function Az_lsp() + +------------------------------------------------------------------------------ +*/ + +#ifndef AZ_LSP_H +#define AZ_LSP_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define grid_points 60 + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 grid[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void Az_lsp( + Word16 a[], /* (i) : predictor coefficients (MP1) */ + Word16 lsp[], /* (o) : line spectral pairs (M) */ + Word16 old_lsp[], /* (i) : old lsp[] (in case not found 10 roots) (M) */ + Flag *pOverflow /* (i/o): overflow flag */ + ); + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _AZ_LSP_H */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/basic_op.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/basic_op.h new file mode 100644 index 00000000..791b8e96 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/basic_op.h @@ -0,0 +1,426 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: basic_op.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file includes all the basicop2.c functions' header files. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef BASIC_OP_H +#define BASIC_OP_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC)) +#include "basic_op_arm_gcc_v5.h" + +#else +#include "basic_op_c_equivalent.h" + +#endif + + + +#include "add.h" +#include "div_s.h" +#include "l_shr_r.h" +#include "mult_r.h" +#include "norm_l.h" +#include "norm_s.h" +#include "round.h" +#include "shr_r.h" +#include "sub.h" +#include "shr.h" +#include "l_negate.h" +#include "l_extract.h" +#include "extract_l.h" +#include "extract_h.h" +#include "l_deposit_h.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: mac_32 + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var3 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + L_var1_hi = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + L_var1_lo = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + L_var2_hi = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + L_var2_lo = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit mac operation resulted in overflow + + Returns: + L_var3 = 32-bit result of L_var3 + (L_var1 * L_var2)(Word32) + + */ + static inline Word32 Mac_32(Word32 L_var3, + Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 L_var2_hi, + Word16 L_var2_lo, + Flag *pOverflow) + { + Word16 product; + + L_var3 = L_mac(L_var3, L_var1_hi, L_var2_hi, pOverflow); + + product = mult(L_var1_hi, L_var2_lo, pOverflow); + L_var3 = L_mac(L_var3, product, 1, pOverflow); + + product = mult(L_var1_lo, L_var2_hi, pOverflow); + L_var3 = L_mac(L_var3, product, 1, pOverflow); + + return (L_var3); + } + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: mac_32_16 + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var3 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + L_var1_hi = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + L_var1_lo = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + var2= 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit mac operation resulted in overflow + + Returns: + L_var3 = 32-bit result of L_var3 + (L_var1 * var2)(Word32) + */ + + static inline Word32 Mac_32_16(Word32 L_var3, + Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 var2, + Flag *pOverflow) + { + Word16 product; + + L_var3 = L_mac(L_var3, L_var1_hi, var2, pOverflow); + + product = mult(L_var1_lo, var2, pOverflow); + L_var3 = L_mac(L_var3, product, 1, pOverflow); + + return (L_var3); + } + + + /*---------------------------------------------------------------------------- + Function Name : negate + + Negate var1 with saturation, saturate in the case where input is -32768: + negate(var1) = sub(0,var1). + + Inputs : + var1 + 16 bit short signed integer (Word16) whose value falls in the + range : 0x8000 <= var1 <= 0x7fff. + + Outputs : + none + + Return Value : + 16 bit short signed integer (Word16) whose value falls in the + range : 0x8000 <= var_out <= 0x7fff. + ----------------------------------------------------------------------------*/ + + static inline Word16 negate(Word16 var1) + { + return (((var1 == MIN_16) ? MAX_16 : -var1)); + } + + /*---------------------------------------------------------------------------- + + Function Name : shl + + Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill + the var2 LSB of the result. If var2 is negative, arithmetically shift + var1 right by -var2 with sign extension. Saturate the result in case of + underflows or overflows. + + Inputs : + var1 + 16 bit short signed integer (Word16) whose value falls in the + range : 0x8000 <= var1 <= 0x7fff. + + var2 + 16 bit short signed integer (Word16) whose value falls in the + range : 0x8000 <= var1 <= 0x7fff. + + pOverflow : pointer to overflow (Flag) + + Return Value : + var_out + 16 bit short signed integer (Word16) whose value falls in the + range : 0x8000 <= var_out <= 0x7fff. + ----------------------------------------------------------------------------*/ + + static inline Word16 shl(Word16 var1, Word16 var2, Flag *pOverflow) + { + Word16 var_out = 0; + + OSCL_UNUSED_ARG(pOverflow); + + if (var2 < 0) + { + var2 = -var2; + if (var2 < 15) + { + var_out = var1 >> var2; + } + + } + else + { + var_out = var1 << var2; + if (var_out >> var2 != var1) + { + var_out = (var1 >> 15) ^ MAX_16; + } + } + return (var_out); + } + + + /*---------------------------------------------------------------------------- + + Function Name : L_shl + + Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero + fill the var2 LSB of the result. If var2 is negative, arithmetically + shift L_var1 right by -var2 with sign extension. Saturate the result in + case of underflows or overflows. + + Inputs : + L_var1 32 bit long signed integer (Word32) whose value falls in the + range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + var2 + 16 bit short signed integer (Word16) whose value falls in the + range : 8000 <= var2 <= 7fff. + + pOverflow : pointer to overflow (Flag) + + Return Value : + 32 bit long signed integer (Word32) whose value falls in the + range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + + ----------------------------------------------------------------------------*/ + + static inline Word32 L_shl(Word32 L_var1, Word16 var2, Flag *pOverflow) + { + Word32 L_var_out = 0; + + OSCL_UNUSED_ARG(pOverflow); + + if (var2 > 0) + { + L_var_out = L_var1 << var2; + if (L_var_out >> var2 != L_var1) + { + L_var_out = (L_var1 >> 31) ^ MAX_32; + } + } + else + { + var2 = -var2; + if (var2 < 31) + { + L_var_out = L_var1 >> var2; + } + + } + + return (L_var_out); + } + + + /*---------------------------------------------------------------------------- + + Function Name : L_shr + + Arithmetically shift the 32 bit input L_var1 right var2 positions with + sign extension. If var2 is negative, arithmetically shift L_var1 left + by -var2 and zero fill the -var2 LSB of the result. Saturate the result + in case of underflows or overflows. + + Inputs : + L_var1 32 bit long signed integer (Word32) whose value falls in the + range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + var2 + 16 bit short signed integer (Word16) whose value falls in the + range : 8000 <= var2 <= 7fff. + + pOverflow : pointer to overflow (Flag) + + Return Value : + 32 bit long signed integer (Word32) whose value falls in the + range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + + ----------------------------------------------------------------------------*/ + + static inline Word32 L_shr(Word32 L_var1, Word16 var2, Flag *pOverflow) + { + Word32 L_var_out = 0; + + OSCL_UNUSED_ARG(pOverflow); + + if (var2 > 0) + { + if (var2 < 31) + { + L_var_out = L_var1 >> var2; + } + } + else + { + var2 = -var2; + + L_var_out = L_var1 << (var2) ; + if ((L_var_out >> (var2)) != L_var1) + { + L_var_out = (L_var1 >> 31) ^ MAX_32; + } + + } + + return (L_var_out); + } + + /*---------------------------------------------------------------------------- + + Function Name : abs_s + + Absolute value of var1; abs_s(-32768) = 32767. + + Inputs : + var1 + 16 bit short signed integer (Word16) whose value falls in the + range : 0x8000 <= var1 <= 0x7fff. + + pOverflow : pointer to overflow (Flag) + + Outputs : + none + + Return Value : + 16 bit short signed integer (Word16) whose value falls in the + range : 0x0000 <= var_out <= 0x7fff. + + ----------------------------------------------------------------------------*/ + + static inline Word16 abs_s(Word16 var1) + { + + Word16 y = var1 - (var1 < 0); + y = y ^(y >> 15); + return (y); + + } + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + + +#endif /* BASIC_OP_H */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/basic_op_arm_gcc_v5.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/basic_op_arm_gcc_v5.h new file mode 100644 index 00000000..5752171a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/basic_op_arm_gcc_v5.h @@ -0,0 +1,537 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: basic_op_arm_gcc_v5.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file includes all the GCC-ARM V5 basicop.c functions. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef BASIC_OP_ARM_GCC_V5_H +#define BASIC_OP_ARM_GCC_V5_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: L_add + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + L_var2 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit add operation resulted in overflow + + Returns: + L_sum = 32-bit sum of L_var1 and L_var2 (Word32) + */ + + static inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow) + { + register Word32 ra = L_var1; + register Word32 rb = L_var2; + Word32 result; + + OSCL_UNUSED_ARG(pOverflow); + + __asm__ volatile("qadd %0, %1, %2" + : "=r"(result) + : "r"(ra), "r"(rb) + ); + return (result); + + } + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: L_sub + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + L_var2 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit add operation resulted in overflow + + Returns: + L_diff = 32-bit difference of L_var1 and L_var2 (Word32) + */ + static inline Word32 L_sub(Word32 L_var1, Word32 L_var2, Flag *pOverflow) +{ + register Word32 ra = L_var1; + register Word32 rb = L_var2; + Word32 result; + + OSCL_UNUSED_ARG(pOverflow); + + __asm__ volatile("qsub %0, %1, %2" + : "=r"(result) + : "r"(ra), "r"(rb) + ); + + return (result); + } + + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: L_mac + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var3 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit add operation resulted in overflow + + Returns: + result = 32-bit result of L_var3 + (var1 * var2)(Word32) + */ + static inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) +{ + register Word32 ra = L_var3; + register Word32 rb = var1; + register Word32 rc = var2; + Word32 result; + + OSCL_UNUSED_ARG(pOverflow); + + __asm__ volatile("smulbb %0, %1, %2" + : "=r"(result) + : "r"(rb), "r"(rc) + ); + + __asm__ volatile("qdadd %0, %1, %2" + : "=r"(rc) + : "r"(ra), "r"(result) + ); + + return (rc); + } + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: L_mult + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + L_var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit add operation resulted in overflow + + Returns: + L_product = 32-bit product of L_var1 and L_var2 (Word32) + */ + + static inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow) +{ + register Word32 ra = var1; + register Word32 rb = var2; + Word32 result; + Word32 product; + + OSCL_UNUSED_ARG(pOverflow); + + __asm__ volatile("smulbb %0, %1, %2" + : "=r"(product) + : "r"(ra), "r"(rb) + ); + + __asm__ volatile("qadd %0, %1, %2" + : "=r"(result) + : "r"(product), "r"(product) + ); + + return(result); + } + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: L_msu + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var3 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit operation resulted in overflow + + Returns: + result = 32-bit result of L_var3 - (var1 * var2) + */ + static inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) +{ + register Word32 ra = L_var3; + register Word32 rb = var1; + register Word32 rc = var2; + Word32 product; + Word32 result; + + OSCL_UNUSED_ARG(pOverflow); + + __asm__ volatile("smulbb %0, %1, %2" + : "=r"(product) + : "r"(rb), "r"(rc) + ); + + __asm__ volatile("qdsub %0, %1, %2" + : "=r"(result) + : "r"(ra), "r"(product) + ); + + return (result); + } + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: Mpy_32 + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1_hi = most significant word of first input (Word16). + L_var1_lo = least significant word of first input (Word16). + L_var2_hi = most significant word of second input (Word16). + L_var2_lo = least significant word of second input (Word16). + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit multiply operation resulted in overflow + + Returns: + L_product = 32-bit product of L_var1 and L_var2 (Word32) + */ + static inline Word32 Mpy_32(Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 L_var2_hi, + Word16 L_var2_lo, + Flag *pOverflow) +{ + register Word32 product32; + register Word32 L_sum; + register Word32 L_product, result; + register Word32 ra = L_var1_hi; + register Word32 rb = L_var1_lo; + register Word32 rc = L_var2_hi; + register Word32 rd = L_var2_lo; + + + + OSCL_UNUSED_ARG(pOverflow); + + __asm__ volatile("smulbb %0, %1, %2" + : "=r"(L_product) + : "r"(ra), "r"(rc) + ); + __asm__ volatile("mov %0, #0" + : "=r"(result) + ); + + __asm__ volatile("qdadd %0, %1, %2" + : "=r"(L_sum) + : "r"(result), "r"(L_product) + ); + + __asm__ volatile("smulbb %0, %1, %2" + : "=r"(product32) + : "r"(ra), "r"(rd) + ); + + __asm__ volatile("mov %0, %1, ASR #15" + : "=r"(ra) + : "r"(product32) + ); + __asm__ volatile("qdadd %0, %1, %2" + : "=r"(L_product) + : "r"(L_sum), "r"(ra) + ); + + __asm__ volatile("smulbb %0, %1, %2" + : "=r"(product32) + : "r"(rb), "r"(rc) + ); + + __asm__ volatile("mov %0, %1, ASR #15" + : "=r"(rb) + : "r"(product32) + ); + + __asm__ volatile("qdadd %0, %1, %2" + : "=r"(L_sum) + : "r"(L_product), "r"(rb) + ); + + return (L_sum); + } + + + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: Mpy_32_16 + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1_hi = most significant 16 bits of 32-bit input (Word16). + L_var1_lo = least significant 16 bits of 32-bit input (Word16). + var2 = 16-bit signed integer (Word16). + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit product operation resulted in overflow + + Returns: + product = 32-bit product of the 32-bit L_var1 and 16-bit var1 (Word32) + */ + static inline Word32 Mpy_32_16(Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 var2, + Flag *pOverflow) +{ + + register Word32 ra = L_var1_hi; + register Word32 rb = L_var1_lo; + register Word32 rc = var2; + Word32 result, L_product; + + OSCL_UNUSED_ARG(pOverflow); + + __asm__ volatile("smulbb %0, %1, %2" + : "=r"(L_product) + : "r"(ra), "r"(rc) + ); + __asm__ volatile("mov %0, #0" + : "=r"(result) + ); + + __asm__ volatile("qdadd %0, %1, %2" + : "=r"(L_product) + : "r"(result), "r"(L_product) + ); + + __asm__ volatile("smulbb %0, %1, %2" + : "=r"(result) + : "r"(rb), "r"(rc) + ); + + __asm__ volatile("mov %0, %1, ASR #15" + : "=r"(ra) + : "r"(result) + ); + __asm__ volatile("qdadd %0, %1, %2" + : "=r"(result) + : "r"(L_product), "r"(ra) + ); + + return (result); + } + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: mult + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the add operation resulted in overflow + + Returns: + product = 16-bit limited product of var1 and var2 (Word16) + */ + static inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow) +{ + register Word32 ra = var1; + register Word32 rb = var2; + Word32 product; + Word32 temp; + + OSCL_UNUSED_ARG(pOverflow); + + __asm__ volatile( + "smulbb %0, %1, %2" + : "=r"(temp) + : "r"(ra), "r"(rb) + ); + __asm__ volatile( + "qadd %0, %1, %2\n\t" + "mov %0, %0, asr #16" + : "=&r*i"(product) + : "r"(temp), "r"(temp) + ); + + return ((Word16) product); + } + + static inline Word32 amrnb_fxp_mac_16_by_16bb(Word32 L_var1, Word32 L_var2, Word32 L_var3) +{ + register Word32 ra = L_var1; + register Word32 rb = L_var2; + register Word32 rc = L_var3; + Word32 result; + + __asm__ volatile("smlabb %0, %1, %2, %3" + : "=r"(result) + : "r"(ra), "r"(rb), "r"(rc) + ); + return (result); + } + + static inline Word32 amrnb_fxp_msu_16_by_16bb(Word32 L_var1, Word32 L_var2, Word32 L_var3) +{ + register Word32 ra = L_var1; + register Word32 rb = L_var2; + register Word32 rc = L_var3; + Word32 result; + + __asm__ volatile("rsb %0, %1, #0" + : "=r"(ra) + : "r"(ra) + ); + + __asm__ volatile("smlabb %0, %1, %2, %3" + : "=r"(result) + : "r"(ra), "r"(rb), "r"(rc) + ); + return (result); + } + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* BASIC_OP_ARM_GCC_V5_H */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/basic_op_c_equivalent.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/basic_op_c_equivalent.h new file mode 100644 index 00000000..62072a55 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/basic_op_c_equivalent.h @@ -0,0 +1,499 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: basic_op_c_equivalent.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file includes all the C-Equivalent basicop.c functions. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef BASIC_OP_C_EQUIVALENT_H +#define BASIC_OP_C_EQUIVALENT_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: L_add + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + L_var2 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit add operation resulted in overflow + + Returns: + L_sum = 32-bit sum of L_var1 and L_var2 (Word32) + */ + static inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow) + { + Word32 L_sum; + + L_sum = L_var1 + L_var2; + + if ((L_var1 ^ L_var2) >= 0) + { + if ((L_sum ^ L_var1) >> 31) + { + L_sum = (L_var1 >> 31) ? MIN_32 : MAX_32; + *pOverflow = 1; + } + } + + return (L_sum); + } + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: L_sub + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + L_var2 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit add operation resulted in overflow + + Returns: + L_diff = 32-bit difference of L_var1 and L_var2 (Word32) + */ + static inline Word32 L_sub(register Word32 L_var1, register Word32 L_var2, + register Flag *pOverflow) + { + Word32 L_diff; + + L_diff = L_var1 - L_var2; + + if ((L_var1 ^ L_var2) >> 31) + { + if ((L_diff ^ L_var1) & MIN_32) + { + L_diff = (L_var1 >> 31) ? MIN_32 : MAX_32; + *pOverflow = 1; + } + } + + return (L_diff); + } + + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: L_mac + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var3 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit add operation resulted in overflow + + Returns: + result = 32-bit result of L_var3 + (var1 * var2)(Word32) + */ + static inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) + { + Word32 result; + Word32 L_sum; + result = (Word32) var1 * var2; + if (result != (Word32) 0x40000000L) + { + L_sum = (result << 1) + L_var3; + + /* Check if L_sum and L_var_3 share the same sign */ + if ((L_var3 ^ result) > 0) + { + if ((L_sum ^ L_var3) >> 31) + { + L_sum = (L_var3 >> 31) ? MIN_32 : MAX_32; + *pOverflow = 1; + } + } + } + else + { + *pOverflow = 1; + L_sum = MAX_32; + } + return (L_sum); + } + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: L_mult + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + L_var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit add operation resulted in overflow + + Returns: + L_product = 32-bit product of L_var1 and L_var2 (Word32) + */ + static inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 L_product; + + L_product = (Word32) var1 * var2; + + if (L_product != (Word32) 0x40000000L) + { + L_product <<= 1; /* Multiply by 2 */ + } + else + { + *pOverflow = 1; + L_product = MAX_32; + } + + return (L_product); + } + + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: L_msu + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var3 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit operation resulted in overflow + + Returns: + result = 32-bit result of L_var3 - (var1 * var2) + */ + + static inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) + { + Word32 result; + + result = L_mult(var1, var2, pOverflow); + result = L_sub(L_var3, result, pOverflow); + + return (result); + } + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: Mpy_32 + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1_hi = most significant word of first input (Word16). + L_var1_lo = least significant word of first input (Word16). + L_var2_hi = most significant word of second input (Word16). + L_var2_lo = least significant word of second input (Word16). + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit multiply operation resulted in overflow + + Returns: + L_product = 32-bit product of L_var1 and L_var2 (Word32) + */ + static inline Word32 Mpy_32(Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 L_var2_hi, + Word16 L_var2_lo, + Flag *pOverflow) + { + Word32 L_product; + Word32 L_sum; + Word32 product32; + + OSCL_UNUSED_ARG(pOverflow); + L_product = (Word32) L_var1_hi * L_var2_hi; + + if (L_product != (Word32) 0x40000000L) + { + L_product <<= 1; + } + else + { + L_product = MAX_32; + } + + /* result = mult (L_var1_hi, L_var2_lo, pOverflow); */ + product32 = ((Word32) L_var1_hi * L_var2_lo) >> 15; + + /* L_product = L_mac (L_product, result, 1, pOverflow); */ + L_sum = L_product + (product32 << 1); + + if ((L_product ^ product32) > 0) + { + if ((L_sum ^ L_product) >> 31) + { + L_sum = (L_product >> 31) ? MIN_32 : MAX_32; + } + } + + L_product = L_sum; + + /* result = mult (L_var1_lo, L_var2_hi, pOverflow); */ + product32 = ((Word32) L_var1_lo * L_var2_hi) >> 15; + + /* L_product = L_mac (L_product, result, 1, pOverflow); */ + L_sum = L_product + (product32 << 1); + + if ((L_product ^ product32) > 0) + { + if ((L_sum ^ L_product) >> 31) + { + L_sum = (L_product >> 31) ? MIN_32 : MAX_32; + } + } + return (L_sum); + } + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: Mpy_32_16 + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1_hi = most significant 16 bits of 32-bit input (Word16). + L_var1_lo = least significant 16 bits of 32-bit input (Word16). + var2 = 16-bit signed integer (Word16). + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit product operation resulted in overflow + + Returns: + product = 32-bit product of the 32-bit L_var1 and 16-bit var1 (Word32) + */ + + static inline Word32 Mpy_32_16(Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 var2, + Flag *pOverflow) + { + + Word32 L_product; + Word32 L_sum; + Word32 result; + L_product = (Word32) L_var1_hi * var2; + + if (L_product != (Word32) 0x40000000L) + { + L_product <<= 1; + } + else + { + *pOverflow = 1; + L_product = MAX_32; + } + + result = ((Word32)L_var1_lo * var2) >> 15; + + L_sum = L_product + (result << 1); + + if ((L_product ^ result) > 0) + { + if ((L_sum ^ L_product) >> 31) + { + L_sum = (L_product >> 31) ? MIN_32 : MAX_32; + *pOverflow = 1; + } + } + return (L_sum); + + } + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: mult + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the add operation resulted in overflow + + Returns: + product = 16-bit limited product of var1 and var2 (Word16) + */ + static inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 product; + + product = ((Word32) var1 * var2) >> 15; + + /* Saturate result (if necessary). */ + /* var1 * var2 >0x00007fff is the only case */ + /* that saturation occurs. */ + + if (product > 0x00007fffL) + { + *pOverflow = 1; + product = (Word32) MAX_16; + } + + + /* Return the product as a 16 bit value by type casting Word32 to Word16 */ + + return ((Word16) product); + } + + + static inline Word32 amrnb_fxp_mac_16_by_16bb(Word32 L_var1, Word32 L_var2, Word32 L_var3) + { + Word32 result; + + result = L_var3 + L_var1 * L_var2; + + return result; + } + + static inline Word32 amrnb_fxp_msu_16_by_16bb(Word32 L_var1, Word32 L_var2, Word32 L_var3) + { + Word32 result; + + result = L_var3 - L_var1 * L_var2; + + return result; + } + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* BASIC_OP_C_EQUIVALENT_H */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/basicop_malloc.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/basicop_malloc.h new file mode 100644 index 00000000..4d94c4cd --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/basicop_malloc.h @@ -0,0 +1,107 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: basicop_malloc.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains constant definitions and external references to the stores + used by any arithmetic function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef BASICOP_MALLOC_H +#define BASICOP_MALLOC_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define MAX_32 (Word32)0x7fffffffL +#define MIN_32 (Word32)0x80000000L + +#define MAX_16 (Word16)0x7fff +#define MIN_16 (Word16)0x8000 + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern Flag Overflow; + extern Flag Carry; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/bitno_tab.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/bitno_tab.h new file mode 100644 index 00000000..b071c716 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/bitno_tab.h @@ -0,0 +1,134 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: bitno_tab.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file declares a tables in bitno_tab.c. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef BITNO_TAB_H +#define BITNO_TAB_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define BIT_0 0 +#define BIT_1 1 + +#define PRMNO_MR475 17 +#define PRMNO_MR515 19 +#define PRMNO_MR59 19 +#define PRMNO_MR67 19 +#define PRMNO_MR74 19 +#define PRMNO_MR795 23 +#define PRMNO_MR102 39 +#define PRMNO_MR122 57 +#define PRMNO_MRDTX 5 + + /* number of parameters to first subframe */ +#define PRMNOFSF_MR475 7 +#define PRMNOFSF_MR515 7 +#define PRMNOFSF_MR59 7 +#define PRMNOFSF_MR67 7 +#define PRMNOFSF_MR74 7 +#define PRMNOFSF_MR795 8 +#define PRMNOFSF_MR102 12 +#define PRMNOFSF_MR122 18 + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 prmno[]; + extern const Word16 prmnofsf[]; + extern const Word16 bitno_MR475[]; + extern const Word16 bitno_MR515[]; + extern const Word16 bitno_MR59[]; + extern const Word16 bitno_MR67[]; + extern const Word16 bitno_MR74[]; + extern const Word16 bitno_MR95[]; + extern const Word16 bitno_MR102[]; + extern const Word16 bitno_MR122[]; + extern const Word16 bitno_MRDTX[]; + extern const Word16 *const bitno[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/bitreorder_tab.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/bitreorder_tab.h new file mode 100644 index 00000000..48d8e086 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/bitreorder_tab.h @@ -0,0 +1,112 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: bitreorder_tab.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file declares a tables in bitreorder.c. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef BITREORDER_H +#define BITREORDER_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 numOfBits[]; + extern const Word16 reorderBits_MR475[]; + extern const Word16 reorderBits_MR515[]; + extern const Word16 reorderBits_MR59[]; + extern const Word16 reorderBits_MR67[]; + extern const Word16 reorderBits_MR74[]; + extern const Word16 reorderBits_MR795[]; + extern const Word16 reorderBits_MR102[]; + extern const Word16 reorderBits_MR122[]; + + extern const Word16 *const reorderBits[]; + extern const Word16 numCompressedBytes[]; + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/bytesused.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/bytesused.h new file mode 100644 index 00000000..f97beaef --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/bytesused.h @@ -0,0 +1,101 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: bytesused.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file declares a table BytesUsed. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef BYTESUSED_H +#define BYTESUSED_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const short BytesUsed[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/cnst.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/cnst.h new file mode 100644 index 00000000..b648eb7d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/cnst.h @@ -0,0 +1,129 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + INCLUDE DESCRIPTION + + This file contains the Speech code (encoder, decoder, and postfilter) + constant parameters. + + NOTE: This file must be synchronized with /gsm-amr/asm/include/cnst.inc file. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef _CNST_H_ +#define _CNST_H_ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define L_TOTAL 320 /* Total size of speech buffer. */ +#define L_WINDOW 240 /* Window size in LP analysis */ +#define L_FRAME 160 /* Frame size */ +#define L_FRAME_BY2 80 /* Frame size divided by 2 */ +#define L_SUBFR 40 /* Subframe size */ +#define L_CODE 40 /* codevector length */ +#define NB_TRACK 5 /* number of tracks */ +#define STEP 5 /* codebook step size */ +#define NB_TRACK_MR102 4 /* number of tracks mode mr102 */ +#define STEP_MR102 4 /* codebook step size mode mr102 */ +#define M 10 /* Order of LP filter */ +#define MP1 (M+1) /* Order of LP filter + 1 */ +#define LSF_GAP 205 /* Minimum distance between LSF after quan- */ + /* tization; 50 Hz = 205 */ +#define LSP_PRED_FAC_MR122 21299 /* MR122 LSP prediction factor (0.65 Q15) */ +#define AZ_SIZE (4*M+4) /* Size of array of LP filters in 4 subfr.s */ +#define PIT_MIN_MR122 18 /* Minimum pitch lag (MR122 mode) */ +#define PIT_MIN 20 /* Minimum pitch lag (all other modes) */ +#define PIT_MAX 143 /* Maximum pitch lag */ +#define L_INTERPOL (10+1) /* Length of filter for interpolation */ +#define L_INTER_SRCH 4 /* Length of filter for CL LTP search */ + /* interpolation */ + +#define MU 26214 /* Factor for tilt compensation filter 0.8 */ +#define AGC_FAC 29491 /* Factor for automatic gain control 0.9 */ + +#define L_NEXT 40 /* Overhead in LP analysis */ +#define SHARPMAX 13017 /* Maximum value of pitch sharpening */ +#define SHARPMIN 0 /* Minimum value of pitch sharpening */ + + +#define MAX_PRM_SIZE 57 /* max. num. of params */ +#define MAX_SERIAL_SIZE 244 /* max. num. of serial bits */ + +#define GP_CLIP 15565 /* Pitch gain clipping = 0.95 */ +#define N_FRAME 7 /* old pitch gains in average calculation */ + +#define EHF_MASK 0x0008 /* encoder homing frame pattern */ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _CNST_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/cnst_vad.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/cnst_vad.h new file mode 100644 index 00000000..6877a1bb --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/cnst_vad.h @@ -0,0 +1,133 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +**-------------------------------------------------------------------------** +** ** +** GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 ** +** R99 Version 3.2.0 ** +** REL-4 Version 4.0.0 ** +** ** +**-------------------------------------------------------------------------** +******************************************************************************** +* +* File : cnst_vad.h +* Purpose : Constants and definitions for VAD +* +******************************************************************************** +*/ +#ifndef cnst_vad_h +#define cnst_vad_h "$Id $" + +#define FRAME_LEN 160 /* Length (samples) of the input frame */ +#define COMPLEN 9 /* Number of sub-bands used by VAD */ +#define INV_COMPLEN 3641 /* 1.0/COMPLEN*2^15 */ +#define LOOKAHEAD 40 /* length of the lookahead used by speech coder */ + +#define UNITY 512 /* Scaling used with SNR calculation */ +#define UNIRSHFT 6 /* = log2(MAX_16/UNITY) */ + +#define TONE_THR (Word16)(0.65*MAX_16) /* Threshold for tone detection */ + +/* Constants for background spectrum update */ +#define ALPHA_UP1 (Word16)((1.0 - 0.95)*MAX_16) /* Normal update, upwards: */ +#define ALPHA_DOWN1 (Word16)((1.0 - 0.936)*MAX_16) /* Normal update, downwards */ +#define ALPHA_UP2 (Word16)((1.0 - 0.985)*MAX_16) /* Forced update, upwards */ +#define ALPHA_DOWN2 (Word16)((1.0 - 0.943)*MAX_16) /* Forced update, downwards */ +#define ALPHA3 (Word16)((1.0 - 0.95)*MAX_16) /* Update downwards */ +#define ALPHA4 (Word16)((1.0 - 0.9)*MAX_16) /* For stationary estimation */ +#define ALPHA5 (Word16)((1.0 - 0.5)*MAX_16) /* For stationary estimation */ + +/* Constants for VAD threshold */ +#define VAD_THR_HIGH 1260 /* Highest threshold */ +#define VAD_THR_LOW 720 /* Lowest threshold */ +#define VAD_P1 0 /* Noise level for highest threshold */ +#define VAD_P2 6300 /* Noise level for lowest threshold */ +#define VAD_SLOPE (Word16)(MAX_16*(float)(VAD_THR_LOW-VAD_THR_HIGH)/(float)(VAD_P2-VAD_P1)) + +/* Parameters for background spectrum recovery function */ +#define STAT_COUNT 20 /* threshold of stationary detection counter */ +#define STAT_COUNT_BY_2 10 /* threshold of stationary detection counter */ +#define CAD_MIN_STAT_COUNT 5 /* threshold of stationary detection counter */ + +#define STAT_THR_LEVEL 184 /* Threshold level for stationarity detection */ +#define STAT_THR 1000 /* Threshold for stationarity detection */ + +/* Limits for background noise estimate */ +#define NOISE_MIN 40 /* minimum */ +#define NOISE_MAX 16000 /* maximum */ +#define NOISE_INIT 150 /* initial */ + +/* Constants for VAD hangover addition */ +#define HANG_NOISE_THR 100 +#define BURST_LEN_HIGH_NOISE 4 +#define HANG_LEN_HIGH_NOISE 7 +#define BURST_LEN_LOW_NOISE 5 +#define HANG_LEN_LOW_NOISE 4 + +/* Thresholds for signal power */ +#define VAD_POW_LOW (Word32)15000 /* If input power is lower, */ +/* VAD is set to 0 */ +#define POW_PITCH_THR (Word32)343040 /* If input power is lower, pitch */ +/* detection is ignored */ + +#define POW_COMPLEX_THR (Word32)15000 /* If input power is lower, complex */ +/* flags value for previous frame is un-set */ + + +/* Constants for the filter bank */ +#define LEVEL_SHIFT 0 /* scaling */ +#define COEFF3 13363 /* coefficient for the 3rd order filter */ +#define COEFF5_1 21955 /* 1st coefficient the for 5th order filter */ +#define COEFF5_2 6390 /* 2nd coefficient the for 5th order filter */ + +/* Constants for pitch detection */ +#define LTHRESH 4 +#define NTHRESH 4 + +/* Constants for complex signal VAD */ +#define CVAD_THRESH_ADAPT_HIGH (Word16)(0.6 * MAX_16) /* threshold for adapt stopping high */ +#define CVAD_THRESH_ADAPT_LOW (Word16)(0.5 * MAX_16) /* threshold for adapt stopping low */ +#define CVAD_THRESH_IN_NOISE (Word16)(0.65 * MAX_16) /* threshold going into speech on */ +/* a short term basis */ + +#define CVAD_THRESH_HANG (Word16)(0.70 * MAX_16) /* threshold */ +#define CVAD_HANG_LIMIT (Word16)(100) /* 2 second estimation time */ +#define CVAD_HANG_LENGTH (Word16)(250) /* 5 second hangover */ + +#define CVAD_LOWPOW_RESET (Word16) (0.40 * MAX_16) /* init in low power segment */ +#define CVAD_MIN_CORR (Word16) (0.40 * MAX_16) /* lowest adaptation value */ + +#define CVAD_BURST 20 /* speech burst length for speech reset */ +#define CVAD_ADAPT_SLOW (Word16)(( 1.0 - 0.98) * MAX_16) /* threshold for slow adaption */ +#define CVAD_ADAPT_FAST (Word16)((1.0 - 0.92) * MAX_16) /* threshold for fast adaption */ +#define CVAD_ADAPT_REALLY_FAST (Word16)((1.0 - 0.80) * MAX_16) /* threshold for really fast */ +/* adaption */ + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/d_gain_c.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/d_gain_c.h new file mode 100644 index 00000000..99c25402 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/d_gain_c.h @@ -0,0 +1,118 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: d_gain_c.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : d_gain_c.h + Purpose : Decode the fixed codebook gain using the received index. + +------------------------------------------------------------------------------ +*/ + +#ifndef _D_GAIN_C_H_ +#define _D_GAIN_C_H_ +#define d_gain_c_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "gc_pred.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + /* + * Function : d_gain_code + * Purpose : Decode the fixed codebook gain using the received index. + * Description : The received index gives the gain correction factor + * gamma. The quantized gain is given by g_q = g0 * gamma + * where g0 is the predicted gain. To find g0, 4th order + * MA prediction is applied to the mean-removed innovation + * energy in dB. + * Returns : void + */ + void d_gain_code( + gc_predState *pred_state, /* i/o : MA predictor state */ + enum Mode mode, /* i : AMR mode */ + Word16 index, /* i : received quantization index */ + Word16 code[], /* i : innovation codevector */ + const Word16* qua_gain_code_ptr, /* i : Pointer to read-only table */ + Word16 *gain_code, /* o : decoded innovation gain */ + Flag *pOverflow + ); + +#ifdef __cplusplus +} +#endif + +#endif /* _D_GAIN_C_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/d_gain_p.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/d_gain_p.h new file mode 100644 index 00000000..04babd99 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/d_gain_p.h @@ -0,0 +1,81 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : d_gain_p.h +* Purpose : Decodes the pitch gain using the received index. +* +******************************************************************************** +*/ +#ifndef d_gain_p_h +#define d_gain_p_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" +#include "mode.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ************************************************************************** + * + * Function : d_gain_pitch + * Purpose : Decodes the pitch gain using the received index. + * Description : In case of no frame erasure, the gain is obtained + * from the quantization table at the given index; + * otherwise, a downscaled past gain is used. + * Returns : Quantized pitch gain + * + ************************************************************************** + */ + Word16 d_gain_pitch( /* return value: gain (Q14) */ + enum Mode mode, /* i : AMR mode */ + Word16 index, /* i : index of quantization */ + const Word16* qua_gain_pitch_ptr /* i : pointer to read-only tables */ + ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/d_plsf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/d_plsf.h new file mode 100644 index 00000000..dbefcba9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/d_plsf.h @@ -0,0 +1,190 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: d_plsf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the d_plsf_3.c and d_plsf_5.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef d_plsf_h +#define d_plsf_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" +#include "mode.h" +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 past_r_q[M]; /* Past quantized prediction error, Q15 */ + Word16 past_lsf_q[M]; /* Past dequantized lsfs, Q15 */ + } D_plsfState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /* + ************************************************************************** + * + * Function : D_plsf_reset + * Purpose : Resets state memory + * Returns : 0 on success + * + ************************************************************************** + */ + Word16 D_plsf_reset(D_plsfState *st, const Word16* mean_lsf_5_ptr); + + /* + ************************************************************************** + * + * Function : D_plsf_exit + * Purpose : The memory used for state memory is freed + * Description : Stores NULL in *st + * Returns : void + * + ************************************************************************** + */ + void D_plsf_exit(D_plsfState **st); + + /* + ************************************************************************** + * + * Function : D_plsf_5 + * Purpose : Decodes the 2 sets of LSP parameters in a frame + * using the received quantization indices. + * Description : The two sets of LSFs are quantized using split by + * 5 matrix quantization (split-MQ) with 1st order MA + * prediction. + * See "q_plsf_5.c" for more details about the + * quantization procedure + * Returns : 0 + * + ************************************************************************** + */ + void D_plsf_5( + D_plsfState *st, /* i/o: State variables */ + Word16 bfi, /* i : bad frame indicator (set to 1 if a bad + frame is received) */ + Word16 *indice, /* i : quantization indices of 5 submatrices, Q0 */ + CommonAmrTbls* common_amr_tbls, /* i : structure containing ptrs to read-only tables */ + Word16 *lsp1_q, /* o : quantized 1st LSP vector (M) Q15 */ + Word16 *lsp2_q, /* o : quantized 2nd LSP vector (M) Q15 */ + Flag *pOverflow /* o : Flag set when overflow occurs */ + ); + + /************************************************************************* + * + * FUNCTION: D_plsf_3() + * + * PURPOSE: Decodes the LSP parameters using the received quantization + * indices.1st order MA prediction and split by 3 matrix + * quantization (split-MQ) + * + *************************************************************************/ + + void D_plsf_3( + D_plsfState *st, /* i/o: State struct */ + enum Mode mode, /* i : coder mode */ + Word16 bfi, /* i : bad frame indicator (set to 1 if a */ + /* bad frame is received) */ + Word16 * indice, /* i : quantization indices of 3 submatrices, Q0 */ + CommonAmrTbls* common_amr_tbls, /* i : structure containing ptrs to read-only tables */ + Word16 * lsp1_q, /* o : quantized 1st LSP vector, Q15 */ + Flag *pOverflow /* o : Flag set when overflow occurs */ + ); + + /************************************************************************* + * + * FUNCTION: Init_D_plsf_3() + * + * PURPOSE: Set the past_r_q[M] vector to one of the eight + * past_rq_init vectors. + * + *************************************************************************/ + void Init_D_plsf_3(D_plsfState *st, /* i/o: State struct */ + Word16 index, /* i : past_rq_init[] index [0, 7] */ + const Word16* past_rq_init_ptr /* ptr to read-only table */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _Q_PLSF_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/div_s.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/div_s.h new file mode 100644 index 00000000..98aa0f9b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/div_s.h @@ -0,0 +1,101 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: div_s.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the div_s function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef DIV_S_H +#define DIV_S_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF Word16 div_s(Word16 var1, Word16 var2); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/dtx_common_def.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/dtx_common_def.h new file mode 100644 index 00000000..0daa965e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/dtx_common_def.h @@ -0,0 +1,96 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: dtx_common_def.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : dtx_common_def.h + Purpose : DTX definitions common to encoder and decoder + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef DTX_COMMON_DEF_H +#define DTX_COMMON_DEF_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define DTX_MAX_EMPTY_THRESH 50 +#define DTX_HIST_SIZE 8 +#define DTX_ELAPSED_FRAMES_THRESH (24 + 7 -1) +#define DTX_HANG_CONST 7 /* yields eight frames of SP HANGOVER */ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* DTX_COMMON_DEF_H */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/extract_h.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/extract_h.h new file mode 100644 index 00000000..2beff971 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/extract_h.h @@ -0,0 +1,130 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: extract_h.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32 ) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + L_var1 = Most significant word of input (Word16) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function returns the 16 MSB of the input, L_var1. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 extract_h (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) (L_var1 >> 16); +#if (WMOPS) + multiCounter[currCounter].extract_h++; +#endif + return (var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word16 extract_h(Word32 L_var1); diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/extract_l.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/extract_l.h new file mode 100644 index 00000000..820ab260 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/extract_l.h @@ -0,0 +1,129 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: extract_l.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32 ) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + L_var1 = Most significant word of input (Word16) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function returns the 16 LSB of the input, L_var1. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 extract_l (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) L_var1; +#if (WMOPS) + multiCounter[currCounter].extract_l++; +#endif + return (var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word16 extract_l(Word32 L_var1); diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/frame.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/frame.h new file mode 100644 index 00000000..1d0c6c10 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/frame.h @@ -0,0 +1,114 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +***************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +***************************************************************************** +* +* File : frame.h +* Purpose : Declaration of received and transmitted frame types +* +***************************************************************************** +*/ +#ifndef frame_h +#define frame_h "$Id $" + +/* +***************************************************************************** +* INCLUDE FILES +***************************************************************************** +*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ***************************************************************************** + * DEFINITION OF DATA TYPES + ***************************************************************************** + * Note: The order of the TX and RX_Type identifiers has been chosen in + * the way below to be compatible to an earlier version of the + * AMR-NB C reference program. + ***************************************************************************** + */ + + enum RXFrameType { RX_SPEECH_GOOD = 0, + RX_SPEECH_DEGRADED, + RX_ONSET, + RX_SPEECH_BAD, + RX_SID_FIRST, + RX_SID_UPDATE, + RX_SID_BAD, + RX_NO_DATA, + RX_N_FRAMETYPES /* number of frame types */ + }; + + enum TXFrameType { TX_SPEECH_GOOD = 0, + TX_SID_FIRST, + TX_SID_UPDATE, + TX_NO_DATA, + TX_SPEECH_DEGRADED, + TX_SPEECH_BAD, + TX_SID_BAD, + TX_ONSET, + TX_N_FRAMETYPES /* number of frame types */ + }; + + + /* Channel decoded frame type */ + enum CHDECFrameType { CHDEC_SID_FIRST = 0, + CHDEC_SID_FIRST_INCOMPLETE, + CHDEC_SID_UPDATE_INCOMPLETE, + CHDEC_SID_UPDATE, + CHDEC_SPEECH, + CHDEC_SPEECH_ONSET, + CHDEC_ESCAPE_MARKER, + CHDEC_ESCAPE_DATA, + CHDEC_NO_DATA + }; + + /* Channel decoded frame quality */ + enum CHDECFrameQuality { CHDEC_GOOD = 0, + CHDEC_PROBABLY_DEGRADED, + CHDEC_PROBABLY_BAD, + CHDEC_BAD + }; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/frame_type_3gpp.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/frame_type_3gpp.h new file mode 100644 index 00000000..f82ec467 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/frame_type_3gpp.h @@ -0,0 +1,113 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: frame_type_3gpp.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains the definition of the 3GPP frame types. + +------------------------------------------------------------------------------ +*/ + +#ifndef FRAME_TYPE_3GPP_H +#define FRAME_TYPE_3GPP_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + enum Frame_Type_3GPP + { + AMR_475 = 0, + AMR_515, + AMR_59, + AMR_67, + AMR_74, + AMR_795, + AMR_102, + AMR_122, + AMR_SID, + GSM_EFR_SID, + TDMA_EFR_SID, + PDC_EFR_SID, + FOR_FUTURE_USE1, + FOR_FUTURE_USE2, + FOR_FUTURE_USE3, + AMR_NO_DATA + }; + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + + +#endif /* _FRAME_TYPE_3GPP_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/gc_pred.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/gc_pred.h new file mode 100644 index 00000000..f2c1f552 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/gc_pred.h @@ -0,0 +1,166 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: gc_pred.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : gc_pred.h + Purpose : codebook gain MA prediction + +------------------------------------------------------------------------------ +*/ + +#ifndef _GC_PRED_H_ +#define _GC_PRED_H_ +#define gc_pred_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" + + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 past_qua_en[4]; /* normal MA predictor memory, Q10 */ + /* (contains 20*log10(qua_err)) */ + Word16 past_qua_en_MR122[4]; /* MA predictor memory for MR122 mode, Q10 */ + /* (contains log2(qua_err)) */ + } gc_predState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + OSCL_IMPORT_REF Word16 gc_pred_reset(gc_predState *st); + /* reset of codebook gain MA predictor state (i.e. set state memory to zero) + returns 0 on success + */ + void gc_pred_exit(gc_predState **st); + /* de-initialize codebook gain MA predictor state (i.e. free state struct) + stores NULL in *st + */ + + void + gc_pred_copy( + gc_predState *st_src, /* i : State struct */ + gc_predState *st_dest /* o : State struct */ + ); + + /* + * FUNCTION: gc_pred() + * PURPOSE: MA prediction of the innovation energy + * (in dB/(20*log10(2))) with mean removed). + */ + OSCL_IMPORT_REF void gc_pred( + gc_predState *st, /* i/o: State struct */ + enum Mode mode, /* i : AMR mode */ + Word16 *code, /* i : innovative codebook vector (L_SUBFR) */ + /* MR122: Q12, other modes: Q13 */ + Word16 *exp_gcode0, /* o : exponent of predicted gain factor, Q0 */ + Word16 *frac_gcode0,/* o : fraction of predicted gain factor Q15 */ + Word16 *exp_en, /* o : exponent of innovation energy, Q0 */ + /* (only calculated for MR795) */ + Word16 *frac_en, /* o : fraction of innovation energy, Q15 */ + /* (only calculated for MR795) */ + Flag *pOverflow + ); + + /* + * FUNCTION: gc_pred_update() + * PURPOSE: update MA predictor with last quantized energy + */ + OSCL_IMPORT_REF void gc_pred_update( + gc_predState *st, /* i/o: State struct */ + Word16 qua_ener_MR122, /* i : quantized energy for update, Q10 */ + /* (log2(qua_err)) */ + Word16 qua_ener /* i : quantized energy for update, Q10 */ + /* (20*log10(qua_err)) */ + ); + + /* + * FUNCTION: gc_pred_average_limited() + * PURPOSE: get average of MA predictor state values (with a lower limit) + * [used in error concealment] + */ + OSCL_IMPORT_REF void gc_pred_average_limited( + gc_predState *st, /* i: State struct */ + Word16 *ener_avg_MR122, /* o: averaged quantized energy, Q10 */ + /* (log2(qua_err)) */ + Word16 *ener_avg, /* o: averaged quantized energy, Q10 */ + /* (20*log10(qua_err)) */ + Flag *pOverflow + ); + + +#ifdef __cplusplus +} +#endif + +#endif /* _GC_PRED_H_ */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/get_const_tbls.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/get_const_tbls.h new file mode 100644 index 00000000..cb617b50 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/get_const_tbls.h @@ -0,0 +1,72 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +#ifndef GET_CONST_TBLS_H +#define GET_CONST_TBLS_H + +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + typedef struct + { + const Word16* dgray_ptr; + const Word16* dico1_lsf_3_ptr; + const Word16* dico1_lsf_5_ptr; + const Word16* dico2_lsf_3_ptr; + const Word16* dico2_lsf_5_ptr; + const Word16* dico3_lsf_3_ptr; + const Word16* dico3_lsf_5_ptr; + const Word16* dico4_lsf_5_ptr; + const Word16* dico5_lsf_5_ptr; + const Word16* gray_ptr; + const Word16* lsp_init_data_ptr; + const Word16* mean_lsf_3_ptr; + const Word16* mean_lsf_5_ptr; + const Word16* mr515_3_lsf_ptr; + const Word16* mr795_1_lsf_ptr; + const Word16* past_rq_init_ptr; + const Word16* pred_fac_3_ptr; + const Word16* qua_gain_code_ptr; + const Word16* qua_gain_pitch_ptr; + const Word16* startPos_ptr; + const Word16* table_gain_lowrates_ptr; + const Word16* table_gain_highrates_ptr; + const Word16* prmno_ptr; + const Word16* const* bitno_ptr; + const Word16* numOfBits_ptr; + const Word16* const* reorderBits_ptr; + const Word16* numCompressedBytes_ptr; + const Word16* window_200_40_ptr; + const Word16* window_160_80_ptr; + const Word16* window_232_8_ptr; + const Word16* ph_imp_low_MR795_ptr; + const Word16* ph_imp_mid_MR795_ptr; + const Word16* ph_imp_low_ptr; + const Word16* ph_imp_mid_ptr; + } CommonAmrTbls; + + OSCL_IMPORT_REF void get_const_tbls(CommonAmrTbls* tbl_struct_ptr); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/gmed_n.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/gmed_n.h new file mode 100644 index 00000000..49f4c51e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/gmed_n.h @@ -0,0 +1,80 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : gmed_n.h +* Purpose : calculates N-point median. +* +******************************************************************************** +*/ +#ifndef gmed_n_h +#define gmed_n_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ******************************************************************************** + * DEFINITION OF DATA TYPES + ******************************************************************************** + */ + + /* + ******************************************************************************** + * DECLARATION OF PROTOTYPES + ******************************************************************************** + */ + OSCL_IMPORT_REF Word16 gmed_n( /* o : index of the median value (0...N-1) */ + Word16 ind[], /* i : Past gain values */ + Word16 n /* i : The number of gains; this routine */ + /* is only valid for a odd number of gains */ + ); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/gsm_amr_typedefs.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/gsm_amr_typedefs.h new file mode 100644 index 00000000..465e705f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/gsm_amr_typedefs.h @@ -0,0 +1,147 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: gsm_amr_typedefs.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains the definition of the amr codec types. + +------------------------------------------------------------------------------ +*/ +#ifndef GSM_AMR_TYPEDEFS_H +#define GSM_AMR_TYPEDEFS_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "oscl_base.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; SIMPLE TYPEDEF'S +----------------------------------------------------------------------------*/ + +#ifndef Word8 +typedef int8 Word8; +#endif + +#ifndef UWord8 +typedef uint8 UWord8; +#endif + + +/*---------------------------------------------------------------------------- +; Define 16 bit signed and unsigned words +----------------------------------------------------------------------------*/ + +#ifndef Word16 +typedef int16 Word16; + +#endif + +#ifndef UWord16 +typedef uint16 UWord16; + +#endif + +/*---------------------------------------------------------------------------- +; Define 32 bit signed and unsigned words +----------------------------------------------------------------------------*/ + +#ifndef Word32 +typedef int32 Word32; +#endif + +#ifndef UWord32 +typedef uint32 UWord32; +#endif + + +/*---------------------------------------------------------------------------- +; Define boolean type +----------------------------------------------------------------------------*/ +#ifndef Bool +typedef int Bool; +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef OFF +#define OFF 0 +#endif + +#ifndef ON +#define ON 1 +#endif + +#ifndef NO +#define NO 0 +#endif + +#ifndef YES +#define YES 1 +#endif + +#ifndef SUCCESS +#define SUCCESS 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef Flag +typedef int32 Flag; +#endif + +#endif /* GSM_AMR_TYPEDEFS_H */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/int_lpc.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/int_lpc.h new file mode 100644 index 00000000..3f241cb7 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/int_lpc.h @@ -0,0 +1,201 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: int_lpc.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the lsp_avg.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef int_lpc_h +#define int_lpc_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /* + ************************************************************************** + * + * Function : Int_lpc_1and3 + * Purpose : Interpolates the LSPs and converts to LPC parameters + * to get a different LP filter in each subframe. + * Description : The 20 ms speech frame is divided into 4 subframes. + * The LSPs are quantized and transmitted at the 2nd and + * 4th subframes (twice per frame) and interpolated at the + * 1st and 3rd subframe. + * + * |------|------|------|------| + * sf1 sf2 sf3 sf4 + * F0 Fm F1 + * + * sf1: 1/2 Fm + 1/2 F0 sf3: 1/2 F1 + 1/2 Fm + * sf2: Fm sf4: F1 + * Returns : void + * + ************************************************************************** + */ + OSCL_IMPORT_REF void Int_lpc_1and3( + Word16 lsp_old[], /* i : LSP vector at the 4th subfr. of past frame (M) */ + Word16 lsp_mid[], /* i : LSP vector at the 2nd subfr. of + present frame (M) */ + Word16 lsp_new[], /* i : LSP vector at the 4th subfr. of + present frame (M) */ + Word16 Az[], /* o : interpolated LP parameters in all subfr. + (AZ_SIZE) */ + Flag *pOverflow + ); + + /* + ************************************************************************** + * + * Function : Int_lpc_1and3_2 + * Purpose : Interpolation of the LPC parameters. Same as the Int_lpc + * function but we do not recompute Az() for subframe 2 and + * 4 because it is already available. + * Returns : void + * + ************************************************************************** + */ + void Int_lpc_1and3_2( + Word16 lsp_old[], /* i : LSP vector at the 4th subfr. of past frame (M) */ + Word16 lsp_mid[], /* i : LSP vector at the 2nd subframe of + present frame (M) */ + Word16 lsp_new[], /* i : LSP vector at the 4th subframe of + present frame (M) */ + Word16 Az[], /* o :interpolated LP parameters + in subframes 1 and 3 (AZ_SIZE) */ + Flag *pOverflow + ); + + /* + ************************************************************************** + * + * Function : Int_lpc_1to3 + * Purpose : Interpolates the LSPs and converts to LPC parameters + * to get a different LP filter in each subframe. + * Description : The 20 ms speech frame is divided into 4 subframes. + * The LSPs are quantized and transmitted at the 4th + * subframes (once per frame) and interpolated at the + * 1st, 2nd and 3rd subframe. + * + * |------|------|------|------| + * sf1 sf2 sf3 sf4 + * F0 F1 + * + * sf1: 3/4 F0 + 1/4 F1 sf3: 1/4 F0 + 3/4 F1 + * sf2: 1/2 F0 + 1/2 F1 sf4: F1 + * Returns : void + * + ************************************************************************** + */ + OSCL_IMPORT_REF void Int_lpc_1to3( + Word16 lsp_old[], /* i : LSP vector at the 4th SF of past frame (M) */ + Word16 lsp_new[], /* i : LSP vector at the 4th SF of present frame (M) */ + Word16 Az[], /* o : interpolated LP parameters in all SFs (AZ_SIZE) */ + Flag *pOverflow + ); + + /* + ************************************************************************** + * + * Function : Int_lpc_1to3_2 + * Purpose : Interpolation of the LPC parameters. Same as the Int_lpc + * function but we do not recompute Az() for subframe 4 + * because it is already available. + * Returns : void + * + ************************************************************************** + */ + void Int_lpc_1to3_2( + Word16 lsp_old[], /* i : LSP vector at the 4th SF of past frame (M) */ + Word16 lsp_new[], /* i : LSP vector at the 4th SF present frame (M) */ + Word16 Az[], /* o :interpolated LP parameters in SFs 1, 2, 3 + (AZ_SIZE) */ + Flag *pOverflow + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _INT_LPC_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/int_lsf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/int_lsf.h new file mode 100644 index 00000000..2ee9e717 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/int_lsf.h @@ -0,0 +1,105 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: int_lsf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the int_lsf function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef int_lsf_h +#define int_lsf_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void Int_lsf( + Word16 lsf_old[], /* i : LSF vector at the 4th SF of past frame */ + Word16 lsf_new[], /* i : LSF vector at the 4th SF of present frame */ + Word16 i_subfr, /* i : Current sf (equal to 0,40,80 or 120) */ + Word16 lsf_out[], /* o : interpolated LSF parameters for current sf */ + Flag *pOverflow /* o : flag set if overflow occurs */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _INT_LSF_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/inv_sqrt.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/inv_sqrt.h new file mode 100644 index 00000000..937a417e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/inv_sqrt.h @@ -0,0 +1,100 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: inv_sqrt.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the inv_sqrt() function. + +------------------------------------------------------------------------------ +*/ + +#ifndef INV_SQRT_H +#define INV_SQRT_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 inv_sqrt_tbl[]; + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF Word32 Inv_sqrt( /* (o) : output value */ + Word32 L_x, /* (i) : input value */ + Flag *pOverflow /* (i) : pointer to overflow flag */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _INV_SQRT_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_add.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_add.h new file mode 100644 index 00000000..ac72c310 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_add.h @@ -0,0 +1,137 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_add.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_add function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_ADD_H +#define L_ADD_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC))/* Instructions for ARM-linux cross-compiler*/ + __inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow) + { + register Word32 ra = L_var1; + register Word32 rb = L_var2; + Word32 result; + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("qadd %0, %1, %2" + : "=r"(result) + : "r"(ra), "r"(rb) + ); + return (result); + + } + +#else /* C EQUIVALENT */ + + + static inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow) + { + Word32 L_sum; + + L_sum = L_var1 + L_var2; + + if ((L_var1 ^ L_var2) >= 0) + { + if ((L_sum ^ L_var1) < 0) + { + L_sum = (L_var1 < 0) ? MIN_32 : MAX_32; + *pOverflow = 1; + } + } + + return (L_sum); + } + +#endif + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_ADD_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_add_c.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_add_c.h new file mode 100644 index 00000000..7af7cdc0 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_add_c.h @@ -0,0 +1,101 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_add_c.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_add_c function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_ADD_C_H +#define L_ADD_C_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word32 L_add_c(Word32 L_var1, Word32 L_var2, Flag *pOverflow, Flag *pCarry); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_ADD_C_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_comp.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_comp.h new file mode 100644 index 00000000..7738ad25 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_comp.h @@ -0,0 +1,101 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_comp.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_comp function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_COMP_H +#define L_COMP_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word32 L_Comp(Word16 hi, Word16 lo, Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_deposit_h.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_deposit_h.h new file mode 100644 index 00000000..8d906a91 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_deposit_h.h @@ -0,0 +1,130 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: l_deposit_h.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + var1 = deposit of var1 into MSWord of 32 bit value (Word32) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function deposits the 16 bit var1 into the 16 MS bits of the 32 bit + output. The 16 LS bits of the output are zeroed. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word32 L_deposit_h (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 << 16; +#if (WMOPS) + multiCounter[currCounter].L_deposit_h++; +#endif + return (L_var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word32 L_deposit_h(Word16 var1); diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_deposit_l.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_deposit_l.h new file mode 100644 index 00000000..99180217 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_deposit_l.h @@ -0,0 +1,130 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: l_deposit_l.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + var1 = deposit of var1 into LSWord of 32 bit value (Word32) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function deposits the 16 bit var1 into the 16 LS bits of the 32 bit + output. The 16 MS bits of the output are sign extended. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word32 L_deposit_l (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1; +#if (WMOPS) + multiCounter[currCounter].L_deposit_l++; +#endif + return (L_var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word32 L_deposit_l(Word16 var1); diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_extract.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_extract.h new file mode 100644 index 00000000..2816f834 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_extract.h @@ -0,0 +1,103 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_extract.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_extract function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_EXTRACT_H +#define L_EXTRACT_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void L_Extract(Word32 L_var, + Word16 *pL_var_hi, + Word16 *pL_var_lo, + Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_EXTRACT_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_mac.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_mac.h new file mode 100644 index 00000000..f6724286 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_mac.h @@ -0,0 +1,152 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: l_mac.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_mac function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_MAC_H +#define L_MAC_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC))/* Instructions for ARM-linux cross-compiler*/ + + static inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 ra = L_var3; + register Word32 rb = var1; + register Word32 rc = var2; + Word32 result; + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("smulbb %0, %1, %2" + : "=r"(result) + : "r"(rb), "r"(rc) + ); + + asm volatile("qdadd %0, %1, %2" + : "=r"(rc) + : "r"(ra), "r"(result) + ); + + return (rc); + } + +#else /* C_EQUIVALENT */ + + __inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) + { + Word32 result; + Word32 L_sum; + result = (Word32) var1 * var2; + if (result != (Word32) 0x40000000L) + { + L_sum = (result << 1) + L_var3; + + /* Check if L_sum and L_var_3 share the same sign */ + if ((L_var3 ^ result) > 0) + { + if ((L_sum ^ L_var3) < 0) + { + L_sum = (L_var3 < 0) ? MIN_32 : MAX_32; + *pOverflow = 1; + } + } + } + else + { + *pOverflow = 1; + L_sum = MAX_32; + } + return (L_sum); + } + +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_MAC_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_msu.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_msu.h new file mode 100644 index 00000000..86c5735b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_msu.h @@ -0,0 +1,137 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: l_msu.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_msu function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_MSU_H +#define L_MSU_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" +#include "l_mult.h" +#include "l_sub.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC))/* Instructions for ARM-linux cross-compiler*/ + + __inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 ra = L_var3; + register Word32 rb = var1; + register Word32 rc = var2; + Word32 product; + Word32 result; + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("smulbb %0, %1, %2" + : "=r"(product) + : "r"(rb), "r"(rc) + ); + + asm volatile("qdsub %0, %1, %2" + : "=r"(result) + : "r"(ra), "r"(product) + ); + + return (result); + } + +#else /* C EQUIVALENT */ + + static inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) + { + Word32 result; + + result = L_mult(var1, var2, pOverflow); + result = L_sub(L_var3, result, pOverflow); + + return (result); + } + +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _L_MSU_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_mult.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_mult.h new file mode 100644 index 00000000..33fedb15 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_mult.h @@ -0,0 +1,143 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_mult.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_mult function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_MULT_H +#define L_MULT_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC))/* Instructions for ARM-linux cross-compiler*/ + + __inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 ra = var1; + register Word32 rb = var2; + Word32 result; + Word32 product; + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("smulbb %0, %1, %2" + : "=r"(product) + : "r"(ra), "r"(rb) + ); + + asm volatile("qadd %0, %1, %2" + : "=r"(result) + : "r"(product), "r"(product) + ); + + return(result); + } + +#else /* C EQUIVALENT */ + + static inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 L_product; + + L_product = (Word32) var1 * var2; + + if (L_product != (Word32) 0x40000000L) + { + L_product <<= 1; /* Multiply by 2 */ + } + else + { + *pOverflow = 1; + L_product = MAX_32; + } + + return (L_product); + } +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_MULT_H */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_negate.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_negate.h new file mode 100644 index 00000000..e406bb80 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_negate.h @@ -0,0 +1,101 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_negate.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_negate function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_NEGATE_H +#define L_NEGATE_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word32 L_negate(Word32 L_var1); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_shl.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_shl.h new file mode 100644 index 00000000..5430bc76 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_shl.h @@ -0,0 +1,102 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_shl.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_shl function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_SHL_H +#define L_SHL_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word32 L_shl(Word32 L_var1, Word16 var2, Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_SHL_H_ */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_shr.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_shr.h new file mode 100644 index 00000000..424c948e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_shr.h @@ -0,0 +1,101 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: l_shr.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_shr function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_SHR_H +#define L_SHR_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word32 L_shr(Word32 L_var1, Word16 var2, Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_SHR_H_ */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_shr_r.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_shr_r.h new file mode 100644 index 00000000..29d99da5 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_shr_r.h @@ -0,0 +1,100 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_shr_r.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_shr_r function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_SHR_R_H +#define L_SHR_R_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF Word32 L_shr_r(Word32 L_var1, Word16 var2, Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_SHR_R_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_sub.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_sub.h new file mode 100644 index 00000000..88d86caf --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/l_sub.h @@ -0,0 +1,141 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_sub.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_sub function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_SUB_H +#define L_SUB_H + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC)) /* Instructions for ARM-linux cross-compiler*/ + + __inline Word32 L_sub(Word32 L_var1, Word32 L_var2, Flag *pOverflow) + { + register Word32 ra = L_var1; + register Word32 rb = L_var2; + Word32 result; + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("qsub %0, %1, %2" + : "=r"(result) + : "r"(ra), "r"(rb) + ); + + return (result); + } + +#else /* C EQUIVALENT */ + + static inline Word32 L_sub(register Word32 L_var1, register Word32 L_var2, + register Flag *pOverflow) + { + Word32 L_diff; + + L_diff = L_var1 - L_var2; + + if ((L_var1 ^ L_var2) < 0) + { + if ((L_diff ^ L_var1) & MIN_32) + { + L_diff = (L_var1 < 0L) ? MIN_32 : MAX_32; + *pOverflow = 1; + } + } + + return (L_diff); + } + +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_SUB_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/log2.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/log2.h new file mode 100644 index 00000000..ce27dba9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/log2.h @@ -0,0 +1,104 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: log2.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains the function prototype definition for Log2 function. + +------------------------------------------------------------------------------ +*/ +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef LOG2_H +#define LOG2_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +#include "log2_norm.h" /* Used by legacy files */ + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF void Log2( + Word32 L_x, /* (i) : input value */ + Word16 *pExponent, /* (o) : Integer part of Log2. (range: 0<=val<=30)*/ + Word16 *pFraction, /* (o) : Fractional part of Log2. (range: 0<=val<1) */ + Flag *pOverflow /* (i/o) : overflow flag */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _LOG2_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/log2_norm.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/log2_norm.h new file mode 100644 index 00000000..3b062443 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/log2_norm.h @@ -0,0 +1,103 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: log2_norm.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains the prototype declaration for Log2_norm function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef LOG2_NORM_H +#define LOG2_NORM_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 log2_tbl[]; + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void Log2_norm( + Word32 L_x, /* (i) : input value (normalized) */ + Word16 exp, /* (i) : norm_l (L_x) */ + Word16 *exponent, /* (o) : Integer part of Log2. (range: 0<=val<=30) */ + Word16 *fraction /* (o) : Fractional part of Log2. (range: 0<=val<1) */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _LOG2_NORM_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsfwt.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsfwt.h new file mode 100644 index 00000000..cca36d46 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsfwt.h @@ -0,0 +1,104 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: lsfwt.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the lsfwt.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef lsfwt_h +#define lsfwt_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void Lsf_wt( + Word16 *lsf, /* input : LSF vector */ + Word16 *wf, /* output: square of weighting factors */ + Flag * pOverflow); /* o : Flag set when overflow occurs */ + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _LSF_WT_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsp.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsp.h new file mode 100644 index 00000000..99b61514 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsp.h @@ -0,0 +1,173 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: lsp.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the lsp.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef lsp_h +#define lsp_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "q_plsf.h" +#include "mode.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + + /* Past LSPs */ + Word16 lsp_old[M]; + Word16 lsp_old_q[M]; + + /* Quantization state */ + Q_plsfState *qSt; + + } lspState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + /* + ************************************************************************** + * + * Function : lsp_init + * Purpose : Allocates memory and initializes state variables + * Description : Stores pointer to filter status struct in *st. This + * pointer has to be passed to lsp in each call. + * Returns : 0 on success + * + ************************************************************************** + */ + OSCL_IMPORT_REF Word16 lsp_init(lspState **st); + + /* + ************************************************************************** + * + * Function : lsp_reset + * Purpose : Resets state memory + * Returns : 0 on success + * + ************************************************************************** + */ + OSCL_IMPORT_REF Word16 lsp_reset(lspState *st); + + /* + ************************************************************************** + * + * Function : lsp_exit + * Purpose : The memory used for state memory is freed + * Description : Stores NULL in *st + * + ************************************************************************** + */ + OSCL_IMPORT_REF void lsp_exit(lspState **st); + + /* + ************************************************************************** + * + * Function : lsp + * Purpose : Conversion from LP coefficients to LSPs. + * Quantization of LSPs. + * Description : Generates 2 sets of LSPs from 2 sets of + * LP coefficients for mode 12.2. For the other + * modes 1 set of LSPs is generated from 1 set of + * LP coefficients. These LSPs are quantized with + * Matrix/Vector quantization (depending on the mode) + * and interpolated for the subframes not yet having + * their own LSPs. + * + ************************************************************************** + */ + OSCL_IMPORT_REF void lsp(lspState *st, /* i/o : State struct */ + enum Mode req_mode, /* i : requested coder mode */ + enum Mode used_mode,/* i : used coder mode */ + Word16 az[], /* i/o : interpolated LP parameters Q12 */ + Word16 azQ[], /* o : quantization interpol. LP parameters Q12*/ + Word16 lsp_new[], /* o : new lsp vector */ + Word16 **anap, /* o : analysis parameters */ + Flag *pOverflow /* o : Flag set when overflow occurs */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _LSP_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsp_az.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsp_az.h new file mode 100644 index 00000000..fb3d248a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsp_az.h @@ -0,0 +1,103 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: lsp_az.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the lsp_az function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef LSP_AZ_H +#define LSP_AZ_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF void Lsp_Az( + Word16 lsp[], /* (i) : line spectral frequencies */ + Word16 a[], /* (o) : predictor coefficients (order = 10) */ + Flag *pOverflow /* (o) : overflow flag */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _LSP_AZ_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsp_lsf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsp_lsf.h new file mode 100644 index 00000000..ac7fca00 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsp_lsf.h @@ -0,0 +1,111 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: lsp_lsf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the lsp_lsf.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef lsp_lsf_h +#define lsp_lsf_h + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + OSCL_IMPORT_REF void Lsf_lsp( + Word16 lsf[], /* (i) : lsf[m] normalized (range: 0.0<=val<=0.5) */ + Word16 lsp[], /* (o) : lsp[m] (range: -1<=val<1) */ + Word16 m, /* (i) : LPC order */ + Flag *pOverflow /* (o) : Flag set when overflow occurs */ + ); + OSCL_IMPORT_REF void Lsp_lsf( + Word16 lsp[], /* (i) : lsp[m] (range: -1<=val<1) */ + Word16 lsf[], /* (o) : lsf[m] normalized (range: 0.0<=val<=0.5) */ + Word16 m, /* (i) : LPC order */ + Flag *pOverflow /* (o) : Flag set when overflow occurs */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _LSP_LSF_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsp_tab.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsp_tab.h new file mode 100644 index 00000000..db3cd525 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/lsp_tab.h @@ -0,0 +1,103 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: lsp_tab.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file declares a table lsp_init_data. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef LSP_TAB_H +#define LSP_TAB_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 lsp_init_data[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mac_32.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mac_32.h new file mode 100644 index 00000000..b79a84f5 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mac_32.h @@ -0,0 +1,136 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: mac_32.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the Mac_32 and Mac_32_16 functions + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef MAC_32_H +#define MAC_32_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + static inline Word32 Mac_32(Word32 L_var3, + Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 L_var2_hi, + Word16 L_var2_lo, + Flag *pOverflow) + { + Word16 product; + + L_var3 = L_mac(L_var3, L_var1_hi, L_var2_hi, pOverflow); + + product = mult(L_var1_hi, L_var2_lo, pOverflow); + L_var3 = L_mac(L_var3, product, 1, pOverflow); + + product = mult(L_var1_lo, L_var2_hi, pOverflow); + L_var3 = L_mac(L_var3, product, 1, pOverflow); + + return (L_var3); + } + + static inline Word32 Mac_32_16(Word32 L_var3, + Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 var2, + Flag *pOverflow) + { + Word16 product; + + L_var3 = L_mac(L_var3, L_var1_hi, var2, pOverflow); + + product = mult(L_var1_lo, var2, pOverflow); + L_var3 = L_mac(L_var3, product, 1, pOverflow); + + return (L_var3); + } + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _MAC_32_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mode.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mode.h new file mode 100644 index 00000000..75f86cb6 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mode.h @@ -0,0 +1,82 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : mode.h +* Purpose : Declaration of mode type +* +******************************************************************************** +*/ +#ifndef mode_h +#define mode_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ******************************************************************************** + * DEFINITION OF DATA TYPES + ******************************************************************************** + */ + enum Mode { MR475 = 0, + MR515, + MR59, + MR67, + MR74, + MR795, + MR102, + MR122, + + MRDTX, + + N_MODES /* number of (SPC) modes */ + + }; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mpy_32.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mpy_32.h new file mode 100644 index 00000000..8df43c98 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mpy_32.h @@ -0,0 +1,224 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: mpy_32.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the Mpy_32 function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef MPY_32_H +#define MPY_32_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC))/* Instructions for ARM-linux cross-compiler*/ + + static inline Word32 Mpy_32(Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 L_var2_hi, + Word16 L_var2_lo, + Flag *pOverflow) + { + register Word32 product32; + register Word32 L_sum; + register Word32 L_product, result; + register Word32 ra = L_var1_hi; + register Word32 rb = L_var1_lo; + register Word32 rc = L_var2_hi; + register Word32 rd = L_var2_lo; + + + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("smulbb %0, %1, %2" + : "=r"(L_product) + : "r"(ra), "r"(rc) + ); + asm volatile("mov %0, #0" + : "=r"(result) + ); + + asm volatile("qdadd %0, %1, %2" + : "=r"(L_sum) + : "r"(result), "r"(L_product) + ); + + asm volatile("smulbb %0, %1, %2" + : "=r"(product32) + : "r"(ra), "r"(rd) + ); + + asm volatile("mov %0, %1, ASR #15" + : "=r"(ra) + : "r"(product32) + ); + asm volatile("qdadd %0, %1, %2" + : "=r"(L_product) + : "r"(L_sum), "r"(ra) + ); + + asm volatile("smulbb %0, %1, %2" + : "=r"(product32) + : "r"(rb), "r"(rc) + ); + + asm volatile("mov %0, %1, ASR #15" + : "=r"(rb) + : "r"(product32) + ); + + asm volatile("qdadd %0, %1, %2" + : "=r"(L_sum) + : "r"(L_product), "r"(rb) + ); + + return (L_sum); + } + +#else /* C_EQUIVALENT */ + + __inline Word32 Mpy_32(Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 L_var2_hi, + Word16 L_var2_lo, + Flag *pOverflow) + { + Word32 L_product; + Word32 L_sum; + Word32 product32; + + OSCL_UNUSED_ARG(pOverflow); + L_product = (Word32) L_var1_hi * L_var2_hi; + + if (L_product != (Word32) 0x40000000L) + { + L_product <<= 1; + } + else + { + L_product = MAX_32; + } + + /* result = mult (L_var1_hi, L_var2_lo, pOverflow); */ + product32 = ((Word32) L_var1_hi * L_var2_lo) >> 15; + + /* L_product = L_mac (L_product, result, 1, pOverflow); */ + L_sum = L_product + (product32 << 1); + + if ((L_product ^ product32) > 0) + { + if ((L_sum ^ L_product) < 0) + { + L_sum = (L_product < 0) ? MIN_32 : MAX_32; + } + } + + L_product = L_sum; + + /* result = mult (L_var1_lo, L_var2_hi, pOverflow); */ + product32 = ((Word32) L_var1_lo * L_var2_hi) >> 15; + + /* L_product = L_mac (L_product, result, 1, pOverflow); */ + L_sum = L_product + (product32 << 1); + + if ((L_product ^ product32) > 0) + { + if ((L_sum ^ L_product) < 0) + { + L_sum = (L_product < 0) ? MIN_32 : MAX_32; + } + } + + /*---------------------------------------------------------------------------- + ; Return nothing or data or data pointer + ----------------------------------------------------------------------------*/ + return (L_sum); + } + +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _MPY_32_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mpy_32_16.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mpy_32_16.h new file mode 100644 index 00000000..3a68e695 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mpy_32_16.h @@ -0,0 +1,184 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: mpy_32_16.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the Mpy_32_16 function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef MPY_32_16_H +#define MPY_32_16_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC))/* Instructions for ARM-linux cross-compiler*/ + + static inline Word32 Mpy_32_16(Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 var2, + Flag *pOverflow) + { + + register Word32 ra = L_var1_hi; + register Word32 rb = L_var1_lo; + register Word32 rc = var2; + Word32 result, L_product; + + OSCL_UNUSED_ARG(pOverflow); + + __asm__ volatile("smulbb %0, %1, %2" + : "=r"(L_product) + : "r"(ra), "r"(rc) + ); + __asm__ volatile("mov %0, #0" + : "=r"(result) + ); + + __asm__ volatile("qdadd %0, %1, %2" + : "=r"(L_product) + : "r"(result), "r"(L_product) + ); + + __asm__ volatile("smulbb %0, %1, %2" + : "=r"(result) + : "r"(rb), "r"(rc) + ); + + __asm__ volatile("mov %0, %1, ASR #15" + : "=r"(ra) + : "r"(result) + ); + __asm__ volatile("qdadd %0, %1, %2" + : "=r"(result) + : "r"(L_product), "r"(ra) + ); + + return (result); + } + +#else /* C_EQUIVALENT */ + static inline Word32 Mpy_32_16(Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 var2, + Flag *pOverflow) + { + + Word32 L_product; + Word32 L_sum; + Word32 result; + L_product = (Word32) L_var1_hi * var2; + + if (L_product != (Word32) 0x40000000L) + { + L_product <<= 1; + } + else + { + *pOverflow = 1; + L_product = MAX_32; + } + + result = ((Word32)L_var1_lo * var2) >> 15; + + L_sum = L_product + (result << 1); + + if ((L_product ^ result) > 0) + { + if ((L_sum ^ L_product) < 0) + { + L_sum = (L_product < 0) ? MIN_32 : MAX_32; + *pOverflow = 1; + } + } + return (L_sum); + + } + +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _MPY_32_16_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mult.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mult.h new file mode 100644 index 00000000..c89a94ee --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mult.h @@ -0,0 +1,152 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: mult.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the mult function. + +------------------------------------------------------------------------------ +*/ + +#ifndef MULT_H +#define MULT_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC)) + + __inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 ra = var1; + register Word32 rb = var2; + Word32 product; + Word32 temp = 0x7FFF; + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("smulbb %0, %1, %2" + : "=r"(product) + : "r"(ra), "r"(rb) + ); + asm volatile("mov %0, %1, ASR #15" + : "=r"(product) + : "r"(product) + ); + asm volatile("cmp %0, %1" + : "=r"(product) + : "r"(temp) + ); + asm volatile("movge %0, %1" + : "=r"(product) + : "r"(temp) + ); + + return ((Word16) product); + } + +#else /* C EQUIVALENT */ + + static inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 product; + + product = ((Word32) var1 * var2) >> 15; + + /* Saturate result (if necessary). */ + /* var1 * var2 >0x00007fff is the only case */ + /* that saturation occurs. */ + + if (product > 0x00007fffL) + { + *pOverflow = 1; + product = (Word32) MAX_16; + } + + + /* Return the product as a 16 bit value by type casting Word32 to Word16 */ + + return ((Word16) product); + } + +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _MULT_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mult_r.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mult_r.h new file mode 100644 index 00000000..90f7e83c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/mult_r.h @@ -0,0 +1,103 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: mult_r.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the mult_r function. + +------------------------------------------------------------------------------ +*/ + +#ifndef MULT_R__H +#define MULT_R__H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF Word16 mult_r(Word16 var1, Word16 var2, Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + + +#endif /* _MULT_R_H_ */ + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/n_proc.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/n_proc.h new file mode 100644 index 00000000..e5738c17 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/n_proc.h @@ -0,0 +1,31 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* $Id $ */ + +void proc_head(char *mes); diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/negate.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/negate.h new file mode 100644 index 00000000..2b77f779 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/negate.h @@ -0,0 +1,100 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/***************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +**************************************************************************/ +/* + Filename: negate.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the negate function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef NEGATE_H +#define NEGATE_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 negate(register Word16 var1); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/norm_l.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/norm_l.h new file mode 100644 index 00000000..288b6c7b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/norm_l.h @@ -0,0 +1,119 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: norm_l.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the norm_l function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef NORM_L_H +#define NORM_L_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC)) + static inline Word16 norm_l(Word32 L_var1) + { + register Word32 var_out = 0; + register Word32 ra = L_var1; + if (L_var1) + { + ra ^= (ra << 1); + __asm__ volatile( + "clz %0, %1" + : "=r"(var_out) + : "r"(ra) + ); + } + return (var_out); + } +#else + /* C EQUIVALENT */ + OSCL_IMPORT_REF Word16 norm_l(Word32 L_var1); + +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/norm_s.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/norm_s.h new file mode 100644 index 00000000..7847f349 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/norm_s.h @@ -0,0 +1,118 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: norm_s.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the norm_s function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef NORM_S_H +#define NORM_S_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC)) + static inline Word16 norm_s(Word16 var1) + { + register Word32 var_out = 0; + register Word32 ra = var1 << 16; + if (ra) + { + ra ^= (ra << 1); + __asm__ volatile( + "clz %0, %1" + : "=r"(var_out) + : "r"(ra) + ); + } + return (var_out); + } +#else + /*C EQUIVALENT */ + OSCL_IMPORT_REF Word16 norm_s(Word16 var1); +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/oper_32b.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/oper_32b.h new file mode 100644 index 00000000..c2ef9753 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/oper_32b.h @@ -0,0 +1,92 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: oper_32b.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file includes all the oper_32b.c functions' header files. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef OPER_32B_H +#define OPER_32B_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +#include "l_comp.h" +#include "l_extract.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; SIMPLE TYPEDEF'S +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; ENUMERATED TYPEDEF'S +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; STRUCTURES TYPEDEF'S +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; GLOBAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; END +----------------------------------------------------------------------------*/ +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/p_ol_wgh.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/p_ol_wgh.h new file mode 100644 index 00000000..f07ea36b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/p_ol_wgh.h @@ -0,0 +1,134 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: p_ol_wgh.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : p_ol_wgh.h + Purpose : Compute the open loop pitch lag with weighting. + +------------------------------------------------------------------------------ +*/ + +#ifndef P_OL_WGH_H +#define P_OL_WGH_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "vad.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + extern const Word16 corrweight[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + /* state variable */ + + typedef struct + { + Word16 old_T0_med; + Word16 ada_w; + Word16 wght_flg; + } pitchOLWghtState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + Word16 p_ol_wgh_init(pitchOLWghtState **st); + /* initialize one instance of the pre processing state. + Stores pointer to filter status struct in *st. This pointer has to + be passed to p_ol_wgh in each call. + returns 0 on success + */ + + Word16 p_ol_wgh_reset(pitchOLWghtState *st); + /* reset of pre processing state (i.e. set state memory to zero) + returns 0 on success + */ + + void p_ol_wgh_exit(pitchOLWghtState **st); + /* de-initialize pre processing state (i.e. free status struct) + stores NULL in *st + */ + + Word16 Pitch_ol_wgh( /* o : open loop pitch lag */ + pitchOLWghtState *st, /* i/o : State struct */ + vadState *vadSt, /* i/o : VAD state struct */ + Word16 signal[], /* i : signal used to compute the open loop pitch */ + /* signal[-pit_max] to signal[-1] should be known */ + Word16 pit_min, /* i : minimum pitch lag */ + Word16 pit_max, /* i : maximum pitch lag */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 old_lags[], /* i : history with old stored Cl lags */ + Word16 ol_gain_flg[], /* i : OL gain flag */ + Word16 idx, /* i : index */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* o : overflow flag */ + ); + +#ifdef __cplusplus +} +#endif + +#endif /* _P_OL_WGH_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/pow2.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/pow2.h new file mode 100644 index 00000000..ba83477c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/pow2.h @@ -0,0 +1,104 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: pow2.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains the prototype declaration for Pow2() function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef POW2_H +#define POW2_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 pow2_tbl[]; + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + OSCL_IMPORT_REF Word32 Pow2( + /* (o) : result (range: 0<=val<=0x7fffffff) */ + Word16 exponent, /* (i) : Integer part. (range: 0<=val<=30) */ + Word16 fraction, /* (i) : Fractional part. (range: 0.0<=val<1.0) */ + Flag *pOverflow /* (i/o) : overflow flag */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _POW2_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/pred_lt.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/pred_lt.h new file mode 100644 index 00000000..28a0dd8c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/pred_lt.h @@ -0,0 +1,105 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: pred_lt.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the pred_lt function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef pred_lt_h +#define pred_lt_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF void Pred_lt_3or6( + Word16 exc[], /* in/out: excitation buffer */ + Word16 T0, /* input : integer pitch lag */ + Word16 frac, /* input : fraction of lag */ + Word16 L_subfr, /* input : subframe size */ + Word16 flag3, /* input : if set, upsampling rate = 3 (6 otherwise) */ + Flag *pOverflow /* output: if set, overflow occurred in this function */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* PRED_LT_H */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/pvgsmamr.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/pvgsmamr.h new file mode 100644 index 00000000..b6975247 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/pvgsmamr.h @@ -0,0 +1,63 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +#ifndef __PVGSMAMR_H +#define __PVGSMAMR_H + + +// includes +#include +#include + +#include "sp_dec.h" +#include "pvglobals.h" + + +// PVGsmDecoder AO +class CPVGsmDecoder : public CBase +{ + public: + IMPORT_C static CPVGsmDecoder* NewL(void); + IMPORT_C ~CPVGsmDecoder(); + IMPORT_C TInt StartL(void); + + // only port the API's used in PVPlayer 2.0 + IMPORT_C TInt DecodeFrame(enum Mode mode, unsigned char* compressedBlock, unsigned char* audioBuffer); + IMPORT_C TInt InitDecoder(void); + IMPORT_C void ExitDecoder(void); + + private: + CPVGsmDecoder(); + void ConstructL(void); + + Speech_Decode_FrameState* decState; + enum RXFrameType rx_type; + struct globalDataStruct *gds; +}; + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/q_plsf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/q_plsf.h new file mode 100644 index 00000000..9298d09f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/q_plsf.h @@ -0,0 +1,156 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: q_plsf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the q_plsf_3.c and q_plsf_5.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef q_plsf_h +#define q_plsf_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" +#include "mode.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define MR795_1_SIZE 512 +#define PAST_RQ_INIT_SIZE 8 + +#define DICO1_SIZE 256 +#define DICO2_SIZE 512 +#define DICO3_SIZE 512 + +#define DICO1_5_SIZE 128 +#define DICO2_5_SIZE 256 +#define DICO3_5_SIZE 256 +#define DICO4_5_SIZE 256 +#define DICO5_5_SIZE 64 + +#define MR515_3_SIZE 128 + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 past_rq[M]; /* Past quantized prediction error, Q15 */ + + } Q_plsfState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + Word16 Q_plsf_init(Q_plsfState **st); + /* initialize one instance of the state. + Stores pointer to filter status struct in *st. This pointer has to + be passed to Q_plsf_5 / Q_plsf_3 in each call. + returns 0 on success + */ + + Word16 Q_plsf_reset(Q_plsfState *st); + /* reset of state (i.e. set state memory to zero) + returns 0 on success + */ + + void Q_plsf_exit(Q_plsfState **st); + /* de-initialize state (i.e. free status struct) + stores NULL in *st + */ + + OSCL_IMPORT_REF void Q_plsf_3( + Q_plsfState *st, /* i/o: state struct */ + enum Mode mode, /* i : coder mode */ + Word16 *lsp1, /* i : 1st LSP vector Q15 */ + Word16 *lsp1_q, /* o : quantized 1st LSP vector Q15 */ + Word16 *indice, /* o : quantization indices of 3 vectors Q0 */ + Word16 *pred_init_i,/* o : init index for MA prediction in DTX mode */ + Flag *pOverflow /* o : Flag set when overflow occurs */ + ); + + OSCL_IMPORT_REF void Q_plsf_5( + Q_plsfState *st, + Word16 *lsp1, /* i : 1st LSP vector, Q15 */ + Word16 *lsp2, /* i : 2nd LSP vector, Q15 */ + Word16 *lsp1_q, /* o : quantized 1st LSP vector, Q15 */ + Word16 *lsp2_q, /* o : quantized 2nd LSP vector, Q15 */ + Word16 *indice, /* o : quantization indices of 5 matrices, Q0 */ + Flag *pOverflow /* o : Flag set when overflow occurs */ + ); + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _Q_PLSF_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/q_plsf_3_tbl.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/q_plsf_3_tbl.h new file mode 100644 index 00000000..8bf70473 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/q_plsf_3_tbl.h @@ -0,0 +1,123 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: q_plsf_3_tbl.h + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ +#define MR795_1_SIZE 512 +#define PAST_RQ_INIT_SIZE 8 + +#define DICO1_SIZE 256 +#define DICO2_SIZE 512 +#define DICO3_SIZE 512 + +#define MR515_3_SIZE 128 + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /* Codebooks of LSF prediction residual */ + extern const Word16 mean_lsf_3[]; + + extern const Word16 pred_fac_3[]; + + extern const Word16 dico1_lsf_3[]; + extern const Word16 dico2_lsf_3[]; + extern const Word16 dico3_lsf_3[]; + + extern const Word16 mr515_3_lsf[]; + extern const Word16 mr795_1_lsf[]; + + extern const Word16 past_rq_init[]; + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/q_plsf_5_tbl.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/q_plsf_5_tbl.h new file mode 100644 index 00000000..e495c4ae --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/q_plsf_5_tbl.h @@ -0,0 +1,104 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: q_plsf_5_tbl.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file declares tables defined in q_plsf_5_tbl.c. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef Q_PLSF_5_TBL_H +#define Q_PLSF_5_TBL_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 mean_lsf_5[]; + extern const Word16 dico1_lsf_5[]; + extern const Word16 dico2_lsf_5[]; + extern const Word16 dico3_lsf_5[]; + extern const Word16 dico4_lsf_5[]; + extern const Word16 dico5_lsf_5[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/qgain475_tab.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/qgain475_tab.h new file mode 100644 index 00000000..cfa5dee9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/qgain475_tab.h @@ -0,0 +1,101 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: qgain475_tab.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file declares tables defined in qgain475_tab.c. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef QGAIN475_TAB_H +#define QGAIN475_TAB_H + +#define MR475_VQ_SIZE 256 + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 table_gain_MR475[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/qua_gain.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/qua_gain.h new file mode 100644 index 00000000..951a2c46 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/qua_gain.h @@ -0,0 +1,126 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: qua_gain.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the file, qua_gain.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef qua_gain_h +#define qua_gain_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "gc_pred.h" +#include "mode.h" +#include "get_const_tbls.h" + + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define VQ_SIZE_HIGHRATES 128 +#define VQ_SIZE_LOWRATES 64 + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + Word16 + Qua_gain( /* o : index of quantization. */ + enum Mode mode, /* i : AMR mode */ + Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ + Word16 frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */ + Word16 exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */ + /* (frac_coeff and exp_coeff computed in */ + /* calc_filt_energies()) */ + Word16 gp_limit, /* i : pitch gain limit */ + Word16 *gain_pit, /* o : Pitch gain, Q14 */ + Word16 *gain_cod, /* o : Code gain, Q1 */ + Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ + /* (for MR122 MA predictor update) */ + Word16 *qua_ener, /* o : quantized energy error, Q10 */ + /* (for other MA predictor update) */ + CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of table ptrs */ + Flag *pOverflow /* o : overflow indicator */ + ); + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* qua_gain_h */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/qua_gain_tbl.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/qua_gain_tbl.h new file mode 100644 index 00000000..b3d2c012 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/qua_gain_tbl.h @@ -0,0 +1,102 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: qua_gain_tbl.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file declares tables defined in qua_gain_tbl.c. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef QUA_GAIN_TBL_H +#define QUA_GAIN_TBL_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 table_gain_highrates[]; + extern const Word16 table_gain_lowrates[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/reorder.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/reorder.h new file mode 100644 index 00000000..231bc9a7 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/reorder.h @@ -0,0 +1,101 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: reorder.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the Reorder_lsf() function. + +------------------------------------------------------------------------------ +*/ + +#ifndef REORDER_H +#define REORDER_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF void Reorder_lsf( + Word16 *lsf, /* (i/o) : vector of LSFs (range: 0<=val<=0.5) */ + Word16 min_dist, /* (i) : minimum required distance */ + Word16 n, /* (i) : LPC order */ + Flag *pOverflow /* (i/o) : overflow Flag */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _REORDER_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/residu.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/residu.h new file mode 100644 index 00000000..2c6d4300 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/residu.h @@ -0,0 +1,83 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : residu.h +* Purpose : Computes the LP residual. +* Description : The LP residual is computed by filtering the input +* : speech through the LP inverse filter A(z). +* +* +******************************************************************************** +*/ +#ifndef residu_h +#define residu_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ******************************************************************************** + * DEFINITION OF DATA TYPES + ******************************************************************************** + */ + + /* + ******************************************************************************** + * DECLARATION OF PROTOTYPES + ******************************************************************************** + */ + OSCL_IMPORT_REF void Residu( + Word16 a[], /* (i) : prediction coefficients */ + Word16 x[], /* (i) : speech signal */ + Word16 y[], /* (o) : residual signal */ + Word16 lg /* (i) : size of filtering */ + ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/reverse_bits.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/reverse_bits.h new file mode 100644 index 00000000..5933e151 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/reverse_bits.h @@ -0,0 +1,100 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: reverse_bits.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the reverse_bits function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef REVERSE_BITS_H +#define REVERSE_BITS_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "mode.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void reverse_bits(enum Mode mode, unsigned char *pCompressedBlock); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/round.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/round.h new file mode 100644 index 00000000..f4f80722 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/round.h @@ -0,0 +1,98 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: round.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the pv_round function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef ROUND_H +#define ROUND_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF Word16 pv_round(Word32 L_var1, Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _ROUND_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/set_zero.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/set_zero.h new file mode 100644 index 00000000..debd223c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/set_zero.h @@ -0,0 +1,79 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : set_zero.h +* Description : Set vector x[] to zero +* +* +******************************************************************************** +*/ +#ifndef set_zero_h +#define set_zero_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ******************************************************************************** + * DEFINITION OF DATA TYPES + ******************************************************************************** + */ + + /* + ******************************************************************************** + * DECLARATION OF PROTOTYPES + ******************************************************************************** + */ + void Set_zero( + Word16 x[], /* (o) : vector to clear */ + Word16 L /* (i) : length of vector */ + ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/shl.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/shl.h new file mode 100644 index 00000000..ca09201e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/shl.h @@ -0,0 +1,102 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: shl.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the shl function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef SHL_H +#define SHL_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 shl(Word16 var1, Word16 var2, Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _SHL_H_ */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/shr.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/shr.h new file mode 100644 index 00000000..b3149a0a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/shr.h @@ -0,0 +1,99 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: shr.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the shr function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef SHR_H +#define SHR_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF Word16 shr(Word16 var1, Word16 var2, Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _SHR_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/shr_r.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/shr_r.h new file mode 100644 index 00000000..30ccf29a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/shr_r.h @@ -0,0 +1,100 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: shr_r.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the shr_r function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef SHR_R_H +#define SHR_R_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF Word16 shr_r(Word16 var1, Word16 var2, Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/sqrt_l.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/sqrt_l.h new file mode 100644 index 00000000..368e9f9c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/sqrt_l.h @@ -0,0 +1,102 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: sqrt_l.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the sqrt_l() function. + +------------------------------------------------------------------------------ +*/ + +#ifndef SQRT_L_H +#define SQRT_L_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 sqrt_l_tbl[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + OSCL_IMPORT_REF Word32 sqrt_l_exp( /* o : output value, Q31 */ + Word32 L_x, /* i : input value, Q31 */ + Word16 *pExp, /* o : right shift to be applied to result, Q1 */ + Flag *pOverflow /* i : pointer to overflow flag */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _SQRT_L__H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/sub.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/sub.h new file mode 100644 index 00000000..b28d6863 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/sub.h @@ -0,0 +1,99 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: sub.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the sub function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef SUB_H +#define SUB_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + OSCL_IMPORT_REF Word16 sub(Word16 var1, Word16 var2, Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _SUB_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/syn_filt.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/syn_filt.h new file mode 100644 index 00000000..4d8cd13f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/syn_filt.h @@ -0,0 +1,83 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : syn_filt.h +* Purpose : Perform synthesis filtering through 1/A(z). +* +* +******************************************************************************** +*/ +#ifndef syn_filt_h +#define syn_filt_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ******************************************************************************** + * DEFINITION OF DATA TYPES + ******************************************************************************** + */ + + /* + ******************************************************************************** + * DECLARATION OF PROTOTYPES + ******************************************************************************** + */ + OSCL_IMPORT_REF void Syn_filt( + Word16 a[], /* (i) : a[m+1] prediction coefficients (m=10) */ + Word16 x[], /* (i) : input signal */ + Word16 y[], /* (o) : output signal */ + Word16 lg, /* (i) : size of filtering */ + Word16 mem[], /* (i/o): memory associated with this filtering. */ + Word16 update /* (i) : 0=no update, 1=update of memory. */ + ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/typedef.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/typedef.h new file mode 100644 index 00000000..3cf16d52 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/typedef.h @@ -0,0 +1,74 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : typedef.c +* Purpose : Basic types. +* +******************************************************************************** +*/ +#include "oscl_base_macros.h"// has integer values of PV_COMPILER +#ifndef typedef_h +#define typedef_h "$Id $" + +#undef ORIGINAL_TYPEDEF_H /* CHANGE THIS TO #define to get the */ +/* "original" ETSI version of typedef.h */ +/* CHANGE TO #undef for PV version */ + +#ifdef ORIGINAL_TYPEDEF_H +/* + * this is the original code from the ETSI file typedef.h + */ + +#if defined(__unix__) || defined(__unix) +typedef signed char Word8; +typedef short Word16; +typedef int Word32; +typedef int Flag; + +#else +#error No System recognized +#endif +#else /* not original typedef.h */ + +/* + * use (improved) type definition file typdefs.h + */ +#include "gsm_amr_typedefs.h" + +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/vad.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/vad.h new file mode 100644 index 00000000..b9ee89f2 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/vad.h @@ -0,0 +1,76 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +**-------------------------------------------------------------------------** +** ** +** GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 ** +** R99 Version 3.2.0 ** +** REL-4 Version 4.0.0 ** +** ** +**-------------------------------------------------------------------------** +******************************************************************************** +* +* File : vad.h +* Purpose : Voice Activity Detection (VAD) for AMR +* +******************************************************************************** +*/ +#ifndef vad_h +#define vad_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ + +#include "vad1.h" /* for VAD option 1 */ +#include "vad2.h" /* for VAD option 2 */ + +/* +******************************************************************************** +* LOCAL VARIABLES AND TABLES +******************************************************************************** +*/ + +/* +******************************************************************************** +* DEFINITION OF DATA TYPES +******************************************************************************** +*/ + +#ifndef VAD2 +#define vadState vadState1 +#else +#define vadState vadState2 +#endif + + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/weight_a.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/weight_a.h new file mode 100644 index 00000000..cede607d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/weight_a.h @@ -0,0 +1,81 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : weight_a.h +* Purpose : Spectral expansion of LP coefficients. (order==10) +* Description : a_exp[i] = a[i] * fac[i-1] ,i=1,10 +* +* +******************************************************************************** +*/ +#ifndef weight_a_h +#define weight_a_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ******************************************************************************** + * DEFINITION OF DATA TYPES + ******************************************************************************** + */ + + /* + ******************************************************************************** + * DECLARATION OF PROTOTYPES + ******************************************************************************** + */ + OSCL_IMPORT_REF void Weight_Ai( + Word16 a[], /* (i) : a[m+1] LPC coefficients (m=10) */ + const Word16 fac[],/* (i) : Spectral expansion factors. */ + Word16 a_exp[] /* (o) : Spectral expanded LPC coefficients */ + ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/window_tab.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/window_tab.h new file mode 100644 index 00000000..5928c547 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/window_tab.h @@ -0,0 +1,103 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: window_tab.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file declares a tables in window_tab.c used in lpc.c. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef WINDOW_TAB_H +#define WINDOW_TAB_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 window_200_40[]; + extern const Word16 window_160_80[]; + extern const Word16 window_232_8[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/wmf_to_ets.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/wmf_to_ets.h new file mode 100644 index 00000000..c005f52e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/include/wmf_to_ets.h @@ -0,0 +1,108 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: wmf_to_ets.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the wmf_to_ets function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef WMF_TO_ETS_H +#define WMF_TO_ETS_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "frame_type_3gpp.h" +#include "typedef.h" +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void wmf_to_ets(enum Frame_Type_3GPP frame_type_3gpp, + UWord8 *wmf_input_ptr, + Word16 *ets_output_ptr, + CommonAmrTbls* common_amr_tbls); + + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_add.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_add.h new file mode 100644 index 00000000..ac72c310 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_add.h @@ -0,0 +1,137 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_add.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_add function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_ADD_H +#define L_ADD_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC))/* Instructions for ARM-linux cross-compiler*/ + __inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow) + { + register Word32 ra = L_var1; + register Word32 rb = L_var2; + Word32 result; + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("qadd %0, %1, %2" + : "=r"(result) + : "r"(ra), "r"(rb) + ); + return (result); + + } + +#else /* C EQUIVALENT */ + + + static inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow) + { + Word32 L_sum; + + L_sum = L_var1 + L_var2; + + if ((L_var1 ^ L_var2) >= 0) + { + if ((L_sum ^ L_var1) < 0) + { + L_sum = (L_var1 < 0) ? MIN_32 : MAX_32; + *pOverflow = 1; + } + } + + return (L_sum); + } + +#endif + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_ADD_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_mac.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_mac.h new file mode 100644 index 00000000..f6724286 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_mac.h @@ -0,0 +1,152 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: l_mac.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_mac function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_MAC_H +#define L_MAC_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC))/* Instructions for ARM-linux cross-compiler*/ + + static inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 ra = L_var3; + register Word32 rb = var1; + register Word32 rc = var2; + Word32 result; + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("smulbb %0, %1, %2" + : "=r"(result) + : "r"(rb), "r"(rc) + ); + + asm volatile("qdadd %0, %1, %2" + : "=r"(rc) + : "r"(ra), "r"(result) + ); + + return (rc); + } + +#else /* C_EQUIVALENT */ + + __inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) + { + Word32 result; + Word32 L_sum; + result = (Word32) var1 * var2; + if (result != (Word32) 0x40000000L) + { + L_sum = (result << 1) + L_var3; + + /* Check if L_sum and L_var_3 share the same sign */ + if ((L_var3 ^ result) > 0) + { + if ((L_sum ^ L_var3) < 0) + { + L_sum = (L_var3 < 0) ? MIN_32 : MAX_32; + *pOverflow = 1; + } + } + } + else + { + *pOverflow = 1; + L_sum = MAX_32; + } + return (L_sum); + } + +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_MAC_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_msu.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_msu.h new file mode 100644 index 00000000..86c5735b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_msu.h @@ -0,0 +1,137 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: l_msu.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_msu function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_MSU_H +#define L_MSU_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" +#include "l_mult.h" +#include "l_sub.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC))/* Instructions for ARM-linux cross-compiler*/ + + __inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 ra = L_var3; + register Word32 rb = var1; + register Word32 rc = var2; + Word32 product; + Word32 result; + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("smulbb %0, %1, %2" + : "=r"(product) + : "r"(rb), "r"(rc) + ); + + asm volatile("qdsub %0, %1, %2" + : "=r"(result) + : "r"(ra), "r"(product) + ); + + return (result); + } + +#else /* C EQUIVALENT */ + + static inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) + { + Word32 result; + + result = L_mult(var1, var2, pOverflow); + result = L_sub(L_var3, result, pOverflow); + + return (result); + } + +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _L_MSU_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_mult.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_mult.h new file mode 100644 index 00000000..33fedb15 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_mult.h @@ -0,0 +1,143 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_mult.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_mult function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_MULT_H +#define L_MULT_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC))/* Instructions for ARM-linux cross-compiler*/ + + __inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 ra = var1; + register Word32 rb = var2; + Word32 result; + Word32 product; + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("smulbb %0, %1, %2" + : "=r"(product) + : "r"(ra), "r"(rb) + ); + + asm volatile("qadd %0, %1, %2" + : "=r"(result) + : "r"(product), "r"(product) + ); + + return(result); + } + +#else /* C EQUIVALENT */ + + static inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 L_product; + + L_product = (Word32) var1 * var2; + + if (L_product != (Word32) 0x40000000L) + { + L_product <<= 1; /* Multiply by 2 */ + } + else + { + *pOverflow = 1; + L_product = MAX_32; + } + + return (L_product); + } +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_MULT_H */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_sub.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_sub.h new file mode 100644 index 00000000..88d86caf --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/l_sub.h @@ -0,0 +1,141 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_sub.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_sub function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_SUB_H +#define L_SUB_H + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC)) /* Instructions for ARM-linux cross-compiler*/ + + __inline Word32 L_sub(Word32 L_var1, Word32 L_var2, Flag *pOverflow) + { + register Word32 ra = L_var1; + register Word32 rb = L_var2; + Word32 result; + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("qsub %0, %1, %2" + : "=r"(result) + : "r"(ra), "r"(rb) + ); + + return (result); + } + +#else /* C EQUIVALENT */ + + static inline Word32 L_sub(register Word32 L_var1, register Word32 L_var2, + register Flag *pOverflow) + { + Word32 L_diff; + + L_diff = L_var1 - L_var2; + + if ((L_var1 ^ L_var2) < 0) + { + if ((L_diff ^ L_var1) & MIN_32) + { + L_diff = (L_var1 < 0L) ? MIN_32 : MAX_32; + *pOverflow = 1; + } + } + + return (L_diff); + } + +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _L_SUB_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/mpy_32_16.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/mpy_32_16.h new file mode 100644 index 00000000..3a68e695 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/mpy_32_16.h @@ -0,0 +1,184 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: mpy_32_16.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the Mpy_32_16 function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef MPY_32_16_H +#define MPY_32_16_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC))/* Instructions for ARM-linux cross-compiler*/ + + static inline Word32 Mpy_32_16(Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 var2, + Flag *pOverflow) + { + + register Word32 ra = L_var1_hi; + register Word32 rb = L_var1_lo; + register Word32 rc = var2; + Word32 result, L_product; + + OSCL_UNUSED_ARG(pOverflow); + + __asm__ volatile("smulbb %0, %1, %2" + : "=r"(L_product) + : "r"(ra), "r"(rc) + ); + __asm__ volatile("mov %0, #0" + : "=r"(result) + ); + + __asm__ volatile("qdadd %0, %1, %2" + : "=r"(L_product) + : "r"(result), "r"(L_product) + ); + + __asm__ volatile("smulbb %0, %1, %2" + : "=r"(result) + : "r"(rb), "r"(rc) + ); + + __asm__ volatile("mov %0, %1, ASR #15" + : "=r"(ra) + : "r"(result) + ); + __asm__ volatile("qdadd %0, %1, %2" + : "=r"(result) + : "r"(L_product), "r"(ra) + ); + + return (result); + } + +#else /* C_EQUIVALENT */ + static inline Word32 Mpy_32_16(Word16 L_var1_hi, + Word16 L_var1_lo, + Word16 var2, + Flag *pOverflow) + { + + Word32 L_product; + Word32 L_sum; + Word32 result; + L_product = (Word32) L_var1_hi * var2; + + if (L_product != (Word32) 0x40000000L) + { + L_product <<= 1; + } + else + { + *pOverflow = 1; + L_product = MAX_32; + } + + result = ((Word32)L_var1_lo * var2) >> 15; + + L_sum = L_product + (result << 1); + + if ((L_product ^ result) > 0) + { + if ((L_sum ^ L_product) < 0) + { + L_sum = (L_product < 0) ? MIN_32 : MAX_32; + *pOverflow = 1; + } + } + return (L_sum); + + } + +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _MPY_32_16_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/mult.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/mult.h new file mode 100644 index 00000000..c89a94ee --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/mult.h @@ -0,0 +1,152 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: mult.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the mult function. + +------------------------------------------------------------------------------ +*/ + +#ifndef MULT_H +#define MULT_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC)) + + __inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 ra = var1; + register Word32 rb = var2; + Word32 product; + Word32 temp = 0x7FFF; + + OSCL_UNUSED_ARG(pOverflow); + + asm volatile("smulbb %0, %1, %2" + : "=r"(product) + : "r"(ra), "r"(rb) + ); + asm volatile("mov %0, %1, ASR #15" + : "=r"(product) + : "r"(product) + ); + asm volatile("cmp %0, %1" + : "=r"(product) + : "r"(temp) + ); + asm volatile("movge %0, %1" + : "=r"(product) + : "r"(temp) + ); + + return ((Word16) product); + } + +#else /* C EQUIVALENT */ + + static inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow) + { + register Word32 product; + + product = ((Word32) var1 * var2) >> 15; + + /* Saturate result (if necessary). */ + /* var1 * var2 >0x00007fff is the only case */ + /* that saturation occurs. */ + + if (product > 0x00007fffL) + { + *pOverflow = 1; + product = (Word32) MAX_16; + } + + + /* Return the product as a 16 bit value by type casting Word32 to Word16 */ + + return ((Word16) product); + } + +#endif + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _MULT_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/add.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/add.cpp new file mode 100644 index 00000000..508a6f98 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/add.cpp @@ -0,0 +1,198 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: add.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Summation function with overflow control + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: add +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the add operation resulted in overflow + + Returns: + sum = 16-bit limited sum of var1 and var2 (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the addition (var1+var2) with overflow control and + saturation; the 16 bit result is set at +32767 when overflow occurs or at + -32768 when underflow occurs. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] add.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Word16 add (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 sum; + + sum = (Word32) var1 + var2; + +* The reference ETSI code uses a global flag for Overflow inside the function +* saturate(). In the actual implementation a pointer to Overflow flag is passed in +* as a parameter to the function + + var_out = saturate (sum); +#if (WMOPS) + multiCounter[currCounter].add++; +#endif + return (var_out); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +//lhc fix add_16 to add +OSCL_EXPORT_REF Word16 add_16(Word16 var1, Word16 var2, Flag *pOverflow) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + Word32 sum; + sum = (Word32) var1 + var2; + + /* Saturate result (if necessary). */ + /* Replaced function call with in-line code */ + /* to conserve MIPS, i.e., var_out = saturate (sum) */ + + if (sum > 0X00007fffL) + { + *pOverflow = 1; + sum = MAX_16; + } + else if (sum < (Word32) - 32768) + { + *pOverflow = 1; + sum = MIN_16; + } + + /* Return the sum as a 16 bit value by type casting Word32 to Word16 */ + + return ((Word16) sum); +} +OSCL_EXPORT_REF Word16 add(Word16 var1, Word16 var2, Flag *pOverflow) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + Word32 sum; + sum = (Word32) var1 + var2; + + /* Saturate result (if necessary). */ + /* Replaced function call with in-line code */ + /* to conserve MIPS, i.e., var_out = saturate (sum) */ + + if (sum > 0X00007fffL) + { + *pOverflow = 1; + sum = MAX_16; + } + else if (sum < (Word32) - 32768) + { + *pOverflow = 1; + sum = MIN_16; + } + + /* Return the sum as a 16 bit value by type casting Word32 to Word16 */ + + return ((Word16) sum); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/az_lsp.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/az_lsp.cpp new file mode 100644 index 00000000..7711ac9c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/az_lsp.cpp @@ -0,0 +1,665 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: az_lsp.cpp + Funtions: Chebps + Chebps_Wrapper + Az_lsp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + These modules compute the LSPs from the LP coefficients. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "az_lsp.h" +#include "cnst.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define NC M/2 /* M = LPC order, NC = M/2 */ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Chebps +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + x = input value (Word16) + f = polynomial (Word16) + n = polynomial order (Word16) + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the operations in the function resulted in saturation. + + Returns: + cheb = Chebyshev polynomial for the input value x.(Word16) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This module evaluates the Chebyshev polynomial series. + - The polynomial order is n = m/2 = 5 + - The polynomial F(z) (F1(z) or F2(z)) is given by + F(w) = 2 exp(-j5w) C(x) + where + C(x) = T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2 + and T_m(x) = cos(mw) is the mth order Chebyshev + polynomial ( x=cos(w) ) + - C(x) for the input x is returned. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + az_lsp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static Word16 Chebps (Word16 x, + Word16 f[], // (n) + Word16 n) +{ + Word16 i, cheb; + Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l; + Word32 t0; + +// The reference ETSI code uses a global flag for Overflow. However, in the +// actual implementation a pointer to Overflow flag is passed in as a +// parameter to the function. This pointer is passed into all the basic math +// functions invoked + + b2_h = 256; // b2 = 1.0 + b2_l = 0; + + t0 = L_mult (x, 512); // 2*x + t0 = L_mac (t0, f[1], 8192); // + f[1] + L_Extract (t0, &b1_h, &b1_l); // b1 = 2*x + f[1] + + for (i = 2; i < n; i++) + { + t0 = Mpy_32_16 (b1_h, b1_l, x); // t0 = 2.0*x*b1 + t0 = L_shl (t0, 1); + t0 = L_mac (t0, b2_h, (Word16) 0x8000); // t0 = 2.0*x*b1 - b2 + t0 = L_msu (t0, b2_l, 1); + t0 = L_mac (t0, f[i], 8192); // t0 = 2.0*x*b1 - b2 + f[i] + + L_Extract (t0, &b0_h, &b0_l); // b0 = 2.0*x*b1 - b2 + f[i] + + b2_l = b1_l; // b2 = b1; + b2_h = b1_h; + b1_l = b0_l; // b1 = b0; + b1_h = b0_h; + } + + t0 = Mpy_32_16 (b1_h, b1_l, x); // t0 = x*b1; + t0 = L_mac (t0, b2_h, (Word16) 0x8000); // t0 = x*b1 - b2 + t0 = L_msu (t0, b2_l, 1); + t0 = L_mac (t0, f[i], 4096); // t0 = x*b1 - b2 + f[i]/2 + + t0 = L_shl (t0, 6); + + cheb = extract_h (t0); + + return (cheb); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 Chebps(Word16 x, + Word16 f[], /* (n) */ + Word16 n, + Flag *pOverflow) +{ + Word16 i; + Word16 cheb; + Word16 b1_h; + Word16 b1_l; + Word32 t0; + Word32 L_temp; + Word16 *p_f = &f[1]; + + OSCL_UNUSED_ARG(pOverflow); + + /* L_temp = 1.0 */ + + L_temp = 0x01000000L; + + t0 = ((Word32) x << 10) + ((Word32) * (p_f++) << 14); + + /* b1 = t0 = 2*x + f[1] */ + + b1_h = (Word16)(t0 >> 16); + b1_l = (Word16)((t0 >> 1) - (b1_h << 15)); + + + for (i = 2; i < n; i++) + { + /* t0 = 2.0*x*b1 */ + t0 = ((Word32) b1_h * x); + t0 += ((Word32) b1_l * x) >> 15; + t0 <<= 2; + + /* t0 = 2.0*x*b1 - b2 */ + t0 -= L_temp; + + /* t0 = 2.0*x*b1 - b2 + f[i] */ + t0 += (Word32) * (p_f++) << 14; + + L_temp = ((Word32) b1_h << 16) + ((Word32) b1_l << 1); + + /* b0 = 2.0*x*b1 - b2 + f[i]*/ + b1_h = (Word16)(t0 >> 16); + b1_l = (Word16)((t0 >> 1) - (b1_h << 15)); + + } + + /* t0 = x*b1; */ + t0 = ((Word32) b1_h * x); + t0 += ((Word32) b1_l * x) >> 15; + t0 <<= 1; + + + /* t0 = x*b1 - b2 */ + t0 -= L_temp; + + /* t0 = x*b1 - b2 + f[i]/2 */ + t0 += (Word32) * (p_f) << 13; + + + if ((UWord32)(t0 + 33554432) < 67108863) + { + cheb = (Word16)(t0 >> 10); + } + else + { + if (t0 > (Word32) 0x01ffffffL) + { + cheb = MAX_16; + + } + else + { + cheb = MIN_16; + } + } + + return (cheb); +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Az_lsp +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS FOR Az_lsp + + Inputs: + a = predictor coefficients (Word16) + lsp = line spectral pairs (Word16) + old_lsp = old line spectral pairs (Word16) + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the operations in the function resulted in saturation. + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes the LSPs from the LP coefficients. + + The sum and difference filters are computed and divided by 1+z^{-1} and + 1-z^{-1}, respectively. + + f1[i] = a[i] + a[11-i] - f1[i-1] ; i=1,...,5 + f2[i] = a[i] - a[11-i] + f2[i-1] ; i=1,...,5 + + The roots of F1(z) and F2(z) are found using Chebyshev polynomial evaluation. + The polynomials are evaluated at 60 points regularly spaced in the + frequency domain. The sign change interval is subdivided 4 times to better + track the root. The LSPs are found in the cosine domain [1,-1]. + + If less than 10 roots are found, the LSPs from the past frame are used. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + az_lsp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Az_lsp ( + Word16 a[], // (i) : predictor coefficients (MP1) + Word16 lsp[], // (o) : line spectral pairs (M) + Word16 old_lsp[] // (i) : old lsp[] (in case not found 10 roots) (M) +) +{ + Word16 i, j, nf, ip; + Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint; + Word16 x, y, sign, exp; + Word16 *coef; + Word16 f1[M / 2 + 1], f2[M / 2 + 1]; + Word32 t0; + + *-------------------------------------------------------------* + * find the sum and diff. pol. F1(z) and F2(z) * + * F1(z) <--- F1(z)/(1+z**-1) & F2(z) <--- F2(z)/(1-z**-1) * + * * + * f1[0] = 1.0; * + * f2[0] = 1.0; * + * * + * for (i = 0; i< NC; i++) * + * { * + * f1[i+1] = a[i+1] + a[M-i] - f1[i] ; * + * f2[i+1] = a[i+1] - a[M-i] + f2[i] ; * + * } * + *-------------------------------------------------------------* + + f1[0] = 1024; // f1[0] = 1.0 + f2[0] = 1024; // f2[0] = 1.0 + +// The reference ETSI code uses a global flag for Overflow. However, in the +// actual implementation a pointer to Overflow flag is passed in as a +// parameter to the function. This pointer is passed into all the basic math +// functions invoked + + for (i = 0; i < NC; i++) + { + t0 = L_mult (a[i + 1], 8192); // x = (a[i+1] + a[M-i]) >> 2 + t0 = L_mac (t0, a[M - i], 8192); + x = extract_h (t0); + // f1[i+1] = a[i+1] + a[M-i] - f1[i] + f1[i + 1] = sub (x, f1[i]); + + t0 = L_mult (a[i + 1], 8192); // x = (a[i+1] - a[M-i]) >> 2 + t0 = L_msu (t0, a[M - i], 8192); + x = extract_h (t0); + // f2[i+1] = a[i+1] - a[M-i] + f2[i] + f2[i + 1] = add (x, f2[i]); + } + + *-------------------------------------------------------------* + * find the LSPs using the Chebychev pol. evaluation * + *-------------------------------------------------------------* + + nf = 0; // number of found frequencies + ip = 0; // indicator for f1 or f2 + + coef = f1; + + xlow = grid[0]; + ylow = Chebps (xlow, coef, NC); + + j = 0; + // while ( (nf < M) && (j < grid_points) ) + while ((sub (nf, M) < 0) && (sub (j, grid_points) < 0)) + { + j++; + xhigh = xlow; + yhigh = ylow; + xlow = grid[j]; + ylow = Chebps (xlow, coef, NC); + + if (L_mult (ylow, yhigh) <= (Word32) 0L) + { + + // divide 4 times the interval + + for (i = 0; i < 4; i++) + { + // xmid = (xlow + xhigh)/2 + xmid = add (shr (xlow, 1), shr (xhigh, 1)); + ymid = Chebps (xmid, coef, NC); + + if (L_mult (ylow, ymid) <= (Word32) 0L) + { + yhigh = ymid; + xhigh = xmid; + } + else + { + ylow = ymid; + xlow = xmid; + } + } + + *-------------------------------------------------------------* + * Linear interpolation * + * xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow); * + *-------------------------------------------------------------* + + x = sub (xhigh, xlow); + y = sub (yhigh, ylow); + + if (y == 0) + { + xint = xlow; + } + else + { + sign = y; + y = abs_s (y); + exp = norm_s (y); + y = shl (y, exp); + y = div_s ((Word16) 16383, y); + t0 = L_mult (x, y); + t0 = L_shr (t0, sub (20, exp)); + y = extract_l (t0); // y= (xhigh-xlow)/(yhigh-ylow) + + if (sign < 0) + y = negate (y); + + t0 = L_mult (ylow, y); + t0 = L_shr (t0, 11); + xint = sub (xlow, extract_l (t0)); // xint = xlow - ylow*y + } + + lsp[nf] = xint; + xlow = xint; + nf++; + + if (ip == 0) + { + ip = 1; + coef = f2; + } + else + { + ip = 0; + coef = f1; + } + ylow = Chebps (xlow, coef, NC); + + } + } + + // Check if M roots found + + if (sub (nf, M) < 0) + { + for (i = 0; i < M; i++) + { + lsp[i] = old_lsp[i]; + } + + } + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void Az_lsp( + Word16 a[], /* (i) : predictor coefficients (MP1) */ + Word16 lsp[], /* (o) : line spectral pairs (M) */ + Word16 old_lsp[], /* (i) : old lsp[] (in case not found 10 roots) (M) */ + Flag *pOverflow /* (i/o): overflow flag */ +) +{ + register Word16 i; + register Word16 j; + register Word16 nf; + register Word16 ip; + Word16 xlow; + Word16 ylow; + Word16 xhigh; + Word16 yhigh; + Word16 xmid; + Word16 ymid; + Word16 xint; + Word16 x; + Word16 y; + Word16 sign; + Word16 exp; + Word16 *coef; + Word16 f1[NC + 1]; + Word16 f2[NC + 1]; + Word32 L_temp1; + Word32 L_temp2; + Word16 *p_f1 = f1; + Word16 *p_f2 = f2; + + /*-------------------------------------------------------------* + * find the sum and diff. pol. F1(z) and F2(z) * + * F1(z) <--- F1(z)/(1+z**-1) & F2(z) <--- F2(z)/(1-z**-1) * + * * + * f1[0] = 1.0; * + * f2[0] = 1.0; * + * * + * for (i = 0; i< NC; i++) * + * { * + * f1[i+1] = a[i+1] + a[M-i] - f1[i] ; * + * f2[i+1] = a[i+1] - a[M-i] + f2[i] ; * + * } * + *-------------------------------------------------------------*/ + + *p_f1 = 1024; /* f1[0] = 1.0 */ + *p_f2 = 1024; /* f2[0] = 1.0 */ + + for (i = 0; i < NC; i++) + { + L_temp1 = (Word32) * (a + i + 1); + L_temp2 = (Word32) * (a + M - i); + /* x = (a[i+1] + a[M-i]) >> 2 */ + x = (Word16)((L_temp1 + L_temp2) >> 2); + /* y = (a[i+1] - a[M-i]) >> 2 */ + y = (Word16)((L_temp1 - L_temp2) >> 2); + /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */ + x -= *(p_f1++); + *(p_f1) = x; + /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */ + y += *(p_f2++); + *(p_f2) = y; + } + + /*-------------------------------------------------------------* + * find the LSPs using the Chebychev pol. evaluation * + *-------------------------------------------------------------*/ + + nf = 0; /* number of found frequencies */ + ip = 0; /* indicator for f1 or f2 */ + + coef = f1; + + xlow = *(grid); + ylow = Chebps(xlow, coef, NC, pOverflow); + + j = 0; + + while ((nf < M) && (j < grid_points)) + { + j++; + xhigh = xlow; + yhigh = ylow; + xlow = *(grid + j); + ylow = Chebps(xlow, coef, NC, pOverflow); + + if (((Word32)ylow*yhigh) <= 0) + { + /* divide 4 times the interval */ + for (i = 4; i != 0; i--) + { + /* xmid = (xlow + xhigh)/2 */ + x = xlow >> 1; + y = xhigh >> 1; + xmid = x + y; + + ymid = Chebps(xmid, coef, NC, pOverflow); + + if (((Word32)ylow*ymid) <= 0) + { + yhigh = ymid; + xhigh = xmid; + } + else + { + ylow = ymid; + xlow = xmid; + } + } + + /*-------------------------------------------------------------* + * Linear interpolation * + * xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow); * + *-------------------------------------------------------------*/ + + x = xhigh - xlow; + y = yhigh - ylow; + + if (y == 0) + { + xint = xlow; + } + else + { + sign = y; + y = abs_s(y); + exp = norm_s(y); + y <<= exp; + y = div_s((Word16) 16383, y); + + y = ((Word32)x * y) >> (19 - exp); + + if (sign < 0) + { + y = -y; + } + + /* xint = xlow - ylow*y */ + xint = xlow - (((Word32) ylow * y) >> 10); + } + + *(lsp + nf) = xint; + xlow = xint; + nf++; + + if (ip == 0) + { + ip = 1; + coef = f2; + } + else + { + ip = 0; + coef = f1; + } + + ylow = Chebps(xlow, coef, NC, pOverflow); + + } + } + + /* Check if M roots found */ + + if (nf < M) + { + for (i = NC; i != 0 ; i--) + { + *lsp++ = *old_lsp++; + *lsp++ = *old_lsp++; + } + } + +} + +Word16 Chebps_Wrapper(Word16 x, + Word16 f[], /* (n) */ + Word16 n, + Flag *pOverflow) +{ + return Chebps(x, f, n, pOverflow); +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/bitno_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/bitno_tab.cpp new file mode 100644 index 00000000..d0ecd396 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/bitno_tab.cpp @@ -0,0 +1,273 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: bitno_tab.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + None + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + File : bitno.tab + Purpose : Tables for bit2prm and prm2bit + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" /* parameter sizes: MAX_PRM_SIZE */ +#include "mode.h" /* N_MODES */ +#include "bitno_tab.h" + + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; LOCAL STORE/BUFFER/POINTER DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + /* number of parameters per modes (values must be <= MAX_PRM_SIZE!) */ + const Word16 prmno[N_MODES] = + { + PRMNO_MR475, + PRMNO_MR515, + PRMNO_MR59, + PRMNO_MR67, + PRMNO_MR74, + PRMNO_MR795, + PRMNO_MR102, + PRMNO_MR122, + PRMNO_MRDTX + }; + + /* number of parameters to first subframe per modes */ + const Word16 prmnofsf[N_MODES - 1] = + { + PRMNOFSF_MR475, + PRMNOFSF_MR515, + PRMNOFSF_MR59, + PRMNOFSF_MR67, + PRMNOFSF_MR74, + PRMNOFSF_MR795, + PRMNOFSF_MR102, + PRMNOFSF_MR122 + }; + + /* parameter sizes (# of bits), one table per mode */ + const Word16 bitno_MR475[PRMNO_MR475] = + { + 8, 8, 7, /* LSP VQ */ + 8, 7, 2, 8, /* first subframe */ + 4, 7, 2, /* second subframe */ + 4, 7, 2, 8, /* third subframe */ + 4, 7, 2, /* fourth subframe */ + }; + + const Word16 bitno_MR515[PRMNO_MR515] = + { + 8, 8, 7, /* LSP VQ */ + 8, 7, 2, 6, /* first subframe */ + 4, 7, 2, 6, /* second subframe */ + 4, 7, 2, 6, /* third subframe */ + 4, 7, 2, 6, /* fourth subframe */ + }; + + const Word16 bitno_MR59[PRMNO_MR59] = + { + 8, 9, 9, /* LSP VQ */ + 8, 9, 2, 6, /* first subframe */ + 4, 9, 2, 6, /* second subframe */ + 8, 9, 2, 6, /* third subframe */ + 4, 9, 2, 6, /* fourth subframe */ + }; + + const Word16 bitno_MR67[PRMNO_MR67] = + { + 8, 9, 9, /* LSP VQ */ + 8, 11, 3, 7, /* first subframe */ + 4, 11, 3, 7, /* second subframe */ + 8, 11, 3, 7, /* third subframe */ + 4, 11, 3, 7, /* fourth subframe */ + }; + + const Word16 bitno_MR74[PRMNO_MR74] = + { + 8, 9, 9, /* LSP VQ */ + 8, 13, 4, 7, /* first subframe */ + 5, 13, 4, 7, /* second subframe */ + 8, 13, 4, 7, /* third subframe */ + 5, 13, 4, 7, /* fourth subframe */ + }; + + const Word16 bitno_MR795[PRMNO_MR795] = + { + 9, 9, 9, /* LSP VQ */ + 8, 13, 4, 4, 5, /* first subframe */ + 6, 13, 4, 4, 5, /* second subframe */ + 8, 13, 4, 4, 5, /* third subframe */ + 6, 13, 4, 4, 5, /* fourth subframe */ + }; + + const Word16 bitno_MR102[PRMNO_MR102] = + { + 8, 9, 9, /* LSP VQ */ + 8, 1, 1, 1, 1, 10, 10, 7, 7, /* first subframe */ + 5, 1, 1, 1, 1, 10, 10, 7, 7, /* second subframe */ + 8, 1, 1, 1, 1, 10, 10, 7, 7, /* third subframe */ + 5, 1, 1, 1, 1, 10, 10, 7, 7, /* fourth subframe */ + }; + + const Word16 bitno_MR122[PRMNO_MR122] = + { + 7, 8, 9, 8, 6, /* LSP VQ */ + 9, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 5, /* first subframe */ + 6, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 5, /* second subframe */ + 9, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 5, /* third subframe */ + 6, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 5 /* fourth subframe */ + }; + + const Word16 bitno_MRDTX[PRMNO_MRDTX] = + { + 3, + 8, 9, 9, + 6 + }; + + /* overall table with all parameter sizes for all modes */ + const Word16 * const bitno[N_MODES] = + { + bitno_MR475, + bitno_MR515, + bitno_MR59, + bitno_MR67, + bitno_MR74, + bitno_MR795, + bitno_MR102, + bitno_MR122, + bitno_MRDTX + }; + /*---------------------------------------------------------------------------- + ; EXTERNAL FUNCTION REFERENCES + ; Declare functions defined elsewhere and referenced in this module + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; Define all local variables +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Function body here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Return nothing or data or data pointer +----------------------------------------------------------------------------*/ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/bitreorder_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/bitreorder_tab.cpp new file mode 100644 index 00000000..3245cdb3 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/bitreorder_tab.cpp @@ -0,0 +1,381 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: bitreorder_tab.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + None + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function contains tables needed to reformat the encoded speech bits + into IF2, WMF, and ETS. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + AMR Speech Codec Frame Structure, + 3GPP TS 26.101 version 4.1.0 Release 4, June 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "bitreorder_tab.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ +#define NUM_MODES 16 +#define NUMBIT_MR475 95 +#define NUMBIT_MR515 103 +#define NUMBIT_MR59 118 +#define NUMBIT_MR67 134 +#define NUMBIT_MR74 148 +#define NUMBIT_MR795 159 +#define NUMBIT_MR102 204 +#define NUMBIT_MR122 244 +#define NUMBIT_AMR_SID 39 +#define NUMBIT_GSMEFR_SID 43 +#define NUMBIT_TDMAEFR_SID 38 +#define NUMBIT_PDCEFR_SID 37 +#define NUMBIT_UNUSED1 0 +#define NUMBIT_UNUSED2 0 +#define NUMBIT_UNUSED3 0 +#define NUMBIT_NO_DATA 0 + +#define MAX_NUM_BITS 244 + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; LOCAL STORE/BUFFER/POINTER DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + /* number of parameters per modes (values must be <= MAX_PRM_SIZE!) */ + const Word16 numOfBits[NUM_MODES] = + { + NUMBIT_MR475, + NUMBIT_MR515, + NUMBIT_MR59, + NUMBIT_MR67, + NUMBIT_MR74, + NUMBIT_MR795, + NUMBIT_MR102, + NUMBIT_MR122, + NUMBIT_AMR_SID, + NUMBIT_GSMEFR_SID, + NUMBIT_TDMAEFR_SID, + NUMBIT_PDCEFR_SID, + NUMBIT_UNUSED1, + NUMBIT_UNUSED2, + NUMBIT_UNUSED3, + NUMBIT_NO_DATA + }; + + const Word16 reorderBits_MR475[NUMBIT_MR475] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 23, 24, 25, 26, + 27, 28, 48, 49, 61, 62, 82, 83, 47, 46, + 45, 44, 81, 80, 79, 78, 17, 18, 20, 22, + 77, 76, 75, 74, 29, 30, 43, 42, 41, 40, + 38, 39, 16, 19, 21, 50, 51, 59, 60, 63, + 64, 72, 73, 84, 85, 93, 94, 32, 33, 35, + 36, 53, 54, 56, 57, 66, 67, 69, 70, 87, + 88, 90, 91, 34, 55, 68, 89, 37, 58, 71, + 92, 31, 52, 65, 86 + }; + + const Word16 reorderBits_MR515[NUMBIT_MR515] = + { + 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, + 13, 12, 11, 10, 9, 8, 23, 24, 25, 26, + 27, 46, 65, 84, 45, 44, 43, 64, 63, 62, + 83, 82, 81, 102, 101, 100, 42, 61, 80, 99, + 28, 47, 66, 85, 18, 41, 60, 79, 98, 29, + 48, 67, 17, 20, 22, 40, 59, 78, 97, 21, + 30, 49, 68, 86, 19, 16, 87, 39, 38, 58, + 57, 77, 35, 54, 73, 92, 76, 96, 95, 36, + 55, 74, 93, 32, 51, 33, 52, 70, 71, 89, + 90, 31, 50, 69, 88, 37, 56, 75, 94, 34, + 53, 72, 91 + }; + + const Word16 reorderBits_MR59[NUMBIT_MR59] = + { + 0, 1, 4, 5, 3, 6, 7, 2, 13, 15, + 8, 9, 11, 12, 14, 10, 16, 28, 74, 29, + 75, 27, 73, 26, 72, 30, 76, 51, 97, 50, + 71, 96, 117, 31, 77, 52, 98, 49, 70, 95, + 116, 53, 99, 32, 78, 33, 79, 48, 69, 94, + 115, 47, 68, 93, 114, 46, 67, 92, 113, 19, + 21, 23, 22, 18, 17, 20, 24, 111, 43, 89, + 110, 64, 65, 44, 90, 25, 45, 66, 91, 112, + 54, 100, 40, 61, 86, 107, 39, 60, 85, 106, + 36, 57, 82, 103, 35, 56, 81, 102, 34, 55, + 80, 101, 42, 63, 88, 109, 41, 62, 87, 108, + 38, 59, 84, 105, 37, 58, 83, 104 + }; + + const Word16 reorderBits_MR67[NUMBIT_MR67] = + { + 0, 1, 4, 3, 5, 6, 13, 7, 2, 8, + 9, 11, 15, 12, 14, 10, 28, 82, 29, 83, + 27, 81, 26, 80, 30, 84, 16, 55, 109, 56, + 110, 31, 85, 57, 111, 48, 73, 102, 127, 32, + 86, 51, 76, 105, 130, 52, 77, 106, 131, 58, + 112, 33, 87, 19, 23, 53, 78, 107, 132, 21, + 22, 18, 17, 20, 24, 25, 50, 75, 104, 129, + 47, 72, 101, 126, 54, 79, 108, 133, 46, 71, + 100, 125, 128, 103, 74, 49, 45, 70, 99, 124, + 42, 67, 96, 121, 39, 64, 93, 118, 38, 63, + 92, 117, 35, 60, 89, 114, 34, 59, 88, 113, + 44, 69, 98, 123, 43, 68, 97, 122, 41, 66, + 95, 120, 40, 65, 94, 119, 37, 62, 91, 116, + 36, 61, 90, 115 + }; + + const Word16 reorderBits_MR74[NUMBIT_MR74] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 26, 87, 27, + 88, 28, 89, 29, 90, 30, 91, 51, 80, 112, + 141, 52, 81, 113, 142, 54, 83, 115, 144, 55, + 84, 116, 145, 58, 119, 59, 120, 21, 22, 23, + 17, 18, 19, 31, 60, 92, 121, 56, 85, 117, + 146, 20, 24, 25, 50, 79, 111, 140, 57, 86, + 118, 147, 49, 78, 110, 139, 48, 77, 53, 82, + 114, 143, 109, 138, 47, 76, 108, 137, 32, 33, + 61, 62, 93, 94, 122, 123, 41, 42, 43, 44, + 45, 46, 70, 71, 72, 73, 74, 75, 102, 103, + 104, 105, 106, 107, 131, 132, 133, 134, 135, 136, + 34, 63, 95, 124, 35, 64, 96, 125, 36, 65, + 97, 126, 37, 66, 98, 127, 38, 67, 99, 128, + 39, 68, 100, 129, 40, 69, 101, 130 + }; + + const Word16 reorderBits_MR795[NUMBIT_MR795] = + { + 8, 7, 6, 5, 4, 3, 2, 14, 16, 9, + 10, 12, 13, 15, 11, 17, 20, 22, 24, 23, + 19, 18, 21, 56, 88, 122, 154, 57, 89, 123, + 155, 58, 90, 124, 156, 52, 84, 118, 150, 53, + 85, 119, 151, 27, 93, 28, 94, 29, 95, 30, + 96, 31, 97, 61, 127, 62, 128, 63, 129, 59, + 91, 125, 157, 32, 98, 64, 130, 1, 0, 25, + 26, 33, 99, 34, 100, 65, 131, 66, 132, 54, + 86, 120, 152, 60, 92, 126, 158, 55, 87, 121, + 153, 117, 116, 115, 46, 78, 112, 144, 43, 75, + 109, 141, 40, 72, 106, 138, 36, 68, 102, 134, + 114, 149, 148, 147, 146, 83, 82, 81, 80, 51, + 50, 49, 48, 47, 45, 44, 42, 39, 35, 79, + 77, 76, 74, 71, 67, 113, 111, 110, 108, 105, + 101, 145, 143, 142, 140, 137, 133, 41, 73, 107, + 139, 37, 69, 103, 135, 38, 70, 104, 136 + }; + + const Word16 reorderBits_MR102[NUMBIT_MR102] = + { + 7, 6, 5, 4, 3, 2, 1, 0, 16, 15, + 14, 13, 12, 11, 10, 9, 8, 26, 27, 28, + 29, 30, 31, 115, 116, 117, 118, 119, 120, 72, + 73, 161, 162, 65, 68, 69, 108, 111, 112, 154, + 157, 158, 197, 200, 201, 32, 33, 121, 122, 74, + 75, 163, 164, 66, 109, 155, 198, 19, 23, 21, + 22, 18, 17, 20, 24, 25, 37, 36, 35, 34, + 80, 79, 78, 77, 126, 125, 124, 123, 169, 168, + 167, 166, 70, 67, 71, 113, 110, 114, 159, 156, + 160, 202, 199, 203, 76, 165, 81, 82, 92, 91, + 93, 83, 95, 85, 84, 94, 101, 102, 96, 104, + 86, 103, 87, 97, 127, 128, 138, 137, 139, 129, + 141, 131, 130, 140, 147, 148, 142, 150, 132, 149, + 133, 143, 170, 171, 181, 180, 182, 172, 184, 174, + 173, 183, 190, 191, 185, 193, 175, 192, 176, 186, + 38, 39, 49, 48, 50, 40, 52, 42, 41, 51, + 58, 59, 53, 61, 43, 60, 44, 54, 194, 179, + 189, 196, 177, 195, 178, 187, 188, 151, 136, 146, + 153, 134, 152, 135, 144, 145, 105, 90, 100, 107, + 88, 106, 89, 98, 99, 62, 47, 57, 64, 45, + 63, 46, 55, 56 + }; + + const Word16 reorderBits_MR122[NUMBIT_MR122] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 23, 15, 16, 17, 18, + 19, 20, 21, 22, 24, 25, 26, 27, 28, 38, + 141, 39, 142, 40, 143, 41, 144, 42, 145, 43, + 146, 44, 147, 45, 148, 46, 149, 47, 97, 150, + 200, 48, 98, 151, 201, 49, 99, 152, 202, 86, + 136, 189, 239, 87, 137, 190, 240, 88, 138, 191, + 241, 91, 194, 92, 195, 93, 196, 94, 197, 95, + 198, 29, 30, 31, 32, 33, 34, 35, 50, 100, + 153, 203, 89, 139, 192, 242, 51, 101, 154, 204, + 55, 105, 158, 208, 90, 140, 193, 243, 59, 109, + 162, 212, 63, 113, 166, 216, 67, 117, 170, 220, + 36, 37, 54, 53, 52, 58, 57, 56, 62, 61, + 60, 66, 65, 64, 70, 69, 68, 104, 103, 102, + 108, 107, 106, 112, 111, 110, 116, 115, 114, 120, + 119, 118, 157, 156, 155, 161, 160, 159, 165, 164, + 163, 169, 168, 167, 173, 172, 171, 207, 206, 205, + 211, 210, 209, 215, 214, 213, 219, 218, 217, 223, + 222, 221, 73, 72, 71, 76, 75, 74, 79, 78, + 77, 82, 81, 80, 85, 84, 83, 123, 122, 121, + 126, 125, 124, 129, 128, 127, 132, 131, 130, 135, + 134, 133, 176, 175, 174, 179, 178, 177, 182, 181, + 180, 185, 184, 183, 188, 187, 186, 226, 225, 224, + 229, 228, 227, 232, 231, 230, 235, 234, 233, 238, + 237, 236, 96, 199 + }; + + /* overall table with all parameter sizes for all modes */ + const Word16 * const reorderBits[NUM_MODES-1] = + { + reorderBits_MR475, + reorderBits_MR515, + reorderBits_MR59, + reorderBits_MR67, + reorderBits_MR74, + reorderBits_MR795, + reorderBits_MR102, + reorderBits_MR122 + }; + + /* Number of Frames (16-bit segments sent for each mode */ + const Word16 numCompressedBytes[16] = + { + 13, /*4.75*/ + 14, /*5.15*/ + 16, /*5.90*/ + 18, /*6.70*/ + 19, /*7.40*/ + 21, /*7.95*/ + 26, /*10.2*/ + 31, /*12.2*/ + 6, /*GsmAmr comfort noise*/ + 6, /*Gsm-Efr comfort noise*/ + 6, /*IS-641 comfort noise*/ + 6, /*Pdc-Efr comfort noise*/ + 0, /*future use*/ + 0, /*future use*/ + 0, /*future use*/ + 1 /*No transmission*/ + }; + /*---------------------------------------------------------------------------- + ; EXTERNAL FUNCTION REFERENCES + ; Declare functions defined elsewhere and referenced in this module + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; Define all local variables +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Function body here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Return nothing or data or data pointer +----------------------------------------------------------------------------*/ + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/bits2prm.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/bits2prm.cpp new file mode 100644 index 00000000..f497b5d1 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/bits2prm.cpp @@ -0,0 +1,249 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: bits2prm.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +//#include "bits2prm.h" +#include "typedef.h" +#include "mode.h" +#include "bitno_tab.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Bin2int +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + no_of_bits = number of bits associated with value + bitstream = pointer to buffer where bits are read + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function : Bin2int + Purpose : Read "no_of_bits" bits from the array bitstream[] + and convert to integer. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + bits2prm.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static Word16 Bin2int ( // Reconstructed parameter + Word16 no_of_bits, // input : number of bits associated with value + Word16 *bitstream // output: address where bits are written +) +{ + Word16 value, i, bit; + + value = 0; + for (i = 0; i < no_of_bits; i++) + { + value = shl (value, 1); + bit = *bitstream++; + if (sub (bit, BIT_1) == 0) + value = add (value, 1); + } + return (value); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +static Word16 Bin2int( /* Reconstructed parameter */ + Word16 no_of_bits, /* input : number of bits associated with value */ + Word16 *bitstream /* input: address where bits are read from */ +) +{ + Word16 value; + Word16 i; + Word16 single_bit; + + value = 0; + for (i = 0; i < no_of_bits; i++) + { + value <<= 1; + single_bit = *(bitstream++); + value |= single_bit; + } + return (value); +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: bits2prm +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + mode = AMR mode of type enum Mode + bits[] = pointer to serial bits of type Word16 + prm[] = pointer to analysis parameters of type Word16 + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function : Bits2prm + Purpose : Retrieves the vector of encoder parameters from + the received serial bits in a frame. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + bits2prm.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Bits2prm ( + enum Mode mode, // i : AMR mode + Word16 bits[], // i : serial bits (size <= MAX_SERIAL_SIZE) + Word16 prm[] // o : analysis parameters (size <= MAX_PRM_SIZE) +) +{ + Word16 i; + + for (i = 0; i < prmno[mode]; i++) + { + prm[i] = Bin2int (bitno[mode][i], bits); + bits += bitno[mode][i]; + add(0,0); // account for above pointer update + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +OSCL_EXPORT_REF void Bits2prm( + enum Mode mode, /* i : AMR mode */ + Word16 bits[], /* i : serial bits (size <= MAX_SERIAL_SIZE) */ + Word16 prm[] /* o : analysis parameters (size <= MAX_PRM_SIZE) */ +) +{ + Word16 i; + + for (i = 0; i < prmno[mode]; i++) + { + prm[i] = Bin2int(bitno[mode][i], bits); + bits += bitno[mode][i]; + } + + return; +} + + + + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/c2_9pf_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/c2_9pf_tab.cpp new file mode 100644 index 00000000..4db7e9b9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/c2_9pf_tab.cpp @@ -0,0 +1,137 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: c2_9pf_tab.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the declaration for startPos[] used by the functions + c2_9pf.c and d2_9pf.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + + extern const Word16 startPos[]; + const Word16 startPos[2*4*2] = + { + 0, 2, 0, 3, + 0, 2, 0, 3, + 1, 3, 2, 4, + 1, 4, 1, 4 + }; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] c2_9pf.c UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/copy.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/copy.cpp new file mode 100644 index 00000000..9a01d037 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/copy.cpp @@ -0,0 +1,86 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* File : copy.h +* +******************************************************************************** +*/ + +/* +******************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +******************************************************************************** +*/ +//#include "copy.h" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" +#include "basic_op.h" +#include "oscl_mem.h" + +/* +******************************************************************************** +* PUBLIC PROGRAM CODE +******************************************************************************** +*/ +/************************************************************************* + * + * FUNCTION: Copy + * + * PURPOSE: Copy vector x[] to y[] + * + * + *************************************************************************/ +/* +************************************************************************** +* +* Function : Copy +* Purpose : Copy vector x[] to y[] +* +************************************************************************** +*/ +void Copy( + const Word16 x[], /* i : input vector (L) */ + Word16 y[], /* o : output vector (L) */ + Word16 L /* i : vector length */ +) +{ + oscl_memmove(y, x, L*sizeof(*x)); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/div_32.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/div_32.cpp new file mode 100644 index 00000000..ea02926d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/div_32.cpp @@ -0,0 +1,172 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: div_32.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: div_32 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_num = 32 bit signed integer (Word32) whose value falls in the + range : 0x0000 0000 < L_num < L_denom + L_denom_hi = 16 bit positive normalized integer whose value falls in + the range : 0x4000 < hi < 0x7fff + L_denom_lo = 16 bit positive integer whose value falls in the range : + 0 < lo < 0x7fff + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit divide operation resulted in overflow + + Returns: + result = 32-bit quotient of of the division of two 32 bit integers + L_num / L_denom (Word32) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function is a fractional integer division of two 32 bit numbers, the + numerator L_num and the denominator L_denom. The denominator is formed by + combining denom_hi and denom_lo. Note that denom_hi is a normalized numbers. + The numerator and denominator must be positive and the numerator must be + less than the denominator. + + The division is done as follows: + 1. Find 1/L_denom by first approximating: approx = 1 / denom_hi. + 2. 1/L_denom = approx * (2.0 - L_denom * approx ). + 3. result = L_num * (1/L_denom). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] div_32() function in oper_32b.c, UMTS GSM AMR speech codec, R99 - + Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word32 Div_32(Word32 L_num, + Word16 L_denom_hi, + Word16 L_denom_lo, + Flag *pOverflow) +{ + + Word16 approx; + Word16 hi; + Word16 lo; + Word16 n_hi; + Word16 n_lo; + Word32 result; + + /* First approximation: 1 / L_denom = 1/L_denom_hi */ + + approx = div_s((Word16) 0x3fff, L_denom_hi); + + /* 1/L_denom = approx * (2.0 - L_denom * approx) */ + + result = Mpy_32_16(L_denom_hi, L_denom_lo, approx, pOverflow); + /* result is > 0 , and less than 1.0 */ + result = 0x7fffffffL - result; + + hi = (Word16)(result >> 16); + lo = (result >> 1) - (hi << 15); + + result = Mpy_32_16(hi, lo, approx, pOverflow); + + /* L_num * (1/L_denom) */ + + hi = (Word16)(result >> 16); + lo = (result >> 1) - (hi << 15); + + n_hi = (Word16)(L_num >> 16); + n_lo = (L_num >> 1) - (n_hi << 15); + + result = Mpy_32(n_hi, n_lo, hi, lo, pOverflow); + result = L_shl(result, 2, pOverflow); + + return (result); +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/div_s.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/div_s.cpp new file mode 100644 index 00000000..f60f18b6 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/div_s.cpp @@ -0,0 +1,235 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: div_s.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit signed integer (Word16) whose value falls in + the range : 0x0000 <= var1 <= 0x7fff. + var2 = 16 bit signed integer (Word16) whose value falls in + the range : 0x0000 <= var1 <= 0x7fff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + var_out = quotient of var1 divided by var2 (Word16) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function produces a result which is the fractional integer division of + var1 by var2; var1 and var2 must be positive and var2 must be greater or equal + to var1; the result is positive (leading bit equal to 0) and truncated to 16 + bits. If var1 = var2 then div(var1,var2) = 32767. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 div_s (Word16 var1, Word16 var2) +{ + Word16 var_out = 0; + Word16 iteration; + Word32 L_num; + Word32 L_denom; + Word16 abort_flag = 0; + + if ((var1 > var2) || (var1 < 0)) + { + printf ("Division Error var1=%d var2=%d\n", var1, var2); + abort_flag = 1; + exit(0); + } + if ((var1 != 0) && (abort_flag == 0)) + { + if (var1 == var2) + { + var_out = MAX_16; + } + else + { + L_num = (Word32) var1; + L_denom = (Word32) var2; + + for (iteration = 15; iteration > 0; iteration--) + { + var_out <<= 1; + L_num <<= 1; + + if (L_num >= L_denom) + { + L_num -= L_denom; + var_out += 1; + } + } + } + } + +#if (WMOPS) + multiCounter[currCounter].div_s++; +#endif + return (var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +OSCL_EXPORT_REF Word16 div_s(register Word16 var1, register Word16 var2) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + Word16 var_out = 0; + register Word16 iteration; + Word32 L_num; + Word32 L_denom; + Word32 L_denom_by_2; + Word32 L_denom_by_4; + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + if ((var1 > var2) || (var1 < 0)) + { + return 0; // used to exit(0); + } + if (var1) + { + if (var1 != var2) + { + + L_num = (Word32) var1; + L_denom = (Word32) var2; + L_denom_by_2 = (L_denom << 1); + L_denom_by_4 = (L_denom << 2); + for (iteration = 5; iteration > 0; iteration--) + { + var_out <<= 3; + L_num <<= 3; + + if (L_num >= L_denom_by_4) + { + L_num -= L_denom_by_4; + var_out |= 4; + } + + if (L_num >= L_denom_by_2) + { + L_num -= L_denom_by_2; + var_out |= 2; + } + + if (L_num >= (L_denom)) + { + L_num -= (L_denom); + var_out |= 1; + } + + } + } + else + { + var_out = MAX_16; + } + } + +#if (WMOPS) + multiCounter[currCounter].div_s++; +#endif + + /*---------------------------------------------------------------------------- + ; Return nothing or data or data pointer + ----------------------------------------------------------------------------*/ + return (var_out); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/extract_h.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/extract_h.cpp new file mode 100644 index 00000000..54d0deea --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/extract_h.cpp @@ -0,0 +1,144 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: extract_h.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32 ) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + L_var1 = Most significant word of input (Word16) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function returns the 16 MSB of the input, L_var1. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 extract_h (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) (L_var1 >> 16); +#if (WMOPS) + multiCounter[currCounter].extract_h++; +#endif + return (var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word16 extract_h(Word32 L_var1) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; Return nothing or data or data pointer + ----------------------------------------------------------------------------*/ + return ((Word16)(L_var1 >> 16)); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/extract_l.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/extract_l.cpp new file mode 100644 index 00000000..a96519ba --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/extract_l.cpp @@ -0,0 +1,143 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: extract_l.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32 ) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + L_var1 = Most significant word of input (Word16) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function returns the 16 LSB of the input, L_var1. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 extract_l (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) L_var1; +#if (WMOPS) + multiCounter[currCounter].extract_l++; +#endif + return (var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word16 extract_l(Word32 L_var1) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; Return nothing or data or data pointer + ----------------------------------------------------------------------------*/ + return ((Word16) L_var1); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/gains_tbl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/gains_tbl.cpp new file mode 100644 index 00000000..925c1dc9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/gains_tbl.cpp @@ -0,0 +1,188 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: gains_tbl.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ +#define NB_QUA_PITCH 16 +#define NB_QUA_CODE 32 + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + + + extern const Word16 qua_gain_pitch[]; + const Word16 qua_gain_pitch[NB_QUA_PITCH] = + { + 0, 3277, 6556, 8192, 9830, 11469, 12288, 13107, + 13926, 14746, 15565, 16384, 17203, 18022, 18842, 19661 + }; + + + extern const Word16 qua_gain_code[]; + const Word16 qua_gain_code[(NB_QUA_CODE+1)*3] = + { + /* gain factor (g_fac) and quantized energy error (qua_ener_MR122, qua_ener) + * are stored: + * + * qua_ener_MR122 = log2(g_fac) (not the rounded floating point value, but + * the value the original EFR algorithm + * calculates from g_fac [using Log2]) + * qua_ener = 20*log10(g_fac); (rounded floating point value) + * + * + * g_fac (Q11), qua_ener_MR122 (Q10), qua_ener (Q10) + */ + 159, -3776, -22731, + 206, -3394, -20428, + 268, -3005, -18088, + 349, -2615, -15739, + 419, -2345, -14113, + 482, -2138, -12867, + 554, -1932, -11629, + 637, -1726, -10387, + 733, -1518, -9139, + 842, -1314, -7906, + 969, -1106, -6656, + 1114, -900, -5416, + 1281, -694, -4173, + 1473, -487, -2931, + 1694, -281, -1688, + 1948, -75, -445, + 2241, 133, 801, + 2577, 339, 2044, + 2963, 545, 3285, + 3408, 752, 4530, + 3919, 958, 5772, + 4507, 1165, 7016, + 5183, 1371, 8259, + 5960, 1577, 9501, + 6855, 1784, 10745, + 7883, 1991, 11988, + 9065, 2197, 13231, + 10425, 2404, 14474, + 12510, 2673, 16096, + 16263, 3060, 18429, + 21142, 3448, 20763, + 27485, 3836, 23097, + 27485, 3836, 23097 + }; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] gains.tab, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/gc_pred.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/gc_pred.cpp new file mode 100644 index 00000000..71519e91 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/gc_pred.cpp @@ -0,0 +1,982 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: gc_pred.cpp + Functions: + gc_pred_reset + gc_pred + gc_pred_update + gc_pred_average_limited + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the functions that perform codebook gain MA prediction. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "gc_pred.h" +#include "basicop_malloc.h" +#include "basic_op.h" +#include "cnst.h" +#include "log2.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define NPRED 4 /* number of prediction taps */ + +/* average innovation energy. */ +/* MEAN_ENER = 36.0/constant, constant = 20*Log10(2) */ +#define MEAN_ENER_MR122 783741L /* 36/(20*log10(2)) (Q17) */ + +/* minimum quantized energy: -14 dB */ +#define MIN_ENERGY -14336 /* 14 Q10 */ +#define MIN_ENERGY_MR122 -2381 /* 14 / (20*log10(2)) Q10 */ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* MA prediction coefficients (Q13) */ +static const Word16 pred[NPRED] = {5571, 4751, 2785, 1556}; + +/* MA prediction coefficients (Q6) */ +static const Word16 pred_MR122[NPRED] = {44, 37, 22, 12}; + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gc_pred_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a structure of type gc_predState + + Outputs: + past_qua_en field in the structure pointed to by state is initialized + to MIN_ENERGY + past_qua_en_MR122 field in the structure pointed to by state is + initialized to MIN_ENERGY_MR122 + + Returns: + return_value = 0, if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function initializes the state memory used by gc_pred to zero. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int gc_pred_reset (gc_predState *state) +{ + Word16 i; + + if (state == (gc_predState *) NULL){ + fprintf(stderr, "gc_pred_reset: invalid parameter\n"); + return -1; + } + + for(i = 0; i < NPRED; i++) + { + state->past_qua_en[i] = MIN_ENERGY; + state->past_qua_en_MR122[i] = MIN_ENERGY_MR122; + } + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF Word16 gc_pred_reset(gc_predState *state) +{ + Word16 i; + + if (state == (gc_predState *) NULL) + { + /* fprintf(stderr, "gc_pred_reset: invalid parameter\n"); */ + return -1; + } + + for (i = 0; i < NPRED; i++) + { + state->past_qua_en[i] = MIN_ENERGY; + state->past_qua_en_MR122[i] = MIN_ENERGY_MR122; + } + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gc_pred +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type gc_predState + mode = AMR mode (enum Mode) + code = pointer to the innovative codebook vector; Q12 in MR122 mode, + otherwise, Q13 (Word16) + exp_gcode0 = pointer to the exponent part of predicted gain factor + (Q0) (Word16) + frac_gcode0 = pointer to the fractional part of predicted gain factor + (Q15) (Word16) + exp_en = pointer to the exponent part of the innovation energy; this + is calculated for MR795 mode, Q0 (Word16) + frac_en = pointer to the fractional part of the innovation energy; + this is calculated for MR795 mode, Q15 (Word16) + pOverflow = pointer to overflow (Flag) + + Outputs: + store pointed to by exp_gcode0 contains the exponent part of the + recently calculated predicted gain factor + store pointed to by frac_gcode0 contains the fractional part of the + recently calculated predicted gain factor + store pointed to by exp_en contains the exponent part of the + recently calculated innovation energy + store pointed to by frac_en contains the fractional part of the + recently calculated innovation energy + pOverflow = 1 if the math functions called by gc_pred + results in overflow else zero. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + pred = table of MA prediction coefficients (Q13) (Word16) + pred_MR122 = table of MA prediction coefficients (Q6) (Word16) + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the MA prediction of the innovation energy (in + dB/(20*log10(2))), with the mean removed. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +The original etsi reference code uses a global flag Overflow. However, in the +actual implementation a pointer to a the overflow flag is passed in. + +void +gc_pred( + gc_predState *st, // i/o: State struct + enum Mode mode, // i : AMR mode + Word16 *code, // i : innovative codebook vector (L_SUBFR) + // MR122: Q12, other modes: Q13 + Word16 *exp_gcode0, // o : exponent of predicted gain factor, Q0 + Word16 *frac_gcode0,// o : fraction of predicted gain factor Q15 + Word16 *exp_en, // o : exponent of innovation energy, Q0 + // (only calculated for MR795) + Word16 *frac_en // o : fraction of innovation energy, Q15 + // (only calculated for MR795) +) +{ + Word16 i; + Word32 ener_code; + Word16 exp, frac; + + *-------------------------------------------------------------------* + * energy of code: * + * ~~~~~~~~~~~~~~~ * + * ener_code = sum(code[i]^2) * + *-------------------------------------------------------------------* + ener_code = L_mac((Word32) 0, code[0], code[0]); + // MR122: Q12*Q12 -> Q25 + // others: Q13*Q13 -> Q27 + for (i = 1; i < L_SUBFR; i++) + ener_code = L_mac(ener_code, code[i], code[i]); + + if (sub (mode, MR122) == 0) + { + Word32 ener; + + // ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 + ener_code = L_mult (pv_round (ener_code), 26214); // Q9 * Q20 -> Q30 + + *-------------------------------------------------------------------* + * energy of code: * + * ~~~~~~~~~~~~~~~ * + * ener_code(Q17) = 10 * Log10(energy) / constant * + * = 1/2 * Log2(energy) * + * constant = 20*Log10(2) * + *-------------------------------------------------------------------* + // ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 + Log2(ener_code, &exp, &frac); + ener_code = L_Comp (sub (exp, 30), frac); // Q16 for log() + // ->Q17 for 1/2 log() + + *-------------------------------------------------------------------* + * predicted energy: * + * ~~~~~~~~~~~~~~~~~ * + * ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant * + * = MEAN_ENER + sum(pred[i]*past_qua_en[i]) * + * constant = 20*Log10(2) * + *-------------------------------------------------------------------* + + ener = MEAN_ENER_MR122; // Q24 (Q17) + for (i = 0; i < NPRED; i++) + { + ener = L_mac (ener, st->past_qua_en_MR122[i], pred_MR122[i]); + // Q10 * Q13 -> Q24 + // Q10 * Q6 -> Q17 + } + + *-------------------------------------------------------------------* + * predicted codebook gain * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 ) * + * = Pow2(ener-ener_code) * + * = Pow2(int(d)+frac(d)) * + * * + * (store exp and frac for pow2()) * + *-------------------------------------------------------------------* + + ener = L_shr (L_sub (ener, ener_code), 1); // Q16 + L_Extract(ener, exp_gcode0, frac_gcode0); + } + else // all modes except 12.2 + { + Word32 L_tmp; + Word16 exp_code, gcode0; + + *-----------------------------------------------------------------* + * Compute: means_ener - 10log10(ener_code/ L_sufr) * + *-----------------------------------------------------------------* + + exp_code = norm_l (ener_code); + ener_code = L_shl (ener_code, exp_code); + + // Log2 = log2 + 27 + Log2_norm (ener_code, exp_code, &exp, &frac); + + // fact = 10/log2(10) = 3.01 = 24660 Q13 + L_tmp = Mpy_32_16(exp, frac, -24660); // Q0.Q15 * Q13 -> Q14 + + * L_tmp = means_ener - 10log10(ener_code/L_SUBFR) + * = means_ener - 10log10(ener_code) + 10log10(L_SUBFR) + * = K - fact * Log2(ener_code) + * = K - fact * log2(ener_code) - fact*27 + * + * ==> K = means_ener + fact*27 + 10log10(L_SUBFR) + * + * means_ener = 33 = 540672 Q14 (MR475, MR515, MR59) + * means_ener = 28.75 = 471040 Q14 (MR67) + * means_ener = 30 = 491520 Q14 (MR74) + * means_ener = 36 = 589824 Q14 (MR795) + * means_ener = 33 = 540672 Q14 (MR102) + * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14 + * fact * 27 = 1331640 Q14 + * ----------------------------------------- + * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2 + * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2 + * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2 + * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2 + * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2 + + + if (sub (mode, MR102) == 0) + { + // mean = 33 dB + L_tmp = L_mac(L_tmp, 16678, 64); // Q14 + } + else if (sub (mode, MR795) == 0) + { + // ener_code = * 2^27*2^exp_code + // frac_en = ener_code / 2^16 + // = * 2^11*2^exp_code + // = *2^11*2^exp * 2^exp_en + // := frac_en * 2^exp_en + + // ==> exp_en = -11-exp_code; + + *frac_en = extract_h (ener_code); + *exp_en = sub (-11, exp_code); + + // mean = 36 dB + L_tmp = L_mac(L_tmp, 17062, 64); // Q14 + } + else if (sub (mode, MR74) == 0) + { + // mean = 30 dB + L_tmp = L_mac(L_tmp, 32588, 32); // Q14 + } + else if (sub (mode, MR67) == 0) + { + // mean = 28.75 dB + L_tmp = L_mac(L_tmp, 32268, 32); // Q14 + } + else // MR59, MR515, MR475 + { + // mean = 33 dB + L_tmp = L_mac(L_tmp, 16678, 64); // Q14 + } + + *-----------------------------------------------------------------* + * Compute gcode0. * + * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener * + *-----------------------------------------------------------------* + + L_tmp = L_shl(L_tmp, 10); // Q24 + for (i = 0; i < 4; i++) + L_tmp = L_mac(L_tmp, pred[i], st->past_qua_en[i]); + // Q13 * Q10 -> Q24 + + gcode0 = extract_h(L_tmp); // Q8 + + *-----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) * + * = pow(2, 3.3219*gcode0/20) * + * = pow(2, 0.166*gcode0) * + *-----------------------------------------------------------------* + + // 5439 Q15 = 0.165985 + // (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15) + if (sub (mode, MR74) == 0) // For IS641 bitexactness + L_tmp = L_mult(gcode0, 5439); // Q8 * Q15 -> Q24 + else + L_tmp = L_mult(gcode0, 5443); // Q8 * Q15 -> Q24 + + L_tmp = L_shr(L_tmp, 8); // -> Q16 + L_Extract(L_tmp, exp_gcode0, frac_gcode0); // -> Q0.Q15 + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void gc_pred( + gc_predState *st, /* i/o: State struct */ + enum Mode mode, /* i : AMR mode */ + Word16 *code, /* i : innovative codebook vector (L_SUBFR) */ + /* MR122: Q12, other modes: Q13 */ + Word16 *exp_gcode0, /* o : exponent of predicted gain factor, Q0 */ + Word16 *frac_gcode0,/* o : fraction of predicted gain factor Q15 */ + Word16 *exp_en, /* o : exponent of innovation energy, Q0 */ + /* (only calculated for MR795) */ + Word16 *frac_en, /* o : fraction of innovation energy, Q15 */ + /* (only calculated for MR795) */ + Flag *pOverflow +) +{ + register Word16 i; + register Word32 L_temp1, L_temp2; + register Word32 L_tmp; + Word32 ener_code; + Word32 ener; + Word16 exp, frac; + Word16 exp_code, gcode0; + Word16 tmp; + Word16 *p_code = &code[0]; + + /*-------------------------------------------------------------------* + * energy of code: * + * ~~~~~~~~~~~~~~~ * + * ener_code = sum(code[i]^2) * + *-------------------------------------------------------------------*/ + ener_code = 0; + + /* MR122: Q12*Q12 -> Q25 */ + /* others: Q13*Q13 -> Q27 */ + + for (i = L_SUBFR >> 2; i != 0; i--) + { + tmp = *(p_code++); + ener_code += ((Word32) tmp * tmp) >> 3; + tmp = *(p_code++); + ener_code += ((Word32) tmp * tmp) >> 3; + tmp = *(p_code++); + ener_code += ((Word32) tmp * tmp) >> 3; + tmp = *(p_code++); + ener_code += ((Word32) tmp * tmp) >> 3; + } + + ener_code <<= 4; + + if ((ener_code >> 31)) /* Check for saturation */ + { + ener_code = MAX_32; + } + + if (mode == MR122) + { + /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 */ + /* Q9 * Q20 -> Q30 */ + + ener_code = ((Word32)(pv_round(ener_code, pOverflow) * 26214)) << 1; + + /*-------------------------------------------------------------* + * energy of code: * + * ~~~~~~~~~~~~~~~ * + * ener_code(Q17) = 10 * Log10(energy) / constant * + * = 1/2 * Log2(energy) * + * constant = 20*Log10(2) * + *-------------------------------------------------------------*/ + /* ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 */ + Log2(ener_code, &exp, &frac, pOverflow); + + /* Q16 for log() */ + /* ->Q17 for 1/2 log()*/ + + L_temp1 = (Word32)(exp - 30) << 16; + ener_code = L_temp1 + ((Word32)frac << 1); + + /*-------------------------------------------------------------* + * predicted energy: * + * ~~~~~~~~~~~~~~~~~ * + * ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant * + * = MEAN_ENER + sum(pred[i]*past_qua_en[i]) * + * constant = 20*Log10(2) * + *-------------------------------------------------------------*/ + + ener = MEAN_ENER_MR122; /* Q24 (Q17) */ + for (i = 0; i < NPRED; i++) + { + L_temp1 = (((Word32) st->past_qua_en_MR122[i]) * + pred_MR122[i]) << 1; + ener = L_add(ener, L_temp1, pOverflow); + + /* Q10 * Q13 -> Q24 */ + /* Q10 * Q6 -> Q17 */ + } + + /*---------------------------------------------------------------* + * predicted codebook gain * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 ) * + * = Pow2(ener-ener_code) * + * = Pow2(int(d)+frac(d)) * + * * + * (store exp and frac for pow2()) * + *---------------------------------------------------------------*/ + /* Q16 */ + + L_temp1 = L_sub(ener, ener_code, pOverflow); + + + *exp_gcode0 = (Word16)(L_temp1 >> 17); + + L_temp2 = (Word32) * exp_gcode0 << 15; + L_temp1 >>= 2; + + *frac_gcode0 = (Word16)(L_temp1 - L_temp2); + + } + else /* all modes except 12.2 */ + { + /*-----------------------------------------------------------------* + * Compute: means_ener - 10log10(ener_code/ L_sufr) * + *-----------------------------------------------------------------*/ + + exp_code = norm_l(ener_code); + ener_code = L_shl(ener_code, exp_code, pOverflow); + + /* Log2 = log2 + 27 */ + Log2_norm(ener_code, exp_code, &exp, &frac); + + /* fact = 10/log2(10) = 3.01 = 24660 Q13 */ + /* Q0.Q15 * Q13 -> Q14 */ + + L_temp2 = (((Word32) exp) * -24660) << 1; + L_tmp = (((Word32) frac) * -24660) >> 15; + + /* Sign-extend resulting product */ + if (L_tmp & (Word32) 0x00010000L) + { + L_tmp = L_tmp | (Word32) 0xffff0000L; + } + + L_tmp = L_tmp << 1; + L_tmp = L_add(L_tmp, L_temp2, pOverflow); + + + /* L_tmp = means_ener - 10log10(ener_code/L_SUBFR) + * = means_ener - 10log10(ener_code) + 10log10(L_SUBFR) + * = K - fact * Log2(ener_code) + * = K - fact * log2(ener_code) - fact*27 + * + * ==> K = means_ener + fact*27 + 10log10(L_SUBFR) + * + * means_ener = 33 = 540672 Q14 (MR475, MR515, MR59) + * means_ener = 28.75 = 471040 Q14 (MR67) + * means_ener = 30 = 491520 Q14 (MR74) + * means_ener = 36 = 589824 Q14 (MR795) + * means_ener = 33 = 540672 Q14 (MR102) + * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14 + * fact * 27 = 1331640 Q14 + * ----------------------------------------- + * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2 + * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2 + * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2 + * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2 + * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2 + */ + + if (mode == MR102) + { + /* mean = 33 dB */ + L_temp2 = (Word32) 16678 << 7; + L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ + } + else if (mode == MR795) + { + /* ener_code = * 2^27*2^exp_code + frac_en = ener_code / 2^16 + = * 2^11*2^exp_code + = *2^11*2^exp * 2^exp_en + : = frac_en * 2^exp_en + ==> exp_en = -11-exp_code; */ + *frac_en = (Word16)(ener_code >> 16); + *exp_en = -11 - exp_code; + + /* mean = 36 dB */ + L_temp2 = (Word32) 17062 << 7; + L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ + } + else if (mode == MR74) + { + /* mean = 30 dB */ + L_temp2 = (Word32) 32588 << 6; + L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ + } + else if (mode == MR67) + { + /* mean = 28.75 dB */ + L_temp2 = (Word32) 32268 << 6; + L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ + } + else /* MR59, MR515, MR475 */ + { + /* mean = 33 dB */ + L_temp2 = (Word32) 16678 << 7; + L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ + } + + /*-------------------------------------------------------------* + * Compute gcode0. * + * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener * + *--------------------------------------------------------------*/ + /* Q24 */ + if (L_tmp > (Word32) 0X001fffffL) + { + *pOverflow = 1; + L_tmp = MAX_32; + } + else if (L_tmp < -2097152) + { + *pOverflow = 1; + L_tmp = MIN_32; + } + else + { + L_tmp = L_tmp << 10; + } + + for (i = 0; i < 4; i++) + { + L_temp2 = ((((Word32) pred[i]) * st->past_qua_en[i]) << 1); + L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q13 * Q10 -> Q24 */ + } + + gcode0 = (Word16)(L_tmp >> 16); /* Q8 */ + + /*-----------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) * + * = pow(2, 3.3219*gcode0/20) * + * = pow(2, 0.166*gcode0) * + *-----------------------------------------------------------*/ + + /* 5439 Q15 = 0.165985 */ + /* (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15) */ + + if (mode == MR74) /* For IS641 bitexactness */ + { + L_tmp = (((Word32) gcode0) * 5439) << 1; /* Q8 * Q15 -> Q24 */ + } + else + { + L_tmp = (((Word32) gcode0) * 5443) << 1; /* Q8 * Q15 -> Q24 */ + } + + if (L_tmp < 0) + { + L_tmp = ~((~L_tmp) >> 8); + } + else + { + L_tmp = L_tmp >> 8; /* -> Q16 */ + } + + *exp_gcode0 = (Word16)(L_tmp >> 16); + if (L_tmp < 0) + { + L_temp1 = ~((~L_tmp) >> 1); + } + else + { + L_temp1 = L_tmp >> 1; + } + L_temp2 = (Word32) * exp_gcode0 << 15; + *frac_gcode0 = (Word16)(L_sub(L_temp1, L_temp2, pOverflow)); + /* -> Q0.Q15 */ + } + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gc_pred_update +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type gc_predState + qua_ener_MR122 = quantized energy for update (Q10); calculated as + (log2(qua_err)) (Word16) + qua_ener = quantized energy for update (Q10); calculated as + (20*log10(qua_err)) (Word16) + + Outputs: + structure pointed to by st contains the calculated quantized energy + for update + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function updates the MA predictor with the last quantized energy. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void gc_pred_update( + gc_predState *st, // i/o: State struct + Word16 qua_ener_MR122, // i : quantized energy for update, Q10 + // (log2(qua_err)) + Word16 qua_ener // i : quantized energy for update, Q10 + // (20*log10(qua_err)) +) +{ + Word16 i; + + for (i = 3; i > 0; i--) + { + st->past_qua_en[i] = st->past_qua_en[i - 1]; + st->past_qua_en_MR122[i] = st->past_qua_en_MR122[i - 1]; + } + + st->past_qua_en_MR122[0] = qua_ener_MR122; // log2 (qua_err), Q10 + + st->past_qua_en[0] = qua_ener; // 20*log10(qua_err), Q10 + +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void gc_pred_update( + gc_predState *st, /* i/o: State struct */ + Word16 qua_ener_MR122, /* i : quantized energy for update, Q10 */ + /* (log2(qua_err)) */ + Word16 qua_ener /* i : quantized energy for update, Q10 */ + /* (20*log10(qua_err)) */ +) +{ + st->past_qua_en[3] = st->past_qua_en[2]; + st->past_qua_en_MR122[3] = st->past_qua_en_MR122[2]; + + st->past_qua_en[2] = st->past_qua_en[1]; + st->past_qua_en_MR122[2] = st->past_qua_en_MR122[1]; + + st->past_qua_en[1] = st->past_qua_en[0]; + st->past_qua_en_MR122[1] = st->past_qua_en_MR122[0]; + + st->past_qua_en_MR122[0] = qua_ener_MR122; /* log2 (qua_err), Q10 */ + + st->past_qua_en[0] = qua_ener; /* 20*log10(qua_err), Q10 */ + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gc_pred_average_limited +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type gc_predState + ener_avg_MR122 = pointer to the averaged quantized energy (Q10); + calculated as (log2(qua_err)) (Word16) + ener_avg = pointer to the averaged quantized energy (Q10); calculated + as (20*log10(qua_err)) (Word16) + pOverflow = pointer to overflow (Flag) + + Outputs: + store pointed to by ener_avg_MR122 contains the new averaged quantized + energy + store pointed to by ener_avg contains the new averaged quantized + energy + pOverflow = 1 if the math functions called by gc_pred_average_limited + results in overflow else zero. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calculates the average of MA predictor state values (with a + lower limit) used in error concealment. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +The original etsi reference code uses a global flag Overflow. However, in the +actual implementation a pointer to a the overflow flag is passed in. + +void gc_pred_average_limited( + gc_predState *st, // i: State struct + Word16 *ener_avg_MR122, // o: everaged quantized energy, Q10 + // (log2(qua_err)) + Word16 *ener_avg // o: averaged quantized energy, Q10 + // (20*log10(qua_err)) +) +{ + Word16 av_pred_en; + Word16 i; + + // do average in MR122 mode (log2() domain) + av_pred_en = 0; + for (i = 0; i < NPRED; i++) + { + av_pred_en = add (av_pred_en, st->past_qua_en_MR122[i]); + } + + // av_pred_en = 0.25*av_pred_en + av_pred_en = mult (av_pred_en, 8192); + + // if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. + + if (sub (av_pred_en, MIN_ENERGY_MR122) < 0) + { + av_pred_en = MIN_ENERGY_MR122; + } + *ener_avg_MR122 = av_pred_en; + + // do average for other modes (20*log10() domain) + av_pred_en = 0; + for (i = 0; i < NPRED; i++) + { + av_pred_en = add (av_pred_en, st->past_qua_en[i]); + } + + // av_pred_en = 0.25*av_pred_en + av_pred_en = mult (av_pred_en, 8192); + + // if (av_pred_en < -14) av_pred_en = .. + + if (sub (av_pred_en, MIN_ENERGY) < 0) + { + av_pred_en = MIN_ENERGY; + } + *ener_avg = av_pred_en; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void gc_pred_average_limited( + gc_predState *st, /* i: State struct */ + Word16 *ener_avg_MR122, /* o: everaged quantized energy, Q10 */ + /* (log2(qua_err)) */ + Word16 *ener_avg, /* o: averaged quantized energy, Q10 */ + /* (20*log10(qua_err)) */ + Flag *pOverflow +) +{ + Word16 av_pred_en; + register Word16 i; + + /* do average in MR122 mode (log2() domain) */ + av_pred_en = 0; + for (i = 0; i < NPRED; i++) + { + av_pred_en = + add_16(av_pred_en, st->past_qua_en_MR122[i], pOverflow); + } + + /* av_pred_en = 0.25*av_pred_en (with sign-extension)*/ + if (av_pred_en < 0) + { + av_pred_en = (av_pred_en >> 2) | 0xc000; + } + else + { + av_pred_en >>= 2; + } + + /* if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. */ + if (av_pred_en < MIN_ENERGY_MR122) + { + av_pred_en = MIN_ENERGY_MR122; + } + *ener_avg_MR122 = av_pred_en; + + /* do average for other modes (20*log10() domain) */ + av_pred_en = 0; + for (i = 0; i < NPRED; i++) + { + av_pred_en = add_16(av_pred_en, st->past_qua_en[i], pOverflow); + } + + /* av_pred_en = 0.25*av_pred_en (with sign-extension)*/ + if (av_pred_en < 0) + { + av_pred_en = (av_pred_en >> 2) | 0xc000; + } + else + { + av_pred_en >>= 2; + } + + /* if (av_pred_en < -14) av_pred_en = .. */ + if (av_pred_en < MIN_ENERGY) + { + av_pred_en = MIN_ENERGY; + } + *ener_avg = av_pred_en; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/get_const_tbls.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/get_const_tbls.cpp new file mode 100644 index 00000000..87ecb864 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/get_const_tbls.cpp @@ -0,0 +1,102 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +#ifndef GET_CONST_TBLS_H +#include "get_const_tbls.h" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + extern const Word16 dgray[]; + extern const Word16 dico1_lsf_3[]; + extern const Word16 dico1_lsf_5[]; + extern const Word16 dico2_lsf_3[]; + extern const Word16 dico2_lsf_5[]; + extern const Word16 dico3_lsf_3[]; + extern const Word16 dico3_lsf_5[]; + extern const Word16 dico4_lsf_5[]; + extern const Word16 dico5_lsf_5[]; + extern const Word16 gray[]; + extern const Word16 lsp_init_data[]; + extern const Word16 mean_lsf_3[]; + extern const Word16 mean_lsf_5[]; + extern const Word16 mr515_3_lsf[]; + extern const Word16 mr795_1_lsf[]; + extern const Word16 past_rq_init[]; + extern const Word16 pred_fac_3[]; + extern const Word16 qua_gain_code[]; + extern const Word16 qua_gain_pitch[]; + extern const Word16 startPos[]; + extern const Word16 table_gain_lowrates[]; + extern const Word16 table_gain_highrates[]; + extern const Word16 prmno[]; + extern const Word16* const bitno[]; + extern const Word16 numOfBits[]; + extern const Word16* const reorderBits[]; + extern const Word16 numCompressedBytes[]; + extern const Word16 window_200_40[]; + extern const Word16 window_160_80[]; + extern const Word16 window_232_8[]; + extern const Word16 ph_imp_low_MR795[]; + extern const Word16 ph_imp_mid_MR795[]; + extern const Word16 ph_imp_low[]; + extern const Word16 ph_imp_mid[]; + +#ifdef __cplusplus +} +#endif + +OSCL_EXPORT_REF void get_const_tbls(CommonAmrTbls* tbl_struct_ptr) +{ + tbl_struct_ptr->dgray_ptr = dgray; + tbl_struct_ptr->dico1_lsf_3_ptr = dico1_lsf_3; + tbl_struct_ptr->dico1_lsf_5_ptr = dico1_lsf_5; + tbl_struct_ptr->dico2_lsf_3_ptr = dico2_lsf_3; + tbl_struct_ptr->dico2_lsf_5_ptr = dico2_lsf_5; + tbl_struct_ptr->dico3_lsf_3_ptr = dico3_lsf_3; + tbl_struct_ptr->dico3_lsf_5_ptr = dico3_lsf_5; + tbl_struct_ptr->dico4_lsf_5_ptr = dico4_lsf_5; + tbl_struct_ptr->dico5_lsf_5_ptr = dico5_lsf_5; + tbl_struct_ptr->gray_ptr = gray; + tbl_struct_ptr->lsp_init_data_ptr = lsp_init_data; + tbl_struct_ptr->mean_lsf_3_ptr = mean_lsf_3; + tbl_struct_ptr->mean_lsf_5_ptr = mean_lsf_5; + tbl_struct_ptr->mr515_3_lsf_ptr = mr515_3_lsf; + tbl_struct_ptr->mr795_1_lsf_ptr = mr795_1_lsf; + tbl_struct_ptr->past_rq_init_ptr = past_rq_init; + tbl_struct_ptr->pred_fac_3_ptr = pred_fac_3; + tbl_struct_ptr->qua_gain_code_ptr = qua_gain_code; + tbl_struct_ptr->qua_gain_pitch_ptr = qua_gain_pitch; + tbl_struct_ptr->startPos_ptr = startPos; + tbl_struct_ptr->table_gain_lowrates_ptr = table_gain_lowrates; + tbl_struct_ptr->table_gain_highrates_ptr = table_gain_highrates; + tbl_struct_ptr->prmno_ptr = prmno; + tbl_struct_ptr->bitno_ptr = bitno; + tbl_struct_ptr->numOfBits_ptr = numOfBits; + tbl_struct_ptr->reorderBits_ptr = reorderBits; + tbl_struct_ptr->numCompressedBytes_ptr = numCompressedBytes; + tbl_struct_ptr->window_200_40_ptr = window_200_40; + tbl_struct_ptr->window_160_80_ptr = window_160_80; + tbl_struct_ptr->window_232_8_ptr = window_232_8; + tbl_struct_ptr->ph_imp_low_MR795_ptr = ph_imp_low_MR795; + tbl_struct_ptr->ph_imp_mid_MR795_ptr = ph_imp_mid_MR795; + tbl_struct_ptr->ph_imp_low_ptr = ph_imp_low; + tbl_struct_ptr->ph_imp_mid_ptr = ph_imp_mid; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/gmed_n.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/gmed_n.cpp new file mode 100644 index 00000000..a723ce45 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/gmed_n.cpp @@ -0,0 +1,184 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: gmed_n.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "gmed_n.h" +#include "typedef.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define NMAX 9 /* largest N used in median calculation */ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gmed_n +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + ind = input values (Word16) + n = number of inputs to find the median (Word16) + + Returns: + median value. + + Outputs: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calculates N-point median of a data set. This routine is only + valid for a odd number of gains (n <= NMAX). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + gmed_n.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 gmed_n ( // o : The median value (0...N-1) + Word16 ind[], // i : Past gain values + Word16 n // i : The number of gains; this routine + // is only valid for a odd number of gains + // (n <= NMAX) +) +{ + Word16 i, j, ix = 0; + Word16 max; + Word16 medianIndex; + Word16 tmp[NMAX]; + Word16 tmp2[NMAX]; + + for (i = 0; i < n; i++) + { + tmp2[i] = ind[i]; + } + + for (i = 0; i < n; i++) + { + max = -32767; + for (j = 0; j < n; j++) + { + if (sub (tmp2[j], max) >= 0) + { + max = tmp2[j]; + ix = j; + } + } + tmp2[ix] = -32768; + tmp[i] = ix; + } + + medianIndex=tmp[ shr(n,1) ]; // account for complex addressing + return (ind[medianIndex]); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF Word16 gmed_n( /* o : the median value */ + Word16 ind[], /* i : input values */ + Word16 n /* i : number of inputs */ +) +{ + register Word16 i, j, ix = 0; + register Word16 max; + register Word16 medianIndex; + Word16 tmp[NMAX]; + Word16 tmp2[NMAX]; + + oscl_memmove(tmp2, ind, n*sizeof(*ind)); + + for (i = 0; i < n; i++) + { + max = -32767; + for (j = 0; j < n; j++) + { + if (*(tmp2 + j) >= max) + { + max = *(tmp2 + j); + ix = j; + } + } + *(tmp2 + ix) = -32768; + *(tmp + i) = ix; + } + + medianIndex = *(tmp + (n >> 1)); /* account for complex addressing */ + + return (*(ind + medianIndex)); +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/gray_tbl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/gray_tbl.cpp new file mode 100644 index 00000000..8b192f2c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/gray_tbl.cpp @@ -0,0 +1,135 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: gray_tbl.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the declaration for the gray encoding and decoding tables, + gray_tbl[] and dgray_tbl[] used by the c1035pf and d1035pf module + respectively. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + + extern const Word16 gray[]; + extern const Word16 dgray[]; + const Word16 gray[8] = {0, 1, 3, 2, 6, 4, 5, 7}; + const Word16 dgray[8] = {0, 1, 3, 2, 5, 6, 4, 7}; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] gray.tab, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/grid_tbl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/grid_tbl.cpp new file mode 100644 index 00000000..48bab680 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/grid_tbl.cpp @@ -0,0 +1,153 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: grid_tbl.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the declaration for grid_tbl[] used by the az_lsp() + function. + + // Table for az_lsp() + // + // grid[0] = 1.0; + // grid[grid_points+1] = -1.0; + // for (i = 1; i < grid_points; i++) + // grid[i] = cos((6.283185307*i)/(2.0*grid_points)); + // + // + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "az_lsp.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ +#define grid_points 60 + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + const Word16 grid[grid_points + 1] = + { + 32760, 32723, 32588, 32364, 32051, 31651, + 31164, 30591, 29935, 29196, 28377, 27481, + 26509, 25465, 24351, 23170, 21926, 20621, + 19260, 17846, 16384, 14876, 13327, 11743, + 10125, 8480, 6812, 5126, 3425, 1714, + 0, -1714, -3425, -5126, -6812, -8480, + -10125, -11743, -13327, -14876, -16384, -17846, + -19260, -20621, -21926, -23170, -24351, -25465, + -26509, -27481, -28377, -29196, -29935, -30591, + -31164, -31651, -32051, -32364, -32588, -32723, + -32760 + }; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] grid.tab, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/int_lpc.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/int_lpc.cpp new file mode 100644 index 00000000..dc08c11d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/int_lpc.cpp @@ -0,0 +1,515 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: int_lpc.cpp + Functions: + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "int_lpc.h" +#include "typedef.h" +#include "cnst.h" +#include "lsp_az.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Int_lpc_1and3 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsp_old -- array of type Word16 -- LSP vector at the + 4th subfr. of past frame (M) + lsp_mid -- array of type Word16 -- LSP vector at the 2nd subfr. of + present frame (M) + lsp_new -- array of type Word16 -- LSP vector at the 4th subfr. of + present frame (M) + + Outputs: + Az -- array of type Word16 -- interpolated LP parameters in all subfr. + (AZ_SIZE) + pOverflow -- pointer to type Flag -- Overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Interpolates the LSPs and converts to LPC parameters + to get a different LP filter in each subframe. + Description : The 20 ms speech frame is divided into 4 subframes. + The LSPs are quantized and transmitted at the 2nd and + 4th subframes (twice per frame) and interpolated at the + 1st and 3rd subframe. + + |------|------|------|------| + sf1 sf2 sf3 sf4 + F0 Fm F1 + + sf1: 1/2 Fm + 1/2 F0 sf3: 1/2 F1 + 1/2 Fm + sf2: Fm sf4: F1 + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + int_lpc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void Int_lpc_1and3( + Word16 lsp_old[], /* i : LSP vector at the 4th subfr. of past frame (M) */ + Word16 lsp_mid[], /* i : LSP vector at the 2nd subfr. of + present frame (M) */ + Word16 lsp_new[], /* i : LSP vector at the 4th subfr. of + present frame (M) */ + Word16 Az[], /* o : interpolated LP parameters in all subfr. + (AZ_SIZE) */ + Flag *pOverflow +) +{ + Word16 i; + Word16 lsp[M]; + Word16 *p_lsp_old = &lsp_old[0]; + Word16 *p_lsp_mid = &lsp_mid[0]; + Word16 *p_lsp_new = &lsp_new[0]; + Word16 *p_lsp = &lsp[0]; + + /* lsp[i] = lsp_mid[i] * 0.5 + lsp_old[i] * 0.5 */ + + for (i = M >> 1; i != 0; i--) + { + *(p_lsp++) = (*(p_lsp_old++) >> 1) + (*(p_lsp_mid++) >> 1); + *(p_lsp++) = (*(p_lsp_old++) >> 1) + (*(p_lsp_mid++) >> 1); + } + + Lsp_Az( + lsp, + Az, + pOverflow); /* Subframe 1 */ + + Az += MP1; + + Lsp_Az( + lsp_mid, + Az, + pOverflow); /* Subframe 2 */ + + Az += MP1; + + p_lsp_mid = &lsp_mid[0]; + p_lsp = &lsp[0]; + + for (i = M >> 1; i != 0; i--) + { + *(p_lsp++) = (*(p_lsp_mid++) >> 1) + (*(p_lsp_new++) >> 1); + *(p_lsp++) = (*(p_lsp_mid++) >> 1) + (*(p_lsp_new++) >> 1); + } + + Lsp_Az( + lsp, + Az, + pOverflow); /* Subframe 3 */ + + Az += MP1; + + Lsp_Az( + lsp_new, + Az, + pOverflow); /* Subframe 4 */ + + return; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Int_lpc_1and3_2 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsp_old -- array of type Word16 -- LSP vector at the + 4th subfr. of past frame (M) + lsp_mid -- array of type Word16 -- LSP vector at the 2nd subfr. of + present frame (M) + lsp_new -- array of type Word16 -- LSP vector at the 4th subfr. of + present frame (M) + + Outputs: + Az -- array of type Word16 -- interpolated LP parameters in. + subfr 1 and 2. + pOverflow -- pointer to type Flag -- Overflow indicator + + Returns: + None + + Global Variables Used: + + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Interpolation of the LPC parameters. Same as the Int_lpc + function but we do not recompute Az() for subframe 2 and + 4 because it is already available. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + int_lpc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void Int_lpc_1and3_2( + Word16 lsp_old[], /* i : LSP vector at the 4th subfr. of past frame (M) */ + Word16 lsp_mid[], /* i : LSP vector at the 2nd subframe of + present frame (M) */ + Word16 lsp_new[], /* i : LSP vector at the 4th subframe of + present frame (M) */ + Word16 Az[], /* o :interpolated LP parameters + in subframes 1 and 3 (AZ_SIZE) */ + Flag *pOverflow +) +{ + Word16 i; + Word16 lsp[M]; + Word16 *p_lsp_old = &lsp_old[0]; + Word16 *p_lsp_mid = &lsp_mid[0]; + Word16 *p_lsp_new = &lsp_new[0]; + Word16 *p_lsp = &lsp[0]; + + /* lsp[i] = lsp_mid[i] * 0.5 + lsp_old[i] * 0.5 */ + + for (i = M >> 1; i != 0; i--) + { + *(p_lsp++) = (*(p_lsp_old++) >> 1) + (*(p_lsp_mid++) >> 1); + *(p_lsp++) = (*(p_lsp_old++) >> 1) + (*(p_lsp_mid++) >> 1); + } + Lsp_Az(lsp, Az, pOverflow); /* Subframe 1 */ + Az += MP1 * 2; + + p_lsp_mid = &lsp_mid[0]; + p_lsp = &lsp[0]; + + for (i = M >> 1; i != 0; i--) + { + *(p_lsp++) = (*(p_lsp_mid++) >> 1) + (*(p_lsp_new++) >> 1); + *(p_lsp++) = (*(p_lsp_mid++) >> 1) + (*(p_lsp_new++) >> 1); + } + + Lsp_Az(lsp, Az, pOverflow); /* Subframe 3 */ + + return; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: lsp +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsp_old -- array of type Word16 -- LSP vector at the + 4th subfr. of past frame (M) + lsp_new -- array of type Word16 -- LSP vector at the 4th subfr. of + present frame (M) + + Outputs: + Az -- array of type Word16 -- interpolated LP parameters in. + all subframes. + pOverflow -- pointer to type Flag -- Overflow indicator + + Returns: + None + + Global Variables Used: + + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Interpolates the LSPs and convert to LP parameters to get + a different LP filter in each subframe. + + DESCRIPTION: + The 20 ms speech frame is divided into 4 subframes. + The LSPs are quantized and transmitted at the 4th subframe + (once per frame) and interpolated at the 1st, 2nd and 3rd subframe. + + |------|------|------|------| + sf1 sf2 sf3 sf4 + F0 F1 + + sf1: 3/4 F0 + 1/4 F1 sf3: 1/4 F0 + 3/4 F1 + sf2: 1/2 F0 + 1/2 F1 sf4: F1 + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + int_lpc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void Int_lpc_1to3( + Word16 lsp_old[], /* input : LSP vector at the 4th SF of past frame */ + Word16 lsp_new[], /* input : LSP vector at the 4th SF of present frame */ + Word16 Az[], /* output: interpolated LP parameters in all SFs */ + Flag *pOverflow +) +{ + Word16 i; + Word16 temp; + + Word16 lsp[M]; + + for (i = 0; i < M; i++) + { + temp = lsp_old[i] - (lsp_old[i] >> 2); + lsp[i] = temp + (lsp_new[i] >> 2); + } + + Lsp_Az( + lsp, + Az, + pOverflow); /* Subframe 1 */ + + Az += MP1; + + + for (i = 0; i < M; i++) + { + lsp[i] = (lsp_new[i] >> 1) + (lsp_old[i] >> 1); + + } + + Lsp_Az(lsp, Az, pOverflow); /* Subframe 2 */ + + Az += MP1; + + for (i = 0; i < M; i++) + { + + temp = lsp_new[i] - (lsp_new[i] >> 2); + lsp[i] = temp + (lsp_old[i] >> 2); + + } + + Lsp_Az(lsp, Az, pOverflow); /* Subframe 3 */ + + Az += MP1; + + Lsp_Az(lsp_new, Az, pOverflow); /* Subframe 4 */ + + return; +} +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Int_lpc_1to3_2 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsp_old -- array of type Word16 -- LSP vector at the + 4th subfr. of past frame (M) + lsp_new -- array of type Word16 -- LSP vector at the 4th subfr. of + present frame (M) + + Outputs: + Az -- array of type Word16 -- interpolated LP parameters in. + subfr 1, 2, and 3. + pOverflow -- pointer to type Flag -- Overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Interpolation of the LPC parameters. + Same as the previous function but we do not recompute Az() for + subframe 4 because it is already available. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + int_lpc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void Int_lpc_1to3_2( + Word16 lsp_old[], /* input : LSP vector at the 4th SF of past frame */ + Word16 lsp_new[], /* input : LSP vector at the 4th SF of present frame */ + Word16 Az[], /* output: interpolated LP parameters in SFs 1,2,3 */ + Flag *pOverflow +) +{ + Word16 i; + Word16 temp; + Word16 lsp[M]; + + for (i = 0; i < M; i++) + { + temp = lsp_old[i] - (lsp_old[i] >> 2); + lsp[i] = temp + (lsp_new[i] >> 2); + + } + + Lsp_Az(lsp, Az, pOverflow); /* Subframe 1 */ + + Az += MP1; + + for (i = 0; i < M; i++) + { + lsp[i] = (lsp_new[i] >> 1) + (lsp_old[i] >> 1); + + } + + Lsp_Az(lsp, Az, pOverflow); /* Subframe 2 */ + + Az += MP1; + + for (i = 0; i < M; i++) + { + temp = lsp_new[i] - (lsp_new[i] >> 2); + lsp[i] = temp + (lsp_old[i] >> 2); + + } + + Lsp_Az(lsp, Az, pOverflow); /* Subframe 3 */ + + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/inv_sqrt.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/inv_sqrt.cpp new file mode 100644 index 00000000..0125dd4b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/inv_sqrt.cpp @@ -0,0 +1,220 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: inv_sqrt.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "inv_sqrt.h" +#include "typedef.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Inv_sqrt +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_x = input value (Word32) + pOverflow = pointer to overflow flag + + Outputs: + pOverflow -> if the Inv_sqrt operation resulted in an overflow. + + Returns: + L_y = inverse squareroot of L_x (Word32) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes 1/sqrt(L_x), where L_x is positive. + If L_x is negative or zero, the result is 1 (3fff ffff). + + The function 1/sqrt(L_x) is approximated by a table and linear + interpolation. The inverse square root is computed using the + following steps: + 1- Normalization of L_x. + 2- If (30-exponent) is even then shift right once. + 3- exponent = (30-exponent)/2 +1 + 4- i = bit25-b31 of L_x; 16<=i<=63 because of normalization. + 5- a = bit10-b24 + 6- i -=16 + 7- L_y = table[i]<<16 - (table[i] - table[i+1]) * a * 2 + 8- L_y >>= exponent + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + inv_sqrt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word32 Inv_sqrt ( // (o) : output value + Word32 L_x // (i) : input value +) +{ + Word16 exp, i, a, tmp; + Word32 L_y; + +* The reference ETSI code uses a global Overflow flag. In the actual +* implementation a pointer to the overflow flag is passed into the function. +* This pointer is in turn passed into the basic math functions such as add(), +* L_shl(), L_shr(), sub() called by this module. + + if (L_x <= (Word32) 0) + return ((Word32) 0x3fffffffL); + + exp = norm_l (L_x); + L_x = L_shl (L_x, exp); // L_x is normalize + + exp = sub (30, exp); + + if ((exp & 1) == 0) // If exponent even -> shift right + { + L_x = L_shr (L_x, 1); + } + exp = shr (exp, 1); + exp = add (exp, 1); + + L_x = L_shr (L_x, 9); + i = extract_h (L_x); // Extract b25-b31 + L_x = L_shr (L_x, 1); + a = extract_l (L_x); // Extract b10-b24 + a = a & (Word16) 0x7fff; + + i = sub (i, 16); + + L_y = L_deposit_h (table[i]); // table[i] << 16 + tmp = sub (table[i], table[i + 1]); // table[i] - table[i+1]) + L_y = L_msu (L_y, tmp, a); // L_y -= tmp*a*2 + + L_y = L_shr (L_y, exp); // denormalization + + return (L_y); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF Word32 Inv_sqrt( /* (o) : output value */ + Word32 L_x, /* (i) : input value */ + Flag * pOverflow /* (i) : pointer to overflow flag */ +) +{ + Word16 exp; + Word16 i; + Word16 a; + Word16 tmp; + Word32 L_y; + OSCL_UNUSED_ARG(pOverflow); + + if (L_x <= (Word32) 0) + { + return ((Word32) 0x3fffffffL); + } + + exp = norm_l(L_x); + L_x <<= exp; /* L_x is normalize */ + + exp = 30 - exp; + + if ((exp & 1) == 0) /* If exponent even -> shift right */ + { + L_x >>= 1; + } + exp >>= 1; + exp += 1; + + L_x >>= 9; + i = (Word16)(L_x >> 16); /* Extract b25-b31 */ + a = (Word16)(L_x >> 1); /* Extract b10-b24 */ + a &= (Word16) 0x7fff; + + i -= 16; + + L_y = (Word32)inv_sqrt_tbl[i] << 16; /* inv_sqrt_tbl[i] << 16 */ + + /* inv_sqrt_tbl[i] - inv_sqrt_tbl[i+1]) */ + tmp = inv_sqrt_tbl[i] - inv_sqrt_tbl[i + 1]; + /* always a positive number less than 200 */ + + L_y -= ((Word32)tmp * a) << 1; /* L_y -= tmp*a*2 */ + /* always a positive minus a small negative number */ + + L_y >>= exp; /* denormalization, exp always 0< exp < 31 */ + + return (L_y); +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/inv_sqrt_tbl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/inv_sqrt_tbl.cpp new file mode 100644 index 00000000..3ae066a1 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/inv_sqrt_tbl.cpp @@ -0,0 +1,138 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: inv_sqrt_tbl.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the declaration for table[] used by the inv_sqrt function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "inv_sqrt.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + const Word16 inv_sqrt_tbl[49] = + { + + 32767, 31790, 30894, 30070, 29309, 28602, 27945, 27330, 26755, 26214, + 25705, 25225, 24770, 24339, 23930, 23541, 23170, 22817, 22479, 22155, + 21845, 21548, 21263, 20988, 20724, 20470, 20225, 19988, 19760, 19539, + 19326, 19119, 18919, 18725, 18536, 18354, 18176, 18004, 17837, 17674, + 17515, 17361, 17211, 17064, 16921, 16782, 16646, 16514, 16384 + }; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] inv_sqrt.tab file, UMTS GSM AMR speech codec, R99 - Version 3.2.0, + March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/l_abs.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/l_abs.cpp new file mode 100644 index 00000000..e436006d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/l_abs.cpp @@ -0,0 +1,160 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: l_abs.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32 ) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + L_var1 = absolute value of input (Word32) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calculates the absolute value of L_var1; saturate in case + where the input is -214783648. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word32 L_abs (Word32 L_var1) +{ + Word32 L_var_out; + + if (L_var1 == MIN_32) + { + L_var_out = MAX_32; + } + else + { + if (L_var1 < 0) + { + L_var_out = -L_var1; + } + else + { + L_var_out = L_var1; + } + } + +#if (WMOPS) + multiCounter[currCounter].L_abs++; +#endif + return (L_var_out); +} + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word32 L_abs(register Word32 L_var1) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + + Word32 y = L_var1 - (L_var1 < 0); + y = y ^(y >> 31); + return (y); + +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/l_deposit_h.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/l_deposit_h.cpp new file mode 100644 index 00000000..2a8ad2fe --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/l_deposit_h.cpp @@ -0,0 +1,144 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: l_deposit_h.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + var1 = deposit of var1 into MSWord of 32 bit value (Word32) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function deposits the 16 bit var1 into the 16 MS bits of the 32 bit + output. The 16 LS bits of the output are zeroed. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word32 L_deposit_h (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 << 16; +#if (WMOPS) + multiCounter[currCounter].L_deposit_h++; +#endif + return (L_var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word32 L_deposit_h(Word16 var1) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; Return nothing or data or data pointer + ----------------------------------------------------------------------------*/ + return ((Word32) var1 << 16); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/l_deposit_l.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/l_deposit_l.cpp new file mode 100644 index 00000000..1f5f1fb9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/l_deposit_l.cpp @@ -0,0 +1,144 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: l_deposit_l.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + var1 = deposit of var1 into LSWord of 32 bit value (Word32) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function deposits the 16 bit var1 into the 16 LS bits of the 32 bit + output. The 16 MS bits of the output are sign extended. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word32 L_deposit_l (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1; +#if (WMOPS) + multiCounter[currCounter].L_deposit_l++; +#endif + return (L_var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word32 L_deposit_l(Word16 var1) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; Return nothing or data or data pointer + ----------------------------------------------------------------------------*/ + return ((Word32) var1); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/l_shr_r.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/l_shr_r.cpp new file mode 100644 index 00000000..0a071356 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/l_shr_r.cpp @@ -0,0 +1,183 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: l_shr_r.cpp + +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: L_shr_r +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32 ) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit shift operation resulted in overflow + + Returns: + result = Shifted result w/ rounding (Word32) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function arithmetically shifts the 32 bit input L_var1 right var2 + positions with rounding. If var2 is negative, the function + arithmetically shifts L_var1 left by -var2 and zero fills the -var2 LSB of + the result. The result is saturated in case of underflows or overflows, i.e., + + - If var2 is greater than zero : + if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1)))) + is equal to zero + then + L_shr_r(L_var1,var2) = L_shr(L_var1,var2) + else + L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1) + - If var2 is less than or equal to zero : + L_shr_r(L_var1,var2) = L_shr(L_var1,var2). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] L_shr_r() function in basic_op2.c, UMTS GSM AMR speech codec, R99 - + Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word32 L_shr_r (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + +* The reference ETSI code uses a global flag for Overflow. In the actual +* implementation a pointer to Overflow flag is passed in as a parameter to the +* function L_shr() + + if (var2 > 31) + { + L_var_out = 0; + } + else + { + L_var_out = L_shr (L_var1, var2); +#if (WMOPS) + multiCounter[currCounter].L_shr--; +#endif + if (var2 > 0) + { + if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0) + { + L_var_out++; + } + } + } +#if (WMOPS) + multiCounter[currCounter].L_shr_r++; +#endif + return (L_var_out); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +OSCL_EXPORT_REF Word32 L_shr_r(register Word32 L_var1, register Word16 var2, Flag *pOverflow) +{ + Word32 result; + + if (var2 > 31) + { + result = 0; + } + else + { + result = L_shr(L_var1, var2, pOverflow); + + if (var2 > 0) + { + if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0) + { + result++; + } + } + } + return (result); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/log2.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/log2.cpp new file mode 100644 index 00000000..d08543f8 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/log2.cpp @@ -0,0 +1,142 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: log2.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "log2.h" +#include "basic_op.h" +#include "log2_norm.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: log2() +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_x = input value of type Word32 + pExponent = pointer to the integer part of Log2 of type Word16 whose + valid range is: 0 <= value <= 30 + pFraction = pointer to the fractional part of Log2 of type Word16 + whose valid range is: 0 <= value < 1 + pOverflow = pointer to overflow flag + + + Outputs: + pExponent -> integer part of the newly calculated Log2 + pFraction -> fractional part of the newly calculated Log2 + pOverflow -> 1 if the log2() operation resulted in saturation + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes logarithm (base2) of the input L_x, where L_x is + positive. If L_x is negative or zero, the result is 0. + + This function first normalizes the input L_x and calls the function Log2_norm + to calculate the logarithm. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] log2.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +OSCL_EXPORT_REF void Log2( + Word32 L_x, /* (i) : input value */ + Word16 *pExponent, /* (o) : Integer part of Log2. (range: 0<=val<=30)*/ + Word16 *pFraction, /* (o) : Fractional part of Log2. (range: 0<=val<1) */ + Flag *pOverflow /* (i/o) : overflow flag */ +) +{ + Word16 exp; + Word32 result; + OSCL_UNUSED_ARG(pOverflow); + + exp = norm_l(L_x); + result = L_x << exp; + Log2_norm(result, exp, pExponent, pFraction); + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/log2_norm.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/log2_norm.cpp new file mode 100644 index 00000000..174d57f2 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/log2_norm.cpp @@ -0,0 +1,202 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: log2_norm.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "log2_norm.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Log2_norm +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_x = normalized input value of type Word32 + exp = number of shifts required to normalize L_x; it is of type Word16 + exponent = pointer to the integer part of Log2 (of type Word16) + whose valid range is: 0 <= value <= 30 + fraction = pointer to the fractional part of Log2 (of type Word16) + whose valid range is: 0 <= value < 1 + + Outputs: + exponent points to the newly calculated integer part of Log2 + fraction points to the newly calculated fractional part of Log2 + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + table = Log2 table of constants of type Word16 + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + The function Log2(L_x) calculates the logarithm of the normalized input + buffer L_x. The logarithm is approximated by a table and linear + interpolation. The following steps are used to compute Log2(L_x): + + 1. exponent = 30 - norm_exponent + 2. i = bit25-b31 of L_x; 32<=i<=63 (because of normalization). + 3. a = bit10-b24 + 4. i = i - 32 + 5. fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2 + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + log2.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Log2_norm ( + Word32 L_x, // (i) : input value (normalized) + Word16 exp, // (i) : norm_l (L_x) + Word16 *exponent, // (o) : Integer part of Log2. (range: 0<=val<=30) + Word16 *fraction // (o) : Fractional part of Log2. (range: 0<=val<1) +) +{ + Word16 i, a, tmp; + Word32 L_y; + + if (L_x <= (Word32) 0) + { + *exponent = 0; + *fraction = 0; + return; + } + + *exponent = sub (30, exp); + + L_x = L_shr (L_x, 9); + i = extract_h (L_x); // Extract b25-b31 + L_x = L_shr (L_x, 1); + a = extract_l (L_x); // Extract b10-b24 of fraction + a = a & (Word16) 0x7fff; + + i = sub (i, 32); + + L_y = L_deposit_h (table[i]); // table[i] << 16 + tmp = sub (table[i], table[i + 1]); // table[i] - table[i+1] + L_y = L_msu (L_y, tmp, a); // L_y -= tmp*a*2 + + *fraction = extract_h (L_y); + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void Log2_norm( + Word32 L_x, /* (i) : input value (normalized) */ + Word16 exp, /* (i) : norm_l (L_x) */ + Word16 *exponent, /* (o) : Integer part of Log2. (range: 0<=val<=30)*/ + Word16 *fraction /* (o) : Fractional part of Log2. (range: 0<=val<1) */ +) +{ + Word16 i, a, tmp; + Word32 L_y; + + if (L_x <= (Word32) 0) + { + *exponent = 0; + *fraction = 0; + } + else + { + /* Calculate exponent portion of Log2 */ + *exponent = 30 - exp; + + /* At this point, L_x > 0 */ + /* Shift L_x to the right by 10 to extract bits 10-31, */ + /* which is needed to calculate fractional part of Log2 */ + L_x >>= 10; + i = (Word16)(L_x >> 15); /* Extract b25-b31 */ + a = L_x & 0x7fff; /* Extract b10-b24 of fraction */ + + /* Calculate table index -> subtract by 32 is done for */ + /* proper table indexing, since 32<=i<=63 (due to normalization) */ + i -= 32; + + /* Fraction part of Log2 is approximated by using table[] */ + /* and linear interpolation, i.e., */ + /* fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2 */ + L_y = (Word32) log2_tbl[i] << 16; /* table[i] << 16 */ + tmp = log2_tbl[i] - log2_tbl[i + 1]; /* table[i] - table[i+1] */ + L_y -= (((Word32) tmp) * a) << 1; /* L_y -= tmp*a*2 */ + + *fraction = (Word16)(L_y >> 16); + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/log2_tbl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/log2_tbl.cpp new file mode 100644 index 00000000..76f66b06 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/log2_tbl.cpp @@ -0,0 +1,137 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: log2_tbl.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the declaration for log2_tbl[] used by the log2() and + log2_norm() function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "log2_norm.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + + const Word16 log2_tbl[33] = + { + 0, 1455, 2866, 4236, 5568, 6863, 8124, 9352, 10549, 11716, + 12855, 13967, 15054, 16117, 17156, 18172, 19167, 20142, 21097, 22033, + 22951, 23852, 24735, 25603, 26455, 27291, 28113, 28922, 29716, 30497, + 31266, 32023, 32767 + }; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] log2.tab, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsfwt.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsfwt.cpp new file mode 100644 index 00000000..310ba3ca --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsfwt.cpp @@ -0,0 +1,202 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: lsfwt.cpp + Functions: Lsf_wt + + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsf -- Pointer to Word16 -- LSF vector + + Outputs: + wf -- Pointer to Word16 -- square of weighting factors + pOverflow -- Pointer to type Flag -- Flag set when overflow occurs + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + +Compute LSF weighting factors + + d[i] = lsf[i+1] - lsf[i-1] + + The weighting factors are approximated by two line segment + + First segment passes by the following 2 points: + + d[i] = 0Hz wf[i] = 3.347 + d[i] = 450Hz wf[i] = 1.8 + + Second segment passes by the following 2 points: + + d[i] = 450Hz wf[i] = 1.8 + d[i] = 1500Hz wf[i] = 1.0 + + if( d[i] < 450Hz ) + wf[i] = 3.347 - ( (3.347-1.8) / (450-0)) * d[i] + else + wf[i] = 1.8 - ( (1.8-1.0) / (1500-450)) * (d[i] - 450) + + + if( d[i] < 1843) + wf[i] = 3427 - (28160*d[i])>>15 + else + wf[i] = 1843 - (6242*(d[i]-1843))>>15 + +------------------------------------------------------------------------------ + REQUIREMENTS + + + +------------------------------------------------------------------------------ + REFERENCES + + lsfwt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "lsfwt.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void Lsf_wt( + Word16 *lsf, /* input : LSF vector */ + Word16 *wf, /* output: square of weighting factors */ + Flag *pOverflow +) +{ + Word16 temp; + Word16 wgt_fct; + Word16 i; + Word16 *p_wf = wf; + Word16 *p_lsf = &lsf[0]; + Word16 *p_lsf_2 = &lsf[1]; + + OSCL_UNUSED_ARG(pOverflow); + + /* wf[0] = lsf[1] - 0 */ + *(p_wf++) = *(p_lsf_2++); + + for (i = 4; i != 0 ; i--) + { + *(p_wf++) = *(p_lsf_2++) - *(p_lsf++); + *(p_wf++) = *(p_lsf_2++) - *(p_lsf++); + } + /* + * wf[9] = 4000 - lsf[8] + */ + *(p_wf) = 16384 - *(p_lsf); + + p_wf = wf; + + for (i = 10; i != 0; i--) + { + /* + * (wf[i] - 450); + * 1843 == 450 Hz (Q15 considering 7FFF = 8000 Hz) + */ + wgt_fct = *p_wf; + temp = wgt_fct - 1843; + + if (temp > 0) + { + temp = (Word16)(((Word32)temp * 6242) >> 15); + wgt_fct = 1843 - temp; + } + else + { + temp = (Word16)(((Word32)wgt_fct * 28160) >> 15); + wgt_fct = 3427 - temp; + } + + *(p_wf++) = wgt_fct << 3; + + } /* for (i = 10; i != 0; i--) */ + + return; + +} /* Lsf_wt() */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp.cpp new file mode 100644 index 00000000..d5c1d27d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp.cpp @@ -0,0 +1,440 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: lsp.cpp + Functions: + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "lsp.h" +#include "typedef.h" +#include "q_plsf.h" +#include "az_lsp.h" +#include "int_lpc.h" +#include "lsp_tab.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: lsp_init (lspState **st) +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = Pointer to type lspState + + Outputs: + st = Pointer to type lspState -- values are initialized. + + Returns: + None + + Global Variables Used: + lsp_init_data = Word16 array. + + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Initializes lsp state data. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + lsp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF Word16 lsp_init(lspState **st) +{ + lspState* s; + + if (st == (lspState **) NULL) + { + /* fprintf(stderr, "lsp_init: invalid parameter\n"); */ + return -1; + } + + *st = NULL; + + /* allocate memory */ + if ((s = (lspState *) oscl_malloc(sizeof(lspState))) == NULL) + { + /* fprintf(stderr, "lsp_init: can not malloc state structure\n"); */ + return -1; + } + + /* Initialize quantization state */ + if (0 != Q_plsf_init(&s->qSt)) + { + return -1; + } + + if (0 != lsp_reset(s)) + { + return -1; + } + + *st = s; + + return 0; +} + + + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: lsp_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = Pointer to type lspState + + Outputs: + st = Pointer to type lspState -- values are reset. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + resets lsp_state data +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + lsp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +OSCL_EXPORT_REF Word16 lsp_reset(lspState *st) +{ + + if (st == (lspState *) NULL) + { + /* fprintf(stderr, "lsp_reset: invalid parameter\n"); */ + return -1; + } + + /* Init lsp_old[] */ + oscl_memcpy(st->lsp_old, lsp_init_data, M*sizeof(Word16)); + + /* Initialize lsp_old_q[] */ + oscl_memcpy(st->lsp_old_q, st->lsp_old, M*sizeof(Word16)); + + /* Reset quantization state */ + Q_plsf_reset(st->qSt); + + return 0; +} + + + + + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: lsp_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = Pointer to type lspState + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Frees memory used by lspState. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + lsp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +OSCL_EXPORT_REF void lsp_exit(lspState **st) +{ + if (st == NULL || *st == NULL) + return; + + /* Deallocate members */ + Q_plsf_exit(&(*st)->qSt); + + /* deallocate memory */ + oscl_free(*st); + *st = NULL; + + return; +} + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: lsp +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + + + Inputs: + st = Pointer to type lspState -- State struct + req_mode = enum Mode -- requested coder mode + used_mode = enum Mode -- used coder mode + az = array of type Word16 -- interpolated LP parameters Q12 + + Outputs: + azQ = array of type Word16 -- quantization interpol. LP parameters Q12 + lsp_new = array of type Word16 -- new lsp vector + anap = Double pointer of type Word16 -- analysis parameters + pOverflow = Pointer to type Flag -- Flag set when overflow occurs + st = Pointer to type lspState -- State struct + az = array of type Word16 -- interpolated LP parameters Q12 + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + lsp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +OSCL_EXPORT_REF void lsp(lspState *st, /* i/o : State struct */ + enum Mode req_mode, /* i : requested coder mode */ + enum Mode used_mode,/* i : used coder mode */ + Word16 az[], /* i/o : interpolated LP parameters Q12 */ + Word16 azQ[], /* o : quantization interpol. LP parameters Q12*/ + Word16 lsp_new[], /* o : new lsp vector */ + Word16 **anap, /* o : analysis parameters */ + Flag *pOverflow) /* o : Flag set when overflow occurs */ + +{ + Word16 lsp_new_q[M]; /* LSPs at 4th subframe */ + Word16 lsp_mid[M], lsp_mid_q[M]; /* LSPs at 2nd subframe */ + + Word16 pred_init_i; /* init index for MA prediction in DTX mode */ + + if (req_mode == MR122) + { + Az_lsp(&az[MP1], lsp_mid, st->lsp_old, pOverflow); + Az_lsp(&az[MP1 * 3], lsp_new, lsp_mid, pOverflow); + + /*--------------------------------------------------------------------* + * Find interpolated LPC parameters in all subframes (both quantized * + * and unquantized). * + * The interpolated parameters are in array A_t[] of size (M+1)*4 * + * and the quantized interpolated parameters are in array Aq_t[] * + *--------------------------------------------------------------------*/ + Int_lpc_1and3_2(st->lsp_old, lsp_mid, lsp_new, az, pOverflow); + + if (used_mode != MRDTX) + { + /* LSP quantization (lsp_mid[] and lsp_new[] jointly quantized) */ + Q_plsf_5( + st->qSt, + lsp_mid, + lsp_new, + lsp_mid_q, + lsp_new_q, + *anap, + pOverflow); + + Int_lpc_1and3(st->lsp_old_q, lsp_mid_q, lsp_new_q, azQ, pOverflow); + + /* Advance analysis parameters pointer */ + (*anap) += 5; + } + } + else + { + Az_lsp(&az[MP1 * 3], lsp_new, st->lsp_old, pOverflow); /* From A(z) to lsp */ + + /*--------------------------------------------------------------------* + * Find interpolated LPC parameters in all subframes (both quantized * + * and unquantized). * + * The interpolated parameters are in array A_t[] of size (M+1)*4 * + * and the quantized interpolated parameters are in array Aq_t[] * + *--------------------------------------------------------------------*/ + + Int_lpc_1to3_2(st->lsp_old, lsp_new, az, pOverflow); + + if (used_mode != MRDTX) + { + /* LSP quantization */ + Q_plsf_3( + st->qSt, + req_mode, + lsp_new, + lsp_new_q, + *anap, + &pred_init_i, + pOverflow); + + Int_lpc_1to3( + st->lsp_old_q, + lsp_new_q, + azQ, + pOverflow); + + /* Advance analysis parameters pointer */ + (*anap) += 3; + } + } + + /* update the LSPs for the next frame */ + oscl_memcpy(st->lsp_old, lsp_new, M*sizeof(Word16)); + + if (used_mode != MRDTX) + { + oscl_memcpy(st->lsp_old_q, lsp_new_q, M*sizeof(Word16)); + } +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp_az.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp_az.cpp new file mode 100644 index 00000000..c41f6141 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp_az.cpp @@ -0,0 +1,376 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: lsp_az.cpp + Functions: Get_lsp_pol + Lsp_Az + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains functions that convert line spectral pairs (LSP) to + linear predictive (LP) coefficients (filter order = 10). The functions + included in this file include Get_lsp_pol, which finds the coefficients of + F1(z) and F2(z), and Lsp_Az, which converts LSP to LPC by multiplying + F1(z) by 1+z^(-1) and F2(z) by 1-z^(-1), then calculating A(z) = (F1(z) + + F2(z))/2. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "lsp_az.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Get_lsp_pol +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsp = pointer to the buffer containing the line spectral pairs (LSP) + of type Word16 + f = pointer to the polynomial of type Word32 to be generated + + pOverflow = pointer set in case where one of the operations overflows. + [data type Pointer to Flag] + + Outputs: + buffer pointed to by f contains the polynomial generated + + pOverflow = pointer set in case where one of the operations overflows. + [data type Pointer to Flag] + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function finds the polynomial F1(z) or F2(z) from the LSPs. If the LSP + vector is passed at address 0, F1(z) is computed and if it is passed at + address 1, F2(z) is computed. + + This is performed by expanding the product polynomials: + + F1(z) = product ( 1 - 2 lsp[i] z^-1 + z^-2 ) + i=0,2,4,6,8 + F2(z) = product ( 1 - 2 lsp[i] z^-1 + z^-2 ) + i=1,3,5,7,9 + + where lsp[] is the LSP vector in the cosine domain. + + The expansion is performed using the following recursion: + + f[0] = 1 + b = -2.0 * lsp[0] + f[1] = b + for i=2 to 5 do + b = -2.0 * lsp[2*i-2]; + for j=i-1 down to 2 do + f[j] = f[j] + b*f[j-1] + f[j-2]; + f[1] = f[1] + b; + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + lsp_az.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static void Get_lsp_pol (Word16 *lsp, Word32 *f) +{ + Word16 i, j, hi, lo; + Word32 t0; + + // f[0] = 1.0; + *f = L_mult (4096, 2048); + f++; + *f = L_msu ((Word32) 0, *lsp, 512); // f[1] = -2.0 * lsp[0]; + f++; + lsp += 2; // Advance lsp pointer + + for (i = 2; i <= 5; i++) + { + *f = f[-2]; + + for (j = 1; j < i; j++, f--) + { + L_Extract (f[-1], &hi, &lo); + t0 = Mpy_32_16 (hi, lo, *lsp); // t0 = f[-1] * lsp + t0 = L_shl (t0, 1); + *f = L_add (*f, f[-2]); // *f += f[-2] + *f = L_sub (*f, t0); // *f -= t0 + } + *f = L_msu (*f, *lsp, 512); // *f -= lsp<<9 + f += i; // Advance f pointer + lsp += 2; // Advance lsp pointer + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void Get_lsp_pol( + Word16 *lsp, + Word32 *f, + Flag *pOverflow) +{ + register Word16 i; + register Word16 j; + + Word16 hi; + Word16 lo; + Word32 t0; + OSCL_UNUSED_ARG(pOverflow); + + /* f[0] = 1.0; */ + *f++ = (Word32) 0x01000000; + *f++ = (Word32) - *(lsp++) << 10; /* f[1] = -2.0 * lsp[0]; */ + lsp++; /* Advance lsp pointer */ + + for (i = 2; i <= 5; i++) + { + *f = *(f - 2); + + for (j = 1; j < i; j++) + { + hi = (Word16)(*(f - 1) >> 16); + + lo = (Word16)((*(f - 1) >> 1) - ((Word32) hi << 15)); + + t0 = ((Word32)hi * *lsp); + t0 += ((Word32)lo * *lsp) >> 15; + + *(f) += *(f - 2); /* *f += f[-2] */ + *(f--) -= t0 << 2; /* *f -= t0 */ + + } + + *f -= (Word32)(*lsp++) << 10; + + f += i; + lsp++; + } + + return; +} + +/****************************************************************************/ + + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Lsp_Az +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsp = pointer to the buffer containing the line spectral pairs (LSP) + of type Word16 + + a = pointer to the buffer containing Linear Predictive (LP) + coefficients of type Word16 to be generated + + pOverflow = pointer set in case where one of the operations overflows. + [data type Pointer to Flag] + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + pOverflow = pointer set in case where one of the operations overflows. + [data type Pointer to Flag] + + Pointers and Buffers Modified: + a buffer contains the generated Linear Predictive (LP) coefficients + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function converts from the line spectral pairs (LSP) to LP coefficients + for a 10th order filter. + + This is done by: + (1) Find the coefficients of F1(z) and F2(z) (see Get_lsp_pol) + (2) Multiply F1(z) by 1+z^{-1} and F2(z) by 1-z^{-1} + (3) A(z) = ( F1(z) + F2(z) ) / 2 + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + lsp_az.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Lsp_Az ( + Word16 lsp[], // (i) : line spectral frequencies + Word16 a[] // (o) : predictor coefficients (order = 10) +) +{ + Word16 i, j; + Word32 f1[6], f2[6]; + Word32 t0; + + Get_lsp_pol (&lsp[0], f1); + Get_lsp_pol (&lsp[1], f2); + + for (i = 5; i > 0; i--) + { + f1[i] = L_add (f1[i], f1[i - 1]); // f1[i] += f1[i-1]; + f2[i] = L_sub (f2[i], f2[i - 1]); // f2[i] -= f2[i-1]; + } + + a[0] = 4096; + for (i = 1, j = 10; i <= 5; i++, j--) + { + t0 = L_add (f1[i], f2[i]); // f1[i] + f2[i] + a[i] = extract_l (L_shr_r (t0, 13)); + t0 = L_sub (f1[i], f2[i]); // f1[i] - f2[i] + a[j] = extract_l (L_shr_r (t0, 13)); + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void Lsp_Az( + Word16 lsp[], /* (i) : line spectral frequencies */ + Word16 a[], /* (o) : predictor coefficients (order = 10) */ + Flag *pOverflow /* (o) : overflow flag */ +) +{ + register Word16 i; + register Word16 j; + + Word32 f1[6]; + Word32 f2[6]; + Word32 t0; + Word32 t1; + Word16 *p_a = &a[0]; + Word32 *p_f1; + Word32 *p_f2; + + Get_lsp_pol(&lsp[0], f1, pOverflow); + + Get_lsp_pol(&lsp[1], f2, pOverflow); + + p_f1 = &f1[5]; + p_f2 = &f2[5]; + + for (i = 5; i > 0; i--) + { + *(p_f1--) += f1[i-1]; + *(p_f2--) -= f2[i-1]; + } + + *(p_a++) = 4096; + p_f1 = &f1[1]; + p_f2 = &f2[1]; + + for (i = 1, j = 10; i <= 5; i++, j--) + { + t0 = *(p_f1) + *(p_f2); /* f1[i] + f2[i] */ + t1 = *(p_f1++) - *(p_f2++); /* f1[i] - f2[i] */ + + t0 = t0 + ((Word32) 1 << 12); + t1 = t1 + ((Word32) 1 << 12); + + *(p_a++) = (Word16)(t0 >> 13); + a[j] = (Word16)(t1 >> 13); + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp_lsf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp_lsf.cpp new file mode 100644 index 00000000..f315f5f4 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp_lsf.cpp @@ -0,0 +1,318 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: lsp_lsf.cpp + Functions: Lsp_lsf + Lsf_lsp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the functions that convert line spectral pairs (LSP) to + line spectral frequencies (LSF) and vice-versa. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "lsp_lsf.h" +#include "basicop_malloc.h" +#include "basic_op.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + extern const Word16 table[]; + extern const Word16 slope[]; + + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Lsf_lsp +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsf = buffer containing normalized line spectral frequencies; valid + range is between 0 and 0.5 (Word16) + lsp = buffer containing line spectral pairs; valid range is between + -1 and 1 (Word16) + m = LPC order (Word16) + + Outputs: + lsp contains the newly calculated line spectral pairs + + Returns: + None + + Global Variables Used: + table = cosine table + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the LSF to LSP transformation using the equation: + + lsf[i] = arccos(lsp[i])/(2*pi) + + The transformation from lsp[i] to lsf[i] is approximated by a look-up table + and interpolation. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + lsp_lsf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Lsf_lsp ( + Word16 lsf[], // (i) : lsf[m] normalized (range: 0.0<=val<=0.5) + Word16 lsp[], // (o) : lsp[m] (range: -1<=val<1) + Word16 m // (i) : LPC order +) +{ + Word16 i, ind, offset; + Word32 L_tmp; + + for (i = 0; i < m; i++) + { + ind = shr (lsf[i], 8); // ind = b8-b15 of lsf[i] + offset = lsf[i] & 0x00ff; // offset = b0-b7 of lsf[i] + + // lsp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 256 + + L_tmp = L_mult (sub (table[ind + 1], table[ind]), offset); + lsp[i] = add (table[ind], extract_l (L_shr (L_tmp, 9))); + + } + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void Lsf_lsp( + Word16 lsf[], /* (i) : lsf[m] normalized (range: 0.0<=val<=0.5) */ + Word16 lsp[], /* (o) : lsp[m] (range: -1<=val<1) */ + Word16 m, /* (i) : LPC order */ + Flag *pOverflow /* (o) : Flag set when overflow occurs */ +) +{ + Word16 i, ind, offset; + Word32 L_tmp; + + for (i = 0; i < m; i++) + { + ind = lsf[i] >> 8; /* ind = b8-b15 of lsf[i] */ + offset = lsf[i] & 0x00ff; /* offset = b0-b7 of lsf[i] */ + + /* lsp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 256 */ + + L_tmp = ((Word32)(table[ind + 1] - table[ind]) * offset) >> 8; + lsp[i] = table[ind] + (Word16) L_tmp; + + } + + return; +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Lsp_lsf +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsp = buffer containing line spectral pairs; valid range is between + -1 and 1 (Word16) + lsf = buffer containing normalized line spectral frequencies; valid + range is between 0 and 0.5 (Word16) + m = LPC order (Word16) + + Outputs: + lsf contains the newly calculated normalized line spectral frequencies + + Returns: + None + + Global Variables Used: + table = cosine table + slope = table to used to calculate inverse cosine + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the LSP to LSF transformation using the equation: + + lsp[i] = cos(2*pi*lsf[i]) + + The transformation from lsf[i] to lsp[i] is approximated by a look-up table + and interpolation. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + lsp_lsf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Lsp_lsf ( + Word16 lsp[], // (i) : lsp[m] (range: -1<=val<1) + Word16 lsf[], // (o) : lsf[m] normalized (range: 0.0<=val<=0.5) + Word16 m // (i) : LPC order +) +{ + Word16 i, ind; + Word32 L_tmp; + + ind = 63; // begin at end of table -1 + + for (i = m - 1; i >= 0; i--) + { + // find value in table that is just greater than lsp[i] + + while (sub (table[ind], lsp[i]) < 0) + { + ind--; + + } + + // acos(lsp[i])= ind*256 + ( ( lsp[i]-table[ind] ) * + slope[ind] )/4096 + + L_tmp = L_mult (sub (lsp[i], table[ind]), slope[ind]); + //(lsp[i]-table[ind])*slope[ind])>>12 + lsf[i] = pv_round (L_shl (L_tmp, 3)); + lsf[i] = add (lsf[i], shl (ind, 8)); + } + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void Lsp_lsf( + Word16 lsp[], /* (i) : lsp[m] (range: -1<=val<1) */ + Word16 lsf[], /* (o) : lsf[m] normalized (range: 0.0<=val<=0.5) */ + Word16 m, /* (i) : LPC order */ + Flag *pOverflow /* (o) : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 ind; + Word16 temp; + Word32 L_tmp; + Word16 *p_lsp = &lsp[m-1]; + Word16 *p_lsf = &lsf[m-1]; + OSCL_UNUSED_ARG(pOverflow); + + ind = 63; /* begin at end of table -1 */ + + for (i = m - 1; i >= 0; i--) + { + /* find value in table that is just greater than lsp[i] */ + temp = *(p_lsp--); + while (table[ind] < temp) + { + ind--; + } + + /* acos(lsp[i])= ind*256 + ( ( lsp[i]-table[ind] ) * + slope[ind] )/4096 */ + + L_tmp = (Word32)(temp - table[ind]) * slope[ind]; + + /*(lsp[i]-table[ind])*slope[ind])>>12*/ + L_tmp = (L_tmp + 0x00000800) >> 12; + + *(p_lsf--) = (Word16)(L_tmp) + (ind << 8); + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp_lsf_tbl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp_lsf_tbl.cpp new file mode 100644 index 00000000..f44aabfd --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp_lsf_tbl.cpp @@ -0,0 +1,105 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: lsp_lsf_tbl.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + + extern const Word16 table[]; + const Word16 table[65] = + { + 32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853, + 30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279, + 23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010, + 12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608, + 0, -1608, -3212, -4808, -6393, -7962, -9512, -11039, + -12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006, + -23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622, + -30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729, + (Word16) 0x8000 + }; + + /* 0x8000 = -32768 (used to silence the compiler) */ + + /* slope used to compute y = acos(x) */ + + extern const Word16 slope[]; + const Word16 slope[64] = + { + -26887, -8812, -5323, -3813, -2979, -2444, -2081, -1811, + -1608, -1450, -1322, -1219, -1132, -1059, -998, -946, + -901, -861, -827, -797, -772, -750, -730, -713, + -699, -687, -677, -668, -662, -657, -654, -652, + -652, -654, -657, -662, -668, -677, -687, -699, + -713, -730, -750, -772, -797, -827, -861, -901, + -946, -998, -1059, -1132, -1219, -1322, -1450, -1608, + -1811, -2081, -2444, -2979, -3813, -5323, -8812, -26887 + }; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp_tab.cpp new file mode 100644 index 00000000..d2361370 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/lsp_tab.cpp @@ -0,0 +1,154 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: lsp_tab.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + None + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + File : lsp.tab + Purpose : Table for lsp init + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "lsp_tab.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; LOCAL STORE/BUFFER/POINTER DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + const Word16 lsp_init_data[M] = + { + 30000, 26000, 21000, 15000, 8000, + 0, -8000, -15000, -21000, -26000 + }; + + /*---------------------------------------------------------------------------- + ; EXTERNAL FUNCTION REFERENCES + ; Declare functions defined elsewhere and referenced in this module + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; Define all local variables +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Function body here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Return nothing or data or data pointer +----------------------------------------------------------------------------*/ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/mult_r.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/mult_r.cpp new file mode 100644 index 00000000..003afc74 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/mult_r.cpp @@ -0,0 +1,183 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: mult_r.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Multiplication function with rounding and overflow control + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: mult_r +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the add operation resulted in overflow + + Returns: + L_product_arr = 16-bit limited product of var1 and var2 (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the multiplication of var1 by var2 with rounding, and + gives a 16 bit result which is scaled, i.e.: + mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and | + mult_r(-32768,-32768) = 32767 + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] mult_r() function in basicop2.c, UMTS GSM AMR speech codec, R99 - + Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 mult_r (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_product_arr; + + L_product_arr = (Word32) var1 *(Word32) var2; + L_product_arr += (Word32) 0x00004000L; + L_product_arr &= (Word32) 0xffff8000L; + L_product_arr >>= 15; + + if (L_product_arr & (Word32) 0x00010000L) + { + L_product_arr |= (Word32) 0xffff0000L; + } +* The reference ETSI code uses a global flag for Overflow inside the function +* saturate(). In the actual implementation a pointer to Overflow flag is passed in +* as a parameter to the function + + var_out = saturate (L_product_arr); + +#if (WMOPS) + multiCounter[currCounter].mult_r++; +#endif + + return (var_out); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +OSCL_EXPORT_REF Word16 mult_r(Word16 var1, Word16 var2, Flag *pOverflow) +{ + + register Word32 L_product_arr; + + L_product_arr = ((Word32) var1) * var2; /* product */ + L_product_arr += (Word32) 0x00004000L; /* round */ + L_product_arr >>= 15; /* shift */ + + /* sign extend when necessary */ + L_product_arr |= (Word32) - (L_product_arr & (Word32) 0x00010000L); + + /* Saturate result (if necessary). */ + /* Replaced function call with in-line code to conserve MIPS, */ + /* i.e., var_out = saturate (L_product_arr) */ + + if (L_product_arr > 0X00007fffL) + { + *pOverflow = 1; + L_product_arr = MAX_16; + } + else if (L_product_arr < (Word32) - 32768) + { + *pOverflow = 1; + L_product_arr = MIN_16; + } + + return ((Word16) L_product_arr); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/negate.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/negate.cpp new file mode 100644 index 00000000..3db2458e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/negate.cpp @@ -0,0 +1,146 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: negate.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + var1 = negated value of input (Word16) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function negates var1 with saturation; saturate in the case where input + is -32768: negate(var1) = sub(0,var1). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 negate (Word16 var1) +{ + Word16 var_out; + + var_out = (var1 == MIN_16) ? MAX_16 : -var1; +#if (WMOPS) + multiCounter[currCounter].negate++; +#endif + return (var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "negate.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word16 negate(register Word16 var1) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + var1 = (var1 == MIN_16) ? MAX_16 : -var1; + + /*---------------------------------------------------------------------------- + ; Return nothing or data or data pointer + ----------------------------------------------------------------------------*/ + return (var1); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/norm_l.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/norm_l.cpp new file mode 100644 index 00000000..dc4ca72f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/norm_l.cpp @@ -0,0 +1,203 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: norm_l.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= var1 <= 0x7fff ffff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + var_out = number of left shifts need to normalize input (Word16) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function produces the number of left shifts needed to normalize the 32 + bit variable L_var1 for positive values on the interval with minimum of + 0x40000000 and maximum of 0x7fffffff, and for negative values on the interval + with minimum of 0x80000000 and maximum of 0xc0000000. Note that when L_var1 + is equal to zero, the output var_out is set to zero. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 norm_l (Word32 L_var1) +{ + Word16 var_out; + + if (L_var1 == 0) + { + var_out = 0; + } + else + { + if (L_var1 == (Word32) 0xffffffffL) + { + var_out = 31; + } + else + { + if (L_var1 < 0) + { + L_var1 = ~L_var1; + } + for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++) + { + L_var1 <<= 1; + } + } + } + +#if (WMOPS) + multiCounter[currCounter].norm_l++; +#endif + return (var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +#if !((PV_CPU_ARCH_VERSION >=5) && ((PV_COMPILER == EPV_ARM_GNUC) || (PV_COMPILER == EPV_ARM_RVCT))) +OSCL_EXPORT_REF Word16 norm_l(register Word32 L_var1) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + register Word16 var_out = 0; + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + + if (L_var1) + { + + Word32 y = L_var1 - (L_var1 < 0); + L_var1 = y ^(y >> 31); + + + while (!(0x40000000L & L_var1)) + { + var_out++; + if ((0x20000000L & L_var1)) + { + break; + } + var_out++; + if ((0x10000000L & L_var1)) + { + break; + } + var_out++; + if ((0x08000000L & L_var1)) + { + break; + } + var_out++; + L_var1 <<= 4; + } + } + + /*---------------------------------------------------------------------------- + ; Return nothing or data or data pointer + ----------------------------------------------------------------------------*/ + + + return (var_out); +} +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/norm_s.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/norm_s.cpp new file mode 100644 index 00000000..4fdc6d26 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/norm_s.cpp @@ -0,0 +1,203 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: norm_s.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit signed integer of type Word16, whose value falls + in the range: 0x8000 <= var1 <= 0x7fff + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + var_out = number of left shifts need to normalize var1 (Word16) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function produces the number of left shifts needed to normalize the 16 + bit variable var1 for positive values on the interval with minimum of 0x4000 + and maximum of 0x7fff, and for negative values on the interval with minimum + of 0x8000 and maximum of 0xc000. Note that when var1 is zero, the resulting + output var_out is set to zero. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 norm_s (Word16 var1) +{ + Word16 var_out; + + if (var1 == 0) + { + var_out = 0; + } + else + { + if (var1 == (Word16) 0xffff) + { + var_out = 15; + } + else + { + if (var1 < 0) + { + var1 = ~var1; + } + for (var_out = 0; var1 < 0x4000; var_out++) + { + var1 <<= 1; + } + } + } + +#if (WMOPS) + multiCounter[currCounter].norm_s++; +#endif + return (var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +#if !((PV_CPU_ARCH_VERSION >=5) && ((PV_COMPILER == EPV_ARM_GNUC) || (PV_COMPILER == EPV_ARM_RVCT))) + +OSCL_EXPORT_REF Word16 norm_s(register Word16 var1) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + + register Word16 var_out = 0; + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + + if (var1) + { + Word16 y = var1 - (var1 < 0); + var1 = y ^(y >> 15); + + while (!(0x4000 & var1)) + { + var_out++; + if ((0x2000 & var1)) + { + break; + } + var_out++; + if ((0x1000 & var1)) + { + break; + } + var_out++; + if ((0x0800 & var1)) + { + break; + } + var_out++; + var1 <<= 4; + } + } + + /*---------------------------------------------------------------------------- + ; Return nothing or data or data pointer + ----------------------------------------------------------------------------*/ + return (var_out); +} + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/overflow_tbl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/overflow_tbl.cpp new file mode 100644 index 00000000..d78d6270 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/overflow_tbl.cpp @@ -0,0 +1,147 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: overflow_tbl.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the declaration for overflow_tbl[] used by the l_shl() + and l_shr() functions. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + const Word32 overflow_tbl [32] = {0x7fffffffL, 0x3fffffffL, + 0x1fffffffL, 0x0fffffffL, + 0x07ffffffL, 0x03ffffffL, + 0x01ffffffL, 0x00ffffffL, + 0x007fffffL, 0x003fffffL, + 0x001fffffL, 0x000fffffL, + 0x0007ffffL, 0x0003ffffL, + 0x0001ffffL, 0x0000ffffL, + 0x00007fffL, 0x00003fffL, + 0x00001fffL, 0x00000fffL, + 0x000007ffL, 0x000003ffL, + 0x000001ffL, 0x000000ffL, + 0x0000007fL, 0x0000003fL, + 0x0000001fL, 0x0000000fL, + 0x00000007L, 0x00000003L, + 0x00000001L, 0x00000000L + }; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] l_shl() function in basic_op2.c, UMTS GSM AMR speech codec, R99 - + Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/ph_disp_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/ph_disp_tab.cpp new file mode 100644 index 00000000..f9e7faaf --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/ph_disp_tab.cpp @@ -0,0 +1,165 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: ph_disp_tab.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the table of impulse responses of the phase dispersion + filters. All impulse responses are in Q15 + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + extern const Word16 ph_imp_low_MR795[]; + const Word16 ph_imp_low_MR795[40] = + { + 26777, 801, 2505, -683, -1382, 582, 604, -1274, 3511, -5894, + 4534, -499, -1940, 3011, -5058, 5614, -1990, -1061, -1459, 4442, + -700, -5335, 4609, 452, -589, -3352, 2953, 1267, -1212, -2590, + 1731, 3670, -4475, -975, 4391, -2537, 949, -1363, -979, 5734 + }; + extern const Word16 ph_imp_mid_MR795[]; + const Word16 ph_imp_mid_MR795[40] = + { + 30274, 3831, -4036, 2972, -1048, -1002, 2477, -3043, 2815, -2231, + 1753, -1611, 1714, -1775, 1543, -1008, 429, -169, 472, -1264, + 2176, -2706, 2523, -1621, 344, 826, -1529, 1724, -1657, 1701, + -2063, 2644, -3060, 2897, -1978, 557, 780, -1369, 842, 655 + }; + + extern const Word16 ph_imp_low[]; + const Word16 ph_imp_low[40] = + { + 14690, 11518, 1268, -2761, -5671, 7514, -35, -2807, -3040, 4823, + 2952, -8424, 3785, 1455, 2179, -8637, 8051, -2103, -1454, 777, + 1108, -2385, 2254, -363, -674, -2103, 6046, -5681, 1072, 3123, + -5058, 5312, -2329, -3728, 6924, -3889, 675, -1775, 29, 10145 + }; + extern const Word16 ph_imp_mid[]; + const Word16 ph_imp_mid[40] = + { + 30274, 3831, -4036, 2972, -1048, -1002, 2477, -3043, 2815, -2231, + 1753, -1611, 1714, -1775, 1543, -1008, 429, -169, 472, -1264, + 2176, -2706, 2523, -1621, 344, 826, -1529, 1724, -1657, 1701, + -2063, 2644, -3060, 2897, -1978, 557, 780, -1369, 842, 655 + }; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] ph_disp.tab, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/pow2.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/pow2.cpp new file mode 100644 index 00000000..637f92dd --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/pow2.cpp @@ -0,0 +1,176 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: pow2.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "pow2.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pow2 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + exponent = Integer part whose valid range is: 0 <= value <= 30 (Word16) + fraction = Fractional part whose valid range is 0 <= value < 1 + + pOverflow = pointer to overflow flag + + Outputs: + L_x = Result of the Pow2() computation (Word32) + pOverflow -> 1 if the Pow2() function results in saturation + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes L_x = pow(2.0, exponent.fraction) + + The function Pow2(L_x) is approximated by a table and linear interpolation. + + 1- i = bit10-b15 of fraction, 0 <= i <= 31 + 2- a = bit0-b9 of fraction + 3- L_x = table[i]<<16 - (table[i] - table[i+1]) * a * 2 + 4- L_x = L_x >> (30-exponent) (with rounding) + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pow2.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word32 Pow2 ( // (o) : result (range: 0<=val<=0x7fffffff) + Word16 exponent, // (i) : Integer part. (range: 0<=val<=30) + Word16 fraction // (i) : Fractional part. (range: 0.0<=val<1.0) +) +{ + Word16 exp, i, a, tmp; + Word32 L_x; + + L_x = L_mult (fraction, 32); // L_x = fraction<<6 + i = extract_h (L_x); // Extract b10-b16 of fraction + L_x = L_shr (L_x, 1); + a = extract_l (L_x); // Extract b0-b9 of fraction + a = a & (Word16) 0x7fff; + + L_x = L_deposit_h (table[i]); // table[i] << 16 + tmp = sub (table[i], table[i + 1]); // table[i] - table[i+1] + L_x = L_msu (L_x, tmp, a); // L_x -= tmp*a*2 + + exp = sub (30, exponent); + L_x = L_shr_r (L_x, exp); + + return (L_x); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +OSCL_EXPORT_REF Word32 Pow2( /* (o) : result (range: 0<=val<=0x7fffffff) */ + Word16 exponent, /* (i) : Integer part. (range: 0<=val<=30) */ + Word16 fraction, /* (i) : Fractional part. (range: 0.0<=val<1.0) */ + Flag *pOverflow +) +{ + Word16 exp, i, a, tmp; + Word32 L_x; + + L_x = L_mult(fraction, 32, pOverflow); /* L_x = fraction<<6 */ + + /* Extract b0-b16 of fraction */ + + i = ((Word16)(L_x >> 16)) & 31; /* ensure index i is bounded */ + a = (Word16)((L_x >> 1) & 0x7fff); + + L_x = ((Word32) pow2_tbl[i] << 16); /* pow2_tbl[i] << 16 */ + + /* pow2_tbl[i] - pow2_tbl[i+1] */ + tmp = pow2_tbl[i] - pow2_tbl[i + 1]; + L_x = L_msu(L_x, tmp, a, pOverflow); /* L_x -= tmp*a*2 */ + + exp = 30 - exponent; + L_x = L_shr_r(L_x, exp, pOverflow); + + return (L_x); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/pow2_tbl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/pow2_tbl.cpp new file mode 100644 index 00000000..e49a89d4 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/pow2_tbl.cpp @@ -0,0 +1,136 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: pow2_tbl.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the declaration for log2_tbl[] used by the Pow2() function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "pow2.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + + const Word16 pow2_tbl[33] = + { + 16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911, + 20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726, + 25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706, + 31379, 32066, 32767 + }; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] pow2.tab, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/pred_lt.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/pred_lt.cpp new file mode 100644 index 00000000..fd51242c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/pred_lt.cpp @@ -0,0 +1,291 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: pred_lt.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "pred_lt.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define UP_SAMP_MAX 6 +#define L_INTER10 (L_INTERPOL-1) +#define FIR_SIZE (UP_SAMP_MAX*L_INTER10+1) + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* 1/6 resolution interpolation filter (-3 dB at 3600 Hz) */ +/* Note: the 1/3 resolution filter is simply a subsampled + * version of the 1/6 resolution filter, i.e. it uses + * every second coefficient: + * + * inter_3l[k] = inter_6[2*k], 0 <= k <= 3*L_INTER10 + */ + +const Word16 inter_6_pred_lt[FIR_SIZE] = +{ + 29443, + 28346, 25207, 20449, 14701, 8693, 3143, + -1352, -4402, -5865, -5850, -4673, -2783, + -672, 1211, 2536, 3130, 2991, 2259, + 1170, 0, -1001, -1652, -1868, -1666, + -1147, -464, 218, 756, 1060, 1099, + 904, 550, 135, -245, -514, -634, + -602, -451, -231, 0, 191, 308, + 340, 296, 198, 78, -36, -120, + -163, -165, -132, -79, -19, 34, + 73, 91, 89, 70, 38, 0 +}; + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pred_lt_3or6 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + exc = buffer containing the excitation (Word16) + T0 = integer pitch lag (Word16) + frac = fraction of lag (Word16) + L_subfr = number of samples per subframe (Word16) + flag3 = flag to indicate the upsampling rate; if set, upsampling + rate is 3, otherwise, upsampling rate is 6 (Word16) + + pOverflow = pointer to overflow (Flag) + + Returns: + None + + Outputs: + exc buffer contains the newly formed adaptive codebook excitation + pOverflow -> 1 if the add operation resulted in overflow + + Global Variables Used: + inter_6_pred_lt = (1/6) resolution interpolation filter table (Word16) + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes the result of long term prediction with fractional + interpolation of resolution 1/3 or 1/6. (Interpolated past excitation). + + The past excitation signal at the given delay is interpolated at + the given fraction to build the adaptive codebook excitation. + On return exc[0..L_subfr-1] contains the interpolated signal + (adaptive codebook excitation). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pred_lt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Pred_lt_3or6 ( + Word16 exc[], // in/out: excitation buffer + Word16 T0, // input : integer pitch lag + Word16 frac, // input : fraction of lag + Word16 L_subfr, // input : subframe size + Word16 flag3 // input : if set, upsampling rate = 3 (6 otherwise) +) +{ + Word16 i, j, k; + Word16 *pX0, *pX1, *pX2; + const Word16 *pC1, *pC2; + Word32 s; + + pX0 = &exc[-T0]; + + frac = negate (frac); + if (flag3 != 0) + { + frac = shl (frac, 1); // inter_3l[k] = inter_6[2*k] -> k' = 2*k + } + + if (frac < 0) + { + frac = add (frac, UP_SAMP_MAX); + pX0--; + } + + for (j = 0; j < L_subfr; j++) + { + pX1 = pX0++; + pX2 = pX0; + pC1 = &inter_6[frac]; + pC2 = &inter_6[sub (UP_SAMP_MAX, frac)]; + + s = 0; + for (i = 0, k = 0; i < L_INTER10; i++, k += UP_SAMP_MAX) + { + s = L_mac (s, pX1[-i], pC1[k]); + s = L_mac (s, pX2[i], pC2[k]); + } + + exc[j] = pv_round (s); + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void Pred_lt_3or6( + Word16 exc[], /* in/out: excitation buffer */ + Word16 T0, /* input : integer pitch lag */ + Word16 frac, /* input : fraction of lag */ + Word16 L_subfr, /* input : subframe size */ + Word16 flag3, /* input : if set, upsampling rate = 3 (6 otherwise) */ + Flag *pOverflow /* output: if set, overflow occurred in this function */ +) +{ + register Word16 i; + register Word16 j; + register Word16 k; + + Word16 *pX0; + Word16 *pX2; + Word16 *pX3; + Word16 *p_exc; + Word16 *pC1; + const Word16 *pC1_ref; + const Word16 *pC2_ref; + + Word16 Coeff_1[(L_INTER10<<1)]; + + Word32 s1; + Word32 s2; + OSCL_UNUSED_ARG(pOverflow); + + pX0 = &(exc[-T0]); + + /* frac goes between -3 and 3 */ + + frac = -frac; + + if (flag3 != 0) + { + frac <<= 1; /* inter_3l[k] = inter_6[2*k] -> k' = 2*k */ + } + + if (frac < 0) + { + frac += UP_SAMP_MAX; + pX0--; + } + + pC1_ref = &inter_6_pred_lt[frac]; + pC2_ref = &inter_6_pred_lt[UP_SAMP_MAX-frac]; + + + pC1 = Coeff_1; + + k = 0; + + for (i = L_INTER10 >> 1; i > 0; i--) + { + *(pC1++) = pC1_ref[k]; + *(pC1++) = pC2_ref[k]; + k += UP_SAMP_MAX; + *(pC1++) = pC1_ref[k]; + *(pC1++) = pC2_ref[k]; + k += UP_SAMP_MAX; + + } + + p_exc = exc; + + for (j = (L_subfr >> 1); j != 0 ; j--) + { + pX0++; + pX2 = pX0; + pX3 = pX0++; + + pC1 = Coeff_1; + + s1 = 0x00004000L; + s2 = 0x00004000L; + + for (i = L_INTER10 >> 1; i > 0; i--) + { + s2 += ((Word32) * (pX3--)) * *(pC1); + s1 += ((Word32) * (pX3)) * *(pC1++); + s1 += ((Word32) * (pX2++)) * *(pC1); + s2 += ((Word32) * (pX2)) * *(pC1++); + s2 += ((Word32) * (pX3--)) * *(pC1); + s1 += ((Word32) * (pX3)) * *(pC1++); + s1 += ((Word32) * (pX2++)) * *(pC1); + s2 += ((Word32) * (pX2)) * *(pC1++); + + } /* for (i = L_INTER10>>1; i > 0; i--) */ + + *(p_exc++) = (Word16)(s1 >> 15); + *(p_exc++) = (Word16)(s2 >> 15); + + } /* for (j = (L_subfr>>1); j != 0 ; j--) */ + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf.cpp new file mode 100644 index 00000000..75392e96 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf.cpp @@ -0,0 +1,142 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : q_plsf.c +* Purpose : common part (init, exit, reset) of LSF quantization +* module (rest in q_plsf_3.c and q_plsf_5.c) +* +******************************************************************************** +*/ + +/* +******************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +******************************************************************************** +*/ +#include "q_plsf.h" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" +#include "basic_op.h" +#include "oscl_mem.h" + + +/* +******************************************************************************** +* PUBLIC PROGRAM CODE +******************************************************************************** +*/ + +/* +************************************************************************** +* +* Function : Q_plsf_init +* Purpose : Allocates memory and initializes state variables +* +************************************************************************** +*/ +Word16 Q_plsf_init(Q_plsfState **state) +{ + Q_plsfState* s; + + if (state == (Q_plsfState **) NULL) + { + /* fprintf(stderr, "Q_plsf_init: invalid parameter\n"); */ + return -1; + } + *state = NULL; + + /* allocate memory */ + if ((s = (Q_plsfState *) oscl_malloc(sizeof(Q_plsfState))) == NULL) + { + /* fprintf(stderr, "Q_plsf_init: can not malloc state structure\n"); */ + return -1; + } + + Q_plsf_reset(s); + *state = s; + + return 0; +} + +/* +************************************************************************** +* +* Function : Q_plsf_reset +* Purpose : Resets state memory +* +************************************************************************** +*/ +Word16 Q_plsf_reset(Q_plsfState *state) +{ + Word16 i; + + if (state == (Q_plsfState *) NULL) + { + /* fprintf(stderr, "Q_plsf_reset: invalid parameter\n"); */ + return -1; + } + + for (i = 0; i < M; i++) + state->past_rq[i] = 0; + + return 0; +} + +/* +************************************************************************** +* +* Function : Q_plsf_exit +* Purpose : The memory used for state memory is freed +* +************************************************************************** +*/ +void Q_plsf_exit(Q_plsfState **state) +{ + if (state == NULL || *state == NULL) + return; + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf_3.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf_3.cpp new file mode 100644 index 00000000..2c5446b3 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf_3.cpp @@ -0,0 +1,1097 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: q_plsf_3.cpp + Funtions: Vq_subvec4 + Test_Vq_subvec4 + Vq_subvec3 + Test_Vq_subvec3 + Q_plsf_3 + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the functions that perform the quantization of LSF + parameters with first order MA prediction and split by 3 vector + quantization (split-VQ). + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "q_plsf.h" +#include "typedef.h" +#include "lsp_lsf.h" +#include "reorder.h" +#include "lsfwt.h" +#include "oscl_mem.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ +#define PAST_RQ_INIT_SIZE 8 + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + /* Codebooks of LSF prediction residual */ + extern const Word16 mean_lsf_3[]; + + extern const Word16 pred_fac_3[]; + + extern const Word16 dico1_lsf_3[]; + extern const Word16 dico2_lsf_3[]; + extern const Word16 dico3_lsf_3[]; + + extern const Word16 mr515_3_lsf[]; + extern const Word16 mr795_1_lsf[]; + + extern const Word16 past_rq_init[]; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Vq_subvec4 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsf_r1 = pointer to the first LSF residual vector (Q15) (Word16) + dico = pointer to the quantization codebook (Q15) (const Word16) + wf1 = pointer to the first LSF weighting factor (Q13) (Word16) + dico_size = size of quantization codebook (Q0) (Word16) + + Outputs: + buffer pointed to by lsf_r1 contains the selected vector + pOverflow -- pointer to Flag -- Flag set when overflow occurs + + Returns: + index = quantization index (Q0) (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the quantization of a 4-dimensional subvector. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + q_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static Word16 +Vq_subvec4( // o: quantization index, Q0 + Word16 * lsf_r1, // i: 1st LSF residual vector, Q15 + Word16 * dico, // i: quantization codebook, Q15 + Word16 * wf1, // i: 1st LSF weighting factors, Q13 + Word16 dico_size) // i: size of quantization codebook, Q0 +{ + Word16 i, index = 0; + Word16 *p_dico, temp; + Word32 dist_min, dist; + + dist_min = MAX_32; + p_dico = dico; + + for (i = 0; i < dico_size; i++) + { + temp = sub (lsf_r1[0], *p_dico++); + temp = mult (wf1[0], temp); + dist = L_mult (temp, temp); + + temp = sub (lsf_r1[1], *p_dico++); + temp = mult (wf1[1], temp); + dist = L_mac (dist, temp, temp); + + temp = sub (lsf_r1[2], *p_dico++); + temp = mult (wf1[2], temp); + dist = L_mac (dist, temp, temp); + + temp = sub (lsf_r1[3], *p_dico++); + temp = mult (wf1[3], temp); + dist = L_mac (dist, temp, temp); + + + if (L_sub (dist, dist_min) < (Word32) 0) + { + dist_min = dist; + index = i; + } + } + + // Reading the selected vector + + p_dico = &dico[shl (index, 2)]; + lsf_r1[0] = *p_dico++; + lsf_r1[1] = *p_dico++; + lsf_r1[2] = *p_dico++; + lsf_r1[3] = *p_dico; + + return index; + +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 Vq_subvec4( /* o: quantization index, Q0 */ + Word16 * lsf_r1, /* i: 1st LSF residual vector, Q15 */ + const Word16 * dico, /* i: quantization codebook, Q15 */ + Word16 * wf1, /* i: 1st LSF weighting factors, Q13 */ + Word16 dico_size, /* i: size of quantization codebook, Q0 */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + register Word16 i; + Word16 temp; + const Word16 *p_dico; + Word16 index = 0; + Word32 dist_min; + Word32 dist; + + Word16 lsf_r1_0; + Word16 lsf_r1_1; + Word16 lsf_r1_2; + Word16 lsf_r1_3; + + Word16 wf1_0; + Word16 wf1_1; + Word16 wf1_2; + Word16 wf1_3; + + OSCL_UNUSED_ARG(pOverflow); + + dist_min = MAX_32; + p_dico = dico; + + lsf_r1_0 = lsf_r1[0]; + lsf_r1_1 = lsf_r1[1]; + lsf_r1_2 = lsf_r1[2]; + lsf_r1_3 = lsf_r1[3]; + + wf1_0 = wf1[0]; + wf1_1 = wf1[1]; + wf1_2 = wf1[2]; + wf1_3 = wf1[3]; + + for (i = 0; i < dico_size; i++) + { + temp = lsf_r1_0 - (*p_dico++); + temp = (Word16)((((Word32) wf1_0) * temp) >> 15); + dist = ((Word32) temp) * temp; + + temp = lsf_r1_1 - (*p_dico++); + temp = (Word16)((((Word32) wf1_1) * temp) >> 15); + dist += ((Word32) temp) * temp; + + temp = lsf_r1_2 - (*p_dico++); + temp = (Word16)((((Word32) wf1_2) * temp) >> 15); + dist += ((Word32) temp) * temp; + + temp = lsf_r1_3 - (*p_dico++); + temp = (Word16)((((Word32) wf1_3) * temp) >> 15); + dist += ((Word32) temp) * temp; + + if (dist < dist_min) + { + dist_min = dist; + index = i; + } + } + + /* Reading the selected vector */ + + p_dico = dico + (index << 2); + *lsf_r1++ = *p_dico++; + *lsf_r1++ = *p_dico++; + *lsf_r1++ = *p_dico++; + *lsf_r1 = *p_dico; + + return(index); + +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Test_Vq_subvec4 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsf_r1 = pointer to the first LSF residual vector (Q15) (Word16) + dico = pointer to the quantization codebook (Q15) (const Word16) + wf1 = pointer to the first LSF weighting factor (Q13) (Word16) + dico_size = size of quantization codebook (Q0) (Word16) + + Outputs: + buffer pointed to by lsf_r1 contains the selected vector + pOverflow -- pointer to Flag -- Flag set when overflow occurs + + Returns: + index = quantization index (Q0) (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calls the static function Vq_subvec4. It is used for testing + purposes only + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + CALL Vq_subvec4(lsf_r1 = lsf_r1 + dico = dico + wf1 = wf1 + dico_size = dico_size) + MODIFYING(nothing) + RETURNING(index = tst_index4) + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Test_Vq_subvec4( + Word16 * lsf_r1, + const Word16 * dico, + Word16 * wf1, + Word16 dico_size, + Flag *pOverflow) +{ + Word16 tst_index4 = 0; + + /*------------------------------------------------------------------------ + CALL Vq_subvec4(lsf_r1 = lsf_r1 + dico = dico + wf1 = wf1 + dico_size = dico_size) + MODIFYING(nothing) + RETURNING(index = index) + ------------------------------------------------------------------------*/ + tst_index4 = + Vq_subvec4( + lsf_r1, + dico, + wf1, + dico_size, + pOverflow); + + return(tst_index4); + +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Vq_subvec3 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsf_r1 = pointer to the first LSF residual vector (Q15) (Word16) + dico = pointer to the quantization codebook (Q15) (const Word16) + wf1 = pointer to the first LSF weighting factor (Q13) (Word16) + dico_size = size of quantization codebook (Q0) (Word16) + use_half = flag to indicate use of every second entry in the + codebook (Flag) + + Outputs: + buffer pointed to by lsf_r1 contains the selected vector + pOverflow -- pointer to Flag -- Flag set when overflow occurs + + Returns: + index = quantization index (Q0) (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the quantization of a 3 dimensional subvector. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + q_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static Word16 +Vq_subvec3( // o: quantization index, Q0 + Word16 * lsf_r1, // i: 1st LSF residual vector, Q15 + Word16 * dico, // i: quantization codebook, Q15 + Word16 * wf1, // i: 1st LSF weighting factors, Q13 + Word16 dico_size, // i: size of quantization codebook, Q0 + Flag use_half) // i: use every second entry in codebook +{ + Word16 i, index = 0; + Word16 *p_dico, temp; + Word32 dist_min, dist; + + dist_min = MAX_32; + p_dico = dico; + + if (use_half == 0) { + for (i = 0; i < dico_size; i++) + { + temp = sub(lsf_r1[0], *p_dico++); + temp = mult(wf1[0], temp); + dist = L_mult(temp, temp); + + temp = sub(lsf_r1[1], *p_dico++); + temp = mult(wf1[1], temp); + dist = L_mac(dist, temp, temp); + + temp = sub(lsf_r1[2], *p_dico++); + temp = mult(wf1[2], temp); + dist = L_mac(dist, temp, temp); + + if (L_sub(dist, dist_min) < (Word32) 0) { + dist_min = dist; + index = i; + } + } + p_dico = &dico[add(index, add(index, index))]; + } + else + { + for (i = 0; i < dico_size; i++) + { + temp = sub(lsf_r1[0], *p_dico++); + temp = mult(wf1[0], temp); + dist = L_mult(temp, temp); + + temp = sub(lsf_r1[1], *p_dico++); + temp = mult(wf1[1], temp); + dist = L_mac(dist, temp, temp); + + temp = sub(lsf_r1[2], *p_dico++); + temp = mult(wf1[2], temp); + dist = L_mac(dist, temp, temp); + + if (L_sub(dist, dist_min) < (Word32) 0) + { + dist_min = dist; + index = i; + } + p_dico = p_dico + 3; add(0,0); + } + p_dico = &dico[shl(add(index, add(index, index)),1)]; + } + + + // Reading the selected vector + lsf_r1[0] = *p_dico++; + lsf_r1[1] = *p_dico++; + lsf_r1[2] = *p_dico++; + + return index; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 Vq_subvec3( /* o: quantization index, Q0 */ + Word16 * lsf_r1, /* i: 1st LSF residual vector, Q15 */ + const Word16 * dico, /* i: quantization codebook, Q15 */ + Word16 * wf1, /* i: 1st LSF weighting factors, Q13 */ + Word16 dico_size, /* i: size of quantization codebook, Q0 */ + Flag use_half, /* i: use every second entry in codebook */ + Flag *pOverflow) /* o : Flag set when overflow occurs */ +{ + register Word16 i; + Word16 temp; + + const Word16 *p_dico; + + Word16 p_dico_index = 0; + Word16 index = 0; + + Word32 dist_min; + Word32 dist; + + Word16 lsf_r1_0; + Word16 lsf_r1_1; + Word16 lsf_r1_2; + + Word16 wf1_0; + Word16 wf1_1; + Word16 wf1_2; + + OSCL_UNUSED_ARG(pOverflow); + + dist_min = MAX_32; + p_dico = dico; + + lsf_r1_0 = lsf_r1[0]; + lsf_r1_1 = lsf_r1[1]; + lsf_r1_2 = lsf_r1[2]; + + wf1_0 = wf1[0]; + wf1_1 = wf1[1]; + wf1_2 = wf1[2]; + + if (use_half != 0) + { + p_dico_index = 3; + } + + for (i = 0; i < dico_size; i++) + { + temp = lsf_r1_0 - (*p_dico++); + temp = (Word16)((((Word32) wf1_0) * temp) >> 15); + dist = ((Word32) temp) * temp; + + temp = lsf_r1_1 - (*p_dico++); + temp = (Word16)((((Word32) wf1_1) * temp) >> 15); + dist += ((Word32) temp) * temp; + + temp = lsf_r1_2 - (*p_dico++); + temp = (Word16)((((Word32) wf1_2) * temp) >> 15); + dist += ((Word32) temp) * temp; + + if (dist < dist_min) + { + dist_min = dist; + index = i; + } + + p_dico = p_dico + p_dico_index; + } + + p_dico = dico + (3 * index); + + if (use_half != 0) + { + p_dico += (3 * index); + } + + /* Reading the selected vector */ + *lsf_r1++ = *p_dico++; + *lsf_r1++ = *p_dico++; + *lsf_r1 = *p_dico; + + return(index); +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Test_Vq_subvec3 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsf_r1 = pointer to the first LSF residual vector (Q15) (Word16) + dico = pointer to the quantization codebook (Q15) (const Word16) + wf1 = pointer to the first LSF weighting factor (Q13) (Word16) + dico_size = size of quantization codebook (Q0) (Word16) + use_half = flag to indicate use of every second entry in the + codebook (Flag) + + Outputs: + buffer pointed to by lsf_r1 contains the selected vector + pOverflow -- pointer to Flag -- Flag set when overflow occurs + + Returns: + index = quantization index (Q0) (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calls the static function Vq_subvec3. It is used for testing + purposes only + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + CALL Vq_subvec3(lsf_r1 = lsf_r1 + dico = dico + wf1 = wf1 + dico_size = dico_size + use_half = use_half) + MODIFYING(nothing) + RETURNING(index = tst_index3) + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Test_Vq_subvec3( + Word16 * lsf_r1, + const Word16 * dico, + Word16 * wf1, + Word16 dico_size, + Flag use_half, + Flag *pOverflow) +{ + Word16 tst_index3 = 0; + + /*------------------------------------------------------------------------ + CALL Vq_subvec3(lsf_r1 = lsf_r1 + dico = dico + wf1 = wf1 + dico_size = dico_size + use_half = use_half) + MODIFYING(nothing) + RETURNING(index = index) + ------------------------------------------------------------------------*/ + tst_index3 = + Vq_subvec3( + lsf_r1, + dico, + wf1, + dico_size, + use_half, + pOverflow); + + return(tst_index3); + +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Q_plsf_3 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to structures of type Q_plsfState (Q_plsfState) + mode = coder mode (enum) + lsp1 = pointer to the first LSP vector (Word16) + lsp1_q = pointer to the quantized first LSP vector (Word16) + indice = pointer to the quantization indices of 3 vectors (Word16) + pred_init_i = pointer to the index of the initial value for + MA prediction in DTX mode (Word16) + + Outputs: + lsp1_q points to a vector containing the new quantized LSPs + indice points to the new quantization indices of 3 vectors + pred_init_i points to the new initial index for MA prediction + in DTX mode + past_rq field of structure pointed to by st contains the current + quantized LSF parameters + pOverflow -- pointer to Flag -- Flag set when overflow occurs + + Returns: + None + + Global Variables Used: + pred_fac = table containing prediction factors (const Word16) + dico1_lsf = quantization table for split_MQ of 2 sets of LSFs + in a 20 ms frame (const Word16) + dico2_lsf = quantization table for split_MQ of 2 sets of LSFs + in a 20 ms frame (const Word16) + dico3_lsf = quantization table for split_MQ of 2 sets of LSFs + in a 20 ms frame (const Word16) + mr515_3_lsf = third codebook for MR475 and MR515 modes (const Word16) + mr795_1_lsf = first codebook for MR795 mode (const Word16) + mean_lsf = table of mean LSFs (const Word16) + past_rq_init = initalization table for MA predictor in DTX mode + (const Word16) + + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs quantization of LSF parameters with 1st order MA + prediction and split by 3 vector quantization (split-VQ) + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + q_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Q_plsf_3( + Q_plsfState *st, // i/o: state struct + enum Mode mode, // i : coder mode + Word16 *lsp1, // i : 1st LSP vector Q15 + Word16 *lsp1_q, // o : quantized 1st LSP vector Q15 + Word16 *indice, // o : quantization indices of 3 vectors Q0 + Word16 *pred_init_i // o : init index for MA prediction in DTX mode +) +{ + Word16 i, j; + Word16 lsf1[M], wf1[M], lsf_p[M], lsf_r1[M]; + Word16 lsf1_q[M]; + + Word32 L_pred_init_err; + Word32 L_min_pred_init_err; + Word16 temp_r1[M]; + Word16 temp_p[M]; + + // convert LSFs to normalize frequency domain 0..16384 + + Lsp_lsf(lsp1, lsf1, M); + + // compute LSF weighting factors (Q13) + + Lsf_wt(lsf1, wf1); + + // Compute predicted LSF and prediction error + if (test(), sub(mode, MRDTX) != 0) + { + for (i = 0; i < M; i++) + { + lsf_p[i] = add(mean_lsf[i], + mult(st->past_rq[i], + pred_fac[i])); + lsf_r1[i] = sub(lsf1[i], lsf_p[i]); + } + } + else + { + // DTX mode, search the init vector that yields + // lowest prediction resuidual energy + *pred_init_i = 0; + L_min_pred_init_err = 0x7fffffff; // 2^31 - 1 + for (j = 0; j < PAST_RQ_INIT_SIZE; j++) + { + L_pred_init_err = 0; + for (i = 0; i < M; i++) + { + temp_p[i] = add(mean_lsf[i], past_rq_init[j*M+i]); + temp_r1[i] = sub(lsf1[i],temp_p[i]); + L_pred_init_err = L_mac(L_pred_init_err, temp_r1[i], temp_r1[i]); + } // next i + + + if (L_sub(L_pred_init_err, L_min_pred_init_err) < (Word32) 0) + { + L_min_pred_init_err = L_pred_init_err; + Copy(temp_r1, lsf_r1, M); + Copy(temp_p, lsf_p, M); + // Set zerom + Copy(&past_rq_init[j*M], st->past_rq, M); + *pred_init_i = j; + } // endif + } // next j + } // endif MRDTX + + //---- Split-VQ of prediction error ---- + if (sub (mode, MR475) == 0 || sub (mode, MR515) == 0) + { // MR475, MR515 + + + indice[0] = Vq_subvec3(&lsf_r1[0], dico1_lsf, &wf1[0], DICO1_SIZE, 0); + + indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE/2, 1); + + indice[2] = Vq_subvec4(&lsf_r1[6], mr515_3_lsf, &wf1[6], MR515_3_SIZE); + + } + else if (sub (mode, MR795) == 0) + { // MR795 + + + indice[0] = Vq_subvec3(&lsf_r1[0], mr795_1_lsf, &wf1[0], MR795_1_SIZE, 0); + + indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE, 0); + + indice[2] = Vq_subvec4(&lsf_r1[6], dico3_lsf, &wf1[6], DICO3_SIZE); + + } + else + { // MR59, MR67, MR74, MR102 , MRDTX + + + indice[0] = Vq_subvec3(&lsf_r1[0], dico1_lsf, &wf1[0], DICO1_SIZE, 0); + + indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE, 0); + + indice[2] = Vq_subvec4(&lsf_r1[6], dico3_lsf, &wf1[6], DICO3_SIZE); + + } + + + // Compute quantized LSFs and update the past quantized residual + + for (i = 0; i < M; i++) + { + lsf1_q[i] = add(lsf_r1[i], lsf_p[i]); + st->past_rq[i] = lsf_r1[i]; + } + + // verification that LSFs has mimimum distance of LSF_GAP Hz + + Reorder_lsf(lsf1_q, LSF_GAP, M); + + // convert LSFs to the cosine domain + + Lsf_lsp(lsf1_q, lsp1_q, M); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void Q_plsf_3( + Q_plsfState *st, /* i/o: state struct */ + enum Mode mode, /* i : coder mode */ + Word16 *lsp1, /* i : 1st LSP vector Q15 */ + Word16 *lsp1_q, /* o : quantized 1st LSP vector Q15 */ + Word16 *indice, /* o : quantization indices of 3 vectors Q0 */ + Word16 *pred_init_i,/* o : init index for MA prediction in DTX mode */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + register Word16 i, j; + Word16 lsf1[M]; + Word16 wf1[M]; + Word16 lsf_p[M]; + Word16 lsf_r1[M]; + Word16 lsf1_q[M]; + + Word32 L_pred_init_err; + Word32 L_min_pred_init_err; + Word32 L_temp; + Word16 temp_r1[M]; + Word16 temp_p[M]; + Word16 temp; + + /* convert LSFs to normalize frequency domain 0..16384 */ + + Lsp_lsf( + lsp1, + lsf1, + M, + pOverflow); + + /* compute LSF weighting factors (Q13) */ + + Lsf_wt( + lsf1, + wf1, + pOverflow); + + /* Compute predicted LSF and prediction error */ + if (mode != MRDTX) + { + for (i = 0; i < M; i++) + { + temp = (Word16)((((Word32) st->past_rq[i]) * + (*(pred_fac_3 + i))) >> 15); + + *(lsf_p + i) = *(mean_lsf_3 + i) + temp; + + *(lsf_r1 + i) = *(lsf1 + i) - *(lsf_p + i); + } + } + else + { + /* DTX mode, search the init vector that yields */ + /* lowest prediction resuidual energy */ + *pred_init_i = 0; + L_min_pred_init_err = 0x7fffffff; /* 2^31 - 1 */ + + for (j = 0; j < PAST_RQ_INIT_SIZE; j++) + { + L_pred_init_err = 0; + for (i = 0; i < M; i++) + { + *(temp_p + i) = *(mean_lsf_3 + i) + *(past_rq_init + j * M + i); + + *(temp_r1 + i) = *(lsf1 + i) - *(temp_p + i); + + L_temp = ((Word32) * (temp_r1 + i)) * *(temp_r1 + i); + + L_pred_init_err = L_pred_init_err + (L_temp << 1); + + } /* next i */ + + + if (L_pred_init_err < L_min_pred_init_err) + { + L_min_pred_init_err = L_pred_init_err; + + oscl_memcpy( + lsf_r1, + temp_r1, + M*sizeof(Word16)); + + oscl_memcpy( + lsf_p, + temp_p, + M*sizeof(Word16)); + + /* Set zerom */ + oscl_memcpy( + st->past_rq, + &past_rq_init[j*M], + M*sizeof(Word16)); + + *pred_init_i = j; + + } /* endif */ + } /* next j */ + } /* endif MRDTX */ + + /*---- Split-VQ of prediction error ----*/ + if ((mode == MR475) || (mode == MR515)) + { /* MR475, MR515 */ + + *indice = + Vq_subvec3( + lsf_r1, + dico1_lsf_3, + wf1, + DICO1_SIZE, + 0, + pOverflow); + + *(indice + 1) = + Vq_subvec3( + lsf_r1 + 3, + dico2_lsf_3, + wf1 + 3, + DICO2_SIZE / 2, + 1, + pOverflow); + + *(indice + 2) = + Vq_subvec4( + lsf_r1 + 6, + mr515_3_lsf, + wf1 + 6, + MR515_3_SIZE, + pOverflow); + + } + else if (mode == MR795) + { /* MR795 */ + + *indice = + Vq_subvec3( + lsf_r1, + mr795_1_lsf, + wf1, + MR795_1_SIZE, + 0, + pOverflow); + + *(indice + 1) = + Vq_subvec3( + lsf_r1 + 3, + dico2_lsf_3, + wf1 + 3, + DICO2_SIZE, + 0, + pOverflow); + + *(indice + 2) = + Vq_subvec4( + lsf_r1 + 6, + dico3_lsf_3, + wf1 + 6, + DICO3_SIZE, + pOverflow); + + } + else + { /* MR59, MR67, MR74, MR102 , MRDTX */ + + *indice = + Vq_subvec3( + lsf_r1, + dico1_lsf_3, + wf1, + DICO1_SIZE, + 0, + pOverflow); + + *(indice + 1) = + Vq_subvec3( + lsf_r1 + 3, + dico2_lsf_3, + wf1 + 3, + DICO2_SIZE, + 0, + pOverflow); + + *(indice + 2) = + Vq_subvec4( + lsf_r1 + 6, + dico3_lsf_3, + wf1 + 6, + DICO3_SIZE, + pOverflow); + + } + + + /* Compute quantized LSFs and update the past quantized residual */ + + for (i = 0; i < M; i++) + { + *(lsf1_q + i) = *(lsf_r1 + i) + *(lsf_p + i); + st->past_rq[i] = *(lsf_r1 + i); + } + + /* verification that LSFs has mimimum distance of LSF_GAP Hz */ + + Reorder_lsf( + lsf1_q, + LSF_GAP, + M, + pOverflow); + + /* convert LSFs to the cosine domain */ + + Lsf_lsp( + lsf1_q, + lsp1_q, + M, + pOverflow); + + return; + +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf_3_tbl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf_3_tbl.cpp new file mode 100644 index 00000000..8714fcdb --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf_3_tbl.cpp @@ -0,0 +1,2083 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: q_plsf_3_tbl.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "q_plsf_3_tbl.h" + +/*--------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : q_plsf_3.tab +* Purpose : Table for routine LSF VQ. +* $Id $ +* +******************************************************************************** +*/ + + +/* initalization table for MA predictor in dtx mode */ +const Word16 past_rq_init[80] = +{ + -258, -318, -439, -634, -656, -773, -711, -502, -268, -193, + -2, 125, 122, -39, -9, 105, 129, 283, 372, 575, + -277, -324, -197, -487, -445, -362, -292, -27, 177, 543, + 342, 517, 516, 130, 27, -104, -120, -140, -74, -56, + -564, -943, -1520, -965, -814, -526, -322, -2, 159, 657, + -312, -284, -386, -597, -493, -526, -418, -229, 105, 449, + -557, -870, -1075, -919, -950, -752, -709, -316, 62, 486, + -314, -191, -203, -330, -160, -103, -51, 131, 338, 515 +}; + + +const Word16 mean_lsf_3[10] = +{ + 1546, + 2272, + 3778, + 5488, + 6972, + 8382, + 10047, + 11229, + 12766, + 13714 +}; + + +const Word16 pred_fac_3[10] = +{ + 9556, + 10769, + 12571, + 13292, + 14381, + 11651, + 10588, + 9767, + 8593, + 6484 +}; + + + +/* first codebook from IS641 */ + +const Word16 dico1_lsf_3[DICO1_SIZE*3] = +{ + 6, 82, -131, + 154, -56, -735, + 183, -65, -265, + 9, -210, -361, + 113, 718, 1817, + 1010, 1214, 1573, + 857, 1333, 2276, + 827, 1568, 1933, + 717, 1989, 2206, + 838, 1172, 1823, + 721, 1000, 2154, + 286, 476, 1509, + -247, -531, 230, + 147, -82, 569, + 26, -177, -944, + -27, -273, 692, + -164, -264, -183, + 224, 790, 1039, + 899, 946, 601, + 485, 771, 1150, + 524, 677, 903, + -140, 375, 778, + 410, 676, 429, + 301, 530, 1009, + 719, 646, 38, + 226, 367, 40, + 145, -45, -505, + 290, 121, -121, + 302, 127, 166, + -124, -383, -956, + -358, -455, -977, + 715, 878, 894, + 978, 923, 211, + 477, 272, 64, + 188, -78, 17, + -143, -65, 38, + 643, 586, 621, + -134, -426, -651, + 347, 545, 2820, + 1188, 2726, 2442, + 142, -80, 1735, + 283, 130, 461, + -262, -399, -1145, + -411, 155, 430, + 329, 375, 779, + 53, -226, -139, + -129, -236, 1682, + 285, 744, 1327, + 738, 697, 1664, + 312, 409, 266, + 325, 720, 135, + 1, 221, 453, + 8, 203, 145, + 299, 640, 760, + 29, 468, 638, + 103, 429, 379, + 420, 954, 932, + 1326, 1210, 1258, + 704, 1012, 1152, + -166, -444, -266, + -316, -130, -376, + 191, 1151, 1904, + -240, -543, -1260, + -112, 268, 1207, + 70, 1062, 1583, + 278, 1360, 1574, + -258, -272, -768, + 19, 563, 2240, + -3, -265, 135, + -295, -591, -388, + 140, 354, -206, + -260, -504, -795, + -433, -718, -1319, + 109, 331, 962, + -429, -87, 652, + -296, 426, 1019, + -239, 775, 851, + 489, 1334, 1073, + -334, -332, 25, + 543, 1206, 1807, + 326, 61, 727, + 578, 849, 1405, + -208, -277, 329, + -152, 64, 669, + -434, -678, -727, + -454, -71, 251, + 605, 480, 254, + -482, 11, 996, + -289, 395, 486, + 722, 1049, 1440, + -30, -316, -786, + -106, -115, -619, + 861, 1474, 1412, + 1055, 1366, 1184, + 812, 1237, 925, + 42, -251, -576, + 342, 141, -454, + -168, -80, 1359, + -342, -656, -1763, + 100, 821, 725, + 990, 747, 800, + 332, 440, 568, + 663, 379, 852, + 112, 165, -369, + 597, 910, 282, + -8, 834, 1281, + -352, 572, 695, + 462, 2246, 1806, + 345, 190, 1374, + 416, 915, 2166, + 168, -82, 280, + -516, -446, 840, + 47, 533, 44, + -362, -711, -1143, + 22, 193, 1472, + -85, 233, 1813, + -62, 579, 1504, + 550, 944, 1749, + 723, 650, 1148, + 972, 884, 1395, + -425, 643, 0, + 1000, 952, 1098, + 249, 1446, 672, + -334, -87, 2172, + -554, 1882, 2672, + 140, 1826, 1853, + 920, 1749, 2590, + 1076, 1933, 2038, + -137, -443, -1555, + 1269, 1174, 468, + -493, -122, 1521, + -451, 1033, 1214, + 482, 1695, 1118, + 815, 649, 384, + -446, -692, 107, + -319, -605, -118, + -207, -505, 525, + -468, -12, 2736, + 75, 1934, 1305, + 880, 2358, 2267, + 1285, 1575, 2004, + -48, -304, -1186, + -435, -461, -251, + -366, -404, -547, + -289, -605, -597, + -538, -810, -165, + -120, 3, 356, + 639, 1241, 1502, + 96, 177, 750, + -435, -585, -1174, + -356, 109, -79, + -485, 288, 2005, + 9, 1116, 731, + 880, 2134, 946, + -265, 1585, 1065, + 1157, 1210, 843, + -498, -668, 431, + 374, 321, -229, + 1440, 2101, 1381, + 449, 461, 1155, + -105, 39, -384, + -263, 367, 182, + -371, -660, 773, + -188, 1151, 971, + 1333, 1632, 1435, + 774, 1267, 1221, + -482, -832, -1489, + -237, -210, 860, + 890, 1615, 1064, + 472, 1062, 1192, + 185, 1077, 989, + -568, -992, -1704, + -449, -902, -2043, + -142, -377, -458, + -210, -554, -1029, + -11, 1133, 2265, + -329, -675, -893, + -250, 657, 1187, + 519, 1510, 1779, + 520, 539, 1403, + 527, 1421, 1302, + -563, -871, -1248, + -147, -463, 879, + -76, 2334, 2840, + 563, 2573, 2385, + 632, 1926, 2920, + 719, 2023, 1840, + -545, -723, 1108, + 129, -125, 884, + 1417, 1632, 925, + -94, 1566, 1751, + -341, 1533, 1551, + 591, 395, -274, + -76, 981, 2831, + 153, 2985, 1844, + 1032, 2565, 2749, + 1508, 2832, 1879, + 791, 1199, 538, + -190, -453, 1489, + -278, -548, 1158, + -245, 1941, 2044, + 1024, 1560, 1650, + 512, 253, 466, + -62, -323, 1151, + -473, -376, 507, + -433, 1380, 2162, + 899, 1943, 1445, + 134, 704, 440, + 460, 525, -28, + -450, 279, 1338, + 0, 971, 252, + -445, -627, -991, + -348, -602, -1424, + 398, 712, 1656, + -107, 314, -178, + 93, 2226, 2238, + 518, 849, 656, + -462, -711, -447, + 174, -34, 1191, + -119, 42, 1005, + -372, 274, 758, + 1036, 2352, 1838, + 675, 1724, 1498, + 430, 1286, 2133, + -129, -439, 0, + -373, 800, 2144, + 6, 1587, 2478, + 478, 596, 2128, + -428, -736, 1505, + 385, 178, 980, + 139, 449, 1225, + -526, -842, -982, + 145, 1554, 1242, + 623, 1448, 656, + 349, 1016, 1482, + 31, -280, 415, + -316, 724, 1641, + 360, 1058, 556, + -436, -358, 1201, + -355, 1123, 1939, + 401, 1584, 2248, + -527, -1012, 355, + 233, 238, 2233, + -550, -897, -639, + -365, -501, 1957, + 389, 1860, 1621, + 162, 1132, 1264, + -237, 1174, 1390, + -640, -411, 116, + -228, 1694, 2298, + 1639, 2186, 2267, + 562, 1273, 2658, + 323, 338, 1774, + 578, 1107, 852, + 22, 594, 934, + -143, 718, 446 +}; + + +/* second codebook from IS641 */ + +const Word16 dico2_lsf_3[DICO2_SIZE*3] = +{ + 50, 71, -9, + -338, -698, -1407, + 102, -138, -820, + -310, -469, -1147, + 414, 67, -267, + 1060, 814, 1441, + 1548, 1360, 1272, + 1754, 1895, 1661, + 2019, 2133, 1820, + 1808, 2318, 1845, + 644, -93, 454, + 858, 329, -136, + 489, -258, -128, + -198, -745, -41, + -52, -265, -985, + 346, 137, 479, + -1741, -748, -684, + -1163, -1725, -367, + -895, -1145, -784, + -488, -946, -968, + -85, -390, -725, + 215, -340, -171, + 1020, 916, 1969, + 564, 179, 746, + 662, 977, 1734, + 887, 622, 914, + 939, 856, 1165, + 309, 688, 803, + 917, 161, 570, + 118, -20, -283, + -816, -42, 204, + -1228, -325, -462, + -963, -202, -143, + -988, -484, -361, + -702, -978, -477, + -302, -790, -1188, + -100, -786, -1088, + -1054, -947, -1684, + -202, -843, -782, + -1039, -1378, -901, + -624, -110, -85, + 356, 213, -10, + -493, 364, 774, + 425, 822, 479, + -83, 557, 520, + -992, -1560, -572, + -603, -741, -26, + -502, -638, -903, + 209, 306, 147, + -316, -593, -596, + -85, -211, -225, + -918, -529, 117, + 233, -439, -738, + 1101, 751, 633, + 1457, 1716, 1511, + 1765, 1457, 910, + 1122, 1156, 849, + 1354, 868, 470, + -871, -1150, -1796, + -871, -861, -992, + -118, 155, 212, + -1051, -849, -606, + -1117, -1849, -2750, + -1019, -1427, -1869, + 370, -184, -414, + 959, 493, 104, + 958, 1039, 543, + 154, 653, 201, + 1249, 507, 150, + 663, 503, 230, + 623, 777, 675, + 659, 88, -110, + 843, 244, 224, + 382, 541, 302, + 724, 433, 666, + 1166, 734, 341, + -138, 20, -397, + -1183, -424, -46, + -321, -352, -124, + 1333, 1021, 1080, + 262, 366, 723, + 922, 283, -551, + 31, -636, -611, + -689, -697, -415, + -952, -779, -201, + -1329, -598, -359, + -953, -1285, 166, + 493, 305, 221, + 846, 703, 610, + 840, 936, 774, + -723, -1324, -1261, + -357, -1025, -1388, + -1096, -1376, -365, + -1416, -1881, -608, + -1798, -1727, -674, + -545, -1173, -703, + 678, 786, 148, + -123, 696, 1288, + 644, 350, -10, + 414, 614, 15, + 137, 344, -211, + -814, -1512, -819, + -391, -930, -588, + 47, -591, -898, + -909, -1097, -163, + -1272, -1167, -157, + -1464, -1525, -389, + -1274, -1188, -624, + 671, 213, 454, + 124, -274, -525, + -729, -496, -152, + -1344, 122, 135, + -2905, -589, -394, + -1728, 441, -50, + 1476, 904, 787, + 316, 236, -440, + -347, 217, 413, + -911, -917, 121, + -455, -932, 202, + -92, -465, -375, + 488, 390, 474, + 876, 729, 316, + -1815, -1312, -669, + 87, 962, 432, + 563, -249, -1058, + 250, 285, 1105, + 1141, 427, 696, + -1038, -1664, -1582, + -948, 346, 160, + -309, -272, -858, + 670, 624, 1250, + -944, -408, -666, + -606, -320, -384, + -492, 230, 65, + 334, -50, -16, + -16, -690, -1397, + 1791, 1716, 1399, + 2478, 2063, 1404, + 1245, 1471, 1426, + -382, -1037, -2, + 173, -398, 1145, + 1491, 2024, 1801, + 772, 1274, 1506, + 1429, 1735, 2001, + 1079, 1218, 1273, + -1154, -1851, -1329, + -808, -1133, -1096, + -451, -1033, -1722, + 65, 578, -84, + -1476, -2434, -1778, + -765, -1366, -494, + -218, -594, -931, + 337, -236, 562, + 2357, 2662, 1938, + 1489, 1276, 874, + 189, 358, 374, + -1519, -2281, -2346, + -967, -1271, -2095, + -628, -1188, -1542, + 1661, 1043, 546, + 565, 1061, 732, + -64, -836, -434, + -436, -96, 203, + 1078, 1216, 1636, + 907, 1534, 986, + 326, 965, 845, + 142, -84, 197, + 470, 2379, 1570, + 1133, 470, 1214, + 395, 1376, 1200, + 1125, 1042, 348, + -543, -1234, -376, + -215, -181, 481, + -1947, -1621, -210, + -750, -1185, 390, + 29, -399, 27, + 820, 1236, 755, + 695, 979, 409, + -174, 1197, 1035, + 912, 1356, 1846, + -992, -1437, 484, + -1485, -1700, 208, + -412, 1204, 1432, + -271, 896, 1144, + -416, 1777, 1434, + -1696, -2644, -204, + -1789, -1551, 1033, + -1656, -1559, 1303, + -1253, -1589, 1081, + -669, -1095, -66, + -682, 320, -345, + 659, 305, 1069, + -1292, -804, -19, + -1635, -1291, 29, + -1683, -497, 71, + -287, -7, -100, + -494, -962, -237, + 852, 1881, 1740, + -1217, -1387, 227, + -660, 302, 373, + 96, 1087, 1257, + -1074, -1669, 160, + 485, 2076, 1798, + -934, -220, 552, + -596, -612, 237, + 336, 1720, 879, + 643, 629, 434, + 1267, 522, 1633, + 15, 244, -441, + 1475, 717, 184, + 1819, 1590, 1709, + 988, 261, 937, + 2093, 2345, 1520, + 2139, 1858, 1606, + -577, -579, -1203, + -956, 135, -488, + -464, 51, -338, + -629, -348, -723, + 1146, 2073, 1442, + 2192, 1466, 911, + -1444, -1572, -2278, + 1400, 710, 1297, + 1335, 633, 928, + 1434, 2194, 2594, + 2422, 2204, 1881, + 982, 2242, 1854, + 380, 792, 1145, + -63, -539, 414, + -252, -964, -314, + -1261, -683, -780, + -831, -526, -1005, + -1666, -1135, -424, + -1611, -452, -299, + 1268, 1048, 642, + 1147, 853, 856, + -675, -336, 139, + 2268, 1343, 1418, + 29, 768, 797, + -1224, 423, 564, + -1318, -1082, 245, + -1302, -812, 573, + -1298, -1617, 646, + -968, 834, 723, + 993, 1652, 2027, + -191, -817, 432, + 662, 60, 198, + 626, 997, 1330, + 1648, 1963, 1289, + -1597, -93, -45, + -1088, 37, -84, + 1653, 2607, 2337, + 1065, 2040, 2377, + 1139, 2326, 2118, + 859, 357, 1510, + 664, 1227, 1099, + 479, 1360, 912, + 1897, 1754, 2019, + 1168, 1909, 1784, + 399, 34, 256, + -593, -304, -1053, + 547, 1694, 1407, + 647, -99, -341, + 1492, 1647, 1190, + 38, -644, -212, + 395, 846, 222, + -704, -765, -716, + -724, -1964, -2804, + -150, 291, -82, + 1233, 1459, 1007, + -140, -155, 153, + 439, 297, 1568, + -1529, -410, -636, + 1536, 455, -237, + -1328, -139, -260, + 531, 554, 868, + 269, 1264, 606, + -233, 883, 463, + 742, 600, -120, + -73, 421, 212, + -439, -58, 804, + -1286, -1241, 728, + 294, -490, 50, + -591, -905, -1254, + 42, -687, 147, + -25, 273, 596, + -311, 1213, 601, + -754, 849, 584, + 429, 607, 587, + -602, -166, 461, + -796, -823, 777, + 1380, 910, 1755, + 119, 1417, 972, + -219, -880, -1596, + -1049, -1010, 438, + -713, -1379, 78, + 0, -447, -1179, + -1136, -1319, -1573, + 2248, 1767, 1309, + 946, 1583, 1432, + 1150, 482, 436, + -469, -1108, 618, + -447, -966, 1088, + -1252, -1515, -114, + -1104, -2008, -579, + 210, 613, 497, + -1975, -1437, 642, + -1269, -856, 1011, + -1646, -1185, 1063, + -1555, -672, 1204, + -1692, -1114, 623, + -979, -1326, -1277, + 539, -147, 894, + -1354, -897, -434, + 888, 475, 428, + 153, -384, 338, + -1492, -511, 359, + -974, -1115, -470, + 105, -550, 677, + -937, -1145, 877, + 380, -260, 210, + 1685, 924, 1256, + 1775, 1190, 1095, + 1419, 631, 533, + 627, 299, -347, + -411, -534, 647, + -650, 29, -595, + -378, -1367, 1563, + 1402, 1121, 1465, + 1089, 1410, 648, + -2096, -1090, -6, + 311, -194, -869, + -639, -831, 416, + -1162, -1224, 1349, + -1247, -941, 1813, + -2193, -1987, 453, + -619, -1367, -956, + -1606, -1972, -1507, + -1175, -1057, -1104, + -377, 601, 201, + 1876, 825, 374, + -430, -1323, 29, + -1397, -1249, -1331, + -1007, -1504, 960, + -1401, -2009, 197, + -1379, -1949, -236, + -1077, 123, 422, + 615, 1269, 546, + -306, 1526, 904, + 1194, 1788, 1177, + -626, -884, -1526, + 199, 766, 1504, + -1065, 862, 197, + -1034, -1773, -887, + -800, 145, 599, + -1134, -519, 626, + -1205, -1926, 500, + -910, -1041, -1395, + -1476, -1567, -969, + -523, 842, 34, + 1794, 646, 862, + -1207, -1888, -1002, + -78, -9, -672, + 1044, 759, 80, + -600, 1139, 1019, + 57, 2000, 1422, + -833, 1414, 1121, + -1202, 1630, 1260, + -461, 1420, 1244, + 1537, 975, 253, + -283, 324, -359, + 599, -195, 106, + 588, 62, -587, + -757, 645, 205, + 51, 1201, 758, + -1209, 673, -390, + -624, 1581, 941, + -151, 1023, 735, + 2820, 1301, 690, + -302, 524, -99, + -900, -1588, -1189, + 1084, 251, 238, + 2014, 1792, 1010, + 1245, 1633, 1741, + -1227, -1540, -1208, + -621, 456, -109, + 40, -65, 788, + -805, -699, -1350, + -583, 904, 832, + -801, 532, 594, + 1972, 1408, 1351, + -1177, -1880, -2114, + -773, 568, 948, + -1015, 1079, 1260, + -1111, 482, -130, + 1778, 1044, 780, + -1491, 245, 912, + -316, -1141, -917, + -536, -1442, -2346, + -785, -1546, -1988, + -2003, 257, 909, + -1849, -633, -1209, + -1538, -1918, -1054, + 1606, 2239, 1576, + -567, -1500, -1544, + -1279, 195, 1369, + -817, 293, 1219, + -525, 630, 1197, + -1698, -2425, -1840, + -303, 731, 747, + -1169, -251, 269, + -950, -75, 1684, + -1182, -453, 1005, + -1599, 585, 378, + -2075, -571, -427, + -529, -1159, -1171, + -283, -205, -564, + -796, 1246, 717, + 2277, 927, 539, + -454, 559, 440, + -717, 1460, 1615, + -1030, 1052, 1610, + -1169, -138, 847, + 226, 39, -612, + -1251, -106, -729, + -651, 968, 1302, + -714, -636, 1727, + 353, 1069, 410, + -798, -156, 1099, + -574, 918, 446, + -1310, 1012, 466, + 1408, 1591, 765, + 1429, 1380, 1757, + 1949, 1956, 2378, + 1578, 2047, 2148, + 916, 98, -7, + 1893, 1418, 2141, + 348, 1405, 1579, + 152, 1134, 1801, + -267, 154, 1395, + -1166, 469, 1054, + -1142, -405, -1073, + -1341, -2264, -1581, + -364, 869, 1706, + -1162, 549, 1550, + -1225, -1932, -1666, + -1485, -1977, -2055, + -1727, -906, -98, + -1897, 233, 1492, + 892, 108, -331, + -1728, -1170, -1700, + -1060, 1980, 1790, + -1070, -1741, -1909, + -11, 1539, 1317, + -1600, 94, 497, + 421, 443, -197, + -1578, -349, -994, + -599, -539, 1140, + -965, -1419, -129, + -1341, 175, -447, + -375, 1311, 2055, + -371, -650, -307, + -1073, 605, 365, + -2057, -113, 430, + 652, 914, 967, + -1012, -1586, -2323, + 1505, 1248, 559, + 262, -486, -401, + -1727, 1342, 1546, + 50, 56, 432, + -330, 119, -604, + -1517, -1080, -810, + 946, 1127, 1055, + -1400, -1703, -1712, + -1270, -704, -1317, + 807, 1821, 1143, + 2760, 1606, 2171, + 1120, 409, -150, + -147, 404, 959, + 2439, 1911, 2189, + -906, -141, -866, + -904, -142, -458, + -557, -708, -1679, + -830, -1431, -1583, + -1842, -1346, -1086, + -1604, -272, 915, + -1196, 772, 1056, + -638, -1234, -1897, + -500, -81, -822, + -1289, -1613, -735, + -117, 785, 168, + -1090, 1133, 922, + -1096, -746, 1384, + 287, -547, -1063, + -1376, -2201, -1204, + -2176, -1570, -1757, + -1511, -2241, -771, + -1737, 1099, 830, + -1588, 724, 1243, + -1542, 693, 805, + -1690, -240, 1665, + -1700, -4, -668, + 2149, 816, 1042, + -818, -1841, 22, + -764, -507, 449, + -1151, -617, 289, + -843, -1596, -240, + 498, -234, -657, + -752, 480, 1678, + -319, -481, 193, + -811, 171, -119, + -2128, -202, -848, + 1717, 1140, 1700 +}; + + +/* third codebook from IS641 */ + +const Word16 dico3_lsf_3[DICO3_SIZE*4] = +{ + 67, -17, 66, -12, + -1690, -581, -104, -272, + -1076, -1186, -1845, -376, + -1140, -926, -420, -58, + -259, -656, -1134, -553, + 1788, 1227, 455, 129, + 462, 441, -240, -528, + 840, 514, 130, -75, + 1114, 623, 153, 216, + 1068, 564, -6, -276, + 1119, 727, 190, -68, + 704, 306, 119, -264, + 329, 61, -100, 156, + 364, 123, 183, -208, + -171, -123, 220, -65, + -306, -62, 402, 17, + -660, -938, -266, 0, + 385, 235, 276, 285, + 320, 268, -336, -200, + -724, 17, -84, 381, + -544, 429, 494, 519, + -117, 288, 304, 329, + 643, 157, 701, 508, + 1200, 625, 796, 608, + 998, 421, 492, 632, + 1204, 780, 446, 132, + 1257, 844, 547, 449, + 829, 658, 541, 470, + 1132, 1258, 918, 639, + 547, 51, 423, 279, + 9, 392, 83, 94, + 542, 543, 229, -147, + -198, 129, 194, -185, + -863, -1321, -302, 30, + -597, -629, -19, 114, + -900, -1081, 466, 353, + -1483, -1573, 15, -143, + -1708, -2059, -751, 196, + -1876, -2067, -642, -258, + -2335, -1470, -450, -564, + -584, -186, -872, -414, + -1805, -988, -1125, -1310, + -726, -1129, 28, 169, + -1039, -864, -718, -246, + 484, 36, -233, -49, + 265, 67, 289, 467, + 178, 543, 810, 540, + 84, 282, 672, 703, + -975, -777, 129, 287, + -938, -227, 955, 595, + -1617, -289, 836, 649, + -1847, -215, 1106, 718, + -2034, -1085, 650, 440, + -2101, -529, 907, 575, + -2011, -336, 670, 204, + -2389, -692, 360, 137, + -2156, -2204, -9, 280, + -266, 119, 39, 193, + 78, -59, -120, 226, + -975, -858, -781, -1095, + -619, -413, -451, -842, + -1216, -1321, -813, -883, + -1376, -1615, -394, -428, + -737, -1113, -549, -790, + -880, -975, -967, -642, + -985, -886, -1273, -1361, + -473, -804, -1401, -1407, + 160, -265, -919, -275, + -248, -250, -718, -380, + 97, -103, -375, -229, + -415, -193, -135, -555, + 628, 361, 119, 216, + 579, 364, 391, 209, + 634, 522, -154, -148, + 526, 389, 170, 33, + 105, 267, 64, 380, + -1503, -1000, -30, -369, + -1070, 58, 647, 223, + -1520, -291, 621, 307, + -1531, 156, 762, 404, + -2029, 141, 734, 499, + -1849, -650, 306, 512, + -187, -104, -59, 438, + 134, -230, 156, -186, + -61, -260, -16, 10, + -569, -3, -421, -297, + -1725, -521, -346, 178, + -1362, -59, -44, 157, + -2146, -461, -470, -349, + -2170, -1, -369, -121, + -1579, -373, -900, -1015, + -1117, -591, -613, -784, + -561, 122, -75, -449, + -4, -171, -123, -372, + 192, 168, -76, -132, + 252, -107, 340, 210, + 392, 509, 272, 181, + -109, 145, 218, 119, + -416, -263, 485, 265, + -181, -8, -286, 226, + -244, -218, 69, -290, + -158, 191, -1, -64, + -592, -90, 213, -96, + 255, 435, 178, -80, + -369, -18, -33, -80, + -42, 415, 140, -222, + 1143, 651, 649, 329, + 767, 556, 249, 235, + 948, 413, 442, 279, + 141, 339, 356, 557, + -470, -170, 99, 237, + -569, -800, 352, 565, + 282, 473, 470, 332, + -199, -690, -1284, -917, + -193, -426, -800, -1122, + -26, -371, -490, -193, + 637, 595, 519, 330, + 408, -115, 79, 12, + 477, 87, -103, -376, + -666, -347, -277, -291, + -510, -481, 169, 297, + -829, -738, -205, -171, + -320, -540, 328, 283, + -859, -958, 442, -2, + 556, 686, 130, 56, + 1383, 1012, 755, 427, + 612, 741, 628, 553, + -339, -796, 134, 277, + -633, -1085, -2, -246, + -880, -1035, -1607, -1064, + -994, -474, -1138, -488, + -414, -795, 73, -206, + -8, -139, 439, 204, + -176, -578, 23, 131, + -269, -757, -191, 245, + -109, -338, 112, 316, + 120, -406, -118, 611, + -180, -186, -645, 115, + -173, 34, -518, -489, + -151, 61, -583, -844, + 220, -138, -681, -1020, + 391, -17, -598, -321, + 157, -295, 129, 155, + -926, -875, -987, 285, + 241, -83, -125, -125, + 620, 597, 432, 92, + 393, 78, 409, 61, + -393, -739, -413, -748, + 83, 54, 361, 27, + -1084, 130, -337, -694, + -1565, 297, 318, -19, + -1873, 36, 51, -317, + -2323, -246, 231, -84, + -2306, -783, 40, -179, + -2233, -930, -474, -462, + -754, -86, -288, -626, + -2411, -455, -63, 171, + -1099, -1094, -26, -143, + -1193, -455, -406, -381, + -605, -210, -96, -51, + -580, -476, -276, -15, + -1195, -634, -1203, -881, + -378, -221, -669, -952, + 594, 178, -403, -676, + 763, 327, 601, 290, + 172, 300, 203, 157, + -56, -336, 356, 24, + -228, -296, -259, -29, + -186, 263, 416, 14, + -353, 373, -12, -216, + 257, 96, 174, 57, + -1526, -616, -954, -499, + -497, -152, -333, 125, + 105, 200, 179, -97, + -331, -224, 765, 697, + 760, 256, 301, 59, + 455, -85, 204, 288, + -514, 240, 251, -109, + 256, 417, -34, -413, + 101, 430, 384, 156, + -31, -10, 206, 426, + 589, 145, 143, 71, + 808, 906, 333, 349, + 986, 938, 589, 331, + 1300, 824, 187, 509, + 1062, 653, 379, 466, + 1462, 937, 401, 274, + 787, 861, 265, 2, + 609, 553, 28, 305, + 926, 340, 106, 386, + 241, -267, -147, 225, + -178, -534, 347, 502, + -643, -381, 397, 30, + -651, -733, -435, 398, + -407, -726, -484, -248, + -789, -914, -438, -476, + -498, -390, 75, -295, + -964, -590, -606, 150, + -121, -49, -155, -78, + 935, 550, 389, 38, + -321, 127, 424, 315, + -285, -113, 283, 259, + 658, 203, 322, 486, + 903, 505, 748, 417, + 611, 423, 555, 512, + 239, -83, -578, -19, + -339, -731, 349, 13, + -934, -1399, -114, -360, + 107, 692, 182, 90, + -1243, -1538, -1551, -725, + -568, -903, -1363, -525, + -517, -853, -861, -1004, + -168, -690, -835, 63, + -137, -556, -547, 144, + -286, -817, 485, 319, + -147, -408, 526, 246, + -347, -434, 297, -28, + -290, -471, -1110, -1285, + -460, -359, -988, -794, + 1347, 1299, 690, 523, + 1216, 1068, 1094, 757, + 825, 1140, 752, 494, + 1252, 1365, 1195, 898, + 521, 1053, 532, 432, + -334, -216, -313, -263, + -160, 52, -472, -155, + 127, 136, -380, 44, + 851, 410, -162, -489, + 123, -255, -796, -667, + 1090, 917, 789, 493, + 1397, 1197, 558, 202, + -51, -118, -342, -701, + 83, 108, -42, -441, + 61, 95, 287, 256, + -27, 89, 524, 531, + 351, 227, 592, 545, + 697, 155, -164, 307, + 638, 274, -489, -50, + 754, 240, -166, -124, + -116, -579, -1212, -63, + 190, -295, -1040, -1296, + 147, -376, -177, -113, + 841, 1241, 1051, 668, + 2, 293, 551, 304, + -1096, -953, -248, 376, + -750, -965, 87, 516, + -275, -516, 689, 391, + -379, -643, 876, 594, + -390, -1013, -645, 573, + -107, -568, -689, -826, + -1025, -27, -328, -203, + 861, 749, 548, 233, + -1660, -1043, 451, 108, + -660, -620, 430, 236, + 21, -396, -1158, -631, + 1372, 1298, 967, 577, + 1125, 1125, 589, 454, + -323, -865, -467, 153, + -468, -699, -804, -509, + -392, -718, -204, -35, + -603, -1093, -567, -162, + -505, -1004, -102, 350, + 219, 224, 423, 252, + 395, 591, 608, 363, + -746, -96, 373, 172, + 171, 295, 714, 339, + 233, 77, 107, 277, + 157, 153, -499, -356, + 1547, 1073, 576, 494, + -292, -339, -504, -592, + -903, -72, -619, -481, + -1594, -1117, -567, -254, + -793, -507, -564, -291, + -492, -532, 502, 560, + -382, 427, 600, 230, + -227, 477, 251, 75, + 285, 842, 813, 476, + -1310, -1333, 186, 377, + -587, -917, 643, 381, + -1186, -553, 411, 82, + -1127, -820, -174, -540, + -604, 119, 543, 205, + -380, 657, 909, 567, + 112, -298, -374, 114, + -857, -251, 56, 159, + 401, 345, -34, -140, + -111, -607, 41, 614, + 355, -114, -77, 474, + 578, 56, 1450, 924, + 1098, 1420, 741, 400, + 246, 22, 588, 313, + -121, 327, 831, 472, + -1138, -608, 856, 552, + -1241, -1072, 638, 600, + -358, 254, -333, -303, + -646, 739, 358, 74, + 1226, 1671, 1221, 849, + 2241, 1624, 983, 636, + 1841, 1477, 749, 384, + 350, 263, 87, 128, + -1902, -941, -144, -64, + -1734, -255, 288, -31, + -2644, -1238, 366, 235, + -1643, -1092, -1344, -304, + -541, -1075, -1116, 123, + -1178, -252, -816, -180, + -1016, 533, 565, 233, + -487, -430, -188, 334, + 867, 1236, 534, 171, + -1590, -1607, 635, 630, + -2196, 310, 924, 412, + -2358, -328, 956, 529, + -2639, -377, 630, 278, + -2602, 317, 799, 299, + -2406, 133, 340, 31, + -2156, -1468, 131, 125, + -1184, -490, -139, 46, + -744, 447, 891, 564, + 67, -451, 646, 604, + -553, -429, -876, 396, + 162, -66, 1305, 915, + 479, 579, 1088, 794, + 450, 278, 566, 324, + -1057, -154, 148, -177, + -2545, 168, 1070, 592, + -2351, -42, 819, 345, + -2344, -707, 721, 250, + -2175, -1497, -309, 122, + -78, -73, 120, 173, + -4, 262, -263, -261, + -431, -64, -405, -732, + -2609, 116, -83, -193, + -1525, -944, -477, -725, + -508, 307, 170, 172, + 832, 417, 832, 686, + -225, 177, 894, 818, + -482, -389, 1279, 1039, + -383, 201, -350, 40, + 730, 635, 226, 526, + 503, 462, 338, 398, + 535, 714, 40, -282, + 1482, 1471, 1085, 731, + 1561, 1072, 909, 693, + 1419, 1282, 889, 879, + 1153, 728, 1186, 840, + -226, 1130, 949, 689, + -494, -986, -1556, -128, + -568, -721, -713, -26, + 317, 524, 70, 135, + -405, -865, -1766, -652, + -174, -801, 885, 773, + -153, -91, 1099, 751, + -506, -1149, 853, 646, + 241, 782, 519, 539, + 1853, 1700, 1101, 684, + -1249, -1486, -464, 188, + -893, -1409, -1312, -341, + -135, 438, -175, 18, + 1111, 976, 319, 208, + -1430, -1768, 83, 458, + -530, -1000, 307, 129, + -840, -15, -29, -356, + -911, -924, -1147, -242, + -119, -528, 127, -133, + -761, -765, 190, -83, + -315, 895, 522, 231, + -222, 102, -63, -428, + 316, 699, 379, 70, + 25, 716, 314, -108, + 507, 874, 566, 238, + 108, 941, 519, 195, + 425, -60, -427, 257, + 139, -103, -630, 446, + 334, 370, 412, 48, + -172, -690, -283, 557, + 187, -286, 158, 483, + 140, 270, -344, -631, + 924, 579, -116, 132, + 142, 466, -68, -64, + 230, -145, -302, -542, + -803, -912, 1018, 737, + -773, 1015, 630, 297, + -2596, 95, 445, 336, + -2122, 491, 510, 191, + -1253, 161, -2, -324, + -1450, -633, -712, -105, + -842, -254, -411, 100, + -640, -290, 1010, 763, + -650, 313, 1169, 730, + 140, 505, 1030, 766, + 772, 287, 1067, 823, + 495, 749, 305, 323, + -164, 462, 78, 399, + -342, -874, 69, 597, + -16, 620, 621, 337, + -138, -444, -265, 218, + 84, -450, 953, 666, + -222, -803, 541, 604, + -921, -1376, 244, 116, + -841, -723, 630, 588, + 140, 663, 294, 368, + 935, 1046, 881, 759, + 1746, 1464, 916, 628, + 436, 963, 281, 1, + -119, 74, 542, 213, + 1, -567, 301, 241, + 260, 435, 222, 396, + 936, 957, 1108, 703, + 510, 506, 808, 478, + 601, 694, 960, 620, + 972, 741, 980, 600, + 834, 717, 767, 684, + 643, 972, 935, 638, + 501, 661, 720, 851, + -105, -632, -303, -117, + -429, 130, 789, 442, + -522, -188, 704, 373, + -759, 42, 814, 523, + -531, -1137, 373, 578, + -682, -1203, -455, 285, + -1163, -1577, -1098, 44, + 81, -82, 712, 363, + 477, 246, 954, 622, + 1604, 1622, 1277, 891, + 1409, 859, 924, 892, + 774, 1041, 947, 1142, + 40, -546, -75, 288, + -616, -106, -697, -26, + -169, -160, -891, -739, + -279, -384, -1029, -350, + 1781, 1308, 1046, 816, + 1580, 1533, 1472, 1178, + 1505, 1076, 1216, 899, + 890, 904, 564, 654, + 920, 692, 1021, 856, + -493, 132, 177, 505, + 71, 195, -28, 97, + 456, 351, -164, 88, + 439, 278, -40, 350, + 1395, 949, 234, -95, + -805, -472, 38, -163, + 367, -98, 489, 523, + 1025, 1178, 1212, 906, + 319, 1314, 814, 461, + -123, -543, -804, 447, + -748, -324, -897, -1127, + -737, -501, -789, -713, + 715, 777, 1239, 922, + 1949, 1939, 1368, 865, + 730, 880, 758, 388, + -871, 454, 17, -251, + -381, -810, -1583, 239, + -521, -966, -792, 259, + -890, -1358, -770, -73, + 166, 349, -212, 323, + -840, -301, 473, 435, + -679, -464, 728, 351, + -156, -199, 667, 432, + 29, -252, 415, 480, + -731, -379, 145, 559, + -528, -631, -1158, -159, + 445, 273, 123, 639, + 373, -126, 800, 568, + 84, -162, 720, 712, + -830, -536, -185, 222, + 408, 452, 501, 771, + -897, -1355, -67, 442, + -792, -1406, 566, 602, + 167, -326, 509, 330, + -95, -626, -730, -344, + 1668, 1217, 779, 455, + 1316, 828, 584, 719, + 404, -31, 1013, 789, + 89, 107, 891, 549, + 871, 1581, 917, 671, + 866, 1479, 1289, 854, + 391, 1068, 1122, 812, + 78, -562, 345, 563, + 429, -103, 417, 787, + -122, -437, 411, 788, + -913, -417, 602, 754, + -226, -16, 151, 760, + -700, 118, -104, -14, + -1128, 48, 284, 393, + -390, -419, -639, -116, + -910, 306, 316, -13, + 1207, 984, 821, 669, + -1195, -693, 140, -213, + -884, -416, -199, -558, + -616, 245, -404, -664, + 262, 56, -617, -724, + -85, -491, -320, -656, + -570, -831, -129, -528, + -1506, -63, -367, -385, + -358, -321, 4, 51, + -366, -214, 319, 511, + 146, 671, -17, -291, + -110, 464, -139, -496, + -202, 220, -312, -631, + -660, -73, -655, -820, + -662, -653, -1288, -857, + -430, -953, -959, -264, + -49, -468, -72, -381, + -350, -563, -193, -407, + 55, -408, -803, 11, + -309, 649, 188, -198, + -512, 461, -79, -458, + -1318, -263, -134, -523, + -1657, -435, -495, -765, + 57, -347, -414, 434, + -1141, -242, -664, -857, + 34, -68, -707, -338 +}; + + + +/* third codebook for MR475, MR515 */ + +const Word16 mr515_3_lsf[MR515_3_SIZE*4] = +{ + 419, 163, -30, -262, + -455, -789, -1430, -721, + 1006, 664, 269, 25, + 619, 260, 183, 96, + -968, -1358, -388, 135, + -693, 835, 456, 154, + 1105, 703, 569, 363, + 1625, 1326, 985, 748, + -220, 219, 76, -208, + -1455, -1662, 49, 149, + -964, -172, -752, -336, + 625, 209, -250, -66, + -1017, -838, -2, 317, + -2168, -1485, -138, 123, + -1876, -2099, -521, 85, + -967, -366, -695, -881, + -921, -1011, -763, -949, + -124, -256, -352, -660, + 178, 463, 354, 304, + -1744, -591, -282, 79, + -2249, 175, 867, 499, + -138, -180, -181, -21, + -2291, -1241, -460, -520, + -771, 451, -10, -308, + 271, -65, 4, 214, + -279, -435, -43, -348, + -670, 35, -65, -211, + 806, 535, 85, 297, + 57, 239, 722, 493, + 225, 661, 840, 547, + -540, -376, 14, 349, + 469, 721, 331, 162, + -544, -752, -62, -10, + 398, -88, 724, 701, + -19, -533, -94, 601, + 136, -71, -681, -747, + -166, -344, 261, -50, + 161, -52, 485, 337, + -1675, 50, 190, -93, + -2282, -231, -194, -82, + -95, -595, -154, 128, + 894, 501, 588, 457, + -345, 206, 122, 110, + -631, -227, -569, 3, + 408, 239, 397, 226, + -197, -2, 128, 491, + 1281, 904, 292, 215, + 538, 306, 259, 509, + -677, -1047, 13, 321, + -679, -588, -358, -212, + -558, 243, 646, 479, + 486, 342, 634, 532, + 107, 802, 331, 136, + -112, -398, -1031, -286, + -326, -705, 288, 272, + 1299, 1144, 1178, 860, + -423, 121, -385, -148, + -295, -302, -834, -819, + 16, -24, -201, -476, + 555, 91, -245, 294, + -38, -379, -962, -1221, + -1191, -1518, -273, -395, + -390, -1013, -645, 573, + -1843, -1030, 505, 468, + 744, 947, 609, 493, + -689, -1172, -628, -135, + -1026, 195, 411, 196, + 1582, 1147, 575, 337, + -1239, -777, -648, -142, + 595, 825, 967, 735, + -1206, -970, -81, -342, + -745, 13, -72, 375, + 454, 19, 1407, 921, + -1647, -172, 861, 562, + 928, 1537, 1063, 740, + -2472, -952, 264, 82, + -502, -965, -1334, 123, + 867, 1236, 534, 171, + -2320, -460, 780, 363, + -1190, -617, 252, -61, + -174, 34, 1011, 788, + -2333, 247, 423, 153, + -16, -355, 262, 449, + -1576, -1073, -544, -371, + -615, -305, 1051, 805, + 687, 528, 6, -182, + 935, 875, 1002, 809, + 199, 257, 126, 76, + -584, -1138, 599, 556, + -1105, -1391, -1591, -519, + -977, -1325, 108, 347, + -722, -975, 365, 101, + -145, 681, 249, -153, + 0, -334, -570, 159, + 412, 285, -336, -617, + -953, -966, 887, 689, + -1251, 84, -185, -398, + -592, 433, 1044, 653, + 85, 329, -40, 361, + -433, -705, 466, 574, + -154, 654, 592, 290, + -167, 72, 349, 175, + 674, 297, 977, 720, + 1235, 1204, 757, 488, + -400, -269, 538, 372, + -1350, -1387, -1194, -91, + 1262, 876, 775, 700, + -599, -38, -430, -722, + 1976, 1630, 991, 608, + 111, 276, -226, -96, + -947, -388, -11, -7, + -303, -531, -839, 338, + 1734, 1710, 1405, 1013, + -516, -855, -645, 210, + -688, -416, 513, 230, + -822, -637, -1146, -320, + -952, -658, -694, 183, + -114, -623, 818, 674, + -191, -204, 731, 635, + 51, 1221, 883, 576, + -954, -431, 826, 598, + -342, -755, -900, -407, + -1126, -354, -206, -512, + -547, -810, -357, -620, + 66, 515, -73, -410, + -872, -945, -1444, -1227, + 191, -17, -544, -231, + -1540, -544, -901, -886 +}; + +/* first codebook for MR795 */ + +const Word16 mr795_1_lsf[MR795_1_SIZE*3] = +{ + -890, -1550, -2541, + -819, -970, 175, + -826, -1234, -762, + -599, -22, 634, + -811, -987, -902, + -323, 203, 26, + -383, -235, -781, + -399, 1262, 906, + -932, -1399, -1380, + -624, 93, 87, + -414, -539, -691, + 37, 633, 510, + -387, -476, -1330, + 399, 66, 263, + -407, -49, -335, + -417, 1041, 1865, + -779, -1089, -1440, + -746, -858, 832, + -581, -759, -371, + -673, -506, 2088, + -560, -634, -1179, + 271, 241, 14, + -438, -244, -397, + 463, 1202, 1047, + -606, -797, -1438, + -51, -323, 481, + -224, -584, -527, + 494, 881, 682, + -433, -306, -1002, + 554, 659, 222, + 171, -160, -353, + 681, 1798, 1565, + -852, -1181, -1695, + -336, -666, 114, + -581, -756, -744, + -195, 375, 497, + -465, -804, -1098, + 154, 282, -131, + -50, -191, -719, + 323, 732, 1542, + -722, -819, -1404, + 105, -250, 185, + -178, -502, -742, + 321, 510, 1111, + -323, -567, -966, + 127, 484, 338, + -160, 52, -338, + 732, 1367, 1554, + -626, -802, -1696, + -286, -586, 676, + -695, -343, -370, + -490, 295, 1893, + -630, -574, -1014, + -80, 645, -69, + -6, -318, -364, + 782, 1450, 1038, + -313, -733, -1395, + 120, 60, 477, + -264, -585, -123, + 711, 1245, 633, + -91, -355, -1016, + 771, 758, 261, + 253, 81, -474, + 930, 2215, 1720, + -808, -1099, -1925, + -560, -782, 169, + -804, -1074, -188, + -626, -55, 1405, + -694, -716, -1194, + -660, 354, 329, + -514, -55, -543, + 366, 1033, 1182, + -658, -959, -1357, + -55, -184, 93, + -605, -286, -662, + 404, 449, 827, + -286, -350, -1263, + 628, 306, 227, + -16, 147, -623, + 186, 923, 2146, + -674, -890, -1606, + -443, -228, 339, + -369, -790, -409, + 231, 86, 1469, + -448, -581, -1061, + 594, 450, -177, + -124, -170, -447, + 671, 1159, 1404, + -476, -667, -1511, + -77, -138, 716, + -177, -372, -381, + 451, 934, 915, + -250, -432, -822, + 272, 828, 446, + 26, 19, -31, + 698, 1692, 2168, + -646, -977, -1924, + -179, -473, 268, + -379, -745, -691, + 11, 127, 1033, + -488, -917, -825, + 61, 323, 135, + 147, -145, -686, + 685, 786, 1682, + -506, -848, -1297, + 35, 90, 222, + -23, -346, -670, + 455, 591, 1287, + -203, -593, -1086, + 652, 352, 437, + 39, 63, -457, + 841, 1265, 2105, + -520, -882, -1584, + -328, -711, 1421, + -596, -342, -70, + 209, 173, 1928, + -423, -598, -921, + 421, 605, -38, + -2, -245, -127, + 896, 1969, 1135, + -379, -518, -1579, + 173, 118, 753, + -55, -381, -52, + 985, 1021, 753, + -2, -291, -891, + 753, 992, 423, + 264, 131, -196, + 895, 2274, 2543, + -635, -1088, -2499, + -529, -982, 526, + -764, -830, -548, + -436, 316, 599, + -675, -940, -746, + -57, 236, -11, + -201, -81, -798, + 16, 845, 1558, + -737, -985, -1212, + -468, 17, 290, + -279, -584, -700, + 183, 822, 705, + -265, -492, -1187, + 421, 152, 468, + -390, 166, -268, + 39, 1550, 1868, + -635, -966, -1571, + -453, -492, 910, + -284, -1027, -75, + -181, -133, 1852, + -445, -624, -1174, + 420, 367, -49, + -389, -212, -169, + 707, 1073, 1208, + -539, -710, -1449, + 83, -163, 484, + -236, -543, -355, + 338, 1175, 814, + -246, -309, -958, + 606, 760, 60, + 166, -8, -163, + -306, 1849, 2563, + -747, -1025, -1783, + -419, -446, 209, + -718, -566, -534, + -506, 693, 857, + -463, -697, -1082, + 325, 431, -206, + -15, -8, -763, + 545, 919, 1518, + -611, -783, -1313, + 256, -55, 208, + -165, -348, -662, + 321, 680, 930, + -326, -429, -951, + 484, 446, 570, + -197, 72, -73, + 909, 1455, 1741, + -563, -737, -1974, + -124, -416, 718, + -478, -404, -314, + -16, 446, 1636, + -551, -537, -750, + -58, 638, 214, + 55, -185, -271, + 1148, 1301, 1212, + -483, -671, -1264, + 117, 285, 543, + -204, -391, -111, + 513, 1538, 854, + -114, -190, -978, + 877, 595, 464, + 260, 260, -311, + 748, 2283, 2216, + -517, -945, -2171, + -326, -708, 378, + -812, -691, -232, + -560, 687, 1409, + -732, -690, -836, + -359, 645, 386, + -265, 62, -678, + 145, 1644, 1208, + -555, -988, -1233, + -78, 14, 114, + -327, -358, -489, + 392, 677, 697, + -201, -236, -1140, + 693, 449, 178, + -243, 256, -433, + 611, 1385, 2456, + -612, -901, -1464, + -307, -17, 499, + -315, -667, -254, + 256, 428, 1463, + -486, -422, -1056, + 655, 370, 18, + -102, -185, -276, + 755, 1578, 1335, + -488, -603, -1418, + 182, -93, 870, + -73, -458, -348, + 835, 862, 957, + -282, -333, -746, + 547, 839, 428, + 273, -89, 13, + 940, 1708, 2576, + -418, -1084, -1758, + -44, -358, 259, + -497, -643, -560, + 99, 557, 961, + -421, -766, -917, + 295, 326, 184, + 175, 15, -626, + 532, 878, 1981, + -443, -768, -1275, + 221, 156, 268, + 39, -363, -505, + 695, 772, 1140, + -162, -459, -912, + 709, 444, 658, + 25, 303, -312, + 1268, 1410, 1715, + -297, -766, -1836, + -263, -108, 1070, + -406, -13, -129, + 57, 438, 2734, + -374, -487, -835, + 304, 696, 164, + 104, -235, 5, + 1611, 1900, 1399, + -229, -582, -1325, + 405, 192, 817, + -87, -438, 111, + 1028, 1199, 993, + 68, -175, -934, + 1033, 1117, 451, + 478, 200, -248, + 2127, 2696, 2042, + -835, -1323, -2131, + -799, -692, 466, + -812, -1032, -469, + -622, 288, 920, + -701, -841, -1070, + -411, 512, 8, + -390, -91, -744, + -30, 1043, 1161, + -822, -1148, -1156, + -294, -46, 110, + -411, -374, -678, + 214, 531, 668, + -406, -420, -1194, + 487, 232, 303, + -318, 91, -472, + 123, 1232, 2445, + -722, -952, -1495, + -738, -675, 1332, + -543, -606, -211, + -95, -98, 1508, + -549, -514, -1193, + 473, 211, 73, + -288, -112, -389, + 537, 1332, 1258, + -567, -755, -1545, + 71, -283, 632, + -170, -481, -493, + 681, 1002, 817, + -356, -331, -877, + 419, 706, 346, + 241, -34, -326, + 377, 1950, 1883, + -727, -1075, -1625, + -233, -543, 116, + -524, -806, -585, + -73, 478, 729, + -288, -925, -1143, + 173, 447, -52, + 68, -229, -606, + 449, 529, 1797, + -591, -875, -1363, + 183, -144, 324, + -103, -452, -666, + 623, 488, 1176, + -238, -511, -1004, + 326, 552, 458, + 136, 108, -319, + 626, 1343, 1883, + -490, -646, -1730, + -186, -449, 984, + -738, -76, -170, + -550, 755, 2560, + -496, -510, -947, + 210, 694, -52, + 84, -322, -199, + 1090, 1625, 1224, + -376, -603, -1396, + 343, 74, 632, + -175, -502, -32, + 972, 1332, 734, + 52, -295, -1113, + 1065, 918, 160, + 393, 107, -397, + 1214, 2649, 1741, + -632, -1201, -1891, + -719, -277, 353, + -651, -880, -122, + -211, 209, 1338, + -562, -714, -1059, + -208, 388, 159, + -320, -61, -551, + 293, 1092, 1443, + -648, -865, -1253, + -49, -143, 305, + -401, -227, -585, + 561, 532, 927, + -117, -443, -1188, + 507, 436, 292, + -79, 233, -458, + 671, 1025, 2396, + -633, -842, -1525, + -308, -286, 640, + -373, -621, -407, + 418, 253, 1305, + -315, -581, -1137, + 572, 685, -281, + 61, -68, -371, + 991, 1101, 1498, + -493, -683, -1362, + -47, 164, 704, + -256, -314, -268, + 631, 949, 1052, + -118, -348, -833, + 68, 1180, 568, + 152, 117, 34, + 1113, 1902, 2239, + -601, -959, -1706, + -143, -489, 480, + -332, -655, -574, + 54, 353, 1192, + -462, -652, -796, + 150, 549, 112, + 195, -111, -515, + 679, 1108, 1647, + -558, -749, -1217, + -9, 272, 341, + -53, -265, -535, + 489, 843, 1298, + -120, -482, -1032, + 632, 543, 408, + 179, 306, -526, + 1124, 1464, 2244, + -417, -786, -1562, + -224, -384, 1364, + -377, -459, -25, + 385, 489, 2174, + -332, -651, -829, + 544, 553, 61, + 22, -113, -89, + 1128, 1725, 1524, + -216, -373, -1653, + 161, 316, 908, + -165, -222, -67, + 1362, 1175, 789, + 73, -252, -767, + 738, 932, 616, + 362, 246, -126, + 787, 2654, 3027, + -691, -1106, -2190, + -565, -588, 524, + -590, -979, -490, + -263, 397, 982, + -577, -837, -945, + -22, 435, -49, + -190, -118, -629, + -88, 1240, 1513, + -636, -1051, -1019, + -291, 189, 259, + -257, -470, -629, + 145, 945, 894, + -326, -364, -1094, + 543, 260, 630, + -202, 189, -209, + 357, 1379, 2091, + -569, -1075, -1449, + -714, -239, 919, + -420, -705, -84, + -109, -114, 2407, + -413, -529, -1177, + 482, 368, 131, + -186, -72, -131, + 861, 1255, 1220, + -611, -658, -1341, + 227, -121, 631, + -176, -489, -218, + 745, 1175, 957, + -321, -148, -936, + 671, 966, 216, + 340, -3, -143, + 469, 1848, 2437, + -729, -961, -1683, + -213, -254, 321, + -511, -438, -521, + -126, 725, 903, + -340, -685, -1032, + 316, 480, 20, + 23, -89, -551, + 353, 1051, 1789, + -544, -757, -1364, + 298, -25, 436, + -100, -392, -519, + 467, 754, 1078, + -210, -398, -1078, + 620, 658, 630, + 33, 147, -178, + 921, 1687, 1921, + -325, -528, -1978, + 2, -285, 910, + -371, -490, -230, + 0, 597, 2010, + -496, -395, -834, + 37, 945, 245, + 181, -160, -144, + 1481, 1373, 1357, + -355, -601, -1270, + 298, 322, 672, + -193, -336, 77, + 1089, 1533, 922, + 177, -39, -1125, + 996, 781, 536, + 456, 366, -432, + 1415, 2440, 2279, + -466, -758, -2325, + -303, -509, 387, + -727, -557, 66, + -145, 643, 1248, + -544, -676, -916, + -225, 862, 588, + -152, 40, -533, + 423, 1423, 1558, + -572, -843, -1145, + -128, 85, 461, + -238, -257, -584, + 605, 748, 861, + 24, -202, -1409, + 797, 487, 303, + -181, 364, -182, + 616, 1378, 2942, + -494, -852, -1441, + -292, 61, 812, + -84, -723, -182, + 555, 532, 1506, + -365, -493, -1057, + 822, 588, 11, + -14, -18, -230, + 1001, 1401, 1451, + -474, -569, -1292, + 302, 62, 1062, + -70, -376, -222, + 982, 974, 1149, + -196, -234, -795, + 479, 1098, 499, + 362, 58, 70, + 1147, 2069, 2857, + -487, -878, -1824, + 73, -288, 348, + -358, -500, -508, + 199, 721, 1242, + -78, -697, -795, + 361, 536, 196, + 374, 110, -735, + 847, 1051, 1896, + -366, -713, -1182, + 315, 320, 429, + 72, -215, -450, + 759, 886, 1363, + -30, -428, -834, + 861, 627, 796, + 118, 468, -279, + 1355, 1883, 1893, + -188, -642, -1612, + 63, -175, 1198, + -418, -211, 51, + 414, 587, 2601, + -234, -557, -858, + 424, 889, 222, + 136, -101, 83, + 1413, 2278, 1383, + -84, -445, -1389, + 414, 313, 1045, + 29, -343, 65, + 1552, 1647, 980, + 183, -91, -829, + 1273, 1413, 360, + 553, 272, -107, + 1587, 3149, 2603 +}; + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf_5.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf_5.cpp new file mode 100644 index 00000000..10d514da --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf_5.cpp @@ -0,0 +1,600 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: q_plsf_5.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "q_plsf.h" +#include "typedef.h" +#include "basic_op.h" +#include "lsp_lsf.h" +#include "reorder.h" +#include "lsfwt.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + /* Codebooks of LSF prediction residual */ + extern const Word16 mean_lsf_5[]; + + extern const Word16 dico1_lsf_5[]; + extern const Word16 dico2_lsf_5[]; + extern const Word16 dico3_lsf_5[]; + extern const Word16 dico4_lsf_5[]; + extern const Word16 dico5_lsf_5[]; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Vq_subvec +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsf_r1 -- array of type Word16 -- 1st LSF residual vector, Q15 + lsf_r2 -- array of type Word16 -- 2nd LSF residual vector, Q15 + dico -- pointer to const Word16 -- quantization codebook, Q15 + wf1 -- array of type Word16 -- 1st LSF weighting factors, Q13 + wf2 -- array of type Word16 -- 2nd LSF weighting factors, Q13 + dico_size -- Word16 -- size of quantization codebook, Q0 + Outputs: + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + Word16 -- quantization index, Q0 + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the quantization of a 4-dimensional subvector. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + q_plsf_5.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +/* Quantization of a 4 dimensional subvector */ + +static Word16 Vq_subvec( /* o : quantization index, Q0 */ + Word16 *lsf_r1, /* i : 1st LSF residual vector, Q15 */ + Word16 *lsf_r2, /* i : 2nd LSF residual vector, Q15 */ + const Word16 *dico, /* i : quantization codebook, Q15 */ + Word16 *wf1, /* i : 1st LSF weighting factors Q13 */ + Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */ + Word16 dico_size, /* i : size of quantization codebook, Q0 */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + Word16 index = 0; /* initialization only needed to keep gcc silent */ + Word16 i; + Word16 temp; + const Word16 *p_dico; + Word32 dist_min; + Word32 dist; + Word16 wf1_0; + Word16 wf1_1; + Word16 wf2_0; + Word16 wf2_1; + Word32 aux1; + Word32 aux2; + Word32 aux3; + Word32 aux4; + + OSCL_UNUSED_ARG(pOverflow); + + dist_min = MAX_32; + p_dico = dico; + + wf1_0 = wf1[0]; + wf1_1 = wf1[1]; + wf2_0 = wf2[0]; + wf2_1 = wf2[1]; + + aux1 = ((Word32) lsf_r1[0] * wf1_0); + aux2 = ((Word32) lsf_r1[1] * wf1_1); + aux3 = ((Word32) lsf_r2[0] * wf2_0); + aux4 = ((Word32) lsf_r2[1] * wf2_1); + + for (i = 0; i < dico_size; i++) + { + temp = (aux1 - ((Word32)wf1_0 * *(p_dico++))) >> 15; + dist = ((Word32)temp * temp); + + if (dist >= dist_min) + { + p_dico += 3; + continue; + } + + temp = (aux2 - ((Word32)wf1_1 * *(p_dico++))) >> 15; + dist += ((Word32)temp * temp); + + if (dist >= dist_min) + { + p_dico += 2; + continue; + } + + temp = (aux3 - ((Word32)wf2_0 * *(p_dico++))) >> 15; + dist += ((Word32)temp * temp); + + if (dist >= dist_min) + { + p_dico += 1; + continue; + } + + temp = (aux4 - ((Word32)wf2_1 * *(p_dico++))) >> 15; + dist += ((Word32)temp * temp); + + + if (dist < dist_min) + { + dist_min = dist; + index = i; + } + } + + + + /* Reading the selected vector */ + + p_dico = &dico[ index<<2]; + lsf_r1[0] = *p_dico++; + lsf_r1[1] = *p_dico++; + lsf_r2[0] = *p_dico++; + lsf_r2[1] = *p_dico; + + return index; + +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Vq_subvec_s +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsf_r1 -- array of type Word16 -- 1st LSF residual vector, Q15 + lsf_r2 -- array of type Word16 -- 2nd LSF residual vector, Q15 + dico -- pointer to const Word16 -- quantization codebook, Q15 + wf1 -- array of type Word16 -- 1st LSF weighting factors, Q13 + wf2 -- array of type Word16 -- 2nd LSF weighting factors, Q13 + dico_size -- Word16 -- size of quantization codebook, Q0 + + Outputs: + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + Word16 -- quantization index, Q0 + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the quantization of a 4-dimensional subvector. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + q_plsf_5.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + + +/* Quantization of a 4 dimensional subvector with a signed codebook */ + +static Word16 Vq_subvec_s( /* o : quantization index Q0 */ + Word16 *lsf_r1, /* i : 1st LSF residual vector Q15 */ + Word16 *lsf_r2, /* i : and LSF residual vector Q15 */ + const Word16 *dico, /* i : quantization codebook Q15 */ + Word16 *wf1, /* i : 1st LSF weighting factors Q13 */ + Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */ + Word16 dico_size, /* i : size of quantization codebook Q0 */ + Flag *pOverflow) /* o : overflow indicator */ +{ + Word16 index = 0; /* initialization only needed to keep gcc silent */ + Word16 sign = 0; /* initialization only needed to keep gcc silent */ + Word16 i; + Word16 temp; + Word16 temp1; + Word16 temp2; + const Word16 *p_dico; + Word32 dist_min; + Word32 dist1; + Word32 dist2; + + Word16 lsf_r1_0; + Word16 lsf_r1_1; + Word16 lsf_r2_0; + Word16 lsf_r2_1; + + Word16 wf1_0; + Word16 wf1_1; + Word16 wf2_0; + Word16 wf2_1; + + OSCL_UNUSED_ARG(pOverflow); + + dist_min = MAX_32; + p_dico = dico; + + + lsf_r1_0 = lsf_r1[0]; + lsf_r1_1 = lsf_r1[1]; + lsf_r2_0 = lsf_r2[0]; + lsf_r2_1 = lsf_r2[1]; + + wf1_0 = wf1[0]; + wf1_1 = wf1[1]; + wf2_0 = wf2[0]; + wf2_1 = wf2[1]; + + for (i = 0; i < dico_size; i++) + { + /* test positive */ + temp = *p_dico++; + temp1 = lsf_r1_0 - temp; + temp2 = lsf_r1_0 + temp; + temp1 = ((Word32)wf1_0 * temp1) >> 15; + temp2 = ((Word32)wf1_0 * temp2) >> 15; + dist1 = ((Word32)temp1 * temp1); + dist2 = ((Word32)temp2 * temp2); + + temp = *p_dico++; + temp1 = lsf_r1_1 - temp; + temp2 = lsf_r1_1 + temp; + temp1 = ((Word32)wf1_1 * temp1) >> 15; + temp2 = ((Word32)wf1_1 * temp2) >> 15; + dist1 += ((Word32)temp1 * temp1); + dist2 += ((Word32)temp2 * temp2); + + if ((dist1 >= dist_min) && (dist2 >= dist_min)) + { + p_dico += 2; + continue; + } + + temp = *p_dico++; + temp1 = lsf_r2_0 - temp; + temp2 = lsf_r2_0 + temp; + temp1 = ((Word32)wf2_0 * temp1) >> 15; + temp2 = ((Word32)wf2_0 * temp2) >> 15; + dist1 += ((Word32)temp1 * temp1); + dist2 += ((Word32)temp2 * temp2); + + temp = *p_dico++; + temp1 = lsf_r2_1 - temp; + temp2 = lsf_r2_1 + temp; + temp1 = ((Word32)wf2_1 * temp1) >> 15; + temp2 = ((Word32)wf2_1 * temp2) >> 15; + dist1 += ((Word32)temp1 * temp1); + dist2 += ((Word32)temp2 * temp2); + + if (dist1 < dist_min) + { + dist_min = dist1; + index = i; + sign = 0; + } + + /* test negative */ + + if (dist2 < dist_min) + { + dist_min = dist2; + index = i; + sign = 1; + } + } + + /* Reading the selected vector */ + + p_dico = &dico[index<<2]; + index <<= 1; + if (sign) + { + lsf_r1[0] = - (*p_dico++); + lsf_r1[1] = - (*p_dico++); + lsf_r2[0] = - (*p_dico++); + lsf_r2[1] = - (*p_dico); + index += 1; + } + else + { + lsf_r1[0] = *p_dico++; + lsf_r1[1] = *p_dico++; + lsf_r2[0] = *p_dico++; + lsf_r2[1] = *p_dico; + } + + return index; + +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Q_plsf_5 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + + Inputs: + st -- pointer to Q_plsfState -- state information + lsp1 -- array of type Word16 -- 1st LSP vector, Q15 + lsp2 -- array of type Word16 -- 2nd LSP vector, Q15 + + Outputs: + lps1_q -- array of type Word16 -- quantized 1st LSP vector, Q15 + lps2_q -- array of type Word16 -- quantized 2nd LSP vector, Q15 + indices -- array of type Word16 -- quantization indices of 5 matrics, Q0 + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + mean_lsf_5[]; + + dico1_lsf_5[]; + dico2_lsf_5[]; + dico3_lsf_5[]; + dico4_lsf_5[]; + dico5_lsf_5[]; + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Quantization of 2 sets of LSF parameters using 1st order MA + prediction and split by 5 matrix quantization (split-MQ) + + DESCRIPTION: + + p[i] = pred_factor*past_rq[i]; i=0,...,m-1 + r1[i]= lsf1[i] - p[i]; i=0,...,m-1 + r2[i]= lsf2[i] - p[i]; i=0,...,m-1 + where: + lsf1[i] 1st mean-removed LSF vector. + lsf2[i] 2nd mean-removed LSF vector. + r1[i] 1st residual prediction vector. + r2[i] 2nd residual prediction vector. + past_r2q[i] Past quantized residual (2nd vector). + + The residual vectors r1[i] and r2[i] are jointly quantized using + split-MQ with 5 codebooks. Each 4th dimension submatrix contains 2 + elements from each residual vector. The 5 submatrices are as follows: + {r1[0], r1[1], r2[0], r2[1]}; {r1[2], r1[3], r2[2], r2[3]}; + {r1[4], r1[5], r2[4], r2[5]}; {r1[6], r1[7], r2[6], r2[7]}; + {r1[8], r1[9], r2[8], r2[9]} + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + q_plsf_5.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void Q_plsf_5( + Q_plsfState *st, + Word16 *lsp1, /* i : 1st LSP vector, Q15 */ + Word16 *lsp2, /* i : 2nd LSP vector, Q15 */ + Word16 *lsp1_q, /* o : quantized 1st LSP vector, Q15 */ + Word16 *lsp2_q, /* o : quantized 2nd LSP vector, Q15 */ + Word16 *indice, /* o : quantization indices of 5 matrices, Q0 */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + Word16 i; + Word16 lsf1[M]; + Word16 lsf2[M]; + Word16 wf1[M]; + Word16 wf2[M]; + Word16 lsf_p[M]; + Word16 lsf_r1[M]; + Word16 lsf_r2[M]; + Word16 lsf1_q[M]; + Word16 lsf2_q[M]; + + Word16 *p_lsf_p; + Word16 *p_lsf1; + Word16 *p_lsf2; + Word16 *p_lsf_r1; + Word16 *p_lsf_r2; + + /* convert LSFs to normalize frequency domain 0..16384 */ + + Lsp_lsf(lsp1, lsf1, M, pOverflow); + Lsp_lsf(lsp2, lsf2, M, pOverflow); + + /* Compute LSF weighting factors (Q13) */ + + Lsf_wt(lsf1, wf1, pOverflow); + Lsf_wt(lsf2, wf2, pOverflow); + + /* Compute predicted LSF and prediction error */ + + p_lsf_p = &lsf_p[0]; + p_lsf1 = &lsf1[0]; + p_lsf2 = &lsf2[0]; + p_lsf_r1 = &lsf_r1[0]; + p_lsf_r2 = &lsf_r2[0]; + + for (i = 0; i < M; i++) + { + *(p_lsf_p) = mean_lsf_5[i] + + (((Word32)st->past_rq[i] * LSP_PRED_FAC_MR122) >> 15); + + *(p_lsf_r1++) = *(p_lsf1++) - *(p_lsf_p); + *(p_lsf_r2++) = *(p_lsf2++) - *(p_lsf_p++); + } + + /*---- Split-MQ of prediction error ----*/ + + indice[0] = Vq_subvec(&lsf_r1[0], &lsf_r2[0], dico1_lsf_5, + &wf1[0], &wf2[0], DICO1_5_SIZE, pOverflow); + + indice[1] = Vq_subvec(&lsf_r1[2], &lsf_r2[2], dico2_lsf_5, + &wf1[2], &wf2[2], DICO2_5_SIZE, pOverflow); + + indice[2] = Vq_subvec_s(&lsf_r1[4], &lsf_r2[4], dico3_lsf_5, + &wf1[4], &wf2[4], DICO3_5_SIZE, pOverflow); + + indice[3] = Vq_subvec(&lsf_r1[6], &lsf_r2[6], dico4_lsf_5, + &wf1[6], &wf2[6], DICO4_5_SIZE, pOverflow); + + indice[4] = Vq_subvec(&lsf_r1[8], &lsf_r2[8], dico5_lsf_5, + &wf1[8], &wf2[8], DICO5_5_SIZE, pOverflow); + + /* Compute quantized LSFs and update the past quantized residual */ + + p_lsf_r1 = &lsf_r1[0]; + p_lsf_r2 = &lsf_r2[0]; + p_lsf_p = &lsf_p[0]; + p_lsf1 = &lsf1_q[0]; + p_lsf2 = &lsf2_q[0]; + + + for (i = 0; i < M; i++) + { + *(p_lsf1++) = *(p_lsf_r1++) + *(p_lsf_p); + *(p_lsf2++) = *(p_lsf_r2) + *(p_lsf_p++); + st->past_rq[i] = *(p_lsf_r2++); + } + + /* verification that LSFs has minimum distance of LSF_GAP */ + + Reorder_lsf(lsf1_q, LSF_GAP, M, pOverflow); + Reorder_lsf(lsf2_q, LSF_GAP, M, pOverflow); + + /* convert LSFs to the cosine domain */ + + Lsf_lsp(lsf1_q, lsp1_q, M, pOverflow); + Lsf_lsp(lsf2_q, lsp2_q, M, pOverflow); +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf_5_tbl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf_5_tbl.cpp new file mode 100644 index 00000000..42f37a15 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/q_plsf_5_tbl.cpp @@ -0,0 +1,1131 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: q_plsf_5_tbl.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "q_plsf_5_tbl.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ +#define NB_QUA_PITCH 16 +#define NB_QUA_CODE 32 + + +#define DICO1_5_SIZE 128 +#define DICO2_5_SIZE 256 +#define DICO3_5_SIZE 256 +#define DICO4_5_SIZE 256 +#define DICO5_5_SIZE 64 + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + /* LSF means ->normalize frequency domain */ + + const Word16 mean_lsf_5[10] = + { + 1384, + 2077, + 3420, + 5108, + 6742, + 8122, + 9863, + 11092, + 12714, + 13701 + }; + + const Word16 dico1_lsf_5[DICO1_5_SIZE * 4] = + { + -451, -1065, -529, -1305, + -450, -756, -497, -863, + -384, -619, -413, -669, + -317, -538, -331, -556, + -414, -508, -424, -378, + -274, -324, -434, -614, + -226, -500, -232, -514, + -263, -377, -298, -410, + -151, -710, -174, -818, + -149, -412, -156, -429, + -288, -462, -186, -203, + -170, -302, -191, -321, + -131, -147, -297, -395, + -228, -214, -245, -192, + -67, -316, -71, -327, + -104, -205, -94, -183, + -143, -38, -193, -95, + 16, -76, -124, -248, + 23, -237, 24, -244, + 18, -136, 44, -111, + -33, -24, -25, 0, + 149, 19, 23, -143, + 158, -169, 174, -181, + 133, -55, 165, -26, + 111, 84, 98, 75, + 87, 183, -115, -11, + -8, 130, 11, 170, + 254, 77, 205, 17, + 183, 112, 262, 194, + 202, 287, 95, 189, + -42, -105, 234, 179, + 39, 186, 163, 345, + 332, 199, 299, 161, + -54, 285, -78, 281, + -133, 141, -182, 111, + 249, 341, 271, 364, + 93, 403, 75, 391, + 92, 510, -138, 220, + -185, -29, -34, 361, + -115, 320, 3, 554, + 99, 286, 218, 591, + -245, 406, -268, 453, + 0, 580, 25, 606, + 275, 532, 148, 450, + -73, 739, -285, 518, + -288, 94, -203, 674, + -140, -74, 205, 714, + -114, 299, 176, 923, + 182, 557, 240, 705, + -16, 513, 485, 593, + 293, 384, 451, 617, + -38, 50, 563, 529, + 303, 209, 459, 363, + 433, 452, 450, 454, + 367, 606, 477, 741, + 432, 353, 368, 267, + 361, 716, 273, 583, + 453, 166, 510, 172, + 201, 629, 274, 191, + 568, 639, 302, 298, + 634, 387, 643, 350, + 587, 560, 612, 565, + 600, 788, 487, 672, + 512, 1015, 321, 333, + 357, 854, -125, 413, + 474, 712, 17, -151, + 564, 285, 270, -241, + 971, 889, 489, 220, + 510, 896, 549, 924, + 327, 825, 290, 911, + 540, 1108, 158, 805, + 199, 957, 511, 730, + 100, 874, 13, 791, + 435, 632, 676, 972, + 249, 900, 467, 1218, + 781, 1074, 585, 785, + -23, 669, 267, 1043, + 619, 1084, 615, 1145, + 622, 905, 916, 1049, + 80, 331, 584, 1075, + 89, 639, 988, 961, + 770, 720, 798, 699, + 492, 447, 899, 627, + 271, 1188, 725, 1333, + 87, 603, 832, 1603, + 616, 1127, 890, 1505, + 1000, 1156, 866, 1009, + 995, 827, 1149, 858, + 817, 1450, 773, 1320, + 500, 1389, 312, 1153, + -20, 1084, 64, 1283, + 2, 1172, 399, 1869, + 514, 1706, 502, 1636, + 886, 1522, 416, 600, + 1131, 1350, 1275, 1390, + 889, 1795, 914, 1766, + 227, 1183, 1250, 1826, + 505, 1854, 919, 2353, + -199, 431, 152, 1735, + -213, -28, 392, 1334, + -153, -52, 978, 1151, + -323, -400, 813, 1703, + -136, 84, 1449, 2015, + -331, -143, -137, 1192, + -256, 534, -157, 1031, + -307, -439, 542, 731, + -329, -420, -97, 616, + -362, -168, -322, 366, + -247, -110, -211, 89, + -196, -309, 20, 59, + -364, -463, -286, 89, + -336, 175, -432, 141, + -379, -190, -434, -196, + -79, 150, -278, -227, + -280, 166, -555, -422, + -155, 541, -366, 54, + -29, -83, -301, -774, + 186, 628, -397, -264, + 242, 293, -197, -585, + 124, 410, 53, -133, + 10, 340, -570, -1065, + 65, -446, 68, -493, + 383, 937, -357, -711, + -359, -250, -677, -1068, + 292, -26, 363, 6, + 607, 1313, -127, -10, + 1513, 1886, 713, 972, + 1469, 2181, 1443, 2016 + }; + + const Word16 dico2_lsf_5[DICO2_5_SIZE * 4] = + { + -1631, -1600, -1796, -2290, + -1027, -1770, -1100, -2025, + -1277, -1388, -1367, -1534, + -947, -1461, -972, -1524, + -999, -1222, -1020, -1172, + -815, -987, -992, -1371, + -1216, -1006, -1289, -1094, + -744, -1268, -755, -1293, + -862, -923, -905, -984, + -678, -1051, -685, -1050, + -1087, -985, -1062, -679, + -989, -641, -1127, -976, + -762, -654, -890, -806, + -833, -1091, -706, -629, + -621, -806, -640, -812, + -775, -634, -779, -543, + -996, -565, -1075, -580, + -546, -611, -572, -619, + -760, -290, -879, -526, + -823, -462, -795, -253, + -553, -415, -589, -439, + -533, -340, -692, -935, + -505, -772, -702, -1131, + -263, -306, -971, -483, + -445, -74, -555, -548, + -614, -129, -693, -234, + -396, -246, -475, -250, + -265, -404, -376, -514, + -417, -510, -300, -313, + -334, -664, -463, -814, + -386, -704, -337, -615, + -234, -201, -233, -239, + -167, -567, -203, -619, + -147, -415, -115, -352, + -166, -750, -171, -761, + -270, -879, -264, -903, + -367, -744, 43, -475, + 14, -653, 43, -670, + 11, -448, -59, -521, + -126, -119, -155, -613, + -42, -863, -27, -931, + 136, -483, 183, -468, + 55, -298, 55, -304, + 313, -609, 313, -720, + 322, -167, 100, -541, + -3, -119, -111, -187, + 233, -236, 260, -234, + 26, -165, 134, -45, + -40, -549, 360, -203, + 378, -388, 450, -383, + 275, 20, 182, -103, + 246, -111, 431, 37, + 462, -146, 487, -157, + -284, -59, 503, -184, + 24, 53, -3, 54, + 122, 259, 333, 66, + 484, 104, 436, 68, + 195, 116, 190, 206, + 269, -9, 482, 352, + 382, 285, 399, 277, + 452, 256, 69, 186, + 13, 297, -13, 259, + -95, 30, 56, 394, + 196, 425, 205, 456, + 281, 577, 15, 191, + 375, 290, 407, 576, + -56, 227, 544, 405, + 0, 549, -92, 528, + -229, 351, -245, 338, + -362, 435, 167, 527, + -75, 302, 91, 824, + 129, 599, 496, 679, + 186, 749, 153, 737, + -281, 600, -348, 615, + -236, 769, 41, 881, + 38, 890, -220, 841, + -357, 883, -393, 903, + -634, 474, -444, 850, + -175, 678, -493, 242, + -519, 785, -714, 582, + -541, 366, -543, 434, + -597, 500, -765, 222, + -702, 917, -743, 962, + -869, 501, -899, 548, + -379, 200, -435, 157, + -819, 214, -861, 157, + -614, 40, -632, 94, + -883, -54, -741, 516, + -501, 298, -614, -171, + -870, -161, -865, -23, + -818, 93, -1015, -267, + -662, -359, -549, 2, + -442, -121, -377, 0, + -227, 33, -414, -126, + -129, 212, -934, 34, + -1082, -282, -1119, -268, + -710, -825, -420, -191, + -1076, -928, -917, -93, + -628, -358, 97, 7, + -206, -393, -101, 24, + -203, 38, -168, 83, + -599, -423, -279, 426, + -700, 118, -75, 206, + -981, -673, -680, 417, + -367, 37, -279, 474, + -129, -318, 319, 296, + -626, -39, 343, 602, + -696, -39, -303, 940, + 104, 233, -380, 137, + -36, 269, -75, -214, + 120, 43, -529, -477, + 459, 164, -202, -229, + -49, -167, 609, 792, + 98, -220, 915, 148, + 293, 283, 869, 91, + 575, 394, 326, -78, + 717, 67, 365, -323, + 616, -36, 731, 27, + 619, 238, 632, 273, + 448, 99, 801, 476, + 869, 273, 685, 64, + 789, 72, 1021, 217, + 793, 459, 734, 360, + 646, 480, 360, 322, + 429, 464, 638, 430, + 756, 363, 1000, 404, + 683, 528, 602, 615, + 655, 413, 946, 687, + 937, 602, 904, 604, + 555, 737, 786, 662, + 467, 654, 362, 589, + 929, 710, 498, 478, + 415, 420, 693, 883, + 813, 683, 781, 925, + 913, 939, 726, 732, + 491, 853, 531, 948, + 734, 963, 315, 808, + 761, 755, 1144, 760, + 655, 1076, 826, 1057, + 1091, 838, 1003, 808, + 1047, 1133, 659, 1101, + 992, 1050, 1074, 1075, + 971, 694, 1226, 1054, + 571, 841, 884, 1404, + 1379, 1096, 1080, 861, + 1231, 735, 1284, 760, + 1272, 991, 1367, 1053, + 1257, 700, 1050, 534, + 988, 453, 1264, 599, + 1140, 679, 1621, 815, + 1384, 521, 1317, 393, + 1564, 805, 1448, 686, + 1068, 648, 875, 307, + 1083, 361, 1047, 317, + 1417, 964, 675, 571, + 1152, 79, 1114, -47, + 1530, 311, 1721, 314, + 1166, 689, 514, -94, + 349, 282, 1412, 328, + 1025, 487, -65, 57, + 805, 970, 36, 62, + 769, -263, 791, -346, + 637, 699, -137, 620, + 534, 541, -735, 194, + 711, 300, -268, -863, + 926, 769, -708, -428, + 506, 174, -892, -630, + 435, 547, -1435, -258, + 621, 471, -1018, -1368, + -393, 521, -920, -686, + -25, 20, -982, -1156, + 340, 9, -1558, -1135, + -352, 48, -1579, -402, + -887, 6, -1156, -888, + -548, -352, -1643, -1168, + -159, 610, -2024, -963, + -225, 193, -1656, -1960, + -245, -493, -964, -1680, + -936, -635, -1299, -1744, + -1388, -604, -1540, -835, + -1397, -135, -1588, -290, + -1670, -712, -2011, -1632, + -1663, -27, -2258, -811, + -1157, 184, -1265, 189, + -1367, 586, -2011, 201, + -790, 712, -1210, 3, + -1033, 808, -1251, 830, + -111, 635, -1636, 447, + -463, -949, -445, -928, + -504, -1162, -501, -1211, + 144, -351, -372, -1052, + -283, -1059, -279, -1123, + -575, -1438, -587, -1614, + -935, -984, 229, 690, + -921, -719, -403, 1362, + -685, -465, 874, 397, + -509, -46, 317, 1334, + -485, 456, 813, 439, + -411, 339, 898, 1067, + -425, 46, 1441, 497, + -909, -800, 1465, 1046, + -254, -321, 1430, 1165, + 68, 350, 1034, 666, + 370, 11, 1311, 790, + 143, 232, 1041, 1562, + -114, 663, 1616, 1078, + 454, 579, 1275, 1040, + -76, 909, 752, 1067, + 153, 512, 348, 1214, + 614, 385, 1843, 808, + 269, 1034, 203, 1086, + 652, 1017, 1783, 1130, + 429, 1327, 387, 1384, + -49, 1183, -72, 1215, + -416, 1001, 544, 1749, + -352, 1223, -502, 1199, + -589, 569, -227, 1630, + -142, 1578, -230, 1715, + -714, 1288, -838, 1398, + 1131, 1357, -208, 1232, + 437, 965, -929, 818, + 811, 1410, 859, 1507, + 164, 1212, 1387, 1793, + 484, 1874, 456, 2063, + 996, 1170, 1326, 1402, + 1316, 1360, 1135, 1262, + 1234, 1618, 1361, 1768, + 1421, 1227, 1584, 1347, + 854, 672, 1685, 1566, + 1139, 1270, 2016, 1825, + 1773, 1581, 1532, 1460, + 1487, 946, 1659, 1021, + 1744, 1212, 1392, 977, + 1772, 1161, 1826, 1164, + 1718, 1429, 1973, 1591, + 1185, 864, 2132, 1061, + 1799, 814, 1838, 757, + 2104, 1315, 2054, 1258, + 2113, 915, 2331, 930, + 1467, 1147, 2590, 1439, + 2245, 1744, 2090, 1620, + 2358, 1454, 2666, 1506, + 1876, 1837, 2070, 1975, + 1739, 1577, 682, 1289, + 1584, 2045, 1454, 2098, + 2498, 2004, 2711, 2066, + 726, 1588, 2756, 2336, + 228, 847, 2456, 1659, + 36, 301, 1942, 1957, + -446, -96, 2154, 1396, + 1533, 1101, 14, 608, + -923, -732, 1383, 1982, + 1345, 952, -680, 321, + 1281, 1268, -1594, 365, + 941, 946, -1737, -822, + 2374, 2787, 1821, 2788 + }; + + const Word16 dico3_lsf_5[DICO3_5_SIZE * 4] = + { + -1812, -2275, -1879, -2537, + -1640, -1848, -1695, -2004, + -1220, -1912, -1221, -2106, + -1559, -1588, -1573, -1556, + -1195, -1615, -1224, -1727, + -1359, -1151, -1616, -1948, + -1274, -1391, -1305, -1403, + -1607, -1179, -1676, -1311, + -1443, -1478, -1367, -898, + -1256, -1059, -1331, -1134, + -982, -1133, -1149, -1504, + -1080, -1308, -1020, -1183, + -980, -1486, -967, -1495, + -988, -922, -1047, -1077, + -838, -1179, -858, -1222, + -1131, -1041, -1064, -767, + -872, -1157, -701, -880, + -706, -906, -774, -1016, + -578, -1080, -801, -1478, + -591, -1111, -592, -1146, + -713, -1388, -640, -1376, + -597, -1059, -416, -903, + -686, -832, -661, -708, + -444, -868, -490, -921, + -374, -776, -619, -1170, + -585, -549, -769, -795, + -435, -659, -530, -741, + -498, -837, -357, -597, + -279, -871, -243, -887, + -282, -665, -280, -667, + -165, -560, -394, -903, + -362, -410, -448, -583, + -409, -574, -313, -357, + -637, -548, -570, -436, + -896, -504, -382, -757, + -58, -481, -165, -618, + -191, -374, -234, -382, + -222, -683, -25, -480, + -418, -359, -730, -353, + -324, -157, -432, -322, + -394, -303, -284, -104, + -601, -289, -556, -196, + -588, -150, -659, -608, + -473, -24, -68, -448, + -474, -8, -506, -45, + -748, -184, -844, -252, + -901, -91, -584, -97, + -652, 138, -764, -131, + -678, -12, -670, 165, + -259, -3, -840, -107, + -909, 37, -992, 44, + -854, -415, -839, 13, + -1001, -271, -1026, -309, + -798, -478, -832, -488, + -943, 168, -1112, -387, + -1185, -101, -1183, -40, + -941, -316, -1030, -770, + -1044, -625, -1081, -538, + -1224, -299, -1312, -436, + -1197, -663, -1167, -161, + -1216, -690, -1237, -831, + -1432, -720, -1403, -493, + -898, -740, -922, -801, + -1102, -402, -1579, -964, + -1061, -638, -1269, -1438, + -1499, -934, -1502, -895, + -1598, -564, -1723, -717, + -606, -597, -1166, -1085, + -1369, -468, -1946, -1493, + -1838, -953, -1932, -931, + -1499, -188, -1635, -421, + -1457, -338, -1448, -22, + -1942, -422, -2006, -249, + -496, -114, -1910, -755, + -1289, 174, -1451, -109, + -482, -257, -1221, -508, + -1617, 151, -1694, 208, + -654, 107, -1651, 29, + -1141, 279, -1215, 306, + -1228, -506, -730, -175, + -1236, -101, -969, 551, + -870, 278, -823, 315, + -563, 376, -1051, 228, + -507, 280, -599, 281, + -758, 253, -305, 379, + -755, -134, -611, 660, + -824, 536, -817, 646, + -413, 49, -341, 177, + -453, 526, -482, 589, + -71, 339, -657, 264, + -244, 295, -237, 315, + -387, 569, -506, -9, + -377, 14, -160, 661, + -216, 40, -308, -46, + 95, 214, -242, 167, + -86, 192, -56, 27, + -76, 31, 36, 309, + -106, -182, -113, 74, + -441, -22, 23, 139, + 81, -11, 44, 15, + -87, -137, -118, -207, + -158, -58, 272, -92, + -156, -441, 8, -136, + 128, -221, 101, -218, + 40, -197, -76, -456, + 9, -445, 33, -423, + 226, 60, 73, -222, + 156, -399, 280, -318, + 245, -341, 166, -499, + 339, -190, 327, -219, + 325, -137, -89, -596, + 100, -627, 144, -677, + 487, 28, 252, -391, + 214, -41, 282, -28, + 99, -286, 331, 49, + 459, -388, 565, -369, + 436, 28, 336, -9, + 397, -167, 618, 34, + 596, -17, 561, -140, + 299, 79, 522, 125, + 203, 2, 244, 288, + 255, 211, 175, 82, + 596, 187, 517, 108, + 381, 255, 365, 297, + 497, 352, 327, -82, + 25, 210, 371, 245, + 261, 3, 545, 449, + 140, 294, 44, 295, + 212, 347, 244, 494, + 331, 528, 201, 307, + 349, 411, 613, 284, + 614, 413, 464, 322, + 624, 397, 97, 200, + -160, 384, 149, 362, + 495, 525, 269, 585, + 33, 491, -121, 433, + 427, 611, 498, 516, + 171, 443, 497, 666, + 440, 275, 566, 575, + 146, 639, 155, 670, + -33, 173, 212, 696, + -166, 601, -191, 695, + -489, 503, 175, 742, + 214, 476, 372, 1083, + 578, 530, 586, 777, + 425, 874, 315, 841, + 374, 848, -165, 565, + 35, 991, -39, 1062, + 329, 712, 786, 840, + 645, 795, 661, 676, + 571, 918, 632, 1079, + 673, 817, 318, 388, + 874, 1012, 564, 848, + 880, 620, 557, 479, + 671, 453, 692, 468, + 840, 642, 844, 645, + 506, 428, 897, 567, + 837, 387, 962, 499, + 691, 561, 939, 926, + 783, 296, 790, 268, + 1028, 530, 874, 329, + 548, 143, 675, 291, + 503, 66, 1041, 359, + 786, 97, 805, 33, + 837, 470, 511, 49, + 1092, 327, 1174, 323, + 3, 242, 872, 474, + 689, 429, 1329, 678, + 1042, 620, 1109, 664, + 321, 193, 889, 950, + 1153, 874, 893, 635, + 877, 862, 948, 913, + 1293, 665, 1320, 639, + 997, 793, 1402, 1030, + 1176, 1012, 1110, 959, + 1410, 925, 1403, 915, + 543, 862, 1116, 1222, + 835, 1190, 835, 1190, + 959, 1148, 1147, 1376, + 1300, 1193, 1415, 1231, + 1335, 1341, 746, 1092, + 1711, 1283, 1389, 1073, + 1334, 1566, 1153, 1475, + 1645, 1137, 1825, 1220, + 1056, 1382, 1521, 1730, + 1632, 1545, 1620, 1542, + 855, 1596, 865, 1667, + 693, 885, 1716, 1519, + 1167, 1296, 2209, 1760, + 1952, 1493, 2020, 1482, + 1534, 1866, 1694, 2008, + 1566, 748, 1761, 825, + 294, 1392, 1084, 2058, + 621, 1315, 365, 1287, + 198, 1028, 488, 1408, + 249, 403, 1014, 1561, + 324, 363, 1645, 1044, + 193, 367, 2034, 1859, + -251, 579, 750, 994, + -243, 30, 1325, 879, + -28, -169, 624, 917, + -453, 159, 186, 1370, + -614, 6, 537, 392, + -94, -291, 781, 229, + -128, -298, 245, 491, + -701, -648, 972, 789, + -501, -640, 178, 255, + -365, -390, -255, 317, + -958, -294, -191, 228, + -775, -447, 157, -237, + -657, -720, -407, 92, + -117, -611, 334, -230, + -679, -1084, -144, -317, + -901, -861, -738, -360, + -85, -727, -90, -787, + 100, -22, -391, -263, + -56, -73, -337, -754, + 5, -189, -706, -624, + 89, -344, -135, -1113, + -353, -237, -684, -1135, + -275, -1102, -269, -1203, + 152, 145, -722, -1232, + 49, 80, -1248, -776, + -248, 391, -732, -547, + 469, 218, -255, -864, + 69, 366, -166, -485, + -688, 191, -1212, -1196, + -170, -169, -1308, -1631, + 321, 470, -1419, -1243, + -64, 272, -1361, -248, + 492, 565, -721, -609, + 195, 485, -573, -133, + 427, 202, -171, -118, + 199, 575, 2, -31, + 694, 755, -1366, -39, + 552, 557, -489, 271, + 680, 537, 13, -453, + 855, 954, -133, -52, + -81, 738, -1169, 637, + 1055, 1059, -95, 676, + 1259, 1081, 489, 305, + -449, 954, -534, 996, + -969, 866, -1058, 1059, + -1294, 618, -1416, 617, + -458, 1366, -159, 1821, + -774, -528, -14, 1110, + -1202, -901, -772, 433, + -1256, -1255, -1011, -302, + -602, -585, -759, -1618, + -760, -1549, -840, -1921, + -816, -539, -1769, -2235, + -227, -36, -2034, -1831, + -2107, -1126, -2471, -1816, + -1470, 252, -2701, -415, + -571, -467, 1509, 1554, + 2180, 1975, 2326, 2020 + }; + + const Word16 dico4_lsf_5[DICO4_5_SIZE * 4] = + { + -1857, -1681, -1857, -1755, + -2056, -1150, -2134, -1654, + -1619, -1099, -1704, -1131, + -1345, -1608, -1359, -1638, + -1338, -1293, -1325, -1265, + -1664, -1649, -1487, -851, + -1346, -1832, -1413, -2188, + -1282, -681, -1785, -1649, + -966, -1082, -1183, -1676, + -1054, -1073, -1142, -1158, + -1207, -744, -1274, -997, + -934, -1383, -927, -1416, + -1010, -1305, -783, -955, + -1049, -900, -993, -817, + -737, -823, -972, -1189, + -738, -1094, -738, -1154, + -784, -801, -810, -786, + -892, -520, -1000, -818, + -644, -965, -577, -882, + -541, -694, -671, -917, + -595, -642, -646, -615, + -956, -621, -925, -515, + -727, -483, -815, -485, + -840, -578, -440, -713, + -578, -325, -657, -670, + -386, -570, -441, -666, + -514, -787, -392, -529, + -522, -453, -487, -423, + -616, -585, -617, -157, + -662, -268, -680, -348, + -322, -323, -632, -444, + -304, -430, -332, -458, + -277, -468, -659, -793, + -319, -636, -227, -554, + -373, -347, -334, -210, + -456, -192, -530, -242, + -216, -198, -366, -370, + -338, -161, -409, -748, + -107, -380, -294, -643, + -223, -665, -234, -741, + -141, -496, -130, -510, + -139, -327, -172, -305, + -306, -580, -164, -263, + -262, -172, -67, -402, + 31, -366, -10, -436, + -86, -527, 71, -377, + -22, -609, -12, -678, + -67, -319, 63, -191, + 35, -181, -39, -242, + 126, -167, -140, -544, + 155, -297, 174, -297, + 38, -8, 117, -380, + 197, -452, 240, -522, + 223, -103, 110, -187, + 87, -155, 169, -47, + 157, 26, -83, -100, + 128, 80, 209, -62, + 6, 7, 22, 5, + 318, -20, 248, -45, + -200, -63, 156, -69, + 250, -183, 369, -126, + -113, -76, -142, -122, + -64, -254, -31, 35, + -177, -71, -7, 171, + 93, 27, 108, 212, + -330, -209, -123, -70, + -279, 95, -96, 20, + -188, -61, -314, 87, + -300, -78, -354, -134, + 11, 122, -140, 122, + -275, 152, -293, 140, + -82, 138, -321, -111, + -480, -156, -359, 76, + -254, -40, -635, -96, + -522, 79, -507, 8, + -268, 303, -539, 68, + -446, 61, -522, 306, + 111, 189, -435, 122, + -379, 166, -571, -398, + -632, -74, -747, -95, + -455, 194, -952, 83, + -798, 192, -755, 192, + -781, -162, -619, 234, + -663, -297, -488, -109, + -964, -132, -838, -68, + -843, 58, -1112, -86, + -805, -299, -944, -253, + -778, -50, -965, -549, + -352, -98, -992, -343, + -1117, -315, -1117, -307, + -1155, -374, -637, -230, + -1166, -43, -1299, -100, + -925, -393, -1274, -600, + -689, -130, -1479, -312, + -1321, -254, -1464, -442, + -1292, -613, -1261, -503, + -1501, -368, -1322, 26, + -1432, -66, -1743, -161, + -1644, -467, -1760, -548, + -1393, -568, -1556, -871, + -1495, -1034, -1387, -571, + -1917, -528, -1783, -123, + -1897, -231, -2054, -323, + -2052, -906, -1976, -567, + -1917, -620, -2047, -989, + -1077, -370, -2031, -704, + -2355, -749, -2740, -1089, + -1909, 159, -2012, 248, + -626, -123, -2339, -962, + -669, -408, -1379, -1174, + -452, -364, -1044, -735, + -132, 183, -1620, -752, + -547, -307, -777, -1261, + -98, 41, -880, -1091, + -257, 97, -1602, -1833, + 31, -26, -644, -561, + -180, -546, -385, -1095, + -410, -802, -414, -827, + -457, -970, -490, -1109, + -215, -916, -144, -937, + -493, -1269, -517, -1507, + 181, 101, -332, -889, + -836, -937, -559, -429, + -629, -547, -183, -337, + -545, -82, -250, -286, + 5, -132, -348, -252, + -293, -472, -158, 100, + -29, 197, -236, -424, + -861, -213, -140, -7, + -427, -443, 187, -97, + -684, -736, -293, 258, + -368, -152, -150, 392, + -609, 175, -142, 299, + -138, 152, -119, 329, + -486, -52, 293, 198, + -183, 117, 175, 331, + -58, -274, 231, 300, + -288, 330, -305, 372, + -111, 409, -9, 423, + 83, 256, 67, 367, + -19, 248, 91, 113, + -35, 406, -191, 154, + 238, 296, 5, 197, + 141, 221, 313, 198, + 211, 421, 244, 334, + 88, 426, -243, 454, + 202, 552, -5, 403, + 291, 185, 219, 301, + 251, 138, 128, 69, + 197, 288, -140, -61, + 188, 361, 197, 598, + 442, 273, 290, 143, + 472, 482, 157, 370, + 415, 321, 372, 385, + 402, 552, 155, 24, + 550, 263, -11, 21, + 360, 227, 147, -254, + 424, 97, 366, -13, + 375, 141, 449, 232, + 396, 507, 474, 272, + 701, 324, 362, -47, + 587, 148, 543, 69, + 400, -51, 561, 59, + 220, -10, 352, 147, + 206, 211, 653, 185, + 563, 297, 565, 284, + 594, 121, 766, 192, + 398, 118, 642, 434, + 233, 264, 481, 467, + 129, -165, 699, 239, + 90, 26, 342, 474, + -55, 27, 388, 94, + -172, 0, 725, 379, + -60, 337, 370, 465, + 95, 319, 806, 595, + 78, 260, 497, 851, + 210, 560, 458, 574, + -464, 202, 497, 625, + -202, 152, 48, 712, + -20, 566, 100, 715, + 455, 468, 411, 605, + 319, 646, 195, 615, + 401, 538, 680, 739, + 201, 667, 434, 954, + 454, 425, 646, 491, + 606, 681, 416, 508, + 497, 822, 426, 815, + 660, 647, 628, 716, + 697, 466, 618, 457, + 685, 460, 365, 309, + 721, 567, 836, 601, + 609, 300, 825, 459, + 943, 687, 681, 533, + 915, 598, 591, 243, + 876, 451, 874, 420, + 786, 317, 732, 220, + 922, 317, 1108, 367, + 531, 466, 1028, 649, + 1053, 615, 1034, 553, + 829, 602, 1021, 799, + 927, 803, 878, 763, + 799, 496, 1373, 773, + 585, 770, 803, 930, + 1099, 793, 1222, 862, + 1209, 895, 1025, 727, + 772, 845, 1172, 1115, + 867, 1021, 830, 1013, + 841, 910, 506, 703, + 1239, 1077, 620, 819, + 1196, 1083, 1155, 1081, + 1142, 907, 1547, 1121, + 1309, 648, 1343, 612, + 1484, 988, 1479, 937, + 985, 1328, 955, 1341, + 429, 910, 841, 1338, + 564, 1179, 412, 1156, + 1427, 1320, 1434, 1330, + 640, 760, 1726, 1410, + 190, 555, 1073, 1005, + 426, 257, 839, 980, + 235, 231, 1520, 1167, + 109, 293, 1014, 1569, + 305, 142, 1148, 539, + -291, -108, 1213, 972, + 22, -216, 667, 828, + -482, 438, 453, 1431, + -581, -422, 789, 387, + -358, -454, 174, 780, + -36, -372, 390, -134, + -629, 160, -306, 751, + -1258, -331, 177, 522, + -248, 574, -251, 639, + -531, 407, -596, 394, + -419, 789, -617, 801, + -986, 399, -857, 727, + -7, 518, -703, 310, + -1143, -24, -1002, 287, + -960, 363, -1299, 312, + -1534, 245, -1557, 305, + 28, 153, -859, -175, + -33, 332, -1398, -154, + 212, 410, -593, -197, + -1092, -704, -904, -65, + 282, 367, -918, -686, + 345, 93, -258, -357, + 696, 644, -693, -28, + 448, 493, -273, 193, + 527, 546, -243, -513, + 384, -136, 273, -353, + 512, -142, 537, -198, + 941, 750, 83, 248, + 578, 861, -56, 592, + 842, 44, 892, 24, + 33, 890, -16, 982, + 831, 1398, 1535, 1898, + 1716, 1376, 1948, 1465 + }; + + const Word16 dico5_lsf_5[DICO5_5_SIZE * 4] = + { + -1002, -929, -1096, -1203, + -641, -931, -604, -961, + -779, -673, -835, -788, + -416, -664, -458, -766, + -652, -521, -662, -495, + -1023, -509, -1023, -428, + -444, -552, -368, -449, + -479, -211, -1054, -903, + -316, -249, -569, -591, + -569, -275, -541, -191, + -716, -188, -842, -264, + -333, -248, -318, -228, + -275, 1, -567, -228, + -115, -221, -238, -374, + -197, -507, -222, -579, + -258, -432, -61, -244, + -345, 2, -338, 39, + -215, -169, -58, 0, + -56, -6, -203, -131, + 1, -186, -5, -211, + 6, -380, 11, -418, + -116, 131, -134, 113, + 89, -4, 71, -2, + -19, -192, 262, 24, + 189, 151, -133, -109, + 186, -153, 166, -219, + 37, 139, 193, 171, + 337, 124, 158, -61, + 141, 226, -13, 190, + 231, 34, 354, 109, + 316, 201, 244, 164, + 330, -85, 390, -84, + 254, 327, 257, 335, + 491, 147, 476, 105, + 54, 77, 437, 370, + 421, 314, 449, 342, + 329, 126, 673, 292, + 571, 388, 243, 193, + 653, 320, 621, 280, + 194, 380, 517, 581, + 45, 323, 111, 422, + 489, 395, 734, 534, + 622, 546, 486, 502, + 318, 572, 189, 550, + 385, 422, -157, 153, + -125, 382, -197, 386, + -263, 334, 228, 697, + -188, 1, 51, 297, + -507, 213, -376, 397, + -24, 255, -547, 89, + -502, -94, 387, 179, + -620, 68, -684, 112, + -642, -350, -260, 172, + -438, -324, 264, 648, + -964, -4, -1121, 7, + -134, 134, -1133, -306, + 143, 96, -420, -497, + -1221, -350, -1527, -685, + -161, 72, 873, 691, + 732, 283, 921, 353, + 334, 475, 1095, 821, + 864, 524, 843, 497, + 714, 711, 788, 750, + 1076, 714, 1204, 753 + }; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] q_plsf_5.tab, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/qua_gain_tbl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/qua_gain_tbl.cpp new file mode 100644 index 00000000..116a1b40 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/qua_gain_tbl.cpp @@ -0,0 +1,363 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: qua_gain_tbl.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "qua_gain_tbl.h" +#include "qua_gain.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + + /* The tables contains the following data: + * + * g_pitch (Q14), + * g_fac (Q12), (g_code = g_code0*g_fac), + * qua_ener_MR122 (Q10), (log2(g_fac)) + * qua_ener (Q10) (20*log10(g_fac)) + * + * The log2() and log10() values are calculated on the fixed point value + * (g_fac Q12) and not on the original floating point value of g_fac + * to make the quantizer/MA predictdor use corresponding values. + */ + + /* table used in 'high' rates: MR67 MR74 */ + + extern const Word16 table_gain_highrates[]; + const Word16 table_gain_highrates[VQ_SIZE_HIGHRATES*4] = + { + + /* + * Note: column 4 (qua_ener) contains the original values from IS641 + * to ensure bit-exactness; however, they are not exactly the + * rounded value of (20*log10(g_fac)) + * + */ + + /*g_pit, g_fac, qua_ener_MR122, qua_ener */ + 577, 662, -2692, -16214, + 806, 1836, -1185, -7135, + 3109, 1052, -2008, -12086, + 4181, 1387, -1600, -9629, + 2373, 1425, -1560, -9394, + 3248, 1985, -1070, -6442, + 1827, 2320, -840, -5056, + 941, 3314, -313, -1885, + 2351, 2977, -471, -2838, + 3616, 2420, -777, -4681, + 3451, 3096, -414, -2490, + 2955, 4301, 72, 434, + 1848, 4500, 139, 836, + 3884, 5416, 413, 2484, + 1187, 7210, 835, 5030, + 3083, 9000, 1163, 7002, + 7384, 883, -2267, -13647, + 5962, 1506, -1478, -8900, + 5155, 2134, -963, -5800, + 7944, 2009, -1052, -6335, + 6507, 2250, -885, -5327, + 7670, 2752, -588, -3537, + 5952, 3016, -452, -2724, + 4898, 3764, -125, -751, + 6989, 3588, -196, -1177, + 8174, 3978, -43, -260, + 6064, 4404, 107, 645, + 7709, 5087, 320, 1928, + 5523, 6021, 569, 3426, + 7769, 7126, 818, 4926, + 6060, 7938, 977, 5885, + 5594, 11487, 1523, 9172, + 10581, 1356, -1633, -9831, + 9049, 1597, -1391, -8380, + 9794, 2035, -1033, -6220, + 8946, 2415, -780, -4700, + 10296, 2584, -681, -4099, + 9407, 2734, -597, -3595, + 8700, 3218, -356, -2144, + 9757, 3395, -277, -1669, + 10177, 3892, -75, -454, + 9170, 4528, 148, 891, + 10152, 5004, 296, 1781, + 9114, 5735, 497, 2993, + 10500, 6266, 628, 3782, + 10110, 7631, 919, 5534, + 8844, 8727, 1117, 6728, + 8956, 12496, 1648, 9921, + 12924, 976, -2119, -12753, + 11435, 1755, -1252, -7539, + 12138, 2328, -835, -5024, + 11388, 2368, -810, -4872, + 10700, 3064, -429, -2580, + 12332, 2861, -530, -3192, + 11722, 3327, -307, -1848, + 11270, 3700, -150, -904, + 10861, 4413, 110, 663, + 12082, 4533, 150, 902, + 11283, 5205, 354, 2132, + 11960, 6305, 637, 3837, + 11167, 7534, 900, 5420, + 12128, 8329, 1049, 6312, + 10969, 10777, 1429, 8604, + 10300, 17376, 2135, 12853, + 13899, 1681, -1316, -7921, + 12580, 2045, -1026, -6179, + 13265, 2439, -766, -4610, + 14033, 2989, -465, -2802, + 13452, 3098, -413, -2482, + 12396, 3658, -167, -1006, + 13510, 3780, -119, -713, + 12880, 4272, 62, 374, + 13533, 4861, 253, 1523, + 12667, 5457, 424, 2552, + 13854, 6106, 590, 3551, + 13031, 6483, 678, 4084, + 13557, 7721, 937, 5639, + 12957, 9311, 1213, 7304, + 13714, 11551, 1532, 9221, + 12591, 15206, 1938, 11667, + 15113, 1540, -1445, -8700, + 15072, 2333, -832, -5007, + 14527, 2511, -723, -4352, + 14692, 3199, -365, -2197, + 15382, 3560, -207, -1247, + 14133, 3960, -50, -300, + 15102, 4236, 50, 298, + 14332, 4824, 242, 1454, + 14846, 5451, 422, 2542, + 15306, 6083, 584, 3518, + 14329, 6888, 768, 4623, + 15060, 7689, 930, 5602, + 14406, 9426, 1231, 7413, + 15387, 9741, 1280, 7706, + 14824, 14271, 1844, 11102, + 13600, 24939, 2669, 16067, + 16396, 1969, -1082, -6517, + 16817, 2832, -545, -3283, + 15713, 2843, -539, -3248, + 16104, 3336, -303, -1825, + 16384, 3963, -49, -294, + 16940, 4579, 165, 992, + 15711, 4599, 171, 1030, + 16222, 5448, 421, 2537, + 16832, 6382, 655, 3945, + 15745, 7141, 821, 4944, + 16326, 7469, 888, 5343, + 16611, 8624, 1100, 6622, + 17028, 10418, 1379, 8303, + 15905, 11817, 1565, 9423, + 16878, 14690, 1887, 11360, + 16515, 20870, 2406, 14483, + 18142, 2083, -999, -6013, + 19401, 3178, -375, -2257, + 17508, 3426, -264, -1589, + 20054, 4027, -25, -151, + 18069, 4249, 54, 326, + 18952, 5066, 314, 1890, + 17711, 5402, 409, 2461, + 19835, 6192, 610, 3676, + 17950, 7014, 795, 4784, + 21318, 7877, 966, 5816, + 17910, 9289, 1210, 7283, + 19144, 9290, 1210, 7284, + 20517, 11381, 1510, 9089, + 18075, 14485, 1866, 11234, + 19999, 17882, 2177, 13108, + 18842, 32764, 3072, 18494 + }; + + + /* table used in 'low' rates: MR475, MR515, MR59 */ + + extern const Word16 table_gain_lowrates[]; + const Word16 table_gain_lowrates[VQ_SIZE_LOWRATES*4] = + { + /*g_pit, g_fac, qua_ener_MR122, qua_ener */ + 10813, 28753, 2879, 17333, + 20480, 2785, -570, -3431, + 18841, 6594, 703, 4235, + 6225, 7413, 876, 5276, + 17203, 10444, 1383, 8325, + 21626, 1269, -1731, -10422, + 21135, 4423, 113, 683, + 11304, 1556, -1430, -8609, + 19005, 12820, 1686, 10148, + 17367, 2498, -731, -4398, + 17858, 4833, 244, 1472, + 9994, 2498, -731, -4398, + 17530, 7864, 964, 5802, + 14254, 1884, -1147, -6907, + 15892, 3153, -387, -2327, + 6717, 1802, -1213, -7303, + 18186, 20193, 2357, 14189, + 18022, 3031, -445, -2678, + 16711, 5857, 528, 3181, + 8847, 4014, -30, -180, + 15892, 8970, 1158, 6972, + 18022, 1392, -1594, -9599, + 16711, 4096, 0, 0, + 8192, 655, -2708, -16305, + 15237, 13926, 1808, 10884, + 14254, 3112, -406, -2444, + 14090, 4669, 193, 1165, + 5406, 2703, -614, -3697, + 13434, 6553, 694, 4180, + 12451, 901, -2237, -13468, + 12451, 2662, -637, -3833, + 3768, 655, -2708, -16305, + 14745, 23511, 2582, 15543, + 19169, 2457, -755, -4546, + 20152, 5079, 318, 1913, + 6881, 4096, 0, 0, + 20480, 8560, 1089, 6556, + 19660, 737, -2534, -15255, + 19005, 4259, 58, 347, + 7864, 2088, -995, -5993, + 11468, 12288, 1623, 9771, + 15892, 1474, -1510, -9090, + 15728, 4628, 180, 1086, + 9175, 1433, -1552, -9341, + 16056, 7004, 793, 4772, + 14827, 737, -2534, -15255, + 15073, 2252, -884, -5321, + 5079, 1228, -1780, -10714, + 13271, 17326, 2131, 12827, + 16547, 2334, -831, -5002, + 15073, 5816, 518, 3118, + 3932, 3686, -156, -938, + 14254, 8601, 1096, 6598, + 16875, 778, -2454, -14774, + 15073, 3809, -107, -646, + 6062, 614, -2804, -16879, + 9338, 9256, 1204, 7251, + 13271, 1761, -1247, -7508, + 13271, 3522, -223, -1343, + 2457, 1966, -1084, -6529, + 11468, 5529, 443, 2668, + 10485, 737, -2534, -15255, + 11632, 3194, -367, -2212, + 1474, 778, -2454, -14774 + }; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] qua_gain.tab, UMTS GSM AMR speech codec, + R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/r_fft.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/r_fft.cpp new file mode 100644 index 00000000..ada38658 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/r_fft.cpp @@ -0,0 +1,573 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: r_fft.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" +#include "oper_32b.h" +#include "vad2.h" +#include "sub.h" +#include "add.h" +#include "shr.h" +#include "shl.h" + +//#include "l_mult.h" +//#include "l_mac.h" +//#include "l_msu.h" + +#include "round.h" +#include "l_negate.h" +//lhc +#include "l_deposit_h.h" +#include "l_shr.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define SIZE 128 +#define SIZE_BY_TWO 64 +#define NUM_STAGE 6 +#define TRUE 1 +#define FALSE 0 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +const Word16 phs_tbl[] = +{ + + 32767, 0, 32729, -1608, 32610, -3212, 32413, -4808, + 32138, -6393, 31786, -7962, 31357, -9512, 30853, -11039, + 30274, -12540, 29622, -14010, 28899, -15447, 28106, -16846, + 27246, -18205, 26320, -19520, 25330, -20788, 24279, -22006, + 23170, -23170, 22006, -24279, 20788, -25330, 19520, -26320, + 18205, -27246, 16846, -28106, 15447, -28899, 14010, -29622, + 12540, -30274, 11039, -30853, 9512, -31357, 7962, -31786, + 6393, -32138, 4808, -32413, 3212, -32610, 1608, -32729, + 0, -32768, -1608, -32729, -3212, -32610, -4808, -32413, + -6393, -32138, -7962, -31786, -9512, -31357, -11039, -30853, + -12540, -30274, -14010, -29622, -15447, -28899, -16846, -28106, + -18205, -27246, -19520, -26320, -20788, -25330, -22006, -24279, + -23170, -23170, -24279, -22006, -25330, -20788, -26320, -19520, + -27246, -18205, -28106, -16846, -28899, -15447, -29622, -14010, + -30274, -12540, -30853, -11039, -31357, -9512, -31786, -7962, + -32138, -6393, -32413, -4808, -32610, -3212, -32729, -1608 + +}; + +const Word16 ii_table[] = + {SIZE / 2, SIZE / 4, SIZE / 8, SIZE / 16, SIZE / 32, SIZE / 64}; + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: c_fft +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + farray_ptr = pointer to complex array that the FFT operates on of type + Word16. + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow = 1 if the math functions called by cor_h_x2 result in overflow + else zero. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This is an implementation of decimation-in-time FFT algorithm for + real sequences. The techniques used here can be found in several + books, e.g., i) Proakis and Manolakis, "Digital Signal Processing", + 2nd Edition, Chapter 9, and ii) W.H. Press et. al., "Numerical + Recipes in C", 2nd Ediiton, Chapter 12. + + Input - There is one input to this function: + + 1) An integer pointer to the input data array + + Output - There is no return value. + The input data are replaced with transformed data. If the + input is a real time domain sequence, it is replaced with + the complex FFT for positive frequencies. The FFT value + for DC and the foldover frequency are combined to form the + first complex number in the array. The remaining complex + numbers correspond to increasing frequencies. If the input + is a complex frequency domain sequence arranged as above, + it is replaced with the corresponding time domain sequence. + + Notes: + + 1) This function is designed to be a part of a VAD + algorithm that requires 128-point FFT of real + sequences. This is achieved here through a 64-point + complex FFT. Consequently, the FFT size information is + not transmitted explicitly. However, some flexibility + is provided in the function to change the size of the + FFT by specifying the size information through "define" + statements. + + 2) The values of the complex sinusoids used in the FFT + algorithm are stored in a ROM table. + + 3) In the c_fft function, the FFT values are divided by + 2 after each stage of computation thus dividing the + final FFT values by 64. This is somewhat different + from the usual definition of FFT where the factor 1/N, + i.e., 1/64, used for the IFFT and not the FFT. No factor + is used in the r_fft function. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + r_fft.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +The original etsi reference code uses a global flag Overflow. However, in the +actual implementation a pointer to a the overflow flag is passed in. + +void c_fft(Word16 * farray_ptr) +{ + Word16 i, j, k, ii, jj, kk, ji, kj, ii2; + Word32 ftmp, ftmp_real, ftmp_imag; + Word16 tmp, tmp1, tmp2; + + // Rearrange the input array in bit reversed order + for (i = 0, j = 0; i < SIZE - 2; i = i + 2) + { + if (sub(j, i) > 0) + { + ftmp = *(farray_ptr + i); + *(farray_ptr + i) = *(farray_ptr + j); + *(farray_ptr + j) = ftmp; + + ftmp = *(farray_ptr + i + 1); + *(farray_ptr + i + 1) = *(farray_ptr + j + 1); + *(farray_ptr + j + 1) = ftmp; + } + + k = SIZE_BY_TWO; + while (sub(j, k) >= 0) + { + j = sub(j, k); + k = shr(k, 1); + } + j = add(j, k); + } + + // The FFT part + for (i = 0; i < NUM_STAGE; i++) + { // i is stage counter + jj = shl(2, i); // FFT size + kk = shl(jj, 1); // 2 * FFT size + ii = ii_table[i]; // 2 * number of FFT's + ii2 = shl(ii, 1); + ji = 0; // ji is phase table index + + for (j = 0; j < jj; j = j + 2) + { // j is sample counter + + for (k = j; k < SIZE; k = k + kk) + { // k is butterfly top + kj = add(k, jj); // kj is butterfly bottom + + // Butterfly computations + ftmp_real = L_mult(*(farray_ptr + kj), phs_tbl[ji]); + ftmp_real = L_msu(ftmp_real, *(farray_ptr + kj + 1), phs_tbl[ji + 1]); + + ftmp_imag = L_mult(*(farray_ptr + kj + 1), phs_tbl[ji]); + ftmp_imag = L_mac(ftmp_imag, *(farray_ptr + kj), phs_tbl[ji + 1]); + + tmp1 = pv_round(ftmp_real); + tmp2 = pv_round(ftmp_imag); + + tmp = sub(*(farray_ptr + k), tmp1); + *(farray_ptr + kj) = shr(tmp, 1); + + tmp = sub(*(farray_ptr + k + 1), tmp2); + *(farray_ptr + kj + 1) = shr(tmp, 1); + + tmp = add(*(farray_ptr + k), tmp1); + *(farray_ptr + k) = shr(tmp, 1); + + tmp = add(*(farray_ptr + k + 1), tmp2); + *(farray_ptr + k + 1) = shr(tmp, 1); + } + + ji = add(ji, ii2); + } + } +} // end of c_fft () + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/* FFT function for complex sequences */ +/* + * The decimation-in-time complex FFT is implemented below. + * The input complex numbers are presented as real part followed by + * imaginary part for each sample. The counters are therefore + * incremented by two to access the complex valued samples. + */ + +void c_fft(Word16 * farray_ptr, Flag *pOverflow) +{ + + Word16 i; + Word16 j; + Word16 k; + Word16 ii; + Word16 jj; + Word16 kk; + Word16 ji; + Word16 kj; + Word16 ii2; + Word32 ftmp; + Word32 ftmp_real; + Word32 ftmp_imag; + Word16 tmp; + Word16 tmp1; + Word16 tmp2; + + /* Rearrange the input array in bit reversed order */ + for (i = 0, j = 0; i < SIZE - 2; i = i + 2) + { + if (j > i) + { + ftmp = *(farray_ptr + i); + *(farray_ptr + i) = *(farray_ptr + j); + *(farray_ptr + j) = (Word16)ftmp; + + ftmp = *(farray_ptr + i + 1); + *(farray_ptr + i + 1) = *(farray_ptr + j + 1); + *(farray_ptr + j + 1) = (Word16)ftmp; + } + + k = SIZE_BY_TWO; + while (j >= k) + { + j = sub(j, k, pOverflow); + k = shr(k, 1, pOverflow); + } + j = add(j, k, pOverflow); + } + + /* The FFT part */ + for (i = 0; i < NUM_STAGE; i++) + { /* i is stage counter */ + jj = shl(2, i, pOverflow); /* FFT size */ + kk = shl(jj, 1, pOverflow); /* 2 * FFT size */ + ii = ii_table[i]; /* 2 * number of FFT's */ + ii2 = shl(ii, 1, pOverflow); + ji = 0; /* ji is phase table index */ + + for (j = 0; j < jj; j = j + 2) + { /* j is sample counter */ + + for (k = j; k < SIZE; k = k + kk) + { /* k is butterfly top */ + kj = add(k, jj, pOverflow); /* kj is butterfly bottom */ + + /* Butterfly computations */ + ftmp_real = L_mult(*(farray_ptr + kj), phs_tbl[ji], pOverflow); + ftmp_real = L_msu(ftmp_real, *(farray_ptr + kj + 1), + phs_tbl[ji + 1], pOverflow); + + ftmp_imag = L_mult(*(farray_ptr + kj + 1), + phs_tbl[ji], pOverflow); + ftmp_imag = L_mac(ftmp_imag, *(farray_ptr + kj), + phs_tbl[ji + 1], pOverflow); + + tmp1 = pv_round(ftmp_real, pOverflow); + tmp2 = pv_round(ftmp_imag, pOverflow); + + tmp = sub(*(farray_ptr + k), tmp1, pOverflow); + *(farray_ptr + kj) = shr(tmp, 1, pOverflow); + + tmp = sub(*(farray_ptr + k + 1), tmp2, pOverflow); + *(farray_ptr + kj + 1) = shr(tmp, 1, pOverflow); + + tmp = add(*(farray_ptr + k), tmp1, pOverflow); + *(farray_ptr + k) = shr(tmp, 1, pOverflow); + + tmp = add(*(farray_ptr + k + 1), tmp2, pOverflow); + *(farray_ptr + k + 1) = shr(tmp, 1, pOverflow); + } + + ji = add(ji, ii2, pOverflow); + } + } +} /* end of c_fft () */ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: r_fft +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + farray_ptr = pointer to complex array that the FFT operates on of type + Word16. + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow = 1 if the math functions called by cor_h_x2 result in overflow + else zero. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This is an implementation of decimation-in-time FFT algorithm for + real sequences. The techniques used here can be found in several + books, e.g., i) Proakis and Manolakis, "Digital Signal Processing", + 2nd Edition, Chapter 9, and ii) W.H. Press et. al., "Numerical + Recipes in C", 2nd Ediiton, Chapter 12. + + Input - There is one input to this function: + + 1) An integer pointer to the input data array + + Output - There is no return value. + The input data are replaced with transformed data. If the + input is a real time domain sequence, it is replaced with + the complex FFT for positive frequencies. The FFT value + for DC and the foldover frequency are combined to form the + first complex number in the array. The remaining complex + numbers correspond to increasing frequencies. If the input + is a complex frequency domain sequence arranged as above, + it is replaced with the corresponding time domain sequence. + + Notes: + + 1) This function is designed to be a part of a VAD + algorithm that requires 128-point FFT of real + sequences. This is achieved here through a 64-point + complex FFT. Consequently, the FFT size information is + not transmitted explicitly. However, some flexibility + is provided in the function to change the size of the + FFT by specifying the size information through "define" + statements. + + 2) The values of the complex sinusoids used in the FFT + algorithm are stored in a ROM table. + + 3) In the c_fft function, the FFT values are divided by + 2 after each stage of computation thus dividing the + final FFT values by 64. This is somewhat different + from the usual definition of FFT where the factor 1/N, + i.e., 1/64, used for the IFFT and not the FFT. No factor + is used in the r_fft function. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + r_fft.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +The original etsi reference code uses a global flag Overflow. However, in the +actual implementation a pointer to a the overflow flag is passed in. + +void r_fft(Word16 * farray_ptr) +{ + + Word16 ftmp1_real, ftmp1_imag, ftmp2_real, ftmp2_imag; + Word32 Lftmp1_real, Lftmp1_imag; + Word16 i, j; + Word32 Ltmp1; + + // Perform the complex FFT + c_fft(farray_ptr); + + // First, handle the DC and foldover frequencies + ftmp1_real = *farray_ptr; + ftmp2_real = *(farray_ptr + 1); + *farray_ptr = add(ftmp1_real, ftmp2_real); + *(farray_ptr + 1) = sub(ftmp1_real, ftmp2_real); + + // Now, handle the remaining positive frequencies + for (i = 2, j = SIZE - i; i <= SIZE_BY_TWO; i = i + 2, j = SIZE - i) + { + ftmp1_real = add(*(farray_ptr + i), *(farray_ptr + j)); + ftmp1_imag = sub(*(farray_ptr + i + 1), *(farray_ptr + j + 1)); + ftmp2_real = add(*(farray_ptr + i + 1), *(farray_ptr + j + 1)); + ftmp2_imag = sub(*(farray_ptr + j), *(farray_ptr + i)); + + Lftmp1_real = L_deposit_h(ftmp1_real); + Lftmp1_imag = L_deposit_h(ftmp1_imag); + + Ltmp1 = L_mac(Lftmp1_real, ftmp2_real, phs_tbl[i]); + Ltmp1 = L_msu(Ltmp1, ftmp2_imag, phs_tbl[i + 1]); + *(farray_ptr + i) = pv_round(L_shr(Ltmp1, 1)); + + Ltmp1 = L_mac(Lftmp1_imag, ftmp2_imag, phs_tbl[i]); + Ltmp1 = L_mac(Ltmp1, ftmp2_real, phs_tbl[i + 1]); + *(farray_ptr + i + 1) = pv_round(L_shr(Ltmp1, 1)); + + Ltmp1 = L_mac(Lftmp1_real, ftmp2_real, phs_tbl[j]); + Ltmp1 = L_mac(Ltmp1, ftmp2_imag, phs_tbl[j + 1]); + *(farray_ptr + j) = pv_round(L_shr(Ltmp1, 1)); + + Ltmp1 = L_negate(Lftmp1_imag); + Ltmp1 = L_msu(Ltmp1, ftmp2_imag, phs_tbl[j]); + Ltmp1 = L_mac(Ltmp1, ftmp2_real, phs_tbl[j + 1]); + *(farray_ptr + j + 1) = pv_round(L_shr(Ltmp1, 1)); + + } +} // end r_fft () + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/* FFT function for complex sequences */ +/* + * The decimation-in-time complex FFT is implemented below. + * The input complex numbers are presented as real part followed by + * imaginary part for each sample. The counters are therefore + * incremented by two to access the complex valued samples. + */ +void r_fft(Word16 * farray_ptr, Flag *pOverflow) +{ + + Word16 ftmp1_real; + Word16 ftmp1_imag; + Word16 ftmp2_real; + Word16 ftmp2_imag; + Word32 Lftmp1_real; + Word32 Lftmp1_imag; + Word16 i; + Word16 j; + Word32 Ltmp1; + + /* Perform the complex FFT */ + c_fft(farray_ptr, pOverflow); + + /* First, handle the DC and foldover frequencies */ + ftmp1_real = *farray_ptr; + ftmp2_real = *(farray_ptr + 1); + *farray_ptr = add(ftmp1_real, ftmp2_real, pOverflow); + *(farray_ptr + 1) = sub(ftmp1_real, ftmp2_real, pOverflow); + + /* Now, handle the remaining positive frequencies */ + for (i = 2, j = SIZE - i; i <= SIZE_BY_TWO; i = i + 2, j = SIZE - i) + { + ftmp1_real = add(*(farray_ptr + i), *(farray_ptr + j), pOverflow); + ftmp1_imag = sub(*(farray_ptr + i + 1), + *(farray_ptr + j + 1), pOverflow); + ftmp2_real = add(*(farray_ptr + i + 1), + *(farray_ptr + j + 1), pOverflow); + ftmp2_imag = sub(*(farray_ptr + j), + *(farray_ptr + i), pOverflow); + + Lftmp1_real = L_deposit_h(ftmp1_real); + Lftmp1_imag = L_deposit_h(ftmp1_imag); + + Ltmp1 = L_mac(Lftmp1_real, ftmp2_real, phs_tbl[i], pOverflow); + Ltmp1 = L_msu(Ltmp1, ftmp2_imag, phs_tbl[i + 1], pOverflow); + *(farray_ptr + i) = pv_round(L_shr(Ltmp1, 1, pOverflow), pOverflow); + + Ltmp1 = L_mac(Lftmp1_imag, ftmp2_imag, phs_tbl[i], pOverflow); + Ltmp1 = L_mac(Ltmp1, ftmp2_real, phs_tbl[i + 1], pOverflow); + *(farray_ptr + i + 1) = pv_round(L_shr(Ltmp1, 1, pOverflow), pOverflow); + + Ltmp1 = L_mac(Lftmp1_real, ftmp2_real, phs_tbl[j], pOverflow); + Ltmp1 = L_mac(Ltmp1, ftmp2_imag, phs_tbl[j + 1], pOverflow); + *(farray_ptr + j) = pv_round(L_shr(Ltmp1, 1, pOverflow), pOverflow); + + Ltmp1 = L_negate(Lftmp1_imag); + Ltmp1 = L_msu(Ltmp1, ftmp2_imag, phs_tbl[j], pOverflow); + Ltmp1 = L_mac(Ltmp1, ftmp2_real, phs_tbl[j + 1], pOverflow); + *(farray_ptr + j + 1) = pv_round(L_shr(Ltmp1, 1, pOverflow), pOverflow); + + } +} /* end r_fft () */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/reorder.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/reorder.cpp new file mode 100644 index 00000000..0f932e5b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/reorder.cpp @@ -0,0 +1,168 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: reorder.cpp + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "reorder.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Reorder_lsf +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsf = vector of LSFs (range: 0<=val<=0.5)(Word16) + min_dist = minimum required distance (Word16) + n = LPC order (Word16) + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the add operation called by Reorder_lsf() results in + overflow + lsf -> reordered vector of LSFs (Word16) + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function makes sure that the LSFs are properly ordered keeps a certain + minimum distance between adjacent LSFs. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] reorder.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Reorder_lsf ( + Word16 *lsf, // (i/o) : vector of LSFs (range: 0<=val<=0.5) + Word16 min_dist, // (i) : minimum required distance + Word16 n // (i) : LPC order +) +{ + Word16 i; + Word16 lsf_min; + +// The reference ETSI code uses a global flag for Overflow. In the actual +// implementation a pointer to Overflow flag is passed into the function +// for use by the math functions add() and sub() + + lsf_min = min_dist; + for (i = 0; i < n; i++) + { + if (sub (lsf[i], lsf_min) < 0) + { + lsf[i] = lsf_min; + } + lsf_min = add (lsf[i], min_dist); + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +OSCL_EXPORT_REF void Reorder_lsf( + Word16 *lsf, /* (i/o) : vector of LSFs (range: 0<=val<=0.5) */ + Word16 min_dist, /* (i) : minimum required distance */ + Word16 n, /* (i) : LPC order */ + Flag *pOverflow /* (i/o) : Overflow flag */ +) +{ + Word16 i; + Word16 lsf_min; + Word16 *p_lsf = &lsf[0]; + OSCL_UNUSED_ARG(pOverflow); + + lsf_min = min_dist; + for (i = 0; i < n; i++) + { + if (*(p_lsf) < lsf_min) + { + *(p_lsf++) = lsf_min; + lsf_min += min_dist; + } + else + { + lsf_min = *(p_lsf++) + min_dist; + } + } +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/residu.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/residu.cpp new file mode 100644 index 00000000..787e043c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/residu.cpp @@ -0,0 +1,205 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: residu.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "residu.h" +#include "typedef.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Residu +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + coef_ptr = pointer to buffer containing the prediction coefficients + input_ptr = pointer to buffer containing the speech signal + input_len = filter order + residual_ptr = pointer to buffer of residual signal + + Outputs: + residual_ptr buffer contains the newly calculated the residual signal + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes the LP residual by filtering the input speech through + the LP inverse filter A(z). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + residu.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Note: Input argument names were changed to be more descriptive. Shown below + are the original names. Shown below are the name changes: + a[] <--> coef_ptr[] + x[] <--> input_ptr[] + y[] <--> residual_ptr[] + lg <--> input_len + + +void Residu ( + Word16 a[], // (i) : prediction coefficients + Word16 x[], // (i) : speech signal + Word16 y[], // (o) : residual signal + Word16 lg // (i) : size of filtering +) +{ + Word16 i, j; + Word32 s; + + for (i = 0; i < lg; i++) + { + s = L_mult (x[i], a[0]); + for (j = 1; j <= M; j++) + { + s = L_mac (s, a[j], x[i - j]); + } + s = L_shl (s, 3); + y[i] = pv_round (s); + } + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void Residu( + Word16 coef_ptr[], /* (i) : prediction coefficients*/ + Word16 input_ptr[], /* (i) : speech signal */ + Word16 residual_ptr[], /* (o) : residual signal */ + Word16 input_len /* (i) : size of filtering */ +) +{ + + + register Word16 i, j; + Word32 s1; + Word32 s2; + Word32 s3; + Word32 s4; + Word16 *p_input1; + Word16 *p_input2; + Word16 *p_input3; + Word16 *p_input4; + Word16 *p_coef; + Word16 *p_residual_ptr = &residual_ptr[input_len-1]; + Word16 *p_input_ptr = &input_ptr[input_len-1-M]; + + for (i = input_len >> 2; i != 0; i--) + { + s1 = 0x0000800L; + s2 = 0x0000800L; + s3 = 0x0000800L; + s4 = 0x0000800L; + p_coef = &coef_ptr[M]; + p_input1 = p_input_ptr--; + p_input2 = p_input_ptr--; + p_input3 = p_input_ptr--; + p_input4 = p_input_ptr--; + + for (j = M >> 1; j != 0; j--) + { + s1 += ((Word32) * (p_coef) * *(p_input1++)); + s2 += ((Word32) * (p_coef) * *(p_input2++)); + s3 += ((Word32) * (p_coef) * *(p_input3++)); + s4 += ((Word32) * (p_coef--) * *(p_input4++)); + s1 += ((Word32) * (p_coef) * *(p_input1++)); + s2 += ((Word32) * (p_coef) * *(p_input2++)); + s3 += ((Word32) * (p_coef) * *(p_input3++)); + s4 += ((Word32) * (p_coef--) * *(p_input4++)); + } + + s1 += (((Word32) * (p_coef)) * *(p_input1)); + s2 += (((Word32) * (p_coef)) * *(p_input2)); + s3 += (((Word32) * (p_coef)) * *(p_input3)); + s4 += (((Word32) * (p_coef)) * *(p_input4)); + + *(p_residual_ptr--) = (Word16)(s1 >> 12); + *(p_residual_ptr--) = (Word16)(s2 >> 12); + *(p_residual_ptr--) = (Word16)(s3 >> 12); + *(p_residual_ptr--) = (Word16)(s4 >> 12); + + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/round.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/round.cpp new file mode 100644 index 00000000..9fd4abb4 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/round.cpp @@ -0,0 +1,152 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: round.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Rounding function with saturation. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: pv_round +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + None + + Returns: + result = MS 16 bits of rounded input L_var1. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function rounds the lower 16 bits of the 32 bit input number into the + MS 16 bits with saturation. Shift the resulting bits right by 16 and return + the 16 bit number: + pv_round(L_var1) = extract_h(L_add(L_var1,32768)) + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] round() function in basic_op2.c, UMTS GSM AMR speech codec, R99 - + Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 pv_round (Word32 L_var1) +{ + Word16 var_out; + Word32 L_rounded; + +* The reference ETSI code uses a global flag for Overflow in the L_add() function. +* In the actual implementation a pointer to Overflow flag is passed in as a +* parameter to the function. + + L_rounded = L_add (L_var1, (Word32) 0x00008000L); +#if (WMOPS) + multiCounter[currCounter].L_add--; +#endif + var_out = extract_h (L_rounded); +#if (WMOPS) + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].round++; +#endif + return (var_out); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +OSCL_EXPORT_REF Word16 pv_round(register Word32 L_var1, Flag *pOverflow) +{ + Word16 result; + + L_var1 = L_add(L_var1, (Word32) 0x00008000L, pOverflow); + result = (Word16)(L_var1 >> 16); + + return (result); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/set_zero.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/set_zero.cpp new file mode 100644 index 00000000..be23b254 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/set_zero.cpp @@ -0,0 +1,74 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : set_zero.h +* +******************************************************************************** +*/ +/* +******************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +******************************************************************************** +*/ +#include "set_zero.h" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" +#include "basic_op.h" + +/* +******************************************************************************** +* PUBLIC PROGRAM CODE +******************************************************************************** +*/ +void Set_zero( + Word16 x[], /* (o) : vector to clear */ + Word16 L /* (i) : length of vector */ +) +{ + Word16 i; + + for (i = 0; i < L; i++) + { + x[i] = 0; + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/shr.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/shr.cpp new file mode 100644 index 00000000..a0fbd352 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/shr.cpp @@ -0,0 +1,201 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: shr.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + Shift right function with overflow control +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: shr +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the shift operation resulted in overflow + + Returns: + product = Shifted result limited to 16 bits (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function arithmetically shifts the 16 bit input var1 right var2 positions + with sign extension. If var2 is negative, arithmetically shift var1 left by + -var2 with sign extension. Saturate the result in case of underflows or + overflows. + +------------------------------------------------------------------------------ + REQUIREMENTS + None +------------------------------------------------------------------------------ + REFERENCES + + [1] shr() function in basic_op2.c, UMTS GSM AMR speech codec, R99 - + Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 shr_std (Word16 var1, Word16 var2) +{ + Word16 var_out; + + if (var2 < 0) + { + if (var2 < -16) + var2 = -16; + var_out = shl_std (var1, -var2); +#if (WMOPS) + mult_stdiCounter[currCounter].shl_std--; +#endif + } + else + { + if (var2 >= 15) + { + var_out = (var1 < 0) ? -1 : 0; + } + else + { + if (var1 < 0) + { + var_out = ~((~var1) >> var2); + } + else + { + var_out = var1 >> var2; + } + } + } + +#if (WMOPS) + mult_stdiCounter[currCounter].shr_std++; +#endif + return (var_out); +} +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +OSCL_EXPORT_REF Word16 shr(register Word16 var1, register Word16 var2, Flag *pOverflow) +{ + register Word16 result; + + if (var2 != 0) + { + if (var2 > 0) + { + if (var2 > 15) + { + var2 = 15; + } + + result = var1 >> var2; + + } + else + { + var2 = -var2; /* Shift right negative is equivalent */ + + if (var2 > 15) + { + var2 = 15; + } + + result = (var1 << var2); + if ((result >> var2) != var1) + { + *pOverflow = 1; + result = ((var1 > 0) ? MAX_16 : MIN_16); + } + } + + } + else + { + result = var1; + } + + return (result); +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/shr_r.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/shr_r.cpp new file mode 100644 index 00000000..b4038852 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/shr_r.cpp @@ -0,0 +1,193 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: shr_r.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + var_out = shifted input w/ rounding (Word16) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function arithmetically shifts the 16 bit input var1 right var2 positions + with rounding. If var2 is negative, arithmetically shift var1 left by + -var2 with rounding. Saturate the result in case of underflows or + overflows. + + - If var2 is greater than zero : + if (sub(shl(shr(var1,var2),1),shr(var1,sub(var2,1)))) + is equal to zero + then + shr_r(var1,var2) = shr(var1,var2) + else + shr_r(var1,var2) = add(shr(var1,var2),1) + - If var2 is less than or equal to zero : + shr_r(var1,var2) = shr(var1,var2). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 shr_r (Word16 var1, Word16 var2) +{ + Word16 var_out; + + if (var2 > 15) + { + var_out = 0; + } + else + { + var_out = shr (var1, var2); +#if (WMOPS) + multiCounter[currCounter].shr--; +#endif + + if (var2 > 0) + { + if ((var1 & ((Word16) 1 << (var2 - 1))) != 0) + { + var_out++; + } + } + } +#if (WMOPS) + multiCounter[currCounter].shr_r++; +#endif + return (var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +OSCL_EXPORT_REF Word16 shr_r(register Word16 var1, register Word16 var2, Flag *pOverflow) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + Word16 var_out; + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + if (var2 > 15) + { + var_out = 0; + } + else + { + var_out = shr(var1, var2, pOverflow); + if (var2 > 0) + { + if ((var1 & ((Word16) 1 << (var2 - 1))) != 0) + { + var_out++; + } + } + } + + /*---------------------------------------------------------------------------- + ; Return nothing or data or data pointer + ----------------------------------------------------------------------------*/ + return (var_out); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/sqrt_l.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/sqrt_l.cpp new file mode 100644 index 00000000..60383883 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/sqrt_l.cpp @@ -0,0 +1,235 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: sqrt_l.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "sqrt_l.h" +#include "typedef.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: sqrt_l_exp +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_x = input value (Word32) + pExp = pointer to right shift to be applied to result + pOverflow = pointer to overflow flag + + Outputs: + pOverflow -> if the Inv_sqrt operation resulted in an overflow. + + Returns: + L_y = squareroot of L_x (Word32) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes sqrt(L_x), where L_x is positive. + If L_var is negative or zero, the result is 0 + + The function sqrt(L_x) is approximated by a table and linear + interpolation. The square root is computed using the + following steps: + 1- Normalization of L_x. + 2- If exponent is even then shift right once. + 3- exponent = exponent/2 + 4- i = bit25-b31 of L_x; 16<=i<=63 because of normalization. + 5- a = bit10-b24 + 6- i -=16 + 7- L_y = table[i]<<16 - (table[i] - table[i+1]) * a * 2 + 8- return L_y and exponent so caller can do denormalization + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + sqrt_l.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word32 sqrt_l_exp ( // o : output value + Word32 L_x, // i : input value + Word16 *exp // o : right shift to be applied to result +) +{ + +// y = sqrt(x) +// x = f * 2^-e, 0.5 <= f < 1 (normalization) +// y = sqrt(f) * 2^(-e/2) +// +// a) e = 2k --> y = sqrt(f) * 2^-k (k = e div 2, +// 0.707 <= sqrt(f) < 1) +// b) e = 2k+1 --> y = sqrt(f/2) * 2^-k (k = e div 2, + 0.5 <= sqrt(f/2) < 0.707) + + + Word16 e, i, a, tmp; + Word32 L_y; + + if (L_x <= (Word32) 0) + { + *exp = 0; + return (Word32) 0; + } + +* The reference ETSI code uses a global Overflow flag. In the actual +* implementation a pointer to the overflow flag is passed into the function. +* This pointer is in turn passed into the basic math functions such as add(), +* L_shl(), L_shr(), sub() called by this module. + + e = norm_l (L_x) & 0xFFFE; // get next lower EVEN norm. exp + L_x = L_shl (L_x, e); // L_x is normalized to [0.25..1) + *exp = e; // return 2*exponent (or Q1) + + L_x = L_shr (L_x, 9); + i = extract_h (L_x); // Extract b25-b31, 16 <= i <= 63 + because of normalization + L_x = L_shr (L_x, 1); + a = extract_l (L_x); // Extract b10-b24 + a = a & (Word16) 0x7fff; + + i = sub (i, 16); // 0 <= i <= 47 + + L_y = L_deposit_h (table[i]); // table[i] << 16 + tmp = sub (table[i], table[i + 1]); // table[i] - table[i+1]) + L_y = L_msu (L_y, tmp, a); // L_y -= tmp*a*2 + + return (L_y); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF Word32 sqrt_l_exp( /* o : output value, Q31 */ + Word32 L_x, /* i : input value, Q31 */ + Word16 *pExp, /* o : right shift to be applied to result, Q1 */ + Flag *pOverflow /* i : pointer to overflow flag */ +) + +{ + Word16 e; + Word16 i; + Word16 a; + Word16 tmp; + Word32 L_y; + + /* + y = sqrt(x) + x = f * 2^-e, 0.5 <= f < 1 (normalization) + y = sqrt(f) * 2^(-e/2) + a) e = 2k --> y = sqrt(f) * 2^-k (k = e div 2, + 0.707 <= sqrt(f) < 1) + b) e = 2k+1 --> y = sqrt(f/2) * 2^-k (k = e div 2, + 0.5 <= sqrt(f/2) < 0.707) + */ + + if (L_x <= (Word32) 0) + { + *pExp = 0; + return (Word32) 0; + } + + e = norm_l(L_x) & 0xFFFE; /* get next lower EVEN norm. exp */ + L_x = L_shl(L_x, e, pOverflow); /* L_x is normalized to [0.25..1) */ + *pExp = e; /* return 2*exponent (or Q1) */ + + L_x >>= 10; + i = (Word16)(L_x >> 15) & 63; /* Extract b25-b31, 16<= i <=63 */ + /* because of normalization */ + + a = (Word16)(L_x); /* Extract b10-b24 */ + a &= (Word16) 0x7fff; + + if (i > 15) + { + i -= 16; /* 0 <= i <= 47 */ + } + + L_y = ((Word32) sqrt_l_tbl[i] << 16); /* sqrt_l_tbl[i] << 16 */ + + /* sqrt_l_tbl[i] - sqrt_l_tbl[i+1]) */ + tmp = sqrt_l_tbl[i] - sqrt_l_tbl[i + 1]; + + L_y = L_msu(L_y, tmp, a, pOverflow); /* L_y -= tmp*a*2 */ + + /* L_y = L_shr (L_y, *exp); */ /* denormalization done by caller */ + + return (L_y); +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/sqrt_l_tbl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/sqrt_l_tbl.cpp new file mode 100644 index 00000000..8b91771b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/sqrt_l_tbl.cpp @@ -0,0 +1,141 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: sqrt_l_tbl.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the declaration for sqrt_l_table[] used by the sqrt_l_exp + function. + + sqrt_l_tbl[i] = sqrt((i+16)*2^-6) * 2^15, i.e. sqrt(x) scaled Q15 + + ------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "sqrt_l.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + const Word16 sqrt_l_tbl[50] = + { + 16384, 16888, 17378, 17854, 18318, 18770, 19212, 19644, 20066, 20480, + 20886, 21283, 21674, 22058, 22435, 22806, 23170, 23530, 23884, 24232, + 24576, 24915, 25249, 25580, 25905, 26227, 26545, 26859, 27170, 27477, + 27780, 28081, 28378, 28672, 28963, 29251, 29537, 29819, 30099, 30377, + 30652, 30924, 31194, 31462, 31727, 31991, 32252, 32511, 32767, 32767 + }; + + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] inv_sqrt.tab file, UMTS GSM AMR speech codec, R99 - Version 3.2.0, + March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/sub.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/sub.cpp new file mode 100644 index 00000000..479c40e2 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/sub.cpp @@ -0,0 +1,176 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: sub.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Subtraction function with overflow control + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: sub +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + var1 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 = 16 bit short signed integer (Word16) whose value falls in + the range : 0xffff 8000 <= var2 <= 0x0000 7fff. + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the subtract operation resulted in overflow + + Returns: + diff = 16-bit limited difference between var1 and var2 (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the subtraction (var1-var2) with overflow control and + saturation; the 16 bit result is set at +32767 when overflow occurs or at + -32768 when underflow occurs. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] sub() function in basicop2.c, UMTS GSM AMR speech codec, R99 - + Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + + PSEUDO-CODE + + Word16 sub (Word16 var1, Word16 var2) + { + Word16 var_out; + Word32 diff; + + diff = (Word32) var1 - var2; + +* The reference ETSI code uses a global flag for Overflow inside the function +* saturate(). In the actual implementation a pointer to Overflow flag is passed +* in as a parameter to the function + + var_out = saturate (diff); + + #if (WMOPS) + multiCounter[currCounter].sub++; + #endif + + return (var_out); + } + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +OSCL_EXPORT_REF Word16 sub(Word16 var1, Word16 var2, Flag *pOverflow) +{ + + Word32 diff; + + diff = (Word32) var1 - var2; + + /* Saturate result (if necessary). */ + /* Replaced function call with in-line code */ + /* to conserve MIPS, i.e., var_out = saturate (diff) */ + + + if ((UWord32)(diff + 32768) > 0x000FFFF) + { + if (diff > (Word32) 0x0007FFFL) + { + diff = MAX_16; + } + else + { + diff = MIN_16; + } + + *pOverflow = 1; + } + + + return ((Word16) diff); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/syn_filt.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/syn_filt.cpp new file mode 100644 index 00000000..e84ee66b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/syn_filt.cpp @@ -0,0 +1,325 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: syn_filt.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "syn_filt.h" +#include "cnst.h" +#include "basic_op.h" +#include "oscl_mem.h" + +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Syn_filt +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + a = buffer containing the prediction coefficients (Word16) max 2^12 + x = input signal buffer (Word16) max 2^15 + y = output signal buffer (Word16) + lg = size of filtering (Word16) + mem = memory buffer associated with this filtering (Word16) + update = flag to indicate memory update; 0=no update, 1=update memory + (Word16) + + Outputs: + mem buffer is changed to be the last M data points of the output signal + if update was set to 1 + y buffer contains the newly calculated filter output + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Perform synthesis filtering through 1/A(z) + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + syn_filt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Syn_filt ( + Word16 a[], // (i) : a[M+1] prediction coefficients (M=10) + Word16 x[], // (i) : input signal + Word16 y[], // (o) : output signal + Word16 lg, // (i) : size of filtering + Word16 mem[], // (i/o) : memory associated with this filtering. + Word16 update // (i) : 0=no update, 1=update of memory. +) +{ + Word16 i, j; + Word32 s; + Word16 tmp[80]; // This is usually done by memory allocation (lg+M) + Word16 *yy; + + // Copy mem[] to yy[] + + yy = tmp; + + for (i = 0; i < M; i++) + { + *yy++ = mem[i]; + } + + // Do the filtering. + + for (i = 0; i < lg; i++) + { + s = L_mult (x[i], a[0]); + for (j = 1; j <= M; j++) + { + s = L_msu (s, a[j], yy[-j]); + } + s = L_shl (s, 3); + *yy++ = pv_round (s); + } + + for (i = 0; i < lg; i++) + { + y[i] = tmp[i + M]; + } + + // Update of memory if update==1 + + if (update != 0) + { + for (i = 0; i < M; i++) + { + mem[i] = y[lg - M + i]; + } + } + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void Syn_filt( + Word16 a[], /* (i) : a[M+1] prediction coefficients (M=10) */ + Word16 x[], /* (i) : input signal */ + Word16 y[], /* (o) : output signal */ + Word16 lg, /* (i) : size of filtering (40) */ + Word16 mem[], /* (i/o) : memory associated with this filtering. */ + Word16 update /* (i) : 0=no update, 1=update of memory. */ +) +{ + Word16 i, j; + Word32 s1; + Word32 s2; + Word16 tmp[2*M]; /* This is usually done by memory allocation (lg+M) */ + Word16 *yy; + + Word16 *p_a; + Word16 *p_yy1; + Word16 *p_y; + Word16 *p_x; + Word16 temp; + /* Copy mem[] to yy[] */ + + yy = tmp; + + oscl_memcpy(yy, mem, M*sizeof(Word16)); + + yy = yy + M; + + /* Do the filtering. */ + + p_y = y; + p_x = x; + p_yy1 = &yy[-1]; + + for (i = M >> 1; i != 0; i--) + { + p_a = a; + + s1 = amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_a), 0x00000800L); + s2 = amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_a++), 0x00000800L); + s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1); + + for (j = (M >> 1) - 2; j != 0; j--) + { + s2 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a), (Word32) * (p_yy1--), s2); + s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1); + s2 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a), (Word32) * (p_yy1--), s2); + s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1); + s2 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a), (Word32) * (p_yy1--), s2); + s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1); + } + + /* check for overflow on s1 */ + if ((UWord32)(s1 + 134217728) < 0x0fffffffL) + { + temp = (Word16)(s1 >> 12); + } + else if (s1 > 0x07ffffffL) + { + temp = MAX_16; + } + else + { + temp = MIN_16; + } + + s2 = amrnb_fxp_msu_16_by_16bb((Word32)a[1], (Word32)temp, s2); + + *(yy++) = temp; + *(p_y++) = temp; + + p_yy1 = yy; + + /* check for overflow on s2 */ + if ((UWord32)(s2 + 134217728) < 0x0fffffffL) + { + temp = (Word16)(s2 >> 12); + } + else if (s2 > 0x07ffffffL) + { + temp = MAX_16; + } + else + { + temp = MIN_16; + } + + *(yy++) = temp; + *(p_y++) = temp; + } + + p_yy1 = &y[M-1]; + + for (i = (lg - M) >> 1; i != 0; i--) + { + p_a = a; + + s1 = amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_a), 0x00000800L); + s2 = amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_a++), 0x00000800L); + s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1); + + for (j = (M >> 1) - 2; j != 0; j--) + { + s2 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a), (Word32) * (p_yy1--), s2); + s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1); + s2 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a), (Word32) * (p_yy1--), s2); + s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1); + s2 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a), (Word32) * (p_yy1--), s2); + s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1); + } + + if ((UWord32)(s1 + 134217728) < 0x0fffffffL) + { + temp = (Word16)(s1 >> 12); + } + else if (s1 > 0x07ffffffL) + { + temp = MAX_16; + } + else + { + temp = MIN_16; + } + + s2 = amrnb_fxp_msu_16_by_16bb((Word32)a[1], (Word32)temp, s2); + + *(p_y++) = temp; + p_yy1 = p_y; + + if ((UWord32)(s2 + 134217728) < 0x0fffffffL) + { + *(p_y++) = (Word16)(s2 >> 12); + } + else if (s2 > 0x07ffffffL) + { + *(p_y++) = MAX_16; + } + else + { + *(p_y++) = MIN_16; + } + } + + /* Update of memory if update==1 */ + if (update != 0) + { + oscl_memcpy(mem, &y[lg-M], M*sizeof(Word16)); + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/vad1.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/vad1.cpp new file mode 100644 index 00000000..d5c42dc2 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/vad1.cpp @@ -0,0 +1,2001 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: vad1.cpp + Functions: + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "vad.h" +#include "typedef.h" +#include "shr.h" +#include "basic_op.h" +#include "cnst_vad.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: first_filter_stage +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + data -- array of type Word16 -- filter memory + in -- array of type Word16 -- input signal + + Outputs: + data -- array of type Word16 -- filter memory + out -- array of type Word16 -- output values, every other + output is low-pass part and + other is high-pass part every + + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Scale input down by one bit. Calculate 5th order + half-band lowpass/highpass filter pair with + decimation. +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void first_filter_stage( + Word16 in[], /* i : input signal */ + Word16 out[], /* o : output values, every other */ + /* output is low-pass part and */ + /* other is high-pass part every */ + Word16 data[], /* i/o : filter memory */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 temp0; + Word16 temp1; + Word16 temp2; + Word16 temp3; + Word16 i; + Word16 data0; + Word16 data1; + + data0 = data[0]; + data1 = data[1]; + + for (i = 0; i < FRAME_LEN / 4; i++) + { + temp0 = mult(COEFF5_1, data0, pOverflow); + temp1 = shr(in[4*i+0], 2, pOverflow); + temp0 = sub(temp1, temp0, pOverflow); + + temp1 = mult(COEFF5_1, temp0, pOverflow); + temp1 = add(data0, temp1, pOverflow); + + temp3 = mult(COEFF5_2, data1, pOverflow); + temp2 = shr(in[4*i+1], 2, pOverflow); + + temp3 = sub(temp2, temp3, pOverflow); + + temp2 = mult(COEFF5_2, temp3, pOverflow); + temp2 = add(data1, temp2, pOverflow); + + out[4*i+0] = add(temp1, temp2, pOverflow); + out[4*i+1] = sub(temp1, temp2, pOverflow); + + temp1 = mult(COEFF5_1, temp0, pOverflow); + temp2 = shr(in[4*i+2], 2, pOverflow); + data0 = sub(temp2, temp1, pOverflow); + + temp1 = mult(COEFF5_1, data0, pOverflow); + temp1 = add(temp0, temp1, pOverflow); + + data1 = mult(COEFF5_2, temp3, pOverflow); + temp2 = shr(in[4*i+3], 2, pOverflow); + data1 = sub(temp2, data1, pOverflow); + + temp2 = mult(COEFF5_2, data1, pOverflow); + temp2 = add(temp3, temp2, pOverflow); + + out[4*i+2] = add(temp1, temp2, pOverflow); + out[4*i+3] = sub(temp1, temp2, pOverflow); + } + + data[0] = data0; + data[1] = data1; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: filter5 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + in0 -- array of type Word16 -- input values; output low-pass part + in1 -- array of type Word16 -- input values; output high-pass part + data -- array of type Word16 -- updated filter memory + + Outputs: + in0 -- array of type Word16 -- input values; output low-pass part + in1 -- array of type Word16 -- input values; output high-pass part + data -- array of type Word16 -- updated filter memory + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Fifth-order half-band lowpass/highpass filter pair with + decimation. +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void filter5(Word16 *in0, /* i/o : input values; output low-pass part */ + Word16 *in1, /* i/o : input values; output high-pass part */ + Word16 data[], /* i/o : updated filter memory */ + Flag *pOverflow /* o : Flag set when overflow occurs */ + ) +{ + Word16 temp0; + Word16 temp1; + Word16 temp2; + + temp0 = mult(COEFF5_1, data[0], pOverflow); + temp0 = sub(*in0, temp0, pOverflow); + + temp1 = mult(COEFF5_1, temp0, pOverflow); + temp1 = add(data[0], temp1, pOverflow); + data[0] = temp0; + + temp0 = mult(COEFF5_2, data[1], pOverflow); + temp0 = sub(*in1, temp0, pOverflow); + + temp2 = mult(COEFF5_2, temp0, pOverflow); + temp2 = add(data[1], temp2, pOverflow); + + data[1] = temp0; + + temp0 = add(temp1, temp2, pOverflow); + *in0 = shr(temp0, 1, pOverflow); + + temp0 = sub(temp1, temp2, pOverflow); + *in1 = shr(temp0, 1, pOverflow); +} + + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: filter3 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + + Inputs: + in0 -- array of type Word16 -- input values; output low-pass part + in1 -- array of type Word16 -- input values; output high-pass part + data -- array of type Word16 -- updated filter memory + + Outputs: + in0 -- array of type Word16 -- input values; output low-pass part + in1 -- array of type Word16 -- input values; output high-pass part + data -- array of type Word16 -- updated filter memory + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Third-order half-band lowpass/highpass filter pair with + decimation. +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void filter3( + Word16 *in0, /* i/o : input values; output low-pass part */ + Word16 *in1, /* i/o : input values; output high-pass part */ + Word16 *data, /* i/o : updated filter memory */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 temp1; + Word16 temp2; + + temp1 = mult(COEFF3, *data, pOverflow); + temp1 = sub(*in1, temp1, pOverflow); + + temp2 = mult(COEFF3, temp1, pOverflow); + temp2 = add(*data, temp2, pOverflow); + + *data = temp1; + + temp1 = sub(*in0, temp2, pOverflow); + + *in1 = shr(temp1, 1, pOverflow); + + temp1 = add(*in0, temp2, pOverflow); + + *in0 = shr(temp1, 1, pOverflow); +} + + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: level_calculation +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + data -- array of type Word16 -- signal buffer + sub_level -- pointer to type Word16 -- level calculated at the end of + the previous frame + + count1 -- Word16 -- number of samples to be counted + count2 -- Word16 -- number of samples to be counted + ind_m -- Word16 -- step size for the index of the data buffer + ind_a -- Word16 -- starting index of the data buffer + scale -- Word16 -- scaling for the level calculation + + Outputs: + sub_level -- pointer to tyep Word16 -- level of signal calculated from the + last (count2 - count1) samples. + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + signal level + + Global Variables Used: + + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Calculate signal level in a sub-band. Level is calculated + by summing absolute values of the input data. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 level_calculation( + Word16 data[], /* i : signal buffer */ + Word16 *sub_level, /* i : level calculate at the end of */ + /* the previous frame */ + /* o : level of signal calculated from the last */ + /* (count2 - count1) samples */ + Word16 count1, /* i : number of samples to be counted */ + Word16 count2, /* i : number of samples to be counted */ + Word16 ind_m, /* i : step size for the index of the data buffer */ + Word16 ind_a, /* i : starting index of the data buffer */ + Word16 scale, /* i : scaling for the level calculation */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word32 l_temp1; + Word32 l_temp2; + Word16 level; + Word16 i; + + l_temp1 = 0L; + + for (i = count1; i < count2; i++) + { + l_temp1 = L_mac(l_temp1, 1, abs_s(data[ind_m*i+ind_a]), pOverflow); + } + + l_temp2 = L_add(l_temp1, L_shl(*sub_level, sub(16, scale, pOverflow), pOverflow), pOverflow); + *sub_level = extract_h(L_shl(l_temp1, scale, pOverflow)); + + for (i = 0; i < count1; i++) + { + l_temp2 = L_mac(l_temp2, 1, abs_s(data[ind_m*i+ind_a]), pOverflow); + } + level = extract_h(L_shl(l_temp2, scale, pOverflow)); + + return level; +} + + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: filter_bank +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + in -- array of type Word16 -- input frame + + Outputs: + level -- array of type Word16 -- signal levels at each band + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Divides input signal into 9-bands and calculas level of + the signal in each band + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void filter_bank( + vadState1 *st, /* i/o : State struct */ + Word16 in[], /* i : input frame */ + Word16 level[], /* 0 : signal levels at each band */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 tmp_buf[FRAME_LEN]; + + /* calculate the filter bank */ + + first_filter_stage(in, tmp_buf, st->a_data5[0], pOverflow); + + for (i = 0; i < FRAME_LEN / 4; i++) + { + filter5(&tmp_buf[4*i], &tmp_buf[4*i+2], st->a_data5[1], pOverflow); + filter5(&tmp_buf[4*i+1], &tmp_buf[4*i+3], st->a_data5[2], pOverflow); + } + for (i = 0; i < FRAME_LEN / 8; i++) + { + filter3(&tmp_buf[8*i+0], &tmp_buf[8*i+4], &st->a_data3[0], pOverflow); + filter3(&tmp_buf[8*i+2], &tmp_buf[8*i+6], &st->a_data3[1], pOverflow); + filter3(&tmp_buf[8*i+3], &tmp_buf[8*i+7], &st->a_data3[4], pOverflow); + } + + for (i = 0; i < FRAME_LEN / 16; i++) + { + filter3(&tmp_buf[16*i+0], &tmp_buf[16*i+8], &st->a_data3[2], pOverflow); + filter3(&tmp_buf[16*i+4], &tmp_buf[16*i+12], &st->a_data3[3], pOverflow); + } + + /* calculate levels in each frequency band */ + + /* 3000 - 4000 Hz*/ + level[8] = level_calculation(tmp_buf, &st->sub_level[8], FRAME_LEN / 4 - 8, + FRAME_LEN / 4, 4, 1, 15, pOverflow); + /* 2500 - 3000 Hz*/ + level[7] = level_calculation(tmp_buf, &st->sub_level[7], FRAME_LEN / 8 - 4, + FRAME_LEN / 8, 8, 7, 16, pOverflow); + /* 2000 - 2500 Hz*/ + level[6] = level_calculation(tmp_buf, &st->sub_level[6], FRAME_LEN / 8 - 4, + FRAME_LEN / 8, 8, 3, 16, pOverflow); + /* 1500 - 2000 Hz*/ + level[5] = level_calculation(tmp_buf, &st->sub_level[5], FRAME_LEN / 8 - 4, + FRAME_LEN / 8, 8, 2, 16, pOverflow); + /* 1000 - 1500 Hz*/ + level[4] = level_calculation(tmp_buf, &st->sub_level[4], FRAME_LEN / 8 - 4, + FRAME_LEN / 8, 8, 6, 16, pOverflow); + /* 750 - 1000 Hz*/ + level[3] = level_calculation(tmp_buf, &st->sub_level[3], FRAME_LEN / 16 - 2, + FRAME_LEN / 16, 16, 4, 16, pOverflow); + /* 500 - 750 Hz*/ + level[2] = level_calculation(tmp_buf, &st->sub_level[2], FRAME_LEN / 16 - 2, + FRAME_LEN / 16, 16, 12, 16, pOverflow); + /* 250 - 500 Hz*/ + level[1] = level_calculation(tmp_buf, &st->sub_level[1], FRAME_LEN / 16 - 2, + FRAME_LEN / 16, 16, 8, 16, pOverflow); + /* 0 - 250 Hz*/ + level[0] = level_calculation(tmp_buf, &st->sub_level[0], FRAME_LEN / 16 - 2, + FRAME_LEN / 16, 16, 0, 16, pOverflow); +} + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: update_cntrl +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + level -- array of type Word16 -- sub-band levels of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Control update of the background noise estimate. + Inputs : pitch: flags for pitch detection + stat_count: stationary counter + tone: flags indicating presence of a tone + complex: flags for complex detection + vadreg: intermediate VAD flags + Output : stat_count: stationary counter + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void update_cntrl( + vadState1 *st, /* i/o : State struct */ + Word16 level[], /* i : sub-band levels of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 temp; + Word16 stat_rat; + Word16 exp; + Word16 num; + Word16 denom; + Word16 alpha; + + /* handle highband complex signal input separately */ + /* if ther has been highband correlation for some time */ + /* make sure that the VAD update speed is low for a while */ + if (st->complex_warning != 0) + { + if (st->stat_count < CAD_MIN_STAT_COUNT) + { + st->stat_count = CAD_MIN_STAT_COUNT; + } + } + /* NB stat_count is allowed to be decreased by one below again */ + /* deadlock in speech is not possible unless the signal is very */ + /* complex and need a high rate */ + + /* if fullband pitch or tone have been detected for a while, initialize stat_count */ + if (((Word16)(st->pitch & 0x6000) == 0x6000) || + ((Word16)(st->tone & 0x7c00) == 0x7c00)) + { + st->stat_count = STAT_COUNT; + } + else + { + /* if 8 last vad-decisions have been "0", reinitialize stat_count */ + if ((st->vadreg & 0x7f80) == 0) + { + st->stat_count = STAT_COUNT; + } + else + { + stat_rat = 0; + for (i = 0; i < COMPLEN; i++) + { + if (level[i] > st->ave_level[i]) + { + num = level[i]; + denom = st->ave_level[i]; + } + else + { + num = st->ave_level[i]; + denom = level[i]; + } + /* Limit nimimum value of num and denom to STAT_THR_LEVEL */ + if (num < STAT_THR_LEVEL) + { + num = STAT_THR_LEVEL; + } + if (denom < STAT_THR_LEVEL) + { + denom = STAT_THR_LEVEL; + } + + exp = norm_s(denom); + + denom = shl(denom, exp, pOverflow); + + /* stat_rat = num/denom * 64 */ + temp = shr(num, 1, pOverflow); + temp = div_s(temp, denom); + + stat_rat = add(stat_rat, shr(temp, sub(8, exp, pOverflow), pOverflow), pOverflow); + } + + /* compare stat_rat with a threshold and update stat_count */ + if (stat_rat > STAT_THR) + { + st->stat_count = STAT_COUNT; + } + else + { + if ((st->vadreg & 0x4000) != 0) + { + if (st->stat_count != 0) + { + st->stat_count = sub(st->stat_count, 1, pOverflow); + } + } + } + } + } + + /* Update average amplitude estimate for stationarity estimation */ + alpha = ALPHA4; + if (st->stat_count == STAT_COUNT) + { + alpha = 32767; + } + else if ((st->vadreg & 0x4000) == 0) + { + alpha = ALPHA5; + } + + for (i = 0; i < COMPLEN; i++) + { + temp = sub(level[i], st->ave_level[i], pOverflow); + temp = mult_r(alpha, temp, pOverflow); + + st->ave_level[i] = + add( + st->ave_level[i], + temp, + pOverflow); + } +} + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: hangover_addition +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + noise_level -- Word16 -- average level of the noise estimates + low_power -- Word16 -- flag power of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicato + + Returns: + VAD_flag indicating final VAD decision (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function : hangover_addition + Purpose : Add hangover for complex signal or after speech bursts + Inputs : burst_count: counter for the length of speech bursts + hang_count: hangover counter + vadreg: intermediate VAD decision + Outputs : burst_count: counter for the length of speech bursts + hang_count: hangover counter + Return value : VAD_flag indicating final VAD decision + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 hangover_addition( + vadState1 *st, /* i/o : State struct */ + Word16 noise_level, /* i : average level of the noise */ + /* estimates */ + Word16 low_power, /* i : flag power of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 hang_len; + Word16 burst_len; + + /* + Calculate burst_len and hang_len + burst_len: number of consecutive intermediate vad flags with "1"-decision + required for hangover addition + hang_len: length of the hangover + */ + + if (noise_level > HANG_NOISE_THR) + { + burst_len = BURST_LEN_HIGH_NOISE; + hang_len = HANG_LEN_HIGH_NOISE; + } + else + { + burst_len = BURST_LEN_LOW_NOISE; + hang_len = HANG_LEN_LOW_NOISE; + } + + /* if the input power (pow_sum) is lower than a threshold, clear + counters and set VAD_flag to "0" "fast exit" */ + if (low_power != 0) + { + st->burst_count = 0; + st->hang_count = 0; + st->complex_hang_count = 0; + st->complex_hang_timer = 0; + return 0; + } + + if (st->complex_hang_timer > CVAD_HANG_LIMIT) + { + if (st->complex_hang_count < CVAD_HANG_LENGTH) + { + st->complex_hang_count = CVAD_HANG_LENGTH; + } + } + + /* long time very complex signal override VAD output function */ + if (st->complex_hang_count != 0) + { + st->burst_count = BURST_LEN_HIGH_NOISE; + st->complex_hang_count = sub(st->complex_hang_count, 1, pOverflow); + return 1; + } + else + { + /* let hp_corr work in from a noise_period indicated by the VAD */ + if (((st->vadreg & 0x3ff0) == 0) && + (st->corr_hp_fast > CVAD_THRESH_IN_NOISE)) + { + return 1; + } + } + + /* update the counters (hang_count, burst_count) */ + if ((st->vadreg & 0x4000) != 0) + { + st->burst_count = add(st->burst_count, 1, pOverflow); + + if (st->burst_count >= burst_len) + { + st->hang_count = hang_len; + } + return 1; + } + else + { + st->burst_count = 0; + if (st->hang_count > 0) + { + st->hang_count = sub(st->hang_count, 1, pOverflow); + return 1; + } + } + return 0; +} + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: noise_estimate_update +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + level -- array of type Word16 -- sub-band levels of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Update of background noise estimate + Inputs : bckr_est: background noise estimate + pitch: flags for pitch detection + stat_count: stationary counter + Outputs : bckr_est: background noise estimate + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void noise_estimate_update( + vadState1 *st, /* i/o : State struct */ + Word16 level[], /* i : sub-band levels of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 alpha_up; + Word16 alpha_down; + Word16 bckr_add; + + /* Control update of bckr_est[] */ + update_cntrl(st, level, pOverflow); + + /* Choose update speed */ + bckr_add = 2; + + if (((0x7800 & st->vadreg) == 0) && + ((st->pitch & 0x7800) == 0) + && (st->complex_hang_count == 0)) + { + alpha_up = ALPHA_UP1; + alpha_down = ALPHA_DOWN1; + } + else + { + if ((st->stat_count == 0) + && (st->complex_hang_count == 0)) + { + alpha_up = ALPHA_UP2; + alpha_down = ALPHA_DOWN2; + } + else + { + alpha_up = 0; + alpha_down = ALPHA3; + bckr_add = 0; + } + } + + /* Update noise estimate (bckr_est) */ + for (i = 0; i < COMPLEN; i++) + { + Word16 temp; + + temp = sub(st->old_level[i], st->bckr_est[i], pOverflow); + + if (temp < 0) + { /* update downwards*/ + temp = mult_r(alpha_down, temp, pOverflow); + temp = add(st->bckr_est[i], temp, pOverflow); + + st->bckr_est[i] = add(-2, temp, pOverflow); + + /* limit minimum value of the noise estimate to NOISE_MIN */ + if (st->bckr_est[i] < NOISE_MIN) + { + st->bckr_est[i] = NOISE_MIN; + } + } + else + { /* update upwards */ + temp = mult_r(alpha_up, temp, pOverflow); + temp = add(st->bckr_est[i], temp, pOverflow); + st->bckr_est[i] = add(bckr_add, temp, pOverflow); + + /* limit maximum value of the noise estimate to NOISE_MAX */ + if (st->bckr_est[i] > NOISE_MAX) + { + st->bckr_est[i] = NOISE_MAX; + } + } + } + + /* Update signal levels of the previous frame (old_level) */ + for (i = 0; i < COMPLEN; i++) + { + st->old_level[i] = level[i]; + } +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: complex_estimate_adapt +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + low_power -- Word16 -- very low level flag of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function : complex_estimate_adapt + Purpose : Update/adapt of complex signal estimate + Inputs : low_power: low signal power flag + Outputs : st->corr_hp_fast: long term complex signal estimate + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void complex_estimate_adapt( + vadState1 *st, /* i/o : VAD state struct */ + Word16 low_power, /* i : very low level flag of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 alpha; /* Q15 */ + Word32 L_tmp; /* Q31 */ + + + /* adapt speed on own state */ + if (st->best_corr_hp < st->corr_hp_fast) /* decrease */ + { + if (st->corr_hp_fast < CVAD_THRESH_ADAPT_HIGH) + { /* low state */ + alpha = CVAD_ADAPT_FAST; + } + else + { /* high state */ + alpha = CVAD_ADAPT_REALLY_FAST; + } + } + else /* increase */ + { + if (st->corr_hp_fast < CVAD_THRESH_ADAPT_HIGH) + { + alpha = CVAD_ADAPT_FAST; + } + else + { + alpha = CVAD_ADAPT_SLOW; + } + } + + L_tmp = L_deposit_h(st->corr_hp_fast); + L_tmp = L_msu(L_tmp, alpha, st->corr_hp_fast, pOverflow); + L_tmp = L_mac(L_tmp, alpha, st->best_corr_hp, pOverflow); + st->corr_hp_fast = pv_round(L_tmp, pOverflow); /* Q15 */ + + if (st->corr_hp_fast < CVAD_MIN_CORR) + { + st->corr_hp_fast = CVAD_MIN_CORR; + } + + if (low_power != 0) + { + st->corr_hp_fast = CVAD_MIN_CORR; + } +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: complex_vad +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + low_power -- Word16 -- flag power of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + + Returns: + the complex background decision + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : complex background decision + Return value : the complex background decision + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 complex_vad( + vadState1 *st, /* i/o : VAD state struct */ + Word16 low_power, /* i : flag power of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + st->complex_high = shr(st->complex_high, 1, pOverflow); + st->complex_low = shr(st->complex_low, 1, pOverflow); + + if (low_power == 0) + { + if (st->corr_hp_fast > CVAD_THRESH_ADAPT_HIGH) + { + st->complex_high |= 0x4000; + } + + if (st->corr_hp_fast > CVAD_THRESH_ADAPT_LOW) + { + st->complex_low |= 0x4000; + } + } + + if (st->corr_hp_fast > CVAD_THRESH_HANG) + { + st->complex_hang_timer = add(st->complex_hang_timer, 1, pOverflow); + } + else + { + st->complex_hang_timer = 0; + } + + return ((Word16)(st->complex_high & 0x7f80) == 0x7f80 || + (Word16)(st->complex_low & 0x7fff) == 0x7fff); +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad_decision +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + level -- array of type Word16 -- sub-band levels of the input frame + pow_sum -- Word32 -- power of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + VAD_flag (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Calculates VAD_flag + Inputs : bckr_est: background noise estimate + vadreg: intermediate VAD flags + Outputs : noise_level: average level of the noise estimates + vadreg: intermediate VAD flags + Return value : VAD_flag + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 vad_decision( + vadState1 *st, /* i/o : State struct */ + Word16 level[COMPLEN], /* i : sub-band levels of the input frame */ + Word32 pow_sum, /* i : power of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 snr_sum; + Word32 L_temp; + Word16 vad_thr; + Word16 temp; + Word16 noise_level; + Word16 low_power_flag; + Word16 temp1; + + /* + Calculate squared sum of the input levels (level) + divided by the background noise components (bckr_est). + */ + L_temp = 0; + + for (i = 0; i < COMPLEN; i++) + { + Word16 exp; + + exp = norm_s(st->bckr_est[i]); + temp = shl(st->bckr_est[i], exp, pOverflow); + temp = div_s(shr(level[i], 1, pOverflow), temp); + temp = shl(temp, sub(exp, UNIRSHFT - 1, pOverflow), pOverflow); + L_temp = L_mac(L_temp, temp, temp, pOverflow); + } + + snr_sum = extract_h(L_shl(L_temp, 6, pOverflow)); + snr_sum = mult(snr_sum, INV_COMPLEN, pOverflow); + + /* Calculate average level of estimated background noise */ + L_temp = 0; + for (i = 0; i < COMPLEN; i++) + { + L_temp = L_add(L_temp, st->bckr_est[i], pOverflow); + } + + noise_level = extract_h(L_shl(L_temp, 13, pOverflow)); + + /* Calculate VAD threshold */ + temp1 = sub(noise_level, VAD_P1, pOverflow); + temp1 = mult(VAD_SLOPE, temp1, pOverflow); + vad_thr = add(temp1, VAD_THR_HIGH, pOverflow); + + if (vad_thr < VAD_THR_LOW) + { + vad_thr = VAD_THR_LOW; + } + + /* Shift VAD decision register */ + st->vadreg = shr(st->vadreg, 1, pOverflow); + + /* Make intermediate VAD decision */ + if (snr_sum > vad_thr) + { + st->vadreg |= 0x4000; + } + /* primary vad decsion made */ + + /* check if the input power (pow_sum) is lower than a threshold" */ + if (L_sub(pow_sum, VAD_POW_LOW, pOverflow) < 0) + { + low_power_flag = 1; + } + else + { + low_power_flag = 0; + } + + /* update complex signal estimate st->corr_hp_fast and hangover reset timer using */ + /* low_power_flag and corr_hp_fast and various adaptation speeds */ + complex_estimate_adapt(st, low_power_flag, pOverflow); + + /* check multiple thresholds of the st->corr_hp_fast value */ + st->complex_warning = complex_vad(st, low_power_flag, pOverflow); + + /* Update speech subband vad background noise estimates */ + noise_estimate_update(st, level, pOverflow); + + /* Add speech and complex hangover and return speech VAD_flag */ + /* long term complex hangover may be added */ + st->speech_vad_decision = hangover_addition(st, noise_level, low_power_flag, pOverflow); + + return (st->speech_vad_decision); +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad1_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state -- double pointer to type vadState1 -- pointer to memory to + be initialized. + + Outputs: + state -- points to initalized area in memory. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Allocates state memory and initializes state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 vad1_init(vadState1 **state) +{ + vadState1* s; + + if (state == (vadState1 **) NULL) + { + return -1; + } + *state = NULL; + + /* allocate memory */ + if ((s = (vadState1 *) oscl_malloc(sizeof(vadState1))) == NULL) + { + return -1; + } + + vad1_reset(s); + + *state = s; + + return 0; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad1_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state -- pointer to type vadState1 -- State struct + + Outputs: + state -- pointer to type vadState1 -- State struct + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose: Resets state memory to zero + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 vad1_reset(vadState1 *state) +{ + Word16 i; + Word16 j; + + if (state == (vadState1 *) NULL) + { + return -1; + } + + /* Initialize pitch detection variables */ + state->oldlag_count = 0; + state->oldlag = 0; + state->pitch = 0; + state->tone = 0; + + state->complex_high = 0; + state->complex_low = 0; + state->complex_hang_timer = 0; + + state->vadreg = 0; + + state->stat_count = 0; + state->burst_count = 0; + state->hang_count = 0; + state->complex_hang_count = 0; + + /* initialize memory used by the filter bank */ + for (i = 0; i < 3; i++) + { + for (j = 0; j < 2; j++) + { + state->a_data5[i][j] = 0; + } + } + + for (i = 0; i < 5; i++) + { + state->a_data3[i] = 0; + } + + /* initialize the rest of the memory */ + for (i = 0; i < COMPLEN; i++) + { + state->bckr_est[i] = NOISE_INIT; + state->old_level[i] = NOISE_INIT; + state->ave_level[i] = NOISE_INIT; + state->sub_level[i] = 0; + } + + state->best_corr_hp = CVAD_LOWPOW_RESET; + + state->speech_vad_decision = 0; + state->complex_warning = 0; + state->sp_burst_count = 0; + + state->corr_hp_fast = CVAD_LOWPOW_RESET; + + return 0; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad1_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state -- pointer to type vadState1 -- State struct + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + The memory used for state memory is freed + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void vad1_exit(vadState1 **state) +{ + if (state == NULL || *state == NULL) + return; + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad_complex_detection_update +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + best_corr_hp -- Word16 -- best Corr + state -- pointer to type vadState1 -- State struct + + Outputs: + state -- pointer to type vadState1 -- State struct + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : update vad->bestCorr_hp complex signal feature state +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void vad_complex_detection_update( + vadState1 *st, /* i/o : State struct */ + Word16 best_corr_hp) /* i : best Corr */ +{ + st->best_corr_hp = best_corr_hp; +} + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad_tone_detection +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + t0 -- Word32 -- autocorrelation maxima + t1 -- Word32 -- energy + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Set tone flag if pitch gain is high. This is used to detect + signaling tones and other signals with high pitch gain. + Inputs : tone: flags indicating presence of a tone + Outputs : tone: flags indicating presence of a tone +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void vad_tone_detection( + vadState1 *st, /* i/o : State struct */ + Word32 t0, /* i : autocorrelation maxima */ + Word32 t1, /* i : energy */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 temp; + /* + if (t0 > TONE_THR * t1) + set tone flag + */ + temp = pv_round(t1, pOverflow); + + if ((temp > 0) && (L_msu(t0, temp, TONE_THR, pOverflow) > 0)) + { + st->tone |= 0x4000; + } +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad_tone_detection_update +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + one_lag_per_frame -- Word16 -- 1 if one open-loop lag is calculated per + each frame, otherwise 0 + st -- pointer to type vadState1 -- State struct + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Update the tone flag register. Tone flags are shifted right + by one bit. This function should be called from the speech + encoder before call to Vad_tone_detection() function. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void vad_tone_detection_update( + vadState1 *st, /* i/o : State struct */ + Word16 one_lag_per_frame, /* i : 1 if one open-loop lag */ + /* is calculated per each */ + /* frame, otherwise 0 */ + Flag *pOverflow /* o : Flags overflow */ +) +{ + /* Shift tone flags right by one bit */ + st->tone = shr(st->tone, 1, pOverflow); + + /* If open-loop lag is calculated only once in each frame, do extra update + and assume that the other tone flag of the frame is one. */ + if (one_lag_per_frame != 0) + { + st->tone = shr(st->tone, 1, pOverflow); + st->tone |= 0x2000; + } +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad_pitch_detection +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + T_op -- array of type Word16 -- speech encoder open loop lags + st -- pointer to type vadState1 -- State struct + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Test whether signal contains pitch or other periodic + component. + Return value : Boolean voiced / unvoiced decision in state variable + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void vad_pitch_detection( + vadState1 *st, /* i/o : State struct */ + Word16 T_op[], /* i : speech encoder open loop lags */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 lagcount; + Word16 i; + Word16 temp; + + lagcount = 0; + + for (i = 0; i < 2; i++) + { + temp = sub(st->oldlag, T_op[i], pOverflow); + temp = abs_s(temp); + + if (temp < LTHRESH) + { + lagcount = add(lagcount, 1, pOverflow); + } + + /* Save the current LTP lag */ + st->oldlag = T_op[i]; + } + + /* Make pitch decision. + Save flag of the pitch detection to the variable pitch. + */ + st->pitch = shr(st->pitch, 1, pOverflow); + + temp = + add( + st->oldlag_count, + lagcount, + pOverflow); + + if (temp >= NTHRESH) + { + st->pitch |= 0x4000; + } + + /* Update oldlagcount */ + st->oldlag_count = lagcount; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad1 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + in_buf -- array of type Word16 -- samples of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + VAD Decision, 1 = speech, 0 = noise + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Main program for Voice Activity Detection (VAD) for AMR + Return value : VAD Decision, 1 = speech, 0 = noise + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 vad1( + vadState1 *st, /* i/o : State struct */ + Word16 in_buf[], /* i : samples of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 level[COMPLEN]; + Word32 pow_sum; + Word16 i; + + /* Calculate power of the input frame. */ + pow_sum = 0L; + + for (i = 0; i < FRAME_LEN; i++) + { + pow_sum = L_mac(pow_sum, in_buf[i-LOOKAHEAD], in_buf[i-LOOKAHEAD], pOverflow); + } + + /* + If input power is very low, clear pitch flag of the current frame + */ + if (L_sub(pow_sum, POW_PITCH_THR, pOverflow) < 0) + { + st->pitch = st->pitch & 0x3fff; + } + + /* + If input power is very low, clear complex flag of the "current" frame + */ + if (L_sub(pow_sum, POW_COMPLEX_THR, pOverflow) < 0) + { + st->complex_low = st->complex_low & 0x3fff; + } + + /* + Run the filter bank which calculates signal levels at each band + */ + filter_bank(st, in_buf, level, pOverflow); + + return (vad_decision(st, level, pow_sum, pOverflow)); +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/vad2.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/vad2.cpp new file mode 100644 index 00000000..4da6ff5a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/vad2.cpp @@ -0,0 +1,1236 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: vad2.cpp + Functions: + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" +#include "log2.h" +#include "pow2.h" +#include "sub.h" +#include "l_shr_r.h" +#include "abs_s.h" +#include "norm_s.h" +#include "shl.h" +#include "shr_r.h" +#include "add.h" +//#include "mult.h" +#include "l_shr.h" +//#include "mpy_32_16.h" + + +#include "basic_op.h" + +//#include "l_add.h" +//#include "l_mac.h" +#include "l_extract.h" +//#include "l_sub.h" +//#include "l_mult.h" + +#include "round.h" +#include "shr.h" +#include "l_shl.h" +#include "mult_r.h" +#include "div_s.h" +#include "oscl_mem.h" + + +#include "vad2.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* + * The channel table is defined below. In this table, the + * lower and higher frequency coefficients for each of the 16 + * channels are specified. The table excludes the coefficients + * with numbers 0 (DC), 1, and 64 (Foldover frequency). + */ + +const Word16 ch_tbl[NUM_CHAN][2] = +{ + + {2, 3}, + {4, 5}, + {6, 7}, + {8, 9}, + {10, 11}, + {12, 13}, + {14, 16}, + {17, 19}, + {20, 22}, + {23, 26}, + {27, 30}, + {31, 35}, + {36, 41}, + {42, 48}, + {49, 55}, + {56, 63} + +}; + +/* channel energy scaling table - allows efficient division by number + * of DFT bins in the channel: 1/2, 1/3, 1/4, etc. + */ + +const Word16 ch_tbl_sh[NUM_CHAN] = +{ + 16384, 16384, 16384, 16384, 16384, 16384, 10923, 10923, + 10923, 8192, 8192, 6554, 5461, 4681, 4681, 4096 +}; + +/* + * The voice metric table is defined below. It is a non- + * linear table with a deadband near zero. It maps the SNR + * index (quantized SNR value) to a number that is a measure + * of voice quality. + */ + +const Word16 vm_tbl[90] = +{ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 15, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 23, 24, + 24, 25, 26, 27, 28, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50 +}; + +/* hangover as a function of peak SNR (3 dB steps) */ +const Word16 hangover_table[20] = +{ + 30, 30, 30, 30, 30, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 8, 8, 8 +}; + +/* burst sensitivity as a function of peak SNR (3 dB steps) */ +const Word16 burstcount_table[20] = +{ + 8, 8, 8, 8, 8, 8, 8, 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4 +}; + +/* voice metric sensitivity as a function of peak SNR (3 dB steps) */ +const Word16 vm_threshold_table[20] = +{ + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 40, 51, 71, 100, 139, 191, 257, 337, 432 +}; + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: fn10Log10 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_Input -- Word32 -- (scaled as 31-fbits,fbits) + fbits -- Word16 -- number of fractional bits on input + + Outputs: + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + output -- Word16 -- (scaled as 7,8) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: + The purpose of this function is to take the 10*log base 10 of input and + divide by 128 and return; i.e. output = 10*log10(input)/128 (scaled as 7,8) + + DESCRIPTION: + + 10*log10(x)/128 = 10*(log10(2) * (log2(x<> 7 + = 3.0103 * (log2(x<> 7 + = ((3.0103/4.0 * (log2(x<> 7 + = (3.0103/4.0 * (log2(x<> 5 + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad2.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 fn10Log10(Word32 L_Input, Word16 fbits, Flag *pOverflow) +{ + + Word16 integer; /* Integer part of Log2. (range: 0<=val<=30) */ + Word16 fraction; /* Fractional part of Log2. (range: 0<=val<1) */ + + Word32 Ltmp; + Word16 tmp; + + Log2(L_Input, &integer, &fraction, pOverflow); + + integer = sub(integer, fbits, pOverflow); + + /* 24660 = 10*log10(2)/4 scaled 0,15 */ + Ltmp = Mpy_32_16(integer, fraction, 24660, pOverflow); + + /* extra shift for 30,1 => 15,0 extract correction */ + Ltmp = L_shr_r(Ltmp, 5 + 1, pOverflow); + + tmp = (Word16) Ltmp; + + return (tmp); +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: block_norm +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + in -- array of type Word16 -- pointer to data sequence to be normalised + length -- Word16 -- number of elements in data sequence + headroom -- Word16 -- number of headroom bits + + Outputs: + out -- array of type Word16 -- normalised output data sequence + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + Word16 -- number of bits sequence was left shifted + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + The purpose of this function is block normalise the input data sequence + + 1) Search for maximum absolute valued data element + 2) Normalise the max element with "headroom" + 3) Transfer/shift the input sequence to the output buffer + 4) Return the number of left shifts + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad2.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION + + An input sequence of all zeros will return the maximum + number of left shifts allowed, NOT the value returned + by a norm_s(0) call, since it desired to associate an + all zeros sequence with low energy. +------------------------------------------------------------------------------ +*/ + +Word16 block_norm( + Word16 * in, + Word16 * out, + Word16 length, + Word16 headroom, + Flag *pOverflow) +{ + + Word16 i; + Word16 max; + Word16 scnt; + Word16 adata; + + max = abs_s(in[0]); + + for (i = 1; i < length; i++) + { + adata = abs_s(in[i]); + + if (adata > max) + { + max = adata; + } + } + if (max != 0) + { + scnt = sub(norm_s(max), headroom, pOverflow); + for (i = 0; i < length; i++) + { + out[i] = shl(in[i], scnt, pOverflow); + } + } + else + { + scnt = sub(16, headroom, pOverflow); + for (i = 0; i < length; i++) + { + out[i] = 0; + } + } + return (scnt); +} + + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad2 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + farray_ptr -- array of type Word16, length 80 (input array) + vadState2 -- pointer to vadState2 state structure + + Outputs: + vadState2 -- pointer to vadState2 state structure -- + state variables are updated + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + Word16 + VAD(m) - two successive calls to vad2() yield + the VAD decision for the 20 ms frame: + VAD_flag = VAD(m-1) || VAD(m) + + Global Variables Used: + + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function provides the Voice Activity Detection function option 2 + for the Adaptive Multi-rate (AMR) codec. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad2.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 vad2(Word16 * farray_ptr, vadState2 * st, Flag *pOverflow) +{ + + /* State tables that use 22,9 or 27,4 scaling for ch_enrg[] */ + + const Word16 noise_floor_chan[2] = {NOISE_FLOOR_CHAN_0, NOISE_FLOOR_CHAN_1}; + const Word16 min_chan_enrg[2] = {MIN_CHAN_ENRG_0, MIN_CHAN_ENRG_1}; + const Word16 ine_noise[2] = {INE_NOISE_0, INE_NOISE_1}; + const Word16 fbits[2] = {FRACTIONAL_BITS_0, FRACTIONAL_BITS_1}; + const Word16 state_change_shift_r[2] = {STATE_1_TO_0_SHIFT_R, STATE_0_TO_1_SHIFT_R}; + + /* Energy scale table given 30,1 input scaling (also account for -6 dB shift on input) */ + const Word16 enrg_norm_shift[2] = {(FRACTIONAL_BITS_0 - 1 + 2), (FRACTIONAL_BITS_1 - 1 + 2)}; + + + /* Automatic variables */ + + Word32 Lenrg; /* scaled as 30,1 */ + Word32 Ltne; /* scaled as 22,9 */ + Word32 Ltce; /* scaled as 22,9 or 27,4 */ + + Word16 tne_db; /* scaled as 7,8 */ + Word16 tce_db; /* scaled as 7,8 */ + + Word16 input_buffer[FRM_LEN]; /* used for block normalising input data */ + Word16 data_buffer[FFT_LEN]; /* used for in-place FFT */ + + Word16 ch_snr[NUM_CHAN]; /* scaled as 7,8 */ + Word16 ch_snrq; /* scaled as 15,0 (in 0.375 dB steps) */ + Word16 vm_sum; /* scaled as 15,0 */ + Word16 ch_enrg_dev; /* scaled as 7,8 */ + + Word32 Lpeak; /* maximum channel energy */ + Word16 p2a_flag; /* flag to indicate spectral peak-to-average ratio > 10 dB */ + + Word16 ch_enrg_db[NUM_CHAN]; /* scaled as 7,8 */ + Word16 ch_noise_db; /* scaled as 7,8 */ + + Word16 alpha; /* scaled as 0,15 */ + Word16 one_m_alpha; /* scaled as 0,15 */ + Word16 update_flag; /* set to indicate a background noise estimate update */ + + Word16 i; + Word16 j; + Word16 j1; + Word16 j2; /* Scratch variables */ + + Word16 hi1; + Word16 lo1; + + Word32 Ltmp; + Word32 Ltmp1; + Word32 Ltmp2; + Word16 tmp; + + Word16 normb_shift; /* block norm shift count */ + + Word16 ivad; /* intermediate VAD decision (return value) */ + Word16 tsnrq; /* total signal-to-noise ratio (quantized 3 dB steps) scaled as 15,0 */ + Word16 xt; /* instantaneous frame SNR in dB, scaled as 7,8 */ + + Word16 state_change; + + + /* Increment frame counter */ + st->Lframe_cnt = L_add(st->Lframe_cnt, 1, pOverflow); + + /* Block normalize the input */ + normb_shift = block_norm(farray_ptr, input_buffer, FRM_LEN, FFT_HEADROOM, pOverflow); + + /* Pre-emphasize the input data and store in the data buffer with the appropriate offset */ + for (i = 0; i < DELAY; i++) + { + data_buffer[i] = 0; + } + + st->pre_emp_mem = shr_r(st->pre_emp_mem, sub(st->last_normb_shift, normb_shift, pOverflow), pOverflow); + st->last_normb_shift = normb_shift; + + data_buffer[DELAY] = add(input_buffer[0], mult(PRE_EMP_FAC, st->pre_emp_mem, pOverflow), pOverflow); + + for (i = DELAY + 1, j = 1; i < DELAY + FRM_LEN; i++, j++) + { + data_buffer[i] = add(input_buffer[j], mult(PRE_EMP_FAC, input_buffer[j-1], pOverflow), pOverflow); + } + st->pre_emp_mem = input_buffer[FRM_LEN-1]; + + for (i = DELAY + FRM_LEN; i < FFT_LEN; i++) + { + data_buffer[i] = 0; + } + + + /* Perform FFT on the data buffer */ + r_fft(data_buffer, pOverflow); + + + /* Use normb_shift factor to determine the scaling of the energy estimates */ + state_change = 0; + if (st->shift_state == 0) + { + if (normb_shift <= (-FFT_HEADROOM + 2)) + { + state_change = 1; + st->shift_state = 1; + } + } + else + { + if (normb_shift >= (-FFT_HEADROOM + 5)) + { + state_change = 1; + st->shift_state = 0; + } + } + + /* Scale channel energy estimate */ + if (state_change) + { + for (i = LO_CHAN; i <= HI_CHAN; i++) + { + st->Lch_enrg[i] = + L_shr( + st->Lch_enrg[i], + state_change_shift_r[st->shift_state], + pOverflow); + } + } + + + /* Estimate the energy in each channel */ + if (st->Lframe_cnt == 1) + { + alpha = 32767; + one_m_alpha = 0; + } + else + { + alpha = CEE_SM_FAC; + one_m_alpha = ONE_MINUS_CEE_SM_FAC; + } + + for (i = LO_CHAN; i <= HI_CHAN; i++) + { + Lenrg = 0; + j1 = ch_tbl[i][0]; + j2 = ch_tbl[i][1]; + + for (j = j1; j <= j2; j++) + { + Lenrg = L_mac( + Lenrg, + data_buffer[2 * j], + data_buffer[2 * j], + pOverflow); + + Lenrg = L_mac( + Lenrg, + data_buffer[2 * j + 1], + data_buffer[2 * j + 1], + pOverflow); + } + + /* Denorm energy & scale 30,1 according to the state */ + tmp = shl(normb_shift, 1, pOverflow); + tmp = sub(tmp, enrg_norm_shift[st->shift_state], pOverflow); + Lenrg = L_shr_r(Lenrg, tmp, pOverflow); + + /* integrate over time: + * e[i] = (1-alpha)*e[i] + alpha*enrg/num_bins_in_chan + */ + tmp = mult(alpha, ch_tbl_sh[i], pOverflow); + L_Extract(Lenrg, &hi1, &lo1, pOverflow); + Ltmp = Mpy_32_16(hi1, lo1, tmp, pOverflow); + + L_Extract(st->Lch_enrg[i], &hi1, &lo1, pOverflow); + + Ltmp1 = Mpy_32_16(hi1, lo1, one_m_alpha, pOverflow); + st->Lch_enrg[i] = L_add(Ltmp, Ltmp1, pOverflow); + + if (st->Lch_enrg[i] < min_chan_enrg[st->shift_state]) + { + st->Lch_enrg[i] = min_chan_enrg[st->shift_state]; + } + + } + + + /* Compute the total channel energy estimate (Ltce) */ + Ltce = 0; + for (i = LO_CHAN; i <= HI_CHAN; i++) + { + Ltce = + L_add( + Ltce, + st->Lch_enrg[i], + pOverflow); + } + + + /* Calculate spectral peak-to-average ratio, set flag if p2a > 10 dB */ + Lpeak = 0; + + /* Sine waves not valid for low frequencies */ + for (i = LO_CHAN + 2; i <= HI_CHAN; i++) + { + if (L_sub(st->Lch_enrg [i], Lpeak, pOverflow) > 0) + { + Lpeak = st->Lch_enrg [i]; + } + } + + /* Set p2a_flag if peak (dB) > average channel energy (dB) + 10 dB */ + /* Lpeak > Ltce/num_channels * 10^(10/10) */ + /* Lpeak > (10/16)*Ltce */ + + L_Extract(Ltce, &hi1, &lo1, pOverflow); + Ltmp = Mpy_32_16(hi1, lo1, 20480, pOverflow); + if (L_sub(Lpeak, Ltmp, pOverflow) > 0) + { + p2a_flag = TRUE; + } + else + { + p2a_flag = FALSE; + } + + + /* Initialize channel noise estimate to either the channel energy or fixed level */ + /* Scale the energy appropriately to yield state 0 (22,9) scaling for noise */ + if (st->Lframe_cnt <= 4) + { + if (p2a_flag == TRUE) + { + for (i = LO_CHAN; i <= HI_CHAN; i++) + { + st->Lch_noise[i] = INE_NOISE_0; + } + } + else + { + for (i = LO_CHAN; i <= HI_CHAN; i++) + { + if (st->Lch_enrg[i] < ine_noise[st->shift_state]) + { + st->Lch_noise[i] = INE_NOISE_0; + } + else + { + if (st->shift_state == 1) + { + st->Lch_noise[i] = + L_shr( + st->Lch_enrg[i], + state_change_shift_r[0], + pOverflow); + } + else + { + st->Lch_noise[i] = st->Lch_enrg[i]; + } + } + } + } + } + + + /* Compute the channel energy (in dB), the channel SNRs, and the sum of voice metrics */ + vm_sum = 0; + for (i = LO_CHAN; i <= HI_CHAN; i++) + { + ch_enrg_db[i] = + fn10Log10( + st->Lch_enrg[i], + fbits[st->shift_state], + pOverflow); + + ch_noise_db = + fn10Log10( + st->Lch_noise[i], + FRACTIONAL_BITS_0, + pOverflow); + + ch_snr[i] = sub(ch_enrg_db[i], ch_noise_db, pOverflow); + + /* quantize channel SNR in 3/8 dB steps (scaled 7,8 => 15,0) */ + /* ch_snr = pv_round((snr/(3/8))>>8) */ + /* = pv_round(((0.6667*snr)<<2)>>8) */ + /* = pv_round((0.6667*snr)>>6) */ + + tmp = mult(21845, ch_snr[i], pOverflow); + + ch_snrq = shr_r(tmp, 6, pOverflow); + + /* Accumulate the sum of voice metrics */ + if (ch_snrq < 89) + { + if (ch_snrq > 0) + { + j = ch_snrq; + } + else + { + j = 0; + } + } + else + { + j = 89; + } + vm_sum = add(vm_sum, vm_tbl[j], pOverflow); + } + + + /* Initialize NOMINAL peak voice energy and average noise energy, calculate instantaneous SNR */ + if (st->Lframe_cnt <= 4 || st->fupdate_flag == TRUE) + { + /* tce_db = (96 - 22 - 10*log10(64) (due to FFT)) scaled as 7,8 */ + tce_db = 14320; + st->negSNRvar = 0; + st->negSNRbias = 0; + + /* Compute the total noise estimate (Ltne) */ + Ltne = 0; + for (i = LO_CHAN; i <= HI_CHAN; i++) + { + Ltne = L_add(Ltne, st->Lch_noise[i], pOverflow); + } + + /* Get total noise in dB */ + tne_db = + fn10Log10( + Ltne, + FRACTIONAL_BITS_0, + pOverflow); + + /* Initialise instantaneous and long-term peak signal-to-noise ratios */ + xt = sub(tce_db, tne_db, pOverflow); + st->tsnr = xt; + } + else + { + /* Calculate instantaneous frame signal-to-noise ratio */ + /* xt = 10*log10( sum(2.^(ch_snr*0.1*log2(10)))/length(ch_snr) ) */ + Ltmp1 = 0; + for (i = LO_CHAN; i <= HI_CHAN; i++) + { + /* Ltmp2 = ch_snr[i] * 0.1 * log2(10); (ch_snr scaled as 7,8) */ + Ltmp2 = L_mult(ch_snr[i], 10885, pOverflow); + Ltmp2 = L_shr(Ltmp2, 8, pOverflow); + + L_Extract(Ltmp2, &hi1, &lo1, pOverflow); + hi1 = add(hi1, 3, pOverflow); /* 2^3 to compensate for negative SNR */ + + Ltmp2 = Pow2(hi1, lo1, pOverflow); + + Ltmp1 = L_add(Ltmp1, Ltmp2, pOverflow); + } + xt = + fn10Log10( + Ltmp1, + 4 + 3, + pOverflow); /* average by 16, inverse compensation 2^3 */ + + /* Estimate long-term "peak" SNR */ + if (xt > st->tsnr) + { + Ltmp1 = L_mult(29491, st->tsnr, pOverflow); + Ltmp2 = L_mult(3277, xt, pOverflow); + Ltmp1 = L_add(Ltmp1, Ltmp2, pOverflow); + + /* tsnr = 0.9*tsnr + 0.1*xt; */ + st->tsnr = pv_round(Ltmp1, pOverflow); + } + /* else if (xt > 0.625*tsnr) */ + else + { + tmp = mult(20480, st->tsnr, pOverflow); + tmp = sub(xt, tmp, pOverflow); + + if (tmp > 0) + { + /* tsnr = 0.998*tsnr + 0.002*xt; */ + Ltmp1 = L_mult(32702, st->tsnr, pOverflow); + Ltmp2 = L_mult(66, xt, pOverflow); + Ltmp1 = L_add(Ltmp1, Ltmp2, pOverflow); + + st->tsnr = pv_round(Ltmp1, pOverflow); + } + } + } + + /* Quantize the long-term SNR in 3 dB steps, limit to 0 <= tsnrq <= 19 */ + tmp = mult(st->tsnr, 10923, pOverflow); + tsnrq = shr(tmp, 8, pOverflow); + + /* tsnrq = min(19, max(0, tsnrq)); */ + if (tsnrq > 19) + { + tsnrq = 19; + } + else if (tsnrq < 0) + { + tsnrq = 0; + } + + /* Calculate the negative SNR sensitivity bias */ + if (xt < 0) + { + /* negSNRvar = 0.99*negSNRvar + 0.01*xt*xt; */ + /* xt scaled as 7,8 => xt*xt scaled as 14,17, shift to 7,8 and round */ + Ltmp1 = L_mult(xt, xt, pOverflow); + Ltmp1 = L_shl(Ltmp1, 7, pOverflow); + tmp = pv_round(Ltmp1, pOverflow); + + Ltmp1 = L_mult(32440, st->negSNRvar, pOverflow); + Ltmp2 = L_mult(328, tmp, pOverflow); + Ltmp1 = L_add(Ltmp1, Ltmp2, pOverflow); + + st->negSNRvar = pv_round(Ltmp1, pOverflow); + + /* if (negSNRvar > 4.0) negSNRvar = 4.0; */ + if (st->negSNRvar > 1024) + { + st->negSNRvar = 1024; + } + + /* negSNRbias = max(12.0*(negSNRvar - 0.65), 0.0); */ + tmp = sub(st->negSNRvar, 166, pOverflow); + tmp = shl(tmp, 4, pOverflow); + tmp = mult_r(tmp, 24576, pOverflow); + + if (tmp < 0) + { + st->negSNRbias = 0; + } + else + { + st->negSNRbias = shr(tmp, 8, pOverflow); + } + } + + + /* Determine VAD as a function of the voice metric sum and quantized SNR */ + + tmp = add(vm_threshold_table[tsnrq], st->negSNRbias, pOverflow); + + if (vm_sum > tmp) + { + ivad = 1; + st->burstcount = add(st->burstcount, 1, pOverflow); + if (st->burstcount > burstcount_table[tsnrq]) + { + st->hangover = hangover_table[tsnrq]; + } + } + else + { + st->burstcount = 0; + st->hangover = sub(st->hangover, 1, pOverflow); + if (st->hangover <= 0) + { + ivad = 0; + st->hangover = 0; + } + else + { + ivad = 1; + } + } + + + /* Calculate log spectral deviation */ + ch_enrg_dev = 0; + if (st->Lframe_cnt == 1) + { + for (i = LO_CHAN; i <= HI_CHAN; i++) + { + st->ch_enrg_long_db[i] = ch_enrg_db[i]; + } + } + else + { + for (i = LO_CHAN; i <= HI_CHAN; i++) + { + tmp = sub(st->ch_enrg_long_db[i], ch_enrg_db[i], pOverflow); + tmp = abs_s(tmp); + + ch_enrg_dev = add(ch_enrg_dev, tmp, pOverflow); + } + } + + /* + * Calculate long term integration constant as + * a function of instantaneous SNR + * (i.e., high SNR (tsnr dB) -> slower integration (alpha = HIGH_ALPHA), + * low SNR (0 dB) -> faster integration (alpha = LOW_ALPHA) + */ + + /* alpha = HIGH_ALPHA - ALPHA_RANGE * (tsnr - xt) + * ---------------------------------------------- + * tsnr, low <= alpha <= high + */ + tmp = sub(st->tsnr, xt, pOverflow); + if (tmp <= 0 || st->tsnr <= 0) + { + alpha = HIGH_ALPHA; + one_m_alpha = 32768L - HIGH_ALPHA; + } + else if (tmp > st->tsnr) + { + alpha = LOW_ALPHA; + one_m_alpha = 32768L - LOW_ALPHA; + } + else + { + tmp = div_s(tmp, st->tsnr); + tmp = mult(ALPHA_RANGE, tmp, pOverflow); + alpha = sub(HIGH_ALPHA, tmp, pOverflow); + one_m_alpha = sub(32767, alpha, pOverflow); + } + + /* Calc long term log spectral energy */ + for (i = LO_CHAN; i <= HI_CHAN; i++) + { + Ltmp1 = L_mult(one_m_alpha, ch_enrg_db[i], pOverflow); + Ltmp2 = L_mult(alpha, st->ch_enrg_long_db[i], pOverflow); + + Ltmp1 = L_add(Ltmp1, Ltmp2, pOverflow); + st->ch_enrg_long_db[i] = pv_round(Ltmp1, pOverflow); + } + + + /* Set or clear the noise update flags */ + update_flag = FALSE; + st->fupdate_flag = FALSE; + if (vm_sum <= UPDATE_THLD) + { + if (st->burstcount == 0) + { + update_flag = TRUE; + st->update_cnt = 0; + } + } + else if (L_sub(Ltce, noise_floor_chan[st->shift_state], pOverflow) > 0) + { + if (ch_enrg_dev < DEV_THLD) + { + if (p2a_flag == FALSE) + { + if (st->LTP_flag == FALSE) + { + st->update_cnt = add(st->update_cnt, 1, pOverflow); + if (st->update_cnt >= UPDATE_CNT_THLD) + { + update_flag = TRUE; + st->fupdate_flag = TRUE; + } + } + } + } + } + if (st->update_cnt == st->last_update_cnt) + { + st->hyster_cnt = add(st->hyster_cnt, 1, pOverflow); + } + else + { + st->hyster_cnt = 0; + } + + st->last_update_cnt = st->update_cnt; + + if (st->hyster_cnt > HYSTER_CNT_THLD) + { + st->update_cnt = 0; + } + + + /* Conditionally update the channel noise estimates */ + if (update_flag == TRUE) + { + /* Check shift state */ + if (st->shift_state == 1) + { + /* get factor to shift ch_enrg[] + * from state 1 to 0 (noise always state 0) + */ + tmp = state_change_shift_r[0]; + } + else + { + /* No shift if already state 0 */ + tmp = 0; + } + + /* Update noise energy estimate */ + for (i = LO_CHAN; i <= HI_CHAN; i++) + { + /* integrate over time: en[i] = (1-alpha)*en[i] + alpha*e[n] */ + /* (extract with shift compensation for state 1) */ + + Ltmp1 = L_shr(st->Lch_enrg[i], tmp, pOverflow); + L_Extract(Ltmp1, &hi1, &lo1, pOverflow); + + Ltmp = Mpy_32_16(hi1, lo1, CNE_SM_FAC, pOverflow); + + L_Extract(st->Lch_noise[i], &hi1, &lo1, pOverflow); + + Ltmp1 = Mpy_32_16(hi1, lo1, ONE_MINUS_CNE_SM_FAC, pOverflow); + st->Lch_noise[i] = L_add(Ltmp, Ltmp1, pOverflow); + + /* Limit low level noise */ + if (st->Lch_noise[i] <= MIN_NOISE_ENRG_0) + { + st->Lch_noise[i] = MIN_NOISE_ENRG_0; + } + } + } + + return(ivad); +} /* end of vad2 () */ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad2_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state -- double pointer to type vadState2 -- pointer to memory to + be initialized. + + Outputs: + state -- points to initalized area in memory. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Allocates state memory and initializes state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad2.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 vad2_init(vadState2 **state) +{ + vadState2* s; + + if (state == (vadState2 **) NULL) + { + return -1; + } + *state = NULL; + + /* allocate memory */ + if ((s = (vadState2 *) oscl_malloc(sizeof(vadState2))) == NULL) + { + return -1; + } + + vad2_reset(s); + + *state = s; + + return 0; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad2_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state -- pointer to type vadState1 -- State struct + + Outputs: + state -- pointer to type vadState1 -- State struct + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose: Resets state memory to zero + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad2.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 vad2_reset(vadState2 * st) +{ + Word16 i; + Word16 *ptr; + + if (st == (vadState2 *) NULL) + { + return -1; + } + ptr = (Word16 *)st; + + for (i = 0; i < sizeof(vadState2) / 2; i++) + { + *ptr++ = 0; + } + + return 0; +} /* end of vad2_reset () */ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad2_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state -- pointer to type vadState1 -- State struct + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + The memory used for state memory is freed + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad2.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void vad2_exit(vadState2 **state) +{ + if (state == NULL || *state == NULL) + { + return; + } + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/weight_a.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/weight_a.cpp new file mode 100644 index 00000000..98382b84 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/weight_a.cpp @@ -0,0 +1,155 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: weight_a.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "weight_a.h" +#include "typedef.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Weight_Ai +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + a = LPC coefficients (Word16) + fac = Spectral expansion factors (Word16) + a_exp = Spectral expanded LPC coefficients (Word16) + + Outputs: + a_exp points to the updated spectral expanded LPC coefficients + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calculates the spectral expansion for the LP coefficients of + order M. + a_exp[i] = a[i] * fac[i-1] ; i=1..M + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + weight_a.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Weight_Ai ( + Word16 a[], // (i) : a[M+1] LPC coefficients (M=10) + const Word16 fac[], // (i) : Spectral expansion factors. + Word16 a_exp[] // (o) : Spectral expanded LPC coefficients +) +{ + Word16 i; + a_exp[0] = a[0]; + + for (i = 1; i <= M; i++) + { + a_exp[i] = pv_round (L_mult (a[i], fac[i - 1])); + } + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +OSCL_EXPORT_REF void Weight_Ai( + Word16 a[], /* (i) : a[M+1] LPC coefficients (M=10) */ + const Word16 fac[], /* (i) : Spectral expansion factors. */ + Word16 a_exp[] /* (o) : Spectral expanded LPC coefficients */ +) +{ + register Word16 i; + + *(a_exp) = *(a); + + for (i = M; i >= 1; i--) + { + a_exp += 1; + a += 1; + fac += 1; + *(a_exp) = (Word16)((((Word32) * (a)) * *(fac - 1) + + 0x00004000L) >> 15); + } + + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/window_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/window_tab.cpp new file mode 100644 index 00000000..14ecf2eb --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/common/src/window_tab.cpp @@ -0,0 +1,244 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: window_tab.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + None + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + File : window.tab + Purpose : Hamming_cos window for LPC analysis. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "window_tab.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; LOCAL STORE/BUFFER/POINTER DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + /************************************************************************* + * + * Hamming_cos windows for LPC analysis. + * + *************************************************************************/ + + /* window for non-EFR modesm; uses 40 samples lookahead */ + + const Word16 window_200_40[L_WINDOW] = + { + 2621, 2623, 2629, 2638, 2651, 2668, 2689, 2713, 2741, 2772, + 2808, 2847, 2890, 2936, 2986, 3040, 3097, 3158, 3223, 3291, + 3363, 3438, 3517, 3599, 3685, 3774, 3867, 3963, 4063, 4166, + 4272, 4382, 4495, 4611, 4731, 4853, 4979, 5108, 5240, 5376, + 5514, 5655, 5800, 5947, 6097, 6250, 6406, 6565, 6726, 6890, + 7057, 7227, 7399, 7573, 7750, 7930, 8112, 8296, 8483, 8672, + 8863, 9057, 9252, 9450, 9650, 9852, 10055, 10261, 10468, 10677, + 10888, 11101, 11315, 11531, 11748, 11967, 12187, 12409, 12632, 12856, + 13082, 13308, 13536, 13764, 13994, 14225, 14456, 14688, 14921, 15155, + 15389, 15624, 15859, 16095, 16331, 16568, 16805, 17042, 17279, 17516, + 17754, 17991, 18228, 18465, 18702, 18939, 19175, 19411, 19647, 19882, + 20117, 20350, 20584, 20816, 21048, 21279, 21509, 21738, 21967, 22194, + 22420, 22644, 22868, 23090, 23311, 23531, 23749, 23965, 24181, 24394, + 24606, 24816, 25024, 25231, 25435, 25638, 25839, 26037, 26234, 26428, + 26621, 26811, 26999, 27184, 27368, 27548, 27727, 27903, 28076, 28247, + 28415, 28581, 28743, 28903, 29061, 29215, 29367, 29515, 29661, 29804, + 29944, 30081, 30214, 30345, 30472, 30597, 30718, 30836, 30950, 31062, + 31170, 31274, 31376, 31474, 31568, 31659, 31747, 31831, 31911, 31988, + 32062, 32132, 32198, 32261, 32320, 32376, 32428, 32476, 32521, 32561, + 32599, 32632, 32662, 32688, 32711, 32729, 32744, 32755, 32763, 32767, + 32767, 32741, 32665, 32537, 32359, 32129, 31850, 31521, 31143, 30716, + 30242, 29720, 29151, 28538, 27879, 27177, 26433, 25647, 24821, 23957, + 23055, 22117, 21145, 20139, 19102, 18036, 16941, 15820, 14674, 13505, + 12315, 11106, 9879, 8637, 7381, 6114, 4838, 3554, 2264, 971 + }; + + + /* window for EFR, first two subframes, no lookahead */ + + const Word16 window_160_80[L_WINDOW] = + { + 2621, 2624, 2633, 2648, 2668, 2695, 2727, 2765, 2809, 2859, + 2915, 2976, 3043, 3116, 3194, 3279, 3368, 3464, 3565, 3671, + 3783, 3900, 4023, 4151, 4285, 4423, 4567, 4716, 4870, 5029, + 5193, 5362, 5535, 5714, 5897, 6084, 6277, 6473, 6674, 6880, + 7089, 7303, 7521, 7742, 7968, 8197, 8430, 8667, 8907, 9151, + 9398, 9648, 9902, 10158, 10417, 10680, 10945, 11212, 11482, 11755, + 12030, 12307, 12586, 12867, 13150, 13435, 13722, 14010, 14299, 14590, + 14882, 15175, 15469, 15764, 16060, 16356, 16653, 16950, 17248, 17546, + 17844, 18141, 18439, 18736, 19033, 19330, 19625, 19920, 20214, 20507, + 20799, 21090, 21380, 21668, 21954, 22239, 22522, 22803, 23083, 23360, + 23635, 23907, 24177, 24445, 24710, 24972, 25231, 25488, 25741, 25991, + 26238, 26482, 26722, 26959, 27192, 27422, 27647, 27869, 28087, 28300, + 28510, 28715, 28916, 29113, 29305, 29493, 29676, 29854, 30028, 30197, + 30361, 30519, 30673, 30822, 30966, 31105, 31238, 31366, 31489, 31606, + 31718, 31825, 31926, 32021, 32111, 32195, 32273, 32346, 32413, 32475, + 32530, 32580, 32624, 32662, 32695, 32721, 32742, 32756, 32765, 32767, + 32767, 32756, 32720, 32661, 32578, 32471, 32341, 32188, 32012, 31813, + 31592, 31349, 31084, 30798, 30492, 30165, 29818, 29453, 29068, 28666, + 28247, 27810, 27358, 26891, 26408, 25913, 25404, 24883, 24350, 23807, + 23255, 22693, 22124, 21548, 20965, 20378, 19786, 19191, 18593, 17994, + 17395, 16796, 16199, 15604, 15012, 14424, 13842, 13265, 12696, 12135, + 11582, 11039, 10507, 9986, 9477, 8981, 8499, 8031, 7579, 7143, + 6723, 6321, 5937, 5571, 5225, 4898, 4591, 4305, 4041, 3798, + 3577, 3378, 3202, 3048, 2918, 2812, 2729, 2669, 2633, 2621 + }; + + /* window for EFR, last two subframes, no lookahead */ + + const Word16 window_232_8[L_WINDOW] = + { + 2621, 2623, 2627, 2634, 2644, 2656, 2671, 2689, 2710, 2734, + 2760, 2789, 2821, 2855, 2893, 2933, 2975, 3021, 3069, 3120, + 3173, 3229, 3288, 3350, 3414, 3481, 3550, 3622, 3697, 3774, + 3853, 3936, 4021, 4108, 4198, 4290, 4385, 4482, 4582, 4684, + 4788, 4895, 5004, 5116, 5230, 5346, 5464, 5585, 5708, 5833, + 5960, 6090, 6221, 6355, 6491, 6629, 6769, 6910, 7054, 7200, + 7348, 7498, 7649, 7803, 7958, 8115, 8274, 8434, 8597, 8761, + 8926, 9093, 9262, 9432, 9604, 9778, 9952, 10129, 10306, 10485, + 10665, 10847, 11030, 11214, 11399, 11586, 11773, 11962, 12152, 12342, + 12534, 12727, 12920, 13115, 13310, 13506, 13703, 13901, 14099, 14298, + 14497, 14698, 14898, 15100, 15301, 15504, 15706, 15909, 16112, 16316, + 16520, 16724, 16928, 17132, 17337, 17541, 17746, 17950, 18155, 18359, + 18564, 18768, 18972, 19175, 19379, 19582, 19785, 19987, 20189, 20390, + 20591, 20792, 20992, 21191, 21390, 21588, 21785, 21981, 22177, 22372, + 22566, 22759, 22951, 23143, 23333, 23522, 23710, 23897, 24083, 24268, + 24451, 24633, 24814, 24994, 25172, 25349, 25525, 25699, 25871, 26042, + 26212, 26380, 26546, 26711, 26874, 27035, 27195, 27353, 27509, 27664, + 27816, 27967, 28115, 28262, 28407, 28550, 28691, 28830, 28967, 29102, + 29234, 29365, 29493, 29619, 29743, 29865, 29985, 30102, 30217, 30330, + 30440, 30548, 30654, 30757, 30858, 30956, 31052, 31146, 31237, 31326, + 31412, 31495, 31576, 31655, 31730, 31804, 31874, 31942, 32008, 32071, + 32131, 32188, 32243, 32295, 32345, 32392, 32436, 32477, 32516, 32552, + 32585, 32615, 32643, 32668, 32690, 32709, 32726, 32740, 32751, 32759, + 32765, 32767, 32767, 32097, 30112, 26895, 22576, 17333, 11380, 4962 + }; + + /*---------------------------------------------------------------------------- + ; EXTERNAL FUNCTION REFERENCES + ; Declare functions defined elsewhere and referenced in this module + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; Define all local variables +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Function body here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Return nothing or data or data pointer +----------------------------------------------------------------------------*/ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/Android.mk b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/Android.mk new file mode 100644 index 00000000..48ecacb9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/Android.mk @@ -0,0 +1,64 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + src/decoder_gsm_amr.cpp \ + src/a_refl.cpp \ + src/agc.cpp \ + src/amrdecode.cpp \ + src/b_cn_cod.cpp \ + src/bgnscd.cpp \ + src/c_g_aver.cpp \ + src/d1035pf.cpp \ + src/d2_11pf.cpp \ + src/d2_9pf.cpp \ + src/d3_14pf.cpp \ + src/d4_17pf.cpp \ + src/d8_31pf.cpp \ + src/d_gain_c.cpp \ + src/d_gain_p.cpp \ + src/d_plsf.cpp \ + src/d_plsf_3.cpp \ + src/d_plsf_5.cpp \ + src/dec_amr.cpp \ + src/dec_gain.cpp \ + src/dec_input_format_tab.cpp \ + src/dec_lag3.cpp \ + src/dec_lag6.cpp \ + src/dtx_dec.cpp \ + src/ec_gains.cpp \ + src/ex_ctrl.cpp \ + src/if2_to_ets.cpp \ + src/int_lsf.cpp \ + src/lsp_avg.cpp \ + src/ph_disp.cpp \ + src/post_pro.cpp \ + src/preemph.cpp \ + src/pstfilt.cpp \ + src/qgain475_tab.cpp \ + src/sp_dec.cpp \ + src/wmf_to_ets.cpp + + +LOCAL_MODULE := libpvdecoder_gsmamr + +LOCAL_CFLAGS := $(PV_CFLAGS) +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := + +LOCAL_SHARED_LIBRARIES := + +LOCAL_C_INCLUDES := \ + $(PV_TOP)/codecs_v2/audio/gsm_amr/amr_nb/dec/src \ + $(PV_TOP)/codecs_v2/audio/gsm_amr/amr_nb/dec/include \ + $(PV_TOP)/codecs_v2/audio/gsm_amr/amr_nb/common/include \ + $(PV_INCLUDES) + +LOCAL_COPY_HEADERS_TO := $(PV_COPY_HEADERS_TO) + +LOCAL_COPY_HEADERS := \ + include/decoder_gsm_amr.h \ + include/pvamrnbdecoder_api.h + +include $(BUILD_STATIC_LIBRARY) diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/build/make/local.mk b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/build/make/local.mk new file mode 100644 index 00000000..f5fcc150 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/build/make/local.mk @@ -0,0 +1,58 @@ +# Get the current local path as the first operation +LOCAL_PATH := $(call get_makefile_dir) + +# Clear out the variables used in the local makefiles +include $(MK)/clear.mk + +TARGET := pvdecoder_gsmamr + + +OPTIMIZE_FOR_PERFORMANCE_OVER_SIZE := true + +XINCDIRS := ../../../common/include + +SRCDIR := ../../src +INCSRCDIR := ../../include + +SRCS := decoder_gsm_amr.cpp \ + a_refl.cpp \ + agc.cpp \ + amrdecode.cpp \ + b_cn_cod.cpp \ + bgnscd.cpp \ + c_g_aver.cpp \ + d1035pf.cpp \ + d2_11pf.cpp \ + d2_9pf.cpp \ + d3_14pf.cpp \ + d4_17pf.cpp \ + d8_31pf.cpp \ + d_gain_c.cpp \ + d_gain_p.cpp \ + d_plsf.cpp \ + d_plsf_3.cpp \ + d_plsf_5.cpp \ + dec_amr.cpp \ + dec_gain.cpp \ + dec_input_format_tab.cpp \ + dec_lag3.cpp \ + dec_lag6.cpp \ + dtx_dec.cpp \ + ec_gains.cpp \ + ex_ctrl.cpp \ + if2_to_ets.cpp \ + int_lsf.cpp \ + lsp_avg.cpp \ + ph_disp.cpp \ + post_pro.cpp \ + preemph.cpp \ + pstfilt.cpp \ + qgain475_tab.cpp \ + sp_dec.cpp \ + wmf_to_ets.cpp + +HDRS := decoder_gsm_amr.h pvamrnbdecoder_api.h + +include $(MK)/library.mk + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/include/decoder_gsm_amr.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/include/decoder_gsm_amr.h new file mode 100644 index 00000000..5fab78de --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/include/decoder_gsm_amr.h @@ -0,0 +1,71 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +////////////////////////////////////////////////////////////////////////////////// +// // +// File: decoder_amr_nb.h // +// // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef _DECODER_AMR_NB_H +#define _DECODER_AMR_NB_H + +#include "oscl_base.h" +#include "pvgsmamrdecoderinterface.h" + +// CDecoder_AMR_WB +class CDecoder_AMRInterface; +class CDecoder_AMR_NB: public CDecoder_AMRInterface +{ + public: + OSCL_IMPORT_REF void ConstructL(); + OSCL_IMPORT_REF static CDecoder_AMR_NB *NewL(); + OSCL_IMPORT_REF virtual ~CDecoder_AMR_NB(); + + OSCL_IMPORT_REF virtual int32 StartL(tPVAmrDecoderExternal * pExt, + bool aAllocateInputBuffer = false, + bool aAllocateOutputBuffer = false); + + OSCL_IMPORT_REF virtual int32 ExecuteL(tPVAmrDecoderExternal * pExt); + + OSCL_IMPORT_REF virtual int32 ResetDecoderL(); + OSCL_IMPORT_REF virtual void StopL(); + OSCL_IMPORT_REF virtual void TerminateDecoderL(); + + private: + void* iDecState; + + int16* iInputBuf; + int16* iOutputBuf; + + +}; + + +#endif + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/include/pvamrnbdecoder_api.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/include/pvamrnbdecoder_api.h new file mode 100644 index 00000000..7c324c54 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/include/pvamrnbdecoder_api.h @@ -0,0 +1,116 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Name: pvamrnbdecoder_api.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + Main header file for the Packet Video AMR Narrow Band decoder library. The + constants, structures, and functions defined within this file, along with + a basic data types header file, is all that is needed to use and communicate + with the library. The internal data structures within the library are + purposely hidden. + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef _PVAMRNBDECODER_API_H +#define _PVAMRNBDECODER_API_H + +#include "oscl_base.h" /* Basic data types used within the lib */ +#include "pvgsmamrdecoderinterface.h" + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define MAX_NUM_FRAMES_PER_PACKET 20 /* Max number of frames per packet */ + +#define MAX_NUM_PACKED_INPUT_BYTES 32 /* Max number of packed input bytes */ + +#define L_FRAME 160 + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + + +#endif /* PVMP4AUDIODECODER_API_H */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/a_refl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/a_refl.cpp new file mode 100644 index 00000000..674094f1 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/a_refl.cpp @@ -0,0 +1,283 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: a_refl.cpp + Functions: a_refl + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "a_refl.h" +#include "typedef.h" +#include "cnst.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS [optional] +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES [optional] +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: AMREncode +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + a[] = pointer to directform coefficients of type Word16 + refl[] = pointer to reflection coefficients of type Word16 + + Outputs: + pOverflow = 1 if overflow exists in the math operations else zero. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + File : a_refl.c + Purpose : Convert from direct form coefficients to + reflection coefficients + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] a_refl.c , 3GPP TS 26.101 version 4.1.0 Release 4, June 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +void A_Refl( + Word16 a[], // i : Directform coefficients + Word16 refl[] // o : Reflection coefficients +) +{ + // local variables + Word16 i,j; + Word16 aState[M]; + Word16 bState[M]; + Word16 normShift; + Word16 normProd; + Word32 L_acc; + Word16 scale; + Word32 L_temp; + Word16 temp; + Word16 mult; + + // initialize states + for (i = 0; i < M; i++) + { + aState[i] = a[i]; + } + + // backward Levinson recursion + for (i = M-1; i >= 0; i--) + { + if (sub(abs_s(aState[i]), 4096) >= 0) + { + goto ExitRefl; + } + + refl[i] = shl(aState[i], 3); + + L_temp = L_mult(refl[i], refl[i]); + L_acc = L_sub(MAX_32, L_temp); + + normShift = norm_l(L_acc); + scale = sub(15, normShift); + + L_acc = L_shl(L_acc, normShift); + normProd = pv_round(L_acc); + + mult = div_s(16384, normProd); + + for (j = 0; j < i; j++) + { + L_acc = L_deposit_h(aState[j]); + L_acc = L_msu(L_acc, refl[i], aState[i-j-1]); + + temp = pv_round(L_acc); + L_temp = L_mult(mult, temp); + L_temp = L_shr_r(L_temp, scale); + + if (L_sub(L_abs(L_temp), 32767) > 0) + { + goto ExitRefl; + } + + bState[j] = extract_l(L_temp); + } + + for (j = 0; j < i; j++) + { + aState[j] = bState[j]; + } + } + return; + +ExitRefl: + for (i = 0; i < M; i++) + { + refl[i] = 0; + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void A_Refl( + Word16 a[], /* i : Directform coefficients */ + Word16 refl[], /* o : Reflection coefficients */ + Flag *pOverflow +) +{ + /* local variables */ + Word16 i; + Word16 j; + Word16 aState[M]; + Word16 bState[M]; + Word16 normShift; + Word16 normProd; + Word32 L_acc; + Word16 scale; + Word32 L_temp; + Word16 temp; + Word16 mult; + + /* initialize states */ + for (i = 0; i < M; i++) + { + aState[i] = a[i]; + } + + /* backward Levinson recursion */ + for (i = M - 1; i >= 0; i--) + { + if (abs_s(aState[i]) >= 4096) + { + for (i = 0; i < M; i++) + { + refl[i] = 0; + } + break; + } + + refl[i] = shl(aState[i], 3, pOverflow); + + L_temp = L_mult(refl[i], refl[i], pOverflow); + L_acc = L_sub(MAX_32, L_temp, pOverflow); + + normShift = norm_l(L_acc); + scale = 15 - normShift; + + L_acc = L_shl(L_acc, normShift, pOverflow); + normProd = pv_round(L_acc, pOverflow); + + mult = div_s(16384, normProd); + + for (j = 0; j < i; j++) + { + L_acc = ((Word32)aState[j] << 16); + L_acc = L_msu(L_acc, refl[i], aState[i-j-1], pOverflow); + + temp = pv_round(L_acc, pOverflow); + L_temp = L_mult(mult, temp, pOverflow); + L_temp = L_shr_r(L_temp, scale, pOverflow); + + + Word32 L_tmp_abs = L_temp - (L_temp < 0); + L_tmp_abs = L_tmp_abs ^(L_tmp_abs >> 31); + + if (L_tmp_abs > 32767) + { + for (i = 0; i < M; i++) + { + refl[i] = 0; + } + break; + } + + bState[j] = (Word16)(L_temp); + } + + for (j = 0; j < i; j++) + { + aState[j] = bState[j]; + } + } + return; +} + + + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/a_refl.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/a_refl.h new file mode 100644 index 00000000..d16e5729 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/a_refl.h @@ -0,0 +1,115 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: a_refl.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : a_refl.h + Purpose : Convert from direct form coefficients to + reflection coefficients + +------------------------------------------------------------------------------ +*/ + +#ifndef A_REFL_H +#define A_REFL_H +#define a_refl_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + /* + * FUNCTION: A_Refl() + * PURPOSE: Convert from direct form coefficients to reflection coefficients + * DESCRIPTION: + * Directform coeffs in Q12 are converted to + * reflection coefficients Q15 + */ + void A_Refl( + Word16 a[], /* i : Directform coefficients */ + Word16 refl[], /* o : Reflection coefficients */ + Flag *pOverflow + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _A_REFL_H_ */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/agc.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/agc.cpp new file mode 100644 index 00000000..9f5525d0 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/agc.cpp @@ -0,0 +1,954 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: agc.cpp + Funtions: energy_old + energy_new + agc_init + agc_reset + agc_exit + agc + agc2 + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This set of modules scale the excitation level and output of the speech + signals. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "agc.h" +#include "cnst.h" +#include "inv_sqrt.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: energy_old +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + in = input signal (Word16) + l_trm = input signal length (Word16) + pOverflow = address of overflow (Flag) + + Outputs: + pOverflow -> 1 if the energy computation saturates + + Returns: + s = return energy of signal (Word32) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Returns the energy of the signal. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + agc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static Word32 energy_old( // o : return energy of signal + Word16 in[], // i : input signal (length l_trm) + Word16 l_trm // i : signal length +) +{ + Word32 s; + Word16 i, temp; + + temp = shr (in[0], 2); + s = L_mult (temp, temp); + + for (i = 1; i < l_trm; i++) + { + temp = shr (in[i], 2); + s = L_mac (s, temp, temp); + } + + return s; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word32 energy_old( /* o : return energy of signal */ + Word16 in[], /* i : input signal (length l_trm) */ + Word16 l_trm, /* i : signal length */ + Flag *pOverflow /* overflow: flag to indicate overflow */ +) + +{ + Word32 s = 0; + Word16 i; + Word16 temp; + + for (i = 0; i < l_trm; i++) + { + temp = in[i] >> 2; + s = L_mac(s, temp, temp, pOverflow); + } + + return(s); +} + +/*----------------------------------------------------------------------------*/ +/* +------------------------------------------------------------------------------ + FUNCTION NAME: energy_old__Wrapper +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + in = input signal (Word16) + l_trm = input signal length (Word16) + pOverflow = address of overflow (Flag) + Outputs: + pOverflow -> 1 if the energy computation saturates + + Returns: + s = return energy of signal (Word32) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function provides external access to the static function energy_old. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + CALL energy_old ( in = in + l_trm = l_trm + pOverflow = pOverflow ) + MODIFYING(nothing) + RETURNING(energy_old_value = s) + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word32 energy_old_Wrapper(Word16 in[], Word16 l_trm, Flag *pOverflow) +{ + Word32 energy_old_value; + + /*---------------------------------------------------------------------------- + CALL energy_old ( in = in + l_trm = l_trm + pOverflow = pOverflow ) + + MODIFYING(nothing) + RETURNING(energy_old_value = s) + ----------------------------------------------------------------------------*/ + energy_old_value = energy_old(in, l_trm, pOverflow); + return(energy_old_value); +} +/*--------------------------------------------------------------------------*/ + +/* +----------------------------------------------------------------------------- + FUNCTION NAME: energy_new +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + in = input signal + l_trm = input signal length + pOverflow = address of overflow (Flag) + + Outputs: + pOverflow -> 1 if the energy computation saturates + + Returns: + s = return energy of signal + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Returns the energy of the signal. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + agc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static Word32 energy_new( // o : return energy of signal + Word16 in[], // i : input signal (length l_trm) + Word16 l_trm ) // i : signal length + +{ + Word32 s; + Word16 i; + Flag ov_save; + + ov_save = Overflow; //save overflow flag in case energy_old + // must be called + s = L_mult(in[0], in[0]); + for (i = 1; i < l_trm; i++) + { + s = L_mac(s, in[i], in[i]); + } + + // check for overflow + if (L_sub (s, MAX_32) == 0L) + { + Overflow = ov_save; // restore overflow flag + s = energy_old (in, l_trm); // function result + } + else + { + s = L_shr(s, 4); + } + + return(s); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word32 energy_new( /* o : return energy of signal */ + Word16 in[], /* i : input signal (length l_trm) */ + Word16 l_trm, /* i : signal length */ + Flag *pOverflow /* i : overflow flag */ +) + +{ + Word32 s = 0; + Word16 i; + Flag ov_save; + + ov_save = *(pOverflow); /* save overflow flag in case energy_old */ + /* must be called */ + + + for (i = 0; i < l_trm; i++) + { + s = L_mac(s, in[i], in[i], pOverflow); + } + + /* check for overflow */ + if (s != MAX_32) + { + /* s is a sum of squares, so it won't be negative */ + s = s >> 4; + } + else + { + *(pOverflow) = ov_save; /* restore overflow flag */ + s = energy_old(in, l_trm, pOverflow); /* function result */ + } + + return (s); +} + +/*--------------------------------------------------------------------------*/ +/* +------------------------------------------------------------------------------ + FUNCTION NAME: energy_new__Wrapper +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + in = input signal (Word16) + l_trm = input signal length (Word16) + overflow = address of overflow (Flag) + + Outputs: + pOverflow -> 1 if the energy computation saturates + + Returns: + s = return energy of signal (Word32) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function provides external access to the static function energy_new. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + CALL energy_new ( in = in + l_trm = l_trm + pOverflow = pOverflow ) + + MODIFYING(nothing) + + RETURNING(energy_new_value = s) + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word32 energy_new_Wrapper(Word16 in[], Word16 l_trm, Flag *pOverflow) +{ + Word32 energy_new_value; + + /*---------------------------------------------------------------------------- + CALL energy_new ( in = in + l_trm = l_trm + pOverflow = pOverflow ) + + MODIFYING(nothing) + RETURNING(energy_new_value = s) + + ----------------------------------------------------------------------------*/ + energy_new_value = energy_new(in, l_trm, pOverflow); + + return(energy_new_value); + +} + +/*--------------------------------------------------------------------------*/ + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: agc_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a structure of type agcState + + Outputs: + Structure pointed to by state is initialized to zeros + + Returns: + Returns 0 if memory was successfully initialized, + otherwise returns -1. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Reset of agc (i.e. set state memory to 1.0). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + agc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int agc_reset (agcState *state) +{ + if (state == (agcState *) NULL) + { + fprintf(stderr, "agc_reset: invalid parameter\n"); + return -1; + } + + state->past_gain = 4096; // initial value of past_gain = 1.0 + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 agc_reset(agcState *state) +{ + if (state == (agcState *) NULL) + { + /* fprintf(stderr, "agc_reset: invalid parameter\n"); */ + return(-1); + } + + state->past_gain = 4096; /* initial value of past_gain = 1.0 */ + + return(0); +} + +/*--------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: agc +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to agc state + sig_in = pointer to a buffer containing the postfilter input signal + sig_out = pointer to a buffer containing the postfilter output signal + agc_fac = AGC factor + l_trm = subframe size + pOverflow = pointer to the overflow flag + + Outputs: + st->past_gain = gain + buffer pointed to by sig_out contains the new postfilter output signal + pOverflow -> 1 if the agc computation saturates + + Returns: + return = 0 + + Global Variables Used: + none. + + Local Variables Needed: + none. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Scales the postfilter output on a subframe basis using: + + sig_out[n] = sig_out[n] * gain[n] + gain[n] = agc_fac * gain[n-1] + (1 - agc_fac) g_in/g_out + + where: gain[n] = gain at the nth sample given by + g_in/g_out = square root of the ratio of energy at + the input and output of the postfilter. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + agc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int agc ( + agcState *st, // i/o : agc state + Word16 *sig_in, // i : postfilter input signal (l_trm) + Word16 *sig_out, // i/o : postfilter output signal (l_trm) + Word16 agc_fac, // i : AGC factor + Word16 l_trm // i : subframe size +) +{ + Word16 i, exp; + Word16 gain_in, gain_out, g0, gain; + Word32 s; + + // calculate gain_out with exponent + s = energy_new(sig_out, l_trm); // function result + + if (s == 0) + { + st->past_gain = 0; + return 0; + } + exp = sub (norm_l (s), 1); + gain_out = pv_round (L_shl (s, exp)); + + // calculate gain_in with exponent + s = energy_new(sig_in, l_trm); // function result + + if (s == 0) + { + g0 = 0; + } + else + { + i = norm_l (s); + gain_in = pv_round (L_shl (s, i)); + exp = sub (exp, i); + + *---------------------------------------------------* + * g0 = (1-agc_fac) * sqrt(gain_in/gain_out); * + *---------------------------------------------------* + + s = L_deposit_l (div_s (gain_out, gain_in)); + s = L_shl (s, 7); // s = gain_out / gain_in + s = L_shr (s, exp); // add exponent + + s = Inv_sqrt (s); // function result + i = pv_round (L_shl (s, 9)); + + // g0 = i * (1-agc_fac) + g0 = mult (i, sub (32767, agc_fac)); + } + + // compute gain[n] = agc_fac * gain[n-1] + + (1-agc_fac) * sqrt(gain_in/gain_out) + // sig_out[n] = gain[n] * sig_out[n] + + gain = st->past_gain; + + for (i = 0; i < l_trm; i++) + { + gain = mult (gain, agc_fac); + gain = add (gain, g0); + sig_out[i] = extract_h (L_shl (L_mult (sig_out[i], gain), 3)); + } + + st->past_gain = gain; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void agc( + agcState *st, /* i/o : agc state */ + Word16 *sig_in, /* i : postfilter input signal (l_trm) */ + Word16 *sig_out, /* i/o : postfilter output signal (l_trm) */ + Word16 agc_fac, /* i : AGC factor */ + Word16 l_trm, /* i : subframe size */ + Flag *pOverflow /* i : overflow Flag */ + +) + +{ + Word16 i; + Word16 exp; + Word16 gain_in; + Word16 gain_out; + Word16 g0; + Word16 gain; + Word32 s; + Word32 L_temp; + Word16 temp; + + Word16 *p_sig_out; + + /* calculate gain_out with exponent */ + s = energy_new(sig_out, l_trm, pOverflow); /* function result */ + + if (s == 0) + { + st->past_gain = 0; + return; + } + exp = norm_l(s) - 1; + + L_temp = L_shl(s, exp, pOverflow); + gain_out = pv_round(L_temp, pOverflow); + + /* calculate gain_in with exponent */ + s = energy_new(sig_in, l_trm, pOverflow); /* function result */ + + if (s == 0) + { + g0 = 0; + } + else + { + i = norm_l(s); + + /* L_temp = L_shl(s, i, pOverflow); */ + L_temp = s << i; + + gain_in = pv_round(L_temp, pOverflow); + + exp -= i; + + /*---------------------------------------------------* + * g0 = (1-agc_fac) * sqrt(gain_in/gain_out); * + *---------------------------------------------------*/ + + /* s = gain_out / gain_in */ + temp = div_s(gain_out, gain_in); + + /* s = L_deposit_l (temp); */ + s = (Word32) temp; + s = s << 7; + s = L_shr(s, exp, pOverflow); /* add exponent */ + + s = Inv_sqrt(s, pOverflow); /* function result */ + L_temp = s << 9; + + i = (Word16)((L_temp + (Word32) 0x00008000L) >> 16); + + /* g0 = i * (1-agc_fac) */ + temp = 32767 - agc_fac; + + g0 = (Word16)(((Word32) i * temp) >> 15); + + } + + /* compute gain[n] = agc_fac * gain[n-1] + + (1-agc_fac) * sqrt(gain_in/gain_out) */ + /* sig_out[n] = gain[n] * sig_out[n] */ + + gain = st->past_gain; + p_sig_out = sig_out; + + for (i = 0; i < l_trm; i++) + { + /* gain = mult (gain, agc_fac, pOverflow); */ + gain = (Word16)(((Word32) gain * agc_fac) >> 15); + + /* gain = add (gain, g0, pOverflow); */ + gain += g0; + + /* L_temp = L_mult (sig_out[i], gain, pOverflow); */ + L_temp = ((Word32)(*(p_sig_out)) * gain) << 1; + + *(p_sig_out++) = (Word16)(L_temp >> 13); + } + + st->past_gain = gain; + + return; +} + +/*--------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: agc2 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + sig_in = pointer to a buffer containing the postfilter input signal + sig_out = pointer to a buffer containing the postfilter output signal + l_trm = subframe size + pOverflow = pointer to overflow flag + + Outputs: + sig_out points to a buffer containing the new scaled output signal. + pOverflow -> 1 if the agc computation saturates + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Scales the excitation on a subframe basis. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + agc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void agc2 ( + Word16 *sig_in, // i : postfilter input signal + Word16 *sig_out, // i/o : postfilter output signal + Word16 l_trm // i : subframe size +) +{ + Word16 i, exp; + Word16 gain_in, gain_out, g0; + Word32 s; + + // calculate gain_out with exponent + s = energy_new(sig_out, l_trm); // function result + + if (s == 0) + { + return; + } + exp = sub (norm_l (s), 1); + gain_out = pv_round (L_shl (s, exp)); + + // calculate gain_in with exponent + s = energy_new(sig_in, l_trm); // function result + + if (s == 0) + { + g0 = 0; + } + else + { + i = norm_l (s); + gain_in = pv_round (L_shl (s, i)); + exp = sub (exp, i); + + *---------------------------------------------------* + * g0 = sqrt(gain_in/gain_out); * + *---------------------------------------------------* + + s = L_deposit_l (div_s (gain_out, gain_in)); + s = L_shl (s, 7); // s = gain_out / gain_in + s = L_shr (s, exp); // add exponent + + s = Inv_sqrt (s); // function result + g0 = pv_round (L_shl (s, 9)); + } + + // sig_out(n) = gain(n) sig_out(n) + + for (i = 0; i < l_trm; i++) + { + sig_out[i] = extract_h (L_shl (L_mult (sig_out[i], g0), 3)); + } + + return; +} +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void agc2( + Word16 *sig_in, /* i : postfilter input signal */ + Word16 *sig_out, /* i/o : postfilter output signal */ + Word16 l_trm, /* i : subframe size */ + Flag *pOverflow /* i : overflow flag */ +) + +{ + Word16 i; + Word16 exp; + Word16 gain_in; + Word16 gain_out; + Word16 g0; + Word32 s; + Word32 L_temp; + Word16 temp; + + /* calculate gain_out with exponent */ + s = energy_new(sig_out, l_trm, pOverflow); /* function result */ + + if (s == 0) + { + return; + } + exp = norm_l(s) - 1; + L_temp = L_shl(s, exp, pOverflow); + gain_out = pv_round(L_temp, pOverflow); + + /* calculate gain_in with exponent */ + s = energy_new(sig_in, l_trm, pOverflow); /* function result */ + + if (s == 0) + { + g0 = 0; + } + else + { + i = norm_l(s); + L_temp = L_shl(s, i, pOverflow); + gain_in = pv_round(L_temp, pOverflow); + exp -= i; + + /*---------------------------------------------------* + * g0 = sqrt(gain_in/gain_out); * + *---------------------------------------------------*/ + + /* s = gain_out / gain_in */ + temp = div_s(gain_out, gain_in); + + /* s = L_deposit_l (temp); */ + s = (Word32)temp; + + if (s > (Word32) 0x00FFFFFFL) + { + s = MAX_32; + } + else if (s < (Word32) - 16777216) + { + s = MIN_32; + } + else + { + s = s << 7; + } + s = L_shr(s, exp, pOverflow); /* add exponent */ + + s = Inv_sqrt(s, pOverflow); /* function result */ + + if (s > (Word32) 0x003FFFFFL) + { + L_temp = MAX_32; + } + else if (s < (Word32) - 4194304) + { + L_temp = MIN_32; + } + else + { + L_temp = s << 9; + } + g0 = pv_round(L_temp, pOverflow); + } + + /* sig_out(n) = gain(n) sig_out(n) */ + + for (i = l_trm - 1; i >= 0; i--) + { + L_temp = L_mult(sig_out[i], g0, pOverflow); + if (L_temp > (Word32) 0x0FFFFFFFL) + { + sig_out[i] = MAX_16; + } + else if (L_temp < (Word32) - 268435456) + { + sig_out[i] = MIN_16; + } + else + { + sig_out[i] = (Word16)(L_temp >> 13); + } + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/agc.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/agc.h new file mode 100644 index 00000000..95cb10e9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/agc.h @@ -0,0 +1,144 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: agc.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : agc.h + Purpose : Scales the postfilter output on a subframe basis + : by automatic control of the subframe gain. + +------------------------------------------------------------------------------ +*/ + +#ifndef _AGC_H_ +#define _AGC_H_ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 past_gain; + } agcState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------- + ; + ; Function : agc_reset + ; Purpose : Reset of agc (i.e. set state memory to 1.0) + ; Returns : 0 on success + ; + ----------------------------------------------------------------------------*/ + Word16 agc_reset(agcState *st); + + + /*---------------------------------------------------------------------------- + ; + ; Function : agc + ; Purpose : Scales the postfilter output on a subframe basis + ; Description : sig_out[n] = sig_out[n] * gain[n]; + ; where gain[n] is the gain at the nth sample given by + ; gain[n] = agc_fac * gain[n-1] + (1 - agc_fac) g_in/g_out + ; g_in/g_out is the square root of the ratio of energy at + ; the input and output of the postfilter. + ; + ----------------------------------------------------------------------------*/ + void agc( + agcState *st, /* i/o : agc state */ + Word16 *sig_in, /* i : postfilter input signal, (l_trm) */ + Word16 *sig_out, /* i/o : postfilter output signal, (l_trm) */ + Word16 agc_fac, /* i : AGC factor */ + Word16 l_trm, /* i : subframe size */ + Flag *pOverflow /* i : overflow flag */ + ); + + /*---------------------------------------------------------------------------- + ; + ; Function: agc2 + ; Purpose: Scales the excitation on a subframe basis + ; + ----------------------------------------------------------------------------*/ + void agc2( + Word16 *sig_in, /* i : postfilter input signal */ + Word16 *sig_out, /* i/o : postfilter output signal */ + Word16 l_trm, /* i : subframe size */ + Flag *pOverflow /* i : overflow flag */ + ); + +#ifdef __cplusplus +} +#endif + +#endif /* _AGC_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/amrdecode.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/amrdecode.cpp new file mode 100644 index 00000000..64fcf031 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/amrdecode.cpp @@ -0,0 +1,468 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + Filename: amrdecode.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "amrdecode.h" +#include "cnst.h" +#include "typedef.h" +#include "frame.h" +#include "sp_dec.h" +#include "wmf_to_ets.h" +#include "if2_to_ets.h" +#include "frame_type_3gpp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: AMRDecode +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state_data = pointer to a structure (type void) + + frame_type = 3GPP frame type (enum Frame_Type_3GPP) + + speech_bits_ptr = pointer to the beginning of the raw encoded speech bits + for the current frame to be decoded (unsigned char) + + raw_pcm_buffer = pointer to the output pcm outputs array (Word16) + + input_format = input format used; valid values are AMR_WMF, AMR_IF2, + and AMR_ETS (Word16) + + Outputs: + raw_pcm_buffer contains the newly decoded linear PCM speech samples + state_data->prev_mode contains the new mode + + Returns: + byte_offset = address offset of the next frame to be processed or + error condition flag (-1) (int) + + Global Variables Used: + WmfDecBytesPerFrame = table containing the number of core AMR data bytes + used by each codec mode for WMF input format (const + int) + + If2DecBytesPerFrame = table containing the number of core AMR data bytes + used by each codec mode for IF2 input format (const + int) + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function is the top level entry function to the GSM AMR Decoder library. + + First, it checks the input format type (input_format) to determine the type + of de-formattting that needs to be done. If input_format is AMR_WMF, the input + data is in WMF (aka, non-IF2) format and the function wmf_to_ets will be + called to convert to the ETS format (1 bit/word, where 1 word = 16 bits), + and byte_offset will be updated according to the contents of WmfDecBytesPerFrame + table. + + If input_format is AMR_IF2, the input data is in IF2 format [1] and the + function if2_to_ets will be called to convert to the ETS format, and + byte_offset will be updated according to the contents of If2DecBytesPerFrame + table. + + The codec mode and receive frame type is initialized based on the incoming + frame_type. + + If input_format is AMR_ETS, the input data is in the ETS format. The receive + frame type is set to the value in the first location of the buffer pointed to + by speech_bits_ptr. Then, the encoded speech parameters in the buffer pointed + to by speech_bits is copied to dec_ets_input_bfr and the type will be changed + from unsigned char to Word16. Lastly, if the receive frame type is not + RX_NO_DATA, the mode is obtained from the buffer pointed to by + speech_bits_ptr, offset by MAX_SERIAL_SIZE+1, otherwise, the mode is set to + the previous mode (found the in state_data->prev_mode). + + If input_format is an unsupported format, byte_offset will be set to -1, to + indicate an error condition has occurred, and the function will exit. + + If there are no errors, GSMFrameDecode is called to decode a 20 ms frame. It + puts the decoded linear PCM samples in the buffer pointed to by + raw_pcm_buffer. Then, the prev_mode field of the structure pointed to by + state_data is updated to the current mode. + + This function returns the new byte_offset value to indicate the address + offset of the next speech frame to be decoded. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] "AMR Speech Codec Frame Structure", 3GPP TS 26.101 version 4.1.0 + Release 4, June 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Note: AMRSID_RXTYPE_BIT_OFFSET = 35 + AMRSID_RXMODE_BIT_OFFSET = 36 + NUM_AMRSID_RXMODE_BITS = 3 + + + // Set up Decoder state structure pointer + Speech_Decode_FrameState *decoder_state + = (Speech_Decode_FrameState *) state_data + + // Determine type of de-formatting + + // Decode WMF or IF2 frames + IF ((input_format == AMR_RX_WMF) | (input_format == AMR_RX_IF2)) + THEN + IF (input_format == AMR_RX_WMF) + THEN + // Convert incoming packetized raw WMF data to ETS format + CALL wmf_to_ets(frame_type = frame_type + input_ptr = speech_bits_ptr + output_ptr = &dec_ets_input_bfr) + MODIFYING(nothing) + RETURNING(nothing) + + // Address offset of the start of next frame + byte_offset = WmfDecBytesPerFrame[frame_type] + + ELSEIF (input_format == AMR_RX_IF2) + THEN + // Convert incoming packetized raw IF2 data to ETS format + CALL if2_to_ets(frame_type = frame_type + input_ptr = speech_bits_ptr + output_ptr = &dec_ets_input_bfr) + MODIFYING(nothing) + RETURNING(nothing) + + // Address offset of the start of next frame + byte_offset = If2DecBytesPerFrame[frame_type] + + ENDIF + + // Determine AMR codec mode and AMR RX frame type + IF (frame_type <= AMR_122) + THEN + mode = (enum Mode) frame_type; + rx_type = RX_SPEECH_GOOD; + + ELSEIF (frame_type == AMR_SID) + THEN + // Clear mode store prior to reading mode info from input buffer + mode = 0 + + FOR i = 0 TO NUM_AMRSID_RXMODE_BITS-1 + + mode |= (dec_ets_input_bfr[AMRSID_RXMODE_BIT_OFFSET+i] << i) + + ENDFOR + + IF (dec_ets_input_bfr[AMRSID_RXTYPE_BIT_OFFSET] == 0) + THEN + rx_type = RX_SID_FIRST + + ELSE + rx_type = RX_SID_UPDATE + + ENDIF + + ELSEIF ((frame_type > AMR_SID) && (frame_type < NO_DATA)) + THEN + // Use previous mode + mode = decoder_state->prev_mode + + // Unsupported SID frames + rx_type = RX_SPEECH_BAD; + + ELSE + // Use previous mode + mode = decoder_state->prev_mode + + // No data received + rx_type = RX_NO_DATA; + + ENDIF + + // Decode ETS frames + ELSEIF (input_format == AMR_RX_ETS) + THEN + // Change type of pointer to incoming raw ETS data + ets_word_ptr = (Word16 *) speech_bits_ptr + + // Get RX frame type + rx_type = (enum RXFrameType) *ets_word_ptr + ets_word_ptr = ets_word_ptr + 1 + + // Copy incoming raw ETS data to dec_ets_input_bfr + FOR i = 0 TO MAX_SERIAL_SIZE-1 + + dec_ets_input_bfr[i] = *ets_word_ptr + ets_word_ptr = ets_word_ptr + 1 + + ENDFOR + + // Get codec mode + IF (rx_type != RX_NO_DATA) + THEN + mode = (enum Mode) *ets_word_ptr + + ELSE + //Use previous mode if no received data + mode = decoder_state->prev_mode + + ENDIF + + // Set up byte_offset + byte_offset = 2*(MAX_SERIAL_SIZE+2) + + ELSE + // Invalid format, return error code + byte_offset = -1 + + ENDIF + + // Proceed with decoding frame, if there are no errors + IF (byte_offset != -1) + THEN + // Decode a 20 ms frame + CALL GSMFrameDecode( st = decoder_state + mode = mode + serial = dec_ets_input_bfr, + frame_type = rx_type, + synth = (Word16 *)raw_pcm_buffer); + MODIFYING (nothing) + RETURNING (Nothing) + + // Save mode for next frame + decoder_state->prev_mode = mode + + ENDIF + + RETURN (byte_offset) + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 AMRDecode( + void *state_data, + enum Frame_Type_3GPP frame_type, + UWord8 *speech_bits_ptr, + Word16 *raw_pcm_buffer, + bitstream_format input_format +) +{ + Word16 *ets_word_ptr; + enum Mode mode = (enum Mode)MR475; + int modeStore; + int tempInt; + enum RXFrameType rx_type = RX_NO_DATA; + Word16 dec_ets_input_bfr[MAX_SERIAL_SIZE]; + Word16 i; + Word16 byte_offset = -1; + + /* Type cast state_data to Speech_Decode_FrameState rather than passing + * that structure type to this function so the structure make up can't + * be viewed from higher level functions than this. + */ + Speech_Decode_FrameState *decoder_state= (Speech_Decode_FrameState *) state_data; + + /* Determine type of de-formatting */ + /* WMF or IF2 frames */ + if ((input_format == MIME_IETF) | (input_format == IF2)) + { + if (input_format == MIME_IETF) + { + /* Convert incoming packetized raw WMF data to ETS format */ + wmf_to_ets(frame_type, speech_bits_ptr, dec_ets_input_bfr, &(decoder_state->decoder_amrState.common_amr_tbls)); + + /* Address offset of the start of next frame */ + byte_offset = WmfDecBytesPerFrame[frame_type]; + } + else /* else has to be input_format IF2 */ + { + /* Convert incoming packetized raw IF2 data to ETS format */ + if2_to_ets(frame_type, speech_bits_ptr, dec_ets_input_bfr, &(decoder_state->decoder_amrState.common_amr_tbls)); + + /* Address offset of the start of next frame */ + byte_offset = If2DecBytesPerFrame[frame_type]; + } + + /* At this point, input data is in ETS format */ + /* Determine AMR codec mode and AMR RX frame type */ + if (frame_type <= AMR_122) + { + mode = (enum Mode) frame_type; + rx_type = RX_SPEECH_GOOD; + } + else if (frame_type == AMR_SID) + { + /* Clear mode store prior to reading mode info from input buffer */ + modeStore = 0; + + for (i = 0; i < NUM_AMRSID_RXMODE_BITS; i++) + { + tempInt = dec_ets_input_bfr[AMRSID_RXMODE_BIT_OFFSET+i] << i; + modeStore |= tempInt; + } + mode = (enum Mode) modeStore; + + /* Get RX frame type */ + if (dec_ets_input_bfr[AMRSID_RXTYPE_BIT_OFFSET] == 0) + { + rx_type = RX_SID_FIRST; + } + else + { + rx_type = RX_SID_UPDATE; + } + } + else if (frame_type < AMR_NO_DATA) + { + /* Invalid frame_type, return error code */ + byte_offset = -1; /* !!! */ + } + else + { + mode = decoder_state->prev_mode; + + /* + * RX_NO_DATA, generate exponential decay from latest valid frame for the first 6 frames + * after that, create silent frames + */ + rx_type = RX_NO_DATA; + + } + + } + + /* ETS frames */ + else if (input_format == ETS) + { + /* Change type of pointer to incoming raw ETS data */ + ets_word_ptr = (Word16 *) speech_bits_ptr; + + /* Get RX frame type */ + rx_type = (enum RXFrameType) * ets_word_ptr; + ets_word_ptr++; + + /* Copy incoming raw ETS data to dec_ets_input_bfr */ + for (i = 0; i < MAX_SERIAL_SIZE; i++) + { + dec_ets_input_bfr[i] = *ets_word_ptr; + ets_word_ptr++; + } + + /* Get codec mode */ + if (rx_type != RX_NO_DATA) + { + /* Get mode from input bitstream */ + mode = (enum Mode) * ets_word_ptr; + } + else + { + /* Use previous mode if no received data */ + mode = decoder_state->prev_mode; + } + + /* Set up byte_offset */ + byte_offset = 2 * (MAX_SERIAL_SIZE + 2); + } + else + { + /* Invalid input format, return error code */ + byte_offset = -1; + } + + /* Proceed with decoding frame, if there are no errors */ + if (byte_offset != -1) + { + /* Decode a 20 ms frame */ + +#ifndef CONSOLE_DECODER_REF + /* Use PV version of sp_dec.c */ + GSMFrameDecode(decoder_state, mode, dec_ets_input_bfr, rx_type, + raw_pcm_buffer); + +#else + /* Use ETS version of sp_dec.c */ + Speech_Decode_Frame(decoder_state, mode, dec_ets_input_bfr, rx_type, + raw_pcm_buffer); + +#endif + + /* Save mode for next frame */ + decoder_state->prev_mode = mode; + } + + return (byte_offset); +} + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/amrdecode.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/amrdecode.h new file mode 100644 index 00000000..1715f0d1 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/amrdecode.h @@ -0,0 +1,114 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: amrdecode.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the norm_s function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef ARMDECODE_H +#define ARMDECODE_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "frame_type_3gpp.h" +#include "pvamrnbdecoder_api.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define NUM_AMRSID_RXMODE_BITS 3 +#define AMRSID_RXMODE_BIT_OFFSET 36 +#define AMRSID_RXTYPE_BIT_OFFSET 35 + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 WmfDecBytesPerFrame[]; + extern const Word16 If2DecBytesPerFrame[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + Word16 AMRDecode( + void *state_data, + enum Frame_Type_3GPP frame_type, + UWord8 *speech_bits_ptr, + Word16 *raw_pcm_buffer, + bitstream_format input_format + ); + +#ifdef __cplusplus +} +#endif + +#endif /* _AMRDECODE_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/b_cn_cod.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/b_cn_cod.cpp new file mode 100644 index 00000000..f5317e6e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/b_cn_cod.cpp @@ -0,0 +1,456 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: b_cn_cod.cpp + Functions: pseudonoise + build_CN_code + build_CN_param + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This module contains functions for comfort noise(CN) generation. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "b_cn_cod.h" +#include "basic_op.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ +#define NB_PULSE 10 /* number of random pulses in DTX operation */ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: pseudonoise +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pShift_reg = pointer to Old CN generator shift register state (Word32) + no_bits = Number of bits (Word16) + + Outputs: + pShift_reg -> Updated CN generator shift register state + + Returns: + noise_bits = Generated random integer value (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Generate a random integer value to use in comfort noise generation. The + algorithm uses polynomial x^31 + x^3 + 1. Length of the PN sequence + is 2^31 - 1 + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 pseudonoise ( + Word32 *shift_reg, // i/o : Old CN generator shift register state + Word16 no_bits // i : Number of bits +) +{ + Word16 noise_bits, Sn, i; + + noise_bits = 0; + for (i = 0; i < no_bits; i++) + { + // State n == 31 + if ((*shift_reg & 0x00000001L) != 0) + { + Sn = 1; + } + else + { + Sn = 0; + } + + // State n == 3 + if ((*shift_reg & 0x10000000L) != 0) + { + Sn = Sn ^ 1; + } + else + { + Sn = Sn ^ 0; + } + + noise_bits = shl (noise_bits, 1); + noise_bits = noise_bits | (extract_l (*shift_reg) & 1); + + *shift_reg = L_shr (*shift_reg, 1); + if (Sn & 1) + { + *shift_reg = *shift_reg | 0x40000000L; + } + } + return noise_bits; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +Word16 pseudonoise( + Word32 *pShift_reg, /* i/o : Old CN generator shift register state */ + Word16 no_bits /* i : Number of bits */ +) +{ + Word16 noise_bits; + Word16 Sn; + Word16 i; + Word16 temp; + + noise_bits = 0; + + for (i = 0; i < no_bits; i++) + { + /* State n == 31 */ + if ((*pShift_reg & 0x00000001L) != 0) + { + Sn = 1; + } + else + { + Sn = 0; + } + + /* State n == 3 */ + if ((*pShift_reg & 0x10000000L) != 0) + { + Sn ^= 1; + } + else + { + Sn ^= 0; + } + + noise_bits <<= 1; + + temp = (Word16)((*pShift_reg) & 1); + noise_bits |= temp; + + *pShift_reg >>= 1; + if (Sn & 1) + { + *pShift_reg |= 0x40000000L; + } + } + return noise_bits; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: build_CN_code +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pSeed = pointer to the Old CN generator shift register state (Word32) + cod[] = array to hold the generated CN fixed code vector (Word16) + pOverflow = pointer to overflow flag (Flag) + + Outputs: + cod[] = generated CN fixed code vector (Word16) + pSeed = Updated CN generator shift register state (Word16) + pOverflow -> 1 if overflow occured + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + +This function computes the comfort noise fixed codebook excitation. The gains +of the pulses are always +/-1. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void build_CN_code ( + Word32 *seed, // i/o : Old CN generator shift register state + Word16 cod[] // o : Generated CN fixed codebook vector +) +{ + Word16 i, j, k; + + for (i = 0; i < L_SUBFR; i++) + { + cod[i] = 0; + } + +// The reference ETSI code uses a global flag for Overflow. However in the +// actual implementation a pointer to the overflow flag is passed into the +// function so that it can be passed into the basic math functions L_mult() +// and add() + + for (k = 0; k < NB_PULSE; k++) + { + i = pseudonoise (seed, 2); // generate pulse position + i = shr (extract_l (L_mult (i, 10)), 1); + i = add (i, k); + + j = pseudonoise (seed, 1); // generate sign + + if (j > 0) + { + cod[i] = 4096; + } + else + { + cod[i] = -4096; + } + } + + return; +} +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +void build_CN_code( + Word32 *pSeed, /* i/o : Old CN generator shift register state */ + Word16 cod[], /* o : Generated CN fixed codebook vector */ + Flag *pOverflow /* i/o : Overflow flag */ +) +{ + Word16 i, j, k; + Word16 temp; + + for (i = 0; i < L_SUBFR; i++) + { + cod[i] = 0; + } + + for (k = 0; k < NB_PULSE; k++) + { + i = pseudonoise(pSeed, 2); /* generate pulse position */ + + temp = (Word16)(L_mult(i, 10, pOverflow)); + i = temp >> 1; + i = add_16(i, k, pOverflow); + + j = pseudonoise(pSeed, 1); /* generate sign */ + + if (j > 0) + { + cod[i] = 4096; + } + else + { + cod[i] = -4096; + } + } + + return; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: build_CN_param +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pSeed = pointer to the Old CN generator shift register state (Word32) + n_param = Number of parameters to randomize (Word16) + param_size_table = table holding paameter sizes (Word16) + param[] = array to hold CN generated paramters (Word16) + pOverflow = pointer to overflow flag (Flag) + + Outputs: + param[] = CN generated parameters (Word16) + pSeed = Updated CN generator shift register state (Word16) + pOverflow -> 1 if overflow occured + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + +This function randomizes the speech parameters, so that they do not produce +tonal artifacts if used by ECU. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + b_cn_cod.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE +void build_CN_param ( + Word16 *seed, // i/o : Old CN generator shift register state + const Word16 n_param, // i : number of params + const Word16 param_size_table[],// i : size of params + Word16 parm[] // o : CN Generated params + ) +{ + Word16 i; + const Word16 *p; + +// The reference ETSI code uses a global flag for Overflow. However in the +// actual implementation a pointer to the overflow flag is passed into the +// function so that it can be passed into the basic math functions L_add() +// and L_mult() + + *seed = extract_l(L_add(L_shr(L_mult(*seed, 31821), 1), 13849L)); + + p = &window_200_40[*seed & 0x7F]; + for(i=0; i< n_param;i++){ + parm[i] = *p++ & ~(0xFFFF<>= 1; + + *pSeed = (Word16)(L_add(L_temp, 13849L, pOverflow)); + + pTemp = &window_200_40_ptr[*pSeed & 0x7F]; + + for (i = 0; i < n_param; i++) + { + temp = ~(0xFFFF << param_size_table[i]); + parm[i] = *pTemp++ & temp; + } +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/b_cn_cod.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/b_cn_cod.h new file mode 100644 index 00000000..aec7c7ce --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/b_cn_cod.h @@ -0,0 +1,147 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: b_cn_cod.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the comfort noise(CN) generator functions + +------------------------------------------------------------------------------ +*/ + +#ifndef B_CN_COD_H +#define B_CN_COD_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + + ; FUNCTION NAME: pseudonoise + ; + ; PURPOSE: Generate a random integer value to use in comfort noise + ; generation. The algorithm uses polynomial x^31 + x^3 + 1 + ; (length of PN sequence is 2^31 - 1). + ; + ----------------------------------------------------------------------------*/ + + Word16 pseudonoise( + Word32 *pShift_reg, /* i/o : Old CN generator shift register state */ + Word16 no_bits /* i : Number of bits */ + ); + + /*---------------------------------------------------------------------------- + + ; FUNCTION NAME: build_CN_code + ; + ; PURPOSE: Compute the comfort noise fixed codebook excitation. The + ; gains of the pulses are always +/-1. + ; + ----------------------------------------------------------------------------*/ + + void build_CN_code( + Word32 *pSeed, /* i/o : Old CN generator shift register state */ + Word16 cod[], /* o : Generated CN fixed codebook vector */ + Flag *pOverflow /* i/o : Overflow flag */ + ); + + /*---------------------------------------------------------------------------- + + ; FUNCTION NAME: build_CN_param + ; + ; PURPOSE: Randomize the speech parameters. So that they + ; do not produce tonal artifacts if used by ECU. + ; + ----------------------------------------------------------------------------*/ + + void build_CN_param( + Word16 *pSeed, /* i/o : Old CN generator shift register state */ + const Word16 n_param, /* i : number of params */ + const Word16 param_size_table[], /* i : size of params */ + Word16 parm[], /* o : CN Generated params */ + const Word16* window_200_40_ptr, /* i : ptr to read-only table */ + Flag *pOverflow /* i/o : Overflow Flag */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _B_CN_COD_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/bgnscd.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/bgnscd.cpp new file mode 100644 index 00000000..e14dbcd4 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/bgnscd.cpp @@ -0,0 +1,555 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Filename: bgnscd.cpp + Functions: + Bgn_scd_reset + Bgn_scd + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Background noise source characteristic detector (SCD) + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "bgnscd.h" +#include "typedef.h" +#include "basic_op.h" +#include "cnst.h" +#include "gmed_n.h" +#include "sqrt_l.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define TRUE 1 +#define FALSE 0 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Bgn_scd_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = points to memory of type Bgn_scdState. + + Outputs: + The memory of type Bgn_scdState pointed to by state is set to all + zeros. + + Returns: + Returns 0 if memory was successfully initialized, + otherwise returns -1. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Resets state memory. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + bgnscd.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 Bgn_scd_reset (Bgn_scdState *state) +{ + if (state == (Bgn_scdState *) NULL){ + fprintf(stderr, "Bgn_scd_reset: invalid parameter\n"); + return -1; + } + + // Static vectors to zero + Set_zero (state->frameEnergyHist, L_ENERGYHIST); + + // Initialize hangover handling + state->bgHangover = 0; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Bgn_scd_reset(Bgn_scdState *state) +{ + if (state == (Bgn_scdState *) NULL) + { + /* fprintf(stderr, "Bgn_scd_reset: invalid parameter\n"); */ + return(-1); + } + + /* Static vectors to zero */ + oscl_memset(state->frameEnergyHist, 0, L_ENERGYHIST*sizeof(Word16)); + + /* Initialize hangover handling */ + state->bgHangover = 0; + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Bgn_scd +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to state variables of type Bgn_scdState + ltpGainHist[] = LTP gain history (Word16) + speech[] = synthesis speech frame (Word16) + voicedHangover = pointer to # of frames after last voiced frame (Word16) + pOverflow = pointer to overflow indicator (Flag) + + Outputs: + st = function updates the state variables of type Bgn_scdState + pointed to by st. + voicedHangover = function updates the # of frames after last voiced + frame pointed to by voicedHangover. + pOverflow = 1 if the basic math function L_add() results in saturation. + else pOverflow is zero. + + Returns: + inbgNoise = flag if background noise is present (Word16) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Characterize synthesis speech and detect background noise. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + bgnscd.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 Bgn_scd (Bgn_scdState *st, // i : State variables for bgn SCD + Word16 ltpGainHist[], // i : LTP gain history + Word16 speech[], // o : synthesis speech frame + Word16 *voicedHangover // o : # of frames after last + voiced frame + ) +{ + Word16 i; + Word16 prevVoiced, inbgNoise; + Word16 temp; + Word16 ltpLimit, frameEnergyMin; + Word16 currEnergy, noiseFloor, maxEnergy, maxEnergyLastPart; + Word32 s; + + // Update the inBackgroundNoise flag (valid for use in next frame if BFI) + // it now works as a energy detector floating on top + // not as good as a VAD. + + currEnergy = 0; + s = (Word32) 0; + + for (i = 0; i < L_FRAME; i++) + { + s = L_mac (s, speech[i], speech[i]); + } + + s = L_shl(s, 2); + + currEnergy = extract_h (s); + + frameEnergyMin = 32767; + + for (i = 0; i < L_ENERGYHIST; i++) + { + if (sub(st->frameEnergyHist[i], frameEnergyMin) < 0) + frameEnergyMin = st->frameEnergyHist[i]; + } + + noiseFloor = shl (frameEnergyMin, 4); // Frame Energy Margin of 16 + + maxEnergy = st->frameEnergyHist[0]; + for (i = 1; i < L_ENERGYHIST-4; i++) + { + if ( sub (maxEnergy, st->frameEnergyHist[i]) < 0) + { + maxEnergy = st->frameEnergyHist[i]; + } + } + + maxEnergyLastPart = st->frameEnergyHist[2*L_ENERGYHIST/3]; + for (i = 2*L_ENERGYHIST/3+1; i < L_ENERGYHIST; i++) + { + if ( sub (maxEnergyLastPart, st->frameEnergyHist[i] ) < 0) + { + maxEnergyLastPart = st->frameEnergyHist[i]; + } + } + + inbgNoise = 0; // false + + // Do not consider silence as noise + // Do not consider continuous high volume as noise + // Or if the current noise level is very low + // Mark as noise if under current noise limit + // OR if the maximum energy is below the upper limit + + if ( (sub(maxEnergy, LOWERNOISELIMIT) > 0) && + (sub(currEnergy, FRAMEENERGYLIMIT) < 0) && + (sub(currEnergy, LOWERNOISELIMIT) > 0) && + ( (sub(currEnergy, noiseFloor) < 0) || + (sub(maxEnergyLastPart, UPPERNOISELIMIT) < 0))) + { + if (sub(add(st->bgHangover, 1), 30) > 0) + { + st->bgHangover = 30; + } else + { + st->bgHangover = add(st->bgHangover, 1); + } + } + else + { + st->bgHangover = 0; + } + + // make final decision about frame state , act somewhat cautiosly + if (sub(st->bgHangover,1) > 0) + inbgNoise = 1; // true + + for (i = 0; i < L_ENERGYHIST-1; i++) + { + st->frameEnergyHist[i] = st->frameEnergyHist[i+1]; + } + st->frameEnergyHist[L_ENERGYHIST-1] = currEnergy; + + // prepare for voicing decision; tighten the threshold after some + time in noise + ltpLimit = 13926; // 0.85 Q14 + if (sub(st->bgHangover, 8) > 0) + { + ltpLimit = 15565; // 0.95 Q14 + } + if (sub(st->bgHangover, 15) > 0) + { + ltpLimit = 16383; // 1.00 Q14 + } + + // weak sort of voicing indication. + prevVoiced = 0; // false + + if (sub(gmed_n(<pGainHist[4], 5), ltpLimit) > 0) + { + prevVoiced = 1; // true + } + if (sub(st->bgHangover, 20) > 0) { + if (sub(gmed_n(ltpGainHist, 9), ltpLimit) > 0) + { + prevVoiced = 1; // true + } + else + { + prevVoiced = 0; // false + } + } + + if (prevVoiced) + { + *voicedHangover = 0; + } + else + { + temp = add(*voicedHangover, 1); + if (sub(temp, 10) > 0) + { + *voicedHangover = 10; + } + else + { + *voicedHangover = temp; + } + } + + return inbgNoise; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Bgn_scd(Bgn_scdState *st, /* i : State variables for bgn SCD */ + Word16 ltpGainHist[], /* i : LTP gain history */ + Word16 speech[], /* o : synthesis speech frame */ + Word16 *voicedHangover,/* o : # of frames after last + voiced frame */ + Flag *pOverflow + ) +{ + Word16 i; + Word16 prevVoiced, inbgNoise; + Word16 temp; + Word16 ltpLimit, frameEnergyMin; + Word16 currEnergy, noiseFloor, maxEnergy, maxEnergyLastPart; + Word32 s, L_temp; + + + /* Update the inBackgroundNoise flag (valid for use in next frame if BFI) */ + /* it now works as a energy detector floating on top */ + /* not as good as a VAD. */ + + s = (Word32) 0; + + for (i = L_FRAME - 1; i >= 0; i--) + { + L_temp = ((Word32) speech[i]) * speech[i]; + if (L_temp != (Word32) 0x40000000L) + { + L_temp = L_temp << 1; + } + else + { + L_temp = MAX_32; + } + s = L_add(s, L_temp, pOverflow); + } + + /* s is a sum of squares, so don't need to check for neg overflow */ + if (s > (Word32)0x1fffffffL) + { + currEnergy = MAX_16; + } + else + { + currEnergy = (Word16)(s >> 14); + } + + frameEnergyMin = 32767; + for (i = L_ENERGYHIST - 1; i >= 0; i--) + { + if (st->frameEnergyHist[i] < frameEnergyMin) + { + frameEnergyMin = st->frameEnergyHist[i]; + } + } + + /* Frame Energy Margin of 16 */ + L_temp = (Word32)frameEnergyMin << 4; + if (L_temp != (Word32)((Word16) L_temp)) + { + if (L_temp > 0) + { + noiseFloor = MAX_16; + } + else + { + noiseFloor = MIN_16; + } + } + else + { + noiseFloor = (Word16)(L_temp); + } + + maxEnergy = st->frameEnergyHist[0]; + for (i = L_ENERGYHIST - 5; i >= 1; i--) + { + if (maxEnergy < st->frameEnergyHist[i]) + { + maxEnergy = st->frameEnergyHist[i]; + } + } + + maxEnergyLastPart = st->frameEnergyHist[2*L_ENERGYHIST/3]; + for (i = 2 * L_ENERGYHIST / 3 + 1; i < L_ENERGYHIST; i++) + { + if (maxEnergyLastPart < st->frameEnergyHist[i]) + { + maxEnergyLastPart = st->frameEnergyHist[i]; + } + } + + /* Do not consider silence as noise */ + /* Do not consider continuous high volume as noise */ + /* Or if the current noise level is very low */ + /* Mark as noise if under current noise limit */ + /* OR if the maximum energy is below the upper limit */ + + if ((maxEnergy > LOWERNOISELIMIT) && + (currEnergy < FRAMEENERGYLIMIT) && + (currEnergy > LOWERNOISELIMIT) && + ((currEnergy < noiseFloor) || + (maxEnergyLastPart < UPPERNOISELIMIT))) + { + if ((st->bgHangover + 1) > 30) + { + st->bgHangover = 30; + } + else + { + st->bgHangover += 1; + } + } + else + { + st->bgHangover = 0; + } + + /* make final decision about frame state , act somewhat cautiosly */ + + if (st->bgHangover > 1) + { + inbgNoise = TRUE; + } + else + { + inbgNoise = FALSE; + } + + for (i = 0; i < L_ENERGYHIST - 1; i++) + { + st->frameEnergyHist[i] = st->frameEnergyHist[i+1]; + } + st->frameEnergyHist[L_ENERGYHIST-1] = currEnergy; + + /* prepare for voicing decision; tighten the threshold after some + time in noise */ + + if (st->bgHangover > 15) + { + ltpLimit = 16383; /* 1.00 Q14 */ + } + else if (st->bgHangover > 8) + { + ltpLimit = 15565; /* 0.95 Q14 */ + } + else + { + ltpLimit = 13926; /* 0.85 Q14 */ + } + + /* weak sort of voicing indication. */ + prevVoiced = FALSE; + + if (gmed_n(<pGainHist[4], 5) > ltpLimit) + { + prevVoiced = TRUE; + } + + if (st->bgHangover > 20) + { + if (gmed_n(ltpGainHist, 9) > ltpLimit) + { + prevVoiced = TRUE; + } + else + { + prevVoiced = FALSE; + } + } + + + if (prevVoiced) + { + *voicedHangover = 0; + } + else + { + temp = *voicedHangover + 1; + + if (temp > 10) + { + *voicedHangover = 10; + } + else + { + *voicedHangover = temp; + } + } + + return(inbgNoise); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/bgnscd.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/bgnscd.h new file mode 100644 index 00000000..f98eab9a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/bgnscd.h @@ -0,0 +1,150 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: bgnscd.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : bgnscd.h + Purpose : Background noise source charateristic detector (SCD) + +------------------------------------------------------------------------------ +*/ + +#ifndef _BGNSCD_H_ +#define _BGNSCD_H_ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ +#define L_ENERGYHIST 60 +#define INV_L_FRAME 102 + + + /* 2*(160*x)^2 / 65536 where x is FLP values 150,5 and 50 */ +#define FRAMEENERGYLIMIT 17578 /* 150 */ +#define LOWERNOISELIMIT 20 /* 5 */ +#define UPPERNOISELIMIT 1953 /* 50 */ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + /* history vector of past synthesis speech energy */ + Word16 frameEnergyHist[L_ENERGYHIST]; + + /* state flags */ + Word16 bgHangover; /* counter; number of frames after last speech frame */ + + } Bgn_scdState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + /* + * Function : Bgn_scd_init + * Purpose : Allocates initializes state memory + * Description : Stores pointer to filter status struct in *st. This + * pointer has to be passed to Bgn_scd in each call. + * Returns : 0 on success + */ + Word16 Bgn_scd_init(Bgn_scdState **st); + + /* + * Function : Bgn_scd_reset + * Purpose : Resets state memory + * Returns : 0 on success + */ + Word16 Bgn_scd_reset(Bgn_scdState *st); + + /* + * Function : Bgn_scd_exit + * Purpose : The memory used for state memory is freed + * Description : Stores NULL in *s + * Returns : void + */ + void Bgn_scd_exit(Bgn_scdState **st); + + /* + * Function : Bgn_scd + * Purpose : Charaterice synthesis speech and detect background noise + * Returns : background noise decision; 0 = bgn, 1 = no bgn + */ + Word16 Bgn_scd(Bgn_scdState *st, /* i : State variables for bgn SCD */ + Word16 ltpGainHist[], /* i : LTP gain history */ + Word16 speech[], /* o : synthesis speech frame */ + Word16 *voicedHangover,/* o : # of frames after last voiced frame */ + Flag *pOverflow + ); + + +#ifdef __cplusplus +} +#endif + +#endif /* _BGNSCD_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/c_g_aver.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/c_g_aver.cpp new file mode 100644 index 00000000..7a867608 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/c_g_aver.cpp @@ -0,0 +1,584 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c_g_aver.cpp + Functions: + Cb_gain_average_reset + Cb_gain_average + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains functions that reset and perform + codebook gain calculations. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "c_g_aver.h" +#include "typedef.h" +#include "mode.h" +#include "cnst.h" + +#include "basic_op.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Cb_gain_average_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a structure of type Cb_gain_averageState + + Outputs: + Structure pointed to by state is initialized to zeros + + Returns: + Returns 0 if memory was successfully initialized, + otherwise returns -1. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Resets state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + c_g_aver.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 Cb_gain_average_reset (Cb_gain_averageState *state) +{ + if (state == (Cb_gain_averageState *) NULL){ + fprintf(stderr, "Cb_gain_average_reset: invalid parameter\n"); + return -1; + } + + // Static vectors to zero + Set_zero (state->cbGainHistory, L_CBGAINHIST); + + // Initialize hangover handling + state->hangVar = 0; + state->hangCount= 0; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Cb_gain_average_reset(Cb_gain_averageState *state) +{ + if (state == (Cb_gain_averageState *) NULL) + { + /* fprint(stderr, "Cb_gain_average_reset: invalid parameter\n"); */ + return(-1); + } + + /* Static vectors to zero */ + oscl_memset(state->cbGainHistory, 0, L_CBGAINHIST*sizeof(Word16)); + + /* Initialize hangover handling */ + state->hangVar = 0; + state->hangCount = 0; + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Cb_gain_average +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to structure of type Cb_gain_averageState + mode = AMR mode (enum Mode) + gain_code = CB gain (Word16) + lsp = the LSP for the current frame (Word16) + lspAver = the average of LSP for 8 frames (Word16) + bfi = bad frame indication flag (Word16) + prev_bf = previous bad frame indication flag (Word16) + pdfi = potential degraded bad frame ind flag (Word16) + prev_pdf = prev pot. degraded bad frame ind flag (Word16) + inBackgroundNoise = background noise decision (Word16) + voicedHangover = # of frames after last voiced frame (Word16) + pOverflow = address of overflow (Flag) + + Returns: + cbGainMix = codebook gain (Word16) + + Outputs: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + The mix cb gains for MR475, MR515, MR59, MR67, MR102; gain_code other modes + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + c_g_aver.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 Cb_gain_average ( + Cb_gain_averageState *st, // i/o : State variables for CB gain avergeing + enum Mode mode, // i : AMR mode + Word16 gain_code, // i : CB gain Q1 + Word16 lsp[], // i : The LSP for the current frame Q15 + Word16 lspAver[], // i : The average of LSP for 8 frames Q15 + Word16 bfi, // i : bad frame indication flag + Word16 prev_bf, // i : previous bad frame indication flag + Word16 pdfi, // i : potential degraded bad frame ind flag + Word16 prev_pdf, // i : prev pot. degraded bad frame ind flag + Word16 inBackgroundNoise, // i : background noise decision + Word16 voicedHangover // i : # of frames after last voiced frame + ) +{ + //---------------------------------------------------------* + * Compute mixed cb gain, used to make cb gain more * + * smooth in background noise for modes 5.15, 5.9 and 6.7 * + * states that needs to be updated by all * + *--------------------------------------------------------- + Word16 i; + Word16 cbGainMix, diff, tmp_diff, bgMix, cbGainMean; + Word32 L_sum; + Word16 tmp[M], tmp1, tmp2, shift1, shift2, shift; + + // set correct cbGainMix for MR74, MR795, MR122 + cbGainMix = gain_code; + + *-------------------------------------------------------* + * Store list of CB gain needed in the CB gain * + * averaging * + *-------------------------------------------------------* + for (i = 0; i < (L_CBGAINHIST-1); i++) + { + st->cbGainHistory[i] = st->cbGainHistory[i+1]; + } + st->cbGainHistory[L_CBGAINHIST-1] = gain_code; + + // compute lsp difference + for (i = 0; i < M; i++) { + tmp1 = abs_s(sub(lspAver[i], lsp[i])); // Q15 + shift1 = sub(norm_s(tmp1), 1); // Qn + tmp1 = shl(tmp1, shift1); // Q15+Qn + shift2 = norm_s(lspAver[i]); // Qm + tmp2 = shl(lspAver[i], shift2); // Q15+Qm + tmp[i] = div_s(tmp1, tmp2); // Q15+(Q15+Qn)-(Q15+Qm) + shift = sub(add(2, shift1), shift2); + if (shift >= 0) + { + tmp[i] = shr(tmp[i], shift); // Q15+Qn-Qm-Qx=Q13 + } + else + { + tmp[i] = shl(tmp[i], negate(shift)); // Q15+Qn-Qm-Qx=Q13 + } + } + + diff = tmp[0]; + for (i = 1; i < M; i++) { + diff = add(diff, tmp[i]); // Q13 + } + + // Compute hangover + if (sub(diff, 5325) > 0) // 0.65 in Q11 + { + st->hangVar = add(st->hangVar, 1); + } + else + { + st->hangVar = 0; + } + + if (sub(st->hangVar, 10) > 0) + { + st->hangCount = 0; // Speech period, reset hangover variable + } + + // Compute mix constant (bgMix) + bgMix = 8192; // 1 in Q13 + if ((sub(mode, MR67) <= 0) || (sub(mode, MR102) == 0)) + // MR475, MR515, MR59, MR67, MR102 + { + // if errors and presumed noise make smoothing probability stronger + if (((((pdfi != 0) && (prev_pdf != 0)) || (bfi != 0) || (prev_bf != 0)) && + (sub(voicedHangover, 1) > 0) && (inBackgroundNoise != 0) && + ((sub(mode, MR475) == 0) || + (sub(mode, MR515) == 0) || + (sub(mode, MR59) == 0)) )) + { + // bgMix = min(0.25, max(0.0, diff-0.55)) / 0.25; + tmp_diff = sub(diff, 4506); // 0.55 in Q13 + + // max(0.0, diff-0.55) + if (tmp_diff > 0) + { + tmp1 = tmp_diff; + } + else + { + tmp1 = 0; + } + + // min(0.25, tmp1) + if (sub(2048, tmp1) < 0) + { + bgMix = 8192; + } + else + { + bgMix = shl(tmp1, 2); + } + } + else + { + // bgMix = min(0.25, max(0.0, diff-0.40)) / 0.25; + tmp_diff = sub(diff, 3277); // 0.4 in Q13 + + // max(0.0, diff-0.40) + if (tmp_diff > 0) + { + tmp1 = tmp_diff; + } + else + { + tmp1 = 0; + } + + // min(0.25, tmp1) + if (sub(2048, tmp1) < 0) + { + bgMix = 8192; + } + else + { + bgMix = shl(tmp1, 2); + } + } + + if ((sub(st->hangCount, 40) < 0) || (sub(diff, 5325) > 0)) // 0.65 in Q13 + { + bgMix = 8192; // disable mix if too short time since + } + + // Smoothen the cb gain trajectory + // smoothing depends on mix constant bgMix + L_sum = L_mult(6554, st->cbGainHistory[2]); // 0.2 in Q15; L_sum in Q17 + for (i = 3; i < L_CBGAINHIST; i++) + { + L_sum = L_mac(L_sum, 6554, st->cbGainHistory[i]); + } + cbGainMean = pv_round(L_sum); // Q1 + + // more smoothing in error and bg noise (NB no DFI used here) + if (((bfi != 0) || (prev_bf != 0)) && (inBackgroundNoise != 0) && + ((sub(mode, MR475) == 0) || + (sub(mode, MR515) == 0) || + (sub(mode, MR59) == 0)) ) + { + L_sum = L_mult(4681, st->cbGainHistory[0]); // 0.143 in Q15; L_sum in Q17 + for (i = 1; i < L_CBGAINHIST; i++) + { + L_sum = L_mac(L_sum, 4681, st->cbGainHistory[i]); + } + cbGainMean = pv_round(L_sum); // Q1 + } + + // cbGainMix = bgMix*cbGainMix + (1-bgMix)*cbGainMean; + L_sum = L_mult(bgMix, cbGainMix); // L_sum in Q15 + L_sum = L_mac(L_sum, 8192, cbGainMean); + L_sum = L_msu(L_sum, bgMix, cbGainMean); + cbGainMix = pv_round(L_shl(L_sum, 2)); // Q1 + } + + st->hangCount = add(st->hangCount, 1); + return cbGainMix; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Cb_gain_average( + Cb_gain_averageState *st, /* i/o : State variables for CB gain averaging */ + enum Mode mode, /* i : AMR mode */ + Word16 gain_code, /* i : CB gain Q1 */ + Word16 lsp[], /* i : The LSP for the current frame Q15 */ + Word16 lspAver[], /* i : The average of LSP for 8 frames Q15 */ + Word16 bfi, /* i : bad frame indication flag */ + Word16 prev_bf, /* i : previous bad frame indication flag */ + Word16 pdfi, /* i : potential degraded bad frame ind flag */ + Word16 prev_pdf, /* i : prev pot. degraded bad frame ind flag */ + Word16 inBackgroundNoise, /* i : background noise decision */ + Word16 voicedHangover, /* i : # of frames after last voiced frame */ + Flag *pOverflow +) +{ + Word16 i; + Word16 cbGainMix; + Word16 diff; + Word16 tmp_diff; + Word16 bgMix; + Word16 cbGainMean; + Word32 L_sum; + Word16 tmp[M]; + Word16 tmp1; + Word16 tmp2; + Word16 shift1; + Word16 shift2; + Word16 shift; + + /*---------------------------------------------------------* + * Compute mixed cb gain, used to make cb gain more * + * smooth in background noise for modes 5.15, 5.9 and 6.7 * + * states that needs to be updated by all * + *---------------------------------------------------------*/ + + /* set correct cbGainMix for MR74, MR795, MR122 */ + cbGainMix = gain_code; + + /*-------------------------------------------------------* + * Store list of CB gain needed in the CB gain * + * averaging * + *-------------------------------------------------------*/ + for (i = 0; i < (L_CBGAINHIST - 1); i++) + { + st->cbGainHistory[i] = st->cbGainHistory[i+1]; + } + st->cbGainHistory[L_CBGAINHIST-1] = gain_code; + + diff = 0; + + /* compute lsp difference */ + for (i = 0; i < M; i++) + { + tmp1 = abs_s(sub(*(lspAver + i), *(lsp + i), pOverflow)); + /* Q15 */ + shift1 = norm_s(tmp1) - 1 ; /* Qn */ + tmp1 = shl(tmp1, shift1, pOverflow); /* Q15+Qn */ + shift2 = norm_s(*(lspAver + i)); /* Qm */ + tmp2 = shl(*(lspAver + i), shift2, pOverflow); /* Q15+Qm */ + tmp[i] = div_s(tmp1, tmp2); /* Q15+(Q15+Qn)-(Q15+Qm) */ + + shift = 2 + shift1 - shift2; + + if (shift >= 0) + { + *(tmp + i) = shr(*(tmp + i), shift, pOverflow); + /* Q15+Qn-Qm-Qx=Q13 */ + } + else + { + *(tmp + i) = shl(*(tmp + i), negate(shift), pOverflow); + /* Q15+Qn-Qm-Qx=Q13 */ + } + + diff = add_16(diff, *(tmp + i), pOverflow); /* Q13 */ + } + + /* Compute hangover */ + + if (diff > 5325) /* 0.65 in Q11 */ + { + st->hangVar += 1; + } + else + { + st->hangVar = 0; + } + + + if (st->hangVar > 10) + { + /* Speech period, reset hangover variable */ + st->hangCount = 0; + } + + /* Compute mix constant (bgMix) */ + bgMix = 8192; /* 1 in Q13 */ + + if ((mode <= MR67) || (mode == MR102)) + /* MR475, MR515, MR59, MR67, MR102 */ + { + /* if errors and presumed noise make smoothing probability stronger */ + + if (((((pdfi != 0) && (prev_pdf != 0)) || (bfi != 0) || + (prev_bf != 0)) + && (voicedHangover > 1) + && (inBackgroundNoise != 0) + && ((mode == MR475) || (mode == MR515) || + (mode == MR59)))) + { + /* bgMix = min(0.25, max(0.0, diff-0.55)) / 0.25; */ + tmp_diff = diff - 4506; /* 0.55 in Q13 */ + } + else + { + /* bgMix = min(0.25, max(0.0, diff-0.40)) / 0.25; */ + tmp_diff = diff - 3277; /* 0.4 in Q13 */ + } + + /* max(0.0, diff-0.55) or */ + /* max(0.0, diff-0.40) */ + if (tmp_diff > 0) + { + tmp1 = tmp_diff; + } + else + { + tmp1 = 0; + } + + /* min(0.25, tmp1) */ + if (2048 < tmp1) + { + bgMix = 8192; + } + else + { + bgMix = shl(tmp1, 2, pOverflow); + } + + if ((st->hangCount < 40) || (diff > 5325)) /* 0.65 in Q13 */ + { + /* disable mix if too short time since */ + bgMix = 8192; + } + + /* Smoothen the cb gain trajectory */ + /* smoothing depends on mix constant bgMix */ + L_sum = L_mult(6554, st->cbGainHistory[2], pOverflow); + /* 0.2 in Q15; L_sum in Q17 */ + + for (i = 3; i < L_CBGAINHIST; i++) + { + L_sum = L_mac(L_sum, 6554, st->cbGainHistory[i], pOverflow); + } + cbGainMean = pv_round(L_sum, pOverflow); /* Q1 */ + + /* more smoothing in error and bg noise (NB no DFI used here) */ + + if (((bfi != 0) || (prev_bf != 0)) && (inBackgroundNoise != 0) + && ((mode == MR475) || (mode == MR515) + || (mode == MR59))) + { + /* 0.143 in Q15; L_sum in Q17 */ + L_sum = L_mult(4681, st->cbGainHistory[0], pOverflow); + for (i = 1; i < L_CBGAINHIST; i++) + { + L_sum = + L_mac(L_sum, 4681, st->cbGainHistory[i], pOverflow); + } + cbGainMean = pv_round(L_sum, pOverflow); /* Q1 */ + } + + /* cbGainMix = bgMix*cbGainMix + (1-bgMix)*cbGainMean; */ + /* L_sum in Q15 */ + L_sum = L_mult(bgMix, cbGainMix, pOverflow); + L_sum = L_mac(L_sum, 8192, cbGainMean, pOverflow); + L_sum = L_msu(L_sum, bgMix, cbGainMean, pOverflow); + cbGainMix = pv_round(L_shl(L_sum, 2, pOverflow), pOverflow); /* Q1 */ + } + + st->hangCount += 1; + + return (cbGainMix); +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/c_g_aver.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/c_g_aver.h new file mode 100644 index 00000000..ac56383e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/c_g_aver.h @@ -0,0 +1,154 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c_g_aver.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : c_g_aver.h + Purpose : Background noise source charateristic detector (SCD) + +------------------------------------------------------------------------------ +*/ + +#ifndef _C_G_AVER_H_ +#define _C_G_AVER_H_ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "cnst.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ +#define L_CBGAINHIST 7 + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + /* history vector of past synthesis speech energy */ + Word16 cbGainHistory[L_CBGAINHIST]; + + /* state flags */ + Word16 hangVar; /* counter; */ + Word16 hangCount; /* counter; */ + + } Cb_gain_averageState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + /* + * Function : Cb_gain_average_init + * Purpose : Allocates initializes state memory + * Description : Stores pointer to filter status struct in *st. This + * pointer has to be passed to Cb_gain_average in each call. + * Returns : 0 on success + */ + Word16 Cb_gain_average_init(Cb_gain_averageState **st); + + /* + * Function : Cb_gain_average_reset + * Purpose : Resets state memory + * Returns : 0 on success + */ + Word16 Cb_gain_average_reset(Cb_gain_averageState *st); + + /* + * Function : Cb_gain_average_exit + * Purpose : The memory used for state memory is freed + * Description : Stores NULL in *s + * Returns : void + */ + void Cb_gain_average_exit(Cb_gain_averageState **st); + + /* + * Function : Cb_gain_average + * Purpose : Charaterice synthesis speech and detect background noise + * Returns : background noise decision; 0 = bgn, 1 = no bgn + */ + Word16 Cb_gain_average( + Cb_gain_averageState *st, /* i/o : State variables for CB gain avergeing */ + enum Mode mode, /* i : AMR mode */ + Word16 gain_code, /* i : CB gain Q1 */ + Word16 lsp[], /* i : The LSP for the current frame Q15 */ + Word16 lspAver[], /* i : The average of LSP for 8 frames Q15 */ + Word16 bfi, /* i : bad frame indication flag */ + Word16 prev_bf, /* i : previous bad frame indication flag */ + Word16 pdfi, /* i : potential degraded bad frame ind flag */ + Word16 prev_pdf, /* i : prev pot. degraded bad frame ind flag */ + Word16 inBackgroundNoise, /* i : background noise decision */ + Word16 voicedHangover, /* i : # of frames after last voiced frame */ + Flag *pOverflow + ); + + +#ifdef __cplusplus +} +#endif + +#endif /* _C_G_AVER_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d1035pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d1035pf.cpp new file mode 100644 index 00000000..d56b9223 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d1035pf.cpp @@ -0,0 +1,231 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d1035pf.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "d1035pf.h" +#include "typedef.h" +#include "basic_op.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define NB_PULSE 10 /* number of pulses */ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: dec_10i40_35bits +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + index = buffer containing index of 10 pulses; each element is + represented by sign+position + cod = buffer of algebraic (fixed) codebook excitation + + Outputs: + cod buffer contains the new algebraic codebook excitation + + Returns: + None + + Global Variables Used: + dgray = gray decoding table + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function builds the innovative codevector from the received index of + algebraic codebook. See c1035pf.c for more details about the algebraic + codebook structure. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + d1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void dec_10i40_35bits ( + Word16 index[], // (i) : index of 10 pulses (sign+position) + Word16 cod[] // (o) : algebraic (fixed) codebook excitation +) +{ + Word16 i, j, pos1, pos2, sign, tmp; + + for (i = 0; i < L_CODE; i++) + { + cod[i] = 0; + } + + // decode the positions and signs of pulses and build the codeword + + for (j = 0; j < NB_TRACK; j++) + { + // compute index i + + tmp = index[j]; + i = tmp & 7; + i = dgray[i]; + + i = extract_l (L_shr (L_mult (i, 5), 1)); + pos1 = add (i, j); // position of pulse "j" + + i = shr (tmp, 3) & 1; + if (i == 0) + { + sign = 4096; // +1.0 + } + else + { + sign = -4096; // -1.0 + } + + cod[pos1] = sign; + + // compute index i + + i = index[add (j, 5)] & 7; + i = dgray[i]; + i = extract_l (L_shr (L_mult (i, 5), 1)); + + pos2 = add (i, j); // position of pulse "j+5" + + if (sub (pos2, pos1) < 0) + { + sign = negate (sign); + } + cod[pos2] = add (cod[pos2], sign); + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void dec_10i40_35bits( + Word16 index[], /* (i) : index of 10 pulses (sign+position) */ + Word16 cod[], /* (o) : algebraic (fixed) codebook excitation */ + const Word16* dgray_ptr /* i : ptr to read-only tbl */ +) +{ + register Word16 i, j, pos1, pos2; + Word16 sign, tmp; + + for (i = 0; i < L_CODE; i++) + { + *(cod + i) = 0; + } + + /* decode the positions and signs of pulses and build the codeword */ + + for (j = 0; j < NB_TRACK; j++) + { + /* compute index i */ + + tmp = *(index + j); + i = tmp & 7; + i = *(dgray_ptr + i); + + i = (Word16)(i * 5); + pos1 = i + j; /* position of pulse "j" */ + + i = (tmp >> 3) & 1; + + if (i == 0) + { + sign = 4096; /* +1.0 */ + } + else + { + sign = -4096; /* -1.0 */ + } + + *(cod + pos1) = sign; + + /* compute index i */ + + i = *(index + j + 5) & 7; + i = *(dgray_ptr + i); + i = (Word16)(i * 5); + + pos2 = i + j; /* position of pulse "j+5" */ + + + if (pos2 < pos1) + { + sign = negate(sign); + } + *(cod + pos2) += sign; + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d1035pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d1035pf.h new file mode 100644 index 00000000..ac15905b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d1035pf.h @@ -0,0 +1,106 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d1035pf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains the prototype declaration for dec_10i40_35bits function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef D1035PF_H +#define D1035PF_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void dec_10i40_35bits( + Word16 index[], /* (i) : index of 10 pulses (sign+position) */ + Word16 cod[], /* (o) : algebraic (fixed) codebook excitation */ + const Word16* dgray_ptr /* i : ptr to read-only tbl */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _D1035PF_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d2_11pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d2_11pf.cpp new file mode 100644 index 00000000..8a700321 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d2_11pf.cpp @@ -0,0 +1,192 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d2_11pf.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "d2_11pf.h" +#include "typedef.h" +#include "cnst.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define NB_PULSE 2 + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: decode_2i40_11bits +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + sign -- Word16 -- signs of 2 pulses. + index -- Word16 -- Positions of the 2 pulses. + + Outputs: + cod[] -- array of type Word16 -- algebraic (fixed) codebook excitation + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + d2_11pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void decode_2i40_11bits( + Word16 sign, /* i : signs of 2 pulses. */ + Word16 index, /* i : Positions of the 2 pulses. */ + Word16 cod[] /* o : algebraic (fixed) codebook excitation */ +) + +{ + Word16 i; + Word16 j; + + Word16 pos[NB_PULSE]; + + /* Decode the positions */ + + j = index & 0x1; + + index >>= 1; + + i = index & 0x7; + + pos[0] = i * 5 + j * 2 + 1; + + + + + index >>= 3; + + j = index & 0x3; + + index >>= 2; + + i = index & 0x7; + + if (j == 3) + { + pos[1] = i * 5 + 4; + } + else + { + pos[1] = i * 5 + j; + } + + + + + /* decode the signs and build the codeword */ + for (i = 0; i < L_SUBFR; i++) + { + cod[i] = 0; + } + + for (j = 0; j < NB_PULSE; j++) + { + i = sign & 1; + + /* This line is equivalent to... + * + * + * if (i == 1) + * { + * cod[pos[j]] = 8191; + * } + * if (i == 0) + * { + * cod[pos[j]] = -8192; + * } + */ + + cod[pos[j]] = i * 16383 - 8192; + + sign >>= 1; + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d2_11pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d2_11pf.h new file mode 100644 index 00000000..aaf2e084 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d2_11pf.h @@ -0,0 +1,93 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : d2_11pf.h +* Purpose : Algebraic codebook decoder +* +******************************************************************************** +*/ +#ifndef d2_11pf_h +#define d2_11pf_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ******************************************************************************** + * LOCAL VARIABLES AND TABLES + ******************************************************************************** + */ + + /* + ******************************************************************************** + * DEFINITION OF DATA TYPES + ******************************************************************************** + */ + + /* + ******************************************************************************** + * DECLARATION OF PROTOTYPES + ******************************************************************************** + */ + /************************************************************************* + * + * FUNCTION: decode_2i40_11bits (decod_ACELP()) + * + * PURPOSE: Algebraic codebook decoder for 2 pulses coded with 11 bits + * + *************************************************************************/ + + void decode_2i40_11bits( + Word16 sign, /* i : signs of 2 pulses. */ + Word16 index, /* i : Positions of the 2 pulses. */ + Word16 cod[] /* o : algebraic (fixed) codebook excitation */ + ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d2_9pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d2_9pf.cpp new file mode 100644 index 00000000..fca7a8a6 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d2_9pf.cpp @@ -0,0 +1,212 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d2_9pf.cpp + Functions: decode_2i40_9bits + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + + FUNCTION: decode_2i40_9bits (decod_ACELP()) + + PURPOSE: Algebraic codebook decoder. For details about the encoding see + c2_9pf.c +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "d2_9pf.h" +#include "typedef.h" +#include "basic_op.h" +#include "cnst.h" + + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ +#define NB_PULSE 2 + + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: decode_2i40_11bits +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + sign -- Word16 -- signs of 2 pulses. + index -- Word16 -- Positions of the 2 pulses. + + Outputs: + cod[] -- array of type Word16 -- algebraic (fixed) codebook excitation + pOverflow = pointer to overflow flag + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + d2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void decode_2i40_9bits( + Word16 subNr, /* i : subframe number */ + Word16 sign, /* i : signs of 2 pulses. */ + Word16 index, /* i : Positions of the 2 pulses. */ + const Word16* startPos_ptr, /* i: ptr to read only table */ + Word16 cod[], /* o : algebraic (fixed) codebook excitation */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 j; + Word16 k; + + Word16 pos[NB_PULSE]; + + /* Decode the positions */ + /* table bit is the MSB */ + + j = (Word16)(index & 64); + + j >>= 3; + + i = index & 7; + + k = + shl( + subNr, + 1, + pOverflow); + + k += j; + + /* pos0 =i*5+startPos_ptr[j*8+subNr*2] */ + pos[0] = i * 5 + startPos_ptr[k++]; + + + index >>= 3; + + i = index & 7; + + /* pos1 =i*5+startPos_ptr[j*8+subNr*2 + 1] */ + pos[1] = i * 5 + startPos_ptr[k]; + + + /* decode the signs and build the codeword */ + + for (i = L_SUBFR - 1; i >= 0; i--) + { + cod[i] = 0; + } + + for (j = 0; j < NB_PULSE; j++) + { + i = sign & 0x1; + + /* This line is equivalent to... + * + * + * if (i == 1) + * { + * cod[pos[j]] = 8191; + * } + * if (i == 0) + * { + * cod[pos[j]] = -8192; + * } + */ + + cod[pos[j]] = i * 16383 - 8192; + + sign >>= 1; + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d2_9pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d2_9pf.h new file mode 100644 index 00000000..ef7c16b1 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d2_9pf.h @@ -0,0 +1,111 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d2_9pf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the d2_9pf.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef d2_9pf_h +#define d2_9pf_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void decode_2i40_9bits( + Word16 subNr, /* i : subframe number */ + Word16 sign, /* i : signs of 2 pulses. */ + Word16 index, /* i : Positions of the 2 pulses. */ + const Word16* startPos_ptr, /* i: ptr to read only table */ + Word16 cod[], /* o : algebraic (fixed) codebook excitation */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _d2_9PF_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d3_14pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d3_14pf.cpp new file mode 100644 index 00000000..193b7de4 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d3_14pf.cpp @@ -0,0 +1,201 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d3_14pf.cpp + Functions: decode_3i40_14bits + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + + FUNCTION: decode_3i40_14bits (decod_ACELP()) + + PURPOSE: Algebraic codebook decoder. For details about the encoding see + c3_14pf.c +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" +#include "d3_14pf.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define NB_PULSE 3 /* number of pulses */ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: decode_3i40_14bits +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + sign -- Word16 -- signs of 3 pulses. + index -- Word16 -- Positions of the 3 pulses. + + Outputs: + cod[] -- array of type Word16 -- algebraic (fixed) codebook excitation + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + d2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void decode_3i40_14bits( + Word16 sign, /* i : signs of 3 pulses. */ + Word16 index, /* i : Positions of the 3 pulses. */ + Word16 cod[] /* o : algebraic (fixed) codebook excitation */ +) +{ + Word16 i; + Word16 j; + + Word16 pos[NB_PULSE]; + + /* Decode the positions */ + + i = index & 0x7; + + pos[0] = i * 5; + + + + + + index >>= 3; + + j = index & 0x1; + + index >>= 1; + + i = index & 0x7; + + pos[1] = i * 5 + j * 2 + 1; + + + + + + index >>= 3; + + j = index & 0x1; + + index >>= 1; + + i = index & 0x7; + + pos[2] = i * 5 + j * 2 + 2; + + + /* decode the signs and build the codeword */ + + for (i = 0; i < L_SUBFR; i++) + { + cod[i] = 0; + } + + for (j = 0; j < NB_PULSE; j++) + { + i = sign & 1; + + /* This line is equivalent to... + * + * + * if (i == 1) + * { + * cod[pos[j]] = 8191; + * } + * if (i == 0) + * { + * cod[pos[j]] = -8192; + * } + */ + + cod[pos[j]] = i * 16383 - 8192; + + sign >>= 1; + + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d3_14pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d3_14pf.h new file mode 100644 index 00000000..e8a0de14 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d3_14pf.h @@ -0,0 +1,107 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d3_14pf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the d3_14pf.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef d3_14pf_h +#define d3_14pf_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void decode_3i40_14bits( + Word16 sign, /* i : signs of 3 pulses. */ + Word16 index, /* i : Positions of the 3 pulses. */ + Word16 cod[] /* o : algebraic (fixed) codebook excitation */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _d3_14PF_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d4_17pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d4_17pf.cpp new file mode 100644 index 00000000..62838bd9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d4_17pf.cpp @@ -0,0 +1,237 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d4_17pf.cpp + Functions: decode_4i40_17bits + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + + FUNCTION: decode_4i40_17bits (decod_ACELP()) + + PURPOSE: Algebraic codebook decoder. For details about the encoding see + c4_17pf.c +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "basic_op.h" +#include "cnst.h" +#include "d4_17pf.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ +#define NB_PULSE 4 /* number of pulses */ + + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: decode_4i40_17bits +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + sign -- Word16 -- signs of 3 pulses. + index -- Word16 -- Positions of the 3 pulses. + + Outputs: + cod[] -- array of type Word16 -- algebraic (fixed) codebook excitation + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + d4_17pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void decode_4i40_17bits( + Word16 sign, /* i : signs of 4 pulses. */ + Word16 index, /* i : Positions of the 4 pulses. */ + const Word16* dgray_ptr, /* i : Pointer to read-only table */ + Word16 cod[] /* o : algebraic (fixed) codebook excitation */ +) +{ + Word16 i; + Word16 j; + + Word16 pos[NB_PULSE]; + + /* Index is a 13-bit value. 3 bits each correspond to the + * positions 0-2, with 4 bits allocated for position 3. + * + * + * [][][][] [][][] [][][] [][][] + * | | | | + * | | | | + * pos3 pos2 pos1 pos0 + */ + + /* Decode the positions */ + + i = index & 0x7; + + i = dgray_ptr[i]; + + pos[0] = i * 5; /* pos0 =i*5 */ + + + index >>= 3; + + i = index & 0x7; + + i = dgray_ptr[i]; + + pos[1] = i * 5 + 1; /* pos1 =i*5+1 */ + + + + index >>= 3; + + i = index & 0x7; + + i = dgray_ptr[i]; + + pos[2] = i * 5 + 2; /* pos2 =i*5+2 */ + + + + + + index >>= 3; + + j = index & 0x1; + + index >>= 1; + + i = index & 0x7; + + i = dgray_ptr[i]; + + pos[3] = i * 5 + 3 + j; /* pos3 =i*5+3+j */ + + + /* decode the signs and build the codeword */ + + for (i = 0; i < L_SUBFR; i++) + { + cod[i] = 0; + } + + for (j = 0; j < NB_PULSE; j++) + { + i = sign & 0x1; + + /* This line is equivalent to... + * + * + * if (i == 1) + * { + * cod[pos[j]] = 8191; + * } + * if (i == 0) + * { + * cod[pos[j]] = -8192; + * } + */ + + cod[pos[j]] = i * 16383 - 8192; + + sign >>= 1; + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d4_17pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d4_17pf.h new file mode 100644 index 00000000..b69cfae1 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d4_17pf.h @@ -0,0 +1,109 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d4_17pf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the d4_17pf.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef d4_17pf_h +#define d4_17pf_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void decode_4i40_17bits( + Word16 sign, /* i : signs of 4 pulses. */ + Word16 index, /* i : Positions of the 4 pulses. */ + const Word16* dgray_ptr, /* i : Pointer to read-only table */ + Word16 cod[] /* o : algebraic (fixed) codebook excitation */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _d4_17PF_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d8_31pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d8_31pf.cpp new file mode 100644 index 00000000..6195896b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d8_31pf.cpp @@ -0,0 +1,556 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d8_31pf.cpp + +------------------------------------------------------------------------------ + + MODULE DESCRIPTION +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "d8_31pf.h" +#include "typedef.h" +#include "basic_op.h" +#include "cnst.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define NB_PULSE 8 /* number of pulses */ + +/* define values/representation for output codevector and sign */ +#define POS_CODE 8191 +#define NEG_CODE 8191 + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: decompress10 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + MSBs -- Word16 -- MSB part of the index + LSBs -- Word16 -- LSB part of the index + index1 -- Word16 -- index for first pos in pos_index[] + index2 -- Word16 -- index for second pos in pos_index[] + index3 -- Word16 -- index for third pos in pos_index[] + + Outputs: + pos_indx[] -- array of type Word16 -- position of 3 pulses (decompressed) + + pOverflow Flag set when overflow occurs, pointer of type Flag * + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + d8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void decompress10( + Word16 MSBs, /* i : MSB part of the index */ + Word16 LSBs, /* i : LSB part of the index */ + Word16 index1, /* i : index for first pos in pos_index[] */ + Word16 index2, /* i : index for second pos in pos_index[] */ + Word16 index3, /* i : index for third pos in pos_index[] */ + Word16 pos_indx[], /* o : position of 3 pulses (decompressed) */ + Flag *pOverflow) /* o : Flag set when overflow occurs */ +{ + Word16 ia; + Word16 ib; + Word16 ic; + Word32 tempWord32; + + /* + pos_indx[index1] = ((MSBs-25*(MSBs/25))%5)*2 + (LSBs-4*(LSBs/4))%2; + pos_indx[index2] = ((MSBs-25*(MSBs/25))/5)*2 + (LSBs-4*(LSBs/4))/2; + pos_indx[index3] = (MSBs/25)*2 + LSBs/4; + */ + + if (MSBs > 124) + { + MSBs = 124; + } + + ia = + mult( + MSBs, + 1311, + pOverflow); + + tempWord32 = + L_mult( + ia, + 25, + pOverflow); + + + ia = (Word16)(MSBs - (tempWord32 >> 1)); + ib = + mult( + ia, + 6554, + pOverflow); + + tempWord32 = + L_mult( + ib, + 5, + pOverflow); + + ib = ia - (Word16)(tempWord32 >> 1); + + ib = + shl( + ib, + 1, + pOverflow); + + + ic = LSBs - ((LSBs >> 2) << 2); + + + pos_indx[index1] = ib + (ic & 1); + + + ib = + mult( + ia, + 6554, + pOverflow); + + ib = + shl( + ib, + 1, + pOverflow); + + + pos_indx[index2] = ib + (ic >> 1); + + + ib = LSBs >> 2; + + ic = + mult( + MSBs, + 1311, + pOverflow); + + ic = + shl( + ic, + 1, + pOverflow); + + pos_indx[index3] = add_16(ib, ic, pOverflow); + + return; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: decompress_code +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + indx[] -- array of type Word16 -- position and sign of + 8 pulses (compressed) + + Outputs: + sign_indx[] -- array of type Word16 -- signs of 4 pulses (signs only) + pos_indx[] -- array of type Word16 -- position index of 8 pulses + (position only) + pOverflow pointer to type Flag -- Flag set when overflow occurs + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: decompression of the linear codewords to 4+three indeces + one bit from each pulse is made robust to errors by + minimizing the phase shift of a bit error. + 4 signs (one for each track) + i0,i4,i1 => one index (7+3) bits, 3 LSBs more robust + i2,i6,i5 => one index (7+3) bits, 3 LSBs more robust + i3,i7 => one index (5+2) bits, 2-3 LSbs more robust + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + d8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void decompress_code( + Word16 indx[], /* i : position and sign of 8 pulses (compressed) */ + Word16 sign_indx[], /* o : signs of 4 pulses (signs only) */ + Word16 pos_indx[], /* o : position index of 8 pulses (position only) */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 ia; + Word16 ib; + Word16 MSBs; + Word16 LSBs; + Word16 MSBs0_24; + Word32 tempWord32; + + for (i = 0; i < NB_TRACK_MR102; i++) + { + sign_indx[i] = indx[i]; + } + + /* + First index: 10x10x10 -> 2x5x2x5x2x5-> 125x2x2x2 -> 7+1x3 bits + MSBs = indx[NB_TRACK]/8; + LSBs = indx[NB_TRACK]%8; + */ + MSBs = indx[NB_TRACK_MR102] >> 3; + + LSBs = indx[NB_TRACK_MR102] & 0x7; + + decompress10( + MSBs, + LSBs, + 0, + 4, + 1, + pos_indx, + pOverflow); + + /* + Second index: 10x10x10 -> 2x5x2x5x2x5-> 125x2x2x2 -> 7+1x3 bits + MSBs = indx[NB_TRACK+1]/8; + LSBs = indx[NB_TRACK+1]%8; + */ + MSBs = indx[NB_TRACK_MR102+1] >> 3; + + LSBs = indx[NB_TRACK_MR102+1] & 0x7; + + decompress10( + MSBs, + LSBs, + 2, + 6, + 5, + pos_indx, + pOverflow); + + /* + Third index: 10x10 -> 2x5x2x5-> 25x2x2 -> 5+1x2 bits + MSBs = indx[NB_TRACK+2]/4; + LSBs = indx[NB_TRACK+2]%4; + MSBs0_24 = (MSBs*25+12)/32; + if ((MSBs0_24/5)%2==1) + pos_indx[3] = (4-(MSBs0_24%5))*2 + LSBs%2; + else + pos_indx[3] = (MSBs0_24%5)*2 + LSBs%2; + pos_indx[7] = (MSBs0_24/5)*2 + LSBs/2; + */ + + MSBs = indx[NB_TRACK_MR102+2] >> 2; + + LSBs = indx[NB_TRACK_MR102+2] & 0x3; + + tempWord32 = + L_mult( + MSBs, + 25, + pOverflow); + + ia = + (Word16) + L_shr( + tempWord32, + 1, + pOverflow); + + ia += 12; + + MSBs0_24 = ia >> 5; + + + ia = + mult( + MSBs0_24, + 6554, + pOverflow); + + ia &= 1; + + + ib = + mult( + MSBs0_24, + 6554, + pOverflow); + + tempWord32 = + L_mult( + ib, + 5, + pOverflow); + + + ib = MSBs0_24 - (Word16)(tempWord32 >> 1); + + if (ia == 1) + { + ib = 4 - ib; + + } + + + ib = + shl( + ib, + 1, + pOverflow); + + ia = LSBs & 0x1; + + pos_indx[3] = + add_16( + ib, + ia, + pOverflow); + + ia = + mult( + MSBs0_24, + 6554, + pOverflow); + + ia = + shl( + ia, + 1, + pOverflow); + + pos_indx[7] = ia + (LSBs >> 1); + +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: dec_8i40_31bits +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + index array of type Word16 -- index of 8 pulses (sign+position) + + Outputs: + cod array of type Word16 -- algebraic (fixed) codebook excitation + pOverflow pointer to type Flag -- Flag set when overflow occurs + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Builds the innovative codevector from the received + index of algebraic codebook. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + d8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void dec_8i40_31bits( + Word16 index[], /* i : index of 8 pulses (sign+position) */ + Word16 cod[], /* o : algebraic (fixed) codebook excitation */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 j; + Word16 pos1; + Word16 pos2; + Word16 sign; + + Word16 linear_signs[NB_TRACK_MR102]; + Word16 linear_codewords[NB_PULSE]; + + for (i = 0; i < L_CODE; i++) + { + cod[i] = 0; + } + + decompress_code( + index, + linear_signs, + linear_codewords, + pOverflow); + + /* decode the positions and signs of pulses and build the codeword */ + for (j = 0; j < NB_TRACK_MR102; j++) /* NB_TRACK_MR102 = 4 */ + { + /* position of pulse "j" */ + + pos1 = (linear_codewords[j] << 2) + j; + + + if (linear_signs[j] == 0) + { + sign = POS_CODE; /* +1.0 */ + } + else + { + sign = -NEG_CODE; /* -1.0 */ + } + + if (pos1 < L_SUBFR) + { + cod[pos1] = sign; /* avoid buffer overflow */ + } + + /* compute index i */ + /* position of pulse "j+4" */ + + pos2 = (linear_codewords[j + 4] << 2) + j; + + + if (pos2 < pos1) + { + sign = negate(sign); + } + + if (pos2 < L_SUBFR) + { + cod[pos2] += sign; /* avoid buffer overflow */ + } + + + } /* for (j = 0; j < NB_TRACK_MR102; j++) */ + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d8_31pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d8_31pf.h new file mode 100644 index 00000000..d46e236a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d8_31pf.h @@ -0,0 +1,108 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d8_31pf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the d8_31pf.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef d8_31pf_h +#define d8_31pf_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void dec_8i40_31bits( + Word16 index[], /* i : index of 8 pulses (sign+position) */ + Word16 cod[], /* o : algebraic (fixed) codebook excitation */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _d8_31PF_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_gain_c.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_gain_c.cpp new file mode 100644 index 00000000..9cc14c00 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_gain_c.cpp @@ -0,0 +1,214 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d_gain_c.cpp + Functions: d_gain_c + + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pred_state = pointer to sturcture type gc_predState. MA predictor state + mode = AMR mode (MR795 or MR122) of type enum Mode + index = received quantization index of type Word16 + code[] = pointer to innovation codevector of type Word16 + pOverflow= pointer to value indicating existence of overflow (Flag) + + Outputs: + pred_state = pointer to sturcture type gc_predState. MA predictor state + gain_code = pointer to decoded innovation gain of type Word16 + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function : d_gain_code + Purpose : Decode the fixed codebook gain using the received index. + +------------------------------------------------------------------------------ + REQUIREMENTS + + + +------------------------------------------------------------------------------ + REFERENCES + + d_gain_c.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "d_gain_c.h" +#include "typedef.h" +#include "mode.h" + +#include "oper_32b.h" +#include "cnst.h" +#include "log2.h" +#include "pow2.h" +#include "gc_pred.h" + +#include "basic_op.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; LOCAL STORE/BUFFER/POINTER DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL FUNCTION REFERENCES + ; Declare functions defined elsewhere and referenced in this module + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +void d_gain_code( + gc_predState *pred_state, /* i/o : MA predictor state */ + enum Mode mode, /* i : AMR mode (MR795 or MR122) */ + Word16 index, /* i : received quantization index */ + Word16 code[], /* i : innovation codevector */ + const Word16* qua_gain_code_ptr, /* i : Pointer to read-only table */ + Word16 *gain_code, /* o : decoded innovation gain */ + Flag *pOverflow +) +{ + Word16 gcode0, exp, frac; + const Word16 *p; + Word16 qua_ener_MR122, qua_ener; + Word16 exp_inn_en; + Word16 frac_inn_en; + Word32 L_tmp; + Word16 tbl_tmp; + Word16 temp; + /*-------------- Decode codebook gain ---------------*/ + + /*-------------------------------------------------------------------* + * predict codebook gain * + * ~~~~~~~~~~~~~~~~~~~~~ * + * gc0 = Pow2(int(d)+frac(d)) * + * = 2^exp + 2^frac * + * * + *-------------------------------------------------------------------*/ + + gc_pred(pred_state, mode, code, &exp, &frac, + &exp_inn_en, &frac_inn_en, pOverflow); + + index &= 31; /* index < 32, to avoid buffer overflow */ + tbl_tmp = index + (index << 1); + + p = &qua_gain_code_ptr[tbl_tmp]; + + /* Different scalings between MR122 and the other modes */ + temp = sub((Word16)mode, (Word16)MR122, pOverflow); + if (temp == 0) + { + gcode0 = (Word16)(Pow2(exp, frac, pOverflow)); /* predicted gain */ + gcode0 = shl(gcode0, 4, pOverflow); + *gain_code = shl(mult(gcode0, *p++, pOverflow), 1, pOverflow); + } + else + { + gcode0 = (Word16)(Pow2(14, frac, pOverflow)); + L_tmp = L_mult(*p++, gcode0, pOverflow); + L_tmp = L_shr(L_tmp, sub(9, exp, pOverflow), pOverflow); + *gain_code = (Word16)(L_tmp >> 16); /* Q1 */ + } + + /*-------------------------------------------------------------------* + * update table of past quantized energies * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + *-------------------------------------------------------------------*/ + qua_ener_MR122 = *p++; + qua_ener = *p++; + gc_pred_update(pred_state, qua_ener_MR122, qua_ener); + + return; +} + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_gain_p.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_gain_p.cpp new file mode 100644 index 00000000..ac399503 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_gain_p.cpp @@ -0,0 +1,153 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d_gain_p.cpp + Functions: d_gain_p + + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + mode -- enumerated type -- AMR mode + index -- Word16 -- index of quantization + Outputs: + None + + Returns: + Word16 gain -- (Q14) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function : d_gain_pitch + Purpose : Decodes the pitch gain using the received index. + output is in Q14 + +------------------------------------------------------------------------------ + REQUIREMENTS + + + +------------------------------------------------------------------------------ + REFERENCES + + d_gain_p.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "d_gain_p.h" +#include "typedef.h" +#include "mode.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; LOCAL STORE/BUFFER/POINTER DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL FUNCTION REFERENCES + ; Declare functions defined elsewhere and referenced in this module + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +Word16 d_gain_pitch( /* return value: gain (Q14) */ + enum Mode mode, /* i : AMR mode */ + Word16 index, /* i : index of quantization */ + const Word16* qua_gain_pitch_ptr /* i : pointer to read-only tables */ +) +{ + Word16 gain; + + gain = qua_gain_pitch_ptr[index]; + + if (mode == MR122) + { + /* clear 2 LSBits */ + gain &= 0xFFFC; + } + + return gain; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_plsf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_plsf.cpp new file mode 100644 index 00000000..7ac56b4d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_plsf.cpp @@ -0,0 +1,170 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d_plsf.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + common part (reset) of LSF decoder + module (rest in d_plsf_3.c and d_plsf_5.c) +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "basic_op.h" +#include "cnst.h" +#include "oscl_mem.h" +#include "d_plsf.h" +#include "q_plsf_5_tbl.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: D_plsf_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to structure of type D_plsf_reset + + Outputs: + fields of the structure pointed to by state is initialized to zero + + Returns: + return_value = 0, if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Resets state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + d_plsf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int D_plsf_reset (D_plsfState *state) +{ + Word16 i; + + if (state == (D_plsfState *) NULL){ + // fprintf(stderr, "D_plsf_reset: invalid parameter\n"); + return -1; + } + + for (i = 0; i < M; i++){ + state->past_r_q[i] = 0; // Past quantized prediction error + } + + // Past dequantized lsfs + Copy(mean_lsf, &state->past_lsf_q[0], M); + + return 0; +} +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 D_plsf_reset(D_plsfState *state, const Word16* mean_lsf_5_ptr) +{ + Word16 i; + + if (state == (D_plsfState *) NULL) + { + /* fprintf(stderr, "D_plsf_reset: invalid parameter\n"); */ + return -1; + } + + for (i = 0; i < M; i++) + { + state->past_r_q[i] = 0; /* Past quantized prediction error */ + } + + /* Past dequantized lsfs */ + oscl_memmove((void *)&state->past_lsf_q[0], mean_lsf_5_ptr, M*sizeof(*mean_lsf_5_ptr)); + + return 0; + +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_plsf_3.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_plsf_3.cpp new file mode 100644 index 00000000..2d3a4ef2 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_plsf_3.cpp @@ -0,0 +1,468 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d_plsf_3.cpp + Functions: D_plsf_3 + + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- Pointer to type struct D_plsfState + mode -- enum Mode -- coder mode + bfi -- Word16 -- bad frame indicator (set to 1 if a bad frame is received) + indice -- Pointer to type Word16 -- quantization indices of + 3 submatrices, Q0 + + Outputs: + st -- Pointer to type struct D_plsfState + lsp1_q -- Pointer to type Word16 -- quantized 1st LSP vector Q15 + pOverflow -- Pointer to type Flag -- Flag set when overflow occurs + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Decodes the LSP parameters using the received quantization + indices.1st order MA prediction and split by 3 vector + quantization (split-VQ) + +------------------------------------------------------------------------------ + REQUIREMENTS + + + +------------------------------------------------------------------------------ + REFERENCES + + d_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "d_plsf.h" +#include "typedef.h" +#include "basic_op.h" +#include "lsp_lsf.h" +#include "reorder.h" +#include "oscl_mem.h" +#include "q_plsf_3_tbl.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define ALPHA 29491 /* ALPHA -> 0.9 */ +#define ONE_ALPHA 3277 /* ONE_ALPHA-> (1.0-ALPHA) */ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void D_plsf_3( + D_plsfState *st, /* i/o: State struct */ + enum Mode mode, /* i : coder mode */ + Word16 bfi, /* i : bad frame indicator (set to 1 if a */ + /* bad frame is received) */ + Word16 * indice, /* i : quantization indices of 3 submatrices, Q0 */ + CommonAmrTbls* common_amr_tbls, /* i : structure containing ptrs to read-only tables */ + Word16 * lsp1_q, /* o : quantized 1st LSP vector, Q15 */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 temp; + Word16 index; + + Word16 lsf1_r[M]; + Word16 lsf1_q[M]; + + const Word16* mean_lsf_3_ptr = common_amr_tbls->mean_lsf_3_ptr; + const Word16* pred_fac_3_ptr = common_amr_tbls->pred_fac_3_ptr; + const Word16* dico1_lsf_3_ptr = common_amr_tbls->dico1_lsf_3_ptr; + const Word16* dico2_lsf_3_ptr = common_amr_tbls->dico2_lsf_3_ptr; + const Word16* dico3_lsf_3_ptr = common_amr_tbls->dico3_lsf_3_ptr; + const Word16* mr515_3_lsf_ptr = common_amr_tbls->mr515_3_lsf_ptr; + const Word16* mr795_1_lsf_ptr = common_amr_tbls->mr795_1_lsf_ptr; + + if (bfi != 0) /* if bad frame */ + { + /* use the past LSFs slightly shifted towards their mean */ + + for (i = 0; i < M; i++) + { + /* lsfi_q[i] = ALPHA*past_lsf_q[i] + ONE_ALPHA*mean_lsf[i]; */ + temp = + mult( + st->past_lsf_q[i], + ALPHA, + pOverflow); + + index = + mult( + mean_lsf_3_ptr[i], + ONE_ALPHA, + pOverflow); + + lsf1_q[i] = + add_16( + index, + temp, + pOverflow); + } + + /* estimate past quantized residual to be used in next frame */ + if (mode != MRDTX) + { + for (i = 0; i < M; i++) + { + /* temp = mean_lsf[i] + past_r2_q[i] * PRED_FAC; */ + + temp = + mult( + st->past_r_q[i], + pred_fac_3_ptr[i], + pOverflow); + + temp = + add_16( + mean_lsf_3_ptr[i], + temp, + pOverflow); + + st->past_r_q[i] = + sub( + lsf1_q[i], + temp, + pOverflow); + } + + } /* if (mode == MRDTX) */ + else + { + for (i = 0; i < M; i++) + { + /* temp = mean_lsf[i] + past_r2_q[i]; */ + + temp = + add_16( + mean_lsf_3_ptr[i], + st->past_r_q[i], + pOverflow); + + st->past_r_q[i] = + sub( + lsf1_q[i], + temp, + pOverflow); + } + } + + } /* if (bfi != 0) */ + + else /* if good LSFs received */ + { + + Word16 index_limit_1 = 0; + Word16 index_limit_2 = (DICO2_SIZE - 1) * 3; + Word16 index_limit_3 = 0; + + const Word16 *p_cb1; + const Word16 *p_cb2; + const Word16 *p_cb3; + const Word16 *p_dico; + + + p_cb2 = dico2_lsf_3_ptr; /* size DICO2_SIZE*3 */ + + if ((mode == MR475) || (mode == MR515)) + { /* MR475, MR515 */ + p_cb1 = dico1_lsf_3_ptr; /* size DICO1_SIZE*3 */ + p_cb3 = mr515_3_lsf_ptr; /* size MR515_3_SIZE*4 */ + + index_limit_1 = (DICO1_SIZE - 1) * 3; + index_limit_3 = (MR515_3_SIZE - 1) * 4; + + } + else if (mode == MR795) + { /* MR795 */ + p_cb1 = mr795_1_lsf_ptr; /* size MR795_1_SIZE*3 */ + p_cb3 = dico3_lsf_3_ptr; /* size DICO3_SIZE*4 */ + + index_limit_1 = (MR795_1_SIZE - 1) * 3; + index_limit_3 = (DICO3_SIZE - 1) * 4; + + } + else + { /* MR59, MR67, MR74, MR102, MRDTX */ + p_cb1 = dico1_lsf_3_ptr; /* size DICO1_SIZE*3 */ + p_cb3 = dico3_lsf_3_ptr; /* size DICO3_SIZE*4 */ + + index_limit_1 = (DICO1_SIZE - 1) * 3; + index_limit_3 = (DICO3_SIZE - 1) * 4; + + } + + /* decode prediction residuals from 3 received indices */ + + index = *indice++; + + /* temp = 3*index; */ + temp = index + (index << 1); + + if (temp > index_limit_1) + { + temp = index_limit_1; /* avoid buffer overrun */ + } + + p_dico = &p_cb1[temp]; + + lsf1_r[0] = *p_dico++; + lsf1_r[1] = *p_dico++; + lsf1_r[2] = *p_dico++; + + index = *indice++; + + if (mode == MR475 || mode == MR515) + { /* MR475, MR515 only using every second entry */ + index <<= 1; + } + + /* temp = 3*index */ + temp = index + (index << 1); + + if (temp > index_limit_2) + { + temp = index_limit_2; /* avoid buffer overrun */ + } + + p_dico = &p_cb2[temp]; + + lsf1_r[3] = *p_dico++; + lsf1_r[4] = *p_dico++; + lsf1_r[5] = *p_dico++; + + index = *indice++; + + temp = index << 2; + + if (temp > index_limit_3) + { + temp = index_limit_3; /* avoid buffer overrun */ + } + + + p_dico = &p_cb3[temp]; + + lsf1_r[6] = *p_dico++; + lsf1_r[7] = *p_dico++; + lsf1_r[8] = *p_dico++; + lsf1_r[9] = *p_dico++; + + /* Compute quantized LSFs and update the past quantized residual */ + + if (mode != MRDTX) + { + for (i = 0; i < M; i++) + { + temp = + mult( + st->past_r_q[i], + pred_fac_3_ptr[i], + pOverflow); + + temp = + add_16( + mean_lsf_3_ptr[i], + temp, + pOverflow); + + lsf1_q[i] = + add_16( + lsf1_r[i], + temp, + pOverflow); + + st->past_r_q[i] = lsf1_r[i]; + } + } + else + { + for (i = 0; i < M; i++) + { + temp = + add_16( + mean_lsf_3_ptr[i], + st->past_r_q[i], + pOverflow); + + lsf1_q[i] = + add_16( + lsf1_r[i], + temp, + pOverflow); + + st->past_r_q[i] = lsf1_r[i]; + } + } + + } + + /* verification that LSFs has minimum distance of LSF_GAP Hz */ + + Reorder_lsf( + lsf1_q, + LSF_GAP, + M, + pOverflow); + + oscl_memmove( + (void *)st->past_lsf_q, + lsf1_q, + M*sizeof(*lsf1_q)); + + /* convert LSFs to the cosine domain */ + + Lsf_lsp( + lsf1_q, + lsp1_q, + M, + pOverflow); + + return; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Init_D_plsf_3 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type D_plsfState + index = Word16, past_rq_init[] index [0, 7] + + Outputs: + st = pointer to a structure of type D_plsfState + + Returns: + None + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function initializes the D_plsfState structure. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + d_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void Init_D_plsf_3( + D_plsfState *st, /* i/o: State struct */ + Word16 index, /* i : past_rq_init[] index [0, 7] */ + const Word16* past_rq_init_ptr /* ptr to read-only table */) +{ + oscl_memmove( + (void *)st->past_r_q, + &past_rq_init_ptr[index * M], + M*sizeof(*past_rq_init_ptr)); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_plsf_5.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_plsf_5.cpp new file mode 100644 index 00000000..8a4e7633 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/d_plsf_5.cpp @@ -0,0 +1,459 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: d_plsf_5.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "d_plsf.h" +#include "typedef.h" +#include "basic_op.h" +#include "lsp_lsf.h" +#include "reorder.h" +#include "cnst.h" +#include "oscl_mem.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + /* ALPHA -> 0.95 */ + /* ONE_ALPHA-> (1.0-ALPHA) */ +#define ALPHA 31128 +#define ONE_ALPHA 1639 + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL STORE/BUFFER/POINTER DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: D_plsf_5 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type D_plsfState + bfi = bad frame indicator; set to 1 if a bad frame is received (Word16) + indice = pointer to quantization indices of 5 submatrices (Word16) + lsp1_q = pointer to the quantized 1st LSP vector (Word16) + lsp2_q = pointer to the quantized 2nd LSP vector (Word16) + + Outputs: + lsp1_q points to the updated quantized 1st LSP vector + lsp2_q points to the updated quantized 2nd LSP vector + Flag *pOverflow -- Flag set when overflow occurs. + + Returns: + return_value = 0 (int) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function decodes the 2 sets of LSP parameters in a frame using the + received quantization indices. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + d_plsf_5.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int D_plsf_5 ( + D_plsfState *st, // i/o: State variables + Word16 bfi, // i : bad frame indicator (set to 1 if a bad + frame is received) + Word16 *indice, // i : quantization indices of 5 submatrices, Q0 + Word16 *lsp1_q, // o : quantized 1st LSP vector (M), Q15 + Word16 *lsp2_q // o : quantized 2nd LSP vector (M), Q15 +) +{ + Word16 i; + const Word16 *p_dico; + Word16 temp, sign; + Word16 lsf1_r[M], lsf2_r[M]; + Word16 lsf1_q[M], lsf2_q[M]; + + if (bfi != 0) // if bad frame + { + // use the past LSFs slightly shifted towards their mean + + for (i = 0; i < M; i++) + { + // lsfi_q[i] = ALPHA*st->past_lsf_q[i] + ONE_ALPHA*mean_lsf[i]; + + lsf1_q[i] = add (mult (st->past_lsf_q[i], ALPHA), + mult (mean_lsf[i], ONE_ALPHA)); + + lsf2_q[i] = lsf1_q[i]; + } + + // estimate past quantized residual to be used in next frame + + for (i = 0; i < M; i++) + { + // temp = mean_lsf[i] + st->past_r_q[i] * LSP_PRED_FAC_MR122; + + temp = add (mean_lsf[i], mult (st->past_r_q[i], + LSP_PRED_FAC_MR122)); + + st->past_r_q[i] = sub (lsf2_q[i], temp); + } + } + else + // if good LSFs received + { + // decode prediction residuals from 5 received indices + + p_dico = &dico1_lsf[shl (indice[0], 2)]; + lsf1_r[0] = *p_dico++; + lsf1_r[1] = *p_dico++; + lsf2_r[0] = *p_dico++; + lsf2_r[1] = *p_dico++; + + p_dico = &dico2_lsf[shl (indice[1], 2)]; + lsf1_r[2] = *p_dico++; + lsf1_r[3] = *p_dico++; + lsf2_r[2] = *p_dico++; + lsf2_r[3] = *p_dico++; + + sign = indice[2] & 1; + i = shr (indice[2], 1); + p_dico = &dico3_lsf[shl (i, 2)]; + + if (sign == 0) + { + lsf1_r[4] = *p_dico++; + lsf1_r[5] = *p_dico++; + lsf2_r[4] = *p_dico++; + lsf2_r[5] = *p_dico++; + } + else + { + lsf1_r[4] = negate (*p_dico++); + lsf1_r[5] = negate (*p_dico++); + lsf2_r[4] = negate (*p_dico++); + lsf2_r[5] = negate (*p_dico++); + } + + p_dico = &dico4_lsf[shl (indice[3], 2)]; + lsf1_r[6] = *p_dico++; + lsf1_r[7] = *p_dico++; + lsf2_r[6] = *p_dico++; + lsf2_r[7] = *p_dico++; + + p_dico = &dico5_lsf[shl (indice[4], 2)]; + lsf1_r[8] = *p_dico++; + lsf1_r[9] = *p_dico++; + lsf2_r[8] = *p_dico++; + lsf2_r[9] = *p_dico++; + + // Compute quantized LSFs and update the past quantized residual + for (i = 0; i < M; i++) + { + temp = add (mean_lsf[i], mult (st->past_r_q[i], + LSP_PRED_FAC_MR122)); + lsf1_q[i] = add (lsf1_r[i], temp); + lsf2_q[i] = add (lsf2_r[i], temp); + st->past_r_q[i] = lsf2_r[i]; + } + } + + // verification that LSFs have minimum distance of LSF_GAP Hz + + Reorder_lsf (lsf1_q, LSF_GAP, M); + Reorder_lsf (lsf2_q, LSF_GAP, M); + + Copy (lsf2_q, st->past_lsf_q, M); + + // convert LSFs to the cosine domain + + Lsf_lsp (lsf1_q, lsp1_q, M); + Lsf_lsp (lsf2_q, lsp2_q, M); + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void D_plsf_5( + D_plsfState *st, /* i/o: State variables */ + Word16 bfi, /* i : bad frame indicator (set to 1 if a bad + frame is received) */ + Word16 *indice, /* i : quantization indices of 5 submatrices, Q0 */ + CommonAmrTbls* common_amr_tbls, /* i : structure containing ptrs to read-only tables */ + Word16 *lsp1_q, /* o : quantized 1st LSP vector (M), Q15 */ + Word16 *lsp2_q, /* o : quantized 2nd LSP vector (M), Q15 */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + register Word16 i; + Word16 temp; + Word16 sign; + + const Word16 *p_dico; + + Word16 lsf1_r[M]; + Word16 lsf2_r[M]; + Word16 lsf1_q[M]; + Word16 lsf2_q[M]; + + /* These tables are defined in q_plsf_5_tbl.c */ + const Word16* mean_lsf_5_ptr = common_amr_tbls->mean_lsf_5_ptr; + const Word16* dico1_lsf_5_ptr = common_amr_tbls->dico1_lsf_5_ptr; + const Word16* dico2_lsf_5_ptr = common_amr_tbls->dico2_lsf_5_ptr; + const Word16* dico3_lsf_5_ptr = common_amr_tbls->dico3_lsf_5_ptr; + const Word16* dico4_lsf_5_ptr = common_amr_tbls->dico4_lsf_5_ptr; + const Word16* dico5_lsf_5_ptr = common_amr_tbls->dico5_lsf_5_ptr; + + if (bfi != 0) /* if bad frame */ + { + /* use the past LSFs slightly shifted towards their mean */ + + for (i = 0; i < M; i++) + { + /* + * lsfi_q[i] = ALPHA*st->past_lsf_q[i] + + * ONE_ALPHA*mean_lsf[i]; + */ + + temp = (Word16)(((Word32) st->past_lsf_q[i] * ALPHA) >> 15); + + sign = (Word16)(((Word32) * (mean_lsf_5_ptr + i) * ONE_ALPHA) >> 15); + + *(lsf1_q + i) = add_16(sign, temp, pOverflow); + + *(lsf2_q + i) = *(lsf1_q + i); + + /* + * estimate past quantized residual to be used in + * next frame + */ + + /* + * temp = mean_lsf[i] + + * st->past_r_q[i] * LSP_PRED_FAC_MR122; + */ + + temp = (Word16)(((Word32) st->past_r_q[i] * LSP_PRED_FAC_MR122) >> 15); + + temp = add_16(*(mean_lsf_5_ptr + i), temp, pOverflow); + + st->past_r_q[i] = sub(*(lsf2_q + i), temp, pOverflow); + } + } + else + /* if good LSFs received */ + { + /* decode prediction residuals from 5 received indices */ + + temp = + shl( + *(indice), + 2, + pOverflow); + + p_dico = &dico1_lsf_5_ptr[temp]; + + *(lsf1_r + 0) = *p_dico++; + *(lsf1_r + 1) = *p_dico++; + *(lsf2_r + 0) = *p_dico++; + *(lsf2_r + 1) = *p_dico++; + + temp = shl(*(indice + 1), 2, pOverflow); + + p_dico = &dico2_lsf_5_ptr[temp]; + + *(lsf1_r + 2) = *p_dico++; + *(lsf1_r + 3) = *p_dico++; + *(lsf2_r + 2) = *p_dico++; + *(lsf2_r + 3) = *p_dico++; + + sign = *(indice + 2) & 1; + + if (*(indice + 2) < 0) + { + i = ~(~(*(indice + 2)) >> 1); + } + else + { + i = *(indice + 2) >> 1; + } + + temp = shl(i, 2, pOverflow); + + p_dico = &dico3_lsf_5_ptr[temp]; + + if (sign == 0) + { + *(lsf1_r + 4) = *p_dico++; + *(lsf1_r + 5) = *p_dico++; + *(lsf2_r + 4) = *p_dico++; + *(lsf2_r + 5) = *p_dico++; + } + else + { + *(lsf1_r + 4) = negate(*p_dico++); + *(lsf1_r + 5) = negate(*p_dico++); + *(lsf2_r + 4) = negate(*p_dico++); + *(lsf2_r + 5) = negate(*p_dico++); + } + + temp = shl(*(indice + 3), 2, pOverflow); + + p_dico = &dico4_lsf_5_ptr[temp]; + + *(lsf1_r + 6) = *p_dico++; + *(lsf1_r + 7) = *p_dico++; + *(lsf2_r + 6) = *p_dico++; + *(lsf2_r + 7) = *p_dico++; + + temp = shl(*(indice + 4), 2, pOverflow); + + p_dico = &dico5_lsf_5_ptr[temp]; + + *(lsf1_r + 8) = *p_dico++; + *(lsf1_r + 9) = *p_dico++; + *(lsf2_r + 8) = *p_dico++; + *(lsf2_r + 9) = *p_dico++; + + /* Compute quantized LSFs and update the past quantized + residual */ + for (i = 0; i < M; i++) + { + temp = + mult( + st->past_r_q[i], + LSP_PRED_FAC_MR122, + pOverflow); + + temp = + add_16( + *(mean_lsf_5_ptr + i), + temp, + pOverflow); + + *(lsf1_q + i) = + add_16( + *(lsf1_r + i), + temp, + pOverflow); + + *(lsf2_q + i) = + add_16( + *(lsf2_r + i), + temp, + pOverflow); + + st->past_r_q[i] = *(lsf2_r + i); + } + } + + /* verification that LSFs have minimum distance of LSF_GAP Hz */ + + Reorder_lsf( + lsf1_q, + LSF_GAP, + M, + pOverflow); + + Reorder_lsf( + lsf2_q, + LSF_GAP, + M, + pOverflow); + + oscl_memmove((void *)st->past_lsf_q, lsf2_q, M*sizeof(*lsf2_q)); + + /* convert LSFs to the cosine domain */ + + Lsf_lsp( + lsf1_q, + lsp1_q, + M, + pOverflow); + + Lsf_lsp( + lsf2_q, + lsp2_q, + M, + pOverflow); + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_amr.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_amr.cpp new file mode 100644 index 00000000..1e62c155 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_amr.cpp @@ -0,0 +1,2333 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Filename: dec_amr.cpp + Funtions: Decoder_amr_init + Decoder_amr_reset + Decoder_amr + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the function used to decode one speech frame using a given + codec mode. The functions used to initialize, reset, and exit are also + included in this file. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "dec_amr.h" +#include "typedef.h" +#include "cnst.h" +#include "set_zero.h" +#include "syn_filt.h" +#include "d_plsf.h" +#include "agc.h" +#include "int_lpc.h" +#include "dec_gain.h" +#include "dec_lag3.h" +#include "dec_lag6.h" +#include "d2_9pf.h" +#include "d2_11pf.h" +#include "d3_14pf.h" +#include "d4_17pf.h" +#include "d8_31pf.h" +#include "d1035pf.h" +#include "pred_lt.h" +#include "d_gain_p.h" +#include "d_gain_c.h" +#include "dec_gain.h" +#include "ec_gains.h" +#include "ph_disp.h" +#include "c_g_aver.h" +#include "int_lsf.h" +#include "lsp_lsf.h" +#include "lsp_avg.h" +#include "bgnscd.h" +#include "ex_ctrl.h" +#include "sqrt_l.h" +#include "frame.h" +#include "b_cn_cod.h" +#include "basic_op.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Decoder_amr_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a pointer to structures of type Decoder_amrState + + Outputs: + structure pointed to by the pointer which is pointed to by state is + initialized to each field's initial values + + state pointer points to the address of the memory allocated by + Decoder_amr_init function + + Returns: + return_value = 0, if the initialization was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function allocates and initializes state memory used by the Decoder_amr + function. It stores the pointer to the filter status structure in state. This + pointer has to be passed to Decoder_amr in each call. The function returns + 0, if initialization was successful and -1, otherwise. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dec_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Decoder_amr_init (Decoder_amrState **state) +{ + Decoder_amrState* s; + Word16 i; + + if (state == (Decoder_amrState **) NULL){ + fprintf(stderr, "Decoder_amr_init: invalid parameter\n"); + return -1; + } + *state = NULL; + + // allocate memory + if ((s= (Decoder_amrState *) malloc(sizeof(Decoder_amrState))) == NULL){ + fprintf(stderr, "Decoder_amr_init: can not malloc state structure\n"); + return -1; + } + + s->T0_lagBuff = 40; + s->inBackgroundNoise = 0; + s->voicedHangover = 0; + for (i = 0; i < 9; i++) + s->ltpGainHistory[i] = 0; + + s->lsfState = NULL; + s->ec_gain_p_st = NULL; + s->ec_gain_c_st = NULL; + s->pred_state = NULL; + s->ph_disp_st = NULL; + s->dtxDecoderState = NULL; + + if (D_plsf_init(&s->lsfState) || + ec_gain_pitch_init(&s->ec_gain_p_st) || + ec_gain_code_init(&s->ec_gain_c_st) || + gc_pred_init(&s->pred_state) || + Cb_gain_average_init(&s->Cb_gain_averState) || + lsp_avg_init(&s->lsp_avg_st) || + Bgn_scd_init(&s->background_state) || + ph_disp_init(&s->ph_disp_st) || + dtx_dec_init(&s->dtxDecoderState)) { + Decoder_amr_exit(&s); + return -1; + } + + Decoder_amr_reset(s, (enum Mode)0); + *state = s; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Decoder_amr_init(Decoder_amrState *s) +{ + Word16 i; + + if (s == (Decoder_amrState *) NULL) + { + /* fprint(stderr, "Decoder_amr_init: invalid parameter\n"); */ + return(-1); + } + + get_const_tbls(&s->common_amr_tbls); + + s->T0_lagBuff = 40; + s->inBackgroundNoise = 0; + s->voicedHangover = 0; + + /* Initialize overflow Flag */ + + s->overflow = 0; + + for (i = 0; i < LTP_GAIN_HISTORY_LEN; i++) + { + s->ltpGainHistory[i] = 0; + } + + D_plsf_reset(&s->lsfState, s->common_amr_tbls.mean_lsf_5_ptr); + ec_gain_pitch_reset(&s->ec_gain_p_st); + ec_gain_code_reset(&s->ec_gain_c_st); + Cb_gain_average_reset(&s->Cb_gain_averState); + lsp_avg_reset(&s->lsp_avg_st, s->common_amr_tbls.mean_lsf_5_ptr); + Bgn_scd_reset(&s->background_state); + ph_disp_reset(&s->ph_disp_st); + dtx_dec_reset(&s->dtxDecoderState); + gc_pred_reset(&s->pred_state); + + Decoder_amr_reset(s, MR475); + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Decoder_amr_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a structure of type Decoder_amrState + mode = codec mode (enum Mode) + + Outputs: + structure pointed to by state is initialized to its reset value + + Returns: + return_value = 0, if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function resets the state memory used by the Decoder_amr function. It + returns a 0, if reset was successful and -1, otherwise. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dec_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Decoder_amr_reset (Decoder_amrState *state, enum Mode mode) +{ + Word16 i; + + if (state == (Decoder_amrState *) NULL){ + fprintf(stderr, "Decoder_amr_reset: invalid parameter\n"); + return -1; + } + + // Initialize static pointer + state->exc = state->old_exc + PIT_MAX + L_INTERPOL; + + // Static vectors to zero + Set_zero (state->old_exc, PIT_MAX + L_INTERPOL); + + if (mode != MRDTX) + Set_zero (state->mem_syn, M); + + // initialize pitch sharpening + state->sharp = SHARPMIN; + state->old_T0 = 40; + + // Initialize state->lsp_old [] + + if (mode != MRDTX) { + Copy(lsp_init_data, &state->lsp_old[0], M); + } + + // Initialize memories of bad frame handling + state->prev_bf = 0; + state->prev_pdf = 0; + state->state = 0; + + state->T0_lagBuff = 40; + state->inBackgroundNoise = 0; + state->voicedHangover = 0; + if (mode != MRDTX) { + for (i=0;i<9;i++) + state->excEnergyHist[i] = 0; + } + + for (i = 0; i < 9; i++) + state->ltpGainHistory[i] = 0; + + Cb_gain_average_reset(state->Cb_gain_averState); + if (mode != MRDTX) + lsp_avg_reset(state->lsp_avg_st); + D_plsf_reset(state->lsfState); + ec_gain_pitch_reset(state->ec_gain_p_st); + ec_gain_code_reset(state->ec_gain_c_st); + + if (mode != MRDTX) + gc_pred_reset(state->pred_state); + + Bgn_scd_reset(state->background_state); + state->nodataSeed = 21845; + ph_disp_reset(state->ph_disp_st); + if (mode != MRDTX) + dtx_dec_reset(state->dtxDecoderState); + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Decoder_amr_reset(Decoder_amrState *state, enum Mode mode) +{ + Word16 i; + + if (state == (Decoder_amrState *) NULL) + { + /* fprint(stderr, "Decoder_amr_reset: invalid parameter\n"); */ + return(-1); + } + + /* Initialize static pointer */ + state->exc = state->old_exc + PIT_MAX + L_INTERPOL; + + /* Static vectors to zero */ + oscl_memset(state->old_exc, 0, sizeof(Word16)*(PIT_MAX + L_INTERPOL)); + + if (mode != MRDTX) + { + oscl_memset(state->mem_syn, 0, sizeof(Word16)*M); + } + /* initialize pitch sharpening */ + state->sharp = SHARPMIN; + state->old_T0 = 40; + + /* Initialize overflow Flag */ + + state->overflow = 0; + + /* Initialize state->lsp_old [] */ + + if (mode != MRDTX) + { + state->lsp_old[0] = 30000; + state->lsp_old[1] = 26000; + state->lsp_old[2] = 21000; + state->lsp_old[3] = 15000; + state->lsp_old[4] = 8000; + state->lsp_old[5] = 0; + state->lsp_old[6] = -8000; + state->lsp_old[7] = -15000; + state->lsp_old[8] = -21000; + state->lsp_old[9] = -26000; + } + + /* Initialize memories of bad frame handling */ + state->prev_bf = 0; + state->prev_pdf = 0; + state->state = 0; + + state->T0_lagBuff = 40; + state->inBackgroundNoise = 0; + state->voicedHangover = 0; + if (mode != MRDTX) + { + for (i = 0; i < EXC_ENERGY_HIST_LEN; i++) + { + state->excEnergyHist[i] = 0; + } + } + + for (i = 0; i < LTP_GAIN_HISTORY_LEN; i++) + { + state->ltpGainHistory[i] = 0; + } + + Cb_gain_average_reset(&(state->Cb_gain_averState)); + if (mode != MRDTX) + { + lsp_avg_reset(&(state->lsp_avg_st), state->common_amr_tbls.mean_lsf_5_ptr); + } + D_plsf_reset(&(state->lsfState), state->common_amr_tbls.mean_lsf_5_ptr); + ec_gain_pitch_reset(&(state->ec_gain_p_st)); + ec_gain_code_reset(&(state->ec_gain_c_st)); + + if (mode != MRDTX) + { + gc_pred_reset(&(state->pred_state)); + } + + Bgn_scd_reset(&(state->background_state)); + state->nodataSeed = 21845; + ph_disp_reset(&(state->ph_disp_st)); + if (mode != MRDTX) + { + dtx_dec_reset(&(state->dtxDecoderState)); + } + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Decoder_amr +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type Decoder_amrState + mode = codec mode (enum Mode) + parm = buffer of synthesis parameters (Word16) + frame_type = received frame type (enum RXFrameType) + synth = buffer containing synthetic speech (Word16) + A_t = buffer containing decoded LP filter in 4 subframes (Word16) + + Outputs: + structure pointed to by st contains the newly calculated decoder + parameters + synth buffer contains the decoded speech samples + A_t buffer contains the decoded LP filter parameters + + Returns: + return_value = 0 (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the decoding of one speech frame for a given codec + mode. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dec_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Decoder_amr ( + Decoder_amrState *st, // i/o : State variables + enum Mode mode, // i : AMR mode + Word16 parm[], // i : vector of synthesis parameters + (PRM_SIZE) + enum RXFrameType frame_type, // i : received frame type + Word16 synth[], // o : synthesis speech (L_FRAME) + Word16 A_t[] // o : decoded LP filter in 4 subframes + (AZ_SIZE) +) +{ + // LPC coefficients + + Word16 *Az; // Pointer on A_t + + // LSPs + + Word16 lsp_new[M]; + Word16 lsp_mid[M]; + + // LSFs + + Word16 prev_lsf[M]; + Word16 lsf_i[M]; + + // Algebraic codevector + + Word16 code[L_SUBFR]; + + // excitation + + Word16 excp[L_SUBFR]; + Word16 exc_enhanced[L_SUBFR]; + + // Scalars + + Word16 i, i_subfr; + Word16 T0, T0_frac, index, index_mr475 = 0; + Word16 gain_pit, gain_code, gain_code_mix, pit_sharp, pit_flag, pitch_fac; + Word16 t0_min, t0_max; + Word16 delta_frc_low, delta_frc_range; + Word16 tmp_shift; + Word16 temp; + Word32 L_temp; + Word16 flag4; + Word16 carefulFlag; + Word16 excEnergy; + Word16 subfrNr; + Word16 evenSubfr = 0; + + Word16 bfi = 0; // bad frame indication flag + Word16 pdfi = 0; // potential degraded bad frame flag + + enum DTXStateType newDTXState; // SPEECH , DTX, DTX_MUTE + + // find the new DTX state SPEECH OR DTX + newDTXState = rx_dtx_handler(st->dtxDecoderState, frame_type); + + // DTX actions + if (sub(newDTXState, SPEECH) != 0 ) + { + Decoder_amr_reset (st, MRDTX); + + dtx_dec(st->dtxDecoderState, + st->mem_syn, + st->lsfState, + st->pred_state, + st->Cb_gain_averState, + newDTXState, + mode, + parm, synth, A_t); + // update average lsp + + Lsf_lsp(st->lsfState->past_lsf_q, st->lsp_old, M); + lsp_avg(st->lsp_avg_st, st->lsfState->past_lsf_q); + goto the_end; + } + + // SPEECH action state machine + if ((sub(frame_type, RX_SPEECH_BAD) == 0) || + (sub(frame_type, RX_NO_DATA) == 0) || + (sub(frame_type, RX_ONSET) == 0)) + { + bfi = 1; + if ((sub(frame_type, RX_NO_DATA) == 0) || + (sub(frame_type, RX_ONSET) == 0)) + { + build_CN_param(&st->nodataSeed, + prmno[mode], + bitno[mode], + parm); + } + } + else if (sub(frame_type, RX_SPEECH_DEGRADED) == 0) + { + pdfi = 1; + } + + if (bfi != 0) + { + st->state = add (st->state, 1); + } + else if (sub (st->state, 6) == 0) + + { + st->state = 5; + } + else + { + st->state = 0; + } + + if (sub (st->state, 6) > 0) + { + st->state = 6; + } + + // If this frame is the first speech frame after CNI period, + // set the BFH state machine to an appropriate state depending + // on whether there was DTX muting before start of speech or not + // If there was DTX muting, the first speech frame is muted. + // If there was no DTX muting, the first speech frame is not + // muted. The BFH state machine starts from state 5, however, to + // keep the audible noise resulting from a SID frame which is + // erroneously interpreted as a good speech frame as small as + // possible (the decoder output in this case is quickly muted) + + if (sub(st->dtxDecoderState->dtxGlobalState, DTX) == 0) + { + st->state = 5; + st->prev_bf = 0; + } + else if (sub(st->dtxDecoderState->dtxGlobalState, DTX_MUTE) == 0) + { + st->state = 5; + st->prev_bf = 1; + } + + // save old LSFs for CB gain smoothing + Copy (st->lsfState->past_lsf_q, prev_lsf, M); + + // decode LSF parameters and generate interpolated lpc coefficients + for the 4 subframes + if (sub (mode, MR122) != 0) + { + D_plsf_3(st->lsfState, mode, bfi, parm, lsp_new); + + // Advance synthesis parameters pointer + parm += 3; + + Int_lpc_1to3(st->lsp_old, lsp_new, A_t); + } + else + { + D_plsf_5 (st->lsfState, bfi, parm, lsp_mid, lsp_new); + + // Advance synthesis parameters pointer + parm += 5; + + Int_lpc_1and3 (st->lsp_old, lsp_mid, lsp_new, A_t); + } + + // update the LSPs for the next frame + for (i = 0; i < M; i++) + { + st->lsp_old[i] = lsp_new[i]; + } + + *------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * + * times * + * - decode the pitch delay * + * - decode algebraic code * + * - decode pitch and codebook gains * + * - find the excitation and compute synthesis speech * + *------------------------------------------------------------------------* + + // pointer to interpolated LPC parameters + Az = A_t; + + evenSubfr = 0; + subfrNr = -1; + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + subfrNr = add(subfrNr, 1); + evenSubfr = sub(1, evenSubfr); + + // flag for first and 3th subframe + pit_flag = i_subfr; + + if (sub (i_subfr, L_FRAME_BY2) == 0) + { + if (sub(mode, MR475) != 0 && sub(mode, MR515) != 0) + { + pit_flag = 0; + } + } + + // pitch index + index = *parm++; + + *-------------------------------------------------------* + * - decode pitch lag and find adaptive codebook vector. * + *-------------------------------------------------------* + + if (sub(mode, MR122) != 0) + { + // flag4 indicates encoding with 4 bit resolution; + // this is needed for mode MR475, MR515, MR59 and MR67 + + flag4 = 0; + if ((sub (mode, MR475) == 0) || + (sub (mode, MR515) == 0) || + (sub (mode, MR59) == 0) || + (sub (mode, MR67) == 0) ) { + flag4 = 1; + } + + *-------------------------------------------------------* + * - get ranges for the t0_min and t0_max * + * - only needed in delta decoding * + *-------------------------------------------------------* + + delta_frc_low = 5; + delta_frc_range = 9; + + if ( sub(mode, MR795) == 0 ) + { + delta_frc_low = 10; + delta_frc_range = 19; + } + + t0_min = sub(st->old_T0, delta_frc_low); + if (sub(t0_min, PIT_MIN) < 0) + { + t0_min = PIT_MIN; + } + t0_max = add(t0_min, delta_frc_range); + if (sub(t0_max, PIT_MAX) > 0) + { + t0_max = PIT_MAX; + t0_min = sub(t0_max, delta_frc_range); + } + + Dec_lag3 (index, t0_min, t0_max, pit_flag, st->old_T0, + &T0, &T0_frac, flag4); + + st->T0_lagBuff = T0; + + if (bfi != 0) + { + if (sub (st->old_T0, PIT_MAX) < 0) + { // Graceful pitch + st->old_T0 = add(st->old_T0, 1); // degradation + } + T0 = st->old_T0; + T0_frac = 0; + + if ( st->inBackgroundNoise != 0 && + sub(st->voicedHangover, 4) > 0 && + ((sub(mode, MR475) == 0 ) || + (sub(mode, MR515) == 0 ) || + (sub(mode, MR59) == 0) ) + ) + { + T0 = st->T0_lagBuff; + } + } + + Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 1); + } + else + { + Dec_lag6 (index, PIT_MIN_MR122, + PIT_MAX, pit_flag, &T0, &T0_frac); + + if ( bfi == 0 && (pit_flag == 0 || sub (index, 61) < 0)) + { + } + else + { + st->T0_lagBuff = T0; + T0 = st->old_T0; + T0_frac = 0; + } + + Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 0); + } + + *-------------------------------------------------------* + * - (MR122 only: Decode pitch gain.) * + * - Decode innovative codebook. * + * - set pitch sharpening factor * + *-------------------------------------------------------* + + if (sub (mode, MR475) == 0 || sub (mode, MR515) == 0) + { // MR475, MR515 + index = *parm++; // index of position + i = *parm++; // signs + + decode_2i40_9bits (subfrNr, i, index, code); + + pit_sharp = shl (st->sharp, 1); + } + else if (sub (mode, MR59) == 0) + { // MR59 + index = *parm++; // index of position + i = *parm++; // signs + + decode_2i40_11bits (i, index, code); + + pit_sharp = shl (st->sharp, 1); + } + else if (sub (mode, MR67) == 0) + { // MR67 + index = *parm++; // index of position + i = *parm++; // signs + + decode_3i40_14bits (i, index, code); + + pit_sharp = shl (st->sharp, 1); + } + else if (sub (mode, MR795) <= 0) + { // MR74, MR795 + index = *parm++; // index of position + i = *parm++; // signs + + decode_4i40_17bits (i, index, code); + + pit_sharp = shl (st->sharp, 1); + } + else if (sub (mode, MR102) == 0) + { // MR102 + dec_8i40_31bits (parm, code); + parm += 7; + + pit_sharp = shl (st->sharp, 1); + } + else + { // MR122 + index = *parm++; + if (bfi != 0) + { + ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); + } + else + { + gain_pit = d_gain_pitch (mode, index); + } + ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, + &gain_pit); + + dec_10i40_35bits (parm, code); + parm += 10; + + // pit_sharp = gain_pit; + // if (pit_sharp > 1.0) pit_sharp = 1.0; + + pit_sharp = shl (gain_pit, 1); + } + + *-------------------------------------------------------* + * - Add the pitch contribution to code[]. * + *-------------------------------------------------------* + for (i = T0; i < L_SUBFR; i++) + { + temp = mult (code[i - T0], pit_sharp); + code[i] = add (code[i], temp); + } + + *------------------------------------------------------------* + * - Decode codebook gain (MR122) or both pitch * + * gain and codebook gain (all others) * + * - Update pitch sharpening "sharp" with quantized gain_pit * + *------------------------------------------------------------* + + if (sub (mode, MR475) == 0) + { + // read and decode pitch and code gain + if (evenSubfr != 0) + { + index_mr475 = *parm++; // index of gain(s) + } + + if (bfi == 0) + { + Dec_gain(st->pred_state, mode, index_mr475, code, + evenSubfr, &gain_pit, &gain_code); + } + else + { + ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); + ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, + &gain_code); + } + ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, + &gain_pit); + ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, + &gain_code); + + pit_sharp = gain_pit; + if (sub (pit_sharp, SHARPMAX) > 0) + { + pit_sharp = SHARPMAX; + } + + } + else if ((sub (mode, MR74) <= 0) || + (sub (mode, MR102) == 0)) + { + // read and decode pitch and code gain + index = *parm++; // index of gain(s) + + if (bfi == 0) + { + Dec_gain(st->pred_state, mode, index, code, + evenSubfr, &gain_pit, &gain_code); + } + else + { + ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); + ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, + &gain_code); + } + ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, + &gain_pit); + ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, + &gain_code); + + pit_sharp = gain_pit; + if (sub (pit_sharp, SHARPMAX) > 0) + { + pit_sharp = SHARPMAX; + } + + if (sub (mode, MR102) == 0) + { + if (sub (st->old_T0, add(L_SUBFR, 5)) > 0) + { + pit_sharp = shr(pit_sharp, 2); + } + } + } + else + { + // read and decode pitch gain + index = *parm++; // index of gain(s) + + if (sub (mode, MR795) == 0) + { + // decode pitch gain + if (bfi != 0) + { + ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); + } + else + { + gain_pit = d_gain_pitch (mode, index); + } + ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, + &gain_pit); + + // read and decode code gain + index = *parm++; + if (bfi == 0) + { + d_gain_code (st->pred_state, mode, index, code, &gain_code); + } + else + { + ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, + &gain_code); + } + ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, + &gain_code); + + pit_sharp = gain_pit; + if (sub (pit_sharp, SHARPMAX) > 0) + { + pit_sharp = SHARPMAX; + } + } + else + { // MR122 + if (bfi == 0) + { + d_gain_code (st->pred_state, mode, index, code, &gain_code); + } + else + { + ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, + &gain_code); + } + ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, + &gain_code); + + pit_sharp = gain_pit; + } + } + + // store pitch sharpening for next subframe + // (for modes which use the previous pitch gain for + // pitch sharpening in the search phase) + // do not update sharpening in even subframes for MR475 + if (sub(mode, MR475) != 0 || evenSubfr == 0) + { + st->sharp = gain_pit; + if (sub (st->sharp, SHARPMAX) > 0) + { + st->sharp = SHARPMAX; + } + } + + pit_sharp = shl (pit_sharp, 1); + if (sub (pit_sharp, 16384) > 0) + { + for (i = 0; i < L_SUBFR; i++) + { + temp = mult (st->exc[i], pit_sharp); + L_temp = L_mult (temp, gain_pit); + if (sub(mode, MR122)==0) + { + L_temp = L_shr (L_temp, 1); + } + excp[i] = pv_round (L_temp); + } + } + + *-------------------------------------------------------* + * - Store list of LTP gains needed in the source * + * characteristic detector (SCD) * + *-------------------------------------------------------* + if ( bfi == 0 ) + { + for (i = 0; i < 8; i++) + { + st->ltpGainHistory[i] = st->ltpGainHistory[i+1]; + } + st->ltpGainHistory[8] = gain_pit; + } + + *-------------------------------------------------------* + * - Limit gain_pit if in background noise and BFI * + * for MR475, MR515, MR59 * + *-------------------------------------------------------* + + if ( (st->prev_bf != 0 || bfi != 0) && st->inBackgroundNoise != 0 && + ((sub(mode, MR475) == 0) || + (sub(mode, MR515) == 0) || + (sub(mode, MR59) == 0)) + ) + { + if ( sub (gain_pit, 12288) > 0) // if (gain_pit > 0.75) in Q14 + gain_pit = add( shr( sub(gain_pit, 12288), 1 ), 12288 ); + // gain_pit = (gain_pit-0.75)/2.0 + 0.75; + + if ( sub (gain_pit, 14745) > 0) // if (gain_pit > 0.90) in Q14 + { + gain_pit = 14745; + } + } + + *-------------------------------------------------------* + * Calculate CB mixed gain * + *-------------------------------------------------------* + Int_lsf(prev_lsf, st->lsfState->past_lsf_q, i_subfr, lsf_i); + gain_code_mix = Cb_gain_average( + st->Cb_gain_averState, mode, gain_code, + lsf_i, st->lsp_avg_st->lsp_meanSave, bfi, + st->prev_bf, pdfi, st->prev_pdf, + st->inBackgroundNoise, st->voicedHangover); + + // make sure that MR74, MR795, MR122 have original code_gain + if ((sub(mode, MR67) > 0) && (sub(mode, MR102) != 0) ) + // MR74, MR795, MR122 + { + gain_code_mix = gain_code; + } + + *-------------------------------------------------------* + * - Find the total excitation. * + * - Find synthesis speech corresponding to st->exc[]. * + *-------------------------------------------------------* + if (sub(mode, MR102) <= 0) // MR475, MR515, MR59, MR67, MR74, MR795, MR102 + { + pitch_fac = gain_pit; + tmp_shift = 1; + } + else // MR122 + { + pitch_fac = shr (gain_pit, 1); + tmp_shift = 2; + } + + // copy unscaled LTP excitation to exc_enhanced (used in phase + * dispersion below) and compute total excitation for LTP feedback + + for (i = 0; i < L_SUBFR; i++) + { + exc_enhanced[i] = st->exc[i]; + + // st->exc[i] = gain_pit*st->exc[i] + gain_code*code[i]; + L_temp = L_mult (st->exc[i], pitch_fac); + // 12.2: Q0 * Q13 + // 7.4: Q0 * Q14 + L_temp = L_mac (L_temp, code[i], gain_code); + // 12.2: Q12 * Q1 + // 7.4: Q13 * Q1 + L_temp = L_shl (L_temp, tmp_shift); // Q16 + st->exc[i] = pv_round (L_temp); + } + + *-------------------------------------------------------* + * - Adaptive phase dispersion * + *-------------------------------------------------------* + ph_disp_release(st->ph_disp_st); // free phase dispersion adaption + + if ( ((sub(mode, MR475) == 0) || + (sub(mode, MR515) == 0) || + (sub(mode, MR59) == 0)) && + sub(st->voicedHangover, 3) > 0 && + st->inBackgroundNoise != 0 && + bfi != 0 ) + { + ph_disp_lock(st->ph_disp_st); // Always Use full Phase Disp. + } // if error in bg noise + + // apply phase dispersion to innovation (if enabled) and + compute total excitation for synthesis part + ph_disp(st->ph_disp_st, mode, + exc_enhanced, gain_code_mix, gain_pit, code, + pitch_fac, tmp_shift); + + *-------------------------------------------------------* + * - The Excitation control module are active during BFI.* + * - Conceal drops in signal energy if in bg noise. * + *-------------------------------------------------------* + + L_temp = 0; + for (i = 0; i < L_SUBFR; i++) + { + L_temp = L_mac (L_temp, exc_enhanced[i], exc_enhanced[i] ); + } + + L_temp = L_shr (L_temp, 1); // excEnergy = sqrt(L_temp) in Q0 + L_temp = sqrt_l_exp(L_temp, &temp); // function result + L_temp = L_shr(L_temp, add( shr(temp, 1), 15)); + L_temp = L_shr(L_temp, 2); // To cope with 16-bit and + excEnergy = extract_l(L_temp); // scaling in ex_ctrl() + + if ( ((sub (mode, MR475) == 0) || + (sub (mode, MR515) == 0) || + (sub (mode, MR59) == 0)) && + sub(st->voicedHangover, 5) > 0 && + st->inBackgroundNoise != 0 && + sub(st->state, 4) < 0 && + ( (pdfi != 0 && st->prev_pdf != 0) || + bfi != 0 || + st->prev_bf != 0) ) + { + carefulFlag = 0; + if ( pdfi != 0 && bfi == 0 ) + { + carefulFlag = 1; + } + + Ex_ctrl(exc_enhanced, + excEnergy, + st->excEnergyHist, + st->voicedHangover, + st->prev_bf, + carefulFlag); + } + + if ( st->inBackgroundNoise != 0 && + ( bfi != 0 || st->prev_bf != 0 ) && + sub(st->state, 4) < 0 ) + { + ; // do nothing! + } + else + { + // Update energy history for all modes + for (i = 0; i < 8; i++) + { + st->excEnergyHist[i] = st->excEnergyHist[i+1]; + } + st->excEnergyHist[8] = excEnergy; + } + *-------------------------------------------------------* + * Excitation control module end. * + *-------------------------------------------------------* + + if (sub (pit_sharp, 16384) > 0) + { + for (i = 0; i < L_SUBFR; i++) + { + excp[i] = add (excp[i], exc_enhanced[i]); + } + agc2 (exc_enhanced, excp, L_SUBFR); + Overflow = 0; + Syn_filt (Az, excp, &synth[i_subfr], L_SUBFR, + st->mem_syn, 0); + } + else + { + Overflow = 0; + Syn_filt (Az, exc_enhanced, &synth[i_subfr], L_SUBFR, + st->mem_syn, 0); + } + + if (Overflow != 0) // Test for overflow + { + for (i = 0; i < PIT_MAX + L_INTERPOL + L_SUBFR; i++) + { + st->old_exc[i] = shr(st->old_exc[i], 2); + } + for (i = 0; i < L_SUBFR; i++) + { + exc_enhanced[i] = shr(exc_enhanced[i], 2); + } + Syn_filt(Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->mem_syn, 1); + } + else + { + Copy(&synth[i_subfr+L_SUBFR-M], st->mem_syn, M); + } + + *--------------------------------------------------* + * Update signal for next frame. * + * -> shift to the left by L_SUBFR st->exc[] * + *--------------------------------------------------* + + Copy (&st->old_exc[L_SUBFR], &st->old_exc[0], PIT_MAX + L_INTERPOL); + + // interpolated LPC parameters for next subframe + Az += MP1; + + // store T0 for next subframe + st->old_T0 = T0; + } + + *-------------------------------------------------------* + * Call the Source Characteristic Detector which updates * + * st->inBackgroundNoise and st->voicedHangover. * + *-------------------------------------------------------* + + st->inBackgroundNoise = Bgn_scd(st->background_state, + &(st->ltpGainHistory[0]), + &(synth[0]), + &(st->voicedHangover) ); + + dtx_dec_activity_update(st->dtxDecoderState, + st->lsfState->past_lsf_q, + synth); + + // store bfi for next subframe + st->prev_bf = bfi; + st->prev_pdf = pdfi; + + *--------------------------------------------------* + * Calculate the LSF averages on the eight * + * previous frames * + *--------------------------------------------------* + + lsp_avg(st->lsp_avg_st, st->lsfState->past_lsf_q); + +the_end: + st->dtxDecoderState->dtxGlobalState = newDTXState; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void Decoder_amr( + Decoder_amrState *st, /* i/o : State variables */ + enum Mode mode, /* i : AMR mode */ + Word16 parm[], /* i : vector of synthesis parameters + (PRM_SIZE) */ + enum RXFrameType frame_type, /* i : received frame type */ + Word16 synth[], /* o : synthesis speech (L_FRAME) */ + Word16 A_t[] /* o : decoded LP filter in 4 subframes + (AZ_SIZE) */ +) +{ + /* LPC coefficients */ + + Word16 *Az; /* Pointer on A_t */ + + /* LSPs */ + + Word16 lsp_new[M]; + Word16 lsp_mid[M]; + + /* LSFs */ + + Word16 prev_lsf[M]; + Word16 lsf_i[M]; + + /* Algebraic codevector */ + + Word16 code[L_SUBFR]; + + /* excitation */ + + Word16 excp[L_SUBFR]; + Word16 exc_enhanced[L_SUBFR]; + + /* Scalars */ + + Word16 i; + Word16 i_subfr; + Word16 T0; + Word16 T0_frac; + Word16 index; + Word16 index_mr475 = 0; + Word16 gain_pit; + Word16 gain_code; + Word16 gain_code_mix; + Word16 pit_sharp; + Word16 pit_flag; + Word16 pitch_fac; + Word16 t0_min; + Word16 t0_max; + Word16 delta_frc_low; + Word16 delta_frc_range; + Word16 tmp_shift; + Word16 temp; + Word32 L_temp; + Word16 flag4; + Word16 carefulFlag; + Word16 excEnergy; + Word16 subfrNr; + Word16 evenSubfr = 0; + + Word16 bfi = 0; /* bad frame indication flag */ + Word16 pdfi = 0; /* potential degraded bad frame flag */ + + enum DTXStateType newDTXState; /* SPEECH , DTX, DTX_MUTE */ + Flag *pOverflow = &(st->overflow); /* Overflow flag */ + + + /* find the new DTX state SPEECH OR DTX */ + newDTXState = rx_dtx_handler(&(st->dtxDecoderState), frame_type, pOverflow); + + /* DTX actions */ + + if (newDTXState != SPEECH) + { + Decoder_amr_reset(st, MRDTX); + + dtx_dec(&(st->dtxDecoderState), + st->mem_syn, + &(st->lsfState), + &(st->pred_state), + &(st->Cb_gain_averState), + newDTXState, + mode, + parm, &(st->common_amr_tbls), synth, A_t, pOverflow); + + /* update average lsp */ + Lsf_lsp( + st->lsfState.past_lsf_q, + st->lsp_old, + M, + pOverflow); + + lsp_avg( + &(st->lsp_avg_st), + st->lsfState.past_lsf_q, + pOverflow); + + goto the_end; + } + + /* SPEECH action state machine */ + if ((frame_type == RX_SPEECH_BAD) || (frame_type == RX_NO_DATA) || + (frame_type == RX_ONSET)) + { + bfi = 1; + + if ((frame_type == RX_NO_DATA) || (frame_type == RX_ONSET)) + { + build_CN_param(&st->nodataSeed, + st->common_amr_tbls.prmno_ptr[mode], + st->common_amr_tbls.bitno_ptr[mode], + parm, + st->common_amr_tbls.window_200_40_ptr, + pOverflow); + } + } + else if (frame_type == RX_SPEECH_DEGRADED) + { + pdfi = 1; + } + + if (bfi != 0) + { + st->state += 1; + } + else if (st->state == 6) + + { + st->state = 5; + } + else + { + st->state = 0; + } + + + if (st->state > 6) + { + st->state = 6; + } + + /* If this frame is the first speech frame after CNI period, */ + /* set the BFH state machine to an appropriate state depending */ + /* on whether there was DTX muting before start of speech or not */ + /* If there was DTX muting, the first speech frame is muted. */ + /* If there was no DTX muting, the first speech frame is not */ + /* muted. The BFH state machine starts from state 5, however, to */ + /* keep the audible noise resulting from a SID frame which is */ + /* erroneously interpreted as a good speech frame as small as */ + /* possible (the decoder output in this case is quickly muted) */ + + if (st->dtxDecoderState.dtxGlobalState == DTX) + { + st->state = 5; + st->prev_bf = 0; + } + else if (st->dtxDecoderState.dtxGlobalState == DTX_MUTE) + { + st->state = 5; + st->prev_bf = 1; + } + + /* save old LSFs for CB gain smoothing */ + oscl_memmove((void *)prev_lsf, st->lsfState.past_lsf_q, M*sizeof(*st->lsfState.past_lsf_q)); + + /* decode LSF parameters and generate interpolated lpc coefficients + for the 4 subframes */ + + if (mode != MR122) + { + D_plsf_3( + &(st->lsfState), + mode, + bfi, + parm, + &st->common_amr_tbls, + lsp_new, + pOverflow); + + /* Advance synthesis parameters pointer */ + parm += 3; + + Int_lpc_1to3( + st->lsp_old, + lsp_new, + A_t, + pOverflow); + } + else + { + D_plsf_5( + &(st->lsfState), + bfi, + parm, + &(st->common_amr_tbls), + lsp_mid, + lsp_new, + pOverflow); + + /* Advance synthesis parameters pointer */ + parm += 5; + + Int_lpc_1and3( + st->lsp_old, + lsp_mid, + lsp_new, + A_t, + pOverflow); + } + + /* update the LSPs for the next frame */ + for (i = 0; i < M; i++) + { + st->lsp_old[i] = lsp_new[i]; + } + + /*------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * + * times * + * - decode the pitch delay * + * - decode algebraic code * + * - decode pitch and codebook gains * + * - find the excitation and compute synthesis speech * + *------------------------------------------------------------------------*/ + + /* pointer to interpolated LPC parameters */ + Az = A_t; + + evenSubfr = 0; + subfrNr = -1; + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + subfrNr += 1; + evenSubfr = 1 - evenSubfr; + + /* flag for first and 3th subframe */ + pit_flag = i_subfr; + + + if (i_subfr == L_FRAME_BY2) + { + if ((mode != MR475) && (mode != MR515)) + { + pit_flag = 0; + } + } + + /* pitch index */ + index = *parm++; + + /*-------------------------------------------------------* + * - decode pitch lag and find adaptive codebook vector. * + *-------------------------------------------------------*/ + + if (mode != MR122) + { + /* flag4 indicates encoding with 4 bit resolution; */ + /* this is needed for mode MR475, MR515, MR59 and MR67 */ + + flag4 = 0; + + if ((mode == MR475) || (mode == MR515) || (mode == MR59) || + (mode == MR67)) + { + flag4 = 1; + } + + /*-------------------------------------------------------* + * - get ranges for the t0_min and t0_max * + * - only needed in delta decoding * + *-------------------------------------------------------*/ + + delta_frc_low = 5; + delta_frc_range = 9; + + if (mode == MR795) + { + delta_frc_low = 10; + delta_frc_range = 19; + } + + t0_min = st->old_T0 - delta_frc_low; + + if (t0_min < PIT_MIN) + { + t0_min = PIT_MIN; + } + t0_max = t0_min + delta_frc_range; + + if (t0_max > PIT_MAX) + { + t0_max = PIT_MAX; + t0_min = t0_max - delta_frc_range; + } + + Dec_lag3(index, t0_min, t0_max, pit_flag, st->old_T0, + &T0, &T0_frac, flag4, pOverflow); + + st->T0_lagBuff = T0; + + if (bfi != 0) + { + if (st->old_T0 < PIT_MAX) + { /* Graceful pitch */ + st->old_T0 += 1; /* degradation */ + } + T0 = st->old_T0; + T0_frac = 0; + + if ((st->inBackgroundNoise != 0) && (st->voicedHangover > 4) && + ((mode == MR475) || (mode == MR515) || (mode == MR59))) + { + T0 = st->T0_lagBuff; + } + } + + Pred_lt_3or6(st->exc, T0, T0_frac, L_SUBFR, 1, pOverflow); + } + else + { + Dec_lag6(index, PIT_MIN_MR122, + PIT_MAX, pit_flag, &T0, &T0_frac, pOverflow); + + + if (!(bfi == 0 && (pit_flag == 0 || index < 61))) + { + st->T0_lagBuff = T0; + T0 = st->old_T0; + T0_frac = 0; + } + + Pred_lt_3or6(st->exc, T0, T0_frac, L_SUBFR, 0, pOverflow); + } + + /*-------------------------------------------------------* + * - (MR122 only: Decode pitch gain.) * + * - Decode innovative codebook. * + * - set pitch sharpening factor * + *-------------------------------------------------------*/ + if ((mode == MR475) || (mode == MR515)) + { /* MR475, MR515 */ + index = *parm++; /* index of position */ + i = *parm++; /* signs */ + + decode_2i40_9bits(subfrNr, i, index, st->common_amr_tbls.startPos_ptr, code, pOverflow); + + L_temp = (Word32)st->sharp << 1; + if (L_temp != (Word32)((Word16) L_temp)) + { + pit_sharp = (st->sharp > 0) ? MAX_16 : MIN_16; + } + else + { + pit_sharp = (Word16) L_temp; + } + } + else if (mode == MR59) + { /* MR59 */ + index = *parm++; /* index of position */ + i = *parm++; /* signs */ + + decode_2i40_11bits(i, index, code); + + L_temp = (Word32)st->sharp << 1; + if (L_temp != (Word32)((Word16) L_temp)) + { + pit_sharp = (st->sharp > 0) ? MAX_16 : MIN_16; + } + else + { + pit_sharp = (Word16) L_temp; + } + } + else if (mode == MR67) + { /* MR67 */ + index = *parm++; /* index of position */ + i = *parm++; /* signs */ + + decode_3i40_14bits(i, index, code); + + L_temp = (Word32)st->sharp << 1; + if (L_temp != (Word32)((Word16) L_temp)) + { + pit_sharp = (st->sharp > 0) ? MAX_16 : MIN_16; + } + else + { + pit_sharp = (Word16) L_temp; + } + } + else if (mode <= MR795) + { /* MR74, MR795 */ + index = *parm++; /* index of position */ + i = *parm++; /* signs */ + + decode_4i40_17bits(i, index, st->common_amr_tbls.dgray_ptr, code); + + L_temp = (Word32)st->sharp << 1; + if (L_temp != (Word32)((Word16) L_temp)) + { + pit_sharp = (st->sharp > 0) ? MAX_16 : MIN_16; + } + else + { + pit_sharp = (Word16) L_temp; + } + } + else if (mode == MR102) + { /* MR102 */ + dec_8i40_31bits(parm, code, pOverflow); + parm += 7; + + L_temp = (Word32)st->sharp << 1; + if (L_temp != (Word32)((Word16) L_temp)) + { + pit_sharp = (st->sharp > 0) ? MAX_16 : MIN_16; + } + else + { + pit_sharp = (Word16) L_temp; + } + } + else + { /* MR122 */ + index = *parm++; + + if (bfi != 0) + { + ec_gain_pitch( + &(st->ec_gain_p_st), + st->state, + &gain_pit, + pOverflow); + } + else + { + gain_pit = d_gain_pitch(mode, index, st->common_amr_tbls.qua_gain_pitch_ptr); + } + ec_gain_pitch_update( + &(st->ec_gain_p_st), + bfi, + st->prev_bf, + &gain_pit, + pOverflow); + + + dec_10i40_35bits(parm, code, st->common_amr_tbls.dgray_ptr); + parm += 10; + + /* pit_sharp = gain_pit; */ + /* if (pit_sharp > 1.0) pit_sharp = 1.0; */ + + L_temp = (Word32)gain_pit << 1; + if (L_temp != (Word32)((Word16) L_temp)) + { + pit_sharp = (gain_pit > 0) ? MAX_16 : MIN_16; + } + else + { + pit_sharp = (Word16) L_temp; + } + } + /*-------------------------------------------------------* + * - Add the pitch contribution to code[]. * + *-------------------------------------------------------*/ + for (i = T0; i < L_SUBFR; i++) + { + temp = mult(*(code + i - T0), pit_sharp, pOverflow); + *(code + i) = add_16(*(code + i), temp, pOverflow); + + } + + /*------------------------------------------------------------* + * - Decode codebook gain (MR122) or both pitch * + * gain and codebook gain (all others) * + * - Update pitch sharpening "sharp" with quantized gain_pit * + *------------------------------------------------------------*/ + if (mode == MR475) + { + /* read and decode pitch and code gain */ + + if (evenSubfr != 0) + { + index_mr475 = *parm++; /* index of gain(s) */ + } + + if (bfi == 0) + { + Dec_gain( + &(st->pred_state), + mode, + index_mr475, + code, + evenSubfr, + &gain_pit, + &gain_code, + &(st->common_amr_tbls), + pOverflow); + } + else + { + ec_gain_pitch( + &(st->ec_gain_p_st), + st->state, + &gain_pit, + pOverflow); + + ec_gain_code( + &(st->ec_gain_c_st), + &(st->pred_state), + st->state, + &gain_code, + pOverflow); + } + ec_gain_pitch_update( + &st->ec_gain_p_st, + bfi, + st->prev_bf, + &gain_pit, + pOverflow); + + ec_gain_code_update( + &st->ec_gain_c_st, + bfi, + st->prev_bf, + &gain_code, + pOverflow); + + pit_sharp = gain_pit; + + if (pit_sharp > SHARPMAX) + { + pit_sharp = SHARPMAX; + } + + } + else if ((mode <= MR74) || (mode == MR102)) + { + /* read and decode pitch and code gain */ + index = *parm++; /* index of gain(s) */ + + if (bfi == 0) + { + Dec_gain( + &(st->pred_state), + mode, + index, + code, + evenSubfr, + &gain_pit, + &gain_code, + &(st->common_amr_tbls), + pOverflow); + } + else + { + ec_gain_pitch( + &(st->ec_gain_p_st), + st->state, + &gain_pit, + pOverflow); + + ec_gain_code( + &(st->ec_gain_c_st), + &(st->pred_state), + st->state, + &gain_code, + pOverflow); + } + + ec_gain_pitch_update( + &(st->ec_gain_p_st), + bfi, + st->prev_bf, + &gain_pit, + pOverflow); + + ec_gain_code_update( + &(st->ec_gain_c_st), + bfi, + st->prev_bf, + &gain_code, + pOverflow); + + pit_sharp = gain_pit; + + if (pit_sharp > SHARPMAX) + { + pit_sharp = SHARPMAX; + } + + if (mode == MR102) + { + if (st->old_T0 > (L_SUBFR + 5)) + { + if (pit_sharp < 0) + { + pit_sharp = ~((~pit_sharp) >> 2); + } + else + { + pit_sharp = pit_sharp >> 2; + } + } + } + } + else + { + /* read and decode pitch gain */ + index = *parm++; /* index of gain(s) */ + + if (mode == MR795) + { + /* decode pitch gain */ + if (bfi != 0) + { + ec_gain_pitch( + &(st->ec_gain_p_st), + st->state, + &gain_pit, + pOverflow); + } + else + { + gain_pit = d_gain_pitch(mode, index, st->common_amr_tbls.qua_gain_pitch_ptr); + } + ec_gain_pitch_update( + &(st->ec_gain_p_st), + bfi, + st->prev_bf, + &gain_pit, + pOverflow); + + /* read and decode code gain */ + index = *parm++; + + if (bfi == 0) + { + d_gain_code( + &(st->pred_state), + mode, + index, + code, + st->common_amr_tbls.qua_gain_code_ptr, + &gain_code, + pOverflow); + } + else + { + ec_gain_code( + &(st->ec_gain_c_st), + &(st->pred_state), + st->state, + &gain_code, + pOverflow); + } + + ec_gain_code_update( + &(st->ec_gain_c_st), + bfi, + st->prev_bf, + &gain_code, + pOverflow); + + pit_sharp = gain_pit; + + if (pit_sharp > SHARPMAX) + { + pit_sharp = SHARPMAX; + } + } + else + { /* MR122 */ + + if (bfi == 0) + { + d_gain_code( + &(st->pred_state), + mode, + index, + code, + st->common_amr_tbls.qua_gain_code_ptr, + &gain_code, + pOverflow); + } + else + { + ec_gain_code( + &(st->ec_gain_c_st), + &(st->pred_state), + st->state, + &gain_code, + pOverflow); + } + + ec_gain_code_update( + &(st->ec_gain_c_st), + bfi, + st->prev_bf, + &gain_code, + pOverflow); + + pit_sharp = gain_pit; + } + } + + /* store pitch sharpening for next subframe */ + /* (for modes which use the previous pitch gain for */ + /* pitch sharpening in the search phase) */ + /* do not update sharpening in even subframes for MR475 */ + if ((mode != MR475) || (evenSubfr == 0)) + { + st->sharp = gain_pit; + + if (st->sharp > SHARPMAX) + { + st->sharp = SHARPMAX; + } + } + + pit_sharp = shl(pit_sharp, 1, pOverflow); + + if (pit_sharp > 16384) + { + for (i = 0; i < L_SUBFR; i++) + { + temp = mult(st->exc[i], pit_sharp, pOverflow); + L_temp = L_mult(temp, gain_pit, pOverflow); + + if (mode == MR122) + { + if (L_temp < 0) + { + L_temp = ~((~L_temp) >> 1); + } + else + { + L_temp = L_temp >> 1; + } + } + *(excp + i) = pv_round(L_temp, pOverflow); + } + } + + /*-------------------------------------------------------* + * - Store list of LTP gains needed in the source * + * characteristic detector (SCD) * + *-------------------------------------------------------*/ + + if (bfi == 0) + { + for (i = 0; i < 8; i++) + { + st->ltpGainHistory[i] = st->ltpGainHistory[i+1]; + } + st->ltpGainHistory[8] = gain_pit; + } + + /*-------------------------------------------------------* + * - Limit gain_pit if in background noise and BFI * + * for MR475, MR515, MR59 * + *-------------------------------------------------------*/ + + + if ((st->prev_bf != 0 || bfi != 0) && st->inBackgroundNoise != 0 && + ((mode == MR475) || (mode == MR515) || (mode == MR59))) + { + + if (gain_pit > 12288) /* if (gain_pit > 0.75) in Q14*/ + { + gain_pit = ((gain_pit - 12288) >> 1) + 12288; + /* gain_pit = (gain_pit-0.75)/2.0 + 0.75; */ + } + + if (gain_pit > 14745) /* if (gain_pit > 0.90) in Q14*/ + { + gain_pit = 14745; + } + } + + /*-------------------------------------------------------* + * Calculate CB mixed gain * + *-------------------------------------------------------*/ + Int_lsf( + prev_lsf, + st->lsfState.past_lsf_q, + i_subfr, + lsf_i, + pOverflow); + + gain_code_mix = + Cb_gain_average( + &(st->Cb_gain_averState), + mode, + gain_code, + lsf_i, + st->lsp_avg_st.lsp_meanSave, + bfi, + st->prev_bf, + pdfi, + st->prev_pdf, + st->inBackgroundNoise, + st->voicedHangover, + pOverflow); + + /* make sure that MR74, MR795, MR122 have original code_gain*/ + if ((mode > MR67) && (mode != MR102)) + /* MR74, MR795, MR122 */ + { + gain_code_mix = gain_code; + } + + /*-------------------------------------------------------* + * - Find the total excitation. * + * - Find synthesis speech corresponding to st->exc[]. * + *-------------------------------------------------------*/ + if (mode <= MR102) /* MR475, MR515, MR59, MR67, MR74, MR795, MR102*/ + { + pitch_fac = gain_pit; + tmp_shift = 1; + } + else /* MR122 */ + { + if (gain_pit < 0) + { + pitch_fac = ~((~gain_pit) >> 1); + } + else + { + pitch_fac = gain_pit >> 1; + } + tmp_shift = 2; + } + + /* copy unscaled LTP excitation to exc_enhanced (used in phase + * dispersion below) and compute total excitation for LTP feedback + */ + for (i = 0; i < L_SUBFR; i++) + { + exc_enhanced[i] = st->exc[i]; + + /* st->exc[i] = gain_pit*st->exc[i] + gain_code*code[i]; */ + L_temp = L_mult(st->exc[i], pitch_fac, pOverflow); + /* 12.2: Q0 * Q13 */ + /* 7.4: Q0 * Q14 */ + L_temp = L_mac(L_temp, code[i], gain_code, pOverflow); + /* 12.2: Q12 * Q1 */ + /* 7.4: Q13 * Q1 */ + L_temp = L_shl(L_temp, tmp_shift, pOverflow); /* Q16 */ + st->exc[i] = pv_round(L_temp, pOverflow); + } + + /*-------------------------------------------------------* + * - Adaptive phase dispersion * + *-------------------------------------------------------*/ + ph_disp_release(&(st->ph_disp_st)); /* free phase dispersion adaption */ + + + if (((mode == MR475) || (mode == MR515) || (mode == MR59)) && + (st->voicedHangover > 3) && (st->inBackgroundNoise != 0) && + (bfi != 0)) + { + ph_disp_lock(&(st->ph_disp_st)); /* Always Use full Phase Disp. */ + } /* if error in bg noise */ + + /* apply phase dispersion to innovation (if enabled) and + compute total excitation for synthesis part */ + ph_disp( + &(st->ph_disp_st), + mode, + exc_enhanced, + gain_code_mix, + gain_pit, + code, + pitch_fac, + tmp_shift, + &(st->common_amr_tbls), + pOverflow); + + /*-------------------------------------------------------* + * - The Excitation control module are active during BFI.* + * - Conceal drops in signal energy if in bg noise. * + *-------------------------------------------------------*/ + L_temp = 0; + for (i = 0; i < L_SUBFR; i++) + { + L_temp = L_mac(L_temp, *(exc_enhanced + i), *(exc_enhanced + i), pOverflow); + } + + /* excEnergy = sqrt(L_temp) in Q0 */ + if (L_temp < 0) + { + L_temp = ~((~L_temp) >> 1); + } + else + { + L_temp = L_temp >> 1; + } + + L_temp = sqrt_l_exp(L_temp, &temp, pOverflow); + /* To cope with 16-bit and scaling in ex_ctrl() */ + L_temp = L_shr(L_temp, (Word16)((temp >> 1) + 15), pOverflow); + if (L_temp < 0) + { + excEnergy = (Word16)(~((~L_temp) >> 2)); + } + else + { + excEnergy = (Word16)(L_temp >> 2); + } + + if (((mode == MR475) || (mode == MR515) || (mode == MR59)) && + (st->voicedHangover > 5) && (st->inBackgroundNoise != 0) && + (st->state < 4) && + ((pdfi != 0 && st->prev_pdf != 0) || bfi != 0 || st->prev_bf != 0)) + { + carefulFlag = 0; + + if (pdfi != 0 && bfi == 0) + { + carefulFlag = 1; + } + + Ex_ctrl(exc_enhanced, + excEnergy, + st->excEnergyHist, + st->voicedHangover, + st->prev_bf, + carefulFlag, pOverflow); + } + + if (!((st->inBackgroundNoise != 0) && (bfi != 0 || st->prev_bf != 0) && + (st->state < 4))) + { + /* Update energy history for all modes */ + for (i = 0; i < 8; i++) + { + st->excEnergyHist[i] = st->excEnergyHist[i+1]; + } + st->excEnergyHist[8] = excEnergy; + } + /*-------------------------------------------------------* + * Excitation control module end. * + *-------------------------------------------------------*/ + if (pit_sharp > 16384) + { + for (i = 0; i < L_SUBFR; i++) + { + *(excp + i) = add_16(*(excp + i), *(exc_enhanced + i), pOverflow); + + } + agc2(exc_enhanced, excp, L_SUBFR, pOverflow); + *pOverflow = 0; + Syn_filt(Az, excp, &synth[i_subfr], L_SUBFR, + st->mem_syn, 0); + } + else + { + *pOverflow = 0; + Syn_filt(Az, exc_enhanced, &synth[i_subfr], L_SUBFR, + st->mem_syn, 0); + } + + if (*pOverflow != 0) /* Test for overflow */ + { + for (i = PIT_MAX + L_INTERPOL + L_SUBFR - 1; i >= 0; i--) + { + if (st->old_exc[i] < 0) + { + st->old_exc[i] = ~((~st->old_exc[i]) >> 2); + } + else + { + st->old_exc[i] = st->old_exc[i] >> 2; + } + + } + + for (i = L_SUBFR - 1; i >= 0; i--) + { + if (*(exc_enhanced + i) < 0) + { + *(exc_enhanced + i) = ~((~(*(exc_enhanced + i))) >> 2); + } + else + { + *(exc_enhanced + i) = *(exc_enhanced + i) >> 2; + } + } + Syn_filt(Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->mem_syn, 1); + } + else + { + oscl_memmove((void *)st->mem_syn, &synth[i_subfr+L_SUBFR-M], M*sizeof(synth[0])); + } + + /*--------------------------------------------------* + * Update signal for next frame. * + * -> shift to the left by L_SUBFR st->exc[] * + *--------------------------------------------------*/ + + oscl_memmove((void *)&st->old_exc[0], &st->old_exc[L_SUBFR], (PIT_MAX + L_INTERPOL)*sizeof(st->old_exc[0])); + + /* interpolated LPC parameters for next subframe */ + Az += MP1; + + /* store T0 for next subframe */ + st->old_T0 = T0; + } + + /*-------------------------------------------------------* + * Call the Source Characteristic Detector which updates * + * st->inBackgroundNoise and st->voicedHangover. * + *-------------------------------------------------------*/ + + st->inBackgroundNoise = + Bgn_scd( + &(st->background_state), + &(st->ltpGainHistory[0]), + &(synth[0]), + &(st->voicedHangover), + pOverflow); + + dtx_dec_activity_update( + &(st->dtxDecoderState), + st->lsfState.past_lsf_q, + synth, + pOverflow); + + /* store bfi for next subframe */ + st->prev_bf = bfi; + st->prev_pdf = pdfi; + + /*--------------------------------------------------* + * Calculate the LSF averages on the eight * + * previous frames * + *--------------------------------------------------*/ + lsp_avg( + &(st->lsp_avg_st), + st->lsfState.past_lsf_q, + pOverflow); + +the_end: + st->dtxDecoderState.dtxGlobalState = newDTXState; + +// return(0); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_amr.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_amr.h new file mode 100644 index 00000000..3066ff78 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_amr.h @@ -0,0 +1,202 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dec_amr.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : dec_amr.h + Purpose : Speech decoder routine. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef DEC_AMR_H +#define DEC_AMR_H "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" +#include "mode.h" +#include "dtx_dec.h" +#include "d_plsf.h" +#include "gc_pred.h" +#include "ec_gains.h" +#include "ph_disp.h" +#include "c_g_aver.h" +#include "bgnscd.h" +#include "lsp_avg.h" +#include "frame.h" +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define EXC_ENERGY_HIST_LEN 9 +#define LTP_GAIN_HISTORY_LEN 9 + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + /* Excitation vector */ + Word16 old_exc[L_SUBFR + PIT_MAX + L_INTERPOL]; + Word16 *exc; + + /* Lsp (Line spectral pairs) */ + /* Word16 lsp[M]; */ /* Used by CN codec */ + Word16 lsp_old[M]; + + /* Filter's memory */ + Word16 mem_syn[M]; + + /* pitch sharpening */ + Word16 sharp; + Word16 old_T0; + + /* Memories for bad frame handling */ + Word16 prev_bf; + Word16 prev_pdf; + Word16 state; + Word16 excEnergyHist[EXC_ENERGY_HIST_LEN]; + + /* Variable holding received ltpLag, used in background noise and BFI */ + Word16 T0_lagBuff; + + /* Variables for the source characteristic detector (SCD) */ + Word16 inBackgroundNoise; + Word16 voicedHangover; + Word16 ltpGainHistory[LTP_GAIN_HISTORY_LEN]; + + Bgn_scdState background_state; + Word16 nodataSeed; + + Cb_gain_averageState Cb_gain_averState; + lsp_avgState lsp_avg_st; + + D_plsfState lsfState; + ec_gain_pitchState ec_gain_p_st; + ec_gain_codeState ec_gain_c_st; + gc_predState pred_state; + ph_dispState ph_disp_st; + dtx_decState dtxDecoderState; + Flag overflow; + CommonAmrTbls common_amr_tbls; + } Decoder_amrState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + /* + * Function : Decoder_amr_init + * Purpose : Allocates initializes state memory + * Description : Stores pointer to filter status struct in *st. This + * pointer has to be passed to Decoder_amr in each call. + * Returns : 0 on success + */ + Word16 Decoder_amr_init(Decoder_amrState *st); + + /* + * Function : Decoder_amr_reset + * Purpose : Resets state memory + * Returns : 0 on success + */ + Word16 Decoder_amr_reset(Decoder_amrState *st, enum Mode mode); + + /* + * Function : Decoder_amr_exit + * Purpose : The memory used for state memory is freed + * Description : Stores NULL in *s + * Returns : void + */ + void Decoder_amr_exit(Decoder_amrState **st); + + /* + * Function : Decoder_amr + * Purpose : Speech decoder routine. + * Returns : 0 + */ + void Decoder_amr( + Decoder_amrState *st, /* i/o : State variables */ + enum Mode mode, /* i : AMR mode */ + Word16 parm[], /* i : vector of synthesis parameters + (PRM_SIZE) */ + enum RXFrameType frame_type, /* i : received frame type */ + Word16 synth[], /* o : synthesis speech (L_FRAME) */ + Word16 A_t[] /* o : decoded LP filter in 4 subframes + (AZ_SIZE) */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* DEC_AMR_H_ */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_gain.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_gain.cpp new file mode 100644 index 00000000..7fd54c15 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_gain.cpp @@ -0,0 +1,265 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dec_gain.cpp + Functions: dec_gain + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "dec_gain.h" +#include "typedef.h" +#include "mode.h" +#include "cnst.h" +#include "pow2.h" +#include "log2.h" +#include "gc_pred.h" +#include "basic_op.h" +#include "qua_gain_tbl.h" +#include "qgain475_tab.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: dec_gain +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pred_state = pointer to MA predictor state of type gc_predState + index = AMR mode of type enum Mode + code[] = pointer to innovative vector of type Word16 + evenSubfr = Flag for even subframes of type Word16 + pOverflow = pointer to overflow flag + + + Outputs: + pred_state = pointer to MA predictor state of type gc_predState + gain_pit = pointer to pitch gain of type Word16 + gain_cod = pointer to code gain of type Word16 + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + File : dec_gain.c + Purpose : Decode the pitch and codebook gains + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + agc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + + + + + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + + +void Dec_gain( + gc_predState *pred_state, /* i/o: MA predictor state */ + enum Mode mode, /* i : AMR mode */ + Word16 index, /* i : index of quantization. */ + Word16 code[], /* i : Innovative vector. */ + Word16 evenSubfr, /* i : Flag for even subframes */ + Word16 * gain_pit, /* o : Pitch gain. */ + Word16 * gain_cod, /* o : Code gain. */ + CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of tbls ptrs */ + Flag * pOverflow +) +{ + const Word16 *p; + Word16 frac; + Word16 gcode0; + Word16 exp; + Word16 qua_ener; + Word16 qua_ener_MR122; + Word16 g_code; + Word32 L_tmp; + Word16 temp1; + Word16 temp2; + + /* Read the quantized gains (table depends on mode) */ + index = shl(index, 2, pOverflow); + + if (mode == MR102 || mode == MR74 || mode == MR67) + { + p = &(common_amr_tbls->table_gain_highrates_ptr[index]); + + *gain_pit = *p++; + g_code = *p++; + qua_ener_MR122 = *p++; + qua_ener = *p; + } + else + { + if (mode == MR475) + { + index += (1 ^ evenSubfr) << 1; /* evenSubfr is 0 or 1 */ + + if (index > (MR475_VQ_SIZE*4 - 2)) + { + index = (MR475_VQ_SIZE * 4 - 2); /* avoid possible buffer overflow */ + } + + p = &table_gain_MR475[index]; + + *gain_pit = *p++; + g_code = *p++; + + /*---------------------------------------------------------* + * calculate predictor update values (not stored in 4.75 * + * quantizer table to save space): * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * * + * qua_ener = log2(g) * + * qua_ener_MR122 = 20*log10(g) * + *---------------------------------------------------------*/ + + /* Log2(x Q12) = log2(x) + 12 */ + temp1 = g_code; + Log2(temp1, &exp, &frac, pOverflow); + exp -= 12; + + temp1 = shr_r(frac, 5, pOverflow); + temp2 = shl(exp, 10, pOverflow); + qua_ener_MR122 = add_16(temp1, temp2, pOverflow); + + /* 24660 Q12 ~= 6.0206 = 20*log10(2) */ + L_tmp = Mpy_32_16(exp, frac, 24660, pOverflow); + L_tmp = L_shl(L_tmp, 13, pOverflow); + qua_ener = pv_round(L_tmp, pOverflow); + /* Q12 * Q0 = Q13 -> Q10 */ + } + else + { + p = &(common_amr_tbls->table_gain_lowrates_ptr[index]); + + *gain_pit = *p++; + g_code = *p++; + qua_ener_MR122 = *p++; + qua_ener = *p; + } + } + + /*-------------------------------------------------------------------* + * predict codebook gain * + * ~~~~~~~~~~~~~~~~~~~~~ * + * gc0 = Pow2(int(d)+frac(d)) * + * = 2^exp + 2^frac * + * * + * gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp) * + *-------------------------------------------------------------------*/ + + gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL, pOverflow); + + gcode0 = (Word16) Pow2(14, frac, pOverflow); + + /*------------------------------------------------------------------* + * read quantized gains, update table of past quantized energies * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant * + * = Log2(g_fac) * + * = qua_ener * + * constant = 20*Log10(2) * + *------------------------------------------------------------------*/ + + L_tmp = L_mult(g_code, gcode0, pOverflow); + temp1 = 10 - exp; + L_tmp = L_shr(L_tmp, temp1, pOverflow); + *gain_cod = (Word16)(L_tmp >> 16); + + /* update table of past quantized energies */ + + gc_pred_update(pred_state, qua_ener_MR122, qua_ener); + + return; +} + + + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_gain.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_gain.h new file mode 100644 index 00000000..ceb6bba7 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_gain.h @@ -0,0 +1,120 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dec_gain.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : dec_gain.h + Purpose : Decode the pitch and codebook gains + +------------------------------------------------------------------------------ +*/ + +#ifndef _DEC_GAIN_H_ +#define _DEC_GAIN_H_ +#define dec_gain_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "gc_pred.h" +#include "mode.h" +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /* + * FUNCTION: Dec_gain() + * PURPOSE: Decode the pitch and codebook gains + */ + void Dec_gain( + gc_predState *pred_state, /* i/o: MA predictor state */ + enum Mode mode, /* i : AMR mode */ + Word16 index, /* i : index of quantization. */ + Word16 code[], /* i : Innovative vector. */ + Word16 evenSubfr, /* i : Flag for even subframes */ + Word16 * gain_pit, /* o : Pitch gain. */ + Word16 * gain_cod, /* o : Code gain. */ + CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of tbls ptrs */ + Flag * pOverflow + ); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _DEC_GAIN_H_ */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_input_format_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_input_format_tab.cpp new file mode 100644 index 00000000..867df28d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_input_format_tab.cpp @@ -0,0 +1,190 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + Filename: dec_input_format_tab.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This file contains the tables of the number of data bytes per codec mode in + both WMF and IF2 input formats. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] AMR Speech Codec Frame Structure, 3GPP TS 26.101 version 4.1.0 Release 4, + June 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "amrdecode.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; LOCAL STORE/BUFFER/POINTER DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + /* Table containing the number of core AMR data bytes for */ + /* each codec mode for WMF input format(number excludes frame type byte) */ + const Word16 WmfDecBytesPerFrame[16] = + { + 12, /* 4.75 */ + 13, /* 5.15 */ + 15, /* 5.90 */ + 17, /* 6.70 */ + 19, /* 7.40 */ + 20, /* 7.95 */ + 26, /* 10.2 */ + 31, /* 12.2 */ + 5, /* GsmAmr comfort noise */ + 6, /* Gsm-Efr comfort noise */ + 5, /* IS-641 comfort noise */ + 5, /* Pdc-Efr comfort noise */ + 0, /* future use */ + 0, /* future use */ + 0, /* future use */ + 0 /* No transmission */ + }; + + /* Table containing the number of core AMR data bytes for */ + /* each codec mode for IF2 input format. */ + const Word16 If2DecBytesPerFrame[16] = + { + 13, /* 4.75 */ + 14, /* 5.15 */ + 16, /* 5.90 */ + 18, /* 6.70 */ + 19, /* 7.40 */ + 21, /* 7.95 */ + 26, /* 10.2 */ + 31, /* 12.2 */ + 6, /* GsmAmr comfort noise */ + 6, /* Gsm-Efr comfort noise */ + 6, /* IS-641 comfort noise */ + 6, /* Pdc-Efr comfort noise */ + 0, /* future use */ + 0, /* future use */ + 0, /* future use */ + 1 /* No transmission */ + }; + + /*---------------------------------------------------------------------------- + ; EXTERNAL FUNCTION REFERENCES + ; Declare functions defined elsewhere and referenced in this module + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; Define all local variables +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Function body here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Return nothing or data or data pointer +----------------------------------------------------------------------------*/ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_lag3.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_lag3.cpp new file mode 100644 index 00000000..07d58adb --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_lag3.cpp @@ -0,0 +1,284 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dec_lag3.cpp + Functions: Dec_lag3 + + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + index -- Word16 -- received pitch index + t0_min -- Word16 -- minimum of search range + t0_max -- Word16 -- maximum of search range + i_subfr -- Word16 -- subframe flag + T0_prev -- Word16 -- integer pitch delay of last subframe + used in 2nd and 4th subframes + flag4 -- Word16 -- flag for encoding with 4 bits + + Outputs: + + T0 -- Pointer to type Word16 -- integer part of pitch lag + T0_frac -- Pointer to type Word16 -- fractional part of pitch lag + pOverflow -- Pointer to type Flag -- Flag set when overflow occurs + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + + + ) +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Decoding of fractional pitch lag with 1/3 resolution. + Extract the integer and fraction parts of the pitch lag from + the received adaptive codebook index. + + See "Enc_lag3.c" for more details about the encoding procedure. + + The fractional lag in 1st and 3rd subframes is encoded with 8 bits + while that in 2nd and 4th subframes is relatively encoded with 4, 5 + and 6 bits depending on the mode. + +------------------------------------------------------------------------------ + REQUIREMENTS + + + +------------------------------------------------------------------------------ + REFERENCES + + dec_lag3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "dec_lag3.h" +#include "typedef.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void Dec_lag3(Word16 index, /* i : received pitch index */ + Word16 t0_min, /* i : minimum of search range */ + Word16 t0_max, /* i : maximum of search range */ + Word16 i_subfr, /* i : subframe flag */ + Word16 T0_prev, /* i : integer pitch delay of last subframe + used in 2nd and 4th subframes */ + Word16 * T0, /* o : integer part of pitch lag */ + Word16 * T0_frac, /* o : fractional part of pitch lag */ + Word16 flag4, /* i : flag for encoding with 4 bits */ + Flag *pOverflow /* o : Flag set when overflow occurs */ + ) +{ + Word16 i; + Word16 tmp_lag; + + if (i_subfr == 0) /* if 1st or 3rd subframe */ + { + + if (index < 197) + { + + tmp_lag = index + 2; + + tmp_lag = + mult( + tmp_lag, + 10923, + pOverflow); + + i = tmp_lag + 19; + + *T0 = i; + + /* i = 3 * (*T0) */ + + i <<= 1; + i += *T0; + + tmp_lag = index - i; + + *T0_frac = tmp_lag + 58; + } + else + { + *T0 = index - 112; + + *T0_frac = 0; + } + + } + else + { /* 2nd or 4th subframe */ + + if (flag4 == 0) + { + + /* 'normal' decoding: either with 5 or 6 bit resolution */ + + i = index + 2; + + i = ((Word32) i * 10923) >> 15; + + + i -= 1; + + *T0 = i + t0_min; + + /* i = 3* (*T0) */ + i = i + (i << 1); + + tmp_lag = index - 2; + + *T0_frac = tmp_lag - i; + } + else + { + + /* decoding with 4 bit resolution */ + + tmp_lag = T0_prev; + + i = + sub( + tmp_lag, + t0_min, + pOverflow); + + if (i > 5) + { + tmp_lag = t0_min + 5; + } + + i = t0_max - tmp_lag; + + if (i > 4) + { + tmp_lag = t0_max - 4; + } + + if (index < 4) + { + i = tmp_lag - 5; + + *T0 = i + index; + + *T0_frac = 0; + } + else + { + /* 4 >= index < 12 */ + if (index < 12) + { + i = index - 5; + i = ((Word32) i * 10923) >> 15; + + + i--; + + *T0 = i + tmp_lag; + + i = i + (i << 1); + + tmp_lag = index - 9; + + *T0_frac = tmp_lag - i; + } + else + { + i = index - 12; + + i = i + tmp_lag; + + *T0 = i + 1; + + *T0_frac = 0; + } + } + + } /* end if (decoding with 4 bit resolution) */ + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_lag3.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_lag3.h new file mode 100644 index 00000000..c90e4598 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_lag3.h @@ -0,0 +1,115 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dec_lag3.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the dec_lag3.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef dec_lag3_h +#define dec_lag3_h "$Id $" + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void Dec_lag3(Word16 index, /* i : received pitch index */ + Word16 T0_min, /* i : minimum of search range */ + Word16 T0_max, /* i : maximum of search range */ + Word16 i_subfr, /* i : subframe flag */ + Word16 T0_prev, /* i : integer pitch delay of last subframe + used in 2nd and 4th subframes */ + Word16 * T0, /* o : integer part of pitch lag */ + Word16 * T0_frac, /* o : fractional part of pitch lag */ + Word16 flag4, /* i : flag for encoding with 4 bits */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _DEC_LAG_3_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_lag6.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_lag6.cpp new file mode 100644 index 00000000..8d580ad7 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_lag6.cpp @@ -0,0 +1,229 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dec_lag6.cpp + Functions: Dec_lag6 + + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + index -- Word16 -- received pitch index + pit_min -- Word16 -- minimum pitch lag + pit_max -- Word16 -- maximum pitch lag + i_subfr -- Word16 -- subframe flag + T0 -- Pointer to type Word16 -- integer part of pitch lag + + Outputs: + + T0 -- Pointer to type Word16 -- integer part of pitch lag + T0_frac -- Pointer to type Word16 -- fractional part of pitch lag + pOverflow -- Pointer to type Flag -- Flag set when overflow occurs + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Decoding of fractional pitch lag with 1/6 resolution. + Extract the integer and fraction parts of the pitch lag from + the received adaptive codebook index. + + See "Enc_lag6.c" for more details about the encoding procedure. + + The fractional lag in 1st and 3rd subframes is encoded with 9 bits + while that in 2nd and 4th subframes is relatively encoded with 6 bits. + Note that in relative encoding only 61 values are used. If the + decoder receives 61, 62, or 63 as the relative pitch index, it means + that a transmission error occurred. In this case, the pitch lag from + previous subframe (actually from previous frame) is used. + +------------------------------------------------------------------------------ + REQUIREMENTS + + + +------------------------------------------------------------------------------ + REFERENCES + + dec_lag6.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "dec_lag6.h" +#include "typedef.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void Dec_lag6( + Word16 index, /* input : received pitch index */ + Word16 pit_min, /* input : minimum pitch lag */ + Word16 pit_max, /* input : maximum pitch lag */ + Word16 i_subfr, /* input : subframe flag */ + Word16 *T0, /* in/out: integer part of pitch lag */ + Word16 *T0_frac, /* output: fractional part of pitch lag */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 T0_min; + Word16 T0_max; + Word16 k; + + if (i_subfr == 0) /* if 1st or 3rd subframe */ + { + if (index < 463) + { + /* T0 = (index+5)/6 + 17 */ + i = index + 5; + i = ((Word32) i * 5462) >> 15; + + + i += 17; + + *T0 = i; + + /* i = 3* (*T0) */ + + i <<= 1; + i += *T0; + + /* *T0_frac = index - T0*6 + 105 */ + + i <<= 1; + + i = index - i; + + *T0_frac = i + 105; + } + else + { + *T0 = index - 368; + + *T0_frac = 0; + } + } + else /* second or fourth subframe */ + { + /* find T0_min and T0_max for 2nd (or 4th) subframe */ + + T0_min = *T0 - 5; + + if (T0_min < pit_min) + { + T0_min = pit_min; + } + + T0_max = T0_min + 9; + + if (T0_max > pit_max) + { + T0_max = pit_max; + + T0_min = T0_max - 9; + } + + /* i = (index+5)/6 - 1 */ + i = index + 5; + + i = ((Word32) i * 5462) >> 15; + + + i -= 1; + + *T0 = i + T0_min; + + /* i = 3* (*T0) */ + + i = i + (i << 1); + + i <<= 1; + + k = index - 3; + + *T0_frac = k - i; + } +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_lag6.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_lag6.h new file mode 100644 index 00000000..5b0073d9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dec_lag6.h @@ -0,0 +1,113 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dec_lag6.h + + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the dec_lag6.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef dec_lag6_h +#define dec_lag6_h "$Id $" + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void Dec_lag6( + Word16 index, /* input : received pitch index */ + Word16 pit_min, /* input : minimum pitch lag */ + Word16 pit_max, /* input : maximum pitch lag */ + Word16 i_subfr, /* input : subframe flag */ + Word16 *T0, /* in/out: integer part of pitch lag */ + Word16 *T0_frac, /* output: fractional part of pitch lag */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _DEC_LAG_6_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/decoder_gsm_amr.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/decoder_gsm_amr.cpp new file mode 100644 index 00000000..8e330c56 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/decoder_gsm_amr.cpp @@ -0,0 +1,262 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +#include "decoder_gsm_amr.h" +#include "sp_dec.h" +#include "amrdecode.h" +#include "pvamrnbdecoder_api.h" + +// Use default DLL entry point +//#include "oscl_dll.h" +//#include "oscl_error_codes.h" +//#include "oscl_exception.h" +#include "oscl_mem.h" + +#define KCAI_CODEC_INIT_FAILURE -1 + +OSCL_DLL_ENTRY_POINT_DEFAULT() + +OSCL_EXPORT_REF CDecoder_AMR_NB *CDecoder_AMR_NB::NewL() +{ + CDecoder_AMR_NB *dec = new CDecoder_AMR_NB; + if (dec == NULL) + OSCL_LEAVE(OsclErrNoMemory); + else + dec->ConstructL(); + return dec; +} + +OSCL_EXPORT_REF void CDecoder_AMR_NB::ConstructL() +{ + iDecState = NULL; +} + + +/* +----------------------------------------------------------------------------- + + CDecoder_AMR_NB + + ~CDecoder_AMR_NB + + Empty decoder destructor. + + Parameters: none + + Return Values: none + +----------------------------------------------------------------------------- +*/ +OSCL_EXPORT_REF CDecoder_AMR_NB::~CDecoder_AMR_NB() +{ + if (iDecState) + oscl_free(iDecState); + iDecState = NULL; + + if (iInputBuf) + { + OSCL_ARRAY_DELETE(iInputBuf); + iInputBuf = NULL; + } + + if (iOutputBuf) + { + OSCL_ARRAY_DELETE(iOutputBuf); + iOutputBuf = NULL; + } +} + + +/* +----------------------------------------------------------------------------- + + CDecoder_AMR_NB + + StartL + + Start decoder object. Initialize codec status. + + Parameters: none + + Return Values: status + +----------------------------------------------------------------------------- +*/ +OSCL_EXPORT_REF int32 CDecoder_AMR_NB::StartL(tPVAmrDecoderExternal * pExt, + bool aAllocateInputBuffer, + bool aAllocateOutputBuffer) +{ + + if (aAllocateInputBuffer) + { + iInputBuf = OSCL_ARRAY_NEW(int16, MAX_NUM_PACKED_INPUT_BYTES); + if (iInputBuf == NULL) + { + return KCAI_CODEC_INIT_FAILURE; + } + } + else + { + iInputBuf = NULL; + } + pExt->pInputBuffer = (uint8 *)iInputBuf; + + if (aAllocateOutputBuffer) + { + iOutputBuf = OSCL_ARRAY_NEW(int16, L_FRAME); + + if (iOutputBuf == NULL) + { + return KCAI_CODEC_INIT_FAILURE; + } + } + else + { + iOutputBuf = NULL; + } + pExt->pOutputBuffer = iOutputBuf; + + pExt->samplingRate = 8000; + pExt->desiredChannels = 1; + + pExt->reset_flag = 0; + pExt->reset_flag_old = 1; + pExt->mode_old = 0; + + return GSMInitDecode(&iDecState, (int8*)"Decoder"); +} + + +/* +----------------------------------------------------------------------------- + + CDecoder_AMR_NB + + ExecuteL + + Execute decoder object. Read one encoded speech frame from the input + stream, decode it and write the decoded frame to output stream. + + Parameters: + + Return Values: status + + +----------------------------------------------------------------------------- +*/ + +OSCL_EXPORT_REF int32 CDecoder_AMR_NB::ExecuteL(tPVAmrDecoderExternal * pExt) +{ + + + if (pExt->input_format == WMF) + pExt->input_format = MIME_IETF; + + return AMRDecode(iDecState, + (enum Frame_Type_3GPP)pExt->mode, + (uint8*) pExt->pInputBuffer, + (int16*) pExt->pOutputBuffer, + pExt->input_format); + +} + +/* +----------------------------------------------------------------------------- + + CDecoder_AMR_NB + + StopL + + Stop decoder object. Flush out last frames, if necessary. + + Parameters: none + + Return Values: none + +----------------------------------------------------------------------------- +*/ +OSCL_EXPORT_REF void CDecoder_AMR_NB::StopL() +{ +} + +/* +----------------------------------------------------------------------------- + + CDecoder_AMR_NB + + ResetDecoderL + + Stop decoder object. Reset decoder. + + Parameters: none + + Return Values: status + +----------------------------------------------------------------------------- +*/ +OSCL_EXPORT_REF int32 CDecoder_AMR_NB::ResetDecoderL() +{ + return Speech_Decode_Frame_reset(iDecState); +} + + +/* +----------------------------------------------------------------------------- + + CDecoder_AMR_NB + + TerminateDecoderL + + Stop decoder object. close decoder. + + Parameters: none + + Return Values: none + +----------------------------------------------------------------------------- +*/ +OSCL_EXPORT_REF void CDecoder_AMR_NB::TerminateDecoderL() +{ + GSMDecodeFrameExit(&iDecState); + iDecState = NULL; + + if (iInputBuf) + { + OSCL_ARRAY_DELETE(iInputBuf); + iInputBuf = NULL; + } + + if (iOutputBuf) + { + OSCL_ARRAY_DELETE(iOutputBuf); + iOutputBuf = NULL; + } +} + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dtx_dec.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dtx_dec.cpp new file mode 100644 index 00000000..665a6ec1 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dtx_dec.cpp @@ -0,0 +1,1895 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dtx_dec.cpp + Functions: + dtx_dec_reset + dtx_dec + dtx_dec_activity_update + rx_dtx_handler + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + These modules decode the comfort noise when in DTX. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "dtx_dec.h" +#include "typedef.h" +#include "basic_op.h" +#include "set_zero.h" +#include "mode.h" +#include "log2.h" +#include "lsp_az.h" +#include "pow2.h" +#include "a_refl.h" +#include "b_cn_cod.h" +#include "syn_filt.h" +#include "lsp_lsf.h" +#include "reorder.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define PN_INITIAL_SEED 0x70816958L /* Pseudo noise generator seed value */ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*************************************************** + * Scaling factors for the lsp variability operation * + ***************************************************/ +static const Word16 lsf_hist_mean_scale[M] = +{ + 20000, + 20000, + 20000, + 20000, + 20000, + 18000, + 16384, + 8192, + 0, + 0 +}; + +/************************************************* + * level adjustment for different modes Q11 * + *************************************************/ +static const Word16 dtx_log_en_adjust[9] = +{ + -1023, /* MR475 */ + -878, /* MR515 */ + -732, /* MR59 */ + -586, /* MR67 */ + -440, /* MR74 */ + -294, /* MR795 */ + -148, /* MR102 */ + 0, /* MR122 */ + 0, /* MRDTX */ +}; + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: dtx_dec_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type dtx_decState + + Outputs: + Structure pointed to by st is initialized to a set of initial values. + + Returns: + return_value = 0 if memory was successfully initialized, + otherwise returns -1 (int) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Reset of state memory for dtx_dec. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + dtx_dec.c, UMTS GSM AMR speech codec, R99 - Version 3.3.0, December 12, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int dtx_dec_reset (dtx_decState *st) +{ + int i; + + if (st == (dtx_decState *) NULL){ + fprintf(stderr, "dtx_dec_reset: invalid parameter\n"); + return -1; + } + + st->since_last_sid = 0; + st->true_sid_period_inv = (1 << 13); + + st->log_en = 3500; + st->old_log_en = 3500; + // low level noise for better performance in DTX handover cases + + st->L_pn_seed_rx = PN_INITIAL_SEED; + + // Initialize state->lsp [] and state->lsp_old [] + Copy(lsp_init_data, &st->lsp[0], M); + Copy(lsp_init_data, &st->lsp_old[0], M); + + st->lsf_hist_ptr = 0; + st->log_pg_mean = 0; + st->log_en_hist_ptr = 0; + + // initialize decoder lsf history + Copy(mean_lsf, &st->lsf_hist[0], M); + + for (i = 1; i < DTX_HIST_SIZE; i++) + { + Copy(&st->lsf_hist[0], &st->lsf_hist[M*i], M); + } + Set_zero(st->lsf_hist_mean, M*DTX_HIST_SIZE); + + // initialize decoder log frame energy + for (i = 0; i < DTX_HIST_SIZE; i++) + { + st->log_en_hist[i] = st->log_en; + } + + st->log_en_adjust = 0; + + st->dtxHangoverCount = DTX_HANG_CONST; + st->decAnaElapsedCount = 32767; + + st->sid_frame = 0; + st->valid_data = 0; + st->dtxHangoverAdded = 0; + + st->dtxGlobalState = DTX; + st->data_updated = 0; + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 dtx_dec_reset(dtx_decState *st) +{ + Word16 i; + + if (st == (dtx_decState *) NULL) + { + /* fprint(stderr, "dtx_dec_reset: invalid parameter\n"); */ + return(-1); + } + + st->since_last_sid = 0; + st->true_sid_period_inv = (1 << 13); + + st->log_en = 3500; + st->old_log_en = 3500; + /* low level noise for better performance in DTX handover cases*/ + + st->L_pn_seed_rx = PN_INITIAL_SEED; + + /* Initialize state->lsp [] */ + st->lsp[0] = 30000; + st->lsp[1] = 26000; + st->lsp[2] = 21000; + st->lsp[3] = 15000; + st->lsp[4] = 8000; + st->lsp[5] = 0; + st->lsp[6] = -8000; + st->lsp[7] = -15000; + st->lsp[8] = -21000; + st->lsp[9] = -26000; + + /* Initialize state->lsp_old [] */ + st->lsp_old[0] = 30000; + st->lsp_old[1] = 26000; + st->lsp_old[2] = 21000; + st->lsp_old[3] = 15000; + st->lsp_old[4] = 8000; + st->lsp_old[5] = 0; + st->lsp_old[6] = -8000; + st->lsp_old[7] = -15000; + st->lsp_old[8] = -21000; + st->lsp_old[9] = -26000; + + st->lsf_hist_ptr = 0; + st->log_pg_mean = 0; + st->log_en_hist_ptr = 0; + + /* initialize decoder lsf history */ + st->lsf_hist[0] = 1384; + st->lsf_hist[1] = 2077; + st->lsf_hist[2] = 3420; + st->lsf_hist[3] = 5108; + st->lsf_hist[4] = 6742; + st->lsf_hist[5] = 8122; + st->lsf_hist[6] = 9863; + st->lsf_hist[7] = 11092; + st->lsf_hist[8] = 12714; + st->lsf_hist[9] = 13701; + + for (i = 1; i < DTX_HIST_SIZE; i++) + { + oscl_memmove((void *)&st->lsf_hist[M*i], &st->lsf_hist[0], M*sizeof(st->lsf_hist[0])); + } + oscl_memset(st->lsf_hist_mean, 0, sizeof(Word16)*M*DTX_HIST_SIZE); + + /* initialize decoder log frame energy */ + for (i = 0; i < DTX_HIST_SIZE; i++) + { + st->log_en_hist[i] = st->log_en; + } + + st->log_en_adjust = 0; + + st->dtxHangoverCount = DTX_HANG_CONST; + st->decAnaElapsedCount = 32767; + + st->sid_frame = 0; + st->valid_data = 0; + st->dtxHangoverAdded = 0; + + st->dtxGlobalState = DTX; + st->data_updated = 0; + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: dtx_dec +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type dtx_decState + mem_syn = AMR decoder state + lsfState = decoder lsf states + predState = prediction states + averState = CB gain average states + new_state = new DTX state + mode = AMR mode + parm = Vector of synthesis parameters + + Outputs: + st points to an updated structure of type dtx_decState + mem_syn = AMR decoder state + lsfState = decoder lsf states + predState = prediction states + averState = CB gain average states + synth = synthesised speech + A_t = decoded LP filter in 4 subframes + + Returns: + return_value = 0 (int) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Decode comfort noise when in DTX. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dtx_dec.c, UMTS GSM AMR speech codec, R99 - Version 3.3.0, December 12, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int dtx_dec( + dtx_decState *st, // i/o : State struct + Word16 mem_syn[], // i/o : AMR decoder state + D_plsfState* lsfState, // i/o : decoder lsf states + gc_predState* predState, // i/o : prediction states + Cb_gain_averageState* averState, // i/o : CB gain average states + enum DTXStateType new_state, // i : new DTX state + enum Mode mode, // i : AMR mode + Word16 parm[], // i : Vector of synthesis parameters + Word16 synth[], // o : synthesised speech + Word16 A_t[] // o : decoded LP filter in 4 subframes + ) +{ + Word16 log_en_index; + Word16 i, j; + Word16 int_fac; + Word32 L_log_en_int; + Word16 lsp_int[M]; + Word16 log_en_int_e; + Word16 log_en_int_m; + Word16 level; + Word16 acoeff[M + 1]; + Word16 refl[M]; + Word16 pred_err; + Word16 ex[L_SUBFR]; + Word16 ma_pred_init; + Word16 log_pg_e, log_pg_m; + Word16 log_pg; + Flag negative; + Word16 lsf_mean; + Word32 L_lsf_mean; + Word16 lsf_variab_index; + Word16 lsf_variab_factor; + Word16 lsf_int[M]; + Word16 lsf_int_variab[M]; + Word16 lsp_int_variab[M]; + Word16 acoeff_variab[M + 1]; + + Word16 lsf[M]; + Word32 L_lsf[M]; + Word16 ptr; + Word16 tmp_int_length; + + + // This function is called if synthesis state is not SPEECH + // the globally passed inputs to this function are + // st->sid_frame + // st->valid_data + // st->dtxHangoverAdded + // new_state (SPEECH, DTX, DTX_MUTE) + + if ((st->dtxHangoverAdded != 0) && + (st->sid_frame != 0)) + { + // sid_first after dtx hangover period + // or sid_upd after dtxhangover + + // set log_en_adjust to correct value + st->log_en_adjust = dtx_log_en_adjust[mode]; + + ptr = add(st->lsf_hist_ptr, M); + if (sub(ptr, 80) == 0) + { + ptr = 0; + } + Copy( &st->lsf_hist[st->lsf_hist_ptr],&st->lsf_hist[ptr],M); + + ptr = add(st->log_en_hist_ptr,1); + if (sub(ptr, DTX_HIST_SIZE) == 0) + { + ptr = 0; + } + st->log_en_hist[ptr] = st->log_en_hist[st->log_en_hist_ptr]; // Q11 + + // compute mean log energy and lsp + // from decoded signal (SID_FIRST) + st->log_en = 0; + for (i = 0; i < M; i++) + { + L_lsf[i] = 0; + } + + // average energy and lsp + for (i = 0; i < DTX_HIST_SIZE; i++) + { + st->log_en = add(st->log_en, + shr(st->log_en_hist[i],3)); + for (j = 0; j < M; j++) + { + L_lsf[j] = L_add(L_lsf[j], + L_deposit_l(st->lsf_hist[i * M + j])); + } + } + + for (j = 0; j < M; j++) + { + lsf[j] = extract_l(L_shr(L_lsf[j],3)); // divide by 8 + } + + Lsf_lsp(lsf, st->lsp, M); + + // make log_en speech coder mode independent + // added again later before synthesis + st->log_en = sub(st->log_en, st->log_en_adjust); + + // compute lsf variability vector + Copy(st->lsf_hist, st->lsf_hist_mean, 80); + + for (i = 0; i < M; i++) + { + L_lsf_mean = 0; + // compute mean lsf + for (j = 0; j < 8; j++) + { + L_lsf_mean = L_add(L_lsf_mean, + L_deposit_l(st->lsf_hist_mean[i+j*M])); + } + + lsf_mean = extract_l(L_shr(L_lsf_mean, 3)); + // subtract mean and limit to within reasonable limits + // moreover the upper lsf's are attenuated + for (j = 0; j < 8; j++) + { + // subtract mean + st->lsf_hist_mean[i+j*M] = + sub(st->lsf_hist_mean[i+j*M], lsf_mean); + + // attenuate deviation from mean, especially for upper lsf's + st->lsf_hist_mean[i+j*M] = + mult(st->lsf_hist_mean[i+j*M], lsf_hist_mean_scale[i]); + + // limit the deviation + if (st->lsf_hist_mean[i+j*M] < 0) + { + negative = 1; + } + else + { + negative = 0; + } + st->lsf_hist_mean[i+j*M] = abs_s(st->lsf_hist_mean[i+j*M]); + + // apply soft limit + if (sub(st->lsf_hist_mean[i+j*M], 655) > 0) + { + st->lsf_hist_mean[i+j*M] = + add(655, shr(sub(st->lsf_hist_mean[i+j*M], 655), 2)); + } + + // apply hard limit + if (sub(st->lsf_hist_mean[i+j*M], 1310) > 0) + { + st->lsf_hist_mean[i+j*M] = 1310; + } + if (negative != 0) + { + st->lsf_hist_mean[i+j*M] = -st->lsf_hist_mean[i+j*M]; + } + + } + } + } + + if (st->sid_frame != 0 ) + { + // Set old SID parameters, always shift + // even if there is no new valid_data + Copy(st->lsp, st->lsp_old, M); + st->old_log_en = st->log_en; + + if (st->valid_data != 0 ) // new data available (no CRC) + { + // Compute interpolation factor, since the division only works + // for values of since_last_sid < 32 we have to limit the + // interpolation to 32 frames + tmp_int_length = st->since_last_sid; + st->since_last_sid = 0; + + if (sub(tmp_int_length, 32) > 0) + { + tmp_int_length = 32; + } + if (sub(tmp_int_length, 2) >= 0) + { + st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10)); + } + else + { + st->true_sid_period_inv = 1 << 14; // 0.5 it Q15 + } + + Init_D_plsf_3(lsfState, parm[0]); // temporay initialization + D_plsf_3(lsfState, MRDTX, 0, &parm[1], st->lsp); + Set_zero(lsfState->past_r_q, M); // reset for next speech frame + + log_en_index = parm[4]; + // Q11 and divide by 4 + st->log_en = shl(log_en_index, (11 - 2)); + + // Subtract 2.5 in Q11 + st->log_en = sub(st->log_en, (2560 * 2)); + + // Index 0 is reserved for silence + if (log_en_index == 0) + { + st->log_en = MIN_16; + } + + // no interpolation at startup after coder reset + // or when SID_UPD has been received right after SPEECH + if ((st->data_updated == 0) || + (sub(st->dtxGlobalState, SPEECH) == 0) + ) + { + Copy(st->lsp, st->lsp_old, M); + st->old_log_en = st->log_en; + } + } // endif valid_data + + // initialize gain predictor memory of other modes + ma_pred_init = sub(shr(st->log_en,1), 9000); + if (ma_pred_init > 0) + { + ma_pred_init = 0; + } + if (sub(ma_pred_init, -14436) < 0) + { + ma_pred_init = -14436; + } + + predState->past_qua_en[0] = ma_pred_init; + predState->past_qua_en[1] = ma_pred_init; + predState->past_qua_en[2] = ma_pred_init; + predState->past_qua_en[3] = ma_pred_init; + + // past_qua_en for other modes than MR122 + ma_pred_init = mult(5443, ma_pred_init); + // scale down by factor 20*log10(2) in Q15 + predState->past_qua_en_MR122[0] = ma_pred_init; + predState->past_qua_en_MR122[1] = ma_pred_init; + predState->past_qua_en_MR122[2] = ma_pred_init; + predState->past_qua_en_MR122[3] = ma_pred_init; + } // endif sid_frame + + // CN generation + // recompute level adjustment factor Q11 + // st->log_en_adjust = 0.9*st->log_en_adjust + + // 0.1*dtx_log_en_adjust[mode]); + st->log_en_adjust = add(mult(st->log_en_adjust, 29491), + shr(mult(shl(dtx_log_en_adjust[mode],5),3277),5)); + + // Interpolate SID info + int_fac = shl(add(1,st->since_last_sid), 10); // Q10 + int_fac = mult(int_fac, st->true_sid_period_inv); // Q10 * Q15 -> Q10 + + // Maximize to 1.0 in Q10 + if (sub(int_fac, 1024) > 0) + { + int_fac = 1024; + } + int_fac = shl(int_fac, 4); // Q10 -> Q14 + + L_log_en_int = L_mult(int_fac, st->log_en); // Q14 * Q11->Q26 + for(i = 0; i < M; i++) + { + lsp_int[i] = mult(int_fac, st->lsp[i]);// Q14 * Q15 -> Q14 + } + + int_fac = sub(16384, int_fac); // 1-k in Q14 + + // (Q14 * Q11 -> Q26) + Q26 -> Q26 + L_log_en_int = L_mac(L_log_en_int, int_fac, st->old_log_en); + for(i = 0; i < M; i++) + { + // Q14 + (Q14 * Q15 -> Q14) -> Q14 + lsp_int[i] = add(lsp_int[i], mult(int_fac, st->lsp_old[i])); + lsp_int[i] = shl(lsp_int[i], 1); // Q14 -> Q15 + } + + // compute the amount of lsf variability + lsf_variab_factor = sub(st->log_pg_mean,2457); // -0.6 in Q12 + // *0.3 Q12*Q15 -> Q12 + lsf_variab_factor = sub(4096, mult(lsf_variab_factor, 9830)); + + // limit to values between 0..1 in Q12 + if (sub(lsf_variab_factor, 4096) > 0) + { + lsf_variab_factor = 4096; + } + if (lsf_variab_factor < 0) + { + lsf_variab_factor = 0; + } + lsf_variab_factor = shl(lsf_variab_factor, 3); // -> Q15 + + // get index of vector to do variability with + lsf_variab_index = pseudonoise(&st->L_pn_seed_rx, 3); + + // convert to lsf + Lsp_lsf(lsp_int, lsf_int, M); + + // apply lsf variability + Copy(lsf_int, lsf_int_variab, M); + for(i = 0; i < M; i++) + { + lsf_int_variab[i] = add(lsf_int_variab[i], + mult(lsf_variab_factor, + st->lsf_hist_mean[i+lsf_variab_index*M])); + } + + // make sure that LSP's are ordered + Reorder_lsf(lsf_int, LSF_GAP, M); + Reorder_lsf(lsf_int_variab, LSF_GAP, M); + + // copy lsf to speech decoders lsf state + Copy(lsf_int, lsfState->past_lsf_q, M); + + // convert to lsp + Lsf_lsp(lsf_int, lsp_int, M); + Lsf_lsp(lsf_int_variab, lsp_int_variab, M); + + // Compute acoeffs Q12 acoeff is used for level + // normalization and postfilter, acoeff_variab is + // used for synthesis filter + // by doing this we make sure that the level + // in high frequenncies does not jump up and down + + Lsp_Az(lsp_int, acoeff); + Lsp_Az(lsp_int_variab, acoeff_variab); + + // For use in postfilter + Copy(acoeff, &A_t[0], M + 1); + Copy(acoeff, &A_t[M + 1], M + 1); + Copy(acoeff, &A_t[2 * (M + 1)], M + 1); + Copy(acoeff, &A_t[3 * (M + 1)], M + 1); + + // Compute reflection coefficients Q15 + A_Refl(&acoeff[1], refl); + + // Compute prediction error in Q15 + pred_err = MAX_16; // 0.99997 in Q15 + for (i = 0; i < M; i++) + { + pred_err = mult(pred_err, sub(MAX_16, mult(refl[i], refl[i]))); + } + + // compute logarithm of prediction gain + Log2(L_deposit_l(pred_err), &log_pg_e, &log_pg_m); + + // convert exponent and mantissa to Word16 Q12 + log_pg = shl(sub(log_pg_e,15), 12); // Q12 + log_pg = shr(sub(0,add(log_pg, shr(log_pg_m, 15-12))), 1); + st->log_pg_mean = add(mult(29491,st->log_pg_mean), + mult(3277, log_pg)); + + // Compute interpolated log energy + L_log_en_int = L_shr(L_log_en_int, 10); // Q26 -> Q16 + + // Add 4 in Q16 + L_log_en_int = L_add(L_log_en_int, 4 * 65536L); + + // subtract prediction gain + L_log_en_int = L_sub(L_log_en_int, L_shl(L_deposit_l(log_pg), 4)); + + // adjust level to speech coder mode + L_log_en_int = L_add(L_log_en_int, + L_shl(L_deposit_l(st->log_en_adjust), 5)); + + log_en_int_e = extract_h(L_log_en_int); + log_en_int_m = extract_l(L_shr(L_sub(L_log_en_int, + L_deposit_h(log_en_int_e)), 1)); + level = extract_l(Pow2(log_en_int_e, log_en_int_m)); // Q4 + + for (i = 0; i < 4; i++) + { + // Compute innovation vector + build_CN_code(&st->L_pn_seed_rx, ex); + for (j = 0; j < L_SUBFR; j++) + { + ex[j] = mult(level, ex[j]); + } + // Synthesize + Syn_filt(acoeff_variab, ex, &synth[i * L_SUBFR], L_SUBFR, + mem_syn, 1); + + } // next i + + // reset codebook averaging variables + averState->hangVar = 20; + averState->hangCount = 0; + + if (sub(new_state, DTX_MUTE) == 0) + { + // mute comfort noise as it has been quite a long time since + * last SID update was performed + + tmp_int_length = st->since_last_sid; + if (sub(tmp_int_length, 32) > 0) + { + tmp_int_length = 32; + } + + // safety guard against division by zero + if(tmp_int_length <= 0) { + tmp_int_length = 8; + } + + st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10)); + + st->since_last_sid = 0; + Copy(st->lsp, st->lsp_old, M); + st->old_log_en = st->log_en; + // subtract 1/8 in Q11 i.e -6/8 dB + st->log_en = sub(st->log_en, 256); + } + + // reset interpolation length timer + // if data has been updated. + if ((st->sid_frame != 0) && + ((st->valid_data != 0) || + ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0))) + { + st->since_last_sid = 0; + st->data_updated = 1; + } + + return 0; +} + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void dtx_dec( + dtx_decState *st, /* i/o : State struct */ + Word16 mem_syn[], /* i/o : AMR decoder state */ + D_plsfState* lsfState, /* i/o : decoder lsf states */ + gc_predState* predState, /* i/o : prediction states */ + Cb_gain_averageState* averState, /* i/o : CB gain average states */ + enum DTXStateType new_state, /* i : new DTX state */ + enum Mode mode, /* i : AMR mode */ + Word16 parm[], /* i : Vector of synthesis parameters */ + CommonAmrTbls* common_amr_tbls, /* i : Ptr to struct of table ptrs */ + Word16 synth[], /* o : synthesised speech */ + Word16 A_t[], /* o : decoded LP filter in 4 subframes*/ + Flag *pOverflow +) +{ + Word16 log_en_index; + Word16 i; + Word16 j; + Word16 int_fac; + Word32 L_log_en_int; + Word16 lsp_int[M]; + Word16 log_en_int_e; + Word16 log_en_int_m; + Word16 level; + Word16 acoeff[M + 1]; + Word16 refl[M]; + Word16 pred_err; + Word16 ex[L_SUBFR]; + Word16 ma_pred_init; + Word16 log_pg_e; + Word16 log_pg_m; + Word16 log_pg; + Flag negative; + Word16 lsf_mean; + Word32 L_lsf_mean; + Word16 lsf_variab_index; + Word16 lsf_variab_factor; + Word16 lsf_int[M]; + Word16 lsf_int_variab[M]; + Word16 lsp_int_variab[M]; + Word16 acoeff_variab[M + 1]; + + Word16 lsf[M]; + Word32 L_lsf[M]; + Word16 ptr; + Word16 tmp_int_length; + + Word32 L_temp; + Word16 temp; + + /* This function is called if synthesis state is not SPEECH + * the globally passed inputs to this function are + * st->sid_frame + * st->valid_data + * st->dtxHangoverAdded + * new_state (SPEECH, DTX, DTX_MUTE) + */ + + if ((st->dtxHangoverAdded != 0) && + (st->sid_frame != 0)) + { + /* sid_first after dtx hangover period */ + /* or sid_upd after dtxhangover */ + + /* set log_en_adjust to correct value */ + st->log_en_adjust = dtx_log_en_adjust[mode]; + + ptr = st->lsf_hist_ptr + M; + + if (ptr == 80) + { + ptr = 0; + } + oscl_memmove((void *)&st->lsf_hist[ptr], &st->lsf_hist[st->lsf_hist_ptr], M*sizeof(*st->lsf_hist)); + + ptr = st->log_en_hist_ptr + 1; + + if (ptr == DTX_HIST_SIZE) + { + ptr = 0; + } + + st->log_en_hist[ptr] = st->log_en_hist[st->log_en_hist_ptr]; /* Q11 */ + + /* compute mean log energy and lsp * + * from decoded signal (SID_FIRST) */ + st->log_en = 0; + for (i = M - 1; i >= 0; i--) + { + L_lsf[i] = 0; + } + + /* average energy and lsp */ + for (i = DTX_HIST_SIZE - 1; i >= 0; i--) + { + if (st->log_en_hist[i] < 0) + { + temp = ~((~st->log_en_hist[i]) >> 3); + } + else + { + temp = st->log_en_hist[i] >> 3; + } + st->log_en = add_16(st->log_en, temp, pOverflow); + for (j = M - 1; j >= 0; j--) + { + L_lsf[j] = L_add(L_lsf[j], + (Word32)(st->lsf_hist[i * M + j]), pOverflow); + } + } + + for (j = M - 1; j >= 0; j--) + { + if (L_lsf[j] < 0) + { + lsf[j] = (Word16)(~((~L_lsf[j]) >> 3)); + } + else + { + lsf[j] = (Word16)(L_lsf[j] >> 3); + } + } + + Lsf_lsp(lsf, st->lsp, M, pOverflow); + + /* make log_en speech coder mode independent */ + /* added again later before synthesis */ + st->log_en = sub(st->log_en, st->log_en_adjust, pOverflow); + + /* compute lsf variability vector */ + oscl_memmove((void *)st->lsf_hist_mean, st->lsf_hist, 80*sizeof(*st->lsf_hist)); + + for (i = M - 1; i >= 0; i--) + { + L_lsf_mean = 0; + /* compute mean lsf */ + for (j = 8 - 1; j >= 0; j--) + { + L_lsf_mean = L_add(L_lsf_mean, + (Word32)(st->lsf_hist_mean[i+j*M]), pOverflow); + } + + if (L_lsf_mean < 0) + { + lsf_mean = (Word16)(~((~L_lsf_mean) >> 3)); + } + else + { + lsf_mean = (Word16)(L_lsf_mean >> 3); + } + /* subtract mean and limit to within reasonable limits * + * moreover the upper lsf's are attenuated */ + for (j = 8 - 1; j >= 0; j--) + { + /* subtract mean */ + st->lsf_hist_mean[i+j*M] = + sub(st->lsf_hist_mean[i+j*M], lsf_mean, pOverflow); + + /* attenuate deviation from mean, especially for upper lsf's */ + st->lsf_hist_mean[i+j*M] = + mult(st->lsf_hist_mean[i+j*M], lsf_hist_mean_scale[i], pOverflow); + + /* limit the deviation */ + if (st->lsf_hist_mean[i+j*M] < 0) + { + negative = 1; + } + else + { + negative = 0; + } + st->lsf_hist_mean[i+j*M] = abs_s(st->lsf_hist_mean[i+j*M]); + + /* apply soft limit */ + if (st->lsf_hist_mean[i+j*M] > 655) + { + st->lsf_hist_mean[i+j*M] = 655 + ((st->lsf_hist_mean[i+j*M] + - 655) >> 2); + } + + /* apply hard limit */ + if (st->lsf_hist_mean[i+j*M] > 1310) + { + st->lsf_hist_mean[i+j*M] = 1310; + } + + if (negative != 0) + { + st->lsf_hist_mean[i+j*M] = -st->lsf_hist_mean[i+j*M]; + } + } + } + } + + + if (st->sid_frame != 0) + { + /* Set old SID parameters, always shift */ + /* even if there is no new valid_data */ + oscl_memmove((void *)st->lsp_old, st->lsp, M*sizeof(*st->lsp)); + st->old_log_en = st->log_en; + + if (st->valid_data != 0) /* new data available (no CRC) */ + { + /* Compute interpolation factor, since the division only works * + * for values of since_last_sid < 32 we have to limit the * + * interpolation to 32 frames */ + tmp_int_length = st->since_last_sid; + st->since_last_sid = 0; + + if (tmp_int_length >= 32) + { + tmp_int_length = 32; + } + + L_temp = ((Word32) tmp_int_length) << 10; + if (L_temp != (Word32)((Word16) L_temp)) + { + *pOverflow = 1; + L_temp = (Word32)((tmp_int_length > 0) ? MAX_16 : MIN_16); + } + temp = (Word16) L_temp; + + if (tmp_int_length >= 2) + { + st->true_sid_period_inv = div_s(1 << 10, temp); + } + else + { + st->true_sid_period_inv = 1 << 14; /* 0.5 it Q15 */ + } + + Init_D_plsf_3(lsfState, parm[0], common_amr_tbls->past_rq_init_ptr); + D_plsf_3(lsfState, MRDTX, 0, &parm[1], common_amr_tbls, st->lsp, pOverflow); + /* reset for next speech frame */ + oscl_memset((void *)lsfState->past_r_q, 0, M*sizeof(*lsfState->past_r_q)); + + log_en_index = parm[4]; + /* Q11 and divide by 4 */ + if ((log_en_index > 63) || (log_en_index < -64)) + { + st->log_en = (log_en_index > 0) ? MAX_16 : MIN_16; + } + else + { + st->log_en = (log_en_index) << (11 - 2); + } + + /* Subtract 2.5 in Q11 */ + st->log_en -= (2560 * 2); + + /* Index 0 is reserved for silence */ + if (log_en_index == 0) + { + st->log_en = MIN_16; + } + + /* no interpolation at startup after coder reset */ + /* or when SID_UPD has been received right after SPEECH */ + + if ((st->data_updated == 0) || + (st->dtxGlobalState == SPEECH)) + { + oscl_memmove((void *)st->lsp_old, st->lsp, M*sizeof(*st->lsp)); + st->old_log_en = st->log_en; + } + } /* endif valid_data */ + + /* initialize gain predictor memory of other modes */ + if (st->log_en < 0) + { + temp = ~((~st->log_en) >> 1); + } + else + { + temp = st->log_en >> 1; + } + ma_pred_init = temp - 9000; + + if (ma_pred_init > 0) + { + ma_pred_init = 0; + } + else if (ma_pred_init < -14436) + { + ma_pred_init = -14436; + } + + predState->past_qua_en[0] = ma_pred_init; + predState->past_qua_en[1] = ma_pred_init; + predState->past_qua_en[2] = ma_pred_init; + predState->past_qua_en[3] = ma_pred_init; + + /* past_qua_en for other modes than MR122 */ + ma_pred_init = ((Word32) ma_pred_init * 5443) >> 15; + + /* scale down by factor 20*log10(2) in Q15 */ + predState->past_qua_en_MR122[0] = ma_pred_init; + predState->past_qua_en_MR122[1] = ma_pred_init; + predState->past_qua_en_MR122[2] = ma_pred_init; + predState->past_qua_en_MR122[3] = ma_pred_init; + } /* endif sid_frame */ + + /* CN generation */ + /* recompute level adjustment factor Q11 * + * st->log_en_adjust = 0.9*st->log_en_adjust + * + * 0.1*dtx_log_en_adjust[mode]); */ + if (dtx_log_en_adjust[mode] > 1023) + { + temp = MAX_16; + } + else if (dtx_log_en_adjust[mode] < -1024) + { + temp = MIN_16; + } + else + { + temp = (((Word32) dtx_log_en_adjust[mode] << 5) * 3277) >> 15; + + + } + + if (temp < 0) + { + temp = ~((~temp) >> 5); + } + else + { + temp >>= 5; + } + st->log_en_adjust = add_16(((Word32)st->log_en_adjust * 29491) >> 15, temp, pOverflow); + + + /* Interpolate SID info */ + int_fac = shl((st->since_last_sid + 1), 10, pOverflow); /* Q10 */ + int_fac = mult(int_fac, st->true_sid_period_inv, pOverflow); /* Q10 * Q15 -> Q10 */ + + /* Maximize to 1.0 in Q10 */ + if (int_fac > 1024) + { + int_fac = 16384; + } + else if (int_fac < -2048) + { + int_fac = MIN_16; + } + else + { + int_fac <<= 4; /* Q10 -> Q14 */ + } + + L_log_en_int = L_mult(int_fac, st->log_en, pOverflow); /* Q14 * Q11->Q26 */ + for (i = M - 1; i >= 0; i--) + { + lsp_int[i] = mult(int_fac, st->lsp[i], pOverflow);/* Q14 * Q15 -> Q14 */ + } + + int_fac = 16384 - int_fac; /* 1-k in Q14 */ + + /* (Q14 * Q11 -> Q26) + Q26 -> Q26 */ + L_log_en_int = L_mac(L_log_en_int, int_fac, st->old_log_en, pOverflow); + for (i = M - 1; i >= 0; i--) + { + /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */ + lsp_int[i] = add_16(lsp_int[i], mult(int_fac, st->lsp_old[i], pOverflow), pOverflow); + + L_temp = ((Word32) lsp_int[i]) << 1; /* Q14 -> Q15 */ + if (L_temp != (Word32)((Word16) L_temp)) + { + *pOverflow = 1; + L_temp = (Word32)((lsp_int[i] > 0) ? MAX_16 : MIN_16); + } + lsp_int[i] = (Word16) L_temp; + } + + /* compute the amount of lsf variability */ + lsf_variab_factor = st->log_pg_mean - 2457; /* -0.6 in Q12 */ + /* *0.3 Q12*Q15 -> Q12 */ + lsf_variab_factor = 4096 - mult(lsf_variab_factor, 9830, pOverflow); + + /* limit to values between 0..1 in Q12 */ + if (lsf_variab_factor > 4095) + { + lsf_variab_factor = MAX_16; + } + else if (lsf_variab_factor < 0) + { + lsf_variab_factor = 0; + } + else + { + lsf_variab_factor <<= 3; /* -> Q15 */ + } + + /* get index of vector to do variability with */ + lsf_variab_index = pseudonoise(&st->L_pn_seed_rx, 3); + + /* convert to lsf */ + Lsp_lsf(lsp_int, lsf_int, M, pOverflow); + + /* apply lsf variability */ + oscl_memmove((void *)lsf_int_variab, lsf_int, M*sizeof(*lsf_int)); + for (i = M - 1; i >= 0; i--) + { + lsf_int_variab[i] = add_16(lsf_int_variab[i], + mult(lsf_variab_factor, + st->lsf_hist_mean[i+lsf_variab_index*M], pOverflow) + , pOverflow); + } + + /* make sure that LSP's are ordered */ + Reorder_lsf(lsf_int, LSF_GAP, M, pOverflow); + Reorder_lsf(lsf_int_variab, LSF_GAP, M, pOverflow); + + /* copy lsf to speech decoders lsf state */ + oscl_memmove((void *)lsfState->past_lsf_q, lsf_int, M*sizeof(*lsf_int)); + + /* convert to lsp */ + Lsf_lsp(lsf_int, lsp_int, M, pOverflow); + Lsf_lsp(lsf_int_variab, lsp_int_variab, M, pOverflow); + + /* Compute acoeffs Q12 acoeff is used for level * + * normalization and postfilter, acoeff_variab is * + * used for synthesis filter * + * by doing this we make sure that the level * + * in high frequenncies does not jump up and down */ + + Lsp_Az(lsp_int, acoeff, pOverflow); + Lsp_Az(lsp_int_variab, acoeff_variab, pOverflow); + + /* For use in postfilter */ + oscl_memmove((void *)&A_t[0], acoeff, (M + 1)*sizeof(*acoeff)); + oscl_memmove((void *)&A_t[M + 1], acoeff, (M + 1)*sizeof(*acoeff)); + oscl_memmove((void *)&A_t[2 *(M + 1)], acoeff, (M + 1)*sizeof(*acoeff)); + oscl_memmove((void *)&A_t[3 *(M + 1)], acoeff, (M + 1)*sizeof(*acoeff)); + + /* Compute reflection coefficients Q15 */ + A_Refl(&acoeff[1], refl, pOverflow); + + /* Compute prediction error in Q15 */ + pred_err = MAX_16; /* 0.99997 in Q15 */ + for (i = 0; i < M; i++) + { + L_temp = (((Word32) refl[i]) * refl[i]) >> 15; + if (L_temp <= 0x00007fffL) + { + temp = MAX_16 - (Word16) L_temp; + } + else + { + *pOverflow = 1; + temp = 0; + } + pred_err = mult(pred_err, temp, pOverflow); + } + + /* compute logarithm of prediction gain */ + Log2((Word32)(pred_err), &log_pg_e, &log_pg_m, pOverflow); + + /* convert exponent and mantissa to Word16 Q12 */ + log_pg = shl((log_pg_e - 15), 12, pOverflow); /* Q12 */ + log_pg = shr(sub(0, add_16(log_pg, shr(log_pg_m, 15 - 12, pOverflow), + pOverflow), pOverflow), 1, pOverflow); + st->log_pg_mean = add_16(mult(29491, st->log_pg_mean, pOverflow), + mult(3277, log_pg, pOverflow), pOverflow); + + /* Compute interpolated log energy */ + L_log_en_int = L_shr(L_log_en_int, 10, pOverflow); /* Q26 -> Q16 */ + + /* Add 4 in Q16 */ + L_log_en_int = L_add(L_log_en_int, 4 * 65536L, pOverflow); + + /* subtract prediction gain */ + L_log_en_int = L_sub(L_log_en_int, L_shl((Word32)(log_pg), 4, pOverflow), pOverflow); + + /* adjust level to speech coder mode */ + L_log_en_int = L_add(L_log_en_int, + L_shl((Word32)(st->log_en_adjust), 5, pOverflow), pOverflow); + + log_en_int_e = (Word16)(L_log_en_int >> 16); + + log_en_int_m = (Word16)(L_shr(L_sub(L_log_en_int, + ((Word32)log_en_int_e << 16), pOverflow), 1, pOverflow)); + level = (Word16)(Pow2(log_en_int_e, log_en_int_m, pOverflow)); /* Q4 */ + + for (i = 0; i < 4; i++) + { + /* Compute innovation vector */ + build_CN_code(&st->L_pn_seed_rx, ex, pOverflow); + for (j = L_SUBFR - 1; j >= 0; j--) + { + ex[j] = mult(level, ex[j], pOverflow); + } + /* Synthesize */ + Syn_filt(acoeff_variab, ex, &synth[i * L_SUBFR], L_SUBFR, + mem_syn, 1); + + } /* next i */ + + /* reset codebook averaging variables */ + averState->hangVar = 20; + averState->hangCount = 0; + + if (new_state == DTX_MUTE) + { + /* mute comfort noise as it has been quite a long time since + * last SID update was performed */ + + tmp_int_length = st->since_last_sid; + + if (tmp_int_length > 32) + { + tmp_int_length = 32; + } + else if (tmp_int_length <= 0) + { + /* safety guard against division by zero */ + tmp_int_length = 8; + } + + L_temp = ((Word32) tmp_int_length) << 10; + if (L_temp != (Word32)((Word16) L_temp)) + { + *pOverflow = 1; + L_temp = (Word32)((tmp_int_length > 0) ? MAX_16 : MIN_16); + } + temp = (Word16) L_temp; + + st->true_sid_period_inv = div_s(1 << 10, temp); + + st->since_last_sid = 0; + oscl_memmove((void *)st->lsp_old, st->lsp, M*sizeof(*st->lsp)); + st->old_log_en = st->log_en; + /* subtract 1/8 in Q11 i.e -6/8 dB */ + st->log_en = st->log_en - 256; + } + + /* reset interpolation length timer + * if data has been updated. */ + if ((st->sid_frame != 0) && + ((st->valid_data != 0) || + ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0))) + { + st->since_last_sid = 0; + st->data_updated = 1; + } + + return; +} + + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: dtx_dec_activity_update +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type dtx_decState + lsf = + frame = + + Outputs: + st points to an updated structure of type dtx_decState + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function updates the DTX parameters. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dtx_dec.c, UMTS GSM AMR speech codec, R99 - Version 3.3.0, December 12, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void dtx_dec_activity_update(dtx_decState *st, + Word16 lsf[], + Word16 frame[]) +{ + Word16 i; + + Word32 L_frame_en; + Word16 log_en_e, log_en_m, log_en; + + // update lsp history + st->lsf_hist_ptr = add(st->lsf_hist_ptr,M); + if (sub(st->lsf_hist_ptr, 80) == 0) + { + st->lsf_hist_ptr = 0; + } + Copy(lsf, &st->lsf_hist[st->lsf_hist_ptr], M); + + // compute log energy based on frame energy + L_frame_en = 0; // Q0 + for (i=0; i < L_FRAME; i++) + { + L_frame_en = L_mac(L_frame_en, frame[i], frame[i]); + } + Log2(L_frame_en, &log_en_e, &log_en_m); + + // convert exponent and mantissa to Word16 Q10 + log_en = shl(log_en_e, 10); // Q10 + log_en = add(log_en, shr(log_en_m, 15-10)); + + // divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 + log_en = sub(log_en, 7497+1024); + + // insert into log energy buffer, no division by two as * + * log_en in decoder is Q11 + st->log_en_hist_ptr = add(st->log_en_hist_ptr, 1); + if (sub(st->log_en_hist_ptr, DTX_HIST_SIZE) == 0) + { + st->log_en_hist_ptr = 0; + } + st->log_en_hist[st->log_en_hist_ptr] = log_en; // Q11 +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void dtx_dec_activity_update(dtx_decState *st, + Word16 lsf[], + Word16 frame[], + Flag *pOverflow) +{ + Word16 i; + + Word32 L_frame_en; + Word32 L_temp; + Word16 log_en_e; + Word16 log_en_m = 0; + Word16 log_en = 0; + + /* update lsp history */ + st->lsf_hist_ptr += M; + + if (st->lsf_hist_ptr == 80) + { + st->lsf_hist_ptr = 0; + } + oscl_memmove((void *)&st->lsf_hist[st->lsf_hist_ptr], lsf, M*sizeof(*lsf)); + + /* compute log energy based on frame energy */ + L_frame_en = 0; /* Q0 */ + for (i = L_FRAME - 1; i >= 0; i--) + { + L_temp = ((Word32) frame[i]) * frame[i]; + if (L_temp != (Word32) 0x40000000L) + { + L_temp = L_temp << 1; + } + else + { + L_temp = MAX_32; + } + L_frame_en = L_add(L_frame_en, L_temp, pOverflow); + } + Log2(L_frame_en, &log_en_e, &log_en_m, pOverflow); + + /* convert exponent and mantissa to Word16 Q10 */ + L_temp = ((Word32) log_en_e) << 10; + + if (L_temp != (Word32)((Word16) L_temp)) + { + *pOverflow = 1; + L_temp = (Word32)((log_en_e > 0) ? MAX_16 : MIN_16); + } + log_en_e = (Word16) L_temp; + + if (log_en_m < 0) + { + log_en_m = ~((~log_en_m) >> 5); + } + else + { + log_en_m >>= 5; + } + log_en = log_en_e + log_en_m; + + /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */ + log_en -= 7497 + 1024; + + /* insert into log energy buffer, no division by two as * + * log_en in decoder is Q11 */ + st->log_en_hist_ptr += 1; + + if (st->log_en_hist_ptr == DTX_HIST_SIZE) + { + st->log_en_hist_ptr = 0; + } + st->log_en_hist[st->log_en_hist_ptr] = log_en; /* Q11 */ + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: rx_dtx_handler +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type dtx_decState + frame_type = RX frame type + + Returns: + newState = variable of type DTXStateType + + Outputs: + st points to an updated structure of type dtx_decState + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function determines the new state of the decoder based on the frame_type + and sets up the decoder parameters according to newState. + + Table of new SPD synthesis states + + | previous SPD_synthesis_state + Incoming | + frame_type | SPEECH | DTX | DTX_MUTE + --------------------------------------------------------------- + RX_SPEECH_GOOD , | | | + RX_SPEECH_PR_DEGRADED | SPEECH | SPEECH | SPEECH + ---------------------------------------------------------------- + RX_SPEECH_PR_BAD, | | | + RX_SPEECH_BAD, | SPEECH | DTX | DTX_MUTE + ---------------------------------------------------------------- + RX_SID_FIRST, | DTX | DTX/(DTX_MUTE)| DTX_MUTE + ---------------------------------------------------------------- + RX_SID_UPDATE, | DTX | DTX | DTX + ---------------------------------------------------------------- + RX_SID_BAD, | DTX | DTX/(DTX_MUTE)| DTX_MUTE + ---------------------------------------------------------------- + RX_NO_DATA | SPEECH | DTX/(DTX_MUTE)| DTX_MUTE + |(class2 garb.)| | + ---------------------------------------------------------------- + RX_ONSET | SPEECH | DTX/(DTX_MUTE)| DTX_MUTE + |(class2 garb.)| | + ---------------------------------------------------------------- + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dtx_dec.c, UMTS GSM AMR speech codec, R99 - Version 3.3.0, December 12, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +enum DTXStateType rx_dtx_handler( + dtx_decState *st, // i/o : State struct + enum RXFrameType frame_type // i : Frame type + ) +{ + enum DTXStateType newState; + enum DTXStateType encState; + + // DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) + if ((sub(frame_type, RX_SID_FIRST) == 0) || + (sub(frame_type, RX_SID_UPDATE) == 0) || + (sub(frame_type, RX_SID_BAD) == 0) || + (((sub(st->dtxGlobalState, DTX) == 0) || + (sub(st->dtxGlobalState, DTX_MUTE) == 0)) && + ((sub(frame_type, RX_NO_DATA) == 0) || + (sub(frame_type, RX_SPEECH_BAD) == 0) || + (sub(frame_type, RX_ONSET) == 0)))) + { + newState = DTX; + + // stay in mute for these input types + if ((sub(st->dtxGlobalState, DTX_MUTE) == 0) && + ((sub(frame_type, RX_SID_BAD) == 0) || + (sub(frame_type, RX_SID_FIRST) == 0) || + (sub(frame_type, RX_ONSET) == 0) || + (sub(frame_type, RX_NO_DATA) == 0))) + { + newState = DTX_MUTE; + } + + // evaluate if noise parameters are too old + // since_last_sid is reset when CN parameters have been updated + st->since_last_sid = add(st->since_last_sid, 1); + + // no update of sid parameters in DTX for a long while + // Due to the delayed update of st->since_last_sid counter + // SID_UPDATE frames need to be handled separately to avoid + // entering DTX_MUTE for late SID_UPDATE frames + if((sub(frame_type, RX_SID_UPDATE) != 0) && + (sub(st->since_last_sid, DTX_MAX_EMPTY_THRESH) > 0)) + { + newState = DTX_MUTE; + } + } + else + { + newState = SPEECH; + st->since_last_sid = 0; + } + + // reset the decAnaElapsed Counter when receiving CNI data the first + // time, to robustify counter missmatch after handover + // this might delay the bwd CNI analysis in the new decoder slightly. + + if ((st->data_updated == 0) && + (sub(frame_type, RX_SID_UPDATE) == 0)) + { + st->decAnaElapsedCount = 0; + } + + // update the SPE-SPD DTX hangover synchronization + // to know when SPE has added dtx hangover + st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1); + st->dtxHangoverAdded = 0; + + if ((sub(frame_type, RX_SID_FIRST) == 0) || + (sub(frame_type, RX_SID_UPDATE) == 0) || + (sub(frame_type, RX_SID_BAD) == 0) || + (sub(frame_type, RX_ONSET) == 0) || + (sub(frame_type, RX_NO_DATA) == 0)) + { + encState = DTX; + + // In frame errors simulations RX_NO_DATA may occasionally mean that + // a speech packet was probably sent by the encoder, + // the assumed _encoder_ state should be SPEECH in such cases. + if((sub(frame_type, RX_NO_DATA) == 0) && + (sub(newState, SPEECH) == 0)) + { + encState = SPEECH; + } + + // Note on RX_ONSET operation differing from RX_NO_DATA operation: + // If a RX_ONSET is received in the decoder (by "accident") + // it is still most likely that the encoder state + // for the "ONSET frame" was DTX. + + } + else + { + encState = SPEECH; + } + + if (sub(encState, SPEECH) == 0) + { + st->dtxHangoverCount = DTX_HANG_CONST; + } + else + { + if (sub(st->decAnaElapsedCount, DTX_ELAPSED_FRAMES_THRESH) > 0) + { + st->dtxHangoverAdded = 1; + st->decAnaElapsedCount = 0; + st->dtxHangoverCount = 0; + } + else if (st->dtxHangoverCount == 0) + { + st->decAnaElapsedCount = 0; + } + else + { + st->dtxHangoverCount = sub(st->dtxHangoverCount, 1); + } + } + + if (sub(newState, SPEECH) != 0) + { + // DTX or DTX_MUTE + // CN data is not in a first SID, first SIDs are marked as SID_BAD + // but will do backwards analysis if a hangover period has been added + // according to the state machine above + + st->sid_frame = 0; + st->valid_data = 0; + + if (sub(frame_type, RX_SID_FIRST) == 0) + { + st->sid_frame = 1; + } + else if (sub(frame_type, RX_SID_UPDATE) == 0) + { + st->sid_frame = 1; + st->valid_data = 1; + } + else if (sub(frame_type, RX_SID_BAD) == 0) + { + st->sid_frame = 1; + st->dtxHangoverAdded = 0; // use old data + } + } + + return newState; + // newState is used by both SPEECH AND DTX synthesis routines +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +enum DTXStateType rx_dtx_handler( + dtx_decState *st, /* i/o : State struct */ + enum RXFrameType frame_type,/* i : Frame type */ + Flag *pOverflow) +{ + enum DTXStateType newState; + enum DTXStateType encState; + + + /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */ + + if ((frame_type == RX_SID_FIRST) || + (frame_type == RX_SID_UPDATE) || + (frame_type == RX_SID_BAD) || + (((st->dtxGlobalState == DTX) || (st->dtxGlobalState == DTX_MUTE)) && + ((frame_type == RX_NO_DATA) || (frame_type == RX_SPEECH_BAD) || + (frame_type == RX_ONSET)))) + { + newState = DTX; + + /* stay in mute for these input types */ + + if ((st->dtxGlobalState == DTX_MUTE) && + ((frame_type == RX_SID_BAD) || + (frame_type == RX_SID_FIRST) || + (frame_type == RX_ONSET) || + (frame_type == RX_NO_DATA))) + { + newState = DTX_MUTE; + } + + /* evaluate if noise parameters are too old */ + /* since_last_sid is reset when CN parameters have been updated */ + st->since_last_sid += 1; + + /* no update of sid parameters in DTX for a long while */ + /* Due to the delayed update of st->since_last_sid counter */ + /* SID_UPDATE frames need to be handled separately to avoid */ + /* entering DTX_MUTE for late SID_UPDATE frames */ + if ((frame_type != RX_SID_UPDATE) && + (st->since_last_sid > DTX_MAX_EMPTY_THRESH)) + { + newState = DTX_MUTE; + } + } + else + { + newState = SPEECH; + st->since_last_sid = 0; + } + + /* + reset the decAnaElapsed Counter when receiving CNI data the first + time, to robustify counter missmatch after handover + this might delay the bwd CNI analysis in the new decoder slightly. + */ + + if ((st->data_updated == 0) && + (frame_type == RX_SID_UPDATE)) + { + st->decAnaElapsedCount = 0; + } + + /* update the SPE-SPD DTX hangover synchronization */ + /* to know when SPE has added dtx hangover */ + st->decAnaElapsedCount = add_16(st->decAnaElapsedCount, 1, pOverflow); + st->dtxHangoverAdded = 0; + + if ((frame_type == RX_SID_FIRST) || + (frame_type == RX_SID_UPDATE) || + (frame_type == RX_SID_BAD) || + (frame_type == RX_ONSET) || + (frame_type == RX_NO_DATA)) + { + encState = DTX; + + /* + In frame errors simulations RX_NO_DATA may occasionally mean that + a speech packet was probably sent by the encoder, + the assumed _encoder_ state should be SPEECH in such cases. + */ + if ((frame_type == RX_NO_DATA) && + (newState == SPEECH)) + { + encState = SPEECH; + } + + /* + Note on RX_ONSET operation differing from RX_NO_DATA operation: + If a RX_ONSET is received in the decoder (by "accident") + it is still most likely that the encoder state + for the "ONSET frame" was DTX. + */ + } + else + { + encState = SPEECH; + } + + + if (encState == SPEECH) + { + st->dtxHangoverCount = DTX_HANG_CONST; + } + else + { + + if (st->decAnaElapsedCount > DTX_ELAPSED_FRAMES_THRESH) + { + st->dtxHangoverAdded = 1; + st->decAnaElapsedCount = 0; + st->dtxHangoverCount = 0; + } + else if (st->dtxHangoverCount == 0) + { + st->decAnaElapsedCount = 0; + } + else + { + st->dtxHangoverCount -= 1; + } + } + + if (newState != SPEECH) + { + /* DTX or DTX_MUTE + * CN data is not in a first SID, first SIDs are marked as SID_BAD + * but will do backwards analysis if a hangover period has been added + * according to the state machine above + */ + + st->sid_frame = 0; + st->valid_data = 0; + + if (frame_type == RX_SID_FIRST) + { + st->sid_frame = 1; + } + else if (frame_type == RX_SID_UPDATE) + { + st->sid_frame = 1; + st->valid_data = 1; + } + else if (frame_type == RX_SID_BAD) + { + st->sid_frame = 1; + st->dtxHangoverAdded = 0; /* use old data */ + } + } + + /* newState is used by both SPEECH AND DTX synthesis routines */ + return(newState); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dtx_dec.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dtx_dec.h new file mode 100644 index 00000000..af462f7d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/dtx_dec.h @@ -0,0 +1,181 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dtx_dec.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : dtx_dec.h + Purpose : Decode comfort noice when in DTX + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef DTX_DEC_H +#define DTX_DEC_H +#define dtx_dec_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "d_plsf.h" +#include "gc_pred.h" +#include "c_g_aver.h" +#include "frame.h" +#include "dtx_common_def.h" +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + enum DTXStateType {SPEECH = 0, DTX, DTX_MUTE}; + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 since_last_sid; + Word16 true_sid_period_inv; + Word16 log_en; + Word16 old_log_en; + Word32 L_pn_seed_rx; + Word16 lsp[M]; + Word16 lsp_old[M]; + + Word16 lsf_hist[M*DTX_HIST_SIZE]; + Word16 lsf_hist_ptr; + Word16 lsf_hist_mean[M*DTX_HIST_SIZE]; + Word16 log_pg_mean; + Word16 log_en_hist[DTX_HIST_SIZE]; + Word16 log_en_hist_ptr; + + Word16 log_en_adjust; + + Word16 dtxHangoverCount; + Word16 decAnaElapsedCount; + + Word16 sid_frame; + Word16 valid_data; + Word16 dtxHangoverAdded; + + enum DTXStateType dtxGlobalState; /* contains previous state */ + /* updated in main decoder */ + + Word16 data_updated; /* marker to know if CNI data is ever renewed */ + + } dtx_decState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /* + * Function : dtx_dec_reset + * Purpose : Resets state memory + * Returns : 0 on success + */ + Word16 dtx_dec_reset(dtx_decState *st); + + /* + * Function : dtx_dec + * Purpose : + * Description : + */ + void dtx_dec( + dtx_decState *st, /* i/o : State struct */ + Word16 mem_syn[], /* i/o : AMR decoder state */ + D_plsfState* lsfState, /* i/o : decoder lsf states */ + gc_predState* predState, /* i/o : prediction states */ + Cb_gain_averageState* averState, /* i/o : CB gain average states */ + enum DTXStateType new_state, /* i : new DTX state */ + enum Mode mode, /* i : AMR mode */ + Word16 parm[], /* i : Vector of synthesis parameters */ + CommonAmrTbls* common_amr_tbls, /* i : Ptr to struct of table ptrs */ + Word16 synth[], /* o : synthesised speech */ + Word16 A_t[], /* o : decoded LP filter in 4 subframes*/ + Flag *pOverflow + ); + + void dtx_dec_activity_update(dtx_decState *st, + Word16 lsf[], + Word16 frame[], + Flag *pOverflow); + + /* + * Function : rx_dtx_handler + * Purpose : reads the frame type and checks history + * Description : to decide what kind of DTX/CNI action to perform + */ + enum DTXStateType rx_dtx_handler(dtx_decState *st, /* i/o : State struct */ + enum RXFrameType frame_type,/* i : Frame type */ + Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* DEC_AMR_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ec_gains.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ec_gains.cpp new file mode 100644 index 00000000..f5d4a9d0 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ec_gains.cpp @@ -0,0 +1,720 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + + Filename: ec_gains.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + These modules execute the code book gains for error concealment. This module + contains the init, reset, exit, and "main" functions in this process. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "ec_gains.h" +#include "typedef.h" +#include "cnst.h" +#include "gmed_n.h" +#include "gc_pred.h" +#include "basic_op.h" + + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ec_gain_code_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a pointer to a structure containing code state data of + stucture type ec_gain_codeState + + Outputs: + None. + + Returns: + None + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function resets the state data for the ec_gain module. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int ec_gain_code_reset (ec_gain_codeState *state) +{ + Word16 i; + + if (state == (ec_gain_codeState *) NULL){ + // fprintf(stderr, "ec_gain_code_reset: invalid parameter\n"); + return -1; + } + + for ( i = 0; i < 5; i++) + state->gbuf[i] = 1; + state->past_gain_code = 0; + state->prev_gc = 1; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 ec_gain_code_reset(ec_gain_codeState *state) +{ + Word16 i; + + if (state == (ec_gain_codeState *) NULL) + { + /* fprintf(stderr, "ec_gain_code_reset: invalid parameter\n"); */ + return -1; + } + + for (i = 0; i < 5; i++) + state->gbuf[i] = 1; + state->past_gain_code = 0; + state->prev_gc = 1; + + return 0; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ec_gain_code +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a pointer to a structure containing code state data of + stucture type ec_gain_codeState + pred_state = pointer to MA predictor state of type gc_predState + state = state of the state machine of type Word16 + gain_code = pointer to decoded innovation gain of type Word16 + pOverflow = pointer to overflow indicator of type Flag + + Outputs: + st = pointer to a pointer to a structure containing code state data of + stucture type ec_gain_codeState + pred_state = pointer to MA predictor state of type gc_predState + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + +This function does error concealment using the codebook. Call this function +only in BFI (instead of normal gain decoding function). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + static const Word16 cdown[7] = + { + 32767, 32112, 32112, 32112, + 32112, 32112, 22937 + }; + + Word16 tmp; + Word16 qua_ener_MR122; + Word16 qua_ener; + + // calculate median of last five gain values + tmp = gmed_n (st->gbuf,5); + + // new gain = minimum(median, past_gain) * cdown[state] + if (sub (tmp, st->past_gain_code) > 0) + { + tmp = st->past_gain_code; + } + tmp = mult (tmp, cdown[state]); + *gain_code = tmp; + + // update table of past quantized energies with average of + // current values + + gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener); + gc_pred_update(pred_state, qua_ener_MR122, qua_ener); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void ec_gain_code( + ec_gain_codeState *st, /* i/o : State struct */ + gc_predState *pred_state, /* i/o : MA predictor state */ + Word16 state, /* i : state of the state machine */ + Word16 *gain_code, /* o : decoded innovation gain */ + Flag *pOverflow +) +{ + static const Word16 cdown[7] = + { + 32767, 32112, 32112, 32112, + 32112, 32112, 22937 + }; + + Word16 tmp; + Word16 qua_ener_MR122; + Word16 qua_ener; + + /* calculate median of last five gain values */ + tmp = gmed_n(st->gbuf, 5); + + /* new gain = minimum(median, past_gain) * cdown[state] */ + if (sub(tmp, st->past_gain_code, pOverflow) > 0) + { + tmp = st->past_gain_code; + } + tmp = mult(tmp, cdown[state], pOverflow); + *gain_code = tmp; + + /* update table of past quantized energies with average of + * current values + */ + gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener, pOverflow); + gc_pred_update(pred_state, qua_ener_MR122, qua_ener); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ec_gain_code_update +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a pointer to a structure containing code state data of + stucture type ec_gain_codeState + bfi = a flag that indicates if the frame is bad of type Word16 + prev_bf = a flag that indicates if the previous frame was bad of type Word16 + gain_code = pointer to decoded innovation gain of type Word16 + pOverflow = pointer to overflow indicator of type Flag + + Outputs: + st = pointer to a pointer to a structure containing code state data of + stucture type ec_gain_codeState + gain_code = pointer to decoded innovation gain of type Word16 + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : update the codebook gain concealment state; + limit gain_code if the previous frame was bad + Call this function always after decoding (or concealing) + the gain + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Word16 i; + + // limit gain_code by previous good gain if previous frame was bad + if (bfi == 0) + { + if (prev_bf != 0) + { + if (sub (*gain_code, st->prev_gc) > 0) + { + *gain_code = st->prev_gc; + } + } + st->prev_gc = *gain_code; + } + + // update EC states: previous gain, gain buffer + st->past_gain_code = *gain_code; + + for (i = 1; i < 5; i++) + { + st->gbuf[i - 1] = st->gbuf[i]; + } + st->gbuf[4] = *gain_code; + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void ec_gain_code_update( + ec_gain_codeState *st, /* i/o : State struct */ + Word16 bfi, /* i : flag: frame is bad */ + Word16 prev_bf, /* i : flag: previous frame was bad */ + Word16 *gain_code, /* i/o : decoded innovation gain */ + Flag *pOverflow +) +{ + Word16 i; + + /* limit gain_code by previous good gain if previous frame was bad */ + if (bfi == 0) + { + if (prev_bf != 0) + { + if (sub(*gain_code, st->prev_gc, pOverflow) > 0) + { + *gain_code = st->prev_gc; + } + } + st->prev_gc = *gain_code; + } + + /* update EC states: previous gain, gain buffer */ + st->past_gain_code = *gain_code; + + for (i = 1; i < 5; i++) + { + st->gbuf[i - 1] = st->gbuf[i]; + } + st->gbuf[4] = *gain_code; + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ec_gain_pitch +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a pointer to a structure containing code + state data of stucture type ec_gain_pitchState + state = state of the state machine of type Word16 + pOverflow = pointer to overflow indicator of type Flag + + Outputs: + state = pointer to a pointer to a structure containing code + state data of stucture type ec_gain_pitchState + gain_pitch = pointer to pitch gain (Q14) of type Word16 + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function conceals the error using code gain implementation in this + function. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + static const Word16 pdown[7] = + { + 32767, 32112, 32112, 26214, + 9830, 6553, 6553 + }; + + Word16 tmp; + + // calculate median of last five gains + tmp = gmed_n (st->pbuf, 5); + + // new gain = minimum(median, past_gain) * pdown[state] + if (sub (tmp, st->past_gain_pit) > 0) + { + tmp = st->past_gain_pit; + } + *gain_pitch = mult (tmp, pdown[state]); + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void ec_gain_pitch( + ec_gain_pitchState *st, /* i/o : state variables */ + Word16 state, /* i : state of the state machine */ + Word16 *gain_pitch, /* o : pitch gain (Q14) */ + Flag *pOverflow +) +{ + static const Word16 pdown[7] = + { + 32767, 32112, 32112, 26214, + 9830, 6553, 6553 + }; + + Word16 tmp; + + /* calculate median of last five gains */ + tmp = gmed_n(st->pbuf, 5); + + /* new gain = minimum(median, past_gain) * pdown[state] */ + if (sub(tmp, st->past_gain_pit, pOverflow) > 0) + { + tmp = st->past_gain_pit; + } + *gain_pitch = mult(tmp, pdown[state], pOverflow); +} + +/****************************************************************************/ +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ec_gain_pitch_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = state of the state machine of type Word16 + pOverflow = pointer to overflow indicator of type Flag + + Outputs: + state = pointer to a pointer to a structure containing code + state data of stucture type ec_gain_pitchState + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function: ec_gain_pitch_reset + Purpose: Resets state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int ec_gain_pitch_reset (ec_gain_pitchState *state) +{ + Word16 i; + + if (state == (ec_gain_pitchState *) NULL){ + // fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n"); + return -1; + } + + for(i = 0; i < 5; i++) + state->pbuf[i] = 1640; + state->past_gain_pit = 0; + state->prev_gp = 16384; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 ec_gain_pitch_reset(ec_gain_pitchState *state) +{ + Word16 i; + + if (state == (ec_gain_pitchState *) NULL) + { + /* fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n"); */ + return -1; + } + + for (i = 0; i < 5; i++) + state->pbuf[i] = 1640; + state->past_gain_pit = 0; + state->prev_gp = 16384; + + return 0; +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ec_gain_pitch_update +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a pointer to a structure containing code + state data of stucture type ec_gain_pitchState + bfi = flag indicating the frame is bad of type Word16 + prev_bf = flag indicating the previous frame was bad of type Word16 + gain_pitch = pointer to pitch gain of type Word16 + pOverflow = pointer to overflow indicator of type Flag + + Outputs: + state = pointer to a pointer to a structure containing code + state data of stucture type ec_gain_pitchState + gain_pitch = pointer to pitch gain of type Word16 + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : update the pitch gain concealment state; + limit gain_pitch if the previous frame was bad + Call this function always after decoding (or concealing) + the gain + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Word16 i; + + if (bfi == 0) + { + if (prev_bf != 0) + { + if (sub (*gain_pitch, st->prev_gp) > 0) + { + *gain_pitch = st->prev_gp; + } + } + st->prev_gp = *gain_pitch; + } + + st->past_gain_pit = *gain_pitch; + + if (sub (st->past_gain_pit, 16384) > 0) // if (st->past_gain_pit > 1.0) + { + st->past_gain_pit = 16384; + } + for (i = 1; i < 5; i++) + { + st->pbuf[i - 1] = st->pbuf[i]; + } + st->pbuf[4] = st->past_gain_pit; + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void ec_gain_pitch_update( + ec_gain_pitchState *st, /* i/o : state variables */ + Word16 bfi, /* i : flag: frame is bad */ + Word16 prev_bf, /* i : flag: previous frame was bad */ + Word16 *gain_pitch, /* i/o : pitch gain */ + Flag *pOverflow +) +{ + Word16 i; + + if (bfi == 0) + { + if (prev_bf != 0) + { + if (sub(*gain_pitch, st->prev_gp, pOverflow) > 0) + { + *gain_pitch = st->prev_gp; + } + } + st->prev_gp = *gain_pitch; + } + + st->past_gain_pit = *gain_pitch; + + if (sub(st->past_gain_pit, 16384, pOverflow) > 0) + /* if (st->past_gain_pit > 1.0) */ + { + st->past_gain_pit = 16384; + } + for (i = 1; i < 5; i++) + { + st->pbuf[i - 1] = st->pbuf[i]; + } + st->pbuf[4] = st->past_gain_pit; +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ec_gains.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ec_gains.h new file mode 100644 index 00000000..6a16e0fb --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ec_gains.h @@ -0,0 +1,196 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Filename: ec_gains.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : ec_gains.c + Purpose: : Error concealment for pitch and codebook gains + +------------------------------------------------------------------------------ +*/ + +#ifndef _EC_GAINS_H_ +#define _EC_GAINS_H_ +#define ec_gains_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "gc_pred.h" + + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 pbuf[5]; + Word16 past_gain_pit; + Word16 prev_gp; + } ec_gain_pitchState; + + typedef struct + { + Word16 gbuf[5]; + Word16 past_gain_code; + Word16 prev_gc; + } ec_gain_codeState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /* + * Function : ec_gain_code_reset + * Purpose : Resets state memory + * + */ + Word16 ec_gain_code_reset( + ec_gain_codeState *state + ); + + + /* + * Function : ec_gain_code + * Purpose : conceal the codebook gain + * Call this function only in BFI (instead of normal gain + * decoding function) + */ + void ec_gain_code( + ec_gain_codeState *st, /* i/o : State struct */ + gc_predState *pred_state, /* i/o : MA predictor state */ + Word16 state, /* i : state of the state machine */ + Word16 *gain_code, /* o : decoded innovation gain */ + Flag *pOverflow + ); + + /* + * Function : ec_gain_code_update + * Purpose : update the codebook gain concealment state; + * limit gain_code if the previous frame was bad + * Call this function always after decoding (or concealing) + * the gain + */ + void ec_gain_code_update( + ec_gain_codeState *st, /* i/o : State struct */ + Word16 bfi, /* i : flag: frame is bad */ + Word16 prev_bf, /* i : flag: previous frame was bad */ + Word16 *gain_code, /* i/o : decoded innovation gain */ + Flag *pOverflow + ); + + + /* + * Function: ec_gain_pitch_reset + * Purpose: Resets state memory + */ + Word16 ec_gain_pitch_reset( + ec_gain_pitchState *state + ); + + /* + * Function : ec_gain_pitch_exit + * Purpose : The memory used for state memory is freed + */ + void ec_gain_pitch_exit( + ec_gain_pitchState **state + ); + + /* + * Function : ec_gain_pitch + * Purpose : conceal the pitch gain + * Call this function only in BFI (instead of normal gain + * decoding function) + */ + void ec_gain_pitch( + ec_gain_pitchState *st, /* i/o : state variables */ + Word16 state, /* i : state of the state machine */ + Word16 *gain_pitch, /* o : pitch gain (Q14) */ + Flag *pOverflow + ); + + /* + * Function : ec_gain_pitch_update + * Purpose : update the pitch gain concealment state; + * limit gain_pitch if the previous frame was bad + * Call this function always after decoding (or concealing) + * the gain + */ + void ec_gain_pitch_update( + ec_gain_pitchState *st, /* i/o : state variables */ + Word16 bfi, /* i : flag: frame is bad */ + Word16 prev_bf, /* i : flag: previous frame was bad */ + Word16 *gain_pitch, /* i/o : pitch gain */ + Flag *pOverflow + ); + + +#ifdef __cplusplus +} +#endif + +#endif /* _EC_GAINS_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ex_ctrl.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ex_ctrl.cpp new file mode 100644 index 00000000..9fae32aa --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ex_ctrl.cpp @@ -0,0 +1,191 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: ex_ctrl.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "ex_ctrl.h" +#include "typedef.h" +#include "cnst.h" +#include "set_zero.h" +#include "gmed_n.h" +#include "sqrt_l.h" +#include "basic_op.h" +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ex_ctrl +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + excitation = pointer to current subframe excitation of type Word16 + excEnergy = Exc. Energy, sqrt(totEx*totEx) of type Word16 + exEnergyHist = pointer to history of subframe energies of type Word16 + voicedHangover = # of fr. after last voiced fr of type Word16 + carefulFlag = restrict dynamic in scaling of type Word16 + pOverflow = pointer to overflow indicator + + Outputs: + pOverflow = 1 if overflow exists in the math functions called by this function. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function : Ex_ctrl + Purpose : Charaterice synthesis speech and detect background noise + Returns : background noise decision; 0 = no bgn, 1 = bgn + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + ex_ctrl.c, 3GPP TS 26.101 version 4.1.0 Release 4, June 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 Ex_ctrl(Word16 excitation[], /*i/o: Current subframe excitation */ + Word16 excEnergy, /* i : Exc. Energy, sqrt(totEx*totEx)*/ + Word16 exEnergyHist[], /* i : History of subframe energies */ + Word16 voicedHangover, /* i : # of fr. after last voiced fr.*/ + Word16 prevBFI, /* i : Set i previous BFI */ + Word16 carefulFlag, /* i : Restrict dymamic in scaling */ + Flag *pOverflow + ) +{ + Word16 i, exp; + Word16 testEnergy, scaleFactor, avgEnergy, prevEnergy; + Word32 t0; + + /* get target level */ + avgEnergy = gmed_n(exEnergyHist, 9); + + prevEnergy = (exEnergyHist[7] + exEnergyHist[8]) >> 1; + if (exEnergyHist[8] < prevEnergy) + { + prevEnergy = exEnergyHist[8]; + } + + /* upscaling to avoid too rapid energy rises for some cases */ + if ((excEnergy < avgEnergy) && (excEnergy > 5)) + { + testEnergy = shl(prevEnergy, 2, pOverflow); /* testEnergy = 4*prevEnergy; */ + + if ((voicedHangover < 7) || prevBFI != 0) + { + /* testEnergy = 3*prevEnergy */ + testEnergy = sub(testEnergy, prevEnergy, pOverflow); + } + + if (avgEnergy > testEnergy) + { + avgEnergy = testEnergy; + } + + /* scaleFactor=avgEnergy/excEnergy in Q0 (const 29 below)*/ + exp = norm_s(excEnergy); + excEnergy = shl(excEnergy, exp, pOverflow); + excEnergy = div_s((Word16) 16383, excEnergy); + t0 = L_mult(avgEnergy, excEnergy, pOverflow); + t0 = L_shr(t0, sub(20, exp, pOverflow), pOverflow); + /* const=30 for t0 in Q0, 20 for Q10 */ + if (t0 > 32767) + { + t0 = 32767; /* saturate */ + } + scaleFactor = (Word16)(t0); + + /* test if scaleFactor > 3.0 */ + if (carefulFlag != 0 && (scaleFactor > 3072)) + { + scaleFactor = 3072; + } + + /* scale the excitation by scaleFactor */ + for (i = 0; i < L_SUBFR; i++) + { + t0 = L_mult(scaleFactor, excitation[i], pOverflow); + t0 = L_shr(t0, 11, pOverflow); + excitation[i] = (Word16)(t0); + } + } + + return 0; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ex_ctrl.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ex_ctrl.h new file mode 100644 index 00000000..8f6472ff --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ex_ctrl.h @@ -0,0 +1,122 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: ex_ctrl.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : ex_ctrl.h + Purpose : Excitation Control module in background noise + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef ex_ctrl_h +#define ex_ctrl_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define L_ENERGYHIST 60 + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + /* + * Function : Ex_ctrl + * Purpose : Charaterice synthesis speech and detect background noise + * Returns : background noise decision; 0 = bgn, 1 = no bgn + */ + Word16 Ex_ctrl(Word16 excitation[], /*i/o: Current subframe excitation */ + Word16 excEnergy, /* i : Exc. Energy, sqrt(totEx*totEx)*/ + Word16 exEnergyHist[], /* i : History of subframe energies */ + Word16 voicedHangover, /* i : # of fr. after last voiced fr.*/ + Word16 prevBFI, /* i : Set i previous BFI */ + Word16 carefulFlag, /* i : Restrict dymamic in scaling */ + Flag *pOverflow + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _ex_ctrl_h_ */ + + + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/gsmamr_dec.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/gsmamr_dec.h new file mode 100644 index 00000000..4b43c9b7 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/gsmamr_dec.h @@ -0,0 +1,150 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: gsmamr_dec.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This header contains all the necessary information needed to allow the gsm amr + decoder library to be used properly upon release. + +------------------------------------------------------------------------------ +*/ +#ifndef _GSMAMR_DEC_H_ +#define _GSMAMR_DEC_H_ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "gsm_amr_typedefs.h" +#include "pvamrnbdecoder_api.h" +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ----------------------------------------------------------------------------*/ + /* Number of 13-bit linear PCM samples per 20 ms frame */ + /* L_FRAME = (8 kHz) * (20 msec) = 160 samples */ +#define L_FRAME 160 + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + enum Frame_Type_3GPP + { + AMR_475 = 0, /* 4.75 kbps */ + AMR_515, /* 5.15 kbps */ + AMR_59, /* 5.9 kbps */ + AMR_67, /* 6.7 kbps */ + AMR_74, /* 7.4 kbps */ + AMR_795, /* 7.95 kbps */ + AMR_102, /* 10.2 kbps */ + AMR_122, /* 12.2 kbps */ + AMR_SID, /* GSM AMR DTX */ + GSM_EFR_SID, /* GSM EFR DTX */ + TDMA_EFR_SID, /* TDMA EFR DTX */ + PDC_EFR_SID, /* PDC EFR DTX */ + FOR_FUTURE_USE1, /* Unused 1 */ + FOR_FUTURE_USE2, /* Unused 2 */ + FOR_FUTURE_USE3, /* Unused 3 */ + AMR_NO_DATA + }; /* No data */ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ----------------------------------------------------------------------------*/ + /* + * This function allocates memory for filter structure and initializes state + * memory used by the GSM AMR decoder. This function returns zero. It will + * return negative one if there is an error. + */ + Word16 GSMInitDecode(void **state_data, + Word8 *id); + + /* + * AMRDecode steps into the part of the library that decodes the raw data + * speech bits for the decoding process. It returns the address offset of + * the next frame to be decoded. + */ + Word16 AMRDecode( + void *state_data, + enum Frame_Type_3GPP frame_type, + UWord8 *speech_bits_ptr, + Word16 *raw_pcm_buffer, + Word16 input_format + ); + + /* + * This function resets the state memory used by the GSM AMR decoder. This + * function returns zero. It will return negative one if there is an error. + */ + Word16 Speech_Decode_Frame_reset(void *state_data); + + /* + * This function frees up the memory used for the state memory of the + * GSM AMR decoder. + */ + void GSMDecodeFrameExit(void **state_data); + + +#ifdef __cplusplus +} +#endif + +#endif /* _GSMAMR_DEC_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/if2_to_ets.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/if2_to_ets.cpp new file mode 100644 index 00000000..6463becc --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/if2_to_ets.cpp @@ -0,0 +1,183 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Filename: if2_to_ets.cpp + Funtions: if2_to_ets + +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "frame_type_3gpp.h" +#include "if2_to_ets.h" +#include "typedef.h" +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: if2_to_ets +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + frame_type_3gpp = decoder speech bit rate (enum Frame_Type_3GPP) + if2_input_ptr = pointer to input encoded speech bits in IF2 format (Word8) + ets_output_ptr = pointer to output encoded speech bits in ETS format (Word16) + + Outputs: + ets_output_ptr = pointer to encoded speech bits in the ETS format (Word16) + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs a transformation on the data buffers. It converts the + data format from IF2 to ETS. IF2 is the storage format where the frame type + is in the first four bits of the first byte. The upper four bits of that byte + contain the first four encoded speech bits for the frame. The following bytes + contain the rest of the encoded speech bits. The final byte has padded zeros + to make the frame byte aligned. ETS format has the encoded speech + bits each separate with only one bit stored in each word. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + +AMR Speech Codec Frame Structure", 3GPP TS 26.101 version 4.1.0 Release 4, June 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void if2_to_ets( + enum Frame_Type_3GPP frame_type_3gpp, + UWord8 *if2_input_ptr, + Word16 *ets_output_ptr, + CommonAmrTbls* common_amr_tbls) +{ + + Word16 i; + Word16 j; + Word16 x = 0; + const Word16* numCompressedBytes_ptr = common_amr_tbls->numCompressedBytes_ptr; + const Word16* numOfBits_ptr = common_amr_tbls->numOfBits_ptr; + const Word16* const* reorderBits_ptr = common_amr_tbls->reorderBits_ptr; + + /* + * The following section of code accesses bits in the IF2 method of + * bit ordering. Each bit is given its own location in the buffer pointed + * to by ets_output_ptr. The bits (for modes less than AMR_SID) are + * reordered using the tables in bitreorder.c before the data is stored + * into the buffer pointed to by ets_output_ptr. + */ + + if (frame_type_3gpp < AMR_SID) + { + for (j = 4; j < 8; j++) + { + ets_output_ptr[reorderBits_ptr[frame_type_3gpp][x++]] = + (if2_input_ptr[0] >> j) & 0x01; + } + for (i = 1; i < numCompressedBytes_ptr[frame_type_3gpp]; i++) + { + for (j = 0; j < 8; j++) + { + if (x >= numOfBits_ptr[frame_type_3gpp]) + { + break; + } + ets_output_ptr[reorderBits_ptr[frame_type_3gpp][x++]] = + (if2_input_ptr[i] >> j) & 0x01; + } + } + } + else + { + for (j = 4; j < 8; j++) + { + ets_output_ptr[x++] = + (if2_input_ptr[0] >> j) & 0x01; + } + for (i = 1; i < numCompressedBytes_ptr[frame_type_3gpp]; i++) + { + for (j = 0; j < 8; j++) + { + ets_output_ptr[x++] = + (if2_input_ptr[i] >> j) & 0x01; + } + } + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/if2_to_ets.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/if2_to_ets.h new file mode 100644 index 00000000..49949914 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/if2_to_ets.h @@ -0,0 +1,111 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: if2_to_ets.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the if2_to_ets function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef IF2_TO_ETS_H +#define IF2_TO_ETS_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "frame_type_3gpp.h" +#include "typedef.h" +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void if2_to_ets(enum Frame_Type_3GPP frame_type_3gpp, + UWord8 *if2_input_ptr, + Word16 *ets_output_ptr, + CommonAmrTbls* common_amr_tbls); + + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/int_lsf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/int_lsf.cpp new file mode 100644 index 00000000..e50eb6c0 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/int_lsf.cpp @@ -0,0 +1,270 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: int_lsf.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "int_lsf.h" +#include "typedef.h" +#include "basic_op.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Int_lsf +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lsf_old = LSF vector at the 4th SF of past frame (Word16) + lsf_new = LSF vector at the 4th SF of present frame (Word16) + i_subfr = Current subframe (equal to 0,40,80 or 120) (Word16) + lsf_out = interpolated LSF parameters for current subframe (Word16) + + Outputs: + lsf_out = new interpolated LSF parameters for current subframe + pOverflow = pointer of type Flag * to overflow indicator. + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function interpolates the LSFs for selected subframe. + The 20 ms speech frame is divided into 4 subframes. The LSFs are + interpolated at the 1st, 2nd and 3rd subframe and only forwarded + at the 4th subframe. + + |------|------|------|------| + sf1 sf2 sf3 sf4 + F0 F1 + + sf1: 3/4 F0 + 1/4 F1 sf3: 1/4 F0 + 3/4 F1 + sf2: 1/2 F0 + 1/2 F1 sf4: F1 + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + int_lsf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Int_lsf( + Word16 lsf_old[], // i : LSF vector at the 4th SF of past frame + Word16 lsf_new[], // i : LSF vector at the 4th SF of present frame + Word16 i_subfr, // i : Pointer to current sf (equal to 0,40,80 or 120) + Word16 lsf_out[] // o : interpolated LSF parameters for current sf +) +{ + Word16 i; + + if ( i_subfr == 0 ) + { + for (i = 0; i < M; i++) { + lsf_out[i] = add(sub(lsf_old[i], shr(lsf_old[i], 2)), + shr(lsf_new[i], 2)); + } + } + else if ( sub(i_subfr, 40) == 0 ) + { + for (i = 0; i < M; i++) { + lsf_out[i] = add(shr(lsf_old[i],1), shr(lsf_new[i], 1) ); + } + } + else if ( sub(i_subfr, 80) == 0 ) + { + for (i = 0; i < M; i++) { + lsf_out[i] = add(shr(lsf_old[i], 2), + sub(lsf_new[i], shr(lsf_new[i], 2))); + } + } + else if ( sub(i_subfr, 120) == 0 ) + { + for (i = 0; i < M; i++) { + lsf_out[i] = lsf_new[i]; + } + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void Int_lsf( + Word16 lsf_old[], /* i : LSF vector at the 4th SF of past frame */ + Word16 lsf_new[], /* i : LSF vector at the 4th SF of present frame */ + Word16 i_subfr, /* i : Current sf (equal to 0,40,80 or 120) */ + Word16 lsf_out[], /* o : interpolated LSF parameters for current sf */ + Flag *pOverflow /* o : flag set if overflow occurs */ +) +{ + register Word16 i; + register Word16 temp1; + register Word16 temp2; + + if (i_subfr == 0) + { + for (i = M - 1; i >= 0; i--) + { + if (*(lsf_old + i) < 0) + { + temp1 = ~(~(*(lsf_old + i)) >> 2); + } + else + { + temp1 = *(lsf_old + i) >> 2; + } + if (*(lsf_new + i) < 0) + { + temp2 = ~(~(*(lsf_new + i)) >> 2); + } + else + { + temp2 = *(lsf_new + i) >> 2; + } + *(lsf_out + i) = add_16((Word16)(*(lsf_old + i) - temp1), + (Word16)temp2, + pOverflow); + } + } + + else if (i_subfr == 40) + { + for (i = M - 1; i >= 0; i--) + { + if (*(lsf_old + i) < 0) + { + temp1 = ~(~(*(lsf_old + i)) >> 1); + } + else + { + temp1 = *(lsf_old + i) >> 1; + } + if (*(lsf_new + i) < 0) + { + temp2 = ~(~(*(lsf_new + i)) >> 1); + } + else + { + temp2 = *(lsf_new + i) >> 1; + } + *(lsf_out + i) = temp1 + temp2; + } + } + + else if (i_subfr == 80) + { + for (i = M - 1; i >= 0; i--) + { + if (*(lsf_old + i) < 0) + { + temp1 = ~(~(*(lsf_old + i)) >> 2); + } + else + { + temp1 = *(lsf_old + i) >> 2; + } + if (*(lsf_new + i) < 0) + { + temp2 = ~(~(*(lsf_new + i)) >> 2); + } + else + { + temp2 = *(lsf_new + i) >> 2; + } + *(lsf_out + i) = add_16((Word16)temp1, + (Word16)(*(lsf_new + i) - temp2), + pOverflow); + + } + } + + else if (i_subfr == 120) + { + for (i = M - 1; i >= 0; i--) + { + *(lsf_out + i) = *(lsf_new + i); + } + } + + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/lsp_avg.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/lsp_avg.cpp new file mode 100644 index 00000000..2850d6e2 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/lsp_avg.cpp @@ -0,0 +1,250 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: lsp_avg.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + LSP averaging and history +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "lsp_avg.h" +#include "basic_op.h" +#include "oper_32b.h" +#include "oscl_mem.h" +#include "q_plsf_5_tbl.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: lsp_avg_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to structure of type lsp_avgState + + Outputs: + fields of the structure pointed to by state are initialized. + + Returns: + return_value = 0, if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + +lsp_avg.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int lsp_avg_reset (lsp_avgState *st) +{ + if (st == (lsp_avgState *) NULL){ + // fprintf(stderr, "lsp_avg_reset: invalid parameter\n"); + return -1; + } + + Copy(mean_lsf, &st->lsp_meanSave[0], M); + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 lsp_avg_reset(lsp_avgState *st, const Word16* mean_lsf_5_ptr) +{ + if (st == (lsp_avgState *) NULL) + { + /* fprintf(stderr, "lsp_avg_reset: invalid parameter\n"); */ + return -1; + } + + oscl_memmove((void *)&st->lsp_meanSave[0], mean_lsf_5_ptr, M*sizeof(*mean_lsf_5_ptr)); + + return 0; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: lsp_avg +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to structure of type lsp_avgState + lsp = pointer to Word16, which reflects the state of the state machine + + Outputs: + st = pointer to structure of type lsp_avgState + pOverflow = pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + +lsp_avg.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +void lsp_avg ( + lsp_avgState *st, // i/o : State struct Q15 + Word16 *lsp // i : state of the state machine Q15 +) +{ + Word16 i; + Word32 L_tmp; // Q31 + + for (i = 0; i < M; i++) { + + // mean = 0.84*mean + L_tmp = L_deposit_h(st->lsp_meanSave[i]); + L_tmp = L_msu(L_tmp, EXPCONST, st->lsp_meanSave[i]); + + // Add 0.16 of newest LSPs to mean + L_tmp = L_mac(L_tmp, EXPCONST, lsp[i]); + + // Save means + st->lsp_meanSave[i] = pv_round(L_tmp); // Q15 + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void lsp_avg( + lsp_avgState *st, /* i/o : State struct Q15 */ + Word16 *lsp, /* i : state of the state machine Q15 */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word32 L_tmp; /* Q31 */ + + for (i = 0; i < M; i++) + { + + /* mean = 0.84*mean */ + L_tmp = ((Word32)st->lsp_meanSave[i] << 16); + L_tmp = L_msu(L_tmp, EXPCONST, st->lsp_meanSave[i], pOverflow); + + /* Add 0.16 of newest LSPs to mean */ + L_tmp = L_mac(L_tmp, EXPCONST, lsp[i], pOverflow); + + /* Save means */ + st->lsp_meanSave[i] = pv_round(L_tmp, pOverflow); /* Q15 */ + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/lsp_avg.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/lsp_avg.h new file mode 100644 index 00000000..4b45b961 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/lsp_avg.h @@ -0,0 +1,120 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: lsp_avg.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the lsp_avg.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef lsp_avg_h +#define lsp_avg_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define EXPCONST 5243 /* 0.16 in Q15 */ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 lsp_meanSave[M]; /* Averaged LSPs saved for efficiency */ + } lsp_avgState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + Word16 lsp_avg_reset( + lsp_avgState *state, + const Word16* mean_lsf_5_ptr + ); + + + void lsp_avg( + lsp_avgState *st, /* i/o : State struct Q15 */ + Word16 *lsp, /* i : LSP vector Q15 */ + Flag *pOverflow /* o : Flag set when overflow occurs */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _LSP_LSF_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ph_disp.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ph_disp.cpp new file mode 100644 index 00000000..22fe3b54 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ph_disp.cpp @@ -0,0 +1,796 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: ph_disp.cpp + Functions: + ph_disp_reset + ph_disp_lock + ph_disp_release + ph_disp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the function that performs adaptive phase dispersion of + the excitation signal. The phase dispersion initialization, reset, and + exit functions are included in this file, as well as, the phase dispersion + lock and release functions. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "ph_disp.h" +#include "typedef.h" +#include "basic_op.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ph_disp_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a structure of type ph_dispState + + Outputs: + Structure pointed to by state is initialized to zeros + + Returns: + return_value = 0, if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function resets the variables used by the phase dispersion function. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + ph_disp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int ph_disp_reset (ph_dispState *state) +{ + Word16 i; + + if (state == (ph_dispState *) NULL){ + fprint(stderr, "ph_disp_reset: invalid parameter\n"); + return -1; + } + for (i=0; igainMem[i] = 0; + } + state->prevState = 0; + state->prevCbGain = 0; + state->lockFull = 0; + state->onset = 0; // assume no onset in start + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 ph_disp_reset(ph_dispState *state) +{ + register Word16 i; + + if (state == (ph_dispState *) NULL) + { + /* fprint(stderr, "ph_disp_reset: invalid parameter\n"); */ + return(-1); + } + for (i = 0; i < PHDGAINMEMSIZE; i++) + { + state->gainMem[i] = 0; + } + state->prevState = 0; + state->prevCbGain = 0; + state->lockFull = 0; + state->onset = 0; /* assume no onset in start */ + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ph_disp_lock +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a structure of type ph_dispState + + Outputs: + lockFull field of the structure pointed to by state is set to 1 + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function sets the lockFull flag to indicate a lock condition. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + ph_disp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void ph_disp_lock (ph_dispState *state) +{ + state->lockFull = 1; + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void ph_disp_lock(ph_dispState *state) +{ + state->lockFull = 1; + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ph_disp_release +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a structure of type ph_dispState + + Outputs: + lockFull field of the structure pointed to by state is set to 0 + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function clears the lockFull flag to indicate an unlocked state. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + ph_disp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void ph_disp_release (ph_dispState *state) +{ + state->lockFull = 0; + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void ph_disp_release(ph_dispState *state) +{ + state->lockFull = 0; + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ph_disp +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a structure of type ph_dispState + mode = codec mode (enum Mode) + x = LTP excitation signal buffer (Word16) + cbGain = codebook gain (Word16) + ltpGain = LTP gain (Word16) + inno = innovation buffer (Word16) + pitch_fac = pitch factor used to scale the LTP excitation (Word16) + tmp_shift = shift factor applied to sum of scaled LTP excitation and + innovation before rounding (Word16) + pOverflow = pointer to overflow indicator (Flag) + + Outputs: + structure pointed to by state contains the updated gainMem array, + prevState, prevCbGain, and onset fields + x buffer contains the new excitation signal + inno buffer contains the new innovation signal + pOverflow -> 1 if there is overflow + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs adaptive phase dispersion, i.e., forming of total + excitation for the synthesis part of the decoder. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + ph_disp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void ph_disp ( + ph_dispState *state, // i/o : State struct + enum Mode mode, // i : codec mode + Word16 x[], // i/o Q0 : in: LTP excitation signal + // out: total excitation signal + Word16 cbGain, // i Q1 : Codebook gain + Word16 ltpGain, // i Q14 : LTP gain + Word16 inno[], // i/o Q13 : Innovation vector (Q12 for 12.2) + Word16 pitch_fac, // i Q14 : pitch factor used to scale the + LTP excitation (Q13 for 12.2) + Word16 tmp_shift // i Q0 : shift factor applied to sum of + scaled LTP ex & innov. before + rounding +) +{ + Word16 i, i1; + Word16 tmp1; + Word32 L_temp; + Word16 impNr; // indicator for amount of disp./filter used + + Word16 inno_sav[L_SUBFR]; + Word16 ps_poss[L_SUBFR]; + Word16 j, nze, nPulse, ppos; + const Word16 *ph_imp; // Pointer to phase dispersion filter + + // Update LTP gain memory + for (i = PHDGAINMEMSIZE-1; i > 0; i--) + { + state->gainMem[i] = state->gainMem[i-1]; + } + state->gainMem[0] = ltpGain; + + // basic adaption of phase dispersion + if (sub(ltpGain, PHDTHR2LTP) < 0) { // if (ltpGain < 0.9) + if (sub(ltpGain, PHDTHR1LTP) > 0) + { // if (ltpGain > 0.6 + impNr = 1; // medium dispersion + } + else + { + impNr = 0; // maximum dispersion + } + } + else + { + impNr = 2; // no dispersion + } + + // onset indicator + // onset = (cbGain > onFact * cbGainMem[0]) + tmp1 = pv_round(L_shl(L_mult(state->prevCbGain, ONFACTPLUS1), 2)); + if (sub(cbGain, tmp1) > 0) + { + state->onset = ONLENGTH; + } + else + { + if (state->onset > 0) + { + state->onset = sub (state->onset, 1); + } + } + + // if not onset, check ltpGain buffer and use max phase dispersion if + half or more of the ltpGain-parameters say so + if (state->onset == 0) + { + // Check LTP gain memory and set filter accordingly + i1 = 0; + for (i = 0; i < PHDGAINMEMSIZE; i++) + { + if (sub(state->gainMem[i], PHDTHR1LTP) < 0) + { + i1 = add (i1, 1); + } + } + if (sub(i1, 2) > 0) + { + impNr = 0; + } + + } + // Restrict decrease in phase dispersion to one step if not onset + if ((sub(impNr, add(state->prevState, 1)) > 0) && (state->onset == 0)) + { + impNr = sub (impNr, 1); + } + // if onset, use one step less phase dispersion + if((sub(impNr, 2) < 0) && (state->onset > 0)) + { + impNr = add (impNr, 1); + } + + // disable for very low levels + if(sub(cbGain, 10) < 0) + { + impNr = 2; + } + + if(sub(state->lockFull, 1) == 0) + { + impNr = 0; + } + + // update static memory + state->prevState = impNr; + state->prevCbGain = cbGain; + + // do phase dispersion for all modes but 12.2 and 7.4; + // don't modify the innovation if impNr >=2 (= no phase disp) + if (sub(mode, MR122) != 0 && + sub(mode, MR102) != 0 && + sub(mode, MR74) != 0 && + sub(impNr, 2) < 0) + { + // track pulse positions, save innovation, + and initialize new innovation + nze = 0; + for (i = 0; i < L_SUBFR; i++) + { + if (inno[i] != 0) + { + ps_poss[nze] = i; + nze = add (nze, 1); + } + inno_sav[i] = inno[i]; + inno[i] = 0; + } + // Choose filter corresponding to codec mode and dispersion criterium + if (sub (mode, MR795) == 0) + { + if (impNr == 0) + { + ph_imp = ph_imp_low_MR795; + } + else + { + ph_imp = ph_imp_mid_MR795; + } + } + else + { + if (impNr == 0) + { + ph_imp = ph_imp_low; + } + else + { + ph_imp = ph_imp_mid; + } + } + + // Do phase dispersion of innovation + for (nPulse = 0; nPulse < nze; nPulse++) + { + ppos = ps_poss[nPulse]; + + // circular convolution with impulse response + j = 0; + for (i = ppos; i < L_SUBFR; i++) + { + // inno[i1] += inno_sav[ppos] * ph_imp[i1-ppos] + tmp1 = mult(inno_sav[ppos], ph_imp[j++]); + inno[i] = add(inno[i], tmp1); + } + + for (i = 0; i < ppos; i++) + { + // inno[i] += inno_sav[ppos] * ph_imp[L_SUBFR-ppos+i] + tmp1 = mult(inno_sav[ppos], ph_imp[j++]); + inno[i] = add(inno[i], tmp1); + } + } + } + + // compute total excitation for synthesis part of decoder + // (using modified innovation if phase dispersion is active) + for (i = 0; i < L_SUBFR; i++) + { + // x[i] = gain_pit*x[i] + cbGain*code[i]; + L_temp = L_mult ( x[i], pitch_fac); + // 12.2: Q0 * Q13 + // 7.4: Q0 * Q14 + L_temp = L_mac (L_temp, inno[i], cbGain); + // 12.2: Q12 * Q1 + // 7.4: Q13 * Q1 + L_temp = L_shl (L_temp, tmp_shift); // Q16 + x[i] = pv_round (L_temp); + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void ph_disp( + ph_dispState *state, /* i/o : State struct */ + enum Mode mode, /* i : codec mode */ + Word16 x[], /* i/o Q0 : in: LTP excitation signal */ + /* out: total excitation signal */ + Word16 cbGain, /* i Q1 : Codebook gain */ + Word16 ltpGain, /* i Q14 : LTP gain */ + Word16 inno[], /* i/o Q13 : Innovation vector (Q12 for 12.2) */ + Word16 pitch_fac, /* i Q14 : pitch factor used to scale the + LTP excitation (Q13 for 12.2) */ + Word16 tmp_shift, /* i Q0 : shift factor applied to sum of + scaled LTP ex & innov. before + rounding */ + CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of table ptrs */ + Flag *pOverflow /* i/o : oveflow indicator */ +) +{ + register Word16 i, i1; + register Word16 tmp1; + Word32 L_temp; + Word32 L_temp2; + Word16 impNr; /* indicator for amount of disp./filter used */ + + Word16 inno_sav[L_SUBFR]; + Word16 ps_poss[L_SUBFR]; + register Word16 nze, nPulse; + Word16 ppos; + const Word16 *ph_imp; /* Pointer to phase dispersion filter */ + + Word16 *p_inno; + Word16 *p_inno_sav; + Word16 *p_x; + const Word16 *p_ph_imp; + Word16 c_inno_sav; + + const Word16* ph_imp_low_MR795_ptr = common_amr_tbls->ph_imp_low_MR795_ptr; + const Word16* ph_imp_mid_MR795_ptr = common_amr_tbls->ph_imp_mid_MR795_ptr; + const Word16* ph_imp_low_ptr = common_amr_tbls->ph_imp_low_ptr; + const Word16* ph_imp_mid_ptr = common_amr_tbls->ph_imp_mid_ptr; + + /* Update LTP gain memory */ + /* Unrolled FOR loop below since PHDGAINMEMSIZE is assumed to stay */ + /* the same. */ + /* for (i = PHDGAINMEMSIZE-1; i > 0; i--) */ + /* { */ + /* state->gainMem[i] = state->gainMem[i-1]; */ + /* } */ + state->gainMem[4] = state->gainMem[3]; + state->gainMem[3] = state->gainMem[2]; + state->gainMem[2] = state->gainMem[1]; + state->gainMem[1] = state->gainMem[0]; + state->gainMem[0] = ltpGain; + + /* basic adaption of phase dispersion */ + + if (ltpGain < PHDTHR2LTP) /* if (ltpGain < 0.9) */ + { + if (ltpGain > PHDTHR1LTP) + { /* if (ltpGain > 0.6 */ + impNr = 1; /* medium dispersion */ + } + else + { + impNr = 0; /* maximum dispersion */ + } + } + else + { + impNr = 2; /* no dispersion */ + } + + /* onset indicator */ + /* onset = (cbGain > onFact * cbGainMem[0]) */ + + L_temp = ((Word32) state->prevCbGain * ONFACTPLUS1) << 1; + + /* (L_temp << 2) calculation with saturation check */ + if (L_temp > (Word32) 0X1fffffffL) + { + *pOverflow = 1; + L_temp = MAX_32; + } + else if (L_temp < (Word32) - 536870912) + { + *pOverflow = 1; + L_temp = MIN_32; + } + else + { + L_temp <<= 2; + } + + tmp1 = pv_round(L_temp, pOverflow); + + if (cbGain > tmp1) + { + state->onset = ONLENGTH; + } + else + { + + if (state->onset > 0) + { + state->onset -= 1; + } + } + + /* if not onset, check ltpGain buffer and use max phase dispersion if + half or more of the ltpGain-parameters say so */ + if (state->onset == 0) + { + /* Check LTP gain memory and set filter accordingly */ + i1 = 0; + for (i = 0; i < PHDGAINMEMSIZE; i++) + { + if (state->gainMem[i] < PHDTHR1LTP) + { + i1 += 1; + } + } + + if (i1 > 2) + { + impNr = 0; + } + } + /* Restrict decrease in phase dispersion to one step if not onset */ + if ((impNr > ((state->prevState) + 1)) && (state->onset == 0)) + { + impNr -= 1; + } + + /* if onset, use one step less phase dispersion */ + if ((impNr < 2) && (state->onset > 0)) + { + impNr += 1; + } + + /* disable for very low levels */ + if (cbGain < 10) + { + impNr = 2; + } + + if (state->lockFull == 1) + { + impNr = 0; + } + + /* update static memory */ + state->prevState = impNr; + state->prevCbGain = cbGain; + + /* do phase dispersion for all modes but 12.2 and 7.4; + don't modify the innovation if impNr >=2 (= no phase disp) */ + if ((mode != MR122) && (mode != MR102) && (mode != MR74) && (impNr < 2)) + { + /* track pulse positions, save innovation, + and initialize new innovation */ + nze = 0; + p_inno = &inno[0]; + p_inno_sav = &inno_sav[0]; + + for (i = 0; i < L_SUBFR; i++) + { + if (*(p_inno) != 0) + { + ps_poss[nze] = i; + nze += 1; + } + *(p_inno_sav++) = *(p_inno); + *(p_inno++) = 0; + } + + /* Choose filter corresponding to codec mode and dispersion criterium */ + if (mode == MR795) + { + if (impNr == 0) + { + ph_imp = ph_imp_low_MR795_ptr; + } + else + { + ph_imp = ph_imp_mid_MR795_ptr; + } + } + else + { + if (impNr == 0) + { + ph_imp = ph_imp_low_ptr; + } + else + { + ph_imp = ph_imp_mid_ptr; + } + } + + /* Do phase dispersion of innovation */ + for (nPulse = 0; nPulse < nze; nPulse++) + { + ppos = ps_poss[nPulse]; + + /* circular convolution with impulse response */ + c_inno_sav = inno_sav[ppos]; + p_inno = &inno[ppos]; + p_ph_imp = ph_imp; + + for (i = ppos; i < L_SUBFR; i++) + { + /* inno[i1] += inno_sav[ppos] * ph_imp[i1-ppos] */ + L_temp = ((Word32) c_inno_sav * *(p_ph_imp++)) >> 15; + tmp1 = (Word16) L_temp; + *(p_inno) = add_16(*(p_inno), tmp1, pOverflow); + p_inno += 1; + } + + p_inno = &inno[0]; + + for (i = 0; i < ppos; i++) + { + /* inno[i] += inno_sav[ppos] * ph_imp[L_SUBFR-ppos+i] */ + L_temp = ((Word32) c_inno_sav * *(p_ph_imp++)) >> 15; + tmp1 = (Word16) L_temp; + *(p_inno) = add_16(*(p_inno), tmp1, pOverflow); + p_inno += 1; + } + } + } + + /* compute total excitation for synthesis part of decoder + (using modified innovation if phase dispersion is active) */ + p_inno = &inno[0]; + p_x = &x[0]; + + for (i = 0; i < L_SUBFR; i++) + { + /* x[i] = gain_pit*x[i] + cbGain*code[i]; */ + L_temp = L_mult(x[i], pitch_fac, pOverflow); + /* 12.2: Q0 * Q13 */ + /* 7.4: Q0 * Q14 */ + L_temp2 = ((Word32) * (p_inno++) * cbGain) << 1; + L_temp = L_add(L_temp, L_temp2, pOverflow); + /* 12.2: Q12 * Q1 */ + /* 7.4: Q13 * Q1 */ + L_temp = L_shl(L_temp, tmp_shift, pOverflow); /* Q16 */ + *(p_x++) = pv_round(L_temp, pOverflow); + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ph_disp.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ph_disp.h new file mode 100644 index 00000000..e48aea06 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/ph_disp.h @@ -0,0 +1,173 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: ph_disp.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the Phase dispersion of excitation signal ph_disp() function. + +------------------------------------------------------------------------------ +*/ + +#ifndef PH_DISP_H +#define PH_DISP_H "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define PHDGAINMEMSIZE 5 +#define PHDTHR1LTP 9830 /* 0.6 in Q14 */ +#define PHDTHR2LTP 14746 /* 0.9 in Q14 */ +#define ONFACTPLUS1 16384 /* 2.0 in Q13 */ +#define ONLENGTH 2 + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 gainMem[PHDGAINMEMSIZE]; + Word16 prevState; + Word16 prevCbGain; + Word16 lockFull; + Word16 onset; + } ph_dispState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; + ; Function: ph_disp_reset + ; Purpose: Initializes state memory + ; + ----------------------------------------------------------------------------*/ + Word16 ph_disp_reset(ph_dispState *state); + + /*---------------------------------------------------------------------------- + ; + ; Function: ph_disp_exit + ; Purpose: The memory used for state memory is freed + ; + ----------------------------------------------------------------------------*/ + void ph_disp_exit(ph_dispState **state); + + /*---------------------------------------------------------------------------- + ; + ; Function: ph_disp_lock + ; Purpose: mark phase dispersion as locked in state struct + ; + ----------------------------------------------------------------------------*/ + void ph_disp_lock(ph_dispState *state); + + /*---------------------------------------------------------------------------- + ; + ; Function: ph_disp_release + ; Purpose: mark phase dispersion as unlocked in state struct + ; + ----------------------------------------------------------------------------*/ + + void ph_disp_release(ph_dispState *state); + + /*---------------------------------------------------------------------------- + ; + ; Function: ph_disp + ; Purpose: perform phase dispersion according to the specified codec + ; mode and computes total excitation for synthesis part + ; if decoder + ; + ----------------------------------------------------------------------------*/ + + void ph_disp( + ph_dispState *state, /* i/o : State struct */ + enum Mode mode, /* i : codec mode */ + Word16 x[], /* i/o Q0 : in: LTP excitation signal */ + /* out: total excitation signal */ + Word16 cbGain, /* i Q1 : Codebook gain */ + Word16 ltpGain, /* i Q14 : LTP gain */ + Word16 inno[], /* i/o Q13 : Innovation vector (Q12 for 12.2) */ + Word16 pitch_fac, /* i Q14 : pitch factor used to scale the + LTP excitation (Q13 for 12.2) */ + Word16 tmp_shift, /* i Q0 : shift factor applied to sum of + scaled LTP ex & innov. before + rounding */ + CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of table ptrs */ + Flag *pOverflow /* i/o : oveflow indicator */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _PH_DISP_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/post_pro.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/post_pro.cpp new file mode 100644 index 00000000..3e3f4e16 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/post_pro.cpp @@ -0,0 +1,316 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: post_pro.cpp + Functions: + Post_Process_reset + Post_Process + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the function that performs post-processing on the output + speech. Post-processing include filtering the output speech through a second + order high pass filter with cutoff frequency of 60 Hz, and up-scaling the + output speech by a factor of 2. In addition to the post-processing function + itself, a post-processing initialization function, post-processing reset + function, and post-processing exit function are also included in this file. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "post_pro.h" +#include "typedef.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* filter coefficients (fc = 60 Hz) */ +static const Word16 b[3] = {7699, -15398, 7699}; +static const Word16 a[3] = {8192, 15836, -7667}; + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Post_Process_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a structure of type Post_ProcessState + + Outputs: + structure pointed to by state will have all its fields initialized + to zero + + Returns: + return_value = 0, if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function initializes state memory to zero. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + post_pro.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Post_Process_reset (Post_ProcessState *state) +{ + if (state == (Post_ProcessState *) NULL){ + fprint(stderr, "Post_Process_reset: invalid parameter\n"); + return -1; + } + + state->y2_hi = 0; + state->y2_lo = 0; + state->y1_hi = 0; + state->y1_lo = 0; + state->x0 = 0; + state->x1 = 0; + + return 0; +} +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Post_Process_reset(Post_ProcessState *state) +{ + if (state == (Post_ProcessState *) NULL) + { + /* fprint(stderr, "Post_Process_reset: invalid parameter\n"); */ + return(-1); + } + + state->y2_hi = 0; + state->y2_lo = 0; + state->y1_hi = 0; + state->y1_lo = 0; + state->x0 = 0; + state->x1 = 0; + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Post_Process +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type Post_ProcessState + signal = buffer containing the input signal (Word16) + lg = length of the input signal (Word16) + pOverflow = pointer to overflow indicator of type Flag + + Outputs: + structure pointed to by st contains new filter input and output values + signal buffer contains the HP filtered and up-scaled input signal + pOverflow points to 1 if overflow occurs in the math functions called + else it points to 0. + + Returns: + return_value = 0 (int) + + Global Variables Used: + a = buffer containing filter coefficients + b = buffer containing filter coefficients + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs post-processing on the output speech signal. First, + the output speech goes through a second order high pass filter with a + cutoff frequency of 60 Hz. Then, the filtered output speech is multiplied + by a factor of 2. The algorithm implemented follows the following difference + equation: + + y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b[2]*x[i-2]*2 + a[1]*y[i-1] + a[2]*y[i-2]; + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + post_pro.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Post_Process ( + Post_ProcessState *st, //i/o : post process state + Word16 signal[], //i/o : signal + Word16 lg //i : length of signal + ) +{ + Word16 i, x2; + Word32 L_tmp; + + for (i = 0; i < lg; i++) + { + x2 = st->x1; + st->x1 = st->x0; + st->x0 = signal[i]; + + // y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b140[2]*x[i-2]/2 + // + a[1]*y[i-1] + a[2] * y[i-2]; + + L_tmp = Mpy_32_16 (st->y1_hi, st->y1_lo, a[1]); + L_tmp = L_add (L_tmp, Mpy_32_16 (st->y2_hi, st->y2_lo, a[2])); + L_tmp = L_mac (L_tmp, st->x0, b[0]); + L_tmp = L_mac (L_tmp, st->x1, b[1]); + L_tmp = L_mac (L_tmp, x2, b[2]); + L_tmp = L_shl (L_tmp, 2); + + //Multiplication by two of output speech with saturation. + signal[i] = pv_round(L_shl(L_tmp, 1)); + + st->y2_hi = st->y1_hi; + st->y2_lo = st->y1_lo; + L_Extract (L_tmp, &st->y1_hi, &st->y1_lo); + } + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void Post_Process( + Post_ProcessState *st, /* i/o : post process state */ + Word16 signal[], /* i/o : signal */ + Word16 lg, /* i : length of signal */ + Flag *pOverflow +) +{ + Word16 i, x2; + Word32 L_tmp; + + Word16 *p_signal; + Word16 c_a1 = a[1]; + Word16 c_a2 = a[2]; + Word16 c_b0 = b[0]; + Word16 c_b1 = b[1]; + Word16 c_b2 = b[2]; + + p_signal = &signal[0]; + + for (i = 0; i < lg; i++) + { + x2 = st->x1; + st->x1 = st->x0; + st->x0 = *(p_signal); + + /* y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b140[2]*x[i-2]/2 */ + /* + a[1]*y[i-1] + a[2] * y[i-2]; */ + + L_tmp = ((Word32) st->y1_hi) * c_a1; + L_tmp += (((Word32) st->y1_lo) * c_a1) >> 15; + L_tmp += ((Word32) st->y2_hi) * c_a2; + L_tmp += (((Word32) st->y2_lo) * c_a2) >> 15; + L_tmp += ((Word32) st->x0) * c_b0; + L_tmp += ((Word32) st->x1) * c_b1; + L_tmp += ((Word32) x2) * c_b2; + + L_tmp = L_shl(L_tmp, 3, pOverflow); + + + /* Multiplication by two of output speech with saturation. */ + + *(p_signal++) = pv_round(L_shl(L_tmp, 1, pOverflow), pOverflow); + + st->y2_hi = st->y1_hi; + st->y2_lo = st->y1_lo; + + st->y1_hi = (Word16)(L_tmp >> 16); + st->y1_lo = (Word16)((L_tmp >> 1) - ((Word32) st->y1_hi << 15)); + + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/post_pro.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/post_pro.h new file mode 100644 index 00000000..820b79ad --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/post_pro.h @@ -0,0 +1,129 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: post_pro.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : post_pro.h + Purpose : Postprocessing of output speech. + + - 2nd order high pass filtering with cut + off frequency at 60 Hz. + - Multiplication of output by two. +------------------------------------------------------------------------------ +*/ + +#ifndef _POST_PRO_H_ +#define _POST_PRO_H_ +#define post_pro_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 y2_hi; + Word16 y2_lo; + Word16 y1_hi; + Word16 y1_lo; + Word16 x0; + Word16 x1; + } Post_ProcessState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + Word16 Post_Process_reset(Post_ProcessState *st); + /* reset of Post processing state (i.e. set state memory to zero) + returns 0 on success + */ + void Post_Process_exit(Post_ProcessState **st); + /* de-initialize Post processing state (i.e. free status struct) + stores NULL in *st + */ + + void Post_Process( + Post_ProcessState *st, /* i/o : post process state */ + Word16 signal[], /* i/o : signal */ + Word16 lg, /* i : lenght of signal */ + Flag *pOverflow + ); + +#ifdef __cplusplus +} +#endif + +#endif /* _POST_PRO_H_ */ + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/preemph.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/preemph.cpp new file mode 100644 index 00000000..5f8d0e3b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/preemph.cpp @@ -0,0 +1,222 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: preemph.cpp + Functions: + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Purpose : Preemphasis filtering + Description : Filtering through 1 - g z^-1 + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "preemph.h" +#include "typedef.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: preemphasis_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- double pointer to preemphasisState + + Outputs: + st -- double ponter to preemphasisState + + Returns: + -1 if an error occurs + 0 if OK + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Initializes state memory to zero +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + preemph.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 preemphasis_reset(preemphasisState *state) +{ + if (state == (preemphasisState *) NULL) + { + /* fprintf(stderr, "preemphasis_reset: invalid parameter\n"); */ + return -1; + } + + state->mem_pre = 0; + + return 0; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: preemphasis +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- Pointer to preemphasisState -- preemphasis filter state + signal -- array of type Word16 -- input signal overwritten by the output + g -- Word16 -- preemphasis coefficient + L -- Word16 -- size of filtering + + Outputs: + st -- Pointer to preemphasisState -- preemphasis filter state + signal -- array of type Word16 -- input signal overwritten by the output + pOverflow -- pointer to type Flag -- overflow indicator + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Filtering through 1 - g z^-1 +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + preemph.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + + +void preemphasis( + preemphasisState *st, /* (i/o) : preemphasis filter state */ + Word16 *signal, /* (i/o) : input signal overwritten by the output */ + Word16 g, /* (i) : preemphasis coefficient */ + Word16 L, /* (i) : size of filtering */ + Flag *pOverflow /* (o) : overflow indicator */ +) +{ + Word16 *p1; + Word16 *p2; + Word16 temp; + Word16 temp2; + Word16 i; + + p1 = signal + L - 1; + p2 = p1 - 1; + temp = *p1; + + for (i = 0; i <= L - 2; i++) + { + temp2 = mult(g, *(p2--), pOverflow); + *p1 = sub(*p1, temp2, pOverflow); + + p1--; + } + + temp2 = mult(g, st->mem_pre, pOverflow); + + *p1 = sub(*p1, temp2, pOverflow); + + st->mem_pre = temp; + + return; +} + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/preemph.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/preemph.h new file mode 100644 index 00000000..0798731b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/preemph.h @@ -0,0 +1,124 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Filename: preemph.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the file, preemph.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef preemph_h +#define preemph_h "$Id $" + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 mem_pre; /* filter state */ + } preemphasisState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + Word16 preemphasis_reset(preemphasisState *st); + /* reset of preemphasis filter (i.e. set state memory to zero) + returns 0 on success + */ + void preemphasis_exit(preemphasisState **st); + /* de-initialize preemphasis filter (i.e. free status struct) + stores NULL in *st + */ + + void preemphasis( + preemphasisState *st, /* (i/o): preemphasis filter state */ + Word16 *signal, /* (i/o): input signal overwritten by the output */ + Word16 g, /* (i) : preemphasis coefficient */ + Word16 L, /* (i) : size of filtering */ + Flag *pOverflow /* (o) : overflow indicator */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* preemph_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pstfilt.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pstfilt.cpp new file mode 100644 index 00000000..479ded78 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pstfilt.cpp @@ -0,0 +1,506 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pstfilt.cpp + Functions: + Post_Filter_reset + Post_Filter + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the function that performs adaptive post-filtering on the + synthesized speech. It also contains the functions that initialize, reset, + and exit the post-filtering function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "pstfilt.h" +#include "typedef.h" +#include "mode.h" +#include "basicop_malloc.h" +#include "basic_op.h" +#include "weight_a.h" +#include "residu.h" +#include "syn_filt.h" +#include "preemph.h" +#include "cnst.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define L_H 22 /* size of truncated impulse response of A(z/g1)/A(z/g2) */ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* Spectral expansion factors */ +static const Word16 gamma3_MR122[M] = +{ + 22938, 16057, 11240, 7868, 5508, + 3856, 2699, 1889, 1322, 925 +}; + +static const Word16 gamma3[M] = +{ + 18022, 9912, 5451, 2998, 1649, 907, 499, 274, 151, 83 +}; + +static const Word16 gamma4_MR122[M] = +{ + 24576, 18432, 13824, 10368, 7776, + 5832, 4374, 3281, 2461, 1846 +}; + +static const Word16 gamma4[M] = +{ + 22938, 16057, 11240, 7868, 5508, 3856, 2699, 1889, 1322, 925 +}; + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Post_Filter_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to structure of type Post_FilterState + + Outputs: + fields of the structure pointed to by state is initialized to zero + + Returns: + return_value = 0, if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function initializes the state memory used by the Post_Filter function + to zero. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pstfilt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Post_Filter_reset (Post_FilterState *state) +{ + if (state == (Post_FilterState *) NULL){ + fprintf(stderr, "Post_Filter_reset: invalid parameter\n"); + return -1; + } + + Set_zero (state->mem_syn_pst, M); + Set_zero (state->res2, L_SUBFR); + Set_zero (state->synth_buf, L_FRAME + M); + agc_reset(state->agc_state); + preemphasis_reset(state->preemph_state); + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Post_Filter_reset(Post_FilterState *state) +{ + if (state == (Post_FilterState *) NULL) + { + /*fprintf(stderr, "Post_Filter_reset: invalid parameter\n"); */ + return(-1); + } + + oscl_memset(state->mem_syn_pst, 0, sizeof(Word16)*M); + oscl_memset(state->res2, 0, sizeof(Word16)*L_SUBFR); + oscl_memset(state->synth_buf, 0, sizeof(Word16)*(L_FRAME + M)); + agc_reset(&(state->agc_state)); + preemphasis_reset(&(state->preemph_state)); + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Post_Filter +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type Post_FilterState + mode = AMR mode + syn = pointer to a buffer containing synthesized speech; upon + exiting this function, it will contain the post-filtered + synthesized speech + Az_4 = pointer to the interpolated LPC parameters for all subframes + pOverflow = pointer to overflow indicator of type Flag + + Outputs: + fields of the structure pointed to by st contains the updated field + values + syn buffer contains the post-filtered synthesized speech + pOverflow = 1 if overflow occurrs in the math functions called else + it is zero. + + Returns: + return_value = 0 (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs the post-filtering on the synthesized speech. The + post-filtering process is described as follows: + (1) inverse filtering of syn[] through A(z/0.7) to get res2[] + (2) tilt compensation filtering; 1 - MU*k*z^-1 + (3) synthesis filtering through 1/A(z/0.75) + (4) adaptive gain control + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pstfilt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Post_Filter ( + Post_FilterState *st, // i/o : post filter states + enum Mode mode, // i : AMR mode + Word16 *syn, // i/o : synthesis speech (postfiltered is output) + Word16 *Az_4 // i : interpolated LPC parameters in all subfr. +) +{ + *-------------------------------------------------------------------* + * Declaration of parameters * + *-------------------------------------------------------------------* + + Word16 Ap3[MP1], Ap4[MP1]; // bandwidth expanded LP parameters + Word16 *Az; // pointer to Az_4: + // LPC parameters in each subframe + Word16 i_subfr; // index for beginning of subframe + Word16 h[L_H]; + + Word16 i; + Word16 temp1, temp2; + Word32 L_tmp; + Word16 *syn_work = &st->synth_buf[M]; + + + *-----------------------------------------------------* + * Post filtering * + *-----------------------------------------------------* + + Copy (syn, syn_work , L_FRAME); + + Az = Az_4; + + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + // Find weighted filter coefficients Ap3[] and ap[4] + + if (sub(mode, MR122) == 0 || sub(mode, MR102) == 0) + { + Weight_Ai (Az, gamma3_MR122, Ap3); + Weight_Ai (Az, gamma4_MR122, Ap4); + } + else + { + Weight_Ai (Az, gamma3, Ap3); + Weight_Ai (Az, gamma4, Ap4); + } + + // filtering of synthesis speech by A(z/0.7) to find res2[] + + Residu (Ap3, &syn_work[i_subfr], st->res2, L_SUBFR); + + // tilt compensation filter + + // impulse response of A(z/0.7)/A(z/0.75) + + Copy (Ap3, h, M + 1); + Set_zero (&h[M + 1], L_H - M - 1); + Syn_filt (Ap4, h, h, L_H, &h[M + 1], 0); + + // 1st correlation of h[] + + L_tmp = L_mult (h[0], h[0]); + for (i = 1; i < L_H; i++) + { + L_tmp = L_mac (L_tmp, h[i], h[i]); + } + temp1 = extract_h (L_tmp); + + L_tmp = L_mult (h[0], h[1]); + for (i = 1; i < L_H - 1; i++) + { + L_tmp = L_mac (L_tmp, h[i], h[i + 1]); + } + temp2 = extract_h (L_tmp); + + if (temp2 <= 0) + { + temp2 = 0; + } + else + { + temp2 = mult (temp2, MU); + temp2 = div_s (temp2, temp1); + } + + preemphasis (st->preemph_state, st->res2, temp2, L_SUBFR); + + // filtering through 1/A(z/0.75) + + Syn_filt (Ap4, st->res2, &syn[i_subfr], L_SUBFR, st->mem_syn_pst, 1); + + // scale output to input + + agc (st->agc_state, &syn_work[i_subfr], &syn[i_subfr], + AGC_FAC, L_SUBFR); + + Az += MP1; + } + + // update syn_work[] buffer + + Copy (&syn_work[L_FRAME - M], &syn_work[-M], M); + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void Post_Filter( + Post_FilterState *st, /* i/o : post filter states */ + enum Mode mode, /* i : AMR mode */ + Word16 *syn, /* i/o : synthesis speech (postfiltered is output) */ + Word16 *Az_4, /* i : interpolated LPC parameters in all subfr. */ + Flag *pOverflow +) +{ + Word16 Ap3[MP1]; + Word16 Ap4[MP1]; /* bandwidth expanded LP parameters */ + Word16 *Az; /* pointer to Az_4: */ + /* LPC parameters in each subframe */ + register Word16 i_subfr; /* index for beginning of subframe */ + Word16 h[L_H]; + + register Word16 i; + Word16 temp1; + Word16 temp2; + Word32 L_tmp; + Word32 L_tmp2; + Word16 *syn_work = &st->synth_buf[M]; + + + /*-----------------------------------------------------* + * Post filtering * + *-----------------------------------------------------*/ + + oscl_memmove((void *)syn_work , syn, L_FRAME*sizeof(*syn)); + + Az = Az_4; + + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + /* Find weighted filter coefficients Ap3[] and ap[4] */ + + if (mode == MR122 || mode == MR102) + { + Weight_Ai(Az, gamma3_MR122, Ap3); + Weight_Ai(Az, gamma4_MR122, Ap4); + } + else + { + Weight_Ai(Az, gamma3, Ap3); + Weight_Ai(Az, gamma4, Ap4); + } + + /* filtering of synthesis speech by A(z/0.7) to find res2[] */ + + Residu(Ap3, &syn_work[i_subfr], st->res2, L_SUBFR); + + /* tilt compensation filter */ + + /* impulse response of A(z/0.7)/A(z/0.75) */ + + oscl_memmove((void *)h, Ap3, (M + 1)*sizeof(*Ap3)); + oscl_memset(&h[M + 1], 0, sizeof(Word16)*(L_H - M - 1)); + Syn_filt(Ap4, h, h, L_H, &h[M + 1], 0); + + /* 1st correlation of h[] */ + + L_tmp = 0; + + for (i = L_H - 1; i >= 0; i--) + { + L_tmp2 = ((Word32) h[i]) * h[i]; + + if (L_tmp2 != (Word32) 0x40000000L) + { + L_tmp2 = L_tmp2 << 1; + } + else + { + *pOverflow = 1; + L_tmp2 = MAX_32; + break; + } + + L_tmp = L_add(L_tmp, L_tmp2, pOverflow); + } + temp1 = (Word16)(L_tmp >> 16); + + L_tmp = 0; + + for (i = L_H - 2; i >= 0; i--) + { + L_tmp2 = ((Word32) h[i]) * h[i + 1]; + + if (L_tmp2 != (Word32) 0x40000000L) + { + L_tmp2 = L_tmp2 << 1; + } + else + { + *pOverflow = 1; + L_tmp2 = MAX_32; + break; + } + + L_tmp = L_add(L_tmp, L_tmp2, pOverflow); + } + temp2 = (Word16)(L_tmp >> 16); + + if (temp2 <= 0) + { + temp2 = 0; + } + else + { + L_tmp = (((Word32) temp2) * MU) >> 15; + + /* Sign-extend product */ + if (L_tmp & (Word32) 0x00010000L) + { + L_tmp = L_tmp | (Word32) 0xffff0000L; + } + temp2 = (Word16) L_tmp; + + temp2 = div_s(temp2, temp1); + } + + preemphasis(&(st->preemph_state), st->res2, temp2, L_SUBFR, pOverflow); + + /* filtering through 1/A(z/0.75) */ + + Syn_filt(Ap4, st->res2, &syn[i_subfr], L_SUBFR, st->mem_syn_pst, 1); + + /* scale output to input */ + + agc(&(st->agc_state), &syn_work[i_subfr], &syn[i_subfr], + AGC_FAC, L_SUBFR, pOverflow); + + Az += MP1; + } + + /* update syn_work[] buffer */ + + oscl_memmove((void *)&syn_work[-M], &syn_work[L_FRAME - M], M*sizeof(*syn_work)); + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pstfilt.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pstfilt.h new file mode 100644 index 00000000..bdee89cb --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pstfilt.h @@ -0,0 +1,132 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pstfilt.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : pstfilt.h + Purpose : Performs adaptive postfiltering on the synthesis + : speech + +------------------------------------------------------------------------------ +*/ + +#ifndef _PSTFILT_H_ +#define _PSTFILT_H_ +#define pstfilt_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "cnst.h" +#include "preemph.h" +#include "agc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 res2[L_SUBFR]; + Word16 mem_syn_pst[M]; + preemphasisState preemph_state; + agcState agc_state; + Word16 synth_buf[M + L_FRAME]; + } Post_FilterState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + Word16 Post_Filter_reset(Post_FilterState *st); + /* reset post filter (i.e. set state memory to zero) + returns 0 on success + */ + + void Post_Filter( + Post_FilterState *st, /* i/o : post filter states */ + enum Mode mode, /* i : AMR mode */ + Word16 *syn, /* i/o : synthesis speech (postfiltered is output) */ + Word16 *Az_4, /* i : interpolated LPC parameters in all subfr. */ + Flag *pOverflow + ); + /* filters the signal syn using the parameters in Az_4 to calculate filter + coefficients. + The filter must be set up using Post_Filter_init prior to the first call + to Post_Filter. Post_FilterState is updated to mirror the current state + of the filter + + return 0 on success + */ + +#ifdef __cplusplus +} +#endif + +#endif /* _PSTFILT_H_ */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pvgsmamrdecoder.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pvgsmamrdecoder.cpp new file mode 100644 index 00000000..95b0b473 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pvgsmamrdecoder.cpp @@ -0,0 +1,77 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ + +#include "PVGSMAMRDecoder.h" + + +///////////////////////////////////////////////////////////////////////////// +OSCL_EXPORT_REF CPVGSMAMRDecoder::CPVGSMAMRDecoder() +{ +} + + +///////////////////////////////////////////////////////////////////////////// +OSCL_EXPORT_REF CPVGSMAMRDecoder::~CPVGSMAMRDecoder() +{ + delete iDecState; + iDecState = NULL; +} + + +///////////////////////////////////////////////////////////////////////////// +OSCL_EXPORT_REF int32 CPVGSMAMRDecoder::InitDecoder(void) +{ + return GSMInitDecode(&iDecState, (int8*)"Decoder"); +} + + +///////////////////////////////////////////////////////////////////////////// +OSCL_EXPORT_REF int32 CPVGSMAMRDecoder::DecodeFrame(Frame_Type_3GPP aType, + uint8* aCompressedBlock, + uint8* aAudioBuffer, + int32 aFormat) +{ + return AMRDecode(iDecState, aType, aCompressedBlock, (Word16*)aAudioBuffer, (Word16) aFormat); +} + + +///////////////////////////////////////////////////////////////////////////// +OSCL_EXPORT_REF int32 CPVGSMAMRDecoder::ResetDecoder(void) +{ + return Speech_Decode_Frame_reset(iDecState); +} + + +///////////////////////////////////////////////////////////////////////////// +OSCL_EXPORT_REF void CPVGSMAMRDecoder::TerminateDecoder(void) +{ + GSMDecodeFrameExit(&iDecState); + iDecState = NULL; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pvgsmamrdecoder.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pvgsmamrdecoder.h new file mode 100644 index 00000000..bfdc07d8 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pvgsmamrdecoder.h @@ -0,0 +1,57 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ + +#ifndef __PVGSMAMRDECODER_H +#define __PVGSMAMRDECODER_H + +#include "oscl_base.h" + +#include "gsmamr_dec.h" + +// PVGSMAMRDecoder +class CPVGSMAMRDecoder +{ + public: + OSCL_IMPORT_REF CPVGSMAMRDecoder(); + OSCL_IMPORT_REF ~CPVGSMAMRDecoder(); + + OSCL_IMPORT_REF int32 InitDecoder(void); + OSCL_IMPORT_REF int32 DecodeFrame(Frame_Type_3GPP aType, + uint8* aCompressedBlock, + uint8* aAudioBuffer, + int32 aFormat); + OSCL_IMPORT_REF int32 ResetDecoder(void); + OSCL_IMPORT_REF void TerminateDecoder(void); + + private: + void* iDecState; +}; + +#endif + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pvgsmamrdecoder_dpi.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pvgsmamrdecoder_dpi.h new file mode 100644 index 00000000..09c778e4 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/pvgsmamrdecoder_dpi.h @@ -0,0 +1,59 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ + +#ifndef __PVGSMAMRDECODER_H +#define __PVGSMAMRDECODER_H + +#include "oscl_base.h" + +#include "gsmamr_dec.h" +#include "gsmamrdpidecoder.h" + +// PVGSMAMRDecoder +class CPVGSMAMRDecoder +{ + public: + OSCL_IMPORT_REF CPVGSMAMRDecoder(); + OSCL_IMPORT_REF ~CPVGSMAMRDecoder(); + + OSCL_IMPORT_REF int32 InitDecoder(void); + OSCL_IMPORT_REF int32 DecodeFrame(Frame_Type_3GPP aType, + uint8* aCompressedBlock, + uint8* aAudioBuffer, + int32 aFormat); + OSCL_IMPORT_REF int32 ResetDecoder(void); + OSCL_IMPORT_REF void TerminateDecoder(void); + + private: + void* iDecState; + CPvGsmAmrDPIDecoder *iDecoder; +}; + +#endif + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/qgain475_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/qgain475_tab.cpp new file mode 100644 index 00000000..9aaafc29 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/qgain475_tab.cpp @@ -0,0 +1,405 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + + + Filename: qgain475_tab.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "qgain475_tab.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + + /* The table contains the following data: + * + * g_pitch(0) (Q14) // for sub- + * g_fac(0) (Q12) // frame 0 and 2 + * g_pitch(1) (Q14) // for sub- + * g_fac(2) (Q12) // frame 1 and 3 + * + */ + const Word16 table_gain_MR475[MR475_VQ_SIZE*4] = + { + /*g_pit(0), g_fac(0), g_pit(1), g_fac(1) */ + 812, 128, 542, 140, + 2873, 1135, 2266, 3402, + 2067, 563, 12677, 647, + 4132, 1798, 5601, 5285, + 7689, 374, 3735, 441, + 10912, 2638, 11807, 2494, + 20490, 797, 5218, 675, + 6724, 8354, 5282, 1696, + 1488, 428, 5882, 452, + 5332, 4072, 3583, 1268, + 2469, 901, 15894, 1005, + 14982, 3271, 10331, 4858, + 3635, 2021, 2596, 835, + 12360, 4892, 12206, 1704, + 13432, 1604, 9118, 2341, + 3968, 1538, 5479, 9936, + 3795, 417, 1359, 414, + 3640, 1569, 7995, 3541, + 11405, 645, 8552, 635, + 4056, 1377, 16608, 6124, + 11420, 700, 2007, 607, + 12415, 1578, 11119, 4654, + 13680, 1708, 11990, 1229, + 7996, 7297, 13231, 5715, + 2428, 1159, 2073, 1941, + 6218, 6121, 3546, 1804, + 8925, 1802, 8679, 1580, + 13935, 3576, 13313, 6237, + 6142, 1130, 5994, 1734, + 14141, 4662, 11271, 3321, + 12226, 1551, 13931, 3015, + 5081, 10464, 9444, 6706, + 1689, 683, 1436, 1306, + 7212, 3933, 4082, 2713, + 7793, 704, 15070, 802, + 6299, 5212, 4337, 5357, + 6676, 541, 6062, 626, + 13651, 3700, 11498, 2408, + 16156, 716, 12177, 751, + 8065, 11489, 6314, 2256, + 4466, 496, 7293, 523, + 10213, 3833, 8394, 3037, + 8403, 966, 14228, 1880, + 8703, 5409, 16395, 4863, + 7420, 1979, 6089, 1230, + 9371, 4398, 14558, 3363, + 13559, 2873, 13163, 1465, + 5534, 1678, 13138, 14771, + 7338, 600, 1318, 548, + 4252, 3539, 10044, 2364, + 10587, 622, 13088, 669, + 14126, 3526, 5039, 9784, + 15338, 619, 3115, 590, + 16442, 3013, 15542, 4168, + 15537, 1611, 15405, 1228, + 16023, 9299, 7534, 4976, + 1990, 1213, 11447, 1157, + 12512, 5519, 9475, 2644, + 7716, 2034, 13280, 2239, + 16011, 5093, 8066, 6761, + 10083, 1413, 5002, 2347, + 12523, 5975, 15126, 2899, + 18264, 2289, 15827, 2527, + 16265, 10254, 14651, 11319, + 1797, 337, 3115, 397, + 3510, 2928, 4592, 2670, + 7519, 628, 11415, 656, + 5946, 2435, 6544, 7367, + 8238, 829, 4000, 863, + 10032, 2492, 16057, 3551, + 18204, 1054, 6103, 1454, + 5884, 7900, 18752, 3468, + 1864, 544, 9198, 683, + 11623, 4160, 4594, 1644, + 3158, 1157, 15953, 2560, + 12349, 3733, 17420, 5260, + 6106, 2004, 2917, 1742, + 16467, 5257, 16787, 1680, + 17205, 1759, 4773, 3231, + 7386, 6035, 14342, 10012, + 4035, 442, 4194, 458, + 9214, 2242, 7427, 4217, + 12860, 801, 11186, 825, + 12648, 2084, 12956, 6554, + 9505, 996, 6629, 985, + 10537, 2502, 15289, 5006, + 12602, 2055, 15484, 1653, + 16194, 6921, 14231, 5790, + 2626, 828, 5615, 1686, + 13663, 5778, 3668, 1554, + 11313, 2633, 9770, 1459, + 14003, 4733, 15897, 6291, + 6278, 1870, 7910, 2285, + 16978, 4571, 16576, 3849, + 15248, 2311, 16023, 3244, + 14459, 17808, 11847, 2763, + 1981, 1407, 1400, 876, + 4335, 3547, 4391, 4210, + 5405, 680, 17461, 781, + 6501, 5118, 8091, 7677, + 7355, 794, 8333, 1182, + 15041, 3160, 14928, 3039, + 20421, 880, 14545, 852, + 12337, 14708, 6904, 1920, + 4225, 933, 8218, 1087, + 10659, 4084, 10082, 4533, + 2735, 840, 20657, 1081, + 16711, 5966, 15873, 4578, + 10871, 2574, 3773, 1166, + 14519, 4044, 20699, 2627, + 15219, 2734, 15274, 2186, + 6257, 3226, 13125, 19480, + 7196, 930, 2462, 1618, + 4515, 3092, 13852, 4277, + 10460, 833, 17339, 810, + 16891, 2289, 15546, 8217, + 13603, 1684, 3197, 1834, + 15948, 2820, 15812, 5327, + 17006, 2438, 16788, 1326, + 15671, 8156, 11726, 8556, + 3762, 2053, 9563, 1317, + 13561, 6790, 12227, 1936, + 8180, 3550, 13287, 1778, + 16299, 6599, 16291, 7758, + 8521, 2551, 7225, 2645, + 18269, 7489, 16885, 2248, + 17882, 2884, 17265, 3328, + 9417, 20162, 11042, 8320, + 1286, 620, 1431, 583, + 5993, 2289, 3978, 3626, + 5144, 752, 13409, 830, + 5553, 2860, 11764, 5908, + 10737, 560, 5446, 564, + 13321, 3008, 11946, 3683, + 19887, 798, 9825, 728, + 13663, 8748, 7391, 3053, + 2515, 778, 6050, 833, + 6469, 5074, 8305, 2463, + 6141, 1865, 15308, 1262, + 14408, 4547, 13663, 4515, + 3137, 2983, 2479, 1259, + 15088, 4647, 15382, 2607, + 14492, 2392, 12462, 2537, + 7539, 2949, 12909, 12060, + 5468, 684, 3141, 722, + 5081, 1274, 12732, 4200, + 15302, 681, 7819, 592, + 6534, 2021, 16478, 8737, + 13364, 882, 5397, 899, + 14656, 2178, 14741, 4227, + 14270, 1298, 13929, 2029, + 15477, 7482, 15815, 4572, + 2521, 2013, 5062, 1804, + 5159, 6582, 7130, 3597, + 10920, 1611, 11729, 1708, + 16903, 3455, 16268, 6640, + 9306, 1007, 9369, 2106, + 19182, 5037, 12441, 4269, + 15919, 1332, 15357, 3512, + 11898, 14141, 16101, 6854, + 2010, 737, 3779, 861, + 11454, 2880, 3564, 3540, + 9057, 1241, 12391, 896, + 8546, 4629, 11561, 5776, + 8129, 589, 8218, 588, + 18728, 3755, 12973, 3149, + 15729, 758, 16634, 754, + 15222, 11138, 15871, 2208, + 4673, 610, 10218, 678, + 15257, 4146, 5729, 3327, + 8377, 1670, 19862, 2321, + 15450, 5511, 14054, 5481, + 5728, 2888, 7580, 1346, + 14384, 5325, 16236, 3950, + 15118, 3744, 15306, 1435, + 14597, 4070, 12301, 15696, + 7617, 1699, 2170, 884, + 4459, 4567, 18094, 3306, + 12742, 815, 14926, 907, + 15016, 4281, 15518, 8368, + 17994, 1087, 2358, 865, + 16281, 3787, 15679, 4596, + 16356, 1534, 16584, 2210, + 16833, 9697, 15929, 4513, + 3277, 1085, 9643, 2187, + 11973, 6068, 9199, 4462, + 8955, 1629, 10289, 3062, + 16481, 5155, 15466, 7066, + 13678, 2543, 5273, 2277, + 16746, 6213, 16655, 3408, + 20304, 3363, 18688, 1985, + 14172, 12867, 15154, 15703, + 4473, 1020, 1681, 886, + 4311, 4301, 8952, 3657, + 5893, 1147, 11647, 1452, + 15886, 2227, 4582, 6644, + 6929, 1205, 6220, 799, + 12415, 3409, 15968, 3877, + 19859, 2109, 9689, 2141, + 14742, 8830, 14480, 2599, + 1817, 1238, 7771, 813, + 19079, 4410, 5554, 2064, + 3687, 2844, 17435, 2256, + 16697, 4486, 16199, 5388, + 8028, 2763, 3405, 2119, + 17426, 5477, 13698, 2786, + 19879, 2720, 9098, 3880, + 18172, 4833, 17336, 12207, + 5116, 996, 4935, 988, + 9888, 3081, 6014, 5371, + 15881, 1667, 8405, 1183, + 15087, 2366, 19777, 7002, + 11963, 1562, 7279, 1128, + 16859, 1532, 15762, 5381, + 14708, 2065, 20105, 2155, + 17158, 8245, 17911, 6318, + 5467, 1504, 4100, 2574, + 17421, 6810, 5673, 2888, + 16636, 3382, 8975, 1831, + 20159, 4737, 19550, 7294, + 6658, 2781, 11472, 3321, + 19397, 5054, 18878, 4722, + 16439, 2373, 20430, 4386, + 11353, 26526, 11593, 3068, + 2866, 1566, 5108, 1070, + 9614, 4915, 4939, 3536, + 7541, 878, 20717, 851, + 6938, 4395, 16799, 7733, + 10137, 1019, 9845, 964, + 15494, 3955, 15459, 3430, + 18863, 982, 20120, 963, + 16876, 12887, 14334, 4200, + 6599, 1220, 9222, 814, + 16942, 5134, 5661, 4898, + 5488, 1798, 20258, 3962, + 17005, 6178, 17929, 5929, + 9365, 3420, 7474, 1971, + 19537, 5177, 19003, 3006, + 16454, 3788, 16070, 2367, + 8664, 2743, 9445, 26358, + 10856, 1287, 3555, 1009, + 5606, 3622, 19453, 5512, + 12453, 797, 20634, 911, + 15427, 3066, 17037, 10275, + 18883, 2633, 3913, 1268, + 19519, 3371, 18052, 5230, + 19291, 1678, 19508, 3172, + 18072, 10754, 16625, 6845, + 3134, 2298, 10869, 2437, + 15580, 6913, 12597, 3381, + 11116, 3297, 16762, 2424, + 18853, 6715, 17171, 9887, + 12743, 2605, 8937, 3140, + 19033, 7764, 18347, 3880, + 20475, 3682, 19602, 3380, + 13044, 19373, 10526, 23124 + }; + + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] qua_gain.tab, UMTS GSM AMR speech codec, + R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/sp_dec.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/sp_dec.cpp new file mode 100644 index 00000000..a98ef72b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/sp_dec.cpp @@ -0,0 +1,806 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: sp_dec.cpp + Functions: GSMInitDecode + Speech_Decode_Frame_reset + GSMDecodeFrameExit + GSMFrameDecode + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the functions that initialize, invoke, reset, and exit + the GSM AMR decoder. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "sp_dec.h" +#include "typedef.h" +#include "cnst.h" +#include "dec_amr.h" +#include "pstfilt.h" +#include "mode.h" +#include "post_pro.h" +#include "oscl_mem.h" +#include "bitno_tab.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Bin2int +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + no_of_bits = number of bits associated with value + bitstream = pointer to buffer where bits are read + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function : Bin2int + Purpose : Read "no_of_bits" bits from the array bitstream[] + and convert to integer. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + bits2prm.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static Word16 Bin2int ( // Reconstructed parameter + Word16 no_of_bits, // input : number of bits associated with value + Word16 *bitstream // output: address where bits are written +) +{ + Word16 value, i, bit; + + value = 0; + for (i = 0; i < no_of_bits; i++) + { + value = shl (value, 1); + bit = *bitstream++; + if (sub (bit, BIT_1) == 0) + value = add (value, 1); + } + return (value); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +static Word16 Bin2int( /* Reconstructed parameter */ + Word16 no_of_bits, /* input : number of bits associated with value */ + Word16 *bitstream /* input: address where bits are read from */ +) +{ + Word16 value; + Word16 i; + Word16 single_bit; + + value = 0; + for (i = 0; i < no_of_bits; i++) + { + value <<= 1; + single_bit = *(bitstream++); + value |= single_bit; + } + return (value); +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: bits2prm +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + mode = AMR mode of type enum Mode + bits[] = pointer to serial bits of type Word16 + prm[] = pointer to analysis parameters of type Word16 + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function : Bits2prm + Purpose : Retrieves the vector of encoder parameters from + the received serial bits in a frame. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + bits2prm.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Bits2prm ( + enum Mode mode, // i : AMR mode + Word16 bits[], // i : serial bits (size <= MAX_SERIAL_SIZE) + Word16 prm[] // o : analysis parameters (size <= MAX_PRM_SIZE) +) +{ + Word16 i; + + for (i = 0; i < prmno[mode]; i++) + { + prm[i] = Bin2int (bitno[mode][i], bits); + bits += bitno[mode][i]; + add(0,0); // account for above pointer update + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +void Bits2prm( + enum Mode mode, /* i : AMR mode */ + Word16 bits[], /* i : serial bits (size <= MAX_SERIAL_SIZE) */ + Word16 prm[], /* o : analysis parameters (size <= MAX_PRM_SIZE) */ + CommonAmrTbls* common_amr_tbls /* i : ptr to strcut of table ptrs */ +) +{ + Word16 i; + const Word16* prmno_ptr = common_amr_tbls->prmno_ptr; + const Word16* const* bitno_ptr = common_amr_tbls->bitno_ptr; + + + for (i = 0; i < prmno_ptr[mode]; i++) + { + prm[i] = Bin2int(bitno_ptr[mode][i], bits); + bits += bitno_ptr[mode][i]; + } + + return; +} + + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: GSMInitDecode +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to an array of pointers to structures of type + Speech_Decode_FrameState + no_hp_post_MR122 = flag to turn off high-pass post filter for 12.2 kbps + mode (Flag) + id = pointer to an array whose contents are of type char + + Outputs: + decoder_amrState field of the structure pointed to by the pointer pointed + to by state is set to NULL + post_state field of the structure pointed to by the pointer pointed to + by state is set to NULL + postHP_state field of the structure pointed to by the pointer pointed to + by state is set to NULL + no_hp_post_MR122 field of the structure pointed to by the pointer pointed + to by state is set to the input no_hp_post_MR122 + + Returns: + return_value = set to zero, if initialization was successful; -1, + otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function allocates memory for filter structure and initializes state + memory used by the GSM AMR decoder. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + sp_dec.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Note: Original function name of Speech_Decode_Frame_init was changed to + GSMInitDecode in the Code section. + +int Speech_Decode_Frame_init (Speech_Decode_FrameState **state, + char *id) +{ + Speech_Decode_FrameState* s; + + if (state == (Speech_Decode_FrameState **) NULL){ + fprintf(stderr, "Speech_Decode_Frame_init: invalid parameter\n"); + return -1; + } + *state = NULL; + + // allocate memory + if ((s= (Speech_Decode_FrameState *) + malloc(sizeof(Speech_Decode_FrameState))) == NULL) { + fprintf(stderr, "Speech_Decode_Frame_init: can not malloc state " + "structure\n"); + return -1; + } + s->decoder_amrState = NULL; + s->post_state = NULL; + s->postHP_state = NULL; + + if (Decoder_amr_init(&s->decoder_amrState) || + Post_Filter_init(&s->post_state) || + Post_Process_init(&s->postHP_state) ) { + Speech_Decode_Frame_exit(&s); + return -1; + } + + s->complexityCounter = getCounterId(id); + + Speech_Decode_Frame_reset(s); + *state = s; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/* fixed error +Word16 GSMInitDecode(void *state_data, + Word8 * id) +{ + Speech_Decode_FrameState* s=(Speech_Decode_FrameState*)state_data; + OSCL_UNUSED_ARG(id); + + if (state_data == NULL) + { + + return (-1); + } + // *state_data = NULL; + + + + if (Decoder_amr_init(&s->decoder_amrState) + || Post_Process_reset(&s->postHP_state)) + { + Speech_Decode_FrameState *tmp = s; + + void** tempVoid = (void**) tmp; + GSMDecodeFrameExit(tempVoid); + return (-1); + } + + + Speech_Decode_Frame_reset(s); + // *state_data = (void *)s; + + return (0); +} +*/ + +//default + +Word16 GSMInitDecode(void **state_data, + Word8 * id) +{ + Speech_Decode_FrameState* s; + OSCL_UNUSED_ARG(id); + + if (state_data == NULL) + { + + return (-1); + } + *state_data = NULL; + + // allocate memory + if ((s = (Speech_Decode_FrameState *) + oscl_malloc(sizeof(Speech_Decode_FrameState))) == NULL) + { + + return (-1); + } + + if (Decoder_amr_init(&s->decoder_amrState) + || Post_Process_reset(&s->postHP_state)) + { + Speech_Decode_FrameState *tmp = s; + + void** tempVoid = (void**) tmp; + GSMDecodeFrameExit(tempVoid); + return (-1); + } + + + Speech_Decode_Frame_reset(s); + *state_data = (void *)s; + + return (0); +} + + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Speech_Decode_Frame_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to structures of type Speech_Decode_FrameState + + Outputs: + None + + Returns: + return_value = set to zero if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function resets the state memory used by the GSM AMR decoder. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + sp_dec.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Speech_Decode_Frame_reset (Speech_Decode_FrameState *state) +{ + if (state == (Speech_Decode_FrameState *) NULL){ + fprintf(stderr, "Speech_Decode_Frame_reset: invalid parameter\n"); + return -1; + } + + Decoder_amr_reset(state->decoder_amrState, (enum Mode)0); + Post_Filter_reset(state->post_state); + Post_Process_reset(state->postHP_state); + + state->prev_mode = (enum Mode)0; + + setCounter(state->complexityCounter); + Init_WMOPS_counter(); + setCounter(0); // set counter to global counter + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 Speech_Decode_Frame_reset(void *state_data) +{ + + Speech_Decode_FrameState *state = + (Speech_Decode_FrameState *) state_data; + + if (state_data == NULL) + { + /* fprintf(stderr, "Speech_Decode_Frame_reset: + invalid parameter\n"); */ + return (-1); + } + + Decoder_amr_reset(&(state->decoder_amrState), MR475); + Post_Filter_reset(&(state->post_state)); + Post_Process_reset(&(state->postHP_state)); + + state->prev_mode = MR475; + + return (0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: GSMDecodeFrameExit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to an array of pointers to structures of type + Speech_Decode_FrameState + + Outputs: + state contents is set to NULL + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function frees up the memory used for the state memory of the GSM AMR + decoder. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + sp_dec.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Note: The original function name of Speech_Decode_Frame_exit was changed to + GSMDecodeFrameExit in the Code section. + +void Speech_Decode_Frame_exit (Speech_Decode_FrameState **state) +{ + if (state == NULL || *state == NULL) + return; + + Decoder_amr_exit(&(*state)->decoder_amrState); + Post_Filter_exit(&(*state)->post_state); + Post_Process_exit(&(*state)->postHP_state); + + setCounter((*state)->complexityCounter); + WMOPS_output(0); + setCounter(0); // set counter to global counter + + // deallocate memory + free(*state); + *state = NULL; + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + + +void GSMDecodeFrameExit(void **state_data) +{ + + Speech_Decode_FrameState **state = + (Speech_Decode_FrameState **) state_data; + + if (state == NULL || *state == NULL) + { + return; + } + + /* deallocate memory */ + // oscl_free(*state); + *state = NULL; + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: GSMFrameDecode +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to structures of type Speech_Decode_FrameState + mode = GSM AMR codec mode (enum Mode) + serial = pointer to the serial bit stream buffer (unsigned char) + frame_type = GSM AMR receive frame type (enum RXFrameType) + synth = pointer to the output synthesis speech buffer (Word16) + + Outputs: + synth contents are truncated to 13 bits if NO13BIT is not defined, + otherwise, its contents are left at 16 bits + + Returns: + return_value = set to zero (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function is the entry point to the GSM AMR decoder. The following + operations are performed on one received frame: First, the codec + parameters are parsed from the buffer pointed to by serial according to + frame_type. Then the AMR decoder is invoked via a call to Decoder_amr. Post + filtering of the decoded data is done via a call to Post_Filter function. + Lastly, the decoded data is post-processed via a call to Post_Process + function. If NO13BIT is not defined, the contents of the buffer pointed to + by synth is truncated to 13 bits. It remains unchanged otherwise. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + sp_dec.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Note: The original function name of Speech_Decode_Frame_exit was changed to + GSMFrameDecode in the Code section. + +int Speech_Decode_Frame ( + Speech_Decode_FrameState *st, // io: post filter states + enum Mode mode, // i : AMR mode + Word16 *serial, // i : serial bit stream + enum RXFrameType frame_type, // i : Frame type + Word16 *synth // o : synthesis speech (postfiltered + // output) +) +{ + Word16 parm[MAX_PRM_SIZE + 1]; // Synthesis parameters + Word16 Az_dec[AZ_SIZE]; // Decoded Az for post-filter + // in 4 subframes + +#if !defined(NO13BIT) + Word16 i; +#endif + + setCounter(st->complexityCounter); + Reset_WMOPS_counter (); // reset WMOPS counter for the new frame + + // Serial to parameters + if ((frame_type == RX_SID_BAD) || + (frame_type == RX_SID_UPDATE)) { + // Override mode to MRDTX + Bits2prm (MRDTX, serial, parm); + } else { + Bits2prm (mode, serial, parm); + } + + // Synthesis + Decoder_amr(st->decoder_amrState, mode, parm, frame_type, + synth, Az_dec); + + Post_Filter(st->post_state, mode, synth, Az_dec); // Post-filter + + // post HP filter, and 15->16 bits + Post_Process(st->postHP_state, synth, L_FRAME); + +#if !defined(NO13BIT) + // Truncate to 13 bits + for (i = 0; i < L_FRAME; i++) + { + synth[i] = synth[i] & 0xfff8; + } +#endif + + setCounter(0); // set counter to global counter + + return 0; +} + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void GSMFrameDecode( + Speech_Decode_FrameState *st, /* io: post filter states */ + enum Mode mode, /* i : AMR mode */ + Word16 *serial, /* i : serial bit stream */ + enum RXFrameType frame_type, /* i : Frame type */ + Word16 *synth) /* o : synthesis speech (postfiltered */ +/* output) */ + +{ + Word16 parm[MAX_PRM_SIZE + 1]; /* Synthesis parameters */ + Word16 Az_dec[AZ_SIZE]; /* Decoded Az for post-filter */ + /* in 4 subframes */ + Flag *pOverflow = &(st->decoder_amrState.overflow); /* Overflow flag */ + +#if !defined(NO13BIT) + Word16 i; +#endif + + /* Serial to parameters */ + if ((frame_type == RX_SID_BAD) || + (frame_type == RX_SID_UPDATE)) + { + /* Override mode to MRDTX */ + Bits2prm(MRDTX, serial, parm, &st->decoder_amrState.common_amr_tbls); + } + else + { + Bits2prm(mode, serial, parm, &st->decoder_amrState.common_amr_tbls); + } + + /* Synthesis */ + Decoder_amr( + &(st->decoder_amrState), + mode, + parm, + frame_type, + synth, + Az_dec); + + /* Post-filter */ + Post_Filter( + &(st->post_state), + mode, + synth, + Az_dec, + pOverflow); + + /* post HP filter, and 15->16 bits */ + Post_Process( + &(st->postHP_state), + synth, + L_FRAME, + pOverflow); + +#if !defined(NO13BIT) + /* Truncate to 13 bits */ + for (i = 0; i < L_FRAME; i++) + { + synth[i] = synth[i] & 0xfff8; + } +#endif + + return; +} + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/sp_dec.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/sp_dec.h new file mode 100644 index 00000000..767e8b31 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/sp_dec.h @@ -0,0 +1,116 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +***************************************************************************** +* +* GSM AMR speech codec Version 2.0.0 February 8, 1999 +* +***************************************************************************** +* +* File : sp_dec.h +* Purpose : Decoding and post filtering of one speech frame. +* + + Description: Replaced "int" and/or "char" with OSCL defined types. + +***************************************************************************** +*/ +#ifndef sp_dec_h +#define sp_dec_h "$Id $" + +/* +***************************************************************************** +* INCLUDE FILES +***************************************************************************** +*/ +#include "typedef.h" +#include "cnst.h" +#include "dec_amr.h" +#include "pstfilt.h" +#include "post_pro.h" +#include "mode.h" + +/* +***************************************************************************** +* DEFINITION OF DATA TYPES +***************************************************************************** +*/ +typedef struct +{ + Decoder_amrState decoder_amrState; + Post_FilterState post_state; + Post_ProcessState postHP_state; + enum Mode prev_mode; +} Speech_Decode_FrameState; + +/* +***************************************************************************** +* DECLARATION OF PROTOTYPES +***************************************************************************** +*/ + +#if defined(__cplusplus) +extern "C" +{ +#endif + + //error + //Word16 GSMInitDecode(void *state_data, Word8 *id); + + Word16 GSMInitDecode(void **state_data, Word8 *id); + /* initialize one instance of the speech decoder + Stores pointer to filter status struct in *st. This pointer has to + be passed to Speech_Decode_Frame in each call. + returns 0 on success + */ + + Word16 Speech_Decode_Frame_reset(void *state_data); + /* reset speech decoder (i.e. set state memory to zero) + returns 0 on success + */ + + void GSMDecodeFrameExit(void **state_data); + /* de-initialize speech decoder (i.e. free status struct) + stores NULL in *s + */ + + void GSMFrameDecode( + Speech_Decode_FrameState *st, /* io: post filter states */ + enum Mode mode, /* i : AMR mode */ + Word16 *serial, /* i : serial bit stream */ + enum RXFrameType frame_type, /* i : Frame type */ + Word16 *synth /* o : synthesis speech (postfiltered */ + /* output) */ + ); + /* return 0 on success + */ +#if defined(__cplusplus) +} +#endif +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/wmf_to_ets.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/wmf_to_ets.cpp new file mode 100644 index 00000000..c60c2cb7 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/dec/src/wmf_to_ets.cpp @@ -0,0 +1,163 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: wmf_to_ets.cpp + Functions: wmf_to_ets + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "frame_type_3gpp.h" +#include "wmf_to_ets.h" +#include "typedef.h" +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: wmf_to_ets +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + frame_type_3gpp = decoder speech bit rate (enum Frame_Type_3GPP) + wmf_input_ptr = pointer to input encoded speech bits in WMF (non-IF2) format + (Word8) + ets_output_ptr = pointer to output encoded speech bits in ETS format (Word16) + + Outputs: + ets_output_ptr = pointer to encoded speech bits in the ETS format (Word16) + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs a transformation on the data buffers. It converts the + data format from WMF (non-IF2) (Wireless Multi-media Forum) to ETS (European + Telecommunication Standard). WMF format has the encoded speech bits byte + aligned with MSB to LSB going left to right. ETS format has the encoded speech + bits each separate with only one bit stored in each word. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + +AMR Speech Codec Frame Structure", 3GPP TS 26.101 version 4.1.0 Release 4, June 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void wmf_to_ets( + enum Frame_Type_3GPP frame_type_3gpp, + UWord8 *wmf_input_ptr, + Word16 *ets_output_ptr, + CommonAmrTbls* common_amr_tbls) +{ + + Word16 i; + const Word16* const* reorderBits_ptr = common_amr_tbls->reorderBits_ptr; + const Word16* numOfBits_ptr = common_amr_tbls->numOfBits_ptr; + + /* + * The following section of code accesses bits in the WMF method of + * bit ordering. Each bit is given its own location in the buffer pointed + * to by ets_output_ptr. If the frame_type_3gpp is less than MRDTX then + * the elements are reordered within the buffer pointed to by ets_output_ptr. + */ + + if (frame_type_3gpp < AMR_SID) + { + /* The table numOfBits[] can be found in bitreorder.c. */ + for (i = numOfBits_ptr[frame_type_3gpp] - 1; i >= 0; i--) + { + /* The table reorderBits[][] can be found in bitreorder.c. */ + ets_output_ptr[reorderBits_ptr[frame_type_3gpp][i]] = + (wmf_input_ptr[i>>3] >> ((~i) & 0x7)) & 0x01; + } + } + else + { + /* The table numOfBits[] can be found in bitreorder.c. */ + for (i = numOfBits_ptr[frame_type_3gpp] - 1; i >= 0; i--) + { + ets_output_ptr[i] = (wmf_input_ptr[i>>3] >> ((~i) & 0x7)) & 0x01; + } + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/Android.mk b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/Android.mk new file mode 100644 index 00000000..a40eaf35 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/Android.mk @@ -0,0 +1,88 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + src/amrencode.cpp \ + src/autocorr.cpp \ + src/c1035pf.cpp \ + src/c2_11pf.cpp \ + src/c2_9pf.cpp \ + src/c3_14pf.cpp \ + src/c4_17pf.cpp \ + src/c8_31pf.cpp \ + src/calc_cor.cpp \ + src/calc_en.cpp \ + src/cbsearch.cpp \ + src/cl_ltp.cpp \ + src/cod_amr.cpp \ + src/convolve.cpp \ + src/cor_h.cpp \ + src/cor_h_x.cpp \ + src/cor_h_x2.cpp \ + src/corrwght_tab.cpp \ + src/div_32.cpp \ + src/dtx_enc.cpp \ + src/enc_lag3.cpp \ + src/enc_lag6.cpp \ + src/enc_output_format_tab.cpp \ + src/ets_to_if2.cpp \ + src/ets_to_wmf.cpp \ + src/g_adapt.cpp \ + src/g_code.cpp \ + src/g_pitch.cpp \ + src/gain_q.cpp \ + src/gsmamr_encoder_wrapper.cpp \ + src/hp_max.cpp \ + src/inter_36.cpp \ + src/inter_36_tab.cpp \ + src/l_abs.cpp \ + src/l_comp.cpp \ + src/l_extract.cpp \ + src/l_negate.cpp \ + src/lag_wind.cpp \ + src/lag_wind_tab.cpp \ + src/levinson.cpp \ + src/lpc.cpp \ + src/ol_ltp.cpp \ + src/p_ol_wgh.cpp \ + src/pitch_fr.cpp \ + src/pitch_ol.cpp \ + src/pre_big.cpp \ + src/pre_proc.cpp \ + src/prm2bits.cpp \ + src/q_gain_c.cpp \ + src/q_gain_p.cpp \ + src/qgain475.cpp \ + src/qgain795.cpp \ + src/qua_gain.cpp \ + src/s10_8pf.cpp \ + src/set_sign.cpp \ + src/sid_sync.cpp \ + src/sp_enc.cpp \ + src/spreproc.cpp \ + src/spstproc.cpp \ + src/ton_stab.cpp \ + src/vad1.cpp + + +LOCAL_MODULE := libpvencoder_gsmamr + +LOCAL_CFLAGS := $(PV_CFLAGS) +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := + +LOCAL_SHARED_LIBRARIES := + +LOCAL_C_INCLUDES := \ + $(PV_TOP)/codecs_v2/audio/gsm_amr/amr_nb/enc/src \ + $(PV_TOP)/codecs_v2/audio/gsm_amr/amr_nb/enc/include \ + $(PV_TOP)/codecs_v2/audio/gsm_amr/amr_nb/common/include \ + $(PV_INCLUDES) + +LOCAL_COPY_HEADERS_TO := $(PV_COPY_HEADERS_TO) + +LOCAL_COPY_HEADERS := \ + include/gsmamr_encoder_wrapper.h + +include $(BUILD_STATIC_LIBRARY) diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/build/make/local.mk b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/build/make/local.mk new file mode 100644 index 00000000..01d55d89 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/build/make/local.mk @@ -0,0 +1,84 @@ +# Get the current local path as the first operation +LOCAL_PATH := $(call get_makefile_dir) + +# Clear out the variables used in the local makefiles +include $(MK)/clear.mk + + + +TARGET := pvencoder_gsmamr + + +OPTIMIZE_FOR_PERFORMANCE_OVER_SIZE := true + +XINCDIRS += ../../../common/include + +SRCDIR := ../../src +INCSRCDIR := ../../include + +SRCS := amrencode.cpp \ + autocorr.cpp \ + c1035pf.cpp \ + c2_11pf.cpp \ + c2_9pf.cpp \ + c3_14pf.cpp \ + c4_17pf.cpp \ + c8_31pf.cpp \ + calc_cor.cpp \ + calc_en.cpp \ + cbsearch.cpp \ + cl_ltp.cpp \ + cod_amr.cpp \ + convolve.cpp \ + cor_h.cpp \ + cor_h_x.cpp \ + cor_h_x2.cpp \ + corrwght_tab.cpp \ + div_32.cpp \ + dtx_enc.cpp \ + enc_lag3.cpp \ + enc_lag6.cpp \ + enc_output_format_tab.cpp \ + ets_to_if2.cpp \ + ets_to_wmf.cpp \ + g_adapt.cpp \ + g_code.cpp \ + g_pitch.cpp \ + gain_q.cpp \ + gsmamr_encoder_wrapper.cpp \ + hp_max.cpp \ + inter_36.cpp \ + inter_36_tab.cpp \ + l_abs.cpp \ + l_comp.cpp \ + l_extract.cpp \ + l_negate.cpp \ + lag_wind.cpp \ + lag_wind_tab.cpp \ + levinson.cpp \ + lpc.cpp \ + ol_ltp.cpp \ + p_ol_wgh.cpp \ + pitch_fr.cpp \ + pitch_ol.cpp \ + pre_big.cpp \ + pre_proc.cpp \ + prm2bits.cpp \ + q_gain_c.cpp \ + q_gain_p.cpp \ + qgain475.cpp \ + qgain795.cpp \ + qua_gain.cpp \ + s10_8pf.cpp \ + set_sign.cpp \ + sid_sync.cpp \ + sp_enc.cpp \ + spreproc.cpp \ + spstproc.cpp \ + ton_stab.cpp \ + vad1.cpp + +HDRS := gsmamr_encoder_wrapper.h + +include $(MK)/library.mk + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/include/gsmamr_encoder_wrapper.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/include/gsmamr_encoder_wrapper.h new file mode 100644 index 00000000..7b54d288 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/include/gsmamr_encoder_wrapper.h @@ -0,0 +1,323 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +#ifndef __GSMAMR_ENCODER_WRAPPER_H__ +#define __GSMAMR_ENCODER_WRAPPER_H__ + +//---------------------------------------------------------------------------- +// INCLUDES +//---------------------------------------------------------------------------- +#include "oscl_base.h" + +class TInputAudioStream +{ + public: + // Pointer to buffer containing the audio samples. + // The application is required to allocate this buffer. + uint8* iSampleBuffer; + + // Number of samples in bytes contained in iSampleBuffer + int32 iSampleLength; + + // Mode of operation (the same as bit rate) + // For example, "GSM_AMR_4_75" (for 4.75 kbps) for GSM-AMR + int32 iMode; + + // Start time when samples were taken + uint64 iStartTime; + + // End time when samples were taken + uint64 iStopTime; +}; + + +class TOutputAudioStream +{ + public: + // Pointer to buffer containing encoded audio samples + uint8* iBitStreamBuffer; + + // Number of sample frames encoded and are contained in the buffer + int32 iNumSampleFrames; + + // Size in bytes of each encoded sample frame; + // This variable may point to an array if the sample frame sizes are + // variable. For example: + // iSampleFrameSize[0] = 23 (frame size of frame #1) + // iSampleFrameSize[1] = 12 (frame size of frame #2) + // . . . + // iSampleFrameSize[iNumSampleFrames] = 10 (frame size of last frame) + int32* iSampleFrameSize; + + // Start time of the encoded samples contained in the bit stream buffer + uint32 iStartTime; + + // Stop time of encoded samples contained in the bit stream buffer + uint32 iStopTime; +}; + +class TEncodeProperties +{ + public: + // ///////////////////////////////////////////// + // Input stream properties (uncompressed audio) + // ///////////////////////////////////////////// + + enum EInterleaveMode + { + EINTERLEAVE_LR, // interleaved left-right + EGROUPED_LR, // non-interleaved left-right + ENUM_INTERLEAVE_MODES // number of modes supported + }; + + // DESCRIPTION: Number of bits per sample. For example, set it to "16" + // bits for PCM. + // USAGE: The authoring application is required to fill this in. + // The CAEI uses the value for encoding. + int32 iInBitsPerSample; + + // DESCRIPTION: Sampling rate of the input samples in Hz. + // For example, set it to "22050" Hz. + // USAGE: The authoring application is required to fill this in. + // If sampling rate is not known until CAEI is initialized, + // use '0'. The CAEI uses the value for encoding. + uint32 iInSamplingRate; + + // DESCRIPTION: Clock rate or time scale to be used for the input timestamps + // (ticks per secs). For example, "22050" ticks/sec. + // USAGE: The authoring application is required to fill this in. + // If sampling rate is not known until CAEI is initialized, + // use '0'. The CAEI uses the value for encoding. + uint32 iInClockRate; + + // DESCRIPTION: Number of input channels:1=Mono,2=Stereo.(Mono uses 1 channel; + // Stereo uses 2 channels). + // USAGE: The authoring application is required to fill this in. + // The CAEI uses the value for encoding. + uint8 iInNumChannels; + + // DESCRIPTION: Whether to interleave or not the multi-channel input samples: + // EINTERLEAVE_LR = LRLRLRLRLR (interleaved left-right) + // EGROUPED_LR = LLLLLL...RRRRRR (non-interleaved left-right) + // USAGE: The authoring application is required to fill this in. + // The CAEI uses the value for encoding. + EInterleaveMode iInInterleaveMode; + + // DESCRIPTION: Desired Sampling rate for a given bitrate combination: + // For example, set it to "16000" Hz if the encoding 16kbps + // mono/stereo or 24 kbps stereo + // USAGE: The authoring application is required to fill this in. + // The CAEI uses the value for encoding. + uint32 iDesiredSamplingRate; + + public: + // //////////////////////////////////////////// + // Output stream properties (compressed audio) + // //////////////////////////////////////////// + + // DESCRIPTION: Mode of operation (the same as bit rate). For example, + // "GSM_AMR_4_75" (for 4.75 kbps). + // USAGE: The authoring application is required to fill this in. + // The CAEI uses the value to configure the codec library. + int32 iMode; + + // DESCRIPTION: Bit order format: + // TRUE = MSB..................LSB + // d7 d6 d5 d4 d3 d2 d1 d0 + // FALSE = MSB..................LSB + // d0 d1 d2 d3 d4 d5 d6 d7 + // USAGE: The authoring application is required to fill this in. + // The CAEI will use the value to setup the codec library. + int32 iBitStreamFormat; + + // DESCRIPTION: Audio object type for the output bitstream; only applies + // to AAC codec + // USAGE: The application is required to fill this in. + // The CADI will use the value to setup the codec library. + int32 iAudioObjectType; + + // DESCRIPTION: Final sampling frequency used when encoding in Hz. + // For example, "44100" Hz. + // USAGE: If the input sampling rate is not appropriate (e.g., + // the codec requires a different sampling frequency), + // the CAEI will fill this in with the final sampling + // rate. The CAEI will perform resampling if the + // input sampling frequency is not the same as the output + // sampling frequency. + uint32 iOutSamplingRate; + + // DESCRIPTION: Number of output channels:1=Mono,2=Stereo. (Mono uses 1 + // channel; Stereo uses 2 channels). + // USAGE: The CAEI will fill this in if it needs to convert + // the input samples to what is required by the codec. + uint8 iOutNumChannels; + + // DESCRIPTION: Clock rate or time scale used for the timestamps (ticks per secs) + // For example, "8000" ticks/sec. + // USAGE: The CAEI will fill this in if the input data will be + // resampled. + uint32 iOutClockRate; +}; + + + +/** +** This class encodes audio samples using the GSM-AMR algorithm. +** This codec operates on a 20-msec frame duration corresponding to 160 +** samples at the sampling frequency of 8000 samples/sec. The size of a frame +** is 320 bytes. For each 20-ms frame, a bit-rate of 4.75, 5.15, 5.90, 6.70, +** 7.40, 7.95, 10.2, or 12.2 kbits/sec can be produced. +** +** Sample usage: +** ------------ +** // create a GSM-AMR encoder object +** CGsmAmrEncoder* myAppEncoder = OSCL_NEW(CGsmAmrEncoder, ()); +** // set input parameters +** TEncodeProperties myProps; +** myProps.iInSamplingRate = 8000; +** myProps.iInBitsPerSample = 16; +** myProps.iOutBitRate = CGsmAmrEncoder::GSM_AMR_12_2; +** myAppEncoder->InitializeEncoder(myProps, 2000); +** +** // encode a sample block +** myAppEncoder->Encode(myInput, myOutput); +** +// // done encoding so cleanup +** myAppEncoder->CleanupEncoder(); +** OSCL_DELETE(myAppEncoder); +** +*/ + +class CPvGsmAmrEncoder +{ + public: + //! Constructor -- creates a GSM-AMR encoder object + OSCL_IMPORT_REF CPvGsmAmrEncoder(); + + //! Destructor -- destroys the GSM-AMR encoder object + OSCL_IMPORT_REF ~CPvGsmAmrEncoder(); + + /** + * This function initializes the GSM-AMR encoder. + * @param "aMaxOutputBufferSize" "the maximum buffer size for the output buffer when Encode() gets called" + * @param "aProps" "TEncodeProperties based pointer for the input encoding setting. if aProps=NULL, then + * default settings will be set" + * @return 0 for the correct operation, and -1 for the wrong operation + */ + OSCL_IMPORT_REF int32 InitializeEncoder(int32 aMaxOutputBufferSize, + TEncodeProperties* aProps = NULL); + + /** + * This function initializes the GSM-AMR encoder. + * @param "aInStream" "TInputAudioStream based reference object that contains the input buffer and buffer size and timestamp info" + * @param "aOutStream" "TOutputAudioStream based reference object that contains the output buffer for compressed data + * @return 0 for the correct operation, and -1 for the wrong operation + */ + OSCL_IMPORT_REF int32 Encode(TInputAudioStream& aInStream, + TOutputAudioStream& aOutStream); + + /** + * This function cleans up the encoder workspace when done encoding. + */ + OSCL_IMPORT_REF int32 CleanupEncoder(); + + /** + * This function reset the encoder workspace. + */ + OSCL_IMPORT_REF int32 Reset(); + + + public: + // GSM AMR modes + // ** values should be the same as the Mode enum specified by AMR library + enum GSM_AMR_MODES + { + GSM_AMR_4_75, + GSM_AMR_5_15, + GSM_AMR_5_90, + GSM_AMR_6_70, + GSM_AMR_7_40, + GSM_AMR_7_95, + GSM_AMR_10_2, + GSM_AMR_12_2, + GSM_AMR_DTX, + GSM_AMR_N_MODES /* number of (SPC) modes */ + }; + + private: + + /** + * This inline function checks whether the specified mode is valid or not. + * @param "aMode" "input the current mode to be used in encoding" + * @return true for the valid mode, and false for the wrong mode + */ + inline bool IsModeValid(int32 aMode) + { + return((aMode < GSM_AMR_N_MODES) && (aMode >= 0)); + } + + private: + + // GSM AMR encoder state variables + void* iEncState; + void* iSidState; + + // contains the current mode of GSM AMR + GSM_AMR_MODES iGsmAmrMode; + + // last mode used + int32 iLastModeUsed; + + // number of samples per frame (granulity) + int32 iNumSamplesPerFrame; + // number of bytes per sample + int32 iBytesPerSample; + + // maximum size allowed for output buffer + int32 iMaxOutputBufferSize; + + // bit stream format + int32 iBitStreamFormat; + +}; + +typedef enum +{ + GSMAMR_ENC_NO_ERROR = 0, + GSMAMR_ENC_NO_MEMORY_ERROR = -1, + GSMAMR_ENC_CODEC_INIT_FAILURE = -2, + GSMAMR_ENC_CODEC_NOT_INITIALIZED = -3, + GSMAMR_ENC_INVALID_PARAM = -4, + GSMAMR_ENC_INVALID_MODE = -5, + GSMAMR_ENC_CODEC_ENCODE_FAILURE = -6, + GSMAMR_ENC_MEMORY_OVERFLOW = -7 +} GSMAMR_ENC_STATUS; + +#endif // __GSMAMR_ENCODER_WRAPPER_H__ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/amrencode.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/amrencode.cpp new file mode 100644 index 00000000..51c116ef --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/amrencode.cpp @@ -0,0 +1,812 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: amrencode.cpp + Functions: AMREncode + AMREncodeInit + AMREncodeReset + AMREncodeExit + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the functions required to initialize, reset, exit, and + invoke the ETS 3GPP GSM AMR encoder. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "cnst.h" +#include "mode.h" +#include "frame_type_3gpp.h" +#include "typedef.h" + +#include "amrencode.h" +#include "ets_to_if2.h" +#include "ets_to_wmf.h" +#include "sid_sync.h" +#include "sp_enc.h" + +/*---------------------------------------------------------------------------- +; MACROS [optional] +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES [optional] +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: AMREncodeInit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pEncStructure = pointer containing the pointer to a structure used by + the encoder (void) + pSidSyncStructure = pointer containing the pointer to a structure used for + SID synchronization (void) + dtx_enable = flag to turn off or turn on DTX (Flag) + + Outputs: + None + + Returns: + init_status = 0, if initialization was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + speech_encoder_state = pointer to encoder frame structure + (Speech_Encode_FrameState) + sid_state = pointer to SID sync structure (sid_syncState) + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function initializes the GSM AMR Encoder library by calling + GSMInitEncode and sid_sync_init. If initialization was successful, + init_status is set to zero, otherwise, it is set to -1. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + // Initialize GSM AMR Encoder + CALL GSMInitEncode(state_data = &pEncStructure, + dtx = dtx_enable, + id = char_id ) + MODIFYING(nothing) + RETURNING(return_value = enc_init_status) + + // Initialize SID synchronization + CALL sid_sync_init(state = &pSidSyncStructure) + MODIFYING(nothing) + RETURNING(return_value = sid_sync_init_status) + + IF ((enc_init_status != 0) || (sid_sync_init != 0)) + THEN + init_status = -1 + + ENDIF + + MODIFY(nothing) + RETURN(init_status) + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 AMREncodeInit( + void **pEncStructure, + void **pSidSyncStructure, + Flag dtx_enable) +{ + Word16 enc_init_status = 0; + Word16 sid_sync_init_status = 0; + Word16 init_status = 0; + + /* Initialize GSM AMR Encoder */ +#ifdef CONSOLE_ENCODER_REF + /* Change to original ETS input types */ + Speech_Encode_FrameState **speech_encode_frame = + (Speech_Encode_FrameState **)(pEncStructure); + + sid_syncState **sid_sync_state = (sid_syncState **)(pSidSyncStructure); + + /* Use ETS version of sp_enc.c */ + enc_init_status = Speech_Encode_Frame_init(speech_encode_frame, + dtx_enable, + (Word8*)"encoder"); + + /* Initialize SID synchronization */ + sid_sync_init_status = sid_sync_init(sid_sync_state); + +#else + /* Use PV version of sp_enc.c */ + enc_init_status = GSMInitEncode(pEncStructure, + dtx_enable, + (Word8*)"encoder"); + + /* Initialize SID synchronization */ + sid_sync_init_status = sid_sync_init(pSidSyncStructure); + + +#endif + + if ((enc_init_status != 0) || (sid_sync_init_status != 0)) + { + init_status = -1; + } + + return(init_status); +} + + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: AMREncodeReset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pEncStructure = pointer to a structure used by the encoder (void) + pSidSyncStructure = pointer to a structure used for SID synchronization + (void) + + Outputs: + None + + Returns: + reset_status = 0, if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + speech_encoder_state = pointer to encoder frame structure + (Speech_Encode_FrameState) + sid_state = pointer to SID sync structure (sid_syncState) + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function resets the state memory used by the Encoder and SID sync + function. If reset was successful, reset_status is set to zero, otherwise, + it is set to -1. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + // Reset GSM AMR Encoder + CALL Speech_Encode_Frame_reset(state_data = pEncStructure) + MODIFYING(nothing) + RETURNING(return_value = enc_reset_status) + + // Reset SID synchronization + CALL sid_sync_reset(state = pSidSyncStructure) + MODIFYING(nothing) + RETURNING(return_value = sid_sync_reset_status) + + IF ((enc_reset_status != 0) || (sid_sync_reset_status != 0)) + THEN + reset_status = -1 + + ENDIF + + MODIFY(nothing) + RETURN(reset_status) + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 AMREncodeReset( + void *pEncStructure, + void *pSidSyncStructure) +{ + Word16 enc_reset_status = 0; + Word16 sid_sync_reset_status = 0; + Word16 reset_status = 0; + + /* Reset GSM AMR Encoder */ + enc_reset_status = Speech_Encode_Frame_reset(pEncStructure); + + + /* Reset SID synchronization */ + sid_sync_reset_status = sid_sync_reset(pSidSyncStructure); + + if ((enc_reset_status != 0) || (sid_sync_reset_status != 0)) + { + reset_status = -1; + } + + return(reset_status); +} + + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: AMREncodeExit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pEncStructure = pointer containing the pointer to a structure used by + the encoder (void) + pSidSyncStructure = pointer containing the pointer to a structure used for + SID synchronization (void) + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + speech_encoder_state = pointer to encoder frame structure + (Speech_Encode_FrameState) + sid_state = pointer to SID sync structure (sid_syncState) + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function frees up the state memory used by the Encoder and SID + synchronization function. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + // Exit GSM AMR Encoder + CALL GSMEncodeFrameExit(state_data = &pEncStructure) + MODIFYING(nothing) + RETURNING(nothing) + + // Exit SID synchronization + CALL sid_sync_exit(state = &pSidSyncStructure) + MODIFYING(nothing) + RETURNING(nothing) + + MODIFY(nothing) + RETURN(nothing) + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void AMREncodeExit( + void **pEncStructure, + void **pSidSyncStructure) +{ + /* Exit GSM AMR Encoder */ + +#ifdef CONSOLE_ENCODER_REF + /* Change to original ETS input types */ + Speech_Encode_FrameState ** speech_encode_frame = + (Speech_Encode_FrameState **)(pEncStructure); + + sid_syncState ** sid_sync_state = (sid_syncState **)(pSidSyncStructure); + + /* Use ETS version of sp_enc.c */ + Speech_Encode_Frame_exit(speech_encode_frame); + + + /* Exit SID synchronization */ + sid_sync_exit(sid_sync_state); + +#else + + /* Use PV version of sp_enc.c */ + GSMEncodeFrameExit(pEncStructure); + + /* Exit SID synchronization */ + sid_sync_exit(pSidSyncStructure); + +#endif + + return; +} + + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: AMREncode +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pEncState = pointer to encoder state structure (void) + pSidSyncState = pointer to SID sync state structure (void) + mode = codec mode (enum Mode) + pEncInput = pointer to the input speech samples (Word16) + pEncOutput = pointer to the encoded bit stream (unsigned char) + p3gpp_frame_type = pointer to the 3GPP frame type (enum Frame_Type_3GPP) + output_format = output format type (Word16); valid values are AMR_WMF, + AMR_IF2, and AMR_ETS + + Outputs: + pEncOutput buffer contains to the newly encoded bit stream + p3gpp_frame_type store contains the new 3GPP frame type + + Returns: + num_enc_bytes = number of encoded bytes for a particular + mode or -1, if an error occurred (int) + + Global Variables Used: + WmfEncBytesPerFrame = table containing the number of encoder frame + data bytes per codec mode for WMF output + format (const int) + If2EncBytesPerFrame = table containing the number of encoder frame + data bytes per codec mode for IF2 output + format (const int) + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function is the top-level entry point to the GSM AMR Encoder library. + + The following describes the encoding process for WMF or IF2 formatted output + data. This functions calls GSMEncodeFrame to encode one frame's worth of + input speech samples, and returns the newly encoded bit stream in the buffer + pointed to by pEncOutput.Then the function sid_sync is called to determine + the transmit frame type. If the transmit frame type is TX_SPEECH_GOOD or + TX_SID_FIRST or TX_SID_UPDATE, p3gpp_frame_type will be set to the encoder + used mode. For SID frames, the SID type information and mode information are + added to the encoded parameter bitstream according to the SID frame format + described in [1]. If the transmit frame type is TX_NO_DATA, the store + pointed to by p3gpp_frame_type will be set to NO_DATA. Then the output + format type (output_format) will be checked to determine the format of the + encoded data. + + If output_format is AMR_TX_WMF, the function ets_to_wmf will be called to + convert from ETS format (1 bit/word, where 1 word = 16 bits, information in + least significant bit) to WMF (aka, non-IF2). The WMF format stores the data + in octets. The least significant 4 bits of the first octet contains the 3GPP + frame type information and the most significant 4 bits are zeroed out. The + succeeding octets contain the packed encoded speech bits. The total number of + WMF bytes encoded is obtained from WmfEncBytesPerFrame table and returned via + num_enc_bytes. + + If output_format is AMR_TX_IF2, the function if2_to_ets will be called to + convert from ETS format to IF2 [1]. The IF2 format stores the data in octets. + The least significant nibble of the first octet contains the 3GPP frame type + and the most significant nibble contains the first 4 encoded speech bits. The + suceeding octets contain the packed encoded speech bits. The total number of + IF2 bytes encoded is obtained from If2EncBytesPerFrame table and returned via + num_enc_bytes. + + If output_format is AMR_TX_ETS, GSMFrameEncode is called to generate the + encoded speech parameters, then, sid_sync is called to determine the transmit + frame type. If the transmit frame type is not TX_NO_DATA, then the transmit + frame type information is saved in the first location of the ets_output_bfr, + followed by the encoded speech parameters. The codec mode information is + stored immediately after the MAX_SERIAL_SIZE encoded speech parameters. If + the transmit frame type is TX_NO_DATA, the transmit frame type, encoded + speech parameters, and codec mode are stored in the same order as before + in ets_output_bfr. However, for the no data case, the codec mode is set to + -1. + + After all the required information is generated, the 16-bit data generated + by the Encoder (in ets_output_bfr) is copied to the buffer pointed to by + pEncOutput in the little endian configuration, i.e., least significant byte, + followed by most significant byte. The num_enc_bytes is set to + 2*(MAX_SERIAL_SIZE+2). + + If output_format is invalid, this function flags the error and sets + num_enc_bytes to -1. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] "AMR Speech Codec Frame Structure", 3GPP TS 26.101 version 4.1.0 + Release 4, June 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + IF ((output_format == AMR_TX_WMF) | (output_format == AMR_TX_IF2)) + THEN + // Encode one speech frame (20 ms) + CALL GSMEncodeFrame( state_data = pEncState, + mode = mode, + new_speech = pEncInput, + serial = &ets_output_bfr[0], + usedMode = &usedMode ) + MODIFYING(nothing) + RETURNING(return_value = 0) + + // Determine transmit frame type + CALL sid_sync(st = pSidSyncState, + mode = usedMode + tx_frame_type = &tx_frame_type) + MODIFYING(nothing) + RETURNING(nothing) + + IF (tx_frame_type != TX_NO_DATA) + THEN + // There is data to transmit + *p3gpp_frame_type = (enum Frame_Type_3GPP) usedMode + + // Add SID type and mode info for SID frames + IF (*p3gpp_frame_type == AMR_SID) + THEN + // Add SID type to encoder output buffer + IF (tx_frame_type == TX_SID_FIRST) + THEN + ets_output_bfr[AMRSID_TXTYPE_BIT_OFFSET] &= 0x7f + + ELSEIF (tx_frame_type == TX_SID_UPDATE ) + THEN + ets_output_bfr[AMRSID_TXTYPE_BIT_OFFSET] |= 0x80 + + ENDIF + + // Add mode information bits + FOR i = 0 TO NUM_AMRSID_TXMODE_BITS-1 + + ets_output_bfr[AMRSID_TXMODE_BIT_OFFSET+i] = (mode>>i)&&0x0001 + + ENDFOR + + ENDIF + + ELSE + // There is no data to transmit + *p3gpp_frame_type = NO_DATA + + ENDIF + + // Determine the output format to use + IF (output_format == AMR_TX_WMF) + THEN + // Change output data format to WMF + CALL ets_to_wmf( frame_type_3gpp = *p3gpp_frame_type, + ets_input_ptr = &ets_output_bfr[0], + wmf_output_ptr = pEncOutput ) + MODIFYING(nothing) + RETURNING(nothing) + + // Set up the number of encoded WMF bytes + num_enc_bytes = WmfEncBytesPerFrame[(int) *p3gpp_frame_type] + + ELSEIF (output_format == AMR_TX_IF2) + THEN + // Change output data format to IF2 + CALL ets_to_if2( frame_type_3gpp = *p3gpp_frame_type, + ets_input_ptr = &ets_output_bfr[0], + if2_output_ptr = pEncOutput ) + MODIFYING(nothing) + RETURNING(nothing) + + // Set up the number of encoded IF2 bytes + num_enc_bytes = If2EncBytesPerFrame[(int) *p3gpp_frame_type] + + ENDIF + + ELSEIF (output_format = AMR_TX_ETS) + THEN + // Encode one speech frame (20 ms) + CALL GSMEncodeFrame( state_data = pEncState, + mode = mode, + new_speech = pEncInput, + serial = &ets_output_bfr[1], + usedMode = &usedMode ) + MODIFYING(nothing) + RETURNING(return_value = 0) + + // Save used mode + *p3gpp_frame_type = (enum Frame_Type_3GPP) usedMode + + // Determine transmit frame type + CALL sid_sync(st = pSidSyncState, + mode = usedMode + tx_frame_type = &tx_frame_type) + MODIFYING(nothing) + RETURNING(nothing) + + // Put TX frame type in output buffer + ets_output_bfr[0] = tx_frame_type + + // Put mode information after the encoded speech parameters + IF (tx_frame_type != TX_NO_DATA) + THEN + ets_output_bfr[MAX_SERIAL_SIZE+1] = mode + + ELSE + ets_output_bfr[MAX_SERIAL_SIZE+1] = -1 + + ENDIF + + // Copy output of encoder to pEncOutput buffer + ets_output_ptr = (unsigned char *) &ets_output_bfr[0] + + // Copy 16-bit data in 8-bit chunks using Little Endian configuration + FOR i = 0 TO (2*(MAX_SERIAL_SIZE+6))-1 + + *(pEncOutput+i) = *ets_output_ptr + ets_output_ptr = ets_output_ptr + 1 + + ENDFOR + + // Set up number of encoded bytes + num_enc_bytes = 2*(MAX_SERIAL_SIZE+6) + + ELSE + // Invalid output_format, set up error code + num_enc_bytes = -1 + + ENDIF + + MODIFY (nothing) + RETURN (num_enc_bytes) + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 AMREncode( + void *pEncState, + void *pSidSyncState, + enum Mode mode, + Word16 *pEncInput, + UWord8 *pEncOutput, + enum Frame_Type_3GPP *p3gpp_frame_type, + Word16 output_format +) +{ + Word16 ets_output_bfr[MAX_SERIAL_SIZE+2]; + UWord8 *ets_output_ptr; + Word16 num_enc_bytes = -1; + Word16 i; + enum TXFrameType tx_frame_type; + //enum Mode usedMode = MR475; + enum Mode usedMode = MR122; + + /* Encode WMF or IF2 frames */ + if ((output_format == AMR_TX_WMF) | (output_format == AMR_TX_IF2) + | (output_format == AMR_TX_IETF)) + { + /* Encode one speech frame (20 ms) */ + +#ifndef CONSOLE_ENCODER_REF + + /* Use PV version of sp_enc.c */ + GSMEncodeFrame(pEncState, mode, pEncInput, ets_output_bfr, &usedMode); + +#else + /* Use ETS version of sp_enc.c */ + Speech_Encode_Frame(pEncState, mode, pEncInput, ets_output_bfr, &usedMode); + +#endif + + /* Determine transmit frame type */ + sid_sync(pSidSyncState, usedMode, &tx_frame_type); + + if (tx_frame_type != TX_NO_DATA) + { + /* There is data to transmit */ + *p3gpp_frame_type = (enum Frame_Type_3GPP) usedMode; + + /* Add SID type and mode info for SID frames */ + if (*p3gpp_frame_type == AMR_SID) + { + /* Add SID type to encoder output buffer */ + if (tx_frame_type == TX_SID_FIRST) + { + ets_output_bfr[AMRSID_TXTYPE_BIT_OFFSET] &= 0x0000; + } + else if (tx_frame_type == TX_SID_UPDATE) + { + ets_output_bfr[AMRSID_TXTYPE_BIT_OFFSET] |= 0x0001; + } + + /* Add mode information bits */ + for (i = 0; i < NUM_AMRSID_TXMODE_BITS; i++) + { + ets_output_bfr[AMRSID_TXMODE_BIT_OFFSET+i] = + (mode >> i) & 0x0001; + } + } + } + else + { + /* This is no data to transmit */ + *p3gpp_frame_type = (enum Frame_Type_3GPP)AMR_NO_DATA; + } + + /* At this point, output format is ETS */ + /* Determine the output format to use */ + if (output_format == AMR_TX_IETF) + { + /* Change output data format to WMF */ + ets_to_ietf(*p3gpp_frame_type, ets_output_bfr, pEncOutput, &(((Speech_Encode_FrameState*)pEncState)->cod_amr_state->common_amr_tbls)); + + /* Set up the number of encoded WMF bytes */ + num_enc_bytes = WmfEncBytesPerFrame[(Word16) *p3gpp_frame_type]; + + } + else if (output_format == AMR_TX_WMF) + { + /* Change output data format to WMF */ + ets_to_wmf(*p3gpp_frame_type, ets_output_bfr, pEncOutput, &(((Speech_Encode_FrameState*)pEncState)->cod_amr_state->common_amr_tbls)); + + /* Set up the number of encoded WMF bytes */ + num_enc_bytes = WmfEncBytesPerFrame[(Word16) *p3gpp_frame_type]; + + } + else if (output_format == AMR_TX_IF2) + { + /* Change output data format to IF2 */ + ets_to_if2(*p3gpp_frame_type, ets_output_bfr, pEncOutput, &(((Speech_Encode_FrameState*)pEncState)->cod_amr_state->common_amr_tbls)); + + /* Set up the number of encoded IF2 bytes */ + num_enc_bytes = If2EncBytesPerFrame[(Word16) *p3gpp_frame_type]; + + } + } + + /* Encode ETS frames */ + else if (output_format == AMR_TX_ETS) + { + /* Encode one speech frame (20 ms) */ + +#ifndef CONSOLE_ENCODER_REF + + /* Use PV version of sp_enc.c */ + GSMEncodeFrame(pEncState, mode, pEncInput, &ets_output_bfr[1], &usedMode); + +#else + /* Use ETS version of sp_enc.c */ + Speech_Encode_Frame(pEncState, mode, pEncInput, &ets_output_bfr[1], &usedMode); + +#endif + + /* Save used mode */ + *p3gpp_frame_type = (enum Frame_Type_3GPP) usedMode; + + /* Determine transmit frame type */ + sid_sync(pSidSyncState, usedMode, &tx_frame_type); + + /* Put TX frame type in output buffer */ + ets_output_bfr[0] = tx_frame_type; + + /* Put mode information after the encoded speech parameters */ + if (tx_frame_type != TX_NO_DATA) + { + ets_output_bfr[1+MAX_SERIAL_SIZE] = (Word16) mode; + } + else + { + ets_output_bfr[1+MAX_SERIAL_SIZE] = -1; + } + + /* Copy output of encoder to pEncOutput buffer */ + ets_output_ptr = (UWord8 *) & ets_output_bfr[0]; + + /* Copy 16-bit data in 8-bit chunks */ + /* using Little Endian configuration */ + for (i = 0; i < 2*(MAX_SERIAL_SIZE + 2); i++) + { + *(pEncOutput + i) = *ets_output_ptr; + ets_output_ptr += 1; + } + + /* Set up the number of encoded bytes */ + num_enc_bytes = 2 * (MAX_SERIAL_SIZE + 2); + + } + + /* Invalid frame format */ + else + { + /* Invalid output format, set up error code */ + num_enc_bytes = -1; + } + + return(num_enc_bytes); +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/amrencode.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/amrencode.h new file mode 100644 index 00000000..1f1dc903 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/amrencode.h @@ -0,0 +1,133 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: amrencode.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains the function prototype of AMREncode. + +------------------------------------------------------------------------------ +*/ + +#ifndef _AMRENCODE_H_ +#define _AMRENCODE_H_ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "frame_type_3gpp.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ +#define NUM_AMRSID_TXMODE_BITS 3 +#define AMRSID_TXMODE_BIT_OFFSET 36 +#define AMRSID_TXTYPE_BIT_OFFSET 35 + + /* Output format types */ + +#define AMR_TX_WMF 0 +#define AMR_TX_IF2 1 +#define AMR_TX_ETS 2 +#define AMR_TX_IETF 3 + + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + extern const Word16 WmfEncBytesPerFrame[]; + extern const Word16 If2EncBytesPerFrame[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + Word16 AMREncodeInit( + void **pEncStructure, + void **pSidSyncStructure, + Flag dtx_enable); + + Word16 AMREncodeReset( + void *pEncStructure, + void *pSidSyncStructure); + + void AMREncodeExit( + void **pEncStructure, + void **pSidSyncStructure); + + Word16 AMREncode( + void *pEncState, + void *pSidSyncState, + enum Mode mode, + Word16 *pEncInput, + UWord8 *pEncOutput, + enum Frame_Type_3GPP *p3gpp_frame_type, + Word16 output_format + ); + +#ifdef __cplusplus +} +#endif + +#endif /* _AMRENCODE_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/autocorr.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/autocorr.cpp new file mode 100644 index 00000000..033c93a9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/autocorr.cpp @@ -0,0 +1,377 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: autocorr.cpp + +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "autocorr.h" +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Autocorr +---------------------------------------------------------------------------- + INPUT AND OUTPUT DEFINITIONS + + Inputs: + x = buffer of input signals of type Word16 + m = LPC order of type Word16 + wind = buffer of window signals of type Word16 + r_h = buffer containing the high word of the autocorrelation values + of type Word16 + r_l = buffer containing the low word of the autocorrelation values + of type Word16 + + pOverflow = pointer to variable of type Flag *, which indicates if + overflow occurs. + + Outputs: + r_h buffer contains the high word of the new autocorrelation values + r_l buffer contains the low word of the new autocorrelation values + pOverflow -> 1 if overflow occurs. + + Returns: + norm = normalized autocorrelation at lag zero of type Word16 + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function windows the input signal with the provided window + then calculates the autocorrelation values for lags of 0,1,...m, + where m is the passed in LPC order. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + autocorr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 Autocorr ( + Word16 x[], // (i) : Input signal (L_WINDOW) + Word16 m, // (i) : LPC order + Word16 r_h[], // (o) : Autocorrelations (msb) + Word16 r_l[], // (o) : Autocorrelations (lsb) + const Word16 wind[] // (i) : window for LPC analysis (L_WINDOW) +) +{ + Word16 i, j, norm; + Word16 y[L_WINDOW]; + Word32 sum; + Word16 overfl, overfl_shft; + + // Windowing of signal + + for (i = 0; i < L_WINDOW; i++) + { + y[i] = mult_r (x[i], wind[i]); + } + + // Compute r[0] and test for overflow + + overfl_shft = 0; + + do + { + overfl = 0; + sum = 0L; + + for (i = 0; i < L_WINDOW; i++) + { + sum = L_mac (sum, y[i], y[i]); + } + + // If overflow divide y[] by 4 + + if (L_sub (sum, MAX_32) == 0L) + { + overfl_shft = add (overfl_shft, 4); + overfl = 1; // Set the overflow flag + + for (i = 0; i < L_WINDOW; i++) + { + y[i] = shr (y[i], 2); + } + } + } + while (overfl != 0); + + sum = L_add (sum, 1L); // Avoid the case of all zeros + + // Normalization of r[0] + + norm = norm_l (sum); + sum = L_shl (sum, norm); + L_Extract (sum, &r_h[0], &r_l[0]); // Put in DPF format (see oper_32b) + + // r[1] to r[m] + + for (i = 1; i <= m; i++) + { + sum = 0; + + for (j = 0; j < L_WINDOW - i; j++) + { + sum = L_mac (sum, y[j], y[j + i]); + } + + sum = L_shl (sum, norm); + L_Extract (sum, &r_h[i], &r_l[i]); + } + + norm = sub (norm, overfl_shft); + + return norm; +} + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Autocorr( + Word16 x[], /* (i) : Input signal (L_WINDOW) */ + Word16 m, /* (i) : LPC order */ + Word16 r_h[], /* (o) : Autocorrelations (msb) */ + Word16 r_l[], /* (o) : Autocorrelations (lsb) */ + const Word16 wind[], /* (i) : window for LPC analysis (L_WINDOW) */ + Flag *pOverflow /* (o) : indicates overflow */ +) +{ + register Word16 i; + register Word16 j; + register Word16 norm; + + Word16 y[L_WINDOW]; + Word32 sum; + Word16 overfl_shft; + + + /* Added for optimization */ + + + Word16 temp; + Word16 *p_x; + Word16 *p_y; + Word16 *p_y_1; + Word16 *p_y_ref; + Word16 *p_rh; + Word16 *p_rl; + const Word16 *p_wind; + p_y = y; + p_x = x; + p_wind = wind; + /* + * Windowing of the signal + */ + + OSCL_UNUSED_ARG(pOverflow); + + sum = 0L; + j = 0; + + for (i = L_WINDOW; i != 0; i--) + { + temp = (Word16)((amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_wind++), 0x04000)) >> 15); + *(p_y++) = temp; + + sum += ((Word32)temp * temp) << 1; + if (sum < 0) + { + /* + * if oveflow exist, then stop accumulation + */ + j = 1; + break; + } + + } + /* + * if oveflow existed, complete windowing operation + * without computing energy + */ + + if (j) + { + p_y = &y[L_WINDOW-i]; + p_x = &x[L_WINDOW-i]; + p_wind = &wind[L_WINDOW-i]; + + for (; i != 0; i--) + { + temp = (Word16)((amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_wind++), 0x04000)) >> 15); + *(p_y++) = temp; + } + } + + + /* + * Compute r[0] and test for overflow + */ + + overfl_shft = 0; + + /* + * scale down by 1/4 only when needed + */ + while (j == 1) + { + /* If overflow divide y[] by 4 */ + /* FYI: For better resolution, we could */ + /* divide y[] by 2 */ + overfl_shft += 4; + p_y = &y[0]; + sum = 0L; + + for (i = (L_WINDOW >> 1); i != 0 ; i--) + { + temp = *p_y >> 2; + *(p_y++) = temp; + sum += ((Word32)temp * temp) << 1; + temp = *p_y >> 2; + *(p_y++) = temp; + sum += ((Word32)temp * temp) << 1; + } + if (sum > 0) + { + j = 0; + } + + } + + sum += 1L; /* Avoid the case of all zeros */ + + /* Normalization of r[0] */ + + norm = norm_l(sum); + + sum <<= norm; + + /* Put in DPF format (see oper_32b) */ + r_h[0] = (Word16)(sum >> 16); + r_l[0] = (Word16)((sum >> 1) - ((Word32)(r_h[0]) << 15)); + + /* r[1] to r[m] */ + + p_y_ref = &y[L_WINDOW - 1 ]; + p_rh = &r_h[m]; + p_rl = &r_l[m]; + + for (i = m; i > 0; i--) + { + sum = 0; + + p_y = &y[L_WINDOW - i - 1]; + p_y_1 = p_y_ref; + + for (j = (L_WINDOW - i - 1) >> 1; j != 0; j--) + { + sum = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y--), (Word32) * (p_y_1--), sum); + sum = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y--), (Word32) * (p_y_1--), sum); + } + + sum = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y--), (Word32) * (p_y_1--), sum); + + if (((L_WINDOW - i - 1) & 1)) + { + sum = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y--), (Word32) * (p_y_1--), sum); + } + + sum <<= (norm + 1); + + *(p_rh) = (Word16)(sum >> 16); + *(p_rl--) = (Word16)((sum >> 1) - ((Word32) * (p_rh--) << 15)); + + } + + norm -= overfl_shft; + + return (norm); + +} /* Autocorr */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/autocorr.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/autocorr.h new file mode 100644 index 00000000..c7f27865 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/autocorr.h @@ -0,0 +1,109 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: autocorr.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the autocorr function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef autocorr_h +#define autocorr_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 Autocorr( + Word16 x[], /* (i) : Input signal (L_WINDOW) */ + Word16 m, /* (i) : LPC order */ + Word16 r_h[], /* (o) : Autocorrelations (msb) */ + Word16 r_l[], /* (o) : Autocorrelations (lsb) */ + const Word16 wind[], /* (i) : window for LPC analysis (L_WINDOW) */ + Flag *pOverflow /* (o) : indicates overflow */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _AUTO_CORR_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c1035pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c1035pf.cpp new file mode 100644 index 00000000..e3e428d6 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c1035pf.cpp @@ -0,0 +1,602 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c1035pf.cpp + Functions: q_p + build_code + code_10i40_35bits + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the function that searches a 35 bit algebraic codebook + containing 10 pulses in a frame of 40 samples. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "c1035pf.h" +#include "cnst.h" +#include "basic_op.h" +#include "inv_sqrt.h" +#include "set_sign.h" +#include "cor_h.h" +#include "cor_h_x.h" +#include "s10_8pf.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ +#define NB_PULSE 10 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: q_p +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pShift_reg = pointer to Old CN generator shift register state (Word32) + no_bits = Number of bits (Word16) + + Outputs: + pShift_reg -> Updated CN generator shift register state + + Returns: + noise_bits = Generated random integer value (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This is a local function that determnes the index of the pulses by looking up + the gray encoder table + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void q_p ( + Word16 *ind, // Pulse position + Word16 n // Pulse number +) +{ + Word16 tmp; + + tmp = *ind; + + if (sub (n, 5) < 0) + { + *ind = (tmp & 0x8) | gray[tmp & 0x7]; + } + else + { + *ind = gray[tmp & 0x7]; + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void q_p( + Word16 *pInd, /* Pulse position */ + Word16 n, /* Pulse number */ + const Word16* gray_ptr +) +{ + Word16 tmp; + + tmp = *pInd; + + if (n < 5) + { + *pInd = (tmp & 0x8) | gray_ptr[tmp & 0x7]; + } + else + { + *pInd = gray_ptr[tmp & 0x7]; + } +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: build_code +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pSeed = pointer to the Old CN generator shift register state (Word32) + n_param = Number of parameters to randomize (Word16) + param_size_table = table holding paameter sizes (Word16) + param[] = array to hold CN generated paramters (Word16) + pOverflow = pointer to overflow flag (Flag) + + Outputs: + param[] = CN generated parameters (Word16) + pSeed = Updated CN generator shift register state (Word16) + pOverflow -> 1 if overflow occured + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function builds the codeword, the filtered codeword and index of the + codevector, based on the signs and positions of 10 pulses. +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE +static void build_code ( + Word16 codvec[], // (i) : position of pulses + Word16 sign[], // (i) : sign of d[n] + Word16 cod[], // (o) : innovative code vector + Word16 h[], // (i) : impulse response of weighted synthesis filter + Word16 y[], // (o) : filtered innovative code + Word16 indx[] // (o) : index of 10 pulses (sign+position) +) +{ + Word16 i, j, k, track, index, _sign[NB_PULSE]; + Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9; + Word32 s; + + for (i = 0; i < L_CODE; i++) + { + cod[i] = 0; + } + for (i = 0; i < NB_TRACK; i++) + { + indx[i] = -1; + } + + for (k = 0; k < NB_PULSE; k++) + { + // read pulse position + i = codvec[k]; + // read sign + j = sign[i]; + + index = mult (i, 6554); // index = pos/5 + // track = pos%5 + track = sub (i, extract_l (L_shr (L_mult (index, 5), 1))); + + if (j > 0) + { + cod[i] = add (cod[i], 4096); + _sign[k] = 8192; + + } + else + { + cod[i] = sub (cod[i], 4096); + _sign[k] = -8192; + index = add (index, 8); + } + + if (indx[track] < 0) + { + indx[track] = index; + } + else + { + if (((index ^ indx[track]) & 8) == 0) + { + // sign of 1st pulse == sign of 2nd pulse + + if (sub (indx[track], index) <= 0) + { + indx[track + 5] = index; + } + else + { + indx[track + 5] = indx[track]; + indx[track] = index; + } + } + else + { + // sign of 1st pulse != sign of 2nd pulse + + if (sub ((Word16)(indx[track] & 7), (Word16)(index & 7)) <= 0) + { + indx[track + 5] = indx[track]; + indx[track] = index; + } + else + { + indx[track + 5] = index; + } + } + } + } + + p0 = h - codvec[0]; + p1 = h - codvec[1]; + p2 = h - codvec[2]; + p3 = h - codvec[3]; + p4 = h - codvec[4]; + p5 = h - codvec[5]; + p6 = h - codvec[6]; + p7 = h - codvec[7]; + p8 = h - codvec[8]; + p9 = h - codvec[9]; + + for (i = 0; i < L_CODE; i++) + { + s = 0; + s = L_mac (s, *p0++, _sign[0]); + s = L_mac (s, *p1++, _sign[1]); + s = L_mac (s, *p2++, _sign[2]); + s = L_mac (s, *p3++, _sign[3]); + s = L_mac (s, *p4++, _sign[4]); + s = L_mac (s, *p5++, _sign[5]); + s = L_mac (s, *p6++, _sign[6]); + s = L_mac (s, *p7++, _sign[7]); + s = L_mac (s, *p8++, _sign[8]); + s = L_mac (s, *p9++, _sign[9]); + y[i] = pv_round (s); + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +static void build_code( + Word16 codvec[], /* (i) : position of pulses */ + Word16 sign[], /* (i) : sign of d[n] */ + Word16 cod[], /* (o) : innovative code vector */ + Word16 h[], /* (i) : impulse response of weighted synthesis filter*/ + Word16 y[], /* (o) : filtered innovative code */ + Word16 indx[], /* (o) : index of 10 pulses (sign+position) */ + Flag *pOverflow /* i/o : overflow Flag */ +) +{ + Word16 i, k, track, index, _sign[NB_PULSE]; + Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9; + Word32 s; + Word16 temp; + Word16 *p__sign; + Word16 *p_y; + Word16 *p_codvec; + + OSCL_UNUSED_ARG(pOverflow); + + oscl_memset(cod, 0, L_CODE*sizeof(*cod)); + oscl_memset(indx, 0xFF, NB_TRACK*sizeof(*indx)); + + p__sign = _sign; + + p0 = &codvec[0]; + + for (k = 0; k < NB_PULSE; k++) + { + /* read pulse position */ + i = *(p0++); + /* read sign */ + + index = ((Word32)i * 6554) >> 15; /* index = pos/5 */ + + /* track = pos%5 */ + /* track = sub (i, extract_l (L_shr (L_mult (index, 5), 1))); */ + track = i - (index + (index << 2)); + + if (sign[i] > 0) + { + cod[i] += 4096; + *(p__sign++) = 8192; + + } + else + { + cod[i] -= 4096; + *(p__sign++) = -8192; + /* index = add (index, 8); */ + index += 8; + } + + p1 = &indx[track]; + + temp = *p1; + + if (temp < 0) + { + *p1 = index; + } + else + { + if (((index ^ temp) & 8) == 0) + { + /* sign of 1st pulse == sign of 2nd pulse */ + + /* if (sub (indx[track], index) <= 0) */ + if (temp <= index) + { + *(p1 + 5) = index; + } + else + { + *(p1 + 5) = temp; + *p1 = index; + } + } + else + { + /* sign of 1st pulse != sign of 2nd pulse */ + + /* if (sub ((Word16)(indx[track] & 7), (Word16)(index & 7)) <= 0) */ + if ((temp & 7) <= (index & 7)) + { + *(p1 + 5) = temp; + *p1 = index; + } + else + { + *(p1 + 5) = index; + } + } + } + } + + p_codvec = &codvec[0]; + + p0 = h - *(p_codvec++); + p1 = h - *(p_codvec++); + p2 = h - *(p_codvec++); + p3 = h - *(p_codvec++); + p4 = h - *(p_codvec++); + p5 = h - *(p_codvec++); + p6 = h - *(p_codvec++); + p7 = h - *(p_codvec++); + p8 = h - *(p_codvec++); + p9 = h - *(p_codvec++); + + p_y = y; + + for (i = L_CODE; i != 0; i--) + { + p__sign = _sign; + + s = (*p0++ * *(p__sign++)) >> 7; + s += (*p1++ * *(p__sign++)) >> 7; + s += (*p2++ * *(p__sign++)) >> 7; + s += (*p3++ * *(p__sign++)) >> 7; + s += (*p4++ * *(p__sign++)) >> 7; + s += (*p5++ * *(p__sign++)) >> 7; + s += (*p6++ * *(p__sign++)) >> 7; + s += (*p7++ * *(p__sign++)) >> 7; + s += (*p8++ * *(p__sign++)) >> 7; + s += (*p9++ * *(p__sign++)) >> 7; + + *(p_y++) = (s + 0x080) >> 8; + } + +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: code_10i40_35bits +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pSeed = pointer to the Old CN generator shift register state (Word32) + n_param = Number of parameters to randomize (Word16) + param_size_table = table holding paameter sizes (Word16) + param[] = array to hold CN generated paramters (Word16) + pOverflow = pointer to overflow flag (Flag) + + Outputs: + param[] = CN generated parameters (Word16) + pSeed = Updated CN generator shift register state (Word16) + pOverflow -> 1 if overflow occured + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function searches a 35 bit algebraic codebook containing 10 pulses in a + frame of 40 samples. + + The code contains 10 nonzero pulses: i0...i9. + All pulses can have two possible amplitudes: +1 or -1. + The 40 positions in a subframe are divided into 5 tracks of + interleaved positions. Each track contains two pulses. + The pulses can have the following possible positions: + + i0, i5 : 0, 5, 10, 15, 20, 25, 30, 35. + i1, i6 : 1, 6, 11, 16, 21, 26, 31, 36. + i2, i7 : 2, 7, 12, 17, 22, 27, 32, 37. + i3, i8 : 3, 8, 13, 18, 23, 28, 33, 38. + i4, i9 : 4, 9, 14, 19, 24, 29, 34, 39. + + Each pair of pulses require 1 bit for their signs and 6 bits for their + positions (3 bits + 3 bits). This results in a 35 bit codebook. + The function determines the optimal pulse signs and positions, builds + the codevector, and computes the filtered codevector. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE +void code_10i40_35bits ( + Word16 x[], // (i) : target vector + Word16 cn[], // (i) : residual after long term prediction + Word16 h[], // (i) : impulse response of weighted synthesis filter + // h[-L_subfr..-1] must be set to zero + Word16 cod[], // (o) : algebraic (fixed) codebook excitation + Word16 y[], // (o) : filtered fixed codebook excitation + Word16 indx[] // (o) : index of 10 pulses (sign + position) +) +{ + Word16 ipos[NB_PULSE], pos_max[NB_TRACK], codvec[NB_PULSE]; + Word16 dn[L_CODE], sign[L_CODE]; + Word16 rr[L_CODE][L_CODE], i; + + cor_h_x (h, x, dn, 2); + set_sign12k2 (dn, cn, sign, pos_max, NB_TRACK, ipos, STEP); + cor_h (h, sign, rr); + + search_10and8i40 (NB_PULSE, STEP, NB_TRACK, + dn, rr, ipos, pos_max, codvec); + + build_code (codvec, sign, cod, h, y, indx); + for (i = 0; i < 10; i++) + { + q_p (&indx[i], i); + } + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +void code_10i40_35bits( + Word16 x[], /* (i) : target vector */ + Word16 cn[], /* (i) : residual after long term prediction */ + Word16 h[], /* (i) : impulse response of weighted synthesis filter + h[-L_subfr..-1] must be set to zero */ + Word16 cod[], /* (o) : algebraic (fixed) codebook excitation */ + Word16 y[], /* (o) : filtered fixed codebook excitation */ + Word16 indx[], /* (o) : index of 10 pulses (sign + position) */ + const Word16* gray_ptr, /* (i) : ptr to read-only table */ + Flag *pOverflow /* (i/o) : overflow Flag */ +) +{ + Word16 ipos[NB_PULSE], pos_max[NB_TRACK], codvec[NB_PULSE]; + Word16 dn[L_CODE], sign[L_CODE]; + Word16 rr[L_CODE][L_CODE], i; + + cor_h_x(h, x, dn, 2, pOverflow); + set_sign12k2(dn, cn, sign, pos_max, NB_TRACK, ipos, STEP, pOverflow); + cor_h(h, sign, rr, pOverflow); + + search_10and8i40(NB_PULSE, STEP, NB_TRACK, + dn, rr, ipos, pos_max, codvec, pOverflow); + + build_code(codvec, sign, cod, h, y, indx, pOverflow); + for (i = 0; i < 10; i++) + { + q_p(&indx[i], i, gray_ptr); + } + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c1035pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c1035pf.h new file mode 100644 index 00000000..4bd970a1 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c1035pf.h @@ -0,0 +1,112 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c1035pf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains the prototype declaration for code_10i40_35bits function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef C1035PF_H +#define C1035PF_H "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void code_10i40_35bits( + Word16 x[], /* (i) : target vector */ + Word16 cn[], /* (i) : residual after long term prediction */ + Word16 h[], /* (i) : impulse response of weighted synthesis filter + h[-L_subfr..-1] must be set to zero */ + Word16 cod[], /* (o) : algebraic (fixed) codebook excitation */ + Word16 y[], /* (o) : filtered fixed codebook excitation */ + Word16 indx[], /* (o) : index of 10 pulses (sign + position) */ + const Word16* gray_ptr, /* (i) : ptr to read-only table */ + Flag *pOverflow /* (i/o) : overflow Flag */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _C1035PF_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c2_11pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c2_11pf.cpp new file mode 100644 index 00000000..95f8d5fb --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c2_11pf.cpp @@ -0,0 +1,771 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c2_11pf.cpp + Functions: + code_2i40_11bits + search_2i40 + build_code + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + ************************************************************************* + * + * FUNCTION: code_2i40_11bits() + * + * PURPOSE: Searches a 11 bit algebraic codebook containing 2 pulses + * in a frame of 40 samples. + * + * DESCRIPTION: + * The code length is 40, containing 2 nonzero pulses: i0...i1. + * All pulses can have two possible amplitudes: +1 or -1. + * Pulse i0 can have 2x8=16 possible positions, pulse i1 can have + * 4x8=32 positions. + * + * i0 : 1, 6, 11, 16, 21, 26, 31, 36. + * 3, 8, 13, 18, 23, 28, 33, 38. + * i1 : 0, 5, 10, 15, 20, 25, 30, 35. + * 1, 6, 11, 16, 21, 26, 31, 36. + * 2, 7, 12, 17, 22, 27, 32, 37. + * 4, 9, 14, 19, 24, 29, 34, 39. + * + ************************************************************************* +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "c2_11pf.h" +#include "typedef.h" +#include "basic_op.h" +#include "inv_sqrt.h" +#include "cnst.h" +#include "cor_h.h" +#include "set_sign.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define NB_PULSE 2 + +#define _1_2 (Word16)(32768L/2) +#define _1_4 (Word16)(32768L/4) +#define _1_8 (Word16)(32768L/8) +#define _1_16 (Word16)(32768L/16) + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ +static void search_2i40( + Word16 dn[], /* i : correlation between target and h[] */ + Word16 rr[][L_CODE],/* i : matrix of autocorrelation */ + Word16 codvec[], /* o : algebraic codebook vector */ + Flag * pOverflow +); + +static Word16 build_code( + Word16 codvec[], /* i : algebraic codebook vector */ + Word16 dn_sign[], /* i : sign of dn[] */ + Word16 cod[], /* o : algebraic (fixed) codebook excitation */ + Word16 h[], /* i : impulse response of weighted synthesis filter */ + Word16 y[], /* o : filtered fixed codebook excitation */ + Word16 sign[], /* o : sign of 2 pulses */ + Flag * pOverflow +); + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +const Word16 startPos1[2] = {1, 3}; +const Word16 startPos2[4] = {0, 1, 2, 4}; + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: code_2i40_11bits +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + x, target vector, array of type Word16 + h, impulse response of weighted synthesis filter, array of type Word16 + T0, Pitch lag, variable of type Word16 + pitch_sharp, Last quantized pitch gain, variable of type Word16 + + Outputs: + code[], Innovative codebook, array of type Word16 + y[], filtered fixed codebook excitation, array of type Word16 + sign, Signs of 2 pulses, pointer of type Word16 * + pOverflow Flag set when overflow occurs, pointer of type Flag * + + Returns: + index + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Searches a 11 bit algebraic codebook containing 2 pulses + in a frame of 40 samples. + + The code length is 40, containing 2 nonzero pulses: i0...i1. + All pulses can have two possible amplitudes: +1 or -1. + Pulse i0 can have 2x8=16 possible positions, pulse i1 can have + 4x8=32 positions. + + i0 : 1, 6, 11, 16, 21, 26, 31, 36. + 3, 8, 13, 18, 23, 28, 33, 38. + i1 : 0, 5, 10, 15, 20, 25, 30, 35. + 1, 6, 11, 16, 21, 26, 31, 36. + 2, 7, 12, 17, 22, 27, 32, 37. + 4, 9, 14, 19, 24, 29, 34, 39. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + c2_11pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 code_2i40_11bits( + Word16 x[], /* i : target vector */ + Word16 h[], /* i : impulse response of weighted synthesis filter */ + /* h[-L_subfr..-1] must be set to zero. */ + Word16 T0, /* i : Pitch lag */ + Word16 pitch_sharp, /* i : Last quantized pitch gain */ + Word16 code[], /* o : Innovative codebook */ + Word16 y[], /* o : filtered fixed codebook excitation */ + Word16 * sign, /* o : Signs of 2 pulses */ + Flag * pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 codvec[NB_PULSE]; + Word16 dn[L_CODE]; + Word16 dn2[L_CODE]; + Word16 dn_sign[L_CODE]; + + Word16 rr[L_CODE][L_CODE]; + + Word16 i; + Word16 index; + Word16 sharp; + Word16 tempWord; + + sharp = pitch_sharp << 1; + + if (T0 < L_CODE) + { + for (i = T0; i < L_CODE; i++) + { + tempWord = + mult( + h[i - T0], + sharp, + pOverflow); + + h[i] = + add_16( + h[i], + tempWord, + pOverflow); + } + + } + + cor_h_x( + h, + x, + dn, + 1, + pOverflow); + + set_sign( + dn, + dn_sign, + dn2, + 8); /* dn2[] not used in this codebook search */ + + cor_h( + h, + dn_sign, + rr, + pOverflow); + + search_2i40( + dn, + rr, + codvec, + pOverflow); + + /* function result */ + + index = + build_code( + codvec, + dn_sign, + code, + h, + y, + sign, + pOverflow); + + /* + * Compute innovation vector gain. + * Include fixed-gain pitch contribution into code[]. + */ + + if (T0 < L_CODE) + { + for (i = T0; i < L_CODE; i++) + { + tempWord = + mult( + code[i - T0], + sharp, + pOverflow); + + code[i] = + add_16( + code[i], + tempWord, + pOverflow); + } + } + + return index; +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: search_2i40 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + dn, correlation between target and h[], array of type Word16 + rr, matrix of autocorrelation, double-array of type Word16 + + Outputs: + codvec[], algebraic codebook vector, array of type Word16 + pOverflow, Flag set when overflow occurs, pointer of type Flag * + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Search the best codevector; determine positions of the 2 pulses + in the 40-sample frame. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + c2_11pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void search_2i40( + Word16 dn[], /* i : correlation between target and h[] */ + Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ + Word16 codvec[], /* o : algebraic codebook vector */ + Flag * pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i0; + Word16 i1; + Word16 ix = 0; /* initialization only needed to keep gcc silent */ + Word16 track1; + Word16 track2; + Word16 ipos[NB_PULSE]; + + Word16 psk; + Word16 ps0; + Word16 ps1; + Word16 sq; + Word16 sq1; + + Word16 alpk; + Word16 alp; + Word16 alp_16; + + Word32 s; + Word32 alp0; + Word32 alp1; + + Word16 i; + Word16 *p_codvec = &codvec[0]; + + psk = -1; + alpk = 1; + + for (i = 0; i < NB_PULSE; i++) + { + *(p_codvec++) = i; + } + + /*------------------------------------------------------------------* + * main loop: try 2x4 tracks. * + *------------------------------------------------------------------*/ + + for (track1 = 0; track1 < 2; track1++) + { + for (track2 = 0; track2 < 4; track2++) + { + /* fix starting position */ + ipos[0] = startPos1[track1]; + ipos[1] = startPos2[track2]; + + /*----------------------------------------------------------------* + * i0 loop: try 8 positions. * + *----------------------------------------------------------------*/ + for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) + { + ps0 = dn[i0]; + + /* alp0 = L_mult(rr[i0][i0], _1_4, pOverflow); */ + alp0 = (Word32) rr[i0][i0] << 14; + + /*-------------------------------------------------------------* + * i1 loop: 8 positions. * + *-------------------------------------------------------------*/ + + sq = -1; + alp = 1; + ix = ipos[1]; + + /*---------------------------------------------------------------* + * These index have low complexity address computation because * + * they are, in fact, pointers with fixed increment. For example,* + * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]" * + * and incremented by "STEP". * + *---------------------------------------------------------------*/ + + for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) + { + /* idx increment = STEP */ + ps1 = add_16(ps0, dn[i1], pOverflow); + + /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */ + + /* idx incr = STEP */ + /* alp1 = L_mac(alp0, rr[i1][i1], _1_4, pOverflow); */ + alp1 = alp0 + ((Word32) rr[i1][i1] << 14); + + /* idx incr = STEP */ + /* alp1 = L_mac(alp1, rr[i0][i1], _1_2, pOverflow); */ + alp1 += (Word32) rr[i0][i1] << 15; + + /* sq1 = mult(ps1, ps1, pOverflow); */ + sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); + + /* alp_16 = pv_round(alp1, pOverflow); */ + alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); + + /* s = L_mult(alp, sq1, pOverflow); */ + s = ((Word32) alp * sq1) << 1; + + /* s =L_msu(s, sq, alp_16, pOverflow); */ + s -= (((Word32) sq * alp_16) << 1); + + if (s > 0) + { + sq = sq1; + alp = alp_16; + ix = i1; + } + + } /* for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) */ + + /* memorize codevector if this one is better than the last one. */ + + /* s = L_mult(alpk, sq, pOverflow); */ + s = ((Word32) alpk * sq) << 1; + + /* s = L_msu(s, psk, alp, pOverflow); */ + s -= (((Word32) psk * alp) << 1); + + if (s > 0) + { + psk = sq; + alpk = alp; + p_codvec = &codvec[0]; + + *(p_codvec++) = i0; + *(p_codvec) = ix; + } + + } /* for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) */ + + } /* for (track2 = 0; track2 < 4; track2++) */ + + } /* for (track1 = 0; track1 < 2; track1++) */ + + return; + +} /* search_2i40 */ + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: build_code +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + codvec, position of pulses, array of type Word16 + dn_sign, sign of pulses, array of type Word16 + h, impulse response of weighted synthesis filter, Word16 array + + Outputs: + + cod, innovative code vector, array of type Word16 + y[], filtered innovative code, array of type Word16 + sign[], sign of 2 pulses, array of type Word16 + pOverflow, Flag set when overflow occurs, pointer of type Flag * + + Returns: + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Builds the codeword, the filtered codeword and index of the + codevector, based on the signs and positions of 2 pulses. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + c2_11pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +static Word16 build_code( + Word16 codvec[], /* i : position of pulses */ + Word16 dn_sign[], /* i : sign of pulses */ + Word16 cod[], /* o : innovative code vector */ + Word16 h[], /* i : impulse response of weighted synthesis filter */ + Word16 y[], /* o : filtered innovative code */ + Word16 sign[], /* o : sign of 2 pulses */ + Flag * pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 j; + Word16 k; + Word16 track; + Word16 index; + Word16 _sign[NB_PULSE]; + Word16 indx; + Word16 rsign; + Word16 tempWord; + + Word16 *p0; + Word16 *p1; + + Word32 s; + + for (i = 0; i < L_CODE; i++) + { + cod[i] = 0; + } + + indx = 0; + rsign = 0; + + for (k = 0; k < NB_PULSE; k++) + { + i = codvec[k]; /* read pulse position */ + j = dn_sign[i]; /* read sign */ + + /* index = pos/5 */ + /* index = mult(i, 6554, pOverflow); */ + index = (Word16)(((Word32) i * 6554) >> 15); + + /* track = pos%5 */ + /* tempWord = + L_mult( + index, + 5, + pOverflow); */ + tempWord = (index << 3) + (index << 1); + + /* tempWord = + L_shr( + tempWord, + 1, + pOverflow); */ + tempWord >>= 1; + + + /* track = + sub( + i, + tempWord, + pOverflow); */ + track = i - tempWord; + + tempWord = track; + + if (tempWord == 0) + { + track = 1; + + /* index = + shl( + index, + 6, + pOverflow); */ + index <<= 6; + } + else if (track == 1) + { + tempWord = k; + + if (tempWord == 0) + { + track = 0; + /* index = + shl( + index, + 1, + pOverflow); */ + index <<= 1; + } + else + { + track = 1; + + /* tempWord = + shl( + index, + 6, + pOverflow); */ + tempWord = index << 6; + + /* index = + add( + tempWord, + 16, + pOverflow); */ + index = tempWord + 16; + } + } + else if (track == 2) + { + track = 1; + + /* tempWord = + shl( + index, + 6, + pOverflow); */ + tempWord = index << 6; + + /* index = + add( + tempWord, + 32, + pOverflow); */ + index = tempWord + 32; + } + else if (track == 3) + { + track = 0; + + /* tempWord = + shl( + index, + 1, + pOverflow); */ + tempWord = index << 1; + + /* index = + add( + tempWord, + 1, + pOverflow); */ + index = tempWord + 1; + } + else if (track == 4) + { + track = 1; + + /* tempWord = + shl( + index, + 6, + pOverflow); */ + tempWord = index << 6; + + /* index = + add( + tempWord, + 48, + pOverflow); */ + index = tempWord + 48; + } + + if (j > 0) + { + cod[i] = 8191; + _sign[k] = 32767; + + tempWord = + shl( + 1, + track, + pOverflow); + + rsign = + add_16( + rsign, + tempWord, + pOverflow); + } + else + { + cod[i] = -8192; + _sign[k] = (Word16) - 32768L; + } + + indx = + add_16( + indx, + index, + pOverflow); + } + *sign = rsign; + + p0 = h - codvec[0]; + p1 = h - codvec[1]; + + for (i = 0; i < L_CODE; i++) + { + s = 0; + + s = + L_mac( + s, + *p0++, + _sign[0], + pOverflow); + + s = + L_mac( + s, + *p1++, + _sign[1], + pOverflow); + + y[i] = + pv_round( + s, + pOverflow); + } + + return indx; +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c2_11pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c2_11pf.h new file mode 100644 index 00000000..391f6401 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c2_11pf.h @@ -0,0 +1,112 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c2_11pf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the c2_11pf.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef c2_11pf_h +#define c2_11pf_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 code_2i40_11bits( + Word16 x[], /* i : target vector */ + Word16 h[], /* i : impulse response of weighted synthesis filter */ + /* h[-L_subfr..-1] must be set to zero. */ + Word16 T0, /* i : Pitch lag */ + Word16 pitch_sharp, /* i : Last quantized pitch gain */ + Word16 code[], /* o : Innovative codebook */ + Word16 y[], /* o : filtered fixed codebook excitation */ + Word16 * sign, /* o : Signs of 2 pulses */ + Flag * pOverflow + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _c2_11PF_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c2_9pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c2_9pf.cpp new file mode 100644 index 00000000..052a53f2 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c2_9pf.cpp @@ -0,0 +1,1108 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c2_9pf.cpp + Functions: code_2i40_9bits + search_2i40 + Test_search_2i40 + build_code + Test_build_code + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the functions that search a 9 bit algebraic codebook + containing 2 pulses in a frame of 40 samples. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "c2_9pf.h" +#include "typedef.h" +#include "basic_op.h" +#include "inv_sqrt.h" +#include "cnst.h" +#include "cor_h.h" +#include "cor_h_x.h" +#include "set_sign.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ +#define NB_PULSE 2 + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + static void search_2i40( + Word16 subNr, /* i : subframe number */ + Word16 dn[], /* i : correlation between target and h[] */ + Word16 rr[][L_CODE],/* i : matrix of autocorrelation */ + const Word16* startPos_ptr, /* i: ptr to read only table */ + Word16 codvec[], /* o : algebraic codebook vector */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ); + + static Word16 build_code( + Word16 subNr, /* i : subframe number */ + Word16 codvec[], /* i : algebraic codebook vector */ + Word16 dn_sign[], /* i : sign of dn[] */ + Word16 cod[], /* o : algebraic (fixed) codebook excitation */ + Word16 h[], /* i : impulse response of weighted synthesis filter */ + Word16 y[], /* o : filtered fixed codebook excitation */ + Word16 sign[], /* o : sign of 2 pulses */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ); + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + const Word16 trackTable[4*5] = + { + 0, 1, 0, 1, -1, /* subframe 1; track to code; + * -1 do not code this position + */ + 0, -1, 1, 0, 1, /* subframe 2 */ + 0, 1, 0, -1, 1, /* subframe 3 */ + 0, 1, -1, 0, 1 + };/* subframe 4 */ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: code_2i40_9bits + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + subNr = subframe number (Word16) + x = target buffer (Word16) + h = buffer containing the impulse response of the + weighted synthesis filter; h[-L_subfr .. -1] must be + set to zero (Word16) + T0 = pitch lag (Word16) + pitch_sharp = last quantized pitch gain (Word16) + code = buffer containing the innovative codebook (Word16) + y = buffer containing the filtered fixed codebook excitation (Word16) + sign = pointer to the signs of 2 pulses (Word16) + + Outputs: + code buffer contains the new innovation vector gains + + Returns: + index = code index (Word16) + + Global Variables Used: + Overflow = overflow flag (Flag) + + Local Variables Needed: + None + + ------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function searches a 9 bit algebraic codebook containing 2 pulses in a + frame of 40 samples. + + The code length is 40, containing 2 nonzero pulses: i0...i1. All pulses can + have two possible amplitudes: +1 or -1. Pulse i0 can have 8 possible positions, + pulse i1 can have 8 positions. Also coded is which track pair should be used, + i.e. first or second pair. Where each pair contains 2 tracks. + + First subframe: + first i0 : 0, 5, 10, 15, 20, 25, 30, 35. + i1 : 2, 7, 12, 17, 22, 27, 32, 37. + second i0 : 1, 6, 11, 16, 21, 26, 31, 36. + i1 : 3, 8, 13, 18, 23, 28, 33, 38. + + Second subframe: + first i0 : 0, 5, 10, 15, 20, 25, 30, 35. + i1 : 3, 8, 13, 18, 23, 28, 33, 38. + second i0 : 2, 7, 12, 17, 22, 27, 32, 37. + i1 : 4, 9, 14, 19, 24, 29, 34, 39. + + Third subframe: + first i0 : 0, 5, 10, 15, 20, 25, 30, 35. + i1 : 2, 7, 12, 17, 22, 27, 32, 37. + second i0 : 1, 6, 11, 16, 21, 26, 31, 36. + i1 : 4, 9, 14, 19, 24, 29, 34, 39. + + Fourth subframe: + first i0 : 0, 5, 10, 15, 20, 25, 30, 35. + i1 : 3, 8, 13, 18, 23, 28, 33, 38. + second i0 : 1, 6, 11, 16, 21, 26, 31, 36. + i1 : 4, 9, 14, 19, 24, 29, 34, 39. + + ------------------------------------------------------------------------------ + REQUIREMENTS + + None + + ------------------------------------------------------------------------------ + REFERENCES + + [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + + ------------------------------------------------------------------------------ + PSEUDO-CODE + + Word16 code_2i40_9bits( + Word16 subNr, // i : subframe number + Word16 x[], // i : target vector + Word16 h[], // i : impulse response of weighted synthesis filter + // h[-L_subfr..-1] must be set to zero. + Word16 T0, // i : Pitch lag + Word16 pitch_sharp, // i : Last quantized pitch gain + Word16 code[], // o : Innovative codebook + Word16 y[], // o : filtered fixed codebook excitation + Word16 * sign // o : Signs of 2 pulses + ) + { + Word16 codvec[NB_PULSE]; + Word16 dn[L_CODE], dn2[L_CODE], dn_sign[L_CODE]; + Word16 rr[L_CODE][L_CODE]; + Word16 i, index, sharp; + + sharp = shl(pitch_sharp, 1); + if (sub(T0, L_CODE) < 0) + for (i = T0; i < L_CODE; i++) { + h[i] = add(h[i], mult(h[i - T0], sharp)); + } + cor_h_x(h, x, dn, 1); + set_sign(dn, dn_sign, dn2, 8); // dn2[] not used in this codebook search + cor_h(h, dn_sign, rr); + search_2i40(subNr, dn, rr, codvec); + index = build_code(subNr, codvec, dn_sign, code, h, y, sign); + + *-----------------------------------------------------------------* + * Compute innovation vector gain. * + * Include fixed-gain pitch contribution into code[]. * + *-----------------------------------------------------------------* + + if (sub(T0, L_CODE) < 0) + for (i = T0; i < L_CODE; i++) { + code[i] = add(code[i], mult(code[i - T0], sharp)); + } + return index; + } + + ------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + + ------------------------------------------------------------------------------ + */ + + Word16 code_2i40_9bits( + Word16 subNr, /* i : subframe number */ + Word16 x[], /* i : target vector */ + Word16 h[], /* i : impulse response of weighted synthesis */ + /* filter h[-L_subfr..-1] must be set to 0. */ + Word16 T0, /* i : Pitch lag */ + Word16 pitch_sharp, /* i : Last quantized pitch gain */ + Word16 code[], /* o : Innovative codebook */ + Word16 y[], /* o : filtered fixed codebook excitation */ + Word16 * sign, /* o : Signs of 2 pulses */ + const Word16* startPos_ptr, /* ptr to read-only table */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ) + { + Word16 codvec[NB_PULSE]; + Word16 dn[L_CODE]; + Word16 dn2[L_CODE]; + Word16 dn_sign[L_CODE]; + Word16 rr[L_CODE][L_CODE]; + + register Word16 i; + + Word16 index; + Word16 sharp; + Word16 temp; + Word32 L_temp; + + L_temp = ((Word32) pitch_sharp) << 1; + + /* Check for overflow condition */ + if (L_temp != (Word32)((Word16) L_temp)) + { + *(pOverflow) = 1; + sharp = (pitch_sharp > 0) ? MAX_16 : MIN_16; + } + else + { + sharp = (Word16) L_temp; + } + + if (T0 < L_CODE) + { + for (i = T0; i < L_CODE; i++) + { + temp = + mult( + *(h + i - T0), + sharp, + pOverflow); + + *(h + i) = + add_16( + *(h + i), + temp, + pOverflow); + } + } + + cor_h_x( + h, + x, + dn, + 1, + pOverflow); + + /* dn2[] not used in this codebook search */ + + set_sign( + dn, + dn_sign, + dn2, + 8); + + cor_h( + h, + dn_sign, + rr, + pOverflow); + + search_2i40( + subNr, + dn, + rr, + startPos_ptr, + codvec, + pOverflow); + + index = + build_code( + subNr, + codvec, + dn_sign, + code, + h, + y, + sign, + pOverflow); + + /*-----------------------------------------------------------------* + * Compute innovation vector gain. * + * Include fixed-gain pitch contribution into code[]. * + *-----------------------------------------------------------------*/ + + if (T0 < L_CODE) + { + for (i = T0; i < L_CODE; i++) + { + temp = + mult( + *(code + i - T0), + sharp, + pOverflow); + + *(code + i) = + add_16( + *(code + i), + temp, + pOverflow); + } + } + + return(index); + } + + /****************************************************************************/ + + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: search_2i40 + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + subNr = subframe number (Word16) + dn = vector containing the correlation between target and the impulse + response of the weighted synthesis filter (Word16) + rr = autocorrelation matrix (Word16) + codvec = algebraic codebook vector (Word16) + + Outputs: + codvec contains the newly calculated codevectors + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + startPos = table containing the start positions used by fixed codebook + routines (const Word16) + + ------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function searches the best codevector and determines the positions of + the 2 pulses in the 40-sample frame. + + ------------------------------------------------------------------------------ + REQUIREMENTS + + None + + ------------------------------------------------------------------------------ + REFERENCES + + [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + + ------------------------------------------------------------------------------ + PSEUDO-CODE + + static void search_2i40( + Word16 subNr, // i : subframe number + Word16 dn[], // i : correlation between target and h[] + Word16 rr[][L_CODE], // i : matrix of autocorrelation + Word16 codvec[] // o : algebraic codebook vector + ) + { + Word16 i0, i1; + Word16 ix = 0; // initialization only needed to keep gcc silent + Word16 track1, ipos[NB_PULSE]; + Word16 psk, ps0, ps1, sq, sq1; + Word16 alpk, alp, alp_16; + Word32 s, alp0, alp1; + Word16 i; + + psk = -1; + alpk = 1; + for (i = 0; i < NB_PULSE; i++) + { + codvec[i] = i; + } + + for (track1 = 0; track1 < 2; track1++) { + // fix starting position + + ipos[0] = startPos[subNr*2+8*track1]; + ipos[1] = startPos[subNr*2+1+8*track1]; + + + *----------------------------------------------------------------* + * i0 loop: try 8 positions. * + *----------------------------------------------------------------* + + for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) { + + ps0 = dn[i0]; + alp0 = L_mult(rr[i0][i0], _1_4); + + *----------------------------------------------------------------* + * i1 loop: 8 positions. * + *----------------------------------------------------------------* + + sq = -1; + alp = 1; + ix = ipos[1]; + + *-------------------------------------------------------------------* + * These index have low complexity address computation because * + * they are, in fact, pointers with fixed increment. For example, * + * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]" * + * and incremented by "STEP". * + *-------------------------------------------------------------------* + + for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) { + ps1 = add(ps0, dn[i1]); // idx increment = STEP + + // alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; + + alp1 = L_mac(alp0, rr[i1][i1], _1_4); // idx incr = STEP + alp1 = L_mac(alp1, rr[i0][i1], _1_2); // idx incr = STEP + + sq1 = mult(ps1, ps1); + + alp_16 = pv_round(alp1); + + s = L_msu(L_mult(alp, sq1), sq, alp_16); + + if (s > 0) { + sq = sq1; + alp = alp_16; + ix = i1; + } + } + + *----------------------------------------------------------------* + * memorise codevector if this one is better than the last one. * + *----------------------------------------------------------------* + + s = L_msu(L_mult(alpk, sq), psk, alp); + + if (s > 0) { + psk = sq; + alpk = alp; + codvec[0] = i0; + codvec[1] = ix; + } + } + } + + return; + } + + ------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + + ------------------------------------------------------------------------------ + */ + + static void search_2i40( + Word16 subNr, /* i : subframe number */ + Word16 dn[], /* i : correlation between target and h[] */ + Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ + const Word16* startPos_ptr, /* i: ptr to read only table */ + Word16 codvec[], /* o : algebraic codebook vector */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ) + { + register Word16 i0; + register Word16 i1; + Word16 ix = 0; /* initialization only needed to keep gcc silent */ + register Word16 track1; + Word16 ipos[NB_PULSE]; + Word16 psk; + Word16 ps0; + Word16 ps1; + Word16 sq; + Word16 sq1; + Word16 alpk; + Word16 alp; + Word16 alp_16; + Word32 s; + Word32 alp0; + Word32 alp1; + register Word16 i; + Word32 L_temp; + Word16 *p_codvec = &codvec[0]; + + OSCL_UNUSED_ARG(pOverflow); + + psk = -1; + alpk = 1; + + /* Unrolled the following FOR loop to save MIPS */ + /* for (i = 0; i < NB_PULSE; i++) */ + /* { */ + /* *(codvec + i) = i; */ + /* } */ + + *(p_codvec++) = 0; + *(p_codvec) = 1; + + for (track1 = 0; track1 < 2; track1++) + { + /* fix starting position */ + + i = (subNr << 1) + (track1 << 3); + *ipos = *(startPos_ptr + i); + *(ipos + 1) = *(startPos_ptr + i + 1); + + + /*----------------------------------------------------------* + * i0 loop: try 8 positions. * + *----------------------------------------------------------*/ + + for (i0 = *ipos; i0 < L_CODE; i0 += STEP) + { + ps0 = *(dn + i0); + + /* Left shift by 1 converts integer product to */ + /* fractional product. */ + alp0 = (Word32) rr[i0][i0] << 14; + + /*--------------------------------------------------* + * i1 loop: 8 positions. * + *--------------------------------------------------*/ + + sq = -1; + alp = 1; + ix = *(ipos + 1); + + /*--------------------------------------------------* + * These index have low complexity address * + * computation because they are, in fact, pointers * + * with fixed increment. For example, "rr[i0][i2]" * + * is a pointer initialized to "&rr[i0][ipos[2]]" * + * and incremented by "STEP". * + *---------------------------------------------------*/ + + for (i1 = *(ipos + 1); i1 < L_CODE; i1 += STEP) + { + /* idx increment = STEP */ + /* ps1 = add(ps0, *(dn + i1), pOverflow); */ + ps1 = ps0 + dn[i1]; + + /* alp1 = alp0+rr[i0][i1]+1/2*rr[i1][i1]; */ + + /* idx incr = STEP */ + /* Extra left shift by 1 converts integer */ + /* product to fractional product */ + /* alp1 = L_add(alp0, s, pOverflow); */ + alp1 = alp0 + ((Word32) rr[i1][i1] << 14); + + /* idx incr = STEP */ + /* Extra left shift by 1 converts integer */ + /* product to fractional product */ + /* alp1 = L_add(alp1, s, pOverflow); */ + alp1 += (Word32) rr[i0][i1] << 15; + + /* sq1 = mult(ps1, ps1, pOverflow); */ + sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); + + /* alp_16 = pv_round(alp1, pOverflow); */ + alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); + + /* L_temp = L_mult(alp, sq1, pOverflow); */ + L_temp = ((Word32) alp * sq1) << 1; + + /* s = L_msu(L_temp, sq, alp_16, pOverflow); */ + s = L_temp - (((Word32) sq * alp_16) << 1); + + if (s > 0) + { + sq = sq1; + alp = alp_16; + ix = i1; + } + } + + /* memorize codevector if this one is better than the last one. */ + + /* L_temp = L_mult(alpk, sq, pOverflow); */ + L_temp = ((Word32) alpk * sq) << 1; + + /* s = L_msu(L_temp, psk, alp, pOverflow); */ + s = L_temp - (((Word32) psk * alp) << 1); + + if (s > 0) + { + psk = sq; + alpk = alp; + p_codvec = &codvec[0]; + *(p_codvec++) = i0; + *(p_codvec) = ix; + } + } + } + + return; + } + + /****************************************************************************/ + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: Test_search_2i40 + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + subNr = subframe number (Word16) + dn = vector containing the correlation between target and the impulse + response of the weighted synthesis filter (Word16) + rr = autocorrelation matrix (Word16) + codvec = algebraic codebook vector (Word16) + + Outputs: + codvec contains the newly calculated codevectors + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + startPos = table containing the start positions used by fixed codebook + routines (const Word16) + + ------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function provides external access to the local function search_2i40. + + ------------------------------------------------------------------------------ + REQUIREMENTS + + None + + ------------------------------------------------------------------------------ + REFERENCES + + [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + + ------------------------------------------------------------------------------ + PSEUDO-CODE + + CALL search_2i40 ( subNr = subNr + dn = dn + rr = rr + codvec = codvec ) + MODIFYING(nothing) + RETURNING(nothing) + + ------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + + ------------------------------------------------------------------------------ + */ + + void Test_search_2i40( + Word16 subNr, /* i : subframe number */ + Word16 dn[], /* i : correlation between target and h[] */ + Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ + const Word16* startPos_ptr, /* i : ptr to read-only table */ + Word16 codvec[], /* o : algebraic codebook vector */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ) + { + /*---------------------------------------------------------------------------- + CALL search_2i40 ( subNr = subNr + dn = dn + rr = rr + codvec = codvec ) + MODIFYING(nothing) + RETURNING(nothing) + ----------------------------------------------------------------------------*/ + search_2i40( + subNr, + dn, + rr, + startPos_ptr, + codvec, + pOverflow); + + return; + } + + /****************************************************************************/ + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: build_code + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + subNr = subframe number (Word16) + codvec = vector containing the position of pulses (Word16) + dn_sign = vector containing the sign of pulses (Word16) + cod = innovative code vector (Word16) + h = vector containing the impulse response of the weighted + synthesis filter (Word16) + y = vector containing the filtered innovative code (Word16) + sign = vector containing the sign of 2 pulses (Word16) + + Outputs: + cod vector contains the new innovative code + y vector contains the new filtered innovative code + sign vector contains the sign of 2 pulses + + Returns: + indx = codebook index (Word16) + + Global Variables Used: + None + + Local Variables Needed: + trackTable = table used for tracking codewords (Word16) + + ------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function builds the codeword, the filtered codeword and index of the + codevector, based on the signs and positions of 2 pulses. + + ------------------------------------------------------------------------------ + REQUIREMENTS + + None + + ------------------------------------------------------------------------------ + REFERENCES + + [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + + ------------------------------------------------------------------------------ + PSEUDO-CODE + + static Word16 build_code( + Word16 subNr, // i : subframe number + Word16 codvec[], // i : position of pulses + Word16 dn_sign[], // i : sign of pulses + Word16 cod[], // o : innovative code vector + Word16 h[], // i : impulse response of weighted synthesis filter + Word16 y[], // o : filtered innovative code + Word16 sign[] // o : sign of 2 pulses + ) + { + Word16 i, j, k, track, first, index, _sign[NB_PULSE], indx, rsign; + Word16 *p0, *p1, *pt; + Word32 s; + static Word16 trackTable[4*5] = { + 0, 1, 0, 1, -1, // subframe 1; track to code; -1 do not code this position + 0, -1, 1, 0, 1, // subframe 2 + 0, 1, 0, -1, 1, // subframe 3 + 0, 1, -1, 0, 1};// subframe 4 + + pt = &trackTable[add(subNr, shl(subNr, 2))]; + + for (i = 0; i < L_CODE; i++) { + cod[i] = 0; + } + + indx = 0; + rsign = 0; + for (k = 0; k < NB_PULSE; k++) { + i = codvec[k]; // read pulse position + j = dn_sign[i]; // read sign + + index = mult(i, 6554); // index = pos/5 + // track = pos%5 + track = sub(i, extract_l(L_shr(L_mult(index, 5), 1))); + + first = pt[track]; + + if (first == 0) { + if (k == 0) { + track = 0; + } else { + track = 1; + index = shl(index, 3); + } + } else { + if (k == 0) { + track = 0; + index = add(index, 64); // table bit is MSB + } else { + track = 1; + index = shl(index, 3); + } + } + + if (j > 0) { + cod[i] = 8191; + _sign[k] = 32767; + rsign = add(rsign, shl(1, track)); + } else { + cod[i] = -8192; + _sign[k] = (Word16) - 32768L; + } + + indx = add(indx, index); + } + *sign = rsign; + + p0 = h - codvec[0]; + p1 = h - codvec[1]; + + for (i = 0; i < L_CODE; i++) { + s = 0; + s = L_mac(s, *p0++, _sign[0]); + s = L_mac(s, *p1++, _sign[1]); + y[i] = pv_round(s); + } + + return indx; + } + + ------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + + ------------------------------------------------------------------------------ + */ + + static Word16 build_code( + Word16 subNr, /* i : subframe number */ + Word16 codvec[], /* i : position of pulses */ + Word16 dn_sign[], /* i : sign of pulses */ + Word16 cod[], /* o : innovative code vector */ + Word16 h[], /* i : impulse response of weighted synthesis */ + /* filter */ + Word16 y[], /* o : filtered innovative code */ + Word16 sign[], /* o : sign of 2 pulses */ + Flag *pOverflow /* o : Flag set when overflow occurs */ + ) + { + register Word16 i; + register Word16 j; + register Word16 k; + register Word16 track; + register Word16 first; + register Word16 index; + register Word16 rsign; + Word16 indx; + Word16 _sign[NB_PULSE]; + Word16 *p0; + Word16 *p1; + + const Word16 *pt; + + Word32 s; + + pt = trackTable + subNr + (subNr << 2); + + for (i = 0; i < L_CODE; i++) + { + *(cod + i) = 0; + } + + indx = 0; + rsign = 0; + + for (k = 0; k < NB_PULSE; k++) + { + i = *(codvec + k); /* read pulse position */ + j = *(dn_sign + i); /* read sign */ + + s = ((Word32)(i * 6554)) >> 15; + index = (Word16) s; /* index = pos/5 */ + + track = i - (5 * index); /* track = pos%5 */ + + first = *(pt + track); + + + if (k == 0) + { + track = 0; + + if (first != 0) + { + index += 64; /* table bit is MSB */ + } + } + else + { + track = 1; + index <<= 3; + } + + if (j > 0) + { + *(cod + i) = 8191; + *(_sign + k) = 32767; + rsign += (1 << track); + } + else + { + *(cod + i) = ~(8192) + 1; + *(_sign + k) = (Word16)(~(32768) + 1); + } + + indx += index; + } + + *sign = rsign; + + p0 = h - *codvec; + p1 = h - *(codvec + 1); + + for (i = 0; i < L_CODE; i++) + { + s = 0; + s = + L_mult( + *p0++, + *_sign, + pOverflow); + + s = + L_mac( + s, + *p1++, + *(_sign + 1), + pOverflow); + + *(y + i) = + pv_round( + s, + pOverflow); + } + + return(indx); + } + + /****************************************************************************/ + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: Test_build_code + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + subNr = subframe number (Word16) + codvec = vector containing the position of pulses (Word16) + dn_sign = vector containing the sign of pulses (Word16) + cod = innovative code vector (Word16) + h = vector containing the impulse response of the weighted + synthesis filter (Word16) + y = vector containing the filtered innovative code (Word16) + sign = vector containing the sign of 2 pulses (Word16) + + Outputs: + cod vector contains the new innovative code + y vector contains the new filtered innovative code + sign vector contains the sign of 2 pulses + + Returns: + indx = codebook index (Word16) + + Global Variables Used: + None + + Local Variables Needed: + trackTable = table used for tracking codewords (Word16) + + ------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function provides external access to the local function build_code. + + ------------------------------------------------------------------------------ + REQUIREMENTS + + None + + ------------------------------------------------------------------------------ + REFERENCES + + [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + + ------------------------------------------------------------------------------ + PSEUDO-CODE + + CALL build_code ( subNr = subNr + codvec = codvec + dn_sign = dn_sign + cod = cod + h = h + y = y + sign = sign ) + MODIFYING(nothing) + RETURNING(indx) + + ------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + + ------------------------------------------------------------------------------ + */ + + Word16 Test_build_code( + Word16 subNr, /* i : subframe number */ + Word16 codvec[], /* i : position of pulses */ + Word16 dn_sign[], /* i : sign of pulses */ + Word16 cod[], /* o : innovative code vector */ + Word16 h[], /* i : impulse response of weighted synthesis */ + /* filter */ + Word16 y[], /* o : filtered innovative code */ + Word16 sign[], /* o : sign of 2 pulses */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ) + { + Word16 test_index; + + /*---------------------------------------------------------------------------- + CALL build_code ( subNr = subNr + codvec = codvec + dn_sign = dn_sign + cod = cod + h = h + y = y + sign = sign ) + MODIFYING(nothing) + RETURNING(indx) + ----------------------------------------------------------------------------*/ + test_index = + build_code( + subNr, + codvec, + dn_sign, + cod, + h, + y, + sign, + pOverflow); + + return(test_index); + } + +#ifdef __cplusplus +} +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c2_9pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c2_9pf.h new file mode 100644 index 00000000..00093523 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c2_9pf.h @@ -0,0 +1,117 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c2_9pf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the c2_9pf.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef c2_9pf_h +#define c2_9pf_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 code_2i40_9bits( + Word16 subNr, /* i : subframe number */ + Word16 x[], /* i : target vector */ + Word16 h[], /* i : impulse response of weighted synthesis filter */ + /* h[-L_subfr..-1] must be set to zero. */ + Word16 T0, /* i : Pitch lag */ + Word16 pitch_sharp, /* i : Last quantized pitch gain */ + Word16 code[], /* o : Innovative codebook */ + Word16 y[], /* o : filtered fixed codebook excitation */ + Word16 * sign, /* o : Signs of 2 pulses */ + const Word16* startPos_ptr, /* ptr to read-only table */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _c2_9PF_H_ */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c3_14pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c3_14pf.cpp new file mode 100644 index 00000000..0b8a5967 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c3_14pf.cpp @@ -0,0 +1,748 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c3_14pf.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "c3_14pf.h" +#include "typedef.h" +#include "inv_sqrt.h" +#include "cnst.h" +#include "cor_h.h" +#include "set_sign.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +#define NB_PULSE 3 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ +static void search_3i40( + Word16 dn[], /* i : correlation between target and h[] */ + Word16 dn2[], /* i : maximum of corr. in each track. */ + Word16 rr[][L_CODE],/* i : matrix of autocorrelation */ + Word16 codvec[], /* o : algebraic codebook vector */ + Flag * pOverflow /* o : Flag set when overflow occurs */ +); + +static Word16 build_code( + Word16 codvec[], /* i : algebraic codebook vector */ + Word16 dn_sign[], /* i : sign of dn[] */ + Word16 cod[], /* o : algebraic (fixed) codebook excitation */ + Word16 h[], /* i : impulse response of weighted synthesis filter */ + Word16 y[], /* o : filtered fixed codebook excitation */ + Word16 sign[], /* o : sign of 3 pulses */ + Flag * pOverflow /* o : Flag set when overflow occurs */ +); + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: code_3i40_14bits +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + x[] Array of type Word16 -- target vector + h[] Array of type Word16 -- impulse response of weighted synthesis filter + h[-L_subfr..-1] must be set to zero. + + T0 Array of type Word16 -- Pitch lag + pitch_sharp, Array of type Word16 -- Last quantized pitch gain + + Outputs: + code[] Array of type Word16 -- Innovative codebook + y[] Array of type Word16 -- filtered fixed codebook excitation + * sign Pointer of type Word16 -- Pointer to the signs of 3 pulses + pOverflow Pointer to Flag -- set when overflow occurs + + Returns: + index + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Searches a 14 bit algebraic codebook containing 3 pulses + in a frame of 40 samples. + + DESCRIPTION: + The code length is 40, containing 3 nonzero pulses: i0...i2. + All pulses can have two possible amplitudes: +1 or -1. + Pulse i0 can have 8 possible positions, pulses i1 and i2 can have + 2x8=16 positions. + + i0 : 0, 5, 10, 15, 20, 25, 30, 35. + i1 : 1, 6, 11, 16, 21, 26, 31, 36. + 3, 8, 13, 18, 23, 28, 33, 38. + i2 : 2, 7, 12, 17, 22, 27, 32, 37. + 4, 9, 14, 19, 24, 29, 34, 39. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 code_3i40_14bits( + Word16 x[], /* i : target vector */ + Word16 h[], /* i : impulse response of weighted synthesis filter */ + /* h[-L_subfr..-1] must be set to zero. */ + Word16 T0, /* i : Pitch lag */ + Word16 pitch_sharp, /* i : Last quantized pitch gain */ + Word16 code[], /* o : Innovative codebook */ + Word16 y[], /* o : filtered fixed codebook excitation */ + Word16 * sign, /* o : Signs of 3 pulses */ + Flag * pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 codvec[NB_PULSE]; + Word16 dn[L_CODE]; + Word16 dn2[L_CODE]; + Word16 dn_sign[L_CODE]; + Word16 rr[L_CODE][L_CODE]; + Word16 i; + Word16 index; + Word16 sharp; + Word16 tempWord; + + /* sharp = shl(pitch_sharp, 1, pOverflow); */ + sharp = pitch_sharp << 1; + + if (T0 < L_CODE) + { + for (i = T0; i < L_CODE; i++) + { + tempWord = + mult( + h[i - T0], + sharp, + pOverflow); + + h[i] = + add_16( + h[i], + tempWord, + pOverflow); + } + } + + cor_h_x( + h, + x, + dn, + 1, + pOverflow); + + set_sign( + dn, + dn_sign, + dn2, + 6); + + cor_h( + h, + dn_sign, + rr, + pOverflow); + + search_3i40( + dn, + dn2, + rr, + codvec, + pOverflow); + + /* function result */ + index = + build_code( + codvec, + dn_sign, + code, + h, + y, + sign, + pOverflow); + + /*-----------------------------------------------------------------* + * Compute innovation vector gain. * + * Include fixed-gain pitch contribution into code[]. * + *-----------------------------------------------------------------*/ + + if (T0 < L_CODE) + { + for (i = T0; i < L_CODE; i++) + { + tempWord = + mult( + code[i - T0], + sharp, + pOverflow); + + code[i] = + add_16( + code[i], + tempWord, + pOverflow); + } + } + return index; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: search_3i40 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + dn[] Array of type Word16 -- correlation between target and h[] + dn2[] Array of type Word16 -- maximum of corr. in each track. + rr[][L_CODE] Double Array of type Word16 -- autocorrelation matrix + + Outputs: + codvec[] Array of type Word16 -- algebraic codebook vector + pOverflow Pointer to Flag -- set when overflow occurs + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Search the best codevector; determine positions of the 3 pulses + in the 40-sample frame. +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +static void search_3i40( + Word16 dn[], /* i : correlation between target and h[] */ + Word16 dn2[], /* i : maximum of corr. in each track. */ + Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ + Word16 codvec[], /* o : algebraic codebook vector */ + Flag * pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i0; + Word16 i1; + Word16 i2; + + Word16 ix = 0; /* initialization only needed to keep gcc silent */ + Word16 ps = 0; /* initialization only needed to keep gcc silent */ + + Word16 i; + Word16 pos; + Word16 track1; + Word16 track2; + Word16 ipos[NB_PULSE]; + + Word16 psk; + Word16 ps0; + Word16 ps1; + Word16 sq; + Word16 sq1; + Word16 alpk; + Word16 alp; + Word16 alp_16; + + Word16 *p_codvec = &codvec[0]; + + Word32 s; + Word32 alp0; + Word32 alp1; + + psk = -1; + alpk = 1; + + for (i = 0; i < NB_PULSE; i++) + { + *(p_codvec++) = i; + } + + for (track1 = 1; track1 < 4; track1 += 2) + { + for (track2 = 2; track2 < 5; track2 += 2) + { + /* fix starting position */ + + ipos[0] = 0; + ipos[1] = track1; + ipos[2] = track2; + + /*------------------------------------------------------------------* + * main loop: try 3 tracks. * + *------------------------------------------------------------------*/ + + for (i = 0; i < NB_PULSE; i++) + { + /*----------------------------------------------------------------* + * i0 loop: try 8 positions. * + *----------------------------------------------------------------*/ + + /* account for ptr. init. (rr[io]) */ + for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) + { + if (dn2[i0] >= 0) + { + ps0 = dn[i0]; + + /* alp0 = L_mult(rr[i0][i0],_1_4, pOverflow); */ + alp0 = (Word32) rr[i0][i0] << 14; + + /*----------------------------------------------------------------* + * i1 loop: 8 positions. * + *----------------------------------------------------------------*/ + + sq = -1; + alp = 1; + ps = 0; + ix = ipos[1]; + + /* initialize 4 index for next loop. */ + /*-------------------------------------------------------------------* + * These index have low complexity address computation because * + * they are, in fact, pointers with fixed increment. For example, * + * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]" * + * and incremented by "STEP". * + *-------------------------------------------------------------------*/ + + for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) + { + /* idx increment = STEP */ + /* ps1 = add(ps0, dn[i1], pOverflow); */ + ps1 = ps0 + dn[i1]; + + /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */ + + /* idx incr = STEP */ + /* alp1 = L_mac(alp0, rr[i1][i1], _1_4, pOverflow); */ + alp1 = alp0 + ((Word32) rr[i1][i1] << 14); + + /* idx incr = STEP */ + /* alp1 = L_mac(alp1, rr[i0][i1], _1_2, pOverflow); */ + alp1 += (Word32) rr[i0][i1] << 15; + + /* sq1 = mult(ps1, ps1, pOverflow); */ + sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); + + /* alp_16 = pv_round(alp1, pOverflow); */ + alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); + + /* s = L_mult(alp, sq1, pOverflow); */ + s = ((Word32) alp * sq1) << 1; + + /* s = L_msu(s, sq, alp_16, pOverflow); */ + s -= (((Word32) sq * alp_16) << 1); + + if (s > 0) + { + sq = sq1; + ps = ps1; + alp = alp_16; + ix = i1; + } + } + i1 = ix; + + /*----------------------------------------------------------------* + * i2 loop: 8 positions. * + *----------------------------------------------------------------*/ + + ps0 = ps; + + /* alp0 = L_mult(alp, _1_4, pOverflow); */ + alp0 = (Word32) alp << 14; + + sq = -1; + alp = 1; + ps = 0; + ix = ipos[2]; + + /* initialize 4 index for next loop (see i1 loop) */ + + for (i2 = ipos[2]; i2 < L_CODE; i2 += STEP) + { + /* index increment = STEP */ + /* ps1 = add(ps0, dn[i2], pOverflow); */ + ps1 = ps0 + dn[i2]; + + /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */ + + /* idx incr = STEP */ + /* alp1 = L_mac(alp0, rr[i2][i2], _1_16, pOverflow); */ + alp1 = alp0 + ((Word32) rr[i2][i2] << 12); + + /* idx incr = STEP */ + /* alp1 = L_mac(alp1, rr[i1][i2], _1_8, pOverflow); */ + alp1 += (Word32) rr[i1][i2] << 13; + + /* idx incr = STEP */ + /* alp1 = L_mac(alp1,rr[i0][i2], _1_8, pOverflow); */ + alp1 += (Word32) rr[i0][i2] << 13; + + /* sq1 = mult(ps1, ps1, pOverflow); */ + sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); + + /* alp_16 = pv_round(alp1, pOverflow); */ + alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); + + /* s = L_mult(alp, sq1, pOverflow); */ + s = ((Word32) alp * sq1) << 1; + + /* s = L_msu(s, sq, alp_16, pOverflow); */ + s -= (((Word32) sq * alp_16) << 1); + + if (s > 0) + { + sq = sq1; + ps = ps1; + alp = alp_16; + ix = i2; + } + } + i2 = ix; + + /* memorize codevector if this one + * is better than the last one. + */ + + s = L_mult(alpk, sq, pOverflow); + //s = ((Word32) alpk * sq) << 1; + + s = L_msu(s, psk, alp, pOverflow); + //s -= (((Word32) psk * alp) << 1); + + if (s > 0) + { + psk = sq; + alpk = alp; + p_codvec = &codvec[0]; + + *(p_codvec++) = i0; + *(p_codvec++) = i1; + *(p_codvec) = i2; + } + } + } + /*----------------------------------------------------------------* + * Cyclic permutation of i0, i1 and i2. * + *----------------------------------------------------------------*/ + + pos = ipos[2]; + ipos[2] = ipos[1]; + ipos[1] = ipos[0]; + ipos[0] = pos; + } + } + } + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: build_code() +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + codvec[] Array of type Word16 -- position of pulses + dn_sign[] Array of type Word16 -- sign of pulses + h[] Array of type Word16 -- impulse response of + weighted synthesis filter + + Outputs: + cod[] Array of type Word16 -- innovative code vector + y[] Array of type Word16 -- filtered innovative code + sign[] Array of type Word16 -- sign of 3 pulses + pOverflow Pointer to Flag -- set when overflow occurs + + Returns: + indx + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Builds the codeword, the filtered codeword and index of the + codevector, based on the signs and positions of 3 pulses. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 +build_code( + Word16 codvec[], /* i : position of pulses */ + Word16 dn_sign[], /* i : sign of pulses */ + Word16 cod[], /* o : innovative code vector */ + Word16 h[], /* i : impulse response of weighted synthesis filter */ + Word16 y[], /* o : filtered innovative code */ + Word16 sign[], /* o : sign of 3 pulses */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 j; + Word16 k; + Word16 track; + Word16 index; + Word16 _sign[NB_PULSE]; + Word16 indx; + Word16 rsign; + + Word16 *p0; + Word16 *p1; + Word16 *p2; + + Word32 s; + + for (i = 0; i < L_CODE; i++) + { + cod[i] = 0; + } + + indx = 0; + rsign = 0; + + for (k = 0; k < NB_PULSE; k++) + { + i = codvec[k]; /* read pulse position */ + j = dn_sign[i]; /* read sign */ + + /* index = pos/5 */ + /* index = mult(i, 6554, pOverflow); */ + index = (Word16)(((Word32) i * 6554) >> 15); + + /* track = pos%5 */ + /* s = L_mult(index, 5, pOverflow); */ + s = ((Word32) index * 5) << 1; + + /* s = L_shr(s, 1, pOverflow); */ + s >>= 1; + + /* track = sub(i, (Word16) s, pOverflow); */ + track = i - (Word16) s; + + if (track == 1) + { + /* index = shl(index, 4, pOverflow); */ + index <<= 4; + } + else if (track == 2) + { + track = 2; + + /* index = shl(index, 8, pOverflow); */ + index <<= 8; + } + else if (track == 3) + { + track = 1; + + /* index = shl(index, 4, pOverflow); */ + index <<= 4; + + /* index = add(index, 8, pOverflow); */ + index += 8; + } + else if (track == 4) + { + track = 2; + + /* index = shl(index, 8, pOverflow); */ + index <<= 8; + + /* index = add(index, 128, pOverflow); */ + index += 128; + } + + if (j > 0) + { + cod[i] = 8191; + _sign[k] = 32767; + + /* track = shl(1, track, pOverflow); */ + track = 1 << track; + + /* rsign = add(rsign, track, pOverflow); */ + rsign += track; + } + else + { + cod[i] = -8192; + _sign[k] = (Word16) - 32768L; + } + + /* indx = add(indx, index, pOverflow); */ + indx += index; + } + *sign = rsign; + + p0 = h - codvec[0]; + p1 = h - codvec[1]; + p2 = h - codvec[2]; + + for (i = 0; i < L_CODE; i++) + { + s = 0; + s = + L_mac( + s, + *p0++, + _sign[0], + pOverflow); + + s = + L_mac( + s, + *p1++, + _sign[1], + pOverflow); + + s = + L_mac( + s, + *p2++, + _sign[2], + pOverflow); + + y[i] = + pv_round( + s, + pOverflow); + } + + return indx; +} + + + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c3_14pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c3_14pf.h new file mode 100644 index 00000000..85cf47b1 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c3_14pf.h @@ -0,0 +1,114 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c3_14pf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by c3_14pf.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef c3_14pf_h +#define c3_14pf_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + Word16 code_3i40_14bits( + Word16 x[], /* (i) : target vector */ + Word16 h[], /* (i) : impulse response of weighted synthesis filter */ + /* h[-L_subfr..-1] must be set to zero. */ + Word16 T0, /* (i) : Pitch lag */ + Word16 pitch_sharp, /* (i) : Last quantized pitch gain */ + Word16 code[], /* (o) : Innovative codebook */ + Word16 y[], /* (o) : filtered fixed codebook excitation */ + Word16 * sign, /* (o) : Signs of 3 pulses */ + Flag *pOverflow + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _c3_14PF_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c4_17pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c4_17pf.cpp new file mode 100644 index 00000000..e5110927 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c4_17pf.cpp @@ -0,0 +1,823 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c4_17pf.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Purpose : Searches a 17 bit algebraic codebook containing 4 pulses + in a frame of 40 samples +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "c4_17pf.h" +#include "typedef.h" +#include "inv_sqrt.h" +#include "cnst.h" +#include "cor_h.h" +#include "set_sign.h" +#include "basic_op.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ +#define NB_PULSE 4 + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + static void search_4i40( + Word16 dn[], /* i : correlation between target and h[] */ + Word16 dn2[], /* i : maximum of corr. in each track. */ + Word16 rr[][L_CODE],/* i : matrix of autocorrelation */ + Word16 codvec[], /* o : algebraic codebook vector */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ); + + static Word16 build_code( + Word16 codvec[], /* i : algebraic codebook vector */ + Word16 dn_sign[], /* i : sign of dn[] */ + Word16 cod[], /* o : algebraic (fixed) codebook excitation */ + Word16 h[], /* i : impulse response of weighted synthesis filter */ + Word16 y[], /* o : filtered fixed codebook excitation */ + Word16 sign[], /* o : index of 4 pulses (position+sign+ampl)*4 */ + const Word16* gray_ptr, /* i : ptr to read-only table */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ); + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: code_4i40_17bits() + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + x[] Array of type Word16 -- target vector + h[] Array of type Word16 -- impulse response of weighted synthesis filter + h[-L_subfr..-1] must be set to zero. + + T0 Array of type Word16 -- Pitch lag + pitch_sharp, Array of type Word16 -- Last quantized pitch gain + + Outputs: + code[] Array of type Word16 -- Innovative codebook + y[] Array of type Word16 -- filtered fixed codebook excitation + * sign Pointer of type Word16 -- Pointer to the signs of 4 pulses + pOverflow Pointer to Flag -- set when overflow occurs + + Returns: + index + + Global Variables Used: + None + + Local Variables Needed: + + ------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Searches a 17 bit algebraic codebook containing 4 pulses + in a frame of 40 samples. + + DESCRIPTION: + The code length is 40, containing 4 nonzero pulses: i0...i3. + All pulses can have two possible amplitudes: +1 or -1. + Pulse i0 to i2 can have 8 possible positions, pulse i3 can have + 2x8=16 positions. + + i0 : 0, 5, 10, 15, 20, 25, 30, 35. + i1 : 1, 6, 11, 16, 21, 26, 31, 36. + i2 : 2, 7, 12, 17, 22, 27, 32, 37. + i3 : 3, 8, 13, 18, 23, 28, 33, 38. + 4, 9, 14, 19, 24, 29, 34, 39. + + ------------------------------------------------------------------------------ + REQUIREMENTS + + None + + ------------------------------------------------------------------------------ + REFERENCES + + [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + + ------------------------------------------------------------------------------ + PSEUDO-CODE + + ------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + + ------------------------------------------------------------------------------ + */ + + Word16 code_4i40_17bits( + Word16 x[], /* i : target vector */ + Word16 h[], /* i : impulse response of weighted synthesis filter */ + /* h[-L_subfr..-1] must be set to zero. */ + Word16 T0, /* i : Pitch lag */ + Word16 pitch_sharp, /* i : Last quantized pitch gain */ + Word16 code[], /* o : Innovative codebook */ + Word16 y[], /* o : filtered fixed codebook excitation */ + Word16 * sign, /* o : Signs of 4 pulses */ + const Word16* gray_ptr, /* i : ptr to read-only table */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ) + { + Word16 codvec[NB_PULSE]; + Word16 dn[L_CODE]; + Word16 dn2[L_CODE]; + Word16 dn_sign[L_CODE]; + + Word16 rr[L_CODE][L_CODE]; + Word16 i; + Word16 index; + Word16 sharp; + Word16 tempWord; + + sharp = pitch_sharp << 1; + + if (T0 < L_CODE) + { + for (i = T0; i < L_CODE; i++) + { + tempWord = + mult( + h[i - T0], + sharp, + pOverflow); + + h[i] = + add_16( + h[i], + tempWord, + pOverflow); + } + } + + cor_h_x( + h, + x, + dn, + 1, + pOverflow); + + set_sign( + dn, + dn_sign, + dn2, + 4); + + cor_h( + h, + dn_sign, + rr, + pOverflow); + + search_4i40( + dn, + dn2, + rr, + codvec, + pOverflow); + + /* function result */ + index = + build_code( + codvec, + dn_sign, + code, + h, + y, + sign, + gray_ptr, + pOverflow); + + /*-----------------------------------------------------------------* + * Compute innovation vector gain. * + * Include fixed-gain pitch contribution into code[]. * + *-----------------------------------------------------------------*/ + + tempWord = T0 - L_CODE; + + if (tempWord < 0) + { + for (i = T0; i < L_CODE; i++) + { + tempWord = + mult( + code[i - T0], + sharp, + pOverflow); + + code[i] = + add_16( + code[i], + tempWord, + pOverflow); + } + } + + return index; + } + /****************************************************************************/ + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: search_4i40() + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + dn[] Array of type Word16 -- correlation between target and h[] + dn2[] Array of type Word16 -- maximum of corr. in each track. + rr[][L_CODE] Double Array of type Word16 -- autocorrelation matrix + + Outputs: + codvec[] Array of type Word16 -- algebraic codebook vector + pOverflow Pointer to Flag -- set when overflow occurs + + Returns: + + + Global Variables Used: + None + + Local Variables Needed: + + + ------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Search the best codevector; determine positions of the 4 pulses + in the 40-sample frame. + + ------------------------------------------------------------------------------ + REQUIREMENTS + + None + + ------------------------------------------------------------------------------ + REFERENCES + + [1] c4_17pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + + ------------------------------------------------------------------------------ + PSEUDO-CODE + + ------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + + ------------------------------------------------------------------------------ + */ + static void search_4i40( + Word16 dn[], /* i : correlation between target and h[] */ + Word16 dn2[], /* i : maximum of corr. in each track. */ + Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ + Word16 codvec[], /* o : algebraic codebook vector */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ) + { + Word16 i0; + Word16 i1; + Word16 i2; + Word16 i3; + + Word16 ix = 0; /* initialization only needed to keep gcc silent */ + Word16 ps = 0; /* initialization only needed to keep gcc silent */ + + Word16 i; + Word16 pos; + Word16 track; + Word16 ipos[NB_PULSE]; + + Word16 psk; + Word16 ps0; + Word16 ps1; + Word16 sq; + Word16 sq1; + + Word16 alpk; + Word16 alp; + Word16 alp_16; + Word16 *p_codvec = &codvec[0]; + + Word32 s; + Word32 alp0; + Word32 alp1; + + OSCL_UNUSED_ARG(pOverflow); + + /* Default value */ + psk = -1; + alpk = 1; + for (i = 0; i < NB_PULSE; i++) + { + *(p_codvec++) = i; + } + + for (track = 3; track < 5; track++) + { + /* fix starting position */ + + ipos[0] = 0; + ipos[1] = 1; + ipos[2] = 2; + ipos[3] = track; + + /*------------------------------------------------------------------* + * main loop: try 4 tracks. * + *------------------------------------------------------------------*/ + + for (i = 0; i < NB_PULSE; i++) + { + /*----------------------------------------------------------------* + * i0 loop: try 4 positions (use position with max of corr.). * + *----------------------------------------------------------------*/ + + for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) + { + if (dn2[i0] >= 0) + { + ps0 = dn[i0]; + + alp0 = (Word32) rr[i0][i0] << 14; + + /*----------------------------------------------------------------* + * i1 loop: 8 positions. * + *----------------------------------------------------------------*/ + + sq = -1; + alp = 1; + ps = 0; + ix = ipos[1]; + + /* initialize 4 index for next loop. */ + /*-------------------------------------------------------------------* + * These index have low complexity address computation because * + * they are, in fact, pointers with fixed increment. For example, * + * "rr[i0][i3]" is a pointer initialized to "&rr[i0][ipos[3]]" * + * and incremented by "STEP". * + *-------------------------------------------------------------------*/ + + for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) + { + /* idx increment = STEP */ + /* ps1 = add(ps0, dn[i1], pOverflow); */ + ps1 = ps0 + dn[i1]; + + /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */ + + /* alp1 = L_mac(alp0, rr[i1][i1], _1_4, pOverflow); */ + alp1 = alp0 + ((Word32) rr[i1][i1] << 14); + + /* alp1 = L_mac(alp1, rr[i0][i1], _1_2, pOverflow); */ + alp1 += (Word32) rr[i0][i1] << 15; + + /* sq1 = mult(ps1, ps1, pOverflow); */ + sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); + + /* alp_16 = pv_round(alp1, pOverflow); */ + alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); + + /* s = L_mult(alp, sq1, pOverflow); */ + s = ((Word32) alp * sq1) << 1; + + /* s = L_msu(s, sq, alp_16, pOverflow); */ + s -= (((Word32) sq * alp_16) << 1); + + if (s > 0) + { + sq = sq1; + ps = ps1; + alp = alp_16; + ix = i1; + } + } + i1 = ix; + + /*----------------------------------------------------------------* + * i2 loop: 8 positions. * + *----------------------------------------------------------------*/ + + ps0 = ps; + + /* alp0 = L_mult(alp, _1_4, pOverflow); */ + alp0 = (Word32) alp << 14; + + sq = -1; + alp = 1; + ps = 0; + ix = ipos[2]; + + /* initialize 4 index for next loop (see i1 loop) */ + + for (i2 = ipos[2]; i2 < L_CODE; i2 += STEP) + { + /* index increment = STEP */ + /* ps1 = add(ps0, dn[i2], pOverflow); */ + ps1 = ps0 + dn[i2]; + + /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */ + + /* idx incr = STEP */ + /* alp1 = L_mac(alp0, rr[i2][i2], _1_16, pOverflow); */ + alp1 = alp0 + ((Word32) rr[i2][i2] << 12); + + /* idx incr = STEP */ + /* alp1 = L_mac(alp1, rr[i1][i2], _1_8, pOverflow); */ + alp1 += (Word32) rr[i1][i2] << 13; + + /* idx incr = STEP */ + /* alp1 = L_mac(alp1,rr[i0][i2], _1_8, pOverflow); */ + alp1 += (Word32) rr[i0][i2] << 13; + + /* sq1 = mult(ps1, ps1, pOverflow); */ + sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); + + /* alp_16 = pv_round(alp1, pOverflow); */ + alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); + + /* s = L_mult(alp, sq1, pOverflow); */ + s = ((Word32) alp * sq1) << 1; + + /* s = L_msu(s, sq, alp_16, pOverflow); */ + s -= (((Word32) sq * alp_16) << 1); + + if (s > 0) + { + sq = sq1; + ps = ps1; + alp = alp_16; + ix = i2; + } + } + i2 = ix; + + /*----------------------------------------------------------------* + * i3 loop: 8 positions. * + *----------------------------------------------------------------*/ + + ps0 = ps; + alp0 = ((Word32)alp << 16); + + sq = -1; + alp = 1; + ps = 0; + ix = ipos[3]; + + /* initialize 5 index for next loop (see i1 loop) */ + + for (i3 = ipos[3]; i3 < L_CODE; i3 += STEP) + { + /* ps1 = add(ps0, dn[i3], pOverflow); */ + ps1 = ps0 + dn[i3]; /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */ + + /* alp1 = L_mac(alp0, rr[i3][i3], _1_16, pOverflow); */ + alp1 = alp0 + ((Word32) rr[i3][i3] << 12); /* idx incr = STEP */ + + /* alp1 = L_mac(alp1, rr[i2][i3], _1_8, pOverflow); */ + alp1 += (Word32) rr[i2][i3] << 13; /* idx incr = STEP */ + + /* alp1 = L_mac(alp1, rr[i1][i3], _1_8, pOverflow); */ + alp1 += (Word32) rr[i1][i3] << 13; /* idx incr = STEP */ + + /* alp1 = L_mac(alp1, rr[i0][i3], _1_8, pOverflow); */ + alp1 += (Word32) rr[i0][i3] << 13; /* idx incr = STEP */ + + /* sq1 = mult(ps1, ps1, pOverflow); */ + sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); + + /* alp_16 = pv_round(alp1, pOverflow); */ + alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); + + /* s = L_mult(alp, sq1, pOverflow); */ + s = ((Word32) alp * sq1) << 1; + + /* s = L_msu(s, sq, alp_16, pOverflow); */ + s -= (((Word32) sq * alp_16) << 1); + + if (s > 0) + { + sq = sq1; + ps = ps1; + alp = alp_16; + ix = i3; + } + } + + + /*----------------------------------------------------------------* + * memorise codevector if this one is better than the last one. * + *----------------------------------------------------------------*/ + + /* s = L_mult(alpk, sq, pOverflow); */ + s = ((Word32) alpk * sq) << 1; + + /* s = L_msu(s, psk, alp, pOverflow); */ + s -= (((Word32) psk * alp) << 1); + + if (s > 0) + { + psk = sq; + alpk = alp; + p_codvec = &codvec[0]; + + *(p_codvec++) = i0; + *(p_codvec++) = i1; + *(p_codvec++) = i2; + *(p_codvec) = ix; + } + } + } + + /*----------------------------------------------------------------* + * Cyclic permutation of i0,i1,i2 and i3. * + *----------------------------------------------------------------*/ + + pos = ipos[3]; + ipos[3] = ipos[2]; + ipos[2] = ipos[1]; + ipos[1] = ipos[0]; + ipos[0] = pos; + } + } + + return; + } + + + + + /****************************************************************************/ + + /* + ------------------------------------------------------------------------------ + FUNCTION NAME: build_code() + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + codvec[] Array of type Word16 -- position of pulses + dn_sign[] Array of type Word16 -- sign of pulses + h[] Array of type Word16 -- impulse response of + weighted synthesis filter + + Outputs: + cod[] Array of type Word16 -- innovative code vector + y[] Array of type Word16 -- filtered innovative code + sign[] Array of type Word16 -- index of 4 pulses (sign + position) + pOverflow Pointer to Flag -- set when overflow occurs + + Returns: + indx + + Global Variables Used: + None + + Local Variables Needed: + + ------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Builds the codeword, the filtered codeword and index of the + codevector, based on the signs and positions of 4 pulses. + + ------------------------------------------------------------------------------ + REQUIREMENTS + + None + + ------------------------------------------------------------------------------ + REFERENCES + + [1] c4_17pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + + ------------------------------------------------------------------------------ + PSEUDO-CODE + + ------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + + ------------------------------------------------------------------------------ + */ + + static Word16 + build_code( + Word16 codvec[], /* i : position of pulses */ + Word16 dn_sign[], /* i : sign of pulses */ + Word16 cod[], /* o : innovative code vector */ + Word16 h[], /* i : impulse response of weighted synthesis filter */ + Word16 y[], /* o : filtered innovative code */ + Word16 sign[], /* o : index of 4 pulses (sign+position) */ + const Word16* gray_ptr, /* i : ptr to read-only table */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ) + { + Word16 i; + Word16 j; + Word16 k; + Word16 track; + Word16 index; + Word16 _sign[NB_PULSE]; + Word16 indx; + Word16 rsign; + + Word16 *p0; + Word16 *p1; + Word16 *p2; + Word16 *p3; + Word16 *p_cod = &cod[0]; + + Word32 s; + + for (i = 0; i < L_CODE; i++) + { + *(p_cod++) = 0; + } + + indx = 0; + rsign = 0; + + for (k = 0; k < NB_PULSE; k++) + { + i = codvec[k]; /* read pulse position */ + j = dn_sign[i]; /* read sign */ + + /* index = pos/5 */ + /* index = mult(i, 6554, pOverflow); */ + index = (Word16)(((Word32) i * 6554) >> 15); + + /* track = pos%5 */ + /* s = L_mult(index, 5, pOverflow); */ + s = ((Word32) index * 5) << 1; + + /* s = L_shr(s, 1, pOverflow); */ + s >>= 1; + + /* track = sub(i, (Word16) s, pOverflow); */ + track = i - (Word16) s; + + index = gray_ptr[index]; + + if (track == 1) + { + /* index = shl(index, 3, pOverflow); */ + index <<= 3; + } + else if (track == 2) + { + /* index = shl(index, 6, pOverflow); */ + index <<= 6; + } + else if (track == 3) + { + /* index = shl(index, 10, pOverflow); */ + index <<= 10; + } + else if (track == 4) + { + track = 3; + + /* index = shl(index, 10, pOverflow); */ + index <<= 10; + + /* index = add(index, 512, pOverflow); */ + index += 512; + } + + if (j > 0) + { + cod[i] = 8191; + _sign[k] = 32767; + + /* track = shl(1, track, pOverflow); */ + track = 1 << track; + + /* rsign = add(rsign, track, pOverflow); */ + rsign += track; + } + else + { + cod[i] = -8192; + _sign[k] = (Word16) - 32768L; + } + + /* indx = add(indx, index, pOverflow); */ + indx += index; + } + *sign = rsign; + + p0 = h - codvec[0]; + p1 = h - codvec[1]; + p2 = h - codvec[2]; + p3 = h - codvec[3]; + + for (i = 0; i < L_CODE; i++) + { + s = 0; + s = + L_mac( + s, + *p0++, + _sign[0], + pOverflow); + + s = + L_mac( + s, + *p1++, + _sign[1], + pOverflow); + + s = + L_mac( + s, + *p2++, + _sign[2], + pOverflow); + + s = + L_mac( + s, + *p3++, + _sign[3], + pOverflow); + + y[i] = + pv_round( + s, + pOverflow); + + } /* for (i = 0; i < L_CODE; i++) */ + + return indx; + + } /* build_code */ + +#ifdef __cplusplus +} +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c4_17pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c4_17pf.h new file mode 100644 index 00000000..5237595b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c4_17pf.h @@ -0,0 +1,115 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c4_17pf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the c4_17pf.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef c4_17pf_h +#define c4_17pf_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 code_4i40_17bits( + Word16 x[], /* (i) : target vector */ + Word16 h[], /* (i) : impulse response of weighted synthesis filter */ + /* h[-L_subfr..-1] must be set to zero. */ + Word16 T0, /* (i) : Pitch lag */ + Word16 pitch_sharp, /* (i) : Last quantized pitch gain */ + Word16 code[], /* (o) : Innovative codebook */ + Word16 y[], /* (o) : filtered fixed codebook excitation */ + Word16 * sign, /* (o) : Signs of 4 pulses */ + const Word16* gray_ptr, /* i : ptr to read-only table */ + Flag * pOverflow /* (o) : Flag set when overflow occurs */ + ); + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _c4_17PF_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c8_31pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c8_31pf.cpp new file mode 100644 index 00000000..9245ce41 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c8_31pf.cpp @@ -0,0 +1,745 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c8_31pf.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Purpose : Searches a 31 bit algebraic codebook containing + : 8 pulses in a frame of 40 samples. + : in the same manner as GSM-EFR +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "c8_31pf.h" +#include "typedef.h" +#include "cnst.h" +#include "inv_sqrt.h" +#include "cor_h.h" +#include "cor_h_x2.h" +#include "set_sign.h" +#include "s10_8pf.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define NB_PULSE 8 + +/* define values/representation for output codevector and sign */ +#define POS_CODE 8191 +#define NEG_CODE 8191 +#define POS_SIGN 32767 +#define NEG_SIGN (Word16) (-32768L) + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + codvec[] Array of type Word16 -- position of pulses + sign[] Array of type Word16 -- sign of pulses + h[] Array of type Word16 -- impulse response of + weighted synthesis filter + Outputs: + cod[] Array of type Word16 -- innovative code vector + y[] Array of type Word16 -- filtered innovative code + sign_indx[] Array of type Word16 -- signs of 4 pulses (signs only) + pos_indx[] Array of type Word16 -- + position index of 8 pulses(position only) + + pOverflow Pointer to Flag -- set when overflow occurs + + Returns: + indx + + Global Variables Used: + None + + Local Variables Needed: + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] c8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/************************************************************************* + * + * FUNCTION: build_code() + * + * PURPOSE: Builds the codeword, the filtered codeword and a + * linear uncombined version of the index of the + * codevector, based on the signs and positions of 8 pulses. + * + *************************************************************************/ + +static void build_code( + Word16 codvec[], /* i : position of pulses */ + Word16 sign[], /* i : sign of d[n] */ + Word16 cod[], /* o : innovative code vector */ + Word16 h[], /* i : impulse response of weighted synthesis filter*/ + Word16 y[], /* o : filtered innovative code */ + Word16 sign_indx[], /* o : signs of 4 pulses (signs only) */ + Word16 pos_indx[], /* o : position index of 8 pulses(position only) */ + Flag * pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 j; + Word16 k; + Word16 track; + Word16 sign_index; + Word16 pos_index; + Word16 _sign[NB_PULSE]; + + Word16 *p0; + Word16 *p1; + Word16 *p2; + Word16 *p3; + Word16 *p4; + Word16 *p5; + Word16 *p6; + Word16 *p7; + + Word16 *p_cod = &cod[0]; + Word16 *p_codvec = &codvec[0]; + + Word32 s; + + for (i = 0; i < L_CODE; i++) + { + *(p_cod++) = 0; + } + + for (i = 0; i < NB_TRACK_MR102; i++) + { + pos_indx[i] = -1; + sign_indx[i] = -1; + } + + for (k = 0; k < NB_PULSE; k++) + { + /* read pulse position */ + i = codvec[k]; + /* read sign */ + j = sign[i]; + + pos_index = i >> 2; /* index = pos/4 */ + + track = i & 3; /* track = pos%4 */ + + if (j > 0) + { + cod[i] = (Word16)((Word32) cod[i] + POS_CODE); + + _sign[k] = POS_SIGN; + sign_index = 0; /* bit=0 -> positive pulse */ + } + else + { + cod[i] = (Word16)((Word32) cod[i] - NEG_CODE); + + _sign[k] = NEG_SIGN; + sign_index = 1; /* bit=1 => negative pulse */ + /* index = add (index, 8); 1 = negative old code */ + } + + if (pos_indx[track] < 0) + { /* first set first NB_TRACK pulses */ + pos_indx[track] = pos_index; + sign_indx[track] = sign_index; + } + else + { /* 2nd row of pulses , test if positions needs to be switched */ + if (((sign_index ^ sign_indx[track]) & 1) == 0) + { + /* sign of 1st pulse == sign of 2nd pulse */ + + if (pos_indx[track] <= pos_index) + { /* no swap */ + pos_indx[track + NB_TRACK_MR102] = pos_index; + } + else + { /* swap*/ + pos_indx[track + NB_TRACK_MR102] = pos_indx[track]; + + pos_indx[track] = pos_index; + sign_indx[track] = sign_index; + } + } + else + { + /* sign of 1st pulse != sign of 2nd pulse */ + + if (pos_indx[track] <= pos_index) + { /*swap*/ + pos_indx[track + NB_TRACK_MR102] = pos_indx[track]; + + pos_indx[track] = pos_index; + sign_indx[track] = sign_index; + } + else + { /*no swap */ + pos_indx[track + NB_TRACK_MR102] = pos_index; + } + } + } + } + + p0 = h - *(p_codvec++); + p1 = h - *(p_codvec++); + p2 = h - *(p_codvec++); + p3 = h - *(p_codvec++); + p4 = h - *(p_codvec++); + p5 = h - *(p_codvec++); + p6 = h - *(p_codvec++); + p7 = h - *(p_codvec); + + for (i = 0; i < L_CODE; i++) + { + s = 0; + + s = + L_mac( + s, + *p0++, + _sign[0], + pOverflow); + s = + L_mac( + s, + *p1++, + _sign[1], + pOverflow); + s = + L_mac( + s, + *p2++, + _sign[2], + pOverflow); + s = + L_mac( + s, + *p3++, + _sign[3], + pOverflow); + s = + L_mac( + s, + *p4++, + _sign[4], + pOverflow); + s = + L_mac( + s, + *p5++, + _sign[5], + pOverflow); + s = + L_mac( + s, + *p6++, + _sign[6], + pOverflow); + s = + L_mac( + s, + *p7++, + _sign[7], + pOverflow); + + y[i] = + pv_round( + s, + pOverflow); + + } /* for (i = 0; i < L_CODE; i++) */ + +} /* build_code */ + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: compress_code() +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + + Outputs: + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + FUNCTION: + + PURPOSE: compression of three indeces [0..9] to one 10 bit index + minimizing the phase shift of a bit error. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] c8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 compress10( + Word16 pos_indxA, /* i : signs of 4 pulses (signs only) */ + Word16 pos_indxB, /* i : position index of 8 pulses (pos only) */ + Word16 pos_indxC, /* i : position and sign of 8 pulses (compressed) */ + Flag *pOverflow) /* o : Flag set when overflow occurs */ +{ + Word16 indx; + Word16 ia; + Word16 ib; + Word16 ic; + + Word32 tempWord32; + + OSCL_UNUSED_ARG(pOverflow); + + ia = pos_indxA >> 1; + + ib = pos_indxB >> 1; + + tempWord32 = ((Word32) ib * 5) << 1; + + tempWord32 = tempWord32 >> 1; + + ib = (Word16) tempWord32; + + ic = pos_indxC >> 1; + + tempWord32 = ((Word32) ic * 25) << 1; + + tempWord32 = tempWord32 >> 1; + + ic = (Word16) tempWord32; + + ib += ic; + + ib += ia; + + indx = ib << 3; + + ia = pos_indxA & 1; + + ib = ((Word16)(pos_indxB & 1)) << 1; + + ic = ((Word16)(pos_indxC & 1)) << 2; + + ib += ic; + + ib += ia; + + indx += ib; + + return indx; + +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: compress_code() +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + sign_indx Array of type Word16 -- signs of 4 pulses (signs only) + pos_indx Array of type Word16 -- position index of 8 pulses + (position only) + + Outputs: + indx Array of type Word16 -- position and sign of 8 pulses + (compressed) + pOverflow Pointer to Flag -- set when overflow occurs + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: compression of the linear codewords to 4+three indeces + one bit from each pulse is made robust to errors by + minimizing the phase shift of a bit error. + 4 signs (one for each track) + i0,i4,i1 => one index (7+3) bits, 3 LSBs more robust + i2,i6,i5 => one index (7+3) bits, 3 LSBs more robust + i3,i7 => one index (5+2) bits, 2-3 LSbs more robust + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void compress_code( + Word16 sign_indx[], /* i : signs of 4 pulses (signs only) */ + Word16 pos_indx[], /* i : position index of 8 pulses (position only) */ + Word16 indx[], /* o : position and sign of 8 pulses (compressed) */ + Flag *pOverflow) /* o : Flag set when overflow occurs */ +{ + Word16 i; + Word16 ia; + Word16 ib; + Word16 ic; + + Word16 *p_indx = &indx[0]; + Word16 *p_sign_indx = &sign_indx[0]; + + Word32 tempWord32; + + for (i = 0; i < NB_TRACK_MR102; i++) + { + *(p_indx++) = *(p_sign_indx++); + } + + /* First index + indx[NB_TRACK] = (ia/2+(ib/2)*5 +(ic/2)*25)*8 + ia%2 + (ib%2)*2 + (ic%2)*4; */ + + indx[NB_TRACK_MR102] = + compress10( + pos_indx[0], + pos_indx[4], + pos_indx[1], + pOverflow); + + /* Second index + indx[NB_TRACK+1] = (ia/2+(ib/2)*5 +(ic/2)*25)*8 + ia%2 + (ib%2)*2 + (ic%2)*4; */ + + indx[NB_TRACK_MR102+1] = + compress10( + pos_indx[2], + pos_indx[6], + pos_indx[5], + pOverflow); + + /* + Third index + if ((ib/2)%2 == 1) + indx[NB_TRACK+2] = ((((4-ia/2) + (ib/2)*5)*32+12)/25)*4 + ia%2 + (ib%2)*2; + else + indx[NB_TRACK+2] = ((((ia/2) + (ib/2)*5)*32+12)/25)*4 + ia%2 + (ib%2)*2; + */ + + ib = pos_indx[7] >> 1; + + ib &= 1; + + ia = pos_indx[3] >> 1; + + if (ib == 1) + { + ia = 4 - ia; + } + + ib = pos_indx[7] >> 1; + + tempWord32 = ((Word32) ib * 5) << 1; + + tempWord32 = tempWord32 >> 1; + + ib = (Word16) tempWord32; + + ib += ia; + + ib <<= 5; + + ib += 12; + + ic = (Word16)(((Word32) ib * 1311) >> 15); + + ic <<= 2; + + ia = pos_indx[3] & 1; + + ib = ((Word16)(pos_indx[7] & 1)) << 1; + + ib += ic; + + ib += ia; + + indx[NB_TRACK_MR102+2] = ib; + +} /* compress_code */ + + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: code_8i40_31bits() +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + x Array of type Word16 -- target vector + cn Array of type Word16 -- residual after long term prediction + h Array of type Word16 -- impulse response of weighted synthesis filter + + + Outputs: + cod Array of type Word16 -- algebraic (fixed) codebook excitation + y Array of type Word16 -- filtered fixed codebook excitation + indx Array of type Word16 -- index of 8 pulses (signs+positions) + pOverflow Pointer to Flag -- set when overflow occurs + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + FUNCTION: + + PURPOSE: Searches a 31 bit algebraic codebook containing 8 pulses + in a frame of 40 samples. + + DESCRIPTION: + The code contains 8 nonzero pulses: i0...i7. + All pulses can have two possible amplitudes: +1 or -1. + The 40 positions in a subframe are divided into 4 tracks of + interleaved positions. Each track contains two pulses. + The pulses can have the following possible positions: + + i0, i4 : 0, 4, 8, 12, 16, 20, 24, 28, 32, 36 + i1, i5 : 1, 5, 9, 13, 17, 21, 25, 29, 33, 37 + i2, i6 : 2, 6, 10, 14, 18, 22, 26, 30, 34, 38 + i3, i7 : 3, 7, 11, 15, 19, 23, 27, 31, 35, 39 + + Each pair of pulses require 1 bit for their signs. The positions + are encoded together 3,3 and 2 resulting in + (7+3) + (7+3) + (5+2) bits for their + positions. This results in a 31 (4 sign and 27 pos) bit codebook. + The function determines the optimal pulse signs and positions, builds + the codevector, and computes the filtered codevector. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] c8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void code_8i40_31bits( + Word16 x[], /* i : target vector */ + Word16 cn[], /* i : residual after long term prediction */ + Word16 h[], /* i : impulse response of weighted synthesis + filter */ + Word16 cod[], /* o : algebraic (fixed) codebook excitation */ + Word16 y[], /* o : filtered fixed codebook excitation */ + Word16 indx[], /* o : 7 Word16, index of 8 pulses (signs+positions) */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 ipos[NB_PULSE]; + Word16 pos_max[NB_TRACK_MR102]; + Word16 codvec[NB_PULSE]; + + Word16 dn[L_CODE]; + Word16 sign[L_CODE]; + + Word16 rr[L_CODE][L_CODE]; + Word16 linear_signs[NB_TRACK_MR102]; + Word16 linear_codewords[NB_PULSE]; + + cor_h_x2( + h, + x, + dn, + 2, + NB_TRACK_MR102, + STEP_MR102, + pOverflow); + + /* 2 = use GSMEFR scaling */ + + set_sign12k2( + dn, + cn, + sign, + pos_max, + NB_TRACK_MR102, + ipos, + STEP_MR102, + pOverflow); + + /* same setsign alg as GSM-EFR new constants though*/ + + cor_h( + h, + sign, + rr, + pOverflow); + + search_10and8i40( + NB_PULSE, + STEP_MR102, + NB_TRACK_MR102, + dn, + rr, + ipos, + pos_max, + codvec, + pOverflow); + + build_code( + codvec, + sign, + cod, + h, + y, + linear_signs, + linear_codewords, + pOverflow); + + compress_code( + linear_signs, + linear_codewords, + indx, + pOverflow); + +} /* code_8i40_31bits */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c8_31pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c8_31pf.h new file mode 100644 index 00000000..2dbf63ea --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/c8_31pf.h @@ -0,0 +1,113 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: c8_31pf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the c8_31pf.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef c8_31pf_h +#define c8_31pf_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void code_8i40_31bits( + Word16 x[], /* i : target vector */ + Word16 cn[], /* i : residual after long term prediction */ + Word16 h[], /* i : impulse response of weighted synthesis + filter */ + Word16 cod[], /* o : algebraic (fixed) codebook excitation */ + Word16 y[], /* o : filtered fixed codebook excitation */ + Word16 indx[], /* o : 7 Word16, index of 8 pulses (signs+positions) */ + Flag * pOverflow /* o : Flag set when overflow occurs */ + ); + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _c8_31PF_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/calc_cor.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/calc_cor.cpp new file mode 100644 index 00000000..b6a41327 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/calc_cor.cpp @@ -0,0 +1,220 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: calc_cor.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "calc_cor.h" +#include "basic_op.h" +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: comp_corr +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + scal_sig = array of input samples. (Word16) + L_frame = length of frame used to compute pitch(Word16) + lag_max = maximum lag (Word16) + lag_min = minimum lag (Word16) + corr = pointer to array of correlations corresponding to the selected + lags. (Word32) + + Outputs: + corr = pointer to array of correlations corresponding to the selected + lags. (Word32) + + Returns: + none + + Global Variables Used: + none + + Local Variables Needed: + none + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calculates all correlations of scal_sig[] in a given delay + range. + + The correlation is given by + + cor[t] = , t=lag_min,...,lag_max + + The function outputs all of the correlations + +------------------------------------------------------------------------------ + REQUIREMENTS + + none + +------------------------------------------------------------------------------ + REFERENCES + + [1] calc_cor.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void comp_corr ( + Word16 scal_sig[], // i : scaled signal. + Word16 L_frame, // i : length of frame to compute pitch + Word16 lag_max, // i : maximum lag + Word16 lag_min, // i : minimum lag + Word32 corr[]) // o : correlation of selected lag +{ + Word16 i, j; + Word16 *p, *p1; + Word32 t0; + + for (i = lag_max; i >= lag_min; i--) + { + p = scal_sig; + p1 = &scal_sig[-i]; + t0 = 0; + + for (j = 0; j < L_frame; j++, p++, p1++) + { + t0 = L_mac (t0, *p, *p1); + } + corr[-i] = t0; + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void comp_corr( + Word16 scal_sig[], /* i : scaled signal. */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word32 corr[]) /* o : correlation of selected lag */ +{ + + + + + /*--------------------------------------------------- + ; lag_max and lag_min are typically negative numbers + -----------------------------------------------------*/ + + + /* PIT_MIN_MR122 18 Minimum pitch lag (MR122 mode) */ + /* PIT_MIN 20 Minimum pitch lag (all other modes) */ + /* PIT_MAX 143 Maximum pitch lag */ + + + Word16 i; + Word16 j; + Word16 *p; + Word16 *p1; + Word16 *p2; + Word16 *p_scal_sig; + Word32 t1; + Word32 t2; + Word32 t3; + Word32 t4; + + corr = corr - lag_max ; + p_scal_sig = &scal_sig[-lag_max]; + + for (i = ((lag_max - lag_min) >> 2) + 1; i > 0; i--) + { + t1 = 0; + t2 = 0; + t3 = 0; + t4 = 0; + p = &scal_sig[0]; + p1 = p_scal_sig++; + p_scal_sig++; + p2 = p_scal_sig++; + p_scal_sig++; + for (j = (L_frame >> 1); j != 0; j--) + { + t1 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p1++), t1); + t2 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p1), t2); + t3 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p2++), t3); + t4 = amrnb_fxp_mac_16_by_16bb((Word32) * (p++), (Word32) * (p2), t4); + + t1 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p1++), t1); + t2 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p1), t2); + t3 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p2++), t3); + t4 = amrnb_fxp_mac_16_by_16bb((Word32) * (p++), (Word32) * (p2), t4); + } + + *(corr++) = t1 << 1; + *(corr++) = t2 << 1; + *(corr++) = t3 << 1; + *(corr++) = t4 << 1; + + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/calc_cor.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/calc_cor.h new file mode 100644 index 00000000..d4a694bb --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/calc_cor.h @@ -0,0 +1,87 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : calc_cor.h +* Purpose : Calculate all correlations for prior the OL LTP +* +******************************************************************************** +*/ +#ifndef calc_cor_h +#define calc_cor_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ******************************************************************************** + * DECLARATION OF PROTOTYPES + ******************************************************************************** + */ + /************************************************************************* + * + * FUNCTION: comp_corr + * + * PURPOSE: Calculate all correlations of scal_sig[] in a given delay + * range. + * + * DESCRIPTION: + * The correlation is given by + * cor[t] = , t=lag_min,...,lag_max + * The functions outputs all correlations in the given range + * + *************************************************************************/ + void comp_corr(Word16 scal_sig[], /* i : scaled signal. */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word32 corr[] /* o : correlation of selected lag */ + ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/calc_en.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/calc_en.cpp new file mode 100644 index 00000000..539df117 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/calc_en.cpp @@ -0,0 +1,777 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: calc_en.cpp + Funtions: calc_unfilt_energies + calc_filt_energies + calc_target_energy + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the functions that calculate the energy coefficients + for unfiltered and filtered excitation signals, the LTP coding gain, and + the target energy. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "calc_en.h" +#include "typedef.h" +#include "basicop_malloc.h" +#include "l_comp.h" +#include "cnst.h" +#include "log2.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: calc_unfilt_energies +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + res = LP residual, buffer type Word16 + exc = LTP excitation (unfiltered), buffer type Word16 + code = CB innovation (unfiltered), buffer type Word16 + gain_pit = pitch gain, type Word16 + L_subfr = Subframe length, type Word16 + frac_en = energy coefficients (4), fraction part, buffer type Word16 + exp_en = energy coefficients (4), exponent part, buffer type Word16 + ltpg = LTP coding gain (log2()), pointer to type Word16 + pOverflow= pointer to value indicating existence of overflow (Flag) + + Outputs: + frac_en buffer containing new fractional parts of energy coefficients + exp_en buffer containing new exponential parts of energy coefficients + ltpg points to new LTP coding gain + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calculates several energy coefficients for unfiltered + excitation signals and the LTP coding gain + + frac_en[0]*2^exp_en[0] = LP residual energy + frac_en[1]*2^exp_en[1] = LTP residual energy + frac_en[2]*2^exp_en[2] = LTP/CB innovation dot product + frac_en[3]*2^exp_en[3] = LTP residual energy + (lres = res - gain_pit*exc) + ltpg = log2(LP_res_en / LTP_res_en) + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + calc_en.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void +calc_unfilt_energies( + Word16 res[], // i : LP residual, Q0 + Word16 exc[], // i : LTP excitation (unfiltered), Q0 + Word16 code[], // i : CB innovation (unfiltered), Q13 + Word16 gain_pit, // i : pitch gain, Q14 + Word16 L_subfr, // i : Subframe length + + Word16 frac_en[], // o : energy coefficients (4), fraction part, Q15 + Word16 exp_en[], // o : energy coefficients (4), exponent part, Q0 + Word16 *ltpg // o : LTP coding gain (log2()), Q13 +) +{ + Word32 s, L_temp; + Word16 i, exp, tmp; + Word16 ltp_res_en, pred_gain; + Word16 ltpg_exp, ltpg_frac; + + // Compute residual energy + s = L_mac((Word32) 0, res[0], res[0]); + for (i = 1; i < L_subfr; i++) + s = L_mac(s, res[i], res[i]); + + // ResEn := 0 if ResEn < 200.0 (= 400 Q1) + if (L_sub (s, 400L) < 0) + { + frac_en[0] = 0; + exp_en[0] = -15; + } + else + { + exp = norm_l(s); + frac_en[0] = extract_h(L_shl(s, exp)); + exp_en[0] = sub(15, exp); + } + + // Compute ltp excitation energy + s = L_mac((Word32) 0, exc[0], exc[0]); + for (i = 1; i < L_subfr; i++) + s = L_mac(s, exc[i], exc[i]); + + exp = norm_l(s); + frac_en[1] = extract_h(L_shl(s, exp)); + exp_en[1] = sub(15, exp); + + // Compute scalar product + s = L_mac((Word32) 0, exc[0], code[0]); + for (i = 1; i < L_subfr; i++) + s = L_mac(s, exc[i], code[i]); + + exp = norm_l(s); + frac_en[2] = extract_h(L_shl(s, exp)); + exp_en[2] = sub(16-14, exp); + + // Compute energy of LTP residual + s = 0L; + for (i = 0; i < L_subfr; i++) + { + L_temp = L_mult(exc[i], gain_pit); + L_temp = L_shl(L_temp, 1); + tmp = sub(res[i], pv_round(L_temp)); // LTP residual, Q0 + s = L_mac (s, tmp, tmp); + } + + exp = norm_l(s); + ltp_res_en = extract_h (L_shl (s, exp)); + exp = sub (15, exp); + + frac_en[3] = ltp_res_en; + exp_en[3] = exp; + + // calculate LTP coding gain, i.e. energy reduction LP res -> LTP res + if (ltp_res_en > 0 && frac_en[0] != 0) + { + // gain = ResEn / LTPResEn + pred_gain = div_s (shr (frac_en[0], 1), ltp_res_en); + exp = sub (exp, exp_en[0]); + + // L_temp = ltpGain * 2^(30 + exp) + L_temp = L_deposit_h (pred_gain); + // L_temp = ltpGain * 2^27 + L_temp = L_shr (L_temp, add (exp, 3)); + + // Log2 = log2() + 27 + Log2(L_temp, <pg_exp, <pg_frac); + + // ltpg = log2(LtpGain) * 2^13 --> range: +- 4 = +- 12 dB + L_temp = L_Comp (sub (ltpg_exp, 27), ltpg_frac); + *ltpg = pv_round (L_shl (L_temp, 13)); // Q13 + } + else + { + *ltpg = 0; + } +} + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void calc_unfilt_energies( + Word16 res[], /* i : LP residual, Q0 */ + Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ + Word16 code[], /* i : CB innovation (unfiltered), Q13 */ + Word16 gain_pit, /* i : pitch gain, Q14 */ + Word16 L_subfr, /* i : Subframe length */ + + Word16 frac_en[], /* o : energy coefficients (4), fraction part, Q15 */ + Word16 exp_en[], /* o : energy coefficients (4), exponent part, Q0 */ + Word16 *ltpg, /* o : LTP coding gain (log2()), Q13 */ + Flag *pOverflow +) +{ + Word32 s1; /* Intermediate energy accumulator */ + Word32 s2; /* Intermediate energy accumulator */ + Word32 s3; /* Intermediate energy accumulator */ + Word32 s4; /* Intermediate energy accumulator */ + Word32 L_temp; /* temporal 32 bits storage */ + + Word16 i; /* index used in all loops */ + Word16 exp; /* nunmber of '0's or '1's before MSB != 0 */ + Word16 tmp1; /* temporal storage */ + Word16 tmp2; /* temporal storage */ + Word16 ltp_res_en; + Word16 pred_gain; /* predictor gain */ + Word16 ltpg_exp; /* LTP gain (exponent) */ + Word16 ltpg_frac; /* LTP gain (mantissa or fractional part) */ + + s1 = 0; + s2 = 0; + s3 = 0; + s4 = 0; + + /*---------------------------------------------------------------------------- + NOTE: Overflow is expected as a result of multiply and accumulated without + scale down the inputs. This modification is not made at this point + to have bit exact results with the pre-optimization code. (JT 6/20/00) + + ----------------------------------------------------------------------------*/ + + for (i = 0; i < L_subfr; i++) + { + tmp1 = res[i]; /* avoid multiple accesses to memory */ + tmp2 = exc[i]; + + s1 = amrnb_fxp_mac_16_by_16bb((Word32) tmp1, (Word32) tmp1, s1); /* Compute residual energy */ + s2 = amrnb_fxp_mac_16_by_16bb((Word32) tmp2, (Word32) tmp2, s2); /* Compute ltp excitation energy */ + s3 = amrnb_fxp_mac_16_by_16bb((Word32) tmp2, (Word32) code[i], s3);/* Compute scalar product */ + /* */ + + L_temp = L_mult(tmp2, gain_pit, pOverflow); + L_temp = L_shl(L_temp, 1, pOverflow); + tmp2 = sub(tmp1, pv_round(L_temp, pOverflow), pOverflow); + /* LTP residual, Q0 */ + s4 = L_mac(s4, tmp2, tmp2, pOverflow); + /* Compute energy of LTP residual */ + } + s1 = s1 << 1; + s2 = s2 << 1; + s3 = s3 << 1; + + if (s1 & MIN_32) + { + s1 = MAX_32; + *pOverflow = 1; + } + + /* ResEn := 0 if ResEn < 200.0 (= 400 Q1) */ + if (s1 < 400L) + { + frac_en[0] = 0; + exp_en[0] = -15; + } + else + { + exp = norm_l(s1); + frac_en[0] = (Word16)(L_shl(s1, exp, pOverflow) >> 16); + exp_en[0] = (15 - exp); + } + + if (s2 & MIN_32) + { + s2 = MAX_32; + *pOverflow = 1; + } + + exp = norm_l(s2); + frac_en[1] = (Word16)(L_shl(s2, exp, pOverflow) >> 16); + exp_en[1] = 15 - exp; + + /* s3 is not always sum of squares */ + exp = norm_l(s3); + frac_en[2] = (Word16)(L_shl(s3, exp, pOverflow) >> 16); + exp_en[2] = 2 - exp; + + exp = norm_l(s4); + ltp_res_en = (Word16)(L_shl(s4, exp, pOverflow) >> 16); + exp = 15 - exp; + + frac_en[3] = ltp_res_en; + exp_en[3] = exp; + + /* calculate LTP coding gain, i.e. energy reduction LP res -> LTP res */ + + if (ltp_res_en > 0 && frac_en[0] != 0) + { + /* gain = ResEn / LTPResEn */ + pred_gain = div_s(shr(frac_en[0], 1, pOverflow), ltp_res_en); + exp = sub(exp, exp_en[0], pOverflow); + + /* L_temp = ltpGain * 2^(30 + exp) */ + L_temp = (Word32) pred_gain << 16; + /* L_temp = ltpGain * 2^27 */ + L_temp = L_shr(L_temp, (Word16)(exp + 3), pOverflow); + + /* Log2 = log2() + 27 */ + Log2(L_temp, <pg_exp, <pg_frac, pOverflow); + + /* ltpg = log2(LtpGain) * 2^13 --> range: +- 4 = +- 12 dB */ + L_temp = L_Comp((ltpg_exp - 27), ltpg_frac, pOverflow); + *ltpg = pv_round(L_shl(L_temp, 13, pOverflow), pOverflow); /* Q13 */ + } + else + { + *ltpg = 0; + } + + return; +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: calc_filt_energies +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + mode = coder mode, type Mode + xn = LTP target vector, buffer type Word16 + xn2 = CB target vector, buffer type Word16 + y1 = Adaptive codebook, buffer type Word16 + Y2 = Filtered innovative vector, buffer type Word16 + g_coeff = Correlations + computed in G_pitch() buffer type Word16 + frac_coeff = energy coefficients (5), fraction part, buffer type Word16 + exp_coeff = energy coefficients (5), exponent part, buffer type Word16 + cod_gain_frac = optimum codebook gain (fraction part), pointer type Word16 + cod_gain_exp = optimum codebook gain (exponent part), pointer type Word16 + pOverflow = pointer to overflow indicator (Flag) + + Outputs: + frac_coeff contains new fraction part energy coefficients + exp_coeff contains new exponent part energy coefficients + cod_gain_frac points to the new optimum codebook gain (fraction part) + cod_gain_exp points to the new optimum codebook gain (exponent part) + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calculates several energy coefficients for filtered + excitation signals + + Compute coefficients need for the quantization and the optimum + codebook gain gcu (for MR475 only). + + coeff[0] = y1 y1 + coeff[1] = -2 xn y1 + coeff[2] = y2 y2 + coeff[3] = -2 xn y2 + coeff[4] = 2 y1 y2 + + gcu = / (0 if <= 0) + + Product and have been computed in G_pitch() and + are in vector g_coeff[]. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + calc_en.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void +calc_filt_energies( + enum Mode mode, // i : coder mode + Word16 xn[], // i : LTP target vector, Q0 + Word16 xn2[], // i : CB target vector, Q0 + Word16 y1[], // i : Adaptive codebook, Q0 + Word16 Y2[], // i : Filtered innovative vector, Q12 + Word16 g_coeff[], // i : Correlations + // computed in G_pitch() + + Word16 frac_coeff[],// o : energy coefficients (5), fraction part, Q15 + Word16 exp_coeff[], // o : energy coefficients (5), exponent part, Q0 + Word16 *cod_gain_frac,// o: optimum codebook gain (fraction part), Q15 + Word16 *cod_gain_exp // o: optimum codebook gain (exponent part), Q0 +) +{ + Word32 s, ener_init; + Word16 i, exp, frac; + Word16 y2[L_SUBFR]; + + if (sub(mode, MR795) == 0 || sub(mode, MR475) == 0) + { + ener_init = 0L; + } + else + { + ener_init = 1L; + } + + for (i = 0; i < L_SUBFR; i++) { + y2[i] = shr(Y2[i], 3); + } + + frac_coeff[0] = g_coeff[0]; + exp_coeff[0] = g_coeff[1]; + frac_coeff[1] = negate(g_coeff[2]); // coeff[1] = -2 xn y1 + exp_coeff[1] = add(g_coeff[3], 1); + + + // Compute scalar product + + s = L_mac(ener_init, y2[0], y2[0]); + for (i = 1; i < L_SUBFR; i++) + s = L_mac(s, y2[i], y2[i]); + + exp = norm_l(s); + frac_coeff[2] = extract_h(L_shl(s, exp)); + exp_coeff[2] = sub(15 - 18, exp); + + // Compute scalar product -2* + + s = L_mac(ener_init, xn[0], y2[0]); + for (i = 1; i < L_SUBFR; i++) + s = L_mac(s, xn[i], y2[i]); + + exp = norm_l(s); + frac_coeff[3] = negate(extract_h(L_shl(s, exp))); + exp_coeff[3] = sub(15 - 9 + 1, exp); + + + // Compute scalar product 2* + + s = L_mac(ener_init, y1[0], y2[0]); + for (i = 1; i < L_SUBFR; i++) + s = L_mac(s, y1[i], y2[i]); + + exp = norm_l(s); + frac_coeff[4] = extract_h(L_shl(s, exp)); + exp_coeff[4] = sub(15 - 9 + 1, exp); + + if (sub(mode, MR475) == 0 || sub(mode, MR795) == 0) + { + // Compute scalar product + + s = L_mac(ener_init, xn2[0], y2[0]); + for (i = 1; i < L_SUBFR; i++) + s = L_mac(s, xn2[i], y2[i]); + + exp = norm_l(s); + frac = extract_h(L_shl(s, exp)); + exp = sub(15 - 9, exp); + + + if (frac <= 0) + { + *cod_gain_frac = 0; + *cod_gain_exp = 0; + } + else + { + // + gcu = / c[2] + = (frac>>1)/frac[2] * 2^(exp+1-exp[2]) + = div_s(frac>>1, frac[2])*2^-15 * 2^(exp+1-exp[2]) + = div_s * 2^(exp-exp[2]-14) + + *cod_gain_frac = div_s (shr (frac,1), frac_coeff[2]); + *cod_gain_exp = sub (sub (exp, exp_coeff[2]), 14); + + } + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void calc_filt_energies( + enum Mode mode, /* i : coder mode */ + Word16 xn[], /* i : LTP target vector, Q0 */ + Word16 xn2[], /* i : CB target vector, Q0 */ + Word16 y1[], /* i : Adaptive codebook, Q0 */ + Word16 Y2[], /* i : Filtered innovative vector, Q12 */ + Word16 g_coeff[], /* i : Correlations */ + /* computed in G_pitch() */ + Word16 frac_coeff[], /* o : energy coefficients (5), fraction part, Q15 */ + Word16 exp_coeff[], /* o : energy coefficients (5), exponent part, Q0 */ + Word16 *cod_gain_frac, /* o : optimum codebook gain (fraction part),Q15 */ + Word16 *cod_gain_exp, /* o : optimum codebook gain (exponent part), Q0 */ + Flag *pOverflow +) +{ + Word32 s1; /* Intermediate energy accumulator */ + Word32 s2; /* Intermediate energy accumulator */ + Word32 s3; /* Intermediate energy accumulator */ + + Word16 i; /* index used in all loops */ + Word16 exp; /* number of '0's or '1's before MSB != 0 */ + Word16 frac; /* fractional part */ + Word16 tmp; /* temporal storage */ + Word16 scaled_y2[L_SUBFR]; + + + frac_coeff[0] = g_coeff[0]; + exp_coeff[0] = g_coeff[1]; + frac_coeff[1] = negate(g_coeff[2]); /* coeff[1] = -2 xn y1 */ + exp_coeff[1] = g_coeff[3] + 1; + + if ((mode == MR795) || (mode == MR475)) + { + s1 = 0L; + s2 = 0L; + s3 = 0L; + } + else + { + s1 = 1L; + s2 = 1L; + s3 = 1L; + } + + for (i = 0; i < L_SUBFR; i++) + { + /* avoid multiple accesses to memory */ + tmp = (Y2[i] >> 3); + scaled_y2[i] = tmp; + + /* Compute scalar product */ + s1 = L_mac(s1, tmp, tmp, pOverflow); + + /* Compute scalar product -2* */ + s2 = L_mac(s2, xn[i], tmp, pOverflow); + + /* Compute scalar product 2* */ + s3 = L_mac(s3, y1[i], tmp, pOverflow); + } + + exp = norm_l(s1); + frac_coeff[2] = (Word16)(L_shl(s1, exp, pOverflow) >> 16); + exp_coeff[2] = (-3 - exp); + + exp = norm_l(s2); + frac_coeff[3] = negate((Word16)(L_shl(s2, exp, pOverflow) >> 16)); + exp_coeff[3] = (7 - exp); + + exp = norm_l(s3); + frac_coeff[4] = (Word16)(L_shl(s3, exp, pOverflow) >> 16); + exp_coeff[4] = (7 - exp); + + + if ((mode == MR795) || (mode == MR475)) + { + /* Compute scalar product */ + s1 = 0L; + + for (i = 0; i < L_SUBFR; i++) + { + s1 = amrnb_fxp_mac_16_by_16bb((Word32) xn2[i], (Word32)scaled_y2[i], s1); + } + + s1 = s1 << 1; + + exp = norm_l(s1); + frac = (Word16)(L_shl(s1, exp, pOverflow) >> 16); + exp = (6 - exp); + + if (frac <= 0) + { + *cod_gain_frac = 0; + *cod_gain_exp = 0; + } + else + { + /* + gcu = / c[2] + = (frac>>1)/frac[2] * 2^(exp+1-exp[2]) + = div_s(frac>>1, frac[2])*2^-15 * 2^(exp+1-exp[2]) + = div_s * 2^(exp-exp[2]-14) + */ + *cod_gain_frac = div_s(shr(frac, 1, pOverflow), frac_coeff[2]); + *cod_gain_exp = ((exp - exp_coeff[2]) - 14); + } + } + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: calc_target_energy +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + xn = LTP target vector, buffer to type Word16 Q0 + en_exp = optimum codebook gain (exponent part) pointer to type Word16 + en_frac = optimum codebook gain (fraction part) pointer to type Word16 + pOverflow = pointer to overflow indicator (Flag) + + Outputs: + en_exp points to new optimum codebook gain (exponent part) + en_frac points to new optimum codebook gain (fraction part) + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calculates the target energy using the formula, + en = + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + calc_en.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void +calc_target_energy( + Word16 xn[], // i: LTP target vector, Q0 + Word16 *en_exp, // o: optimum codebook gain (exponent part), Q0 + Word16 *en_frac // o: optimum codebook gain (fraction part), Q15 +) +{ + Word32 s; + Word16 i, exp; + + // Compute scalar product + s = L_mac(0L, xn[0], xn[0]); + for (i = 1; i < L_SUBFR; i++) + s = L_mac(s, xn[i], xn[i]); + + // s = SUM 2*xn(i) * xn(i) = * 2 + exp = norm_l(s); + *en_frac = extract_h(L_shl(s, exp)); + *en_exp = sub(16, exp); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void calc_target_energy( + Word16 xn[], /* i: LTP target vector, Q0 */ + Word16 *en_exp, /* o: optimum codebook gain (exponent part), Q0 */ + Word16 *en_frac, /* o: optimum codebook gain (fraction part), Q15 */ + Flag *pOverflow +) +{ + Word32 s; /* Intermediate energy accumulator */ + Word16 i; /* index used in all loops */ + Word16 exp; + + /* Compute scalar product */ + s = 0; + for (i = 0; i < L_SUBFR; i++) + { + s = amrnb_fxp_mac_16_by_16bb((Word32) xn[i], (Word32) xn[i], s); + } + + if (s < 0) + { + *pOverflow = 1; + s = MAX_32; + } + + /* s = SUM 2*xn(i) * xn(i) = * 2 */ + exp = norm_l(s); + *en_frac = (Word16)(L_shl(s, exp, pOverflow) >> 16); + *en_exp = (16 - exp); + + return; +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/calc_en.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/calc_en.h new file mode 100644 index 00000000..e74253bc --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/calc_en.h @@ -0,0 +1,183 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: calc_en.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : calc_en.h + Purpose : calculation of energy coefficients for quantizers + +------------------------------------------------------------------------------ +*/ + +#ifndef _CALC_EN_H_ +#define _CALC_EN_H_ +#define calc_en_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + /* + * FUNCTION: calc_unfilt_energies + * + * PURPOSE: calculation of several energy coefficients for unfiltered + * excitation signals and the LTP coding gain + * + * frac_en[0]*2^exp_en[0] = // LP residual energy + * frac_en[1]*2^exp_en[1] = // LTP residual energy + * frac_en[2]*2^exp_en[2] = // LTP/CB innovation dot product + * frac_en[3]*2^exp_en[3] = // LTP residual energy + * // (lres = res - gain_pit*exc) + * ltpg = log2(LP_res_en / LTP_res_en) + */ + void + calc_unfilt_energies( + Word16 res[], /* i : LP residual, Q0 */ + Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ + Word16 code[], /* i : CB innovation (unfiltered), Q13 */ + Word16 gain_pit, /* i : pitch gain, Q14 */ + Word16 L_subfr, /* i : Subframe length */ + + Word16 frac_en[], /* o : energy coefficients (3), fraction part, Q15 */ + Word16 exp_en[], /* o : energy coefficients (3), exponent part, Q0 */ + Word16 *ltpg, /* o : LTP coding gain (log2()), Q13 */ + Flag *pOverflow + ); + + /* + * FUNCTION: calc_filt_energies + * + * PURPOSE: calculation of several energy coefficients for filtered + * excitation signals + * + * Compute coefficients need for the quantization and the optimum + * codebook gain gcu (for MR475 only). + * + * coeff[0] = y1 y1 + * coeff[1] = -2 xn y1 + * coeff[2] = y2 y2 + * coeff[3] = -2 xn y2 + * coeff[4] = 2 y1 y2 + * + * + * gcu = / (0 if <= 0) + * + * Product and have been computed in G_pitch() and + * are in vector g_coeff[]. + */ + void + calc_filt_energies( + enum Mode mode, /* i : coder mode */ + Word16 xn[], /* i : LTP target vector, Q0 */ + Word16 xn2[], /* i : CB target vector, Q0 */ + Word16 y1[], /* i : Adaptive codebook, Q0 */ + Word16 Y2[], /* i : Filtered innovative vector, Q12 */ + Word16 g_coeff[], /* i : Correlations */ + /* computed in G_pitch() */ + + Word16 frac_coeff[],/* o : energy coefficients (5), fraction part, Q15 */ + Word16 exp_coeff[], /* o : energy coefficients (5), exponent part, Q0 */ + Word16 *cod_gain_frac,/* o: optimum codebook gain (fraction part), Q15 */ + Word16 *cod_gain_exp, /* o: optimum codebook gain (exponent part), Q0 */ + Flag *pOverflow + ); + + /* + * FUNCTION: calc_target_energy + * + * PURPOSE: calculation of target energy + * + * en = + */ + void + calc_target_energy( + Word16 xn[], /* i: LTP target vector, Q0 */ + Word16 *en_exp, /* o: optimum codebook gain (exponent part), Q0 */ + Word16 *en_frac, /* o: optimum codebook gain (fraction part), Q15 */ + Flag *pOverflow + ); + +#ifdef __cplusplus +} +#endif + +#endif /* _CALC_EN_H_ */ + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cbsearch.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cbsearch.cpp new file mode 100644 index 00000000..a566ea06 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cbsearch.cpp @@ -0,0 +1,360 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: cbsearch.cpp + Functions: D_plsf_3 + + ------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + x[] -- array of type Word16 -- target vector, Q0 + h[] -- array of type Word16 -- impulse response of weighted synthesis + filter h[-L_subfr..-1] must be set to + zero. Q12 + T0 -- Word16 -- Pitch lag + pitch_sharp -- Word16 -- Last quantized pitch gain, Q14 + gain_pit -- Word16 gain_pit -- Pitch gain, Q14 + res2[] -- array of type Word16 -- Long term prediction residual, Q0 + mode -- enum Mode -- coder mode + subNr -- Word16 -- subframe number + + Outputs: + code[] -- array of type Word16 -- Innovative codebook, Q13 + y[] -- array of type Word16 -- filtered fixed codebook excitation + Q12 + + anap -- Double pointer to Word16 -- Signs of the pulses + + + pOverflow -- pointer to Flag -- Flag set when overflow occurs + + Returns: + Zero + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Inovative codebook search (find index and gain) + +------------------------------------------------------------------------------ + REQUIREMENTS + + + +------------------------------------------------------------------------------ + REFERENCES + + cbsearch.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "cbsearch.h" + +#include "typedef.h" +#include "c2_9pf.h" +#include "c2_11pf.h" +#include "c3_14pf.h" +#include "c4_17pf.h" +#include "c8_31pf.h" +#include "c1035pf.h" +#include "mode.h" +#include "basic_op.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void cbsearch(Word16 x[], /* i : target vector, Q0 */ + Word16 h[], /* i : impulse response of weighted synthesis*/ + /* filter h[-L_subfr..-1] must be set to */ + /* zero. Q12 */ + Word16 T0, /* i : Pitch lag */ + Word16 pitch_sharp,/* i : Last quantized pitch gain, Q14 */ + Word16 gain_pit, /* i : Pitch gain, Q14 */ + Word16 res2[], /* i : Long term prediction residual, Q0 */ + Word16 code[], /* o : Innovative codebook, Q13 */ + Word16 y[], /* o : filtered fixed codebook excitation */ + /* Q12 */ + Word16 **anap, /* o : Signs of the pulses */ + enum Mode mode, /* i : coder mode */ + Word16 subNr, /* i : subframe number */ + CommonAmrTbls* common_amr_tbls, /* ptr to struct of tables */ + Flag *pOverflow) /* o : Flag set when overflow occurs */ +{ + Word16 index; + Word16 i; + Word16 temp; + Word16 pit_sharpTmp; + + /* For MR74, the pre and post CB pitch sharpening is included in the + * codebook search routine, while for MR122 is it not. + */ + + if ((mode == MR475) || (mode == MR515)) + { + /* MR475, MR515 */ + *(*anap)++ = + code_2i40_9bits( + subNr, + x, + h, + T0, + pitch_sharp, + code, + y, + &index, + common_amr_tbls->startPos_ptr, + pOverflow); + + *(*anap)++ = index; /* sign index */ + } + else if (mode == MR59) + { /* MR59 */ + *(*anap)++ = + code_2i40_11bits( + x, + h, + T0, + pitch_sharp, + code, + y, + &index, + pOverflow); + + *(*anap)++ = index; /* sign index */ + } + else if (mode == MR67) + { /* MR67 */ + *(*anap)++ = + code_3i40_14bits( + x, + h, + T0, + pitch_sharp, + code, + y, + &index, + pOverflow); + + *(*anap)++ = index; /* sign index */ + } + else if ((mode == MR74) || (mode == MR795)) + { /* MR74, MR795 */ + *(*anap)++ = + code_4i40_17bits( + x, + h, + T0, + pitch_sharp, + code, + y, + &index, + common_amr_tbls->gray_ptr, + pOverflow); + + *(*anap)++ = index; /* sign index */ + } + else if (mode == MR102) + { /* MR102 */ + /*-------------------------------------------------------------* + * - include pitch contribution into impulse resp. h1[] * + *-------------------------------------------------------------*/ + /* pit_sharpTmp = pit_sharp; */ + /* if (pit_sharpTmp > 1.0) pit_sharpTmp = 1.0; */ + + pit_sharpTmp = + shl( + pitch_sharp, + 1, + pOverflow); + + for (i = T0; i < L_SUBFR; i++) + { + temp = + mult( + h[i - T0], + pit_sharpTmp, + pOverflow); + + h[i] = + add_16( + h[i], + temp, + pOverflow); + } + + /*--------------------------------------------------------------* + * - Innovative codebook search (find index and gain) * + *--------------------------------------------------------------*/ + code_8i40_31bits( + x, + res2, + h, + code, + y, + *anap, + pOverflow); + + *anap += 7; + + /*-------------------------------------------------------* + * - Add the pitch contribution to code[]. * + *-------------------------------------------------------*/ + for (i = T0; i < L_SUBFR; i++) + { + temp = + mult( + code[i - T0], + pit_sharpTmp, + pOverflow); + + code[i] = + add_16( + code[i], + temp, + pOverflow); + } + } + else + { /* MR122 */ + /*-------------------------------------------------------------* + * - include pitch contribution into impulse resp. h1[] * + *-------------------------------------------------------------*/ + + /* pit_sharpTmp = gain_pit; */ + /* if (pit_sharpTmp > 1.0) pit_sharpTmp = 1.0; */ + + pit_sharpTmp = shl(gain_pit, 1, pOverflow); + + for (i = T0; i < L_SUBFR; i++) + { + temp = ((Word32)h[i - T0] * pit_sharpTmp) >> 15; + /* + mult( + h[i - T0], + , + pOverflow); + */ + h[i] = + add_16( + h[i], + temp, + pOverflow); + } + /*--------------------------------------------------------------* + * - Innovative codebook search (find index and gain) * + *--------------------------------------------------------------*/ + + code_10i40_35bits( + x, + res2, + h, + code, + y, + *anap, + common_amr_tbls->gray_ptr, + pOverflow); + + *anap += 10; + + /*-------------------------------------------------------* + * - Add the pitch contribution to code[]. * + *-------------------------------------------------------*/ + for (i = T0; i < L_SUBFR; i++) + { + temp = + mult( + code[i - T0], + pit_sharpTmp, + pOverflow); + + code[i] = + add_16( + code[i], + temp, + pOverflow); + } + } + +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cbsearch.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cbsearch.h new file mode 100644 index 00000000..caad7359 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cbsearch.h @@ -0,0 +1,124 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: cbsearch.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the cbsearch.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef cbsearch_h +#define cbsearch_h "$Id $" + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void cbsearch(Word16 x[], /* i : target vector, Q0 */ + Word16 h[], /* i : impulse response of weighted synthesis */ + /* filter h[-L_subfr..-1] must be set to */ + /* zero. Q12 */ + Word16 T0, /* i : Pitch lag */ + Word16 pitch_sharp, /* i : Last quantized pitch gain, Q14 */ + Word16 gain_pit,/* i : Pitch gain, Q14 */ + Word16 res2[], /* i : Long term prediction residual, Q0 */ + Word16 code[], /* o : Innovative codebook, Q13 */ + Word16 y[], /* o : filtered fixed codebook excitation, Q12 */ + Word16 **anap, /* o : Signs of the pulses */ + enum Mode mode, /* i : coder mode */ + Word16 subNr, /* i : subframe number */ + CommonAmrTbls* common_amr_tbls, /* ptr to struct of tables */ + Flag *pOverflow /* o : Flag set when overflow occurs */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _CBSEARCH_H_ */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cl_ltp.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cl_ltp.cpp new file mode 100644 index 00000000..50eb6b93 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cl_ltp.cpp @@ -0,0 +1,671 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: cl_ltp.cpp + Funtions: cl_ltp_init + cl_ltp_reset + cl_ltp_exit + cl_ltp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains functions that perform closed-loop fractional pitch + search. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "cl_ltp.h" +#include "basicop_malloc.h" +#include "cnst.h" +#include "convolve.h" +#include "g_pitch.h" +#include "pred_lt.h" +#include "pitch_fr.h" +#include "enc_lag3.h" +#include "enc_lag6.h" +#include "q_gain_p.h" +#include "ton_stab.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cl_ltp_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = Pointer to a pointer to a clLtpState structure + + Outputs: + state points to the newly created clLtpState structure. + + Returns: + This function returns 0 upon success and -1 upon failure. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Allocates state memory and initializes state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + cl_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int cl_ltp_init (clLtpState **state) +{ + clLtpState* s; + + if (state == (clLtpState **) NULL){ + fprintf(stderr, "cl_ltp_init: invalid parameter\n"); + return -1; + } + *state = NULL; + + // allocate memory + if ((s= (clLtpState *) malloc(sizeof(clLtpState))) == NULL){ + fprintf(stderr, "cl_ltp_init: can not malloc state structure\n"); + return -1; + } + + // init the sub state + if (Pitch_fr_init(&s->pitchSt)) { + cl_ltp_exit(&s); + return -1; + } + + cl_ltp_reset(s); + + *state = s; + + return 0; +} + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 cl_ltp_init(clLtpState **state) +{ + clLtpState* s; + + if (state == (clLtpState **) NULL) + { + /*fprint(stderr, "cl_ltp_init: invalid parameter\n");*/ + return(-1); + } + *state = NULL; + + /* allocate memory */ + if ((s = (clLtpState *) oscl_malloc(sizeof(clLtpState))) == NULL) + { + /*fprint(stderr, "cl_ltp_init: can not malloc state structure\n");*/ + return(-1); + } + + /* init the sub state */ + if (Pitch_fr_init(&s->pitchSt)) + { + cl_ltp_exit(&s); + return(-1); + } + + cl_ltp_reset(s); + + *state = s; + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cl_ltp_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to the clLtpState structure to be reset + + Outputs: + The state structure pointed to by clLtpState *state is reset. + + Returns: + The function returns int 0 if successful, -1 otherwise. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Initializes state memory to zero. + +------------------------------------------------------------------------------ + REQUIREMENTS + +------------------------------------------------------------------------------ + REFERENCES + + cl_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + + ------------------------------------------------------------------------------ + PSEUDO-CODE + +int cl_ltp_reset (clLtpState *state) +{ + if (state == (clLtpState *) NULL){ + fprintf(stderr, "cl_ltp_reset: invalid parameter\n"); + return -1; + } + + // Reset pitch search states + Pitch_fr_reset (state->pitchSt); + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 cl_ltp_reset(clLtpState *state) +{ + if (state == (clLtpState *) NULL) + { + /*fprint(stderr, "cl_ltp_reset: invalid parameter\n"); */ + return(-1); + } + + /* Reset pitch search states */ + Pitch_fr_reset(state->pitchSt); + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cl_ltp_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + clLtpState **state = Reference to the state object to be freed. + + Outputs: + The memory used by the structure which is pointed to by 'state' + is freed. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + The memory used for state memory is freed + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + cl_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void cl_ltp_exit (clLtpState **state) +{ + if (state == NULL || *state == NULL) + return; + + // dealloc members + Pitch_fr_exit(&(*state)->pitchSt); + + // deallocate memory + free(*state); + *state = NULL; + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void cl_ltp_exit(clLtpState **state) +{ + if (state == NULL || *state == NULL) + { + return; + } + + /* dealloc members */ + Pitch_fr_exit(&(*state)->pitchSt); + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cl_ltp +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + clSt = pointer to the clLtpState struct + tonSt = pointer to the tonStabState structure + mode = codec mode value, of type enum Mode + frameOffset = offset to subframe (Word16) + T_op = pointer to buffer of open loop pitch lags (Word16) + h1 = pointer to impulse response vector (Word16) + exc = pointer to excitation vector (Word16) + res2 = pointer to long term prediction residual (Word16) + xn = pointer to target vector for pitch search (Word16) + lsp_flag = LSP resonance flag (Word16) + + Outputs: + clSt = pointer to the clLtpState struct + tonSt = pointer to the tonStabState structure + exc = pointer to excitation vector (Word16) + res2 = pointer to long term prediction residual (Word16) + xn2 = pointer to target vector for codebook search (Word16) + yl = pointer to buffer of filtered adaptive excitation (Word16) + T0 = pointer to pitch delay (integer part) (Word16) + T0_frac = pointer to pitch delay (fractional part) (Word16) + gain_pit = pointer to pitch gain (Word16) + g_coeff = pointer to array of correlations between xn, y1, & y2 (Word16) + anap = pointer to pointer to analysis parameters (Word16) + gp_limit = pointer to the pitch gain limit (Word16) + pOverflow = pointer to overflow indicator (Flag) + + Returns: + return_value = 0 (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs closed-loop fractional pitch search. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + cl_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE FOR cl_ltp + +int cl_ltp ( + clLtpState *clSt, // i/o : State struct + tonStabState *tonSt, // i/o : State struct + enum Mode mode, // i : coder mode + Word16 frameOffset, // i : Offset to subframe + Word16 T_op[], // i : Open loop pitch lags + Word16 *h1, // i : Impulse response vector Q12 + Word16 *exc, // i/o : Excitation vector Q0 + Word16 res2[], // i/o : Long term prediction residual Q0 + Word16 xn[], // i : Target vector for pitch search Q0 + Word16 lsp_flag, // i : LSP resonance flag + Word16 xn2[], // o : Target vector for codebook search Q0 + Word16 y1[], // o : Filtered adaptive excitation Q0 + Word16 *T0, // o : Pitch delay (integer part) + Word16 *T0_frac, // o : Pitch delay (fractional part) + Word16 *gain_pit, // o : Pitch gain Q14 + Word16 g_coeff[], // o : Correlations between xn, y1, & y2 + Word16 **anap, // o : Analysis parameters + Word16 *gp_limit // o : pitch gain limit +) +{ + Word16 i; + Word16 index; + Word32 L_temp; // temporarily variable + Word16 resu3; // flag for upsample resolution + Word16 gpc_flag; + + *----------------------------------------------------------------------* + * Closed-loop fractional pitch search * + *----------------------------------------------------------------------* + *T0 = Pitch_fr(clSt->pitchSt, + mode, T_op, exc, xn, h1, + L_SUBFR, frameOffset, + T0_frac, &resu3, &index); + + *(*anap)++ = index; + + *-----------------------------------------------------------------* + * - find unity gain pitch excitation (adapitve codebook entry) * + * with fractional interpolation. * + * - find filtered pitch exc. y1[]=exc[] convolve with h1[]) * + * - compute pitch gain and limit between 0 and 1.2 * + * - update target vector for codebook search * + * - find LTP residual. * + *-----------------------------------------------------------------* + + Pred_lt_3or6(exc, *T0, *T0_frac, L_SUBFR, resu3); + + Convolve(exc, h1, y1, L_SUBFR); + + // gain_pit is Q14 for all modes + *gain_pit = G_pitch(mode, xn, y1, g_coeff, L_SUBFR); + + + // check if the pitch gain should be limit due to resonance in LPC filter + gpc_flag = 0; + *gp_limit = MAX_16; + if ((lsp_flag != 0) && + (sub(*gain_pit, GP_CLIP) > 0)) + { + gpc_flag = check_gp_clipping(tonSt, *gain_pit); + } + + // special for the MR475, MR515 mode; limit the gain to 0.85 to + // cope with bit errors in the decoder in a better way. + if ((sub (mode, MR475) == 0) || (sub (mode, MR515) == 0)) { + if ( sub (*gain_pit, 13926) > 0) { + *gain_pit = 13926; // 0.85 in Q14 + } + + if (gpc_flag != 0) { + *gp_limit = GP_CLIP; + } + } + else + { + if (gpc_flag != 0) + { + *gp_limit = GP_CLIP; + *gain_pit = GP_CLIP; + } + // For MR122, gain_pit is quantized here and not in gainQuant + if (sub(mode, MR122)==0) + { + *(*anap)++ = q_gain_pitch(MR122, *gp_limit, gain_pit, + NULL, NULL); + } + } + + // update target vector und evaluate LTP residual + for (i = 0; i < L_SUBFR; i++) { + L_temp = L_mult(y1[i], *gain_pit); + L_temp = L_shl(L_temp, 1); + xn2[i] = sub(xn[i], extract_h(L_temp)); + + L_temp = L_mult(exc[i], *gain_pit); + L_temp = L_shl(L_temp, 1); + res2[i] = sub(res2[i], extract_h(L_temp)); + } + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void cl_ltp( + clLtpState *clSt, /* i/o : State struct */ + tonStabState *tonSt, /* i/o : State struct */ + enum Mode mode, /* i : coder mode */ + Word16 frameOffset, /* i : Offset to subframe */ + Word16 T_op[], /* i : Open loop pitch lags */ + Word16 *h1, /* i : Impulse response vector Q12 */ + Word16 *exc, /* i/o : Excitation vector Q0 */ + Word16 res2[], /* i/o : Long term prediction residual Q0 */ + Word16 xn[], /* i : Target vector for pitch search Q0 */ + Word16 lsp_flag, /* i : LSP resonance flag */ + Word16 xn2[], /* o : Target vector for codebook search Q0 */ + Word16 yl[], /* o : Filtered adaptive excitation Q0 */ + Word16 *T0, /* o : Pitch delay (integer part) */ + Word16 *T0_frac, /* o : Pitch delay (fractional part) */ + Word16 *gain_pit, /* o : Pitch gain Q14 */ + Word16 g_coeff[], /* o : Correlations between xn, y1, & y2 */ + Word16 **anap, /* o : Analysis parameters */ + Word16 *gp_limit, /* o : pitch gain limit */ + const Word16* qua_gain_pitch_ptr, /* i : ptr to read-only table */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + register Word16 i; + Word16 index; + Word32 L_temp; /* temporarily variable */ + Word16 resu3; /* flag for upsample resolution */ + Word16 gpc_flag; + + Word16 temp; + Word16 *p_exc; + Word16 *p_xn; + Word16 *p_xn2; + Word16 *p_yl; + + /*----------------------------------------------------------------------* + * Closed-loop fractional pitch search * + *----------------------------------------------------------------------*/ + *T0 = + Pitch_fr( + clSt->pitchSt, + mode, + T_op, + exc, + xn, + h1, + L_SUBFR, + frameOffset, + T0_frac, + &resu3, + &index, + pOverflow); + + *(*anap)++ = index; + + /*-----------------------------------------------------------------* + * - find unity gain pitch excitation (adapitve codebook entry) * + * with fractional interpolation. * + * - find filtered pitch exc. y1[]=exc[] convolve with h1[]) * + * - compute pitch gain and limit between 0 and 1.2 * + * - update target vector for codebook search * + * - find LTP residual. * + *-----------------------------------------------------------------*/ + + Pred_lt_3or6( + exc, + *T0, + *T0_frac, + L_SUBFR, + resu3, + pOverflow); + + Convolve(exc, h1, yl, L_SUBFR); + + /* gain_pit is Q14 for all modes */ + *gain_pit = + G_pitch( + mode, + xn, + yl, + g_coeff, + L_SUBFR, + pOverflow); + + + /* check if the pitch gain should be limit due to resonance in LPC filter */ + gpc_flag = 0; + *gp_limit = MAX_16; + + if ((lsp_flag != 0) && ((Word32)(*gain_pit) > GP_CLIP)) + { + gpc_flag = check_gp_clipping(tonSt, *gain_pit, pOverflow); + } + + /* special for the MR475, MR515 mode; limit the gain to 0.85 to */ + /* cope with bit errors in the decoder in a better way. */ + + if ((mode == MR475) || (mode == MR515)) + { + *gain_pit = ((Word32) * gain_pit > 13926) ? 13926 : *gain_pit; + + if (gpc_flag != 0) + { + *gp_limit = GP_CLIP; + } + } + else + { + if (gpc_flag != 0) + { + *gp_limit = GP_CLIP; + *gain_pit = GP_CLIP; + } + /* For MR122, gain_pit is quantized here and not in gainQuant */ + if (mode == MR122) + { + *(*anap)++ = + q_gain_pitch( + MR122, + *gp_limit, + gain_pit, + NULL, + NULL, + qua_gain_pitch_ptr, + pOverflow); + } + } + + + p_exc = &exc[0]; + p_xn = &xn[0]; + p_xn2 = &xn2[0]; + p_yl = &yl[0]; + + temp = *gain_pit; + + /* update target vector und evaluate LTP residual */ + for (i = 0; i < L_SUBFR; i++) + { + L_temp = ((Word32) * (p_yl++) * temp) >> 14; + *(p_xn2++) = *(p_xn++) - (Word16)L_temp; + + L_temp = ((Word32) * (p_exc++) * temp) >> 14; + res2[i] -= (Word16)L_temp; + } + +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cl_ltp.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cl_ltp.h new file mode 100644 index 00000000..22da3fbc --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cl_ltp.h @@ -0,0 +1,150 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: cl_ltp.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the cl_ltp.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef cl_ltp_h +#define cl_ltp_h "$Id $" + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "pitch_fr.h" +#include "ton_stab.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /* state variable */ + typedef struct + { + Pitch_frState *pitchSt; + } clLtpState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 cl_ltp_init(clLtpState **st); + /* initialize one instance of the pre processing state. + Stores pointer to filter status struct in *st. This pointer has to + be passed to cl_ltp in each call. + returns 0 on success + */ + + Word16 cl_ltp_reset(clLtpState *st); + /* reset of pre processing state (i.e. set state memory to zero) + returns 0 on success + */ + void cl_ltp_exit(clLtpState **st); + /* de-initialize pre processing state (i.e. free status struct) + stores NULL in *st + */ + + void cl_ltp( + clLtpState *clSt, /* i/o : State struct */ + tonStabState *tonSt, /* i/o : State struct */ + enum Mode mode, /* i : coder mode */ + Word16 frameOffset, /* i : Offset to subframe */ + Word16 T_op[], /* i : Open loop pitch lags */ + Word16 *h1, /* i : Impulse response vector Q12 */ + Word16 *exc, /* i/o : Excitation vector Q0 */ + Word16 res2[], /* i/o : Long term prediction residual Q0 */ + Word16 xn[], /* i : Target vector for pitch search Q0 */ + Word16 lsp_flag, /* i : LSP resonance flag */ + Word16 xn2[], /* o : Target vector for codebook search Q0 */ + Word16 y1[], /* o : Filtered adaptive excitation Q0 */ + Word16 *T0, /* o : Pitch delay (integer part) */ + Word16 *T0_frac, /* o : Pitch delay (fractional part) */ + Word16 *gain_pit, /* o : Pitch gain Q14 */ + Word16 g_coeff[], /* o : Correlations between xn, y1, & y2 */ + Word16 **anap, /* o : Analysis parameters */ + Word16 *gp_limit, /* o : pitch gain limit */ + const Word16* qua_gain_pitch_ptr, /* i : ptr to read-only table */ + Flag *pOverflow /* o : overflow indicator */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _CL_LTP_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cod_amr.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cod_amr.cpp new file mode 100644 index 00000000..f1c101c5 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cod_amr.cpp @@ -0,0 +1,1502 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: cod_amr.cpp + Functions: cod_amr_init + cod_amr_reset + cod_amr_exit + cod_amr_first + cod_amr + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + These functions comprise the main encoder routine operating on a frame basis. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "cod_amr.h" +#include "typedef.h" +#include "cnst.h" +#include "qua_gain.h" +#include "lpc.h" +#include "lsp.h" +#include "pre_big.h" +#include "ol_ltp.h" +#include "p_ol_wgh.h" +#include "spreproc.h" +#include "cl_ltp.h" +#include "pred_lt.h" +#include "spstproc.h" +#include "cbsearch.h" +#include "gain_q.h" +#include "convolve.h" +#include "ton_stab.h" +#include "vad.h" +#include "dtx_enc.h" +#include "oscl_mem.h" + +#ifdef VAD2 +#include "vad2.h" +#endif + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* Spectral expansion factors */ + +static const Word16 gamma1[M] = +{ + 30802, 28954, 27217, 25584, 24049, + 22606, 21250, 19975, 18777, 17650 +}; + +/* gamma1 differs for the 12k2 coder */ +static const Word16 gamma1_12k2[M] = +{ + 29491, 26542, 23888, 21499, 19349, + 17414, 15672, 14105, 12694, 11425 +}; + +static const Word16 gamma2[M] = +{ + 19661, 11797, 7078, 4247, 2548, + 1529, 917, 550, 330, 198 +}; + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cod_amr_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a pointer to a structure of type cod_amrState + + Outputs: + Structure pointed to by the pointer pointed to by state is + initialized to its reset value + state points to the allocated memory + + Returns: + Returns 0 if memory was successfully initialized, + otherwise returns -1. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function allocates memory and initializes state variables. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int cod_amr_init (cod_amrState **state, Flag dtx) +{ + cod_amrState* s; + + if (state == (cod_amrState **) NULL){ + fprintf(stderr, "cod_amr_init: invalid parameter\n"); + return -1; + } + *state = NULL; + + // allocate memory + if ((s= (cod_amrState *) malloc(sizeof(cod_amrState))) == NULL){ + fprintf(stderr, "cod_amr_init: can not malloc state structure\n"); + return -1; + } + + s->lpcSt = NULL; + s->lspSt = NULL; + s->clLtpSt = NULL; + s->gainQuantSt = NULL; + s->pitchOLWghtSt = NULL; + s->tonStabSt = NULL; + s->vadSt = NULL; + s->dtx_encSt = NULL; + s->dtx = dtx; + + // Init sub states + if (cl_ltp_init(&s->clLtpSt) || + lsp_init(&s->lspSt) || + gainQuant_init(&s->gainQuantSt) || + p_ol_wgh_init(&s->pitchOLWghtSt) || + ton_stab_init(&s->tonStabSt) || +#ifndef VAD2 + vad1_init(&s->vadSt) || +#else + vad2_init(&s->vadSt) || +#endif + dtx_enc_init(&s->dtx_encSt) || + lpc_init(&s->lpcSt)) { + cod_amr_exit(&s); + return -1; + } + + cod_amr_reset(s); + + *state = s; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 cod_amr_init(cod_amrState **state, Flag dtx) +{ + cod_amrState* s; + + if (state == (cod_amrState **) NULL) + { + /* fprint(stderr, "cod_amr_init: invalid parameter\n"); */ + return(-1); + } + *state = NULL; + + /* allocate memory */ + if ((s = (cod_amrState *) oscl_malloc(sizeof(cod_amrState))) == NULL) + { + /* fprint(stderr, "cod_amr_init: + can not malloc state structure\n"); */ + return(-1); + } + + get_const_tbls(&s->common_amr_tbls); + + s->lpcSt = NULL; + s->lspSt = NULL; + s->clLtpSt = NULL; + s->gainQuantSt = NULL; + s->pitchOLWghtSt = NULL; + s->tonStabSt = NULL; + s->vadSt = NULL; + s->dtx_encSt = NULL; + s->dtx = dtx; + + /* Initialize overflow Flag */ + + s->overflow = 0; + + + /* Init sub states */ + if (cl_ltp_init(&s->clLtpSt) || + lsp_init(&s->lspSt) || + gainQuant_init(&s->gainQuantSt) || + p_ol_wgh_init(&s->pitchOLWghtSt) || + ton_stab_init(&s->tonStabSt) || +#ifndef VAD2 + vad1_init(&s->vadSt) || +#else + vad2_init(&s->vadSt) || +#endif + dtx_enc_init(&s->dtx_encSt, s->common_amr_tbls.lsp_init_data_ptr) || + lpc_init(&s->lpcSt)) + { + cod_amr_exit(&s); + return(-1); + } + + cod_amr_reset(s); + + *state = s; + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cod_amr_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a structure of type cod_amrState + + Outputs: + Structure pointed to by state is initialized to initial values. + + Returns: + Returns 0 if memory was successfully initialized, + otherwise returns -1. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function resets the state memory for cod_amr. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int cod_amr_reset (cod_amrState *st) +{ + Word16 i; + + if (st == (cod_amrState *) NULL){ + fprintf(stderr, "cod_amr_reset: invalid parameter\n"); + return -1; + } + + *-----------------------------------------------------------------------* + * Initialize pointers to speech vector. * + *-----------------------------------------------------------------------* + + st->new_speech = st->old_speech + L_TOTAL - L_FRAME; // New speech + + st->speech = st->new_speech - L_NEXT; // Present frame + + st->p_window = st->old_speech + L_TOTAL - L_WINDOW; // For LPC window + st->p_window_12k2 = st->p_window - L_NEXT; // EFR LPC window: no lookahead + + // Initialize static pointers + + st->wsp = st->old_wsp + PIT_MAX; + st->exc = st->old_exc + PIT_MAX + L_INTERPOL; + st->zero = st->ai_zero + MP1; + st->error = st->mem_err + M; + st->h1 = &st->hvec[L_SUBFR]; + + // Static vectors to zero + + Set_zero(st->old_speech, L_TOTAL); + Set_zero(st->old_exc, PIT_MAX + L_INTERPOL); + Set_zero(st->old_wsp, PIT_MAX); + Set_zero(st->mem_syn, M); + Set_zero(st->mem_w, M); + Set_zero(st->mem_w0, M); + Set_zero(st->mem_err, M); + Set_zero(st->zero, L_SUBFR); + Set_zero(st->hvec, L_SUBFR); // set to zero "h1[-L_SUBFR..-1]" + + // OL LTP states + for (i = 0; i < 5; i++) + { + st->old_lags[i] = 40; + } + + // Reset lpc states + lpc_reset(st->lpcSt); + + // Reset lsp states + lsp_reset(st->lspSt); + + // Reset clLtp states + cl_ltp_reset(st->clLtpSt); + + gainQuant_reset(st->gainQuantSt); + + p_ol_wgh_reset(st->pitchOLWghtSt); + + ton_stab_reset(st->tonStabSt); + +#ifndef VAD2 + vad1_reset(st->vadSt); +#else + vad2_reset(st->vadSt); +#endif + + dtx_enc_reset(st->dtx_encSt); + + st->sharp = SHARPMIN; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 cod_amr_reset(cod_amrState *st) +{ + Word16 i; + + if (st == (cod_amrState *) NULL) + { + /* fprint(stderr, "cod_amr_reset: invalid parameter\n"); */ + return(-1); + } + + /*-----------------------------------------------------------------------* + * Initialize pointers to speech vector. * + *-----------------------------------------------------------------------*/ + + st->new_speech = st->old_speech + L_TOTAL - L_FRAME; /* New speech */ + + st->speech = st->new_speech - L_NEXT; /* Present frame */ + + st->p_window = st->old_speech + L_TOTAL - L_WINDOW; /* For LPC window */ + st->p_window_12k2 = st->p_window - L_NEXT; /* EFR LPC window: no lookahead */ + + /* Initialize static pointers */ + + st->wsp = st->old_wsp + PIT_MAX; + st->exc = st->old_exc + PIT_MAX + L_INTERPOL; + st->zero = st->ai_zero + MP1; + st->error = st->mem_err + M; + st->h1 = &st->hvec[L_SUBFR]; + + /* Initialize overflow Flag */ + + st->overflow = 0; + + /* Static vectors to zero */ + oscl_memset(st->old_speech, 0, sizeof(Word16)*L_TOTAL); + oscl_memset(st->old_exc, 0, sizeof(Word16)*(PIT_MAX + L_INTERPOL)); + oscl_memset(st->old_wsp, 0, sizeof(Word16)*PIT_MAX); + oscl_memset(st->mem_syn, 0, sizeof(Word16)*M); + oscl_memset(st->mem_w, 0, sizeof(Word16)*M); + oscl_memset(st->mem_w0, 0, sizeof(Word16)*M); + oscl_memset(st->mem_err, 0, sizeof(Word16)*M); + oscl_memset(st->zero, 0, sizeof(Word16)*L_SUBFR); + oscl_memset(st->hvec, 0, sizeof(Word16)*L_SUBFR); /* set to zero "h1[-L_SUBFR..-1]" */ + + /* OL LTP states */ + for (i = 0; i < 5; i++) + { + st->old_lags[i] = 40; + } + + /* Reset lpc states */ + lpc_reset(st->lpcSt); + + /* Reset lsp states */ + lsp_reset(st->lspSt); + + /* Reset clLtp states */ + cl_ltp_reset(st->clLtpSt); + + gainQuant_reset(st->gainQuantSt); + + p_ol_wgh_reset(st->pitchOLWghtSt); + + ton_stab_reset(st->tonStabSt); + +#ifndef VAD2 + vad1_reset(st->vadSt); +#else + vad2_reset(st->vadSt); +#endif + + dtx_enc_reset(st->dtx_encSt, st->common_amr_tbls.lsp_init_data_ptr); + + st->sharp = SHARPMIN; + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cod_amr_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a pointer to a structure of type cod_amrState + + Outputs: + state points to a NULL address + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function frees the memory used for state memory. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void cod_amr_exit (cod_amrState **state) +{ + if (state == NULL || *state == NULL) + return; + + // dealloc members + lpc_exit(&(*state)->lpcSt); + lsp_exit(&(*state)->lspSt); + gainQuant_exit(&(*state)->gainQuantSt); + cl_ltp_exit(&(*state)->clLtpSt); + p_ol_wgh_exit(&(*state)->pitchOLWghtSt); + ton_stab_exit(&(*state)->tonStabSt); +#ifndef VAD2 + vad1_exit(&(*state)->vadSt); +#else + vad2_exit(&(*state)->vadSt); +#endif + dtx_enc_exit(&(*state)->dtx_encSt); + + // deallocate memory + free(*state); + *state = NULL; + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void cod_amr_exit(cod_amrState **state) +{ + if (state == NULL || *state == NULL) + { + return; + } + + /* dealloc members */ + lpc_exit(&(*state)->lpcSt); + lsp_exit(&(*state)->lspSt); + gainQuant_exit(&(*state)->gainQuantSt); + cl_ltp_exit(&(*state)->clLtpSt); + p_ol_wgh_exit(&(*state)->pitchOLWghtSt); + ton_stab_exit(&(*state)->tonStabSt); +#ifndef VAD2 + vad1_exit(&(*state)->vadSt); +#else + vad2_exit(&(*state)->vadSt); +#endif + dtx_enc_exit(&(*state)->dtx_encSt); + + /* deallocate memory */ + oscl_free(*state); // BX + *state = NULL; + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cod_amr_first +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type cod_amrState + new_speech = pointer to buffer of length L_FRAME that contains + the speech input (Word16) + + Outputs: + The structure of type cod_amrState pointed to by st is updated. + + Returns: + return_value = 0 (int) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function copes with look-ahead and calls cod_amr. + No input argument are passed to this function. However, before + calling this function, 40 new speech data should be copied to the + vector new_speech[]. This is a global pointer which is declared in + this file (it points to the end of speech buffer minus 200). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int cod_amr_first(cod_amrState *st, // i/o : State struct + Word16 new_speech[]) // i : speech input (L_FRAME) +{ + Copy(new_speech,&st->new_speech[-L_NEXT], L_NEXT); + // Copy(new_speech,st->new_speech,L_FRAME); + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 cod_amr_first(cod_amrState *st, /* i/o : State struct */ + Word16 new_speech[]) /* i : speech input (L_FRAME) */ +{ + + oscl_memcpy(&st->new_speech[-L_NEXT], new_speech, L_NEXT*sizeof(Word16)); + + /* Copy(new_speech,st->new_speech,L_FRAME); */ + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cod_amr +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type cod_amrState + mode = AMR mode of type enum Mode + new_speech = pointer to buffer of length L_FRAME that contains + the speech input of type Word16 + ana = pointer to the analysis parameters of type Word16 + usedMode = pointer to the used mode of type enum Mode + synth = pointer to a buffer containing the local synthesis speech of + type Word16 + + Outputs: + The structure of type cod_amrState pointed to by st is updated. + The analysis parameter buffer pointed to by ana is updated. + The value pointed to by usedMode is updated. + The local synthesis speech buffer pointed to by synth is updated. + + Returns: + return_value = 0 (int) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function is the main encoder routine. It is called every 20 ms speech + frame, operating on the newly read 160 speech samples. It performs the + principle encoding functions to produce the set of encoded parameters + which include the LSP, adaptive codebook, and fixed codebook + quantization indices (addresses and gains). + + Before calling this function, 160 new speech data should be copied to the + vector new_speech[]. This is a global pointer which is declared in + this file (it points to the end of speech buffer minus 160). + + The outputs of the function are: + ana[]: vector of analysis parameters. + synth[]: Local synthesis speech (for debugging purposes) + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + cod_amr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int cod_amr( + cod_amrState *st, // i/o : State struct + enum Mode mode, // i : AMR mode + Word16 new_speech[], // i : speech input (L_FRAME) + Word16 ana[], // o : Analysis parameters + enum Mode *usedMode, // o : used mode + Word16 synth[] // o : Local synthesis +) +{ + // LPC coefficients + Word16 A_t[(MP1) * 4]; // A(z) unquantized for the 4 subframes + Word16 Aq_t[(MP1) * 4]; // A(z) quantized for the 4 subframes + Word16 *A, *Aq; // Pointer on A_t and Aq_t + Word16 lsp_new[M]; + + // Other vectors + Word16 xn[L_SUBFR]; // Target vector for pitch search + Word16 xn2[L_SUBFR]; // Target vector for codebook search + Word16 code[L_SUBFR]; // Fixed codebook excitation + Word16 y1[L_SUBFR]; // Filtered adaptive excitation + Word16 y2[L_SUBFR]; // Filtered fixed codebook excitation + Word16 gCoeff[6]; // Correlations between xn, y1, & y2: + Word16 res[L_SUBFR]; // Short term (LPC) prediction residual + Word16 res2[L_SUBFR]; // Long term (LTP) prediction residual + + // Vector and scalars needed for the MR475 + Word16 xn_sf0[L_SUBFR]; // Target vector for pitch search + Word16 y2_sf0[L_SUBFR]; // Filtered codebook innovation + Word16 code_sf0[L_SUBFR]; // Fixed codebook excitation + Word16 h1_sf0[L_SUBFR]; // The impulse response of sf0 + Word16 mem_syn_save[M]; // Filter memory + Word16 mem_w0_save[M]; // Filter memory + Word16 mem_err_save[M]; // Filter memory + Word16 sharp_save; // Sharpening + Word16 evenSubfr; // Even subframe indicator + Word16 T0_sf0 = 0; // Integer pitch lag of sf0 + Word16 T0_frac_sf0 = 0; // Fractional pitch lag of sf0 + Word16 i_subfr_sf0 = 0; // Position in exc[] for sf0 + Word16 gain_pit_sf0; // Quantized pitch gain for sf0 + Word16 gain_code_sf0; // Quantized codebook gain for sf0 + + // Scalars + Word16 i_subfr, subfrNr; + Word16 T_op[L_FRAME/L_FRAME_BY2]; + Word16 T0, T0_frac; + Word16 gain_pit, gain_code; + + // Flags + Word16 lsp_flag = 0; // indicates resonance in LPC filter + Word16 gp_limit; // pitch gain limit value + Word16 vad_flag; // VAD decision flag + Word16 compute_sid_flag; // SID analysis flag + + Copy(new_speech, st->new_speech, L_FRAME); + + *usedMode = mode; + + // DTX processing + if (st->dtx) + { // no test() call since this if is only in simulation env + // Find VAD decision + +#ifdef VAD2 + vad_flag = vad2 (st->new_speech, st->vadSt); + vad_flag = vad2 (st->new_speech+80, st->vadSt) || vad_flag; +#else + vad_flag = vad1(st->vadSt, st->new_speech); +#endif + + // NB! usedMode may change here + compute_sid_flag = tx_dtx_handler(st->dtx_encSt, + vad_flag, + usedMode); + } + else + { + compute_sid_flag = 0; + } + + *------------------------------------------------------------------------* + * - Perform LPC analysis: * + * * autocorrelation + lag windowing * + * * Levinson-durbin algorithm to find a[] * + * * convert a[] to lsp[] * + * * quantize and code the LSPs * + * * find the interpolated LSPs and convert to a[] for all * + * subframes (both quantized and unquantized) * + *------------------------------------------------------------------------* + + // LP analysis + lpc(st->lpcSt, mode, st->p_window, st->p_window_12k2, A_t); + + + // From A(z) to lsp. LSP quantization and interpolation + lsp(st->lspSt, mode, *usedMode, A_t, Aq_t, lsp_new, &ana); + + + // Buffer lsp's and energy + dtx_buffer(st->dtx_encSt, + lsp_new, + st->new_speech); + + // Check if in DTX mode + if (sub(*usedMode, MRDTX) == 0) + { + dtx_enc(st->dtx_encSt, + compute_sid_flag, + st->lspSt->qSt, + st->gainQuantSt->gc_predSt, + &ana); + + Set_zero(st->old_exc, PIT_MAX + L_INTERPOL); + Set_zero(st->mem_w0, M); + Set_zero(st->mem_err, M); + Set_zero(st->zero, L_SUBFR); + Set_zero(st->hvec, L_SUBFR); // set to zero "h1[-L_SUBFR..-1]" + // Reset lsp states + lsp_reset(st->lspSt); + Copy(lsp_new, st->lspSt->lsp_old, M); + Copy(lsp_new, st->lspSt->lsp_old_q, M); + + // Reset clLtp states + cl_ltp_reset(st->clLtpSt); + st->sharp = SHARPMIN; + } + else + { + // check resonance in the filter + lsp_flag = check_lsp(st->tonStabSt, st->lspSt->lsp_old); + } + + *----------------------------------------------------------------------* + * - Find the weighted input speech w_sp[] for the whole speech frame * + * - Find the open-loop pitch delay for first 2 subframes * + * - Set the range for searching closed-loop pitch in 1st subframe * + * - Find the open-loop pitch delay for last 2 subframes * + *----------------------------------------------------------------------* + +#ifdef VAD2 + if (st->dtx) + { // no test() call since this if is only in simulation env + st->vadSt->L_Rmax = 0; + st->vadSt->L_R0 = 0; + } +#endif + for(subfrNr = 0, i_subfr = 0; + subfrNr < L_FRAME/L_FRAME_BY2; + subfrNr++, i_subfr += L_FRAME_BY2) + { + // Pre-processing on 80 samples + pre_big(mode, gamma1, gamma1_12k2, gamma2, A_t, i_subfr, st->speech, + st->mem_w, st->wsp); + + if ((sub(mode, MR475) != 0) && (sub(mode, MR515) != 0)) + { + // Find open loop pitch lag for two subframes + ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[i_subfr], + &T_op[subfrNr], st->old_lags, st->ol_gain_flg, subfrNr, + st->dtx); + } + } + + if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0)) + { + // Find open loop pitch lag for ONE FRAME ONLY + // search on 160 samples + + ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[0], &T_op[0], + st->old_lags, st->ol_gain_flg, 1, st->dtx); + T_op[1] = T_op[0]; + } + +#ifdef VAD2 + if (st->dtx) + { // no test() call since this if is only in simulation env + LTP_flag_update(st->vadSt, mode); + } +#endif + +#ifndef VAD2 + // run VAD pitch detection + if (st->dtx) + { // no test() call since this if is only in simulation env + vad_pitch_detection(st->vadSt, T_op); + } +#endif + + if (sub(*usedMode, MRDTX) == 0) + { + goto the_end; + } + + *------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * To find the pitch and innovation parameters. The subframe size is * + * L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times. * + * - find the weighted LPC coefficients * + * - find the LPC residual signal res[] * + * - compute the target signal for pitch search * + * - compute impulse response of weighted synthesis filter (h1[]) * + * - find the closed-loop pitch parameters * + * - encode the pitch dealy * + * - update the impulse response h1[] by including fixed-gain pitch * + * - find target vector for codebook search * + * - codebook search * + * - encode codebook address * + * - VQ of pitch and codebook gains * + * - find synthesis speech * + * - update states of weighting filter * + *------------------------------------------------------------------------* + + A = A_t; // pointer to interpolated LPC parameters + Aq = Aq_t; // pointer to interpolated quantized LPC parameters + + evenSubfr = 0; + subfrNr = -1; + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + subfrNr = add(subfrNr, 1); + evenSubfr = sub(1, evenSubfr); + + // Save states for the MR475 mode + if ((evenSubfr != 0) && (sub(*usedMode, MR475) == 0)) + { + Copy(st->mem_syn, mem_syn_save, M); + Copy(st->mem_w0, mem_w0_save, M); + Copy(st->mem_err, mem_err_save, M); + sharp_save = st->sharp; + } + + *-----------------------------------------------------------------* + * - Preprocessing of subframe * + *-----------------------------------------------------------------* + if (sub(*usedMode, MR475) != 0) + { + subframePreProc(*usedMode, gamma1, gamma1_12k2, + gamma2, A, Aq, &st->speech[i_subfr], + st->mem_err, st->mem_w0, st->zero, + st->ai_zero, &st->exc[i_subfr], + st->h1, xn, res, st->error); + } + else + { // MR475 + subframePreProc(*usedMode, gamma1, gamma1_12k2, + gamma2, A, Aq, &st->speech[i_subfr], + st->mem_err, mem_w0_save, st->zero, + st->ai_zero, &st->exc[i_subfr], + st->h1, xn, res, st->error); + + // save impulse response (modified in cbsearch) + if (evenSubfr != 0) + { + Copy (st->h1, h1_sf0, L_SUBFR); + } + } + + // copy the LP residual (res2 is modified in the CL LTP search) + Copy (res, res2, L_SUBFR); + + + *-----------------------------------------------------------------* + * - Closed-loop LTP search * + *-----------------------------------------------------------------* + cl_ltp(st->clLtpSt, st->tonStabSt, *usedMode, i_subfr, T_op, st->h1, + &st->exc[i_subfr], res2, xn, lsp_flag, xn2, y1, + &T0, &T0_frac, &gain_pit, gCoeff, &ana, + &gp_limit); + + // update LTP lag history + if ((subfrNr == 0) && (st->ol_gain_flg[0] > 0)) + { + st->old_lags[1] = T0; + } + + if ((sub(subfrNr, 3) == 0) && (st->ol_gain_flg[1] > 0)) + { + st->old_lags[0] = T0; + } + + + *-----------------------------------------------------------------* + * - Inovative codebook search (find index and gain) * + *-----------------------------------------------------------------* + cbsearch(xn2, st->h1, T0, st->sharp, gain_pit, res2, + code, y2, &ana, *usedMode, subfrNr); + + *------------------------------------------------------* + * - Quantization of gains. * + *------------------------------------------------------* + gainQuant(st->gainQuantSt, *usedMode, res, &st->exc[i_subfr], code, + xn, xn2, y1, y2, gCoeff, evenSubfr, gp_limit, + &gain_pit_sf0, &gain_code_sf0, + &gain_pit, &gain_code, &ana); + + // update gain history + update_gp_clipping(st->tonStabSt, gain_pit); + + if (sub(*usedMode, MR475) != 0) + { + // Subframe Post Porcessing + subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, + gain_code, Aq, synth, xn, code, y1, y2, st->mem_syn, + st->mem_err, st->mem_w0, st->exc, &st->sharp); + } + else + { + if (evenSubfr != 0) + { + i_subfr_sf0 = i_subfr; + Copy(xn, xn_sf0, L_SUBFR); + Copy(y2, y2_sf0, L_SUBFR); + Copy(code, code_sf0, L_SUBFR); + T0_sf0 = T0; + T0_frac_sf0 = T0_frac; + + // Subframe Post Porcessing + subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, + gain_code, Aq, synth, xn, code, y1, y2, + mem_syn_save, st->mem_err, mem_w0_save, + st->exc, &st->sharp); + st->sharp = sharp_save; + } + else + { + // update both subframes for the MR475 + + // Restore states for the MR475 mode + Copy(mem_err_save, st->mem_err, M); + + // re-build excitation for sf 0 + Pred_lt_3or6(&st->exc[i_subfr_sf0], T0_sf0, T0_frac_sf0, + L_SUBFR, 1); + Convolve(&st->exc[i_subfr_sf0], h1_sf0, y1, L_SUBFR); + + Aq -= MP1; + subframePostProc(st->speech, *usedMode, i_subfr_sf0, + gain_pit_sf0, gain_code_sf0, Aq, + synth, xn_sf0, code_sf0, y1, y2_sf0, + st->mem_syn, st->mem_err, st->mem_w0, st->exc, + &sharp_save); // overwrites sharp_save + Aq += MP1; + + // re-run pre-processing to get xn right (needed by postproc) + // (this also reconstructs the unsharpened h1 for sf 1) + subframePreProc(*usedMode, gamma1, gamma1_12k2, + gamma2, A, Aq, &st->speech[i_subfr], + st->mem_err, st->mem_w0, st->zero, + st->ai_zero, &st->exc[i_subfr], + st->h1, xn, res, st->error); + + // re-build excitation sf 1 (changed if lag < L_SUBFR) + Pred_lt_3or6(&st->exc[i_subfr], T0, T0_frac, L_SUBFR, 1); + Convolve(&st->exc[i_subfr], st->h1, y1, L_SUBFR); + + subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, + gain_code, Aq, synth, xn, code, y1, y2, + st->mem_syn, st->mem_err, st->mem_w0, + st->exc, &st->sharp); + } + } + + + A += MP1; // interpolated LPC parameters for next subframe + Aq += MP1; + } + + Copy(&st->old_exc[L_FRAME], &st->old_exc[0], PIT_MAX + L_INTERPOL); + +the_end: + + *--------------------------------------------------* + * Update signal for next frame. * + *--------------------------------------------------* + Copy(&st->old_wsp[L_FRAME], &st->old_wsp[0], PIT_MAX); + + Copy(&st->old_speech[L_FRAME], &st->old_speech[0], L_TOTAL - L_FRAME); + + return 0; +} +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 cod_amr( + cod_amrState *st, /* i/o : State struct */ + enum Mode mode, /* i : AMR mode */ + Word16 new_speech[], /* i : speech input (L_FRAME) */ + Word16 ana[], /* o : Analysis parameters */ + enum Mode *usedMode, /* o : used mode */ + Word16 synth[] /* o : Local synthesis */ +) +{ + /* LPC coefficients */ + Word16 A_t[(MP1) * 4]; /* A(z) unquantized for the 4 subframes */ + Word16 Aq_t[(MP1) * 4]; /* A(z) quantized for the 4 subframes */ + Word16 *A, *Aq; /* Pointer on A_t and Aq_t */ + Word16 lsp_new[M]; + + /* Other vectors */ + Word16 xn[L_SUBFR]; /* Target vector for pitch search */ + Word16 xn2[L_SUBFR]; /* Target vector for codebook search */ + Word16 code[L_SUBFR]; /* Fixed codebook excitation */ + Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */ + Word16 y2[L_SUBFR]; /* Filtered fixed codebook excitation */ + Word16 gCoeff[6]; /* Correlations between xn, y1, & y2: */ + Word16 res[L_SUBFR]; /* Short term (LPC) prediction residual */ + Word16 res2[L_SUBFR]; /* Long term (LTP) prediction residual */ + + /* Vector and scalars needed for the MR475 */ + Word16 xn_sf0[L_SUBFR]; /* Target vector for pitch search */ + Word16 y2_sf0[L_SUBFR]; /* Filtered codebook innovation */ + Word16 code_sf0[L_SUBFR]; /* Fixed codebook excitation */ + Word16 h1_sf0[L_SUBFR]; /* The impulse response of sf0 */ + Word16 mem_syn_save[M]; /* Filter memory */ + Word16 mem_w0_save[M]; /* Filter memory */ + Word16 mem_err_save[M]; /* Filter memory */ + Word16 sharp_save; /* Sharpening */ + Word16 evenSubfr; /* Even subframe indicator */ + Word16 T0_sf0 = 0; /* Integer pitch lag of sf0 */ + Word16 T0_frac_sf0 = 0; /* Fractional pitch lag of sf0 */ + Word16 i_subfr_sf0 = 0; /* Position in exc[] for sf0 */ + Word16 gain_pit_sf0; /* Quantized pitch gain for sf0 */ + Word16 gain_code_sf0; /* Quantized codebook gain for sf0 */ + + /* Scalars */ + Word16 i_subfr, subfrNr; + Word16 T_op[L_FRAME/L_FRAME_BY2]; + Word16 T0, T0_frac; + Word16 gain_pit, gain_code; + + /* Flags */ + Word16 lsp_flag = 0; /* indicates resonance in LPC filter */ + Word16 gp_limit; /* pitch gain limit value */ + Word16 vad_flag; /* VAD decision flag */ + Word16 compute_sid_flag; /* SID analysis flag */ + Flag *pOverflow = &(st->overflow); /* Overflow flag */ + + + oscl_memcpy(st->new_speech, new_speech, L_FRAME*sizeof(Word16)); + + *usedMode = mode; + + /* DTX processing */ + if (st->dtx) + { + /* Find VAD decision */ +#ifdef VAD2 + vad_flag = vad2(st->new_speech, st->vadSt, pOverflow); + vad_flag = vad2(st->new_speech + 80, st->vadSt, pOverflow) || vad_flag; +#else + vad_flag = vad1(st->vadSt, st->new_speech, pOverflow); +#endif + + /* NB! usedMode may change here */ + compute_sid_flag = tx_dtx_handler(st->dtx_encSt, + vad_flag, + usedMode, pOverflow); + } + else + { + compute_sid_flag = 0; + } + + /*------------------------------------------------------------------------* + * - Perform LPC analysis: * + * * autocorrelation + lag windowing * + * * Levinson-durbin algorithm to find a[] * + * * convert a[] to lsp[] * + * * quantize and code the LSPs * + * * find the interpolated LSPs and convert to a[] for all * + * subframes (both quantized and unquantized) * + *------------------------------------------------------------------------*/ + + /* LP analysis */ + lpc(st->lpcSt, mode, st->p_window, st->p_window_12k2, A_t, &(st->common_amr_tbls), pOverflow); + + /* From A(z) to lsp. LSP quantization and interpolation */ + lsp(st->lspSt, mode, *usedMode, A_t, Aq_t, lsp_new, &ana, pOverflow); + + /* Buffer lsp's and energy */ + dtx_buffer(st->dtx_encSt, + lsp_new, + st->new_speech, pOverflow); + + /* Check if in DTX mode */ + + if (*usedMode == MRDTX) + { + dtx_enc(st->dtx_encSt, + compute_sid_flag, + st->lspSt->qSt, + &(st->gainQuantSt->gc_predSt), + &ana, pOverflow); + + oscl_memset(st->old_exc, 0, sizeof(Word16)*(PIT_MAX + L_INTERPOL)); + oscl_memset(st->mem_w0, 0, sizeof(Word16)*M); + oscl_memset(st->mem_err, 0, sizeof(Word16)*M); + oscl_memset(st->zero, 0, sizeof(Word16)*L_SUBFR); + oscl_memset(st->hvec, 0, sizeof(Word16)*L_SUBFR); /* set to zero "h1[-L_SUBFR..-1]" */ + /* Reset lsp states */ + lsp_reset(st->lspSt); + + oscl_memcpy(st->lspSt->lsp_old, lsp_new, M*sizeof(Word16)); + oscl_memcpy(st->lspSt->lsp_old_q, lsp_new, M*sizeof(Word16)); + + /* Reset clLtp states */ + cl_ltp_reset(st->clLtpSt); + st->sharp = SHARPMIN; + } + else + { + /* check resonance in the filter */ + lsp_flag = check_lsp(st->tonStabSt, st->lspSt->lsp_old, pOverflow); + } + + /*----------------------------------------------------------------------* + * - Find the weighted input speech w_sp[] for the whole speech frame * + * - Find the open-loop pitch delay for first 2 subframes * + * - Set the range for searching closed-loop pitch in 1st subframe * + * - Find the open-loop pitch delay for last 2 subframes * + *----------------------------------------------------------------------*/ + +#ifdef VAD2 + if (st->dtx) + { + st->vadSt->L_Rmax = 0; + st->vadSt->L_R0 = 0; + } +#endif + + for (subfrNr = 0, i_subfr = 0; + subfrNr < L_FRAME / L_FRAME_BY2; + subfrNr++, i_subfr += L_FRAME_BY2) + { + /* Pre-processing on 80 samples */ + pre_big(mode, gamma1, gamma1_12k2, gamma2, A_t, i_subfr, st->speech, + st->mem_w, st->wsp, pOverflow); + + + if ((mode != MR475) && (mode != MR515)) + { + /* Find open loop pitch lag for two subframes */ + ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[i_subfr], + &T_op[subfrNr], st->old_lags, st->ol_gain_flg, subfrNr, + st->dtx, pOverflow); + } + } + + if ((mode == MR475) || (mode == MR515)) + { + /* Find open loop pitch lag for ONE FRAME ONLY */ + /* search on 160 samples */ + + ol_ltp(st->pitchOLWghtSt, st->vadSt, mode, &st->wsp[0], &T_op[0], + st->old_lags, st->ol_gain_flg, 1, st->dtx, pOverflow); + T_op[1] = T_op[0]; + } + +#ifdef VAD2 + if (st->dtx) + { + LTP_flag_update(st->vadSt, (Word16) mode, pOverflow); + } +#endif + +#ifndef VAD2 + /* run VAD pitch detection */ + if (st->dtx) + { + vad_pitch_detection(st->vadSt, T_op, pOverflow); + } +#endif + + if (*usedMode == MRDTX) + { + goto the_end; + } + + /*------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * To find the pitch and innovation parameters. The subframe size is * + * L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times. * + * - find the weighted LPC coefficients * + * - find the LPC residual signal res[] * + * - compute the target signal for pitch search * + * - compute impulse response of weighted synthesis filter (h1[]) * + * - find the closed-loop pitch parameters * + * - encode the pitch dealy * + * - update the impulse response h1[] by including fixed-gain pitch * + * - find target vector for codebook search * + * - codebook search * + * - encode codebook address * + * - VQ of pitch and codebook gains * + * - find synthesis speech * + * - update states of weighting filter * + *------------------------------------------------------------------------*/ + + A = A_t; /* pointer to interpolated LPC parameters */ + Aq = Aq_t; /* pointer to interpolated quantized LPC parameters */ + + evenSubfr = 0; + subfrNr = -1; + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + subfrNr++; + evenSubfr = 1 - evenSubfr; + + /* Save states for the MR475 mode */ + + if ((evenSubfr != 0) && (*usedMode == MR475)) + { + oscl_memcpy(mem_syn_save, st->mem_syn, M*sizeof(Word16)); + oscl_memcpy(mem_w0_save, st->mem_w0, M*sizeof(Word16)); + oscl_memcpy(mem_err_save, st->mem_err, M*sizeof(Word16)); + + sharp_save = st->sharp; + } + + /*-----------------------------------------------------------------* + * - Preprocessing of subframe * + *-----------------------------------------------------------------*/ + + if (*usedMode != MR475) + { + subframePreProc(*usedMode, gamma1, gamma1_12k2, + gamma2, A, Aq, &st->speech[i_subfr], + st->mem_err, st->mem_w0, st->zero, + st->ai_zero, &st->exc[i_subfr], + st->h1, xn, res, st->error); + } + else + { /* MR475 */ + subframePreProc(*usedMode, gamma1, gamma1_12k2, + gamma2, A, Aq, &st->speech[i_subfr], + st->mem_err, mem_w0_save, st->zero, + st->ai_zero, &st->exc[i_subfr], + st->h1, xn, res, st->error); + + /* save impulse response (modified in cbsearch) */ + + if (evenSubfr != 0) + { + oscl_memcpy(h1_sf0, st->h1, L_SUBFR*sizeof(Word16)); + + } + } + + /* copy the LP residual (res2 is modified in the CL LTP search) */ + oscl_memcpy(res2, res, L_SUBFR*sizeof(Word16)); + + /*-----------------------------------------------------------------* + * - Closed-loop LTP search * + *-----------------------------------------------------------------*/ + cl_ltp(st->clLtpSt, st->tonStabSt, *usedMode, i_subfr, T_op, st->h1, + &st->exc[i_subfr], res2, xn, lsp_flag, xn2, y1, + &T0, &T0_frac, &gain_pit, gCoeff, &ana, + &gp_limit, st->common_amr_tbls.qua_gain_pitch_ptr, pOverflow); + + /* update LTP lag history */ + + if ((subfrNr == 0) && (st->ol_gain_flg[0] > 0)) + { + st->old_lags[1] = T0; + } + + + if ((subfrNr == 3) && (st->ol_gain_flg[1] > 0)) + { + st->old_lags[0] = T0; + } + + /*-----------------------------------------------------------------* + * - Inovative codebook search (find index and gain) * + *-----------------------------------------------------------------*/ + cbsearch(xn2, st->h1, T0, st->sharp, gain_pit, res2, + code, y2, &ana, *usedMode, subfrNr, &(st->common_amr_tbls), pOverflow); + + /*------------------------------------------------------* + * - Quantization of gains. * + *------------------------------------------------------*/ + gainQuant(st->gainQuantSt, *usedMode, res, &st->exc[i_subfr], code, + xn, xn2, y1, y2, gCoeff, evenSubfr, gp_limit, + &gain_pit_sf0, &gain_code_sf0, + &gain_pit, &gain_code, &ana, &(st->common_amr_tbls), pOverflow); + + /* update gain history */ + update_gp_clipping(st->tonStabSt, gain_pit, pOverflow); + + + if (*usedMode != MR475) + { + /* Subframe Post Porcessing */ + subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, + gain_code, Aq, synth, xn, code, y1, y2, st->mem_syn, + st->mem_err, st->mem_w0, st->exc, &st->sharp, pOverflow); + } + else + { + + if (evenSubfr != 0) + { + i_subfr_sf0 = i_subfr; + + oscl_memcpy(xn_sf0, xn, L_SUBFR*sizeof(Word16)); + oscl_memcpy(y2_sf0, y2, L_SUBFR*sizeof(Word16)); + oscl_memcpy(code_sf0, code, L_SUBFR*sizeof(Word16)); + + T0_sf0 = T0; + T0_frac_sf0 = T0_frac; + + /* Subframe Post Porcessing */ + subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, + gain_code, Aq, synth, xn, code, y1, y2, + mem_syn_save, st->mem_err, mem_w0_save, + st->exc, &st->sharp, pOverflow); + st->sharp = sharp_save; + } + else + { + /* update both subframes for the MR475 */ + + /* Restore states for the MR475 mode */ + oscl_memcpy(st->mem_err, mem_err_save, M*sizeof(Word16)); + + + /* re-build excitation for sf 0 */ + Pred_lt_3or6(&st->exc[i_subfr_sf0], T0_sf0, T0_frac_sf0, + L_SUBFR, 1, pOverflow); + Convolve(&st->exc[i_subfr_sf0], h1_sf0, y1, L_SUBFR); + + Aq -= MP1; + subframePostProc(st->speech, *usedMode, i_subfr_sf0, + gain_pit_sf0, gain_code_sf0, Aq, + synth, xn_sf0, code_sf0, y1, y2_sf0, + st->mem_syn, st->mem_err, st->mem_w0, st->exc, + &sharp_save, pOverflow); /* overwrites sharp_save */ + Aq += MP1; + + /* re-run pre-processing to get xn right (needed by postproc) */ + /* (this also reconstructs the unsharpened h1 for sf 1) */ + subframePreProc(*usedMode, gamma1, gamma1_12k2, + gamma2, A, Aq, &st->speech[i_subfr], + st->mem_err, st->mem_w0, st->zero, + st->ai_zero, &st->exc[i_subfr], + st->h1, xn, res, st->error); + + /* re-build excitation sf 1 (changed if lag < L_SUBFR) */ + Pred_lt_3or6(&st->exc[i_subfr], T0, T0_frac, L_SUBFR, 1, pOverflow); + Convolve(&st->exc[i_subfr], st->h1, y1, L_SUBFR); + + subframePostProc(st->speech, *usedMode, i_subfr, gain_pit, + gain_code, Aq, synth, xn, code, y1, y2, + st->mem_syn, st->mem_err, st->mem_w0, + st->exc, &st->sharp, pOverflow); + } + } + + A += MP1; /* interpolated LPC parameters for next subframe */ + Aq += MP1; + } + + oscl_memcpy(&st->old_exc[0], &st->old_exc[L_FRAME], (PIT_MAX + L_INTERPOL)*sizeof(Word16)); + +the_end: + + /*--------------------------------------------------* + * Update signal for next frame. * + *--------------------------------------------------*/ + + oscl_memcpy(&st->old_wsp[0], &st->old_wsp[L_FRAME], PIT_MAX*sizeof(Word16)); + oscl_memcpy(&st->old_speech[0], &st->old_speech[L_FRAME], (L_TOTAL - L_FRAME)*sizeof(Word16)); + + return(0); +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cod_amr.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cod_amr.h new file mode 100644 index 00000000..4eb60156 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cod_amr.h @@ -0,0 +1,264 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: cod_amr.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : cod_amr.h + Purpose : Main encoder routine operating on a frame basis. + +------------------------------------------------------------------------------ +*/ + +#ifndef cod_amr_h +#define cod_amr_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" +#include "mode.h" +#include "lpc.h" +#include "lsp.h" +#include "cl_ltp.h" +#include "gain_q.h" +#include "p_ol_wgh.h" +#include "ton_stab.h" +#include "vad.h" +#include "dtx_enc.h" +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + /*-----------------------------------------------------------* + * Coder constant parameters (defined in "cnst.h") * + *-----------------------------------------------------------* + * L_WINDOW : LPC analysis window size. * + * L_NEXT : Samples of next frame needed for autocor. * + * L_FRAME : Frame size. * + * L_FRAME_BY2 : Half the frame size. * + * L_SUBFR : Sub-frame size. * + * M : LPC order. * + * MP1 : LPC order+1 * + * L_TOTAL7k4 : Total size of speech buffer. * + * PIT_MIN7k4 : Minimum pitch lag. * + * PIT_MAX : Maximum pitch lag. * + * L_INTERPOL : Length of filter for interpolation * + *-----------------------------------------------------------*/ + typedef struct + { + /* Speech vector */ + Word16 old_speech[L_TOTAL]; + Word16 *speech, *p_window, *p_window_12k2; + Word16 *new_speech; /* Global variable */ + + /* Weight speech vector */ + Word16 old_wsp[L_FRAME + PIT_MAX]; + Word16 *wsp; + + /* OL LTP states */ + Word16 old_lags[5]; + Word16 ol_gain_flg[2]; + + /* Excitation vector */ + Word16 old_exc[L_FRAME + PIT_MAX + L_INTERPOL]; + Word16 *exc; + + /* Zero vector */ + Word16 ai_zero[L_SUBFR + MP1]; + Word16 *zero; + + /* Impulse response vector */ + Word16 *h1; + Word16 hvec[L_SUBFR * 2]; + + /* Substates */ + lpcState *lpcSt; + lspState *lspSt; + clLtpState *clLtpSt; + gainQuantState *gainQuantSt; + pitchOLWghtState *pitchOLWghtSt; + tonStabState *tonStabSt; + vadState *vadSt; + Flag dtx; + dtx_encState *dtx_encSt; + + /* Filter's memory */ + Word16 mem_syn[M], mem_w0[M], mem_w[M]; + Word16 mem_err[M + L_SUBFR], *error; + + Word16 sharp; + + /* tables from amr common lib */ + CommonAmrTbls common_amr_tbls; + + /* Overflow flag */ + Flag overflow; + + } cod_amrState; + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + /* + ************************************************************************** + * + * Function : cod_amr_init + * Purpose : Allocates memory and initializes state variables + * Description : Stores pointer to filter status struct in *st. This + * pointer has to be passed to cod_amr in each call. + * - initilize pointers to speech buffer + * - initialize static pointers + * - set static vectors to zero + * Returns : 0 on success + * + ************************************************************************** + */ + Word16 cod_amr_init(cod_amrState **st, Flag dtx); + + /* + ************************************************************************** + * + * Function : cod_amr_reset + * Purpose : Resets state memory + * Returns : 0 on success + * + ************************************************************************** + */ + Word16 cod_amr_reset(cod_amrState *st); + + /* + ************************************************************************** + * + * Function : cod_amr_exit + * Purpose : The memory used for state memory is freed + * Description : Stores NULL in *st + * + ************************************************************************** + */ + void cod_amr_exit(cod_amrState **st); + + /*************************************************************************** + * FUNCTION: cod_amr_first + * + * PURPOSE: Copes with look-ahead. + * + * INPUTS: + * No input argument are passed to this function. However, before + * calling this function, 40 new speech data should be copied to the + * vector new_speech[]. This is a global pointer which is declared in + * this file (it points to the end of speech buffer minus 200). + * + ***************************************************************************/ + + Word16 cod_amr_first(cod_amrState *st, /* i/o : State struct */ + Word16 new_speech[] /* i : speech input (L_FRAME) */ + ); + + /*************************************************************************** + * FUNCTION: cod_amr + * + * PURPOSE: Main encoder routine. + * + * DESCRIPTION: This function is called every 20 ms speech frame, + * operating on the newly read 160 speech samples. It performs the + * principle encoding functions to produce the set of encoded parameters + * which include the LSP, adaptive codebook, and fixed codebook + * quantization indices (addresses and gains). + * + * INPUTS: + * No input argument are passed to this function. However, before + * calling this function, 160 new speech data should be copied to the + * vector new_speech[]. This is a global pointer which is declared in + * this file (it points to the end of speech buffer minus 160). + * + * OUTPUTS: + * + * ana[]: vector of analysis parameters. + * synth[]: Local synthesis speech (for debugging purposes) + * + ***************************************************************************/ + + Word16 cod_amr(cod_amrState *st, /* i/o : State struct */ + enum Mode mode, /* i : AMR mode */ + Word16 new_speech[], /* i : speech input (L_FRAME) */ + Word16 ana[], /* o : Analysis parameters */ + enum Mode *usedMode, /* o : used mode */ + Word16 synth[] /* o : Local synthesis */ + ); + + +#ifdef __cplusplus +} +#endif + +#endif /* _cod_amr_h_ */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/convolve.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/convolve.cpp new file mode 100644 index 00000000..e1471d6f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/convolve.cpp @@ -0,0 +1,188 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: convolve.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "convolve.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Convolve +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + x = pointer to input vector of L elements of type Word16 + h = pointer to the filter's impulse response vector of L elements + of type Word16 + y = pointer to the output vector of L elements of type Word16 used for + storing the convolution of x and h; + L = Length of the convolution; type definition is Word16 + + Outputs: + y buffer contains the new convolution output + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Perform the convolution between two vectors x[] and h[] and write the result + in the vector y[]. All vectors are of length L and only the first L samples + of the convolution are computed. + + The convolution is given by: + + y[n] = sum_{i=0}^{n} x[i] h[n-i], n=0,...,L-1 + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + convolve.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Convolve ( + Word16 x[], // (i) : input vector + Word16 h[], // (i) : impulse response + Word16 y[], // (o) : output vector + Word16 L // (i) : vector size +) +{ + Word16 i, n; + Word32 s; + + for (n = 0; n < L; n++) + { + s = 0; move32 (); + for (i = 0; i <= n; i++) + { + s = L_mac (s, x[i], h[n - i]); + } + s = L_shl (s, 3); + y[n] = extract_h (s); move16 (); + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void Convolve( + Word16 x[], /* (i) : input vector */ + Word16 h[], /* (i) : impulse response */ + Word16 y[], /* (o) : output vector */ + Word16 L /* (i) : vector size */ +) +{ + register Word16 i, n; + Word32 s1, s2; + + + for (n = 1; n < L; n = n + 2) + { + + h = h + n; + + s2 = ((Word32) * (x)) * *(h--); + s1 = ((Word32) * (x++)) * *(h); + + for (i = (n - 1) >> 1; i != 0; i--) + { + s2 = amrnb_fxp_mac_16_by_16bb((Word32) * (x), (Word32) * (h--), s2); + s1 = amrnb_fxp_mac_16_by_16bb((Word32) * (x++), (Word32) * (h), s1); + s2 = amrnb_fxp_mac_16_by_16bb((Word32) * (x), (Word32) * (h--), s2); + s1 = amrnb_fxp_mac_16_by_16bb((Word32) * (x++), (Word32) * (h), s1); + } + + s2 = amrnb_fxp_mac_16_by_16bb((Word32) * (x), (Word32) * (h), s2); + + *(y++) = (Word16)(s1 >> 12); + *(y++) = (Word16)(s2 >> 12); + + x = x - n; + + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/convolve.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/convolve.h new file mode 100644 index 00000000..1f2b503f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/convolve.h @@ -0,0 +1,83 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : convolve.h +* Purpose : Perform the convolution between two vectors x[] +* : and h[] and write the result in the vector y[]. +* : All vectors are of length L and only the first +* : L samples of the convolution are computed. +* +******************************************************************************** +*/ +#ifndef convolve_h +#define convolve_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ******************************************************************************** + * DEFINITION OF DATA TYPES + ******************************************************************************** + */ + + /* + ******************************************************************************** + * DECLARATION OF PROTOTYPES + ******************************************************************************** + */ + void Convolve( + Word16 x[], /* (i) : input vector */ + Word16 h[], /* (i) : impulse response */ + Word16 y[], /* (o) : output vector */ + Word16 L /* (i) : vector size */ + ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h.cpp new file mode 100644 index 00000000..32fbdd10 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h.cpp @@ -0,0 +1,350 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: cor_h.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "cnst.h" +#include "cor_h.h" +#include "basicop_malloc.h" +#include "inv_sqrt.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cor_h +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + h = vector containing the impulse response of the weighted synthesis + filter; vector contents are of type Word16; vector length is + 2 * L_SUBFR + sign = vector containing the sign information for the correlation + values; vector contents are of type Word16; vector length is + L_CODE + rr = autocorrelation matrix; matrix contents are of type Word16; + matrix dimension is L_CODE by L_CODE + + Outputs: + rr contents are the newly calculated autocorrelation values + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes correlations of the impulse response (h) needed for + the codebook search, and includes the sign information into the correlations. + + The correlations are given by: + rr[i][j] = sum_{n=i}^{L-1} h[n-i] h[n-j]; i>=j; i,j=0,...,L-1 + + The sign information is included by: + rr[i][j] = rr[i][j]*sign[i]*sign[j] + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + cor_h.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void cor_h ( + Word16 h[], // (i) : impulse response of weighted synthesis + filter + Word16 sign[], // (i) : sign of d[n] + Word16 rr[][L_CODE] // (o) : matrix of autocorrelation +) +{ + Word16 i, j, k, dec, h2[L_CODE]; + Word32 s; + + // Scaling for maximum precision + + s = 2; + for (i = 0; i < L_CODE; i++) + s = L_mac (s, h[i], h[i]); + + j = sub (extract_h (s), 32767); + if (j == 0) + { + for (i = 0; i < L_CODE; i++) + { + h2[i] = shr (h[i], 1); + } + } + else + { + s = L_shr (s, 1); + k = extract_h (L_shl (Inv_sqrt (s), 7)); + k = mult (k, 32440); // k = 0.99*k + + for (i = 0; i < L_CODE; i++) + { + h2[i] = pv_round (L_shl (L_mult (h[i], k), 9)); + } + } + + // build matrix rr[] + s = 0; + i = L_CODE - 1; + for (k = 0; k < L_CODE; k++, i--) + { + s = L_mac (s, h2[k], h2[k]); + rr[i][i] = pv_round (s); + } + + for (dec = 1; dec < L_CODE; dec++) + { + s = 0; + j = L_CODE - 1; + i = sub (j, dec); + for (k = 0; k < (L_CODE - dec); k++, i--, j--) + { + s = L_mac (s, h2[k], h2[k + dec]); + rr[j][i] = mult (pv_round (s), mult (sign[i], sign[j])); + rr[i][j] = rr[j][i]; + } + } +} + +--------------------------------------------------------------------------- + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void cor_h( + Word16 h[], /* (i) : impulse response of weighted synthesis + filter */ + Word16 sign[], /* (i) : sign of d[n] */ + Word16 rr[][L_CODE], /* (o) : matrix of autocorrelation */ + Flag *pOverflow +) +{ + register Word16 i; + register Word16 dec; + + Word16 h2[L_CODE]; + Word32 s; + Word32 s2; + Word16 tmp1; + Word16 tmp2; + Word16 tmp11; + Word16 tmp22; + + Word16 *p_h; + Word16 *p_h2; + Word16 *rr1; + Word16 *rr2; + Word16 *rr3; + Word16 *p_rr_ref1; + Word16 *p_sign1; + Word16 *p_sign2; + + /* Scaling for maximum precision */ + + /* Initialize accumulator to 1 since left shift happens */ + /* after the accumulation of the sum of squares (original */ + /* code initialized s to 2) */ + s = 1; + p_h = h; + + for (i = (L_CODE >> 1); i != 0 ; i--) + { + tmp1 = *(p_h++); + s = amrnb_fxp_mac_16_by_16bb((Word32) tmp1, (Word32) tmp1, s); + tmp1 = *(p_h++); + s = amrnb_fxp_mac_16_by_16bb((Word32) tmp1, (Word32) tmp1, s); + + } + + s <<= 1; + + if (s & MIN_32) + { + p_h2 = h2; + p_h = h; + + for (i = (L_CODE >> 1); i != 0; i--) + { + *(p_h2++) = *(p_h++) >> 1; + *(p_h2++) = *(p_h++) >> 1; + } + } + else + { + + s >>= 1; + + s = Inv_sqrt(s, pOverflow); + + if (s < (Word32) 0x00ffffffL) + { + /* k = 0.99*k */ + dec = (Word16)(((s >> 9) * 32440) >> 15); + } + else + { + dec = 32440; /* 0.99 */ + } + + p_h = h; + p_h2 = h2; + + for (i = (L_CODE >> 1); i != 0; i--) + { + *(p_h2++) = (Word16)((amrnb_fxp_mac_16_by_16bb((Word32) * (p_h++), (Word32) dec, 0x020L)) >> 6); + *(p_h2++) = (Word16)((amrnb_fxp_mac_16_by_16bb((Word32) * (p_h++), (Word32) dec, 0x020L)) >> 6); + } + } + /* build matrix rr[] */ + + s = 0; + + p_h2 = h2; + + rr1 = &rr[L_CODE-1][L_CODE-1]; + + for (i = L_CODE >> 1; i != 0 ; i--) + { + tmp1 = *(p_h2++); + s = amrnb_fxp_mac_16_by_16bb((Word32) tmp1, (Word32) tmp1, s); + *rr1 = (Word16)((s + 0x00004000L) >> 15); + rr1 -= (L_CODE + 1); + tmp1 = *(p_h2++); + s = amrnb_fxp_mac_16_by_16bb((Word32) tmp1, (Word32) tmp1, s); + *rr1 = (Word16)((s + 0x00004000L) >> 15); + rr1 -= (L_CODE + 1); + } + + + p_rr_ref1 = rr[L_CODE-1]; + + for (dec = 1; dec < L_CODE; dec += 2) + { + rr1 = &p_rr_ref1[L_CODE-1-dec]; + + rr2 = &rr[L_CODE-1-dec][L_CODE-1]; + rr3 = &rr[L_CODE-1-(dec+1)][L_CODE-1]; + + s = 0; + s2 = 0; + + p_sign1 = &sign[L_CODE - 1]; + p_sign2 = &sign[L_CODE - 1 - dec]; + + p_h2 = h2; + p_h = &h2[dec]; + + for (i = (L_CODE - dec - 1); i != 0 ; i--) + { + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_h2), (Word32) * (p_h++), s); + s2 = amrnb_fxp_mac_16_by_16bb((Word32) * (p_h2++), (Word32) * (p_h), s2); + + tmp1 = (Word16)((s + 0x00004000L) >> 15); + tmp11 = (Word16)((s2 + 0x00004000L) >> 15); + + tmp2 = ((Word32) * (p_sign1) * *(p_sign2--)) >> 15; + tmp22 = ((Word32) * (p_sign1--) * *(p_sign2)) >> 15; + + *rr2 = ((Word32) tmp1 * tmp2) >> 15; + *(rr1--) = *rr2; + *rr1 = ((Word32) tmp11 * tmp22) >> 15; + *rr3 = *rr1; + + rr1 -= (L_CODE); + rr2 -= (L_CODE + 1); + rr3 -= (L_CODE + 1); + + } + + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_h2), (Word32) * (p_h), s); + + tmp1 = (Word16)((s + 0x00004000L) >> 15); + + tmp2 = ((Word32) * (p_sign1) * *(p_sign2)) >> 15; + *rr1 = ((Word32) tmp1 * tmp2) >> 15; + + *rr2 = *rr1; + + rr1 -= (L_CODE + 1); + rr2 -= (L_CODE + 1); + + } + + return; + +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h.h new file mode 100644 index 00000000..59b9d685 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h.h @@ -0,0 +1,96 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef COR_H_H +#define COR_H_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +#include "cor_h_x.h" /* Used by legacy files */ +#include "cor_h_x2.h" /* Used by legacy files */ + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void cor_h( + Word16 h[], /* (i) : impulse response of weighted synthesis + filter */ + Word16 sign[], /* (i) : sign of d[n] */ + Word16 rr[][L_CODE], /* (o) : matrix of autocorrelation */ + Flag *pOverflow + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h_x.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h_x.cpp new file mode 100644 index 00000000..7bb54bba --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h_x.cpp @@ -0,0 +1,273 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: cor_h_x.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" +#include "cor_h_x.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cor_h_x +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + h = vector containing the impulse response of the weighted synthesis + filter; vector contents are of type Word16; vector length is + 2 * L_SUBFR + x = target signal vector; vector contents are of type Word16; vector + length is L_SUBFR + dn = vector containing the correlation between the target and the + impulse response; vector contents are of type Word16; vector + length is L_CODE + sf = scaling factor of type Word16 ; 2 when mode is MR122, 1 for all + other modes + + Outputs: + dn contents are the newly calculated correlation values + + pOverflow = pointer of type Flag * to overflow indicator. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes the correlation between the target signal (x) and the + impulse response (h). + + The correlation is given by: d[n] = sum_{i=n}^{L-1} x[i] h[i-n], + where: n=0,...,L-1 + + d[n] is normalized such that the sum of 5 maxima of d[n] corresponding to + each position track does not saturate. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + cor_h.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void cor_h_x ( + Word16 h[], // (i): impulse response of weighted synthesis filter + Word16 x[], // (i): target + Word16 dn[], // (o): correlation between target and h[] + Word16 sf // (i): scaling factor: 2 for 12.2, 1 for others +) +{ + cor_h_x2(h, x, dn, sf, NB_TRACK, STEP); +} + + +void cor_h_x2 ( + Word16 h[], // (i): impulse response of weighted synthesis filter + Word16 x[], // (i): target + Word16 dn[], // (o): correlation between target and h[] + Word16 sf, // (i): scaling factor: 2 for 12.2, 1 for others + Word16 nb_track,// (i): the number of ACB tracks + Word16 step // (i): step size from one pulse position to the next + in one track +) +{ + Word16 i, j, k; + Word32 s, y32[L_CODE], max, tot; + + // first keep the result on 32 bits and find absolute maximum + + tot = 5; + + for (k = 0; k < nb_track; k++) + { + max = 0; + for (i = k; i < L_CODE; i += step) + { + s = 0; + for (j = i; j < L_CODE; j++) + s = L_mac (s, x[j], h[j - i]); + + y32[i] = s; + + s = L_abs (s); + if (L_sub (s, max) > (Word32) 0L) + max = s; + } + tot = L_add (tot, L_shr (max, 1)); + } + + j = sub (norm_l (tot), sf); + + for (i = 0; i < L_CODE; i++) + { + dn[i] = pv_round (L_shl (y32[i], j)); + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void cor_h_x( + Word16 h[], /* (i): impulse response of weighted synthesis filter */ + Word16 x[], /* (i): target */ + Word16 dn[], /* (o): correlation between target and h[] */ + Word16 sf, /* (i): scaling factor: 2 for 12.2, 1 for others */ + Flag *pOverflow /* (o): pointer to overflow flag */ +) +{ + register Word16 i; + register Word16 j; + register Word16 k; + + Word32 s; + Word32 y32[L_CODE]; + Word32 max; + Word32 tot; + + Word16 *p_x; + Word16 *p_ptr; + Word32 *p_y32; + + + tot = 5; + for (k = 0; k < NB_TRACK; k++) /* NB_TRACK = 5 */ + { + max = 0; + for (i = k; i < L_CODE; i += STEP) /* L_CODE = 40; STEP = 5 */ + { + s = 0; + p_x = &x[i]; + p_ptr = h; + + for (j = (L_CODE - i - 1) >> 1; j != 0; j--) + { + s += ((Word32) * (p_x++) * *(p_ptr++)) << 1; + s += ((Word32) * (p_x++) * *(p_ptr++)) << 1; + } + + s += ((Word32) * (p_x++) * *(p_ptr++)) << 1; + + if (!((L_CODE - i) & 1)) /* if even number of iterations */ + { + s += ((Word32) * (p_x++) * *(p_ptr++)) << 1; + } + + y32[i] = s; + + if (s < 0) + { + s = -s; + } + + if (s > max) + { + max = s; + } + } + + tot += (max >> 1); + } + + + j = norm_l(tot) - sf; + + p_ptr = dn; + p_y32 = y32;; + + for (i = L_CODE >> 1; i != 0; i--) + { + s = L_shl(*(p_y32++), j, pOverflow); + *(p_ptr++) = (s + 0x00008000) >> 16; + s = L_shl(*(p_y32++), j, pOverflow); + *(p_ptr++) = (s + 0x00008000) >> 16; + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h_x.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h_x.h new file mode 100644 index 00000000..66ada72a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h_x.h @@ -0,0 +1,103 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains prototype declaration for cor_h_x function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef COR_H_X_H +#define COR_H_X_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void cor_h_x( + Word16 h[], /* (i): impulse response of weighted synthesis filter */ + Word16 x[], /* (i): target */ + Word16 dn[], /* (o): correlation between target and h[] */ + Word16 sf, /* (i): scaling factor: 2 for 12.2, 1 for others */ + Flag *pOverflow /* (o): pointer to overflow flag */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h_x2.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h_x2.cpp new file mode 100644 index 00000000..9d72ab32 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h_x2.cpp @@ -0,0 +1,240 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: cor_h_x2.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" +#include "cor_h_x.h" +#include "cor_h_x2.h" // BX +#include "basic_op.h" +#include "l_abs.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define LOG2_OF_32 5 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cor_h_x2 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + h = vector containing the impulse response of the weighted synthesis + filter; vector contents are of type Word16; vector length is + 2 * L_SUBFR + x = target signal vector; vector contents are of type Word16; vector + length is L_SUBFR + dn = vector containing the correlation between the target and the + impulse response; vector contents are of type Word16; vector + length is L_CODE + sf = scaling factor of type Word16 ; 2 when mode is MR122, 1 for all + other modes + nb_track = number of ACB tracks (Word16) + step = step size between pulses in one track (Word16) + pOverflow = pointer to overflow (Flag) + + Outputs: + dn contents are the newly calculated correlation values + pOverflow = 1 if the math functions called by cor_h_x2 result in overflow + else zero. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes the correlation between the target signal (x) and the + impulse response (h). + + The correlation is given by: d[n] = sum_{i=n}^{L-1} x[i] h[i-n], + where: n=0,...,L-1 + + d[n] is normalized such that the sum of 5 maxima of d[n] corresponding to + each position track does not saturate. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + cor_h.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +The original etsi reference code uses a global flag Overflow. However, in the +actual implementation a pointer to a the overflow flag is passed in. + +void cor_h_x2 ( + Word16 h[], // (i): impulse response of weighted synthesis filter + Word16 x[], // (i): target + Word16 dn[], // (o): correlation between target and h[] + Word16 sf, // (i): scaling factor: 2 for 12.2, 1 for others + Word16 nb_track,// (i): the number of ACB tracks + Word16 step // (i): step size from one pulse position to the next + in one track +) +{ + Word16 i, j, k; + Word32 s, y32[L_CODE], max, tot; + + // first keep the result on 32 bits and find absolute maximum + + tot = 5; + + for (k = 0; k < nb_track; k++) + { + max = 0; + for (i = k; i < L_CODE; i += step) + { + s = 0; + for (j = i; j < L_CODE; j++) + s = L_mac (s, x[j], h[j - i]); + + y32[i] = s; + + s = L_abs (s); + if (L_sub (s, max) > (Word32) 0L) + max = s; + } + tot = L_add (tot, L_shr (max, 1)); + } + + j = sub (norm_l (tot), sf); + + for (i = 0; i < L_CODE; i++) + { + dn[i] = pv_round (L_shl (y32[i], j)); + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void cor_h_x2( + Word16 h[], /* (i): impulse response of weighted synthesis filter */ + Word16 x[], /* (i): target */ + Word16 dn[], /* (o): correlation between target and h[] */ + Word16 sf, /* (i): scaling factor: 2 for 12.2, 1 for others */ + Word16 nb_track,/* (i): the number of ACB tracks */ + Word16 step, /* (i): step size from one pulse position to the next + in one track */ + Flag *pOverflow +) +{ + register Word16 i; + register Word16 j; + register Word16 k; + Word32 s; + Word32 y32[L_CODE]; + Word32 max; + Word32 tot; + + + /* first keep the result on 32 bits and find absolute maximum */ + tot = LOG2_OF_32; + for (k = 0; k < nb_track; k++) + { + max = 0; + for (i = k; i < L_CODE; i += step) + { + s = 0; + + for (j = i; j < L_CODE; j++) + { + s = amrnb_fxp_mac_16_by_16bb((Word32)x[j], (Word32)h[j-i], s); + } + + s = s << 1; + y32[i] = s; + s = L_abs(s); + + if (s > max) + { + max = s; + } + } + tot = (tot + (max >> 1)); + } + + j = norm_l(tot) - sf; + + for (i = 0; i < L_CODE; i++) + { + dn[i] = pv_round(L_shl(y32[i], j, pOverflow), pOverflow); + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h_x2.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h_x2.h new file mode 100644 index 00000000..8f43b995 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/cor_h_x2.h @@ -0,0 +1,108 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: cor_h_x2.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains prototype declaration for cor_h_x2 function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef COR_H_X2_H +#define COR_H_X2_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void cor_h_x2( + Word16 h[], /* (i): impulse response of weighted synthesis filter */ + Word16 x[], /* (i): target */ + Word16 dn[], /* (o): correlation between target and h[] */ + Word16 sf, /* (i): scaling factor: 2 for 12.2, 1 for others */ + Word16 nb_track,/* (i): the number of ACB tracks */ + Word16 step, /* (i): step size from one pulse position to the next + in one track */ + Flag *pOverflow + ); + +#ifdef __cplusplus +} +#endif + +#endif /* _COR_H_X2_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/corrwght_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/corrwght_tab.cpp new file mode 100644 index 00000000..34b8a683 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/corrwght_tab.cpp @@ -0,0 +1,170 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + + + + Filename: corrwght_tab.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the tables for correlation weights + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "p_ol_wgh.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here. Include conditional + ; compile variables also.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; [Variable declaration - defined here and used outside this module] + ----------------------------------------------------------------------------*/ + const Word16 corrweight[251] = + { + 20473, 20506, 20539, 20572, 20605, 20644, 20677, + 20716, 20749, 20788, 20821, 20860, 20893, 20932, + 20972, 21011, 21050, 21089, 21129, 21168, 21207, + 21247, 21286, 21332, 21371, 21417, 21456, 21502, + 21542, 21588, 21633, 21679, 21725, 21771, 21817, + 21863, 21909, 21961, 22007, 22059, 22105, 22158, + 22210, 22263, 22315, 22367, 22420, 22472, 22531, + 22584, 22643, 22702, 22761, 22820, 22879, 22938, + 23003, 23062, 23128, 23193, 23252, 23324, 23390, + 23455, 23527, 23600, 23665, 23744, 23816, 23888, + 23967, 24045, 24124, 24202, 24288, 24366, 24451, + 24537, 24628, 24714, 24805, 24904, 24995, 25094, + 25192, 25297, 25395, 25500, 25611, 25723, 25834, + 25952, 26070, 26188, 26313, 26444, 26575, 26706, + 26844, 26988, 27132, 27283, 27440, 27597, 27761, + 27931, 28108, 28285, 28475, 28665, 28869, 29078, + 29295, 29524, 29760, 30002, 30258, 30527, 30808, + 31457, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 31457, 30808, 30527, 30258, 30002, + 29760, 29524, 29295, 29078, 28869, 28665, 28475, + 28285, 28108, 27931, 27761, 27597, 27440, 27283, + 27132, 26988, 26844, 26706, 26575, 26444, 26313, + 26188, 26070, 25952, 25834, 25723, 25611, 25500, + 25395, 25297, 25192, 25094, 24995, 24904, 24805, + 24714, 24628, 24537, 24451, 24366, 24288, 24202, + 24124, 24045, 23967, 23888, 23816, 23744, 23665, + 23600, 23527, 23455, 23390, 23324, 23252, 23193, + 23128, 23062, 23003, 22938, 22879, 22820, 22761, + 22702, 22643, 22584, 22531, 22472, 22420, 22367, + 22315, 22263, 22210, 22158, 22105, 22059, 22007, + 21961, 21909, 21863, 21817, 21771, 21725, 21679, + 21633, 21588, 21542, 21502, 21456, 21417, 21371, + 21332, 21286, 21247, 21207, 21168, 21129, 21089, + 21050, 21011, 20972, 20932, 20893, 20860, 20821, + 20788, 20749, 20716, 20677, 20644, 20605, 20572, + 20539, 20506, 20473, 20434, 20401, 20369, 20336 + }; + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + None + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] corrwght.tab, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/div_32.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/div_32.cpp new file mode 100644 index 00000000..02149871 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/div_32.cpp @@ -0,0 +1,173 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: div_32.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" +#include "div_32.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: div_32 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_num = 32 bit signed integer (Word32) whose value falls in the + range : 0x0000 0000 < L_num < L_denom + L_denom_hi = 16 bit positive normalized integer whose value falls in + the range : 0x4000 < hi < 0x7fff + L_denom_lo = 16 bit positive integer whose value falls in the range : + 0 < lo < 0x7fff + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit divide operation resulted in overflow + + Returns: + result = 32-bit quotient of of the division of two 32 bit integers + L_num / L_denom (Word32) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function is a fractional integer division of two 32 bit numbers, the + numerator L_num and the denominator L_denom. The denominator is formed by + combining denom_hi and denom_lo. Note that denom_hi is a normalized numbers. + The numerator and denominator must be positive and the numerator must be + less than the denominator. + + The division is done as follows: + 1. Find 1/L_denom by first approximating: approx = 1 / denom_hi. + 2. 1/L_denom = approx * (2.0 - L_denom * approx ). + 3. result = L_num * (1/L_denom). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] div_32() function in oper_32b.c, UMTS GSM AMR speech codec, R99 - + Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word32 Div_32(Word32 L_num, + Word16 L_denom_hi, + Word16 L_denom_lo, + Flag *pOverflow) +{ + + Word16 approx; + Word16 hi; + Word16 lo; + Word16 n_hi; + Word16 n_lo; + Word32 result; + + /* First approximation: 1 / L_denom = 1/L_denom_hi */ + + approx = div_s((Word16) 0x3fff, L_denom_hi); + + /* 1/L_denom = approx * (2.0 - L_denom * approx) */ + + result = Mpy_32_16(L_denom_hi, L_denom_lo, approx, pOverflow); + /* result is > 0 , and less than 1.0 */ + result = 0x7fffffffL - result; + + hi = (Word16)(result >> 16); + lo = (result >> 1) - (hi << 15); + + result = Mpy_32_16(hi, lo, approx, pOverflow); + + /* L_num * (1/L_denom) */ + + hi = (Word16)(result >> 16); + lo = (result >> 1) - (hi << 15); + + n_hi = (Word16)(L_num >> 16); + n_lo = (L_num >> 1) - (n_hi << 15); + + result = Mpy_32(n_hi, n_lo, hi, lo, pOverflow); + result = L_shl(result, 2, pOverflow); + + return (result); +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/div_32.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/div_32.h new file mode 100644 index 00000000..281be6aa --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/div_32.h @@ -0,0 +1,103 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: div_32.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the Div_32 function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef DIV_32_H +#define DIV_32_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word32 Div_32(Word32 L_num, + Word16 L_denom_hi, + Word16 L_denom_lo, + Flag *pOverflow) ; + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _DIV_32_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/dtx_enc.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/dtx_enc.cpp new file mode 100644 index 00000000..f4f25f90 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/dtx_enc.cpp @@ -0,0 +1,1004 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dtx_enc.cpp + Functions: dtx_enc_init + dtx_enc_reset + dtx_enc_exit + dtx_enc + dtx_buffer + tx_dtx_handler + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the various functions that perform the computation of the + Silence Indicator (SID) parameters when in Discontinuous Transmission (DTX) + mode. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "dtx_enc.h" +#include "q_plsf.h" +#include "typedef.h" +#include "mode.h" +#include "basic_op.h" +#include "log2.h" +#include "lsp_lsf.h" +#include "reorder.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ +extern Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow); + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: dtx_enc_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to an array of pointers to structures of type + dtx_encState + + Outputs: + pointer pointed to by st is set to the address of the allocated + memory + + Returns: + return_value = 0, if initialization was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function allocates the state memory used by the dtx_enc function. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int dtx_enc_init (dtx_encState **st) +{ + dtx_encState* s; + + if (st == (dtx_encState **) NULL){ + fprintf(stderr, "dtx_enc_init: invalid parameter\n"); + return -1; + } + + *st = NULL; + + // allocate memory + if ((s= (dtx_encState *) malloc(sizeof(dtx_encState))) == NULL){ + fprintf(stderr, "dtx_enc_init: can not malloc state structure\n"); + return -1; + } + + dtx_enc_reset(s); + *st = s; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 dtx_enc_init(dtx_encState **st, const Word16* lsp_init_data_ptr) +{ + dtx_encState* s; + + if (st == (dtx_encState **) NULL) + { + return(-1); + } + + *st = NULL; + + /* allocate memory */ + if ((s = (dtx_encState *) oscl_malloc(sizeof(dtx_encState))) == NULL) + { + return(-1); + } + + dtx_enc_reset(s, lsp_init_data_ptr); + *st = s; + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: dtx_enc_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to structures of type dtx_encState + + Outputs: + structure pointed to by st is initialized to its reset value + + Returns: + return_value = 1, if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + lsp_init_data = table containing LSP initialization values; + table elements are constants of type Word16; + table length is M + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function initializes the fields of the state memory used by dtx_enc + to their reset values. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int dtx_enc_reset (dtx_encState *st) +{ + Word16 i; + + if (st == (dtx_encState *) NULL){ + fprintf(stderr, "dtx_enc_reset: invalid parameter\n"); + return -1; + } + + st->hist_ptr = 0; + st->log_en_index = 0; + st->init_lsf_vq_index = 0; + st->lsp_index[0] = 0; + st->lsp_index[1] = 0; + st->lsp_index[2] = 0; + + // Init lsp_hist[] + for(i = 0; i < DTX_HIST_SIZE; i++) + { + Copy(lsp_init_data, &st->lsp_hist[i * M], M); + } + + // Reset energy history + Set_zero(st->log_en_hist, M); + + st->dtxHangoverCount = DTX_HANG_CONST; + st->decAnaElapsedCount = 32767; + + return 1; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 dtx_enc_reset(dtx_encState *st, const Word16* lsp_init_data_ptr) +{ + Word16 i; + + if (st == (dtx_encState *) NULL) + { + return(-1); + } + + st->hist_ptr = 0; + st->log_en_index = 0; + st->init_lsf_vq_index = 0; + st->lsp_index[0] = 0; + st->lsp_index[1] = 0; + st->lsp_index[2] = 0; + + /* Init lsp_hist[] */ + for (i = 0; i < DTX_HIST_SIZE; i++) + { + oscl_memcpy(&st->lsp_hist[i * M], lsp_init_data_ptr, M*sizeof(Word16)); + } + + /* Reset energy history */ + oscl_memset(st->log_en_hist, 0, sizeof(Word16)*M); + st->dtxHangoverCount = DTX_HANG_CONST; + st->decAnaElapsedCount = 32767; + + return(1); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: dtx_enc_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to an array of pointers to structures of type + dtx_encState + + Outputs: + st points to the NULL address + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function deallocates the state memory used by dtx_enc function. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void dtx_enc_exit (dtx_encState **st) +{ + if (st == NULL || *st == NULL) + return; + + // deallocate memory + free(*st); + *st = NULL; + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void dtx_enc_exit(dtx_encState **st) +{ + if (st == NULL || *st == NULL) + { + return; + } + + /* deallocate memory */ + oscl_free(*st); + *st = NULL; + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: dtx_enc +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to structures of type dtx_encState + computeSidFlag = compute SID flag of type Word16 + qSt = pointer to structures of type Q_plsfState + predState = pointer to structures of type gc_predState + anap = pointer to an array of pointers to analysis parameters of + type Word16 + + Outputs: + structure pointed to by st contains the newly calculated SID + parameters + structure pointed to by predState contains the new logarithmic frame + energy + pointer pointed to by anap points to the location of the new + logarithmic frame energy and new LSPs + + Returns: + return_value = 0 (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calculates the SID parameters when in the DTX mode. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int dtx_enc(dtx_encState *st, // i/o : State struct + Word16 computeSidFlag, // i : compute SID + Q_plsfState *qSt, // i/o : Qunatizer state struct + gc_predState* predState, // i/o : State struct + Word16 **anap // o : analysis parameters + ) +{ + Word16 i,j; + Word16 log_en; + Word16 lsf[M]; + Word16 lsp[M]; + Word16 lsp_q[M]; + Word32 L_lsp[M]; + + // VOX mode computation of SID parameters + if ((computeSidFlag != 0) || + (st->log_en_index == 0)) + { + // compute new SID frame if safe i.e don't + // compute immediately after a talk spurt + log_en = 0; + for (i = 0; i < M; i++) + { + L_lsp[i] = 0; + } + + // average energy and lsp + for (i = 0; i < DTX_HIST_SIZE; i++) + { + log_en = add(log_en, + shr(st->log_en_hist[i],2)); + + for (j = 0; j < M; j++) + { + L_lsp[j] = L_add(L_lsp[j], + L_deposit_l(st->lsp_hist[i * M + j])); + } + } + + log_en = shr(log_en, 1); + for (j = 0; j < M; j++) + { + lsp[j] = extract_l(L_shr(L_lsp[j], 3)); // divide by 8 + } + + // quantize logarithmic energy to 6 bits + st->log_en_index = add(log_en, 2560); // +2.5 in Q10 + st->log_en_index = add(st->log_en_index, 128); // add 0.5/4 in Q10 + st->log_en_index = shr(st->log_en_index, 8); + + if (sub(st->log_en_index, 63) > 0) + { + st->log_en_index = 63; + } + if (st->log_en_index < 0) + { + st->log_en_index = 0; + } + + // update gain predictor memory + log_en = shl(st->log_en_index, -2+10); // Q11 and divide by 4 + log_en = sub(log_en, 2560); // add 2.5 in Q11 + + log_en = sub(log_en, 9000); + if (log_en > 0) + { + log_en = 0; + } + if (sub(log_en, -14436) < 0) + { + log_en = -14436; + } + + // past_qua_en for other modes than MR122 + predState->past_qua_en[0] = log_en; + predState->past_qua_en[1] = log_en; + predState->past_qua_en[2] = log_en; + predState->past_qua_en[3] = log_en; + + // scale down by factor 20*log10(2) in Q15 + log_en = mult(5443, log_en); + + // past_qua_en for mode MR122 + predState->past_qua_en_MR122[0] = log_en; + predState->past_qua_en_MR122[1] = log_en; + predState->past_qua_en_MR122[2] = log_en; + predState->past_qua_en_MR122[3] = log_en; + + // make sure that LSP's are ordered + Lsp_lsf(lsp, lsf, M); + Reorder_lsf(lsf, LSF_GAP, M); + Lsf_lsp(lsf, lsp, M); + + // Quantize lsp and put on parameter list + Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index, + &st->init_lsf_vq_index); + } + + *(*anap)++ = st->init_lsf_vq_index; // 3 bits + + *(*anap)++ = st->lsp_index[0]; // 8 bits + *(*anap)++ = st->lsp_index[1]; // 9 bits + *(*anap)++ = st->lsp_index[2]; // 9 bits + + + *(*anap)++ = st->log_en_index; // 6 bits + // = 35 bits + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void dtx_enc(dtx_encState *st, /* i/o : State struct */ + Word16 computeSidFlag, /* i : compute SID */ + Q_plsfState *qSt, /* i/o : Qunatizer state struct */ + gc_predState* predState, /* i/o : State struct */ + Word16 **anap, /* o : analysis parameters */ + Flag *pOverflow /* i/o : overflow indicator */ + ) +{ + register Word16 i, j; + Word16 temp; + Word16 log_en; + Word16 lsf[M]; + Word16 lsp[M]; + Word16 lsp_q[M]; + Word32 L_lsp[M]; + + /* VOX mode computation of SID parameters */ + + if ((computeSidFlag != 0) || + (st->log_en_index == 0)) + { + /* compute new SID frame if safe i.e don't + * compute immediately after a talk spurt */ + log_en = 0; + for (i = M - 1; i >= 0; i--) + { + L_lsp[i] = 0; + } + + /* average energy and lsp */ + for (i = DTX_HIST_SIZE - 1; i >= 0; i--) + { + if (st->log_en_hist[i] < 0) + { + temp = ~((~(st->log_en_hist[i])) >> 2); + } + else + { + temp = st->log_en_hist[i] >> 2; + } + log_en = add_16(log_en, temp, pOverflow); + + for (j = M - 1; j >= 0; j--) + { + L_lsp[j] = L_add(L_lsp[j], + (Word32)(st->lsp_hist[i * M + j]), + pOverflow); + } + } + + if (log_en < 0) + { + log_en = ~((~log_en) >> 1); + } + else + { + log_en = log_en >> 1; + } + + for (j = M - 1; j >= 0; j--) + { + /* divide by 8 */ + if (L_lsp[j] < 0) + { + lsp[j] = (Word16)(~((~L_lsp[j]) >> 3)); + } + else + { + lsp[j] = (Word16)(L_lsp[j] >> 3); + } + } + + /* quantize logarithmic energy to 6 bits */ + /* +2.5 in Q10 */ + st->log_en_index = log_en + 2560; + /* add 0.5/4 in Q10 */ + st->log_en_index += 128; + if (st->log_en_index < 0) + { + st->log_en_index = ~((~st->log_en_index) >> 8); + } + else + { + st->log_en_index = st->log_en_index >> 8; + } + + /*---------------------------------------------*/ + /* Limit to max and min allowable 6-bit values */ + /* Note: For assembly implementation, use the */ + /* following: */ + /* if(st->long_en_index >> 6 != 0) */ + /* { */ + /* if(st->long_en_index < 0) */ + /* { */ + /* st->long_en_index = 0 */ + /* } */ + /* else */ + /* { */ + /* st->long_en_index = 63 */ + /* } */ + /* } */ + /*---------------------------------------------*/ + if (st->log_en_index > 63) + { + st->log_en_index = 63; + } + else if (st->log_en_index < 0) + { + st->log_en_index = 0; + } + + /* update gain predictor memory */ + /* Q11 and divide by 4 */ + log_en = (Word16)(((Word32) st->log_en_index) << (-2 + 10)); + + log_en = sub(log_en, 11560, pOverflow); + + if (log_en > 0) + { + log_en = 0; + } + else if (log_en < -14436) + { + log_en = -14436; + } + + /* past_qua_en for other modes than MR122 */ + predState->past_qua_en[0] = log_en; + predState->past_qua_en[1] = log_en; + predState->past_qua_en[2] = log_en; + predState->past_qua_en[3] = log_en; + + /* scale down by factor 20*log10(2) in Q15 */ + log_en = (Word16)(((Word32)(5443 * log_en)) >> 15); + + /* past_qua_en for mode MR122 */ + predState->past_qua_en_MR122[0] = log_en; + predState->past_qua_en_MR122[1] = log_en; + predState->past_qua_en_MR122[2] = log_en; + predState->past_qua_en_MR122[3] = log_en; + + /* make sure that LSP's are ordered */ + Lsp_lsf(lsp, lsf, M, pOverflow); + Reorder_lsf(lsf, LSF_GAP, M, pOverflow); + Lsf_lsp(lsf, lsp, M, pOverflow); + + /* Quantize lsp and put on parameter list */ + Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index, + &st->init_lsf_vq_index, pOverflow); + } + + *(*anap)++ = st->init_lsf_vq_index; /* 3 bits */ + *(*anap)++ = st->lsp_index[0]; /* 8 bits */ + *(*anap)++ = st->lsp_index[1]; /* 9 bits */ + *(*anap)++ = st->lsp_index[2]; /* 9 bits */ + *(*anap)++ = st->log_en_index; /* 6 bits */ + /* = 35 bits */ + +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: dtx_buffer +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to structures of type dtx_encState + lsp_new = LSP vector whose elements are of type Word16; vector + length is M + speech = vector of speech samples of type Word16; vector length is + BFR_SIZE_GSM + + Outputs: + structure pointed to by st contains the new LSPs and logarithmic + frame energy + + Returns: + return_value = 0 (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function handles the DTX buffer. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int dtx_buffer(dtx_encState *st, // i/o : State struct + Word16 lsp_new[], // i : LSP vector + Word16 speech[] // i : speech samples +) +{ + Word16 i; + Word32 L_frame_en; + Word16 log_en_e; + Word16 log_en_m; + Word16 log_en; + + // update pointer to circular buffer + st->hist_ptr = add(st->hist_ptr, 1); + if (sub(st->hist_ptr, DTX_HIST_SIZE) == 0) + { + st->hist_ptr = 0; + } + + // copy lsp vector into buffer + Copy(lsp_new, &st->lsp_hist[st->hist_ptr * M], M); + + // compute log energy based on frame energy + L_frame_en = 0; // Q0 + for (i=0; i < L_FRAME; i++) + { + L_frame_en = L_mac(L_frame_en, speech[i], speech[i]); + } + Log2(L_frame_en, &log_en_e, &log_en_m); + + // convert exponent and mantissa to Word16 Q10 + log_en = shl(log_en_e, 10); // Q10 + log_en = add(log_en, shr(log_en_m, 15-10)); + + // divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 + log_en = sub(log_en, 8521); + + // insert into log energy buffer with division by 2 + log_en = shr(log_en, 1); + st->log_en_hist[st->hist_ptr] = log_en; // Q10 + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void dtx_buffer(dtx_encState *st, /* i/o : State struct */ + Word16 lsp_new[], /* i : LSP vector */ + Word16 speech[], /* i : speech samples */ + Flag *pOverflow /* i/o : overflow indicator */ + ) +{ + + register Word16 i; + Word32 L_frame_en; + Word32 L_temp; + Word16 log_en_e; + Word16 log_en_m; + Word16 log_en; + Word16 *p_speech = &speech[0]; + + /* update pointer to circular buffer */ + st->hist_ptr += 1; + + if (st->hist_ptr == DTX_HIST_SIZE) + { + st->hist_ptr = 0; + } + + /* copy lsp vector into buffer */ + oscl_memcpy(&st->lsp_hist[st->hist_ptr * M], lsp_new, M*sizeof(Word16)); + + /* compute log energy based on frame energy */ + L_frame_en = 0; /* Q0 */ + + for (i = L_FRAME; i != 0; i--) + { + L_frame_en += (((Word32) * p_speech) * *(p_speech)) << 1; + p_speech++; + if (L_frame_en < 0) + { + L_frame_en = MAX_32; + break; + } + } + + Log2(L_frame_en, &log_en_e, &log_en_m, pOverflow); + + /* convert exponent and mantissa to Word16 Q10 */ + /* Q10 */ + L_temp = ((Word32) log_en_e) << 10; + if (L_temp != (Word32)((Word16) L_temp)) + { + *pOverflow = 1; + log_en = (log_en_e > 0) ? MAX_16 : MIN_16; + } + else + { + log_en = (Word16) L_temp; + } + + log_en += log_en_m >> (15 - 10); + + /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */ + log_en -= 8521; + + /* insert into log energy buffer with division by 2 */ + + st->log_en_hist[st->hist_ptr] = log_en >> 1; /* Q10 */ + +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: tx_dtx_handler +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to structures of type dtx_encState + vad_flag = VAD decision flag of type Word16 + usedMode = pointer to the currently used mode of type enum Mode + + Outputs: + structure pointed to by st contains the newly calculated speech + hangover + + Returns: + compute_new_sid_possible = flag to indicate a change in the + used mode; store type is Word16 + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function adds extra speech hangover to analyze speech on the decoding + side. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 tx_dtx_handler(dtx_encState *st, // i/o : State struct + Word16 vad_flag, // i : vad decision + enum Mode *usedMode // i/o : mode changed or not + ) +{ + Word16 compute_new_sid_possible; + + // this state machine is in synch with the GSMEFR txDtx machine + st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1); + + compute_new_sid_possible = 0; + + if (vad_flag != 0) + { + st->dtxHangoverCount = DTX_HANG_CONST; + } + else + { // non-speech + if (st->dtxHangoverCount == 0) + { // out of decoder analysis hangover + st->decAnaElapsedCount = 0; + *usedMode = MRDTX; + compute_new_sid_possible = 1; + } + else + { // in possible analysis hangover + st->dtxHangoverCount = sub(st->dtxHangoverCount, 1); + + // decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH + if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount), + DTX_ELAPSED_FRAMES_THRESH) < 0) + { + *usedMode = MRDTX; + // if short time since decoder update, do not add extra HO + } + // else + // override VAD and stay in + // speech mode *usedMode + // and add extra hangover + } + } + + return compute_new_sid_possible; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 tx_dtx_handler(dtx_encState *st, /* i/o : State struct */ + Word16 vad_flag, /* i : vad decision */ + enum Mode *usedMode, /* i/o : mode changed or not */ + Flag *pOverflow /* i/o : overflow indicator */ + ) +{ + Word16 compute_new_sid_possible; + Word16 count; + + /* this state machine is in synch with the GSMEFR txDtx machine */ + st->decAnaElapsedCount = add_16(st->decAnaElapsedCount, 1, pOverflow); + + compute_new_sid_possible = 0; + + if (vad_flag != 0) + { + st->dtxHangoverCount = DTX_HANG_CONST; + } + else + { /* non-speech */ + if (st->dtxHangoverCount == 0) + { /* out of decoder analysis hangover */ + st->decAnaElapsedCount = 0; + *usedMode = MRDTX; + compute_new_sid_possible = 1; + } + else + { /* in possible analysis hangover */ + st->dtxHangoverCount -= 1; + + /* decAnaElapsedCount + dtxHangoverCount < */ + /* DTX_ELAPSED_FRAMES_THRESH */ + count = add_16(st->decAnaElapsedCount, st->dtxHangoverCount, + pOverflow); + if (count < DTX_ELAPSED_FRAMES_THRESH) + { + *usedMode = MRDTX; + /* if short time since decoder update, */ + /* do not add extra HO */ + } + } + } + + return(compute_new_sid_possible); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/dtx_enc.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/dtx_enc.h new file mode 100644 index 00000000..8142b15d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/dtx_enc.h @@ -0,0 +1,198 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dtx_enc.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : dtx_enc.h + Purpose : DTX mode computation of SID parameters + +------------------------------------------------------------------------------ +*/ + +#ifndef dtx_enc_h +#define dtx_enc_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" +#include "q_plsf.h" +#include "gc_pred.h" +#include "mode.h" +#include "dtx_common_def.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 lsp_hist[M * DTX_HIST_SIZE]; + Word16 log_en_hist[DTX_HIST_SIZE]; + Word16 hist_ptr; + Word16 log_en_index; + Word16 init_lsf_vq_index; + Word16 lsp_index[3]; + + /* DTX handler stuff */ + Word16 dtxHangoverCount; + Word16 decAnaElapsedCount; + + } dtx_encState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + /* + ************************************************************************** + * Function : dtx_enc_init + * Purpose : Allocates memory and initializes state variables + * Description : Stores pointer to filter status struct in *st. This + * pointer has to be passed to dtx_enc in each call. + * Returns : 0 on success + * + ************************************************************************** + */ + Word16 dtx_enc_init(dtx_encState **st, const Word16* lsp_init_data_ptr); + + /* + ************************************************************************** + * + * Function : dtx_enc_reset + * Purpose : Resets state memory + * Returns : 0 on success + * + ************************************************************************** + */ + Word16 dtx_enc_reset(dtx_encState *st, const Word16* lsp_init_data_ptr); + + /* + ************************************************************************** + * + * Function : dtx_enc_exit + * Purpose : The memory used for state memory is freed + * Description : Stores NULL in *st + * + ************************************************************************** + */ + void dtx_enc_exit(dtx_encState **st); + + /* + ************************************************************************** + * + * Function : dtx_enc + * Purpose : + * Description : + * + ************************************************************************** + */ + void dtx_enc(dtx_encState *st, /* i/o : State struct */ + Word16 computeSidFlag, /* i : compute SID */ + Q_plsfState *qSt, /* i/o : Qunatizer state struct */ + gc_predState* predState, /* i/o : State struct */ + Word16 **anap, /* o : analysis parameters */ + Flag *pOverflow /* i/o : overflow indicator */ + ); + + /* + ************************************************************************** + * + * Function : dtx_buffer + * Purpose : handles the DTX buffer + * + ************************************************************************** + */ + void dtx_buffer(dtx_encState *st, /* i/o : State struct */ + Word16 lsp_new[], /* i : LSP vector */ + Word16 speech[], /* i : speech samples */ + Flag *pOverflow /* i/o : overflow indicator */ + ); + + /* + ************************************************************************** + * + * Function : tx_dtx_handler + * Purpose : adds extra speech hangover to analyze speech on the decoding side. + * Description : returns 1 when a new SID analysis may be made + * otherwise it adds the appropriate hangover after a sequence + * with out updates of SID parameters . + * + ************************************************************************** + */ + Word16 tx_dtx_handler(dtx_encState *st, /* i/o : State struct */ + Word16 vad_flag, /* i : vad decision */ + enum Mode *usedMode, /* i/o : mode changed or not */ + Flag *pOverflow /* i/o : overflow indicator */ + ); + + +#ifdef __cplusplus +} +#endif + +#endif /* _dtx_enc_h_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_lag3.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_lag3.cpp new file mode 100644 index 00000000..0d604a7e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_lag3.cpp @@ -0,0 +1,321 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: enc_lag3.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "enc_lag3.h" +#include "typedef.h" +#include "basic_op.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: enc_lag3 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + T0 = Pitch delay of type Word16 + T0_frac = Fractional pitch delay of type Word16 + T0_prev = Integer pitch delay of last subframe of type Word16 + T0_min = minimum of search range of type Word16 + T0_max = maximum of search range of type Word16 + delta_flag = Flag for 1st (or 3rd) subframe of type Word16 + flag4 = Flag for encoding with 4 bits of type Word16 + pOverflow = pointer indicating overflow of type Flag + + Outputs: + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function implements the encoding of fractional pitch lag with + 1/3 resolution. + + * FUNCTION: Enc_lag3 + * + * PURPOSE: Encoding of fractional pitch lag with 1/3 resolution. + * + * DESCRIPTION: + * First and third subframes: + * -------------------------- + * The pitch range is divided as follows: + * 19 1/3 to 84 2/3 resolution 1/3 + * 85 to 143 resolution 1 + * + * The period is encoded with 8 bits. + * For the range with fractions: + * index = (T-19)*3 + frac - 1; + * where T=[19..85] and frac=[-1,0,1] + * and for the integer only range + * index = (T - 85) + 197; where T=[86..143] + * + * Second and fourth subframes: + * ---------------------------- + * For the 2nd and 4th subframes a resolution of 1/3 is always used, + * and the search range is relative to the lag in previous subframe. + * If t0 is the lag in the previous subframe then + * t_min=t0-5 and t_max=t0+4 and the range is given by + * t_min - 2/3 to t_max + 2/3 + * + * The period in the 2nd (and 4th) subframe is encoded with 5 bits: + * index = (T-(t_min-1))*3 + frac - 1; + * where T=[t_min-1..t_max+1] + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + enc_lag3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Word16 index, i, tmp_ind, uplag; + Word16 tmp_lag; + + if (delta_flag == 0) + { // if 1st or 3rd subframe + + // encode pitch delay (with fraction) + + if (sub (T0, 85) <= 0) + { + // index = T0*3 - 58 + T0_frac + i = add (add (T0, T0), T0); + index = add (sub (i, 58), T0_frac); + } + else + { + index = add (T0, 112); + } + } + else + { // if second or fourth subframe + if (flag4 == 0) { + + // 'normal' encoding: either with 5 or 6 bit resolution + + // index = 3*(T0 - T0_min) + 2 + T0_frac + i = sub (T0, T0_min); + i = add (add (i, i), i); + index = add (add (i, 2), T0_frac); + } + else { + + // encoding with 4 bit resolution + + tmp_lag = T0_prev; + + if ( sub( sub(tmp_lag, T0_min), 5) > 0) + tmp_lag = add (T0_min, 5); + if ( sub( sub(T0_max, tmp_lag), 4) > 0) + tmp_lag = sub (T0_max, 4); + + uplag = add (add (add (T0, T0), T0), T0_frac); + + i = sub (tmp_lag, 2); + tmp_ind = add (add (i, i), i); + + if (sub (tmp_ind, uplag) >= 0) { + index = add (sub (T0, tmp_lag), 5); + } + else { + + i = add (tmp_lag, 1); + i = add (add (i, i), i); + + if (sub (i, uplag) > 0) { + + index = add ( sub (uplag, tmp_ind), 3); + } + else { + + index = add (sub (T0, tmp_lag), 11); + } + } + + } // end if (encoding with 4 bit resolution) + } // end if (second of fourth subframe) + + return index; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + + +Word16 Enc_lag3( /* o : Return index of encoding */ + Word16 T0, /* i : Pitch delay */ + Word16 T0_frac, /* i : Fractional pitch delay */ + Word16 T0_prev, /* i : Integer pitch delay of last subframe */ + Word16 T0_min, /* i : minimum of search range */ + Word16 T0_max, /* i : maximum of search range */ + Word16 delta_flag, /* i : Flag for 1st (or 3rd) subframe */ + Word16 flag4, /* i : Flag for encoding with 4 bits */ + Flag *pOverflow +) +{ + Word16 index, i, tmp_ind, uplag; + Word16 tmp_lag; + Word16 temp1; + Word16 temp2; + + + + if (delta_flag == 0) + { /* if 1st or 3rd subframe */ + + /* encode pitch delay (with fraction) */ + temp1 = T0 - 85; + if (temp1 <= 0) + { + /* index = T0*3 - 58 + T0_frac */ + index = (T0 << 1) + T0 - 58 + T0_frac; + } + else + { + index = T0 + 112; + } + } + else + { /* if second or fourth subframe */ + if (flag4 == 0) + { + + /* 'normal' encoding: either with 5 or 6 bit resolution */ + + /* index = 3*(T0 - T0_min) + 2 + T0_frac */ + i = T0 - T0_min; + index = i + (i << 1) + 2 + T0_frac; + } + else + { + + /* encoding with 4 bit resolution */ + + tmp_lag = T0_prev; + temp1 = tmp_lag - T0_min; + temp2 = temp1 - 5; + if (temp2 > 0) + { + tmp_lag = T0_min + 5; + } + temp1 = T0_max - tmp_lag; + temp2 = temp1 - 4; + if (temp2 > 0) + { + tmp_lag = T0_max - 4; + } + uplag = T0 + (T0 << 1); + uplag += T0_frac; + i = tmp_lag - 2; + + tmp_ind = i + (i << 1); + temp1 = tmp_ind - uplag; + + if (temp1 >= 0) + { + index = T0 - tmp_lag + 5; + } + else + { + i = tmp_lag + 1; + + i += i << 1; + + if (i > uplag) + { + index = uplag - tmp_ind + 3; + } + else + { + index = T0 - tmp_lag + 11; + } + } + + } /* end if (encoding with 4 bit resolution) */ + } /* end if (second of fourth subframe) */ + + return index; +} + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_lag3.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_lag3.h new file mode 100644 index 00000000..b3dbaa43 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_lag3.h @@ -0,0 +1,116 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: enc_lag3.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : enc_lag3.h + Purpose : Encoding of fractional pitch lag with 1/3 resolution. + +------------------------------------------------------------------------------ +*/ + +#ifndef _ENC_LAG3_H_ +#define _ENC_LAG3_H_ +#define enc_lag3_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 past_gain; + } agcState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + Word16 + Enc_lag3( /* o : Return index of encoding */ + Word16 T0, /* i : Pitch delay */ + Word16 T0_frac, /* i : Fractional pitch delay */ + Word16 T0_prev, /* i : Integer pitch delay of last subframe */ + Word16 T0_min, /* i : minimum of search range */ + Word16 T0_max, /* i : maximum of search range */ + Word16 delta_flag, /* i : Flag for 1st (or 3rd) subframe */ + Word16 flag4, /* i : Flag for encoding with 4 bits */ + Flag *pOverflow + ); + + + + +#ifdef __cplusplus +} +#endif + +#endif /* _ENC_LAG3_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_lag6.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_lag6.cpp new file mode 100644 index 00000000..6b81ff5d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_lag6.cpp @@ -0,0 +1,193 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: enc_lag6.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "enc_lag6.h" +#include "typedef.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Enc_lag6 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + T0 -- Word16 -- Pitch delay + T0_frac -- Word16 -- Fractional pitch delay + T0_min -- Word16 -- minimum of search range + delta_flag -- Word16 -- Flag for 1st (or 3rd) subframe + + Outputs: + pOverflow -- Pointer to Flag -- overflow indicator + + Returns: + Word16 -- Return index of encoding + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Encoding of fractional pitch lag with 1/6 resolution. + + DESCRIPTION: + First and third subframes: + -------------------------- + The pitch range is divided as follows: + 17 3/6 to 94 3/6 resolution 1/6 + 95 to 143 resolution 1 + + The period is encoded with 9 bits. + For the range with fractions: + index = (T-17)*6 + frac - 3; + where T=[17..94] and frac=[-2,-1,0,1,2,3] + and for the integer only range + index = (T - 95) + 463; where T=[95..143] + + Second and fourth subframes: + ---------------------------- + For the 2nd and 4th subframes a resolution of 1/6 is always used, + and the search range is relative to the lag in previous subframe. + If t0 is the lag in the previous subframe then + t_min=t0-5 and t_max=t0+4 and the range is given by + (t_min-1) 3/6 to (t_max) 3/6 + + The period in the 2nd (and 4th) subframe is encoded with 6 bits: + index = (T-(t_min-1))*6 + frac - 3; + where T=[t_min-1..t_max] and frac=[-2,-1,0,1,2,3] + + Note that only 61 values are used. If the decoder receives 61, 62, + or 63 as the relative pitch index, it means that a transmission + error occurred and the pitch from previous subframe should be used. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + enc_lag6.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Enc_lag6( /* o : Return index of encoding */ + Word16 T0, /* i : Pitch delay */ + Word16 T0_frac, /* i : Fractional pitch delay */ + Word16 T0_min, /* i : minimum of search range */ + Word16 delta_flag, /* i : Flag for 1st (or 3rd) subframe */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + Word16 index; + Word16 i; + Word16 temp; + + if (delta_flag == 0) /* if 1st or 3rd subframe */ + { + /* encode pitch delay (with fraction) */ + if (T0 <= 94) + { + /* index = T0*6 - 105 + T0_frac */ + i = (T0 << 3) - (T0 << 1) - 105; + + index = i + T0_frac; + } + else + { + index = T0 + 368; + } + + } + else + /* if second or fourth subframe */ + { + /* index = 6*(T0-T0_min) + 3 + T0_frac */ + temp = (T0 - T0_min); + + i = (temp << 3) - (temp << 1); + i += 3; + + index = i + T0_frac; + } + + return index; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_lag6.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_lag6.h new file mode 100644 index 00000000..d9d0f5c1 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_lag6.h @@ -0,0 +1,110 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: enc_lag6.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the file, enc_lag6.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef enc_lag6_h +#define enc_lag6_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 Enc_lag6( /* o : Return index of encoding */ + Word16 T0, /* i : Pitch delay */ + Word16 T0_frac, /* i : Fractional pitch delay */ + Word16 T0_min, /* i : minimum of search range */ + Word16 delta_flag, /* i : Flag for 1st (or 3rd) subframe */ + Flag *pOverflow /* o : Overflow indicator */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* enc_lag6_h */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_output_format_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_output_format_tab.cpp new file mode 100644 index 00000000..39e81e8f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/enc_output_format_tab.cpp @@ -0,0 +1,193 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + Filename: enc_output_format_tab.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This file contains the tables of the number of data bytes per codec mode in + both WMF and IF2 output formats. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] AMR Speech Codec Frame Structure, 3GPP TS 26.101 version 4.1.0 Release 4, + June 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "amrencode.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; LOCAL STORE/BUFFER/POINTER DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + /* Number of data bytes in an encoder frame for each codec mode */ + /* for WMF output format. */ + /* Each entry is the sum of the 3GPP frame type byte and the */ + /* number of packed core AMR data bytes */ + const Word16 WmfEncBytesPerFrame[16] = + { + 13, /* 4.75 */ + 14, /* 5.15 */ + 16, /* 5.90 */ + 18, /* 6.70 */ + 20, /* 7.40 */ + 21, /* 7.95 */ + 27, /* 10.2 */ + 32, /* 12.2 */ + 6, /* GsmAmr comfort noise */ + 7, /* Gsm-Efr comfort noise */ + 6, /* IS-641 comfort noise */ + 6, /* Pdc-Efr comfort noise */ + 0, /* future use */ + 0, /* future use */ + 0, /* future use */ + 1 /* No transmission */ + }; + + + /* Number of data bytes in an encoder frame for each codec mode */ + /* for IF2 output format */ + const Word16 If2EncBytesPerFrame[16] = + { + 13, /* 4.75 */ + 14, /* 5.15 */ + 16, /* 5.90 */ + 18, /* 6.70 */ + 19, /* 7.40 */ + 21, /* 7.95 */ + 26, /* 10.2 */ + 31, /* 12.2 */ + 6, /* GsmAmr comfort noise */ + 6, /* Gsm-Efr comfort noise */ + 6, /* IS-641 comfort noise */ + 6, /* Pdc-Efr comfort noise */ + 0, /* future use */ + 0, /* future use */ + 0, /* future use */ + 1 /* No transmission */ + }; + + /*---------------------------------------------------------------------------- + ; EXTERNAL FUNCTION REFERENCES + ; Declare functions defined elsewhere and referenced in this module + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; Define all local variables +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Function body here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Return nothing or data or data pointer +----------------------------------------------------------------------------*/ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ets_to_if2.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ets_to_if2.cpp new file mode 100644 index 00000000..dc9b7aa9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ets_to_if2.cpp @@ -0,0 +1,228 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Filename: ets_to_if2.cpp + Funtions: ets_to_if2 + +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "frame_type_3gpp.h" +#include "ets_to_if2.h" +#include "typedef.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ets_to_if2 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + frame_type_3gpp = decoder speech bit rate (enum Frame_Type_3GPP) + ets_input_ptr = pointer to input encoded speech bits in ETS format (Word16) + if2_output_ptr = pointer to output encoded speech bits in IF2 format (UWord8) + + Outputs: + if2_output_ptr = pointer to encoded speech bits in the IF2 format (UWord8) + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs a transformation on the data buffers. It converts the + data format from ETS (European Telecommunication Standard) to IF2. ETS format + has the encoded speech bits each separate with only one bit stored in each + word. IF2 is the storage format where the frame type is in the first four bits + of the first byte. The upper four bits of that byte contain the first four + encoded speech bits for the frame. The following bytes contain the rest of + the encoded speech bits. The final byte has padded zeros to make the frame + byte aligned. +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + +AMR Speech Codec Frame Structure", 3GPP TS 26.101 version 4.1.0 Release 4, June 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void ets_to_if2( + enum Frame_Type_3GPP frame_type_3gpp, + Word16 *ets_input_ptr, + UWord8 *if2_output_ptr, + CommonAmrTbls* common_amr_tbls) +{ + Word16 i; + Word16 k; + Word16 j = 0; + Word16 *ptr_temp; + Word16 bits_left; + UWord8 accum; + const Word16* const* reorderBits_ptr = common_amr_tbls->reorderBits_ptr; + const Word16* numOfBits_ptr = common_amr_tbls->numOfBits_ptr; + + if (frame_type_3gpp < AMR_SID) + { + if2_output_ptr[j++] = (UWord8)(frame_type_3gpp) | + (ets_input_ptr[reorderBits_ptr[frame_type_3gpp][0]] << 4) | + (ets_input_ptr[reorderBits_ptr[frame_type_3gpp][1]] << 5) | + (ets_input_ptr[reorderBits_ptr[frame_type_3gpp][2]] << 6) | + (ets_input_ptr[reorderBits_ptr[frame_type_3gpp][3]] << 7); + + for (i = 4; i < numOfBits_ptr[frame_type_3gpp] - 7;) + { + if2_output_ptr[j] = + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]]; + if2_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 1; + if2_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 2; + if2_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 3; + if2_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 4; + if2_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 5; + if2_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 6; + if2_output_ptr[j++] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 7; + } + + bits_left = 4 + numOfBits_ptr[frame_type_3gpp] - + ((4 + numOfBits_ptr[frame_type_3gpp]) & 0xFFF8); + + if (bits_left != 0) + { + if2_output_ptr[j] = 0; + + for (k = 0; k < bits_left; k++) + { + if2_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << k; + } + } + } + else + { + if (frame_type_3gpp != AMR_NO_DATA) + { + /* First octet contains 3GPP frame type and */ + /* first 4 bits of encoded parameters */ + if2_output_ptr[j++] = (UWord8)(frame_type_3gpp) | + (ets_input_ptr[0] << 4) | (ets_input_ptr[1] << 5) | + (ets_input_ptr[2] << 6) | (ets_input_ptr[3] << 7); + ptr_temp = &ets_input_ptr[4]; + + bits_left = ((4 + numOfBits_ptr[frame_type_3gpp]) & 0xFFF8); + + for (i = (bits_left - 7) >> 3; i > 0; i--) + { + accum = (UWord8) * (ptr_temp++); + accum |= (UWord8) * (ptr_temp++) << 1; + accum |= (UWord8) * (ptr_temp++) << 2; + accum |= (UWord8) * (ptr_temp++) << 3; + accum |= (UWord8) * (ptr_temp++) << 4; + accum |= (UWord8) * (ptr_temp++) << 5; + accum |= (UWord8) * (ptr_temp++) << 6; + accum |= (UWord8) * (ptr_temp++) << 7; + + if2_output_ptr[j++] = accum; + } + + bits_left = 4 + numOfBits_ptr[frame_type_3gpp] - bits_left; + + if (bits_left != 0) + { + if2_output_ptr[j] = 0; + + for (i = 0; i < bits_left; i++) + { + if2_output_ptr[j] |= (ptr_temp[i] << i); + } + } + } + else + { + /* When there is no data, LSnibble of first octet */ + /* is the 3GPP frame type, MSnibble is zeroed out */ + if2_output_ptr[j++] = (UWord8)(frame_type_3gpp); + } + + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ets_to_if2.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ets_to_if2.h new file mode 100644 index 00000000..cbdfde58 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ets_to_if2.h @@ -0,0 +1,111 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: ets_to_if2.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the ets_to_if2 function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef ETS_TO_IF2_H +#define ETS_TO_IF2_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "mode.h" +#include "typedef.h" +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void ets_to_if2(enum Frame_Type_3GPP mode, + Word16 *ets_input_ptr, + UWord8 *if2_output_ptr, + CommonAmrTbls* common_amr_tbls); + + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ets_to_wmf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ets_to_wmf.cpp new file mode 100644 index 00000000..76634b09 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ets_to_wmf.cpp @@ -0,0 +1,300 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: ets_to_wmf.cpp + Functions: ets_to_wmf + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "ets_to_wmf.h" +#include "typedef.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ets_to_wmf +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + frame_type_3gpp = decoder speech bit rate (enum Frame_Type_3GPP) + ets_input_ptr = pointer to input encoded speech bits in ETS format (Word16) + wmf_output_ptr = pointer to output encoded speech bits in WMF format(UWord8) + + Outputs: + wmf_output_ptr = pointer to encoded speech bits in the WMF format (UWord8) + + Returns: + None + + Global Variables Used: + numOfBits = table of values that describe the number of bits per frame for + each 3GPP frame type mode. The table is type const Word16 and has + NUM_MODES elements. This table is located in bitreorder_tab.c. + reorderBits = table of pointers that point to tables used to reorder the + encoded speech bits when converting from ETS to WMF or IF2 + format. The table is of type const Word16 * and contains + NUM_MODES-1 elements. This table is located in bitreorder_tab.c. + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs a transformation on the data buffers. It converts the + data format from ETS (European Telecommunication Standard) to WMF (wireless + multimedia forum). ETS format has the encoded speech bits each separate with + only one bit stored in each word. WMF is the storage format where the frame + type is in the first four bits of the first byte. This first byte has the + upper four bits as padded zeroes. The following bytes contain the rest of the + encoded speech bits. The final byte has padded zeros to make the frame byte + aligned. +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void ets_to_wmf( + enum Frame_Type_3GPP frame_type_3gpp, + Word16 *ets_input_ptr, + UWord8 *wmf_output_ptr, + CommonAmrTbls* common_amr_tbls) +{ + Word16 i; + Word16 k = 0; + Word16 j = 0; + Word16 *ptr_temp; + Word16 bits_left; + UWord8 accum; + const Word16* const* reorderBits_ptr = common_amr_tbls->reorderBits_ptr; + const Word16* numOfBits_ptr = common_amr_tbls->numOfBits_ptr; + + wmf_output_ptr[j++] = (UWord8)(frame_type_3gpp) & 0x0f; + + if (frame_type_3gpp < AMR_SID) + { + + for (i = 0; i < numOfBits_ptr[frame_type_3gpp] - 7;) + { + wmf_output_ptr[j] = + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 7; + wmf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 6; + wmf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 5; + wmf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 4; + wmf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 3; + wmf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 2; + wmf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 1; + wmf_output_ptr[j++] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]]; + } + + bits_left = numOfBits_ptr[frame_type_3gpp] - + (numOfBits_ptr[frame_type_3gpp] & 0xFFF8); + + wmf_output_ptr[j] = 0; + + for (k = 0; k < bits_left; k++) + { + wmf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << (7 - k); + + } + } + else + { + + ptr_temp = &ets_input_ptr[0]; + + for (i = numOfBits_ptr[frame_type_3gpp] - 7; i > 0; i -= 8) + { + accum = (UWord8) * (ptr_temp++) << 7; + accum |= (UWord8) * (ptr_temp++) << 6; + accum |= (UWord8) * (ptr_temp++) << 5; + accum |= (UWord8) * (ptr_temp++) << 4; + accum |= (UWord8) * (ptr_temp++) << 3; + accum |= (UWord8) * (ptr_temp++) << 2; + accum |= (UWord8) * (ptr_temp++) << 1; + accum |= (UWord8) * (ptr_temp++); + + wmf_output_ptr[j++] = accum; + } + + bits_left = numOfBits_ptr[frame_type_3gpp] - + (numOfBits_ptr[frame_type_3gpp] & 0xFFF8); + + wmf_output_ptr[j] = 0; + + for (i = 0; i < bits_left; i++) + { + wmf_output_ptr[j] |= *(ptr_temp++) << (7 - i); + } + } + + return; +} + + + +void ets_to_ietf( + enum Frame_Type_3GPP frame_type_3gpp, + Word16 *ets_input_ptr, + UWord8 *ietf_output_ptr, + CommonAmrTbls* common_amr_tbls) +{ + Word16 i; + Word16 k = 0; + Word16 j = 0; + Word16 *ptr_temp; + Word16 bits_left; + UWord8 accum; + const Word16* const* reorderBits_ptr = common_amr_tbls->reorderBits_ptr; + const Word16* numOfBits_ptr = common_amr_tbls->numOfBits_ptr; + + ietf_output_ptr[j++] = (UWord8)(frame_type_3gpp << 3); + + if (frame_type_3gpp < AMR_SID) + { + for (i = 0; i < numOfBits_ptr[frame_type_3gpp] - 7;) + { + ietf_output_ptr[j] = + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 7; + ietf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 6; + ietf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 5; + ietf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 4; + ietf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 3; + ietf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 2; + ietf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << 1; + ietf_output_ptr[j++] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]]; + } + + bits_left = numOfBits_ptr[frame_type_3gpp] - + (numOfBits_ptr[frame_type_3gpp] & 0xFFF8); + + ietf_output_ptr[j] = 0; + + for (k = 0; k < bits_left; k++) + { + ietf_output_ptr[j] |= + (UWord8) ets_input_ptr[reorderBits_ptr[frame_type_3gpp][i++]] << (7 - k); + + } + } + else + { + + ptr_temp = &ets_input_ptr[0]; + + for (i = numOfBits_ptr[frame_type_3gpp] - 7; i > 0; i -= 8) + { + accum = (UWord8) * (ptr_temp++) << 7; + accum |= (UWord8) * (ptr_temp++) << 6; + accum |= (UWord8) * (ptr_temp++) << 5; + accum |= (UWord8) * (ptr_temp++) << 4; + accum |= (UWord8) * (ptr_temp++) << 3; + accum |= (UWord8) * (ptr_temp++) << 2; + accum |= (UWord8) * (ptr_temp++) << 1; + accum |= (UWord8) * (ptr_temp++); + + ietf_output_ptr[j++] = accum; + } + + bits_left = numOfBits_ptr[frame_type_3gpp] - + (numOfBits_ptr[frame_type_3gpp] & 0xFFF8); + + ietf_output_ptr[j] = 0; + + for (i = 0; i < bits_left; i++) + { + ietf_output_ptr[j] |= *(ptr_temp++) << (7 - i); + } + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ets_to_wmf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ets_to_wmf.h new file mode 100644 index 00000000..c26ca30a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ets_to_wmf.h @@ -0,0 +1,115 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: ets_to_wmf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the ets_to_wmf function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef ETS_TO_WMF_H +#define ETS_TO_WMF_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "frame_type_3gpp.h" +#include "typedef.h" +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void ets_to_wmf(enum Frame_Type_3GPP frame_type_3gpp, + Word16 *ets_input_ptr, + UWord8 *wmf_output_ptr, + CommonAmrTbls* common_amr_tbls); + + void ets_to_ietf(enum Frame_Type_3GPP frame_type_3gpp, + Word16 *ets_input_ptr, + UWord8 *ietf_output_ptr, + CommonAmrTbls* common_amr_tbls); + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_adapt.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_adapt.cpp new file mode 100644 index 00000000..9d8e6706 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_adapt.cpp @@ -0,0 +1,442 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: g_adapt.cpp + Functions: + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "g_adapt.h" +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" +#include "cnst.h" +#include "gmed_n.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define LTP_GAIN_THR1 2721 /* 2721 Q13 = 0.3322 ~= 1.0 / (10*log10(2)) */ +#define LTP_GAIN_THR2 5443 /* 5443 Q13 = 0.6644 ~= 2.0 / (10*log10(2)) */ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gain_adapt_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- double pointer to GainAdaptState + + Outputs: + st -- double ponter to GainAdaptState + + Returns: + -1 if an error occurs during memory initialization + 0 if OK + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Allocates state memory and initializes state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 gain_adapt_init(GainAdaptState **st) +{ + GainAdaptState* s; + + if (st == (GainAdaptState **) NULL) + { + /* fprintf(stderr, "gain_adapt_init: invalid parameter\n"); */ + return -1; + } + *st = NULL; + + /* allocate memory */ + if ((s = (GainAdaptState *) oscl_malloc(sizeof(GainAdaptState))) == NULL) + { + /* fprintf(stderr, "gain_adapt_init: can't malloc state structure\n"); */ + return -1; + } + gain_adapt_reset(s); + *st = s; + + return 0; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gain_adapt_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- double pointer to GainAdaptState + + Outputs: + st -- double ponter to GainAdaptState + + Returns: + -1 if an error occurs + 0 if OK + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Initializes state memory to zero +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 gain_adapt_reset(GainAdaptState *st) +{ + Word16 i; + + if (st == (GainAdaptState *) NULL) + { + /* fprintf(stderr, "gain_adapt_reset: invalid parameter\n"); */ + return -1; + } + + st->onset = 0; + st->prev_alpha = 0; + st->prev_gc = 0; + + for (i = 0; i < LTPG_MEM_SIZE; i++) + { + st->ltpg_mem[i] = 0; + } + + return 0; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gain_adapt_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- double pointer to GainAdaptState + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + The memory used for state memory is freed +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void gain_adapt_exit(GainAdaptState **st) +{ + if (st == NULL || *st == NULL) + return; + + /* deallocate memory */ + oscl_free(*st); + *st = NULL; + + return; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gain_adapt +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- double pointer to GainAdaptState + ltpg -- Word16 -- ltp coding gain (log2()), Q13 + gain_cod -- Word16 -- code gain, Q1 + + Outputs: + alpha -- Pointer to Word16 -- gain adaptation factor, Q15 + pOverflow -- Pointer to Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose: calculate pitch/codebook gain adaptation factor alpha + (and update the adaptor state) + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void gain_adapt( + GainAdaptState *st, /* i : state struct */ + Word16 ltpg, /* i : ltp coding gain (log2()), Q13 */ + Word16 gain_cod, /* i : code gain, Q1 */ + Word16 *alpha, /* o : gain adaptation factor, Q15 */ + Flag *pOverflow +) +{ + Word16 adapt; /* adaptdation status; 0, 1, or 2 */ + Word16 result; /* alpha factor, Q13 */ + Word16 filt; /* median-filtered LTP coding gain, Q13 */ + Word16 tmp; + Word16 i; + + /* basic adaptation */ + if (ltpg <= LTP_GAIN_THR1) + { + adapt = 0; + } + else + { + if (ltpg <= LTP_GAIN_THR2) + { + adapt = 1; + } + else + { + adapt = 2; + } + } + + /* + * // onset indicator + * if ((cbGain > onFact * cbGainMem[0]) && (cbGain > 100.0)) + * onset = 8; + * else + * if (onset) + * onset--; + */ + /* tmp = cbGain / onFact; onFact = 2.0; 200 Q1 = 100.0 */ + tmp = shr_r(gain_cod, 1, pOverflow); + + if ((tmp > st->prev_gc) && (gain_cod > 200)) + { + st->onset = 8; + } + else + { + if (st->onset != 0) + { + st->onset--; + } + } + + /* + * // if onset, increase adaptor state + * if (onset && (gainAdapt < 2)) gainAdapt++; + */ + if ((st->onset != 0) && (adapt < 2)) + { + adapt += 1; + } + + st->ltpg_mem[0] = ltpg; + filt = gmed_n(st->ltpg_mem, 5); /* function result */ + + if (adapt == 0) + { + if (filt > 5443) /* 5443 Q13 = 0.66443... */ + { + result = 0; + } + else + { + if (filt < 0) + { + result = 16384; /* 16384 Q15 = 0.5 */ + } + else + { /* result = 0.5 - 0.75257499*filt */ + /* result (Q15) = 16384 - 24660 * (filt << 2) */ + filt = shl(filt, 2, pOverflow); /* Q15 */ + result = mult(24660, filt, pOverflow); + result = 16384 - result; + } + } + } + else + { + result = 0; + } + /* + * if (prevAlpha == 0.0) result = 0.5 * (result + prevAlpha); + */ + if (st->prev_alpha == 0) + { + result = shr(result, 1, pOverflow); + } + + /* store the result */ + *alpha = result; + + /* update adapter state memory */ + st->prev_alpha = result; + st->prev_gc = gain_cod; + + for (i = LTPG_MEM_SIZE - 1; i > 0; i--) + { + st->ltpg_mem[i] = st->ltpg_mem[i-1]; + } + /* mem[0] is just present for convenience in calling the gmed_n[5] + * function above. The memory depth is really LTPG_MEM_SIZE-1. + */ +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_adapt.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_adapt.h new file mode 100644 index 00000000..f63d41ed --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_adapt.h @@ -0,0 +1,145 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: g_adapt.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the file, g_adapt.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef g_adapt_h +#define g_adapt_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ +#define LTPG_MEM_SIZE 5 /* number of stored past LTP coding gains + 1 */ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 onset; /* onset state, Q0 */ + Word16 prev_alpha; /* previous adaptor output, Q15 */ + Word16 prev_gc; /* previous code gain, Q1 */ + + Word16 ltpg_mem[LTPG_MEM_SIZE]; /* LTP coding gain history, Q13 */ + /* (ltpg_mem[0] not used for history) */ + } GainAdaptState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 gain_adapt_init(GainAdaptState **st); + /* initialize one instance of the gain adaptor + Stores pointer to state struct in *st. This pointer has to + be passed to gain_adapt and gain_adapt_update in each call. + returns 0 on success + */ + + Word16 gain_adapt_reset(GainAdaptState *st); + /* reset of gain adaptor state (i.e. set state memory to zero) + returns 0 on success + */ + + void gain_adapt_exit(GainAdaptState **st); + /* de-initialize gain adaptor state (i.e. free state struct) + stores NULL in *st + */ + + /************************************************************************* + * + * Function: gain_adapt() + * Purpose: calculate pitch/codebook gain adaptation factor alpha + * (and update the adaptor state) + * + ************************************************************************** + */ + void gain_adapt( + GainAdaptState *st, /* i : state struct */ + Word16 ltpg, /* i : ltp coding gain (log2()), Q */ + Word16 gain_cod, /* i : code gain, Q13 */ + Word16 *alpha, /* o : gain adaptation factor, Q15 */ + Flag *pOverflow /* o : overflow indicator */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_code.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_code.cpp new file mode 100644 index 00000000..595935c3 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_code.cpp @@ -0,0 +1,277 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: g_code.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "g_code.h" +#include "cnst.h" +#include "basic_op.h" +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: G_code +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + xn2[] = target vector (Word16) + y2[] = filtered innovation vector + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the innovative gain calculation resulted in overflow + + Returns: + gain = Gain of Innovation code (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes the innovative codebook gain. + + The innovative codebook gain is given by + g = / + + where x[] is the target vector, y[] is the filtered innovative codevector, + and <> denotes dot product. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] g_code.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 G_code ( // out : Gain of innovation code + Word16 xn2[], // in : target vector + Word16 y2[] // in : filtered innovation vector +) +{ + Word16 i; + Word16 xy, yy, exp_xy, exp_yy, gain; + Word16 scal_y2[L_SUBFR]; + Word32 s; + +// The original ETSI implementation uses a global overflow flag. However in +// actual implementation a pointer to Overflow flag is passed into the +// function for access by the low level math functions. + + // Scale down Y[] by 2 to avoid overflow + + for (i = 0; i < L_SUBFR; i++) + { + scal_y2[i] = shr (y2[i], 1); + } + + // Compute scalar product + + s = 1L; // Avoid case of all zeros + for (i = 0; i < L_SUBFR; i++) + { + s = L_mac (s, xn2[i], scal_y2[i]); + } + exp_xy = norm_l (s); + xy = extract_h (L_shl (s, exp_xy)); + + // If (xy < 0) gain = 0 + + if (xy <= 0) + return ((Word16) 0); + + // Compute scalar product + + s = 0L; + for (i = 0; i < L_SUBFR; i++) + { + s = L_mac (s, scal_y2[i], scal_y2[i]); + } + exp_yy = norm_l (s); + yy = extract_h (L_shl (s, exp_yy)); + + // compute gain = xy/yy + + xy = shr (xy, 1); // Be sure xy < yy + gain = div_s (xy, yy); + + // Denormalization of division + i = add (exp_xy, 5); // 15-1+9-18 = 5 + i = sub (i, exp_yy); + + gain = shl (shr (gain, i), 1); // Q0 -> Q1/ + + return (gain); +} + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word16 G_code( /* o : Gain of innovation code */ + Word16 xn2[], /* i : target vector */ + Word16 y2[], /* i : filtered innovation vector */ + Flag *pOverflow /* i/o : overflow flag */ +) +{ + Word16 i; + Word16 xy, yy, exp_xy, exp_yy, gain; + Word32 s; + + Word16 *p_xn2 = xn2; + Word16 *p_y2 = y2; + Word16 temp; + Word32 temp2; + + OSCL_UNUSED_ARG(pOverflow); + + /* Compute scalar product */ + s = 0; + + for (i = (L_SUBFR >> 2); i != 0 ; i--) + { + temp2 = (Word32)(*(p_y2++) >> 1); + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn2++), temp2, s); + temp2 = (Word32)(*(p_y2++) >> 1); + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn2++), temp2, s); + temp2 = (Word32)(*(p_y2++) >> 1); + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn2++), temp2, s); + temp2 = (Word32)(*(p_y2++) >> 1); + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn2++), temp2, s); + } + s <<= 1; + exp_xy = norm_l(s + 1); /* Avoid case of all zeros, add 1 */ + + if (exp_xy < 17) /* extra right shift to be sure xy < yy */ + { + xy = (Word16)(s >> (17 - exp_xy)); + } + else + { + xy = (Word16)(s << (exp_xy - 17)); + } + + /* If (xy < 0) gain = 0 */ + + if (xy <= 0) + { + return ((Word16) 0); + } + + /* Compute scalar product */ + + s = 0L; + p_y2 = y2; + + for (i = (L_SUBFR >> 1); i != 0 ; i--) + { + temp = *(p_y2++) >> 1; + s += ((Word32) temp * temp) >> 2; + temp = *(p_y2++) >> 1; + s += ((Word32) temp * temp) >> 2; + } + s <<= 3; + exp_yy = norm_l(s); + + if (exp_yy < 16) + { + yy = (Word16)(s >> (16 - exp_yy)); + } + else + { + yy = (Word16)(s << (exp_yy - 16)); + } + + gain = div_s(xy, yy); + + /* Denormalization of division */ + i = exp_xy + 5; /* 15-1+9-18 = 5 */ + i -= exp_yy; + + // gain = shl (shr (gain, i), 1); /* Q0 -> Q1 */ + + if (i > 1) + { + gain >>= i - 1; + } + else + { + gain <<= 1 - i; + } + + + return (gain); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_code.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_code.h new file mode 100644 index 00000000..e7b8407c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_code.h @@ -0,0 +1,104 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: g_code.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the G_code() function. + +------------------------------------------------------------------------------ +*/ + +#ifndef G_CODE_H +#define G_CODE_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 G_code( /* o : Gain of innovation code */ + Word16 xn2[], /* i : target vector */ + Word16 y2[], /* i : filtered innovation vector */ + Flag *pOverflow /* i/o : overflow flag */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _G_CODE_H */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_pitch.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_pitch.cpp new file mode 100644 index 00000000..325e29b6 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_pitch.cpp @@ -0,0 +1,412 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: g_pitch.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "g_pitch.h" +#include "mode.h" +#include "cnst.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: G_pitch +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + mode = AMR mode (enum Mode) + xn = pointer to pitch target buffer (Word16) + y1 = pointer to filtered adaptive codebook buffer (Word16) + g_coeff = pointer to buffer of correlations needed for gain quantization + (Word16) + L_subfr = length of subframe (Word16) + pOverflow = pointer to overflow flag (Flag) + + Outputs: + g_coeff contains the mantissa and exponent of the two dot products. + pOverflow -> 1 if an overflow occurs + + Returns: + gain = ratio of dot products.(Word16) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes the pitch (adaptive codebook) gain. The adaptive + codebook gain is given by + + g = / + + where: x[] is the target vector + y[] is the filtered adaptive codevector + <> denotes dot product. + + The gain is limited to the range [0,1.2] (=0..19661 Q14) + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + g_pitch.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 G_pitch ( // o : Gain of pitch lag saturated to 1.2 + enum Mode mode, // i : AMR mode + Word16 xn[], // i : Pitch target. + Word16 y1[], // i : Filtered adaptive codebook. + Word16 g_coeff[], // i : Correlations need for gain quantization + Word16 L_subfr // i : Length of subframe. +) +{ + Word16 i; + Word16 xy, yy, exp_xy, exp_yy, gain; + Word32 s; + + Word16 scaled_y1[L_SUBFR]; // Usually dynamic allocation of (L_subfr) + + // divide "y1[]" by 4 to avoid overflow + +// The reference ETSI code uses a global overflow Flag. However in the actual +// implementation a pointer to the overflow flag is passed into the function. + + for (i = 0; i < L_subfr; i++) + { + scaled_y1[i] = shr (y1[i], 2); + } + + // Compute scalar product + + // Q12 scaling / MR122 + Overflow = 0; + s = 1L; // Avoid case of all zeros + for (i = 0; i < L_subfr; i++) + { + s = L_mac (s, y1[i], y1[i]); + } + if (Overflow == 0) // Test for overflow + { + exp_yy = norm_l (s); + yy = pv_round (L_shl (s, exp_yy)); + } + else + { + s = 1L; // Avoid case of all zeros + for (i = 0; i < L_subfr; i++) + { + s = L_mac (s, scaled_y1[i], scaled_y1[i]); + } + exp_yy = norm_l (s); + yy = pv_round (L_shl (s, exp_yy)); + exp_yy = sub (exp_yy, 4); + } + + // Compute scalar product + + Overflow = 0; + s = 1L; // Avoid case of all zeros + + for (i = 0; i < L_subfr; i++) + { + s = L_mac(s, xn[i], y1[i]); + } + if (Overflow == 0) + { + exp_xy = norm_l (s); + xy = pv_round (L_shl (s, exp_xy)); + } + else + { + s = 1L; // Avoid case of all zeros + for (i = 0; i < L_subfr; i++) + { + s = L_mac (s, xn[i], scaled_y1[i]); + } + exp_xy = norm_l (s); + xy = pv_round (L_shl (s, exp_xy)); + exp_xy = sub (exp_xy, 2); + } + + g_coeff[0] = yy; + g_coeff[1] = sub (15, exp_yy); + g_coeff[2] = xy; + g_coeff[3] = sub (15, exp_xy); + + // If (xy < 4) gain = 0 + + i = sub (xy, 4); + + if (i < 0) + return ((Word16) 0); + + // compute gain = xy/yy + + xy = shr (xy, 1); // Be sure xy < yy + gain = div_s (xy, yy); + + i = sub (exp_xy, exp_yy); // Denormalization of division + gain = shr (gain, i); + + // if(gain >1.2) gain = 1.2 + + if (sub (gain, 19661) > 0) + { + gain = 19661; + } + + if (sub(mode, MR122) == 0) + { + // clear 2 LSBits + gain = gain & 0xfffC; + } + + return (gain); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 G_pitch( /* o : Gain of pitch lag saturated to 1.2 */ + enum Mode mode, /* i : AMR mode */ + Word16 xn[], /* i : Pitch target. Q0 */ + Word16 y1[], /* i : Filtered adaptive codebook. Q12 */ + Word16 g_coeff[], /* i : Correlations need for gain quantization */ + Word16 L_subfr, /* i : Length of subframe. */ + Flag *pOverflow /* i/o : Overflow flag */ +) +{ + + Word16 i; + Word16 xy; + Word16 yy; + Word16 exp_xy; + Word16 exp_yy; + Word16 gain; + Word16 tmp; + Word32 s; + Word32 s1; + Word32 L_temp; /* Use this as an intermediate value */ + Word16 *p_xn = &xn[0]; + Word16 *p_y1 = &y1[0]; + + /* Compute scalar product */ + + /* Q12 scaling / MR122 */ + *pOverflow = 0; + s = 0; + + for (i = L_subfr >> 2; i != 0; i--) + { + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y1), (Word32) * (p_y1), s); + p_y1++; + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y1), (Word32) * (p_y1), s); + p_y1++; + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y1), (Word32) * (p_y1), s); + p_y1++; + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y1), (Word32) * (p_y1), s); + p_y1++; + } + if ((s >= 0) & (s < 0x40000000)) + { + s <<= 1; + s += 1; /* Avoid case of all zeros */ + + exp_yy = norm_l(s); /* Note 0<=exp_yy <= 31 */ + L_temp = s << exp_yy; + yy = pv_round(L_temp, pOverflow); + } + else + { + s = 0; /* Avoid case of all zeros */ + p_y1 = &y1[0]; + for (i = (L_subfr >> 1); i != 0; i--) + { + tmp = *(p_y1++) >> 2; + s = amrnb_fxp_mac_16_by_16bb((Word32) tmp, (Word32) tmp, s); + tmp = *(p_y1++) >> 2; + s = amrnb_fxp_mac_16_by_16bb((Word32) tmp, (Word32) tmp, s); + } + + s <<= 1; + s += 1; /* Avoid case of all zeros */ + + exp_yy = norm_l(s); + L_temp = s << exp_yy; + yy = pv_round(L_temp, pOverflow); + exp_yy = exp_yy - 4; + + } + + /* Compute scalar product */ + + s = 0; + p_y1 = &y1[0]; + *pOverflow = 0; + + for (i = L_subfr; i != 0; i--) + { + L_temp = ((Word32) * (p_xn++) * *(p_y1++)); + s1 = s; + s = s1 + L_temp; + + if ((s1 ^ L_temp) > 0) + { + if ((s1 ^ s) < 0) + { + *pOverflow = 1; + break; + } + } + } + + if (!(*pOverflow)) + { + + s <<= 1; + s += 1; /* Avoid case of all zeros */ + + exp_xy = norm_l(s); /* Note 0<=exp_yy <= 31 */ + L_temp = s << exp_xy; + xy = pv_round(L_temp, pOverflow); + } + else + { + s = 0; /* re-initialize calculations */ + p_y1 = &y1[0]; + p_xn = &xn[0]; + + for (i = (L_subfr >> 2); i != 0; i--) + { + L_temp = (Word32)(*(p_y1++) >> 2); + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn++), L_temp, s); + L_temp = (Word32)(*(p_y1++) >> 2); + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn++), L_temp, s); + L_temp = (Word32)(*(p_y1++) >> 2); + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn++), L_temp, s); + L_temp = (Word32)(*(p_y1++) >> 2); + s = amrnb_fxp_mac_16_by_16bb((Word32) * (p_xn++), L_temp, s); + } + + s <<= 1; + s += 1; /* Avoid case of all zeros */ + + exp_xy = norm_l(s); + L_temp = s << exp_xy; + xy = pv_round(L_temp, pOverflow); + exp_xy = exp_xy - 4; + + } + + g_coeff[0] = yy; + g_coeff[1] = 15 - exp_yy; + g_coeff[2] = xy; + g_coeff[3] = 15 - exp_xy; + + /* If (xy < 4) gain = 0 */ + if (xy < 4) + { + return ((Word16) 0); + } + + /* compute gain = xy/yy */ + /* Be sure xy < yy */ + + xy = xy >> 1; + + gain = div_s(xy, yy); + + i = exp_xy - exp_yy; /* Denormalization of division */ + + gain = shr(gain, i, pOverflow); + + + /* if(gain >1.2) gain = 1.2 */ + if (gain > 19661) + { + gain = 19661; + } + + if (mode == MR122) + { + /* clear 2 LSBits */ + gain = gain & 0xfffC; + } + + return(gain); + +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_pitch.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_pitch.h new file mode 100644 index 00000000..fb33f667 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/g_pitch.h @@ -0,0 +1,108 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: g_pitch.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the G_pitch() function. + +------------------------------------------------------------------------------ +*/ + +#ifndef G_PITCH_H +#define G_PITCH_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "mode.h" +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 G_pitch( /* o : Gain of pitch lag saturated to 1.2 */ + enum Mode mode, /* i : AMR mode */ + Word16 xn[], /* i : Pitch target. */ + Word16 y1[], /* i : Filtered adaptive codebook. */ + Word16 g_coeff[], /* i : Correlations need for gain quantization */ + Word16 L_subfr, /* i : Length of subframe. */ + Flag *pOverflow /* i/o : Overflow flag */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _G_PITCH_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/gain_q.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/gain_q.cpp new file mode 100644 index 00000000..b9b191b5 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/gain_q.cpp @@ -0,0 +1,658 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: gain_q.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Quantazation of gains +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "gain_q.h" +#include "typedef.h" +#include "basic_op.h" +#include "qua_gain.h" +#include "cnst.h" +#include "mode.h" +#include "g_code.h" +#include "q_gain_c.h" +#include "calc_en.h" +#include "qgain795.h" +#include "qgain475.h" +#include "set_zero.h" +#include "oscl_mem.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define NPRED 4 /* number of prediction taps */ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gainQuant_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- double pointer to gainQuantState + + Outputs: + st -- double ponter to gainQuantState + + Returns: + -1 if an error occurs during memory initialization + 0 if OK + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Allocates state memory and initializes state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 gainQuant_init(gainQuantState **state) +{ + gainQuantState* s; + + if (state == (gainQuantState **) NULL) + { + /* fprintf(stderr, "gainQuant_init: invalid parameter\n"); */ + return -1; + } + *state = NULL; + + /* allocate memory */ + if ((s = (gainQuantState *) oscl_malloc(sizeof(gainQuantState))) == NULL) + { + /* fprintf(stderr, "gainQuant_init: can not malloc state structure\n"); */ + return -1; + } + + s->gain_idx_ptr = NULL; + + s->adaptSt = NULL; + + /* Init sub states */ + if (gc_pred_reset(&s->gc_predSt) + || gc_pred_reset(&s->gc_predUnqSt) + || gain_adapt_init(&s->adaptSt)) + { + gainQuant_exit(&s); + return -1; + } + + gainQuant_reset(s); + *state = s; + + return 0; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gainQuant_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- double pointer to gainQuantState + + Outputs: + st -- double ponter to gainQuantState + + Returns: + -1 if an error occurs + 0 if OK + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Initializes state memory to zero +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 gainQuant_reset(gainQuantState *state) +{ + + if (state == (gainQuantState *) NULL) + { + /* fprintf(stderr, "gainQuant_reset: invalid parameter\n"); */ + return -1; + } + + state->sf0_exp_gcode0 = 0; + state->sf0_frac_gcode0 = 0; + state->sf0_exp_target_en = 0; + state->sf0_frac_target_en = 0; + + + oscl_memset((void *)state->sf0_exp_coeff, 0, 5*sizeof(*state->sf0_exp_coeff)); + oscl_memset((void *)state->sf0_frac_coeff, 0, 5*sizeof(*state->sf0_frac_coeff)); + + state->gain_idx_ptr = NULL; + + gc_pred_reset(&(state->gc_predSt)); + gc_pred_reset(&(state->gc_predUnqSt)); + gain_adapt_reset(state->adaptSt); + + return 0; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gainQuant_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- double pointer to gainQuantState + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + The memory used for state memory is freed +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void gainQuant_exit(gainQuantState **state) +{ + if (state == NULL || *state == NULL) + return; + + gain_adapt_exit(&(*state)->adaptSt); + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: gainQuant +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to gainQuantState + mode -- enum Mode -- coder mode + res -- Word16 array -- LP residual, Q0 + exc -- Word16 array -- LTP excitation (unfiltered), Q0 + code -- Word16 array -- CB innovation (unfiltered), Q13 + (unsharpened for MR475) + xn -- Word16 array -- Target vector. + xn2 -- Word16 array -- Target vector. + y1 -- Word16 array -- Adaptive codebook. + Y2 -- Word16 array -- Filtered innovative vector. + g_coeff -- Word16 array -- Correlations + Compute in G_pitch(). + + even_subframe -- Word16 -- even subframe indicator flag + gp_limit -- Word16 -- pitch gain limit + gain_pit -- Word16 Pointer -- Pitch gain. + + Outputs: + st -- pointer to gainQuantState + sf0_gain_pit -- Word16 Pointer -- Pitch gain sf 0. MR475 + sf0_gain_cod -- Word16 Pointer -- Code gain sf 0. MR475 + gain_pit -- Word16 Pointer -- Pitch gain. + gain_cod -- Word16 Pointer -- Code gain. + MR475: gain_* unquantized in even + subframes, quantized otherwise + + anap -- Word16 Double Pointer -- Index of quantization + + pOverflow -- Flag Pointer -- overflow indicator + + Returns: + Zero + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Quantazation of gains + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + + + +void gainQuant( + gainQuantState *st, /* i/o : State struct */ + enum Mode mode, /* i : coder mode */ + Word16 res[], /* i : LP residual, Q0 */ + Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ + Word16 code[], /* i : CB innovation (unfiltered), Q13 */ + /* (unsharpened for MR475) */ + Word16 xn[], /* i : Target vector. */ + Word16 xn2[], /* i : Target vector. */ + Word16 y1[], /* i : Adaptive codebook. */ + Word16 Y2[], /* i : Filtered innovative vector. */ + Word16 g_coeff[], /* i : Correlations */ + /* Compute in G_pitch(). */ + Word16 even_subframe, /* i : even subframe indicator flag */ + Word16 gp_limit, /* i : pitch gain limit */ + Word16 *sf0_gain_pit, /* o : Pitch gain sf 0. MR475 */ + Word16 *sf0_gain_cod, /* o : Code gain sf 0. MR475 */ + Word16 *gain_pit, /* i/o : Pitch gain. */ + Word16 *gain_cod, /* o : Code gain. */ + /* MR475: gain_* unquantized in even */ + /* subframes, quantized otherwise */ + Word16 **anap, /* o : Index of quantization */ + CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of tbl ptrs */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + Word16 exp_gcode0; + Word16 frac_gcode0; + Word16 qua_ener_MR122; + Word16 qua_ener; + Word16 frac_coeff[5]; + Word16 exp_coeff[5]; + Word16 exp_en; + Word16 frac_en; + Word16 cod_gain_exp; + Word16 cod_gain_frac; + Word16 temp; + + if (mode == MR475) + { + if (even_subframe != 0) + { + /* save position in output parameter stream and current + state of codebook gain predictor */ + st->gain_idx_ptr = (*anap)++; + +// gc_pred_copy(&(st->gc_predSt), &(st->gc_predUnqSt)); + + oscl_memcpy(st->gc_predUnqSt.past_qua_en, + st->gc_predSt.past_qua_en, + NPRED*sizeof(Word16)); + oscl_memcpy(st->gc_predUnqSt.past_qua_en_MR122, + st->gc_predSt.past_qua_en_MR122, + NPRED*sizeof(Word16)); + + + /* predict codebook gain (using "unquantized" predictor)*/ + /* (note that code[] is unsharpened in MR475) */ + gc_pred( + &(st->gc_predUnqSt), + mode, + code, + &st->sf0_exp_gcode0, + &st->sf0_frac_gcode0, + &exp_en, + &frac_en, + pOverflow); + + /* calculate energy coefficients for quantization + and store them in state structure (will be used + in next subframe when real quantizer is run) */ + calc_filt_energies( + mode, + xn, + xn2, + y1, + Y2, + g_coeff, + st->sf0_frac_coeff, + st->sf0_exp_coeff, + &cod_gain_frac, + &cod_gain_exp, + pOverflow); + + /* store optimum codebook gain (Q1) */ + temp = cod_gain_exp + 1; + + *gain_cod = + shl( + cod_gain_frac, + temp, + pOverflow); + + calc_target_energy( + xn, + &st->sf0_exp_target_en, + &st->sf0_frac_target_en, + pOverflow); + + /* calculate optimum codebook gain and update + "unquantized" predictor */ + MR475_update_unq_pred( + &(st->gc_predUnqSt), + st->sf0_exp_gcode0, + st->sf0_frac_gcode0, + cod_gain_exp, + cod_gain_frac, + pOverflow); + + /* the real quantizer is not run here... */ + } + else + { + /* predict codebook gain (using "unquantized" predictor) */ + /* (note that code[] is unsharpened in MR475) */ + gc_pred( + &(st->gc_predUnqSt), + mode, + code, + &exp_gcode0, + &frac_gcode0, + &exp_en, + &frac_en, + pOverflow); + + /* calculate energy coefficients for quantization */ + calc_filt_energies( + mode, + xn, + xn2, + y1, + Y2, + g_coeff, + frac_coeff, + exp_coeff, + &cod_gain_frac, + &cod_gain_exp, + pOverflow); + + calc_target_energy( + xn, + &exp_en, + &frac_en, + pOverflow); + + /* run real (4-dim) quantizer and update real gain predictor */ + *st->gain_idx_ptr = + MR475_gain_quant( + &(st->gc_predSt), + st->sf0_exp_gcode0, + st->sf0_frac_gcode0, + st->sf0_exp_coeff, + st->sf0_frac_coeff, + st->sf0_exp_target_en, + st->sf0_frac_target_en, + code, + exp_gcode0, + frac_gcode0, + exp_coeff, + frac_coeff, + exp_en, + frac_en, + gp_limit, + sf0_gain_pit, + sf0_gain_cod, + gain_pit, + gain_cod, + pOverflow); + } + } + else + { + /*-------------------------------------------------------------------* + * predict codebook gain and quantize * + * (also compute normalized CB innovation energy for MR795) * + *-------------------------------------------------------------------*/ + gc_pred( + &(st->gc_predSt), + mode, + code, + &exp_gcode0, + &frac_gcode0, + &exp_en, + &frac_en, + pOverflow); + + if (mode == MR122) + { + *gain_cod = + G_code( + xn2, + Y2, + pOverflow); + + *(*anap)++ = + q_gain_code( + mode, + exp_gcode0, + frac_gcode0, + gain_cod, + &qua_ener_MR122, + &qua_ener, + common_amr_tbls->qua_gain_code_ptr, + pOverflow); + } + else + { + /* calculate energy coefficients for quantization */ + calc_filt_energies( + mode, + xn, + xn2, + y1, + Y2, + g_coeff, + frac_coeff, + exp_coeff, + &cod_gain_frac, + &cod_gain_exp, + pOverflow); + + if (mode == MR795) + { + MR795_gain_quant( + st->adaptSt, + res, + exc, + code, + frac_coeff, + exp_coeff, + exp_en, + frac_en, + exp_gcode0, + frac_gcode0, + L_SUBFR, + cod_gain_frac, + cod_gain_exp, + gp_limit, + gain_pit, + gain_cod, + &qua_ener_MR122, + &qua_ener, + anap, + common_amr_tbls, + pOverflow); + } + else + { + *(*anap)++ = + Qua_gain( + mode, + exp_gcode0, + frac_gcode0, + frac_coeff, + exp_coeff, + gp_limit, + gain_pit, + gain_cod, + &qua_ener_MR122, + &qua_ener, + common_amr_tbls, + pOverflow); + } + } + + /*------------------------------------------------------------------* + * update table of past quantized energies * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * st->past_qua_en(Q10) = 20 * Log10(qua_gain_code) / constant * + * = Log2(qua_gain_code) * + * = qua_ener * + * constant = 20*Log10(2) * + *------------------------------------------------------------------*/ + gc_pred_update( + &(st->gc_predSt), + qua_ener_MR122, + qua_ener); + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/gain_q.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/gain_q.h new file mode 100644 index 00000000..a0a7c2cf --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/gain_q.h @@ -0,0 +1,161 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: gain_q.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the file, gain_q.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef gain_q_h +#define gain_q_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "gc_pred.h" +#include "g_adapt.h" +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 sf0_exp_gcode0; + Word16 sf0_frac_gcode0; + Word16 sf0_exp_target_en; + Word16 sf0_frac_target_en; + Word16 sf0_exp_coeff[5]; + Word16 sf0_frac_coeff[5]; + Word16 *gain_idx_ptr; + + gc_predState gc_predSt; + gc_predState gc_predUnqSt; + GainAdaptState *adaptSt; + } gainQuantState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 gainQuant_init(gainQuantState **st); + /* initialize one instance of the pre processing state. + Stores pointer to filter status struct in *st. This pointer has to + be passed to gainQuant in each call. + returns 0 on success + */ + Word16 gainQuant_reset(gainQuantState *st); + /* reset of pre processing state (i.e. set state memory to zero) + returns 0 on success + */ + void gainQuant_exit(gainQuantState **st); + /* de-initialize pre processing state (i.e. free status struct) + stores NULL in *st + */ + + void gainQuant( + gainQuantState *st, /* i/o : State struct */ + enum Mode mode, /* i : coder mode */ + Word16 res[], /* i : LP residual, Q0 */ + Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ + Word16 code[], /* i : CB innovation (unfiltered), Q13 */ + /* (unsharpened for MR475) */ + Word16 xn[], /* i : Target vector. */ + Word16 xn2[], /* i : Target vector. */ + Word16 y1[], /* i : Adaptive codebook. */ + Word16 Y2[], /* i : Filtered innovative vector. */ + Word16 g_coeff[], /* i : Correlations */ + /* Compute in G_pitch(). */ + Word16 even_subframe, /* i : even subframe indicator flag */ + Word16 gp_limit, /* i : pitch gain limit */ + Word16 *sf0_gain_pit, /* o : Pitch gain sf 0. MR475 */ + Word16 *sf0_gain_cod, /* o : Code gain sf 0. MR475 */ + Word16 *gain_pit, /* i/o : Pitch gain. */ + Word16 *gain_cod, /* o : Code gain. */ + /* MR475: gain_* unquantized in even */ + /* subframes, quantized otherwise */ + Word16 **anap, /* o : Index of quantization */ + CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of tbl ptrs */ + Flag *pOverflow /* o : overflow indicator */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* gain_q_h */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/gsmamr_enc.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/gsmamr_enc.h new file mode 100644 index 00000000..078b787b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/gsmamr_enc.h @@ -0,0 +1,176 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: gsmamr_enc.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This header contains all the necessary information needed to use the + GSM AMR encoder library. + +------------------------------------------------------------------------------ +*/ +#ifndef _GSMAMR_ENC_H_ +#define _GSMAMR_ENC_H_ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "gsm_amr_typedefs.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ----------------------------------------------------------------------------*/ + /* Number of 13-bit linear PCM samples per 20 ms frame */ + /* L_FRAME = (8 kHz) * (20 msec) = 160 samples */ +#define L_FRAME 160 + + /* Output format types */ +#define AMR_TX_WMF 0 +#define AMR_TX_IF2 1 +#define AMR_TX_ETS 2 +#define AMR_TX_IETF 3 + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + enum Mode + { + MR475 = 0,/* 4.75 kbps */ + MR515, /* 5.15 kbps */ + MR59, /* 5.90 kbps */ + MR67, /* 6.70 kbps */ + MR74, /* 7.40 kbps */ + MR795, /* 7.95 kbps */ + MR102, /* 10.2 kbps */ + MR122, /* 12.2 kbps */ + MRDTX, /* DTX */ + N_MODES /* Not Used */ + }; + + enum Frame_Type_3GPP + { + AMR_475 = 0, /* 4.75 kbps */ + AMR_515, /* 5.15 kbps */ + AMR_59, /* 5.9 kbps */ + AMR_67, /* 6.7 kbps */ + AMR_74, /* 7.4 kbps */ + AMR_795, /* 7.95 kbps */ + AMR_102, /* 10.2 kbps */ + AMR_122, /* 12.2 kbps */ + AMR_SID, /* GSM AMR DTX */ + GSM_EFR_SID, /* GSM EFR DTX */ + TDMA_EFR_SID, /* TDMA EFR DTX */ + PDC_EFR_SID, /* PDC EFR DTX */ + FOR_FUTURE_USE1, /* Unused 1 */ + FOR_FUTURE_USE2, /* Unused 2 */ + FOR_FUTURE_USE3, /* Unused 3 */ + AMR_NO_DATA /* No data */ + }; + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ----------------------------------------------------------------------------*/ + /* AMREncodeInit initializes the GSM AMR Encoder library by calling + * GSMInitEncode and sid_sync_init. If initialization was successful, + * init_status is set to zero, otherwise, it is set to -1. + */ + int AMREncodeInit( + void **pEncStructure, + void **pSidSyncStructure, + Flag dtx_enable); + + /* AMREncodeReset resets the state memory used by the Encoder and SID sync + * function. If reset was successful, reset_status is set to zero, otherwise, + * it is set to -1. + */ + int AMREncodeReset( + void *pEncStructure, + void *pSidSyncStructure); + + /* AMREncodeExit frees up the state memory used by the Encoder and SID + * synchronization function. + */ + void AMREncodeExit( + void **pEncStructure, + void **pSidSyncStructure); + + /* + * AMREncode is the entry point to the ETS Encoder library that encodes the raw + * data speech bits and converts the encoded bitstream into either an IF2- + * formatted bitstream, WMF-formatted bitstream, or ETS-formatted bitstream, + * depending on the the value of output_format. A zero is returned on success. + */ + int AMREncode( + void *pEncState, + void *pSidSyncState, + enum Mode mode, + Word16 *pEncInput, + unsigned char *pEncOutput, + enum Frame_Type_3GPP *p3gpp_frame_type, + Word16 output_format + ); + +#ifdef __cplusplus +} +#endif + + +#endif /* _GSMAMR_DEC_H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/gsmamr_encoder_wrapper.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/gsmamr_encoder_wrapper.cpp new file mode 100644 index 00000000..8be29a7e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/gsmamr_encoder_wrapper.cpp @@ -0,0 +1,227 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +#ifndef GSMAMR_ENC_H_INCLUDED +#include "gsmamr_enc.h" +#endif + +#ifndef GSMAMR_ENCODER_WRAPPER_H_INCLUDED +#include "gsmamr_encoder_wrapper.h" +#endif + +//lhc fix;no this file +#ifndef OSCL_DLL_H_INCLUDED +#include "oscl_dll.h" +#endif + +// Define entry point for this DLL +OSCL_DLL_ENTRY_POINT_DEFAULT(); + +//---------------------------------------------------------------------------- +// CONSTANTS +//---------------------------------------------------------------------------- + +// Number of samples per frame +#define KGAMR_NUM_SAMPLES_PER_FRAME 160 + +// Default mode +#define KDFLT_GAMR_MODE MR475 + +// Default bits per sample for input audio +#define KDFLT_GAMR_BITS_PER_SAMPLE 16 + +// Default sampling rate for input audio (in Hz) +#define KDFLT_GAMR_SAMPLING_RATE 8000 + +// Default input clock rate for input audio (in ticks/sec) +#define KDFLT_GAMR_CLOCK_RATE 8000 + +// Default number of channels +#define KDFLT_GAMR_NUM_CHANNELS 1 + +// length of uncompressed audio frame in bytes +// Formula: (num_samples_per_frame * bits_per_sample) / num_bits_per_byte +#define PV_GSM_AMR_20_MSEC_SIZE ((KGAMR_NUM_SAMPLES_PER_FRAME * KDFLT_GAMR_BITS_PER_SAMPLE)/8) + + +/////////////////////////////////////////////////////////////////////////////// +OSCL_EXPORT_REF CPvGsmAmrEncoder::CPvGsmAmrEncoder() +{ + // initialize member data to default values + iEncState = NULL; + iSidState = NULL; + iGsmAmrMode = (GSM_AMR_MODES)KDFLT_GAMR_MODE; + iLastModeUsed = 0; + iBitStreamFormat = AMR_TX_WMF; + iNumSamplesPerFrame = KGAMR_NUM_SAMPLES_PER_FRAME; +} +/////////////////////////////////////////////////////////////////////////////// +OSCL_EXPORT_REF CPvGsmAmrEncoder::~CPvGsmAmrEncoder() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////// +OSCL_EXPORT_REF int32 CPvGsmAmrEncoder::InitializeEncoder(int32 aMaxOutputBufferSize, TEncodeProperties* aProps) +{ + if (aProps == NULL) + { + // use default parameters + TEncodeProperties dfltProps; + aProps = &dfltProps; + dfltProps.iInBitsPerSample = KDFLT_GAMR_BITS_PER_SAMPLE; + dfltProps.iInSamplingRate = KDFLT_GAMR_SAMPLING_RATE; + dfltProps.iInClockRate = dfltProps.iInSamplingRate; + dfltProps.iInNumChannels = KDFLT_GAMR_NUM_CHANNELS; + iGsmAmrMode = (GSM_AMR_MODES)KDFLT_GAMR_MODE; + iBitStreamFormat = AMR_TX_WMF; + } + else + { + // check first if input parameters are valid + if ((IsModeValid(aProps->iMode) == false) || + (aProps->iInBitsPerSample == 0) || + (aProps->iInClockRate == 0) || + (aProps->iInSamplingRate == 0) || + (aProps->iInNumChannels == 0)) + { + return GSMAMR_ENC_INVALID_PARAM; + } + // set AMR mode (bits per second) + iGsmAmrMode = (GSM_AMR_MODES)aProps->iMode; + if (aProps->iBitStreamFormat == AMR_TX_WMF) + { + iBitStreamFormat = AMR_TX_WMF; + } + else if (aProps->iBitStreamFormat == AMR_TX_IF2) + { + iBitStreamFormat = AMR_TX_IF2; + } + else if (aProps->iBitStreamFormat == AMR_TX_IETF) + { + iBitStreamFormat = AMR_TX_IETF; + } + else + { + iBitStreamFormat = AMR_TX_ETS; + } + } + + iBytesPerSample = aProps->iInBitsPerSample / 8; + + // set maximum buffer size for encoded data + iMaxOutputBufferSize = aMaxOutputBufferSize; + // return output parameters that will be used + aProps->iOutSamplingRate = KDFLT_GAMR_SAMPLING_RATE; + aProps->iOutNumChannels = KDFLT_GAMR_NUM_CHANNELS; + aProps->iOutClockRate = aProps->iOutSamplingRate; + + // initialize AMR encoder + int32 nResult = AMREncodeInit(&iEncState, &iSidState, false); + if (nResult < 0) return(GSMAMR_ENC_CODEC_INIT_FAILURE); + + return GSMAMR_ENC_NO_ERROR; +} + + +//////////////////////////////////////////////////////////////////////////// +OSCL_EXPORT_REF int32 CPvGsmAmrEncoder::Encode(TInputAudioStream& aInStream, + TOutputAudioStream& aOutStream) +{ + // check first if mode specified is invalid + if (IsModeValid(aInStream.iMode) == false) + return GSMAMR_ENC_INVALID_MODE; + + // set AMR mode for this set of samples + iGsmAmrMode = (GSM_AMR_MODES)aInStream.iMode; + + // get the maximum number of frames // BX + int32 bytesPerFrame = iNumSamplesPerFrame * iBytesPerSample; + int32 maxNumFrames = aInStream.iSampleLength / bytesPerFrame; + uint8 *pFrameIn = aInStream.iSampleBuffer; + uint8 *pFrameOut = aOutStream.iBitStreamBuffer; + int32 i; + + // encode samples + for (i = 0; i < maxNumFrames; i++) + { + + // ////////////////////////////////////////// + // encode this frame + // ////////////////////////////////////////// + int32 * temp = & iLastModeUsed; + Word16 nStatus = AMREncode(iEncState, iSidState, // BX, Word16 instead of int32 to avoid wierd case(IF2 format): the function returns 31, but nStatus ends up with a big wierd number + (Mode)iGsmAmrMode, + (Word16 *)pFrameIn, + (unsigned char *)pFrameOut, + (Frame_Type_3GPP*) temp, + iBitStreamFormat); + + if (nStatus < 0) + { + // an error when encoding was received, so quit + return(GSMAMR_ENC_CODEC_ENCODE_FAILURE); + } + + // save nStatus as this indicates the encoded frame size + int32 encFrameSize = (int32)nStatus; + aOutStream.iSampleFrameSize[i] = encFrameSize; + pFrameOut += encFrameSize; + pFrameIn += bytesPerFrame; + } + + // set other values to be returned + aOutStream.iNumSampleFrames = maxNumFrames; + return(GSMAMR_ENC_NO_ERROR); +} + +//////////////////////////////////////////////////////////////////////////// +OSCL_EXPORT_REF int32 CPvGsmAmrEncoder::CleanupEncoder() +{ + // call terminate function of GSM AMR encoder + AMREncodeExit(&iEncState, &iSidState); + + iEncState = NULL; + iSidState = NULL; + + return GSMAMR_ENC_NO_ERROR; +} + +//////////////////////////////////////////////////////////////////////////// +OSCL_EXPORT_REF int32 CPvGsmAmrEncoder::Reset() +{ + // reset GSM AMR encoder (state memory and SID sync function.) + Word16 nStatus = AMREncodeReset(&iEncState, &iSidState); + + if (nStatus < 0) + { + return GSMAMR_ENC_CODEC_ENCODE_FAILURE; + } + return GSMAMR_ENC_NO_ERROR; +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/hp_max.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/hp_max.cpp new file mode 100644 index 00000000..e2a67f96 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/hp_max.cpp @@ -0,0 +1,308 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: hp_max.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "hp_max.h" +#include "basic_op.h" +#include "cnst.h" +#include "l_abs.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: hp_max +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + corr[] = correlation vector (Word16) + scal_sig[] = scaled signal vector (Word16) + L_frame = length of frame to compute pitch (Word16 + lag_max = maximum lag (Word16) + lag_min = minimum lag (Word16) + cor_hp_max = pointer to max high-pass filtered norm. correlation (Word16) + pOverflow = pointer to overflow (Flag) + + Outputs: + cor_hp_max contains max high-pass filtered norm. correlation (Word16) + pOverflow -> 1 if the maximum correlation computation resulted in overflow + + Returns: + 0 (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function finds the maximum high-pass filtered correlation of scal_sig[] + in a given delay range. + + The correlation is given by + corr[t] = , t=lag_min,...,lag_max + The functions outputs the maximum high-pass filtered correlation after + normalization. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] hp_max.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 hp_max ( + Word32 corr[], // i : correlation vector + Word16 scal_sig[], // i : scaled signal + Word16 L_frame, // i : length of frame to compute pitch + Word16 lag_max, // i : maximum lag + Word16 lag_min, // i : minimum lag + Word16 *cor_hp_max) // o : max high-pass filtered norm. correlation +{ + Word16 i; + Word16 *p, *p1; + Word32 max, t0, t1; + Word16 max16, t016, cor_max; + Word16 shift, shift1, shift2; + + max = MIN_32; + t0 = 0L; +* The reference ETSI code uses a global flag for Overflow inside the math functions +* saturate(). In the actual implementation a pointer to Overflow flag is passed in +* as a parameter to the function + + for (i = lag_max-1; i > lag_min; i--) + { + // high-pass filtering + t0 = L_sub (L_sub(L_shl(corr[-i], 1), corr[-i-1]), corr[-i+1]); + t0 = L_abs (t0); + + if (L_sub (t0, max) >= 0) + { + max = t0; + } + } + + // compute energy + p = scal_sig; + p1 = &scal_sig[0]; + t0 = 0L; + for (i = 0; i < L_frame; i++, p++, p1++) + { + t0 = L_mac (t0, *p, *p1); + } + + p = scal_sig; + p1 = &scal_sig[-1]; + t1 = 0L; + for (i = 0; i < L_frame; i++, p++, p1++) + { + t1 = L_mac (t1, *p, *p1); + } + + // high-pass filtering + t0 = L_sub(L_shl(t0, 1), L_shl(t1, 1)); + t0 = L_abs (t0); + + // max/t0 + shift1 = sub(norm_l(max), 1); + max16 = extract_h(L_shl(max, shift1)); + shift2 = norm_l(t0); + t016 = extract_h(L_shl(t0, shift2)); + + if (t016 != 0) + { + cor_max = div_s(max16, t016); + } + else + { + cor_max = 0; + } + + shift = sub(shift1, shift2); + + if (shift >= 0) + { + *cor_hp_max = shr(cor_max, shift); // Q15 + } + else + { + *cor_hp_max = shl(cor_max, negate(shift)); // Q15 + } + + return 0; +} + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word16 hp_max( + Word32 corr[], /* i : correlation vector. */ + Word16 scal_sig[], /* i : scaled signal. */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word16 *cor_hp_max, /* o : max high-pass filtered norm. correlation */ + Flag *pOverflow /* i/o : overflow Flag */ +) +{ + Word16 i; + Word16 *p, *p1; + Word32 max, t0, t1; + Word16 max16, t016, cor_max; + Word16 shift, shift1, shift2; + Word32 L_temp; + + max = MIN_32; + t0 = 0L; + + for (i = lag_max - 1; i > lag_min; i--) + { + /* high-pass filtering */ + t0 = L_shl(corr[-i], 1, pOverflow); + L_temp = L_sub(t0, corr[-i-1], pOverflow); + t0 = L_sub(L_temp, corr[-i+1], pOverflow); + t0 = L_abs(t0); + + if (t0 >= max) + { + max = t0; + } + } + + /* compute energy */ + p = scal_sig; + p1 = &scal_sig[0]; + t0 = 0L; + for (i = 0; i < L_frame; i++, p++, p1++) + { + t0 = L_mac(t0, *p, *p1, pOverflow); + } + + p = scal_sig; + p1 = &scal_sig[-1]; + t1 = 0L; + for (i = 0; i < L_frame; i++, p++, p1++) + { + t1 = L_mac(t1, *p, *p1, pOverflow); + } + + /* high-pass filtering */ + L_temp = L_shl(t0, 1, pOverflow); + t1 = L_shl(t1, 1, pOverflow); + t0 = L_sub(L_temp, t1, pOverflow); + t0 = L_abs(t0); + + /* max/t0 */ + /* shift1 = sub(norm_l(max), 1); + max16 = extract_h(L_shl(max, shift1)); + shift2 = norm_l(t0); + t016 = extract_h(L_shl(t0, shift2)); */ + + t016 = norm_l(max); + shift1 = t016 - 1; + + L_temp = L_shl(max, shift1, pOverflow); + max16 = (Word16)(L_temp >> 16); + + shift2 = norm_l(t0); + L_temp = L_shl(t0, shift2, pOverflow); + t016 = (Word16)(L_temp >> 16); + + if (t016 != 0) + { + cor_max = div_s(max16, t016); + } + else + { + cor_max = 0; + } + + shift = shift1 - shift2; + + if (shift >= 0) + { + *cor_hp_max = shr(cor_max, shift, pOverflow); /* Q15 */ + } + else + { + *cor_hp_max = shl(cor_max, negate(shift), pOverflow); /* Q15 */ + } + + return 0; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/hp_max.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/hp_max.h new file mode 100644 index 00000000..67df2aaa --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/hp_max.h @@ -0,0 +1,107 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: hp_max.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : hp_max.h + Purpose : Find the maximum correlation of scal_sig[] in a given + delay range. + +------------------------------------------------------------------------------ +*/ + +#ifndef HP_MAX_H +#define HP_MAX_H "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + Word16 hp_max( + Word32 corr[], /* i : correlation vector. */ + Word16 scal_sig[], /* i : scaled signal. */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word16 *cor_hp_max, /* o : max high-pass filtered norm. correlation */ + Flag *pOverflow /* i/o : overflow Flag */ + ); + +#ifdef __cplusplus +} +#endif + +#endif /* _HP_MAX_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/inter_36.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/inter_36.cpp new file mode 100644 index 00000000..d8cf9781 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/inter_36.cpp @@ -0,0 +1,208 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: inter_36.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "inter_36.h" +#include "cnst.h" +#include "inter_36_tab.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define UP_SAMP_MAX 6 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: inter_36 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pX = pointer to input vector of type Word16 + frac = fraction (-2..2 for 3*, -3..3 for 6*) of type Word16 + flag3 = if set, upsampling rate = 3 (6 otherwise) of type Word16 + pOverflow = pointer to overflow flag + + Outputs: + None + + Returns: + None + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + File : inter_36.c + Purpose : Interpolating the normalized correlation + : with 1/3 or 1/6 resolution. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + inter_36.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Word16 i, k; + Word16 *x1, *x2; + const Word16 *c1, *c2; + Word32 s; + + if (flag3 != 0) + { + frac = shl (frac, 1); // inter_3[k] = inter_6[2*k] -> k' = 2*k + } + + if (frac < 0) + { + frac = add (frac, UP_SAMP_MAX); + x--; + } + + x1 = &x[0]; + x2 = &x[1]; + c1 = &inter_6[frac]; + c2 = &inter_6[sub (UP_SAMP_MAX, frac)]; + + s = 0; + for (i = 0, k = 0; i < L_INTER_SRCH; i++, k += UP_SAMP_MAX) + { + s = L_mac (s, x1[-i], c1[k]); + s = L_mac (s, x2[i], c2[k]); + } + + return pv_round (s); + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 Interpol_3or6( /* o : interpolated value */ + Word16 *pX, /* i : input vector */ + Word16 frac, /* i : fraction (-2..2 for 3*, -3..3 for 6*) */ + Word16 flag3, /* i : if set, upsampling rate = 3 (6 otherwise) */ + Flag *pOverflow +) +{ + Word16 i; + Word16 k; + Word16 *pX1; + Word16 *pX2; + const Word16 *pC1; + const Word16 *pC2; + Word32 s; + Word16 temp1; + + OSCL_UNUSED_ARG(pOverflow); + + if (flag3 != 0) + { + frac <<= 1; + /* inter_3[k] = inter_6[2*k] -> k' = 2*k */ + } + + if (frac < 0) + { + frac += UP_SAMP_MAX; + pX--; + } + + pX1 = &pX[0]; + pX2 = &pX[1]; + pC1 = &inter_6[frac]; + temp1 = UP_SAMP_MAX - frac; + pC2 = &inter_6[temp1]; + + s = 0x04000; + k = 0; + + for (i = (L_INTER_SRCH >> 1); i != 0; i--) + { + s = amrnb_fxp_mac_16_by_16bb((Word32) * (pX1--), (Word32) pC1[k], s); + s = amrnb_fxp_mac_16_by_16bb((Word32) * (pX2++), (Word32) pC2[k], s); + k += UP_SAMP_MAX; + s = amrnb_fxp_mac_16_by_16bb((Word32) * (pX1--), (Word32) pC1[k], s); + s = amrnb_fxp_mac_16_by_16bb((Word32) * (pX2++), (Word32) pC2[k], s); + k <<= 1; + } + + return((Word16)(s >> 15)); +} + + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/inter_36.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/inter_36.h new file mode 100644 index 00000000..7c964717 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/inter_36.h @@ -0,0 +1,108 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: inter_36.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : inter_36.h + Purpose : Interpolating the normalized correlation + : with 1/3 or 1/6 resolution. + +------------------------------------------------------------------------------ +*/ + +#ifndef _INTER_36_H_ +#define _INTER_36_H_ +#define inter_36_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + Word16 Interpol_3or6( /* (o) : interpolated value */ + Word16 *x, /* (i) : input vector */ + Word16 frac, /* (i) : fraction (-2..2 for 3*, -3..3 for 6*) */ + Word16 flag3, /* (i) : if set, upsampling rate = 3 (6 otherwise) */ + Flag *pOverflow + ); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _INTER_36_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/inter_36_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/inter_36_tab.cpp new file mode 100644 index 00000000..264d0bfa --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/inter_36_tab.cpp @@ -0,0 +1,174 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Filename: inter_36_tab.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + None + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + File : inter_36.tab + Purpose : Tables for interpolating the normalized correlation + with 1/3 or 1/6 resolution. + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "inter_36_tab.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ +#define UP_SAMP_MAX 6 +#define FIR_SIZE (UP_SAMP_MAX*L_INTER_SRCH+1) + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; LOCAL STORE/BUFFER/POINTER DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + /* 1/6 resolution interpolation filter (-3 dB at 3600 Hz) */ + /* Note: The IS641 (7.4) 1/3 resolution filter is simply a subsampled + version of the 1/6 resolution filter, i.e. it uses + every second coefficient: + + inter_3[k] = inter_6[2*k], 0 <= k <= 3*L_INTER_SRCH + */ + + const Word16 inter_6[FIR_SIZE] = + { + 29519, + 28316, 24906, 19838, 13896, 7945, 2755, + -1127, -3459, -4304, -3969, -2899, -1561, + -336, 534, 970, 1023, 823, 516, + 220, 0, -131, -194, -215, 0 + }; + + /*---------------------------------------------------------------------------- + ; EXTERNAL FUNCTION REFERENCES + ; Declare functions defined elsewhere and referenced in this module + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; Define all local variables +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Function body here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Return nothing or data or data pointer +----------------------------------------------------------------------------*/ + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/inter_36_tab.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/inter_36_tab.h new file mode 100644 index 00000000..a99140a5 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/inter_36_tab.h @@ -0,0 +1,104 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Filename: inter_36_tab.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file declares a table BytesUsed. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef INTER_36_TAB_H +#define INTER_36_TAB_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 inter_6[]; + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_abs.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_abs.cpp new file mode 100644 index 00000000..eed4fc3d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_abs.cpp @@ -0,0 +1,160 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: l_abs.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32 ) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + L_var1 = absolute value of input (Word32) + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calculates the absolute value of L_var1; saturate in case + where the input is -214783648. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word32 L_abs (Word32 L_var1) +{ + Word32 L_var_out; + + if (L_var1 == MIN_32) + { + L_var_out = MAX_32; + } + else + { + if (L_var1 < 0) + { + L_var_out = -L_var1; + } + else + { + L_var_out = L_var1; + } + } + +#if (WMOPS) + multiCounter[currCounter].L_abs++; +#endif + return (L_var_out); +} + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "l_abs.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word32 L_abs(Word32 L_var1) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + + Word32 y = L_var1 - (L_var1 < 0); + y = y ^(y >> 31); + return (y); + +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_abs.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_abs.h new file mode 100644 index 00000000..9a1eaa94 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_abs.h @@ -0,0 +1,101 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: l_abs.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the L_abs function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef L_ABS_H +#define L_ABS_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word32 L_abs(Word32 L_var1); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_comp.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_comp.cpp new file mode 100644 index 00000000..bd6c6f68 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_comp.cpp @@ -0,0 +1,140 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + hi = 16 bit signed integer (Word16) whose value falls in + the range : 0x8000 <= hi <= 0x7fff. + lo = 16 bit signed integer (Word16) whose value falls in + the range : 0x8000 <= lo <= 0x7fff. + + Outputs: + pOverflow = 1 if overflow happens in a math function called by this function. + L_out = 32-bit result of (hi<<16 + lo<<1). + + Returns: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function composes a 32 bit integer from two 16 bit double precision + format (DPF) numbers hi and lo by the following operation: + 1. Deposit hi into the 16 MS bits of the 32 bit output L_out. + 2. Shift lo left by 1. + 3. Add results from 1 and 2 with saturation to return the 32 bit result + L_out. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] oper_32b.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "l_comp.h" +#include "basic_op.h" +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +Word32 L_Comp(Word16 hi, Word16 lo, Flag *pOverflow) +{ + + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + Word32 L_32; + Word32 temp32; + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + + L_32 = ((Word32)hi << 16); + + temp32 = L_mac(L_32, lo, 1, pOverflow); + /*---------------------------------------------------------------------------- + ; Return nothing or data or data pointer + ----------------------------------------------------------------------------*/ + + return (temp32); /* = hi<<16 + lo<<1 */ +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_extract.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_extract.cpp new file mode 100644 index 00000000..ba348d30 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_extract.cpp @@ -0,0 +1,146 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + + + + Filename: l_extract.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: L_extract +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var = 32 bit signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_32 <= 0x7fff ffff. + + pL_var_hi = pointer to the most significant word of L_var (Word16). + + pL_var_lo = pointer to the least significant word of L_var shifted + to the left by 1 (Word16). + + pOverflow = pointer to overflow (Flag) + + Outputs: + pOverflow -> 1 if the 32 bit add operation resulted in overflow + pL_var_hi -> MS word of L_32. + pL_var_lo -> LS word of L_32 shifted left by 1. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function extracts two 16-bit double precision format (DPF) numbers + from a 32-bit integer. The MS word of L_var will be stored in the location + pointed to by pL_var_hi and the shifted LS word of L_var will be stored in + the location pointed to by pL_var_lo. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] L_extract() function in oper_32b.c, UMTS GSM AMR speech codec, R99 - + Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +void L_Extract(Word32 L_var, + Word16 *pL_var_hi, + Word16 *pL_var_lo, + Flag *pOverflow) +{ + + Word32 temp; + + OSCL_UNUSED_ARG(pOverflow); + + temp = (L_var >> 16); + + *(pL_var_hi) = (Word16) temp; + *(pL_var_lo) = (Word16)((L_var >> 1) - (temp << 15)); + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_negate.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_negate.cpp new file mode 100644 index 00000000..9699095f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/l_negate.cpp @@ -0,0 +1,144 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + L_var1 = 32 bit long signed integer (Word32) whose value falls + in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + L_var1 = 32-bit negation of input + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function negates the 32 bit variable, L_var1, with saturation; saturate + in the case where input is -2147483648 (0x8000 0000). + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + [1] basicop2.c, ETS Version 2.0.0, February 8, 1999 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word32 L_negate (Word32 L_var1) +{ + Word32 L_var_out; + + L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1; +#if (WMOPS) + multiCounter[currCounter].L_negate++; +#endif + return (L_var_out); +} + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Word32 L_negate(register Word32 L_var1) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + L_var1 = (L_var1 == MIN_32) ? MAX_32 : -L_var1; + + /*---------------------------------------------------------------------------- + ; Return nothing or data or data pointer + ----------------------------------------------------------------------------*/ + return (L_var1); +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lag_wind.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lag_wind.cpp new file mode 100644 index 00000000..9b733d8c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lag_wind.cpp @@ -0,0 +1,163 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: lag_wind.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "lag_wind.h" +#include "lag_wind_tab.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: lag_wind +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + m = LPC order of type Word16 + r_h[] = pointer to autocorrelations (msb) of type Word16 + r_l[] = pointer to autocorrelations (lsb) of type Word16 + pOverflow = pointer to overflow flag + + Outputs: + None + + Returns: + None + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + File : lag_wind.c + Purpose : Lag windowing of autocorrelations. + + FUNCTION: Lag_window() + + PURPOSE: Lag windowing of autocorrelations. + + DESCRIPTION: + r[i] = r[i]*lag_wind[i], i=1,...,10 + + r[i] and lag_wind[i] are in special double precision format. + See "oper_32b.c" for the format. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + lag_wind.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Word16 i; + Word32 x; + + for (i = 1; i <= m; i++) + { + x = Mpy_32 (r_h[i], r_l[i], lag_h[i - 1], lag_l[i - 1], pOverflow); + L_Extract (x, &r_h[i], &r_l[i], pOverflow); + } + return; + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void Lag_window( + Word16 m, /* (i) : LPC order */ + Word16 r_h[], /* (i/o) : Autocorrelations (msb) */ + Word16 r_l[], /* (i/o) : Autocorrelations (lsb) */ + Flag *pOverflow +) +{ + Word16 i; + Word32 x; + const Word16 *p_lag_h = &lag_h[0]; + const Word16 *p_lag_l = &lag_l[0]; + Word16 *p_r_h = &r_h[1]; + Word16 *p_r_l = &r_l[1]; + + for (i = m; i != 0 ; i--) + { + x = Mpy_32(*(p_r_h), *(p_r_l), *(p_lag_h++), *(p_lag_l++), pOverflow); + *(p_r_h) = (Word16)(x >> 16); + *(p_r_l++) = (x >> 1) - (*(p_r_h++) << 15); + } + + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lag_wind.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lag_wind.h new file mode 100644 index 00000000..b533c42a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lag_wind.h @@ -0,0 +1,108 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: lag_wind.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : lag_wind.h + Purpose : Lag windowing of autocorrelations. + +------------------------------------------------------------------------------ +*/ + +#ifndef _LAG_WIND_H_ +#define _LAG_WIND_H_ +#define lag_wind_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + void Lag_window( + Word16 m, /* (i) : LPC order */ + Word16 r_h[], /* (i/o) : Autocorrelations (msb) */ + Word16 r_l[], /* (i/o) : Autocorrelations (lsb) */ + Flag *pOverflow + ); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _LAG_WIND_H_ */ + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lag_wind_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lag_wind_tab.cpp new file mode 100644 index 00000000..c16090a9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lag_wind_tab.cpp @@ -0,0 +1,197 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Filename: lag_wind_tab.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + None + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + None + + Pointers and Buffers Modified: + None + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + File : lag_wind.tab + Purpose : Table of lag_window for autocorrelation. + + *-----------------------------------------------------* + | Table of lag_window for autocorrelation. | + | | + | noise floor = 1.0001 = (0.9999 on r[1] ..r[10]) | + | Bandwitdh expansion = 60 Hz | + | | + | | + | lag_wind[0] = 1.00000000 (not stored) | + | lag_wind[1] = 0.99879038 | + | lag_wind[2] = 0.99546897 | + | lag_wind[3] = 0.98995781 | + | lag_wind[4] = 0.98229337 | + | lag_wind[5] = 0.97252619 | + | lag_wind[6] = 0.96072036 | + | lag_wind[7] = 0.94695264 | + | lag_wind[8] = 0.93131179 | + | lag_wind[9] = 0.91389757 | + | lag_wind[10]= 0.89481968 | + ------------------------------------------------------- + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + None + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "lag_wind_tab.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; LOCAL STORE/BUFFER/POINTER DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + const Word16 lag_h[10] = + { + 32728, + 32619, + 32438, + 32187, + 31867, + 31480, + 31029, + 30517, + 29946, + 29321 + }; + + const Word16 lag_l[10] = + { + 11904, + 17280, + 30720, + 25856, + 24192, + 28992, + 24384, + 7360, + 19520, + 14784 + }; + + /*---------------------------------------------------------------------------- + ; EXTERNAL FUNCTION REFERENCES + ; Declare functions defined elsewhere and referenced in this module + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; Define all local variables +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Function body here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Return nothing or data or data pointer +----------------------------------------------------------------------------*/ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lag_wind_tab.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lag_wind_tab.h new file mode 100644 index 00000000..ed047069 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lag_wind_tab.h @@ -0,0 +1,103 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Filename: lag_wind_tab.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file declares tables used by lag_wind.c. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef LAG_WIND_TAB_H +#define LAG_WIND_TAB_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + extern const Word16 lag_h[]; + extern const Word16 lag_l[]; + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/levinson.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/levinson.cpp new file mode 100644 index 00000000..cbd27d7e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/levinson.cpp @@ -0,0 +1,759 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: levinson.cpp + Funtions: Levinson_init + Levinson_reset + Levinson_exit + Levinson + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the function the implements the Levinson-Durbin algorithm + using double-precision arithmetic. This file also includes functions to + initialize, allocate, and deallocate memory used by the Levinson function. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "levinson.h" +#include "basicop_malloc.h" +#include "basic_op.h" +#include "l_abs.h" +#include "div_32.h" +#include "cnst.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Levinson_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to an array of pointers to structures of type + LevinsonState + + Outputs: + pointer pointed to by state points to the newly allocated memory to + be used by Levinson function + + Returns: + return_value = 0, if initialization was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function allocates and initializes the state memory used by the + Levinson function. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + levinson.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Levinson_init (LevinsonState **state) +{ + LevinsonState* s; + + if (state == (LevinsonState **) NULL){ + //fprint(stderr, "Levinson_init: invalid parameter\n"); + return -1; + } + *state = NULL; + + // allocate memory + if ((s= (LevinsonState *) malloc(sizeof(LevinsonState))) == NULL){ + //fprint(stderr, "Levinson_init: can not malloc state structure\n"); + return -1; + } + + Levinson_reset(s); + *state = s; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Levinson_init(LevinsonState **state) +{ + LevinsonState* s; + + if (state == (LevinsonState **) NULL) + { + /* fprint(stderr, "Levinson_init: invalid parameter\n"); */ + return(-1); + } + *state = NULL; + + /* allocate memory */ + if ((s = (LevinsonState *) oscl_malloc(sizeof(LevinsonState))) == NULL) + { + /* fprint(stderr, "Levinson_init: + can not malloc state structure\n"); */ + return(-1); + } + + Levinson_reset(s); + *state = s; + + return(0); +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Levinson_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to structures of type LevinsonState + + Outputs: + old_A field of structure pointed to by state is initialized to 4096 + (first location) and the rest to zeros + + Returns: + return_value = 0, if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function initializes the state memory used by the Levinson function to + zero. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + levinson.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Levinson_reset (LevinsonState *state) +{ + Word16 i; + + if (state == (LevinsonState *) NULL){ + fprint(stderr, "Levinson_reset: invalid parameter\n"); + return -1; + } + + state->old_A[0] = 4096; + for(i = 1; i < M + 1; i++) + state->old_A[i] = 0; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Levinson_reset(LevinsonState *state) +{ + Word16 i; + + if (state == (LevinsonState *) NULL) + { + /* fprint(stderr, "Levinson_reset: invalid parameter\n"); */ + return(-1); + } + + state->old_A[0] = 4096; + for (i = 1; i < M + 1; i++) + { + state->old_A[i] = 0; + } + + return(0); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Levinson_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to an array of pointers to structures of type + LevinsonState + + Outputs: + pointer pointed to by state is set to the NULL address + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function deallocates the state memory used by the Levinson function. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + levinson.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Levinson_exit (LevinsonState **state) +{ + if (state == NULL || *state == NULL) + return; + + // deallocate memory + free(*state); + *state = NULL; + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void Levinson_exit(LevinsonState **state) +{ + if (state == NULL || *state == NULL) + { + return; + } + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Levinson +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to structures of type LevinsonState + Rh = vector containing most significant byte of + autocorrelation values (Word16) + Rl = vector containing least significant byte of + autocorrelation values (Word16) + A = vector of LPC coefficients (10th order) (Word16) + rc = vector containing first four reflection coefficients (Word16) + pOverflow = pointer to overflow indicator (Flag) + + Outputs: + A contains the newly calculated LPC coefficients + rc contains the newly calculated reflection coefficients + + Returns: + return_value = 0 (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function implements the Levinson-Durbin algorithm using double- + precision arithmetic. This is used to compute the Linear Predictive (LP) + filter parameters from the speech autocorrelation values. + + The algorithm implemented is as follows: + A[0] = 1 + K = -R[1]/R[0] + A[1] = K + Alpha = R[0] * (1-K**2] + + FOR i = 2 to M + + S = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] + K = -S / Alpha + + FOR j = 1 to i-1 + An[j] = A[j] + K*A[i-j] where An[i] = new A[i] + ENDFOR + + An[i]=K + Alpha=Alpha * (1-K**2) + + END + + where: + R[i] = autocorrelations + A[i] = filter coefficients + K = reflection coefficient + Alpha = prediction gain + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + levinson.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Levinson ( + LevinsonState *st, + Word16 Rh[], // i : Rh[m+1] Vector of autocorrelations (msb) + Word16 Rl[], // i : Rl[m+1] Vector of autocorrelations (lsb) + Word16 A[], // o : A[m] LPC coefficients (m = 10) + Word16 rc[] // o : rc[4] First 4 reflection coefficients +) +{ + Word16 i, j; + Word16 hi, lo; + Word16 Kh, Kl; // reflexion coefficient; hi and lo + Word16 alp_h, alp_l, alp_exp; // Prediction gain; hi lo and exponent + Word16 Ah[M + 1], Al[M + 1]; // LPC coef. in double prec. + Word16 Anh[M + 1], Anl[M + 1];// LPC coef.for next iteration in double + prec. + Word32 t0, t1, t2; // temporary variable + + // K = A[1] = -R[1] / R[0] + + t1 = L_Comp (Rh[1], Rl[1]); + t2 = L_abs (t1); // abs R[1] + t0 = Div_32 (t2, Rh[0], Rl[0]); // R[1]/R[0] + if (t1 > 0) + t0 = L_negate (t0); // -R[1]/R[0] + L_Extract (t0, &Kh, &Kl); // K in DPF + + rc[0] = pv_round (t0); + + t0 = L_shr (t0, 4); // A[1] in + L_Extract (t0, &Ah[1], &Al[1]); // A[1] in DPF + + // Alpha = R[0] * (1-K**2) + + t0 = Mpy_32 (Kh, Kl, Kh, Kl); // K*K + t0 = L_abs (t0); // Some case <0 !! + t0 = L_sub ((Word32) 0x7fffffffL, t0); // 1 - K*K + L_Extract (t0, &hi, &lo); // DPF format + t0 = Mpy_32 (Rh[0], Rl[0], hi, lo); // Alpha in + + // Normalize Alpha + + alp_exp = norm_l (t0); + t0 = L_shl (t0, alp_exp); + L_Extract (t0, &alp_h, &alp_l); // DPF format + + *--------------------------------------* + * ITERATIONS I=2 to M * + *--------------------------------------* + + for (i = 2; i <= M; i++) + { + // t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] + + t0 = 0; + for (j = 1; j < i; j++) + { + t0 = L_add (t0, Mpy_32 (Rh[j], Rl[j], Ah[i - j], Al[i - j])); + } + t0 = L_shl (t0, 4); + + t1 = L_Comp (Rh[i], Rl[i]); + t0 = L_add (t0, t1); // add R[i] + + // K = -t0 / Alpha + + t1 = L_abs (t0); + t2 = Div_32 (t1, alp_h, alp_l); // abs(t0)/Alpha + if (t0 > 0) + t2 = L_negate (t2); // K =-t0/Alpha + t2 = L_shl (t2, alp_exp); // denormalize; compare to Alpha + L_Extract (t2, &Kh, &Kl); // K in DPF + + if (sub (i, 5) < 0) + { + rc[i - 1] = pv_round (t2); + } + // Test for unstable filter. If unstable keep old A(z) + + if (sub (abs_s (Kh), 32750) > 0) + { + for (j = 0; j <= M; j++) + { + A[j] = st->old_A[j]; + } + + for (j = 0; j < 4; j++) + { + rc[j] = 0; + } + + return 0; + } + *------------------------------------------* + * Compute new LPC coeff. -> An[i] * + * An[j]= A[j] + K*A[i-j] , j=1 to i-1 * + * An[i]= K * + *------------------------------------------* + + for (j = 1; j < i; j++) + { + t0 = Mpy_32 (Kh, Kl, Ah[i - j], Al[i - j]); + t0 = L_add(t0, L_Comp(Ah[j], Al[j])); + L_Extract (t0, &Anh[j], &Anl[j]); + } + t2 = L_shr (t2, 4); + L_Extract (t2, &Anh[i], &Anl[i]); + + // Alpha = Alpha * (1-K**2) + + t0 = Mpy_32 (Kh, Kl, Kh, Kl); // K*K + t0 = L_abs (t0); // Some case <0 !! + t0 = L_sub ((Word32) 0x7fffffffL, t0); // 1 - K*K + L_Extract (t0, &hi, &lo); // DPF format + t0 = Mpy_32 (alp_h, alp_l, hi, lo); + + // Normalize Alpha + + j = norm_l (t0); + t0 = L_shl (t0, j); + L_Extract (t0, &alp_h, &alp_l); // DPF format + alp_exp = add (alp_exp, j); // Add normalization to + alp_exp + + // A[j] = An[j] + + for (j = 1; j <= i; j++) + { + Ah[j] = Anh[j]; + Al[j] = Anl[j]; + } + } + + A[0] = 4096; + for (i = 1; i <= M; i++) + { + t0 = L_Comp (Ah[i], Al[i]); + st->old_A[i] = A[i] = pv_round (L_shl (t0, 1)); + } + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Levinson( + LevinsonState *st, + Word16 Rh[], /* i : Rh[m+1] Vector of autocorrelations (msb) */ + Word16 Rl[], /* i : Rl[m+1] Vector of autocorrelations (lsb) */ + Word16 A[], /* o : A[m] LPC coefficients (m = 10) */ + Word16 rc[], /* o : rc[4] First 4 reflection coefficients */ + Flag *pOverflow +) +{ + register Word16 i; + register Word16 j; + Word16 hi; + Word16 lo; + Word16 Kh; /* reflexion coefficient; hi and lo */ + Word16 Kl; + Word16 alp_h; /* Prediction gain; hi lo and exponent*/ + Word16 alp_l; + Word16 alp_exp; + Word16 Ah[M + 1]; /* LPC coef. in double prec. */ + Word16 Al[M + 1]; + Word16 Anh[M + 1]; /* LPC coef.for next iteration in */ + Word16 Anl[M + 1]; /* double prec. */ + register Word32 t0; /* temporary variable */ + register Word32 t1; /* temporary variable */ + register Word32 t2; /* temporary variable */ + + Word16 *p_Rh; + Word16 *p_Rl; + Word16 *p_Ah; + Word16 *p_Al; + Word16 *p_Anh; + Word16 *p_Anl; + Word16 *p_A; + + /* K = A[1] = -R[1] / R[0] */ + t1 = ((Word32) * (Rh + 1)) << 16; + t1 += *(Rl + 1) << 1; + + t2 = L_abs(t1); /* abs R[1] - required by Div_32 */ + t0 = Div_32(t2, *Rh, *Rl, pOverflow); /* R[1]/R[0] */ + + if (t1 > 0) + { + t0 = L_negate(t0); /* -R[1]/R[0] */ + } + + /* K in DPF */ + Kh = (Word16)(t0 >> 16); + Kl = (Word16)((t0 >> 1) - ((Word32)(Kh) << 15)); + + *rc = pv_round(t0, pOverflow); + + t0 = t0 >> 4; + + /* A[1] in DPF */ + *(Ah + 1) = (Word16)(t0 >> 16); + + *(Al + 1) = (Word16)((t0 >> 1) - ((Word32)(*(Ah + 1)) << 15)); + + /* Alpha = R[0] * (1-K**2) */ + t0 = Mpy_32(Kh, Kl, Kh, Kl, pOverflow); /* K*K */ + t0 = L_abs(t0); /* Some case <0 !! */ + t0 = 0x7fffffffL - t0; /* 1 - K*K */ + + /* DPF format */ + hi = (Word16)(t0 >> 16); + lo = (Word16)((t0 >> 1) - ((Word32)(hi) << 15)); + + t0 = Mpy_32(*Rh, *Rl, hi, lo, pOverflow); /* Alpha in */ + + /* Normalize Alpha */ + + alp_exp = norm_l(t0); + t0 = t0 << alp_exp; + + /* DPF format */ + alp_h = (Word16)(t0 >> 16); + alp_l = (Word16)((t0 >> 1) - ((Word32)(alp_h) << 15)); + + /*--------------------------------------* + * ITERATIONS I=2 to M * + *--------------------------------------*/ + + for (i = 2; i <= M; i++) + { + /* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] */ + + t0 = 0; + p_Rh = &Rh[1]; + p_Rl = &Rl[1]; + p_Ah = &Ah[i-1]; + p_Al = &Al[i-1]; + for (j = 1; j < i; j++) + { + t0 += (((Word32) * (p_Rh)* *(p_Al--)) >> 15); + t0 += (((Word32) * (p_Rl++)* *(p_Ah)) >> 15); + t0 += ((Word32) * (p_Rh++)* *(p_Ah--)); + } + + t0 = t0 << 5; + + t1 = ((Word32) * (Rh + i) << 16) + ((Word32)(*(Rl + i)) << 1); + t0 += t1; + + /* K = -t0 / Alpha */ + + t1 = L_abs(t0); + t2 = Div_32(t1, alp_h, alp_l, pOverflow); /* abs(t0)/Alpha */ + + if (t0 > 0) + { + t2 = L_negate(t2); /* K =-t0/Alpha */ + } + + t2 = L_shl(t2, alp_exp, pOverflow); /* denormalize; compare to Alpha */ + Kh = (Word16)(t2 >> 16); + Kl = (Word16)((t2 >> 1) - ((Word32)(Kh) << 15)); + + if (i < 5) + { + *(rc + i - 1) = (Word16)((t2 + 0x00008000L) >> 16); + } + /* Test for unstable filter. If unstable keep old A(z) */ + if ((abs_s(Kh)) > 32750) + { + oscl_memcpy(A, &(st->old_A[0]), sizeof(Word16)*(M + 1)); + oscl_memset(rc, 0, sizeof(Word16)*4); + return(0); + } + /*------------------------------------------* + * Compute new LPC coeff. -> An[i] * + * An[j]= A[j] + K*A[i-j] , j=1 to i-1 * + * An[i]= K * + *------------------------------------------*/ + p_Ah = &Ah[i-1]; + p_Al = &Al[i-1]; + p_Anh = &Anh[1]; + p_Anl = &Anl[1]; + for (j = 1; j < i; j++) + { + t0 = (((Word32)Kh* *(p_Al--)) >> 15); + t0 += (((Word32)Kl* *(p_Ah)) >> 15); + t0 += ((Word32)Kh* *(p_Ah--)); + + t0 += (Ah[j] << 15) + Al[j]; + + *(p_Anh) = (Word16)(t0 >> 15); + *(p_Anl++) = (Word16)(t0 - ((Word32)(*(p_Anh++)) << 15)); + } + + *(p_Anh) = (Word16)(t2 >> 20); + *(p_Anl) = (Word16)((t2 >> 5) - ((Word32)(*(Anh + i)) << 15)); + + /* Alpha = Alpha * (1-K**2) */ + + t0 = Mpy_32(Kh, Kl, Kh, Kl, pOverflow); /* K*K */ + t0 = L_abs(t0); /* Some case <0 !! */ + t0 = 0x7fffffffL - t0; /* 1 - K*K */ + + hi = (Word16)(t0 >> 16); + lo = (Word16)((t0 >> 1) - ((Word32)(hi) << 15)); + + t0 = (((Word32)alp_h * lo) >> 15); + t0 += (((Word32)alp_l * hi) >> 15); + t0 += ((Word32)alp_h * hi); + + t0 <<= 1; + /* Normalize Alpha */ + + j = norm_l(t0); + t0 <<= j; + alp_h = (Word16)(t0 >> 16); + alp_l = (Word16)((t0 >> 1) - ((Word32)(alp_h) << 15)); + alp_exp += j; /* Add normalization to alp_exp */ + + /* A[j] = An[j] */ + oscl_memcpy(&Ah[1], &Anh[1], sizeof(Word16)*i); + oscl_memcpy(&Al[1], &Anl[1], sizeof(Word16)*i); + } + + p_A = &A[0]; + *(p_A++) = 4096; + p_Ah = &Ah[1]; + p_Al = &Al[1]; + + for (i = 1; i <= M; i++) + { + t0 = ((Word32) * (p_Ah++) << 15) + *(p_Al++); + st->old_A[i] = *(p_A++) = (Word16)((t0 + 0x00002000) >> 14); + } + + return(0); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/levinson.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/levinson.h new file mode 100644 index 00000000..dec67185 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/levinson.h @@ -0,0 +1,131 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: levinson.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : lag_wind.h + Purpose : Lag windowing of autocorrelations. + +------------------------------------------------------------------------------ +*/ + +#ifndef _LEVINSON_H_ +#define _LEVINSON_H_ +#define levinson_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 old_A[M + 1]; /* Last A(z) for case of unstable filter */ + } LevinsonState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + Word16 Levinson_init(LevinsonState **st); + /* initialize one instance of the pre processing state. + Stores pointer to filter status struct in *st. This pointer has to + be passed to Levinson in each call. + returns 0 on success + */ + + Word16 Levinson_reset(LevinsonState *st); + /* reset of pre processing state (i.e. set state memory to zero) + returns 0 on success + */ + void Levinson_exit(LevinsonState **st); + /* de-initialize pre processing state (i.e. free status struct) + stores NULL in *st + */ + + Word16 Levinson( + LevinsonState *st, + Word16 Rh[], /* i : Rh[m+1] Vector of autocorrelations (msb) */ + Word16 Rl[], /* i : Rl[m+1] Vector of autocorrelations (lsb) */ + Word16 A[], /* o : A[m] LPC coefficients (m = 10) */ + Word16 rc[], /* o : rc[4] First 4 reflection coefficients */ + Flag *pOverflow + ); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _LEVINSON_H_ */ + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lflg_upd.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lflg_upd.cpp new file mode 100644 index 00000000..61e5655e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lflg_upd.cpp @@ -0,0 +1,184 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: lflg_upd.cpp + Functions: LTP_flag_update + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + LTP_flag update for AMR VAD option 2 +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" +#include "l_extract.h" +//#include "mpy_32_16.h" + +#include "basic_op_c_equivalent.h" +#include "vad2.h" +#include "mode.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- Pointer to vadState2 + mode -- Word16 -- AMR mode + + Outputs: + st -- Pointer to vadState2 + pOverflow -- Pointer to Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + LTP_flag update for AMR VAD option 2 + + + PURPOSE: + Set LTP_flag if the LTP gain > LTP_THRESHOLD, where the value of + LTP_THRESHOLD depends on the LTP analysis window length. + + INPUTS: + + mode + AMR mode + vadState->L_R0 + LTP energy + vadState->L_Rmax + LTP maximum autocorrelation + OUTPUTS: + + vadState->LTP_flag + Set if LTP gain > LTP_THRESHOLD + + RETURN VALUE: + + none + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + lflg_upd.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void LTP_flag_update( + vadState2 * st, + Word16 mode, + Flag *pOverflow) +{ + Word16 thresh; + Word16 hi1; + Word16 lo1; + Word32 Ltmp; + + if ((mode == MR475) || (mode == MR515)) + { + thresh = 18022; /* (Word16)(32768.0*0.55); */ + } + else if (mode == MR102) + { + thresh = 19660; /* (Word16)(32768.0*0.60); */ + } + else + { + thresh = 21299; /* (Word16)(32768.0*0.65); */ + } + + L_Extract(st->L_R0, &hi1, &lo1, pOverflow); + + Ltmp = Mpy_32_16(hi1, lo1, thresh, pOverflow); + + if (st->L_Rmax > Ltmp) + { + st->LTP_flag = TRUE; + } + else + { + st->LTP_flag = FALSE; + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lpc.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lpc.cpp new file mode 100644 index 00000000..bd0e9905 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lpc.cpp @@ -0,0 +1,467 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: lpc.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "lpc.h" +#include "typedef.h" +#include "oper_32b.h" +#include "autocorr.h" +#include "lag_wind.h" +#include "levinson.h" +#include "cnst.h" +#include "mode.h" +#include "sub.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: lpc_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to pointer of state data of type lpcState + + Outputs: + None + + Returns: + None + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function initializes the state data for the LPC module. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + lpc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + lpcState* s; + + if (state == (lpcState **) NULL){ + // fprintf(stderr, "lpc_init: invalid parameter\n"); + return -1; + } + *state = NULL; + + // allocate memory + if ((s= (lpcState *) malloc(sizeof(lpcState))) == NULL){ + // fprintf(stderr, "lpc_init: can not malloc state structure\n"); + return -1; + } + + s->levinsonSt = NULL; + + // Init sub states + if (Levinson_init(&s->levinsonSt)) { + lpc_exit(&s); + return -1; + } + + + lpc_reset(s); + *state = s; + + return 0; + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 lpc_init(lpcState **state) +{ + lpcState* s; + + if (state == (lpcState **) NULL) + { + /* fprintf(stderr, "lpc_init: invalid parameter\n"); */ + return -1; + } + *state = NULL; + + /* allocate memory */ + if ((s = (lpcState *) oscl_malloc(sizeof(lpcState))) == NULL) + { + /* fprintf(stderr, "lpc_init: can not malloc state structure\n"); */ + return -1; + } + + s->levinsonSt = NULL; + + /* Init sub states */ + if (Levinson_init(&s->levinsonSt)) + { + lpc_exit(&s); + return -1; + } + + lpc_reset(s); + *state = s; + + return 0; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: lpc_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to pointer of state data of type lpcState + + Outputs: + None + + Returns: + None + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function resets the state data for the LPC module. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + lpc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + if (state == (lpcState *) NULL){ + // fprintf(stderr, "lpc_reset: invalid parameter\n"); + return -1; + } + + Levinson_reset(state->levinsonSt); + + return 0; + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 lpc_reset(lpcState *state) +{ + + if (state == (lpcState *) NULL) + { + /* fprintf(stderr, "lpc_reset: invalid parameter\n"); */ + return -1; + } + + Levinson_reset(state->levinsonSt); + + return 0; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: lpc_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to pointer of state data of type lpcState + + Outputs: + None + + Returns: + None + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function frees the state data for the LPC module. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + lpc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + + if (state == NULL || *state == NULL) + return; + + Levinson_exit(&(*state)->levinsonSt); + + // deallocate memory + free(*state); + *state = NULL; + + return; + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void lpc_exit(lpcState **state) +{ + if (state == NULL || *state == NULL) + return; + + Levinson_exit(&(*state)->levinsonSt); + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: lpc +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to state data of type lpcState + mode = coder mode of type enum Mode + x[] = pointer to input signal (Q15) of type Word16 + x_12k2[] = pointer to input signal (EFR) (Q15) of type Word16 + pOverflow = pointer to overflow indicator of type Flag + + Outputs: + a[] = pointer to predictor coefficients (Q12) of type Word16 + + Returns: + None + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function executes the LPC functionality for GSM AMR. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + lpc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Word16 rc[4]; // First 4 reflection coefficients Q15 + Word16 rLow[MP1], rHigh[MP1]; // Autocorrelations low and hi + // No fixed Q value but normalized + // so that overflow is avoided + + if ( sub ((Word16)mode, (Word16)MR122) == 0) + { + // Autocorrelations + Autocorr(x_12k2, M, rHigh, rLow, window_160_80); + // Lag windowing + Lag_window(M, rHigh, rLow); + // Levinson Durbin + Levinson(st->levinsonSt, rHigh, rLow, &a[MP1], rc); + + // Autocorrelations + Autocorr(x_12k2, M, rHigh, rLow, window_232_8); + // Lag windowing + Lag_window(M, rHigh, rLow); + // Levinson Durbin + Levinson(st->levinsonSt, rHigh, rLow, &a[MP1 * 3], rc); + } + else + { + // Autocorrelations + Autocorr(x, M, rHigh, rLow, window_200_40); + // Lag windowing + Lag_window(M, rHigh, rLow); + // Levinson Durbin + Levinson(st->levinsonSt, rHigh, rLow, &a[MP1 * 3], rc); + } + + return 0; + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void lpc( + lpcState *st, /* i/o: State struct */ + enum Mode mode, /* i : coder mode */ + Word16 x[], /* i : Input signal Q15 */ + Word16 x_12k2[], /* i : Input signal (EFR) Q15 */ + Word16 a[], /* o : predictor coefficients Q12 */ + CommonAmrTbls* common_amr_tbls, /* i : ptr to struct with table ptrs */ + Flag *pOverflow +) +{ + Word16 rc[4]; /* First 4 reflection coefficients Q15 */ + Word16 rLow[MP1], rHigh[MP1]; /* Autocorrelations low and hi */ + /* No fixed Q value but normalized */ + /* so that overflow is avoided */ + + const Word16* window_160_80_ptr = common_amr_tbls->window_160_80_ptr; + const Word16* window_232_8_ptr = common_amr_tbls->window_232_8_ptr; + const Word16* window_200_40_ptr = common_amr_tbls->window_200_40_ptr; + + if (mode == MR122) + { + /* Autocorrelations */ + Autocorr(x_12k2, M, rHigh, rLow, window_160_80_ptr, pOverflow); + /* Lag windowing */ + Lag_window(M, rHigh, rLow, pOverflow); + /* Levinson Durbin */ + Levinson(st->levinsonSt, rHigh, rLow, &a[MP1], rc, pOverflow); + + /* Autocorrelations */ + Autocorr(x_12k2, M, rHigh, rLow, window_232_8_ptr, pOverflow); + /* Lag windowing */ + Lag_window(M, rHigh, rLow, pOverflow); + /* Levinson Durbin */ + Levinson(st->levinsonSt, rHigh, rLow, &a[MP1 * 3], rc, pOverflow); + } + else + { + /* Autocorrelations */ + Autocorr(x, M, rHigh, rLow, window_200_40_ptr, pOverflow); + /* Lag windowing */ + Lag_window(M, rHigh, rLow, pOverflow); + /* Levinson Durbin */ + Levinson(st->levinsonSt, rHigh, rLow, &a[MP1 * 3], rc, pOverflow); + } + +} + + + + + + + + + + + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lpc.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lpc.h new file mode 100644 index 00000000..e0b40b20 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/lpc.h @@ -0,0 +1,138 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: lpc.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : lpc.h + Purpose : 2 LP analyses centered at 2nd and 4th subframe + for mode 12.2. For all other modes a + LP analysis centered at 4th subframe is + performed. + +------------------------------------------------------------------------------ +*/ + +#ifndef _LPC_H_ +#define _LPC_H_ +#define lpc_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "levinson.h" +#include "mode.h" +#include "get_const_tbls.h" + + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + LevinsonState *levinsonSt; + } lpcState; + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + Word16 lpc_init(lpcState **st); + /* initialize one instance of the pre processing state. + Stores pointer to filter status struct in *st. This pointer has to + be passed to lpc in each call. + returns 0 on success + */ + + Word16 lpc_reset(lpcState *st); + /* reset of pre processing state (i.e. set state memory to zero) + returns 0 on success + */ + void lpc_exit(lpcState **st); + /* de-initialize pre processing state (i.e. free status struct) + stores NULL in *st + */ + + void lpc( + lpcState *st, /* i/o: State struct */ + enum Mode mode, /* i : coder mode */ + Word16 x[], /* i : Input signal Q15 */ + Word16 x_12k2[], /* i : Input signal (EFR) Q15 */ + Word16 a[], /* o : predictor coefficients Q12 */ + CommonAmrTbls* common_amr_tbls, /* i : ptr to struct with table ptrs */ + Flag *pOverflow + ); + + +#ifdef __cplusplus +} +#endif + +#endif /* _LPC_H_ */ + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ol_ltp.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ol_ltp.cpp new file mode 100644 index 00000000..43b3f02b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ol_ltp.cpp @@ -0,0 +1,216 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: ol_ltp.cpp + Functions: ol_ltp + +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "ol_ltp.h" +#include "cnst.h" +#include "pitch_ol.h" +#include "p_ol_wgh.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ol_ltp +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to pitchOLWghtState structure + vadSt = pointer to a vadState structure + mode = coder mode (Mode) + wsp = pointer to buffer of signal used to compute the Open loop pitch + T_op = pointer to open loop pitch lag + old_lags = pointer to history with old stored Cl lags (Word16) + ol_gain_flg = pointer to OL gain flag (Word16) + idx = 16 bit value specifies the frame index + dtx = Data of type 'Flag' used for dtx. Use dtx=1, do not use dtx=0 + pOverflow = pointer to Overflow indicator (Flag) + + Outputs: + pOverflow -> 1 if processing this funvction results in satuaration + + Returns: + Zero + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes the open loop pitch lag. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + ol_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int ol_ltp( + pitchOLWghtState *st, // i/o : State struct + vadState *vadSt, // i/o : VAD state struct + enum Mode mode, // i : coder mode + Word16 wsp[], // i : signal used to compute the OL pitch, Q0 + // uses signal[-pit_max] to signal[-1] + Word16 *T_op, // o : open loop pitch lag, Q0 + Word16 old_lags[], // i : history with old stored Cl lags + Word16 ol_gain_flg[], // i : OL gain flag + Word16 idx, // i : index + Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0 + ) +{ + if (sub ((Word16)mode, (Word16)MR102) != 0 ) + { + ol_gain_flg[0] = 0; + ol_gain_flg[1] = 0; + } + + if (sub ((Word16)mode, (Word16)MR475) == 0 || sub ((Word16)mode, (Word16)MR515) == 0 ) + { + *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN, PIT_MAX, L_FRAME, idx, dtx); + } + else + { + if ( sub ((Word16)mode, (Word16)MR795) <= 0 ) + { + *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN, PIT_MAX, L_FRAME_BY2, + idx, dtx); + } + else if ( sub ((Word16)mode, (Word16)MR102) == 0 ) + { + *T_op = Pitch_ol_wgh(st, vadSt, wsp, PIT_MIN, PIT_MAX, L_FRAME_BY2, + old_lags, ol_gain_flg, idx, dtx); + } + else + { + *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN_MR122, PIT_MAX, + L_FRAME_BY2, idx, dtx); + } + } + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +void ol_ltp( + pitchOLWghtState *st, /* i/o : State struct */ + vadState *vadSt, /* i/o : VAD state struct */ + enum Mode mode, /* i : coder mode */ + Word16 wsp[], /* i : signal used to compute the OL pitch, Q0 */ + /* uses signal[-pit_max] to signal[-1] */ + Word16 *T_op, /* o : open loop pitch lag, Q0 */ + Word16 old_lags[], /* i : history with old stored Cl lags */ + Word16 ol_gain_flg[], /* i : OL gain flag */ + Word16 idx, /* i : index */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow indicator */ +) +{ + if ((mode != MR102)) + { + ol_gain_flg[0] = 0; + ol_gain_flg[1] = 0; + } + + if ((mode == MR475) || (mode == MR515)) + { + *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN, PIT_MAX, L_FRAME, idx, dtx, + pOverflow); + } + else + { + if (mode <= MR795) + { + *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN, PIT_MAX, L_FRAME_BY2, + idx, dtx, pOverflow); + } + else if (mode == MR102) + { + *T_op = Pitch_ol_wgh(st, vadSt, wsp, PIT_MIN, PIT_MAX, L_FRAME_BY2, + old_lags, ol_gain_flg, idx, dtx, pOverflow); + } + else + { + *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN_MR122, PIT_MAX, + L_FRAME_BY2, idx, dtx, pOverflow); + } + } + +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ol_ltp.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ol_ltp.h new file mode 100644 index 00000000..044e1c47 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ol_ltp.h @@ -0,0 +1,114 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: ol_ltp.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : ol_ltp.h + Purpose : Compute the open loop pitch lag. + +------------------------------------------------------------------------------ +*/ + +#ifndef OL_LTP_H +#define OL_LTP_H "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "p_ol_wgh.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + void ol_ltp( + pitchOLWghtState *st, /* i/o : State struct */ + vadState *vadSt, /* i/o : VAD state struct */ + enum Mode mode, /* i : coder mode */ + Word16 wsp[], /* i : signal used to compute the OL pitch, Q0 */ + /* uses signal[-pit_max] to signal[-1] */ + Word16 *T_op, /* o : open loop pitch lag, Q0 */ + Word16 old_lags[], /* i : history with old stored Cl lags */ + Word16 ol_gain_flg[], /* i : OL gain flag */ + Word16 idx, /* i : index */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow Flag */ + ); + + +#ifdef __cplusplus +} +#endif + +#endif /* _OL_LTP_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/p_ol_wgh.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/p_ol_wgh.cpp new file mode 100644 index 00000000..3a239e34 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/p_ol_wgh.cpp @@ -0,0 +1,892 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: p_ol_wgh.cpp + Functions: p_ol_wgh_init + p_ol_wgh_reset + p_ol_wgh_exit + Lag_max + Pitch_ol_wgh + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + The modules in this file compute the open loop pitch lag with weighting. +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "p_ol_wgh.h" +#include "typedef.h" +#include "cnst.h" +#include "basic_op.h" +#include "gmed_n.h" +#include "inv_sqrt.h" +#include "vad1.h" +#include "calc_cor.h" +#include "hp_max.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: p_ol_wgh_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs + state = pointer to a pointer of structure type pitchOLWghtState + + Outputs: + None + + Returns: + 0 if the memory allocation is a success + -1 if the memory allocation fails + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function allocates state memory and initializes state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int p_ol_wgh_init (pitchOLWghtState **state) +{ + pitchOLWghtState* s; + + if (state == (pitchOLWghtState **) NULL){ + // fprintf(stderr, "p_ol_wgh_init: invalid parameter\n"); + return -1; + } + *state = NULL; + + // allocate memory + if ((s= (pitchOLWghtState *) malloc(sizeof(pitchOLWghtState))) == NULL){ + // fprintf(stderr, "p_ol_wgh_init: can not malloc state structure\n"); + return -1; + } + + p_ol_wgh_reset(s); + + *state = s; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 p_ol_wgh_init(pitchOLWghtState **state) +{ + pitchOLWghtState* s; + + if (state == (pitchOLWghtState **) NULL) + { + /* fprintf(stderr, "p_ol_wgh_init: invalid parameter\n"); */ + return -1; + } + *state = NULL; + + /* allocate memory */ + if ((s = (pitchOLWghtState *) oscl_malloc(sizeof(pitchOLWghtState))) == NULL) + { + /* fprintf(stderr, "p_ol_wgh_init: can not malloc state structure\n"); */ + return -1; + } + + p_ol_wgh_reset(s); + + *state = s; + + return 0; +} + +/*---------------------------------------------------------------------------- +; End Function: p_ol_wgh_init +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: p_ol_wgh_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs + st = pointer to structure type pitchOLWghtState + + Outputs: + None + + Returns: + 0 if the memory initialization is a success + -1 if the memory initialization fails + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function initializes state memory to zero + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int p_ol_wgh_reset (pitchOLWghtState *st) +{ + if (st == (pitchOLWghtState *) NULL){ + // fprintf(stderr, "p_ol_wgh_reset: invalid parameter\n"); + return -1; + } + + // Reset pitch search states + st->old_T0_med = 40; + st->ada_w = 0; + st->wght_flg = 0; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 p_ol_wgh_reset(pitchOLWghtState *st) +{ + if (st == (pitchOLWghtState *) NULL) + { + /* fprintf(stderr, "p_ol_wgh_reset: invalid parameter\n"); */ + return -1; + } + + /* Reset pitch search states */ + st->old_T0_med = 40; + st->ada_w = 0; + st->wght_flg = 0; + + return 0; +} + +/*---------------------------------------------------------------------------- +; End Function: p_ol_wgh_reset +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: p_ol_wgh_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs + st = pointer to a pointer of structure type pitchOLWghtState + + Outputs: + None + + Returns: + 0 if the memory initialization is a success + -1 if the memory initialization fails + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function frees the memory used for state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void p_ol_wgh_exit (pitchOLWghtState **state) +{ + if (state == NULL || *state == NULL) + return; + + // deallocate memory + free(*state); + *state = NULL; + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void p_ol_wgh_exit(pitchOLWghtState **state) +{ + if (state == NULL || *state == NULL) + return; + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} + + +/*---------------------------------------------------------------------------- +; End Function: p_ol_wgh_exit +----------------------------------------------------------------------------*/ +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Lag_max +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + corr = pointer to buffer of correlation values (Word32) + scal_sig = pointer to buffer of scaled signal values (Word16) + scal_fac = scaled signal factor (Word16) + scal_flag = EFR compatible scaling flag (Word16) + L_frame = length of frame to compute pitch (Word16) + lag_max = maximum lag (Word16) + lag_min = minimum lag (Word16) + cor_max = pointer to the normalized correlation of selected lag (Word16) + rmax = pointer to max(), (Word32) + r0 = pointer to the residual energy (Word32) + dtx = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag) + pOverflow = Pointer to overflow (Flag) + + Outputs: + cor_max contains the newly calculated normalized correlation of the + selected lag + rmax contains the newly calculated max() + r0 contains the newly calculated residual energy + pOverflow -> 1 if the math functions called by this routine saturate. + + Returns: + p_max = lag of the max correlation found (Word16) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function finds the lag that has maximum correlation of scal_sig[] in a + given delay range. + The correlation is given by + cor[t] = , t=lag_min,...,lag_max + The functions outputs the maximum correlation after normalization and the + corresponding lag. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + p_ol_wgh.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static Word16 Lag_max ( // o : lag found + vadState *vadSt, // i/o : VAD state struct + Word32 corr[], // i : correlation vector. + Word16 scal_sig[], // i : scaled signal. + Word16 L_frame, // i : length of frame to compute pitch + Word16 lag_max, // i : maximum lag + Word16 lag_min, // i : minimum lag + Word16 old_lag, // i : old open-loop lag + Word16 *cor_max, // o : normalized correlation of selected lag + Word16 wght_flg, // i : is weighting function used + Word16 *gain_flg, // o : open-loop flag + Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0 + ) +{ + Word16 i, j; + Word16 *p, *p1; + Word32 max, t0; + Word16 t0_h, t0_l; + Word16 p_max; + const Word16 *ww, *we; + Word32 t1; + + ww = &corrweight[250]; + we = &corrweight[123 + lag_max - old_lag]; + + max = MIN_32; + p_max = lag_max; + + for (i = lag_max; i >= lag_min; i--) + { + t0 = corr[-i]; + + // Weighting of the correlation function. + L_Extract (corr[-i], &t0_h, &t0_l); + t0 = Mpy_32_16 (t0_h, t0_l, *ww); + ww--; + if (wght_flg > 0) { + // Weight the neighbourhood of the old lag + L_Extract (t0, &t0_h, &t0_l); + t0 = Mpy_32_16 (t0_h, t0_l, *we); + we--; + } + + if (L_sub (t0, max) >= 0) + { + max = t0; + p_max = i; + } + } + + p = &scal_sig[0]; + p1 = &scal_sig[-p_max]; + t0 = 0; + t1 = 0; + + for (j = 0; j < L_frame; j++, p++, p1++) + { + t0 = L_mac (t0, *p, *p1); + t1 = L_mac (t1, *p1, *p1); + } + + if (dtx) + { // no test() call since this if is only in simulation env +#ifdef VAD2 + vadSt->L_Rmax = L_add(vadSt->L_Rmax, t0); // Save max correlation + vadSt->L_R0 = L_add(vadSt->L_R0, t1); // Save max energy +#else + // update and detect tone + vad_tone_detection_update (vadSt, 0); + vad_tone_detection (vadSt, t0, t1); +#endif + } + + // gain flag is set according to the open_loop gain + // is t2/t1 > 0.4 ? + *gain_flg = pv_round(L_msu(t0, pv_round(t1), 13107)); + + *cor_max = 0; + + return (p_max); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 Lag_max( /* o : lag found */ + vadState *vadSt, /* i/o : VAD state struct */ + Word32 corr[], /* i : correlation vector. */ + Word16 scal_sig[], /* i : scaled signal. */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word16 old_lag, /* i : old open-loop lag */ + Word16 *cor_max, /* o : normalized correlation of selected lag */ + Word16 wght_flg, /* i : is weighting function used */ + Word16 *gain_flg, /* o : open-loop flag */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* o : overflow flag */ +) +{ + Word16 i; + Word16 j; + Word16 *p; + Word16 *p1; + Word32 max; + Word32 t0; + Word16 t0_h; + Word16 t0_l; + Word16 p_max; + const Word16 *ww; + const Word16 *we; + Word32 t1; + Word16 temp; + + ww = &corrweight[250]; + we = &corrweight[123 + lag_max - old_lag]; + + max = MIN_32; + p_max = lag_max; + + for (i = lag_max; i >= lag_min; i--) + { + t0 = corr[-i]; + + /* Weighting of the correlation function. */ + L_Extract(corr[-i], &t0_h, &t0_l, pOverflow); + t0 = Mpy_32_16(t0_h, t0_l, *ww, pOverflow); + ww--; + if (wght_flg > 0) + { + /* Weight the neighbourhood of the old lag. */ + L_Extract(t0, &t0_h, &t0_l, pOverflow); + t0 = Mpy_32_16(t0_h, t0_l, *we, pOverflow); + we--; + } + + /* if (L_sub (t0, max) >= 0) */ + if (t0 >= max) + { + max = t0; + p_max = i; + } + } + p = &scal_sig[0]; + p1 = &scal_sig[-p_max]; + t0 = 0; + t1 = 0; + + for (j = 0; j < L_frame; j++, p++, p1++) + { + t0 = L_mac(t0, *p, *p1, pOverflow); + t1 = L_mac(t1, *p1, *p1, pOverflow); + } + + if (dtx) + { /* no test() call since this if is only in simulation env */ +#ifdef VAD2 + /* Save max correlation */ + vadSt->L_Rmax = L_add(vadSt->L_Rmax, t0, pOverflow); + /* Save max energy */ + vadSt->L_R0 = L_add(vadSt->L_R0, t1, pOverflow); +#else + /* update and detect tone */ + vad_tone_detection_update(vadSt, 0, pOverflow); + vad_tone_detection(vadSt, t0, t1, pOverflow); +#endif + } + + /* gain flag is set according to the open_loop gain */ + /* is t2/t1 > 0.4 ? */ + temp = pv_round(t1, pOverflow); + t1 = L_msu(t0, temp, 13107, pOverflow); + *gain_flg = pv_round(t1, pOverflow); + + *cor_max = 0; + + return (p_max); +} +/*---------------------------------------------------------------------------- +; End Function: Lag_max +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pitch_ol_wgh +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to pitchOLWghtState structure + vadSt = pointer to a vadState structure + signal = pointer to buffer of signal used to compute the open loop + pitch where signal[-pit_max] to signal[-1] should be known + pit_min = 16 bit value specifies the minimum pitch lag + pit_max = 16 bit value specifies the maximum pitch lag + L_frame = 16 bit value specifies the length of frame to compute pitch + old_lags = pointer to history with old stored Cl lags (Word16) + ol_gain_flg = pointer to OL gain flag (Word16) + idx = 16 bit value specifies the frame index + dtx = Data of type 'Flag' used for dtx. Use dtx=1, do not use dtx=0 + pOverflow = pointer to Overflow indicator (Flag) + Outputs + st = The pitchOLWghtState may be modified + vadSt = The vadSt state structure may be modified. + pOverflow -> 1 if the math functions invoked by this routine saturate. + + Returns: + p_max1 = 16 bit value representing the open loop pitch lag. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs an open-loop pitch search with weighting +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 Pitch_ol_wgh ( // o : open loop pitch lag + pitchOLWghtState *st, // i/o : State struct + vadState *vadSt, // i/o : VAD state struct/ + Word16 signal[], // i : signal used to compute the open loop pitch + // signal[-pit_max] to signal[-1] should be known + Word16 pit_min, // i : minimum pitch lag + Word16 pit_max, // i : maximum pitch lag + Word16 L_frame, // i : length of frame to compute pitch + Word16 old_lags[], // i : history with old stored Cl lags + Word16 ol_gain_flg[], // i : OL gain flag + Word16 idx, // i : index + Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0 + ) +{ + Word16 i; + Word16 max1; + Word16 p_max1; + Word32 t0; +#ifndef VAD2 + Word16 corr_hp_max; +#endif + Word32 corr[PIT_MAX+1], *corr_ptr; + + // Scaled signal + Word16 scaled_signal[PIT_MAX + L_FRAME]; + Word16 *scal_sig; + + scal_sig = &scaled_signal[pit_max]; + + t0 = 0L; + for (i = -pit_max; i < L_frame; i++) + { + t0 = L_mac (t0, signal[i], signal[i]); + } + // + // Scaling of input signal + // + // if Overflow -> scal_sig[i] = signal[i]>>2 + // else if t0 < 1^22 -> scal_sig[i] = signal[i]<<2 + // else -> scal_sig[i] = signal[i] + + // + // Verification for risk of overflow. + // + + // Test for overflow + if (L_sub (t0, MAX_32) == 0L) + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = shr (signal[i], 3); + } + } + else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0) + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = shl (signal[i], 3); + } + } + else + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = signal[i]; + } + } + + // calculate all coreelations of scal_sig, from pit_min to pit_max + corr_ptr = &corr[pit_max]; + comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr); + + p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min, + st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx], + dtx); + + if (ol_gain_flg[idx] > 0) + { + // Calculate 5-point median of previous lag + for (i = 4; i > 0; i--) // Shift buffer + { + old_lags[i] = old_lags[i-1]; + } + old_lags[0] = p_max1; + st->old_T0_med = gmed_n (old_lags, 5); + st->ada_w = 32767; // Q15 = 1.0 + } + else + { + st->old_T0_med = p_max1; + st->ada_w = mult(st->ada_w, 29491); // = ada_w = ada_w * 0.9 + } + + if (sub(st->ada_w, 9830) < 0) // ada_w - 0.3 + { + st->wght_flg = 0; + } + else + { + st->wght_flg = 1; + } + +#ifndef VAD2 + if (dtx) + { // no test() call since this if is only in simulation env + if (sub(idx, 1) == 0) + { + // calculate max high-passed filtered correlation of all lags + hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max); + + // update complex background detector + vad_complex_detection_update(vadSt, corr_hp_max); + } + } +#endif + + return (p_max1); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Pitch_ol_wgh( /* o : open loop pitch lag */ + pitchOLWghtState *st, /* i/o : State struct */ + vadState *vadSt, /* i/o : VAD state struct */ + Word16 signal[], /* i : signal used to compute the open loop pitch */ + /* signal[-pit_max] to signal[-1] should be known */ + Word16 pit_min, /* i : minimum pitch lag */ + Word16 pit_max, /* i : maximum pitch lag */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 old_lags[], /* i : history with old stored Cl lags */ + Word16 ol_gain_flg[], /* i : OL gain flag */ + Word16 idx, /* i : index */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* o : overflow flag */ +) +{ + Word16 i; + Word16 max1; + Word16 p_max1; + Word32 t0; +#ifndef VAD2 + Word16 corr_hp_max; +#endif + Word32 corr[PIT_MAX+1], *corr_ptr; + + /* Scaled signal */ + Word16 scaled_signal[PIT_MAX + L_FRAME]; + Word16 *scal_sig; + + scal_sig = &scaled_signal[pit_max]; + + t0 = 0L; + for (i = -pit_max; i < L_frame; i++) + { + t0 = L_mac(t0, signal[i], signal[i], pOverflow); + } + /*--------------------------------------------------------* + * Scaling of input signal. * + * * + * if Overflow -> scal_sig[i] = signal[i]>>2 * + * else if t0 < 1^22 -> scal_sig[i] = signal[i]<<2 * + * else -> scal_sig[i] = signal[i] * + *--------------------------------------------------------*/ + + /*--------------------------------------------------------* + * Verification for risk of overflow. * + *--------------------------------------------------------*/ + + /* Test for overflow */ + if (L_sub(t0, MAX_32, pOverflow) == 0L) + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = shr(signal[i], 3, pOverflow); + } + } + else if (L_sub(t0, (Word32) 1048576L, pOverflow) < (Word32) 0) + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = shl(signal[i], 3, pOverflow); + } + } + else + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = signal[i]; + } + } + + /* calculate all coreelations of scal_sig, from pit_min to pit_max */ + corr_ptr = &corr[pit_max]; + comp_corr(scal_sig, L_frame, pit_max, pit_min, corr_ptr); + + p_max1 = Lag_max(vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min, + st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx], + dtx, pOverflow); + + if (ol_gain_flg[idx] > 0) + { + /* Calculate 5-point median of previous lags */ + for (i = 4; i > 0; i--) /* Shift buffer */ + { + old_lags[i] = old_lags[i-1]; + } + old_lags[0] = p_max1; + st->old_T0_med = gmed_n(old_lags, 5); + st->ada_w = 32767; /* Q15 = 1.0 */ + } + else + { + st->old_T0_med = p_max1; + /* = ada_w = ada_w * 0.9 */ + st->ada_w = (Word16)((Word32)(st->ada_w * 29491) >> 15); + } + + if (sub(st->ada_w, 9830, pOverflow) < 0) /* ada_w - 0.3 */ + { + st->wght_flg = 0; + } + else + { + st->wght_flg = 1; + } + +#ifndef VAD2 + if (dtx) + { /* no test() call since this if is only in simulation env */ + if (sub(idx, 1, pOverflow) == 0) + { + /* calculate max high-passed filtered correlation of all lags */ + hp_max(corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max, pOverflow); + + /* update complex background detector */ + vad_complex_detection_update(vadSt, corr_hp_max); + } + } +#endif + + return (p_max1); +} + +/*---------------------------------------------------------------------------- +; End Function: Pitch_ol_wgh +----------------------------------------------------------------------------*/ + + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pitch_fr.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pitch_fr.cpp new file mode 100644 index 00000000..5f70021d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pitch_fr.cpp @@ -0,0 +1,1462 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pitch_fr.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + File : pitch_fr.c + Purpose : Find the pitch period with 1/3 or 1/6 subsample + : resolution (closed loop). + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "pitch_fr.h" +#include "oper_32b.h" +#include "cnst.h" +#include "enc_lag3.h" +#include "enc_lag6.h" +#include "inter_36.h" +#include "inv_sqrt.h" +#include "convolve.h" + +#include "basic_op.h" +#include "oscl_mem.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* + * mode dependent parameters used in Pitch_fr() + * Note: order of MRxx in 'enum Mode' is important! + */ +static const struct +{ + Word16 max_frac_lag; /* lag up to which fractional lags are used */ + Word16 flag3; /* enable 1/3 instead of 1/6 fract. resolution */ + Word16 first_frac; /* first fractional to check */ + Word16 last_frac; /* last fractional to check */ + Word16 delta_int_low; /* integer lag below TO to start search from */ + Word16 delta_int_range; /* integer range around T0 */ + Word16 delta_frc_low; /* fractional below T0 */ + Word16 delta_frc_range; /* fractional range around T0 */ + Word16 pit_min; /* minimum pitch */ +} mode_dep_parm[N_MODES] = +{ + /* MR475 */ { 84, 1, -2, 2, 5, 10, 5, 9, PIT_MIN }, + /* MR515 */ { 84, 1, -2, 2, 5, 10, 5, 9, PIT_MIN }, + /* MR59 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, + /* MR67 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, + /* MR74 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, + /* MR795 */ { 84, 1, -2, 2, 3, 6, 10, 19, PIT_MIN }, + /* MR102 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, + /* MR122 */ { 94, 0, -3, 3, 3, 6, 5, 9, PIT_MIN_MR122 } +}; + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Norm_Corr +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + exc[] = pointer to buffer of type Word16 + xn[] = pointer to buffer of type Word16 + h[] = pointer to buffer of type Word16 + L_subfr = length of sub frame (Word16) + t_min = the minimum table value of type Word16 + t_max = the maximum table value of type Word16 + corr_norm[] = pointer to buffer of type Word16 + + Outputs: + pOverflow = 1 if the math functions called result in overflow else zero. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + FUNCTION: Norm_Corr() + + PURPOSE: Find the normalized correlation between the target vector + and the filtered past excitation. + + DESCRIPTION: + The normalized correlation is given by the correlation between the + target and filtered past excitation divided by the square root of + the energy of filtered excitation. + corr[k] = /sqrt(y_k[],y_k[]) + where x[] is the target vector and y_k[] is the filtered past + excitation at delay k. + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static void Norm_Corr (Word16 exc[], Word16 xn[], Word16 h[], Word16 L_subfr, + Word16 t_min, Word16 t_max, Word16 corr_norm[]) +{ + Word16 i, j, k; + Word16 corr_h, corr_l, norm_h, norm_l; + Word32 s; + + // Usally dynamic allocation of (L_subfr) + Word16 excf[L_SUBFR]; + Word16 scaling, h_fac, *s_excf, scaled_excf[L_SUBFR]; + + k = -t_min; + + // compute the filtered excitation for the first delay t_min + + Convolve (&exc[k], h, excf, L_subfr); + + // scale "excf[]" to avoid overflow + + for (j = 0; j < L_subfr; j++) { + scaled_excf[j] = shr (excf[j], 2); + } + + // Compute 1/sqrt(energy of excf[]) + + s = 0; + for (j = 0; j < L_subfr; j++) { + s = L_mac (s, excf[j], excf[j]); + } + if (L_sub (s, 67108864L) <= 0) { // if (s <= 2^26) + s_excf = excf; + h_fac = 15 - 12; + scaling = 0; + } + else { + // "excf[]" is divided by 2 + s_excf = scaled_excf; + h_fac = 15 - 12 - 2; + scaling = 2; + } + + // loop for every possible period + + for (i = t_min; i <= t_max; i++) { + // Compute 1/sqrt(energy of excf[]) + + s = 0; + for (j = 0; j < L_subfr; j++) { + s = L_mac (s, s_excf[j], s_excf[j]); + } + + s = Inv_sqrt (s); + L_Extract (s, &norm_h, &norm_l); + + // Compute correlation between xn[] and excf[] + + s = 0; + for (j = 0; j < L_subfr; j++) { + s = L_mac (s, xn[j], s_excf[j]); + } + L_Extract (s, &corr_h, &corr_l); + + // Normalize correlation = correlation * (1/sqrt(energy)) + + s = Mpy_32 (corr_h, corr_l, norm_h, norm_l); + + corr_norm[i] = extract_h (L_shl (s, 16)); + + // modify the filtered excitation excf[] for the next iteration + + if (sub (i, t_max) != 0) { + k--; + for (j = L_subfr - 1; j > 0; j--) { + s = L_mult (exc[k], h[j]); + s = L_shl (s, h_fac); + s_excf[j] = add (extract_h (s), s_excf[j - 1]); + } + s_excf[0] = shr (exc[k], scaling); + } + } + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void Norm_Corr(Word16 exc[], + Word16 xn[], + Word16 h[], + Word16 L_subfr, + Word16 t_min, + Word16 t_max, + Word16 corr_norm[], + Flag *pOverflow) +{ + Word16 i; + Word16 j; + Word16 k; + Word16 corr_h; + Word16 corr_l; + Word16 norm_h; + Word16 norm_l; + Word32 s; + Word32 s2; + Word16 excf[L_SUBFR]; + Word16 scaling; + Word16 h_fac; + Word16 *s_excf; + Word16 scaled_excf[L_SUBFR]; + Word16 *p_s_excf; + Word16 *p_excf; + Word16 temp; + Word16 *p_x; + Word16 *p_h; + + k = -t_min; + + /* compute the filtered excitation for the first delay t_min */ + + Convolve(&exc[k], h, excf, L_subfr); + + /* scale "excf[]" to avoid overflow */ + s = 0; + p_s_excf = scaled_excf; + p_excf = excf; + + for (j = (L_subfr >> 1); j != 0; j--) + { + temp = *(p_excf++); + *(p_s_excf++) = temp >> 2; + s += (Word32) temp * temp; + temp = *(p_excf++); + *(p_s_excf++) = temp >> 2; + s += (Word32) temp * temp; + } + + + if (s <= (67108864L >> 1)) + { + s_excf = excf; + h_fac = 12; + scaling = 0; + } + else + { + /* "excf[]" is divided by 2 */ + s_excf = scaled_excf; + h_fac = 14; + scaling = 2; + } + + /* loop for every possible period */ + + for (i = t_min; i <= t_max; i++) + { + /* Compute 1/sqrt(energy of excf[]) */ + + s = s2 = 0; + p_x = xn; + p_s_excf = s_excf; + j = L_subfr >> 1; + + while (j--) + { + s += (Word32) * (p_x++) * *(p_s_excf); + s2 += ((Word32)(*(p_s_excf)) * (*(p_s_excf))); + p_s_excf++; + s += (Word32) * (p_x++) * *(p_s_excf); + s2 += ((Word32)(*(p_s_excf)) * (*(p_s_excf))); + p_s_excf++; + } + + s2 = s2 << 1; + s2 = Inv_sqrt(s2, pOverflow); + norm_h = (Word16)(s2 >> 16); + norm_l = (Word16)((s2 >> 1) - (norm_h << 15)); + corr_h = (Word16)(s >> 15); + corr_l = (Word16)((s) - (corr_h << 15)); + + /* Normalize correlation = correlation * (1/sqrt(energy)) */ + + s = Mpy_32(corr_h, corr_l, norm_h, norm_l, pOverflow); + + corr_norm[i] = (Word16) s ; + + /* modify the filtered excitation excf[] for the next iteration */ + if (i != t_max) + { + k--; + temp = exc[k]; + p_s_excf = &s_excf[L_subfr - 1]; + p_h = &h[L_subfr - 1]; + + p_excf = &s_excf[L_subfr - 2]; + for (j = (L_subfr - 1) >> 1; j != 0; j--) + { + s = ((Word32) temp * *(p_h--)) >> h_fac; + *(p_s_excf--) = (Word16) s + *(p_excf--); + s = ((Word32) temp * *(p_h--)) >> h_fac; + *(p_s_excf--) = (Word16) s + *(p_excf--); + } + + s = ((Word32) temp * *(p_h)) >> h_fac; + *(p_s_excf--) = (Word16) s + *(p_excf); + + *(p_s_excf) = temp >> scaling; + } + + } + return; +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: searchFrac +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + lag = pointer to integer pitch of type Word16 + frac = pointer to starting point of search fractional pitch of type Word16 + last_frac = endpoint of search of type Word16 + corr[] = pointer to normalized correlation of type Word16 + flag3 = subsample resolution (3: =1 / 6: =0) of type Word16 + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + FUNCTION: searchFrac() + + PURPOSE: Find fractional pitch + + DESCRIPTION: + The function interpolates the normalized correlation at the + fractional positions around lag T0. The position at which the + interpolation function reaches its maximum is the fractional pitch. + Starting point of the search is frac, end point is last_frac. + frac is overwritten with the fractional pitch. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static void searchFrac ( + Word16 *lag, // i/o : integer pitch + Word16 *frac, // i/o : start point of search - + fractional pitch + Word16 last_frac, // i : endpoint of search + Word16 corr[], // i : normalized correlation + Word16 flag3 // i : subsample resolution + (3: =1 / 6: =0) +) +{ + Word16 i; + Word16 max; + Word16 corr_int; + + // Test the fractions around T0 and choose the one which maximizes + // the interpolated normalized correlation. + + max = Interpol_3or6 (&corr[*lag], *frac, flag3); // function result + + for (i = add (*frac, 1); i <= last_frac; i++) { + corr_int = Interpol_3or6 (&corr[*lag], i, flag3); + if (sub (corr_int, max) > 0) { + max = corr_int; + *frac = i; + } + } + + if (flag3 == 0) { + // Limit the fraction value in the interval [-2,-1,0,1,2,3] + + if (sub (*frac, -3) == 0) { + *frac = 3; + *lag = sub (*lag, 1); + } + } + else { + // limit the fraction value between -1 and 1 + + if (sub (*frac, -2) == 0) { + *frac = 1; + *lag = sub (*lag, 1); + } + if (sub (*frac, 2) == 0) { + *frac = -1; + *lag = add (*lag, 1); + } + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void searchFrac( + Word16 *lag, /* i/o : integer pitch */ + Word16 *frac, /* i/o : start point of search - + fractional pitch */ + Word16 last_frac, /* i : endpoint of search */ + Word16 corr[], /* i : normalized correlation */ + Word16 flag3, /* i : subsample resolution + (3: =1 / 6: =0) */ + Flag *pOverflow +) +{ + Word16 i; + Word16 max; + Word16 corr_int; + + /* Test the fractions around T0 and choose the one which maximizes */ + /* the interpolated normalized correlation. */ + + max = Interpol_3or6(&corr[*lag], *frac, flag3, pOverflow); + /* function result */ + + for (i = *frac + 1; i <= last_frac; i++) + { + corr_int = Interpol_3or6(&corr[*lag], i, flag3, pOverflow); + if (corr_int > max) + { + max = corr_int; + *frac = i; + } + } + + if (flag3 == 0) + { + /* Limit the fraction value in the interval [-2,-1,0,1,2,3] */ + + if (*frac == -3) + { + *frac = 3; + (*lag)--; + } + } + else + { + /* limit the fraction value between -1 and 1 */ + + if (*frac == -2) + { + *frac = 1; + (*lag)--; + } + if (*frac == 2) + { + *frac = -1; + (*lag)++; + } + } +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: getRange +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + T0 = integer pitch of type Word16 + delta_low = search start offset of type Word16 + delta_range = search range of type Word16 + pitmin = minimum pitch of type Word16 + pitmax = maximum pitch of type Word16 + t0_min = search range minimum of type Word16 + t0_max = search range maximum of type Word16 + + Outputs: + pOverflow = 1 if the math functions called result in overflow else zero. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + FUNCTION: getRange() + + PURPOSE: Sets range around open-loop pitch or integer pitch of last subframe + + DESCRIPTION: + Takes integer pitch T0 and calculates a range around it with + t0_min = T0-delta_low and t0_max = (T0-delta_low) + delta_range + t0_min and t0_max are bounded by pitmin and pitmax +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static void getRange ( + Word16 T0, // i : integer pitch + Word16 delta_low, // i : search start offset + Word16 delta_range, // i : search range + Word16 pitmin, // i : minimum pitch + Word16 pitmax, // i : maximum pitch + Word16 *t0_min, // o : search range minimum + Word16 *t0_max) // o : search range maximum +{ + *t0_min = sub(T0, delta_low); + if (sub(*t0_min, pitmin) < 0) { + *t0_min = pitmin; + } + *t0_max = add(*t0_min, delta_range); + if (sub(*t0_max, pitmax) > 0) { + *t0_max = pitmax; + *t0_min = sub(*t0_max, delta_range); + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +static void getRange( + Word16 T0, /* i : integer pitch */ + Word16 delta_low, /* i : search start offset */ + Word16 delta_range, /* i : search range */ + Word16 pitmin, /* i : minimum pitch */ + Word16 pitmax, /* i : maximum pitch */ + Word16 *t0_min, /* o : search range minimum */ + Word16 *t0_max, /* o : search range maximum */ + Flag *pOverflow) +{ + + Word16 temp; + OSCL_UNUSED_ARG(pOverflow); + + temp = *t0_min; + temp = T0 - delta_low; + if (temp < pitmin) + { + temp = pitmin; + } + *t0_min = temp; + + temp += delta_range; + if (temp > pitmax) + { + temp = pitmax; + *t0_min = pitmax - delta_range; + } + *t0_max = temp; + +} + + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pitch_fr_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a pointer of structure type Pitch_fr_State. + + Outputs: + None + + Returns: + Returns a zero if successful and -1 if not successful. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function: Pitch_fr_init + Purpose: Allocates state memory and initializes state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Pitch_fr_init (Pitch_frState **state) +{ + Pitch_frState* s; + + if (state == (Pitch_frState **) NULL){ + // fprintf(stderr, "Pitch_fr_init: invalid parameter\n"); + return -1; + } + *state = NULL; + + // allocate memory + if ((s= (Pitch_frState *) malloc(sizeof(Pitch_frState))) == NULL){ + // fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n"); + return -1; + } + + Pitch_fr_reset(s); + *state = s; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 Pitch_fr_init(Pitch_frState **state) +{ + Pitch_frState* s; + + if (state == (Pitch_frState **) NULL) + { + /* fprintf(stderr, "Pitch_fr_init: invalid parameter\n"); */ + return -1; + } + *state = NULL; + + /* allocate memory */ + if ((s = (Pitch_frState *) oscl_malloc(sizeof(Pitch_frState))) == NULL) + { + /* fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n"); */ + return -1; + } + + Pitch_fr_reset(s); + *state = s; + + return 0; +} + + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pitch_fr_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a pointer of structure type Pitch_fr_State. + + Outputs: + None + + Returns: + Returns a zero if successful and -1 if not successful. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function: Pitch_fr_reset + Purpose: Initializes state memory to zero + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Pitch_fr_reset (Pitch_frState *state) +{ + + if (state == (Pitch_frState *) NULL){ + // fprintf(stderr, "Pitch_fr_reset: invalid parameter\n"); + return -1; + } + + state->T0_prev_subframe = 0; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 Pitch_fr_reset(Pitch_frState *state) +{ + + if (state == (Pitch_frState *) NULL) + { + /* fprintf(stderr, "Pitch_fr_reset: invalid parameter\n"); */ + return -1; + } + + state->T0_prev_subframe = 0; + + return 0; +} + + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pitch_fr_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a pointer of structure type Pitch_fr_State. + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function: Pitch_fr_exit + Purpose: The memory for state is freed. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Pitch_fr_exit (Pitch_frState **state) +{ + if (state == NULL || *state == NULL) + return; + + // deallocate memory + free(*state); + *state = NULL; + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void Pitch_fr_exit(Pitch_frState **state) +{ + if (state == NULL || *state == NULL) + return; + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pitch_fr +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to stat structure of type Pitch_frState + mode = codec mode of type enum Mode + T_op[] = pointer to open loop pitch lags of type Word16 + exc[] = pointer to excitation buffer of type Word16 + xn[] = pointer to target vector of type Word16 + h[] = pointer to impulse response of synthesis and weighting filters + of type Word16 + L_subfr = length of subframe of type Word16 + i_subfr = subframe offset of type Word16 + + Outputs: + pit_frac = pointer to pitch period (fractional) of type Word16 + resu3 = pointer to subsample resolution of type Word16 + ana_index = pointer to index of encoding of type Word16 + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + FUNCTION: Pitch_fr() + + PURPOSE: Find the pitch period with 1/3 or 1/6 subsample resolution + (closed loop). + + DESCRIPTION: + - find the normalized correlation between the target and filtered + past excitation in the search range. + - select the delay with maximum normalized correlation. + - interpolate the normalized correlation at fractions -3/6 to 3/6 + with step 1/6 around the chosen delay. + - The fraction which gives the maximum interpolated value is chosen. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 Pitch_fr ( // o : pitch period (integer) + Pitch_frState *st, // i/o : State struct + enum Mode mode, // i : codec mode + Word16 T_op[], // i : open loop pitch lags + Word16 exc[], // i : excitation buffer Q0 + Word16 xn[], // i : target vector Q0 + Word16 h[], // i : impulse response of synthesis and + weighting filters Q12 + Word16 L_subfr, // i : Length of subframe + Word16 i_subfr, // i : subframe offset + Word16 *pit_frac, // o : pitch period (fractional) + Word16 *resu3, // o : subsample resolution 1/3 (=1) or 1/6 (=0) + Word16 *ana_index // o : index of encoding +) +{ + Word16 i; + Word16 t_min, t_max; + Word16 t0_min, t0_max; + Word16 max, lag, frac; + Word16 tmp_lag; + Word16 *corr; + Word16 corr_v[40]; // Total length = t0_max-t0_min+1+2*L_INTER_SRCH + + Word16 max_frac_lag; + Word16 flag3, flag4; + Word16 last_frac; + Word16 delta_int_low, delta_int_range; + Word16 delta_frc_low, delta_frc_range; + Word16 pit_min; + Word16 frame_offset; + Word16 delta_search; + + //----------------------------------------------------------------------- + // set mode specific variables + //---------------------------------------------------------------------- + + max_frac_lag = mode_dep_parm[mode].max_frac_lag; + flag3 = mode_dep_parm[mode].flag3; + frac = mode_dep_parm[mode].first_frac; + last_frac = mode_dep_parm[mode].last_frac; + delta_int_low = mode_dep_parm[mode].delta_int_low; + delta_int_range = mode_dep_parm[mode].delta_int_range; + + delta_frc_low = mode_dep_parm[mode].delta_frc_low; + delta_frc_range = mode_dep_parm[mode].delta_frc_range; + pit_min = mode_dep_parm[mode].pit_min; + + //----------------------------------------------------------------------- + // decide upon full or differential search + //----------------------------------------------------------------------- + + delta_search = 1; + + if ((i_subfr == 0) || (sub(i_subfr,L_FRAME_BY2) == 0)) { + + // Subframe 1 and 3 + + if (((sub((Word16)mode, (Word16)MR475) != 0) && (sub((Word16)mode, + (Word16)MR515) != 0)) || + (sub(i_subfr,L_FRAME_BY2) != 0)) { + + // set t0_min, t0_max for full search + // this is *not* done for mode MR475, MR515 in subframe 3 + + delta_search = 0; // no differential search + + // calculate index into T_op which contains the open-loop + // pitch estimations for the 2 big subframes + + frame_offset = 1; + if (i_subfr == 0) + frame_offset = 0; + + // get T_op from the corresponding half frame and + // set t0_min, t0_max + + getRange (T_op[frame_offset], delta_int_low, delta_int_range, + pit_min, PIT_MAX, &t0_min, &t0_max); + } + else { + + // mode MR475, MR515 and 3. Subframe: delta search as well + getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range, + pit_min, PIT_MAX, &t0_min, &t0_max); + } + } + else { + + // for Subframe 2 and 4 + // get range around T0 of previous subframe for delta search + + getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range, + pit_min, PIT_MAX, &t0_min, &t0_max); + } + + //----------------------------------------------------------------------- + Find interval to compute normalized correlation + ----------------------------------------------------------------------- + + t_min = sub (t0_min, L_INTER_SRCH); + t_max = add (t0_max, L_INTER_SRCH); + + corr = &corr_v[-t_min]; + + //----------------------------------------------------------------------- + Compute normalized correlation between target and filtered excitation + ----------------------------------------------------------------------- + + Norm_Corr (exc, xn, h, L_subfr, t_min, t_max, corr); + + //----------------------------------------------------------------------- + Find integer pitch + ----------------------------------------------------------------------- + + max = corr[t0_min]; + lag = t0_min; + + for (i = t0_min + 1; i <= t0_max; i++) { + if (sub (corr[i], max) >= 0) { + max = corr[i]; + lag = i; + } + } + + //----------------------------------------------------------------------- + Find fractional pitch + ----------------------------------------------------------------------- + if ((delta_search == 0) && (sub (lag, max_frac_lag) > 0)) { + + // full search and integer pitch greater than max_frac_lag + // fractional search is not needed, set fractional to zero + + frac = 0; + } + else { + + // if differential search AND mode MR475 OR MR515 OR MR59 OR MR67 + // then search fractional with 4 bits resolution + + if ((delta_search != 0) && + ((sub ((Word16)mode, (Word16)MR475) == 0) || + (sub ((Word16)mode, (Word16)MR515) == 0) || + (sub ((Word16)mode, (Word16)MR59) == 0) || + (sub ((Word16)mode, (Word16)MR67) == 0))) { + + // modify frac or last_frac according to position of last + // integer pitch: either search around integer pitch, + // or only on left or right side + + tmp_lag = st->T0_prev_subframe; + if ( sub( sub(tmp_lag, t0_min), 5) > 0) + tmp_lag = add (t0_min, 5); + if ( sub( sub(t0_max, tmp_lag), 4) > 0) + tmp_lag = sub (t0_max, 4); + + if ((sub (lag, tmp_lag) == 0) || + (sub (lag, sub(tmp_lag, 1)) == 0)) { + + // normal search in fractions around T0 + + searchFrac (&lag, &frac, last_frac, corr, flag3); + + } + else if (sub (lag, sub (tmp_lag, 2)) == 0) { + // limit search around T0 to the right side + frac = 0; + searchFrac (&lag, &frac, last_frac, corr, flag3); + } + else if (sub (lag, add(tmp_lag, 1)) == 0) { + // limit search around T0 to the left side + last_frac = 0; + searchFrac (&lag, &frac, last_frac, corr, flag3); + } + else { + // no fractional search + frac = 0; + } + } + else + // test the fractions around T0 + searchFrac (&lag, &frac, last_frac, corr, flag3); + } + + //----------------------------------------------------------------------- + // encode pitch + //----------------------------------------------------------------------- + + if (flag3 != 0) { + // flag4 indicates encoding with 4 bit resolution; + // this is needed for mode MR475, MR515 and MR59 + + flag4 = 0; + if ( (sub ((Word16)mode, (Word16)MR475) == 0) || + (sub ((Word16)mode, (Word16)MR515) == 0) || + (sub ((Word16)mode, (Word16)MR59) == 0) || + (sub ((Word16)mode, (Word16)MR67) == 0) ) { + flag4 = 1; + } + + // encode with 1/3 subsample resolution + + *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe, + t0_min, t0_max, delta_search, flag4); + // function result + + } + else + { + // encode with 1/6 subsample resolution + + *ana_index = Enc_lag6(lag, frac, t0_min, delta_search); + // function result + } + + //----------------------------------------------------------------------- + // update state variables + //----------------------------------------------------------------------- + + st->T0_prev_subframe = lag; + + //----------------------------------------------------------------------- + // update output variables + //----------------------------------------------------------------------- + + *resu3 = flag3; + + *pit_frac = frac; + + return (lag); +} + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 Pitch_fr( /* o : pitch period (integer) */ + Pitch_frState *st, /* i/o : State struct */ + enum Mode mode, /* i : codec mode */ + Word16 T_op[], /* i : open loop pitch lags */ + Word16 exc[], /* i : excitation buffer Q0 */ + Word16 xn[], /* i : target vector Q0 */ + Word16 h[], /* i : impulse response of synthesis and + weighting filters Q12 */ + Word16 L_subfr, /* i : Length of subframe */ + Word16 i_subfr, /* i : subframe offset */ + Word16 *pit_frac, /* o : pitch period (fractional) */ + Word16 *resu3, /* o : subsample resolution 1/3 (=1) or 1/6 (=0) */ + Word16 *ana_index, /* o : index of encoding */ + Flag *pOverflow +) +{ + Word16 i; + Word16 t_min; + Word16 t_max; + Word16 t0_min = 0; + Word16 t0_max; + Word16 max; + Word16 lag; + Word16 frac; + Word16 tmp_lag; + Word16 *corr; + Word16 corr_v[40]; /* Total length = t0_max-t0_min+1+2*L_INTER_SRCH */ + + Word16 max_frac_lag; + Word16 flag3; + Word16 flag4; + Word16 last_frac; + Word16 delta_int_low; + Word16 delta_int_range; + Word16 delta_frc_low; + Word16 delta_frc_range; + Word16 pit_min; + Word16 frame_offset; + Word16 delta_search; + + /*-----------------------------------------------------------------------* + * set mode specific variables * + *-----------------------------------------------------------------------*/ + + max_frac_lag = mode_dep_parm[mode].max_frac_lag; + flag3 = mode_dep_parm[mode].flag3; + frac = mode_dep_parm[mode].first_frac; + last_frac = mode_dep_parm[mode].last_frac; + delta_int_low = mode_dep_parm[mode].delta_int_low; + delta_int_range = mode_dep_parm[mode].delta_int_range; + + delta_frc_low = mode_dep_parm[mode].delta_frc_low; + delta_frc_range = mode_dep_parm[mode].delta_frc_range; + pit_min = mode_dep_parm[mode].pit_min; + + /*-----------------------------------------------------------------------* + * decide upon full or differential search * + *-----------------------------------------------------------------------*/ + + delta_search = 1; + + if ((i_subfr == 0) || (i_subfr == L_FRAME_BY2)) + { + + /* Subframe 1 and 3 */ + + if (((mode != MR475) && (mode != MR515)) || (i_subfr != L_FRAME_BY2)) + { + + /* set t0_min, t0_max for full search */ + /* this is *not* done for mode MR475, MR515 in subframe 3 */ + + delta_search = 0; /* no differential search */ + + /* calculate index into T_op which contains the open-loop */ + /* pitch estimations for the 2 big subframes */ + + frame_offset = 1; + if (i_subfr == 0) + frame_offset = 0; + + /* get T_op from the corresponding half frame and */ + /* set t0_min, t0_max */ + + getRange(T_op[frame_offset], delta_int_low, delta_int_range, + pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow); + } + else + { + + /* mode MR475, MR515 and 3. Subframe: delta search as well */ + getRange(st->T0_prev_subframe, delta_frc_low, delta_frc_range, + pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow); + } + } + else + { + + /* for Subframe 2 and 4 */ + /* get range around T0 of previous subframe for delta search */ + + getRange(st->T0_prev_subframe, delta_frc_low, delta_frc_range, + pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow); + } + + /*-----------------------------------------------------------------------* + * Find interval to compute normalized correlation * + *-----------------------------------------------------------------------*/ + + t_min = t0_min - L_INTER_SRCH; + t_max = t0_max + L_INTER_SRCH; + + corr = &corr_v[-t_min]; + + /*-----------------------------------------------------------------------* + * Compute normalized correlation between target and filtered excitation * + *-----------------------------------------------------------------------*/ + + Norm_Corr(exc, xn, h, L_subfr, t_min, t_max, corr, pOverflow); + + /*-----------------------------------------------------------------------* + * Find integer pitch * + *-----------------------------------------------------------------------*/ + + max = corr[t0_min]; + lag = t0_min; + + for (i = t0_min + 1; i <= t0_max; i++) + { + if (corr[i] >= max) + { + max = corr[i]; + lag = i; + } + } + + /*-----------------------------------------------------------------------* + * Find fractional pitch * + *-----------------------------------------------------------------------*/ + if ((delta_search == 0) && (lag > max_frac_lag)) + { + + /* full search and integer pitch greater than max_frac_lag */ + /* fractional search is not needed, set fractional to zero */ + + frac = 0; + } + else + { + + /* if differential search AND mode MR475 OR MR515 OR MR59 OR MR67 */ + /* then search fractional with 4 bits resolution */ + + if ((delta_search != 0) && + ((mode == MR475) || (mode == MR515) || + (mode == MR59) || (mode == MR67))) + { + + /* modify frac or last_frac according to position of last */ + /* integer pitch: either search around integer pitch, */ + /* or only on left or right side */ + + tmp_lag = st->T0_prev_subframe; + if ((tmp_lag - t0_min) > 5) + { + tmp_lag = t0_min + 5; + } + if ((t0_max - tmp_lag) > 4) + { + tmp_lag = t0_max - 4; + } + + if ((lag == tmp_lag) || (lag == (tmp_lag - 1))) + { + + /* normal search in fractions around T0 */ + + searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow); + + } + else if (lag == (tmp_lag - 2)) + { + /* limit search around T0 to the right side */ + frac = 0; + searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow); + } + else if (lag == (tmp_lag + 1)) + { + /* limit search around T0 to the left side */ + last_frac = 0; + searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow); + } + else + { + /* no fractional search */ + frac = 0; + } + } + else + /* test the fractions around T0 */ + searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow); + } + + /*-----------------------------------------------------------------------* + * encode pitch * + *-----------------------------------------------------------------------*/ + + if (flag3 != 0) + { + /* flag4 indicates encoding with 4 bit resolution; */ + /* this is needed for mode MR475, MR515 and MR59 */ + + flag4 = 0; + if ((mode == MR475) || (mode == MR515) || + (mode == MR59) || (mode == MR67)) + { + flag4 = 1; + } + + /* encode with 1/3 subsample resolution */ + + *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe, + t0_min, t0_max, delta_search, flag4, pOverflow); + /* function result */ + + } + else + { + /* encode with 1/6 subsample resolution */ + + *ana_index = Enc_lag6(lag, frac, t0_min, delta_search, pOverflow); + /* function result */ + } + + /*-----------------------------------------------------------------------* + * update state variables * + *-----------------------------------------------------------------------*/ + + st->T0_prev_subframe = lag; + + /*-----------------------------------------------------------------------* + * update output variables * + *-----------------------------------------------------------------------*/ + + *resu3 = flag3; + + *pit_frac = frac; + + return (lag); +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pitch_fr.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pitch_fr.h new file mode 100644 index 00000000..f48d171a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pitch_fr.h @@ -0,0 +1,137 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pitch_fr.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : pitch_fr.h + Purpose : Find the pitch period with 1/3 or 1/6 subsample + : resolution (closed loop). + +------------------------------------------------------------------------------ +*/ + +#ifndef _PITCH_FR_H_ +#define _PITCH_FR_H_ +#define pitch_fr_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 T0_prev_subframe; /* integer pitch lag of previous sub-frame */ + } Pitch_frState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + Word16 Pitch_fr_init(Pitch_frState **st); + /* initialize one instance of the pre processing state. + Stores pointer to filter status struct in *st. This pointer has to + be passed to Pitch_fr in each call. + returns 0 on success + */ + + Word16 Pitch_fr_reset(Pitch_frState *st); + /* reset of pre processing state (i.e. set state memory to zero) + returns 0 on success + */ + + void Pitch_fr_exit(Pitch_frState **st); + /* de-initialize pre processing state (i.e. free status struct) + stores NULL in *st + */ + + Word16 Pitch_fr( /* o : pitch period (integer) */ + Pitch_frState *st, /* i/o : State struct */ + enum Mode mode, /* i : codec mode */ + Word16 T_op[], /* i : open loop pitch lags */ + Word16 exc[], /* i : excitation buffer */ + Word16 xn[], /* i : target vector */ + Word16 h[], /* i : impulse response of synthesis and + weighting filters */ + Word16 L_subfr, /* i : Length of subframe */ + Word16 i_subfr, /* i : subframe offset */ + Word16 *pit_frac, /* o : pitch period (fractional) */ + Word16 *resu3, /* o : subsample resolution 1/3 (=1) or 1/6 (=0) */ + Word16 *ana_index, /* o : index of encoding */ + Flag *pOverflow + ); + +#ifdef __cplusplus +} +#endif + +#endif /* _PITCH_FR_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pitch_ol.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pitch_ol.cpp new file mode 100644 index 00000000..d8efa1ee --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pitch_ol.cpp @@ -0,0 +1,1165 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pitch_ol.cpp + Funtions: Pitch_ol + Lag_max + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + The modules in this file compute the open loop pitch lag. +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "pitch_ol.h" +#include "typedef.h" +#include "basicop_malloc.h" +#include "cnst.h" +#include "inv_sqrt.h" +#include "vad.h" +#include "calc_cor.h" +#include "hp_max.h" +#include "oscl_mem.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define THRESHOLD 27853 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Lag_max +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS (If VAD2 is defined) + + Inputs + corr = pointer to buffer of correlation values (Word32) + scal_sig = pointer to buffer of scaled signal values (Word16) + scal_fac = scaled signal factor (Word16) + scal_flag = EFR compatible scaling flag (Word16) + L_frame = length of frame to compute pitch (Word16) + lag_max = maximum lag (Word16) + lag_min = minimum lag (Word16) + cor_max = pointer to the normalized correlation of selected lag (Word16) + rmax = pointer to max(), (Word32) + r0 = pointer to the residual energy (Word32) + dtx = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag) + + Outputs: + cor_max contains the newly calculated normalized correlation of the + selected lag + rmax contains the newly calculated max() + r0 contains the newly calculated residual energy + + Returns: + p_max = lag of the max correlation found (Word16) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS (If VAD2 is not defined) + + Inputs + vadSt = pointer to a vadState structure + corr = pointer to buffer of correlation values (Word32) + scal_sig = pointer to buffer of scaled signal values (Word16) + scal_fac = scaled signal factor (Word16) + scal_flag = EFR compatible scaling flag (Word16) + L_frame = length of frame to compute pitch (Word16) + lag_max = maximum lag (Word16) + lag_min = minimum lag (Word16) + cor_max = pointer to the normalized correlation of selected lag (Word16) + dtx = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag) + pOverflow = pointer to overflow indicator (Flag) + + Outputs: + cor_max contains the newly calculated normalized correlation of the + selected lag + vadSt contains the updated VAD state parameters + pOverflow -> 1 if the math operations called by this routine saturate + + Returns: + p_max = lag of the max correlation found (Word16) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Find the lag that has maximum correlation of scal_sig in a given delay range. + The correlation is given by: + + cor[t] = , t=lag_min,...,lag_max + + The function returns the maximum correlation after normalization and the + corresponding lag. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +#ifdef VAD2 +static Word16 Lag_max ( // o : lag found + Word32 corr[], // i : correlation vector. + Word16 scal_sig[], // i : scaled signal. + Word16 scal_fac, // i : scaled signal factor. + Word16 scal_flag, // i : if 1 use EFR compatible scaling + Word16 L_frame, // i : length of frame to compute pitch + Word16 lag_max, // i : maximum lag + Word16 lag_min, // i : minimum lag + Word16 *cor_max, // o : normalized correlation of selected lag + Word32 *rmax, // o : max() + Word32 *r0, // o : residual energy + Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0 + ) +#else +static Word16 Lag_max ( // o : lag found + vadState *vadSt, // i/o : VAD state struct + Word32 corr[], // i : correlation vector. + Word16 scal_sig[], // i : scaled signal. + Word16 scal_fac, // i : scaled signal factor. + Word16 scal_flag, // i : if 1 use EFR compatible scaling + Word16 L_frame, // i : length of frame to compute pitch + Word16 lag_max, // i : maximum lag + Word16 lag_min, // i : minimum lag + Word16 *cor_max, // o : normalized correlation of selected lag + Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0 + ) +#endif +{ + Word16 i, j; + Word16 *p; + Word32 max, t0; + Word16 max_h, max_l, ener_h, ener_l; + Word16 p_max = 0; // initialization only needed to keep gcc silent + + max = MIN_32; + p_max = lag_max; + + for (i = lag_max, j = (PIT_MAX-lag_max-1); i >= lag_min; i--, j--) + { + if (L_sub (corr[-i], max) >= 0) + { + max = corr[-i]; + p_max = i; + } + } + + // compute energy + + t0 = 0; + p = &scal_sig[-p_max]; + for (i = 0; i < L_frame; i++, p++) + { + t0 = L_mac (t0, *p, *p); + } + // 1/sqrt(energy) + + if (dtx) + { // no test() call since this if is only in simulation env +#ifdef VAD2 + *rmax = max; + *r0 = t0; +#else + // check tone + vad_tone_detection (vadSt, max, t0); +#endif + } + + t0 = Inv_sqrt (t0); + + if (scal_flag) + { + t0 = L_shl (t0, 1); + } + + // max = max/sqrt(energy) + + L_Extract (max, &max_h, &max_l); + L_Extract (t0, &ener_h, &ener_l); + + t0 = Mpy_32 (max_h, max_l, ener_h, ener_l); + + if (scal_flag) + { + t0 = L_shr (t0, scal_fac); + *cor_max = extract_h (L_shl (t0, 15)); // divide by 2 + } + else + { + *cor_max = extract_l(t0); + } + + return (p_max); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +#ifdef VAD2 +static Word16 Lag_max( /* o : lag found */ + Word32 corr[], /* i : correlation vector. */ + Word16 scal_sig[], /* i : scaled signal. */ + Word16 scal_fac, /* i : scaled signal factor. */ + Word16 scal_flag, /* i : if 1 use EFR compatible scaling */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word16 *cor_max, /* o : normalized correlation of selected lag */ + Word32 *rmax, /* o : max() */ + Word32 *r0, /* o : residual energy */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow Flag */ +) +#else +static Word16 Lag_max( /* o : lag found */ + vadState *vadSt, /* i/o : VAD state struct */ + Word32 corr[], /* i : correlation vector. */ + Word16 scal_sig[], /* i : scaled signal. */ + Word16 scal_fac, /* i : scaled signal factor. */ + Word16 scal_flag, /* i : if 1 use EFR compatible scaling */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word16 *cor_max, /* o : normalized correlation of selected lag */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow Flag */ +) +#endif +{ + register Word16 i; + Word16 *p; + Word32 max; + Word32 t0; + Word16 max_h; + Word16 max_l; + Word16 ener_h; + Word16 ener_l; + Word16 p_max = 0; /* initialization only needed to keep gcc silent */ + Word32 L_temp; + Word32 L_temp_2; + Word32 L_temp_3; + Word32 *p_corr = &corr[-lag_max]; + + max = MIN_32; + p_max = lag_max; + + for (i = lag_max; i >= lag_min; i--) + { + /* The negative array index is equivalent to a negative */ + /* address offset, i.e., corr[-i] == *(corr - i) */ + if (*(p_corr++) >= max) + { + p_corr--; + max = *(p_corr++); + p_max = i; + } + } + + /* compute energy */ + + t0 = 0; + + /* The negative array index is equivalent to a negative */ + /* address offset, i.e., scal_sig[-p_max] == *(scal_sig - p_max) */ + p = &scal_sig[-p_max]; + for (i = (L_frame >> 2); i != 0; i--) + { + t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0); + p++; + t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0); + p++; + t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0); + p++; + t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0); + p++; + } + + t0 <<= 1; + /* 1/sqrt(energy) */ + + if (dtx) + { /* no test() call since this if is only in simulation env */ + /* check tone */ +#ifdef VAD2 + *rmax = max; + *r0 = t0; +#else + /* check tone */ + vad_tone_detection(vadSt, max, t0, pOverflow); +#endif + } + + t0 = Inv_sqrt(t0, pOverflow); + + if (scal_flag) + { + if (t0 > (Word32) 0x3fffffffL) + { + t0 = MAX_32; + } + else + { + t0 = t0 << 1; + } + } + + /* max = max/sqrt(energy) */ + /* The following code is an inlined version of */ + /* L_Extract (max, &max_h, &max_l), i.e. */ + /* */ + /* *max_h = extract_h (max); */ + max_h = (Word16)(max >> 16); + + /* L_temp_2 = L_shr(max,1), which is used in */ + /* the calculation of *max_l (see next operation) */ + L_temp_2 = max >> 1; + + /* *max_l = extract_l (L_msu (L_shr (max, 1), *max_h, 16384)); */ + L_temp_3 = (Word32)(max_h << 15); + + L_temp = L_temp_2 - L_temp_3; + + max_l = (Word16)L_temp; + + /* The following code is an inlined version of */ + /* L_Extract (t0, &ener_h, &ener_l), i.e. */ + /* */ + /* *ener_h = extract_h (t0); */ + ener_h = (Word16)(t0 >> 16); + + /* L_temp_2 = L_shr(t0,1), which is used in */ + /* the calculation of *ener_l (see next operation) */ + + L_temp_2 = t0 >> 1; + + L_temp_3 = (Word32)(ener_h << 15); + + L_temp = L_temp_2 - L_temp_3; + + ener_l = (Word16)L_temp; + + t0 = Mpy_32(max_h, max_l, ener_h, ener_l, pOverflow); + + if (scal_flag) + { + t0 = L_shr(t0, scal_fac, pOverflow); + + if (t0 > (Word32) 0X0000FFFFL) + { + *cor_max = MAX_16; + } + else if (t0 < (Word32) 0xFFFF0000L) + { + *cor_max = MIN_16; + } + else + { + *cor_max = (Word16)(t0 >> 1); + } + } + else + { + *cor_max = (Word16)t0; + } + + return (p_max); +} + +/*---------------------------------------------------------------------------- +; End Function: Lag_max +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Lag_max_wrapper +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs + corr = pointer to buffer of correlation values (Word32) + scal_sig = pointer to buffer of scaled signal values (Word16) + scal_fac = scaled signal factor (Word16) + scal_flag = EFR compatible scaling flag (Word16) + L_frame = length of frame to compute pitch (Word16) + lag_max = maximum lag (Word16) + lag_min = minimum lag (Word16) + cor_max = pointer to the normalized correlation of selected lag (Word16) + rmax = pointer to max(), (Word32) + r0 = pointer to the residual energy (Word32) + dtx = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag) + pOverflow = pointer to overflow indicator (Flag) + + Outputs: + cor_max contains the newly calculated normalized correlation of the + selected lag + rmax contains the newly calculated max() + r0 contains the newly calculated residual energy + pOverflow -> 1 if the math operations called by this routine saturate + + Returns: + p_max = lag of the max correlation found (Word16) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS (If VAD2 is not defined) + + Inputs + vadSt = pointer to a vadState structure + corr = pointer to buffer of correlation values (Word32) + scal_sig = pointer to buffer of scaled signal values (Word16) + scal_fac = scaled signal factor (Word16) + scal_flag = EFR compatible scaling flag (Word16) + L_frame = length of frame to compute pitch (Word16) + lag_max = maximum lag (Word16) + lag_min = minimum lag (Word16) + cor_max = pointer to the normalized correlation of selected lag (Word16) + dtx = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag) + pOverflow = pointer to overflow indicator (Flag) + + Outputs: + cor_max contains the newly calculated normalized correlation of the + selected lag + vadSt contains the updated VAD state parameters + pOverflow -> 1 if the math operations called by this routine saturate + + Returns: + p_max = lag of the max correlation found (Word16) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function provides external access to the local function Lag_max. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +#ifdef VAD2 + CALL Lag_max(corr = corr + scal_sig = scal_sig + scal_fac = scal_fac + scal_flag = scal_flag + L_frame = L_frame + lag_max = lag_max + lag_min = lag_min + cor_max = cor_max + rmax = rmax + r0 = r0 + dtx = dtx + pOverflow = pOverflow) + MODIFYING(nothing) + RETURNING(temp) + +#else + CALL Lag_max(vadSt = vadSt + corr = corr + scal_sig = scal_sig + scal_fac = scal_fac + scal_flag = scal_flag + L_frame = L_frame + lag_max = lag_max + lag_min = lag_min + cor_max = cor_max + dtx = dtx + pOverflow = pOverflow) + MODIFYING(nothing) + RETURNING(temp) + +#endif + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +#ifdef VAD2 +Word16 Lag_max_wrapper( /* o : lag found */ + Word32 corr[], /* i : correlation vector. */ + Word16 scal_sig[], /* i : scaled signal. */ + Word16 scal_fac, /* i : scaled signal factor. */ + Word16 scal_flag, /* i : if 1 use EFR compatible scaling */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word16 *cor_max, /* o : normalized correlation of selected lag */ + Word32 *rmax, /* o : max() */ + Word32 *r0, /* o : residual energy */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow Flag */ +) +{ + Word16 temp; + + temp = Lag_max(corr, scal_sig, scal_fac, scal_flag, L_frame, lag_max, + lag_min, cor_max, rmax, r0, dtx, pOverflow); + + return(temp); +} + +#else +Word16 Lag_max_wrapper( /* o : lag found */ + vadState *vadSt, /* i/o : VAD state struct */ + Word32 corr[], /* i : correlation vector. */ + Word16 scal_sig[], /* i : scaled signal. */ + Word16 scal_fac, /* i : scaled signal factor. */ + Word16 scal_flag, /* i : if 1 use EFR compatible scaling */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word16 *cor_max, /* o : normalized correlation of selected lag */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow Flag */ +) +{ + Word16 temp; + + temp = Lag_max(vadSt, corr, scal_sig, scal_fac, scal_flag, L_frame, + lag_max, lag_min, cor_max, dtx, pOverflow); + + return(temp); +} + +#endif + +/*---------------------------------------------------------------------------- +; End Function: Lag_max_wrapper +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pitch_ol +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + vadSt = pointer to a vadState structure + mode = data of type enum Mode specifies the mode. + signal = pointer to buffer of signal used to compute the open loop + pitch + where signal[-pit_max] to signal[-1] should be known + pit_min = 16 bit value specifies the minimum pitch lag + pit_max = 16 bit value specifies the maximum pitch lag + L_frame = 16 bit value specifies the length of frame to compute pitch + idx = 16 bit value specifies the frame index + dtx = Data of type 'Flag' used for dtx. Use dtx=1, do not use dtx=0 + pOverflow = pointer to overflow indicator (Flag) + + Outputs + vadSt = The vadSt state structure may be modified. + pOverflow -> 1 if the math operations called by this routine saturate + + Returns: + p_max1 = 16 bit value representing the open loop pitch lag. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes the open loop pitch lag based on the perceptually + weighted speech signal. This is done in the following steps: + - find three maxima of the correlation , + dividing the search range into three parts: + pit_min ... 2*pit_min-1 + 2*pit_min ... 4*pit_min-1 + 4*pit_min ... pit_max + - divide each maximum by where t is the delay at + that maximum correlation. + - select the delay of maximum normalized correlation (among the + three candidates) while favoring the lower delay ranges. + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 Pitch_ol ( // o : open loop pitch lag + vadState *vadSt, // i/o : VAD state struct + enum Mode mode, // i : coder mode + Word16 signal[], // i : signal used to compute the open loop pitch + // signal[-pit_max] to signal[-1] should be known + Word16 pit_min, // i : minimum pitch lag + Word16 pit_max, // i : maximum pitch lag + Word16 L_frame, // i : length of frame to compute pitch + Word16 idx, // i : frame index + Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0 + ) +{ + Word16 i, j; + Word16 max1, max2, max3; + Word16 p_max1, p_max2, p_max3; + Word16 scal_flag = 0; + Word32 t0; +#ifdef VAD2 + Word32 r01, r02, r03; + Word32 rmax1, rmax2, rmax3; +#else + Word16 corr_hp_max; +#endif + Word32 corr[PIT_MAX+1], *corr_ptr; + + // Scaled signal + + Word16 scaled_signal[L_FRAME + PIT_MAX]; + Word16 *scal_sig, scal_fac; + +#ifndef VAD2 + if (dtx) + { // no test() call since this if is only in simulation env + // update tone detection + if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0)) + { + vad_tone_detection_update (vadSt, 1); + } + else + { + vad_tone_detection_update (vadSt, 0); + } + } +#endif + + scal_sig = &scaled_signal[pit_max]; + + t0 = 0L; + for (i = -pit_max; i < L_frame; i++) + { + t0 = L_mac (t0, signal[i], signal[i]); + } + + *--------------------------------------------------------* + * Scaling of input signal. * + * * + * if Overflow -> scal_sig[i] = signal[i]>>3 * + * else if t0 < 1^20 -> scal_sig[i] = signal[i]<<3 * + * else -> scal_sig[i] = signal[i] * + *--------------------------------------------------------* + + *--------------------------------------------------------* + * Verification for risk of overflow. * + *--------------------------------------------------------* + + if (L_sub (t0, MAX_32) == 0L) // Test for overflow + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = shr (signal[i], 3); + } + scal_fac = 3; + } + else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0) + // if (t0 < 2^20) + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = shl (signal[i], 3); + } + scal_fac = -3; + } + else + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = signal[i]; + } + scal_fac = 0; + } + + // calculate all coreelations of scal_sig, from pit_min to pit_max + corr_ptr = &corr[pit_max]; + comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr); + + *--------------------------------------------------------------------* + * The pitch lag search is divided in three sections. * + * Each section cannot have a pitch multiple. * + * We find a maximum for each section. * + * We compare the maximum of each section by favoring small lags. * + * * + * First section: lag delay = pit_max downto 4*pit_min * + * Second section: lag delay = 4*pit_min-1 downto 2*pit_min * + * Third section: lag delay = 2*pit_min-1 downto pit_min * + *--------------------------------------------------------------------* + + // mode dependent scaling in Lag_max + if (sub(mode, MR122) == 0) + { + scal_flag = 1; + } + else + { + scal_flag = 0; + } + +#ifdef VAD2 + j = shl (pit_min, 2); + p_max1 = Lag_max (corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + pit_max, j, &max1, &rmax1, &r01, dtx); + + i = sub (j, 1); + j = shl (pit_min, 1); + p_max2 = Lag_max (corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, j, &max2, &rmax2, &r02, dtx); + + i = sub (j, 1); + p_max3 = Lag_max (corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, pit_min, &max3, &rmax3, &r03, dtx); +#else + j = shl (pit_min, 2); + p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + pit_max, j, &max1, dtx); + + i = sub (j, 1); + j = shl (pit_min, 1); + p_max2 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, j, &max2, dtx); + + i = sub (j, 1); + p_max3 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, pit_min, &max3, dtx); + + if (dtx) + { // no test() call since this if is only in simulation env + if (sub(idx, 1) == 0) + { + // calculate max high-passed filtered correlation of all lags + hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max); + + // update complex background detector + vad_complex_detection_update(vadSt, corr_hp_max); + } + } +#endif + + *--------------------------------------------------------------------* + * Compare the 3 sections maximum, and favor small lag. * + *--------------------------------------------------------------------* + + if (sub (mult (max1, THRESHOLD), max2) < 0) + { + max1 = max2; + p_max1 = p_max2; +#ifdef VAD2 + if (dtx) + { + rmax1 = rmax2; + r01 = r02; +#endif + } + if (sub (mult (max1, THRESHOLD), max3) < 0) + { + p_max1 = p_max3; +#ifdef VAD2 + if (dtx) + { + rmax1 = rmax3; + r01 = r03; + } +#endif + } + +#ifdef VAD2 + if (dtx) + { + vadSt->L_Rmax = L_add(vadSt->L_Rmax, rmax1); // Save max correlation + vadSt->L_R0 = L_add(vadSt->L_R0, r01); // Save max energy + } +#endif + + return (p_max1); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Pitch_ol( /* o : open loop pitch lag */ + vadState *vadSt, /* i/o : VAD state struct */ + enum Mode mode, /* i : coder mode */ + Word16 signal[], /* i : signal used to compute the open loop pitch */ + /* signal[-pit_max] to signal[-1] should be known */ + Word16 pit_min, /* i : minimum pitch lag */ + Word16 pit_max, /* i : maximum pitch lag */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 idx, /* i : frame index */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow Flag */ +) +{ + Word16 i; + Word16 j; + Word16 max1; + Word16 max2; + Word16 max3; + Word16 p_max1; + Word16 p_max2; + Word16 p_max3; + Word16 scal_flag = 0; + Word32 t0; + +#ifdef VAD2 + Word32 r01; + Word32 r02; + Word32 r03; + Word32 rmax1; + Word32 rmax2; + Word32 rmax3; +#else + Word16 corr_hp_max; +#endif + Word32 corr[PIT_MAX+1]; + Word32 *corr_ptr; + + /* Scaled signal */ + + Word16 scaled_signal[L_FRAME + PIT_MAX]; + Word16 *scal_sig; + Word16 *p_signal; + Word16 scal_fac; + Word32 L_temp; + +#ifndef VAD2 + if (dtx) + { /* no test() call since this if is only in simulation env */ + /* update tone detection */ + if ((mode == MR475) || (mode == MR515)) + { + vad_tone_detection_update(vadSt, 1, pOverflow); + } + else + { + vad_tone_detection_update(vadSt, 0, pOverflow); + } + } +#endif + + + t0 = 0L; + p_signal = &signal[-pit_max]; + + for (i = -pit_max; i < L_frame; i++) + { + t0 += (((Word32) * (p_signal)) * *(p_signal)) << 1; + p_signal++; + if (t0 < 0) + { + t0 = MAX_32; + break; + } + + } + + /*--------------------------------------------------------* + * Scaling of input signal. * + * * + * if Overflow -> scal_sig[i] = signal[i]>>3 * + * else if t0 < 1^20 -> scal_sig[i] = signal[i]<<3 * + * else -> scal_sig[i] = signal[i] * + *--------------------------------------------------------*/ + + /*--------------------------------------------------------* + * Verification for risk of overflow. * + *--------------------------------------------------------*/ + + scal_sig = &scaled_signal[0]; + p_signal = &signal[-pit_max]; + + if (t0 == MAX_32) /* Test for overflow */ + { + + for (i = (pit_max + L_frame) >> 1; i != 0; i--) + { + *(scal_sig++) = (Word16)(((Word32) * (p_signal++) >> 3)); + *(scal_sig++) = (Word16)(((Word32) * (p_signal++) >> 3)); + } + + if ((pit_max + L_frame) & 1) + { + *(scal_sig) = (Word16)(((Word32) * (p_signal) >> 3)); + } + + scal_fac = 3; + } + else if (t0 < (Word32)1048576L) + /* if (t0 < 2^20) */ + { + for (i = (pit_max + L_frame) >> 1; i != 0; i--) + { + *(scal_sig++) = (Word16)(((Word32) * (p_signal++) << 3)); + *(scal_sig++) = (Word16)(((Word32) * (p_signal++) << 3)); + } + + if ((pit_max + L_frame) & 1) + { + *(scal_sig) = (Word16)(((Word32) * (p_signal) << 3)); + } + scal_fac = -3; + } + else + { + + oscl_memcpy(scal_sig, p_signal, (L_frame + pit_max)*sizeof(*signal)); + scal_fac = 0; + } + + /* calculate all coreelations of scal_sig, from pit_min to pit_max */ + corr_ptr = &corr[pit_max]; + + scal_sig = &scaled_signal[pit_max]; + + comp_corr(scal_sig, L_frame, pit_max, pit_min, corr_ptr); + + /*--------------------------------------------------------------------* + * The pitch lag search is divided in three sections. * + * Each section cannot have a pitch multiple. * + * We find a maximum for each section. * + * We compare the maximum of each section by favoring small lags. * + * * + * First section: lag delay = pit_max downto 4*pit_min * + * Second section: lag delay = 4*pit_min-1 downto 2*pit_min * + * Third section: lag delay = 2*pit_min-1 downto pit_min * + *--------------------------------------------------------------------*/ + + /* mode dependent scaling in Lag_max */ + + if (mode == MR122) + { + scal_flag = 1; + } + else + { + scal_flag = 0; + } + +#ifdef VAD2 + L_temp = ((Word32)pit_min) << 2; + if (L_temp != (Word32)((Word16) L_temp)) + { + *pOverflow = 1; + j = (pit_min > 0) ? MAX_16 : MIN_16; + } + else + { + j = (Word16)L_temp; + } + + p_max1 = Lag_max(corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + pit_max, j, &max1, &rmax1, &r01, dtx, pOverflow); + + i = j - 1; + + j = pit_min << 1; + + p_max2 = Lag_max(corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, j, &max2, &rmax2, &r02, dtx, pOverflow); + + i = j - 1; + + p_max3 = Lag_max(corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, pit_min, &max3, &rmax3, &r03, dtx, pOverflow); + +#else + L_temp = ((Word32)pit_min) << 2; + if (L_temp != (Word32)((Word16) L_temp)) + { + *pOverflow = 1; + j = (pit_min > 0) ? MAX_16 : MIN_16; + } + else + { + j = (Word16)L_temp; + } + + p_max1 = Lag_max(vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + pit_max, j, &max1, dtx, pOverflow); + + i = j - 1; + + + j = pit_min << 1; + + + p_max2 = Lag_max(vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, j, &max2, dtx, pOverflow); + + i = j - 1; + p_max3 = Lag_max(vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, pit_min, &max3, dtx, pOverflow); + + if (dtx) + { /* no test() call since this if is only in simulation env */ + + if (idx == 1) + { + /* calculate max high-passed filtered correlation of all lags */ + hp_max(corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max, + pOverflow); + + /* update complex background detector */ + vad_complex_detection_update(vadSt, corr_hp_max); + } + } +#endif + + /*--------------------------------------------------------------------* + * Compare the 3 sections maximum, and favor small lag. * + *--------------------------------------------------------------------*/ + + i = (Word16)(((Word32)max1 * THRESHOLD) >> 15); + + if (i < max2) + { + max1 = max2; + p_max1 = p_max2; + +#ifdef VAD2 + if (dtx) + { + rmax1 = rmax2; + r01 = r02; + } +#endif + } + + i = (Word16)(((Word32)max1 * THRESHOLD) >> 15); + + + if (i < max3) + { + p_max1 = p_max3; + +#ifdef VAD2 + if (dtx) + { + rmax1 = rmax3; + r01 = r03; + } +#endif + } + +#ifdef VAD2 + if (dtx) + { + /* Save max correlation */ + vadSt->L_Rmax = L_add(vadSt->L_Rmax, rmax1, pOverflow); + /* Save max energy */ + vadSt->L_R0 = L_add(vadSt->L_R0, r01, pOverflow); + } +#endif + + return (p_max1); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pitch_ol.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pitch_ol.h new file mode 100644 index 00000000..9b25895e --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pitch_ol.h @@ -0,0 +1,113 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pitch_ol.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : pitch_ol.h + Purpose : Compute the open loop pitch lag. + +------------------------------------------------------------------------------ +*/ + +#ifndef PITCH_OL_H +#define PITCH_OL_H "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "vad.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + Word16 Pitch_ol( /* o : open loop pitch lag */ + vadState *vadSt, /* i/o : VAD state struct */ + enum Mode mode, /* i : coder mode */ + Word16 signal[], /* i : signal used to compute the open loop pitch */ + /* signal[-pit_max] to signal[-1] should be known */ + Word16 pit_min, /* i : minimum pitch lag */ + Word16 pit_max, /* i : maximum pitch lag */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 idx, /* i : frame index */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow Flag */ + ); + + +#ifdef __cplusplus +} +#endif + +#endif /* PITCH_OL_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pre_big.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pre_big.cpp new file mode 100644 index 00000000..b0fcf754 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pre_big.cpp @@ -0,0 +1,181 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pre_big.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Big subframe (2 subframes) preprocessing +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "pre_big.h" +#include "typedef.h" +#include "basic_op.h" +#include "syn_filt.h" +#include "weight_a.h" +#include "residu.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: pre_big +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + mode = enum Mode -- coder mode + gamma1 = array of type const Word16 -- spectral exp. factor 1 + gamma1_12k2 = array of type const Word16 -- spectral exp. factor 1 for EFR + gamma2 = array of type const Word16 -- spectral exp. factor 2 + A_t = array of type Word16 -- A(z) unquantized, for 4 subframes, Q12 + frameOffset = Word16 -- Start position in speech vector, Q0 + speech[] = array of type Word16 -- speech, Q0 + + Outputs: + mem_w = array of type Word16 -- synthesis filter memory state, Q0 + wsp = array of type Word16 -- weighted speech Q0 + pOverflow = pointer of type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pre_big.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void pre_big( + enum Mode mode, /* i : coder mode */ + const Word16 gamma1[], /* i : spectral exp. factor 1 */ + const Word16 gamma1_12k2[],/* i : spectral exp. factor 1 for EFR */ + const Word16 gamma2[], /* i : spectral exp. factor 2 */ + Word16 A_t[], /* i : A(z) unquantized, for 4 subframes, Q12 */ + Word16 frameOffset, /* i : Start position in speech vector, Q0 */ + Word16 speech[], /* i : speech, Q0 */ + Word16 mem_w[], /* i/o: synthesis filter memory state, Q0 */ + Word16 wsp[], /* o : weighted speech Q0 */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + Word16 Ap1[MP1]; /* A(z) with spectral expansion */ + Word16 Ap2[MP1]; /* A(z) with spectral expansion */ + const Word16 *g1; /* Pointer to correct gammma1 vector */ + Word16 aOffset; + Word16 i; + + if (mode <= MR795) + { + g1 = gamma1; + } + else + { + g1 = gamma1_12k2; + } + + if (frameOffset > 0) + { + aOffset = MP1 << 1; + } + else + { + aOffset = 0; + } + + /* process two subframes (which form the "big" subframe) */ + for (i = 0; i < 2; i++) + { + Weight_Ai(&A_t[aOffset], g1, Ap1); + Weight_Ai(&A_t[aOffset], gamma2, Ap2); + Residu(Ap1, &speech[frameOffset], &wsp[frameOffset], L_SUBFR); + + Syn_filt(Ap2, &wsp[frameOffset], &wsp[frameOffset], L_SUBFR, mem_w, 1); + + aOffset += MP1; + + frameOffset += L_SUBFR; + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pre_big.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pre_big.h new file mode 100644 index 00000000..590750d1 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pre_big.h @@ -0,0 +1,117 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pre_big.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the file, pre_big.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef pre_big_h +#define pre_big_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "cnst.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void pre_big( + enum Mode mode, /* i : coder mode */ + const Word16 gamma1[], /* i : spectral exp. factor 1 */ + const Word16 gamma1_12k2[],/* i : spectral exp. factor 1 for EFR */ + const Word16 gamma2[], /* i : spectral exp. factor 2 */ + Word16 A_t[], /* i : A(z) unquantized, for 4 subframes, Q12 */ + Word16 frameOffset, /* i : Start position in speech vector, Q0 */ + Word16 speech[], /* i : speech, Q0 */ + Word16 mem_w[], /* i/o: synthesis filter memory state, Q0 */ + Word16 wsp[], /* o : weighted speech Q0 */ + Flag *pOverflow /* o : overflow indicator */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _H_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pre_proc.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pre_proc.cpp new file mode 100644 index 00000000..93d23b55 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pre_proc.cpp @@ -0,0 +1,483 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pre_proc.cpp + Funtions: Pre_Process_init + Pre_Process_reset + Pre_Process_exit + Pre_Process + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + These modules handle the preprocessing of input speech. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "pre_proc.h" +#include "typedef.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pre_Process_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to an array of pointer to structures of type + Pre_ProcessState + + Outputs: + Structure pointed to by the pointer pointed to by state is + initialized to its reset value + state points to the allocated memory + + Returns: + return_value = 0 if memory was successfully initialized, + otherwise returns -1. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Allocates state memory and initializes state memory. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Pre_Process_init (Pre_ProcessState **state) +{ + Pre_ProcessState* s; + + if (state == (Pre_ProcessState **) NULL){ + fprintf(stderr, "Pre_Process_init: invalid parameter\n"); + return -1; + } + *state = NULL; + + // allocate memory + if ((s= (Pre_ProcessState *) malloc(sizeof(Pre_ProcessState))) == NULL){ + fprintf(stderr, "Pre_Process_init: can not malloc state structure\n"); + return -1; + } + + Pre_Process_reset(s); + *state = s; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Pre_Process_init(Pre_ProcessState **state) +{ + Pre_ProcessState* s; + + if (state == (Pre_ProcessState **) NULL) + { + /* fprintf(stderr, "Pre_Process_init: invalid parameter\n"); */ + return(-1); + } + *state = NULL; + + /* allocate memory */ + if ((s = (Pre_ProcessState *) oscl_malloc(sizeof(Pre_ProcessState))) == NULL) + { + /* fprintf(stderr, "Pre_Process_init: + can not malloc state structure\n"); */ + return(-1); + } + + Pre_Process_reset(s); + *state = s; + + return(0); +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pre_Process_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to structure of type Pre_ProcessState + + Outputs: + Structure pointed to by state is initialized to zero. + + Returns: + return_value = 0 if memory was successfully reset, + otherwise returns -1. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Initializes state memory to zero. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Pre_Process_reset (Pre_ProcessState *state) +{ + if (state == (Pre_ProcessState *) NULL){ + fprintf(stderr, "Pre_Process_reset: invalid parameter\n"); + return -1; + } + + state->y2_hi = 0; + state->y2_lo = 0; + state->y1_hi = 0; + state->y1_lo = 0; + state->x0 = 0; + state->x1 = 0; + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Pre_Process_reset(Pre_ProcessState *state) +{ + if (state == (Pre_ProcessState *) NULL) + { + /* fprintf(stderr, "Pre_Process_reset: invalid parameter\n"); */ + return(-1); + } + + state->y2_hi = 0; + state->y2_lo = 0; + state->y1_hi = 0; + state->y1_lo = 0; + state->x0 = 0; + state->x1 = 0; + + return(0); +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pre_Process_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = a pointer to an array of pointers to structures of + type Pre_ProcessState + + Outputs: + state points to a NULL address + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + The memory used for state memory is freed. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Pre_Process_exit (Pre_ProcessState **state) +{ + if (state == NULL || *state == NULL) + return; + + // deallocate memory + free(*state); + *state = NULL; + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void Pre_Process_exit(Pre_ProcessState **state) +{ + if (state == NULL || *state == NULL) + { + return; + } + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pre_Process +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = a pointer to a structure of type Pre_ProcessState + signal = input/output signal (Word16) + lg = length of signal (Word16) + + Outputs: + st points to the updated structure + + Returns: + return_value = 0 (int) + + Global Variables Used: + a = points to a buffer of filter coefficients + b = points to a buffer of filter coefficients + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This module performs the preprocessing of the input speech. + The signal is passed through a 2nd order high pass filtering with cut off + frequency at 80 Hz. The input is divided by two in the filtering process. + + y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b[2]*x[i-2]/2 + + a[1]*y[i-1] + a[2]*y[i-2]; + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Pre_Process ( + Pre_ProcessState *st, + Word16 signal[], // input/output signal + Word16 lg) // lenght of signal +{ + Word16 i, x2; + Word32 L_tmp; + + for (i = 0; i < lg; i++) + { + x2 = st->x1; + st->x1 = st->x0; + st->x0 = signal[i]; + + // y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2 + // + a[1]*y[i-1] + a[2] * y[i-2]; + + L_tmp = Mpy_32_16 (st->y1_hi, st->y1_lo, a[1]); + L_tmp = L_add (L_tmp, Mpy_32_16 (st->y2_hi, st->y2_lo, a[2])); + L_tmp = L_mac (L_tmp, st->x0, b[0]); + L_tmp = L_mac (L_tmp, st->x1, b[1]); + L_tmp = L_mac (L_tmp, x2, b[2]); + L_tmp = L_shl (L_tmp, 3); + signal[i] = pv_round (L_tmp); + + st->y2_hi = st->y1_hi; + st->y2_lo = st->y1_lo; + L_Extract (L_tmp, &st->y1_hi, &st->y1_lo); + } + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +/* + filter coefficients (fc = 80 Hz, coeff. b[] is divided by 2) + const Word16 b[3] = {1899, -3798, 1899}; + const Word16 a[3] = {4096, 7807, -3733}; + +*/ + +void Pre_Process( + Pre_ProcessState *st, + Word16 signal[], /* input/output signal */ + Word16 lg) /* length of signal */ +{ + register Word16 i; + Word16 x_n_2; + Word16 x_n_1; + Word32 L_tmp; + Word16 *p_signal = signal; + + x_n_2 = st->x1; + x_n_1 = st->x0; + + for (i = lg; i != 0; i--) + { + + + /* y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2 */ + /* + a[1]*y[i-1] + a[2] * y[i-2]; */ + + L_tmp = ((Word32) st->y1_hi) * 7807; + L_tmp += (Word32)(((Word32) st->y1_lo * 7807) >> 15); + + L_tmp += ((Word32) st->y2_hi) * (-3733); + st->y2_hi = st->y1_hi; + L_tmp += (Word32)(((Word32) st->y2_lo * (-3733)) >> 15); + st->y2_lo = st->y1_lo; + + L_tmp += ((Word32) x_n_2) * 1899; + x_n_2 = x_n_1; + L_tmp += ((Word32) x_n_1) * (-3798); + x_n_1 = *(p_signal); + L_tmp += ((Word32) x_n_1) * 1899; + + + *(p_signal++) = (Word16)((L_tmp + 0x0000800L) >> 12); + + st->y1_hi = (Word16)(L_tmp >> 12); + st->y1_lo = (Word16)((L_tmp << 3) - ((Word32)(st->y1_hi) << 15)); + + } + + st->x1 = x_n_2; + st->x0 = x_n_1; + + return; +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pre_proc.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pre_proc.h new file mode 100644 index 00000000..abe676ff --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/pre_proc.h @@ -0,0 +1,114 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : pre_proc.h +* Purpose : Preprocessing of input speech. +* + + Description: Replaced "int" and/or "char" with OSCL defined types. + +******************************************************************************** +*/ +#ifndef pre_proc_h +#define pre_proc_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ******************************************************************************** + * LOCAL VARIABLES AND TABLES + ******************************************************************************** + */ + + /* + ******************************************************************************** + * DEFINITION OF DATA TYPES + ******************************************************************************** + */ + typedef struct + { + Word16 y2_hi; + Word16 y2_lo; + Word16 y1_hi; + Word16 y1_lo; + Word16 x0; + Word16 x1; + } Pre_ProcessState; + + /* + ******************************************************************************** + * DECLARATION OF PROTOTYPES + ******************************************************************************** + */ + + Word16 Pre_Process_init(Pre_ProcessState **st); + /* initialize one instance of the pre processing state. + Stores pointer to filter status struct in *st. This pointer has to + be passed to Pre_Process in each call. + returns 0 on success + */ + + Word16 Pre_Process_reset(Pre_ProcessState *st); + /* reset of pre processing state (i.e. set state memory to zero) + returns 0 on success + */ + void Pre_Process_exit(Pre_ProcessState **st); + /* de-initialize pre processing state (i.e. free status struct) + stores NULL in *st + */ + + void Pre_Process( + Pre_ProcessState *st, + Word16 signal[], /* Input/output signal */ + Word16 lg /* Lenght of signal */ + ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/prm2bits.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/prm2bits.cpp new file mode 100644 index 00000000..198ea4f7 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/prm2bits.cpp @@ -0,0 +1,263 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + + + + Filename: prm2bits.cpp + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "prm2bits.h" +#include "mode.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ +#define MASK 0x0001 +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Int2bin +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + value = value to be converted to binary of type Word16 + no_of_bits = number of bits associated with value of type Word16 + + Outputs: + bitstream = pointer to address where bits are written of type Word16 + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + FUNCTION: Int2bin + + PURPOSE: convert integer to binary and write the bits to the array + bitstream[]. The most significant bits are written first. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + prm2bits.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static void Int2bin ( + Word16 value, // input : value to be converted to binary + Word16 no_of_bits, // input : number of bits associated with value + Word16 *bitstream // output: address where bits are written +) +{ + Word16 *pt_bitstream, i, bit; + + pt_bitstream = &bitstream[no_of_bits]; + + for (i = 0; i < no_of_bits; i++) + { + bit = value & MASK; + if (bit == 0) + { + *--pt_bitstream = BIT_0; + } + else + { + *--pt_bitstream = BIT_1; + } + value = shr (value, 1); + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +static void Int2bin( + Word16 value, /* input : value to be converted to binary */ + Word16 no_of_bits, /* input : number of bits associated with value */ + Word16 *bitstream /* output: address where bits are written */ +) +{ + Word16 *pt_bitstream; + Word16 i; + + pt_bitstream = &bitstream[no_of_bits-1]; + + for (i = no_of_bits; i != 0; i--) + { + *(pt_bitstream--) = value & MASK; + value >>= 1; + } + +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: prm2bits +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + mode = AMR mode of type enum Mode + prm[] = pointer to analysis parameters of type Word16 + + Outputs: + bits[] = pointer to serial bits of type Word16 + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + FUNCTION: Prm2bits + + PURPOSE: converts the encoder parameter vector into a vector of serial + bits. + + DESCRIPTION: depending on the mode, different numbers of parameters + (with differing numbers of bits) are processed. Details + are found in bitno.tab + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + prm2bits.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void Prm2bits ( + enum Mode mode, // i : AMR mode + Word16 prm[], // i : analysis parameters (size <= MAX_PRM_SIZE) + Word16 bits[] // o : serial bits (size <= MAX_SERIAL_SIZE) +) +{ + Word16 i; + + for (i = 0; i < prmno[mode]; i++) + { + Int2bin (prm[i], bitno[mode][i], bits); + bits += bitno[mode][i]; + add(0,0); // account for above pointer update + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +void Prm2bits( + enum Mode mode, /* i : AMR mode */ + Word16 prm[], /* i : analysis parameters (size <= MAX_PRM_SIZE) */ + Word16 bits[], /* o : serial bits (size <= MAX_SERIAL_SIZE) */ + CommonAmrTbls* common_amr_tbls /* i : ptr to strcut of table ptrs */ +) +{ + Word16 i; + const Word16 *p_mode; + Word16 *p_prm; + const Word16* prmno_ptr = common_amr_tbls->prmno_ptr; + + p_mode = &common_amr_tbls->bitno_ptr[mode][0]; + p_prm = &prm[0]; + + for (i = prmno_ptr[mode]; i != 0; i--) + { + Int2bin(*(p_prm++), *(p_mode), bits); + bits += *(p_mode++); + } + + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/prm2bits.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/prm2bits.h new file mode 100644 index 00000000..a515df2d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/prm2bits.h @@ -0,0 +1,83 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.5.0 March 2, 2001 +* R99 Version 3.2.0 +* REL-4 Version 4.0.0 +* +******************************************************************************** +* +* File : prm2bits.h +* Purpose : Converts the encoder parameter vector into a +* : vector of serial bits. +* +******************************************************************************** +*/ +#ifndef prm2bits_h +#define prm2bits_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" +#include "mode.h" +#include "get_const_tbls.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* + ******************************************************************************** + * DEFINITION OF DATA TYPES + ******************************************************************************** + */ + + /* + ******************************************************************************** + * DECLARATION OF PROTOTYPES + ******************************************************************************** + */ + void Prm2bits( + enum Mode mode, /* i : AMR mode */ + Word16 prm[], /* input : analysis parameters */ + Word16 bits[], /* output: serial bits */ + CommonAmrTbls* common_amr_tbls /* i : ptr to strcut of table ptrs */ + ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/q_gain_c.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/q_gain_c.cpp new file mode 100644 index 00000000..fcaf18a8 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/q_gain_c.cpp @@ -0,0 +1,253 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: q_gain_c.cpp + Functions: q_gain_code + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Scalar quantization of the innovative codebook gain. + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "q_gain_c.h" +#include "mode.h" +#include "oper_32b.h" +#include "basic_op.h" +#include "log2.h" +#include "pow2.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ +#define NB_QUA_CODE 32 + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: q_gain_code +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + mode -- enum Mode -- AMR mode + exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0 + frac_gcode0 -- Word16 -- predicted CB gain (fraction), Q15 + gain -- Pointer to Word16 -- quantized fixed codebook gain, Q1 + + Outputs: + gain -- Pointer to Word16 -- quantized fixed codebook gain, Q1 + + qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10 + (for MR122 MA predictor update) + + qua_ener -- Pointer to Word16 -- quantized energy error, Q10 + (for other MA predictor update) + + pOverflow -- Pointer to Flag -- overflow indicator + Returns: + quantization index -- Word16 -- Q0 + + Global Variables Used: + qua_gain_code[] + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Scalar quantization of the innovative codebook gain. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + q_gain_c.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 q_gain_code( /* o : quantization index, Q0 */ + enum Mode mode, /* i : AMR mode */ + Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ + Word16 *gain, /* i/o: quantized fixed codebook gain, Q1 */ + Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ + /* (for MR122 MA predictor update) */ + Word16 *qua_ener, /* o : quantized energy error, Q10 */ + /* (for other MA predictor update) */ + const Word16* qua_gain_code_ptr, /* i : ptr to read-only table */ + Flag *pOverflow +) +{ + const Word16 *p; + Word16 i; + Word16 index; + Word16 gcode0; + Word16 err; + Word16 err_min; + Word16 g_q0; + Word16 temp; + + if (mode == MR122) + { + g_q0 = *gain >> 1; /* Q1 -> Q0 */ + } + else + { + g_q0 = *gain; + } + + /*-------------------------------------------------------------------* + * predicted codebook gain * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * gc0 = Pow2(int(d)+frac(d)) * + * = 2^exp + 2^frac * + * * + *-------------------------------------------------------------------*/ + + gcode0 = (Word16) Pow2(exp_gcode0, frac_gcode0, pOverflow); /* predicted gain */ + + if (mode == MR122) + { + gcode0 = shl(gcode0, 4, pOverflow); + } + else + { + gcode0 = shl(gcode0, 5, pOverflow); + } + + /*-------------------------------------------------------------------* + * Search for best quantizer * + *-------------------------------------------------------------------*/ + + p = &qua_gain_code_ptr[0]; + err_min = ((Word32)gcode0 * *(p++)) >> 15; + err_min = g_q0 - err_min; + if (err_min < 0) + { + err_min = -err_min; + } + + p += 2; /* skip quantized energy errors */ + index = 0; + + for (i = 1; i < NB_QUA_CODE; i++) + { + err = ((Word32)gcode0 * *(p++)) >> 15; + err = g_q0 - err; + + if (err < 0) + { + err = -err; + } + + p += 2; /* skip quantized energy error */ + + if (err < err_min) + { + err_min = err; + index = i; + } + } + + temp = index + (index << 1); + + p = &qua_gain_code_ptr[temp]; + + temp = (gcode0 * *(p++)) >> 15; + if (mode == MR122) + { + *gain = temp << 1; + } + else + { + *gain = temp; + } + + /* quantized error energies (for MA predictor update) */ + *qua_ener_MR122 = *p++; + *qua_ener = *p; + + return index; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/q_gain_c.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/q_gain_c.h new file mode 100644 index 00000000..64829639 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/q_gain_c.h @@ -0,0 +1,125 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: q_gain_c.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the file, q_gain.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef q_gain_c_h +#define q_gain_c_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "gc_pred.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------* + * Function q_gain_code() * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * Scalar quantization of the innovative codebook gain. * + * * + * gc_pred() is used for MA prediction of the innovation energy * + *--------------------------------------------------------------------------*/ + Word16 q_gain_code( /* o : quantization index, Q0 */ + enum Mode mode, /* i : AMR mode */ + Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ + Word16 *gain, /* i/o: quantized fixed codebook gain, Q1 */ + Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ + /* (for MR122 MA predictor update) */ + Word16 *qua_ener, /* o : quantized energy error, Q10 */ + /* (for other MA predictor update) */ + const Word16* qua_gain_code_ptr, /* i : ptr to read-only table */ + Flag *pOverflow + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* q_gain_c_h */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/q_gain_p.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/q_gain_p.cpp new file mode 100644 index 00000000..7748115c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/q_gain_p.cpp @@ -0,0 +1,237 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: q_gain_p.cpp + Functions: q_gain_pitch + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "q_gain_p.h" +#include "typedef.h" +#include "oper_32b.h" +#include "cnst.h" +#include "basic_op.h" + + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ +#define NB_QUA_PITCH 16 + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: q_gain_pitch +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + mode -- enum Mode -- AMR mode + gp_limit -- Word16 -- pitch gain limit + gain -- Pointer to Word16 -- Pitch gain (unquant/quant), Q14 + + Outputs: + gain -- Pointer to Word16 -- Pitch gain (unquant/quant), Q14 + + gain_cand -- Array of type Word16 -- pitch gain candidates (3), + MR795 only, Q14 + + gain_cind -- Array of type Word16 -- pitch gain cand. indices (3), + MR795 only, Q0 + + pOverflow -- Pointer to Flag -- overflow indicator + + Returns: + Word16 -- index of quantization + + Global Variables Used: + qua_gain_pitch + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + q_gain_p.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 q_gain_pitch( /* Return index of quantization */ + enum Mode mode, /* i : AMR mode */ + Word16 gp_limit, /* i : pitch gain limit */ + Word16 *gain, /* i/o: Pitch gain (unquant/quant), Q14 */ + Word16 gain_cand[], /* o : pitch gain candidates (3), MR795 only, Q14 */ + Word16 gain_cind[], /* o : pitch gain cand. indices (3),MR795 only, Q0 */ + const Word16* qua_gain_pitch_ptr, /* i : ptr to read-only table */ + Flag *pOverflow +) +{ + Word16 i; + Word16 index; + Word16 err; + Word16 err_min; + + err_min = sub(*gain, qua_gain_pitch_ptr[0], pOverflow); + err_min = abs_s(err_min); + + index = 0; + + for (i = 1; i < NB_QUA_PITCH; i++) + { + if (qua_gain_pitch_ptr[i] <= gp_limit) + { + err = sub(*gain, qua_gain_pitch_ptr[i], pOverflow); + err = abs_s(err); + + if (err < err_min) + { + err_min = err; + index = i; + } + } + } + + if (mode == MR795) + { + /* in MR795 mode, compute three gain_pit candidates around the index + * found in the quantization loop: the index found and the two direct + * neighbours, except for the extreme cases (i=0 or i=NB_QUA_PITCH-1), + * where the direct neighbour and the neighbour to that is used. + */ + Word16 ii; + + if (index == 0) + { + ii = index; + } + else + { + if (index == (NB_QUA_PITCH - 1) || + (qua_gain_pitch_ptr[index+1] > gp_limit)) + { + ii = index - 2; + } + else + { + ii = index - 1; + } + } + + /* store candidate indices and values */ + for (i = 0; i < 3; i++) + { + gain_cind[i] = ii; + gain_cand[i] = qua_gain_pitch_ptr[ii]; + + ii += 1; + } + + *gain = qua_gain_pitch_ptr[index]; + } + else + { + /* in MR122 mode, just return the index and gain pitch found. + * If bitexactness is required, mask away the two LSBs (because + * in the original EFR, gain_pit was scaled Q12) + */ + if (mode == MR122) + { + /* clear 2 LSBits */ + *gain = qua_gain_pitch_ptr[index] & 0xFFFC; + } + else + { + *gain = qua_gain_pitch_ptr[index]; + } + } + return index; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/q_gain_p.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/q_gain_p.h new file mode 100644 index 00000000..ceaaa9b1 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/q_gain_p.h @@ -0,0 +1,113 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: q_gain_p.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the file, q_gain_p.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef q_gain_p_h +#define q_gain_p_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + Word16 q_gain_pitch( /* Return index of quantization */ + enum Mode mode, /* i : AMR mode */ + Word16 gp_limit, /* i : pitch gain limit */ + Word16 *gain, /* i/o: Pitch gain (unquant/quant), Q14 */ + Word16 gain_cand[], /* o : pitch gain candidates (3), MR795 only, Q14 */ + Word16 gain_cind[], /* o : pitch gain cand. indices (3),MR795 only, Q0 */ + const Word16* qua_gain_pitch_ptr, /* i : ptr to read-only table */ + Flag *pOverflow + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* q_gain_p_h */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qgain475.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qgain475.cpp new file mode 100644 index 00000000..e5af47f9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qgain475.cpp @@ -0,0 +1,1397 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: qgain475.cpp + Funtions: MR475_quant_store_results + MR475_update_unq_pred + MR475_gain_quant + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + These modules handle the quantization of pitch and codebook gains for MR475. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "qgain475.h" +#include "typedef.h" +#include "basic_op.h" +#include "mode.h" +#include "cnst.h" +#include "pow2.h" +#include "log2.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define MR475_VQ_SIZE 256 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* The table contains the following data: + * + * g_pitch(0) (Q14) // for sub- + * g_fac(0) (Q12) // frame 0 and 2 + * g_pitch(1) (Q14) // for sub- + * g_fac(2) (Q12) // frame 1 and 3 + * + */ +static const Word16 table_gain_MR475[MR475_VQ_SIZE*4] = +{ + /*g_pit(0), g_fac(0), g_pit(1), g_fac(1) */ + 812, 128, 542, 140, + 2873, 1135, 2266, 3402, + 2067, 563, 12677, 647, + 4132, 1798, 5601, 5285, + 7689, 374, 3735, 441, + 10912, 2638, 11807, 2494, + 20490, 797, 5218, 675, + 6724, 8354, 5282, 1696, + 1488, 428, 5882, 452, + 5332, 4072, 3583, 1268, + 2469, 901, 15894, 1005, + 14982, 3271, 10331, 4858, + 3635, 2021, 2596, 835, + 12360, 4892, 12206, 1704, + 13432, 1604, 9118, 2341, + 3968, 1538, 5479, 9936, + 3795, 417, 1359, 414, + 3640, 1569, 7995, 3541, + 11405, 645, 8552, 635, + 4056, 1377, 16608, 6124, + 11420, 700, 2007, 607, + 12415, 1578, 11119, 4654, + 13680, 1708, 11990, 1229, + 7996, 7297, 13231, 5715, + 2428, 1159, 2073, 1941, + 6218, 6121, 3546, 1804, + 8925, 1802, 8679, 1580, + 13935, 3576, 13313, 6237, + 6142, 1130, 5994, 1734, + 14141, 4662, 11271, 3321, + 12226, 1551, 13931, 3015, + 5081, 10464, 9444, 6706, + 1689, 683, 1436, 1306, + 7212, 3933, 4082, 2713, + 7793, 704, 15070, 802, + 6299, 5212, 4337, 5357, + 6676, 541, 6062, 626, + 13651, 3700, 11498, 2408, + 16156, 716, 12177, 751, + 8065, 11489, 6314, 2256, + 4466, 496, 7293, 523, + 10213, 3833, 8394, 3037, + 8403, 966, 14228, 1880, + 8703, 5409, 16395, 4863, + 7420, 1979, 6089, 1230, + 9371, 4398, 14558, 3363, + 13559, 2873, 13163, 1465, + 5534, 1678, 13138, 14771, + 7338, 600, 1318, 548, + 4252, 3539, 10044, 2364, + 10587, 622, 13088, 669, + 14126, 3526, 5039, 9784, + 15338, 619, 3115, 590, + 16442, 3013, 15542, 4168, + 15537, 1611, 15405, 1228, + 16023, 9299, 7534, 4976, + 1990, 1213, 11447, 1157, + 12512, 5519, 9475, 2644, + 7716, 2034, 13280, 2239, + 16011, 5093, 8066, 6761, + 10083, 1413, 5002, 2347, + 12523, 5975, 15126, 2899, + 18264, 2289, 15827, 2527, + 16265, 10254, 14651, 11319, + 1797, 337, 3115, 397, + 3510, 2928, 4592, 2670, + 7519, 628, 11415, 656, + 5946, 2435, 6544, 7367, + 8238, 829, 4000, 863, + 10032, 2492, 16057, 3551, + 18204, 1054, 6103, 1454, + 5884, 7900, 18752, 3468, + 1864, 544, 9198, 683, + 11623, 4160, 4594, 1644, + 3158, 1157, 15953, 2560, + 12349, 3733, 17420, 5260, + 6106, 2004, 2917, 1742, + 16467, 5257, 16787, 1680, + 17205, 1759, 4773, 3231, + 7386, 6035, 14342, 10012, + 4035, 442, 4194, 458, + 9214, 2242, 7427, 4217, + 12860, 801, 11186, 825, + 12648, 2084, 12956, 6554, + 9505, 996, 6629, 985, + 10537, 2502, 15289, 5006, + 12602, 2055, 15484, 1653, + 16194, 6921, 14231, 5790, + 2626, 828, 5615, 1686, + 13663, 5778, 3668, 1554, + 11313, 2633, 9770, 1459, + 14003, 4733, 15897, 6291, + 6278, 1870, 7910, 2285, + 16978, 4571, 16576, 3849, + 15248, 2311, 16023, 3244, + 14459, 17808, 11847, 2763, + 1981, 1407, 1400, 876, + 4335, 3547, 4391, 4210, + 5405, 680, 17461, 781, + 6501, 5118, 8091, 7677, + 7355, 794, 8333, 1182, + 15041, 3160, 14928, 3039, + 20421, 880, 14545, 852, + 12337, 14708, 6904, 1920, + 4225, 933, 8218, 1087, + 10659, 4084, 10082, 4533, + 2735, 840, 20657, 1081, + 16711, 5966, 15873, 4578, + 10871, 2574, 3773, 1166, + 14519, 4044, 20699, 2627, + 15219, 2734, 15274, 2186, + 6257, 3226, 13125, 19480, + 7196, 930, 2462, 1618, + 4515, 3092, 13852, 4277, + 10460, 833, 17339, 810, + 16891, 2289, 15546, 8217, + 13603, 1684, 3197, 1834, + 15948, 2820, 15812, 5327, + 17006, 2438, 16788, 1326, + 15671, 8156, 11726, 8556, + 3762, 2053, 9563, 1317, + 13561, 6790, 12227, 1936, + 8180, 3550, 13287, 1778, + 16299, 6599, 16291, 7758, + 8521, 2551, 7225, 2645, + 18269, 7489, 16885, 2248, + 17882, 2884, 17265, 3328, + 9417, 20162, 11042, 8320, + 1286, 620, 1431, 583, + 5993, 2289, 3978, 3626, + 5144, 752, 13409, 830, + 5553, 2860, 11764, 5908, + 10737, 560, 5446, 564, + 13321, 3008, 11946, 3683, + 19887, 798, 9825, 728, + 13663, 8748, 7391, 3053, + 2515, 778, 6050, 833, + 6469, 5074, 8305, 2463, + 6141, 1865, 15308, 1262, + 14408, 4547, 13663, 4515, + 3137, 2983, 2479, 1259, + 15088, 4647, 15382, 2607, + 14492, 2392, 12462, 2537, + 7539, 2949, 12909, 12060, + 5468, 684, 3141, 722, + 5081, 1274, 12732, 4200, + 15302, 681, 7819, 592, + 6534, 2021, 16478, 8737, + 13364, 882, 5397, 899, + 14656, 2178, 14741, 4227, + 14270, 1298, 13929, 2029, + 15477, 7482, 15815, 4572, + 2521, 2013, 5062, 1804, + 5159, 6582, 7130, 3597, + 10920, 1611, 11729, 1708, + 16903, 3455, 16268, 6640, + 9306, 1007, 9369, 2106, + 19182, 5037, 12441, 4269, + 15919, 1332, 15357, 3512, + 11898, 14141, 16101, 6854, + 2010, 737, 3779, 861, + 11454, 2880, 3564, 3540, + 9057, 1241, 12391, 896, + 8546, 4629, 11561, 5776, + 8129, 589, 8218, 588, + 18728, 3755, 12973, 3149, + 15729, 758, 16634, 754, + 15222, 11138, 15871, 2208, + 4673, 610, 10218, 678, + 15257, 4146, 5729, 3327, + 8377, 1670, 19862, 2321, + 15450, 5511, 14054, 5481, + 5728, 2888, 7580, 1346, + 14384, 5325, 16236, 3950, + 15118, 3744, 15306, 1435, + 14597, 4070, 12301, 15696, + 7617, 1699, 2170, 884, + 4459, 4567, 18094, 3306, + 12742, 815, 14926, 907, + 15016, 4281, 15518, 8368, + 17994, 1087, 2358, 865, + 16281, 3787, 15679, 4596, + 16356, 1534, 16584, 2210, + 16833, 9697, 15929, 4513, + 3277, 1085, 9643, 2187, + 11973, 6068, 9199, 4462, + 8955, 1629, 10289, 3062, + 16481, 5155, 15466, 7066, + 13678, 2543, 5273, 2277, + 16746, 6213, 16655, 3408, + 20304, 3363, 18688, 1985, + 14172, 12867, 15154, 15703, + 4473, 1020, 1681, 886, + 4311, 4301, 8952, 3657, + 5893, 1147, 11647, 1452, + 15886, 2227, 4582, 6644, + 6929, 1205, 6220, 799, + 12415, 3409, 15968, 3877, + 19859, 2109, 9689, 2141, + 14742, 8830, 14480, 2599, + 1817, 1238, 7771, 813, + 19079, 4410, 5554, 2064, + 3687, 2844, 17435, 2256, + 16697, 4486, 16199, 5388, + 8028, 2763, 3405, 2119, + 17426, 5477, 13698, 2786, + 19879, 2720, 9098, 3880, + 18172, 4833, 17336, 12207, + 5116, 996, 4935, 988, + 9888, 3081, 6014, 5371, + 15881, 1667, 8405, 1183, + 15087, 2366, 19777, 7002, + 11963, 1562, 7279, 1128, + 16859, 1532, 15762, 5381, + 14708, 2065, 20105, 2155, + 17158, 8245, 17911, 6318, + 5467, 1504, 4100, 2574, + 17421, 6810, 5673, 2888, + 16636, 3382, 8975, 1831, + 20159, 4737, 19550, 7294, + 6658, 2781, 11472, 3321, + 19397, 5054, 18878, 4722, + 16439, 2373, 20430, 4386, + 11353, 26526, 11593, 3068, + 2866, 1566, 5108, 1070, + 9614, 4915, 4939, 3536, + 7541, 878, 20717, 851, + 6938, 4395, 16799, 7733, + 10137, 1019, 9845, 964, + 15494, 3955, 15459, 3430, + 18863, 982, 20120, 963, + 16876, 12887, 14334, 4200, + 6599, 1220, 9222, 814, + 16942, 5134, 5661, 4898, + 5488, 1798, 20258, 3962, + 17005, 6178, 17929, 5929, + 9365, 3420, 7474, 1971, + 19537, 5177, 19003, 3006, + 16454, 3788, 16070, 2367, + 8664, 2743, 9445, 26358, + 10856, 1287, 3555, 1009, + 5606, 3622, 19453, 5512, + 12453, 797, 20634, 911, + 15427, 3066, 17037, 10275, + 18883, 2633, 3913, 1268, + 19519, 3371, 18052, 5230, + 19291, 1678, 19508, 3172, + 18072, 10754, 16625, 6845, + 3134, 2298, 10869, 2437, + 15580, 6913, 12597, 3381, + 11116, 3297, 16762, 2424, + 18853, 6715, 17171, 9887, + 12743, 2605, 8937, 3140, + 19033, 7764, 18347, 3880, + 20475, 3682, 19602, 3380, + 13044, 19373, 10526, 23124 +}; + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: MR475_quant_store_results +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pred_st = pointer to structure of type gc_predState + p = pointer to selected quantizer table entry (const Word16) + gcode0 = predicted CB gain (Word16) + exp_gcode0 = exponent of predicted CB gain (Word16) + gain_pit = pointer to Pitch gain (Word16) + gain_cod = pointer to Code gain (Word16) + + Outputs: + pred_st points to the updated structure of type gc_predState + gain_pit points to Pitch gain + gain_cod points to Code gain + pOverflow points to overflow indicator (Flag) + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function calculates the final fixed codebook gain and the predictor + update values, and updates the gain predictor. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + qgain475.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +static void MR475_quant_store_results( + + gc_predState *pred_st, // i/o: gain predictor state struct + const Word16 *p, // i : pointer to selected quantizer table entry + Word16 gcode0, // i : predicted CB gain, Q(14 - exp_gcode0) + Word16 exp_gcode0, // i : exponent of predicted CB gain, Q0 + Word16 *gain_pit, // o : Pitch gain, Q14 + Word16 *gain_cod // o : Code gain, Q1 +) +{ + + Word16 g_code, exp, frac, tmp; + Word32 L_tmp; + + Word16 qua_ener_MR122; // o : quantized energy error, MR122 version Q10 + Word16 qua_ener; // o : quantized energy error, Q10 + + // Read the quantized gains + *gain_pit = *p++; + g_code = *p++; + + //------------------------------------------------------------------* + * calculate final fixed codebook gain: * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * * + * gc = gc0 * g * + *------------------------------------------------------------------ + + L_tmp = L_mult(g_code, gcode0); + L_tmp = L_shr(L_tmp, sub(10, exp_gcode0)); + *gain_cod = extract_h(L_tmp); + + //------------------------------------------------------------------* + * calculate predictor update values and update gain predictor: * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * * + * qua_ener = log2(g) * + * qua_ener_MR122 = 20*log10(g) * + *------------------------------------------------------------------ + + Log2 (L_deposit_l (g_code), &exp, &frac); // Log2(x Q12) = log2(x) + 12 + exp = sub(exp, 12); + + tmp = shr_r (frac, 5); + qua_ener_MR122 = add (tmp, shl (exp, 10)); + + L_tmp = Mpy_32_16(exp, frac, 24660); // 24660 Q12 ~= 6.0206 = 20*log10(2) + qua_ener = pv_round (L_shl (L_tmp, 13)); // Q12 * Q0 = Q13 -> Q10 + + gc_pred_update(pred_st, qua_ener_MR122, qua_ener); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void MR475_quant_store_results( + gc_predState *pred_st, /* i/o: gain predictor state struct */ + const Word16 *p, /* i : pointer to selected quantizer table entry */ + Word16 gcode0, /* i : predicted CB gain, Q(14 - exp_gcode0) */ + Word16 exp_gcode0, /* i : exponent of predicted CB gain, Q0 */ + Word16 *gain_pit, /* o : Pitch gain, Q14 */ + Word16 *gain_cod, /* o : Code gain, Q1 */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + Word16 g_code; + Word16 exp; + Word16 frac; + Word16 tmp; + Word32 L_tmp; + + Word16 qua_ener_MR122; /* o : quantized energy error, MR122 version Q10 */ + Word16 qua_ener; /* o : quantized energy error, Q10 */ + + + /* Read the quantized gains */ + *gain_pit = *p++; + g_code = *p++; + + /*------------------------------------------------------------------* + * calculate final fixed codebook gain: * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * * + * gc = gc0 * g * + *------------------------------------------------------------------*/ + + L_tmp = ((Word32) g_code * gcode0) << 1; + tmp = 10 - exp_gcode0; + L_tmp = L_shr(L_tmp, tmp, pOverflow); + *gain_cod = (Word16)(L_tmp >> 16); + + /*------------------------------------------------------------------* + * calculate predictor update values and update gain predictor: * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * * + * qua_ener = log2(g) * + * qua_ener_MR122 = 20*log10(g) * + *------------------------------------------------------------------*/ + + /* Log2(x Q12) = log2(x) + 12 */ + Log2((Word32) g_code, &exp, &frac, pOverflow); + exp -= 12; + + tmp = shr_r(frac, 5, pOverflow); + qua_ener_MR122 = exp << 10; + qua_ener_MR122 = tmp + qua_ener_MR122; + + /* 24660 Q12 ~= 6.0206 = 20*log10(2) */ + L_tmp = Mpy_32_16(exp, frac, 24660, pOverflow); + L_tmp = L_tmp << 13; + + /* Q12 * Q0 = Q13 -> Q10 */ + qua_ener = (Word16)((L_tmp + (Word32) 0x00008000L) >> 16); + + gc_pred_update(pred_st, qua_ener_MR122, qua_ener); + + return; +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: MR475_update_unq_pred +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pred_st = pointer to structure of type gc_predState + exp_gcode0 = predicted CB gain (exponent MSW) (Word16) + frac_gcode0 = predicted CB gain (exponent LSW) (Word16) + cod_gain_exp = optimum codebook gain (exponent)(Word16) + cod_gain_frac = optimum codebook gain (fraction) (Word16) + + Outputs: + pred_st points to the updated structure of type gc_predState + pOverflow points to overflow indicator (Flag) + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This module uses the optimum codebook gain and updates the "unquantized" + gain predictor with the (bounded) prediction error. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + qgain475.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void +MR475_update_unq_pred( + gc_predState *pred_st, // i/o: gain predictor state struct + Word16 exp_gcode0, // i : predicted CB gain (exponent MSW), Q0 + Word16 frac_gcode0, // i : predicted CB gain (exponent LSW), Q15 + Word16 cod_gain_exp, // i : optimum codebook gain (exponent), Q0 + Word16 cod_gain_frac // i : optimum codebook gain (fraction), Q15 +) +{ + Word16 tmp, exp, frac; + Word16 qua_ener, qua_ener_MR122; + Word32 L_tmp; + + // calculate prediction error factor (given optimum CB gain gcu): + // predErrFact = gcu / gcode0 + // (limit to MIN_PRED_ERR_FACT <= predErrFact <= MAX_PRED_ERR_FACT + // -> limit qua_ener*) + // + // calculate prediction error (log): + // + // qua_ener_MR122 = log2(predErrFact) + // qua_ener = 20*log10(predErrFact) + + if (cod_gain_frac <= 0) + { + // if gcu <= 0 -> predErrFact = 0 < MIN_PRED_ERR_FACT + // -> set qua_ener(_MR122) directly + qua_ener = MIN_QUA_ENER; + qua_ener_MR122 = MIN_QUA_ENER_MR122; + } + else + { + // convert gcode0 from DPF to standard fraction/exponent format + // with normalized frac, i.e. 16384 <= frac <= 32767 + // Note: exponent correction (exp=exp-14) is done after div_s + frac_gcode0 = extract_l (Pow2 (14, frac_gcode0)); + + // make sure cod_gain_frac < frac_gcode0 for div_s + if (sub(cod_gain_frac, frac_gcode0) >= 0) + { + cod_gain_frac = shr (cod_gain_frac, 1); + cod_gain_exp = add (cod_gain_exp, 1); + } + + // predErrFact + // = gcu / gcode0 + // = cod_gain_frac/frac_gcode0 * 2^(cod_gain_exp-(exp_gcode0-14)) + // = div_s (c_g_f, frac_gcode0)*2^-15 * 2^(c_g_e-exp_gcode0+14) + // = div_s * 2^(cod_gain_exp-exp_gcode0 - 1) + + frac = div_s (cod_gain_frac, frac_gcode0); + tmp = sub (sub (cod_gain_exp, exp_gcode0), 1); + + Log2 (L_deposit_l (frac), &exp, &frac); + exp = add (exp, tmp); + + // calculate prediction error (log2, Q10) + qua_ener_MR122 = shr_r (frac, 5); + qua_ener_MR122 = add (qua_ener_MR122, shl (exp, 10)); + + if (sub(qua_ener_MR122, MIN_QUA_ENER_MR122) < 0) + { + qua_ener = MIN_QUA_ENER; + qua_ener_MR122 = MIN_QUA_ENER_MR122; + } + else if (sub(qua_ener_MR122, MAX_QUA_ENER_MR122) > 0) + { + qua_ener = MAX_QUA_ENER; + qua_ener_MR122 = MAX_QUA_ENER_MR122; + } + else + { + // calculate prediction error (20*log10, Q10) + L_tmp = Mpy_32_16(exp, frac, 24660); + // 24660 Q12 ~= 6.0206 = 20*log10(2) + qua_ener = pv_round (L_shl (L_tmp, 13)); + // Q12 * Q0 = Q13 -> Q26 -> Q10 + } + } + + // update MA predictor memory + gc_pred_update(pred_st, qua_ener_MR122, qua_ener); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void MR475_update_unq_pred( + gc_predState *pred_st, /* i/o: gain predictor state struct */ + Word16 exp_gcode0, /* i : predicted CB gain (exponent MSW), Q0 */ + Word16 frac_gcode0, /* i : predicted CB gain (exponent LSW), Q15 */ + Word16 cod_gain_exp, /* i : optimum codebook gain (exponent), Q0 */ + Word16 cod_gain_frac, /* i : optimum codebook gain (fraction), Q15 */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + Word16 tmp; + Word16 exp; + Word16 frac; + Word16 qua_ener; + Word16 qua_ener_MR122; + Word32 L_tmp; + + /* calculate prediction error factor (given optimum CB gain gcu): + * + * predErrFact = gcu / gcode0 + * (limit to MIN_PRED_ERR_FACT <= predErrFact <= MAX_PRED_ERR_FACT + * -> limit qua_ener*) + * + * calculate prediction error (log): + * + * qua_ener_MR122 = log2(predErrFact) + * qua_ener = 20*log10(predErrFact) + * + */ + + if (cod_gain_frac <= 0) + { + /* if gcu <= 0 -> predErrFact = 0 < MIN_PRED_ERR_FACT */ + /* -> set qua_ener(_MR122) directly */ + qua_ener = MIN_QUA_ENER; + qua_ener_MR122 = MIN_QUA_ENER_MR122; + } + else + { + /* convert gcode0 from DPF to standard fraction/exponent format */ + /* with normalized frac, i.e. 16384 <= frac <= 32767 */ + /* Note: exponent correction (exp=exp-14) is done after div_s */ + frac_gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow)); + + /* make sure cod_gain_frac < frac_gcode0 for div_s */ + if (cod_gain_frac >= frac_gcode0) + { + cod_gain_frac >>= 1; + cod_gain_exp += 1; + } + + /* + predErrFact + = gcu / gcode0 + = cod_gain_frac/frac_gcode0 * 2^(cod_gain_exp-(exp_gcode0-14)) + = div_s (c_g_f, frac_gcode0)*2^-15 * 2^(c_g_e-exp_gcode0+14) + = div_s * 2^(cod_gain_exp-exp_gcode0 - 1) + */ + frac = div_s(cod_gain_frac, frac_gcode0); + tmp = cod_gain_exp - exp_gcode0; + tmp -= 1; + + Log2((Word32) frac, &exp, &frac, pOverflow); + exp += tmp; + + /* calculate prediction error (log2, Q10) */ + qua_ener_MR122 = shr_r(frac, 5, pOverflow); + tmp = exp << 10; + qua_ener_MR122 += tmp; + + if (qua_ener_MR122 > MAX_QUA_ENER_MR122) + { + qua_ener = MAX_QUA_ENER; + qua_ener_MR122 = MAX_QUA_ENER_MR122; + } + else + { + /* calculate prediction error (20*log10, Q10) */ + L_tmp = Mpy_32_16(exp, frac, 24660, pOverflow); + /* 24660 Q12 ~= 6.0206 = 20*log10(2) */ + L_tmp = L_shl(L_tmp, 13, pOverflow); + qua_ener = pv_round(L_tmp, pOverflow); + + /* Q12 * Q0 = Q13 -> Q26 -> Q10 */ + } + } + + /* update MA predictor memory */ + gc_pred_update(pred_st, qua_ener_MR122, qua_ener); + + + return; +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: MR475_gain_quant +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + pred_st = pointer to structure of type gc_predState + sf0_exp_gcode0 = predicted CB gain (exponent) (Word16) + f0_frac_gcode0 = predicted CB gain (fraction) (Word16) + sf0_exp_coeff = energy coeff. (exponent part) (Word16) + sf0_frac_coeff = energy coeff. ((fraction part) (Word16) + sf0_exp_target_en = exponent of target energy (Word16) + sf0_frac_target_en = fraction of target energy (Word16) + sf1_code_nosharp = innovative codebook vector (Word16) + sf1_exp_gcode0 = predicted CB gain (exponent) (Word16) + sf1_frac_gcode0 = predicted CB gain (fraction) (Word16) + sf1_exp_coeff = energy coeff. (exponent part) (Word16) + sf1_frac_coeff = energy coeff. (fraction part) (Word16) + sf1_exp_target_en = exponent of target energy (Word16) + sf1_frac_target_en = fraction of target energy (Word16) + gp_limit = pitch gain limit (Word16) + sf0_gain_pit = pointer to Pitch gain (Word16) + sf0_gain_cod = pointer to Code gain (Word16) + sf1_gain_pit = pointer to Pitch gain (Word16) + sf1_gain_cod = pointer to Code gain (Word16) + + Outputs: + pred_st points to the updated structure of type gc_predState + sf0_gain_pit points to Pitch gain + sf0_gain_cod points to Code gain + sf1_gain_pit points to Pitch gain + sf1_gain_cod points to Code gain + + Returns: + index = index of quantization + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This module provides quantization of pitch and codebook gains for two + subframes using the predicted codebook gain. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + qgain475.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 +MR475_gain_quant( // o : index of quantization. + gc_predState *pred_st, // i/o: gain predictor state struct + + // data from subframe 0 (or 2) + Word16 sf0_exp_gcode0, // i : predicted CB gain (exponent), Q0 + Word16 sf0_frac_gcode0, // i : predicted CB gain (fraction), Q15 + Word16 sf0_exp_coeff[], // i : energy coeff. (5), exponent part, Q0 + Word16 sf0_frac_coeff[], // i : energy coeff. (5), fraction part, Q15 + // (frac_coeff and exp_coeff computed in + // calc_filt_energies()) + Word16 sf0_exp_target_en, // i : exponent of target energy, Q0 + Word16 sf0_frac_target_en, // i : fraction of target energy, Q15 + + // data from subframe 1 (or 3) + Word16 sf1_code_nosharp[], // i : innovative codebook vector (L_SUBFR) + // (whithout pitch sharpening) + Word16 sf1_exp_gcode0, // i : predicted CB gain (exponent), Q0 + Word16 sf1_frac_gcode0, // i : predicted CB gain (fraction), Q15 + Word16 sf1_exp_coeff[], // i : energy coeff. (5), exponent part, Q0 + Word16 sf1_frac_coeff[], // i : energy coeff. (5), fraction part, Q15 + // (frac_coeff and exp_coeff computed in + // calc_filt_energies()) + Word16 sf1_exp_target_en, // i : exponent of target energy, Q0 + Word16 sf1_frac_target_en, // i : fraction of target energy, Q15 + + Word16 gp_limit, // i : pitch gain limit + + Word16 *sf0_gain_pit, // o : Pitch gain, Q14 + Word16 *sf0_gain_cod, // o : Code gain, Q1 + + Word16 *sf1_gain_pit, // o : Pitch gain, Q14 + Word16 *sf1_gain_cod // o : Code gain, Q1 +) +{ + const Word16 *p; + Word16 i, index = 0; + Word16 tmp; + Word16 exp; + Word16 sf0_gcode0, sf1_gcode0; + Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod; + Word16 coeff[10], coeff_lo[10], exp_max[10]; // 0..4: sf0; 5..9: sf1 + Word32 L_tmp, dist_min; + + *-------------------------------------------------------------------* + * predicted codebook gain * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * gc0 = 2^exp_gcode0 + 2^frac_gcode0 * + * * + * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) * + *-------------------------------------------------------------------* + + sf0_gcode0 = extract_l(Pow2(14, sf0_frac_gcode0)); + sf1_gcode0 = extract_l(Pow2(14, sf1_frac_gcode0)); + + * For each subframe, the error energy (sum) to be minimized consists + * of five terms, t[0..4]. + * + * t[0] = gp^2 * + * t[1] = -2*gp * + * t[2] = gc^2 * + * t[3] = -2*gc * + * t[4] = 2*gp*gc * + * + + // sf 0 + // determine the scaling exponent for g_code: ec = ec0 - 11 + exp = sub(sf0_exp_gcode0, 11); + + // calculate exp_max[i] = s[i]-1 + exp_max[0] = sub(sf0_exp_coeff[0], 13); + exp_max[1] = sub(sf0_exp_coeff[1], 14); + exp_max[2] = add(sf0_exp_coeff[2], add(15, shl(exp, 1))); + exp_max[3] = add(sf0_exp_coeff[3], exp); + exp_max[4] = add(sf0_exp_coeff[4], add(1, exp)); + + // sf 1 + // determine the scaling exponent for g_code: ec = ec0 - 11 + exp = sub(sf1_exp_gcode0, 11); + + // calculate exp_max[i] = s[i]-1 + exp_max[5] = sub(sf1_exp_coeff[0], 13); + exp_max[6] = sub(sf1_exp_coeff[1], 14); + exp_max[7] = add(sf1_exp_coeff[2], add(15, shl(exp, 1))); + exp_max[8] = add(sf1_exp_coeff[3], exp); + exp_max[9] = add(sf1_exp_coeff[4], add(1, exp)); + + *-------------------------------------------------------------------* + * Gain search equalisation: * + * ~~~~~~~~~~~~~~~~~~~~~~~~~ * + * The MSE for the two subframes is weighted differently if there * + * is a big difference in the corresponding target energies * + *-------------------------------------------------------------------* + + // make the target energy exponents the same by de-normalizing the + // fraction of the smaller one. This is necessary to be able to compare + // them + + exp = sf0_exp_target_en - sf1_exp_target_en; + if (exp > 0) + { + sf1_frac_target_en = shr (sf1_frac_target_en, exp); + } + else + { + sf0_frac_target_en = shl (sf0_frac_target_en, exp); + } + + // assume no change of exponents + exp = 0; + + // test for target energy difference; set exp to +1 or -1 to scale + // up/down coefficients for sf 1 + + tmp = shr_r (sf1_frac_target_en, 1); // tmp = ceil(0.5*en(sf1)) + if (sub (tmp, sf0_frac_target_en) > 0) // tmp > en(sf0)? + { + // target_energy(sf1) > 2*target_energy(sf0) + // -> scale up MSE(sf0) by 2 by adding 1 to exponents 0..4 + exp = 1; + } + else + { + tmp = shr (add (sf0_frac_target_en, 3), 2); // tmp=ceil(0.25*en(sf0)) + if (sub (tmp, sf1_frac_target_en) > 0) // tmp > en(sf1)? + { + // target_energy(sf1) < 0.25*target_energy(sf0) + // -> scale down MSE(sf0) by 0.5 by subtracting 1 from + // coefficients 0..4 + exp = -1; + } + } + + for (i = 0; i < 5; i++) + { + exp_max[i] = add (exp_max[i], exp); + } + + *-------------------------------------------------------------------* + * Find maximum exponent: * + * ~~~~~~~~~~~~~~~~~~~~~~ * + * * + * For the sum operation, all terms must have the same scaling; * + * that scaling should be low enough to prevent overflow. There- * + * fore, the maximum scale is determined and all coefficients are * + * re-scaled: * + * * + * exp = max(exp_max[i]) + 1; * + * e = exp_max[i]-exp; e <= 0! * + * c[i] = c[i]*2^e * + *-------------------------------------------------------------------* + + exp = exp_max[0]; + for (i = 1; i < 10; i++) + { + if (sub(exp_max[i], exp) > 0) + { + exp = exp_max[i]; + } + } + exp = add(exp, 1); // To avoid overflow + + p = &sf0_frac_coeff[0]; + for (i = 0; i < 5; i++) { + tmp = sub(exp, exp_max[i]); + L_tmp = L_deposit_h(*p++); + L_tmp = L_shr(L_tmp, tmp); + L_Extract(L_tmp, &coeff[i], &coeff_lo[i]); + } + p = &sf1_frac_coeff[0]; + for (; i < 10; i++) { + tmp = sub(exp, exp_max[i]); + L_tmp = L_deposit_h(*p++); + L_tmp = L_shr(L_tmp, tmp); + L_Extract(L_tmp, &coeff[i], &coeff_lo[i]); + } + + //-------------------------------------------------------------------* + * Codebook search: * + * ~~~~~~~~~~~~~~~~ * + * * + * For each pair (g_pitch, g_fac) in the table calculate the * + * terms t[0..4] and sum them up; the result is the mean squared * + * error for the quantized gains from the table. The index for the * + * minimum MSE is stored and finally used to retrieve the quantized * + * gains * + *------------------------------------------------------------------- + + // start with "infinite" MSE + dist_min = MAX_32; + + p = &table_gain_MR475[0]; + + for (i = 0; i < MR475_VQ_SIZE; i++) + { + // subframe 0 (and 2) calculations + g_pitch = *p++; + g_code = *p++; + + g_code = mult(g_code, sf0_gcode0); + g2_pitch = mult(g_pitch, g_pitch); + g2_code = mult(g_code, g_code); + g_pit_cod = mult(g_code, g_pitch); + + L_tmp = Mpy_32_16( coeff[0], coeff_lo[0], g2_pitch); + L_tmp = Mac_32_16(L_tmp, coeff[1], coeff_lo[1], g_pitch); + L_tmp = Mac_32_16(L_tmp, coeff[2], coeff_lo[2], g2_code); + L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3], g_code); + L_tmp = Mac_32_16(L_tmp, coeff[4], coeff_lo[4], g_pit_cod); + + tmp = sub (g_pitch, gp_limit); + + // subframe 1 (and 3) calculations + g_pitch = *p++; + g_code = *p++; + + if (tmp <= 0 && sub(g_pitch, gp_limit) <= 0) + { + g_code = mult(g_code, sf1_gcode0); + g2_pitch = mult(g_pitch, g_pitch); + g2_code = mult(g_code, g_code); + g_pit_cod = mult(g_code, g_pitch); + + L_tmp = Mac_32_16(L_tmp, coeff[5], coeff_lo[5], g2_pitch); + L_tmp = Mac_32_16(L_tmp, coeff[6], coeff_lo[6], g_pitch); + L_tmp = Mac_32_16(L_tmp, coeff[7], coeff_lo[7], g2_code); + L_tmp = Mac_32_16(L_tmp, coeff[8], coeff_lo[8], g_code); + L_tmp = Mac_32_16(L_tmp, coeff[9], coeff_lo[9], g_pit_cod); + + // store table index if MSE for this index is lower + than the minimum MSE seen so far + if (L_sub(L_tmp, dist_min) < (Word32) 0) + { + dist_min = L_tmp; + index = i; + } + } + } + + *------------------------------------------------------------------* + * read quantized gains and update MA predictor memories * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + *------------------------------------------------------------------* + + // for subframe 0, the pre-calculated gcode0/exp_gcode0 are the same + // as those calculated from the "real" predictor using quantized gains + tmp = shl(index, 2); + MR475_quant_store_results(pred_st, + &table_gain_MR475[tmp], + sf0_gcode0, + sf0_exp_gcode0, + sf0_gain_pit, + sf0_gain_cod); + + // calculate new predicted gain for subframe 1 (this time using + // the real, quantized gains) + gc_pred(pred_st, MR475, sf1_code_nosharp, + &sf1_exp_gcode0, &sf1_frac_gcode0, + &sf0_exp_gcode0, &sf0_gcode0); // last two args are dummy + sf1_gcode0 = extract_l(Pow2(14, sf1_frac_gcode0)); + + tmp = add (tmp, 2); + MR475_quant_store_results(pred_st, + &table_gain_MR475[tmp], + sf1_gcode0, + sf1_exp_gcode0, + sf1_gain_pit, + sf1_gain_cod); + + return index; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 MR475_gain_quant( /* o : index of quantization. */ + gc_predState *pred_st, /* i/o: gain predictor state struct */ + + /* data from subframe 0 (or 2) */ + Word16 sf0_exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 sf0_frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ + Word16 sf0_exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */ + Word16 sf0_frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */ + /* (frac_coeff and exp_coeff computed in */ + /* calc_filt_energies()) */ + Word16 sf0_exp_target_en, /* i : exponent of target energy, Q0 */ + Word16 sf0_frac_target_en, /* i : fraction of target energy, Q15 */ + + /* data from subframe 1 (or 3) */ + Word16 sf1_code_nosharp[], /* i : innovative codebook vector (L_SUBFR) */ + /* (whithout pitch sharpening) */ + Word16 sf1_exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 sf1_frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ + Word16 sf1_exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */ + Word16 sf1_frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */ + /* (frac_coeff and exp_coeff computed in */ + /* calc_filt_energies()) */ + Word16 sf1_exp_target_en, /* i : exponent of target energy, Q0 */ + Word16 sf1_frac_target_en, /* i : fraction of target energy, Q15 */ + + Word16 gp_limit, /* i : pitch gain limit */ + + Word16 *sf0_gain_pit, /* o : Pitch gain, Q14 */ + Word16 *sf0_gain_cod, /* o : Code gain, Q1 */ + + Word16 *sf1_gain_pit, /* o : Pitch gain, Q14 */ + Word16 *sf1_gain_cod, /* o : Code gain, Q1 */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + const Word16 *p; + Word16 i; + Word16 index = 0; + Word16 tmp; + Word16 exp; + Word16 sf0_gcode0; + Word16 sf1_gcode0; + Word16 g_pitch; + Word16 g2_pitch; + Word16 g_code; + Word16 g2_code; + Word16 g_pit_cod; + Word16 coeff[10]; + Word16 coeff_lo[10]; + Word16 exp_max[10]; /* 0..4: sf0; 5..9: sf1 */ + Word32 L_tmp; + Word32 dist_min; + + /*-------------------------------------------------------------------* + * predicted codebook gain * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * gc0 = 2^exp_gcode0 + 2^frac_gcode0 * + * * + * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) * + *-------------------------------------------------------------------*/ + + sf0_gcode0 = (Word16)(Pow2(14, sf0_frac_gcode0, pOverflow)); + sf1_gcode0 = (Word16)(Pow2(14, sf1_frac_gcode0, pOverflow)); + + /* + * For each subframe, the error energy (sum) to be minimized consists + * of five terms, t[0..4]. + * + * t[0] = gp^2 * + * t[1] = -2*gp * + * t[2] = gc^2 * + * t[3] = -2*gc * + * t[4] = 2*gp*gc * + * + */ + + /* sf 0 */ + /* determine the scaling exponent for g_code: ec = ec0 - 11 */ + exp = sf0_exp_gcode0 - 11; + + /* calculate exp_max[i] = s[i]-1 */ + exp_max[0] = (sf0_exp_coeff[0] - 13); + exp_max[1] = (sf0_exp_coeff[1] - 14); + exp_max[2] = (sf0_exp_coeff[2] + (15 + (exp << 1))); + exp_max[3] = (sf0_exp_coeff[3] + exp); + exp_max[4] = (sf0_exp_coeff[4] + (1 + exp)); + + /* sf 1 */ + /* determine the scaling exponent for g_code: ec = ec0 - 11 */ + exp = sf1_exp_gcode0 - 11; + + /* calculate exp_max[i] = s[i]-1 */ + exp_max[5] = (sf1_exp_coeff[0] - 13); + exp_max[6] = (sf1_exp_coeff[1] - 14); + exp_max[7] = (sf1_exp_coeff[2] + (15 + (exp << 1))); + exp_max[8] = (sf1_exp_coeff[3] + exp); + exp_max[9] = (sf1_exp_coeff[4] + (1 + exp)); + + /*-------------------------------------------------------------------* + * Gain search equalisation: * + * ~~~~~~~~~~~~~~~~~~~~~~~~~ * + * The MSE for the two subframes is weighted differently if there * + * is a big difference in the corresponding target energies * + *-------------------------------------------------------------------*/ + + /* make the target energy exponents the same by de-normalizing the + fraction of the smaller one. This is necessary to be able to compare + them + */ + exp = sf0_exp_target_en - sf1_exp_target_en; + if (exp > 0) + { + sf1_frac_target_en >>= exp; + } + else + { + sf0_frac_target_en >>= (-exp); + } + + /* assume no change of exponents */ + exp = 0; + + /* test for target energy difference; set exp to +1 or -1 to scale + * up/down coefficients for sf 1 + */ + tmp = shr_r(sf1_frac_target_en, 1, pOverflow); /* tmp = ceil(0.5*en(sf1)) */ + + if (tmp > sf0_frac_target_en) /* tmp > en(sf0)? */ + { + /* + * target_energy(sf1) > 2*target_energy(sf0) + * -> scale up MSE(sf0) by 2 by adding 1 to exponents 0..4 + */ + exp = 1; + } + else + { + tmp = ((sf0_frac_target_en + 3) >> 2); /* tmp=ceil(0.25*en(sf0)) */ + + if (tmp > sf1_frac_target_en) /* tmp > en(sf1)? */ + { + /* + * target_energy(sf1) < 0.25*target_energy(sf0) + * -> scale down MSE(sf0) by 0.5 by subtracting 1 from + * coefficients 0..4 + */ + exp = -1; + } + } + + for (i = 0; i < 5; i++) + { + exp_max[i] += exp; + } + + /*-------------------------------------------------------------------* + * Find maximum exponent: * + * ~~~~~~~~~~~~~~~~~~~~~~ * + * * + * For the sum operation, all terms must have the same scaling; * + * that scaling should be low enough to prevent overflow. There- * + * fore, the maximum scale is determined and all coefficients are * + * re-scaled: * + * * + * exp = max(exp_max[i]) + 1; * + * e = exp_max[i]-exp; e <= 0! * + * c[i] = c[i]*2^e * + *-------------------------------------------------------------------*/ + + exp = exp_max[0]; + for (i = 9; i > 0; i--) + { + if (exp_max[i] > exp) + { + exp = exp_max[i]; + } + } + exp++; /* To avoid overflow */ + + p = &sf0_frac_coeff[0]; + for (i = 0; i < 5; i++) + { + tmp = (exp - exp_max[i]); + L_tmp = ((Word32)(*p++) << 16); + L_tmp = L_shr(L_tmp, tmp, pOverflow); + coeff[i] = (Word16)(L_tmp >> 16); + coeff_lo[i] = (Word16)((L_tmp >> 1) - ((L_tmp >> 16) << 15)); + } + p = &sf1_frac_coeff[0]; + for (; i < 10; i++) + { + tmp = exp - exp_max[i]; + L_tmp = ((Word32)(*p++) << 16); + L_tmp = L_shr(L_tmp, tmp, pOverflow); + coeff[i] = (Word16)(L_tmp >> 16); + coeff_lo[i] = (Word16)((L_tmp >> 1) - ((L_tmp >> 16) << 15)); + } + + + /*-------------------------------------------------------------------* + * Codebook search: * + * ~~~~~~~~~~~~~~~~ * + * * + * For each pair (g_pitch, g_fac) in the table calculate the * + * terms t[0..4] and sum them up; the result is the mean squared * + * error for the quantized gains from the table. The index for the * + * minimum MSE is stored and finally used to retrieve the quantized * + * gains * + *-------------------------------------------------------------------*/ + + /* start with "infinite" MSE */ + dist_min = MAX_32; + + p = &table_gain_MR475[0]; + + for (i = 0; i < MR475_VQ_SIZE; i++) + { + /* subframe 0 (and 2) calculations */ + g_pitch = *p++; + g_code = *p++; + + /* Need to be there OKA */ + g_code = (Word16)(((Word32) g_code * sf0_gcode0) >> 15); + g2_pitch = (Word16)(((Word32) g_pitch * g_pitch) >> 15); + g2_code = (Word16)(((Word32) g_code * g_code) >> 15); + g_pit_cod = (Word16)(((Word32) g_code * g_pitch) >> 15); + + + L_tmp = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow) + + Mpy_32_16(coeff[1], coeff_lo[1], g_pitch, pOverflow) + + Mpy_32_16(coeff[2], coeff_lo[2], g2_code, pOverflow) + + Mpy_32_16(coeff[3], coeff_lo[3], g_code, pOverflow) + + Mpy_32_16(coeff[4], coeff_lo[4], g_pit_cod, pOverflow); + + tmp = (g_pitch - gp_limit); + + /* subframe 1 (and 3) calculations */ + g_pitch = *p++; + g_code = *p++; + + if ((tmp <= 0) && (g_pitch <= gp_limit)) + { + g_code = (Word16)(((Word32) g_code * sf1_gcode0) >> 15); + g2_pitch = (Word16)(((Word32) g_pitch * g_pitch) >> 15); + g2_code = (Word16)(((Word32) g_code * g_code) >> 15); + g_pit_cod = (Word16)(((Word32) g_code * g_pitch) >> 15); + + L_tmp += (Mpy_32_16(coeff[5], coeff_lo[5], g2_pitch, pOverflow) + + Mpy_32_16(coeff[6], coeff_lo[6], g_pitch, pOverflow) + + Mpy_32_16(coeff[7], coeff_lo[7], g2_code, pOverflow) + + Mpy_32_16(coeff[8], coeff_lo[8], g_code, pOverflow) + + Mpy_32_16(coeff[9], coeff_lo[9], g_pit_cod, pOverflow)); + + /* store table index if MSE for this index is lower + than the minimum MSE seen so far */ + if (L_tmp < dist_min) + { + dist_min = L_tmp; + index = i; + } + } + } + + /*------------------------------------------------------------------* + * read quantized gains and update MA predictor memories * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + *------------------------------------------------------------------*/ + + /* for subframe 0, the pre-calculated gcode0/exp_gcode0 are the same + as those calculated from the "real" predictor using quantized gains */ + tmp = index << 2; + MR475_quant_store_results(pred_st, + &table_gain_MR475[tmp], + sf0_gcode0, + sf0_exp_gcode0, + sf0_gain_pit, + sf0_gain_cod, + pOverflow); + + /* calculate new predicted gain for subframe 1 (this time using + the real, quantized gains) */ + gc_pred(pred_st, MR475, sf1_code_nosharp, + &sf1_exp_gcode0, &sf1_frac_gcode0, + &sf0_exp_gcode0, &sf0_gcode0, /* dummy args */ + pOverflow); + + sf1_gcode0 = (Word16)(Pow2(14, sf1_frac_gcode0, pOverflow)); + + tmp += 2; + MR475_quant_store_results( + pred_st, + &table_gain_MR475[tmp], + sf1_gcode0, + sf1_exp_gcode0, + sf1_gain_pit, + sf1_gain_cod, + pOverflow); + + return(index); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qgain475.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qgain475.h new file mode 100644 index 00000000..0dd3f46d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qgain475.h @@ -0,0 +1,166 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: qgain475.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains the defines and function prototypes used in the + quantization of pitch and codebook gains for MR475. + +------------------------------------------------------------------------------ +*/ +#ifndef _QGAIN475_H_ +#define _QGAIN475_H_ +#define qgain475_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "gc_pred.h" +#include "mode.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + /* minimum allowed gain code prediction error: 102.887/4096 = 0.0251189 */ +#define MIN_QUA_ENER ( -5443) /* Q10 <-> log2 (0.0251189) */ +#define MIN_QUA_ENER_MR122 (-32768) /* Q10 <-> 20*log10(0.0251189) */ + + /* minimum allowed gain code prediction error: 32000/4096 = 7.8125 */ +#define MAX_QUA_ENER ( 3037) /* Q10 <-> log2 (7.8125) */ +#define MAX_QUA_ENER_MR122 ( 18284) /* Q10 <-> 20*log10(7.8125) */ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + + /************************************************************************* + * + * FUNCTION: MR475_update_unq_pred() + * + * PURPOSE: use optimum codebook gain and update "unquantized" + * gain predictor with the (bounded) prediction error + * + *************************************************************************/ + void + MR475_update_unq_pred( + gc_predState *pred_st, /* i/o: gain predictor state struct */ + Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ + Word16 cod_gain_exp, /* i : optimum codebook gain (exponent), Q0 */ + Word16 cod_gain_frac, /* i : optimum codebook gain (fraction), Q15 */ + Flag *pOverflow /* o : overflow indicator */ + ); + + /************************************************************************* + * + * FUNCTION: MR475_gain_quant() + * + * PURPOSE: Quantization of pitch and codebook gains for two subframes + * (using predicted codebook gain) + * + *************************************************************************/ + + Word16 + MR475_gain_quant( /* o : index of quantization. */ + gc_predState *pred_st, /* i/o: gain predictor state struct */ + + /* data from subframe 0 (or 2) */ + Word16 sf0_exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 sf0_frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ + Word16 sf0_exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */ + Word16 sf0_frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */ + /* (frac_coeff and exp_coeff computed in */ + /* calc_filt_energies()) */ + Word16 sf0_exp_target_en, /* i : exponent of target energy, Q0 */ + Word16 sf0_frac_target_en, /* i : fraction of target energy, Q15 */ + + /* data from subframe 1 (or 3) */ + Word16 sf1_code_nosharp[], /* i : innovative codebook vector (L_SUBFR) */ + /* (whithout pitch sharpening) */ + Word16 sf1_exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 sf1_frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ + Word16 sf1_exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */ + Word16 sf1_frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */ + /* (frac_coeff and exp_coeff computed in */ + /* calc_filt_energies()) */ + Word16 sf1_exp_target_en, /* i : exponent of target energy, Q0 */ + Word16 sf1_frac_target_en, /* i : fraction of target energy, Q15 */ + + Word16 gp_limit, /* i : pitch gain limit */ + + Word16 *sf0_gain_pit, /* o : Pitch gain, Q14 */ + Word16 *sf0_gain_cod, /* o : Code gain, Q1 */ + + Word16 *sf1_gain_pit, /* o : Pitch gain, Q14 */ + Word16 *sf1_gain_cod, /* o : Code gain, Q1 */ + Flag *pOverflow /* o : overflow indicator */ + ); +#ifdef __cplusplus +} +#endif + +#endif /* _QGAIN475_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qgain795.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qgain795.cpp new file mode 100644 index 00000000..9bd49520 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qgain795.cpp @@ -0,0 +1,832 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: qgain795.cpp + Functions: MR795_gain_code_quant3 + MR795_gain_code_quant_mod + MR795_gain_quant + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "qgain795.h" +#include "typedef.h" +#include "basic_op.h" +#include "cnst.h" +#include "log2.h" +#include "pow2.h" +#include "sqrt_l.h" +#include "g_adapt.h" +#include "calc_en.h" +#include "q_gain_p.h" + + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ +#define NB_QUA_CODE 32 + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: MR795_gain_code_quant3 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0 + gcode0 -- Word16 -- predicted CB gain (norm.) + g_pitch_cand[] -- Word16 array -- Pitch gain candidates (3), Q14 + g_pitch_cind[] -- Word16 array -- Pitch gain cand. indices (3), Q0 + frac_coeff[] -- Word16 array -- coefficients (5), Q15 + exp_coeff[] -- Word16 array -- energy coefficients (5), Q0 + coefficients from calc_filt_ener() + + Outputs: + gain_pit -- Pointer to Word16 -- Pitch gain, Q14 + gain_pit_ind -- Pointer to Word16 -- Pitch gain index, Q0 + gain_cod -- Pointer to Word16 -- Code gain, Q1 + gain_cod_ind -- Pointer to Word16 -- Code gain index, Q0 + qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10 + (for MR122 MA predictor update) + + qua_ener -- Pointer to Word16 -- quantized energy error, Q10 + (for other MA predictor update) + + pOverflow -- Pointer to Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Pre-quantization of codebook gains, given three possible + LTP gains (using predicted codebook gain) +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void +MR795_gain_code_quant3( + Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */ + Word16 g_pitch_cand[], /* i : Pitch gain candidates (3), Q14 */ + Word16 g_pitch_cind[], /* i : Pitch gain cand. indices (3), Q0 */ + Word16 frac_coeff[], /* i : coefficients (5), Q15 */ + Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */ + /* coefficients from calc_filt_ener()*/ + Word16 *gain_pit, /* o : Pitch gain, Q14 */ + Word16 *gain_pit_ind, /* o : Pitch gain index, Q0 */ + Word16 *gain_cod, /* o : Code gain, Q1 */ + Word16 *gain_cod_ind, /* o : Code gain index, Q0 */ + Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ + /* (for MR122 MA predictor update) */ + Word16 *qua_ener, /* o : quantized energy error, Q10 */ + /* (for other MA predictor update) */ + const Word16* qua_gain_code_ptr, /* i : ptr to read-only table */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + const Word16 *p; + Word16 i; + Word16 j; + Word16 cod_ind; + Word16 pit_ind; + Word16 e_max; + Word16 exp_code; + Word16 g_pitch; + Word16 g2_pitch; + Word16 g_code; + Word16 g2_code_h; + Word16 g2_code_l; + Word16 g_pit_cod_h; + Word16 g_pit_cod_l; + Word16 coeff[5]; + Word16 coeff_lo[5]; + Word16 exp_max[5]; + Word32 L_tmp; + Word32 L_tmp0; + Word32 dist_min; + + /* + * The error energy (sum) to be minimized consists of five terms, t[0..4]. + * + * t[0] = gp^2 * + * t[1] = -2*gp * + * t[2] = gc^2 * + * t[3] = -2*gc * + * t[4] = 2*gp*gc * + * + */ + + /* determine the scaling exponent for g_code: ec = ec0 - 10 */ + exp_code = exp_gcode0 - 10; + + /* calculate exp_max[i] = s[i]-1 */ + exp_max[0] = exp_coeff[0] - 13; + exp_max[1] = exp_coeff[1] - 14; + exp_max[2] = exp_coeff[2] + shl(exp_code, 1, pOverflow) + 15; + exp_max[3] = exp_coeff[3] + exp_code; + exp_max[4] = exp_coeff[4] + (exp_code + 1); + + + /*-------------------------------------------------------------------* + * Find maximum exponent: * + * ~~~~~~~~~~~~~~~~~~~~~~ * + * * + * For the sum operation, all terms must have the same scaling; * + * that scaling should be low enough to prevent overflow. There- * + * fore, the maximum scale is determined and all coefficients are * + * re-scaled: * + * * + * e_max = max(exp_max[i]) + 1; * + * e = exp_max[i]-e_max; e <= 0! * + * c[i] = c[i]*2^e * + *-------------------------------------------------------------------*/ + + e_max = exp_max[0]; + for (i = 1; i < 5; i++) /* implemented flattened */ + { + if (exp_max[i] > e_max) + { + e_max = exp_max[i]; + } + } + + e_max = add_16(e_max, 1, pOverflow); /* To avoid overflow */ + + for (i = 0; i < 5; i++) + { + j = e_max - exp_max[i]; + L_tmp = ((Word32)frac_coeff[i] << 16); + L_tmp = L_shr(L_tmp, j, pOverflow); + L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow); + } + + + /*-------------------------------------------------------------------* + * Codebook search: * + * ~~~~~~~~~~~~~~~~ * + * * + * For each of the candiates LTP gains in g_pitch_cand[], the terms * + * t[0..4] are calculated from the values in the table (and the * + * pitch gain candidate) and summed up; the result is the mean * + * squared error for the LPT/CB gain pair. The index for the mini- * + * mum MSE is stored and finally used to retrieve the quantized CB * + * gain * + *-------------------------------------------------------------------*/ + + /* start with "infinite" MSE */ + dist_min = MAX_32; + cod_ind = 0; + pit_ind = 0; + + /* loop through LTP gain candidates */ + for (j = 0; j < 3; j++) + { + /* pre-calculate terms only dependent on pitch gain */ + g_pitch = g_pitch_cand[j]; + g2_pitch = mult(g_pitch, g_pitch, pOverflow); + L_tmp0 = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow); + L_tmp0 = Mac_32_16(L_tmp0, coeff[1], coeff_lo[1], g_pitch, pOverflow); + + p = &qua_gain_code_ptr[0]; + for (i = 0; i < NB_QUA_CODE; i++) + { + g_code = *p++; /* this is g_fac Q11 */ + p++; /* skip log2(g_fac) */ + p++; /* skip 20*log10(g_fac) */ + + g_code = mult(g_code, gcode0, pOverflow); + + L_tmp = L_mult(g_code, g_code, pOverflow); + L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow); + + L_tmp = L_mult(g_code, g_pitch, pOverflow); + L_Extract(L_tmp, &g_pit_cod_h, &g_pit_cod_l, pOverflow); + + L_tmp = Mac_32(L_tmp0, coeff[2], coeff_lo[2], + g2_code_h, g2_code_l, pOverflow); + L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3], + g_code, pOverflow); + L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], + g_pit_cod_h, g_pit_cod_l, pOverflow); + + /* store table index if MSE for this index is lower + than the minimum MSE seen so far; also store the + pitch gain for this (so far) lowest MSE */ + if (L_tmp < dist_min) + { + dist_min = L_tmp; + cod_ind = i; + pit_ind = j; + } + } + } + + /*------------------------------------------------------------------* + * read quantized gains and new values for MA predictor memories * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + *------------------------------------------------------------------*/ + + /* Read the quantized gains */ + p = &qua_gain_code_ptr[(cod_ind<<2) - cod_ind]; + + g_code = *p++; + *qua_ener_MR122 = *p++; + *qua_ener = *p; + + /*------------------------------------------------------------------* + * calculate final fixed codebook gain: * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * * + * gc = gc0 * g * + *------------------------------------------------------------------*/ + + L_tmp = L_mult(g_code, gcode0, pOverflow); + L_tmp = L_shr(L_tmp, 9 - exp_gcode0, pOverflow); + *gain_cod = (Word16)(L_tmp >> 16); + *gain_cod_ind = cod_ind; + *gain_pit = g_pitch_cand[pit_ind]; + *gain_pit_ind = g_pitch_cind[pit_ind]; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: MR795_gain_code_quant_mod +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + gain_pit -- Word16 -- pitch gain, Q14 + exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0 + gcode0 -- Word16 -- predicted CB gain (norm.), Q14 + frac_en[] -- Word16 array -- energy coefficients (4), fraction part, Q15 + exp_en[] -- Word16 array -- energy coefficients (4), exponent part, Q0 + alpha -- Word16 -- gain adaptor factor (>0), Q15 + + gain_cod_unq -- Word16 -- Code gain (unquantized) + (scaling: Q10 - exp_gcode0) + + gain_cod -- Pointer to Word16 -- Code gain (pre-/quantized), Q1 + + Outputs: + qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10 + (for MR122 MA predictor update) + qua_ener -- Pointer to Word16 -- quantized energy error, Q10 + (for other MA predictor update) + pOverflow -- Pointer to Flag -- overflow indicator + + Returns: + index of quantization (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + PURPOSE: Modified quantization of the MR795 codebook gain + + Uses pre-computed energy coefficients in frac_en[]/exp_en[] + + frac_en[0]*2^exp_en[0] = // LP residual energy + frac_en[1]*2^exp_en[1] = // LTP residual energy + frac_en[2]*2^exp_en[2] = // LTP/CB innovation dot product + frac_en[3]*2^exp_en[3] = // CB innovation energy +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 +MR795_gain_code_quant_mod( /* o : index of quantization. */ + Word16 gain_pit, /* i : pitch gain, Q14 */ + Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */ + Word16 frac_en[], /* i : energy coefficients (4), + fraction part, Q15 */ + Word16 exp_en[], /* i : energy coefficients (4), + eponent part, Q0 */ + Word16 alpha, /* i : gain adaptor factor (>0), Q15 */ + Word16 gain_cod_unq, /* i : Code gain (unquantized) */ + /* (scaling: Q10 - exp_gcode0) */ + Word16 *gain_cod, /* i/o: Code gain (pre-/quantized), Q1 */ + Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ + /* (for MR122 MA predictor update) */ + Word16 *qua_ener, /* o : quantized energy error, Q10 */ + /* (for other MA predictor update) */ + const Word16* qua_gain_code_ptr, /* i : ptr to read-only ptr */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + const Word16 *p; + Word16 i; + Word16 index; + Word16 tmp; + Word16 one_alpha; + Word16 exp; + Word16 e_max; + + Word16 g2_pitch; + Word16 g_code; + Word16 g2_code_h; + Word16 g2_code_l; + Word16 d2_code_h; + Word16 d2_code_l; + Word16 coeff[5]; + Word16 coeff_lo[5]; + Word16 exp_coeff[5]; + Word32 L_tmp; + Word32 L_t0; + Word32 L_t1; + Word32 dist_min; + Word16 gain_code; + + /* + Steps in calculation of the error criterion (dist): + --------------------------------------------------- + + underlined = constant; alp = FLP value of alpha, alpha = FIP + ---------- + + + ExEn = gp^2 * LtpEn + 2.0*gp*gc[i] * XC + gc[i]^2 * InnEn; + ------------ ------ -- ----- + + aExEn= alp * ExEn + = alp*gp^2*LtpEn + 2.0*alp*gp*XC* gc[i] + alp*InnEn* gc[i]^2 + -------------- ------------- --------- + + = t[1] + t[2] + t[3] + + dist = d1 + d2; + + d1 = (1.0 - alp) * InnEn * (gcu - gc[i])^2 = t[4] + ------------------- --- + + d2 = alp * (ResEn - 2.0 * sqrt(ResEn*ExEn) + ExEn); + --- ----- --- ----- + + = alp * (sqrt(ExEn) - sqrt(ResEn))^2 + --- ----------- + + = (sqrt(aExEn) - sqrt(alp*ResEn))^2 + --------------- + + = (sqrt(aExEn) - t[0] )^2 + ---- + + */ + + /* + * calculate scalings of the constant terms + */ + gain_code = shl(*gain_cod, (10 - exp_gcode0), pOverflow); /* Q1 -> Q11 (-ec0) */ + g2_pitch = mult(gain_pit, gain_pit, pOverflow); /* Q14 -> Q13 */ + /* 0 < alpha <= 0.5 => 0.5 <= 1-alpha < 1, i.e one_alpha is normalized */ + one_alpha = add_16((32767 - alpha), 1, pOverflow); /* 32768 - alpha */ + + + /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */ + L_t1 = L_mult(alpha, frac_en[1], pOverflow); + L_t1 = L_shl(L_t1, 1, pOverflow); + tmp = (Word16)(L_t1 >> 16); + + /* directly store in 32 bit variable because no further mult. required */ + L_t1 = L_mult(tmp, g2_pitch, pOverflow); + exp_coeff[1] = exp_en[1] - 15; + + + tmp = (Word16)(L_shl(L_mult(alpha, frac_en[2], pOverflow), 1, pOverflow) >> 16); + coeff[2] = mult(tmp, gain_pit, pOverflow); + exp = exp_gcode0 - 10; + exp_coeff[2] = add_16(exp_en[2], exp, pOverflow); + + + /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */ + coeff[3] = (Word16)(L_shl(L_mult(alpha, frac_en[3], pOverflow), 1, pOverflow) >> 16); + exp = shl(exp_gcode0, 1, pOverflow) - 7; + exp_coeff[3] = add_16(exp_en[3], exp, pOverflow); + + + coeff[4] = mult(one_alpha, frac_en[3], pOverflow); + exp_coeff[4] = add_16(exp_coeff[3], 1, pOverflow); + + + L_tmp = L_mult(alpha, frac_en[0], pOverflow); + /* sqrt_l returns normalized value and 2*exponent + -> result = val >> (exp/2) + exp_coeff holds 2*exponent for c[0] */ + /* directly store in 32 bit variable because no further mult. required */ + L_t0 = sqrt_l_exp(L_tmp, &exp, pOverflow); /* normalization included in sqrt_l_exp */ + exp += 47; + exp_coeff[0] = exp_en[0] - exp; + + /* + * Determine the maximum exponent occuring in the distance calculation + * and adjust all fractions accordingly (including a safety margin) + * + */ + + /* find max(e[1..4],e[0]+31) */ + e_max = exp_coeff[0] + 31; + for (i = 1; i <= 4; i++) + { + if (exp_coeff[i] > e_max) + { + e_max = exp_coeff[i]; + } + } + + /* scale c[1] (requires no further multiplication) */ + tmp = e_max - exp_coeff[1]; + L_t1 = L_shr(L_t1, tmp, pOverflow); + + /* scale c[2..4] (used in Mpy_32_16 in the quantizer loop) */ + for (i = 2; i <= 4; i++) + { + tmp = e_max - exp_coeff[i]; + L_tmp = ((Word32)coeff[i] << 16); + L_tmp = L_shr(L_tmp, tmp, pOverflow); + L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow); + } + + /* scale c[0] (requires no further multiplication) */ + exp = e_max - 31; /* new exponent */ + tmp = exp - exp_coeff[0]; + L_t0 = L_shr(L_t0, shr(tmp, 1, pOverflow), pOverflow); + /* perform correction by 1/sqrt(2) if exponent difference is odd */ + if ((tmp & 0x1) != 0) + { + L_Extract(L_t0, &coeff[0], &coeff_lo[0], pOverflow); + L_t0 = Mpy_32_16(coeff[0], coeff_lo[0], + 23170, pOverflow); /* 23170 Q15 = 1/sqrt(2)*/ + } + + /* search the quantizer table for the lowest value + of the search criterion */ + dist_min = MAX_32; + index = 0; + p = &qua_gain_code_ptr[0]; + + for (i = 0; i < NB_QUA_CODE; i++) + { + g_code = *p++; /* this is g_fac (Q11) */ + p++; /* skip log2(g_fac) */ + p++; /* skip 20*log10(g_fac) */ + g_code = mult(g_code, gcode0, pOverflow); + + /* only continue if gc[i] < 2.0*gc + which is equiv. to g_code (Q10-ec0) < gain_code (Q11-ec0) */ + + if (g_code >= gain_code) + { + break; + } + + L_tmp = L_mult(g_code, g_code, pOverflow); + L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow); + + tmp = sub(g_code, gain_cod_unq, pOverflow); + L_tmp = L_mult(tmp, tmp, pOverflow); + L_Extract(L_tmp, &d2_code_h, &d2_code_l, pOverflow); + + /* t2, t3, t4 */ + L_tmp = Mac_32_16(L_t1, coeff[2], coeff_lo[2], g_code, pOverflow); + L_tmp = Mac_32(L_tmp, coeff[3], coeff_lo[3], g2_code_h, g2_code_l, pOverflow); + + L_tmp = sqrt_l_exp(L_tmp, &exp, pOverflow); + L_tmp = L_shr(L_tmp, shr(exp, 1, pOverflow), pOverflow); + + /* d2 */ + tmp = pv_round(L_sub(L_tmp, L_t0, pOverflow), pOverflow); + L_tmp = L_mult(tmp, tmp, pOverflow); + + /* dist */ + L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], d2_code_h, d2_code_l, pOverflow); + + /* store table index if distance measure for this + index is lower than the minimum seen so far */ + if (L_tmp < dist_min) + { + dist_min = L_tmp; + index = i; + } + } + + /*------------------------------------------------------------------* + * read quantized gains and new values for MA predictor memories * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + *------------------------------------------------------------------*/ + + /* Read the quantized gains */ + p = &qua_gain_code_ptr[(index<<2) - index]; + g_code = *p++; + *qua_ener_MR122 = *p++; + *qua_ener = *p; + + /*------------------------------------------------------------------* + * calculate final fixed codebook gain: * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * * + * gc = gc0 * g * + *------------------------------------------------------------------*/ + + L_tmp = L_mult(g_code, gcode0, pOverflow); + L_tmp = L_shr(L_tmp, 9 - exp_gcode0, pOverflow); + *gain_cod = (Word16)(L_tmp >> 16); + + return index; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: MR795_gain_quant +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS +MR795_gain_quant( + + + Inputs: + adapt_st -- Pointer to GainAdaptState -- gain adapter state structure + res -- Word16 array -- LP residual, Q0 + exc -- Word16 array -- LTP excitation (unfiltered), Q0 + code -- Word16 array -- CB innovation (unfiltered), Q13 + frac_coeff -- Word16 array -- coefficients (5), Q15 + exp_coeff -- Word16 array -- energy coefficients (5), Q0 + coefficients from calc_filt_ener() + exp_code_en -- Word16 -- innovation energy (exponent), Q0 + frac_code_en -- Word16 -- innovation energy (fraction), Q15 + exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0 + frac_gcode0 -- Word16 -- predicted CB gain (fraction), Q15 + L_subfr -- Word16 -- Subframe length + cod_gain_frac -- Word16 -- opt. codebook gain (fraction),Q15 + cod_gain_exp -- Word16 -- opt. codebook gain (exponent), Q0 + gp_limit -- Word16 -- pitch gain limit + gain_pit -- Pointer to Word16 -- Pitch gain, Q14 + + Output + adapt_st -- Pointer to GainAdaptState -- gain adapter state structure + gain_pit -- Pointer to Word16 -- Pitch gain, Q14 + + gain_pit -- Pointer to Word16 -- Pitch gain, Q14 + gain_cod -- Pointer to Word16 -- Code gain, Q1 + qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10 + (for MR122 MA predictor update) + + qua_ener -- Pointer to Word16 -- quantized energy error, Q10 + (for other MA predictor update) + + anap -- Double Pointer to Word16 -- Index of quantization + (first gain pitch, then code pitch) + + pOverflow -- Pointer to Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + pitch and codebook quantization for MR795 +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void +MR795_gain_quant( + GainAdaptState *adapt_st, /* i/o: gain adapter state structure */ + Word16 res[], /* i : LP residual, Q0 */ + Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ + Word16 code[], /* i : CB innovation (unfiltered), Q13 */ + Word16 frac_coeff[], /* i : coefficients (5), Q15 */ + Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */ + /* coefficients from calc_filt_ener() */ + Word16 exp_code_en, /* i : innovation energy (exponent), Q0 */ + Word16 frac_code_en, /* i : innovation energy (fraction), Q15 */ + Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ + Word16 L_subfr, /* i : Subframe length */ + Word16 cod_gain_frac, /* i : opt. codebook gain (fraction),Q15 */ + Word16 cod_gain_exp, /* i : opt. codebook gain (exponent), Q0 */ + Word16 gp_limit, /* i : pitch gain limit */ + Word16 *gain_pit, /* i/o: Pitch gain, Q14 */ + Word16 *gain_cod, /* o : Code gain, Q1 */ + Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ + /* (for MR122 MA predictor update) */ + Word16 *qua_ener, /* o : quantized energy error, Q10 */ + /* (for other MA predictor update) */ + Word16 **anap, /* o : Index of quantization */ + /* (first gain pitch, then code pitch)*/ + CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of table ptrs */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + Word16 frac_en[4]; + Word16 exp_en[4]; + Word16 ltpg, alpha, gcode0; + Word16 g_pitch_cand[3]; /* pitch gain candidates Q14 */ + Word16 g_pitch_cind[3]; /* pitch gain indices Q0 */ + Word16 gain_pit_index; + Word16 gain_cod_index; + Word16 exp; + Word16 gain_cod_unq; /* code gain (unq.) Q(10-exp_gcode0) */ + + + /* get list of candidate quantized pitch gain values + * and corresponding quantization indices + */ + gain_pit_index = q_gain_pitch(MR795, gp_limit, gain_pit, + g_pitch_cand, g_pitch_cind, common_amr_tbls->qua_gain_pitch_ptr, pOverflow); + + /*-------------------------------------------------------------------* + * predicted codebook gain * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * gc0 = 2^exp_gcode0 + 2^frac_gcode0 * + * * + * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) * + *-------------------------------------------------------------------*/ + gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow)); /* Q14 */ + + /* pre-quantization of codebook gain + * (using three pitch gain candidates); + * result: best guess of pitch gain and code gain + */ + MR795_gain_code_quant3( + exp_gcode0, gcode0, g_pitch_cand, g_pitch_cind, + frac_coeff, exp_coeff, + gain_pit, &gain_pit_index, gain_cod, &gain_cod_index, + qua_ener_MR122, qua_ener, common_amr_tbls->qua_gain_code_ptr, pOverflow); + + /* calculation of energy coefficients and LTP coding gain */ + calc_unfilt_energies(res, exc, code, *gain_pit, L_subfr, + frac_en, exp_en, <pg, pOverflow); + + /* run gain adaptor, calculate alpha factor to balance LTP/CB gain + * (this includes the gain adaptor update) + * Note: ltpg = 0 if frac_en[0] == 0, so the update is OK in that case + */ + gain_adapt(adapt_st, ltpg, *gain_cod, &alpha, pOverflow); + + /* if this is a very low energy signal (threshold: see + * calc_unfilt_energies) or alpha <= 0 then don't run the modified quantizer + */ + if (frac_en[0] != 0 && alpha > 0) + { + /* innovation energy was already computed in gc_pred() */ + /* (this overwrites the LtpResEn which is no longer needed) */ + frac_en[3] = frac_code_en; + exp_en[3] = exp_code_en; + + /* store optimum codebook gain in Q(10-exp_gcode0) */ + exp = sub(cod_gain_exp, exp_gcode0, pOverflow) + 10; + gain_cod_unq = shl(cod_gain_frac, exp, pOverflow); + + /* run quantization with modified criterion */ + gain_cod_index = MR795_gain_code_quant_mod( + *gain_pit, exp_gcode0, gcode0, + frac_en, exp_en, alpha, gain_cod_unq, + gain_cod, qua_ener_MR122, qua_ener, common_amr_tbls->qua_gain_code_ptr, + pOverflow); /* function result */ + } + + *(*anap)++ = gain_pit_index; + *(*anap)++ = gain_cod_index; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qgain795.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qgain795.h new file mode 100644 index 00000000..a4d9a5aa --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qgain795.h @@ -0,0 +1,133 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: qgain795.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the file, qgain795.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef qgain795_h +#define qgain795_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "g_adapt.h" +#include "get_const_tbls.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void + MR795_gain_quant( + GainAdaptState *adapt_st, /* i/o: gain adapter state structure */ + Word16 res[], /* i : LP residual, Q0 */ + Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ + Word16 code[], /* i : CB innovation (unfiltered), Q13 */ + Word16 frac_coeff[], /* i : coefficients (5), Q15 */ + Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */ + /* coefficients from calc_filt_ener() */ + Word16 exp_code_en, /* i : innovation energy (exponent), Q0 */ + Word16 frac_code_en, /* i : innovation energy (fraction), Q15 */ + Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ + Word16 L_subfr, /* i : Subframe length */ + Word16 cod_gain_frac, /* i : opt. codebook gain (fraction),Q15 */ + Word16 cod_gain_exp, /* i : opt. codebook gain (exponent), Q0 */ + Word16 gp_limit, /* i : pitch gain limit */ + Word16 *gain_pit, /* i/o: Pitch gain (unquant/quant), Q14 */ + Word16 *gain_cod, /* o : Code gain, Q1 */ + Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ + /* (for MR122 MA predictor update) */ + Word16 *qua_ener, /* o : quantized energy error, Q10 */ + /* (for other MA predictor update) */ + Word16 **anap, /* o : Index of quantization */ + /* (first gain pitch, then code pitch)*/ + CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of table ptrs */ + Flag *pOverflow /* o : overflow indicator */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* qgain795_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qua_gain.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qua_gain.cpp new file mode 100644 index 00000000..5a4e1c81 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/qua_gain.cpp @@ -0,0 +1,363 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: qua_gain.cpp + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Quantization of pitch and codebook gains. +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "qua_gain.h" +#include "typedef.h" +#include "basic_op.h" + +#include "mode.h" +#include "cnst.h" +#include "pow2.h" +#include "gc_pred.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. Include conditional + ; compile variables also. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; LOCAL VARIABLE DEFINITIONS + ; Variable declaration - defined here and used outside this module + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + + Inputs: + mode -- enum Mode -- AMR mode + Word16 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0 + Word16 frac_gcode0 -- Word16 -- predicted CB gain (fraction), Q15 + Word16 frac_coeff -- Word16 Array -- energy coeff. (5), fraction part, Q15 + Word16 exp_coeff -- Word16 Array -- energy coeff. (5), exponent part, Q0 + (frac_coeff and exp_coeff computed in + calc_filt_energies()) + + Word16 gp_limit -- Word16 -- pitch gain limit + + Outputs: + Word16 *gain_pit -- Pointer to Word16 -- Pitch gain, Q14 + Word16 *gain_cod -- Pointer to Word16 -- Code gain, Q1 + Word16 *qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10 + (for MR122 MA predictor update) + Word16 *qua_ener -- Pointer to Word16 -- quantized energy error, Q10 + (for other MA predictor update) + Flag *pOverflow -- Pointer to Flag -- overflow indicator + + Returns: + Word16 -- index of quantization. + + Global Variables Used: + + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Quantization of pitch and codebook gains. +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + qua_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + + +Word16 +Qua_gain( /* o : index of quantization. */ + enum Mode mode, /* i : AMR mode */ + Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ + Word16 frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */ + Word16 exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */ + /* (frac_coeff and exp_coeff computed in */ + /* calc_filt_energies()) */ + Word16 gp_limit, /* i : pitch gain limit */ + Word16 *gain_pit, /* o : Pitch gain, Q14 */ + Word16 *gain_cod, /* o : Code gain, Q1 */ + Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ + /* (for MR122 MA predictor update) */ + Word16 *qua_ener, /* o : quantized energy error, Q10 */ + /* (for other MA predictor update) */ + CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of tables ptrs */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + const Word16 *p; + Word16 i; + Word16 j; + Word16 index = 0; + Word16 gcode0; + Word16 e_max; + Word16 temp; + Word16 exp_code; + Word16 g_pitch; + Word16 g2_pitch; + Word16 g_code; + Word16 g2_code; + Word16 g_pit_cod; + Word16 coeff[5]; + Word16 coeff_lo[5]; + Word16 exp_max[5]; + Word32 L_tmp; + Word32 L_tmp2; + Word32 dist_min; + const Word16 *table_gain; + Word16 table_len; + + if (mode == MR102 || mode == MR74 || mode == MR67) + { + table_len = VQ_SIZE_HIGHRATES; + table_gain = common_amr_tbls->table_gain_highrates_ptr; + } + else + { + table_len = VQ_SIZE_LOWRATES; + table_gain = common_amr_tbls->table_gain_lowrates_ptr; + } + + /*-------------------------------------------------------------------* + * predicted codebook gain * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * gc0 = 2^exp_gcode0 + 2^frac_gcode0 * + * * + * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) * + *-------------------------------------------------------------------*/ + + gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow)); + + /*-------------------------------------------------------------------* + * Scaling considerations: * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + *-------------------------------------------------------------------*/ + + /* + * The error energy (sum) to be minimized consists of five terms, t[0..4]. + * + * t[0] = gp^2 * + * t[1] = -2*gp * + * t[2] = gc^2 * + * t[3] = -2*gc * + * t[4] = 2*gp*gc * + * + */ + + /* determine the scaling exponent for g_code: ec = ec0 - 11 */ + exp_code = exp_gcode0 - 11; + + /* calculate exp_max[i] = s[i]-1 */ + exp_max[0] = exp_coeff[0] - 13; + exp_max[1] = exp_coeff[1] - 14; + + temp = shl(exp_code, 1, pOverflow); + temp += 15; + exp_max[2] = add_16(exp_coeff[2], temp, pOverflow); + + exp_max[3] = add_16(exp_coeff[3], exp_code, pOverflow); + + temp = exp_code + 1; + exp_max[4] = add_16(exp_coeff[4], temp, pOverflow); + + + /*-------------------------------------------------------------------* + * Find maximum exponent: * + * ~~~~~~~~~~~~~~~~~~~~~~ * + * * + * For the sum operation, all terms must have the same scaling; * + * that scaling should be low enough to prevent overflow. There- * + * fore, the maximum scale is determined and all coefficients are * + * re-scaled: * + * * + * e_max = max(exp_max[i]) + 1; * + * e = exp_max[i]-e_max; e <= 0! * + * c[i] = c[i]*2^e * + *-------------------------------------------------------------------*/ + + e_max = exp_max[0]; + for (i = 1; i < 5; i++) + { + if (exp_max[i] > e_max) + { + e_max = exp_max[i]; + } + } + + e_max++; + + for (i = 0; i < 5; i++) + { + j = e_max - exp_max[i]; + L_tmp = ((Word32)frac_coeff[i] << 16); + L_tmp = L_shr(L_tmp, j, pOverflow); + L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow); + } + + + /*-------------------------------------------------------------------* + * Codebook search: * + * ~~~~~~~~~~~~~~~~ * + * * + * For each pair (g_pitch, g_fac) in the table calculate the * + * terms t[0..4] and sum them up; the result is the mean squared * + * error for the quantized gains from the table. The index for the * + * minimum MSE is stored and finally used to retrieve the quantized * + * gains * + *-------------------------------------------------------------------*/ + + /* start with "infinite" MSE */ + dist_min = MAX_32; + + p = &table_gain[0]; + + for (i = 0; i < table_len; i++) + { + g_pitch = *p++; + g_code = *p++; /* this is g_fac */ + p++; /* skip log2(g_fac) */ + p++; /* skip 20*log10(g_fac) */ + + if (g_pitch <= gp_limit) + { + g_code = mult(g_code, gcode0, pOverflow); + g2_pitch = mult(g_pitch, g_pitch, pOverflow); + g2_code = mult(g_code, g_code, pOverflow); + g_pit_cod = mult(g_code, g_pitch, pOverflow); + + L_tmp = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow); + L_tmp2 = Mpy_32_16(coeff[1], coeff_lo[1], g_pitch, pOverflow); + L_tmp = L_add(L_tmp, L_tmp2, pOverflow); + + L_tmp2 = Mpy_32_16(coeff[2], coeff_lo[2], g2_code, pOverflow); + L_tmp = L_add(L_tmp, L_tmp2, pOverflow); + + L_tmp2 = Mpy_32_16(coeff[3], coeff_lo[3], g_code, pOverflow); + L_tmp = L_add(L_tmp, L_tmp2, pOverflow); + + L_tmp2 = Mpy_32_16(coeff[4], coeff_lo[4], g_pit_cod, pOverflow); + L_tmp = L_add(L_tmp, L_tmp2, pOverflow); + + /* store table index if MSE for this index is lower + than the minimum MSE seen so far */ + if (L_tmp < dist_min) + { + dist_min = L_tmp; + index = i; + } + } + } + + /*------------------------------------------------------------------* + * read quantized gains and new values for MA predictor memories * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + *------------------------------------------------------------------*/ + + /* Read the quantized gains */ + p = &table_gain[shl(index, 2, pOverflow)]; + *gain_pit = *p++; + g_code = *p++; + *qua_ener_MR122 = *p++; + *qua_ener = *p; + + /*------------------------------------------------------------------* + * calculate final fixed codebook gain: * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * * + * gc = gc0 * g * + *------------------------------------------------------------------*/ + + L_tmp = L_mult(g_code, gcode0, pOverflow); + temp = 10 - exp_gcode0; + L_tmp = L_shr(L_tmp, temp, pOverflow); + + *gain_cod = (Word16)(L_tmp >> 16); + + return index; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/s10_8pf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/s10_8pf.cpp new file mode 100644 index 00000000..f8bf23f6 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/s10_8pf.cpp @@ -0,0 +1,916 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: s10_8pf.cpp + Funtions: search_10and8i40 + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "s10_8pf.h" +#include "cnst.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: search_10and8i40 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + nbPulse = nbPulses to find (Word16) + step = step size (Word16) + nbTracks = nbTracks (Word16) + dn[] = correlation between target and h[] (Word16) + rr[][] = matrix of autocorrelation (Word16) + ipos[] = starting position of each pulse (Word16) + pos_max[] = Position of maximum dn[] (Word16) + codvec[] = Algebraic codebook vector (Word16) + pOverflow = pointer to Overflow flag (Flag) + + Outputs: + codvec[] = Algebraic codebook vector (Word16) + pOverflow -> 1 if processing this funvction results in satuaration + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function searches for the best codevector; It determines the positions + of the 10/8 pulses in the 40-sample frame. + + search_10and8i40 (10,5,5,dn, rr, ipos, pos_max, codvec); for GSMEFR + search_10and8i40 (8, 4,4,dn, rr, ipos, pos_max, codvec); for 10.2 + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + s10_8pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void search_10and8i40 ( + Word16 nbPulse, // i : nbpulses to find + Word16 step, // i : stepsize + Word16 nbTracks, // i : nbTracks + Word16 dn[], // i : correlation between target and h[] + Word16 rr[][L_CODE], // i : matrix of autocorrelation + Word16 ipos[], // i : starting position for each pulse + Word16 pos_max[], // i : position of maximum of dn[] + Word16 codvec[] // o : algebraic codebook vector +) +{ + Word16 i0, i1, i2, i3, i4, i5, i6, i7, i8, i9; + Word16 i, j, k, pos, ia, ib; + Word16 psk, ps, ps0, ps1, ps2, sq, sq2; + Word16 alpk, alp, alp_16; + Word16 rrv[L_CODE]; + Word32 s, alp0, alp1, alp2; + Word16 gsmefrFlag; + + + if (sub(nbPulse, 10) == 0) + { + gsmefrFlag=1; + } + else + { + gsmefrFlag=0; + } + + // fix i0 on maximum of correlation position + i0 = pos_max[ipos[0]]; + + // + // i1 loop: * + // + + // Default value + + psk = -1; + alpk = 1; + for (i = 0; i < nbPulse; i++) + { + codvec[i] = i; + } + + for (i = 1; i < nbTracks; i++) + { + i1 = pos_max[ipos[1]]; + ps0 = add (dn[i0], dn[i1]); + alp0 = L_mult (rr[i0][i0], _1_16); + alp0 = L_mac (alp0, rr[i1][i1], _1_16); + alp0 = L_mac (alp0, rr[i0][i1], _1_8); + + // + // i2 and i3 loop + // + + for (i3 = ipos[3]; i3 < L_CODE; i3 += step) + { + s = L_mult (rr[i3][i3], _1_8); // index incr= step+L_CODE + s = L_mac (s, rr[i0][i3], _1_4); // index increment = step + s = L_mac (s, rr[i1][i3], _1_4); // index increment = step + rrv[i3] = pv_round (s); + } + + // Default value + sq = -1; + alp = 1; + ps = 0; + ia = ipos[2]; + ib = ipos[3]; + + for (i2 = ipos[2]; i2 < L_CODE; i2 += step) + { + // index increment = step + ps1 = add (ps0, dn[i2]); + + // index incr= step+L_CODE + alp1 = L_mac (alp0, rr[i2][i2], _1_16); + + // index increment = step + alp1 = L_mac (alp1, rr[i0][i2], _1_8); + + // index increment = step + alp1 = L_mac (alp1, rr[i1][i2], _1_8); + + for (i3 = ipos[3]; i3 < L_CODE; i3 += step) + { + // index increment = step + ps2 = add (ps1, dn[i3]); + + // index increment = step + alp2 = L_mac (alp1, rrv[i3], _1_2); + + // index increment = step + alp2 = L_mac (alp2, rr[i2][i3], _1_8); + + sq2 = mult (ps2, ps2); + + alp_16 = pv_round (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + + if (s > 0) + { + sq = sq2; + ps = ps2; + alp = alp_16; + ia = i2; + ib = i3; + } + } + } + i2 = ia; + i3 = ib; + + // + // i4 and i5 loop: + // + + ps0 = ps; + alp0 = L_mult (alp, _1_2); + + for (i5 = ipos[5]; i5 < L_CODE; i5 += step) + { + s = L_mult (rr[i5][i5], _1_8); + s = L_mac (s, rr[i0][i5], _1_4); + s = L_mac (s, rr[i1][i5], _1_4); + s = L_mac (s, rr[i2][i5], _1_4); + s = L_mac (s, rr[i3][i5], _1_4); + rrv[i5] = pv_round (s); + } + + // Default value + sq = -1; + alp = 1; + ps = 0; + ia = ipos[4]; + ib = ipos[5]; + + for (i4 = ipos[4]; i4 < L_CODE; i4 += step) + { + ps1 = add (ps0, dn[i4]); + + alp1 = L_mac (alp0, rr[i4][i4], _1_32); + alp1 = L_mac (alp1, rr[i0][i4], _1_16); + alp1 = L_mac (alp1, rr[i1][i4], _1_16); + alp1 = L_mac (alp1, rr[i2][i4], _1_16); + alp1 = L_mac (alp1, rr[i3][i4], _1_16); + + for (i5 = ipos[5]; i5 < L_CODE; i5 += step) + { + ps2 = add (ps1, dn[i5]); + + alp2 = L_mac (alp1, rrv[i5], _1_4); + alp2 = L_mac (alp2, rr[i4][i5], _1_16); + + sq2 = mult (ps2, ps2); + + alp_16 = pv_round (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + + if (s > 0) + { + sq = sq2; + ps = ps2; + alp = alp_16; + ia = i4; + ib = i5; + } + } + } + i4 = ia; + i5 = ib; + + // + // i6 and i7 loop: + // + + ps0 = ps; + alp0 = L_mult (alp, _1_2); + + for (i7 = ipos[7]; i7 < L_CODE; i7 += step) + { + s = L_mult (rr[i7][i7], _1_16); + s = L_mac (s, rr[i0][i7], _1_8); + s = L_mac (s, rr[i1][i7], _1_8); + s = L_mac (s, rr[i2][i7], _1_8); + s = L_mac (s, rr[i3][i7], _1_8); + s = L_mac (s, rr[i4][i7], _1_8); + s = L_mac (s, rr[i5][i7], _1_8); + rrv[i7] = pv_round (s); + } + + // Default value + sq = -1; + alp = 1; + ps = 0; + ia = ipos[6]; + ib = ipos[7]; + + for (i6 = ipos[6]; i6 < L_CODE; i6 += step) + { + ps1 = add (ps0, dn[i6]); + + alp1 = L_mac (alp0, rr[i6][i6], _1_64); + alp1 = L_mac (alp1, rr[i0][i6], _1_32); + alp1 = L_mac (alp1, rr[i1][i6], _1_32); + alp1 = L_mac (alp1, rr[i2][i6], _1_32); + alp1 = L_mac (alp1, rr[i3][i6], _1_32); + alp1 = L_mac (alp1, rr[i4][i6], _1_32); + alp1 = L_mac (alp1, rr[i5][i6], _1_32); + + for (i7 = ipos[7]; i7 < L_CODE; i7 += step) + { + ps2 = add (ps1, dn[i7]); + + alp2 = L_mac (alp1, rrv[i7], _1_4); + alp2 = L_mac (alp2, rr[i6][i7], _1_32); + + sq2 = mult (ps2, ps2); + + alp_16 = pv_round (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + + if (s > 0) + { + sq = sq2; + ps = ps2; + alp = alp_16; + ia = i6; + ib = i7; + } + } + } + i6 = ia; + i7 = ib; + + // now finished searching a set of 8 pulses + + if(gsmefrFlag != 0){ + // go on with the two last pulses for GSMEFR + // + // i8 and i9 loop: + // + + ps0 = ps; + alp0 = L_mult (alp, _1_2); + + for (i9 = ipos[9]; i9 < L_CODE; i9 += step) + { + s = L_mult (rr[i9][i9], _1_16); + s = L_mac (s, rr[i0][i9], _1_8); + s = L_mac (s, rr[i1][i9], _1_8); + s = L_mac (s, rr[i2][i9], _1_8); + s = L_mac (s, rr[i3][i9], _1_8); + s = L_mac (s, rr[i4][i9], _1_8); + s = L_mac (s, rr[i5][i9], _1_8); + s = L_mac (s, rr[i6][i9], _1_8); + s = L_mac (s, rr[i7][i9], _1_8); + rrv[i9] = pv_round (s); + } + + // Default value + sq = -1; + alp = 1; + ps = 0; + ia = ipos[8]; + ib = ipos[9]; + + for (i8 = ipos[8]; i8 < L_CODE; i8 += step) + { + ps1 = add (ps0, dn[i8]); + + alp1 = L_mac (alp0, rr[i8][i8], _1_128); + alp1 = L_mac (alp1, rr[i0][i8], _1_64); + alp1 = L_mac (alp1, rr[i1][i8], _1_64); + alp1 = L_mac (alp1, rr[i2][i8], _1_64); + alp1 = L_mac (alp1, rr[i3][i8], _1_64); + alp1 = L_mac (alp1, rr[i4][i8], _1_64); + alp1 = L_mac (alp1, rr[i5][i8], _1_64); + alp1 = L_mac (alp1, rr[i6][i8], _1_64); + alp1 = L_mac (alp1, rr[i7][i8], _1_64); + + for (i9 = ipos[9]; i9 < L_CODE; i9 += step) + { + ps2 = add (ps1, dn[i9]); + + alp2 = L_mac (alp1, rrv[i9], _1_8); + alp2 = L_mac (alp2, rr[i8][i9], _1_64); + + sq2 = mult (ps2, ps2); + + alp_16 = pv_round (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + + if (s > 0) + { + sq = sq2; + ps = ps2; + alp = alp_16; + ia = i8; + ib = i9; + } + } + } + } // end gsmefrFlag + + // + // test and memorise if this combination is better than the last one/ + // + + s = L_msu (L_mult (alpk, sq), psk, alp); + + if (s > 0) + { + psk = sq; + alpk = alp; + codvec[0] = i0; + codvec[1] = i1; + codvec[2] = i2; + codvec[3] = i3; + codvec[4] = i4; + codvec[5] = i5; + codvec[6] = i6; + codvec[7] = i7; + + if (gsmefrFlag != 0) + { + codvec[8] = ia; + codvec[9] = ib; + } + } + + // + // Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9)/ + // + + pos = ipos[1]; + for (j = 1, k = 2; k < nbPulse; j++, k++) + { + ipos[j] = ipos[k]; + } + ipos[sub(nbPulse,1)] = pos; + } // end 1..nbTracks loop +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +void search_10and8i40( + Word16 nbPulse, /* i : nbpulses to find */ + Word16 step, /* i : stepsize */ + Word16 nbTracks, /* i : nbTracks */ + Word16 dn[], /* i : correlation between target and h[] */ + Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ + Word16 ipos[], /* i : starting position for each pulse */ + Word16 pos_max[], /* i : position of maximum of dn[] */ + Word16 codvec[], /* o : algebraic codebook vector */ + Flag *pOverflow /* i/o : overflow flag */ +) +{ + Word16 i0, i1, i2, i3, i4, i5, i6, i7, i9; + Word16 i, j, k/*, m*/; + Word16 pos, ia, ib; + Word16 psk; + Word16 sq, sq2; + Word16 alpk, alp, alp_16; + Word32 s; + Word32 alp0, alp1, alp2; + Word16 gsmefrFlag; + Word16 *p_codvec = codvec; + Word16 *p_temp2; + + Word16 temp1[2*L_CODE]; + Word16 *p_temp1; + Word16 ps2; + Word16 ps1; + Word16 ps; + Word16 ps0; + + Word16 index[10]; + + OSCL_UNUSED_ARG(pOverflow); + + if (nbPulse == 10) + { + gsmefrFlag = 1; + } + else + { + gsmefrFlag = 0; + } + + /* fix i0 on maximum of correlation position */ + i0 = pos_max[ipos[0]]; + index[0] = i0; + /*------------------------------------------------------------------* + * i1 loop: * + *------------------------------------------------------------------*/ + + /* Default value */ + psk = -1; + alpk = 1; + for (i = 0; i < nbPulse; i++) + { + *(p_codvec++) = i; + } + + for (i = 1; i < nbTracks; i++) + { + i1 = pos_max[ipos[1]]; + index[1] = i1; + + /* ps0 = add (dn[i0], dn[i1], pOverflow);*/ + ps0 = (Word16)((Word32) dn[i0] + dn[i1]); + + /* alp0 = L_mult (rr[i0][i0], _1_16, pOverflow); */ + alp0 = (Word32) rr[i0][i0] << 12; + + /* alp0 = L_mac (alp0, rr[i1][i1], _1_16, pOverflow); */ + alp0 += (Word32) rr[i1][i1] << 12; + + /* alp0 = L_mac (alp0, rr[i0][i1], _1_8, pOverflow); */ + alp0 += (Word32) rr[i0][i1] << 13; + alp0 += 0x00008000L; + + /*----------------------------------------------------------------* + * i2 and i3 loop: * + *----------------------------------------------------------------*/ + + p_temp1 = temp1; + for (i3 = ipos[3]; i3 < L_CODE; i3 += step) + { + p_temp2 = &rr[i3][0]; + s = (Word32) * (p_temp2 + i3) >> 1; + s += (Word32) * (p_temp2 + i0); + s += (Word32) * (p_temp2 + i1); + *(p_temp1++) = ps0 + dn[i3]; + *(p_temp1++) = (Word16)((s + 2) >> 2); + } + + /* Default value */ + sq = -1; + alp = 1; + ps = 0; + ia = ipos[2]; + ib = ipos[3]; + + s = (alp0 >> 12); + + for (j = ipos[2]; j < L_CODE; j += step) + { + /* index increment = step */ + p_temp2 = &rr[j][0]; + + alp1 = (s + (Word32) * (p_temp2 + j)) >> 1; + + alp1 += (Word32) * (p_temp2 + i0); + + alp1 += (Word32) * (p_temp2 + i1); + + p_temp1 = temp1; + ps1 = dn[j]; + + + for (i3 = ipos[3]; i3 < L_CODE; i3 += step) + { + /* index increment = step */ + ps2 = ps1 + *(p_temp1++); + + sq2 = (Word16)(((Word32) ps2 * ps2) >> 15); + + alp2 = (alp1 + p_temp2[i3]) >> 2; + alp2 = (alp2 + *(p_temp1++)) >> 1; /* alp2 is always > 0 */ + if (((Word32) sq2 * alp) > ((Word32) sq * alp2)) + { + sq = sq2; + ps = ps2; + alp = (Word16)alp2; + ia = j; + ib = i3; + } + } + + } + i2 = ia; + i3 = ib; + index[2] = ia; + index[3] = ib; + + /*----------------------------------------------------------------* + * i4 and i5 loop: * + *----------------------------------------------------------------*/ + + alp0 = ((Word32) alp << 15) + 0x00008000L; + p_temp1 = temp1; + + for (i5 = ipos[5]; i5 < L_CODE; i5 += step) + { + p_temp2 = &rr[i5][0]; + s = (Word32) * (p_temp2 + i5) >> 1; + s += (Word32) * (p_temp2 + i0); + s += (Word32) * (p_temp2 + i1); + s += (Word32) * (p_temp2 + i2); + s += (Word32) * (p_temp2 + i3); + + *(p_temp1++) = ps + dn[i5]; + *(p_temp1++) = (Word16)((s + 2) >> 2); + } + + /* Default value */ + sq = -1; + alp = 1; + ps = 0; + ia = ipos[4]; + ib = ipos[5]; + + for (j = ipos[4]; j < L_CODE; j += step) + { + /* ps1 = add (ps0, dn[i4], pOverflow); */ + p_temp2 = &rr[j][0]; + + /* alp1 = L_mac (alp0, rr[i4][i4], _1_32, pOverflow); */ + alp1 = alp0 + ((Word32) * (p_temp2 + j) << 11); + + /* alp1 = L_mac (alp1, rr[i0][i4], _1_16, pOverflow); */ + alp1 += (Word32) * (p_temp2 + i0) << 12; + + /* alp1 = L_mac (alp1, rr[i1][i4], _1_16, pOverflow); */ + alp1 += (Word32) * (p_temp2 + i1) << 12; + + /* alp1 = L_mac (alp1, rr[i2][i4], _1_16, pOverflow); */ + alp1 += (Word32) * (p_temp2 + i2) << 12; + + /* alp1 = L_mac (alp1, rr[i3][i4], _1_16, pOverflow); */ + alp1 += (Word32) * (p_temp2 + i3) << 12; + + p_temp1 = temp1; + ps1 = dn[j]; + + for (i5 = ipos[5]; i5 < L_CODE; i5 += step) + { + ps2 = ps1 + *(p_temp1++); + + alp2 = alp1 + ((Word32) * (p_temp2 + i5) << 12); + + alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16); + sq2 = (Word16)(((Word32) ps2 * ps2) >> 15); + + if (((Word32) sq2 * alp) > ((Word32) sq * alp_16)) + { + sq = sq2; + ps = ps2; + alp = alp_16; + ia = j; + ib = i5; + } + + } + } + i4 = ia; + i5 = ib; + index[4] = ia; + index[5] = ib; + + /*----------------------------------------------------------------* + * i6 and i7 loop: * + *----------------------------------------------------------------*/ + + alp0 = ((Word32) alp << 15) + 0x00008000L; + + p_temp1 = temp1; + + for (i7 = ipos[7]; i7 < L_CODE; i7 += step) + { + s = (Word32) rr[i7][i7] >> 1; + s += (Word32) rr[i0][i7]; + s += (Word32) rr[i1][i7]; + s += (Word32) rr[i2][i7]; + s += (Word32) rr[i3][i7]; + s += (Word32) rr[i4][i7]; + s += (Word32) rr[i5][i7]; + *(p_temp1++) = ps + dn[i7]; + *(p_temp1++) = (Word16)((s + 4) >> 3); + } + + + /* Default value */ + sq = -1; + alp = 1; + ps = 0; + ia = ipos[6]; + ib = ipos[7]; + + for (j = ipos[6]; j < L_CODE; j += step) + { + /* ps1 = add (ps0, dn[i6], pOverflow); */ + + p_temp2 = (Word16 *) & rr[j]; + + /* alp1 = L_mac (alp0, rr[i6][i6], _1_64, pOverflow); */ + alp1 = alp0 + ((Word32) * (p_temp2 + j) << 10); + + /* alp1 = L_mac (alp1, rr[i0][i6], _1_32, pOverflow); */ + alp1 += (Word32) * (p_temp2 + i0) << 11; + + + /* alp1 = L_mac (alp1, rr[i1][i6], _1_32, pOverflow); */ + alp1 += (Word32) * (p_temp2 + i1) << 11; + + /* alp1 = L_mac (alp1, rr[i2][i6], _1_32, pOverflow); */ + alp1 += (Word32) * (p_temp2 + i2) << 11; + + /* alp1 = L_mac (alp1, rr[i3][i6], _1_32, pOverflow); */ + alp1 += (Word32) * (p_temp2 + i3) << 11; + + /* alp1 = L_mac (alp1, rr[i4][i6], _1_32, pOverflow); */ + alp1 += (Word32) * (p_temp2 + i4) << 11; + + /* alp1 = L_mac (alp1, rr[i5][i6], _1_32, pOverflow); */ + alp1 += (Word32) * (p_temp2 + i5) << 11; + + p_temp1 = temp1; + ps1 = dn[j]; + + for (i7 = ipos[7]; i7 < L_CODE; i7 += step) + { + ps2 = ps1 + *(p_temp1++); + + alp2 = alp1 + ((Word32) * (p_temp2 + i7) << 11); + + alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16); + + sq2 = (Word16)(((Word32) ps2 * ps2) >> 15); + + if (((Word32) sq2 * alp) > ((Word32) sq * alp_16)) + { + sq = sq2; + ps = ps2; + alp = alp_16; + ia = j; + ib = i7; + } + } + } + + i6 = ia; + i7 = ib; + index[6] = ia; + index[7] = ib; + + /* now finished searching a set of 8 pulses */ + + if (gsmefrFlag != 0) + { + /* go on with the two last pulses for GSMEFR */ + /*----------------------------------------------------------------* + * i8 and i9 loop: * + *----------------------------------------------------------------*/ + + alp0 = ((Word32) alp << 15) + 0x00008000L; + + p_temp1 = temp1; + + for (i9 = ipos[9]; i9 < L_CODE; i9 += step) + { + s = (Word32) rr[i9][i9] >> 1; + s += (Word32) rr[i0][i9]; + s += (Word32) rr[i1][i9]; + s += (Word32) rr[i2][i9]; + s += (Word32) rr[i3][i9]; + s += (Word32) rr[i4][i9]; + s += (Word32) rr[i5][i9]; + s += (Word32) rr[i6][i9]; + s += (Word32) rr[i7][i9]; + + *(p_temp1++) = ps + dn[i9]; + *(p_temp1++) = (Word16)((s + 4) >> 3); + } + + /* Default value */ + sq = -1; + alp = 1; + ps = 0; + ia = ipos[8]; + ib = ipos[9]; + + for (j = ipos[8]; j < L_CODE; j += step) + { + /* ps1 = add (ps0, dn[i8], pOverflow); */ + p_temp2 = &rr[j][0]; + + /* alp1 = L_mac (alp0, rr[i8][i8], _1_128, pOverflow); */ + alp1 = alp0 + ((Word32) * (p_temp2 + j) << 9); + + /* alp1 = L_mac (alp1, rr[i0][i8], _1_64, pOverflow); */ + alp1 += (Word32) rr[i0][j] << 10; + + /* alp1 = L_mac (alp1, rr[i1][i8], _1_64, pOverflow); */ + alp1 += (Word32) rr[i1][j] << 10; + + /* alp1 = L_mac (alp1, rr[i2][i8], _1_64, pOverflow); */ + alp1 += (Word32) rr[i2][j] << 10; + + /* alp1 = L_mac (alp1, rr[i3][i8], _1_64, pOverflow); */ + alp1 += (Word32) rr[i3][j] << 10; + + /* alp1 = L_mac (alp1, rr[i4][i8], _1_64, pOverflow); */ + alp1 += (Word32) rr[i4][j] << 10; + + /* alp1 = L_mac (alp1, rr[i5][i8], _1_64, pOverflow); */ + alp1 += (Word32) rr[i5][j] << 10; + + /* alp1 = L_mac (alp1, rr[i6][i8], _1_64, pOverflow); */ + alp1 += (Word32) rr[i6][j] << 10; + + /* alp1 = L_mac (alp1, rr[i7][i8], _1_64, pOverflow); */ + alp1 += (Word32) rr[i7][j] << 10; + + p_temp1 = temp1; + ps1 = dn[j]; + + for (i9 = ipos[9]; i9 < L_CODE; i9 += step) + { + /* ps2 = add (ps1, dn[i9], pOverflow); */ + ps2 = ps1 + *(p_temp1++); + + /* sq2 = mult (ps2, ps2, pOverflow); */ + sq2 = (Word16)(((Word32) ps2 * ps2) >> 15); + + /* alp2 = L_mac (alp1, rrv[i9], _1_8, pOverflow); */ + alp2 = alp1 + ((Word32) * (p_temp2 + i9) << 10) ; + + /* alp2 = L_mac (alp2, rr[i8][i9], _1_64, pOverflow); */ + alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 13)) >> 16); + + if (((Word32) sq2 * alp) > ((Word32) sq * alp_16)) + { + sq = sq2; + ps = ps2; + alp = alp_16; + ia = j; + ib = i9; + } + } + } + + index[8] = ia; + index[9] = ib; + + }/* end gsmefrFlag */ + + /*---------------------------------------------------------------- * + * test and memorise if this combination is better than the last one.* + *----------------------------------------------------------------*/ + + if (((Word32) alpk * sq) > ((Word32) psk * alp)) + { + psk = sq; + alpk = alp; + + if (gsmefrFlag != 0) + { + oscl_memcpy(codvec, index, (2*NB_TRACK)*sizeof(*index)); + } + else + { + oscl_memcpy(codvec, index, (2*NB_TRACK_MR102)*sizeof(*index)); + } + + } + /*----------------------------------------------------------------* + * Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9). * + *----------------------------------------------------------------*/ + + pos = ipos[1]; + for (j = 1, k = 2; k < nbPulse; j++, k++) + { + ipos[j] = ipos[k]; + } + ipos[nbPulse-1] = pos; + } /* end 1..nbTracks loop*/ +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/s10_8pf.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/s10_8pf.h new file mode 100644 index 00000000..5e84b76a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/s10_8pf.h @@ -0,0 +1,109 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: s10_8pf.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the s10_8pf module. +------------------------------------------------------------------------------ +*/ + +#ifndef S10_8PF_H +#define S10_8PF_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" +#include "cnst.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void search_10and8i40( + Word16 nbPulse, /* i : nbpulses to find */ + Word16 step, /* i : stepsize */ + Word16 nbTracks, /* i : nbTracks */ + Word16 dn[], /* i : correlation between target and h[] */ + Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ + Word16 ipos[], /* i : starting position for each pulse */ + Word16 pos_max[], /* i : position of maximum of dn[] */ + Word16 codvec[], /* o : algebraic codebook vector */ + Flag *pOverflow /* i/o : Overflow flag */ + ); + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _S10_8PF_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/set_sign.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/set_sign.cpp new file mode 100644 index 00000000..f7599014 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/set_sign.cpp @@ -0,0 +1,539 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: set_sign.cpp + Funtions: set_sign + set_sign12k2 + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This module contains the functions set_sign and set_sign12k2. + These functions are used to build a sign vector according + to the values in the input arrays. These functions also + find the position in the input codes of the maximum correlation + and the starting position for each pulse. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "set_sign.h" +#include "basic_op.h" +#include "inv_sqrt.h" +#include "cnst.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: set_sign +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + dn = buffer of correlation values (Word16) + sign = buffer containing sign of dn elements (Word16) + dn2 = buffer containing the maximum of correlation in each track.(Word16) + n = number of maximum correlations in dn2 (Word16) + + Returns: + None + + Outputs: + dn buffer is modified to contain the absolute value of its input + sign buffer is modified to contain the sign information for the + values in dn buffer + dn2 buffer is modified to denote the location of the maximum + correlation for each track. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + + This function builds sign vector according to dn buffer It also finds + the position of maximum of correlation in each track and the starting + position for each pulse. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + set_sign.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void set_sign(Word16 dn[], i/o : correlation between target and h[] + Word16 sign[], o : sign of dn[] + Word16 dn2[], o : maximum of correlation in each track. + Word16 n i : # of maximum correlations in dn2[] +) +{ + Word16 i, j, k; + Word16 val, min; + Word16 pos = 0; //initialization only needed to keep gcc silent + + // set sign according to dn[] + + for (i = 0; i < L_CODE; i++) { + val = dn[i]; + + if (val >= 0) { + sign[i] = 32767; + } else { + sign[i] = -32767; + val = negate(val); + } + dn[i] = val; // modify dn[] according to the fixed sign + dn2[i] = val; + } + + // keep 8-n maximum positions/8 of each track and store it in dn2[] + + for (i = 0; i < NB_TRACK; i++) + { + for (k = 0; k < (8-n); k++) + { + min = 0x7fff; + for (j = i; j < L_CODE; j += STEP) + { + if (dn2[j] >= 0) + { + val = sub(dn2[j], min); + + if (val < 0) + { + min = dn2[j]; + pos = j; + } + } + } + dn2[pos] = -1; + } + } + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void set_sign(Word16 dn[], /* i/o : correlation between target and h[] */ + Word16 sign[], /* o : sign of dn[] */ + Word16 dn2[], /* o : maximum of correlation in each track. */ + Word16 n /* i : # of maximum correlations in dn2[] */ + ) +{ + register Word16 i, j, k; + Word16 val, min; + Word16 pos = 0; /* initialization only needed to keep gcc silent */ + + /* set sign according to dn[] */ + for (i = L_CODE - 1; i >= 0; i--) + { + val = dn[i]; + + if (val >= 0) + { + sign[i] = 32767; + } + else + { + sign[i] = -32767; + val = negate(val); + dn[i] = val; /* modify dn[] according to the fixed sign */ + } + + dn2[i] = val; + } + + /* keep 8-n maximum positions/8 of each track and store it in dn2[] */ + + for (i = 0; i < NB_TRACK; i++) + { + for (k = 0; k < (8 - n); k++) + { + min = 0x7fff; + for (j = i; j < L_CODE; j += STEP) + { + if (dn2[j] >= 0) + { + if (dn2[j] < min) + { + min = dn2[j]; + pos = j; + } + } + } + dn2[pos] = -1; + } + } + + return; +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: set_sign12k2() +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + dn = buffer of correlation values (Word16) + cn = buffer of residual after long term prediction (Word16) + sign = sign of correlation buffer elements (Word16) + pos_max = buffer containing position of maximum correlation (Word16) + nb_track = number of tracks (Word16) + ipos = buffer containing the starting position for each pulse (Word16) + step = step size in the tracks (Word16) + pOverflow = pointer to Overflow flag (Flag) + + Outputs: + sign buffer contains the sign of correlation values + dn buffer contains the sign-adjusted correlation values + pos_max buffer contains the maximum correlation position + ipos buffer contains the starting position of each pulse + pOverflow -> 1 if the math operations called by this function result in + saturation + + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function builds the sign vector according to dn and cn, and modifies + dn to include the sign information (dn[i]=sign[i]*dn[i]). It also finds + the position of maximum of correlation in each track and the starting + position for each pulse. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + set_sign.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void set_sign12k2 ( + Word16 dn[], //i/o : correlation between target and h[] + Word16 cn[], //i : residual after long term prediction + Word16 sign[], //o : sign of d[n] + Word16 pos_max[], //o : position of maximum correlation + Word16 nb_track, //i : number of tracks tracks + Word16 ipos[], //o : starting position for each pulse + Word16 step //i : the step size in the tracks +) +{ + Word16 i, j; + Word16 val, cor, k_cn, k_dn, max, max_of_all; + Word16 pos = 0; // initialization only needed to keep gcc silent + Word16 en[L_CODE]; // correlation vector + Word32 s; + + // The reference ETSI code uses a global flag for Overflow. However in the + // actual implementation a pointer to the overflow flag is passed in. This + // pointer is passed into the basic math functions called by this routine. + + // calculate energy for normalization of cn[] and dn[] + + s = 256; + for (i = 0; i < L_CODE; i++) + { + s = L_mac (s, cn[i], cn[i]); + } + s = Inv_sqrt (s); + k_cn = extract_h (L_shl (s, 5)); + + s = 256; + for (i = 0; i < L_CODE; i++) + { + s = L_mac (s, dn[i], dn[i]); + } + s = Inv_sqrt (s); + k_dn = extract_h (L_shl (s, 5)); + + for (i = 0; i < L_CODE; i++) + { + val = dn[i]; + cor = pv_round (L_shl (L_mac (L_mult (k_cn, cn[i]), k_dn, val), 10)); + + if (cor >= 0) + { + sign[i] = 32767; // sign = +1 + } + else + { + sign[i] = -32767; // sign = -1 + cor = negate (cor); + val = negate (val); + } + // modify dn[] according to the fixed sign + dn[i] = val; + en[i] = cor; + } + + max_of_all = -1; + for (i = 0; i < nb_track; i++) + { + max = -1; + + for (j = i; j < L_CODE; j += step) + { + cor = en[j]; + val = sub (cor, max); + + if (val > 0) + { + max = cor; + pos = j; + } + } + // store maximum correlation position + pos_max[i] = pos; + val = sub (max, max_of_all); + + if (val > 0) + { + max_of_all = max; + // starting position for i0 + ipos[0] = i; + } + } + + // + // Set starting position of each pulse. + // + + pos = ipos[0]; + ipos[nb_track] = pos; + + for (i = 1; i < nb_track; i++) + { + pos = add (pos, 1); + + if (sub (pos, nb_track) >= 0) + { + pos = 0; + } + ipos[i] = pos; + ipos[add(i, nb_track)] = pos; + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void set_sign12k2( + Word16 dn[], /* i/o : correlation between target and h[] */ + Word16 cn[], /* i : residual after long term prediction */ + Word16 sign[], /* o : sign of d[n] */ + Word16 pos_max[], /* o : position of maximum correlation */ + Word16 nb_track, /* i : number of tracks tracks */ + Word16 ipos[], /* o : starting position for each pulse */ + Word16 step, /* i : the step size in the tracks */ + Flag *pOverflow /* i/o: overflow flag */ +) +{ + Word16 i, j; + Word16 val; + Word16 cor; + Word16 k_cn; + Word16 k_dn; + Word16 max; + Word16 max_of_all; + Word16 pos = 0; /* initialization only needed to keep gcc silent */ + Word16 en[L_CODE]; /* correlation vector */ + Word32 s; + Word32 t; + Word32 L_temp; + Word16 *p_cn; + Word16 *p_dn; + Word16 *p_sign; + Word16 *p_en; + + /* calculate energy for normalization of cn[] and dn[] */ + + s = 256; + t = 256; + p_cn = cn; + p_dn = dn; /* crosscorrelation values do not have strong peaks, so + scaling applied in cor_h_x (sf=2) guaranteed that the + mac of the energy for this vector will not overflow */ + + for (i = L_CODE; i != 0; i--) + { + val = *(p_cn++); + s = L_mac(s, val, val, pOverflow); + val = *(p_dn++); + t += ((Word32) val * val) << 1; + } + s = Inv_sqrt(s, pOverflow); + k_cn = (Word16)((L_shl(s, 5, pOverflow)) >> 16); + + t = Inv_sqrt(t, pOverflow); + k_dn = (Word16)(t >> 11); + + p_cn = &cn[L_CODE-1]; + p_sign = &sign[L_CODE-1]; + p_en = &en[L_CODE-1]; + + for (i = L_CODE - 1; i >= 0; i--) + { + L_temp = ((Word32)k_cn * *(p_cn--)) << 1; + val = dn[i]; + s = L_mac(L_temp, k_dn, val, pOverflow); + L_temp = L_shl(s, 10, pOverflow); + cor = pv_round(L_temp, pOverflow); + + if (cor >= 0) + { + *(p_sign--) = 32767; /* sign = +1 */ + } + else + { + *(p_sign--) = -32767; /* sign = -1 */ + cor = negate(cor); + + /* modify dn[] according to the fixed sign */ + dn[i] = negate(val); + } + + *(p_en--) = cor; + } + + max_of_all = -1; + for (i = 0; i < nb_track; i++) + { + max = -1; + + for (j = i; j < L_CODE; j += step) + { + cor = en[j]; + if (cor > max) + { + max = cor; + pos = j; + } + } + /* store maximum correlation position */ + pos_max[i] = pos; + if (max > max_of_all) + { + max_of_all = max; + /* starting position for i0 */ + ipos[0] = i; + } + } + + /*----------------------------------------------------------------* + * Set starting position of each pulse. * + *----------------------------------------------------------------*/ + + pos = ipos[0]; + ipos[nb_track] = pos; + + for (i = 1; i < nb_track; i++) + { + pos++; + + if (pos >= nb_track) + { + pos = 0; + } + ipos[ i] = pos; + ipos[ i + nb_track] = pos; + } + + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/set_sign.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/set_sign.h new file mode 100644 index 00000000..9ca482c6 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/set_sign.h @@ -0,0 +1,113 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: set_sign.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the set_sign() and set_sign12k2() function. + +------------------------------------------------------------------------------ +*/ + +#ifndef SET_SIGN_H +#define SET_SIGN_H "@(#)$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "basicop_malloc.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void set_sign(Word16 dn[], /* i/o : correlation between target and h[] */ + Word16 sign[], /* o : sign of dn[] */ + Word16 dn2[], /* o : maximum of correlation in each track. */ + Word16 n /* i : # of maximum correlations in dn2[] */ + ); + + void set_sign12k2( + Word16 dn[], /* i/o : correlation between target and h[] */ + Word16 cn[], /* i : residual after long term prediction */ + Word16 sign[], /* o : sign of d[n] */ + Word16 pos_max[], /* o : position of maximum correlation */ + Word16 nb_track, /* i : number of tracks tracks */ + Word16 ipos[], /* o : starting position for each pulse */ + Word16 step, /* i : the step size in the tracks */ + Flag *pOverflow /* i/o : overflow flag */ + ); + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _SET_SIGN_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/sid_sync.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/sid_sync.cpp new file mode 100644 index 00000000..2981e7b8 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/sid_sync.cpp @@ -0,0 +1,447 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: sid_sync.cpp + Functions: sid_sync_init + sid_sync_reset + sid_sync_exit + sid_sync_set_handover_debt + sid_sync + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + This file contains the functions that initialize, reset, exit, and perform + SID synchronization. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "basic_op.h" +#include "mode.h" +#include "sid_sync.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; [Define module specific macros here] +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; [Include all pre-processor statements here. Include conditional +; compile variables also.] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; [List function prototypes here] +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; [Variable declaration - defined here and used outside this module] +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: sid_sync_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer containing a pointer to the state structure used for + SID synchronization (void) + + Outputs: + None + + Returns: + return_value = status of sid_sync_reset function; -1, if state is pointing + to a NULL address (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function initialize one instance of the sid_sync module. It stores + the pointer to state struct in *st. This pointer has to be passed to sid_sync + in each call. This function returns 0 on success, otherwise, -1. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + sid_sync.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 sid_sync_init(void **state) +{ + sid_syncState* s; + + if (state == NULL) + { + /* fprintf(stderr, "sid_sync_init:invalid state parameter\n"); */ + return -1; + } + + *state = NULL; + + /* allocate memory */ + if ((s = (sid_syncState *) + oscl_malloc(sizeof(sid_syncState))) == NULL) + { + /* fprintf(stderr, + "sid_sync_init: " + "can not malloc state structure\n"); */ + return -1; + } + s->sid_update_rate = 8; + + *state = (void *)s; + + return(sid_sync_reset(s)); +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: sid_sync_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to the state structure used for SID synchronization (void) + + Outputs: + None + + Returns: + return_value = 0 (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs a reset of the sid_sync module by setting the state + memory to zero. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + sid_sync.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +Word16 sid_sync_reset(void *st) +{ + sid_syncState *state = (sid_syncState *) st; + + state->sid_update_counter = 3; + state->sid_handover_debt = 0; + state->prev_ft = TX_SPEECH_GOOD; + + return 0; +} + + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: sid_sync_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer containing a pointer to the state structure used for + SID synchronization (void) + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function frees up the state structure used by sid_sync function. It + stores NULL in *state. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + sid_sync.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void sid_sync_exit(void **state) +{ + sid_syncState **st = (sid_syncState **) state; + + if (st == NULL || *st == NULL) + { + return; + } + + /* deallocate memory */ + oscl_free(*st); + *st = NULL; + + return; + +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: sid_sync_set_handover_debt +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to the state structure used for SID synchronization + (sid_syncState) + debtFrames = number of handover debt frames (Word16) + + Outputs: + st->sid_handover_debt is set to debtFrames + + Returns: + return_value = 0 + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function updates the handover debt to debtFrames. Extra SID_UPD are + scheduled to update remote decoder CNI states, right after an handover. + This is primarily for use on MS UL side. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + sid_sync.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void sid_sync_set_handover_debt(sid_syncState *st, + Word16 debtFrames) +{ + /* debtFrames >= 0 */ + st->sid_handover_debt = debtFrames; + return; +} + + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: sid_sync +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to the state structure used for SID synchronization + (sid_syncState) + mode = codec mode (enum Mode) + tx_frame_type = pointer to TX frame type store (enum TXFrameType) + + Outputs: + tx_frame_type contains the new TX frame type + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function performs SID frame synchronization to ensure that the mode + only switches to a neighbouring mode. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + sid_sync.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ +void sid_sync(void *state, + enum Mode mode, + enum TXFrameType *tx_frame_type) +{ + + sid_syncState *st = (sid_syncState *) state; + + if (mode == MRDTX) + { + + st->sid_update_counter--; + + if (st->prev_ft == TX_SPEECH_GOOD) + { + *tx_frame_type = TX_SID_FIRST; + st->sid_update_counter = 3; + } + else + { + /* TX_SID_UPDATE or TX_NO_DATA */ + if ((st->sid_handover_debt > 0) && + (st->sid_update_counter > 2)) + { + /* ensure extra updates are properly delayed after + a possible SID_FIRST */ + *tx_frame_type = TX_SID_UPDATE; + st->sid_handover_debt--; + } + else + { + if (st->sid_update_counter == 0) + { + *tx_frame_type = TX_SID_UPDATE; + st->sid_update_counter = st->sid_update_rate; + } + else + { + *tx_frame_type = TX_NO_DATA; + } + } + } + } + else + { + st->sid_update_counter = st->sid_update_rate ; + *tx_frame_type = TX_SPEECH_GOOD; + } + st->prev_ft = *tx_frame_type; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/sid_sync.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/sid_sync.h new file mode 100644 index 00000000..e5c33cf8 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/sid_sync.h @@ -0,0 +1,134 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: sid_sync.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains the type definition and function prototypes used by the + SID synchronization functions. + +------------------------------------------------------------------------------ +*/ + +#ifndef _SID_SYNC_H_ +#define _SID_SYNC_H_ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "frame.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ +#define sid_sync_h "$Id $" + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Word16 sid_update_rate; /* Send SID Update every sid_update_rate frame */ + Word16 sid_update_counter; /* Number of frames since last SID */ + Word16 sid_handover_debt; /* Number of extra SID_UPD frames to schedule*/ + enum TXFrameType prev_ft; + } sid_syncState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + /* initialize one instance of the sid_sync module + Stores pointer to state struct in *st. This pointer has to + be passed to sid_sync in each call. + returns 0 on success + */ + Word16 sid_sync_init(void **st); + + /* reset of sid_sync module (i.e. set state memory to zero) + returns 0 on success + */ + Word16 sid_sync_reset(void *st); + + /* de-initialize sid_sync module (i.e. free status struct) + stores NULL in *st + */ + void sid_sync_exit(void **st); + + /* update handover debt + debtFrames extra SID_UPD are scheduled . + to update remote decoder CNI states, right after an handover. + (primarily for use on MS UL side ) + */ + void sid_sync_set_handover_debt(sid_syncState *st, /* i/o: sid_sync state */ + Word16 debtFrames); + + /* To ensure that the mode only switches to a neighbouring mode */ + void sid_sync(void *st , + enum Mode mode, + enum TXFrameType *tx_frame_type); + +#ifdef __cplusplus +} +#endif + +#endif /* _SID_SYNC_H_ */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/sp_enc.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/sp_enc.cpp new file mode 100644 index 00000000..7a7f3686 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/sp_enc.cpp @@ -0,0 +1,655 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: sp_enc.cpp + Funtions: GSMInitEncode + Speech_Encode_Frame_reset + GSMEncodeFrameExit + Speech_Encode_Frame_First + GSMEncodeFrame + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + These functions comprise the pre filtering and encoding of one speech frame. + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "sp_enc.h" +#include "typedef.h" +#include "cnst.h" +#include "set_zero.h" +#include "pre_proc.h" +#include "prm2bits.h" +#include "mode.h" +#include "cod_amr.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: GSMInitEncode +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + Inputs: + state = pointer to an array of pointers to structures of type + Speech_Decode_FrameState + dtx = flag to turn off or turn on DTX (Flag) + id = pointer to an array whose contents are of type char + + Outputs: + pre_state field of the structure pointed to by the pointer pointed to + by state is set to NULL + cod_amr_state field of the structure pointed to by the pointer pointed to + by state is set to NULL + dtx field of the structure pointed to by the pointer pointed to by state + is set to the input dtx + + Returns: + return_value = set to zero, if initialization was successful; -1, + otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function allocates memory for filter structure and initializes state + memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + sp_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + Note: Original function name of Speech_Encode_Frame_init was changed to + GSMInitEncode in the Code section. + +int Speech_Encode_Frame_init (void **state_data, + Flag dtx, + char *id) +{ + Speech_Encode_FrameState* s; + + if (state_data == NULL){ + fprintf(stderr, "Speech_Encode_Frame_init: invalid parameter\n"); + return -1; + } + *state_data = NULL; + + // allocate memory + if ((s= (Speech_Encode_FrameState *) malloc(sizeof(Speech_Encode_FrameState))) == NULL){ + fprintf(stderr, "Speech_Encode_Frame_init: can not malloc state " + "structure\n"); + return -1; + } + + s->complexityCounter = getCounterId(id); + + s->pre_state = NULL; + s->cod_amr_state = NULL; + s->dtx = dtx; + + if (Pre_Process_init(&s->pre_state) || + cod_amr_init(&s->cod_amr_state, s->dtx)) { + GSMEncodeFrameExit(&s); + return -1; + } + + Speech_Encode_Frame_reset(s); + *state_data = (void *)s; + + return 0; +} + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 GSMInitEncode(void **state_data, + Flag dtx, + Word8 *id) +{ + Speech_Encode_FrameState* s; + + OSCL_UNUSED_ARG(id); + + if (state_data == NULL) + { + /* fprintf(stderr, "Speech_Encode_Frame_init: invalid parameter\n"); */ + return -1; + } + *state_data = NULL; + + /* allocate memory */ + if ((s = (Speech_Encode_FrameState *) oscl_malloc(sizeof(Speech_Encode_FrameState))) == NULL) + { + /* fprintf(stderr, "Speech_Encode_Frame_init: can not malloc state " + "structure\n"); */ + return -1; + } + + s->pre_state = NULL; + s->cod_amr_state = NULL; + s->dtx = dtx; + + if (Pre_Process_init(&s->pre_state) || + cod_amr_init(&s->cod_amr_state, s->dtx)) + { + Speech_Encode_FrameState** temp = &s; + GSMEncodeFrameExit((void**)temp); + return -1; + } + + Speech_Encode_Frame_reset(s); + *state_data = (void *)s; + + return 0; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Speech_Encode_Frame_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to structures of type Speech_Decode_FrameState + + Outputs: + None + + Returns: + return_value = set to zero if reset was successful; -1, otherwise (int) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function resets state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + sp_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Speech_Encode_Frame_reset (void *state_data) +{ + + Speech_Encode_FrameState *state = + (Speech_Encode_FrameState *) state_data; + + if (state_data == NULL){ + fprintf(stderr, "Speech_Encode_Frame_reset + : invalid parameter\n"); + return -1; + } + + Pre_Process_reset(state->pre_state); + cod_amr_reset(state->cod_amr_state); + + setCounter(state->complexityCounter); + Init_WMOPS_counter(); + setCounter(0); // set counter to global counter + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 Speech_Encode_Frame_reset(void *state_data) +{ + + Speech_Encode_FrameState *state = + (Speech_Encode_FrameState *) state_data; + + if (state_data == NULL) + { + /* fprintf(stderr, "Speech_Encode_Frame_reset + : invalid parameter\n"); */ + return -1; + } + + Pre_Process_reset(state->pre_state); + cod_amr_reset(state->cod_amr_state); + + return 0; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: GSMEncodeFrameExit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to a pointer to a structure of type cod_amrState + + Outputs: + state points to a NULL address + + Returns: + None. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function frees the memory used for state memory. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + sp_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Note: Original function name of Speech_Encode_Frame_exit was changed to + GSMEncodeFrameExit in the Code section. + +void Speech_Encode_Frame_exit (void **state_data) +{ + + Speech_Encode_FrameState **state = + (Speech_Encode_FrameState **) state_data; + + if (state == NULL || *state == NULL) + return; + + Pre_Process_exit(&(*state)->pre_state); + cod_amr_exit(&(*state)->cod_amr_state); + + setCounter((*state)->complexityCounter); + WMOPS_output(0); + setCounter(0); // set counter to global counter + + // deallocate memory + free(*state); + *state = NULL; + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void GSMEncodeFrameExit(void **state_data) +{ + + Speech_Encode_FrameState **state = + (Speech_Encode_FrameState **) state_data; + + if (state == NULL || *state == NULL) + return; + + Pre_Process_exit(&(*state)->pre_state); + cod_amr_exit(&(*state)->cod_amr_state); + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Speech_Encode_Frame_First +------------------------------------------------------------------------------ + + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to a structure of type Speech_Encode_FrameState that contains + the post filter states + new_speech = pointer to buffer of length L_FRAME that contains + the speech input (Word16) + + Outputs: + The structure of type Speech_Encode_FrameState pointed to by st is updated. + + Returns: + return_value = 0 (int) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function encodes the first frame of speech. It calls the pre-processing + filter and the first frame encoder. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + sp_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int Speech_Encode_Frame_First ( + Speech_Encode_FrameState *st, // i/o : post filter states + Word16 *new_speech) // i : speech input +{ +#if !defined(NO13BIT) + Word16 i; +#endif + + setCounter(st->complexityCounter); + +#if !defined(NO13BIT) + // Delete the 3 LSBs (13-bit input) + for (i = 0; i < L_NEXT; i++) + { + new_speech[i] = new_speech[i] & 0xfff8; + } +#endif + + // filter + downscaling + Pre_Process (st->pre_state, new_speech, L_NEXT); + + cod_amr_first(st->cod_amr_state, new_speech); + + Init_WMOPS_counter (); // reset WMOPS counter for the new frame + + return 0; +} + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void Speech_Encode_Frame_First( + Speech_Encode_FrameState *st, /* i/o : post filter states */ + Word16 *new_speech) /* i : speech input */ +{ +#if !defined(NO13BIT) + Word16 i; +#endif + +#if !defined(NO13BIT) + /* Delete the 3 LSBs (13-bit input) */ + for (i = 0; i < L_NEXT; i++) + { + new_speech[i] = new_speech[i] & 0xfff8; + } +#endif + + /* filter + downscaling */ + Pre_Process(st->pre_state, new_speech, L_NEXT); + + cod_amr_first(st->cod_amr_state, new_speech); + + return; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: cod_amr +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state_data = a void pointer to the post filter states + mode = AMR mode of type enum Mode + new_speech = pointer to buffer of length L_FRAME that contains + the speech input of type Word16 + serial = pointer to the serial bit stream of type Word16 + usedMode = pointer to the used mode of type enum Mode + + Outputs: + serial -> encoded serial bit stream + The value pointed to by usedMode is updated. + + Returns: + return_value = 0 (int) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function is the entry point to the GSM AMR encoder. The following + operations are performed to generate one encoded frame: First, the incoming + audio samples are passed through the pre-processing filter where they are + filtered and downscaled. A call is then made to the main encoder cod_amr(). + This generates the set of encoded parameters which include the LSP, adaptive + codebook, and fixed codebook quantization indices (addresses and gains). The + generated parameters are then converted to serial bits. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + sp_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + Note: Original function name of Speech_Encode_Frame was changed to + GSMEncodeFrame in the Code section. + +int Speech_Encode_Frame ( + void *state_data, // i/o : post filter states + enum Mode mode, // i : speech coder mode + Word16 *new_speech, // i : speech input + Word16 *serial, // o : serial bit stream + enum Mode *usedMode // o : used speech coder mode + ) +{ + + Speech_Encode_FrameState *st = + (Speech_Encode_FrameState *) state_data; + + Word16 prm[MAX_PRM_SIZE]; // Analysis parameters + Word16 syn[L_FRAME]; // Buffer for synthesis speech + Word16 i; + + setCounter(st->complexityCounter); + Reset_WMOPS_counter (); // reset WMOPS counter for the new frame + // initialize the serial output frame to zero + for (i = 0; i < MAX_SERIAL_SIZE; i++) + { + serial[i] = 0; + } +#if !defined(NO13BIT) + // Delete the 3 LSBs (13-bit input) + for (i = 0; i < L_FRAME; i++) + { + new_speech[i] = new_speech[i] & 0xfff8; + + + } +#endif + + // filter + downscaling + Pre_Process (st->pre_state, new_speech, L_FRAME); + + // Call the speech encoder + cod_amr(st->cod_amr_state, mode, new_speech, prm, usedMode, syn); + + // Parameters to serial bits + Prm2bits (*usedMode, prm, &serial[0]); + + fwc(); + setCounter(0); // set counter to global counter + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void GSMEncodeFrame( + void *state_data, /* i/o : post filter states */ + enum Mode mode, /* i : speech coder mode */ + Word16 *new_speech, /* i : speech input */ + Word16 *serial, /* o : serial bit stream */ + enum Mode *usedMode /* o : used speech coder mode */ +) +{ + + Speech_Encode_FrameState *st = + (Speech_Encode_FrameState *) state_data; + + Word16 prm[MAX_PRM_SIZE]; /* Analysis parameters. */ + Word16 syn[L_FRAME]; /* Buffer for synthesis speech */ + Word16 i; + + /* initialize the serial output frame to zero */ + for (i = 0; i < MAX_SERIAL_SIZE; i++) + { + serial[i] = 0; + } +#if !defined(NO13BIT) + /* Delete the 3 LSBs (13-bit input) */ + for (i = 0; i < L_FRAME; i++) + { + new_speech[i] = new_speech[i] & 0xfff8; + } +#endif + + /* filter + downscaling */ + Pre_Process(st->pre_state, new_speech, L_FRAME); + + /* Call the speech encoder */ + cod_amr(st->cod_amr_state, mode, new_speech, prm, usedMode, syn); + + /* Parameters to serial bits */ + Prm2bits(*usedMode, prm, &serial[0], &(st->cod_amr_state->common_amr_tbls)); + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/sp_enc.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/sp_enc.h new file mode 100644 index 00000000..ba6abac4 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/sp_enc.h @@ -0,0 +1,135 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: sp_enc.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : sp_enc.h + Purpose : Encoding of one speech frame + +------------------------------------------------------------------------------ +*/ + +#ifndef sp_enc_h +#define sp_enc_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst.h" +#include "pre_proc.h" +#include "mode.h" +#include "cod_amr.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; [Define module specific macros here] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; [Include all pre-processor statements here.] + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; [Declare variables used in this module but defined elsewhere] + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + typedef struct + { + Pre_ProcessState *pre_state; + cod_amrState *cod_amr_state; + Flag dtx; + } Speech_Encode_FrameState; + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; [List function prototypes here] + ----------------------------------------------------------------------------*/ + /* initialize one instance of the speech encoder + Stores pointer to filter status struct in *st. This pointer has to + be passed to Speech_Encode_Frame in each call. + returns 0 on success */ + Word16 GSMInitEncode(void **state_data, + Flag dtx, + Word8 *id); + + + /* reset speech encoder (i.e. set state memory to zero) + returns 0 on success */ + Word16 Speech_Encode_Frame_reset(void *state_data); + + /* de-initialize speech encoder (i.e. free status struct) + stores NULL in *s */ + void GSMEncodeFrameExit(void **state_data); + + void Speech_Encode_Frame_First( + Speech_Encode_FrameState *st, /* i/o : post filter states */ + Word16 *new_speech); /* i : speech input */ + + void GSMEncodeFrame( + void *state_data, /* i/o : encoder states */ + enum Mode mode, /* i : speech coder mode */ + Word16 *new_speech, /* i : input speech */ + Word16 *serial, /* o : serial bit stream */ + enum Mode *usedMode /* o : used speech coder mode */ + ); + +#ifdef __cplusplus +} +#endif + +#endif /* _sp_enc_h_ */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/spreproc.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/spreproc.cpp new file mode 100644 index 00000000..ca827ae6 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/spreproc.cpp @@ -0,0 +1,198 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: spreproc.cpp + Functions: subframePreProc + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "spreproc.h" +#include "typedef.h" +#include "weight_a.h" +#include "syn_filt.h" +#include "residu.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: subframePreProc +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + mode -- enum Mode -- coder mode + gamma1 -- const Word16 array -- spectral exp. factor 1 + gamma1_12k2 -- const Word16 array -- spectral exp. factor 1 for EFR + gamma2 -- const Word16 array -- spectral exp. factor 2 + A -- Pointer to Word16 -- A(z) unquantized for the 4 subframes + Aq -- Pointer to Word16 -- A(z) quantized for the 4 subframes + speech -- Pointer to Word16 -- speech segment + mem_err -- Pointer to Word16 -- pointer to error signal + mem_w0 -- Pointer to Word16 -- memory of weighting filter + zero -- Pointer to Word16 -- pointer to zero vector + + Outputs: + ai_zero -- Word16 array -- history of weighted synth. filter + exc -- Word16 array -- long term prediction residual + h1 -- Word16 array -- impulse response + xn -- Word16 array -- target vector for pitch search + res2 -- Word16 array -- long term prediction residual + error -- Word16 array -- error of LPC synthesis filter + + Returns: + Zero + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + spreproc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void subframePreProc( + enum Mode mode, /* i : coder mode */ + const Word16 gamma1[], /* i : spectral exp. factor 1 */ + const Word16 gamma1_12k2[],/* i : spectral exp. factor 1 for EFR */ + const Word16 gamma2[], /* i : spectral exp. factor 2 */ + Word16 *A, /* i : A(z) unquantized for the 4 subframes */ + Word16 *Aq, /* i : A(z) quantized for the 4 subframes */ + Word16 *speech, /* i : speech segment */ + Word16 *mem_err, /* i : pointer to error signal */ + Word16 *mem_w0, /* i : memory of weighting filter */ + Word16 *zero, /* i : pointer to zero vector */ + Word16 ai_zero[], /* o : history of weighted synth. filter */ + Word16 exc[], /* o : long term prediction residual */ + Word16 h1[], /* o : impulse response */ + Word16 xn[], /* o : target vector for pitch search */ + Word16 res2[], /* o : long term prediction residual */ + Word16 error[] /* o : error of LPC synthesis filter */ +) +{ + Word16 Ap1[MP1]; /* A(z) with spectral expansion */ + Word16 Ap2[MP1]; /* A(z) with spectral expansion */ + const Word16 *g1; /* Pointer to correct gammma1 vector */ + + /* mode specific pointer to gamma1 values */ + if (mode == MR122 || mode == MR102) + { + g1 = gamma1_12k2; + } + else + { + g1 = gamma1; + } + + /* Find the weighted LPC coefficients for the weighting filter. */ + Weight_Ai(A, g1, Ap1); + Weight_Ai(A, gamma2, Ap2); + + oscl_memcpy(ai_zero, Ap1, (M + 1)*sizeof(Word16)); + + + Syn_filt(Aq, ai_zero, h1, L_SUBFR, zero, 0); + Syn_filt(Ap2, h1, h1, L_SUBFR, zero, 0); + + /* + * + * Find the target vector for pitch search: + * + */ + + /* LPC residual */ + Residu(Aq, speech, res2, L_SUBFR); + + oscl_memcpy(exc, res2, L_SUBFR*sizeof(Word16)); + + Syn_filt(Aq, exc, error, L_SUBFR, mem_err, 0); + + Residu(Ap1, error, xn, L_SUBFR); + + /* target signal xn[]*/ + Syn_filt(Ap2, xn, xn, L_SUBFR, mem_w0, 0); + + return; + +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/spreproc.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/spreproc.h new file mode 100644 index 00000000..ee283dc6 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/spreproc.h @@ -0,0 +1,122 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: spreproc.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the file, spreproc.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef spreproc_h +#define spreproc_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "cnst.h" +#include "mode.h" +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + void subframePreProc( + enum Mode mode, /* i : coder mode */ + const Word16 gamma1[], /* i : spectral exp. factor 1 */ + const Word16 gamma1_12k2[],/* i : spectral exp. factor 1 for EFR */ + const Word16 gamma2[], /* i : spectral exp. factor 2 */ + Word16 *A, /* i : A(z) unquantized for the 4 subframes */ + Word16 *Aq, /* i : A(z) quantized for the 4 subframes */ + Word16 *speech, /* i : speech segment */ + Word16 *mem_err, /* i : pointer to error signal */ + Word16 *mem_w0, /* i : memory of weighting filter */ + Word16 *zero, /* i : pointer to zero vector */ + Word16 ai_zero[], /* o : history of weighted synth. filter */ + Word16 exc[], /* o : long term prediction residual */ + Word16 h1[], /* o : impulse response */ + Word16 xn[], /* o : target vector for pitch search */ + Word16 res2[], /* o : long term prediction residual */ + Word16 error[] /* o : error of LPC synthesis filter */ + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* spreproc_h */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/spstproc.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/spstproc.cpp new file mode 100644 index 00000000..3e2c2347 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/spstproc.cpp @@ -0,0 +1,277 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: spstproc.cpp + Functions: subframePostProc + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + Subframe post processing +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "spstproc.h" +#include "syn_filt.h" +#include "cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: subframePostProc +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + + Inputs: + speech -- Pointer to Word16 -- speech segment + mode -- enum Mode -- coder mode + i_subfr -- Word16 -- Subframe nr + gain_pit -- Word16 -- Pitch gain Q14 + gain_code -- Word16 -- Decoded innovation gain + Aq -- Pointer to Word16 -- A(z) quantized for the 4 subframes + synth -- Word16 Array -- Local synthesis + xn -- Word16 Array -- Target vector for pitch search + code -- Word16 Array -- Fixed codebook exitation + y1 -- Word16 Array -- Filtered adaptive exitation + y2 -- Word16 Array -- Filtered fixed codebook excitation + mem_syn -- Pointer to Word16 -- memory of synthesis filter + + Outputs: + mem_syn -- Pointer to Word16 -- memory of synthesis filter + mem_err -- Pointer to Word16 -- pointer to error signal + mem_w0 -- Pointer to Word16 -- memory of weighting filter + exc -- Pointer to Word16 -- long term prediction residual + sharp -- Pointer to Word16 -- pitch sharpening value + pOverflow -- Pointer to Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + spstproc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void subframePostProc( + Word16 *speech, /* i : speech segment */ + enum Mode mode, /* i : coder mode */ + Word16 i_subfr, /* i : Subframe nr */ + Word16 gain_pit, /* i : Pitch gain Q14 */ + Word16 gain_code, /* i : Decoded innovation gain */ + Word16 *Aq, /* i : A(z) quantized for the 4 subframes */ + Word16 synth[], /* i : Local snthesis */ + Word16 xn[], /* i : Target vector for pitch search */ + Word16 code[], /* i : Fixed codebook exitation */ + Word16 y1[], /* i : Filtered adaptive exitation */ + Word16 y2[], /* i : Filtered fixed codebook excitation */ + Word16 *mem_syn, /* i/o : memory of synthesis filter */ + Word16 *mem_err, /* o : pointer to error signal */ + Word16 *mem_w0, /* o : memory of weighting filter */ + Word16 *exc, /* o : long term prediction residual */ + Word16 *sharp, /* o : pitch sharpening value */ + Flag *pOverflow /* o : overflow indicator */ +) +{ + Word16 i; + Word16 j; + Word16 temp; + Word32 L_temp; + Word32 L_temp2; + Word16 tempShift; + Word16 kShift; + Word16 pitch_fac; + Word16 *p_exc; + Word16 *p_code; + + OSCL_UNUSED_ARG(pOverflow); + + if (mode != MR122) + { + tempShift = 1; + kShift = 16 - 2 - 1; + pitch_fac = gain_pit; + } + else + { + tempShift = 2; + kShift = 16 - 4 - 1; + pitch_fac = gain_pit >> 1; + } + + /*------------------------------------------------------------* + * - Update pitch sharpening "sharp" with quantized gain_pit * + *------------------------------------------------------------*/ + + if (gain_pit < SHARPMAX) + { + *sharp = gain_pit; + } + else + { + *sharp = SHARPMAX; + } + + /*------------------------------------------------------* + * - Find the total excitation * + * - find synthesis speech corresponding to exc[] * + * - update filters memories for finding the target * + * vector in the next subframe * + * (update error[-m..-1] and mem_w_err[]) * + *------------------------------------------------------*/ + + p_exc = &exc[ i_subfr]; + p_code = &code[0]; + + for (i = L_SUBFR >> 1; i != 0 ; i--) + { + /* exc[i] = gain_pit*exc[i] + gain_code*code[i]; */ + + /* + * 12k2 others + * --------------------------------- + * exc Q0 Q0 + * gain_pit Q14 Q14 + * pitch_fac Q13 Q14 + * product: Q14 Q15 + * + * code Q12 Q13 + * gain_code Q1 Q1 + * product Q14 Q15 + * sum Q14 Q15 + * + * tempShift 2 1 + * sum< exc Q0 Q0 + */ + L_temp = ((Word32) * (p_exc++) * pitch_fac) << 1; + L_temp2 = ((Word32) * (p_exc--) * pitch_fac) << 1; + L_temp += ((Word32) * (p_code++) * gain_code) << 1; + L_temp2 += ((Word32) * (p_code++) * gain_code) << 1; + L_temp <<= tempShift; + L_temp2 <<= tempShift; + *(p_exc++) = (Word16)((L_temp + 0x08000L) >> 16); + *(p_exc++) = (Word16)((L_temp2 + 0x08000L) >> 16); + + } + + Syn_filt( + Aq, + &exc[i_subfr], + &synth[i_subfr], + L_SUBFR, + mem_syn, + 1); + + for (i = L_SUBFR - M, j = 0; i < L_SUBFR; i++, j++) + { + mem_err[j] = speech[i_subfr + i] - synth[i_subfr + i]; + + /* + * 12k2 others + * --------------------------------- + * y1 Q0 Q0 + * gain_pit Q14 Q14 + * product Q15 Q15 + * shifted prod. Q16 Q16 + * temp Q0 Q0 + * + * y2 Q10 Q12 + * gain_code Q1 Q1 + * product Q12 Q14 + * kshift 4 2 + * shifted prod. Q16 Q16 + * k Q0 Q0 + * mem_w0,xn,sum Q0 Q0 + */ + + L_temp = ((Word32)y1[i] * gain_pit); + temp = (Word16)(L_temp >> 14); + + L_temp = ((Word32)y2[i] * gain_code); + temp += (Word16)(L_temp >> kShift); + + mem_w0[j] = xn[i] - temp; + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/spstproc.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/spstproc.h new file mode 100644 index 00000000..4c122798 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/spstproc.h @@ -0,0 +1,122 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: spstproc.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions and prototype definitions + needed by the file, spstproc.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef spstproc_h +#define spstproc_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void subframePostProc( + Word16 *speech, /* i : speech segment */ + enum Mode mode, /* i : coder mode */ + Word16 i_subfr, /* i : Subframe nr */ + Word16 gain_pit, /* i : Pitch gain Q14 */ + Word16 gain_code, /* i : Decoded innovation gain */ + Word16 *Aq, /* i : A(z) quantized for the 4 subframes */ + Word16 synth[], /* i : Local snthesis */ + Word16 xn[], /* i : Target vector for pitch search */ + Word16 code[], /* i : Fixed codebook exitation */ + Word16 y1[], /* i : Filtered adaptive exitation */ + Word16 y2[], /* i : Filtered fixed codebook excitation */ + Word16 *mem_syn, /* i/o : memory of synthesis filter */ + Word16 *mem_err, /* o : pointer to error signal */ + Word16 *mem_w0, /* o : memory of weighting filter */ + Word16 *exc, /* o : long term prediction residual */ + Word16 *sharp, /* o : pitch sharpening value */ + Flag *pOverflow + ); + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* spstproc_h */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ton_stab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ton_stab.cpp new file mode 100644 index 00000000..8418c709 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ton_stab.cpp @@ -0,0 +1,683 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: ton_stab.cpp + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "ton_stab.h" +#include "oper_32b.h" +#include "cnst.h" +#include "set_zero.h" +#include "basic_op.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ton_stab_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to pointer to structure type tonStabState. + + Outputs: + None + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function: ton_stab_init + Purpose: Allocates state memory and initializes state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + ton_stab.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int ton_stab_init (tonStabState **state) +{ + tonStabState* s; + + if (state == (tonStabState **) NULL){ + // fprintf(stderr, "ton_stab_init: invalid parameter\n"); + return -1; + } + *state = NULL; + + // allocate memory + if ((s= (tonStabState *) malloc(sizeof(tonStabState))) == NULL){ + // fprintf(stderr, "ton_stab_init: can not malloc state structure\n"); + return -1; + } + + ton_stab_reset(s); + + *state = s; + + return 0; +} + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 ton_stab_init(tonStabState **state) +{ + tonStabState* s; + + if (state == (tonStabState **) NULL) + { + /* fprintf(stderr, "ton_stab_init: invalid parameter\n"); */ + return -1; + } + *state = NULL; + + /* allocate memory */ + if ((s = (tonStabState *) oscl_malloc(sizeof(tonStabState))) == NULL) + { + /* fprintf(stderr, "ton_stab_init: can not malloc state structure\n"); */ + return -1; + } + + ton_stab_reset(s); + + *state = s; + + return 0; +} + +/****************************************************************************/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ton_stab_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st = pointer to pointer to structure type tonStabState. + + Outputs: + None + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function: ton_stab_reset + Purpose: Initializes state memory to zero + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + ton_stab.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +int ton_stab_reset (tonStabState *st) +{ + if (st == (tonStabState *) NULL){ + // fprintf(stderr, "ton_stab_init: invalid parameter\n"); + return -1; + } + + // initialize tone stabilizer state + st->count = 0; + Set_zero(st->gp, N_FRAME); // Init Gp_Clipping + + return 0; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 ton_stab_reset(tonStabState *st) +{ + if (st == (tonStabState *) NULL) + { + /* fprintf(stderr, "ton_stab_init: invalid parameter\n"); */ + return -1; + } + + /* initialize tone stabilizer state */ + st->count = 0; + /* Init Gp_Clipping */ + oscl_memset((void *)st->gp, 0, N_FRAME*sizeof(*st->gp)); + + + return 0; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: ton_stab_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to pointer to structure type tonStabState. + + Outputs: + None + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function: ton_stab_exit + Purpose: The memory used for state memory is freed + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + ton_stab.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void ton_stab_exit (tonStabState **state) +{ + if (state == NULL || *state == NULL) + return; + + // deallocate memory + free(*state); + *state = NULL; + + return; +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void ton_stab_exit(tonStabState **state) +{ + if (state == NULL || *state == NULL) + return; + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: check_lsp +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to pointer to structure type tonStabState. + lsp = pointer to unquantized LSPs of type Word16 + + Outputs: + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function: check_lsp() + Purpose: Check the LSP's to detect resonances + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + ton_stab.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 check_lsp(tonStabState *st, // i/o : State struct + Word16 *lsp // i : unquantized LSP's +) +{ + Word16 i, dist, dist_min1, dist_min2, dist_th; + + // Check for a resonance: + // Find minimum distance between lsp[i] and lsp[i+1] + + dist_min1 = MAX_16; + for (i = 3; i < M-2; i++) + { + dist = sub(lsp[i], lsp[i+1]); + + if (sub(dist, dist_min1) < 0) + { + dist_min1 = dist; + } + } + + dist_min2 = MAX_16; + for (i = 1; i < 3; i++) + { + dist = sub(lsp[i], lsp[i+1]); + + if (sub(dist, dist_min2) < 0) + { + dist_min2 = dist; + } + } + + if (sub(lsp[1], 32000) > 0) + { + dist_th = 600; + } + else if (sub(lsp[1], 30500) > 0) + { + dist_th = 800; + } + else + { + dist_th = 1100; + } + + if (sub(dist_min1, 1500) < 0 || + sub(dist_min2, dist_th) < 0) + { + st->count = add(st->count, 1); + } + else + { + st->count = 0; + } + + // Need 12 consecutive frames to set the flag + if (sub(st->count, 12) >= 0) + { + st->count = 12; + return 1; + } + else + { + return 0; + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 check_lsp(tonStabState *st, /* i/o : State struct */ + Word16 *lsp, /* i : unquantized LSP's */ + Flag *pOverflow + ) +{ + Word16 i; + Word16 dist; + Word16 dist_min1; + Word16 dist_min2; + Word16 dist_th; + Word16 *p_lsp = &lsp[3]; + Word16 *p_lsp_1 = &lsp[4]; + + OSCL_UNUSED_ARG(pOverflow); + /* Check for a resonance: */ + /* Find minimum distance between lsp[i] and lsp[i+1] */ + + dist_min1 = MAX_16; + for (i = 3; i < M - 2; i++) + { + dist = *(p_lsp++) - *(p_lsp_1++); + + if (dist < dist_min1) + { + dist_min1 = dist; + } + } + + dist_min2 = MAX_16; + p_lsp = &lsp[1]; + p_lsp_1 = &lsp[2]; + + for (i = 1; i < 3; i++) + { + dist = *(p_lsp++) - *(p_lsp_1++); + + if (dist < dist_min2) + { + dist_min2 = dist; + } + } + + if (lsp[1] > 32000) + { + dist_th = 600; + } + else if (lsp[1] > 30500) + { + dist_th = 800; + } + else + { + dist_th = 1100; + } + + if ((dist_min1 < 1500) || (dist_min2 < dist_th)) + { + st->count++; + } + else + { + st->count = 0; + } + + /* Need 12 consecutive frames to set the flag */ + if (st->count >= 12) + { + st->count = 12; + return 1; + } + else + { + return 0; + } +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: check_gp_clipping +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to pointer to structure type tonStabState. + g_pitch = pitch gain of type Word16 + + Outputs: + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function: Check_Gp_Clipping() + Purpose: Verify that the sum of the last (N_FRAME+1) pitch + gains is under a certain threshold. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + ton_stab.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 check_gp_clipping(tonStabState *st, // i/o : State struct + Word16 g_pitch // i : pitch gain +) +{ + Word16 i, sum; + + sum = shr(g_pitch, 3); // Division by 8 + for (i = 0; i < N_FRAME; i++) + { + sum = add(sum, st->gp[i]); + } + + if (sub(sum, GP_CLIP) > 0) + { + return 1; + } + else + { + return 0; + } +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 check_gp_clipping(tonStabState *st, /* i/o : State struct */ + Word16 g_pitch, /* i : pitch gain */ + Flag *pOverflow + ) +{ + Word16 i; + Word16 sum; + + sum = shr(g_pitch, 3, pOverflow); /* Division by 8 */ + for (i = 0; i < N_FRAME; i++) + { + sum = add_16(sum, st->gp[i], pOverflow); + } + + if (sum > GP_CLIP) + { + return 1; + } + else + { + return 0; + } +} + +/****************************************************************************/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: update_gp_clipping +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state = pointer to pointer to structure type tonStabState. + g_pitch = pitch gain of type Word16 + + Outputs: + pOverflow = 1 if there is an overflow else it is zero. + + Returns: + None. + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function: Update_Gp_Clipping() + Purpose: Update past pitch gain memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + ton_stab.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +void update_gp_clipping(tonStabState *st, // i/o : State struct + Word16 g_pitch // i : pitch gain +) +{ + Copy(&st->gp[1], &st->gp[0], N_FRAME-1); + st->gp[N_FRAME-1] = shr(g_pitch, 3); +} + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void update_gp_clipping(tonStabState *st, /* i/o : State struct */ + Word16 g_pitch, /* i : pitch gain */ + Flag *pOverflow + ) +{ + OSCL_UNUSED_ARG(pOverflow); + for (int i = 0; i < N_FRAME - 1; i++) + { + st->gp[i] = st->gp[i+1]; + } + st->gp[N_FRAME-1] = g_pitch >> 3; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ton_stab.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ton_stab.h new file mode 100644 index 00000000..90e53789 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/ton_stab.h @@ -0,0 +1,144 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: ton_stab.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + File : ton_stab.h + Purpose : Tone stabilization routines + +------------------------------------------------------------------------------ +*/ + +#ifndef TON_STAB_H +#define TON_STAB_H +#define ton_stab_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "mode.h" +#include "cnst.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + /* state variable */ + typedef struct + { + /* counters */ + Word16 count; + /* gain history Q11 */ + Word16 gp[N_FRAME]; + } tonStabState; + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 ton_stab_init(tonStabState **st); + /* initialize one instance of the pre processing state. + Stores pointer to filter status struct in *st. This pointer has to + be passed to ton_stab in each call. + returns 0 on success + */ + + Word16 ton_stab_reset(tonStabState *st); + /* reset of pre processing state (i.e. set state memory to zero) + returns 0 on success + */ + + void ton_stab_exit(tonStabState **st); + /* de-initialize pre processing state (i.e. free status struct) + stores NULL in *st + */ + + Word16 check_lsp(tonStabState *st, /* i/o : State struct */ + Word16 *lsp, /* i : unquantized LSP's */ + Flag *pOverflow + ); + + Word16 check_gp_clipping(tonStabState *st, /* i/o : State struct */ + Word16 g_pitch, /* i : pitch gain */ + Flag *pOverflow + ); + + void update_gp_clipping(tonStabState *st, /* i/o : State struct */ + Word16 g_pitch, /* i : pitch gain */ + Flag *pOverflow + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _TON_STAB_H_ */ + + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/vad1.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/vad1.cpp new file mode 100644 index 00000000..d949b6c2 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/vad1.cpp @@ -0,0 +1,2013 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: vad1.cpp + Functions: + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "vad.h" +#include "typedef.h" +#include "shr.h" +#include "basic_op.h" +#include "cnst_vad.h" +#include "oscl_mem.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: first_filter_stage +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + data -- array of type Word16 -- filter memory + in -- array of type Word16 -- input signal + + Outputs: + data -- array of type Word16 -- filter memory + out -- array of type Word16 -- output values, every other + output is low-pass part and + other is high-pass part every + + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Scale input down by one bit. Calculate 5th order + half-band lowpass/highpass filter pair with + decimation. +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void first_filter_stage( + Word16 in[], /* i : input signal */ + Word16 out[], /* o : output values, every other */ + /* output is low-pass part and */ + /* other is high-pass part every */ + Word16 data[], /* i/o : filter memory */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 temp0; + Word16 temp1; + Word16 temp2; + Word16 temp3; + Word16 i; + Word16 data0; + Word16 data1; + + data0 = data[0]; + data1 = data[1]; + + for (i = 0; i < FRAME_LEN / 4; i++) + { +// temp0 = mult(COEFF5_1, data0, pOverflow); + temp0 = (Word16)(((Word32)COEFF5_1 * data0) >> 15); + temp1 = in[4*i+0] >> 2; + temp0 = sub(temp1, temp0, pOverflow); + +// temp1 = mult(COEFF5_1, temp0, pOverflow); + temp1 = (Word16)(((Word32)COEFF5_1 * temp0) >> 15); + temp1 = add_16(data0, temp1, pOverflow); + +// temp3 = mult(COEFF5_2, data1, pOverflow); + temp3 = (Word16)(((Word32)COEFF5_2 * data1) >> 15); + + temp2 = in[4*i+1] >> 2; + + temp3 = sub(temp2, temp3, pOverflow); + +// temp2 = mult(COEFF5_2, temp3, pOverflow); + temp2 = (Word16)(((Word32)COEFF5_2 * temp3) >> 15); + + temp2 = add_16(data1, temp2, pOverflow); + + out[4*i+0] = add_16(temp1, temp2, pOverflow); + out[4*i+1] = sub(temp1, temp2, pOverflow); + +// temp1 = mult(COEFF5_1, temp0, pOverflow); + temp1 = (Word16)(((Word32)COEFF5_1 * temp0) >> 15); + + temp2 = in[4*i+2] >> 2; + data0 = sub(temp2, temp1, pOverflow); + +// temp1 = mult(COEFF5_1, data0, pOverflow); + temp1 = (Word16)(((Word32)COEFF5_1 * data0) >> 15); + + temp1 = add_16(temp0, temp1, pOverflow); + +// data1 = mult(COEFF5_2, temp3, pOverflow); + data1 = (Word16)(((Word32)COEFF5_2 * temp3) >> 15); + temp2 = in[4*i+3] >> 2; + data1 = sub(temp2, data1, pOverflow); + +// temp2 = mult(COEFF5_2, data1, pOverflow); + temp2 = (Word16)(((Word32)COEFF5_2 * data1) >> 15); + temp2 = add_16(temp3, temp2, pOverflow); + + out[4*i+2] = add_16(temp1, temp2, pOverflow); + out[4*i+3] = sub(temp1, temp2, pOverflow); + } + + data[0] = data0; + data[1] = data1; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: filter5 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + in0 -- array of type Word16 -- input values; output low-pass part + in1 -- array of type Word16 -- input values; output high-pass part + data -- array of type Word16 -- updated filter memory + + Outputs: + in0 -- array of type Word16 -- input values; output low-pass part + in1 -- array of type Word16 -- input values; output high-pass part + data -- array of type Word16 -- updated filter memory + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Fifth-order half-band lowpass/highpass filter pair with + decimation. +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void filter5(Word16 *in0, /* i/o : input values; output low-pass part */ + Word16 *in1, /* i/o : input values; output high-pass part */ + Word16 data[], /* i/o : updated filter memory */ + Flag *pOverflow /* o : Flag set when overflow occurs */ + ) +{ + Word16 temp0; + Word16 temp1; + Word16 temp2; + + temp0 = mult(COEFF5_1, data[0], pOverflow); + temp0 = sub(*in0, temp0, pOverflow); + + temp1 = mult(COEFF5_1, temp0, pOverflow); + temp1 = add_16(data[0], temp1, pOverflow); + data[0] = temp0; + + temp0 = mult(COEFF5_2, data[1], pOverflow); + temp0 = sub(*in1, temp0, pOverflow); + + temp2 = mult(COEFF5_2, temp0, pOverflow); + temp2 = add_16(data[1], temp2, pOverflow); + + data[1] = temp0; + + temp0 = add_16(temp1, temp2, pOverflow); + *in0 = shr(temp0, 1, pOverflow); + + temp0 = sub(temp1, temp2, pOverflow); + *in1 = shr(temp0, 1, pOverflow); +} + + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: filter3 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + + Inputs: + in0 -- array of type Word16 -- input values; output low-pass part + in1 -- array of type Word16 -- input values; output high-pass part + data -- array of type Word16 -- updated filter memory + + Outputs: + in0 -- array of type Word16 -- input values; output low-pass part + in1 -- array of type Word16 -- input values; output high-pass part + data -- array of type Word16 -- updated filter memory + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Third-order half-band lowpass/highpass filter pair with + decimation. +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void filter3( + Word16 *in0, /* i/o : input values; output low-pass part */ + Word16 *in1, /* i/o : input values; output high-pass part */ + Word16 *data, /* i/o : updated filter memory */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 temp1; + Word16 temp2; + + temp1 = mult(COEFF3, *data, pOverflow); + temp1 = sub(*in1, temp1, pOverflow); + + temp2 = mult(COEFF3, temp1, pOverflow); + temp2 = add_16(*data, temp2, pOverflow); + + *data = temp1; + + temp1 = sub(*in0, temp2, pOverflow); + + *in1 = shr(temp1, 1, pOverflow); + + temp1 = add_16(*in0, temp2, pOverflow); + + *in0 = shr(temp1, 1, pOverflow); +} + + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: level_calculation +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + data -- array of type Word16 -- signal buffer + sub_level -- pointer to type Word16 -- level calculated at the end of + the previous frame + + count1 -- Word16 -- number of samples to be counted + count2 -- Word16 -- number of samples to be counted + ind_m -- Word16 -- step size for the index of the data buffer + ind_a -- Word16 -- starting index of the data buffer + scale -- Word16 -- scaling for the level calculation + + Outputs: + sub_level -- pointer to tyep Word16 -- level of signal calculated from the + last (count2 - count1) samples. + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + signal level + + Global Variables Used: + + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Calculate signal level in a sub-band. Level is calculated + by summing absolute values of the input data. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 level_calculation( + Word16 data[], /* i : signal buffer */ + Word16 *sub_level, /* i : level calculate at the end of */ + /* the previous frame */ + /* o : level of signal calculated from the last */ + /* (count2 - count1) samples */ + Word16 count1, /* i : number of samples to be counted */ + Word16 count2, /* i : number of samples to be counted */ + Word16 ind_m, /* i : step size for the index of the data buffer */ + Word16 ind_a, /* i : starting index of the data buffer */ + Word16 scale, /* i : scaling for the level calculation */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word32 l_temp1; + Word32 l_temp2; + Word16 level; + Word16 i; + + l_temp1 = 0L; + + for (i = count1; i < count2; i++) + { + l_temp1 = L_mac(l_temp1, 1, abs_s(data[ind_m*i+ind_a]), pOverflow); + } + + l_temp2 = L_add(l_temp1, L_shl(*sub_level, sub(16, scale, pOverflow), pOverflow), pOverflow); + *sub_level = (Word16)(L_shl(l_temp1, scale, pOverflow) >> 16); + + for (i = 0; i < count1; i++) + { + l_temp2 = L_mac(l_temp2, 1, abs_s(data[ind_m*i+ind_a]), pOverflow); + } + level = (Word16)(L_shl(l_temp2, scale, pOverflow) >> 16); + + return level; +} + + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: filter_bank +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + in -- array of type Word16 -- input frame + + Outputs: + level -- array of type Word16 -- signal levels at each band + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Divides input signal into 9-bands and calculas level of + the signal in each band + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void filter_bank( + vadState1 *st, /* i/o : State struct */ + Word16 in[], /* i : input frame */ + Word16 level[], /* 0 : signal levels at each band */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 tmp_buf[FRAME_LEN]; + + /* calculate the filter bank */ + + first_filter_stage(in, tmp_buf, st->a_data5[0], pOverflow); + + for (i = 0; i < FRAME_LEN / 4; i++) + { + filter5(&tmp_buf[4*i], &tmp_buf[4*i+2], st->a_data5[1], pOverflow); + filter5(&tmp_buf[4*i+1], &tmp_buf[4*i+3], st->a_data5[2], pOverflow); + } + for (i = 0; i < FRAME_LEN / 8; i++) + { + filter3(&tmp_buf[8*i+0], &tmp_buf[8*i+4], &st->a_data3[0], pOverflow); + filter3(&tmp_buf[8*i+2], &tmp_buf[8*i+6], &st->a_data3[1], pOverflow); + filter3(&tmp_buf[8*i+3], &tmp_buf[8*i+7], &st->a_data3[4], pOverflow); + } + + for (i = 0; i < FRAME_LEN / 16; i++) + { + filter3(&tmp_buf[16*i+0], &tmp_buf[16*i+8], &st->a_data3[2], pOverflow); + filter3(&tmp_buf[16*i+4], &tmp_buf[16*i+12], &st->a_data3[3], pOverflow); + } + + /* calculate levels in each frequency band */ + + /* 3000 - 4000 Hz*/ + level[8] = level_calculation(tmp_buf, &st->sub_level[8], FRAME_LEN / 4 - 8, + FRAME_LEN / 4, 4, 1, 15, pOverflow); + /* 2500 - 3000 Hz*/ + level[7] = level_calculation(tmp_buf, &st->sub_level[7], FRAME_LEN / 8 - 4, + FRAME_LEN / 8, 8, 7, 16, pOverflow); + /* 2000 - 2500 Hz*/ + level[6] = level_calculation(tmp_buf, &st->sub_level[6], FRAME_LEN / 8 - 4, + FRAME_LEN / 8, 8, 3, 16, pOverflow); + /* 1500 - 2000 Hz*/ + level[5] = level_calculation(tmp_buf, &st->sub_level[5], FRAME_LEN / 8 - 4, + FRAME_LEN / 8, 8, 2, 16, pOverflow); + /* 1000 - 1500 Hz*/ + level[4] = level_calculation(tmp_buf, &st->sub_level[4], FRAME_LEN / 8 - 4, + FRAME_LEN / 8, 8, 6, 16, pOverflow); + /* 750 - 1000 Hz*/ + level[3] = level_calculation(tmp_buf, &st->sub_level[3], FRAME_LEN / 16 - 2, + FRAME_LEN / 16, 16, 4, 16, pOverflow); + /* 500 - 750 Hz*/ + level[2] = level_calculation(tmp_buf, &st->sub_level[2], FRAME_LEN / 16 - 2, + FRAME_LEN / 16, 16, 12, 16, pOverflow); + /* 250 - 500 Hz*/ + level[1] = level_calculation(tmp_buf, &st->sub_level[1], FRAME_LEN / 16 - 2, + FRAME_LEN / 16, 16, 8, 16, pOverflow); + /* 0 - 250 Hz*/ + level[0] = level_calculation(tmp_buf, &st->sub_level[0], FRAME_LEN / 16 - 2, + FRAME_LEN / 16, 16, 0, 16, pOverflow); +} + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: update_cntrl +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + level -- array of type Word16 -- sub-band levels of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Control update of the background noise estimate. + Inputs : pitch: flags for pitch detection + stat_count: stationary counter + tone: flags indicating presence of a tone + complex: flags for complex detection + vadreg: intermediate VAD flags + Output : stat_count: stationary counter + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void update_cntrl( + vadState1 *st, /* i/o : State struct */ + Word16 level[], /* i : sub-band levels of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 temp; + Word16 stat_rat; + Word16 exp; + Word16 num; + Word16 denom; + Word16 alpha; + + /* handle highband complex signal input separately */ + /* if ther has been highband correlation for some time */ + /* make sure that the VAD update speed is low for a while */ + if (st->complex_warning != 0) + { + if (st->stat_count < CAD_MIN_STAT_COUNT) + { + st->stat_count = CAD_MIN_STAT_COUNT; + } + } + /* NB stat_count is allowed to be decreased by one below again */ + /* deadlock in speech is not possible unless the signal is very */ + /* complex and need a high rate */ + + /* if fullband pitch or tone have been detected for a while, initialize stat_count */ + if (((Word16)(st->pitch & 0x6000) == 0x6000) || + ((Word16)(st->tone & 0x7c00) == 0x7c00)) + { + st->stat_count = STAT_COUNT; + } + else + { + /* if 8 last vad-decisions have been "0", reinitialize stat_count */ + if ((st->vadreg & 0x7f80) == 0) + { + st->stat_count = STAT_COUNT; + } + else + { + stat_rat = 0; + for (i = 0; i < COMPLEN; i++) + { + if (level[i] > st->ave_level[i]) + { + num = level[i]; + denom = st->ave_level[i]; + } + else + { + num = st->ave_level[i]; + denom = level[i]; + } + /* Limit nimimum value of num and denom to STAT_THR_LEVEL */ + if (num < STAT_THR_LEVEL) + { + num = STAT_THR_LEVEL; + } + if (denom < STAT_THR_LEVEL) + { + denom = STAT_THR_LEVEL; + } + + exp = norm_s(denom); + + denom = shl(denom, exp, pOverflow); + + /* stat_rat = num/denom * 64 */ + temp = shr(num, 1, pOverflow); + temp = div_s(temp, denom); + + stat_rat = add_16(stat_rat, shr(temp, sub(8, exp, pOverflow), pOverflow), pOverflow); + } + + /* compare stat_rat with a threshold and update stat_count */ + if (stat_rat > STAT_THR) + { + st->stat_count = STAT_COUNT; + } + else + { + if ((st->vadreg & 0x4000) != 0) + { + if (st->stat_count != 0) + { + st->stat_count = sub(st->stat_count, 1, pOverflow); + } + } + } + } + } + + /* Update average amplitude estimate for stationarity estimation */ + alpha = ALPHA4; + if (st->stat_count == STAT_COUNT) + { + alpha = 32767; + } + else if ((st->vadreg & 0x4000) == 0) + { + alpha = ALPHA5; + } + + for (i = 0; i < COMPLEN; i++) + { + temp = sub(level[i], st->ave_level[i], pOverflow); + temp = mult_r(alpha, temp, pOverflow); + + st->ave_level[i] = + add_16( + st->ave_level[i], + temp, + pOverflow); + } +} + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: hangover_addition +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + noise_level -- Word16 -- average level of the noise estimates + low_power -- Word16 -- flag power of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicato + + Returns: + VAD_flag indicating final VAD decision (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function : hangover_addition + Purpose : Add hangover for complex signal or after speech bursts + Inputs : burst_count: counter for the length of speech bursts + hang_count: hangover counter + vadreg: intermediate VAD decision + Outputs : burst_count: counter for the length of speech bursts + hang_count: hangover counter + Return value : VAD_flag indicating final VAD decision + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 hangover_addition( + vadState1 *st, /* i/o : State struct */ + Word16 noise_level, /* i : average level of the noise */ + /* estimates */ + Word16 low_power, /* i : flag power of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 hang_len; + Word16 burst_len; + + /* + Calculate burst_len and hang_len + burst_len: number of consecutive intermediate vad flags with "1"-decision + required for hangover addition + hang_len: length of the hangover + */ + + if (noise_level > HANG_NOISE_THR) + { + burst_len = BURST_LEN_HIGH_NOISE; + hang_len = HANG_LEN_HIGH_NOISE; + } + else + { + burst_len = BURST_LEN_LOW_NOISE; + hang_len = HANG_LEN_LOW_NOISE; + } + + /* if the input power (pow_sum) is lower than a threshold, clear + counters and set VAD_flag to "0" "fast exit" */ + if (low_power != 0) + { + st->burst_count = 0; + st->hang_count = 0; + st->complex_hang_count = 0; + st->complex_hang_timer = 0; + return 0; + } + + if (st->complex_hang_timer > CVAD_HANG_LIMIT) + { + if (st->complex_hang_count < CVAD_HANG_LENGTH) + { + st->complex_hang_count = CVAD_HANG_LENGTH; + } + } + + /* long time very complex signal override VAD output function */ + if (st->complex_hang_count != 0) + { + st->burst_count = BURST_LEN_HIGH_NOISE; + st->complex_hang_count = sub(st->complex_hang_count, 1, pOverflow); + return 1; + } + else + { + /* let hp_corr work in from a noise_period indicated by the VAD */ + if (((st->vadreg & 0x3ff0) == 0) && + (st->corr_hp_fast > CVAD_THRESH_IN_NOISE)) + { + return 1; + } + } + + /* update the counters (hang_count, burst_count) */ + if ((st->vadreg & 0x4000) != 0) + { + st->burst_count = add_16(st->burst_count, 1, pOverflow); + + if (st->burst_count >= burst_len) + { + st->hang_count = hang_len; + } + return 1; + } + else + { + st->burst_count = 0; + if (st->hang_count > 0) + { + st->hang_count = sub(st->hang_count, 1, pOverflow); + return 1; + } + } + return 0; +} + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: noise_estimate_update +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + level -- array of type Word16 -- sub-band levels of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Update of background noise estimate + Inputs : bckr_est: background noise estimate + pitch: flags for pitch detection + stat_count: stationary counter + Outputs : bckr_est: background noise estimate + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void noise_estimate_update( + vadState1 *st, /* i/o : State struct */ + Word16 level[], /* i : sub-band levels of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 alpha_up; + Word16 alpha_down; + Word16 bckr_add; + + /* Control update of bckr_est[] */ + update_cntrl(st, level, pOverflow); + + /* Choose update speed */ + bckr_add = 2; + + if (((0x7800 & st->vadreg) == 0) && + ((st->pitch & 0x7800) == 0) + && (st->complex_hang_count == 0)) + { + alpha_up = ALPHA_UP1; + alpha_down = ALPHA_DOWN1; + } + else + { + if ((st->stat_count == 0) + && (st->complex_hang_count == 0)) + { + alpha_up = ALPHA_UP2; + alpha_down = ALPHA_DOWN2; + } + else + { + alpha_up = 0; + alpha_down = ALPHA3; + bckr_add = 0; + } + } + + /* Update noise estimate (bckr_est) */ + for (i = 0; i < COMPLEN; i++) + { + Word16 temp; + + temp = sub(st->old_level[i], st->bckr_est[i], pOverflow); + + if (temp < 0) + { /* update downwards*/ + temp = mult_r(alpha_down, temp, pOverflow); + temp = add_16(st->bckr_est[i], temp, pOverflow); + + st->bckr_est[i] = add_16(-2, temp, pOverflow); + + /* limit minimum value of the noise estimate to NOISE_MIN */ + if (st->bckr_est[i] < NOISE_MIN) + { + st->bckr_est[i] = NOISE_MIN; + } + } + else + { /* update upwards */ + temp = mult_r(alpha_up, temp, pOverflow); + temp = add_16(st->bckr_est[i], temp, pOverflow); + st->bckr_est[i] = add_16(bckr_add, temp, pOverflow); + + /* limit maximum value of the noise estimate to NOISE_MAX */ + if (st->bckr_est[i] > NOISE_MAX) + { + st->bckr_est[i] = NOISE_MAX; + } + } + } + + /* Update signal levels of the previous frame (old_level) */ + for (i = 0; i < COMPLEN; i++) + { + st->old_level[i] = level[i]; + } +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: complex_estimate_adapt +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + low_power -- Word16 -- very low level flag of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Function : complex_estimate_adapt + Purpose : Update/adapt of complex signal estimate + Inputs : low_power: low signal power flag + Outputs : st->corr_hp_fast: long term complex signal estimate + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static void complex_estimate_adapt( + vadState1 *st, /* i/o : VAD state struct */ + Word16 low_power, /* i : very low level flag of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 alpha; /* Q15 */ + Word32 L_tmp; /* Q31 */ + + + /* adapt speed on own state */ + if (st->best_corr_hp < st->corr_hp_fast) /* decrease */ + { + if (st->corr_hp_fast < CVAD_THRESH_ADAPT_HIGH) + { /* low state */ + alpha = CVAD_ADAPT_FAST; + } + else + { /* high state */ + alpha = CVAD_ADAPT_REALLY_FAST; + } + } + else /* increase */ + { + if (st->corr_hp_fast < CVAD_THRESH_ADAPT_HIGH) + { + alpha = CVAD_ADAPT_FAST; + } + else + { + alpha = CVAD_ADAPT_SLOW; + } + } + + L_tmp = ((Word32)st->corr_hp_fast << 16); + L_tmp = L_msu(L_tmp, alpha, st->corr_hp_fast, pOverflow); + L_tmp = L_mac(L_tmp, alpha, st->best_corr_hp, pOverflow); + st->corr_hp_fast = pv_round(L_tmp, pOverflow); /* Q15 */ + + if (st->corr_hp_fast < CVAD_MIN_CORR) + { + st->corr_hp_fast = CVAD_MIN_CORR; + } + + if (low_power != 0) + { + st->corr_hp_fast = CVAD_MIN_CORR; + } +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: complex_vad +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + low_power -- Word16 -- flag power of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + + Returns: + the complex background decision + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : complex background decision + Return value : the complex background decision + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 complex_vad( + vadState1 *st, /* i/o : VAD state struct */ + Word16 low_power, /* i : flag power of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + st->complex_high = shr(st->complex_high, 1, pOverflow); + st->complex_low = shr(st->complex_low, 1, pOverflow); + + if (low_power == 0) + { + if (st->corr_hp_fast > CVAD_THRESH_ADAPT_HIGH) + { + st->complex_high |= 0x4000; + } + + if (st->corr_hp_fast > CVAD_THRESH_ADAPT_LOW) + { + st->complex_low |= 0x4000; + } + } + + if (st->corr_hp_fast > CVAD_THRESH_HANG) + { + st->complex_hang_timer = add_16(st->complex_hang_timer, 1, pOverflow); + } + else + { + st->complex_hang_timer = 0; + } + + return ((Word16)(st->complex_high & 0x7f80) == 0x7f80 || + (Word16)(st->complex_low & 0x7fff) == 0x7fff); +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad_decision +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + level -- array of type Word16 -- sub-band levels of the input frame + pow_sum -- Word32 -- power of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + VAD_flag (Word16) + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Calculates VAD_flag + Inputs : bckr_est: background noise estimate + vadreg: intermediate VAD flags + Outputs : noise_level: average level of the noise estimates + vadreg: intermediate VAD flags + Return value : VAD_flag + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +static Word16 vad_decision( + vadState1 *st, /* i/o : State struct */ + Word16 level[COMPLEN], /* i : sub-band levels of the input frame */ + Word32 pow_sum, /* i : power of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 i; + Word16 snr_sum; + Word32 L_temp; + Word16 vad_thr; + Word16 temp; + Word16 noise_level; + Word16 low_power_flag; + Word16 temp1; + + /* + Calculate squared sum of the input levels (level) + divided by the background noise components (bckr_est). + */ + L_temp = 0; + + for (i = 0; i < COMPLEN; i++) + { + Word16 exp; + + exp = norm_s(st->bckr_est[i]); + temp = shl(st->bckr_est[i], exp, pOverflow); + temp = div_s(shr(level[i], 1, pOverflow), temp); + temp = shl(temp, sub(exp, UNIRSHFT - 1, pOverflow), pOverflow); + L_temp = L_mac(L_temp, temp, temp, pOverflow); + } + + snr_sum = (Word16)(L_shl(L_temp, 6, pOverflow) >> 16); + snr_sum = mult(snr_sum, INV_COMPLEN, pOverflow); + + /* Calculate average level of estimated background noise */ + L_temp = 0; + for (i = 0; i < COMPLEN; i++) + { + L_temp = L_add(L_temp, st->bckr_est[i], pOverflow); + } + + noise_level = (Word16)(L_shl(L_temp, 13, pOverflow) >> 16); + + /* Calculate VAD threshold */ + temp1 = sub(noise_level, VAD_P1, pOverflow); + temp1 = mult(VAD_SLOPE, temp1, pOverflow); + vad_thr = add_16(temp1, VAD_THR_HIGH, pOverflow); + + if (vad_thr < VAD_THR_LOW) + { + vad_thr = VAD_THR_LOW; + } + + /* Shift VAD decision register */ + st->vadreg = shr(st->vadreg, 1, pOverflow); + + /* Make intermediate VAD decision */ + if (snr_sum > vad_thr) + { + st->vadreg |= 0x4000; + } + /* primary vad decsion made */ + + /* check if the input power (pow_sum) is lower than a threshold" */ + if (L_sub(pow_sum, VAD_POW_LOW, pOverflow) < 0) + { + low_power_flag = 1; + } + else + { + low_power_flag = 0; + } + + /* update complex signal estimate st->corr_hp_fast and hangover reset timer using */ + /* low_power_flag and corr_hp_fast and various adaptation speeds */ + complex_estimate_adapt(st, low_power_flag, pOverflow); + + /* check multiple thresholds of the st->corr_hp_fast value */ + st->complex_warning = complex_vad(st, low_power_flag, pOverflow); + + /* Update speech subband vad background noise estimates */ + noise_estimate_update(st, level, pOverflow); + + /* Add speech and complex hangover and return speech VAD_flag */ + /* long term complex hangover may be added */ + st->speech_vad_decision = hangover_addition(st, noise_level, low_power_flag, pOverflow); + + return (st->speech_vad_decision); +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad1_init +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state -- double pointer to type vadState1 -- pointer to memory to + be initialized. + + Outputs: + state -- points to initalized area in memory. + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Allocates state memory and initializes state memory + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 vad1_init(vadState1 **state) +{ + vadState1* s; + + if (state == (vadState1 **) NULL) + { + return -1; + } + *state = NULL; + + /* allocate memory */ + if ((s = (vadState1 *) oscl_malloc(sizeof(vadState1))) == NULL) + { + return -1; + } + + vad1_reset(s); + + *state = s; + + return 0; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad1_reset +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state -- pointer to type vadState1 -- State struct + + Outputs: + state -- pointer to type vadState1 -- State struct + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose: Resets state memory to zero + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 vad1_reset(vadState1 *state) +{ + Word16 i; + Word16 j; + + if (state == (vadState1 *) NULL) + { + return -1; + } + + /* Initialize pitch detection variables */ + state->oldlag_count = 0; + state->oldlag = 0; + state->pitch = 0; + state->tone = 0; + + state->complex_high = 0; + state->complex_low = 0; + state->complex_hang_timer = 0; + + state->vadreg = 0; + + state->stat_count = 0; + state->burst_count = 0; + state->hang_count = 0; + state->complex_hang_count = 0; + + /* initialize memory used by the filter bank */ + for (i = 0; i < 3; i++) + { + for (j = 0; j < 2; j++) + { + state->a_data5[i][j] = 0; + } + } + + for (i = 0; i < 5; i++) + { + state->a_data3[i] = 0; + } + + /* initialize the rest of the memory */ + for (i = 0; i < COMPLEN; i++) + { + state->bckr_est[i] = NOISE_INIT; + state->old_level[i] = NOISE_INIT; + state->ave_level[i] = NOISE_INIT; + state->sub_level[i] = 0; + } + + state->best_corr_hp = CVAD_LOWPOW_RESET; + + state->speech_vad_decision = 0; + state->complex_warning = 0; + state->sp_burst_count = 0; + + state->corr_hp_fast = CVAD_LOWPOW_RESET; + + return 0; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad1_exit +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + state -- pointer to type vadState1 -- State struct + + Outputs: + None + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + The memory used for state memory is freed + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void vad1_exit(vadState1 **state) +{ + if (state == NULL || *state == NULL) + return; + + /* deallocate memory */ + oscl_free(*state); + *state = NULL; + + return; +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad_complex_detection_update +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + best_corr_hp -- Word16 -- best Corr + state -- pointer to type vadState1 -- State struct + + Outputs: + state -- pointer to type vadState1 -- State struct + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : update vad->bestCorr_hp complex signal feature state +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void vad_complex_detection_update( + vadState1 *st, /* i/o : State struct */ + Word16 best_corr_hp) /* i : best Corr */ +{ + st->best_corr_hp = best_corr_hp; +} + + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad_tone_detection +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + t0 -- Word32 -- autocorrelation maxima + t1 -- Word32 -- energy + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Set tone flag if pitch gain is high. This is used to detect + signaling tones and other signals with high pitch gain. + Inputs : tone: flags indicating presence of a tone + Outputs : tone: flags indicating presence of a tone +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void vad_tone_detection( + vadState1 *st, /* i/o : State struct */ + Word32 t0, /* i : autocorrelation maxima */ + Word32 t1, /* i : energy */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 temp; + /* + if (t0 > TONE_THR * t1) + set tone flag + */ + temp = pv_round(t1, pOverflow); + + if ((temp > 0) && (L_msu(t0, temp, TONE_THR, pOverflow) > 0)) + { + st->tone |= 0x4000; + } +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad_tone_detection_update +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + one_lag_per_frame -- Word16 -- 1 if one open-loop lag is calculated per + each frame, otherwise 0 + st -- pointer to type vadState1 -- State struct + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Update the tone flag register. Tone flags are shifted right + by one bit. This function should be called from the speech + encoder before call to Vad_tone_detection() function. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void vad_tone_detection_update( + vadState1 *st, /* i/o : State struct */ + Word16 one_lag_per_frame, /* i : 1 if one open-loop lag */ + /* is calculated per each */ + /* frame, otherwise 0 */ + Flag *pOverflow /* o : Flags overflow */ +) +{ + /* Shift tone flags right by one bit */ + st->tone = shr(st->tone, 1, pOverflow); + + /* If open-loop lag is calculated only once in each frame, do extra update + and assume that the other tone flag of the frame is one. */ + if (one_lag_per_frame != 0) + { + st->tone = shr(st->tone, 1, pOverflow); + st->tone |= 0x2000; + } +} + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad_pitch_detection +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + T_op -- array of type Word16 -- speech encoder open loop lags + st -- pointer to type vadState1 -- State struct + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + None + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Test whether signal contains pitch or other periodic + component. + Return value : Boolean voiced / unvoiced decision in state variable + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +void vad_pitch_detection( + vadState1 *st, /* i/o : State struct */ + Word16 T_op[], /* i : speech encoder open loop lags */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 lagcount; + Word16 i; + Word16 temp; + + lagcount = 0; + + for (i = 0; i < 2; i++) + { + temp = sub(st->oldlag, T_op[i], pOverflow); + temp = abs_s(temp); + + if (temp < LTHRESH) + { + lagcount += 1; + } + + /* Save the current LTP lag */ + st->oldlag = T_op[i]; + } + + /* Make pitch decision. + Save flag of the pitch detection to the variable pitch. + */ + st->pitch = shr(st->pitch, 1, pOverflow); + + temp = + add_16( + st->oldlag_count, + lagcount, + pOverflow); + + if (temp >= NTHRESH) + { + st->pitch |= 0x4000; + } + + /* Update oldlagcount */ + st->oldlag_count = lagcount; +} + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: vad1 +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + st -- pointer to type vadState1 -- State struct + in_buf -- array of type Word16 -- samples of the input frame + + Outputs: + st -- pointer to type vadState1 -- State struct + pOverflow -- pointer to type Flag -- overflow indicator + + Returns: + VAD Decision, 1 = speech, 0 = noise + + Global Variables Used: + None + + Local Variables Needed: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Purpose : Main program for Voice Activity Detection (VAD) for AMR + Return value : VAD Decision, 1 = speech, 0 = noise + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + vad1.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + + +------------------------------------------------------------------------------ + CAUTION [optional] + [State any special notes, constraints or cautions for users of this function] + +------------------------------------------------------------------------------ +*/ + +Word16 vad1( + vadState1 *st, /* i/o : State struct */ + Word16 in_buf[], /* i : samples of the input frame */ + Flag *pOverflow /* o : Flag set when overflow occurs */ +) +{ + Word16 level[COMPLEN]; + Word32 pow_sum; + Word16 i; + + /* Calculate power of the input frame. */ + pow_sum = 0L; + + for (i = 0; i < FRAME_LEN; i++) + { + pow_sum = L_mac(pow_sum, in_buf[i-LOOKAHEAD], in_buf[i-LOOKAHEAD], pOverflow); + } + + /* + If input power is very low, clear pitch flag of the current frame + */ + if (L_sub(pow_sum, POW_PITCH_THR, pOverflow) < 0) + { + st->pitch = st->pitch & 0x3fff; + } + + /* + If input power is very low, clear complex flag of the "current" frame + */ + if (L_sub(pow_sum, POW_COMPLEX_THR, pOverflow) < 0) + { + st->complex_low = st->complex_low & 0x3fff; + } + + /* + Run the filter bank which calculates signal levels at each band + */ + filter_bank(st, in_buf, level, pOverflow); + + return (vad_decision(st, level, pow_sum, pOverflow)); +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/vad1.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/vad1.h new file mode 100644 index 00000000..ab3438fe --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/vad1.h @@ -0,0 +1,185 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: vad1.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions, prototype and structure + definitions needed by vad_1.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef vad_1_h +#define vad_1_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" +#include "cnst_vad.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + /* state variable */ + typedef struct + { + + Word16 bckr_est[COMPLEN]; /* background noise estimate */ + Word16 ave_level[COMPLEN]; /* averaged input components for stationary */ + /* estimation */ + Word16 old_level[COMPLEN]; /* input levels of the previous frame */ + Word16 sub_level[COMPLEN]; /* input levels calculated at the end of + a frame (lookahead) */ + Word16 a_data5[3][2]; /* memory for the filter bank */ + Word16 a_data3[5]; /* memory for the filter bank */ + + Word16 burst_count; /* counts length of a speech burst */ + Word16 hang_count; /* hangover counter */ + Word16 stat_count; /* stationary counter */ + + /* Note that each of the following three variables (vadreg, pitch and tone) + holds 15 flags. Each flag reserves 1 bit of the variable. The newest + flag is in the bit 15 (assuming that LSB is bit 1 and MSB is bit 16). */ + Word16 vadreg; /* flags for intermediate VAD decisions */ + Word16 pitch; /* flags for pitch detection */ + Word16 tone; /* flags for tone detection */ + Word16 complex_high; /* flags for complex detection */ + Word16 complex_low; /* flags for complex detection */ + + Word16 oldlag_count, oldlag; /* variables for pitch detection */ + + Word16 complex_hang_count; /* complex hangover counter, used by VAD */ + Word16 complex_hang_timer; /* hangover initiator, used by CAD */ + + Word16 best_corr_hp; /* FIP filtered value Q15 */ + + Word16 speech_vad_decision; /* final decision */ + Word16 complex_warning; /* complex background warning */ + + Word16 sp_burst_count; /* counts length of a speech burst incl */ + Word16 corr_hp_fast; /* filtered value */ + } vadState1; + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 vad1_init(vadState1 **st); + /* initialize one instance of the pre processing state. + Stores pointer to filter status struct in *st. This pointer has to + be passed to vad in each call. + returns 0 on success + */ + + Word16 vad1_reset(vadState1 *st); + /* reset of pre processing state (i.e. set state memory to zero) + returns 0 on success + */ + + void vad1_exit(vadState1 **st); + /* de-initialize pre processing state (i.e. free status struct) + stores NULL in *st + */ + + void vad_complex_detection_update(vadState1 *st, /* i/o : State struct */ + Word16 best_corr_hp /* i : best Corr Q15 */ + ); + + void vad_tone_detection(vadState1 *st, /* i/o : State struct */ + Word32 t0, /* i : autocorrelation maxima */ + Word32 t1, /* i : energy */ + Flag *pOverflow + ); + + void vad_tone_detection_update( + vadState1 *st, /* i/o : State struct */ + Word16 one_lag_per_frame, /* i : 1 if one open-loop lag is + calculated per each frame, + otherwise 0 */ + Flag *pOverflow + ); + + void vad_pitch_detection(vadState1 *st, /* i/o : State struct */ + Word16 lags[], /* i : speech encoder open loop lags */ + Flag *pOverflow + ); + + Word16 vad1(vadState1 *st, /* i/o : State struct */ + Word16 in_buf[], /* i : samples of the input frame + inbuf[159] is the very last sample, + incl lookahead */ + Flag *pOverflow + ); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _VAD1_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/vad2.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/vad2.h new file mode 100644 index 00000000..909801ff --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_nb/enc/src/vad2.h @@ -0,0 +1,186 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.073 + ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec + Available from http://www.3gpp.org + +(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + Filename: vad2.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file contains all the constant definitions, prototype and structure + definitions needed by vad_2.c + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef vad_2_h +#define vad_2_h "$Id $" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "typedef.h" + +/*--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + +#define YES 1 +#define NO 0 +#define ON 1 +#define OFF 0 +#define TRUE 1 +#define FALSE 0 + +#define FRM_LEN 80 +#define DELAY 24 +#define FFT_LEN 128 + +#define NUM_CHAN 16 +#define LO_CHAN 0 +#define HI_CHAN 15 + +#define UPDATE_THLD 35 +#define HYSTER_CNT_THLD 6 +#define UPDATE_CNT_THLD 50 + +#define SHIFT_STATE_0 0 /* channel energy scaled as 22,9 */ +#define SHIFT_STATE_1 1 /* channel energy scaled as 27,4 */ + +#define NOISE_FLOOR_CHAN_0 512 /* 1.0 scaled as 22,9 */ +#define MIN_CHAN_ENRG_0 32 /* 0.0625 scaled as 22,9 */ +#define MIN_NOISE_ENRG_0 32 /* 0.0625 scaled as 22,9 */ +#define INE_NOISE_0 8192 /* 16.0 scaled as 22,9 */ +#define FRACTIONAL_BITS_0 9 /* used as input to fn10Log10() */ + +#define NOISE_FLOOR_CHAN_1 16 /* 1.0 scaled as 27,4 */ +#define MIN_CHAN_ENRG_1 1 /* 0.0625 scaled as 27,4 */ +#define MIN_NOISE_ENRG_1 1 /* 0.0625 scaled as 27,4 */ +#define INE_NOISE_1 256 /* 16.0 scaled as 27,4 */ +#define FRACTIONAL_BITS_1 4 /* used as input to fn10Log10() */ + +#define STATE_1_TO_0_SHIFT_R (FRACTIONAL_BITS_1-FRACTIONAL_BITS_0) /* state correction factor */ +#define STATE_0_TO_1_SHIFT_R (FRACTIONAL_BITS_0-FRACTIONAL_BITS_1) /* state correction factor */ + +#define HIGH_ALPHA 29491 /* 0.9 scaled as 0,15 */ +#define LOW_ALPHA 22938 /* 0.7 scaled as 0,15 */ +#define ALPHA_RANGE (HIGH_ALPHA - LOW_ALPHA) +#define DEV_THLD 7168 /* 28.0 scaled as 7,8 */ + +#define PRE_EMP_FAC (-26214) /* -0.8 scaled as 0,15 */ + +#define CEE_SM_FAC 18022 /* 0.55 scaled as 0,15 */ +#define ONE_MINUS_CEE_SM_FAC 14746 /* 0.45 scaled as 0,15 */ + +#define CNE_SM_FAC 3277 /* 0.1 scaled as 0,15 */ +#define ONE_MINUS_CNE_SM_FAC 29491 /* 0.9 scaled as 0,15 */ + +#define FFT_HEADROOM 2 + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + typedef struct + { + Word16 pre_emp_mem; + Word16 update_cnt; + Word16 hyster_cnt; + Word16 last_update_cnt; + Word16 ch_enrg_long_db[NUM_CHAN]; /* scaled as 7,8 */ + + Word32 Lframe_cnt; + Word32 Lch_enrg[NUM_CHAN]; /* scaled as 22,9 or 27,4 */ + Word32 Lch_noise[NUM_CHAN]; /* scaled as 22,9 */ + + Word16 last_normb_shift; /* last block norm shift count */ + + Word16 tsnr; /* total signal-to-noise ratio in dB (scaled as 7,8) */ + Word16 hangover; + Word16 burstcount; + Word16 fupdate_flag; /* forced update flag from previous frame */ + Word16 negSNRvar; /* Negative SNR variance (scaled as 7,8) */ + Word16 negSNRbias; /* sensitivity bias from negative SNR variance (scaled as 15,0) */ + + Word16 shift_state; /* use 22,9 or 27,4 scaling for ch_enrg[] */ + + Word32 L_R0; + Word32 L_Rmax; + Flag LTP_flag; /* Use to indicate the the LTP gain is > LTP_THRESH */ + + } vadState2; + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + Word16 vad2(Word16 *farray_ptr, vadState2 *st, Flag *pOverflow); + Word16 vad2_init(vadState2 **st); + Word16 vad2_reset(vadState2 *st); + void vad2_exit(vadState2 **state); + + void r_fft(Word16 *farray_ptr, Flag *pOverflow); + + void LTP_flag_update(vadState2 *st, Word16 mode, Flag *pOverflow); + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* _VAD2_H_ */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/Android.mk b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/Android.mk new file mode 100644 index 00000000..21d9ddbe --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/Android.mk @@ -0,0 +1,67 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + src/agc2_amr_wb.cpp \ + src/band_pass_6k_7k.cpp \ + src/dec_acelp_2p_in_64.cpp \ + src/dec_acelp_4p_in_64.cpp \ + src/dec_alg_codebook.cpp \ + src/dec_gain2_amr_wb.cpp \ + src/decoder_amr_wb.cpp \ + src/deemphasis_32.cpp \ + src/dtx_decoder_amr_wb.cpp \ + src/get_amr_wb_bits.cpp \ + src/highpass_400hz_at_12k8.cpp \ + src/highpass_50hz_at_12k8.cpp \ + src/homing_amr_wb_dec.cpp \ + src/interpolate_isp.cpp \ + src/isf_extrapolation.cpp \ + src/isp_az.cpp \ + src/isp_isf.cpp \ + src/lagconceal.cpp \ + src/low_pass_filt_7k.cpp \ + src/median5.cpp \ + src/mime_io.cpp \ + src/noise_gen_amrwb.cpp \ + src/normalize_amr_wb.cpp \ + src/oversamp_12k8_to_16k.cpp \ + src/phase_dispersion.cpp \ + src/pit_shrp.cpp \ + src/pred_lt4.cpp \ + src/preemph_amrwb_dec.cpp \ + src/pvamrwb_math_op.cpp \ + src/pvamrwbdecoder.cpp \ + src/q_gain2_tab.cpp \ + src/qisf_ns.cpp \ + src/qisf_ns_tab.cpp \ + src/qpisf_2s.cpp \ + src/qpisf_2s_tab.cpp \ + src/scale_signal.cpp \ + src/synthesis_amr_wb.cpp \ + src/voice_factor.cpp \ + src/wb_syn_filt.cpp \ + src/weight_amrwb_lpc.cpp + + +LOCAL_MODULE := libpvamrwbdecoder + +LOCAL_CFLAGS := $(PV_CFLAGS) +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := + +LOCAL_SHARED_LIBRARIES := + +LOCAL_C_INCLUDES := \ + $(PV_TOP)/codecs_v2/audio/gsm_amr/amr_wb/dec/src \ + $(PV_TOP)/codecs_v2/audio/gsm_amr/amr_wb/dec/include \ + $(PV_INCLUDES) + +LOCAL_COPY_HEADERS_TO := $(PV_COPY_HEADERS_TO) + +LOCAL_COPY_HEADERS := \ + include/decoder_amr_wb.h \ + include/pvamrwbdecoder_api.h + +include $(BUILD_STATIC_LIBRARY) diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/build/make/local.mk b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/build/make/local.mk new file mode 100644 index 00000000..7b914eb7 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/build/make/local.mk @@ -0,0 +1,59 @@ +# Get the current local path as the first operation +LOCAL_PATH := $(call get_makefile_dir) + +# Clear out the variables used in the local makefiles +include $(MK)/clear.mk + +TARGET := pvamrwbdecoder + + +OPTIMIZE_FOR_PERFORMANCE_OVER_SIZE := true + +SRCDIR := ../../src +INCSRCDIR := ../../include +SRCS := agc2_amr_wb.cpp \ + band_pass_6k_7k.cpp \ + dec_acelp_2p_in_64.cpp \ + dec_acelp_4p_in_64.cpp \ + dec_alg_codebook.cpp \ + dec_gain2_amr_wb.cpp \ + decoder_amr_wb.cpp \ + deemphasis_32.cpp \ + dtx_decoder_amr_wb.cpp \ + get_amr_wb_bits.cpp \ + highpass_400hz_at_12k8.cpp \ + highpass_50hz_at_12k8.cpp \ + homing_amr_wb_dec.cpp \ + interpolate_isp.cpp \ + isf_extrapolation.cpp \ + isp_az.cpp \ + isp_isf.cpp \ + lagconceal.cpp \ + low_pass_filt_7k.cpp \ + median5.cpp \ + mime_io.cpp \ + noise_gen_amrwb.cpp \ + normalize_amr_wb.cpp \ + oversamp_12k8_to_16k.cpp \ + phase_dispersion.cpp \ + pit_shrp.cpp \ + pred_lt4.cpp \ + preemph_amrwb_dec.cpp \ + pvamrwb_math_op.cpp \ + pvamrwbdecoder.cpp \ + q_gain2_tab.cpp \ + qisf_ns.cpp \ + qisf_ns_tab.cpp \ + qpisf_2s.cpp \ + qpisf_2s_tab.cpp \ + scale_signal.cpp \ + synthesis_amr_wb.cpp \ + voice_factor.cpp \ + wb_syn_filt.cpp \ + weight_amrwb_lpc.cpp + + +HDRS := decoder_amr_wb.h pvamrwbdecoder_api.h + +include $(MK)/library.mk + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/include/decoder_amr_wb.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/include/decoder_amr_wb.h new file mode 100644 index 00000000..d026c17f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/include/decoder_amr_wb.h @@ -0,0 +1,75 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +////////////////////////////////////////////////////////////////////////////////// +// // +// File: decoder_amr_wb.h // +// // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef _DECODER_AMR_WB_H +#define _DECODER_AMR_WB_H + +#include "oscl_base.h" +#include "pvamrwbdecoder_api.h" +#include "pvgsmamrdecoderinterface.h" + +// CDecoder_AMR_WB +class CDecoder_AMRInterface; +class CDecoder_AMR_WB: public CDecoder_AMRInterface +{ + public: + OSCL_IMPORT_REF void ConstructL(); + OSCL_IMPORT_REF static CDecoder_AMR_WB *NewL(); + OSCL_IMPORT_REF virtual ~CDecoder_AMR_WB(); + + OSCL_IMPORT_REF virtual int32 StartL(tPVAmrDecoderExternal * pExt, + bool aAllocateInputBuffer = false, + bool aAllocateOutputBuffer = false); + + OSCL_IMPORT_REF virtual int32 ExecuteL(tPVAmrDecoderExternal * pExt); + + OSCL_IMPORT_REF virtual int32 ResetDecoderL(void); + OSCL_IMPORT_REF virtual void StopL(); + OSCL_IMPORT_REF virtual void TerminateDecoderL(); + + private: + void *st; /* State structure */ + void *pt_st; + int16 *ScratchMem; + + uint8* iInputBuf; + int16* iInputSampleBuf; + int16* iOutputBuf; + + +}; + + +#endif + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/include/pvamrwbdecoder_api.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/include/pvamrwbdecoder_api.h new file mode 100644 index 00000000..24fa429f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/include/pvamrwbdecoder_api.h @@ -0,0 +1,148 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Name: pvamrwbdecoder_api.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + Main header file for the Packet Video AMR Wide Band decoder library. The + constants, structures, and functions defined within this file, along with + a basic data types header file, is all that is needed to use and communicate + with the library. The internal data structures within the library are + purposely hidden. + + ---* Need description of the input buffering. *------- + + ---* Need an example of calling the library here *---- + +------------------------------------------------------------------------------ + REFERENCES + + (Normally header files do not have a reference section) + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef _PVAMRWBDECODER_API_H +#define _PVAMRWBDECODER_API_H + +#include "oscl_base.h" /* Basic data types used within the lib */ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + +#define AMR_WB_PCM_FRAME 320 /* Frame size at 16kHz */ + + +#define NBBITS_7k 132 /* 6.60k */ +#define NBBITS_9k 177 /* 8.85k */ +#define NBBITS_12k 253 /* 12.65k */ +#define NBBITS_14k 285 /* 14.25k */ +#define NBBITS_16k 317 /* 15.85k */ +#define NBBITS_18k 365 /* 18.25k */ +#define NBBITS_20k 397 /* 19.85k */ +#define NBBITS_23k 461 /* 23.05k */ +#define NBBITS_24k 477 /* 23.85k */ + +#define NBBITS_SID 35 + +#define KAMRWB_NB_BITS_MAX NBBITS_24k +#define KAMRWB_NB_BYTES_MAX ((KAMRWB_NB_BITS_MAX>>3)+1) + +#define NUM_OF_MODES 10 + + + static const int16 AMR_WB_COMPRESSED[NUM_OF_MODES] = + { + NBBITS_7k, + NBBITS_9k, + NBBITS_12k, + NBBITS_14k, + NBBITS_16k, + NBBITS_18k, + NBBITS_20k, + NBBITS_23k, + NBBITS_24k, + NBBITS_SID + }; + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + + +#endif /* PVMP4AUDIODECODER_API_H */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/agc2_amr_wb.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/agc2_amr_wb.cpp new file mode 100644 index 00000000..0b01ef03 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/agc2_amr_wb.cpp @@ -0,0 +1,182 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: agc2_amr_wb.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 * sig_in, (i) : postfilter input signal + int16 * sig_out, (i/o) : postfilter output signal + int16 l_trm (i) : subframe size + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Performs adaptive gain control + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwb_math_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void agc2_amr_wb( + int16 * sig_in, /* (i) : postfilter input signal */ + int16 * sig_out, /* (i/o) : postfilter output signal */ + int16 l_trm /* (i) : subframe size */ +) +{ + + int16 i, exp; + int16 gain_in, gain_out, g0; + int32 s; + + int16 temp; + + /* calculate gain_out with exponent */ + + temp = sig_out[0] >> 2; + s = fxp_mul_16by16(temp, temp) << 1; + for (i = 1; i < l_trm; i++) + { + temp = sig_out[i] >> 2; + s = mac_16by16_to_int32(s, temp, temp); + } + + + if (s == 0) + { + return; + } + exp = normalize_amr_wb(s) - 1; + gain_out = amr_wb_round(s << exp); + + /* calculate gain_in with exponent */ + + temp = sig_in[0] >> 2; + s = mul_16by16_to_int32(temp, temp); + for (i = 1; i < l_trm; i++) + { + temp = sig_in[i] >> 2; + s = mac_16by16_to_int32(s, temp, temp); + } + + + if (s == 0) + { + g0 = 0; + } + else + { + i = normalize_amr_wb(s); + gain_in = amr_wb_round(s << i); + exp -= i; + + /* + * g0 = sqrt(gain_in/gain_out) + */ + + s = div_16by16(gain_out, gain_in); + s = shl_int32(s, 7); /* s = gain_out / gain_in */ + s = shr_int32(s, exp); /* add exponent */ + + s = one_ov_sqrt(s); + g0 = amr_wb_round(shl_int32(s, 9)); + } + /* sig_out(n) = gain(n) sig_out(n) */ + + for (i = 0; i < l_trm; i++) + { + sig_out[i] = extract_h(shl_int32(fxp_mul_16by16(sig_out[i], g0), 3)); + + } + + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/band_pass_6k_7k.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/band_pass_6k_7k.cpp new file mode 100644 index 00000000..5d12eabf --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/band_pass_6k_7k.cpp @@ -0,0 +1,232 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: band_pass_6k_7k.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 signal[], input signal / output is divided by 16 + int16 lg, lenght of signal + int16 mem[] in/out: memory (size=30) + int16 x[] scratch mem ( size= 60) + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + 15th order band pass 6kHz to 7kHz FIR filter. + + frequency: 4kHz 5kHz 5.5kHz 6kHz 6.5kHz 7kHz 7.5kHz 8kHz + dB loss: -60dB -45dB -13dB -3dB 0dB -3dB -13dB -45dB + + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_acelp.h" +#include "pvamrwbdecoder_cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +#define L_FIR 30 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* filter coefficients (gain=4.0) */ + +const int16 fir_6k_7k[L_FIR] = +{ + -32, 47, 32, -27, + -369, 1122, -1421, 0, + 3798, -8880, 12349, -10984, + 3548, 7766, -18001, + 22118, + -18001, 7766, 3548, -10984, + 12349, -8880, 3798, 0, + -1421, 1122, -369, -27, + 32, 47 +}; + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void band_pass_6k_7k_init(int16 mem[]) /* mem[30] */ +{ + pv_memset((void *)mem, 0, L_FIR*sizeof(*mem)); +} + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +void band_pass_6k_7k( + int16 signal[], /* input: signal */ + int16 lg, /* input: length of input */ + int16 mem[], /* in/out: memory (size=30) */ + int16 x[] +) +{ + int16 i, j; + int32 L_tmp1; + int32 L_tmp2; + int32 L_tmp3; + int32 L_tmp4; + + int16 *pt_sign = signal; + + pv_memcpy((void *)x, (void *)mem, L_FIR*sizeof(*x)); + + + for (i = 0; i < lg >> 2; i++) + { + + x[(i<<2) + L_FIR ] = *(pt_sign) >> 2; /* gain of filter = 4 */ + x[(i<<2) + L_FIR + 1] = *(pt_sign + 1) >> 2; /* gain of filter = 4 */ + x[(i<<2) + L_FIR + 2] = *(pt_sign + 2) >> 2; /* gain of filter = 4 */ + x[(i<<2) + L_FIR + 3] = *(pt_sign + 3) >> 2; /* gain of filter = 4 */ + + L_tmp1 = 0x00004000; + L_tmp2 = 0x00004000; + L_tmp3 = 0x00004000; + L_tmp4 = 0x00004000; + + L_tmp1 -= ((int32)x[(i<<2)+L_FIR ] << 5); + L_tmp2 -= ((int32)x[(i<<2)+L_FIR+1] << 5); + L_tmp3 -= ((int32)x[(i<<2)+L_FIR+2] << 5); + L_tmp4 -= ((int32)x[(i<<2)+L_FIR+3] << 5); + + L_tmp1 -= ((int32)x[(i<<2)] << 5); + L_tmp2 -= ((int32)x[(i<<2)+1] << 5); + L_tmp3 -= ((int32)x[(i<<2)+2] << 5); + L_tmp4 -= ((int32)x[(i<<2)+3] << 5); + + + for (j = 1; j < L_FIR - 1; j += 4) + { + int16 tmp1 = x[(i<<2)+j ]; + int16 tmp2 = x[(i<<2)+j+1]; + int16 tmp3 = x[(i<<2)+j+2]; + + L_tmp1 = fxp_mac_16by16(tmp1, fir_6k_7k[j ], L_tmp1); + L_tmp2 = fxp_mac_16by16(tmp2, fir_6k_7k[j ], L_tmp2); + L_tmp1 = fxp_mac_16by16(tmp2, fir_6k_7k[j+1], L_tmp1); + L_tmp2 = fxp_mac_16by16(tmp3, fir_6k_7k[j+1], L_tmp2); + L_tmp3 = fxp_mac_16by16(tmp3, fir_6k_7k[j ], L_tmp3); + L_tmp1 = fxp_mac_16by16(tmp3, fir_6k_7k[j+2], L_tmp1); + + tmp1 = x[(i<<2)+j+3]; + tmp2 = x[(i<<2)+j+4]; + + L_tmp2 = fxp_mac_16by16(tmp1, fir_6k_7k[j+2], L_tmp2); + L_tmp4 = fxp_mac_16by16(tmp1, fir_6k_7k[j ], L_tmp4); + L_tmp3 = fxp_mac_16by16(tmp1, fir_6k_7k[j+1], L_tmp3); + L_tmp1 = fxp_mac_16by16(tmp1, fir_6k_7k[j+3], L_tmp1); + L_tmp2 = fxp_mac_16by16(tmp2, fir_6k_7k[j+3], L_tmp2); + L_tmp4 = fxp_mac_16by16(tmp2, fir_6k_7k[j+1], L_tmp4); + L_tmp3 = fxp_mac_16by16(tmp2, fir_6k_7k[j+2], L_tmp3); + + tmp1 = x[(i<<2)+j+5]; + tmp2 = x[(i<<2)+j+6]; + + L_tmp4 = fxp_mac_16by16(tmp1, fir_6k_7k[j+2], L_tmp4); + L_tmp3 = fxp_mac_16by16(tmp1, fir_6k_7k[j+3], L_tmp3); + L_tmp4 = fxp_mac_16by16(tmp2, fir_6k_7k[j+3], L_tmp4); + + } + + L_tmp1 = fxp_mac_16by16(x[(i<<2)+j ], fir_6k_7k[L_FIR-1 ], L_tmp1); + L_tmp2 = fxp_mac_16by16(x[(i<<2)+j+1], fir_6k_7k[L_FIR-1 ], L_tmp2); + L_tmp3 = fxp_mac_16by16(x[(i<<2)+j+2], fir_6k_7k[L_FIR-1 ], L_tmp3); + L_tmp4 = fxp_mac_16by16(x[(i<<2)+j+3], fir_6k_7k[L_FIR-1 ], L_tmp4); + + + *(pt_sign++) = (int16)(L_tmp1 >> 15); + *(pt_sign++) = (int16)(L_tmp2 >> 15); + *(pt_sign++) = (int16)(L_tmp3 >> 15); + *(pt_sign++) = (int16)(L_tmp4 >> 15); + + } + + pv_memcpy((void *)mem, (void *)(x + lg), L_FIR*sizeof(*mem)); + +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dec_acelp_2p_in_64.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dec_acelp_2p_in_64.cpp new file mode 100644 index 00000000..d0b4c48c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dec_acelp_2p_in_64.cpp @@ -0,0 +1,149 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dec_acelp_2p_in_64.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 index, (i): 12 bits index + int16 code[] (o): Q9 algebraic (fixed) codebook excitation + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + 12 bits algebraic codebook decoder. + 2 tracks x 32 positions per track = 64 samples. + + 12 bits --> 2 pulses in a frame of 64 samples. + + All pulses can have two (2) possible amplitudes: +1 or -1. + Each pulse can have 32 possible positions. + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define L_CODE 64 /* codevector length */ +#define NB_TRACK 2 /* number of track */ +#define NB_POS 32 /* number of position */ + + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void dec_acelp_2p_in_64( + int16 index, /* (i): 12 bits index */ + int16 code[] /* (o): Q9 algebraic (fixed) codebook excitation */ +) +{ + int16 i; + + pv_memset(code, 0, L_CODE*sizeof(*code)); + + /* decode the positions and signs of pulses and build the codeword */ + + i = (index >> 5) & 0x003E; + + if (((index >> 6) & NB_POS) == 0) + { + code[i] = 512; + } + else + { + code[i] = -512; + } + + i = ((index & 0x001F) << 1) + 1; + + if ((index & NB_POS) == 0) + { + code[i] = 512; + } + else + { + code[i] = -512; + } + +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dec_acelp_4p_in_64.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dec_acelp_4p_in_64.cpp new file mode 100644 index 00000000..d02021a9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dec_acelp_4p_in_64.cpp @@ -0,0 +1,257 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dec_acelp_4p_in_64.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 index[], (i) : index (20): 5+5+5+5 = 20 bits. + (i) : index (36): 9+9+9+9 = 36 bits. + (i) : index (44): 13+9+13+9 = 44 bits. + (i) : index (52): 13+13+13+13 = 52 bits. + (i) : index (64): 2+2+2+2+14+14+14+14 = 64 bits. + (i) : index (72): 10+2+10+2+10+14+10+14 = 72 bits. + (i) : index (88): 11+11+11+11+11+11+11+11 = 88 bits. + int16 nbbits, (i) : 20, 36, 44, 52, 64, 72 or 88 bits + int16 code[] (o) Q9: algebraic (fixed) codebook excitation + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + 20, 36, 44, 52, 64, 72, 88 bits algebraic codebook decoder. + 4 tracks x 16 positions per track = 64 samples. + + 20 bits --> 4 pulses in a frame of 64 samples. + 36 bits --> 8 pulses in a frame of 64 samples. + 44 bits --> 10 pulses in a frame of 64 samples. + 52 bits --> 12 pulses in a frame of 64 samples. + 64 bits --> 16 pulses in a frame of 64 samples. + 72 bits --> 18 pulses in a frame of 64 samples. + 88 bits --> 24 pulses in a frame of 64 samples. + + All pulses can have two (2) possible amplitudes: +1 or -1. + Each pulse can have sixteen (16) possible positions. + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" + +#include "q_pulse.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define L_CODE 64 /* codevector length */ +#define NB_TRACK 4 /* number of track */ +#define NB_POS 16 /* number of position */ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + void add_pulses(int16 pos[], int16 nb_pulse, int16 track, int16 code[]); + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void dec_acelp_4p_in_64( + int16 index[], /* (i) : index (20): 5+5+5+5 = 20 bits. */ + /* (i) : index (36): 9+9+9+9 = 36 bits. */ + /* (i) : index (44): 13+9+13+9 = 44 bits. */ + /* (i) : index (52): 13+13+13+13 = 52 bits. */ + /* (i) : index (64): 2+2+2+2+14+14+14+14 = 64 bits. */ + /* (i) : index (72): 10+2+10+2+10+14+10+14 = 72 bits. */ + /* (i) : index (88): 11+11+11+11+11+11+11+11 = 88 bits. */ + int16 nbbits, /* (i) : 20, 36, 44, 52, 64, 72 or 88 bits */ + int16 code[] /* (o) Q9: algebraic (fixed) codebook excitation */ +) +{ + int16 k, pos[6]; + int32 L_index; + pv_memset(code, 0, L_CODE*sizeof(*code)); + + /* decode the positions and signs of pulses and build the codeword */ + + + switch (nbbits) + { + case 20: + for (k = 0; k < NB_TRACK; k++) + { + L_index = index[k]; + dec_1p_N1(L_index, 4, 0, pos); + add_pulses(pos, 1, k, code); + } + break; + + case 36: + for (k = 0; k < NB_TRACK; k++) + { + L_index = index[k]; + dec_2p_2N1(L_index, 4, 0, pos); + add_pulses(pos, 2, k, code); + } + break; + case 44: + for (k = 0; k < NB_TRACK - 2; k++) + { + L_index = index[k]; + dec_3p_3N1(L_index, 4, 0, pos); + add_pulses(pos, 3, k, code); + } + for (k = 2; k < NB_TRACK; k++) + { + L_index = index[k]; + dec_2p_2N1(L_index, 4, 0, pos); + add_pulses(pos, 2, k, code); + } + break; + case 52: + for (k = 0; k < NB_TRACK; k++) + { + L_index = index[k]; + dec_3p_3N1(L_index, 4, 0, pos); + add_pulses(pos, 3, k, code); + } + break; + case 64: + for (k = 0; k < NB_TRACK; k++) + { + L_index = ((int32)index[k] << 14) + index[k + NB_TRACK]; + dec_4p_4N(L_index, 4, 0, pos); + add_pulses(pos, 4, k, code); + } + break; + case 72: + for (k = 0; k < NB_TRACK - 2; k++) + { + L_index = ((int32)index[k] << 10) + index[k + NB_TRACK]; + dec_5p_5N(L_index, 4, 0, pos); + add_pulses(pos, 5, k, code); + } + for (k = 2; k < NB_TRACK; k++) + { + L_index = ((int32)index[k] << 14) + index[k + NB_TRACK]; + dec_4p_4N(L_index, 4, 0, pos); + add_pulses(pos, 4, k, code); + } + break; + case 88: + for (k = 0; k < NB_TRACK; k++) + { + L_index = ((int32)index[k] << 11) + index[k + NB_TRACK]; + dec_6p_6N_2(L_index, 4, 0, pos); + add_pulses(pos, 6, k, code); + } + default: + break; + } + + +} + + + +void add_pulses(int16 pos[], int16 nb_pulse, int16 track, int16 code[]) +{ + int16 i, k; + + for (k = 0; k < nb_pulse; k++) + { + /* i = ((pos[k] & (NB_POS-1))*NB_TRACK) + track; */ + i = ((pos[k] & (NB_POS - 1)) << 2) + track; + + if ((pos[k] & NB_POS) == 0) + { + code[i] += 512; + } + else + { + code[i] -= 512; + } + } + +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dec_alg_codebook.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dec_alg_codebook.cpp new file mode 100644 index 00000000..76ad69c2 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dec_alg_codebook.cpp @@ -0,0 +1,384 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dec_alg_codebook.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + decoding of algebraic codebook + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "q_pulse.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +#define NB_POS 16 /* pos in track, mask for sign bit */ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +void dec_1p_N1(int32 index, int16 N, int16 offset, int16 pos[]) +{ + int16 pos1; + int32 mask, i; + + mask = ((1 << N) - 1); + /*-------------------------------------------------------* + * Decode 1 pulse with N+1 bits: * + *-------------------------------------------------------*/ + pos1 = ((index & mask) + offset); + + i = ((index >> N) & 1L); /* i = ((index >> N) & 1); */ + + if (i == 1) + { + pos1 += NB_POS; + } + pos[0] = pos1; + +} + + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void dec_2p_2N1(int32 index, int16 N, int16 offset, int16 pos[]) +{ + int16 pos1, pos2, tmp; + int32 mask, i; + + mask = (int32)(sub_int16(shl_int16(1, N), 1)); /* mask = ((1<> N) & mask) + offset); */ + pos1 = (int16)(add_int32((shr_int32(index, N) & mask), (int32)(offset))); + tmp = shl_int16(N, 1); + i = (index >> tmp) & 1L; /* i = (index >> (2*N)) & 1; */ + pos2 = add_int16((int16)(index & mask), offset); /* pos2 = ((index & mask) + offset); */ + + if (pos2 < pos1) /* ((pos2 - pos1) < 0) */ + { + if (i == 1) + { /* (i == 1) */ + pos1 += NB_POS; /* pos1 += NB_POS; */ + } + else + { + pos2 += NB_POS; /* pos2 += NB_POS; */ + } + } + else + { + if (i == 1) + { /* (i == 1) */ + pos1 += NB_POS; /* pos1 += NB_POS; */ + pos2 += NB_POS; /* pos2 += NB_POS; */ + } + } + + pos[0] = pos1; + pos[1] = pos2; + + return; +} + + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void dec_3p_3N1(int32 index, int16 N, int16 offset, int16 pos[]) +{ + int16 j, tmp; + int32 mask, idx; + + /*-------------------------------------------------------* + * Decode 3 pulses with 3*N+1 bits: * + *-------------------------------------------------------*/ + tmp = sub_int16(shl_int16(N, 1), 1); /* mask = ((1<<((2*N)-1))-1); */ + + mask = ((1 << ((2 * N) - 1)) - 1); + + idx = index & mask; + j = offset; + tmp = (N << 1) - 1; + + + if (((index >> tmp) & 1L) != 0L) + { /* if (((index >> ((2*N)-1)) & 1) == 1){ */ + j += (1 << (N - 1)); /* j += (1<<(N-1)); */ + } + dec_2p_2N1(idx, (int16)(N - 1), j, pos); + + mask = ((1 << (N + 1)) - 1); + tmp = N << 1; /* idx = (index >> (2*N)) & mask; */ + idx = (index >> tmp) & mask; + + dec_1p_N1(idx, N, offset, pos + 2); + + return; +} + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void dec_4p_4N1(int32 index, int16 N, int16 offset, int16 pos[]) +{ + int16 j, tmp; + int32 mask, idx; + + /*-------------------------------------------------------* + * Decode 4 pulses with 4*N+1 bits: * + *-------------------------------------------------------*/ + tmp = (N << 1) - 1; + mask = (1L << tmp) - 1L; + idx = index & mask; + j = offset; + tmp = (N << 1) - 1; + + + if (((index >> tmp) & 1L) != 0L) + { /* (((index >> ((2*N)-1)) & 1) == 1) */ + j += (1 << (N - 1)); /* j += (1<<(N-1)); */ + } + dec_2p_2N1(idx, (int16)(N - 1), j, pos); + + + tmp = (N << 1) + 1; /* mask = ((1<<((2*N)+1))-1); */ + mask = (1L << tmp) - 1L; + idx = (index >> (N << 1)) & mask; /* idx = (index >> (2*N)) & mask; */ + dec_2p_2N1(idx, N, offset, pos + 2); /* dec_2p_2N1(idx, N, offset, pos+2); */ + + return; +} + + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void dec_4p_4N(int32 index, int16 N, int16 offset, int16 pos[]) +{ + int16 j, n_1, tmp; + + /*-------------------------------------------------------* + * Decode 4 pulses with 4*N bits: * + *-------------------------------------------------------*/ + + n_1 = N - 1; + j = offset + (1 << n_1); /* j = offset + (1 << n_1); */ + + tmp = (N << 2) - 2; + + switch ((index >> tmp) & 3) + { /* ((index >> ((4*N)-2)) & 3) */ + case 0: + tmp = (n_1 << 2) + 1; + + if ((index >> tmp) & 1) + { /* (((index >> ((4*n_1)+1)) & 1) == 0) */ + dec_4p_4N1(index, n_1, j, pos); + } + else + { + dec_4p_4N1(index, n_1, offset, pos); + } + break; + case 1: + tmp = (3 * n_1) + 1; /* dec_1p_N1((index>>((3*n_1)+1)), n_1, offset, pos) */ + dec_1p_N1(index >> tmp, n_1, offset, pos); + dec_3p_3N1(index, n_1, j, pos + 1); + break; + case 2: + tmp = (n_1 << 1) + 1; /* dec_2p_2N1((index>>((2*n_1)+1)), n_1, offset, pos); */ + dec_2p_2N1(index >> tmp, n_1, offset, pos); + dec_2p_2N1(index, n_1, j, pos + 2); + break; + case 3: + tmp = n_1 + 1; /* dec_3p_3N1((index>>(n_1+1)), n_1, offset, pos); */ + dec_3p_3N1(index >> tmp, n_1, offset, pos); + dec_1p_N1(index, n_1, j, pos + 3); + break; + } + return; +} + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void dec_5p_5N(int32 index, int16 N, int16 offset, int16 pos[]) +{ + int16 j, n_1, tmp; + int32 idx; + + /*-------------------------------------------------------* + * Decode 5 pulses with 5*N bits: * + *-------------------------------------------------------*/ + + n_1 = (int16)(N - 1); + j = add_int16(offset, shl_int16(1, n_1)); /* j = offset + (1 << n_1); */ + tmp = (N << 1) + 1; /* idx = (index >> ((2*N)+1)); */ + idx = index >> tmp; + tmp = (5 * N) - 1; /* ((5*N)-1)) */ + + + if ((index >> tmp) & 1) /* ((index >> ((5*N)-1)) & 1) */ + { + dec_3p_3N1(idx, n_1, j, pos); + dec_2p_2N1(index, N, offset, pos + 3); + } + else + { + dec_3p_3N1(idx, n_1, offset, pos); + dec_2p_2N1(index, N, offset, pos + 3); + } + return; +} + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void dec_6p_6N_2(int32 index, int16 N, int16 offset, int16 pos[]) +{ + int16 j, n_1, offsetA, offsetB; + + n_1 = N - 1; + j = offset + (1 << n_1); /* j = offset + (1 << n_1); */ + + + /* !! N and n_1 are constants -> it doesn't need to be operated by Basic Operators */ + + offsetA = offsetB = j; + + if (((index >> (6*N - 5)) & 1L) == 0) + { /* if (((index >> ((6*N)-5)) & 1) == 0) */ + offsetA = offset; + } + else + { + offsetB = offset; + } + + + switch ((index >> (6*N - 4)) & 3) + { /* (index >> ((6*N)-4)) & 3 */ + case 0: + dec_5p_5N(index >> N, n_1, offsetA, pos); /* dec_5p_5N(index>>N, n_1, offsetA, pos); */ + dec_1p_N1(index, n_1, offsetA, pos + 5); + break; + case 1: + dec_5p_5N(index >> N, n_1, offsetA, pos); /* dec_5p_5N(index>>N, n_1, offsetA, pos); */ + dec_1p_N1(index, n_1, offsetB, pos + 5); + break; + case 2: + dec_4p_4N(index >> (2*n_1 + 1), n_1, offsetA, pos); /* dec_4p_4N(index>>((2*n_1)+1 ), n_1, offsetA, pos); */ + dec_2p_2N1(index, n_1, offsetB, pos + 4); + break; + case 3: + dec_3p_3N1(index >> (3*n_1 + 1), n_1, offset, pos); /* dec_3p_3N1(index>>((3*n_1)+ 1), n_1, offset, pos); */ + dec_3p_3N1(index, n_1, j, pos + 3); + break; + } + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dec_gain2_amr_wb.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dec_gain2_amr_wb.cpp new file mode 100644 index 00000000..927f7cab --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dec_gain2_amr_wb.cpp @@ -0,0 +1,396 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dec_gain2_amr_wb.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 index, (i) : index of quantization. + int16 nbits, (i) : number of bits (6 or 7) + int16 code[], (i) Q9 : Innovative vector. + int16 L_subfr, (i) : Subframe lenght. + int16 * gain_pit, (o) Q14 : Pitch gain. + int32 * gain_cod, (o) Q16 : Code gain. + int16 bfi, (i) : bad frame indicator + int16 prev_bfi, (i) : Previous BF indicator + int16 state, (i) : State of BFH + int16 unusable_frame, (i) : UF indicator + int16 vad_hist, (i) : number of non-speech frames + int16 * mem (i/o) : static memory (4 words) + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Decode the pitch and codebook gains + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwb_math_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" + +#include "qisf_ns.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +#define MEAN_ENER 30 +#define PRED_ORDER 4 + +#define L_LTPHIST 5 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +const int16 pdown_unusable[7] = {32767, 31130, 29491, 24576, 7537, 1638, 328}; +const int16 cdown_unusable[7] = {32767, 16384, 8192, 8192, 8192, 4915, 3277}; + +const int16 pdown_usable[7] = {32767, 32113, 31457, 24576, 7537, 1638, 328}; +const int16 cdown_usable[7] = {32767, 32113, 32113, 32113, 32113, 32113, 22938}; + + +/* MA prediction coeff ={0.5, 0.4, 0.3, 0.2} in Q13 */ +const int16 pred[PRED_ORDER] = {4096, 3277, 2458, 1638}; + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +/* output :static memory (4 words) */ +void dec_gain2_amr_wb_init(int16 * mem) +{ + + /* 4nd order quantizer energy predictor (init to -14.0 in Q10) */ + mem[0] = -14336; /* past_qua_en[0] */ + mem[1] = -14336; /* past_qua_en[1] */ + mem[2] = -14336; /* past_qua_en[2] */ + mem[3] = -14336; /* past_qua_en[3] */ + /* 4 *past_gain_pit */ + /* 5 *past_gain_code */ + /* 6 *prev_gc */ + /* next 5 pbuf[] */ + /* next 5 gbuf[] */ + /* next 5 pbuf2[] */ + pv_memset((void *)&mem[4], 0, 18*sizeof(*mem)); + + mem[22] = 21845; + +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void dec_gain2_amr_wb( + int16 index, /* (i) : index of quantization. */ + int16 nbits, /* (i) : number of bits (6 or 7) */ + int16 code[], /* (i) Q9 : Innovative vector. */ + int16 L_subfr, /* (i) : Subframe lenght. */ + int16 * gain_pit, /* (o) Q14 : Pitch gain. */ + int32 * gain_cod, /* (o) Q16 : Code gain. */ + int16 bfi, /* (i) : bad frame indicator */ + int16 prev_bfi, /* (i) : Previous BF indicator */ + int16 state, /* (i) : State of BFH */ + int16 unusable_frame, /* (i) : UF indicator */ + int16 vad_hist, /* (i) : number of non-speech frames */ + int16 * mem /* (i/o) : static memory (4 words) */ +) +{ + const int16 *p; + int16 *past_gain_pit, *past_gain_code, *past_qua_en, *gbuf, *pbuf, *prev_gc; + int16 *pbuf2; + int16 i, tmp, exp, frac, gcode0, exp_gcode0, qua_ener, gcode_inov; + int16 tmp1, g_code; + int16 tmp2; + int32 L_tmp; + + past_qua_en = mem; + past_gain_pit = mem + 4; + past_gain_code = mem + 5; + prev_gc = mem + 6; + pbuf = mem + 7; + gbuf = mem + 12; + pbuf2 = mem + 17; + + /* + * Find energy of code and compute: + * + * L_tmp = 1.0 / sqrt(energy of code/ L_subfr) + */ + + L_tmp = Dot_product12(code, code, L_subfr, &exp); + exp -= 24; /* exp: -18 (code in Q9), -6 (/L_subfr) */ + + one_ov_sqrt_norm(&L_tmp, &exp); + + gcode_inov = extract_h(shl_int32(L_tmp, exp - 3)); /* g_code_inov in Q12 */ + + /* + * Case of erasure. + */ + + if (bfi != 0) + { + tmp = median5(&pbuf[2]); + *past_gain_pit = tmp; + + if (*past_gain_pit > 15565) + { + *past_gain_pit = 15565; /* 0.95 in Q14 */ + + } + + if (unusable_frame != 0) + { + *gain_pit = mult_int16(pdown_unusable[state], *past_gain_pit); + } + else + { + *gain_pit = mult_int16(pdown_usable[state], *past_gain_pit); + } + tmp = median5(&gbuf[2]); + + if (vad_hist > 2) + { + *past_gain_code = tmp; + } + else + { + + if (unusable_frame != 0) + { + *past_gain_code = mult_int16(cdown_unusable[state], tmp); + } + else + { + *past_gain_code = mult_int16(cdown_usable[state], tmp); + } + } + + /* update table of past quantized energies */ + + tmp = past_qua_en[3]; + tmp1 = past_qua_en[2]; + L_tmp = tmp; + L_tmp += tmp1; + past_qua_en[3] = tmp; + tmp = past_qua_en[1]; + tmp1 = past_qua_en[0]; + L_tmp += tmp; + L_tmp += tmp1; + past_qua_en[2] = tmp; + qua_ener = (int16)(L_tmp >> 3); + past_qua_en[1] = tmp1; + + + qua_ener -= 3072; /* -3 in Q10 */ + + if (qua_ener < -14336) + { + qua_ener = -14336; /* -14 in Q10 */ + } + + past_qua_en[0] = qua_ener; + + + for (i = 1; i < 5; i++) + { + gbuf[i - 1] = gbuf[i]; + pbuf[i - 1] = pbuf[i]; + } + gbuf[4] = *past_gain_code; + pbuf[4] = *past_gain_pit; + + + /* adjust gain according to energy of code */ + /* past_gain_code(Q3) * gcode_inov(Q12) => Q16 */ + *gain_cod = mul_16by16_to_int32(*past_gain_code, gcode_inov); + + return; + } + /* + * Compute gcode0 + * = Sum(i=0,1) pred[i]*past_qua_en[i] + mean_ener - ener_code + */ + + L_tmp = L_deposit_h(MEAN_ENER); /* MEAN_ENER in Q16 */ + L_tmp = shl_int32(L_tmp, 8); /* From Q16 to Q24 */ + L_tmp = mac_16by16_to_int32(L_tmp, pred[0], past_qua_en[0]); /* Q13*Q10 -> Q24 */ + L_tmp = mac_16by16_to_int32(L_tmp, pred[1], past_qua_en[1]); /* Q13*Q10 -> Q24 */ + L_tmp = mac_16by16_to_int32(L_tmp, pred[2], past_qua_en[2]); /* Q13*Q10 -> Q24 */ + L_tmp = mac_16by16_to_int32(L_tmp, pred[3], past_qua_en[3]); /* Q13*Q10 -> Q24 */ + + gcode0 = extract_h(L_tmp); /* From Q24 to Q8 */ + + /* + * gcode0 = pow(10.0, gcode0/20) + * = pow(2, 3.321928*gcode0/20) + * = pow(2, 0.166096*gcode0) + */ + + L_tmp = ((int32)gcode0 * 5443) >> 7; /* *0.166096 in Q15 -> Q24 */ + + int32_to_dpf(L_tmp, &exp_gcode0, &frac); /* Extract exponant of gcode0 */ + + gcode0 = (int16)(power_of_2(14, frac)); /* Put 14 as exponant so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 -= 14; + + /* Read the quantized gains */ + + if (nbits == 6) + { + p = &t_qua_gain6b[index<<1]; + } + else + { + p = &t_qua_gain7b[index<<1]; + } + *gain_pit = *p++; /* selected pitch gain in Q14 */ + g_code = *p++; /* selected code gain in Q11 */ + + L_tmp = mul_16by16_to_int32(g_code, gcode0); /* Q11*Q0 -> Q12 */ + L_tmp = shl_int32(L_tmp, exp_gcode0 + 4); /* Q12 -> Q16 */ + + *gain_cod = L_tmp; /* gain of code in Q16 */ + + if (prev_bfi == 1) + { + L_tmp = mul_16by16_to_int32(*prev_gc, 5120); /* prev_gc(Q3) * 1.25(Q12) = Q16 */ + /* if((*gain_cod > ((*prev_gc) * 1.25)) && (*gain_cod > 100.0)) */ + + if ((*gain_cod > L_tmp) && (*gain_cod > 6553600)) + { + *gain_cod = L_tmp; + } + } + /* keep past gain code in Q3 for frame erasure (can saturate) */ + *past_gain_code = amr_wb_round(shl_int32(*gain_cod, 3)); + *past_gain_pit = *gain_pit; + + + *prev_gc = *past_gain_code; + tmp = gbuf[1]; + tmp1 = pbuf[1]; + tmp2 = pbuf2[1]; + for (i = 1; i < 5; i++) + { + gbuf[i - 1] = tmp; + pbuf[i - 1] = tmp1; + pbuf2[i - 1] = tmp2; + tmp = gbuf[i]; + tmp1 = pbuf[i]; + tmp2 = pbuf2[i]; + } + gbuf[4] = *past_gain_code; + pbuf[4] = *past_gain_pit; + pbuf2[4] = *past_gain_pit; + + + /* adjust gain according to energy of code */ + int32_to_dpf(*gain_cod, &exp, &frac); + L_tmp = mul_32by16(exp, frac, gcode_inov); + + *gain_cod = shl_int32(L_tmp, 3); /* gcode_inov in Q12 */ + + + past_qua_en[3] = past_qua_en[2]; + past_qua_en[2] = past_qua_en[1]; + past_qua_en[1] = past_qua_en[0]; + + /* + * qua_ener = 20*log10(g_code) + * = 6.0206*log2(g_code) + * = 6.0206*(log2(g_codeQ11) - 11) + */ + L_tmp = (int32)g_code; + amrwb_log_2(L_tmp, &exp, &frac); + exp -= 11; + L_tmp = mul_32by16(exp, frac, 24660); /* x 6.0206 in Q12 */ + + /* update table of past quantized energies */ + + past_qua_en[0] = (int16)(L_tmp >> 3); /* result in Q10 */ + + return; +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/decoder_amr_wb.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/decoder_amr_wb.cpp new file mode 100644 index 00000000..494b3643 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/decoder_amr_wb.cpp @@ -0,0 +1,384 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +////////////////////////////////////////////////////////////////////////////////// +// // +// File: decoder_amr_wb.cpp // +// // +////////////////////////////////////////////////////////////////////////////////// + +#include "decoder_amr_wb.h" +#include "pvamrwbdecoder_api.h" +#include "pvamrwbdecoder.h" +#include "pvamrwbdecoder_cnst.h" +#include "dtx.h" + + +// Use default DLL entry point +#include "oscl_dll.h" +#include "oscl_error.h" +#include "oscl_error_codes.h" +#include "oscl_exception.h" +#include "oscl_mem.h" + + +#define KCAI_CODEC_INIT_FAILURE -1 + + +OSCL_DLL_ENTRY_POINT_DEFAULT() + +OSCL_EXPORT_REF CDecoder_AMR_WB *CDecoder_AMR_WB::NewL() +{ + CDecoder_AMR_WB *dec = new CDecoder_AMR_WB; + if (dec == NULL) + OSCL_LEAVE(OsclErrNoMemory); + else + dec->ConstructL(); + return dec; +} + +OSCL_EXPORT_REF void CDecoder_AMR_WB::ConstructL() +{ + st = NULL; + pt_st = NULL; + ScratchMem = NULL; + iInputBuf = NULL; + iOutputBuf = NULL; +} + + +/* +----------------------------------------------------------------------------- + + CDecoder_AMR_WB + + ~CDecoder_AMR_WB + + Empty decoder destructor. + + Parameters: none + + Return Values: none + +----------------------------------------------------------------------------- +*/ +OSCL_EXPORT_REF CDecoder_AMR_WB::~CDecoder_AMR_WB() +{ + st = NULL; + ScratchMem = NULL; + + if (pt_st != NULL) + { + OSCL_ARRAY_DELETE((uint8*)pt_st); + pt_st = NULL; + } + + if (iInputBuf) + { + OSCL_ARRAY_DELETE(iInputBuf); + iInputBuf = NULL; + } + + if (iOutputBuf) + { + OSCL_ARRAY_DELETE(iOutputBuf); + iOutputBuf = NULL; + } +} + + +/* +----------------------------------------------------------------------------- + + CDecoder_AMR_WB + + StartL + + Start decoder object. Initialize codec status. + + Parameters: none + + Return Values: status + +----------------------------------------------------------------------------- +*/ +OSCL_EXPORT_REF int32 CDecoder_AMR_WB::StartL(tPVAmrDecoderExternal * pExt, + bool aAllocateInputBuffer, + bool aAllocateOutputBuffer) +{ + + /* + * Allocate Input bitstream buffer + */ + if (aAllocateInputBuffer) + { + iInputBuf = OSCL_ARRAY_NEW(uint8, KAMRWB_NB_BYTES_MAX); + if (iInputBuf == NULL) + { + return KCAI_CODEC_INIT_FAILURE; + } + } + else + { + iInputBuf = NULL; + } + pExt->pInputBuffer = iInputBuf; + + iInputSampleBuf = OSCL_ARRAY_NEW(int16, KAMRWB_NB_BITS_MAX); + if (iInputSampleBuf == NULL) + { + return KCAI_CODEC_INIT_FAILURE; + } + pExt->pInputSampleBuffer = iInputSampleBuf; + + /* + * Allocate Output PCM buffer + */ + if (aAllocateOutputBuffer) + { + iOutputBuf = OSCL_ARRAY_NEW(int16, AMR_WB_PCM_FRAME); + + if (iOutputBuf == NULL) + { + return KCAI_CODEC_INIT_FAILURE; + } + } + else + { + iOutputBuf = NULL; + } + pExt->pOutputBuffer = iOutputBuf; + + pExt->samplingRate = 16000; + pExt->desiredChannels = 1; + + pExt->reset_flag = 0; + pExt->reset_flag_old = 1; + pExt->mode_old = 0; + pExt->rx_state.prev_ft = RX_SPEECH_GOOD; + pExt->rx_state.prev_mode = 0; + + + int32 memreq = pvDecoder_AmrWbMemRequirements(); + + pt_st = OSCL_ARRAY_NEW(uint8, memreq); + + if (pt_st == 0) + { + return(KCAI_CODEC_INIT_FAILURE); + } + + pvDecoder_AmrWb_Init(&st, pt_st, &ScratchMem); + + return 0; +} + + +/* +----------------------------------------------------------------------------- + + CDecoder_AMR_WB + + ExecuteL + + Execute decoder object. Read one encoded speech frame from the input + stream, decode it and write the decoded frame to output stream. + + Parameters: + + Return Values: status + + +----------------------------------------------------------------------------- +*/ + + +OSCL_EXPORT_REF int32 CDecoder_AMR_WB::ExecuteL(tPVAmrDecoderExternal * pExt) +{ + + if (pExt->input_format == MIME_IETF) /* MIME/storage file format */ + { + mime_unsorting(pExt->pInputBuffer, + pExt->pInputSampleBuffer, + &pExt->frame_type, + &pExt->mode, + pExt->quality, + &pExt->rx_state); + } + + + if ((pExt->frame_type == RX_NO_DATA) | (pExt->frame_type == RX_SPEECH_LOST)) + { + pExt->mode = pExt->mode_old; + pExt->reset_flag = 0; + } + else + { + pExt->mode_old = pExt->mode; + + /* if homed: check if this frame is another homing frame */ + if (pExt->reset_flag_old == 1) + { + /* only check until end of first subframe */ + pExt->reset_flag = pvDecoder_AmrWb_homing_frame_test_first(pExt->pInputSampleBuffer, + pExt->mode); + } + } + + /* produce encoder homing frame if homed & input=decoder homing frame */ + if ((pExt->reset_flag != 0) && (pExt->reset_flag_old != 0)) + { + /* set homing sequence ( no need to decode anything */ + + for (int16 i = 0; i < AMR_WB_PCM_FRAME; i++) + { + pExt->pOutputBuffer[i] = EHF_MASK; + } + } + else + { + pExt->status = pvDecoder_AmrWb(pExt->mode, + pExt->pInputSampleBuffer, + pExt->pOutputBuffer, + &pExt->frameLength, + st, + pExt->frame_type, + ScratchMem); + } + + for (int16 i = 0; i < AMR_WB_PCM_FRAME; i++) /* Delete the 2 LSBs (14-bit output) */ + { + pExt->pOutputBuffer[i] &= 0xfffC; + } + + + /* if not homed: check whether current frame is a homing frame */ + if (pExt->reset_flag_old == 0) + { + /* check whole frame */ + pExt->reset_flag = pvDecoder_AmrWb_homing_frame_test(pExt->pInputSampleBuffer, + pExt->mode); + } + /* reset decoder if current frame is a homing frame */ + if (pExt->reset_flag != 0) + { + pvDecoder_AmrWb_Reset(st, 1);; + } + pExt->reset_flag_old = pExt->reset_flag; + + return pExt->status; + +} + +/* +----------------------------------------------------------------------------- + + CDecoder_AMR_WB + + StopL + + Stop decoder object. + + Parameters: none + + Return Values: none + +----------------------------------------------------------------------------- +*/ +OSCL_EXPORT_REF void CDecoder_AMR_WB::StopL() +{ +} + +/* +----------------------------------------------------------------------------- + + CDecoder_AMR_WB + + ResetDecoderL + + Stop decoder object. Reset decoder. + + Parameters: none + + Return Values: status + +----------------------------------------------------------------------------- +*/ +OSCL_EXPORT_REF int32 CDecoder_AMR_WB::ResetDecoderL() +{ + pvDecoder_AmrWb_Reset(st, 1); + return 0; +} + + +/* +----------------------------------------------------------------------------- + + CDecoder_AMR_WB + + TerminateDecoderL + + Stop decoder object. close decoder. + + Parameters: none + + Return Values: none + +----------------------------------------------------------------------------- +*/ +OSCL_EXPORT_REF void CDecoder_AMR_WB::TerminateDecoderL() +{ + st = NULL; + ScratchMem = NULL; + + if (pt_st != NULL) + { + OSCL_ARRAY_DELETE((uint8*)pt_st); + pt_st = NULL; + } + + if (iInputBuf) + { + OSCL_ARRAY_DELETE(iInputBuf); + iInputBuf = NULL; + } + + if (iOutputBuf) + { + OSCL_ARRAY_DELETE(iOutputBuf); + iOutputBuf = NULL; + } + + if (iInputSampleBuf != NULL) + { + OSCL_ARRAY_DELETE(iInputSampleBuf); + iInputSampleBuf = NULL; + } + +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/deemphasis_32.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/deemphasis_32.cpp new file mode 100644 index 00000000..38cd619f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/deemphasis_32.cpp @@ -0,0 +1,158 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: deemphasis_32.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 x_hi[], (i) : input signal (bit31..16) + int16 x_lo[], (i) : input signal (bit15..4) + int16 y[], (o) : output signal (x16) + int16 mu, (i) Q15 : deemphasis factor + int16 L, (i) : vector size + int16 * mem (i/o) : memory (y[-1]) + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + 32-bits filtering through 1/(1-mu z^-1) + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + + Deemphasis H(z) = 1/(1 - 0.68z^(-1)) where mu = 0.67999 in Q15 + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwb_math_op.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void deemphasis_32( + int16 x_hi[], /* (i) : input signal (bit31..16) */ + int16 x_lo[], /* (i) : input signal (bit15..4) */ + int16 y[], /* (o) : output signal (x16) */ + int16 mu, /* (i) Q15 : deemphasis factor */ + int16 L, /* (i) : vector size */ + int16 * mem /* (i/o) : memory (y[-1]) */ +) +{ + int16 i; + int32 L_tmp; + int16 lo, hi; + + L_tmp = ((int32)x_hi[0]) << 16; + L_tmp += ((int32)x_lo[0]) << 4; + L_tmp = shl_int32(L_tmp, 3); + + L_tmp = fxp_mac_16by16(*mem, mu, L_tmp), + + L_tmp = shl_int32(L_tmp, 1); /* saturation can occur here */ + y[0] = amr_wb_round(L_tmp); + + lo = x_lo[1]; + hi = x_hi[1]; + for (i = 1; i < L - 1; i++) + { + L_tmp = ((int32)hi) << 16; + L_tmp += ((int32)lo) << 4; + L_tmp = shl_int32(L_tmp, 3); + L_tmp = fxp_mac_16by16(y[i - 1], mu, L_tmp), + L_tmp = shl_int32(L_tmp, 1); /* saturation can occur here */ + y[i] = amr_wb_round(L_tmp); + lo = x_lo[i+1]; + hi = x_hi[i+1]; + } + L_tmp = ((int32)hi) << 16; + L_tmp += ((int32)lo) << 4; + L_tmp = shl_int32(L_tmp, 3); + L_tmp = fxp_mac_16by16(y[i - 1], mu, L_tmp), + L_tmp = shl_int32(L_tmp, 1); /* saturation can occur here */ + y[i] = amr_wb_round(L_tmp); + + *mem = y[L - 1]; + + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dtx.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dtx.h new file mode 100644 index 00000000..a87bf1c9 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dtx.h @@ -0,0 +1,236 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./cpp/include/dtx.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + Static memory, constants and frametypes for the DTX +------------------------------------------------------------------------------ +*/ +#ifndef DTX_H +#define DTX_H + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES AND SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + +#define DTX_MAX_EMPTY_THRESH 50 +#define DTX_HIST_SIZE 8 +#define DTX_HIST_SIZE_MIN_ONE 7 +#define DTX_ELAPSED_FRAMES_THRESH (24 + 7 -1) +#define DTX_HANG_CONST 7 /* yields eight frames of SP HANGOVER */ +#define INV_MED_THRESH 14564 +#define ISF_GAP 128 /* 50 */ +#define ONE_MINUS_ISF_GAP 16384 - ISF_GAP + +#define ISF_GAP 128 +#define ISF_DITH_GAP 448 +#define ISF_FACTOR_LOW 256 +#define ISF_FACTOR_STEP 2 + +#define GAIN_THR 180 +#define GAIN_FACTOR 75 + + typedef struct + { + int16 isf_hist[M * DTX_HIST_SIZE]; + int16 log_en_hist[DTX_HIST_SIZE]; + int16 hist_ptr; + int16 log_en_index; + int16 cng_seed; + + /* DTX handler stuff */ + int16 dtxHangoverCount; + int16 decAnaElapsedCount; + int32 D[28]; + int32 sumD[DTX_HIST_SIZE]; + } dtx_encState; + +#define SPEECH 0 +#define DTX 1 +#define DTX_MUTE 2 + +#define TX_SPEECH 0 +#define TX_SID_FIRST 1 +#define TX_SID_UPDATE 2 +#define TX_NO_DATA 3 + +#define RX_SPEECH_GOOD 0 +#define RX_SPEECH_PROBABLY_DEGRADED 1 +#define RX_SPEECH_LOST 2 +#define RX_SPEECH_BAD 3 +#define RX_SID_FIRST 4 +#define RX_SID_UPDATE 5 +#define RX_SID_BAD 6 +#define RX_NO_DATA 7 + + /***************************************************************************** + * + * DEFINITION OF DATA TYPES + *****************************************************************************/ + + typedef struct + { + int16 since_last_sid; + int16 true_sid_period_inv; + int16 log_en; + int16 old_log_en; + int16 level; + int16 isf[M]; + int16 isf_old[M]; + int16 cng_seed; + + int16 isf_hist[M * DTX_HIST_SIZE]; + int16 log_en_hist[DTX_HIST_SIZE]; + int16 hist_ptr; + + int16 dtxHangoverCount; + int16 decAnaElapsedCount; + + int16 sid_frame; + int16 valid_data; + int16 dtxHangoverAdded; + + int16 dtxGlobalState; /* contains previous state */ + /* updated in main decoder */ + + int16 data_updated; /* marker to know if CNI data is ever renewed */ + + int16 dither_seed; + int16 CN_dith; + + } dtx_decState; + + int16 dtx_enc_init(dtx_encState ** st, int16 isf_init[]); + int16 dtx_enc_reset(dtx_encState * st, int16 isf_init[]); + void dtx_enc_exit(dtx_encState ** st); + + int16 dtx_enc( + dtx_encState * st, /* i/o : State struct */ + int16 isf[M], /* o : CN ISF vector */ + int16 * exc2, /* o : CN excitation */ + int16 ** prms + ); + + int16 dtx_buffer( + dtx_encState * st, /* i/o : State struct */ + int16 isf_new[], /* i : isf vector */ + int32 enr, /* i : residual energy (in L_FRAME) */ + int16 codec_mode + ); + + void tx_dtx_handler(dtx_encState * st, /* i/o : State struct */ + int16 vad_flag, /* i : vad decision */ + int16 * usedMode /* i/o : mode changed or not */ + ); + + void Qisf_ns( + int16 * isf1, /* input : ISF in the frequency domain (0..0.5) */ + int16 * isf_q, /* output: quantized ISF */ + int16 * indice /* output: quantization indices */ + ); + + + int16 dtx_dec_amr_wb_reset(dtx_decState * st, const int16 isf_init[]); + + int16 dtx_dec_amr_wb( + dtx_decState * st, /* i/o : State struct */ + int16 * exc2, /* o : CN excitation */ + int16 new_state, /* i : New DTX state */ + int16 isf[], /* o : CN ISF vector */ + int16 ** prms + ); + + void dtx_dec_amr_wb_activity_update( + dtx_decState * st, + int16 isf[], + int16 exc[]); + + + int16 rx_amr_wb_dtx_handler( + dtx_decState * st, /* i/o : State struct */ + int16 frame_type /* i : Frame type */ + ); + + void Disf_ns( + int16 * indice, /* input: quantization indices */ + int16 * isf_q /* input : ISF in the frequency domain (0..0.5) */ + ); + + void aver_isf_history( + int16 isf_old[], + int16 indices[], + int32 isf_aver[] + ); + void find_frame_indices( + int16 isf_old_tx[], + int16 indices[], + dtx_encState * st + ); + + int16 dithering_control( + dtx_encState * st + ); + void CN_dithering( + int16 isf[M], + int32 * L_log_en_int, + int16 * dither_seed + ); + +#ifdef __cplusplus +} +#endif + +#endif /* DTX_H */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dtx_decoder_amr_wb.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dtx_decoder_amr_wb.cpp new file mode 100644 index 00000000..125b87a0 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/dtx_decoder_amr_wb.cpp @@ -0,0 +1,976 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: dtx_decoder_amr_wb.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + DTX functions + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwb_math_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" /* prototype of functions */ +#include "get_amr_wb_bits.h" +#include "dtx.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +/* + * Function : dtx_dec_amr_wb_reset + */ +int16 dtx_dec_amr_wb_reset(dtx_decState * st, const int16 isf_init[]) +{ + int16 i; + + + if (st == (dtx_decState *) NULL) + { + /* dtx_dec_amr_wb_reset invalid parameter */ + return (-1); + } + st->since_last_sid = 0; + st->true_sid_period_inv = (1 << 13); /* 0.25 in Q15 */ + + st->log_en = 3500; + st->old_log_en = 3500; + /* low level noise for better performance in DTX handover cases */ + + st->cng_seed = RANDOM_INITSEED; + + st->hist_ptr = 0; + + /* Init isf_hist[] and decoder log frame energy */ + pv_memcpy((void *)st->isf, (void *)isf_init, M*sizeof(*isf_init)); + + pv_memcpy((void *)st->isf_old, (void *)isf_init, M*sizeof(*isf_init)); + + for (i = 0; i < DTX_HIST_SIZE; i++) + { + pv_memcpy((void *)&st->isf_hist[i * M], (void *)isf_init, M*sizeof(*isf_init)); + st->log_en_hist[i] = st->log_en; + } + + st->dtxHangoverCount = DTX_HANG_CONST; + st->decAnaElapsedCount = 32767; + + st->sid_frame = 0; + st->valid_data = 0; + st->dtxHangoverAdded = 0; + + st->dtxGlobalState = SPEECH; + st->data_updated = 0; + + st->dither_seed = RANDOM_INITSEED; + st->CN_dith = 0; + + return 0; +} + + +/* + Table of new SPD synthesis states + + | previous SPD_synthesis_state + Incoming | + frame_type | SPEECH | DTX | DTX_MUTE + --------------------------------------------------------------- + RX_SPEECH_GOOD , | | | + RX_SPEECH_PR_DEGRADED | SPEECH | SPEECH | SPEECH + ---------------------------------------------------------------- + RX_SPEECH_BAD, | SPEECH | DTX | DTX_MUTE + ---------------------------------------------------------------- + RX_SID_FIRST, | DTX | DTX/(DTX_MUTE)| DTX_MUTE + ---------------------------------------------------------------- + RX_SID_UPDATE, | DTX | DTX | DTX + ---------------------------------------------------------------- + RX_SID_BAD, | DTX | DTX/(DTX_MUTE)| DTX_MUTE + ---------------------------------------------------------------- + RX_NO_DATA, | SPEECH | DTX/(DTX_MUTE)| DTX_MUTE + RX_SPARE |(class2 garb.)| | + ---------------------------------------------------------------- +*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +/* + * Function : dtx_dec_amr_wb + */ +int16 dtx_dec_amr_wb( + dtx_decState * st, /* i/o : State struct */ + int16 * exc2, /* o : CN excitation */ + int16 new_state, /* i : New DTX state */ + int16 isf[], /* o : CN ISF vector */ + int16 ** prms +) +{ + int16 log_en_index; + int16 ind[7]; + int16 i, j; + int16 int_fac; + int16 gain; + + int32 L_isf[M], L_log_en_int, level32, ener32; + int16 ptr; + int16 tmp_int_length; + int16 tmp, exp, exp0, log_en_int_e, log_en_int_m, level; + + /* This function is called if synthesis state is not SPEECH the globally passed inputs to this function + * are st->sid_frame st->valid_data st->dtxHangoverAdded new_state (SPEECH, DTX, DTX_MUTE) */ + + if ((st->dtxHangoverAdded != 0) && + (st->sid_frame != 0)) + { + /* sid_first after dtx hangover period */ + /* or sid_upd after dtxhangover */ + + /* consider twice the last frame */ + ptr = st->hist_ptr + 1; + + if (ptr == DTX_HIST_SIZE) + ptr = 0; + + pv_memcpy((void *)&st->isf_hist[ptr * M], (void *)&st->isf_hist[st->hist_ptr * M], M*sizeof(*st->isf_hist)); + + st->log_en_hist[ptr] = st->log_en_hist[st->hist_ptr]; + + /* compute mean log energy and isf from decoded signal (SID_FIRST) */ + st->log_en = 0; + for (i = 0; i < M; i++) + { + L_isf[i] = 0; + } + + /* average energy and isf */ + for (i = 0; i < DTX_HIST_SIZE; i++) + { + /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer log_en is in Q10 */ + st->log_en = add_int16(st->log_en, st->log_en_hist[i]); + + for (j = 0; j < M; j++) + { + L_isf[j] = add_int32(L_isf[j], (int32)(st->isf_hist[i * M + j])); + } + } + + /* st->log_en in Q9 */ + st->log_en >>= 1; + + /* Add 2 in Q9, in order to have only positive values for Pow2 */ + /* this value is subtracted back after Pow2 function */ + st->log_en += 1024; + + if (st->log_en < 0) + st->log_en = 0; + + for (j = 0; j < M; j++) + { + st->isf[j] = (int16)(L_isf[j] >> 3); /* divide by 8 */ + } + + } + + if (st->sid_frame != 0) + { + /* Set old SID parameters, always shift */ + /* even if there is no new valid_data */ + + pv_memcpy((void *)st->isf_old, (void *)st->isf, M*sizeof(*st->isf)); + + st->old_log_en = st->log_en; + + if (st->valid_data != 0) /* new data available (no CRC) */ + { + /* st->true_sid_period_inv = 1.0f/st->since_last_sid; */ + /* Compute interpolation factor, since the division only works * for values of since_last_sid < + * 32 we have to limit the * interpolation to 32 frames */ + tmp_int_length = st->since_last_sid; + + + if (tmp_int_length > 32) + { + tmp_int_length = 32; + } + + if (tmp_int_length >= 2) + { + st->true_sid_period_inv = div_16by16(1 << 10, shl_int16(tmp_int_length, 10)); + } + else + { + st->true_sid_period_inv = 1 << 14; /* 0.5 it Q15 */ + } + + ind[0] = Serial_parm(6, prms); + ind[1] = Serial_parm(6, prms); + ind[2] = Serial_parm(6, prms); + ind[3] = Serial_parm(5, prms); + ind[4] = Serial_parm(5, prms); + + Disf_ns(ind, st->isf); + + log_en_index = Serial_parm(6, prms); + + /* read background noise stationarity information */ + st->CN_dith = Serial_parm_1bit(prms); + + /* st->log_en = (float)log_en_index / 2.625 - 2.0; */ + /* log2(E) in Q9 (log2(E) lies in between -2:22) */ + st->log_en = shl_int16(log_en_index, 15 - 6); + + /* Divide by 2.625 */ + st->log_en = mult_int16(st->log_en, 12483); + /* Subtract 2 in Q9 is done later, after Pow2 function */ + + /* no interpolation at startup after coder reset */ + /* or when SID_UPD has been received right after SPEECH */ + + if ((st->data_updated == 0) || (st->dtxGlobalState == SPEECH)) + { + pv_memcpy((void *)st->isf_old, (void *)st->isf, M*sizeof(*st->isf)); + + st->old_log_en = st->log_en; + } + } /* endif valid_data */ + } /* endif sid_frame */ + + + if ((st->sid_frame != 0) && (st->valid_data != 0)) + { + st->since_last_sid = 0; + } + /* Interpolate SID info */ + int_fac = shl_int16(st->since_last_sid, 10); /* Q10 */ + int_fac = mult_int16(int_fac, st->true_sid_period_inv); /* Q10 * Q15 -> Q10 */ + + /* Maximize to 1.0 in Q10 */ + + if (int_fac > 1024) + { + int_fac = 1024; + } + int_fac = shl_int16(int_fac, 4); /* Q10 -> Q14 */ + + L_log_en_int = mul_16by16_to_int32(int_fac, st->log_en); /* Q14 * Q9 -> Q24 */ + + for (i = 0; i < M; i++) + { + isf[i] = mult_int16(int_fac, st->isf[i]);/* Q14 * Q15 -> Q14 */ + } + + int_fac = 16384 - int_fac; /* 1-k in Q14 */ + + /* ( Q14 * Q9 -> Q24 ) + Q24 -> Q24 */ + L_log_en_int = mac_16by16_to_int32(L_log_en_int, int_fac, st->old_log_en); + + for (i = 0; i < M; i++) + { + /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */ + isf[i] = add_int16(isf[i], mult_int16(int_fac, st->isf_old[i])); + isf[i] = shl_int16(isf[i], 1); /* Q14 -> Q15 */ + } + + /* If background noise is non-stationary, insert comfort noise dithering */ + if (st->CN_dith != 0) + { + CN_dithering(isf, &L_log_en_int, &st->dither_seed); + } + /* L_log_en_int corresponds to log2(E)+2 in Q24, i.e log2(gain)+1 in Q25 */ + /* Q25 -> Q16 */ + L_log_en_int >>= 9; + + /* Find integer part */ + log_en_int_e = extract_h(L_log_en_int); + + /* Find fractional part */ + log_en_int_m = (int16)(sub_int32(L_log_en_int, L_deposit_h(log_en_int_e)) >> 1); + + /* Subtract 2 from L_log_en_int in Q9, i.e divide the gain by 2 (energy by 4) */ + /* Add 16 in order to have the result of pow2 in Q16 */ + log_en_int_e += 15; + + /* level = (float)( pow( 2.0f, log_en ) ); */ + level32 = power_of_2(log_en_int_e, log_en_int_m); /* Q16 */ + + exp0 = normalize_amr_wb(level32); + level32 <<= exp0; /* level in Q31 */ + exp0 = 15 - exp0; + level = (int16)(level32 >> 16); /* level in Q15 */ + + /* generate white noise vector */ + for (i = 0; i < L_FRAME; i++) + { + exc2[i] = noise_gen_amrwb(&(st->cng_seed)) >> 4; + } + + /* gain = level / sqrt(ener) * sqrt(L_FRAME) */ + + /* energy of generated excitation */ + ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp); + + one_ov_sqrt_norm(&ener32, &exp); + + gain = extract_h(ener32); + + gain = mult_int16(level, gain); /* gain in Q15 */ + + exp += exp0; + + /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */ + exp += 4; + + for (i = 0; i < L_FRAME; i++) + { + tmp = mult_int16(exc2[i], gain); /* Q0 * Q15 */ + exc2[i] = shl_int16(tmp, exp); + } + + + if (new_state == DTX_MUTE) + { + /* mute comfort noise as it has been quite a long time since last SID update was performed */ + + tmp_int_length = st->since_last_sid; + + if (tmp_int_length > 32) + { + tmp_int_length = 32; + } + + st->true_sid_period_inv = div_16by16(1 << 10, shl_int16(tmp_int_length, 10)); + + st->since_last_sid = 0; + st->old_log_en = st->log_en; + /* subtract 1/8 in Q9 (energy), i.e -3/8 dB */ + st->log_en -= 64; + } + /* reset interpolation length timer if data has been updated. */ + + if ((st->sid_frame != 0) && + ((st->valid_data != 0) || + ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0))) + { + st->since_last_sid = 0; + st->data_updated = 1; + } + return 0; +} + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void dtx_dec_amr_wb_activity_update( + dtx_decState * st, + int16 isf[], + int16 exc[]) +{ + int16 i; + + int32 L_frame_en; + int16 log_en_e, log_en_m, log_en; + + + st->hist_ptr++; + + if (st->hist_ptr == DTX_HIST_SIZE) + { + st->hist_ptr = 0; + } + pv_memcpy((void *)&st->isf_hist[st->hist_ptr * M], (void *)isf, M*sizeof(*isf)); + + + /* compute log energy based on excitation frame energy in Q0 */ + L_frame_en = 0; + for (i = 0; i < L_FRAME; i++) + { + L_frame_en = mac_16by16_to_int32(L_frame_en, exc[i], exc[i]); + } + L_frame_en >>= 1; + + /* log_en = (float)log10(L_frame_en/(float)L_FRAME)/(float)log10(2.0f); */ + amrwb_log_2(L_frame_en, &log_en_e, &log_en_m); + + /* convert exponent and mantissa to int16 Q7. Q7 is used to simplify averaging in dtx_enc */ + log_en = shl_int16(log_en_e, 7); /* Q7 */ + log_en += log_en_m >> 8; + + /* Divide by L_FRAME = 256, i.e subtract 8 in Q7 = 1024 */ + log_en -= 1024; + + /* insert into log energy buffer */ + st->log_en_hist[st->hist_ptr] = log_en; + + return; +} + + +/* + Table of new SPD synthesis states + + | previous SPD_synthesis_state + Incoming | + frame_type | SPEECH | DTX | DTX_MUTE + --------------------------------------------------------------- + RX_SPEECH_GOOD , | | | + RX_SPEECH_PR_DEGRADED | SPEECH | SPEECH | SPEECH + ---------------------------------------------------------------- + RX_SPEECH_BAD, | SPEECH | DTX | DTX_MUTE + ---------------------------------------------------------------- + RX_SID_FIRST, | DTX | DTX/(DTX_MUTE)| DTX_MUTE + ---------------------------------------------------------------- + RX_SID_UPDATE, | DTX | DTX | DTX + ---------------------------------------------------------------- + RX_SID_BAD, | DTX | DTX/(DTX_MUTE)| DTX_MUTE + ---------------------------------------------------------------- + RX_NO_DATA, | SPEECH | DTX/(DTX_MUTE)| DTX_MUTE + RX_SPARE |(class2 garb.)| | + ---------------------------------------------------------------- +*/ + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +int16 rx_amr_wb_dtx_handler( + dtx_decState * st, /* i/o : State struct */ + int16 frame_type /* i : Frame type */ +) +{ + int16 newState; + int16 encState; + + /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */ + + + + if ((frame_type == RX_SID_FIRST) || + (frame_type == RX_SID_UPDATE) || + (frame_type == RX_SID_BAD) || + (((st->dtxGlobalState == DTX) || + (st->dtxGlobalState == DTX_MUTE)) && + ((frame_type == RX_NO_DATA) || + (frame_type == RX_SPEECH_BAD) || + (frame_type == RX_SPEECH_LOST)))) + { + newState = DTX; + + /* stay in mute for these input types */ + + if ((st->dtxGlobalState == DTX_MUTE) && + ((frame_type == RX_SID_BAD) || + (frame_type == RX_SID_FIRST) || + (frame_type == RX_SPEECH_LOST) || + (frame_type == RX_NO_DATA))) + { + newState = DTX_MUTE; + } + /* evaluate if noise parameters are too old */ + /* since_last_sid is reset when CN parameters have been updated */ + st->since_last_sid = add_int16(st->since_last_sid, 1); + + /* no update of sid parameters in DTX for a long while */ + + if (st->since_last_sid > DTX_MAX_EMPTY_THRESH) + { + newState = DTX_MUTE; + } + } + else + { + newState = SPEECH; + st->since_last_sid = 0; + } + + /* reset the decAnaElapsed Counter when receiving CNI data the first time, to robustify counter missmatch + * after handover this might delay the bwd CNI analysis in the new decoder slightly. */ + + if ((st->data_updated == 0) && + (frame_type == RX_SID_UPDATE)) + { + st->decAnaElapsedCount = 0; + } + /* update the SPE-SPD DTX hangover synchronization */ + /* to know when SPE has added dtx hangover */ + st->decAnaElapsedCount = add_int16(st->decAnaElapsedCount, 1); + st->dtxHangoverAdded = 0; + + + if ((frame_type == RX_SID_FIRST) || + (frame_type == RX_SID_UPDATE) || + (frame_type == RX_SID_BAD) || + (frame_type == RX_NO_DATA)) + { + encState = DTX; + } + else + { + encState = SPEECH; + } + + + if (encState == SPEECH) + { + st->dtxHangoverCount = DTX_HANG_CONST; + } + else + { + + if (st->decAnaElapsedCount > DTX_ELAPSED_FRAMES_THRESH) + { + st->dtxHangoverAdded = 1; + st->decAnaElapsedCount = 0; + st->dtxHangoverCount = 0; + } + else if (st->dtxHangoverCount == 0) + { + st->decAnaElapsedCount = 0; + } + else + { + st->dtxHangoverCount--; + } + } + + if (newState != SPEECH) + { + /* DTX or DTX_MUTE CN data is not in a first SID, first SIDs are marked as SID_BAD but will do + * backwards analysis if a hangover period has been added according to the state machine above */ + + st->sid_frame = 0; + st->valid_data = 0; + + + if (frame_type == RX_SID_FIRST) + { + st->sid_frame = 1; + } + else if (frame_type == RX_SID_UPDATE) + { + st->sid_frame = 1; + st->valid_data = 1; + } + else if (frame_type == RX_SID_BAD) + { + st->sid_frame = 1; + st->dtxHangoverAdded = 0; /* use old data */ + } + } + return newState; + /* newState is used by both SPEECH AND DTX synthesis routines */ +} + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void aver_isf_history( + int16 isf_old[], + int16 indices[], + int32 isf_aver[] +) +{ + int16 i, j, k; + int16 isf_tmp[2 * M]; + int32 L_tmp; + + /* Memorize in isf_tmp[][] the ISF vectors to be replaced by */ + /* the median ISF vector prior to the averaging */ + for (k = 0; k < 2; k++) + { + + if (indices[k] + 1 != 0) + { + for (i = 0; i < M; i++) + { + isf_tmp[k * M + i] = isf_old[indices[k] * M + i]; + isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i]; + } + } + } + + /* Perform the ISF averaging */ + for (j = 0; j < M; j++) + { + L_tmp = 0; + + for (i = 0; i < DTX_HIST_SIZE; i++) + { + L_tmp = add_int32(L_tmp, (int32)(isf_old[i * M + j])); + } + isf_aver[j] = L_tmp; + } + + /* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */ + for (k = 0; k < 2; k++) + { + + if (indices[k] + 1 != 0) + { + for (i = 0; i < M; i++) + { + isf_old[indices[k] * M + i] = isf_tmp[k * M + i]; + } + } + } + + return; +} + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void find_frame_indices( + int16 isf_old_tx[], + int16 indices[], + dtx_encState * st +) +{ + int32 L_tmp, summin, summax, summax2nd; + int16 i, j, tmp; + int16 ptr; + + /* Remove the effect of the oldest frame from the column */ + /* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is */ + /* not updated since it will be removed later. */ + + tmp = DTX_HIST_SIZE_MIN_ONE; + j = -1; + for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++) + { + j += tmp; + st->sumD[i] = sub_int32(st->sumD[i], st->D[j]); + tmp--; + } + + /* Shift the column sum sumD. The element sumD[DTX_HIST_SIZE-1] */ + /* corresponding to the oldest frame is removed. The sum of */ + /* the distances between the latest isf and other isfs, */ + /* i.e. the element sumD[0], will be computed during this call. */ + /* Hence this element is initialized to zero. */ + + for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--) + { + st->sumD[i] = st->sumD[i - 1]; + } + st->sumD[0] = 0; + + /* Remove the oldest frame from the distance matrix. */ + /* Note that the distance matrix is replaced by a one- */ + /* dimensional array to save static memory. */ + + tmp = 0; + for (i = 27; i >= 12; i -= tmp) + { + tmp++; + for (j = tmp; j > 0; j--) + { + st->D[i - j + 1] = st->D[i - j - tmp]; + } + } + + /* Compute the first column of the distance matrix D */ + /* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */ + + ptr = st->hist_ptr; + for (i = 1; i < DTX_HIST_SIZE; i++) + { + /* Compute the distance between the latest isf and the other isfs. */ + ptr--; + + if (ptr < 0) + { + ptr = DTX_HIST_SIZE_MIN_ONE; + } + L_tmp = 0; + for (j = 0; j < M; j++) + { + tmp = sub_int16(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]); + L_tmp = mac_16by16_to_int32(L_tmp, tmp, tmp); + } + st->D[i - 1] = L_tmp; + + /* Update also the column sums. */ + st->sumD[0] = add_int32(st->sumD[0], st->D[i - 1]); + st->sumD[i] = add_int32(st->sumD[i], st->D[i - 1]); + } + + /* Find the minimum and maximum distances */ + summax = st->sumD[0]; + summin = st->sumD[0]; + indices[0] = 0; + indices[2] = 0; + for (i = 1; i < DTX_HIST_SIZE; i++) + { + + if (st->sumD[i] > summax) + { + indices[0] = i; + summax = st->sumD[i]; + } + + if (st->sumD[i] < summin) + { + indices[2] = i; + summin = st->sumD[i]; + } + } + + /* Find the second largest distance */ + summax2nd = -2147483647L; + indices[1] = -1; + for (i = 0; i < DTX_HIST_SIZE; i++) + { + + if ((st->sumD[i] > summax2nd) && (i != indices[0])) + { + indices[1] = i; + summax2nd = st->sumD[i]; + } + } + + for (i = 0; i < 3; i++) + { + indices[i] = sub_int16(st->hist_ptr, indices[i]); + + if (indices[i] < 0) + { + indices[i] = add_int16(indices[i], DTX_HIST_SIZE); + } + } + + /* If maximum distance/MED_THRESH is smaller than minimum distance */ + /* then the median ISF vector replacement is not performed */ + tmp = normalize_amr_wb(summax); + summax <<= tmp; + summin <<= tmp; + L_tmp = mul_16by16_to_int32(amr_wb_round(summax), INV_MED_THRESH); + + if (L_tmp <= summin) + { + indices[0] = -1; + } + /* If second largest distance/MED_THRESH is smaller than */ + /* minimum distance then the median ISF vector replacement is */ + /* not performed */ + summax2nd = shl_int32(summax2nd, tmp); + L_tmp = mul_16by16_to_int32(amr_wb_round(summax2nd), INV_MED_THRESH); + + if (L_tmp <= summin) + { + indices[1] = -1; + } + return; +} + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +int16 dithering_control(dtx_encState * st) +{ + int16 i, tmp, mean, CN_dith, gain_diff; + int32 ISF_diff; + + /* determine how stationary the spectrum of background noise is */ + ISF_diff = 0; + for (i = 0; i < 8; i++) + { + ISF_diff = add_int32(ISF_diff, st->sumD[i]); + } + if ((ISF_diff >> 26) > 0) + { + CN_dith = 1; + } + else + { + CN_dith = 0; + } + + /* determine how stationary the energy of background noise is */ + mean = 0; + for (i = 0; i < DTX_HIST_SIZE; i++) + { + mean = add_int16(mean, st->log_en_hist[i]); + } + mean >>= 3; + gain_diff = 0; + for (i = 0; i < DTX_HIST_SIZE; i++) + { + tmp = sub_int16(st->log_en_hist[i], mean); + tmp = tmp - (tmp < 0); + + gain_diff += tmp ^(tmp >> 15); /* tmp ^sign(tmp) */; + } + if (gain_diff > GAIN_THR) + { + CN_dith = 1; + } + return CN_dith; +} + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void CN_dithering( + int16 isf[M], + int32 * L_log_en_int, + int16 * dither_seed +) +{ + int16 temp, temp1, i, dither_fac, rand_dith; + int16 rand_dith2; + + /* Insert comfort noise dithering for energy parameter */ + rand_dith = noise_gen_amrwb(dither_seed) >> 1; + rand_dith2 = noise_gen_amrwb(dither_seed) >> 1; + rand_dith += rand_dith2; + *L_log_en_int = add_int32(*L_log_en_int, mul_16by16_to_int32(rand_dith, GAIN_FACTOR)); + + if (*L_log_en_int < 0) + { + *L_log_en_int = 0; + } + /* Insert comfort noise dithering for spectral parameters (ISF-vector) */ + dither_fac = ISF_FACTOR_LOW; + + rand_dith = noise_gen_amrwb(dither_seed) >> 1; + rand_dith2 = noise_gen_amrwb(dither_seed) >> 1; + rand_dith += rand_dith2; + temp = add_int16(isf[0], mult_int16_r(rand_dith, dither_fac)); + + /* Make sure that isf[0] will not get negative values */ + if (temp < ISF_GAP) + { + isf[0] = ISF_GAP; + } + else + { + isf[0] = temp; + } + + for (i = 1; i < M - 1; i++) + { + dither_fac = add_int16(dither_fac, ISF_FACTOR_STEP); + + rand_dith = noise_gen_amrwb(dither_seed) >> 1; + rand_dith2 = noise_gen_amrwb(dither_seed) >> 1; + rand_dith += rand_dith2; + temp = add_int16(isf[i], mult_int16_r(rand_dith, dither_fac)); + temp1 = sub_int16(temp, isf[i - 1]); + + /* Make sure that isf spacing remains at least ISF_DITH_GAP Hz */ + if (temp1 < ISF_DITH_GAP) + { + isf[i] = isf[i - 1] + ISF_DITH_GAP; + } + else + { + isf[i] = temp; + } + } + + /* Make sure that isf[M-2] will not get values above 16384 */ + if (isf[M - 2] > 16384) + { + isf[M - 2] = 16384; + } + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/e_pv_amrwbdec.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/e_pv_amrwbdec.h new file mode 100644 index 00000000..bd766e1d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/e_pv_amrwbdec.h @@ -0,0 +1,126 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + + Filename: e_pv_amrwbdec.h + +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef E_PV_AMRWBDEC_H +#define E_PV_AMRWBDEC_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pvamrwbdecoder_cnst.h" /* coder constant parameters */ +#include "dtx.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; SIMPLE TYPEDEF'S +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; ENUMERATED TYPEDEF'S +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; STRUCTURES TYPEDEF'S +----------------------------------------------------------------------------*/ + + +typedef struct +{ + int16 old_exc[PIT_MAX + L_INTERPOL]; /* old excitation vector */ + int16 ispold[M]; /* old isp (immittance spectral pairs)*/ + int16 isfold[M]; /* old isf (frequency domain) */ + int16 isf_buf[L_MEANBUF * M]; /* isf buffer(frequency domain) */ + int16 past_isfq[M]; /* past isf quantizer */ + int16 tilt_code; /* tilt of code */ + int16 Q_old; /* old scaling factor */ + int16 Qsubfr[4]; /* old maximum scaling factor */ + int32 L_gc_thres; /* threshold for noise enhancer */ + int16 mem_syn_hi[M]; /* modified synthesis memory (MSB) */ + int16 mem_syn_lo[M]; /* modified synthesis memory (LSB) */ + int16 mem_deemph; /* speech deemph filter memory */ + int16 mem_sig_out[6]; /* hp50 filter memory for synthesis */ + int16 mem_oversamp[2 * L_FILT]; /* synthesis oversampled filter memory */ + int16 mem_syn_hf[M16k]; /* HF synthesis memory */ + int16 mem_hf[2 * L_FILT16k]; /* HF band-pass filter memory */ + int16 mem_hf2[2 * L_FILT16k]; /* HF band-pass filter memory */ + int16 mem_hf3[2 * L_FILT16k]; /* HF band-pass filter memory */ + int16 seed; /* random memory for frame erasure */ + int16 seed2; /* random memory for HF generation */ + int16 old_T0; /* old pitch lag */ + int16 old_T0_frac; /* old pitch fraction lag */ + int16 lag_hist[5]; + int16 dec_gain[23]; /* gain decoder memory */ + int16 seed3; /* random memory for lag concealment */ + int16 disp_mem[8]; /* phase dispersion memory */ + int16 mem_hp400[6]; /* hp400 filter memory for synthesis */ + + int16 prev_bfi; + int16 state; + int16 first_frame; + dtx_decState dtx_decSt; + int16 vad_hist; + +} Decoder_State; + +typedef struct +{ + Decoder_State state; + int16 ScratchMem[L_SUBFR + L_SUBFR16k + ((L_SUBFR + M + M16k +1)<<1) + \ + (2*L_FRAME + 1) + PIT_MAX + L_INTERPOL + NB_SUBFR*(M+1) \ + + 3*(M+L_SUBFR) + M16k]; +} PV_AmrWbDec; + + +/*---------------------------------------------------------------------------- +; END +----------------------------------------------------------------------------*/ +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/get_amr_wb_bits.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/get_amr_wb_bits.cpp new file mode 100644 index 00000000..d9842fcd --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/get_amr_wb_bits.cpp @@ -0,0 +1,155 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: get_amr_wb_bits.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 no_of_bits, input : number of bits + int16 ** prms bitstream pointer + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Returns no_of_bits from serial bit stream + Serial_parm -> convert serial stream to parameters + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_cnst.h" +#include "get_amr_wb_bits.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +int16 Serial_parm( /* Return the parameter */ + int16 no_of_bits, /* input : number of bits */ + int16 ** prms +) +{ + int16 value = 0; + + for (int16 i = no_of_bits >> 1; i != 0; i--) + { + value <<= 2; + + if (*((*prms)++) == BIT_1) + { + value |= 2; + } + + if (*((*prms)++) == BIT_1) + { + value |= 1; + } + + } + + if (no_of_bits&1) + { + value <<= 1; + + if (*((*prms)++) == BIT_1) + { + value |= 1; + } + + } + + return (value); +} + + +int16 Serial_parm_1bit(int16 ** prms) /* Return the parameter */ +{ + int16 value = 0; + + if (*((*prms)++) == BIT_1) + { + value = 1; + } + return (value); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/get_amr_wb_bits.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/get_amr_wb_bits.h new file mode 100644 index 00000000..48e43dba --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/get_amr_wb_bits.h @@ -0,0 +1,60 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/*--------------------------------------------------------------------------* + * get_amr_wb_bits.h * + *--------------------------------------------------------------------------* + * Number of bits for different modes * + *--------------------------------------------------------------------------*/ + +#ifndef GET_AMR_WB_BITS_H +#define GET_AMR_WB_BITS_H + + +#include "pv_amr_wb_type_defs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + + int16 Serial_parm( /* Return the parameter */ + int16 no_of_bits, /* input : number of bits */ + int16 ** prms + ); + + int16 Serial_parm_1bit( /* Return the parameter */ + int16 ** prms + ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/highpass_400hz_at_12k8.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/highpass_400hz_at_12k8.cpp new file mode 100644 index 00000000..d10a20d5 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/highpass_400hz_at_12k8.cpp @@ -0,0 +1,193 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: highpass_400Hz_at_12k8.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 signal[], input signal / output is divided by 16 + int16 lg, lenght of signal + int16 mem[] filter memory [6] + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + 2nd order high pass filter with cut off frequency at 400 Hz. + Designed with cheby2 function in MATLAB. + Optimized for fixed-point to get the following frequency response: + + frequency: 0Hz 100Hz 200Hz 300Hz 400Hz 630Hz 1.5kHz 3kHz + dB loss: -infdB -30dB -20dB -10dB -3dB +6dB +1dB 0dB + + Algorithm: + + y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] + + a[1]*y[i-1] + a[2]*y[i-2]; + + int16 b[3] = {3660, -7320, 3660}; in Q12 + int16 a[3] = {4096, 7320, -3540}; in Q12 + + float --> b[3] = {0.893554687, -1.787109375, 0.893554687}; + a[3] = {1.000000000, 1.787109375, -0.864257812}; + + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwb_math_op.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +/* Initialization of static values */ + +void highpass_400Hz_at_12k8_init(int16 mem[]) +{ + pv_memset((void *)mem, 0, 6*sizeof(*mem)); +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void highpass_400Hz_at_12k8( + int16 signal[], /* input signal / output is divided by 16 */ + int16 lg, /* lenght of signal */ + int16 mem[] /* filter memory [6] */ +) +{ + int16 i, x2; + int16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1; + int32 L_tmp1; + int32 L_tmp2; + + y2_hi = mem[0]; + y2_lo = mem[1]; + y1_hi = mem[2]; + y1_lo = mem[3]; + x0 = mem[4]; + x1 = mem[5]; + + for (i = 0; i < lg; i++) + { + + /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[0]*x[i-2] */ + /* + a[0]*y[i-1] + a[1] * y[i-2]; */ + + L_tmp1 = fxp_mac_16by16(y1_lo, 29280, 8192L); + L_tmp2 = fxp_mul_16by16(y1_hi, 29280); + L_tmp1 = fxp_mac_16by16(y2_lo, -14160, L_tmp1); + L_tmp2 = fxp_mac_16by16(y2_hi, -14160, L_tmp2); + x2 = x1; + x1 = x0; + x0 = signal[i]; + L_tmp2 = fxp_mac_16by16(x2, 915, L_tmp2); + L_tmp2 = fxp_mac_16by16(x1, -1830, L_tmp2); + L_tmp2 = fxp_mac_16by16(x0, 915, L_tmp2); + + L_tmp1 = (L_tmp1 >> 13) + (L_tmp2 << 2); /* coeff Q12 --> Q13 */ + + y2_hi = y1_hi; + y2_lo = y1_lo; + /* signal is divided by 16 to avoid overflow in energy computation */ + signal[i] = (int16)((L_tmp1 + 0x00008000) >> 16); + + y1_hi = (int16)(L_tmp1 >> 16); + y1_lo = (int16)((L_tmp1 - (y1_hi << 16)) >> 1); + + + } + + + mem[0] = y2_hi; + mem[1] = y2_lo; + mem[2] = y1_hi; + mem[3] = y1_lo; + mem[4] = x0; + mem[5] = x1; + +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/highpass_50hz_at_12k8.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/highpass_50hz_at_12k8.cpp new file mode 100644 index 00000000..f78f5b44 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/highpass_50hz_at_12k8.cpp @@ -0,0 +1,197 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: highpass_50Hz_at_12k8.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 signal[], input signal / output is divided by 16 + int16 lg, lenght of signal + int16 mem[] filter memory [6] + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + 2nd order high pass filter with cut off frequency at 31 Hz. + Designed with cheby2 function in MATLAB. + Optimized for fixed-point to get the following frequency response: + + frequency: 0Hz 14Hz 24Hz 31Hz 37Hz 41Hz 47Hz + dB loss: -infdB -15dB -6dB -3dB -1.5dB -1dB -0.5dB + + Algorithm: + + y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] + + a[1]*y[i-1] + a[2]*y[i-2]; + + int16 b[3] = {4053, -8106, 4053}; in Q12 + int16 a[3] = {8192, 16211, -8021}; in Q12 + + float --> b[3] = {0.989501953, -1.979003906, 0.989501953}; + a[3] = {1.000000000, 1.978881836, -0.979125977}; + + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwb_math_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void highpass_50Hz_at_12k8_init(int16 mem[]) +{ + pv_memset((void *)mem, 0, 6*sizeof(*mem)); +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void highpass_50Hz_at_12k8( + int16 signal[], /* input/output signal */ + int16 lg, /* lenght of signal */ + int16 mem[] /* filter memory [6] */ +) +{ + int16 i, x2; + int16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1; + int32 L_tmp1; + int32 L_tmp2; + int16 *pt_sign = signal; + + y2_hi = mem[0]; + y2_lo = mem[1]; + y1_hi = mem[2]; + y1_lo = mem[3]; + x0 = mem[4]; + x1 = mem[5]; + + + for (i = lg; i != 0; i--) + { + + /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[0]*x[i-2] */ + /* + a[0]*y[i-1] + a[1] * y[i-2]; */ + + L_tmp1 = fxp_mac_16by16(y1_lo, 16211, 8192L); + L_tmp1 = fxp_mac_16by16(y2_lo, -8021, L_tmp1); + L_tmp2 = fxp_mul_16by16(y1_hi, 32422); + L_tmp2 = fxp_mac_16by16(y2_hi, -16042, L_tmp2); + + x2 = x1; + x1 = x0; + x0 = *pt_sign; + L_tmp2 = fxp_mac_16by16(x2, 8106, L_tmp2); + L_tmp2 = fxp_mac_16by16(x1, -16212, L_tmp2); + L_tmp2 = fxp_mac_16by16(x0, 8106, L_tmp2); + + + L_tmp1 = ((L_tmp1 >> 14) + L_tmp2) << 2; + + y2_hi = y1_hi; + y2_lo = y1_lo; + y1_hi = (int16)(L_tmp1 >> 16); + y1_lo = (int16)((L_tmp1 - (y1_hi << 16)) >> 1); + + /* coeff Q14 --> Q15 with saturation */ + *(pt_sign++) = amr_wb_shl1_round(L_tmp1); + + } + + + mem[0] = y2_hi; + mem[1] = y2_lo; + mem[2] = y1_hi; + mem[3] = y1_lo; + mem[4] = x0; + mem[5] = x1; + +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/homing_amr_wb_dec.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/homing_amr_wb_dec.cpp new file mode 100644 index 00000000..987b700b --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/homing_amr_wb_dec.cpp @@ -0,0 +1,362 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: homing_amr_wb_dec.cpp + +------------------------------------------------------------------------------ + + + +INPUT AND OUTPUT DEFINITIONS + +Input + int16 input_frame[], 16-bit input frame + int16 mode 16-bit mode + int16 nparms 16-bit number of parameters +Returns + Int16 i number of leading zeros on x + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Performs the homing routines + + int16 dhf_test(int16 input_frame[], int16 mode, int16 nparms) + int16 decoder_homing_frame_test(int16 input_frame[], int16 mode) + int16 decoder_homing_frame_test_first(int16 input_frame[], int16 mode) + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder.h" +#include "pvamrwbdecoder_basic_op.h" +#include "get_amr_wb_bits.h" +#include "pvamrwbdecoder_api.h" +#include "pvamrwbdecoder.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define DHF_PARMS_MAX 32 /* homing frame pattern */ +#define NUM_OF_SPMODES 9 + +#define PRML 15 +#define PRMN_7k NBBITS_7k/PRML + 1 +#define PRMN_9k NBBITS_9k/PRML + 1 +#define PRMN_12k NBBITS_12k/PRML + 1 +#define PRMN_14k NBBITS_14k/PRML + 1 +#define PRMN_16k NBBITS_16k/PRML + 1 +#define PRMN_18k NBBITS_18k/PRML + 1 +#define PRMN_20k NBBITS_20k/PRML + 1 +#define PRMN_23k NBBITS_23k/PRML + 1 +#define PRMN_24k NBBITS_24k/PRML + 1 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + int16 dhf_test(int16 input_frame[], int32 mode, int16 nparms); + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ +static const int16 prmnofsf[NUM_OF_SPMODES] = +{ + 63, 81, 100, + 108, 116, 128, + 136, 152, 156 +}; + + +const int16 dfh_M7k[PRMN_7k] = +{ + 3168, 29954, 29213, 16121, + 64, 13440, 30624, 16430, + 19008 +}; + +const int16 dfh_M9k[PRMN_9k] = +{ + 3168, 31665, 9943, 9123, + 15599, 4358, 20248, 2048, + 17040, 27787, 16816, 13888 +}; + +const int16 dfh_M12k[PRMN_12k] = +{ + 3168, 31665, 9943, 9128, + 3647, 8129, 30930, 27926, + 18880, 12319, 496, 1042, + 4061, 20446, 25629, 28069, + 13948 +}; + +const int16 dfh_M14k[PRMN_14k] = +{ + 3168, 31665, 9943, 9131, + 24815, 655, 26616, 26764, + 7238, 19136, 6144, 88, + 4158, 25733, 30567, 30494, + 221, 20321, 17823 +}; + +const int16 dfh_M16k[PRMN_16k] = +{ + 3168, 31665, 9943, 9131, + 24815, 700, 3824, 7271, + 26400, 9528, 6594, 26112, + 108, 2068, 12867, 16317, + 23035, 24632, 7528, 1752, + 6759, 24576 +}; + +const int16 dfh_M18k[PRMN_18k] = +{ + 3168, 31665, 9943, 9135, + 14787, 14423, 30477, 24927, + 25345, 30154, 916, 5728, + 18978, 2048, 528, 16449, + 2436, 3581, 23527, 29479, + 8237, 16810, 27091, 19052, + 0 +}; + +const int16 dfh_M20k[PRMN_20k] = +{ + 3168, 31665, 9943, 9129, + 8637, 31807, 24646, 736, + 28643, 2977, 2566, 25564, + 12930, 13960, 2048, 834, + 3270, 4100, 26920, 16237, + 31227, 17667, 15059, 20589, + 30249, 29123, 0 +}; + +const int16 dfh_M23k[PRMN_23k] = +{ + 3168, 31665, 9943, 9132, + 16748, 3202, 28179, 16317, + 30590, 15857, 19960, 8818, + 21711, 21538, 4260, 16690, + 20224, 3666, 4194, 9497, + 16320, 15388, 5755, 31551, + 14080, 3574, 15932, 50, + 23392, 26053, 31216 +}; + +const int16 dfh_M24k[PRMN_24k] = +{ + 3168, 31665, 9943, 9134, + 24776, 5857, 18475, 28535, + 29662, 14321, 16725, 4396, + 29353, 10003, 17068, 20504, + 720, 0, 8465, 12581, + 28863, 24774, 9709, 26043, + 7941, 27649, 13965, 15236, + 18026, 22047, 16681, 3968 +}; + + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +int16 dhf_test(int16 input_frame[], int32 mode, int16 nparms) +{ + int16 i, j, tmp, shift; + int16 param[DHF_PARMS_MAX]; + int16 *prms; + + /* overall table with the parameters of the + decoder homing frames for all modes */ + + const int16 *dhf[] = + { + dfh_M7k, + dfh_M9k, + dfh_M12k, + dfh_M14k, + dfh_M16k, + dfh_M18k, + dfh_M20k, + dfh_M23k, + dfh_M24k, + dfh_M24k + }; + + prms = input_frame; + j = 0; + i = 0; + + if (mode != MRDTX) + { + if (mode != MODE_24k) + { + /* convert the received serial bits */ + tmp = nparms - 15; + while (tmp > j) + { + param[i] = Serial_parm(15, &prms); + j += 15; + i++; + } + tmp = nparms - j; + param[i] = Serial_parm(tmp, &prms); + shift = 15 - tmp; + param[i] = shl_int16(param[i], shift); + } + else + { + /*If mode is 23.85Kbit/s, remove high band energy bits */ + for (i = 0; i < 10; i++) + { + param[i] = Serial_parm(15, &prms); + } + param[10] = Serial_parm(15, &prms) & 0x61FF; + + for (i = 11; i < 17; i++) + { + param[i] = Serial_parm(15, &prms); + } + param[17] = Serial_parm(15, &prms) & 0xE0FF; + + for (i = 18; i < 24; i++) + { + param[i] = Serial_parm(15, &prms); + } + param[24] = Serial_parm(15, &prms) & 0x7F0F; + + for (i = 25; i < 31; i++) + { + param[i] = Serial_parm(15, &prms); + } + + tmp = Serial_parm(8, &prms); + param[31] = shl_int16(tmp, 7); + shift = 0; + } + + /* check if the parameters matches the parameters of the corresponding decoder homing frame */ + tmp = i; + j = 0; + for (i = 0; i < tmp; i++) + { + j = (param[i] ^ dhf[mode][i]); + if (j) + { + break; + } + } + tmp = 0x7fff; + tmp >>= shift; + tmp = shl_int16(tmp, shift); + tmp = (dhf[mode][i] & tmp); + tmp = (param[i] ^ tmp); + j = (int16)(j | tmp); + + } + else + { + j = 1; + } + + return (!j); +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +int16 pvDecoder_AmrWb_homing_frame_test(int16 input_frame[], int16 mode) +{ + /* perform test for COMPLETE parameter frame */ + return dhf_test(input_frame, mode, AMR_WB_COMPRESSED[mode]); +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +int16 pvDecoder_AmrWb_homing_frame_test_first(int16 input_frame[], int16 mode) +{ + /* perform test for FIRST SUBFRAME of parameter frame ONLY */ + return dhf_test(input_frame, mode, prmnofsf[mode]); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/interpolate_isp.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/interpolate_isp.cpp new file mode 100644 index 00000000..08046c66 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/interpolate_isp.cpp @@ -0,0 +1,138 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: interpolate_isp.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 isp_old[], input : isps from past frame + int16 isp_new[], input : isps from present frame + const int16 frac[], input : fraction for 3 first subfr (Q15) + int16 Az[] output: LP coefficients in 4 subframes + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Interpolation of the LP parameters in 4 subframes + + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +#define MP1 (M+1) + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void interpolate_isp( + int16 isp_old[], /* input : isps from past frame */ + int16 isp_new[], /* input : isps from present frame */ + const int16 frac[], /* input : fraction for 3 first subfr (Q15) */ + int16 Az[] /* output: LP coefficients in 4 subframes */ +) +{ + int16 i, k, fac_old, fac_new; + int16 isp[M]; + int32 L_tmp; + + for (k = 0; k < 3; k++) + { + fac_new = frac[k]; + fac_old = add_int16(sub_int16(32767, fac_new), 1); /* 1.0 - fac_new */ + + for (i = 0; i < M; i++) + { + L_tmp = mul_16by16_to_int32(isp_old[i], fac_old); + L_tmp = mac_16by16_to_int32(L_tmp, isp_new[i], fac_new); + isp[i] = amr_wb_round(L_tmp); + } + Isp_Az(isp, Az, M, 0); + Az += MP1; + } + + /* 4th subframe: isp_new (frac=1.0) */ + + Isp_Az(isp_new, Az, M, 0); + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/isf_extrapolation.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/isf_extrapolation.cpp new file mode 100644 index 00000000..b421e879 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/isf_extrapolation.cpp @@ -0,0 +1,266 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: isf_extrapolation.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 HfIsf[] (i/o) isf vector + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Conversion of 16th-order 12.8kHz ISF vector + into 20th-order 16kHz ISF vector + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" +#include "pvamrwb_math_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define INV_LENGTH 2731 /* 1/12 */ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +void isf_extrapolation(int16 HfIsf[]) +{ + int16 IsfDiff[M - 2]; + int32 IsfCorr[3]; + int32 L_tmp; + int16 coeff, mean, tmp, tmp2, tmp3; + int16 exp, exp2, hi, lo; + int16 i, MaxCorr; + + HfIsf[M16k - 1] = HfIsf[M - 1]; + + /* Difference vector */ + for (i = 1; i < (M - 1); i++) + { + IsfDiff[i - 1] = sub_int16(HfIsf[i], HfIsf[i - 1]); + } + L_tmp = 0; + + /* Mean of difference vector */ + for (i = 3; i < (M - 1); i++) + { + L_tmp = mac_16by16_to_int32(L_tmp, IsfDiff[i - 1], INV_LENGTH); + + } + mean = amr_wb_round(L_tmp); + + IsfCorr[0] = 0; + + tmp = 0; + for (i = 0; i < (M - 2); i++) + { + if (IsfDiff[i] > tmp) + { + tmp = IsfDiff[i]; + } + } + exp = norm_s(tmp); + for (i = 0; i < (M - 2); i++) + { + IsfDiff[i] = shl_int16(IsfDiff[i], exp); + } + mean = shl_int16(mean, exp); + for (i = 7; i < (M - 2); i++) + { + tmp2 = sub_int16(IsfDiff[i], mean); + tmp3 = sub_int16(IsfDiff[i - 2], mean); + L_tmp = mul_16by16_to_int32(tmp2, tmp3); + int32_to_dpf(L_tmp, &hi, &lo); + L_tmp = mpy_dpf_32(hi, lo, hi, lo); + IsfCorr[0] = add_int32(IsfCorr[0], L_tmp); + } + IsfCorr[1] = 0; + for (i = 7; i < (M - 2); i++) + { + tmp2 = sub_int16(IsfDiff[i], mean); + tmp3 = sub_int16(IsfDiff[i - 3], mean); + L_tmp = mul_16by16_to_int32(tmp2, tmp3); + int32_to_dpf(L_tmp, &hi, &lo); + L_tmp = mpy_dpf_32(hi, lo, hi, lo); + IsfCorr[1] = add_int32(IsfCorr[1], L_tmp); + } + IsfCorr[2] = 0; + for (i = 7; i < (M - 2); i++) + { + tmp2 = sub_int16(IsfDiff[i], mean); + tmp3 = sub_int16(IsfDiff[i - 4], mean); + L_tmp = mul_16by16_to_int32(tmp2, tmp3); + int32_to_dpf(L_tmp, &hi, &lo); + L_tmp = mpy_dpf_32(hi, lo, hi, lo); + IsfCorr[2] = add_int32(IsfCorr[2], L_tmp); + } + + if (IsfCorr[0] > IsfCorr[1]) + { + MaxCorr = 0; + } + else + { + MaxCorr = 1; + } + + + if (IsfCorr[2] > IsfCorr[MaxCorr]) + { + MaxCorr = 2; + } + + MaxCorr++; /* Maximum correlation of difference vector */ + + for (i = M - 1; i < (M16k - 1); i++) + { + tmp = sub_int16(HfIsf[i - 1 - MaxCorr], HfIsf[i - 2 - MaxCorr]); + HfIsf[i] = add_int16(HfIsf[i - 1], tmp); + } + + /* tmp=7965+(HfIsf[2]-HfIsf[3]-HfIsf[4])/6; */ + tmp = add_int16(HfIsf[4], HfIsf[3]); + tmp = sub_int16(HfIsf[2], tmp); + tmp = mult_int16(tmp, 5461); + tmp += 20390; + + + if (tmp > 19456) + { /* Maximum value of ISF should be at most 7600 Hz */ + tmp = 19456; + } + tmp = sub_int16(tmp, HfIsf[M - 2]); + tmp2 = sub_int16(HfIsf[M16k - 2], HfIsf[M - 2]); + + exp2 = norm_s(tmp2); + exp = norm_s(tmp); + exp--; + tmp <<= exp; + tmp2 <<= exp2; + coeff = div_16by16(tmp, tmp2); /* Coefficient for stretching the ISF vector */ + exp = exp2 - exp; + + for (i = M - 1; i < (M16k - 1); i++) + { + tmp = mult_int16(sub_int16(HfIsf[i], HfIsf[i - 1]), coeff); + IsfDiff[i - (M - 1)] = shl_int16(tmp, exp); + } + + for (i = M; i < (M16k - 1); i++) + { + /* The difference between ISF(n) and ISF(n-2) should be at least 500 Hz */ + tmp = IsfDiff[i - (M - 1)] + IsfDiff[i - M] - 1280; + + if (tmp < 0) + { + + if (IsfDiff[i - (M - 1)] > IsfDiff[i - M]) + { + IsfDiff[i - M] = 1280 - IsfDiff[i - (M - 1)]; + } + else + { + IsfDiff[i - (M - 1)] = 1280 - IsfDiff[i - M]; + } + } + } + + for (i = M - 1; i < (M16k - 1); i++) + { + HfIsf[i] = add_int16(HfIsf[i - 1], IsfDiff[i - (M - 1)]); + } + + for (i = 0; i < (M16k - 1); i++) + { + HfIsf[i] = mult_int16(HfIsf[i], 26214); /* Scale the ISF vector correctly for 16000 kHz */ + } + + Isf_isp(HfIsf, HfIsf, M16k); + + return; +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/isp_az.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/isp_az.cpp new file mode 100644 index 00000000..e353f31f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/isp_az.cpp @@ -0,0 +1,391 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: isp_az.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 isp[], (i) Q15 : Immittance spectral pairs + int16 a[], (o) Q12 : predictor coefficients (order=M) + int16 m, (i) : order + int16 adaptive_scaling (i) 0 : adaptive scaling disabled + 1 : adaptive scaling enabled + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Compute the LPC coefficients from isp (order=M) +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" +#include "pvamrwb_math_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define NC (M/2) +#define NC16k (M16k/2) + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif + + void Get_isp_pol(int16 * isp, int32 * f, int16 n); + void Get_isp_pol_16kHz(int16 * isp, int32 * f, int16 n); + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void Isp_Az( + int16 isp[], /* (i) Q15 : Immittance spectral pairs */ + int16 a[], /* (o) Q12 : predictor coefficients (order=M) */ + int16 m, /* (i) : order */ + int16 adaptive_scaling /* (i) 0 : adaptive scaling disabled */ + /* 1 : adaptive scaling enabled */ +) +{ + int16 i, j; + int32 f1[NC16k + 1], f2[NC16k]; + int16 nc; + int32 t0; + int32 t1; + int16 q, q_sug; + int32 tmax; + + nc = m >> 1; + + + if (nc > 8) + { + Get_isp_pol_16kHz(&isp[0], f1, nc); + for (i = 0; i <= nc; i++) + { + f1[i] = shl_int32(f1[i], 2); + } + Get_isp_pol_16kHz(&isp[1], f2, nc - 1); + for (i = 0; i <= nc - 1; i++) + { + f2[i] = shl_int32(f2[i], 2); + } + } + else + { + Get_isp_pol(&isp[0], f1, nc); + Get_isp_pol(&isp[1], f2, nc - 1); + } + + /* + * Multiply F2(z) by (1 - z^-2) + */ + + for (i = nc - 1; i > 1; i--) + { + f2[i] -= f2[i - 2]; /* f2[i] -= f2[i-2]; */ + } + + /* + * Scale F1(z) by (1+isp[m-1]) and F2(z) by (1-isp[m-1]) + */ + + for (i = 0; i < nc; i++) + { + /* f1[i] *= (1.0 + isp[M-1]); */ + + /* f2[i] *= (1.0 - isp[M-1]); */ + t0 = f1[i]; + t1 = f2[i]; + t0 = fxp_mul32_by_16b(t0, isp[m - 1]) << 1; + t1 = fxp_mul32_by_16b(t1, isp[m - 1]) << 1; + f1[i] += t0; + f2[i] -= t1; + + } + + /* + * A(z) = (F1(z)+F2(z))/2 + * F1(z) is symmetric and F2(z) is antisymmetric + */ + + /* a[0] = 1.0; */ + a[0] = 4096; + tmax = 1; + j = m - 1; + for (i = 1; i < nc; i++) + { + /* a[i] = 0.5*(f1[i] + f2[i]); */ + + t0 = add_int32(f1[i], f2[i]); /* f1[i] + f2[i] */ + /* compute t1 = abs(t0) */ + t1 = t0 - (t0 < 0); + t1 = t1 ^(t1 >> 31); /* t1 = t1 ^sign(t1) */ + + tmax |= t1; + /* from Q23 to Q12 and * 0.5 */ + a[i] = (int16)((t0 >> 12) + ((t0 >> 11) & 1)); + + + /* a[j] = 0.5*(f1[i] - f2[i]); */ + + t0 = sub_int32(f1[i], f2[i]); /* f1[i] - f2[i] */ + /* compute t1 = abs(t0) */ + t1 = t0 - (t0 < 0); + t1 = t1 ^(t1 >> 31); /* t1 = t1 ^sign(t1) */ + + tmax |= t1; + + /* from Q23 to Q12 and * 0.5 */ + a[j--] = (int16)((t0 >> 12) + ((t0 >> 11) & 1)); + + } + + /* rescale data if overflow has occured and reprocess the loop */ + + + if (adaptive_scaling == 1) + { + q = 4 - normalize_amr_wb(tmax); /* adaptive scaling enabled */ + } + else + { + q = 0; /* adaptive scaling disabled */ + } + + + if (q > 0) + { + q_sug = 12 + q; + for (i = 1, j = m - 1; i < nc; i++, j--) + { + /* a[i] = 0.5*(f1[i] + f2[i]); */ + + t0 = add_int32(f1[i], f2[i]); /* f1[i] + f2[i] */ + /* from Q23 to Q12 and * 0.5 */ + a[i] = (int16)((t0 >> q_sug) + ((t0 >> (q_sug - 1)) & 1)); + + + /* a[j] = 0.5*(f1[i] - f2[i]); */ + + t0 = sub_int32(f1[i], f2[i]); /* f1[i] - f2[i] */ + /* from Q23 to Q12 and * 0.5 */ + a[j] = (int16)((t0 >> q_sug) + ((t0 >> (q_sug - 1)) & 1)); + + } + a[0] >>= q; + } + else + { + q_sug = 12; + q = 0; + } + + /* a[NC] = 0.5*f1[NC]*(1.0 + isp[M-1]); */ + t0 = (int32)(((int64)f1[nc] * isp[m - 1]) >> 16) << 1; + t0 = add_int32(f1[nc], t0); + + /* from Q23 to Q12 and * 0.5 */ + a[nc] = (int16)((t0 >> q_sug) + ((t0 >> (q_sug - 1)) & 1)); + a[m] = shr_rnd(isp[m - 1], (3 + q)); /* from Q15 to Q12 */ + + /* a[m] = isp[m-1]; */ + + + return; +} + + + +/* +Get_isp_pol +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + isp[] : isp vector (cosine domaine) in Q15 + f[] : the coefficients of F1 or F2 in Q23 + n : == NC for F1(z); == NC-1 for F2(z) + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Find the polynomial F1(z) or F2(z) from the ISPs. + This is performed by expanding the product polynomials: + + F1(z) = product ( 1 - 2 isp_i z^-1 + z^-2 ) + i=0,2,4,6,8 + F2(z) = product ( 1 - 2 isp_i z^-1 + z^-2 ) + i=1,3,5,7 + + where isp_i are the ISPs in the cosine domain. +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +void Get_isp_pol(int16 * isp, int32 * f, int16 n) +{ + int16 i, j; + int32 t0; + + + /* All computation in Q23 */ + + f[0] = 0x00800000; /* f[0] = 1.0; in Q23 */ + f[1] = -isp[0] << 9; /* f[1] = -2.0*isp[0] in Q23 */ + + f += 2; /* Advance f pointer */ + isp += 2; /* Advance isp pointer */ + + for (i = 2; i <= n; i++) + { + *f = f[-2]; + + for (j = 1; j < i; j++) + { + + t0 = fxp_mul32_by_16b(f[-1], *isp); + t0 = shl_int32(t0, 2); + + *f -= t0; /* *f -= t0 */ + *(f) += f[-2]; /* *f += f[-2] */ + f--; + + + } + *f -= *isp << 9; + + f += i; /* Advance f pointer */ + isp += 2; /* Advance isp pointer */ + } +} + +void Get_isp_pol_16kHz(int16 * isp, int32 * f, int16 n) +{ + int16 i, j; + int32 t0; + + /* All computation in Q23 */ + + f[0] = 0x00200000; /* f[0] = 0.25; in Q23 */ + + f[1] = -isp[0] << 7; /* f[1] = -0.5*isp[0] in Q23 */ + + f += 2; /* Advance f pointer */ + isp += 2; /* Advance isp pointer */ + + for (i = 2; i <= n; i++) + { + *f = f[-2]; + + for (j = 1; j < i; j++, f--) + { + t0 = fxp_mul32_by_16b(f[-1], *isp); + t0 = shl_int32(t0, 2); + + *f -= t0; /* *f -= t0 */ + *f += f[-2]; /* *f += f[-2] */ + } + *f -= *isp << 7; + f += i; /* Advance f pointer */ + isp += 2; /* Advance isp pointer */ + } + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/isp_isf.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/isp_isf.cpp new file mode 100644 index 00000000..8cc13b52 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/isp_isf.cpp @@ -0,0 +1,167 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: isp_isf.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 isf[], (i) Q15 : isf[m] normalized (range: 0.0<=val<=0.5) + int16 isp[], (o) Q15 : isp[m] (range: -1<=val<1) + int16 m (i) : LPC order + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Isf_isp Transformation isf to isp + + The transformation from isf[i] to isp[i] is + approximated by a look-up table and interpolation. + + + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* Look-up table for transformations */ + +/* table of cos(x) in Q15 */ + +static const int16 table[129] = +{ + 32767, + 32758, 32729, 32679, 32610, 32522, 32413, 32286, 32138, + 31972, 31786, 31581, 31357, 31114, 30853, 30572, 30274, + 29957, 29622, 29269, 28899, 28511, 28106, 27684, 27246, + 26791, 26320, 25833, 25330, 24812, 24279, 23732, 23170, + 22595, 22006, 21403, 20788, 20160, 19520, 18868, 18205, + 17531, 16846, 16151, 15447, 14733, 14010, 13279, 12540, + 11793, 11039, 10279, 9512, 8740, 7962, 7180, 6393, + 5602, 4808, 4011, 3212, 2411, 1608, 804, 0, + -804, -1608, -2411, -3212, -4011, -4808, -5602, -6393, + -7180, -7962, -8740, -9512, -10279, -11039, -11793, -12540, + -13279, -14010, -14733, -15447, -16151, -16846, -17531, -18205, + -18868, -19520, -20160, -20788, -21403, -22006, -22595, -23170, + -23732, -24279, -24812, -25330, -25833, -26320, -26791, -27246, + -27684, -28106, -28511, -28899, -29269, -29622, -29957, -30274, + -30572, -30853, -31114, -31357, -31581, -31786, -31972, -32138, + -32286, -32413, -32522, -32610, -32679, -32729, -32758, -32768 +}; + + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +void Isf_isp( + int16 isf[], /* (i) Q15 : isf[m] normalized (range: 0.0<=val<=0.5) */ + int16 isp[], /* (o) Q15 : isp[m] (range: -1<=val<1) */ + int16 m /* (i) : LPC order */ +) +{ + int16 i, ind, offset; + int32 L_tmp; + + for (i = 0; i < m - 1; i++) + { + isp[i] = isf[i]; + } + isp[m - 1] = shl_int16(isf[m - 1], 1); + + for (i = 0; i < m; i++) + { + ind = isp[i] >> 7; /* ind = b7-b15 of isf[i] */ + offset = (isp[i] & 0x007f); /* offset = b0-b6 of isf[i] */ + + /* isp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 128 */ + + L_tmp = mul_16by16_to_int32(table[ind + 1] - table[ind], offset); + isp[i] = add_int16(table[ind], (int16)(L_tmp >> 8)); + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/lagconceal.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/lagconceal.cpp new file mode 100644 index 00000000..e4094746 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/lagconceal.cpp @@ -0,0 +1,356 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: lagconceal.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 gain_hist[], (i) : Gain history + int16 lag_hist[], (i) : Subframe size + int16 * T0, (i/o): current lag + int16 * old_T0, (i/o): previous lag + int16 * seed, + int16 unusable_frame + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Concealment of LTP lags during bad frames + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define L_LTPHIST 5 +#define ONE_PER_3 10923 +#define ONE_PER_LTPHIST 6554 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ +void insertion_sort(int16 array[], int16 n); +void insert(int16 array[], int16 num, int16 x); + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +void Init_Lagconc(int16 lag_hist[]) +{ + int16 i; + + for (i = 0; i < L_LTPHIST; i++) + { + lag_hist[i] = 64; + } +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void lagconceal( + int16 gain_hist[], /* (i) : Gain history */ + int16 lag_hist[], /* (i) : Subframe size */ + int16 * T0, + int16 * old_T0, + int16 * seed, + int16 unusable_frame +) +{ + int16 maxLag, minLag, lastLag, lagDif, meanLag = 0; + int16 lag_hist2[L_LTPHIST] = {0}; + int16 i, tmp, tmp2; + int16 minGain, lastGain, secLastGain; + int16 D, D2; + + /* Is lag index such that it can be aplied directly or does it has to be subtituted */ + + lastGain = gain_hist[4]; + secLastGain = gain_hist[3]; + + lastLag = lag_hist[0]; + + /******* SMALLEST history lag *******/ + minLag = lag_hist[0]; + /******* BIGGEST history lag *******/ + maxLag = lag_hist[0]; + for (i = 1; i < L_LTPHIST; i++) + { + if (lag_hist[i] < minLag) + { + minLag = lag_hist[i]; + } + if (lag_hist[i] > maxLag) + { + maxLag = lag_hist[i]; + } + } + /***********SMALLEST history gain***********/ + minGain = gain_hist[0]; + for (i = 1; i < L_LTPHIST; i++) + { + + if (gain_hist[i] < minGain) + { + minGain = gain_hist[i]; + } + } + /***Difference between MAX and MIN lag**/ + lagDif = sub_int16(maxLag, minLag); + + + if (unusable_frame != 0) + { + /* LTP-lag for RX_SPEECH_LOST */ + /**********Recognition of the LTP-history*********/ + + if ((minGain > 8192) && (lagDif < 10)) + { + *T0 = *old_T0; + } + else if (lastGain > 8192 && secLastGain > 8192) + { + *T0 = lag_hist[0]; + } + else + { + /********SORT************/ + /* The sorting of the lag history */ + for (i = 0; i < L_LTPHIST; i++) + { + lag_hist2[i] = lag_hist[i]; + } + insertion_sort(lag_hist2, 5); + + /* Lag is weighted towards bigger lags */ + /* and random variation is added */ + lagDif = sub_int16(lag_hist2[4], lag_hist2[2]); + + + if (lagDif > 40) + { + lagDif = 40; + } + + D = noise_gen_amrwb(seed); /* D={-1, ...,1} */ + /* D2={-lagDif/2..lagDif/2} */ + tmp = lagDif >> 1; + D2 = mult_int16(tmp, D); + tmp = add_int16(add_int16(lag_hist2[2], lag_hist2[3]), lag_hist2[4]); + *T0 = add_int16(mult_int16(tmp, ONE_PER_3), D2); + } + /* New lag is not allowed to be bigger or smaller than last lag values */ + + if (*T0 > maxLag) + { + *T0 = maxLag; + } + + if (*T0 < minLag) + { + *T0 = minLag; + } + } + else + { + /* LTP-lag for RX_BAD_FRAME */ + + /***********MEAN lag**************/ + meanLag = 0; + for (i = 0; i < L_LTPHIST; i++) + { + meanLag = add_int16(meanLag, lag_hist[i]); + } + meanLag = mult_int16(meanLag, ONE_PER_LTPHIST); + + tmp = *T0 - maxLag; + tmp2 = *T0 - lastLag; + + if ((lagDif < 10) && (*T0 > (minLag - 5)) && (tmp < 5)) + { + *T0 = *T0; + } + else if ((lastGain > 8192) && (secLastGain > 8192) && ((tmp2 + 10) > 0 && tmp2 < 10)) + { + *T0 = *T0; + } + else if ((minGain < 6554) && (lastGain == minGain) && (*T0 > minLag && *T0 < maxLag)) + { + *T0 = *T0; + } + else if ((lagDif < 70) && (*T0 > minLag) && (*T0 < maxLag)) + { + *T0 = *T0; + } + else if ((*T0 > meanLag) && (*T0 < maxLag)) + { + *T0 = *T0; + } + else + { + + + if ((minGain > 8192) & (lagDif < 10)) + { + *T0 = lag_hist[0]; + } + else if ((lastGain > 8192) && (secLastGain > 8192)) + { + *T0 = lag_hist[0]; + } + else + { + /********SORT************/ + /* The sorting of the lag history */ + for (i = 0; i < L_LTPHIST; i++) + { + lag_hist2[i] = lag_hist[i]; + } + insertion_sort(lag_hist2, 5); + + /* Lag is weighted towards bigger lags */ + /* and random variation is added */ + lagDif = sub_int16(lag_hist2[4], lag_hist2[2]); + + if (lagDif > 40) + { + lagDif = 40; + } + + D = noise_gen_amrwb(seed); /* D={-1,.., 1} */ + /* D2={-lagDif/2..lagDif/2} */ + tmp = lagDif >> 1; + D2 = mult_int16(tmp, D); + tmp = add_int16(add_int16(lag_hist2[2], lag_hist2[3]), lag_hist2[4]); + *T0 = add_int16(mult_int16(tmp, ONE_PER_3), D2); + } + /* New lag is not allowed to be bigger or smaller than last lag values */ + + if (*T0 > maxLag) + { + *T0 = maxLag; + } + + if (*T0 < minLag) + { + *T0 = minLag; + } + } + } +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void insertion_sort(int16 array[], int16 n) +{ + int16 i; + + for (i = 0; i < n; i++) + { + insert(array, i, array[i]); + } +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void insert(int16 array[], int16 n, int16 x) +{ + int16 i; + + for (i = (n - 1); i >= 0; i--) + { + + if (x < array[i]) + { + array[i + 1] = array[i]; + } + else + { + break; + } + } + array[i + 1] = x; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/low_pass_filt_7k.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/low_pass_filt_7k.cpp new file mode 100644 index 00000000..bb21cd93 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/low_pass_filt_7k.cpp @@ -0,0 +1,212 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: low_pass_filt_7k.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 signal[], input signal / output is divided by 16 + int16 lg, lenght of signal + int16 mem[] in/out: memory (size=30) + int16 x[] scratch mem ( size= 60) + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + 15th order high pass 7kHz FIR filter + + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define L_FIR 30 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ +const int16 fir_7k[L_FIR+1] = +{ + -21, 47, -89, 146, -203, + 229, -177, 0, 335, -839, + 1485, -2211, 2931, -3542, 3953, + 28682, 3953, -3542, 2931, -2211, + 1485, -839, 335, 0, -177, + 229, -203, 146, -89, 47, + -21 +}; + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +void low_pass_filt_7k_init(int16 mem[]) /* mem[30] */ +{ + pv_memset((void *)mem, 0, (L_FIR)*sizeof(*mem)); + + return; +} + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +void low_pass_filt_7k( + int16 signal[], /* input: signal */ + int16 lg, /* input: length of input */ + int16 mem[], /* in/out: memory (size=30) */ + int16 x[] +) +{ + int16 i, j; + int32 L_tmp1; + int32 L_tmp2; + int32 L_tmp3; + int32 L_tmp4; + + pv_memcpy((void *)x, (void *)mem, (L_FIR)*sizeof(*x)); + + for (i = 0; i < lg >> 2; i++) + { + x[(i<<2) + L_FIR ] = signal[(i<<2)]; + x[(i<<2) + L_FIR + 1] = signal[(i<<2)+1]; + x[(i<<2) + L_FIR + 2] = signal[(i<<2)+2]; + x[(i<<2) + L_FIR + 3] = signal[(i<<2)+3]; + + L_tmp1 = fxp_mac_16by16(x[(i<<2)] + signal[(i<<2)], fir_7k[0], 0x00004000); + L_tmp2 = fxp_mac_16by16(x[(i<<2)+1] + signal[(i<<2)+1], fir_7k[0], 0x00004000); + L_tmp3 = fxp_mac_16by16(x[(i<<2)+2] + signal[(i<<2)+2], fir_7k[0], 0x00004000); + L_tmp4 = fxp_mac_16by16(x[(i<<2)+3] + signal[(i<<2)+3], fir_7k[0], 0x00004000); + + for (j = 1; j < L_FIR - 1; j += 4) + { + + + int16 tmp1 = x[(i<<2)+j ]; + int16 tmp2 = x[(i<<2)+j+1]; + int16 tmp3 = x[(i<<2)+j+2]; + + L_tmp1 = fxp_mac_16by16(tmp1, fir_7k[j ], L_tmp1); + L_tmp2 = fxp_mac_16by16(tmp2, fir_7k[j ], L_tmp2); + L_tmp1 = fxp_mac_16by16(tmp2, fir_7k[j+1], L_tmp1); + L_tmp2 = fxp_mac_16by16(tmp3, fir_7k[j+1], L_tmp2); + L_tmp3 = fxp_mac_16by16(tmp3, fir_7k[j ], L_tmp3); + L_tmp1 = fxp_mac_16by16(tmp3, fir_7k[j+2], L_tmp1); + + tmp1 = x[(i<<2)+j+3]; + tmp2 = x[(i<<2)+j+4]; + + L_tmp2 = fxp_mac_16by16(tmp1, fir_7k[j+2], L_tmp2); + L_tmp4 = fxp_mac_16by16(tmp1, fir_7k[j ], L_tmp4); + L_tmp3 = fxp_mac_16by16(tmp1, fir_7k[j+1], L_tmp3); + L_tmp1 = fxp_mac_16by16(tmp1, fir_7k[j+3], L_tmp1); + L_tmp2 = fxp_mac_16by16(tmp2, fir_7k[j+3], L_tmp2); + L_tmp4 = fxp_mac_16by16(tmp2, fir_7k[j+1], L_tmp4); + L_tmp3 = fxp_mac_16by16(tmp2, fir_7k[j+2], L_tmp3); + + tmp1 = x[(i<<2)+j+5]; + tmp2 = x[(i<<2)+j+6]; + + L_tmp4 = fxp_mac_16by16(tmp1, fir_7k[j+2], L_tmp4); + L_tmp3 = fxp_mac_16by16(tmp1, fir_7k[j+3], L_tmp3); + L_tmp4 = fxp_mac_16by16(tmp2, fir_7k[j+3], L_tmp4); + + } + + L_tmp1 = fxp_mac_16by16(x[(i<<2)+j ], fir_7k[j ], L_tmp1); + L_tmp2 = fxp_mac_16by16(x[(i<<2)+j+1], fir_7k[j ], L_tmp2); + L_tmp3 = fxp_mac_16by16(x[(i<<2)+j+2], fir_7k[j ], L_tmp3); + L_tmp4 = fxp_mac_16by16(x[(i<<2)+j+3], fir_7k[j ], L_tmp4); + + signal[(i<<2)] = (int16)(L_tmp1 >> 15); + signal[(i<<2)+1] = (int16)(L_tmp2 >> 15); + signal[(i<<2)+2] = (int16)(L_tmp3 >> 15); + signal[(i<<2)+3] = (int16)(L_tmp4 >> 15); + + } + + pv_memcpy((void *)mem, (void *)(x + lg), (L_FIR)*sizeof(*mem)); + + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/median5.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/median5.cpp new file mode 100644 index 00000000..32d10afd --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/median5.cpp @@ -0,0 +1,172 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: median5.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + INPUT + X[-2:2] 16-bit integers. + + RETURN VALUE + The median of {X[-2], X[-1],..., X[2]}. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Returns the median of the set {X[-2], X[-1],..., X[2]}, + whose elements are 16-bit integers. + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_acelp.h" +#include "pvamrwb_math_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +int16 median5(int16 x[]) +{ + int16 x1, x2, x3, x4, x5; + int16 tmp; + + x1 = x[-2]; + x2 = x[-1]; + x3 = x[0]; + x4 = x[1]; + x5 = x[2]; + + + + if (x2 < x1) + { + tmp = x1; + x1 = x2; + x2 = tmp; + } + if (x3 < x1) + { + tmp = x1; + x1 = x3; + x3 = tmp; + } + if (x4 < x1) + { + tmp = x1; + x1 = x4; + x4 = tmp; + } + if (x5 < x1) + { + x5 = x1; + } + if (x3 < x2) + { + tmp = x2; + x2 = x3; + x3 = tmp; + } + if (x4 < x2) + { + tmp = x2; + x2 = x4; + x4 = tmp; + } + if (x5 < x2) + { + x5 = x2; + } + if (x4 < x3) + { + x3 = x4; + } + if (x5 < x3) + { + x3 = x5; + } + return (x3); +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/mime_io.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/mime_io.cpp new file mode 100644 index 00000000..beac1bb6 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/mime_io.cpp @@ -0,0 +1,721 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + Pathname: ./src/mime_io.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + [input_variable_name] = [description of the input to module, its type + definition, and length (when applicable)] + + Local Stores/Buffers/Pointers Needed: + [local_store_name] = [description of the local store, its type + definition, and length (when applicable)] + [local_buffer_name] = [description of the local buffer, its type + definition, and length (when applicable)] + [local_ptr_name] = [description of the local pointer, its type + definition, and length (when applicable)] + + Global Stores/Buffers/Pointers Needed: + [global_store_name] = [description of the global store, its type + definition, and length (when applicable)] + [global_buffer_name] = [description of the global buffer, its type + definition, and length (when applicable)] + [global_ptr_name] = [description of the global pointer, its type + definition, and length (when applicable)] + + Outputs: + [return_variable_name] = [description of data/pointer returned + by module, its type definition, and length + (when applicable)] + + Pointers and Buffers Modified: + [variable_bfr_ptr] points to the [describe where the + variable_bfr_ptr points to, its type definition, and length + (when applicable)] + [variable_bfr] contents are [describe the new contents of + variable_bfr] + + Local Stores Modified: + [local_store_name] = [describe new contents, its type + definition, and length (when applicable)] + + Global Stores Modified: + [global_store_name] = [describe new contents, its type + definition, and length (when applicable)] + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + [Describe what the module does by using the variable names + listed in the Input and Output Definitions Section above.] + +------------------------------------------------------------------------------ + REQUIREMENTS + + [List requirements to be satisfied by this module.] + +------------------------------------------------------------------------------ + REFERENCES + + [List all references used in designing this module.] + +------------------------------------------------------------------------------ + PSEUDO-CODE + + ------------------------------------------------------------------------------ + RESOURCES USED + + STACK USAGE: + + DATA MEMORY USED: x words + + PROGRAM MEMORY USED: x words + + CLOCK CYCLES: + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_api.h" +#include "pvamrwbdecoder.h" +#include "pvamrwbdecoder_mem_funcs.h" +#include "pvamrwbdecoder_cnst.h" +#include "dtx.h" +#include "mime_io.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +#define MRSID 9 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +const uint8 toc_byte[16] = {0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34, 0x3C, + 0x44, 0x4C, 0x54, 0x5C, 0x64, 0x6C, 0x74, 0x7C + }; + +/* number of speech bits for all modes */ +const int16 unpacked_size[16] = +{ + 132, 177, 253, 285, + 317, 365, 397, 461, + 477, 35, 0, 0, + 0, 0, 0, 0 +}; + +/* size of packed frame for each mode, excluding TOC byte */ +const int16 packed_size[16] = {17, 23, 32, 36, 40, 46, 50, 58, + 60, 5, 0, 0, 0, 0, 0, 0 + }; + +/* number of unused speech bits in packed format for each mode */ +const int16 unused_size[16] = {4, 7, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0}; + +/* sorting tables for all modes */ + +const int16 sort_660[132] = +{ + 0, 5, 6, 7, 61, 84, 107, 130, 62, 85, + 8, 4, 37, 38, 39, 40, 58, 81, 104, 127, + 60, 83, 106, 129, 108, 131, 128, 41, 42, 80, + 126, 1, 3, 57, 103, 82, 105, 59, 2, 63, + 109, 110, 86, 19, 22, 23, 64, 87, 18, 20, + 21, 17, 13, 88, 43, 89, 65, 111, 14, 24, + 25, 26, 27, 28, 15, 16, 44, 90, 66, 112, + 9, 11, 10, 12, 67, 113, 29, 30, 31, 32, + 34, 33, 35, 36, 45, 51, 68, 74, 91, 97, + 114, 120, 46, 69, 92, 115, 52, 75, 98, 121, + 47, 70, 93, 116, 53, 76, 99, 122, 48, 71, + 94, 117, 54, 77, 100, 123, 49, 72, 95, 118, + 55, 78, 101, 124, 50, 73, 96, 119, 56, 79, + 102, 125 +}; + +const int16 sort_885[177] = +{ + 0, 4, 6, 7, 5, 3, 47, 48, 49, 112, + 113, 114, 75, 106, 140, 171, 80, 111, 145, 176, + 77, 108, 142, 173, 78, 109, 143, 174, 79, 110, + 144, 175, 76, 107, 141, 172, 50, 115, 51, 2, + 1, 81, 116, 146, 19, 21, 12, 17, 18, 20, + 16, 25, 13, 10, 14, 24, 23, 22, 26, 8, + 15, 52, 117, 31, 82, 147, 9, 33, 11, 83, + 148, 53, 118, 28, 27, 84, 149, 34, 35, 29, + 46, 32, 30, 54, 119, 37, 36, 39, 38, 40, + 85, 150, 41, 42, 43, 44, 45, 55, 60, 65, + 70, 86, 91, 96, 101, 120, 125, 130, 135, 151, + 156, 161, 166, 56, 87, 121, 152, 61, 92, 126, + 157, 66, 97, 131, 162, 71, 102, 136, 167, 57, + 88, 122, 153, 62, 93, 127, 158, 67, 98, 132, + 163, 72, 103, 137, 168, 58, 89, 123, 154, 63, + 94, 128, 159, 68, 99, 133, 164, 73, 104, 138, + 169, 59, 90, 124, 155, 64, 95, 129, 160, 69, + 100, 134, 165, 74, 105, 139, 170 +}; + +const int16 sort_1265[253] = +{ + 0, 4, 6, 93, 143, 196, 246, 7, 5, 3, + 47, 48, 49, 50, 51, 150, 151, 152, 153, 154, + 94, 144, 197, 247, 99, 149, 202, 252, 96, 146, + 199, 249, 97, 147, 200, 250, 100, 203, 98, 148, + 201, 251, 95, 145, 198, 248, 52, 2, 1, 101, + 204, 155, 19, 21, 12, 17, 18, 20, 16, 25, + 13, 10, 14, 24, 23, 22, 26, 8, 15, 53, + 156, 31, 102, 205, 9, 33, 11, 103, 206, 54, + 157, 28, 27, 104, 207, 34, 35, 29, 46, 32, + 30, 55, 158, 37, 36, 39, 38, 40, 105, 208, + 41, 42, 43, 44, 45, 56, 106, 159, 209, 57, + 66, 75, 84, 107, 116, 125, 134, 160, 169, 178, + 187, 210, 219, 228, 237, 58, 108, 161, 211, 62, + 112, 165, 215, 67, 117, 170, 220, 71, 121, 174, + 224, 76, 126, 179, 229, 80, 130, 183, 233, 85, + 135, 188, 238, 89, 139, 192, 242, 59, 109, 162, + 212, 63, 113, 166, 216, 68, 118, 171, 221, 72, + 122, 175, 225, 77, 127, 180, 230, 81, 131, 184, + 234, 86, 136, 189, 239, 90, 140, 193, 243, 60, + 110, 163, 213, 64, 114, 167, 217, 69, 119, 172, + 222, 73, 123, 176, 226, 78, 128, 181, 231, 82, + 132, 185, 235, 87, 137, 190, 240, 91, 141, 194, + 244, 61, 111, 164, 214, 65, 115, 168, 218, 70, + 120, 173, 223, 74, 124, 177, 227, 79, 129, 182, + 232, 83, 133, 186, 236, 88, 138, 191, 241, 92, + 142, 195, 245 +}; + +const int16 sort_1425[285] = +{ + 0, 4, 6, 101, 159, 220, 278, 7, 5, 3, + 47, 48, 49, 50, 51, 166, 167, 168, 169, 170, + 102, 160, 221, 279, 107, 165, 226, 284, 104, 162, + 223, 281, 105, 163, 224, 282, 108, 227, 106, 164, + 225, 283, 103, 161, 222, 280, 52, 2, 1, 109, + 228, 171, 19, 21, 12, 17, 18, 20, 16, 25, + 13, 10, 14, 24, 23, 22, 26, 8, 15, 53, + 172, 31, 110, 229, 9, 33, 11, 111, 230, 54, + 173, 28, 27, 112, 231, 34, 35, 29, 46, 32, + 30, 55, 174, 37, 36, 39, 38, 40, 113, 232, + 41, 42, 43, 44, 45, 56, 114, 175, 233, 62, + 120, 181, 239, 75, 133, 194, 252, 57, 115, 176, + 234, 63, 121, 182, 240, 70, 128, 189, 247, 76, + 134, 195, 253, 83, 141, 202, 260, 92, 150, 211, + 269, 84, 142, 203, 261, 93, 151, 212, 270, 85, + 143, 204, 262, 94, 152, 213, 271, 86, 144, 205, + 263, 95, 153, 214, 272, 64, 122, 183, 241, 77, + 135, 196, 254, 65, 123, 184, 242, 78, 136, 197, + 255, 87, 145, 206, 264, 96, 154, 215, 273, 58, + 116, 177, 235, 66, 124, 185, 243, 71, 129, 190, + 248, 79, 137, 198, 256, 88, 146, 207, 265, 97, + 155, 216, 274, 59, 117, 178, 236, 67, 125, 186, + 244, 72, 130, 191, 249, 80, 138, 199, 257, 89, + 147, 208, 266, 98, 156, 217, 275, 60, 118, 179, + 237, 68, 126, 187, 245, 73, 131, 192, 250, 81, + 139, 200, 258, 90, 148, 209, 267, 99, 157, 218, + 276, 61, 119, 180, 238, 69, 127, 188, 246, 74, + 132, 193, 251, 82, 140, 201, 259, 91, 149, 210, + 268, 100, 158, 219, 277 +}; + +const int16 sort_1585[317] = +{ + 0, 4, 6, 109, 175, 244, 310, 7, 5, 3, + 47, 48, 49, 50, 51, 182, 183, 184, 185, 186, + 110, 176, 245, 311, 115, 181, 250, 316, 112, 178, + 247, 313, 113, 179, 248, 314, 116, 251, 114, 180, + 249, 315, 111, 177, 246, 312, 52, 2, 1, 117, + 252, 187, 19, 21, 12, 17, 18, 20, 16, 25, + 13, 10, 14, 24, 23, 22, 26, 8, 15, 53, + 188, 31, 118, 253, 9, 33, 11, 119, 254, 54, + 189, 28, 27, 120, 255, 34, 35, 29, 46, 32, + 30, 55, 190, 37, 36, 39, 38, 40, 121, 256, + 41, 42, 43, 44, 45, 56, 122, 191, 257, 63, + 129, 198, 264, 76, 142, 211, 277, 89, 155, 224, + 290, 102, 168, 237, 303, 57, 123, 192, 258, 70, + 136, 205, 271, 83, 149, 218, 284, 96, 162, 231, + 297, 62, 128, 197, 263, 75, 141, 210, 276, 88, + 154, 223, 289, 101, 167, 236, 302, 58, 124, 193, + 259, 71, 137, 206, 272, 84, 150, 219, 285, 97, + 163, 232, 298, 59, 125, 194, 260, 64, 130, 199, + 265, 67, 133, 202, 268, 72, 138, 207, 273, 77, + 143, 212, 278, 80, 146, 215, 281, 85, 151, 220, + 286, 90, 156, 225, 291, 93, 159, 228, 294, 98, + 164, 233, 299, 103, 169, 238, 304, 106, 172, 241, + 307, 60, 126, 195, 261, 65, 131, 200, 266, 68, + 134, 203, 269, 73, 139, 208, 274, 78, 144, 213, + 279, 81, 147, 216, 282, 86, 152, 221, 287, 91, + 157, 226, 292, 94, 160, 229, 295, 99, 165, 234, + 300, 104, 170, 239, 305, 107, 173, 242, 308, 61, + 127, 196, 262, 66, 132, 201, 267, 69, 135, 204, + 270, 74, 140, 209, 275, 79, 145, 214, 280, 82, + 148, 217, 283, 87, 153, 222, 288, 92, 158, 227, + 293, 95, 161, 230, 296, 100, 166, 235, 301, 105, + 171, 240, 306, 108, 174, 243, 309 +}; + +const int16 sort_1825[365] = +{ + 0, 4, 6, 121, 199, 280, 358, 7, 5, 3, + 47, 48, 49, 50, 51, 206, 207, 208, 209, 210, + 122, 200, 281, 359, 127, 205, 286, 364, 124, 202, + 283, 361, 125, 203, 284, 362, 128, 287, 126, 204, + 285, 363, 123, 201, 282, 360, 52, 2, 1, 129, + 288, 211, 19, 21, 12, 17, 18, 20, 16, 25, + 13, 10, 14, 24, 23, 22, 26, 8, 15, 53, + 212, 31, 130, 289, 9, 33, 11, 131, 290, 54, + 213, 28, 27, 132, 291, 34, 35, 29, 46, 32, + 30, 55, 214, 37, 36, 39, 38, 40, 133, 292, + 41, 42, 43, 44, 45, 56, 134, 215, 293, 198, + 299, 136, 120, 138, 60, 279, 58, 62, 357, 139, + 140, 295, 156, 57, 219, 297, 63, 217, 137, 170, + 300, 222, 64, 106, 61, 78, 294, 92, 142, 141, + 135, 221, 296, 301, 343, 59, 298, 184, 329, 315, + 220, 216, 265, 251, 218, 237, 352, 223, 157, 86, + 171, 87, 164, 351, 111, 302, 65, 178, 115, 323, + 72, 192, 101, 179, 93, 73, 193, 151, 337, 309, + 143, 274, 69, 324, 165, 150, 97, 338, 110, 310, + 330, 273, 68, 107, 175, 245, 114, 79, 113, 189, + 246, 259, 174, 71, 185, 96, 344, 100, 322, 83, + 334, 316, 333, 252, 161, 348, 147, 82, 269, 232, + 260, 308, 353, 347, 163, 231, 306, 320, 188, 270, + 146, 177, 266, 350, 256, 85, 149, 116, 191, 160, + 238, 258, 336, 305, 255, 88, 224, 99, 339, 230, + 228, 227, 272, 242, 241, 319, 233, 311, 102, 74, + 180, 275, 66, 194, 152, 325, 172, 247, 244, 261, + 117, 158, 166, 354, 75, 144, 108, 312, 94, 186, + 303, 80, 234, 89, 195, 112, 340, 181, 345, 317, + 326, 276, 239, 167, 118, 313, 70, 355, 327, 253, + 190, 176, 271, 104, 98, 153, 103, 90, 76, 267, + 277, 248, 225, 262, 182, 84, 154, 235, 335, 168, + 331, 196, 341, 249, 162, 307, 148, 349, 263, 321, + 257, 243, 229, 356, 159, 119, 67, 187, 173, 145, + 240, 77, 304, 332, 314, 342, 109, 254, 81, 278, + 105, 91, 346, 318, 183, 250, 197, 328, 95, 155, + 169, 268, 226, 236, 264 +}; + +const int16 sort_1985[397] = +{ + 0, 4, 6, 129, 215, 304, 390, 7, 5, 3, + 47, 48, 49, 50, 51, 222, 223, 224, 225, 226, + 130, 216, 305, 391, 135, 221, 310, 396, 132, 218, + 307, 393, 133, 219, 308, 394, 136, 311, 134, 220, + 309, 395, 131, 217, 306, 392, 52, 2, 1, 137, + 312, 227, 19, 21, 12, 17, 18, 20, 16, 25, + 13, 10, 14, 24, 23, 22, 26, 8, 15, 53, + 228, 31, 138, 313, 9, 33, 11, 139, 314, 54, + 229, 28, 27, 140, 315, 34, 35, 29, 46, 32, + 30, 55, 230, 37, 36, 39, 38, 40, 141, 316, + 41, 42, 43, 44, 45, 56, 142, 231, 317, 63, + 73, 92, 340, 82, 324, 149, 353, 159, 334, 165, + 338, 178, 163, 254, 77, 168, 257, 153, 343, 57, + 248, 238, 79, 252, 166, 67, 80, 201, 101, 267, + 143, 164, 341, 255, 339, 187, 376, 318, 78, 328, + 362, 115, 232, 242, 253, 290, 276, 62, 58, 158, + 68, 93, 179, 319, 148, 169, 154, 72, 385, 329, + 333, 344, 102, 83, 144, 233, 323, 124, 243, 192, + 354, 237, 64, 247, 202, 209, 150, 116, 335, 268, + 239, 299, 188, 196, 298, 94, 195, 258, 123, 363, + 384, 109, 325, 371, 170, 370, 84, 110, 295, 180, + 74, 210, 191, 106, 291, 205, 367, 381, 377, 206, + 355, 122, 119, 120, 383, 160, 105, 108, 277, 380, + 294, 284, 285, 345, 208, 269, 249, 366, 386, 300, + 297, 259, 125, 369, 197, 97, 194, 286, 211, 281, + 280, 183, 372, 87, 155, 283, 59, 348, 327, 184, + 76, 111, 330, 203, 349, 69, 98, 152, 145, 189, + 66, 320, 337, 173, 358, 251, 198, 174, 263, 262, + 126, 241, 193, 88, 388, 117, 95, 387, 112, 359, + 287, 244, 103, 272, 301, 171, 162, 234, 273, 127, + 373, 181, 292, 85, 378, 302, 121, 107, 364, 346, + 356, 212, 278, 213, 65, 382, 288, 207, 113, 175, + 99, 296, 374, 368, 199, 260, 185, 336, 331, 161, + 270, 264, 250, 240, 75, 350, 151, 60, 89, 321, + 156, 274, 360, 326, 70, 282, 167, 146, 352, 81, + 91, 389, 266, 245, 177, 235, 190, 256, 204, 342, + 128, 118, 303, 104, 379, 182, 114, 375, 200, 96, + 293, 172, 214, 365, 279, 86, 289, 351, 347, 357, + 261, 186, 176, 271, 90, 100, 147, 322, 275, 361, + 71, 332, 61, 265, 157, 246, 236 +}; + +const int16 sort_2305[461] = +{ + 0, 4, 6, 145, 247, 352, 454, 7, 5, 3, + 47, 48, 49, 50, 51, 254, 255, 256, 257, 258, + 146, 248, 353, 455, 151, 253, 358, 460, 148, 250, + 355, 457, 149, 251, 356, 458, 152, 359, 150, 252, + 357, 459, 147, 249, 354, 456, 52, 2, 1, 153, + 360, 259, 19, 21, 12, 17, 18, 20, 16, 25, + 13, 10, 14, 24, 23, 22, 26, 8, 15, 53, + 260, 31, 154, 361, 9, 33, 11, 155, 362, 54, + 261, 28, 27, 156, 363, 34, 35, 29, 46, 32, + 30, 55, 262, 37, 36, 39, 38, 40, 157, 364, + 41, 42, 43, 44, 45, 56, 158, 263, 365, 181, + 192, 170, 79, 57, 399, 90, 159, 297, 377, 366, + 275, 68, 183, 388, 286, 194, 299, 92 , 70, 182, + 401, 172, 59, 91, 58, 400, 368, 161, 81, 160, + 264, 171, 80, 389, 390, 378, 379, 193, 298, 69, + 266, 265, 367, 277, 288, 276, 287, 184, 60, 195, + 82, 93, 71, 369, 402, 173, 162, 444, 300, 391, + 98, 76, 278, 61, 267, 374, 135, 411, 167, 102, + 380, 200, 87, 178, 65, 94, 204, 124, 72, 342, + 189, 305, 381, 396, 433, 301, 226, 407, 289, 237, + 113, 215, 185, 128, 309, 403, 116, 320, 196, 331, + 370, 422, 174, 64, 392, 83, 425, 219, 134, 188, + 432, 112, 427, 139, 279, 163, 436, 208, 447, 218, + 236, 229, 97, 294, 385, 230, 166, 268, 177, 443, + 225, 426, 101, 272, 138, 127, 290, 117, 347, 199, + 414, 95, 140, 240, 410, 395, 209, 129, 283, 346, + 105, 241, 437, 86, 308, 448, 203, 345, 186, 107, + 220, 415, 334, 319, 106, 313, 118, 123, 73, 207, + 421, 214, 384, 373, 438, 62, 371, 341, 75, 449, + 168, 323, 164, 242, 416, 324, 304, 197, 335, 404, + 271, 63, 191, 325, 96, 169, 231, 280, 312, 187, + 406, 84, 201, 100, 67, 382, 175, 336, 202, 330, + 269, 393, 376, 383, 293, 307, 409, 179, 285, 314, + 302, 372, 398, 190, 180, 89, 99, 103, 232, 78, + 88, 77, 136, 387, 165, 198, 394, 125, 176, 428, + 74, 375, 238, 227, 66, 273, 282, 141, 306, 412, + 114, 85, 130, 348, 119, 291, 296, 386, 233, 397, + 303, 405, 284, 445, 423, 221, 210, 205, 450, 108, + 274, 434, 216, 343, 337, 142, 243, 321, 408, 451, + 310, 292, 120, 109, 281, 439, 270, 429, 332, 295, + 418, 211, 315, 222, 326, 131, 430, 244, 327, 349, + 417, 316, 143, 338, 440, 234, 110, 212, 452, 245, + 121, 419, 350, 223, 132, 441, 328, 413, 317, 339, + 126, 104, 137, 446, 344, 239, 435, 115, 333, 206, + 322, 217, 228, 424, 453, 311, 351, 111, 442, 224, + 213, 122, 431, 340, 235, 246, 133, 144, 420, 329, + 318 +}; + +const int16 sort_2385[477] = +{ + 0, 4, 6, 145, 251, 360, 466, 7, 5, 3, + 47, 48, 49, 50, 51, 262, 263, 264, 265, 266, + 146, 252, 361, 467, 151, 257, 366, 472, 148, 254, + 363, 469, 149, 255, 364, 470, 156, 371, 150, 256, + 365, 471, 147, 253, 362, 468, 52, 2, 1, 157, + 372, 267, 19, 21, 12, 17, 18, 20, 16, 25, + 13, 10, 14, 24, 23, 22, 26, 8, 15, 53, + 268, 31, 152, 153, 154, 155, 258, 259, 260, 261, + 367, 368, 369, 370, 473, 474, 475, 476, 158, 373, + 9, 33, 11, 159, 374, 54, 269, 28, 27, 160, + 375, 34, 35, 29, 46, 32, 30, 55, 270, 37, + 36, 39, 38, 40, 161, 376, 41, 42, 43, 44, + 45, 56, 162, 271, 377, 185, 196, 174, 79, 57, + 411, 90, 163, 305, 389, 378, 283, 68, 187, 400, + 294, 198, 307, 92, 70, 186, 413, 176, 59, 91, + 58, 412, 380, 165, 81, 164, 272, 175, 80, 401, + 402, 390, 391, 197, 306, 69, 274, 273, 379, 285, + 296, 284, 295, 188, 60, 199, 82, 93, 71, 381, + 414, 177, 166, 456, 308, 403, 98, 76, 286, 61, + 275, 386, 135, 423, 171, 102, 392, 204, 87, 182, + 65, 94, 208, 124, 72, 350, 193, 313, 393, 408, + 445, 309, 230, 419, 297, 241, 113, 219, 189, 128, + 317, 415, 116, 328, 200, 339, 382, 434, 178, 64, + 404, 83, 437, 223, 134, 192, 444, 112, 439, 139, + 287, 167, 448, 212, 459, 222, 240, 233, 97, 302, + 397, 234, 170, 276, 181, 455, 229, 438, 101, 280, + 138, 127, 298, 117, 355, 203, 426, 95, 140, 244, + 422, 407, 213, 129, 291, 354, 105, 245, 449, 86, + 316, 460, 207, 353, 190, 107, 224, 427, 342, 327, + 106, 321, 118, 123, 73, 211, 433, 218, 396, 385, + 450, 62, 383, 349, 75, 461, 172, 331, 168, 246, + 428, 332, 312, 201, 343, 416, 279, 63, 195, 333, + 96, 173, 235, 288, 320, 191, 418, 84, 205, 100, + 67, 394, 179, 344, 206, 338, 277, 405, 388, 395, + 301, 315, 421, 183, 293, 322, 310, 384, 410, 194, + 184, 89, 99, 103, 236, 78, 88, 77, 136, 399, + 169, 202, 406, 125, 180, 440, 74, 387, 242, 231, + 66, 281, 290, 141, 314, 424, 114, 85, 130, 356, + 119, 299, 304, 398, 237, 409, 311, 417, 292, 457, + 435, 225, 214, 209, 462, 108, 282, 446, 220, 351, + 345, 142, 247, 329, 420, 463, 318, 300, 120, 109, + 289, 451, 278, 441, 340, 303, 430, 215, 323, 226, + 334, 131, 442, 248, 335, 357, 429, 324, 143, 346, + 452, 238, 110, 216, 464, 249, 121, 431, 358, 227, + 132, 453, 336, 425, 325, 347, 126, 104, 137, 458, + 352, 243, 447, 115, 341, 210, 330, 221, 232, 436, + 465, 319, 359, 111, 454, 228, 217, 122, 443, 348, + 239, 250, 133, 144, 432, 337, 326 +}; + +const int16 sort_SID[35] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34 +}; + + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void mime_unsorting(uint8 unsorted_bits[], + int16 sorted_bits_into_int16[], + int16 * frame_type, + int16 * mode, + uint8 quality, + RX_State *st) +{ + + int16 i; + int16 j; + uint8 temp = 0; + uint8 *unsorted_bits_ptr = (uint8*)unsorted_bits; + + /* pointer table for bit sorting tables */ + const int16 *AmrWbSortingTables[16] = + { + sort_660, sort_885, sort_1265, sort_1425, + sort_1585, sort_1825, sort_1985, sort_2305, + sort_2385, sort_SID, NULL, NULL, + NULL, NULL, NULL, NULL + }; + + const int16 * pt_AmrWbSortingTables = AmrWbSortingTables[*mode]; + + /* clear compressed speech bit buffer */ + pv_memset(sorted_bits_into_int16, + 0, + unpacked_size[*mode]*sizeof(*sorted_bits_into_int16)); + + /* unpack and unsort speech or SID bits */ + + + for (i = unpacked_size[*mode] >> 3; i != 0; i--) + { + temp = *(unsorted_bits_ptr++); + + for (j = 2; j != 0; j--) + { + switch (temp & 0xf0) + { + case 0xf0: + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + break; + case 0xe0: + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + pt_AmrWbSortingTables++; + break; + case 0xd0: + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + pt_AmrWbSortingTables++; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + break; + case 0xc0: + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + pt_AmrWbSortingTables += 2; + break; + case 0xb0: + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + pt_AmrWbSortingTables++; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + break; + case 0xa0: + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + pt_AmrWbSortingTables++; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + pt_AmrWbSortingTables++; + break; + case 0x90: + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + pt_AmrWbSortingTables += 2; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + break; + case 0x80: + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + pt_AmrWbSortingTables += 3; + break; + case 0x70: + pt_AmrWbSortingTables++; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + break; + case 0x60: + pt_AmrWbSortingTables++; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + pt_AmrWbSortingTables++; + break; + case 0x50: + pt_AmrWbSortingTables++; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + pt_AmrWbSortingTables++; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + break; + case 0x40: + pt_AmrWbSortingTables++; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + pt_AmrWbSortingTables += 2; + break; + case 0x30: + pt_AmrWbSortingTables += 2; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + break; + case 0x20: + pt_AmrWbSortingTables += 2; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + pt_AmrWbSortingTables++; + break; + case 0x10: + pt_AmrWbSortingTables += 3; + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + break; + default: + pt_AmrWbSortingTables += 4; + break; + } + temp <<= 4; + } + } + + if (unpacked_size[*mode] % 4) + { + temp <<= 1; + + if (temp & 0x80) + { + sorted_bits_into_int16[*(pt_AmrWbSortingTables++)] = BIT_1; + } + } + + /* set frame type */ + switch (*mode) + { + case MODE_7k: + case MODE_9k: + case MODE_12k: + case MODE_14k: + case MODE_16k: + case MODE_18k: + case MODE_20k: + case MODE_23k: + case MODE_24k: + if (quality) + { + *frame_type = RX_SPEECH_GOOD; + } + else + { + *frame_type = RX_SPEECH_BAD; + } + break; + + case MRSID: + if (quality) + { + if (temp & 0x80) + { + *frame_type = RX_SID_UPDATE; + } + else + { + *frame_type = RX_SID_FIRST; + } + } + else + { + *frame_type = RX_SID_BAD; + } + + /* set mode index */ + *mode = st->prev_mode; + break; + case 14: /* SPEECH_LOST */ + *frame_type = RX_SPEECH_LOST; + *mode = st->prev_mode; + break; + case 15: /* NO_DATA */ + *frame_type = RX_NO_DATA; + *mode = st->prev_mode; + break; + default: /* replace frame with unused mode index by NO_DATA frame */ + *frame_type = RX_NO_DATA; + *mode = st->prev_mode; + break; + } + + st->prev_mode = *mode; + +} + + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/mime_io.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/mime_io.h new file mode 100644 index 00000000..9c040bc8 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/mime_io.h @@ -0,0 +1,118 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./cpp/include/mime_io.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +#ifndef MIME_IO_H +#define MIME_IO_H + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +----------------------------------------------------------------------------*/ + + + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +----------------------------------------------------------------------------*/ +extern const uint8 toc_byte[16]; + +/* number of speech bits for all modes */ +extern const int16 unpacked_size[16]; + +/* size of packed frame for each mode, excluding TOC byte */ +extern const int16 packed_size[16]; + +/* number of unused speech bits in packed format for each mode */ +extern const int16 unused_size[16]; + +/* sorting tables for all modes */ + +extern const int16 sort_660[132]; + +extern const int16 sort_885[177]; + +extern const int16 sort_1265[253]; + +extern const int16 sort_1425[285]; + +extern const int16 sort_1585[317]; + +extern const int16 sort_1825[365]; + +extern const int16 sort_1985[397]; + +extern const int16 sort_2305[461]; + +extern const int16 sort_2385[477]; + +extern const int16 sort_SID[35]; + + +/*---------------------------------------------------------------------------- +; SIMPLE TYPEDEF'S +----------------------------------------------------------------------------*/ + + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#ifdef __cplusplus +} +#endif + + + + +#endif /* MIME_IO_H */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/noise_gen_amrwb.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/noise_gen_amrwb.cpp new file mode 100644 index 00000000..2c3f2101 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/noise_gen_amrwb.cpp @@ -0,0 +1,110 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: noise_gen_amrwb.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 * seed seed for the random ng + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Signed 16 bits random generator + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +int16 noise_gen_amrwb(int16 * seed) +{ + /* int16 seed = 21845; */ + *seed = (int16)fxp_mac_16by16(*seed, 31821, 13849L); + + return (*seed); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/normalize_amr_wb.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/normalize_amr_wb.cpp new file mode 100644 index 00000000..bdca939f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/normalize_amr_wb.cpp @@ -0,0 +1,173 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: normalize_amr_wb.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + +Input + Int32 x 32-bit integer non-zero input +Returns + Int16 i number of leading zeros on x + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Returns number of leading zeros on the non-zero input + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "normalize_amr_wb.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +#if ((PV_CPU_ARCH_VERSION >=5) && ((PV_COMPILER == EPV_ARM_RVCT) || (PV_COMPILER == EPV_ARM_GNUC))) +/* function is inlined in header file */ + + +#else + +int16 normalize_amr_wb(int32 x) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + int16 i; + + + if (x > 0x0FFFFFFF) + { + i = 0; /* most likely case */ + } + else if (x > 0x00FFFFFF) + { + i = 3; /* second most likely case */ + } + else if (x > 0x0000FFFF) + { + i = x > 0x000FFFFF ? 7 : 11; + } + else + { + if (x > 0x000000FF) + { + i = x > 0x00000FFF ? 15 : 19; + } + else + { + i = x > 0x0000000F ? 23 : 27; + } + } + + + x <<= i; + + switch (x & 0x78000000) + { + case 0x08000000: + i += 3; + break; + + case 0x18000000: + case 0x10000000: + i += 2; + break; + case 0x28000000: + case 0x20000000: + case 0x38000000: + case 0x30000000: + i++; + + default: + ; + } + + return i; + +} + +#endif + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/normalize_amr_wb.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/normalize_amr_wb.h new file mode 100644 index 00000000..73ccb714 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/normalize_amr_wb.h @@ -0,0 +1,99 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./c/include/normalize_amr_wb.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +#ifndef NORMALIZE_AMR_WB_H +#define NORMALIZE_AMR_WB_H + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES AND SIMPLE TYPEDEF'S +----------------------------------------------------------------------------*/ + +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC)) + + +__inline int16 normalize_amr_wb(int32 x) +{ + register int32 y; + register int32 ra = x; + + + asm volatile( + "clz %0, %1\n\t" + "sub %0, %0, #1" + : "=&r*i"(y) + : "r"(ra)); + return (y); + +} + +#else + +#ifdef __cplusplus +extern "C" +{ +#endif + + int16 normalize_amr_wb(int32 x); + +#ifdef __cplusplus +} +#endif + +#endif + + + +#endif /* PV_NORMALIZE_H */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/oversamp_12k8_to_16k.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/oversamp_12k8_to_16k.cpp new file mode 100644 index 00000000..8e4534be --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/oversamp_12k8_to_16k.cpp @@ -0,0 +1,334 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: oversamp_12k8_to_16k.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 signal[], input signal / output is divided by 16 + int16 lg, lenght of signal + int16 mem[] in/out: memory (size=30) + int16 x[] scratch mem ( size= 60) + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Oversamp_16k : oversampling from 12.8kHz to 16kHz. + + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_acelp.h" +#include "pvamrwbdecoder_cnst.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +#define FAC4 4 +#define FAC5 5 +#define INV_FAC5 6554 /* 1/5 in Q15 */ +#define DOWN_FAC 26215 /* 4/5 in Q15 */ +#define UP_FAC 20480 /* 5/4 in Q14 */ +#define NB_COEF_DOWN 15 +#define NB_COEF_UP 12 +#define N_LOOP_COEF_UP 4 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +{ +#endif + + + /* Local functions */ + + void AmrWbUp_samp( + int16 * sig_d, /* input: signal to oversampling */ + int16 * sig_u, /* output: oversampled signal */ + int16 L_frame /* input: length of output */ + ); + + + int16 AmrWbInterpol( /* return result of interpolation */ + int16 * x, /* input vector */ + const int16 * fir, /* filter coefficient */ + int16 nb_coef /* number of coefficients */ + ); + + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* 1/5 resolution interpolation filter (in Q14) */ +/* -1.5dB @ 6kHz, -6dB @ 6.4kHz, -10dB @ 6.6kHz, + -20dB @ 6.9kHz, -25dB @ 7kHz, -55dB @ 8kHz */ + + +const int16 fir_up[4][24] = +{ + + { + -1, 12, -33, 68, -119, 191, + -291, 430, -634, 963, -1616, 3792, + 15317, -2496, 1288, -809, 542, -369, + 247, -160, 96, -52, 23, -6, + }, + { + -4, 24, -62, 124, -213, 338, + -510, 752, -1111, 1708, -2974, 8219, + 12368, -3432, 1881, -1204, 812, -552, + 368, -235, 139, -73, 30, -7, + }, + { + -7, 30, -73, 139, -235, 368, + -552, 812, -1204, 1881, -3432, 12368, + 8219, -2974, 1708, -1111, 752, -510, + 338, -213, 124, -62, 24, -4, + }, + { + -6, 23, -52, 96, -160, 247, + -369, 542, -809, 1288, -2496, 15317, + 3792, -1616, 963, -634, 430, -291, + 191, -119, 68, -33, 12, -1, + } +}; + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +/* output: memory (2*NB_COEF_UP) set to zeros */ +void oversamp_12k8_to_16k_init(int16 mem[]) +{ + pv_memset((void *)mem, 0, (2*NB_COEF_UP)*sizeof(*mem)); + +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void oversamp_12k8_to_16k( + int16 sig12k8[], /* input: signal to oversampling */ + int16 lg, /* input: length of input */ + int16 sig16k[], /* output: oversampled signal */ + int16 mem[], /* in/out: memory (2*NB_COEF_UP) */ + int16 signal[] +) +{ + int16 lg_up; + + pv_memcpy((void *)signal, + (void *)mem, + (2*NB_COEF_UP)*sizeof(*mem)); + + pv_memcpy((void *)(signal + (2*NB_COEF_UP)), + (void *)sig12k8, + lg*sizeof(*sig12k8)); + + lg_up = lg + (lg >> 2); /* 5/4 of lg */ + + AmrWbUp_samp(signal + NB_COEF_UP, sig16k, lg_up); + + pv_memcpy((void *)mem, + (void *)(signal + lg), + (2*NB_COEF_UP)*sizeof(*signal)); + + return; +} + + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +void AmrWbUp_samp( + int16 * sig_d, /* input: signal to oversampling */ + int16 * sig_u, /* output: oversampled signal */ + int16 L_frame /* input: length of output */ +) +{ + + int32 i; + int16 frac; + int16 * pt_sig_u = sig_u; + + frac = 1; + for (int16 j = 0; j < L_frame; j++) + { + i = ((int32)j * INV_FAC5) >> 13; /* integer part = pos * 1/5 */ + + frac--; + if (frac) + { + *(pt_sig_u++) = AmrWbInterpol(&sig_d[i], + fir_up[(FAC5-1) - frac], + N_LOOP_COEF_UP); + } + else + { + *(pt_sig_u++) = sig_d[i+12 - NB_COEF_UP ]; + frac = FAC5; + } + } + +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +/* Fractional interpolation of signal at position (frac/resol) */ + + +int16 AmrWbInterpol( /* return result of interpolation */ + int16 * x, /* input vector */ + const int16 *fir, /* filter coefficient */ + int16 nb_coef /* number of coefficients */ +) +{ + int32 L_sum; + const int16 *pt_fir = fir; + + int16 tmp1, tmp2, tmp3, tmp4; + int16 *pt_x = x - nb_coef - (nb_coef << 1) + 1; + + + tmp1 = *(pt_x++); + tmp2 = *(pt_x++); + tmp3 = *(pt_x++); + tmp4 = *(pt_x++); + L_sum = fxp_mac_16by16(tmp1, *(pt_fir++), 0x00002000L); + L_sum = fxp_mac_16by16(tmp2, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp3, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp4, *(pt_fir++), L_sum); + tmp1 = *(pt_x++); + tmp2 = *(pt_x++); + tmp3 = *(pt_x++); + tmp4 = *(pt_x++); + L_sum = fxp_mac_16by16(tmp1, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp2, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp3, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp4, *(pt_fir++), L_sum); + tmp1 = *(pt_x++); + tmp2 = *(pt_x++); + tmp3 = *(pt_x++); + tmp4 = *(pt_x++); + L_sum = fxp_mac_16by16(tmp1, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp2, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp3, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp4, *(pt_fir++), L_sum); + tmp1 = *(pt_x++); + tmp2 = *(pt_x++); + tmp3 = *(pt_x++); + tmp4 = *(pt_x++); + L_sum = fxp_mac_16by16(tmp1, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp2, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp3, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp4, *(pt_fir++), L_sum); + tmp1 = *(pt_x++); + tmp2 = *(pt_x++); + tmp3 = *(pt_x++); + tmp4 = *(pt_x++); + L_sum = fxp_mac_16by16(tmp1, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp2, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp3, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp4, *(pt_fir++), L_sum); + tmp1 = *(pt_x++); + tmp2 = *(pt_x++); + tmp3 = *(pt_x++); + tmp4 = *(pt_x++); + L_sum = fxp_mac_16by16(tmp1, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp2, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp3, *(pt_fir++), L_sum); + L_sum = fxp_mac_16by16(tmp4, *(pt_fir++), L_sum); + + + L_sum = shl_int32(L_sum, 2); /* saturation can occur here */ + + return ((int16)(L_sum >> 16)); +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/phase_dispersion.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/phase_dispersion.cpp new file mode 100644 index 00000000..55229dbf --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/phase_dispersion.cpp @@ -0,0 +1,253 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: phase_dispersion.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 gain_code, (i) Q0 : gain of code + int16 gain_pit, (i) Q14 : gain of pitch + int16 code[], (i/o) : code vector + int16 mode, (i) : level, 0=hi, 1=lo, 2=off + int16 disp_mem[], (i/o) : static memory (size = 8) + int16 ScratchMem[] + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + post-processing to enhance noise in low bit rate. + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_mem_funcs.h" +#include "pvamrwbdecoder_acelp.h" +#include "pvamrwb_math_op.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define pitch_0_9 14746 /* 0.9 in Q14 */ +#define pitch_0_6 9830 /* 0.6 in Q14 */ +#define L_SUBFR 64 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ +/* impulse response with phase dispersion */ + +/* 2.0 - 6.4 kHz phase dispersion */ +static const int16 ph_imp_low[L_SUBFR] = +{ + 20182, 9693, 3270, -3437, 2864, -5240, 1589, -1357, + 600, 3893, -1497, -698, 1203, -5249, 1199, 5371, + -1488, -705, -2887, 1976, 898, 721, -3876, 4227, + -5112, 6400, -1032, -4725, 4093, -4352, 3205, 2130, + -1996, -1835, 2648, -1786, -406, 573, 2484, -3608, + 3139, -1363, -2566, 3808, -639, -2051, -541, 2376, + 3932, -6262, 1432, -3601, 4889, 370, 567, -1163, + -2854, 1914, 39, -2418, 3454, 2975, -4021, 3431 +}; + +/* 3.2 - 6.4 kHz phase dispersion */ +static const int16 ph_imp_mid[L_SUBFR] = +{ + 24098, 10460, -5263, -763, 2048, -927, 1753, -3323, + 2212, 652, -2146, 2487, -3539, 4109, -2107, -374, + -626, 4270, -5485, 2235, 1858, -2769, 744, 1140, + -763, -1615, 4060, -4574, 2982, -1163, 731, -1098, + 803, 167, -714, 606, -560, 639, 43, -1766, + 3228, -2782, 665, 763, 233, -2002, 1291, 1871, + -3470, 1032, 2710, -4040, 3624, -4214, 5292, -4270, + 1563, 108, -580, 1642, -2458, 957, 544, 2540 +}; + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void phase_dispersion( + int16 gain_code, /* (i) Q0 : gain of code */ + int16 gain_pit, /* (i) Q14 : gain of pitch */ + int16 code[], /* (i/o) : code vector */ + int16 mode, /* (i) : level, 0=hi, 1=lo, 2=off */ + int16 disp_mem[], /* (i/o) : static memory (size = 8) */ + int16 ScratchMem[] +) +{ + int16 i, j, state; + int16 *prev_gain_pit, *prev_gain_code, *prev_state; + int16 *code2 = ScratchMem; + + prev_state = disp_mem; + prev_gain_code = disp_mem + 1; + prev_gain_pit = disp_mem + 2; + + pv_memset((void *)code2, 0, (2*L_SUBFR)*sizeof(*code2)); + + + if (gain_pit < pitch_0_6) + { + state = 0; + } + else if (gain_pit < pitch_0_9) + { + state = 1; + } + else + { + state = 2; + } + + for (i = 5; i > 0; i--) + { + prev_gain_pit[i] = prev_gain_pit[i - 1]; + } + prev_gain_pit[0] = gain_pit; + + if (sub_int16(gain_code, *prev_gain_code) > shl_int16(*prev_gain_code, 1)) + { + /* onset */ + if (state < 2) + { + state++; + } + } + else + { + j = 0; + for (i = 0; i < 6; i++) + { + if (prev_gain_pit[i] < pitch_0_6) + { + j++; + } + } + + if (j > 2) + { + state = 0; + } + if (state > *prev_state + 1) + { + state--; + } + } + + *prev_gain_code = gain_code; + *prev_state = state; + + /* circular convolution */ + + state += mode; /* level of dispersion */ + + if (state == 0) + { + for (i = 0; i < L_SUBFR; i++) + { + if (code[i] != 0) + { + for (j = 0; j < L_SUBFR; j++) + { + code2[i + j] = add_int16(code2[i + j], mult_int16_r(code[i], ph_imp_low[j])); + } + } + } + } + else if (state == 1) + { + for (i = 0; i < L_SUBFR; i++) + { + if (code[i] != 0) + { + for (j = 0; j < L_SUBFR; j++) + { + code2[i + j] = add_int16(code2[i + j], mult_int16_r(code[i], ph_imp_mid[j])); + } + } + } + } + if (state < 2) + { + for (i = 0; i < L_SUBFR; i++) + { + code[i] = add_int16(code2[i], code2[i + L_SUBFR]); + } + } + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pit_shrp.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pit_shrp.cpp new file mode 100644 index 00000000..abdef812 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pit_shrp.cpp @@ -0,0 +1,124 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pit_shrp.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 * x, in/out: impulse response (or algebraic code) + int16 pit_lag, input : pitch lag + int16 sharp, input : pitch sharpening factor (Q15) + int16 L_subfr input : subframe size + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Performs Pitch sharpening routine + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void Pit_shrp( + int16 * x, /* in/out: impulse response (or algebraic code) */ + int16 pit_lag, /* input : pitch lag */ + int16 sharp, /* input : pitch sharpening factor (Q15) */ + int16 L_subfr /* input : subframe size */ +) +{ + int16 i; + int32 L_tmp; + + for (i = pit_lag; i < L_subfr; i++) + { + L_tmp = mac_16by16_to_int32((int32)x[i] << 16, x[i - pit_lag], sharp); + x[i] = amr_wb_round(L_tmp); + + } + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pred_lt4.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pred_lt4.cpp new file mode 100644 index 00000000..ab4ab21c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pred_lt4.cpp @@ -0,0 +1,259 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pred_lt4.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 signal[], input signal / output is divided by 16 + int16 lg, lenght of signal + int16 mem[] in/out: memory (size=30) + int16 x[] scratch mem ( size= 60) + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Compute the result of long term prediction with fractionnal + interpolation of resolution 1/4. + + On return exc[0..L_subfr-1] contains the interpolated signal + (adaptive codebook excitation) + + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +#define UP_SAMP 4 +#define L_INTERPOL2 16 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* 1/4 resolution interpolation filter (-3 dB at 0.856*fs/2) in Q14 */ + + +const int16 inter4_2[UP_SAMP][ 2*L_INTERPOL2] = +{ + { + 0, -2, 4, -2, -10, 38, + -88, 165, -275, 424, -619, 871, + -1207, 1699, -2598, 5531, 14031, -2147, + 780, -249, -16, 153, -213, 226, + -209, 175, -133, 91, -55, 28, + -10, 2 + }, + { + 1, -7, 19, -33, 47, -52, + 43, -9, -60, 175, -355, 626, + -1044, 1749, -3267, 10359, 10359, -3267, + 1749, -1044, 626, -355, 175, -60, + -9, 43, -52, 47, -33, 19, + -7, 1 + }, + { + 2, -10, 28, -55, 91, -133, + 175, -209, 226, -213, 153, -16, + -249, 780, -2147, 14031, 5531, -2598, + 1699, -1207, 871, -619, 424, -275, + 165, -88, 38, -10, -2, 4, + -2, 0 + }, + { + 1, -7, 22, -49, 92, -153, + 231, -325, 431, -544, 656, -762, + 853, -923, 968, 15401, 968, -923, + 853, -762, 656, -544, 431, -325, + 231, -153, 92, -49, 22, -7, + 1, 0 + } +}; + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void Pred_lt4( + int16 exc[], /* in/out: excitation buffer */ + int16 T0, /* input : integer pitch lag */ + int16 frac, /* input : fraction of lag */ + int16 L_subfr /* input : subframe size */ +) +{ + int16 i, j, *pt_exc; + int32 L_sum1; + int32 L_sum2; + int32 L_sum3; + int32 L_sum4; + pt_exc = &exc[-T0]; + + const int16 *pt_inter4_2; + + frac = -frac; + + if (frac < 0) + { + frac += UP_SAMP; + pt_exc--; + + } + pt_exc -= (L_INTERPOL2 - 1); + + pt_inter4_2 = inter4_2[UP_SAMP-1 - frac]; + + for (j = 0; j < (L_subfr >> 2); j++) + { + + L_sum1 = 0x00002000; /* pre-roundig */ + L_sum2 = 0x00002000; + L_sum3 = 0x00002000; + L_sum4 = 0x00002000; + + for (i = 0; i < L_INTERPOL2 << 1; i += 4) + { + int16 tmp1 = pt_exc[i ]; + int16 tmp2 = pt_exc[i+1]; + int16 tmp3 = pt_exc[i+2]; + + + L_sum1 = fxp_mac_16by16(tmp1, pt_inter4_2[i ], L_sum1); + L_sum2 = fxp_mac_16by16(tmp2, pt_inter4_2[i ], L_sum2); + L_sum1 = fxp_mac_16by16(tmp2, pt_inter4_2[i+1], L_sum1); + L_sum2 = fxp_mac_16by16(tmp3, pt_inter4_2[i+1], L_sum2); + L_sum3 = fxp_mac_16by16(tmp3, pt_inter4_2[i ], L_sum3); + L_sum1 = fxp_mac_16by16(tmp3, pt_inter4_2[i+2], L_sum1); + + tmp1 = pt_exc[i+3]; + tmp2 = pt_exc[i+4]; + + L_sum4 = fxp_mac_16by16(tmp1, pt_inter4_2[i ], L_sum4); + L_sum3 = fxp_mac_16by16(tmp1, pt_inter4_2[i+1], L_sum3); + L_sum2 = fxp_mac_16by16(tmp1, pt_inter4_2[i+2], L_sum2); + L_sum1 = fxp_mac_16by16(tmp1, pt_inter4_2[i+3], L_sum1); + L_sum4 = fxp_mac_16by16(tmp2, pt_inter4_2[i+1], L_sum4); + L_sum2 = fxp_mac_16by16(tmp2, pt_inter4_2[i+3], L_sum2); + L_sum3 = fxp_mac_16by16(tmp2, pt_inter4_2[i+2], L_sum3); + + tmp1 = pt_exc[i+5]; + tmp2 = pt_exc[i+6]; + + L_sum4 = fxp_mac_16by16(tmp1, pt_inter4_2[i+2], L_sum4); + L_sum3 = fxp_mac_16by16(tmp1, pt_inter4_2[i+3], L_sum3); + L_sum4 = fxp_mac_16by16(tmp2, pt_inter4_2[i+3], L_sum4); + + } + + + + exc[(j<<2)] = (int16)(L_sum1 >> 14); + exc[(j<<2)+1] = (int16)(L_sum2 >> 14); + exc[(j<<2)+2] = (int16)(L_sum3 >> 14); + exc[(j<<2)+3] = (int16)(L_sum4 >> 14); + + pt_exc += 4; + + } + + if (L_subfr&1) + { + L_sum1 = 0x00002000; + + for (i = 0; i < 2*L_INTERPOL2; i += 4) + { + int16 tmp1 = pt_exc[i ]; + int16 tmp2 = pt_exc[i+1]; + L_sum1 = fxp_mac_16by16(tmp1, pt_inter4_2[i ], L_sum1); + L_sum1 = fxp_mac_16by16(tmp2, pt_inter4_2[i+1], L_sum1); + tmp1 = pt_exc[i+2]; + tmp2 = pt_exc[i+3]; + L_sum1 = fxp_mac_16by16(tmp1, pt_inter4_2[i+2], L_sum1); + L_sum1 = fxp_mac_16by16(tmp2, pt_inter4_2[i+3], L_sum1); + + } + + exc[(j<<2)] = (int16)((L_sum1) >> 14); + + } + + + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/preemph_amrwb_dec.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/preemph_amrwb_dec.cpp new file mode 100644 index 00000000..78359e26 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/preemph_amrwb_dec.cpp @@ -0,0 +1,122 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: preemph_amrwb_dec.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 x[], (i/o) : input signal overwritten by the output + int16 mu, (i) Q15 : preemphasis coefficient + int16 lg (i) : lenght of filtering + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Preemphasis: filtering through 1 - g z^-1 + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +void preemph_amrwb_dec( + int16 x[], /* (i/o) : input signal overwritten by the output */ + int16 mu, /* (i) Q15 : preemphasis coefficient */ + int16 lg /* (i) : lenght of filtering */ +) +{ + int16 i; + int32 L_tmp; + + for (i = lg - 1; i != 0; i--) + { + L_tmp = msu_16by16_from_int32((int32)x[i] << 16, x[i - 1], mu); + x[i] = amr_wb_round(L_tmp); + } + +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pv_amr_wb_type_defs.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pv_amr_wb_type_defs.h new file mode 100644 index 00000000..243aa908 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pv_amr_wb_type_defs.h @@ -0,0 +1,177 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./cpp/include/pv_amr_wb_type_defs.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + This file was derived from a number of standards bodies. The type + definitions below were created from some of the best practices observed + in the standards bodies. + + This file is dependent on limits.h for defining the bit widths. In an + ANSI C environment limits.h is expected to always be present and contain + the following definitions: + + SCHAR_MIN + SCHAR_MAX + UCHAR_MAX + + INT_MAX + INT_MIN + UINT_MAX + + SHRT_MIN + SHRT_MAX + USHRT_MAX + + LONG_MIN + LONG_MAX + ULONG_MAX + +------------------------------------------------------------------------------ +*/ + +#ifndef PV_AMR_WB_TYPE_DEFS_H +#define PV_AMR_WB_TYPE_DEFS_H + +#include "oscl_base.h" + + +#ifndef Word8 +typedef int8 Word8; +#endif + +#ifndef UWord8 +typedef uint8 UWord8; +#endif + +/*---------------------------------------------------------------------------- +; Define generic signed and unsigned int +----------------------------------------------------------------------------*/ +#ifndef Int +typedef signed int Int; +#endif + +#ifndef UInt +typedef unsigned int UInt; +#endif + + +/*---------------------------------------------------------------------------- +; Define 16 bit signed and unsigned words +----------------------------------------------------------------------------*/ + +#ifndef INT16_MIN +#define INT16_MIN (-32768) +#endif + +#ifndef INT16_MAX +#define INT16_MAX 32767 +#endif + +/*---------------------------------------------------------------------------- +; Define 32 bit signed and unsigned words +----------------------------------------------------------------------------*/ + + + +#ifndef INT32_MIN +#define INT32_MIN (-2147483647 - 1) +#endif +#ifndef INT32_MAX +#define INT32_MAX 2147483647 +#endif + + +#ifndef UINT32_MIN +#define UINT32_MIN 0 +#endif +#ifndef UINT32_MAX +#define UINT32_MAX 0xffffffff +#endif + + +#ifndef INT_MAX +//#define INT_MAX INT32_MAX /* for 32 bit */ +#endif + +/*---------------------------------------------------------------------------- +; Define 64 bit signed and unsigned words +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; Define boolean type +----------------------------------------------------------------------------*/ + +#ifndef Flag +typedef Int Flag; +#endif + +#ifndef Bool +typedef Int Bool; +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef OFF +#define OFF 0 +#endif +#ifndef ON +#define ON 1 +#endif + +#ifndef NO +#define NO 0 +#endif +#ifndef YES +#define YES 1 +#endif + +#ifndef SUCCESS +#define SUCCESS 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + + +#endif /* PV_AMR_WB_TYPE_DEFS_H */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwb_math_op.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwb_math_op.cpp new file mode 100644 index 00000000..d1ec7909 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwb_math_op.cpp @@ -0,0 +1,627 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/*___________________________________________________________________________ + + This file contains mathematic operations in fixed point. + + mult_int16_r() : Same as mult_int16 with rounding + shr_rnd() : Same as shr(var1,var2) but with rounding + div_16by16() : fractional integer division + one_ov_sqrt() : Compute 1/sqrt(L_x) + one_ov_sqrt_norm() : Compute 1/sqrt(x) + power_of_2() : power of 2 + Dot_product12() : Compute scalar product of using accumulator + Isqrt() : inverse square root (16 bits precision). + amrwb_log_2() : log2 (16 bits precision). + + These operations are not standard double precision operations. + They are used where low complexity is important and the full 32 bits + precision is not necessary. For example, the function Div_32() has a + 24 bits precision which is enough for our purposes. + + In this file, the values use theses representations: + + int32 L_32 : standard signed 32 bits format + int16 hi, lo : L_32 = hi<<16 + lo<<1 (DPF - Double Precision Format) + int32 frac, int16 exp : L_32 = frac << exp-31 (normalised format) + int16 int, frac : L_32 = int.frac (fractional format) + ----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwb_math_op.h" + + +/*---------------------------------------------------------------------------- + + Function Name : mult_int16_r + + Purpose : + + Same as mult_int16 with rounding, i.e.: + mult_int16_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and + mult_int16_r(-32768,-32768) = 32767. + + Complexity weight : 2 + + Inputs : + + var1 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + Outputs : + + none + + Return Value : + + var_out + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var_out <= 0x0000 7fff. + ----------------------------------------------------------------------------*/ + +int16 mult_int16_r(int16 var1, int16 var2) +{ + int32 L_product_arr; + + L_product_arr = (int32) var1 * (int32) var2; /* product */ + L_product_arr += (int32) 0x00004000L; /* round */ + L_product_arr >>= 15; /* shift */ + if ((L_product_arr >> 15) != (L_product_arr >> 31)) + { + L_product_arr = (L_product_arr >> 31) ^ MAX_16; + } + + return ((int16)L_product_arr); +} + + + +/*---------------------------------------------------------------------------- + + Function Name : shr_rnd + + Purpose : + + Same as shr(var1,var2) but with rounding. Saturate the result in case of| + underflows or overflows : + - If var2 is greater than zero : + if (sub(shl_int16(shr(var1,var2),1),shr(var1,sub(var2,1)))) + is equal to zero + then + shr_rnd(var1,var2) = shr(var1,var2) + else + shr_rnd(var1,var2) = add_int16(shr(var1,var2),1) + - If var2 is less than or equal to zero : + shr_rnd(var1,var2) = shr(var1,var2). + + Complexity weight : 2 + + Inputs : + + var1 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 + 16 bit short signed integer (int16) whose value falls in the + range : 0x0000 0000 <= var2 <= 0x0000 7fff. + + Outputs : + + none + + Return Value : + + var_out + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var_out <= 0x0000 7fff. + ----------------------------------------------------------------------------*/ + +int16 shr_rnd(int16 var1, int16 var2) +{ + int16 var_out; + + var_out = (int16)(var1 >> (var2 & 0xf)); + if (var2) + { + if ((var1 & ((int16) 1 << (var2 - 1))) != 0) + { + var_out++; + } + } + return (var_out); +} + + +/*---------------------------------------------------------------------------- + + Function Name : div_16by16 + + Purpose : + + Produces a result which is the fractional integer division of var1 by + var2; var1 and var2 must be positive and var2 must be greater or equal + to var1; the result is positive (leading bit equal to 0) and truncated + to 16 bits. + If var1 = var2 then div(var1,var2) = 32767. + + Complexity weight : 18 + + Inputs : + + var1 + 16 bit short signed integer (int16) whose value falls in the + range : 0x0000 0000 <= var1 <= var2 and var2 != 0. + + var2 + 16 bit short signed integer (int16) whose value falls in the + range : var1 <= var2 <= 0x0000 7fff and var2 != 0. + + Outputs : + + none + + Return Value : + + var_out + 16 bit short signed integer (int16) whose value falls in the + range : 0x0000 0000 <= var_out <= 0x0000 7fff. + It's a Q15 value (point between b15 and b14). + ----------------------------------------------------------------------------*/ + +int16 div_16by16(int16 var1, int16 var2) +{ + + int16 var_out = 0; + register int16 iteration; + int32 L_num; + int32 L_denom; + int32 L_denom_by_2; + int32 L_denom_by_4; + + if ((var1 > var2) || (var1 < 0)) + { + return 0; // used to exit(0); + } + if (var1) + { + if (var1 != var2) + { + + L_num = (int32) var1; + L_denom = (int32) var2; + L_denom_by_2 = (L_denom << 1); + L_denom_by_4 = (L_denom << 2); + for (iteration = 5; iteration > 0; iteration--) + { + var_out <<= 3; + L_num <<= 3; + + if (L_num >= L_denom_by_4) + { + L_num -= L_denom_by_4; + var_out |= 4; + } + + if (L_num >= L_denom_by_2) + { + L_num -= L_denom_by_2; + var_out |= 2; + } + + if (L_num >= (L_denom)) + { + L_num -= (L_denom); + var_out |= 1; + } + + } + } + else + { + var_out = MAX_16; + } + } + + return (var_out); + +} + + + +/*---------------------------------------------------------------------------- + + Function Name : one_ov_sqrt + + Compute 1/sqrt(L_x). + if L_x is negative or zero, result is 1 (7fffffff). + + Algorithm: + + 1- Normalization of L_x. + 2- call Isqrt_n(L_x, exponant) + 3- L_y = L_x << exponant + ----------------------------------------------------------------------------*/ +int32 one_ov_sqrt( /* (o) Q31 : output value (range: 0<=val<1) */ + int32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ +) +{ + int16 exp; + int32 L_y; + + exp = normalize_amr_wb(L_x); + L_x <<= exp; /* L_x is normalized */ + exp = 31 - exp; + + one_ov_sqrt_norm(&L_x, &exp); + + L_y = shl_int32(L_x, exp); /* denormalization */ + + return (L_y); +} + +/*---------------------------------------------------------------------------- + + Function Name : one_ov_sqrt_norm + + Compute 1/sqrt(value). + if value is negative or zero, result is 1 (frac=7fffffff, exp=0). + + Algorithm: + + The function 1/sqrt(value) is approximated by a table and linear + interpolation. + + 1- If exponant is odd then shift fraction right once. + 2- exponant = -((exponant-1)>>1) + 3- i = bit25-b30 of fraction, 16 <= i <= 63 ->because of normalization. + 4- a = bit10-b24 + 5- i -=16 + 6- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2 + ----------------------------------------------------------------------------*/ +static const int16 table_isqrt[49] = +{ + 32767, 31790, 30894, 30070, 29309, 28602, 27945, 27330, 26755, 26214, + 25705, 25225, 24770, 24339, 23930, 23541, 23170, 22817, 22479, 22155, + 21845, 21548, 21263, 20988, 20724, 20470, 20225, 19988, 19760, 19539, + 19326, 19119, 18919, 18725, 18536, 18354, 18176, 18004, 17837, 17674, + 17515, 17361, 17211, 17064, 16921, 16782, 16646, 16514, 16384 +}; + +void one_ov_sqrt_norm( + int32 * frac, /* (i/o) Q31: normalized value (1.0 < frac <= 0.5) */ + int16 * exp /* (i/o) : exponent (value = frac x 2^exponent) */ +) +{ + int16 i, a, tmp; + + + if (*frac <= (int32) 0) + { + *exp = 0; + *frac = 0x7fffffffL; + return; + } + + if ((*exp & 1) == 1) /* If exponant odd -> shift right */ + *frac >>= 1; + + *exp = negate_int16((*exp - 1) >> 1); + + *frac >>= 9; + i = extract_h(*frac); /* Extract b25-b31 */ + *frac >>= 1; + a = (int16)(*frac); /* Extract b10-b24 */ + a = (int16)(a & (int16) 0x7fff); + + i -= 16; + + *frac = L_deposit_h(table_isqrt[i]); /* table[i] << 16 */ + tmp = table_isqrt[i] - table_isqrt[i + 1]; /* table[i] - table[i+1]) */ + + *frac = msu_16by16_from_int32(*frac, tmp, a); /* frac -= tmp*a*2 */ + + return; +} + +/*---------------------------------------------------------------------------- + + Function Name : power_2() + + L_x = pow(2.0, exponant.fraction) (exponant = interger part) + = pow(2.0, 0.fraction) << exponant + + Algorithm: + + The function power_2(L_x) is approximated by a table and linear + interpolation. + + 1- i = bit10-b15 of fraction, 0 <= i <= 31 + 2- a = bit0-b9 of fraction + 3- L_x = table[i]<<16 - (table[i] - table[i+1]) * a * 2 + 4- L_x = L_x >> (30-exponant) (with rounding) + ----------------------------------------------------------------------------*/ +const int16 table_pow2[33] = +{ + 16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911, + 20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726, + 25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706, + 31379, 32066, 32767 +}; + +int32 power_of_2( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */ + int16 exponant, /* (i) Q0 : Integer part. (range: 0<=val<=30) */ + int16 fraction /* (i) Q15 : Fractionnal part. (range: 0.0<=val<1.0) */ +) +{ + int16 exp, i, a, tmp; + int32 L_x; + + L_x = fraction << 5; /* L_x = fraction<<6 */ + i = (fraction >> 10); /* Extract b10-b16 of fraction */ + a = (int16)(L_x); /* Extract b0-b9 of fraction */ + a = (int16)(a & (int16) 0x7fff); + + L_x = ((int32)table_pow2[i]) << 15; /* table[i] << 16 */ + tmp = table_pow2[i] - table_pow2[i + 1]; /* table[i] - table[i+1] */ + L_x -= ((int32)tmp * a); /* L_x -= tmp*a*2 */ + + exp = 29 - exponant ; + + if (exp) + { + L_x = ((L_x >> exp) + ((L_x >> (exp - 1)) & 1)); + } + + return (L_x); +} + +/*---------------------------------------------------------------------------- + * + * Function Name : Dot_product12() + * + * Compute scalar product of using accumulator. + * + * The result is normalized (in Q31) with exponent (0..30). + * + * Algorithm: + * + * dot_product = sum(x[i]*y[i]) i=0..N-1 + ----------------------------------------------------------------------------*/ + +int32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */ + int16 x[], /* (i) 12bits: x vector */ + int16 y[], /* (i) 12bits: y vector */ + int16 lg, /* (i) : vector length */ + int16 * exp /* (o) : exponent of result (0..+30) */ +) +{ + int16 i, sft; + int32 L_sum; + int16 *pt_x = x; + int16 *pt_y = y; + + L_sum = 1L; + + + for (i = lg >> 3; i != 0; i--) + { + L_sum = mac_16by16_to_int32(L_sum, *(pt_x++), *(pt_y++)); + L_sum = mac_16by16_to_int32(L_sum, *(pt_x++), *(pt_y++)); + L_sum = mac_16by16_to_int32(L_sum, *(pt_x++), *(pt_y++)); + L_sum = mac_16by16_to_int32(L_sum, *(pt_x++), *(pt_y++)); + L_sum = mac_16by16_to_int32(L_sum, *(pt_x++), *(pt_y++)); + L_sum = mac_16by16_to_int32(L_sum, *(pt_x++), *(pt_y++)); + L_sum = mac_16by16_to_int32(L_sum, *(pt_x++), *(pt_y++)); + L_sum = mac_16by16_to_int32(L_sum, *(pt_x++), *(pt_y++)); + } + + /* Normalize acc in Q31 */ + + sft = normalize_amr_wb(L_sum); + L_sum <<= sft; + + *exp = 30 - sft; /* exponent = 0..30 */ + + return (L_sum); +} + +/* Table for Log2() */ +const int16 Log2_norm_table[33] = +{ + 0, 1455, 2866, 4236, 5568, 6863, 8124, 9352, 10549, 11716, + 12855, 13967, 15054, 16117, 17156, 18172, 19167, 20142, 21097, 22033, + 22951, 23852, 24735, 25603, 26455, 27291, 28113, 28922, 29716, 30497, + 31266, 32023, 32767 +}; + +/*---------------------------------------------------------------------------- + * + * FUNCTION: Lg2_normalized() + * + * PURPOSE: Computes log2(L_x, exp), where L_x is positive and + * normalized, and exp is the normalisation exponent + * If L_x is negative or zero, the result is 0. + * + * DESCRIPTION: + * The function Log2(L_x) is approximated by a table and linear + * interpolation. The following steps are used to compute Log2(L_x) + * + * 1- exponent = 30-norm_exponent + * 2- i = bit25-b31 of L_x; 32<=i<=63 (because of normalization). + * 3- a = bit10-b24 + * 4- i -=32 + * 5- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2 + * +----------------------------------------------------------------------------*/ +void Lg2_normalized( + int32 L_x, /* (i) : input value (normalized) */ + int16 exp, /* (i) : norm_l (L_x) */ + int16 *exponent, /* (o) : Integer part of Log2. (range: 0<=val<=30) */ + int16 *fraction /* (o) : Fractional part of Log2. (range: 0<=val<1) */ +) +{ + int16 i, a, tmp; + int32 L_y; + + if (L_x <= (int32) 0) + { + *exponent = 0; + *fraction = 0;; + return; + } + + *exponent = 30 - exp; + + L_x >>= 9; + i = extract_h(L_x); /* Extract b25-b31 */ + L_x >>= 1; + a = (int16)(L_x); /* Extract b10-b24 of fraction */ + a &= 0x7fff; + + i -= 32; + + L_y = L_deposit_h(Log2_norm_table[i]); /* table[i] << 16 */ + tmp = Log2_norm_table[i] - Log2_norm_table[i + 1]; /* table[i] - table[i+1] */ + L_y = msu_16by16_from_int32(L_y, tmp, a); /* L_y -= tmp*a*2 */ + + *fraction = extract_h(L_y); + + return; +} + + + +/*---------------------------------------------------------------------------- + * + * FUNCTION: amrwb_log_2() + * + * PURPOSE: Computes log2(L_x), where L_x is positive. + * If L_x is negative or zero, the result is 0. + * + * DESCRIPTION: + * normalizes L_x and then calls Lg2_normalized(). + * + ----------------------------------------------------------------------------*/ +void amrwb_log_2( + int32 L_x, /* (i) : input value */ + int16 *exponent, /* (o) : Integer part of Log2. (range: 0<=val<=30) */ + int16 *fraction /* (o) : Fractional part of Log2. (range: 0<=val<1) */ +) +{ + int16 exp; + + exp = normalize_amr_wb(L_x); + Lg2_normalized(shl_int32(L_x, exp), exp, exponent, fraction); +} + + +/***************************************************************************** + * + * These operations are not standard double precision operations. * + * They are used where single precision is not enough but the full 32 bits * + * precision is not necessary. For example, the function Div_32() has a * + * 24 bits precision which is enough for our purposes. * + * * + * The double precision numbers use a special representation: * + * * + * L_32 = hi<<16 + lo<<1 * + * * + * L_32 is a 32 bit integer. * + * hi and lo are 16 bit signed integers. * + * As the low part also contains the sign, this allows fast multiplication. * + * * + * 0x8000 0000 <= L_32 <= 0x7fff fffe. * + * * + * We will use DPF (Double Precision Format )in this file to specify * + * this special format. * + ***************************************************************************** +*/ + + +/*---------------------------------------------------------------------------- + * + * Function int32_to_dpf() + * + * Extract from a 32 bit integer two 16 bit DPF. + * + * Arguments: + * + * L_32 : 32 bit integer. + * 0x8000 0000 <= L_32 <= 0x7fff ffff. + * hi : b16 to b31 of L_32 + * lo : (L_32 - hi<<16)>>1 + * + ----------------------------------------------------------------------------*/ + +void int32_to_dpf(int32 L_32, int16 *hi, int16 *lo) +{ + *hi = (int16)(L_32 >> 16); + *lo = (int16)((L_32 - (*hi << 16)) >> 1); + return; +} + + +/*---------------------------------------------------------------------------- + * Function mpy_dpf_32() + * + * Multiply two 32 bit integers (DPF). The result is divided by 2**31 + * + * L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 + * + * This operation can also be viewed as the multiplication of two Q31 + * number and the result is also in Q31. + * + * Arguments: + * + * hi1 hi part of first number + * lo1 lo part of first number + * hi2 hi part of second number + * lo2 lo part of second number + * + ----------------------------------------------------------------------------*/ + +int32 mpy_dpf_32(int16 hi1, int16 lo1, int16 hi2, int16 lo2) +{ + int32 L_32; + + L_32 = mul_16by16_to_int32(hi1, hi2); + L_32 = mac_16by16_to_int32(L_32, mult_int16(hi1, lo2), 1); + L_32 = mac_16by16_to_int32(L_32, mult_int16(lo1, hi2), 1); + + return (L_32); +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwb_math_op.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwb_math_op.h new file mode 100644 index 00000000..e84ce90f --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwb_math_op.h @@ -0,0 +1,126 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./src/pvamrwb_math_op.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +#ifndef PVAMRWB_MATH_OP_H +#define PVAMRWB_MATH_OP_H + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" + +/*---------------------------------------------------------------------------- +; DEFINES +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +----------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + + int32 one_ov_sqrt( /* (o) Q31 : output value (range: 0<=val<1) */ + int32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ + ); + void one_ov_sqrt_norm( + int32 * frac, /* (i/o) Q31: normalized value (1.0 < frac <= 0.5) */ + int16 * exp /* (i/o) : exponent (value = frac x 2^exponent) */ + ); + int32 power_of_2( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */ + int16 exponant, /* (i) Q0 : Integer part. (range: 0<=val<=30) */ + int16 fraction /* (i) Q15 : Fractionnal part. (range: 0.0<=val<1.0) */ + ); + int32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */ + int16 x[], /* (i) 12bits: x vector */ + int16 y[], /* (i) 12bits: y vector */ + int16 lg, /* (i) : vector length */ + int16 * exp /* (o) : exponent of result (0..+30) */ + ); + + + void amrwb_log_2( + int32 L_x, /* (i) : input value */ + int16 *exponent, /* (o) : Integer part of Log2. (range: 0<=val<=30) */ + int16 *fraction /* (o) : Fractional part of Log2. (range: 0<=val<1)*/ + ); + + void Lg2_normalized( + int32 L_x, /* (i) : input value (normalized) */ + int16 exp, /* (i) : norm_l (L_x) */ + int16 *exponent, /* (o) : Integer part of Log2. (range: 0<=val<=30) */ + int16 *fraction /* (o) : Fractional part of Log2. (range: 0<=val<1) */ + ); + + + int16 mult_int16_r(int16 var1, int16 var2); /* Mult with round, 2 */ + int16 shr_rnd(int16 var1, int16 var2); /* Shift right with round, 2 */ + + int16 div_16by16(int16 var1, int16 var2); /* Short division, 18 */ + + + void int32_to_dpf(int32 L_32, int16 *hi, int16 *lo); + int32 mpy_dpf_32(int16 hi1, int16 lo1, int16 hi2, int16 lo2); + + +#define norm_s( x) (normalize_amr_wb( x) - 16) + + +#define extract_h( x) (int16)(x>>16) +#define L_deposit_h( x) (int32)(x<<16) + + +#ifdef __cplusplus +} +#endif + + +#endif /* PVAMRWB_MATH_OP_H */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder.cpp new file mode 100644 index 00000000..85edaa13 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder.cpp @@ -0,0 +1,1141 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pvamrwbdecoder.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 mode, input : used mode + int16 prms[], input : parameter vector + int16 synth16k[], output: synthesis speech + int16 * frame_length, output: lenght of the frame + void *spd_state, i/o : State structure + int16 frame_type, input : received frame type + int16 ScratchMem[] + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Performs the main decoder routine AMR WB ACELP coding algorithm with 20 ms + speech frames for wideband speech signals. + + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_mem_funcs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" +#include "e_pv_amrwbdec.h" +#include "get_amr_wb_bits.h" +#include "pvamrwb_math_op.h" +#include "pvamrwbdecoder_api.h" +#include "pvamrwbdecoder.h" +#include "synthesis_amr_wb.h" + + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/* LPC interpolation coef {0.45, 0.8, 0.96, 1.0}; in Q15 */ +static const int16 interpol_frac[NB_SUBFR] = {14746, 26214, 31457, 32767}; + + +/* isp tables for initialization */ + +static const int16 isp_init[M] = +{ + 32138, 30274, 27246, 23170, 18205, 12540, 6393, 0, + -6393, -12540, -18205, -23170, -27246, -30274, -32138, 1475 +}; + +static const int16 isf_init[M] = +{ + 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, + 9216, 10240, 11264, 12288, 13312, 14336, 15360, 3840 +}; + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + FUNCTION DESCRIPTION pvDecoder_AmrWb_Init + + Initialization of variables for the decoder section. + +----------------------------------------------------------------------------*/ + + + + +void pvDecoder_AmrWb_Init(void **spd_state, void *pt_st, int16 **ScratchMem) +{ + /* Decoder states */ + Decoder_State *st = &(((PV_AmrWbDec *)pt_st)->state); + + *ScratchMem = ((PV_AmrWbDec *)pt_st)->ScratchMem; + /* + * Init dtx decoding + */ + dtx_dec_amr_wb_reset(&(st->dtx_decSt), isf_init); + + pvDecoder_AmrWb_Reset((void *) st, 1); + + *spd_state = (void *) st; + + return; +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void pvDecoder_AmrWb_Reset(void *st, int16 reset_all) +{ + int16 i; + + Decoder_State *dec_state; + + dec_state = (Decoder_State *) st; + + pv_memset((void *)dec_state->old_exc, + 0, + (PIT_MAX + L_INTERPOL)*sizeof(*dec_state->old_exc)); + + pv_memset((void *)dec_state->past_isfq, + 0, + M*sizeof(*dec_state->past_isfq)); + + + dec_state->old_T0_frac = 0; /* old pitch value = 64.0 */ + dec_state->old_T0 = 64; + dec_state->first_frame = 1; + dec_state->L_gc_thres = 0; + dec_state->tilt_code = 0; + + pv_memset((void *)dec_state->disp_mem, + 0, + 8*sizeof(*dec_state->disp_mem)); + + + /* scaling memories for excitation */ + dec_state->Q_old = Q_MAX; + dec_state->Qsubfr[3] = Q_MAX; + dec_state->Qsubfr[2] = Q_MAX; + dec_state->Qsubfr[1] = Q_MAX; + dec_state->Qsubfr[0] = Q_MAX; + + if (reset_all != 0) + { + /* routines initialization */ + + dec_gain2_amr_wb_init(dec_state->dec_gain); + oversamp_12k8_to_16k_init(dec_state->mem_oversamp); + band_pass_6k_7k_init(dec_state->mem_hf); + low_pass_filt_7k_init(dec_state->mem_hf3); + highpass_50Hz_at_12k8_init(dec_state->mem_sig_out); + highpass_400Hz_at_12k8_init(dec_state->mem_hp400); + Init_Lagconc(dec_state->lag_hist); + + /* isp initialization */ + + pv_memcpy((void *)dec_state->ispold, (void *)isp_init, M*sizeof(*isp_init)); + + pv_memcpy((void *)dec_state->isfold, (void *)isf_init, M*sizeof(*isf_init)); + for (i = 0; i < L_MEANBUF; i++) + { + pv_memcpy((void *)&dec_state->isf_buf[i * M], + (void *)isf_init, + M*sizeof(*isf_init)); + } + /* variable initialization */ + + dec_state->mem_deemph = 0; + + dec_state->seed = 21845; /* init random with 21845 */ + dec_state->seed2 = 21845; + dec_state->seed3 = 21845; + + dec_state->state = 0; + dec_state->prev_bfi = 0; + + /* Static vectors to zero */ + + pv_memset((void *)dec_state->mem_syn_hf, + 0, + M16k*sizeof(*dec_state->mem_syn_hf)); + + pv_memset((void *)dec_state->mem_syn_hi, + 0, + M*sizeof(*dec_state->mem_syn_hi)); + + pv_memset((void *)dec_state->mem_syn_lo, + 0, + M*sizeof(*dec_state->mem_syn_lo)); + + + dtx_dec_amr_wb_reset(&(dec_state->dtx_decSt), isf_init); + dec_state->vad_hist = 0; + + } + return; +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +int32 pvDecoder_AmrWbMemRequirements() +{ + return(sizeof(PV_AmrWbDec)); +} + + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +/* Main decoder routine. */ + +int32 pvDecoder_AmrWb( + int16 mode, /* input : used mode */ + int16 prms[], /* input : parameter vector */ + int16 synth16k[], /* output: synthesis speech */ + int16 * frame_length, /* output: lenght of the frame */ + void *spd_state, /* i/o : State structure */ + int16 frame_type, /* input : received frame type */ + int16 ScratchMem[] +) +{ + + /* Decoder states */ + Decoder_State *st; + + int16 *ScratchMem2 = &ScratchMem[ L_SUBFR + L_SUBFR16k + ((L_SUBFR + M + M16k +1)<<1)]; + + + /* Excitation vector */ + + + int16 *old_exc = ScratchMem2; + + int16 *Aq = &old_exc[(L_FRAME + 1) + PIT_MAX + L_INTERPOL];/* A(z) quantized for the 4 subframes */ + + int16 *ispnew = &Aq[NB_SUBFR * (M + 1)];/* immittance spectral pairs at 4nd sfr */ + int16 *isf = &ispnew[M]; /* ISF (frequency domain) at 4nd sfr */ + int16 *isf_tmp = &isf[M]; + int16 *code = &isf_tmp[M]; /* algebraic codevector */ + int16 *excp = &code[L_SUBFR]; + int16 *exc2 = &excp[L_SUBFR]; /* excitation vector */ + int16 *HfIsf = &exc2[L_FRAME]; + + + int16 *exc; + + /* LPC coefficients */ + + int16 *p_Aq; /* ptr to A(z) for the 4 subframes */ + + + + int16 fac, stab_fac, voice_fac, Q_new = 0; + int32 L_tmp, L_gain_code; + + /* Scalars */ + + int16 i, j, i_subfr, index, ind[8], tmp; + int32 max; + int16 T0, T0_frac, pit_flag, T0_max, select, T0_min = 0; + int16 gain_pit, gain_code; + int16 newDTXState, bfi, unusable_frame, nb_bits; + int16 vad_flag; + int16 pit_sharp; + + int16 corr_gain = 0; + + st = (Decoder_State *) spd_state; + + /* mode verification */ + + nb_bits = AMR_WB_COMPRESSED[mode]; + + *frame_length = AMR_WB_PCM_FRAME; + + /* find the new DTX state SPEECH OR DTX */ + newDTXState = rx_amr_wb_dtx_handler(&(st->dtx_decSt), frame_type); + + + if (newDTXState != SPEECH) + { + dtx_dec_amr_wb(&(st->dtx_decSt), exc2, newDTXState, isf, &prms); + } + /* SPEECH action state machine */ + + if ((frame_type == RX_SPEECH_BAD) || + (frame_type == RX_SPEECH_PROBABLY_DEGRADED)) + { + /* bfi for all index, bits are not usable */ + bfi = 1; + unusable_frame = 0; + } + else if ((frame_type == RX_NO_DATA) || + (frame_type == RX_SPEECH_LOST)) + { + /* bfi only for lsf, gains and pitch period */ + bfi = 1; + unusable_frame = 1; + } + else + { + bfi = 0; + unusable_frame = 0; + } + + if (bfi != 0) + { + st->state += 1; + + if (st->state > 6) + { + st->state = 6; + } + } + else + { + st->state >>= 1; + } + + /* If this frame is the first speech frame after CNI period, + * set the BFH state machine to an appropriate state depending + * on whether there was DTX muting before start of speech or not + * If there was DTX muting, the first speech frame is muted. + * If there was no DTX muting, the first speech frame is not + * muted. The BFH state machine starts from state 5, however, to + * keep the audible noise resulting from a SID frame which is + * erroneously interpreted as a good speech frame as small as + * possible (the decoder output in this case is quickly muted) + */ + + if (st->dtx_decSt.dtxGlobalState == DTX) + { + st->state = 5; + st->prev_bfi = 0; + } + else if (st->dtx_decSt.dtxGlobalState == DTX_MUTE) + { + st->state = 5; + st->prev_bfi = 1; + } + + if (newDTXState == SPEECH) + { + vad_flag = Serial_parm_1bit(&prms); + + if (bfi == 0) + { + if (vad_flag == 0) + { + st->vad_hist = add_int16(st->vad_hist, 1); + } + else + { + st->vad_hist = 0; + } + } + } + /* + * DTX-CNG + */ + + if (newDTXState != SPEECH) /* CNG mode */ + { + /* increase slightly energy of noise below 200 Hz */ + + /* Convert ISFs to the cosine domain */ + Isf_isp(isf, ispnew, M); + + Isp_Az(ispnew, Aq, M, 1); + + pv_memcpy((void *)isf_tmp, (void *)st->isfold, M*sizeof(*isf_tmp)); + + + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + j = i_subfr >> 6; + + for (i = 0; i < M; i++) + { + L_tmp = mul_16by16_to_int32(isf_tmp[i], sub_int16(32767, interpol_frac[j])); + L_tmp = mac_16by16_to_int32(L_tmp, isf[i], interpol_frac[j]); + HfIsf[i] = amr_wb_round(L_tmp); + } + + synthesis_amr_wb(Aq, + &exc2[i_subfr], + 0, + &synth16k[i_subfr *5/4], + (short) 1, + HfIsf, + nb_bits, + newDTXState, + st, + bfi, + ScratchMem); + } + + /* reset speech coder memories */ + pvDecoder_AmrWb_Reset(st, 0); + + pv_memcpy((void *)st->isfold, (void *)isf, M*sizeof(*isf)); + + st->prev_bfi = bfi; + st->dtx_decSt.dtxGlobalState = newDTXState; + + return 0; + } + /* + * ACELP + */ + + /* copy coder memory state into working space (internal memory for DSP) */ + + pv_memcpy((void *)old_exc, (void *)st->old_exc, (PIT_MAX + L_INTERPOL)*sizeof(*old_exc)); + + exc = old_exc + PIT_MAX + L_INTERPOL; + + /* Decode the ISFs */ + + if (nb_bits > NBBITS_7k) /* all rates but 6.6 Kbps */ + { + ind[0] = Serial_parm(8, &prms); /* index of 1st ISP subvector */ + ind[1] = Serial_parm(8, &prms); /* index of 2nd ISP subvector */ + ind[2] = Serial_parm(6, &prms); /* index of 3rd ISP subvector */ + ind[3] = Serial_parm(7, &prms); /* index of 4th ISP subvector */ + ind[4] = Serial_parm(7, &prms); /* index of 5th ISP subvector */ + ind[5] = Serial_parm(5, &prms); /* index of 6th ISP subvector */ + ind[6] = Serial_parm(5, &prms); /* index of 7th ISP subvector */ + + Dpisf_2s_46b(ind, isf, st->past_isfq, st->isfold, st->isf_buf, bfi, 1); + } + else + { + ind[0] = Serial_parm(8, &prms); + ind[1] = Serial_parm(8, &prms); + ind[2] = Serial_parm(14, &prms); + ind[3] = ind[2] & 0x007F; + ind[2] >>= 7; + ind[4] = Serial_parm(6, &prms); + + Dpisf_2s_36b(ind, isf, st->past_isfq, st->isfold, st->isf_buf, bfi, 1); + } + + /* Convert ISFs to the cosine domain */ + + Isf_isp(isf, ispnew, M); + + if (st->first_frame != 0) + { + st->first_frame = 0; + pv_memcpy((void *)st->ispold, (void *)ispnew, M*sizeof(*ispnew)); + + } + /* Find the interpolated ISPs and convert to a[] for all subframes */ + interpolate_isp(st->ispold, ispnew, interpol_frac, Aq); + + /* update ispold[] for the next frame */ + pv_memcpy((void *)st->ispold, (void *)ispnew, M*sizeof(*ispnew)); + + /* Check stability on isf : distance between old isf and current isf */ + + L_tmp = 0; + for (i = 0; i < M - 1; i++) + { + tmp = sub_int16(isf[i], st->isfold[i]); + L_tmp = mac_16by16_to_int32(L_tmp, tmp, tmp); + } + tmp = extract_h(shl_int32(L_tmp, 8)); + tmp = mult_int16(tmp, 26214); /* tmp = L_tmp*0.8/256 */ + + tmp = 20480 - tmp; /* 1.25 - tmp */ + stab_fac = shl_int16(tmp, 1); /* Q14 -> Q15 with saturation */ + + if (stab_fac < 0) + { + stab_fac = 0; + } + pv_memcpy((void *)isf_tmp, (void *)st->isfold, M*sizeof(*isf_tmp)); + + pv_memcpy((void *)st->isfold, (void *)isf, M*sizeof(*isf)); + + /* + * Loop for every subframe in the analysis frame + * + * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR + * times + * - decode the pitch delay and filter mode + * - decode algebraic code + * - decode pitch and codebook gains + * - find voicing factor and tilt of code for next subframe. + * - find the excitation and compute synthesis speech + */ + + p_Aq = Aq; /* pointer to interpolated LPC parameters */ + + + /* + * Sub process next 3 subframes + */ + + + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + pit_flag = i_subfr; + + + if ((i_subfr == 2*L_SUBFR) && (nb_bits > NBBITS_7k)) + { + pit_flag = 0; /* set to 0 for 3rd subframe, <=> is not 6.6 kbps */ + } + /*-------------------------------------------------* + * - Decode pitch lag * + * Lag indeces received also in case of BFI, * + * so that the parameter pointer stays in sync. * + *-------------------------------------------------*/ + + if (pit_flag == 0) + { + + if (nb_bits <= NBBITS_9k) + { + index = Serial_parm(8, &prms); + + if (index < (PIT_FR1_8b - PIT_MIN) * 2) + { + T0 = PIT_MIN + (index >> 1); + T0_frac = sub_int16(index, shl_int16(sub_int16(T0, PIT_MIN), 1)); + T0_frac = shl_int16(T0_frac, 1); + } + else + { + T0 = add_int16(index, PIT_FR1_8b - ((PIT_FR1_8b - PIT_MIN) * 2)); + T0_frac = 0; + } + } + else + { + index = Serial_parm(9, &prms); + + if (index < (PIT_FR2 - PIT_MIN) * 4) + { + T0 = PIT_MIN + (index >> 2); + T0_frac = sub_int16(index, shl_int16(sub_int16(T0, PIT_MIN), 2)); + } + else if (index < (((PIT_FR2 - PIT_MIN) << 2) + ((PIT_FR1_9b - PIT_FR2) << 1))) + { + index -= (PIT_FR2 - PIT_MIN) << 2; + T0 = PIT_FR2 + (index >> 1); + T0_frac = sub_int16(index, shl_int16(sub_int16(T0, PIT_FR2), 1)); + T0_frac = shl_int16(T0_frac, 1); + } + else + { + T0 = add_int16(index, (PIT_FR1_9b - ((PIT_FR2 - PIT_MIN) * 4) - ((PIT_FR1_9b - PIT_FR2) * 2))); + T0_frac = 0; + } + } + + /* find T0_min and T0_max for subframe 2 and 4 */ + + T0_min = T0 - 8; + + if (T0_min < PIT_MIN) + { + T0_min = PIT_MIN; + } + T0_max = T0_min + 15; + + if (T0_max > PIT_MAX) + { + T0_max = PIT_MAX; + T0_min = PIT_MAX - 15; + } + } + else + { /* if subframe 2 or 4 */ + + if (nb_bits <= NBBITS_9k) + { + index = Serial_parm(5, &prms); + + T0 = T0_min + (index >> 1); + T0_frac = sub_int16(index, shl_int16(T0 - T0_min, 1)); + T0_frac = shl_int16(T0_frac, 1); + } + else + { + index = Serial_parm(6, &prms); + + T0 = T0_min + (index >> 2); + T0_frac = sub_int16(index, shl_int16(T0 - T0_min, 2)); + } + } + + /* check BFI after pitch lag decoding */ + + if (bfi != 0) /* if frame erasure */ + { + lagconceal(&(st->dec_gain[17]), st->lag_hist, &T0, &(st->old_T0), &(st->seed3), unusable_frame); + T0_frac = 0; + } + /* + * Find the pitch gain, the interpolation filter + * and the adaptive codebook vector. + */ + + Pred_lt4(&exc[i_subfr], T0, T0_frac, L_SUBFR + 1); + + + if (unusable_frame) + { + select = 1; + } + else + { + + if (nb_bits <= NBBITS_9k) + { + select = 0; + } + else + { + select = Serial_parm_1bit(&prms); + } + } + + + if (select == 0) + { + /* find pitch excitation with lp filter */ + for (i = 0; i < L_SUBFR; i++) + { + L_tmp = ((int32) exc[i-1+i_subfr] + exc[i+1+i_subfr]); + L_tmp *= 5898; + L_tmp += ((int32) exc[i+i_subfr] * 20972); + + code[i] = amr_wb_round(L_tmp << 1); + } + pv_memcpy((void *)&exc[i_subfr], (void *)code, L_SUBFR*sizeof(*code)); + + } + /* + * Decode innovative codebook. + * Add the fixed-gain pitch contribution to code[]. + */ + + if (unusable_frame != 0) + { + /* the innovative code doesn't need to be scaled (see Q_gain2) */ + for (i = 0; i < L_SUBFR; i++) + { + code[i] = noise_gen_amrwb(&(st->seed)) >> 3; + } + } + else if (nb_bits <= NBBITS_7k) + { + ind[0] = Serial_parm(12, &prms); + dec_acelp_2p_in_64(ind[0], code); + } + else if (nb_bits <= NBBITS_9k) + { + for (i = 0; i < 4; i++) + { + ind[i] = Serial_parm(5, &prms); + } + dec_acelp_4p_in_64(ind, 20, code); + } + else if (nb_bits <= NBBITS_12k) + { + for (i = 0; i < 4; i++) + { + ind[i] = Serial_parm(9, &prms); + } + dec_acelp_4p_in_64(ind, 36, code); + } + else if (nb_bits <= NBBITS_14k) + { + ind[0] = Serial_parm(13, &prms); + ind[1] = Serial_parm(13, &prms); + ind[2] = Serial_parm(9, &prms); + ind[3] = Serial_parm(9, &prms); + dec_acelp_4p_in_64(ind, 44, code); + } + else if (nb_bits <= NBBITS_16k) + { + for (i = 0; i < 4; i++) + { + ind[i] = Serial_parm(13, &prms); + } + dec_acelp_4p_in_64(ind, 52, code); + } + else if (nb_bits <= NBBITS_18k) + { + for (i = 0; i < 4; i++) + { + ind[i] = Serial_parm(2, &prms); + } + for (i = 4; i < 8; i++) + { + ind[i] = Serial_parm(14, &prms); + } + dec_acelp_4p_in_64(ind, 64, code); + } + else if (nb_bits <= NBBITS_20k) + { + ind[0] = Serial_parm(10, &prms); + ind[1] = Serial_parm(10, &prms); + ind[2] = Serial_parm(2, &prms); + ind[3] = Serial_parm(2, &prms); + ind[4] = Serial_parm(10, &prms); + ind[5] = Serial_parm(10, &prms); + ind[6] = Serial_parm(14, &prms); + ind[7] = Serial_parm(14, &prms); + dec_acelp_4p_in_64(ind, 72, code); + } + else + { + for (i = 0; i < 8; i++) + { + ind[i] = Serial_parm(11, &prms); + } + + dec_acelp_4p_in_64(ind, 88, code); + } + + preemph_amrwb_dec(code, st->tilt_code, L_SUBFR); + + tmp = T0; + + if (T0_frac > 2) + { + tmp++; + } + Pit_shrp(code, tmp, PIT_SHARP, L_SUBFR); + + /* + * Decode codebooks gains. + */ + + if (nb_bits <= NBBITS_9k) + { + index = Serial_parm(6, &prms); /* codebook gain index */ + + dec_gain2_amr_wb(index, + 6, + code, + L_SUBFR, + &gain_pit, + &L_gain_code, + bfi, + st->prev_bfi, + st->state, + unusable_frame, + st->vad_hist, + st->dec_gain); + } + else + { + index = Serial_parm(7, &prms); /* codebook gain index */ + + dec_gain2_amr_wb(index, + 7, + code, + L_SUBFR, + &gain_pit, + &L_gain_code, + bfi, + st->prev_bfi, + st->state, + unusable_frame, + st->vad_hist, + st->dec_gain); + } + + /* find best scaling to perform on excitation (Q_new) */ + + tmp = st->Qsubfr[0]; + for (i = 1; i < 4; i++) + { + if (st->Qsubfr[i] < tmp) + { + tmp = st->Qsubfr[i]; + } + } + + /* limit scaling (Q_new) to Q_MAX: see pv_amr_wb_cnst.h and syn_filt_32() */ + + if (tmp > Q_MAX) + { + tmp = Q_MAX; + } + Q_new = 0; + L_tmp = L_gain_code; /* L_gain_code in Q16 */ + + + while ((L_tmp < 0x08000000L) && (Q_new < tmp)) + { + L_tmp <<= 1; + Q_new += 1; + + } + gain_code = amr_wb_round(L_tmp); /* scaled gain_code with Qnew */ + + scale_signal(exc + i_subfr - (PIT_MAX + L_INTERPOL), + PIT_MAX + L_INTERPOL + L_SUBFR, + (int16)(Q_new - st->Q_old)); + + st->Q_old = Q_new; + + + /* + * Update parameters for the next subframe. + * - tilt of code: 0.0 (unvoiced) to 0.5 (voiced) + */ + + + if (bfi == 0) + { + /* LTP-Lag history update */ + for (i = 4; i > 0; i--) + { + st->lag_hist[i] = st->lag_hist[i - 1]; + } + st->lag_hist[0] = T0; + + st->old_T0 = T0; + st->old_T0_frac = 0; /* Remove fraction in case of BFI */ + } + /* find voice factor in Q15 (1=voiced, -1=unvoiced) */ + + /* + * Scale down by 1/8 + */ + for (i = L_SUBFR - 1; i >= 0; i--) + { + exc2[i] = (exc[i_subfr + i] + (0x0004 * (exc[i_subfr + i] != MAX_16))) >> 3; + } + + + /* post processing of excitation elements */ + + if (nb_bits <= NBBITS_9k) + { + pit_sharp = shl_int16(gain_pit, 1); + + if (pit_sharp > 16384) + { + for (i = 0; i < L_SUBFR; i++) + { + tmp = mult_int16(exc2[i], pit_sharp); + L_tmp = mul_16by16_to_int32(tmp, gain_pit); + L_tmp >>= 1; + excp[i] = amr_wb_round(L_tmp); + } + } + } + else + { + pit_sharp = 0; + } + + voice_fac = voice_factor(exc2, -3, gain_pit, code, gain_code, L_SUBFR); + + /* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */ + + st->tilt_code = (voice_fac >> 2) + 8192; + + /* + * - Find the total excitation. + * - Find synthesis speech corresponding to exc[]. + * - Find maximum value of excitation for next scaling + */ + + pv_memcpy((void *)exc2, (void *)&exc[i_subfr], L_SUBFR*sizeof(*exc2)); + max = 1; + + for (i = 0; i < L_SUBFR; i++) + { + L_tmp = mul_16by16_to_int32(code[i], gain_code); + L_tmp = shl_int32(L_tmp, 5); + L_tmp = mac_16by16_to_int32(L_tmp, exc[i + i_subfr], gain_pit); + L_tmp = shl_int32(L_tmp, 1); + tmp = amr_wb_round(L_tmp); + exc[i + i_subfr] = tmp; + tmp = tmp - (tmp < 0); + max |= tmp ^(tmp >> 15); /* |= tmp ^sign(tmp) */ + } + + + /* tmp = scaling possible according to max value of excitation */ + tmp = add_int16(norm_s(max), Q_new) - 1; + + st->Qsubfr[3] = st->Qsubfr[2]; + st->Qsubfr[2] = st->Qsubfr[1]; + st->Qsubfr[1] = st->Qsubfr[0]; + st->Qsubfr[0] = tmp; + + /* + * phase dispersion to enhance noise in low bit rate + */ + + + if (nb_bits <= NBBITS_7k) + { + j = 0; /* high dispersion for rate <= 7.5 kbit/s */ + } + else if (nb_bits <= NBBITS_9k) + { + j = 1; /* low dispersion for rate <= 9.6 kbit/s */ + } + else + { + j = 2; /* no dispersion for rate > 9.6 kbit/s */ + } + + /* L_gain_code in Q16 */ + + phase_dispersion((int16)(L_gain_code >> 16), + gain_pit, + code, + j, + st->disp_mem, + ScratchMem); + + /* + * noise enhancer + * - Enhance excitation on noise. (modify gain of code) + * If signal is noisy and LPC filter is stable, move gain + * of code 1.5 dB toward gain of code threshold. + * This decrease by 3 dB noise energy variation. + */ + + tmp = 16384 - (voice_fac >> 1); /* 1=unvoiced, 0=voiced */ + fac = mult_int16(stab_fac, tmp); + + L_tmp = L_gain_code; + + if (L_tmp < st->L_gc_thres) + { + L_tmp += fxp_mul32_by_16b(L_gain_code, 6226) << 1; + + if (L_tmp > st->L_gc_thres) + { + L_tmp = st->L_gc_thres; + } + } + else + { + L_tmp = fxp_mul32_by_16b(L_gain_code, 27536) << 1; + + if (L_tmp < st->L_gc_thres) + { + L_tmp = st->L_gc_thres; + } + } + st->L_gc_thres = L_tmp; + + L_gain_code = fxp_mul32_by_16b(L_gain_code, (32767 - fac)) << 1; + + + L_gain_code = add_int32(L_gain_code, fxp_mul32_by_16b(L_tmp, fac) << 1); + + /* + * pitch enhancer + * - Enhance excitation on voice. (HP filtering of code) + * On voiced signal, filtering of code by a smooth fir HP + * filter to decrease energy of code in low frequency. + */ + + tmp = (voice_fac >> 3) + 4096;/* 0.25=voiced, 0=unvoiced */ + + /* build excitation */ + + gain_code = amr_wb_round(shl_int32(L_gain_code, Q_new)); + + L_tmp = (int32)(code[0] << 16); + L_tmp = msu_16by16_from_int32(L_tmp, code[1], tmp); + L_tmp = mul_16by16_to_int32(amr_wb_round(L_tmp), gain_code); + L_tmp = shl_int32(L_tmp, 5); + L_tmp = mac_16by16_to_int32(L_tmp, exc2[0], gain_pit); + L_tmp = shl_int32(L_tmp, 1); /* saturation can occur here */ + exc2[0] = amr_wb_round(L_tmp); + + + for (i = 1; i < L_SUBFR - 1; i++) + { + L_tmp = (int32)(code[i] << 16); + L_tmp = msu_16by16_from_int32(L_tmp, (code[i + 1] + code[i - 1]), tmp); + L_tmp = mul_16by16_to_int32(amr_wb_round(L_tmp), gain_code); + L_tmp = shl_int32(L_tmp, 5); + L_tmp = mac_16by16_to_int32(L_tmp, exc2[i], gain_pit); + L_tmp = shl_int32(L_tmp, 1); /* saturation can occur here */ + exc2[i] = amr_wb_round(L_tmp); + } + + L_tmp = (int32)(code[L_SUBFR - 1] << 16); + L_tmp = msu_16by16_from_int32(L_tmp, code[L_SUBFR - 2], tmp); + L_tmp = mul_16by16_to_int32(amr_wb_round(L_tmp), gain_code); + L_tmp = shl_int32(L_tmp, 5); + L_tmp = mac_16by16_to_int32(L_tmp, exc2[L_SUBFR - 1], gain_pit); + L_tmp = shl_int32(L_tmp, 1); /* saturation can occur here */ + exc2[L_SUBFR - 1] = amr_wb_round(L_tmp); + + + + if (nb_bits <= NBBITS_9k) + { + if (pit_sharp > 16384) + { + for (i = 0; i < L_SUBFR; i++) + { + excp[i] = add_int16(excp[i], exc2[i]); + } + agc2_amr_wb(exc2, excp, L_SUBFR); + pv_memcpy((void *)exc2, (void *)excp, L_SUBFR*sizeof(*exc2)); + + } + } + if (nb_bits <= NBBITS_7k) + { + j = i_subfr >> 6; + for (i = 0; i < M; i++) + { + L_tmp = mul_16by16_to_int32(isf_tmp[i], sub_int16(32767, interpol_frac[j])); + L_tmp = mac_16by16_to_int32(L_tmp, isf[i], interpol_frac[j]); + HfIsf[i] = amr_wb_round(L_tmp); + } + } + else + { + pv_memset((void *)st->mem_syn_hf, + 0, + (M16k - M)*sizeof(*st->mem_syn_hf)); + } + + if (nb_bits >= NBBITS_24k) + { + corr_gain = Serial_parm(4, &prms); + } + else + { + corr_gain = 0; + } + + synthesis_amr_wb(p_Aq, + exc2, + Q_new, + &synth16k[i_subfr + (i_subfr>>2)], + corr_gain, + HfIsf, + nb_bits, + newDTXState, + st, + bfi, + ScratchMem); + + p_Aq += (M + 1); /* interpolated LPC parameters for next subframe */ + } + + /* + * Update signal for next frame. + * -> save past of exc[] + * -> save pitch parameters + */ + + pv_memcpy((void *)st->old_exc, + (void *)&old_exc[L_FRAME], + (PIT_MAX + L_INTERPOL)*sizeof(*old_exc)); + + scale_signal(exc, L_FRAME, (int16)(-Q_new)); + + dtx_dec_amr_wb_activity_update(&(st->dtx_decSt), isf, exc); + + st->dtx_decSt.dtxGlobalState = newDTXState; + + st->prev_bfi = bfi; + + return 0; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder.h new file mode 100644 index 00000000..d017d068 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder.h @@ -0,0 +1,146 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Name: pvamrwbdecoder.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + Main header file for the Packet Video AMR Wide Band decoder library. The + constants, structures, and functions defined within this file, along with + a basic data types header file, is all that is needed to use and communicate + with the library. The internal data structures within the library are + purposely hidden. + + ---* Need description of the input buffering. *------- + + ---* Need an example of calling the library here *---- + +------------------------------------------------------------------------------ + REFERENCES + + (Normally header files do not have a reference section) + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ +#ifndef _PVAMRWBDECODER_H +#define _PVAMRWBDECODER_H + +#include "oscl_base.h" /* Basic data types used within the lib */ +#include "pvamrwbdecoder_api.h" +#include "pvgsmamrdecoderinterface.h" + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" +{ +#endif + + /*---------------------------------------------------------------------------- + ; MACROS + ; Define module specific macros here + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; DEFINES + ; Include all pre-processor statements here. + ----------------------------------------------------------------------------*/ + + + + /*---------------------------------------------------------------------------- + ; EXTERNAL VARIABLES REFERENCES + ; Declare variables used in this module but defined elsewhere + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; SIMPLE TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; ENUMERATED TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; STRUCTURES TYPEDEF'S + ----------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + ; GLOBAL FUNCTION DEFINITIONS + ; Function Prototype declaration + ----------------------------------------------------------------------------*/ + + void pvDecoder_AmrWb_Init(void **spd_state, void *st, int16 ** ScratchMem); + + int32 pvDecoder_AmrWb( + int16 mode, /* input : used mode */ + int16 prms[], /* input : parameter vector */ + int16 synth16k[], /* output: synthesis speech */ + int16 * frame_length, /* output: lenght of the frame */ + void *spd_state, /* i/o : State structure */ + int16 frame_type, /* input : received frame type */ + int16 ScratchMem[] + ); + + void pvDecoder_AmrWb_Reset(void *st, int16 reset_all); + + int16 pvDecoder_AmrWb_homing_frame_test(int16 input_frame[], int16 mode); + + int16 pvDecoder_AmrWb_homing_frame_test_first(int16 input_frame[], int16 mode); + + int32 pvDecoder_AmrWbMemRequirements(); + + void mime_unsorting(uint8 packet[], + int16 compressed_data[], + int16 *frame_type, + int16 *mode, + uint8 q, + RX_State *st); + + + /*---------------------------------------------------------------------------- + ; END + ----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + + +#endif /* PVMP4AUDIODECODER_API_H */ + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_acelp.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_acelp.h new file mode 100644 index 00000000..52001ad0 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_acelp.h @@ -0,0 +1,323 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./cpp/include/pvamrwbdecoder_acelp.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +#ifndef PVAMRWBDECODER_ACELP_H +#define PVAMRWBDECODER_ACELP_H + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_mem_funcs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /*-----------------------------------------------------------------* + * LPC prototypes * + *-----------------------------------------------------------------*/ + + void isf_extrapolation(int16 HfIsf[]); + + void Init_Lagconc(int16 lag_hist[]); + void lagconceal( + int16 gain_hist[], /* (i) : Gain history */ + int16 lag_hist[], /* (i) : Subframe size */ + int16 * T0, + int16 * old_T0, + int16 * seed, + int16 unusable_frame + ); + + void agc2_amr_wb( + int16 * sig_in, /* input : postfilter input signal */ + int16 * sig_out, /* in/out: postfilter output signal */ + int16 l_trm /* input : subframe size */ + ); + + void low_pass_filt_7k_init(int16 mem[]); + void low_pass_filt_7k( + int16 signal[], /* input: signal */ + int16 lg, /* input: length of input */ + int16 mem[], /* in/out: memory (size=30) */ + int16 x[] + ); + + int16 median5(int16 x[]); + + void Isp_Az( + int16 isp[], /* (i) Q15 : Immittance spectral pairs */ + int16 a[], /* (o) Q12 : predictor coefficients (order = M) */ + int16 m, + int16 adaptive_scaling /* (i) 0 : adaptive scaling disabled */ + /* 1 : adaptive scaling enabled */ + ); + void Isf_isp( + int16 isf[], /* (i) Q15 : isf[m] normalized (range: 0.0<=val<=0.5) */ + int16 isp[], /* (o) Q15 : isp[m] (range: -1<=val<1) */ + int16 m /* (i) : LPC order */ + ); + void interpolate_isp( + int16 isp_old[], /* input : isps from past frame */ + int16 isp_new[], /* input : isps from present frame */ + const int16 frac[], /* input : fraction for 3 first subfr (Q15) */ + int16 Az[] /* output: LP coefficients in 4 subframes */ + ); + void weight_amrwb_lpc( + int16 a[], /* (i) Q12 : a[m+1] LPC coefficients */ + int16 ap[], /* (o) Q12 : Spectral expanded LPC coefficients */ + int16 gamma, /* (i) Q15 : Spectral expansion factor. */ + int16 m /* (i) : LPC order. */ + ); + + + /*-----------------------------------------------------------------* + * isf quantizers * + *-----------------------------------------------------------------*/ + + void Disf_ns( + int16 * indice, /* input: quantization indices */ + int16 * isf_q /* input : ISF in the frequency domain (0..0.5) */ + ); + + void Dpisf_2s_46b( + int16 * indice, /* input: quantization indices */ + int16 * isf_q, /* output: quantized ISF in frequency domain (0..0.5) */ + int16 * past_isfq, /* i/0 : past ISF quantizer */ + int16 * isfold, /* input : past quantized ISF */ + int16 * isf_buf, /* input : isf buffer */ + int16 bfi, /* input : Bad frame indicator */ + int16 enc_dec + ); + void Dpisf_2s_36b( + int16 * indice, /* input: quantization indices */ + int16 * isf_q, /* output: quantized ISF in frequency domain (0..0.5) */ + int16 * past_isfq, /* i/0 : past ISF quantizer */ + int16 * isfold, /* input : past quantized ISF */ + int16 * isf_buf, /* input : isf buffer */ + int16 bfi, /* input : Bad frame indicator */ + int16 enc_dec + ); + + + void Reorder_isf( + int16 * isf, /* (i/o) Q15: ISF in the frequency domain (0..0.5) */ + int16 min_dist, /* (i) Q15 : minimum distance to keep */ + int16 n /* (i) : number of ISF */ + ); + + /*-----------------------------------------------------------------* + * filter prototypes * + *-----------------------------------------------------------------*/ + + void oversamp_12k8_to_16k_init( + int16 mem[] /* output: memory (2*NB_COEF_UP) set to zeros */ + ); + void oversamp_12k8_to_16k( + int16 sig12k8[], /* input: signal to oversampling */ + int16 lg, /* input: length of input */ + int16 sig16k[], /* output: oversampled signal */ + int16 mem[], /* in/out: memory (2*NB_COEF_UP) */ + int16 signal[] + ); + + void highpass_50Hz_at_12k8_init(int16 mem[]); + void highpass_50Hz_at_12k8( + int16 signal[], /* input/output signal */ + int16 lg, /* lenght of signal */ + int16 mem[] /* filter memory [6] */ + ); + void highpass_400Hz_at_12k8_init(int16 mem[]); + void highpass_400Hz_at_12k8( + int16 signal[], /* input/output signal */ + int16 lg, /* lenght of signal */ + int16 mem[] /* filter memory [6] */ + ); + + void band_pass_6k_7k_init(int16 mem[]); + void band_pass_6k_7k( + int16 signal[], /* input: signal */ + int16 lg, /* input: length of input */ + int16 mem[], /* in/out: memory (size=30) */ + int16 x[] + ); + + + void preemph_amrwb_dec( + int16 x[], /* (i/o) : input signal overwritten by the output */ + int16 mu, /* (i) Q15 : preemphasis coefficient */ + int16 lg /* (i) : lenght of filtering */ + ); + + void deemphasis_32( + int16 x_hi[], /* (i) : input signal (bit31..16) */ + int16 x_lo[], /* (i) : input signal (bit15..4) */ + int16 y[], /* (o) : output signal (x16) */ + int16 mu, /* (i) Q15 : deemphasis factor */ + int16 L, /* (i) : vector size */ + int16 * mem /* (i/o) : memory (y[-1]) */ + ); + + + void wb_syn_filt( + int16 a[], /* (i) Q12 : a[m+1] prediction coefficients */ + int16 m, /* (i) : order of LP filter */ + int16 x[], /* (i) : input signal */ + int16 y[], /* (o) : output signal */ + int16 lg, /* (i) : size of filtering */ + int16 mem[], /* (i/o) : memory associated with this filtering. */ + int16 update, /* (i) : 0=no update, 1=update of memory. */ + int16 y_buf[] + ); + void Syn_filt_32( + int16 a[], /* (i) Q12 : a[m+1] prediction coefficients */ + int16 m, /* (i) : order of LP filter */ + int16 exc[], /* (i) Qnew: excitation (exc[i] >> Qnew) */ + int16 Qnew, /* (i) : exc scaling = 0(min) to 8(max) */ + int16 sig_hi[], /* (o) /16 : synthesis high */ + int16 sig_lo[], /* (o) /16 : synthesis low */ + int16 lg /* (i) : size of filtering */ + ); + + /*-----------------------------------------------------------------* + * pitch prototypes * + *-----------------------------------------------------------------*/ + + + void Pred_lt4( + int16 exc[], /* in/out: excitation buffer */ + int16 T0, /* input : integer pitch lag */ + int16 frac, /* input : fraction of lag */ + int16 L_subfr /* input : subframe size */ + ); + + /*-----------------------------------------------------------------* + * gain prototypes * + *-----------------------------------------------------------------*/ + + + void dec_gain2_amr_wb_init( + int16 * mem /* output : memory (4 words) */ + ); + void dec_gain2_amr_wb( + int16 index, /* (i) :index of quantization. */ + int16 nbits, /* (i) : number of bits (6 or 7) */ + int16 code[], /* (i) Q9 :Innovative vector. */ + int16 L_subfr, /* (i) :Subframe lenght. */ + int16 * gain_pit, /* (o) Q14 :Pitch gain. */ + int32 * gain_cod, /* (o) Q16 :Code gain. */ + int16 bfi, /* (i) :bad frame indicator */ + int16 prev_bfi, /* (i) : Previous BF indicator */ + int16 state, /* (i) : State of BFH */ + int16 unusable_frame, /* (i) : UF indicator */ + int16 vad_hist, /* (i) :number of non-speech frames */ + int16 * mem /* (i/o) : memory (4 words) */ + ); + + /*-----------------------------------------------------------------* + * acelp prototypes * + *-----------------------------------------------------------------*/ + + void dec_acelp_2p_in_64( + int16 index, /* (i) : 12 bits index */ + int16 code[] /* (o) :Q9 algebraic (fixed) codebook excitation */ + ); + + void dec_acelp_4p_in_64( + int16 index[], /* (i) : index (20): 5+5+5+5 = 20 bits. */ + /* (i) : index (36): 9+9+9+9 = 36 bits. */ + /* (i) : index (44): 13+9+13+9 = 44 bits. */ + /* (i) : index (52): 13+13+13+13 = 52 bits. */ + /* (i) : index (64): 2+2+2+2+14+14+14+14 = 64 bits. */ + /* (i) : index (72): 10+2+10+2+10+14+10+14 = 72 bits. */ + /* (i) : index (88): 11+11+11+11+11+11+11+11 = 88 bits. */ + int16 nbbits, /* (i) : 20, 36, 44, 52, 64, 72 or 88 bits */ + int16 code[] /* (o) Q9: algebraic (fixed) codebook excitation */ + ); + void Pit_shrp( + int16 * x, /* in/out: impulse response (or algebraic code) */ + int16 pit_lag, /* input : pitch lag */ + int16 sharp, /* input : pitch sharpening factor (Q15) */ + int16 L_subfr /* input : subframe size */ + ); + + + /*-----------------------------------------------------------------* + * others prototypes * + *-----------------------------------------------------------------*/ + + int16 voice_factor( /* (o) Q15 : factor (-1=unvoiced to 1=voiced) */ + int16 exc[], /* (i) Q_exc: pitch excitation */ + int16 Q_exc, /* (i) : exc format */ + int16 gain_pit, /* (i) Q14 : gain of pitch */ + int16 code[], /* (i) Q9 : Fixed codebook excitation */ + int16 gain_code, /* (i) Q0 : gain of code */ + int16 L_subfr /* (i) : subframe length */ + ); + + void scale_signal( + int16 x[], /* (i/o) : signal to scale */ + int16 lg, /* (i) : size of x[] */ + int16 exp /* (i) : exponent: x = round(x << exp) */ + ); + + int16 noise_gen_amrwb(int16 * seed); + + + void phase_dispersion( + int16 gain_code, /* (i) Q0 : gain of code */ + int16 gain_pit, /* (i) Q14 : gain of pitch */ + int16 code[], /* (i/o) : code vector */ + int16 mode, /* (i) : level, 0=hi, 1=lo, 2=off */ + int16 disp_mem[], /* (i/o) : memory (size = 8) */ + int16 ScratchMem[] + ); + +#ifdef __cplusplus +} +#endif + +#endif /* ACELP_H */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_basic_op.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_basic_op.h new file mode 100644 index 00000000..86f70b37 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_basic_op.h @@ -0,0 +1,239 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./src/pvamrwbdecoder_basic_op.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + + +#ifndef PVAMRWBDECODER_BASIC_OP_H +#define PVAMRWBDECODER_BASIC_OP_H + + +#include "normalize_amr_wb.h" + + +#define MAX_32 (int32)0x7fffffffL +#define MIN_32 (int32)0x80000000L + +#define MAX_16 (int16)+32767 /* 0x7fff */ +#define MIN_16 (int16)-32768 /* 0x8000 */ + + + + +/*---------------------------------------------------------------------------- + Function Name : negate_int16 + + Negate var1 with saturation, saturate in the case where input is -32768: + negate(var1) = sub(0,var1). + + Inputs : + var1 + 16 bit short signed integer (int16) whose value falls in the + range : 0x8000 <= var1 <= 0x7fff. + + Outputs : + none + + Return Value : + 16 bit short signed integer (int16) whose value falls in the + range : 0x8000 <= var_out <= 0x7fff. + ----------------------------------------------------------------------------*/ + +static inline int16 negate_int16(int16 var1) +{ + return (((var1 == MIN_16) ? MAX_16 : -var1)); +} + + +/*---------------------------------------------------------------------------- + + Function Name : shl_int16 + + Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill + the var2 LSB of the result. If var2 is negative, arithmetically shift + var1 right by -var2 with sign extension. Saturate the result in case of + underflows or overflows. + + Inputs : + var1 + 16 bit short signed integer (int16) whose value falls in the + range : 0x8000 <= var1 <= 0x7fff. + + var2 + 16 bit short signed integer (int16) whose value falls in the + range : 0x8000 <= var1 <= 0x7fff. + + Return Value : + var_out + 16 bit short signed integer (int16) whose value falls in the + range : 0x8000 <= var_out <= 0x7fff. + ----------------------------------------------------------------------------*/ + +static inline int16 shl_int16(int16 var1, int16 var2) +{ + int16 var_out; + + if (var2 < 0) + { + var2 = (-var2) & (0xf); + var_out = var1 >> var2; + } + else + { + var2 &= 0xf; + var_out = var1 << var2; + if (var_out >> var2 != var1) + { + var_out = (var1 >> 15) ^ MAX_16; + } + } + return (var_out); +} + + +/*---------------------------------------------------------------------------- + + Function Name : shl_int32 + + Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero + fill the var2 LSB of the result. If var2 is negative, arithmetically + shift L_var1 right by -var2 with sign extension. Saturate the result in + case of underflows or overflows. + + Inputs : + L_var1 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + var2 + 16 bit short signed integer (int16) whose value falls in the + range : 8000 <= var2 <= 7fff. + Return Value : + 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + + ----------------------------------------------------------------------------*/ + +static inline int32 shl_int32(int32 L_var1, int16 var2) +{ + int32 L_var_out; + + if (var2 > 0) + { + L_var_out = L_var1 << var2; + if (L_var_out >> var2 != L_var1) + { + L_var_out = (L_var1 >> 31) ^ MAX_32; + } + } + else + { + var2 = (-var2) & (0xf); + L_var_out = L_var1 >> var2; + } + + return (L_var_out); +} + + +/*---------------------------------------------------------------------------- + + Function Name : shr_int32 + + Arithmetically shift the 32 bit input L_var1 right var2 positions with + sign extension. If var2 is negative, arithmetically shift L_var1 left + by -var2 and zero fill the -var2 LSB of the result. Saturate the result + in case of underflows or overflows. + + Inputs : + L_var1 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + var2 + 16 bit short signed integer (int16) whose value falls in the + range : 8000 <= var2 <= 7fff. + Return Value : + 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + + ----------------------------------------------------------------------------*/ + +static inline int32 shr_int32(int32 L_var1, int16 var2) +{ + int32 L_var_out; + + if (var2 >= 0) + { + L_var_out = L_var1 >> (var2 & 0x1f); + } + else + { + var2 = (int16)(-var2); + var2 &= 0x1f; + L_var_out = L_var1 << var2; + if (L_var_out >> var2 != L_var1) + { + L_var_out = (L_var1 >> 31) ^ MAX_32; + } + + } + return (L_var_out); +} + + + + + + +#if ((PV_CPU_ARCH_VERSION >=5) && (PV_COMPILER == EPV_ARM_GNUC)) + +#include "pvamrwbdecoder_basic_op_gcc_armv5.h" + +#else + +#ifndef C_EQUIVALENT +#define C_EQUIVALENT // default to C_EQUIVALENT +#endif + +#include "pvamrwbdecoder_basic_op_cequivalent.h" + +#endif + + +#endif /* PVAMRWBDECODER_BASIC_OP_H */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h new file mode 100644 index 00000000..8b9faaa7 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h @@ -0,0 +1,538 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./src/pvamrwbdecoder_basic_op_cequivalent.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + +------------------------------------------------------------------------------ +*/ +#ifndef PVAMRWBDECODER_BASIC_OP_CEQUIVALENT_H +#define PVAMRWBDECODER_BASIC_OP_CEQUIVALENT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#include "normalize_amr_wb.h" + +#if defined(C_EQUIVALENT) + + + /*---------------------------------------------------------------------------- + + Function Name : add_int16 + + Purpose : + + Performs the addition (var1+var2) with overflow control and saturation; + the 16 bit result is set at +32767 when overflow occurs or at -32768 + when underflow occurs. + + Inputs : + var1 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + Outputs : + none + + Return Value : + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var_out <= 0x0000 7fff. + + ----------------------------------------------------------------------------*/ + static inline int16 add_int16(int16 var1, int16 var2) + { + int32 L_sum; + + L_sum = (int32) var1 + var2; + if ((L_sum >> 15) != (L_sum >> 31)) + { + L_sum = (L_sum >> 31) ^ MAX_16; + } + return ((int16)(L_sum)); + } + + + /*---------------------------------------------------------------------------- + + Function Name : sub_int16 + + Performs the subtraction (var1+var2) with overflow control and satu- + ration; the 16 bit result is set at +32767 when overflow occurs or at + -32768 when underflow occurs. + + Inputs : + + var1 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + Outputs : + none + + Return Value : + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var_out <= 0x0000 7fff. + + ----------------------------------------------------------------------------*/ + static inline int16 sub_int16(int16 var1, int16 var2) + { + int32 L_diff; + + L_diff = (int32) var1 - var2; + if ((L_diff >> 15) != (L_diff >> 31)) + { + L_diff = (L_diff >> 31) ^ MAX_16; + } + return ((int16)(L_diff)); + } + + + /*---------------------------------------------------------------------------- + + Function Name : mult_int16 + + Performs the multiplication of var1 by var2 and gives a 16 bit result + which is scaled i.e.: + mult_int16(var1,var2) = extract_l(L_shr((var1 times var2),15)) and + mult_int16(-32768,-32768) = 32767. + + Inputs : + var1 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + + Return Value : + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var_out <= 0x0000 7fff. + + ----------------------------------------------------------------------------*/ + + static inline int16 mult_int16(int16 var1, int16 var2) + { + int32 L_product; + + L_product = ((int32) var1 * (int32) var2) >> 15; + + if ((L_product >> 15) != (L_product >> 31)) + { + L_product = (L_product >> 31) ^ MAX_16; + } + + return ((int16)L_product); + } + + + /*---------------------------------------------------------------------------- + + Function Name : add_int32 + + 32 bits addition of the two 32 bits variables (L_var1+L_var2) with + overflow control and saturation; the result is set at +2147483647 when + overflow occurs or at -2147483648 when underflow occurs. + + Inputs : + + L_var1 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + + L_var2 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + + + Return Value : + L_var_out + 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + + ----------------------------------------------------------------------------*/ + + + static inline int32 add_int32(int32 L_var1, int32 L_var2) + { + int32 L_var_out; + + L_var_out = L_var1 + L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) == 0) /* same sign ? */ + { + if ((L_var_out ^ L_var1) & MIN_32) /* addition matches sign ? */ + { + L_var_out = (L_var1 >> 31) ^ MAX_32; + } + } + return (L_var_out); + } + + + + + /*---------------------------------------------------------------------------- + + Function Name : sub_int32 + + 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with + overflow control and saturation; the result is set at +2147483647 when + overflow occurs or at -2147483648 when underflow occurs. + + Inputs : + + L_var1 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + + L_var2 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + + + Return Value : + L_var_out + 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + + ----------------------------------------------------------------------------*/ + + + static inline int32 sub_int32(int32 L_var1, int32 L_var2) + { + int32 L_var_out; + + L_var_out = L_var1 - L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) != 0) /* different sign ? */ + { + if ((L_var_out ^ L_var1) & MIN_32) /* difference matches sign ? */ + { + L_var_out = (L_var1 >> 31) ^ MAX_32; + } + } + return (L_var_out); + } + + + + /*---------------------------------------------------------------------------- + + Function Name : mac_16by16_to_int32 + + Multiply var1 by var2 and shift the result left by 1. Add the 32 bit + result to L_var3 with saturation, return a 32 bit result: + L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)). + + Inputs : + + L_var3 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + + var1 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + + Return Value : + 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + + ----------------------------------------------------------------------------*/ + + + static inline int32 mac_16by16_to_int32(int32 L_var3, int16 var1, int16 var2) + { + int32 L_var_out; + int32 L_mul; + + L_mul = ((int32) var1 * (int32) var2); + + if (L_mul != 0x40000000) + { + L_mul <<= 1; + } + else + { + L_mul = MAX_32; /* saturation */ + } + + L_var_out = L_var3 + L_mul; + + if (((L_mul ^ L_var3) & MIN_32) == 0) /* same sign ? */ + { + if ((L_var_out ^ L_var3) & MIN_32) /* addition matches sign ? */ + { + L_var_out = (L_var3 >> 31) ^ MAX_32; + } + } + + return (L_var_out); + } + + + + /*---------------------------------------------------------------------------- + + Function Name : msu_16by16_from_int32 + + Multiply var1 by var2 and shift the result left by 1. Subtract the 32 bit + result to L_var3 with saturation, return a 32 bit result: + L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)). + + Inputs : + + L_var3 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + + var1 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + + Return Value : + 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + + ----------------------------------------------------------------------------*/ + + static inline int32 msu_16by16_from_int32(int32 L_var3, int16 var1, int16 var2) + { + int32 L_var_out; + int32 L_mul; + + L_mul = ((int32) var1 * (int32) var2); + + if (L_mul != 0x40000000) + { + L_mul <<= 1; + } + else + { + L_mul = MAX_32; /* saturation */ + } + + L_var_out = L_var3 - L_mul; + + if (((L_mul ^ L_var3) & MIN_32) != 0) /* different sign ? */ + { + if ((L_var_out ^ L_var3) & MIN_32) /* difference matches sign ? */ + { + L_var_out = (L_var3 >> 31) ^ MAX_32; + } + } + + return (L_var_out); + } + + + /*---------------------------------------------------------------------------- + + Function Name : mul_16by16_to_int32 + + mul_16by16_to_int32 is the 32 bit result of the multiplication of var1 + times var2 with one shift left i.e.: + L_mult(var1,var2) = L_shl((var1 times var2),1) and + L_mult(-32768,-32768) = 2147483647. + + Inputs : + var1 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + var2 + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var1 <= 0x0000 7fff. + + Return Value : + 32 bit long signed integer (int32) whose value falls in the + range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + + ----------------------------------------------------------------------------*/ + + + static inline int32 mul_16by16_to_int32(int16 var1, int16 var2) + { + int32 L_mul; + + L_mul = ((int32) var1 * (int32) var2); + + if (L_mul != 0x40000000) + { + L_mul <<= 1; + } + else + { + L_mul = MAX_32; /* saturation */ + } + + return (L_mul); + + } + + /*---------------------------------------------------------------------------- + + Function Name : amr_wb_round + + Round the lower 16 bits of the 32 bit input number into the MS 16 bits + with saturation. Shift the resulting bits right by 16 and return the 16 + bit number: + round(L_var1) = extract_h(L_add(L_var1,32768)) + + Inputs : + L_var1 + 32 bit long signed integer (int32 ) whose value falls in the + range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + Return Value : + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var_out <= 0x0000 7fff. + + ----------------------------------------------------------------------------*/ + static inline int16 amr_wb_round(int32 L_var1) + { + if (L_var1 != MAX_32) + { + L_var1 += 0x00008000L; + } + return ((int16)(L_var1 >> 16)); + } + + + /*---------------------------------------------------------------------------- + + Function Name : amr_wb_shl1_round + + Shift the 32 bit input number to the left by 1, round up the result and + shift down by 16 + amr_wb_shl1_round(L_var1) = round(L_shl(L_var1,1)) + + Inputs : + L_var1 + 32 bit long signed integer (int32 ) whose value falls in the + range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + + Return Value : + 16 bit short signed integer (int16) whose value falls in the + range : 0xffff 8000 <= var_out <= 0x0000 7fff. + + ----------------------------------------------------------------------------*/ + static inline int16 amr_wb_shl1_round(int32 L_var1) + { + int16 var_out; + + if ((L_var1 << 1) >> 1 == L_var1) + { + var_out = (int16)((L_var1 + 0x00004000) >> 15); + } + else + { + var_out = (int16)(((L_var1 >> 31) ^ MAX_32) >> 16); + } + + return (var_out); + } + + /*---------------------------------------------------------------------------- + Function Name : mul_32by16 + + Multiply a 16 bit integer by a 32 bit (DPF). The result is divided + by 2^15 + + L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 + + Inputs : + + hi hi part of 32 bit number. + lo lo part of 32 bit number. + n 16 bit number. + + ----------------------------------------------------------------------------*/ + + + static inline int32 mul_32by16(int16 hi, int16 lo, int16 n) + { + return (((((int32)hi*n)) + ((((int32)lo*n) >> 15))) << 1); + } + + static inline int32 fxp_mac_16by16(int16 var1, int16 var2, int32 L_add) + { + + L_add += (int32)var1 * var2; + + return L_add; + } + + static inline int32 fxp_mul_16by16(int16 var1, const int16 var2) + { + int32 L_mul = (int32)var1 * var2; + + return L_mul; + } + + static inline int32 fxp_mul32_by_16b(int32 L_var1, const int32 L_var2) + { + int32 L_mul = (int32)(((int64)L_var1 * (L_var2 << 16)) >> 32); + + return L_mul; + } + + +#ifdef __cplusplus +} +#endif + +#endif + +#endif /* PVAMRWBDECODER_BASIC_OP_CEQUIVALENT_H */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h new file mode 100644 index 00000000..c2c9f365 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h @@ -0,0 +1,311 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2010 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./src/pvamrwbdecoder_basic_op_gcc_armv5.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +#ifndef PVAMRWBDECODER_BASIC_OP_GCC_ARMV5_H +#define PVAMRWBDECODER_BASIC_OP_GCC_ARMV5_H + + +#ifdef __cplusplus +extern "C" +{ +#endif + + + static inline int16 sub_int16(int16 var1, int16 var2) + { + register int32 L_var_out; + register int32 L_var_aux; + register int32 ra = (int32)var1; + register int32 rb = (int32)var2; + + asm volatile( + "mov %0, %2, lsl #16\n" + "mov %1, %3, lsl #16\n" + "qsub %0, %0, %1\n" + "mov %0, %0, asr #16" + : "=&r*i"(L_var_out), + "=&r*i"(L_var_aux) + : "r"(ra), + "r"(rb)); + + return (int16)L_var_out; + + } + + static inline int16 add_int16(int16 var1, int16 var2) +{ + register int32 L_var_out; + register int32 L_var_aux; + register int32 ra = (int32)var1; + register int32 rb = (int32)var2; + + asm volatile( + "mov %0, %2, lsl #16\n" + "mov %1, %3, lsl #16\n" + "qadd %0, %0, %1\n" + "mov %0, %0, asr #16" + : "=&r*i"(L_var_out), + "=&r*i"(L_var_aux) + : "r"(ra), + "r"(rb)); + + return (int16)L_var_out; + + } + + static inline int32 mul_32by16(int16 hi, int16 lo, int16 n) +{ + register int32 H_32; + register int32 L_32; + register int32 ra = (int32)hi; + register int32 rb = (int32)lo; + register int32 rc = (int32)n; + + + asm volatile( + "smulbb %0, %2, %4\n" + "smulbb %1, %3, %4\n" + "add %0, %0, %1, asr #15\n" + "qadd %0, %0, %0" + : "=&r*i"(H_32), + "=&r*i"(L_32) + : "r"(ra), + "r"(rb), + "r"(rc)); + + return H_32; + } + + + static inline int32 sub_int32(int32 L_var1, int32 L_var2) +{ + register int32 L_var_out; + register int32 ra = L_var1; + register int32 rb = L_var2; + + asm volatile( + "qsub %0, %1, %2" + : "=&r*i"(L_var_out) + : "r"(ra), + "r"(rb)); + + return L_var_out; + } + + static inline int32 add_int32(int32 L_var1, int32 L_var2) +{ + register int32 L_var_out; + register int32 ra = L_var1; + register int32 rb = L_var2; + + asm volatile( + "qadd %0, %1, %2" + : "=&r*i"(L_var_out) + : "r"(ra), + "r"(rb)); + + return L_var_out; + } + + static inline int32 msu_16by16_from_int32(int32 L_var3, int16 var1, int16 var2) +{ + register int32 L_var_out; + register int32 ra = (int32)var1; + register int32 rb = (int32)var2; + register int32 rc = L_var3; + + asm volatile( + "smulbb %0, %1, %2\n" + "qdsub %0, %3, %0" + : "=&r*i"(L_var_out) + : "r"(ra), + "r"(rb), + "r"(rc)); + + return L_var_out; + } + + + static inline int32 mac_16by16_to_int32(int32 L_var3, int16 var1, int16 var2) +{ + register int32 L_var_out; + register int32 ra = (int32)var1; + register int32 rb = (int32)var2; + register int32 rc = L_var3; + + asm volatile( + "smulbb %0, %1, %2\n" + "qdadd %0, %3, %0" + : "=&r*i"(L_var_out) + : "r"(ra), + "r"(rb), + "r"(rc)); + + return L_var_out; + } + + + static inline int32 mul_16by16_to_int32(int16 var1, int16 var2) +{ + register int32 L_var_out; + register int32 ra = (int32)var1; + register int32 rb = (int32)var2; + + asm volatile( + "smulbb %0, %1, %2\n" + "qadd %0, %0, %0" + : "=&r*i"(L_var_out) + : "r"(ra), + "r"(rb)); + + return L_var_out; + } + + + static inline int16 mult_int16(int16 var1, int16 var2) +{ + register int32 L_var_out; + register int32 ra = (int32)var1; + register int32 rb = (int32)var2; + + asm volatile( + "smulbb %0, %1, %2\n" + "mov %0, %0, asr #15" + : "=&r*i"(L_var_out) + : "r"(ra), + "r"(rb)); + + return (int16)L_var_out; + } + + static inline int16 amr_wb_round(int32 L_var1) +{ + register int32 L_var_out; + register int32 ra = (int32)L_var1; + register int32 rb = (int32)0x00008000L; + + asm volatile( + "qadd %0, %1, %2\n" + "mov %0, %0, asr #16" + : "=&r*i"(L_var_out) + : "r"(ra), + "r"(rb)); + return (int16)L_var_out; + } + + static inline int16 amr_wb_shl1_round(int32 L_var1) +{ + register int32 L_var_out; + register int32 ra = (int32)L_var1; + register int32 rb = (int32)0x00008000L; + + asm volatile( + "qadd %0, %1, %1\n" + "qadd %0, %0, %2\n" + "mov %0, %0, asr #16" + : "=&r*i"(L_var_out) + : "r"(ra), + "r"(rb)); + return (int16)L_var_out; + } + + + static inline int32 fxp_mac_16by16(const int16 L_var1, const int16 L_var2, int32 L_add) +{ + register int32 tmp; + register int32 ra = (int32)L_var1; + register int32 rb = (int32)L_var2; + register int32 rc = (int32)L_add; + + asm volatile( + "smlabb %0, %1, %2, %3" + : "=&r*i"(tmp) + : "r"(ra), + "r"(rb), + "r"(rc)); + return (tmp); + } + + static inline int32 fxp_mul_16by16bb(int16 L_var1, const int16 L_var2) +{ + register int32 tmp; + register int32 ra = (int32)L_var1; + register int32 rb = (int32)L_var2; + + asm volatile( + "smulbb %0, %1, %2" + : "=&r*i"(tmp) + : "r"(ra), + "r"(rb)); + return (tmp); + } + + +#define fxp_mul_16by16(a, b) fxp_mul_16by16bb( a, b) + + + static inline int32 fxp_mul32_by_16(int32 L_var1, const int32 L_var2) +{ + register int32 tmp; + register int32 ra = (int32)L_var1; + register int32 rb = (int32)L_var2; + + asm volatile( + "smulwb %0, %1, %2" + : "=&r*i"(tmp) + : "r"(ra), + "r"(rb)); + return (tmp); + } + +#define fxp_mul32_by_16b( a, b) fxp_mul32_by_16( a, b) + + + +#ifdef __cplusplus +} +#endif + + + + +#endif /* PVAMRWBDECODER_BASIC_OP_GCC_ARMV5_H */ + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_cnst.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_cnst.h new file mode 100644 index 00000000..16b51271 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_cnst.h @@ -0,0 +1,134 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + Name: pvamrwbdecoder_cnst.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + Main header file for the Packet Video AMR Wide Band decoder library. The + constants, structures, and functions defined within this file, along with + a basic data types header file, is all that is needed to use and communicate + with the library. The internal data structures within the library are + purposely hidden. + + +------------------------------------------------------------------------------ + REFERENCES + + (Normally header files do not have a reference section) + +------------------------------------------------------------------------------ +*/ + +/*---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ + +#ifndef PVAMRWBDECODER_CNST_H +#define PVAMRWBDECODER_CNST_H + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. +----------------------------------------------------------------------------*/ + +#define L_FRAME 256 /* Frame size */ +#define L_SUBFR16k 80 /* Subframe size at 16kHz */ + +#define L_SUBFR 64 /* Subframe size */ +#define NB_SUBFR 4 /* Number of subframe per frame */ + +#define L_NEXT 64 /* Overhead in LP analysis */ +#define L_WINDOW 384 /* window size in LP analysis */ +#define L_TOTAL 384 /* Total size of speech buffer. */ +#define M 16 /* Order of LP filter */ +#define M16k 20 + +#define L_FILT16k 15 /* Delay of down-sampling filter */ +#define L_FILT 12 /* Delay of up-sampling filter */ + +#define GP_CLIP 15565 /* Pitch gain clipping = 0.95 Q14 */ +#define PIT_SHARP 27853 /* pitch sharpening factor = 0.85 Q15 */ + +#define PIT_MIN 34 /* Minimum pitch lag with resolution 1/4 */ +#define PIT_FR2 128 /* Minimum pitch lag with resolution 1/2 */ +#define PIT_FR1_9b 160 /* Minimum pitch lag with resolution 1 */ +#define PIT_FR1_8b 92 /* Minimum pitch lag with resolution 1 */ +#define PIT_MAX 231 /* Maximum pitch lag */ +#define L_INTERPOL (16+1) /* Length of filter for interpolation */ + +#define OPL_DECIM 2 /* Decimation in open-loop pitch analysis */ + +#define PREEMPH_FAC 22282 /* preemphasis factor (0.68 in Q15) */ +#define GAMMA1 30147 /* Weighting factor (numerator) (0.92 in Q15) */ +#define TILT_FAC 22282 /* tilt factor (denominator) (0.68 in Q15) */ + +#define Q_MAX 8 /* scaling max for signal (see syn_filt_32) */ + +#define RANDOM_INITSEED 21845 /* own random init value */ + +#define L_MEANBUF 3 +#define ONE_PER_MEANBUF 10923 + +#define MODE_7k 0 +#define MODE_9k 1 +#define MODE_12k 2 +#define MODE_14k 3 +#define MODE_16k 4 +#define MODE_18k 5 +#define MODE_20k 6 +#define MODE_23k 7 +#define MODE_24k 8 +#define MRDTX 9 +//#define NUM_OF_MODES 10 /* see bits.h for bits definition */ + +#define EHF_MASK (int16)0x0008 /* homing frame pattern */ + +#define BIT_0 (int16)-127 +#define BIT_1 (int16)127 +#define BIT_0_ITU (int16)0x007F +#define BIT_1_ITU (int16)0x0081 + +/*---------------------------------------------------------------------------- +; END +----------------------------------------------------------------------------*/ + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_mem_funcs.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_mem_funcs.h new file mode 100644 index 00000000..42e74914 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/pvamrwbdecoder_mem_funcs.h @@ -0,0 +1,58 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: pvamrwbdecoder_mem_funcs.h + + +---------------------------------------------------------------------------- +; CONTINUE ONLY IF NOT ALREADY DEFINED +----------------------------------------------------------------------------*/ + +#ifndef PVAMRWBDECODER_MEM_FUNCS_H +#define PVAMRWBDECODER_MEM_FUNCS_H + + +#include "oscl_mem.h" + + + +#define pv_memset(to, c, n) oscl_memset(to, c, n) + + +#define pv_memcpy(to, from, n) oscl_memcpy(to, from, n) +#define pv_memmove(to, from, n) oscl_memmove(to, from, n) +#define pv_memcmp(p, q, n) oscl_memcmp(p, q, n) + + + +#endif diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/q_gain2_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/q_gain2_tab.cpp new file mode 100644 index 00000000..92c235f0 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/q_gain2_tab.cpp @@ -0,0 +1,244 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +#include "qisf_ns.h" + + +/* + * Tables for function q_gain2() + * + * g_pitch(Q14), g_code(Q11) + * + * pitch gain are ordered in table to reduce complexity + * during quantization of gains. + */ + + + + +const int16 t_qua_gain6b[NB_QUA_GAIN6B*2] = +{ + 1566, 1332, + 1577, 3557, + 3071, 6490, + 4193, 10163, + 4496, 2534, + 5019, 4488, + 5586, 15614, + 5725, 1422, + 6453, 580, + 6724, 6831, + 7657, 3527, + 8072, 2099, + 8232, 5319, + 8827, 8775, + 9740, 2868, + 9856, 1465, + 10087, 12488, + 10241, 4453, + 10859, 6618, + 11321, 3587, + 11417, 1800, + 11643, 2428, + 11718, 988, + 12312, 5093, + 12523, 8413, + 12574, 26214, + 12601, 3396, + 13172, 1623, + 13285, 2423, + 13418, 6087, + 13459, 12810, + 13656, 3607, + 14111, 4521, + 14144, 1229, + 14425, 1871, + 14431, 7234, + 14445, 2834, + 14628, 10036, + 14860, 17496, + 15161, 3629, + 15209, 5819, + 15299, 2256, + 15518, 4722, + 15663, 1060, + 15759, 7972, + 15939, 11964, + 16020, 2996, + 16086, 1707, + 16521, 4254, + 16576, 6224, + 16894, 2380, + 16906, 681, + 17213, 8406, + 17610, 3418, + 17895, 5269, + 18168, 11748, + 18230, 1575, + 18607, 32767, + 18728, 21684, + 19137, 2543, + 19422, 6577, + 19446, 4097, + 19450, 9056, + 20371, 14885 +}; + +const int16 t_qua_gain7b[NB_QUA_GAIN7B*2] = +{ + 204, 441, + 464, 1977, + 869, 1077, + 1072, 3062, + 1281, 4759, + 1647, 1539, + 1845, 7020, + 1853, 634, + 1995, 2336, + 2351, 15400, + 2661, 1165, + 2702, 3900, + 2710, 10133, + 3195, 1752, + 3498, 2624, + 3663, 849, + 3984, 5697, + 4214, 3399, + 4415, 1304, + 4695, 2056, + 5376, 4558, + 5386, 676, + 5518, 23554, + 5567, 7794, + 5644, 3061, + 5672, 1513, + 5957, 2338, + 6533, 1060, + 6804, 5998, + 6820, 1767, + 6937, 3837, + 7277, 414, + 7305, 2665, + 7466, 11304, + 7942, 794, + 8007, 1982, + 8007, 1366, + 8326, 3105, + 8336, 4810, + 8708, 7954, + 8989, 2279, + 9031, 1055, + 9247, 3568, + 9283, 1631, + 9654, 6311, + 9811, 2605, + 10120, 683, + 10143, 4179, + 10245, 1946, + 10335, 1218, + 10468, 9960, + 10651, 3000, + 10951, 1530, + 10969, 5290, + 11203, 2305, + 11325, 3562, + 11771, 6754, + 11839, 1849, + 11941, 4495, + 11954, 1298, + 11975, 15223, + 11977, 883, + 11986, 2842, + 12438, 2141, + 12593, 3665, + 12636, 8367, + 12658, 1594, + 12886, 2628, + 12984, 4942, + 13146, 1115, + 13224, 524, + 13341, 3163, + 13399, 1923, + 13549, 5961, + 13606, 1401, + 13655, 2399, + 13782, 3909, + 13868, 10923, + 14226, 1723, + 14232, 2939, + 14278, 7528, + 14439, 4598, + 14451, 984, + 14458, 2265, + 14792, 1403, + 14818, 3445, + 14899, 5709, + 15017, 15362, + 15048, 1946, + 15069, 2655, + 15405, 9591, + 15405, 4079, + 15570, 7183, + 15687, 2286, + 15691, 1624, + 15699, 3068, + 15772, 5149, + 15868, 1205, + 15970, 696, + 16249, 3584, + 16338, 1917, + 16424, 2560, + 16483, 4438, + 16529, 6410, + 16620, 11966, + 16839, 8780, + 17030, 3050, + 17033, 18325, + 17092, 1568, + 17123, 5197, + 17351, 2113, + 17374, 980, + 17566, 26214, + 17609, 3912, + 17639, 32767, + 18151, 7871, + 18197, 2516, + 18202, 5649, + 18679, 3283, + 18930, 1370, + 19271, 13757, + 19317, 4120, + 19460, 1973, + 19654, 10018, + 19764, 6792, + 19912, 5135, + 20040, 2841, + 21234, 19833 +}; + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/q_pulse.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/q_pulse.h new file mode 100644 index 00000000..172a6f95 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/q_pulse.h @@ -0,0 +1,73 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./cpp/include/q_pulse.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + + Coding and decoding of algebraic codebook +------------------------------------------------------------------------------ +*/ + +#ifndef Q_PULSE_H +#define Q_PULSE_H + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + + void dec_1p_N1(int32 index, int16 N, int16 offset, int16 pos[]); + void dec_2p_2N1(int32 index, int16 N, int16 offset, int16 pos[]); + void dec_3p_3N1(int32 index, int16 N, int16 offset, int16 pos[]); + void dec_4p_4N1(int32 index, int16 N, int16 offset, int16 pos[]); + void dec_4p_4N(int32 index, int16 N, int16 offset, int16 pos[]); + void dec_5p_5N(int32 index, int16 N, int16 offset, int16 pos[]); + void dec_6p_6N_2(int32 index, int16 N, int16 offset, int16 pos[]); + + +#ifdef __cplusplus +} +#endif + +#endif /* Q_PULSE_H */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qisf_ns.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qisf_ns.cpp new file mode 100644 index 00000000..10483e84 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qisf_ns.cpp @@ -0,0 +1,137 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: qisf_ns.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 indice[] : indices of the selected codebook entries + int16 isf[] : quantized ISFs (in frequency domain) + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Coding/Decoding of ISF parameters for background noise. + + The ISF vector is quantized using VQ with split-by-5 + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_acelp.h" +#include "qisf_ns.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void Disf_ns( + int16 * indice, /* input: quantization indices */ + int16 * isf_q /* input: ISF in the frequency domain (0..0.5)*/ +) +{ + int16 i; + + isf_q[0] = dico1_isf_noise[(indice[0] << 1)]; + isf_q[1] = dico1_isf_noise[(indice[0] << 1) + 1]; + + for (i = 0; i < 3; i++) + { + isf_q[i + 2] = dico2_isf_noise[(indice[1] << 1) + indice[1] + i]; + isf_q[i + 5] = dico3_isf_noise[(indice[2] << 1) + indice[2] + i]; + } + + for (i = 0; i < 4; i++) + { + isf_q[i + 8] = dico4_isf_noise[(indice[3] << 2) + i]; + isf_q[i + 12] = dico5_isf_noise[(indice[4] << 2) + i]; + } + + for (i = 0; i < ORDER; i++) + { + isf_q[i] = add_int16(isf_q[i], mean_isf_noise[i]); + } + + Reorder_isf(isf_q, ISF_GAP, ORDER); + +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qisf_ns.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qisf_ns.h new file mode 100644 index 00000000..eddf1f5c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qisf_ns.h @@ -0,0 +1,107 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./cpp/include/qisf_ns.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +#ifndef QISF_NS_H +#define QISF_NS_H + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" + +/*---------------------------------------------------------------------------- +; DEFINES +----------------------------------------------------------------------------*/ + + +#define ORDER 16 /* order of linear prediction filter */ +#define ISF_GAP 128 + +#define SIZE_BK_NOISE1 64 +#define SIZE_BK_NOISE2 64 +#define SIZE_BK_NOISE3 64 +#define SIZE_BK_NOISE4 32 +#define SIZE_BK_NOISE5 32 + +#define NB_QUA_GAIN6B 64 /* Number of quantization level */ +#define NB_QUA_GAIN7B 128 /* Number of quantization level */ + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +----------------------------------------------------------------------------*/ +extern const int16 mean_isf_noise[ORDER]; +extern const int16 dico1_isf_noise[SIZE_BK_NOISE1*2]; +extern const int16 dico2_isf_noise[SIZE_BK_NOISE2*3]; +extern const int16 dico3_isf_noise[SIZE_BK_NOISE3*3]; +extern const int16 dico4_isf_noise[SIZE_BK_NOISE4*4]; +extern const int16 dico5_isf_noise[SIZE_BK_NOISE5*4]; + +extern const int16 t_qua_gain6b[NB_QUA_GAIN6B*2]; +extern const int16 t_qua_gain7b[NB_QUA_GAIN7B*2]; + +/*---------------------------------------------------------------------------- +; SIMPLE TYPEDEF'S +----------------------------------------------------------------------------*/ + + + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#ifdef __cplusplus +} +#endif + + + + +#endif /* QISF_NS_H */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qisf_ns_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qisf_ns_tab.cpp new file mode 100644 index 00000000..e5630e8d --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qisf_ns_tab.cpp @@ -0,0 +1,367 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* + * qisf_ns_tab.cpp + * + * Quantization tables for split by 5 VQ of ISFs for a background + * noise database + * Version whith no prediction + */ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "qisf_ns.h" + + +/* means of ISFs */ +const int16 mean_isf_noise[ORDER] = +{ + + 478, 1100, 2213, 3267, 4219, 5222, 6198, 7240, + 8229, 9153, 10098, 11108, 12144, 13184, 14165, 3803 +}; + + +/* 28 bits */ +/* + * isf codebooks: split-by-5 VQ + * + * codebook vector dimension number of vectors + * ~~~~~~~~ ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ + * 1 2 64 + * 2 3 64 + * 3 3 64 + * 4 4 32 + * 5 4 32 + */ + +/* + * 1st split: isf0 to isf1 + */ + + +const int16 dico1_isf_noise[SIZE_BK_NOISE1*2] = +{ + + -269, -673, + -222, -537, + -233, -430, + -138, -451, + -212, -331, + -192, -241, + -87, -231, + -191, -128, + -70, -106, + -164, -6, + 74, -179, + 27, -33, + -102, 74, + -162, 115, + -94, 172, + -6, 130, + -143, 234, + 14, 218, + -65, 270, + 88, 182, + -124, 341, + -44, 381, + 38, 335, + 117, 274, + -112, 454, + 74, 431, + -5, 488, + 175, 384, + -83, 561, + 122, 529, + 21, 601, + 229, 481, + 231, 303, + 226, 608, + 300, 372, + 210, 187, + 306, 265, + 328, 473, + 382, 331, + 371, 132, + 139, 58, + 365, 21, + 250, -82, + 443, 218, + 483, 110, + 426, 415, + 579, 222, + 518, 333, + 573, 448, + 455, 529, + 685, 329, + 332, 580, + 595, 593, + 468, 645, + 762, 517, + 326, 709, + 485, 793, + 130, 684, + 671, 737, + 354, 876, + 88, 806, + -65, 706, + -35, 1016, + 266, 1123 +}; + + +/* + * 2nd split: isf2 to isf4 + */ + +const int16 dico2_isf_noise[SIZE_BK_NOISE2*3] = +{ + + -824, -884, -949, + -805, -456, -418, + -442, -438, -541, + -217, -578, -793, + -168, -444, -582, + -287, -492, -274, + -552, -297, -300, + -163, -333, -358, + -370, -232, -232, + -175, -358, -159, + -381, -21, -357, + -184, -159, -162, + -53, -191, -280, + 18, -267, -215, + -138, 61, -283, + 71, -95, -294, + 13, -156, -546, + 0, -83, -79, + 44, 97, -316, + 178, -52, -213, + 222, -261, -422, + 237, -118, -44, + 141, 145, -132, + 363, 81, -287, + 213, 65, 34, + -107, 94, -5, + 91, -29, 126, + -355, 51, -41, + -219, -76, 145, + -63, 100, 244, + -719, 44, 27, + -572, -124, 155, + -423, 133, 315, + -917, 71, 224, + -268, 318, 131, + -93, -190, 420, + -97, 122, 491, + -79, 317, 355, + 130, 100, 325, + 86, -293, 210, + 133, 258, 161, + 176, -73, 465, + 195, 300, 384, + 348, 22, 221, + 376, 183, 409, + 377, 286, 202, + 242, 213, 659, + 257, 565, 248, + 344, 408, -76, + 405, 440, 509, + 612, 385, 379, + 536, 607, 216, + -56, 582, 192, + 100, 517, 567, + -365, 448, 445, + 728, 347, 10, + 505, 357, 759, + 636, 582, 658, + 335, 517, 852, + 378, 809, 572, + -195, 878, 829, + 529, 707, 987, + 918, 726, 392, + 1250, 997, 1063 +}; + +/* + * 3rd split: isf5 to isf7 + */ + +const int16 dico3_isf_noise[SIZE_BK_NOISE3*3] = +{ + + -805, -838, -774, + -522, -627, -828, + -477, -486, -603, + -295, -481, -634, + -366, -384, -393, + -186, -414, -396, + -237, -394, -106, + -252, -202, -275, + -61, -177, -442, + -84, -198, -199, + -179, -125, -31, + -72, -47, -163, + -298, -220, 215, + -64, -168, 251, + -133, 156, -59, + -30, -2, 127, + 54, 66, -61, + -233, 21, 251, + 209, -50, 32, + 33, 194, 136, + -117, -18, 475, + 202, 46, 309, + 256, 185, 53, + 35, 200, 390, + 200, 263, 242, + -216, 302, 294, + 128, 358, 0, + 19, 431, 287, + 224, 447, 280, + 367, 165, 213, + 397, 314, 319, + 383, 379, 75, + 277, 325, 462, + 394, 505, 334, + 251, 98, -213, + 450, 153, 448, + 565, 226, 76, + 470, 383, 502, + 635, 390, 278, + 237, 135, 620, + 342, 401, 649, + 331, 551, 518, + 130, 418, 592, + 531, 306, 737, + 729, 389, 580, + 497, 557, 699, + 296, 383, 874, + 283, 624, 759, + 126, 622, 476, + 559, 595, 472, + 382, 770, 616, + 719, 613, 745, + 540, 639, 928, + 517, 826, 801, + 684, 811, 604, + 752, 786, 857, + 933, 661, 350, + 694, 450, 1061, + 562, 911, 1051, + 824, 813, 1104, + 758, 1047, 882, + 1140, 917, 889, + 1039, 1246, 1426, + 1483, 1666, 1876 +}; + +/* + * 4th split: isf8 to isf11 + */ + +const int16 dico4_isf_noise[SIZE_BK_NOISE4*4] = +{ + + -776, -854, -891, -920, + -552, -610, -663, -741, + -321, -370, -476, -565, + 274, -160, -456, 201, + 265, 67, -160, -306, + -8, -210, 79, 272, + 163, 236, 307, 308, + 578, 317, 64, 298, + -9, 197, 342, 620, + 343, 232, 314, 622, + 173, 149, 548, 527, + 356, 370, 481, 376, + 135, 444, 488, 556, + 391, 471, 487, 653, + 228, 424, 576, 835, + 422, 372, 722, 682, + 295, 673, 693, 635, + 539, 596, 590, 449, + 475, 618, 659, 818, + 735, 517, 491, 673, + 602, 346, 257, 877, + 625, 635, 849, 720, + 727, 818, 698, 595, + 653, 481, 690, 1139, + 814, 762, 704, 908, + 507, 747, 898, 936, + 848, 855, 924, 785, + 646, 1037, 882, 795, + 772, 845, 1024, 1151, + 1133, 983, 818, 921, + 940, 1068, 1252, 1302, + 1588, 1767, 1718, 1513 +}; + +/* + * 5th split: isf12 to isf15 + */ + +const int16 dico5_isf_noise[SIZE_BK_NOISE5*4] = +{ + -810, -879, -945, -254, + 248, 184, 671, 128, + 288, 703, 918, 99, + 658, 558, 662, 219, + 552, 585, 910, 208, + 559, 804, 759, 119, + 606, 774, 921, -139, + 782, 761, 748, 208, + 756, 708, 983, 56, + 544, 864, 1010, 152, + 737, 698, 987, 299, + 771, 924, 879, 103, + 536, 785, 961, 405, + 667, 916, 801, 328, + 738, 705, 773, 439, + 823, 871, 992, 355, + 640, 1004, 1052, 369, + 724, 822, 949, 597, + 415, 655, 729, 482, + 1009, 896, 793, 363, + 908, 803, 687, -25, + 1016, 838, 1011, 189, + 947, 1112, 942, 222, + 914, 1049, 981, 527, + 956, 987, 1011, -120, + 781, 1049, 1121, 92, + 1178, 1053, 884, 47, + 1123, 1059, 1182, 118, + 933, 972, 1277, 357, + 1109, 918, 1101, 503, + 1039, 1286, 1220, 317, + 1351, 1207, 1010, 326 +}; + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qpisf_2s.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qpisf_2s.cpp new file mode 100644 index 00000000..0b635635 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qpisf_2s.cpp @@ -0,0 +1,342 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: qpisf_2s.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 * seed seed for the random ng + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Coding/Decoding of ISF parameters with prediction. + + The ISF vector is quantized using two-stage VQ with split-by-2 + in 1st stage and split-by-5 (or 3)in the second stage. + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" + +#include "qisf_ns.h" +#include "qpisf_2s.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define MU 10923 /* Prediction factor (1.0/3.0) in Q15 */ +#define N_SURV_MAX 4 /* 4 survivors max */ +#define ALPHA 29491 /* 0. 9 in Q15 */ +#define ONE_ALPHA (32768-ALPHA) /* (1.0 - ALPHA) in Q15 */ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------* + * routine: Disf_2s_46b() * + * ~~~~~~~~~ * + * Decoding of ISF parameters * + *-------------------------------------------------------------------*/ + +void Dpisf_2s_46b( + int16 * indice, /* input: quantization indices */ + int16 * isf_q, /* output: quantized ISF in frequency domain (0..0.5) */ + int16 * past_isfq,/* i/0 : past ISF quantizer */ + int16 * isfold, /* input : past quantized ISF */ + int16 * isf_buf, /* input : isf buffer */ + int16 bfi, /* input : Bad frame indicator */ + int16 enc_dec +) +{ + int16 ref_isf[M]; + int16 i, j, tmp; + int32 L_tmp; + + + if (bfi == 0) /* Good frame */ + { + for (i = 0; i < 9; i++) + { + isf_q[i] = dico1_isf[(indice[0] << 3) + indice[0] + i]; + } + for (i = 0; i < 7; i++) + { + isf_q[i + 9] = dico2_isf[(indice[1] << 3) - indice[1] + i]; + } + + for (i = 0; i < 3; i++) + { + isf_q[i] += dico21_isf[indice[2] * 3 + i]; + isf_q[i + 3] += dico22_isf[indice[3] * 3 + i]; + isf_q[i + 6] += dico23_isf[indice[4] * 3 + i]; + isf_q[i + 9] += dico24_isf[indice[5] * 3 + i]; + isf_q[i + 12] += dico25_isf[(indice[6] << 2) + i]; + } + + isf_q[i + 12] += dico25_isf[(indice[6] << 2) + i]; + + for (i = 0; i < ORDER; i++) + { + tmp = isf_q[i]; + isf_q[i] += mean_isf[i]; + isf_q[i] += ((int32)MU * past_isfq[i]) >> 15; + past_isfq[i] = tmp; + } + + + if (enc_dec) + { + for (i = 0; i < M; i++) + { + for (j = (L_MEANBUF - 1); j > 0; j--) + { + isf_buf[j * M + i] = isf_buf[(j - 1) * M + i]; + } + isf_buf[i] = isf_q[i]; + } + } + } + else + { /* bad frame */ + for (i = 0; i < M; i++) + { + L_tmp = mul_16by16_to_int32(mean_isf[i], 8192); + for (j = 0; j < L_MEANBUF; j++) + { + L_tmp = mac_16by16_to_int32(L_tmp, isf_buf[j * M + i], 8192); + } + ref_isf[i] = amr_wb_round(L_tmp); + } + + /* use the past ISFs slightly shifted towards their mean */ + for (i = 0; i < ORDER; i++) + { + isf_q[i] = add_int16(mult_int16(ALPHA, isfold[i]), mult_int16(ONE_ALPHA, ref_isf[i])); + } + + /* estimate past quantized residual to be used in next frame */ + + for (i = 0; i < ORDER; i++) + { + tmp = add_int16(ref_isf[i], mult_int16(past_isfq[i], MU)); /* predicted ISF */ + past_isfq[i] = sub_int16(isf_q[i], tmp); + past_isfq[i] >>= 1; /* past_isfq[i] *= 0.5 */ + } + + } + + Reorder_isf(isf_q, ISF_GAP, ORDER); +} + +/* + * routine: Disf_2s_36b() + * ~~~~~~~~~ + * Decoding of ISF parameters + */ + +void Dpisf_2s_36b( + int16 * indice, /* input: quantization indices */ + int16 * isf_q, /* output: quantized ISF in frequency domain (0..0.5) */ + int16 * past_isfq, /* i/0 : past ISF quantizer */ + int16 * isfold, /* input : past quantized ISF */ + int16 * isf_buf, /* input : isf buffer */ + int16 bfi, /* input : Bad frame indicator */ + int16 enc_dec +) +{ + int16 ref_isf[M]; + int16 i, j, tmp; + int32 L_tmp; + + + if (bfi == 0) /* Good frame */ + { + for (i = 0; i < 9; i++) + { + isf_q[i] = dico1_isf[indice[0] * 9 + i]; + } + for (i = 0; i < 7; i++) + { + isf_q[i + 9] = add_int16(dico2_isf[indice[1] * 7 + i], dico23_isf_36b[indice[4] * 7 + i]); + } + + for (i = 0; i < 5; i++) + { + isf_q[i] = add_int16(isf_q[i], dico21_isf_36b[indice[2] * 5 + i]); + } + for (i = 0; i < 4; i++) + { + isf_q[i + 5] = add_int16(isf_q[i + 5], dico22_isf_36b[(indice[3] << 2) + i]); + } + + for (i = 0; i < ORDER; i++) + { + tmp = isf_q[i]; + isf_q[i] = add_int16(tmp, mean_isf[i]); + isf_q[i] = add_int16(isf_q[i], mult_int16(MU, past_isfq[i])); + past_isfq[i] = tmp; + } + + + if (enc_dec) + { + for (i = 0; i < M; i++) + { + for (j = (L_MEANBUF - 1); j > 0; j--) + { + isf_buf[j * M + i] = isf_buf[(j - 1) * M + i]; + } + isf_buf[i] = isf_q[i]; + } + } + } + else + { /* bad frame */ + for (i = 0; i < M; i++) + { + L_tmp = mul_16by16_to_int32(mean_isf[i], 8192); + for (j = 0; j < L_MEANBUF; j++) + { + L_tmp = mac_16by16_to_int32(L_tmp, isf_buf[j * M + i], 8192); + } + + ref_isf[i] = amr_wb_round(L_tmp); + } + + /* use the past ISFs slightly shifted towards their mean */ + for (i = 0; i < ORDER; i++) + { + isf_q[i] = add_int16(mult_int16(ALPHA, isfold[i]), mult_int16(ONE_ALPHA, ref_isf[i])); + } + + /* estimate past quantized residual to be used in next frame */ + + for (i = 0; i < ORDER; i++) + { + tmp = add_int16(ref_isf[i], mult_int16(past_isfq[i], MU)); /* predicted ISF */ + past_isfq[i] = sub_int16(isf_q[i], tmp); + past_isfq[i] >>= 1; /* past_isfq[i] *= 0.5 */ + } + } + + Reorder_isf(isf_q, ISF_GAP, ORDER); + + return; +} + +/* + * procedure Reorder_isf() + * ~~~~~~~~~~~~~ + * To make sure that the isfs are properly order and to keep a certain + * minimum distance between consecutive isfs. + * + * Argument description in/out + * ~~~~~~~~ ~~~~~~~~~~~ ~~~~~~ + * isf[] vector of isfs i/o + * min_dist minimum required distance i + * n LPC order i + */ + +void Reorder_isf( + int16 * isf, /* (i/o) Q15: ISF in the frequency domain (0..0.5) */ + int16 min_dist, /* (i) Q15 : minimum distance to keep */ + int16 n /* (i) : number of ISF */ +) +{ + int16 i, isf_min; + + isf_min = min_dist; + + for (i = 0; i < n - 1; i++) + { + if (isf[i] < isf_min) + { + isf[i] = isf_min; + } + isf_min = add_int16(isf[i], min_dist); + } + + return; +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qpisf_2s.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qpisf_2s.h new file mode 100644 index 00000000..51e32b60 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qpisf_2s.h @@ -0,0 +1,111 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./cpp/include/qpisf_2s.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +#ifndef QPISF_2S_H +#define QPISF_2S_H + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "qisf_ns.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +----------------------------------------------------------------------------*/ + +#define N_SURV 4 + +#define SIZE_BK1 256 +#define SIZE_BK2 256 +#define SIZE_BK21 64 +#define SIZE_BK22 128 +#define SIZE_BK23 128 +#define SIZE_BK24 32 +#define SIZE_BK25 32 + +#define SIZE_BK21_36b 128 +#define SIZE_BK22_36b 128 +#define SIZE_BK23_36b 64 + + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +----------------------------------------------------------------------------*/ +extern const int16 mean_isf[ORDER]; +extern const int16 dico1_isf[SIZE_BK1*9]; +extern const int16 dico2_isf[SIZE_BK2*7]; +extern const int16 dico21_isf[SIZE_BK21*3]; +extern const int16 dico22_isf[SIZE_BK22*3]; +extern const int16 dico23_isf[SIZE_BK23*3]; +extern const int16 dico24_isf[SIZE_BK24*3]; +extern const int16 dico25_isf[SIZE_BK25*4]; +extern const int16 dico21_isf_36b[SIZE_BK21_36b*5]; +extern const int16 dico22_isf_36b[SIZE_BK22_36b*4]; +extern const int16 dico23_isf_36b[SIZE_BK23_36b*7]; + +/*---------------------------------------------------------------------------- +; SIMPLE TYPEDEF'S +----------------------------------------------------------------------------*/ + + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#ifdef __cplusplus +} +#endif + + + + +#endif /* QPISF_2S_H */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qpisf_2s_tab.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qpisf_2s_tab.cpp new file mode 100644 index 00000000..d57522ec --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/qpisf_2s_tab.cpp @@ -0,0 +1,1383 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/*-------------------------------------------------------------------* + * qpisf_2s_tab.cpp + *-------------------------------------------------------------------* + * Quantization tables for two-stage of ISFs (split by 2 in 1st stage) + * Version whith prediction MU = 0.25 + *-------------------------------------------------------------------*/ + +#include "qisf_ns.h" +#include "qpisf_2s.h" + + + + +/* means of ISFs */ +const int16 mean_isf[ORDER] = +{ + + 738, 1326, 2336, 3578, 4596, 5662, 6711, 7730, + 8750, 9753, 10705, 11728, 12833, 13971, 15043, 4037 +}; + +/* 46 bits */ +/* + * isf codebooks: two-stage VQ with split-by-5 in 2nd stage + * + * codebook vector dimension number of vectors + * ~~~~~~~~ ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ + * 1_1 9 256 + * 1_2 7 256 + * 2_1 3 64 + * 2_2 3 128 + * 2_3 3 128 + * 2_4 3 32 + * 2_5 4 32 + */ + +/* + * 1st stage codebook; 1st split: isf0 to isf8 + */ + +const int16 dico1_isf[SIZE_BK1*9] = +{ + + 579, 1081, 1035, 390, 3, -263, -198, -82, 38, + 18, -68, -12, 313, 761, 405, 249, 111, -76, + 740, 1263, 1292, 1006, 997, 1019, 1017, 976, 923, + -91, 827, 948, 648, 613, 535, 522, 490, 421, + 41, -44, -281, -472, 652, 534, 193, 135, -90, + 41, -121, -356, -60, 663, 307, 61, -48, -344, + 557, 946, 1049, 867, 846, 990, 1112, 1262, 1241, + -118, -204, 328, 512, 870, 793, 610, 402, 186, + 156, 293, 74, -338, -475, -897, -594, -161, -497, + 226, 131, -138, 307, 169, -271, -164, -387, -624, + 62, -32, -61, -252, -541, -828, -1027, -523, -662, + 102, -61, 141, 112, -270, -251, -541, 25, -150, + 6, -132, -356, -686, -96, -322, -522, -31, -326, + -36, -209, -521, -229, 307, -132, -5, -99, -384, + 60, -51, -237, -668, -973, -407, -708, -75, -172, + 26, -138, -266, 111, -302, 43, -278, -356, -359, + 570, 822, 496, -154, -312, -92, 137, 279, 371, + -146, 368, 409, 68, 6, 77, 167, 202, 162, + 633, 898, 996, 756, 662, 683, 783, 909, 996, + -103, 294, 607, 415, 483, 462, 480, 431, 408, + -120, -338, -612, -524, 584, 331, 92, 433, 276, + -178, -293, -154, -41, 269, 100, -9, 213, 160, + 830, 736, 278, 820, 1254, 686, 712, 1039, 473, + -218, -304, 463, 454, 397, 273, 202, 286, 273, + -232, 7, 6, -388, -472, -427, -378, -167, -100, + -294, -183, 134, -47, 101, -88, -84, -117, -3, + 57, 17, -202, -634, -989, -1119, -533, 176, -36, + 120, -28, 23, 111, -319, 318, -22, -77, 266, + -271, -464, -434, -658, -640, -385, -385, -99, -69, + -198, -259, -266, -44, -39, -139, -137, 171, 66, + 9, -145, -377, -846, -1000, -111, -325, 342, 135, + -81, -286, -380, 192, -57, 307, 76, -24, -140, + 677, 702, 247, 56, 249, 141, -105, -236, -99, + 36, -39, -69, 348, 198, -93, 322, 91, -72, + 503, 885, 1508, 1307, 1282, 1172, 1119, 1209, 1061, + 416, 719, 989, 1227, 1001, 1052, 954, 741, 1044, + -127, -376, -657, 139, 623, 223, 501, 306, 220, + -113, -384, -796, 504, 438, 85, 213, -83, -194, + 585, 1132, 1233, 1091, 1247, 1433, 1512, 1448, 1314, + -174, -422, 7, 1155, 1089, 1182, 1003, 945, 806, + 8, -126, -317, -103, -351, -695, -98, -268, -537, + 33, -103, -290, 167, -39, -407, 44, -208, -375, + 104, -23, -64, -291, -637, -851, -1084, -61, -112, + -75, -306, -434, 218, -148, -354, -680, -133, -216, + -121, -377, -718, -97, -130, -361, -156, -379, -599, + -56, -254, -586, 235, 157, -214, 11, -260, -149, + -124, -267, -397, -580, -593, -527, -805, -385, 346, + -193, -440, -708, -351, -141, -255, -499, -147, -185, + 448, 660, 494, 208, 509, 461, 338, 291, 149, + -223, 88, 335, 159, 212, 191, 286, 308, 205, + -31, 469, 803, 659, 619, 658, 843, 987, 1113, + -171, -242, 514, 362, 295, 524, 552, 694, 585, + -64, -308, -448, -21, 284, 786, 446, 289, 92, + -218, -390, -7, 169, 206, 330, 352, 408, 358, + -36, 702, 959, 859, 861, 1115, 1269, 1357, 1305, + -133, -341, -65, 678, 417, 440, 486, 518, 780, + 33, -44, -191, -344, -461, -755, -201, 217, -31, + -353, -547, -44, 123, -61, -68, -79, 29, 60, + 73, -57, -406, -766, -1243, -1203, 240, 400, 165, + -73, -282, -601, -213, -171, -375, 332, 35, -103, + -29, -207, -553, -476, -638, -908, 172, -22, -135, + -192, -239, -164, -103, -111, -47, 153, 125, 110, + -1, -203, -570, -1030, -1424, -535, 155, 1, 147, + -333, -653, -865, -197, -158, -21, -44, 95, 108, + 389, 588, 490, 33, -237, -524, -628, -136, -260, + 40, -177, -462, 453, 862, 380, 131, -130, -405, + 842, 1678, 1841, 1549, 1474, 1256, 1082, 905, 742, + 370, 1216, 1768, 1633, 1212, 636, 22, -330, 71, + -76, -281, -741, -742, 898, 619, 277, 71, -222, + -32, -265, -556, -25, 994, 682, 305, 126, -165, + 73, 738, 893, 968, 993, 1768, 2273, 1840, 1391, + -69, -349, -585, 234, 1158, 903, 626, 510, 251, + -1, -99, -272, -210, -603, -351, -540, -811, -383, + -16, -230, -504, 410, 149, -205, -343, -651, -639, + 103, -9, -227, -205, -562, -781, -1079, -1208, -156, + 143, 63, -135, -67, -317, -602, -784, -1154, -640, + -144, -391, -674, -622, -200, -254, -660, -947, -395, + -40, -250, -625, 27, 543, 94, -131, -386, -673, + -123, -371, -757, -451, -564, -614, -415, -711, -35, + -116, -309, -593, -268, 239, -33, -338, -650, -135, + 94, 251, 554, 57, -312, -423, -154, -57, 235, + -268, -71, 381, 114, -44, -87, 125, 173, 133, + 1513, 1714, 1238, 534, 276, 315, 461, 459, 508, + -131, -19, 1149, 670, 486, 356, 309, 369, 296, + -223, -501, -899, -722, -70, 6, 131, 310, 394, + -99, -303, -517, 249, 64, -53, 135, -11, 453, + -147, -399, -730, -401, 817, 738, 802, 749, 575, + -154, -435, -739, 800, 593, 366, 529, 318, 326, + -224, 45, -39, -387, -515, -518, -608, -384, -321, + -315, -377, 143, -101, -113, -377, -177, -144, -12, + 117, 40, -239, -651, -1051, -581, -737, -990, -328, + 26, -50, -157, -23, -453, -283, -531, -546, 192, + -252, -501, -743, -589, -627, -499, -328, -118, -72, + -324, -494, -244, -306, -144, -177, -262, -135, -78, + -36, -234, -519, -961, -1290, -314, -479, -371, -45, + -95, -292, -535, -8, -300, 112, -164, -277, 198, + -99, -128, 880, 836, 579, 351, 23, -95, -217, + -27, -258, 124, 1011, 597, 425, 144, 7, -73, + 421, 1293, 1640, 1623, 1742, 1617, 1499, 1284, 1006, + -95, 752, 1680, 1569, 1618, 1436, 1200, 980, 712, + -69, -300, -683, -435, 1132, 899, 504, 332, 109, + -74, -323, -637, 563, 1074, 608, 371, 105, -49, + -78, 831, 1194, 1110, 1378, 1481, 1492, 1365, 1217, + -259, -121, 1440, 1334, 1628, 1490, 1438, 1223, 933, + -82, -306, -613, -222, -378, -675, -545, -671, -845, + 53, -124, -347, 422, 52, -125, -270, -529, 9, + 79, -89, -320, -662, -999, -1199, -1243, -676, -297, + -68, -273, -611, 137, -146, -397, -627, -845, -220, + -112, -346, -797, -826, 234, -132, -188, -278, -522, + -159, -405, -734, -419, 293, 74, -167, -167, 184, + -153, -437, -833, -1080, -336, -472, -561, -340, -253, + -169, -423, -820, -904, -131, -19, -346, -604, 31, + 33, -31, 312, 62, -148, 49, -59, 564, 486, + -306, -333, 194, -44, 67, 72, 147, 205, 243, + -207, -49, 1360, 983, 969, 991, 1014, 1110, 973, + -211, -172, 883, 627, 711, 674, 705, 798, 746, + -88, -325, -763, -974, 687, 908, 514, 382, 172, + -292, -612, -805, 63, 131, 270, 259, 352, 348, + -235, -84, 955, 818, 1120, 1289, 1559, 1480, 1285, + -180, -461, -614, 657, 691, 745, 854, 783, 713, + -97, -309, -477, -614, -777, -734, -768, -526, -472, + -344, -476, -35, -169, 49, -77, -150, -240, -141, + -52, -268, -639, -919, -1278, -1113, -342, -333, -151, + -68, -242, -585, -73, -209, -478, -159, -429, 133, + -197, -499, -1005, -1268, -272, -224, -105, -67, 17, + -363, -618, -414, -116, -62, 20, 10, 116, 108, + -195, -475, -906, -1260, -891, -441, -277, -142, -28, + -226, -519, -950, -700, -275, -266, -116, -105, 82, + 404, 511, 520, 327, 17, -194, -333, -536, -586, + -114, -130, 276, 237, 204, 342, 135, -16, -111, + 670, 1208, 1168, 860, 742, 601, 528, 403, 309, + 397, 621, 966, 752, 579, 398, 400, 329, 252, + 191, 180, -137, -467, 272, 106, -95, 17, -192, + -80, -290, -626, 194, 598, 196, 21, -281, 77, + 510, 864, 1108, 807, 939, 902, 925, 717, 481, + 137, 367, 534, 764, 670, 382, 296, 153, 84, + 303, 497, 144, -85, -125, -539, -482, -464, -764, + 233, 347, 68, -147, 169, -210, -242, -226, -482, + 307, 422, 154, -175, -386, -722, -724, -904, -1015, + 309, 308, 160, -60, -470, -420, -598, -791, -219, + 68, 121, -137, -560, -146, -446, -515, -494, -729, + 130, 53, -227, 46, 474, 32, -161, -192, -490, + 213, 164, -71, -465, -876, -161, -456, -587, -48, + 218, 117, 39, 177, -194, -88, -226, -418, 50, + 210, 547, 569, 279, 121, -44, -50, 10, -84, + 58, 140, 182, -5, 267, 117, 106, 211, 198, + 539, 835, 913, 719, 617, 544, 591, 565, 642, + 153, 559, 872, 460, 222, 108, 188, 180, 183, + 158, 119, 284, -153, -271, 229, 87, 110, -57, + -183, 82, 118, 21, 13, 40, 118, 191, 185, + 162, 889, 654, 108, -34, 244, 488, 561, 532, + 163, 56, 609, 341, 50, 329, 68, 266, 218, + 100, 206, 18, -304, -107, -436, -487, -65, -306, + -86, 154, 134, -30, -45, -73, -104, -80, -96, + 245, 330, 10, -440, -849, -1082, 79, 40, -265, + 196, 372, 272, -181, -493, -389, 275, 80, -59, + 2, -12, -246, -505, -100, -436, 21, -187, -431, + -221, -48, 36, -271, -186, -147, -109, 26, 71, + 213, 140, 72, -351, -620, -84, -363, 69, 46, + 91, 167, -3, -95, -99, -105, -48, 114, 147, + 259, 249, 172, 607, 406, 52, 59, -189, -320, + 115, -85, -54, 574, 128, 226, -59, -253, 130, + -62, 1033, 1308, 1035, 1127, 1098, 1029, 961, 823, + 39, 364, 757, 940, 728, 660, 659, 583, 770, + -115, -338, -760, -471, 394, 37, 441, 178, 6, + -57, -305, -525, 796, 453, 188, -4, -114, 248, + 71, 444, 797, 731, 1096, 1157, 1222, 1029, 811, + 135, 359, 551, 425, 749, 815, 874, 704, 502, + 132, 247, 0, -206, -449, -750, -258, -514, -633, + 248, 249, 91, 121, -195, -499, -90, -282, -435, + 78, 20, -277, -623, -983, -1224, -415, -458, -639, + 347, 509, 208, -179, -464, -728, -76, -237, -486, + -103, -343, -756, -713, -265, -609, -191, -398, -636, + -121, -383, -749, 567, 252, -36, -354, -417, -50, + 204, 100, -149, -650, -1081, -47, -7, -263, 111, + -46, -180, -267, -324, -562, -394, -692, 398, 292, + 482, 670, 683, 624, 442, 165, 116, 36, -149, + 108, 247, 291, 247, 355, 122, 109, 224, 296, + -14, 945, 990, 801, 755, 815, 847, 913, 892, + 292, 349, 725, 482, 388, 329, 429, 620, 667, + -34, 197, 213, -127, 84, 494, 620, 575, 375, + 126, 207, 172, 167, 362, 202, 296, 395, 455, + -6, 250, 539, 467, 636, 801, 1149, 1287, 1118, + 27, 240, 369, 280, 440, 411, 634, 892, 953, + 159, 170, -58, -395, -797, -690, 77, -211, -334, + -5, -28, -13, -74, -335, -603, 300, 88, -205, + 82, -33, -364, -698, -1203, -1153, 110, -146, -289, + 113, 1, -243, -588, -994, -496, 414, 160, 42, + -56, -247, -440, -693, -996, -479, 11, -178, -357, + -151, -353, -327, -211, -340, 141, 65, 425, 453, + 34, -169, -455, -932, -1215, 138, 499, 256, 324, + 68, 139, -15, -547, -478, 17, 306, 502, 481, + -32, -134, 445, 129, -143, -244, -503, -507, -599, + 61, -140, -345, 496, 458, -2, 20, -227, -514, + 394, 1765, 1666, 1339, 1117, 806, 642, 479, 380, + 215, 519, 920, 1053, 1090, 791, 528, 290, 155, + -54, -233, -647, -602, 639, 294, -2, -167, -442, + -78, -315, -791, -113, 820, 403, 158, -116, -356, + 529, 1851, 2003, 1228, 622, -41, -416, 344, 819, + -105, -379, -236, 1224, 893, 749, 568, 356, 214, + -17, -199, -144, 50, -283, -247, -578, -846, -1087, + 69, -11, -381, -206, 209, -284, -387, -416, -716, + 39, -5, -145, -374, -682, -909, -1074, -1169, -1066, + 287, 226, 67, -221, -662, -171, -421, -642, -707, + -132, -348, -538, -448, -20, -4, -354, -748, -933, + 4, -75, -289, -598, 317, 52, -208, -297, -559, + -88, -264, -358, -589, -631, -248, -523, -822, -1071, + 70, -8, 54, -314, -515, 92, -146, -274, -493, + 199, 62, 391, 158, -141, 71, -219, -203, -207, + 152, 40, 329, 162, -29, 48, -149, 108, 127, + 635, 1058, 883, 492, 372, 312, 317, 274, 241, + 267, 722, 1256, 882, 625, 248, 8, -81, -60, + -58, -138, -291, -600, -12, -2, -39, 147, 117, + -107, -345, -513, 459, 76, 92, -272, 388, 262, + 362, 516, 203, -409, -716, -831, -331, 185, 209, + -117, -391, -298, 671, 292, 538, 257, 166, -38, + -102, -319, -194, -283, -573, -262, -579, -219, -444, + -235, 78, 11, -168, -101, -229, -263, -321, -123, + 70, 50, -170, -599, -996, -588, -263, -516, -455, + 394, 363, 229, -136, -538, 21, -183, -348, -201, + -124, -368, -640, -879, -847, -209, -409, -494, -515, + -127, -341, -541, -425, -510, -10, -252, -473, -291, + 84, -69, -201, -676, -868, 103, -311, -132, -320, + 5, -173, -188, -297, -628, 197, -57, 7, -11, + 49, -160, 56, 558, 111, 33, -311, -440, -463, + -1, -246, -307, 862, 453, 139, -170, -355, -232, + 279, 966, 1642, 1478, 1463, 1123, 795, 525, 339, + -197, -38, 1702, 1331, 1252, 950, 692, 504, 426, + -108, -344, -861, -1172, 444, 354, 88, -46, -220, + -53, -321, -494, 1113, 744, 364, 198, -34, -75, + 457, 955, 1177, 1214, 1427, 1457, 1345, 917, 539, + -69, 199, 897, 1140, 1343, 1183, 977, 742, 522, + 122, 44, -269, 27, -155, -562, -307, -590, -773, + 154, 42, -160, 252, -129, -305, -471, -733, -371, + 135, 185, -82, -416, -722, -913, -504, -743, -880, + 149, 214, -84, -329, -680, -835, -426, -661, -81, + -128, -380, -735, -998, -337, 17, -182, -467, -697, + -84, -290, -510, -592, 13, 440, 154, -38, -279, + 70, -61, -246, -727, -1047, -80, -381, -535, -704, + 178, -2, -146, -670, -938, 482, 138, 63, 65, + -11, 15, 772, 443, 142, -20, -209, -126, -161, + -32, -249, 95, 552, 124, 30, -343, 82, -86, + 148, 751, 1515, 1105, 867, 606, 474, 448, 399, + -163, -257, 899, 1097, 906, 751, 502, 390, 294, + -51, -258, -447, -806, -368, 763, 464, 364, 183, + -166, -374, -367, 87, 35, 399, 418, 856, 833, + -205, -310, 588, 778, 785, 1065, 1118, 1245, 1157, + -173, -312, 107, 345, 400, 790, 870, 1113, 1001, + -7, -120, -387, -410, -614, -943, -226, -384, -491, + -203, -288, -51, -331, -90, -178, -408, -573, -338, + 56, -29, -273, -627, -1041, -798, -247, -467, 148, + 66, -2, -205, -205, -575, -349, -57, -352, -58, + -45, -225, -471, -924, -497, 77, -32, 44, -135, + -277, -491, -497, -502, -424, -202, -137, 77, 96, + 26, -179, -469, -1008, -1260, 262, -35, -132, -259, + -66, -232, -447, -533, -789, -191, -100, -267, 364 +}; + +/*------------------------------------------------* + * 1st stage codebook; 2nd split: isf9 to isf15 + *------------------------------------------------*/ + +const int16 dico2_isf[SIZE_BK2*7] = +{ + + 1357, 1313, 1136, 784, 438, 181, 145, + 636, 648, 667, 568, 442, 217, 362, + 427, 440, 674, 524, 332, 117, -417, + 121, 295, 468, 465, 230, 44, -221, + -147, -240, 149, 80, 390, 278, 106, + -418, -556, 552, 511, 235, 144, -95, + 43, 193, 274, 150, 67, 34, -273, + -43, -126, 171, 416, 282, 63, -354, + -372, -86, -344, -108, -94, -182, -89, + -600, -840, -200, 465, 258, -11, -253, + -48, 329, 97, -290, -543, -795, -354, + -570, -117, 187, 10, -133, -416, -76, + -618, -129, -247, -371, 45, -76, 277, + -1022, -1079, 126, 474, 254, 127, 52, + -281, 76, -167, -361, -283, -551, -283, + -119, -52, -1, 134, -32, -204, -415, + 1064, 827, 637, 684, 464, 209, 12, + 482, 416, 449, 371, 335, 294, 194, + 719, 576, 365, 135, 113, 91, -199, + 298, 176, 493, 366, 194, 163, 36, + -35, -236, -259, -36, -4, 99, 152, + -98, -306, -27, 228, 90, 111, -86, + 91, 13, -211, -258, -106, 86, -64, + 73, -35, -57, -31, 162, 35, -192, + -109, -335, -629, -66, -61, -128, 322, + -495, -669, -728, 193, 31, -220, 122, + 324, 95, -89, -91, -409, -710, -154, + 0, -234, 92, 33, -343, -609, -220, + -343, -408, -476, -655, -153, 82, 222, + -490, -745, -255, 49, -48, 135, -127, + 119, -67, -328, -390, -272, -545, -56, + -57, -130, -10, -7, -164, -47, -22, + 984, 1064, 961, 568, 210, -27, 16, + 811, 691, 754, 514, 224, -35, 166, + 662, 704, 618, 386, 57, -211, -257, + 510, 359, 418, 393, 91, -144, -18, + -193, -31, -27, 223, 89, -143, 24, + -112, -98, 471, 319, 185, 3, 175, + 252, 146, -47, 272, 48, -211, -234, + 146, 69, 203, 364, 68, -52, 51, + -259, -478, -697, -349, -758, -501, 63, + -501, -769, -289, 79, -311, -497, -106, + 251, 53, -235, -469, -895, -884, 145, + -416, -551, 140, -133, -523, -775, 44, + -326, -423, -713, -497, -86, -431, 99, + -757, -772, -160, -76, -46, -32, 379, + 85, -35, -200, -401, -663, -1040, -247, + -180, -330, -92, -376, 27, -183, -110, + 1279, 1086, 781, 502, 324, 164, 157, + 682, 466, 449, 277, 146, 28, 409, + 635, 472, 390, 107, -232, -538, -139, + 196, 396, 332, 213, 209, -29, -81, + 150, -95, -312, 76, -77, -320, -50, + 46, 9, 47, 175, 139, 30, 384, + 218, 206, -24, -250, -96, -276, -183, + 26, 119, 38, 14, -4, -133, -52, + -477, -614, -987, -715, -631, -813, 200, + -744, -1009, -1065, -745, -631, -171, 18, + -137, -251, -483, -613, -980, -1203, 12, + -605, -767, -562, -686, -1088, -515, 58, + -202, -428, -782, -1072, -96, -234, -179, + -480, -709, -1070, -897, -131, -92, 321, + -145, -193, -512, -729, -572, -765, -210, + -331, -585, -525, -631, -281, -208, -303, + 1165, 1104, 939, 828, 716, 426, 155, + 6, -109, 820, 778, 415, 113, -27, + 381, 339, 314, 265, 121, -9, -474, + -373, 47, 584, 442, 99, -231, -113, + -496, -38, -285, 262, 305, 170, 4, + -587, -556, 69, 66, 471, 354, 13, + -138, 70, -18, 106, 67, 167, -302, + -445, -141, 185, 191, 151, 83, -133, + -257, -521, -720, -198, 134, -46, -182, + -819, -1168, -777, 512, 359, 95, -113, + 137, -2, -74, -138, -401, -114, -371, + -242, -466, 204, 223, -31, -212, -192, + -532, -637, -466, -686, 256, 277, -139, + -1141, -1244, -381, -75, -54, 14, 88, + -311, 115, -143, -499, -343, 124, -416, + -616, -147, -135, 43, -4, 121, -369, + 835, 783, 641, 390, 355, 350, 64, + 72, 194, 443, 467, 436, 219, 372, + 464, 369, 192, 4, -156, -72, -226, + 57, 206, 303, 205, 188, 101, 265, + -40, -205, -488, -184, 276, 64, -26, + -217, -433, -297, 137, 328, 308, -289, + 378, 81, -308, -465, 57, -37, 227, + -100, 24, -36, -151, 199, 8, 143, + -426, -697, -1059, -133, 388, 161, 321, + -644, -1023, -1271, 39, 66, -123, 70, + 372, 177, -173, -556, -553, -304, -189, + -117, -369, -425, -122, -462, -152, -73, + -649, -850, -1189, -767, 497, 360, 222, + -798, -1139, -1455, -190, 430, 234, 179, + 42, -94, -405, -692, 38, -202, -246, + -169, -366, -290, -88, -64, 32, -292, + 1010, 923, 938, 710, 465, 230, 342, + 217, 300, 1054, 675, 68, -458, -179, + 78, 453, 316, 18, -237, -496, -243, + 167, 21, 424, 215, -91, -303, -170, + -290, -81, -70, -67, 40, 54, -59, + -353, -427, -90, 53, 94, 9, 54, + -28, 318, 283, 15, -240, -58, 79, + -75, -121, 229, 35, 58, 6, -133, + -351, -514, -744, -834, -705, -137, 164, + -1124, -1388, -1055, -230, -73, 40, 36, + -163, -233, -532, -785, -1170, -697, 96, + -788, -959, -246, -430, -624, -165, -8, + -856, -540, -630, -907, -337, -70, 76, + -937, -1042, -659, -733, -208, 199, -26, + -523, 78, -98, -501, -869, -890, -81, + -624, -703, -45, -348, -25, 87, -186, + 1005, 823, 546, 249, 90, -22, 207, + 298, 397, 381, 319, 200, 62, 303, + 473, 379, 133, -247, -632, -441, 75, + 284, 208, 391, 115, -25, 44, 95, + -72, 79, -95, -63, -129, -293, 203, + -164, -349, 115, 122, 69, -1, 378, + 348, 170, 99, 58, -179, -302, 188, + -190, -2, 150, 23, -51, -11, 216, + -615, -863, -1090, -1427, -802, -48, -6, + -961, -1276, -1548, -727, -58, 56, 223, + -124, -255, -561, -988, -1277, -148, -82, + -480, -660, -891, -1191, -1339, -325, 20, + -621, -917, -1296, -1350, 264, 289, 50, + -844, -1022, -1345, -1329, -293, 46, 278, + -260, -468, -829, -1176, -533, -560, -78, + -215, -484, -822, -1233, -791, 15, -138, + 1301, 1317, 1262, 1048, 716, 357, -64, + 578, 824, 925, 802, 630, 362, 102, + 470, 925, 767, 514, 327, 190, -112, + 225, 492, 495, 437, 598, 384, -45, + 43, 82, -42, 175, 519, 342, -64, + -304, -154, 159, 576, 403, 221, 327, + 214, 244, 122, -62, 312, 92, -160, + 218, 208, 310, 268, 306, 323, -199, + -285, -269, -79, -124, -143, -153, 236, + -205, -384, -426, 344, 59, -185, -184, + -272, 247, 126, -210, -518, -468, 78, + -99, -120, 502, 160, -280, -557, 304, + -423, -17, -283, -443, 215, 212, -140, + -564, -684, -228, 510, 361, 130, 323, + -428, 335, 98, -65, 36, -215, -246, + -362, 51, 364, -16, -234, 150, -165, + 914, 883, 751, 653, 676, 464, -153, + 631, 545, 535, 720, 596, 360, -81, + 783, 712, 512, 439, 341, 251, -391, + 497, 417, 249, 372, 295, 173, -193, + 128, -110, -385, 93, 39, 173, -231, + 216, -59, -253, 462, 389, 154, 69, + 455, 270, -4, -337, -49, 233, -322, + 307, 143, 53, 218, 128, 236, -156, + -37, -186, -240, -411, -110, 9, 399, + -140, -365, -628, 258, 380, 214, 277, + 131, 454, 177, -285, -520, 108, -214, + 77, -141, 201, -123, -490, -131, 60, + -14, -194, -521, -741, 273, 362, -33, + -362, -566, -287, -228, 161, 237, 317, + -269, 195, -75, -375, -204, 11, 77, + -128, -264, -156, -223, -475, 265, 27, + 1238, 1147, 916, 689, 432, 210, -280, + 800, 664, 879, 726, 411, 160, -164, + 454, 686, 536, 275, 147, 46, 111, + 303, 486, 512, 355, 241, 181, -69, + 79, 92, 29, 147, 233, 52, 17, + -171, 289, 131, 439, 271, 3, -10, + 413, 241, 144, 174, 155, -2, 14, + 58, 217, 247, 219, 149, 175, -18, + 228, -8, -240, -206, -513, -191, 202, + -96, -272, -454, 33, -300, -575, 46, + -10, -108, -246, -347, -770, -535, 9, + -326, -430, -61, -321, -704, -299, 201, + -1, -280, -603, -419, -185, 18, -36, + -516, -522, -379, -291, -181, -97, 27, + -159, -313, -525, -224, -510, -831, -197, + -292, -459, -59, -310, -562, -143, -351, + 1066, 912, 631, 389, 207, 86, -224, + 596, 512, 596, 505, 314, 122, -48, + 787, 861, 441, -93, -303, 33, -190, + 257, 469, 337, 51, 15, 298, -93, + 295, 73, -119, 25, 36, 23, 108, + -28, -3, -32, 114, 21, 185, 107, + 482, 305, 15, -279, -319, 52, 96, + 226, 46, 115, 72, -136, 133, -125, + 18, -207, -559, -590, -503, -482, 321, + -571, -789, -951, -172, -441, -538, 113, + 181, 14, -310, -641, -1001, -202, 159, + -136, -393, -433, -513, -911, -144, -22, + 72, -265, -706, -954, -159, 53, 332, + -338, -591, -852, -383, -395, 56, 44, + 43, -158, -464, -897, -631, -157, -294, + -161, -128, -328, -573, -483, -125, 11, + 1017, 906, 1051, 1005, 679, 341, -102, + 359, 334, 1567, 1314, 723, 105, 10, + -65, 726, 529, 301, 220, 43, -273, + -510, 436, 719, 566, 358, 179, 114, + -560, 298, 133, -120, 342, 225, 14, + -899, -101, 217, 617, 400, 146, -58, + -41, 352, 82, -196, 39, 121, -167, + -212, 59, 447, 284, 423, 250, -169, + -371, -484, -596, 30, -41, 249, 22, + -372, -650, -794, 477, 445, 216, -79, + -352, 275, 17, -443, -929, 92, 19, + -699, -696, 431, 264, -49, -310, 182, + -978, -217, -430, -400, 101, 261, 72, + -929, -889, -357, -13, 463, 378, 236, + -826, 56, 30, -299, -360, -128, -51, + -878, -299, -111, 75, 65, 36, 3, + 817, 368, -25, 354, 697, 591, -173, + 309, 212, 222, 751, 484, 140, -56, + 593, 379, 70, -8, 258, 180, 110, + 165, -46, 255, 297, 219, 273, 105, + 160, -70, -358, -181, 379, 330, 319, + -238, -369, -198, 740, 580, 319, -143, + 201, 109, -202, -456, 328, 276, -141, + 203, 170, 111, 42, 207, 360, 188, + -345, -399, -513, -233, 650, 422, 81, + -635, -961, -1220, 463, 539, 204, 209, + 202, -25, -194, -498, -787, 193, -143, + -449, -538, 195, -106, -331, 68, 62, + -228, -477, -840, -576, 317, 128, 283, + -671, -937, -807, -114, 391, 335, -62, + 246, 2, -314, -679, -303, 180, -88, + -107, -272, 90, -198, -28, 290, -112, + 885, 1149, 1021, 712, 496, 281, -83, + 269, 492, 787, 643, 347, 70, 124, + 336, 636, 499, 92, -229, -179, 191, + 26, 402, 564, 340, 149, -11, 135, + -440, 561, 470, 204, -72, -186, 140, + -720, 14, 355, 229, 68, -133, 465, + 110, 310, 103, 12, 106, 29, 158, + -178, 113, 161, 142, 121, 115, 27, + -651, -414, -645, -152, -164, -13, -429, + -639, -944, -681, -104, -81, 52, -189, + -663, -164, -316, -683, -954, -205, -83, + -609, -669, -172, -517, -694, 283, -80, + -646, -152, -383, -678, -246, -40, -143, + -747, -796, -745, -390, -98, 43, 275, + -599, -199, -398, -433, -436, -538, 31, + -1107, -568, -376, -265, -126, -21, 1, + 847, 573, 308, 392, 305, 101, 55, + 273, 293, 201, 267, 346, 201, 123, + 727, 480, 226, 2, -65, -138, 164, + 273, 208, 173, 292, 12, 253, 174, + 340, 207, 180, 88, 116, 46, 475, + -460, -166, -30, 13, 110, 173, 396, + 137, 88, 43, -137, -94, 34, 284, + 96, -14, 226, 40, 63, 70, 130, + -467, -735, -1012, -1174, -307, 305, -67, + -612, -920, -1146, -567, -8, 92, -25, + -182, -271, -492, -754, -857, 287, -75, + -494, -787, -689, -683, -709, 137, -326, + -288, -550, -903, -1105, 334, 321, -62, + -354, -653, -834, -445, 1, 377, -152, + -162, -306, -608, -937, -297, 247, -192, + -234, -477, -244, -488, -266, 342, -332 +}; + +/* + * 2nd stage codebook; 1st split: isf2_0 to isf2_2 + */ + + +const int16 dico21_isf[SIZE_BK21*3] = +{ + + 329, 409, 249, + -33, 505, 160, + -29, -14, 582, + -262, 127, 354, + 145, 237, 175, + -152, 245, 122, + 27, 42, 340, + -84, -93, 311, + 285, 222, -156, + 47, -43, -504, + 234, 121, 385, + 104, -317, 45, + 176, 195, 8, + 104, -59, -94, + 177, 53, 192, + -34, -127, 152, + 570, 277, -34, + -67, -329, -639, + -157, -272, 462, + -177, -462, 198, + 322, 179, 115, + -386, 171, 19, + 19, -12, 195, + -120, -252, 201, + 304, 36, -336, + -128, -221, -380, + 171, -185, 296, + -242, -312, 23, + 198, 39, 16, + -3, -177, -111, + 111, -93, 76, + -92, -223, 4, + 177, 406, -44, + -168, 380, -149, + -4, 273, 331, + -420, 513, 277, + 21, 247, 47, + -58, 131, -2, + -3, 134, 180, + -145, 40, 175, + 189, 74, -145, + -27, -45, -325, + 370, -114, -21, + -83, -415, -173, + 77, 95, -51, + -40, -30, -67, + 71, 88, 86, + -35, -98, 14, + 69, 197, -334, + -196, 79, -231, + -348, -137, 218, + -352, -89, -85, + 47, 201, -130, + -165, 37, -15, + -43, 3, 86, + -161, -108, 79, + 83, 21, -237, + -81, -149, -238, + 150, -186, -251, + -186, -249, -162, + -19, 66, -139, + -26, -50, -181, + 24, 11, 0, + -130, -105, -98 +}; + + + +/* + * 2nd stage codebook; 2nd split: isf2_3 to isf2_5 + */ + + +const int16 dico22_isf[SIZE_BK22*3] = +{ + + -127, 310, 42, + -242, 197, 5, + -151, 84, -17, + -214, 127, -149, + -247, -131, 159, + -268, -267, -95, + -217, 1, -79, + -271, -80, -185, + -45, 436, 159, + 165, 199, 391, + -33, 81, 187, + -66, -42, 355, + -298, -57, 343, + -108, -537, 226, + -144, -23, 193, + 176, -402, 87, + 53, 296, 25, + -84, 253, -104, + -58, 105, -126, + -169, 174, -314, + -48, 44, -294, + -164, -417, -242, + -139, 3, -194, + -155, -207, -211, + 119, 322, 213, + 333, 50, 380, + 237, 247, -2, + 466, -16, 201, + 238, -255, -107, + 67, -440, -149, + 122, -88, -139, + 88, -247, -73, + -41, 231, 167, + -62, 155, 16, + -65, 16, 77, + -68, -2, -63, + -151, -300, 160, + -18, -333, 54, + -56, -94, 5, + 2, -190, 14, + 92, 148, 209, + 108, 9, 272, + 108, 35, 110, + 142, -85, 145, + 47, -157, 279, + 3, -320, 246, + 43, -72, 68, + 86, -217, 135, + 36, 140, 79, + 56, 175, -49, + 26, 45, 3, + 73, 55, -101, + 109, -183, -242, + -4, -283, -242, + 48, -68, -48, + -6, -153, -122, + 161, 196, 96, + 232, 80, 190, + 165, 97, 11, + 258, -31, 71, + 267, -77, -91, + 311, -209, 87, + 152, -14, -22, + 150, -149, 9, + -324, 557, 187, + -384, 307, 46, + -251, 27, 77, + -365, 77, -52, + -482, -84, 160, + -424, -515, -64, + -294, -120, -4, + -476, -116, -109, + -97, 318, 365, + 106, 627, 445, + -190, 120, 287, + -146, 65, 619, + -427, 242, 363, + -361, -371, 432, + -347, 102, 168, + -629, 195, -14, + -65, 476, -47, + -297, 320, -168, + -55, 356, -264, + -391, 82, -286, + -51, -31, -556, + -178, -399, -586, + -205, -49, -360, + -343, -238, -337, + 220, 457, 58, + 561, 467, 259, + 340, 270, -168, + 450, 77, -280, + 60, 167, -413, + 133, -252, -492, + 216, 157, -290, + 282, 0, -495, + -226, 293, 183, + -157, 135, 122, + -158, -59, 39, + -133, -118, -97, + -332, -309, 113, + -160, -425, -6, + -149, -211, 24, + -80, -277, -90, + -11, 125, 338, + 130, -71, 465, + 5, -45, 184, + 237, -95, 253, + -139, -197, 297, + -19, -300, 511, + -63, -152, 139, + 250, -289, 336, + 124, 339, -150, + 34, 176, -208, + 171, 166, -116, + 94, 38, -229, + 75, -65, -339, + -78, -205, -385, + 0, -30, -163, + -56, -110, -242, + 321, 244, 194, + 505, 238, -1, + 317, 116, 65, + 309, 88, -74, + 452, -51, -50, + 334, -217, -290, + 211, 41, -152, + 238, -55, -260 +}; + + +/* + * 2nd stage codebook; 3rd split: isf2_6 to isf2_8 + */ + + +const int16 dico23_isf[SIZE_BK23*3] = +{ + + -10, 151, 359, + 136, 298, 223, + 255, -104, 290, + 423, 6, 183, + -270, -269, -98, + -52, -82, 13, + -82, -274, -97, + 90, -246, -72, + -299, -70, 421, + -88, 365, 430, + 187, -318, 381, + 380, 37, 488, + -373, -316, 79, + -308, -101, 5, + -135, -451, 8, + 72, -421, -154, + 180, 170, -121, + 62, 177, -40, + 326, 80, -105, + 248, 263, -5, + -168, -181, -221, + -2, -23, -158, + -14, -149, -121, + 119, -91, -147, + 119, 332, -153, + 49, 303, 34, + 442, -55, -69, + 217, 454, 58, + -359, -187, -375, + -42, 50, -274, + -8, -267, -249, + 85, -86, -346, + -77, -40, 345, + 89, 134, 219, + 156, -80, 160, + 108, 40, 116, + -158, -206, 29, + 5, -32, 175, + -65, -158, 146, + 55, -78, 73, + -114, -222, 353, + -47, 81, 211, + 49, -151, 268, + 105, 4, 302, + -263, -132, 183, + -151, -28, 201, + -177, -307, 166, + 101, -221, 130, + 74, 58, -98, + 32, 44, 13, + 194, 30, -142, + 170, 96, 8, + -136, -119, -91, + -65, 8, -55, + 3, -188, 12, + 45, -63, -49, + 149, -21, -19, + 24, 144, 95, + 254, -22, 60, + 161, 196, 96, + -158, -61, 48, + -70, 33, 82, + -23, -321, 58, + 155, -147, 5, + -364, 328, 77, + -21, 453, 173, + -108, 82, 630, + 367, 263, 208, + -300, -62, -176, + -205, 143, -158, + -169, -410, -264, + 257, -269, -100, + -636, 289, -2, + -292, 627, 173, + -382, -363, 387, + 248, 524, 447, + -521, -111, -107, + -395, 118, -274, + -343, -680, -125, + -172, -447, -663, + 75, 148, -367, + -79, 263, -94, + 249, 148, -286, + 380, 271, -162, + -142, -4, -186, + -57, 111, -125, + -35, -108, -254, + 100, 29, -242, + -80, 303, -264, + -78, 464, -57, + 248, -22, -494, + 661, 662, 44, + -193, -40, -330, + -178, 145, -337, + -90, -199, -400, + -40, -23, -498, + -192, 114, 315, + -41, 244, 190, + 88, -97, 485, + 241, 80, 212, + -246, 40, 87, + -156, 147, 134, + -2, -334, 239, + 308, -203, 110, + -459, 251, 422, + -218, 310, 228, + -86, -346, 654, + 184, 175, 425, + -481, -63, 169, + -349, 117, 188, + -125, -560, 310, + 158, -416, 94, + 46, 171, -192, + -63, 157, 14, + 256, -35, -271, + 322, 123, 53, + -214, 4, -76, + -156, 86, -18, + 128, -197, -232, + 265, -90, -98, + -308, 332, -145, + -131, 308, 58, + 509, 59, -339, + 562, 196, -14, + -378, 100, -47, + -234, 202, 1, + 104, -270, -493, + 319, -210, -325 +}; + + +/* + * 2nd stage codebook; 4th split: isf2_9 to isf2_11 + */ + +const int16 dico24_isf[SIZE_BK24*3] = +{ + + -79, -89, -4, + -171, 77, -211, + 160, -193, 98, + 120, -103, 323, + 32, -22, -129, + 72, 78, -268, + 182, -76, -66, + 309, 99, -145, + -229, -157, -84, + -383, 98, -71, + -90, -352, 12, + -284, -178, 178, + -65, -125, -166, + -87, -175, -351, + 42, -198, -48, + 154, -140, -243, + -77, 18, 108, + -39, 355, 91, + 87, 8, 155, + -4, 158, 239, + 128, 95, -54, + 7, 246, -124, + 258, 15, 89, + 206, 216, 98, + -201, 9, 18, + -312, 233, 204, + -39, -174, 155, + -144, -9, 284, + -57, 70, -69, + -157, 187, 18, + 54, -30, 23, + 24, 135, 55 +}; + + +/* + * 2nd stage codebook; 5th split: isf2_12 to isf2_15 + */ + +const int16 dico25_isf[SIZE_BK25*4] = +{ + + 169, 142, -119, 115, + 206, -20, 94, 226, + -106, 313, -21, 16, + -62, 161, 71, 255, + -89, 101, -185, 125, + 72, -30, -201, 344, + -258, 33, -8, 81, + -104, -154, 72, 296, + 144, -68, -268, -25, + 81, -78, -87, 106, + 22, 155, -186, -119, + -46, -28, 27, 91, + -114, -37, -175, -33, + -94, -222, -189, 122, + -132, -119, -191, -270, + -172, -173, 18, -43, + 279, 135, -42, -128, + 187, -86, 229, -138, + 159, 240, 140, 46, + 69, 25, 227, 77, + 21, 115, 13, 8, + 68, -248, 126, 81, + -150, 137, 207, -9, + -154, -133, 289, 67, + 143, -37, -86, -326, + 180, -32, 19, -23, + 26, 168, 116, -233, + -32, -26, 118, -78, + 3, -8, -45, -115, + 57, -215, -54, -83, + -209, 112, -22, -167, + -91, -151, 168, -262 +}; + + + +/* 36 bit */ +/* + * isf codebooks: two-stage VQ with split-by-3 in 2nd stage + * 1st stage is kept the same as the 46 bit quantizer + * + * codebook vector dimension number of vectors + * ~~~~~~~~ ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ + * 1_1 9 256 + * 1_2 7 256 + * 2_1 5 128 + * 2_2 4 128 + * 2_3 7 64 + */ + +const int16 dico21_isf_36b[SIZE_BK21_36b*5] = +{ + + -52, -96, 212, 315, -73, + 82, -204, 363, 136, -197, + -126, -331, 183, 218, 143, + -49, -41, 557, 230, 72, + 2, -73, 163, 377, 221, + 133, 111, 278, 215, -110, + -102, -20, 284, 113, 273, + 84, 319, 290, 18, 85, + -25, -5, 125, 132, -204, + -38, -5, 286, -9, -356, + -140, -256, 92, 117, -189, + -144, 191, 313, 51, -98, + 167, -10, 44, 247, 36, + 381, 197, 238, 74, 6, + 38, -408, 29, -3, -85, + 92, 266, 157, -25, -200, + 161, -121, 70, 84, -140, + -16, -86, 112, -94, -189, + -269, -270, 351, 107, -24, + -68, -67, 492, -103, -155, + -53, -131, 62, 122, 10, + 135, 84, 283, -55, -120, + -12, -219, 331, -81, 167, + 220, -136, 147, -172, -42, + 140, -95, -109, -88, -194, + 0, -2, -4, -33, -381, + -66, -217, 152, -186, -402, + 244, 108, 156, -140, -395, + 113, -136, -196, 110, -24, + 214, 118, 11, -64, -131, + -110, -286, -6, -332, 16, + 94, 97, 79, -291, -205, + -5, -39, -20, 252, -96, + 76, 174, 101, 163, 61, + -69, -239, -55, 399, 6, + -115, 319, 164, 275, 196, + -15, 36, -47, 331, 121, + 226, 209, 271, 325, 184, + 13, -80, -218, 471, 353, + 288, 378, 16, -51, 251, + 174, 116, 52, 149, -279, + 235, 276, 39, 120, -48, + 0, -108, -108, 241, -339, + -93, 534, 45, 33, -87, + 194, 149, -71, 405, -44, + 409, 370, 81, -186, -154, + 25, -102, -448, 124, -173, + 22, 408, -110, -310, -214, + -26, 23, -83, 114, 14, + -110, 164, 52, 223, -82, + 37, -25, -263, 306, -15, + -466, 415, 292, 165, -18, + 29, -19, -171, 155, 182, + 179, 144, -27, 231, 258, + -103, -247, -396, 238, 113, + 375, -154, -109, -4, 156, + 98, 85, -292, -5, -124, + 116, 139, -116, -98, -294, + -14, -83, -278, -117, -378, + 106, 33, -106, -344, -484, + 119, 17, -412, 138, 166, + 384, 101, -204, 88, -156, + -121, -284, -300, -1, -166, + 280, 33, -152, -313, -81, + -37, 22, 229, 153, 37, + -60, -83, 236, -8, -41, + -169, -228, 126, -20, 363, + -235, 17, 364, -156, 156, + -25, -30, 72, 144, 156, + 153, -26, 256, 97, 144, + -21, -37, 48, -65, 250, + 63, 77, 273, -128, 124, + -129, -26, 40, 9, -115, + -6, 82, 38, -90, -182, + -336, -13, 28, 158, 91, + -30, 241, 137, -170, -17, + 146, 14, -11, 33, 61, + 192, 197, 54, -84, 85, + 23, -200, -78, -29, 140, + 122, 237, 106, -341, 136, + -57, -142, -85, -16, -74, + -59, -90, -8, -187, -20, + -211, -267, 216, -179, -110, + -50, -7, 220, -267, -70, + -57, -42, -17, -15, 71, + 32, 21, 63, -137, 33, + -137, -175, 104, -68, 97, + -67, -43, 133, -301, 221, + -116, -200, -81, -92, -272, + -64, -41, -54, -244, -220, + -287, -242, -50, -87, -89, + -245, 236, 102, -166, -295, + 66, 24, -162, -71, 95, + 66, 136, -90, -220, -36, + -98, -161, -222, -188, 29, + -18, 18, -19, -415, 9, + 49, 61, 100, 39, -56, + -111, 82, 135, -31, 52, + -90, -153, -93, 189, 182, + -214, 295, 119, -74, 284, + 2, 137, 37, 47, 182, + 92, 117, 184, -53, 373, + -21, -14, -35, 136, 391, + 146, 129, -164, -28, 333, + 92, 80, -84, 100, -134, + -8, 217, -32, 3, -47, + -151, 251, -215, 142, 92, + -224, 310, -172, -275, 98, + 159, 155, -177, 112, 53, + 205, 27, 8, -240, 192, + 169, 120, -319, -201, 106, + 11, 36, -86, -237, 455, + -109, -154, -163, 174, -55, + -38, 32, -101, -78, -59, + -205, -321, -97, 69, 79, + -310, 44, 18, -185, 34, + -115, -20, -148, -39, 203, + -29, 154, -30, -158, 166, + -45, -131, -317, -24, 363, + -165, -205, -112, -222, 265, + -32, -44, -150, 54, -193, + -6, -38, -255, -169, -115, + -266, 87, -189, -36, -169, + -60, -87, -266, -436, -170, + -68, -81, -278, 24, 38, + -23, -19, -155, -256, 141, + -61, -226, -565, -175, 71, + 9, -29, -237, -515, 263 +}; + +const int16 dico22_isf_36b[SIZE_BK22_36b*4] = +{ + + -298, -6, 95, 31, + -213, -87, -122, 261, + 4, -49, 208, 14, + -129, -110, 30, 118, + -214, 258, 110, -235, + -41, -18, -126, 120, + 103, 65, 127, -37, + 126, -36, -24, 25, + -138, -67, -278, -186, + -164, -194, -201, 78, + -211, -87, -51, -221, + -174, -79, -94, -39, + 23, -6, -157, -240, + 22, -110, -153, -68, + 148, -5, -2, -149, + -1, -135, -39, -179, + 68, 360, -117, -15, + 137, 47, -278, 146, + 136, 260, 135, 65, + 61, 116, -45, 97, + 231, 379, 87, -120, + 338, 177, -272, 3, + 266, 156, 28, -69, + 260, 84, -85, 86, + -266, 154, -256, -182, + -17, -65, -304, -6, + -40, 175, -151, -180, + -27, 27, -87, -63, + 121, 114, -166, -469, + 159, -66, -323, -231, + 214, 152, -141, -212, + 137, 36, -184, -51, + -282, -237, 40, 10, + -48, -235, -37, 251, + -54, -323, 136, 29, + -88, -174, 213, 198, + -390, 99, -63, -375, + 107, -169, -164, 424, + 69, -111, 141, -167, + 74, -129, 65, 144, + -353, -207, -205, -109, + -160, -386, -355, 98, + -176, -493, -20, -143, + -252, -432, -2, 216, + -90, -174, -168, -411, + 13, -284, -229, -160, + -87, -279, 34, -251, + -75, -263, -58, -42, + 420, 53, -211, -358, + 384, -35, -374, 396, + 68, -228, 323, -2, + 167, -307, 192, 194, + 459, 329, -5, -332, + 375, 79, -7, 313, + 282, -124, 200, -92, + 271, -162, -70, 180, + -157, -298, -514, -309, + 58, -163, -546, 18, + 124, -364, 167, -238, + 83, -411, -117, 96, + 140, -112, -388, -624, + 259, -133, -317, 41, + 163, -130, -64, -334, + 226, -165, -124, -110, + -466, -61, 6, 229, + -153, 205, -145, 242, + -159, 48, 195, 148, + -58, 28, 31, 279, + -303, 185, 279, -4, + -61, 197, 59, 86, + -114, 123, 168, -52, + 35, 36, 100, 126, + -407, 102, -77, -40, + -338, -1, -342, 156, + -179, 105, -34, -97, + -185, 84, -35, 108, + -133, 107, -91, -357, + -180, 54, -229, 24, + -44, 47, 47, -182, + -66, 13, 45, 4, + -339, 251, 64, 226, + -42, 101, -350, 275, + -99, 398, 142, 121, + 111, 12, -102, 260, + 0, 505, 260, -94, + 161, 285, -96, 224, + -4, 206, 314, 33, + 167, 139, 88, 204, + -235, 316, -60, -25, + -8, -150, -312, 201, + -36, 292, 61, -104, + -40, 174, -162, 42, + -21, 402, -29, -351, + 21, 152, -360, -93, + 57, 191, 212, -196, + 76, 158, -21, -69, + -328, -185, 331, 119, + -53, 285, 56, 337, + -107, -24, 405, 29, + -18, 137, 272, 277, + -255, 22, 173, -191, + 295, 322, 325, 302, + 21, -27, 332, -178, + 119, 13, 271, 129, + -455, -180, 116, -191, + -227, 62, -148, 524, + -176, -287, 282, -157, + -243, 13, 199, 430, + -59, -49, 115, -365, + 72, -172, -137, 93, + -138, -126, 141, -84, + 5, -124, 38, -20, + -258, 311, 601, 213, + 94, 130, -61, 502, + -1, -157, 485, 313, + 146, -74, 158, 345, + 276, 135, 280, -57, + 490, 252, 99, 43, + 267, -74, 429, 105, + 278, -23, 119, 94, + -542, 488, 257, -115, + -84, -244, -438, 478, + -113, -545, 387, 101, + -95, -306, 111, 498, + 95, 166, 22, -301, + 420, -15, -58, -78, + 270, 29, 122, -282, + 160, -240, 50, -38 +}; + +const int16 dico23_isf_36b[SIZE_BK23_36b*7] = +{ + + 81, -18, 68, -27, -122, -280, -4, + 45, -177, 209, -30, -136, -74, 131, + -44, 101, -75, -88, -48, -137, -54, + -245, -28, 63, -18, -112, -103, 58, + -79, -6, 220, -65, 114, -35, -50, + 109, -65, 143, -114, 129, 76, 125, + 166, 90, -61, -242, 186, -74, -43, + -46, -92, 49, -227, 24, -155, 39, + 67, 85, 99, -42, 53, -184, -281, + 142, -122, 0, 21, -142, -15, -17, + 223, 92, -21, -48, -82, -14, -167, + 51, -37, -243, -30, -90, 18, -56, + 54, 105, 74, 86, 69, 13, -101, + 196, 72, -89, 43, 65, 19, 39, + 121, 34, 131, -82, 25, 213, -156, + 101, -102, -136, -21, 57, 214, 22, + 36, -124, 205, 204, 58, -156, -83, + 83, -117, 137, 137, 85, 116, 44, + -92, -148, -68, 11, -102, -197, -220, + -76, -185, -58, 132, -26, -183, 85, + -7, -31, -2, 23, 205, -151, 10, + -27, -37, -5, -18, 292, 131, 1, + 117, -168, 9, -93, 80, -59, -125, + -182, -244, 98, -24, 135, -22, 94, + 221, 97, 106, 42, 43, -160, 83, + 25, -64, -21, 6, 14, -15, 154, + 126, 15, -140, 150, -10, -207, -114, + 79, -63, -211, -70, -28, -217, 165, + 46, 38, -22, 281, 132, -62, 109, + 112, 54, -112, -93, 208, 27, 296, + 115, 10, -147, 41, 216, 42, -276, + 50, -115, -254, 167, 117, -2, 61, + 17, 144, 34, -72, -186, -150, 272, + -29, -66, -89, -95, -149, 129, 251, + 122, 0, -50, -234, -91, 36, 26, + -105, -102, -88, -121, -236, -7, -11, + -204, 109, 5, -191, 105, -15, 163, + -80, 32, -24, -209, 41, 294, 70, + -106, -94, -204, -118, 120, -50, -37, + -82, -241, 46, -131, -29, 150, -55, + 33, 155, 120, -89, -8, 7, 62, + 213, 82, 61, 18, -161, 144, 152, + 30, 131, 65, -87, -255, -17, -107, + -8, 85, -64, 51, -162, 223, -53, + -134, 261, 69, -56, 218, 72, -111, + 2, 155, -113, -87, 49, 85, -28, + -163, 42, -1, -196, 7, 39, -245, + 14, -137, -79, 11, -160, 202, -293, + -94, 33, 208, 100, 56, -44, 326, + -78, -41, 232, 13, -142, 227, 80, + -16, -87, 201, 33, -133, 15, -183, + -58, -192, -47, 184, -128, 133, 99, + -205, 11, -155, 78, 52, 72, 141, + -246, 26, 99, 151, 59, 115, -64, + -79, -47, -16, -14, 6, 47, -43, + -72, -178, -27, 162, 112, 43, -174, + -175, 238, 186, 71, -54, -188, -76, + -225, 233, 39, -39, -158, 122, 44, + -26, 43, 84, 130, -93, -51, 22, + 3, 92, -150, 136, -182, -57, 97, + -131, 179, -78, 80, 91, -165, 90, + -2, 148, 15, 130, 65, 175, 117, + -138, 114, -137, 132, 3, -10, -186, + 140, -4, -37, 254, -62, 92, -109 +}; + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/scale_signal.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/scale_signal.cpp new file mode 100644 index 00000000..d225d28a --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/scale_signal.cpp @@ -0,0 +1,146 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: scale_signal.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 signal[], (i/o) : signal to scale + int16 lg, (i) : size of x[] + int16 exp (i) : exponent: x = round(x << exp) + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Scale signal to get maximum of dynamic range + + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void scale_signal( + int16 x[], /* (i/o) : signal to scale */ + int16 lg, /* (i) : size of x[] */ + int16 exp /* (i) : exponent: x = round(x << exp) */ +) +{ + int16 i; + int16 tmp; + int16 *pt_x; + + + int32 L_tmp; + + + if (exp > 0) + { + for (i = 0; i < lg; i++) + { + L_tmp = shl_int32(((int32)x[i] << 16), exp); /* saturation can occur here */ + x[i] = amr_wb_round(L_tmp); + } + } + else if (exp < 0) + { + exp = -exp; + exp &= 0xf; + tmp = (int16)(0x00008000 >> (16 - exp)); + pt_x = x; + + for (i = lg >> 1; i != 0; i--) + { + *(pt_x) = add_int16(*(pt_x), tmp) >> exp; + pt_x++; + *(pt_x) = add_int16(*(pt_x), tmp) >> exp; + pt_x++; + } + + } + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/synthesis_amr_wb.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/synthesis_amr_wb.cpp new file mode 100644 index 00000000..987729f7 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/synthesis_amr_wb.cpp @@ -0,0 +1,432 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: synthesis_amr_wb.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 Aq[], A(z) : quantized Az + int16 exc[], (i) : excitation at 12kHz + int16 Q_new, (i) : scaling performed on exc + int16 synth16k[], (o) : 16kHz synthesis signal + int16 prms, (i) : compressed amr wb + int16 HfIsf[], + int16 nb_bits, + int16 newDTXState, + Decoder_State * st, (i/o) : State structure + int16 bfi, (i) : bad frame indicator + int16 *ScratchMem + + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Synthesis of signal at 16kHz with HF extension + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_mem_funcs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" +#include "e_pv_amrwbdec.h" +#include "get_amr_wb_bits.h" +#include "pvamrwb_math_op.h" +#include "pvamrwbdecoder_api.h" +#include "synthesis_amr_wb.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ +/* High Band encoding */ +const int16 HP_gain[16] = +{ + 3624, 4673, 5597, 6479, 7425, 8378, 9324, 10264, + 11210, 12206, 13391, 14844, 16770, 19655, 24289, 32728 +}; + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void synthesis_amr_wb( + int16 Aq[], /* A(z) : quantized Az */ + int16 exc[], /* (i) : excitation at 12kHz */ + int16 Q_new, /* (i) : scaling performed on exc */ + int16 synth16k[], /* (o) : 16kHz synthesis signal */ + int16 prms, /* (i) : parameter */ + int16 HfIsf[], + int16 nb_bits, + int16 newDTXState, + Decoder_State * st, /* (i/o) : State structure */ + int16 bfi, /* (i) : bad frame indicator */ + int16 *ScratchMem +) +{ + int16 i, fac, exp; + int16 tmp; + int16 ener, exp_ener; + int32 L_tmp; + int32 L_tmp2; + + int16 HF_corr_gain; + int16 HF_gain_ind; + int16 gain1, gain2; + + int16 *pt_synth; + int16 *pt_HF; + int16 *synth_hi = ScratchMem; + int16 *synth_lo = &ScratchMem[M + L_SUBFR]; + int16 *synth = &synth_lo[M + L_SUBFR]; + int16 *HF = &synth[L_SUBFR]; + int16 *Ap = &HF[L_SUBFR16k]; /* High Frequency vector */ + int16 *HfA = &Ap[M16k + 1]; + int16 *pt_tmp; + + /*------------------------------------------------------------* + * speech synthesis * + * ~~~~~~~~~~~~~~~~ * + * - Find synthesis speech corresponding to exc2[]. * + * - Perform fixed deemphasis and hp 50hz filtering. * + * - Oversampling from 12.8kHz to 16kHz. * + *------------------------------------------------------------*/ + + pv_memcpy((void *)synth_hi, + (void *)st->mem_syn_hi, + M*sizeof(*synth_hi)); + + pv_memcpy((void *)synth_lo, + (void *)st->mem_syn_lo, + M*sizeof(*synth_lo)); + + Syn_filt_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR); + + pv_memcpy((void *)st->mem_syn_hi, + (void *)(synth_hi + L_SUBFR), + M*sizeof(*st->mem_syn_hi)); + + pv_memcpy((void *)st->mem_syn_lo, + (void *)(synth_lo + L_SUBFR), + M*sizeof(*st->mem_syn_lo)); + + deemphasis_32(synth_hi + M, + synth_lo + M, + synth, + PREEMPH_FAC, + L_SUBFR, + &(st->mem_deemph)); + + highpass_50Hz_at_12k8(synth, + L_SUBFR, + st->mem_sig_out); + + oversamp_12k8_to_16k(synth, + L_SUBFR, + synth16k, + st->mem_oversamp, + ScratchMem); + + /* + * HF noise synthesis + * - Generate HF noise between 5.5 and 7.5 kHz. + * - Set energy of noise according to synthesis tilt. + * tilt > 0.8 ==> - 14 dB (voiced) + * tilt 0.5 ==> - 6 dB (voiced or noise) + * tilt < 0.0 ==> 0 dB (noise) + */ + + /* generate white noise vector */ + pt_tmp = HF; + for (i = L_SUBFR16k >> 2; i != 0 ; i--) + { + *(pt_tmp++) = noise_gen_amrwb(&(st->seed2)) >> 3; + *(pt_tmp++) = noise_gen_amrwb(&(st->seed2)) >> 3; + *(pt_tmp++) = noise_gen_amrwb(&(st->seed2)) >> 3; + *(pt_tmp++) = noise_gen_amrwb(&(st->seed2)) >> 3; + } + /* energy of excitation */ + + pt_tmp = exc; + + for (i = L_SUBFR >> 2; i != 0; i--) + { + *(pt_tmp) = add_int16(*(pt_tmp), 0x0004) >> 3; + pt_tmp++; + *(pt_tmp) = add_int16(*(pt_tmp), 0x0004) >> 3; + pt_tmp++; + *(pt_tmp) = add_int16(*(pt_tmp), 0x0004) >> 3; + pt_tmp++; + *(pt_tmp) = add_int16(*(pt_tmp), 0x0004) >> 3; + pt_tmp++; + } + + + Q_new -= 3; + + ener = extract_h(Dot_product12(exc, exc, L_SUBFR, &exp_ener)); + exp_ener -= Q_new << 1; + + /* set energy of white noise to energy of excitation */ + + tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp)); + + if (tmp > ener) + { + tmp >>= 1; /* Be sure tmp < ener */ + exp += 1; + } + L_tmp = L_deposit_h(div_16by16(tmp, ener)); /* result is normalized */ + exp -= exp_ener; + one_ov_sqrt_norm(&L_tmp, &exp); + L_tmp = shl_int32(L_tmp, exp + 1); /* L_tmp x 2, L_tmp in Q31 */ + + tmp = (int16)(L_tmp >> 16); /* tmp = 2 x sqrt(ener_exc/ener_hf) */ + + + + pt_tmp = HF; + for (i = L_SUBFR16k >> 2; i != 0 ; i--) + { + *(pt_tmp) = (int16)(fxp_mul_16by16(*(pt_tmp), tmp) >> 15); + pt_tmp++; + *(pt_tmp) = (int16)(fxp_mul_16by16(*(pt_tmp), tmp) >> 15); + pt_tmp++; + *(pt_tmp) = (int16)(fxp_mul_16by16(*(pt_tmp), tmp) >> 15); + pt_tmp++; + *(pt_tmp) = (int16)(fxp_mul_16by16(*(pt_tmp), tmp) >> 15); + pt_tmp++; + } + + /* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */ + + highpass_400Hz_at_12k8(synth, L_SUBFR, st->mem_hp400); + + L_tmp = 1L; + L_tmp2 = 1L; + + + L_tmp = mac_16by16_to_int32(L_tmp, synth[0], synth[0]); + + for (i = 1; i < L_SUBFR; i++) + { + L_tmp = mac_16by16_to_int32(L_tmp, synth[i], synth[i ]); + L_tmp2 = mac_16by16_to_int32(L_tmp2, synth[i], synth[i - 1]); + } + + + exp = normalize_amr_wb(L_tmp); + + ener = (int16)((L_tmp << exp) >> 16); /* ener = r[0] */ + tmp = (int16)((L_tmp2 << exp) >> 16); /* tmp = r[1] */ + + if (tmp > 0) + { + fac = div_16by16(tmp, ener); + } + else + { + fac = 0; + } + + /* modify energy of white noise according to synthesis tilt */ + gain1 = 32767 - fac; + gain2 = mult_int16(gain1, 20480); + gain2 = shl_int16(gain2, 1); + + if (st->vad_hist > 0) + { + tmp = gain2 - 1; + } + else + { + tmp = gain1 - 1; + } + + + if (tmp != 0) + { + tmp++; + } + + if (tmp < 3277) + { + tmp = 3277; /* 0.1 in Q15 */ + + } + + + if ((nb_bits >= NBBITS_24k) && (bfi == 0)) + { + /* HF correction gain */ + HF_gain_ind = prms; + HF_corr_gain = HP_gain[HF_gain_ind]; + + pt_tmp = HF; + for (i = L_SUBFR16k >> 2; i != 0 ; i--) + { + *(pt_tmp) = mult_int16(*(pt_tmp), HF_corr_gain) << 1; + pt_tmp++; + *(pt_tmp) = mult_int16(*(pt_tmp), HF_corr_gain) << 1; + pt_tmp++; + *(pt_tmp) = mult_int16(*(pt_tmp), HF_corr_gain) << 1; + pt_tmp++; + *(pt_tmp) = mult_int16(*(pt_tmp), HF_corr_gain) << 1; + pt_tmp++; + } + + /* HF gain */ + } + else + { + pt_tmp = HF; + for (i = L_SUBFR16k >> 2; i != 0 ; i--) + { + *(pt_tmp) = mult_int16(*(pt_tmp), tmp); + pt_tmp++; + *(pt_tmp) = mult_int16(*(pt_tmp), tmp); + pt_tmp++; + *(pt_tmp) = mult_int16(*(pt_tmp), tmp); + pt_tmp++; + *(pt_tmp) = mult_int16(*(pt_tmp), tmp); + pt_tmp++; + } + } + + + if ((nb_bits <= NBBITS_7k) && (newDTXState == SPEECH)) + { + isf_extrapolation(HfIsf); + Isp_Az(HfIsf, HfA, M16k, 0); + + weight_amrwb_lpc(HfA, Ap, 29491, M16k); /* fac=0.9 */ + + wb_syn_filt(Ap, + M16k, + HF, + HF, + L_SUBFR16k, + st->mem_syn_hf, + 1, + ScratchMem); + } + else + { + /* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */ + weight_amrwb_lpc(Aq, Ap, 19661, M); /* fac=0.6 */ + + wb_syn_filt(Ap, + M, + HF, + HF, + L_SUBFR16k, + st->mem_syn_hf + (M16k - M), + 1, + ScratchMem); + } + + /* noise Band Pass filtering (1ms of delay) */ + band_pass_6k_7k(HF, + L_SUBFR16k, + st->mem_hf, + ScratchMem); + + + if (nb_bits >= NBBITS_24k) + { + /* Low Pass filtering (7 kHz) */ + low_pass_filt_7k(HF, + L_SUBFR16k, + st->mem_hf3, + ScratchMem); + } + /* add filtered HF noise to speech synthesis */ + + pt_synth = synth16k; + pt_HF = HF; + + for (i = L_SUBFR16k >> 1; i != 0; i--) + { + *(pt_synth) = add_int16(*(pt_synth), *(pt_HF++)); /* check 16 bit saturation */ + pt_synth++; + *(pt_synth) = add_int16(*(pt_synth), *(pt_HF++)); + pt_synth++; + } + +} + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/synthesis_amr_wb.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/synthesis_amr_wb.h new file mode 100644 index 00000000..2074aabe --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/synthesis_amr_wb.h @@ -0,0 +1,90 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Pathname: ./cpp/include/synthesis_amr_wb.h + +------------------------------------------------------------------------------ + INCLUDE DESCRIPTION + +------------------------------------------------------------------------------ +*/ + +#ifndef SYNTHESIS_AMR_WB_H +#define SYNTHESIS_AMR_WB_H + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL VARIABLES REFERENCES +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES AND SIMPLE TYPEDEF'S +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +{ +#endif + + void synthesis_amr_wb( + int16 Aq[], /* A(z) : quantized Az */ + int16 exc[], /* (i) : excitation at 12kHz */ + int16 Q_new, /* (i) : scaling performed on exc */ + int16 synth16k[], /* (o) : 16kHz synthesis signal */ + int16 prms, /* (i) : parameter */ + int16 HfIsf[], + int16 nb_bits, + int16 newDTXState, + Decoder_State * st, /* (i/o) : State structure */ + int16 bfi, /* (i) : bad frame indicator */ + int16 * ScratchMemory + ); + +#ifdef __cplusplus +} +#endif + + + +#endif /* PV_NORMALIZE_H */ diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/voice_factor.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/voice_factor.cpp new file mode 100644 index 00000000..6163335c --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/voice_factor.cpp @@ -0,0 +1,167 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: voice_factor.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 exc[], (i) Q_exc : pitch excitation + int16 Q_exc, (i) : exc format + int16 gain_pit, (i) Q14 : gain of pitch + int16 code[], (i) Q9 : Fixed codebook excitation + int16 gain_code, (i) Q0 : gain of code + int16 L_subfr (i) : subframe length + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Find the voicing factor (1=voice to -1=unvoiced). + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwb_math_op.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +int16 voice_factor( /* (o) Q15 : factor (-1=unvoiced to 1=voiced) */ + int16 exc[], /* (i) Q_exc : pitch excitation */ + int16 Q_exc, /* (i) : exc format */ + int16 gain_pit, /* (i) Q14 : gain of pitch */ + int16 code[], /* (i) Q9 : Fixed codebook excitation */ + int16 gain_code, /* (i) Q0 : gain of code */ + int16 L_subfr /* (i) : subframe length */ +) +{ + int16 i, tmp, exp, ener1, exp1, ener2, exp2; + int32 L_tmp; + + ener1 = extract_h(Dot_product12(exc, exc, L_subfr, &exp1)); + exp1 = sub_int16(exp1, Q_exc << 1); + L_tmp = mul_16by16_to_int32(gain_pit, gain_pit); + exp = normalize_amr_wb(L_tmp); + + tmp = (int16)((L_tmp << exp) >> 16); + ener1 = mult_int16(ener1, tmp); + exp1 -= (exp + 10); /* 10 -> gain_pit Q14 to Q9 */ + + ener2 = extract_h(Dot_product12(code, code, L_subfr, &exp2)); + + exp = norm_s(gain_code); + tmp = shl_int16(gain_code, exp); + tmp = mult_int16(tmp, tmp); + ener2 = mult_int16(ener2, tmp); + exp2 -= (exp << 1); + + i = exp1 - exp2; + + + if (i >= 0) + { + ener1 >>= 1; + ener2 >>= (i + 1); + } + else + { + ener1 >>= (1 - i); + ener2 >>= 1; + } + + tmp = ener1 - ener2; + ener1 += ener2 + 1; + + + if (tmp >= 0) + { + tmp = div_16by16(tmp, ener1); + } + else + { + tmp = negate_int16(div_16by16(negate_int16(tmp), ener1)); + } + + return (tmp); +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/wb_syn_filt.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/wb_syn_filt.cpp new file mode 100644 index 00000000..f307deef --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/wb_syn_filt.cpp @@ -0,0 +1,299 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: wb_syn_filt.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + +wb_syn_filt + + int16 a[], (i) Q12 : a[m+1] prediction coefficients + int16 m, (i) : order of LP filter + int16 x[], (i) : input signal + int16 y[], (o) : output signal + int16 lg, (i) : size of filtering + int16 mem[], (i/o) : memory associated with this filtering. + int16 update, (i) : 0=no update, 1=update of memory. + int16 y_buf[] + +Syn_filt_32 + + int16 a[], (i) Q12 : a[m+1] prediction coefficients + int16 m, (i) : order of LP filter + int16 exc[], (i) Qnew: excitation (exc[i] >> Qnew) + int16 Qnew, (i) : exc scaling = 0(min) to 8(max) + int16 sig_hi[], (o) /16 : synthesis high + int16 sig_lo[], (o) /16 : synthesis low + int16 lg (i) : size of filtering + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Do the synthesis filtering 1/A(z) 16 and 32-bits version + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_mem_funcs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwb_math_op.h" +#include "pvamrwbdecoder_cnst.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void wb_syn_filt( + int16 a[], /* (i) Q12 : a[m+1] prediction coefficients */ + int16 m, /* (i) : order of LP filter */ + int16 x[], /* (i) : input signal */ + int16 y[], /* (o) : output signal */ + int16 lg, /* (i) : size of filtering */ + int16 mem[], /* (i/o) : memory associated with this filtering. */ + int16 update, /* (i) : 0=no update, 1=update of memory. */ + int16 y_buf[] +) +{ + + int16 i, j; + int32 L_tmp1; + int32 L_tmp2; + int32 L_tmp3; + int32 L_tmp4; + int16 *yy; + + /* copy initial filter states into synthesis buffer */ + pv_memcpy(y_buf, mem, m*sizeof(*yy)); + + yy = &y_buf[m]; + + /* Do the filtering. */ + + for (i = 0; i < lg >> 2; i++) + { + L_tmp1 = -((int32)x[(i<<2)] << 11); + L_tmp2 = -((int32)x[(i<<2)+1] << 11); + L_tmp3 = -((int32)x[(i<<2)+2] << 11); + L_tmp4 = -((int32)x[(i<<2)+3] << 11); + + /* a[] uses Q12 and abs(a) =< 1 */ + + L_tmp1 = fxp_mac_16by16(yy[(i<<2) -3], a[3], L_tmp1); + L_tmp2 = fxp_mac_16by16(yy[(i<<2) -2], a[3], L_tmp2); + L_tmp1 = fxp_mac_16by16(yy[(i<<2) -2], a[2], L_tmp1); + L_tmp2 = fxp_mac_16by16(yy[(i<<2) -1], a[2], L_tmp2); + L_tmp1 = fxp_mac_16by16(yy[(i<<2) -1], a[1], L_tmp1); + + for (j = 4; j < m; j += 2) + { + L_tmp1 = fxp_mac_16by16(yy[(i<<2)-1 - j], a[j+1], L_tmp1); + L_tmp2 = fxp_mac_16by16(yy[(i<<2) - j], a[j+1], L_tmp2); + L_tmp1 = fxp_mac_16by16(yy[(i<<2) - j], a[j ], L_tmp1); + L_tmp2 = fxp_mac_16by16(yy[(i<<2)+1 - j], a[j ], L_tmp2); + L_tmp3 = fxp_mac_16by16(yy[(i<<2)+1 - j], a[j+1], L_tmp3); + L_tmp4 = fxp_mac_16by16(yy[(i<<2)+2 - j], a[j+1], L_tmp4); + L_tmp3 = fxp_mac_16by16(yy[(i<<2)+2 - j], a[j ], L_tmp3); + L_tmp4 = fxp_mac_16by16(yy[(i<<2)+3 - j], a[j ], L_tmp4); + } + + L_tmp1 = fxp_mac_16by16(yy[(i<<2) - j], a[j], L_tmp1); + L_tmp2 = fxp_mac_16by16(yy[(i<<2)+1 - j], a[j], L_tmp2); + L_tmp3 = fxp_mac_16by16(yy[(i<<2)+2 - j], a[j], L_tmp3); + L_tmp4 = fxp_mac_16by16(yy[(i<<2)+3 - j], a[j], L_tmp4); + + L_tmp1 = shl_int32(L_tmp1, 4); + + y[(i<<2)] = yy[(i<<2)] = amr_wb_round(-L_tmp1); + + L_tmp2 = fxp_mac_16by16(yy[(i<<2)], a[1], L_tmp2); + + L_tmp2 = shl_int32(L_tmp2, 4); + + y[(i<<2)+1] = yy[(i<<2)+1] = amr_wb_round(-L_tmp2); + + L_tmp3 = fxp_mac_16by16(yy[(i<<2) - 1], a[3], L_tmp3); + L_tmp4 = fxp_mac_16by16(yy[(i<<2)], a[3], L_tmp4); + L_tmp3 = fxp_mac_16by16(yy[(i<<2)], a[2], L_tmp3); + L_tmp4 = fxp_mac_16by16(yy[(i<<2) + 1], a[2], L_tmp4); + L_tmp3 = fxp_mac_16by16(yy[(i<<2) + 1], a[1], L_tmp3); + + L_tmp3 = shl_int32(L_tmp3, 4); + + y[(i<<2)+2] = yy[(i<<2)+2] = amr_wb_round(-L_tmp3); + + L_tmp4 = fxp_mac_16by16(yy[(i<<2)+2], a[1], L_tmp4); + + L_tmp4 = shl_int32(L_tmp4, 4); + + y[(i<<2)+3] = yy[(i<<2)+3] = amr_wb_round(-L_tmp4); + } + + + /* Update memory if required */ + + if (update) + { + pv_memcpy(mem, &y[lg - m], m*sizeof(*y)); + } + + return; +} + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void Syn_filt_32( + int16 a[], /* (i) Q12 : a[m+1] prediction coefficients */ + int16 m, /* (i) : order of LP filter */ + int16 exc[], /* (i) Qnew: excitation (exc[i] >> Qnew) */ + int16 Qnew, /* (i) : exc scaling = 0(min) to 8(max) */ + int16 sig_hi[], /* (o) /16 : synthesis high */ + int16 sig_lo[], /* (o) /16 : synthesis low */ + int16 lg /* (i) : size of filtering */ +) +{ + int16 i, k, a0; + int32 L_tmp1; + int32 L_tmp2; + int32 L_tmp3; + int32 L_tmp4; + + a0 = 9 - Qnew; /* input / 16 and >>Qnew */ + + /* Do the filtering. */ + + for (i = 0; i < lg >> 1; i++) + { + + L_tmp3 = 0; + L_tmp4 = 0; + + L_tmp1 = fxp_mul_16by16(sig_lo[(i<<1) - 1], a[1]); + L_tmp2 = fxp_mul_16by16(sig_hi[(i<<1) - 1], a[1]); + + for (k = 2; k < m; k += 2) + { + + L_tmp1 = fxp_mac_16by16(sig_lo[(i<<1)-1 - k], a[k+1], L_tmp1); + L_tmp2 = fxp_mac_16by16(sig_hi[(i<<1)-1 - k], a[k+1], L_tmp2); + L_tmp1 = fxp_mac_16by16(sig_lo[(i<<1) - k], a[k ], L_tmp1); + L_tmp2 = fxp_mac_16by16(sig_hi[(i<<1) - k], a[k ], L_tmp2); + L_tmp3 = fxp_mac_16by16(sig_lo[(i<<1) - k], a[k+1], L_tmp3); + L_tmp4 = fxp_mac_16by16(sig_hi[(i<<1) - k], a[k+1], L_tmp4); + L_tmp3 = fxp_mac_16by16(sig_lo[(i<<1)+1 - k], a[k ], L_tmp3); + L_tmp4 = fxp_mac_16by16(sig_hi[(i<<1)+1 - k], a[k ], L_tmp4); + } + + L_tmp1 = -fxp_mac_16by16(sig_lo[(i<<1) - k], a[k], L_tmp1); + L_tmp3 = fxp_mac_16by16(sig_lo[(i<<1)+1 - k], a[k], L_tmp3); + L_tmp2 = fxp_mac_16by16(sig_hi[(i<<1) - k], a[k], L_tmp2); + L_tmp4 = fxp_mac_16by16(sig_hi[(i<<1)+1 - k], a[k], L_tmp4); + + + + L_tmp1 >>= 11; /* -4 : sig_lo[i] << 4 */ + + L_tmp1 += (int32)exc[(i<<1)] << a0; + + L_tmp1 -= (L_tmp2 << 1); + /* sig_hi = bit16 to bit31 of synthesis */ + L_tmp1 = shl_int32(L_tmp1, 3); /* ai in Q12 */ + + sig_hi[(i<<1)] = (int16)(L_tmp1 >> 16); + + L_tmp4 = fxp_mac_16by16((int16)(L_tmp1 >> 16), a[1], L_tmp4); + + /* sig_lo = bit4 to bit15 of synthesis */ + /* L_tmp1 >>= 4 : sig_lo[i] >> 4 */ + sig_lo[(i<<1)] = (int16)((L_tmp1 >> 4) - ((L_tmp1 >> 16) << 12)); + + L_tmp3 = fxp_mac_16by16(sig_lo[(i<<1)], a[1], L_tmp3); + L_tmp3 = -L_tmp3 >> 11; + + L_tmp3 += (int32)exc[(i<<1)+1] << a0; + + L_tmp3 -= (L_tmp4 << 1); + /* sig_hi = bit16 to bit31 of synthesis */ + L_tmp3 = shl_int32(L_tmp3, 3); /* ai in Q12 */ + sig_hi[(i<<1)+1] = (int16)(L_tmp3 >> 16); + + /* sig_lo = bit4 to bit15 of synthesis */ + /* L_tmp1 >>= 4 : sig_lo[i] >> 4 */ + sig_lo[(i<<1)+1] = (int16)((L_tmp3 >> 4) - (sig_hi[(i<<1)+1] << 12)); + } + +} + + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/weight_amrwb_lpc.cpp b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/weight_amrwb_lpc.cpp new file mode 100644 index 00000000..726ef463 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/amr_wb/dec/src/weight_amrwb_lpc.cpp @@ -0,0 +1,127 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/**************************************************************************************** +Portions of this file are derived from the following 3GPP standard: + + 3GPP TS 26.173 + ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec + Available from http://www.3gpp.org + +(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) +Permission to distribute, modify and use this file under the standard license +terms listed above has been obtained from the copyright holder. +****************************************************************************************/ +/* +------------------------------------------------------------------------------ + + + + Filename: weight_amrwb_lpc.cpp + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + int16 a[], (i) Q12 : a[m+1] LPC coefficients + int16 ap[], (o) Q12 : Spectral expanded LPC coefficients + int16 gamma, (i) Q15 : Spectral expansion factor. + int16 m (i) : LPC order. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Weighting of LPC coefficients. + ap[i] = a[i] (gamma i) + +------------------------------------------------------------------------------ + REQUIREMENTS + + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ + +#include "pv_amr_wb_type_defs.h" +#include "pvamrwbdecoder_basic_op.h" +#include "pvamrwbdecoder_acelp.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ + +void weight_amrwb_lpc( + int16 a[], /* (i) Q12 : a[m+1] LPC coefficients */ + int16 ap[], /* (o) Q12 : Spectral expanded LPC coefficients */ + int16 gamma, /* (i) Q15 : Spectral expansion factor. */ + int16 m /* (i) : LPC order. */ +) +{ + int16 i, fac; + int32 roundFactor = 0x00004000L; + ap[0] = a[0]; + fac = gamma; + for (i = 1; i < m; i++) + { + ap[i] = (int16)(fxp_mac_16by16(a[i], fac, roundFactor) >> 15); + fac = (int16)(fxp_mac_16by16(fac, gamma, roundFactor) >> 15); + } + ap[i] = (int16)(fxp_mac_16by16(a[i], fac, roundFactor) >> 15); + + return; +} diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/common/dec/Android.mk b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/common/dec/Android.mk new file mode 100644 index 00000000..3ba1c634 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/common/dec/Android.mk @@ -0,0 +1,27 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + + + + + +LOCAL_CFLAGS := $(PV_CFLAGS) + + +LOCAL_STATIC_LIBRARIES := + +LOCAL_SHARED_LIBRARIES := + +LOCAL_C_INCLUDES := \ + $(PV_TOP)/codecs_v2/audio/gsm_amr/common/dec/build/make \ + $(PV_TOP)/codecs_v2/audio/gsm_amr/common/dec/include \ + $(PV_INCLUDES) + +LOCAL_COPY_HEADERS_TO := $(PV_COPY_HEADERS_TO) + +LOCAL_COPY_HEADERS := \ + include/pvgsmamrdecoderinterface.h + +include $(BUILD_COPY_HEADERS) diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/common/dec/build/make/local.mk b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/common/dec/build/make/local.mk new file mode 100644 index 00000000..8db50c46 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/common/dec/build/make/local.mk @@ -0,0 +1,16 @@ +# Get the current local path as the first operation +LOCAL_PATH := $(call get_makefile_dir) + +# Clear out the variables used in the local makefiles +include $(MK)/clear.mk + +TARGET := + + +INCSRCDIR := ../../include + +HDRS := pvgsmamrdecoderinterface.h + + +include $(MK)/library.mk + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/common/dec/include/pvgsmamrdecoderinterface.h b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/common/dec/include/pvgsmamrdecoderinterface.h new file mode 100644 index 00000000..2d9b9dfa --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/common/dec/include/pvgsmamrdecoderinterface.h @@ -0,0 +1,206 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +////////////////////////////////////////////////////////////////////////////////// +// // +// File: pvgsmamrdecoderinterface.h // +// // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef _PVGSMAMR_DECODER_INTERFACE_H +#define _PVGSMAMR_DECODER_INTERFACE_H + +#include "oscl_base.h" + +/*---------------------------------------------------------------------------- +; ENUMERATED TYPEDEF'S +----------------------------------------------------------------------------*/ + +typedef enum +{ + /* + * One word (2-byte) to indicate type of frame type. + * One word (2-byte) to indicate frame type. + * One word (2-byte) to indicate mode. + * N words (2-byte) containing N bits (bit 0 = 0xff81, bit 1 = 0x007f). + */ + ETS = 0, /* Both AMR-Narrowband and AMR-Wideband */ + + /* + * One word (2-byte) for sync word (good frames: 0x6b21, bad frames: 0x6b20) + * One word (2-byte) for frame length N. + * N words (2-byte) containing N bits (bit 0 = 0x007f, bit 1 = 0x0081). + */ + ITU, /* AMR-Wideband */ + + /* + * AMR-WB MIME/storage format, see RFC 3267 (sections 5.1 and 5.3) for details + */ + MIME_IETF, + + WMF, /* AMR-Narrowband */ + + IF2 /* AMR-Narrowband */ + +} bitstream_format; + + + +/*---------------------------------------------------------------------------- +; STRUCTURES TYPEDEF'S +----------------------------------------------------------------------------*/ +typedef struct +{ + int16 prev_ft; + int16 prev_mode; +} RX_State; + + +typedef struct tPVAmrDecoderExternal +{ + /* + * INPUT: + * Pointer to the input buffer that contains the encoded bistream data. + * The data is filled in such that the first bit transmitted is + * the most-significant bit (MSB) of the first array element. + * The buffer is accessed in a linear fashion for speed, and the number of + * bytes consumed varies frame to frame. This is use for mime/ietf data + */ + uint8 *pInputBuffer; + + /* + * INPUT: + * Pointer to the input buffer that contains the encoded stream data. + * The data is filled such that the first bit transmitted is + * in the first int16 element. + * The buffer is accessed in a linear fashion for speed, and the number of + * bytes consumed varies frame to frame. + */ + int16 *pInputSampleBuffer; + + /* + * INPUT: (but what is pointed to is an output) + * Pointer to the output buffer to hold the 16-bit PCM audio samples. + */ + int16 *pOutputBuffer; + + /* + * INPUT: + * Number of requested output audio channels. This relieves the calling + * environment from having to perform stereo-to-mono or mono-to-stereo + * conversions. + */ + int32 desiredChannels; + + /* + * INPUT: + * Format type of the encoded bitstream. + */ + bitstream_format input_format; + + /* + * OUTPUT: + * The sampling rate decoded from the bitstream, in units of + * samples/second. For this release of the library this value does + * not change from frame to frame, but future versions will. + */ + int32 samplingRate; + + /* + * OUTPUT: + * This value is the bitrate in units of bits/second. IT + * is calculated using the number of bits consumed for the current frame, + * and then multiplying by the sampling_rate, divided by points in a frame. + * This value can changes frame to frame. + */ + int32 bitRate; + + /* + * OUTPUT: + * The number of channels decoded from the bitstream. The output data + * will have be the amount specified in the variable desiredChannels, + * this output is informative only, and can be ignored. + */ + int32 encodedChannels; + + /* + * OUTPUT: + * This value is the number of output PCM samples per channel. + * It is 320. + */ + int16 frameLength; + + /* + * OUTPUT: + * This value is the quality indicator. 1 (good) 0 (bad) + */ + uint8 quality; + + + /* + * OUTPUT: + * GSM AMR NB and WB mode (i.e. bit-rate ) + */ + int16 mode; + int16 mode_old; + + /* + * OUTPUT: + * GSM AMR NB and WB frame type ( speech_good, speech_bad, sid, etc.) + */ + int16 frame_type; + + int16 reset_flag; + int16 reset_flag_old; + + /* + * OUTPUT: + * Decoder status + */ + int32 status; + + /* + * OUTPUT: + * Rx status state + */ + RX_State rx_state; + +} tPVAmrDecoderExternal; + +// CDecoder_AMRInterface + +#ifdef __cplusplus + +class CDecoder_AMRInterface +{ + public: + virtual ~CDecoder_AMRInterface() {}; + OSCL_IMPORT_REF virtual int32 StartL(tPVAmrDecoderExternal * pExt, + bool aAllocateInputBuffer = false, + bool aAllocateOutputBuffer = false) = 0; + + OSCL_IMPORT_REF virtual int32 ExecuteL(tPVAmrDecoderExternal * pExt) = 0; + + OSCL_IMPORT_REF virtual int32 ResetDecoderL() = 0; + OSCL_IMPORT_REF virtual void StopL() = 0; + OSCL_IMPORT_REF virtual void TerminateDecoderL() = 0; +}; +#endif + + +#endif + diff --git a/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/patent_disclaimer.txt b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/patent_disclaimer.txt new file mode 100644 index 00000000..b4bf11d4 --- /dev/null +++ b/src/libs/opencore-amr/opencore/codecs_v2/audio/gsm_amr/patent_disclaimer.txt @@ -0,0 +1,9 @@ + +THIS IS NOT A GRANT OF PATENT RIGHTS. + +Google makes no representation or warranty that the codecs for which +source code is made available hereunder are unencumbered by +third-party patents. Those intending to use this source code in +hardware or software products are advised that implementations of +these codecs, including in open source software or shareware, may +require patent licenses from the relevant patent holders. diff --git a/src/libs/opencore-amr/opencore/patent_disclaimer.txt b/src/libs/opencore-amr/opencore/patent_disclaimer.txt new file mode 100644 index 00000000..b4bf11d4 --- /dev/null +++ b/src/libs/opencore-amr/opencore/patent_disclaimer.txt @@ -0,0 +1,9 @@ + +THIS IS NOT A GRANT OF PATENT RIGHTS. + +Google makes no representation or warranty that the codecs for which +source code is made available hereunder are unencumbered by +third-party patents. Those intending to use this source code in +hardware or software products are advised that implementations of +these codecs, including in open source software or shareware, may +require patent licenses from the relevant patent holders. diff --git a/src/libs/opencore-amr/oscl/inttypes.h b/src/libs/opencore-amr/oscl/inttypes.h new file mode 100644 index 00000000..589d36d5 --- /dev/null +++ b/src/libs/opencore-amr/oscl/inttypes.h @@ -0,0 +1,5 @@ +// +// Created by mvp@mvplayer.net +// FIXME: use official inttypes.h +// +#include "stdint.h" diff --git a/src/libs/opencore-amr/oscl/oscl_base.h b/src/libs/opencore-amr/oscl/oscl_base.h new file mode 100644 index 00000000..93e82461 --- /dev/null +++ b/src/libs/opencore-amr/oscl/oscl_base.h @@ -0,0 +1,37 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#ifndef OSCL_BASE_H +#define OSCL_BASE_H + +#include + +typedef int8_t int8; +typedef uint8_t uint8; +typedef int16_t int16; +typedef uint16_t uint16; +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; + +#define OSCL_IMPORT_REF +#define OSCL_EXPORT_REF +#define OSCL_UNUSED_ARG(x) (void)(x) + +#endif diff --git a/src/libs/opencore-amr/oscl/oscl_base_macros.h b/src/libs/opencore-amr/oscl/oscl_base_macros.h new file mode 100644 index 00000000..7fadf2e3 --- /dev/null +++ b/src/libs/opencore-amr/oscl/oscl_base_macros.h @@ -0,0 +1,25 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#ifndef OSCL_BASE_MACROS_H +#define OSCL_BASE_MACROS_H + +#define EPV_ARM_GNUC 1 +#define EPV_ARM_RVCT 2 + +#endif diff --git a/src/libs/opencore-amr/oscl/oscl_dll.h b/src/libs/opencore-amr/oscl/oscl_dll.h new file mode 100644 index 00000000..611f691d --- /dev/null +++ b/src/libs/opencore-amr/oscl/oscl_dll.h @@ -0,0 +1,39 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +#ifndef OSCL_DLL_H_INCLUDED +#define OSCL_DLL_H_INCLUDED + +#define OSCL_DLL_ENTRY_POINT() void oscl_dll_entry_point() {} + + +/** + * Default DLL entry/exit point function. + * + * The body of the DLL entry point is given. The macro + * only needs to be declared within the source file. + * + * Usage : + * + * OSCL_DLL_ENTRY_POINT_DEFAULT() + */ + +#define OSCL_DLL_ENTRY_POINT_DEFAULT() + + + +#endif // OSCL_DLL_H_INCLUDED diff --git a/src/libs/opencore-amr/oscl/oscl_error.h b/src/libs/opencore-amr/oscl/oscl_error.h new file mode 100644 index 00000000..3ee97183 --- /dev/null +++ b/src/libs/opencore-amr/oscl/oscl_error.h @@ -0,0 +1,49 @@ +/* ------------------------------------------------------------------ + + * Copyright (C) 1998-2009 PacketVideo + + * + + * Licensed under the Apache License, Version 2.0 (the "License"); + + * you may not use this file except in compliance with the License. + + * You may obtain a copy of the License at + + * + + * http://www.apache.org/licenses/LICENSE-2.0 + + * + + * Unless required by applicable law or agreed to in writing, software + + * distributed under the License is distributed on an "AS IS" BASIS, + + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + + * express or implied. + + * See the License for the specific language governing permissions + + * and limitations under the License. + + * ------------------------------------------------------------------- + + */ + +#ifndef OSCL_ERROR_H_INCLUDED + +#define OSCL_ERROR_H_INCLUDED + + + + + +#define OSCL_LEAVE(x) + + + + + +#endif //OSCL_ERROR_H_INCLUDED diff --git a/src/libs/opencore-amr/oscl/oscl_error_codes.h b/src/libs/opencore-amr/oscl/oscl_error_codes.h new file mode 100644 index 00000000..90730f5b --- /dev/null +++ b/src/libs/opencore-amr/oscl/oscl_error_codes.h @@ -0,0 +1,113 @@ +/* ------------------------------------------------------------------ + + * Copyright (C) 1998-2009 PacketVideo + + * + + * Licensed under the Apache License, Version 2.0 (the "License"); + + * you may not use this file except in compliance with the License. + + * You may obtain a copy of the License at + + * + + * http://www.apache.org/licenses/LICENSE-2.0 + + * + + * Unless required by applicable law or agreed to in writing, software + + * distributed under the License is distributed on an "AS IS" BASIS, + + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + + * express or implied. + + * See the License for the specific language governing permissions + + * and limitations under the License. + + * ------------------------------------------------------------------- + + */ + + + +#ifndef OSCL_ERROR_CODES_H_INCLUDED + +#define OSCL_ERROR_CODES_H_INCLUDED + + + + + +/** Leave Codes + +*/ + +typedef int32 OsclLeaveCode; + + + +#define OsclErrNone 0 + +#define OsclErrGeneral 100 + +#define OsclErrNoMemory 101 + +#define OsclErrCancelled 102 + +#define OsclErrNotSupported 103 + +#define OsclErrArgument 104 + +#define OsclErrBadHandle 105 + +#define OsclErrAlreadyExists 106 + +#define OsclErrBusy 107 + +#define OsclErrNotReady 108 + +#define OsclErrCorrupt 109 + +#define OsclErrTimeout 110 + +#define OsclErrOverflow 111 + +#define OsclErrUnderflow 112 + +#define OsclErrInvalidState 113 + +#define OsclErrNoResources 114 + + + +/** For backward compatibility with old definitions + +*/ + +#define OSCL_ERR_NONE OsclErrNone + +#define OSCL_BAD_ALLOC_EXCEPTION_CODE OsclErrNoMemory + + + +/** Return Codes + +*/ + +typedef int32 OsclReturnCode; + + + +#define OsclSuccess 0 + +#define OsclPending 1 + +#define OsclFailure -1 + + + +#endif diff --git a/src/libs/opencore-amr/oscl/oscl_exception.h b/src/libs/opencore-amr/oscl/oscl_exception.h new file mode 100644 index 00000000..08a93490 --- /dev/null +++ b/src/libs/opencore-amr/oscl/oscl_exception.h @@ -0,0 +1,50 @@ + + +/* ------------------------------------------------------------------ + + * Copyright (C) 1998-2009 PacketVideo + + * + + * Licensed under the Apache License, Version 2.0 (the "License"); + + * you may not use this file except in compliance with the License. + + * You may obtain a copy of the License at + + * + + * http://www.apache.org/licenses/LICENSE-2.0 + + * + + * Unless required by applicable law or agreed to in writing, software + + * distributed under the License is distributed on an "AS IS" BASIS, + + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + + * express or implied. + + * See the License for the specific language governing permissions + + * and limitations under the License. + + * ------------------------------------------------------------------- + + */ + + + +#ifndef OSCL_EXCEPTION_H_INCLUDED + +#define OSCL_EXCEPTION_H_INCLUDED + + + + + + + +#endif // INCLUDED_OSCL_EXCEPTION_H + diff --git a/src/libs/opencore-amr/oscl/oscl_mem.h b/src/libs/opencore-amr/oscl/oscl_mem.h new file mode 100644 index 00000000..0cbeb092 --- /dev/null +++ b/src/libs/opencore-amr/oscl/oscl_mem.h @@ -0,0 +1,42 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#ifndef OSCL_MEM_H +#define OSCL_MEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#define oscl_malloc malloc +#define oscl_free free +#define oscl_memset memset +#define oscl_memmove memmove +#define oscl_memcpy memcpy + +#define OSCL_ARRAY_DELETE(ptr) delete [] ptr + +#define OSCL_ARRAY_NEW(T, count) new T[count] + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/opencore-amr/oscl/stdint.h b/src/libs/opencore-amr/oscl/stdint.h new file mode 100644 index 00000000..92c169ec --- /dev/null +++ b/src/libs/opencore-amr/oscl/stdint.h @@ -0,0 +1,168 @@ +// +// Created by mvp@mvplayer.net +// +#ifndef STDINT_H +#define STDINT_H +#include + +/* 7.18.1.1 Exact-width integer types */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned uint32_t; + +#ifdef __GNUC__ +typedef long long int64_t; +typedef unsigned long long uint64_t; +#else +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#endif + +/* 7.18.1.2 Minimum-width integer types */ +typedef signed char int_least8_t; +typedef unsigned char uint_least8_t; +typedef short int_least16_t; +typedef unsigned short uint_least16_t; +typedef int int_least32_t; +typedef unsigned uint_least32_t; + +#ifdef __GNUC__ +typedef long long int_least64_t; +typedef unsigned long long uint_least64_t; +#else +typedef __int64 int_least64_t; +typedef unsigned __int64 uint_least64_t; +#endif + +/* 7.18.1.3 Fastest minimum-width integer types + * Not actually guaranteed to be fastest for all purposes + * Here we use the exact-width types for 8 and 16-bit ints. + */ +typedef char int_fast8_t; +typedef unsigned char uint_fast8_t; +typedef short int_fast16_t; +typedef unsigned short uint_fast16_t; +typedef int int_fast32_t; +typedef unsigned int uint_fast32_t; + +#ifdef __GNUC__ +typedef long long int_fast64_t; +typedef unsigned long long uint_fast64_t; +#else +typedef __int64 int_fast64_t; +typedef unsigned __int64 uint_fast64_t; +#endif + +/* 7.18.1.4 Integer types capable of holding object pointers */ +typedef int intptr_t; +typedef unsigned uintptr_t; + +/* 7.18.1.5 Greatest-width integer types */ +#ifdef __GNUC__ +typedef long long intmax_t; +typedef unsigned long long uintmax_t; +#else +typedef __int64 intmax_t; +typedef unsigned __int64 uintmax_t; +#endif + +/* 7.18.2 Limits of specified-width integer types */ +#if !defined ( __cplusplus) || defined (__STDC_LIMIT_MACROS) + +/* 7.18.2.1 Limits of exact-width integer types */ +#define INT8_MIN (-128) +#define INT16_MIN (-32768) +#define INT32_MIN (-2147483647 - 1) +#ifdef __GNUC__ +#define INT64_MIN (-9223372036854775807LL - 1) +#else +#define INT64_MIN (-9223372036854775807i64 - 1) +#endif + +#define INT8_MAX 127 +#define INT16_MAX 32767 +#define INT32_MAX 2147483647 +#ifdef __GNUC__ +#define INT64_MAX 9223372036854775807LL +#else +#define INT64_MAX 9223372036854775807i64 +#endif + +#define UINT8_MAX 0xff /* 255U */ +#define UINT16_MAX 0xffff /* 65535U */ +#define UINT32_MAX 0xffffffff /* 4294967295U */ +#ifdef __GNUC__ +#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */ +#else +#define UINT64_MAX 0xffffffffffffffffui64 /* 18446744073709551615ULL */ +#endif + +/* 7.18.2.2 Limits of minimum-width integer types */ +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST64_MIN INT64_MIN + +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MAX INT64_MAX + +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +/* 7.18.2.3 Limits of fastest minimum-width integer types */ +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST64_MIN INT64_MIN + +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MAX INT64_MAX + +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +/* 7.18.2.4 Limits of integer types capable of holding + object pointers */ +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#define UINTPTR_MAX UINT32_MAX + +/* 7.18.2.5 Limits of greatest-width integer types */ +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +/* 7.18.3 Limits of other integer types */ +#define PTRDIFF_MIN INT32_MIN +#define PTRDIFF_MAX INT32_MAX + +#define SIG_ATOMIC_MIN INT32_MIN +#define SIG_ATOMIC_MAX INT32_MAX + +#define SIZE_MAX UINT32_MAX + +#ifndef WCHAR_MIN /* also in wchar.h */ +#define WCHAR_MIN 0 +#define WCHAR_MAX 0xffff /* UINT16_MAX */ +#endif + +/* + * wint_t is unsigned short for compatibility with MS runtime + */ +#define WINT_MIN 0 +#define WINT_MAX 0xffff /* UINT16_MAX */ + +#endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */ + +#endif //STDINT_H diff --git a/src/libs/opencore-amr/test/Makefile.am b/src/libs/opencore-amr/test/Makefile.am new file mode 100644 index 00000000..a0c4ffa6 --- /dev/null +++ b/src/libs/opencore-amr/test/Makefile.am @@ -0,0 +1,35 @@ + +bin_PROGRAMS = amrwb-dec$(EXEEXT) +noinst_PROGRAMS = linkboth$(EXEEXT) +AM_CFLAGS = + +if AMRNB_DECODER + bin_PROGRAMS += amrnb-dec$(EXEEXT) +else + AM_CFLAGS += -DDISABLE_AMRNB_DECODER +endif +if AMRNB_ENCODER + bin_PROGRAMS += amrnb-enc$(EXEEXT) + noinst_PROGRAMS += amrnb-enc-sine$(EXEEXT) +else + AM_CFLAGS += -DDISABLE_AMRNB_ENCODER +endif + +INCLUDES = -I$(top_srcdir)/amrnb -I$(top_srcdir)/amrwb + +amrnb_dec_LDADD = $(top_builddir)/amrnb/libopencore-amrnb.la +amrnb_enc_LDADD = $(top_builddir)/amrnb/libopencore-amrnb.la +amrnb_enc_sine_LDADD = $(top_builddir)/amrnb/libopencore-amrnb.la +amrnb_enc_sine_LDFLAGS = -lm +amrwb_dec_LDADD = $(top_builddir)/amrwb/libopencore-amrwb.la +linkboth_LDFLAGS = -static +linkboth_LDADD = $(top_builddir)/amrnb/libopencore-amrnb.la $(top_builddir)/amrwb/libopencore-amrwb.la + +amrnb_dec_SOURCES = amrnb-dec.c wavwriter.c +amrnb_enc_SOURCES = amrnb-enc.c wavreader.c +amrnb_enc_sine_SOURCES = amrnb-enc-sine.c +amrwb_dec_SOURCES = amrwb-dec.c wavwriter.c +linkboth_SOURCES = linkboth.c + +noinst_HEADERS = wavwriter.h wavreader.h + diff --git a/src/libs/opencore-amr/test/Makefile.in b/src/libs/opencore-amr/test/Makefile.in new file mode 100644 index 00000000..fdf116dd --- /dev/null +++ b/src/libs/opencore-amr/test/Makefile.in @@ -0,0 +1,614 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@AMRNB_DECODER_TRUE@am__append_1 = amrnb-dec$(EXEEXT) +@AMRNB_DECODER_FALSE@am__append_2 = -DDISABLE_AMRNB_DECODER +@AMRNB_ENCODER_TRUE@am__append_3 = amrnb-enc$(EXEEXT) +@AMRNB_ENCODER_TRUE@am__append_4 = amrnb-enc-sine$(EXEEXT) +@AMRNB_ENCODER_FALSE@am__append_5 = -DDISABLE_AMRNB_ENCODER +subdir = test +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) +am_amrnb_dec_OBJECTS = amrnb-dec.$(OBJEXT) wavwriter.$(OBJEXT) +amrnb_dec_OBJECTS = $(am_amrnb_dec_OBJECTS) +amrnb_dec_DEPENDENCIES = $(top_builddir)/amrnb/libopencore-amrnb.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am_amrnb_enc_OBJECTS = amrnb-enc.$(OBJEXT) wavreader.$(OBJEXT) +amrnb_enc_OBJECTS = $(am_amrnb_enc_OBJECTS) +amrnb_enc_DEPENDENCIES = $(top_builddir)/amrnb/libopencore-amrnb.la +am_amrnb_enc_sine_OBJECTS = amrnb-enc-sine.$(OBJEXT) +amrnb_enc_sine_OBJECTS = $(am_amrnb_enc_sine_OBJECTS) +amrnb_enc_sine_DEPENDENCIES = \ + $(top_builddir)/amrnb/libopencore-amrnb.la +amrnb_enc_sine_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(amrnb_enc_sine_LDFLAGS) $(LDFLAGS) -o \ + $@ +am_amrwb_dec_OBJECTS = amrwb-dec.$(OBJEXT) wavwriter.$(OBJEXT) +amrwb_dec_OBJECTS = $(am_amrwb_dec_OBJECTS) +amrwb_dec_DEPENDENCIES = $(top_builddir)/amrwb/libopencore-amrwb.la +am_linkboth_OBJECTS = linkboth.$(OBJEXT) +linkboth_OBJECTS = $(am_linkboth_OBJECTS) +linkboth_DEPENDENCIES = $(top_builddir)/amrnb/libopencore-amrnb.la \ + $(top_builddir)/amrwb/libopencore-amrwb.la +linkboth_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(linkboth_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(amrnb_dec_SOURCES) $(amrnb_enc_SOURCES) \ + $(amrnb_enc_sine_SOURCES) $(amrwb_dec_SOURCES) \ + $(linkboth_SOURCES) +DIST_SOURCES = $(amrnb_dec_SOURCES) $(amrnb_enc_SOURCES) \ + $(amrnb_enc_sine_SOURCES) $(amrwb_dec_SOURCES) \ + $(linkboth_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENCORE_AMRNB_VERSION = @OPENCORE_AMRNB_VERSION@ +OPENCORE_AMRWB_VERSION = @OPENCORE_AMRWB_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +bin_PROGRAMS = amrwb-dec$(EXEEXT) $(am__append_1) $(am__append_3) +noinst_PROGRAMS = linkboth$(EXEEXT) $(am__append_4) +AM_CFLAGS = $(am__append_2) $(am__append_5) +INCLUDES = -I$(top_srcdir)/amrnb -I$(top_srcdir)/amrwb +amrnb_dec_LDADD = $(top_builddir)/amrnb/libopencore-amrnb.la +amrnb_enc_LDADD = $(top_builddir)/amrnb/libopencore-amrnb.la +amrnb_enc_sine_LDADD = $(top_builddir)/amrnb/libopencore-amrnb.la +amrnb_enc_sine_LDFLAGS = -lm +amrwb_dec_LDADD = $(top_builddir)/amrwb/libopencore-amrwb.la +linkboth_LDFLAGS = -static +linkboth_LDADD = $(top_builddir)/amrnb/libopencore-amrnb.la $(top_builddir)/amrwb/libopencore-amrwb.la +amrnb_dec_SOURCES = amrnb-dec.c wavwriter.c +amrnb_enc_SOURCES = amrnb-enc.c wavreader.c +amrnb_enc_sine_SOURCES = amrnb-enc-sine.c +amrwb_dec_SOURCES = amrwb-dec.c wavwriter.c +linkboth_SOURCES = linkboth.c +noinst_HEADERS = wavwriter.h wavreader.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu test/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +amrnb-dec$(EXEEXT): $(amrnb_dec_OBJECTS) $(amrnb_dec_DEPENDENCIES) $(EXTRA_amrnb_dec_DEPENDENCIES) + @rm -f amrnb-dec$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(amrnb_dec_OBJECTS) $(amrnb_dec_LDADD) $(LIBS) +amrnb-enc$(EXEEXT): $(amrnb_enc_OBJECTS) $(amrnb_enc_DEPENDENCIES) $(EXTRA_amrnb_enc_DEPENDENCIES) + @rm -f amrnb-enc$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(amrnb_enc_OBJECTS) $(amrnb_enc_LDADD) $(LIBS) +amrnb-enc-sine$(EXEEXT): $(amrnb_enc_sine_OBJECTS) $(amrnb_enc_sine_DEPENDENCIES) $(EXTRA_amrnb_enc_sine_DEPENDENCIES) + @rm -f amrnb-enc-sine$(EXEEXT) + $(AM_V_CCLD)$(amrnb_enc_sine_LINK) $(amrnb_enc_sine_OBJECTS) $(amrnb_enc_sine_LDADD) $(LIBS) +amrwb-dec$(EXEEXT): $(amrwb_dec_OBJECTS) $(amrwb_dec_DEPENDENCIES) $(EXTRA_amrwb_dec_DEPENDENCIES) + @rm -f amrwb-dec$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(amrwb_dec_OBJECTS) $(amrwb_dec_LDADD) $(LIBS) +linkboth$(EXEEXT): $(linkboth_OBJECTS) $(linkboth_DEPENDENCIES) $(EXTRA_linkboth_DEPENDENCIES) + @rm -f linkboth$(EXEEXT) + $(AM_V_CCLD)$(linkboth_LINK) $(linkboth_OBJECTS) $(linkboth_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amrnb-dec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amrnb-enc-sine.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amrnb-enc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amrwb-dec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linkboth.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wavreader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wavwriter.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool clean-noinstPROGRAMS ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/opencore-amr/test/amrnb-dec.c b/src/libs/opencore-amr/test/amrnb-dec.c new file mode 100644 index 00000000..f708fcb5 --- /dev/null +++ b/src/libs/opencore-amr/test/amrnb-dec.c @@ -0,0 +1,168 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +//xx ../encode-8k-1ch.amr ../decode-8k-1ch.wav +#include +#include +#include +#include "wavwriter.h" +#include + +/* From WmfDecBytesPerFrame in dec_input_format_tab.cpp */ +const int sizes[] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 6, 5, 5, 0, 0, 0, 0 }; + +//#define DISABLE_AMRNB_ENCODER + + +int main(int argc, char *argv[]) { + + FILE* in; + char header[6]; + int n; + void *wav;// + void *amr; + void *amrDecoder; + + +//lhc mp4 dec 1/4 +FileWrapperPtr inputFile; + +// void* amrDecoder = (void*) malloc(sizeof(void *)); + //void* amrDecoder = NULL; + + + fprintf(stderr, "AMR-NB DEcode .amr file to .wav\n"); + + if (argc < 1) { + fprintf(stderr, "%s in.amr out.wav\n", argv[0]); + return 1; + } + +//+++/////////////////////////////////////////////// + +//lhc mp4 open 2/4 + inputFile = FileWrapper_Open(argv[1]); + if (inputFile == 0) { + fprintf(stderr, "Failed to open bitstream file %s\n", argv[1]); + return -1; + } else if (!FileWrapper_IsMp4File(inputFile)) { + fprintf(stderr, "Invalid input file %s\n", argv[1]); + return -2; + } else { + fprintf(stderr, "Input bitstream file:\t%s\n", argv[1]); + } + +//+++///////////////////////////////=========//// + + +//default + // ../encode-8k-1ch.amr ../decode-8k-1ch.wav + in = fopen(argv[1], "rb"); +//in = fopen("encode-8k-1ch.amr", "rb"); + if (!in) { + perror(argv[1]); + return 1; + } + + + //check the file format + n = fread(header, 1, 6, in); + if (n != 6 || memcmp(header, "#!AMR\n", 6)) { + fprintf(stderr, "Bad header\n"); + return 1; + } + + +//ready output file +// wav = wav_write_open("decode-8k-1ch.wav", 8000, 16, 1); + wav = wav_write_open(argv[2], 8000, 16, 1); + if (!wav) { + fprintf(stderr, "Unable to open %s\n", argv[2]); + return 1; + } + + + + //amr = Decoder_Interface_init(); + //Decoder_Interface_init(amrDecoder); + amr =Decoder_Interface_init(); + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + while (1) { + + uint8_t buffer[500], littleendian[320], *ptr; + int size, i; + int16_t outbuffer[160]; + + +//default read frame to buffer + /* Read the mode byte */ + n = fread(buffer, 1, 1, in); + if (n <= 0) + break; + + /* Find the packet size */ + size = sizes[(buffer[0] >> 3) & 0x0f]; + n = fread(buffer + 1, 1, size, in); + if (n != size) + break; +//default read data to buffer ============= + + + + /* Decode the packet */ + //Decoder_Interface_Decode(amr, buffer, outbuffer, 0); + //Decoder_Interface_Decode(amrDecoder, buffer, outbuffer, 0); + Decoder_Interface_Decode(amr, buffer, outbuffer, 0); + + /* Convert to little endian and write to wav */ + ptr = littleendian; + for (i = 0; i < 160; i++) { + *ptr++ = (outbuffer[i] >> 0) & 0xff; + *ptr++ = (outbuffer[i] >> 8) & 0xff; + } + + //lhc wave + wav_write_data(wav, littleendian, 320); + } + + ///++++++++++++++++++++++++++++++ + //lhc 3gp exit + + //default + fclose(in); + + + + + Decoder_Interface_exit(amr); + //Decoder_Interface_exit(amrDecoder); + + //free(amrDecoder); + //amrDecoder=NULL; + + + //lhc wave + wav_write_close(wav); + + fprintf(stderr, "Finished Decode \n"); + //getchar(); + return 0; +} + diff --git a/src/libs/opencore-amr/test/amrnb-enc-sine.c b/src/libs/opencore-amr/test/amrnb-enc-sine.c new file mode 100644 index 00000000..51c04b28 --- /dev/null +++ b/src/libs/opencore-amr/test/amrnb-enc-sine.c @@ -0,0 +1,59 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + int i, j; + void* amr; + FILE* out; + int sample_pos = 0; + + if (argc < 2) { + fprintf(stderr, "%s out.amr\n", argv[0]); + return 1; + } + + amr = Encoder_Interface_init(0); + out = fopen(argv[1], "wb"); + if (!out) { + perror(argv[1]); + return 1; + } + + fwrite("#!AMR\n", 1, 6, out); + for (i = 0; i < 1000; i++) { + short buf[160]; + uint8_t outbuf[500]; + int n; + for (j = 0; j < 160; j++) { + buf[j] = 32767*sin(440*2*3.141592654*sample_pos/8000); + sample_pos++; + } + n = Encoder_Interface_Encode(amr, MR475, buf, outbuf, 0); + fwrite(outbuf, 1, n, out); + } + fclose(out); + Encoder_Interface_exit(amr); + + return 0; +} + diff --git a/src/libs/opencore-amr/test/amrnb-enc.c b/src/libs/opencore-amr/test/amrnb-enc.c new file mode 100644 index 00000000..6ecd9dbe --- /dev/null +++ b/src/libs/opencore-amr/test/amrnb-enc.c @@ -0,0 +1,218 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +//use: xx -r 12200 -d ../test-8k-1ch.amr ../encode-8k-1ch-MR122-dtx.wav +//use: xx -r 12200 ../test-8k-1ch.amr ../encode-8k-1ch.wav + +#include +#include +#include +//#include +#include + + +#include "wavreader.h" + +#define DISABLE_AMRNB_DECODER + +void usage(const char* name) { + fprintf(stderr, "%s [-r bitrate] [-d] in.wav out.amr\n", name); +} + +enum Mode findMode(const char* str) { + struct { + enum Mode mode; + int rate; + } modes[] = { + { MR475, 4750 }, + { MR515, 5150 }, + { MR59, 5900 }, + { MR67, 6700 }, + { MR74, 7400 }, + { MR795, 7950 }, + { MR102, 10200 }, + { MR122, 12200 } + }; + int rate = atoi(str); + int closest = -1; + int closestdiff = 0; + unsigned int i; + + for (i = 0; i < sizeof(modes)/sizeof(modes[0]); i++) { + if (modes[i].rate == rate) + return modes[i].mode; + if (closest < 0 || closestdiff > abs(modes[i].rate - rate)) { + closest = i; + closestdiff = abs(modes[i].rate - rate); + } + } + fprintf(stderr, "Using bitrate %d\n", modes[closest].rate); + return modes[closest].mode; +} + +int main(int argc, char *argv[]) { + + //enum Mode optarg = MR122; + enum Mode mode = MR122; + + char *setMode = "12200"; + + int ch, dtx = 0; + int optind=3; + + const char *infile, *outfile; + + FILE *out; + void *wav; + // *amr; + + + + + int format=1; + int sampleRate=8000; + int channels= 1; + int bitsPerSample=16; + + int inputSize; + + uint8_t* inputBuf; + + //struct encoder_state* amr = (struct encoder_state*) malloc(sizeof(struct encoder_state)); + void* amr; + + fprintf(stderr, "AMR-NB Encode .wav file to .amr\n"); + + while ((ch = getopt(argc, argv, "r:d")) != -1) { + switch (ch) { + case 'r': + //mode = findMode(optarg); + mode = findMode(argv[2]); + + break; + case 'd': + dtx = 1; + optind=4; + break; + case '?': + default: + usage(argv[0]); + return 1; + } + } + + if (argc - optind < 2) { + usage(argv[0]); + return 1; + } + + infile = argv[optind]; + outfile = argv[optind+1]; + + wav = wav_read_open(infile); + + if (!wav) { + fprintf(stderr, "Unable to open wav file %s\n", infile); + return 1; + } + if (!wav_get_header(wav, &format, &channels, &sampleRate, &bitsPerSample, NULL)) { + fprintf(stderr, "Bad wav file %s\n", infile); + return 1; + } + if (format != 1) { + fprintf(stderr, "Unsupported WAV format %d\n", format); + return 1; + } + if (bitsPerSample != 16) { + fprintf(stderr, "Unsupported WAV sample depth %d\n", bitsPerSample); + return 1; + } + if (channels != 1) + fprintf(stderr, "Warning, only compressing one audio channel\n"); + if (sampleRate != 8000) + fprintf(stderr, "Warning, AMR-NB uses 8000 Hz sample rate (WAV file has %d Hz)\n", sampleRate); + + inputSize = channels*2*160; + inputBuf = (uint8_t*) malloc(inputSize); + + amr = Encoder_Interface_init(dtx); + + //work + // Encoder_Interface_init(amr,dtx); + + + //amr default + out = fopen(outfile, "wb"); + if (!out) { + perror(outfile); + return 1; + } + + + fwrite("#!AMR\n", 1, 6, out); + + while (1) { + short buf[160]; + uint8_t outbuf[500]; + int read, i, n; + + + read = wav_read_data(wav, inputBuf, inputSize); + + read /= channels; + read /= 2; + + if (read < 160) + break; + for (i = 0; i < 160; i++) { + const uint8_t* in = &inputBuf[2*channels*i]; + buf[i] = in[0] | (in[1] << 8); + } + + n = Encoder_Interface_Encode(amr, mode, buf, outbuf, 0); + + //lhc mp4 write + + + //default + fwrite(outbuf, 1, n, out); + + + }//end while + + + free(inputBuf); + + + //lhc mp4 5/5 WriteMP4File CloseMP4File + //lhc mp4 5/5 end + + + fclose(out); + + + Encoder_Interface_exit(amr); + + + //close input file + wav_read_close(wav); + + fprintf(stderr, "Finished Encode\n"); + //getchar(); + return 0; +} + diff --git a/src/libs/opencore-amr/test/amrwb-dec.c b/src/libs/opencore-amr/test/amrwb-dec.c new file mode 100644 index 00000000..7a121e80 --- /dev/null +++ b/src/libs/opencore-amr/test/amrwb-dec.c @@ -0,0 +1,87 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#include +#include +#include +#include "wavwriter.h" +#include + +/* From pvamrwbdecoder_api.h, by dividing by 8 and rounding up */ +const int sizes[] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, -1, 0 }; + +int main(int argc, char *argv[]) { + FILE* in; + char header[9]; + int n; + void *wav, *amr; + if (argc < 3) { + fprintf(stderr, "%s in.amr out.wav\n", argv[0]); + return 1; + } + + in = fopen(argv[1], "rb"); + if (!in) { + perror(argv[1]); + return 1; + } + n = fread(header, 1, 9, in); + if (n != 9 || memcmp(header, "#!AMR-WB\n", 9)) { + fprintf(stderr, "Bad header\n"); + return 1; + } + + wav = wav_write_open(argv[2], 16000, 16, 1); + if (!wav) { + fprintf(stderr, "Unable to open %s\n", argv[2]); + return 1; + } + amr = D_IF_init(); + while (1) { + uint8_t buffer[500], littleendian[640], *ptr; + int size, i; + int16_t outbuffer[320]; + /* Read the mode byte */ + n = fread(buffer, 1, 1, in); + if (n <= 0) + break; + /* Find the packet size */ + size = sizes[(buffer[0] >> 3) & 0x0f]; + if (size < 0) + break; + n = fread(buffer + 1, 1, size, in); + if (n != size) + break; + + /* Decode the packet */ + D_IF_decode(amr, buffer, outbuffer, 0); + + /* Convert to little endian and write to wav */ + ptr = littleendian; + for (i = 0; i < 320; i++) { + *ptr++ = (outbuffer[i] >> 0) & 0xff; + *ptr++ = (outbuffer[i] >> 8) & 0xff; + } + wav_write_data(wav, littleendian, 640); + } + fclose(in); + D_IF_exit(amr); + wav_write_close(wav); + return 0; +} + diff --git a/src/libs/opencore-amr/test/getopt.c b/src/libs/opencore-amr/test/getopt.c new file mode 100644 index 00000000..dae9d273 --- /dev/null +++ b/src/libs/opencore-amr/test/getopt.c @@ -0,0 +1,74 @@ + +//getopt.cļ룺 +/* got this off net.sources */ +#include +#include +#include "getopt.h" + +/* + * get option letter from argument vector + */ +int + opterr = 1, // should error messages be printed? + optind = 1, // index into parent argv vector + optopt; // character checked for validity +char *optarg; // argument associated with option + +#define EMSG "" +char *progname; // may also be defined elsewhere + +static void error(char *pch) +{ + if (!opterr) { + return; // without printing + } + fprintf(stderr, "%s: %s: %c\n", + (NULL != progname) ? progname : "getopt", pch, optopt); +} + +int getopt(int argc, char **argv, char *ostr) +{ + static char *place = EMSG; /* option letter processing */ + register char *oli; /* option letter list index */ + if (!*place) { + // update scanning pointer + if (optind >= argc || *(place = argv[optind]) != '-' || !*++place) { + return EOF; + } + if (*place == '-') { + // found "--" + ++optind; + return EOF; + } + } + /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' + || !(oli = strchr(ostr, optopt))) { + if (!*place) { + ++optind; + } + error("illegal option"); + return BADCH; + } + if (*++oli != ':') { + /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } else { + /* need an argument */ + if (*place) { + optarg = place; /* no white space */ + } else if (argc <= ++optind) { + /* no arg */ + place = EMSG; + error("option requires an argument"); + return BADCH; + } else { + optarg = argv[optind]; /* white space */ + } + place = EMSG; + ++optind; + } + return optopt; // return option letter +} diff --git a/src/libs/opencore-amr/test/getopt.h b/src/libs/opencore-amr/test/getopt.h new file mode 100644 index 00000000..0fe6019b --- /dev/null +++ b/src/libs/opencore-amr/test/getopt.h @@ -0,0 +1,11 @@ +//getopt.hļ룺 +#ifndef _GETOPT_ +#define _GETOPT_ +int getopt(int argc, char **argv, char *optstring); +extern char *optarg; // returned arg to go with this option +extern int optind; // index to next argv element to process +extern int opterr; // should error messages be printed? +extern int optopt; // +#define BADCH ('?') +#endif // _GETOPT + diff --git a/src/libs/opencore-amr/test/linkboth.c b/src/libs/opencore-amr/test/linkboth.c new file mode 100644 index 00000000..26a3f357 --- /dev/null +++ b/src/libs/opencore-amr/test/linkboth.c @@ -0,0 +1,39 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { +#ifndef DISABLE_AMRNB_DECODER + void* amrnb = Decoder_Interface_init(); + Decoder_Interface_exit(amrnb); +#endif +#ifndef DISABLE_AMRNB_ENCODER + void* amrnb_enc = Encoder_Interface_init(0); + Encoder_Interface_exit(amrnb_enc); +#endif + void* amrwb = D_IF_init(); + D_IF_exit(amrwb); + return 0; +} + diff --git a/src/libs/opencore-amr/test/unistd.h b/src/libs/opencore-amr/test/unistd.h new file mode 100644 index 00000000..c746bbb1 --- /dev/null +++ b/src/libs/opencore-amr/test/unistd.h @@ -0,0 +1,11 @@ +/** This file is part of the Mingw32 package. +* unistd.h maps (roughly) to io.h +*/ + +#ifndef _UNISTD_H +#define _UNISTD_H + +#include +#include + +#endif /* _UNISTD_H */ \ No newline at end of file diff --git a/src/libs/opencore-amr/test/wavreader.c b/src/libs/opencore-amr/test/wavreader.c new file mode 100644 index 00000000..55d2ab9e --- /dev/null +++ b/src/libs/opencore-amr/test/wavreader.c @@ -0,0 +1,162 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#include "wavreader.h" +#include +#include +#include +#include + +#define TAG(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) + +struct wav_reader { + FILE *wav; + uint32_t data_length; + + int format; + int sample_rate; + int bits_per_sample; + int channels; + int byte_rate; + int block_align; +}; + +static uint32_t read_tag(struct wav_reader* wr) { + uint32_t tag = 0; + tag = (tag << 8) | fgetc(wr->wav); + tag = (tag << 8) | fgetc(wr->wav); + tag = (tag << 8) | fgetc(wr->wav); + tag = (tag << 8) | fgetc(wr->wav); + return tag; +} + +static uint32_t read_int32(struct wav_reader* wr) { + uint32_t value = 0; + value |= fgetc(wr->wav) << 0; + value |= fgetc(wr->wav) << 8; + value |= fgetc(wr->wav) << 16; + value |= fgetc(wr->wav) << 24; + return value; +} + +static uint16_t read_int16(struct wav_reader* wr) { + uint16_t value = 0; + value |= fgetc(wr->wav) << 0; + value |= fgetc(wr->wav) << 8; + return value; +} + +void* wav_read_open(const char *filename) { + struct wav_reader* wr = (struct wav_reader*) malloc(sizeof(*wr)); + long data_pos = 0; + memset(wr, 0, sizeof(*wr)); + + wr->wav = fopen(filename, "rb"); + if (wr->wav == NULL) { + free(wr); + return NULL; + } + + while (1) { + uint32_t tag, tag2, length; + tag = read_tag(wr); + if (feof(wr->wav)) + break; + length = read_int32(wr); + if (tag != TAG('R', 'I', 'F', 'F') || length < 4) { + fseek(wr->wav, length, SEEK_CUR); + continue; + } + tag2 = read_tag(wr); + length -= 4; + if (tag2 != TAG('W', 'A', 'V', 'E')) { + fseek(wr->wav, length, SEEK_CUR); + continue; + } + // RIFF chunk found, iterate through it + while (length >= 8) { + uint32_t subtag, sublength; + subtag = read_tag(wr); + if (feof(wr->wav)) + break; + sublength = read_int32(wr); + length -= 8; + if (length < sublength) + break; + if (subtag == TAG('f', 'm', 't', ' ')) { + if (sublength < 16) { + // Insufficient data for 'fmt ' + break; + } + wr->format = read_int16(wr); + wr->channels = read_int16(wr); + wr->sample_rate = read_int32(wr); + wr->byte_rate = read_int32(wr); + wr->block_align = read_int16(wr); + wr->bits_per_sample = read_int16(wr); + } else if (subtag == TAG('d', 'a', 't', 'a')) { + data_pos = ftell(wr->wav); + wr->data_length = sublength; + fseek(wr->wav, sublength, SEEK_CUR); + } else { + fseek(wr->wav, sublength, SEEK_CUR); + } + length -= sublength; + } + if (length > 0) { + // Bad chunk? + fseek(wr->wav, length, SEEK_CUR); + } + } + fseek(wr->wav, data_pos, SEEK_SET); + return wr; +} + +void wav_read_close(void* obj) { + struct wav_reader* wr = (struct wav_reader*) obj; + fclose(wr->wav); + free(wr); +} + +int wav_get_header(void* obj, int* format, int* channels, int* sample_rate, int* bits_per_sample, unsigned int* data_length) { + struct wav_reader* wr = (struct wav_reader*) obj; + if (format) + *format = wr->format; + if (channels) + *channels = wr->channels; + if (sample_rate) + *sample_rate = wr->sample_rate; + if (bits_per_sample) + *bits_per_sample = wr->bits_per_sample; + if (data_length) + *data_length = wr->data_length; + return wr->format && wr->sample_rate; +} + +int wav_read_data(void* obj, unsigned char* data, unsigned int length) { + struct wav_reader* wr = (struct wav_reader*) obj; + int n; + if (wr->wav == NULL) + return -1; + if (length > wr->data_length) + length = wr->data_length; + n = fread(data, 1, length, wr->wav); + wr->data_length -= length; + return n; +} + diff --git a/src/libs/opencore-amr/test/wavreader.h b/src/libs/opencore-amr/test/wavreader.h new file mode 100644 index 00000000..57a13ffb --- /dev/null +++ b/src/libs/opencore-amr/test/wavreader.h @@ -0,0 +1,37 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#ifndef WAVREADER_H +#define WAVREADER_H + +#ifdef __cplusplus +extern "C" { +#endif + +void* wav_read_open(const char *filename); +void wav_read_close(void* obj); + +int wav_get_header(void* obj, int* format, int* channels, int* sample_rate, int* bits_per_sample, unsigned int* data_length); +int wav_read_data(void* obj, unsigned char* data, unsigned int length); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/libs/opencore-amr/test/wavwriter.c b/src/libs/opencore-amr/test/wavwriter.c new file mode 100644 index 00000000..0951cac3 --- /dev/null +++ b/src/libs/opencore-amr/test/wavwriter.c @@ -0,0 +1,111 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#include "wavwriter.h" +#include +#include +#include +#include + +struct wav_writer { + FILE *wav; + int data_length; + + int sample_rate; + int bits_per_sample; + int channels; +}; + +static void write_string(struct wav_writer* ww, const char *str) { + fputc(str[0], ww->wav); + fputc(str[1], ww->wav); + fputc(str[2], ww->wav); + fputc(str[3], ww->wav); +} + +static void write_int32(struct wav_writer* ww, int value) { + fputc((value >> 0) & 0xff, ww->wav); + fputc((value >> 8) & 0xff, ww->wav); + fputc((value >> 16) & 0xff, ww->wav); + fputc((value >> 24) & 0xff, ww->wav); +} + +static void write_int16(struct wav_writer* ww, int value) { + fputc((value >> 0) & 0xff, ww->wav); + fputc((value >> 8) & 0xff, ww->wav); +} + +static void write_header(struct wav_writer* ww, int length) { + int bytes_per_frame, bytes_per_sec; + write_string(ww, "RIFF"); + write_int32(ww, 4 + 8 + 16 + 8 + length); + write_string(ww, "WAVE"); + + write_string(ww, "fmt "); + write_int32(ww, 16); + + bytes_per_frame = ww->bits_per_sample/8*ww->channels; + bytes_per_sec = bytes_per_frame*ww->sample_rate; + write_int16(ww, 1); // Format + write_int16(ww, ww->channels); // Channels + write_int32(ww, ww->sample_rate); // Samplerate + write_int32(ww, bytes_per_sec); // Bytes per sec + write_int16(ww, bytes_per_frame); // Bytes per frame + write_int16(ww, ww->bits_per_sample); // Bits per sample + + write_string(ww, "data"); + write_int32(ww, length); +} + +void* wav_write_open(const char *filename, int sample_rate, int bits_per_sample, int channels) { + struct wav_writer* ww = (struct wav_writer*) malloc(sizeof(*ww)); + memset(ww, 0, sizeof(*ww)); + ww->wav = fopen(filename, "wb"); + if (ww->wav == NULL) { + free(ww); + return NULL; + } + ww->data_length = 0; + ww->sample_rate = sample_rate; + ww->bits_per_sample = bits_per_sample; + ww->channels = channels; + + write_header(ww, ww->data_length); + return ww; +} + +void wav_write_close(void* obj) { + struct wav_writer* ww = (struct wav_writer*) obj; + if (ww->wav == NULL) { + free(ww); + return; + } + fseek(ww->wav, 0, SEEK_SET); + write_header(ww, ww->data_length); + fclose(ww->wav); + free(ww); +} + +void wav_write_data(void* obj, char* data, int length) { + struct wav_writer* ww = (struct wav_writer*) obj; + if (ww->wav == NULL) + return; + fwrite(data, length, 1, ww->wav); + ww->data_length += length; +} + diff --git a/src/libs/opencore-amr/test/wavwriter.h b/src/libs/opencore-amr/test/wavwriter.h new file mode 100644 index 00000000..f76ce0b7 --- /dev/null +++ b/src/libs/opencore-amr/test/wavwriter.h @@ -0,0 +1,36 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#ifndef WAVWRITER_H +#define WAVWRITER_H + +#ifdef __cplusplus +extern "C" { +#endif + +void* wav_write_open(const char *filename, int sample_rate, int bits_per_sample, int channels); +void wav_write_close(void* obj); + +void wav_write_data(void* obj, char* data, int length); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/libs/resiprocate/CMakeLists.txt b/src/libs/resiprocate/CMakeLists.txt new file mode 100644 index 00000000..c7901c90 --- /dev/null +++ b/src/libs/resiprocate/CMakeLists.txt @@ -0,0 +1,308 @@ +project (resiprocate) + +# Rely on C++ 11 +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +set (ARES_SOURCES + contrib/ares/ares_timeout.c + contrib/ares/ares_strerror.c + contrib/ares/ares_send.c + contrib/ares/ares_search.c + contrib/ares/ares_query.c + contrib/ares/ares_process.c + contrib/ares/ares_parse_ptr_reply.c + contrib/ares/ares_parse_a_reply.c + contrib/ares/ares_mkquery.c + contrib/ares/ares_local.c + contrib/ares/ares_init.c + contrib/ares/ares_gethostbyname.c + contrib/ares/ares_gethostbyaddr.c + contrib/ares/ares_free_string.c + contrib/ares/ares_free_hostent.c + contrib/ares/ares_free_errmem.c + contrib/ares/ares_fds.c + contrib/ares/ares_expand_name.c + contrib/ares/ares_destroy.c + contrib/ares/ares__read_line.c + contrib/ares/ares__get_hostent.c + contrib/ares/ares__close_sockets.c +) + +set (STACK_SOURCES + resip/stack/Compression.cxx + resip/stack/CallId.cxx + resip/stack/BranchParameter.cxx + resip/stack/BasicNonceHelper.cxx + resip/stack/Auth.cxx + resip/stack/ApplicationSip.cxx + resip/stack/ApiCheck.cxx + resip/stack/Aor.cxx + resip/stack/DateCategory.cxx + resip/stack/DataParameter.cxx + resip/stack/CSeqCategory.cxx + resip/stack/CpimContents.cxx + resip/stack/ContentsFactoryBase.cxx + resip/stack/Contents.cxx + resip/stack/ConnectionManager.cxx + resip/stack/ConnectionBase.cxx + resip/stack/Connection.cxx + resip/stack/DnsResult.cxx + resip/stack/DnsInterface.cxx + resip/stack/DeprecatedDialog.cxx + resip/stack/GenericUri.cxx + resip/stack/GenericContents.cxx + resip/stack/FloatParameter.cxx + resip/stack/ExternalBodyContents.cxx + resip/stack/ExtensionParameter.cxx + resip/stack/ExtensionHeader.cxx + resip/stack/ExpiresCategory.cxx + resip/stack/ExistsParameter.cxx + resip/stack/ExistsOrDataParameter.cxx + resip/stack/EventStackThread.cxx + resip/stack/Embedded.cxx + resip/stack/DtlsMessage.cxx + resip/stack/HeaderHash.cxx + resip/stack/HeaderFieldValueList.cxx + resip/stack/HeaderFieldValue.cxx + resip/stack/MsgHeaderScanner.cxx + resip/stack/Mime.cxx + resip/stack/MethodTypes.cxx + resip/stack/MethodHash.cxx + resip/stack/MessageWaitingContents.cxx + resip/stack/MessageFilterRule.cxx + resip/stack/Message.cxx + resip/stack/LazyParser.cxx + resip/stack/KeepAliveMessage.cxx + resip/stack/InvalidContents.cxx + resip/stack/InterruptableStackThread.cxx + resip/stack/InteropHelper.cxx + resip/stack/InternalTransport.cxx + resip/stack/IntegerParameter.cxx + resip/stack/IntegerCategory.cxx + resip/stack/Helper.cxx + resip/stack/HeaderTypes.cxx + resip/stack/Headers.cxx + resip/stack/ParameterHash.cxx + resip/stack/Parameter.cxx + resip/stack/OctetContents.cxx + resip/stack/NonceHelper.cxx + resip/stack/NameAddr.cxx + resip/stack/MultipartSignedContents.cxx + resip/stack/MultipartRelatedContents.cxx + resip/stack/MultipartMixedContents.cxx + resip/stack/MultipartAlternativeContents.cxx + resip/stack/SipStack.cxx + resip/stack/SipMessage.cxx + resip/stack/SipFrag.cxx + resip/stack/SERNonceHelper.cxx + resip/stack/SecurityAttributes.cxx + resip/stack/SdpContents.cxx + resip/stack/RportParameter.cxx + resip/stack/Rlmi.cxx + resip/stack/RequestLine.cxx + resip/stack/RAckCategory.cxx + resip/stack/QValueParameter.cxx + resip/stack/QValue.cxx + resip/stack/QuotedDataParameter.cxx + resip/stack/PrivacyCategory.cxx + resip/stack/PlainContents.cxx + resip/stack/Pkcs8Contents.cxx + resip/stack/Pkcs7Contents.cxx + resip/stack/Pidf.cxx + resip/stack/ParserContainerBase.cxx + resip/stack/ParserCategory.cxx + resip/stack/ParserCategories.cxx + resip/stack/ParameterTypes.cxx + resip/stack/X509Contents.cxx + resip/stack/WarningCategory.cxx + resip/stack/Via.cxx + resip/stack/Uri.cxx + resip/stack/UnknownParameter.cxx + resip/stack/UInt32Parameter.cxx + resip/stack/UInt32Category.cxx + resip/stack/UdpTransport.cxx + resip/stack/TuSelector.cxx + resip/stack/TupleMarkManager.cxx + resip/stack/Tuple.cxx + resip/stack/TuIM.cxx + resip/stack/TransportThread.cxx + resip/stack/TransportSelector.cxx + resip/stack/TransportFailure.cxx + resip/stack/Transport.cxx + resip/stack/TransactionUserMessage.cxx + resip/stack/TransactionUser.cxx + resip/stack/TransactionState.cxx + resip/stack/TransactionMap.cxx + resip/stack/TransactionController.cxx + resip/stack/Token.cxx + resip/stack/TimerQueue.cxx + resip/stack/TimerMessage.cxx + resip/stack/TimeAccumulate.cxx + resip/stack/TcpTransport.cxx + resip/stack/TcpConnection.cxx + resip/stack/TcpBaseTransport.cxx + resip/stack/Symbols.cxx + resip/stack/StringCategory.cxx + resip/stack/StatusLine.cxx + resip/stack/StatisticsMessage.cxx + resip/stack/StatisticsManager.cxx + resip/stack/StatisticsHandler.cxx + resip/stack/StatelessHandler.cxx + resip/stack/StackThread.cxx + resip/stack/ssl/Security.cxx + resip/stack/ssl/MacSecurity.cxx + resip/stack/ssl/WinSecurity.cxx + resip/stack/ssl/TlsConnection.cxx + resip/stack/ssl/TlsTransport.cxx + ) + +set (DUM_SOURCES + resip/dum/DialogUsageManager.cxx + resip/dum/DialogUsage.cxx + resip/dum/DialogSetId.cxx + resip/dum/DialogSet.cxx + resip/dum/DialogId.cxx + resip/dum/DialogEventStateManager.cxx + resip/dum/DialogEventInfo.cxx + resip/dum/Dialog.cxx + resip/dum/DestroyUsage.cxx + resip/dum/DefaultServerReferHandler.cxx + resip/dum/ContactInstanceRecord.cxx + resip/dum/ClientSubscription.cxx + resip/dum/ClientRegistration.cxx + resip/dum/ClientPublication.cxx + resip/dum/ClientPagerMessage.cxx + resip/dum/ClientOutOfDialogReq.cxx + resip/dum/ClientInviteSession.cxx + resip/dum/ClientAuthManager.cxx + resip/dum/ClientAuthExtension.cxx + resip/dum/ChallengeInfo.cxx + resip/dum/CertMessage.cxx + resip/dum/BaseUsage.cxx + resip/dum/BaseSubscription.cxx + resip/dum/BaseCreator.cxx + resip/dum/AppDialogSetFactory.cxx + resip/dum/AppDialogSet.cxx + resip/dum/AppDialog.cxx + resip/dum/KeepAliveTimeout.cxx + resip/dum/KeepAliveManager.cxx + resip/dum/InviteSessionHandler.cxx + resip/dum/InviteSessionCreator.cxx + resip/dum/InviteSession.cxx + resip/dum/InMemorySyncRegDb.cxx + resip/dum/InMemoryRegistrationDatabase.cxx + resip/dum/IdentityHandler.cxx + resip/dum/HttpProvider.cxx + resip/dum/HttpGetMessage.cxx + resip/dum/HandleManager.cxx + resip/dum/HandleException.cxx + resip/dum/Handled.cxx + resip/dum/Handle.cxx + resip/dum/EncryptionRequest.cxx + resip/dum/DumTimeout.cxx + resip/dum/DumThread.cxx + resip/dum/DumProcessHandler.cxx + resip/dum/DumHelper.cxx + resip/dum/DumFeatureMessage.cxx + resip/dum/DumFeatureChain.cxx + resip/dum/DumFeature.cxx + resip/dum/DumDecrypted.cxx + resip/dum/ServerSubscription.cxx + resip/dum/ServerRegistration.cxx + resip/dum/ServerPublication.cxx + resip/dum/ServerPagerMessage.cxx + resip/dum/ServerOutOfDialogReq.cxx + resip/dum/ServerInviteSession.cxx + resip/dum/ServerAuthManager.cxx + resip/dum/RegistrationHandler.cxx + resip/dum/RegistrationCreator.cxx + resip/dum/RedirectManager.cxx + resip/dum/RADIUSServerAuthManager.cxx + resip/dum/PublicationCreator.cxx + resip/dum/Profile.cxx + resip/dum/PagerMessageCreator.cxx + resip/dum/OutOfDialogReqCreator.cxx + resip/dum/OutgoingEvent.cxx + resip/dum/NonDialogUsage.cxx + resip/dum/NetworkAssociation.cxx + resip/dum/MergedRequestRemovalCommand.cxx + resip/dum/MergedRequestKey.cxx + resip/dum/MasterProfile.cxx + resip/dum/UserProfile.cxx + resip/dum/UserAuthInfo.cxx + resip/dum/TlsPeerAuthManager.cxx + resip/dum/TargetCommand.cxx + resip/dum/SubscriptionState.cxx + resip/dum/SubscriptionHandler.cxx + resip/dum/SubscriptionCreator.cxx + resip/dum/ssl/EncryptionManager.cxx + ) + +SET (RUTIL_SOURCES + rutil/FileSystem.cxx + rutil/FdPoll.cxx + rutil/DnsUtil.cxx + rutil/ssl/OpenSSLInit.cxx + rutil/ssl/SHA1Stream.cxx + rutil/dns/RRVip.cxx + rutil/dns/RROverlay.cxx + rutil/dns/RRList.cxx + rutil/dns/RRCache.cxx + rutil/dns/QueryTypes.cxx + rutil/dns/LocalDns.cxx + rutil/dns/ExternalDnsFactory.cxx + rutil/dns/DnsThread.cxx + rutil/dns/DnsStub.cxx + rutil/dns/DnsSrvRecord.cxx + rutil/dns/DnsResourceRecord.cxx + rutil/dns/DnsNaptrRecord.cxx + rutil/dns/DnsHostRecord.cxx + rutil/dns/DnsCnameRecord.cxx + rutil/dns/DnsAAAARecord.cxx + rutil/dns/AresDns.cxx + rutil/DataStream.cxx + rutil/Data.cxx + rutil/CountStream.cxx + rutil/ConfigParse.cxx + rutil/Condition.cxx + rutil/Coders.cxx + rutil/BaseException.cxx + rutil/AbstractFifo.cxx + rutil/XMLCursor.cxx + rutil/vmd5.cxx + rutil/TransportType.cxx + rutil/Timer.cxx + rutil/Time.cxx + rutil/ThreadIf.cxx + rutil/SysLogStream.cxx + rutil/SysLogBuf.cxx + rutil/Subsystem.cxx + rutil/stun/Udp.cxx + rutil/stun/Stun.cxx + rutil/Socket.cxx + rutil/ServerProcess.cxx + rutil/SelectInterruptor.cxx + rutil/RWMutex.cxx + rutil/resipfaststreams.cxx + rutil/RecursiveMutex.cxx + rutil/Random.cxx + rutil/RADIUSDigestAuthenticator.cxx + rutil/PoolBase.cxx + rutil/Poll.cxx + rutil/ParseException.cxx + rutil/ParseBuffer.cxx + rutil/Mutex.cxx + rutil/MD5Stream.cxx + rutil/Log.cxx + rutil/Lock.cxx + rutil/KeyValueStore.cxx + rutil/HeapInstanceCounter.cxx + rutil/GeneralCongestionManager.cxx + rutil/AtomicCounter.cxx + rutil/WinCompat.cxx + ) + + +add_library(resiprocate ${ARES_SOURCES} ${RUTIL_SOURCES} ${STACK_SOURCES} ${DUM_SOURCES}) +add_library(resiprocate_lite ${RUTIL_SOURCES} ${STACK_SOURCES}) diff --git a/src/libs/resiprocate/INSTALL b/src/libs/resiprocate/INSTALL new file mode 100644 index 00000000..b3902b86 --- /dev/null +++ b/src/libs/resiprocate/INSTALL @@ -0,0 +1,45 @@ +Quick guide to building the libraries and tests: +------------------------------------------------ + +1) ./configure + +By default, configure runs interactively, prompting for each configuration option. configure may be run in non-interactive mode by using a -y flag. Additionally, a -m flag may be used for menu-based configuration. + +2) make + +Notes: +- all binaries and object files will be placed in a subdirectory of the directory containing the source files. +- a symbolic link is made to any target executables in the directory where the main is +- If you configure --with-shared-libs, it will only build shared libraries so you will need to set LD_LIBRARY_PATH. (DYLD_LIBRARY_PATH under OS X) +e.g. BASH example on linux with debug libraries +export LD_LIBRARY_PATH=$(RESIP_PATH)/lib.debug.Linux.i686 + +e.g. tcsh example on linux with optimized libraries +setenv LD_LIBRARY_PATH $(RESIP_PATH)/lib.opt.Linux.i686 + +e.g. BASH example on an Intel Macintosh running OS X +export DYLD_LIBRARY_PATH=$(RESIP_PATH)/obj.debug.Darwin.i386 + +To build with distcc for distributed compilation (assume you have 4 hosts runing distccd) +See http://distcc.samba.org/ +% ./configure --with-distcc +% make -j 8 + + +Supported Systems +----------------- + +Supported Platforms: (to add new platform support see build/Makefile.osarch) +FreeBSD +Linux +QNX +SunOS +Mac +cygwin + +Supported toolchains: (to add new toolchain support see build/Makefile.tools) +gnu (g++) +Intel (icc) +ARM cross-compiler (arm-linux-g++) +Sunpro (CC) + diff --git a/src/libs/resiprocate/Makefile b/src/libs/resiprocate/Makefile new file mode 100644 index 00000000..917db61a --- /dev/null +++ b/src/libs/resiprocate/Makefile @@ -0,0 +1,350 @@ +BUILD = build +-include $(BUILD)/Makefile.conf +-include $(BUILD)/Makefile.all +-include $(BUILD)/Makefile.tools +-include $(BUILD)/Makefile.osarch + +DEFAULTS := +ifeq ($(BUILD_RECON), yes) +DEFAULTS += dtls-srtp-openssl +endif +DEFAULTS += stack +ifeq ($(BUILD_REPRO),yes) +DEFAULTS += repro +endif +ifeq ($(BUILD_RECON),yes) +DEFAULTS += recon +endif +ifeq ($(BUILD_RETURN_CLIENT),yes) +DEFAULTS += return-client +endif +ifeq ($(BUILD_RETURN_SERVER),yes) +DEFAULTS += return-server +endif +ifeq ($(BUILD_TFM),yes) +DEFAULTS += tfm +endif + +default: $(DEFAULTS) +#default: repro dum tests + +stack: dum tests + +all: repro dum tests tfm apps recon + +tfm: tfmcontrib + $(MAKE) -C tfm + +contrib: + +rutil: contrib + $(MAKE) -C rutil + +resiprocate: rutil + $(MAKE) -C resip/stack + +dum: resiprocate + $(MAKE) -C resip/dum + +b2bua: resiprocate + $(MAKE) -C b2bua + +repro: dum + $(MAKE) -C repro + +tests: resiprocate + $(MAKE) -C rutil/test + $(MAKE) -C resip/stack/test + $(MAKE) -C resip/dum/test + +check: tests + cd resip/stack/test && ./runtests.sh + cd rutil/test && ./runtests.sh + +presSvr: resiprocate + $(MAKE) -C presSvr + +apps: dum + $(MAKE) -C apps + +return: return-server return-client + +reTurn: return + +reTURN: return + +return-server: rutil + $(MAKE) -C reTurn + +return-client: rutil + $(MAKE) -C reTurn/client + $(MAKE) -C reTurn/client/test + +recon: dum reflow + $(MAKE) -C resip/recon + $(MAKE) -C resip/recon/test + +reflow: dtls-srtp-openssl return-client srtp + $(MAKE) -C reflow + +ifeq (${BUILD_SHARED_LIBS},no) + NETXX_USE_SHARED_LIBS=--disable-shared + CPPUNIT_USE_SHARED_LIBS=--enable-shared=false +endif + +configure_netxx: tfm/contrib/Netxx-0.3.2/Makefile + +tfm/contrib/Netxx-0.3.2/Makefile: + cd tfm/contrib/Netxx-0.3.2 && CXX="$(CXX)" CXXFLAGS='$(CXXFLAGS)' perl configure.pl --contrib --disable-examples ${NETXX_USE_SHARED_LIBS} + +ifeq ($(OSTYPE),MinGW) +netxx: + $(MAKE) -C tfm/contrib/Netxx-0.3.2 -f Makefile.MinGW +else +netxx: configure_netxx + $(MAKE) -C tfm/contrib/Netxx-0.3.2 +endif + +configure_cppunit: tfm/contrib/cppunit/Makefile + +tfm/contrib/cppunit/Makefile: + cd tfm/contrib/cppunit && CC="$(CC)" CFLAGS='$(CFLAGS)' CXX="$(CXX)" CXXFLAGS='$(CXXFLAGS)' ./configure ${CPPUNIT_USE_SHARED_LIBS} ${CONFIGURE_ARGS} --disable-doxygen + +cppunit: configure_cppunit + $(MAKE) -C tfm/contrib/cppunit/src/cppunit libcppunit.la + +contrib/srtp/Makefile: + cd contrib/srtp && ./configure ${CONFIGURE_ARGS} + +configure_srtp: contrib/srtp/Makefile + +srtp: configure_srtp + $(MAKE) -C contrib/srtp + +ifneq ($(SSL_LOCATION),) +$(SSL_LOCATION)/Makefile: + cd $(SSL_LOCATION) && ./Configure linux-generic32 --openssldir=/usr enable-tlsext ${CONFIGURE_ARGS} && $(MAKE) depend + +configure_dtls-srtp-openssl: $(SSL_LOCATION)/Makefile + +dtls-srtp-openssl: configure_dtls-srtp-openssl + $(MAKE) -C $(SSL_LOCATION) +else +dtls-srtp-openssl: +endif + +tfmcontrib: cppunit netxx + +########################################################################### +# Resiprocate Custom ares rules + +ifeq ($(DNS_RESOLVER),resip-ares) + +ifeq (${USE_IPV6},yes) + ARES_IPV6=--with-ipv6 +endif + +ifeq (${ARES_PREFIX},) + ARES_PREFIX_ARG= +else + ARES_PREFIX_ARG=--prefix=${ARES_PREFIX} +endif + +contrib/ares-build.$(OS_ARCH)/Makefile: + mkdir -p contrib/ares-build.$(OS_ARCH) + cd contrib/ares-build.$(OS_ARCH) && \ + ../ares/configure ${ARES_IPV6} ${ARES_PREFIX_ARG} ${CONFIGURE_ARGS} + +configure_ares: contrib/ares-build.$(OS_ARCH)/Makefile + +ares: configure_ares + $(MAKE) -C contrib/ares-build.$(OS_ARCH) + +contrib: ares + +install-ares: + $(MAKE) -C contrib/ares-build.$(OS_ARCH) install + +else +# Dummy rules to use when resip-ares is not being used +install-ares: +endif + +clean-ares: + -rm -Rf contrib/ares-build.* + +########################################################################### +# Various clean targets +CLEANDIRS := resip/stack resip/dum resip/dum/test resip/stack/test presSvr \ + repro rutil rutil/test tfm apps reTurn reTurn/client \ + reTurn/client/test p2p p2p/s2c/s2c reflow resip/recon resip/recon/test + + +cleancontrib: clean-ares + -$(MAKE) -C tfm/contrib/cppunit distclean + -$(MAKE) -C tfm/contrib/Netxx-0.3.2 realclean + find tfm/contrib/Netxx-0.3.2 -name 'Netxx-config' -exec rm -f '{}' \; + -$(MAKE) -C contrib/srtp superclean + -$(MAKE) -C contrib/srtp/crypto superclean + -$(MAKE) -C contrib/srtp/doc superclean + -$(MAKE) -C contrib/openssl clean + +clean: cleanpkg + for dir in $(CLEANDIRS); do $(MAKE) -C $$dir clean; done ; true + +cleanall: cleancontrib + for dir in $(CLEANDIRS); do $(MAKE) -C $$dir cleanall; done ; true + +superclean: cleancontrib cleanpkg + for dir in $(CLEANDIRS); do $(MAKE) -C $$dir distclean; done ; true + find * -name '*.db' -exec rm -f '{}' \; + -rm -Rf .make_prefs + -rm -f SVN-VERSION + -rm -Rf lib.*.* + +distclean: superclean + -rm -Rf build/Makefile.conf + +########################################################################### +install: install-ares install-rutil install-resip install-dum + +install-rutil: + $(MAKE) -C rutil install + +install-resip: + $(MAKE) -C resip/stack install + +install-dum: + $(MAKE) -C resip/dum install + +install-repro: + $(MAKE) -C repro install + +install-recon: install install-reflow install-returnclient + $(MAKE) -C resip/recon install + +install-reflow: + $(MAKE) -C reflow install + +install-returnclient: + $(MAKE) -C reTurn/client install + +SVN-VERSION: + @if test -d .svn ; \ + then \ + echo "Generating SVN-VERSION from svnversion"; \ + svnversion . \ + | perl -p \ + -e 'm /(\d+)/ && do { $$padded=sprintf( "%06d", $$1 ); s/\d+/$$padded/; };' \ + -e 's/:/./; s/M/.M/;' \ + > SVN-VERSION ; \ + elif test -r SVN-EXPORT-VERSION ; \ + then \ + echo "Copying SVN-VERSION from SVN-EXPORT-VERSION"; \ + cp SVN-EXPORT-VERSION SVN-VERSION ; \ + else \ + echo "Unknown SVN-VERSION"; \ + echo '0' > SVN-VERSION ; \ + fi + @echo -n "SVN-VERSION=" ; cat SVN-VERSION; echo "" + +REPRO_VERSION = $(shell cat repro/VERSION) + +RPMBUILD_TOPDIR = $(shell pwd)/rpm +repro-rpm: repro-dist rpmbuild-area + rpmbuild -ta \ + --define="buildno $(shell cat SVN-VERSION)" \ + --define="_topdir $(RPMBUILD_TOPDIR)" \ + repro-$(REPRO_VERSION).tar.gz + ls -l $(RPMBUILD_TOPDIR)/SRPMS/repro-$(REPRO_VERSION)-*.rpm + ls -l $(RPMBUILD_TOPDIR)/RPMS/*/repro*-$(REPRO_VERSION)-*.rpm + +RPMBUILD_SUBDIRS = BUILD RPMS SOURCES SPECS SRPMS +rpmbuild-area: $(foreach subdir,$(RPMBUILD_SUBDIRS),$(RPMBUILD_TOPDIR)/$(subdir)) + +$(RPMBUILD_TOPDIR) : + test -d $(RPMBUILD_TOPDIR) || mkdir $(RPMBUILD_TOPDIR) + +$(foreach subdir,$(RPMBUILD_SUBDIRS),$(RPMBUILD_TOPDIR)/$(subdir)) : $(RPMBUILD_TOPDIR) + test -d $@ || mkdir $@ + +repro-dist: cleanpkg repro-$(REPRO_VERSION).tar.gz repro-$(REPRO_VERSION).tar.gz.md5 + +tmptarfile=/tmp/repro.tar.gz.$$ +repro-$(REPRO_VERSION).tar.gz: SVN-VERSION repro.spec + rm -f repro-$(REPRO_VERSION) + ln -s . repro-$(REPRO_VERSION) + find repro-$(REPRO_VERSION)/ \( -name .svn -prune -o -type f -print0 \) \ + | tar -c -f $(tmptarfile) -z --null -h -T - + mv $(tmptarfile) $@ + rm -f repro-$(REPRO_VERSION) + +repro-$(REPRO_VERSION).tar.gz.md5: repro-$(REPRO_VERSION).tar.gz + md5sum repro-$(REPRO_VERSION).tar.gz > repro-$(REPRO_VERSION).tar.gz.md5 + +repro.spec: repro/repro.spec + $(MAKE) -C repro repro.spec.inst + mv repro/repro.spec.inst repro.spec + +cleanpkg: + rm -f repro-*.tar.gz repro-*.tar.gz.md5 repro-*.rpm + rm -rf rpm repro-$(REPRO_VERSION) + +# If the make configuration isn't there, create a default one. +$(BUILD)/Makefile.conf: + ./configure -y + +.PHONY: resiprocate tests contrib ares srtp dtls-srtp-openssl +.PHONY: install install-ares install-rutil install-resip install-repro install-dum install-reflow install-returnclient install-recon +.PHONY: SVN-VERSION repro-rpm repro-dist cleanpkg rpmbuild-area +.PHONY: repro dum tests tfm tfmcontrib contrib rutil check presSvr + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# . +# +############################################################################## diff --git a/src/libs/resiprocate/README b/src/libs/resiprocate/README new file mode 100644 index 00000000..1b50741a --- /dev/null +++ b/src/libs/resiprocate/README @@ -0,0 +1,88 @@ +The reSIProcate build system is derived from the VOCAL build system (http://www.vovida.org). + +Adding New Files to a module +---------------------------- + +Example: Adding a new file Foo.cxx to the stack + +1) Edit resip/stack/Makefile +2) Add Foo.cxx to the SRC list + +Example: Adding a new file Bar.cxx to rutil +1) Edit rutil/Makefile +2) Add Bar.cxx to the SRC list + +Notes: +- All files noted in SRC list will be added to the target library +- Adding a new header file does not need to be noted in the Makefile +- To add something to the compile line add to CXXFLAGS. +e.g. CXXFLAGS += -DMYSPECIALDEFINE +- To add something to the link line add to LDFLAGS and/or LDLIBS +e.g. LDFLAGS += -L/usr/local/myspeciallibdir +e.g. LDLIBS += -lmyspeciallib + + +Creating an application based on the stack: + +Option 1: (Using the resip build system) +For example applications using the resip build system look at resip/stack/test or at repro. + +########################################################################################### +# Create a Makefile in the directory with the units with the following template +# This should be the path to the build directory of resip (in the sip subdirectory) +BUILD = ../../build + +# Includes macros +include $(BUILD)/Makefile.pre + +# Add any options that need to be passed to the C++ compiler here +#CXXFLAGS += -DMYSPECIALDEFINE + +# Add any options that need to be passed to the C compiler here +#CFLAGS += -DMYOTHERDEFINE + +# Add any options that need to be passed to the linker here +#LDFLAGS += -L/usr/local/mydir + +# Add any libraries that need to be passed to the linker here +#LDLIBS += -lmylib + +# All of these packages are prerequisites for resiprocate +PACKAGES += RESIP RUTIL OPENSSL ARES PTHREAD + +# Add an entry to TESTPROGRAMS for each target that has a main in it +# On linux this will generate an executable in bin.debug.Linux.i686/main +TESTPROGRAMS += main.cxx + +# Add each of the C++ or C files that other than the main +# Each main target (from TESTPROGRAMS) will be linked with all of the files in SRC +SRC = TestSupport.cxx + +# Includes macros +include $(BUILD)/Makefile.post +########################################################################################### + +Option 2: (Using a third party build system) + +Prerequisites: +- Install ares library from contrib/ares + - cd contrib/ares + - ./configure + - make + - make install + +Pass the following flags to C++ compiler: +Assumptions: +- have pthreads +- have openssl installed +- have ares installed +- resiprocate library is built and installed + +# Linux Example +CXXFLAGS += -Wall -fPIC -Wno-deprecated -march=i686 \ + -D_REENTRANT -DUSE_SSL -DNEW_MSG_HEADER_SCANNER -DUSE_IPV6 -DUSE_ARES \ + -I/usr/kerberos/include -I$(RESIP_DIR)/lib.debug.Linux.i686 +LDFLAGS += -L$(RESIP_DIR)/lib.debug.Linux.i686 +LDLIBS += -lresip -lrutil -lssl -lcrypto -lares -lpthread + + diff --git a/src/libs/resiprocate/ReleaseNotes.txt b/src/libs/resiprocate/ReleaseNotes.txt new file mode 100644 index 00000000..9040a871 --- /dev/null +++ b/src/libs/resiprocate/ReleaseNotes.txt @@ -0,0 +1,104 @@ += Release Notes v 1.6 = + +==General== +===New features=== +* new clicktocall project +* new ichat to SIP gateway project +* adding Tarasenko Volodymyr's autotools macro for use in external projects + +==Build system== +===New features=== +* auto-detect c-ares headers/libs, both for in-place builds, and installed headers +* added VS2010 project files + +===Bug fixes=== +* added missing LEAK_CHECK defines to windows DEBUG builds of dum, resiprocate and rutil +* if popt is in a default location, don't include it with -I and -L +* added missing AresCompat.hxx (in rutil VS 9.0 project file) + +==rutil== +===New features=== +* added ParseBuffer::skipBackToOneOf() +* added ability to createLocalLogger instances, and assign these instances to threads (Thanks to Alexander Chemeris) + +===Bug fixes=== +* remove spurious boost include +* override std::exception::what() in BaseException, so we actually get a usable error if we don't catch one +* stop asserting if we get an empty DNS response, and implemented handling code for this case + +==stack== +===New features=== +* define Remote-Party-Id header as a multi header +* change from Gregor Jasny to be tolerant of rtpmap lines missing the rate parameter +* new generic DigestStream class for any openSSL digest +* change to allow XMLCursor to parse an XML document with no prolog +* change to SDP parser to be tolerant of whitespace following the codec id on the m line +* added Uri::getAorNoReally() which actually returns the AoR as defined by RFC 3261 +* send 503 to TU instead of 408 if DNS times out +* better reason phrases when timeouts occur +* changes to resip stack to allow passing a port of 0 into addTransport interface to allow OS to choose an appropriate port number + +===Bug fixes=== +* some fixes to the sigcomp code +* fixing a few params to be quoted-string instead of non-quoted data (vendor, model, and version) +* don't call encode twice on bodies (major inefficiency, but didn't really result in bad behavior) +* replace a couple of static objects with member objects, so we don't have problems with multiple SipStacks in the same process +* close connected-UDP sockets (used by TransportSelector to query the routing table when we haven't explicitly specified what interface we want to use when sending) on teardown; allows a single process to create and destroy SipStacks repeatedly without leaking fds (mainly for unit-tests) +* stop sitting around on our thumbs for 200ms when DNS processing needs to be done +* removed incorrect Q value compare fn in Uri class - q-value is a contact/name-addr parameter, not a uri parameter +* fix issue with logging errno after SSL_ERROR_SYSCALL in TlsConnection +* moved various fn local static variables to file level static variables to avoid multi-threaded first call runtime race conditions with initializing local static variables + +==DUM== +===New features=== +* patch from Chris Brody so that the tests will build if not using POPT +* added "invariant" reason code from 3265bis00 (for subscriptions) +* change optional RWMutex parameter to Lockable base type in dum::process to allow other types of Mutex's to be passed in + +===Bug fixes=== +* fix bug where wrong terminated reason is sent in callback when receiving a CANCEL +* ClientInviteSession changes to react appropriately to reception of UPDATE messages before connected state +* always allow reject to be called after onOffer - adding case where offer comes in 2xx response after invite with no sdp - ACK 200, then BYE session +* fix to UAC handling to be able to handle sending ACK then BYE when a CANCEL request crosses a 200/Inv. This fix handles the case when we don't have any formed dialogs at the time of cancel +* fixed bug where DialogSet::ifMatch() would not work for resubscribes +* don't tear down server subscriptions when the app sends an error response that implies either an optional retry-after, or implies application-dependent behavior +* fixed RedirectManager Q-Value ordering function - it was looking for q-value as a uri parameter - also changed to treat no q-value as q=1.0 +* ensure auth headers are cleared out before retrying client registration +* fixing a bug with Glare timers if we placed the call (UAC) - they were not being properly dispatched to InviteSession +* use supported mimetype for subscriptions in NOTIFY messages instead of SUBSCRIBE messages +* stop using UPDATE for confirmed dialogs, since it is recommended against in RFC 3311 +* fixed a bug in client subscription if AppDialogSet's are used, and a retry is attempted +* fixed a ClientSubscription bug when retrying - not reusing profile used in original subscription setup +* fixed a difficult to find, and long standing memory leak bug in ClientSubscriptions +* added handling to ClientRegistration for strange border case where registrar returns an Expires header of 0 after attempting to register + +==repro== +===New features=== +* some logging improvements +* better description of defaults for command-line options +* modification to repro so that contacts without a q-value are treated as having q=1.0 +* changes to repro to allow Registration, and Publish/Subscribe forwarding to other domains + +===Bug fixes=== +* actual Proxy-Require support (yeah, yeah, about time, I know) +* reject requests with a garbage next-hop Route header immediately, instead of having the stack complain when we try to forward +* various bugfixes related to outbound +* ignore user-part of topmost Route header if it doesn't parse as a flow-token + +==reTurn== +===New features=== +* pad the content of the SOFTWARE header so that we are on a 4 byte boundary for size (prevents STUN messages from reTurn showing up in Wireshark as malformed packets) + +===Bug fixes=== +* fix a couple of spots where we try to erase from mActiveRequestMap using an invalidated iterator +* fixed a bug in processTurnAllocateRequest that led to reTurnServer giving "unauthorized" errors + +==recon== + +===Bug fixes=== +* recon memory leak fixes - thanks to Julio Cabezas +* update to recon VS2008/2005/2003 solution files for sipXtapi rev 11413 with speex update +* allow recon to properly reject media lines with unknown media types and protocols +* fixup sdp direction attribute in our offers in scenarios where we are being held by the other party +* fix UserProfile selection when receiving refer with no subscription +* make sure our ReferTo header doesn't have tags in it diff --git a/src/libs/resiprocate/ax_resip.m4 b/src/libs/resiprocate/ax_resip.m4 new file mode 100644 index 00000000..409539c1 --- /dev/null +++ b/src/libs/resiprocate/ax_resip.m4 @@ -0,0 +1,175 @@ +# +# SYNOPSIS +# +# AX_RESIP([MINIMUM-VERSION]) +# +# NOTE +# Currently macros does not check the version of the resiprocate library +# +# DESCRIPTION +# +# This macro provides tests of availability of the resiprocate library (resiprocate.org) +# +# Next options are available: +# --with-resip=path defines the complete path to the Resiprocate includes and +# libraries +# --with-resip-inc=path defines the complete path to resip headers +# --with-resip-lib=path defines the complete path to resip library +# +# This macro calls: +# +# AC_SUBST(RESIP_CPPFLAGS) +# AC_SUBST(RESIP_LDFLAGS) +# AC_SUBST(RESIP_LIBS) +# +# And sets: +# +# HAVE_RESIPROCATE +# +# COPYLEFT +# +# Copyright (c) 2009 Tarasenko Volodymyr +# +# Copying and distribution of this file, with or without +# modification, are permitted in any medium without royalty provided +# the copyright notice and this notice are preserved. This file is +# offered as-is, without any warranty. + + +AC_DEFUN([AX_RESIP], +[ + AC_ARG_WITH([resip], + AC_HELP_STRING([--with-resip=@<:@ARG@:>@], + [use Resiprocate library @<:@default=yes@:>@, optionally specify a path to includes and library] + ), + [ + if test "$withval" = "no"; then + want_resip="no" + elif test "$withval" = "yes"; then + want_resip="yes" + else + want_resip="yes" + resip_path="$withval" + fi + ], + [want_resip="yes"] + ) + dnl + dnl RESIP includes + dnl + AC_ARG_WITH([resip_inc], + AC_HELP_STRING([--with-resip-inc=@<:@ARG@:>@], + [specify Resiprocate includes] + ), + [ + case "$withval" in + /* ) ;; + * ) AC_MSG_ERROR([The Resiprocate includes directory must be an absolute path.]) ;; + esac + + resip_inc_path="$withval" + ], + [resip_inc_path="/usr/include /usr/include/resip /usr/local/include /usr/local/resip"] + ) + dnl + dnl RESIP libraries + dnl + AC_ARG_WITH([resip_lib], + AC_HELP_STRING([--with-resip-lib=@<:@ARG@:>@], + [specify Resiprocate library path] + ), + [ + case "$withval" in + /* ) ;; + * ) AC_MSG_ERROR([The Resiprocate library path directory must be an absolute path.]) ;; + esac + + resip_lib_path="$withval" + ], + [resip_lib_path="/lib /usr/lib /usr/lib64 /usr/local/lib /usr/local/resip"] + ) + + RESIP_CPPFLAGS="" + RESIP_LDFLAGS="" + RESIP_LIBS="" + + dnl + dnl Do checks + dnl + + AC_MSG_CHECKING([for Resiprocate library]) + + if test "x$want_resip" = "xyes"; then + AC_REQUIRE([AC_PROG_CPP]) + AC_REQUIRE([AC_CANONICAL_BUILD]) + + if test -n "$resip_path"; then + RESIP_CPPFLAGS="-I$resip_path" + RESIP_LDFLAGS="-L$resip_path" + else + for inc in $resip_inc_path; do + if test -f "$inc/resip/stack/SipStack.hxx"; then + RESIP_CPPFLAGS="-I$inc" + break + fi + done + + for inc in $resip_lib_path; do + if test -f "$inc/libresip.so" || test -f "$inc/libresip.a" + then + RESIP_LDFLAGS="-L$inc" + break + fi + done + fi + dnl + dnl Simple add libresip and librutil, should be fixed in future + RESIP_LIBS="-ldum -lresip -lrutil -lares" + + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $RESIP_CPPFLAGS $CFLAGS" + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $RESIP_LDFLAGS" + + LIBS_SAVED="$LIBS" + LIBS="$RESIP_LIBS $LIBS" + + AC_LANG_PUSH(C++) + + AC_LINK_IFELSE(AC_LANG_PROGRAM([[ @%:@include + ]], + [[ + + resip::SipStack stack(0, resip::DnsStub::EmptyNameserverList,0,false,0); + return 0; + ]]), + [resip_found="yes"], + [resip_found="no"]) + + AC_LANG_POP([C++]) + + LDFLAGS="$LDFLAGS_SAVED" + CPPFLAGS="$CPPFLAGS_SAVED" + LIBS="$LIBS_SAVED" + + if test "x$resip_found" = "xyes"; then + AC_DEFINE([HAVE_RESIPROCATE], [1], + [Define to 1 if RESIPROCATE library is available]) + + AC_SUBST(RESIP_CPPFLAGS) + + AC_SUBST(RESIP_LDFLAGS) + + AC_SUBST(RESIP_LIBS) + + AC_MSG_RESULT([yes]) + else + AC_MSG_ERROR([[Could not detect the Resiprocate libraries.]]) + AC_MSG_RESULT([no]) + + fi + else + AC_MSG_RESULT([no]) + fi +]) diff --git a/src/libs/resiprocate/b2bua/AccountingManager.hxx b/src/libs/resiprocate/b2bua/AccountingManager.hxx new file mode 100644 index 00000000..f0bac7bc --- /dev/null +++ b/src/libs/resiprocate/b2bua/AccountingManager.hxx @@ -0,0 +1,68 @@ + +#ifndef __AccountingManager_h +#define __AccountingManager_h + + +#include "rutil/Data.h" + +namespace b2bua +{ + +class AccountingManager { + +public: + // Call has entered system + virtual void onCallStart() = 0; + // Call has been authorised + virtual void onCallAuthorise() = 0; + // Call has connected + virtual void onCallConnect() = 0; + // A route has failed + virtual void onCallRouteFail() = 0; + // All routes have been tried and failed, or the call was not authorised + virtual void onCallFail() = 0; + // The call connected and completed successfully + virtual void onCallFinish() = 0; +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/AuthenticationManager.cxx b/src/libs/resiprocate/b2bua/AuthenticationManager.cxx new file mode 100644 index 00000000..22484bf7 --- /dev/null +++ b/src/libs/resiprocate/b2bua/AuthenticationManager.cxx @@ -0,0 +1,45 @@ + +#include "AuthenticationManager.hxx" + +using namespace b2bua; + +AuthenticationManager::SecretListener::~SecretListener() { +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/AuthenticationManager.hxx b/src/libs/resiprocate/b2bua/AuthenticationManager.hxx new file mode 100644 index 00000000..76d40a2e --- /dev/null +++ b/src/libs/resiprocate/b2bua/AuthenticationManager.hxx @@ -0,0 +1,79 @@ + +#ifndef __AuthenticationManager_h +#define __AuthenticationManager_h + +#include "rutil/Data.hxx" + +namespace b2bua +{ + +class AuthenticationManager { + +// const resip::Data& realm; +// const resip::Data& user; + +public: + + /** + * The application should implement SecretListener to receive callbacks + * when authentication is complete. + */ + class SecretListener { + public: + virtual ~SecretListener(); + // Called when the secret is found successfully + virtual void onSuccess(const resip::Data& realm, const resip::Data& user, const resip::Data& secret) = 0; + // Called when the user ID is not recognised + virtual void onUserUnknown(const resip::Data& realm, const resip::Data& user) = 0; + // Called when an internal failure or timeout occurs + virtual void onFailure(const resip::Data& realm, const resip::Data& user) = 0; + }; + + virtual ~AuthenticationManager() {}; + + virtual void getSecret(const resip::Data& realm, const resip::Data& user, AuthenticationManager::SecretListener *secretListener) = 0; + +}; + +} + +#endif + + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/AuthorizationManager.hxx b/src/libs/resiprocate/b2bua/AuthorizationManager.hxx new file mode 100644 index 00000000..d50817ef --- /dev/null +++ b/src/libs/resiprocate/b2bua/AuthorizationManager.hxx @@ -0,0 +1,92 @@ + +#ifndef __AuthorizationManager_h +#define __AuthorizationManager_h + +#include "rutil/Data.hxx" + +#include "CallHandle.hxx" + +namespace b2bua +{ + +class AuthorizationManager { + +public: + + typedef enum DenialReason { + AuthenticationRequired, // A username is required + PeerUnknown, // IP or username unrecognised by + // the AuthorizationManager + InsufficientFunds, // Deposit more funds + Unspecified, // Request denied for an unspecified + // reason (e.g. account suspended), + // but not due to error + DestinationIncomplete, // Number is too short + DestinationInvalid, // Unrecognised destination prefix + // or name + InvalidRequest, // Some other aspect of the request + // is invalid + NetworkError, // An error occurred communicating + // with a remote auth server + Timeout, // A timeout occurred + GeneralError // An error while processing + }; + + class AuthorizationListener { + public: + virtual ~AuthorizationListener() {}; + // Call is authorized + virtual void onSuccess() = 0; + // Call is denied + virtual void onDeny(AuthorizationManager::DenialReason reason) = 0; + }; + + //virtual void getAuthorization(); + + virtual ~AuthorizationManager() {}; + + virtual CallHandle *authorizeCall(const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPass, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId, time_t startTime) = 0; + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/B2BCall.cxx b/src/libs/resiprocate/b2bua/B2BCall.cxx new file mode 100644 index 00000000..424d1971 --- /dev/null +++ b/src/libs/resiprocate/b2bua/B2BCall.cxx @@ -0,0 +1,1321 @@ + +#include + +#include "resip/dum/ServerInviteSession.hxx" + +#include "B2BCall.hxx" +#include "CallHandle.hxx" +#include "Logging.hxx" +#include "MyAppDialog.hxx" + +using namespace b2bua; +using namespace resip; +using namespace std; + +// DialogUsageManager *B2BCall::dum = NULL; +// CallController *B2BCall::callController = NULL; +// list B2BCall::calls; + +Data B2BCall::callStateNames[] = { + Data("NewCall"), + Data("CallerCancel"), + Data("AuthorizationPending"), + Data("AuthorizationSuccess"), + Data("AuthorizationFail"), + Data("MediaProxySuccess"), + Data("MediaProxyFail"), + Data("ReadyToDial"), + Data("DialInProgress"), + Data("DialFailed"), + Data("DialRejected"), + Data("SelectAlternateRoute"), + Data("DialAborted"), + Data("DialReceived180"), + Data("DialReceivedEarlyAnswer"), + Data("DialEarlyMediaProxySuccess"), + Data("DialEarlyMediaProxyFail"), + Data("CallAccepted"), + Data("CallAcceptedMediaProxySuccess"), + Data("CallAcceptedMediaProxyFail"), + Data("CallActive"), + Data("CallerHangup"), + Data("CalleeHangup"), + Data("LocalHangup"), + Data("CallStop"), + Data("CallStopMediaProxySuccess"), + Data("CallStopMediaProxyFail"), + Data("CallStopFinal") +}; + +const char *B2BCall::basicClearingReasonName[] = { + "NO ANSWER", + "BUSY", + "CONGESTION", + "ERROR", + "ANSWERED" +}; + +/* void B2BCall::setDum(DialogUsageManager *dum) { + B2BCall::dum = dum; +} */ + +/* void B2BCall::setCallController(CallController *callController) { + B2BCall::callController = callController; +} */ + +B2BCall::B2BCall(CDRHandler& cdrHandler, DialogUsageManager& dum, AuthorizationManager& authorizationManager, MyAppDialog *aLegAppDialog, const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPassword, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId) : cdrHandler(cdrHandler), dum(dum), authorizationManager(authorizationManager), sourceAddr(sourceAddr), destinationAddr(destinationAddr), authRealm(authRealm), authUser(authUser), authPassword(authPassword), srcIp(srcIp), contextId(contextId), accountId(accountId), baseIp(baseIp), controlId(controlId) { + callHandle = NULL; + fullClearingReason = Unset; + rejectOtherCode = 0; + failureStatusCode = -1; + this->aLegAppDialog = aLegAppDialog; + aLegAppDialog->setB2BCall(this); + bLegAppDialogSet = NULL; + bLegAppDialog = NULL; + //callState = CALL_NEW; + callState = NewCall; + time(&startTime); + connectTime = 0; + finishTime = 0; + //aLegSdp = NULL; + //bLegSdp = NULL; + try { + mediaManager = new MediaManager(*this, aLegAppDialog->getDialogId().getCallId(), aLegAppDialog->getDialogId().getLocalTag(), Data("")); + } catch (...) { + B2BUA_LOG_ERR("failed to instantiate MediaManager"); + throw new exception; + } + earlyAnswerSent = false; + failureReason = NULL; +// calls.push_back(this); +} + +B2BCall::~B2BCall() { + if(callHandle != NULL) + delete callHandle; + if(mediaManager != NULL) + delete mediaManager; + if(failureReason != NULL) + delete failureReason; + if(aLegAppDialog != NULL) + aLegAppDialog->setB2BCall(NULL); + if(bLegAppDialogSet != NULL) + bLegAppDialogSet->setB2BCall(NULL); + if(bLegAppDialog != NULL) + bLegAppDialog->setB2BCall(NULL); +} + + +bool B2BCall::setCallState(B2BCall::B2BCallState newCallState) { + B2BUA_LOG_DEBUG("CallState change: " << callState << ":" << getCallStateName(callState) << " -> " << newCallState << ":" << getCallStateName(newCallState) << ": "); + if(!isCallStatePermitted(newCallState)) { + B2BUA_LOG_ERR("Denied call state change: %d: %s -> %d: %s", callState, getCallStateName(callState).c_str(), newCallState, getCallStateName(newCallState).c_str()); + return false; + } + B2BUA_LOG_DEBUG("permitted."); + callState = newCallState; + return true; +} + +bool B2BCall::isCallStatePermitted(B2BCall::B2BCallState newCallState) { + switch(callState) { + + case NewCall: + switch(newCallState) { + case CallerCancel: + case AuthorizationPending: + case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case CallerCancel: + switch(newCallState) { + case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case AuthorizationPending: + switch(newCallState) { + case AuthorizationSuccess: + case AuthorizationFail: + case CallerCancel: + //case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case AuthorizationSuccess: + switch(newCallState) { + case CallerCancel: + case MediaProxySuccess: + case MediaProxyFail: + case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case AuthorizationFail: + switch(newCallState) { + case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case MediaProxySuccess: + switch(newCallState) { + case CallerCancel: + case ReadyToDial: + //case DialInProgress: + case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case MediaProxyFail: + switch(newCallState) { + case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case ReadyToDial: + switch(newCallState) { + case CallerCancel: + case DialInProgress: + callState = newCallState; + return true; + default: + return false; + } + + case DialInProgress: + switch(newCallState) { + case CallerCancel: + case DialFailed: + case DialRejected: + case DialInProgress: // FIXME - should we change to same state? + //case DialReceived100: + case DialReceived180: + case DialReceivedEarlyAnswer: + case CallAccepted: + //case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case DialFailed: + switch(newCallState) { + case CallerCancel: + //case MediaProxySuccess: + //case ReadyToDial: + case SelectAlternateRoute: + //case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case DialRejected: + switch(newCallState) { + case CallerCancel: + //case MediaProxySuccess: + //case ReadyToDial: + case SelectAlternateRoute: + case DialAborted: + //case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case SelectAlternateRoute: + switch(newCallState) { + case CallerCancel: + case ReadyToDial: + case DialAborted: + callState = newCallState; + return true; + default: + return false; + }; + + case DialAborted: + switch(newCallState) { + case CallStop: + return true; + default: + return false; + }; + + /* case DialReceived100: + switch(newCallState) { + case CallerCancel: + case DialInProgress: + case DialReceived180: + case DialReceivedEarlyAnswer: + case DialFailed: + case DialRejected: + case CallAccepted: + case CallStop: + callState = newCallState; + return true; + default: + return false; + }; */ + + case DialReceived180: + switch(newCallState) { + case CallerCancel: + case DialInProgress: + case DialFailed: + case DialRejected: + case DialReceivedEarlyAnswer: + case CallAccepted: + //case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case DialReceivedEarlyAnswer: + switch(newCallState) { + case CallerCancel: + case DialInProgress: + case DialFailed: + case DialRejected: + case DialEarlyMediaProxySuccess: + case DialEarlyMediaProxyFail: + case CallAccepted: + //case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + +/* case DialEarlyMediaProxyRequested: + switch(newCallState) { + case : + callState = newCallState; + return true; + default: + return false; + }; */ + + case DialEarlyMediaProxySuccess: + switch(newCallState) { + case CallerCancel: + case DialInProgress: + case DialFailed: + case DialRejected: + case CallAccepted: + //case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case DialEarlyMediaProxyFail: + switch(newCallState) { + case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case CallAccepted: + switch(newCallState) { + case CallerCancel: + case CallAcceptedMediaProxySuccess: + case CallAcceptedMediaProxyFail: + case CallActive: + case CallerHangup: + case CalleeHangup: + case LocalHangup: + //case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + +/* case CallAcceptedMediaProxyRequested: + switch(newCallState) { + case : + callState = newCallState; + return true; + default: + return false; + }; */ + + case CallAcceptedMediaProxySuccess: + switch(newCallState) { + case CallerCancel: + case CallActive: + case CallerHangup: + case CalleeHangup: + case LocalHangup: + //case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case CallAcceptedMediaProxyFail: + switch(newCallState) { + case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case CallActive: + switch(newCallState) { + case CallerCancel: + case CallerHangup: + case CalleeHangup: + case LocalHangup: + //case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case CallerHangup: + switch(newCallState) { + case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case CalleeHangup: + switch(newCallState) { + case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case LocalHangup: + switch(newCallState) { + case CallStop: + callState = newCallState; + return true; + default: + return false; + }; + + case CallStop: + switch(newCallState) { + case CallStopMediaProxySuccess: + case CallStopMediaProxyFail: + case CallStopFinal: + callState = newCallState; + return true; + default: + return false; + }; + +/* case CallStopMediaProxyNotified: + switch(newCallState) { + case : + callState = newCallState; + return true; + default: + return false; + }; */ + + case CallStopMediaProxySuccess: + switch(newCallState) { + case CallStopFinal: + callState = newCallState; + return true; + default: + return false; + }; + + case CallStopMediaProxyFail: + switch(newCallState) { + case CallStopFinal: + callState = newCallState; + return true; + default: + return false; + }; + + case CallStopFinal: + return false; // no state changes permitted + + default: + B2BUA_LOG_ERR("B2BCall in unknown call state %d", callState); + return false; + }; +}; + +const Data& B2BCall::getCallStateName(B2BCallState s) { + return callStateNames[s]; +}; + +void B2BCall::setALegSdp(const SdpContents& sdp, const in_addr_t& msgSourceAddress) { + // try { + mediaManager->setALegSdp(sdp, msgSourceAddress); + //} catch (...) { + // FIXME - call state + // B2BUA_LOG_WARNING, "failed to accept SDP from A leg"); + //callState = CALL_STOP; + //} +} + +void B2BCall::setBLegSdp(const SdpContents& sdp, const in_addr_t& msgSourceAddress) { + //try { + mediaManager->setBLegSdp(sdp, msgSourceAddress); + //} catch (...) { + // B2BUA_LOG_WARNING, "failed to accept SDP from B leg"); + //callState = CALL_STOP; + //} +} + +void B2BCall::setBLegAppDialog(MyAppDialog *myAppDialog) { + bLegAppDialog = myAppDialog; + //mediaManager->setToTag(bLegAppDialog->getDialogId().getLocalTag()); +} + +void B2BCall::releaseAppDialog(MyAppDialog *myAppDialog) { + if(myAppDialog == aLegAppDialog) { + aLegAppDialog = NULL; + } else if(myAppDialog == bLegAppDialog) { + bLegAppDialog = NULL; + } else { + B2BUA_LOG_ERR("releaseAppDialog for unknown AppDialog"); + } +} + +void B2BCall::releaseAppDialogSet(MyAppDialogSet *myAppDialogSet) { + if(myAppDialogSet == bLegAppDialogSet) { + bLegAppDialogSet = NULL; + } else { + B2BUA_LOG_ERR("releaseAppDialogSet for unknown AppDialogSet"); + } +} + +/* This method is called regularly. + Instead, the callbacks or setCallState should send a message to + B2BUA to say that the call needs attention. */ +void B2BCall::checkProgress(time_t now, bool stopping) { + switch(callState) { + case NewCall: + doNewCall(); + break; + case CallerCancel: + doCallerCancel(); + break; + case AuthorizationPending: + doAuthorizationPending(); + break; + case AuthorizationSuccess: + doAuthorizationSuccess(); + break; + case AuthorizationFail: + doAuthorizationFail(); + break; + case MediaProxySuccess: + doMediaProxySuccess(); + break; + case MediaProxyFail: + doMediaProxyFail(); + break; + case ReadyToDial: + doReadyToDial(); + break; + case DialInProgress: + // FIXME - route timeout? + break; + case DialFailed: + doDialFailed(); + break; + case DialRejected: + doDialRejected(); + break; + case SelectAlternateRoute: + doSelectAlternateRoute(); + break; + case DialAborted: + doDialAborted(); + break; + /* case DialReceived100: + doDialReceived100(); + break; */ + case DialReceived180: + doDialReceived180(); + break; + /* case CALL_DIAL_183: + doCallDial183(); + break; */ + case DialReceivedEarlyAnswer: + doDialReceivedEarlyAnswer(); + break; + case DialEarlyMediaProxySuccess: + doDialEarlyMediaProxySuccess(); + break; + case DialEarlyMediaProxyFail: + doDialEarlyMediaProxyFail(); + break; + //case CALL_DIAL_PROGRESS: + //doCallDialProgress(); + //break; + case CallAccepted: + doCallAccepted(); + break; + case CallAcceptedMediaProxySuccess: + doCallAcceptedMediaProxySuccess(); + break; + case CallAcceptedMediaProxyFail: + doCallAcceptedMediaProxyFail(); + break; + case CallActive: + doCallActive(); + break; + case CallerHangup: + case CalleeHangup: + case LocalHangup: + doHangup(); + case CallStop: + doCallStop(); + break; + case CallStopMediaProxySuccess: + doCallStopMediaProxySuccess(); + break; + case CallStopMediaProxyFail: + doCallStopMediaProxyFail(); + break; + case CallStopFinal: + doCallStopFinal(); + break; + default: + B2BUA_LOG_ERR("unknown call state %d", callState); + assert(0); + break; + } +} + +bool B2BCall::isComplete() { + return (callState == CallStopFinal); +} + +B2BCall::CallStatus B2BCall::getStatus() { + switch(callState) { + case NewCall: + return PreDial; + case CallerCancel: + return Finishing; + case AuthorizationPending: + case AuthorizationSuccess: + case AuthorizationFail: + case MediaProxySuccess: + case MediaProxyFail: + return PreDial; + case ReadyToDial: + case DialInProgress: + case DialFailed: + case DialRejected: + case SelectAlternateRoute: + case DialAborted: + //case DialReceived100: + case DialReceived180: + case DialReceivedEarlyAnswer: + case DialEarlyMediaProxySuccess: + case DialEarlyMediaProxyFail: + return Dialing; + case CallAccepted: + case CallAcceptedMediaProxySuccess: + case CallAcceptedMediaProxyFail: + case CallActive: + return Connected; + case CallerHangup: + case CalleeHangup: + case LocalHangup: + case CallStop: + case CallStopMediaProxySuccess: + case CallStopMediaProxyFail: + case CallStopFinal: + return Finishing; + default: + return Unknown; + } +} + +void B2BCall::doNewCall() { + // Indicate trying + ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + sis->provisional(100); + callHandle = authorizationManager.authorizeCall(sourceAddr, destinationAddr, authRealm, authUser, authPassword, srcIp, contextId, accountId, baseIp, controlId, startTime); + if(callHandle == NULL) { + B2BUA_LOG_WARNING("failed to get callHandle"); + setCallState(CallStop); + } else { + setCallState(AuthorizationPending); + } +} + +void B2BCall::doCallerCancel() { + setClearingReason(NoAnswerCancel, -1); + // If B leg dialing, send a CANCEL + if(bLegAppDialogSet != NULL) { + bLegAppDialogSet->end(); + } + setCallState(CallStop); +} + +void B2BCall::doAuthorizationPending() { + switch(callHandle->getAuthResult()) { + case CC_PENDING: + return; + case CC_PERMITTED: + setCallState(AuthorizationSuccess); + break; + default: + setCallState(AuthorizationFail); + } + return; +} + +void B2BCall::doAuthorizationSuccess() { + // point to the first route + callRoute = callHandle->getRoutes().begin(); + if(callRoute == callHandle->getRoutes().end()) { + appRef1 = Data(""); + appRef2 = Data(""); + setClearingReason(InvalidDestination, -1); + B2BUA_LOG_NOTICE("no routes returned"); + ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + sis->reject(500); // Server internal error + setCallState(CallStop); + return; + } + appRef1 = (*callRoute)->getAppRef1(); + appRef2 = (*callRoute)->getAppRef2(); + setCallState(MediaProxySuccess); + doMediaProxySuccess(); +} + +void B2BCall::doAuthorizationFail() { + setClearingReason(AuthError, -1); + if(aLegAppDialog != NULL) { + ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + switch(callHandle->getAuthResult()) { + case CC_AUTH_REQUIRED: + sis->reject(401); // Unauthorized/credentials required + break; + case CC_PAYMENT_REQUIRED: + sis->reject(402); // Payment required + break; + case CC_REQUEST_DENIED: + case CC_IP_DENIED: + sis->reject(403); // Permission denied/forbidden + break; + case CC_ERROR: + sis->reject(500); // Server internal error + break; + case CC_INVALID: + sis->reject(403); // Forbidden + break; + case CC_DESTINATION_INCOMPLETE: + sis->reject(484); // Incomplete + break; + case CC_DESTINATION_INVALID: + sis->reject(404); // User doesn't exist + break; + case CC_TIMEOUT: + sis->reject(500); // Server internal error + break; + default: + sis->reject(500); // Server internal error + } + } + setCallState(CallStop); +} + +void B2BCall::doMediaProxySuccess() { + setCallState(ReadyToDial); + doReadyToDial(); +} + +void B2BCall::doMediaProxyFail() { + setClearingReason(AuthError, -1); + B2BUA_LOG_ERR("failed to prepare media proxy"); + setCallState(CallStop); +} + +void B2BCall::doReadyToDial() { + // Media Proxy is ready, now we can create the B-leg and send an INVITE + try { + //SharedPtr outboundUserProfile(new UserProfile); + SharedPtr outboundUserProfile(dum.getMasterUserProfile()); + outboundUserProfile->setDefaultFrom((*callRoute)->getSourceAddr()); + outboundUserProfile->setDigestCredential((*callRoute)->getAuthRealm(), (*callRoute)->getAuthUser(), (*callRoute)->getAuthPass()); + if((*callRoute)->getOutboundProxy() != Uri()) + outboundUserProfile->setOutboundProxy((*callRoute)->getOutboundProxy()); + bLegAppDialogSet = new MyAppDialogSet(dum, this, outboundUserProfile); + + SharedPtr msgB; + SdpContents *initialOffer = (SdpContents *)mediaManager->getALegSdp().clone(); + msgB = dum.makeInviteSession((*callRoute)->getDestinationAddr(), outboundUserProfile, initialOffer, bLegAppDialogSet); + delete initialOffer; + dum.send(msgB); + + setCallState(DialInProgress); + } catch (...) { + B2BUA_LOG_WARNING("failed to create new InviteSession"); + setClearingReason(AuthError, -1); + setCallState(DialFailed); + return; + } +} + +// A route failed (timeout, ICMP, invalid domain, etc), try the next route +void B2BCall::doDialFailed() { + if(bLegAppDialogSet != NULL) { + bLegAppDialogSet->end(); + bLegAppDialogSet->setB2BCall(NULL); + } + bLegAppDialogSet = NULL; + bLegAppDialog = NULL; + failureStatusCode = -1; + //setClearingReason(AuthError, -1); + setCallState(SelectAlternateRoute); + doSelectAlternateRoute(); +} + +// A route rejected the call, try the next route +void B2BCall::doDialRejected() { + switch(failureStatusCode) { + case -1: + //setClearingReason(AuthError, -1); + setCallState(SelectAlternateRoute); + doSelectAlternateRoute(); + break; + //case 480: // Temporarily not available + case 486: // Busy + //case 600: // Busy everywhere + //case 603: // Decline + // We will consider all of the above to be `BUSY' + setClearingReason(RejectBusy, failureStatusCode); + setCallState(DialAborted); + doDialAborted(); + break; + default: + //setClearingReason(RejectOther, failureStatusCode); + if(bLegAppDialogSet != NULL) { + bLegAppDialogSet->end(); + bLegAppDialogSet->setB2BCall(NULL); + } + bLegAppDialogSet = NULL; + bLegAppDialog = NULL; + setCallState(SelectAlternateRoute); + doSelectAlternateRoute(); + break; + } +} + +void B2BCall::doSelectAlternateRoute() { + callRoute++; + if(callRoute == callHandle->getRoutes().end()) { + B2BUA_LOG_DEBUG("no routes remaining, aborting attempt"); + setCallState(DialAborted); + doDialAborted(); + return; + } + appRef1 = (*callRoute)->getAppRef1(); + appRef2 = (*callRoute)->getAppRef2(); + setCallState(ReadyToDial); + doReadyToDial(); +} + +void B2BCall::doDialAborted() { + ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + if(failureStatusCode == -1) { + setClearingReason(AuthError, failureStatusCode); // FIXME + sis->reject(503); + } else { + setClearingReason(RejectOther, failureStatusCode); + sis->reject(failureStatusCode); + } + setCallState(CallStop); + doCallStop(); +} + + +/* void B2BCall::doDialReceived100() { + setCallState(DialInProgress); +} */ + +void B2BCall::doDialReceived180() { + if(setCallState(DialInProgress)) { + ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + sis->provisional(180); + } +} + +/* void B2BCall::doCallDial183() { + // FIXME - do nothing for now, unless there is an offer + setCallState(DialInProgress); +} */ + +void B2BCall::doDialReceivedEarlyAnswer() { + if(earlyAnswerSent == true) { + setCallState(DialInProgress); + return; + } + ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + //sis->provideAnswer(*bLegSdp); + try { + sis->provideAnswer(mediaManager->getBLegSdp()); + } catch (...) { + B2BUA_LOG_WARNING("failed to get B Leg SDP"); + setClearingReason(AuthError, -1); + setCallState(DialEarlyMediaProxyFail); + return; + } + //sis->provisional(183); + //earlyAnswerSent = true; + setCallState(DialEarlyMediaProxySuccess); + doDialEarlyMediaProxySuccess(); +} + +void B2BCall::doDialEarlyMediaProxySuccess() { + ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + sis->provisional(183); + earlyAnswerSent = true; + setCallState(DialInProgress); +} + +void B2BCall::doDialEarlyMediaProxyFail() { + setClearingReason(AuthError, -1); + ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + sis->reject(500); // FIXME - error code + setCallState(CallStop); +} + +void B2BCall::doCallAccepted() { + ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + if(!earlyAnswerSent) { + try { + SdpContents& sdp = mediaManager->getBLegSdp(); + sis->provideAnswer(sdp); // FIXME - for re-INVITE + } catch(...) { + //setClearingReason(Error, -1); + setClearingReason(AnsweredError, -1); + setCallState(CallAcceptedMediaProxyFail); + return; + } + } + setCallState(CallAcceptedMediaProxySuccess); + doCallAcceptedMediaProxySuccess(); +} + +void B2BCall::doCallAcceptedMediaProxySuccess() { + ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + sis->accept(); + time(&connectTime); + callHandle->connect(&connectTime); + setCallState(CallActive); +} + +void B2BCall::doCallAcceptedMediaProxyFail() { + setClearingReason(AnsweredError, -1); + ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + sis->reject(500); // FIXME - error codes + setCallState(CallStop); +} + +void B2BCall::doCallActive() { + if(callHandle->mustHangup()) { + B2BUA_LOG_DEBUG("ending a call due to mustHangup()"); + setClearingReason(AnsweredLimit, -1); + setCallState(LocalHangup); + } +} + +void B2BCall::doHangup() { + setCallState(CallStop); +} + +void B2BCall::doCallStop() { +// setClearingReason(AnsweredUnknown, -1); + time(&finishTime); + if(callHandle != NULL) { + if(connectTime != 0) + callHandle->finish(&finishTime); + else + callHandle->fail(&finishTime); + } + if(aLegAppDialog != NULL) { + ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + sis->end(); + } + if(bLegAppDialogSet != NULL) { + bLegAppDialogSet->end(); + } + writeCDR(); + setCallState(CallStopFinal); +} + +void B2BCall::doCallStopMediaProxySuccess() { + setCallState(CallStopFinal); +} + +void B2BCall::doCallStopMediaProxyFail() { + setCallState(CallStopFinal); +} + +void B2BCall::doCallStopFinal() { + // do nothing, the call should be deleted shortly + if(callHandle != NULL) { + delete callHandle; + callHandle = NULL; + } +} + +void B2BCall::setClearingReason(FullClearingReason reason, int code) { + // has a reason already been specified? If so, leave it alone + if(fullClearingReason != Unset) + return; + + fullClearingReason = reason; + if(fullClearingReason == RejectOther) + rejectOtherCode = code; + switch(fullClearingReason) { + case InvalidDestination: + case AuthError: + basicClearingReason = Error; + break; + case NoAnswerCancel: + case NoAnswerTimeout: + basicClearingReason = NoAnswer; + break; + case NoAnswerError: + basicClearingReason = Error; + break; + case RejectBusy: + basicClearingReason = Busy; + break; + case RejectOther: + switch(rejectOtherCode) { + /* case 503: // ambiguous, could also indicate out of funds with a carrier + basicClearingReason = Congestion; + break; */ + default: + basicClearingReason = Error; + break; + }; + break; + case AnsweredALegHangup: + case AnsweredBLegHangup: + case AnsweredLimit: + case AnsweredShutdown: + case AnsweredError: + case AnsweredUnknown: + basicClearingReason = Answered; + break; + default: + basicClearingReason = Error; + break; + }; +} + +void B2BCall::setClearingReasonMediaFail() { + if(connectTime == 0) + setClearingReason(NoAnswerError, -1); + else + setClearingReason(AnsweredError, -1); +} + +void B2BCall::writeCDR() { + std::ostringstream cdrStream; + cdrStream << sourceAddr << ","; + cdrStream << destinationAddr << ","; + cdrStream << contextId << ","; + cdrStream << '"' << basicClearingReasonName[basicClearingReason] << '"' << ","; + cdrStream << fullClearingReason << ","; + cdrStream << rejectOtherCode << ","; + cdrStream << startTime << ","; + if(connectTime == 0) + cdrStream << ","; + else + cdrStream << connectTime << ","; + cdrStream << finishTime << ","; + cdrStream << finishTime - startTime << ","; + if(connectTime != 0) + cdrStream << finishTime - connectTime; + cdrStream << ","; + cdrStream << appRef1 << "," << appRef2 << ","; + cdrHandler.handleRecord(cdrStream.str()); +} + +/* void B2BCall::onTrying() { + setCallState(DialReceived100); +} */ + +void B2BCall::onRinging() { + //callState = CALL_DIAL_180; + setCallState(DialReceived180); +} + +//void B2BCall::onSessionProgress() { + //callState = CALL_DIAL_183; + //setCallState(DialReceived183); +//} + +void B2BCall::onEarlyMedia(const SdpContents& sdp, const in_addr_t& msgSourceAddress) { + setCallState(DialReceivedEarlyAnswer); + try { + setBLegSdp(sdp, msgSourceAddress); + } catch (...) { + // FIXME + setCallState(DialEarlyMediaProxyFail); + B2BUA_LOG_WARNING("onEarlyMedia: exception while calling setBLegSdp"); + setClearingReason(NoAnswerError, -1); + //setCallState(CallStop); + return; + } + //ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get()); + //sis->provideOffer(sdp); + //sis->provisional(183); +} + +void B2BCall::onCancel() { + //callState = CALL_CANCEL; + setCallState(CallerCancel); +} + +// Dial Failure due to ICMP, Timeout, protocol error or other reason +void B2BCall::onFailure(MyAppDialog *myAppDialog) { + + // If we are about to try another route, bLegAppDialogSet will be NULL + if(bLegAppDialogSet == NULL) + return; + + // No need to do anything if it's already been rejected + if(callState == DialRejected) + return; + + if(setCallState(DialFailed)) { + } +} + +// Dial failure due to rejection by remote party +void B2BCall::onRejected(int statusCode, const Data& reason) { + if(setCallState(DialRejected)) { + failureStatusCode = statusCode; + failureReason = new Data(reason); + } +} + + +void B2BCall::onOffer(MyAppDialog *myAppDialog, const SdpContents& sdp, const in_addr_t& msgSourceAddress) { + InviteSession *otherInviteSession = NULL; // used to relay SDP to + // other party + SdpContents *otherSdp = NULL; + if(myAppDialog == aLegAppDialog) { + B2BUA_LOG_DEBUG("received SDP offer from A leg"); + try { + setALegSdp(sdp, msgSourceAddress); + } catch (...) { + // FIXME - + setClearingReasonMediaFail(); + B2BUA_LOG_WARNING("onOffer: exception while calling setALegSdp"); + setCallState(CallStop); + return; + } + if(bLegAppDialog != NULL) { + otherInviteSession = (InviteSession *)(bLegAppDialog->getInviteSession().get()); + otherSdp = (SdpContents *)mediaManager->getALegSdp().clone(); + } + } else if(myAppDialog == bLegAppDialog) { + B2BUA_LOG_DEBUG("received SDP offer from B leg"); + try { + setBLegSdp(sdp, msgSourceAddress); + } catch (...) { + // FIXME + setClearingReasonMediaFail(); + B2BUA_LOG_WARNING("onOffer: exception while calling setBLegSdp"); + setCallState(CallStop); + return; + } + if(aLegAppDialog != NULL) { + otherInviteSession = (InviteSession *)(aLegAppDialog->getInviteSession().get()); + otherSdp = (SdpContents *)mediaManager->getBLegSdp().clone(); + } + } else { + B2BUA_LOG_ERR("onOffer: unrecognised myAppDialog"); + throw new exception; + } + if(callState == CallActive) { + // Must be a re-INVITE, relay to other party + // FIXME - change state + B2BUA_LOG_DEBUG("processing a re-INVITE"); + if(otherInviteSession != NULL) + otherInviteSession->provideOffer(*otherSdp); + else { + B2BUA_LOG_ERR("onOffer: otherInviteSession == NULL"); + throw new exception; // FIXME + } + } + if(otherSdp != NULL) + delete otherSdp; +} + +void B2BCall::onAnswer(MyAppDialog *myAppDialog, const SdpContents& sdp, const in_addr_t& msgSourceAddress) { + mediaManager->setToTag(bLegAppDialog->getDialogId().getLocalTag()); + if(callState != CallActive) { + B2BUA_LOG_DEBUG("received answer"); + // Answer to original INVITE + //callState = CALL_ANSWERED; + setCallState(CallAccepted); + time(&connectTime); + try { + setBLegSdp(sdp, msgSourceAddress); + } catch (...) { + // FIXME - stop the call + setClearingReasonMediaFail(); + B2BUA_LOG_WARNING("onAnswer: exception while processing SDP"); + setCallState(CallStop); + return; + } + } else { + // Answer to re-INVITE + InviteSession *inviteSession = NULL; + SdpContents *otherSdp = NULL; + if(myAppDialog == aLegAppDialog) { + B2BUA_LOG_DEBUG("answer received from A leg"); + setALegSdp(sdp, msgSourceAddress); + inviteSession = (InviteSession *)(bLegAppDialog->getInviteSession().get()); + otherSdp = (SdpContents *)mediaManager->getALegSdp().clone(); + } else { + B2BUA_LOG_DEBUG("answer received from B leg"); + setBLegSdp(sdp, msgSourceAddress); + inviteSession = (InviteSession *)(aLegAppDialog->getInviteSession().get()); + otherSdp = (SdpContents *)mediaManager->getBLegSdp().clone(); + } + inviteSession->provideAnswer(*otherSdp); + if(otherSdp != NULL) + delete otherSdp; + } +} + +void B2BCall::onMediaTimeout() { + B2BUA_LOG_NOTICE("call hangup due to media timeout"); + if(connectTime == 0) + setClearingReason(AnsweredNoMedia, -1); + else + setClearingReason(NoAnswerError, -1); + time(&finishTime); + setCallState(CallStop); +} + +void B2BCall::onHangup(MyAppDialog *myAppDialog) { + if(myAppDialog == aLegAppDialog) { + B2BUA_LOG_DEBUG("call hung up by a leg"); + setClearingReason(AnsweredALegHangup, -1); + setCallState(CallerHangup); + time(&finishTime); + } else if(myAppDialog == bLegAppDialog) { + B2BUA_LOG_DEBUG("call hung up by b leg"); + setClearingReason(AnsweredBLegHangup, -1); + setCallState(CalleeHangup); + time(&finishTime); + } else { + // possible termination of B leg after route fail + B2BUA_LOG_WARNING("B2BCall::onHangup(): unrecognised MyAppDialog"); + } + //time(&finishTime); + //setCallState(CallStop); +} + +void B2BCall::onStopping() { + // FIXME - should any states be handled differently? + switch(callState) { + case CallerCancel: + case AuthorizationFail: + case MediaProxyFail: + case DialEarlyMediaProxyFail: + case CallAcceptedMediaProxyFail: + case CallerHangup: + case CalleeHangup: + case LocalHangup: + case CallStop: + case CallStopMediaProxySuccess: + case CallStopMediaProxyFail: + case CallStopFinal: + return; + default: + onHangup(NULL); + } +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/B2BCall.hxx b/src/libs/resiprocate/b2bua/B2BCall.hxx new file mode 100644 index 00000000..f941285a --- /dev/null +++ b/src/libs/resiprocate/b2bua/B2BCall.hxx @@ -0,0 +1,308 @@ + +#ifndef __B2BCall_h +#define __B2BCall_h + +/* B2BCall models a bridged call between a caller and a callee +*/ + +#include "rutil/Data.hxx" +#include "resip/dum/DialogUsageManager.hxx" + +namespace b2bua +{ + +class B2BCall; +class MyDialogSetHandler; + +} + +#include "AuthorizationManager.hxx" +#include "CallHandle.hxx" +#include "CDRHandler.hxx" +#include "MediaManager.hxx" +#include "MyAppDialog.hxx" + + +namespace b2bua +{ + +class B2BCall { + +protected: + + typedef enum B2BCallState { + NewCall = 0, // just started + CallerCancel, // CANCEL received from A leg + AuthorizationPending, + AuthorizationSuccess, + AuthorizationFail, +// RoutesPending, // routes requested +// RoutesSuccess, +// RoutesFail, +// MediaProxyPending, // Media Proxy requested + MediaProxySuccess, + MediaProxyFail, + ReadyToDial, // Route ready + DialInProgress, // INVITE sent + DialFailed, // Network error, e.g. ICMP + DialRejected, // SIP error received + // error code in data member + // failureStatusCode + SelectAlternateRoute, // Need to select another + // route + DialAborted, // No other carriers + // available, or a failure + // that doesn't require us + // to try another carrier + // e.g. Busy +// DialReceived100, // 100 response received + DialReceived180, // 180 response received +// DialReceived183, // 183 response received + DialReceivedEarlyAnswer, // early answer (SDP) received +// DialEarlyMediaProxyRequested, // Media proxy requested for + // early media + DialEarlyMediaProxySuccess, // Media Proxy ready + DialEarlyMediaProxyFail, // Media Proxy failed + CallAccepted, // 200 received +// CallAcceptedMediaProxyRequested, // Media proxy requested for + // media + CallAcceptedMediaProxySuccess, // Media Proxy ready + CallAcceptedMediaProxyFail, // Media proxy failed + CallActive, // Call in progress + CallerHangup, // Caller has hungup + CalleeHangup, // Callee has hungup + LocalHangup, // B2BUA initiated hangup + CallStop, // Call is stopped +// CallStopMediaProxyNotified, // Media proxy informed + CallStopMediaProxySuccess, // Media proxy acknowledged + CallStopMediaProxyFail, // Media proxy failed to ack + CallStopFinal // Call can be purged from + // the system + }; + + static resip::Data callStateNames[]; + + typedef enum BasicClearingReason { + NoAnswer = 0, // caller gave up/timeout + Busy, // callee indicated busy + Congestion, // callee indicated congestion + Error, // callee indicated error + Answered // call was answered + }; + + static const char *basicClearingReasonName[]; + + typedef enum FullClearingReason { + Unset, + + // No attempted + InvalidDestination, + AuthError, + + // not answered + NoAnswerCancel, + NoAnswerTimeout, + NoAnswerError, // media negotiation failed + + // Rejected + RejectBusy, + RejectOther, // rejectOtherCode = SIP error code + + // Answered + AnsweredALegHangup, // A leg hangup first + AnsweredBLegHangup, // B leg hangup first + AnsweredLimit, // reached limit + AnsweredShutdown, // Answered, B2BUA shutdown + AnsweredError, // An error occured, e.g. during a re-INVITE + AnsweredNoMedia, // Media stopped + AnsweredUnknown // Answered, hangup for unknown reason + }; + + CDRHandler& cdrHandler; + resip::DialogUsageManager& dum; + //CallController *callController; + AuthorizationManager& authorizationManager; + + //static std::list calls; + + // Attributes of the call, from the original INVITE + resip::NameAddr sourceAddr; + resip::Uri destinationAddr; + resip::Data authRealm; + resip::Data authUser; + resip::Data authPassword; + resip::Data srcIp; + resip::Data contextId; + resip::Data accountId; + resip::Data baseIp; + resip::Data controlId; + + //int callState; + + B2BCallState callState; + + BasicClearingReason basicClearingReason; + FullClearingReason fullClearingReason; + int rejectOtherCode; + + // Call time information + time_t startTime; + time_t connectTime; + time_t finishTime; + + // CallHandle from CallController + CallHandle *callHandle; + std::list::iterator callRoute; + resip::Data appRef1; + resip::Data appRef2; + + // If we are waiting for something, this is the timeout + time_t timeout; + + MyAppDialog *aLegAppDialog; + MyAppDialog *bLegAppDialog; + MyAppDialogSet *bLegAppDialogSet; + //resip::SdpContents *aLegSdp; // most recent offer from A leg + //resip::SdpContents *bLegSdp; // most recent offer from B leg + bool earlyAnswerSent; + MediaManager *mediaManager; + // resip::SharedPtr outboundUserProfile; + + int failureStatusCode; + resip::Data *failureReason; + + // Returns true if successful, false if new state is not + // permitted + bool setCallState(B2BCallState newCallState); + bool isCallStatePermitted(B2BCallState newCallState); + const resip::Data& getCallStateName(B2BCallState s); + + void setALegSdp(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress); + void setBLegSdp(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress); + + void doNewCall(); + void doCallerCancel(); + void doAuthorizationPending(); + void doAuthorizationSuccess(); + void doAuthorizationFail(); + void doMediaProxySuccess(); + void doMediaProxyFail(); + void doReadyToDial(); + void doDialFailed(); + void doDialRejected(); + void doSelectAlternateRoute(); + void doDialAborted(); + //void doDialReceived100(); + void doDialReceived180(); + //void doCallDial183(); + void doDialReceivedEarlyAnswer(); + void doDialEarlyMediaProxySuccess(); + void doDialEarlyMediaProxyFail(); + void doCallAccepted(); + void doCallAcceptedMediaProxySuccess(); + void doCallAcceptedMediaProxyFail(); + void doCallActive(); + void doHangup(); + void doCallStop(); + void doCallStopMediaProxySuccess(); + void doCallStopMediaProxyFail(); + void doCallStopFinal(); + + // sets the clearing reason codes if necessary + void setClearingReason(FullClearingReason reason, int code); + void setClearingReasonMediaFail(); + + void writeCDR(); + +public: + + // More basic then B2BCallState, used for reporting + typedef enum CallStatus { + PreDial, // the call hasn't started dialing + Dialing, // the call is dialing + Connected, // the call has connected + Finishing, // the call has been hung up + Unknown // unknown + }; + + void checkProgress(time_t now, bool stopping); + bool isComplete(); + + CallStatus getStatus(); + + //static void setDum(resip::DialogUsageManager *dum); + //static void setCallController(CallController *callController); + + // B2BCall(MyAppDialog *aLegDialog); + B2BCall(CDRHandler& cdrHandler, resip::DialogUsageManager& dum, AuthorizationManager& authorizationManager, MyAppDialog *aLegDialog, const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPassword, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId); + virtual ~B2BCall(); + + void setBLegAppDialog(MyAppDialog *myAppDialog); + + // called every time we go through the main program loop + //static void checkCalls(); + + // For InviteSessionHandler + //void onTrying(); + void onRinging(); + //void onSessionProgress(); + void onEarlyMedia(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress); + void onCancel(); + void onFailure(MyAppDialog *myAppDialog); + void onRejected(int statusCode, const resip::Data& reason); + void onOffer(MyAppDialog *myAppDialog, const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress); + void onAnswer(MyAppDialog *myAppDialog, const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress); + void onMediaTimeout(); + void onHangup(MyAppDialog *myAppDialog); + + // For B2BCallManager + void onStopping(); + + void releaseAppDialog(MyAppDialog *myAppDialog); + void releaseAppDialogSet(MyAppDialogSet *myAppDialogSet); + + friend class MyDialogSetHandler; + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/B2BCallManager.cxx b/src/libs/resiprocate/b2bua/B2BCallManager.cxx new file mode 100644 index 00000000..c66db5db --- /dev/null +++ b/src/libs/resiprocate/b2bua/B2BCallManager.cxx @@ -0,0 +1,135 @@ + + +#include + +#include "B2BCallManager.hxx" +#include "Logging.hxx" + +using namespace b2bua; +using namespace resip; +using namespace std; + +B2BCallManager::B2BCallManager(resip::DialogUsageManager& dum, AuthorizationManager *authorizationManager, CDRHandler& cdrHandler) : dum(dum), authorizationManager(authorizationManager), cdrHandler(cdrHandler) { + stopping = false; + mustStopCalls = false; +} + +B2BCallManager::~B2BCallManager() { +} + +void B2BCallManager::setAuthorizationManager(AuthorizationManager *authorizationManager) { + this->authorizationManager = authorizationManager; +} + +TaskManager::TaskResult B2BCallManager::doTaskProcessing() { + time_t now; + + if(mustStopCalls) { + B2BUA_LOG_NOTICE("notifying calls to stop"); + list::iterator call = calls.begin(); + while(call != calls.end()) { + (*call)->onStopping(); + call++; + } + mustStopCalls = false; + } + + time(&now); + list::iterator i = calls.begin(); + while(i != calls.end()) { + (*i)->checkProgress(now, stopping); + if((*i)->isComplete()) { + B2BCall *call = *i; + i++; + calls.remove(call); + delete call; + } else + i++; + } + if(stopping && calls.begin() == calls.end()) { + B2BUA_LOG_NOTICE("no (more) calls in progress"); + return TaskManager::TaskComplete; + } + return TaskManager::TaskNotComplete; +} + +void B2BCallManager::stop() { + stopping = true; + mustStopCalls = true; +} + +bool B2BCallManager::isStopping() { + return stopping; +} + +void B2BCallManager::onNewCall(MyAppDialog *aLegDialog, const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPassword, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId) { + + B2BCall *call = new B2BCall(cdrHandler, dum, *authorizationManager, aLegDialog, sourceAddr, destinationAddr, authRealm, authUser, authPassword, srcIp, contextId, accountId, baseIp, controlId); + + calls.push_back(call); + +} + +void B2BCallManager::logStats() { + int preDial = 0, dialing = 0, connected = 0, finishing = 0, unknown = 0; + list::iterator call = calls.begin(); + while(call != calls.end()) { + switch((*call)->getStatus()) { + case B2BCall::PreDial: + preDial++; + break; + case B2BCall::Dialing: + dialing++; + break; + case B2BCall::Connected: + connected++; + break; + case B2BCall::Finishing: + finishing++; + break; + default: + unknown++; + break; + } + call++; + } + B2BUA_LOG_NOTICE("call info: preDial = %d, dialing = %d, connected = %d, finishing = %d, unknown = %d, total = %d", preDial, dialing, connected, finishing, unknown, (preDial + dialing + connected + finishing + unknown)); +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/B2BCallManager.hxx b/src/libs/resiprocate/b2bua/B2BCallManager.hxx new file mode 100644 index 00000000..b9f7cf70 --- /dev/null +++ b/src/libs/resiprocate/b2bua/B2BCallManager.hxx @@ -0,0 +1,94 @@ + +#ifndef __B2BCallManager_h +#define __B2BCallManager_h + +#include +#include + + +#include "resip/dum/DialogUsageManager.hxx" + +#include "AuthorizationManager.hxx" +#include "B2BCall.hxx" +#include "CDRHandler.hxx" +#include "TaskManager.hxx" + +namespace b2bua +{ + +class B2BCallManager : public TaskManager::RecurringTask { + +protected: + resip::DialogUsageManager& dum; + AuthorizationManager *authorizationManager; + + std::list calls; + + bool stopping; + bool mustStopCalls; + + CDRHandler& cdrHandler; + +public: + B2BCallManager(resip::DialogUsageManager& dum, AuthorizationManager *authorizationManager, CDRHandler& cdrHandler); + virtual ~B2BCallManager(); + + void setAuthorizationManager(AuthorizationManager *authorizationManager); + + TaskManager::TaskResult doTaskProcessing(); + + /** + * Stop accepting new calls + * Shutdown existing calls + * Blocks until all existing calls stopped + */ + void stop(); + bool isStopping(); + + void onNewCall(MyAppDialog *aLegDialog, const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPassword, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId); + + void logStats(); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/B2BUA.cxx b/src/libs/resiprocate/b2bua/B2BUA.cxx new file mode 100644 index 00000000..0988b296 --- /dev/null +++ b/src/libs/resiprocate/b2bua/B2BUA.cxx @@ -0,0 +1,111 @@ + + +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/ClientAuthManager.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/ServerAuthManager.hxx" + +#include "B2BUA.hxx" +#include "DefaultAuthorizationManager.hxx" +#include "DialogUsageManagerRecurringTask.hxx" +#include "Logging.hxx" +#include "MyAppDialog.hxx" +#include "MyDialogSetHandler.hxx" +#include "MyInviteSessionHandler.hxx" + +using namespace b2bua; +using namespace resip; +using namespace std; + +B2BUA::B2BUA(AuthorizationManager *authorizationManager, CDRHandler& cdrHandler) { + + if(authorizationManager == NULL) { + authorizationManager = new DefaultAuthorizationManager(); + } + + taskManager = new TaskManager(); + + sipStack = new SipStack(); + dialogUsageManager = new DialogUsageManager(*sipStack); + uasMasterProfile = SharedPtr(new MasterProfile); + dialogUsageManager->setMasterProfile(uasMasterProfile); + auto_ptr myAppDialogSetFactory(new MyAppDialogSetFactory); + dialogUsageManager->setAppDialogSetFactory(myAppDialogSetFactory); + + // Set up authentication when we act as UAC + auto_ptr clientAuth(new ClientAuthManager); + dialogUsageManager->setClientAuthManager(clientAuth); + + dialogUsageManager->setDialogSetHandler(new MyDialogSetHandler()); + + DialogUsageManagerRecurringTask *dialogUsageManagerTask = new DialogUsageManagerRecurringTask(*sipStack, *dialogUsageManager); + taskManager->addRecurringTask(dialogUsageManagerTask); + callManager = new B2BCallManager(*dialogUsageManager, authorizationManager, cdrHandler); + taskManager->addRecurringTask(callManager); + + MyInviteSessionHandler *uas = new MyInviteSessionHandler(*dialogUsageManager, *callManager); + dialogUsageManager->setInviteSessionHandler(uas); + +} + +B2BUA::~B2BUA() { +} + +void B2BUA::setAuthorizationManager(AuthorizationManager *authorizationManager) { + this->authorizationManager = authorizationManager; + callManager->setAuthorizationManager(authorizationManager); +} + +void B2BUA::run() { + taskManager->start(); +} + +void B2BUA::logStats() { + callManager->logStats(); +} + +void B2BUA::stop() { + //B2BUA_LOG_CRIT("B2BUA::stop not implemented!"); + //assert(0); + B2BUA_LOG_NOTICE("B2BUA beginning shutdown process"); + taskManager->stop(); +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/B2BUA.hxx b/src/libs/resiprocate/b2bua/B2BUA.hxx new file mode 100644 index 00000000..18bb02a8 --- /dev/null +++ b/src/libs/resiprocate/b2bua/B2BUA.hxx @@ -0,0 +1,102 @@ + +#ifndef __B2BUA_h +#define __B2BUA_h + +#include "resip/stack/SipStack.hxx" +#include "resip/dum/DialogUsageManager.hxx" + +#include "B2BCallManager.hxx" +#include "CDRHandler.hxx" +#include "DefaultAuthorizationManager.hxx" +#include "TaskManager.hxx" + +namespace b2bua +{ + +/** + * Provides the framework for a B2BUA and implements the core activities + * + * Derived classes might extend the way some activities are performed, and + * must define ways to initialise the managers required by the application + */ +class B2BUA { + +protected: + + TaskManager *taskManager; + + B2BCallManager *callManager; + + AuthorizationManager *authorizationManager; +// AuthorizationManager *authorizationManager; +// AccountingManager *accountingManager; + +// std::list calls; + +// MediaManager *mediaManager; + +// resip::ServerAuthManager *serverAuthManager; +// resip::InviteSessionHandler *inviteSessionHandler; + resip::SharedPtr uasMasterProfile; + resip::DialogUsageManager *dialogUsageManager; + resip::SipStack *sipStack; + + B2BUA(AuthorizationManager *authorizationManager, CDRHandler& cdrHandler); + virtual ~B2BUA(); + void setAuthorizationManager(AuthorizationManager *authorizationManager); + +public: + // Run the B2BUA + // only returns when B2BUA stops + virtual void run(); + + // Send some stats about the system to syslog + virtual void logStats(); + + // Indicate to the B2BUA that it should shutdown cleanly + // (stop all calls, wait for all managers to stop) + virtual void stop(); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/CDRHandler.hxx b/src/libs/resiprocate/b2bua/CDRHandler.hxx new file mode 100644 index 00000000..a1514040 --- /dev/null +++ b/src/libs/resiprocate/b2bua/CDRHandler.hxx @@ -0,0 +1,81 @@ + +#ifndef __CDRHandler_h +#define __CDRHandler_h + +#include +#include +#include + +namespace b2bua +{ + +class CDRHandler { + +public: + + + virtual ~CDRHandler() {}; + + virtual void handleRecord(const std::string& record) = 0; + +}; + +class DailyCDRHandler : public CDRHandler { + +protected: + std::string mBasename; + int last_write; + std::ofstream cdrStream; + + int day_number(struct tm* tm); + void updateTime(); + void initFile(struct tm* tm); + +public: + DailyCDRHandler(const char* basename); + ~DailyCDRHandler(); + void handleRecord(const std::string& record); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/CallHandle.cxx b/src/libs/resiprocate/b2bua/CallHandle.cxx new file mode 100644 index 00000000..ec49cb12 --- /dev/null +++ b/src/libs/resiprocate/b2bua/CallHandle.cxx @@ -0,0 +1,48 @@ + +#include "CallHandle.hxx" + +using namespace b2bua; + +CallRoute::~CallRoute() { +} + +CallHandle::~CallHandle() { +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/CallHandle.hxx b/src/libs/resiprocate/b2bua/CallHandle.hxx new file mode 100644 index 00000000..d14031e1 --- /dev/null +++ b/src/libs/resiprocate/b2bua/CallHandle.hxx @@ -0,0 +1,101 @@ + +#ifndef __CallHandle_h +#define __CallHandle_h + +#include +#include + +#include "resip/stack/NameAddr.hxx" +#include "resip/stack/Uri.hxx" +#include "rutil/Data.hxx" +#include "rutil/SharedPtr.hxx" + +namespace b2bua +{ + +#define CC_PERMITTED 0 // Call is permitted +#define CC_AUTH_REQUIRED 1 // Auth is required +#define CC_PAYMENT_REQUIRED 2 // Payment is required +#define CC_IP_DENIED 3 // IP is blocked/unrecognised +#define CC_ERROR 4 // Server error +#define CC_INVALID 5 // Request is invalid +#define CC_PENDING 6 // Waiting for server +#define CC_DESTINATION_INCOMPLETE 7 // Destination number too short +#define CC_DESTINATION_INVALID 8 // Destination invalid +#define CC_TIMEOUT 9 // Timeout waiting for server +#define CC_USER_UNKNOWN 10 // User unknown +#define CC_REALM_UNKNOWN 11 // Realm unknown +#define CC_REQUEST_DENIED 12 // Request denied for + // administrative reason + +class CallRoute { +public: + virtual ~CallRoute(); + virtual const resip::Data& getAppRef1() = 0; + virtual const resip::Data& getAppRef2() = 0; + virtual const resip::Data& getAuthRealm() = 0; + virtual const resip::Data& getAuthUser() = 0; + virtual const resip::Data& getAuthPass() = 0; + virtual const resip::NameAddr& getSourceAddr() = 0; + virtual const resip::NameAddr& getDestinationAddr() = 0; + virtual const resip::Uri& getOutboundProxy() = 0; + virtual const bool isSrvQuery() = 0; +}; + +class CallHandle { +public: + virtual ~CallHandle(); + virtual int getAuthResult() = 0; + virtual const resip::Data& getRealm() = 0; // Realm for client auth, + // if we require further auth + virtual time_t getHangupTime() = 0; // The time to hangup, + // 0 for no limit + virtual bool mustHangup() = 0; + virtual void connect(time_t *connectTime) = 0; // The call connected + virtual void fail(time_t *finishTime) = 0; // The attempt failed, or + // the caller gave up + virtual void finish(time_t *finishTime) = 0; // The call hungup + virtual std::list& getRoutes() = 0; +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/DailyCDRHandler.cxx b/src/libs/resiprocate/b2bua/DailyCDRHandler.cxx new file mode 100644 index 00000000..f0ffaf97 --- /dev/null +++ b/src/libs/resiprocate/b2bua/DailyCDRHandler.cxx @@ -0,0 +1,93 @@ + +#include "CDRHandler.hxx" +#include "Logging.hxx" + +using namespace b2bua; + +DailyCDRHandler::DailyCDRHandler(const char* basename) : + mBasename(basename), + last_write(0) { + +} + +DailyCDRHandler::~DailyCDRHandler() { + if(cdrStream.is_open()) + cdrStream.close(); +} + +void DailyCDRHandler::handleRecord(const std::string& record) { + + // First check the time + updateTime(); + + // Now write to file + cdrStream << record << std::endl; + cdrStream.flush(); +} + +int DailyCDRHandler::day_number(struct tm* tm) { + return (tm->tm_year + 1900) * 10000 + ((tm->tm_mon + 1) * 100) + tm->tm_mday; +} + +void DailyCDRHandler::updateTime() { + time_t now; + time(&now); + struct tm* tm = gmtime(&now); + int x = day_number(tm); + if(x > last_write) { + last_write = x; + initFile(tm); + } +} + +void DailyCDRHandler::initFile(struct tm* tm) { + if(cdrStream.is_open()) { + cdrStream.close(); + } + char buf[200]; + sprintf(buf, "%s-%04d-%02d-%02d.csv", mBasename.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); + cdrStream.open(buf, std::ios::out | std::ios::app); + if(!cdrStream.is_open()) { + B2BUA_LOG_ERR("Failed to open CDR file"); + throw; + } +} + + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/DefaultAuthorizationManager.cxx b/src/libs/resiprocate/b2bua/DefaultAuthorizationManager.cxx new file mode 100644 index 00000000..b0ba6b04 --- /dev/null +++ b/src/libs/resiprocate/b2bua/DefaultAuthorizationManager.cxx @@ -0,0 +1,60 @@ + + + +#include "DefaultAuthorizationManager.hxx" +#include "Logging.hxx" + +using namespace b2bua; + +DefaultAuthorizationManager::DefaultAuthorizationManager() { +} + + +void DefaultAuthorizationManager::getAuthorization() { + B2BUA_LOG_CRIT("DefaultAuthorizationManager::getAuthorization not implemented"); + assert(0); +} + +CallHandle *DefaultAuthorizationManager::authorizeCall(const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPass, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId, time_t startTime) { + B2BUA_LOG_CRIT("DefaultAuthorizationManager::authorizeCall not implemented"); + assert(0); + return NULL; +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/DefaultAuthorizationManager.hxx b/src/libs/resiprocate/b2bua/DefaultAuthorizationManager.hxx new file mode 100644 index 00000000..9f8f657f --- /dev/null +++ b/src/libs/resiprocate/b2bua/DefaultAuthorizationManager.hxx @@ -0,0 +1,60 @@ + +#ifndef __DefaultAuthorizationManager_h +#define __DefaultAuthorizationManager_h + + +#include "AuthorizationManager.hxx" +#include "CallHandle.hxx" + +namespace b2bua +{ + +class DefaultAuthorizationManager : public AuthorizationManager { + +public: + DefaultAuthorizationManager(); + void getAuthorization(); + CallHandle *authorizeCall(const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPass, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId, time_t startTime); +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/DialogUsageManagerRecurringTask.cxx b/src/libs/resiprocate/b2bua/DialogUsageManagerRecurringTask.cxx new file mode 100644 index 00000000..4068e17c --- /dev/null +++ b/src/libs/resiprocate/b2bua/DialogUsageManagerRecurringTask.cxx @@ -0,0 +1,91 @@ + + +#include "resip/dum/DialogUsageManager.hxx" + +#include "DialogUsageManagerRecurringTask.hxx" +#include "Logging.hxx" +#include "TaskManager.hxx" + +using namespace b2bua; +using namespace resip; +using namespace std; + +DialogUsageManagerRecurringTask::DialogUsageManagerRecurringTask(resip::SipStack& sipStack, resip::DialogUsageManager& dum) : sipStack(sipStack), dum(dum) { + stopping = false; +} + +TaskManager::TaskResult DialogUsageManagerRecurringTask::doTaskProcessing() { + FdSet fdset; + sipStack.buildFdSet(fdset); + // FIXME - allow time for other tasks + int err = fdset.selectMilliSeconds(resipMin((int)sipStack.getTimeTillNextProcessMS(), 50)); + if(err == -1) { + if(errno != EINTR) { + B2BUA_LOG_ERR("fdset.select returned error code %d", err); + assert(0); // FIXME + } + } + // Process all SIP stack activity + sipStack.process(fdset); + // Process all DUM activity + //try { + while(dum.process()); + //} catch(...) { + // B2BUA_LOG_ERR("Exception in dum.process(), continuing anyway"); + //} + + // FIXME If sipStack and dum are finished, then we should return TaskDone + if(!stopping) + return TaskManager::TaskNotComplete; + + time_t t; + time(&t); + if(t > stopTime) + return TaskManager::TaskIndefinite; + else + return TaskManager::TaskNotComplete; +} + +void DialogUsageManagerRecurringTask::stop() { + stopping = true; + time(&stopTime); + stopTime += STOP_TIMEOUT; +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/DialogUsageManagerRecurringTask.hxx b/src/libs/resiprocate/b2bua/DialogUsageManagerRecurringTask.hxx new file mode 100644 index 00000000..821d175d --- /dev/null +++ b/src/libs/resiprocate/b2bua/DialogUsageManagerRecurringTask.hxx @@ -0,0 +1,72 @@ + +#ifndef __DialogUsageManagerRecurringTask_h +#define __DialogUsageManagerRecurringTask_h + +#include "resip/stack/SipStack.hxx" +#include "resip/dum/DialogUsageManager.hxx" + +#include "TaskManager.hxx" + +namespace b2bua +{ + +#define STOP_TIMEOUT 3 // how many seconds to wait before shutdown + +class DialogUsageManagerRecurringTask : public TaskManager::RecurringTask { + +protected: + resip::SipStack& sipStack; + resip::DialogUsageManager& dum; + bool stopping; + time_t stopTime; + +public: + DialogUsageManagerRecurringTask(resip::SipStack& sipStack, resip::DialogUsageManager& dum); + TaskManager::TaskResult doTaskProcessing(); + + // let's the task know the application would like to stop soon + void stop(); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/DummyRegistrationPersistenceManager.cxx b/src/libs/resiprocate/b2bua/DummyRegistrationPersistenceManager.cxx new file mode 100644 index 00000000..bf545613 --- /dev/null +++ b/src/libs/resiprocate/b2bua/DummyRegistrationPersistenceManager.cxx @@ -0,0 +1,75 @@ + + +#include "DummyRegistrationPersistenceManager.hxx" + +using namespace b2bua; + +void DummyRegistrationPersistenceManager::addAor(const resip::Uri& aor, const resip::ContactList contacts = resip::ContactList()) { +} + +void DummyRegistrationPersistenceManager::removeAor(const resip::Uri& aor) { +} + +bool DummyRegistrationPersistenceManager::aorIsRegistered(const resip::Uri& aor) { + return false; +} + +void DummyRegistrationPersistenceManager::lockRecord(const resip::Uri& aor) { +} + +void DummyRegistrationPersistenceManager::unlockRecord(const resip::Uri& aor) { +} + +resip::RegistrationPersistenceManager::UriList DummyRegistrationPersistenceManager::getAors() { + return resip::RegistrationPersistenceManager::UriList(); +} + +resip::RegistrationPersistenceManager::update_status_t DummyRegistrationPersistenceManager::updateContact(const resip::Uri& aor, const resip::Uri& contact, time_t expires, float q) { + return CONTACT_CREATED; +} + +void DummyRegistrationPersistenceManager::removeContact(const resip::Uri& aor, const resip::Uri& contact) { +} + +resip::ContactList DummyRegistrationPersistenceManager::getContacts(const resip::Uri& aor) { + return resip::ContactList(); +} + + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/DummyRegistrationPersistenceManager.hxx b/src/libs/resiprocate/b2bua/DummyRegistrationPersistenceManager.hxx new file mode 100644 index 00000000..1e9caa76 --- /dev/null +++ b/src/libs/resiprocate/b2bua/DummyRegistrationPersistenceManager.hxx @@ -0,0 +1,67 @@ + +#ifndef __DummyRegistrationPersistenceManager_h +#define __DummyRegistrationPersistenceManager_h + +#include "resip/dum/ContactInstanceRecord.hxx" +#include "resip/dum/RegistrationPersistenceManager.hxx" + +namespace b2bua +{ + +class DummyRegistrationPersistenceManager : public resip::RegistrationPersistenceManager { +public: + + void addAor(const resip::Uri& aor, const resip::ContactList contacts); + void removeAor(const resip::Uri& aor); + bool aorIsRegistered(const resip::Uri& aor); + void lockRecord(const resip::Uri& aor); + void unlockRecord(const resip::Uri& aor); + UriList getAors(); + update_status_t updateContact(const resip::Uri& aor, const resip::Uri& contact, time_t expires, float q = -1); + void removeContact(const resip::Uri& aor, const resip::Uri& contact); + resip::ContactList getContacts(const resip::Uri& aor); + + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/DummyServerRegistrationHandler.cxx b/src/libs/resiprocate/b2bua/DummyServerRegistrationHandler.cxx new file mode 100644 index 00000000..eabe5d7e --- /dev/null +++ b/src/libs/resiprocate/b2bua/DummyServerRegistrationHandler.cxx @@ -0,0 +1,34 @@ + + +#include "resip/stack/SipMessage.hxx" + +#include "resip/dum/ServerRegistration.hxx" + +#include "DummyServerRegistrationHandler.hxx" +#include "Logging.hxx" + +using namespace b2bua; +using namespace resip; +using namespace std; + +void DummyServerRegistrationHandler::onRefresh(ServerRegistrationHandle sr, const SipMessage& reg) { + sr->accept(200); +} + +void DummyServerRegistrationHandler::onRemove(ServerRegistrationHandle sr, const SipMessage& reg) { + sr->accept(200); +} + +void DummyServerRegistrationHandler::onRemoveAll(ServerRegistrationHandle sr, const SipMessage& reg) { + sr->accept(200); +} + +void DummyServerRegistrationHandler::onAdd(ServerRegistrationHandle sr, const SipMessage& reg) { + B2BUA_LOG_INFO("client trying to register, username=%s", reg.header(h_From).uri().user().c_str()); + sr->accept(200); +} + +void DummyServerRegistrationHandler::onQuery(ServerRegistrationHandle sr, const SipMessage& reg) { + sr->accept(200); +} + diff --git a/src/libs/resiprocate/b2bua/DummyServerRegistrationHandler.hxx b/src/libs/resiprocate/b2bua/DummyServerRegistrationHandler.hxx new file mode 100644 index 00000000..511db9e5 --- /dev/null +++ b/src/libs/resiprocate/b2bua/DummyServerRegistrationHandler.hxx @@ -0,0 +1,62 @@ + +#ifndef __DummyServerRegistrationHandler_h +#define __DummyServerRegistrationHandler_h + +#include "resip/dum/RegistrationHandler.hxx" + +namespace b2bua +{ + +class DummyServerRegistrationHandler : public resip::ServerRegistrationHandler { + +public: +// virtual ~ServerRegistrationHandler(); + void onRefresh(resip::ServerRegistrationHandle, const resip::SipMessage& reg); + void onRemove(resip::ServerRegistrationHandle, const resip::SipMessage& reg); + void onRemoveAll(resip::ServerRegistrationHandle, const resip::SipMessage& reg); + void onAdd(resip::ServerRegistrationHandle, const resip::SipMessage& reg); + void onQuery(resip::ServerRegistrationHandle, const resip::SipMessage& reg); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/Logging.hxx b/src/libs/resiprocate/b2bua/Logging.hxx new file mode 100644 index 00000000..f0b91aa6 --- /dev/null +++ b/src/libs/resiprocate/b2bua/Logging.hxx @@ -0,0 +1,71 @@ + +/* + + Logging.h provides definitions for logging. + + Possible implementations of these definitions are: + - no logging - empty definitions for production use + - syslog - pass all messages to syslog + - file or stream - log all messages to a file or stream + - resip - log all messages to the underlying resiprocate logging method + - Log4C - pass all logging to Log4c +*/ + +#ifndef __Logging_h +#define __Logging_h + + +// syslog implementation + +#include + +#define B2BUA_LOG_INIT(n) openlog(n, LOG_ODELAY | LOG_PID, LOG_LOCAL0) + +#define B2BUA_LOG_DEBUG(fmt, ...) syslog(LOG_DEBUG, "b2bua:%s:%d: " #fmt, __FILE__, __LINE__, ## __VA_ARGS__) +#define B2BUA_LOG_INFO(fmt, ...) syslog(LOG_INFO, "b2bua:%s:%d: " #fmt, __FILE__, __LINE__, ## __VA_ARGS__) +#define B2BUA_LOG_NOTICE(fmt, ...) syslog(LOG_NOTICE, "b2bua:%s:%d: " #fmt, __FILE__, __LINE__, ## __VA_ARGS__) +#define B2BUA_LOG_WARNING(fmt, ...) syslog(LOG_WARNING, "b2bua:%s:%d: " #fmt, __FILE__, __LINE__, ## __VA_ARGS__) +#define B2BUA_LOG_ERR(fmt, ...) syslog(LOG_ERR, "b2bua:%s:%d: " #fmt, __FILE__, __LINE__, ## __VA_ARGS__) +#define B2BUA_LOG_CRIT(fmt, ...) syslog(LOG_CRIT, "b2bua:%s:%d: " #fmt, __FILE__, __LINE__, ## __VA_ARGS__) + + +#endif + + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/Makefile b/src/libs/resiprocate/b2bua/Makefile new file mode 100644 index 00000000..434e8a81 --- /dev/null +++ b/src/libs/resiprocate/b2bua/Makefile @@ -0,0 +1,83 @@ +# $Id: Makefile,v 1.144 2004/05/18 01:40:48 jason Exp $ + +BUILD = ../build +include $(BUILD)/Makefile.pre + +PACKAGES += DUM RESIP RUTIL OPENSSL ARES PTHREAD + +CXXFLAGS += -I.. +CODE_SUBDIRS = +TARGET_LIBRARY = libb2bua +TESTPROGRAMS = + +SRC = \ + AuthenticationManager.cxx \ + B2BCall.cxx \ + B2BCallManager.cxx \ + B2BUA.cxx \ + CallHandle.cxx \ + DailyCDRHandler.cxx \ + DefaultAuthorizationManager.cxx \ + DialogUsageManagerRecurringTask.cxx \ + DummyRegistrationPersistenceManager.cxx \ + DummyServerRegistrationHandler.cxx \ + MediaManager.cxx \ + MediaProxy.cxx \ + MyAppDialog.cxx \ + MyDialogSetHandler.cxx \ + MyInviteSessionHandler.cxx \ + RtpProxyRecurringTask.cxx \ + RtpProxyUtil.cxx \ + TaskManager.cxx + +include $(BUILD)/Makefile.post + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# . +# +############################################################################## diff --git a/src/libs/resiprocate/b2bua/MediaManager.cxx b/src/libs/resiprocate/b2bua/MediaManager.cxx new file mode 100644 index 00000000..633e6cf1 --- /dev/null +++ b/src/libs/resiprocate/b2bua/MediaManager.cxx @@ -0,0 +1,112 @@ + +#include "rutil/Data.hxx" + +#include "MediaManager.hxx" + +using namespace b2bua; +using namespace resip; +using namespace std; + +Data MediaManager::proxyAddress; + +void MediaManager::setProxyAddress(const Data& proxyAddress) { + MediaManager::proxyAddress = proxyAddress; +}; + +MediaManager::MediaManager(B2BCall& b2BCall) : b2BCall(b2BCall) { + aLegProxy = NULL; + bLegProxy = NULL; + rtpProxyUtil = NULL; +}; + +MediaManager::MediaManager(B2BCall& b2BCall, const Data& callId, const Data& fromTag, const Data& toTag) : b2BCall(b2BCall), callId(callId), fromTag(fromTag), toTag(toTag) { + aLegProxy = NULL; + bLegProxy = NULL; + rtpProxyUtil = NULL; +}; + +MediaManager::~MediaManager() { + if(aLegProxy != NULL) + delete aLegProxy; + if(bLegProxy != NULL) + delete bLegProxy; + if(rtpProxyUtil != NULL) + delete rtpProxyUtil; +}; + +void MediaManager::setFromTag(const Data& fromTag) { + this->fromTag = fromTag; +}; + +void MediaManager::setToTag(const Data& toTag) { + this->toTag = toTag; +}; + +int MediaManager::setALegSdp(const SdpContents& sdp, const in_addr_t& msgSourceAddress) { + aLegSdp = sdp; + if(aLegProxy == NULL) + aLegProxy = new MediaProxy(*this); + return aLegProxy->updateSdp(aLegSdp, msgSourceAddress); +}; + +SdpContents& MediaManager::getALegSdp() { + if(aLegProxy == NULL) { + throw new exception; + } + return aLegProxy->getSdp(); +}; + +int MediaManager::setBLegSdp(const SdpContents& sdp, const in_addr_t& msgSourceAddress) { + bLegSdp = sdp; + if(bLegProxy == NULL) + bLegProxy = new MediaProxy(*this); + return bLegProxy->updateSdp(bLegSdp, msgSourceAddress); +}; + +SdpContents& MediaManager::getBLegSdp() { + if(bLegProxy == NULL) + throw new exception; + return bLegProxy->getSdp(); +}; + +void MediaManager::onMediaTimeout() { + b2BCall.onMediaTimeout(); +}; + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/MediaManager.hxx b/src/libs/resiprocate/b2bua/MediaManager.hxx new file mode 100644 index 00000000..01b99e37 --- /dev/null +++ b/src/libs/resiprocate/b2bua/MediaManager.hxx @@ -0,0 +1,130 @@ + +#ifndef __MediaManager_h +#define __MediaManager_h + +#include "resip/stack/SdpContents.hxx" +#include "rutil/Data.hxx" + +namespace b2bua +{ + +class MediaManager; + +} + +#include "B2BCall.hxx" +#include "MediaProxy.hxx" +#include "RtpProxyUtil.hxx" + +namespace b2bua +{ + +/* + Each B2BCall requires a MediaManager to handle the SDP and media + (typically RTP/AVP). + + MediaManager is responsible for: + - validating the content of the SDP (IP4 only, UDP only, etc) + - creating and destroying pairs of MediaProxy instances as needed + - rewriting the SDP connection addresses and port numbers + - hiding information about the remote party (e.g. phone, web, fax) +*/ + +// FIXME - use enum types +#define MM_SDP_OK 0 // The SDP was acceptable +#define MM_SDP_BAD 1 // The SDP was not acceptable + +class B2BCall; + +class MediaManager : public RtpProxyUtil::TimeoutListener { + +private: + + static resip::Data proxyAddress; + + B2BCall& b2BCall; + + resip::Data callId; // from A Leg + resip::Data fromTag; // `from' tag for A leg party + resip::Data toTag; // `to' tag for B leg party + resip::SdpContents aLegSdp; + resip::SdpContents newALegSdp; + resip::SdpContents bLegSdp; + resip::SdpContents newBLegSdp; + + RtpProxyUtil *rtpProxyUtil; // Access to rtpproxy + + MediaProxy *aLegProxy; // Proxies on behalf of A leg + MediaProxy *bLegProxy; // Proxies on behalf of B leg + +public: + friend class MediaProxy; + + // Set the proxyAddress + static void setProxyAddress(const resip::Data& proxyAddress); + + // Instantiate a MediaManager + MediaManager(B2BCall& b2BCall); + MediaManager(B2BCall& b2BCall, const resip::Data& callId, const resip::Data& fromTag, const resip::Data& toTag); + virtual ~MediaManager(); + + // Set the From tag + void setFromTag(const resip::Data& fromTag); + // Set the To tag + void setToTag(const resip::Data& toTag); + + // inspect and save an offer (A leg) + int setALegSdp(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress); + // generate an offer (to send to B leg) + resip::SdpContents& getALegSdp(); + + // inspect and save an answer (B leg) + int setBLegSdp(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress); + // generate an answer (to send to A leg) + resip::SdpContents& getBLegSdp(); + + void onMediaTimeout(); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/MediaProxy.cxx b/src/libs/resiprocate/b2bua/MediaProxy.cxx new file mode 100644 index 00000000..0d46a06d --- /dev/null +++ b/src/libs/resiprocate/b2bua/MediaProxy.cxx @@ -0,0 +1,218 @@ + +#include +#include + +#include "Logging.hxx" +#include "MediaProxy.hxx" + +using namespace b2bua; +using namespace resip; +using namespace std; + +bool MediaProxy::mNatHelper = false; + +void MediaProxy::setNatHelper(bool natHelper) { + mNatHelper = natHelper; +} + +MediaProxy::MediaProxy(MediaManager& mediaManager) : mediaManager(mediaManager) { + originalSdp = NULL; + newSdp = NULL; +} + +MediaProxy::~MediaProxy() { + if(originalSdp != NULL) + delete originalSdp; + if(newSdp != NULL) + delete newSdp; +} + +int MediaProxy::updateSdp(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress) { + bool callerAsymmetric = true; + bool calleeAsymmetric = true; + if(originalSdp != NULL) + delete originalSdp; + originalSdp = (SdpContents *)sdp.clone(); + if(newSdp != NULL) + delete newSdp; + newSdp = (SdpContents *)sdp.clone(); + + // Process the Origin + if(originalSdp->session().origin().getAddressType() != SdpContents::IP4) { + // FIXME - implement IPv6 + B2BUA_LOG_WARNING("processing SDP origin, only IP4 is supported"); + return MM_SDP_BAD; + } + // FIXME - set username also + newSdp->session().origin().setAddress(MediaManager::proxyAddress); + + // Process the default connection + if(originalSdp->session().connection().getAddressType() != SdpContents::IP4) { + // FIXME - implement IPv6 + B2BUA_LOG_WARNING("processing SDP connection, only IP4 is supported"); + return MM_SDP_BAD; + } + newSdp->session().connection().setAddress(MediaManager::proxyAddress); + + newSdp->session().clearMedium(); + list::iterator i = originalSdp->session().media().begin(); + while(i != originalSdp->session().media().end()) { + if(allowProtocol((*i).protocol())) { + if(newSdp->session().media().size() > 0) { + // FIXME + B2BUA_LOG_WARNING("only one medium definition supported"); + return MM_SDP_BAD; + } + struct MediaProxy::EndPoint endpoint; + endpoint.address = originalSdp->session().connection().getAddress(); + // Should we adjust the address because of NAT? + if(mNatHelper) { + in_addr_t sdpConnectionAddr = inet_addr(originalSdp->session().connection().getAddress().c_str()); + // Is the endpoint a private address? + bool addressIsPrivate = isAddressPrivate(sdpConnectionAddr); + if(addressIsPrivate) + B2BUA_LOG_WARNING("IP address in SDP is private: %s", originalSdp->session().connection().getAddress().c_str()); + + // Does the endpoint address not match the msg source address? + bool matchesMsgSource = false; + if(sdpConnectionAddr == msgSourceAddress) + matchesMsgSource = true; + + if(addressIsPrivate && !matchesMsgSource) { + // use the msg source address instead of the address in the SDP + struct in_addr sa; + sa.s_addr = msgSourceAddress; + endpoint.address = Data(inet_ntoa(sa)); + callerAsymmetric = false; + B2BUA_LOG_WARNING("rewriting NAT address, was %s, using %s", originalSdp->session().connection().getAddress().c_str(), endpoint.address.c_str()); + } + } + // Check for a connection spec + if((*i).getMediumConnections().size() > 1) { + // FIXME - connection for each medium + B2BUA_LOG_WARNING("multiple medium specific connections not supported"); + return MM_SDP_BAD; + } + if((*i).getMediumConnections().size() == 1) { + const SdpContents::Session::Connection& mc = (*i).getMediumConnections().front(); + // FIXME - check address type, etc, or implement operator== + if(!(mc.getAddress() == originalSdp->session().connection().getAddress())) { + B2BUA_LOG_WARNING("medium specific connection doesn't match global connection"); + return MM_SDP_BAD; + } + + } + // Get the old port, insert new port + endpoint.originalPort = (*i).port(); + SdpContents::Session::Medium m(*i); + // FIXME - only needed until more detailed handling of medium specific + // connections is implemented: + //m.getMediumConnections().clear(); + m.setConnection(newSdp->session().connection()); + if(mediaManager.aLegProxy == this) { + // this must be A leg + if(mediaManager.rtpProxyUtil == NULL) { + mediaManager.rtpProxyUtil = new RtpProxyUtil(); + mediaManager.rtpProxyUtil->setTimeoutListener(&mediaManager); + } + endpoint.proxyPort = mediaManager.rtpProxyUtil->setupCaller(mediaManager.callId.c_str(), endpoint.address.c_str(), endpoint.originalPort, mediaManager.fromTag.c_str(), callerAsymmetric); + if(endpoint.proxyPort == 0) + throw new exception; + } else { + // this must be B leg + endpoint.proxyPort = mediaManager.rtpProxyUtil->setupCallee(endpoint.address.c_str(), endpoint.originalPort, mediaManager.toTag.c_str(), calleeAsymmetric); + if(endpoint.proxyPort == 0) + throw new exception; + } + m.setPort(endpoint.proxyPort); + //newMedia.push_back(m); + newSdp->session().addMedium(m); + endpoints.push_back(endpoint); + } else { + B2BUA_LOG_WARNING("media protocol %s not recognised, removed from SDP", (*i).protocol().c_str()); + } + i++; + } + if(endpoints.size() == 0) { + B2BUA_LOG_WARNING("no acceptable media protocol found, try RTP/AVP or UDP"); + return MM_SDP_BAD; + } + + return MM_SDP_OK; + +} + +resip::SdpContents& MediaProxy::getSdp() { + return *newSdp; +} + +bool MediaProxy::allowProtocol(const resip::Data& protocol) { + if(protocol == Data("RTP/AVP") || protocol == Data("UDP") || protocol == Data("udp") || protocol == Data("udptl")) { + return true; + } + return false; +} + +// 10.0.0.0/8 - 10.255.255.255 +// 172.16.0.0/12 - 172.31.255.255 +// 192.168.0.0/16 - 192.168.255.255 +bool MediaProxy::isAddressPrivate(const in_addr_t& subj_addr) { + //in_addr_t subj_addr = inet_addr(address.c_str()); + if(subj_addr == INADDR_NONE) { + B2BUA_LOG_WARNING("subject address is invalid: INADDR_NONE"); + return false; + } + + uint32_t subj_addr1 = ntohl(subj_addr); + uint32_t priv1 = (10 << 24); + uint32_t nm1 = 0xff000000; + uint32_t priv2 = (172 << 24) + (16 << 16); + uint32_t nm2 = 0xfff00000; + uint32_t priv3 = (192 << 24) + (168 << 16); + uint32_t nm3 = 0xffff0000; + + if(((subj_addr1 & nm1) == priv1) || + ((subj_addr1 & nm2) == priv2) || + ((subj_addr1 & nm3) == priv3)) + return true; + + return false; +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/MediaProxy.hxx b/src/libs/resiprocate/b2bua/MediaProxy.hxx new file mode 100644 index 00000000..577f0582 --- /dev/null +++ b/src/libs/resiprocate/b2bua/MediaProxy.hxx @@ -0,0 +1,111 @@ + +#ifndef __MediaProxy_h +#define __MediaProxy_h + +#include "resip/stack/SdpContents.hxx" + +namespace b2bua +{ + +class MediaProxy; + +} + +#include "MediaManager.hxx" + +namespace b2bua +{ + +/* + A generic MediaProxy is based on the SDP from a single endpoint. + + Two MediaProxys must work together to provide a symmetric RTP service + that will get through NAT. The two MediaProxy instances are + synchronised by the MediaManager. + + For an implementation based on rtpproxy, we must also use SIP callID, + from-tag and to-tag, as these are the values rtpproxy expects to use + for uniquely identifying each call. + + Alternatively, we could use our own unique identifier system. +*/ + +class MediaProxy { + +protected: + struct EndPoint { + resip::Data address; // the address we should forward to + unsigned int originalPort; // the port on the dest address + unsigned int proxyPort; // the port we listen with + }; + + static bool mNatHelper; + +private: + MediaManager& mediaManager; // the MediaManager who controls us + std::list endpoints; // the endpoints for each media + // offer in the SDP + resip::SdpContents *originalSdp; // the original SDP + resip::SdpContents *newSdp; // the modified SDP + +public: + static void setNatHelper(bool natHelper); + MediaProxy(MediaManager& mediaManager); + virtual ~MediaProxy(); + int updateSdp(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress); // update the SDP, + // as a result of a + // new offer + resip::SdpContents& getSdp(); // get the SDP + // that should be sent + // to the other party + // we correspond with + bool allowProtocol(const resip::Data& protocol); // discover if protocol + // is permitted/handled + // by this proxy + // implementation + + bool isAddressPrivate(const in_addr_t& subj_addr); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/MyAppDialog.cxx b/src/libs/resiprocate/b2bua/MyAppDialog.cxx new file mode 100644 index 00000000..92403d35 --- /dev/null +++ b/src/libs/resiprocate/b2bua/MyAppDialog.cxx @@ -0,0 +1,100 @@ + +#include "MyAppDialog.hxx" + +using namespace b2bua; +using namespace resip; +using namespace std; + +MyAppDialog::MyAppDialog(HandleManager& ham) : AppDialog(ham) { + setB2BCall(NULL); +} + +MyAppDialog::MyAppDialog(HandleManager& ham, B2BCall *b2BCall) : AppDialog(ham) { + setB2BCall(b2BCall); + // FIXME - is this the B Leg? + if(b2BCall != NULL) + b2BCall->setBLegAppDialog(this); +} + +MyAppDialog::~MyAppDialog() { + if(b2BCall != NULL) + b2BCall->releaseAppDialog(this); +} + +B2BCall *MyAppDialog::getB2BCall() { + return b2BCall; +} + +void MyAppDialog::setB2BCall(B2BCall *b2BCall) { + this->b2BCall = b2BCall; +} + +MyAppDialogSet::MyAppDialogSet(DialogUsageManager& dum) : AppDialogSet(dum) { + this->b2BCall = NULL; + //userProfile = NULL; +} + +MyAppDialogSet::MyAppDialogSet(DialogUsageManager& dum, B2BCall *b2BCall, SharedPtr& userProfile) : AppDialogSet(dum) { + this->b2BCall = b2BCall; + this->userProfile = userProfile; +} + +MyAppDialogSet::~MyAppDialogSet() { + if(b2BCall != NULL) + b2BCall->releaseAppDialogSet(this); +} + +AppDialog* MyAppDialogSet::createAppDialog(const SipMessage& msg) { + return new MyAppDialog(mDum, b2BCall); +} + +/* SharedPtr MyAppDialogSet::getUserProfile() { + return userProfile; +} */ + +SharedPtr MyAppDialogSet::selectUASUserProfile(const SipMessage& msg) { + //return getUserProfile(); + return mDum.getMasterUserProfile(); +} + +AppDialogSet* MyAppDialogSetFactory::createAppDialogSet(DialogUsageManager& dum, const SipMessage& msg) { + return new MyAppDialogSet(dum); +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/MyAppDialog.hxx b/src/libs/resiprocate/b2bua/MyAppDialog.hxx new file mode 100644 index 00000000..bc1ad989 --- /dev/null +++ b/src/libs/resiprocate/b2bua/MyAppDialog.hxx @@ -0,0 +1,107 @@ + +#ifndef __MyAppDialog_h +#define __MyAppDialog_h + +#include "resip/stack/SipMessage.hxx" + +#include "resip/dum/AppDialog.hxx" +#include "resip/dum/AppDialogSet.hxx" +#include "resip/dum/AppDialogSetFactory.hxx" +#include "resip/dum/DialogUsageManager.hxx" + +namespace b2bua +{ + +class MyAppDialog; +class MyAppDialogSet; +class MyDialogSetHandler; + +} + +#include "B2BCall.hxx" + +namespace b2bua +{ + +class MyAppDialog : public resip::AppDialog { + +protected: + B2BCall *b2BCall; + +public: + + MyAppDialog(resip::HandleManager& ham); + MyAppDialog(resip::HandleManager& ham, B2BCall *b2BCall); + virtual ~MyAppDialog(); + B2BCall *getB2BCall(); + void setB2BCall(B2BCall *b2BCall); + +}; + +class MyAppDialogSet : public resip::AppDialogSet { + +protected: + B2BCall *b2BCall; + resip::SharedPtr userProfile; + +public: + MyAppDialogSet(resip::DialogUsageManager& dum); + MyAppDialogSet(resip::DialogUsageManager& dum, B2BCall *b2BCall, resip::SharedPtr& userProfile); + virtual ~MyAppDialogSet(); + virtual resip::AppDialog* createAppDialog(const resip::SipMessage& msg); + // virtual resip::SharedPtr getUserProfile(); + virtual resip::SharedPtr selectUASUserProfile(const resip::SipMessage& msg); + void setB2BCall(B2BCall *b2BCall) + { this->b2BCall = b2BCall; }; + + friend class MyDialogSetHandler; +}; + +class MyAppDialogSetFactory : public resip::AppDialogSetFactory { + +public: + virtual resip::AppDialogSet* createAppDialogSet(resip::DialogUsageManager& dum, const resip::SipMessage& msg); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/MyDialogSetHandler.cxx b/src/libs/resiprocate/b2bua/MyDialogSetHandler.cxx new file mode 100644 index 00000000..1ee005e4 --- /dev/null +++ b/src/libs/resiprocate/b2bua/MyDialogSetHandler.cxx @@ -0,0 +1,64 @@ + + +#include "B2BCall.hxx" +#include "Logging.hxx" +#include "MyAppDialog.hxx" +#include "MyDialogSetHandler.hxx" + +using namespace b2bua; +using namespace resip; +using namespace std; + +MyDialogSetHandler::~MyDialogSetHandler() { +} + +void MyDialogSetHandler::onTrying(resip::AppDialogSetHandle ah, const resip::SipMessage& msg) { +} + +void MyDialogSetHandler::onNonDialogCreatingProvisional(resip::AppDialogSetHandle ah, const resip::SipMessage& msg) { + B2BUA_LOG_DEBUG("received 180 without contact header"); + MyAppDialogSet *ads = dynamic_cast(ah.get()); + if(ads) { + B2BUA_LOG_DEBUG("dialog found"); + if(ads->b2BCall) + ads->b2BCall->doDialReceived180(); + } +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/MyDialogSetHandler.hxx b/src/libs/resiprocate/b2bua/MyDialogSetHandler.hxx new file mode 100644 index 00000000..b692f7d4 --- /dev/null +++ b/src/libs/resiprocate/b2bua/MyDialogSetHandler.hxx @@ -0,0 +1,61 @@ + +#ifndef __MyDialogSetHandler_h +#define __MyDialogSetHandler_h + +#include "resip/dum/DialogSetHandler.hxx" + +namespace b2bua +{ + +class MyDialogSetHandler : public resip::DialogSetHandler { + +public: + ~MyDialogSetHandler(); + + virtual void onTrying(resip::AppDialogSetHandle ah, const resip::SipMessage& msg); + + virtual void onNonDialogCreatingProvisional(resip::AppDialogSetHandle ah, const resip::SipMessage& msg); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/MyInviteSessionHandler.cxx b/src/libs/resiprocate/b2bua/MyInviteSessionHandler.cxx new file mode 100644 index 00000000..816f451a --- /dev/null +++ b/src/libs/resiprocate/b2bua/MyInviteSessionHandler.cxx @@ -0,0 +1,334 @@ + + + +#include "resip/stack/ExtensionHeader.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Tuple.hxx" +#include "rutil/Data.hxx" + +#include "B2BCall.hxx" +#include "B2BCallManager.hxx" +#include "Logging.hxx" +#include "MyInviteSessionHandler.hxx" + +using namespace b2bua; +using namespace resip; +using namespace std; + +MyInviteSessionHandler::MyInviteSessionHandler(DialogUsageManager& dum, B2BCallManager& callManager) : dum(dum), callManager(callManager) { +} + +void MyInviteSessionHandler::onSuccess(ClientRegistrationHandle h, const SipMessage& response) { +} + +void MyInviteSessionHandler::onFailure(ClientRegistrationHandle, const SipMessage& msg) { +} + +void MyInviteSessionHandler::onMessage(resip::Handle, const resip::SipMessage& msg) { +} + +void MyInviteSessionHandler::onMessageSuccess(resip::Handle, const resip::SipMessage&) { +} + +void MyInviteSessionHandler::onMessageFailure(resip::Handle, const resip::SipMessage&) { +} + +void MyInviteSessionHandler::onFailure(ClientInviteSessionHandle cis, const SipMessage& msg) { + B2BUA_LOG_DEBUG("onFailure: %d, %s", msg.header(h_StatusLine).statusCode(), msg.header(h_StatusLine).reason().c_str()); + B2BCall *call = getB2BCall(cis.get()); + if(call == NULL) { + B2BUA_LOG_WARNING("onFailure: unrecognised dialog"); + return; + } + call->onRejected(msg.header(h_StatusLine).statusCode(), msg.header(h_StatusLine).reason()); +} + +void MyInviteSessionHandler::onForkDestroyed(ClientInviteSessionHandle) { +} + +void MyInviteSessionHandler::onInfoSuccess(InviteSessionHandle, const SipMessage& msg) { +} + +void MyInviteSessionHandler::onInfoFailure(InviteSessionHandle, const SipMessage& msg) { +} + +void MyInviteSessionHandler::onProvisional(ClientInviteSessionHandle cis, const SipMessage& msg) { + B2BCall *call = getB2BCall(cis.get()); + if(call == NULL) { + B2BUA_LOG_WARNING("onProvisional: unrecognised dialog"); + return; + } + int code = msg.header(h_StatusLine).statusCode(); + switch(code) { + case 100: + //call->onTrying(); + break; + case 180: + call->onRinging(); + break; + case 183: + //call->onSessionProgress(); + break; + default: + B2BUA_LOG_DEBUG("onProvisional: unknown provisional code (%d)", code); + } +} + +void MyInviteSessionHandler::onConnected(ClientInviteSessionHandle, const SipMessage& msg) { + // FIXME - start charging here instead of waiting for onAnswer +} + +void MyInviteSessionHandler::onStaleCallTimeout(ClientInviteSessionHandle) { +} + +void MyInviteSessionHandler::onConnected(InviteSessionHandle, const SipMessage& msg) { + // FIXME +} + +void MyInviteSessionHandler::onRedirected(ClientInviteSessionHandle, const SipMessage& msg) { +} + +void MyInviteSessionHandler::onAnswer(InviteSessionHandle is, const SipMessage& msg, const SdpContents& sdp) { + MyAppDialog *myAppDialog = (MyAppDialog *)is->getAppDialog().get(); + B2BCall *call = getB2BCall(is.get()); + if(call == NULL) { + B2BUA_LOG_WARNING("onAnswer: unrecognised dialog"); + return; + } + Tuple sourceTuple = msg.getSource(); + in_addr_t msgSourceAddress = sourceTuple.toGenericIPAddress().v4Address.sin_addr.s_addr; + call->onAnswer(myAppDialog, sdp, msgSourceAddress); +} + +void MyInviteSessionHandler::onEarlyMedia(ClientInviteSessionHandle cis, const SipMessage& msg, const SdpContents& sdp) { + B2BCall *call = getB2BCall(cis.get()); + if(call == NULL) { + B2BUA_LOG_WARNING("onEarlyMedia: unrecognised dialog"); + return; + } + Tuple sourceTuple = msg.getSource(); + in_addr_t msgSourceAddress = sourceTuple.toGenericIPAddress().v4Address.sin_addr.s_addr; + call->onEarlyMedia(sdp, msgSourceAddress); +} + +void MyInviteSessionHandler::onOfferRequired(InviteSessionHandle, const SipMessage& msg) { + // FIXME +} + +void MyInviteSessionHandler::onOfferRejected(Handle, const SipMessage *msg) { + // FIXME + B2BUA_LOG_DEBUG("onOfferRejected: %d, %s", msg->header(h_StatusLine).statusCode(), msg->header(h_StatusLine).reason().c_str()); +} + +void MyInviteSessionHandler::onInfo(InviteSessionHandle, const SipMessage& msg) { +} + +void MyInviteSessionHandler::onRefer(InviteSessionHandle, ServerSubscriptionHandle, const SipMessage& msg) { +} + +void MyInviteSessionHandler::onReferAccepted(InviteSessionHandle, ClientSubscriptionHandle, const SipMessage& msg) { +} + +void MyInviteSessionHandler::onReferRejected(InviteSessionHandle, const SipMessage& msg) { +} + +void MyInviteSessionHandler::onReferNoSub(resip::Handle is, const resip::SipMessage& msg) { +} + +void MyInviteSessionHandler::onRemoved(ClientRegistrationHandle) { +} + +int MyInviteSessionHandler::onRequestRetry(ClientRegistrationHandle, int retrySeconds, const SipMessage& response) { +// cerr << "onRequestRetry not implemented" << endl; + //FIXME + B2BUA_LOG_DEBUG("onRequestRetry not implemented"); + return -1; +} + +// New inbound connection +// We must create a B2BCall and insert the B2BCall into the linked list +void MyInviteSessionHandler::onNewSession(ServerInviteSessionHandle sis, InviteSession::OfferAnswerType oat, const SipMessage& msg) { + //cerr << "onNewSession sis" << endl; + + // Are we shutting down? If so, reject the call with SIP code 503 + if(callManager.isStopping()) { + B2BUA_LOG_DEBUG("rejecting inbound call as we are stopping"); + sis->reject(503); + return; + } + + // Check the headers + if(!msg.exists(h_From)) { + B2BUA_LOG_WARNING("inbound connection missing from header, rejecting dialog"); + sis->reject(603); + return; + } + // FIXME - do above for all headers + if(msg.getReceivedTransport() == 0) { + // msg not received from the wire + // FIXME + B2BUA_LOG_WARNING("request not received from the wire"); + sis->reject(603); + } + Tuple sourceTuple = msg.getSource(); + Data sourceIp = Data(inet_ntoa(sourceTuple.toGenericIPAddress().v4Address.sin_addr)); + Data contextId; + Data accountId; + Data baseIp; + Data controlId; + ExtensionHeader xContextId("X-MyB2BUA-Context-ID"); + if(msg.exists(xContextId)) { + const StringCategories& contextIds = msg.header(xContextId); + contextId = Data((contextIds.begin())->value()); + } + ExtensionHeader xAccountId("X-MyB2BUA-Account-ID"); + if(msg.exists(xAccountId)) { + const StringCategories& accountIds = msg.header(xAccountId); + accountId = Data((accountIds.begin())->value()); + } + ExtensionHeader xBaseIp("X-MyB2BUA-Base-IP"); + if(msg.exists(xBaseIp)) { + const StringCategories& baseIps = msg.header(xBaseIp); + baseIp = Data((baseIps.begin())->value()); + } + ExtensionHeader xControlId("X-MyB2BUA-Control-ID"); + if(msg.exists(xControlId)) { + const StringCategories& controlIds = msg.header(xControlId); + controlId = Data((controlIds.begin())->value()); + } + // Now inspect the authentication info + Data authRealm(""); + Data authUser(""); + Data authPassword(""); + if(msg.exists(h_ProxyAuthorizations)) { + for(Auths::const_iterator it = msg.header(h_ProxyAuthorizations).begin(); it != msg.header(h_ProxyAuthorizations).end(); it++) { + if(dum.isMyDomain(it->param(p_realm))) { + authRealm = it->param(p_realm); + authUser = it->param(p_username); + } + } + } + try { + callManager.onNewCall((MyAppDialog *)sis->getAppDialog().get(), msg.header(h_From), msg.header(h_RequestLine).uri(), authRealm, authUser, Data(""), sourceIp, contextId, accountId, baseIp, controlId); + } catch (...) { + B2BUA_LOG_ERR("failed to instantiate B2BCall"); + sis->reject(500); // Indicate temporary error condition + } +} + +void MyInviteSessionHandler::onNewSession(ClientInviteSessionHandle cis, InviteSession::OfferAnswerType oat, const SipMessage& msg) { +} + +void MyInviteSessionHandler::onTerminated(InviteSessionHandle is, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg) { + B2BUA_LOG_DEBUG("onTerminated, reason = %d", reason); + B2BCall *call = getB2BCall(is.get()); + if(call == NULL) { + B2BUA_LOG_WARNING("onTerminated: unrecognised dialog"); + return; + } + MyAppDialog *myAppDialog = (MyAppDialog *)is->getAppDialog().get(); + switch(reason) { + + // received a BYE or CANCEL from peer + case RemoteCancel: + B2BUA_LOG_DEBUG("onTerminated: RemoteCancel"); + call->onCancel(); + break; + + case RemoteBye: + B2BUA_LOG_DEBUG("onTerminated: RemoteBye"); + // MyAppDialog *myAppDialog = (MyAppDialog *)is->getAppDialog().get(); + call->onHangup(myAppDialog); + break; + + // ended by the application + case LocalBye: + B2BUA_LOG_DEBUG("onTerminated: LocalBye"); + //call->onFailure(myAppDialog); + break; + + case Referred: + B2BUA_LOG_DEBUG("onTerminated: Referred"); + //call->onFailure(myAppDialog); + break; + + // ended due to a failure + case Error: + B2BUA_LOG_DEBUG("onTerminated: Error"); + call->onFailure(myAppDialog); + break; + + case Timeout: + B2BUA_LOG_DEBUG("onTerminated: Timeout"); + call->onFailure(myAppDialog); + break; + + case LocalCancel: // ended by the application via Cancel + B2BUA_LOG_DEBUG("onTerminated: LocalCancel"); + // no need to do anything, because we have initiated this cancel + break; + + default: + B2BUA_LOG_WARNING("onTerminated: unhandled case %d", reason); + break; + } +} + +void MyInviteSessionHandler::onOffer(InviteSessionHandle is, const SipMessage& msg, const SdpContents& sdp) { + B2BCall *call = getB2BCall(is.get()); + if(call == NULL) { + B2BUA_LOG_WARNING("onOffer: unrecognised dialog"); + return; + } + B2BUA_LOG_DEBUG("onOffer received"); + MyAppDialog *myAppDialog = (MyAppDialog *)is->getAppDialog().get(); + Tuple sourceTuple = msg.getSource(); + in_addr_t msgSourceAddress = sourceTuple.toGenericIPAddress().v4Address.sin_addr.s_addr; + call->onOffer(myAppDialog, sdp, msgSourceAddress); +} + +/** + * Handy utility functions + */ +B2BCall *MyInviteSessionHandler::getB2BCall(InviteSession *is) { + MyAppDialog *myAppDialog = (MyAppDialog *)is->getAppDialog().get(); + return (B2BCall *)myAppDialog->getB2BCall(); +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/MyInviteSessionHandler.hxx b/src/libs/resiprocate/b2bua/MyInviteSessionHandler.hxx new file mode 100644 index 00000000..c1de9e21 --- /dev/null +++ b/src/libs/resiprocate/b2bua/MyInviteSessionHandler.hxx @@ -0,0 +1,97 @@ + + +#ifndef __MyInviteSessionHandler_h +#define __MyInviteSessionHandler_h + +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/ClientInviteSession.hxx" +#include "resip/dum/InviteSessionHandler.hxx" +#include "resip/dum/ServerInviteSession.hxx" + +namespace b2bua +{ + +class MyInviteSessionHandler : public resip::InviteSessionHandler { + +protected: + resip::DialogUsageManager& dum; + B2BCallManager& callManager; + +public: + MyInviteSessionHandler(resip::DialogUsageManager& dum, B2BCallManager& callManager); + virtual void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response); + virtual void onFailure(resip::ClientRegistrationHandle, const resip::SipMessage& msg); + virtual void onMessage(resip::Handle, const resip::SipMessage& msg); + virtual void onMessageSuccess(resip::Handle, const resip::SipMessage&); + virtual void onMessageFailure(resip::Handle, const resip::SipMessage&); + virtual void onFailure(resip::ClientInviteSessionHandle cis, const resip::SipMessage& msg); + virtual void onForkDestroyed(resip::ClientInviteSessionHandle); + virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onProvisional(resip::ClientInviteSessionHandle cis, const resip::SipMessage& msg); + virtual void onConnected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg); + virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onStaleCallTimeout(resip::ClientInviteSessionHandle); + virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg); + virtual void onAnswer(resip::InviteSessionHandle is, const resip::SipMessage& msg, const resip::SdpContents& sdp); + virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents& sdp); + virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onOfferRejected(resip::Handle, const resip::SipMessage *msg); + virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg); + virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg); + virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onReferNoSub(resip::Handle, const resip::SipMessage&); + virtual void onRemoved(resip::ClientRegistrationHandle); + virtual int onRequestRetry(resip::ClientRegistrationHandle, int retrySeconds, const resip::SipMessage& response); + virtual void onNewSession(resip::ServerInviteSessionHandle sis, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg); + virtual void onNewSession(resip::ClientInviteSessionHandle cis, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg); + virtual void onTerminated(resip::InviteSessionHandle is, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* msg); + virtual void onOffer(resip::InviteSessionHandle is, const resip::SipMessage& msg, const resip::SdpContents& sdp); + + // Utility functions + B2BCall *getB2BCall(resip::InviteSession *is); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/README.txt b/src/libs/resiprocate/b2bua/README.txt new file mode 100644 index 00000000..14e135a7 --- /dev/null +++ b/src/libs/resiprocate/b2bua/README.txt @@ -0,0 +1,94 @@ + +Introduction +============ + +This is a reSIProcate based B2BUA library. + +The library is libb2bua.so + +It is built on top of reSIProcate's dialog usage manager (DUM) + +Building +======== + +In the main reSIProcate directory, when you run configure, you +must explicitly request that the library is built: + +./configure --with-b2bua + +NOTE: configure does NOT include the B2BUA by default. + +Background and technical notes +============================== + +The code has been adapted from a previous project. Consequently, +the initial import to the reSIProcate repository doesn't fully adhere to +reSIProcate coding standards. Nonetheless, it is working code, +so a decision was taken to commit the code as-is, without +modification, and then gradually overhaul it in subsequent commits. + +Some key points about this code: + +- It produces a shared object - to produce an executable, + the B2BUA class must be instantiated and put to work. + Such an example exists in the apps/basicB2BUA directory. A typical + implementation of a B2BUA must implement the following + classes: + - b2bua::CallRoute + - b2bua::CallHandle + - b2bua::AuthorizationManager + - b2bua::B2BUA + +- It relies on rtpproxy from http://www.rtpproxy.org to relay + the media streams. There are also various patches for + rtpproxy 0.2: + - rtpproxy sends notification to the B2BUA on media timeout + - fix a file descriptor bug + - timeout on either direction + The rtpproxy patches have been posted on the rtpproxy mailing + list: + + http://lists.rtpproxy.org/pipermail/users/2008-May/000016.html + +Daniel Pocock +daniel@pocock.com.au + + + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/RtpProxyRecurringTask.cxx b/src/libs/resiprocate/b2bua/RtpProxyRecurringTask.cxx new file mode 100644 index 00000000..9faae5ec --- /dev/null +++ b/src/libs/resiprocate/b2bua/RtpProxyRecurringTask.cxx @@ -0,0 +1,54 @@ + +#include "RtpProxyRecurringTask.hxx" +#include "RtpProxyUtil.hxx" + +using namespace b2bua; + +RtpProxyRecurringTask::RtpProxyRecurringTask() { +} + +TaskManager::TaskResult RtpProxyRecurringTask::doTaskProcessing() { + RtpProxyUtil::do_timeouts(); + return TaskManager::TaskIndefinite; +} + +void RtpProxyRecurringTask::stop() { +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/RtpProxyRecurringTask.hxx b/src/libs/resiprocate/b2bua/RtpProxyRecurringTask.hxx new file mode 100644 index 00000000..ab8f5d21 --- /dev/null +++ b/src/libs/resiprocate/b2bua/RtpProxyRecurringTask.hxx @@ -0,0 +1,68 @@ + +#ifndef __RtpProxyRecurringTask_h +#define __RtpProxyRecurringTask_h + + +#include "TaskManager.hxx" + +namespace b2bua +{ + +#define STOP_TIMEOUT 3 // how many seconds to wait before shutdown + +class RtpProxyRecurringTask : public TaskManager::RecurringTask { + +protected: + bool stopping; + time_t stopTime; + +public: + RtpProxyRecurringTask(); + TaskManager::TaskResult doTaskProcessing(); + + // let's the task know the application would like to stop soon + void stop(); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/RtpProxyUtil.cxx b/src/libs/resiprocate/b2bua/RtpProxyUtil.cxx new file mode 100644 index 00000000..e989a0ca --- /dev/null +++ b/src/libs/resiprocate/b2bua/RtpProxyUtil.cxx @@ -0,0 +1,488 @@ + +/* Todo: + - handle re-INVITE + - share a socket? + - test socket when app starts + - release ports when object destroyed +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "Logging.hxx" +#include "RtpProxyUtil.hxx" + +#define STR2IOVEC(sx, ix) {(ix).iov_base = (sx); (ix).iov_len = strlen((sx));} + +#define RTPPROXY_RETRY_COUNT 3 + +using namespace b2bua; +using namespace std; + +int RtpProxyUtil::umode = 0; +char *RtpProxyUtil::rtpproxy_sock = (char *)DEFAULT_RTPPROXY_SOCK; +int RtpProxyUtil::controlfd = 0; +char *RtpProxyUtil::timeout_sock = (char *)DEFAULT_RTPPROXY_TIMEOUT_SOCK; +int RtpProxyUtil::timeoutfd = 0; +int RtpProxyUtil::timeout_clientfd = -1; +int RtpProxyUtil::rtpproxy_retr = DEFAULT_RTPPROXY_RETR; +int RtpProxyUtil::rtpproxy_tout = DEFAULT_RTPPROXY_TOUT; + +map RtpProxyUtil::proxies; + +void RtpProxyUtil::setSocket(const char *socket) { + if((rtpproxy_sock = (char *)malloc(strlen(socket) + 1)) == NULL) { + B2BUA_LOG_ERR("setSocket: malloc failed"); + throw; + } + strcpy(rtpproxy_sock, socket); +} + +void RtpProxyUtil::setTimeoutSocket(const char *socket) { + if((timeout_sock = (char *)malloc(strlen(socket) + 1)) == NULL) { + B2BUA_LOG_ERR("setSocket: malloc failed"); + throw; + } + strcpy(timeout_sock, socket); +} + +void RtpProxyUtil::init() { + umode = 0; +// rtpproxy_sock = DEFAULT_RTPPROXY_SOCK; +// timeout_sock = DEFAULT_RTPPROXY_TIMEOUT_SOCK; + rtpproxy_retr = DEFAULT_RTPPROXY_RETR; + rtpproxy_tout = DEFAULT_RTPPROXY_TOUT; + + int len; + struct sockaddr_un local; + + int flags; + + if ((timeoutfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + B2BUA_LOG_ERR("socket: %m"); + exit(1); // FIXME + } + + local.sun_family = AF_UNIX; + strcpy(local.sun_path, timeout_sock); + unlink(local.sun_path); + len = strlen(local.sun_path) + sizeof(local.sun_family); + if (bind(timeoutfd, (struct sockaddr *)&local, len) == -1) { + B2BUA_LOG_ERR("bind: %m"); + exit(1); // FIXME + } + + if (listen(timeoutfd, 5) == -1) { + B2BUA_LOG_ERR("listen: %m"); + exit(1); // FIXME + } + + flags = fcntl(timeoutfd, F_GETFL); + flags |= O_NONBLOCK; + fcntl(timeoutfd, F_SETFL, flags); + + timeout_clientfd = -1; + + B2BUA_LOG_NOTICE("telling rtpproxy to flush calls"); + // Check the version + struct iovec v[2] = {{NULL, 0}, {(char *)"x", 1}}; + char *cp = sendCommandRetry(RTPPROXY_RETRY_COUNT, v, 2, ""); + if(cp == NULL) + throw new exception; +} + +void RtpProxyUtil::do_timeouts() { + // check for new connections with accept + // read any data with read + socklen_t t; + struct sockaddr_un remote; + int flags; + int n; + char buf[100]; + int p1, p2; + + if(timeout_clientfd == -1) { + t = sizeof(remote); + if((timeout_clientfd = accept(timeoutfd, (struct sockaddr *)&remote, &t)) == -1) { + if(errno == EAGAIN) { + // no connections coming in from rtpproxy + return; + } + B2BUA_LOG_ERR("accept: %m"); + exit(1); + } + B2BUA_LOG_DEBUG("accepted a new connection from rtpproxy"); + flags = fcntl(timeout_clientfd, F_GETFL); + flags |= O_NONBLOCK; + fcntl(timeout_clientfd, F_SETFL, flags); + } + + n = recv(timeout_clientfd, buf, 100, 0); + if (n == -1) { + if (errno != EAGAIN) { + // FIXME + B2BUA_LOG_ERR("recv: %m"); + close(timeout_clientfd); + timeout_clientfd = -1; + } + return; + } + if(n== 0) { + // n = 0 means that socket closed remotely + timeout_clientfd = -1; + return; + } + + buf[n] = 0; + if((n = sscanf(buf, "%d %d\n", &p1, &p2)) != 2) { + B2BUA_LOG_WARNING("invalid number of arguments from rtpproxy_timeout client [%s]", buf); + } else { + B2BUA_LOG_DEBUG("timeout on ports %d %d", p1, p2); + if(proxies.count(p1) == 1) { + RtpProxyUtil *proxy = proxies.find(p1)->second; + proxy->mediaTimeout(); + } + } +} + + +RtpProxyUtil::RtpProxyUtil() { + timeoutListener = NULL; + valid = true; + mypid = getpid(); + myseqn = 0; + callID = NULL; + callerAddr = NULL; + callerPort = 0; + calleeAddr = NULL; + calleePort = 0; + fromTag = NULL; + toTag = NULL; + + callerProxyPort = 0; + calleeProxyPort = 0; + + // Check the version + struct iovec v[2] = {{NULL, 0}, {(char *)"V", 1}}; + char *cp = sendCommandRetry(RTPPROXY_RETRY_COUNT, v, 2, gencookie()); + if(cp == NULL) + throw new exception; + +} + +RtpProxyUtil::~RtpProxyUtil() { + + if(callerProxyPort != 0) + proxies.erase(callerProxyPort); + if(calleeProxyPort != 0) + proxies.erase(calleeProxyPort); + + struct iovec v[1 + 4 + 3] = {{NULL, 0}, {(char *)"D", 1}, {(char *)" ", 1}, {NULL, 0}, {(char *)" ", 1}, {NULL, 0}, {(char *)" ", 1}, {NULL, 0}}; + STR2IOVEC(callID, v[3]); + STR2IOVEC(fromTag, v[5]); + if(toTag != NULL) + STR2IOVEC(toTag, v[7]); + // ignore return value + sendCommandRetry(RTPPROXY_RETRY_COUNT, v, (toTag != NULL) ? 8 : 6, gencookie()); + + if(callID != NULL) + free(callID); + if(callerAddr != NULL) + free(callerAddr); + if(calleeAddr != NULL) + free(calleeAddr); + if(fromTag != NULL) + free(fromTag); + if(toTag != NULL) + free(toTag); + +} + +void RtpProxyUtil::setTimeoutListener(TimeoutListener *timeoutListener) { + this->timeoutListener = timeoutListener; +} + +void RtpProxyUtil::mediaTimeout() { + valid = false; + if(timeoutListener != NULL) + timeoutListener->onMediaTimeout(); +} + +unsigned int RtpProxyUtil::setupCaller(const char *callID, const char *callerAddr, int callerPort, const char *fromTag, bool callerAsymmetric) { + if(this->callID != NULL) + free(this->callID); + if((this->callID=(char *)malloc(strlen(callID) + 1))==NULL) { + return 0; + } + if(this->callerAddr != NULL) + free(this->callerAddr); + if((this->callerAddr=(char *)malloc(strlen(callerAddr) + 1))==NULL) { + return 0; + } + if(this->fromTag != NULL) + free(this->fromTag); + if((this->fromTag=(char *)malloc(strlen(fromTag) + 1))==NULL) { + return 0; + } + strcpy(this->callID, callID); + strcpy(this->callerAddr, callerAddr); + this->callerPort = callerPort; + strcpy(this->fromTag, fromTag); + + char buf[BUF_SIZE]; + struct iovec v[1 + 6 + 5] = {{NULL, 0}, {NULL, 0}, {(char *)" ", 1}, {NULL, 0}, + {(char *)" ", 1}, {NULL, 7}, {(char *)" ", 1}, {NULL, 1}, {(char *)" ", 1}, {NULL, 0}, + {(char *)" ", 1}, {NULL, 0}}; + if(callerAsymmetric == true) + v[1].iov_base = (char *)"Ua"; + else + v[1].iov_base = (char *)"Us"; + v[1].iov_len = 2; + STR2IOVEC((char *)callID, v[3]); + STR2IOVEC((char *)callerAddr, v[5]); + sprintf(buf, "%d", callerPort); + STR2IOVEC(buf, v[7]); + STR2IOVEC((char *)fromTag, v[9]); + // STR2IOVEC(toTag, v[11]); + char *cp = sendCommandRetry(RTPPROXY_RETRY_COUNT, v, 10, gencookie()); + if(cp == NULL) + throw new exception; + callerProxyPort = atoi(cp); + proxies[callerProxyPort] = this; + return callerProxyPort; +} + +void RtpProxyUtil::ammendCaller(const char *callerAddr, int callerPort) { +} + +unsigned int RtpProxyUtil::setupCallee(const char *calleeAddr, int calleePort, const char *toTag, bool calleeAsymmetric) { + if(this->calleeAddr != NULL) + free(this->calleeAddr); + if((this->calleeAddr=(char *)malloc(strlen(calleeAddr) + 1))==NULL) { + return 0; + } + if(this->toTag != NULL) + free(this->toTag); + if((this->toTag=(char *)malloc(strlen(toTag) + 1))==NULL) { + return 0; + } + strcpy(this->calleeAddr, calleeAddr); + this->calleePort = calleePort; + strcpy(this->toTag, toTag); + + char buf[BUF_SIZE]; + struct iovec v[1 + 6 + 5] = {{NULL, 0}, {NULL, 0}, {(char *)" ", 1}, {NULL, 0}, + {(char *)" ", 1}, {NULL, 7}, {(char *)" ", 1}, {NULL, 1}, {(char *)" ", 1}, +{NULL, 0}, + {(char *)" ", 1}, {NULL, 0}}; + if(calleeAsymmetric == true) + v[1].iov_base = (char *)"La"; + else + v[1].iov_base = (char *)"Ls"; + v[1].iov_len = 2; + STR2IOVEC(callID, v[3]); + STR2IOVEC((char *)calleeAddr, v[5]); + sprintf(buf, "%d", calleePort); + STR2IOVEC(buf, v[7]); + STR2IOVEC(fromTag, v[9]); + STR2IOVEC((char *)toTag, v[11]); + char *cp = sendCommandRetry(RTPPROXY_RETRY_COUNT, v, 12, gencookie()); + if(cp == NULL) + throw new exception; + calleeProxyPort = atoi(cp); + proxies[calleeProxyPort] = this; + return calleeProxyPort; +} + +void RtpProxyUtil::ammendCallee(const char *calleeAddr, int calleePort) { +} + +unsigned int RtpProxyUtil::getCallerProxyPort() { + return callerProxyPort; +} + +unsigned int RtpProxyUtil::getCalleeProxyPort() { + return calleeProxyPort; +} + +char *RtpProxyUtil::sendCommandRetry(int retries, struct iovec *v, int vcnt, char *my_cookie) { + int c = 0; + char *result; + while(c++ < retries) { + result = sendCommand(v, vcnt, my_cookie); + if(result != NULL) + return result; + } + return NULL; +} + +char *RtpProxyUtil::sendCommand(struct iovec *v, int vcnt, char *my_cookie) { + + struct sockaddr_un addr; + int fd, i, len; + char *cp; + static char buf[256]; + struct pollfd fds[1]; + + len = 0; + cp = buf; + if (umode == 0) { + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_LOCAL; + strncpy(addr.sun_path, rtpproxy_sock, + sizeof(addr.sun_path) - 1); +#ifdef HAVE_SOCKADDR_SA_LEN + addr.sun_len = strlen(addr.sun_path); +#endif + + fd = socket(AF_LOCAL, SOCK_STREAM, 0); + if (fd < 0) { + B2BUA_LOG_ERR("send_rtpp_command: can't create socket"); + return NULL; + } + if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + close(fd); + B2BUA_LOG_ERR("ERROR: send_rtpp_command: can't connect to RTP proxy: %s", addr.sun_path); + //perror("RtpProxyUtil"); + return NULL; + } + + do { + len = writev(fd, v + 1, vcnt - 1); + } while (len == -1 && errno == EINTR); + if (len <= 0) { + close(fd); + B2BUA_LOG_ERR("ERROR: send_rtpp_command: can't send command to a RTP proxy"); + return NULL; + } + do { + len = read(fd, buf, sizeof(buf) - 1); + } while (len == -1 && errno == EINTR); + close(fd); + if (len <= 0) { + B2BUA_LOG_ERR("ERROR: send_rtpp_command: can't read reply from the RTP proxy, errno = %d", errno); + return NULL; + } + } else { + fds[0].fd = controlfd; + fds[0].events = POLLIN; + fds[0].revents = 0; + /* Drain input buffer */ + while ((poll(fds, 1, 0) == 1) && + ((fds[0].revents & POLLIN) != 0)) { + recv(controlfd, buf, sizeof(buf) - 1, 0); + fds[0].revents = 0; + } + v[0].iov_base = my_cookie; + v[0].iov_len = strlen((const char *)v[0].iov_base); + for (i = 0; i < rtpproxy_retr; i++) { + do { + len = writev(controlfd, v, vcnt); + } while (len == -1 && (errno == EINTR || errno == ENOBUFS)); + if (len <= 0) { + /* LOG(L_ERR, "ERROR: send_rtpp_command: " + "can't send command to a RTP proxy\n"); */ + B2BUA_LOG_ERR("ERROR: send_rtpp_command: can't send command to a RTP proxy"); + return NULL; + } + while ((poll(fds, 1, rtpproxy_tout * 1000) == 1) && + (fds[0].revents & POLLIN) != 0) { + do { + len = recv(controlfd, buf, sizeof(buf) - 1, 0); + } while (len == -1 && errno == EINTR); + if (len <= 0) { + /* LOG(L_ERR, "ERROR: send_rtpp_command: " + "can't read reply from a RTP proxy\n"); */ + B2BUA_LOG_ERR("ERROR: send_rtpp_command:can't read reply from a RTP proxy"); + return NULL; + } + if (len >= (v[0].iov_len - 1) && + memcmp(buf, v[0].iov_base, (v[0].iov_len - 1)) == 0) { + len -= (v[0].iov_len - 1); + cp += (v[0].iov_len - 1); + if (len != 0) { + len--; + cp++; + } + goto out; + } + fds[0].revents = 0; + } + } + if (i == rtpproxy_retr) { + /* LOG(L_ERR, "ERROR: send_rtpp_command: " + "timeout waiting reply from a RTP proxy\n"); */ + B2BUA_LOG_ERR("ERROR: send_rtpp_command: timeout waiting reply from a RTP proxy"); + return NULL; + } + } + +out: + cp[len] = '\0'; + return cp; + +} + + +char *RtpProxyUtil::gencookie() { + static char cook[34]; + + sprintf(cook, "%d_%u ", (int)mypid, myseqn); + myseqn++; + return cook; +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/RtpProxyUtil.hxx b/src/libs/resiprocate/b2bua/RtpProxyUtil.hxx new file mode 100644 index 00000000..bf602f72 --- /dev/null +++ b/src/libs/resiprocate/b2bua/RtpProxyUtil.hxx @@ -0,0 +1,137 @@ + +#ifndef __RtpProxyUtil_h +#define __RtpProxyUtil_h + +#include + +namespace b2bua +{ + +#define DEFAULT_RTPPROXY_SOCK "/var/run/rtpproxy.sock" +#define DEFAULT_RTPPROXY_TIMEOUT_SOCK "/var/run/rtpproxy.timeout.sock" +#define DEFAULT_RTPPROXY_RETR 5 +#define DEFAULT_RTPPROXY_TOUT 1 + +#define BUF_SIZE 250 + +class RtpProxyUtil { + +public: + + class TimeoutListener { + public: + virtual ~TimeoutListener() {}; + virtual void onMediaTimeout() = 0; + }; + + +private: + + + // Static variables for system wide settings + static int umode; + static char *rtpproxy_sock; + static int controlfd; + static char *timeout_sock; + static int timeoutfd; + static int timeout_clientfd; + static int rtpproxy_retr; + static int rtpproxy_tout; + static std::map proxies; + + // Instance variables for per-instance data + pid_t mypid; + int myseqn; + + + TimeoutListener *timeoutListener; + + bool valid; + + char *callID; + char *callerAddr; + unsigned int callerPort; + char *calleeAddr; + unsigned int calleePort; + char *fromTag; + char *toTag; + + unsigned int callerProxyPort; + unsigned int calleeProxyPort; + +protected: + static char *sendCommandRetry(int retries, struct iovec *v, int vcnt, char *my_cookie); + static char *sendCommand(struct iovec *v, int vcnt, char *my_cookie); + char *gencookie(); + + // called when a media timeout occurs + void mediaTimeout(); + +public: + + static void setSocket(const char *socket); + static void setTimeoutSocket(const char *socket); + static void init(); + // check for timeout data from socket + static void do_timeouts(); + + RtpProxyUtil(); + ~RtpProxyUtil(); + + void setTimeoutListener(TimeoutListener *timeoutListener); + + // Inform rtpproxy of the caller's details + unsigned int setupCaller(const char *callID, const char *callerAddr, int callerPort, const char *fromTag, bool callerAsymmetric); + // ammend the caller's details (after the caller sends re-INVITE) + void ammendCaller(const char *callerAddr, int callerPort); + // Inform rtpproxy of the callee's details + unsigned int setupCallee(const char *calleeAddr, int calleePort, const char *toTag, bool calleeAsymmetric); + // ammend the callee's details + void ammendCallee(const char *calleeAddr, int calleePort); + + unsigned int getCallerProxyPort(); + unsigned int getCalleeProxyPort(); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/TaskManager.cxx b/src/libs/resiprocate/b2bua/TaskManager.cxx new file mode 100644 index 00000000..48493b3a --- /dev/null +++ b/src/libs/resiprocate/b2bua/TaskManager.cxx @@ -0,0 +1,99 @@ + +#include +#include + +#include "Logging.hxx" +#include "TaskManager.hxx" + +using namespace b2bua; +using namespace std; + +TaskManager::TaskManager() { +} + +void TaskManager::start() { + while(true) { + int incompleteCount = 0; + list::iterator iterator = recurringTasks.begin(); + while(iterator != recurringTasks.end()) { + // FIXME - read return value, remove completed tasks + RecurringTask *t = *iterator; + iterator++; + TaskResult r = t->doTaskProcessing(); + switch(r) { + case TaskComplete: + recurringTasks.remove(t); + break; + case TaskNotComplete: + incompleteCount++; + break; + default: + // ignore any other return value + break; + } + } + if(incompleteCount == 0) { + // All tasks are done + B2BUA_LOG_NOTICE("all tasks complete"); + return; + } + // FIXME - do scheduled tasks (not yet implemented) + } +} + +void TaskManager::addRecurringTask(RecurringTask *t) { + recurringTasks.push_back(t); +} + +void TaskManager::scheduleTask(ScheduledTask *t, time_t& executionTime) { + // FIXME - not yet implemented + B2BUA_LOG_CRIT("scheduleTask not implemented"); + assert(0); +} + +void TaskManager::stop() { + list::iterator iterator = recurringTasks.begin(); + while(iterator != recurringTasks.end()) { + RecurringTask *t = *iterator; + iterator++; + t->stop(); + } +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/b2bua/TaskManager.hxx b/src/libs/resiprocate/b2bua/TaskManager.hxx new file mode 100644 index 00000000..41cbbb60 --- /dev/null +++ b/src/libs/resiprocate/b2bua/TaskManager.hxx @@ -0,0 +1,102 @@ + +#ifndef __TaskManager_h +#define __TaskManager_h + +#include +#include + +namespace b2bua +{ + +/** + * The TaskManager keeps a record of all recurring tasks, and + * also tasks scheduled to take place at a specified time. + * It provides an efficient way of giving CPU time to each task. + * TaskManager is expected to be used with tasks that do not block + * or run for extended periods of time. + * TaskManager runs all tasks in a single thread. + */ + +class TaskManager { + +public: + + typedef enum TaskResult { + TaskComplete, // the task doesn't need to run again + TaskNotComplete, // the task would like to run again shortly + TaskIndefinite // the task can be run again, but doesn't + // object if the TaskManager stops + }; + + class RecurringTask { + public: + virtual ~RecurringTask() {}; + virtual TaskResult doTaskProcessing() = 0; + virtual void stop() = 0; + }; + + class ScheduledTask { + public: + virtual ~ScheduledTask() {}; + virtual void doTaskSchedule() = 0; + }; + + TaskManager(); + + /** + * Start the task manager - blocks until complete. + * Exits when all recurring tasks exit and no scheduled tasks remain. + */ + void start(); + void addRecurringTask(RecurringTask *t); + void scheduleTask(ScheduledTask *t, time_t& executionTime); + + void stop(); + +protected: + std::list recurringTasks; + std::list scheduleTasks; + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/buginfo.pl b/src/libs/resiprocate/buginfo.pl new file mode 100644 index 00000000..5e22a13d --- /dev/null +++ b/src/libs/resiprocate/buginfo.pl @@ -0,0 +1,68 @@ +#!/usr/bin/perl + +$uname = `uname -a`; + +§ion ("uname -a"); +print "$uname \n"; + +$cc = `make show.CC`; +chop $cc; +$cc =~ s/.*=//g; + +&exec("$cc --version"); + +$conf = `grep := build/Makefile.conf`; +§ion("Makefile.conf"); +print $conf."\n"; + +while ($conf =~ /([^ ]*) *:= *(.*)/g) +{ + $name = $1; + $val = $2; + $name =~ s/[\r\n]//g; + $val =~ s/[\r\n]//g; + $conf{$name} = $val; +} + +if ($conf{'USE_SSL'} eq 'yes') +{ + if (length ($conf{SSL_LOCATION})) + { + &exec("${SSL_LOCATION}/apps/openssl version"); + } + else + { + &exec("openssl version"); + } +} + +&exec ("svnversion"); + +if (-e 'ReleaseNotes.txt') +{ + &exec ("head ReleaseNotes.txt"); +} + +if ($uname =~ /Darwin/i) +{ + &exec ("sysctl -a hw"); +} +elsif ($uname =~ /Linux/i) +{ + &exec ("cat /proc/cpuinfo"); +} + + +sub exec +{ + my ($cmd) = shift; + §ion($cmd); + print `$cmd`."\n"; +} + +sub section +{ + my ($title) = shift; + my ($center) = int(36 - length($title)/2); + print (('='x$center)." $title ".('='x$center)."\n"); +} diff --git a/src/libs/resiprocate/configure b/src/libs/resiprocate/configure new file mode 100644 index 00000000..63b065ce --- /dev/null +++ b/src/libs/resiprocate/configure @@ -0,0 +1,1634 @@ +#!/bin/sh + +for PERL in /opt/local/bin/perl \ + /usr/bin/perl \ + /bin/perl \ + /usr/local/bin/perl \ + /usr/pkg/bin/perl \ + /usr/athena/bin/perl \ + `which perl` +do + if [ -x $PERL ] + then + break + fi +done + +if [ ! -x $PERL ] +then + echo "" + echo "*** Warning: Could not find perl interpreter." + if [ ! -e build/Makefile.conf ] + then + echo "*** Creating default config file in build/Makefile.conf" + echo "*** Please install perl and re-run $0" + echo "VOCAL_TOOLCHAIN_TYPE := gnu +VOCAL_COMPILE_TYPE := debug +CROSS_PLATFORM := arm-unknown-linux-gnu +CROSS_TOOL_PREFIX := arm-unknown-linux-gnu +VOCAL_CROSS_ROOT := /opt/crosstool/current/arm-unknown-linux-gnu/bin +BUILD_SHARED_LIBS := no +USE_DISTCC := no +USE_CCACHE := no +BUILD_REPRO := yes +REPRO_DB := berkeley-db4 +DB_HEADERS := /usr/include/db4 +BUILD_RADIUS := no +BUILD_TFM := no +BUILD_RECON := no +BUILD_RETURN_CLIENT := no +BUILD_RETURN_SERVER := no +USE_SSL := yes +USE_DTLS := no +SSL_LOCATION := +BOOST_INCDIR_CONFIG := /usr/local/include +SIPX_INSTALLED := no +SIPX_ROOT := ../sipXtapi +SIPX_LIBDIR := /usr/local/lib +SIPX_INCDIR := /usr/local/include +USE_POPT := yes +USE_CURL := no +USE_GOOGLE_MALLOC := no +USE_GOOGLE_CPUPERF := no +USE_IPV6 := no +POPT_INCDIR_CONFIG := +POPT_LIBDIR_CONFIG := +RESIP_FIXED_POINT := no +PEDANTIC_STACK := no +# USE_SIGCOMP := no +# SIGCOMP_BASEDIR:= /usr/local +INSTALL_PREFIX := /usr/local +DNS_RESOLVER := resip-ares +ARES_PREFIX := /usr/local +CARES_INCDIR := +CARES_LIBDIR := " > build/Makefile.conf + exit + fi + echo "*** Leaving build/Makefile.conf unmodified" + exit +fi + +exec $PERL -wx $0 $@ +echo <<__END__ +#!perl + +###################################################################### +# Usage: +# ./configure [-y] [-m] +# +# Options: +# -y Run non-interactively +# -m Run with text menu interface +###################################################################### + +# Change directory so that we can find the Makefile.conf file +$mydir = $0; +$mydir =~ s/\/[^\/]*$//; +chdir ($mydir); + +$non_interactive = 0; + +$uname = `uname`; + +@yesno = ('yes','no'); +@toolchains = ('gnu','intel','sunpro','msgnu', 'gnu-cross'); +@compiletypes = ('debug','nodebug','opt','gopt','prof','small'); +@whichdb = ('berkeley-db4'); +@resolvers = ('resip-ares','c-ares'); + +###################################################################### +# NOTE: Any configuration variables that contain path information +# must be added to the following array for proper behavior. + +@pathoptions = ("DB_HEADERS", "BOOST_INCDIR_CONFIG", + "POPT_INCDIR_CONFIG", "POPT_LIBDIR_CONFIG", + "SIPX_ROOT", "SIPX_LIBDIR", "SIPX_INCDIR", + "SSL_LOCATION", "INSTALL_PREFIX", "ARES_PREFIX"); + + +###################################################################### +# The entries in the following array have the following +# fields: +# +# name - Variable name to be used by the make system +# +# description - Question to ask the user +# +# default - Value to use by default +# +# evaldefault - Flag: if set, default is evaluated as perl statement +# +# validate - Optional array of allowed values +# +# predicate - Optional logical test; if false, the user +# will not be asked to configure the value +# +# forcedefault - If set, any questions hidden by the predicate +# will be reset to their default values every +# time the script is run +# +# recalc - List of options to recalculate and reset to defaults +# when value is updated +# +# flag - For "yes/no" entries, adds commandline +# flags of "--enable-foo" and "--disable-foo" +# +# option - Adds commandline options of "--foo=..." +# + +@parameters = ( + { + name => "VOCAL_TOOLCHAIN_TYPE", + description => "Which toolchain do you want to use?", + default => &detectToolchain, + validate => [@toolchains], + recalc => [@pathoptions], + option => 'with-toolchain', + }, + { + name => "CROSS_PLATFORM", + description => "What is the name your toolchain uses for the cross platform?", + default => "arm-unknown-linux-gnu", + predicate => "\$config{VOCAL_TOOLCHAIN_TYPE} =~ /cross/", + recalc => ["CROSS_TOOL_PREFIX","VOCAL_CROSS_ROOT",@pathoptions], + option => 'with-cross-platform', + }, + { + name => "CROSS_TOOL_PREFIX", + description => "What is the prefix for the cross-compiler binaries?", + default => "\$config{CROSS_PLATFORM}", + evaldefault => 1, + predicate => "\$config{VOCAL_TOOLCHAIN_TYPE} =~ /cross/", + recalc => ["VOCAL_CROSS_ROOT"], + option => 'with-cross-tool-prefix', + }, + { + name => "VOCAL_CROSS_ROOT", + description => "Where is your cross compiler installed?", + default => "&findCrossRoot", + evaldefault => 1, + predicate => "\$config{VOCAL_TOOLCHAIN_TYPE} =~ /cross/", + option => 'with-cross-compiler-dir', + }, + { + name => "VOCAL_COMPILE_TYPE", + description => "What compile profile will you use?", + default => "debug", + validate => [@compiletypes], + option => 'with-compile-type', + }, + { + name => "BUILD_SHARED_LIBS", + description => "Should the resip libraries be built shared?", + default => "no", + validate => [@yesno], + flag => 'shared-libs', + }, + { + name => "USE_DISTCC", + description => "Will you be using distcc?", + default => &detectDistcc, + validate => [@yesno], + flag => 'distcc', + }, + { + name => "USE_CCACHE", + description => "Will you be using ccache?", + default => "no", + validate => [@yesno], + flag => 'ccache', + }, + { + name => "BUILD_REPRO", + description => "Build the Repro proxy server?", + default => "yes", + validate => [@yesno], + flag => 'repro', + }, + { + name => "REPRO_DB", + description => "Which database should be used with Repro?", + default => "berkeley-db4", + validate => [@whichdb], + predicate => "\$config{BUILD_REPRO} eq 'yes'", + option => 'repro-db' + }, + { + name => "DB_HEADERS", + description => "Where is db_cxx.h?", + default => "&findDb4", + evaldefault => 1, + predicate => "(\$config{BUILD_REPRO} eq 'yes') and (\$config{REPRO_DB} eq 'berkeley-db4')", + option => "db4-headers", + }, + { + name => "USE_RADIUS_CLIENT", + description => "Build the RADIUS authentication module? (requires radiusclient-ng)", + default => "no", + validate => [@yesno], + flag => 'radius', + }, + { + name => "BUILD_TFM", + description => "Build the TFM test framework?", + default => "no", + validate => [@yesno], + flag => 'tfm', + }, + { + name => "BUILD_RECON", + description => "Build the reCon Conversation Manager? (requires dtls-srtp patched OpenSSL)", + default => "no", + validate => [@yesno], + flag => 'recon', + }, + { + name => "BUILD_RETURN_CLIENT", + description => "Build the reTurn client?", + default => "\$config{BUILD_RECON}", + evaldefault => 1, + forcedefault=> 1, + validate => [@yesno], + predicate => "\$config{BUILD_RECON} eq 'no'", + flag => 'return-client', + }, + { + name => "BUILD_RETURN_SERVER", + description => "Build the reTurn server?", + default => "no", + validate => [@yesno], + flag => 'return-server', + }, + { + name => "BOOST_INCDIR_CONFIG", + description => "Where is boost/config.hpp?", + default => "&findBoostInclude", + evaldefault => 1, + predicate => "(\$config{BUILD_RETURN_CLIENT} eq 'yes') or (\$config{BUILD_RETURN_SERVER} eq 'yes')", + option => "boost-headers", + }, + { + name => "SIPX_INSTALLED", + description => "Are the sipX libraries and headers installed?", + default => "no", + validate => [@yesno], + predicate => "\$config{BUILD_RECON} eq 'yes'", + flag => "sipx-installed", + }, + { + name => "SIPX_ROOT", + description => "Where is the common root of the sipX libraries?", + default => "../sipXtapi", + predicate => "(\$config{BUILD_RECON} eq 'yes') and (\$config{SIPX_INSTALLED} eq 'no')", + option => "libsipx-lib", + }, + { + name => "SIPX_LIBDIR", + description => "Where are the sipX libraries installed?", + default => "/usr/local/lib", +# default => &findSipXLibs, + predicate => "(\$config{BUILD_RECON} eq 'yes') and (\$config{SIPX_INSTALLED} eq 'yes')", + option => "sipx-libdir", + }, + { + name => "SIPX_INCDIR", + description => "Where are the sipX header files installed?", + default => "/usr/local/include", +# default => &findSipXIncludes, + predicate => "(\$config{BUILD_RECON} eq 'yes') and (\$config{SIPX_INSTALLED} eq 'yes')", + option => "sipx-incdir", + }, + { + name => "USE_SSL", + description => "Include SIP over TLS, SMIME or Identity header support? (Requires OpenSSL)", + default => "yes", + forcedefault=> 1, + validate => [@yesno], + predicate => "(\$config{BUILD_RETURN_CLIENT} ne 'yes') and (\$config{BUILD_RETURN_SERVER} ne 'yes')", + flag => 'ssl', + }, + { + name => "USE_DTLS", + description => "Do you want to include SIP over DTLS support? (Requires OpenSSL 0.9.8+)", + default => "no", + validate => [@yesno], + predicate => "\$config{USE_SSL} eq 'yes'", + flag => 'dtls', + }, + { + name => "SSL_LOCATION", + description => "Where is OpenSSL? (leave blank to use installed copy)", + default => "&guessSslLocation", + evaldefault => 1, + predicate => "(\$config{USE_SSL} eq 'yes')", + option => 'with-ssl-location', + }, +# { +# name => "USE_SIGCOMP", +# description => "Do you want to include SigComp support?", +# default => &sigcompInstalled, +# validate => [@yesno], +# flag => 'sigcomp', +# }, +# { +# name => "SIGCOMP_BASEDIR", +# description => "What is the base directory Open SigComp is installed in?", +# default => "/usr/local", +# predicate => "\$config{USE_SIGCOMP} eq 'yes'", +# option => 'with-sigcomp-basedir', +# }, + { + name => "USE_CURL", + description => "Should DUM use curl to retreive identity information?", + default => "no", + validate => [@yesno], + flag => 'curl', + }, + { + name => "USE_GOOGLE_MALLOC", + description => "Use the Google malloc() implementation?", + default => "no", + validate => [@yesno], + flag => 'google-malloc', + }, + { + name => "USE_GOOGLE_CPUPERF", + description => "Use Google cpuperf?", + default => "no", + validate => [@yesno], + flag => 'google-cpuperf', + }, + { + name => "USE_IPV6", + description => "Compile in IPv6 support?", +# default => &detectIpv6, #Should we enable this by default if supported? + default => "no", + validate => [@yesno], + flag => 'ipv6', + }, + { + name => "USE_POPT", + description => "Use popt to read commandline options?", + default => "yes", + validate => [@yesno], + flag => 'popt', + }, + { + name => "POPT_INCDIR_CONFIG", + description => "Where is popt.h?", + default => "&findPoptInclude", + evaldefault => 1, + option => "popt-headers", + predicate => "\$config{USE_POPT} eq 'yes'", + }, + { + name => "POPT_LIBDIR_CONFIG", + description => "Where is libpopt?", + default => "&findPoptLib", + evaldefault => 1, + option => "popt-lib", + predicate => "\$config{USE_POPT} eq 'yes'", + }, + { + name => "RESIP_FIXED_POINT", + description => "Compile with no floating point functions?", + default => "no", + validate => [@yesno], + flag => 'resip-fixed-point', + }, + { + name => "PEDANTIC_STACK", + description => "Force stack to fully parse every message it receives?", + default => "no", + validate => [@yesno], + flag => 'pedantic-stack', + }, + { + name => "INSTALL_PREFIX", + description => "Where should the libraries be installed?", + default => "&guessInstallPath", + evaldefault => 1, + option => "prefix", + }, + { + name => "DNS_RESOLVER", + description => "Which DNS resolution library do you want to use?", + default => 'resip-ares', + validate => [@resolvers], + recalc => ['ARES_PREFIX','CARES_INCLUDEDIRS','CARES_LIBDIRS'], + option => 'with-resolver', + }, + { + name => "ARES_PREFIX", + description => "Where should ares be installed?", + default => "&guessInstallPath", + evaldefault => 1, + option => "ares-prefix", + predicate => "\$config{DNS_RESOLVER} eq 'resip-ares'", + }, + { + name => "CARES_INCLUDEDIRS", + description => "If using c-ares, the directory containing its headers.", + default => "&findCaresIncludes", + evaldefault => 1, + option => "cares-headers", + predicate => "\$config{DNS_RESOLVER} eq 'c-ares'", + }, + { + name => "CARES_LIBDIRS", + description => "If using c-ares, the directory containing its libraries.", + default => "&findCaresLibs", + evaldefault => 1, + option => "cares-libs", + predicate => "\$config{DNS_RESOLVER} eq 'c-ares'", + }, +); + +if (open (CONF, "build/Makefile.conf")) +{ + while () + { + chomp; + if (/([^ :=]+) *:?= *([^ #]*)/) + { + $config{$1} = $2; + } + } + close (CONF); +} + +&parseOptions; + +if (!$non_interactive) +{ + if ($use_text_menu) + { + &simpleTextMenu; + } + elsif ($use_curses_menu) + { + &cursesMenu; + exit; + } + else + { + &simpleTextQuestionnaire; + } +} + +&setAllDefaults; +print "Writing Makefile.conf...\n"; +&saveValues; +&checkForWarnings; + +###################################################################### +# Write out the resulting configure file to Makefile.conf +###################################################################### +sub saveValues +{ + open (CONF, ">build/Makefile.conf") || die "Could not write to build/Makefile.conf: $!"; + foreach $parameter (@parameters) + { + print CONF ("# ".$parameter->{description}."\n"); + if (exists $parameter->{validate}) + { + print CONF ("# Allowed values: ".join(', ',@{$parameter->{validate}})."\n"); + } + print CONF ($parameter->{name}." := ".$config{$parameter->{name}}."\n\n"); + } + close (CONF); + + system "rm -Rf contrib/ares-build*"; +} +###################################################################### +# Initialize any empty or invalid entries to their default values +###################################################################### +sub setAllDefaults +{ + foreach $parameter (@parameters) + { + if ($parameter->{forcedefault} + && exists($parameter->{predicate}) + && !eval($parameter->{predicate})) + { + delete $config{$parameter->{name}}; + } + + setSingleDefault($parameter); + } +} + +###################################################################### +# Initalizes a single configuration parameter to its initial value +# unless it already contains a valid value +###################################################################### + +sub setSingleDefault +{ + my ($parameter) = shift; + + if (defined($config{$parameter->{name}}) && + exists($parameter->{validate}) && + !&validate($config{$parameter->{name}},@{$parameter->{validate}})) + { + warn "$0: '$config{$parameter->{name}}' is not a valid value for ". + "$parameter->{name} -- using default: $parameter->{default}\n"; + delete $config{$parameter->{name}}; + } + + if (!exists($config{$parameter->{name}})) + { + if ($parameter->{evaldefault}) + { + $config{$parameter->{name}} = eval($parameter->{default}); + } + else + { + $config{$parameter->{name}} = $parameter->{default}; + } + } +} + +###################################################################### +sub recalcDefault +{ + my (@params) = @{$_[0]}; + my ($param); + foreach $param(@params) + { + delete $config{$param}; + } +} + +###################################################################### +sub inputParameter +{ + my ($parameter) = shift; + my ($userinput); + do + { + if (exists($parameter->{validate}) && + !&validate($config{$parameter->{name}},@{$parameter->{validate}})) + { + print "*** '$config{$parameter->{name}}' is not a valid value for ". + "$parameter->{name}\n\n"; + $config{$parameter->{name}} = $parameter->{default}; + } + + print "".$parameter->{description}."\n"; + + if (exists $parameter->{validate}) + { + print "(".join(', ',@{$parameter->{validate}}).") "; + } + + print "[".$config{$parameter->{name}}."] "; + $userinput = readline(*STDIN); + chomp ($userinput); + if (length($userinput)) + { + $config{$parameter->{name}} = $userinput; + if (exists($parameter->{recalc})) + { + &recalcDefault($parameter->{recalc}); + } + } + print "\n"; + } + until (!exists($parameter->{validate}) || + &validate($config{$parameter->{name}},@{$parameter->{validate}})); +} + +###################################################################### +sub simpleTextQuestionnaire +{ + my ($parameter); + + print "**********************************************************************\n". + "* On most platforms, the menu-based configuration is much easier *\n". + "* to use than the text-based questionairre. To use the menu system, *\n". + "* hit ctrl-c, and re-run this script as '$0".(@ARGV?' ':'').join(' ',@ARGV)." -m'\n". + "**********************************************************************\n\n"; + + foreach $parameter (@parameters) + { + setSingleDefault($parameter); + + if (exists($parameter->{predicate}) && !eval($parameter->{predicate})) + { + next; + } + &inputParameter($parameter); + } +} + +###################################################################### +# Relatively crude text-based menu system +# +# Ideally, this should be superceded by a curses-based system +# at some point, but doing so will be a non-trivial effort. +# +# Currently, this makes a number of assumptions, including: +# - The terminal is at least tall enough to display all the options +# - The terminal implements at least a minimal subset of VT-100 +# command codes +# - The arrow keys are communicated using the VT-100 esc-[A through +# esc-[D codes +# - 'stty' is present on the system and behaves in the way expected +# for turning on and off immediate keyboard input +###################################################################### +sub simpleTextMenu +{ + my ($termwidth) = 80; + my ($termheight) = 24; + my ($parameter); + my ($max_label_length) = 0; + my ($value_length); + my ($last_row); + my ($current_parameter); + my ($selected_row) = 0; + my ($indent); + + my ($vt_clear_eos) = "\033[0J"; + my ($vt_home) = "\033[0;0H"; + my ($vt_clear_line) = "\033[2K"; + my ($vt_clear_eol) = "\033[0K"; + my ($vt_clear_screen) = "\033[2J${vt_home}"; + my ($vt_reverse) = "\033[7m"; + my ($vt_normal) = "\033[0m"; + + $SIG{'WINCH'} = 'queryWindowSize'; + + print "${vt_clear_screen}"; + + # We want to capture each key as it is pressed. + &cbreak; + + foreach $parameter (@parameters) + { + if (length($parameter->{name})>$max_label_length) + { + $max_label_length = length($parameter->{name}); + } + } + $max_label_length += 4; + $value_length = $termwidth-$max_label_length; + + &queryWindowSize; + + # Print the currently available options and their values + while (1) + { + print $vt_home; + $last_row = 0; + foreach $parameter (@parameters) + { + + if (exists($parameter->{predicate}) && !eval($parameter->{predicate})) + { + if ($parameter->{forcedefault}) + { + delete $config{$parameter->{name}}; + &setSingleDefault($parameter); + printf "%-$max_label_length.${max_label_length}s", ' '.$parameter->{name}; + print " [".$config{$parameter->{name}}."] (Locked)$vt_clear_eol\n"; + } + next; + } + + setSingleDefault($parameter); + print $vt_clear_line; + if ($last_row == $selected_row) + { + print $vt_reverse; + printf "%-${termwidth}.${termwidth}s", $parameter->{description}; + print "$vt_clear_eol\n"; + $current_parameter = $parameter; + } + + $indent = (exists($parameter->{predicate}) + && !$parameter->{forcedefault})?' ':' '; + + printf "%-$max_label_length.${max_label_length}s", $indent.$parameter->{name}; + printf "%-$value_length.${value_length}s", " [".$config{$parameter->{name}}."]"; + print "$vt_clear_eol\n$vt_normal"; + $last_row++; + } + + # Print menu + print "$vt_clear_eol\n[D - Reset to Default] ". + "[S - Save and Quit] ". + "[Q - Quit without Saving]". + "$vt_clear_eol\n"; + + if (exists($current_parameter->{validate})) + { + print "[<- and -> - Change Value] (". + join(', ',@{$current_parameter->{validate}}).")". + "$vt_clear_eol"; + } + else + { + print "[Enter - Change Value] [B - Blank Value]$vt_clear_eol"; + } + + print $vt_clear_eos; + + # Get user input + $key = getc(STDIN); + + # Input remaining bytes if an arrow key is pressed + if ($key eq "\033") + { + my ($tmp); + $key = getc(STDIN); + if ($key eq '[') + { + do + { + $tmp = getc(STDIN); + $key .= $tmp; + } + while $tmp =~ /[0-9;]/; + } + } + + # Adjust for screen resizing + if ($key =~ /\[([0-9]+);([0-9]+)R/) + { + $termheight = $1; + $termwidth = $2; + $value_length = $termwidth-$max_label_length; + if ($value_length < 0) { $value_length = 0; } + } + + $key =~ y/a-z/A-Z/; + + # Save and exit + if ($key eq 'S') + { + last; + } + + # Quit, abandoning any changes + elsif ($key eq 'Q') + { + print "$vt_clear_line\nExiting without saving\n"; + &nocbreak; + exit; + } + + # Set current parameter to its default value + elsif ($key eq 'D') + { + delete $config{$current_parameter->{name}}; + &setSingleDefault($current_parameter); + if (exists($current_parameter->{recalc})) + { + &recalcDefault($current_parameter->{recalc}); + } + } + + # Blank the current option + elsif ($key eq 'B' && !exists($current_parameter->{validate})) + { + $config{$current_parameter->{name}} = ''; + if (exists($current_parameter->{recalc})) + { + &recalcDefault($current_parameter->{recalc}); + } + } + + # Arrow Up + elsif ($key eq '[A' && $selected_row > 0){ $selected_row--; } + + # Arrow Down + elsif ($key eq '[B' && $selected_row < $last_row-1) { $selected_row++; } + + # Right Arrow, Enter + elsif ($key =~ /([\r\n]|\[C|>|\.)/ + && defined $current_parameter) + { + if (exists($current_parameter->{validate})) + { + my ($new_value) = ${$current_parameter->{validate}}[0]; + my ($found) = 0; + my ($p); + foreach $p (@{$current_parameter->{validate}}) + { + if ($found) { $new_value = $p; last; } + if ($p eq $config{$current_parameter->{name}}) { $found = 1; } + } + $config{$current_parameter->{name}} = $new_value; + } + else + { + &nocbreak; + print "$vt_clear_line\n"; + &inputParameter($current_parameter); + &cbreak; + } + + if (exists($current_parameter->{recalc})) + { + &recalcDefault($current_parameter->{recalc}); + } + } + + # Left Arrow + elsif ($key =~ /(\[D|<|,)/ + && defined $current_parameter + && exists($current_parameter->{validate})) + { + my (@values) = @{$current_parameter->{validate}}; + my ($new_value) = $values[$#values]; + my ($prev) = $new_value; + my ($p); + foreach $p (@values) + { + if ($p eq $config{$current_parameter->{name}} && length($prev)) + { + $new_value = $prev; last; + } + $prev = $p; + } + $config{$current_parameter->{name}} = $new_value; + + if (exists($current_parameter->{recalc})) + { + &recalcDefault($current_parameter->{recalc}); + } + } + + # Any other key (mostly to let y/n change yes/no values) + else + { + if (defined $current_parameter + && exists($current_parameter->{validate})) + { + my ($v); + my ($v2); + foreach $v (@{$current_parameter->{validate}}) + { + $v2 = substr($v,0,1); + $v2 =~ y/a-z/A-Z/; + if ($v2 eq $key) + { + $config{$current_parameter->{name}} = $v; + if (exists($current_parameter->{recalc})) + { + &recalcDefault($current_parameter->{recalc}); + } + } + } + } + } + } + print "$vt_clear_line\n"; + + # Return keyboard functioning to normal + &nocbreak; +} + +sub cbreak +{ + system ("stty", '-icanon') && system ('stty','eol',"\001"); +} + +sub nocbreak +{ + system "reset" || + (system "stty", 'icanon' && system 'stty','eol',"\000"); +} + +###################################################################### +sub queryWindowSize +{ + my ($tmp) = $|; + $| = 1; + print "\0337"; # Save Cursor Position + print "\033[999;999H"; # Move to lower right corner + print "\033[6n"; # Request position report + print "\0338"; # Restore Cursor Position + $| = $tmp; +} + +###################################################################### +# Slightly less crude curses-based menu system +###################################################################### +sub cursesMenu +{ + my $curses_ui_installed = undef; + eval('use Curses::UI; $curses_ui_installed=1'); + if (!$curses_ui_installed) + { + die "Curses mode requires the Curses::UI module.\n". + "Run 'cpan Curses::UI' as root to install.\n"; + } + + $ui = new Curses::UI( -color_support => 1, + -mouse_support => 1); + $ui->draw(); + + my @menu = + ( + { + -label => 'File', + -submenu => [ + { -label => 'Save', -value => \&saveValues }, + { -label => 'Quit', -value => \&guiQuit }, + ] + }, + ); + + my $menu = $ui->add('menu','Menubar', -menu => \@menu); + + my $sb = $ui->add('status_bar','Window', + -border => 0, + -height => 1, + -width => undef, + -y => -1, + ); + + my $mainwin = $ui->add('mainwin','Window', + -border => 1, + -bfg => 'red', + -x => 0, + -y => 1, + -width => -1, + -height => -1, + -padbottom => 1, + ); + + $gui_st = $sb->add('status_text','Label', + -bg => 'blue', + -fg => 'white', + -paddingspaces => 1, + -width => -1, + ); + + $gui_list = $mainwin->add('list','Listbox', + -values => [&guiList], + -labels => {&guiLabels}, + -onselchange => \&guiSelectionChanged, + -vscrollbar => 'right', + ); + +# $gui_st->text(join ' ',sort keys %{$list}); + + $ui->set_binding(sub{$menu->focus()}, "\cF"); + $ui->set_binding(\&guiQuit, "q"); + + $gui_list->set_binding(\&guiChange,' '); + $gui_list->set_binding(\&guiChange,'|'); + $gui_list->set_binding(\&guiChange,Curses::UI::Widget::KEY_RIGHT()); + $gui_list->set_binding(\&guiChange,Curses::UI::Widget::KEY_ENTER()); + $gui_list->set_binding(sub{},'y'); + $gui_list->set_binding(sub{},'n'); + $gui_list->set_binding(sub{},'0'); + $gui_list->set_binding(sub{},'1'); + + $gui_list->focus(); + &guiSelectionChanged(); + $ui->mainloop(); +} + +sub guiSelectionChanged +{ + my ($description) = ''; + my ($key) = $gui_list->get_active_value(); + + foreach $parameter (@parameters) + { + if ($parameter->{name} eq $key) + { + $description = ' '.$parameter->{description}; + last; + } + } + + $gui_st->text($description); + $gui_st->focus(); + $gui_list->focus(); +} + +sub guiChange +{ + my ($key) = $gui_list->get_active_value(); + + foreach $parameter (@parameters) + { + if ($parameter->{name} eq $key) + { + if (exists($parameter->{validate})) + { + # select from choices + my ($p); + my ($index) = 0; + foreach $p (@{$parameter->{validate}}) + { + if ($p eq $config{$parameter->{name}}) { last; } + $index++; + } + + + my ($i); + my ($j); + my (%k) = (); + my (%shortcut); + foreach $i (@{$parameter->{validate}}) + { + $j = 0; + while ($k{substr($i,$j,1)}){$j++} + $shortcut{$i}=substr($i,$j,1); + $k{substr($i,$j,1)}++; + } + + $i = 0; + my (@buttons) = map { + {-label => '<'.$_.'>', + -value => $i++, + -shortcut => $shortcut{$_} } } + @{$parameter->{validate}}; + + my ($description) = $parameter->{description}; + $description =~ s/(.{40}) /$1\n/g; + + $index = $ui->dialog(-message => $description, + -buttons => [@buttons], + -selected => $index); + + my ($new_value) = ${$parameter->{validate}}[$index]; + $config{$parameter->{name}} = $new_value; + } + else + { + # input string + my ($new_value) = $ui->dirbrowser( + -path => '/'.$config{$parameter->{name}}, + -title => $parameter->{description}, + ); + if (defined($new_value)) + { + $config{$parameter->{name}} = $new_value; + } + } + + +# { +# # input string +# my ($new_value) = $ui->question($parameter->{description}); +# if (defined($new_value)) +# { +# $config{$parameter->{name}} = $new_value; +# } +# } + + if (exists($current_parameter->{recalc})) + { + &recalcDefault($current_parameter->{recalc}); + } + + my ($index) = $gui_list->get_active_id(); + $gui_list->values([&guiList]); + $gui_list->labels({&guiLabels}); + + # WOW! Is this ever ugly. There isn't any sane way to set the + # active id.... + while ($index--) + { + $gui_list->process_bindings(Curses::UI::Widget::KEY_DOWN()); + } + return; + } + } +} + +sub guiList +{ + my (@list) = (); + foreach $parameter (@parameters) + { + if (exists($parameter->{predicate}) && !eval($parameter->{predicate}) + && ! ($parameter->{forcedefault})) + { + next; + } + + push (@list, $parameter->{name}); + } + + return @list; +} + +sub guiLabels +{ + my (%labels) = (); + my ($max_label_length) = 0; + + foreach $parameter (@parameters) + { + if (length($parameter->{name})>$max_label_length) + { + $max_label_length = length($parameter->{name}); + } + } + $max_label_length += 2; + + foreach $parameter (@parameters) + { + if (exists($parameter->{predicate}) && !eval($parameter->{predicate}) + && ! ($parameter->{forcedefault})) + { + next; + } + + setSingleDefault($parameter); + + $indent = (exists($parameter->{predicate}) + && !$parameter->{forcedefault})?' ':''; + + $labels{$parameter->{name}} = + sprintf ("%-$max_label_length.${max_label_length}s %s", + $indent.$parameter->{name}, + "[".$config{$parameter->{name}}."]"); + } + + return %labels; +} + +sub guiQuit +{ + exit; +} + +###################################################################### + +sub validate +{ + my ($value, @allowed) = @_; + my ($allowed); + + if (@allowed == 0) + { + return 1; + } + + foreach $allowed (@allowed) + { + if (defined($value) && $value eq $allowed) + { + return 1; + } + } + + return 0; +} + +###################################################################### +sub parseOptions +{ + my($option); + my($curr); + my ($parameter); + + option: foreach $option (@ARGV) + { + if ($option eq '-y' || $option eq '--non-interactive') + { + $non_interactive = 1; + next option; + } + + if ($option eq '-m' || $option eq '--use-text-menu') + { + $use_text_menu = 1; + next option; + } + + if ($option eq '-c' || $option eq '--use-curses-menu') + { + $use_curses_menu = 1; + next option; + } + + foreach $parameter (@parameters) + { + if (defined $parameter->{flag}) + { + $curr = $parameter->{flag}; + if ($option =~ /^--(enable|disable)-$curr$/) + { + $config{$parameter->{name}} = ($1 eq 'enable'?'yes':'no'); + next option; + } + } + + if (defined $parameter->{option}) + { + $curr = $parameter->{option}; + if ($option =~ /^--$curr\=\"?([^"]*)\"?$/) + { + $config{$parameter->{name}} = $1; + next option; + } + } + + } + + print "\nUnknown option: $option\n\n"; + &setAllDefaults; + &usage; + } +} + +###################################################################### +sub usage +{ + my ($parameter); + print <{flag}) + { + print " --enable-".$parameter->{flag}."\n"; + print " --disable-".$parameter->{flag}."\n"; + print " ".$parameter->{description}." "; + print "(Now ".($config{$parameter->{name}} eq 'yes'? + "enabled":"disabled").")\n"; + } + if (defined $parameter->{option}) + { + print " --".$parameter->{option}."=\"...\"\n"; + print " ".$parameter->{description}." "; + print "(Now \"".$config{$parameter->{name}}."\")\n"; + if (defined $parameter->{validate}) + { + print " Valid values are: [". + join(', ',@{$parameter->{validate}})."]\n"; + } + } + + print "\n"; + } + exit; +} + +###################################################################### +# Here are functions to determine reasonable defaults + +sub detectToolchain +{ + if ($uname =~ /SunOS/ || $uname =~ /Solaris/) + { + return "sunpro"; + } + "gnu"; +} + +sub detectDistcc +{ + if ($ENV{DISTCC_HOSTS}) + { + return "yes"; + } + "no"; +} + +sub detectIpv6 +{ + if (-e "/usr/include/netinet6/in6.h") + { + return "yes"; + } + return "no"; +} + +sub sigcompInstalled +{ + if (-e "/usr/local/lib/libopensigcomp.a") + { + return "yes"; + } + "no"; +} + +sub findDb4 +{ + if ($config{VOCAL_TOOLCHAIN_TYPE} =~ /cross/) + { + my ($crossPath) = $config{VOCAL_CROSS_ROOT} =~ m|(.*)/bin|; + return "$crossPath/include/db4"; + } + + my (@candidates) = + ( + '/usr/include/db4', + '/opt/local/include/db42', + '/opt/local/include/db4', + '/include/db4', + '/usr/local/include/db4', + ); + my ($candidate); + + foreach $candidate (@candidates) + { + if (-e "${candidate}/db_cxx.h") + { + return $candidate; + } + } + + $candidates[0]; +} + +sub findCaresIncludes +{ + if ($config{VOCAL_TOOLCHAIN_TYPE} =~ /cross/) + { + my ($crossPath) = $config{VOCAL_CROSS_ROOT} =~ m|(.*)/bin|; + return "$crossPath/include"; + } + + my (@candidates) = + ( + '/usr/include', + '/opt/local/include', + '/include', + '/usr/local/include', + ); + my ($candidate); + + foreach $candidate (@candidates) + { + if (-e "${candidate}/ares.h") + { + return $candidate; + } + } + + $candidates[0]; +} + +sub findCaresLibs +{ + if ($config{VOCAL_TOOLCHAIN_TYPE} =~ /cross/) + { + my ($crossPath) = $config{VOCAL_CROSS_ROOT} =~ m|(.*)/bin|; + return "$crossPath/lib"; + } + + my (@candidates) = + ( + '/usr/lib', + '/opt/local/lib', + '/lib', + '/usr/local/lib', + ); + my ($candidate); + + foreach $candidate (@candidates) + { + if (-e "${candidate}/libcares.a") + { + return $candidate; + } + } + + $candidates[0]; +} + +sub findPoptInclude +{ + if ($config{VOCAL_TOOLCHAIN_TYPE} =~ /cross/) + { + my ($crossPath) = $config{VOCAL_CROSS_ROOT} =~ m|(.*)/bin|; + return "$crossPath/include"; + } + + if ($uname =~ /MinGW/i) + { + return "\$\(ROOT\)/contrib/popt/win32/include"; + } + + my (@candidates) = + ( + '/usr/local/include', + '/include', + '/opt/popt/include', + ); + my ($candidate); + + foreach $candidate (@candidates) + { + if (-e "${candidate}/popt.h") + { + return $candidate; + } + } + + $candidates[0]; +} + +sub findPoptLib +{ + if ($config{VOCAL_TOOLCHAIN_TYPE} =~ /cross/) + { + my ($crossPath) = $config{VOCAL_CROSS_ROOT} =~ m|(.*)/bin|; + return "$crossPath/lib"; + } + + if ($uname =~ /MinGW/i) + { + return "\$\(ROOT\)/contrib/popt/win32/lib"; + } + + my (@candidates) = + ( + '/usr/local/lib', + '/lib', + '/opt/popt/lib', + ); + my ($candidate); + + foreach $candidate (@candidates) + { + if (-e "${candidate}/libpopt.a" || + -e "${candidate}/libpopt.so" || + -e "${candidate}/libpopt.dylib") + { + return $candidate; + } + } + + $candidates[0]; +} + +sub findBoostInclude +{ + if ($config{VOCAL_TOOLCHAIN_TYPE} =~ /cross/) + { + my ($crossPath) = $config{VOCAL_CROSS_ROOT} =~ m|(.*)/bin|; + return "$crossPath/include"; + } + + my (@candidates) = + ( + '/usr/include', + '/usr/local/include', + '/include', + '/opt/include', + '/opt/local/include', + '/opt/csw/include', + '/sw/include', + ); + my ($candidate); + + foreach $candidate (@candidates) + { + if (-e "${candidate}/boost/config.hpp") + { + return $candidate; + } + } + + $candidates[0]; +} + +sub findCrossRoot +{ + my (@candidates) = reverse sort + glob("/opt/crosstool/*/".$config{CROSS_PLATFORM}."/bin/"); + + if (@candidates) + { + return $candidates[0]; + } + + return "/opt/crosstool/current/".$config{CROSS_PLATFORM}."/bin/"; +} + +sub guessInstallPath +{ + if ($config{VOCAL_TOOLCHAIN_TYPE} =~ /cross/) + { + my ($crossPath) = $config{VOCAL_CROSS_ROOT} =~ m|(.*)/bin|; + return "$crossPath"; + } + + return "/usr/local"; +} + +sub guessSslLocation +{ + if ($config{VOCAL_TOOLCHAIN_TYPE} =~ /cross/) + { + my ($crossPath) = $config{VOCAL_CROSS_ROOT} =~ m|(.*)/bin|; + return "$crossPath/OpenSSL"; + } + + return ""; +} + +sub checkForWarnings +{ + my ($option); + my ($parameters); + + if ($config{VOCAL_TOOLCHAIN_TYPE} =~ /cross/) + { + print ("\n".('*!' x 30)."\n\n"); + print " WARNING: when cross-compiling, the paths for include\n". + " files and libraries must point to directories that\n". + " contain information appropriate to the target platform.\n". + " please double-check that the following paths contain\n". + " information *ONLY* for the $config{CROSS_PLATFORM}\n". + " environment:\n\n"; + + foreach $option (@pathoptions) + { + foreach $parameter (@parameters) + { + if ($parameter->{name} eq $option + && (!exists($parameter->{predicate}) || + eval($parameter->{predicate})) + ) + { + print (" ".$parameter->{name}." := ".$config{$parameter->{name}}."\n"); + } + } + } + + print "\n You may be able to eliminate some of these paths by\n". + " turning off features you don't plan to use; examples\n". + " include SSL and popt.\n"; + + print ("\n".('*!' x 30)."\n"); + } +} + +__END__ + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# . +# +############################################################################## diff --git a/src/libs/resiprocate/contrib/.cvsignore b/src/libs/resiprocate/contrib/.cvsignore new file mode 100644 index 00000000..e43b0f98 --- /dev/null +++ b/src/libs/resiprocate/contrib/.cvsignore @@ -0,0 +1 @@ +.DS_Store diff --git a/src/libs/resiprocate/contrib/GeoIP/AUTHORS b/src/libs/resiprocate/contrib/GeoIP/AUTHORS new file mode 100644 index 00000000..b1295b9b --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/AUTHORS @@ -0,0 +1 @@ +T.J. Mather diff --git a/src/libs/resiprocate/contrib/GeoIP/COPYING b/src/libs/resiprocate/contrib/GeoIP/COPYING new file mode 100644 index 00000000..45574c3c --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/COPYING @@ -0,0 +1,509 @@ +[ Note that while the core GeoIP library is licensed under the +LGPL, the libGeoIPUpdate library depends on md5.c and types.h +which are licensed under the GPL. ] + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/src/libs/resiprocate/contrib/GeoIP/ChangeLog b/src/libs/resiprocate/contrib/GeoIP/ChangeLog new file mode 100644 index 00000000..572960f0 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/ChangeLog @@ -0,0 +1,628 @@ +1.4.8 + * Fix GEOIP_DOMAIN_EDITION_V6 ( Boris Zentner ) + * Add new Datatypes GEOIP_NETSPEED_EDITION_REV1_V6 and + GEOIP_NETSPEED_EDITION_REV1 ( Boris Zentner ) + * Fix possible directory traversal weakness in geoipupdate-pureperl.pl with + malicious update server ( Boris Zentner ) + * Fix GEOIP_ORG_EDITION_V6 and GEOIP_ISP_EDITION_V6 ( Boris Zentner ) +1.4.7 + * Upd timezone.c Add SX, BQ and CW remove AN and FX ( Boris Zentner ) + * Add support for the new types in geoiplookup6 ( Boris Zentner ) + * Add new database types GEOIP_CITY_EDITION_REV0_V6, + GEOIP_CITY_EDITION_REV1_V6, GEOIP_DOMAIN_EDITION_V6, + GEOIP_ORG_EDITION_V6 and GEOIP_ISP_EDITION_V6 ( Boris Zentner ) + * Remove AN and FX. Add SX, BQ and CW ( Boris Zentner ) + * Fix possible segfault in geoipupdate if the connection disappear + unexpected. ( Boris Zentner ) + * Add sanity check for geoipupdate-pureperl.pl ( Boris Zentner ) + * Add GEOIP_USERTYPE_EDITION and GEOIP_USERTYPE_EDITION_V6 + datatypes ( Boris Zentner ) + * Add new functions GeoIP_is_private_ipnum_v4 and GeoIP_is_private_v4 + ( Boris Zentner ) + * Add new functions GeoIP_teredo and GeoIP_enable_teredo. + teredo is enabled by default ( Boris Zentner ) + * Fix output of geoiplookup for unknown or private regions. + ( Boris Zentner ) + * Fix geoipupdate-pureperl.pl to accept more product codes. + ( Boris Zentner ) + * Fix minor output issue in geoipupdate -v ( Boris Zentner ) + * Add support for various databases. ( Boris Zentner ) + * Add experimental teredo support ( Boris Zentner ) + * Fix possible buffer overflow in conjunction with + http_proxies ( Elso Andras ) + * Remove memcpy/bcopy macro for BSD ( Boris Zentner ) + * Add GeoIP_lib_version and GeoIP_cleanup ( Ladar Levison ) + * Upd Makefile.vc ( Thomas Winzig ) + * Fix typo in DK,18,Midtjylland ( Boris Zentner ) + * Update libGeoIP/regionName.c with FIPS codes 20100810 ( Boris Zentner ) + * Fix continent codes ( Boris Zentner ) + * Fix 3letter country codes for ATA, BVT, IOT, CXR, CCK, ATF, HMD, + MYT, SGS and UMI ( Boris Zentner ) + * Fix typo/segfault in GeoIP_id_by_name_v6 ( Boris Zentner ) + * Update libGeoIP/regionName.c with FIPS codes 20100529 ( Boris Zentner ) + * Remove buffered IO functions, to fix issues with dup'ed file + descriptors ( Boris Zentner ) + * Fix very minor memleak in geoipupdate ( Boris Zentner ) + * Add GEOIP_CITYCONFIDENCEDIST_EDITION, GEOIP_LARGE_COUNTRY_EDITION + and GEOIP_LARGE_COUNTRY_EDITION_V6 database types ( Boris Zentner ) + * Update libGeoIP/regionName.c with FIPS codes 20100422 ( Boris Zentner ) + * Update libGeoIP/regionName.c with FIPS codes 20100420 ( Boris Zentner ) + * Update libGeoIP/regionName.c with FIPS codes 20100221 ( Boris Zentner ) + * Add missing timezones ( Boris Zentner ) + * Add missing include for Windows 2000 ( Jaap Keute ) + * 'GeoIP Database up to date' and 'Updated database' prints to stdout + instead of stderr ( Boris Zentner ) + * Add missing GeoIPRecord_delete to geoiplookup.c ( Piotr Kaczuba ) + * Add some IPv4 helper functions + unsigned long GeoIP_addr_to_num(const char *addr); + char * GeoIP_num_to_addr(unsigned long ipnum); ( Boris Zentner ) + * Fix default name for the accuracy radius database to GeoIPDistance.dat ( Boris Zentner ) + * Add GEOIP_CITYCONFIDENCE_EDITION database type. ( Boris Zentner ) + * geoiplookup use GeoIPDistance.dat files if avail ( Boris Zentner ) + * Fix geoiplookup/geoiplookup6 output, when the databaseinfo string is + not avail. ( Boris Zentner ) + * Change continent code for RU from AS to EU ( Boris Zentner ) + * Add GEOIP_ACCURACYRADIUS_EDITION database type. ( Boris Zentner ) + * Add GEOIP_LOCATIONA_EDITION the database to map back from binary to + the csv database ( Boris Zentner ) + * Change Turkey's continent code from Asia to Europe ( Boris Zentner ) + * Rename _iso_8859_1__utf8 to _GeoIP_iso_8859_1__utf8 ( Boris Zentner ) + * GEOIP_ORG_EDITION, GEOIP_ISP_EDITION, GEOIP_DOMAIN_EDITION and + GEOIP_ASNUM_EDITION databases return UTF8 results, if gi->charset is set + to GEOIP_CHARSET_UTF8 ( Boris Zentner ) + * Avoid unnecesary call to gettimeofday when GEOIP_CHECK_CACHE is not set ( John Douglass ) + * Delayed loading of changed database files for 60 seconds. To avoid + reading halve written databases ( Boris Zentner ) + * Update README.OSX for Leopard and Snow Leopard ( Boris Zentner ) + * Add more IPv6 functions ( Boris Zentner ) + const char *GeoIP_country_code_by_addr_v6 (GeoIP* gi, const char *addr); + const char *GeoIP_country_code_by_name_v6 (GeoIP* gi, const char *host); + const char *GeoIP_country_code3_by_addr_v6 (GeoIP* gi, const char *addr); + const char *GeoIP_country_code3_by_name_v6 (GeoIP* gi, const char *host); + const char *GeoIP_country_name_by_addr_v6 (GeoIP* gi, const char *addr); + const char *GeoIP_country_name_by_name_v6 (GeoIP* gi, const char *host); + * Make sure that GeoIP_*_v6 functions refuse GEOIP_PROXY_EDITION and + GEOIP_NETSPEED_EDITION databases ( Boris Zentner ) + * Update libGeoIP/regionName.c with FIPS codes from 20090723 ( Boris Zentner ) + * Fix geoipupdate's -v option to not change the license filename ( Thom May ) + * Fix geoipupdate's exit code ( Thom May ) + * Add support for ASNUM_EDITION ( Boris Zentner ) + * Fix -i output for larger values, sign issue ( Boris Zentner ) + * Add -i flag for more information on netmask, range_by_ip and the current network range ( Boris Zentner ) + * Add support for DOMAIN_EDITION database type ( Boris Zentner ) + * Fix apps/geoipupdate-pureperl.pl output layer on W32 ( Boris Zentner ) +1.4.6 2009-02-25 + * Fix geoipupdate's my_printf function ( Boris Zentner ) + * Fix typo in apps/geoipupdate-pureperl.pl replace PerlIO::Gzip with PerlIO::gzip ( Boris Zentner ) + * Update region codes in libGeoIP/regionName.c ( Boris Zentner ) + * Fix regioncode/generate_regionName.pl to handle regioncodes with ',' correct ( Boris Zentner ) + * Update fips codes 20090201 ( Boris Zentner ) + * Fix unicode builds on WIN32 and eliminate some warnings ( Stu Redman ) + * Fix sign error in _iso_8859_1__utf8 for PPC64 ( Boris Zentner ) + * Change WIN32 to _WIN32, since _WIN32 is defined by default. _WIN32 is also defined for WIN64 machines ( Boris Zentner ) + ! Remove the WSAStartup call from GeoIP_open. All Applications need to call WSAStartup and WSACleanup to initialize the Windows Socket library. Before they use any of the GeoIP_*_by_name functions. ( Boris Zentner ) + * geoiplookup and test-geoip-* output N/A instead of (null) ( Boris Zentner ) + * Silence various warnings. ( Boris Zentner ) + * Add more timezone region's for Australia + * Fix possible segfault in apps/geoiplookup with null pointers in non gnu printf implementations for example solaris ( Boris Zentner ) + * Add README.OSX to build fat binaries easy ( Boris Zentner ) + * Silence vasprintf warning via AC_GNU_SOURCE ( Boris Zentner ) + * Add several Makefiles to build a static GeoIP.lib for w32 ( Stanislaw Pusep and Randy Kobes ) + * Silence signedness warnings ( Peter Volkov ) + * Remove --with-city configure option. ( Boris Zentner ) + * Remove configure's --with-dbdir option. Use the similar --datadir instead ( Peter Volkov ) + * Various autotools improvements and cleanups. Including parallel + build fix ( Peter Volkov ) + * Fix libGeoIP/timeZone.c ( Martin Haller ) + * Fix timezone/generate_timeZone.pl ( Boris Zenter ) + * Sync FIPS codes again Jan 14th, 2009 ( Boris Zentner ) + * Fix CA,NL regioncode. ( Boris Zentner ) + * Change logic in generate_regionName.pl and GeoIP_region_name_by_code to handle any mixture of two letter fips codes matching [A-Z0-9]{2} the change allow GZ and WE region codes ( Boris Zentner ) + * Sync regionName.c with http://www.maxmind.com/app/fips10_4 from Dec 17th, 2008 ( Boris Zentner ) + * Fix _GeoIP_lookupaddress for 64bit big endian systems like ppc64 ( Peter Volkov ) + * Add proper WIN32/64 support ( Gerald Combs ) + * Escape - in all manpages ( Patrick Matthaei ) + * Add manpage for geoiplookup6 ( Boris Zentner ) + * Fix -d command line option ( Klaus Heinz ) + * GeoIPUpdate.c use vasprintf if avail, otherwise try vsnprintf and sprintf ( Boris Zentner ) + * avoid pre/postincrement and assignment on the same variable ( Boris Zentner ) +1.4.5 2008-09-16 + * metro_code replace the depreciated dma_code field ( Boris Zentner ) + * Add new function GeoIP_range_by_ip_delete + r = GeoIP_range_by_ip(gi, '24.24.24.24'); + ... + GeoIP_range_by_ip_delete(r); ( Boris Zentner ) + * Fix small memoryleak and wrap around in GeoIP_range_by_ip ( Boris Zentner ) + * CHECK_CACHE stat the database file not faster than once a second anymore ( Patrick McManus ) + * Fixed a typo in the geoipupdate(1) manpage and also an non-existent path on Debian (Patrick Matthi) + * Fixes two little format errors (hyphen used as minus sign) in both manpages (Patrick Matthi) + * Sync regionName.c with a recent fips code list ( Boris Zentner ) + * Fix segfault when open failed for a custom file (-f) ( Boris Zentner ) + * Fix sync geoiplookup's man page with the code ( Klaus Heinz ) + * remove unused code from GeoIP_country_name_by_addr and GeoIP_country_code3_by_addr ( Boris Zentner ) + * Fix geoiplookup and geoiplookup6 to distinguish between failed namelookups and unknown ips ( Boris Zentner ) + * add geoiplookup6 that can handle the new database type GEOIP_COUNTRY_EDITION_V6 ( Boris Zentner ) + * add new functions to handle ipv6 + + GEOIP_API const char *GeoIP_country_name_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API const char *GeoIP_country_code_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API const char *GeoIP_country_code3_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API char *GeoIP_org_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API char *GeoIP_org_by_addr_v6 (GeoIP* gi, const char *addr); + GEOIP_API char *GeoIP_org_by_name_v6 (GeoIP* gi, const char *name); + GEOIP_API int GeoIP_id_by_addr_v6 (GeoIP* gi, const char *addr); + GEOIP_API int GeoIP_id_by_name_v6 (GeoIP* gi, const char *host); + GEOIP_API int GeoIP_id_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API GeoIPRegion * GeoIP_region_by_addr_v6 (GeoIP* gi, const char *addr); + GEOIP_API GeoIPRegion * GeoIP_region_by_name_v6 (GeoIP* gi, const char *host); + GEOIP_API GeoIPRegion * GeoIP_region_by_ipnum_v6 (GeoIP *gi, geoipv6_t ipnum); + GEOIP_API void GeoIP_assign_region_by_inetaddr_v6(GeoIP* gi, geoipv6_t inetaddr, GeoIPRegion *gir); + GEOIP_API char *GeoIP_name_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API char *GeoIP_name_by_addr_v6 (GeoIP* gi, const char *addr); + GEOIP_API char *GeoIP_name_by_name_v6 (GeoIP* gi, const char *name); + + # allowed input for addr + 2001:4860:0:1001::68 + ::85.8.93.71 + ::1 + ::5508::5d47 + ::ffff:5508::5d47 + + # allowed input for host + ipv6.google.com + 2001:4860:0:1001::68 + ::85.8.93.71 + ::1 + ::5508::5d47 + ::ffff:5508::5d47 + ( Boris Zentner ) + * Fix geoiplookup usage string ( add -d -f ) ( Boris Zentner ) + * Added GeoIP_range_by_ip, returns the start and end IP address for the range containing the IP address. + This range has a constant value in the GeoIP database. + * Add geoipupdate-pureperl.pl a alternative geoipupdate version. with Proxy Server support via via the "http_proxy" environment variable. Easy to customize. ( Boris Zentner ) + * Add WIN64 since WIN32 is not defined on WIN64 Systems ( Boris Zentner ) + * Fix WIN32 compilation by encircle all MMAP functions with #ifdef WIN32 #endif pairs. MMAP is not avail in W32 ( Boris Zentner ) + * Update timezone/generate_timeZone.pl ( Boris Zentner ) + * Update libGeoIP/timeZone.c ( Boris Zentner ) + * Added GeoIP_printf and GeoIP_fprintf as a experimental feature to + libGeoIPUpdate. ( Boris Zentner, Andrew Droffner ) + * Added cast in _iso_8859_1__utf8 function to fix NetWare/Win32 compilation issue (Guenter Knauf) + * Add HTTP Proxy Server support for geoipupdate via the "http_proxy" + environment variable. + ie: export http_proxy="http://proxy-hostname:port" + ( Andrew Droffner, Derek Nicol ) + * Notice, that __YOU__ need to free the results of + + GeoIP_database_info + GeoIP_name_by_ipnum + GeoIP_name_by_addr + GeoIP_name_by_name + GeoIP_org_by_ipnum + GeoIP_org_by_addr + GeoIP_org_by_name + + not libgeoip + ( Boris Zentner, Andrew Cheung ) + * Fixed segfault with geoiplookup, if used with a custom_file database, that + could not be opened. ( Boris Zentner ) + * Add Usage info for options -f and -d in geoipupdate ( Boris Zentner ) + * Fixed segfault with geoipupdate when called with a illformed license file + ( Boris Zentner ) + * Update add more timezones to GeoIP_time_zone_by_country_and_region + ( Boris Zentner ) + * Add array access functions so programs can avoid accessing the + arrays directly which whould break binary compatability (Ludwig Nussel at SUSE) + * Updated README to state API is only thread-safe if GEOIP_CHECK_CACHE is not used + +1.4.4 2008-1-21 + * Updated original geoipupdate to return "Invalid product ID or subscription expired" + * Added BL/Saint Barthelemy, MF/Saint Martin (ISO-3166-1 additions) + * Check for illegal IP strings, return 0 if IP is not well formed IPv4 e.g. 1.2.3.4.5 and 1.2.3 + * Clarified that while core GeoIP library is LGPL, libGeoIPUpdate depends on md5.c and types.h which are GPL. + * speedup the conversion from ipstring to ipnum in _GeoIP_addr_to_num. Doubles the speed of GEOIP_MEMORY_CACHE and GEOIP_MMAP_CACHE + * Added new mmap shared memory caching option, GEOIP_MMAP_CACHE (Peter Shipley, LookSmart) + - mmaps: our maps are shared, but we need only private readonly pages + +1.4.3 2007-8-30 + ! CHANGE with geoiplookup facility: -v flag now returns database info for all databases, not just GeoIP Country + * Added ability to get netmask of network block from last lookup using GeoIP_last_netmask + * Fixed GeoIP_database_info bug with GeoLite City + * Replaced 4 with sizeof(char*) to fix issues with geoipupdate on 64 Bit machines + * Added GeoIP_set_charset function - enables UTF8 output of city name if GEOIP_CHARSET_UTF8 flag is passed + to GeoIP_set_charset + * Fixed segfault issue if calling GeoIP_db_avail before opening a database + * Added continent_code to GeoIP City's record struct (Frank Mather) + +1.4.2 2007-2-8 + * Added -d flag to enable custom path for geoipupdate utility program (Frank Mather) + * Replaced _WIN32 with WIN32 since WIN32 is already set by compilers + * Moved var definitions to top of code, defined size_t (Guenter Knauf) + * Added Makefile.win32, Makefile.netware, get_ver.awk, geoip.ico to EXTRA_DIST in Makefile.am (Guenter Knauf) + +1.4.1 2007-1-2 + * Replaced CS/Serbia and Montenegro with RS/Serbia, removed ZR/Zaire, added ME/Montenegro + * Added AX/Aland Islands, GG/Guernsey, IM/Isle of Man, JE/Jersey (ISO-3166-1 changes) + * Added GeoIP_time_zone_by_country_and_region, to lookup zoneinfo timezone by country and region (Frank Mather) + * Added GeoIP_region_name_by_code, to lookup region name from region code (Frank Mather) + * added -f and -d flags to enable custom paths for geoiplookup utility program (Frank Mather) + * Added benchmarks for GeoIP Region and City in test/benchmark.c (Frank Mather) + * Fixed build issue when using --as-needed flag (Diego 'Flameeyes' Petten) + * Add sanity checking for filename returned by MaxMind.com server for geoipupdate filename + (Dean Gaudet, arctic.org) + * Fixed memory leaks under error conditions, buffer overflow using sprintf, + and issue where a corrupted cache file could core dump the file + (Nick Galbreath, Right Media Inc) + +1.4.0 2006-8-7 + * Changed license from GPL to LGPL, so that PHP Extension can be included in PECL (Olivier Hill) + * Rewrote GEOIP_CHECK_CACHE code, fixed numerous bugs + - CheckCache now works if GeoIP file is overwriten by mv command + - Fixed bug where CheckCache kept reloading in GEOIP_STANDARD_MODE + - Fixed segfault issue in GEOIP_MEMORY_CACHE mode + - Fixed garbage data appearing in GEOIP_INDEX_CACHE mode + - Fixed realloc in case realloc returns new memory block (Andre Morozov of Stone Steps) + * Updated geoipupdate to print status messages for each database instead of just last database + * Check that gi is not null before running code in GeoIP_delete + * Fixed alpha-3 codes ordering, replaced TLS,TKM,TUN,TON with TKM,TUN,TON,TLS + * TP/East Timor changed to TL/Timor-Leste, reflecting changes in ISO-3166 + * Added Netware and Windows makefiles (Guenter Knauf) + * Fixed NetWare compiler issue with char block[block_size] declaration (Guenter Knauf) + * Updated geoipupdate example to run weekly + +1.3.17 2006-5-14 + * Fixed headers for Windows/Netware compilation (Guenter Knauf) + * Fixed Received Error -21 (Sanity check database_info string failed) + when running geoipupdate with GeoIP Country when UserId and + productIds were not specified. Bug was introduced in 1.3.15. + +1.3.16 2006-4-17 + * Fixed compliation error in GeoIPUpdate.c + +1.3.15 2006-4-14 + * Updated README documentation + * Updated geoipupdate so that it writes file as it is uncompressed instead + of storing entire GeoIP.dat file in memory (Frank Mather) + * Updated geoiplookup so that it returns GeoIP Domain Name if available + (Frank Mather) + * Updated geoipupdate so that it reports whether databases are updated + in non-verbose mode (Frank Mather) + +1.3.14 2005-9-7 + * Check if byte, ushort, ulong, u16, u32 are defined in configure + script. Fixes compilation issue on FreeBSD systems. + * Check for Big Endian byte order (needed for MD5 code in geoipupdate + to work properly on Mac OS X and other Big Endian processors) + * Fixed GEOIP_CHECK_CACHE mode when used with GEOIP_STANDARD to + only refresh upon file change + * Fixed memory leak when refreshing file in GEOIP_CHECK_CACHE mode + * Updated ltmain.sh to support Debian GNU/k*BSD bug #315425 (Marek Habersack) + * Added lookup functions using IP numeric representation as input (Frank Mather) + * Removed geoipexport + * Replaced Yugoslavia with Serbia and Montenegro + * Updated geoiplookup to only perform country lookup once instead of twice by using GeoIP_id_by_name + +1.3.13 2005-8-1 + * Fixed autoconf weirdness that resulted in libraries being + installed without .so suffix + +1.3.12 2005-7-19 + * Removed -lGeoIP from libGeoIPUpdate_la_LIBADD - fixes compilation error + if GeoIP isn't already installed (Thomas Steudten) + +1.3.11 2005-7-7 + * Fixed gcc warnings and bug. Use int + instead of char for checking the return value of getopt in geoipupdate.c. + Moved the internal functions to GeoIP_internal.h to get rid + of those 'implicit declaration' warnings. (Ludwig Nussel/SUSE) + * Cleaned up name space by prefixing internal functions with + _GeoIP* (Ludwig Nussel/SUSE) + * Memory Leak fix for GeoIP City if fread error + * Added more verbose error messages for geoipupdate (Frank Mather) + * Added check for zlib.h to configure.in + +1.3.10 2005-4-17 + * Added types.h to Makefile.am - fixes compilation error + +1.3.9 2005-4-14 + * fixed bug with GEOIP_INDEX_CACHE (Frank Mather) + * fixed segfault issue if GeoIP.dat not found (Frank Mather) + * Updated MD5 checksum code to use GnuPG code which works + on 64bit machines (Frank Mather) + * Fixed memory leak in test-geoip-isp.c and test-geoip-org.c + * Added support for GeoIP Domain Names in geoipupdate + +1.3.8 2004-11-7 + * Updated geoipupdate to report invalid userID and productID errors + * Check if gethostbyname_r is version that returns int or is other version + - should fix compile errors on Solaris and FreeBSD + * Updated URL to get license key, userId, and product Ids in conf/GeoIP.conf.default + * Updated test case, removed www.asahi.com + * Added support for GEOIP_INDEX_CACHE - which just caches + the most frequently access index portion of the database, resulting + in faster lookups than GEOIP_STANDARD, but less memory usage than + GEOIP_MEMORY_CACHE (Frank Mather) + +1.3.7 2004-10-5 + * Updated test case, removed www.bundesregierung.de added www.asahi.com + +1.3.6 2004-8-8 + * Check for gethostbyname_r support in configure (Mac OS X doesn't support gethostbyname_r) + * Made GeoIP City code thread safe + * Fixed bug with geoipupdate reading in product ids + * Added support for GeoIP Netspeed geoipupdate + * Fix memleak in lookupaddress (Ludwig Nussel/SUSE) + * Add prototype for _full_path_to to make 64bit clean + (Ludwig Nussel/SUSE) + * Add return values to test programs (Ludwig Nussel/SUSE) + +1.3.5 2004-7-5 + * Added more documentation to README file + * Made GEOIP_CHECK_CACHE work with GEOIP_STANDARD mode - reloads filehandle + in case file changes. + * Added GeoIP_country_code_by_ipnum and GeoIP_id_by_ipnum to use + existing ulong IP Address in numeric form instead of having to + convert it to string (Boris Hajduk) + * Made code thread safe by replacing gethostbyname with gethostbyname_r + +1.3.4 2004-6-4 + * Fixed bug where *.gz file(s) didn't get removed after geoipupdate + +1.3.3 2004-6-2 + * Added support for NetSpeed lookup to geoiplookup + * inet_addr patch for 64 bit systems (Thomas Steudten) + * Added Support for automated downloads of GeoIP Region, City, ISP and Organization databases (Frank Mather) + * INADDR_NONE Patch for Solaris 9 (John Young) + +1.3.2 2004-4-20 + * Added support for Maxmind NetSpeed + +MinGW patch from Stanislaw Pusep + +I was re-compiling Geolizer (http://sysd.org/log.php#glzr) on Win32 so I firstly needed to put up-to-date Win32 compatibility of libGeoIP itself. Fortunately MinGW plataform evolved a lot since last time I used it to compile libGeoIP. I'm sending you the patch with changes required for libGeoIP to work on both Win32 and UN*X. UN*X behavior is unaffected. Now, detailed explanation of what I did at all: +1) Made correct header imports for both Win32 and UN*X. UN*X imports netdb.h & netinet/in.h and Win32 imports windows.h & winsock.h +2) Win32 gethostbyname() is only able to resolve hostnames, it can't convert "127.0.0.1" string to 32-bit IP address. Thus I added lookupaddress() function that safely resolves any string to IP address and replaced all gethostbyname() calls by it. +3) Database files were referenced by pre-compiled static strings. I malloc()ed buffers for file names so they can be changed "on fly". Thus, on Win32 version GeoIP.dat & other files are being seeked in the same directory as executable file or library. +4) Added README.MinGW file with brief explanation on how to get GeoIP working under MinGW system. + +1.3.1 2003-11-11 + * Check for stdint.h in autoconf (Sean Chittenden) + * prevent the geoipupdate man page from trying to install itself directly in the system directory (Gyepi Sam) + +1.3.0 2003-09-29 + * Fixed includes to compile on Windows (Fabrice Colin) + * Removed the _addr_to_num() calls from GeoIP_*_by_name() + * _seek_record() optimizations (Maurice Cinquini) + 1) Use a single buf ptr inside the loops. + Set to the stack buffer or the cached memory the start of the function. + 2) Unroll the i=0,1 loop to allow constant folding. + 3) Unroll the j loop for the common case of j = STANDARD_RECORD_LENGTH + (I've already done the above changes see attached function.) + With gcc -O2 calculating x[0] and x[1] for STANDARD_RECORD_LENGTH now + only takes 15 (was > 100) i80x86 instructions with 6 byte accesses of RAM. 4) only calculate x[0], x[1] when needed, may be a bigger win + than the above since all the other optimizations above only reduced + CPU instructions operating on CPU cached RAM. + ! IMPORTANT API Change: Changed GeoIPRegion to have region in structure. Saves space and a malloc. + Since GeoIPRegion.region is no longer a pointer but an in-structure + array so test the first byte of region == 0 rather testing if the region + pointer is NULL. (Maurice Cinquini) + * Added GeoIP_assign_region_by_inetaddr which doesn't do any mallocs and made all other region APIs go thru it (Maurice Cinquini) + * Replaced _h_addr_to_num() with ntohl() and removed _h_addr_to_num() (Maurice Cinquini) + * Fixed bug when IP address not found in region rev1 database (Jason Linhart) + * Added added extern "C" to GeoIPCity.h fixes problems when included in C++ library + +1.2.2 2003-08-10 + * Added support for GeoIP ISP Edition identifier + * Fixed bug in GeoIP_database_info (Jason Linhart) + * Added support for GeoIP AS Number Edition + ! renamed GeoIP_org_by_* functions to GeoIP_name_by_* to reduce confusion + since these functions are used by GeoIP ISP and GeoIP ASNum as well + as GeoIP Organization + * Added support for GeoIP Proxy Edition + ! renamed GeoIP_country_id_by_* functions to GeoIP_id_by_* + +1.2.1 2003-07-12 + * Added GeoIP_record_id_by_addr and GeoIP_next_record functions + * Added support for new GeoIP Region format, including Canadian Provinces + +1.2.0 2003-04-26 + * Added support for GeoIP City format revision 1, including dma code and area code + * geoiplookup returns results from GeoIP Region, City, ISP and Organization databases + * Standardized location for GeoIP Region, City, ISP and Organization databases + * Added GeoIP_open_type to open database from default location for other dbs besides country + * Added check to make sure that the appropriate database is loaded for each lookup method + * Updated update code to check for first 12 characters of license key + * Added GeoIP_country_continent array to lookup continent by country ID + +1.1.9 2003-03-10 + * merged windows patch into main code base (Kenneth R. Robinette) + * Changed const int to #define for windows compatibility + +1.1.8 2003-03-04 + * Fixed bug with city database introduced in 1.1.6 + +1.1.7 2003-03-04 + * Fixed bug introduced in 1.1.6 when run in GEOIP_STANDARD mode + * Added test to test GEOIP_STANDARD + +1.1.6 2003-03-03 + * Added spec for building RPMs (Ryan Weaver) + * Added support for 4byte records for Organization database + * Changed Taiwan, Province of China to Taiwan + +1.1.5 2003-02-10 + * Added support for GeoIP Organization database + +1.1.4 2002-12-30 + * Cast number to int in _num_to_addr in geoipexport (Ralf S. Engelschall) + * Removed printf debug statements from geoipexport + * correct library build ordering (Ralf S. Engelschall) + * ulong -> unsigned long (Sean Chittenden) + +1.1.3 2002-12-24 + * Added GeoIPUpdate.h to EXTRA_DISTS + * Compile fixes for Solaris, FreeBSD (Michael McClennen, Corris Randall) + * Handle NULL in printf in test-geoip-region + +1.1.2 2002-12-16 + * Added support for postal codes + * Added geoipexport, program to export bit binary file to + binary tree format and csv format + * Split update code into separate library, GeoIPUpdate.la + * Allow passing NULL callback to GeoIP_update_database function + (Sean Chittenden) + * Added geoipexport program, exports to CSV file + * Added GeoIP_database_edition method + * Changed DATADIR to GEOIPDATADIR + +1.1.1 2002-11-07 + * Fixed segfault issue with GeoIPRegion_delete + * Handle test failures where lookup returns NULL more gracefully + +1.1.0 2002-11-06 + * Perform sanity checking before installing datebase using geoipupdate + * Removed file locking, since we install file by renaming instead of writing to it. + * Fixed geoipupdate to check for NULL return value + * Added constants for different editions + * Added O1 code for "Other country", used in per-country city editions + * fixed multi-line string literals warning in test-geoip.c + * Use enum constants for GeoIP_update_database values + * Added GEOIP_CHECK_CACHE option (not working yet) + +1.0.10 2002-10-28 + * IMPORTANT API Change - Return NULL instead of '--' and 'N/A' + Be sure to check the return value for NULL to avoid segmentation faults!!!! + * Added callback to print messages from GeoIP_update_database + * Moved GeoIPConfFile to geoipupdate.c + * Changed databaseSegments to unsigned int (Chris Gibbs) + * Fixed compiler warnings (Chris Gibbs) + * API Change - GeoIPRegion region member set to NULL when no region available + * Change short int to int (Chris Gibbs) + * Added write/read file locking for GeoIPUpdate.c/GeoIP.c + +1.0.9 2002-10-16 + * removed -ansi from Makefile.am to avoid compile error on Solaris 8 + * Compile fix for FreeBSD Stable (Kimura Fuyuki) + +1.0.8 2002-10-05 + * Included header required for *BSD (Akinori Musha) + +1.0.7 2002-10-05 + * Fixed compilation error with GeoIPUpdate.c + +1.0.6 2002-10-04 + * Moved update code into separate file + * Added md5 checksums to update code + * Fixed memory leak when running geoiplookup -v + * Moved const RECORD_LENGTH to #define RECORD_LENGTH for Windows compatibility + (Randy Kobes) + * Cleaned up GeoIP_new code + +1.0.5 2002-09-23 + * Supports GeoIP Regional Edition + * Macau is now "Macao" per ISO 3166-1 change + * Romania "ROM" is now "ROU" per ISO 3166-1 change + * Added #define for memcpy -> BSD's bcopy (Chris Gibbs) + * Removed "private" functions from GeoIP.h + +1.0.4 2002-08-27 + * rewrote _seek_country to use loop instead of recursion for faster performance + * Removed "orphan" nodes from demo database resulting in smaller size (Jason Linhart) + * Moved changes for building windows DLL into separate patch + * Fixed segfaults when passed malformed IP addresses + +1.0.3 2002-08-26 + * Added more changes for windows compatibility + (Stanislaw Pusep) + * Added benchmark program + +1.0.2 2002-08-21 + * Open database using "rb" for windows compatibility + (Stanislaw Pusep) + * Removed superfluous inet_ntop command (Stanislaw Pusep) + +1.0.1 2002-08-20 + * Fixed bug with resolving hostnames + * More fixes for compiler warnings (Chris Gibbs) + * Changed int to unsigned int in _is_ipaddr (Chris Gibbs) + +1.0.0 2002-08-12 + * Changed license to GPL + * Don't perform Reverse DNS lookups on IP addresses + * Only include getopt.h on Linux (OpenPKG patch) + * Avoid the_license_key_str warning (OpenPKG patch) + * Added license for March 2002 database + +0.3.0 2002-08-04 + * Added support for 'A2', Satellite Providers + +0.2.8 2002-07-30 + * Handle malformed input gracefully + * Added section to README on Solaris workarounds + * Added geoipupdate man page + +0.2.7 2002-07-27 + * Added section to README on automatic updates + * link to socket library on solaris + +0.2.6 2002-07-25 + * optimized GeoIP_open (Chris Gibbs) + * check for partial file read in GeoIP_open (Chris Gibbs) + * optimized _addr_to_num() (Chris Gibbs) + * changed write and read to send and recv for sockets + * Only install GeoIP.conf and GeoIP.dat if not already installed + +0.2.5 2002-07-22 + * Added verbose option to GeoIP_update_database + +0.2.4 2002-07-22 + * Fix for GeoIP_update_database + +0.2.3 2002-07-22 + * Fixes for FreeBSD + * All calls to malloc are checked for NULL pointer (Chris Gibbs) + * Fixed spelling of "Kazakhstan" (Chris Gibbs) + * Initialize cache_buf to NULL (Chris Gibbs) + * More memory leak fixes (Chris Gibbs) + +0.2.2 2002-07-18 + * Added update database function + * Fixed memory leak in GeoIP_new (Chris Gibbs) + +0.2.1 2002-07-03 + * Added support for anonymous proxies + +0.2.0 2002-06-23 + * Added new memory caching option for improved performance + +0.1.7 2002-05-29 + * Only add -lnsl for systems that support libnsl + * Added decl for 3 letter country code array to GeoIP.h + +0.1.6 2002-05-25 + * Added 3 letter country code + +0.1.5 2002-05-23 + * Added -lnsl fixed compile errors + +0.1.4 2002-05-11 + * Fixed bugs in demo March 2002 database + +0.1.3 2002-04-21 + * Fixed bug related to signed int (Brian Grossman) + * Better error handling when hostname not found + * Fixed bug when netmask=32 for netblock + +0.1.2 2002-04-20 + * Added two new functions, GeoIP_country_id_by_addr + and GeoIP_country_id_by_name. + * Made GeoIP_country_code and GeoIP_country_name + viewable outside of library, to be with with + GeoIP_country_id_by_* functions. + +0.1.1 2002-04-07 + * GeoIP.h is now installed to includedir + * constructor and destructor are now provided by + GeoIP_new, GeoIP_open, and GeoIP_delete + +0.1.0 2002-04-07 + * Initial release diff --git a/src/libs/resiprocate/contrib/GeoIP/GeoIP.spec.in b/src/libs/resiprocate/contrib/GeoIP/GeoIP.spec.in new file mode 100644 index 00000000..072cd1f5 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/GeoIP.spec.in @@ -0,0 +1,80 @@ +Name: @PACKAGE@ +Version: @VERSION@ +Summary: GeoIP is a C library finds the location of an IP address. +Release: 1 +Group: System Environment/Libraries +URL: http://www.maxmind.com/app/c +Vendor: MaxMind LLC +Source0: http://www.maxmind.com/download/geoip/api/c/GeoIP-%{version}.tar.gz +License: GPL +BuildRoot: %{_tmppath}/%{name}-%{version}-root + +%description +GeoIP is a C library that enables the user to find geographical and +network information of an IP address. +Included is a free GeoLite Country database +that is updated at the beginning of every month. +To download the latest free GeoLite Country database, go to: +http://www.maxmind.com/app/geoip_country + +There is also a free city-level geolocation database, GeoLite City, +available from: +http://www.maxmind.com/app/geolitecity + +%package devel +Summary: GeoIP headers, libraries +Group: Development/Libraries +Requires: %name = %{version} + +%description devel +This package contain the devel files for GeoIP. + +%prep +%setup -q + +%build +%configure +make +make check + +%install +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +%makeinstall +# Fixup permissions on shared libraries so that findreqs will work right. +chmod 755 $RPM_BUILD_ROOT/%{_libdir}/* + +%clean +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root) +%doc AUTHORS COPYING ChangeLog README TODO +%attr(0755,root,root) %{_libdir}/*.so.*.* +%{_bindir}/* +%{_sysconfdir}/* +%dir %{_datadir}/GeoIP +%{_datadir}/GeoIP/* +%{_libdir}/*.so +%{_mandir}/*/* + +%files devel +%{_includedir}/* +%{_libdir}/*.a +%{_libdir}/*.la + +%changelog +* Fri Apr 14 2006 Thomas Mather +- Updated description to reference free GeoLite City database + +* Thu Jul 7 2005 Thomas Mather +- Updated description to reflect monthly updates for free country database. + +* Mon Sep 8 2003 Dr. Peter Bieringer +- Fix for RHL 9, created a new devel package definition. + +* Thu Feb 27 2003 Ryan Weaver +- Initial RPM Build diff --git a/src/libs/resiprocate/contrib/GeoIP/GeoIP1.4.8-Win.patch b/src/libs/resiprocate/contrib/GeoIP/GeoIP1.4.8-Win.patch new file mode 100644 index 00000000..362f9fab --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/GeoIP1.4.8-Win.patch @@ -0,0 +1,83 @@ +Index: GeoIP.c +=================================================================== +--- GeoIP.c (revision 9431) ++++ GeoIP.c (working copy) +@@ -26,6 +26,32 @@ + #include + #include + #include ++#else ++#define ssize_t SSIZE_T ++#include ++#include ++ ++ssize_t pread (int fd, void *buf, size_t count, off_t offset) ++{ ++ HANDLE handle = (HANDLE)(intptr_t)_get_osfhandle (fd); ++ ++ OVERLAPPED olap = { 0 }; ++ DWORD written; ++ ++ if (handle == INVALID_HANDLE_VALUE) ++ return -1; ++ ++ olap.Offset = offset; ++ //olap.OffsetHigh = offset >> 32; ++ ++ /* This braindead API will override the file pointer even if we specify ++ * an explicit read offset... So do not expect this to mix well with ++ * regular read() calls. */ ++ if (ReadFile (handle, buf, count, &written, &olap)) ++ return written; ++ return -1; ++} ++ + #endif /* !defined(_WIN32) */ + + #include +Index: GeoIPCity.c +=================================================================== +--- GeoIPCity.c (revision 9431) ++++ GeoIPCity.c (working copy) +@@ -38,8 +38,8 @@ + static + const int FULL_RECORD_LENGTH = 50; + +-static const int CITYCONFIDENCE_FIXED_RECORD = 4; +-static const int CITYCONFIDENCEDIST_FIXED_RECORD = 6; ++#define CITYCONFIDENCE_FIXED_RECORD 4 ++#define CITYCONFIDENCEDIST_FIXED_RECORD 6 + + + static +@@ -55,6 +55,7 @@ + double latitude = 0, longitude = 0; + int metroarea_combo = 0; + int bytes_read = 0; ++ int t = 0; + if (seek_record == gi->databaseSegments[0]) + return NULL; + +@@ -93,11 +94,12 @@ + record->city_conf = tmp_fixed_record[2]; + record->postal_conf = tmp_fixed_record[3]; + ++ t = fixed_rec_size - gi->record_length; ++ + record->accuracy_radius = + gi->databaseType == GEOIP_CITYCONFIDENCEDIST_EDITION + ? ((tmp_fixed_record[4] + (tmp_fixed_record[5] << 8)) & 0x3ff) : 0x3ff; + +- int t = fixed_rec_size - gi->record_length; + + record_pointer = dseg + tmp_fixed_record[t] + + (tmp_fixed_record[t + 1] << 8) + (tmp_fixed_record[t + 2] << 16) ; +@@ -129,7 +131,7 @@ + gi->databaseType == GEOIP_CITYCONFIDENCEDIST_EDITION + ? ((record_buf[4] + (record_buf[5] << 8)) & 0x3ff) : 0x3ff; + +- int t = fixed_rec_size - gi->record_length; ++ t = fixed_rec_size - gi->record_length; + + record_pointer = dseg + record_buf[t] + + (record_buf[t + 1] << 8) + (record_buf[t + 2] << 16) ; diff --git a/src/libs/resiprocate/contrib/GeoIP/GeoIPWinDLL.patch b/src/libs/resiprocate/contrib/GeoIP/GeoIPWinDLL.patch new file mode 100644 index 00000000..98119fc2 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/GeoIPWinDLL.patch @@ -0,0 +1,183 @@ +Index: GeoIP.c +=================================================================== +RCS file: /home/maxmind/geoip/c/libGeoIP/GeoIP.c,v +retrieving revision 1.32 +retrieving revision 1.33 +diff -u -r1.32 -r1.33 +--- GeoIP.c 25 Aug 2002 22:42:48 -0000 1.32 ++++ GeoIP.c 27 Aug 2002 06:50:02 -0000 1.33 +@@ -23,16 +23,24 @@ + #include + #include + #include ++#ifndef _WIN32 + #include ++#endif /* _WIN32 */ + #include + #include /* for fstat */ + #include /* for fstat */ + #include "zlib.h" + #include "time.h" + ++#ifndef _WIN32 ++#include + #include + #include + #include ++#else ++#include ++#include ++#endif /* _WIN32 */ + + #define COUNTRY_BEGIN 16776960; + const int RECORD_LENGTH = 3; +@@ -57,9 +65,66 @@ + const char *GeoIPUpdateHost = "updates.maxmind.com"; + const char *GeoIPHTTPRequest = "GET /app/update?license_key=%s HTTP/1.0\nHost: updates.maxmind.com\n\n"; + ++#ifdef _WIN32 ++char * _dat_in_module_path () { ++ HMODULE GeoIPdll; ++ struct _stat st; ++ int i; ++ char * buf; ++ ++ buf = (char *) malloc(MAX_PATH); ++ ++ GeoIPdll = GetModuleHandle("GeoIP.dll"); ++ if (!GeoIPdll) ++ { ++ GeoIPdll = GetModuleHandle(NULL); ++ if (!GeoIPdll) ++ return NULL; ++ } ++ GetModuleFileName(GeoIPdll, buf, MAX_PATH); ++ for (i = strlen(buf); (i >= 0) && (buf[i] != '\\'); i--); ++ if (i) ++ { ++ buf[i] = '\0'; ++ strcat(buf, "\\"); ++ strcat(buf, GeoIPDBFileName); ++ if (_stat(buf, &st) == 0) ++ return buf; ++ } ++ ++ free(buf); ++ return NULL; ++} ++ ++char * _dat_path_in_regkey () { ++ DWORD lpdwDisposition, type, size = MAX_PATH; ++ HKEY hkGeoIP; ++ char * buf, * filename; ++ ++ buf = (char *) malloc(MAX_PATH); ++ filename = (char *) malloc(MAX_PATH); ++ ++ if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\MaxMind\\GeoIP", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkGeoIP, &lpdwDisposition) != ERROR_SUCCESS) ++ return NULL; ++ if (RegQueryValueEx(hkGeoIP, "DATADIR", 0, &type, buf, &size) != ERROR_SUCCESS) ++ strcpy(buf, "%SystemRoot%\\SYSTEM32"); ++ if (RegSetValueEx(hkGeoIP, "DATADIR", 0, REG_EXPAND_SZ, buf, strlen(buf)) != ERROR_SUCCESS) ++ return NULL; ++ ExpandEnvironmentStrings(buf, filename, MAX_PATH); ++ ++ free(buf); ++ strcat(filename, "\\"); ++ strcat(filename, GeoIPDBFileName); ++ ++ return filename; ++} ++#endif /* _WIN32 */ ++ + GeoIP* GeoIP_new (int flags) { + char * filename; + GeoIP * gi; ++ ++#ifndef _WIN32 + filename = malloc(sizeof(char) * (strlen(DATADIR)+strlen(GeoIPDBFileName)+2)); + if (filename == NULL) + return NULL; +@@ -67,6 +132,17 @@ + strcat(filename, DATADIR); + strcat(filename, "/"); + strcat(filename, GeoIPDBFileName); ++#else ++ filename = _dat_in_module_path(); ++ if (filename == NULL) ++ filename = _dat_path_in_regkey(); ++ if (filename == NULL) ++ { ++ fprintf(stderr,"Unable to query registry for database location\n"); ++ return NULL; ++ } ++#endif /* _WIN32 */ ++ + gi = GeoIP_open (filename, flags); + free(filename); + return gi; +@@ -96,7 +172,7 @@ + } + gi->cache = (unsigned char *) malloc(sizeof(unsigned char) * buf.st_size); + if (gi->cache != NULL) { +- if (fread(gi->cache, sizeof(unsigned char), buf.st_size, gi->GeoIPDatabase) != buf.st_size) { ++ if (fread(gi->cache, sizeof(unsigned char), buf.st_size, gi->GeoIPDatabase) != (unsigned) buf.st_size) { + fprintf(stderr,"Error reading file %s\n",filename); + free(gi->cache); + free(gi); +Index: GeoIP.h +=================================================================== +RCS file: /home/maxmind/geoip/c/libGeoIP/GeoIP.h,v +retrieving revision 1.19 +retrieving revision 1.20 +diff -u -r1.19 -r1.20 +--- GeoIP.h 20 Aug 2002 00:52:00 -0000 1.19 ++++ GeoIP.h 27 Aug 2002 06:50:02 -0000 1.20 +@@ -45,25 +45,31 @@ + extern const char * GeoIP_country_name[246]; + extern const char * GeoIPConfFile; + +-GeoIP* GeoIP_new(int flags); +-GeoIP* GeoIP_open(char * filename, int flags); +-void GeoIP_delete(GeoIP* gi); +-const char *GeoIP_country_code_by_addr (GeoIP* gi, const char *addr); +-const char *GeoIP_country_code_by_name (GeoIP* gi, const char *host); +-const char *GeoIP_country_code3_by_addr (GeoIP* gi, const char *addr); +-const char *GeoIP_country_code3_by_name (GeoIP* gi, const char *host); +-const char *GeoIP_country_name_by_addr (GeoIP* gi, const char *addr); +-const char *GeoIP_country_name_by_name (GeoIP* gi, const char *host); +-short int GeoIP_country_id_by_addr (GeoIP* gi, const char *addr); +-short int GeoIP_country_id_by_name (GeoIP* gi, const char *host); ++#ifdef _WIN32 ++#define GEOIP_API __declspec(dllexport) ++#else ++#define GEOIP_API ++#endif /* _WIN32 */ + +-char *GeoIP_database_info (GeoIP* gi); +-short int GeoIP_update_database (GeoIP* gi, char * license_key, int verbose); ++GEOIP_API GeoIP* GeoIP_new(int flags); ++GEOIP_API GeoIP* GeoIP_open(char * filename, int flags); ++GEOIP_API void GeoIP_delete(GeoIP* gi); ++GEOIP_API const char *GeoIP_country_code_by_addr (GeoIP* gi, const char *addr); ++GEOIP_API const char *GeoIP_country_code_by_name (GeoIP* gi, const char *host); ++GEOIP_API const char *GeoIP_country_code3_by_addr (GeoIP* gi, const char *addr); ++GEOIP_API const char *GeoIP_country_code3_by_name (GeoIP* gi, const char *host); ++GEOIP_API const char *GeoIP_country_name_by_addr (GeoIP* gi, const char *addr); ++GEOIP_API const char *GeoIP_country_name_by_name (GeoIP* gi, const char *host); ++GEOIP_API short int GeoIP_country_id_by_addr (GeoIP* gi, const char *addr); ++GEOIP_API short int GeoIP_country_id_by_name (GeoIP* gi, const char *host); + +-int _seek_country (GeoIP* gi, const int offset, unsigned long ipnum, int depth); +-unsigned long _addr_to_num (const char *addr); +-unsigned long _h_addr_to_num (unsigned char *addr); +-short int _is_ipaddr (const char *name); ++GEOIP_API char *GeoIP_database_info (GeoIP* gi); ++GEOIP_API short int GeoIP_update_database (GeoIP* gi, char * license_key, int verbose); ++ ++GEOIP_API int _seek_country (GeoIP* gi, const int offset, unsigned long ipnum, int depth); ++GEOIP_API unsigned long _addr_to_num (const char *addr); ++GEOIP_API unsigned long _h_addr_to_num (unsigned char *addr); + + #ifdef __cplusplus + } diff --git a/src/libs/resiprocate/contrib/GeoIP/GeoIP_10_0.vcxproj b/src/libs/resiprocate/contrib/GeoIP/GeoIP_10_0.vcxproj new file mode 100644 index 00000000..d9e8d63f --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/GeoIP_10_0.vcxproj @@ -0,0 +1,200 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + GeoIP + {6527D843-EE53-4F1E-B0A9-12ABBA8E75CC} + GeoIP + Win32Proj + + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + true + true + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + false + false + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + Disabled + libGeoIP\;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;GEOIP_EXPORTS;PACKAGE_VERSION="1.4.8";DLL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + EditAndContinue + + + ws2_32.lib;%(AdditionalDependencies) + true + Windows + MachineX86 + + + copy "$(TargetPath)" ..\..\repro + + + + + Disabled + libGeoIP\;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;GEOIP_EXPORTS;PACKAGE_VERSION="1.4.8";DLL;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + ws2_32.lib;%(AdditionalDependencies) + true + Windows + + + copy "$(TargetPath)" ..\..\repro + + + + + MaxSpeed + true + libGeoIP\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;GEOIP_EXPORTS;PACKAGE_VERSION="1.4.8";DLL;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + ws2_32.lib;%(AdditionalDependencies) + true + Windows + true + true + MachineX86 + + + copy "$(TargetPath)" ..\..\repro + + + + + MaxSpeed + true + libGeoIP\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;GEOIP_EXPORTS;PACKAGE_VERSION="1.4.8";DLL;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + ws2_32.lib;%(AdditionalDependencies) + true + Windows + true + true + + + copy "$(TargetPath)" ..\..\repro + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/GeoIP/GeoIP_10_0.vcxproj.filters b/src/libs/resiprocate/contrib/GeoIP/GeoIP_10_0.vcxproj.filters new file mode 100644 index 00000000..181e7507 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/GeoIP_10_0.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/GeoIP/GeoIP_9_0.vcproj b/src/libs/resiprocate/contrib/GeoIP/GeoIP_9_0.vcproj new file mode 100644 index 00000000..52b3f0e0 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/GeoIP_9_0.vcproj @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/GeoIP/INSTALL b/src/libs/resiprocate/contrib/GeoIP/INSTALL new file mode 100644 index 00000000..7d1c323b --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/INSTALL @@ -0,0 +1,365 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/src/libs/resiprocate/contrib/GeoIP/Makefile.am b/src/libs/resiprocate/contrib/GeoIP/Makefile.am new file mode 100644 index 00000000..bd4da3a3 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -Wall -ansi + +SUBDIRS = \ + libGeoIP \ + apps \ + conf \ + data \ + test \ + man + +EXTRA_DIST = README.OSX READMEwin32static.txt README.MinGW READMEwin32.txt GeoIPWinDLL.patch TODO bootstrap GeoIP.spec GeoIP.spec.in Makefile.netware Makefile.vc Makefile.win32 get_ver.awk geoip.ico diff --git a/src/libs/resiprocate/contrib/GeoIP/Makefile.in b/src/libs/resiprocate/contrib/GeoIP/Makefile.in new file mode 100644 index 00000000..c2a5d3f5 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/Makefile.in @@ -0,0 +1,707 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/GeoIP.spec.in \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ + TODO config.guess config.sub depcomp install-sh ltmain.sh \ + missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = GeoIP.spec +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d "$(distdir)" \ + || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr "$(distdir)"; }; } +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEOIP_VERSION_INFO = @GEOIP_VERSION_INFO@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -Wall -ansi +SUBDIRS = \ + libGeoIP \ + apps \ + conf \ + data \ + test \ + man + +EXTRA_DIST = README.OSX READMEwin32static.txt README.MinGW READMEwin32.txt GeoIPWinDLL.patch TODO bootstrap GeoIP.spec GeoIP.spec.in Makefile.netware Makefile.vc Makefile.win32 get_ver.awk geoip.ico +all: all-recursive + +.SUFFIXES: +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): +GeoIP.spec: $(top_builddir)/config.status $(srcdir)/GeoIP.spec.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @$(am__cd) '$(distuninstallcheck_dir)' \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ + dist-gzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-generic distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/resiprocate/contrib/GeoIP/Makefile.netware b/src/libs/resiprocate/contrib/GeoIP/Makefile.netware new file mode 100644 index 00000000..44a569de --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/Makefile.netware @@ -0,0 +1,301 @@ +################################################################### +# +## Makefile for building GeoIP stuff (NetWare version - gnu make) +## To build the binaries you need awk, GNU make and gcc / nlmconv +## or Metrowerks CodeWarrior CommandlineTools. +## Usage: make -f Makefile.netware [all|dist|clean|distclean] +## +## hacked by: Guenter Knauf +# +################################################################### + +# Edit the path below to point to the base of your Novell NDK. +ifndef NDKBASE +NDKBASE = c:/novell +endif + +# Edit the path below to point to your zlib sources and libs. +ifndef ZLIBSDK +ZLIBSDK = d:/projects/cw/zlib-1.2.3 +endif + +ifndef DISTDIR +DISTDIR = GeoIP-$(GEOIP_VERSION_STR)-bin-nw +endif +ARCHIVE = $(DISTDIR).zip + +# Edit the vars below to change NLM target settings. +TARGETS := $(patsubst apps/%.c,%.nlm,$(wildcard apps/*.c)) +DESCR = $(subst .def,,$(notdir $@)) $(GEOIP_VERSION_STR) +COMPANY = MaxMind LLC +COPYR = Copyright (C) 2003-2006 MaxMind LLC All Rights Reserved. +WWWURL = http://www.maxmind.com/app/c +MTSAFE = YES +STACK = 64000 +#SCREEN = none +DATADIR = sys:/etc/GeoIP +CONFDIR = sys:/etc + +# Comment the line below if you dont want to link with the static libz.lib. +LSTATIC = 1 + +# Edit the var below to point to your lib architecture. +ifndef LIBARCH +LIBARCH = LIBC +endif + +# must be equal to DEBUG or NDEBUG +DB = NDEBUG +# DB = DEBUG +# Optimization: -O or debugging: -g +ifeq ($(DB),NDEBUG) + OPT = -O2 + OBJDIR = release +else + OPT = -g + OBJDIR = debug +endif +OBJLIB = lib-$(OBJDIR) + +# Include the version info retrieved from header. +-include $(OBJDIR)/version.inc + +# Global tools and toolflags used with all compilers. +ZIP = zip -qzR9 +CP = cp -afv +MV = mv -fv +# RM = rm -f +# if you want to mark the target as MTSAFE you will need a tool for +# generating the xdc data for the linker; here's a minimal tool: +# http://www.gknw.com/development/prgtools/mkxdc.zip +MPKXDC = mkxdc + +# The following line defines your compiler. +ifdef METROWERKS + CC = mwccnlm +else + CC = gcc +endif + +# Global flags for all compilers +CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc +CFLAGS += -DGEOIPDATADIR=\"$(DATADIR)\" +CFLAGS += -DSYSCONFDIR=\"$(CONFDIR)\" + +ifeq ($(CC),mwccnlm) +LD = mwldnlm +LDFLAGS = -nostdlib $(PRELUDE) $(LDLIBS) $(LIBOBJS) $(OBJDIR)/$(basename $@).o -o $@ -commandfile +AR = mwldnlm +ARFLAGS = -type library -w nocmdline $(OBJDIR)/*.o -o +LIBEXT = lib +CFLAGS += -msgstyle gcc -gccinc -opt nointrinsics -proc 586 +CFLAGS += -relax_pointers +#CFLAGS += -w on +ifeq ($(LIBARCH),LIBC) + PRELUDE = $(SDK_LIBC)/imports/libcpre.o + CFLAGS += -align 4 +else + PRELUDE = "$(METROWERKS)/Novell Support/Libraries/runtime/prelude.obj" +# CFLAGS += -include "$(METROWERKS)/Novell Support/Headers/nlm_prefix.h" + CFLAGS += -align 1 +endif +else +LD = nlmconv +LDFLAGS = -T +AR = ar +ARFLAGS = -cq +LIBEXT = lib +CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return -fno-strict-aliasing +CFLAGS += -Wall -Wno-unused #-Wno-format # -pedantic +ifeq ($(LIBARCH),LIBC) + PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o +else + PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o + CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h +endif +endif +DESCR += ($(LIBARCH)) - $(CC) build + +NDK_ROOT = $(NDKBASE)/ndk +SDK_CLIB = $(NDK_ROOT)/nwsdk +SDK_LIBC = $(NDK_ROOT)/libc + +ifeq ($(LIBARCH),LIBC) + INCLUDES += -I$(SDK_LIBC)/include -I$(SDK_LIBC)/include/nks + # INCLUDES += -I$(SDK_LIBC)/include/winsock + CFLAGS += -D_POSIX_SOURCE + # CFLAGS += -D__ANSIC__ +else + INCLUDES += -I$(SDK_CLIB)/include/nlm -I$(SDK_CLIB)/include + # INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete + CFLAGS += -DNETDB_USE_INTERNET +endif + +INCLUDES += -I./libGeoIP +INCLUDES += -I$(ZLIBSDK) +CFLAGS += $(INCLUDES) + +ifeq ($(MTSAFE),YES) + XDCOPT = -n +endif +ifeq ($(MTSAFE),NO) + XDCOPT = -u +endif + +LIBPATH += -L$(ZLIBSDK)/nw/release +ifdef LSTATIC + LDLIBS += $(ZLIBSDK)/nw/release/libz.$(LIBEXT) +else + IMPORTS += @$(ZLIBSDK)/nw/release/libz.imp + MODULES += libz +endif + +ifeq ($(findstring linux,$(OSTYPE)),linux) +DL = ' +#-include $(NDKBASE)/nlmconv/ncpfs.inc +endif + +vpath %.c ./apps ./libGeoIP + +LIBOBJS = $(OBJLIB)/GeoIP.o $(OBJLIB)/GeoIPCity.o +UPDOBJS = $(OBJLIB)/GeoIPUpdate.o $(OBJLIB)/md5.o +LIBOBJS += $(UPDOBJS) + +.PRECIOUS: $(OBJLIB)/%.o $(OBJDIR)/%.o $(OBJDIR)/%.def + + +all: prebuild $(TARGETS) + +prebuild: $(OBJLIB) $(OBJDIR) $(OBJDIR)/version.inc + +dist: $(DISTDIR) all $(DISTDIR)/readme_bin.txt + @$(CP) *.nlm $(DISTDIR) + @$(CP) Changelog $(DISTDIR) + @$(CP) README $(DISTDIR) + @$(CP) conf/GeoIP.conf.default $(DISTDIR) + @$(CP) data/GeoIP.dat $(DISTDIR) + @echo Creating $(ARCHIVE) + @$(ZIP) $(ARCHIVE) $(DISTDIR)/* < $(DISTDIR)/readme_bin.txt + +clean: + -$(RM) -r $(OBJDIR) $(OBJLIB) + -$(RM) $(TARGETS) + +distclean: + -$(RM) -r $(DISTDIR) + -$(RM) $(ARCHIVE) + +%.nlm: $(OBJDIR)/%.def $(LIBOBJS) $(OBJDIR)/%.o $(OBJDIR)/%.xdc + @echo Linking $@ + @-$(RM) $@ + @$(LD) $(LDFLAGS) $< + +$(DISTDIR): + @mkdir $@ + +$(OBJDIR): + @mkdir $@ + +$(OBJLIB): + @mkdir $@ + +$(OBJDIR)/%.o: %.c +# @echo Compiling $< + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJLIB)/%.o: %.c +# @echo Compiling $< + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)/version.inc: configure.in $(OBJDIR) + @echo Creating $@ + @awk -f get_ver.awk $< > $@ + +$(OBJDIR)/%.xdc: Makefile.netware + @echo Creating $@ + @$(MPKXDC) $(XDCOPT) $@ + +$(OBJDIR)/%.def: Makefile.netware + @echo Creating $@ + @echo $(DL)# DEF file for linking with $(LD)$(DL) > $@ + @echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@ + @echo $(DL)# All your changes will be lost!!$(DL) >> $@ + @echo $(DL)#$(DL) >> $@ + @echo $(DL)copyright "$(COPYR)"$(DL) >> $@ + @echo $(DL)description "$(DESCR)"$(DL) >> $@ + @echo $(DL)version $(GEOIP_VERSION)$(DL) >> $@ +ifdef NLMTYPE + @echo $(DL)type $(NLMTYPE)$(DL) >> $@ +endif +ifdef STACK + @echo $(DL)stack $(STACK)$(DL) >> $@ +endif +ifdef SCREEN + @echo $(DL)screenname "$(SCREEN)"$(DL) >> $@ +else + @echo $(DL)screenname "DEFAULT"$(DL) >> $@ +endif +ifeq ($(DB),DEBUG) + @echo $(DL)debug$(DL) >> $@ +endif + @echo $(DL)threadname "$(subst .def,,$(notdir $@))"$(DL) >> $@ +ifdef XDCOPT + @echo $(DL)xdcdata $(@:.def=.xdc)$(DL) >> $@ +endif +ifeq ($(LDRING),0) + @echo $(DL)flag_on 16$(DL) >> $@ +endif +ifeq ($(LDRING),3) + @echo $(DL)flag_on 512$(DL) >> $@ +endif +ifeq ($(LIBARCH),CLIB) + @echo $(DL)start _Prelude$(DL) >> $@ + @echo $(DL)exit _Stop$(DL) >> $@ + @echo $(DL)import @$(SDK_CLIB)/imports/clib.imp$(DL) >> $@ + @echo $(DL)import @$(SDK_CLIB)/imports/threads.imp$(DL) >> $@ + @echo $(DL)import @$(SDK_CLIB)/imports/nlmlib.imp$(DL) >> $@ + @echo $(DL)module clib$(DL) >> $@ +else + @echo $(DL)flag_on 64$(DL) >> $@ + @echo $(DL)pseudopreemption$(DL) >> $@ + @echo $(DL)start _LibCPrelude$(DL) >> $@ + @echo $(DL)exit _LibCPostlude$(DL) >> $@ + @echo $(DL)check _LibCCheckUnload$(DL) >> $@ + @echo $(DL)import @$(SDK_LIBC)/imports/libc.imp$(DL) >> $@ + @echo $(DL)import @$(SDK_LIBC)/imports/netware.imp$(DL) >> $@ + @echo $(DL)module libc$(DL) >> $@ +endif +ifdef MODULES + @echo $(DL)module $(MODULES)$(DL) >> $@ +endif +ifdef EXPORTS + @echo $(DL)export $(EXPORTS)$(DL) >> $@ +endif +ifdef IMPORTS + @echo $(DL)import $(IMPORTS)$(DL) >> $@ +endif +ifeq ($(LD),nlmconv) +ifdef LDLIBS + @echo $(DL)input $(LDLIBS)$(DL) >> $@ +endif + @echo $(DL)input $(PRELUDE)$(DL) >> $@ + @echo $(DL)input $(LIBOBJS)$(DL) >> $@ + @echo $(DL)input $(@:.def=.o)$(DL) >> $@ + @echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@ +endif + +$(DISTDIR)/readme_bin.txt: Makefile.netware + @echo Creating $@ + @echo $(DL)This is a binary distribution for NetWare platform.$(DL) > $@ + @echo $(DL)GeoIP version $(GEOIP_VERSION_STR)$(DL) >> $@ +ifndef LSTATIC + @echo $(DL)These binaries depend on libz.nlm in the search path!$(DL) >> $@ +endif + @echo $(DL)Please download the complete GeoIP package for$(DL) >> $@ + @echo $(DL)any further documentation:$(DL) >> $@ + @echo $(DL)$(WWWURL)$(DL) >> $@ + +info: + @echo Targets to build: $(TARGETS) + + diff --git a/src/libs/resiprocate/contrib/GeoIP/Makefile.vc b/src/libs/resiprocate/contrib/GeoIP/Makefile.vc new file mode 100644 index 00000000..bd575955 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/Makefile.vc @@ -0,0 +1,84 @@ +#NMAKE makefile for Windows developers. +#Produces a static library (GeoIP.lib). + +################################################################# +# configuration section +################################################################ + +# place to put the GeoIP.dat database file +# !!! Please keep the 2 \\ as directory separators !!! +# +GEOIPDATADIR="C:\\Windows\\SYSTEM32" +# +# System inc, lib, and bin directories +!ifndef INSTDIR +INSTDIR="C:\GeoIP-1.4.5" +!endif + +# Location where GeoIP.lib should be installed my "make install" +INSTALL_LIB=$(INSTDIR)\Lib + +#Location where .h files should be installed by "make install". +INSTALL_INC=$(INSTDIR)\Include + +#Location where programs should be installed by "make install". +INSTALL_BIN=$(INSTDIR)\Bin + +################################################################ +# end configuration section +################################################################ + +DATA_DIR=data + +DATA_FILE=GeoIP.dat + +LIB_DIR = libGeoIP + +TEST_DIR=test + +APP_DIR=apps + +GEOIP_LIB = GeoIP.lib + +APP_PROGRAMS = geoiplookup.exe + +TEST_PROGRAMS = benchmark.exe test-geoip.exe + +all: GeoIP.lib test_progs app_progs + +$(GEOIP_LIB): + cd $(LIB_DIR) + $(MAKE) -nologo -f Makefile.vc GEOIPDATADIR=$(GEOIPDATADIR) + cd .. + +test_progs: + cd $(TEST_DIR) + $(MAKE) -nologo -f Makefile.vc + cd .. + +app_progs: + cd $(APP_DIR) + $(MAKE) -nologo -f Makefile.vc + cd .. + +test: $(GEOIP_LIB) test_progs + cd $(TEST_DIR) + benchmark.exe + test-geoip.exe + cd .. + +install: $(GEOIP_LIB) app_progs + cd $(LIB_DIR) + copy $(GEOIP_LIB) $(INSTALL_LIB) + copy *.h $(INSTALL_INC) + cd ..\$(APP_DIR) + copy $(APP_PROGRAMS) $(INSTALL_BIN) + cd ..\$(DATA_DIR) + copy $(DATA_FILE) $(GEOIPDATADIR) + cd .. + +clean: + del $(LIB_DIR)\*.obj $(LIB_DIR)\*.lib \ + $(APP_DIR)\*.obj $(APP_DIR)\*.exe \ + $(TEST_DIR)\*.obj $(TEST_DIR)\*.exe + diff --git a/src/libs/resiprocate/contrib/GeoIP/Makefile.win32 b/src/libs/resiprocate/contrib/GeoIP/Makefile.win32 new file mode 100644 index 00000000..a8902d67 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/Makefile.win32 @@ -0,0 +1,232 @@ +################################################################### +# +## Makefile for building GeoIP stuff (Win32 version - gnu make) +## To build the binaries you need awk, GNU make and MingW32 gcc +## or Metrowerks CodeWarrior CommandlineTools. +## Usage: make -f Makefile.win32 [all|dist|clean|distclean] +## +## hacked by: Guenter Knauf +# +################################################################### + +# Edit the path below to point to your zlib sources and libs. +ifndef ZLIBSDK +ZLIBSDK = d:/projects/mingw32/zlib-1.2.3 +endif + +ifndef DISTDIR +DISTDIR = GeoIP-$(GEOIP_VERSION_STR)-bin-w32 +endif +ARCHIVE = $(DISTDIR).zip + +# Edit the vars below to change EXE target settings. +TARGETS := $(patsubst apps/%.c,%.exe,$(wildcard apps/*.c)) +DESCR = $(subst .rc,,$(notdir $@)) $(GEOIP_VERSION_STR) +COMPANY = MaxMind LLC +COPYR = 2003-2006 MaxMind LLC All Rights Reserved. +WWWURL = http://www.maxmind.com/app/c +LICENSE = Licensed under LGPL +ICON = geoip.ico +DATADIR = c:/GeoIP +CONFDIR = c:/GeoIP + +# Comment the line below if you dont want to link with the static libz.lib. +LSTATIC = 1 + +# must be equal to DEBUG or NDEBUG +DB = NDEBUG +# DB = DEBUG +# Optimization: -O or debugging: -g +ifeq ($(DB),NDEBUG) + OPT = -O2 + OBJDIR = release +else + OPT = -g + OBJDIR = debug +endif +OBJLIB = lib-$(OBJDIR) + +# Include the version info retrieved from header. +-include $(OBJDIR)/version.inc + +# Global tools and toolflags used with all compilers. +ZIP = zip -qzR9 +CP = cp -afv +MV = mv -fv +# RM = rm -f +RE = reimp -d +DLLTOOL = dlltool +DTFLAGS = -k + +# The following line defines your compiler. +ifdef METROWERKS + CC = mwcc +else + CC = gcc +endif + +# Global flags for all compilers +CFLAGS = $(OPT) -D$(DB) -D_WIN32 +# -nostdinc +CFLAGS += -DHAVE_STDINT_H +CFLAGS += -DGEOIPDATADIR=\"$(DATADIR)\" +CFLAGS += -DSYSCONFDIR=\"$(CONFDIR)\" + +ifeq ($(CC),mwcc) +LD = mwld +LDFLAGS = -nostdlib +LIBPATH = -lr "$(METROWERKS)/MSL" -lr "$(METROWERKS)/Win32-x86 Support/Libraries" +CWLIBS = -lMSL_Runtime_x86.lib -lMSL_C_x86.lib -lMSL_Extras_x86.lib +LDLIBS = -lkernel32.lib -luser32.lib $(CWLIBS) +AR = mwld +ARFLAGS = -type library -w nocmdline $(OBJDIR)/*.o -o +LIBEXT = lib +RC = mwwinrc +CFLAGS += -nostdinc +CFLAGS += -msgstyle gcc -gccinc -opt nointrinsics -proc 586 +CFLAGS += -relax_pointers +#CFLAGS += -w on +CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support/Headers" +else +LD = gcc +LDFLAGS = -s +AR = ar +ARFLAGS = -cq +LIBEXT = a +RC = windres +RCFLAGS = -I rc -O coff -i +CFLAGS += -Wall -Wno-unused # -Wno-format #-pedantic +endif + +INCLUDES += -I./libGeoIP +INCLUDES += -I$(ZLIBSDK) +CFLAGS += $(INCLUDES) + +LDLIBS += -lwsock32 +LIBPATH += -L$(ZLIBSDK) +ifdef LSTATIC + LDLIBS += -lz +else + LDLIBS += -lzdll +endif + +ifeq ($(findstring linux,$(OSTYPE)),linux) +DL = ' +#-include $(NDKBASE)/nlmconv/ncpfs.inc +endif + +vpath %.c ./apps ./libGeoIP + +LIBOBJS = $(OBJLIB)/GeoIP.o $(OBJLIB)/GeoIPCity.o +UPDOBJS = $(OBJLIB)/GeoIPUpdate.o $(OBJLIB)/md5.o +LIBOBJS += $(UPDOBJS) + +.PRECIOUS: $(OBJLIB)/%.o $(OBJDIR)/%.o $(OBJDIR)/%.rc + +all: prebuild $(TARGETS) + +prebuild: $(OBJLIB) $(OBJDIR) $(OBJDIR)/version.inc + +dist: $(DISTDIR) all $(DISTDIR)/readme_bin.txt + @$(CP) *.exe $(DISTDIR) + @$(CP) Changelog $(DISTDIR) + @$(CP) README $(DISTDIR) + @$(CP) conf/GeoIP.conf.default $(DISTDIR) + @$(CP) data/GeoIP.dat $(DISTDIR) + @echo Creating $(ARCHIVE) + @$(ZIP) $(ARCHIVE) $(DISTDIR)/* < $(DISTDIR)/readme_bin.txt + +clean: + -$(RM) -r $(OBJDIR) $(OBJLIB) + -$(RM) $(TARGETS) + +distclean: + -$(RM) -r $(DISTDIR) + -$(RM) $(ARCHIVE) + +%.exe: $(OBJDIR)/%.res $(LIBOBJS) $(OBJDIR)/%.o + @echo Linking $@ + @-$(RM) $@ + $(LD) $(LDFLAGS) -o $@ $^ $(LIBPATH) $(LDLIBS) +# $(LD) $(LDFLAGS) $(LIBPATH) $(LIBFILES) -o $@ $^ + +$(DISTDIR): + @mkdir $@ + +$(OBJDIR): + @mkdir $@ + +$(OBJLIB): + @mkdir $@ + +$(OBJDIR)/%.o: %.c +# @echo Compiling $< + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJLIB)/%.o: %.c +# @echo Compiling $< + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)/version.inc: configure.in $(OBJDIR) + @echo Creating $@ + @awk -f get_ver.awk $< > $@ + +$(OBJDIR)/%.res: $(OBJDIR)/%.rc + @echo Creating $@ + @$(RC) $(RCFLAGS) $< -o $@ + +$(OBJDIR)/%.rc: Makefile.win32 + @echo 1 VERSIONINFO > $@ + @echo FILEVERSION $(GEOIP_VERSION),0 >> $@ + @echo PRODUCTVERSION $(GEOIP_VERSION),0 >> $@ + @echo FILEFLAGSMASK 0x3fL >> $@ + @echo FILEOS 0x40004L >> $@ + @echo FILEFLAGS 0x0L >> $@ + @echo FILETYPE 0x1L >> $@ + @echo FILESUBTYPE 0x0L >> $@ + @echo BEGIN >> $@ + @echo BLOCK "StringFileInfo" >> $@ + @echo BEGIN >> $@ + @echo BLOCK "040904E4" >> $@ + @echo BEGIN >> $@ + @echo VALUE "LegalCopyright","$(COPYR)\0" >> $@ +ifdef COMPANY + @echo VALUE "CompanyName","$(COMPANY)\0" >> $@ +endif +ifdef LICENSE + @echo VALUE "License","$(LICENSE)\0" >> $@ +endif + @echo VALUE "ProductName","$(basename $(notdir $@))\0" >> $@ + @echo VALUE "ProductVersion","$(GEOIP_VERSION_STR)\0" >> $@ + @echo VALUE "FileDescription","$(DESCR)\0" >> $@ + @echo VALUE "FileVersion","$(GEOIP_VERSION_STR)\0" >> $@ + @echo VALUE "InternalName","$(basename $(notdir $@))\0" >> $@ + @echo VALUE "OriginalFilename","$(basename $(notdir $@)).exe\0" >> $@ + @echo VALUE "WWW","$(WWWURL)\0" >> $@ + @echo END >> $@ + @echo END >> $@ + @echo BLOCK "VarFileInfo" >> $@ + @echo BEGIN >> $@ + @echo VALUE "Translation", 0x409, 1252 >> $@ + @echo END >> $@ + @echo END >> $@ +ifdef ICON + @echo 10 ICON DISCARDABLE "$(ICON)" >> $@ +endif + +$(DISTDIR)/readme_bin.txt: Makefile.win32 + @echo Creating $@ + @echo $(DL)This is a binary distribution for Win32 platform.$(DL) > $@ + @echo $(DL)GeoIP version $(GEOIP_VERSION_STR)$(DL) >> $@ +ifndef LSTATIC + @echo $(DL)These binaries depend on zlib1.dll in the search path!$(DL) >> $@ +endif + @echo $(DL)Please download the complete GeoIP package for$(DL) >> $@ + @echo $(DL)any further documentation:$(DL) >> $@ + @echo $(DL)$(WWWURL)$(DL) >> $@ + +info: + @echo Targets to build: $(TARGETS) + + + diff --git a/src/libs/resiprocate/contrib/GeoIP/NEWS b/src/libs/resiprocate/contrib/GeoIP/NEWS new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/resiprocate/contrib/GeoIP/README b/src/libs/resiprocate/contrib/GeoIP/README new file mode 100644 index 00000000..a1b67256 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/README @@ -0,0 +1,208 @@ + GeoIP 1.4.8 + ----------- + +*** Experimental IPv6 notice *** + +- the experimental IPv6 part of libGeoIP may change in the future. +- It is possible, that geoiplookup and geoiplookup6 will merged. + +*** + +The new perl script geoipupdate-pureperl.pl is a drop in replacement for +geoipupdate. Useful, if you like to customize, pre or postprocess new or +old databases. To archive the databases or signal apache whatever. +Another advantage is, that geoipupdate-pureperl.pl is able to handle proxy +requests even with authentication. + +IMPORTANT API Change for 1.3.x and above users for GeoIP Region database +GeoIPRegion.region is no longer a pointer but an in-structure +array so test the first byte of region == 0 rather testing if the region +pointer is NULL. + +IMPORTANT API Change for 1.1.x and above users - as of GeoIP 1.1.0 the +GeoIP_country_xxx_by_xxx functions return NULL if a country can not +be found (it used to return '--' or 'N/A'. Be sure to check the +return value for NULL, to avoid segmentation faults! + +GeoIP is a C library that enables the user to find geographical and +network information of an IP address. +Included is a free GeoLite Country database +that is updated at the beginning of every month. +To download the latest free GeoLite Country database, go to: +http://www.maxmind.com/app/geoip_country + +There is also a free city-level geolocation database, GeoLite City, +available from: +http://www.maxmind.com/app/geolitecity + +We also offer commercial GeoIP databases with greater accuracy and +additional network information, for more details, see: +http://www.maxmind.com/app/products + +As of version 1.4.5 geoipupdate can handle updates via HTTP Proxy Server. +If the environ variable http_proxy="http://proxy-host:port" is set. +The username:password (as in FTP URLs) is not supported! +Thanks to Andrew Droffner for the patch! + +As of version 1.3.6, the GeoIP C library is thread safe, as long as +GEOIP_CHECK_CACHE is not used. + +This module can be used to automatically select the geographically closest +mirror, to analyze your web server logs to determine the countries of your +visitors, for credit card fraud detection, and for software export controls. + +If you use GeoIP to block access from high risk countries in order +to reduce fraud or abuse, you should also block access from known +proxy servers. For more details, see: +http://www.maxmind.com/app/proxy + +To install, run: + +./configure +make +make check +make install + +The GeoIP C library relies on GNU make, not on BSD make + +MEMORY CACHING AND OTHER OPTIONS + +There are four options available: + +GEOIP_STANDARD - read database from filesystem, uses least memory. + +GEOIP_MEMORY_CACHE - load database into memory, faster performance + but uses more memory + +GEOIP_CHECK_CACHE - check for updated database. If database has been updated, + reload filehandle and/or memory cache. + +GEOIP_INDEX_CACHE - just cache + the most frequently accessed index portion of the database, resulting + in faster lookups than GEOIP_STANDARD, but less memory usage than + GEOIP_MEMORY_CACHE - useful for larger databases such as + GeoIP Organization and GeoIP City. Note, for GeoIP Country, Region + and Netspeed databases, GEOIP_INDEX_CACHE is equivalent to GEOIP_MEMORY_CACHE + +GEOIP_MMAP_CACHE - load database into mmap shared memory ( MMAP is not avail for WIN32 ) + +The options can be combined using bit operators. For example you can +use both GEOIP_MEMORY_CACHE and GEOIP_CHECK_CACHE by calling: + + GeoIP_open("/path/to/GeoIP.dat", GEOIP_MEMORY_CACHE | GEOIP_CHECK_CACHE); + +By default, the city name is returned in iso-8859-1 charset. To obtain the +city name in utf8 instead, run: + + GeoIP_set_charset(gi, GEOIP_CHARSET_UTF8); + +To get the netmask of the netblock of the last lookup, use GeoIP_last_netblock(gi). + +EXAMPLES + +See +test/ + test-geoip.c + test-geoip-region.c + test-geoip-city.c + test-geoip-isp.c + test-geoip-org.c + test-geoip-netspeed.c + +for examples of how to use the API. The test-geoip.c program works with both the GeoLite and +GeoIP Country databases. The test-geoip-city.c program works with both the GeoLite and +GeoIP City databases. The other example programs require the paid databases available +from http://www.maxmind.com/app/products + +AUTOMATIC UPDATES + +MaxMind offers a service where you can have your database updated +automically each week. For more details see: + +http://www.maxmind.com/app/license_key + +RESOURCES Mailinglists + +Please join the very low traffic mailinglists you are interested in. + +http://sourceforge.net/mail/?group_id=66844 + +Preformance Patches. + +Patrick McManus provide a patch to enhance the lookupspeed in MEMORY_CACHE mode. If you feel, that the current MEMORY_CACHE mode is to slow try the patch: + +http://sourceforge.net/mailarchive/forum.php?forum_name=geoip-c-discuss&max_rows=25&style=nested&viewmonth=200803 + +TROUBLESHOOTING + +If you run into trouble building your application with GeoIP support, try adding -fms-extensions to your CFLAGS. If you use Solaris and there C-Compiler use -features=extensions instead. These options enable unnamed union support and fix problems like: 'improper member use: dma_code' or 'GeoIPRecord' has no member named 'dma_code'. + +Note that it is recommended that you use GNU make. Also, if you are using +OpenBSD, GeoIP requires OpenBSD 3.1 or greater. + +if you get "cannot load shared object file: No such file or directory" +error, add the directory libGeoIP.so was installed to to /etc/ld.so.conf +and run ldconfig + +On Solaris, if you get a +ld: fatal: relocations remain against allocatable but non-writable sections +error, try running + +# make clean +# ./configure --disable-shared +# make + +If you get a "ar : command not found" error, make sure that ar is +in your path. On Solaris, ar is typically found in /usr/ccs/bin + +If you get a "geoipupdate.c:24: getopt.h: No such file or directory" +error, run + +# export CPPFLAGS="-I/usr/local/include" + +(assuming that getopt.h is in /usr/local/include) + +If you get a "zlib.h: No such file or directory" error, make sure +that the zlib development libraries are installed on your server. +These are typically included in a "zlib-devel" package. + +If you get a "bad interpreter: No such file or directory" error +when running ./configure, make sure that there are no DOS +returns in the configure script. To remove DOS returns, +run perl -pi -e 's!\r!!g' configure. + +If gcc fails while consuming a large amount of memory, try +compiling with CFLAGS=-O1 (or -O0) instead of the default -O2. +It seems that some +versions of gcc have a bug and consume 1 GB of memory when optimizing +certain source files (the other source file where this was reported is +from XORG X-Server). It happens at least with gcc 3.3.1 and with gcc +4.2(.0). Thanks to Kai Schtzl for the report. + +If GEOIP_MMAP_CACHE doesn't work on a 64bit machine, try adding +the flag "MAP_32BIT" to the mmap call. + +If you get a "passing argument 3 of 'gethostbyname_r' from incompatible pointer type" +error on AIX, download and/or untar a fresh copy of GeoIP. ( To avoid cached +results from a previous ./configure run ) + +cd ./GeoIP-1.4.6 +then edit the file ./configure + +and delete these two lines: + +#define HAVE_GETHOSTBYNAME_R 1 + +#define GETHOSTBYNAME_R_RETURNS_INT 1 + +then save the configure script + +and build it as usual + +./configure +make +sudo make install + + + +To submit a patch, please contact support@maxmind.com diff --git a/src/libs/resiprocate/contrib/GeoIP/README.MinGW b/src/libs/resiprocate/contrib/GeoIP/README.MinGW new file mode 100644 index 00000000..8a192f95 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/README.MinGW @@ -0,0 +1,13 @@ +# how to build under MinGW/MSYS: +# (first you need to build & "install" zlib) + +export "CFLAGS=-O3 -I/usr/local/include" +export "LDFLAGS=-L/usr/local/lib -lwsock32" +./configure +make +cp data/GeoIP.dat test/ +make check + +# note that GeoIP.dat file should be placed in the +# same place as GeoIP-enabled executable modules! +# there's NO DEFAULT PATH concept on Win32 :) diff --git a/src/libs/resiprocate/contrib/GeoIP/README.OSX b/src/libs/resiprocate/contrib/GeoIP/README.OSX new file mode 100644 index 00000000..4dddf08c --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/README.OSX @@ -0,0 +1,35 @@ +#!/bin/sh +# +# Building OSX fat binaries is easy. +# +# - start in a clean directory. +# - copy the shell script below to a file and edit the file to your needs. +# +# 1.) modify export GEOIP_ARCH='-arch i386 -arch x86_64 -arch ppc -arch ppc64' +# to include all architectures you need. +# 2.) add whatever you want to the ./configure line. +# 3.) execute the script. +# 4.) do a 'make install' +# +# +# make clean or make distclean before building this +# +# tell systems before leopard that we like to build for 10.5 or higher +# with MACOSX_DEPLOYMENT_TARGET=10.5 +# starting with leopard we have to add -mmacosx-version-min=10.5 +# to the CFLAGS and export MACOSX_DEPLOYMENT_TARGET!? + +## for tiger, leopard and snow leopard you might use this +## export GEOIP_ARCH='-arch i386 -arch x86_64 -arch ppc -arch ppc64' +## export MACOSX_DEPLOYMENT_TARGET=10.4 +## export LDFLAGS=$GEOIP_ARCH +## export CFLAGS="-mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk $GEOIP_ARCH" + +# here we go for leopard and snow leopard +export GEOIP_ARCH='-arch i386 -arch x86_64 -arch ppc' +export MACOSX_DEPLOYMENT_TARGET=10.5 +export LDFLAGS=$GEOIP_ARCH +export CFLAGS="-g -mmacosx-version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk $GEOIP_ARCH" +./configure --disable-dependency-tracking +perl -i.bak -pe'/^archive_cmds=/ and !/\bGEOIP_ARCH\b/ and s/-dynamiclib\b/-dynamiclib \\\$(GEOIP_ARCH)/' ./libtool +make diff --git a/src/libs/resiprocate/contrib/GeoIP/READMEwin32.txt b/src/libs/resiprocate/contrib/GeoIP/READMEwin32.txt new file mode 100644 index 00000000..90e0ff71 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/READMEwin32.txt @@ -0,0 +1,44 @@ +======================================================= + +Environmental variables: + +1. GeoIPDBFileName is hardcoded to "\\windows\\system32\\GeoIP.dat" on +windows in GeoIP.c +2. #ifdef DLL is used to determine whether you want to have a DLL built +in GeoIP.h + +You may want to change these depending on your system configuration +and compiler. + +======================================================= +Thanks to Chris Gibbs for supplying these instructions. + +The GeoIP C library should work under windows. Note that it requires the zlib +DLL. + +To install zlib with GeoIP: + +i) Downloda the zlib prebuilt DLL and static library from +http://www.winimage.com/zLibDll/ look for "pre-built zlib DLL". + +Unzip it to some location on your hard drive, and in Project-->Settings , +go to the Link tab, and add the following 3 libraries: + +ws2_32.lib +zlib.lib +zlibstat.lib + +iii) Go to Tools-->Options, then the Directories tab, and add library paths to +the locations of the zlib static libraries. You will also need to add the +include path to zlib.h to the include paths. + +iv) NOTE: These instructions are for MS VC++ 6.0, but should be similar for +previous versions, and for VC .NET. + +======================================================= +Building GeoIP as a DLL + +Stanislaw Pusep has contributed a patch for building GeoIP as a DLL. +You can find the patch in GeoIPWinDLL.patch + +Note a modified version of this patch is now merged into the main code. diff --git a/src/libs/resiprocate/contrib/GeoIP/READMEwin32static.txt b/src/libs/resiprocate/contrib/GeoIP/READMEwin32static.txt new file mode 100644 index 00000000..5e521da3 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/READMEwin32static.txt @@ -0,0 +1,17 @@ +To make a static GeoIP.lib, edit the top level +Makefile.vc to reflect where the GeoIP.dat database +file should be placed, as well as the locations +of the lib, include, and bin directories for installation. +Then give the command + nmake /f Makefile.vc +This will build the GeoIP.lib library, as well as available +application and test programs. The command + nmake /f Makefile.vc test +will run available tests in the test/ subdirectory. + nmake /f Makefile.vc install +will then copy the lib and header files to the locations +specified in the top-level Makefile.vc, as well as +available application programs in the apps/ subdirectory. + nmake /f Makefile.vc clean +will remove intermediate object and executable files. + diff --git a/src/libs/resiprocate/contrib/GeoIP/TODO b/src/libs/resiprocate/contrib/GeoIP/TODO new file mode 100644 index 00000000..32a6c805 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/TODO @@ -0,0 +1,54 @@ +Rutger Okhuizen 7/31/2006 + +Implement waiting algorithm for GEOIP_CHECK_CACHE, +so stat is called on every lookup. + +----------------------- + +Maurice Cinquini + +*** ifndef WIN32 on netdb.h ? *** +In GeoIPCity.c you don't "#ifndef WIN32" the netdb.h include, +but in GeoIP.c you do. Which one is right? + +*** Warnings in GeoIP-1.2.1 before I made changes *** +GeoIPUpdate.c:73: warning: implicit declaration of function `_setup_dbfilename' + I suggest a GeoIP_private.h file to include prototypes for + _setup_dbfilename and other private functions also used by GeoIPCity.c + +*** Drop the GeoIP_*_by_addr API calls *** +And now that I think of it, why do you need a seperate +GeoIP_region_by_addr and GeoIP_region_by_name since +the later does the work of the former just as efficently. +For backward compatibility you could #define GeoIP_region_by_addr +to GeoIP_region_by_name + + + + +Performance improvements suggested by Jason Linhart +1. cluster nodes to improve disk performance when using GEOIP_STANDARD +2. evaluate preformance of replacing binary tree with nodes containing 4 children + +Write function to list countries, sorted by name. Chris Gibbs contributed this which could be +used: + + int GeoIP_country_sorted_index[246] = { + 0, 5, 8, 61, 14, 3, 11, 7, 12, 6, 13, 9, 17, 1, 16, 15, 18, 32, 25, 21, + 20,36, 22, 37, 27, 28, 33, 30, 19, 35, 34, 31, 104, 29, 24, 23, 26, +114, 47, 38, 52,121, 41, 207, 46, 48, 53, 39, 49, 116, 42, 40, 45, + 50, 44, 97, 51, 54, 55, 58, 57, 59, 60, 216, 62, 64, 203, 87, 66, + 63, 68, 2, 71, 73, 70, 69, 74, 75, 80, 170,208, 76, 84, 79, 56, 81, +82, 88, 83, 78, 86, 91, 90, 85, 92, 93, 98, 95, 228, 96,94, 99, 107, + 103, 100, 106, 105, 101, 102, 108, 109, 111, 110, 122, 112, 115, + 118,119, 120, 113, 123, 132, 124, 129, 128, 133, 126, 130, 131, + 143, 139, 137,151,153, 150, 140, 148, 138, 145, 146, 149, 238, + 152, 72, 136, 135, 142, 147, 134,154, 141, 155, 164, 163, 161, +10, 156, 166, 160, 157, 159, 165, 158, 144, 162, 167,173, 180, +178, 168, 171, 181, 169, 172, 176, 174, 179, 177, 182, 183, 184, +185,186, 193, 117, 125, 175, 229, 236, 198, 202, 187, 199, 189, +197, 192, 196,194,188, 200, 240, 89, 67, 127, 190, 201, 195, 205, +191, 43, 204, 220, 211, 221,210,209, 212, 215, 218, 214, 217, +213,206, 219, 223, 222, 4, 77, 225, 224, 226,227,234, 230, 233, + 231,232, 235, 65, 237, 239, 242, 241, 243, 244, 245}; + diff --git a/src/libs/resiprocate/contrib/GeoIP/aclocal.m4 b/src/libs/resiprocate/contrib/GeoIP/aclocal.m4 new file mode 100644 index 00000000..91c7b241 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/aclocal.m4 @@ -0,0 +1,8917 @@ +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],, +[m4_warning([this file was generated for autoconf 2.65. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 56 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl +_LT_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Fix-up fallback echo if it was mangled by the above quoting rules. +case \$lt_ECHO in +*'\\\[$]0 --fallback-echo"')dnl " + lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` + ;; +esac + +_LT_OUTPUT_LIBTOOL_INIT +]) + + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +cat >"$CONFIG_LT" <<_LTEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate a libtool stub with the current configuration. + +lt_cl_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AS_SHELL_SANITIZE +_AS_PREPARE + +exec AS_MESSAGE_FD>&1 +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2008 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +if test "$no_create" != yes; then + lt_cl_success=: + test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" + exec AS_MESSAGE_LOG_FD>/dev/null + $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false + exec AS_MESSAGE_LOG_FD>>config.log + $lt_cl_success || AS_EXIT(1) +fi +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_XSI_SHELLFNS + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES +# -------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=echo + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX +# ----------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_SHELL_INIT + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[_LT_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$lt_ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +ECHO=${lt_ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<_LT_EOF +[$]* +_LT_EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test -z "$lt_ECHO"; then + if test "X${echo_test_string+set}" != Xset; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if { echo_test_string=`eval $cmd`; } 2>/dev/null && + { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null + then + break + fi + done + fi + + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : + else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$ECHO" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + ECHO='print -r' + elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + ECHO='printf %s\n' + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + ECHO="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + ECHO=echo + fi + fi + fi + fi + fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +lt_ECHO=$ECHO +if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(lt_ECHO) +]) +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], + [An echo program that does not interpret backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[AC_CHECK_TOOL(AR, ar, false) +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1]) + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ + = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line __oline__ "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[[3-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method == "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC*) + # IBM XL 8.0 on PPC + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl*) + # IBM XL C 8.0/Fortran 10.1 on PPC + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac +AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + ;; + linux* | k*bsd*-gnu) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag= + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE(int foo(void) {}, + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + ) + LDFLAGS="$save_LDFLAGS" + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], + [[If ld is used when linking, flag to hardcode $libdir into a binary + during linking. This must work even if $libdir does not exist]]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [fix_srcfile_path], [1], + [Fix the shell variable $srcfile for the compiler]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_PROG_CXX +# ------------ +# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ +# compiler, we have our own version here. +m4_defun([_LT_PROG_CXX], +[ +pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) +AC_PROG_CXX +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi +popdef([AC_MSG_ERROR]) +])# _LT_PROG_CXX + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([_LT_PROG_CXX], []) + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[AC_REQUIRE([_LT_PROG_CXX])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 will use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + xl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=echo + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +]) +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_PROG_F77 +# ------------ +# Since AC_PROG_F77 is broken, in that it returns the empty string +# if there is no fortran compiler, we have our own version here. +m4_defun([_LT_PROG_F77], +[ +pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) +AC_PROG_F77 +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi +popdef([AC_MSG_ERROR]) +])# _LT_PROG_F77 + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([_LT_PROG_F77], []) + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_REQUIRE([_LT_PROG_F77])dnl +AC_LANG_PUSH(Fortran 77) + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + CC=${F77-"f77"} + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_PROG_FC +# ----------- +# Since AC_PROG_FC is broken, in that it returns the empty string +# if there is no fortran compiler, we have our own version here. +m4_defun([_LT_PROG_FC], +[ +pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) +AC_PROG_FC +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi +popdef([AC_MSG_ERROR]) +])# _LT_PROG_FC + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([_LT_PROG_FC], []) + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_REQUIRE([_LT_PROG_FC])dnl +AC_LANG_PUSH(Fortran) + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + CC=${FC-"f95"} + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC="$lt_save_CC" +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC="$lt_save_CC" +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_XSI_SHELLFNS +# --------------------- +# Bourne and XSI compatible variants of some useful shell functions. +m4_defun([_LT_PROG_XSI_SHELLFNS], +[case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $[*] )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + +dnl func_dirname_and_basename +dnl A portable version of this function is already defined in general.m4sh +dnl so there is no need for it here. + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[[^=]]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$[@]"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$[1]+=\$[2]" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$[1]=\$$[1]\$[2]" +} + +_LT_EOF + ;; + esac +]) + +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [0], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) + +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) + +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# Generated from ltversion.in. + +# serial 3017 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.2.6b]) +m4_define([LT_PACKAGE_REVISION], [1.3017]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.2.6b' +macro_revision='1.3017' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) + +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 4 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 10 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/src/libs/resiprocate/contrib/GeoIP/apps/Makefile.am b/src/libs/resiprocate/contrib/GeoIP/apps/Makefile.am new file mode 100644 index 00000000..46cf501f --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/apps/Makefile.am @@ -0,0 +1,26 @@ +INCLUDES = \ + -I$(top_srcdir)/libGeoIP \ + -Wall + +AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\" -Wall + +DEPS = $(top_builddir)/libGeoIP/libGeoIP.la +LDADDS = $(top_builddir)/libGeoIP/libGeoIP.la + +bin_PROGRAMS = geoiplookup geoiplookup6 geoipupdate + +geoiplookup_SOURCES = geoiplookup.c +geoiplookup_LDFLAGS = +geoiplookup_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +geoiplookup_LDADD = $(top_builddir)/libGeoIP/libGeoIP.la + +geoiplookup6_SOURCES = geoiplookup6.c +geoiplookup6_LDFLAGS = +geoiplookup6_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +geoiplookup6_LDADD = $(top_builddir)/libGeoIP/libGeoIP.la + +geoipupdate_SOURCES = geoipupdate.c +geoipupdate_LDFLAGS = +geoipupdate_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la $(top_builddir)/libGeoIP/libGeoIPUpdate.la +geoipupdate_LDADD = $(top_builddir)/libGeoIP/libGeoIPUpdate.la $(top_builddir)/libGeoIP/libGeoIP.la +EXTRA_DIST = geoipupdate-pureperl.pl Makefile.vc diff --git a/src/libs/resiprocate/contrib/GeoIP/apps/Makefile.in b/src/libs/resiprocate/contrib/GeoIP/apps/Makefile.in new file mode 100644 index 00000000..934f6b6a --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/apps/Makefile.in @@ -0,0 +1,544 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = geoiplookup$(EXEEXT) geoiplookup6$(EXEEXT) \ + geoipupdate$(EXEEXT) +subdir = apps +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am_geoiplookup_OBJECTS = geoiplookup.$(OBJEXT) +geoiplookup_OBJECTS = $(am_geoiplookup_OBJECTS) +geoiplookup_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(geoiplookup_LDFLAGS) $(LDFLAGS) -o $@ +am_geoiplookup6_OBJECTS = geoiplookup6.$(OBJEXT) +geoiplookup6_OBJECTS = $(am_geoiplookup6_OBJECTS) +geoiplookup6_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(geoiplookup6_LDFLAGS) $(LDFLAGS) -o $@ +am_geoipupdate_OBJECTS = geoipupdate.$(OBJEXT) +geoipupdate_OBJECTS = $(am_geoipupdate_OBJECTS) +geoipupdate_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(geoipupdate_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(geoiplookup_SOURCES) $(geoiplookup6_SOURCES) \ + $(geoipupdate_SOURCES) +DIST_SOURCES = $(geoiplookup_SOURCES) $(geoiplookup6_SOURCES) \ + $(geoipupdate_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEOIP_VERSION_INFO = @GEOIP_VERSION_INFO@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = \ + -I$(top_srcdir)/libGeoIP \ + -Wall + +AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\" -Wall +DEPS = $(top_builddir)/libGeoIP/libGeoIP.la +LDADDS = $(top_builddir)/libGeoIP/libGeoIP.la +geoiplookup_SOURCES = geoiplookup.c +geoiplookup_LDFLAGS = +geoiplookup_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +geoiplookup_LDADD = $(top_builddir)/libGeoIP/libGeoIP.la +geoiplookup6_SOURCES = geoiplookup6.c +geoiplookup6_LDFLAGS = +geoiplookup6_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +geoiplookup6_LDADD = $(top_builddir)/libGeoIP/libGeoIP.la +geoipupdate_SOURCES = geoipupdate.c +geoipupdate_LDFLAGS = +geoipupdate_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la $(top_builddir)/libGeoIP/libGeoIPUpdate.la +geoipupdate_LDADD = $(top_builddir)/libGeoIP/libGeoIPUpdate.la $(top_builddir)/libGeoIP/libGeoIP.la +EXTRA_DIST = geoipupdate-pureperl.pl Makefile.vc +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu apps/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu apps/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +geoiplookup$(EXEEXT): $(geoiplookup_OBJECTS) $(geoiplookup_DEPENDENCIES) + @rm -f geoiplookup$(EXEEXT) + $(geoiplookup_LINK) $(geoiplookup_OBJECTS) $(geoiplookup_LDADD) $(LIBS) +geoiplookup6$(EXEEXT): $(geoiplookup6_OBJECTS) $(geoiplookup6_DEPENDENCIES) + @rm -f geoiplookup6$(EXEEXT) + $(geoiplookup6_LINK) $(geoiplookup6_OBJECTS) $(geoiplookup6_LDADD) $(LIBS) +geoipupdate$(EXEEXT): $(geoipupdate_OBJECTS) $(geoipupdate_DEPENDENCIES) + @rm -f geoipupdate$(EXEEXT) + $(geoipupdate_LINK) $(geoipupdate_OBJECTS) $(geoipupdate_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geoiplookup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geoiplookup6.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geoipupdate.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-binPROGRAMS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/resiprocate/contrib/GeoIP/apps/Makefile.vc b/src/libs/resiprocate/contrib/GeoIP/apps/Makefile.vc new file mode 100644 index 00000000..266a9319 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/apps/Makefile.vc @@ -0,0 +1,25 @@ +#NMAKE makefile for Windows developers. +#Produces a static library (GeoIP.lib). + +COMPILER=cl + +LINK = link -nologo + +CFLAGS=-DWIN32 -MD -nologo + +GEOIPINC = -I..\libGeoIP + +CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) + +GEOIPLIB = ..\libGeoIP\GeoIP.lib + +EXTRA_LIBS= advapi32.lib wsock32.lib + +AR=lib + +APPS: geoiplookup.exe + +geoiplookup.exe: geoiplookup.c + $(CC1) -c geoiplookup.c + $(LINK) geoiplookup.obj $(GEOIPLIB) + diff --git a/src/libs/resiprocate/contrib/GeoIP/apps/geoiplookup.c b/src/libs/resiprocate/contrib/GeoIP/apps/geoiplookup.c new file mode 100644 index 00000000..bd3c6fca --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/apps/geoiplookup.c @@ -0,0 +1,401 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* geoiplookup.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include "GeoIPCity.h" +#include "GeoIP_internal.h" + +#if defined(_WIN32) +# ifndef uint32_t +typedef unsigned int uint32_t; +# endif +#endif + +void geoiplookup(GeoIP* gi,char *hostname,int i); + +void usage() { + fprintf(stderr,"Usage: geoiplookup [-d custom_dir] [-f custom_file] [-v] [-i] \n"); +} + +/* extra info used in _say_range_ip */ +int info_flag = 0; + +int main (int argc, char *argv[]) { + char * hostname = NULL; + char * db_info; + GeoIP * gi; + int i; + char *custom_directory = NULL; + char *custom_file = NULL; + int version_flag = 0; + + if (argc < 2) { + usage(); + exit(1); + } + i = 1; + while (i < argc) { + if (strcmp(argv[i],"-v") == 0) { + version_flag = 1; + } else if (strcmp(argv[i],"-i") == 0) { + info_flag = 1; + } else if (strcmp(argv[i],"-f") == 0) { + if ((i+1) < argc){ + i++; + custom_file = argv[i]; + } + } else if (strcmp(argv[i],"-d") == 0) { + if ((i+1) < argc){ + i++; + custom_directory = argv[i]; + } + } else { + hostname = argv[i]; + } + i++; + } + if (hostname == NULL) { + usage(); + exit(1); + } + + if (custom_directory != NULL) { + GeoIP_setup_custom_directory(custom_directory); + } + _GeoIP_setup_dbfilename(); + + if (custom_file != NULL) { + gi = GeoIP_open(custom_file, GEOIP_STANDARD); + + if (NULL == gi) { + printf("%s not available, skipping...\n", custom_file); + } else { + i = GeoIP_database_edition(gi); + if (version_flag == 1) { + db_info = GeoIP_database_info(gi); + printf("%s: %s\n",GeoIPDBDescription[i],db_info == NULL ? "": db_info ); + free(db_info); + } else { + geoiplookup(gi,hostname,i); + } + } + GeoIP_delete(gi); + } else { + /* iterate through different database types */ + for (i = 0; i < NUM_DB_TYPES; ++i) { + if (GeoIP_db_avail(i)) { + gi = GeoIP_open_type(i, GEOIP_STANDARD); + if (NULL == gi) { + printf("%s not available, skipping...\n", GeoIPDBDescription[i]); + } else { + if (version_flag == 1) { + db_info = GeoIP_database_info(gi); + printf("%s: %s\n",GeoIPDBDescription[i], db_info == NULL ? "" : db_info ); + free(db_info); + } else { + geoiplookup(gi,hostname,i); + } + } + GeoIP_delete(gi); + } + } + } + return 0; +} + +static const char * _mk_NA( const char * p ){ + return p ? p : "N/A"; +} + +static void _mk_conf_str( unsigned char val , char * to, int size){ + if ( ( val & 0x7f ) == 0x7f ){ + snprintf(to, 5, "N/A"); + return; + } + snprintf(to, 5, "%d", val); + return; +} + +static unsigned long +__addr_to_num(const char *addr) +{ + unsigned int c, octet, t; + unsigned long ipnum; + int i = 3; + + octet = ipnum = 0; + while ((c = *addr++)) { + if (c == '.') { + if (octet > 255) + return 0; + ipnum <<= 8; + ipnum += octet; + i--; + octet = 0; + } else { + t = octet; + octet <<= 3; + octet += t; + octet += t; + c -= '0'; + if (c > 9) + return 0; + octet += c; + } + } + if ((octet > 255) || (i != 0)) + return 0; + ipnum <<= 8; + return ipnum + octet; +} + + + +/* ptr must be a memory area with at least 16 bytes */ +static char *__num_to_addr_r (unsigned long ipnum, char * ptr) { + char *cur_str; + int octet[4]; + int num_chars_written, i; + + cur_str = ptr; + + for (i = 0; i<4; i++) { + octet[3 - i] = ipnum % 256; + ipnum >>= 8; + } + + for (i = 0; i<4; i++) { + num_chars_written = sprintf(cur_str, "%d", octet[i]); + cur_str += num_chars_written; + + if (i < 3) { + cur_str[0] = '.'; + cur_str++; + } + } + + return ptr; +} + +void _say_range_by_ip(GeoIP * gi, uint32_t ipnum ) { + unsigned long last_nm, mask, low, hi; + char ipaddr[16]; + char tmp[16]; + char ** range; + + if ( info_flag == 0 ) + return; /* noop unless extra information is requested */ + + range = GeoIP_range_by_ip( gi, __num_to_addr_r( ipnum, ipaddr ) ); + if ( range == NULL ) + return; + + printf ( " ipaddr: %s\n", ipaddr ); + + printf( " range_by_ip: %s - %s\n", range[0], range[1] ); + last_nm = GeoIP_last_netmask(gi); + mask = 0xffffffff << ( 32 - last_nm ); + low = ipnum & mask; + hi = low + ( 0xffffffff & ~mask ); + printf( " network: %s - %s ::%ld\n", + __num_to_addr_r( low, ipaddr ), + __num_to_addr_r( hi, tmp ), + last_nm + ); + printf( " ipnum: %u\n", ipnum ); + printf( " range_by_num: %lu - %lu\n", __addr_to_num(range[0]), __addr_to_num(range[1]) ); + printf( " network num: %lu - %lu ::%lu\n", low, hi, last_nm ); + + GeoIP_range_by_ip_delete(range); +} + +void +geoiplookup(GeoIP * gi, char *hostname, int i) +{ + const char *country_code; + const char *country_name; + const char *domain_name; + const char *asnum_name; + int netspeed; + int country_id; + GeoIPRegion *region; + GeoIPRecord *gir; + const char *org; + uint32_t ipnum; + + ipnum = _GeoIP_lookupaddress(hostname); + if (ipnum == 0) { + printf("%s: can't resolve hostname ( %s )\n", GeoIPDBDescription[i], hostname); + + } + else { + + if (GEOIP_DOMAIN_EDITION == i) { + domain_name = GeoIP_name_by_ipnum(gi, ipnum); + if (domain_name == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s\n", GeoIPDBDescription[i], domain_name); + _say_range_by_ip(gi, ipnum); + } + } + else if (GEOIP_LOCATIONA_EDITION == i || GEOIP_ACCURACYRADIUS_EDITION == i || GEOIP_ASNUM_EDITION == i || GEOIP_USERTYPE_EDITION == i || GEOIP_REGISTRAR_EDITION == i || GEOIP_NETSPEED_EDITION_REV1 == i ) { + asnum_name = GeoIP_name_by_ipnum(gi, ipnum); + if (asnum_name == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s\n", GeoIPDBDescription[i], asnum_name); + _say_range_by_ip(gi, ipnum); + } + } + else if (GEOIP_COUNTRY_EDITION == i) { + country_id = GeoIP_id_by_ipnum(gi, ipnum); + country_code = GeoIP_country_code[country_id]; + country_name = GeoIP_country_name[country_id]; + if (country_id == 0) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s, %s\n", GeoIPDBDescription[i], country_code, country_name); + _say_range_by_ip(gi, ipnum); + } + } + else if (GEOIP_REGION_EDITION_REV0 == i || GEOIP_REGION_EDITION_REV1 == i) { + region = GeoIP_region_by_ipnum(gi, ipnum); + if (NULL == region || region->country_code[0] == '\0' ) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s, %s\n", GeoIPDBDescription[i], region->country_code, region->region); + _say_range_by_ip(gi, ipnum); + GeoIPRegion_delete(region); + } + } + else if (GEOIP_CITY_EDITION_REV0 == i) { + gir = GeoIP_record_by_ipnum(gi, ipnum); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s, %s, %s, %s, %f, %f\n", GeoIPDBDescription[i], gir->country_code, _mk_NA(gir->region), + _mk_NA(gir->city), _mk_NA(gir->postal_code), gir->latitude, gir->longitude); + _say_range_by_ip(gi, ipnum); + GeoIPRecord_delete(gir); + } + } + else if (GEOIP_CITY_EDITION_REV1 == i) { + gir = GeoIP_record_by_ipnum(gi, ipnum); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s, %s, %s, %s, %f, %f, %d, %d\n", GeoIPDBDescription[i], gir->country_code, _mk_NA(gir->region), _mk_NA(gir->city), _mk_NA(gir->postal_code), + gir->latitude, gir->longitude, gir->metro_code, gir->area_code); + _say_range_by_ip(gi, ipnum); + GeoIPRecord_delete(gir); + } + } + else if (GEOIP_CITYCONFIDENCE_EDITION == i) { + gir = GeoIP_record_by_ipnum(gi, ipnum); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + char country_str[5], region_str[5], city_str[5], postal_str[5]; + _mk_conf_str(gir->country_conf, country_str, 5); + _mk_conf_str(gir->region_conf, region_str, 5); + _mk_conf_str(gir->city_conf, city_str, 5); + _mk_conf_str(gir->postal_conf, postal_str, 5); + + printf("%s: %s, %s, %s, %s, %f, %f, %d, %d, %s, %s, %s, %s\n", GeoIPDBDescription[i], gir->country_code, _mk_NA(gir->region), _mk_NA(gir->city), _mk_NA(gir->postal_code), + gir->latitude, gir->longitude, gir->metro_code, gir->area_code, + country_str, region_str, city_str, postal_str + ); + _say_range_by_ip(gi, ipnum); + GeoIPRecord_delete(gir); + } + } + else if (GEOIP_CITYCONFIDENCEDIST_EDITION == i) { + gir = GeoIP_record_by_ipnum(gi, ipnum); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + char country_str[5], region_str[5], city_str[5], postal_str[5], accuracy_radius_str[5]; + _mk_conf_str(gir->country_conf, country_str, 5); + _mk_conf_str(gir->region_conf, region_str, 5); + _mk_conf_str(gir->city_conf, city_str, 5); + _mk_conf_str(gir->postal_conf, postal_str, 5); + if (gir->accuracy_radius != 1023){ + sprintf(accuracy_radius_str, "%d", gir->accuracy_radius ); +} else { + strcpy(accuracy_radius_str,"N/A");} + + printf("%s: %s, %s, %s, %s, %f, %f, %d, %d, %s, %s, %s, %s, %s\n", GeoIPDBDescription[i], gir->country_code, _mk_NA(gir->region), _mk_NA(gir->city), _mk_NA(gir->postal_code), + gir->latitude, gir->longitude, gir->metro_code, gir->area_code, + country_str, region_str, city_str, postal_str, accuracy_radius_str + ); + _say_range_by_ip(gi, ipnum); + GeoIPRecord_delete(gir); + } + } + else if (GEOIP_ORG_EDITION == i || GEOIP_ISP_EDITION == i) { + org = GeoIP_org_by_ipnum(gi, ipnum); + if (org == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s\n", GeoIPDBDescription[i], org); + _say_range_by_ip(gi, ipnum); + } + } + else if (GEOIP_NETSPEED_EDITION == i) { + netspeed = GeoIP_id_by_ipnum(gi, ipnum); + if (netspeed == GEOIP_UNKNOWN_SPEED) { + printf("%s: Unknown\n", GeoIPDBDescription[i]); + } + else if (netspeed == GEOIP_DIALUP_SPEED) { + printf("%s: Dialup\n", GeoIPDBDescription[i]); + } + else if (netspeed == GEOIP_CABLEDSL_SPEED) { + printf("%s: Cable/DSL\n", GeoIPDBDescription[i]); + } + else if (netspeed == GEOIP_CORPORATE_SPEED) { + printf("%s: Corporate\n", GeoIPDBDescription[i]); + } + _say_range_by_ip(gi, ipnum); + } + else { + + /* + * Silent ignore IPv6 databases. Otherwise we get annoying + * messages whenever we have a mixed environment IPv4 and + * IPv6 + */ + + /* + * printf("Can not handle database type -- try geoiplookup6\n"); + */ + ; + } + } +} diff --git a/src/libs/resiprocate/contrib/GeoIP/apps/geoiplookup6.c b/src/libs/resiprocate/contrib/GeoIP/apps/geoiplookup6.c new file mode 100644 index 00000000..dc0ff9ba --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/apps/geoiplookup6.c @@ -0,0 +1,255 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* geoiplookup.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +void geoiplookup(GeoIP* gi,char *hostname,int i); + +void usage() { + fprintf(stderr,"Usage: geoiplookup [-d custom_dir] [-f custom_file] [-v] \n"); +} + +int main (int argc, char *argv[]) { + char * hostname = NULL; + char * db_info; + GeoIP * gi; + int i; + char *custom_directory = NULL; + char *custom_file = NULL; + int version_flag = 0; + + if (argc < 2) { + usage(); + exit(1); + } + i = 1; + while (i < argc) { + if (strcmp(argv[i],"-v") == 0) { + version_flag = 1; + } else if (strcmp(argv[i],"-f") == 0) { + if ((i+1) < argc){ + i++; + custom_file = argv[i]; + } + } else if (strcmp(argv[i],"-d") == 0) { + if ((i+1) < argc){ + i++; + custom_directory = argv[i]; + } + } else { + hostname = argv[i]; + } + i++; + } + if (hostname == NULL) { + usage(); + exit(1); + } + + if (custom_directory != NULL) { + GeoIP_setup_custom_directory(custom_directory); + } + _GeoIP_setup_dbfilename(); + + if (custom_file != NULL) { + gi = GeoIP_open(custom_file, GEOIP_STANDARD); + if (NULL == gi) { + printf("%s not available, skipping...\n", custom_file); + } else { + i = GeoIP_database_edition(gi); + if (version_flag == 1) { + db_info = GeoIP_database_info(gi); + printf("%s: %s\n",GeoIPDBDescription[i],db_info == NULL ? "": db_info ); + free(db_info); + } else { + geoiplookup(gi,hostname,i); + } + } + GeoIP_delete(gi); + } else { + /* iterate through different database types */ + for (i = 0; i < NUM_DB_TYPES; ++i) { + if (GeoIP_db_avail(i)) { + gi = GeoIP_open_type(i, GEOIP_STANDARD); + if (NULL == gi) { + printf("%s not available, skipping...\n", GeoIPDBDescription[i]); + } else { + if (version_flag == 1) { + db_info = GeoIP_database_info(gi); + printf("%s: %s\n",GeoIPDBDescription[i],db_info); + free(db_info); + } else { + geoiplookup(gi,hostname,i); + } + } + GeoIP_delete(gi); + } + } + } + return 0; +} + +static const char * _mk_NA( const char * p ){ + return p ? p : "N/A"; +} + +void +geoiplookup(GeoIP * gi, char *hostname, int i) +{ + const char *country_code; + const char *country_name; + const char *domain_name; + const char *asnum_name; + int netspeed; + int country_id; + GeoIPRegion *region; + GeoIPRecord *gir; + const char *org; + + geoipv6_t ipnum; + ipnum = _GeoIP_lookupaddress_v6(hostname); + if (__GEOIP_V6_IS_NULL(ipnum)) { + printf("%s: can't resolve hostname ( %s )\n", GeoIPDBDescription[i], hostname); + + } + else { + + +#if 0 + if (GEOIP_DOMAIN_EDITION_V6 == i) { + domain_name = GeoIP_name_by_name_v6(gi, hostname); + if (domain_name == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s\n", GeoIPDBDescription[i], domain_name); + } + } +#endif + + + + if (GEOIP_LOCATIONA_EDITION_V6 == i || GEOIP_ASNUM_EDITION_V6 == i || GEOIP_USERTYPE_EDITION_V6 == i || GEOIP_REGISTRAR_EDITION_V6 == i || GEOIP_DOMAIN_EDITION_V6 == i || GEOIP_ORG_EDITION_V6 == i || GEOIP_ISP_EDITION_V6 == i || GEOIP_NETSPEED_EDITION_REV1_V6 == i ) { + asnum_name = GeoIP_name_by_ipnum_v6(gi, ipnum); + if (asnum_name == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s\n", GeoIPDBDescription[i], asnum_name); + // _say_range_by_ip(gi, ipnum); + } + } + + else if (GEOIP_CITY_EDITION_REV0_V6 == i) { + gir = GeoIP_record_by_name_v6(gi, hostname); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s, %s, %s, %s, %f, %f\n", GeoIPDBDescription[i], gir->country_code, _mk_NA(gir->region), + _mk_NA(gir->city), _mk_NA(gir->postal_code), gir->latitude, gir->longitude); + } + } + else if (GEOIP_CITY_EDITION_REV1_V6 == i) { + gir = GeoIP_record_by_name_v6(gi, hostname); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s, %s, %s, %s, %f, %f, %d, %d\n", GeoIPDBDescription[i], gir->country_code, _mk_NA(gir->region), _mk_NA(gir->city), _mk_NA(gir->postal_code), + gir->latitude, gir->longitude, gir->metro_code, gir->area_code); + } + } + + else if (GEOIP_COUNTRY_EDITION_V6 == i) { + + country_id = GeoIP_id_by_ipnum_v6(gi, ipnum); + country_code = GeoIP_country_code[country_id]; + country_name = GeoIP_country_name[country_id]; + if (country_id == 0) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s, %s\n", GeoIPDBDescription[i], country_code, country_name); + } + } + } + +#if 0 + + else + if (GEOIP_REGION_EDITION_REV0 == i || GEOIP_REGION_EDITION_REV1 == i) { + region = GeoIP_region_by_name_v6(gi, hostname); + if (NULL == region) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s, %s\n", GeoIPDBDescription[i], region->country_code, region->region); + } + } + else if (GEOIP_CITY_EDITION_REV0 == i) { + gir = GeoIP_record_by_name(gi, hostname); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s, %s, %s, %s, %f, %f\n", GeoIPDBDescription[i], gir->country_code, gir->region, + gir->city, gir->postal_code, gir->latitude, gir->longitude); + } + } + else if (GEOIP_CITY_EDITION_REV1 == i) { + gir = GeoIP_record_by_name(gi, hostname); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s, %s, %s, %s, %f, %f, %d, %d\n", GeoIPDBDescription[i], gir->country_code, gir->region, gir->city, gir->postal_code, + gir->latitude, gir->longitude, gir->metro_code, gir->area_code); + } + } + else if (GEOIP_ORG_EDITION == i || GEOIP_ISP_EDITION == i) { + org = GeoIP_org_by_name_v6(gi, hostname); + if (org == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } + else { + printf("%s: %s\n", GeoIPDBDescription[i], org); + } + } + else if (GEOIP_NETSPEED_EDITION == i) { + netspeed = GeoIP_id_by_name_v6(gi, hostname); + if (netspeed == GEOIP_UNKNOWN_SPEED) { + printf("%s: Unknown\n", GeoIPDBDescription[i]); + } + else if (netspeed == GEOIP_DIALUP_SPEED) { + printf("%s: Dialup\n", GeoIPDBDescription[i]); + } + else if (netspeed == GEOIP_CABLEDSL_SPEED) { + printf("%s: Cable/DSL\n", GeoIPDBDescription[i]); + } + else if (netspeed == GEOIP_CORPORATE_SPEED) { + printf("%s: Corporate\n", GeoIPDBDescription[i]); + } + + } +#endif + +} diff --git a/src/libs/resiprocate/contrib/GeoIP/apps/geoipupdate-pureperl.pl b/src/libs/resiprocate/contrib/GeoIP/apps/geoipupdate-pureperl.pl new file mode 100644 index 00000000..a8f04bee --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/apps/geoipupdate-pureperl.pl @@ -0,0 +1,260 @@ +#!/usr/bin/perl + +=pod + +/* + * + * Copyright (C) 2008 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +=cut + +=pod + +pure perl version of geoipupdate. can handle anything, that + + GeoIP_update_database + GeoIP_update_database_general + +handle. It is a drop in replacement for geoipupdate, as opposide to geoipupdate is the +pp version able to handle proxy requests even with authentication and can be used with +https + +=cut + +use strict; +use warnings; + +our $VERSION = '0.07'; + +use 5.008; +use Data::Dumper; +use Digest::MD5; +use File::Spec; +use File::Basename; +use Getopt::Std; +use HTTP::Request::Common; +use LWP::UserAgent; +use PerlIO::gzip; +use URI; + +my $ua = LWP::UserAgent->new( agent => "pp_geoipupdate/$VERSION" ); +$ua->env_proxy; + +## --- for auth proxies use +## $ua->proxy(['http', 'ftp'] => 'http://username:password@proxy.myorg.com'); + +my $license_file = 'GeoIP.conf'; +my $update_host = 'updates.maxmind.com'; +my $proto = 'http'; +my %opts; + +if ( !getopts( 'hvf:d:', \%opts ) or $opts{h} ) { + print STDERR + "Usage: geoipupdate [-hv] [-f license_file] [-d custom directory]\n"; + exit @ARGV ? 1 : 0; +} + +my $rootdir = File::Spec->rootdir; +$opts{d} ||= File::Spec->catfile( $rootdir, qw/ usr local share GeoIP / ); +$opts{f} ||= + File::Spec->catfile( $rootdir, qw/ usr local etc /, $license_file ); + +die "dir $opts{d} does not exist or is not readable or is not a directory\n" + unless -d $opts{d}; +die "license_file $opts{f} does not exist, is not readable or is not a file\n" + unless -f $opts{f}; + +# +# --- parse license file +# +open my $fh, '<', $opts{f} + or die "Error opening GeoIP Configuration file $opts{f}\n"; +print "Opened License file $opts{f}\n" if $opts{v}; + +my ( $user_id, $license_key, @product_ids ); +{ + local $_; + + while (<$fh>) { + next if /^\s*#/; # skip comments + /^\s*UserId\s+(\d+)/ and $user_id = $1, next; + /^\s*LicenseKey\s+(\S{12})/ and $license_key = $1, next; + /^\s*ProductIds\s+(\d+(?:[a-zA-Z]{2,3})?(?:\s+\d+(?:[a-zA-Z]{2,3})?)*)/ + and @product_ids = split( /\s+/, $1 ), next; + + } +} + +if ( $opts{v} ) { + print "User id $user_id\n" if $user_id; + print "Read in license key $license_key\n"; + print "Product ids @product_ids\n"; +} + +if ($user_id) { + for my $product_id (@product_ids) { + + # update the databases using the user id string, + # the license key string and the product id for each database + eval { + GeoIP_update_database_general( $user_id, $license_key, + $product_id, $opts{v} ); + }; + my $err = $@; + die $err if $err and $err !~ /^No new updates available/i; + print $err; + } +} else { + + # Old format with just license key for MaxMind GeoIP Country database updates + # here for backwards compatibility + eval { GeoIP_update_database( $license_key, $opts{v} ); }; + my $err = $@; + die $err if $err and $err !~ /^No new updates available/i; + print $err; +} + +exit 0; + +sub GeoIP_update_database_general { + my ( $user_id, $license_key, $product_id, $verbose, $client_ipaddr ) = @_; + my $u = URI->new("$proto://$update_host/app/update_getfilename"); + $u->query_form( product_id => $product_id ); + + print 'Send request ' . $u->as_string, "\n" if ($verbose); + my $res = $ua->request( GET $u->as_string, Host => $update_host ); + die $res->status_line unless ( $res->is_success ); + # make sure to use only the filename for security reason + my $geoip_filename = File::Spec->catfile( $opts{d}, basename($res->content) ); + + # /* get MD5 of current GeoIP database file */ + my $old_md5 = _get_hexdigest($geoip_filename); + + print "MD5 sum of database $geoip_filename is $old_md5\n" if $verbose; + + unless ($client_ipaddr) { + print 'Send request ' . $u->as_string, "\n" if ($verbose); + + # /* get client ip address from MaxMind web page */ + $res = $ua->request( GET "$proto://$update_host/app/update_getipaddr", + Host => $update_host ); + die $res->status_line unless ( $res->is_success ); + $client_ipaddr = $res->content; + } + + print "client ip address: $client_ipaddr\n" if $verbose; + my $hex_digest2 = + Digest::MD5->new->add( $license_key, $client_ipaddr )->hexdigest; + print "md5sum of ip address and license key is $hex_digest2\n" if $verbose; + + my $mk_db_req_cref = sub { + + $u->path('/app/update_secure'); + $u->query_form( + db_md5 => shift, + challenge_md5 => $hex_digest2, + user_id => $user_id, + edition_id => $product_id + ); + print 'Send request ' . $u->as_string, "\n" if ($verbose); + return $ua->request( GET $u->as_string, Host => $update_host ); + }; + $res = $mk_db_req_cref->($old_md5); + die $res->status_line unless ( $res->is_success ); + + # print Dumper($res); + print "Downloading gzipped GeoIP Database...\n" if $verbose; + + _gunzip_and_replace( + $res->content, + $geoip_filename, + sub { + + # as sanity check request a update for the new downloaded file + # md5 of the new unpacked file + my $new_md5 = _get_hexdigest(shift); + return $mk_db_req_cref->($new_md5); + } + ); + print "Done\n" if $verbose; +} + +sub GeoIP_update_database { + my ( $license_key, $verbose ) = @_; + my $geoip_filename = File::Spec->catfile( $opts{d}, 'GeoIP.dat' ); + + # /* get MD5 of current GeoIP database file */ + my $hexdigest = _get_hexdigest($geoip_filename); + + print "MD5 sum of database $geoip_filename is $hexdigest\n" if $verbose; + + my $u = URI->new("$proto://$update_host/app/update"); + $u->query_form( license_key => $license_key, md5 => $hexdigest ); + + print 'Send request ' . $u->as_string, "\n" if ($verbose); + my $res = $ua->request( GET $u->as_string, Host => $update_host ); + die $res->status_line unless ( $res->is_success ); + print "Downloading gzipped GeoIP Database...\n" if $verbose; + _gunzip_and_replace( $res->content, $geoip_filename ); + print "Done\n" if $verbose; + +} + +# --- hexdigest of the file or 00000000000000000000000000000000 +sub _get_hexdigest { + my $md5 = '0' x 32; + if ( open my $fh, '<:raw', shift ) { + $md5 = Digest::MD5->new->addfile($fh)->hexdigest; + } + return $md5; +} + +sub _gunzip_and_replace { + my ( $content, $geoip_filename, $sanity_check_c ) = @_; + my $max_retry = 1; + + my $tmp_fname = $geoip_filename . '.test'; + + { + + # --- error if our content does not start with the gzip header + die $content || 'Not a gzip file' if substr( $content, 0, 2 ) ne "\x1f\x8b"; + + # --- uncompress the gzip data + { + local $_; + open my $gin, '<:gzip', \$content or die $!; + open my $gout, '>:raw', $tmp_fname or die $!; + print {$gout} $_ while (<$gin>); + } + + # --- sanity check + if ( defined $sanity_check_c ) { + die "Download failed" if $max_retry-- <= 0; + my $res = $sanity_check_c->($tmp_fname); + die $res->status_line unless ( $res->is_success ); + $content = $res->content; + + redo if ( $content !~ /^No new updates available/ ); + } + } + + # --- install GeoIP.dat.test -> GeoIP.dat + rename( $tmp_fname, $geoip_filename ) or die $!; +} + diff --git a/src/libs/resiprocate/contrib/GeoIP/apps/geoipupdate.c b/src/libs/resiprocate/contrib/GeoIP/apps/geoipupdate.c new file mode 100644 index 00000000..b3a553b2 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/apps/geoipupdate.c @@ -0,0 +1,283 @@ +/* geoipupdate.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include "GeoIPUpdate.h" + +#include +#include +#include +#ifdef __linux__ +#include +#endif +#include + +#define PRODUCT_ID_TOKEN "ProductIds" +#define USER_ID_TOKEN "UserId" +#define LICENSE_KEY_TOKEN "LicenseKey" +#define LICENSE_KEY_LENGTH 12 + +const char *GeoIPConfFile = "GeoIP.conf"; + +void usage() { + fprintf(stderr,"Usage: geoipupdate [-hv] [-f license_file] [-d custom directory]\n"); +} + +void my_printf(char * str) { + printf("%s", str); +} + +void print_status (int err, char * license_file) { + if (err == GEOIP_NO_NEW_UPDATES) { + fprintf(stdout,"GeoIP Database up to date\n"); + } else if (err == GEOIP_LICENSE_KEY_INVALID_ERR) { + fprintf(stderr,"Invalid License Key in %s - Please visit http://www.maxmind.com/app/products for a subscription\n",license_file); + } else if (err == GEOIP_USER_ID_INVALID_ERR){ + fprintf(stderr,"Invalid UserID\n"); + } else if (err == GEOIP_PRODUCT_ID_INVALID_ERR){ + fprintf(stderr,"Invalid product ID or subscription expired\n"); + } else if (err < 0) { + fprintf(stderr,"Received Error %d (%s) when attempting to update GeoIP Database\n",err, GeoIP_get_error_message(err)); + } else { + fprintf(stdout,"Updated database\n"); + } +} + +int main (int argc, char *argv[]) { + int verbose = 0; + char * license_file = NULL; + FILE * license_fh; + int n = 40; + int line_index = 0; + unsigned char *lineptr = malloc(sizeof(char) * n); + char *a_license_key_str, *a_ptr; + char *the_license_key_str = ""; + char * the_reference_empty_license_key_str = the_license_key_str; + char *a_user_id_str = NULL; + /* the string that holds the user id */ + char *the_user_id_str = NULL; + /* the integer that holds the length of the string the_user_id_str */ + int the_user_id_strl = 0; + /* the integer that holds the alloc length of the string the_user_id_str */ + int the_user_id_stral = 0; + char *a_product_id_str = NULL; + char **the_product_id_str = NULL; + int *the_product_id_strl = NULL; + int *the_product_id_stral = NULL; + int num_product_ids = 0; + char * client_ipaddr = NULL; + char * custom_directory = NULL; + int c; + int err = 0; + int i; + + opterr = 0; + + while ((c = getopt (argc, argv, "hvf:d:")) != -1) + switch (c) { + case 'h': + usage(); + exit(0); + case 'v': + verbose = 1; + break; + case 'f': + license_file = optarg; + break; + case 'd': + custom_directory = optarg; + break; + case '?': + if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, + "Unknown option character `\\x%x'.\n", + optopt); + usage(); + exit(1); + default: + abort(); + } + + if (custom_directory != NULL) { + GeoIP_setup_custom_directory(custom_directory); + } + if (license_file == NULL) { + license_file = malloc(sizeof(char) * (strlen(SYSCONFDIR)+strlen(GeoIPConfFile)+2)); + license_file[0] = '\0'; + strcat(license_file, SYSCONFDIR); + strcat(license_file, "/"); + strcat(license_file, GeoIPConfFile); + } + + license_fh = fopen(license_file,"r"); + if (license_fh == NULL) { + fprintf(stderr,"Error opening GeoIP Configuration file %s\n",license_file); + exit(1); + } + + if (verbose == 1) + printf("Opened License file %s\n", license_file); + + do { + c = fgetc(license_fh); + if (line_index >= n) { + n += 20; + lineptr = realloc(lineptr, n); + } + if (c == 10 || c == EOF) { + lineptr[line_index++] = '\0'; + line_index = 0; + if (lineptr[0] == '#') + continue; + /* get the product ids from the config file */ + a_product_id_str = strstr((char *)lineptr, PRODUCT_ID_TOKEN);//search for a product id token in the line + if (a_product_id_str != NULL) { + a_ptr = a_product_id_str; + /* set pos at the end of product id token */ + a_ptr += strlen(PRODUCT_ID_TOKEN) + 1; + while (a_ptr[0] == ' ') { + /* skip spaces */ + a_ptr++; + } + /* alloc the array of product ids */ + the_product_id_str = (char **) malloc((num_product_ids+1) * sizeof(char*)); /* array of strings */ + the_product_id_strl = (int *) malloc((num_product_ids+1) * sizeof(char*)); /* array of string lengths */ + the_product_id_stral = (int *) malloc((num_product_ids+1) * sizeof(char*)); /* array of string alloc lengths */ + while (a_ptr[0] != '\0') { + /* add new product id to the array of product ids */ + the_product_id_str[num_product_ids] = (char *) malloc(20); /* the string */ + the_product_id_strl[num_product_ids] = 0; /* the length of the string */ + the_product_id_stral[num_product_ids] = 20; /* the alloc length of the string */ + while ((a_ptr[0] != ' ') & (a_ptr[0] != '\0')) { + if (the_product_id_strl[num_product_ids] >= the_product_id_stral[num_product_ids]) { + /* if the length of the string is equal or more than + * alloc length of the string then realloc the string and + * increase the alloc length by 20 */ + the_product_id_stral[num_product_ids] = the_product_id_stral[num_product_ids] + 20; + the_product_id_str[num_product_ids] = (char *) realloc(the_product_id_str[num_product_ids],the_product_id_stral[num_product_ids]+4); + } + /* read the product id from the line in the config file */ + the_product_id_str[num_product_ids][the_product_id_strl[num_product_ids]] = a_ptr[0]; + the_product_id_strl[num_product_ids]++; + a_ptr++; + } + the_product_id_str[num_product_ids][the_product_id_strl[num_product_ids]] = 0; + while ((a_ptr[0] == ' ') & (a_ptr[0] != '\0')) { + a_ptr++;//skip spaces + } + /* new product id add, realloc the arrays */ + num_product_ids = num_product_ids + 1; + /* array of string */ + the_product_id_str = (char **) realloc(the_product_id_str,(num_product_ids+1) * sizeof(char*)); + /* array of string lengths */ + the_product_id_strl = (int *) realloc(the_product_id_strl,(num_product_ids+1) * sizeof(char*)); + /* array of string alloc lengths */ + the_product_id_stral = (int *) realloc(the_product_id_stral,(num_product_ids+1) * sizeof(char*)); + } + } + + /* get the user id from the config file */ + a_user_id_str = strstr((char *)lineptr, USER_ID_TOKEN); /* search for a user id token in the line */ + if (a_user_id_str != NULL) { + a_ptr = a_user_id_str; + /* set the position at the end of user id token */ + a_ptr += strlen(USER_ID_TOKEN) + 1; + while (a_ptr[0] == ' ') { + /* skip spaces */ + a_ptr++; + } + /* get the string that has the user id */ + the_user_id_stral = 20; + the_user_id_str = (char *)malloc(the_user_id_stral); + /* loop while the chars are numbers */ + while ((a_ptr[0] >= '0') & (a_ptr[0] <= '9')) { + the_user_id_str[the_user_id_strl++] = a_ptr[0]; + a_ptr++; + if (the_user_id_strl >= the_user_id_stral) { + /* if the length of user id string is greater or equal to + * the alloc length of user id string then + * add 20 to the alloc length and realloc the user id string */ + the_user_id_stral += 20; + the_user_id_str = realloc(the_user_id_str,the_user_id_stral); + } + } + the_user_id_str[the_user_id_strl] = 0; /* add NUL char */ + } + a_license_key_str = strstr((char *)lineptr, LICENSE_KEY_TOKEN); + if (a_license_key_str != NULL) { + a_ptr = a_license_key_str; + a_ptr += strlen(LICENSE_KEY_TOKEN) + 1; + while (a_ptr[0] == ' ') { + a_ptr++; + } + the_license_key_str = malloc(sizeof(char) * (LICENSE_KEY_LENGTH + 1)); + strncpy(the_license_key_str, a_ptr, LICENSE_KEY_LENGTH); + the_license_key_str[LICENSE_KEY_LENGTH] = '\0'; + } + } else { + lineptr[line_index++] = c; + } + } while (c != EOF); + + free(lineptr); + + fclose(license_fh); + + if (verbose == 1) { + printf("Read in license key %s\n", the_license_key_str); + printf("number of product ids %d \n",num_product_ids); + } + + if (the_user_id_str != NULL) { + /* update the databases using the user id string, the license key string and the product id for each database */ + client_ipaddr = NULL; + for (i = 0; i < num_product_ids; i++) { + err = GeoIP_update_database_general(the_user_id_str, the_license_key_str, the_product_id_str[i], verbose,&client_ipaddr, &my_printf); + print_status(err, license_file); + } + } else { + /* Old format with just license key for MaxMind GeoIP Country database updates + * here for backwards compatibility */ + err = GeoIP_update_database(the_license_key_str, verbose, &my_printf); + print_status(err, license_file); + } + + if (the_product_id_str != NULL) { + /* free the product ids */ + for (i = 0; i < num_product_ids; i++ ) { + free(the_product_id_str[i]); + } + free(the_product_id_str); + free(the_product_id_strl); + free(the_product_id_stral); + } + + if ( the_reference_empty_license_key_str != the_license_key_str ) + free(the_license_key_str); + + if (the_user_id_str) + free(the_user_id_str); + + if (client_ipaddr) { + free(client_ipaddr); + } + exit(err); +} diff --git a/src/libs/resiprocate/contrib/GeoIP/bootstrap b/src/libs/resiprocate/contrib/GeoIP/bootstrap new file mode 100644 index 00000000..d3a651db --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/bootstrap @@ -0,0 +1,8 @@ +#! /bin/sh + +# disable dependency trackeing for OS X with multiply arch option's +# automake -i --gnu --add-missing + +aclocal \ +&& automake -i --gnu --add-missing \ +&& autoconf diff --git a/src/libs/resiprocate/contrib/GeoIP/conf/GeoIP.conf.default b/src/libs/resiprocate/contrib/GeoIP/conf/GeoIP.conf.default new file mode 100644 index 00000000..33f55265 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/conf/GeoIP.conf.default @@ -0,0 +1,19 @@ +# If you purchase a subscription to the GeoIP database, +# then you will obtain a license key which you can +# use to automatically obtain updates. +# for more details, please go to +# http://www.maxmind.com/app/products + +# see https://www.maxmind.com/app/license_key_login to obtain License Key, +# UserId, and available ProductIds + +# Enter your license key here +LicenseKey YOUR_LICENSE_KEY_HERE + +# Enter your User ID here +UserId YOUR_USER_ID_HERE + +# Enter the Product ID(s) of the database(s) you would like to update +# By default 106 (MaxMind GeoIP Country) is listed below +ProductIds 106 + diff --git a/src/libs/resiprocate/contrib/GeoIP/conf/Makefile.am b/src/libs/resiprocate/contrib/GeoIP/conf/Makefile.am new file mode 100644 index 00000000..c55ec18b --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/conf/Makefile.am @@ -0,0 +1,16 @@ +dist_sysconf_DATA = GeoIP.conf.default + +DEFAULT_CONFIG_FILE = $(sysconfdir)/GeoIP.conf + +install-exec-hook: + @if test -f "$(DESTDIR)$(DEFAULT_CONFIG_FILE)" ; then \ + echo "$@ will not overwrite existing $(DESTDIR)$(DEFAULT_CONFIG_FILE)" ; \ + else \ + echo "$(INSTALL_DATA) GeoIP.conf.default $(DESTDIR)$(DEFAULT_CONFIG_FILE)"; \ + $(INSTALL_DATA) "$(srcdir)/GeoIP.conf.default" "$(DESTDIR)$(DEFAULT_CONFIG_FILE)"; \ + fi + +uninstall-hook: + @if test -f "$(DESTDIR)$(DEFAULT_CONFIG_FILE)" ; then \ + rm "$(DESTDIR)$(DEFAULT_CONFIG_FILE)"; \ +fi diff --git a/src/libs/resiprocate/contrib/GeoIP/conf/Makefile.in b/src/libs/resiprocate/contrib/GeoIP/conf/Makefile.in new file mode 100644 index 00000000..2a4ad929 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/conf/Makefile.in @@ -0,0 +1,414 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = conf +DIST_COMMON = $(dist_sysconf_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(sysconfdir)" +DATA = $(dist_sysconf_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEOIP_VERSION_INFO = @GEOIP_VERSION_INFO@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +dist_sysconf_DATA = GeoIP.conf.default +DEFAULT_CONFIG_FILE = $(sysconfdir)/GeoIP.conf +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu conf/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu conf/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dist_sysconfDATA: $(dist_sysconf_DATA) + @$(NORMAL_INSTALL) + test -z "$(sysconfdir)" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)" + @list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sysconfdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(sysconfdir)" || exit $$?; \ + done + +uninstall-dist_sysconfDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sysconfdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sysconfdir)" && rm -f $$files +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(sysconfdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-dist_sysconfDATA + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_sysconfDATA + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +.MAKE: install-am install-exec-am install-strip uninstall-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_sysconfDATA \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-exec-hook install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-dist_sysconfDATA uninstall-hook + + +install-exec-hook: + @if test -f "$(DESTDIR)$(DEFAULT_CONFIG_FILE)" ; then \ + echo "$@ will not overwrite existing $(DESTDIR)$(DEFAULT_CONFIG_FILE)" ; \ + else \ + echo "$(INSTALL_DATA) GeoIP.conf.default $(DESTDIR)$(DEFAULT_CONFIG_FILE)"; \ + $(INSTALL_DATA) "$(srcdir)/GeoIP.conf.default" "$(DESTDIR)$(DEFAULT_CONFIG_FILE)"; \ + fi + +uninstall-hook: + @if test -f "$(DESTDIR)$(DEFAULT_CONFIG_FILE)" ; then \ + rm "$(DESTDIR)$(DEFAULT_CONFIG_FILE)"; \ +fi + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/resiprocate/contrib/GeoIP/config.guess b/src/libs/resiprocate/contrib/GeoIP/config.guess new file mode 100644 index 00000000..e3a2116a --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/config.guess @@ -0,0 +1,1533 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2009-06-10' + +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[456]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd | genuineintel) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/libs/resiprocate/contrib/GeoIP/config.sub b/src/libs/resiprocate/contrib/GeoIP/config.sub new file mode 100644 index 00000000..eb0389a6 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/config.sub @@ -0,0 +1,1693 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2009-06-11' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/libs/resiprocate/contrib/GeoIP/configure b/src/libs/resiprocate/contrib/GeoIP/configure new file mode 100644 index 00000000..246e7563 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/configure @@ -0,0 +1,13633 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.65 for GeoIP 1.4.8. +# +# Report bugs to . +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: support@maxmind.com about your system, including any +$0: error possibly output before this message. Then install +$0: a modern shell, or manually run the script under such a +$0: shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$lt_ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +ECHO=${lt_ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<_LT_EOF +$* +_LT_EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test -z "$lt_ECHO"; then + if test "X${echo_test_string+set}" != Xset; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if { echo_test_string=`eval $cmd`; } 2>/dev/null && + { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null + then + break + fi + done + fi + + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : + else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$ECHO" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + ECHO='print -r' + elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + ECHO='printf %s\n' + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + ECHO="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + ECHO=echo + fi + fi + fi + fi + fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +lt_ECHO=$ECHO +if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='GeoIP' +PACKAGE_TARNAME='GeoIP' +PACKAGE_VERSION='1.4.8' +PACKAGE_STRING='GeoIP 1.4.8' +PACKAGE_BUGREPORT='support@maxmind.com' +PACKAGE_URL='' + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_unique_file="libGeoIP/GeoIP.c" +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +lt_ECHO +RANLIB +AR +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +GEOIP_VERSION_INFO +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +enable_libtool_lock +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information." + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures GeoIP 1.4.8 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/GeoIP] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of GeoIP 1.4.8:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +GeoIP configure 1.4.8 +generated by GNU Autoconf 2.65 + +Copyright (C) 2009 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( cat <<\_ASBOX +## ---------------------------------- ## +## Report this to support@maxmind.com ## +## ---------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_func + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_type +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by GeoIP $as_me 1.4.8, which was +generated by GNU Autoconf 2.65. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + ac_site_file1=$CONFIG_SITE +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "no acceptable C compiler found in \$PATH +See \`config.log' for more details." "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "C compiler cannot create executables +See \`config.log' for more details." "$LINENO" 5; }; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot compute suffix of object files: cannot compile +See \`config.log' for more details." "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if test "${ac_cv_path_GREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = x""yes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if test "${ac_cv_safe_to_define___extensions__+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + + +am__api_version='1.11' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + for ac_t in install-sh install.sh shtool; do + if test -f "$ac_dir/$ac_t"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/$ac_t -c" + break 2 + fi + done +done +if test -z "$ac_aux_dir"; then + as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if test "${ac_cv_path_mkdir+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='GeoIP' + VERSION='1.4.8' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + + +GEOIP_VERSION_INFO=`echo $VERSION | awk -F. '{ printf "%d:%d:%d", $1+$2, $3, $2 }'` + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "no acceptable C compiler found in \$PATH +See \`config.log' for more details." "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.2.6b' +macro_revision='1.3017' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if test "${ac_cv_build+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if test "${ac_cv_path_SED+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if test "${ac_cv_path_FGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if test "${lt_cv_path_NM+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$ac_tool_prefix"; then + for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_DUMPBIN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in "dumpbin -symbols" "link -dump -symbols" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if test "${lt_cv_nm_interface+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:5395: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:5398: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:5401: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if test "${lt_cv_sys_max_cmd_len+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ + = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if test "${lt_cv_ld_reload_flag+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OBJDUMP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if test "${lt_cv_deplibs_check_method+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + + + + + + + + + + + + + + + + + + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 6606 "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if test "${lt_cv_cc_needs_belf+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_DSYMUTIL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_NMEDIT+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_LIPO+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OTOOL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OTOOL64+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if test "${lt_cv_apple_cc_single_mod+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if test "${lt_cv_ld_exported_symbols_list+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if test "${lt_cv_objdir+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + + + + + + + + + + + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:7864: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:7868: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl*) + # IBM XL C 8.0/Fortran 10.1 on PPC + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 +$as_echo "$lt_prog_compiler_pic" >&6; } + + + + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test "${lt_cv_prog_compiler_pic_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:8203: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:8207: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test "${lt_cv_prog_compiler_static_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:8308: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:8312: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:8363: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:8367: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag= + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + whole_archive_flag_spec='' + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=echo + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo(void) {} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + archive_cmds_need_lc=no + else + archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 +$as_echo "$archive_cmds_need_lc" >&6; } + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = x""yes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if test "${ac_cv_lib_dld_shl_load+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = x""yes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if test "${ac_cv_lib_svld_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if test "${ac_cv_lib_dld_dld_link+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = x""yes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if test "${lt_cv_dlopen_self+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 10747 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if test "${lt_cv_dlopen_self_static+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 10843 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +ac_fn_c_check_type "$LINENO" "byte" "ac_cv_type_byte" "$ac_includes_default" +if test "x$ac_cv_type_byte" = x""yes; then : + $as_echo "#define HAVE_BYTE_TYPEDEF 1" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "ushort" "ac_cv_type_ushort" "$ac_includes_default" +if test "x$ac_cv_type_ushort" = x""yes; then : + $as_echo "#define HAVE_USHORT_TYPEDEF 1" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "ulong" "ac_cv_type_ulong" "$ac_includes_default" +if test "x$ac_cv_type_ulong" = x""yes; then : + $as_echo "#define HAVE_ULONG_TYPEDEF 1" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "u16" "ac_cv_type_u16" "$ac_includes_default" +if test "x$ac_cv_type_u16" = x""yes; then : + $as_echo "#define HAVE_U16_TYPEDEF 1" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "u32" "ac_cv_type_u32" "$ac_includes_default" +if test "x$ac_cv_type_u32" = x""yes; then : + $as_echo "#define HAVE_U32_TYPEDEF 1" >>confdefs.h + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if test "${ac_cv_c_bigendian+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define BIG_ENDIAN_HOST 1" >>confdefs.h +;; #( + no) + $as_echo "#define LITTLE_ENDIAN_HOST 1" >>confdefs.h + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + +for ac_header in stdint.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" +if test "x$ac_cv_header_stdint_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STDINT_H 1 +_ACEOF + +fi + +done + +for ac_header in zlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ZLIB_H 1 +_ACEOF + +else + as_fn_error "Zlib header (zlib.h) not found. Tor requires zlib to build. You may need to install a zlib development package." "$LINENO" 5 +fi + +done + + +ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" +if test "x$ac_cv_func_gettimeofday" = x""yes; then : + $as_echo "#define HAVE_GETTIMEOFDAY 1" >>confdefs.h + +fi + +ac_fn_c_check_func "$LINENO" "vasprintf" "ac_cv_func_vasprintf" +if test "x$ac_cv_func_vasprintf" = x""yes; then : + $as_echo "#define HAVE_VASPRINTF 1" >>confdefs.h + +fi + +ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" +if test "x$ac_cv_func_vsnprintf" = x""yes; then : + $as_echo "#define HAVE_VSNPRINTF 1" >>confdefs.h + +fi + +ac_fn_c_check_func "$LINENO" "vsprintf" "ac_cv_func_vsprintf" +if test "x$ac_cv_func_vsprintf" = x""yes; then : + $as_echo "#define HAVE_VSPRINTF 1" >>confdefs.h + +fi + + +ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" +if test "x$ac_cv_func_gethostbyname" = x""yes; then : + $as_echo "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 +$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_gethostbyname=yes +else + ac_cv_lib_nsl_gethostbyname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 +$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } +if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then : + $as_echo "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h + + LIBS="${LIBS} -lsocket -lnsl" +fi + +fi + + +ac_fn_c_check_func "$LINENO" "gethostbyname_r" "ac_cv_func_gethostbyname_r" +if test "x$ac_cv_func_gethostbyname_r" = x""yes; then : + + $as_echo "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h + + # We look for the one that returns `int'. + # Hopefully this check is robust enough. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "int.*gethostbyname_r" >/dev/null 2>&1; then : + + $as_echo "#define GETHOSTBYNAME_R_RETURNS_INT 1" >>confdefs.h + +fi +rm -f conftest* + + +fi + + +ac_config_files="$ac_config_files Makefile GeoIP.spec libGeoIP/Makefile apps/Makefile conf/Makefile data/Makefile man/Makefile test/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + + + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by GeoIP $as_me 1.4.8, which was +generated by GNU Autoconf 2.65. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +GeoIP config.status 1.4.8 +configured by $0, generated by GNU Autoconf 2.65, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2009 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' +macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' +enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' +pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' +host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' +host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' +host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' +build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' +build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' +build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' +SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' +Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' +GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' +EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' +FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' +LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' +NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' +LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' +ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' +exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' +lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' +reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' +AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' +STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' +RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' +CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' +compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' +GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' +objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' +SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' +ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' +need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' +LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' +OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' +libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' +module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' +fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' +need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' +version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' +runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' +libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' +soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' +finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' +old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' +striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# Quote evaled strings. +for var in SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +AR \ +AR_FLAGS \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +SHELL \ +ECHO \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_wl \ +lt_prog_compiler_pic \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +fix_srcfile_path \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec; do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Fix-up fallback echo if it was mangled by the above quoting rules. +case \$lt_ECHO in +*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` + ;; +esac + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "GeoIP.spec") CONFIG_FILES="$CONFIG_FILES GeoIP.spec" ;; + "libGeoIP/Makefile") CONFIG_FILES="$CONFIG_FILES libGeoIP/Makefile" ;; + "apps/Makefile") CONFIG_FILES="$CONFIG_FILES apps/Makefile" ;; + "conf/Makefile") CONFIG_FILES="$CONFIG_FILES conf/Makefile" ;; + "data/Makefile") CONFIG_FILES="$CONFIG_FILES data/Makefile" ;; + "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; + "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; + + *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || as_fn_error "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + + +eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + ;; + + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="" + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that does not interpret backslashes. +ECHO=$lt_ECHO + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $* )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[^=]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$@"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1+=\$2" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1=\$$1\$2" +} + +_LT_EOF + ;; + esac + + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit $? +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/src/libs/resiprocate/contrib/GeoIP/configure.in b/src/libs/resiprocate/contrib/GeoIP/configure.in new file mode 100644 index 00000000..77309b18 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/configure.in @@ -0,0 +1,50 @@ +dnl AM_CONFIG_HEADER(config.h) + +AC_INIT([GeoIP], [1.4.8],[support@maxmind.com],[GeoIP]) +AC_GNU_SOURCE +AM_INIT_AUTOMAKE +AC_CONFIG_SRCDIR([libGeoIP/GeoIP.c]) +GEOIP_VERSION_INFO=`echo $VERSION | awk -F. '{ printf "%d:%d:%d", $1+$2, $3, $2 }'` +AC_SUBST(GEOIP_VERSION_INFO) + +AC_PROG_CC +AC_PROG_LIBTOOL + +AC_CHECK_TYPE(byte,[AC_DEFINE(HAVE_BYTE_TYPEDEF)],[]) +AC_CHECK_TYPE(ushort,[AC_DEFINE(HAVE_USHORT_TYPEDEF)],[]) +AC_CHECK_TYPE(ulong,[AC_DEFINE(HAVE_ULONG_TYPEDEF)],[]) +AC_CHECK_TYPE(u16,[AC_DEFINE(HAVE_U16_TYPEDEF)],[]) +AC_CHECK_TYPE(u32,[AC_DEFINE(HAVE_U32_TYPEDEF)],[]) + +AC_C_BIGENDIAN([AC_DEFINE(BIG_ENDIAN_HOST,1)],[AC_DEFINE(LITTLE_ENDIAN_HOST,1)]) + +AC_CHECK_HEADERS(stdint.h) +AC_CHECK_HEADERS(zlib.h, , AC_MSG_ERROR(Zlib header (zlib.h) not found. Tor requires zlib to build. You may need to install a zlib development package.)) + +AC_CHECK_FUNC(gettimeofday, AC_DEFINE(HAVE_GETTIMEOFDAY)) +AC_CHECK_FUNC(vasprintf, AC_DEFINE(HAVE_VASPRINTF)) +AC_CHECK_FUNC(vsnprintf, AC_DEFINE(HAVE_VSNPRINTF)) +AC_CHECK_FUNC(vsprintf, AC_DEFINE(HAVE_VSPRINTF)) + +AC_CHECK_FUNC(gethostbyname, AC_DEFINE(HAVE_GETHOSTBYNAME), + AC_CHECK_LIB(nsl, gethostbyname, AC_DEFINE(HAVE_GETHOSTBYNAME) + LIBS="${LIBS} -lsocket -lnsl")) + +AC_CHECK_FUNC(gethostbyname_r, [ + AC_DEFINE(HAVE_GETHOSTBYNAME_R) + # We look for the one that returns `int'. + # Hopefully this check is robust enough. + AC_EGREP_HEADER(int.*gethostbyname_r, netdb.h, [ + AC_DEFINE(GETHOSTBYNAME_R_RETURNS_INT)]) + ]) + +AC_OUTPUT([ +Makefile +GeoIP.spec +libGeoIP/Makefile +apps/Makefile +conf/Makefile +data/Makefile +man/Makefile +test/Makefile +]) diff --git a/src/libs/resiprocate/contrib/GeoIP/data/GeoIP.dat b/src/libs/resiprocate/contrib/GeoIP/data/GeoIP.dat new file mode 100644 index 00000000..602dead7 Binary files /dev/null and b/src/libs/resiprocate/contrib/GeoIP/data/GeoIP.dat differ diff --git a/src/libs/resiprocate/contrib/GeoIP/data/Makefile.am b/src/libs/resiprocate/contrib/GeoIP/data/Makefile.am new file mode 100644 index 00000000..5b7b9096 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/data/Makefile.am @@ -0,0 +1,19 @@ +pkgdata_DATA = + +dist_pkgdata_DATA = GeoIP.dat + +DEFAULT_DB_FILE = $(pkgdatadir)/GeoIP.dat + +install-data-hook: + @if test -f "$(DESTDIR)$(DEFAULT_DB_FILE)" ; then \ + echo "$@ will not overwrite existing $(DESTDIR)$(DEFAULT_DB_FILE)" ; \ + else \ + echo "$(INSTALL_DATA) GeoIP.dat $(DESTDIR)$(DEFAULT_DB_FILE)"; \ + $(INSTALL_DATA) "$(srcdir)/GeoIP.dat" "$(DESTDIR)$(DEFAULT_DB_FILE)"; \ + fi + +uninstall-hook: + @if test -f "$(DESTDIR)$(DEFAULT_DB_FILE)" ; then \ + rm "$(DESTDIR)$(DEFAULT_DB_FILE)"; \ +$(INSTALL_DATA) GeoIP.dat $(DESTDIR)$(DEFAULT_DB_FILE); \ + fi diff --git a/src/libs/resiprocate/contrib/GeoIP/data/Makefile.in b/src/libs/resiprocate/contrib/GeoIP/data/Makefile.in new file mode 100644 index 00000000..9d814220 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/data/Makefile.in @@ -0,0 +1,437 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = data +DIST_COMMON = $(dist_pkgdata_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgdatadir)" +DATA = $(dist_pkgdata_DATA) $(pkgdata_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEOIP_VERSION_INFO = @GEOIP_VERSION_INFO@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkgdata_DATA = +dist_pkgdata_DATA = GeoIP.dat +DEFAULT_DB_FILE = $(pkgdatadir)/GeoIP.dat +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu data/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu data/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dist_pkgdataDATA: $(dist_pkgdata_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" + @list='$(dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ + done + +uninstall-dist_pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkgdatadir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkgdatadir)" && rm -f $$files +install-pkgdataDATA: $(pkgdata_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ + done + +uninstall-pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkgdatadir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkgdatadir)" && rm -f $$files +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgdatadir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_pkgdataDATA install-pkgdataDATA + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_pkgdataDATA uninstall-pkgdataDATA + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +.MAKE: install-am install-data-am install-strip uninstall-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-data-hook \ + install-dist_pkgdataDATA install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkgdataDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + uninstall uninstall-am uninstall-dist_pkgdataDATA \ + uninstall-hook uninstall-pkgdataDATA + + +install-data-hook: + @if test -f "$(DESTDIR)$(DEFAULT_DB_FILE)" ; then \ + echo "$@ will not overwrite existing $(DESTDIR)$(DEFAULT_DB_FILE)" ; \ + else \ + echo "$(INSTALL_DATA) GeoIP.dat $(DESTDIR)$(DEFAULT_DB_FILE)"; \ + $(INSTALL_DATA) "$(srcdir)/GeoIP.dat" "$(DESTDIR)$(DEFAULT_DB_FILE)"; \ + fi + +uninstall-hook: + @if test -f "$(DESTDIR)$(DEFAULT_DB_FILE)" ; then \ + rm "$(DESTDIR)$(DEFAULT_DB_FILE)"; \ +$(INSTALL_DATA) GeoIP.dat $(DESTDIR)$(DEFAULT_DB_FILE); \ + fi + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/resiprocate/contrib/GeoIP/depcomp b/src/libs/resiprocate/contrib/GeoIP/depcomp new file mode 100644 index 00000000..df8eea7e --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/depcomp @@ -0,0 +1,630 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free +# Software Foundation, Inc. + +# 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 2, 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 . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u="sed s,\\\\\\\\,/,g" + depmode=msvisualcpp +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/src/libs/resiprocate/contrib/GeoIP/geoip.ico b/src/libs/resiprocate/contrib/GeoIP/geoip.ico new file mode 100644 index 00000000..ac13353b Binary files /dev/null and b/src/libs/resiprocate/contrib/GeoIP/geoip.ico differ diff --git a/src/libs/resiprocate/contrib/GeoIP/get_ver.awk b/src/libs/resiprocate/contrib/GeoIP/get_ver.awk new file mode 100644 index 00000000..5e7abc08 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/get_ver.awk @@ -0,0 +1,14 @@ +# fetch version number from input file and write them to STDOUT +BEGIN { + while ((getline < ARGV[1]) > 0) { + if (match ($0, /^VERSION=/)) { + split($1, t, "="); + my_ver_str = t[2]; + split(my_ver_str, v, "."); + gsub("[^0-9].*$", "", v[3]); + my_ver = v[1] "," v[2] "," v[3]; + } + } + print "GEOIP_VERSION = " my_ver ""; + print "GEOIP_VERSION_STR = " my_ver_str ""; +} diff --git a/src/libs/resiprocate/contrib/GeoIP/install-sh b/src/libs/resiprocate/contrib/GeoIP/install-sh new file mode 100644 index 00000000..6781b987 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/install-sh @@ -0,0 +1,520 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2009-04-28.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIP.c b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIP.c new file mode 100644 index 00000000..c50655df --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIP.c @@ -0,0 +1,1981 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIP.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +static geoipv6_t IPV6_NULL; + +#if !defined(_WIN32) +#include +#include +#include +#else +#define ssize_t SSIZE_T +#include +#include + +ssize_t pread (int fd, void *buf, size_t count, off_t offset) +{ + HANDLE handle = (HANDLE)(intptr_t)_get_osfhandle (fd); + + OVERLAPPED olap = { 0 }; + DWORD written; + + if (handle == INVALID_HANDLE_VALUE) + return -1; + + olap.Offset = offset; + //olap.OffsetHigh = offset >> 32; + + /* This braindead API will override the file pointer even if we specify + * an explicit read offset... So do not expect this to mix well with + * regular read() calls. */ + if (ReadFile (handle, buf, count, &written, &olap)) + return written; + return -1; +} + +#endif /* !defined(_WIN32) */ + +#include +#include +#include +#include +#include +#include /* for fstat */ +#include /* for fstat */ + +#ifdef HAVE_GETTIMEOFDAY +#include /* for gettimeofday */ +#endif + +#ifdef HAVE_STDINT_H +#include /* For uint32_t */ +#endif + +#ifndef INADDR_NONE +#define INADDR_NONE -1 +#endif + +#define COUNTRY_BEGIN 16776960 +#define LARGE_COUNTRY_BEGIN 16515072 +#define STATE_BEGIN_REV0 16700000 +#define STATE_BEGIN_REV1 16000000 +#define STRUCTURE_INFO_MAX_SIZE 20 +#define DATABASE_INFO_MAX_SIZE 100 +#define MAX_ORG_RECORD_LENGTH 300 +#define US_OFFSET 1 +#define CANADA_OFFSET 677 +#define WORLD_OFFSET 1353 +#define FIPS_RANGE 360 + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +const char GeoIP_country_code[254][3] = { "--","AP","EU","AD","AE","AF","AG","AI","AL","AM","CW", + "AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB", + "BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO", + "BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD", + "CF","CG","CH","CI","CK","CL","CM","CN","CO","CR", + "CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO", + "DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ", + "FK","FM","FO","FR","SX","GA","GB","GD","GE","GF", + "GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT", + "GU","GW","GY","HK","HM","HN","HR","HT","HU","ID", + "IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO", + "JP","KE","KG","KH","KI","KM","KN","KP","KR","KW", + "KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT", + "LU","LV","LY","MA","MC","MD","MG","MH","MK","ML", + "MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV", + "MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI", + "NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF", + "PG","PH","PK","PL","PM","PN","PR","PS","PT","PW", + "PY","QA","RE","RO","RU","RW","SA","SB","SC","SD", + "SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO", + "SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH", + "TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW", + "TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE", + "VG","VI","VN","VU","WF","WS","YE","YT","RS","ZA", + "ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE", + "BL","MF", "BQ"}; + +static const unsigned num_GeoIP_countries = (unsigned)(sizeof(GeoIP_country_code)/sizeof(GeoIP_country_code[0])); + +const char GeoIP_country_code3[254][4] = { "--","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","CUW", + "AGO","ATA","ARG","ASM","AUT","AUS","ABW","AZE","BIH","BRB", + "BGD","BEL","BFA","BGR","BHR","BDI","BEN","BMU","BRN","BOL", + "BRA","BHS","BTN","BVT","BWA","BLR","BLZ","CAN","CCK","COD", + "CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI", + "CUB","CPV","CXR","CYP","CZE","DEU","DJI","DNK","DMA","DOM", + "DZA","ECU","EST","EGY","ESH","ERI","ESP","ETH","FIN","FJI", + "FLK","FSM","FRO","FRA","SXM","GAB","GBR","GRD","GEO","GUF", + "GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","SGS","GTM", + "GUM","GNB","GUY","HKG","HMD","HND","HRV","HTI","HUN","IDN", + "IRL","ISR","IND","IOT","IRQ","IRN","ISL","ITA","JAM","JOR", + "JPN","KEN","KGZ","KHM","KIR","COM","KNA","PRK","KOR","KWT", + "CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU", + "LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI", + "MMR","MNG","MAC","MNP","MTQ","MRT","MSR","MLT","MUS","MDV", + "MWI","MEX","MYS","MOZ","NAM","NCL","NER","NFK","NGA","NIC", + "NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER","PYF", + "PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW", + "PRY","QAT","REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN", + "SWE","SGP","SHN","SVN","SJM","SVK","SLE","SMR","SEN","SOM", + "SUR","STP","SLV","SYR","SWZ","TCA","TCD","ATF","TGO","THA", + "TJK","TKL","TKM","TUN","TON","TLS","TUR","TTO","TUV","TWN", + "TZA","UKR","UGA","UMI","USA","URY","UZB","VAT","VCT","VEN", + "VGB","VIR","VNM","VUT","WLF","WSM","YEM","MYT","SRB","ZAF", + "ZMB","MNE","ZWE","A1","A2","O1","ALA","GGY","IMN","JEY", + "BLM","MAF", "BES"}; + +const char * GeoIP_utf8_country_name[254] = {"N/A","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Cura" "\xc3\xa7" "ao", + "Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados", + "Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia", + "Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the", + "Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica", + "Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic", + "Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji", + "Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","Sint Maarten (Dutch part)","Gabon","United Kingdom","Grenada","Georgia","French Guiana", + "Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala", + "Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia", + "Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan", + "Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait", + "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania", + "Luxembourg","Latvia","Libyan Arab Jamahiriya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali", + "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives", + "Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua", + "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia", + "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau", + "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan", + "Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname", + "Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand", + "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan", + "Tanzania, United Republic of","Ukraine","Uganda","United States Minor Outlying Islands","United States","Uruguay","Uzbekistan","Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela", + "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa", + "Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey", + "Saint Barthelemy","Saint Martin", "Bonaire, Saint Eustatius and Saba"}; + +const char * GeoIP_country_name[254] = {"N/A","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Cura" "\xe7" "ao", + "Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados", + "Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia", + "Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the", + "Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica", + "Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic", + "Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji", + "Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","Sint Maarten (Dutch part)","Gabon","United Kingdom","Grenada","Georgia","French Guiana", + "Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala", + "Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia", + "Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan", + "Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait", + "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania", + "Luxembourg","Latvia","Libyan Arab Jamahiriya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali", + "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives", + "Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua", + "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia", + "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau", + "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan", + "Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname", + "Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand", + "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan", + "Tanzania, United Republic of","Ukraine","Uganda","United States Minor Outlying Islands","United States","Uruguay","Uzbekistan","Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela", + "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa", + "Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey", + "Saint Barthelemy","Saint Martin", "Bonaire, Saint Eustatius and Saba"}; + +/* Possible continent codes are AF, AS, EU, NA, OC, SA for Africa, Asia, Europe, North America, Oceania +and South America. */ + +const char GeoIP_country_continent[254][3] = { + "--", "AS","EU","EU","AS","AS","NA","NA","EU","AS","NA", + "AF","AN","SA","OC","EU","OC","NA","AS","EU","NA", + "AS","EU","AF","EU","AS","AF","AF","NA","AS","SA", + "SA","NA","AS","AN","AF","EU","NA","NA","AS","AF", + "AF","AF","EU","AF","OC","SA","AF","AS","SA","NA", + "NA","AF","AS","AS","EU","EU","AF","EU","NA","NA", + "AF","SA","EU","AF","AF","AF","EU","AF","EU","OC", + "SA","OC","EU","EU","NA","AF","EU","NA","AS","SA", + "AF","EU","NA","AF","AF","NA","AF","EU","AN","NA", + "OC","AF","SA","AS","AN","NA","EU","NA","EU","AS", + "EU","AS","AS","AS","AS","AS","EU","EU","NA","AS", + "AS","AF","AS","AS","OC","AF","NA","AS","AS","AS", + "NA","AS","AS","AS","NA","EU","AS","AF","AF","EU", + "EU","EU","AF","AF","EU","EU","AF","OC","EU","AF", + "AS","AS","AS","OC","NA","AF","NA","EU","AF","AS", + "AF","NA","AS","AF","AF","OC","AF","OC","AF","NA", + "EU","EU","AS","OC","OC","OC","AS","NA","SA","OC", + "OC","AS","AS","EU","NA","OC","NA","AS","EU","OC", + "SA","AS","AF","EU","EU","AF","AS","OC","AF","AF", + "EU","AS","AF","EU","EU","EU","AF","EU","AF","AF", + "SA","AF","NA","AS","AF","NA","AF","AN","AF","AS", + "AS","OC","AS","AF","OC","AS","EU","NA","OC","AS", + "AF","EU","AF","OC","NA","SA","AS","EU","NA","SA", + "NA","NA","AS","OC","OC","OC","AS","AF","EU","AF", + "AF","EU","AF","--","--","--","EU","EU","EU","EU", + "NA","NA","NA" +}; + +geoipv6_t _GeoIP_lookupaddress_v6 (const char *host); + +#if defined(_WIN32) +/* http://www.mail-archive.com/users@ipv6.org/msg02107.html */ +static const char * _GeoIP_inet_ntop(int af, const void *src, char *dst, socklen_t cnt) +{ + if (af == AF_INET) + { + struct sockaddr_in in; + memset(&in, 0, sizeof(in)); + in.sin_family = AF_INET; + memcpy(&in.sin_addr, src, sizeof(struct in_addr)); + getnameinfo((struct sockaddr *)&in, sizeof(struct +sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST); + return dst; + } + else if (af == AF_INET6) + { + struct sockaddr_in6 in; + memset(&in, 0, sizeof(in)); + in.sin6_family = AF_INET6; + memcpy(&in.sin6_addr, src, sizeof(struct in_addr6)); + getnameinfo((struct sockaddr *)&in, sizeof(struct +sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST); + return dst; + } + return NULL; +} + +static int _GeoIP_inet_pton(int af, const char *src, void *dst) +{ + struct addrinfo hints, *res, *ressave; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = af; + + if (getaddrinfo(src, NULL, &hints, &res) != 0) + { + fprintf(stderr, "Couldn't resolve host %s\n", src); + return -1; + } + + ressave = res; + + while (res) + { + memcpy(dst, res->ai_addr, res->ai_addrlen); + res = res->ai_next; + } + + freeaddrinfo(ressave); + return 0; +} +#else +static int _GeoIP_inet_pton(int af, const char *src, void *dst) { + return inet_pton(af, src, dst); +} +static const char * _GeoIP_inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { + return inet_ntop(af, src, dst, cnt); +} + +#endif /* defined(_WIN32) */ + + +int __GEOIP_V6_IS_NULL(geoipv6_t v6) { + int i; + for (i=0;i<16;i++) { + if (v6.s6_addr[i]) + return 0; + } + return 1; +} + +void __GEOIP_PREPARE_TEREDO(geoipv6_t* v6){ + int i; + if ((v6->s6_addr[0]) != 0x20) return; + if ((v6->s6_addr[1]) != 0x01) return; + if ((v6->s6_addr[2]) != 0x00) return; + if ((v6->s6_addr[3]) != 0x00) return; + + for ( i = 0; i< 12; i++) + v6->s6_addr[i] = 0; + for ( ; i < 16; i++) + v6->s6_addr[i]^=0xff; +} + +const char * GeoIPDBDescription[NUM_DB_TYPES] = { + NULL, + "GeoIP Country Edition", + "GeoIP City Edition, Rev 1", + "GeoIP Region Edition, Rev 1", + "GeoIP ISP Edition", + "GeoIP Organization Edition", + "GeoIP City Edition, Rev 0", + "GeoIP Region Edition, Rev 0", + "GeoIP Proxy Edition", + "GeoIP ASNum Edition", + "GeoIP Netspeed Edition", + "GeoIP Domain Name Edition", + "GeoIP Country V6 Edition", + "GeoIP LocationID ASCII Edition", + "GeoIP Accuracy Radius Edition", + "GeoIP City with Confidence Edition", + "GeoIP City with Confidence and Accuracy Edition", + "GeoIP Large Country Edition", + "GeoIP Large Country V6 Edition", + NULL, + "GeoIP CCM Edition", + "GeoIP ASNum V6 Edition", + "GeoIP ISP V6 Edition", + "GeoIP Organization V6 Edition", + "GeoIP Domain Name V6 Edition", + "GeoIP LocationID ASCII V6 Edition", + "GeoIP Registrar Edition", + "GeoIP Registrar V6 Edition", + "GeoIP UserType Edition", + "GeoIP UserType V6 Edition", + "GeoIP City Edition V6, Rev 1", + "GeoIP City Edition V6, Rev 0", + "GeoIP Netspeed Edition, Rev 1", + "GeoIP Netspeed Edition V6, Rev1" +}; + +char * custom_directory = NULL; + +void GeoIP_setup_custom_directory (char * dir) { + custom_directory = dir; +} + +char *_GeoIP_full_path_to(const char *file_name) { + int len; + char *path = malloc(sizeof(char) * 1024); + + if (custom_directory == NULL){ +#if !defined(_WIN32) + memset(path, 0, sizeof(char) * 1024); + snprintf(path, sizeof(char) * 1024 - 1, "%s/%s", GEOIPDATADIR, file_name); +#else + char buf[MAX_PATH], *p, *q = NULL; + memset(buf, 0, sizeof(buf)); + len = GetModuleFileNameA(GetModuleHandle(NULL), buf, sizeof(buf) - 1); + for (p = buf + len; p > buf; p--) + if (*p == '\\') + { + if (!q) + q = p; + else + *p = '/'; + } + *q = 0; + memset(path, 0, sizeof(char) * 1024); + snprintf(path, sizeof(char) * 1024 - 1, "%s/%s", buf, file_name); +#endif + } else { + len = strlen(custom_directory); + if (custom_directory[len-1] != '/') { + snprintf(path, sizeof(char) * 1024 - 1, "%s/%s",custom_directory, file_name); + } else { + snprintf(path, sizeof(char) * 1024 - 1, "%s%s", custom_directory, file_name); + } + } + return path; +} + +char ** GeoIPDBFileName = NULL; + +void _GeoIP_setup_dbfilename() { + if (NULL == GeoIPDBFileName) { + GeoIPDBFileName = malloc(sizeof(char *) * NUM_DB_TYPES); + memset(GeoIPDBFileName, 0, sizeof(char *) * NUM_DB_TYPES); + + GeoIPDBFileName[GEOIP_COUNTRY_EDITION] = _GeoIP_full_path_to("GeoIP.dat"); + GeoIPDBFileName[GEOIP_REGION_EDITION_REV0] = _GeoIP_full_path_to("GeoIPRegion.dat"); + GeoIPDBFileName[GEOIP_REGION_EDITION_REV1] = _GeoIP_full_path_to("GeoIPRegion.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV0] = _GeoIP_full_path_to("GeoIPCity.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV1] = _GeoIP_full_path_to("GeoIPCity.dat"); + GeoIPDBFileName[GEOIP_ISP_EDITION] = _GeoIP_full_path_to("GeoIPISP.dat"); + GeoIPDBFileName[GEOIP_ORG_EDITION] = _GeoIP_full_path_to("GeoIPOrg.dat"); + GeoIPDBFileName[GEOIP_PROXY_EDITION] = _GeoIP_full_path_to("GeoIPProxy.dat"); + GeoIPDBFileName[GEOIP_ASNUM_EDITION] = _GeoIP_full_path_to("GeoIPASNum.dat"); + GeoIPDBFileName[GEOIP_NETSPEED_EDITION] = _GeoIP_full_path_to("GeoIPNetSpeed.dat"); + GeoIPDBFileName[GEOIP_DOMAIN_EDITION] = _GeoIP_full_path_to("GeoIPDomain.dat"); + GeoIPDBFileName[GEOIP_COUNTRY_EDITION_V6] = _GeoIP_full_path_to("GeoIPv6.dat"); + GeoIPDBFileName[GEOIP_LOCATIONA_EDITION] = _GeoIP_full_path_to("GeoIPLocA.dat"); + GeoIPDBFileName[GEOIP_ACCURACYRADIUS_EDITION] = _GeoIP_full_path_to("GeoIPDistance.dat"); + GeoIPDBFileName[GEOIP_CITYCONFIDENCE_EDITION] = _GeoIP_full_path_to("GeoIPCityConfidence.dat"); + GeoIPDBFileName[GEOIP_CITYCONFIDENCEDIST_EDITION] = _GeoIP_full_path_to("GeoIPCityConfidenceDist.dat"); + GeoIPDBFileName[GEOIP_LARGE_COUNTRY_EDITION] = _GeoIP_full_path_to("GeoIP.dat"); + GeoIPDBFileName[GEOIP_LARGE_COUNTRY_EDITION_V6] = _GeoIP_full_path_to("GeoIPv6.dat"); + GeoIPDBFileName[GEOIP_ASNUM_EDITION_V6] = _GeoIP_full_path_to("GeoIPASNumv6.dat"); + GeoIPDBFileName[GEOIP_ISP_EDITION_V6] = _GeoIP_full_path_to("GeoIPISPv6.dat"); + GeoIPDBFileName[GEOIP_ORG_EDITION_V6] = _GeoIP_full_path_to("GeoIPOrgv6.dat"); + GeoIPDBFileName[GEOIP_DOMAIN_EDITION_V6] = _GeoIP_full_path_to("GeoIPDomainv6.dat"); + GeoIPDBFileName[GEOIP_LOCATIONA_EDITION_V6] = _GeoIP_full_path_to("GeoIPLocAv6.dat"); + GeoIPDBFileName[GEOIP_REGISTRAR_EDITION] = _GeoIP_full_path_to("GeoIPRegistrar.dat"); + GeoIPDBFileName[GEOIP_REGISTRAR_EDITION_V6] = _GeoIP_full_path_to("GeoIPRegistrarv6.dat"); + GeoIPDBFileName[GEOIP_USERTYPE_EDITION] = _GeoIP_full_path_to("GeoIPUserType.dat"); + GeoIPDBFileName[GEOIP_USERTYPE_EDITION_V6] = _GeoIP_full_path_to("GeoIPUserTypev6.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV0_V6] = _GeoIP_full_path_to("GeoIPCityv6.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV1_V6] = _GeoIP_full_path_to("GeoIPCityv6.dat"); + GeoIPDBFileName[GEOIP_NETSPEED_EDITION_REV1] = _GeoIP_full_path_to("GeoIPNetspeedCell.dat"); + GeoIPDBFileName[GEOIP_NETSPEED_EDITION_REV1_V6] = _GeoIP_full_path_to("GeoIPNetseedCellv6.dat"); + } +} + +static +int _file_exists(const char *file_name) { + struct stat file_stat; + return( (stat(file_name, &file_stat) == 0) ? 1:0); +} + +char * _GeoIP_iso_8859_1__utf8(const char * iso) { + signed char c; + char k; + char * p; + char * t = (char *)iso; + int len = 0; + while ( ( c = *t++) ){ + if ( c < 0 ) + len++; + } + len += t - iso; + t = p = malloc( len ); + + if ( p ){ + while ( ( c = *iso++ ) ) { + if (c < 0 ) { + k = 0xc2; + if (c >= -64 ) + k++; + *t++ = k; + c &= ~0x40; + } + *t++ = c; + } + *t++ = 0x00; + } + return p; +} + +int GeoIP_is_private_ipnum_v4( unsigned long ipnum ){ +return ((ipnum >= 167772160U && ipnum <= 184549375U) + || (ipnum >= 2851995648U && ipnum <= 2852061183U) + || (ipnum >= 2886729728U && ipnum <= 2887778303U) + || (ipnum >= 3232235520U && ipnum <= 3232301055U) + || (ipnum >= 2130706432U && ipnum <= 2147483647U))? 1 : 0; +} + +int GeoIP_is_private_v4( const char * addr ){ + unsigned long ipnum = GeoIP_addr_to_num(addr); + return GeoIP_is_private_ipnum_v4(ipnum); +} + +int GeoIP_db_avail(int type) { + const char * filePath; + if (type < 0 || type >= NUM_DB_TYPES) { + return 0; + } + _GeoIP_setup_dbfilename(); + filePath = GeoIPDBFileName[type]; + if (NULL == filePath) { + return 0; + } + return _file_exists(filePath); +} + +static +void _setup_segments(GeoIP * gi) { + int i, j, segment_record_length; + unsigned char delim[3]; + unsigned char buf[LARGE_SEGMENT_RECORD_LENGTH]; + ssize_t silence; + int fno = fileno(gi->GeoIPDatabase); + + gi->databaseSegments = NULL; + + /* default to GeoIP Country Edition */ + gi->databaseType = GEOIP_COUNTRY_EDITION; + gi->record_length = STANDARD_RECORD_LENGTH; + lseek(fno, -3l, SEEK_END); + for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) { + silence = read(fno, delim, 3); + if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) { + silence = read(fno, &gi->databaseType, 1 ); + if (gi->databaseType >= 106) { + /* backwards compatibility with databases from April 2003 and earlier */ + gi->databaseType -= 105; + } + + if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { + /* Region Edition, pre June 2003 */ + gi->databaseSegments = malloc(sizeof(int)); + gi->databaseSegments[0] = STATE_BEGIN_REV0; + } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { + /* Region Edition, post June 2003 */ + gi->databaseSegments = malloc(sizeof(int)); + gi->databaseSegments[0] = STATE_BEGIN_REV1; + } else if (gi->databaseType == GEOIP_CITY_EDITION_REV0 || + gi->databaseType == GEOIP_CITY_EDITION_REV1 || + gi->databaseType == GEOIP_ORG_EDITION || + gi->databaseType == GEOIP_ORG_EDITION_V6 || + gi->databaseType == GEOIP_DOMAIN_EDITION || + gi->databaseType == GEOIP_DOMAIN_EDITION_V6 || + gi->databaseType == GEOIP_ISP_EDITION || + gi->databaseType == GEOIP_ISP_EDITION_V6 || + gi->databaseType == GEOIP_REGISTRAR_EDITION || + gi->databaseType == GEOIP_REGISTRAR_EDITION_V6 || + gi->databaseType == GEOIP_USERTYPE_EDITION || + gi->databaseType == GEOIP_USERTYPE_EDITION_V6 || + gi->databaseType == GEOIP_ASNUM_EDITION || + gi->databaseType == GEOIP_ASNUM_EDITION_V6 || + gi->databaseType == GEOIP_NETSPEED_EDITION_REV1 || + gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6 || + gi->databaseType == GEOIP_LOCATIONA_EDITION || + gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION || + gi->databaseType == GEOIP_CITYCONFIDENCE_EDITION || + gi->databaseType == GEOIP_CITYCONFIDENCEDIST_EDITION || + gi->databaseType == GEOIP_CITY_EDITION_REV0_V6 || + gi->databaseType == GEOIP_CITY_EDITION_REV1_V6 + + ) { + /* City/Org Editions have two segments, read offset of second segment */ + gi->databaseSegments = malloc(sizeof(int)); + gi->databaseSegments[0] = 0; + + segment_record_length = gi->databaseType == GEOIP_CITYCONFIDENCEDIST_EDITION ? LARGE_SEGMENT_RECORD_LENGTH : SEGMENT_RECORD_LENGTH; + + silence = read(fno, buf, segment_record_length ); + for (j = 0; j < segment_record_length; j++) { + gi->databaseSegments[0] += (buf[j] << (j * 8)); + } + + /* the record_length must be correct from here on */ + if (gi->databaseType == GEOIP_ORG_EDITION || + gi->databaseType == GEOIP_ORG_EDITION_V6 || + gi->databaseType == GEOIP_DOMAIN_EDITION || + gi->databaseType == GEOIP_DOMAIN_EDITION_V6 || + gi->databaseType == GEOIP_ISP_EDITION || + gi->databaseType == GEOIP_ISP_EDITION_V6 || + gi->databaseType == GEOIP_CITYCONFIDENCEDIST_EDITION + ) + gi->record_length = ORG_RECORD_LENGTH; + + if ( gi->databaseType == GEOIP_CITYCONFIDENCE_EDITION + || gi->databaseType == GEOIP_CITYCONFIDENCEDIST_EDITION + ) { + silence = pread(fileno(gi->GeoIPDatabase), buf, gi->record_length, gi->databaseSegments[0] * 2 * gi->record_length); + gi->dyn_seg_size = 0; + for (j = 0; j < gi->record_length; j++) { + gi->dyn_seg_size += (buf[j] << (j * 8)); + } + } + + } + break; + } else { + lseek(fno, -4l, SEEK_CUR); + } + } + if (gi->databaseType == GEOIP_COUNTRY_EDITION || + gi->databaseType == GEOIP_PROXY_EDITION || + gi->databaseType == GEOIP_NETSPEED_EDITION || + gi->databaseType == GEOIP_COUNTRY_EDITION_V6 ) { + gi->databaseSegments = malloc(sizeof(int)); + gi->databaseSegments[0] = COUNTRY_BEGIN; + } + else if ( gi->databaseType == GEOIP_LARGE_COUNTRY_EDITION || + gi->databaseType == GEOIP_LARGE_COUNTRY_EDITION_V6 ) { + gi->databaseSegments = malloc(sizeof(int)); + gi->databaseSegments[0] = LARGE_COUNTRY_BEGIN; + } + +} + +static +int _check_mtime(GeoIP *gi) { + struct stat buf; + +#if !defined(_WIN32) + struct timeval t; +#else /* !defined(_WIN32) */ + FILETIME ft; + ULONGLONG t; +#endif /* !defined(_WIN32) */ + + if (gi->flags & GEOIP_CHECK_CACHE) { + +#if !defined(_WIN32) + /* stat only has second granularity, so don't + * call it more than once a second */ + gettimeofday(&t, NULL); + if (t.tv_sec == gi->last_mtime_check){ + return 0; + } + gi->last_mtime_check = t.tv_sec; + +#else /* !defined(_WIN32) */ + + /* stat only has second granularity, so don't + call it more than once a second */ + GetSystemTimeAsFileTime(&ft); + t = FILETIME_TO_USEC(ft) / 1000 / 1000; + if (t == gi->last_mtime_check){ + return 0; + } + gi->last_mtime_check = t; + +#endif /* !defined(_WIN32) */ + + if (stat(gi->file_path, &buf) != -1) { + /* make sure that the database file is at least 60 + * seconds untouched. Otherwise we might load the + * database only partly and crash + */ + if (buf.st_mtime != gi->mtime && ( buf.st_mtime + 60 < gi->last_mtime_check ) ) { + /* GeoIP Database file updated */ + if (gi->flags & (GEOIP_MEMORY_CACHE | GEOIP_MMAP_CACHE)) { + if ( gi->flags & GEOIP_MMAP_CACHE) { +#if !defined(_WIN32) + /* MMAP is only avail on UNIX */ + munmap(gi->cache, gi->size); + gi->cache = NULL; +#endif + } else { + /* reload database into memory cache */ + if ((gi->cache = (unsigned char*) realloc(gi->cache, buf.st_size)) == NULL) { + fprintf(stderr,"Out of memory when reloading %s\n",gi->file_path); + return -1; + } + } + } + /* refresh filehandle */ + fclose(gi->GeoIPDatabase); + gi->GeoIPDatabase = fopen(gi->file_path,"rb"); + if (gi->GeoIPDatabase == NULL) { + fprintf(stderr,"Error Opening file %s when reloading\n",gi->file_path); + return -1; + } + gi->mtime = buf.st_mtime; + gi->size = buf.st_size; + + if ( gi->flags & GEOIP_MMAP_CACHE) { +#if defined(_WIN32) + fprintf(stderr, "GEOIP_MMAP_CACHE is not supported on WIN32\n"); + gi->cache = 0; + return -1; +#else + gi->cache = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fileno(gi->GeoIPDatabase), 0); + if ( gi->cache == MAP_FAILED ) { + + fprintf(stderr,"Error remapping file %s when reloading\n",gi->file_path); + + gi->cache = NULL; + return -1; + } +#endif + } else if ( gi->flags & GEOIP_MEMORY_CACHE ) { + if (pread(fileno(gi->GeoIPDatabase), gi->cache, buf.st_size, 0) != (ssize_t) buf.st_size) { + fprintf(stderr,"Error reading file %s when reloading\n",gi->file_path); + return -1; + } + } + + if (gi->databaseSegments != NULL) { + free(gi->databaseSegments); + gi->databaseSegments = NULL; + } + _setup_segments(gi); + if (gi->databaseSegments == NULL) { + fprintf(stderr, "Error reading file %s -- corrupt\n", gi->file_path); + return -1; + } + if (gi->flags & GEOIP_INDEX_CACHE) { + gi->index_cache = (unsigned char *) realloc(gi->index_cache, sizeof(unsigned char) * ((gi->databaseSegments[0] * (long)gi->record_length * 2))); + if (gi->index_cache != NULL) { + if (pread(fileno(gi->GeoIPDatabase), gi->index_cache, + gi->databaseSegments[0] * (long)gi->record_length * 2, 0 ) != (ssize_t) (gi->databaseSegments[0]*(long)gi->record_length * 2)) { + fprintf(stderr,"Error reading file %s where reloading\n",gi->file_path); + return -1; + } + } + } + } + } + } + return 0; +} + +#define ADDR_STR_LEN (8 * 4 + 7 + 1) +unsigned int _GeoIP_seek_record_v6 (GeoIP *gi, geoipv6_t ipnum) { + int depth; + char paddr[ADDR_STR_LEN]; + unsigned int x; + unsigned char stack_buffer[2 * MAX_RECORD_LENGTH]; + const unsigned char *buf = (gi->cache == NULL) ? stack_buffer : NULL; + unsigned int offset = 0; + + const unsigned char * p; + int j; + ssize_t silence; + int fno = fileno(gi->GeoIPDatabase); + _check_mtime(gi); + if ( GeoIP_teredo(gi) ) + __GEOIP_PREPARE_TEREDO(&ipnum); + for (depth = 127; depth >= 0; depth--) { + if (gi->cache == NULL && gi->index_cache == NULL) { + /* read from disk */ + silence = pread(fno, stack_buffer,gi->record_length * 2, (long)gi->record_length * 2 * offset ); + } else if (gi->index_cache == NULL) { + /* simply point to record in memory */ + buf = gi->cache + (long)gi->record_length * 2 *offset; + } else { + buf = gi->index_cache + (long)gi->record_length * 2 * offset; + } + + if (GEOIP_CHKBIT_V6(depth, ipnum.s6_addr )) { + /* Take the right-hand branch */ + if ( gi->record_length == 3 ) { + /* Most common case is completely unrolled and uses constants. */ + x = (buf[3*1 + 0] << (0*8)) + + (buf[3*1 + 1] << (1*8)) + + (buf[3*1 + 2] << (2*8)); + + } else { + /* General case */ + j = gi->record_length; + p = &buf[2*j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while ( --j ); + } + + } else { + /* Take the left-hand branch */ + if ( gi->record_length == 3 ) { + /* Most common case is completely unrolled and uses constants. */ + x = (buf[3*0 + 0] << (0*8)) + + (buf[3*0 + 1] << (1*8)) + + (buf[3*0 + 2] << (2*8)); + } else { + /* General case */ + j = gi->record_length; + p = &buf[1*j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while ( --j ); + } + } + + if (x >= gi->databaseSegments[0]) { + gi->netmask = 128 - depth; + return x; + } + offset = x; + } + + /* shouldn't reach here */ + _GeoIP_inet_ntop(AF_INET6, &ipnum.s6_addr[0], paddr, ADDR_STR_LEN); + fprintf(stderr,"Error Traversing Database for ipnum = %s - Perhaps database is corrupt?\n", paddr); + return 0; +} + +geoipv6_t +_GeoIP_addr_to_num_v6(const char *addr) +{ + geoipv6_t ipnum; + if ( 1 == _GeoIP_inet_pton(AF_INET6, addr, &ipnum.s6_addr[0] ) ) + return ipnum; + return IPV6_NULL; +} + +unsigned int _GeoIP_seek_record (GeoIP *gi, unsigned long ipnum) { + int depth; + unsigned int x; + unsigned char stack_buffer[2 * MAX_RECORD_LENGTH]; + const unsigned char *buf = (gi->cache == NULL) ? stack_buffer : NULL; + unsigned int offset = 0; + ssize_t silence; + + const unsigned char * p; + int j; + int fno = fileno(gi->GeoIPDatabase); + _check_mtime(gi); + for (depth = 31; depth >= 0; depth--) { + if (gi->cache == NULL && gi->index_cache == NULL) { + /* read from disk */ + silence = pread(fno, stack_buffer, gi->record_length * 2, gi->record_length * 2 * offset); + } else if (gi->index_cache == NULL) { + /* simply point to record in memory */ + buf = gi->cache + (long)gi->record_length * 2 *offset; + } else { + buf = gi->index_cache + (long)gi->record_length * 2 * offset; + } + + if (ipnum & (1 << depth)) { + /* Take the right-hand branch */ + if ( gi->record_length == 3 ) { + /* Most common case is completely unrolled and uses constants. */ + x = (buf[3*1 + 0] << (0*8)) + + (buf[3*1 + 1] << (1*8)) + + (buf[3*1 + 2] << (2*8)); + + } else { + /* General case */ + j = gi->record_length; + p = &buf[2*j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while ( --j ); + } + + } else { + /* Take the left-hand branch */ + if ( gi->record_length == 3 ) { + /* Most common case is completely unrolled and uses constants. */ + x = (buf[3*0 + 0] << (0*8)) + + (buf[3*0 + 1] << (1*8)) + + (buf[3*0 + 2] << (2*8)); + } else { + /* General case */ + j = gi->record_length; + p = &buf[1*j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while ( --j ); + } + } + + if (x >= gi->databaseSegments[0]) { + gi->netmask = 32 - depth; + return x; + } + offset = x; + } + /* shouldn't reach here */ + fprintf(stderr,"Error Traversing Database for ipnum = %lu - Perhaps database is corrupt?\n",ipnum); + return 0; +} + +unsigned long +GeoIP_addr_to_num(const char *addr) +{ + unsigned int c, octet, t; + unsigned long ipnum; + int i = 3; + + octet = ipnum = 0; + while ((c = *addr++)) { + if (c == '.') { + if (octet > 255) + return 0; + ipnum <<= 8; + ipnum += octet; + i--; + octet = 0; + } else { + t = octet; + octet <<= 3; + octet += t; + octet += t; + c -= '0'; + if (c > 9) + return 0; + octet += c; + } + } + if ((octet > 255) || (i != 0)) + return 0; + ipnum <<= 8; + return ipnum + octet; +} + +GeoIP* GeoIP_open_type (int type, int flags) { + GeoIP * gi; + const char * filePath; + if (type < 0 || type >= NUM_DB_TYPES) { + printf("Invalid database type %d\n", type); + return NULL; + } + _GeoIP_setup_dbfilename(); + filePath = GeoIPDBFileName[type]; + if (filePath == NULL) { + printf("Invalid database type %d\n", type); + return NULL; + } + gi = GeoIP_open (filePath, flags); + return gi; +} + +GeoIP* GeoIP_new (int flags) { + GeoIP * gi; + _GeoIP_setup_dbfilename(); + gi = GeoIP_open (GeoIPDBFileName[GEOIP_COUNTRY_EDITION], flags); + return gi; +} + +GeoIP* GeoIP_open (const char * filename, int flags) { + struct stat buf; + GeoIP * gi; + size_t len; + + gi = (GeoIP *)malloc(sizeof(GeoIP)); + if (gi == NULL) + return NULL; + len = sizeof(char) * (strlen(filename)+1); + gi->file_path = malloc(len); + if (gi->file_path == NULL) { + free(gi); + return NULL; + } + strncpy(gi->file_path, filename, len); + gi->GeoIPDatabase = fopen(filename,"rb"); + if (gi->GeoIPDatabase == NULL) { + fprintf(stderr,"Error Opening file %s\n",filename); + free(gi->file_path); + free(gi); + return NULL; + } else { + if (flags & (GEOIP_MEMORY_CACHE | GEOIP_MMAP_CACHE) ) { + if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) { + fprintf(stderr,"Error stating file %s\n",filename); + free(gi->file_path); + free(gi); + return NULL; + } + gi->mtime = buf.st_mtime; + gi->size = buf.st_size; + + /* MMAP added my Peter Shipley */ + if ( flags & GEOIP_MMAP_CACHE ) { +#if !defined(_WIN32) + gi->cache = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fileno(gi->GeoIPDatabase), 0); + if ( gi->cache == MAP_FAILED ) { + fprintf(stderr,"Error mmaping file %s\n",filename); + free(gi->file_path); + free(gi); + return NULL; + } +#endif + } else { + gi->cache = (unsigned char *) malloc(sizeof(unsigned char) * buf.st_size); + + if (gi->cache != NULL) { + if (pread(fileno(gi->GeoIPDatabase),gi->cache, buf.st_size, 0) != (ssize_t) buf.st_size) { + fprintf(stderr,"Error reading file %s\n",filename); + free(gi->cache); + free(gi->file_path); + free(gi); + return NULL; + } + } + } + } else { + if (flags & GEOIP_CHECK_CACHE) { + if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) { + fprintf(stderr,"Error stating file %s\n",filename); + free(gi->file_path); + free(gi); + return NULL; + } + gi->mtime = buf.st_mtime; + } + gi->cache = NULL; + } + gi->flags = flags; + gi->charset = GEOIP_CHARSET_ISO_8859_1; + gi->ext_flags = 1U << GEOIP_TEREDO_BIT; + _setup_segments(gi); + if (flags & GEOIP_INDEX_CACHE) { + gi->index_cache = (unsigned char *) malloc(sizeof(unsigned char) * ((gi->databaseSegments[0] * (long)gi->record_length * 2))); + if (gi->index_cache != NULL) { + if (pread(fileno(gi->GeoIPDatabase),gi->index_cache, gi->databaseSegments[0] * (long)gi->record_length * 2, 0) != (size_t) (gi->databaseSegments[0]*(long)gi->record_length * 2)) { + fprintf(stderr,"Error reading file %s\n",filename); + free(gi->databaseSegments); + free(gi->index_cache); + free(gi); + return NULL; + } + } + } else { + gi->index_cache = NULL; + } + return gi; + } +} + +void GeoIP_delete (GeoIP *gi) { + if (gi == NULL ) + return; + if (gi->GeoIPDatabase != NULL) + fclose(gi->GeoIPDatabase); + if (gi->cache != NULL) { + if ( gi->flags & GEOIP_MMAP_CACHE ) { +#if !defined(_WIN32) + munmap(gi->cache, gi->size); +#endif + } else { + free(gi->cache); + } + gi->cache = NULL; + } + if (gi->index_cache != NULL) + free(gi->index_cache); + if (gi->file_path != NULL) + free(gi->file_path); + if (gi->databaseSegments != NULL) + free(gi->databaseSegments); + free(gi); +} + +const char *GeoIP_country_code_by_name_v6 (GeoIP* gi, const char *name) { + int country_id; + country_id = GeoIP_id_by_name_v6(gi, name); + return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; +} + +const char *GeoIP_country_code_by_name (GeoIP* gi, const char *name) { + int country_id; + country_id = GeoIP_id_by_name(gi, name); + return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; +} + +const char *GeoIP_country_code3_by_name_v6 (GeoIP* gi, const char *name) { + int country_id; + country_id = GeoIP_id_by_name_v6(gi, name); + return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; +} + +const char *GeoIP_country_code3_by_name (GeoIP* gi, const char *name) { + int country_id; + country_id = GeoIP_id_by_name(gi, name); + return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; +} + +const char *GeoIP_country_name_by_name_v6 (GeoIP* gi, const char *name) { + int country_id; + country_id = GeoIP_id_by_name_v6(gi, name); + return GeoIP_country_name_by_id(gi, country_id ); +} + +const char *GeoIP_country_name_by_name (GeoIP* gi, const char *name) { + int country_id; + country_id = GeoIP_id_by_name(gi, name); + return GeoIP_country_name_by_id(gi, country_id ); +} + +unsigned long _GeoIP_lookupaddress (const char *host) { + unsigned long addr = inet_addr(host); + struct hostent phe2; + struct hostent * phe = &phe2; + char *buf = NULL; +#ifdef HAVE_GETHOSTBYNAME_R + int buflength = 16384; + int herr = 0; +#endif + int result = 0; +#ifdef HAVE_GETHOSTBYNAME_R + buf = malloc(buflength); +#endif + if (addr == INADDR_NONE) { +#ifdef HAVE_GETHOSTBYNAME_R + while (1) { + /* we use gethostbyname_r here because it is thread-safe and gethostbyname is not */ +#ifdef GETHOSTBYNAME_R_RETURNS_INT + result = gethostbyname_r(host,&phe2,buf,buflength,&phe,&herr); +#else + phe = gethostbyname_r(host,&phe2,buf,buflength,&herr); +#endif + if (herr != ERANGE) + break; + if (result == 0) + break; + /* double the buffer if the buffer is too small */ + buflength = buflength * 2; + buf = realloc(buf,buflength); + } +#else + /* Some systems do not support gethostbyname_r, such as Mac OS X */ + phe = gethostbyname(host); +#endif + if (!phe || result != 0) { + free(buf); + return 0; + } +#if !defined(_WIN32) + addr = *((in_addr_t *) phe->h_addr_list[0]); +#else + addr = ((IN_ADDR *) phe->h_addr_list[0])->S_un.S_addr; +#endif + } +#ifdef HAVE_GETHOSTBYNAME_R + free(buf); +#endif + return ntohl(addr); +} + +geoipv6_t +_GeoIP_lookupaddress_v6(const char *host) +{ + geoipv6_t ipnum; + int gaierr; + struct addrinfo hints, *aifirst; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + /* hints.ai_flags = AI_V4MAPPED; */ + hints.ai_socktype = SOCK_STREAM; + + if ((gaierr = getaddrinfo(host, NULL, &hints, &aifirst)) != 0) { + /* fprintf(stderr, "Err: %s (%d %s)\n", host, gaierr, gai_strerror(gaierr)); */ + return IPV6_NULL; + } + memcpy(ipnum.s6_addr, ((struct sockaddr_in6 *) aifirst->ai_addr)->sin6_addr.s6_addr, sizeof(geoipv6_t)); + freeaddrinfo(aifirst); + /* inet_pton(AF_INET6, host, ipnum.s6_addr); */ + + return ipnum; +} + +int GeoIP_id_by_name (GeoIP* gi, const char *name) { + unsigned long ipnum; + int ret; + if (name == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION && gi->databaseType != GEOIP_COUNTRY_EDITION && gi->databaseType != GEOIP_PROXY_EDITION && gi->databaseType != GEOIP_NETSPEED_EDITION) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_COUNTRY_EDITION]); + return 0; + } + if (!(ipnum = _GeoIP_lookupaddress(name))) + return 0; + ret = _GeoIP_seek_record(gi, ipnum) - gi->databaseSegments[0]; + return ret; + +} + +int GeoIP_id_by_name_v6 (GeoIP* gi, const char *name) { + geoipv6_t ipnum; + int ret; + if (name == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION_V6 && gi->databaseType != GEOIP_COUNTRY_EDITION_V6) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_COUNTRY_EDITION_V6]); + return 0; + } + ipnum = _GeoIP_lookupaddress_v6(name); + if (__GEOIP_V6_IS_NULL(ipnum)) + return 0; + + ret = _GeoIP_seek_record_v6(gi, ipnum) - gi->databaseSegments[0]; + return ret; +} + +const char *GeoIP_country_code_by_addr_v6 (GeoIP* gi, const char *addr) { + int country_id; + country_id = GeoIP_id_by_addr_v6(gi, addr); + return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; +} + +const char *GeoIP_country_code_by_addr (GeoIP* gi, const char *addr) { + int country_id; + country_id = GeoIP_id_by_addr(gi, addr); + return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; +} + +const char *GeoIP_country_code3_by_addr_v6 (GeoIP* gi, const char *addr) { + int country_id; + country_id = GeoIP_id_by_addr_v6(gi, addr); + return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; +} + +const char *GeoIP_country_code3_by_addr (GeoIP* gi, const char *addr) { + int country_id; + country_id = GeoIP_id_by_addr(gi, addr); + return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; +} + +const char *GeoIP_country_name_by_addr_v6 (GeoIP* gi, const char *addr) { + int country_id; + country_id = GeoIP_id_by_addr_v6(gi, addr); + return GeoIP_country_name_by_id(gi, country_id ); +} + +const char *GeoIP_country_name_by_addr (GeoIP* gi, const char *addr) { + int country_id; + country_id = GeoIP_id_by_addr(gi, addr); + return GeoIP_country_name_by_id(gi, country_id ); +} + +const char *GeoIP_country_name_by_ipnum (GeoIP* gi, unsigned long ipnum) { + int country_id; + country_id = GeoIP_id_by_ipnum(gi, ipnum); + return GeoIP_country_name_by_id(gi, country_id ); +} + +const char *GeoIP_country_name_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum) { + int country_id; + country_id = GeoIP_id_by_ipnum_v6(gi, ipnum); + return GeoIP_country_name_by_id(gi, country_id ); +} + +const char *GeoIP_country_code_by_ipnum (GeoIP* gi, unsigned long ipnum) { + int country_id; + country_id = GeoIP_id_by_ipnum(gi, ipnum); + return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; +} + +const char *GeoIP_country_code_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum) { + int country_id; + country_id = GeoIP_id_by_ipnum_v6(gi, ipnum); + return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; +} + +const char *GeoIP_country_code3_by_ipnum (GeoIP* gi, unsigned long ipnum) { + int country_id; + country_id = GeoIP_id_by_ipnum(gi, ipnum); + return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; +} + +const char *GeoIP_country_code3_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum) { + int country_id; + country_id = GeoIP_id_by_ipnum_v6(gi, ipnum); + return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; +} + +int GeoIP_country_id_by_addr_v6 (GeoIP* gi, const char *addr) { + return GeoIP_id_by_addr_v6(gi, addr); +} + +int GeoIP_country_id_by_addr (GeoIP* gi, const char *addr) { + return GeoIP_id_by_addr(gi, addr); +} + +int GeoIP_country_id_by_name_v6 (GeoIP* gi, const char *host) { + return GeoIP_id_by_name_v6(gi, host); +} + +int GeoIP_country_id_by_name (GeoIP* gi, const char *host) { + return GeoIP_id_by_name(gi, host); +} + +int GeoIP_id_by_addr_v6 (GeoIP* gi, const char *addr) { + geoipv6_t ipnum; + int ret; + if (addr == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_COUNTRY_EDITION_V6 + && gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION_V6) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_COUNTRY_EDITION_V6]); + return 0; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + ret = _GeoIP_seek_record_v6(gi, ipnum) - gi->databaseSegments[0]; + return ret; +} + +int GeoIP_id_by_addr (GeoIP* gi, const char *addr) { + unsigned long ipnum; + int ret; + if (addr == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_COUNTRY_EDITION && + gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION && + gi->databaseType != GEOIP_PROXY_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_COUNTRY_EDITION]); + return 0; + } + ipnum = GeoIP_addr_to_num(addr); + ret = _GeoIP_seek_record(gi, ipnum) - gi->databaseSegments[0]; + return ret; +} + +int GeoIP_id_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum) { + int ret; +/* if (ipnum == 0) { + return 0; + } +*/ + if (gi->databaseType != GEOIP_COUNTRY_EDITION_V6 + && gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION_V6) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_COUNTRY_EDITION_V6]); + return 0; + } + ret = _GeoIP_seek_record_v6(gi, ipnum) - gi->databaseSegments[0]; + return ret; +} + + + +int GeoIP_id_by_ipnum (GeoIP* gi, unsigned long ipnum) { + int ret; + if (ipnum == 0) { + return 0; + } + if (gi->databaseType != GEOIP_COUNTRY_EDITION && + gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION && + gi->databaseType != GEOIP_PROXY_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_COUNTRY_EDITION]); + return 0; + } + ret = _GeoIP_seek_record(gi, ipnum) - gi->databaseSegments[0]; + return ret; +} + +char *GeoIP_database_info (GeoIP* gi) { + int i; + unsigned char buf[3]; + char *retval; + int hasStructureInfo = 0; + ssize_t silence; + int fno = fileno(gi->GeoIPDatabase); + + if(gi == NULL) + return NULL; + + _check_mtime(gi); + lseek(fno, -3l, SEEK_END); + + /* first get past the database structure information */ + for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) { + silence = read(fno, buf, 3 ); + if (buf[0] == 255 && buf[1] == 255 && buf[2] == 255) { + hasStructureInfo = 1; + break; + } + lseek(fno, -4l, SEEK_CUR); + } + if (hasStructureInfo == 1) { + lseek(fno, -6l, SEEK_CUR); + } else { + /* no structure info, must be pre Sep 2002 database, go back to end */ + lseek(fno, -3l, SEEK_END); + } + + for (i = 0; i < DATABASE_INFO_MAX_SIZE; i++) { + silence = read(fno, buf, 3 ); + if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0) { + retval = malloc(sizeof(char) * (i+1)); + if (retval == NULL) { + return NULL; + } + silence = read(fno, retval, i); + retval[i] = '\0'; + return retval; + } + lseek(fno, -4l, SEEK_CUR); + } + return NULL; +} + +/* GeoIP Region Edition functions */ + +void GeoIP_assign_region_by_inetaddr(GeoIP* gi, unsigned long inetaddr, GeoIPRegion *region) { + unsigned int seek_region; + + /* This also writes in the terminating NULs (if you decide to + * keep them) and clear any fields that are not set. */ + memset(region, 0, sizeof(GeoIPRegion)); + + seek_region = _GeoIP_seek_record(gi, ntohl(inetaddr)); + + if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { + /* Region Edition, pre June 2003 */ + seek_region -= STATE_BEGIN_REV0; + if (seek_region >= 1000) { + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char) ((seek_region - 1000)/26 + 65); + region->region[1] = (char) ((seek_region - 1000)%26 + 65); + } else { + memcpy(region->country_code, GeoIP_country_code[seek_region], 2); + } + } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { + /* Region Edition, post June 2003 */ + seek_region -= STATE_BEGIN_REV1; + if (seek_region < US_OFFSET) { + /* Unknown */ + /* we don't need to do anything here b/c we memset region to 0 */ + } else if (seek_region < CANADA_OFFSET) { + /* USA State */ + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char) ((seek_region - US_OFFSET)/26 + 65); + region->region[1] = (char) ((seek_region - US_OFFSET)%26 + 65); + } else if (seek_region < WORLD_OFFSET) { + /* Canada Province */ + region->country_code[0] = 'C'; + region->country_code[1] = 'A'; + region->region[0] = (char) ((seek_region - CANADA_OFFSET)/26 + 65); + region->region[1] = (char) ((seek_region - CANADA_OFFSET)%26 + 65); + } else { + /* Not US or Canada */ + memcpy(region->country_code, GeoIP_country_code[(seek_region - WORLD_OFFSET) / FIPS_RANGE], 2); + } + } +} + +void GeoIP_assign_region_by_inetaddr_v6(GeoIP* gi, geoipv6_t inetaddr, GeoIPRegion *region) { + unsigned int seek_region; + + /* This also writes in the terminating NULs (if you decide to + * keep them) and clear any fields that are not set. */ + memset(region, 0, sizeof(GeoIPRegion)); + + seek_region = _GeoIP_seek_record_v6(gi, inetaddr); + + if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { + /* Region Edition, pre June 2003 */ + seek_region -= STATE_BEGIN_REV0; + if (seek_region >= 1000) { + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char) ((seek_region - 1000)/26 + 65); + region->region[1] = (char) ((seek_region - 1000)%26 + 65); + } else { + memcpy(region->country_code, GeoIP_country_code[seek_region], 2); + } + } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { + /* Region Edition, post June 2003 */ + seek_region -= STATE_BEGIN_REV1; + if (seek_region < US_OFFSET) { + /* Unknown */ + /* we don't need to do anything here b/c we memset region to 0 */ + } else if (seek_region < CANADA_OFFSET) { + /* USA State */ + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char) ((seek_region - US_OFFSET)/26 + 65); + region->region[1] = (char) ((seek_region - US_OFFSET)%26 + 65); + } else if (seek_region < WORLD_OFFSET) { + /* Canada Province */ + region->country_code[0] = 'C'; + region->country_code[1] = 'A'; + region->region[0] = (char) ((seek_region - CANADA_OFFSET)/26 + 65); + region->region[1] = (char) ((seek_region - CANADA_OFFSET)%26 + 65); + } else { + /* Not US or Canada */ + memcpy(region->country_code, GeoIP_country_code[(seek_region - WORLD_OFFSET) / FIPS_RANGE], 2); + } + } +} + +static +GeoIPRegion * _get_region(GeoIP* gi, unsigned long ipnum) { + GeoIPRegion * region; + + region = malloc(sizeof(GeoIPRegion)); + if (region) { + GeoIP_assign_region_by_inetaddr(gi, htonl(ipnum), region); + } + return region; +} + +static +GeoIPRegion * _get_region_v6(GeoIP* gi, geoipv6_t ipnum) { + GeoIPRegion * region; + + region = malloc(sizeof(GeoIPRegion)); + if (region) { + GeoIP_assign_region_by_inetaddr_v6(gi, ipnum, region); + } + return region; +} + +GeoIPRegion * GeoIP_region_by_addr (GeoIP* gi, const char *addr) { + unsigned long ipnum; + if (addr == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_REGION_EDITION_REV1]); + return 0; + } + ipnum = GeoIP_addr_to_num(addr); + return _get_region(gi, ipnum); +} + +GeoIPRegion * GeoIP_region_by_addr_v6 (GeoIP* gi, const char *addr) { + geoipv6_t ipnum; + if (addr == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_REGION_EDITION_REV1]); + return 0; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + return _get_region_v6(gi, ipnum); +} + +GeoIPRegion * GeoIP_region_by_name (GeoIP* gi, const char *name) { + unsigned long ipnum; + if (name == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_REGION_EDITION_REV1]); + return 0; + } + if (!(ipnum = _GeoIP_lookupaddress(name))) + return 0; + return _get_region(gi, ipnum); +} + +GeoIPRegion * GeoIP_region_by_name_v6 (GeoIP* gi, const char *name) { + geoipv6_t ipnum; + if (name == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_REGION_EDITION_REV1]); + return 0; + } + + ipnum = _GeoIP_lookupaddress_v6(name); + if (__GEOIP_V6_IS_NULL(ipnum)) + return 0; + return _get_region_v6(gi, ipnum); +} + +GeoIPRegion * GeoIP_region_by_ipnum (GeoIP* gi, unsigned long ipnum) { + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_REGION_EDITION_REV1]); + return 0; + } + return _get_region(gi, ipnum); +} + +GeoIPRegion * GeoIP_region_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum) { + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_REGION_EDITION_REV1]); + return 0; + } + return _get_region_v6(gi, ipnum); +} + +void GeoIPRegion_delete (GeoIPRegion *gir) { + free(gir); +} + +/* GeoIP Organization, ISP and AS Number Edition private method */ +static +char *_get_name (GeoIP* gi, unsigned long ipnum) { + int seek_org; + char buf[MAX_ORG_RECORD_LENGTH]; + char * org_buf, * buf_pointer; + int record_pointer; + size_t len; + ssize_t silence; + + if (gi->databaseType != GEOIP_ORG_EDITION && + gi->databaseType != GEOIP_ISP_EDITION && + gi->databaseType != GEOIP_DOMAIN_EDITION && + gi->databaseType != GEOIP_ASNUM_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION_REV1 && + gi->databaseType != GEOIP_USERTYPE_EDITION && + gi->databaseType != GEOIP_REGISTRAR_EDITION && + gi->databaseType != GEOIP_LOCATIONA_EDITION + ) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_ORG_EDITION]); + return NULL; + } + + seek_org = _GeoIP_seek_record(gi, ipnum); + if (seek_org == gi->databaseSegments[0]) + return NULL; + + record_pointer = seek_org + (2 * gi->record_length - 1) * gi->databaseSegments[0]; + + if (gi->cache == NULL) { + silence = pread(fileno(gi->GeoIPDatabase), buf, MAX_ORG_RECORD_LENGTH, record_pointer); + if ( gi->charset == GEOIP_CHARSET_UTF8 ) { + org_buf = _GeoIP_iso_8859_1__utf8( (const char * ) buf ); + } else { + len = sizeof(char) * (strlen(buf)+1); + org_buf = malloc(len); + strncpy(org_buf, buf, len); + } + } else { + buf_pointer = (char *)(gi->cache + (long)record_pointer); + if ( gi->charset == GEOIP_CHARSET_UTF8 ) { + org_buf = _GeoIP_iso_8859_1__utf8( (const char * ) buf_pointer ); + } else { + len = sizeof(char) * (strlen(buf_pointer)+1); + org_buf = malloc(len); + strncpy(org_buf, buf_pointer, len); + } + } + return org_buf; +} + +char *_get_name_v6 (GeoIP* gi, geoipv6_t ipnum) { + int seek_org; + char buf[MAX_ORG_RECORD_LENGTH]; + char * org_buf, * buf_pointer; + int record_pointer; + size_t len; + ssize_t silence; + + if ( + gi->databaseType != GEOIP_ORG_EDITION_V6 && + gi->databaseType != GEOIP_ISP_EDITION_V6 && + gi->databaseType != GEOIP_DOMAIN_EDITION_V6 && + gi->databaseType != GEOIP_ASNUM_EDITION_V6 && + gi->databaseType != GEOIP_NETSPEED_EDITION_REV1_V6 && + gi->databaseType != GEOIP_USERTYPE_EDITION_V6 && + gi->databaseType != GEOIP_REGISTRAR_EDITION_V6 && + gi->databaseType != GEOIP_LOCATIONA_EDITION + ) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_ORG_EDITION]); + return NULL; + } + + seek_org = _GeoIP_seek_record_v6(gi, ipnum); + if (seek_org == gi->databaseSegments[0]) + return NULL; + + record_pointer = seek_org + (2 * gi->record_length - 1) * gi->databaseSegments[0]; + + if (gi->cache == NULL) { + silence = pread(fileno(gi->GeoIPDatabase), buf, MAX_ORG_RECORD_LENGTH, record_pointer); + if ( gi->charset == GEOIP_CHARSET_UTF8 ) { + org_buf = _GeoIP_iso_8859_1__utf8( (const char * ) buf ); + } else { + len = sizeof(char) * (strlen(buf)+1); + org_buf = malloc(len); + strncpy(org_buf, buf, len); + } + } else { + buf_pointer = (char *)(gi->cache + (long)record_pointer); + if ( gi->charset == GEOIP_CHARSET_UTF8 ) { + org_buf = _GeoIP_iso_8859_1__utf8( (const char * ) buf_pointer ); + } else { + len = sizeof(char) * (strlen(buf_pointer)+1); + org_buf = malloc(len); + strncpy(org_buf, buf_pointer, len); + } + } + return org_buf; +} + +char * GeoIP_num_to_addr (unsigned long ipnum) { + char *ret_str; + char *cur_str; + int octet[4]; + int num_chars_written, i; + + ret_str = malloc(sizeof(char) * 16); + cur_str = ret_str; + + for (i = 0; i<4; i++) { + octet[3 - i] = ipnum % 256; + ipnum >>= 8; + } + + for (i = 0; i<4; i++) { + num_chars_written = sprintf(cur_str, "%d", octet[i]); + cur_str += num_chars_written; + + if (i < 3) { + cur_str[0] = '.'; + cur_str++; + } + } + + return ret_str; +} + +char **GeoIP_range_by_ip (GeoIP* gi, const char *addr) { + unsigned long ipnum; + unsigned long left_seek; + unsigned long right_seek; + unsigned long mask; + int orig_netmask; + int target_value; + char **ret; + + if (addr == NULL) { + return 0; + } + + ret = malloc(sizeof(char *) * 2); + + ipnum = GeoIP_addr_to_num(addr); + target_value = _GeoIP_seek_record(gi, ipnum); + orig_netmask = GeoIP_last_netmask(gi); + mask = 0xffffffff << ( 32 - orig_netmask ); + left_seek = ipnum & mask; + right_seek = left_seek + ( 0xffffffff & ~mask ); + + while (left_seek != 0 + && target_value == _GeoIP_seek_record(gi, left_seek - 1) ) { + + /* Go to beginning of netblock defined by netmask */ + mask = 0xffffffff << ( 32 - GeoIP_last_netmask(gi) ); + left_seek = ( left_seek - 1 ) & mask; + } + ret[0] = GeoIP_num_to_addr(left_seek); + + while (right_seek != 0xffffffff + && target_value == _GeoIP_seek_record(gi, right_seek + 1) ) { + + /* Go to end of netblock defined by netmask */ + mask = 0xffffffff << ( 32 - GeoIP_last_netmask(gi) ); + right_seek = ( right_seek + 1 ) & mask; + right_seek += 0xffffffff & ~mask; + } + ret[1] = GeoIP_num_to_addr(right_seek); + + gi->netmask = orig_netmask; + + return ret; +} + +void GeoIP_range_by_ip_delete( char ** ptr ){ + if ( ptr ){ + if ( ptr[0] ) + free(ptr[0]); + if ( ptr[1] ) + free(ptr[1]); + free(ptr); + } +} + +char *GeoIP_name_by_ipnum (GeoIP* gi, unsigned long ipnum) { + return _get_name(gi,ipnum); +} + +char *GeoIP_name_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum) { + return _get_name_v6(gi,ipnum); +} + +char *GeoIP_name_by_addr (GeoIP* gi, const char *addr) { + unsigned long ipnum; + if (addr == NULL) { + return 0; + } + ipnum = GeoIP_addr_to_num(addr); + return _get_name(gi, ipnum); +} + +char *GeoIP_name_by_addr_v6 (GeoIP* gi, const char *addr) { + geoipv6_t ipnum; + if (addr == NULL) { + return 0; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + return _get_name_v6(gi, ipnum); +} + +char *GeoIP_name_by_name (GeoIP* gi, const char *name) { + unsigned long ipnum; + if (name == NULL) { + return 0; + } + if (!(ipnum = _GeoIP_lookupaddress(name))) + return 0; + return _get_name(gi, ipnum); +} + +char *GeoIP_name_by_name_v6 (GeoIP* gi, const char *name) { + geoipv6_t ipnum; + if (name == NULL) { + return 0; + } + ipnum = _GeoIP_lookupaddress_v6(name); + if (__GEOIP_V6_IS_NULL(ipnum)) + return 0; + return _get_name_v6(gi, ipnum); +} + +char *GeoIP_org_by_ipnum (GeoIP* gi, unsigned long ipnum) { + return GeoIP_name_by_ipnum(gi, ipnum); +} + +char *GeoIP_org_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum) { + return GeoIP_name_by_ipnum_v6(gi, ipnum); +} + +char *GeoIP_org_by_addr (GeoIP* gi, const char *addr) { + return GeoIP_name_by_addr(gi, addr); +} + +char *GeoIP_org_by_addr_v6 (GeoIP* gi, const char *addr) { + return GeoIP_name_by_addr_v6(gi, addr); +} + +char *GeoIP_org_by_name (GeoIP* gi, const char *name) { + return GeoIP_name_by_name(gi, name); +} + +char *GeoIP_org_by_name_v6 (GeoIP* gi, const char *name) { + return GeoIP_name_by_name_v6(gi, name); +} + +unsigned char GeoIP_database_edition (GeoIP* gi) { + return gi->databaseType; +} + +int GeoIP_enable_teredo(GeoIP* gi, int true_false){ + unsigned int mask = ( 1U << GEOIP_TEREDO_BIT ); + int b = ( gi->ext_flags & mask ) ? 1 : 0; + gi->ext_flags &= ~mask ; + if ( true_false ) + gi->ext_flags |= true_false; + return b; +} + +int GeoIP_teredo ( GeoIP* gi ){ + unsigned int mask = ( 1U << GEOIP_TEREDO_BIT ); + return ( gi->ext_flags & mask ) ? 1 : 0; +} + +int GeoIP_charset( GeoIP* gi){ + return gi->charset; +} + +int GeoIP_set_charset( GeoIP* gi, int charset ){ + int old_charset = gi->charset; + gi->charset = charset; + return old_charset; +} + +int GeoIP_last_netmask (GeoIP* gi) { + return gi->netmask; +} + + +/** return two letter country code */ +const char* GeoIP_code_by_id(int id) +{ + if (id < 0 || id >= (int) num_GeoIP_countries) + return NULL; + + return GeoIP_country_code[id]; +} + +/** return three letter country code */ +const char* GeoIP_code3_by_id(int id) +{ + if (id < 0 || id >= (int) num_GeoIP_countries) + return NULL; + + return GeoIP_country_code3[id]; +} + + +/** return full name of country in utf8 or iso-8859-1 */ +const char* GeoIP_country_name_by_id(GeoIP * gi, int id) +{ + /* return NULL also even for index 0 for backward compatibility */ + if (id <= 0 || id >= (int) num_GeoIP_countries) + return NULL; + return ((gi->charset == GEOIP_CHARSET_UTF8) + ? GeoIP_utf8_country_name[id] + : GeoIP_country_name[id]); +} + +/** return full name of country in iso-8859-1 */ +const char* GeoIP_name_by_id(int id) +{ + if (id < 0 || id >= (int) num_GeoIP_countries) + return NULL; + + return GeoIP_country_name[id]; +} + +/** return continent of country */ +const char* GeoIP_continent_by_id(int id) +{ + if (id < 0 || id >= (int) num_GeoIP_countries) + return NULL; + + return GeoIP_country_continent[id]; +} + +/** return id by country code **/ +int GeoIP_id_by_code(const char *country) +{ + unsigned i; + + for ( i = 0; i < num_GeoIP_countries; ++i) + { + if (strcmp(country, GeoIP_country_code[i]) == 0) + return i; + } + + return 0; +} + +unsigned GeoIP_num_countries(void) +{ + return num_GeoIP_countries; +} + +const char * GeoIP_lib_version(void) +{ + return PACKAGE_VERSION; +} + +int GeoIP_cleanup(void) +{ + int i, result = 0; + if (GeoIPDBFileName) { + + for (i = 0; i < NUM_DB_TYPES; i++) { + if (GeoIPDBFileName[i]) free(GeoIPDBFileName[i]); + } + + free(GeoIPDBFileName); + GeoIPDBFileName = NULL; + result = 1; + } + + return result; +} + diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIP.h b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIP.h new file mode 100644 index 00000000..dcb90e1a --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIP.h @@ -0,0 +1,307 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIP.h + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef GEOIP_H +#define GEOIP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#if !defined(_WIN32) +#include +#include +#include +#else /* !defined(_WIN32) */ +#include +#include +//#include +#include +#define snprintf _snprintf +#define FILETIME_TO_USEC(ft) (((unsigned __int64) ft.dwHighDateTime << 32 | ft.dwLowDateTime) / 10) +#endif /* !defined(_WIN32) */ + +#include +#include +#include +#include /* for fstat */ +#include /* for fstat */ + +#define SEGMENT_RECORD_LENGTH 3 +#define LARGE_SEGMENT_RECORD_LENGTH 4 +#define STANDARD_RECORD_LENGTH 3 +#define ORG_RECORD_LENGTH 4 +#define MAX_RECORD_LENGTH 4 +#define NUM_DB_TYPES (33+1) + +/* 128 bit address in network order */ +typedef struct in6_addr geoipv6_t; + +#define GEOIP_CHKBIT_V6(bit,ptr) (ptr[((127UL - bit) >> 3)] & (1UL << (~(127 - bit) & 7))) + +typedef struct GeoIPTag { + FILE *GeoIPDatabase; + char *file_path; + unsigned char *cache; + unsigned char *index_cache; + unsigned int *databaseSegments; + char databaseType; + time_t mtime; + int flags; + off_t size; + char record_length; + int charset; /* 0 iso-8859-1 1 utf8 */ + int record_iter; /* used in GeoIP_next_record */ + int netmask; /* netmask of last lookup - set using depth in _GeoIP_seek_record */ + time_t last_mtime_check; + off_t dyn_seg_size; /* currently only used by the cityconfidence database */ + unsigned int ext_flags; /* bit 0 teredo support enabled */ +} GeoIP; + + +typedef enum { + GEOIP_TEREDO_BIT = 0 +} GeoIPExtFlags; + +typedef enum { + GEOIP_CHARSET_ISO_8859_1 = 0, + GEOIP_CHARSET_UTF8 = 1 +} GeoIPCharset; + +typedef struct GeoIPRegionTag { + char country_code[3]; + char region[3]; +} GeoIPRegion; + +typedef enum { + GEOIP_STANDARD = 0, + GEOIP_MEMORY_CACHE = 1, + GEOIP_CHECK_CACHE = 2, + GEOIP_INDEX_CACHE = 4, + GEOIP_MMAP_CACHE = 8, +} GeoIPOptions; + +typedef enum { + GEOIP_COUNTRY_EDITION = 1, + GEOIP_REGION_EDITION_REV0 = 7, + GEOIP_CITY_EDITION_REV0 = 6, + GEOIP_ORG_EDITION = 5, + GEOIP_ISP_EDITION = 4, + GEOIP_CITY_EDITION_REV1 = 2, + GEOIP_REGION_EDITION_REV1 = 3, + GEOIP_PROXY_EDITION = 8, + GEOIP_ASNUM_EDITION = 9, + GEOIP_NETSPEED_EDITION = 10, + GEOIP_DOMAIN_EDITION = 11, + GEOIP_COUNTRY_EDITION_V6 = 12, + GEOIP_LOCATIONA_EDITION = 13, + GEOIP_ACCURACYRADIUS_EDITION = 14, + GEOIP_CITYCONFIDENCE_EDITION = 15, + GEOIP_CITYCONFIDENCEDIST_EDITION = 16, + GEOIP_LARGE_COUNTRY_EDITION = 17, + GEOIP_LARGE_COUNTRY_EDITION_V6 = 18, + GEOIP_CITYCONFIDENCEDIST_ISP_ORG_EDITION = 19, /* unsued, but gaps are not allowed */ + GEOIP_CCM_COUNTRY_EDITION =20, /* unsued, but gaps are not allowed */ + GEOIP_ASNUM_EDITION_V6 = 21, + GEOIP_ISP_EDITION_V6 = 22, + GEOIP_ORG_EDITION_V6 = 23, + GEOIP_DOMAIN_EDITION_V6 = 24, + GEOIP_LOCATIONA_EDITION_V6 = 25, + GEOIP_REGISTRAR_EDITION = 26, + GEOIP_REGISTRAR_EDITION_V6 = 27, + GEOIP_USERTYPE_EDITION = 28, + GEOIP_USERTYPE_EDITION_V6 = 29, + GEOIP_CITY_EDITION_REV1_V6 = 30, + GEOIP_CITY_EDITION_REV0_V6 = 31, + GEOIP_NETSPEED_EDITION_REV1 = 32, + GEOIP_NETSPEED_EDITION_REV1_V6 = 33 +} GeoIPDBTypes; + +typedef enum { + GEOIP_ANON_PROXY = 1, + GEOIP_HTTP_X_FORWARDED_FOR_PROXY = 2, + GEOIP_HTTP_CLIENT_IP_PROXY = 3, +} GeoIPProxyTypes; + +typedef enum { + GEOIP_UNKNOWN_SPEED = 0, + GEOIP_DIALUP_SPEED = 1, + GEOIP_CABLEDSL_SPEED = 2, + GEOIP_CORPORATE_SPEED = 3, +} GeoIPNetspeedValues; + +extern char **GeoIPDBFileName; +extern const char * GeoIPDBDescription[NUM_DB_TYPES]; +extern const char *GeoIPCountryDBFileName; +extern const char *GeoIPRegionDBFileName; +extern const char *GeoIPCityDBFileName; +extern const char *GeoIPOrgDBFileName; +extern const char *GeoIPISPDBFileName; +extern const char *GeoIPLocationADBFileName; +extern const char *GeoIPAccuracyRadiusFileName; +extern const char *GeoIPCityConfidenceFileName; + +/* Warning: do not use those arrays as doing so may break your + * program with newer GeoIP versions */ +extern const char GeoIP_country_code[254][3]; +extern const char GeoIP_country_code3[254][4]; +extern const char * GeoIP_country_name[254]; +extern const char * GeoIP_utf8_country_name[254]; +extern const char GeoIP_country_continent[254][3]; + +#ifdef DLL +#define GEOIP_API __declspec(dllexport) +#else +#define GEOIP_API +#endif /* DLL */ + +GEOIP_API void GeoIP_setup_custom_directory(char *dir); +GEOIP_API GeoIP* GeoIP_open_type (int type, int flags); +GEOIP_API GeoIP* GeoIP_new(int flags); +GEOIP_API GeoIP* GeoIP_open(const char * filename, int flags); +GEOIP_API int GeoIP_db_avail(int type); +GEOIP_API void GeoIP_delete(GeoIP* gi); +GEOIP_API const char *GeoIP_country_code_by_addr (GeoIP* gi, const char *addr); +GEOIP_API const char *GeoIP_country_code_by_name (GeoIP* gi, const char *host); +GEOIP_API const char *GeoIP_country_code3_by_addr (GeoIP* gi, const char *addr); +GEOIP_API const char *GeoIP_country_code3_by_name (GeoIP* gi, const char *host); +GEOIP_API const char *GeoIP_country_name_by_addr (GeoIP* gi, const char *addr); +GEOIP_API const char *GeoIP_country_name_by_name (GeoIP* gi, const char *host); +GEOIP_API const char *GeoIP_country_name_by_ipnum (GeoIP* gi, unsigned long ipnum); +GEOIP_API const char *GeoIP_country_code_by_ipnum (GeoIP* gi, unsigned long ipnum); +GEOIP_API const char *GeoIP_country_code3_by_ipnum (GeoIP* gi, unsigned long ipnum); + +/* */ +GEOIP_API const char *GeoIP_country_name_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); +GEOIP_API const char *GeoIP_country_code_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); +GEOIP_API const char *GeoIP_country_code3_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + +GEOIP_API const char *GeoIP_country_code_by_addr_v6 (GeoIP* gi, const char *addr); +GEOIP_API const char *GeoIP_country_code_by_name_v6 (GeoIP* gi, const char *host); +GEOIP_API const char *GeoIP_country_code3_by_addr_v6 (GeoIP* gi, const char *addr); +GEOIP_API const char *GeoIP_country_code3_by_name_v6 (GeoIP* gi, const char *host); +GEOIP_API const char *GeoIP_country_name_by_addr_v6 (GeoIP* gi, const char *addr); +GEOIP_API const char *GeoIP_country_name_by_name_v6 (GeoIP* gi, const char *host); + +/* Deprecated - for backwards compatibility only */ +GEOIP_API int GeoIP_country_id_by_addr (GeoIP* gi, const char *addr); +GEOIP_API int GeoIP_country_id_by_name (GeoIP* gi, const char *host); +GEOIP_API char *GeoIP_org_by_addr (GeoIP* gi, const char *addr); +GEOIP_API char *GeoIP_org_by_name (GeoIP* gi, const char *host); +GEOIP_API char *GeoIP_org_by_ipnum (GeoIP* gi, unsigned long ipnum); + +GEOIP_API char *GeoIP_org_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); +GEOIP_API char *GeoIP_org_by_addr_v6 (GeoIP* gi, const char *addr); +GEOIP_API char *GeoIP_org_by_name_v6 (GeoIP* gi, const char *name); + +/* End deprecated */ + +GEOIP_API int GeoIP_id_by_addr (GeoIP* gi, const char *addr); +GEOIP_API int GeoIP_id_by_name (GeoIP* gi, const char *host); +GEOIP_API int GeoIP_id_by_ipnum (GeoIP* gi, unsigned long ipnum); + +GEOIP_API int GeoIP_id_by_addr_v6 (GeoIP* gi, const char *addr); +GEOIP_API int GeoIP_id_by_name_v6 (GeoIP* gi, const char *host); +GEOIP_API int GeoIP_id_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + +GEOIP_API GeoIPRegion * GeoIP_region_by_addr (GeoIP* gi, const char *addr); +GEOIP_API GeoIPRegion * GeoIP_region_by_name (GeoIP* gi, const char *host); +GEOIP_API GeoIPRegion * GeoIP_region_by_ipnum (GeoIP *gi, unsigned long ipnum); + +GEOIP_API GeoIPRegion * GeoIP_region_by_addr_v6 (GeoIP* gi, const char *addr); +GEOIP_API GeoIPRegion * GeoIP_region_by_name_v6 (GeoIP* gi, const char *host); +GEOIP_API GeoIPRegion * GeoIP_region_by_ipnum_v6 (GeoIP *gi, geoipv6_t ipnum); + +/* Warning - don't call this after GeoIP_assign_region_by_inetaddr calls */ +GEOIP_API void GeoIPRegion_delete (GeoIPRegion *gir); + +GEOIP_API void GeoIP_assign_region_by_inetaddr(GeoIP* gi, unsigned long inetaddr, GeoIPRegion *gir); + +GEOIP_API void GeoIP_assign_region_by_inetaddr_v6(GeoIP* gi, geoipv6_t inetaddr, GeoIPRegion *gir); + +/* Used to query GeoIP Organization, ISP and AS Number databases */ +GEOIP_API char *GeoIP_name_by_ipnum (GeoIP* gi, unsigned long ipnum); +GEOIP_API char *GeoIP_name_by_addr (GeoIP* gi, const char *addr); +GEOIP_API char *GeoIP_name_by_name (GeoIP* gi, const char *host); + +GEOIP_API char *GeoIP_name_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); +GEOIP_API char *GeoIP_name_by_addr_v6 (GeoIP* gi, const char *addr); +GEOIP_API char *GeoIP_name_by_name_v6 (GeoIP* gi, const char *name); + +/** return two letter country code */ +GEOIP_API const char* GeoIP_code_by_id(int id); + +/** return three letter country code */ +GEOIP_API const char* GeoIP_code3_by_id(int id); + +/** return full name of country in utf8 or iso-8859-1 */ +GEOIP_API const char* GeoIP_country_name_by_id(GeoIP* gi, int id); + +/** return full name of country */ +GEOIP_API const char* GeoIP_name_by_id(int id); + +/** return continent of country */ +GEOIP_API const char* GeoIP_continent_by_id(int id); + +/** return id by country code **/ +GEOIP_API int GeoIP_id_by_code(const char *country); + +/** return return number of known countries */ +GEOIP_API unsigned GeoIP_num_countries(void); + +GEOIP_API char *GeoIP_database_info (GeoIP* gi); +GEOIP_API unsigned char GeoIP_database_edition (GeoIP* gi); + +GEOIP_API int GeoIP_charset (GeoIP* gi); +GEOIP_API int GeoIP_set_charset (GeoIP* gi, int charset); +GEOIP_API int GeoIP_enable_teredo (GeoIP* gi, int true_false ); +GEOIP_API int GeoIP_teredo (GeoIP* gi ); + +GEOIP_API int GeoIP_last_netmask (GeoIP* gi); +GEOIP_API char **GeoIP_range_by_ip (GeoIP* gi, const char *addr); +GEOIP_API void GeoIP_range_by_ip_delete(char **ptr); + +/* Convert region code to region name */ +GEOIP_API const char * GeoIP_region_name_by_code(const char *country_code, const char *region_code); + +/* Get timezone from country and region code */ +GEOIP_API const char * GeoIP_time_zone_by_country_and_region(const char *country_code, const char *region_code); + +/* some v4 helper functions as of 1.4.7 exported to the public API */ +GEOIP_API unsigned long GeoIP_addr_to_num(const char *addr); +GEOIP_API char * GeoIP_num_to_addr(unsigned long ipnum); + +/* Internal function -- convert iso to utf8; return a malloced utf8 string. */ +char * _GeoIP_iso_8859_1__utf8(const char * iso); + +/* Cleans up memory used to hold file name paths. Returns 1 if successful; otherwise 0. + * */ +GEOIP_API int GeoIP_cleanup(void); + +/* Returns the library version in use. Helpful if your loading dynamically. */ +GEOIP_API const char * GeoIP_lib_version(void); + +# +#ifdef __cplusplus +} +#endif + +#endif /* GEOIP_H */ diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIPCity.c b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIPCity.c new file mode 100644 index 00000000..79dff6b0 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIPCity.c @@ -0,0 +1,394 @@ + +/* + * GeoIPCity.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#if !defined(_WIN32) +#include +#include +#include /* For ntohl */ +#else +#include +#include +#endif +#include /* For uint32_t */ +#ifdef HAVE_STDINT_H +#include /* For uint32_t */ +#endif + +static +const int FULL_RECORD_LENGTH = 50; + +#define CITYCONFIDENCE_FIXED_RECORD 4 +#define CITYCONFIDENCEDIST_FIXED_RECORD 6 + + +static +GeoIPRecord * +_extract_record(GeoIP * gi, unsigned int seek_record, int *next_record_ptr) +{ + int record_pointer; + unsigned char *record_buf = NULL; + unsigned char *begin_record_buf = NULL; + GeoIPRecord *record; + int str_length = 0; + int j; + double latitude = 0, longitude = 0; + int metroarea_combo = 0; + int bytes_read = 0; + int t = 0; + if (seek_record == gi->databaseSegments[0]) + return NULL; + + record = malloc(sizeof(GeoIPRecord)); + memset(record, 0, sizeof(GeoIPRecord)); + record->charset = gi->charset; + + if (gi->databaseType == GEOIP_CITYCONFIDENCE_EDITION + || gi->databaseType == GEOIP_CITYCONFIDENCEDIST_EDITION) { + + int fixed_rec_size = gi->record_length + + ((gi->databaseType == GEOIP_CITYCONFIDENCE_EDITION) + ? CITYCONFIDENCE_FIXED_RECORD + : CITYCONFIDENCEDIST_FIXED_RECORD); + + //allocate max rec size, even for CITYCONFIDENCE_FIXED_RECORD + //+4 is the max_record_length + unsigned char tmp_fixed_record[CITYCONFIDENCEDIST_FIXED_RECORD + 4]; + int dseg = gi->databaseSegments[0] * gi->record_length * 2 + gi->record_length; +// int aligned_dseg = dseg ; + + int offset = seek_record - gi->databaseSegments[0] - 1; /* -1 b/c zero is not + * found. but the array + * start with 0 */ + record_pointer = offset * fixed_rec_size + dseg + gi->dyn_seg_size; + if (gi->cache == NULL) { + + /* read from disk */ + bytes_read = pread(fileno(gi->GeoIPDatabase), tmp_fixed_record, fixed_rec_size, record_pointer); + + if (bytes_read != fixed_rec_size) + return NULL; + + record->country_conf = tmp_fixed_record[0]; + record->region_conf = tmp_fixed_record[1]; + record->city_conf = tmp_fixed_record[2]; + record->postal_conf = tmp_fixed_record[3]; + + t = fixed_rec_size - gi->record_length; + + record->accuracy_radius = + gi->databaseType == GEOIP_CITYCONFIDENCEDIST_EDITION + ? ((tmp_fixed_record[4] + (tmp_fixed_record[5] << 8)) & 0x3ff) : 0x3ff; + + + record_pointer = dseg + tmp_fixed_record[t] + + (tmp_fixed_record[t + 1] << 8) + (tmp_fixed_record[t + 2] << 16) ; + + if (gi->record_length == 4) + record_pointer += (tmp_fixed_record[t + 3] << 24); + + begin_record_buf = record_buf = malloc(sizeof(char) * FULL_RECORD_LENGTH); + + bytes_read = pread(fileno(gi->GeoIPDatabase), record_buf, FULL_RECORD_LENGTH, record_pointer); + + if (bytes_read == 0) { + /* eof or other error */ + free(begin_record_buf); + free(record); + return NULL; + } + + } + else { + record_buf = gi->cache + (long) record_pointer; + + record->country_conf = record_buf[0]; + record->region_conf = record_buf[1]; + record->city_conf = record_buf[2]; + record->postal_conf = record_buf[3]; + + record->accuracy_radius = + gi->databaseType == GEOIP_CITYCONFIDENCEDIST_EDITION + ? ((record_buf[4] + (record_buf[5] << 8)) & 0x3ff) : 0x3ff; + + t = fixed_rec_size - gi->record_length; + + record_pointer = dseg + record_buf[t] + + (record_buf[t + 1] << 8) + (record_buf[t + 2] << 16) ; + + if (gi->record_length == 4) + record_pointer += (record_buf[t + 3] << 24); + + record_buf = gi->cache + (long) record_pointer; + } + + } /* other city records */ + else { + + record->country_conf = GEOIP_UNKNOWN_CONF; + record->region_conf = GEOIP_UNKNOWN_CONF; + record->city_conf = GEOIP_UNKNOWN_CONF; + record->postal_conf = GEOIP_UNKNOWN_CONF; + record->accuracy_radius = GEOIP_UNKNOWN_ACCURACY_RADIUS; + + record_pointer = seek_record + (2 * gi->record_length - 1) * gi->databaseSegments[0]; + + if (gi->cache == NULL) { + begin_record_buf = record_buf = malloc(sizeof(char) * FULL_RECORD_LENGTH); + bytes_read = pread(fileno(gi->GeoIPDatabase), record_buf, FULL_RECORD_LENGTH, record_pointer); + if (bytes_read == 0) { + /* eof or other error */ + free(begin_record_buf); + free(record); + return NULL; + } + } + else { + record_buf = gi->cache + (long) record_pointer; + } + } + + /* get country */ + record->continent_code = (char *) GeoIP_country_continent[record_buf[0]]; + record->country_code = (char *) GeoIP_country_code[record_buf[0]]; + record->country_code3 = (char *) GeoIP_country_code3[record_buf[0]]; + record->country_name = (char *) GeoIP_country_name_by_id(gi, record_buf[0]); + record_buf++; + + /* get region */ + while (record_buf[str_length] != '\0') + str_length++; + if (str_length > 0) { + record->region = malloc(str_length + 1); + strncpy(record->region, (char *) record_buf, str_length + 1); + } + record_buf += str_length + 1; + str_length = 0; + + /* get city */ + while (record_buf[str_length] != '\0') + str_length++; + if (str_length > 0) { + if (gi->charset == GEOIP_CHARSET_UTF8) { + record->city = _GeoIP_iso_8859_1__utf8((const char *) record_buf); + } + else { + record->city = malloc(str_length + 1); + strncpy(record->city, (const char *) record_buf, str_length + 1); + } + } + record_buf += (str_length + 1); + str_length = 0; + + /* get postal code */ + while (record_buf[str_length] != '\0') + str_length++; + if (str_length > 0) { + record->postal_code = malloc(str_length + 1); + strncpy(record->postal_code, (char *) record_buf, str_length + 1); + } + record_buf += (str_length + 1); + + /* get latitude */ + for (j = 0; j < 3; ++j) + latitude += (record_buf[j] << (j * 8)); + record->latitude = latitude / 10000 - 180; + record_buf += 3; + + /* get longitude */ + for (j = 0; j < 3; ++j) + longitude += (record_buf[j] << (j * 8)); + record->longitude = longitude / 10000 - 180; + + /* + * get area code and metro code for post April 2002 databases and for US + * locations + */ + if (GEOIP_CITY_EDITION_REV1 == gi->databaseType + || GEOIP_CITYCONFIDENCE_EDITION == gi->databaseType) { + if (!strcmp(record->country_code, "US")) { + record_buf += 3; + for (j = 0; j < 3; ++j) + metroarea_combo += (record_buf[j] << (j * 8)); + record->metro_code = metroarea_combo / 1000; + record->area_code = metroarea_combo % 1000; + } + } + + if (gi->cache == NULL) + free(begin_record_buf); + + /* Used for GeoIP_next_record */ + if (next_record_ptr != NULL) + *next_record_ptr = seek_record + record_buf - begin_record_buf + 3; + + return record; +} + +static +GeoIPRecord * +_get_record(GeoIP * gi, unsigned long ipnum) +{ + unsigned int seek_record; + if (gi->databaseType != GEOIP_CITY_EDITION_REV0 + && gi->databaseType != GEOIP_CITY_EDITION_REV1 + && gi->databaseType != GEOIP_CITYCONFIDENCE_EDITION + && gi->databaseType != GEOIP_CITYCONFIDENCEDIST_EDITION) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int) gi->databaseType], GeoIPDBDescription[GEOIP_CITY_EDITION_REV1]); + return 0; + } + + seek_record = _GeoIP_seek_record(gi, ipnum); + return _extract_record(gi, seek_record, NULL); +} + +static +GeoIPRecord * +_get_record_v6(GeoIP * gi, geoipv6_t ipnum) +{ + unsigned int seek_record; + if (gi->databaseType != GEOIP_CITY_EDITION_REV0_V6 && + gi->databaseType != GEOIP_CITY_EDITION_REV1_V6) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int) gi->databaseType], GeoIPDBDescription[GEOIP_CITY_EDITION_REV1_V6]); + return 0; + } + + seek_record = _GeoIP_seek_record_v6(gi, ipnum); + return _extract_record(gi, seek_record, NULL); +} + + + +GeoIPRecord * +GeoIP_record_by_ipnum(GeoIP * gi, unsigned long ipnum) +{ + return _get_record(gi, ipnum); +} + +GeoIPRecord * +GeoIP_record_by_ipnum_v6(GeoIP * gi, geoipv6_t ipnum) +{ + return _get_record_v6(gi, ipnum); +} + +GeoIPRecord * +GeoIP_record_by_addr(GeoIP * gi, const char *addr) +{ + unsigned long ipnum; + if (addr == NULL) { + return 0; + } + ipnum = GeoIP_addr_to_num(addr); + return _get_record(gi, ipnum); +} + +GeoIPRecord * +GeoIP_record_by_addr_v6(GeoIP * gi, const char *addr) +{ + geoipv6_t ipnum; + if (addr == NULL) { + return 0; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + return _get_record_v6(gi, ipnum); +} + +GeoIPRecord * +GeoIP_record_by_name(GeoIP * gi, const char *name) +{ + unsigned long ipnum; + if (name == NULL) { + return 0; + } + ipnum = _GeoIP_lookupaddress(name); + return _get_record(gi, ipnum); +} + +GeoIPRecord * +GeoIP_record_by_name_v6(GeoIP * gi, const char *name) +{ + geoipv6_t ipnum; + if (name == NULL) { + return 0; + } + ipnum = _GeoIP_lookupaddress_v6(name); + return _get_record_v6(gi, ipnum); +} + +int +GeoIP_record_id_by_addr(GeoIP * gi, const char *addr) +{ + unsigned long ipnum; + if (gi->databaseType != GEOIP_CITY_EDITION_REV0 && + gi->databaseType != GEOIP_CITY_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int) gi->databaseType], GeoIPDBDescription[GEOIP_CITY_EDITION_REV1]); + return 0; + } + if (addr == NULL) { + return 0; + } + ipnum = GeoIP_addr_to_num(addr); + return _GeoIP_seek_record(gi, ipnum); +} + +int +GeoIP_record_id_by_addr_v6(GeoIP * gi, const char *addr) +{ + geoipv6_t ipnum; + if (gi->databaseType != GEOIP_CITY_EDITION_REV0_V6 && + gi->databaseType != GEOIP_CITY_EDITION_REV1_V6) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int) gi->databaseType], GeoIPDBDescription[GEOIP_CITY_EDITION_REV1]); + return 0; + } + if (addr == NULL) { + return 0; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + return _GeoIP_seek_record_v6(gi, ipnum); +} + +int +GeoIP_init_record_iter(GeoIP * gi) +{ + return gi->databaseSegments[0] + 1; +} + +int +GeoIP_next_record(GeoIP * gi, GeoIPRecord ** gir, int *record_iter) +{ + if (gi->cache != NULL) { + printf("GeoIP_next_record not supported in memory cache mode\n"); + return 1; + } + *gir = _extract_record(gi, *record_iter, record_iter); + return 0; +} + +void +GeoIPRecord_delete(GeoIPRecord * gir) +{ + free(gir->region); + free(gir->city); + free(gir->postal_code); + free(gir); +} diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIPCity.h b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIPCity.h new file mode 100644 index 00000000..a7828d66 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIPCity.h @@ -0,0 +1,79 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIPCity.h + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef GEOIPCITY_H +#define GEOIPCITY_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GEOIP_UNKNOWN_CONF ( 0x7f ) +#define GEOIP_UNKNOWN_ACCURACY_RADIUS ( 0x3ff ) + +typedef struct GeoIPRecordTag { + char *country_code; + char *country_code3; + char *country_name; + char *region; + char *city; + char *postal_code; + float latitude; + float longitude; + union { + int metro_code; /* metro_code is a alias for dma_code */ + int dma_code; + }; + int area_code; + int charset; + char *continent_code; + /* confidence factor for Country/Region/City/Postal */ + unsigned char country_conf, region_conf, city_conf, postal_conf; + int accuracy_radius; +} GeoIPRecord; + + +GEOIP_API GeoIPRecord * GeoIP_record_by_ipnum (GeoIP* gi, unsigned long ipnum); +GEOIP_API GeoIPRecord * GeoIP_record_by_addr (GeoIP* gi, const char *addr); +GEOIP_API GeoIPRecord * GeoIP_record_by_name (GeoIP* gi, const char *host); + +GEOIP_API GeoIPRecord * GeoIP_record_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); +GEOIP_API GeoIPRecord * GeoIP_record_by_addr_v6 (GeoIP* gi, const char *addr); +GEOIP_API GeoIPRecord * GeoIP_record_by_name_v6 (GeoIP* gi, const char *host); + +GEOIP_API int GeoIP_record_id_by_addr (GeoIP* gi, const char *addr); +GEOIP_API int GeoIP_record_id_by_addr_v6 (GeoIP* gi, const char *addr); + +GEOIP_API int GeoIP_init_record_iter (GeoIP* gi); +/* returns 0 on success, 1 on failure */ +GEOIP_API int GeoIP_next_record (GeoIP* gi, GeoIPRecord **gir, int *record_iter); + +GEOIP_API void GeoIPRecord_delete (GeoIPRecord *gir); + +/* NULL on failure otherwise a malloced string in utf8 */ +/* char * GeoIP_iso_8859_1__utf8(const char *); */ + +#ifdef __cplusplus +} +#endif + +#endif /* GEOIPCITY_H */ diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIPUpdate.c b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIPUpdate.c new file mode 100644 index 00000000..c125d2d9 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIPUpdate.c @@ -0,0 +1,974 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIPUpdate.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIPCity.h" +#include "GeoIP.h" +#include "GeoIPUpdate.h" +#include "GeoIP_internal.h" + +#include "global.h" +#include "md5.h" +#include +#if !defined(_WIN32) +#include +#include +#include +#include +#else +#include +#include +#endif +#include +#include +#include +#include + + +#define BLOCK_SIZE 1024 + +/* Update DB Host & HTTP GET Request formats: + * ------------------------------------------ + * GET must support an optional HTTP Proxy. + */ +const char *GeoIPUpdateHost = "updates.maxmind.com"; +/* This is the direct, or proxy port number. */ +static int GeoIPHTTPPort = 80; +/* License-only format (OLD) */ +const char *GeoIPHTTPRequest = "GET %s%s/app/update?license_key=%s&md5=%s HTTP/1.0\nHost: updates.maxmind.com\n\n"; +/* General DB Types formats */ +const char *GeoIPHTTPRequestFilename = "GET %s%s/app/update_getfilename?product_id=%s HTTP/1.0\nHost: %s\n\n"; +const char *GeoIPHTTPRequestClientIP = "GET %s%s/app/update_getipaddr HTTP/1.0\nHost: %s\n\n"; +const char *GeoIPHTTPRequestMD5 = "GET %s%s/app/update_secure?db_md5=%s&challenge_md5=%s&user_id=%s&edition_id=%s HTTP/1.0\nHost: updates.maxmind.com\n\n"; + +/* messages */ +const char *NoCurrentDB = "%s can't be opened, proceeding to download database\n"; +const char *MD5Info = "MD5 Digest of installed database is %s\n"; +const char *SavingGzip = "Saving gzip file to %s ... "; +const char *WritingFile = "Writing uncompressed data to %s ..."; + +const char * GeoIP_get_error_message(int i) { + switch (i) { + case GEOIP_NO_NEW_UPDATES: + return "no new updates"; + case GEOIP_SUCCESS: + return "Success"; + case GEOIP_LICENSE_KEY_INVALID_ERR: + return "License Key Invalid"; + case GEOIP_DNS_ERR: + return "Unable to resolve hostname"; + case GEOIP_NON_IPV4_ERR: + return "Non - IPv4 address"; + case GEOIP_SOCKET_OPEN_ERR: + return "Error opening socket"; + case GEOIP_CONNECTION_ERR: + return "Unable to connect"; + case GEOIP_GZIP_IO_ERR: + return "Unable to write GeoIP.dat.gz file"; + case GEOIP_TEST_IO_ERR: + return "Unable to write GeoIP.dat.test file"; + case GEOIP_GZIP_READ_ERR: + return "Unable to read gzip data"; + case GEOIP_OUT_OF_MEMORY_ERR: + return "Out of memory error"; + case GEOIP_SOCKET_READ_ERR: + return "Error reading from socket, see errno"; + case GEOIP_SANITY_OPEN_ERR: + return "Sanity check GeoIP_open error"; + case GEOIP_SANITY_INFO_FAIL: + return "Sanity check database_info string failed"; + case GEOIP_SANITY_LOOKUP_FAIL: + return "Sanity check ip address lookup failed"; + case GEOIP_RENAME_ERR: + return "Rename error while installing db, check errno"; + case GEOIP_USER_ID_INVALID_ERR: + return "Invalid userID"; + case GEOIP_PRODUCT_ID_INVALID_ERR: + return "Invalid product ID or subscription expired"; + case GEOIP_INVALID_SERVER_RESPONSE: + return "Server returned something unexpected"; + default: + return "no error"; + } +} +int GeoIP_fprintf(int (*f)(FILE *, char *),FILE *fp, const char *str, ...) { + va_list ap; + int rc; + char * f_str; + int silence; + + if ( f == NULL ) + return 0; + va_start(ap, str); +#if defined(HAVE_VASPRINTF) + silence = vasprintf(&f_str, str, ap); +#elif defined (HAVE_VSNPRINTF) + f_str = malloc(4096); + if ( f_str ) + silence = vsnprintf(f_str, 4096, str, ap); +#else + f_str = malloc(4096); + if ( f_str ) + silence = vsprintf(f_str, str, ap); +#endif + va_end(ap); + if ( f_str == NULL ) + return -1; + rc = (*f)(fp, f_str); + free(f_str); + return(rc); +} + +void GeoIP_printf(void (*f)(char *), const char *str,...) { + va_list params; + char * f_str; + int silence; + if (f == NULL) + return; + va_start(params, str); +#if defined(HAVE_VASPRINTF) + silence = vasprintf(&f_str, str, params); +#elif defined (HAVE_VSNPRINTF) + f_str = malloc(4096); + if ( f_str ) + silence = vsnprintf(f_str, 4096, str, params); +#else + f_str = malloc(4096); + if ( f_str ) + silence = vsprintf(f_str, str, params); +#endif + va_end(params); + if ( f_str == NULL ) + return; + (*f)(f_str); + free(f_str); +} + +/* Support HTTP Proxy Host + * -------------------------------------------------- + * Use typical OS support for the optional HTTP Proxy. + * + * Proxy adds http://{real-hostname} to URI format strings: + * sprintf("GET %s%s/ HTTP/1.0\r\n",GeoIPProxyHTTP,GeoIPProxiedHost, ...); + */ + +/* The Protocol is usually "" OR "http://" with a proxy. */ +static char *GeoIPProxyHTTP = ""; +/* GeoIP Hostname where proxy forwards requests. */ +static char *GeoIPProxiedHost = ""; + +/* Read http_proxy env. variable & parse it. + * ----------------------------------------- + * Allow only these formats: + * "http://server.com", "http://server.com:8080" + * OR + * "server.com", "server.com:8080" + * + * A "user:password@" part will break this. + */ +short int parse_http_proxy(char **proxy_host, int *port) { + char * http_proxy; + char * port_value; + + if ((http_proxy = getenv("http_proxy"))) { + + if (! strncmp("http://", http_proxy, 7)) http_proxy += 7; + + *proxy_host = strdup(http_proxy); + if ( *proxy_host == NULL ) + return 0; /* let the other functions deal with the memory error */ + + if ((port_value = strchr(*proxy_host, ':'))) { + *port_value++ = '\0'; + *port = atoi(port_value); + } + else { + *port = 80; + } + return(1); + } + else { + return(0); + } +} + +/* Get the GeoIP host or the current HTTP Proxy host. */ +struct hostent *GeoIP_get_host_or_proxy (void) { + char * hostname = (char *) GeoIPUpdateHost; + char * proxy_host; + int proxy_port; + + /* Set Proxy from OS: Unix/Linux */ + if (parse_http_proxy(&proxy_host,&proxy_port)) { + hostname = proxy_host; + GeoIPProxyHTTP = "http://"; + GeoIPProxiedHost = (char *) GeoIPUpdateHost; + GeoIPHTTPPort = proxy_port; + } + + /* Resolve DNS host entry. */ + return(gethostbyname(hostname)); +} + +short int GeoIP_update_database (char * license_key, int verbose, void (*f)( char * )) { + struct hostent *hostlist; + int sock; + char * buf; + struct sockaddr_in sa; + int offset = 0, err; + char * request_uri; + char * compr; + unsigned long comprLen; + FILE *comp_fh, *cur_db_fh, *gi_fh; + gzFile gz_fh; + char * file_path_gz, * file_path_test; + MD5_CONTEXT context; + unsigned char buffer[1024], digest[16]; + char hex_digest[33] = "00000000000000000000000000000000\0"; + unsigned int i; + GeoIP * gi; + char * db_info; + char block[BLOCK_SIZE]; + int block_size = BLOCK_SIZE; + size_t len; + size_t written; + _GeoIP_setup_dbfilename(); + + /* get MD5 of current GeoIP database file */ + if ((cur_db_fh = fopen (GeoIPDBFileName[GEOIP_COUNTRY_EDITION], "rb")) == NULL) { + GeoIP_printf(f,"%s%s", NoCurrentDB, GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); + } else { + md5_init(&context); + while ((len = fread (buffer, 1, 1024, cur_db_fh)) > 0) + md5_write (&context, buffer, len); + md5_final (&context); + memcpy(digest,context.buf,16); + fclose (cur_db_fh); + for (i = 0; i < 16; i++) { + // "%02x" will write 3 chars + snprintf (&hex_digest[2*i], 3, "%02x", digest[i]); + } + GeoIP_printf(f, MD5Info, hex_digest); + } + + hostlist = GeoIP_get_host_or_proxy(); + + if (hostlist == NULL) + return GEOIP_DNS_ERR; + + if (hostlist->h_addrtype != AF_INET) + return GEOIP_NON_IPV4_ERR; + + if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + return GEOIP_SOCKET_OPEN_ERR; + } + + memset(&sa, 0, sizeof(struct sockaddr_in)); + sa.sin_port = htons(GeoIPHTTPPort); + memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length); + sa.sin_family = AF_INET; + + if (verbose == 1){ + GeoIP_printf(f,"Connecting to MaxMind GeoIP Update server\n"); + GeoIP_printf(f, "via Host or Proxy Server: %s:%d\n", hostlist->h_name, GeoIPHTTPPort); + } + + /* Download gzip file */ + if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0) + return GEOIP_CONNECTION_ERR; + + request_uri = malloc(sizeof(char) * (strlen(license_key) + strlen(GeoIPHTTPRequest) + + strlen(GeoIPProxyHTTP) + strlen(GeoIPProxiedHost) + 36 + 1)); + if (request_uri == NULL) + return GEOIP_OUT_OF_MEMORY_ERR; + sprintf(request_uri,GeoIPHTTPRequest,GeoIPProxyHTTP,GeoIPProxiedHost,license_key, hex_digest); + send(sock, request_uri, strlen(request_uri),0); + free(request_uri); + + buf = malloc(sizeof(char) * block_size + 1); + if (buf == NULL) + return GEOIP_OUT_OF_MEMORY_ERR; + + if (verbose == 1) + GeoIP_printf(f,"Downloading gzipped GeoIP Database...\n"); + + for (;;) { + int amt; + amt = recv(sock, &buf[offset], block_size,0); + if (amt == 0) { + break; + } else if (amt == -1) { + free(buf); + return GEOIP_SOCKET_READ_ERR; + } + offset += amt; + buf = realloc(buf, offset+block_size + 1); + if (buf == NULL) + return GEOIP_OUT_OF_MEMORY_ERR; + } + + buf[offset]=0; + compr = strstr(buf, "\r\n\r\n"); + if ( compr == NULL ) { + free(buf); + return GEOIP_INVALID_SERVER_RESPONSE; + } + /* skip searchstr "\r\n\r\n" */ + compr += 4; + comprLen = offset + buf - compr; + + if (strstr(compr, "License Key Invalid") != NULL) { + if (verbose == 1) + GeoIP_printf(f,"Failed\n"); + free(buf); + return GEOIP_LICENSE_KEY_INVALID_ERR; + } else if (strstr(compr, "Invalid product ID or subscription expired") != NULL){ + free(buf); + return GEOIP_PRODUCT_ID_INVALID_ERR; + } else if (strstr(compr, "No new updates available") != NULL) { + free(buf); + return GEOIP_NO_NEW_UPDATES; + } + + if (verbose == 1) + GeoIP_printf(f,"Done\n"); + + /* save gzip file */ + file_path_gz = malloc(sizeof(char) * (strlen(GeoIPDBFileName[GEOIP_COUNTRY_EDITION]) + 4)); + if (file_path_gz == NULL) + return GEOIP_OUT_OF_MEMORY_ERR; + strcpy(file_path_gz,GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); + strcat(file_path_gz,".gz"); + if (verbose == 1) { + GeoIP_printf(f, SavingGzip, file_path_gz); + } + comp_fh = fopen(file_path_gz, "wb"); + + if(comp_fh == NULL) { + free(file_path_gz); + free(buf); + return GEOIP_GZIP_IO_ERR; + } + + written = fwrite(compr, 1, comprLen, comp_fh); + fclose(comp_fh); + free(buf); + + if ( written != comprLen ) + return GEOIP_GZIP_IO_ERR; + + if (verbose == 1) + GeoIP_printf(f,"Done\n"); + + if (verbose == 1) + GeoIP_printf(f,"Uncompressing gzip file ... "); + + /* uncompress gzip file */ + gz_fh = gzopen(file_path_gz, "rb"); + file_path_test = malloc(sizeof(char) * (strlen(GeoIPDBFileName[GEOIP_COUNTRY_EDITION]) + 6)); + if (file_path_test == NULL) + return GEOIP_OUT_OF_MEMORY_ERR; + strcpy(file_path_test,GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); + strcat(file_path_test,".test"); + gi_fh = fopen(file_path_test, "wb"); + + if(gi_fh == NULL) { + free(file_path_test); + return GEOIP_TEST_IO_ERR; + } + for (;;) { + int amt; + amt = gzread(gz_fh, block, block_size); + if (amt == -1) { + free(file_path_test); + fclose(gi_fh); + gzclose(gz_fh); + return GEOIP_GZIP_READ_ERR; + } + if (amt == 0) { + break; + } + if ( fwrite(block,1,amt,gi_fh) != amt ){ + free(file_path_test); + fclose(gi_fh); + gzclose(gz_fh); + return GEOIP_GZIP_READ_ERR; + } + } + gzclose(gz_fh); + unlink(file_path_gz); + free(file_path_gz); + fclose(gi_fh); + + if (verbose == 1) + GeoIP_printf(f,"Done\n"); + + if (verbose == 1) { + GeoIP_printf(f, WritingFile, GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); + } + + /* sanity check */ + gi = GeoIP_open(file_path_test, GEOIP_STANDARD); + + if (verbose == 1) + GeoIP_printf(f,"Performing santity checks ... "); + + if (gi == NULL) { + GeoIP_printf(f,"Error opening sanity check database\n"); + return GEOIP_SANITY_OPEN_ERR; + } + + /* this checks to make sure the files is complete, since info is at the end */ + /* dependent on future databases having MaxMind in info */ + if (verbose == 1) + GeoIP_printf(f,"database_info "); + db_info = GeoIP_database_info(gi); + if (db_info == NULL) { + GeoIP_delete(gi); + if (verbose == 1) + GeoIP_printf(f,"FAIL\n"); + return GEOIP_SANITY_INFO_FAIL; + } + if (strstr(db_info, "MaxMind") == NULL) { + free(db_info); + GeoIP_delete(gi); + if (verbose == 1) + GeoIP_printf(f,"FAIL\n"); + return GEOIP_SANITY_INFO_FAIL; + } + free(db_info); + if (verbose == 1) + GeoIP_printf(f,"PASS "); + + /* this performs an IP lookup test of a US IP address */ + if (verbose == 1) + GeoIP_printf(f,"lookup "); + if (strcmp(GeoIP_country_code_by_addr(gi,"24.24.24.24"), "US") != 0) { + GeoIP_delete(gi); + if (verbose == 1) + GeoIP_printf(f,"FAIL\n"); + return GEOIP_SANITY_LOOKUP_FAIL; + } + GeoIP_delete(gi); + if (verbose == 1) + GeoIP_printf(f,"PASS\n"); + + /* install GeoIP.dat.test -> GeoIP.dat */ + err = rename(file_path_test, GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); + if (err != 0) { + GeoIP_printf(f,"GeoIP Install error while renaming file\n"); + return GEOIP_RENAME_ERR; + } + + if (verbose == 1) + GeoIP_printf(f,"Done\n"); + + return 0; +} + +short int GeoIP_update_database_general (char * user_id,char * license_key,char *data_base_type, int verbose,char ** client_ipaddr, void (*f)( char *)) { + struct hostent *hostlist; + int sock; + char * buf; + struct sockaddr_in sa; + int offset = 0, err; + char * request_uri; + char * compr; + unsigned long comprLen; + FILE *comp_fh, *cur_db_fh, *gi_fh; + gzFile gz_fh; + char * file_path_gz, * file_path_test; + MD5_CONTEXT context; + MD5_CONTEXT context2; + unsigned char buffer[1024], digest[16] ,digest2[16]; + char hex_digest[33] = "0000000000000000000000000000000\0"; + char hex_digest2[33] = "0000000000000000000000000000000\0"; + unsigned int i; + char *f_str; + GeoIP * gi; + char * db_info; + char *ipaddress; + char *geoipfilename; + char *tmpstr; + int dbtype; + int lookupresult = 1; + char block[BLOCK_SIZE]; + int block_size = BLOCK_SIZE; + size_t len; + size_t request_uri_len; + size_t size; + + hostlist = GeoIP_get_host_or_proxy(); + + if (hostlist == NULL) + return GEOIP_DNS_ERR; + + if (hostlist->h_addrtype != AF_INET) + return GEOIP_NON_IPV4_ERR; + if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + return GEOIP_SOCKET_OPEN_ERR; + } + + memset(&sa, 0, sizeof(struct sockaddr_in)); + sa.sin_port = htons(GeoIPHTTPPort); + memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length); + sa.sin_family = AF_INET; + + if (verbose == 1) { + GeoIP_printf(f,"Connecting to MaxMind GeoIP server\n"); + GeoIP_printf(f, "via Host or Proxy Server: %s:%d\n", hostlist->h_name, GeoIPHTTPPort); + } + + if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0) + return GEOIP_CONNECTION_ERR; + request_uri = malloc(sizeof(char) * (strlen(GeoIPHTTPRequestFilename) + + strlen(GeoIPProxyHTTP) + strlen(GeoIPProxiedHost) + + strlen(data_base_type) + strlen(GeoIPUpdateHost) + 1)); + if (request_uri == NULL) + return GEOIP_OUT_OF_MEMORY_ERR; + + /* get the file name from a web page using the product id */ + sprintf(request_uri,GeoIPHTTPRequestFilename,GeoIPProxyHTTP,GeoIPProxiedHost,data_base_type,GeoIPUpdateHost); + if (verbose == 1) { + GeoIP_printf(f, "sending request %s \n",request_uri); + } + send(sock, request_uri, strlen(request_uri),0); /* send the request */ + free(request_uri); + buf = malloc(sizeof(char) * (block_size+4)); + if (buf == NULL) + return GEOIP_OUT_OF_MEMORY_ERR; + offset = 0; + for (;;){ + int amt; + amt = recv(sock, &buf[offset], block_size,0); + if (amt == 0){ + break; + } else if (amt == -1) { + free(buf); + return GEOIP_SOCKET_READ_ERR; + } + offset += amt; + buf = realloc(buf, offset + block_size + 4); + } + buf[offset] = 0; + offset = 0; + tmpstr = strstr(buf, "\r\n\r\n"); + if ( tmpstr == NULL ) { + free(buf); + return GEOIP_INVALID_SERVER_RESPONSE; + } + /* skip searchstr "\r\n\r\n" */ + tmpstr += 4; + if (tmpstr[0] == '.' || strchr(tmpstr, '/') != NULL || strchr(tmpstr, '\\') != NULL) { + free(buf); + return GEOIP_INVALID_SERVER_RESPONSE; + } + geoipfilename = _GeoIP_full_path_to(tmpstr); + free(buf); + + /* print the database product id and the database filename */ + if (verbose == 1){ + GeoIP_printf(f, "database product id %s database file name %s \n",data_base_type,geoipfilename); + } + _GeoIP_setup_dbfilename(); + + /* get MD5 of current GeoIP database file */ + if ((cur_db_fh = fopen (geoipfilename, "rb")) == NULL) { + GeoIP_printf(f, NoCurrentDB, geoipfilename); + } else { + md5_init(&context); + while ((len = fread (buffer, 1, 1024, cur_db_fh)) > 0) + md5_write (&context, buffer, len); + md5_final (&context); + memcpy(digest,context.buf,16); + fclose (cur_db_fh); + for (i = 0; i < 16; i++) + sprintf (&hex_digest[2*i], "%02x", digest[i]); + GeoIP_printf(f, MD5Info, hex_digest ); + } + if (verbose == 1) { + GeoIP_printf(f,"MD5 sum of database %s is %s \n",geoipfilename,hex_digest); + } + if (client_ipaddr[0] == NULL) { + /* We haven't gotten our IP address yet, so let's request it */ + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + free(geoipfilename); + return GEOIP_SOCKET_OPEN_ERR; + } + + memset(&sa, 0, sizeof(struct sockaddr_in)); + sa.sin_port = htons(GeoIPHTTPPort); + memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length); + sa.sin_family = AF_INET; + + if (verbose == 1) + GeoIP_printf(f,"Connecting to MaxMind GeoIP Update server\n"); + + /* Download gzip file */ + if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0) { + free(geoipfilename); + return GEOIP_CONNECTION_ERR; + } + request_uri = malloc(sizeof(char) * (strlen(GeoIPHTTPRequestClientIP) + + strlen(GeoIPProxyHTTP) + + strlen(GeoIPProxiedHost) + + strlen(GeoIPUpdateHost) + 1 )); + if (request_uri == NULL) { + free(geoipfilename); + return GEOIP_OUT_OF_MEMORY_ERR; + } + + /* get client ip address from MaxMind web page */ + sprintf(request_uri,GeoIPHTTPRequestClientIP,GeoIPProxyHTTP,GeoIPProxiedHost,GeoIPUpdateHost); + send(sock, request_uri, strlen(request_uri),0); /* send the request */ + if (verbose == 1) { + GeoIP_printf(f, "sending request %s", request_uri); + } + free(request_uri); + buf = malloc(sizeof(char) * (block_size+1)); + if (buf == NULL) { + free(geoipfilename); + return GEOIP_OUT_OF_MEMORY_ERR; + } + offset = 0; + + for (;;){ + int amt; + amt = recv(sock, &buf[offset], block_size,0); + if (amt == 0) { + break; + } else if (amt == -1) { + free(buf); + return GEOIP_SOCKET_READ_ERR; + } + offset += amt; + buf = realloc(buf, offset+block_size+1); + } + + buf[offset] = 0; + offset = 0; + ipaddress = strstr(buf, "\r\n\r\n") + 4; /* get the ip address */ + ipaddress = malloc(strlen(strstr(buf, "\r\n\r\n") + 4)+5); + strcpy(ipaddress,strstr(buf, "\r\n\r\n") + 4); + client_ipaddr[0] = ipaddress; + if (verbose == 1) { + GeoIP_printf(f, "client ip address: %s\n",ipaddress); + } + free(buf); + close(sock); + } + + ipaddress = client_ipaddr[0]; + + /* make a md5 sum of ip address and license_key and store it in hex_digest2 */ + md5_init(&context2); + md5_write (&context2, (byte *)license_key, 12);//add license key to the md5 sum + md5_write (&context2, (byte *)ipaddress, strlen(ipaddress));//add ip address to the md5 sum + md5_final (&context2); + memcpy(digest2,context2.buf,16); + for (i = 0; i < 16; i++) + snprintf (&hex_digest2[2*i], 3, "%02x", digest2[i]);// change the digest to a hex digest + if (verbose == 1) { + GeoIP_printf(f, "md5sum of ip address and license key is %s \n",hex_digest2); + } + + /* send the request using the user id,product id, + * md5 sum of the prev database and + * the md5 sum of the license_key and ip address */ + if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + return GEOIP_SOCKET_OPEN_ERR; + } + memset(&sa, 0, sizeof(struct sockaddr_in)); + sa.sin_port = htons(GeoIPHTTPPort); + memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length); + sa.sin_family = AF_INET; + if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0) + return GEOIP_CONNECTION_ERR; + request_uri_len = sizeof(char) * 2036; + request_uri = malloc(request_uri_len); + if (request_uri == NULL) + return GEOIP_OUT_OF_MEMORY_ERR; + snprintf(request_uri, request_uri_len, GeoIPHTTPRequestMD5,GeoIPProxyHTTP,GeoIPProxiedHost,hex_digest,hex_digest2,user_id,data_base_type); + send(sock, request_uri, strlen(request_uri),0); + if (verbose == 1) { + GeoIP_printf(f, "sending request %s\n",request_uri); + } + + free(request_uri); + + offset = 0; + buf = malloc(sizeof(char) * block_size); + if (buf == NULL) + return GEOIP_OUT_OF_MEMORY_ERR; + + if (verbose == 1) + GeoIP_printf(f,"Downloading gzipped GeoIP Database...\n"); + + for (;;) { + int amt; + amt = recv(sock, &buf[offset], block_size,0); + + if (amt == 0) { + break; + } else if (amt == -1) { + free(buf); + return GEOIP_SOCKET_READ_ERR; + } + offset += amt; + buf = realloc(buf, offset+block_size); + if (buf == NULL) + return GEOIP_OUT_OF_MEMORY_ERR; + } + + compr = strstr(buf, "\r\n\r\n") + 4; + comprLen = offset + buf - compr; + + if (strstr(compr, "License Key Invalid") != NULL) { + if (verbose == 1) + GeoIP_printf(f,"Failed\n"); + free(buf); + return GEOIP_LICENSE_KEY_INVALID_ERR; + } else if (strstr(compr, "No new updates available") != NULL) { + free(buf); + GeoIP_printf(f, "%s is up to date, no updates required\n", geoipfilename); + return GEOIP_NO_NEW_UPDATES; + } else if (strstr(compr, "Invalid UserId") != NULL){ + free(buf); + return GEOIP_USER_ID_INVALID_ERR; + } else if (strstr(compr, "Invalid product ID or subscription expired") != NULL){ + free(buf); + return GEOIP_PRODUCT_ID_INVALID_ERR; + } + + if (verbose == 1) + GeoIP_printf(f,"Done\n"); + + GeoIP_printf(f, "Updating %s\n", geoipfilename); + + /* save gzip file */ + file_path_gz = malloc(sizeof(char) * (strlen(geoipfilename) + 4)); + + if (file_path_gz == NULL) + return GEOIP_OUT_OF_MEMORY_ERR; + strcpy(file_path_gz,geoipfilename); + strcat(file_path_gz,".gz"); + if (verbose == 1) { + GeoIP_printf(f, SavingGzip, file_path_gz ); + } + comp_fh = fopen(file_path_gz, "wb"); + + if(comp_fh == NULL) { + free(file_path_gz); + free(buf); + return GEOIP_GZIP_IO_ERR; + } + + size = fwrite(compr, 1, comprLen, comp_fh); + fclose(comp_fh); + free(buf); + if ( size != comprLen ) { + return GEOIP_GZIP_IO_ERR; + } + + if (verbose == 1) { + GeoIP_printf(f, "download data to a gz file named %s \n",file_path_gz); + GeoIP_printf(f,"Done\n"); + GeoIP_printf(f,"Uncompressing gzip file ... "); + } + + file_path_test = malloc(sizeof(char) * (strlen(GeoIPDBFileName[GEOIP_COUNTRY_EDITION]) + 6)); + if (file_path_test == NULL) { + free(file_path_gz); + return GEOIP_OUT_OF_MEMORY_ERR; + } + strcpy(file_path_test,GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); + strcat(file_path_test,".test"); + gi_fh = fopen(file_path_test, "wb"); + if(gi_fh == NULL) { + free(file_path_test); + free(file_path_gz); + return GEOIP_TEST_IO_ERR; + } + /* uncompress gzip file */ + offset = 0; + gz_fh = gzopen(file_path_gz, "rb"); + for (;;) { + int amt; + amt = gzread(gz_fh, block, block_size); + if (amt == -1) { + free(file_path_gz); + free(file_path_test); + gzclose(gz_fh); + fclose(gi_fh); + return GEOIP_GZIP_READ_ERR; + } + if (amt == 0) { + break; + } + if ( amt != fwrite(block,1,amt,gi_fh) ){ + return GEOIP_GZIP_IO_ERR; + } + } + gzclose(gz_fh); + unlink(file_path_gz); + free(file_path_gz); + fclose(gi_fh); + + if (verbose == 1) + GeoIP_printf(f,"Done\n"); + + if (verbose == 1) { + len = strlen(WritingFile) + strlen(geoipfilename) - 1; + f_str = malloc(len); + snprintf(f_str,len,WritingFile,geoipfilename); + free(f_str); + } + + /* sanity check */ + gi = GeoIP_open(file_path_test, GEOIP_STANDARD); + + if (verbose == 1) + GeoIP_printf(f,"Performing santity checks ... "); + + if (gi == NULL) { + GeoIP_printf(f,"Error opening sanity check database\n"); + return GEOIP_SANITY_OPEN_ERR; + } + + + /* get the database type */ + dbtype = GeoIP_database_edition(gi); + if (verbose == 1) { + GeoIP_printf(f, "Database type is %d\n",dbtype); + } + + /* this checks to make sure the files is complete, since info is at the end + dependent on future databases having MaxMind in info (ISP and Organization databases currently don't have info string */ + + if ((dbtype != GEOIP_ISP_EDITION)&& + (dbtype != GEOIP_ORG_EDITION)) { + if (verbose == 1) + GeoIP_printf(f,"database_info "); + db_info = GeoIP_database_info(gi); + if (db_info == NULL) { + GeoIP_delete(gi); + if (verbose == 1) + GeoIP_printf(f,"FAIL null\n"); + return GEOIP_SANITY_INFO_FAIL; + } + if (strstr(db_info, "MaxMind") == NULL) { + free(db_info); + GeoIP_delete(gi); + if (verbose == 1) + GeoIP_printf(f,"FAIL maxmind\n"); + return GEOIP_SANITY_INFO_FAIL; + } + free(db_info); + if (verbose == 1) + GeoIP_printf(f,"PASS "); + } + + /* this performs an IP lookup test of a US IP address */ + if (verbose == 1) + GeoIP_printf(f,"lookup "); + if (dbtype == GEOIP_NETSPEED_EDITION) { + int netspeed = GeoIP_id_by_name(gi,"24.24.24.24"); + lookupresult = 0; + if (netspeed == GEOIP_CABLEDSL_SPEED){ + lookupresult = 1; + } + } + if (dbtype == GEOIP_COUNTRY_EDITION) { + /* if data base type is country then call the function + * named GeoIP_country_code_by_addr */ + lookupresult = 1; + if (strcmp(GeoIP_country_code_by_addr(gi,"24.24.24.24"), "US") != 0) { + lookupresult = 0; + } + if (verbose == 1) { + GeoIP_printf(f,"testing GEOIP_COUNTRY_EDITION\n"); + } + } + if (dbtype == GEOIP_REGION_EDITION_REV1) { + /* if data base type is region then call the function + * named GeoIP_region_by_addr */ + GeoIPRegion *r = GeoIP_region_by_addr(gi,"24.24.24.24"); + lookupresult = 0; + if (r != NULL) { + lookupresult = 1; + free(r); + } + if (verbose == 1) { + GeoIP_printf(f,"testing GEOIP_REGION_EDITION\n"); + } + } + if (dbtype == GEOIP_CITY_EDITION_REV1) { + /* if data base type is city then call the function + * named GeoIP_record_by_addr */ + GeoIPRecord *r = GeoIP_record_by_addr(gi,"24.24.24.24"); + lookupresult = 0; + if (r != NULL) { + lookupresult = 1; + free(r); + } + if (verbose == 1) { + GeoIP_printf(f,"testing GEOIP_CITY_EDITION\n"); + } + } + if ((dbtype == GEOIP_ISP_EDITION)|| + (dbtype == GEOIP_ORG_EDITION)) { + /* if data base type is isp or org then call the function + * named GeoIP_org_by_addr */ + GeoIPRecord *r = (GeoIPRecord*)GeoIP_org_by_addr(gi,"24.24.24.24"); + lookupresult = 0; + if (r != NULL) { + lookupresult = 1; + free(r); + } + if (verbose == 1) { + if (dbtype == GEOIP_ISP_EDITION) { + GeoIP_printf(f,"testing GEOIP_ISP_EDITION\n"); + } + if (dbtype == GEOIP_ORG_EDITION) { + GeoIP_printf(f,"testing GEOIP_ORG_EDITION\n"); + } + } + } + if (lookupresult == 0) { + GeoIP_delete(gi); + if (verbose == 1) + GeoIP_printf(f,"FAIL\n"); + return GEOIP_SANITY_LOOKUP_FAIL; + } + GeoIP_delete(gi); + if (verbose == 1) + GeoIP_printf(f,"PASS\n"); + + /* install GeoIP.dat.test -> GeoIP.dat */ + err = rename(file_path_test, geoipfilename); + if (err != 0) { + GeoIP_printf(f,"GeoIP Install error while renaming file\n"); + return GEOIP_RENAME_ERR; + } + + if (verbose == 1) + GeoIP_printf(f,"Done\n"); + free(geoipfilename); + return 0; +} diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIPUpdate.h b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIPUpdate.h new file mode 100644 index 00000000..7e6bbe18 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIPUpdate.h @@ -0,0 +1,69 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIP.h + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef GEOIPUPDATE_H +#define GEOIPUPDATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef enum { + GEOIP_NO_NEW_UPDATES = 1, /* Database up-to-date, no action taken */ + GEOIP_SUCCESS = 0, /* Success */ + GEOIP_LICENSE_KEY_INVALID_ERR = -1, /* License Key Invalid */ + GEOIP_DNS_ERR = -11, /* Unable to resolve hostname */ + GEOIP_NON_IPV4_ERR = -12, /* Non - IPv4 address */ + GEOIP_SOCKET_OPEN_ERR = -13, /* Error opening socket */ + GEOIP_CONNECTION_ERR = -14, /* Unable to connect */ + GEOIP_GZIP_IO_ERR = -15, /* Unable to write GeoIP.dat.gz file */ + GEOIP_TEST_IO_ERR = -16, /* Unable to write GeoIP.dat.test file */ + GEOIP_GZIP_READ_ERR = -17, /* Unable to read gzip data */ + GEOIP_OUT_OF_MEMORY_ERR = -18, /* Out of memory error */ + GEOIP_SOCKET_READ_ERR = -19, /* Error reading from socket, see errno */ + GEOIP_SANITY_OPEN_ERR = -20, /* Sanity check GeoIP_open error */ + GEOIP_SANITY_INFO_FAIL = -21, /* Sanity check database_info string failed */ + GEOIP_SANITY_LOOKUP_FAIL = -22, /* Sanity check ip address lookup failed */ + GEOIP_RENAME_ERR = -23, /* Rename error while installing db, check errno */ + GEOIP_USER_ID_INVALID_ERR = -24, /* Invalid userID */ + GEOIP_PRODUCT_ID_INVALID_ERR = -25, /* Invalid product ID or subscription expired */ + GEOIP_INVALID_SERVER_RESPONSE = -26 /* Server returned invalid response */ +} GeoIPUpdateCode; + +const char * GeoIP_get_error_message(int i); + +/* Original Update Function, just for MaxMind GeoIP Country database */ + short int GeoIP_update_database (char * license_key, int verbose, void (*f)( char *)); + +/* More generalized update function that works more databases */ + short int GeoIP_update_database_general (char * user_id, char * license_key,char * data_base_type, int verbose,char ** client_ipaddr, void (*f)( char *)); + + /* experimental export */ + int GeoIP_fprintf(int (*f)(FILE *, char *),FILE *fp, const char *fmt, ...); + void GeoIP_printf(void (*f)(char *), const char *fmt, ...); + +#ifdef __cplusplus +} +#endif + +#endif /* GEOIPUPDATE_H */ diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIP_internal.h b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIP_internal.h new file mode 100644 index 00000000..c19870fa --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/GeoIP_internal.h @@ -0,0 +1,18 @@ +#ifndef GEOIP_INTERNAL_H +#define GEOIP_INTERNAL_H + +#include "GeoIP.h" + +GEOIP_API unsigned int _GeoIP_seek_record (GeoIP *gi, unsigned long ipnum); + +GEOIP_API unsigned int _GeoIP_seek_record_v6 (GeoIP *gi, geoipv6_t ipnum); +GEOIP_API geoipv6_t _GeoIP_addr_to_num_v6 (const char *addr); + +GEOIP_API unsigned long _GeoIP_lookupaddress (const char *host); +GEOIP_API geoipv6_t _GeoIP_lookupaddress_v6 (const char *host); +GEOIP_API int __GEOIP_V6_IS_NULL(geoipv6_t v6); + +GEOIP_API void _GeoIP_setup_dbfilename(); +GEOIP_API char *_GeoIP_full_path_to(const char *file_name); + +#endif diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/Makefile.am b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/Makefile.am new file mode 100644 index 00000000..5fa0a903 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/Makefile.am @@ -0,0 +1,27 @@ +lib_LTLIBRARIES = libGeoIP.la libGeoIPUpdate.la + +EXTRA_DIST = Makefile.vc md5.h global.h types.h GeoIP_internal.h + +AM_CPPFLAGS = -DGEOIPDATADIR=\"$(pkgdatadir)\" -Wall + +libGeoIP_la_SOURCES = GeoIP.c GeoIPCity.c regionName.c timeZone.c +include_HEADERS = GeoIP.h GeoIPCity.h GeoIPUpdate.h + +libGeoIPUpdate_la_SOURCES = GeoIPUpdate.c md5.c + +libGeoIP_la_LDFLAGS = -version-info @GEOIP_VERSION_INFO@ + +libGeoIPUpdate_la_LIBADD = -lz libGeoIP.la + +GeoIP.lo GeoIP.o: GeoIP.c GeoIP.h + +GeoIPCity.lo GeoIPCity.o: GeoIPCity.c GeoIP.h + +GeoIPUpdate.lo GeoIPUpdate.o: GeoIPUpdate.c GeoIPCity.h GeoIP.h + +regionName.lo regionName.o: regionName.c + +md5.lo md5.o: md5.c + +timeZone.lo timeZone.o: timeZone.c + diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/Makefile.in b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/Makefile.in new file mode 100644 index 00000000..5cb5c9f1 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/Makefile.in @@ -0,0 +1,567 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libGeoIP +DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libGeoIP_la_LIBADD = +am_libGeoIP_la_OBJECTS = GeoIP.lo GeoIPCity.lo regionName.lo \ + timeZone.lo +libGeoIP_la_OBJECTS = $(am_libGeoIP_la_OBJECTS) +libGeoIP_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libGeoIP_la_LDFLAGS) $(LDFLAGS) -o $@ +libGeoIPUpdate_la_DEPENDENCIES = libGeoIP.la +am_libGeoIPUpdate_la_OBJECTS = GeoIPUpdate.lo md5.lo +libGeoIPUpdate_la_OBJECTS = $(am_libGeoIPUpdate_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libGeoIP_la_SOURCES) $(libGeoIPUpdate_la_SOURCES) +DIST_SOURCES = $(libGeoIP_la_SOURCES) $(libGeoIPUpdate_la_SOURCES) +HEADERS = $(include_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEOIP_VERSION_INFO = @GEOIP_VERSION_INFO@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +lib_LTLIBRARIES = libGeoIP.la libGeoIPUpdate.la +EXTRA_DIST = Makefile.vc md5.h global.h types.h GeoIP_internal.h +AM_CPPFLAGS = -DGEOIPDATADIR=\"$(pkgdatadir)\" -Wall +libGeoIP_la_SOURCES = GeoIP.c GeoIPCity.c regionName.c timeZone.c +include_HEADERS = GeoIP.h GeoIPCity.h GeoIPUpdate.h +libGeoIPUpdate_la_SOURCES = GeoIPUpdate.c md5.c +libGeoIP_la_LDFLAGS = -version-info @GEOIP_VERSION_INFO@ +libGeoIPUpdate_la_LIBADD = -lz libGeoIP.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libGeoIP/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu libGeoIP/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libGeoIP.la: $(libGeoIP_la_OBJECTS) $(libGeoIP_la_DEPENDENCIES) + $(libGeoIP_la_LINK) -rpath $(libdir) $(libGeoIP_la_OBJECTS) $(libGeoIP_la_LIBADD) $(LIBS) +libGeoIPUpdate.la: $(libGeoIPUpdate_la_OBJECTS) $(libGeoIPUpdate_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libGeoIPUpdate_la_OBJECTS) $(libGeoIPUpdate_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GeoIP.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GeoIPCity.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GeoIPUpdate.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regionName.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timeZone.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(includedir)" && rm -f $$files + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-includeHEADERS install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-includeHEADERS \ + uninstall-libLTLIBRARIES + + +GeoIP.lo GeoIP.o: GeoIP.c GeoIP.h + +GeoIPCity.lo GeoIPCity.o: GeoIPCity.c GeoIP.h + +GeoIPUpdate.lo GeoIPUpdate.o: GeoIPUpdate.c GeoIPCity.h GeoIP.h + +regionName.lo regionName.o: regionName.c + +md5.lo md5.o: md5.c + +timeZone.lo timeZone.o: timeZone.c + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/Makefile.vc b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/Makefile.vc new file mode 100644 index 00000000..2a167319 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/Makefile.vc @@ -0,0 +1,34 @@ +#NMAKE makefile for Windows developers. +#Produces a static library (GeoIP.lib). + +COMPILER=cl + +CFLAGS=-DWIN32 -MD -nologo + +GEOIPINC = -I..\libGeoIP + +CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) -DGEOIPDATADIR=\"$(GEOIPDATADIR)\" + +OBJS=GeoIP.obj GeoIPCity.obj regionName.obj md5.obj timeZone.obj + +EXTRA_LIBS= advapi32.lib wsock32.lib + +AR=lib + +GeoIP.lib: GeoIP.obj GeoIPCity.obj regionName.obj md5.obj timeZone.obj + $(AR) -nologo $(OBJS) $(EXTRA_LIBS) /OUT:GeoIP.lib + +GeoIP.obj: GeoIP.c + $(CC1) -c GeoIP.c $(GEOIPINC) + +GeoIPCity.obj: GeoIPCity.c + $(CC1) -c GeoIPCity.c $(GEOIPINC) + +regionName.obj: regionName.c + $(CC1) -c regionName.c $(GEOIPINC) + +md5.obj: md5.c + $(CC1) -c md5.c $(GEOIPINC) + +timeZone.obj: timeZone.c + $(CC1) -c timeZone.c $(GEOIPINC) diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/global.h b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/global.h new file mode 100644 index 00000000..22c5684b --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/global.h @@ -0,0 +1,32 @@ +/* GLOBAL.H - RSAREF types and constants + */ + +/* PROTOTYPES should be set to one if and only if the compiler supports + function argument prototyping. +The following makes PROTOTYPES default to 0 if it has not already + + been defined with C compiler flags. + */ +#ifndef PROTOTYPES +#define PROTOTYPES 0 +#endif + +/* POINTER defines a generic pointer type */ +typedef unsigned char *POINTER; + +/* UINT2 defines a two byte word */ +typedef unsigned short int UINT2; + +/* UINT4 defines a four byte word */ +typedef unsigned long int UINT4; + +/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. +If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it + returns an empty list. + */ +#if PROTOTYPES +#define PROTO_LIST(list) list +#else +#define PROTO_LIST(list) () +#endif + diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/md5.c b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/md5.c new file mode 100644 index 00000000..4b0c237f --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/md5.c @@ -0,0 +1,326 @@ +/* md5.c - MD5 Message-Digest Algorithm + * Copyright (C) 1995, 1996, 1998, 1999, + * 2000, 2001 Free Software Foundation, Inc. + * + * 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 2, 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * According to the definition of MD5 in RFC 1321 from April 1992. + * NOTE: This is *not* the same file as the one from glibc. + */ +/* Written by Ulrich Drepper , 1995. */ +/* Heavily modified for GnuPG by */ + +#include +#include +#include +#include + +#include "types.h" + +#ifdef WORDS_BIGENDIAN +#define BIG_ENDIAN_HOST +#endif + +//#define DIM(v) (sizeof(v)/sizeof((v)[0])) +#define wipememory2(_ptr,_set,_len) do { volatile char *_vptr=(volatile char *)(_ptr); size_t _vlen=(_len); while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } } while(0) +#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) +#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) ) + +typedef struct { + u32 A,B,C,D; /* chaining variables */ + u32 nblocks; + byte buf[64]; + int count; +} MD5_CONTEXT; + + +void +md5_init( MD5_CONTEXT *ctx ) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + + ctx->nblocks = 0; + ctx->count = 0; +} + + + + +/* These are the four functions used in the four steps of the MD5 algorithm + and defined in the RFC 1321. The first function is a little bit optimized + (as found in Colin Plumbs public domain implementation). */ +/* #define FF(b, c, d) ((b & c) | (~b & d)) */ +#define FF(b, c, d) (d ^ (b & (c ^ d))) +#define FG(b, c, d) FF (d, b, c) +#define FH(b, c, d) (b ^ c ^ d) +#define FI(b, c, d) (c ^ (b | ~d)) + +static void +burn_stack (int bytes) +{ + char buf[128]; + + wipememory(buf,sizeof buf); + bytes -= sizeof buf; + if (bytes > 0) + burn_stack (bytes); +} + + + +/**************** + * transform n*64 bytes + */ +static void +/*transform( MD5_CONTEXT *ctx, const void *buffer, size_t len )*/ +transform( MD5_CONTEXT *ctx, byte *data ) +{ + u32 correct_words[16]; + u32 A = ctx->A; + u32 B = ctx->B; + u32 C = ctx->C; + u32 D = ctx->D; + u32 *cwp = correct_words; + +#ifdef BIG_ENDIAN_HOST + { int i; + byte *p2, *p1; + for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 ) { + p2[3] = *p1++; + p2[2] = *p1++; + p2[1] = *p1++; + p2[0] = *p1++; + } + } +#else + memcpy( correct_words, data, 64 ); +#endif + + +#define OP(a, b, c, d, s, T) \ + do \ + { \ + a += FF (b, c, d) + (*cwp++) + T; \ + a = rol(a, s); \ + a += b; \ + } \ + while (0) + + /* Before we start, one word about the strange constants. + They are defined in RFC 1321 as + + T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 + */ + + /* Round 1. */ + OP (A, B, C, D, 7, 0xd76aa478); + OP (D, A, B, C, 12, 0xe8c7b756); + OP (C, D, A, B, 17, 0x242070db); + OP (B, C, D, A, 22, 0xc1bdceee); + OP (A, B, C, D, 7, 0xf57c0faf); + OP (D, A, B, C, 12, 0x4787c62a); + OP (C, D, A, B, 17, 0xa8304613); + OP (B, C, D, A, 22, 0xfd469501); + OP (A, B, C, D, 7, 0x698098d8); + OP (D, A, B, C, 12, 0x8b44f7af); + OP (C, D, A, B, 17, 0xffff5bb1); + OP (B, C, D, A, 22, 0x895cd7be); + OP (A, B, C, D, 7, 0x6b901122); + OP (D, A, B, C, 12, 0xfd987193); + OP (C, D, A, B, 17, 0xa679438e); + OP (B, C, D, A, 22, 0x49b40821); + +#undef OP +#define OP(f, a, b, c, d, k, s, T) \ + do \ + { \ +a += f (b, c, d) + correct_words[k] + T; \ +a = rol(a, s); \ +a += b; \ + } \ + while (0) + + /* Round 2. */ + OP (FG, A, B, C, D, 1, 5, 0xf61e2562); + OP (FG, D, A, B, C, 6, 9, 0xc040b340); + OP (FG, C, D, A, B, 11, 14, 0x265e5a51); + OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); + OP (FG, A, B, C, D, 5, 5, 0xd62f105d); + OP (FG, D, A, B, C, 10, 9, 0x02441453); + OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); + OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); + OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); + OP (FG, D, A, B, C, 14, 9, 0xc33707d6); + OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); + OP (FG, B, C, D, A, 8, 20, 0x455a14ed); + OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); + OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); + OP (FG, C, D, A, B, 7, 14, 0x676f02d9); + OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); + + /* Round 3. */ + OP (FH, A, B, C, D, 5, 4, 0xfffa3942); + OP (FH, D, A, B, C, 8, 11, 0x8771f681); + OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); + OP (FH, B, C, D, A, 14, 23, 0xfde5380c); + OP (FH, A, B, C, D, 1, 4, 0xa4beea44); + OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); + OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); + OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); + OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); + OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); + OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); + OP (FH, B, C, D, A, 6, 23, 0x04881d05); + OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); + OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); + OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); + OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); + + /* Round 4. */ + OP (FI, A, B, C, D, 0, 6, 0xf4292244); + OP (FI, D, A, B, C, 7, 10, 0x432aff97); + OP (FI, C, D, A, B, 14, 15, 0xab9423a7); + OP (FI, B, C, D, A, 5, 21, 0xfc93a039); + OP (FI, A, B, C, D, 12, 6, 0x655b59c3); + OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); + OP (FI, C, D, A, B, 10, 15, 0xffeff47d); + OP (FI, B, C, D, A, 1, 21, 0x85845dd1); + OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); + OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); + OP (FI, C, D, A, B, 6, 15, 0xa3014314); + OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); + OP (FI, A, B, C, D, 4, 6, 0xf7537e82); + OP (FI, D, A, B, C, 11, 10, 0xbd3af235); + OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); + OP (FI, B, C, D, A, 9, 21, 0xeb86d391); + + /* Put checksum in context given as argument. */ + ctx->A += A; + ctx->B += B; + ctx->C += C; + ctx->D += D; +} + + + +/* The routine updates the message-digest context to + * account for the presence of each of the characters inBuf[0..inLen-1] + * in the message whose digest is being computed. + */ +void +md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen) +{ + if( hd->count == 64 ) { /* flush the buffer */ + transform( hd, hd->buf ); + burn_stack (80+6*sizeof(void*)); + hd->count = 0; + hd->nblocks++; + } + if( !inbuf ) + return; + if( hd->count ) { + for( ; inlen && hd->count < 64; inlen-- ) + hd->buf[hd->count++] = *inbuf++; + md5_write( hd, NULL, 0 ); + if( !inlen ) + return; + } + + while( inlen >= 64 ) { + transform( hd, inbuf ); + hd->count = 0; + hd->nblocks++; + inlen -= 64; + inbuf += 64; + } + burn_stack (80+6*sizeof(void*)); + for( ; inlen && hd->count < 64; inlen-- ) + hd->buf[hd->count++] = *inbuf++; +} +/* The routine final terminates the message-digest computation and + * ends with the desired message digest in mdContext->digest[0...15]. + * The handle is prepared for a new MD5 cycle. + * Returns 16 bytes representing the digest. + */ + +void +md5_final( MD5_CONTEXT *hd ) +{ + u32 t, msb, lsb; + byte *p; + + md5_write(hd, NULL, 0); /* flush */; + + t = hd->nblocks; + /* multiply by 64 to make a byte count */ + lsb = t << 6; + msb = t >> 26; + /* add the count */ + t = lsb; + if( (lsb += hd->count) < t ) + msb++; + /* multiply by 8 to make a bit count */ + t = lsb; + lsb <<= 3; + msb <<= 3; + msb |= t >> 29; + + if( hd->count < 56 ) { /* enough room */ + hd->buf[hd->count++] = 0x80; /* pad */ + while( hd->count < 56 ) + hd->buf[hd->count++] = 0; /* pad */ + } + else { /* need one extra block */ + hd->buf[hd->count++] = 0x80; /* pad character */ + while( hd->count < 64 ) + hd->buf[hd->count++] = 0; + md5_write(hd, NULL, 0); /* flush */; + memset(hd->buf, 0, 56 ); /* fill next block with zeroes */ + } + /* append the 64 bit count */ + hd->buf[56] = lsb ; + hd->buf[57] = lsb >> 8; + hd->buf[58] = lsb >> 16; + hd->buf[59] = lsb >> 24; + hd->buf[60] = msb ; + hd->buf[61] = msb >> 8; + hd->buf[62] = msb >> 16; + hd->buf[63] = msb >> 24; + transform( hd, hd->buf ); + burn_stack (80+6*sizeof(void*)); + + p = hd->buf; +#ifdef BIG_ENDIAN_HOST +#define X(a) do { *p++ = hd-> a ; *p++ = hd-> a >> 8; \ + *p++ = hd-> a >> 16; *p++ = hd-> a >> 24; } while(0) +#else /* little endian */ +#define X(a) do { *(u32*)p = hd-> a ; p += 4; } while(0) +#endif + X(A); + X(B); + X(C); + X(D); +#undef X + +} + +static byte * +md5_read( MD5_CONTEXT *hd ) +{ + return hd->buf; +} diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/md5.h b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/md5.h new file mode 100644 index 00000000..e1607be9 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/md5.h @@ -0,0 +1,40 @@ +/* MD5.H - header file for MD5C.C + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + +/* MD5 context. */ + +#include "types.h" + +typedef struct { + u32 A,B,C,D; /* chaining variables */ + u32 nblocks; + byte buf[64]; + int count; +} MD5_CONTEXT; + +void md5_init( MD5_CONTEXT *ctx ); +void md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen); +void md5_final( MD5_CONTEXT *hd ); + diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/regionName.c b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/regionName.c new file mode 100644 index 00000000..4f90f386 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/regionName.c @@ -0,0 +1,12780 @@ +#include +#include + +const char * GeoIP_region_name_by_code(const char * country_code,const char * region_code) { + const char * name = NULL; + int region_code2 = -1; + if (region_code == NULL) { return NULL; } + + if ( ((region_code[0] >= 48) && (region_code[0] < (48 + 10))) + && ((region_code[1] >= 48) && (region_code[1] < (48 + 10))) + ) { + + /* only numbers, that shorten the large switch statements */ + region_code2 = (region_code[0] - 48) * 10 + region_code[1] - 48; + } + + else if ( ( ((region_code[0] >= 65) && (region_code[0] < (65 + 26))) + || ((region_code[0] >= 48) && (region_code[0] < (48 + 10)))) + && ( ((region_code[1] >= 65) && (region_code[1] < (65 + 26))) + || ((region_code[1] >= 48) && (region_code[1] < (48 + 10)))) + ) { + + region_code2 = (region_code[0] - 48) * (65 + 26 - 48) + region_code[1] - 48 + 100; + } + + if (region_code2 == -1) {return NULL;} + + if (strcmp(country_code,"CA") == 0) { + switch (region_code2) { + case 849: + name = "Alberta"; + break; + case 893: + name = "British Columbia"; + break; + case 1365: + name = "Manitoba"; + break; + case 1408: + name = "New Brunswick"; + break; + case 1418: + name = "Newfoundland"; + break; + case 1425: + name = "Nova Scotia"; + break; + case 1427: + name = "Nunavut"; + break; + case 1463: + name = "Ontario"; + break; + case 1497: + name = "Prince Edward Island"; + break; + case 1538: + name = "Quebec"; + break; + case 1632: + name = "Saskatchewan"; + break; + case 1426: + name = "Northwest Territories"; + break; + case 1899: + name = "Yukon Territory"; + break; + } + } + if (strcmp(country_code,"US") == 0) { + switch (region_code2) { + case 848: + name = "Armed Forces Americas"; + break; + case 852: + name = "Armed Forces Europe, Middle East, & Canada"; + break; + case 858: + name = "Alaska"; + break; + case 859: + name = "Alabama"; + break; + case 863: + name = "Armed Forces Pacific"; + break; + case 865: + name = "Arkansas"; + break; + case 866: + name = "American Samoa"; + break; + case 873: + name = "Arizona"; + break; + case 934: + name = "California"; + break; + case 948: + name = "Colorado"; + break; + case 953: + name = "Connecticut"; + break; + case 979: + name = "District of Columbia"; + break; + case 981: + name = "Delaware"; + break; + case 1074: + name = "Florida"; + break; + case 1075: + name = "Federated States of Micronesia"; + break; + case 1106: + name = "Georgia"; + break; + case 1126: + name = "Guam"; + break; + case 1157: + name = "Hawaii"; + break; + case 1192: + name = "Iowa"; + break; + case 1195: + name = "Idaho"; + break; + case 1203: + name = "Illinois"; + break; + case 1205: + name = "Indiana"; + break; + case 1296: + name = "Kansas"; + break; + case 1302: + name = "Kentucky"; + break; + case 1321: + name = "Louisiana"; + break; + case 1364: + name = "Massachusetts"; + break; + case 1367: + name = "Maryland"; + break; + case 1368: + name = "Maine"; + break; + case 1371: + name = "Marshall Islands"; + break; + case 1372: + name = "Michigan"; + break; + case 1377: + name = "Minnesota"; + break; + case 1378: + name = "Missouri"; + break; + case 1379: + name = "Northern Mariana Islands"; + break; + case 1382: + name = "Mississippi"; + break; + case 1383: + name = "Montana"; + break; + case 1409: + name = "North Carolina"; + break; + case 1410: + name = "North Dakota"; + break; + case 1411: + name = "Nebraska"; + break; + case 1414: + name = "New Hampshire"; + break; + case 1416: + name = "New Jersey"; + break; + case 1419: + name = "New Mexico"; + break; + case 1428: + name = "Nevada"; + break; + case 1431: + name = "New York"; + break; + case 1457: + name = "Ohio"; + break; + case 1460: + name = "Oklahoma"; + break; + case 1467: + name = "Oregon"; + break; + case 1493: + name = "Pennsylvania"; + break; + case 1510: + name = "Puerto Rico"; + break; + case 1515: + name = "Palau"; + break; + case 1587: + name = "Rhode Island"; + break; + case 1624: + name = "South Carolina"; + break; + case 1625: + name = "South Dakota"; + break; + case 1678: + name = "Tennessee"; + break; + case 1688: + name = "Texas"; + break; + case 1727: + name = "Utah"; + break; + case 1751: + name = "Virginia"; + break; + case 1759: + name = "Virgin Islands"; + break; + case 1770: + name = "Vermont"; + break; + case 1794: + name = "Washington"; + break; + case 1815: + name = "West Virginia"; + break; + case 1802: + name = "Wisconsin"; + break; + case 1818: + name = "Wyoming"; + break; + } + } + if (strcmp(country_code,"AD") == 0) { + switch (region_code2) { + case 2: + name = "Canillo"; + break; + case 3: + name = "Encamp"; + break; + case 4: + name = "La Massana"; + break; + case 5: + name = "Ordino"; + break; + case 6: + name = "Sant Julia de Loria"; + break; + case 7: + name = "Andorra la Vella"; + break; + case 8: + name = "Escaldes-Engordany"; + break; + } + } + if (strcmp(country_code,"AE") == 0) { + switch (region_code2) { + case 1: + name = "Abu Dhabi"; + break; + case 2: + name = "Ajman"; + break; + case 3: + name = "Dubai"; + break; + case 4: + name = "Fujairah"; + break; + case 5: + name = "Ras Al Khaimah"; + break; + case 6: + name = "Sharjah"; + break; + case 7: + name = "Umm Al Quwain"; + break; + } + } + if (strcmp(country_code,"AF") == 0) { + switch (region_code2) { + case 1: + name = "Badakhshan"; + break; + case 2: + name = "Badghis"; + break; + case 3: + name = "Baghlan"; + break; + case 5: + name = "Bamian"; + break; + case 6: + name = "Farah"; + break; + case 7: + name = "Faryab"; + break; + case 8: + name = "Ghazni"; + break; + case 9: + name = "Ghowr"; + break; + case 10: + name = "Helmand"; + break; + case 11: + name = "Herat"; + break; + case 13: + name = "Kabol"; + break; + case 14: + name = "Kapisa"; + break; + case 17: + name = "Lowgar"; + break; + case 18: + name = "Nangarhar"; + break; + case 19: + name = "Nimruz"; + break; + case 23: + name = "Kandahar"; + break; + case 24: + name = "Kondoz"; + break; + case 26: + name = "Takhar"; + break; + case 27: + name = "Vardak"; + break; + case 28: + name = "Zabol"; + break; + case 29: + name = "Paktika"; + break; + case 30: + name = "Balkh"; + break; + case 31: + name = "Jowzjan"; + break; + case 32: + name = "Samangan"; + break; + case 33: + name = "Sar-e Pol"; + break; + case 34: + name = "Konar"; + break; + case 35: + name = "Laghman"; + break; + case 36: + name = "Paktia"; + break; + case 37: + name = "Khowst"; + break; + case 38: + name = "Nurestan"; + break; + case 39: + name = "Oruzgan"; + break; + case 40: + name = "Parvan"; + break; + case 41: + name = "Daykondi"; + break; + case 42: + name = "Panjshir"; + break; + } + } + if (strcmp(country_code,"AG") == 0) { + switch (region_code2) { + case 1: + name = "Barbuda"; + break; + case 3: + name = "Saint George"; + break; + case 4: + name = "Saint John"; + break; + case 5: + name = "Saint Mary"; + break; + case 6: + name = "Saint Paul"; + break; + case 7: + name = "Saint Peter"; + break; + case 8: + name = "Saint Philip"; + break; + case 9: + name = "Redonda"; + break; + } + } + if (strcmp(country_code,"AL") == 0) { + switch (region_code2) { + case 40: + name = "Berat"; + break; + case 41: + name = "Diber"; + break; + case 42: + name = "Durres"; + break; + case 43: + name = "Elbasan"; + break; + case 44: + name = "Fier"; + break; + case 45: + name = "Gjirokaster"; + break; + case 46: + name = "Korce"; + break; + case 47: + name = "Kukes"; + break; + case 48: + name = "Lezhe"; + break; + case 49: + name = "Shkoder"; + break; + case 50: + name = "Tirane"; + break; + case 51: + name = "Vlore"; + break; + } + } + if (strcmp(country_code,"AM") == 0) { + switch (region_code2) { + case 1: + name = "Aragatsotn"; + break; + case 2: + name = "Ararat"; + break; + case 3: + name = "Armavir"; + break; + case 4: + name = "Geghark'unik'"; + break; + case 5: + name = "Kotayk'"; + break; + case 6: + name = "Lorri"; + break; + case 7: + name = "Shirak"; + break; + case 8: + name = "Syunik'"; + break; + case 9: + name = "Tavush"; + break; + case 10: + name = "Vayots' Dzor"; + break; + case 11: + name = "Yerevan"; + break; + } + } + if (strcmp(country_code,"AO") == 0) { + switch (region_code2) { + case 1: + name = "Benguela"; + break; + case 2: + name = "Bie"; + break; + case 3: + name = "Cabinda"; + break; + case 4: + name = "Cuando Cubango"; + break; + case 5: + name = "Cuanza Norte"; + break; + case 6: + name = "Cuanza Sul"; + break; + case 7: + name = "Cunene"; + break; + case 8: + name = "Huambo"; + break; + case 9: + name = "Huila"; + break; + case 12: + name = "Malanje"; + break; + case 13: + name = "Namibe"; + break; + case 14: + name = "Moxico"; + break; + case 15: + name = "Uige"; + break; + case 16: + name = "Zaire"; + break; + case 17: + name = "Lunda Norte"; + break; + case 18: + name = "Lunda Sul"; + break; + case 19: + name = "Bengo"; + break; + case 20: + name = "Luanda"; + break; + } + } + if (strcmp(country_code,"AR") == 0) { + switch (region_code2) { + case 1: + name = "Buenos Aires"; + break; + case 2: + name = "Catamarca"; + break; + case 3: + name = "Chaco"; + break; + case 4: + name = "Chubut"; + break; + case 5: + name = "Cordoba"; + break; + case 6: + name = "Corrientes"; + break; + case 7: + name = "Distrito Federal"; + break; + case 8: + name = "Entre Rios"; + break; + case 9: + name = "Formosa"; + break; + case 10: + name = "Jujuy"; + break; + case 11: + name = "La Pampa"; + break; + case 12: + name = "La Rioja"; + break; + case 13: + name = "Mendoza"; + break; + case 14: + name = "Misiones"; + break; + case 15: + name = "Neuquen"; + break; + case 16: + name = "Rio Negro"; + break; + case 17: + name = "Salta"; + break; + case 18: + name = "San Juan"; + break; + case 19: + name = "San Luis"; + break; + case 20: + name = "Santa Cruz"; + break; + case 21: + name = "Santa Fe"; + break; + case 22: + name = "Santiago del Estero"; + break; + case 23: + name = "Tierra del Fuego"; + break; + case 24: + name = "Tucuman"; + break; + } + } + if (strcmp(country_code,"AT") == 0) { + switch (region_code2) { + case 1: + name = "Burgenland"; + break; + case 2: + name = "Karnten"; + break; + case 3: + name = "Niederosterreich"; + break; + case 4: + name = "Oberosterreich"; + break; + case 5: + name = "Salzburg"; + break; + case 6: + name = "Steiermark"; + break; + case 7: + name = "Tirol"; + break; + case 8: + name = "Vorarlberg"; + break; + case 9: + name = "Wien"; + break; + } + } + if (strcmp(country_code,"AU") == 0) { + switch (region_code2) { + case 1: + name = "Australian Capital Territory"; + break; + case 2: + name = "New South Wales"; + break; + case 3: + name = "Northern Territory"; + break; + case 4: + name = "Queensland"; + break; + case 5: + name = "South Australia"; + break; + case 6: + name = "Tasmania"; + break; + case 7: + name = "Victoria"; + break; + case 8: + name = "Western Australia"; + break; + } + } + if (strcmp(country_code,"AZ") == 0) { + switch (region_code2) { + case 1: + name = "Abseron"; + break; + case 2: + name = "Agcabadi"; + break; + case 3: + name = "Agdam"; + break; + case 4: + name = "Agdas"; + break; + case 5: + name = "Agstafa"; + break; + case 6: + name = "Agsu"; + break; + case 7: + name = "Ali Bayramli"; + break; + case 8: + name = "Astara"; + break; + case 9: + name = "Baki"; + break; + case 10: + name = "Balakan"; + break; + case 11: + name = "Barda"; + break; + case 12: + name = "Beylaqan"; + break; + case 13: + name = "Bilasuvar"; + break; + case 14: + name = "Cabrayil"; + break; + case 15: + name = "Calilabad"; + break; + case 16: + name = "Daskasan"; + break; + case 17: + name = "Davaci"; + break; + case 18: + name = "Fuzuli"; + break; + case 19: + name = "Gadabay"; + break; + case 20: + name = "Ganca"; + break; + case 21: + name = "Goranboy"; + break; + case 22: + name = "Goycay"; + break; + case 23: + name = "Haciqabul"; + break; + case 24: + name = "Imisli"; + break; + case 25: + name = "Ismayilli"; + break; + case 26: + name = "Kalbacar"; + break; + case 27: + name = "Kurdamir"; + break; + case 28: + name = "Lacin"; + break; + case 29: + name = "Lankaran"; + break; + case 30: + name = "Lankaran"; + break; + case 31: + name = "Lerik"; + break; + case 32: + name = "Masalli"; + break; + case 33: + name = "Mingacevir"; + break; + case 34: + name = "Naftalan"; + break; + case 35: + name = "Naxcivan"; + break; + case 36: + name = "Neftcala"; + break; + case 37: + name = "Oguz"; + break; + case 38: + name = "Qabala"; + break; + case 39: + name = "Qax"; + break; + case 40: + name = "Qazax"; + break; + case 41: + name = "Qobustan"; + break; + case 42: + name = "Quba"; + break; + case 43: + name = "Qubadli"; + break; + case 44: + name = "Qusar"; + break; + case 45: + name = "Saatli"; + break; + case 46: + name = "Sabirabad"; + break; + case 47: + name = "Saki"; + break; + case 48: + name = "Saki"; + break; + case 49: + name = "Salyan"; + break; + case 50: + name = "Samaxi"; + break; + case 51: + name = "Samkir"; + break; + case 52: + name = "Samux"; + break; + case 53: + name = "Siyazan"; + break; + case 54: + name = "Sumqayit"; + break; + case 55: + name = "Susa"; + break; + case 56: + name = "Susa"; + break; + case 57: + name = "Tartar"; + break; + case 58: + name = "Tovuz"; + break; + case 59: + name = "Ucar"; + break; + case 60: + name = "Xacmaz"; + break; + case 61: + name = "Xankandi"; + break; + case 62: + name = "Xanlar"; + break; + case 63: + name = "Xizi"; + break; + case 64: + name = "Xocali"; + break; + case 65: + name = "Xocavand"; + break; + case 66: + name = "Yardimli"; + break; + case 67: + name = "Yevlax"; + break; + case 68: + name = "Yevlax"; + break; + case 69: + name = "Zangilan"; + break; + case 70: + name = "Zaqatala"; + break; + case 71: + name = "Zardab"; + break; + } + } + if (strcmp(country_code,"BA") == 0) { + switch (region_code2) { + case 1: + name = "Federation of Bosnia and Herzegovina"; + break; + case 2: + name = "Republika Srpska"; + break; + } + } + if (strcmp(country_code,"BB") == 0) { + switch (region_code2) { + case 1: + name = "Christ Church"; + break; + case 2: + name = "Saint Andrew"; + break; + case 3: + name = "Saint George"; + break; + case 4: + name = "Saint James"; + break; + case 5: + name = "Saint John"; + break; + case 6: + name = "Saint Joseph"; + break; + case 7: + name = "Saint Lucy"; + break; + case 8: + name = "Saint Michael"; + break; + case 9: + name = "Saint Peter"; + break; + case 10: + name = "Saint Philip"; + break; + case 11: + name = "Saint Thomas"; + break; + } + } + if (strcmp(country_code,"BD") == 0) { + switch (region_code2) { + case 81: + name = "Dhaka"; + break; + case 82: + name = "Khulna"; + break; + case 83: + name = "Rajshahi"; + break; + case 84: + name = "Chittagong"; + break; + case 85: + name = "Barisal"; + break; + case 86: + name = "Sylhet"; + break; + } + } + if (strcmp(country_code,"BE") == 0) { + switch (region_code2) { + case 1: + name = "Antwerpen"; + break; + case 3: + name = "Hainaut"; + break; + case 4: + name = "Liege"; + break; + case 5: + name = "Limburg"; + break; + case 6: + name = "Luxembourg"; + break; + case 7: + name = "Namur"; + break; + case 8: + name = "Oost-Vlaanderen"; + break; + case 9: + name = "West-Vlaanderen"; + break; + case 10: + name = "Brabant Wallon"; + break; + case 11: + name = "Brussels Hoofdstedelijk Gewest"; + break; + case 12: + name = "Vlaams-Brabant"; + break; + } + } + if (strcmp(country_code,"BF") == 0) { + switch (region_code2) { + case 15: + name = "Bam"; + break; + case 19: + name = "Boulkiemde"; + break; + case 20: + name = "Ganzourgou"; + break; + case 21: + name = "Gnagna"; + break; + case 28: + name = "Kouritenga"; + break; + case 33: + name = "Oudalan"; + break; + case 34: + name = "Passore"; + break; + case 36: + name = "Sanguie"; + break; + case 40: + name = "Soum"; + break; + case 42: + name = "Tapoa"; + break; + case 44: + name = "Zoundweogo"; + break; + case 45: + name = "Bale"; + break; + case 46: + name = "Banwa"; + break; + case 47: + name = "Bazega"; + break; + case 48: + name = "Bougouriba"; + break; + case 49: + name = "Boulgou"; + break; + case 50: + name = "Gourma"; + break; + case 51: + name = "Houet"; + break; + case 52: + name = "Ioba"; + break; + case 53: + name = "Kadiogo"; + break; + case 54: + name = "Kenedougou"; + break; + case 55: + name = "Komoe"; + break; + case 56: + name = "Komondjari"; + break; + case 57: + name = "Kompienga"; + break; + case 58: + name = "Kossi"; + break; + case 59: + name = "Koulpelogo"; + break; + case 60: + name = "Kourweogo"; + break; + case 61: + name = "Leraba"; + break; + case 62: + name = "Loroum"; + break; + case 63: + name = "Mouhoun"; + break; + case 64: + name = "Namentenga"; + break; + case 65: + name = "Naouri"; + break; + case 66: + name = "Nayala"; + break; + case 67: + name = "Noumbiel"; + break; + case 68: + name = "Oubritenga"; + break; + case 69: + name = "Poni"; + break; + case 70: + name = "Sanmatenga"; + break; + case 71: + name = "Seno"; + break; + case 72: + name = "Sissili"; + break; + case 73: + name = "Sourou"; + break; + case 74: + name = "Tuy"; + break; + case 75: + name = "Yagha"; + break; + case 76: + name = "Yatenga"; + break; + case 77: + name = "Ziro"; + break; + case 78: + name = "Zondoma"; + break; + } + } + if (strcmp(country_code,"BG") == 0) { + switch (region_code2) { + case 33: + name = "Mikhaylovgrad"; + break; + case 38: + name = "Blagoevgrad"; + break; + case 39: + name = "Burgas"; + break; + case 40: + name = "Dobrich"; + break; + case 41: + name = "Gabrovo"; + break; + case 42: + name = "Grad Sofiya"; + break; + case 43: + name = "Khaskovo"; + break; + case 44: + name = "Kurdzhali"; + break; + case 45: + name = "Kyustendil"; + break; + case 46: + name = "Lovech"; + break; + case 47: + name = "Montana"; + break; + case 48: + name = "Pazardzhik"; + break; + case 49: + name = "Pernik"; + break; + case 50: + name = "Pleven"; + break; + case 51: + name = "Plovdiv"; + break; + case 52: + name = "Razgrad"; + break; + case 53: + name = "Ruse"; + break; + case 54: + name = "Shumen"; + break; + case 55: + name = "Silistra"; + break; + case 56: + name = "Sliven"; + break; + case 57: + name = "Smolyan"; + break; + case 58: + name = "Sofiya"; + break; + case 59: + name = "Stara Zagora"; + break; + case 60: + name = "Turgovishte"; + break; + case 61: + name = "Varna"; + break; + case 62: + name = "Veliko Turnovo"; + break; + case 63: + name = "Vidin"; + break; + case 64: + name = "Vratsa"; + break; + case 65: + name = "Yambol"; + break; + } + } + if (strcmp(country_code,"BH") == 0) { + switch (region_code2) { + case 1: + name = "Al Hadd"; + break; + case 2: + name = "Al Manamah"; + break; + case 5: + name = "Jidd Hafs"; + break; + case 6: + name = "Sitrah"; + break; + case 8: + name = "Al Mintaqah al Gharbiyah"; + break; + case 9: + name = "Mintaqat Juzur Hawar"; + break; + case 10: + name = "Al Mintaqah ash Shamaliyah"; + break; + case 11: + name = "Al Mintaqah al Wusta"; + break; + case 12: + name = "Madinat"; + break; + case 13: + name = "Ar Rifa"; + break; + case 14: + name = "Madinat Hamad"; + break; + case 15: + name = "Al Muharraq"; + break; + case 16: + name = "Al Asimah"; + break; + case 17: + name = "Al Janubiyah"; + break; + case 18: + name = "Ash Shamaliyah"; + break; + case 19: + name = "Al Wusta"; + break; + } + } + if (strcmp(country_code,"BI") == 0) { + switch (region_code2) { + case 2: + name = "Bujumbura"; + break; + case 9: + name = "Bubanza"; + break; + case 10: + name = "Bururi"; + break; + case 11: + name = "Cankuzo"; + break; + case 12: + name = "Cibitoke"; + break; + case 13: + name = "Gitega"; + break; + case 14: + name = "Karuzi"; + break; + case 15: + name = "Kayanza"; + break; + case 16: + name = "Kirundo"; + break; + case 17: + name = "Makamba"; + break; + case 18: + name = "Muyinga"; + break; + case 19: + name = "Ngozi"; + break; + case 20: + name = "Rutana"; + break; + case 21: + name = "Ruyigi"; + break; + case 22: + name = "Muramvya"; + break; + case 23: + name = "Mwaro"; + break; + } + } + if (strcmp(country_code,"BJ") == 0) { + switch (region_code2) { + case 7: + name = "Alibori"; + break; + case 8: + name = "Atakora"; + break; + case 9: + name = "Atlanyique"; + break; + case 10: + name = "Borgou"; + break; + case 11: + name = "Collines"; + break; + case 12: + name = "Kouffo"; + break; + case 13: + name = "Donga"; + break; + case 14: + name = "Littoral"; + break; + case 15: + name = "Mono"; + break; + case 16: + name = "Oueme"; + break; + case 17: + name = "Plateau"; + break; + case 18: + name = "Zou"; + break; + } + } + if (strcmp(country_code,"BM") == 0) { + switch (region_code2) { + case 1: + name = "Devonshire"; + break; + case 2: + name = "Hamilton"; + break; + case 3: + name = "Hamilton"; + break; + case 4: + name = "Paget"; + break; + case 5: + name = "Pembroke"; + break; + case 6: + name = "Saint George"; + break; + case 7: + name = "Saint George's"; + break; + case 8: + name = "Sandys"; + break; + case 9: + name = "Smiths"; + break; + case 10: + name = "Southampton"; + break; + case 11: + name = "Warwick"; + break; + } + } + if (strcmp(country_code,"BN") == 0) { + switch (region_code2) { + case 7: + name = "Alibori"; + break; + case 8: + name = "Belait"; + break; + case 9: + name = "Brunei and Muara"; + break; + case 10: + name = "Temburong"; + break; + case 11: + name = "Collines"; + break; + case 12: + name = "Kouffo"; + break; + case 13: + name = "Donga"; + break; + case 14: + name = "Littoral"; + break; + case 15: + name = "Tutong"; + break; + case 16: + name = "Oueme"; + break; + case 17: + name = "Plateau"; + break; + case 18: + name = "Zou"; + break; + } + } + if (strcmp(country_code,"BO") == 0) { + switch (region_code2) { + case 1: + name = "Chuquisaca"; + break; + case 2: + name = "Cochabamba"; + break; + case 3: + name = "El Beni"; + break; + case 4: + name = "La Paz"; + break; + case 5: + name = "Oruro"; + break; + case 6: + name = "Pando"; + break; + case 7: + name = "Potosi"; + break; + case 8: + name = "Santa Cruz"; + break; + case 9: + name = "Tarija"; + break; + } + } + if (strcmp(country_code,"BR") == 0) { + switch (region_code2) { + case 1: + name = "Acre"; + break; + case 2: + name = "Alagoas"; + break; + case 3: + name = "Amapa"; + break; + case 4: + name = "Amazonas"; + break; + case 5: + name = "Bahia"; + break; + case 6: + name = "Ceara"; + break; + case 7: + name = "Distrito Federal"; + break; + case 8: + name = "Espirito Santo"; + break; + case 11: + name = "Mato Grosso do Sul"; + break; + case 13: + name = "Maranhao"; + break; + case 14: + name = "Mato Grosso"; + break; + case 15: + name = "Minas Gerais"; + break; + case 16: + name = "Para"; + break; + case 17: + name = "Paraiba"; + break; + case 18: + name = "Parana"; + break; + case 20: + name = "Piaui"; + break; + case 21: + name = "Rio de Janeiro"; + break; + case 22: + name = "Rio Grande do Norte"; + break; + case 23: + name = "Rio Grande do Sul"; + break; + case 24: + name = "Rondonia"; + break; + case 25: + name = "Roraima"; + break; + case 26: + name = "Santa Catarina"; + break; + case 27: + name = "Sao Paulo"; + break; + case 28: + name = "Sergipe"; + break; + case 29: + name = "Goias"; + break; + case 30: + name = "Pernambuco"; + break; + case 31: + name = "Tocantins"; + break; + } + } + if (strcmp(country_code,"BS") == 0) { + switch (region_code2) { + case 5: + name = "Bimini"; + break; + case 6: + name = "Cat Island"; + break; + case 10: + name = "Exuma"; + break; + case 13: + name = "Inagua"; + break; + case 15: + name = "Long Island"; + break; + case 16: + name = "Mayaguana"; + break; + case 18: + name = "Ragged Island"; + break; + case 22: + name = "Harbour Island"; + break; + case 23: + name = "New Providence"; + break; + case 24: + name = "Acklins and Crooked Islands"; + break; + case 25: + name = "Freeport"; + break; + case 26: + name = "Fresh Creek"; + break; + case 27: + name = "Governor's Harbour"; + break; + case 28: + name = "Green Turtle Cay"; + break; + case 29: + name = "High Rock"; + break; + case 30: + name = "Kemps Bay"; + break; + case 31: + name = "Marsh Harbour"; + break; + case 32: + name = "Nichollstown and Berry Islands"; + break; + case 33: + name = "Rock Sound"; + break; + case 34: + name = "Sandy Point"; + break; + case 35: + name = "San Salvador and Rum Cay"; + break; + } + } + if (strcmp(country_code,"BT") == 0) { + switch (region_code2) { + case 5: + name = "Bumthang"; + break; + case 6: + name = "Chhukha"; + break; + case 7: + name = "Chirang"; + break; + case 8: + name = "Daga"; + break; + case 9: + name = "Geylegphug"; + break; + case 10: + name = "Ha"; + break; + case 11: + name = "Lhuntshi"; + break; + case 12: + name = "Mongar"; + break; + case 13: + name = "Paro"; + break; + case 14: + name = "Pemagatsel"; + break; + case 15: + name = "Punakha"; + break; + case 16: + name = "Samchi"; + break; + case 17: + name = "Samdrup"; + break; + case 18: + name = "Shemgang"; + break; + case 19: + name = "Tashigang"; + break; + case 20: + name = "Thimphu"; + break; + case 21: + name = "Tongsa"; + break; + case 22: + name = "Wangdi Phodrang"; + break; + } + } + if (strcmp(country_code,"BW") == 0) { + switch (region_code2) { + case 1: + name = "Central"; + break; + case 3: + name = "Ghanzi"; + break; + case 4: + name = "Kgalagadi"; + break; + case 5: + name = "Kgatleng"; + break; + case 6: + name = "Kweneng"; + break; + case 8: + name = "North-East"; + break; + case 9: + name = "South-East"; + break; + case 10: + name = "Southern"; + break; + case 11: + name = "North-West"; + break; + } + } + if (strcmp(country_code,"BY") == 0) { + switch (region_code2) { + case 1: + name = "Brestskaya Voblasts'"; + break; + case 2: + name = "Homyel'skaya Voblasts'"; + break; + case 3: + name = "Hrodzyenskaya Voblasts'"; + break; + case 4: + name = "Minsk"; + break; + case 5: + name = "Minskaya Voblasts'"; + break; + case 6: + name = "Mahilyowskaya Voblasts'"; + break; + case 7: + name = "Vitsyebskaya Voblasts'"; + break; + } + } + if (strcmp(country_code,"BZ") == 0) { + switch (region_code2) { + case 1: + name = "Belize"; + break; + case 2: + name = "Cayo"; + break; + case 3: + name = "Corozal"; + break; + case 4: + name = "Orange Walk"; + break; + case 5: + name = "Stann Creek"; + break; + case 6: + name = "Toledo"; + break; + } + } + if (strcmp(country_code,"CD") == 0) { + switch (region_code2) { + case 1: + name = "Bandundu"; + break; + case 2: + name = "Equateur"; + break; + case 4: + name = "Kasai-Oriental"; + break; + case 5: + name = "Katanga"; + break; + case 6: + name = "Kinshasa"; + break; + case 8: + name = "Bas-Congo"; + break; + case 9: + name = "Orientale"; + break; + case 10: + name = "Maniema"; + break; + case 11: + name = "Nord-Kivu"; + break; + case 12: + name = "Sud-Kivu"; + break; + } + } + if (strcmp(country_code,"CF") == 0) { + switch (region_code2) { + case 1: + name = "Bamingui-Bangoran"; + break; + case 2: + name = "Basse-Kotto"; + break; + case 3: + name = "Haute-Kotto"; + break; + case 4: + name = "Mambere-Kadei"; + break; + case 5: + name = "Haut-Mbomou"; + break; + case 6: + name = "Kemo"; + break; + case 7: + name = "Lobaye"; + break; + case 8: + name = "Mbomou"; + break; + case 9: + name = "Nana-Mambere"; + break; + case 11: + name = "Ouaka"; + break; + case 12: + name = "Ouham"; + break; + case 13: + name = "Ouham-Pende"; + break; + case 14: + name = "Cuvette-Ouest"; + break; + case 15: + name = "Nana-Grebizi"; + break; + case 16: + name = "Sangha-Mbaere"; + break; + case 17: + name = "Ombella-Mpoko"; + break; + case 18: + name = "Bangui"; + break; + } + } + if (strcmp(country_code,"CG") == 0) { + switch (region_code2) { + case 1: + name = "Bouenza"; + break; + case 4: + name = "Kouilou"; + break; + case 5: + name = "Lekoumou"; + break; + case 6: + name = "Likouala"; + break; + case 7: + name = "Niari"; + break; + case 8: + name = "Plateaux"; + break; + case 10: + name = "Sangha"; + break; + case 11: + name = "Pool"; + break; + case 12: + name = "Brazzaville"; + break; + case 13: + name = "Cuvette"; + break; + case 14: + name = "Cuvette-Ouest"; + break; + } + } + if (strcmp(country_code,"CH") == 0) { + switch (region_code2) { + case 1: + name = "Aargau"; + break; + case 2: + name = "Ausser-Rhoden"; + break; + case 3: + name = "Basel-Landschaft"; + break; + case 4: + name = "Basel-Stadt"; + break; + case 5: + name = "Bern"; + break; + case 6: + name = "Fribourg"; + break; + case 7: + name = "Geneve"; + break; + case 8: + name = "Glarus"; + break; + case 9: + name = "Graubunden"; + break; + case 10: + name = "Inner-Rhoden"; + break; + case 11: + name = "Luzern"; + break; + case 12: + name = "Neuchatel"; + break; + case 13: + name = "Nidwalden"; + break; + case 14: + name = "Obwalden"; + break; + case 15: + name = "Sankt Gallen"; + break; + case 16: + name = "Schaffhausen"; + break; + case 17: + name = "Schwyz"; + break; + case 18: + name = "Solothurn"; + break; + case 19: + name = "Thurgau"; + break; + case 20: + name = "Ticino"; + break; + case 21: + name = "Uri"; + break; + case 22: + name = "Valais"; + break; + case 23: + name = "Vaud"; + break; + case 24: + name = "Zug"; + break; + case 25: + name = "Zurich"; + break; + case 26: + name = "Jura"; + break; + } + } + if (strcmp(country_code,"CI") == 0) { + switch (region_code2) { + case 74: + name = "Agneby"; + break; + case 75: + name = "Bafing"; + break; + case 76: + name = "Bas-Sassandra"; + break; + case 77: + name = "Denguele"; + break; + case 78: + name = "Dix-Huit Montagnes"; + break; + case 79: + name = "Fromager"; + break; + case 80: + name = "Haut-Sassandra"; + break; + case 81: + name = "Lacs"; + break; + case 82: + name = "Lagunes"; + break; + case 83: + name = "Marahoue"; + break; + case 84: + name = "Moyen-Cavally"; + break; + case 85: + name = "Moyen-Comoe"; + break; + case 86: + name = "N'zi-Comoe"; + break; + case 87: + name = "Savanes"; + break; + case 88: + name = "Sud-Bandama"; + break; + case 89: + name = "Sud-Comoe"; + break; + case 90: + name = "Vallee du Bandama"; + break; + case 91: + name = "Worodougou"; + break; + case 92: + name = "Zanzan"; + break; + } + } + if (strcmp(country_code,"CL") == 0) { + switch (region_code2) { + case 1: + name = "Valparaiso"; + break; + case 2: + name = "Aisen del General Carlos Ibanez del Campo"; + break; + case 3: + name = "Antofagasta"; + break; + case 4: + name = "Araucania"; + break; + case 5: + name = "Atacama"; + break; + case 6: + name = "Bio-Bio"; + break; + case 7: + name = "Coquimbo"; + break; + case 8: + name = "Libertador General Bernardo O'Higgins"; + break; + case 9: + name = "Los Lagos"; + break; + case 10: + name = "Magallanes y de la Antartica Chilena"; + break; + case 11: + name = "Maule"; + break; + case 12: + name = "Region Metropolitana"; + break; + case 13: + name = "Tarapaca"; + break; + case 14: + name = "Los Lagos"; + break; + case 15: + name = "Tarapaca"; + break; + case 16: + name = "Arica y Parinacota"; + break; + case 17: + name = "Los Rios"; + break; + } + } + if (strcmp(country_code,"CM") == 0) { + switch (region_code2) { + case 4: + name = "Est"; + break; + case 5: + name = "Littoral"; + break; + case 7: + name = "Nord-Ouest"; + break; + case 8: + name = "Ouest"; + break; + case 9: + name = "Sud-Ouest"; + break; + case 10: + name = "Adamaoua"; + break; + case 11: + name = "Centre"; + break; + case 12: + name = "Extreme-Nord"; + break; + case 13: + name = "Nord"; + break; + case 14: + name = "Sud"; + break; + } + } + if (strcmp(country_code,"CN") == 0) { + switch (region_code2) { + case 1: + name = "Anhui"; + break; + case 2: + name = "Zhejiang"; + break; + case 3: + name = "Jiangxi"; + break; + case 4: + name = "Jiangsu"; + break; + case 5: + name = "Jilin"; + break; + case 6: + name = "Qinghai"; + break; + case 7: + name = "Fujian"; + break; + case 8: + name = "Heilongjiang"; + break; + case 9: + name = "Henan"; + break; + case 10: + name = "Hebei"; + break; + case 11: + name = "Hunan"; + break; + case 12: + name = "Hubei"; + break; + case 13: + name = "Xinjiang"; + break; + case 14: + name = "Xizang"; + break; + case 15: + name = "Gansu"; + break; + case 16: + name = "Guangxi"; + break; + case 18: + name = "Guizhou"; + break; + case 19: + name = "Liaoning"; + break; + case 20: + name = "Nei Mongol"; + break; + case 21: + name = "Ningxia"; + break; + case 22: + name = "Beijing"; + break; + case 23: + name = "Shanghai"; + break; + case 24: + name = "Shanxi"; + break; + case 25: + name = "Shandong"; + break; + case 26: + name = "Shaanxi"; + break; + case 28: + name = "Tianjin"; + break; + case 29: + name = "Yunnan"; + break; + case 30: + name = "Guangdong"; + break; + case 31: + name = "Hainan"; + break; + case 32: + name = "Sichuan"; + break; + case 33: + name = "Chongqing"; + break; + } + } + if (strcmp(country_code,"CO") == 0) { + switch (region_code2) { + case 1: + name = "Amazonas"; + break; + case 2: + name = "Antioquia"; + break; + case 3: + name = "Arauca"; + break; + case 4: + name = "Atlantico"; + break; + case 5: + name = "Bolivar Department"; + break; + case 6: + name = "Boyaca Department"; + break; + case 7: + name = "Caldas Department"; + break; + case 8: + name = "Caqueta"; + break; + case 9: + name = "Cauca"; + break; + case 10: + name = "Cesar"; + break; + case 11: + name = "Choco"; + break; + case 12: + name = "Cordoba"; + break; + case 14: + name = "Guaviare"; + break; + case 15: + name = "Guainia"; + break; + case 16: + name = "Huila"; + break; + case 17: + name = "La Guajira"; + break; + case 18: + name = "Magdalena Department"; + break; + case 19: + name = "Meta"; + break; + case 20: + name = "Narino"; + break; + case 21: + name = "Norte de Santander"; + break; + case 22: + name = "Putumayo"; + break; + case 23: + name = "Quindio"; + break; + case 24: + name = "Risaralda"; + break; + case 25: + name = "San Andres y Providencia"; + break; + case 26: + name = "Santander"; + break; + case 27: + name = "Sucre"; + break; + case 28: + name = "Tolima"; + break; + case 29: + name = "Valle del Cauca"; + break; + case 30: + name = "Vaupes"; + break; + case 31: + name = "Vichada"; + break; + case 32: + name = "Casanare"; + break; + case 33: + name = "Cundinamarca"; + break; + case 34: + name = "Distrito Especial"; + break; + case 35: + name = "Bolivar"; + break; + case 36: + name = "Boyaca"; + break; + case 37: + name = "Caldas"; + break; + case 38: + name = "Magdalena"; + break; + } + } + if (strcmp(country_code,"CR") == 0) { + switch (region_code2) { + case 1: + name = "Alajuela"; + break; + case 2: + name = "Cartago"; + break; + case 3: + name = "Guanacaste"; + break; + case 4: + name = "Heredia"; + break; + case 6: + name = "Limon"; + break; + case 7: + name = "Puntarenas"; + break; + case 8: + name = "San Jose"; + break; + } + } + if (strcmp(country_code,"CU") == 0) { + switch (region_code2) { + case 1: + name = "Pinar del Rio"; + break; + case 2: + name = "Ciudad de la Habana"; + break; + case 3: + name = "Matanzas"; + break; + case 4: + name = "Isla de la Juventud"; + break; + case 5: + name = "Camaguey"; + break; + case 7: + name = "Ciego de Avila"; + break; + case 8: + name = "Cienfuegos"; + break; + case 9: + name = "Granma"; + break; + case 10: + name = "Guantanamo"; + break; + case 11: + name = "La Habana"; + break; + case 12: + name = "Holguin"; + break; + case 13: + name = "Las Tunas"; + break; + case 14: + name = "Sancti Spiritus"; + break; + case 15: + name = "Santiago de Cuba"; + break; + case 16: + name = "Villa Clara"; + break; + } + } + if (strcmp(country_code,"CV") == 0) { + switch (region_code2) { + case 1: + name = "Boa Vista"; + break; + case 2: + name = "Brava"; + break; + case 4: + name = "Maio"; + break; + case 5: + name = "Paul"; + break; + case 7: + name = "Ribeira Grande"; + break; + case 8: + name = "Sal"; + break; + case 10: + name = "Sao Nicolau"; + break; + case 11: + name = "Sao Vicente"; + break; + case 13: + name = "Mosteiros"; + break; + case 14: + name = "Praia"; + break; + case 15: + name = "Santa Catarina"; + break; + case 16: + name = "Santa Cruz"; + break; + case 17: + name = "Sao Domingos"; + break; + case 18: + name = "Sao Filipe"; + break; + case 19: + name = "Sao Miguel"; + break; + case 20: + name = "Tarrafal"; + break; + } + } + if (strcmp(country_code,"CY") == 0) { + switch (region_code2) { + case 1: + name = "Famagusta"; + break; + case 2: + name = "Kyrenia"; + break; + case 3: + name = "Larnaca"; + break; + case 4: + name = "Nicosia"; + break; + case 5: + name = "Limassol"; + break; + case 6: + name = "Paphos"; + break; + } + } + if (strcmp(country_code,"CZ") == 0) { + switch (region_code2) { + case 52: + name = "Hlavni mesto Praha"; + break; + case 78: + name = "Jihomoravsky kraj"; + break; + case 79: + name = "Jihocesky kraj"; + break; + case 80: + name = "Vysocina"; + break; + case 81: + name = "Karlovarsky kraj"; + break; + case 82: + name = "Kralovehradecky kraj"; + break; + case 83: + name = "Liberecky kraj"; + break; + case 84: + name = "Olomoucky kraj"; + break; + case 85: + name = "Moravskoslezsky kraj"; + break; + case 86: + name = "Pardubicky kraj"; + break; + case 87: + name = "Plzensky kraj"; + break; + case 88: + name = "Stredocesky kraj"; + break; + case 89: + name = "Ustecky kraj"; + break; + case 90: + name = "Zlinsky kraj"; + break; + } + } + if (strcmp(country_code,"DE") == 0) { + switch (region_code2) { + case 1: + name = "Baden-Wurttemberg"; + break; + case 2: + name = "Bayern"; + break; + case 3: + name = "Bremen"; + break; + case 4: + name = "Hamburg"; + break; + case 5: + name = "Hessen"; + break; + case 6: + name = "Niedersachsen"; + break; + case 7: + name = "Nordrhein-Westfalen"; + break; + case 8: + name = "Rheinland-Pfalz"; + break; + case 9: + name = "Saarland"; + break; + case 10: + name = "Schleswig-Holstein"; + break; + case 11: + name = "Brandenburg"; + break; + case 12: + name = "Mecklenburg-Vorpommern"; + break; + case 13: + name = "Sachsen"; + break; + case 14: + name = "Sachsen-Anhalt"; + break; + case 15: + name = "Thuringen"; + break; + case 16: + name = "Berlin"; + break; + } + } + if (strcmp(country_code,"DJ") == 0) { + switch (region_code2) { + case 1: + name = "Ali Sabieh"; + break; + case 4: + name = "Obock"; + break; + case 5: + name = "Tadjoura"; + break; + case 6: + name = "Dikhil"; + break; + case 7: + name = "Djibouti"; + break; + case 8: + name = "Arta"; + break; + } + } + if (strcmp(country_code,"DK") == 0) { + switch (region_code2) { + case 17: + name = "Hovedstaden"; + break; + case 18: + name = "Midtjylland"; + break; + case 19: + name = "Nordjylland"; + break; + case 20: + name = "Sjelland"; + break; + case 21: + name = "Syddanmark"; + break; + } + } + if (strcmp(country_code,"DM") == 0) { + switch (region_code2) { + case 2: + name = "Saint Andrew"; + break; + case 3: + name = "Saint David"; + break; + case 4: + name = "Saint George"; + break; + case 5: + name = "Saint John"; + break; + case 6: + name = "Saint Joseph"; + break; + case 7: + name = "Saint Luke"; + break; + case 8: + name = "Saint Mark"; + break; + case 9: + name = "Saint Patrick"; + break; + case 10: + name = "Saint Paul"; + break; + case 11: + name = "Saint Peter"; + break; + } + } + if (strcmp(country_code,"DO") == 0) { + switch (region_code2) { + case 1: + name = "Azua"; + break; + case 2: + name = "Baoruco"; + break; + case 3: + name = "Barahona"; + break; + case 4: + name = "Dajabon"; + break; + case 5: + name = "Distrito Nacional"; + break; + case 6: + name = "Duarte"; + break; + case 8: + name = "Espaillat"; + break; + case 9: + name = "Independencia"; + break; + case 10: + name = "La Altagracia"; + break; + case 11: + name = "Elias Pina"; + break; + case 12: + name = "La Romana"; + break; + case 14: + name = "Maria Trinidad Sanchez"; + break; + case 15: + name = "Monte Cristi"; + break; + case 16: + name = "Pedernales"; + break; + case 17: + name = "Peravia"; + break; + case 18: + name = "Puerto Plata"; + break; + case 19: + name = "Salcedo"; + break; + case 20: + name = "Samana"; + break; + case 21: + name = "Sanchez Ramirez"; + break; + case 23: + name = "San Juan"; + break; + case 24: + name = "San Pedro De Macoris"; + break; + case 25: + name = "Santiago"; + break; + case 26: + name = "Santiago Rodriguez"; + break; + case 27: + name = "Valverde"; + break; + case 28: + name = "El Seibo"; + break; + case 29: + name = "Hato Mayor"; + break; + case 30: + name = "La Vega"; + break; + case 31: + name = "Monsenor Nouel"; + break; + case 32: + name = "Monte Plata"; + break; + case 33: + name = "San Cristobal"; + break; + case 34: + name = "Distrito Nacional"; + break; + case 35: + name = "Peravia"; + break; + case 36: + name = "San Jose de Ocoa"; + break; + case 37: + name = "Santo Domingo"; + break; + } + } + if (strcmp(country_code,"DZ") == 0) { + switch (region_code2) { + case 1: + name = "Alger"; + break; + case 3: + name = "Batna"; + break; + case 4: + name = "Constantine"; + break; + case 6: + name = "Medea"; + break; + case 7: + name = "Mostaganem"; + break; + case 9: + name = "Oran"; + break; + case 10: + name = "Saida"; + break; + case 12: + name = "Setif"; + break; + case 13: + name = "Tiaret"; + break; + case 14: + name = "Tizi Ouzou"; + break; + case 15: + name = "Tlemcen"; + break; + case 18: + name = "Bejaia"; + break; + case 19: + name = "Biskra"; + break; + case 20: + name = "Blida"; + break; + case 21: + name = "Bouira"; + break; + case 22: + name = "Djelfa"; + break; + case 23: + name = "Guelma"; + break; + case 24: + name = "Jijel"; + break; + case 25: + name = "Laghouat"; + break; + case 26: + name = "Mascara"; + break; + case 27: + name = "M'sila"; + break; + case 29: + name = "Oum el Bouaghi"; + break; + case 30: + name = "Sidi Bel Abbes"; + break; + case 31: + name = "Skikda"; + break; + case 33: + name = "Tebessa"; + break; + case 34: + name = "Adrar"; + break; + case 35: + name = "Ain Defla"; + break; + case 36: + name = "Ain Temouchent"; + break; + case 37: + name = "Annaba"; + break; + case 38: + name = "Bechar"; + break; + case 39: + name = "Bordj Bou Arreridj"; + break; + case 40: + name = "Boumerdes"; + break; + case 41: + name = "Chlef"; + break; + case 42: + name = "El Bayadh"; + break; + case 43: + name = "El Oued"; + break; + case 44: + name = "El Tarf"; + break; + case 45: + name = "Ghardaia"; + break; + case 46: + name = "Illizi"; + break; + case 47: + name = "Khenchela"; + break; + case 48: + name = "Mila"; + break; + case 49: + name = "Naama"; + break; + case 50: + name = "Ouargla"; + break; + case 51: + name = "Relizane"; + break; + case 52: + name = "Souk Ahras"; + break; + case 53: + name = "Tamanghasset"; + break; + case 54: + name = "Tindouf"; + break; + case 55: + name = "Tipaza"; + break; + case 56: + name = "Tissemsilt"; + break; + } + } + if (strcmp(country_code,"EC") == 0) { + switch (region_code2) { + case 1: + name = "Galapagos"; + break; + case 2: + name = "Azuay"; + break; + case 3: + name = "Bolivar"; + break; + case 4: + name = "Canar"; + break; + case 5: + name = "Carchi"; + break; + case 6: + name = "Chimborazo"; + break; + case 7: + name = "Cotopaxi"; + break; + case 8: + name = "El Oro"; + break; + case 9: + name = "Esmeraldas"; + break; + case 10: + name = "Guayas"; + break; + case 11: + name = "Imbabura"; + break; + case 12: + name = "Loja"; + break; + case 13: + name = "Los Rios"; + break; + case 14: + name = "Manabi"; + break; + case 15: + name = "Morona-Santiago"; + break; + case 17: + name = "Pastaza"; + break; + case 18: + name = "Pichincha"; + break; + case 19: + name = "Tungurahua"; + break; + case 20: + name = "Zamora-Chinchipe"; + break; + case 22: + name = "Sucumbios"; + break; + case 23: + name = "Napo"; + break; + case 24: + name = "Orellana"; + break; + } + } + if (strcmp(country_code,"EE") == 0) { + switch (region_code2) { + case 1: + name = "Harjumaa"; + break; + case 2: + name = "Hiiumaa"; + break; + case 3: + name = "Ida-Virumaa"; + break; + case 4: + name = "Jarvamaa"; + break; + case 5: + name = "Jogevamaa"; + break; + case 6: + name = "Kohtla-Jarve"; + break; + case 7: + name = "Laanemaa"; + break; + case 8: + name = "Laane-Virumaa"; + break; + case 9: + name = "Narva"; + break; + case 10: + name = "Parnu"; + break; + case 11: + name = "Parnumaa"; + break; + case 12: + name = "Polvamaa"; + break; + case 13: + name = "Raplamaa"; + break; + case 14: + name = "Saaremaa"; + break; + case 15: + name = "Sillamae"; + break; + case 16: + name = "Tallinn"; + break; + case 17: + name = "Tartu"; + break; + case 18: + name = "Tartumaa"; + break; + case 19: + name = "Valgamaa"; + break; + case 20: + name = "Viljandimaa"; + break; + case 21: + name = "Vorumaa"; + break; + } + } + if (strcmp(country_code,"EG") == 0) { + switch (region_code2) { + case 1: + name = "Ad Daqahliyah"; + break; + case 2: + name = "Al Bahr al Ahmar"; + break; + case 3: + name = "Al Buhayrah"; + break; + case 4: + name = "Al Fayyum"; + break; + case 5: + name = "Al Gharbiyah"; + break; + case 6: + name = "Al Iskandariyah"; + break; + case 7: + name = "Al Isma'iliyah"; + break; + case 8: + name = "Al Jizah"; + break; + case 9: + name = "Al Minufiyah"; + break; + case 10: + name = "Al Minya"; + break; + case 11: + name = "Al Qahirah"; + break; + case 12: + name = "Al Qalyubiyah"; + break; + case 13: + name = "Al Wadi al Jadid"; + break; + case 14: + name = "Ash Sharqiyah"; + break; + case 15: + name = "As Suways"; + break; + case 16: + name = "Aswan"; + break; + case 17: + name = "Asyut"; + break; + case 18: + name = "Bani Suwayf"; + break; + case 19: + name = "Bur Sa'id"; + break; + case 20: + name = "Dumyat"; + break; + case 21: + name = "Kafr ash Shaykh"; + break; + case 22: + name = "Matruh"; + break; + case 23: + name = "Qina"; + break; + case 24: + name = "Suhaj"; + break; + case 26: + name = "Janub Sina'"; + break; + case 27: + name = "Shamal Sina'"; + break; + } + } + if (strcmp(country_code,"ER") == 0) { + switch (region_code2) { + case 1: + name = "Anseba"; + break; + case 2: + name = "Debub"; + break; + case 3: + name = "Debubawi K'eyih Bahri"; + break; + case 4: + name = "Gash Barka"; + break; + case 5: + name = "Ma'akel"; + break; + case 6: + name = "Semenawi K'eyih Bahri"; + break; + } + } + if (strcmp(country_code,"ES") == 0) { + switch (region_code2) { + case 7: + name = "Islas Baleares"; + break; + case 27: + name = "La Rioja"; + break; + case 29: + name = "Madrid"; + break; + case 31: + name = "Murcia"; + break; + case 32: + name = "Navarra"; + break; + case 34: + name = "Asturias"; + break; + case 39: + name = "Cantabria"; + break; + case 51: + name = "Andalucia"; + break; + case 52: + name = "Aragon"; + break; + case 53: + name = "Canarias"; + break; + case 54: + name = "Castilla-La Mancha"; + break; + case 55: + name = "Castilla y Leon"; + break; + case 56: + name = "Catalonia"; + break; + case 57: + name = "Extremadura"; + break; + case 58: + name = "Galicia"; + break; + case 59: + name = "Pais Vasco"; + break; + case 60: + name = "Comunidad Valenciana"; + break; + } + } + if (strcmp(country_code,"ET") == 0) { + switch (region_code2) { + case 44: + name = "Adis Abeba"; + break; + case 45: + name = "Afar"; + break; + case 46: + name = "Amara"; + break; + case 47: + name = "Binshangul Gumuz"; + break; + case 48: + name = "Dire Dawa"; + break; + case 49: + name = "Gambela Hizboch"; + break; + case 50: + name = "Hareri Hizb"; + break; + case 51: + name = "Oromiya"; + break; + case 52: + name = "Sumale"; + break; + case 53: + name = "Tigray"; + break; + case 54: + name = "YeDebub Biheroch Bihereseboch na Hizboch"; + break; + } + } + if (strcmp(country_code,"FI") == 0) { + switch (region_code2) { + case 1: + name = "Aland"; + break; + case 6: + name = "Lapland"; + break; + case 8: + name = "Oulu"; + break; + case 13: + name = "Southern Finland"; + break; + case 14: + name = "Eastern Finland"; + break; + case 15: + name = "Western Finland"; + break; + } + } + if (strcmp(country_code,"FJ") == 0) { + switch (region_code2) { + case 1: + name = "Central"; + break; + case 2: + name = "Eastern"; + break; + case 3: + name = "Northern"; + break; + case 4: + name = "Rotuma"; + break; + case 5: + name = "Western"; + break; + } + } + if (strcmp(country_code,"FM") == 0) { + switch (region_code2) { + case 1: + name = "Kosrae"; + break; + case 2: + name = "Pohnpei"; + break; + case 3: + name = "Chuuk"; + break; + case 4: + name = "Yap"; + break; + } + } + if (strcmp(country_code,"FR") == 0) { + switch (region_code2) { + case 97: + name = "Aquitaine"; + break; + case 98: + name = "Auvergne"; + break; + case 99: + name = "Basse-Normandie"; + break; + case 832: + name = "Bourgogne"; + break; + case 833: + name = "Bretagne"; + break; + case 834: + name = "Centre"; + break; + case 835: + name = "Champagne-Ardenne"; + break; + case 836: + name = "Corse"; + break; + case 837: + name = "Franche-Comte"; + break; + case 838: + name = "Haute-Normandie"; + break; + case 839: + name = "Ile-de-France"; + break; + case 840: + name = "Languedoc-Roussillon"; + break; + case 875: + name = "Limousin"; + break; + case 876: + name = "Lorraine"; + break; + case 877: + name = "Midi-Pyrenees"; + break; + case 878: + name = "Nord-Pas-de-Calais"; + break; + case 879: + name = "Pays de la Loire"; + break; + case 880: + name = "Picardie"; + break; + case 881: + name = "Poitou-Charentes"; + break; + case 882: + name = "Provence-Alpes-Cote d'Azur"; + break; + case 883: + name = "Rhone-Alpes"; + break; + case 918: + name = "Alsace"; + break; + } + } + if (strcmp(country_code,"GA") == 0) { + switch (region_code2) { + case 1: + name = "Estuaire"; + break; + case 2: + name = "Haut-Ogooue"; + break; + case 3: + name = "Moyen-Ogooue"; + break; + case 4: + name = "Ngounie"; + break; + case 5: + name = "Nyanga"; + break; + case 6: + name = "Ogooue-Ivindo"; + break; + case 7: + name = "Ogooue-Lolo"; + break; + case 8: + name = "Ogooue-Maritime"; + break; + case 9: + name = "Woleu-Ntem"; + break; + } + } + if (strcmp(country_code,"GB") == 0) { + switch (region_code2) { + case 832: + name = "Barking and Dagenham"; + break; + case 833: + name = "Barnet"; + break; + case 834: + name = "Barnsley"; + break; + case 835: + name = "Bath and North East Somerset"; + break; + case 836: + name = "Bedfordshire"; + break; + case 837: + name = "Bexley"; + break; + case 838: + name = "Birmingham"; + break; + case 839: + name = "Blackburn with Darwen"; + break; + case 840: + name = "Blackpool"; + break; + case 875: + name = "Bolton"; + break; + case 876: + name = "Bournemouth"; + break; + case 877: + name = "Bracknell Forest"; + break; + case 878: + name = "Bradford"; + break; + case 879: + name = "Brent"; + break; + case 880: + name = "Brighton and Hove"; + break; + case 881: + name = "Bristol, City of"; + break; + case 882: + name = "Bromley"; + break; + case 883: + name = "Buckinghamshire"; + break; + case 918: + name = "Bury"; + break; + case 919: + name = "Calderdale"; + break; + case 920: + name = "Cambridgeshire"; + break; + case 921: + name = "Camden"; + break; + case 922: + name = "Cheshire"; + break; + case 923: + name = "Cornwall"; + break; + case 924: + name = "Coventry"; + break; + case 925: + name = "Croydon"; + break; + case 926: + name = "Cumbria"; + break; + case 961: + name = "Darlington"; + break; + case 962: + name = "Derby"; + break; + case 963: + name = "Derbyshire"; + break; + case 964: + name = "Devon"; + break; + case 965: + name = "Doncaster"; + break; + case 966: + name = "Dorset"; + break; + case 967: + name = "Dudley"; + break; + case 968: + name = "Durham"; + break; + case 969: + name = "Ealing"; + break; + case 1004: + name = "East Riding of Yorkshire"; + break; + case 1005: + name = "East Sussex"; + break; + case 1006: + name = "Enfield"; + break; + case 1007: + name = "Essex"; + break; + case 1008: + name = "Gateshead"; + break; + case 1009: + name = "Gloucestershire"; + break; + case 1010: + name = "Greenwich"; + break; + case 1011: + name = "Hackney"; + break; + case 1012: + name = "Halton"; + break; + case 1047: + name = "Hammersmith and Fulham"; + break; + case 1048: + name = "Hampshire"; + break; + case 1049: + name = "Haringey"; + break; + case 1050: + name = "Harrow"; + break; + case 1051: + name = "Hartlepool"; + break; + case 1052: + name = "Havering"; + break; + case 1053: + name = "Herefordshire"; + break; + case 1054: + name = "Hertford"; + break; + case 1055: + name = "Hillingdon"; + break; + case 1090: + name = "Hounslow"; + break; + case 1091: + name = "Isle of Wight"; + break; + case 1092: + name = "Islington"; + break; + case 1093: + name = "Kensington and Chelsea"; + break; + case 1094: + name = "Kent"; + break; + case 1095: + name = "Kingston upon Hull, City of"; + break; + case 1096: + name = "Kingston upon Thames"; + break; + case 1097: + name = "Kirklees"; + break; + case 1098: + name = "Knowsley"; + break; + case 1133: + name = "Lambeth"; + break; + case 1134: + name = "Lancashire"; + break; + case 1135: + name = "Leeds"; + break; + case 1136: + name = "Leicester"; + break; + case 1137: + name = "Leicestershire"; + break; + case 1138: + name = "Lewisham"; + break; + case 1139: + name = "Lincolnshire"; + break; + case 1140: + name = "Liverpool"; + break; + case 1141: + name = "London, City of"; + break; + case 1176: + name = "Luton"; + break; + case 1177: + name = "Manchester"; + break; + case 1178: + name = "Medway"; + break; + case 1179: + name = "Merton"; + break; + case 1180: + name = "Middlesbrough"; + break; + case 1181: + name = "Milton Keynes"; + break; + case 1182: + name = "Newcastle upon Tyne"; + break; + case 1183: + name = "Newham"; + break; + case 1184: + name = "Norfolk"; + break; + case 1219: + name = "Northamptonshire"; + break; + case 1220: + name = "North East Lincolnshire"; + break; + case 1221: + name = "North Lincolnshire"; + break; + case 1222: + name = "North Somerset"; + break; + case 1223: + name = "North Tyneside"; + break; + case 1224: + name = "Northumberland"; + break; + case 1225: + name = "North Yorkshire"; + break; + case 1226: + name = "Nottingham"; + break; + case 1227: + name = "Nottinghamshire"; + break; + case 1262: + name = "Oldham"; + break; + case 1263: + name = "Oxfordshire"; + break; + case 1264: + name = "Peterborough"; + break; + case 1265: + name = "Plymouth"; + break; + case 1266: + name = "Poole"; + break; + case 1267: + name = "Portsmouth"; + break; + case 1268: + name = "Reading"; + break; + case 1269: + name = "Redbridge"; + break; + case 1270: + name = "Redcar and Cleveland"; + break; + case 1305: + name = "Richmond upon Thames"; + break; + case 1306: + name = "Rochdale"; + break; + case 1307: + name = "Rotherham"; + break; + case 1308: + name = "Rutland"; + break; + case 1309: + name = "Salford"; + break; + case 1310: + name = "Shropshire"; + break; + case 1311: + name = "Sandwell"; + break; + case 1312: + name = "Sefton"; + break; + case 1313: + name = "Sheffield"; + break; + case 1348: + name = "Slough"; + break; + case 1349: + name = "Solihull"; + break; + case 1350: + name = "Somerset"; + break; + case 1351: + name = "Southampton"; + break; + case 1352: + name = "Southend-on-Sea"; + break; + case 1353: + name = "South Gloucestershire"; + break; + case 1354: + name = "South Tyneside"; + break; + case 1355: + name = "Southwark"; + break; + case 1356: + name = "Staffordshire"; + break; + case 1391: + name = "St. Helens"; + break; + case 1392: + name = "Stockport"; + break; + case 1393: + name = "Stockton-on-Tees"; + break; + case 1394: + name = "Stoke-on-Trent"; + break; + case 1395: + name = "Suffolk"; + break; + case 1396: + name = "Sunderland"; + break; + case 1397: + name = "Surrey"; + break; + case 1398: + name = "Sutton"; + break; + case 1399: + name = "Swindon"; + break; + case 1434: + name = "Tameside"; + break; + case 1435: + name = "Telford and Wrekin"; + break; + case 1436: + name = "Thurrock"; + break; + case 1437: + name = "Torbay"; + break; + case 1438: + name = "Tower Hamlets"; + break; + case 1439: + name = "Trafford"; + break; + case 1440: + name = "Wakefield"; + break; + case 1441: + name = "Walsall"; + break; + case 1442: + name = "Waltham Forest"; + break; + case 1477: + name = "Wandsworth"; + break; + case 1478: + name = "Warrington"; + break; + case 1479: + name = "Warwickshire"; + break; + case 1480: + name = "West Berkshire"; + break; + case 1481: + name = "Westminster"; + break; + case 1482: + name = "West Sussex"; + break; + case 1483: + name = "Wigan"; + break; + case 1484: + name = "Wiltshire"; + break; + case 1485: + name = "Windsor and Maidenhead"; + break; + case 1520: + name = "Wirral"; + break; + case 1521: + name = "Wokingham"; + break; + case 1522: + name = "Wolverhampton"; + break; + case 1523: + name = "Worcestershire"; + break; + case 1524: + name = "York"; + break; + case 1525: + name = "Antrim"; + break; + case 1526: + name = "Ards"; + break; + case 1527: + name = "Armagh"; + break; + case 1528: + name = "Ballymena"; + break; + case 1563: + name = "Ballymoney"; + break; + case 1564: + name = "Banbridge"; + break; + case 1565: + name = "Belfast"; + break; + case 1566: + name = "Carrickfergus"; + break; + case 1567: + name = "Castlereagh"; + break; + case 1568: + name = "Coleraine"; + break; + case 1569: + name = "Cookstown"; + break; + case 1570: + name = "Craigavon"; + break; + case 1571: + name = "Down"; + break; + case 1606: + name = "Dungannon"; + break; + case 1607: + name = "Fermanagh"; + break; + case 1608: + name = "Larne"; + break; + case 1609: + name = "Limavady"; + break; + case 1610: + name = "Lisburn"; + break; + case 1611: + name = "Derry"; + break; + case 1612: + name = "Magherafelt"; + break; + case 1613: + name = "Moyle"; + break; + case 1614: + name = "Newry and Mourne"; + break; + case 1649: + name = "Newtownabbey"; + break; + case 1650: + name = "North Down"; + break; + case 1651: + name = "Omagh"; + break; + case 1652: + name = "Strabane"; + break; + case 1653: + name = "Aberdeen City"; + break; + case 1654: + name = "Aberdeenshire"; + break; + case 1655: + name = "Angus"; + break; + case 1656: + name = "Argyll and Bute"; + break; + case 1657: + name = "Scottish Borders, The"; + break; + case 1692: + name = "Clackmannanshire"; + break; + case 1693: + name = "Dumfries and Galloway"; + break; + case 1694: + name = "Dundee City"; + break; + case 1695: + name = "East Ayrshire"; + break; + case 1696: + name = "East Dunbartonshire"; + break; + case 1697: + name = "East Lothian"; + break; + case 1698: + name = "East Renfrewshire"; + break; + case 1699: + name = "Edinburgh, City of"; + break; + case 1700: + name = "Falkirk"; + break; + case 1735: + name = "Fife"; + break; + case 1736: + name = "Glasgow City"; + break; + case 1737: + name = "Highland"; + break; + case 1738: + name = "Inverclyde"; + break; + case 1739: + name = "Midlothian"; + break; + case 1740: + name = "Moray"; + break; + case 1741: + name = "North Ayrshire"; + break; + case 1742: + name = "North Lanarkshire"; + break; + case 1743: + name = "Orkney"; + break; + case 1778: + name = "Perth and Kinross"; + break; + case 1779: + name = "Renfrewshire"; + break; + case 1780: + name = "Shetland Islands"; + break; + case 1781: + name = "South Ayrshire"; + break; + case 1782: + name = "South Lanarkshire"; + break; + case 1783: + name = "Stirling"; + break; + case 1784: + name = "West Dunbartonshire"; + break; + case 1785: + name = "Eilean Siar"; + break; + case 1786: + name = "West Lothian"; + break; + case 1821: + name = "Isle of Anglesey"; + break; + case 1822: + name = "Blaenau Gwent"; + break; + case 1823: + name = "Bridgend"; + break; + case 1824: + name = "Caerphilly"; + break; + case 1825: + name = "Cardiff"; + break; + case 1826: + name = "Ceredigion"; + break; + case 1827: + name = "Carmarthenshire"; + break; + case 1828: + name = "Conwy"; + break; + case 1829: + name = "Denbighshire"; + break; + case 1864: + name = "Flintshire"; + break; + case 1865: + name = "Gwynedd"; + break; + case 1866: + name = "Merthyr Tydfil"; + break; + case 1867: + name = "Monmouthshire"; + break; + case 1868: + name = "Neath Port Talbot"; + break; + case 1869: + name = "Newport"; + break; + case 1870: + name = "Pembrokeshire"; + break; + case 1871: + name = "Powys"; + break; + case 1872: + name = "Rhondda Cynon Taff"; + break; + case 1907: + name = "Swansea"; + break; + case 1908: + name = "Torfaen"; + break; + case 1909: + name = "Vale of Glamorgan, The"; + break; + case 1910: + name = "Wrexham"; + break; + } + } + if (strcmp(country_code,"GD") == 0) { + switch (region_code2) { + case 1: + name = "Saint Andrew"; + break; + case 2: + name = "Saint David"; + break; + case 3: + name = "Saint George"; + break; + case 4: + name = "Saint John"; + break; + case 5: + name = "Saint Mark"; + break; + case 6: + name = "Saint Patrick"; + break; + } + } + if (strcmp(country_code,"GE") == 0) { + switch (region_code2) { + case 1: + name = "Abashis Raioni"; + break; + case 2: + name = "Abkhazia"; + break; + case 3: + name = "Adigenis Raioni"; + break; + case 4: + name = "Ajaria"; + break; + case 5: + name = "Akhalgoris Raioni"; + break; + case 6: + name = "Akhalk'alak'is Raioni"; + break; + case 7: + name = "Akhalts'ikhis Raioni"; + break; + case 8: + name = "Akhmetis Raioni"; + break; + case 9: + name = "Ambrolauris Raioni"; + break; + case 10: + name = "Aspindzis Raioni"; + break; + case 11: + name = "Baghdat'is Raioni"; + break; + case 12: + name = "Bolnisis Raioni"; + break; + case 13: + name = "Borjomis Raioni"; + break; + case 14: + name = "Chiat'ura"; + break; + case 15: + name = "Ch'khorotsqus Raioni"; + break; + case 16: + name = "Ch'okhatauris Raioni"; + break; + case 17: + name = "Dedop'listsqaros Raioni"; + break; + case 18: + name = "Dmanisis Raioni"; + break; + case 19: + name = "Dushet'is Raioni"; + break; + case 20: + name = "Gardabanis Raioni"; + break; + case 21: + name = "Gori"; + break; + case 22: + name = "Goris Raioni"; + break; + case 23: + name = "Gurjaanis Raioni"; + break; + case 24: + name = "Javis Raioni"; + break; + case 25: + name = "K'arelis Raioni"; + break; + case 26: + name = "Kaspis Raioni"; + break; + case 27: + name = "Kharagaulis Raioni"; + break; + case 28: + name = "Khashuris Raioni"; + break; + case 29: + name = "Khobis Raioni"; + break; + case 30: + name = "Khonis Raioni"; + break; + case 31: + name = "K'ut'aisi"; + break; + case 32: + name = "Lagodekhis Raioni"; + break; + case 33: + name = "Lanch'khut'is Raioni"; + break; + case 34: + name = "Lentekhis Raioni"; + break; + case 35: + name = "Marneulis Raioni"; + break; + case 36: + name = "Martvilis Raioni"; + break; + case 37: + name = "Mestiis Raioni"; + break; + case 38: + name = "Mts'khet'is Raioni"; + break; + case 39: + name = "Ninotsmindis Raioni"; + break; + case 40: + name = "Onis Raioni"; + break; + case 41: + name = "Ozurget'is Raioni"; + break; + case 42: + name = "P'ot'i"; + break; + case 43: + name = "Qazbegis Raioni"; + break; + case 44: + name = "Qvarlis Raioni"; + break; + case 45: + name = "Rust'avi"; + break; + case 46: + name = "Sach'kheris Raioni"; + break; + case 47: + name = "Sagarejos Raioni"; + break; + case 48: + name = "Samtrediis Raioni"; + break; + case 49: + name = "Senakis Raioni"; + break; + case 50: + name = "Sighnaghis Raioni"; + break; + case 51: + name = "T'bilisi"; + break; + case 52: + name = "T'elavis Raioni"; + break; + case 53: + name = "T'erjolis Raioni"; + break; + case 54: + name = "T'et'ritsqaros Raioni"; + break; + case 55: + name = "T'ianet'is Raioni"; + break; + case 56: + name = "Tqibuli"; + break; + case 57: + name = "Ts'ageris Raioni"; + break; + case 58: + name = "Tsalenjikhis Raioni"; + break; + case 59: + name = "Tsalkis Raioni"; + break; + case 60: + name = "Tsqaltubo"; + break; + case 61: + name = "Vanis Raioni"; + break; + case 62: + name = "Zestap'onis Raioni"; + break; + case 63: + name = "Zugdidi"; + break; + case 64: + name = "Zugdidis Raioni"; + break; + } + } + if (strcmp(country_code,"GH") == 0) { + switch (region_code2) { + case 1: + name = "Greater Accra"; + break; + case 2: + name = "Ashanti"; + break; + case 3: + name = "Brong-Ahafo"; + break; + case 4: + name = "Central"; + break; + case 5: + name = "Eastern"; + break; + case 6: + name = "Northern"; + break; + case 8: + name = "Volta"; + break; + case 9: + name = "Western"; + break; + case 10: + name = "Upper East"; + break; + case 11: + name = "Upper West"; + break; + } + } + if (strcmp(country_code,"GL") == 0) { + switch (region_code2) { + case 1: + name = "Nordgronland"; + break; + case 2: + name = "Ostgronland"; + break; + case 3: + name = "Vestgronland"; + break; + } + } + if (strcmp(country_code,"GM") == 0) { + switch (region_code2) { + case 1: + name = "Banjul"; + break; + case 2: + name = "Lower River"; + break; + case 3: + name = "Central River"; + break; + case 4: + name = "Upper River"; + break; + case 5: + name = "Western"; + break; + case 7: + name = "North Bank"; + break; + } + } + if (strcmp(country_code,"GN") == 0) { + switch (region_code2) { + case 1: + name = "Beyla"; + break; + case 2: + name = "Boffa"; + break; + case 3: + name = "Boke"; + break; + case 4: + name = "Conakry"; + break; + case 5: + name = "Dabola"; + break; + case 6: + name = "Dalaba"; + break; + case 7: + name = "Dinguiraye"; + break; + case 9: + name = "Faranah"; + break; + case 10: + name = "Forecariah"; + break; + case 11: + name = "Fria"; + break; + case 12: + name = "Gaoual"; + break; + case 13: + name = "Gueckedou"; + break; + case 15: + name = "Kerouane"; + break; + case 16: + name = "Kindia"; + break; + case 17: + name = "Kissidougou"; + break; + case 18: + name = "Koundara"; + break; + case 19: + name = "Kouroussa"; + break; + case 21: + name = "Macenta"; + break; + case 22: + name = "Mali"; + break; + case 23: + name = "Mamou"; + break; + case 25: + name = "Pita"; + break; + case 27: + name = "Telimele"; + break; + case 28: + name = "Tougue"; + break; + case 29: + name = "Yomou"; + break; + case 30: + name = "Coyah"; + break; + case 31: + name = "Dubreka"; + break; + case 32: + name = "Kankan"; + break; + case 33: + name = "Koubia"; + break; + case 34: + name = "Labe"; + break; + case 35: + name = "Lelouma"; + break; + case 36: + name = "Lola"; + break; + case 37: + name = "Mandiana"; + break; + case 38: + name = "Nzerekore"; + break; + case 39: + name = "Siguiri"; + break; + } + } + if (strcmp(country_code,"GQ") == 0) { + switch (region_code2) { + case 3: + name = "Annobon"; + break; + case 4: + name = "Bioko Norte"; + break; + case 5: + name = "Bioko Sur"; + break; + case 6: + name = "Centro Sur"; + break; + case 7: + name = "Kie-Ntem"; + break; + case 8: + name = "Litoral"; + break; + case 9: + name = "Wele-Nzas"; + break; + } + } + if (strcmp(country_code,"GR") == 0) { + switch (region_code2) { + case 1: + name = "Evros"; + break; + case 2: + name = "Rodhopi"; + break; + case 3: + name = "Xanthi"; + break; + case 4: + name = "Drama"; + break; + case 5: + name = "Serrai"; + break; + case 6: + name = "Kilkis"; + break; + case 7: + name = "Pella"; + break; + case 8: + name = "Florina"; + break; + case 9: + name = "Kastoria"; + break; + case 10: + name = "Grevena"; + break; + case 11: + name = "Kozani"; + break; + case 12: + name = "Imathia"; + break; + case 13: + name = "Thessaloniki"; + break; + case 14: + name = "Kavala"; + break; + case 15: + name = "Khalkidhiki"; + break; + case 16: + name = "Pieria"; + break; + case 17: + name = "Ioannina"; + break; + case 18: + name = "Thesprotia"; + break; + case 19: + name = "Preveza"; + break; + case 20: + name = "Arta"; + break; + case 21: + name = "Larisa"; + break; + case 22: + name = "Trikala"; + break; + case 23: + name = "Kardhitsa"; + break; + case 24: + name = "Magnisia"; + break; + case 25: + name = "Kerkira"; + break; + case 26: + name = "Levkas"; + break; + case 27: + name = "Kefallinia"; + break; + case 28: + name = "Zakinthos"; + break; + case 29: + name = "Fthiotis"; + break; + case 30: + name = "Evritania"; + break; + case 31: + name = "Aitolia kai Akarnania"; + break; + case 32: + name = "Fokis"; + break; + case 33: + name = "Voiotia"; + break; + case 34: + name = "Evvoia"; + break; + case 35: + name = "Attiki"; + break; + case 36: + name = "Argolis"; + break; + case 37: + name = "Korinthia"; + break; + case 38: + name = "Akhaia"; + break; + case 39: + name = "Ilia"; + break; + case 40: + name = "Messinia"; + break; + case 41: + name = "Arkadhia"; + break; + case 42: + name = "Lakonia"; + break; + case 43: + name = "Khania"; + break; + case 44: + name = "Rethimni"; + break; + case 45: + name = "Iraklion"; + break; + case 46: + name = "Lasithi"; + break; + case 47: + name = "Dhodhekanisos"; + break; + case 48: + name = "Samos"; + break; + case 49: + name = "Kikladhes"; + break; + case 50: + name = "Khios"; + break; + case 51: + name = "Lesvos"; + break; + } + } + if (strcmp(country_code,"GT") == 0) { + switch (region_code2) { + case 1: + name = "Alta Verapaz"; + break; + case 2: + name = "Baja Verapaz"; + break; + case 3: + name = "Chimaltenango"; + break; + case 4: + name = "Chiquimula"; + break; + case 5: + name = "El Progreso"; + break; + case 6: + name = "Escuintla"; + break; + case 7: + name = "Guatemala"; + break; + case 8: + name = "Huehuetenango"; + break; + case 9: + name = "Izabal"; + break; + case 10: + name = "Jalapa"; + break; + case 11: + name = "Jutiapa"; + break; + case 12: + name = "Peten"; + break; + case 13: + name = "Quetzaltenango"; + break; + case 14: + name = "Quiche"; + break; + case 15: + name = "Retalhuleu"; + break; + case 16: + name = "Sacatepequez"; + break; + case 17: + name = "San Marcos"; + break; + case 18: + name = "Santa Rosa"; + break; + case 19: + name = "Solola"; + break; + case 20: + name = "Suchitepequez"; + break; + case 21: + name = "Totonicapan"; + break; + case 22: + name = "Zacapa"; + break; + } + } + if (strcmp(country_code,"GW") == 0) { + switch (region_code2) { + case 1: + name = "Bafata"; + break; + case 2: + name = "Quinara"; + break; + case 4: + name = "Oio"; + break; + case 5: + name = "Bolama"; + break; + case 6: + name = "Cacheu"; + break; + case 7: + name = "Tombali"; + break; + case 10: + name = "Gabu"; + break; + case 11: + name = "Bissau"; + break; + case 12: + name = "Biombo"; + break; + } + } + if (strcmp(country_code,"GY") == 0) { + switch (region_code2) { + case 10: + name = "Barima-Waini"; + break; + case 11: + name = "Cuyuni-Mazaruni"; + break; + case 12: + name = "Demerara-Mahaica"; + break; + case 13: + name = "East Berbice-Corentyne"; + break; + case 14: + name = "Essequibo Islands-West Demerara"; + break; + case 15: + name = "Mahaica-Berbice"; + break; + case 16: + name = "Pomeroon-Supenaam"; + break; + case 17: + name = "Potaro-Siparuni"; + break; + case 18: + name = "Upper Demerara-Berbice"; + break; + case 19: + name = "Upper Takutu-Upper Essequibo"; + break; + } + } + if (strcmp(country_code,"HN") == 0) { + switch (region_code2) { + case 1: + name = "Atlantida"; + break; + case 2: + name = "Choluteca"; + break; + case 3: + name = "Colon"; + break; + case 4: + name = "Comayagua"; + break; + case 5: + name = "Copan"; + break; + case 6: + name = "Cortes"; + break; + case 7: + name = "El Paraiso"; + break; + case 8: + name = "Francisco Morazan"; + break; + case 9: + name = "Gracias a Dios"; + break; + case 10: + name = "Intibuca"; + break; + case 11: + name = "Islas de la Bahia"; + break; + case 12: + name = "La Paz"; + break; + case 13: + name = "Lempira"; + break; + case 14: + name = "Ocotepeque"; + break; + case 15: + name = "Olancho"; + break; + case 16: + name = "Santa Barbara"; + break; + case 17: + name = "Valle"; + break; + case 18: + name = "Yoro"; + break; + } + } + if (strcmp(country_code,"HR") == 0) { + switch (region_code2) { + case 1: + name = "Bjelovarsko-Bilogorska"; + break; + case 2: + name = "Brodsko-Posavska"; + break; + case 3: + name = "Dubrovacko-Neretvanska"; + break; + case 4: + name = "Istarska"; + break; + case 5: + name = "Karlovacka"; + break; + case 6: + name = "Koprivnicko-Krizevacka"; + break; + case 7: + name = "Krapinsko-Zagorska"; + break; + case 8: + name = "Licko-Senjska"; + break; + case 9: + name = "Medimurska"; + break; + case 10: + name = "Osjecko-Baranjska"; + break; + case 11: + name = "Pozesko-Slavonska"; + break; + case 12: + name = "Primorsko-Goranska"; + break; + case 13: + name = "Sibensko-Kninska"; + break; + case 14: + name = "Sisacko-Moslavacka"; + break; + case 15: + name = "Splitsko-Dalmatinska"; + break; + case 16: + name = "Varazdinska"; + break; + case 17: + name = "Viroviticko-Podravska"; + break; + case 18: + name = "Vukovarsko-Srijemska"; + break; + case 19: + name = "Zadarska"; + break; + case 20: + name = "Zagrebacka"; + break; + case 21: + name = "Grad Zagreb"; + break; + } + } + if (strcmp(country_code,"HT") == 0) { + switch (region_code2) { + case 3: + name = "Nord-Ouest"; + break; + case 6: + name = "Artibonite"; + break; + case 7: + name = "Centre"; + break; + case 9: + name = "Nord"; + break; + case 10: + name = "Nord-Est"; + break; + case 11: + name = "Ouest"; + break; + case 12: + name = "Sud"; + break; + case 13: + name = "Sud-Est"; + break; + case 14: + name = "Grand' Anse"; + break; + case 15: + name = "Nippes"; + break; + } + } + if (strcmp(country_code,"HU") == 0) { + switch (region_code2) { + case 1: + name = "Bacs-Kiskun"; + break; + case 2: + name = "Baranya"; + break; + case 3: + name = "Bekes"; + break; + case 4: + name = "Borsod-Abauj-Zemplen"; + break; + case 5: + name = "Budapest"; + break; + case 6: + name = "Csongrad"; + break; + case 7: + name = "Debrecen"; + break; + case 8: + name = "Fejer"; + break; + case 9: + name = "Gyor-Moson-Sopron"; + break; + case 10: + name = "Hajdu-Bihar"; + break; + case 11: + name = "Heves"; + break; + case 12: + name = "Komarom-Esztergom"; + break; + case 13: + name = "Miskolc"; + break; + case 14: + name = "Nograd"; + break; + case 15: + name = "Pecs"; + break; + case 16: + name = "Pest"; + break; + case 17: + name = "Somogy"; + break; + case 18: + name = "Szabolcs-Szatmar-Bereg"; + break; + case 19: + name = "Szeged"; + break; + case 20: + name = "Jasz-Nagykun-Szolnok"; + break; + case 21: + name = "Tolna"; + break; + case 22: + name = "Vas"; + break; + case 23: + name = "Veszprem"; + break; + case 24: + name = "Zala"; + break; + case 25: + name = "Gyor"; + break; + case 26: + name = "Bekescsaba"; + break; + case 27: + name = "Dunaujvaros"; + break; + case 28: + name = "Eger"; + break; + case 29: + name = "Hodmezovasarhely"; + break; + case 30: + name = "Kaposvar"; + break; + case 31: + name = "Kecskemet"; + break; + case 32: + name = "Nagykanizsa"; + break; + case 33: + name = "Nyiregyhaza"; + break; + case 34: + name = "Sopron"; + break; + case 35: + name = "Szekesfehervar"; + break; + case 36: + name = "Szolnok"; + break; + case 37: + name = "Szombathely"; + break; + case 38: + name = "Tatabanya"; + break; + case 39: + name = "Veszprem"; + break; + case 40: + name = "Zalaegerszeg"; + break; + case 41: + name = "Salgotarjan"; + break; + case 42: + name = "Szekszard"; + break; + case 43: + name = "Erd"; + break; + } + } + if (strcmp(country_code,"ID") == 0) { + switch (region_code2) { + case 1: + name = "Aceh"; + break; + case 2: + name = "Bali"; + break; + case 3: + name = "Bengkulu"; + break; + case 4: + name = "Jakarta Raya"; + break; + case 5: + name = "Jambi"; + break; + case 6: + name = "Jawa Barat"; + break; + case 7: + name = "Jawa Tengah"; + break; + case 8: + name = "Jawa Timur"; + break; + case 9: + name = "Papua"; + break; + case 10: + name = "Yogyakarta"; + break; + case 11: + name = "Kalimantan Barat"; + break; + case 12: + name = "Kalimantan Selatan"; + break; + case 13: + name = "Kalimantan Tengah"; + break; + case 14: + name = "Kalimantan Timur"; + break; + case 15: + name = "Lampung"; + break; + case 16: + name = "Maluku"; + break; + case 17: + name = "Nusa Tenggara Barat"; + break; + case 18: + name = "Nusa Tenggara Timur"; + break; + case 19: + name = "Riau"; + break; + case 20: + name = "Sulawesi Selatan"; + break; + case 21: + name = "Sulawesi Tengah"; + break; + case 22: + name = "Sulawesi Tenggara"; + break; + case 23: + name = "Sulawesi Utara"; + break; + case 24: + name = "Sumatera Barat"; + break; + case 25: + name = "Sumatera Selatan"; + break; + case 26: + name = "Sumatera Utara"; + break; + case 28: + name = "Maluku"; + break; + case 29: + name = "Maluku Utara"; + break; + case 30: + name = "Jawa Barat"; + break; + case 31: + name = "Sulawesi Utara"; + break; + case 32: + name = "Sumatera Selatan"; + break; + case 33: + name = "Banten"; + break; + case 34: + name = "Gorontalo"; + break; + case 35: + name = "Kepulauan Bangka Belitung"; + break; + case 36: + name = "Papua"; + break; + case 37: + name = "Riau"; + break; + case 38: + name = "Sulawesi Selatan"; + break; + case 39: + name = "Irian Jaya Barat"; + break; + case 40: + name = "Kepulauan Riau"; + break; + case 41: + name = "Sulawesi Barat"; + break; + } + } + if (strcmp(country_code,"IE") == 0) { + switch (region_code2) { + case 1: + name = "Carlow"; + break; + case 2: + name = "Cavan"; + break; + case 3: + name = "Clare"; + break; + case 4: + name = "Cork"; + break; + case 6: + name = "Donegal"; + break; + case 7: + name = "Dublin"; + break; + case 10: + name = "Galway"; + break; + case 11: + name = "Kerry"; + break; + case 12: + name = "Kildare"; + break; + case 13: + name = "Kilkenny"; + break; + case 14: + name = "Leitrim"; + break; + case 15: + name = "Laois"; + break; + case 16: + name = "Limerick"; + break; + case 18: + name = "Longford"; + break; + case 19: + name = "Louth"; + break; + case 20: + name = "Mayo"; + break; + case 21: + name = "Meath"; + break; + case 22: + name = "Monaghan"; + break; + case 23: + name = "Offaly"; + break; + case 24: + name = "Roscommon"; + break; + case 25: + name = "Sligo"; + break; + case 26: + name = "Tipperary"; + break; + case 27: + name = "Waterford"; + break; + case 29: + name = "Westmeath"; + break; + case 30: + name = "Wexford"; + break; + case 31: + name = "Wicklow"; + break; + } + } + if (strcmp(country_code,"IL") == 0) { + switch (region_code2) { + case 1: + name = "HaDarom"; + break; + case 2: + name = "HaMerkaz"; + break; + case 3: + name = "HaZafon"; + break; + case 4: + name = "Hefa"; + break; + case 5: + name = "Tel Aviv"; + break; + case 6: + name = "Yerushalayim"; + break; + } + } + if (strcmp(country_code,"IN") == 0) { + switch (region_code2) { + case 1: + name = "Andaman and Nicobar Islands"; + break; + case 2: + name = "Andhra Pradesh"; + break; + case 3: + name = "Assam"; + break; + case 5: + name = "Chandigarh"; + break; + case 6: + name = "Dadra and Nagar Haveli"; + break; + case 7: + name = "Delhi"; + break; + case 9: + name = "Gujarat"; + break; + case 10: + name = "Haryana"; + break; + case 11: + name = "Himachal Pradesh"; + break; + case 12: + name = "Jammu and Kashmir"; + break; + case 13: + name = "Kerala"; + break; + case 14: + name = "Lakshadweep"; + break; + case 16: + name = "Maharashtra"; + break; + case 17: + name = "Manipur"; + break; + case 18: + name = "Meghalaya"; + break; + case 19: + name = "Karnataka"; + break; + case 20: + name = "Nagaland"; + break; + case 21: + name = "Orissa"; + break; + case 22: + name = "Puducherry"; + break; + case 23: + name = "Punjab"; + break; + case 24: + name = "Rajasthan"; + break; + case 25: + name = "Tamil Nadu"; + break; + case 26: + name = "Tripura"; + break; + case 28: + name = "West Bengal"; + break; + case 29: + name = "Sikkim"; + break; + case 30: + name = "Arunachal Pradesh"; + break; + case 31: + name = "Mizoram"; + break; + case 32: + name = "Daman and Diu"; + break; + case 33: + name = "Goa"; + break; + case 34: + name = "Bihar"; + break; + case 35: + name = "Madhya Pradesh"; + break; + case 36: + name = "Uttar Pradesh"; + break; + case 37: + name = "Chhattisgarh"; + break; + case 38: + name = "Jharkhand"; + break; + case 39: + name = "Uttarakhand"; + break; + } + } + if (strcmp(country_code,"IQ") == 0) { + switch (region_code2) { + case 1: + name = "Al Anbar"; + break; + case 2: + name = "Al Basrah"; + break; + case 3: + name = "Al Muthanna"; + break; + case 4: + name = "Al Qadisiyah"; + break; + case 5: + name = "As Sulaymaniyah"; + break; + case 6: + name = "Babil"; + break; + case 7: + name = "Baghdad"; + break; + case 8: + name = "Dahuk"; + break; + case 9: + name = "Dhi Qar"; + break; + case 10: + name = "Diyala"; + break; + case 11: + name = "Arbil"; + break; + case 12: + name = "Karbala'"; + break; + case 13: + name = "At Ta'mim"; + break; + case 14: + name = "Maysan"; + break; + case 15: + name = "Ninawa"; + break; + case 16: + name = "Wasit"; + break; + case 17: + name = "An Najaf"; + break; + case 18: + name = "Salah ad Din"; + break; + } + } + if (strcmp(country_code,"IR") == 0) { + switch (region_code2) { + case 1: + name = "Azarbayjan-e Bakhtari"; + break; + case 3: + name = "Chahar Mahall va Bakhtiari"; + break; + case 4: + name = "Sistan va Baluchestan"; + break; + case 5: + name = "Kohkiluyeh va Buyer Ahmadi"; + break; + case 7: + name = "Fars"; + break; + case 8: + name = "Gilan"; + break; + case 9: + name = "Hamadan"; + break; + case 10: + name = "Ilam"; + break; + case 11: + name = "Hormozgan"; + break; + case 12: + name = "Kerman"; + break; + case 13: + name = "Bakhtaran"; + break; + case 15: + name = "Khuzestan"; + break; + case 16: + name = "Kordestan"; + break; + case 17: + name = "Mazandaran"; + break; + case 18: + name = "Semnan Province"; + break; + case 19: + name = "Markazi"; + break; + case 21: + name = "Zanjan"; + break; + case 22: + name = "Bushehr"; + break; + case 23: + name = "Lorestan"; + break; + case 24: + name = "Markazi"; + break; + case 25: + name = "Semnan"; + break; + case 26: + name = "Tehran"; + break; + case 27: + name = "Zanjan"; + break; + case 28: + name = "Esfahan"; + break; + case 29: + name = "Kerman"; + break; + case 30: + name = "Khorasan"; + break; + case 31: + name = "Yazd"; + break; + case 32: + name = "Ardabil"; + break; + case 33: + name = "East Azarbaijan"; + break; + case 34: + name = "Markazi"; + break; + case 35: + name = "Mazandaran"; + break; + case 36: + name = "Zanjan"; + break; + case 37: + name = "Golestan"; + break; + case 38: + name = "Qazvin"; + break; + case 39: + name = "Qom"; + break; + case 40: + name = "Yazd"; + break; + case 41: + name = "Khorasan-e Janubi"; + break; + case 42: + name = "Khorasan-e Razavi"; + break; + case 43: + name = "Khorasan-e Shemali"; + break; + } + } + if (strcmp(country_code,"IS") == 0) { + switch (region_code2) { + case 3: + name = "Arnessysla"; + break; + case 5: + name = "Austur-Hunavatnssysla"; + break; + case 6: + name = "Austur-Skaftafellssysla"; + break; + case 7: + name = "Borgarfjardarsysla"; + break; + case 9: + name = "Eyjafjardarsysla"; + break; + case 10: + name = "Gullbringusysla"; + break; + case 15: + name = "Kjosarsysla"; + break; + case 17: + name = "Myrasysla"; + break; + case 20: + name = "Nordur-Mulasysla"; + break; + case 21: + name = "Nordur-Tingeyjarsysla"; + break; + case 23: + name = "Rangarvallasysla"; + break; + case 28: + name = "Skagafjardarsysla"; + break; + case 29: + name = "Snafellsnes- og Hnappadalssysla"; + break; + case 30: + name = "Strandasysla"; + break; + case 31: + name = "Sudur-Mulasysla"; + break; + case 32: + name = "Sudur-Tingeyjarsysla"; + break; + case 34: + name = "Vestur-Bardastrandarsysla"; + break; + case 35: + name = "Vestur-Hunavatnssysla"; + break; + case 36: + name = "Vestur-Isafjardarsysla"; + break; + case 37: + name = "Vestur-Skaftafellssysla"; + break; + case 40: + name = "Norourland Eystra"; + break; + case 41: + name = "Norourland Vestra"; + break; + case 42: + name = "Suourland"; + break; + case 43: + name = "Suournes"; + break; + case 44: + name = "Vestfiroir"; + break; + case 45: + name = "Vesturland"; + break; + } + } + if (strcmp(country_code,"IT") == 0) { + switch (region_code2) { + case 1: + name = "Abruzzi"; + break; + case 2: + name = "Basilicata"; + break; + case 3: + name = "Calabria"; + break; + case 4: + name = "Campania"; + break; + case 5: + name = "Emilia-Romagna"; + break; + case 6: + name = "Friuli-Venezia Giulia"; + break; + case 7: + name = "Lazio"; + break; + case 8: + name = "Liguria"; + break; + case 9: + name = "Lombardia"; + break; + case 10: + name = "Marche"; + break; + case 11: + name = "Molise"; + break; + case 12: + name = "Piemonte"; + break; + case 13: + name = "Puglia"; + break; + case 14: + name = "Sardegna"; + break; + case 15: + name = "Sicilia"; + break; + case 16: + name = "Toscana"; + break; + case 17: + name = "Trentino-Alto Adige"; + break; + case 18: + name = "Umbria"; + break; + case 19: + name = "Valle d'Aosta"; + break; + case 20: + name = "Veneto"; + break; + } + } + if (strcmp(country_code,"JM") == 0) { + switch (region_code2) { + case 1: + name = "Clarendon"; + break; + case 2: + name = "Hanover"; + break; + case 4: + name = "Manchester"; + break; + case 7: + name = "Portland"; + break; + case 8: + name = "Saint Andrew"; + break; + case 9: + name = "Saint Ann"; + break; + case 10: + name = "Saint Catherine"; + break; + case 11: + name = "Saint Elizabeth"; + break; + case 12: + name = "Saint James"; + break; + case 13: + name = "Saint Mary"; + break; + case 14: + name = "Saint Thomas"; + break; + case 15: + name = "Trelawny"; + break; + case 16: + name = "Westmoreland"; + break; + case 17: + name = "Kingston"; + break; + } + } + if (strcmp(country_code,"JO") == 0) { + switch (region_code2) { + case 2: + name = "Al Balqa'"; + break; + case 7: + name = "Ma"; + break; + case 9: + name = "Al Karak"; + break; + case 10: + name = "Al Mafraq"; + break; + case 11: + name = "Amman Governorate"; + break; + case 12: + name = "At Tafilah"; + break; + case 13: + name = "Az Zarqa"; + break; + case 14: + name = "Irbid"; + break; + case 16: + name = "Amman"; + break; + } + } + if (strcmp(country_code,"JP") == 0) { + switch (region_code2) { + case 1: + name = "Aichi"; + break; + case 2: + name = "Akita"; + break; + case 3: + name = "Aomori"; + break; + case 4: + name = "Chiba"; + break; + case 5: + name = "Ehime"; + break; + case 6: + name = "Fukui"; + break; + case 7: + name = "Fukuoka"; + break; + case 8: + name = "Fukushima"; + break; + case 9: + name = "Gifu"; + break; + case 10: + name = "Gumma"; + break; + case 11: + name = "Hiroshima"; + break; + case 12: + name = "Hokkaido"; + break; + case 13: + name = "Hyogo"; + break; + case 14: + name = "Ibaraki"; + break; + case 15: + name = "Ishikawa"; + break; + case 16: + name = "Iwate"; + break; + case 17: + name = "Kagawa"; + break; + case 18: + name = "Kagoshima"; + break; + case 19: + name = "Kanagawa"; + break; + case 20: + name = "Kochi"; + break; + case 21: + name = "Kumamoto"; + break; + case 22: + name = "Kyoto"; + break; + case 23: + name = "Mie"; + break; + case 24: + name = "Miyagi"; + break; + case 25: + name = "Miyazaki"; + break; + case 26: + name = "Nagano"; + break; + case 27: + name = "Nagasaki"; + break; + case 28: + name = "Nara"; + break; + case 29: + name = "Niigata"; + break; + case 30: + name = "Oita"; + break; + case 31: + name = "Okayama"; + break; + case 32: + name = "Osaka"; + break; + case 33: + name = "Saga"; + break; + case 34: + name = "Saitama"; + break; + case 35: + name = "Shiga"; + break; + case 36: + name = "Shimane"; + break; + case 37: + name = "Shizuoka"; + break; + case 38: + name = "Tochigi"; + break; + case 39: + name = "Tokushima"; + break; + case 40: + name = "Tokyo"; + break; + case 41: + name = "Tottori"; + break; + case 42: + name = "Toyama"; + break; + case 43: + name = "Wakayama"; + break; + case 44: + name = "Yamagata"; + break; + case 45: + name = "Yamaguchi"; + break; + case 46: + name = "Yamanashi"; + break; + case 47: + name = "Okinawa"; + break; + } + } + if (strcmp(country_code,"KE") == 0) { + switch (region_code2) { + case 1: + name = "Central"; + break; + case 2: + name = "Coast"; + break; + case 3: + name = "Eastern"; + break; + case 5: + name = "Nairobi Area"; + break; + case 6: + name = "North-Eastern"; + break; + case 7: + name = "Nyanza"; + break; + case 8: + name = "Rift Valley"; + break; + case 9: + name = "Western"; + break; + } + } + if (strcmp(country_code,"KG") == 0) { + switch (region_code2) { + case 1: + name = "Bishkek"; + break; + case 2: + name = "Chuy"; + break; + case 3: + name = "Jalal-Abad"; + break; + case 4: + name = "Naryn"; + break; + case 5: + name = "Osh"; + break; + case 6: + name = "Talas"; + break; + case 7: + name = "Ysyk-Kol"; + break; + case 8: + name = "Osh"; + break; + case 9: + name = "Batken"; + break; + } + } + if (strcmp(country_code,"KH") == 0) { + switch (region_code2) { + case 1: + name = "Batdambang"; + break; + case 2: + name = "Kampong Cham"; + break; + case 3: + name = "Kampong Chhnang"; + break; + case 4: + name = "Kampong Speu"; + break; + case 5: + name = "Kampong Thum"; + break; + case 6: + name = "Kampot"; + break; + case 7: + name = "Kandal"; + break; + case 8: + name = "Koh Kong"; + break; + case 9: + name = "Kracheh"; + break; + case 10: + name = "Mondulkiri"; + break; + case 11: + name = "Phnum Penh"; + break; + case 12: + name = "Pursat"; + break; + case 13: + name = "Preah Vihear"; + break; + case 14: + name = "Prey Veng"; + break; + case 15: + name = "Ratanakiri Kiri"; + break; + case 16: + name = "Siem Reap"; + break; + case 17: + name = "Stung Treng"; + break; + case 18: + name = "Svay Rieng"; + break; + case 19: + name = "Takeo"; + break; + case 25: + name = "Banteay Meanchey"; + break; + case 29: + name = "Batdambang"; + break; + case 30: + name = "Pailin"; + break; + } + } + if (strcmp(country_code,"KI") == 0) { + switch (region_code2) { + case 1: + name = "Gilbert Islands"; + break; + case 2: + name = "Line Islands"; + break; + case 3: + name = "Phoenix Islands"; + break; + } + } + if (strcmp(country_code,"KM") == 0) { + switch (region_code2) { + case 1: + name = "Anjouan"; + break; + case 2: + name = "Grande Comore"; + break; + case 3: + name = "Moheli"; + break; + } + } + if (strcmp(country_code,"KN") == 0) { + switch (region_code2) { + case 1: + name = "Christ Church Nichola Town"; + break; + case 2: + name = "Saint Anne Sandy Point"; + break; + case 3: + name = "Saint George Basseterre"; + break; + case 4: + name = "Saint George Gingerland"; + break; + case 5: + name = "Saint James Windward"; + break; + case 6: + name = "Saint John Capisterre"; + break; + case 7: + name = "Saint John Figtree"; + break; + case 8: + name = "Saint Mary Cayon"; + break; + case 9: + name = "Saint Paul Capisterre"; + break; + case 10: + name = "Saint Paul Charlestown"; + break; + case 11: + name = "Saint Peter Basseterre"; + break; + case 12: + name = "Saint Thomas Lowland"; + break; + case 13: + name = "Saint Thomas Middle Island"; + break; + case 15: + name = "Trinity Palmetto Point"; + break; + } + } + if (strcmp(country_code,"KP") == 0) { + switch (region_code2) { + case 1: + name = "Chagang-do"; + break; + case 3: + name = "Hamgyong-namdo"; + break; + case 6: + name = "Hwanghae-namdo"; + break; + case 7: + name = "Hwanghae-bukto"; + break; + case 8: + name = "Kaesong-si"; + break; + case 9: + name = "Kangwon-do"; + break; + case 11: + name = "P'yongan-bukto"; + break; + case 12: + name = "P'yongyang-si"; + break; + case 13: + name = "Yanggang-do"; + break; + case 14: + name = "Namp'o-si"; + break; + case 15: + name = "P'yongan-namdo"; + break; + case 17: + name = "Hamgyong-bukto"; + break; + case 18: + name = "Najin Sonbong-si"; + break; + } + } + if (strcmp(country_code,"KR") == 0) { + switch (region_code2) { + case 1: + name = "Cheju-do"; + break; + case 3: + name = "Cholla-bukto"; + break; + case 5: + name = "Ch'ungch'ong-bukto"; + break; + case 6: + name = "Kangwon-do"; + break; + case 10: + name = "Pusan-jikhalsi"; + break; + case 11: + name = "Seoul-t'ukpyolsi"; + break; + case 12: + name = "Inch'on-jikhalsi"; + break; + case 13: + name = "Kyonggi-do"; + break; + case 14: + name = "Kyongsang-bukto"; + break; + case 15: + name = "Taegu-jikhalsi"; + break; + case 16: + name = "Cholla-namdo"; + break; + case 17: + name = "Ch'ungch'ong-namdo"; + break; + case 18: + name = "Kwangju-jikhalsi"; + break; + case 19: + name = "Taejon-jikhalsi"; + break; + case 20: + name = "Kyongsang-namdo"; + break; + case 21: + name = "Ulsan-gwangyoksi"; + break; + } + } + if (strcmp(country_code,"KW") == 0) { + switch (region_code2) { + case 1: + name = "Al Ahmadi"; + break; + case 2: + name = "Al Kuwayt"; + break; + case 5: + name = "Al Jahra"; + break; + case 7: + name = "Al Farwaniyah"; + break; + case 8: + name = "Hawalli"; + break; + case 9: + name = "Mubarak al Kabir"; + break; + } + } + if (strcmp(country_code,"KY") == 0) { + switch (region_code2) { + case 1: + name = "Creek"; + break; + case 2: + name = "Eastern"; + break; + case 3: + name = "Midland"; + break; + case 4: + name = "South Town"; + break; + case 5: + name = "Spot Bay"; + break; + case 6: + name = "Stake Bay"; + break; + case 7: + name = "West End"; + break; + case 8: + name = "Western"; + break; + } + } + if (strcmp(country_code,"KZ") == 0) { + switch (region_code2) { + case 1: + name = "Almaty"; + break; + case 2: + name = "Almaty City"; + break; + case 3: + name = "Aqmola"; + break; + case 4: + name = "Aqtobe"; + break; + case 5: + name = "Astana"; + break; + case 6: + name = "Atyrau"; + break; + case 7: + name = "West Kazakhstan"; + break; + case 8: + name = "Bayqonyr"; + break; + case 9: + name = "Mangghystau"; + break; + case 10: + name = "South Kazakhstan"; + break; + case 11: + name = "Pavlodar"; + break; + case 12: + name = "Qaraghandy"; + break; + case 13: + name = "Qostanay"; + break; + case 14: + name = "Qyzylorda"; + break; + case 15: + name = "East Kazakhstan"; + break; + case 16: + name = "North Kazakhstan"; + break; + case 17: + name = "Zhambyl"; + break; + } + } + if (strcmp(country_code,"LA") == 0) { + switch (region_code2) { + case 1: + name = "Attapu"; + break; + case 2: + name = "Champasak"; + break; + case 3: + name = "Houaphan"; + break; + case 4: + name = "Khammouan"; + break; + case 5: + name = "Louang Namtha"; + break; + case 7: + name = "Oudomxai"; + break; + case 8: + name = "Phongsali"; + break; + case 9: + name = "Saravan"; + break; + case 10: + name = "Savannakhet"; + break; + case 11: + name = "Vientiane"; + break; + case 13: + name = "Xaignabouri"; + break; + case 14: + name = "Xiangkhoang"; + break; + case 17: + name = "Louangphrabang"; + break; + } + } + if (strcmp(country_code,"LB") == 0) { + switch (region_code2) { + case 1: + name = "Beqaa"; + break; + case 2: + name = "Al Janub"; + break; + case 3: + name = "Liban-Nord"; + break; + case 4: + name = "Beyrouth"; + break; + case 5: + name = "Mont-Liban"; + break; + case 6: + name = "Liban-Sud"; + break; + case 7: + name = "Nabatiye"; + break; + case 8: + name = "Beqaa"; + break; + case 9: + name = "Liban-Nord"; + break; + case 10: + name = "Aakk,r"; + break; + case 11: + name = "Baalbek-Hermel"; + break; + } + } + if (strcmp(country_code,"LC") == 0) { + switch (region_code2) { + case 1: + name = "Anse-la-Raye"; + break; + case 2: + name = "Dauphin"; + break; + case 3: + name = "Castries"; + break; + case 4: + name = "Choiseul"; + break; + case 5: + name = "Dennery"; + break; + case 6: + name = "Gros-Islet"; + break; + case 7: + name = "Laborie"; + break; + case 8: + name = "Micoud"; + break; + case 9: + name = "Soufriere"; + break; + case 10: + name = "Vieux-Fort"; + break; + case 11: + name = "Praslin"; + break; + } + } + if (strcmp(country_code,"LI") == 0) { + switch (region_code2) { + case 1: + name = "Balzers"; + break; + case 2: + name = "Eschen"; + break; + case 3: + name = "Gamprin"; + break; + case 4: + name = "Mauren"; + break; + case 5: + name = "Planken"; + break; + case 6: + name = "Ruggell"; + break; + case 7: + name = "Schaan"; + break; + case 8: + name = "Schellenberg"; + break; + case 9: + name = "Triesen"; + break; + case 10: + name = "Triesenberg"; + break; + case 11: + name = "Vaduz"; + break; + case 21: + name = "Gbarpolu"; + break; + case 22: + name = "River Gee"; + break; + } + } + if (strcmp(country_code,"LK") == 0) { + switch (region_code2) { + case 1: + name = "Amparai"; + break; + case 2: + name = "Anuradhapura"; + break; + case 3: + name = "Badulla"; + break; + case 4: + name = "Batticaloa"; + break; + case 6: + name = "Galle"; + break; + case 7: + name = "Hambantota"; + break; + case 9: + name = "Kalutara"; + break; + case 10: + name = "Kandy"; + break; + case 11: + name = "Kegalla"; + break; + case 12: + name = "Kurunegala"; + break; + case 14: + name = "Matale"; + break; + case 15: + name = "Matara"; + break; + case 16: + name = "Moneragala"; + break; + case 17: + name = "Nuwara Eliya"; + break; + case 18: + name = "Polonnaruwa"; + break; + case 19: + name = "Puttalam"; + break; + case 20: + name = "Ratnapura"; + break; + case 21: + name = "Trincomalee"; + break; + case 23: + name = "Colombo"; + break; + case 24: + name = "Gampaha"; + break; + case 25: + name = "Jaffna"; + break; + case 26: + name = "Mannar"; + break; + case 27: + name = "Mullaittivu"; + break; + case 28: + name = "Vavuniya"; + break; + case 29: + name = "Central"; + break; + case 30: + name = "North Central"; + break; + case 31: + name = "Northern"; + break; + case 32: + name = "North Western"; + break; + case 33: + name = "Sabaragamuwa"; + break; + case 34: + name = "Southern"; + break; + case 35: + name = "Uva"; + break; + case 36: + name = "Western"; + break; + } + } + if (strcmp(country_code,"LR") == 0) { + switch (region_code2) { + case 1: + name = "Bong"; + break; + case 4: + name = "Grand Cape Mount"; + break; + case 5: + name = "Lofa"; + break; + case 6: + name = "Maryland"; + break; + case 7: + name = "Monrovia"; + break; + case 9: + name = "Nimba"; + break; + case 10: + name = "Sino"; + break; + case 11: + name = "Grand Bassa"; + break; + case 12: + name = "Grand Cape Mount"; + break; + case 13: + name = "Maryland"; + break; + case 14: + name = "Montserrado"; + break; + case 17: + name = "Margibi"; + break; + case 18: + name = "River Cess"; + break; + case 19: + name = "Grand Gedeh"; + break; + case 20: + name = "Lofa"; + break; + case 21: + name = "Gbarpolu"; + break; + case 22: + name = "River Gee"; + break; + } + } + if (strcmp(country_code,"LS") == 0) { + switch (region_code2) { + case 10: + name = "Berea"; + break; + case 11: + name = "Butha-Buthe"; + break; + case 12: + name = "Leribe"; + break; + case 13: + name = "Mafeteng"; + break; + case 14: + name = "Maseru"; + break; + case 15: + name = "Mohales Hoek"; + break; + case 16: + name = "Mokhotlong"; + break; + case 17: + name = "Qachas Nek"; + break; + case 18: + name = "Quthing"; + break; + case 19: + name = "Thaba-Tseka"; + break; + } + } + if (strcmp(country_code,"LT") == 0) { + switch (region_code2) { + case 56: + name = "Alytaus Apskritis"; + break; + case 57: + name = "Kauno Apskritis"; + break; + case 58: + name = "Klaipedos Apskritis"; + break; + case 59: + name = "Marijampoles Apskritis"; + break; + case 60: + name = "Panevezio Apskritis"; + break; + case 61: + name = "Siauliu Apskritis"; + break; + case 62: + name = "Taurages Apskritis"; + break; + case 63: + name = "Telsiu Apskritis"; + break; + case 64: + name = "Utenos Apskritis"; + break; + case 65: + name = "Vilniaus Apskritis"; + break; + } + } + if (strcmp(country_code,"LU") == 0) { + switch (region_code2) { + case 1: + name = "Diekirch"; + break; + case 2: + name = "Grevenmacher"; + break; + case 3: + name = "Luxembourg"; + break; + } + } + if (strcmp(country_code,"LV") == 0) { + switch (region_code2) { + case 1: + name = "Aizkraukles"; + break; + case 2: + name = "Aluksnes"; + break; + case 3: + name = "Balvu"; + break; + case 4: + name = "Bauskas"; + break; + case 5: + name = "Cesu"; + break; + case 6: + name = "Daugavpils"; + break; + case 7: + name = "Daugavpils"; + break; + case 8: + name = "Dobeles"; + break; + case 9: + name = "Gulbenes"; + break; + case 10: + name = "Jekabpils"; + break; + case 11: + name = "Jelgava"; + break; + case 12: + name = "Jelgavas"; + break; + case 13: + name = "Jurmala"; + break; + case 14: + name = "Kraslavas"; + break; + case 15: + name = "Kuldigas"; + break; + case 16: + name = "Liepaja"; + break; + case 17: + name = "Liepajas"; + break; + case 18: + name = "Limbazu"; + break; + case 19: + name = "Ludzas"; + break; + case 20: + name = "Madonas"; + break; + case 21: + name = "Ogres"; + break; + case 22: + name = "Preilu"; + break; + case 23: + name = "Rezekne"; + break; + case 24: + name = "Rezeknes"; + break; + case 25: + name = "Riga"; + break; + case 26: + name = "Rigas"; + break; + case 27: + name = "Saldus"; + break; + case 28: + name = "Talsu"; + break; + case 29: + name = "Tukuma"; + break; + case 30: + name = "Valkas"; + break; + case 31: + name = "Valmieras"; + break; + case 32: + name = "Ventspils"; + break; + case 33: + name = "Ventspils"; + break; + } + } + if (strcmp(country_code,"LY") == 0) { + switch (region_code2) { + case 3: + name = "Al Aziziyah"; + break; + case 5: + name = "Al Jufrah"; + break; + case 8: + name = "Al Kufrah"; + break; + case 13: + name = "Ash Shati'"; + break; + case 30: + name = "Murzuq"; + break; + case 34: + name = "Sabha"; + break; + case 41: + name = "Tarhunah"; + break; + case 42: + name = "Tubruq"; + break; + case 45: + name = "Zlitan"; + break; + case 47: + name = "Ajdabiya"; + break; + case 48: + name = "Al Fatih"; + break; + case 49: + name = "Al Jabal al Akhdar"; + break; + case 50: + name = "Al Khums"; + break; + case 51: + name = "An Nuqat al Khams"; + break; + case 52: + name = "Awbari"; + break; + case 53: + name = "Az Zawiyah"; + break; + case 54: + name = "Banghazi"; + break; + case 55: + name = "Darnah"; + break; + case 56: + name = "Ghadamis"; + break; + case 57: + name = "Gharyan"; + break; + case 58: + name = "Misratah"; + break; + case 59: + name = "Sawfajjin"; + break; + case 60: + name = "Surt"; + break; + case 61: + name = "Tarabulus"; + break; + case 62: + name = "Yafran"; + break; + } + } + if (strcmp(country_code,"MA") == 0) { + switch (region_code2) { + case 45: + name = "Grand Casablanca"; + break; + case 46: + name = "Fes-Boulemane"; + break; + case 47: + name = "Marrakech-Tensift-Al Haouz"; + break; + case 48: + name = "Meknes-Tafilalet"; + break; + case 49: + name = "Rabat-Sale-Zemmour-Zaer"; + break; + case 50: + name = "Chaouia-Ouardigha"; + break; + case 51: + name = "Doukkala-Abda"; + break; + case 52: + name = "Gharb-Chrarda-Beni Hssen"; + break; + case 53: + name = "Guelmim-Es Smara"; + break; + case 54: + name = "Oriental"; + break; + case 55: + name = "Souss-Massa-Dr,a"; + break; + case 56: + name = "Tadla-Azilal"; + break; + case 57: + name = "Tanger-Tetouan"; + break; + case 58: + name = "Taza-Al Hoceima-Taounate"; + break; + case 59: + name = "La,youne-Boujdour-Sakia El Hamra"; + break; + } + } + if (strcmp(country_code,"MC") == 0) { + switch (region_code2) { + case 1: + name = "La Condamine"; + break; + case 2: + name = "Monaco"; + break; + case 3: + name = "Monte-Carlo"; + break; + } + } + if (strcmp(country_code,"MD") == 0) { + switch (region_code2) { + case 51: + name = "Gagauzia"; + break; + case 57: + name = "Chisinau"; + break; + case 58: + name = "Stinga Nistrului"; + break; + case 59: + name = "Anenii Noi"; + break; + case 60: + name = "Balti"; + break; + case 61: + name = "Basarabeasca"; + break; + case 62: + name = "Bender"; + break; + case 63: + name = "Briceni"; + break; + case 64: + name = "Cahul"; + break; + case 65: + name = "Cantemir"; + break; + case 66: + name = "Calarasi"; + break; + case 67: + name = "Causeni"; + break; + case 68: + name = "Cimislia"; + break; + case 69: + name = "Criuleni"; + break; + case 70: + name = "Donduseni"; + break; + case 71: + name = "Drochia"; + break; + case 72: + name = "Dubasari"; + break; + case 73: + name = "Edinet"; + break; + case 74: + name = "Falesti"; + break; + case 75: + name = "Floresti"; + break; + case 76: + name = "Glodeni"; + break; + case 77: + name = "Hincesti"; + break; + case 78: + name = "Ialoveni"; + break; + case 79: + name = "Leova"; + break; + case 80: + name = "Nisporeni"; + break; + case 81: + name = "Ocnita"; + break; + case 83: + name = "Rezina"; + break; + case 84: + name = "Riscani"; + break; + case 85: + name = "Singerei"; + break; + case 86: + name = "Soldanesti"; + break; + case 87: + name = "Soroca"; + break; + case 88: + name = "Stefan-Voda"; + break; + case 89: + name = "Straseni"; + break; + case 90: + name = "Taraclia"; + break; + case 91: + name = "Telenesti"; + break; + case 92: + name = "Ungheni"; + break; + } + } + if (strcmp(country_code,"MG") == 0) { + switch (region_code2) { + case 1: + name = "Antsiranana"; + break; + case 2: + name = "Fianarantsoa"; + break; + case 3: + name = "Mahajanga"; + break; + case 4: + name = "Toamasina"; + break; + case 5: + name = "Antananarivo"; + break; + case 6: + name = "Toliara"; + break; + } + } + if (strcmp(country_code,"MK") == 0) { + switch (region_code2) { + case 1: + name = "Aracinovo"; + break; + case 2: + name = "Bac"; + break; + case 3: + name = "Belcista"; + break; + case 4: + name = "Berovo"; + break; + case 5: + name = "Bistrica"; + break; + case 6: + name = "Bitola"; + break; + case 7: + name = "Blatec"; + break; + case 8: + name = "Bogdanci"; + break; + case 9: + name = "Bogomila"; + break; + case 10: + name = "Bogovinje"; + break; + case 11: + name = "Bosilovo"; + break; + case 12: + name = "Brvenica"; + break; + case 13: + name = "Cair"; + break; + case 14: + name = "Capari"; + break; + case 15: + name = "Caska"; + break; + case 16: + name = "Cegrane"; + break; + case 17: + name = "Centar"; + break; + case 18: + name = "Centar Zupa"; + break; + case 19: + name = "Cesinovo"; + break; + case 20: + name = "Cucer-Sandevo"; + break; + case 21: + name = "Debar"; + break; + case 22: + name = "Delcevo"; + break; + case 23: + name = "Delogozdi"; + break; + case 24: + name = "Demir Hisar"; + break; + case 25: + name = "Demir Kapija"; + break; + case 26: + name = "Dobrusevo"; + break; + case 27: + name = "Dolna Banjica"; + break; + case 28: + name = "Dolneni"; + break; + case 29: + name = "Dorce Petrov"; + break; + case 30: + name = "Drugovo"; + break; + case 31: + name = "Dzepciste"; + break; + case 32: + name = "Gazi Baba"; + break; + case 33: + name = "Gevgelija"; + break; + case 34: + name = "Gostivar"; + break; + case 35: + name = "Gradsko"; + break; + case 36: + name = "Ilinden"; + break; + case 37: + name = "Izvor"; + break; + case 38: + name = "Jegunovce"; + break; + case 39: + name = "Kamenjane"; + break; + case 40: + name = "Karbinci"; + break; + case 41: + name = "Karpos"; + break; + case 42: + name = "Kavadarci"; + break; + case 43: + name = "Kicevo"; + break; + case 44: + name = "Kisela Voda"; + break; + case 45: + name = "Klecevce"; + break; + case 46: + name = "Kocani"; + break; + case 47: + name = "Konce"; + break; + case 48: + name = "Kondovo"; + break; + case 49: + name = "Konopiste"; + break; + case 50: + name = "Kosel"; + break; + case 51: + name = "Kratovo"; + break; + case 52: + name = "Kriva Palanka"; + break; + case 53: + name = "Krivogastani"; + break; + case 54: + name = "Krusevo"; + break; + case 55: + name = "Kuklis"; + break; + case 56: + name = "Kukurecani"; + break; + case 57: + name = "Kumanovo"; + break; + case 58: + name = "Labunista"; + break; + case 59: + name = "Lipkovo"; + break; + case 60: + name = "Lozovo"; + break; + case 61: + name = "Lukovo"; + break; + case 62: + name = "Makedonska Kamenica"; + break; + case 63: + name = "Makedonski Brod"; + break; + case 64: + name = "Mavrovi Anovi"; + break; + case 65: + name = "Meseista"; + break; + case 66: + name = "Miravci"; + break; + case 67: + name = "Mogila"; + break; + case 68: + name = "Murtino"; + break; + case 69: + name = "Negotino"; + break; + case 70: + name = "Negotino-Polosko"; + break; + case 71: + name = "Novaci"; + break; + case 72: + name = "Novo Selo"; + break; + case 73: + name = "Oblesevo"; + break; + case 74: + name = "Ohrid"; + break; + case 75: + name = "Orasac"; + break; + case 76: + name = "Orizari"; + break; + case 77: + name = "Oslomej"; + break; + case 78: + name = "Pehcevo"; + break; + case 79: + name = "Petrovec"; + break; + case 80: + name = "Plasnica"; + break; + case 81: + name = "Podares"; + break; + case 82: + name = "Prilep"; + break; + case 83: + name = "Probistip"; + break; + case 84: + name = "Radovis"; + break; + case 85: + name = "Rankovce"; + break; + case 86: + name = "Resen"; + break; + case 87: + name = "Rosoman"; + break; + case 88: + name = "Rostusa"; + break; + case 89: + name = "Samokov"; + break; + case 90: + name = "Saraj"; + break; + case 91: + name = "Sipkovica"; + break; + case 92: + name = "Sopiste"; + break; + case 93: + name = "Sopotnica"; + break; + case 94: + name = "Srbinovo"; + break; + case 95: + name = "Staravina"; + break; + case 96: + name = "Star Dojran"; + break; + case 97: + name = "Staro Nagoricane"; + break; + case 98: + name = "Stip"; + break; + case 99: + name = "Struga"; + break; + case 832: + name = "Strumica"; + break; + case 833: + name = "Studenicani"; + break; + case 834: + name = "Suto Orizari"; + break; + case 835: + name = "Sveti Nikole"; + break; + case 836: + name = "Tearce"; + break; + case 837: + name = "Tetovo"; + break; + case 838: + name = "Topolcani"; + break; + case 839: + name = "Valandovo"; + break; + case 840: + name = "Vasilevo"; + break; + case 875: + name = "Veles"; + break; + case 876: + name = "Velesta"; + break; + case 877: + name = "Vevcani"; + break; + case 878: + name = "Vinica"; + break; + case 879: + name = "Vitoliste"; + break; + case 880: + name = "Vranestica"; + break; + case 881: + name = "Vrapciste"; + break; + case 882: + name = "Vratnica"; + break; + case 883: + name = "Vrutok"; + break; + case 918: + name = "Zajas"; + break; + case 919: + name = "Zelenikovo"; + break; + case 920: + name = "Zelino"; + break; + case 921: + name = "Zitose"; + break; + case 922: + name = "Zletovo"; + break; + case 923: + name = "Zrnovci"; + break; + } + } + if (strcmp(country_code,"ML") == 0) { + switch (region_code2) { + case 1: + name = "Bamako"; + break; + case 3: + name = "Kayes"; + break; + case 4: + name = "Mopti"; + break; + case 5: + name = "Segou"; + break; + case 6: + name = "Sikasso"; + break; + case 7: + name = "Koulikoro"; + break; + case 8: + name = "Tombouctou"; + break; + case 9: + name = "Gao"; + break; + case 10: + name = "Kidal"; + break; + } + } + if (strcmp(country_code,"MM") == 0) { + switch (region_code2) { + case 1: + name = "Rakhine State"; + break; + case 2: + name = "Chin State"; + break; + case 3: + name = "Irrawaddy"; + break; + case 4: + name = "Kachin State"; + break; + case 5: + name = "Karan State"; + break; + case 6: + name = "Kayah State"; + break; + case 7: + name = "Magwe"; + break; + case 8: + name = "Mandalay"; + break; + case 9: + name = "Pegu"; + break; + case 10: + name = "Sagaing"; + break; + case 11: + name = "Shan State"; + break; + case 12: + name = "Tenasserim"; + break; + case 13: + name = "Mon State"; + break; + case 14: + name = "Rangoon"; + break; + case 17: + name = "Yangon"; + break; + } + } + if (strcmp(country_code,"MN") == 0) { + switch (region_code2) { + case 1: + name = "Arhangay"; + break; + case 2: + name = "Bayanhongor"; + break; + case 3: + name = "Bayan-Olgiy"; + break; + case 5: + name = "Darhan"; + break; + case 6: + name = "Dornod"; + break; + case 7: + name = "Dornogovi"; + break; + case 8: + name = "Dundgovi"; + break; + case 9: + name = "Dzavhan"; + break; + case 10: + name = "Govi-Altay"; + break; + case 11: + name = "Hentiy"; + break; + case 12: + name = "Hovd"; + break; + case 13: + name = "Hovsgol"; + break; + case 14: + name = "Omnogovi"; + break; + case 15: + name = "Ovorhangay"; + break; + case 16: + name = "Selenge"; + break; + case 17: + name = "Suhbaatar"; + break; + case 18: + name = "Tov"; + break; + case 19: + name = "Uvs"; + break; + case 20: + name = "Ulaanbaatar"; + break; + case 21: + name = "Bulgan"; + break; + case 22: + name = "Erdenet"; + break; + case 23: + name = "Darhan-Uul"; + break; + case 24: + name = "Govisumber"; + break; + case 25: + name = "Orhon"; + break; + } + } + if (strcmp(country_code,"MO") == 0) { + switch (region_code2) { + case 1: + name = "Ilhas"; + break; + case 2: + name = "Macau"; + break; + } + } + if (strcmp(country_code,"MR") == 0) { + switch (region_code2) { + case 1: + name = "Hodh Ech Chargui"; + break; + case 2: + name = "Hodh El Gharbi"; + break; + case 3: + name = "Assaba"; + break; + case 4: + name = "Gorgol"; + break; + case 5: + name = "Brakna"; + break; + case 6: + name = "Trarza"; + break; + case 7: + name = "Adrar"; + break; + case 8: + name = "Dakhlet Nouadhibou"; + break; + case 9: + name = "Tagant"; + break; + case 10: + name = "Guidimaka"; + break; + case 11: + name = "Tiris Zemmour"; + break; + case 12: + name = "Inchiri"; + break; + } + } + if (strcmp(country_code,"MS") == 0) { + switch (region_code2) { + case 1: + name = "Saint Anthony"; + break; + case 2: + name = "Saint Georges"; + break; + case 3: + name = "Saint Peter"; + break; + } + } + if (strcmp(country_code,"MU") == 0) { + switch (region_code2) { + case 12: + name = "Black River"; + break; + case 13: + name = "Flacq"; + break; + case 14: + name = "Grand Port"; + break; + case 15: + name = "Moka"; + break; + case 16: + name = "Pamplemousses"; + break; + case 17: + name = "Plaines Wilhems"; + break; + case 18: + name = "Port Louis"; + break; + case 19: + name = "Riviere du Rempart"; + break; + case 20: + name = "Savanne"; + break; + case 21: + name = "Agalega Islands"; + break; + case 22: + name = "Cargados Carajos"; + break; + case 23: + name = "Rodrigues"; + break; + } + } + if (strcmp(country_code,"MV") == 0) { + switch (region_code2) { + case 1: + name = "Seenu"; + break; + case 5: + name = "Laamu"; + break; + case 30: + name = "Alifu"; + break; + case 31: + name = "Baa"; + break; + case 32: + name = "Dhaalu"; + break; + case 33: + name = "Faafu "; + break; + case 34: + name = "Gaafu Alifu"; + break; + case 35: + name = "Gaafu Dhaalu"; + break; + case 36: + name = "Haa Alifu"; + break; + case 37: + name = "Haa Dhaalu"; + break; + case 38: + name = "Kaafu"; + break; + case 39: + name = "Lhaviyani"; + break; + case 40: + name = "Maale"; + break; + case 41: + name = "Meemu"; + break; + case 42: + name = "Gnaviyani"; + break; + case 43: + name = "Noonu"; + break; + case 44: + name = "Raa"; + break; + case 45: + name = "Shaviyani"; + break; + case 46: + name = "Thaa"; + break; + case 47: + name = "Vaavu"; + break; + } + } + if (strcmp(country_code,"MW") == 0) { + switch (region_code2) { + case 2: + name = "Chikwawa"; + break; + case 3: + name = "Chiradzulu"; + break; + case 4: + name = "Chitipa"; + break; + case 5: + name = "Thyolo"; + break; + case 6: + name = "Dedza"; + break; + case 7: + name = "Dowa"; + break; + case 8: + name = "Karonga"; + break; + case 9: + name = "Kasungu"; + break; + case 11: + name = "Lilongwe"; + break; + case 12: + name = "Mangochi"; + break; + case 13: + name = "Mchinji"; + break; + case 15: + name = "Mzimba"; + break; + case 16: + name = "Ntcheu"; + break; + case 17: + name = "Nkhata Bay"; + break; + case 18: + name = "Nkhotakota"; + break; + case 19: + name = "Nsanje"; + break; + case 20: + name = "Ntchisi"; + break; + case 21: + name = "Rumphi"; + break; + case 22: + name = "Salima"; + break; + case 23: + name = "Zomba"; + break; + case 24: + name = "Blantyre"; + break; + case 25: + name = "Mwanza"; + break; + case 26: + name = "Balaka"; + break; + case 27: + name = "Likoma"; + break; + case 28: + name = "Machinga"; + break; + case 29: + name = "Mulanje"; + break; + case 30: + name = "Phalombe"; + break; + } + } + if (strcmp(country_code,"MX") == 0) { + switch (region_code2) { + case 1: + name = "Aguascalientes"; + break; + case 2: + name = "Baja California"; + break; + case 3: + name = "Baja California Sur"; + break; + case 4: + name = "Campeche"; + break; + case 5: + name = "Chiapas"; + break; + case 6: + name = "Chihuahua"; + break; + case 7: + name = "Coahuila de Zaragoza"; + break; + case 8: + name = "Colima"; + break; + case 9: + name = "Distrito Federal"; + break; + case 10: + name = "Durango"; + break; + case 11: + name = "Guanajuato"; + break; + case 12: + name = "Guerrero"; + break; + case 13: + name = "Hidalgo"; + break; + case 14: + name = "Jalisco"; + break; + case 15: + name = "Mexico"; + break; + case 16: + name = "Michoacan de Ocampo"; + break; + case 17: + name = "Morelos"; + break; + case 18: + name = "Nayarit"; + break; + case 19: + name = "Nuevo Leon"; + break; + case 20: + name = "Oaxaca"; + break; + case 21: + name = "Puebla"; + break; + case 22: + name = "Queretaro de Arteaga"; + break; + case 23: + name = "Quintana Roo"; + break; + case 24: + name = "San Luis Potosi"; + break; + case 25: + name = "Sinaloa"; + break; + case 26: + name = "Sonora"; + break; + case 27: + name = "Tabasco"; + break; + case 28: + name = "Tamaulipas"; + break; + case 29: + name = "Tlaxcala"; + break; + case 30: + name = "Veracruz-Llave"; + break; + case 31: + name = "Yucatan"; + break; + case 32: + name = "Zacatecas"; + break; + } + } + if (strcmp(country_code,"MY") == 0) { + switch (region_code2) { + case 1: + name = "Johor"; + break; + case 2: + name = "Kedah"; + break; + case 3: + name = "Kelantan"; + break; + case 4: + name = "Melaka"; + break; + case 5: + name = "Negeri Sembilan"; + break; + case 6: + name = "Pahang"; + break; + case 7: + name = "Perak"; + break; + case 8: + name = "Perlis"; + break; + case 9: + name = "Pulau Pinang"; + break; + case 11: + name = "Sarawak"; + break; + case 12: + name = "Selangor"; + break; + case 13: + name = "Terengganu"; + break; + case 14: + name = "Kuala Lumpur"; + break; + case 15: + name = "Labuan"; + break; + case 16: + name = "Sabah"; + break; + case 17: + name = "Putrajaya"; + break; + } + } + if (strcmp(country_code,"MZ") == 0) { + switch (region_code2) { + case 1: + name = "Cabo Delgado"; + break; + case 2: + name = "Gaza"; + break; + case 3: + name = "Inhambane"; + break; + case 4: + name = "Maputo"; + break; + case 5: + name = "Sofala"; + break; + case 6: + name = "Nampula"; + break; + case 7: + name = "Niassa"; + break; + case 8: + name = "Tete"; + break; + case 9: + name = "Zambezia"; + break; + case 10: + name = "Manica"; + break; + case 11: + name = "Maputo"; + break; + } + } + if (strcmp(country_code,"NA") == 0) { + switch (region_code2) { + case 1: + name = "Bethanien"; + break; + case 2: + name = "Caprivi Oos"; + break; + case 3: + name = "Boesmanland"; + break; + case 4: + name = "Gobabis"; + break; + case 5: + name = "Grootfontein"; + break; + case 6: + name = "Kaokoland"; + break; + case 7: + name = "Karibib"; + break; + case 8: + name = "Keetmanshoop"; + break; + case 9: + name = "Luderitz"; + break; + case 10: + name = "Maltahohe"; + break; + case 11: + name = "Okahandja"; + break; + case 12: + name = "Omaruru"; + break; + case 13: + name = "Otjiwarongo"; + break; + case 14: + name = "Outjo"; + break; + case 15: + name = "Owambo"; + break; + case 16: + name = "Rehoboth"; + break; + case 17: + name = "Swakopmund"; + break; + case 18: + name = "Tsumeb"; + break; + case 20: + name = "Karasburg"; + break; + case 21: + name = "Windhoek"; + break; + case 22: + name = "Damaraland"; + break; + case 23: + name = "Hereroland Oos"; + break; + case 24: + name = "Hereroland Wes"; + break; + case 25: + name = "Kavango"; + break; + case 26: + name = "Mariental"; + break; + case 27: + name = "Namaland"; + break; + case 28: + name = "Caprivi"; + break; + case 29: + name = "Erongo"; + break; + case 30: + name = "Hardap"; + break; + case 31: + name = "Karas"; + break; + case 32: + name = "Kunene"; + break; + case 33: + name = "Ohangwena"; + break; + case 34: + name = "Okavango"; + break; + case 35: + name = "Omaheke"; + break; + case 36: + name = "Omusati"; + break; + case 37: + name = "Oshana"; + break; + case 38: + name = "Oshikoto"; + break; + case 39: + name = "Otjozondjupa"; + break; + } + } + if (strcmp(country_code,"NE") == 0) { + switch (region_code2) { + case 1: + name = "Agadez"; + break; + case 2: + name = "Diffa"; + break; + case 3: + name = "Dosso"; + break; + case 4: + name = "Maradi"; + break; + case 5: + name = "Niamey"; + break; + case 6: + name = "Tahoua"; + break; + case 7: + name = "Zinder"; + break; + case 8: + name = "Niamey"; + break; + } + } + if (strcmp(country_code,"NG") == 0) { + switch (region_code2) { + case 5: + name = "Lagos"; + break; + case 11: + name = "Federal Capital Territory"; + break; + case 16: + name = "Ogun"; + break; + case 21: + name = "Akwa Ibom"; + break; + case 22: + name = "Cross River"; + break; + case 23: + name = "Kaduna"; + break; + case 24: + name = "Katsina"; + break; + case 25: + name = "Anambra"; + break; + case 26: + name = "Benue"; + break; + case 27: + name = "Borno"; + break; + case 28: + name = "Imo"; + break; + case 29: + name = "Kano"; + break; + case 30: + name = "Kwara"; + break; + case 31: + name = "Niger"; + break; + case 32: + name = "Oyo"; + break; + case 35: + name = "Adamawa"; + break; + case 36: + name = "Delta"; + break; + case 37: + name = "Edo"; + break; + case 39: + name = "Jigawa"; + break; + case 40: + name = "Kebbi"; + break; + case 41: + name = "Kogi"; + break; + case 42: + name = "Osun"; + break; + case 43: + name = "Taraba"; + break; + case 44: + name = "Yobe"; + break; + case 45: + name = "Abia"; + break; + case 46: + name = "Bauchi"; + break; + case 47: + name = "Enugu"; + break; + case 48: + name = "Ondo"; + break; + case 49: + name = "Plateau"; + break; + case 50: + name = "Rivers"; + break; + case 51: + name = "Sokoto"; + break; + case 52: + name = "Bayelsa"; + break; + case 53: + name = "Ebonyi"; + break; + case 54: + name = "Ekiti"; + break; + case 55: + name = "Gombe"; + break; + case 56: + name = "Nassarawa"; + break; + case 57: + name = "Zamfara"; + break; + } + } + if (strcmp(country_code,"NI") == 0) { + switch (region_code2) { + case 1: + name = "Boaco"; + break; + case 2: + name = "Carazo"; + break; + case 3: + name = "Chinandega"; + break; + case 4: + name = "Chontales"; + break; + case 5: + name = "Esteli"; + break; + case 6: + name = "Granada"; + break; + case 7: + name = "Jinotega"; + break; + case 8: + name = "Leon"; + break; + case 9: + name = "Madriz"; + break; + case 10: + name = "Managua"; + break; + case 11: + name = "Masaya"; + break; + case 12: + name = "Matagalpa"; + break; + case 13: + name = "Nueva Segovia"; + break; + case 14: + name = "Rio San Juan"; + break; + case 15: + name = "Rivas"; + break; + case 16: + name = "Zelaya"; + break; + case 17: + name = "Autonoma Atlantico Norte"; + break; + case 18: + name = "Region Autonoma Atlantico Sur"; + break; + } + } + if (strcmp(country_code,"NL") == 0) { + switch (region_code2) { + case 1: + name = "Drenthe"; + break; + case 2: + name = "Friesland"; + break; + case 3: + name = "Gelderland"; + break; + case 4: + name = "Groningen"; + break; + case 5: + name = "Limburg"; + break; + case 6: + name = "Noord-Brabant"; + break; + case 7: + name = "Noord-Holland"; + break; + case 8: + name = "Overijssel"; + break; + case 9: + name = "Utrecht"; + break; + case 10: + name = "Zeeland"; + break; + case 11: + name = "Zuid-Holland"; + break; + case 15: + name = "Overijssel"; + break; + case 16: + name = "Flevoland"; + break; + } + } + if (strcmp(country_code,"NO") == 0) { + switch (region_code2) { + case 1: + name = "Akershus"; + break; + case 2: + name = "Aust-Agder"; + break; + case 4: + name = "Buskerud"; + break; + case 5: + name = "Finnmark"; + break; + case 6: + name = "Hedmark"; + break; + case 7: + name = "Hordaland"; + break; + case 8: + name = "More og Romsdal"; + break; + case 9: + name = "Nordland"; + break; + case 10: + name = "Nord-Trondelag"; + break; + case 11: + name = "Oppland"; + break; + case 12: + name = "Oslo"; + break; + case 13: + name = "Ostfold"; + break; + case 14: + name = "Rogaland"; + break; + case 15: + name = "Sogn og Fjordane"; + break; + case 16: + name = "Sor-Trondelag"; + break; + case 17: + name = "Telemark"; + break; + case 18: + name = "Troms"; + break; + case 19: + name = "Vest-Agder"; + break; + case 20: + name = "Vestfold"; + break; + } + } + if (strcmp(country_code,"NP") == 0) { + switch (region_code2) { + case 1: + name = "Bagmati"; + break; + case 2: + name = "Bheri"; + break; + case 3: + name = "Dhawalagiri"; + break; + case 4: + name = "Gandaki"; + break; + case 5: + name = "Janakpur"; + break; + case 6: + name = "Karnali"; + break; + case 7: + name = "Kosi"; + break; + case 8: + name = "Lumbini"; + break; + case 9: + name = "Mahakali"; + break; + case 10: + name = "Mechi"; + break; + case 11: + name = "Narayani"; + break; + case 12: + name = "Rapti"; + break; + case 13: + name = "Sagarmatha"; + break; + case 14: + name = "Seti"; + break; + } + } + if (strcmp(country_code,"NR") == 0) { + switch (region_code2) { + case 1: + name = "Aiwo"; + break; + case 2: + name = "Anabar"; + break; + case 3: + name = "Anetan"; + break; + case 4: + name = "Anibare"; + break; + case 5: + name = "Baiti"; + break; + case 6: + name = "Boe"; + break; + case 7: + name = "Buada"; + break; + case 8: + name = "Denigomodu"; + break; + case 9: + name = "Ewa"; + break; + case 10: + name = "Ijuw"; + break; + case 11: + name = "Meneng"; + break; + case 12: + name = "Nibok"; + break; + case 13: + name = "Uaboe"; + break; + case 14: + name = "Yaren"; + break; + } + } + if (strcmp(country_code,"NZ") == 0) { + switch (region_code2) { + case 10: + name = "Chatham Islands"; + break; + case 1010: + name = "Auckland"; + break; + case 1011: + name = "Bay of Plenty"; + break; + case 1012: + name = "Canterbury"; + break; + case 1047: + name = "Gisborne"; + break; + case 1048: + name = "Hawke's Bay"; + break; + case 1049: + name = "Manawatu-Wanganui"; + break; + case 1050: + name = "Marlborough"; + break; + case 1051: + name = "Nelson"; + break; + case 1052: + name = "Northland"; + break; + case 1053: + name = "Otago"; + break; + case 1054: + name = "Southland"; + break; + case 1055: + name = "Taranaki"; + break; + case 1090: + name = "Waikato"; + break; + case 1091: + name = "Wellington"; + break; + case 1092: + name = "West Coast"; + break; + } + } + if (strcmp(country_code,"OM") == 0) { + switch (region_code2) { + case 1: + name = "Ad Dakhiliyah"; + break; + case 2: + name = "Al Batinah"; + break; + case 3: + name = "Al Wusta"; + break; + case 4: + name = "Ash Sharqiyah"; + break; + case 5: + name = "Az Zahirah"; + break; + case 6: + name = "Masqat"; + break; + case 7: + name = "Musandam"; + break; + case 8: + name = "Zufar"; + break; + } + } + if (strcmp(country_code,"PA") == 0) { + switch (region_code2) { + case 1: + name = "Bocas del Toro"; + break; + case 2: + name = "Chiriqui"; + break; + case 3: + name = "Cocle"; + break; + case 4: + name = "Colon"; + break; + case 5: + name = "Darien"; + break; + case 6: + name = "Herrera"; + break; + case 7: + name = "Los Santos"; + break; + case 8: + name = "Panama"; + break; + case 9: + name = "San Blas"; + break; + case 10: + name = "Veraguas"; + break; + } + } + if (strcmp(country_code,"PE") == 0) { + switch (region_code2) { + case 1: + name = "Amazonas"; + break; + case 2: + name = "Ancash"; + break; + case 3: + name = "Apurimac"; + break; + case 4: + name = "Arequipa"; + break; + case 5: + name = "Ayacucho"; + break; + case 6: + name = "Cajamarca"; + break; + case 7: + name = "Callao"; + break; + case 8: + name = "Cusco"; + break; + case 9: + name = "Huancavelica"; + break; + case 10: + name = "Huanuco"; + break; + case 11: + name = "Ica"; + break; + case 12: + name = "Junin"; + break; + case 13: + name = "La Libertad"; + break; + case 14: + name = "Lambayeque"; + break; + case 15: + name = "Lima"; + break; + case 16: + name = "Loreto"; + break; + case 17: + name = "Madre de Dios"; + break; + case 18: + name = "Moquegua"; + break; + case 19: + name = "Pasco"; + break; + case 20: + name = "Piura"; + break; + case 21: + name = "Puno"; + break; + case 22: + name = "San Martin"; + break; + case 23: + name = "Tacna"; + break; + case 24: + name = "Tumbes"; + break; + case 25: + name = "Ucayali"; + break; + } + } + if (strcmp(country_code,"PG") == 0) { + switch (region_code2) { + case 1: + name = "Central"; + break; + case 2: + name = "Gulf"; + break; + case 3: + name = "Milne Bay"; + break; + case 4: + name = "Northern"; + break; + case 5: + name = "Southern Highlands"; + break; + case 6: + name = "Western"; + break; + case 7: + name = "North Solomons"; + break; + case 8: + name = "Chimbu"; + break; + case 9: + name = "Eastern Highlands"; + break; + case 10: + name = "East New Britain"; + break; + case 11: + name = "East Sepik"; + break; + case 12: + name = "Madang"; + break; + case 13: + name = "Manus"; + break; + case 14: + name = "Morobe"; + break; + case 15: + name = "New Ireland"; + break; + case 16: + name = "Western Highlands"; + break; + case 17: + name = "West New Britain"; + break; + case 18: + name = "Sandaun"; + break; + case 19: + name = "Enga"; + break; + case 20: + name = "National Capital"; + break; + } + } + if (strcmp(country_code,"PH") == 0) { + switch (region_code2) { + case 1: + name = "Abra"; + break; + case 2: + name = "Agusan del Norte"; + break; + case 3: + name = "Agusan del Sur"; + break; + case 4: + name = "Aklan"; + break; + case 5: + name = "Albay"; + break; + case 6: + name = "Antique"; + break; + case 7: + name = "Bataan"; + break; + case 8: + name = "Batanes"; + break; + case 9: + name = "Batangas"; + break; + case 10: + name = "Benguet"; + break; + case 11: + name = "Bohol"; + break; + case 12: + name = "Bukidnon"; + break; + case 13: + name = "Bulacan"; + break; + case 14: + name = "Cagayan"; + break; + case 15: + name = "Camarines Norte"; + break; + case 16: + name = "Camarines Sur"; + break; + case 17: + name = "Camiguin"; + break; + case 18: + name = "Capiz"; + break; + case 19: + name = "Catanduanes"; + break; + case 20: + name = "Cavite"; + break; + case 21: + name = "Cebu"; + break; + case 22: + name = "Basilan"; + break; + case 23: + name = "Eastern Samar"; + break; + case 24: + name = "Davao"; + break; + case 25: + name = "Davao del Sur"; + break; + case 26: + name = "Davao Oriental"; + break; + case 27: + name = "Ifugao"; + break; + case 28: + name = "Ilocos Norte"; + break; + case 29: + name = "Ilocos Sur"; + break; + case 30: + name = "Iloilo"; + break; + case 31: + name = "Isabela"; + break; + case 32: + name = "Kalinga-Apayao"; + break; + case 33: + name = "Laguna"; + break; + case 34: + name = "Lanao del Norte"; + break; + case 35: + name = "Lanao del Sur"; + break; + case 36: + name = "La Union"; + break; + case 37: + name = "Leyte"; + break; + case 38: + name = "Marinduque"; + break; + case 39: + name = "Masbate"; + break; + case 40: + name = "Mindoro Occidental"; + break; + case 41: + name = "Mindoro Oriental"; + break; + case 42: + name = "Misamis Occidental"; + break; + case 43: + name = "Misamis Oriental"; + break; + case 44: + name = "Mountain"; + break; + case 45: + name = "Negros Occidental"; + break; + case 46: + name = "Negros Oriental"; + break; + case 47: + name = "Nueva Ecija"; + break; + case 48: + name = "Nueva Vizcaya"; + break; + case 49: + name = "Palawan"; + break; + case 50: + name = "Pampanga"; + break; + case 51: + name = "Pangasinan"; + break; + case 53: + name = "Rizal"; + break; + case 54: + name = "Romblon"; + break; + case 55: + name = "Samar"; + break; + case 56: + name = "Maguindanao"; + break; + case 57: + name = "North Cotabato"; + break; + case 58: + name = "Sorsogon"; + break; + case 59: + name = "Southern Leyte"; + break; + case 60: + name = "Sulu"; + break; + case 61: + name = "Surigao del Norte"; + break; + case 62: + name = "Surigao del Sur"; + break; + case 63: + name = "Tarlac"; + break; + case 64: + name = "Zambales"; + break; + case 65: + name = "Zamboanga del Norte"; + break; + case 66: + name = "Zamboanga del Sur"; + break; + case 67: + name = "Northern Samar"; + break; + case 68: + name = "Quirino"; + break; + case 69: + name = "Siquijor"; + break; + case 70: + name = "South Cotabato"; + break; + case 71: + name = "Sultan Kudarat"; + break; + case 72: + name = "Tawitawi"; + break; + case 832: + name = "Angeles"; + break; + case 833: + name = "Bacolod"; + break; + case 834: + name = "Bago"; + break; + case 835: + name = "Baguio"; + break; + case 836: + name = "Bais"; + break; + case 837: + name = "Basilan City"; + break; + case 838: + name = "Batangas City"; + break; + case 839: + name = "Butuan"; + break; + case 840: + name = "Cabanatuan"; + break; + case 875: + name = "Cadiz"; + break; + case 876: + name = "Cagayan de Oro"; + break; + case 877: + name = "Calbayog"; + break; + case 878: + name = "Caloocan"; + break; + case 879: + name = "Canlaon"; + break; + case 880: + name = "Cavite City"; + break; + case 881: + name = "Cebu City"; + break; + case 882: + name = "Cotabato"; + break; + case 883: + name = "Dagupan"; + break; + case 918: + name = "Danao"; + break; + case 919: + name = "Dapitan"; + break; + case 920: + name = "Davao City"; + break; + case 921: + name = "Dipolog"; + break; + case 922: + name = "Dumaguete"; + break; + case 923: + name = "General Santos"; + break; + case 924: + name = "Gingoog"; + break; + case 925: + name = "Iligan"; + break; + case 926: + name = "Iloilo City"; + break; + case 961: + name = "Iriga"; + break; + case 962: + name = "La Carlota"; + break; + case 963: + name = "Laoag"; + break; + case 964: + name = "Lapu-Lapu"; + break; + case 965: + name = "Legaspi"; + break; + case 966: + name = "Lipa"; + break; + case 967: + name = "Lucena"; + break; + case 968: + name = "Mandaue"; + break; + case 969: + name = "Manila"; + break; + case 1004: + name = "Marawi"; + break; + case 1005: + name = "Naga"; + break; + case 1006: + name = "Olongapo"; + break; + case 1007: + name = "Ormoc"; + break; + case 1008: + name = "Oroquieta"; + break; + case 1009: + name = "Ozamis"; + break; + case 1010: + name = "Pagadian"; + break; + case 1011: + name = "Palayan"; + break; + case 1012: + name = "Pasay"; + break; + case 1047: + name = "Puerto Princesa"; + break; + case 1048: + name = "Quezon City"; + break; + case 1049: + name = "Roxas"; + break; + case 1050: + name = "San Carlos"; + break; + case 1051: + name = "San Carlos"; + break; + case 1052: + name = "San Jose"; + break; + case 1053: + name = "San Pablo"; + break; + case 1054: + name = "Silay"; + break; + case 1055: + name = "Surigao"; + break; + case 1090: + name = "Tacloban"; + break; + case 1091: + name = "Tagaytay"; + break; + case 1092: + name = "Tagbilaran"; + break; + case 1093: + name = "Tangub"; + break; + case 1094: + name = "Toledo"; + break; + case 1095: + name = "Trece Martires"; + break; + case 1096: + name = "Zamboanga"; + break; + case 1097: + name = "Aurora"; + break; + case 1134: + name = "Quezon"; + break; + case 1135: + name = "Negros Occidental"; + break; + } + } + if (strcmp(country_code,"PK") == 0) { + switch (region_code2) { + case 1: + name = "Federally Administered Tribal Areas"; + break; + case 2: + name = "Balochistan"; + break; + case 3: + name = "North-West Frontier"; + break; + case 4: + name = "Punjab"; + break; + case 5: + name = "Sindh"; + break; + case 6: + name = "Azad Kashmir"; + break; + case 7: + name = "Northern Areas"; + break; + case 8: + name = "Islamabad"; + break; + } + } + if (strcmp(country_code,"PL") == 0) { + switch (region_code2) { + case 72: + name = "Dolnoslaskie"; + break; + case 73: + name = "Kujawsko-Pomorskie"; + break; + case 74: + name = "Lodzkie"; + break; + case 75: + name = "Lubelskie"; + break; + case 76: + name = "Lubuskie"; + break; + case 77: + name = "Malopolskie"; + break; + case 78: + name = "Mazowieckie"; + break; + case 79: + name = "Opolskie"; + break; + case 80: + name = "Podkarpackie"; + break; + case 81: + name = "Podlaskie"; + break; + case 82: + name = "Pomorskie"; + break; + case 83: + name = "Slaskie"; + break; + case 84: + name = "Swietokrzyskie"; + break; + case 85: + name = "Warminsko-Mazurskie"; + break; + case 86: + name = "Wielkopolskie"; + break; + case 87: + name = "Zachodniopomorskie"; + break; + } + } + if (strcmp(country_code,"PS") == 0) { + switch (region_code2) { + case 1131: + name = "Gaza"; + break; + case 1798: + name = "West Bank"; + break; + } + } + if (strcmp(country_code,"PT") == 0) { + switch (region_code2) { + case 2: + name = "Aveiro"; + break; + case 3: + name = "Beja"; + break; + case 4: + name = "Braga"; + break; + case 5: + name = "Braganca"; + break; + case 6: + name = "Castelo Branco"; + break; + case 7: + name = "Coimbra"; + break; + case 8: + name = "Evora"; + break; + case 9: + name = "Faro"; + break; + case 10: + name = "Madeira"; + break; + case 11: + name = "Guarda"; + break; + case 13: + name = "Leiria"; + break; + case 14: + name = "Lisboa"; + break; + case 16: + name = "Portalegre"; + break; + case 17: + name = "Porto"; + break; + case 18: + name = "Santarem"; + break; + case 19: + name = "Setubal"; + break; + case 20: + name = "Viana do Castelo"; + break; + case 21: + name = "Vila Real"; + break; + case 22: + name = "Viseu"; + break; + case 23: + name = "Azores"; + break; + } + } + if (strcmp(country_code,"PY") == 0) { + switch (region_code2) { + case 1: + name = "Alto Parana"; + break; + case 2: + name = "Amambay"; + break; + case 3: + name = "Boqueron"; + break; + case 4: + name = "Caaguazu"; + break; + case 5: + name = "Caazapa"; + break; + case 6: + name = "Central"; + break; + case 7: + name = "Concepcion"; + break; + case 8: + name = "Cordillera"; + break; + case 10: + name = "Guaira"; + break; + case 11: + name = "Itapua"; + break; + case 12: + name = "Misiones"; + break; + case 13: + name = "Neembucu"; + break; + case 15: + name = "Paraguari"; + break; + case 16: + name = "Presidente Hayes"; + break; + case 17: + name = "San Pedro"; + break; + case 19: + name = "Canindeyu"; + break; + case 20: + name = "Chaco"; + break; + case 21: + name = "Nueva Asuncion"; + break; + case 23: + name = "Alto Paraguay"; + break; + } + } + if (strcmp(country_code,"QA") == 0) { + switch (region_code2) { + case 1: + name = "Ad Dawhah"; + break; + case 2: + name = "Al Ghuwariyah"; + break; + case 3: + name = "Al Jumaliyah"; + break; + case 4: + name = "Al Khawr"; + break; + case 5: + name = "Al Wakrah Municipality"; + break; + case 6: + name = "Ar Rayyan"; + break; + case 8: + name = "Madinat ach Shamal"; + break; + case 9: + name = "Umm Salal"; + break; + case 10: + name = "Al Wakrah"; + break; + case 11: + name = "Jariyan al Batnah"; + break; + case 12: + name = "Umm Sa'id"; + break; + } + } + if (strcmp(country_code,"RO") == 0) { + switch (region_code2) { + case 1: + name = "Alba"; + break; + case 2: + name = "Arad"; + break; + case 3: + name = "Arges"; + break; + case 4: + name = "Bacau"; + break; + case 5: + name = "Bihor"; + break; + case 6: + name = "Bistrita-Nasaud"; + break; + case 7: + name = "Botosani"; + break; + case 8: + name = "Braila"; + break; + case 9: + name = "Brasov"; + break; + case 10: + name = "Bucuresti"; + break; + case 11: + name = "Buzau"; + break; + case 12: + name = "Caras-Severin"; + break; + case 13: + name = "Cluj"; + break; + case 14: + name = "Constanta"; + break; + case 15: + name = "Covasna"; + break; + case 16: + name = "Dambovita"; + break; + case 17: + name = "Dolj"; + break; + case 18: + name = "Galati"; + break; + case 19: + name = "Gorj"; + break; + case 20: + name = "Harghita"; + break; + case 21: + name = "Hunedoara"; + break; + case 22: + name = "Ialomita"; + break; + case 23: + name = "Iasi"; + break; + case 25: + name = "Maramures"; + break; + case 26: + name = "Mehedinti"; + break; + case 27: + name = "Mures"; + break; + case 28: + name = "Neamt"; + break; + case 29: + name = "Olt"; + break; + case 30: + name = "Prahova"; + break; + case 31: + name = "Salaj"; + break; + case 32: + name = "Satu Mare"; + break; + case 33: + name = "Sibiu"; + break; + case 34: + name = "Suceava"; + break; + case 35: + name = "Teleorman"; + break; + case 36: + name = "Timis"; + break; + case 37: + name = "Tulcea"; + break; + case 38: + name = "Vaslui"; + break; + case 39: + name = "Valcea"; + break; + case 40: + name = "Vrancea"; + break; + case 41: + name = "Calarasi"; + break; + case 42: + name = "Giurgiu"; + break; + case 43: + name = "Ilfov"; + break; + } + } + if (strcmp(country_code,"RS") == 0) { + switch (region_code2) { + case 1: + name = "Kosovo"; + break; + case 2: + name = "Vojvodina"; + break; + } + } + if (strcmp(country_code,"RU") == 0) { + switch (region_code2) { + case 1: + name = "Adygeya, Republic of"; + break; + case 2: + name = "Aginsky Buryatsky AO"; + break; + case 3: + name = "Gorno-Altay"; + break; + case 4: + name = "Altaisky krai"; + break; + case 5: + name = "Amur"; + break; + case 6: + name = "Arkhangel'sk"; + break; + case 7: + name = "Astrakhan'"; + break; + case 8: + name = "Bashkortostan"; + break; + case 9: + name = "Belgorod"; + break; + case 10: + name = "Bryansk"; + break; + case 11: + name = "Buryat"; + break; + case 12: + name = "Chechnya"; + break; + case 13: + name = "Chelyabinsk"; + break; + case 14: + name = "Chita"; + break; + case 15: + name = "Chukot"; + break; + case 16: + name = "Chuvashia"; + break; + case 17: + name = "Dagestan"; + break; + case 18: + name = "Evenk"; + break; + case 19: + name = "Ingush"; + break; + case 20: + name = "Irkutsk"; + break; + case 21: + name = "Ivanovo"; + break; + case 22: + name = "Kabardin-Balkar"; + break; + case 23: + name = "Kaliningrad"; + break; + case 24: + name = "Kalmyk"; + break; + case 25: + name = "Kaluga"; + break; + case 26: + name = "Kamchatka"; + break; + case 27: + name = "Karachay-Cherkess"; + break; + case 28: + name = "Karelia"; + break; + case 29: + name = "Kemerovo"; + break; + case 30: + name = "Khabarovsk"; + break; + case 31: + name = "Khakass"; + break; + case 32: + name = "Khanty-Mansiy"; + break; + case 33: + name = "Kirov"; + break; + case 34: + name = "Komi"; + break; + case 35: + name = "Komi-Permyak"; + break; + case 36: + name = "Koryak"; + break; + case 37: + name = "Kostroma"; + break; + case 38: + name = "Krasnodar"; + break; + case 39: + name = "Krasnoyarsk"; + break; + case 40: + name = "Kurgan"; + break; + case 41: + name = "Kursk"; + break; + case 42: + name = "Leningrad"; + break; + case 43: + name = "Lipetsk"; + break; + case 44: + name = "Magadan"; + break; + case 45: + name = "Mariy-El"; + break; + case 46: + name = "Mordovia"; + break; + case 47: + name = "Moskva"; + break; + case 48: + name = "Moscow City"; + break; + case 49: + name = "Murmansk"; + break; + case 50: + name = "Nenets"; + break; + case 51: + name = "Nizhegorod"; + break; + case 52: + name = "Novgorod"; + break; + case 53: + name = "Novosibirsk"; + break; + case 54: + name = "Omsk"; + break; + case 55: + name = "Orenburg"; + break; + case 56: + name = "Orel"; + break; + case 57: + name = "Penza"; + break; + case 58: + name = "Perm'"; + break; + case 59: + name = "Primor'ye"; + break; + case 60: + name = "Pskov"; + break; + case 61: + name = "Rostov"; + break; + case 62: + name = "Ryazan'"; + break; + case 63: + name = "Sakha"; + break; + case 64: + name = "Sakhalin"; + break; + case 65: + name = "Samara"; + break; + case 66: + name = "Saint Petersburg City"; + break; + case 67: + name = "Saratov"; + break; + case 68: + name = "North Ossetia"; + break; + case 69: + name = "Smolensk"; + break; + case 70: + name = "Stavropol'"; + break; + case 71: + name = "Sverdlovsk"; + break; + case 72: + name = "Tambovskaya oblast"; + break; + case 73: + name = "Tatarstan"; + break; + case 74: + name = "Taymyr"; + break; + case 75: + name = "Tomsk"; + break; + case 76: + name = "Tula"; + break; + case 77: + name = "Tver'"; + break; + case 78: + name = "Tyumen'"; + break; + case 79: + name = "Tuva"; + break; + case 80: + name = "Udmurt"; + break; + case 81: + name = "Ul'yanovsk"; + break; + case 82: + name = "Ust-Orda Buryat"; + break; + case 83: + name = "Vladimir"; + break; + case 84: + name = "Volgograd"; + break; + case 85: + name = "Vologda"; + break; + case 86: + name = "Voronezh"; + break; + case 87: + name = "Yamal-Nenets"; + break; + case 88: + name = "Yaroslavl'"; + break; + case 89: + name = "Yevrey"; + break; + case 90: + name = "Permskiy Kray"; + break; + case 91: + name = "Krasnoyarskiy Kray"; + break; + case 942: + name = "Chechnya Republic"; + break; + } + } + if (strcmp(country_code,"RW") == 0) { + switch (region_code2) { + case 1: + name = "Butare"; + break; + case 6: + name = "Gitarama"; + break; + case 7: + name = "Kibungo"; + break; + case 9: + name = "Kigali"; + break; + case 11: + name = "Est"; + break; + case 12: + name = "Kigali"; + break; + case 13: + name = "Nord"; + break; + case 14: + name = "Ouest"; + break; + case 15: + name = "Sud"; + break; + } + } + if (strcmp(country_code,"SA") == 0) { + switch (region_code2) { + case 2: + name = "Al Bahah"; + break; + case 3: + name = "Al Jawf"; + break; + case 5: + name = "Al Madinah"; + break; + case 6: + name = "Ash Sharqiyah"; + break; + case 8: + name = "Al Qasim"; + break; + case 9: + name = "Al Qurayyat"; + break; + case 10: + name = "Ar Riyad"; + break; + case 13: + name = "Ha'il"; + break; + case 14: + name = "Makkah"; + break; + case 15: + name = "Al Hudud ash Shamaliyah"; + break; + case 16: + name = "Najran"; + break; + case 17: + name = "Jizan"; + break; + case 19: + name = "Tabuk"; + break; + case 20: + name = "Al Jawf"; + break; + } + } + if (strcmp(country_code,"SB") == 0) { + switch (region_code2) { + case 3: + name = "Malaita"; + break; + case 6: + name = "Guadalcanal"; + break; + case 7: + name = "Isabel"; + break; + case 8: + name = "Makira"; + break; + case 9: + name = "Temotu"; + break; + case 10: + name = "Central"; + break; + case 11: + name = "Western"; + break; + case 12: + name = "Choiseul"; + break; + case 13: + name = "Rennell and Bellona"; + break; + } + } + if (strcmp(country_code,"SC") == 0) { + switch (region_code2) { + case 1: + name = "Anse aux Pins"; + break; + case 2: + name = "Anse Boileau"; + break; + case 3: + name = "Anse Etoile"; + break; + case 4: + name = "Anse Louis"; + break; + case 5: + name = "Anse Royale"; + break; + case 6: + name = "Baie Lazare"; + break; + case 7: + name = "Baie Sainte Anne"; + break; + case 8: + name = "Beau Vallon"; + break; + case 9: + name = "Bel Air"; + break; + case 10: + name = "Bel Ombre"; + break; + case 11: + name = "Cascade"; + break; + case 12: + name = "Glacis"; + break; + case 13: + name = "Grand' Anse"; + break; + case 14: + name = "Grand' Anse"; + break; + case 15: + name = "La Digue"; + break; + case 16: + name = "La Riviere Anglaise"; + break; + case 17: + name = "Mont Buxton"; + break; + case 18: + name = "Mont Fleuri"; + break; + case 19: + name = "Plaisance"; + break; + case 20: + name = "Pointe La Rue"; + break; + case 21: + name = "Port Glaud"; + break; + case 22: + name = "Saint Louis"; + break; + case 23: + name = "Takamaka"; + break; + } + } + if (strcmp(country_code,"SD") == 0) { + switch (region_code2) { + case 27: + name = "Al Wusta"; + break; + case 28: + name = "Al Istiwa'iyah"; + break; + case 29: + name = "Al Khartum"; + break; + case 30: + name = "Ash Shamaliyah"; + break; + case 31: + name = "Ash Sharqiyah"; + break; + case 32: + name = "Bahr al Ghazal"; + break; + case 33: + name = "Darfur"; + break; + case 34: + name = "Kurdufan"; + break; + case 35: + name = "Upper Nile"; + break; + case 40: + name = "Al Wahadah State"; + break; + case 44: + name = "Central Equatoria State"; + break; + } + } + if (strcmp(country_code,"SE") == 0) { + switch (region_code2) { + case 2: + name = "Blekinge Lan"; + break; + case 3: + name = "Gavleborgs Lan"; + break; + case 5: + name = "Gotlands Lan"; + break; + case 6: + name = "Hallands Lan"; + break; + case 7: + name = "Jamtlands Lan"; + break; + case 8: + name = "Jonkopings Lan"; + break; + case 9: + name = "Kalmar Lan"; + break; + case 10: + name = "Dalarnas Lan"; + break; + case 12: + name = "Kronobergs Lan"; + break; + case 14: + name = "Norrbottens Lan"; + break; + case 15: + name = "Orebro Lan"; + break; + case 16: + name = "Ostergotlands Lan"; + break; + case 18: + name = "Sodermanlands Lan"; + break; + case 21: + name = "Uppsala Lan"; + break; + case 22: + name = "Varmlands Lan"; + break; + case 23: + name = "Vasterbottens Lan"; + break; + case 24: + name = "Vasternorrlands Lan"; + break; + case 25: + name = "Vastmanlands Lan"; + break; + case 26: + name = "Stockholms Lan"; + break; + case 27: + name = "Skane Lan"; + break; + case 28: + name = "Vastra Gotaland"; + break; + } + } + if (strcmp(country_code,"SH") == 0) { + switch (region_code2) { + case 1: + name = "Ascension"; + break; + case 2: + name = "Saint Helena"; + break; + case 3: + name = "Tristan da Cunha"; + break; + } + } + if (strcmp(country_code,"SI") == 0) { + switch (region_code2) { + case 1: + name = "Ajdovscina"; + break; + case 2: + name = "Beltinci"; + break; + case 3: + name = "Bled"; + break; + case 4: + name = "Bohinj"; + break; + case 5: + name = "Borovnica"; + break; + case 6: + name = "Bovec"; + break; + case 7: + name = "Brda"; + break; + case 8: + name = "Brezice"; + break; + case 9: + name = "Brezovica"; + break; + case 11: + name = "Celje"; + break; + case 12: + name = "Cerklje na Gorenjskem"; + break; + case 13: + name = "Cerknica"; + break; + case 14: + name = "Cerkno"; + break; + case 15: + name = "Crensovci"; + break; + case 16: + name = "Crna na Koroskem"; + break; + case 17: + name = "Crnomelj"; + break; + case 19: + name = "Divaca"; + break; + case 20: + name = "Dobrepolje"; + break; + case 22: + name = "Dol pri Ljubljani"; + break; + case 24: + name = "Dornava"; + break; + case 25: + name = "Dravograd"; + break; + case 26: + name = "Duplek"; + break; + case 27: + name = "Gorenja Vas-Poljane"; + break; + case 28: + name = "Gorisnica"; + break; + case 29: + name = "Gornja Radgona"; + break; + case 30: + name = "Gornji Grad"; + break; + case 31: + name = "Gornji Petrovci"; + break; + case 32: + name = "Grosuplje"; + break; + case 34: + name = "Hrastnik"; + break; + case 35: + name = "Hrpelje-Kozina"; + break; + case 36: + name = "Idrija"; + break; + case 37: + name = "Ig"; + break; + case 38: + name = "Ilirska Bistrica"; + break; + case 39: + name = "Ivancna Gorica"; + break; + case 40: + name = "Izola-Isola"; + break; + case 42: + name = "Jursinci"; + break; + case 44: + name = "Kanal"; + break; + case 45: + name = "Kidricevo"; + break; + case 46: + name = "Kobarid"; + break; + case 47: + name = "Kobilje"; + break; + case 49: + name = "Komen"; + break; + case 50: + name = "Koper-Capodistria"; + break; + case 51: + name = "Kozje"; + break; + case 52: + name = "Kranj"; + break; + case 53: + name = "Kranjska Gora"; + break; + case 54: + name = "Krsko"; + break; + case 55: + name = "Kungota"; + break; + case 57: + name = "Lasko"; + break; + case 61: + name = "Ljubljana"; + break; + case 62: + name = "Ljubno"; + break; + case 64: + name = "Logatec"; + break; + case 66: + name = "Loski Potok"; + break; + case 68: + name = "Lukovica"; + break; + case 71: + name = "Medvode"; + break; + case 72: + name = "Menges"; + break; + case 73: + name = "Metlika"; + break; + case 74: + name = "Mezica"; + break; + case 76: + name = "Mislinja"; + break; + case 77: + name = "Moravce"; + break; + case 78: + name = "Moravske Toplice"; + break; + case 79: + name = "Mozirje"; + break; + case 80: + name = "Murska Sobota"; + break; + case 81: + name = "Muta"; + break; + case 82: + name = "Naklo"; + break; + case 83: + name = "Nazarje"; + break; + case 84: + name = "Nova Gorica"; + break; + case 86: + name = "Odranci"; + break; + case 87: + name = "Ormoz"; + break; + case 88: + name = "Osilnica"; + break; + case 89: + name = "Pesnica"; + break; + case 91: + name = "Pivka"; + break; + case 92: + name = "Podcetrtek"; + break; + case 94: + name = "Postojna"; + break; + case 97: + name = "Puconci"; + break; + case 98: + name = "Racam"; + break; + case 99: + name = "Radece"; + break; + case 832: + name = "Radenci"; + break; + case 833: + name = "Radlje ob Dravi"; + break; + case 834: + name = "Radovljica"; + break; + case 837: + name = "Rogasovci"; + break; + case 838: + name = "Rogaska Slatina"; + break; + case 839: + name = "Rogatec"; + break; + case 875: + name = "Semic"; + break; + case 876: + name = "Sencur"; + break; + case 877: + name = "Sentilj"; + break; + case 878: + name = "Sentjernej"; + break; + case 880: + name = "Sevnica"; + break; + case 881: + name = "Sezana"; + break; + case 882: + name = "Skocjan"; + break; + case 883: + name = "Skofja Loka"; + break; + case 918: + name = "Skofljica"; + break; + case 919: + name = "Slovenj Gradec"; + break; + case 921: + name = "Slovenske Konjice"; + break; + case 922: + name = "Smarje pri Jelsah"; + break; + case 923: + name = "Smartno ob Paki"; + break; + case 924: + name = "Sostanj"; + break; + case 925: + name = "Starse"; + break; + case 926: + name = "Store"; + break; + case 961: + name = "Sveti Jurij"; + break; + case 962: + name = "Tolmin"; + break; + case 963: + name = "Trbovlje"; + break; + case 964: + name = "Trebnje"; + break; + case 965: + name = "Trzic"; + break; + case 966: + name = "Turnisce"; + break; + case 967: + name = "Velenje"; + break; + case 968: + name = "Velike Lasce"; + break; + case 1004: + name = "Vipava"; + break; + case 1005: + name = "Vitanje"; + break; + case 1006: + name = "Vodice"; + break; + case 1008: + name = "Vrhnika"; + break; + case 1009: + name = "Vuzenica"; + break; + case 1010: + name = "Zagorje ob Savi"; + break; + case 1012: + name = "Zavrc"; + break; + case 1047: + name = "Zelezniki"; + break; + case 1048: + name = "Ziri"; + break; + case 1049: + name = "Zrece"; + break; + case 1093: + name = "Dobrova-Horjul-Polhov Gradec"; + break; + case 1096: + name = "Domzale"; + break; + case 1136: + name = "Jesenice"; + break; + case 1138: + name = "Kamnik"; + break; + case 1139: + name = "Kocevje"; + break; + case 1177: + name = "Kuzma"; + break; + case 1178: + name = "Lenart"; + break; + case 1180: + name = "Litija"; + break; + case 1181: + name = "Ljutomer"; + break; + case 1182: + name = "Loska Dolina"; + break; + case 1184: + name = "Luce"; + break; + case 1219: + name = "Majsperk"; + break; + case 1220: + name = "Maribor"; + break; + case 1223: + name = "Miren-Kostanjevica"; + break; + case 1225: + name = "Novo Mesto"; + break; + case 1227: + name = "Piran"; + break; + case 1266: + name = "Preddvor"; + break; + case 1268: + name = "Ptuj"; + break; + case 1305: + name = "Ribnica"; + break; + case 1307: + name = "Ruse"; + break; + case 1311: + name = "Sentjur pri Celju"; + break; + case 1312: + name = "Slovenska Bistrica"; + break; + case 1392: + name = "Videm"; + break; + case 1393: + name = "Vojnik"; + break; + case 1395: + name = "Zalec"; + break; + } + } + if (strcmp(country_code,"SK") == 0) { + switch (region_code2) { + case 1: + name = "Banska Bystrica"; + break; + case 2: + name = "Bratislava"; + break; + case 3: + name = "Kosice"; + break; + case 4: + name = "Nitra"; + break; + case 5: + name = "Presov"; + break; + case 6: + name = "Trencin"; + break; + case 7: + name = "Trnava"; + break; + case 8: + name = "Zilina"; + break; + } + } + if (strcmp(country_code,"SL") == 0) { + switch (region_code2) { + case 1: + name = "Eastern"; + break; + case 2: + name = "Northern"; + break; + case 3: + name = "Southern"; + break; + case 4: + name = "Western Area"; + break; + } + } + if (strcmp(country_code,"SM") == 0) { + switch (region_code2) { + case 1: + name = "Acquaviva"; + break; + case 2: + name = "Chiesanuova"; + break; + case 3: + name = "Domagnano"; + break; + case 4: + name = "Faetano"; + break; + case 5: + name = "Fiorentino"; + break; + case 6: + name = "Borgo Maggiore"; + break; + case 7: + name = "San Marino"; + break; + case 8: + name = "Monte Giardino"; + break; + case 9: + name = "Serravalle"; + break; + } + } + if (strcmp(country_code,"SN") == 0) { + switch (region_code2) { + case 1: + name = "Dakar"; + break; + case 3: + name = "Diourbel"; + break; + case 5: + name = "Tambacounda"; + break; + case 7: + name = "Thies"; + break; + case 9: + name = "Fatick"; + break; + case 10: + name = "Kaolack"; + break; + case 11: + name = "Kolda"; + break; + case 12: + name = "Ziguinchor"; + break; + case 13: + name = "Louga"; + break; + case 14: + name = "Saint-Louis"; + break; + case 15: + name = "Matam"; + break; + } + } + if (strcmp(country_code,"SO") == 0) { + switch (region_code2) { + case 1: + name = "Bakool"; + break; + case 2: + name = "Banaadir"; + break; + case 3: + name = "Bari"; + break; + case 4: + name = "Bay"; + break; + case 5: + name = "Galguduud"; + break; + case 6: + name = "Gedo"; + break; + case 7: + name = "Hiiraan"; + break; + case 8: + name = "Jubbada Dhexe"; + break; + case 9: + name = "Jubbada Hoose"; + break; + case 10: + name = "Mudug"; + break; + case 11: + name = "Nugaal"; + break; + case 12: + name = "Sanaag"; + break; + case 13: + name = "Shabeellaha Dhexe"; + break; + case 14: + name = "Shabeellaha Hoose"; + break; + case 16: + name = "Woqooyi Galbeed"; + break; + case 18: + name = "Nugaal"; + break; + case 19: + name = "Togdheer"; + break; + case 20: + name = "Woqooyi Galbeed"; + break; + case 21: + name = "Awdal"; + break; + case 22: + name = "Sool"; + break; + } + } + if (strcmp(country_code,"SR") == 0) { + switch (region_code2) { + case 10: + name = "Brokopondo"; + break; + case 11: + name = "Commewijne"; + break; + case 12: + name = "Coronie"; + break; + case 13: + name = "Marowijne"; + break; + case 14: + name = "Nickerie"; + break; + case 15: + name = "Para"; + break; + case 16: + name = "Paramaribo"; + break; + case 17: + name = "Saramacca"; + break; + case 18: + name = "Sipaliwini"; + break; + case 19: + name = "Wanica"; + break; + } + } + if (strcmp(country_code,"ST") == 0) { + switch (region_code2) { + case 1: + name = "Principe"; + break; + case 2: + name = "Sao Tome"; + break; + } + } + if (strcmp(country_code,"SV") == 0) { + switch (region_code2) { + case 1: + name = "Ahuachapan"; + break; + case 2: + name = "Cabanas"; + break; + case 3: + name = "Chalatenango"; + break; + case 4: + name = "Cuscatlan"; + break; + case 5: + name = "La Libertad"; + break; + case 6: + name = "La Paz"; + break; + case 7: + name = "La Union"; + break; + case 8: + name = "Morazan"; + break; + case 9: + name = "San Miguel"; + break; + case 10: + name = "San Salvador"; + break; + case 11: + name = "Santa Ana"; + break; + case 12: + name = "San Vicente"; + break; + case 13: + name = "Sonsonate"; + break; + case 14: + name = "Usulutan"; + break; + } + } + if (strcmp(country_code,"SY") == 0) { + switch (region_code2) { + case 1: + name = "Al Hasakah"; + break; + case 2: + name = "Al Ladhiqiyah"; + break; + case 3: + name = "Al Qunaytirah"; + break; + case 4: + name = "Ar Raqqah"; + break; + case 5: + name = "As Suwayda'"; + break; + case 6: + name = "Dar"; + break; + case 7: + name = "Dayr az Zawr"; + break; + case 8: + name = "Rif Dimashq"; + break; + case 9: + name = "Halab"; + break; + case 10: + name = "Hamah"; + break; + case 11: + name = "Hims"; + break; + case 12: + name = "Idlib"; + break; + case 13: + name = "Dimashq"; + break; + case 14: + name = "Tartus"; + break; + } + } + if (strcmp(country_code,"SZ") == 0) { + switch (region_code2) { + case 1: + name = "Hhohho"; + break; + case 2: + name = "Lubombo"; + break; + case 3: + name = "Manzini"; + break; + case 4: + name = "Shiselweni"; + break; + case 5: + name = "Praslin"; + break; + } + } + if (strcmp(country_code,"TD") == 0) { + switch (region_code2) { + case 1: + name = "Batha"; + break; + case 2: + name = "Biltine"; + break; + case 3: + name = "Borkou-Ennedi-Tibesti"; + break; + case 4: + name = "Chari-Baguirmi"; + break; + case 5: + name = "Guera"; + break; + case 6: + name = "Kanem"; + break; + case 7: + name = "Lac"; + break; + case 8: + name = "Logone Occidental"; + break; + case 9: + name = "Logone Oriental"; + break; + case 10: + name = "Mayo-Kebbi"; + break; + case 11: + name = "Moyen-Chari"; + break; + case 12: + name = "Ouaddai"; + break; + case 13: + name = "Salamat"; + break; + case 14: + name = "Tandjile"; + break; + } + } + if (strcmp(country_code,"TG") == 0) { + switch (region_code2) { + case 22: + name = "Centrale"; + break; + case 23: + name = "Kara"; + break; + case 24: + name = "Maritime"; + break; + case 25: + name = "Plateaux"; + break; + case 26: + name = "Savanes"; + break; + } + } + if (strcmp(country_code,"TH") == 0) { + switch (region_code2) { + case 1: + name = "Mae Hong Son"; + break; + case 2: + name = "Chiang Mai"; + break; + case 3: + name = "Chiang Rai"; + break; + case 4: + name = "Nan"; + break; + case 5: + name = "Lamphun"; + break; + case 6: + name = "Lampang"; + break; + case 7: + name = "Phrae"; + break; + case 8: + name = "Tak"; + break; + case 9: + name = "Sukhothai"; + break; + case 10: + name = "Uttaradit"; + break; + case 11: + name = "Kamphaeng Phet"; + break; + case 12: + name = "Phitsanulok"; + break; + case 13: + name = "Phichit"; + break; + case 14: + name = "Phetchabun"; + break; + case 15: + name = "Uthai Thani"; + break; + case 16: + name = "Nakhon Sawan"; + break; + case 17: + name = "Nong Khai"; + break; + case 18: + name = "Loei"; + break; + case 20: + name = "Sakon Nakhon"; + break; + case 21: + name = "Nakhon Phanom"; + break; + case 22: + name = "Khon Kaen"; + break; + case 23: + name = "Kalasin"; + break; + case 24: + name = "Maha Sarakham"; + break; + case 25: + name = "Roi Et"; + break; + case 26: + name = "Chaiyaphum"; + break; + case 27: + name = "Nakhon Ratchasima"; + break; + case 28: + name = "Buriram"; + break; + case 29: + name = "Surin"; + break; + case 30: + name = "Sisaket"; + break; + case 31: + name = "Narathiwat"; + break; + case 32: + name = "Chai Nat"; + break; + case 33: + name = "Sing Buri"; + break; + case 34: + name = "Lop Buri"; + break; + case 35: + name = "Ang Thong"; + break; + case 36: + name = "Phra Nakhon Si Ayutthaya"; + break; + case 37: + name = "Saraburi"; + break; + case 38: + name = "Nonthaburi"; + break; + case 39: + name = "Pathum Thani"; + break; + case 40: + name = "Krung Thep"; + break; + case 41: + name = "Phayao"; + break; + case 42: + name = "Samut Prakan"; + break; + case 43: + name = "Nakhon Nayok"; + break; + case 44: + name = "Chachoengsao"; + break; + case 45: + name = "Prachin Buri"; + break; + case 46: + name = "Chon Buri"; + break; + case 47: + name = "Rayong"; + break; + case 48: + name = "Chanthaburi"; + break; + case 49: + name = "Trat"; + break; + case 50: + name = "Kanchanaburi"; + break; + case 51: + name = "Suphan Buri"; + break; + case 52: + name = "Ratchaburi"; + break; + case 53: + name = "Nakhon Pathom"; + break; + case 54: + name = "Samut Songkhram"; + break; + case 55: + name = "Samut Sakhon"; + break; + case 56: + name = "Phetchaburi"; + break; + case 57: + name = "Prachuap Khiri Khan"; + break; + case 58: + name = "Chumphon"; + break; + case 59: + name = "Ranong"; + break; + case 60: + name = "Surat Thani"; + break; + case 61: + name = "Phangnga"; + break; + case 62: + name = "Phuket"; + break; + case 63: + name = "Krabi"; + break; + case 64: + name = "Nakhon Si Thammarat"; + break; + case 65: + name = "Trang"; + break; + case 66: + name = "Phatthalung"; + break; + case 67: + name = "Satun"; + break; + case 68: + name = "Songkhla"; + break; + case 69: + name = "Pattani"; + break; + case 70: + name = "Yala"; + break; + case 71: + name = "Ubon Ratchathani"; + break; + case 72: + name = "Yasothon"; + break; + case 73: + name = "Nakhon Phanom"; + break; + case 75: + name = "Ubon Ratchathani"; + break; + case 76: + name = "Udon Thani"; + break; + case 77: + name = "Amnat Charoen"; + break; + case 78: + name = "Mukdahan"; + break; + case 79: + name = "Nong Bua Lamphu"; + break; + case 80: + name = "Sa Kaeo"; + break; + } + } + if (strcmp(country_code,"TJ") == 0) { + switch (region_code2) { + case 1: + name = "Kuhistoni Badakhshon"; + break; + case 2: + name = "Khatlon"; + break; + case 3: + name = "Sughd"; + break; + } + } + if (strcmp(country_code,"TM") == 0) { + switch (region_code2) { + case 1: + name = "Ahal"; + break; + case 2: + name = "Balkan"; + break; + case 3: + name = "Dashoguz"; + break; + case 4: + name = "Lebap"; + break; + case 5: + name = "Mary"; + break; + } + } + if (strcmp(country_code,"TN") == 0) { + switch (region_code2) { + case 2: + name = "Kasserine"; + break; + case 3: + name = "Kairouan"; + break; + case 6: + name = "Jendouba"; + break; + case 10: + name = "Qafsah"; + break; + case 14: + name = "El Kef"; + break; + case 15: + name = "Al Mahdia"; + break; + case 16: + name = "Al Munastir"; + break; + case 17: + name = "Bajah"; + break; + case 18: + name = "Bizerte"; + break; + case 19: + name = "Nabeul"; + break; + case 22: + name = "Siliana"; + break; + case 23: + name = "Sousse"; + break; + case 27: + name = "Ben Arous"; + break; + case 28: + name = "Madanin"; + break; + case 29: + name = "Gabes"; + break; + case 31: + name = "Kebili"; + break; + case 32: + name = "Sfax"; + break; + case 33: + name = "Sidi Bou Zid"; + break; + case 34: + name = "Tataouine"; + break; + case 35: + name = "Tozeur"; + break; + case 36: + name = "Tunis"; + break; + case 37: + name = "Zaghouan"; + break; + case 38: + name = "Aiana"; + break; + case 39: + name = "Manouba"; + break; + } + } + if (strcmp(country_code,"TO") == 0) { + switch (region_code2) { + case 1: + name = "Ha"; + break; + case 2: + name = "Tongatapu"; + break; + case 3: + name = "Vava"; + break; + } + } + if (strcmp(country_code,"TR") == 0) { + switch (region_code2) { + case 2: + name = "Adiyaman"; + break; + case 3: + name = "Afyonkarahisar"; + break; + case 4: + name = "Agri"; + break; + case 5: + name = "Amasya"; + break; + case 7: + name = "Antalya"; + break; + case 8: + name = "Artvin"; + break; + case 9: + name = "Aydin"; + break; + case 10: + name = "Balikesir"; + break; + case 11: + name = "Bilecik"; + break; + case 12: + name = "Bingol"; + break; + case 13: + name = "Bitlis"; + break; + case 14: + name = "Bolu"; + break; + case 15: + name = "Burdur"; + break; + case 16: + name = "Bursa"; + break; + case 17: + name = "Canakkale"; + break; + case 19: + name = "Corum"; + break; + case 20: + name = "Denizli"; + break; + case 21: + name = "Diyarbakir"; + break; + case 22: + name = "Edirne"; + break; + case 23: + name = "Elazig"; + break; + case 24: + name = "Erzincan"; + break; + case 25: + name = "Erzurum"; + break; + case 26: + name = "Eskisehir"; + break; + case 28: + name = "Giresun"; + break; + case 31: + name = "Hatay"; + break; + case 32: + name = "Mersin"; + break; + case 33: + name = "Isparta"; + break; + case 34: + name = "Istanbul"; + break; + case 35: + name = "Izmir"; + break; + case 37: + name = "Kastamonu"; + break; + case 38: + name = "Kayseri"; + break; + case 39: + name = "Kirklareli"; + break; + case 40: + name = "Kirsehir"; + break; + case 41: + name = "Kocaeli"; + break; + case 43: + name = "Kutahya"; + break; + case 44: + name = "Malatya"; + break; + case 45: + name = "Manisa"; + break; + case 46: + name = "Kahramanmaras"; + break; + case 48: + name = "Mugla"; + break; + case 49: + name = "Mus"; + break; + case 50: + name = "Nevsehir"; + break; + case 52: + name = "Ordu"; + break; + case 53: + name = "Rize"; + break; + case 54: + name = "Sakarya"; + break; + case 55: + name = "Samsun"; + break; + case 57: + name = "Sinop"; + break; + case 58: + name = "Sivas"; + break; + case 59: + name = "Tekirdag"; + break; + case 60: + name = "Tokat"; + break; + case 61: + name = "Trabzon"; + break; + case 62: + name = "Tunceli"; + break; + case 63: + name = "Sanliurfa"; + break; + case 64: + name = "Usak"; + break; + case 65: + name = "Van"; + break; + case 66: + name = "Yozgat"; + break; + case 68: + name = "Ankara"; + break; + case 69: + name = "Gumushane"; + break; + case 70: + name = "Hakkari"; + break; + case 71: + name = "Konya"; + break; + case 72: + name = "Mardin"; + break; + case 73: + name = "Nigde"; + break; + case 74: + name = "Siirt"; + break; + case 75: + name = "Aksaray"; + break; + case 76: + name = "Batman"; + break; + case 77: + name = "Bayburt"; + break; + case 78: + name = "Karaman"; + break; + case 79: + name = "Kirikkale"; + break; + case 80: + name = "Sirnak"; + break; + case 81: + name = "Adana"; + break; + case 82: + name = "Cankiri"; + break; + case 83: + name = "Gaziantep"; + break; + case 84: + name = "Kars"; + break; + case 85: + name = "Zonguldak"; + break; + case 86: + name = "Ardahan"; + break; + case 87: + name = "Bartin"; + break; + case 88: + name = "Igdir"; + break; + case 89: + name = "Karabuk"; + break; + case 90: + name = "Kilis"; + break; + case 91: + name = "Osmaniye"; + break; + case 92: + name = "Yalova"; + break; + case 93: + name = "Duzce"; + break; + } + } + if (strcmp(country_code,"TT") == 0) { + switch (region_code2) { + case 1: + name = "Arima"; + break; + case 2: + name = "Caroni"; + break; + case 3: + name = "Mayaro"; + break; + case 4: + name = "Nariva"; + break; + case 5: + name = "Port-of-Spain"; + break; + case 6: + name = "Saint Andrew"; + break; + case 7: + name = "Saint David"; + break; + case 8: + name = "Saint George"; + break; + case 9: + name = "Saint Patrick"; + break; + case 10: + name = "San Fernando"; + break; + case 11: + name = "Tobago"; + break; + case 12: + name = "Victoria"; + break; + } + } + if (strcmp(country_code,"TW") == 0) { + switch (region_code2) { + case 1: + name = "Fu-chien"; + break; + case 2: + name = "Kao-hsiung"; + break; + case 3: + name = "T'ai-pei"; + break; + case 4: + name = "T'ai-wan"; + break; + } + } + if (strcmp(country_code,"TZ") == 0) { + switch (region_code2) { + case 2: + name = "Pwani"; + break; + case 3: + name = "Dodoma"; + break; + case 4: + name = "Iringa"; + break; + case 5: + name = "Kigoma"; + break; + case 6: + name = "Kilimanjaro"; + break; + case 7: + name = "Lindi"; + break; + case 8: + name = "Mara"; + break; + case 9: + name = "Mbeya"; + break; + case 10: + name = "Morogoro"; + break; + case 11: + name = "Mtwara"; + break; + case 12: + name = "Mwanza"; + break; + case 13: + name = "Pemba North"; + break; + case 14: + name = "Ruvuma"; + break; + case 15: + name = "Shinyanga"; + break; + case 16: + name = "Singida"; + break; + case 17: + name = "Tabora"; + break; + case 18: + name = "Tanga"; + break; + case 19: + name = "Kagera"; + break; + case 20: + name = "Pemba South"; + break; + case 21: + name = "Zanzibar Central"; + break; + case 22: + name = "Zanzibar North"; + break; + case 23: + name = "Dar es Salaam"; + break; + case 24: + name = "Rukwa"; + break; + case 25: + name = "Zanzibar Urban"; + break; + case 26: + name = "Arusha"; + break; + case 27: + name = "Manyara"; + break; + } + } + if (strcmp(country_code,"UA") == 0) { + switch (region_code2) { + case 1: + name = "Cherkas'ka Oblast'"; + break; + case 2: + name = "Chernihivs'ka Oblast'"; + break; + case 3: + name = "Chernivets'ka Oblast'"; + break; + case 4: + name = "Dnipropetrovs'ka Oblast'"; + break; + case 5: + name = "Donets'ka Oblast'"; + break; + case 6: + name = "Ivano-Frankivs'ka Oblast'"; + break; + case 7: + name = "Kharkivs'ka Oblast'"; + break; + case 8: + name = "Khersons'ka Oblast'"; + break; + case 9: + name = "Khmel'nyts'ka Oblast'"; + break; + case 10: + name = "Kirovohrads'ka Oblast'"; + break; + case 11: + name = "Krym"; + break; + case 12: + name = "Kyyiv"; + break; + case 13: + name = "Kyyivs'ka Oblast'"; + break; + case 14: + name = "Luhans'ka Oblast'"; + break; + case 15: + name = "L'vivs'ka Oblast'"; + break; + case 16: + name = "Mykolayivs'ka Oblast'"; + break; + case 17: + name = "Odes'ka Oblast'"; + break; + case 18: + name = "Poltavs'ka Oblast'"; + break; + case 19: + name = "Rivnens'ka Oblast'"; + break; + case 20: + name = "Sevastopol'"; + break; + case 21: + name = "Sums'ka Oblast'"; + break; + case 22: + name = "Ternopil's'ka Oblast'"; + break; + case 23: + name = "Vinnyts'ka Oblast'"; + break; + case 24: + name = "Volyns'ka Oblast'"; + break; + case 25: + name = "Zakarpats'ka Oblast'"; + break; + case 26: + name = "Zaporiz'ka Oblast'"; + break; + case 27: + name = "Zhytomyrs'ka Oblast'"; + break; + } + } + if (strcmp(country_code,"UG") == 0) { + switch (region_code2) { + case 26: + name = "Apac"; + break; + case 28: + name = "Bundibugyo"; + break; + case 29: + name = "Bushenyi"; + break; + case 30: + name = "Gulu"; + break; + case 31: + name = "Hoima"; + break; + case 33: + name = "Jinja"; + break; + case 36: + name = "Kalangala"; + break; + case 37: + name = "Kampala"; + break; + case 38: + name = "Kamuli"; + break; + case 39: + name = "Kapchorwa"; + break; + case 40: + name = "Kasese"; + break; + case 41: + name = "Kibale"; + break; + case 42: + name = "Kiboga"; + break; + case 43: + name = "Kisoro"; + break; + case 45: + name = "Kotido"; + break; + case 46: + name = "Kumi"; + break; + case 47: + name = "Lira"; + break; + case 50: + name = "Masindi"; + break; + case 52: + name = "Mbarara"; + break; + case 56: + name = "Mubende"; + break; + case 58: + name = "Nebbi"; + break; + case 59: + name = "Ntungamo"; + break; + case 60: + name = "Pallisa"; + break; + case 61: + name = "Rakai"; + break; + case 65: + name = "Adjumani"; + break; + case 66: + name = "Bugiri"; + break; + case 67: + name = "Busia"; + break; + case 69: + name = "Katakwi"; + break; + case 70: + name = "Luwero"; + break; + case 71: + name = "Masaka"; + break; + case 72: + name = "Moyo"; + break; + case 73: + name = "Nakasongola"; + break; + case 74: + name = "Sembabule"; + break; + case 76: + name = "Tororo"; + break; + case 77: + name = "Arua"; + break; + case 78: + name = "Iganga"; + break; + case 79: + name = "Kabarole"; + break; + case 80: + name = "Kaberamaido"; + break; + case 81: + name = "Kamwenge"; + break; + case 82: + name = "Kanungu"; + break; + case 83: + name = "Kayunga"; + break; + case 84: + name = "Kitgum"; + break; + case 85: + name = "Kyenjojo"; + break; + case 86: + name = "Mayuge"; + break; + case 87: + name = "Mbale"; + break; + case 88: + name = "Moroto"; + break; + case 89: + name = "Mpigi"; + break; + case 90: + name = "Mukono"; + break; + case 91: + name = "Nakapiripirit"; + break; + case 92: + name = "Pader"; + break; + case 93: + name = "Rukungiri"; + break; + case 94: + name = "Sironko"; + break; + case 95: + name = "Soroti"; + break; + case 96: + name = "Wakiso"; + break; + case 97: + name = "Yumbe"; + break; + } + } + if (strcmp(country_code,"UY") == 0) { + switch (region_code2) { + case 1: + name = "Artigas"; + break; + case 2: + name = "Canelones"; + break; + case 3: + name = "Cerro Largo"; + break; + case 4: + name = "Colonia"; + break; + case 5: + name = "Durazno"; + break; + case 6: + name = "Flores"; + break; + case 7: + name = "Florida"; + break; + case 8: + name = "Lavalleja"; + break; + case 9: + name = "Maldonado"; + break; + case 10: + name = "Montevideo"; + break; + case 11: + name = "Paysandu"; + break; + case 12: + name = "Rio Negro"; + break; + case 13: + name = "Rivera"; + break; + case 14: + name = "Rocha"; + break; + case 15: + name = "Salto"; + break; + case 16: + name = "San Jose"; + break; + case 17: + name = "Soriano"; + break; + case 18: + name = "Tacuarembo"; + break; + case 19: + name = "Treinta y Tres"; + break; + } + } + if (strcmp(country_code,"UZ") == 0) { + switch (region_code2) { + case 1: + name = "Andijon"; + break; + case 2: + name = "Bukhoro"; + break; + case 3: + name = "Farghona"; + break; + case 4: + name = "Jizzakh"; + break; + case 5: + name = "Khorazm"; + break; + case 6: + name = "Namangan"; + break; + case 7: + name = "Nawoiy"; + break; + case 8: + name = "Qashqadaryo"; + break; + case 9: + name = "Qoraqalpoghiston"; + break; + case 10: + name = "Samarqand"; + break; + case 11: + name = "Sirdaryo"; + break; + case 12: + name = "Surkhondaryo"; + break; + case 13: + name = "Toshkent"; + break; + case 14: + name = "Toshkent"; + break; + } + } + if (strcmp(country_code,"VC") == 0) { + switch (region_code2) { + case 1: + name = "Charlotte"; + break; + case 2: + name = "Saint Andrew"; + break; + case 3: + name = "Saint David"; + break; + case 4: + name = "Saint George"; + break; + case 5: + name = "Saint Patrick"; + break; + case 6: + name = "Grenadines"; + break; + } + } + if (strcmp(country_code,"VE") == 0) { + switch (region_code2) { + case 1: + name = "Amazonas"; + break; + case 2: + name = "Anzoategui"; + break; + case 3: + name = "Apure"; + break; + case 4: + name = "Aragua"; + break; + case 5: + name = "Barinas"; + break; + case 6: + name = "Bolivar"; + break; + case 7: + name = "Carabobo"; + break; + case 8: + name = "Cojedes"; + break; + case 9: + name = "Delta Amacuro"; + break; + case 11: + name = "Falcon"; + break; + case 12: + name = "Guarico"; + break; + case 13: + name = "Lara"; + break; + case 14: + name = "Merida"; + break; + case 15: + name = "Miranda"; + break; + case 16: + name = "Monagas"; + break; + case 17: + name = "Nueva Esparta"; + break; + case 18: + name = "Portuguesa"; + break; + case 19: + name = "Sucre"; + break; + case 20: + name = "Tachira"; + break; + case 21: + name = "Trujillo"; + break; + case 22: + name = "Yaracuy"; + break; + case 23: + name = "Zulia"; + break; + case 24: + name = "Dependencias Federales"; + break; + case 25: + name = "Distrito Federal"; + break; + case 26: + name = "Vargas"; + break; + } + } + if (strcmp(country_code,"VN") == 0) { + switch (region_code2) { + case 1: + name = "An Giang"; + break; + case 3: + name = "Ben Tre"; + break; + case 5: + name = "Cao Bang"; + break; + case 9: + name = "Dong Thap"; + break; + case 13: + name = "Hai Phong"; + break; + case 20: + name = "Ho Chi Minh"; + break; + case 21: + name = "Kien Giang"; + break; + case 23: + name = "Lam Dong"; + break; + case 24: + name = "Long An"; + break; + case 30: + name = "Quang Ninh"; + break; + case 32: + name = "Son La"; + break; + case 33: + name = "Tay Ninh"; + break; + case 34: + name = "Thanh Hoa"; + break; + case 35: + name = "Thai Binh"; + break; + case 37: + name = "Tien Giang"; + break; + case 39: + name = "Lang Son"; + break; + case 43: + name = "An Giang"; + break; + case 44: + name = "Dac Lac"; + break; + case 45: + name = "Dong Nai"; + break; + case 46: + name = "Dong Thap"; + break; + case 47: + name = "Kien Giang"; + break; + case 49: + name = "Song Be"; + break; + case 50: + name = "Vinh Phu"; + break; + case 51: + name = "Ha Noi"; + break; + case 52: + name = "Ho Chi Minh"; + break; + case 53: + name = "Ba Ria-Vung Tau"; + break; + case 54: + name = "Binh Dinh"; + break; + case 55: + name = "Binh Thuan"; + break; + case 58: + name = "Ha Giang"; + break; + case 59: + name = "Ha Tay"; + break; + case 60: + name = "Ha Tinh"; + break; + case 61: + name = "Hoa Binh"; + break; + case 62: + name = "Khanh Hoa"; + break; + case 63: + name = "Kon Tum"; + break; + case 64: + name = "Quang Tri"; + break; + case 65: + name = "Nam Ha"; + break; + case 66: + name = "Nghe An"; + break; + case 67: + name = "Ninh Binh"; + break; + case 68: + name = "Ninh Thuan"; + break; + case 69: + name = "Phu Yen"; + break; + case 70: + name = "Quang Binh"; + break; + case 71: + name = "Quang Ngai"; + break; + case 72: + name = "Quang Tri"; + break; + case 73: + name = "Soc Trang"; + break; + case 74: + name = "Thua Thien"; + break; + case 75: + name = "Tra Vinh"; + break; + case 76: + name = "Tuyen Quang"; + break; + case 77: + name = "Vinh Long"; + break; + case 78: + name = "Da Nang"; + break; + case 79: + name = "Hai Duong"; + break; + case 80: + name = "Ha Nam"; + break; + case 81: + name = "Hung Yen"; + break; + case 82: + name = "Nam Dinh"; + break; + case 83: + name = "Phu Tho"; + break; + case 84: + name = "Quang Nam"; + break; + case 85: + name = "Thai Nguyen"; + break; + case 86: + name = "Vinh Puc Province"; + break; + case 87: + name = "Can Tho"; + break; + case 88: + name = "Dak Lak"; + break; + case 89: + name = "Lai Chau"; + break; + case 90: + name = "Lao Cai"; + break; + case 91: + name = "Dak Nong"; + break; + case 92: + name = "Dien Bien"; + break; + case 93: + name = "Hau Giang"; + break; + } + } + if (strcmp(country_code,"VU") == 0) { + switch (region_code2) { + case 5: + name = "Ambrym"; + break; + case 6: + name = "Aoba"; + break; + case 7: + name = "Torba"; + break; + case 8: + name = "Efate"; + break; + case 9: + name = "Epi"; + break; + case 10: + name = "Malakula"; + break; + case 11: + name = "Paama"; + break; + case 12: + name = "Pentecote"; + break; + case 13: + name = "Sanma"; + break; + case 14: + name = "Shepherd"; + break; + case 15: + name = "Tafea"; + break; + case 16: + name = "Malampa"; + break; + case 17: + name = "Penama"; + break; + case 18: + name = "Shefa"; + break; + } + } + if (strcmp(country_code,"WS") == 0) { + switch (region_code2) { + case 2: + name = "Aiga-i-le-Tai"; + break; + case 3: + name = "Atua"; + break; + case 4: + name = "Fa"; + break; + case 5: + name = "Gaga"; + break; + case 6: + name = "Va"; + break; + case 7: + name = "Gagaifomauga"; + break; + case 8: + name = "Palauli"; + break; + case 9: + name = "Satupa"; + break; + case 10: + name = "Tuamasaga"; + break; + case 11: + name = "Vaisigano"; + break; + } + } + if (strcmp(country_code,"YE") == 0) { + switch (region_code2) { + case 1: + name = "Abyan"; + break; + case 2: + name = "Adan"; + break; + case 3: + name = "Al Mahrah"; + break; + case 4: + name = "Hadramawt"; + break; + case 5: + name = "Shabwah"; + break; + case 6: + name = "Al Ghaydah"; + break; + case 8: + name = "Al Hudaydah"; + break; + case 10: + name = "Al Mahwit"; + break; + case 11: + name = "Dhamar"; + break; + case 14: + name = "Ma'rib"; + break; + case 15: + name = "Sa"; + break; + case 16: + name = "San"; + break; + case 20: + name = "Al Bayda'"; + break; + case 21: + name = "Al Jawf"; + break; + case 22: + name = "Hajjah"; + break; + case 23: + name = "Ibb"; + break; + case 24: + name = "Lahij"; + break; + case 25: + name = "Ta"; + break; + } + } + if (strcmp(country_code,"ZA") == 0) { + switch (region_code2) { + case 1: + name = "North-Western Province"; + break; + case 2: + name = "KwaZulu-Natal"; + break; + case 3: + name = "Free State"; + break; + case 5: + name = "Eastern Cape"; + break; + case 6: + name = "Gauteng"; + break; + case 7: + name = "Mpumalanga"; + break; + case 8: + name = "Northern Cape"; + break; + case 9: + name = "Limpopo"; + break; + case 10: + name = "North-West"; + break; + case 11: + name = "Western Cape"; + break; + } + } + if (strcmp(country_code,"ZM") == 0) { + switch (region_code2) { + case 1: + name = "Western"; + break; + case 2: + name = "Central"; + break; + case 3: + name = "Eastern"; + break; + case 4: + name = "Luapula"; + break; + case 5: + name = "Northern"; + break; + case 6: + name = "North-Western"; + break; + case 7: + name = "Southern"; + break; + case 8: + name = "Copperbelt"; + break; + case 9: + name = "Lusaka"; + break; + } + } + if (strcmp(country_code,"ZW") == 0) { + switch (region_code2) { + case 1: + name = "Manicaland"; + break; + case 2: + name = "Midlands"; + break; + case 3: + name = "Mashonaland Central"; + break; + case 4: + name = "Mashonaland East"; + break; + case 5: + name = "Mashonaland West"; + break; + case 6: + name = "Matabeleland North"; + break; + case 7: + name = "Matabeleland South"; + break; + case 8: + name = "Masvingo"; + break; + case 9: + name = "Bulawayo"; + break; + case 10: + name = "Harare"; + break; + } + } + return name; +} diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/timeZone.c b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/timeZone.c new file mode 100644 index 00000000..9db5fb8a --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/timeZone.c @@ -0,0 +1,2077 @@ +#include +const char* GeoIP_time_zone_by_country_and_region(const char * country,const char * region) { + const char* timezone = NULL; + if (country == NULL) { + return NULL; + } + if (region == NULL) { + region = ""; + } + if ( strcmp (country, "AD") == 0 ) { + timezone = "Europe/Andorra"; + } + else if ( strcmp (country, "AE") == 0 ) { + timezone = "Asia/Dubai"; + } + else if ( strcmp (country, "AF") == 0 ) { + timezone = "Asia/Kabul"; + } + else if ( strcmp (country, "AG") == 0 ) { + timezone = "America/Antigua"; + } + else if ( strcmp (country, "AI") == 0 ) { + timezone = "America/Anguilla"; + } + else if ( strcmp (country, "AL") == 0 ) { + timezone = "Europe/Tirane"; + } + else if ( strcmp (country, "AM") == 0 ) { + timezone = "Asia/Yerevan"; + } + else if ( strcmp (country, "AO") == 0 ) { + timezone = "Africa/Luanda"; + } + else if ( strcmp (country, "AR") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "America/Argentina/Buenos_Aires"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "America/Argentina/Catamarca"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "America/Argentina/Tucuman"; + } + else if ( strcmp (region, "04") == 0 ) { + timezone = "America/Argentina/Rio_Gallegos"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "America/Argentina/Cordoba"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "America/Argentina/Tucuman"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "America/Argentina/Buenos_Aires"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "America/Argentina/Buenos_Aires"; + } + else if ( strcmp (region, "09") == 0 ) { + timezone = "America/Argentina/Tucuman"; + } + else if ( strcmp (region, "10") == 0 ) { + timezone = "America/Argentina/Jujuy"; + } + else if ( strcmp (region, "11") == 0 ) { + timezone = "America/Argentina/San_Luis"; + } + else if ( strcmp (region, "12") == 0 ) { + timezone = "America/Argentina/La_Rioja"; + } + else if ( strcmp (region, "13") == 0 ) { + timezone = "America/Argentina/Mendoza"; + } + else if ( strcmp (region, "14") == 0 ) { + timezone = "America/Argentina/Buenos_Aires"; + } + else if ( strcmp (region, "15") == 0 ) { + timezone = "America/Argentina/San_Luis"; + } + else if ( strcmp (region, "16") == 0 ) { + timezone = "America/Argentina/Buenos_Aires"; + } + else if ( strcmp (region, "17") == 0 ) { + timezone = "America/Argentina/Salta"; + } + else if ( strcmp (region, "18") == 0 ) { + timezone = "America/Argentina/San_Juan"; + } + else if ( strcmp (region, "19") == 0 ) { + timezone = "America/Argentina/San_Luis"; + } + else if ( strcmp (region, "20") == 0 ) { + timezone = "America/Argentina/Rio_Gallegos"; + } + else if ( strcmp (region, "21") == 0 ) { + timezone = "America/Argentina/Buenos_Aires"; + } + else if ( strcmp (region, "22") == 0 ) { + timezone = "America/Argentina/Catamarca"; + } + else if ( strcmp (region, "23") == 0 ) { + timezone = "America/Argentina/Ushuaia"; + } + else if ( strcmp (region, "24") == 0 ) { + timezone = "America/Argentina/Tucuman"; + } + } + else if ( strcmp (country, "AS") == 0 ) { + timezone = "US/Samoa"; + } + else if ( strcmp (country, "AT") == 0 ) { + timezone = "Europe/Vienna"; + } + else if ( strcmp (country, "AU") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "Australia/Canberra"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "Australia/NSW"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "Australia/North"; + } + else if ( strcmp (region, "04") == 0 ) { + timezone = "Australia/Queensland"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "Australia/South"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "Australia/Tasmania"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "Australia/Victoria"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "Australia/West"; + } + } + else if ( strcmp (country, "AW") == 0 ) { + timezone = "America/Aruba"; + } + else if ( strcmp (country, "AX") == 0 ) { + timezone = "Europe/Mariehamn"; + } + else if ( strcmp (country, "AZ") == 0 ) { + timezone = "Asia/Baku"; + } + else if ( strcmp (country, "BA") == 0 ) { + timezone = "Europe/Sarajevo"; + } + else if ( strcmp (country, "BB") == 0 ) { + timezone = "America/Barbados"; + } + else if ( strcmp (country, "BD") == 0 ) { + timezone = "Asia/Dhaka"; + } + else if ( strcmp (country, "BE") == 0 ) { + timezone = "Europe/Brussels"; + } + else if ( strcmp (country, "BF") == 0 ) { + timezone = "Africa/Ouagadougou"; + } + else if ( strcmp (country, "BG") == 0 ) { + timezone = "Europe/Sofia"; + } + else if ( strcmp (country, "BH") == 0 ) { + timezone = "Asia/Bahrain"; + } + else if ( strcmp (country, "BI") == 0 ) { + timezone = "Africa/Bujumbura"; + } + else if ( strcmp (country, "BJ") == 0 ) { + timezone = "Africa/Porto-Novo"; + } + else if ( strcmp (country, "BL") == 0 ) { + timezone = "America/St_Barthelemy"; + } + else if ( strcmp (country, "BM") == 0 ) { + timezone = "Atlantic/Bermuda"; + } + else if ( strcmp (country, "BN") == 0 ) { + timezone = "Asia/Brunei"; + } + else if ( strcmp (country, "BO") == 0 ) { + timezone = "America/La_Paz"; + } + else if ( strcmp (country, "BQ") == 0 ) { + timezone = "America/Curacao"; + } + else if ( strcmp (country, "BR") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "America/Rio_Branco"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "America/Maceio"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "America/Sao_Paulo"; + } + else if ( strcmp (region, "04") == 0 ) { + timezone = "America/Manaus"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "America/Bahia"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "America/Fortaleza"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "America/Sao_Paulo"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "America/Sao_Paulo"; + } + else if ( strcmp (region, "11") == 0 ) { + timezone = "America/Campo_Grande"; + } + else if ( strcmp (region, "13") == 0 ) { + timezone = "America/Belem"; + } + else if ( strcmp (region, "14") == 0 ) { + timezone = "America/Cuiaba"; + } + else if ( strcmp (region, "15") == 0 ) { + timezone = "America/Sao_Paulo"; + } + else if ( strcmp (region, "16") == 0 ) { + timezone = "America/Belem"; + } + else if ( strcmp (region, "17") == 0 ) { + timezone = "America/Recife"; + } + else if ( strcmp (region, "18") == 0 ) { + timezone = "America/Sao_Paulo"; + } + else if ( strcmp (region, "20") == 0 ) { + timezone = "America/Fortaleza"; + } + else if ( strcmp (region, "21") == 0 ) { + timezone = "America/Sao_Paulo"; + } + else if ( strcmp (region, "22") == 0 ) { + timezone = "America/Recife"; + } + else if ( strcmp (region, "23") == 0 ) { + timezone = "America/Sao_Paulo"; + } + else if ( strcmp (region, "24") == 0 ) { + timezone = "America/Porto_Velho"; + } + else if ( strcmp (region, "25") == 0 ) { + timezone = "America/Boa_Vista"; + } + else if ( strcmp (region, "26") == 0 ) { + timezone = "America/Sao_Paulo"; + } + else if ( strcmp (region, "27") == 0 ) { + timezone = "America/Sao_Paulo"; + } + else if ( strcmp (region, "28") == 0 ) { + timezone = "America/Maceio"; + } + else if ( strcmp (region, "29") == 0 ) { + timezone = "America/Sao_Paulo"; + } + else if ( strcmp (region, "30") == 0 ) { + timezone = "America/Recife"; + } + else if ( strcmp (region, "31") == 0 ) { + timezone = "America/Araguaina"; + } + } + else if ( strcmp (country, "BS") == 0 ) { + timezone = "America/Nassau"; + } + else if ( strcmp (country, "BT") == 0 ) { + timezone = "Asia/Thimphu"; + } + else if ( strcmp (country, "BW") == 0 ) { + timezone = "Africa/Gaborone"; + } + else if ( strcmp (country, "BY") == 0 ) { + timezone = "Europe/Minsk"; + } + else if ( strcmp (country, "BZ") == 0 ) { + timezone = "America/Belize"; + } + else if ( strcmp (country, "CA") == 0 ) { + if ( strcmp (region, "AB") == 0 ) { + timezone = "America/Edmonton"; + } + else if ( strcmp (region, "BC") == 0 ) { + timezone = "America/Vancouver"; + } + else if ( strcmp (region, "MB") == 0 ) { + timezone = "America/Winnipeg"; + } + else if ( strcmp (region, "NB") == 0 ) { + timezone = "America/Halifax"; + } + else if ( strcmp (region, "NL") == 0 ) { + timezone = "America/St_Johns"; + } + else if ( strcmp (region, "NS") == 0 ) { + timezone = "America/Halifax"; + } + else if ( strcmp (region, "NT") == 0 ) { + timezone = "America/Yellowknife"; + } + else if ( strcmp (region, "NU") == 0 ) { + timezone = "America/Rankin_Inlet"; + } + else if ( strcmp (region, "ON") == 0 ) { + timezone = "America/Rainy_River"; + } + else if ( strcmp (region, "PE") == 0 ) { + timezone = "America/Halifax"; + } + else if ( strcmp (region, "QC") == 0 ) { + timezone = "America/Montreal"; + } + else if ( strcmp (region, "SK") == 0 ) { + timezone = "America/Regina"; + } + else if ( strcmp (region, "YT") == 0 ) { + timezone = "America/Whitehorse"; + } + } + else if ( strcmp (country, "CC") == 0 ) { + timezone = "Indian/Cocos"; + } + else if ( strcmp (country, "CD") == 0 ) { + if ( strcmp (region, "02") == 0 ) { + timezone = "Africa/Kinshasa"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "Africa/Lubumbashi"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "Africa/Kinshasa"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "Africa/Kinshasa"; + } + else if ( strcmp (region, "10") == 0 ) { + timezone = "Africa/Lubumbashi"; + } + else if ( strcmp (region, "11") == 0 ) { + timezone = "Africa/Lubumbashi"; + } + else if ( strcmp (region, "12") == 0 ) { + timezone = "Africa/Lubumbashi"; + } + } + else if ( strcmp (country, "CF") == 0 ) { + timezone = "Africa/Bangui"; + } + else if ( strcmp (country, "CG") == 0 ) { + timezone = "Africa/Brazzaville"; + } + else if ( strcmp (country, "CH") == 0 ) { + timezone = "Europe/Zurich"; + } + else if ( strcmp (country, "CI") == 0 ) { + timezone = "Africa/Abidjan"; + } + else if ( strcmp (country, "CK") == 0 ) { + timezone = "Pacific/Rarotonga"; + } + else if ( strcmp (country, "CL") == 0 ) { + timezone = "Chile/Continental"; + } + else if ( strcmp (country, "CM") == 0 ) { + timezone = "Africa/Lagos"; + } + else if ( strcmp (country, "CN") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "Asia/Shanghai"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "Asia/Shanghai"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "Asia/Shanghai"; + } + else if ( strcmp (region, "04") == 0 ) { + timezone = "Asia/Shanghai"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "Asia/Harbin"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "Asia/Shanghai"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "Asia/Harbin"; + } + else if ( strcmp (region, "09") == 0 ) { + timezone = "Asia/Shanghai"; + } + else if ( strcmp (region, "10") == 0 ) { + timezone = "Asia/Shanghai"; + } + else if ( strcmp (region, "11") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "12") == 0 ) { + timezone = "Asia/Shanghai"; + } + else if ( strcmp (region, "13") == 0 ) { + timezone = "Asia/Urumqi"; + } + else if ( strcmp (region, "14") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "15") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "16") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "18") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "19") == 0 ) { + timezone = "Asia/Harbin"; + } + else if ( strcmp (region, "20") == 0 ) { + timezone = "Asia/Harbin"; + } + else if ( strcmp (region, "21") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "22") == 0 ) { + timezone = "Asia/Harbin"; + } + else if ( strcmp (region, "23") == 0 ) { + timezone = "Asia/Shanghai"; + } + else if ( strcmp (region, "24") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "25") == 0 ) { + timezone = "Asia/Shanghai"; + } + else if ( strcmp (region, "26") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "28") == 0 ) { + timezone = "Asia/Shanghai"; + } + else if ( strcmp (region, "29") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "30") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "31") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "32") == 0 ) { + timezone = "Asia/Chongqing"; + } + else if ( strcmp (region, "33") == 0 ) { + timezone = "Asia/Chongqing"; + } + } + else if ( strcmp (country, "CO") == 0 ) { + timezone = "America/Bogota"; + } + else if ( strcmp (country, "CR") == 0 ) { + timezone = "America/Costa_Rica"; + } + else if ( strcmp (country, "CU") == 0 ) { + timezone = "America/Havana"; + } + else if ( strcmp (country, "CV") == 0 ) { + timezone = "Atlantic/Cape_Verde"; + } + else if ( strcmp (country, "CW") == 0 ) { + timezone = "America/Curacao"; + } + else if ( strcmp (country, "CX") == 0 ) { + timezone = "Indian/Christmas"; + } + else if ( strcmp (country, "CY") == 0 ) { + timezone = "Asia/Nicosia"; + } + else if ( strcmp (country, "CZ") == 0 ) { + timezone = "Europe/Prague"; + } + else if ( strcmp (country, "DE") == 0 ) { + timezone = "Europe/Berlin"; + } + else if ( strcmp (country, "DJ") == 0 ) { + timezone = "Africa/Djibouti"; + } + else if ( strcmp (country, "DK") == 0 ) { + timezone = "Europe/Copenhagen"; + } + else if ( strcmp (country, "DM") == 0 ) { + timezone = "America/Dominica"; + } + else if ( strcmp (country, "DO") == 0 ) { + timezone = "America/Santo_Domingo"; + } + else if ( strcmp (country, "DZ") == 0 ) { + timezone = "Africa/Algiers"; + } + else if ( strcmp (country, "EC") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "Pacific/Galapagos"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "04") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "09") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "10") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "11") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "12") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "13") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "14") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "15") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "17") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "18") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "19") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "20") == 0 ) { + timezone = "America/Guayaquil"; + } + else if ( strcmp (region, "22") == 0 ) { + timezone = "America/Guayaquil"; + } + } + else if ( strcmp (country, "EE") == 0 ) { + timezone = "Europe/Tallinn"; + } + else if ( strcmp (country, "EG") == 0 ) { + timezone = "Africa/Cairo"; + } + else if ( strcmp (country, "EH") == 0 ) { + timezone = "Africa/El_Aaiun"; + } + else if ( strcmp (country, "ER") == 0 ) { + timezone = "Africa/Asmera"; + } + else if ( strcmp (country, "ES") == 0 ) { + if ( strcmp (region, "07") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "27") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "29") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "31") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "32") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "34") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "39") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "51") == 0 ) { + timezone = "Africa/Ceuta"; + } + else if ( strcmp (region, "52") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "53") == 0 ) { + timezone = "Atlantic/Canary"; + } + else if ( strcmp (region, "54") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "55") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "56") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "57") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "58") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "59") == 0 ) { + timezone = "Europe/Madrid"; + } + else if ( strcmp (region, "60") == 0 ) { + timezone = "Europe/Madrid"; + } + } + else if ( strcmp (country, "ET") == 0 ) { + timezone = "Africa/Addis_Ababa"; + } + else if ( strcmp (country, "FI") == 0 ) { + timezone = "Europe/Helsinki"; + } + else if ( strcmp (country, "FJ") == 0 ) { + timezone = "Pacific/Fiji"; + } + else if ( strcmp (country, "FK") == 0 ) { + timezone = "Atlantic/Stanley"; + } + else if ( strcmp (country, "FO") == 0 ) { + timezone = "Atlantic/Faeroe"; + } + else if ( strcmp (country, "FR") == 0 ) { + timezone = "Europe/Paris"; + } + else if ( strcmp (country, "GA") == 0 ) { + timezone = "Africa/Libreville"; + } + else if ( strcmp (country, "GB") == 0 ) { + timezone = "Europe/London"; + } + else if ( strcmp (country, "GD") == 0 ) { + timezone = "America/Grenada"; + } + else if ( strcmp (country, "GE") == 0 ) { + timezone = "Asia/Tbilisi"; + } + else if ( strcmp (country, "GF") == 0 ) { + timezone = "America/Cayenne"; + } + else if ( strcmp (country, "GG") == 0 ) { + timezone = "Europe/Guernsey"; + } + else if ( strcmp (country, "GH") == 0 ) { + timezone = "Africa/Accra"; + } + else if ( strcmp (country, "GI") == 0 ) { + timezone = "Europe/Gibraltar"; + } + else if ( strcmp (country, "GL") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "America/Thule"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "America/Godthab"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "America/Godthab"; + } + } + else if ( strcmp (country, "GM") == 0 ) { + timezone = "Africa/Banjul"; + } + else if ( strcmp (country, "GN") == 0 ) { + timezone = "Africa/Conakry"; + } + else if ( strcmp (country, "GP") == 0 ) { + timezone = "America/Guadeloupe"; + } + else if ( strcmp (country, "GQ") == 0 ) { + timezone = "Africa/Malabo"; + } + else if ( strcmp (country, "GR") == 0 ) { + timezone = "Europe/Athens"; + } + else if ( strcmp (country, "GS") == 0 ) { + timezone = "Atlantic/South_Georgia"; + } + else if ( strcmp (country, "GT") == 0 ) { + timezone = "America/Guatemala"; + } + else if ( strcmp (country, "GU") == 0 ) { + timezone = "Pacific/Guam"; + } + else if ( strcmp (country, "GW") == 0 ) { + timezone = "Africa/Bissau"; + } + else if ( strcmp (country, "GY") == 0 ) { + timezone = "America/Guyana"; + } + else if ( strcmp (country, "HK") == 0 ) { + timezone = "Asia/Hong_Kong"; + } + else if ( strcmp (country, "HN") == 0 ) { + timezone = "America/Tegucigalpa"; + } + else if ( strcmp (country, "HR") == 0 ) { + timezone = "Europe/Zagreb"; + } + else if ( strcmp (country, "HT") == 0 ) { + timezone = "America/Port-au-Prince"; + } + else if ( strcmp (country, "HU") == 0 ) { + timezone = "Europe/Budapest"; + } + else if ( strcmp (country, "ID") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "Asia/Pontianak"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "Asia/Makassar"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "Asia/Jakarta"; + } + else if ( strcmp (region, "04") == 0 ) { + timezone = "Asia/Jakarta"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "Asia/Jakarta"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "Asia/Jakarta"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "Asia/Jakarta"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "Asia/Jakarta"; + } + else if ( strcmp (region, "09") == 0 ) { + timezone = "Asia/Jayapura"; + } + else if ( strcmp (region, "10") == 0 ) { + timezone = "Asia/Jakarta"; + } + else if ( strcmp (region, "11") == 0 ) { + timezone = "Asia/Pontianak"; + } + else if ( strcmp (region, "12") == 0 ) { + timezone = "Asia/Makassar"; + } + else if ( strcmp (region, "13") == 0 ) { + timezone = "Asia/Makassar"; + } + else if ( strcmp (region, "14") == 0 ) { + timezone = "Asia/Makassar"; + } + else if ( strcmp (region, "15") == 0 ) { + timezone = "Asia/Jakarta"; + } + else if ( strcmp (region, "16") == 0 ) { + timezone = "Asia/Makassar"; + } + else if ( strcmp (region, "17") == 0 ) { + timezone = "Asia/Makassar"; + } + else if ( strcmp (region, "18") == 0 ) { + timezone = "Asia/Makassar"; + } + else if ( strcmp (region, "19") == 0 ) { + timezone = "Asia/Pontianak"; + } + else if ( strcmp (region, "20") == 0 ) { + timezone = "Asia/Makassar"; + } + else if ( strcmp (region, "21") == 0 ) { + timezone = "Asia/Makassar"; + } + else if ( strcmp (region, "22") == 0 ) { + timezone = "Asia/Makassar"; + } + else if ( strcmp (region, "23") == 0 ) { + timezone = "Asia/Makassar"; + } + else if ( strcmp (region, "24") == 0 ) { + timezone = "Asia/Jakarta"; + } + else if ( strcmp (region, "25") == 0 ) { + timezone = "Asia/Pontianak"; + } + else if ( strcmp (region, "26") == 0 ) { + timezone = "Asia/Pontianak"; + } + else if ( strcmp (region, "30") == 0 ) { + timezone = "Asia/Jakarta"; + } + else if ( strcmp (region, "31") == 0 ) { + timezone = "Asia/Makassar"; + } + else if ( strcmp (region, "33") == 0 ) { + timezone = "Asia/Jakarta"; + } + } + else if ( strcmp (country, "IE") == 0 ) { + timezone = "Europe/Dublin"; + } + else if ( strcmp (country, "IL") == 0 ) { + timezone = "Asia/Jerusalem"; + } + else if ( strcmp (country, "IM") == 0 ) { + timezone = "Europe/Isle_of_Man"; + } + else if ( strcmp (country, "IN") == 0 ) { + timezone = "Asia/Calcutta"; + } + else if ( strcmp (country, "IO") == 0 ) { + timezone = "Indian/Chagos"; + } + else if ( strcmp (country, "IQ") == 0 ) { + timezone = "Asia/Baghdad"; + } + else if ( strcmp (country, "IR") == 0 ) { + timezone = "Asia/Tehran"; + } + else if ( strcmp (country, "IS") == 0 ) { + timezone = "Atlantic/Reykjavik"; + } + else if ( strcmp (country, "IT") == 0 ) { + timezone = "Europe/Rome"; + } + else if ( strcmp (country, "JE") == 0 ) { + timezone = "Europe/Jersey"; + } + else if ( strcmp (country, "JM") == 0 ) { + timezone = "America/Jamaica"; + } + else if ( strcmp (country, "JO") == 0 ) { + timezone = "Asia/Amman"; + } + else if ( strcmp (country, "JP") == 0 ) { + timezone = "Asia/Tokyo"; + } + else if ( strcmp (country, "KE") == 0 ) { + timezone = "Africa/Nairobi"; + } + else if ( strcmp (country, "KG") == 0 ) { + timezone = "Asia/Bishkek"; + } + else if ( strcmp (country, "KH") == 0 ) { + timezone = "Asia/Phnom_Penh"; + } + else if ( strcmp (country, "KI") == 0 ) { + timezone = "Pacific/Tarawa"; + } + else if ( strcmp (country, "KM") == 0 ) { + timezone = "Indian/Comoro"; + } + else if ( strcmp (country, "KN") == 0 ) { + timezone = "America/St_Kitts"; + } + else if ( strcmp (country, "KP") == 0 ) { + timezone = "Asia/Pyongyang"; + } + else if ( strcmp (country, "KR") == 0 ) { + timezone = "Asia/Seoul"; + } + else if ( strcmp (country, "KW") == 0 ) { + timezone = "Asia/Kuwait"; + } + else if ( strcmp (country, "KY") == 0 ) { + timezone = "America/Cayman"; + } + else if ( strcmp (country, "KZ") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "Asia/Almaty"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "Asia/Almaty"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "Asia/Qyzylorda"; + } + else if ( strcmp (region, "04") == 0 ) { + timezone = "Asia/Aqtobe"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "Asia/Qyzylorda"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "Asia/Aqtau"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "Asia/Oral"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "Asia/Qyzylorda"; + } + else if ( strcmp (region, "09") == 0 ) { + timezone = "Asia/Aqtau"; + } + else if ( strcmp (region, "10") == 0 ) { + timezone = "Asia/Qyzylorda"; + } + else if ( strcmp (region, "11") == 0 ) { + timezone = "Asia/Almaty"; + } + else if ( strcmp (region, "12") == 0 ) { + timezone = "Asia/Qyzylorda"; + } + else if ( strcmp (region, "13") == 0 ) { + timezone = "Asia/Aqtobe"; + } + else if ( strcmp (region, "14") == 0 ) { + timezone = "Asia/Qyzylorda"; + } + else if ( strcmp (region, "15") == 0 ) { + timezone = "Asia/Almaty"; + } + else if ( strcmp (region, "16") == 0 ) { + timezone = "Asia/Aqtobe"; + } + else if ( strcmp (region, "17") == 0 ) { + timezone = "Asia/Almaty"; + } + } + else if ( strcmp (country, "LA") == 0 ) { + timezone = "Asia/Vientiane"; + } + else if ( strcmp (country, "LB") == 0 ) { + timezone = "Asia/Beirut"; + } + else if ( strcmp (country, "LC") == 0 ) { + timezone = "America/St_Lucia"; + } + else if ( strcmp (country, "LI") == 0 ) { + timezone = "Europe/Vaduz"; + } + else if ( strcmp (country, "LK") == 0 ) { + timezone = "Asia/Colombo"; + } + else if ( strcmp (country, "LR") == 0 ) { + timezone = "Africa/Monrovia"; + } + else if ( strcmp (country, "LS") == 0 ) { + timezone = "Africa/Maseru"; + } + else if ( strcmp (country, "LT") == 0 ) { + timezone = "Europe/Vilnius"; + } + else if ( strcmp (country, "LU") == 0 ) { + timezone = "Europe/Luxembourg"; + } + else if ( strcmp (country, "LV") == 0 ) { + timezone = "Europe/Riga"; + } + else if ( strcmp (country, "LY") == 0 ) { + timezone = "Africa/Tripoli"; + } + else if ( strcmp (country, "MA") == 0 ) { + timezone = "Africa/Casablanca"; + } + else if ( strcmp (country, "MC") == 0 ) { + timezone = "Europe/Monaco"; + } + else if ( strcmp (country, "MD") == 0 ) { + timezone = "Europe/Chisinau"; + } + else if ( strcmp (country, "ME") == 0 ) { + timezone = "Europe/Podgorica"; + } + else if ( strcmp (country, "MF") == 0 ) { + timezone = "America/Marigot"; + } + else if ( strcmp (country, "MG") == 0 ) { + timezone = "Indian/Antananarivo"; + } + else if ( strcmp (country, "MK") == 0 ) { + timezone = "Europe/Skopje"; + } + else if ( strcmp (country, "ML") == 0 ) { + timezone = "Africa/Bamako"; + } + else if ( strcmp (country, "MM") == 0 ) { + timezone = "Asia/Rangoon"; + } + else if ( strcmp (country, "MN") == 0 ) { + timezone = "Asia/Choibalsan"; + } + else if ( strcmp (country, "MO") == 0 ) { + timezone = "Asia/Macao"; + } + else if ( strcmp (country, "MP") == 0 ) { + timezone = "Pacific/Saipan"; + } + else if ( strcmp (country, "MQ") == 0 ) { + timezone = "America/Martinique"; + } + else if ( strcmp (country, "MR") == 0 ) { + timezone = "Africa/Nouakchott"; + } + else if ( strcmp (country, "MS") == 0 ) { + timezone = "America/Montserrat"; + } + else if ( strcmp (country, "MT") == 0 ) { + timezone = "Europe/Malta"; + } + else if ( strcmp (country, "MU") == 0 ) { + timezone = "Indian/Mauritius"; + } + else if ( strcmp (country, "MV") == 0 ) { + timezone = "Indian/Maldives"; + } + else if ( strcmp (country, "MW") == 0 ) { + timezone = "Africa/Blantyre"; + } + else if ( strcmp (country, "MX") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "America/Tijuana"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "America/Hermosillo"; + } + else if ( strcmp (region, "04") == 0 ) { + timezone = "America/Merida"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "America/Chihuahua"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "America/Monterrey"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "09") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "10") == 0 ) { + timezone = "America/Mazatlan"; + } + else if ( strcmp (region, "11") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "12") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "13") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "14") == 0 ) { + timezone = "America/Mazatlan"; + } + else if ( strcmp (region, "15") == 0 ) { + timezone = "America/Chihuahua"; + } + else if ( strcmp (region, "16") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "17") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "18") == 0 ) { + timezone = "America/Mazatlan"; + } + else if ( strcmp (region, "19") == 0 ) { + timezone = "America/Monterrey"; + } + else if ( strcmp (region, "20") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "21") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "22") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "23") == 0 ) { + timezone = "America/Cancun"; + } + else if ( strcmp (region, "24") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "25") == 0 ) { + timezone = "America/Mazatlan"; + } + else if ( strcmp (region, "26") == 0 ) { + timezone = "America/Hermosillo"; + } + else if ( strcmp (region, "27") == 0 ) { + timezone = "America/Merida"; + } + else if ( strcmp (region, "28") == 0 ) { + timezone = "America/Monterrey"; + } + else if ( strcmp (region, "29") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "30") == 0 ) { + timezone = "America/Mexico_City"; + } + else if ( strcmp (region, "31") == 0 ) { + timezone = "America/Merida"; + } + else if ( strcmp (region, "32") == 0 ) { + timezone = "America/Monterrey"; + } + } + else if ( strcmp (country, "MY") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "Asia/Kuala_Lumpur"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "Asia/Kuala_Lumpur"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "Asia/Kuala_Lumpur"; + } + else if ( strcmp (region, "04") == 0 ) { + timezone = "Asia/Kuala_Lumpur"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "Asia/Kuala_Lumpur"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "Asia/Kuala_Lumpur"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "Asia/Kuala_Lumpur"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "Asia/Kuala_Lumpur"; + } + else if ( strcmp (region, "09") == 0 ) { + timezone = "Asia/Kuala_Lumpur"; + } + else if ( strcmp (region, "11") == 0 ) { + timezone = "Asia/Kuching"; + } + else if ( strcmp (region, "12") == 0 ) { + timezone = "Asia/Kuala_Lumpur"; + } + else if ( strcmp (region, "13") == 0 ) { + timezone = "Asia/Kuala_Lumpur"; + } + else if ( strcmp (region, "14") == 0 ) { + timezone = "Asia/Kuala_Lumpur"; + } + else if ( strcmp (region, "15") == 0 ) { + timezone = "Asia/Kuching"; + } + else if ( strcmp (region, "16") == 0 ) { + timezone = "Asia/Kuching"; + } + } + else if ( strcmp (country, "MZ") == 0 ) { + timezone = "Africa/Maputo"; + } + else if ( strcmp (country, "NA") == 0 ) { + timezone = "Africa/Windhoek"; + } + else if ( strcmp (country, "NC") == 0 ) { + timezone = "Pacific/Noumea"; + } + else if ( strcmp (country, "NE") == 0 ) { + timezone = "Africa/Niamey"; + } + else if ( strcmp (country, "NF") == 0 ) { + timezone = "Pacific/Norfolk"; + } + else if ( strcmp (country, "NG") == 0 ) { + timezone = "Africa/Lagos"; + } + else if ( strcmp (country, "NI") == 0 ) { + timezone = "America/Managua"; + } + else if ( strcmp (country, "NL") == 0 ) { + timezone = "Europe/Amsterdam"; + } + else if ( strcmp (country, "NO") == 0 ) { + timezone = "Europe/Oslo"; + } + else if ( strcmp (country, "NP") == 0 ) { + timezone = "Asia/Katmandu"; + } + else if ( strcmp (country, "NR") == 0 ) { + timezone = "Pacific/Nauru"; + } + else if ( strcmp (country, "NU") == 0 ) { + timezone = "Pacific/Niue"; + } + else if ( strcmp (country, "NZ") == 0 ) { + if ( strcmp (region, "85") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "E7") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "E8") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "E9") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "F1") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "F2") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "F3") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "F4") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "F5") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "F7") == 0 ) { + timezone = "Pacific/Chatham"; + } + else if ( strcmp (region, "F8") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "F9") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "G1") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "G2") == 0 ) { + timezone = "Pacific/Auckland"; + } + else if ( strcmp (region, "G3") == 0 ) { + timezone = "Pacific/Auckland"; + } + } + else if ( strcmp (country, "OM") == 0 ) { + timezone = "Asia/Muscat"; + } + else if ( strcmp (country, "PA") == 0 ) { + timezone = "America/Panama"; + } + else if ( strcmp (country, "PE") == 0 ) { + timezone = "America/Lima"; + } + else if ( strcmp (country, "PF") == 0 ) { + timezone = "Pacific/Marquesas"; + } + else if ( strcmp (country, "PG") == 0 ) { + timezone = "Pacific/Port_Moresby"; + } + else if ( strcmp (country, "PH") == 0 ) { + timezone = "Asia/Manila"; + } + else if ( strcmp (country, "PK") == 0 ) { + timezone = "Asia/Karachi"; + } + else if ( strcmp (country, "PL") == 0 ) { + timezone = "Europe/Warsaw"; + } + else if ( strcmp (country, "PM") == 0 ) { + timezone = "America/Miquelon"; + } + else if ( strcmp (country, "PN") == 0 ) { + timezone = "Pacific/Pitcairn"; + } + else if ( strcmp (country, "PR") == 0 ) { + timezone = "America/Puerto_Rico"; + } + else if ( strcmp (country, "PS") == 0 ) { + timezone = "Asia/Gaza"; + } + else if ( strcmp (country, "PT") == 0 ) { + if ( strcmp (region, "02") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "04") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "09") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "10") == 0 ) { + timezone = "Atlantic/Madeira"; + } + else if ( strcmp (region, "11") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "13") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "14") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "16") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "17") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "18") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "19") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "20") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "21") == 0 ) { + timezone = "Europe/Lisbon"; + } + else if ( strcmp (region, "22") == 0 ) { + timezone = "Europe/Lisbon"; + } + } + else if ( strcmp (country, "PW") == 0 ) { + timezone = "Pacific/Palau"; + } + else if ( strcmp (country, "PY") == 0 ) { + timezone = "America/Asuncion"; + } + else if ( strcmp (country, "QA") == 0 ) { + timezone = "Asia/Qatar"; + } + else if ( strcmp (country, "RE") == 0 ) { + timezone = "Indian/Reunion"; + } + else if ( strcmp (country, "RO") == 0 ) { + timezone = "Europe/Bucharest"; + } + else if ( strcmp (country, "RS") == 0 ) { + timezone = "Europe/Belgrade"; + } + else if ( strcmp (country, "RU") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "Europe/Volgograd"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "Asia/Irkutsk"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "Asia/Novokuznetsk"; + } + else if ( strcmp (region, "04") == 0 ) { + timezone = "Asia/Novosibirsk"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "Asia/Vladivostok"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "Europe/Volgograd"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "Europe/Samara"; + } + else if ( strcmp (region, "09") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "10") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "11") == 0 ) { + timezone = "Asia/Irkutsk"; + } + else if ( strcmp (region, "13") == 0 ) { + timezone = "Asia/Yekaterinburg"; + } + else if ( strcmp (region, "14") == 0 ) { + timezone = "Asia/Irkutsk"; + } + else if ( strcmp (region, "15") == 0 ) { + timezone = "Asia/Anadyr"; + } + else if ( strcmp (region, "16") == 0 ) { + timezone = "Europe/Samara"; + } + else if ( strcmp (region, "17") == 0 ) { + timezone = "Europe/Volgograd"; + } + else if ( strcmp (region, "18") == 0 ) { + timezone = "Asia/Krasnoyarsk"; + } + else if ( strcmp (region, "20") == 0 ) { + timezone = "Asia/Irkutsk"; + } + else if ( strcmp (region, "21") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "22") == 0 ) { + timezone = "Europe/Volgograd"; + } + else if ( strcmp (region, "23") == 0 ) { + timezone = "Europe/Kaliningrad"; + } + else if ( strcmp (region, "24") == 0 ) { + timezone = "Europe/Volgograd"; + } + else if ( strcmp (region, "25") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "26") == 0 ) { + timezone = "Asia/Kamchatka"; + } + else if ( strcmp (region, "27") == 0 ) { + timezone = "Europe/Volgograd"; + } + else if ( strcmp (region, "28") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "29") == 0 ) { + timezone = "Asia/Novokuznetsk"; + } + else if ( strcmp (region, "30") == 0 ) { + timezone = "Asia/Vladivostok"; + } + else if ( strcmp (region, "31") == 0 ) { + timezone = "Asia/Krasnoyarsk"; + } + else if ( strcmp (region, "32") == 0 ) { + timezone = "Asia/Omsk"; + } + else if ( strcmp (region, "33") == 0 ) { + timezone = "Asia/Yekaterinburg"; + } + else if ( strcmp (region, "34") == 0 ) { + timezone = "Asia/Yekaterinburg"; + } + else if ( strcmp (region, "35") == 0 ) { + timezone = "Asia/Yekaterinburg"; + } + else if ( strcmp (region, "36") == 0 ) { + timezone = "Asia/Anadyr"; + } + else if ( strcmp (region, "37") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "38") == 0 ) { + timezone = "Europe/Volgograd"; + } + else if ( strcmp (region, "39") == 0 ) { + timezone = "Asia/Krasnoyarsk"; + } + else if ( strcmp (region, "40") == 0 ) { + timezone = "Asia/Yekaterinburg"; + } + else if ( strcmp (region, "41") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "42") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "43") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "44") == 0 ) { + timezone = "Asia/Magadan"; + } + else if ( strcmp (region, "45") == 0 ) { + timezone = "Europe/Samara"; + } + else if ( strcmp (region, "46") == 0 ) { + timezone = "Europe/Samara"; + } + else if ( strcmp (region, "47") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "48") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "49") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "50") == 0 ) { + timezone = "Asia/Yekaterinburg"; + } + else if ( strcmp (region, "51") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "52") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "53") == 0 ) { + timezone = "Asia/Novosibirsk"; + } + else if ( strcmp (region, "54") == 0 ) { + timezone = "Asia/Omsk"; + } + else if ( strcmp (region, "55") == 0 ) { + timezone = "Europe/Samara"; + } + else if ( strcmp (region, "56") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "57") == 0 ) { + timezone = "Europe/Samara"; + } + else if ( strcmp (region, "58") == 0 ) { + timezone = "Asia/Yekaterinburg"; + } + else if ( strcmp (region, "59") == 0 ) { + timezone = "Asia/Vladivostok"; + } + else if ( strcmp (region, "60") == 0 ) { + timezone = "Europe/Kaliningrad"; + } + else if ( strcmp (region, "61") == 0 ) { + timezone = "Europe/Volgograd"; + } + else if ( strcmp (region, "62") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "63") == 0 ) { + timezone = "Asia/Yakutsk"; + } + else if ( strcmp (region, "64") == 0 ) { + timezone = "Asia/Sakhalin"; + } + else if ( strcmp (region, "65") == 0 ) { + timezone = "Europe/Samara"; + } + else if ( strcmp (region, "66") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "67") == 0 ) { + timezone = "Europe/Samara"; + } + else if ( strcmp (region, "68") == 0 ) { + timezone = "Europe/Volgograd"; + } + else if ( strcmp (region, "69") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "70") == 0 ) { + timezone = "Europe/Volgograd"; + } + else if ( strcmp (region, "71") == 0 ) { + timezone = "Asia/Yekaterinburg"; + } + else if ( strcmp (region, "72") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "73") == 0 ) { + timezone = "Europe/Samara"; + } + else if ( strcmp (region, "74") == 0 ) { + timezone = "Asia/Krasnoyarsk"; + } + else if ( strcmp (region, "75") == 0 ) { + timezone = "Asia/Novosibirsk"; + } + else if ( strcmp (region, "76") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "77") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "78") == 0 ) { + timezone = "Asia/Yekaterinburg"; + } + else if ( strcmp (region, "79") == 0 ) { + timezone = "Asia/Irkutsk"; + } + else if ( strcmp (region, "80") == 0 ) { + timezone = "Asia/Yekaterinburg"; + } + else if ( strcmp (region, "81") == 0 ) { + timezone = "Europe/Samara"; + } + else if ( strcmp (region, "82") == 0 ) { + timezone = "Asia/Irkutsk"; + } + else if ( strcmp (region, "83") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "84") == 0 ) { + timezone = "Europe/Volgograd"; + } + else if ( strcmp (region, "85") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "86") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "87") == 0 ) { + timezone = "Asia/Novosibirsk"; + } + else if ( strcmp (region, "88") == 0 ) { + timezone = "Europe/Moscow"; + } + else if ( strcmp (region, "89") == 0 ) { + timezone = "Asia/Vladivostok"; + } + } + else if ( strcmp (country, "RW") == 0 ) { + timezone = "Africa/Kigali"; + } + else if ( strcmp (country, "SA") == 0 ) { + timezone = "Asia/Riyadh"; + } + else if ( strcmp (country, "SB") == 0 ) { + timezone = "Pacific/Guadalcanal"; + } + else if ( strcmp (country, "SC") == 0 ) { + timezone = "Indian/Mahe"; + } + else if ( strcmp (country, "SD") == 0 ) { + timezone = "Africa/Khartoum"; + } + else if ( strcmp (country, "SE") == 0 ) { + timezone = "Europe/Stockholm"; + } + else if ( strcmp (country, "SG") == 0 ) { + timezone = "Asia/Singapore"; + } + else if ( strcmp (country, "SH") == 0 ) { + timezone = "Atlantic/St_Helena"; + } + else if ( strcmp (country, "SI") == 0 ) { + timezone = "Europe/Ljubljana"; + } + else if ( strcmp (country, "SJ") == 0 ) { + timezone = "Arctic/Longyearbyen"; + } + else if ( strcmp (country, "SK") == 0 ) { + timezone = "Europe/Bratislava"; + } + else if ( strcmp (country, "SL") == 0 ) { + timezone = "Africa/Freetown"; + } + else if ( strcmp (country, "SM") == 0 ) { + timezone = "Europe/San_Marino"; + } + else if ( strcmp (country, "SN") == 0 ) { + timezone = "Africa/Dakar"; + } + else if ( strcmp (country, "SO") == 0 ) { + timezone = "Africa/Mogadishu"; + } + else if ( strcmp (country, "SR") == 0 ) { + timezone = "America/Paramaribo"; + } + else if ( strcmp (country, "ST") == 0 ) { + timezone = "Africa/Sao_Tome"; + } + else if ( strcmp (country, "SV") == 0 ) { + timezone = "America/El_Salvador"; + } + else if ( strcmp (country, "SX") == 0 ) { + timezone = "America/Curacao"; + } + else if ( strcmp (country, "SY") == 0 ) { + timezone = "Asia/Damascus"; + } + else if ( strcmp (country, "SZ") == 0 ) { + timezone = "Africa/Mbabane"; + } + else if ( strcmp (country, "TC") == 0 ) { + timezone = "America/Grand_Turk"; + } + else if ( strcmp (country, "TD") == 0 ) { + timezone = "Africa/Ndjamena"; + } + else if ( strcmp (country, "TF") == 0 ) { + timezone = "Indian/Kerguelen"; + } + else if ( strcmp (country, "TG") == 0 ) { + timezone = "Africa/Lome"; + } + else if ( strcmp (country, "TH") == 0 ) { + timezone = "Asia/Bangkok"; + } + else if ( strcmp (country, "TJ") == 0 ) { + timezone = "Asia/Dushanbe"; + } + else if ( strcmp (country, "TK") == 0 ) { + timezone = "Pacific/Fakaofo"; + } + else if ( strcmp (country, "TL") == 0 ) { + timezone = "Asia/Dili"; + } + else if ( strcmp (country, "TM") == 0 ) { + timezone = "Asia/Ashgabat"; + } + else if ( strcmp (country, "TN") == 0 ) { + timezone = "Africa/Tunis"; + } + else if ( strcmp (country, "TO") == 0 ) { + timezone = "Pacific/Tongatapu"; + } + else if ( strcmp (country, "TR") == 0 ) { + timezone = "Asia/Istanbul"; + } + else if ( strcmp (country, "TT") == 0 ) { + timezone = "America/Port_of_Spain"; + } + else if ( strcmp (country, "TV") == 0 ) { + timezone = "Pacific/Funafuti"; + } + else if ( strcmp (country, "TW") == 0 ) { + timezone = "Asia/Taipei"; + } + else if ( strcmp (country, "TZ") == 0 ) { + timezone = "Africa/Dar_es_Salaam"; + } + else if ( strcmp (country, "UA") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "Europe/Kiev"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "Europe/Kiev"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "Europe/Uzhgorod"; + } + else if ( strcmp (region, "04") == 0 ) { + timezone = "Europe/Zaporozhye"; + } + else if ( strcmp (region, "05") == 0 ) { + timezone = "Europe/Zaporozhye"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "Europe/Uzhgorod"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "Europe/Zaporozhye"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "Europe/Simferopol"; + } + else if ( strcmp (region, "09") == 0 ) { + timezone = "Europe/Kiev"; + } + else if ( strcmp (region, "10") == 0 ) { + timezone = "Europe/Zaporozhye"; + } + else if ( strcmp (region, "11") == 0 ) { + timezone = "Europe/Simferopol"; + } + else if ( strcmp (region, "13") == 0 ) { + timezone = "Europe/Kiev"; + } + else if ( strcmp (region, "14") == 0 ) { + timezone = "Europe/Zaporozhye"; + } + else if ( strcmp (region, "15") == 0 ) { + timezone = "Europe/Uzhgorod"; + } + else if ( strcmp (region, "16") == 0 ) { + timezone = "Europe/Zaporozhye"; + } + else if ( strcmp (region, "17") == 0 ) { + timezone = "Europe/Simferopol"; + } + else if ( strcmp (region, "18") == 0 ) { + timezone = "Europe/Zaporozhye"; + } + else if ( strcmp (region, "19") == 0 ) { + timezone = "Europe/Kiev"; + } + else if ( strcmp (region, "20") == 0 ) { + timezone = "Europe/Simferopol"; + } + else if ( strcmp (region, "21") == 0 ) { + timezone = "Europe/Kiev"; + } + else if ( strcmp (region, "22") == 0 ) { + timezone = "Europe/Uzhgorod"; + } + else if ( strcmp (region, "23") == 0 ) { + timezone = "Europe/Kiev"; + } + else if ( strcmp (region, "24") == 0 ) { + timezone = "Europe/Uzhgorod"; + } + else if ( strcmp (region, "25") == 0 ) { + timezone = "Europe/Uzhgorod"; + } + else if ( strcmp (region, "26") == 0 ) { + timezone = "Europe/Zaporozhye"; + } + else if ( strcmp (region, "27") == 0 ) { + timezone = "Europe/Kiev"; + } + } + else if ( strcmp (country, "UG") == 0 ) { + timezone = "Africa/Kampala"; + } + else if ( strcmp (country, "US") == 0 ) { + if ( strcmp (region, "AK") == 0 ) { + timezone = "America/Anchorage"; + } + else if ( strcmp (region, "AL") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "AR") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "AZ") == 0 ) { + timezone = "America/Phoenix"; + } + else if ( strcmp (region, "CA") == 0 ) { + timezone = "America/Los_Angeles"; + } + else if ( strcmp (region, "CO") == 0 ) { + timezone = "America/Denver"; + } + else if ( strcmp (region, "CT") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "DC") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "DE") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "FL") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "GA") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "HI") == 0 ) { + timezone = "Pacific/Honolulu"; + } + else if ( strcmp (region, "IA") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "ID") == 0 ) { + timezone = "America/Denver"; + } + else if ( strcmp (region, "IL") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "IN") == 0 ) { + timezone = "America/Indianapolis"; + } + else if ( strcmp (region, "KS") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "KY") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "LA") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "MA") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "MD") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "ME") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "MI") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "MN") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "MO") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "MS") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "MT") == 0 ) { + timezone = "America/Denver"; + } + else if ( strcmp (region, "NC") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "ND") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "NE") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "NH") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "NJ") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "NM") == 0 ) { + timezone = "America/Denver"; + } + else if ( strcmp (region, "NV") == 0 ) { + timezone = "America/Los_Angeles"; + } + else if ( strcmp (region, "NY") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "OH") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "OK") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "OR") == 0 ) { + timezone = "America/Los_Angeles"; + } + else if ( strcmp (region, "PA") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "RI") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "SC") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "SD") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "TN") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "TX") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "UT") == 0 ) { + timezone = "America/Denver"; + } + else if ( strcmp (region, "VA") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "VT") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "WA") == 0 ) { + timezone = "America/Los_Angeles"; + } + else if ( strcmp (region, "WI") == 0 ) { + timezone = "America/Chicago"; + } + else if ( strcmp (region, "WV") == 0 ) { + timezone = "America/New_York"; + } + else if ( strcmp (region, "WY") == 0 ) { + timezone = "America/Denver"; + } + } + else if ( strcmp (country, "UY") == 0 ) { + timezone = "America/Montevideo"; + } + else if ( strcmp (country, "UZ") == 0 ) { + if ( strcmp (region, "01") == 0 ) { + timezone = "Asia/Tashkent"; + } + else if ( strcmp (region, "02") == 0 ) { + timezone = "Asia/Samarkand"; + } + else if ( strcmp (region, "03") == 0 ) { + timezone = "Asia/Tashkent"; + } + else if ( strcmp (region, "06") == 0 ) { + timezone = "Asia/Tashkent"; + } + else if ( strcmp (region, "07") == 0 ) { + timezone = "Asia/Samarkand"; + } + else if ( strcmp (region, "08") == 0 ) { + timezone = "Asia/Samarkand"; + } + else if ( strcmp (region, "09") == 0 ) { + timezone = "Asia/Samarkand"; + } + else if ( strcmp (region, "10") == 0 ) { + timezone = "Asia/Samarkand"; + } + else if ( strcmp (region, "12") == 0 ) { + timezone = "Asia/Samarkand"; + } + else if ( strcmp (region, "13") == 0 ) { + timezone = "Asia/Tashkent"; + } + else if ( strcmp (region, "14") == 0 ) { + timezone = "Asia/Tashkent"; + } + } + else if ( strcmp (country, "VA") == 0 ) { + timezone = "Europe/Vatican"; + } + else if ( strcmp (country, "VC") == 0 ) { + timezone = "America/St_Vincent"; + } + else if ( strcmp (country, "VE") == 0 ) { + timezone = "America/Caracas"; + } + else if ( strcmp (country, "VG") == 0 ) { + timezone = "America/Tortola"; + } + else if ( strcmp (country, "VI") == 0 ) { + timezone = "America/St_Thomas"; + } + else if ( strcmp (country, "VN") == 0 ) { + timezone = "Asia/Phnom_Penh"; + } + else if ( strcmp (country, "VU") == 0 ) { + timezone = "Pacific/Efate"; + } + else if ( strcmp (country, "WF") == 0 ) { + timezone = "Pacific/Wallis"; + } + else if ( strcmp (country, "WS") == 0 ) { + timezone = "Pacific/Samoa"; + } + else if ( strcmp (country, "YE") == 0 ) { + timezone = "Asia/Aden"; + } + else if ( strcmp (country, "YT") == 0 ) { + timezone = "Indian/Mayotte"; + } + else if ( strcmp (country, "YU") == 0 ) { + timezone = "Europe/Belgrade"; + } + else if ( strcmp (country, "ZA") == 0 ) { + timezone = "Africa/Johannesburg"; + } + else if ( strcmp (country, "ZM") == 0 ) { + timezone = "Africa/Lusaka"; + } + else if ( strcmp (country, "ZW") == 0 ) { + timezone = "Africa/Harare"; + } + return timezone; +} diff --git a/src/libs/resiprocate/contrib/GeoIP/libGeoIP/types.h b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/types.h new file mode 100644 index 00000000..42c5ddd0 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/libGeoIP/types.h @@ -0,0 +1,140 @@ +/* types.h - some common typedefs + * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + * + * This file is part of GNUPG. + * + * GNUPG 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 2 of the License, or + * (at your option) any later version. + * + * GNUPG 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef G10_TYPES_H +#define G10_TYPES_H + +#ifdef HAVE_INTTYPES_H +/* For uint64_t */ +#include +#endif + +/* The AC_CHECK_SIZEOF() in configure fails for some machines. + * we provide some fallback values here */ +#if !SIZEOF_UNSIGNED_SHORT +#undef SIZEOF_UNSIGNED_SHORT +#define SIZEOF_UNSIGNED_SHORT 2 +#endif +#if !SIZEOF_UNSIGNED_INT +#undef SIZEOF_UNSIGNED_INT +#define SIZEOF_UNSIGNED_INT 4 +#endif +#if !SIZEOF_UNSIGNED_LONG +#undef SIZEOF_UNSIGNED_LONG +#define SIZEOF_UNSIGNED_LONG 4 +#endif + + +#include + +#ifndef HAVE_BYTE_TYPEDEF +#undef byte /* maybe there is a macro with this name */ +#ifndef __riscos__ +typedef unsigned char byte; +#else +/* Norcroft treats char = unsigned char as legal assignment + but char* = unsigned char* as illegal assignment + and the same applies to the signed variants as well */ +typedef char byte; +#endif +#define HAVE_BYTE_TYPEDEF +#endif + +#ifndef HAVE_USHORT_TYPEDEF +#undef ushort /* maybe there is a macro with this name */ +typedef unsigned short ushort; +#define HAVE_USHORT_TYPEDEF +#endif + +#ifndef HAVE_ULONG_TYPEDEF +#undef ulong /* maybe there is a macro with this name */ +typedef unsigned long ulong; +#define HAVE_ULONG_TYPEDEF +#endif + +#ifndef HAVE_U16_TYPEDEF +#undef u16 /* maybe there is a macro with this name */ +#if SIZEOF_UNSIGNED_INT == 2 +typedef unsigned int u16; +#elif SIZEOF_UNSIGNED_SHORT == 2 +typedef unsigned short u16; +#else +#error no typedef for u16 +#endif +#define HAVE_U16_TYPEDEF +#endif + +#ifndef HAVE_U32_TYPEDEF +#undef u32 /* maybe there is a macro with this name */ +#if SIZEOF_UNSIGNED_INT == 4 +typedef unsigned int u32; +#elif SIZEOF_UNSIGNED_LONG == 4 +typedef unsigned long u32; +#else +#error no typedef for u32 +#endif +#define HAVE_U32_TYPEDEF +#endif + +/**************** + * Warning: Some systems segfault when this u64 typedef and + * the dummy code in cipher/md.c is not available. Examples are + * Solaris and IRIX. + */ +#ifndef HAVE_U64_TYPEDEF +#undef u64 /* maybe there is a macro with this name */ +#if SIZEOF_UINT64_T == 8 +typedef uint64_t u64; +#define U64_C(c) (UINT64_C(c)) +#define HAVE_U64_TYPEDEF +#elif SIZEOF_UNSIGNED_INT == 8 +typedef unsigned int u64; +#define U64_C(c) (c ## U) +#define HAVE_U64_TYPEDEF +#elif SIZEOF_UNSIGNED_LONG == 8 +typedef unsigned long u64; +#define U64_C(c) (c ## UL) +#define HAVE_U64_TYPEDEF +#elif SIZEOF_UNSIGNED_LONG_LONG == 8 +typedef unsigned long long u64; +#define U64_C(c) (c ## ULL) +#define HAVE_U64_TYPEDEF +#endif +#endif + +typedef union { + int a; + short b; + char c[1]; + long d; +#ifdef HAVE_U64_TYPEDEF + u64 e; +#endif + float f; + double g; +} PROPERLY_ALIGNED_TYPE; + +typedef struct string_list { + struct string_list *next; + unsigned int flags; + char d[1]; +} *STRLIST; + +#endif /*G10_TYPES_H*/ diff --git a/src/libs/resiprocate/contrib/GeoIP/ltmain.sh b/src/libs/resiprocate/contrib/GeoIP/ltmain.sh new file mode 100644 index 00000000..7ed280bc --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/ltmain.sh @@ -0,0 +1,8413 @@ +# Generated from ltmain.m4sh. + +# ltmain.sh (GNU libtool) 2.2.6b +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print informational messages (default) +# --version print version information +# -h, --help print short or long help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.2.6b Debian-2.2.6b-2ubuntu1 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION="2.2.6b Debian-2.2.6b-2ubuntu1" +TIMESTAMP="" +package_revision=1.3017 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# NLS nuisances: We save the old values to restore during execute mode. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done + +$lt_unset CDPATH + + + + + +: ${CP="cp -f"} +: ${ECHO="echo"} +: ${EGREP="/bin/grep -E"} +: ${FGREP="/bin/grep -F"} +: ${GREP="/bin/grep"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="/bin/sed"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + +# Generated shell functions inserted here. + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +# In the unlikely event $progname began with a '-', it would play havoc with +# func_echo (imagine progname=-n), so we prepend ./ in that case: +func_dirname_and_basename "$progpath" +progname=$func_basename_result +case $progname in + -*) progname=./$progname ;; +esac + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=: + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname${mode+: }$mode: $*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` + done + my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "X$my_tmpdir" | $Xsed +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "X$1" | $Xsed \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + + + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $SED -n '/^# Usage:/,/# -h/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + $ECHO + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help +# Echo long help message to standard output and exit. +func_help () +{ + $SED -n '/^# Usage:/,/# Report bugs to/ { + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + p + }' < "$progpath" + exit $? +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + func_error "missing argument for $1" + exit_cmd=exit +} + +exit_cmd=: + + + + + +# Check that we have a working $ECHO. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell, and then maybe $ECHO will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# Parse options once, thoroughly. This comes as soon as possible in +# the script to make things like `libtool --version' happen quickly. +{ + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Parse non-mode specific arguments: + while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --config) func_config ;; + + --debug) preserve_args="$preserve_args $opt" + func_echo "enabling shell trace mode" + opt_debug='set -x' + $opt_debug + ;; + + -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break + execute_dlfiles="$execute_dlfiles $1" + shift + ;; + + --dry-run | -n) opt_dry_run=: ;; + --features) func_features ;; + --finish) mode="finish" ;; + + --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break + case $1 in + # Valid mode arguments: + clean) ;; + compile) ;; + execute) ;; + finish) ;; + install) ;; + link) ;; + relink) ;; + uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; + esac + + mode="$1" + shift + ;; + + --preserve-dup-deps) + opt_duplicate_deps=: ;; + + --quiet|--silent) preserve_args="$preserve_args $opt" + opt_silent=: + ;; + + --verbose| -v) preserve_args="$preserve_args $opt" + opt_silent=false + ;; + + --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break + preserve_args="$preserve_args $opt $1" + func_enable_tag "$1" # tagname is set here + shift + ;; + + # Separate optargs to long options: + -dlopen=*|--mode=*|--tag=*) + func_opt_split "$opt" + set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} + shift + ;; + + -\?|-h) func_usage ;; + --help) opt_help=: ;; + --version) func_version ;; + + -*) func_fatal_help "unrecognized option \`$opt'" ;; + + *) nonopt="$opt" + break + ;; + esac + done + + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_duplicate_deps + ;; + esac + + # Having warned about all mis-specified options, bail out if + # anything was wrong. + $exit_cmd $EXIT_FAILURE +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +## ----------- ## +## Main. ## +## ----------- ## + +$opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + test -z "$mode" && func_fatal_error "error: you must specify a MODE." + + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$mode' for more information." +} + + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_ltwrapper_scriptname_result="" + if func_ltwrapper_executable_p "$1"; then + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" + fi +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + case "$@ " in + " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T <?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + removelist="$removelist $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + removelist="$removelist $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + command="$command -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { +test "$mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$mode'" + ;; + esac + + $ECHO + $ECHO "Try \`$progname --help' for more information about other modes." + + exit $? +} + + # Now that we've collected a possible --mode arg, show help if necessary + $opt_help && func_mode_help + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_quote_for_eval "$file" + args="$args $func_quote_for_eval_result" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + $ECHO "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + $ECHO "X----------------------------------------------------------------------" | $Xsed + $ECHO "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + $ECHO + $ECHO "If you ever happen to want to link against installed libraries" + $ECHO "in a given directory, LIBDIR, you must either use libtool, and" + $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'" + $ECHO "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable" + $ECHO " during execution" + fi + if test -n "$runpath_var"; then + $ECHO " - add LIBDIR to the \`$runpath_var' environment variable" + $ECHO " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $ECHO + + $ECHO "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual" + $ECHO "pages." + ;; + *) + $ECHO "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + $ECHO "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS +} + +test "$mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $ECHO "X$nonopt" | $GREP shtool >/dev/null; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + install_prog="$install_prog$func_quote_for_eval_result" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + install_prog="$install_prog $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_verbose "extracting global C symbols from \`$progfile'" + $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + $ECHO >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +" + case $host in + *cygwin* | *mingw* | *cegcc* ) + $ECHO >> "$output_objdir/$my_dlsyms" "\ +/* DATA imports from DLLs on WIN32 con't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs. */" + lt_dlsym_const= ;; + *osf5*) + echo >> "$output_objdir/$my_dlsyms" "\ +/* This system does not cope well with relocations in const data */" + lt_dlsym_const= ;; + *) + lt_dlsym_const=const ;; + esac + + $ECHO >> "$output_objdir/$my_dlsyms" "\ +extern $lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +$lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + $ECHO >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) symtab_cflags="$symtab_cflags $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + + +# func_emit_wrapper_part1 [arg=no] +# +# Emit the first part of a libtool wrapper script on stdout. +# For more information, see the description associated with +# func_emit_wrapper(), below. +func_emit_wrapper_part1 () +{ + func_emit_wrapper_part1_arg1=no + if test -n "$1" ; then + func_emit_wrapper_part1_arg1=$1 + fi + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + ECHO=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$ECHO works! + : + else + # Restart under the correct shell, and then maybe \$ECHO will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $ECHO "\ + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done +" +} +# end: func_emit_wrapper_part1 + +# func_emit_wrapper_part2 [arg=no] +# +# Emit the second part of a libtool wrapper script on stdout. +# For more information, see the description associated with +# func_emit_wrapper(), below. +func_emit_wrapper_part2 () +{ + func_emit_wrapper_part2_arg1=no + if test -n "$1" ; then + func_emit_wrapper_part2_arg1=$1 + fi + + $ECHO "\ + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} +# end: func_emit_wrapper_part2 + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=no + if test -n "$1" ; then + func_emit_wrapper_arg1=$1 + fi + + # split this up so that func_emit_cwrapperexe_src + # can call each part independently. + func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" + func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" +} + + +# func_to_host_path arg +# +# Convert paths to host format when used with build tools. +# Intended for use with "native" mingw (where libtool itself +# is running under the msys shell), or in the following cross- +# build environments: +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# where wine is equipped with the `winepath' executable. +# In the native mingw case, the (msys) shell automatically +# converts paths for any non-msys applications it launches, +# but that facility isn't available from inside the cwrapper. +# Similar accommodations are necessary for $host mingw and +# $build cygwin. Calling this function does no harm for other +# $host/$build combinations not listed above. +# +# ARG is the path (on $build) that should be converted to +# the proper representation for $host. The result is stored +# in $func_to_host_path_result. +func_to_host_path () +{ + func_to_host_path_result="$1" + if test -n "$1" ; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + case $build in + *mingw* ) # actually, msys + # awkward: cmd appends spaces to result + lt_sed_strip_trailing_spaces="s/[ ]*\$//" + func_to_host_path_tmp1=`( cmd //c echo "$1" |\ + $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_path_tmp1=`cygpath -w "$1"` + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # Unfortunately, winepath does not exit with a non-zero + # error code, so we are forced to check the contents of + # stdout. On the other hand, if the command is not + # found, the shell will set an exit code of 127 and print + # *an error message* to stdout. So we must check for both + # error code of zero AND non-empty stdout, which explains + # the odd construction: + func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` + if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + else + # Allow warning below. + func_to_host_path_result="" + fi + ;; + esac + if test -z "$func_to_host_path_result" ; then + func_error "Could not determine host path corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_path_result="$1" + fi + ;; + esac + fi +} +# end: func_to_host_path + +# func_to_host_pathlist arg +# +# Convert pathlists to host format when used with build tools. +# See func_to_host_path(), above. This function supports the +# following $build/$host combinations (but does no harm for +# combinations not listed here): +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# +# Path separators are also converted from $build format to +# $host format. If ARG begins or ends with a path separator +# character, it is preserved (but converted to $host format) +# on output. +# +# ARG is a pathlist (on $build) that should be converted to +# the proper representation on $host. The result is stored +# in $func_to_host_pathlist_result. +func_to_host_pathlist () +{ + func_to_host_pathlist_result="$1" + if test -n "$1" ; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_to_host_pathlist_tmp2="$1" + # Once set for this call, this variable should not be + # reassigned. It is used in tha fallback case. + func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e 's|^:*||' -e 's|:*$||'` + case $build in + *mingw* ) # Actually, msys. + # Awkward: cmd appends spaces to result. + lt_sed_strip_trailing_spaces="s/[ ]*\$//" + func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # unfortunately, winepath doesn't convert pathlists + func_to_host_pathlist_result="" + func_to_host_pathlist_oldIFS=$IFS + IFS=: + for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do + IFS=$func_to_host_pathlist_oldIFS + if test -n "$func_to_host_pathlist_f" ; then + func_to_host_path "$func_to_host_pathlist_f" + if test -n "$func_to_host_path_result" ; then + if test -z "$func_to_host_pathlist_result" ; then + func_to_host_pathlist_result="$func_to_host_path_result" + else + func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" + fi + fi + fi + IFS=: + done + IFS=$func_to_host_pathlist_oldIFS + ;; + esac + if test -z "$func_to_host_pathlist_result" ; then + func_error "Could not determine the host path(s) corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This may break if $1 contains DOS-style drive + # specifications. The fix is not to complicate the expression + # below, but for the user to provide a working wine installation + # with winepath so that path translation in the cross-to-mingw + # case works properly. + lt_replace_pathsep_nix_to_dos="s|:|;|g" + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_replace_pathsep_nix_to_dos"` + fi + # Now, add the leading and trailing path separators back + case "$1" in + :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" + ;; + esac + case "$1" in + *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" + ;; + esac + ;; + esac + fi +} +# end: func_to_host_pathlist + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +# define setmode _setmode +#else +# include +# include +# ifdef __CYGWIN__ +# include +# define HAVE_SETENV +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +#ifdef _MSC_VER +# define S_IXUSR _S_IEXEC +# define stat _stat +# ifndef _INTPTR_T_DEFINED +# define intptr_t int +# endif +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifdef __CYGWIN__ +# define FOPEN_WB "wb" +#endif + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#undef LTWRAPPER_DEBUGPRINTF +#if defined DEBUGWRAPPER +# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args +static void +ltwrapper_debugprintf (const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); +} +#else +# define LTWRAPPER_DEBUGPRINTF(args) +#endif + +const char *program_name = NULL; + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_fatal (const char *message, ...); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_opt_process_env_set (const char *arg); +void lt_opt_process_env_prepend (const char *arg); +void lt_opt_process_env_append (const char *arg); +int lt_split_name_value (const char *arg, char** name, char** value); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); + +static const char *script_text_part1 = +EOF + + func_emit_wrapper_part1 yes | + $SED -e 's/\([\\"]\)/\\\1/g' \ + -e 's/^/ "/' -e 's/$/\\n"/' + echo ";" + cat <"))); + for (i = 0; i < newargc; i++) + { + LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); + } + +EOF + + case $host_os in + mingw*) + cat <<"EOF" + /* execv doesn't actually work on mingw as expected on unix */ + rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); + if (rval == -1) + { + /* failed to start process */ + LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno)); + return 127; + } + return rval; +EOF + ;; + *) + cat <<"EOF" + execv (lt_argv_zero, newargz); + return rval; /* =127, but avoids unused variable warning */ +EOF + ;; + esac + + cat <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void *p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), + string) : NULL; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char) name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable (const char *path) +{ + struct stat st; + + LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", + path ? (*path ? path : "EMPTY!") : "NULL!")); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", + path ? (*path ? path : "EMPTY!") : "NULL!")); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", + wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n", + tmp_pathspec)); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + char *errstr = strerror (errno); + lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal ("Could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} + +void +lt_setenv (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", + (name ? name : ""), + (value ? value : ""))); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +int +lt_split_name_value (const char *arg, char** name, char** value) +{ + const char *p; + int len; + if (!arg || !*arg) + return 1; + + p = strchr (arg, (int)'='); + + if (!p) + return 1; + + *value = xstrdup (++p); + + len = strlen (arg) - strlen (*value); + *name = XMALLOC (char, len); + strncpy (*name, arg, len-1); + (*name)[len - 1] = '\0'; + + return 0; +} + +void +lt_opt_process_env_set (const char *arg) +{ + char *name = NULL; + char *value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); + } + + lt_setenv (name, value); + XFREE (name); + XFREE (value); +} + +void +lt_opt_process_env_prepend (const char *arg) +{ + char *name = NULL; + char *value = NULL; + char *new_value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); + } + + new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + XFREE (name); + XFREE (value); +} + +void +lt_opt_process_env_append (const char *arg) +{ + char *name = NULL; + char *value = NULL; + char *new_value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); + } + + new_value = lt_extend_str (getenv (name), value, 1); + lt_setenv (name, new_value); + XFREE (new_value); + XFREE (name); + XFREE (value); +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + (name ? name : ""), + (value ? value : ""))); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + (name ? name : ""), + (value ? value : ""))); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + + +EOF +} +# end: func_emit_cwrapperexe_src + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) deplibs="$deplibs $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + weak_libs="$weak_libs $arg" + prev= + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname '-L' '' "$arg" + dir=$func_stripname_result + if test -z "$dir"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" + linker_flags="$linker_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -F/path gives path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_duplicate_deps ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + case $lib in + *.la) func_source "$lib" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` + case " $weak_libs " in + *" $deplib_base "*) ;; + *) deplibs="$deplibs $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + dir=$func_stripname_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $ECHO + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because the file extensions .$libext of this argument makes me believe" + $ECHO "*** that it is just a static archive that I should not use here." + else + $ECHO + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) temp_rpath="$temp_rpath$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + notinst_deplibs="$notinst_deplibs $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + $ECHO + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $ECHO + $ECHO "*** And there doesn't seem to be a static archive available" + $ECHO "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $ECHO + $ECHO "*** Warning: This system can not link to static lib archive $lib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $ECHO "*** But as you try to build a module library, libtool will still create " + $ECHO "*** a static module, that should work as long as the dlopening application" + $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $ECHO + $ECHO "*** However, this would only work if libtool was able to extract symbol" + $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" + $ECHO "*** not find such a program. So, this module is probably useless." + $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_dirname "$deplib" "" "." + dir="$func_dirname_result" + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + $ECHO + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type \`$version_type'" + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + libobjs="$libobjs $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` + # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` + # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $ECHO + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $ECHO + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ + -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` + done + fi + if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | + $GREP . >/dev/null; then + $ECHO + if test "X$deplibs_check_method" = "Xnone"; then + $ECHO "*** Warning: inter-library dependencies are not supported in this platform." + else + $ECHO "*** Warning: inter-library dependencies are not known to be supported." + fi + $ECHO "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $ECHO + $ECHO "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + $ECHO "*** a static module, that should work as long as the dlopening" + $ECHO "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $ECHO + $ECHO "*** However, this would only work if libtool was able to extract symbol" + $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" + $ECHO "*** not find such a program. So, this module is probably useless." + $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $ECHO "*** The inter-library dependencies that have been dropped here will be" + $ECHO "*** automatically added whenever a program is linked with this library" + $ECHO "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $ECHO + $ECHO "*** Since this library must not contain undefined symbols," + $ECHO "*** because either the platform does not support them or" + $ECHO "*** it was explicitly requested with -no-undefined," + $ECHO "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + delfiles="$delfiles $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + func_len " $cmd" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$ECHO "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + $ECHO 'INPUT (' > $output + for obj in $save_libobjs + do + $ECHO "$obj" >> $output + done + $ECHO ')' >> $output + delfiles="$delfiles $output" + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + $ECHO "$obj" >> $output + done + delfiles="$delfiles $output" + output=$firstobj\"$file_list_spec$output\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + delfiles="$delfiles $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *cegcc) + # Disable wrappers for cegcc, we are cross compiling anyway. + wrappers_required=no + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $ECHO for shipping. + if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + oldobjs="$oldobjs $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $ECHO "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlfiles="$newdlfiles $libdir/$name" + ;; + *) newdlfiles="$newdlfiles $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlprefiles="$newdlprefiles $libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$mode" = link || test "$mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) RM="$RM $arg"; rmforce=yes ;; + -*) RM="$RM $arg" ;; + *) files="$files $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + rmfiles="$rmfiles $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$mode" = uninstall || test "$mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/src/libs/resiprocate/contrib/GeoIP/man/Makefile.am b/src/libs/resiprocate/contrib/GeoIP/man/Makefile.am new file mode 100644 index 00000000..0db02e3c --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/man/Makefile.am @@ -0,0 +1,29 @@ +man_MANS = geoipupdate.1 geoiplookup6.1 geoiplookup.1 + +EXTRA_DIST = geoiplookup6.1.in geoiplookup.1.in geoipupdate.1.in + + +edit = sed \ + -e 's|DATADIR|$(pkgdatadir)|g' \ + -e 's|CONF_DIR|$(sysconfdir)|g' + +geoipupdate.1 geoiplookup.1 geoiplookup6.1: Makefile + rm -f $@ $@.tmp + $(edit) '$(srcdir)/$@.in' >$@.tmp + mv $@.tmp $@ + +geoipupdate.1: geoipupdate.1.in +geoiplookup.1: geoiplookup.1.in +geoiplookup6.1: geoiplookup6.1.in + +CLEANFILES = geoiplookup6.1 geoipupdate.1 geoiplookup.1 + +UPDATE_MAN = $(mandir)/man1/geoipupdate.1 +LOOKUP_MAN = $(mandir)/man1/geoiplookup.1 +LOOKUP6_MAN = $(mandir)/man1/geoiplookup6.1 + +install-data-hook: + cat geoipupdate.1 | sed s,DATADIR,$(pkgdatadir), | sed s,CONF_DIR,$(sysconfdir), > $(DESTDIR)$(UPDATE_MAN) + cat geoiplookup.1 | sed s,DATADIR,$(pkgdatadir), > $(DESTDIR)$(LOOKUP_MAN) + cat geoiplookup6.1 | sed s,DATADIR,$(pkgdatadir), > $(DESTDIR)$(LOOKUP6_MAN) + diff --git a/src/libs/resiprocate/contrib/GeoIP/man/Makefile.in b/src/libs/resiprocate/contrib/GeoIP/man/Makefile.in new file mode 100644 index 00000000..0e8b1436 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/man/Makefile.in @@ -0,0 +1,455 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = man +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +man1dir = $(mandir)/man1 +am__installdirs = "$(DESTDIR)$(man1dir)" +NROFF = nroff +MANS = $(man_MANS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEOIP_VERSION_INFO = @GEOIP_VERSION_INFO@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +man_MANS = geoipupdate.1 geoiplookup6.1 geoiplookup.1 +EXTRA_DIST = geoiplookup6.1.in geoiplookup.1.in geoipupdate.1.in +edit = sed \ + -e 's|DATADIR|$(pkgdatadir)|g' \ + -e 's|CONF_DIR|$(sysconfdir)|g' + +CLEANFILES = geoiplookup6.1 geoipupdate.1 geoiplookup.1 +UPDATE_MAN = $(mandir)/man1/geoipupdate.1 +LOOKUP_MAN = $(mandir)/man1/geoiplookup.1 +LOOKUP6_MAN = $(mandir)/man1/geoiplookup6.1 +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu man/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" + @list=''; test -n "$(man1dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically \`make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(MANS) +installdirs: + for dir in "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: install-am install-data-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-data-hook install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-man1 install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am uninstall uninstall-am uninstall-man uninstall-man1 + + +geoipupdate.1 geoiplookup.1 geoiplookup6.1: Makefile + rm -f $@ $@.tmp + $(edit) '$(srcdir)/$@.in' >$@.tmp + mv $@.tmp $@ + +geoipupdate.1: geoipupdate.1.in +geoiplookup.1: geoiplookup.1.in +geoiplookup6.1: geoiplookup6.1.in + +install-data-hook: + cat geoipupdate.1 | sed s,DATADIR,$(pkgdatadir), | sed s,CONF_DIR,$(sysconfdir), > $(DESTDIR)$(UPDATE_MAN) + cat geoiplookup.1 | sed s,DATADIR,$(pkgdatadir), > $(DESTDIR)$(LOOKUP_MAN) + cat geoiplookup6.1 | sed s,DATADIR,$(pkgdatadir), > $(DESTDIR)$(LOOKUP6_MAN) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/resiprocate/contrib/GeoIP/man/geoiplookup.1.in b/src/libs/resiprocate/contrib/GeoIP/man/geoiplookup.1.in new file mode 100644 index 00000000..ede2e518 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/man/geoiplookup.1.in @@ -0,0 +1,37 @@ +.TH GEOIPLOOKUP 1 "2 Jan 2007" +.UC 4 +.SH NAME +geoiplookup \- look up country using IP Address or hostname +.SH SYNOPSIS +geoiplookup [\-d directory] [\-f filename] [\-v] +.SH DESCRIPTION +geoiplookup uses the GeoIP library and database to find the Country +that an IP address or hostname originates from. +.PP +For example +.PP +.I geoiplookup 80.60.233.195 +.PP +will find the Country that 80.60.233.195 originates from, in the following format: +.PP +.I NL, Netherlands +.PP +.SH OPTIONS +.IP "\-f" +Specify a custom path to a single GeoIP datafile. +.IP "\-d" +Specify a custom directory containing GeoIP datafile(s). By default geoiplookup looks in DATADIR +.IP "\-v" +Lists the date and build number for the GeoIP datafile(s). +.SH AUTHOR +Written by T.J. Mather +.SH "REPORTING BUGS" +Report bugs to +.SH COPYRIGHT +Copyright 2006 MaxMind LLC + +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +.SH "SEE ALSO" +geoipupdate(1), nslookup(1). diff --git a/src/libs/resiprocate/contrib/GeoIP/man/geoiplookup6.1.in b/src/libs/resiprocate/contrib/GeoIP/man/geoiplookup6.1.in new file mode 100644 index 00000000..2a49ee1a --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/man/geoiplookup6.1.in @@ -0,0 +1,42 @@ +.TH GEOIPLOOKUP6 1 "28 Oct 2008" +.UC 4 +.SH NAME +geouplookup6 \- look up country using IP Address or hostname +.SH SYNOPSIS +geouplookup6 [\-d directory] [\-f filename] [\-v] +.SH DESCRIPTION +geouplookup6 uses the GeoIP library and database to find the Country +that an IP address or hostname originates from. You must install a database suitable for geoiplookup6. IE: GeoIPv6.dat +.PP +For example: +.PP +.I geouplookup6 2001:4860:0:1001::68 +.PP +.I geoiplookup6 ipv6.google.com +.PP +will find the Country that 2001:4860:0:1001::68 originates from, in the following format: +.PP +.I US, United States +.PP +.PP Please notice, that names must resolve to a ipv6 address. For example +.PP geoiplookup6 www.maxmind.com does not work, since there is no ipv6 +.PP DNS entry +.SH OPTIONS +.IP "\-f" +Specify a custom path to a single GeoIP datafile. +.IP "\-d" +Specify a custom directory containing GeoIP datafile(s). By default geouplookup6 looks in DATADIR +.IP "\-v" +Lists the date and build number for the GeoIP datafile(s). +.SH AUTHOR +Written by T.J. Mather +.SH "REPORTING BUGS" +Report bugs to +.SH COPYRIGHT +Copyright 2008 MaxMind LLC + +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +.SH "SEE ALSO" +geoipupdate(1), nslookup(1). diff --git a/src/libs/resiprocate/contrib/GeoIP/man/geoipupdate.1.in b/src/libs/resiprocate/contrib/GeoIP/man/geoipupdate.1.in new file mode 100644 index 00000000..c0f9a854 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/man/geoipupdate.1.in @@ -0,0 +1,68 @@ +.TH GEOIPUPDATE 1 "5 Oct 2010" +.UC 4 +.SH NAME +geoipupdate \- a program for updating the MaxMind GeoIP databases +.SH SYNOPSIS +geoipupdate [\-v] [\-f licensefile] +.SH DESCRIPTION +geoipupdate automatically updates the GeoIP database for GeoIP +subscribers. It connects to the MaxMind GeoIP Update server +and checks for an updated database. If it finds an updated +database, then it downloads it, uncompresses it, and installs it. +If you are running a firewall, it requires that the DNS and +HTTP (80) ports be open. +.PP +For example +.PP +.I geoipupdate \-v +.PP +Performs the update in verbose mode. +.PP +.SH OPTIONS +.IP "\-v" +Verbose mode, prints out the steps that geoipupdate takes. +.IP "\-d" +Specify a custom directory target to install the GeoIP datafile(s). By default geoipupdate installs to DATADIR +.IP "\-f" +Specifies the configuration file that contains the license key. +Defaults to CONF_DIR/GeoIP.conf +.SH USAGE +Typically you'll want to write a weekly crontab that will run geoipupdate. +Below is a sample crontab that runs geoipupdate on each Wednesday at noon: +.PP +.RS +# top of crontab +.PP +MAILTO=your@email.com +.PP +0 12 * * 3 BIN_DIR/geoipupdate +.PP +# end of crontab +.RE +To use with a proxy server, set the http_proxy environment variable. +E.g. +.RS +export http_proxy="http://proxy-hostname:port" +.RE +.SH RETURN CODES +geoipupdate returns 0 on success, 1 on error. +.SH FILES +.PP +.I CONF_DIR/GeoIP.conf +.PP +Configuration file for GeoIP, should contain license key. +.SH AUTHOR +Written by T.J. Mather +.SH "REPORTING BUGS" +Report bugs to +.SH COPYRIGHT +Copyright 2011 MaxMind LLC + +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +.SH "SEE ALSO" +Visit to +sign up for a GeoIP subscription. +.PP +geoiplookup(1), crontab(5) diff --git a/src/libs/resiprocate/contrib/GeoIP/missing b/src/libs/resiprocate/contrib/GeoIP/missing new file mode 100644 index 00000000..28055d2a --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/missing @@ -0,0 +1,376 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# 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 2, 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 . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + tar*) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar*) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/src/libs/resiprocate/contrib/GeoIP/test/Makefile.am b/src/libs/resiprocate/contrib/GeoIP/test/Makefile.am new file mode 100644 index 00000000..fffcbed3 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/Makefile.am @@ -0,0 +1,37 @@ +INCLUDES = \ + -I$(top_srcdir)/libGeoIP \ + -Wall + +check_PROGRAMS = test-geoip + +noinst_PROGRAMS = benchmark test-geoip-region test-geoip-city test-geoip-org test-geoip-asnum test-geoip-isp test-geoip-netspeed + +EXTRA_PROGRAMS = benchmark \ + test-geoip-region \ + test-geoip-city \ + test-geoip-org \ + test-geoip-asnum \ + test-geoip-isp \ + test-geoip-netspeed + +LDADD = $(top_builddir)/libGeoIP/libGeoIP.la +AM_CPPFLAGS = -DSRCDIR=\"$(top_srcdir)\" + +test_geoip_SOURCES = test-geoip.c + +test_geoip_region_SOURCES = test-geoip-region.c + +test_geoip_org_SOURCES = test-geoip-org.c + +test_geoip_isp_SOURCES = test-geoip-isp.c + +test_geoip_asnum_SOURCES = test-geoip-asnum.c + +test_geoip_netspeed_SOURCES = test-geoip-netspeed.c + +test_geoip_city_SOURCES = test-geoip-city.c + +benchmark_SOURCES = benchmark.c + +EXTRA_DIST = Makefile.vc city_test.txt country_test.txt country_test2.txt country_test_name.txt region_test.txt +TESTS = test-geoip diff --git a/src/libs/resiprocate/contrib/GeoIP/test/Makefile.in b/src/libs/resiprocate/contrib/GeoIP/test/Makefile.in new file mode 100644 index 00000000..6d1282bd --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/Makefile.in @@ -0,0 +1,657 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test-geoip$(EXEEXT) +noinst_PROGRAMS = benchmark$(EXEEXT) test-geoip-region$(EXEEXT) \ + test-geoip-city$(EXEEXT) test-geoip-org$(EXEEXT) \ + test-geoip-asnum$(EXEEXT) test-geoip-isp$(EXEEXT) \ + test-geoip-netspeed$(EXEEXT) +EXTRA_PROGRAMS = benchmark$(EXEEXT) test-geoip-region$(EXEEXT) \ + test-geoip-city$(EXEEXT) test-geoip-org$(EXEEXT) \ + test-geoip-asnum$(EXEEXT) test-geoip-isp$(EXEEXT) \ + test-geoip-netspeed$(EXEEXT) +TESTS = test-geoip$(EXEEXT) +subdir = test +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_benchmark_OBJECTS = benchmark.$(OBJEXT) +benchmark_OBJECTS = $(am_benchmark_OBJECTS) +benchmark_LDADD = $(LDADD) +benchmark_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +am_test_geoip_OBJECTS = test-geoip.$(OBJEXT) +test_geoip_OBJECTS = $(am_test_geoip_OBJECTS) +test_geoip_LDADD = $(LDADD) +test_geoip_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +am_test_geoip_asnum_OBJECTS = test-geoip-asnum.$(OBJEXT) +test_geoip_asnum_OBJECTS = $(am_test_geoip_asnum_OBJECTS) +test_geoip_asnum_LDADD = $(LDADD) +test_geoip_asnum_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +am_test_geoip_city_OBJECTS = test-geoip-city.$(OBJEXT) +test_geoip_city_OBJECTS = $(am_test_geoip_city_OBJECTS) +test_geoip_city_LDADD = $(LDADD) +test_geoip_city_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +am_test_geoip_isp_OBJECTS = test-geoip-isp.$(OBJEXT) +test_geoip_isp_OBJECTS = $(am_test_geoip_isp_OBJECTS) +test_geoip_isp_LDADD = $(LDADD) +test_geoip_isp_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +am_test_geoip_netspeed_OBJECTS = test-geoip-netspeed.$(OBJEXT) +test_geoip_netspeed_OBJECTS = $(am_test_geoip_netspeed_OBJECTS) +test_geoip_netspeed_LDADD = $(LDADD) +test_geoip_netspeed_DEPENDENCIES = \ + $(top_builddir)/libGeoIP/libGeoIP.la +am_test_geoip_org_OBJECTS = test-geoip-org.$(OBJEXT) +test_geoip_org_OBJECTS = $(am_test_geoip_org_OBJECTS) +test_geoip_org_LDADD = $(LDADD) +test_geoip_org_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +am_test_geoip_region_OBJECTS = test-geoip-region.$(OBJEXT) +test_geoip_region_OBJECTS = $(am_test_geoip_region_OBJECTS) +test_geoip_region_LDADD = $(LDADD) +test_geoip_region_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(benchmark_SOURCES) $(test_geoip_SOURCES) \ + $(test_geoip_asnum_SOURCES) $(test_geoip_city_SOURCES) \ + $(test_geoip_isp_SOURCES) $(test_geoip_netspeed_SOURCES) \ + $(test_geoip_org_SOURCES) $(test_geoip_region_SOURCES) +DIST_SOURCES = $(benchmark_SOURCES) $(test_geoip_SOURCES) \ + $(test_geoip_asnum_SOURCES) $(test_geoip_city_SOURCES) \ + $(test_geoip_isp_SOURCES) $(test_geoip_netspeed_SOURCES) \ + $(test_geoip_org_SOURCES) $(test_geoip_region_SOURCES) +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEOIP_VERSION_INFO = @GEOIP_VERSION_INFO@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = \ + -I$(top_srcdir)/libGeoIP \ + -Wall + +LDADD = $(top_builddir)/libGeoIP/libGeoIP.la +AM_CPPFLAGS = -DSRCDIR=\"$(top_srcdir)\" +test_geoip_SOURCES = test-geoip.c +test_geoip_region_SOURCES = test-geoip-region.c +test_geoip_org_SOURCES = test-geoip-org.c +test_geoip_isp_SOURCES = test-geoip-isp.c +test_geoip_asnum_SOURCES = test-geoip-asnum.c +test_geoip_netspeed_SOURCES = test-geoip-netspeed.c +test_geoip_city_SOURCES = test-geoip-city.c +benchmark_SOURCES = benchmark.c +EXTRA_DIST = Makefile.vc city_test.txt country_test.txt country_test2.txt country_test_name.txt region_test.txt +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu test/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +benchmark$(EXEEXT): $(benchmark_OBJECTS) $(benchmark_DEPENDENCIES) + @rm -f benchmark$(EXEEXT) + $(LINK) $(benchmark_OBJECTS) $(benchmark_LDADD) $(LIBS) +test-geoip$(EXEEXT): $(test_geoip_OBJECTS) $(test_geoip_DEPENDENCIES) + @rm -f test-geoip$(EXEEXT) + $(LINK) $(test_geoip_OBJECTS) $(test_geoip_LDADD) $(LIBS) +test-geoip-asnum$(EXEEXT): $(test_geoip_asnum_OBJECTS) $(test_geoip_asnum_DEPENDENCIES) + @rm -f test-geoip-asnum$(EXEEXT) + $(LINK) $(test_geoip_asnum_OBJECTS) $(test_geoip_asnum_LDADD) $(LIBS) +test-geoip-city$(EXEEXT): $(test_geoip_city_OBJECTS) $(test_geoip_city_DEPENDENCIES) + @rm -f test-geoip-city$(EXEEXT) + $(LINK) $(test_geoip_city_OBJECTS) $(test_geoip_city_LDADD) $(LIBS) +test-geoip-isp$(EXEEXT): $(test_geoip_isp_OBJECTS) $(test_geoip_isp_DEPENDENCIES) + @rm -f test-geoip-isp$(EXEEXT) + $(LINK) $(test_geoip_isp_OBJECTS) $(test_geoip_isp_LDADD) $(LIBS) +test-geoip-netspeed$(EXEEXT): $(test_geoip_netspeed_OBJECTS) $(test_geoip_netspeed_DEPENDENCIES) + @rm -f test-geoip-netspeed$(EXEEXT) + $(LINK) $(test_geoip_netspeed_OBJECTS) $(test_geoip_netspeed_LDADD) $(LIBS) +test-geoip-org$(EXEEXT): $(test_geoip_org_OBJECTS) $(test_geoip_org_DEPENDENCIES) + @rm -f test-geoip-org$(EXEEXT) + $(LINK) $(test_geoip_org_OBJECTS) $(test_geoip_org_LDADD) $(LIBS) +test-geoip-region$(EXEEXT): $(test_geoip_region_OBJECTS) $(test_geoip_region_DEPENDENCIES) + @rm -f test-geoip-region$(EXEEXT) + $(LINK) $(test_geoip_region_OBJECTS) $(test_geoip_region_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/benchmark.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-geoip-asnum.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-geoip-city.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-geoip-isp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-geoip-netspeed.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-geoip-org.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-geoip-region.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-geoip.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes$$std"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/resiprocate/contrib/GeoIP/test/Makefile.vc b/src/libs/resiprocate/contrib/GeoIP/test/Makefile.vc new file mode 100644 index 00000000..eaa23763 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/Makefile.vc @@ -0,0 +1,29 @@ +#NMAKE makefile for Windows developers. +#Produces a static library (GeoIP.lib). + +COMPILER=cl + +LINK = link -nologo + +CFLAGS=-DWIN32 -MD -nologo + +GEOIPINC = -I..\libGeoIP + +CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) + +GEOIPLIB = ..\libGeoIP\GeoIP.lib + +EXTRA_LIBS= advapi32.lib wsock32.lib + +AR=lib + +TEST: benchmark.exe test-geoip.exe + +benchmark.exe: benchmark.c + $(CC1) -c benchmark.c + $(LINK) benchmark.obj $(GEOIPLIB) + +test-geoip.exe: test-geoip.c + $(CC1) -c test-geoip.c + $(LINK) test-geoip.obj $(GEOIPLIB) + diff --git a/src/libs/resiprocate/contrib/GeoIP/test/benchmark.c b/src/libs/resiprocate/contrib/GeoIP/test/benchmark.c new file mode 100644 index 00000000..3d2346f2 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/benchmark.c @@ -0,0 +1,135 @@ +#include +#include +#include +#if !defined(_WIN32) +#include +#endif /* !defined(_WIN32) */ + +char *ipstring[4] = {"24.24.24.24","80.24.24.80", +"200.24.24.40","68.24.24.46"}; +int numipstrings = 4; + +#if !defined(_WIN32) +struct timeval timer_t1; +struct timeval timer_t2; +#else /* !defined(_WIN32) */ +FILETIME timer_t1; /* 100 ns */ +FILETIME timer_t2; +#endif /* !defined(_WIN32) */ + +#if !defined(_WIN32) +void timerstart() { + gettimeofday(&timer_t1,NULL); +} +double timerstop() { + int a1 = 0; + int a2 = 0; + double r = 0; + gettimeofday(&timer_t2,NULL); + a1 = timer_t2.tv_sec - timer_t1.tv_sec; + a2 = timer_t2.tv_usec - timer_t1.tv_usec; + if (a1 < 0) { + a1 = a1 - 1; + a2 = a2 + 1000000; + } + r = (((double) a1) + (((double) a2) / 1000000)); + return r; +} +#else /* !defined(_WIN32) */ +void timerstart() { + GetSystemTimeAsFileTime(&timer_t1); +} +double timerstop() { + __int64 delta; /* VC6 can't convert an unsigned int64 to to double */ + GetSystemTimeAsFileTime(&timer_t2); + delta = FILETIME_TO_USEC(timer_t2) - FILETIME_TO_USEC(timer_t2); + return delta; +} +#endif /* !defined(_WIN32) */ + +void testgeoipcountry(int flags,const char *msg,int numlookups) { + const char *str = NULL; + double t = 0; + int i4 = 0; + int i2 = 0; + GeoIP *i = NULL; + i = GeoIP_open("/usr/local/share/GeoIP/GeoIP.dat",flags); + if (i == NULL) { + printf("error: GeoIP.dat does not exist\n"); + return; + } + timerstart(); + for (i2 = 0;i2 < numlookups;i2++) { + str = GeoIP_country_name_by_addr(i,ipstring[i4]); + i4 = (i4 + 1) % numipstrings; + } + t = timerstop(); + printf("%s\n", msg); + printf("%d lookups made in %f seconds \n",numlookups,t); + GeoIP_delete(i); +} + +void testgeoipregion(int flags,const char *msg,int numlookups) { + GeoIP *i = NULL; + GeoIPRegion *i3 = NULL; + int i4 = 0; + int i2 = 0; + double t = 0; + i = GeoIP_open("/usr/local/share/GeoIP/GeoIPRegion.dat",flags); + if (i == NULL) { + printf("error: GeoIPRegion.dat does not exist\n"); + return; + } + timerstart(); + for (i2 = 0;i2 < numlookups;i2++) { + i3 = GeoIP_region_by_addr(i,ipstring[i4]); + GeoIPRegion_delete(i3); + i4 = (i4 + 1) % numipstrings; + } + t = timerstop(); + printf("%s\n", msg); + printf("%d lookups made in %f seconds \n",numlookups,t); + GeoIP_delete(i); +} + +void testgeoipcity(int flags,const char *msg,int numlookups) { + GeoIP *i = NULL; + GeoIPRecord * i3 = NULL; + int i4 = 0; + int i2 = 0; + double t = 0; + i = GeoIP_open("/usr/local/share/GeoIP/GeoIPCity.dat",flags); + if (i == NULL) { + printf("error: GeoLiteCity.dat does not exist\n"); + return; + } + timerstart(); + for (i2 = 0;i2 < numlookups;i2++) { + i3 = GeoIP_record_by_addr(i,ipstring[i4]); + GeoIPRecord_delete(i3); + i4 = (i4 + 1) % numipstrings; + } + t = timerstop(); + printf("%s\n", msg); + printf("%d lookups made in %f seconds \n",numlookups,t); + GeoIP_delete(i); +} + +int main(){ + int time = 300*numipstrings; + testgeoipcountry(0,"GeoIP Country",100*time); + testgeoipcountry(GEOIP_CHECK_CACHE,"GeoIP Country with GEOIP_CHECK_CACHE",100*time); + testgeoipcountry(GEOIP_MEMORY_CACHE,"GeoIP Country with GEOIP_MEMORY_CACHE",1000*time); + testgeoipcountry(GEOIP_MEMORY_CACHE | GEOIP_CHECK_CACHE,"GeoIP Country with GEOIP_MEMORY_CACHE and GEOIP_CHECK_CACHE",1000*time); + + testgeoipregion(0,"GeoIP Region",100*time); + testgeoipregion(GEOIP_CHECK_CACHE,"GeoIP Region with GEOIP_CHECK_CACHE",100*time); + testgeoipregion(GEOIP_MEMORY_CACHE,"GeoIP Region with GEOIP_MEMORY_CACHE",1000*time); + testgeoipregion(GEOIP_MEMORY_CACHE | GEOIP_CHECK_CACHE,"GeoIP Region with GEOIP_MEMORY_CACHE and GEOIP_CHECK_CACHE",1000*time); + + testgeoipcity(0,"GeoIP City",50*time); + testgeoipcity(GEOIP_INDEX_CACHE,"GeoIP City with GEOIP_INDEX_CACHE",200*time); + testgeoipcity(GEOIP_INDEX_CACHE | GEOIP_CHECK_CACHE,"GeoIP City with GEOIP_INDEX_CACHE and GEOIP_CHECK_CACHE",200*time); + testgeoipcity(GEOIP_MEMORY_CACHE,"GeoIP City with GEOIP_MEMORY_CACHE",500*time); + return 0; +} diff --git a/src/libs/resiprocate/contrib/GeoIP/test/city_test.txt b/src/libs/resiprocate/contrib/GeoIP/test/city_test.txt new file mode 100644 index 00000000..2ba04acb --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/city_test.txt @@ -0,0 +1,2 @@ +24.24.24.24 # Should return Ithaca, NY, US +80.24.24.24 # Should return Madrid, 29, ES diff --git a/src/libs/resiprocate/contrib/GeoIP/test/country_test.txt b/src/libs/resiprocate/contrib/GeoIP/test/country_test.txt new file mode 100644 index 00000000..11d5fa60 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/country_test.txt @@ -0,0 +1,69 @@ +216.236.135.152 US USA +192.106.51.100 IT ITA +147.251.48.1 CZ CZE +203.174.65.12 JP JPN +212.208.74.140 FR FRA +200.219.192.106 BR BRA +134.102.101.18 DE DEU +193.75.148.28 BE BEL +194.244.83.2 IT ITA +203.15.106.23 AU AUS +196.31.1.1 ZA ZAF +151.28.39.114 IT ITA +151.38.70.94 IT ITA +193.56.4.124 FR FRA +195.142.146.198 TR TUR +211.232.0.0 KR KOR +211.240.0.0 KR KOR +193.194.4.0 MA MAR +139.20.112.104 DE DEU +139.20.112.3 DE DEU +145.236.125.211 HU HUN +149.225.169.61 DE DEU +151.17.191.46 IT ITA +151.24.176.194 IT ITA +151.25.8.136 IT ITA +151.26.146.192 IT ITA +151.26.153.66 IT ITA +151.26.167.71 IT ITA +151.26.35.204 IT ITA +151.26.64.157 IT ITA +151.27.138.182 IT ITA +151.28.39.114 IT ITA +151.29.150.217 IT ITA +151.29.237.39 IT ITA +151.29.73.189 IT ITA +151.30.134.242 IT ITA +151.30.135.85 IT ITA +151.30.168.224 IT ITA +151.35.80.202 IT ITA +151.35.80.240 IT ITA +151.36.191.229 IT ITA +151.38.70.94 IT ITA +151.38.92.126 IT ITA +151.42.100.132 IT ITA +151.42.169.71 IT ITA +193.56.4.124 FR FRA +195.142.146.198 TR TUR +195.142.49.205 TR TUR +202.247.74.18 JP JPN +202.247.74.71 JP JPN +202.247.74.81 JP JPN +202.247.74.88 JP JPN +203.242.239.188 KR KOR +203.174.65.12 JP JPN +212.208.74.140 FR FRA +200.219.192.106 BR BRA +202.53.254.193 ID IDN +12.168.0.0 US USA +12.169.0.0 US USA +12.200.0.0 US USA +203.121.0.8 MY MYS +203.20.231.1 AU AUS +203.87.98.29 AU AUS +203.181.121.150 JP JPN +202.166.127.246 SG SGP +62.188.202.242 GB GBR +12.12.197.23 US USA +12.12.199.3 US USA +12.12.200.79 US USA diff --git a/src/libs/resiprocate/contrib/GeoIP/test/country_test2.txt b/src/libs/resiprocate/contrib/GeoIP/test/country_test2.txt new file mode 100644 index 00000000..362367a9 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/country_test2.txt @@ -0,0 +1,29 @@ +212.118.5.94 JO +64.170.57.29 US +202.7.216.215 AU +212.33.164.149 SA +68.96.110.210 US +213.166.131.168 SA +64.158.191.179 US +24.247.251.23 US +203.199.228.66 IN +195.14.141.225 CY +200.52.94.98 MX +203.197.187.193 IN +203.128.9.170 PK +144.106.240.140 US +195.248.180.102 UA +213.1.0.118 GB +64.255.148.52 US +12.78.124.119 US +212.68.224.183 BE +62.148.73.85 PL +203.146.135.180 TH +209.204.179.145 US +64.123.0.164 US +202.56.198.16 IN +61.0.94.172 IN +62.42.171.190 ES +192.117.245.177 IL +213.123.75.243 GB +80.56.171.62 NL diff --git a/src/libs/resiprocate/contrib/GeoIP/test/country_test_name.txt b/src/libs/resiprocate/contrib/GeoIP/test/country_test_name.txt new file mode 100644 index 00000000..ce714090 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/country_test_name.txt @@ -0,0 +1 @@ +yahoo.com US diff --git a/src/libs/resiprocate/contrib/GeoIP/test/region_test.txt b/src/libs/resiprocate/contrib/GeoIP/test/region_test.txt new file mode 100644 index 00000000..2828a57f --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/region_test.txt @@ -0,0 +1,24 @@ +216.236.135.152 US USA +24.24.24.24 US USA +147.251.48.1 CZ CZE +203.174.65.12 JP JPN +212.208.74.140 FR FRA +200.219.192.106 BR BRA +134.102.101.18 DE DEU +193.75.148.28 BE BEL +194.244.83.2 IT ITA +203.15.106.23 AU AUS +196.31.1.1 ZA ZAF +151.28.39.114 IT ITA +151.38.70.94 IT ITA +193.56.4.124 FR FRA +195.142.146.198 TR TUR +211.232.0.0 KR KOR +211.240.0.0 KR KOR +193.194.4.0 MA MAR +139.20.112.104 DE DEU +139.20.112.3 DE DEU +145.236.125.211 HU HUN +yahoo.com US USA +amazon.com US USA +www.uspto.gov US USA diff --git a/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-asnum.c b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-asnum.c new file mode 100644 index 00000000..d6c3afcd --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-asnum.c @@ -0,0 +1,63 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-asnum.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +static const char * _mk_NA( const char * p ){ + return p ? p : "N/A"; +} + +int main (int argc, char* argv[]) { + FILE *f; + GeoIP * gi; + char * org; + int generate = 0; + char host[50]; + + if (argc == 2) + if (!strcmp(argv[1],"gen")) + generate = 1; + + gi = GeoIP_open("../data/GeoIPASNum.dat", GEOIP_STANDARD); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("asnum_test.txt","r"); + + if (f == NULL) { + fprintf(stderr, "Error opening asnum_test.txt\n"); + exit(1); + } + + while (fscanf(f, "%s", host) != EOF) { + org = GeoIP_org_by_name (gi, (const char *)host); + + if (org != NULL) { + printf("%s\t%s\n", host, _mk_NA(org)); + } + } + + GeoIP_delete(gi); + + return 0; +} diff --git a/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-city.c b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-city.c new file mode 100644 index 00000000..4a48fdea --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-city.c @@ -0,0 +1,83 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-city.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include "GeoIPCity.h" + + +static const char * _mk_NA( const char * p ){ + return p ? p : "N/A"; +} + +int +main(int argc, char *argv[]) +{ + FILE *f; + GeoIP *gi; + GeoIPRecord *gir; + int generate = 0; + char host[50]; + const char *time_zone = NULL; + char **ret; + if (argc == 2) + if (!strcmp(argv[1], "gen")) + generate = 1; + + gi = GeoIP_open("../data/GeoIPCity.dat", GEOIP_INDEX_CACHE); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("city_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening city_test.txt\n"); + exit(1); + } + + while (fscanf(f, "%s", host) != EOF) { + gir = GeoIP_record_by_name(gi, (const char *) host); + + if (gir != NULL) { + ret = GeoIP_range_by_ip(gi, (const char *) host); + time_zone = GeoIP_time_zone_by_country_and_region(gir->country_code, gir->region); + printf("%s\t%s\t%s\t%s\t%s\t%s\t%f\t%f\t%d\t%d\t%s\t%s\t%s\n", host, + _mk_NA(gir->country_code), + _mk_NA(gir->region), + _mk_NA(GeoIP_region_name_by_code(gir->country_code, gir->region)), + _mk_NA(gir->city), + _mk_NA(gir->postal_code), + gir->latitude, + gir->longitude, + gir->metro_code, + gir->area_code, + _mk_NA(time_zone), + ret[0], + ret[1]); + GeoIP_range_by_ip_delete(ret); + GeoIPRecord_delete(gir); + } + } + GeoIP_delete(gi); + return 0; + +} diff --git a/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-isp.c b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-isp.c new file mode 100644 index 00000000..d6212b86 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-isp.c @@ -0,0 +1,65 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-isp.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +static const char * _mk_NA( const char * p ){ + return p ? p : "N/A"; +} + +int main (int argc, char* argv[]) { + FILE *f; + GeoIP * gi; + char * org; + int generate = 0; + char host[50]; + + if (argc == 2) + if (!strcmp(argv[1],"gen")) + generate = 1; + + gi = GeoIP_open("../data/GeoIPISP.dat", GEOIP_STANDARD); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("isp_test.txt","r"); + + if (f == NULL) { + fprintf(stderr, "Error opening isp_test.txt\n"); + exit(1); + } + + while (fscanf(f, "%s", host) != EOF) { + org = GeoIP_org_by_name (gi, (const char *)host); + + if (org != NULL) { + printf("%s\t%s\n", host, _mk_NA(org)); + free(org); + } + } + + fclose(f); + GeoIP_delete(gi); + + return 0; +} diff --git a/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-netspeed.c b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-netspeed.c new file mode 100644 index 00000000..05def4e9 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-netspeed.c @@ -0,0 +1,59 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-netspeed.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +int main (int argc, char* argv[]) { + FILE *f; + GeoIP * gi; + int netspeed; + char host[50]; + + gi = GeoIP_open("../data/GeoIPNetSpeed.dat", GEOIP_STANDARD); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("netspeed_test.txt","r"); + + if (f == NULL) { + fprintf(stderr, "Error opening netspeed_test.txt\n"); + exit(1); + } + + while (fscanf(f, "%s", host) != EOF) { + netspeed = GeoIP_id_by_name (gi, (const char *)host); + if (netspeed == GEOIP_UNKNOWN_SPEED) { + printf("%s\tUnknown\n", host); + } else if (netspeed == GEOIP_DIALUP_SPEED) { + printf("%s\tDialup\n", host); + } else if (netspeed == GEOIP_CABLEDSL_SPEED) { + printf("%s\tCable/DSL\n", host); + } else if (netspeed == GEOIP_CORPORATE_SPEED) { + printf("%s\tCorporate\n", host); + } + } + fclose(f); + GeoIP_delete(gi); + + return 0; +} diff --git a/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-org.c b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-org.c new file mode 100644 index 00000000..74ba01be --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-org.c @@ -0,0 +1,71 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-org.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "GeoIP.h" + +static const char * _mk_NA( const char * p ){ + return p ? p : "N/A"; +} + +int +main(int argc, char *argv[]) +{ + FILE *f; + GeoIP *gi; + char *org; + int generate = 0; + char host[50]; + char **ret; + if (argc == 2) + if (!strcmp(argv[1], "gen")) + generate = 1; + + gi = GeoIP_open("../data/GeoIPOrg.dat", GEOIP_INDEX_CACHE); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("org_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening org_test.txt\n"); + exit(1); + } + + printf("IP\torganization\tnetmask\tbeginIp\tendIp\n"); + while (fscanf(f, "%s", host) != EOF) { + org = GeoIP_name_by_name(gi, (const char *) host); + + if (org != NULL) { + ret = GeoIP_range_by_ip(gi, (const char *) host); + + printf("%s\t%s\t%d\t%s\t%s\n", host, _mk_NA(org), GeoIP_last_netmask(gi), ret[0], ret[1]); + GeoIP_range_by_ip_delete(ret); + free(org); + } + } + + fclose(f); + GeoIP_delete(gi); + return 0; +} diff --git a/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-region.c b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-region.c new file mode 100644 index 00000000..0be75177 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip-region.c @@ -0,0 +1,114 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-region.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include /* For uint32_t */ +#ifdef HAVE_STDINT_H +#include /* For uint32_t */ +#endif +#if !defined(_WIN32) +#include /* For gethostbyname */ +#include /* For ntohl */ +#else +#include +#include +#endif +#include + +unsigned long inetaddr(const char * name) +{ + struct hostent * host; + struct in_addr inaddr; + + host = gethostbyname(name); assert(host); + inaddr.s_addr = *((uint32_t*)host->h_addr_list[0]); + return inaddr.s_addr; +} + +static const char * _mk_NA ( const char * p ){ + return p ? p : "N/A"; +} + +int main () { + GeoIP * gi; + GeoIPRegion * gir, giRegion; + + FILE *f; + char ipAddress[30]; + char expectedCountry[3]; + char expectedCountry3[4]; + const char * time_zone; + + gi = GeoIP_open("../data/GeoIPRegion.dat", GEOIP_MEMORY_CACHE); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("region_test.txt","r"); + + if (f == NULL) { + fprintf(stderr, "Error opening region_test.txt\n"); + exit(1); + } + + gir = GeoIP_region_by_addr (gi, "10.0.0.0"); + if (gir != NULL) { + printf("lookup of private IP address: country = %s, region = %s\n", gir->country_code, gir->region); + } + + while (fscanf(f, "%s%s%s", ipAddress, expectedCountry, expectedCountry3 ) != EOF) { + printf("ip = %s\n",ipAddress); + + gir = GeoIP_region_by_name (gi, ipAddress); + time_zone = GeoIP_time_zone_by_country_and_region(gir->country_code, gir->region); + if (gir != NULL) { + printf("%s, %s, %s, %s\n", + gir->country_code, + (!gir->region[0]) ? "N/A" : gir->region, + _mk_NA(GeoIP_region_name_by_code(gir->country_code, gir->region)), + _mk_NA(time_zone)); + } else { + printf("NULL!\n"); + } + + GeoIP_assign_region_by_inetaddr (gi, inetaddr(ipAddress), &giRegion); + if (gir != NULL) { + assert(giRegion.country_code[0]); + assert(!strcmp(gir->country_code, giRegion.country_code)); + if ( gir->region[0] ) { + assert(giRegion.region[0]); + assert(!strcmp(gir->region, giRegion.region)); + } else { + assert(!giRegion.region[0]); + } + } else { + assert(!giRegion.country_code[0]); + } + + if ( gir != NULL ) { + GeoIPRegion_delete(gir); + } + } + + GeoIP_delete(gi); + return 0; +} diff --git a/src/libs/resiprocate/contrib/GeoIP/test/test-geoip.c b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip.c new file mode 100644 index 00000000..4bb209e8 --- /dev/null +++ b/src/libs/resiprocate/contrib/GeoIP/test/test-geoip.c @@ -0,0 +1,113 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip.c + * + * Copyright (C) 2006 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +int main () { + FILE *f; + char ipAddress[30]; + char expectedCountry[3]; + char expectedCountry3[4]; + const char * returnedCountry; + GeoIP * gi; + int failed = 0; + int test_num = 1; + + int i; + for (i = 0; i < 2; ++i) { + if (0 == i) { + /* Read from filesystem, check for updated file */ + gi = GeoIP_open(SRCDIR"/data/GeoIP.dat", GEOIP_STANDARD | GEOIP_CHECK_CACHE); + } else { + /* Read from memory, faster but takes up more memory */ + gi = GeoIP_open(SRCDIR"/data/GeoIP.dat", GEOIP_MEMORY_CACHE); + } + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + /* make sure GeoIP deals with invalid query gracefully */ + returnedCountry = GeoIP_country_code_by_addr(gi,NULL); + if (returnedCountry != NULL) { + fprintf(stderr,"Invalid Query test failed, got non NULL, expected NULL\n"); + failed = 1; + } + + returnedCountry = GeoIP_country_code_by_name(gi,NULL); + if (returnedCountry != NULL) { + fprintf(stderr,"Invalid Query test failed, got non NULL, expected NULL\n"); + failed = 1; + } + + f = fopen(SRCDIR"/test/country_test.txt","r"); + + while (fscanf(f, "%s%s%s", ipAddress, expectedCountry, expectedCountry3) != EOF) { + returnedCountry = GeoIP_country_code_by_addr(gi,ipAddress); + if (returnedCountry == NULL || strcmp(returnedCountry, expectedCountry) != 0) { + fprintf(stderr,"Test addr %d for %s failed, got %s, expected %s\n",test_num,ipAddress,returnedCountry,expectedCountry); + failed = 1; + } + returnedCountry = GeoIP_country_code_by_name(gi,ipAddress); + if (returnedCountry == NULL || strcmp(returnedCountry, expectedCountry) != 0) { + fprintf(stderr,"Test name %d for %s failed, got %s, expected %s\n",test_num,ipAddress,returnedCountry,expectedCountry); + failed = 1; + } + returnedCountry = GeoIP_country_code3_by_addr(gi,ipAddress); + if (returnedCountry == NULL || strcmp(returnedCountry, expectedCountry3) != 0) { + fprintf(stderr,"Test addr %d for %s failed, got %s, expected %s\n",test_num,ipAddress,returnedCountry,expectedCountry); + failed = 1; + } + returnedCountry = GeoIP_country_code3_by_name(gi,ipAddress); + if (returnedCountry == NULL || strcmp(returnedCountry, expectedCountry3) != 0) { + fprintf(stderr,"Test name %d for %s failed, got %s, expected %s\n",test_num,ipAddress,returnedCountry,expectedCountry); + failed = 1; + } + test_num++; + } + fclose(f); + + f = fopen(SRCDIR"/test/country_test2.txt","r"); + while (fscanf(f, "%s%s", ipAddress, expectedCountry ) != EOF) { + returnedCountry = GeoIP_country_code_by_addr(gi,ipAddress); + if (returnedCountry == NULL || strcmp(returnedCountry, expectedCountry) != 0) { + fprintf(stderr,"Test addr %d %s failed, got %s, expected %s\n",test_num,ipAddress,returnedCountry,expectedCountry); + failed = 1; + } + test_num++; + } + fclose(f); + + f = fopen(SRCDIR"/test/country_test_name.txt","r"); + while (fscanf(f, "%s%s", ipAddress, expectedCountry) != EOF) { + returnedCountry = GeoIP_country_code_by_name(gi,ipAddress); + if (returnedCountry == NULL || strcmp(returnedCountry, expectedCountry) != 0) { + fprintf(stderr,"Test addr %d %s failed, got %s, expected %s\n",test_num,ipAddress,returnedCountry,expectedCountry); + failed = 1; + } + test_num++; + } + + fclose(f); + GeoIP_delete(gi); + } + return failed; +} diff --git a/src/libs/resiprocate/contrib/ares/.cvsignore b/src/libs/resiprocate/contrib/ares/.cvsignore new file mode 100644 index 00000000..96b3624e --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/.cvsignore @@ -0,0 +1,12 @@ +.DS_Store +Makefile +adig +ahost +config.cache +config.log +config.status +Makefile +config.cache +config.log +config.status +libares.a diff --git a/src/libs/resiprocate/contrib/ares/Debug/ares_9_0.log b/src/libs/resiprocate/contrib/ares/Debug/ares_9_0.log new file mode 100644 index 00000000..33ad8fed --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/Debug/ares_9_0.log @@ -0,0 +1,55 @@ +Build started 10/22/2015 2:04:14 PM. + 1>Project "C:\works\own\rtphone\Libs\resiprocate\contrib\ares\ares_9_0.vcxproj" on node 4 (Rebuild target(s)). + 1>ClCompile: + C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\CL.exe /c /IC:\works\own\rtphone\/contrib/ares /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D USE_IPV6 /D _CRT_SECURE_NO_WARNINGS /D _VC80_UPGRADE=0x0710 /D _USING_V110_SDK71_ /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t- /Zc:forScope /Fo"Debug\\" /Fd"Debug\vc120.pdb" /Gd /TC /analyze- /errorReport:prompt /MP ares__close_sockets.c ares__get_hostent.c ares__read_line.c ares_destroy.c ares_expand_name.c ares_fds.c ares_free_errmem.c ares_free_hostent.c ares_free_string.c ares_gethostbyaddr.c ares_gethostbyname.c ares_init.c ares_local.c ares_mkquery.c ares_parse_a_reply.c ares_parse_ptr_reply.c ares_process.c ares_query.c ares_search.c ares_send.c ares_strerror.c ares_timeout.c + ares__close_sockets.c + ares__get_hostent.c + ares__read_line.c + ares_destroy.c + ares_expand_name.c + ares_fds.c + ares_free_errmem.c + ares_free_hostent.c + ares_free_string.c + ares_gethostbyaddr.c + ares_gethostbyname.c + ares_init.c + ares_local.c + ares_mkquery.c + ares_parse_a_reply.c + ares_parse_ptr_reply.c + ares_process.c + ares_query.c + ares_search.c + ares_send.c + ares_strerror.c + ares_timeout.c + Lib: + C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\Lib.exe /OUT:"Debug\ares.lib" /NOLOGO Debug\ares__close_sockets.obj + Debug\ares__get_hostent.obj + Debug\ares__read_line.obj + Debug\ares_destroy.obj + Debug\ares_expand_name.obj + Debug\ares_fds.obj + Debug\ares_free_errmem.obj + Debug\ares_free_hostent.obj + Debug\ares_free_string.obj + Debug\ares_gethostbyaddr.obj + Debug\ares_gethostbyname.obj + Debug\ares_init.obj + Debug\ares_local.obj + Debug\ares_mkquery.obj + Debug\ares_parse_a_reply.obj + Debug\ares_parse_ptr_reply.obj + Debug\ares_process.obj + Debug\ares_query.obj + Debug\ares_search.obj + Debug\ares_send.obj + Debug\ares_strerror.obj + Debug\ares_timeout.obj + ares_9_0.vcxproj -> C:\works\own\rtphone\Libs\resiprocate\contrib\ares\Debug\ares.lib + 1>Done Building Project "C:\works\own\rtphone\Libs\resiprocate\contrib\ares\ares_9_0.vcxproj" (Rebuild target(s)). + +Build succeeded. + +Time Elapsed 00:00:35.01 diff --git a/src/libs/resiprocate/contrib/ares/Makefile.am b/src/libs/resiprocate/contrib/ares/Makefile.am new file mode 100644 index 00000000..f7ec3f81 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/Makefile.am @@ -0,0 +1,43 @@ +# $Id: $ +AUTOMAKE_OPTIONS = foreign + +CFLAGS=@CFLAGS@ ${WARN_CFLAGS} ${ERROR_CFLAGS} + +ALL_CFLAGS=${CPPFLAGS} ${CFLAGS} ${DEFS} + +INCLUDES = -I$(top_srcdir) + +lib_LIBRARIES = libares.a +libares_a_SOURCES = \ + ares__close_sockets.c ares__get_hostent.c ares__read_line.c \ + ares_destroy.c ares_expand_name.c ares_fds.c ares_free_errmem.c \ + ares_free_hostent.c ares_free_string.c ares_gethostbyaddr.c \ + ares_gethostbyname.c ares_init.c ares_mkquery.c ares_parse_a_reply.c \ + ares_parse_ptr_reply.c ares_process.c ares_query.c ares_search.c \ + ares_send.c ares_strerror.c ares_timeout.c ares_local.c + +libares_adir = ares +libares_a_HEADERS =\ + ares.h ares_compat.h ares_dns.h ares_local.h ares_version.h + +noinst_HEADERS = ares_private.h +man3_MANS = \ + ares_destroy.3 ares_free_hostent.3 ares_init.3 \ + ares_parse_ptr_reply.3 ares_send.3 ares_expand_name.3 \ + ares_free_string.3 ares_init_options.3 ares_process.3 \ + ares_strerror.3 ares_fds.3 ares_gethostbyaddr.3 \ + ares_mkquery.3 ares_query.3 ares_timeout.3 \ + ares_free_errmem.3 ares_gethostbyname.3 ares_parse_a_reply.3 \ + ares_search.3 + +EXTRA_DIST = $(man3_MANS) adig.c ahost.c ares.vcproj ares_7_1.vcproj + +adig: adig.o libares.a + ${CC} ${LDFLAGS} -o $@ adig.o libares.a ${LIBS} + +ahost: ahost.o libares.a + ${CC} ${LDFLAGS} -o $@ ahost.o libares.a ${LIBS} + + +#distclean: clean +# rm -f config.cache config.log config.status Makefile diff --git a/src/libs/resiprocate/contrib/ares/Makefile.in b/src/libs/resiprocate/contrib/ares/Makefile.in new file mode 100644 index 00000000..ede5751b --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/Makefile.in @@ -0,0 +1,661 @@ +# Makefile.in generated by automake 1.7.5 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = . + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +ARES_VERSION = @ARES_VERSION@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ + +CFLAGS = @CFLAGS@ ${WARN_CFLAGS} ${ERROR_CFLAGS} +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EXEEXT = @EXEEXT@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ + +# $Id: $ +AUTOMAKE_OPTIONS = foreign + +ALL_CFLAGS = ${CPPFLAGS} ${CFLAGS} ${DEFS} + +INCLUDES = -I$(top_srcdir) + +lib_LIBRARIES = libares.a +libares_a_SOURCES = \ + ares__close_sockets.c ares__get_hostent.c ares__read_line.c \ + ares_destroy.c ares_expand_name.c ares_fds.c ares_free_errmem.c \ + ares_free_hostent.c ares_free_string.c ares_gethostbyaddr.c \ + ares_gethostbyname.c ares_init.c ares_mkquery.c ares_parse_a_reply.c \ + ares_parse_ptr_reply.c ares_process.c ares_query.c ares_search.c \ + ares_send.c ares_strerror.c ares_timeout.c ares_local.c + + +libares_adir = ares +libares_a_HEADERS = \ + ares.h ares_compat.h ares_dns.h ares_local.h ares_version.h + + +noinst_HEADERS = ares_private.h +man3_MANS = \ + ares_destroy.3 ares_free_hostent.3 ares_init.3 \ + ares_parse_ptr_reply.3 ares_send.3 ares_expand_name.3 \ + ares_free_string.3 ares_init_options.3 ares_process.3 \ + ares_strerror.3 ares_fds.3 ares_gethostbyaddr.3 \ + ares_mkquery.3 ares_query.3 ares_timeout.3 \ + ares_free_errmem.3 ares_gethostbyname.3 ares_parse_a_reply.3 \ + ares_search.3 + + +EXTRA_DIST = $(man3_MANS) adig.c ahost.c ares.vcproj ares_7_1.vcproj +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +LIBRARIES = $(lib_LIBRARIES) + +libares_a_AR = $(AR) cru +libares_a_LIBADD = +am_libares_a_OBJECTS = ares__close_sockets.$(OBJEXT) \ + ares__get_hostent.$(OBJEXT) ares__read_line.$(OBJEXT) \ + ares_destroy.$(OBJEXT) ares_expand_name.$(OBJEXT) \ + ares_fds.$(OBJEXT) ares_free_errmem.$(OBJEXT) \ + ares_free_hostent.$(OBJEXT) ares_free_string.$(OBJEXT) \ + ares_gethostbyaddr.$(OBJEXT) ares_gethostbyname.$(OBJEXT) \ + ares_init.$(OBJEXT) ares_mkquery.$(OBJEXT) \ + ares_parse_a_reply.$(OBJEXT) ares_parse_ptr_reply.$(OBJEXT) \ + ares_process.$(OBJEXT) ares_query.$(OBJEXT) \ + ares_search.$(OBJEXT) ares_send.$(OBJEXT) \ + ares_strerror.$(OBJEXT) ares_timeout.$(OBJEXT) \ + ares_local.$(OBJEXT) +libares_a_OBJECTS = $(am_libares_a_OBJECTS) + +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/ares__close_sockets.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares__get_hostent.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares__read_line.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_destroy.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_expand_name.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_fds.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_free_errmem.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_free_hostent.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_free_string.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_gethostbyaddr.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_gethostbyname.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_init.Po ./$(DEPDIR)/ares_local.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_mkquery.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_parse_a_reply.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_parse_ptr_reply.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_process.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_query.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_search.Po ./$(DEPDIR)/ares_send.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_strerror.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ares_timeout.Po +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(libares_a_SOURCES) + +NROFF = nroff +MANS = $(man3_MANS) +HEADERS = $(libares_a_HEADERS) $(noinst_HEADERS) + +DIST_COMMON = README $(libares_a_HEADERS) $(noinst_HEADERS) Makefile.am \ + Makefile.in NEWS aclocal.m4 config.guess config.sub configure \ + configure.ac depcomp install-sh missing mkinstalldirs +SOURCES = $(libares_a_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj + +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe) + +$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(srcdir)/configure.ac $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.ac + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +AR = ar +libLIBRARIES_INSTALL = $(INSTALL_DATA) +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(libLIBRARIES_INSTALL) $$p $(DESTDIR)$(libdir)/$$f"; \ + $(libLIBRARIES_INSTALL) $$p $(DESTDIR)$(libdir)/$$f; \ + else :; fi; \ + done + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + p="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \ + $(RANLIB) $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + p="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(libdir)/$$p"; \ + rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) +libares.a: $(libares_a_OBJECTS) $(libares_a_DEPENDENCIES) + -rm -f libares.a + $(libares_a_AR) libares.a $(libares_a_OBJECTS) $(libares_a_LIBADD) + $(RANLIB) libares.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares__close_sockets.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares__get_hostent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares__read_line.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_destroy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_expand_name.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_fds.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_free_errmem.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_free_hostent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_free_string.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_gethostbyaddr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_gethostbyname.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_init.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_local.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_mkquery.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_parse_a_reply.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_parse_ptr_reply.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_process.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_query.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_search.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_send.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_strerror.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares_timeout.Po@am__quote@ + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` +uninstall-info-am: + +man3dir = $(mandir)/man3 +install-man3: $(man3_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(man3dir) + @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.3*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 3*) ;; \ + *) ext='3' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst; \ + done +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.3*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 3*) ;; \ + *) ext='3' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man3dir)/$$inst"; \ + rm -f $(DESTDIR)$(man3dir)/$$inst; \ + done +libares_aHEADERS_INSTALL = $(INSTALL_HEADER) +install-libares_aHEADERS: $(libares_a_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libares_adir) + @list='$(libares_a_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(libares_aHEADERS_INSTALL) $$d$$p $(DESTDIR)$(libares_adir)/$$f"; \ + $(libares_aHEADERS_INSTALL) $$d$$p $(DESTDIR)$(libares_adir)/$$f; \ + done + +uninstall-libares_aHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(libares_a_HEADERS)'; for p in $$list; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(libares_adir)/$$f"; \ + rm -f $(DESTDIR)$(libares_adir)/$$f; \ + done + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = . +distdir = $(PACKAGE)-$(VERSION) + +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } + +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print + +distdir: $(DISTFILES) + $(am__remove_distdir) + mkdir $(distdir) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist dist-all: distdir + $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + $(am__remove_distdir) + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && $(mkinstalldirs) "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \ + && rm -f $(distdir).tar.gz \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @echo "$(distdir).tar.gz is ready for distribution" | \ + sed 'h;s/./=/g;p;x;p;x' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(MANS) $(HEADERS) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(man3dir) $(DESTDIR)$(libares_adir) +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-libares_aHEADERS install-man + +install-exec-am: install-libLIBRARIES + +install-info: install-info-am + +install-man: install-man3 + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf autom4te.cache +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-libLIBRARIES \ + uninstall-libares_aHEADERS uninstall-man + +uninstall-man: uninstall-man3 + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLIBRARIES ctags dist dist-all dist-gzip distcheck \ + distclean distclean-compile distclean-depend distclean-generic \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-libLIBRARIES install-libares_aHEADERS \ + install-man install-man3 install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-info-am uninstall-libLIBRARIES \ + uninstall-libares_aHEADERS uninstall-man uninstall-man3 + + +adig: adig.o libares.a + ${CC} ${LDFLAGS} -o $@ adig.o libares.a ${LIBS} + +ahost: ahost.o libares.a + ${CC} ${LDFLAGS} -o $@ ahost.o libares.a ${LIBS} + +#distclean: clean +# rm -f config.cache config.log config.status Makefile +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/resiprocate/contrib/ares/NEWS b/src/libs/resiprocate/contrib/ares/NEWS new file mode 100644 index 00000000..728b4b8e --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/NEWS @@ -0,0 +1,18 @@ +Major changes in release 1.1.1: +* ares should now compile as C++ code (no longer uses reserved word + "class"). +* Added SRV support to adig test program. +* Fixed a few error handling bugs in query processing. + +Major changes in release 1.1.0: +* Added ares_free_string() function so that memory can be freed in the + same layer as it is allocated, a desirable feature in some + environments. +* A few of the ares_dns.h macros are fixed to use the proper bitwise + operator. +* Fixed a couple of fenceposts fixed in ares_expand_name()'s + bounds-checking. +* In process_timeouts(), extract query->next before calling + next_server() and possibly freeing the query structure. +* Casted arguments to ctype macros casted to unsigned char, since not + all char values are valid inputs to those macros according to ANSI. diff --git a/src/libs/resiprocate/contrib/ares/README b/src/libs/resiprocate/contrib/ares/README new file mode 100644 index 00000000..06b5e81c --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/README @@ -0,0 +1,41 @@ +This is ares, an asynchronous resolver library. It is intended for +applications which need to perform DNS queries without blocking, or +need to perform multiple DNS queries in parallel. The primary +examples of such applications are servers which communicate with +multiple clients and programs with graphical user interfaces. + +This library implementation is not especially portable to crufty old +systems like SunOS 4. It assumes a compiler which can handle ANSI C +syntax, a system malloc which properly handles realloc(NULL, foo) and +free(NULL), and a reasonably up-to-date . + +I have attempted to preserve the externally visible behavior of the +BIND resolver in nearly all respects. The API of the library is, of +course, very different from the synchronous BIND API; instead of +invoking a function like res_send() and getting a return value back +indicating the number of bytes in the response, you invoke a function +like ares_send() and give it a callback function to invoke when the +response arrives. You then have to select() on the file descriptors +indicated by ares_fds(), with a timeout given by ares_timeout(). You +call ares_process() when select() returns. + +Some features are missing from the current version of ares, relative +to the BIND resolver: + + * There is no IPV6 support. + * There is no hostname verification. + * There is no logging of unexpected events. + * There is no debugging-oriented logging. + * There is no YP support. + +libares requires an ANSI compiler to compile and use. To build the +library, just run "./configure" and "make". To install it, run "make +install". Run "./configure --help" to see a list of options you can +provide to configure to change how the library builds. libares has no +data files, so you can move the include file and library around freely +without leaving behind any dependencies on old paths. Building the +library will also build the "adig" program, a little toy for trying +out the library. It doesn't get installed. + +libares is distributed at athena-dist.mit.edu:pub/ATHENA/ares. Please +send bug reports and comments to ghudson@mit.edu. diff --git a/src/libs/resiprocate/contrib/ares/aclocal.m4 b/src/libs/resiprocate/contrib/ares/aclocal.m4 new file mode 100644 index 00000000..dad53fd4 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/aclocal.m4 @@ -0,0 +1,859 @@ +# generated automatically by aclocal 1.7.5 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# Do all the work for Automake. -*- Autoconf -*- + +# This macro actually does too much some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 10 + +AC_PREREQ([2.54]) + +# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow +# the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG(AMTAR, tar) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl + +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright 2002 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.7.5])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright 2001, 2002 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# +# Check to make sure that the build environment is sane. +# + +# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# -*- Autoconf -*- + + +# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# AM_AUX_DIR_EXPAND + +# Copyright 2001 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +# Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50]) + +AC_DEFUN([AM_AUX_DIR_EXPAND], [ +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. + +# Copyright 2001 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# AM_PROG_INSTALL_STRIP + +# Copyright 2001 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# -*- Autoconf -*- +# Copyright (C) 2003 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# serial 5 -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + echo '#include "conftest.h"' > conftest.c + echo 'int i;' > conftest.h + echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=conftest.c object=conftest.o \ + depfile=conftest.Po tmpdepfile=conftest.TPo \ + $SHELL ./depcomp $depcc -c -o conftest.o conftest.c \ + >/dev/null 2>conftest.err && + grep conftest.h conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # (even with -Werror). So we grep stderr for any message + # that says an option was ignored. + if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking Speeds up one-time builds + --enable-dependency-tracking Do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +#serial 2 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue + # Extract the definition of DEP_FILES from the Makefile without + # running `make'. + DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` + test -z "$DEPDIR" && continue + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n -e '/^U = / s///p' < "$mf"` + test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" + # We invoke sed twice because it is the simplest approach to + # changing $(DEPDIR) to its actual value in the expansion. + for file in `sed -n -e ' + /^DEP_FILES = .*\\\\$/ { + s/^DEP_FILES = // + :loop + s/\\\\$// + p + n + /\\\\$/ b loop + p + } + /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright 1997, 2000, 2001 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 5 + +AC_PREREQ(2.52) + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]) +fi])]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# Copyright 1996, 1998, 2000, 2001, 2002 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + diff --git a/src/libs/resiprocate/contrib/ares/adig.c b/src/libs/resiprocate/contrib/ares/adig.c new file mode 100644 index 00000000..c34cb516 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/adig.c @@ -0,0 +1,754 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include + +#ifdef WIN32 +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#endif + +#include +#include +#include +#include +#include + +#include + +#include "ares.h" +#include "ares_dns.h" +#include "ares_compat.h" + +#if defined(WIN32) || defined(__QNX__) +#define strcasecmp(a,b) stricmp(a,b) +#define strncasecmp(a,b,c) strnicmp(a,b,c) +#endif + + +#ifndef INADDR_NONE +#define INADDR_NONE 0xffffffff +#endif + +extern int optind; +extern char *optarg; + +struct nv { + const char *name; + int value; +}; + +static const struct nv flags[] = { + { "usevc", ARES_FLAG_USEVC }, + { "primary", ARES_FLAG_PRIMARY }, + { "igntc", ARES_FLAG_IGNTC }, + { "norecurse", ARES_FLAG_NORECURSE }, + { "stayopen", ARES_FLAG_STAYOPEN }, + { "noaliases", ARES_FLAG_NOALIASES } +}; +static const int nflags = sizeof(flags) / sizeof(flags[0]); + +static const struct nv classes[] = { + { "IN", C_IN }, + { "CHAOS", C_CHAOS }, + { "HS", C_HS }, + { "ANY", C_ANY } +}; +static const int nclasses = sizeof(classes) / sizeof(classes[0]); + +static const struct nv types[] = { + { "A", T_A }, + { "NS", T_NS }, + { "MD", T_MD }, + { "MF", T_MF }, + { "CNAME", T_CNAME }, + { "SOA", T_SOA }, + { "MB", T_MB }, + { "MG", T_MG }, + { "MR", T_MR }, + { "NULL", T_NULL }, + { "WKS", T_WKS }, + { "PTR", T_PTR }, + { "HINFO", T_HINFO }, + { "MINFO", T_MINFO }, + { "MX", T_MX }, + { "TXT", T_TXT }, + { "RP", T_RP }, + { "AFSDB", T_AFSDB }, + { "X25", T_X25 }, + { "ISDN", T_ISDN }, + { "RT", T_RT }, + { "NSAP", T_NSAP }, + { "NSAP_PTR", T_NSAP_PTR }, + { "SIG", T_SIG }, + { "KEY", T_KEY }, + { "PX", T_PX }, + { "GPOS", T_GPOS }, + { "AAAA", T_AAAA }, + { "LOC", T_LOC }, + { "SRV", T_SRV }, + { "AXFR", T_AXFR }, + { "MAILB", T_MAILB }, + { "MAILA", T_MAILA }, + { "NAPTR", T_NAPTR }, + { "ANY", T_ANY } +}; +static const int ntypes = sizeof(types) / sizeof(types[0]); + +static const char *opcodes[] = { + "QUERY", "IQUERY", "STATUS", "(reserved)", "NOTIFY", + "(unknown)", "(unknown)", "(unknown)", "(unknown)", + "UPDATEA", "UPDATED", "UPDATEDA", "UPDATEM", "UPDATEMA", + "ZONEINIT", "ZONEREF" +}; + +static const char *rcodes[] = { + "NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", "NOTIMP", "REFUSED", + "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)", + "(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE" +}; + +static void callback(void *arg, int status, unsigned char *abuf, int alen); +static const unsigned char *display_question(const unsigned char *aptr, + const unsigned char *abuf, + int alen); +static const unsigned char *display_rr(const unsigned char *aptr, + const unsigned char *abuf, int alen); +static const char *type_name(int type); +static const char *class_name(int dnsclass); +static void usage(void); + +#ifdef WIN32 +struct option +{ + const char *name; + int has_arg; + int *flag; + int val; +}; + +char *optarg = 0; +int optind = 0; + +/** + * This is a very hacked version for WIN32 that will support only what + * we need. This is NOT a generic getopt_long() + */ +int getopt(int argc, + char * argv[], + char *optstring ) +{ + static int carg = 0; + //static int nextchar = 0; + char * p; + + carg++; + if ( carg >= argc ) return -1; + + p = argv[carg]; + //register int al = strlen(argv[carg]); + + if (*p == '-' && isalnum(*(p+1))) + { + char o = *(p+1); + int i,l; + + l = (int)strlen(optstring); + + for( i = 0 ; i < l; i++) + { + + if (optstring[i] == ':') continue; + + if ( optstring[i] == o ) // match option char + { + + if ( optstring[i+1] == ':' ) // arg option + { + optind = ++carg; + optarg = argv[optind]; + + } + else + { + optind = 0; + optarg = 0; + } + return (int)o; + } + + } + + return (int)'?'; + } + return (int)'?'; +} +#endif + +int main(int argc, char **argv) +{ + ares_channel channel; + int c, i, optmask = ARES_OPT_FLAGS, dnsclass = C_IN, type = T_A; + int status, nfds, count; + struct ares_options options; + struct hostent *hostent; + fd_set read_fds, write_fds; + struct timeval *tvp, tv; + char *errmem; + +#ifdef WIN32 + WORD wVersionRequested = MAKEWORD( 2, 2 ); + WSADATA wsaData; + int err; + + err = WSAStartup( wVersionRequested, &wsaData ); + if ( err != 0 ) + { + // could not find a usable WinSock DLL + //cerr << "Could not load winsock" << endl; + assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work + exit(1); + } + + /* Confirm that the WinSock DLL supports 2.2.*/ + /* Note that if the DLL supports versions greater */ + /* than 2.2 in addition to 2.2, it will still return */ + /* 2.2 in wVersion since that is the version we */ + /* requested. */ + + if ( LOBYTE( wsaData.wVersion ) != 2 || + HIBYTE( wsaData.wVersion ) != 2 ) + { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + WSACleanup( ); + //cerr << "Bad winsock verion" << endl; + assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work + exit(1); + } +#endif + + options.flags = ARES_FLAG_NOCHECKRESP; + options.servers = NULL; + options.nservers = 0; + + while ((c = getopt(argc, argv, "f:s:c:t:T:U:")) != -1) + { + switch (c) + { + case 'f': + /* Add a flag. */ + for (i = 0; i < nflags; i++) + { + if (strcmp(flags[i].name, optarg) == 0) + break; + } + if (i == nflags) + usage(); + options.flags |= flags[i].value; + break; + + case 's': + /* Add a server, and specify servers in the option mask. */ + hostent = gethostbyname(optarg); + if (!hostent || hostent->h_addrtype != AF_INET) + { + fprintf(stderr, "adig: server %s not found.\n", optarg); + return 1; + } + options.servers = realloc(options.servers, (options.nservers + 1) + * sizeof(struct in_addr)); + if (!options.servers) + { + fprintf(stderr, "Out of memory!\n"); + return 1; + } + memcpy(&options.servers[options.nservers], hostent->h_addr, + sizeof(struct in_addr)); + options.nservers++; + optmask |= ARES_OPT_SERVERS; + break; + + case 'c': + /* Set the query class. */ + for (i = 0; i < nclasses; i++) + { + if (strcasecmp(classes[i].name, optarg) == 0) + break; + } + if (i == nclasses) + usage(); + dnsclass = classes[i].value; + break; + + case 't': + /* Set the query type. */ + for (i = 0; i < ntypes; i++) + { + if (strcasecmp(types[i].name, optarg) == 0) + break; + } + if (i == ntypes) + usage(); + type = types[i].value; + break; + + case 'T': + /* Set the TCP port number. */ + if (!isdigit((unsigned char)*optarg)) + usage(); + options.tcp_port = (unsigned short)strtol(optarg, NULL, 0); + optmask |= ARES_OPT_TCP_PORT; + break; + + case 'U': + /* Set the UDP port number. */ + if (!isdigit((unsigned char)*optarg)) + usage(); + options.udp_port = (unsigned short)strtol(optarg, NULL, 0); + optmask |= ARES_OPT_UDP_PORT; + break; + } + } + argc -= optind; + argv += optind; + if (argc == 0) + usage(); + + status = ares_init_options(&channel, &options, optmask); + if (status != ARES_SUCCESS) + { + fprintf(stderr, "ares_init_options: %s\n", + ares_strerror(status)); //, &errmem)); + ares_free_errmem(errmem); + return 1; + } + + /* Initiate the queries, one per command-line argument. If there is + * only one query to do, supply NULL as the callback argument; + * otherwise, supply the query name as an argument so we can + * distinguish responses for the user when printing them out. + */ + if (argc == 1) + ares_query(channel, *argv, dnsclass, type, callback, (char *) NULL); + else + { + for (; *argv; argv++) + ares_query(channel, *argv, dnsclass, type, callback, *argv); + } + + /* Wait for all queries to complete. */ + while (1) + { + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + nfds = ares_fds(channel, &read_fds, &write_fds); + if (nfds == 0) + break; + tvp = ares_timeout(channel, NULL, &tv); + count = select(nfds, &read_fds, &write_fds, NULL, tvp); + if (count < 0 && errno != EINVAL) + { + perror("select"); + return 1; + } + ares_process(channel, &read_fds, &write_fds); + } + + ares_destroy(channel); + return 0; +} + +static void callback(void *arg, int status, unsigned char *abuf, int alen) +{ + char *name = (char *) arg, *errmem; + int id, qr, opcode, aa, tc, rd, ra, rcode, i; + unsigned int qdcount, ancount, nscount, arcount; + const unsigned char *aptr; + + /* Display the query name if given. */ + if (name) + printf("Answer for query %s:\n", name); + + /* Display an error message if there was an error, but only stop if + * we actually didn't get an answer buffer. + */ + if (status != ARES_SUCCESS) + { + printf("%s\n", ares_strerror(status));//, &errmem)); + ares_free_errmem(errmem); + if (!abuf) + return; + } + + /* Won't happen, but check anyway, for safety. */ + if (alen < HFIXEDSZ) + return; + + /* Parse the answer header. */ + id = DNS_HEADER_QID(abuf); /* query identification number */ + qr = DNS_HEADER_QR(abuf); /* query response */ + opcode = DNS_HEADER_OPCODE(abuf); /* opcode */ + aa = DNS_HEADER_AA(abuf); /* authoritative answer */ + tc = DNS_HEADER_TC(abuf); /* truncation */ + rd = DNS_HEADER_RD(abuf); /* recursion desired */ + ra = DNS_HEADER_RA(abuf); /* recursion available */ + rcode = DNS_HEADER_RCODE(abuf); /* response code */ + qdcount = DNS_HEADER_QDCOUNT(abuf); /* question count */ + ancount = DNS_HEADER_ANCOUNT(abuf); /* answer record count */ + nscount = DNS_HEADER_NSCOUNT(abuf); /* name server record count */ + arcount = DNS_HEADER_ARCOUNT(abuf); /* additional record count */ + + /* Display the answer header. */ + printf("id: %d\n", id); + printf("flags: %s%s%s%s%s\n", + qr ? "qr " : "", + aa ? "aa " : "", + tc ? "tc " : "", + rd ? "rd " : "", + ra ? "ra " : ""); + printf("opcode: %s\n", opcodes[opcode]); + printf("rcode: %s\n", rcodes[rcode]); + + /* Display the questions. */ + printf("Questions:\n"); + aptr = abuf + HFIXEDSZ; + for (i = 0; i < (int)qdcount; i++) + { + aptr = display_question(aptr, abuf, alen); + if (aptr == NULL) + return; + } + + /* Display the answers. */ + printf("Answers:\n"); + for (i = 0; i < (int)ancount; i++) + { + aptr = display_rr(aptr, abuf, alen); + if (aptr == NULL) + return; + } + + /* Display the NS records. */ + printf("NS records:\n"); + for (i = 0; i < (int)nscount; i++) + { + aptr = display_rr(aptr, abuf, alen); + if (aptr == NULL) + return; + } + + /* Display the additional records. */ + printf("Additional records:\n"); + for (i = 0; i < (int)arcount; i++) + { + aptr = display_rr(aptr, abuf, alen); + if (aptr == NULL) + return; + } +} + +static const unsigned char *display_question(const unsigned char *aptr, + const unsigned char *abuf, + int alen) +{ + char *name; + int type, dnsclass, status, len; + + /* Parse the question name. */ + status = ares_expand_name(aptr, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return NULL; + aptr += len; + + /* Make sure there's enough data after the name for the fixed part + * of the question. + */ + if (aptr + QFIXEDSZ > abuf + alen) + { + free(name); + return NULL; + } + + /* Parse the question type and class. */ + type = DNS_QUESTION_TYPE(aptr); + dnsclass = DNS_QUESTION_CLASS(aptr); + aptr += QFIXEDSZ; + + /* Display the question, in a format sort of similar to how we will + * display RRs. + */ + printf("\t%-15s.\t", name); + if (dnsclass != C_IN) + printf("\t%s", class_name(dnsclass)); + printf("\t%s\n", type_name(type)); + free(name); + return aptr; +} + +static const unsigned char *display_rr(const unsigned char *aptr, + const unsigned char *abuf, int alen) +{ + const unsigned char *p; + char *name; + int type, dnsclass, ttl, dlen, status, len; + struct in_addr addr; + + /* Parse the RR name. */ + status = ares_expand_name(aptr, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return NULL; + aptr += len; + + /* Make sure there is enough data after the RR name for the fixed + * part of the RR. + */ + if (aptr + RRFIXEDSZ > abuf + alen) + { + free(name); + return NULL; + } + + /* Parse the fixed part of the RR, and advance to the RR data + * field. */ + type = DNS_RR_TYPE(aptr); + dnsclass = DNS_RR_CLASS(aptr); + ttl = DNS_RR_TTL(aptr); + dlen = DNS_RR_LEN(aptr); + aptr += RRFIXEDSZ; + if (aptr + dlen > abuf + alen) + { + free(name); + return NULL; + } + + /* Display the RR name, class, and type. */ + printf("\t%-15s.\t%d", name, ttl); + if (dnsclass != C_IN) + printf("\t%s", class_name(dnsclass)); + printf("\t%s", type_name(type)); + free(name); + + /* Display the RR data. Don't touch aptr. */ + switch (type) + { + case T_CNAME: + case T_MB: + case T_MD: + case T_MF: + case T_MG: + case T_MR: + case T_NS: + case T_PTR: + /* For these types, the RR data is just a domain name. */ + status = ares_expand_name(aptr, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return NULL; + printf("\t%s.", name); + free(name); + break; + + case T_HINFO: + /* The RR data is two length-counted character strings. */ + p = aptr; + len = *p; + if (p + len + 1 > aptr + dlen) + return NULL; + printf("\t%.*s", len, p + 1); + p += len + 1; + len = *p; + if (p + len + 1 > aptr + dlen) + return NULL; + printf("\t%.*s", len, p + 1); + break; + + case T_MINFO: + /* The RR data is two domain names. */ + p = aptr; + status = ares_expand_name(p, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return NULL; + printf("\t%s.", name); + free(name); + p += len; + status = ares_expand_name(p, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return NULL; + printf("\t%s.", name); + free(name); + break; + + case T_MX: + /* The RR data is two bytes giving a preference ordering, and + * then a domain name. + */ + if (dlen < 2) + return NULL; + printf("\t%d", (aptr[0] << 8) | aptr[1]); + status = ares_expand_name(aptr + 2, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return NULL; + printf("\t%s.", name); + free(name); + break; + + case T_SOA: + /* The RR data is two domain names and then five four-byte + * numbers giving the serial number and some timeouts. + */ + p = aptr; + status = ares_expand_name(p, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return NULL; + printf("\t%s.\n", name); + free(name); + p += len; + status = ares_expand_name(p, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return NULL; + printf("\t\t\t\t\t\t%s.\n", name); + free(name); + p += len; + if (p + 20 > aptr + dlen) + return NULL; + printf("\t\t\t\t\t\t( %d %d %d %d %d )", + (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3], + (p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7], + (p[8] << 24) | (p[9] << 16) | (p[10] << 8) | p[11], + (p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15], + (p[16] << 24) | (p[17] << 16) | (p[18] << 8) | p[19]); + break; + + case T_TXT: + /* The RR data is one or more length-counted character + * strings. */ + p = aptr; + while (p < aptr + dlen) + { + len = *p; + if (p + len + 1 > aptr + dlen) + return NULL; + printf("\t%.*s", len, p + 1); + p += len + 1; + } + break; + + case T_A: + /* The RR data is a four-byte Internet address. */ + if (dlen != 4) + return NULL; + memcpy(&addr, aptr, sizeof(struct in_addr)); + printf("\t%s", inet_ntoa(addr)); + break; + + case T_WKS: + /* Not implemented yet */ + break; + + case T_SRV: + /* The RR data is three two-byte numbers representing the + * priority, weight, and port, followed by a domain name. + */ + + printf("\t%d", DNS__16BIT(aptr)); + printf(" %d", DNS__16BIT(aptr + 2)); + printf(" %d", DNS__16BIT(aptr + 4)); + + status = ares_expand_name(aptr + 6, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return NULL; + printf("\t%s.", name); + free(name); + break; + + case T_NAPTR: + /* The RR data is two two-byte numbers representing the + * order and preference, followed by three character strings + * representing flags, services, a regex, and a domain name. + */ + + printf("\t%d", DNS__16BIT(aptr)); + printf(" %d", DNS__16BIT(aptr + 2)); + + p = aptr + 4; + len = *p; + if (p + len + 1 > aptr + dlen) + return NULL; + printf(" %.*s", len, p + 1); + p += len + 1; + len = *p; + if (p + len + 1 > aptr + dlen) + return NULL; + printf(" %.*s", len, p + 1); + p += len + 1; + len = *p; + if (p + len + 1 > aptr + dlen) + return NULL; + printf(" %.*s", len, p + 1); + p += len + 1; + status = ares_expand_name(p, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return NULL; + printf("\t%s.", name); + free(name); + break; + + default: + printf("\t[Unknown RR; cannot parse]"); + } + printf("\n"); + + return aptr + dlen; +} + +static const char *type_name(int type) +{ + int i; + + for (i = 0; i < ntypes; i++) + { + if (types[i].value == type) + return types[i].name; + } + return "(unknown)"; +} + +static const char *class_name(int dnsclass) +{ + int i; + + for (i = 0; i < nclasses; i++) + { + if (classes[i].value == dnsclass) + return classes[i].name; + } + return "(unknown)"; +} + +static void usage(void) +{ + fprintf(stderr, "usage: adig [-f flag] [-s server] [-c class] " + "[-t type] [-p port] name ...\n"); + exit(1); +} diff --git a/src/libs/resiprocate/contrib/ares/ahost.c b/src/libs/resiprocate/contrib/ares/ahost.c new file mode 100644 index 00000000..2cd16084 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ahost.c @@ -0,0 +1,111 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#ifndef WIN32 +#include +#include +#include +#include +#include +#include +#include +#endif +#include +#include +#include +#include "ares.h" +#include "ares_dns.h" + +#ifndef INADDR_NONE +#define INADDR_NONE 0xffffffff +#endif + +static void callback(void *arg, int status, struct hostent *host); +static void usage(void); + +int main(int argc, char **argv) +{ + ares_channel channel; + int status, nfds; + fd_set read_fds, write_fds; + struct timeval *tvp, tv; + char *errmem; + struct in_addr addr; + + if (argc == 0) + usage(); + + status = ares_init(&channel); + if (status != ARES_SUCCESS) + { + fprintf(stderr, "ares_init: %s\n", ares_strerror(status));//, &errmem)); + ares_free_errmem(errmem); + return 1; + } + + /* Initiate the queries, one per command-line argument. */ + for (argv++; *argv; argv++) + { + addr.s_addr = inet_addr(*argv); + if (addr.s_addr == INADDR_NONE) + ares_gethostbyname(channel, *argv, AF_INET, callback, *argv); + else + { + ares_gethostbyaddr(channel, &addr, sizeof(addr), AF_INET, callback, + *argv); + } + } + + /* Wait for all queries to complete. */ + while (1) + { + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + nfds = ares_fds(channel, &read_fds, &write_fds); + if (nfds == 0) + break; + tvp = ares_timeout(channel, NULL, &tv); + select(nfds, &read_fds, &write_fds, NULL, tvp); + ares_process(channel, &read_fds, &write_fds); + } + + ares_destroy(channel); + return 0; +} + +static void callback(void *arg, int status, struct hostent *host) +{ + struct in_addr addr; + char *mem, **p; + + if (status != ARES_SUCCESS) + { + fprintf(stderr, "%s: %s\n", (char *) arg, ares_strerror(status));//, &mem)); + ares_free_errmem(mem); + return; + } + + for (p = host->h_addr_list; *p; p++) + { + memcpy(&addr, *p, sizeof(struct in_addr)); + printf("%-32s\t%s\n", host->h_name, inet_ntoa(addr)); + } +} + +static void usage(void) +{ + fprintf(stderr, "usage: ahost {host|addr} ...\n"); + exit(1); +} diff --git a/src/libs/resiprocate/contrib/ares/ares.h b/src/libs/resiprocate/contrib/ares/ares.h new file mode 100644 index 00000000..c96bae88 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares.h @@ -0,0 +1,297 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#ifndef ARES__H +#define ARES__H + +#ifdef WIN32 + #include + #include + #include + #include + #include + #include + #include + // Remove compiler warnings: "warning C4996: 'xxxxx': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _xxxxxx." + #define strdup _strdup + #define stricmp _stricmp + #define strnicmp _strnicmp + #define write _write +#endif + + +#if !defined(DNS__16BIT) +# define DNS__16BIT(p) (((p)[0] << 8) | (p)[1]) +# define DNS__32BIT(p) (((p)[0] << 24) | ((p)[1] << 16) | \ + ((p)[2] << 8) | (p)[3]) +# define DNS_HEADER_QDCOUNT(h) DNS__16BIT((h) + 4) +# define DNS_HEADER_ANCOUNT(h) DNS__16BIT((h) + 6) +# define DNS_HEADER_NSCOUNT(h) DNS__16BIT((h) + 8) +# define DNS_HEADER_ARCOUNT(h) DNS__16BIT((h) + 10) +# define DNS_RR_TYPE(r) DNS__16BIT(r) +# define DNS_RR_LEN(r) DNS__16BIT((r) + 8) +# define DNS_RR_TTL(r) DNS__32BIT((r) + 4) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(__APPLE__) +#include +#if !defined(MAC_OS_X_VERSION_MIN_REQUIRED) || (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_2) +#include +#endif +#endif + +#include +#ifndef WIN32 +/* why was this commented out?! ah, it was a 'fix for windows' */ +#include +#ifdef __ANDROID_API__ +# include +#endif +#endif + +#include "ares_socketfunc.h" + +#define ARES_SUCCESS 0 + +/* Server error codes (ARES_ENODATA indicates no relevant answer) */ +#define ARES_ENODATA 1 +#define ARES_EFORMERR 2 +#define ARES_ESERVFAIL 3 +#define ARES_ENOTFOUND 4 +#define ARES_ENOTIMP 5 +#define ARES_EREFUSED 6 + +/* Locally generated error codes */ +#define ARES_EBADQUERY 7 +#define ARES_EBADNAME 8 +#define ARES_EBADFAMILY 9 +#define ARES_EBADRESP 10 +#define ARES_ECONNREFUSED 11 +#define ARES_ETIMEOUT 12 +#define ARES_EOF 13 +#define ARES_EFILE 14 +#define ARES_ENOMEM 15 +#define ARES_EDESTRUCTION 16 + +/* Flag values */ +#define ARES_FLAG_USEVC (1 << 0) +#define ARES_FLAG_PRIMARY (1 << 1) +#define ARES_FLAG_IGNTC (1 << 2) +#define ARES_FLAG_NORECURSE (1 << 3) +#define ARES_FLAG_STAYOPEN (1 << 4) +#define ARES_FLAG_NOSEARCH (1 << 5) +#define ARES_FLAG_NOALIASES (1 << 6) +#define ARES_FLAG_NOCHECKRESP (1 << 7) +#define ARES_FLAG_TRY_NEXT_SERVER_ON_RCODE3 (1 << 8) /* when rcode of 3 ('No such name') is recvd */ + +/* Option mask values */ +#define ARES_OPT_FLAGS (1 << 0) +#define ARES_OPT_TIMEOUT (1 << 1) +#define ARES_OPT_TRIES (1 << 2) +#define ARES_OPT_NDOTS (1 << 3) +#define ARES_OPT_UDP_PORT (1 << 4) +#define ARES_OPT_TCP_PORT (1 << 5) +#define ARES_OPT_SERVERS (1 << 6) +#define ARES_OPT_DOMAINS (1 << 7) +#define ARES_OPT_LOOKUPS (1 << 8) + +/* Capability mask values */ + +#define ARES_CAP_IPV6 (1 << 0) + +typedef enum ares_poll_action { + ARES_POLLACTION_NULL= (0), + ARES_POLLACTION_OPEN= (1), // ares just opened this + ARES_POLLACTION_CLOSE= (2), // ares just closed this + ARES_POLLACTION_WRITEON= (3), // tell ares when writable + ARES_POLLACTION_WRITEOFF= (4) // don't tell ares when writable +} ares_poll_action_t; +struct ares_channeldata; +typedef void (ares_poll_cb_func)(void *cb_data, struct ares_channeldata* chan, int sockidx, + int fd, ares_poll_action_t act); + +#if defined(WIN32) || defined(sun) +typedef unsigned char u_int8_t; +#endif + +#ifdef USE_IPV6 +struct multiFamilyAddr { + u_int8_t family; + struct in6_addr addr6; + struct in_addr addr; +}; +#endif + +struct ares_options { + int flags; + int timeout; + int tries; + int ndots; + unsigned short udp_port; + unsigned short tcp_port; +#ifdef USE_IPV6 + struct multiFamilyAddr *servers; +#else + struct in_addr *servers; +#endif + int nservers; + char **domains; + int ndomains; + char *lookups; +}; + +struct hostent; +struct timeval; +struct ares_channeldata; +typedef struct ares_channeldata *ares_channel; +typedef void (*ares_callback)(void *arg, int status, unsigned char *abuf, + int alen); +typedef void (*ares_host_callback)(void *arg, int status, + struct hostent *hostent); + +extern int ares_init(ares_channel *channelptr); +extern int ares_init_with_socket_function(ares_channel *channelptr, socket_function_ptr); + +extern int ares_capabilities(int capmask); + +extern int ares_init_options(ares_channel *channelptr, struct ares_options *options, + int optmask); + +extern int ares_init_options_with_socket_function(ares_channel *channelptr, struct ares_options *options, + int optmask, socket_function_ptr); +extern void ares_destroy(ares_channel channel); +extern void ares_destroy_suppress_callbacks(ares_channel channel); + +extern void ares_destroy_internal(ares_channel channel, int suppressCallbacks); + +extern void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, + ares_callback callback, void *arg); +extern void ares_query(ares_channel channel, const char *name, int dnsclass, + int type, ares_callback callback, void *arg); +extern void ares_search(ares_channel channel, const char *name, int dnsclass, + int type, ares_callback callback, void *arg); +extern void ares_gethostbyname(ares_channel channel, const char *name, int family, + ares_host_callback callback, void *arg); +extern void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, + int family, ares_host_callback callback, void *arg); +extern int hostfile_lookup(const char *name, struct hostent **host); + +extern int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds); +extern struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv, + struct timeval *tv); +extern void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds); +extern void ares_process_set_poll_cb(ares_channel channel, ares_poll_cb_func* cb_func, void *cb_data); +extern void ares_process_poll(ares_channel channel, int server_idx, + int rdFd, int wrFd, time_t now); + + +extern int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, + int rd, unsigned char **buf, int *buflen); +extern int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, + int alen, char **s, long *enclen); +extern int ares_parse_a_reply(const unsigned char *abuf, int alen, + struct hostent **host); +extern int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, + int addrlen, int family, struct hostent **host); +extern void ares_free_string(char *str); +extern void ares_free_hostent(struct hostent *host); +extern const char *ares_strerror(int code); +extern void ares_free_errmem(char *mem); + + +#if defined(WIN32) || defined (__CYGWIN__) || defined(__ANDROID_API__) + +#define T_A 1 /* host address */ +#define T_NS 2 /* authoritative server */ +#define T_MD 3 /* mail destination */ +#define T_MF 4 /* mail forwarder */ +#define T_CNAME 5 /* canonical name */ +#define T_SOA 6 /* start of authority zone */ +#define T_MB 7 /* mailbox domain name */ +#define T_MG 8 /* mail group member */ +#define T_MR 9 /* mail rename name */ +#define T_NULL 10 /* null resource record */ +#define T_WKS 11 /* well known service */ +#define T_PTR 12 /* domain name pointer */ +#define T_HINFO 13 /* host information */ +#define T_MINFO 14 /* mailbox information */ +#define T_MX 15 /* mail routing information */ +#define T_TXT 16 /* text strings */ +#define T_RP 17 /* responsible person */ +#define T_AFSDB 18 /* AFS cell database */ +#define T_X25 19 /* X_25 calling address */ +#define T_ISDN 20 /* ISDN calling address */ +#define T_RT 21 /* router */ +#define T_NSAP 22 /* NSAP address */ +#define T_NSAP_PTR 23 /* reverse NSAP lookup (deprecated) */ +#define T_SIG 24 /* security signature */ +#define T_KEY 25 /* security key */ +#define T_PX 26 /* X.400 mail mapping */ +#define T_GPOS 27 /* geographical position (withdrawn) */ +#define T_AAAA 28 /* IP6 Address */ +#define T_LOC 29 /* Location Information */ + /* non standard */ +#define T_UINFO 100 /* user (finger) information */ +#define T_UID 101 /* user ID */ +#define T_GID 102 /* group ID */ +#define T_UNSPEC 103 /* Unspecified format (binary data) */ + /* Query type values which do not appear in resource records */ +#define T_AXFR 252 /* transfer zone of authority */ +#define T_MAILB 253 /* transfer mailbox records */ +#define T_MAILA 254 /* transfer mail agent records */ +#define T_ANY 255 /* wildcard match */ + + +#define C_IN 1 +#define C_CHAOS 3 +#define C_HS 4 +#define C_ANY 255 + +#define INDIR_MASK 0xc0 +#define HFIXEDSZ 12 +#define QFIXEDSZ 4 +#define RRFIXEDSZ 10 + +#define NOERROR 0 +#define FORMERR 1 +#define SERVFAIL 2 +#define NXDOMAIN 3 +#define NOTIMP 4 +#define REFUSED 5 + +#define PACKETSZ 512 + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 256 +#endif + +#define NS_DEFAULTPORT 53 +#define NAMESERVER_PORT NS_DEFAULTPORT + +#define QUERY 0 +#define MAXLABEL 63 + +#endif + +#if defined(__cplusplus) +} +#endif + + +#endif /* ARES__H */ diff --git a/src/libs/resiprocate/contrib/ares/ares.pro b/src/libs/resiprocate/contrib/ares/ares.pro new file mode 100644 index 00000000..f75fdbbb --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares.pro @@ -0,0 +1,58 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2010-11-29T22:20:23 +# +#------------------------------------------------- + +QT -= core gui + +TARGET = ares +TEMPLATE = lib +CONFIG += staticlib +INCLUDEPATH += ../ ../../ +DEFINES += WINVER=0x0501 USE_IPV6 + +win32 { + DESTDIR = ../../../../Libs/compiled/win +} + +SOURCES += \ + ares_timeout.c \ + ares_strerror.c \ + ares_send.c \ + ares_search.c \ + ares__read_line.c \ + ares_query.c \ + ares_process.c \ + ares_parse_ptr_reply.c \ + ares_parse_a_reply.c \ + ares_mkquery.c \ + ares_local.c \ + ares_init.c \ + ares__get_hostent.c \ + ares_gethostbyname.c \ + ares_gethostbyaddr.c \ + ares_free_string.c \ + ares_free_hostent.c \ + ares_free_errmem.c \ + ares_fds.c \ + ares_expand_name.c \ + ares_destroy.c \ + ares__close_sockets.c + +HEADERS += \ + ares_version.h \ + ares_socketfunc.h \ + ares_private.h \ + ares_local.h \ + ares_dns.h \ + ares_compat.h \ + ares.h +unix:!symbian { + maemo5 { + target.path = /opt/usr/lib + } else { + target.path = /usr/local/lib + } + INSTALLS += target +} diff --git a/src/libs/resiprocate/contrib/ares/ares_10_0.vcxproj b/src/libs/resiprocate/contrib/ares/ares_10_0.vcxproj new file mode 100644 index 00000000..5719b5c2 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_10_0.vcxproj @@ -0,0 +1,196 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + ares + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + ares + ManagedCProj + + + + StaticLibrary + MultiByte + false + v140 + + + StaticLibrary + MultiByte + false + v140 + + + StaticLibrary + false + MultiByte + false + v140 + + + StaticLibrary + false + MultiByte + false + v140 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.21006.1 + Debug\ + Debug\ + Debug\ + Debug\ + Release\ + Release\ + Release\ + Release\ + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + Disabled + $(SolutionDir)/contrib/ares;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_IPV6;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + CompileAsC + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + Disabled + $(SolutionDir)/contrib/ares;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_IPV6;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + CompileAsC + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + MaxSpeed + OnlyExplicitInline + WIN32;NDEBUG;USE_IPV6;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + MultiThreadedDLL + + + Level3 + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + MaxSpeed + OnlyExplicitInline + WIN32;NDEBUG;USE_IPV6;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + MultiThreadedDLL + + + Level3 + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/ares/ares_10_0.vcxproj.filters b/src/libs/resiprocate/contrib/ares/ares_10_0.vcxproj.filters new file mode 100644 index 00000000..9e131107 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_10_0.vcxproj.filters @@ -0,0 +1,102 @@ + + + + + {9e3fe614-9662-442b-b374-aec5b9bad845} + h;hpp;hxx;hm;inl;inc + + + {f2e854cf-73f0-440a-985a-0a76057eda91} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;r + + + {228966ed-c824-43cf-bc6c-0ffce8218a9f} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/ares/ares_7_1.vcproj b/src/libs/resiprocate/contrib/ares/ares_7_1.vcproj new file mode 100644 index 00000000..c5ce0626 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_7_1.vcproj @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/ares/ares_8_0.vcproj b/src/libs/resiprocate/contrib/ares/ares_8_0.vcproj new file mode 100644 index 00000000..c5b39009 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_8_0.vcproj @@ -0,0 +1,278 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/ares/ares_9_0.vcproj b/src/libs/resiprocate/contrib/ares/ares_9_0.vcproj new file mode 100644 index 00000000..351365b1 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_9_0.vcproj @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/ares/ares_9_0.vcxproj b/src/libs/resiprocate/contrib/ares/ares_9_0.vcxproj new file mode 100644 index 00000000..3d1a0663 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_9_0.vcxproj @@ -0,0 +1,125 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + ares + {96CD935E-1951-43B8-AF75-F1C06B3778C1} + ares + ManagedCProj + + + + StaticLibrary + v120_xp + MultiByte + false + + + StaticLibrary + v120 + false + MultiByte + false + + + + + + + + + + + + + + + <_ProjectFileVersion>12.0.21005.1 + + + $(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\ + + + $(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\ + + + + /MP %(AdditionalOptions) + Disabled + $(SolutionDir)/contrib/ares;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_IPV6;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebugDLL + false + + Level3 + ProgramDatabase + CompileAsC + + + $(OutDir)ares.lib + + + + + /MP %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + WIN32;NDEBUG;USE_IPV6;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + MultiThreadedDLL + + Level3 + ProgramDatabase + + + $(OutDir)ares.lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/ares/ares_9_0.vcxproj.filters b/src/libs/resiprocate/contrib/ares/ares_9_0.vcxproj.filters new file mode 100644 index 00000000..575e4072 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_9_0.vcxproj.filters @@ -0,0 +1,102 @@ + + + + + {40eeb60d-8eea-4026-9958-c5db72139973} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {3fb12883-71c7-411a-8587-19c7b88abdf5} + h;hpp;hxx;hm;inl;inc + + + {5b56b2f5-3097-4c73-a87a-6bc3479bae6d} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;r + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/ares/ares_9_0.vcxproj.user b/src/libs/resiprocate/contrib/ares/ares_9_0.vcxproj.user new file mode 100644 index 00000000..abe8dd89 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_9_0.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/ares/ares__close_sockets.c b/src/libs/resiprocate/contrib/ares/ares__close_sockets.c new file mode 100644 index 00000000..fcd21713 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares__close_sockets.c @@ -0,0 +1,67 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include +#ifndef WIN32 +#include +#endif + +#include "ares.h" +#include "ares_private.h" + +void ares__close_poll(ares_channel channel, int server_idx) { + if ( channel->poll_cb_func ) { + struct server_state *server = &channel->servers[server_idx]; + if ( server->udp_socket!=-1 ) + (*(channel->poll_cb_func))( channel->poll_cb_data, + channel, server_idx, server->udp_socket, ARES_POLLACTION_CLOSE); + if ( server->tcp_socket!=-1 ) + (*(channel->poll_cb_func))( channel->poll_cb_data, + channel, server_idx, server->udp_socket, ARES_POLLACTION_CLOSE); + } +} + +void ares__close_sockets(struct server_state *server) +{ + struct send_request *sendreq; + + /* Free all pending output buffers. */ + while (server->qhead) + { + /* Advance server->qhead; pull out query as we go. */ + sendreq = server->qhead; + server->qhead = sendreq->next; + free(sendreq); + } + server->qtail = NULL; + + /* Reset any existing input buffer. */ + if (server->tcp_buffer) + free(server->tcp_buffer); + server->tcp_buffer = NULL; + server->tcp_lenbuf_pos = 0; + + /* Close the TCP and UDP sockets. */ + if (server->tcp_socket != -1) + { + ares__kill_socket(server->tcp_socket); + server->tcp_socket = -1; + } + if (server->udp_socket != -1) + { + ares__kill_socket(server->udp_socket); + server->udp_socket = -1; + } +} diff --git a/src/libs/resiprocate/contrib/ares/ares__get_hostent.c b/src/libs/resiprocate/contrib/ares/ares__get_hostent.c new file mode 100644 index 00000000..7b0c41d2 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares__get_hostent.c @@ -0,0 +1,168 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#include +#include +#include +#endif + + +#include "ares.h" +#include "ares_private.h" + +int ares__get_hostent(FILE *fp, struct hostent **host) +{ + char *line = NULL, *p, *q, *canonical, **alias; + int status, linesize, end_at_hostname, naliases; + struct in_addr addr; + struct hostent *hostent = NULL; + + while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) + { + /* Skip comment lines; terminate line at comment character. */ + if (*line == '#' || !*line) + continue; + p = strchr(line, '#'); + if (p) + *p = 0; + + /* Get the address part. */ + p = line; + while (*p && !isspace((unsigned char)*p)) + p++; + if (!*p) + continue; + *p = 0; + addr.s_addr = inet_addr(line); + if (addr.s_addr == INADDR_NONE) + continue; + + /* Get the canonical hostname. */ + p++; + while (isspace((unsigned char)*p)) + p++; + if (!*p) + continue; + q = p; + while (*q && !isspace((unsigned char)*q)) + q++; + end_at_hostname = (*q == 0); + *q = 0; + canonical = p; + + naliases = 0; + if (!end_at_hostname) + { + /* Count the aliases. */ + p = q + 1; + while (isspace((unsigned char)*p)) + p++; + while (*p) + { + while (*p && !isspace((unsigned char)*p)) + p++; + while (isspace((unsigned char)*p)) + p++; + naliases++; + } + } + + /* Allocate memory for the host structure. */ + hostent = malloc(sizeof(struct hostent)); + if (!hostent) + break; + hostent->h_aliases = NULL; + hostent->h_addr_list = NULL; + hostent->h_name = strdup(canonical); + if (!hostent->h_name) + break; + hostent->h_addr_list = malloc(2 * sizeof(char *)); + if (!hostent->h_addr_list) + break; + hostent->h_addr_list[0] = malloc(sizeof(struct in_addr)); + if (!hostent->h_addr_list[0]) + break; + hostent->h_aliases = malloc((naliases + 1) * sizeof(char *)); + if (!hostent->h_aliases) + break; + + /* Copy in aliases. */ + naliases = 0; + if (!end_at_hostname) + { + p = canonical + strlen(canonical) + 1; + while (isspace((unsigned char)*p)) + p++; + while (*p) + { + q = p; + while (*q && !isspace((unsigned char)*q)) + q++; + hostent->h_aliases[naliases] = malloc(q - p + 1); + if (hostent->h_aliases[naliases] == NULL) + break; + memcpy(hostent->h_aliases[naliases], p, q - p); + hostent->h_aliases[naliases][q - p] = 0; + p = q; + while (isspace((unsigned char)*p)) + p++; + naliases++; + } + if (*p) + break; + } + hostent->h_aliases[naliases] = NULL; + + hostent->h_addrtype = AF_INET; + hostent->h_length = sizeof(struct in_addr); + memcpy(hostent->h_addr_list[0], &addr, sizeof(struct in_addr)); + hostent->h_addr_list[1] = NULL; + *host = hostent; + free(line); + return ARES_SUCCESS; + } + free(line); + + if (status == ARES_SUCCESS) + { + /* Memory allocation failure; clean up. */ + if (hostent) + { + free((char *) hostent->h_name); + if (hostent->h_aliases) + { + for (alias = hostent->h_aliases; *alias; alias++) + free(*alias); + } + free(hostent->h_aliases); + if (hostent->h_addr_list) + free(hostent->h_addr_list[0]); + free(hostent->h_addr_list); + } + free(hostent); + return ARES_ENOMEM; + } + + return status; +} diff --git a/src/libs/resiprocate/contrib/ares/ares__read_line.c b/src/libs/resiprocate/contrib/ares/ares__read_line.c new file mode 100644 index 00000000..9e827d79 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares__read_line.c @@ -0,0 +1,63 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include +#include +#include "ares.h" +#include "ares_private.h" + +/* This is an internal function. Its contract is to read a line from + * a file into a dynamically allocated buffer, zeroing the trailing + * newline if there is one. The calling routine may call + * ares__read_line multiple times with the same buf and bufsize + * pointers; *buf will be reallocated and *bufsize adjusted as + * appropriate. The initial value of *buf should be NULL. After the + * calling routine is done reading lines, it should free *buf. + */ +int ares__read_line(FILE *fp, char **buf, int *bufsize) +{ + char *newbuf; + int offset = 0, len; + + if (*buf == NULL) + { + *buf = malloc(128); + if (!*buf) + return ARES_ENOMEM; + *bufsize = 128; + } + + while (1) + { + if (!fgets(*buf + offset, *bufsize - offset, fp)) + return (offset != 0) ? 0 : (ferror(fp)) ? ARES_EFILE : ARES_EOF; + len = offset + (int)strlen(*buf + offset); + if ((*buf)[len - 1] == '\n') + { + (*buf)[len - 1] = 0; + return ARES_SUCCESS; + } + offset = len; + + /* Allocate more space. */ + newbuf = realloc(*buf, *bufsize * 2); + if (!newbuf) + return ARES_ENOMEM; + *buf = newbuf; + *bufsize *= 2; + } +} diff --git a/src/libs/resiprocate/contrib/ares/ares_compat.h b/src/libs/resiprocate/contrib/ares/ares_compat.h new file mode 100644 index 00000000..864ed019 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_compat.h @@ -0,0 +1,23 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#if !defined(T_SRV) +#define T_SRV 33 +#endif + +#if !defined(T_NAPTR) +#define T_NAPTR 35 +#endif + diff --git a/src/libs/resiprocate/contrib/ares/ares_destroy.3 b/src/libs/resiprocate/contrib/ares/ares_destroy.3 new file mode 100644 index 00000000..0c3478e7 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_destroy.3 @@ -0,0 +1,42 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_DESTROY 3 "23 July 1998" +.SH NAME +ares_destroy \- Destroy a resolver channel +.SH SYNOPSIS +.nf +.B #include +.PP +.B int ares_destroy(ares_channel \fIchannel\fP) +.fi +.SH DESCRIPTION +The +.B ares_destroy +function destroys the name service channel identified by +.IR channel , +freeing all memory and closing all sockets used by the channel. +.B ares_destroy +invokes the callbacks for each pending query on the channel, passing a +status of +.BR ARES_EDESTRUCTION . +These calls give the callbacks a chance to clean up any state which +might have been stored in their arguments. +.SH SEE ALSO +.BR ares_init (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_destroy.c b/src/libs/resiprocate/contrib/ares/ares_destroy.c new file mode 100644 index 00000000..2d7f6a50 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_destroy.c @@ -0,0 +1,61 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include "ares.h" +#include "ares_private.h" + + + +void ares_destroy(ares_channel channel) +{ + ares_destroy_internal(channel, 0); +} + +void ares_destroy_suppress_callbacks(ares_channel channel) +{ + ares_destroy_internal(channel, 1); +} + +void ares_destroy_internal(ares_channel channel, int suppressCallbacks) +{ + int i; + struct query *query; + + for (i = 0; i < channel->nservers; i++) { + ares__close_poll(channel, i); + ares__close_sockets(&channel->servers[i]); + } + free(channel->servers); + for (i = 0; i < channel->ndomains; i++) + free(channel->domains[i]); + free(channel->domains); + free(channel->sortlist); + free(channel->lookups); + while (channel->queries) + { + query = channel->queries; + channel->queries = query->next; + if (!suppressCallbacks) + { + query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0); + } + free(query->tcpbuf); + free(query->skip_server); + free(query); + } + free(channel); +} diff --git a/src/libs/resiprocate/contrib/ares/ares_dns.h b/src/libs/resiprocate/contrib/ares/ares_dns.h new file mode 100644 index 00000000..50ca37ed --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_dns.h @@ -0,0 +1,79 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#ifndef ARES__DNS_H +#define ARES__DNS_H + +#define DNS__16BIT(p) (((p)[0] << 8) | (p)[1]) +#define DNS__32BIT(p) (((p)[0] << 24) | ((p)[1] << 16) | \ + ((p)[2] << 8) | (p)[3]) +#define DNS__SET16BIT(p, v) (((p)[0] = ((v) >> 8) & 0xff), \ + ((p)[1] = (v) & 0xff)) +#define DNS__SET32BIT(p, v) (((p)[0] = ((v) >> 24) & 0xff), \ + ((p)[1] = ((v) >> 16) & 0xff), \ + ((p)[2] = ((v) >> 8) & 0xff), \ + ((p)[3] = (v) & 0xff)) + +/* Macros for parsing a DNS header */ +#define DNS_HEADER_QID(h) DNS__16BIT(h) +#define DNS_HEADER_QR(h) (((h)[2] >> 7) & 0x1) +#define DNS_HEADER_OPCODE(h) (((h)[2] >> 3) & 0xf) +#define DNS_HEADER_AA(h) (((h)[2] >> 2) & 0x1) +#define DNS_HEADER_TC(h) (((h)[2] >> 1) & 0x1) +#define DNS_HEADER_RD(h) ((h)[2] & 0x1) +#define DNS_HEADER_RA(h) (((h)[3] >> 7) & 0x1) +#define DNS_HEADER_Z(h) (((h)[3] >> 4) & 0x7) +#define DNS_HEADER_RCODE(h) ((h)[3] & 0xf) +#define DNS_HEADER_QDCOUNT(h) DNS__16BIT((h) + 4) +#define DNS_HEADER_ANCOUNT(h) DNS__16BIT((h) + 6) +#define DNS_HEADER_NSCOUNT(h) DNS__16BIT((h) + 8) +#define DNS_HEADER_ARCOUNT(h) DNS__16BIT((h) + 10) + +/* Macros for constructing a DNS header */ +#define DNS_HEADER_SET_QID(h, v) DNS__SET16BIT(h, v) +#define DNS_HEADER_SET_QR(h, v) ((h)[2] |= (((v) & 0x1) << 7)) +#define DNS_HEADER_SET_OPCODE(h, v) ((h)[2] |= (((v) & 0xf) << 3)) +#define DNS_HEADER_SET_AA(h, v) ((h)[2] |= (((v) & 0x1) << 2)) +#define DNS_HEADER_SET_TC(h, v) ((h)[2] |= (((v) & 0x1) << 1)) +#define DNS_HEADER_SET_RD(h, v) ((h)[2] |= (((v) & 0x1))) +#define DNS_HEADER_SET_RA(h, v) ((h)[3] |= (((v) & 0x1) << 7)) +#define DNS_HEADER_SET_Z(h, v) ((h)[3] |= (((v) & 0x7) << 4)) +#define DNS_HEADER_SET_RCODE(h, v) ((h)[3] |= (((v) & 0xf))) +#define DNS_HEADER_SET_QDCOUNT(h, v) DNS__SET16BIT((h) + 4, v) +#define DNS_HEADER_SET_ANCOUNT(h, v) DNS__SET16BIT((h) + 6, v) +#define DNS_HEADER_SET_NSCOUNT(h, v) DNS__SET16BIT((h) + 8, v) +#define DNS_HEADER_SET_ARCOUNT(h, v) DNS__SET16BIT((h) + 10, v) + +/* Macros for parsing the fixed part of a DNS question */ +#define DNS_QUESTION_TYPE(q) DNS__16BIT(q) +#define DNS_QUESTION_CLASS(q) DNS__16BIT((q) + 2) + +/* Macros for constructing the fixed part of a DNS question */ +#define DNS_QUESTION_SET_TYPE(q, v) DNS__SET16BIT(q, v) +#define DNS_QUESTION_SET_CLASS(q, v) DNS__SET16BIT((q) + 2, v) + +/* Macros for parsing the fixed part of a DNS resource record */ +#define DNS_RR_TYPE(r) DNS__16BIT(r) +#define DNS_RR_CLASS(r) DNS__16BIT((r) + 2) +#define DNS_RR_TTL(r) DNS__32BIT((r) + 4) +#define DNS_RR_LEN(r) DNS__16BIT((r) + 8) + +/* Macros for constructing the fixed part of a DNS resource record */ +#define DNS_RR_SET_TYPE(r,v) DNS__SET16BIT(r, v) +#define DNS_RR_SET_CLASS(r,v) DNS__SET16BIT((r) + 2, v) +#define DNS_RR_SET_TTL(r,v) DNS__SET32BIT((r) + 4, v) +#define DNS_RR_SET_LEN(r,v) DNS__SET16BIT((r) + 8, v) + +#endif /* ARES__DNS_H */ diff --git a/src/libs/resiprocate/contrib/ares/ares_expand_name.3 b/src/libs/resiprocate/contrib/ares/ares_expand_name.3 new file mode 100644 index 00000000..12ddbcc5 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_expand_name.3 @@ -0,0 +1,64 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_EXPAND_NAME 3 "23 July 1998" +.SH NAME +ares_expand_name \- Expand a DNS-encoded domain name +.SH SYNOPSIS +.nf +.B #include +.PP +.B int ares_expand_name(const unsigned char *\fIencoded\fP, +.B + const unsigned char *\fIabuf\fP, int \fIalen\fP, char **\fIs\fP, +.B int *\fIenclen\fP) +.fi +.SH DESCRIPTION +The +.B ares_expand_name +function converts a DNS-encoded domain name to a dot-separated C +string. The argument +.I encoded +gives the beginning of the encoded domain name, and the arguments +.I abuf +and +.I alen +give the containing message buffer (necessary for the processing of +indirection pointers within the encoded domain name). The result is +placed in a NUL-terminated allocated buffer, a pointer to which is +stored in the variable pointed to by +.IR s . +The length of the encoded name is stored in the variable pointed to by +.I enclen +so that the caller can advance past the encoded domain name to read +further data in the message. +.SH RETURN VALUES +.B ares_expand_name +can return any of the following values: +.TP 15 +.B ARES_SUCCESS +Expansion of the encoded name succeeded. +.TP 15 +.B ARES_EBADNAME +The encoded domain name was malformed and could not be expanded. +.TP 15 +.B ARES_ENOMEM +Memory was exhausted. +.SH SEE ALSO +.BR ares_mkquery (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_expand_name.c b/src/libs/resiprocate/contrib/ares/ares_expand_name.c new file mode 100644 index 00000000..67d47ae7 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_expand_name.c @@ -0,0 +1,158 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include + +#if !defined(WIN32) && !defined(__CYGWIN__) +#include +#include +#endif + +#include "ares.h" + +static int name_length(const unsigned char *encoded, const unsigned char *abuf, + int alen); + +/* Expand an RFC1035-encoded domain name given by encoded. The + * containing message is given by abuf and alen. The result given by + * *s, which is set to a NUL-terminated allocated buffer. *enclen is + * set to the length of the encoded name (not the length of the + * expanded name; the goal is to tell the caller how many bytes to + * move forward to get past the encoded name). + * + * In the simple case, an encoded name is a series of labels, each + * composed of a one-byte length (limited to values between 0 and 63 + * inclusive) followed by the label contents. The name is terminated + * by a zero-length label. + * + * In the more complicated case, a label may be terminated by an + * indirection pointer, specified by two bytes with the high bits of + * the first byte (corresponding to INDIR_MASK) set to 11. With the + * two high bits of the first byte stripped off, the indirection + * pointer gives an offset from the beginning of the containing + * message with more labels to decode. Indirection can happen an + * arbitrary number of times, so we have to detect loops. + * + * Since the expanded name uses '.' as a label separator, we use + * backslashes to escape periods or backslashes in the expanded name. + */ + +int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, + int alen, char **s, long *enclen) +{ + int len, indir = 0; + char *q; + const unsigned char *p; + + len = name_length(encoded, abuf, alen); + if (len == -1) + return ARES_EBADNAME; + + *s = malloc(len + 1); + if (!*s) + return ARES_ENOMEM; + q = *s; + + /* No error-checking necessary; it was all done by name_length(). */ + p = encoded; + while (*p) + { + if ((*p & INDIR_MASK) == INDIR_MASK) + { + if (!indir) + { + *enclen = (long)(p + 2 - encoded); + indir = 1; + } + p = abuf + ((*p & ~INDIR_MASK) << 8 | *(p + 1)); + } + else + { + len = *p; + p++; + while (len--) + { + if (*p == '.' || *p == '\\') + *q++ = '\\'; + *q++ = *p; + p++; + } + *q++ = '.'; + } + } + if (!indir) + *enclen = (long)(p + 1 - encoded); + + /* Nuke the trailing period if we wrote one. */ + if (q > *s) + q--; + /* Write a trailing NUL in any case. */ + *q = 0; + + return ARES_SUCCESS; +} + +/* Return the length of the expansion of an encoded domain name, or + * -1 if the encoding is invalid. + */ +static int name_length(const unsigned char *encoded, const unsigned char *abuf, + int alen) +{ + int n = 0, offset, indir = 0; + + /* Allow the caller to pass us abuf + alen and have us check for it. */ + if (encoded == abuf + alen) + return -1; + + while (*encoded) + { + if ((*encoded & INDIR_MASK) == INDIR_MASK) + { + /* Check the offset and go there. */ + if (encoded + 1 >= abuf + alen) + return -1; + offset = (*encoded & ~INDIR_MASK) << 8 | *(encoded + 1); + if (offset >= alen) + return -1; + encoded = abuf + offset; + + /* If we've seen more indirects than the message length, + * then there's a loop. + */ + if (++indir > alen) + return -1; + } + else + { + offset = *encoded; + if (encoded + offset + 1 >= abuf + alen) + return -1; + encoded++; + while (offset--) + { + n += (*encoded == '.' || *encoded == '\\') ? 2 : 1; + encoded++; + } + n++; + } + } + + /* If there were any labels at all, then the number of dots is one + * less than the number of labels, so subtract one. + */ + return (n) ? n - 1 : n; +} diff --git a/src/libs/resiprocate/contrib/ares/ares_fds.3 b/src/libs/resiprocate/contrib/ares/ares_fds.3 new file mode 100644 index 00000000..743e45e4 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_fds.3 @@ -0,0 +1,61 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_FDS 3 "23 July 1998" +.SH NAME +ares_fds \- Get file descriptors to select on for name service +.SH SYNOPSIS +.nf +.B #include +.PP +.B int ares_fds(ares_channel \fIchannel\fP, fd_set *\fIread_fds\fP, +.B fd_set *\fIwrite_fds\fP) +.fi +.SH DESCRIPTION +The +.B ares_fds +function retrieves the set of file descriptors which the calling +application should select on for reading and writing for the +processing of name service queries pending on the name service channel +identified by +.IR channel . +File descriptors will be set in the file descriptor sets pointed to by +.I read_fds +and +.I write_fds +as appropriate. File descriptors already set in +.I read_fds +and +.I write_fds +will remain set; initialization of the file descriptor sets +(using +.BR FD_ZERO ) +is the responsibility of the caller. +.SH RETURN VALUES +.B ares_fds +returns one greater than the number of the highest socket set in either +.I read_fds +or +.IR write_fds . +If no queries are active, +.B ares_fds +will return 0. +.SH SEE ALSO +.BR ares_timeout (3), +.BR ares_process (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_fds.c b/src/libs/resiprocate/contrib/ares/ares_fds.c new file mode 100644 index 00000000..932286d9 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_fds.c @@ -0,0 +1,51 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +//#include +#include "ares.h" +#include "ares_private.h" + +int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds) +{ + struct server_state *server; + int i, nfds; + + /* No queries, no file descriptors. */ + if (!channel->queries) + return 0; + + nfds = 0; + for (i = 0; i < channel->nservers; i++) + { + server = &channel->servers[i]; + if (server->udp_socket != -1) + { + FD_SET(server->udp_socket, read_fds); + if (server->udp_socket >= nfds) + nfds = server->udp_socket + 1; + } + if (server->tcp_socket != -1) + { + FD_SET(server->tcp_socket, read_fds); + if (server->qhead) + FD_SET(server->tcp_socket, write_fds); + if (server->tcp_socket >= nfds) + nfds = server->tcp_socket + 1; + } + } + return nfds; +} diff --git a/src/libs/resiprocate/contrib/ares/ares_free_errmem.3 b/src/libs/resiprocate/contrib/ares/ares_free_errmem.3 new file mode 100644 index 00000000..35085847 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_free_errmem.3 @@ -0,0 +1,41 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_FREE_ERRMEM 3 "23 July 1998" +.SH NAME +ares_free_errmem \- Free memory allocated by ares_strerror +.SH SYNOPSIS +.nf +.B #include +.PP +.B void ares_free_errmem(char *\fIerrmem\fP) +.fi +.SH DESCRIPTION +The +.B ares_free_errmem +function frees any memory which might have been allocated by the +.BR ares_strerror (3) +function. The parameter +.I errmem +should be set to the variable pointed to by the +.I memptr +argument previously passed to +.IR ares_strerror . +.SH SEE ALSO +.BR ares_strerror (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_free_errmem.c b/src/libs/resiprocate/contrib/ares/ares_free_errmem.c new file mode 100644 index 00000000..0d1e663e --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_free_errmem.c @@ -0,0 +1,25 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include "ares.h" + +/* Do nothing, for now. A future implementation may want to deal with + * internationalization, in which case ares_strerror() might allocate + * memory which we would then have to free. + */ +void ares_free_errmem(char *mem) +{ +} diff --git a/src/libs/resiprocate/contrib/ares/ares_free_hostent.3 b/src/libs/resiprocate/contrib/ares/ares_free_hostent.3 new file mode 100644 index 00000000..ea97baee --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_free_hostent.3 @@ -0,0 +1,48 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_FREE_HOSTENT 3 "23 July 1998" +.SH NAME +ares_free_hostent \- Free host structure allocated by ares functions +.SH SYNOPSIS +.nf +.B #include +.PP +.B void ares_free_hostent(struct hostent *\fIhost\fP) +.fi +.SH DESCRIPTION +The +.I ares_free_hostent +function frees a +.B struct hostent +allocated by one of the functions +.I ares_parse_a_reply +or +.IR ares_parse_ptr_reply . +.SH SEE ALSO +.BR ares_parse_a_reply (3), +.BR ares_parse_ptr_reply (3) +.SH NOTES +It is not necessary (and is not correct) to free the host structure +passed to the callback functions for +.I ares_gethostbyname +or +.IR ares_gethostbyaddr . +The ares library will automatically free such host structures when the +callback returns. +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_free_hostent.c b/src/libs/resiprocate/contrib/ares/ares_free_hostent.c new file mode 100644 index 00000000..a92059f0 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_free_hostent.c @@ -0,0 +1,35 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include "ares.h" + +#ifndef WIN32 +#include +#endif + +void ares_free_hostent(struct hostent *host) +{ + char **p; + + free(host->h_name); + for (p = host->h_aliases; *p; p++) + free(*p); + free(host->h_aliases); + free(host->h_addr_list[0]); + free(host->h_addr_list); + free(host); +} diff --git a/src/libs/resiprocate/contrib/ares/ares_free_string.3 b/src/libs/resiprocate/contrib/ares/ares_free_string.3 new file mode 100644 index 00000000..55844eb1 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_free_string.3 @@ -0,0 +1,36 @@ +.\" +.\" Copyright 2000 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_FREE_STRING 3 "4 January 2000" +.SH NAME +ares_free_string \- Free strings allocated by ares functions +.SH SYNOPSIS +.nf +.B #include +.PP +.B void ares_free_string(char *\fIstr\fP) +.fi +.SH DESCRIPTION +The +.I ares_free_string +function frees a string allocated by the +.I ares_mkquery +function. +.SH SEE ALSO +.BR ares_mkquery (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 2000 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_free_string.c b/src/libs/resiprocate/contrib/ares/ares_free_string.c new file mode 100644 index 00000000..1c611101 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_free_string.c @@ -0,0 +1,23 @@ +/* Copyright 2000 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include "ares.h" + +void ares_free_string(char *str) +{ + free(str); +} diff --git a/src/libs/resiprocate/contrib/ares/ares_gethostbyaddr.3 b/src/libs/resiprocate/contrib/ares/ares_gethostbyaddr.3 new file mode 100644 index 00000000..53f2c258 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_gethostbyaddr.3 @@ -0,0 +1,99 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_GETHOSTBYADDR 3 "24 July 1998" +.SH NAME +ares_gethostbyaddr \- Initiate a host query by address +.SH SYNOPSIS +.nf +.B #include +.PP +.B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP, +.B struct hostent *\fIhostent\fP) +.PP +.B void ares_gethostbyaddr(ares_channel \fIchannel\fP, const void *\fIaddr\fP, +.B int \fIaddrlen\fP, int \fIfamily\fP, ares_host_callback \fIcallback\fP, +.B void *\fIarg\fP) +.fi +.SH DESCRIPTION +The +.B ares_gethostbyaddr +function initiates a host query by address on the name service channel +identified by +.IR channel . +The parameters +.I addr +and +.I addrlen +give the address as a series of bytes, and +.I family +gives the type of address. When the query is complete or has failed, +the ares library will invoke +.IR callback . +Completion or failure of the query may happen immediately, or may +happen during a later call to +.BR ares_process (3) +or +.BR ares_destroy (3). +.PP +The callback argument +.I arg +is copied from the +.B ares_gethostbyaddr +argument +.IR arg . +The callback argument +.I status +indicates whether the query succeeded and, if not, how it failed. It +may have any of the following values: +.TP 19 +.B ARES_SUCCESS +The host lookup completed successfully. +.TP 19 +.B ARES_ENOTIMP +The ares library does not know how to look up addresses of type +.IR family . +.TP 19 +.B ARES_ENOTFOUND +The address +.I addr +was not found. +.TP 19 +.B ARES_ENOMEM +Memory was exhausted. +.TP 19 +.B ARES_EDESTRUCTION +The name service channel +.I channel +is being destroyed; the query will not be completed. +.PP +On successful completion of the query, the callback argument +.I hostent +points to a +.B struct hostent +containing the name of the host returned by the query. The callback +need not and should not attempt to free the memory pointed to by +.IR hostent ; +the ares library will free it when the callback returns. If the query +did not complete successfully, +.I hostent +will be +.BR NULL . +.SH SEE ALSO +.BR ares_process (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_gethostbyaddr.c b/src/libs/resiprocate/contrib/ares/ares_gethostbyaddr.c new file mode 100644 index 00000000..225fdb5b --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_gethostbyaddr.c @@ -0,0 +1,168 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include +#include +#include + +#ifndef WIN32 +#include +#include +#ifndef __CYGWIN__ +# include +#endif +#include +#endif + +#include "ares.h" +#include "ares_private.h" + +struct addr_query { + /* Arguments passed to ares_gethostbyaddr() */ + ares_channel channel; + struct in_addr addr; + ares_host_callback callback; + void *arg; + + const char *remaining_lookups; +}; + +static void next_lookup(struct addr_query *aquery); +static void addr_callback(void *arg, int status, unsigned char *abuf, + int alen); +static void end_aquery(struct addr_query *aquery, int status, + struct hostent *host); +static int file_lookup(struct in_addr *addr, struct hostent **host); + +#ifdef WIN32 +extern char w32hostspath[]; +#endif + +void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, + int family, ares_host_callback callback, void *arg) +{ + struct addr_query *aquery; + + if (family != AF_INET || addrlen != sizeof(struct in_addr)) + { + callback(arg, ARES_ENOTIMP, NULL); + return; + } + + aquery = malloc(sizeof(struct addr_query)); + if (!aquery) + { + callback(arg, ARES_ENOMEM, NULL); + return; + } + aquery->channel = channel; + memcpy(&aquery->addr, addr, sizeof(aquery->addr)); + aquery->callback = callback; + aquery->arg = arg; + aquery->remaining_lookups = channel->lookups; + + next_lookup(aquery); +} + +static void next_lookup(struct addr_query *aquery) +{ + const char *p; + char name[64]; + int a1, a2, a3, a4, status; + struct hostent *host; + unsigned long addr; + + for (p = aquery->remaining_lookups; *p; p++) + { + switch (*p) + { + case 'b': + addr = ntohl(aquery->addr.s_addr); + a1 = (addr >> 24) & 0xff; // .kw. in case signed-ness changes + a2 = (addr >> 16) & 0xff; + a3 = (addr >> 8) & 0xff; + a4 = addr & 0xff; + sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1); + aquery->remaining_lookups = p + 1; + ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback, + aquery); + return; + case 'f': + status = file_lookup(&aquery->addr, &host); + if (status != ARES_ENOTFOUND) + { + end_aquery(aquery, status, host); + return; + } + break; + } + } + end_aquery(aquery, ARES_ENOTFOUND, NULL); +} + +static void addr_callback(void *arg, int status, unsigned char *abuf, int alen) +{ + struct addr_query *aquery = (struct addr_query *) arg; + struct hostent *host; + + if (status == ARES_SUCCESS) + { + status = ares_parse_ptr_reply(abuf, alen, &aquery->addr, + sizeof(struct in_addr), AF_INET, &host); + end_aquery(aquery, status, host); + } + else if (status == ARES_EDESTRUCTION) + end_aquery(aquery, status, NULL); + else + next_lookup(aquery); +} + +static void end_aquery(struct addr_query *aquery, int status, + struct hostent *host) +{ + aquery->callback(aquery->arg, status, host); + if (host) + ares_free_hostent(host); + free(aquery); +} + +static int file_lookup(struct in_addr *addr, struct hostent **host) +{ + FILE *fp; + int status; + +#ifdef WIN32 + fp = fopen(w32hostspath, "r"); +#else + fp = fopen(PATH_HOSTS, "r"); +#endif + if (!fp) + return ARES_ENOTFOUND; + + while ((status = ares__get_hostent(fp, host)) == ARES_SUCCESS) + { + if (memcmp((*host)->h_addr, addr, sizeof(struct in_addr)) == 0) + break; + ares_free_hostent(*host); + } + fclose(fp); + if (status == ARES_EOF) + status = ARES_ENOTFOUND; + if (status != ARES_SUCCESS) + *host = NULL; + return status; +} diff --git a/src/libs/resiprocate/contrib/ares/ares_gethostbyname.3 b/src/libs/resiprocate/contrib/ares/ares_gethostbyname.3 new file mode 100644 index 00000000..0880da84 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_gethostbyname.3 @@ -0,0 +1,102 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_GETHOSTBYNAME 3 "25 July 1998" +.SH NAME +ares_gethostbyname \- Initiate a host query by name +.SH SYNOPSIS +.nf +.B #include +.PP +.B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP, +.B struct hostent *\fIhostent\fP) +.PP +.B void ares_gethostbyname(ares_channel \fIchannel\fP, const char *\fIname\fP, +.B int \fIfamily\fP, ares_host_callback \fIcallback\fP, void *\fIarg\fP) +.fi +.SH DESCRIPTION +The +.B ares_gethostbyname +function initiates a host query by name on the name service channel +identified by +.IR channel . +The parameter +.I name +gives the hostname as a NUL-terminated C string, and +.I family +gives the desired type of address for the resulting host entry. When +the query is complete or has failed, the ares library will invoke +.IR callback . +Completion or failure of the query may happen immediately, or may +happen during a later call to +.BR ares_process (3) +or +.BR ares_destroy (3). +.PP +The callback argument +.I arg +is copied from the +.B ares_gethostbyname +argument +.IR arg . +The callback argument +.I status +indicates whether the query succeeded and, if not, how it failed. It +may have any of the following values: +.TP 19 +.B ARES_SUCCESS +The host lookup completed successfully. +.TP 19 +.B ARES_ENOTIMP +The ares library does not know how to find addresses of type +.IR family . +.TP 19 +.B ARES_EBADNAME +The hostname +.B name +is composed entirely of numbers and periods, but is not a valid +representation of an Internet address. +.TP 19 +.B ARES_ENOTFOUND +The address +.I addr +was not found. +.TP 19 +.B ARES_ENOMEM +Memory was exhausted. +.TP 19 +.B ARES_EDESTRUCTION +The name service channel +.I channel +is being destroyed; the query will not be completed. +.PP +On successful completion of the query, the callback argument +.I hostent +points to a +.B struct hostent +containing the name of the host returned by the query. The callback +need not and should not attempt to free the memory pointed to by +.IR hostent ; +the ares library will free it when the callback returns. If the query +did not complete successfully, +.I hostent +will be +.BR NULL . +.SH SEE ALSO +.BR ares_process (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_gethostbyname.c b/src/libs/resiprocate/contrib/ares/ares_gethostbyname.c new file mode 100644 index 00000000..5b91998c --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_gethostbyname.c @@ -0,0 +1,303 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#include +#include +#ifndef __CYGWIN__ +# include +#endif +#include +#endif + +#include "ares.h" +#include "ares_private.h" +#include "ares_local.h" + +struct host_query { + /* Arguments passed to ares_gethostbyname() */ + ares_channel channel; + char *name; + ares_host_callback callback; + void *arg; + + const char *remaining_lookups; +}; + +static void next_lookup(struct host_query *hquery); +static void host_callback(void *arg, int status, unsigned char *abuf, + int alen); +static void end_hquery(struct host_query *hquery, int status, + struct hostent *host); +static int fake_hostent(const char *name, ares_host_callback callback, + void *arg); +static int file_lookup(const char *name, struct hostent **host); +static void sort_addresses(struct hostent *host, struct apattern *sortlist, + int nsort); +static int get_address_index(struct in_addr *addr, struct apattern *sortlist, + int nsort); + +#ifdef WIN32 +extern char w32hostspath[]; +#endif + +void ares_gethostbyname(ares_channel channel, const char *name, int family, + ares_host_callback callback, void *arg) +{ + struct host_query *hquery; + + /* See if request can be handled by local pseudo-domain DNS */ + if (ares_local_gethostbyname(channel, name, family, callback, arg)) + { + return; + } + + /* Right now we only know how to look up Internet addresses. */ + if (family != AF_INET) + { + callback(arg, ARES_ENOTIMP, NULL); + return; + } + + if (fake_hostent(name, callback, arg)) + return; + + /* Allocate and fill in the host query structure. */ + hquery = malloc(sizeof(struct host_query)); + if (!hquery) + { + callback(arg, ARES_ENOMEM, NULL); + return; + } + hquery->channel = channel; + hquery->name = strdup(name); + if (!hquery->name) + { + free(hquery); + callback(arg, ARES_ENOMEM, NULL); + return; + } + hquery->callback = callback; + hquery->arg = arg; + hquery->remaining_lookups = channel->lookups; + + /* Start performing lookups according to channel->lookups. */ + next_lookup(hquery); +} + +static void next_lookup(struct host_query *hquery) +{ + int status; + const char *p; + struct hostent *host; + + for (p = hquery->remaining_lookups; *p; p++) + { + switch (*p) + { + case 'b': + /* DNS lookup */ + hquery->remaining_lookups = p + 1; + ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, + hquery); + return; + + case 'f': + /* Host file lookup */ + status = file_lookup(hquery->name, &host); + if (status != ARES_ENOTFOUND) + { + end_hquery(hquery, status, host); + return; + } + break; + } + } + end_hquery(hquery, ARES_ENOTFOUND, NULL); +} + +static void host_callback(void *arg, int status, unsigned char *abuf, int alen) +{ + struct host_query *hquery = (struct host_query *) arg; + ares_channel channel = hquery->channel; + struct hostent *host; + + if (status == ARES_SUCCESS) + { + status = ares_parse_a_reply(abuf, alen, &host); + if (host && channel->nsort) + sort_addresses(host, channel->sortlist, channel->nsort); + end_hquery(hquery, status, host); + } + else if (status == ARES_EDESTRUCTION) + end_hquery(hquery, status, NULL); + else + next_lookup(hquery); +} + +static void end_hquery(struct host_query *hquery, int status, + struct hostent *host) +{ + hquery->callback(hquery->arg, status, host); + if (host) + ares_free_hostent(host); + free(hquery->name); + free(hquery); +} + +/* If the name looks like an IP address, fake up a host entry, end the + * query immediately, and return true. Otherwise return false. + */ +static int fake_hostent(const char *name, ares_host_callback callback, + void *arg) +{ + struct in_addr addr; + struct hostent hostent; + const char *p; + char *aliases[1] = { NULL }; + char *addrs[2]; + + /* It only looks like an IP address if it's all numbers and dots. */ + for (p = name; *p; p++) + { + if (!isdigit((unsigned char)*p) && *p != '.') + return 0; + } + + /* It also only looks like an IP address if it's non-zero-length and + * doesn't end with a dot. + */ + if (p == name || *(p - 1) == '.') + return 0; + + /* It looks like an IP address. Figure out what IP address it is. */ + addr.s_addr = inet_addr(name); + if (addr.s_addr == INADDR_NONE) + { + callback(arg, ARES_EBADNAME, NULL); + return 1; + } + + /* Duplicate the name, to avoid a constness violation. */ + hostent.h_name = strdup(name); + if (!hostent.h_name) + { + callback(arg, ARES_ENOMEM, NULL); + return 1; + } + + /* Fill in the rest of the host structure and terminate the query. */ + addrs[0] = (char *) &addr; + addrs[1] = NULL; + hostent.h_aliases = aliases; + hostent.h_addrtype = AF_INET; + hostent.h_length = sizeof(struct in_addr); + hostent.h_addr_list = addrs; + callback(arg, ARES_SUCCESS, &hostent); + + free(hostent.h_name); + return 1; +} + +int hostfile_lookup(const char *name, struct hostent **host) +{ + return file_lookup(name, host); +} + +static int file_lookup(const char *name, struct hostent **host) +{ + FILE *fp; + char **alias; + int status; + +#ifdef WIN32 + fp = fopen(w32hostspath, "r"); +#else + fp = fopen(PATH_HOSTS, "r"); +#endif + if (!fp) + return ARES_ENOTFOUND; + + while ((status = ares__get_hostent(fp, host)) == ARES_SUCCESS) + { + if (strcasecmp((*host)->h_name, name) == 0) + break; + for (alias = (*host)->h_aliases; *alias; alias++) + { + if (strcasecmp(*alias, name) == 0) + break; + } + if (*alias) + break; + ares_free_hostent(*host); + } + fclose(fp); + if (status == ARES_EOF) + status = ARES_ENOTFOUND; + if (status != ARES_SUCCESS) + *host = NULL; + return status; +} + +static void sort_addresses(struct hostent *host, struct apattern *sortlist, + int nsort) +{ + struct in_addr a1, a2; + int i1, i2, ind1, ind2; + + /* This is a simple insertion sort, not optimized at all. i1 walks + * through the address list, with the loop invariant that everything + * to the left of i1 is sorted. In the loop body, the value at i1 is moved + * back through the list (via i2) until it is in sorted order. + */ + for (i1 = 0; host->h_addr_list[i1]; i1++) + { + memcpy(&a1, host->h_addr_list[i1], sizeof(struct in_addr)); + ind1 = get_address_index(&a1, sortlist, nsort); + for (i2 = i1 - 1; i2 >= 0; i2--) + { + memcpy(&a2, host->h_addr_list[i2], sizeof(struct in_addr)); + ind2 = get_address_index(&a2, sortlist, nsort); + if (ind2 <= ind1) + break; + memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in_addr)); + } + memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in_addr)); + } +} + +/* Find the first entry in sortlist which matches addr. Return nsort + * if none of them match. + */ +static int get_address_index(struct in_addr *addr, struct apattern *sortlist, + int nsort) +{ + int i; + + for (i = 0; i < nsort; i++) + { + if ((addr->s_addr & sortlist[i].mask.s_addr) == sortlist[i].addr.s_addr) + break; + } + return i; +} diff --git a/src/libs/resiprocate/contrib/ares/ares_init.3 b/src/libs/resiprocate/contrib/ares/ares_init.3 new file mode 100644 index 00000000..95c99c7f --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_init.3 @@ -0,0 +1,169 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_INIT 3 "21 July 1998" +.SH NAME +ares_init, ares_init_options \- Initialize a resolver channel +.SH SYNOPSIS +.nf +.B #include +.PP +.B int ares_init(ares_channel *\fIchannel\fP) +.B int ares_init_options(ares_channel *\fIchannel\fP, +.B struct ares_options *\fIoptions\fP, int \fIoptmask\fP) +.PP +.B cc file.c -lares +.fi +.SH DESCRIPTION +The +.B ares_init +function initializes a communications channel for name service +lookups. If it returns successfully, +.B ares_init +will set the variable pointed to by +.I channel +to a handle used to identify the name service channel. The caller +should invoke +.BR ares_destroy (3) +on the handle when the channel is no longer needed. +.PP +The +.B ares_init_options +function also initializes a name service channel, with additional +options useful for applications requiring more control over name +service configuration. The +.I optmask +parameter specifies which fields in the structure pointed to by +.I options +are set, as follows: +.PP +.TP 18 +.B ARES_OPT_FLAGS +.B int \fIflags\fP; +.br +Flags controlling the behavior of the resolver. See below for a +description of possible flag values. +.TP 18 +.B ARES_OPT_TIMEOUT +.B int \fItimeout\fP; +.br +The number of seconds each name server is given to respond to a query +on the first try. (After the first try, the timeout algorithm becomes +more complicated, but scales linearly with the value of +\fItimeout\fP.) The default is five seconds. +.TP 18 +.B ARES_OPT_TRIES +.B int \fItries\fP; +.br +The number of tries the resolver will try contacting each name server +before giving up. The default is four tries. +.TP 18 +.B ARES_OPT_NDOTS +.B int \fIndots\fP; +.br +The number of dots which must be present in a domain name for it to be +queried for "as is" prior to querying for it with the default domain +extensions appended. The default value is 1 unless set otherwise by +resolv.conf or the RES_OPTIONS environment variable. +.TP 18 +.B ARES_OPT_PORT +.B unsigned short \fIport\fP; +.br +The port to use for queries (both TCP and UDP), in network byte order. +The default value is 53 (in network byte order), the standard name +service port. +.TP 18 +.B ARES_OPT_SERVERS +.B struct in_addr *\fIservers\fP; +.br +.B int \fInservers\fP; +.br +The list of servers to contact, instead of the servers specified in +resolv.conf or the local named. +.TP 18 +.B ARES_OPT_DOMAINS +.B char **\fIdomains\fP; +.br +.B int \fIndomains\fP; +.br +The domains to search, instead of the domains specified in resolv.conf +or the domain derived from the kernel hostname variable. +.TP 18 +.B ARES_OPT_LOOKUPS +.B char *\fIlookups\fP; +.br +The lookups to perform for host queries. +.I lookups +should be set to a string of the characters "b" or "f", where "b" +indicates a DNS lookup and "f" indicates a lookup in the hosts file. +.PP +The +.I flags +field should be the bitwise or of some subset of the following values: +.TP 23 +.B ARES_FLAG_USEVC +Always use TCP queries (the "virtual circuit") instead of UDP +queries. Normally, TCP is only used if a UDP query yields a truncated +result. +.TP 23 +.B ARES_FLAG_PRIMARY +Only query the first server in the list of servers to query. +.TP 23 +.B ARES_FLAG_IGNTC +If a truncated response to a UDP query is received, do not fall back +to TCP; simply continue on with the truncated response. +.TP 23 +.B ARES_FLAG_NORECURSE +Do not set the "recursion desired" bit on outgoing queries, so that +the name server being contacted will not try to fetch the answer from +other servers if it doesn't know the answer locally. +.TP 23 +.B ARES_FLAG_STAYOPEN +Do not close communciations sockets when the number of active queries +drops to zero. +.TP 23 +.B ARES_FLAG_NOSEARCH +Do not use the default search domains; only query hostnames as-is or +as aliases. +.TP 23 +.B ARES_FLAG_NOALIASES +Do not honor the HOSTALIASES environment variable, which normally +specifies a file of hostname translations. +.TP 23 +.B ARES_FLAG_NOCHECKRESP +Do not discard responses with the SERVFAIL, NOTIMP, or REFUSED +response code or responses whose questions don't match the questions +in the request. Primarily useful for writing clients which might be +used to test or debug name servers. +.SH RETURN VALUES +.I ares_init +or +.I ares_init_options +can return any of the following values: +.TP 14 +.B ARES_SUCCESS +Initialization succeeded. +.TP 14 +.B ARES_EFILE +A configuration file could not be read. +.TP 14 +.B ARES_ENOMEM +The process's available memory was exhausted. +.SH SEE ALSO +.BR ares_destroy (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_init.c b/src/libs/resiprocate/contrib/ares/ares_init.c new file mode 100644 index 00000000..15508c76 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_init.c @@ -0,0 +1,1194 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#include +#include +#include +#include +#ifndef __CYGWIN__ +# include +#endif +#include +#include +#include +#else +#include +#include +#include +#include +#endif + +#include "ares.h" +#include "ares_private.h" + +#if defined(__APPLE__) || defined(__MACH__) +#include +#define __CF_USE_FRAMEWORK_INCLUDES__ +#include +#endif + +static int init_by_options(ares_channel channel, struct ares_options *options, + int optmask); +static int init_by_environment(ares_channel channel); +static int init_by_resolv_conf(ares_channel channel); +static int init_by_defaults(ares_channel channel); +static int config_domain(ares_channel channel, char *str); +static int config_lookup(ares_channel channel, const char *str); +static int config_nameserver(struct server_state **servers, int *nservers, + const char *str); +static int config_sortlist(struct apattern **sortlist, int *nsort, + const char *str); +static int set_search(ares_channel channel, const char *str); +static int set_options(ares_channel channel, const char *str); +static char *try_config(char *s, char *opt); +static const char *try_option(const char *p, const char *q, const char *opt); +static int ip_addr(const char *s, int len, struct in_addr *addr); +static void natural_mask(struct apattern *pat); +static int find_server(struct server_state *servers, int nservers, struct in_addr addr); +static int get_physical_address(char *physicalAddr, int physicalAddrBufSz, int* physAddrLen, struct in_addr addr); + +static int inet_pton4(const char *src, u_char *dst); +#ifdef USE_IPV6 +static int inet_pton6(const char *src, u_char *dst); +#endif + +#ifdef WIN32 +char w32hostspath[256]; +#endif + + +int ares_capabilities(int capmask) +{ +#ifdef USE_IPV6 + static int ares_caps = ARES_CAP_IPV6; +#else + static int ares_caps = 0; +#endif + return (capmask & ares_caps); +} + +int ares_init(ares_channel *channelptr) +{ + return ares_init_options_with_socket_function(channelptr, NULL, 0, NULL); +} + +int ares_init_with_socket_function(ares_channel *channelptr, socket_function_ptr socketFunc) +{ + return ares_init_options_with_socket_function(channelptr, NULL, 0, socketFunc); +} + +int ares_init_options(ares_channel *channelptr, struct ares_options *options, + int optmask) +{ + return ares_init_options_with_socket_function(channelptr, options, optmask, NULL); +} + +int ares_init_options_with_socket_function(ares_channel *channelptr, struct ares_options *options, + int optmask, socket_function_ptr socketFunc) +{ + ares_channel channel; + int i, status; + struct server_state *server; +#ifdef WIN32 + { + HKEY hKey; + char hostpath[256]; + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + DWORD dwSize = sizeof(hostpath); + if(RegQueryValueEx(hKey, TEXT("DatabasePath"), 0, 0, (LPBYTE)&hostpath, &dwSize) == ERROR_SUCCESS) + { + hostpath[dwSize] = '\0'; +#if defined(UNDER_CE) + ZeroMemory(hostpath,strlen(hostpath)*sizeof(TCHAR)); +#else + ExpandEnvironmentStrings(hostpath, w32hostspath, sizeof(w32hostspath)); +#endif + if(strlen(w32hostspath) < sizeof(w32hostspath) - 6) + { + strcat(w32hostspath, "\\hosts"); + } + } + RegCloseKey(hKey); + } + } +#endif + // struct timeval tv; + + channel = malloc(sizeof(struct ares_channeldata)); + if (!channel) + return ARES_ENOMEM; + + /* Set everything to distinguished values so we know they haven't + * been set yet. + */ + channel->socket_function = socketFunc; + channel->poll_cb_func = NULL; + channel->poll_cb_data = NULL; + channel->flags = -1; + channel->timeout = -1; + channel->tries = -1; + channel->ndots = -1; + channel->udp_port = -1; + channel->tcp_port = -1; + channel->nservers = -1; + channel->ndomains = -1; + channel->nsort = -1; + channel->lookups = NULL; + + /* Initialize configuration by each of the four sources, from highest + * precedence to lowest. + */ + status = init_by_options(channel, options, optmask); + if (status == ARES_SUCCESS || !channel->nservers) + { + status = init_by_environment(channel); + if (status == ARES_SUCCESS) + status = init_by_resolv_conf(channel); + if (status == ARES_SUCCESS) + status = init_by_defaults(channel); + } + + if (status != ARES_SUCCESS) + { + /* Something failed; clean up memory we may have allocated. */ + if (channel->nservers != -1) + free(channel->servers); + if (channel->ndomains != -1) + { + for (i = 0; i < channel->ndomains; i++) + free(channel->domains[i]); + free(channel->domains); + } + if (channel->nsort != -1) + free(channel->sortlist); + free(channel->lookups); + free(channel); + return status; + } + + /* Trim to one server if ARES_FLAG_PRIMARY is set. */ + if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1) + channel->nservers = 1; + + /* Initialize server states. */ + for (i = 0; i < channel->nservers; i++) + { + server = &channel->servers[i]; + server->udp_socket = -1; + server->tcp_socket = -1; + server->tcp_lenbuf_pos = 0; + server->tcp_buffer = NULL; + server->qhead = NULL; + server->qtail = NULL; + } + + /* Choose a somewhat random query ID. The main point is to avoid + * collisions with stale queries. An attacker trying to spoof a DNS + * answer also has to guess the query ID, but it's only a 16-bit + * field, so there's not much to be done about that. + */ +// gettimeofday(&tv, NULL); +// channel->next_id = (tv.tv_sec ^ tv.tv_usec ^ getpid()) & 0xffff; + { + static int cjNextID=1; + channel->next_id = cjNextID++; + } + + channel->queries = NULL; + + *channelptr = channel; + return ARES_SUCCESS; +} + +static int init_by_options(ares_channel channel, struct ares_options *options, + int optmask) +{ + int i; + + /* Easy stuff. */ + if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1) + channel->flags = options->flags; + if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1) + channel->timeout = options->timeout; + if ((optmask & ARES_OPT_TRIES) && channel->tries == -1) + channel->tries = options->tries; + if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1) + channel->ndots = options->ndots; + if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1) + channel->udp_port = options->udp_port; + if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1) + channel->tcp_port = options->tcp_port; + + /* Copy the servers, if given. */ + if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1 && options->nservers>0 ) + { + channel->servers = + malloc(options->nservers * sizeof(struct server_state)); + if (channel->servers == NULL) + return ARES_ENOMEM; + memset(channel->servers, '\0', options->nservers * sizeof(struct server_state)); + for (i = 0; i < options->nservers; i++) + { +#ifdef USE_IPV6 + channel->servers[i].family = options->servers[i].family; + if (options->servers[i].family == AF_INET6) + { + channel->servers[i].addr6 = options->servers[i].addr6; + } + else + { + assert( channel->servers[i].family == AF_INET ); + channel->servers[i].addr = options->servers[i].addr; + } +#else + channel->servers[i].addr = options->servers[i]; +#endif + // .kw. why is this inside the loop? + channel->nservers = options->nservers; + } + } + + /* Copy the domains, if given. Keep channel->ndomains consistent so + * we can clean up in case of error. + */ + if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1) + { + channel->domains = malloc(options->ndomains * sizeof(char *)); + if (!channel->domains && options->ndomains != 0) + return ARES_ENOMEM; + for (i = 0; i < options->ndomains; i++) + { + channel->ndomains = i; + channel->domains[i] = strdup(options->domains[i]); + if (!channel->domains[i]) + return ARES_ENOMEM; + } + channel->ndomains = options->ndomains; + } + + /* Set lookups, if given. */ + if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups) + { + channel->lookups = strdup(options->lookups); + if (!channel->lookups) + return ARES_ENOMEM; + } + + return ARES_SUCCESS; +} + +static int init_by_environment(ares_channel channel) +{ + const char *localdomain, *res_options; + int status; + +#if defined(UNDER_CE) + localdomain = NULL; +#else + localdomain = getenv("LOCALDOMAIN"); +#endif + if (localdomain && channel->ndomains == -1) + { + status = set_search(channel, localdomain); + if (status != ARES_SUCCESS) + return status; + } + +#if defined(UNDER_CE) + res_options = NULL; +#else + res_options = getenv("RES_OPTIONS"); +#endif + if (res_options) + { + status = set_options(channel, res_options); + if (status != ARES_SUCCESS) + return status; + } + + return ARES_SUCCESS; +} + +static int init_by_resolv_conf(ares_channel channel) +{ + FILE *fp; + char *line = NULL, *p; + int linesize, status, nservers = 0, nsort = 0; + struct server_state *servers = NULL; + struct apattern *sortlist = NULL; + + fp = fopen(PATH_RESOLV_CONF, "r"); +#if defined(UNDER_CE) + errno = ENOENT; +#endif + if (!fp) + return (errno == ENOENT) ? ARES_SUCCESS : ARES_EFILE; + while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) + { + if ((p = try_config(line, "domain")) && channel->ndomains == -1) + status = config_domain(channel, p); + else if ((p = try_config(line, "lookup")) && !channel->lookups) + status = config_lookup(channel, p); + else if ((p = try_config(line, "search")) && channel->ndomains == -1) + status = set_search(channel, p); + else if ((p = try_config(line, "nameserver")) && channel->nservers == -1) + status = config_nameserver(&servers, &nservers, p); + else if ((p = try_config(line, "sortlist")) && channel->nsort == -1) + status = config_sortlist(&sortlist, &nsort, p); + else if ((p = try_config(line, "options"))) + status = set_options(channel, p); + else + status = ARES_SUCCESS; + if (status != ARES_SUCCESS) + break; + } + free(line); + fclose(fp); + + /* Handle errors. */ + if (status != ARES_EOF) + { + free(servers); + free(sortlist); + return status; + } + + /* If we got any name server entries, fill them in. */ + if (servers) + { + channel->servers = servers; + channel->nservers = nservers; + } + + /* If we got any sortlist entries, fill them in. */ + if (sortlist) + { + channel->sortlist = sortlist; + channel->nsort = nsort; + } + + return ARES_SUCCESS; +} + +#if defined(__APPLE__) || defined(__MACH__) +static void init_by_defaults_systemconfiguration(ares_channel channel) +{ + SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL}; + SCDynamicStoreRef store = 0; + + channel->nservers = 0; + // .amr. iPhone/iOS SDK's don't support SCDynamicStoreCreate so in that case fall back + // to the nservers=0 case. +#ifndef TARGET_OS_IPHONE + store = SCDynamicStoreCreate(NULL, CFSTR("init_by_defaults_systemconfiguration"), NULL, &context); + + if (store) + { + // kSCDynamicStoreDomainState/kSCCompNetwork/kSCCompGlobal/kSCEntNetDNS + CFStringRef key = CFSTR("State:/Network/Global/DNS"); + CFDictionaryRef dnsDict = SCDynamicStoreCopyValue(store, key); + + if (dnsDict) + { + CFArrayRef addresses = (CFArrayRef) CFDictionaryGetValue(dnsDict, kSCPropNetDNSServerAddresses); + if (addresses) + { + //CFShow(addresses); + channel->nservers = CFArrayGetCount(addresses); + channel->servers = malloc(channel->nservers * sizeof(struct server_state)); + memset(channel->servers, '\0', channel->nservers * sizeof(struct server_state)); + + int i; + for (i = 0; i < channel->nservers; i++) + { + CFStringRef address = CFArrayGetValueAtIndex(addresses, i); + //CFShow(address); + const int kBufferSize = 20; + char str[kBufferSize]; + + CFStringGetCString(address, str, kBufferSize, kCFStringEncodingUTF8); + inet_pton4(str, (u_char*)&channel->servers[i].addr); +#ifdef USE_IPV6 + channel->servers[i].family = AF_INET; +#endif + } + } + + CFRelease(dnsDict); + } + + CFRelease(store); + } +#endif // TARGET_OS_IPHONE + + /* If no specified servers, try a local named. */ + if (channel->nservers == 0) + { + channel->servers = malloc(sizeof(struct server_state)); + memset(channel->servers, '\0', sizeof(struct server_state)); + +#ifdef USE_IPV6 + channel->servers[0].family = AF_INET; +#endif + + channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK); + channel->servers[0].default_localhost_server = 1; + channel->nservers = 1; + } +} +#endif + +static int init_by_defaults(ares_channel channel) +{ + char hostname[MAXHOSTNAMELEN + 1]; + + if (channel->flags == -1) + channel->flags = 0; + if (channel->timeout == -1) + channel->timeout = DEFAULT_TIMEOUT; + if (channel->tries == -1) + channel->tries = DEFAULT_TRIES; + if (channel->ndots == -1) + channel->ndots = 1; + if (channel->udp_port == -1) + channel->udp_port = htons(NAMESERVER_PORT); + if (channel->tcp_port == -1) + channel->tcp_port = htons(NAMESERVER_PORT); + + if (channel->nservers == -1) + { +#ifdef WIN32 + /* + * Way of getting nameservers that should work on all Windows from 98 on. + */ + FIXED_INFO * FixedInfo; + ULONG ulOutBufLen; + DWORD dwRetVal; + IP_ADDR_STRING * pIPAddr; + HANDLE hLib; + int num; + + typedef DWORD (WINAPI *GetNetworkParamsType)(FIXED_INFO*, DWORD*); + GetNetworkParamsType GetNetworkParams = NULL; + + hLib = LoadLibrary(TEXT("iphlpapi.dll")); + if(!hLib) + { + return ARES_ENOTIMP; + } + + GetNetworkParams = (GetNetworkParamsType)GetProcAddress(hLib, "GetNetworkParams"); + if(!GetNetworkParams) + { + FreeLibrary(hLib); + return ARES_ENOTIMP; + } + //printf("ARES: figuring out DNS servers\n"); + FixedInfo = (FIXED_INFO *) GlobalAlloc( GPTR, sizeof( FIXED_INFO ) ); + ulOutBufLen = sizeof( FIXED_INFO ); + + if( ERROR_BUFFER_OVERFLOW == (*GetNetworkParams)( FixedInfo, &ulOutBufLen ) ) + { + GlobalFree( FixedInfo ); + FixedInfo = (FIXED_INFO *)GlobalAlloc( GPTR, ulOutBufLen ); + } + + if ( dwRetVal = (*GetNetworkParams)( FixedInfo, &ulOutBufLen ) ) + { + //printf("ARES: couldn't get network params\n"); + GlobalFree( FixedInfo ); + FreeLibrary(hLib); + return ARES_ENODATA; + } + else + { + /** + printf( "Host Name: %s\n", FixedInfo -> HostName ); + printf( "Domain Name: %s\n", FixedInfo -> DomainName ); + printf( "DNS Servers:\n" ); + printf( "\t%s\n", FixedInfo -> DnsServerList.IpAddress.String ); + **/ + + // Count how many nameserver entries we have and allocate memory for them. + num = 0; + pIPAddr = &FixedInfo->DnsServerList; + while ( pIPAddr && strlen(pIPAddr->IpAddress.String) > 0) + { + num++; + pIPAddr = pIPAddr ->Next; + } + if(num>0) + { + channel->servers = malloc( (num) * sizeof(struct server_state)); + if (!channel->servers) + { + GlobalFree( FixedInfo ); + FreeLibrary(hLib); + return ARES_ENOMEM; + } + memset(channel->servers, '\0', num * sizeof(struct server_state)); + + channel->nservers = 0; + pIPAddr = &FixedInfo->DnsServerList; + while ( pIPAddr && strlen(pIPAddr->IpAddress.String) > 0) + { + struct in_addr addr; + addr.s_addr = inet_addr(pIPAddr->IpAddress.String); + // append unique only + if (find_server(channel->servers, channel->nservers, addr) == -1) + { + // printf( "ARES: %s\n", pIPAddr ->IpAddress.String ); +#ifdef USE_IPV6 + channel->servers[ channel->nservers ].family = AF_INET; +#endif + channel->servers[channel->nservers].addr = addr; + if ((channel->flags & ARES_FLAG_TRY_NEXT_SERVER_ON_RCODE3)) + { + get_physical_address(channel->servers[channel->nservers].physical_addr, + MAX_ADAPTER_ADDRESS_LENGTH, + &channel->servers[channel->nservers].physical_addr_len, + addr); + } + channel->nservers++; + } + + pIPAddr = pIPAddr ->Next; + } + //printf("ARES: got all %d nameservers\n",num); + } + else + { + /* If no specified servers, try a local named. */ + channel->servers = malloc(sizeof(struct server_state)); + if (!channel->servers) + return ARES_ENOMEM; + memset(channel->servers, '\0', sizeof(struct server_state)); + +#ifdef USE_IPV6 + channel->servers[0].family = AF_INET; +#endif + + channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK); + channel->servers[0].default_localhost_server = 1; + channel->nservers = 1; + } + + GlobalFree( FixedInfo ); + FreeLibrary(hLib); + } +#elif defined(__APPLE__) || defined(__MACH__) + init_by_defaults_systemconfiguration(channel); +#else + /* If nobody specified servers, try a local named. */ + channel->servers = malloc(sizeof(struct server_state)); + if (!channel->servers) + return ARES_ENOMEM; + memset(channel->servers, '\0', sizeof(struct server_state)); + + // need a way to test here if v4 or v6 is running + // if v4 is running... + channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK); + channel->servers[0].default_localhost_server = 1; + + // if v6 is running... + // channel->servers[0].addr6.s_addr = htonl6(IN6ADDR_LOOPBACK_INIT); + // hard to decide if there is one server or two here + channel->nservers = 1; +#endif + + } + + if (channel->ndomains == -1) + { + /* Derive a default domain search list from the kernel hostname, + * or set it to empty if the hostname isn't helpful. + */ + if (gethostname(hostname, sizeof(hostname)) == -1 + || !strchr(hostname, '.')) + { + channel->domains = 0; // malloc(0); + channel->ndomains = 0; + } + else + { + channel->domains = malloc(sizeof(char *)); + if (!channel->domains) + return ARES_ENOMEM; + channel->ndomains = 0; + channel->domains[0] = strdup(strchr(hostname, '.') + 1); + if (!channel->domains[0]) + return ARES_ENOMEM; + channel->ndomains = 1; + } + } + + if (channel->nsort == -1) + { + channel->sortlist = NULL; + channel->nsort = 0; + } + + if (!channel->lookups) + { + channel->lookups = strdup("bf"); + if (!channel->lookups) + return ARES_ENOMEM; + } + + return ARES_SUCCESS; +} + +static int config_domain(ares_channel channel, char *str) +{ + char *q; + + /* Set a single search domain. */ + q = str; + while (*q && !isspace((unsigned char)*q)) + q++; + *q = 0; + return set_search(channel, str); +} + +static int config_lookup(ares_channel channel, const char *str) +{ + char lookups[3], *l; + const char *p; + + /* Set the lookup order. Only the first letter of each work + * is relevant, and it has to be "b" for DNS or "f" for the + * host file. Ignore everything else. + */ + l = lookups; + p = str; + while (*p) + { + if ((*p == 'b' || *p == 'f') && l < lookups + 2) + *l++ = *p; + while (*p && !isspace((unsigned char)*p)) + p++; + while (isspace((unsigned char)*p)) + p++; + } + *l = 0; + channel->lookups = strdup(lookups); + return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM; +} + +static int config_nameserver(struct server_state **servers, int *nservers, + const char *str) +{ + struct in_addr addr; + struct server_state *newserv; +#ifdef USE_IPV6 + u_int8_t family; + struct in6_addr addr6; + + /* Add a nameserver entry, if this is a valid address. */ + + if (inet_pton4(str, (u_char *) & addr)) /* is it an IPv4 address? */ + family = AF_INET; + else + { + if (inet_pton6(str, (u_char *) & addr6)) /* how about an IPv6 address? */ + family = AF_INET6; + else + return ARES_SUCCESS; /* nope, it was garbage, return early */ + } +#else + /* Add a nameserver entry, if this is a valid address. */ + + if (!inet_pton4(str, (u_char *) & addr)) /* is it an IPv4 address? */ + return ARES_SUCCESS; /* nope, it was garbage, return early */ +#endif + + newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state)); + if (!newserv) + return ARES_ENOMEM; + memset(&newserv[*nservers], '\0', sizeof(struct server_state)); // clear *new* memory only + +#ifdef USE_IPV6 + newserv[*nservers].family = family; + if (family == AF_INET6) + newserv[*nservers].addr6 = addr6; + else +#endif + newserv[*nservers].addr = addr; + + *servers = newserv; + (*nservers)++; + return ARES_SUCCESS; +} + +static int config_sortlist(struct apattern **sortlist, int *nsort, + const char *str) +{ + struct apattern pat, *newsort; + const char *q; + + /* Add sortlist entries. */ + while (*str && *str != ';') + { + q = str; + while (*q && *q != '/' && *q != ';' && !isspace((unsigned char)*q)) + q++; + if (ip_addr(str, (int)(q - str), &pat.addr) == 0) + { + /* We have a pattern address; now determine the mask. */ + if (*q == '/') + { + str = q + 1; + while (*q && *q != ';' && !isspace((unsigned char)*q)) + q++; + if (ip_addr(str, (int)(q - str), &pat.mask) != 0) + natural_mask(&pat); + } + else + natural_mask(&pat); + + /* Add this pattern to our list. */ + newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern)); + if (!newsort) + return ARES_ENOMEM; + newsort[*nsort] = pat; + *sortlist = newsort; + (*nsort)++; + } + else + { + while (*q && *q != ';' && !isspace((unsigned char)*q)) + q++; + } + str = q; + while (isspace((unsigned char)*str)) + str++; + } + + return ARES_SUCCESS; +} + +static int set_search(ares_channel channel, const char *str) +{ + int n; + const char *p, *q; + + /* Count the domains given. */ + n = 0; + p = str; + while (*p) + { + while (*p && !isspace((unsigned char)*p)) + p++; + while (isspace((unsigned char)*p)) + p++; + n++; + } + + channel->domains = malloc(n * sizeof(char *)); + if (!channel->domains && n) + return ARES_ENOMEM; + + /* Now copy the domains. */ + n = 0; + p = str; + while (*p) + { + channel->ndomains = n; + q = p; + while (*q && !isspace((unsigned char)*q)) + q++; + channel->domains[n] = malloc(q - p + 1); + if (!channel->domains[n]) + return ARES_ENOMEM; + memcpy(channel->domains[n], p, q - p); + channel->domains[n][q - p] = 0; + p = q; + while (isspace((unsigned char)*p)) + p++; + n++; + } + channel->ndomains = n; + + return ARES_SUCCESS; +} + +static int set_options(ares_channel channel, const char *str) +{ + const char *p, *q, *val; + + p = str; + while (*p) + { + q = p; + while (*q && !isspace((unsigned char)*q)) + q++; + val = try_option(p, q, "ndots:"); + if (val && channel->ndots == -1) + channel->ndots = atoi(val); + val = try_option(p, q, "retrans:"); + if (val && channel->timeout == -1) + channel->timeout = atoi(val); + val = try_option(p, q, "retry:"); + if (val && channel->tries == -1) + channel->tries = atoi(val); + p = q; + while (isspace((unsigned char)*p)) + p++; + } + + return ARES_SUCCESS; +} + +static char *try_config(char *s, char *opt) +{ + int len; + + len = (int)strlen(opt); + if (strncmp(s, opt, len) != 0 || !isspace((unsigned char)s[len])) + return NULL; + s += len; + while (isspace((unsigned char)*s)) + s++; + return s; +} + +static const char *try_option(const char *p, const char *q, const char *opt) +{ + int len; + + len = (int)strlen(opt); + return (q - p > len && strncmp(p, opt, len) == 0) ? p + len : NULL; +} + +static int ip_addr(const char *s, int len, struct in_addr *addr) +{ + char ipbuf[16]; + + /* Four octets and three periods yields at most 15 characters. */ + if (len > 15) + return -1; + memcpy(ipbuf, s, len); + ipbuf[len] = 0; + + addr->s_addr = inet_addr(ipbuf); + if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0) + return -1; + return 0; +} + +static void natural_mask(struct apattern *pat) +{ + struct in_addr addr; + + /* Store a host-byte-order copy of pat in a struct in_addr. Icky, + * but portable. + */ + addr.s_addr = ntohl(pat->addr.s_addr); + + /* This is out of date in the CIDR world, but some people might + * still rely on it. + */ + if (IN_CLASSA(addr.s_addr)) + pat->mask.s_addr = htonl(IN_CLASSA_NET); + else if (IN_CLASSB(addr.s_addr)) + pat->mask.s_addr = htonl(IN_CLASSB_NET); + else + pat->mask.s_addr = htonl(IN_CLASSC_NET); +} + +/* + * Finds a V4 addr in list of servers. + * return: + * index i of servers whose servers[i].addr == addr + * else -1, failed to find + */ +static int find_server(struct server_state *servers, int nservers, struct in_addr addr) +{ + int i = 0; + + if (nservers == 0) + return -1; + + for (; i < nservers; i++) + { + if (servers[i].addr.s_addr == addr.s_addr) + break; + } + return (i < nservers ? i : -1); +} + +/* + * V4. Get the physical address of the first NIC whose list of DNS servers contain 'addr'. + * return: ARES_SUCCESS, etc. + */ +static int get_physical_address(char *physicalAddr, int physicalAddrBufSz, int* physAddrLen, struct in_addr addr) +{ +#ifdef WIN32 + typedef DWORD (WINAPI * GetAdaptersAddressesType)(ULONG, DWORD, VOID *, IP_ADAPTER_ADDRESSES *, ULONG *); + GetAdaptersAddressesType GetAdaptersAddressesProc = NULL; + + HANDLE hLib = 0; + DWORD dwRet = ERROR_BUFFER_OVERFLOW; + DWORD dwSize = 0; + IP_ADAPTER_ADDRESSES *pAdapterAddresses = 0; + int rc = ARES_ENOTFOUND; + + memset(physicalAddr, '\0', physicalAddrBufSz); + *physAddrLen = 0; + + hLib = LoadLibrary(TEXT("iphlpapi.dll")); + if (!hLib) + return ARES_ENOTIMP; + + GetAdaptersAddressesProc = (GetAdaptersAddressesType)GetProcAddress(hLib, "GetAdaptersAddresses"); + if(!GetAdaptersAddressesProc) + { + rc = ARES_ENOTIMP; + goto cleanup; + } + + // Getting buffer size, expects overflow error + dwRet = (*GetAdaptersAddressesProc)(AF_UNSPEC, 0, NULL, NULL, &dwSize); + assert(dwRet == ERROR_BUFFER_OVERFLOW); + if (dwRet == ERROR_BUFFER_OVERFLOW) + { + pAdapterAddresses = (IP_ADAPTER_ADDRESSES *) LocalAlloc(LMEM_ZEROINIT, dwSize); + if (! pAdapterAddresses) + { + rc = ARES_ENOMEM; + goto cleanup; + } + } + else + { + rc = ARES_ENODATA; + goto cleanup; + } + + dwRet = (*GetAdaptersAddressesProc)(AF_UNSPEC, 0, NULL, pAdapterAddresses, &dwSize); + if (dwRet != ERROR_SUCCESS) + { + rc = ARES_ENODATA; + goto cleanup; + } + + { + IP_ADAPTER_ADDRESSES * AI = NULL; + for (AI = pAdapterAddresses; AI != NULL; AI = AI->Next) + { + PIP_ADAPTER_DNS_SERVER_ADDRESS dnsServers = AI->FirstDnsServerAddress; + // find 'addr' in adapter's list of dns servers. + for (; dnsServers; dnsServers = dnsServers->Next) + { + if (! dnsServers->Address.lpSockaddr) + continue; + + if (dnsServers->Address.lpSockaddr->sa_family == AF_INET) + { + struct sockaddr_in sockAddr = *(struct sockaddr_in*)(dnsServers->Address.lpSockaddr); + if (memcmp(&addr, &sockAddr.sin_addr.s_addr, sizeof(struct in_addr)) == 0) + { + *physAddrLen = AI->PhysicalAddressLength; + if (*physAddrLen > physicalAddrBufSz) + *physAddrLen = physicalAddrBufSz; + memcpy(physicalAddr, &AI->PhysicalAddress[0], *physAddrLen); + rc = ARES_SUCCESS; + goto cleanup; + } + } + } + } + } + rc = ARES_ENOTFOUND; + +cleanup: + if (hLib) + FreeLibrary(hLib); + if (pAdapterAddresses) + LocalFree(pAdapterAddresses); + return rc; +#else // WIN32 + return ARES_ENOTIMP; +#endif // WIN32 +} + + +#define NS_INT16SZ 2 +#define NS_INADDRSZ 4 +#define NS_IN6ADDRSZ 16 + +#ifdef USE_IPV6 +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * (1) does not touch `dst' unless it's returning 1. + * (2) :: in a full address is silently ignored. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton6(const char *src, u_char *dst) +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + u_int val; + + memset((tp = tmp), '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += NS_INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if (saw_xdigit) { + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = (int)(tp - colonp); + int i; + + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return (0); + memcpy(dst, tmp, NS_IN6ADDRSZ); + return (1); +} + +#endif + +/* int + * inet_pton4(src, dst) + * like inet_aton() but without all the hexadecimal and shorthand. + * return: + * 1 if `src' is a valid dotted quad, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton4(const char *src, u_char *dst) +{ + static const char digits[] = "0123456789"; + int saw_digit, octets, ch; + u_char tmp[NS_INADDRSZ], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + u_int newVal = (u_int)(*tp * 10 + (pch - digits)); + + if (newVal > 255) + return (0); + *tp = newVal; + if (! saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return (0); + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return (0); + + memcpy(dst, tmp, NS_INADDRSZ); + return (1); +} + +/* + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/contrib/ares/ares_init_options.3 b/src/libs/resiprocate/contrib/ares/ares_init_options.3 new file mode 100644 index 00000000..27b149bf --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_init_options.3 @@ -0,0 +1 @@ +.so man3/ares_init.3 diff --git a/src/libs/resiprocate/contrib/ares/ares_local.c b/src/libs/resiprocate/contrib/ares/ares_local.c new file mode 100644 index 00000000..d0e51572 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_local.c @@ -0,0 +1,30 @@ +#include "ares.h" +#include "ares_local.h" + + + +int ares_local_gethostbyname(ares_channel channel, const char *name, int family, + ares_host_callback callback, void *arg) +{ + (void)(channel,name,family,callback,arg); + return 0; +} + +int ares_local_gethostbyaddr(ares_channel channel, const char *addr, int addrlen, + int family, ares_host_callback callback, void*arg) +{ + (void)(channel,addr,addrlen,family,callback,arg); + return 0; +} + +int ares_local_query(ares_channel channel, const char *name, int dnsclass, + int type, ares_callback callback, void *arg) +{ + (void)(channel,name,dnsclass,type,callback,arg); + return 0; +} + +void ares_local_process_requests() +{ + return; +} diff --git a/src/libs/resiprocate/contrib/ares/ares_local.h b/src/libs/resiprocate/contrib/ares/ares_local.h new file mode 100644 index 00000000..a344df7f --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_local.h @@ -0,0 +1,23 @@ +#ifndef ARES_LOCAL__H +#define ARES_LOCAL__H +/* +** Define a suite of callbacks that can return locally configured DNS results. +** Very useful for testing or simulation. +** +** Returns 0 when unable to handle request, non-zero when handled (and callbacks invoked). +** +*/ + +int ares_local_gethostbyname(ares_channel channel, const char *name, int family, + ares_host_callback callback, void *arg); + +int ares_local_gethostbyaddr(ares_channel channel, const char *addr, int addrlen, + int family, ares_host_callback callback, void*arg); + +int ares_local_query(ares_channel channel, const char *name, int dnsclass, + int type, ares_callback callback, void *arg); + + +void ares_local_process_requests(); + +#endif diff --git a/src/libs/resiprocate/contrib/ares/ares_mkquery.3 b/src/libs/resiprocate/contrib/ares/ares_mkquery.3 new file mode 100644 index 00000000..bb6721e4 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_mkquery.3 @@ -0,0 +1,78 @@ +.\" +.\" Copyright 1998, 2000 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_MKQUERY 3 "4 January 2000" +.SH NAME +ares_mkquery \- Compose a single-question DNS query buffer +.SH SYNOPSIS +.nf +.B #include +.PP +.B +int ares_mkquery(const char *\fIname\fP, int \fIdnsclass\fP, int \fItype\fP, +.B + unsigned short \fIid\fP, int \fIrd\fP, char **\fIbuf\fP, + int *\fIbuflen\fP) +.fi +.SH DESCRIPTION +The +.B ares_mkquery +function composes a DNS query with a single question. +The parameter +.I name +gives the query name as a NUL-terminated C string of period-separated +labels optionally ending with a period; periods and backslashes within +a label must be escaped with a backlash. The parameters +.I dnsclass +and +.I type +give the class and type of the query using the values defined in +.BR . +The parameter +.I id +gives a 16-bit identifier for the query. The parameter +.I rd +should be nonzero if recursion is desired, zero if not. The query +will be placed in an allocated buffer, a pointer to which will be +stored in the variable pointed to by +.IR buf , +and the length of which will be stored in the variable pointed to by +.IR buflen . +It is the caller's responsibility to free this buffer using +.B ares_free_string +when it is no longer needed. +.SH RETURN VALUES +.B ares_mkquery +can return any of the following values: +.TP 15 +.B ARES_SUCCESS +Construction of the DNS query succeeded. +.TP 15 +.B ARES_EBADNAME +The query name +.I name +could not be encoded as a domain name, either because it contained a +zero-length label or because it contained a label of more than 63 +characters. +.TP 15 +.B ARES_ENOMEM +Memory was exhausted. +.SH SEE ALSO +.BR ares_expand_name (3), +.BR ares_free_string (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998, 2000 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_mkquery.c b/src/libs/resiprocate/contrib/ares/ares_mkquery.c new file mode 100644 index 00000000..25495e7f --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_mkquery.c @@ -0,0 +1,158 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#ifndef WIN32 +#include +#ifndef __CYGWIN__ +# include +#endif +#endif +#include +#include +#include "ares.h" +#include "ares_dns.h" + +/* Header format, from RFC 1035: + * 1 1 1 1 1 1 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | ID | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * |QR| Opcode |AA|TC|RD|RA| Z | RCODE | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | QDCOUNT | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | ANCOUNT | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | NSCOUNT | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | ARCOUNT | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * + * AA, TC, RA, and RCODE are only set in responses. Brief description + * of the remaining fields: + * ID Identifier to match responses with queries + * QR Query (0) or response (1) + * Opcode For our purposes, always QUERY + * RD Recursion desired + * Z Reserved (zero) + * QDCOUNT Number of queries + * ANCOUNT Number of answers + * NSCOUNT Number of name server records + * ARCOUNT Number of additional records + * + * Question format, from RFC 1035: + * 1 1 1 1 1 1 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | | + * / QNAME / + * / / + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | QTYPE | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | QCLASS | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * + * The query name is encoded as a series of labels, each represented + * as a one-byte length (maximum 63) followed by the text of the + * label. The list is terminated by a label of length zero (which can + * be thought of as the root domain). + */ + +int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, + int rd, unsigned char **buf, int *buflen) +{ + int len; + unsigned char *q; + const char *p; + + /* Compute the length of the encoded name so we can check buflen. + * Start counting at 1 for the zero-length label at the end. */ + len = 1; + for (p = name; *p; p++) + { + if (*p == '\\' && *(p + 1) != 0) + p++; + len++; + } + /* If there are n periods in the name, there are n + 1 labels, and + * thus n + 1 length fields, unless the name is empty or ends with a + * period. So add 1 unless name is empty or ends with a period. + */ + if (*name && *(p - 1) != '.') + len++; + + *buflen = len + HFIXEDSZ + QFIXEDSZ; + *buf = malloc(*buflen); + if (!*buf) + return ARES_ENOMEM; + + /* Set up the header. */ + q = *buf; + memset(q, 0, HFIXEDSZ); + DNS_HEADER_SET_QID(q, id); + DNS_HEADER_SET_OPCODE(q, QUERY); + DNS_HEADER_SET_RD(q, (rd) ? 1 : 0); + DNS_HEADER_SET_QDCOUNT(q, 1); + + /* A name of "." is a screw case for the loop below, so adjust it. */ + if (strcmp(name, ".") == 0) + name++; + + /* Start writing out the name after the header. */ + q += HFIXEDSZ; + while (*name) + { + if (*name == '.') + return ARES_EBADNAME; + + /* Count the number of bytes in this label. */ + len = 0; + for (p = name; *p && *p != '.'; p++) + { + if (*p == '\\' && *(p + 1) != 0) + p++; + len++; + } + if (len > MAXLABEL) + return ARES_EBADNAME; + + /* Encode the length and copy the data. */ + *q++ = len; + for (p = name; *p && *p != '.'; p++) + { + if (*p == '\\' && *(p + 1) != 0) + p++; + *q++ = *p; + } + + /* Go to the next label and repeat, unless we hit the end. */ + if (!*p) + break; + name = p + 1; + } + + /* Add the zero-length label at the end. */ + *q++ = 0; + + /* Finish off the question with the type and class. */ + DNS_QUESTION_SET_TYPE(q, type); + DNS_QUESTION_SET_CLASS(q, dnsclass); + + return ARES_SUCCESS; +} diff --git a/src/libs/resiprocate/contrib/ares/ares_parse_a_reply.3 b/src/libs/resiprocate/contrib/ares/ares_parse_a_reply.3 new file mode 100644 index 00000000..758170a9 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_parse_a_reply.3 @@ -0,0 +1,64 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_PARSE_A_REPLY 3 "25 July 1998" +.SH NAME +ares_parse_a_reply \- Parse a reply to a DNS query of type A into a hostent +.SH SYNOPSIS +.nf +.B #include +.PP +.B +int ares_parse_a_reply(const unsigned char *\fIabuf\fB, int \fIalen\fB, +.B struct hostent **\fIhost\fB); +.fi +.SH DESCRIPTION +The +.B ares_parse_a_reply +function parses the response to a query of type A into a +.BR "struct hostent" . +The parameters +.I abuf +and +.I alen +give the contents of the response. The result is stored in allocated +memory and a pointer to it stored into the variable pointed to by +.IR host . +It is the caller's responsibility to free the resulting host structure +using +.BR ares_free_hostent (3) +when it is no longer needed. +.SH RETURN VALUES +.B ares_parse_a_reply +can return any of the following values: +.TP 15 +.B ARES_SUCCESS +The response was successfully parsed. +.TP 15 +.B ARES_EBADRESP +The response was malformatted. +.TP 15 +.B ARES_ENODATA +The response did not contain an answer to the query. +.TP 15 +.B ARES_ENOMEM +Memory was exhausted. +.SH SEE ALSO +.BR ares_gethostbyname (3), +.BR ares_free_hostent (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_parse_a_reply.c b/src/libs/resiprocate/contrib/ares/ares_parse_a_reply.c new file mode 100644 index 00000000..2733fe44 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_parse_a_reply.c @@ -0,0 +1,173 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include +#include +#include "ares.h" +#include "ares_dns.h" +#include "ares_private.h" + +#ifndef WIN32 +#include +#include +#include +#ifndef __CYGWIN__ +# include +#endif +#include +#endif + +int ares_parse_a_reply(const unsigned char *abuf, int alen, + struct hostent **host) +{ + unsigned int qdcount, ancount; + int status, i, rr_type, rr_class, rr_len, naddrs; + long int len; + int naliases; + const unsigned char *aptr; + char *hostname, *rr_name, *rr_data, **aliases; + struct in_addr *addrs; + struct hostent *hostent; + + /* Set *host to NULL for all failure cases. */ + *host = NULL; + + /* Give up if abuf doesn't have room for a header. */ + if (alen < HFIXEDSZ) + return ARES_EBADRESP; + + /* Fetch the question and answer count from the header. */ + qdcount = DNS_HEADER_QDCOUNT(abuf); + ancount = DNS_HEADER_ANCOUNT(abuf); + if (qdcount != 1) + return ARES_EBADRESP; + + /* Expand the name from the question, and skip past the question. */ + aptr = abuf + HFIXEDSZ; + status = ares_expand_name(aptr, abuf, alen, &hostname, &len); + if (status != ARES_SUCCESS) + return status; + if (aptr + len + QFIXEDSZ > abuf + alen) + { + free(hostname); + return ARES_EBADRESP; + } + aptr += len + QFIXEDSZ; + + /* Allocate addresses and aliases; ancount gives an upper bound for both. */ + addrs = malloc(ancount * sizeof(struct in_addr)); + if (!addrs) + { + free(hostname); + return ARES_ENOMEM; + } + aliases = malloc((ancount + 1) * sizeof(char *)); + if (!aliases) + { + free(hostname); + free(addrs); + return ARES_ENOMEM; + } + naddrs = 0; + naliases = 0; + + /* Examine each answer resource record (RR) in turn. */ + for (i = 0; i < (int)ancount; i++) + { + /* Decode the RR up to the data field. */ + status = ares_expand_name(aptr, abuf, alen, &rr_name, &len); + if (status != ARES_SUCCESS) + break; + aptr += len; + if (aptr + RRFIXEDSZ > abuf + alen) + { + free(rr_name); + status = ARES_EBADRESP; + break; + } + rr_type = DNS_RR_TYPE(aptr); + rr_class = DNS_RR_CLASS(aptr); + rr_len = DNS_RR_LEN(aptr); + aptr += RRFIXEDSZ; + + if (rr_class == C_IN && rr_type == T_A + && rr_len == sizeof(struct in_addr) + && strcasecmp(rr_name, hostname) == 0) + { + memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr)); + naddrs++; + status = ARES_SUCCESS; + } + + if (rr_class == C_IN && rr_type == T_CNAME) + { + /* Record the RR name as an alias. */ + aliases[naliases] = rr_name; + naliases++; + + /* Decode the RR data and replace the hostname with it. */ + status = ares_expand_name(aptr, abuf, alen, &rr_data, &len); + if (status != ARES_SUCCESS) + break; + free(hostname); + hostname = rr_data; + } + else + free(rr_name); + + aptr += rr_len; + if (aptr > abuf + alen) + { + status = ARES_EBADRESP; + break; + } + } + + if (status == ARES_SUCCESS && naddrs == 0) + status = ARES_ENODATA; + if (status == ARES_SUCCESS) + { + /* We got our answer. Allocate memory to build the host entry. */ + aliases[naliases] = NULL; + hostent = malloc(sizeof(struct hostent)); + if (hostent) + { + hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *)); + if (hostent->h_addr_list) + { + /* Fill in the hostent and return successfully. */ + hostent->h_name = hostname; + hostent->h_aliases = aliases; + hostent->h_addrtype = AF_INET; + hostent->h_length = sizeof(struct in_addr); + for (i = 0; i < naddrs; i++) + hostent->h_addr_list[i] = (char *) &addrs[i]; + hostent->h_addr_list[naddrs] = NULL; + *host = hostent; + return ARES_SUCCESS; + } + free(hostent); + } + status = ARES_ENOMEM; + } + for (i = 0; i < naliases; i++) + free(aliases[i]); + free(aliases); + free(addrs); + free(hostname); + return status; +} diff --git a/src/libs/resiprocate/contrib/ares/ares_parse_ptr_reply.3 b/src/libs/resiprocate/contrib/ares/ares_parse_ptr_reply.3 new file mode 100644 index 00000000..97355df1 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_parse_ptr_reply.3 @@ -0,0 +1,76 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_PARSE_PTR_REPLY 3 "25 July 1998" +.SH NAME +ares_parse_ptr_reply \- Parse a reply to a DNS query of type PTR into a hostent +.SH SYNOPSIS +.nf +.B #include +.PP +.B +int ares_parse_ptr_reply(const unsigned char *\fIabuf\fB, int \fIalen\fB, +.B + const void *\fIaddr\fP, int \fIaddrlen\fP, int \fIfamily\fP, +.B struct hostent **\fIhost\fB); +.fi +.SH DESCRIPTION +The +.B ares_parse_ptr_reply +function parses the response to a query of type PTR into a +.BR "struct hostent" . +The parameters +.I abuf +and +.I alen +give the contents of the response. The parameters +.IR addr , +.IR addrlen , +and +.I family +specify which address was queried for; they are not used to verify the +response, merely used to fill in the address of the +.BR "struct hostent" . +The resulting +.B struct hostent +is stored in allocated memory and a pointer to it stored into the +variable pointed to by +.IR host . +It is the caller's responsibility to free the resulting host structure +using +.BR ares_free_hostent (3) +when it is no longer needed. +.SH RETURN VALUES +.B ares_parse_ptr_reply +can return any of the following values: +.TP 15 +.B ARES_SUCCESS +The response was successfully parsed. +.TP 15 +.B ARES_EBADRESP +The response was malformatted. +.TP 15 +.B ARES_ENODATA +The response did not contain an answer to the query. +.TP 15 +.B ARES_ENOMEM +Memory was exhausted. +.SH SEE ALSO +.BR ares_gethostbyaddr (3), +.BR ares_free_hostent (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_parse_ptr_reply.c b/src/libs/resiprocate/contrib/ares/ares_parse_ptr_reply.c new file mode 100644 index 00000000..d4ecd7c1 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_parse_ptr_reply.c @@ -0,0 +1,161 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include +#include + +#ifndef WIN32 +#include +#include +#include +#ifndef __CYGWIN__ +# include +#endif +#include +#endif + +#include "ares.h" +#include "ares_dns.h" +#include "ares_private.h" + +int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, + int addrlen, int family, struct hostent **host) +{ + unsigned int qdcount, ancount; + int status, i, rr_type, rr_class, rr_len; + long int len; + const unsigned char *aptr; + char *ptrname, *hostname, *rr_name, *rr_data; + struct hostent *hostent; + + /* Set *host to NULL for all failure cases. */ + *host = NULL; + + /* Give up if abuf doesn't have room for a header. */ + if (alen < HFIXEDSZ) + return ARES_EBADRESP; + + /* Fetch the question and answer count from the header. */ + qdcount = DNS_HEADER_QDCOUNT(abuf); + ancount = DNS_HEADER_ANCOUNT(abuf); + if (qdcount != 1) + return ARES_EBADRESP; + + /* Expand the name from the question, and skip past the question. */ + aptr = abuf + HFIXEDSZ; + status = ares_expand_name(aptr, abuf, alen, &ptrname, &len); + if (status != ARES_SUCCESS) + return status; + if (aptr + len + QFIXEDSZ > abuf + alen) + { + free(ptrname); + return ARES_EBADRESP; + } + aptr += len + QFIXEDSZ; + + /* Examine each answer resource record (RR) in turn. */ + hostname = NULL; + for (i = 0; i < (int)ancount; i++) + { + /* Decode the RR up to the data field. */ + status = ares_expand_name(aptr, abuf, alen, &rr_name, &len); + if (status != ARES_SUCCESS) + break; + aptr += len; + if (aptr + RRFIXEDSZ > abuf + alen) + { + free(rr_name); + status = ARES_EBADRESP; + break; + } + rr_type = DNS_RR_TYPE(aptr); + rr_class = DNS_RR_CLASS(aptr); + rr_len = DNS_RR_LEN(aptr); + aptr += RRFIXEDSZ; + + if (rr_class == C_IN && rr_type == T_PTR + && strcasecmp(rr_name, ptrname) == 0) + { + /* Decode the RR data and set hostname to it. */ + status = ares_expand_name(aptr, abuf, alen, &rr_data, &len); + if (status != ARES_SUCCESS) + break; + if (hostname) + free(hostname); + hostname = rr_data; + } + + if (rr_class == C_IN && rr_type == T_CNAME) + { + /* Decode the RR data and replace ptrname with it. */ + status = ares_expand_name(aptr, abuf, alen, &rr_data, &len); + if (status != ARES_SUCCESS) + break; + free(ptrname); + ptrname = rr_data; + } + + free(rr_name); + aptr += rr_len; + if (aptr > abuf + alen) + { + status = ARES_EBADRESP; + break; + } + } + + if (status == ARES_SUCCESS && !hostname) + status = ARES_ENODATA; + if (status == ARES_SUCCESS) + { + /* We got our answer. Allocate memory to build the host entry. */ + hostent = malloc(sizeof(struct hostent)); + if (hostent) + { + hostent->h_addr_list = malloc(2 * sizeof(char *)); + if (hostent->h_addr_list) + { + hostent->h_addr_list[0] = malloc(addrlen); + if (hostent->h_addr_list[0]) + { + hostent->h_aliases = malloc(sizeof (char *)); + if (hostent->h_aliases) + { + /* Fill in the hostent and return successfully. */ + hostent->h_name = hostname; + hostent->h_aliases[0] = NULL; + hostent->h_addrtype = family; + hostent->h_length = addrlen; + memcpy(hostent->h_addr_list[0], addr, addrlen); + hostent->h_addr_list[1] = NULL; + *host = hostent; + free(ptrname); + return ARES_SUCCESS; + } + free(hostent->h_addr_list[0]); + } + free(hostent->h_addr_list); + } + free(hostent); + } + status = ARES_ENOMEM; + } + if (hostname) + free(hostname); + free(ptrname); + return status; +} diff --git a/src/libs/resiprocate/contrib/ares/ares_private.h b/src/libs/resiprocate/contrib/ares/ares_private.h new file mode 100644 index 00000000..5222ecc9 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_private.h @@ -0,0 +1,158 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include +#ifndef WIN32 +#include +#else +#include +#include +#include +#endif + +#include +#include + +#define DEFAULT_TIMEOUT 5 +#define DEFAULT_TRIES 4 +#ifndef INADDR_NONE +#define INADDR_NONE 0xffffffff +#endif +#ifndef MAX_ADAPTER_ADDRESS_LENGTH +#define MAX_ADAPTER_ADDRESS_LENGTH 8 +#endif + +#define PATH_RESOLV_CONF "/etc/resolv.conf" +#ifdef ETC_INET +#define PATH_HOSTS "/etc/inet/hosts" +#else +#define PATH_HOSTS "/etc/hosts" +#endif + +struct send_request { + /* Remaining data to send */ + const char *data; + int len; + + /* Next request in queue */ + struct send_request *next; +}; + +struct server_state { +#ifdef USE_IPV6 + // added by Rohan on 7-Sep-2004 + // define address and family contructs for IPv6 + u_int8_t family; + struct in6_addr addr6; +#endif + struct in_addr addr; + unsigned char physical_addr[MAX_ADAPTER_ADDRESS_LENGTH]; + int physical_addr_len; + int default_localhost_server; + + int udp_socket; + int tcp_socket; + + /* Mini-buffer for reading the length word */ + unsigned char tcp_lenbuf[2]; + int tcp_lenbuf_pos; + int tcp_length; + + /* Buffer for reading actual TCP data */ + unsigned char *tcp_buffer; + int tcp_buffer_pos; + + /* TCP output queue */ + struct send_request *qhead; + struct send_request *qtail; +}; + +struct query { + /* Query ID from qbuf, for faster lookup, and current timeout */ + unsigned short qid; + time_t timeout; + + /* Query buf with length at beginning, for TCP transmission */ + char *tcpbuf; + int tcplen; + + /* Arguments passed to ares_send() (qbuf points into tcpbuf) */ + const char *qbuf; + int qlen; + ares_callback callback; + void *arg; + + /* Query status */ + int itry; + int server; + int *skip_server; + int using_tcp; + int error_status; + + /* Next query in chain */ + struct query *next; +}; + +/* An IP address pattern; matches an IP address X if X & mask == addr */ +struct apattern { + struct in_addr addr; + struct in_addr mask; +}; + +struct ares_channeldata { + /* Configuration data */ + int flags; + int timeout; + int tries; + int ndots; + int udp_port; + int tcp_port; + char **domains; + int ndomains; + struct apattern *sortlist; + int nsort; + char *lookups; + + /* Server addresses and communications state */ + struct server_state *servers; + int nservers; + + /* ID to use for next query */ + unsigned short next_id; + + /* Active queries */ + struct query *queries; + + /* post socket creation function pointer */ + socket_function_ptr socket_function; + + /* poll() system support */ + ares_poll_cb_func *poll_cb_func; + void* poll_cb_data; +}; + +void ares__send_query(ares_channel channel, struct query *query, time_t now); +void ares__close_poll(ares_channel channel, int server_idx); +void ares__close_sockets(struct server_state *server); +int ares__get_hostent(FILE *fp, struct hostent **host); +int ares__read_line(FILE *fp, char **buf, int *bufsize); + +void ares__kill_socket(int s); + +#ifdef WIN32 +#define strcasecmp(a,b) stricmp(a,b) +#define strncasecmp(a,b,n) strnicmp(a,b,n) +#endif + diff --git a/src/libs/resiprocate/contrib/ares/ares_process.3 b/src/libs/resiprocate/contrib/ares/ares_process.3 new file mode 100644 index 00000000..a8a346d5 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_process.3 @@ -0,0 +1,78 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_PROCESS 3 "25 July 1998" +.SH NAME +ares_process \- Process events for name resolution +.SH SYNOPSIS +.nf +.B #include +.PP +.B void ares_process(ares_channel \fIchannel\fP, fd_set *\fIread_fds\fP, +.B fd_set *\fIwrite_fds\fP) +.fi +.SH DESCRIPTION +The +.B ares_process +function handles input/output events and timeouts associated with +queries pending on the name service channel identified by +.IR channel . +The file descriptor sets pointed to by +.I read_fds +and +.I write_fds +should have file descriptors set in them according to whether the file +descriptors specified by +.BR ares_fds (3) +are ready for reading and writing. (The easiest way to determine this +information is to invoke +.B select +with a timeout no greater than the timeout given by +.BR ares_timeout (3)). +.PP +The +.B ares_process +function will invoke callbacks for pending queries if they complete +successfully or fail. +.SS EXAMPLE +The following code fragment waits for all pending queries on a channel +to complete: +.PP +.RS +.nf +int nfds, count; +fd_set readers, writers; +struct timeval tv, *tvp; + +while (1) + { + FD_ZERO(&readers); + FD_ZERO(&writers); + nfds = ares_fds(channel, &readers, &writers); + if (nfds == 0) + break; + tvp = ares_timeout(channel, NULL, &tv); + count = select(nfds, &readers, &writers, NULL, tvp); + ares_process(channel, &readers, &writers); + } +.fi +.RE +.SH SEE ALSO +.BR ares_fds (3), +.BR ares_timeout (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_process.c b/src/libs/resiprocate/contrib/ares/ares_process.c new file mode 100644 index 00000000..0c7e1104 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_process.c @@ -0,0 +1,990 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include + +#ifndef WIN32 +#include +#include +#include +#ifndef __CYGWIN__ +# include +#endif +#include +#endif + +#include +#include +#include +#include +#include +#include "ares.h" +#include "ares_dns.h" +#include "ares_private.h" +#include "ares_local.h" + +#ifdef WIN32 +static int getErrno() { return WSAGetLastError(); } +#else +static int getErrno() { return errno; } +#endif + +static void write_tcp_data_core(ares_channel channel, int server_idx, + time_t now); +static void write_tcp_data(ares_channel channel, + fd_set *write_fds, time_t now); +static void read_tcp_data(ares_channel channel, int server_idx, + fd_set *read_fds, time_t now); +static void read_udp_packets(ares_channel channel, int server_idx, + fd_set *read_fds, + time_t now); +static void process_timeouts(ares_channel channel, time_t now); +static void process_answer(ares_channel channel, unsigned char *abuf, + int alen, int whichserver, int tcp, time_t now); +static void handle_error(ares_channel channel, int whichserver, time_t now); +static void next_server(ares_channel channel, struct query *query, time_t now); +static int next_server_new_network(ares_channel channel, struct query *query, time_t now); +static int open_tcp_socket(ares_channel channel, struct server_state *server); +static int open_udp_socket(ares_channel channel, struct server_state *server); +static int same_questions(const unsigned char *qbuf, int qlen, + const unsigned char *abuf, int alen); +static void end_query(ares_channel channel, struct query *query, int status, + unsigned char *abuf, int alen); +static int make_socket_non_blocking(int s); + +/* Something interesting happened on the wire, or there was a timeout. + * See what's up and respond accordingly. + */ +void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds) +{ + time_t now; + + time(&now); + write_tcp_data(channel, write_fds, now); + read_tcp_data(channel, -1, read_fds, now); + read_udp_packets(channel, -1, read_fds, now); + process_timeouts(channel, now); + + /* See if our local pseudo-db has any results. */ + /* Querying this only on timeouts is OK (is not high-performance) */ + ares_local_process_requests(); +} + +/* Something happened on wire or there was a timeout. This interface + * is called for poll()-like systems. + */ +void ares_process_poll(ares_channel channel, int server_idx, + int rdFd, int wrFd, time_t now) { + if ( server_idx!= -1 ) { + assert( rdFd!=-1 || wrFd!=-1 ); // at least one active + if ( wrFd!=-1 && channel->servers[server_idx].tcp_socket==wrFd ) { + write_tcp_data_core(channel, server_idx, now); + } + // writes can only be for TCP (we don't ask for UDP writable events) + if ( rdFd!=-1 && channel->servers[server_idx].tcp_socket == rdFd ) + read_tcp_data(channel, server_idx, NULL, now); + if ( rdFd!=-1 && channel->servers[server_idx].udp_socket == rdFd ) + read_udp_packets(channel, server_idx, NULL, now); + } else { + process_timeouts(channel, now); + ares_local_process_requests(); + } +} + +/* If any TCP sockets select true for writing, write out queued data + * we have for them. + */ +static void write_tcp_data_core(ares_channel channel, int server_idx, + time_t now) +{ + struct server_state *server; + struct send_request *sendreq; +#ifdef WIN32 + WSABUF *vec; +#else + struct iovec *vec; +#endif + int n, count; + + server = &channel->servers[server_idx]; + if (!server->qhead || server->tcp_socket == -1 ) + return; + + /* Count the number of send queue items. */ + n = 0; + for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) + n++; + +#ifdef WIN32 + /* Allocate iovecs so we can send all our data at once. */ + vec = malloc(n * sizeof(WSABUF)); + if (vec) + { + int err; + /* Fill in the iovecs and send. */ + n = 0; + for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) + { + vec[n].buf = (char *) sendreq->data; + vec[n].len = sendreq->len; + n++; + } + err = WSASend(server->tcp_socket, vec, n, &count,0,0,0 ); + if ( err == SOCKET_ERROR ) + { + count =-1; + } + free(vec); +#else + /* Allocate iovecs so we can send all our data at once. */ + vec = malloc(n * sizeof(struct iovec)); + if (vec) + { + // int err; + /* Fill in the iovecs and send. */ + n = 0; + for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) + { + vec[n].iov_base = (char *) sendreq->data; + vec[n].iov_len = sendreq->len; + n++; + } + count = writev(server->tcp_socket, vec, n); + free(vec); +#endif + + if (count < 0) + { + handle_error(channel, server_idx, now); + return; + } + + /* Advance the send queue by as many bytes as we sent. */ + while (count) + { + sendreq = server->qhead; + if (count >= sendreq->len) + { + count -= sendreq->len; + server->qhead = sendreq->next; + free(sendreq); + if (server->qhead == NULL) + { + server->qtail = NULL; + assert(count==0); + break; + } + } + else + { + sendreq->data += count; + sendreq->len -= count; + break; + } + } + } + else + { + /* Can't allocate iovecs; just send the first request. */ + sendreq = server->qhead; +#ifndef UNDER_CE + count = write(server->tcp_socket, sendreq->data, sendreq->len); +#else + count = send(server->tcp_socket, sendreq->data, sendreq->len,0); +#endif + if (count < 0) + { + handle_error(channel, server_idx, now); + return; + } + + /* Advance the send queue by as many bytes as we sent. */ + if (count == sendreq->len) + { + server->qhead = sendreq->next; + if (server->qhead == NULL) + server->qtail = NULL; + free(sendreq); + } + else + { + sendreq->data += count; + sendreq->len -= count; + } + } + if ( server->qhead==NULL && channel->poll_cb_func ) { + (*(channel->poll_cb_func))( channel->poll_cb_data, channel, server_idx, + server->tcp_socket, ARES_POLLACTION_WRITEOFF); + } +} + + +static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now) +{ + struct server_state *server; + int i; + + for (i = 0; i < channel->nservers; i++) + { + /* Make sure server has data to send and is selected in write_fds. */ + server = &channel->servers[i]; + if (!server->qhead || server->tcp_socket == -1 ) + continue; + if ( write_fds && !FD_ISSET(server->tcp_socket, write_fds)) + continue; + + write_tcp_data_core(channel, i, now); + } +} + +/* If any TCP socket selects true for reading, read some data, + * allocate a buffer if we finish reading the length word, and process + * a packet if we finish reading one. + */ +static void read_tcp_data(ares_channel channel, int server_idx, fd_set *read_fds, time_t now) +{ + struct server_state *server; + int i, count; + + for (i = 0; i < channel->nservers; i++) + { + /* Make sure the server has a socket and is selected in read_fds. */ + if ( server_idx>=0 && i != server_idx ) + continue; + server = &channel->servers[i]; + if (server->tcp_socket == -1 ) + continue; + if (!FD_ISSET(server->tcp_socket, read_fds)) + continue; + + if (server->tcp_lenbuf_pos != 2) + { + /* We haven't yet read a length word, so read that (or + * what's left to read of it). + */ +#if defined UNDER_CE || defined WIN32 + count = recv(server->tcp_socket, + server->tcp_lenbuf + server->tcp_lenbuf_pos, + 2 - server->tcp_lenbuf_pos,0); +#else + count = read(server->tcp_socket, + server->tcp_lenbuf + server->tcp_lenbuf_pos, + 2 - server->tcp_lenbuf_pos); +#endif + if (count <= 0) + { + handle_error(channel, i, now); + continue; + } + + server->tcp_lenbuf_pos += count; + if (server->tcp_lenbuf_pos == 2) + { + /* We finished reading the length word. Decode the + * length and allocate a buffer for the data. + */ + server->tcp_length = server->tcp_lenbuf[0] << 8 + | server->tcp_lenbuf[1]; + server->tcp_buffer = malloc(server->tcp_length); + if (!server->tcp_buffer) + handle_error(channel, i, now); + server->tcp_buffer_pos = 0; + } + } + else + { + /* Read data into the allocated buffer. */ +#if defined UNDER_CE || defined WIN32 + count = recv(server->tcp_socket, + server->tcp_buffer + server->tcp_buffer_pos, + server->tcp_length - server->tcp_buffer_pos,0); +#else + count = read(server->tcp_socket, + server->tcp_buffer + server->tcp_buffer_pos, + server->tcp_length - server->tcp_buffer_pos); +#endif + + if (count <= 0) + { + handle_error(channel, i, now); + continue; + } + + server->tcp_buffer_pos += count; + if (server->tcp_buffer_pos == server->tcp_length) + { + /* We finished reading this answer; process it and + * prepare to read another length word. + */ + process_answer(channel, server->tcp_buffer, server->tcp_length, + i, 1, now); + free(server->tcp_buffer); + server->tcp_buffer = NULL; + server->tcp_lenbuf_pos = 0; + } + } + } +} + +/* If any UDP sockets select true for reading, process them. */ +static void read_udp_packets(ares_channel channel, int server_idx, + fd_set *read_fds, time_t now) +{ + struct server_state *server; + int i, count; + unsigned char buf[PACKETSZ + 1]; + + for (i = 0; i < channel->nservers; i++) + { + if ( server_idx>=0 && i != server_idx ) + continue; + /* Make sure the server has a socket and is selected in read_fds. */ + server = &channel->servers[i]; + if ( (server->udp_socket == -1) ) + continue; + if ( read_fds && !FD_ISSET(server->udp_socket, read_fds) ) + continue; + + assert( server->udp_socket != -1 ); + + count = recv(server->udp_socket, buf, sizeof(buf), 0); + if (count <= 0) + { +#if defined(WIN32) + //int err; + //err = WSAGetLastError(); + //err = errno; + switch (getErrno()) + { + case WSAEWOULDBLOCK: + if ( read_fds ) { + // read_fds is only null when using epoll + // which shouldn't happen under windows + // don't know why CLR is here anyways + FD_CLR(server->udp_socket, read_fds); + } + continue; + case WSAECONNABORTED: + break; + case WSAECONNRESET: // got an ICMP error on a previous send + break; + } +#endif + handle_error(channel, i, now); + } + else + { + process_answer(channel, buf, count, i, 0, now); + } + } +} + +/* If any queries have timed out, note the timeout and move them on. */ +static void process_timeouts(ares_channel channel, time_t now) +{ + struct query *query, *next; + + for (query = channel->queries; query; query = next) + { + next = query->next; + if (query->timeout != 0 && now >= query->timeout) + { + //fprintf(stderr, "kennard:ares:process_timeouts: got timeout\n"); + query->error_status = ARES_ETIMEOUT; + next_server(channel, query, now); + } + } +} + +/* Handle an answer from a server. */ +static void process_answer(ares_channel channel, unsigned char *abuf, + int alen, int whichserver, int tcp, time_t now) +{ + int id, tc, rcode; + struct query *query; + + /* If there's no room in the answer for a header, we can't do much + * with it. */ + if (alen < HFIXEDSZ) + return; + + /* Grab the query ID, truncate bit, and response code from the packet. */ + id = DNS_HEADER_QID(abuf); + tc = DNS_HEADER_TC(abuf); + rcode = DNS_HEADER_RCODE(abuf); + + /* Find the query corresponding to this packet. */ + for (query = channel->queries; query; query = query->next) + { + if (query->qid == id) + break; + } + if (!query) + return; + + /* If we got a truncated UDP packet and are not ignoring truncation, + * don't accept the packet, and switch the query to TCP if we hadn't + * done so already. + */ + if ((tc || alen > PACKETSZ) && !tcp && !(channel->flags & ARES_FLAG_IGNTC)) + { + if (!query->using_tcp) + { + query->using_tcp = 1; + ares__send_query(channel, query, now); + } + return; + } + + /* Limit alen to PACKETSZ if we aren't using TCP (only relevant if we + * are ignoring truncation. + */ + if (alen > PACKETSZ && !tcp) + alen = PACKETSZ; + + /* If we aren't passing through all error packets, discard packets + * with SERVFAIL, NOTIMP, or REFUSED response codes. + */ + if (!(channel->flags & ARES_FLAG_NOCHECKRESP)) + { + if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED) + { + query->skip_server[whichserver] = 1; + if (query->server == whichserver) + next_server(channel, query, now); + return; + } + if (!same_questions((unsigned char*)query->qbuf, query->qlen, abuf, alen)) + { + if (query->server == whichserver) + next_server(channel, query, now); + return; + } + + /* 'No such name' */ + if ((channel->flags & ARES_FLAG_TRY_NEXT_SERVER_ON_RCODE3) && rcode == NXDOMAIN) + { + if (query->server == whichserver) + { + if (next_server_new_network(channel, query, now)) + return; + } + } + } + + end_query(channel, query, ARES_SUCCESS, abuf, alen); +} + +static void handle_error(ares_channel channel, int whichserver, time_t now) +{ + struct query *query; + + /* Reset communications with this server. */ + //fprintf(stderr,"kennard:ares:handle_error: ...\n"); + ares__close_poll(channel, whichserver); + ares__close_sockets(&channel->servers[whichserver]); + + /* Tell all queries talking to this server to move on and not try + * this server again. + */ + for (query = channel->queries; query != 0; query = query->next) + { + assert( query != 0 ); + assert( channel->queries != 0 ); + + if (query->server == whichserver) + { + query->skip_server[whichserver] = 1; +#if 0 // !cj! - this seem to corrput memory when it is called + next_server(channel, query, now); +#endif + } + } +} + +static void next_server(ares_channel channel, struct query *query, time_t now) +{ + /* Advance to the next server or try. */ + query->server++; + for (; query->itry < channel->tries; query->itry++) + { + for (; query->server < channel->nservers; query->server++) + { + if (!query->skip_server[query->server]) + { + ares__send_query(channel, query, now); + return; + } + } + query->server = 0; + + /* Only one try if we're using TCP. */ + if (query->using_tcp) + break; + } + //fprintf(stderr, "kennard:ares:next_server: ran out of servers: code %d\n", query->error_status); + end_query(channel, query, query->error_status, NULL, 0); +} + +/* + * Same as next_server, but only attempt the next one if it's in a different network + * (subnet, designated by the NIC's physical address). We don't loop around to the + * beginning of the servers list since server responded with reply-code of 3 + * 'No such name' + * returns: + * 1 - query sent + * 0 - nothing happened + */ +static int next_server_new_network(ares_channel channel, struct query *query, time_t now) +{ + if (query->itry >= channel->tries) + return 0; + + query->server++; + for (; query->server < channel->nservers; query->server++) + { + int i = 0; + struct server_state* nextToTry = &channel->servers[query->server]; + if (query->skip_server[query->server]) + continue; + if (nextToTry->physical_addr_len == 0) + continue; + + // only try the next DNS server, nextToTry, if it hasn't been tried UP TO THIS POINT: query->server. + for (i = 0; i < query->server; i++) + { + if ( (channel->servers[i].physical_addr_len == nextToTry->physical_addr_len) + && (memcmp(nextToTry->physical_addr, channel->servers[i].physical_addr, nextToTry->physical_addr_len) == 0)) + { + // we've tried this network already, try next one (query->server++). + break; + } + } + if (i == query->server) + { + ares__send_query(channel, query, now); + return 1; + } + } + return 0; +} + +void ares__send_query(ares_channel channel, struct query *query, time_t now) +{ + struct send_request *sendreq; + struct server_state *server; + + server = &channel->servers[query->server]; + if (query->using_tcp) + { + int tryWrite = 0; + /* Make sure the TCP socket for this server is set up and queue + * a send request. + */ + if (server->tcp_socket == -1) + { + if (open_tcp_socket(channel, server) == -1) + { + query->skip_server[query->server] = 1; + next_server(channel, query, now); + return; + } + if ( channel->poll_cb_func ) { + // printf("ares_send_q: pollopen tcp fd=%d\n", server->tcp_socket); + (*(channel->poll_cb_func))( channel->poll_cb_data, channel, + query->server, server->tcp_socket, ARES_POLLACTION_OPEN); + } + } + sendreq = malloc(sizeof(struct send_request)); + if (!sendreq) + end_query(channel, query, ARES_ENOMEM, NULL, 0); + sendreq->data = query->tcpbuf; + sendreq->len = query->tcplen; + sendreq->next = NULL; + if (server->qtail) { + server->qtail->next = sendreq; + } else { + server->qhead = sendreq; + tryWrite = 1; + } + server->qtail = sendreq; + query->timeout = 0; + if ( tryWrite ) + { +#if 0 + time_t now; + time(&now); + write_tcp_data(channel, query->server, now); + /* XXX: the write code doesn't seem to handle EAGAIN properly! */ +#else + if ( channel->poll_cb_func ) + (*(channel->poll_cb_func))( channel->poll_cb_data, + channel, query->server, + server->tcp_socket, ARES_POLLACTION_WRITEON); +#endif + } + } + else + { + if (server->udp_socket == -1) + { + if (open_udp_socket(channel, server) == -1) + { + //fprintf(stderr,"kennard:ares:send_query:open_udp failed\n"); + query->skip_server[query->server] = 1; + next_server(channel, query, now); + return; + } + if ( channel->poll_cb_func ) { + // printf("ares_send_q: pollopen udp fd=%d\n", server->udp_socket); + (*(channel->poll_cb_func))( channel->poll_cb_data, channel, + query->server, server->udp_socket, ARES_POLLACTION_OPEN); + } + } + if (send(server->udp_socket, query->qbuf, query->qlen, 0) == -1) + { + //fprintf(stderr,"kennard:ares:send_query:send_udp failed\n"); + query->skip_server[query->server] = 1; + next_server(channel, query, now); + return; + } + query->timeout = now + + ((query->itry == 0) ? channel->timeout + : channel->timeout << query->itry / channel->nservers); + } +} + +static int open_tcp_socket(ares_channel channel, struct server_state *server) +{ + int s; + struct sockaddr_in sin; +#ifdef USE_IPV6 + struct sockaddr_in6 sin6; +#endif + + /* Acquire a socket. */ +#ifdef USE_IPV6 + assert(server->family == AF_INET || server->family == AF_INET6); + s = (int)socket(server->family, SOCK_STREAM, 0); +#else + s = (int)socket(AF_INET, SOCK_STREAM, 0); +#endif + if (s == -1) + return -1; + + if (make_socket_non_blocking(s)) + { + ares__kill_socket(s); + return -1; + } + +#ifdef WIN32 +#define PORTABLE_INPROGRESS_ERR WSAEWOULDBLOCK +#else +#define PORTABLE_INPROGRESS_ERR EINPROGRESS +#endif + + /* Connect to the server. */ +#ifdef USE_IPV6 + if (server->family == AF_INET6) + { + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + sin6.sin6_addr = server->addr6; + sin6.sin6_port = channel->tcp_port; + sin6.sin6_flowinfo = 0; + sin6.sin6_scope_id = 0; + // do i need to explicitly set the length? + + if (connect(s, (const struct sockaddr *) &sin6 , sizeof(sin6)) == -1 + && getErrno() != PORTABLE_INPROGRESS_ERR) + { + ares__kill_socket(s); + return -1; + } + } + else // IPv4 DNS server + { + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr = server->addr; + sin.sin_port = channel->tcp_port; + + if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1 && getErrno() != PORTABLE_INPROGRESS_ERR) + { + ares__kill_socket(s); + return -1; + } + } +#else + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr = server->addr; + sin.sin_port = channel->tcp_port; + + if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1 + && getErrno() != PORTABLE_INPROGRESS_ERR) + { + ares__kill_socket(s); + return -1; + } +#endif + + server->tcp_socket = s; + return 0; +} + +static int connect_udp_ipv4(int s, ares_channel channel, struct server_state *server) { + struct sockaddr_in sin; + + /* Connect to the server. */ + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr = server->addr; + sin.sin_port = channel->udp_port; + + if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1) + { + //fprintf(stderr,"kennard:ares:open_udp:ipv4: connect error %d: %s\n", errno, strerror(errno)); + ares__kill_socket(s); + return -1; + } + return 0; +} + +static int open_udp_socket(ares_channel channel, struct server_state *server) +{ + u_int8_t family; + int s; + +#ifdef USE_IPV6 + family = server->family; + if (family != AF_INET && family != AF_INET6) + return -1; + //assert(family == AF_INET || family == AF_INET6); +#else + family = AF_INET; +#endif + + /* Acquire a socket. */ + s = (int)socket(family, SOCK_DGRAM, 0); + + if (s == -1) { + //fprintf(stderr,"kennard:ares:open_udp: no socket %d: %s\n", errno, strerror(errno)); + return -1; + } + + if (make_socket_non_blocking(s)) + { + //fprintf(stderr,"kennard:ares:open_udp: nonblocking failed %d: %s\n", errno, strerror(errno)); + ares__kill_socket(s); + return -1; + } + +#ifdef USE_IPV6 + // added by Rohan 7-Sept-2004 + // should really replace sockaddr_in6 with sockaddr_storage + + + /* Connect to the server. */ + if (server->family == AF_INET6) + { + struct sockaddr_in6 sin6; + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + sin6.sin6_addr = server->addr6; + sin6.sin6_port = channel->udp_port; + sin6.sin6_flowinfo = 0; + sin6.sin6_scope_id = 0; + // do i need to explicitly set the length? + + if (connect(s, (const struct sockaddr *) &sin6, sizeof(sin6)) == -1) + { + ares__kill_socket(s); + return -1; + } + } + else // IPv4 DNS server + { + if ( connect_udp_ipv4(s, channel, server)==-1 ) + return -1; + } + +#else + + if ( connect_udp_ipv4(s, channel, server)==-1 ) + return -1; + +#endif + if(channel->socket_function) + { + channel->socket_function(s, 0, __FILE__, __LINE__); + } + + server->udp_socket = s; + return 0; +} + +static int same_questions(const unsigned char *qbuf, int qlen, + const unsigned char *abuf, int alen) +{ + struct { + const unsigned char *p; + int qdcount; + char *name; + long int namelen; + int type; + int dnsclass; + } q, a; + int i, j; + + if (qlen < HFIXEDSZ || alen < HFIXEDSZ) + return 0; + + /* Extract qdcount from the request and reply buffers and compare them. */ + q.qdcount = DNS_HEADER_QDCOUNT(qbuf); + a.qdcount = DNS_HEADER_QDCOUNT(abuf); + if (q.qdcount != a.qdcount) + return 0; + + /* For each question in qbuf, find it in abuf. */ + q.p = qbuf + HFIXEDSZ; + for (i = 0; i < q.qdcount; i++) + { + /* Decode the question in the query. */ + if (ares_expand_name(q.p, qbuf, qlen, &q.name, &q.namelen) + != ARES_SUCCESS) + return 0; + q.p += q.namelen; + if (q.p + QFIXEDSZ > qbuf + qlen) + { + free(q.name); + return 0; + } + q.type = DNS_QUESTION_TYPE(q.p); + q.dnsclass = DNS_QUESTION_CLASS(q.p); + q.p += QFIXEDSZ; + + /* Search for this question in the answer. */ + a.p = abuf + HFIXEDSZ; + for (j = 0; j < a.qdcount; j++) + { + /* Decode the question in the answer. */ + if (ares_expand_name(a.p, abuf, alen, &a.name, &a.namelen) + != ARES_SUCCESS) + { + free(q.name); + return 0; + } + a.p += a.namelen; + if (a.p + QFIXEDSZ > abuf + alen) + { + free(q.name); + free(a.name); + return 0; + } + a.type = DNS_QUESTION_TYPE(a.p); + a.dnsclass = DNS_QUESTION_CLASS(a.p); + a.p += QFIXEDSZ; + + /* Compare the decoded questions. */ + if (strcasecmp(q.name, a.name) == 0 && q.type == a.type + && q.dnsclass == a.dnsclass) + { + free(a.name); + break; + } + free(a.name); + } + + free(q.name); + if (j == a.qdcount) + return 0; + } + return 1; +} + +static void end_query(ares_channel channel, struct query *query, int status, + unsigned char *abuf, int alen) +{ + struct query **q; + int i; + + query->callback(query->arg, status, abuf, alen); + for (q = &channel->queries; *q; q = &(*q)->next) + { + if (*q == query) + break; + } + *q = query->next; + free(query->tcpbuf); + free(query->skip_server); + free(query); + + /* Simple cleanup policy: if no queries are remaining, close all + * network sockets unless STAYOPEN is set. + */ + if (!channel->queries && !(channel->flags & ARES_FLAG_STAYOPEN)) + { + for (i = 0; i < channel->nservers; i++) + { + //printf("end_query: closing...\n"); + ares__close_poll(channel, i); + ares__close_sockets(&channel->servers[i]); + } + } +} + +void ares__kill_socket(int s) +{ +#ifdef WIN32 + closesocket(s); +#else + close(s); +#endif + s = -1; // otherwise we will try using it again! +} + +int make_socket_non_blocking(int s) +{ +#ifdef WIN32 + unsigned long noBlock = 1; + int errNoBlock = ioctlsocket( s, FIONBIO , &noBlock ); + if ( errNoBlock != 0 ) + { + return -1; + } +#else + int flags; + // WATCHOUT: F_GETTL returns the flags, it doesn't use the argument! + if ((flags=fcntl(s, F_GETFL, 0)) == -1) + { + return -1; + } + flags |= O_NONBLOCK; // Fixed evil but here - used to be &= + if (fcntl(s, F_SETFL, flags) == -1) + { + return -1; + } +#endif + return 0; +} + +void ares_process_set_poll_cb(ares_channel channel, ares_poll_cb_func *cbf, void *cbd) { + channel->poll_cb_func = cbf; + channel->poll_cb_data = cbd; +} diff --git a/src/libs/resiprocate/contrib/ares/ares_query.3 b/src/libs/resiprocate/contrib/ares/ares_query.3 new file mode 100644 index 00000000..e203a0bf --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_query.3 @@ -0,0 +1,141 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_QUERY 3 "24 July 1998" +.SH NAME +ares_query \- Initiate a single-question DNS query +.SH SYNOPSIS +.nf +.B #include +.PP +.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, +.B unsigned char *\fIabuf\fP, int \fIalen\fP) +.PP +.B void ares_query(ares_channel \fIchannel\fP, const char *\fIname\fP, +.B int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP, +.B void *\fIarg\fP) +.fi +.SH DESCRIPTION +The +.B ares_query +function initiates a single-question DNS query on the name service +channel identified by +.IR channel . +The parameter +.I name +gives the query name as a NUL-terminated C string of period-separated +labels optionally ending with a period; periods and backslashes within +a label must be escaped with a backslash. The parameters +.I dnsclass +and +.I type +give the class and type of the query using the values defined in +.BR . +When the query is complete or has failed, the ares library will invoke +.IR callback . +Completion or failure of the query may happen immediately, or may +happen during a later call to +.BR ares_process (3) +or +.BR ares_destroy (3). +.PP +The callback argument +.I arg +is copied from the +.B ares_query +argument +.IR arg . +The callback argument +.I status +indicates whether the query succeeded and, if not, how it failed. It +may have any of the following values: +.TP 19 +.B ARES_SUCCESS +The query completed successfully. +.TP 19 +.B ARES_ENODATA +The query completed but contains no answers. +.TP 19 +.B ARES_EFORMERR +The query completed but the server claims that the query was +malformatted. +.TP 19 +.B ARES_ESERVFAIL +The query completed but the server claims to have experienced a +failure. (This code can only occur if the +.B ARES_FLAG_NOCHECKRESP +flag was specified at channel initialization time; otherwise, such +responses are ignored at the +.BR ares_send (3) +level.) +.TP 19 +.B ARES_ENOTFOUND +The query completed but the queried-for domain name was not found. +.TP 19 +.B ARES_ENOTIMP +The query completed but the server does not implement the operation +requested by the query. (This code can only occur if the +.B ARES_FLAG_NOCHECKRESP +flag was specified at channel initialization time; otherwise, such +responses are ignored at the +.BR ares_send (3) +level.) +.TP 19 +.B ARES_EREFUSED +The query completed but the server refused the query. (This code can +only occur if the +.B ARES_FLAG_NOCHECKRESP +flag was specified at channel initialization time; otherwise, such +responses are ignored at the +.BR ares_send (3) +level.) +.TP 19 +.B ARES_EBADNAME +The query name +.I name +could not be encoded as a domain name, either because it contained a +zero-length label or because it contained a label of more than 63 +characters. +.TP 19 +.B ARES_ETIMEOUT +No name servers responded within the timeout period. +.TP 19 +.B ARES_ECONNREFUSED +No name servers could be contacted. +.TP 19 +.B ARES_ENOMEM +Memory was exhausted. +.TP 19 +.B ARES_EDESTRUCTION +The name service channel +.I channel +is being destroyed; the query will not be completed. +.PP +If the query completed (even if there was something wrong with it, as +indicated by some of the above error codes), the callback argument +.I abuf +points to a result buffer of length +.IR alen . +If the query did not complete, +.I abuf +will be NULL and +.I alen +will be 0. +.SH SEE ALSO +.BR ares_process (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_query.c b/src/libs/resiprocate/contrib/ares/ares_query.c new file mode 100644 index 00000000..f602cb62 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_query.c @@ -0,0 +1,122 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include + +#ifndef WIN32 +#include +#ifndef __CYGWIN__ +# include +#endif +#endif + +#include +#include "ares.h" +#include "ares_dns.h" +#include "ares_private.h" +#include "ares_local.h" + +struct qquery { + ares_callback callback; + void *arg; +}; + +static void qcallback(void *arg, int status, unsigned char *abuf, int alen); + +void ares_query(ares_channel channel, const char *name, int dnsclass, + int type, ares_callback callback, void *arg) +{ + struct qquery *qquery; + unsigned char *qbuf; + int qlen, rd, status; + + /* See if query can be handled by local pseudo-domain DNS */ + if (ares_local_query(channel, name, dnsclass, type, callback, arg) != 0) + { + /* printf("ares_query: query for %s was handled locally\n",name); */ + return; + } + + /* Compose the query. */ + rd = !(channel->flags & ARES_FLAG_NORECURSE); + qbuf = 0; + status = ares_mkquery(name, dnsclass, type, channel->next_id, rd, &qbuf, + &qlen); + /* WATCHOUT: qbuf is always allocated except in case of ENOMEM */ + channel->next_id++; + if (status != ARES_SUCCESS) + { + if (qbuf) + ares_free_string((char*)qbuf); + callback(arg, status, NULL, 0); + return; + } + + /* Allocate and fill in the query structure. */ + qquery = malloc(sizeof(struct qquery)); + if (!qquery) + { + ares_free_string((char*)qbuf); + callback(arg, ARES_ENOMEM, NULL, 0); + return; + } + qquery->callback = callback; + qquery->arg = arg; + + /* Send it off. qcallback will be called when we get an answer. */ + ares_send(channel, qbuf, qlen, qcallback, qquery); + ares_free_string((char*)qbuf); +} + +static void qcallback(void *arg, int status, unsigned char *abuf, int alen) +{ + struct qquery *qquery = (struct qquery *) arg; + unsigned int ancount; + int rcode; + + if (status != ARES_SUCCESS) + qquery->callback(qquery->arg, status, abuf, alen); + else + { + /* Pull the response code and answer count from the packet. */ + rcode = DNS_HEADER_RCODE(abuf); + ancount = DNS_HEADER_ANCOUNT(abuf); + + /* Convert errors. */ + switch (rcode) + { + case NOERROR: + status = (ancount > 0) ? ARES_SUCCESS : ARES_ENODATA; + break; + case FORMERR: + status = ARES_EFORMERR; + break; + case SERVFAIL: + status = ARES_ESERVFAIL; + break; + case NXDOMAIN: + status = ARES_ENOTFOUND; + break; + case NOTIMP: + status = ARES_ENOTIMP; + break; + case REFUSED: + status = ARES_EREFUSED; + break; + } + qquery->callback(qquery->arg, status, abuf, alen); + } + free(qquery); +} diff --git a/src/libs/resiprocate/contrib/ares/ares_search.3 b/src/libs/resiprocate/contrib/ares/ares_search.3 new file mode 100644 index 00000000..6cdcec58 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_search.3 @@ -0,0 +1,143 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_SEARCH 3 "24 July 1998" +.SH NAME +ares_search \- Initiate a DNS query with domain search +.SH SYNOPSIS +.nf +.B #include +.PP +.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, +.B unsigned char *\fIabuf\fP, int \fIalen\fP) +.PP +.B void ares_search(ares_channel \fIchannel\fP, const char *\fIname\fP, +.B int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP, +.B void *\fIarg\fP) +.fi +.SH DESCRIPTION +The +.B ares_search +function initiates a series of single-question DNS queries on the name +service channel identified by +.IR channel , +using the channel's search domains as well as a host alias file given +by the HOSTALIAS environment variable. The parameter +.I name +gives the alias name or the base of the query name as a NUL-terminated +C string of period-separated labels; if it ends with a period, the +channel's search domains will not be used. Periods and backslashes +within a label must be escaped with a backslash. The parameters +.I dnsclass +and +.I type +give the class and type of the query using the values defined in +.BR . +When the query sequence is complete or has failed, the ares library +will invoke +.IR callback . +Completion or failure of the query sequence may happen immediately, or +may happen during a later call to +.BR ares_process (3) +or +.BR ares_destroy (3). +.PP +The callback argument +.I arg +is copied from the +.B ares_search +argument +.IR arg . +The callback argument +.I status +indicates whether the query sequence ended with a successful query +and, if not, how the query sequence failed. It may have any of the +following values: +.TP 19 +.B ARES_SUCCESS +A query completed successfully. +.TP 19 +.B ARES_ENODATA +No query completed successfully; when the query was tried without a +search domain appended, a response was returned with no answers. +.TP 19 +.B ARES_EFORMERR +A query completed but the server claimed that the query was +malformatted. +.TP 19 +.B ARES_ESERVFAIL +No query completed successfully; when the query was tried without a +search domain appended, the server claimed to have experienced a +failure. (This code can only occur if the +.B ARES_FLAG_NOCHECKRESP +flag was specified at channel initialization time; otherwise, such +responses are ignored at the +.BR ares_send (3) +level.) +.TP 19 +.B ARES_ENOTFOUND +No query completed successfully; when the query was tried without a +search domain appended, the server reported that the queried-for +domain name was not found. +.TP 19 +.B ARES_ENOTIMP +A query completed but the server does not implement the operation +requested by the query. (This code can only occur if the +.B ARES_FLAG_NOCHECKRESP +flag was specified at channel initialization time; otherwise, such +responses are ignored at the +.BR ares_send (3) +level.) +.TP 19 +.B ARES_EREFUSED +A query completed but the server refused the query. (This code can +only occur returned if the +.B ARES_FLAG_NOCHECKRESP +flag was specified at channel initialization time; otherwise, such +responses are ignored at the +.BR ares_send (3) +level.) +.TP 19 +.B ARES_TIMEOUT +No name servers responded to a query within the timeout period. +.TP 19 +.B ARES_ECONNREFUSED +No name servers could be contacted. +.TP 19 +.B ARES_ENOMEM +Memory was exhausted. +.TP 19 +.B ARES_EDESTRUCTION +The name service channel +.I channel +is being destroyed; the query will not be completed. +.PP +If a query completed successfully, the callback argument +.I abuf +points to a result buffer of length +.IR alen . +If the query did not complete successfully, +.I abuf +will usually be NULL and +.I alen +will usually be 0, but in some cases an unsuccessful query result may +be placed in +.IR abuf . +.SH SEE ALSO +.BR ares_process (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_search.c b/src/libs/resiprocate/contrib/ares/ares_search.c new file mode 100644 index 00000000..4cc6d5ae --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_search.c @@ -0,0 +1,275 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include +#include +#include +#include +#include "ares.h" +#include "ares_private.h" + +struct search_query { + /* Arguments passed to ares_search */ + ares_channel channel; + char *name; /* copied into an allocated buffer */ + int dnsclass; + int type; + ares_callback callback; + void *arg; + + int status_as_is; /* error status from trying as-is */ + int next_domain; /* next search domain to try */ + int trying_as_is; /* current query is for name as-is */ +}; + +static void search_callback(void *arg, int status, unsigned char *abuf, + int alen); +static void end_squery(struct search_query *squery, int status, + unsigned char *abuf, int alen); +static int cat_domain(const char *name, const char *domain, char **s); +static int single_domain(ares_channel channel, const char *name, char **s); + +void ares_search(ares_channel channel, const char *name, int dnsclass, + int type, ares_callback callback, void *arg) +{ + struct search_query *squery; + char *s; + const char *p; + int status, ndots; + + /* If name only yields one domain to search, then we don't have + * to keep extra state, so just do an ares_query(). + */ + status = single_domain(channel, name, &s); + if (status != ARES_SUCCESS) + { + callback(arg, status, NULL, 0); + return; + } + if (s) + { + ares_query(channel, s, dnsclass, type, callback, arg); + free(s); + return; + } + + /* Allocate a search_query structure to hold the state necessary for + * doing multiple lookups. + */ + squery = malloc(sizeof(struct search_query)); + if (!squery) + { + callback(arg, ARES_ENOMEM, NULL, 0); + return; + } + squery->channel = channel; + squery->name = strdup(name); + if (!squery->name) + { + free(squery); + callback(arg, ARES_ENOMEM, NULL, 0); + return; + } + squery->dnsclass = dnsclass; + squery->type = type; + squery->status_as_is = -1; + squery->callback = callback; + squery->arg = arg; + + /* Count the number of dots in name. */ + ndots = 0; + for (p = name; *p; p++) + { + if (*p == '.') + ndots++; + } + + /* If ndots is at least the channel ndots threshold (usually 1), + * then we try the name as-is first. Otherwise, we try the name + * as-is last. + */ + if (ndots >= channel->ndots) + { + /* Try the name as-is first. */ + squery->next_domain = 0; + squery->trying_as_is = 1; + ares_query(channel, name, dnsclass, type, search_callback, squery); + } + else + { + /* Try the name as-is last; start with the first search domain. */ + squery->next_domain = 1; + squery->trying_as_is = 0; + status = cat_domain(name, channel->domains[0], &s); + if (status == ARES_SUCCESS) + { + ares_query(channel, s, dnsclass, type, search_callback, squery); + free(s); + } + else + { + free(squery->name); + free(squery); + callback(arg, status, NULL, 0); + } + } +} + +static void search_callback(void *arg, int status, unsigned char *abuf, + int alen) +{ + struct search_query *squery = (struct search_query *) arg; + ares_channel channel = squery->channel; + char *s; + + /* Stop searching unless we got a non-fatal error. */ + if (status != ARES_ENODATA && status != ARES_ESERVFAIL + && status != ARES_ENOTFOUND) + end_squery(squery, status, abuf, alen); + else + { + /* Save the status if we were trying as-is. */ + if (squery->trying_as_is) + squery->status_as_is = status; + if (squery->next_domain < channel->ndomains) + { + /* Try the next domain. */ + status = cat_domain(squery->name, + channel->domains[squery->next_domain], &s); + if (status != ARES_SUCCESS) + end_squery(squery, status, NULL, 0); + else + { + squery->trying_as_is = 0; + squery->next_domain++; + ares_query(channel, s, squery->dnsclass, squery->type, + search_callback, squery); + free(s); + } + } + else if (squery->status_as_is == -1) + { + /* Try the name as-is at the end. */ + squery->trying_as_is = 1; + ares_query(channel, squery->name, squery->dnsclass, squery->type, + search_callback, squery); + } + else + end_squery(squery, squery->status_as_is, NULL, 0); + } +} + +static void end_squery(struct search_query *squery, int status, + unsigned char *abuf, int alen) +{ + squery->callback(squery->arg, status, abuf, alen); + free(squery->name); + free(squery); +} + +/* Concatenate two domains. */ +static int cat_domain(const char *name, const char *domain, char **s) +{ + size_t nlen = strlen(name), dlen = strlen(domain); + + *s = malloc(nlen + 1 + dlen + 1); + if (!*s) + return ARES_ENOMEM; + memcpy(*s, name, nlen); + (*s)[nlen] = '.'; + memcpy(*s + nlen + 1, domain, dlen); + (*s)[nlen + 1 + dlen] = 0; + return ARES_SUCCESS; +} + +/* Determine if this name only yields one query. If it does, set *s to + * the string we should query, in an allocated buffer. If not, set *s + * to NULL. + */ +static int single_domain(ares_channel channel, const char *name, char **s) +{ + size_t len = strlen(name); + const char *hostaliases; + FILE *fp; + char *line = NULL; + int linesize, status; + const char *p, *q; + + /* If the name contains a trailing dot, then the single query is the name + * sans the trailing dot. + */ + if (name[len - 1] == '.') + { + *s = strdup(name); + return (*s) ? ARES_SUCCESS : ARES_ENOMEM; + } + + if (!(channel->flags & ARES_FLAG_NOALIASES) && !strchr(name, '.')) + { + /* The name might be a host alias. */ +#ifdef UNDER_CE + hostaliases = NULL; +#else + hostaliases = getenv("HOSTALIASES"); +#endif + if (hostaliases) + { + fp = fopen(hostaliases, "r"); + if (fp) + { + while ((status = ares__read_line(fp, &line, &linesize)) + == ARES_SUCCESS) + { + if (strncasecmp(line, name, len) != 0 || + !isspace((unsigned char)line[len])) + continue; + p = line + len; + while (isspace((unsigned char)*p)) + p++; + if (*p) + { + q = p + 1; + while (*q && !isspace((unsigned char)*q)) + q++; + *s = malloc(q - p + 1); + if (*s) + { + memcpy(*s, p, q - p); + (*s)[q - p] = 0; + } + free(line); + fclose(fp); + return (*s) ? ARES_SUCCESS : ARES_ENOMEM; + } + } + free(line); + fclose(fp); + if (status != ARES_SUCCESS) + return status; + } + } + } + + if (channel->flags & ARES_FLAG_NOSEARCH || channel->ndomains == 0) + { + /* No domain search to do; just try the name as-is. */ + *s = strdup(name); + return (*s) ? ARES_SUCCESS : ARES_ENOMEM; + } + + *s = NULL; + return ARES_SUCCESS; +} diff --git a/src/libs/resiprocate/contrib/ares/ares_send.3 b/src/libs/resiprocate/contrib/ares/ares_send.3 new file mode 100644 index 00000000..ee0b20d4 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_send.3 @@ -0,0 +1,116 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_SEND 3 "25 July 1998" +.SH NAME +ares_send \- Initiate a DNS query +.SH SYNOPSIS +.nf +.B #include +.PP +.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, +.B unsigned char *\fIabuf\fP, int \fIalen\fP) +.PP +.B +void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP, +.B int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP) +.fi +.SH DESCRIPTION +The +.B ares_send +function initiates a DNS query on the name service channel identified +by +.IR channel . +The parameters +.I qbuf +and +.I qlen +give the DNS query, which should already have been formatted according +to the DNS protocol. When the query is complete or has failed, the +ares library will invoke +.IR callback . +Completion or failure of the query may happen immediately, or may +happen during a later call to +.BR ares_process (3) +or +.BR ares_destroy (3). +.PP +The callback argument +.I arg +is copied from the +.B ares_send +argument +.IR arg . +The callback argument +.I status +indicates whether the query succeeded and, if not, how it failed. It +may have any of the following values: +.TP 19 +.B ARES_SUCCESS +The query completed. +.TP 19 +.B ARES_EBADQUERY +The query buffer was poorly formed (was not long enough for a DNS +header or was too long for TCP transmission). +.TP 19 +.B ARES_ETIMEOUT +No name servers responded within the timeout period. +.TP 19 +.B ARES_ECONNREFUSED +No name servers could be contacted. +.TP 19 +.B ARES_ENOMEM +Memory was exhausted. +.TP 19 +.B ARES_EDESTRUCTION +The name service channel +.I channel +is being destroyed; the query will not be completed. +.PP +If the query completed, the callback argument +.I abuf +points to a result buffer of length +.IR alen . +If the query did not complete, +.I abuf +will be NULL and +.I alen +will be 0. +.PP +Unless the flag +.B ARES_FLAG_NOCHECKRESP +was set at channel initialization time, +.B ares_send +will normally ignore responses whose questions do not match the +questions in +.IR qbuf , +as well as responses with reply codes of +.BR SERVFAIL , +.BR NOTIMP , +and +.BR REFUSED . +Unlike other query functions in the ares library, however, +.B ares_send +does not inspect the header of the reply packet to determine the error +status, so a callback status of +.B ARES_SUCCESS +does not reflect as much about the response as for other query +functions. +.SH SEE ALSO +.BR ares_process (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_send.c b/src/libs/resiprocate/contrib/ares/ares_send.c new file mode 100644 index 00000000..a7df020f --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_send.c @@ -0,0 +1,111 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +#include + +#ifndef WIN32 +#include +#ifndef __CYGWIN__ +# include +#endif +#endif + +#include +#include +#include +#include "ares.h" +#include "ares_dns.h" +#include "ares_private.h" + +void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, + ares_callback callback, void *arg) +{ + struct query *query; + int i; + time_t now; + + /* Verify that the query is at least long enough to hold the header. */ + if (qlen < HFIXEDSZ || qlen >= (1 << 16)) + { + callback(arg, ARES_EBADQUERY, NULL, 0); + return; + } + + /* Allocate space for query and allocated fields. */ + query = malloc(sizeof(struct query)); + if (!query) + { + callback(arg, ARES_ENOMEM, NULL, 0); + return; + } + query->tcpbuf = malloc(qlen + 2); + if (!query->tcpbuf) + { + free(query); + callback(arg, ARES_ENOMEM, NULL, 0); + return; + } + if (channel->nservers) + { + query->skip_server = malloc(channel->nservers * sizeof(int)); + } + else + { + query->skip_server = 0; + } + + if (!query->skip_server) + { + free(query->tcpbuf); + free(query); + callback(arg, ARES_ENOMEM, NULL, 0); + return; + } + + /* Compute the query ID. Start with no timeout. */ + query->qid = DNS_HEADER_QID(qbuf); + query->timeout = 0; + + /* Form the TCP query buffer by prepending qlen (as two + * network-order bytes) to qbuf. + */ + query->tcpbuf[0] = (qlen >> 8) & 0xff; + query->tcpbuf[1] = qlen & 0xff; + memcpy(query->tcpbuf + 2, qbuf, qlen); + query->tcplen = qlen + 2; + + /* Fill in query arguments. */ + query->qbuf = query->tcpbuf + 2; + query->qlen = qlen; + query->callback = callback; + query->arg = arg; + + /* Initialize query status. */ + query->itry = 0; + query->server = 0; + for (i = 0; i < channel->nservers; i++) + query->skip_server[i] = 0; + query->using_tcp = (channel->flags & ARES_FLAG_USEVC) || qlen > PACKETSZ; + query->error_status = ARES_ECONNREFUSED; + + /* Chain the query into this channel's query list. */ + query->next = channel->queries; + channel->queries = query; + + /* Perform the first query action. */ + time(&now); + ares__send_query(channel, query, now); +} diff --git a/src/libs/resiprocate/contrib/ares/ares_socketfunc.h b/src/libs/resiprocate/contrib/ares/ares_socketfunc.h new file mode 100644 index 00000000..01d849b0 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_socketfunc.h @@ -0,0 +1,18 @@ +#ifndef ARES__SOCKETFUNC_H +#define ARES__SOCKETFUNC_H + + +#ifdef WIN32 +#include +#endif + +#ifndef WIN32 +typedef int Socket; +#else +typedef SOCKET Socket; +#endif + +typedef void(*socket_function_ptr)(Socket s, int transportType, const char* file, int line); + +#endif + diff --git a/src/libs/resiprocate/contrib/ares/ares_strerror.3 b/src/libs/resiprocate/contrib/ares/ares_strerror.3 new file mode 100644 index 00000000..3c7d9198 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_strerror.3 @@ -0,0 +1,43 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_STRERROR 3 "25 July 1998" +.SH NAME +ares_strerror \- Get the description of an ares library error code +.SH SYNOPSIS +.nf +.B #include +.PP +.B const char *ares_strerror(int \fIcode\fP, char **\fImemptr\fP) +.fi +.SH DESCRIPTION +The +.B ares_strerror +function gets the description of the ares library error code +.IR code , +returning the result as a NUL-terminated C string. A pointer to +allocated data necessary to compose the error description may be +stored in the variable pointed to by +.IR memptr . +It is the caller's responsibility to invoke +.BR ares_free_errmem (3) +with the value of that variable when the error description is no +longer needed. +.SH SEE ALSO +.BR ares_free_errmem (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_strerror.c b/src/libs/resiprocate/contrib/ares/ares_strerror.c new file mode 100644 index 00000000..f375d7ae --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_strerror.c @@ -0,0 +1,47 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include +#include "ares.h" + +const char *ares_strerror(int code) +{ + /* A future implementation may want to handle internationalization. + * For now, just return a string literal from a table. + */ + const char *errtext[] = { + "Successful completion", + "DNS server returned answer with no data", + "DNS server claims query was misformatted", + "DNS server returned general failure", + "Domain name not found", + "DNS server does not implement requested operation", + "DNS server refused query", + "Misformatted DNS query", + "Misformatted domain name", + "Unsupported address family", + "Misformatted DNS reply", + "Could not contact DNS servers", + "Timeout while contacting DNS servers", + "End of file", + "Error reading file", + "Out of memory", + "Destructing" + }; + + assert(code >= 0 && code < (sizeof(errtext) / sizeof(*errtext))); + + return errtext[code]; +} diff --git a/src/libs/resiprocate/contrib/ares/ares_timeout.3 b/src/libs/resiprocate/contrib/ares/ares_timeout.3 new file mode 100644 index 00000000..acb4f4c7 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_timeout.3 @@ -0,0 +1,63 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_TIMEOUT 3 "25 July 1998" +.SH NAME +ares_fds \- Get file descriptors to select on for name service +.SH SYNOPSIS +.nf +.B #include +.PP +.B struct timeval *ares_timeout(ares_channel \fIchannel\fP, +.B struct timeval *\fImaxtv\fP, struct timeval *\fItvbuf\fP) +.fi +.SH DESCRIPTION +The +.B ares_timeout +function determines the maximum time for which the caller should wait +before invoking +.BR ares_process (3) +to process timeouts. The parameter +.I maxtv +specifies a existing maximum timeout, or +.B NULL +if the caller does not wish to apply a maximum timeout. The parameter +.I tvbuf +must point to a writable buffer of type +.BR "struct timeval" . +It is valid for +.I maxtv +and +.I tvbuf +to have the same value. +.PP +If no queries have timeouts pending sooner than the given maximum +timeout, +.B ares_timeout +returns the value of +.IR maxtv; +otherwise +.B ares_timeout +stores the appropriate timeout value into the buffer pointed to by +.I tvbuf +and returns the value of +.IR tvbuf . +.SH SEE ALSO +.BR ares_fds (3), +.BR ares_process (3) +.SH AUTHOR +Greg Hudson, MIT Information Systems +.br +Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/src/libs/resiprocate/contrib/ares/ares_timeout.c b/src/libs/resiprocate/contrib/ares/ares_timeout.c new file mode 100644 index 00000000..1917fd7e --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_timeout.c @@ -0,0 +1,61 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include +#include +#include "ares.h" +#include "ares_private.h" +#ifndef WIN32 +#include +#endif + +struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv, + struct timeval *tvbuf) +{ + struct query *query; + time_t now; + time_t offset, min_offset; + + /* No queries, no timeout (and no fetch of the current time). */ + if (!channel->queries) + return maxtv; + + /* Find the minimum timeout for the current set of queries. */ + time(&now); + min_offset = -1; + for (query = channel->queries; query; query = query->next) + { + if (query->timeout == 0) + continue; + offset = query->timeout - now; + if (offset < 0) + offset = 0; + if (min_offset == -1 || offset < min_offset) + min_offset = offset; + } + + /* If we found a minimum timeout and it's sooner than the one + * specified in maxtv (if any), return it. Otherwise go with + * maxtv. + */ + if (min_offset != -1 && (!maxtv || min_offset <= maxtv->tv_sec)) + { + tvbuf->tv_sec = (long)min_offset; + tvbuf->tv_usec = 0; + return tvbuf; + } + else + return maxtv; +} diff --git a/src/libs/resiprocate/contrib/ares/ares_version.h b/src/libs/resiprocate/contrib/ares/ares_version.h new file mode 100644 index 00000000..52cbed50 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/ares_version.h @@ -0,0 +1,8 @@ +/* $Id: ares_version.h,v 1.14 2008-08-29 08:55:02 bagder Exp $ */ + +#ifndef ARES__VERSION_H +#define ARES__VERSION_H + +// Dummy include file... +#endif + diff --git a/src/libs/resiprocate/contrib/ares/config.guess b/src/libs/resiprocate/contrib/ares/config.guess new file mode 100644 index 00000000..ed2e03b7 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/config.guess @@ -0,0 +1,1321 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-20' + +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c ; + for c in cc gcc c89 c99 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $dummy.c $dummy.o $dummy.rel ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/libs/resiprocate/contrib/ares/config.sub b/src/libs/resiprocate/contrib/ares/config.sub new file mode 100644 index 00000000..f3657978 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/config.sub @@ -0,0 +1,1443 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-07' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dsp16xx \ + | fr30 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el | mips64vr4300 \ + | mips64vr4300el | mips64vr5000 | mips64vr5000el \ + | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ + | mipsisa32 | mipsisa64 \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ + | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ + | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3d) + basic_machine=alpha-cray + os=-unicos + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh3eb | sh4eb) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/libs/resiprocate/contrib/ares/configure b/src/libs/resiprocate/contrib/ares/configure new file mode 100644 index 00000000..14e68b78 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/configure @@ -0,0 +1,4505 @@ +#! /bin/sh +# From configure.ac Revision:. +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59. +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="ares_init.c" +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot ARES_VERSION CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE RANLIB ac_ct_RANLIB build build_cpu build_vendor build_os host host_cpu host_vendor host_os MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking Speeds up one-time builds + --enable-dependency-tracking Do not reject slow dependency extractors + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-ipv6 enable ipv6 + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + +PACKAGE=ares +VERSION=1.1.2 +ARES_VERSION=${VERSION} + +echo "$as_me:$LINENO: result: Configuring ${PACKAGE} ${VERSION}" >&5 +echo "${ECHO_T}Configuring ${PACKAGE} ${VERSION}" >&6 + + +am__api_version="1.7" +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +test "$program_prefix" != NONE && + program_transform_name="s,^,$program_prefix,;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$,$program_suffix,;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm conftest.sed + + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$AWK" && break +done + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + + # test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=${PACKAGE} + VERSION=${VERSION} + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + + ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6 +rm -f confinc confmf + +# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval="$enable_dependency_tracking" + +fi; +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + + +depcc="$CC" am_compiler_list= + +echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + echo '#include "conftest.h"' > conftest.c + echo 'int i;' > conftest.h + echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=conftest.c object=conftest.o \ + depfile=conftest.Po tmpdepfile=conftest.TPo \ + $SHELL ./depcomp $depcc -c -o conftest.o conftest.c \ + >/dev/null 2>conftest.err && + grep conftest.h conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # (even with -Werror). So we grep stderr for any message + # that says an option was ignored. + if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +case $host_os in +solaris*) + +cat >>confdefs.h <<\_ACEOF +#define ETC_INET +_ACEOF + + ;; +esac + + +# Check whether --with-ipv6 or --without-ipv6 was given. +if test "${with_ipv6+set}" = set; then + withval="$with_ipv6" + CFLAGS="${CFLAGS} -DUSE_IPV6=1" +fi; + + +echo "$as_me:$LINENO: checking for library containing gethostbyname" >&5 +echo $ECHO_N "checking for library containing gethostbyname... $ECHO_C" >&6 +if test "${ac_cv_search_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_gethostbyname=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_gethostbyname="none required" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_gethostbyname" = no; then + for ac_lib in nsl; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_gethostbyname="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_search_gethostbyname" >&6 +if test "$ac_cv_search_gethostbyname" != no; then + test "$ac_cv_search_gethostbyname" = "none required" || LIBS="$ac_cv_search_gethostbyname $LIBS" + +fi + +echo "$as_me:$LINENO: checking for library containing socket" >&5 +echo $ECHO_N "checking for library containing socket... $ECHO_C" >&6 +if test "${ac_cv_search_socket+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_socket=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_socket="none required" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_socket" = no; then + for ac_lib in socket; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_socket="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_socket" >&5 +echo "${ECHO_T}$ac_cv_search_socket" >&6 +if test "$ac_cv_search_socket" != no; then + test "$ac_cv_search_socket" = "none required" || LIBS="$ac_cv_search_socket $LIBS" + +fi + + +echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi; + echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5 +echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + + ac_config_files="$ac_config_files Makefile" +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then we branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +cat >confdef2opt.sed <<\_ACEOF +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g +t quote +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g +t quote +d +: quote +s,[ `~#$^&*(){}\\|;'"<>?],\\&,g +s,\[,\\&,g +s,\],\\&,g +s,\$,$$,g +p +_ACEOF +# We use echo to avoid assuming a particular line-breaking character. +# The extra dot is to prevent the shell from consuming trailing +# line-breaks from the sub-command output. A line-break within +# single-quotes doesn't work because, if this script is created in a +# platform that uses two characters for line-breaks (e.g., DOS), tr +# would break. +ac_LF_and_DOT=`echo; echo .` +DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` +rm -f confdef2opt.sed + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS section. +# + +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@CYGPATH_W@,$CYGPATH_W,;t t +s,@PACKAGE@,$PACKAGE,;t t +s,@VERSION@,$VERSION,;t t +s,@ACLOCAL@,$ACLOCAL,;t t +s,@AUTOCONF@,$AUTOCONF,;t t +s,@AUTOMAKE@,$AUTOMAKE,;t t +s,@AUTOHEADER@,$AUTOHEADER,;t t +s,@MAKEINFO@,$MAKEINFO,;t t +s,@AMTAR@,$AMTAR,;t t +s,@install_sh@,$install_sh,;t t +s,@STRIP@,$STRIP,;t t +s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t +s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t +s,@AWK@,$AWK,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@am__leading_dot@,$am__leading_dot,;t t +s,@ARES_VERSION@,$ARES_VERSION,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@DEPDIR@,$DEPDIR,;t t +s,@am__include@,$am__include,;t t +s,@am__quote@,$am__quote,;t t +s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t +s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t +s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t +s,@CCDEPMODE@,$CCDEPMODE,;t t +s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t +s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t +s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t +s,@MAINT@,$MAINT,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 +echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`(dirname "$mf") 2>/dev/null || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + else + continue + fi + grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue + # Extract the definition of DEP_FILES from the Makefile without + # running `make'. + DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` + test -z "$DEPDIR" && continue + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n -e '/^U = / s///p' < "$mf"` + test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" + # We invoke sed twice because it is the simplest approach to + # changing $(DEPDIR) to its actual value in the expansion. + for file in `sed -n -e ' + /^DEP_FILES = .*\\\\$/ { + s/^DEP_FILES = // + :loop + s/\\\\$// + p + n + /\\\\$/ b loop + p + } + /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`(dirname "$file") 2>/dev/null || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p $dirpart/$fdir + else + as_dir=$dirpart/$fdir + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 +echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} + { (exit 1); exit 1; }; }; } + + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + esac +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + + diff --git a/src/libs/resiprocate/contrib/ares/configure.ac b/src/libs/resiprocate/contrib/ares/configure.ac new file mode 100644 index 00000000..ebbdbf05 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/configure.ac @@ -0,0 +1,44 @@ +dnl Process this file with autoconf to produce a configure script. +AC_PREREQ(2.51) + +AC_INIT([ares_init.c],,) + +PACKAGE=ares +VERSION=1.1.2 +ARES_VERSION=${VERSION} + +AC_MSG_RESULT([Configuring ${PACKAGE} ${VERSION}]) + +dnl AC_CONFIG_SRCDIR([config.h.in]) +dnl AC_CONFIG_HEADER([config.h]) + +AM_INIT_AUTOMAKE(${PACKAGE}, ${VERSION}) +AC_SUBST(ARES_VERSION) + +AC_REVISION($Revision:$) +AC_LANG(C) +dnl AC_PROG_GXX + +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_MAKE_SET +AC_PROG_RANLIB + +AC_CANONICAL_HOST +case $host_os in +solaris*) + AC_DEFINE([ETC_INET], [], [Solaris ETC_INET flag]) + ;; +esac + +AC_ARG_WITH(ipv6, + AC_HELP_STRING([--with-ipv6],[enable ipv6]), + [CFLAGS="${CFLAGS} -DUSE_IPV6=1"]) + +AC_SEARCH_LIBS(gethostbyname, nsl) +AC_SEARCH_LIBS(socket, socket) + +AM_MAINTAINER_MODE + +AC_OUTPUT(Makefile) + diff --git a/src/libs/resiprocate/contrib/ares/depcomp b/src/libs/resiprocate/contrib/ares/depcomp new file mode 100644 index 00000000..51606f8c --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/depcomp @@ -0,0 +1,464 @@ +#! /bin/sh + +# depcomp - compile a program generating dependencies as side-effects +# Copyright 1999, 2000 Free Software Foundation, Inc. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi +# `libtool' can also be set to `yes' or `no'. + +if test -z "$depfile"; then + base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` + dir=`echo "$object" | sed 's,/.*$,/,'` + if test "$dir" = "$object"; then + dir= + fi + # FIXME: should be _deps on DOS. + depfile="$dir.deps/$base" +fi + +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. This file always lives in the current directory. + # Also, the AIX compiler puts `$object:' at the start of each line; + # $object doesn't have directory information. + stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + outname="$stripped.o" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Must come before tru64. + + # Intel's C compiler understands `-MD -MF file'. However + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^[^:]*: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + tmpdepfile1="$dir.libs/$base.lo.d" + tmpdepfile2="$dir.libs/$base.d" + "$@" -Wc,-MD + else + tmpdepfile1="$dir$base.o.d" + tmpdepfile2="$dir$base.d" + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + if test -f "$tmpdepfile1"; then + tmpdepfile="$tmpdepfile1" + else + tmpdepfile="$tmpdepfile2" + fi + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a space and a tab in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 diff --git a/src/libs/resiprocate/contrib/ares/install-sh b/src/libs/resiprocate/contrib/ares/install-sh new file mode 100644 index 00000000..e9de2384 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/src/libs/resiprocate/contrib/ares/missing b/src/libs/resiprocate/contrib/ares/missing new file mode 100644 index 00000000..6a37006e --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/missing @@ -0,0 +1,336 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# 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 2, 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing 0.4 - GNU automake" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. + You can get \`$1Help2man' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/src/libs/resiprocate/contrib/ares/mkinstalldirs b/src/libs/resiprocate/contrib/ares/mkinstalldirs new file mode 100644 index 00000000..f112d621 --- /dev/null +++ b/src/libs/resiprocate/contrib/ares/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.1 2003/06/05 00:30:38 ryker Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/src/libs/resiprocate/contrib/asio/asio.hpp b/src/libs/resiprocate/contrib/asio/asio.hpp new file mode 100644 index 00000000..d8acd585 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio.hpp @@ -0,0 +1,101 @@ +// +// asio.hpp +// ~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_HPP +#define ASIO_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/basic_datagram_socket.hpp" +#include "asio/basic_deadline_timer.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/basic_raw_socket.hpp" +#include "asio/basic_serial_port.hpp" +#include "asio/basic_socket_acceptor.hpp" +#include "asio/basic_socket_iostream.hpp" +#include "asio/basic_socket_streambuf.hpp" +#include "asio/basic_stream_socket.hpp" +#include "asio/basic_streambuf.hpp" +#include "asio/buffer.hpp" +#include "asio/buffered_read_stream_fwd.hpp" +#include "asio/buffered_read_stream.hpp" +#include "asio/buffered_stream_fwd.hpp" +#include "asio/buffered_stream.hpp" +#include "asio/buffered_write_stream_fwd.hpp" +#include "asio/buffered_write_stream.hpp" +#include "asio/buffers_iterator.hpp" +#include "asio/completion_condition.hpp" +#include "asio/datagram_socket_service.hpp" +#include "asio/deadline_timer_service.hpp" +#include "asio/deadline_timer.hpp" +#include "asio/error.hpp" +#include "asio/error_code.hpp" +#include "asio/handler_alloc_hook.hpp" +#include "asio/handler_invoke_hook.hpp" +#include "asio/io_service.hpp" +#include "asio/ip/address.hpp" +#include "asio/ip/address_v4.hpp" +#include "asio/ip/address_v6.hpp" +#include "asio/ip/basic_endpoint.hpp" +#include "asio/ip/basic_resolver.hpp" +#include "asio/ip/basic_resolver_entry.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/ip/host_name.hpp" +#include "asio/ip/icmp.hpp" +#include "asio/ip/multicast.hpp" +#include "asio/ip/resolver_query_base.hpp" +#include "asio/ip/resolver_service.hpp" +#include "asio/ip/tcp.hpp" +#include "asio/ip/udp.hpp" +#include "asio/ip/unicast.hpp" +#include "asio/ip/v6_only.hpp" +#include "asio/is_read_buffered.hpp" +#include "asio/is_write_buffered.hpp" +#include "asio/local/basic_endpoint.hpp" +#include "asio/local/connect_pair.hpp" +#include "asio/local/datagram_protocol.hpp" +#include "asio/local/stream_protocol.hpp" +#include "asio/placeholders.hpp" +#include "asio/posix/basic_descriptor.hpp" +#include "asio/posix/basic_stream_descriptor.hpp" +#include "asio/posix/descriptor_base.hpp" +#include "asio/posix/stream_descriptor.hpp" +#include "asio/posix/stream_descriptor_service.hpp" +#include "asio/raw_socket_service.hpp" +#include "asio/read.hpp" +#include "asio/read_at.hpp" +#include "asio/read_until.hpp" +#include "asio/serial_port.hpp" +#include "asio/serial_port_base.hpp" +#include "asio/serial_port_service.hpp" +#include "asio/socket_acceptor_service.hpp" +#include "asio/socket_base.hpp" +#include "asio/strand.hpp" +#include "asio/stream_socket_service.hpp" +#include "asio/streambuf.hpp" +#include "asio/system_error.hpp" +#include "asio/thread.hpp" +#include "asio/time_traits.hpp" +#include "asio/version.hpp" +#include "asio/windows/basic_handle.hpp" +#include "asio/windows/basic_random_access_handle.hpp" +#include "asio/windows/basic_stream_handle.hpp" +#include "asio/windows/overlapped_ptr.hpp" +#include "asio/windows/random_access_handle.hpp" +#include "asio/windows/random_access_handle_service.hpp" +#include "asio/windows/stream_handle.hpp" +#include "asio/windows/stream_handle_service.hpp" +#include "asio/write.hpp" +#include "asio/write_at.hpp" + +#endif // ASIO_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/basic_datagram_socket.hpp b/src/libs/resiprocate/contrib/asio/asio/basic_datagram_socket.hpp new file mode 100644 index 00000000..cb149f98 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/basic_datagram_socket.hpp @@ -0,0 +1,803 @@ +// +// basic_datagram_socket.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BASIC_DATAGRAM_SOCKET_HPP +#define ASIO_BASIC_DATAGRAM_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_socket.hpp" +#include "asio/datagram_socket_service.hpp" +#include "asio/error.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { + +/// Provides datagram-oriented socket functionality. +/** + * The basic_datagram_socket class template provides asynchronous and blocking + * datagram-oriented socket functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template > +class basic_datagram_socket + : public basic_socket +{ +public: + /// The native representation of a socket. + typedef typename DatagramSocketService::native_type native_type; + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// Construct a basic_datagram_socket without opening it. + /** + * This constructor creates a datagram socket without opening it. The open() + * function must be called before data can be sent or received on the socket. + * + * @param io_service The io_service object that the datagram socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + */ + explicit basic_datagram_socket(asio::io_service& io_service) + : basic_socket(io_service) + { + } + + /// Construct and open a basic_datagram_socket. + /** + * This constructor creates and opens a datagram socket. + * + * @param io_service The io_service object that the datagram socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws asio::system_error Thrown on failure. + */ + basic_datagram_socket(asio::io_service& io_service, + const protocol_type& protocol) + : basic_socket(io_service, protocol) + { + } + + /// Construct a basic_datagram_socket, opening it and binding it to the given + /// local endpoint. + /** + * This constructor creates a datagram socket and automatically opens it bound + * to the specified endpoint on the local machine. The protocol used is the + * protocol associated with the given endpoint. + * + * @param io_service The io_service object that the datagram socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + * + * @param endpoint An endpoint on the local machine to which the datagram + * socket will be bound. + * + * @throws asio::system_error Thrown on failure. + */ + basic_datagram_socket(asio::io_service& io_service, + const endpoint_type& endpoint) + : basic_socket(io_service, endpoint) + { + } + + /// Construct a basic_datagram_socket on an existing native socket. + /** + * This constructor creates a datagram socket object to hold an existing + * native socket. + * + * @param io_service The io_service object that the datagram socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket The new underlying socket implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_datagram_socket(asio::io_service& io_service, + const protocol_type& protocol, const native_type& native_socket) + : basic_socket( + io_service, protocol, native_socket) + { + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One ore more data buffers to be sent on the socket. + * + * @returns The number of bytes sent. + * + * @throws asio::system_error Thrown on failure. + * + * @note The send operation can only be used with a connected socket. Use + * the send_to function to send data on an unconnected datagram socket. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code socket.send(asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send(const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.send(this->implementation, buffers, 0, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One ore more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @returns The number of bytes sent. + * + * @throws asio::system_error Thrown on failure. + * + * @note The send operation can only be used with a connected socket. Use + * the send_to function to send data on an unconnected datagram socket. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->service.send( + this->implementation, buffers, flags, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes sent. + * + * @note The send operation can only be used with a connected socket. Use + * the send_to function to send data on an unconnected datagram socket. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return this->service.send(this->implementation, buffers, flags, ec); + } + + /// Start an asynchronous send on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The async_send operation can only be used with a connected socket. + * Use the async_send_to function to send data on an unconnected datagram + * socket. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_send(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_send(const ConstBufferSequence& buffers, WriteHandler handler) + { + this->service.async_send(this->implementation, buffers, 0, handler); + } + + /// Start an asynchronous send on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The async_send operation can only be used with a connected socket. + * Use the async_send_to function to send data on an unconnected datagram + * socket. + */ + template + void async_send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, WriteHandler handler) + { + this->service.async_send(this->implementation, buffers, flags, handler); + } + + /// Send a datagram to the specified endpoint. + /** + * This function is used to send a datagram to the specified remote endpoint. + * The function call will block until the data has been sent successfully or + * an error occurs. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * + * @param destination The remote endpoint to which the data will be sent. + * + * @returns The number of bytes sent. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * asio::ip::udp::endpoint destination( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.send_to(asio::buffer(data, size), destination); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination) + { + asio::error_code ec; + std::size_t s = this->service.send_to( + this->implementation, buffers, destination, 0, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Send a datagram to the specified endpoint. + /** + * This function is used to send a datagram to the specified remote endpoint. + * The function call will block until the data has been sent successfully or + * an error occurs. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * + * @param destination The remote endpoint to which the data will be sent. + * + * @param flags Flags specifying how the send call is to be made. + * + * @returns The number of bytes sent. + * + * @throws asio::system_error Thrown on failure. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->service.send_to( + this->implementation, buffers, destination, flags, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Send a datagram to the specified endpoint. + /** + * This function is used to send a datagram to the specified remote endpoint. + * The function call will block until the data has been sent successfully or + * an error occurs. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * + * @param destination The remote endpoint to which the data will be sent. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes sent. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + asio::error_code& ec) + { + return this->service.send_to(this->implementation, + buffers, destination, flags, ec); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send a datagram to the specified + * remote endpoint. The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param destination The remote endpoint to which the data will be sent. + * Copies will be made of the endpoint as required. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * asio::ip::udp::endpoint destination( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.async_send_to( + * asio::buffer(data, size), destination, handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, WriteHandler handler) + { + this->service.async_send_to(this->implementation, buffers, destination, 0, + handler); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send a datagram to the specified + * remote endpoint. The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param destination The remote endpoint to which the data will be sent. + * Copies will be made of the endpoint as required. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + */ + template + void async_send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + WriteHandler handler) + { + this->service.async_send_to(this->implementation, buffers, destination, + flags, handler); + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the datagram socket. The function + * call will block until data has been received successfully or an error + * occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. + * + * @note The receive operation can only be used with a connected socket. Use + * the receive_from function to receive data on an unconnected datagram + * socket. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code socket.receive(asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive(const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.receive( + this->implementation, buffers, 0, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the datagram socket. The function + * call will block until data has been received successfully or an error + * occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. + * + * @note The receive operation can only be used with a connected socket. Use + * the receive_from function to receive data on an unconnected datagram + * socket. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->service.receive( + this->implementation, buffers, flags, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the datagram socket. The function + * call will block until data has been received successfully or an error + * occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes received. + * + * @note The receive operation can only be used with a connected socket. Use + * the receive_from function to receive data on an unconnected datagram + * socket. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return this->service.receive(this->implementation, buffers, flags, ec); + } + + /// Start an asynchronous receive on a connected socket. + /** + * This function is used to asynchronously receive data from the datagram + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The async_receive operation can only be used with a connected socket. + * Use the async_receive_from function to receive data on an unconnected + * datagram socket. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_receive(const MutableBufferSequence& buffers, ReadHandler handler) + { + this->service.async_receive(this->implementation, buffers, 0, handler); + } + + /// Start an asynchronous receive on a connected socket. + /** + * This function is used to asynchronously receive data from the datagram + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The async_receive operation can only be used with a connected socket. + * Use the async_receive_from function to receive data on an unconnected + * datagram socket. + */ + template + void async_receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, ReadHandler handler) + { + this->service.async_receive(this->implementation, buffers, flags, handler); + } + + /// Receive a datagram with the endpoint of the sender. + /** + * This function is used to receive a datagram. The function call will block + * until data has been received successfully or an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * asio::ip::udp::endpoint sender_endpoint; + * socket.receive_from( + * asio::buffer(data, size), sender_endpoint); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint) + { + asio::error_code ec; + std::size_t s = this->service.receive_from( + this->implementation, buffers, sender_endpoint, 0, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Receive a datagram with the endpoint of the sender. + /** + * This function is used to receive a datagram. The function call will block + * until data has been received successfully or an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->service.receive_from( + this->implementation, buffers, sender_endpoint, flags, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Receive a datagram with the endpoint of the sender. + /** + * This function is used to receive a datagram. The function call will block + * until data has been received successfully or an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes received. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + asio::error_code& ec) + { + return this->service.receive_from(this->implementation, buffers, + sender_endpoint, flags, ec); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive a datagram. The function + * call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. Ownership of the sender_endpoint object + * is retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code socket.async_receive_from( + * asio::buffer(data, size), 0, sender_endpoint, handler); @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, ReadHandler handler) + { + this->service.async_receive_from(this->implementation, buffers, + sender_endpoint, 0, handler); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive a datagram. The function + * call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. Ownership of the sender_endpoint object + * is retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + */ + template + void async_receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + ReadHandler handler) + { + this->service.async_receive_from(this->implementation, buffers, + sender_endpoint, flags, handler); + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_DATAGRAM_SOCKET_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/basic_deadline_timer.hpp b/src/libs/resiprocate/contrib/asio/asio/basic_deadline_timer.hpp new file mode 100644 index 00000000..0d183f76 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/basic_deadline_timer.hpp @@ -0,0 +1,445 @@ +// +// basic_deadline_timer.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BASIC_DEADLINE_TIMER_HPP +#define ASIO_BASIC_DEADLINE_TIMER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_io_object.hpp" +#include "asio/deadline_timer_service.hpp" +#include "asio/error.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { + +/// Provides waitable timer functionality. +/** + * The basic_deadline_timer class template provides the ability to perform a + * blocking or asynchronous wait for a timer to expire. + * + * A deadline timer is always in one of two states: "expired" or "not expired". + * If the wait() or async_wait() function is called on an expired timer, the + * wait operation will complete immediately. + * + * Most applications will use the asio::deadline_timer typedef. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Examples + * Performing a blocking wait: + * @code + * // Construct a timer without setting an expiry time. + * asio::deadline_timer timer(io_service); + * + * // Set an expiry time relative to now. + * timer.expires_from_now(boost::posix_time::seconds(5)); + * + * // Wait for the timer to expire. + * timer.wait(); + * @endcode + * + * @par + * Performing an asynchronous wait: + * @code + * void handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Timer expired. + * } + * } + * + * ... + * + * // Construct a timer with an absolute expiry time. + * asio::deadline_timer timer(io_service, + * boost::posix_time::time_from_string("2005-12-07 23:59:59.000")); + * + * // Start an asynchronous wait. + * timer.async_wait(handler); + * @endcode + * + * @par Changing an active deadline_timer's expiry time + * + * Changing the expiry time of a timer while there are pending asynchronous + * waits causes those wait operations to be cancelled. To ensure that the action + * associated with the timer is performed only once, use something like this: + * used: + * + * @code + * void on_some_event() + * { + * if (my_timer.expires_from_now(seconds(5)) > 0) + * { + * // We managed to cancel the timer. Start new asynchronous wait. + * my_timer.async_wait(on_timeout); + * } + * else + * { + * // Too late, timer has already expired! + * } + * } + * + * void on_timeout(const asio::error_code& e) + * { + * if (e != asio::error::operation_aborted) + * { + * // Timer was not cancelled, take necessary action. + * } + * } + * @endcode + * + * @li The asio::basic_deadline_timer::expires_from_now() function + * cancels any pending asynchronous waits, and returns the number of + * asynchronous waits that were cancelled. If it returns 0 then you were too + * late and the wait handler has already been executed, or will soon be + * executed. If it returns 1 then the wait handler was successfully cancelled. + * + * @li If a wait handler is cancelled, the asio::error_code passed to + * it contains the value asio::error::operation_aborted. + */ +template , + typename TimerService = deadline_timer_service > +class basic_deadline_timer + : public basic_io_object +{ +public: + /// The time traits type. + typedef TimeTraits traits_type; + + /// The time type. + typedef typename traits_type::time_type time_type; + + /// The duration type. + typedef typename traits_type::duration_type duration_type; + + /// Constructor. + /** + * This constructor creates a timer without setting an expiry time. The + * expires_at() or expires_from_now() functions must be called to set an + * expiry time before the timer can be waited on. + * + * @param io_service The io_service object that the timer will use to dispatch + * handlers for any asynchronous operations performed on the timer. + */ + explicit basic_deadline_timer(asio::io_service& io_service) + : basic_io_object(io_service) + { + } + + /// Constructor to set a particular expiry time as an absolute time. + /** + * This constructor creates a timer and sets the expiry time. + * + * @param io_service The io_service object that the timer will use to dispatch + * handlers for any asynchronous operations performed on the timer. + * + * @param expiry_time The expiry time to be used for the timer, expressed + * as an absolute time. + */ + basic_deadline_timer(asio::io_service& io_service, + const time_type& expiry_time) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.expires_at(this->implementation, expiry_time, ec); + asio::detail::throw_error(ec); + } + + /// Constructor to set a particular expiry time relative to now. + /** + * This constructor creates a timer and sets the expiry time. + * + * @param io_service The io_service object that the timer will use to dispatch + * handlers for any asynchronous operations performed on the timer. + * + * @param expiry_time The expiry time to be used for the timer, relative to + * now. + */ + basic_deadline_timer(asio::io_service& io_service, + const duration_type& expiry_time) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.expires_from_now(this->implementation, expiry_time, ec); + asio::detail::throw_error(ec); + } + + /// Cancel any asynchronous operations that are waiting on the timer. + /** + * This function forces the completion of any pending asynchronous wait + * operations against the timer. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * Cancelling the timer does not change the expiry time. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws asio::system_error Thrown on failure. + * + * @note If the timer has already expired when cancel() is called, then the + * handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t cancel() + { + asio::error_code ec; + std::size_t s = this->service.cancel(this->implementation, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Cancel any asynchronous operations that are waiting on the timer. + /** + * This function forces the completion of any pending asynchronous wait + * operations against the timer. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * Cancelling the timer does not change the expiry time. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. + * + * @note If the timer has already expired when cancel() is called, then the + * handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t cancel(asio::error_code& ec) + { + return this->service.cancel(this->implementation, ec); + } + + /// Get the timer's expiry time as an absolute time. + /** + * This function may be used to obtain the timer's current expiry time. + * Whether the timer has expired or not does not affect this value. + */ + time_type expires_at() const + { + return this->service.expires_at(this->implementation); + } + + /// Set the timer's expiry time as an absolute time. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws asio::system_error Thrown on failure. + * + * @note If the timer has already expired when expires_at() is called, then + * the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_at(const time_type& expiry_time) + { + asio::error_code ec; + std::size_t s = this->service.expires_at( + this->implementation, expiry_time, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Set the timer's expiry time as an absolute time. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. + * + * @note If the timer has already expired when expires_at() is called, then + * the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_at(const time_type& expiry_time, + asio::error_code& ec) + { + return this->service.expires_at(this->implementation, expiry_time, ec); + } + + /// Get the timer's expiry time relative to now. + /** + * This function may be used to obtain the timer's current expiry time. + * Whether the timer has expired or not does not affect this value. + */ + duration_type expires_from_now() const + { + return this->service.expires_from_now(this->implementation); + } + + /// Set the timer's expiry time relative to now. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @return The number of asynchronous operations that were cancelled. + * + * @throws asio::system_error Thrown on failure. + * + * @note If the timer has already expired when expires_from_now() is called, + * then the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_from_now(const duration_type& expiry_time) + { + asio::error_code ec; + std::size_t s = this->service.expires_from_now( + this->implementation, expiry_time, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Set the timer's expiry time relative to now. + /** + * This function sets the expiry time. Any pending asynchronous wait + * operations will be cancelled. The handler for each cancelled operation will + * be invoked with the asio::error::operation_aborted error code. + * + * @param expiry_time The expiry time to be used for the timer. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of asynchronous operations that were cancelled. + * + * @note If the timer has already expired when expires_from_now() is called, + * then the handlers for asynchronous wait operations will: + * + * @li have already been invoked; or + * + * @li have been queued for invocation in the near future. + * + * These handlers can no longer be cancelled, and therefore are passed an + * error code that indicates the successful completion of the wait operation. + */ + std::size_t expires_from_now(const duration_type& expiry_time, + asio::error_code& ec) + { + return this->service.expires_from_now( + this->implementation, expiry_time, ec); + } + + /// Perform a blocking wait on the timer. + /** + * This function is used to wait for the timer to expire. This function + * blocks and does not return until the timer has expired. + * + * @throws asio::system_error Thrown on failure. + */ + void wait() + { + asio::error_code ec; + this->service.wait(this->implementation, ec); + asio::detail::throw_error(ec); + } + + /// Perform a blocking wait on the timer. + /** + * This function is used to wait for the timer to expire. This function + * blocks and does not return until the timer has expired. + * + * @param ec Set to indicate what error occurred, if any. + */ + void wait(asio::error_code& ec) + { + this->service.wait(this->implementation, ec); + } + + /// Start an asynchronous wait on the timer. + /** + * This function may be used to initiate an asynchronous wait against the + * timer. It always returns immediately. + * + * For each call to async_wait(), the supplied handler will be called exactly + * once. The handler will be called when: + * + * @li The timer has expired. + * + * @li The timer was cancelled, in which case the handler is passed the error + * code asio::error::operation_aborted. + * + * @param handler The handler to be called when the timer expires. Copies + * will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const asio::error_code& error // Result of operation. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + */ + template + void async_wait(WaitHandler handler) + { + this->service.async_wait(this->implementation, handler); + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_DEADLINE_TIMER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/basic_io_object.hpp b/src/libs/resiprocate/contrib/asio/asio/basic_io_object.hpp new file mode 100644 index 00000000..092170df --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/basic_io_object.hpp @@ -0,0 +1,97 @@ +// +// basic_io_object.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BASIC_IO_OBJECT_HPP +#define ASIO_BASIC_IO_OBJECT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/io_service.hpp" +#include "asio/detail/noncopyable.hpp" + +namespace asio { + +/// Base class for all I/O objects. +template +class basic_io_object + : private noncopyable +{ +public: + /// The type of the service that will be used to provide I/O operations. + typedef IoObjectService service_type; + + /// The underlying implementation type of I/O object. + typedef typename service_type::implementation_type implementation_type; + + /// (Deprecated: use get_io_service().) Get the io_service associated with + /// the object. + /** + * This function may be used to obtain the io_service object that the I/O + * object uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_service object that the I/O object will use + * to dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_service& io_service() + { + return service.get_io_service(); + } + + /// Get the io_service associated with the object. + /** + * This function may be used to obtain the io_service object that the I/O + * object uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_service object that the I/O object will use + * to dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_service& get_io_service() + { + return service.get_io_service(); + } + +protected: + /// Construct a basic_io_object. + /** + * Performs: + * @code service.construct(implementation); @endcode + */ + explicit basic_io_object(asio::io_service& io_service) + : service(asio::use_service(io_service)) + { + service.construct(implementation); + } + + /// Protected destructor to prevent deletion through this type. + /** + * Performs: + * @code service.destroy(implementation); @endcode + */ + ~basic_io_object() + { + service.destroy(implementation); + } + + /// The service associated with the I/O object. + service_type& service; + + /// The underlying implementation of the I/O object. + implementation_type implementation; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_IO_OBJECT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/basic_raw_socket.hpp b/src/libs/resiprocate/contrib/asio/asio/basic_raw_socket.hpp new file mode 100644 index 00000000..9d93b97f --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/basic_raw_socket.hpp @@ -0,0 +1,798 @@ +// +// basic_raw_socket.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BASIC_RAW_SOCKET_HPP +#define ASIO_BASIC_RAW_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_socket.hpp" +#include "asio/raw_socket_service.hpp" +#include "asio/error.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { + +/// Provides raw-oriented socket functionality. +/** + * The basic_raw_socket class template provides asynchronous and blocking + * raw-oriented socket functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template > +class basic_raw_socket + : public basic_socket +{ +public: + /// The native representation of a socket. + typedef typename RawSocketService::native_type native_type; + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// Construct a basic_raw_socket without opening it. + /** + * This constructor creates a raw socket without opening it. The open() + * function must be called before data can be sent or received on the socket. + * + * @param io_service The io_service object that the raw socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + */ + explicit basic_raw_socket(asio::io_service& io_service) + : basic_socket(io_service) + { + } + + /// Construct and open a basic_raw_socket. + /** + * This constructor creates and opens a raw socket. + * + * @param io_service The io_service object that the raw socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws asio::system_error Thrown on failure. + */ + basic_raw_socket(asio::io_service& io_service, + const protocol_type& protocol) + : basic_socket(io_service, protocol) + { + } + + /// Construct a basic_raw_socket, opening it and binding it to the given + /// local endpoint. + /** + * This constructor creates a raw socket and automatically opens it bound + * to the specified endpoint on the local machine. The protocol used is the + * protocol associated with the given endpoint. + * + * @param io_service The io_service object that the raw socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + * + * @param endpoint An endpoint on the local machine to which the raw + * socket will be bound. + * + * @throws asio::system_error Thrown on failure. + */ + basic_raw_socket(asio::io_service& io_service, + const endpoint_type& endpoint) + : basic_socket(io_service, endpoint) + { + } + + /// Construct a basic_raw_socket on an existing native socket. + /** + * This constructor creates a raw socket object to hold an existing + * native socket. + * + * @param io_service The io_service object that the raw socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket The new underlying socket implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_raw_socket(asio::io_service& io_service, + const protocol_type& protocol, const native_type& native_socket) + : basic_socket( + io_service, protocol, native_socket) + { + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the raw socket. The function call + * will block until the data has been sent successfully or an error occurs. + * + * @param buffers One ore more data buffers to be sent on the socket. + * + * @returns The number of bytes sent. + * + * @throws asio::system_error Thrown on failure. + * + * @note The send operation can only be used with a connected socket. Use + * the send_to function to send data on an unconnected raw socket. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code socket.send(asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send(const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.send(this->implementation, buffers, 0, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the raw socket. The function call + * will block until the data has been sent successfully or an error occurs. + * + * @param buffers One ore more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @returns The number of bytes sent. + * + * @throws asio::system_error Thrown on failure. + * + * @note The send operation can only be used with a connected socket. Use + * the send_to function to send data on an unconnected raw socket. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->service.send( + this->implementation, buffers, flags, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the raw socket. The function call + * will block until the data has been sent successfully or an error occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes sent. + * + * @note The send operation can only be used with a connected socket. Use + * the send_to function to send data on an unconnected raw socket. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return this->service.send(this->implementation, buffers, flags, ec); + } + + /// Start an asynchronous send on a connected socket. + /** + * This function is used to send data on the raw socket. The function call + * will block until the data has been sent successfully or an error occurs. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The async_send operation can only be used with a connected socket. + * Use the async_send_to function to send data on an unconnected raw + * socket. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_send(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_send(const ConstBufferSequence& buffers, WriteHandler handler) + { + this->service.async_send(this->implementation, buffers, 0, handler); + } + + /// Start an asynchronous send on a connected socket. + /** + * This function is used to send data on the raw socket. The function call + * will block until the data has been sent successfully or an error occurs. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The async_send operation can only be used with a connected socket. + * Use the async_send_to function to send data on an unconnected raw + * socket. + */ + template + void async_send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, WriteHandler handler) + { + this->service.async_send(this->implementation, buffers, flags, handler); + } + + /// Send raw data to the specified endpoint. + /** + * This function is used to send raw data to the specified remote endpoint. + * The function call will block until the data has been sent successfully or + * an error occurs. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * + * @param destination The remote endpoint to which the data will be sent. + * + * @returns The number of bytes sent. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * asio::ip::udp::endpoint destination( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.send_to(asio::buffer(data, size), destination); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination) + { + asio::error_code ec; + std::size_t s = this->service.send_to( + this->implementation, buffers, destination, 0, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Send raw data to the specified endpoint. + /** + * This function is used to send raw data to the specified remote endpoint. + * The function call will block until the data has been sent successfully or + * an error occurs. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * + * @param destination The remote endpoint to which the data will be sent. + * + * @param flags Flags specifying how the send call is to be made. + * + * @returns The number of bytes sent. + * + * @throws asio::system_error Thrown on failure. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->service.send_to( + this->implementation, buffers, destination, flags, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Send raw data to the specified endpoint. + /** + * This function is used to send raw data to the specified remote endpoint. + * The function call will block until the data has been sent successfully or + * an error occurs. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * + * @param destination The remote endpoint to which the data will be sent. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes sent. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + asio::error_code& ec) + { + return this->service.send_to(this->implementation, + buffers, destination, flags, ec); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send raw data to the specified + * remote endpoint. The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param destination The remote endpoint to which the data will be sent. + * Copies will be made of the endpoint as required. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * asio::ip::udp::endpoint destination( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.async_send_to( + * asio::buffer(data, size), destination, handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, WriteHandler handler) + { + this->service.async_send_to(this->implementation, buffers, destination, 0, + handler); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send raw data to the specified + * remote endpoint. The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param destination The remote endpoint to which the data will be sent. + * Copies will be made of the endpoint as required. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + */ + template + void async_send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + WriteHandler handler) + { + this->service.async_send_to(this->implementation, buffers, destination, + flags, handler); + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the raw socket. The function + * call will block until data has been received successfully or an error + * occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. + * + * @note The receive operation can only be used with a connected socket. Use + * the receive_from function to receive data on an unconnected raw + * socket. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code socket.receive(asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive(const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.receive( + this->implementation, buffers, 0, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the raw socket. The function + * call will block until data has been received successfully or an error + * occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. + * + * @note The receive operation can only be used with a connected socket. Use + * the receive_from function to receive data on an unconnected raw + * socket. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->service.receive( + this->implementation, buffers, flags, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the raw socket. The function + * call will block until data has been received successfully or an error + * occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes received. + * + * @note The receive operation can only be used with a connected socket. Use + * the receive_from function to receive data on an unconnected raw + * socket. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return this->service.receive(this->implementation, buffers, flags, ec); + } + + /// Start an asynchronous receive on a connected socket. + /** + * This function is used to asynchronously receive data from the raw + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The async_receive operation can only be used with a connected socket. + * Use the async_receive_from function to receive data on an unconnected + * raw socket. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_receive(const MutableBufferSequence& buffers, ReadHandler handler) + { + this->service.async_receive(this->implementation, buffers, 0, handler); + } + + /// Start an asynchronous receive on a connected socket. + /** + * This function is used to asynchronously receive data from the raw + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The async_receive operation can only be used with a connected socket. + * Use the async_receive_from function to receive data on an unconnected + * raw socket. + */ + template + void async_receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, ReadHandler handler) + { + this->service.async_receive(this->implementation, buffers, flags, handler); + } + + /// Receive raw data with the endpoint of the sender. + /** + * This function is used to receive raw data. The function call will block + * until data has been received successfully or an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the data. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * asio::ip::udp::endpoint sender_endpoint; + * socket.receive_from( + * asio::buffer(data, size), sender_endpoint); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint) + { + asio::error_code ec; + std::size_t s = this->service.receive_from( + this->implementation, buffers, sender_endpoint, 0, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Receive raw data with the endpoint of the sender. + /** + * This function is used to receive raw data. The function call will block + * until data has been received successfully or an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the data. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->service.receive_from( + this->implementation, buffers, sender_endpoint, flags, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Receive raw data with the endpoint of the sender. + /** + * This function is used to receive raw data. The function call will block + * until data has been received successfully or an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the data. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes received. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + asio::error_code& ec) + { + return this->service.receive_from(this->implementation, buffers, + sender_endpoint, flags, ec); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive raw data. The function + * call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the data. Ownership of the sender_endpoint object + * is retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code socket.async_receive_from( + * asio::buffer(data, size), 0, sender_endpoint, handler); @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, ReadHandler handler) + { + this->service.async_receive_from(this->implementation, buffers, + sender_endpoint, 0, handler); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive raw data. The function + * call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the data. Ownership of the sender_endpoint object + * is retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + */ + template + void async_receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + ReadHandler handler) + { + this->service.async_receive_from(this->implementation, buffers, + sender_endpoint, flags, handler); + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_RAW_SOCKET_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/basic_serial_port.hpp b/src/libs/resiprocate/contrib/asio/asio/basic_serial_port.hpp new file mode 100644 index 00000000..edb7bb07 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/basic_serial_port.hpp @@ -0,0 +1,622 @@ +// +// basic_serial_port.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BASIC_SERIAL_PORT_HPP +#define ASIO_BASIC_SERIAL_PORT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_io_object.hpp" +#include "asio/error.hpp" +#include "asio/serial_port_base.hpp" +#include "asio/serial_port_service.hpp" +#include "asio/detail/throw_error.hpp" + +#if defined(ASIO_HAS_SERIAL_PORT) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { + +/// Provides serial port functionality. +/** + * The basic_serial_port class template provides functionality that is common + * to all serial ports. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_serial_port + : public basic_io_object, + public serial_port_base +{ +public: + /// The native representation of a serial port. + typedef typename SerialPortService::native_type native_type; + + /// A basic_serial_port is always the lowest layer. + typedef basic_serial_port lowest_layer_type; + + /// Construct a basic_serial_port without opening it. + /** + * This constructor creates a serial port without opening it. + * + * @param io_service The io_service object that the serial port will use to + * dispatch handlers for any asynchronous operations performed on the port. + */ + explicit basic_serial_port(asio::io_service& io_service) + : basic_io_object(io_service) + { + } + + /// Construct and open a basic_serial_port. + /** + * This constructor creates and opens a serial port for the specified device + * name. + * + * @param io_service The io_service object that the serial port will use to + * dispatch handlers for any asynchronous operations performed on the port. + * + * @param device The platform-specific device name for this serial + * port. + */ + explicit basic_serial_port(asio::io_service& io_service, + const char* device) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.open(this->implementation, device, ec); + asio::detail::throw_error(ec); + } + + /// Construct and open a basic_serial_port. + /** + * This constructor creates and opens a serial port for the specified device + * name. + * + * @param io_service The io_service object that the serial port will use to + * dispatch handlers for any asynchronous operations performed on the port. + * + * @param device The platform-specific device name for this serial + * port. + */ + explicit basic_serial_port(asio::io_service& io_service, + const std::string& device) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.open(this->implementation, device, ec); + asio::detail::throw_error(ec); + } + + /// Construct a basic_serial_port on an existing native serial port. + /** + * This constructor creates a serial port object to hold an existing native + * serial port. + * + * @param io_service The io_service object that the serial port will use to + * dispatch handlers for any asynchronous operations performed on the port. + * + * @param native_serial_port A native serial port. + * + * @throws asio::system_error Thrown on failure. + */ + basic_serial_port(asio::io_service& io_service, + const native_type& native_serial_port) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.assign(this->implementation, native_serial_port, ec); + asio::detail::throw_error(ec); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since a basic_serial_port cannot contain any further layers, it + * simply returns a reference to itself. + * + * @return A reference to the lowest layer in the stack of layers. Ownership + * is not transferred to the caller. + */ + lowest_layer_type& lowest_layer() + { + return *this; + } + + /// Get a const reference to the lowest layer. + /** + * This function returns a const reference to the lowest layer in a stack of + * layers. Since a basic_serial_port cannot contain any further layers, it + * simply returns a reference to itself. + * + * @return A const reference to the lowest layer in the stack of layers. + * Ownership is not transferred to the caller. + */ + const lowest_layer_type& lowest_layer() const + { + return *this; + } + + /// Open the serial port using the specified device name. + /** + * This function opens the serial port for the specified device name. + * + * @param device The platform-specific device name. + * + * @throws asio::system_error Thrown on failure. + */ + void open(const std::string& device) + { + asio::error_code ec; + this->service.open(this->implementation, device, ec); + asio::detail::throw_error(ec); + } + + /// Open the serial port using the specified device name. + /** + * This function opens the serial port using the given platform-specific + * device name. + * + * @param device The platform-specific device name. + * + * @param ec Set the indicate what error occurred, if any. + */ + asio::error_code open(const std::string& device, + asio::error_code& ec) + { + return this->service.open(this->implementation, device, ec); + } + + /// Assign an existing native serial port to the serial port. + /* + * This function opens the serial port to hold an existing native serial port. + * + * @param native_serial_port A native serial port. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_type& native_serial_port) + { + asio::error_code ec; + this->service.assign(this->implementation, native_serial_port, ec); + asio::detail::throw_error(ec); + } + + /// Assign an existing native serial port to the serial port. + /* + * This function opens the serial port to hold an existing native serial port. + * + * @param native_serial_port A native serial port. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code assign(const native_type& native_serial_port, + asio::error_code& ec) + { + return this->service.assign(this->implementation, native_serial_port, ec); + } + + /// Determine whether the serial port is open. + bool is_open() const + { + return this->service.is_open(this->implementation); + } + + /// Close the serial port. + /** + * This function is used to close the serial port. Any asynchronous read or + * write operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->service.close(this->implementation, ec); + asio::detail::throw_error(ec); + } + + /// Close the serial port. + /** + * This function is used to close the serial port. Any asynchronous read or + * write operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code close(asio::error_code& ec) + { + return this->service.close(this->implementation, ec); + } + + /// Get the native serial port representation. + /** + * This function may be used to obtain the underlying representation of the + * serial port. This is intended to allow access to native serial port + * functionality that is not otherwise provided. + */ + native_type native() + { + return this->service.native(this->implementation); + } + + /// Cancel all asynchronous operations associated with the serial port. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->service.cancel(this->implementation, ec); + asio::detail::throw_error(ec); + } + + /// Cancel all asynchronous operations associated with the serial port. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code cancel(asio::error_code& ec) + { + return this->service.cancel(this->implementation, ec); + } + + /// Send a break sequence to the serial port. + /** + * This function causes a break sequence of platform-specific duration to be + * sent out the serial port. + * + * @throws asio::system_error Thrown on failure. + */ + void send_break() + { + asio::error_code ec; + this->service.send_break(this->implementation, ec); + asio::detail::throw_error(ec); + } + + /// Send a break sequence to the serial port. + /** + * This function causes a break sequence of platform-specific duration to be + * sent out the serial port. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code send_break(asio::error_code& ec) + { + return this->service.send_break(this->implementation, ec); + } + + /// Set an option on the serial port. + /** + * This function is used to set an option on the serial port. + * + * @param option The option value to be set on the serial port. + * + * @throws asio::system_error Thrown on failure. + * + * @sa SettableSerialPortOption @n + * asio::serial_port_base::baud_rate @n + * asio::serial_port_base::flow_control @n + * asio::serial_port_base::parity @n + * asio::serial_port_base::stop_bits @n + * asio::serial_port_base::character_size + */ + template + void set_option(const SettableSerialPortOption& option) + { + asio::error_code ec; + this->service.set_option(this->implementation, option, ec); + asio::detail::throw_error(ec); + } + + /// Set an option on the serial port. + /** + * This function is used to set an option on the serial port. + * + * @param option The option value to be set on the serial port. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa SettableSerialPortOption @n + * asio::serial_port_base::baud_rate @n + * asio::serial_port_base::flow_control @n + * asio::serial_port_base::parity @n + * asio::serial_port_base::stop_bits @n + * asio::serial_port_base::character_size + */ + template + asio::error_code set_option(const SettableSerialPortOption& option, + asio::error_code& ec) + { + return this->service.set_option(this->implementation, option, ec); + } + + /// Get an option from the serial port. + /** + * This function is used to get the current value of an option on the serial + * port. + * + * @param option The option value to be obtained from the serial port. + * + * @throws asio::system_error Thrown on failure. + * + * @sa GettableSerialPortOption @n + * asio::serial_port_base::baud_rate @n + * asio::serial_port_base::flow_control @n + * asio::serial_port_base::parity @n + * asio::serial_port_base::stop_bits @n + * asio::serial_port_base::character_size + */ + template + void get_option(GettableSerialPortOption& option) + { + asio::error_code ec; + this->service.get_option(this->implementation, option, ec); + asio::detail::throw_error(ec); + } + + /// Get an option from the serial port. + /** + * This function is used to get the current value of an option on the serial + * port. + * + * @param option The option value to be obtained from the serial port. + * + * @param ec Set to indicate what error occured, if any. + * + * @sa GettableSerialPortOption @n + * asio::serial_port_base::baud_rate @n + * asio::serial_port_base::flow_control @n + * asio::serial_port_base::parity @n + * asio::serial_port_base::stop_bits @n + * asio::serial_port_base::character_size + */ + template + asio::error_code get_option(GettableSerialPortOption& option, + asio::error_code& ec) + { + return this->service.get_option(this->implementation, option, ec); + } + + /// Write some data to the serial port. + /** + * This function is used to write data to the serial port. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the serial port. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * serial_port.write_some(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.write_some(this->implementation, buffers, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Write some data to the serial port. + /** + * This function is used to write data to the serial port. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the serial port. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. Returns 0 if an error occurred. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) + { + return this->service.write_some(this->implementation, buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the serial port. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the serial port. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * serial_port.async_write_some(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + this->service.async_write_some(this->implementation, buffers, handler); + } + + /// Read some data from the serial port. + /** + * This function is used to read data from the serial port. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * serial_port.read_some(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.read_some(this->implementation, buffers, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Read some data from the serial port. + /** + * This function is used to read data from the serial port. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. Returns 0 if an error occurred. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return this->service.read_some(this->implementation, buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the serial port. + * The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be read. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read function if you need to ensure that the + * requested amount of data is read before the asynchronous operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * serial_port.async_read_some(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + this->service.async_read_some(this->implementation, buffers, handler); + } +}; + +} // namespace asio + +#endif // defined(ASIO_HAS_SERIAL_PORT) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_SERIAL_PORT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/basic_socket.hpp b/src/libs/resiprocate/contrib/asio/asio/basic_socket.hpp new file mode 100644 index 00000000..8b3f1d7f --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/basic_socket.hpp @@ -0,0 +1,1063 @@ +// +// basic_socket.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BASIC_SOCKET_HPP +#define ASIO_BASIC_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_io_object.hpp" +#include "asio/error.hpp" +#include "asio/socket_base.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { + +/// Provides socket functionality. +/** + * The basic_socket class template provides functionality that is common to both + * stream-oriented and datagram-oriented sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_socket + : public basic_io_object, + public socket_base +{ +public: + /// The native representation of a socket. + typedef typename SocketService::native_type native_type; + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// A basic_socket is always the lowest layer. + typedef basic_socket lowest_layer_type; + + /// Construct a basic_socket without opening it. + /** + * This constructor creates a socket without opening it. + * + * @param io_service The io_service object that the socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + */ + explicit basic_socket(asio::io_service& io_service) + : basic_io_object(io_service) + { + } + + /// Construct and open a basic_socket. + /** + * This constructor creates and opens a socket. + * + * @param io_service The io_service object that the socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws asio::system_error Thrown on failure. + */ + basic_socket(asio::io_service& io_service, + const protocol_type& protocol) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.open(this->implementation, protocol, ec); + asio::detail::throw_error(ec); + } + + /// Construct a basic_socket, opening it and binding it to the given local + /// endpoint. + /** + * This constructor creates a socket and automatically opens it bound to the + * specified endpoint on the local machine. The protocol used is the protocol + * associated with the given endpoint. + * + * @param io_service The io_service object that the socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param endpoint An endpoint on the local machine to which the socket will + * be bound. + * + * @throws asio::system_error Thrown on failure. + */ + basic_socket(asio::io_service& io_service, + const endpoint_type& endpoint) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.open(this->implementation, endpoint.protocol(), ec); + asio::detail::throw_error(ec); + this->service.bind(this->implementation, endpoint, ec); + asio::detail::throw_error(ec); + } + + /// Construct a basic_socket on an existing native socket. + /** + * This constructor creates a socket object to hold an existing native socket. + * + * @param io_service The io_service object that the socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket A native socket. + * + * @throws asio::system_error Thrown on failure. + */ + basic_socket(asio::io_service& io_service, + const protocol_type& protocol, const native_type& native_socket) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.assign(this->implementation, protocol, native_socket, ec); + asio::detail::throw_error(ec); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since a basic_socket cannot contain any further layers, it simply + * returns a reference to itself. + * + * @return A reference to the lowest layer in the stack of layers. Ownership + * is not transferred to the caller. + */ + lowest_layer_type& lowest_layer() + { + return *this; + } + + /// Get a const reference to the lowest layer. + /** + * This function returns a const reference to the lowest layer in a stack of + * layers. Since a basic_socket cannot contain any further layers, it simply + * returns a reference to itself. + * + * @return A const reference to the lowest layer in the stack of layers. + * Ownership is not transferred to the caller. + */ + const lowest_layer_type& lowest_layer() const + { + return *this; + } + + /// Open the socket using the specified protocol. + /** + * This function opens the socket so that it will use the specified protocol. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * socket.open(asio::ip::tcp::v4()); + * @endcode + */ + void open(const protocol_type& protocol = protocol_type()) + { + asio::error_code ec; + this->service.open(this->implementation, protocol, ec); + asio::detail::throw_error(ec); + } + + /// Open the socket using the specified protocol. + /** + * This function opens the socket so that it will use the specified protocol. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * asio::error_code ec; + * socket.open(asio::ip::tcp::v4(), ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + asio::error_code open(const protocol_type& protocol, + asio::error_code& ec) + { + return this->service.open(this->implementation, protocol, ec); + } + + /// Assign an existing native socket to the socket. + /* + * This function opens the socket to hold an existing native socket. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param native_socket A native socket. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const protocol_type& protocol, const native_type& native_socket) + { + asio::error_code ec; + this->service.assign(this->implementation, protocol, native_socket, ec); + asio::detail::throw_error(ec); + } + + /// Assign an existing native socket to the socket. + /* + * This function opens the socket to hold an existing native socket. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param native_socket A native socket. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code assign(const protocol_type& protocol, + const native_type& native_socket, asio::error_code& ec) + { + return this->service.assign(this->implementation, + protocol, native_socket, ec); + } + + /// Determine whether the socket is open. + bool is_open() const + { + return this->service.is_open(this->implementation); + } + + /// Close the socket. + /** + * This function is used to close the socket. Any asynchronous send, receive + * or connect operations will be cancelled immediately, and will complete + * with the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + * + * @note For portable behaviour with respect to graceful closure of a + * connected socket, call shutdown() before closing the socket. + */ + void close() + { + asio::error_code ec; + this->service.close(this->implementation, ec); + asio::detail::throw_error(ec); + } + + /// Close the socket. + /** + * This function is used to close the socket. Any asynchronous send, receive + * or connect operations will be cancelled immediately, and will complete + * with the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::error_code ec; + * socket.close(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + * + * @note For portable behaviour with respect to graceful closure of a + * connected socket, call shutdown() before closing the socket. + */ + asio::error_code close(asio::error_code& ec) + { + return this->service.close(this->implementation, ec); + } + + /// Get the native socket representation. + /** + * This function may be used to obtain the underlying representation of the + * socket. This is intended to allow access to native socket functionality + * that is not otherwise provided. + */ + native_type native() + { + return this->service.native(this->implementation); + } + + /// Cancel all asynchronous operations associated with the socket. + /** + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + * + * @note Calls to cancel() will always fail with + * asio::error::operation_not_supported when run on Windows XP, Windows + * Server 2003, and earlier versions of Windows, unless + * ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has + * two issues that should be considered before enabling its use: + * + * @li It will only cancel asynchronous operations that were initiated in the + * current thread. + * + * @li It can appear to complete without error, but the request to cancel the + * unfinished operations may be silently ignored by the operating system. + * Whether it works or not seems to depend on the drivers that are installed. + * + * For portable cancellation, consider using one of the following + * alternatives: + * + * @li Disable asio's I/O completion port backend by defining + * ASIO_DISABLE_IOCP. + * + * @li Use the close() function to simultaneously cancel the outstanding + * operations and close the socket. + * + * When running on Windows Vista, Windows Server 2008, and later, the + * CancelIoEx function is always used. This function does not have the + * problems described above. + */ +#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ + && !defined(ASIO_ENABLE_CANCELIO) + __declspec(deprecated("By default, this function always fails with " + "operation_not_supported when used on Windows XP, Windows Server 2003, " + "or earlier. Consult documentation for details.")) +#endif + void cancel() + { + asio::error_code ec; + this->service.cancel(this->implementation, ec); + asio::detail::throw_error(ec); + } + + /// Cancel all asynchronous operations associated with the socket. + /** + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note Calls to cancel() will always fail with + * asio::error::operation_not_supported when run on Windows XP, Windows + * Server 2003, and earlier versions of Windows, unless + * ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has + * two issues that should be considered before enabling its use: + * + * @li It will only cancel asynchronous operations that were initiated in the + * current thread. + * + * @li It can appear to complete without error, but the request to cancel the + * unfinished operations may be silently ignored by the operating system. + * Whether it works or not seems to depend on the drivers that are installed. + * + * For portable cancellation, consider using one of the following + * alternatives: + * + * @li Disable asio's I/O completion port backend by defining + * ASIO_DISABLE_IOCP. + * + * @li Use the close() function to simultaneously cancel the outstanding + * operations and close the socket. + * + * When running on Windows Vista, Windows Server 2008, and later, the + * CancelIoEx function is always used. This function does not have the + * problems described above. + */ +#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ + && !defined(ASIO_ENABLE_CANCELIO) + __declspec(deprecated("By default, this function always fails with " + "operation_not_supported when used on Windows XP, Windows Server 2003, " + "or earlier. Consult documentation for details.")) +#endif + asio::error_code cancel(asio::error_code& ec) + { + return this->service.cancel(this->implementation, ec); + } + + /// Determine whether the socket is at the out-of-band data mark. + /** + * This function is used to check whether the socket input is currently + * positioned at the out-of-band data mark. + * + * @return A bool indicating whether the socket is at the out-of-band data + * mark. + * + * @throws asio::system_error Thrown on failure. + */ + bool at_mark() const + { + asio::error_code ec; + bool b = this->service.at_mark(this->implementation, ec); + asio::detail::throw_error(ec); + return b; + } + + /// Determine whether the socket is at the out-of-band data mark. + /** + * This function is used to check whether the socket input is currently + * positioned at the out-of-band data mark. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return A bool indicating whether the socket is at the out-of-band data + * mark. + */ + bool at_mark(asio::error_code& ec) const + { + return this->service.at_mark(this->implementation, ec); + } + + /// Determine the number of bytes available for reading. + /** + * This function is used to determine the number of bytes that may be read + * without blocking. + * + * @return The number of bytes that may be read without blocking, or 0 if an + * error occurs. + * + * @throws asio::system_error Thrown on failure. + */ + std::size_t available() const + { + asio::error_code ec; + std::size_t s = this->service.available(this->implementation, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Determine the number of bytes available for reading. + /** + * This function is used to determine the number of bytes that may be read + * without blocking. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of bytes that may be read without blocking, or 0 if an + * error occurs. + */ + std::size_t available(asio::error_code& ec) const + { + return this->service.available(this->implementation, ec); + } + + /// Bind the socket to the given local endpoint. + /** + * This function binds the socket to the specified endpoint on the local + * machine. + * + * @param endpoint An endpoint on the local machine to which the socket will + * be bound. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * socket.open(asio::ip::tcp::v4()); + * socket.bind(asio::ip::tcp::endpoint( + * asio::ip::tcp::v4(), 12345)); + * @endcode + */ + void bind(const endpoint_type& endpoint) + { + asio::error_code ec; + this->service.bind(this->implementation, endpoint, ec); + asio::detail::throw_error(ec); + } + + /// Bind the socket to the given local endpoint. + /** + * This function binds the socket to the specified endpoint on the local + * machine. + * + * @param endpoint An endpoint on the local machine to which the socket will + * be bound. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * socket.open(asio::ip::tcp::v4()); + * asio::error_code ec; + * socket.bind(asio::ip::tcp::endpoint( + * asio::ip::tcp::v4(), 12345), ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + asio::error_code bind(const endpoint_type& endpoint, + asio::error_code& ec) + { + return this->service.bind(this->implementation, endpoint, ec); + } + + /// Connect the socket to the specified endpoint. + /** + * This function is used to connect a socket to the specified remote endpoint. + * The function call will block until the connection is successfully made or + * an error occurs. + * + * The socket is automatically opened if it is not already open. If the + * connect fails, and the socket was automatically opened, the socket is + * not returned to the closed state. + * + * @param peer_endpoint The remote endpoint to which the socket will be + * connected. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::endpoint endpoint( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.connect(endpoint); + * @endcode + */ + void connect(const endpoint_type& peer_endpoint) + { + asio::error_code ec; + if (!is_open()) + { + this->service.open(this->implementation, peer_endpoint.protocol(), ec); + asio::detail::throw_error(ec); + } + this->service.connect(this->implementation, peer_endpoint, ec); + asio::detail::throw_error(ec); + } + + /// Connect the socket to the specified endpoint. + /** + * This function is used to connect a socket to the specified remote endpoint. + * The function call will block until the connection is successfully made or + * an error occurs. + * + * The socket is automatically opened if it is not already open. If the + * connect fails, and the socket was automatically opened, the socket is + * not returned to the closed state. + * + * @param peer_endpoint The remote endpoint to which the socket will be + * connected. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::endpoint endpoint( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * asio::error_code ec; + * socket.connect(endpoint, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + asio::error_code connect(const endpoint_type& peer_endpoint, + asio::error_code& ec) + { + if (!is_open()) + { + if (this->service.open(this->implementation, + peer_endpoint.protocol(), ec)) + { + return ec; + } + } + + return this->service.connect(this->implementation, peer_endpoint, ec); + } + + /// Start an asynchronous connect. + /** + * This function is used to asynchronously connect a socket to the specified + * remote endpoint. The function call always returns immediately. + * + * The socket is automatically opened if it is not already open. If the + * connect fails, and the socket was automatically opened, the socket is + * not returned to the closed state. + * + * @param peer_endpoint The remote endpoint to which the socket will be + * connected. Copies will be made of the endpoint object as required. + * + * @param handler The handler to be called when the connection operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error // Result of operation + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * @code + * void connect_handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Connect succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::endpoint endpoint( + * asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.async_connect(endpoint, connect_handler); + * @endcode + */ + template + void async_connect(const endpoint_type& peer_endpoint, ConnectHandler handler) + { + if (!is_open()) + { + asio::error_code ec; + if (this->service.open(this->implementation, + peer_endpoint.protocol(), ec)) + { + this->get_io_service().post( + asio::detail::bind_handler(handler, ec)); + return; + } + } + + this->service.async_connect(this->implementation, peer_endpoint, handler); + } + + /// Set an option on the socket. + /** + * This function is used to set an option on the socket. + * + * @param option The new option value to be set on the socket. + * + * @throws asio::system_error Thrown on failure. + * + * @sa SettableSocketOption @n + * asio::socket_base::broadcast @n + * asio::socket_base::do_not_route @n + * asio::socket_base::keep_alive @n + * asio::socket_base::linger @n + * asio::socket_base::receive_buffer_size @n + * asio::socket_base::receive_low_watermark @n + * asio::socket_base::reuse_address @n + * asio::socket_base::send_buffer_size @n + * asio::socket_base::send_low_watermark @n + * asio::ip::multicast::join_group @n + * asio::ip::multicast::leave_group @n + * asio::ip::multicast::enable_loopback @n + * asio::ip::multicast::outbound_interface @n + * asio::ip::multicast::hops @n + * asio::ip::tcp::no_delay + * + * @par Example + * Setting the IPPROTO_TCP/TCP_NODELAY option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::ip::tcp::no_delay option(true); + * socket.set_option(option); + * @endcode + */ + template + void set_option(const SettableSocketOption& option) + { + asio::error_code ec; + this->service.set_option(this->implementation, option, ec); + asio::detail::throw_error(ec); + } + + /// Set an option on the socket. + /** + * This function is used to set an option on the socket. + * + * @param option The new option value to be set on the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa SettableSocketOption @n + * asio::socket_base::broadcast @n + * asio::socket_base::do_not_route @n + * asio::socket_base::keep_alive @n + * asio::socket_base::linger @n + * asio::socket_base::receive_buffer_size @n + * asio::socket_base::receive_low_watermark @n + * asio::socket_base::reuse_address @n + * asio::socket_base::send_buffer_size @n + * asio::socket_base::send_low_watermark @n + * asio::ip::multicast::join_group @n + * asio::ip::multicast::leave_group @n + * asio::ip::multicast::enable_loopback @n + * asio::ip::multicast::outbound_interface @n + * asio::ip::multicast::hops @n + * asio::ip::tcp::no_delay + * + * @par Example + * Setting the IPPROTO_TCP/TCP_NODELAY option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::ip::tcp::no_delay option(true); + * asio::error_code ec; + * socket.set_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + asio::error_code set_option(const SettableSocketOption& option, + asio::error_code& ec) + { + return this->service.set_option(this->implementation, option, ec); + } + + /// Get an option from the socket. + /** + * This function is used to get the current value of an option on the socket. + * + * @param option The option value to be obtained from the socket. + * + * @throws asio::system_error Thrown on failure. + * + * @sa GettableSocketOption @n + * asio::socket_base::broadcast @n + * asio::socket_base::do_not_route @n + * asio::socket_base::keep_alive @n + * asio::socket_base::linger @n + * asio::socket_base::receive_buffer_size @n + * asio::socket_base::receive_low_watermark @n + * asio::socket_base::reuse_address @n + * asio::socket_base::send_buffer_size @n + * asio::socket_base::send_low_watermark @n + * asio::ip::multicast::join_group @n + * asio::ip::multicast::leave_group @n + * asio::ip::multicast::enable_loopback @n + * asio::ip::multicast::outbound_interface @n + * asio::ip::multicast::hops @n + * asio::ip::tcp::no_delay + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::ip::tcp::socket::keep_alive option; + * socket.get_option(option); + * bool is_set = option.get(); + * @endcode + */ + template + void get_option(GettableSocketOption& option) const + { + asio::error_code ec; + this->service.get_option(this->implementation, option, ec); + asio::detail::throw_error(ec); + } + + /// Get an option from the socket. + /** + * This function is used to get the current value of an option on the socket. + * + * @param option The option value to be obtained from the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa GettableSocketOption @n + * asio::socket_base::broadcast @n + * asio::socket_base::do_not_route @n + * asio::socket_base::keep_alive @n + * asio::socket_base::linger @n + * asio::socket_base::receive_buffer_size @n + * asio::socket_base::receive_low_watermark @n + * asio::socket_base::reuse_address @n + * asio::socket_base::send_buffer_size @n + * asio::socket_base::send_low_watermark @n + * asio::ip::multicast::join_group @n + * asio::ip::multicast::leave_group @n + * asio::ip::multicast::enable_loopback @n + * asio::ip::multicast::outbound_interface @n + * asio::ip::multicast::hops @n + * asio::ip::tcp::no_delay + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::ip::tcp::socket::keep_alive option; + * asio::error_code ec; + * socket.get_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * bool is_set = option.get(); + * @endcode + */ + template + asio::error_code get_option(GettableSocketOption& option, + asio::error_code& ec) const + { + return this->service.get_option(this->implementation, option, ec); + } + + /// Perform an IO control command on the socket. + /** + * This function is used to execute an IO control command on the socket. + * + * @param command The IO control command to be performed on the socket. + * + * @throws asio::system_error Thrown on failure. + * + * @sa IoControlCommand @n + * asio::socket_base::bytes_readable @n + * asio::socket_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::ip::tcp::socket::bytes_readable command; + * socket.io_control(command); + * std::size_t bytes_readable = command.get(); + * @endcode + */ + template + void io_control(IoControlCommand& command) + { + asio::error_code ec; + this->service.io_control(this->implementation, command, ec); + asio::detail::throw_error(ec); + } + + /// Perform an IO control command on the socket. + /** + * This function is used to execute an IO control command on the socket. + * + * @param command The IO control command to be performed on the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa IoControlCommand @n + * asio::socket_base::bytes_readable @n + * asio::socket_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::ip::tcp::socket::bytes_readable command; + * asio::error_code ec; + * socket.io_control(command, ec); + * if (ec) + * { + * // An error occurred. + * } + * std::size_t bytes_readable = command.get(); + * @endcode + */ + template + asio::error_code io_control(IoControlCommand& command, + asio::error_code& ec) + { + return this->service.io_control(this->implementation, command, ec); + } + + /// Get the local endpoint of the socket. + /** + * This function is used to obtain the locally bound endpoint of the socket. + * + * @returns An object that represents the local endpoint of the socket. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); + * @endcode + */ + endpoint_type local_endpoint() const + { + asio::error_code ec; + endpoint_type ep = this->service.local_endpoint(this->implementation, ec); + asio::detail::throw_error(ec); + return ep; + } + + /// Get the local endpoint of the socket. + /** + * This function is used to obtain the locally bound endpoint of the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns An object that represents the local endpoint of the socket. + * Returns a default-constructed endpoint object if an error occurred. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::error_code ec; + * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + endpoint_type local_endpoint(asio::error_code& ec) const + { + return this->service.local_endpoint(this->implementation, ec); + } + + /// Get the remote endpoint of the socket. + /** + * This function is used to obtain the remote endpoint of the socket. + * + * @returns An object that represents the remote endpoint of the socket. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); + * @endcode + */ + endpoint_type remote_endpoint() const + { + asio::error_code ec; + endpoint_type ep = this->service.remote_endpoint(this->implementation, ec); + asio::detail::throw_error(ec); + return ep; + } + + /// Get the remote endpoint of the socket. + /** + * This function is used to obtain the remote endpoint of the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns An object that represents the remote endpoint of the socket. + * Returns a default-constructed endpoint object if an error occurred. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::error_code ec; + * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + endpoint_type remote_endpoint(asio::error_code& ec) const + { + return this->service.remote_endpoint(this->implementation, ec); + } + + /// Disable sends or receives on the socket. + /** + * This function is used to disable send operations, receive operations, or + * both. + * + * @param what Determines what types of operation will no longer be allowed. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * Shutting down the send side of the socket: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * socket.shutdown(asio::ip::tcp::socket::shutdown_send); + * @endcode + */ + void shutdown(shutdown_type what) + { + asio::error_code ec; + this->service.shutdown(this->implementation, what, ec); + asio::detail::throw_error(ec); + } + + /// Disable sends or receives on the socket. + /** + * This function is used to disable send operations, receive operations, or + * both. + * + * @param what Determines what types of operation will no longer be allowed. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * Shutting down the send side of the socket: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::error_code ec; + * socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + asio::error_code shutdown(shutdown_type what, + asio::error_code& ec) + { + return this->service.shutdown(this->implementation, what, ec); + } + +protected: + /// Protected destructor to prevent deletion through this type. + ~basic_socket() + { + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_SOCKET_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/basic_socket_acceptor.hpp b/src/libs/resiprocate/contrib/asio/asio/basic_socket_acceptor.hpp new file mode 100644 index 00000000..97fa56b7 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/basic_socket_acceptor.hpp @@ -0,0 +1,824 @@ +// +// basic_socket_acceptor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BASIC_SOCKET_ACCEPTOR_HPP +#define ASIO_BASIC_SOCKET_ACCEPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/basic_io_object.hpp" +#include "asio/basic_socket.hpp" +#include "asio/error.hpp" +#include "asio/socket_acceptor_service.hpp" +#include "asio/socket_base.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { + +/// Provides the ability to accept new connections. +/** + * The basic_socket_acceptor class template is used for accepting new socket + * connections. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Example + * Opening a socket acceptor with the SO_REUSEADDR option enabled: + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port); + * acceptor.open(endpoint.protocol()); + * acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true)); + * acceptor.bind(endpoint); + * acceptor.listen(); + * @endcode + */ +template > +class basic_socket_acceptor + : public basic_io_object, + public socket_base +{ +public: + /// The native representation of an acceptor. + typedef typename SocketAcceptorService::native_type native_type; + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// Construct an acceptor without opening it. + /** + * This constructor creates an acceptor without opening it to listen for new + * connections. The open() function must be called before the acceptor can + * accept new socket connections. + * + * @param io_service The io_service object that the acceptor will use to + * dispatch handlers for any asynchronous operations performed on the + * acceptor. + */ + explicit basic_socket_acceptor(asio::io_service& io_service) + : basic_io_object(io_service) + { + } + + /// Construct an open acceptor. + /** + * This constructor creates an acceptor and automatically opens it. + * + * @param io_service The io_service object that the acceptor will use to + * dispatch handlers for any asynchronous operations performed on the + * acceptor. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws asio::system_error Thrown on failure. + */ + basic_socket_acceptor(asio::io_service& io_service, + const protocol_type& protocol) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.open(this->implementation, protocol, ec); + asio::detail::throw_error(ec); + } + + /// Construct an acceptor opened on the given endpoint. + /** + * This constructor creates an acceptor and automatically opens it to listen + * for new connections on the specified endpoint. + * + * @param io_service The io_service object that the acceptor will use to + * dispatch handlers for any asynchronous operations performed on the + * acceptor. + * + * @param endpoint An endpoint on the local machine on which the acceptor + * will listen for new connections. + * + * @param reuse_addr Whether the constructor should set the socket option + * socket_base::reuse_address. + * + * @throws asio::system_error Thrown on failure. + * + * @note This constructor is equivalent to the following code: + * @code + * basic_socket_acceptor acceptor(io_service); + * acceptor.open(endpoint.protocol()); + * if (reuse_addr) + * acceptor.set_option(socket_base::reuse_address(true)); + * acceptor.bind(endpoint); + * acceptor.listen(listen_backlog); + * @endcode + */ + basic_socket_acceptor(asio::io_service& io_service, + const endpoint_type& endpoint, bool reuse_addr = true) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.open(this->implementation, endpoint.protocol(), ec); + asio::detail::throw_error(ec); + if (reuse_addr) + { + this->service.set_option(this->implementation, + socket_base::reuse_address(true), ec); + asio::detail::throw_error(ec); + } + this->service.bind(this->implementation, endpoint, ec); + asio::detail::throw_error(ec); + this->service.listen(this->implementation, + socket_base::max_connections, ec); + asio::detail::throw_error(ec); + } + + /// Construct a basic_socket_acceptor on an existing native acceptor. + /** + * This constructor creates an acceptor object to hold an existing native + * acceptor. + * + * @param io_service The io_service object that the acceptor will use to + * dispatch handlers for any asynchronous operations performed on the + * acceptor. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_acceptor A native acceptor. + * + * @throws asio::system_error Thrown on failure. + */ + basic_socket_acceptor(asio::io_service& io_service, + const protocol_type& protocol, const native_type& native_acceptor) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.assign(this->implementation, protocol, native_acceptor, ec); + asio::detail::throw_error(ec); + } + + /// Open the acceptor using the specified protocol. + /** + * This function opens the socket acceptor so that it will use the specified + * protocol. + * + * @param protocol An object specifying which protocol is to be used. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * acceptor.open(asio::ip::tcp::v4()); + * @endcode + */ + void open(const protocol_type& protocol = protocol_type()) + { + asio::error_code ec; + this->service.open(this->implementation, protocol, ec); + asio::detail::throw_error(ec); + } + + /// Open the acceptor using the specified protocol. + /** + * This function opens the socket acceptor so that it will use the specified + * protocol. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * asio::error_code ec; + * acceptor.open(asio::ip::tcp::v4(), ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + asio::error_code open(const protocol_type& protocol, + asio::error_code& ec) + { + return this->service.open(this->implementation, protocol, ec); + } + + /// Assigns an existing native acceptor to the acceptor. + /* + * This function opens the acceptor to hold an existing native acceptor. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param native_acceptor A native acceptor. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const protocol_type& protocol, const native_type& native_acceptor) + { + asio::error_code ec; + this->service.assign(this->implementation, protocol, native_acceptor, ec); + asio::detail::throw_error(ec); + } + + /// Assigns an existing native acceptor to the acceptor. + /* + * This function opens the acceptor to hold an existing native acceptor. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param native_acceptor A native acceptor. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code assign(const protocol_type& protocol, + const native_type& native_acceptor, asio::error_code& ec) + { + return this->service.assign(this->implementation, + protocol, native_acceptor, ec); + } + + /// Determine whether the acceptor is open. + bool is_open() const + { + return this->service.is_open(this->implementation); + } + + /// Bind the acceptor to the given local endpoint. + /** + * This function binds the socket acceptor to the specified endpoint on the + * local machine. + * + * @param endpoint An endpoint on the local machine to which the socket + * acceptor will be bound. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * acceptor.open(asio::ip::tcp::v4()); + * acceptor.bind(asio::ip::tcp::endpoint(12345)); + * @endcode + */ + void bind(const endpoint_type& endpoint) + { + asio::error_code ec; + this->service.bind(this->implementation, endpoint, ec); + asio::detail::throw_error(ec); + } + + /// Bind the acceptor to the given local endpoint. + /** + * This function binds the socket acceptor to the specified endpoint on the + * local machine. + * + * @param endpoint An endpoint on the local machine to which the socket + * acceptor will be bound. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * acceptor.open(asio::ip::tcp::v4()); + * asio::error_code ec; + * acceptor.bind(asio::ip::tcp::endpoint(12345), ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + asio::error_code bind(const endpoint_type& endpoint, + asio::error_code& ec) + { + return this->service.bind(this->implementation, endpoint, ec); + } + + /// Place the acceptor into the state where it will listen for new + /// connections. + /** + * This function puts the socket acceptor into the state where it may accept + * new connections. + * + * @param backlog The maximum length of the queue of pending connections. + * + * @throws asio::system_error Thrown on failure. + */ + void listen(int backlog = socket_base::max_connections) + { + asio::error_code ec; + this->service.listen(this->implementation, backlog, ec); + asio::detail::throw_error(ec); + } + + /// Place the acceptor into the state where it will listen for new + /// connections. + /** + * This function puts the socket acceptor into the state where it may accept + * new connections. + * + * @param backlog The maximum length of the queue of pending connections. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::error_code ec; + * acceptor.listen(asio::socket_base::max_connections, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + asio::error_code listen(int backlog, asio::error_code& ec) + { + return this->service.listen(this->implementation, backlog, ec); + } + + /// Close the acceptor. + /** + * This function is used to close the acceptor. Any asynchronous accept + * operations will be cancelled immediately. + * + * A subsequent call to open() is required before the acceptor can again be + * used to again perform socket accept operations. + * + * @throws asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->service.close(this->implementation, ec); + asio::detail::throw_error(ec); + } + + /// Close the acceptor. + /** + * This function is used to close the acceptor. Any asynchronous accept + * operations will be cancelled immediately. + * + * A subsequent call to open() is required before the acceptor can again be + * used to again perform socket accept operations. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::error_code ec; + * acceptor.close(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + asio::error_code close(asio::error_code& ec) + { + return this->service.close(this->implementation, ec); + } + + /// Get the native acceptor representation. + /** + * This function may be used to obtain the underlying representation of the + * acceptor. This is intended to allow access to native acceptor functionality + * that is not otherwise provided. + */ + native_type native() + { + return this->service.native(this->implementation); + } + + /// Cancel all asynchronous operations associated with the acceptor. + /** + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->service.cancel(this->implementation, ec); + asio::detail::throw_error(ec); + } + + /// Cancel all asynchronous operations associated with the acceptor. + /** + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code cancel(asio::error_code& ec) + { + return this->service.cancel(this->implementation, ec); + } + + /// Set an option on the acceptor. + /** + * This function is used to set an option on the acceptor. + * + * @param option The new option value to be set on the acceptor. + * + * @throws asio::system_error Thrown on failure. + * + * @sa SettableSocketOption @n + * asio::socket_base::reuse_address + * asio::socket_base::enable_connection_aborted + * + * @par Example + * Setting the SOL_SOCKET/SO_REUSEADDR option: + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::ip::tcp::acceptor::reuse_address option(true); + * acceptor.set_option(option); + * @endcode + */ + template + void set_option(const SettableSocketOption& option) + { + asio::error_code ec; + this->service.set_option(this->implementation, option, ec); + asio::detail::throw_error(ec); + } + + /// Set an option on the acceptor. + /** + * This function is used to set an option on the acceptor. + * + * @param option The new option value to be set on the acceptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa SettableSocketOption @n + * asio::socket_base::reuse_address + * asio::socket_base::enable_connection_aborted + * + * @par Example + * Setting the SOL_SOCKET/SO_REUSEADDR option: + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::ip::tcp::acceptor::reuse_address option(true); + * asio::error_code ec; + * acceptor.set_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + asio::error_code set_option(const SettableSocketOption& option, + asio::error_code& ec) + { + return this->service.set_option(this->implementation, option, ec); + } + + /// Get an option from the acceptor. + /** + * This function is used to get the current value of an option on the + * acceptor. + * + * @param option The option value to be obtained from the acceptor. + * + * @throws asio::system_error Thrown on failure. + * + * @sa GettableSocketOption @n + * asio::socket_base::reuse_address + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::ip::tcp::acceptor::reuse_address option; + * acceptor.get_option(option); + * bool is_set = option.get(); + * @endcode + */ + template + void get_option(GettableSocketOption& option) + { + asio::error_code ec; + this->service.get_option(this->implementation, option, ec); + asio::detail::throw_error(ec); + } + + /// Get an option from the acceptor. + /** + * This function is used to get the current value of an option on the + * acceptor. + * + * @param option The option value to be obtained from the acceptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa GettableSocketOption @n + * asio::socket_base::reuse_address + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::ip::tcp::acceptor::reuse_address option; + * asio::error_code ec; + * acceptor.get_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * bool is_set = option.get(); + * @endcode + */ + template + asio::error_code get_option(GettableSocketOption& option, + asio::error_code& ec) + { + return this->service.get_option(this->implementation, option, ec); + } + + /// Get the local endpoint of the acceptor. + /** + * This function is used to obtain the locally bound endpoint of the acceptor. + * + * @returns An object that represents the local endpoint of the acceptor. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); + * @endcode + */ + endpoint_type local_endpoint() const + { + asio::error_code ec; + endpoint_type ep = this->service.local_endpoint(this->implementation, ec); + asio::detail::throw_error(ec); + return ep; + } + + /// Get the local endpoint of the acceptor. + /** + * This function is used to obtain the locally bound endpoint of the acceptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns An object that represents the local endpoint of the acceptor. + * Returns a default-constructed endpoint object if an error occurred and the + * error handler did not throw an exception. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::error_code ec; + * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + endpoint_type local_endpoint(asio::error_code& ec) const + { + return this->service.local_endpoint(this->implementation, ec); + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer into the + * given socket. The function call will block until a new connection has been + * accepted successfully or an error occurs. + * + * @param peer The socket into which the new connection will be accepted. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::ip::tcp::socket socket(io_service); + * acceptor.accept(socket); + * @endcode + */ + template + void accept(basic_socket& peer) + { + asio::error_code ec; + this->service.accept(this->implementation, peer, 0, ec); + asio::detail::throw_error(ec); + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer into the + * given socket. The function call will block until a new connection has been + * accepted successfully or an error occurs. + * + * @param peer The socket into which the new connection will be accepted. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::ip::tcp::soocket socket(io_service); + * asio::error_code ec; + * acceptor.accept(socket, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + asio::error_code accept( + basic_socket& peer, + asio::error_code& ec) + { + return this->service.accept(this->implementation, peer, 0, ec); + } + + /// Start an asynchronous accept. + /** + * This function is used to asynchronously accept a new connection into a + * socket. The function call always returns immediately. + * + * @param peer The socket into which the new connection will be accepted. + * Ownership of the peer object is retained by the caller, which must + * guarantee that it is valid until the handler is called. + * + * @param handler The handler to be called when the accept operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error // Result of operation. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * @code + * void accept_handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::ip::tcp::socket socket(io_service); + * acceptor.async_accept(socket, accept_handler); + * @endcode + */ + template + void async_accept(basic_socket& peer, + AcceptHandler handler) + { + this->service.async_accept(this->implementation, peer, 0, handler); + } + + /// Accept a new connection and obtain the endpoint of the peer + /** + * This function is used to accept a new connection from a peer into the + * given socket, and additionally provide the endpoint of the remote peer. + * The function call will block until a new connection has been accepted + * successfully or an error occurs. + * + * @param peer The socket into which the new connection will be accepted. + * + * @param peer_endpoint An endpoint object which will receive the endpoint of + * the remote peer. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::endpoint endpoint; + * acceptor.accept(socket, endpoint); + * @endcode + */ + template + void accept(basic_socket& peer, + endpoint_type& peer_endpoint) + { + asio::error_code ec; + this->service.accept(this->implementation, peer, &peer_endpoint, ec); + asio::detail::throw_error(ec); + } + + /// Accept a new connection and obtain the endpoint of the peer + /** + * This function is used to accept a new connection from a peer into the + * given socket, and additionally provide the endpoint of the remote peer. + * The function call will block until a new connection has been accepted + * successfully or an error occurs. + * + * @param peer The socket into which the new connection will be accepted. + * + * @param peer_endpoint An endpoint object which will receive the endpoint of + * the remote peer. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::endpoint endpoint; + * asio::error_code ec; + * acceptor.accept(socket, endpoint, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + asio::error_code accept( + basic_socket& peer, + endpoint_type& peer_endpoint, asio::error_code& ec) + { + return this->service.accept(this->implementation, peer, &peer_endpoint, ec); + } + + /// Start an asynchronous accept. + /** + * This function is used to asynchronously accept a new connection into a + * socket, and additionally obtain the endpoint of the remote peer. The + * function call always returns immediately. + * + * @param peer The socket into which the new connection will be accepted. + * Ownership of the peer object is retained by the caller, which must + * guarantee that it is valid until the handler is called. + * + * @param peer_endpoint An endpoint object into which the endpoint of the + * remote peer will be written. Ownership of the peer_endpoint object is + * retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param handler The handler to be called when the accept operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error // Result of operation. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + */ + template + void async_accept(basic_socket& peer, + endpoint_type& peer_endpoint, AcceptHandler handler) + { + this->service.async_accept(this->implementation, + peer, &peer_endpoint, handler); + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_SOCKET_ACCEPTOR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/basic_socket_iostream.hpp b/src/libs/resiprocate/contrib/asio/asio/basic_socket_iostream.hpp new file mode 100644 index 00000000..361ecb82 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/basic_socket_iostream.hpp @@ -0,0 +1,156 @@ +// +// basic_socket_iostream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BASIC_SOCKET_IOSTREAM_HPP +#define ASIO_BASIC_SOCKET_IOSTREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_socket_streambuf.hpp" +#include "asio/stream_socket_service.hpp" + +#if !defined(ASIO_SOCKET_IOSTREAM_MAX_ARITY) +#define ASIO_SOCKET_IOSTREAM_MAX_ARITY 5 +#endif // !defined(ASIO_SOCKET_IOSTREAM_MAX_ARITY) + +// A macro that should expand to: +// template +// explicit basic_socket_iostream(T1 x1, ..., Tn xn) +// : basic_iostream(&this->boost::base_from_member< +// basic_socket_streambuf >::member) +// { +// if (rdbuf()->connect(x1, ..., xn) == 0) +// this->setstate(std::ios_base::failbit); +// } +// This macro should only persist within this file. + +#define ASIO_PRIVATE_CTR_DEF(z, n, data) \ + template \ + explicit basic_socket_iostream(BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \ + : std::basic_iostream(&this->boost::base_from_member< \ + basic_socket_streambuf >::member) \ + { \ + tie(this); \ + if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \ + this->setstate(std::ios_base::failbit); \ + } \ + /**/ + +// A macro that should expand to: +// template +// void connect(T1 x1, ..., Tn xn) +// { +// if (rdbuf()->connect(x1, ..., xn) == 0) +// this->setstate(std::ios_base::failbit); +// } +// This macro should only persist within this file. + +#define ASIO_PRIVATE_CONNECT_DEF(z, n, data) \ + template \ + void connect(BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \ + { \ + if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \ + this->setstate(std::ios_base::failbit); \ + } \ + /**/ + +namespace asio { + +/// Iostream interface for a socket. +template > +class basic_socket_iostream + : public boost::base_from_member< + basic_socket_streambuf >, + public std::basic_iostream +{ +public: + /// Construct a basic_socket_iostream without establishing a connection. + basic_socket_iostream() + : std::basic_iostream(&this->boost::base_from_member< + basic_socket_streambuf >::member) + { + tie(this); + } + +#if defined(GENERATING_DOCUMENTATION) + /// Establish a connection to an endpoint corresponding to a resolver query. + /** + * This constructor automatically establishes a connection based on the + * supplied resolver query parameters. The arguments are used to construct + * a resolver query object. + */ + template + explicit basic_socket_iostream(T1 t1, ..., TN tn); +#else + BOOST_PP_REPEAT_FROM_TO( + 1, BOOST_PP_INC(ASIO_SOCKET_IOSTREAM_MAX_ARITY), + ASIO_PRIVATE_CTR_DEF, _ ) +#endif + +#if defined(GENERATING_DOCUMENTATION) + /// Establish a connection to an endpoint corresponding to a resolver query. + /** + * This function automatically establishes a connection based on the supplied + * resolver query parameters. The arguments are used to construct a resolver + * query object. + */ + template + void connect(T1 t1, ..., TN tn); +#else + BOOST_PP_REPEAT_FROM_TO( + 1, BOOST_PP_INC(ASIO_SOCKET_IOSTREAM_MAX_ARITY), + ASIO_PRIVATE_CONNECT_DEF, _ ) +#endif + + /// Close the connection. + void close() + { + if (rdbuf()->close() == 0) + this->setstate(std::ios_base::failbit); + } + + /// Return a pointer to the underlying streambuf. + basic_socket_streambuf* rdbuf() const + { + return const_cast*>( + &this->boost::base_from_member< + basic_socket_streambuf >::member); + } +}; + +} // namespace asio + +#undef ASIO_PRIVATE_CTR_DEF +#undef ASIO_PRIVATE_CONNECT_DEF + +#endif // defined(BOOST_NO_IOSTREAM) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_SOCKET_IOSTREAM_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/basic_socket_streambuf.hpp b/src/libs/resiprocate/contrib/asio/asio/basic_socket_streambuf.hpp new file mode 100644 index 00000000..ae0264e3 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/basic_socket_streambuf.hpp @@ -0,0 +1,295 @@ +// +// basic_socket_streambuf.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BASIC_SOCKET_STREAMBUF_HPP +#define ASIO_BASIC_SOCKET_STREAMBUF_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_socket.hpp" +#include "asio/io_service.hpp" +#include "asio/stream_socket_service.hpp" +#include "asio/detail/throw_error.hpp" + +#if !defined(ASIO_SOCKET_STREAMBUF_MAX_ARITY) +#define ASIO_SOCKET_STREAMBUF_MAX_ARITY 5 +#endif // !defined(ASIO_SOCKET_STREAMBUF_MAX_ARITY) + +// A macro that should expand to: +// template +// basic_socket_streambuf* connect( +// T1 x1, ..., Tn xn) +// { +// init_buffers(); +// asio::error_code ec; +// this->basic_socket::close(ec); +// typedef typename Protocol::resolver resolver_type; +// typedef typename resolver_type::query resolver_query; +// resolver_query query(x1, ..., xn); +// resolve_and_connect(query, ec); +// return !ec ? this : 0; +// } +// This macro should only persist within this file. + +#define ASIO_PRIVATE_CONNECT_DEF( z, n, data ) \ + template \ + basic_socket_streambuf* connect( \ + BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \ + { \ + init_buffers(); \ + asio::error_code ec; \ + this->basic_socket::close(ec); \ + typedef typename Protocol::resolver resolver_type; \ + typedef typename resolver_type::query resolver_query; \ + resolver_query query(BOOST_PP_ENUM_PARAMS(n, x)); \ + resolve_and_connect(query, ec); \ + return !ec ? this : 0; \ + } \ + /**/ + +namespace asio { + +/// Iostream streambuf for a socket. +template > +class basic_socket_streambuf + : public std::streambuf, + private boost::base_from_member, + public basic_socket +{ +public: + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// Construct a basic_socket_streambuf without establishing a connection. + basic_socket_streambuf() + : basic_socket( + boost::base_from_member::member), + unbuffered_(false) + { + init_buffers(); + } + + /// Destructor flushes buffered data. + virtual ~basic_socket_streambuf() + { + if (pptr() != pbase()) + overflow(traits_type::eof()); + } + + /// Establish a connection. + /** + * This function establishes a connection to the specified endpoint. + * + * @return \c this if a connection was successfully established, a null + * pointer otherwise. + */ + basic_socket_streambuf* connect( + const endpoint_type& endpoint) + { + init_buffers(); + asio::error_code ec; + this->basic_socket::close(ec); + this->basic_socket::connect(endpoint, ec); + return !ec ? this : 0; + } + +#if defined(GENERATING_DOCUMENTATION) + /// Establish a connection. + /** + * This function automatically establishes a connection based on the supplied + * resolver query parameters. The arguments are used to construct a resolver + * query object. + * + * @return \c this if a connection was successfully established, a null + * pointer otherwise. + */ + template + basic_socket_streambuf* connect( + T1 t1, ..., TN tn); +#else + BOOST_PP_REPEAT_FROM_TO( + 1, BOOST_PP_INC(ASIO_SOCKET_STREAMBUF_MAX_ARITY), + ASIO_PRIVATE_CONNECT_DEF, _ ) +#endif + + /// Close the connection. + /** + * @return \c this if a connection was successfully established, a null + * pointer otherwise. + */ + basic_socket_streambuf* close() + { + asio::error_code ec; + sync(); + this->basic_socket::close(ec); + if (!ec) + init_buffers(); + return !ec ? this : 0; + } + +protected: + int_type underflow() + { + if (gptr() == egptr()) + { + asio::error_code ec; + std::size_t bytes_transferred = this->service.receive( + this->implementation, + asio::buffer(asio::buffer(get_buffer_) + putback_max), + 0, ec); + if (ec) + return traits_type::eof(); + setg(get_buffer_.begin(), get_buffer_.begin() + putback_max, + get_buffer_.begin() + putback_max + bytes_transferred); + return traits_type::to_int_type(*gptr()); + } + else + { + return traits_type::eof(); + } + } + + int_type overflow(int_type c) + { + if (unbuffered_) + { + if (traits_type::eq_int_type(c, traits_type::eof())) + { + // Nothing to do. + return traits_type::not_eof(c); + } + else + { + // Send the single character immediately. + asio::error_code ec; + char_type ch = traits_type::to_char_type(c); + this->service.send(this->implementation, + asio::buffer(&ch, sizeof(char_type)), 0, ec); + if (ec) + return traits_type::eof(); + return c; + } + } + else + { + // Send all data in the output buffer. + asio::const_buffer buffer = + asio::buffer(pbase(), pptr() - pbase()); + while (asio::buffer_size(buffer) > 0) + { + asio::error_code ec; + std::size_t bytes_transferred = this->service.send( + this->implementation, asio::buffer(buffer), + 0, ec); + if (ec) + return traits_type::eof(); + buffer = buffer + bytes_transferred; + } + setp(put_buffer_.begin(), put_buffer_.end()); + + // If the new character is eof then our work here is done. + if (traits_type::eq_int_type(c, traits_type::eof())) + return traits_type::not_eof(c); + + // Add the new character to the output buffer. + *pptr() = traits_type::to_char_type(c); + pbump(1); + return c; + } + } + + int sync() + { + return overflow(traits_type::eof()); + } + + std::streambuf* setbuf(char_type* s, std::streamsize n) + { + if (pptr() == pbase() && s == 0 && n == 0) + { + unbuffered_ = true; + setp(0, 0); + return this; + } + + return 0; + } + +private: + void init_buffers() + { + setg(get_buffer_.begin(), + get_buffer_.begin() + putback_max, + get_buffer_.begin() + putback_max); + if (unbuffered_) + setp(0, 0); + else + setp(put_buffer_.begin(), put_buffer_.end()); + } + + template + void resolve_and_connect(const ResolverQuery& query, + asio::error_code& ec) + { + typedef typename Protocol::resolver resolver_type; + typedef typename resolver_type::iterator iterator_type; + resolver_type resolver( + boost::base_from_member::member); + iterator_type i = resolver.resolve(query, ec); + if (!ec) + { + iterator_type end; + ec = asio::error::host_not_found; + while (ec && i != end) + { + this->basic_socket::close(); + this->basic_socket::connect(*i, ec); + ++i; + } + } + } + + enum { putback_max = 8 }; + enum { buffer_size = 512 }; + boost::array get_buffer_; + boost::array put_buffer_; + bool unbuffered_; +}; + +} // namespace asio + +#undef ASIO_PRIVATE_CONNECT_DEF + +#endif // !defined(BOOST_NO_IOSTREAM) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_SOCKET_STREAMBUF_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/basic_stream_socket.hpp b/src/libs/resiprocate/contrib/asio/asio/basic_stream_socket.hpp new file mode 100644 index 00000000..b7b4f065 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/basic_stream_socket.hpp @@ -0,0 +1,718 @@ +// +// basic_stream_socket.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BASIC_STREAM_SOCKET_HPP +#define ASIO_BASIC_STREAM_SOCKET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_socket.hpp" +#include "asio/error.hpp" +#include "asio/stream_socket_service.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { + +/// Provides stream-oriented socket functionality. +/** + * The basic_stream_socket class template provides asynchronous and blocking + * stream-oriented socket functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template > +class basic_stream_socket + : public basic_socket +{ +public: + /// The native representation of a socket. + typedef typename StreamSocketService::native_type native_type; + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// Construct a basic_stream_socket without opening it. + /** + * This constructor creates a stream socket without opening it. The socket + * needs to be opened and then connected or accepted before data can be sent + * or received on it. + * + * @param io_service The io_service object that the stream socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + */ + explicit basic_stream_socket(asio::io_service& io_service) + : basic_socket(io_service) + { + } + + /// Construct and open a basic_stream_socket. + /** + * This constructor creates and opens a stream socket. The socket needs to be + * connected or accepted before data can be sent or received on it. + * + * @param io_service The io_service object that the stream socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws asio::system_error Thrown on failure. + */ + basic_stream_socket(asio::io_service& io_service, + const protocol_type& protocol) + : basic_socket(io_service, protocol) + { + } + + /// Construct a basic_stream_socket, opening it and binding it to the given + /// local endpoint. + /** + * This constructor creates a stream socket and automatically opens it bound + * to the specified endpoint on the local machine. The protocol used is the + * protocol associated with the given endpoint. + * + * @param io_service The io_service object that the stream socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param endpoint An endpoint on the local machine to which the stream + * socket will be bound. + * + * @throws asio::system_error Thrown on failure. + */ + basic_stream_socket(asio::io_service& io_service, + const endpoint_type& endpoint) + : basic_socket(io_service, endpoint) + { + } + + /// Construct a basic_stream_socket on an existing native socket. + /** + * This constructor creates a stream socket object to hold an existing native + * socket. + * + * @param io_service The io_service object that the stream socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket The new underlying socket implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_stream_socket(asio::io_service& io_service, + const protocol_type& protocol, const native_type& native_socket) + : basic_socket( + io_service, protocol, native_socket) + { + } + + /// Send some data on the socket. + /** + * This function is used to send data on the stream socket. The function + * call will block until one or more bytes of the data has been sent + * successfully, or an until error occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @returns The number of bytes sent. + * + * @throws asio::system_error Thrown on failure. + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref write function if you need to ensure that all data + * is written before the blocking operation completes. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.send(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send(const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.send( + this->implementation, buffers, 0, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Send some data on the socket. + /** + * This function is used to send data on the stream socket. The function + * call will block until one or more bytes of the data has been sent + * successfully, or an until error occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @returns The number of bytes sent. + * + * @throws asio::system_error Thrown on failure. + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref write function if you need to ensure that all data + * is written before the blocking operation completes. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.send(asio::buffer(data, size), 0); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->service.send( + this->implementation, buffers, flags, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Send some data on the socket. + /** + * This function is used to send data on the stream socket. The function + * call will block until one or more bytes of the data has been sent + * successfully, or an until error occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes sent. Returns 0 if an error occurred. + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref write function if you need to ensure that all data + * is written before the blocking operation completes. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return this->service.send(this->implementation, buffers, flags, ec); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send data on the stream socket. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_send(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_send(const ConstBufferSequence& buffers, WriteHandler handler) + { + this->service.async_send(this->implementation, buffers, 0, handler); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send data on the stream socket. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_send(asio::buffer(data, size), 0, handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, WriteHandler handler) + { + this->service.async_send(this->implementation, buffers, flags, handler); + } + + /// Receive some data on the socket. + /** + * This function is used to receive data on the stream socket. The function + * call will block until one or more bytes of data has been received + * successfully, or until an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.receive(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive(const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.receive(this->implementation, buffers, 0, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Receive some data on the socket. + /** + * This function is used to receive data on the stream socket. The function + * call will block until one or more bytes of data has been received + * successfully, or until an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @returns The number of bytes received. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.receive(asio::buffer(data, size), 0); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags) + { + asio::error_code ec; + std::size_t s = this->service.receive( + this->implementation, buffers, flags, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the stream socket. The function + * call will block until one or more bytes of data has been received + * successfully, or until an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes received. Returns 0 if an error occurred. + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return this->service.receive(this->implementation, buffers, flags, ec); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive data from the stream + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref async_read function if you need to ensure + * that the requested amount of data is received before the asynchronous + * operation completes. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_receive(const MutableBufferSequence& buffers, ReadHandler handler) + { + this->service.async_receive(this->implementation, buffers, 0, handler); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive data from the stream + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref async_read function if you need to ensure + * that the requested amount of data is received before the asynchronous + * operation completes. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive(asio::buffer(data, size), 0, handler); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, ReadHandler handler) + { + this->service.async_receive(this->implementation, buffers, flags, handler); + } + + /// Write some data to the socket. + /** + * This function is used to write data to the stream socket. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the socket. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * socket.write_some(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.send(this->implementation, buffers, 0, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Write some data to the socket. + /** + * This function is used to write data to the stream socket. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. Returns 0 if an error occurred. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) + { + return this->service.send(this->implementation, buffers, 0, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the stream socket. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the socket. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_write_some(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + this->service.async_send(this->implementation, buffers, 0, handler); + } + + /// Read some data from the socket. + /** + * This function is used to read data from the stream socket. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * socket.read_some(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.receive(this->implementation, buffers, 0, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Read some data from the socket. + /** + * This function is used to read data from the stream socket. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. Returns 0 if an error occurred. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return this->service.receive(this->implementation, buffers, 0, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the stream socket. + * The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be read. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read function if you need to ensure that the + * requested amount of data is read before the asynchronous operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_read_some(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + this->service.async_receive(this->implementation, buffers, 0, handler); + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BASIC_STREAM_SOCKET_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/basic_streambuf.hpp b/src/libs/resiprocate/contrib/asio/asio/basic_streambuf.hpp new file mode 100644 index 00000000..b34b3fec --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/basic_streambuf.hpp @@ -0,0 +1,348 @@ +// +// basic_streambuf.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BASIC_STREAMBUF_HPP +#define ASIO_BASIC_STREAMBUF_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffer.hpp" +#include "asio/detail/noncopyable.hpp" + +namespace asio { + +/// Automatically resizable buffer class based on std::streambuf. +/** + * The @c basic_streambuf class is derived from @c std::streambuf to associate + * the streambuf's input and output sequences with one or more character + * arrays. These character arrays are internal to the @c basic_streambuf + * object, but direct access to the array elements is provided to permit them + * to be used efficiently with I/O operations. Characters written to the output + * sequence of a @c basic_streambuf object are appended to the input sequence + * of the same object. + * + * The @c basic_streambuf class's public interface is intended to permit the + * following implementation strategies: + * + * @li A single contiguous character array, which is reallocated as necessary + * to accommodate changes in the size of the character sequence. This is the + * implementation approach currently used in Asio. + * + * @li A sequence of one or more character arrays, where each array is of the + * same size. Additional character array objects are appended to the sequence + * to accommodate changes in the size of the character sequence. + * + * @li A sequence of one or more character arrays of varying sizes. Additional + * character array objects are appended to the sequence to accommodate changes + * in the size of the character sequence. + * + * The constructor for basic_streambuf accepts a @c size_t argument specifying + * the maximum of the sum of the sizes of the input sequence and output + * sequence. During the lifetime of the @c basic_streambuf object, the following + * invariant holds: + * @code size() <= max_size()@endcode + * Any member function that would, if successful, cause the invariant to be + * violated shall throw an exception of class @c std::length_error. + * + * The constructor for @c basic_streambuf takes an Allocator argument. A copy + * of this argument is used for any memory allocation performed, by the + * constructor and by all member functions, during the lifetime of each @c + * basic_streambuf object. + * + * @par Examples + * Writing directly from an streambuf to a socket: + * @code + * asio::streambuf b; + * std::ostream os(&b); + * os << "Hello, World!\n"; + * + * // try sending some data in input sequence + * size_t n = sock.send(b.data()); + * + * b.consume(n); // sent data is removed from input sequence + * @endcode + * + * Reading from a socket directly into a streambuf: + * @code + * asio::streambuf b; + * + * // reserve 512 bytes in output sequence + * asio::streambuf::mutable_buffers_type bufs = b.prepare(512); + * + * size_t n = sock.receive(bufs); + * + * // received data is "committed" from output sequence to input sequence + * b.commit(n); + * + * std::istream is(&b); + * std::string s; + * is >> s; + * @endcode + */ +template > +class basic_streambuf + : public std::streambuf, + private noncopyable +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The type used to represent the input sequence as a list of buffers. + typedef implementation_defined const_buffers_type; + + /// The type used to represent the output sequence as a list of buffers. + typedef implementation_defined mutable_buffers_type; +#else + typedef asio::const_buffers_1 const_buffers_type; + typedef asio::mutable_buffers_1 mutable_buffers_type; +#endif + + /// Construct a basic_streambuf object. + /** + * Constructs a streambuf with the specified maximum size. The initial size + * of the streambuf's input sequence is 0. + */ + explicit basic_streambuf( + std::size_t max_size = (std::numeric_limits::max)(), + const Allocator& allocator = Allocator()) + : max_size_(max_size), + buffer_(allocator) + { + std::size_t pend = (std::min)(max_size_, buffer_delta); + buffer_.resize((std::max)(pend, 1)); + setg(&buffer_[0], &buffer_[0], &buffer_[0]); + setp(&buffer_[0], &buffer_[0] + pend); + } + + /// Get the size of the input sequence. + /** + * @returns The size of the input sequence. The value is equal to that + * calculated for @c s in the following code: + * @code + * size_t s = 0; + * const_buffers_type bufs = data(); + * const_buffers_type::const_iterator i = bufs.begin(); + * while (i != bufs.end()) + * { + * const_buffer buf(*i++); + * s += buffer_size(buf); + * } + * @endcode + */ + std::size_t size() const + { + return pptr() - gptr(); + } + + /// Get the maximum size of the basic_streambuf. + /** + * @returns The allowed maximum of the sum of the sizes of the input sequence + * and output sequence. + */ + std::size_t max_size() const + { + return max_size_; + } + + /// Get a list of buffers that represents the input sequence. + /** + * @returns An object of type @c const_buffers_type that satisfies + * ConstBufferSequence requirements, representing all character arrays in the + * input sequence. + * + * @note The returned object is invalidated by any @c basic_streambuf member + * function that modifies the input sequence or output sequence. + */ + const_buffers_type data() const + { + return asio::buffer(asio::const_buffer(gptr(), + (pptr() - gptr()) * sizeof(char_type))); + } + + /// Get a list of buffers that represents the output sequence, with the given + /// size. + /** + * Ensures that the output sequence can accommodate @c n characters, + * reallocating character array objects as necessary. + * + * @returns An object of type @c mutable_buffers_type that satisfies + * MutableBufferSequence requirements, representing character array objects + * at the start of the output sequence such that the sum of the buffer sizes + * is @c n. + * + * @throws std::length_error If size() + n > max_size(). + * + * @note The returned object is invalidated by any @c basic_streambuf member + * function that modifies the input sequence or output sequence. + */ + mutable_buffers_type prepare(std::size_t n) + { + reserve(n); + return asio::buffer(asio::mutable_buffer( + pptr(), n * sizeof(char_type))); + } + + /// Move characters from the output sequence to the input sequence. + /** + * Appends @c n characters from the start of the output sequence to the input + * sequence. The beginning of the output sequence is advanced by @c n + * characters. + * + * Requires a preceding call prepare(x) where x >= n, and + * no intervening operations that modify the input or output sequence. + * + * @throws std::length_error If @c n is greater than the size of the output + * sequence. + */ + void commit(std::size_t n) + { + if (pptr() + n > epptr()) + n = epptr() - pptr(); + pbump(static_cast(n)); + setg(eback(), gptr(), pptr()); + } + + /// Remove characters from the input sequence. + /** + * Removes @c n characters from the beginning of the input sequence. + * + * @throws std::length_error If n > size(). + */ + void consume(std::size_t n) + { + if (gptr() + n > pptr()) + n = pptr() - gptr(); + gbump(static_cast(n)); + } + +protected: + enum { buffer_delta = 128 }; + + /// Override std::streambuf behaviour. + /** + * Behaves according to the specification of @c std::streambuf::underflow(). + */ + int_type underflow() + { + if (gptr() < pptr()) + { + setg(&buffer_[0], gptr(), pptr()); + return traits_type::to_int_type(*gptr()); + } + else + { + return traits_type::eof(); + } + } + + /// Override std::streambuf behaviour. + /** + * Behaves according to the specification of @c std::streambuf::overflow(), + * with the specialisation that @c std::length_error is thrown if appending + * the character to the input sequence would require the condition + * size() > max_size() to be true. + */ + int_type overflow(int_type c) + { + if (!traits_type::eq_int_type(c, traits_type::eof())) + { + if (pptr() == epptr()) + { + std::size_t buffer_size = pptr() - gptr(); + if (buffer_size < max_size_ && max_size_ - buffer_size < buffer_delta) + { + reserve(max_size_ - buffer_size); + } + else + { + reserve(buffer_delta); + } + } + + *pptr() = traits_type::to_char_type(c); + pbump(1); + return c; + } + + return traits_type::not_eof(c); + } + + void reserve(std::size_t n) + { + // Get current stream positions as offsets. + std::size_t gnext = gptr() - &buffer_[0]; + std::size_t pnext = pptr() - &buffer_[0]; + std::size_t pend = epptr() - &buffer_[0]; + + // Check if there is already enough space in the put area. + if (n <= pend - pnext) + { + return; + } + + // Shift existing contents of get area to start of buffer. + if (gnext > 0) + { + pnext -= gnext; + std::memmove(&buffer_[0], &buffer_[0] + gnext, pnext); + } + + // Ensure buffer is large enough to hold at least the specified size. + if (n > pend - pnext) + { + if (n <= max_size_ && pnext <= max_size_ - n) + { + pend = pnext + n; + buffer_.resize((std::max)(pend, 1)); + } + else + { + std::length_error ex("asio::streambuf too long"); + boost::throw_exception(ex); + } + } + + // Update stream positions. + setg(&buffer_[0], &buffer_[0], &buffer_[0] + pnext); + setp(&buffer_[0] + pnext, &buffer_[0] + pend); + } + +private: + std::size_t max_size_; + std::vector buffer_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(BOOST_NO_IOSTREAM) + +#endif // ASIO_BASIC_STREAMBUF_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/buffer.hpp b/src/libs/resiprocate/contrib/asio/asio/buffer.hpp new file mode 100644 index 00000000..43b475c5 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/buffer.hpp @@ -0,0 +1,1040 @@ +// +// buffer.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BUFFER_HPP +#define ASIO_BUFFER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_MSVC) +# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0) +# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING) +# define ASIO_ENABLE_BUFFER_DEBUGGING +# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING) +# endif // defined(_HAS_ITERATOR_DEBUGGING) +#endif // defined(BOOST_MSVC) + +#if defined(__GNUC__) +# if defined(_GLIBCXX_DEBUG) +# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING) +# define ASIO_ENABLE_BUFFER_DEBUGGING +# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING) +# endif // defined(_GLIBCXX_DEBUG) +#endif // defined(__GNUC__) + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) +# include "asio/detail/push_options.hpp" +# include +# include "asio/detail/pop_options.hpp" +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + +namespace asio { + +class mutable_buffer; +class const_buffer; + +namespace detail { +void* buffer_cast_helper(const mutable_buffer&); +const void* buffer_cast_helper(const const_buffer&); +std::size_t buffer_size_helper(const mutable_buffer&); +std::size_t buffer_size_helper(const const_buffer&); +} // namespace detail + +/// Holds a buffer that can be modified. +/** + * The mutable_buffer class provides a safe representation of a buffer that can + * be modified. It does not own the underlying data, and so is cheap to copy or + * assign. + */ +class mutable_buffer +{ +public: + /// Construct an empty buffer. + mutable_buffer() + : data_(0), + size_(0) + { + } + + /// Construct a buffer to represent a given memory range. + mutable_buffer(void* data, std::size_t size) + : data_(data), + size_(size) + { + } + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + mutable_buffer(void* data, std::size_t size, + boost::function debug_check) + : data_(data), + size_(size), + debug_check_(debug_check) + { + } + + const boost::function& get_debug_check() const + { + return debug_check_; + } +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + +private: + friend void* asio::detail::buffer_cast_helper( + const mutable_buffer& b); + friend std::size_t asio::detail::buffer_size_helper( + const mutable_buffer& b); + + void* data_; + std::size_t size_; + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + boost::function debug_check_; +#endif // ASIO_ENABLE_BUFFER_DEBUGGING +}; + +namespace detail { + +inline void* buffer_cast_helper(const mutable_buffer& b) +{ +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + if (b.size_ && b.debug_check_) + b.debug_check_(); +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + return b.data_; +} + +inline std::size_t buffer_size_helper(const mutable_buffer& b) +{ + return b.size_; +} + +} // namespace detail + +/// Cast a non-modifiable buffer to a specified pointer to POD type. +/** + * @relates mutable_buffer + */ +template +inline PointerToPodType buffer_cast(const mutable_buffer& b) +{ + return static_cast(detail::buffer_cast_helper(b)); +} + +/// Get the number of bytes in a non-modifiable buffer. +/** + * @relates mutable_buffer + */ +inline std::size_t buffer_size(const mutable_buffer& b) +{ + return detail::buffer_size_helper(b); +} + +/// Create a new modifiable buffer that is offset from the start of another. +/** + * @relates mutable_buffer + */ +inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start) +{ + if (start > buffer_size(b)) + return mutable_buffer(); + char* new_data = buffer_cast(b) + start; + std::size_t new_size = buffer_size(b) - start; + return mutable_buffer(new_data, new_size +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new modifiable buffer that is offset from the start of another. +/** + * @relates mutable_buffer + */ +inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b) +{ + if (start > buffer_size(b)) + return mutable_buffer(); + char* new_data = buffer_cast(b) + start; + std::size_t new_size = buffer_size(b) - start; + return mutable_buffer(new_data, new_size +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Adapts a single modifiable buffer so that it meets the requirements of the +/// MutableBufferSequence concept. +class mutable_buffers_1 + : public mutable_buffer +{ +public: + /// The type for each element in the list of buffers. + typedef mutable_buffer value_type; + + /// A random-access iterator type that may be used to read elements. + typedef const mutable_buffer* const_iterator; + + /// Construct to represent a given memory range. + mutable_buffers_1(void* data, std::size_t size) + : mutable_buffer(data, size) + { + } + + /// Construct to represent a single modifiable buffer. + explicit mutable_buffers_1(const mutable_buffer& b) + : mutable_buffer(b) + { + } + + /// Get a random-access iterator to the first element. + const_iterator begin() const + { + return this; + } + + /// Get a random-access iterator for one past the last element. + const_iterator end() const + { + return begin() + 1; + } +}; + +/// Holds a buffer that cannot be modified. +/** + * The const_buffer class provides a safe representation of a buffer that cannot + * be modified. It does not own the underlying data, and so is cheap to copy or + * assign. + */ +class const_buffer +{ +public: + /// Construct an empty buffer. + const_buffer() + : data_(0), + size_(0) + { + } + + /// Construct a buffer to represent a given memory range. + const_buffer(const void* data, std::size_t size) + : data_(data), + size_(size) + { + } + + /// Construct a non-modifiable buffer from a modifiable one. + const_buffer(const mutable_buffer& b) + : data_(asio::detail::buffer_cast_helper(b)), + size_(asio::detail::buffer_size_helper(b)) +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , debug_check_(b.get_debug_check()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + { + } + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + const_buffer(const void* data, std::size_t size, + boost::function debug_check) + : data_(data), + size_(size), + debug_check_(debug_check) + { + } + + const boost::function& get_debug_check() const + { + return debug_check_; + } +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + +private: + friend const void* asio::detail::buffer_cast_helper( + const const_buffer& b); + friend std::size_t asio::detail::buffer_size_helper( + const const_buffer& b); + + const void* data_; + std::size_t size_; + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + boost::function debug_check_; +#endif // ASIO_ENABLE_BUFFER_DEBUGGING +}; + +namespace detail { + +inline const void* buffer_cast_helper(const const_buffer& b) +{ +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + if (b.size_ && b.debug_check_) + b.debug_check_(); +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + return b.data_; +} + +inline std::size_t buffer_size_helper(const const_buffer& b) +{ + return b.size_; +} + +} // namespace detail + +/// Cast a non-modifiable buffer to a specified pointer to POD type. +/** + * @relates const_buffer + */ +template +inline PointerToPodType buffer_cast(const const_buffer& b) +{ + return static_cast(detail::buffer_cast_helper(b)); +} + +/// Get the number of bytes in a non-modifiable buffer. +/** + * @relates const_buffer + */ +inline std::size_t buffer_size(const const_buffer& b) +{ + return detail::buffer_size_helper(b); +} + +/// Create a new non-modifiable buffer that is offset from the start of another. +/** + * @relates const_buffer + */ +inline const_buffer operator+(const const_buffer& b, std::size_t start) +{ + if (start > buffer_size(b)) + return const_buffer(); + const char* new_data = buffer_cast(b) + start; + std::size_t new_size = buffer_size(b) - start; + return const_buffer(new_data, new_size +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new non-modifiable buffer that is offset from the start of another. +/** + * @relates const_buffer + */ +inline const_buffer operator+(std::size_t start, const const_buffer& b) +{ + if (start > buffer_size(b)) + return const_buffer(); + const char* new_data = buffer_cast(b) + start; + std::size_t new_size = buffer_size(b) - start; + return const_buffer(new_data, new_size +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Adapts a single non-modifiable buffer so that it meets the requirements of +/// the ConstBufferSequence concept. +class const_buffers_1 + : public const_buffer +{ +public: + /// The type for each element in the list of buffers. + typedef const_buffer value_type; + + /// A random-access iterator type that may be used to read elements. + typedef const const_buffer* const_iterator; + + /// Construct to represent a given memory range. + const_buffers_1(const void* data, std::size_t size) + : const_buffer(data, size) + { + } + + /// Construct to represent a single non-modifiable buffer. + explicit const_buffers_1(const const_buffer& b) + : const_buffer(b) + { + } + + /// Get a random-access iterator to the first element. + const_iterator begin() const + { + return this; + } + + /// Get a random-access iterator for one past the last element. + const_iterator end() const + { + return begin() + 1; + } +}; + +/// An implementation of both the ConstBufferSequence and MutableBufferSequence +/// concepts to represent a null buffer sequence. +class null_buffers +{ +public: + /// The type for each element in the list of buffers. + typedef mutable_buffer value_type; + + /// A random-access iterator type that may be used to read elements. + typedef const mutable_buffer* const_iterator; + + /// Get a random-access iterator to the first element. + const_iterator begin() const + { + return &buf_; + } + + /// Get a random-access iterator for one past the last element. + const_iterator end() const + { + return &buf_; + } + +private: + mutable_buffer buf_; +}; + +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) +namespace detail { + +template +class buffer_debug_check +{ +public: + buffer_debug_check(Iterator iter) + : iter_(iter) + { + } + + ~buffer_debug_check() + { +#if BOOST_WORKAROUND(BOOST_MSVC, == 1400) + // MSVC 8's string iterator checking may crash in a std::string::iterator + // object's destructor when the iterator points to an already-destroyed + // std::string object, unless the iterator is cleared first. + iter_ = Iterator(); +#endif // BOOST_WORKAROUND(BOOST_MSVC, == 1400) + } + + void operator()() + { + *iter_; + } + +private: + Iterator iter_; +}; + +} // namespace detail +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + +/** @defgroup buffer asio::buffer + * + * @brief The asio::buffer function is used to create a buffer object to + * represent raw memory, an array of POD elements, a vector of POD elements, + * or a std::string. + * + * A buffer object represents a contiguous region of memory as a 2-tuple + * consisting of a pointer and size in bytes. A tuple of the form {void*, + * size_t} specifies a mutable (modifiable) region of memory. Similarly, a + * tuple of the form {const void*, size_t} specifies a const + * (non-modifiable) region of memory. These two forms correspond to the classes + * mutable_buffer and const_buffer, respectively. To mirror C++'s conversion + * rules, a mutable_buffer is implicitly convertible to a const_buffer, and the + * opposite conversion is not permitted. + * + * The simplest use case involves reading or writing a single buffer of a + * specified size: + * + * @code sock.send(asio::buffer(data, size)); @endcode + * + * In the above example, the return value of asio::buffer meets the + * requirements of the ConstBufferSequence concept so that it may be directly + * passed to the socket's write function. A buffer created for modifiable + * memory also meets the requirements of the MutableBufferSequence concept. + * + * An individual buffer may be created from a builtin array, std::vector or + * boost::array of POD elements. This helps prevent buffer overruns by + * automatically determining the size of the buffer: + * + * @code char d1[128]; + * size_t bytes_transferred = sock.receive(asio::buffer(d1)); + * + * std::vector d2(128); + * bytes_transferred = sock.receive(asio::buffer(d2)); + * + * boost::array d3; + * bytes_transferred = sock.receive(asio::buffer(d3)); @endcode + * + * In all three cases above, the buffers created are exactly 128 bytes long. + * Note that a vector is @e never automatically resized when creating or using + * a buffer. The buffer size is determined using the vector's size() + * member function, and not its capacity. + * + * @par Accessing Buffer Contents + * + * The contents of a buffer may be accessed using the asio::buffer_size + * and asio::buffer_cast functions: + * + * @code asio::mutable_buffer b1 = ...; + * std::size_t s1 = asio::buffer_size(b1); + * unsigned char* p1 = asio::buffer_cast(b1); + * + * asio::const_buffer b2 = ...; + * std::size_t s2 = asio::buffer_size(b2); + * const void* p2 = asio::buffer_cast(b2); @endcode + * + * The asio::buffer_cast function permits violations of type safety, so + * uses of it in application code should be carefully considered. + * + * @par Buffer Invalidation + * + * A buffer object does not have any ownership of the memory it refers to. It + * is the responsibility of the application to ensure the memory region remains + * valid until it is no longer required for an I/O operation. When the memory + * is no longer available, the buffer is said to have been invalidated. + * + * For the asio::buffer overloads that accept an argument of type + * std::vector, the buffer objects returned are invalidated by any vector + * operation that also invalidates all references, pointers and iterators + * referring to the elements in the sequence (C++ Std, 23.2.4) + * + * For the asio::buffer overloads that accept an argument of type + * std::string, the buffer objects returned are invalidated according to the + * rules defined for invalidation of references, pointers and iterators + * referring to elements of the sequence (C++ Std, 21.3). + * + * @par Buffer Arithmetic + * + * Buffer objects may be manipulated using simple arithmetic in a safe way + * which helps prevent buffer overruns. Consider an array initialised as + * follows: + * + * @code boost::array a = { 'a', 'b', 'c', 'd', 'e' }; @endcode + * + * A buffer object @c b1 created using: + * + * @code b1 = asio::buffer(a); @endcode + * + * represents the entire array, { 'a', 'b', 'c', 'd', 'e' }. An + * optional second argument to the asio::buffer function may be used to + * limit the size, in bytes, of the buffer: + * + * @code b2 = asio::buffer(a, 3); @endcode + * + * such that @c b2 represents the data { 'a', 'b', 'c' }. Even if the + * size argument exceeds the actual size of the array, the size of the buffer + * object created will be limited to the array size. + * + * An offset may be applied to an existing buffer to create a new one: + * + * @code b3 = b1 + 2; @endcode + * + * where @c b3 will set to represent { 'c', 'd', 'e' }. If the offset + * exceeds the size of the existing buffer, the newly created buffer will be + * empty. + * + * Both an offset and size may be specified to create a buffer that corresponds + * to a specific range of bytes within an existing buffer: + * + * @code b4 = asio::buffer(b1 + 1, 3); @endcode + * + * so that @c b4 will refer to the bytes { 'b', 'c', 'd' }. + * + * @par Buffers and Scatter-Gather I/O + * + * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple + * buffer objects may be assigned into a container that supports the + * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts: + * + * @code + * char d1[128]; + * std::vector d2(128); + * boost::array d3; + * + * boost::array bufs1 = { + * asio::buffer(d1), + * asio::buffer(d2), + * asio::buffer(d3) }; + * bytes_transferred = sock.receive(bufs1); + * + * std::vector bufs2; + * bufs2.push_back(asio::buffer(d1)); + * bufs2.push_back(asio::buffer(d2)); + * bufs2.push_back(asio::buffer(d3)); + * bytes_transferred = sock.send(bufs2); @endcode + */ +/*@{*/ + +/// Create a new modifiable buffer from an existing buffer. +/** + * @returns mutable_buffers_1(b). + */ +inline mutable_buffers_1 buffer(const mutable_buffer& b) +{ + return mutable_buffers_1(b); +} + +/// Create a new modifiable buffer from an existing buffer. +/** + * @returns A mutable_buffers_1 value equivalent to: + * @code mutable_buffers_1( + * buffer_cast(b), + * min(buffer_size(b), max_size_in_bytes)); @endcode + */ +inline mutable_buffers_1 buffer(const mutable_buffer& b, + std::size_t max_size_in_bytes) +{ + return mutable_buffers_1( + mutable_buffer(buffer_cast(b), + buffer_size(b) < max_size_in_bytes + ? buffer_size(b) : max_size_in_bytes +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new non-modifiable buffer from an existing buffer. +/** + * @returns const_buffers_1(b). + */ +inline const_buffers_1 buffer(const const_buffer& b) +{ + return const_buffers_1(b); +} + +/// Create a new non-modifiable buffer from an existing buffer. +/** + * @returns A const_buffers_1 value equivalent to: + * @code const_buffers_1( + * buffer_cast(b), + * min(buffer_size(b), max_size_in_bytes)); @endcode + */ +inline const_buffers_1 buffer(const const_buffer& b, + std::size_t max_size_in_bytes) +{ + return const_buffers_1( + const_buffer(buffer_cast(b), + buffer_size(b) < max_size_in_bytes + ? buffer_size(b) : max_size_in_bytes +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new modifiable buffer that represents the given memory range. +/** + * @returns mutable_buffers_1(data, size_in_bytes). + */ +inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes) +{ + return mutable_buffers_1(mutable_buffer(data, size_in_bytes)); +} + +/// Create a new non-modifiable buffer that represents the given memory range. +/** + * @returns const_buffers_1(data, size_in_bytes). + */ +inline const_buffers_1 buffer(const void* data, + std::size_t size_in_bytes) +{ + return const_buffers_1(const_buffer(data, size_in_bytes)); +} + +/// Create a new modifiable buffer that represents the given POD array. +/** + * @returns A mutable_buffers_1 value equivalent to: + * @code mutable_buffers_1( + * static_cast(data), + * N * sizeof(PodType)); @endcode + */ +template +inline mutable_buffers_1 buffer(PodType (&data)[N]) +{ + return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType))); +} + +/// Create a new modifiable buffer that represents the given POD array. +/** + * @returns A mutable_buffers_1 value equivalent to: + * @code mutable_buffers_1( + * static_cast(data), + * min(N * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline mutable_buffers_1 buffer(PodType (&data)[N], + std::size_t max_size_in_bytes) +{ + return mutable_buffers_1( + mutable_buffer(data, + N * sizeof(PodType) < max_size_in_bytes + ? N * sizeof(PodType) : max_size_in_bytes)); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffers_1 value equivalent to: + * @code const_buffers_1( + * static_cast(data), + * N * sizeof(PodType)); @endcode + */ +template +inline const_buffers_1 buffer(const PodType (&data)[N]) +{ + return const_buffers_1(const_buffer(data, N * sizeof(PodType))); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffers_1 value equivalent to: + * @code const_buffers_1( + * static_cast(data), + * min(N * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline const_buffers_1 buffer(const PodType (&data)[N], + std::size_t max_size_in_bytes) +{ + return const_buffers_1( + const_buffer(data, + N * sizeof(PodType) < max_size_in_bytes + ? N * sizeof(PodType) : max_size_in_bytes)); +} + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \ + || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) + +// Borland C++ and Sun Studio think the overloads: +// +// unspecified buffer(boost::array& array ...); +// +// and +// +// unspecified buffer(boost::array& array ...); +// +// are ambiguous. This will be worked around by using a buffer_types traits +// class that contains typedefs for the appropriate buffer and container +// classes, based on whether PodType is const or non-const. + +namespace detail { + +template +struct buffer_types_base; + +template <> +struct buffer_types_base +{ + typedef mutable_buffer buffer_type; + typedef mutable_buffers_1 container_type; +}; + +template <> +struct buffer_types_base +{ + typedef const_buffer buffer_type; + typedef const_buffers_1 container_type; +}; + +template +struct buffer_types + : public buffer_types_base::value> +{ +}; + +} // namespace detail + +template +inline typename detail::buffer_types::container_type +buffer(boost::array& data) +{ + typedef typename asio::detail::buffer_types::buffer_type + buffer_type; + typedef typename asio::detail::buffer_types::container_type + container_type; + return container_type( + buffer_type(data.c_array(), data.size() * sizeof(PodType))); +} + +template +inline typename detail::buffer_types::container_type +buffer(boost::array& data, std::size_t max_size_in_bytes) +{ + typedef typename asio::detail::buffer_types::buffer_type + buffer_type; + typedef typename asio::detail::buffer_types::container_type + container_type; + return container_type( + buffer_type(data.c_array(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes)); +} + +#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) + // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) + +/// Create a new modifiable buffer that represents the given POD array. +/** + * @returns A mutable_buffers_1 value equivalent to: + * @code mutable_buffers_1( + * data.data(), + * data.size() * sizeof(PodType)); @endcode + */ +template +inline mutable_buffers_1 buffer(boost::array& data) +{ + return mutable_buffers_1( + mutable_buffer(data.c_array(), data.size() * sizeof(PodType))); +} + +/// Create a new modifiable buffer that represents the given POD array. +/** + * @returns A mutable_buffers_1 value equivalent to: + * @code mutable_buffers_1( + * data.data(), + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline mutable_buffers_1 buffer(boost::array& data, + std::size_t max_size_in_bytes) +{ + return mutable_buffers_1( + mutable_buffer(data.c_array(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes)); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffers_1 value equivalent to: + * @code const_buffers_1( + * data.data(), + * data.size() * sizeof(PodType)); @endcode + */ +template +inline const_buffers_1 buffer(boost::array& data) +{ + return const_buffers_1( + const_buffer(data.data(), data.size() * sizeof(PodType))); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffers_1 value equivalent to: + * @code const_buffers_1( + * data.data(), + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline const_buffers_1 buffer(boost::array& data, + std::size_t max_size_in_bytes) +{ + return const_buffers_1( + const_buffer(data.data(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes)); +} + +#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) + // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffers_1 value equivalent to: + * @code const_buffers_1( + * data.data(), + * data.size() * sizeof(PodType)); @endcode + */ +template +inline const_buffers_1 buffer(const boost::array& data) +{ + return const_buffers_1( + const_buffer(data.data(), data.size() * sizeof(PodType))); +} + +/// Create a new non-modifiable buffer that represents the given POD array. +/** + * @returns A const_buffers_1 value equivalent to: + * @code const_buffers_1( + * data.data(), + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + */ +template +inline const_buffers_1 buffer(const boost::array& data, + std::size_t max_size_in_bytes) +{ + return const_buffers_1( + const_buffer(data.data(), + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes)); +} + +/// Create a new modifiable buffer that represents the given POD vector. +/** + * @returns A mutable_buffers_1 value equivalent to: + * @code mutable_buffers_1( + * data.size() ? &data[0] : 0, + * data.size() * sizeof(PodType)); @endcode + * + * @note The buffer is invalidated by any vector operation that would also + * invalidate iterators. + */ +template +inline mutable_buffers_1 buffer(std::vector& data) +{ + return mutable_buffers_1( + mutable_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType) +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::vector::iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new modifiable buffer that represents the given POD vector. +/** + * @returns A mutable_buffers_1 value equivalent to: + * @code mutable_buffers_1( + * data.size() ? &data[0] : 0, + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + * + * @note The buffer is invalidated by any vector operation that would also + * invalidate iterators. + */ +template +inline mutable_buffers_1 buffer(std::vector& data, + std::size_t max_size_in_bytes) +{ + return mutable_buffers_1( + mutable_buffer(data.size() ? &data[0] : 0, + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::vector::iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new non-modifiable buffer that represents the given POD vector. +/** + * @returns A const_buffers_1 value equivalent to: + * @code const_buffers_1( + * data.size() ? &data[0] : 0, + * data.size() * sizeof(PodType)); @endcode + * + * @note The buffer is invalidated by any vector operation that would also + * invalidate iterators. + */ +template +inline const_buffers_1 buffer( + const std::vector& data) +{ + return const_buffers_1( + const_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType) +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::vector::const_iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new non-modifiable buffer that represents the given POD vector. +/** + * @returns A const_buffers_1 value equivalent to: + * @code const_buffers_1( + * data.size() ? &data[0] : 0, + * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode + * + * @note The buffer is invalidated by any vector operation that would also + * invalidate iterators. + */ +template +inline const_buffers_1 buffer( + const std::vector& data, std::size_t max_size_in_bytes) +{ + return const_buffers_1( + const_buffer(data.size() ? &data[0] : 0, + data.size() * sizeof(PodType) < max_size_in_bytes + ? data.size() * sizeof(PodType) : max_size_in_bytes +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check< + typename std::vector::const_iterator + >(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new non-modifiable buffer that represents the given string. +/** + * @returns const_buffers_1(data.data(), data.size()). + * + * @note The buffer is invalidated by any non-const operation called on the + * given string object. + */ +inline const_buffers_1 buffer(const std::string& data) +{ + return const_buffers_1(const_buffer(data.data(), data.size() +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/// Create a new non-modifiable buffer that represents the given string. +/** + * @returns A const_buffers_1 value equivalent to: + * @code const_buffers_1( + * data.data(), + * min(data.size(), max_size_in_bytes)); @endcode + * + * @note The buffer is invalidated by any non-const operation called on the + * given string object. + */ +inline const_buffers_1 buffer(const std::string& data, + std::size_t max_size_in_bytes) +{ + return const_buffers_1( + const_buffer(data.data(), + data.size() < max_size_in_bytes + ? data.size() : max_size_in_bytes +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , detail::buffer_debug_check(data.begin()) +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + )); +} + +/*@}*/ + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BUFFER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/buffered_read_stream.hpp b/src/libs/resiprocate/contrib/asio/asio/buffered_read_stream.hpp new file mode 100644 index 00000000..afd22cec --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/buffered_read_stream.hpp @@ -0,0 +1,461 @@ +// +// buffered_read_stream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BUFFERED_READ_STREAM_HPP +#define ASIO_BUFFERED_READ_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffered_read_stream_fwd.hpp" +#include "asio/buffer.hpp" +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_resize_guard.hpp" +#include "asio/detail/buffered_stream_storage.hpp" +#include "asio/detail/noncopyable.hpp" + +namespace asio { + +/// Adds buffering to the read-related operations of a stream. +/** + * The buffered_read_stream class template can be used to add buffering to the + * synchronous and asynchronous read operations of a stream. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, Sync_Read_Stream, SyncWriteStream. + */ +template +class buffered_read_stream + : private noncopyable +{ +public: + /// The type of the next layer. + typedef typename boost::remove_reference::type next_layer_type; + + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + +#if defined(GENERATING_DOCUMENTATION) + /// The default buffer size. + static const std::size_t default_buffer_size = implementation_defined; +#else + BOOST_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024); +#endif + + /// Construct, passing the specified argument to initialise the next layer. + template + explicit buffered_read_stream(Arg& a) + : next_layer_(a), + storage_(default_buffer_size) + { + } + + /// Construct, passing the specified argument to initialise the next layer. + template + buffered_read_stream(Arg& a, std::size_t buffer_size) + : next_layer_(a), + storage_(buffer_size) + { + } + + /// Get a reference to the next layer. + next_layer_type& next_layer() + { + return next_layer_; + } + + /// Get a reference to the lowest layer. + lowest_layer_type& lowest_layer() + { + return next_layer_.lowest_layer(); + } + + /// Get a const reference to the lowest layer. + const lowest_layer_type& lowest_layer() const + { + return next_layer_.lowest_layer(); + } + + /// (Deprecated: use get_io_service().) Get the io_service associated with + /// the object. + asio::io_service& io_service() + { + return next_layer_.get_io_service(); + } + + /// Get the io_service associated with the object. + asio::io_service& get_io_service() + { + return next_layer_.get_io_service(); + } + + /// Close the stream. + void close() + { + next_layer_.close(); + } + + /// Close the stream. + asio::error_code close(asio::error_code& ec) + { + return next_layer_.close(ec); + } + + /// Write the given data to the stream. Returns the number of bytes written. + /// Throws an exception on failure. + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + return next_layer_.write_some(buffers); + } + + /// Write the given data to the stream. Returns the number of bytes written, + /// or 0 if an error occurred. + template + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) + { + return next_layer_.write_some(buffers, ec); + } + + /// Start an asynchronous write. The data being written must be valid for the + /// lifetime of the asynchronous operation. + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + next_layer_.async_write_some(buffers, handler); + } + + /// Fill the buffer with some data. Returns the number of bytes placed in the + /// buffer as a result of the operation. Throws an exception on failure. + std::size_t fill() + { + detail::buffer_resize_guard + resize_guard(storage_); + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + storage_.resize(previous_size + next_layer_.read_some(buffer( + storage_.data() + previous_size, + storage_.size() - previous_size))); + resize_guard.commit(); + return storage_.size() - previous_size; + } + + /// Fill the buffer with some data. Returns the number of bytes placed in the + /// buffer as a result of the operation, or 0 if an error occurred. + std::size_t fill(asio::error_code& ec) + { + detail::buffer_resize_guard + resize_guard(storage_); + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + storage_.resize(previous_size + next_layer_.read_some(buffer( + storage_.data() + previous_size, + storage_.size() - previous_size), + ec)); + resize_guard.commit(); + return storage_.size() - previous_size; + } + + template + class fill_handler + { + public: + fill_handler(asio::io_service& io_service, + detail::buffered_stream_storage& storage, + std::size_t previous_size, ReadHandler handler) + : io_service_(io_service), + storage_(storage), + previous_size_(previous_size), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + storage_.resize(previous_size_ + bytes_transferred); + io_service_.dispatch(detail::bind_handler( + handler_, ec, bytes_transferred)); + } + + private: + asio::io_service& io_service_; + detail::buffered_stream_storage& storage_; + std::size_t previous_size_; + ReadHandler handler_; + }; + + /// Start an asynchronous fill. + template + void async_fill(ReadHandler handler) + { + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + next_layer_.async_read_some( + buffer( + storage_.data() + previous_size, + storage_.size() - previous_size), + fill_handler(get_io_service(), + storage_, previous_size, handler)); + } + + /// Read some data from the stream. Returns the number of bytes read. Throws + /// an exception on failure. + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + size_t total_buffer_size = 0; + for (; iter != end; ++iter) + { + asio::mutable_buffer buffer(*iter); + total_buffer_size += asio::buffer_size(buffer); + } + + if (total_buffer_size == 0) + return 0; + + if (storage_.empty()) + fill(); + + return copy(buffers); + } + + /// Read some data from the stream. Returns the number of bytes read or 0 if + /// an error occurred. + template + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + ec = asio::error_code(); + + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + size_t total_buffer_size = 0; + for (; iter != end; ++iter) + { + asio::mutable_buffer buffer(*iter); + total_buffer_size += asio::buffer_size(buffer); + } + + if (total_buffer_size == 0) + return 0; + + if (storage_.empty() && !fill(ec)) + return 0; + + return copy(buffers); + } + + template + class read_some_handler + { + public: + read_some_handler(asio::io_service& io_service, + detail::buffered_stream_storage& storage, + const MutableBufferSequence& buffers, ReadHandler handler) + : io_service_(io_service), + storage_(storage), + buffers_(buffers), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, std::size_t) + { + if (ec || storage_.empty()) + { + std::size_t length = 0; + io_service_.dispatch(detail::bind_handler(handler_, ec, length)); + } + else + { + using namespace std; // For memcpy. + + std::size_t bytes_avail = storage_.size(); + std::size_t bytes_copied = 0; + + typename MutableBufferSequence::const_iterator iter = buffers_.begin(); + typename MutableBufferSequence::const_iterator end = buffers_.end(); + for (; iter != end && bytes_avail > 0; ++iter) + { + std::size_t max_length = buffer_size(*iter); + std::size_t length = (max_length < bytes_avail) + ? max_length : bytes_avail; + memcpy(buffer_cast(*iter), + storage_.data() + bytes_copied, length); + bytes_copied += length; + bytes_avail -= length; + } + + storage_.consume(bytes_copied); + io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied)); + } + } + + private: + asio::io_service& io_service_; + detail::buffered_stream_storage& storage_; + MutableBufferSequence buffers_; + ReadHandler handler_; + }; + + /// Start an asynchronous read. The buffer into which the data will be read + /// must be valid for the lifetime of the asynchronous operation. + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + size_t total_buffer_size = 0; + for (; iter != end; ++iter) + { + asio::mutable_buffer buffer(*iter); + total_buffer_size += asio::buffer_size(buffer); + } + + if (total_buffer_size == 0) + { + get_io_service().post(detail::bind_handler( + handler, asio::error_code(), 0)); + } + else if (storage_.empty()) + { + async_fill(read_some_handler( + get_io_service(), storage_, buffers, handler)); + } + else + { + std::size_t length = copy(buffers); + get_io_service().post(detail::bind_handler( + handler, asio::error_code(), length)); + } + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read. + /// Throws an exception on failure. + template + std::size_t peek(const MutableBufferSequence& buffers) + { + if (storage_.empty()) + fill(); + return peek_copy(buffers); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read, + /// or 0 if an error occurred. + template + std::size_t peek(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + ec = asio::error_code(); + if (storage_.empty() && !fill(ec)) + return 0; + return peek_copy(buffers); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail() + { + return storage_.size(); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail(asio::error_code& ec) + { + ec = asio::error_code(); + return storage_.size(); + } + +private: + /// Copy data out of the internal buffer to the specified target buffer. + /// Returns the number of bytes copied. + template + std::size_t copy(const MutableBufferSequence& buffers) + { + using namespace std; // For memcpy. + + std::size_t bytes_avail = storage_.size(); + std::size_t bytes_copied = 0; + + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + for (; iter != end && bytes_avail > 0; ++iter) + { + std::size_t max_length = buffer_size(*iter); + std::size_t length = (max_length < bytes_avail) + ? max_length : bytes_avail; + memcpy(buffer_cast(*iter), storage_.data() + bytes_copied, length); + bytes_copied += length; + bytes_avail -= length; + } + + storage_.consume(bytes_copied); + return bytes_copied; + } + + /// Copy data from the internal buffer to the specified target buffer, without + /// removing the data from the internal buffer. Returns the number of bytes + /// copied. + template + std::size_t peek_copy(const MutableBufferSequence& buffers) + { + using namespace std; // For memcpy. + + std::size_t bytes_avail = storage_.size(); + std::size_t bytes_copied = 0; + + typename MutableBufferSequence::const_iterator iter = buffers.begin(); + typename MutableBufferSequence::const_iterator end = buffers.end(); + for (; iter != end && bytes_avail > 0; ++iter) + { + std::size_t max_length = buffer_size(*iter); + std::size_t length = (max_length < bytes_avail) + ? max_length : bytes_avail; + memcpy(buffer_cast(*iter), storage_.data() + bytes_copied, length); + bytes_copied += length; + bytes_avail -= length; + } + + return bytes_copied; + } + + /// The next layer. + Stream next_layer_; + + // The data in the buffer. + detail::buffered_stream_storage storage_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BUFFERED_READ_STREAM_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/buffered_read_stream_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/buffered_read_stream_fwd.hpp new file mode 100644 index 00000000..5078775d --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/buffered_read_stream_fwd.hpp @@ -0,0 +1,29 @@ +// +// buffered_read_stream_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BUFFERED_READ_STREAM_FWD_HPP +#define ASIO_BUFFERED_READ_STREAM_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +class buffered_read_stream; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BUFFERED_READ_STREAM_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/buffered_stream.hpp b/src/libs/resiprocate/contrib/asio/asio/buffered_stream.hpp new file mode 100644 index 00000000..23dc9c33 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/buffered_stream.hpp @@ -0,0 +1,256 @@ +// +// buffered_stream.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BUFFERED_STREAM_HPP +#define ASIO_BUFFERED_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffered_read_stream.hpp" +#include "asio/buffered_write_stream.hpp" +#include "asio/buffered_stream_fwd.hpp" +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/noncopyable.hpp" + +namespace asio { + +/// Adds buffering to the read- and write-related operations of a stream. +/** + * The buffered_stream class template can be used to add buffering to the + * synchronous and asynchronous read and write operations of a stream. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template +class buffered_stream + : private noncopyable +{ +public: + /// The type of the next layer. + typedef typename boost::remove_reference::type next_layer_type; + + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + + /// Construct, passing the specified argument to initialise the next layer. + template + explicit buffered_stream(Arg& a) + : inner_stream_impl_(a), + stream_impl_(inner_stream_impl_) + { + } + + /// Construct, passing the specified argument to initialise the next layer. + template + explicit buffered_stream(Arg& a, std::size_t read_buffer_size, + std::size_t write_buffer_size) + : inner_stream_impl_(a, write_buffer_size), + stream_impl_(inner_stream_impl_, read_buffer_size) + { + } + + /// Get a reference to the next layer. + next_layer_type& next_layer() + { + return stream_impl_.next_layer().next_layer(); + } + + /// Get a reference to the lowest layer. + lowest_layer_type& lowest_layer() + { + return stream_impl_.lowest_layer(); + } + + /// Get a const reference to the lowest layer. + const lowest_layer_type& lowest_layer() const + { + return stream_impl_.lowest_layer(); + } + + /// (Deprecated: use get_io_service().) Get the io_service associated with + /// the object. + asio::io_service& io_service() + { + return stream_impl_.get_io_service(); + } + + /// Get the io_service associated with the object. + asio::io_service& get_io_service() + { + return stream_impl_.get_io_service(); + } + + /// Close the stream. + void close() + { + stream_impl_.close(); + } + + /// Close the stream. + asio::error_code close(asio::error_code& ec) + { + return stream_impl_.close(ec); + } + + /// Flush all data from the buffer to the next layer. Returns the number of + /// bytes written to the next layer on the last write operation. Throws an + /// exception on failure. + std::size_t flush() + { + return stream_impl_.next_layer().flush(); + } + + /// Flush all data from the buffer to the next layer. Returns the number of + /// bytes written to the next layer on the last write operation, or 0 if an + /// error occurred. + std::size_t flush(asio::error_code& ec) + { + return stream_impl_.next_layer().flush(ec); + } + + /// Start an asynchronous flush. + template + void async_flush(WriteHandler handler) + { + return stream_impl_.next_layer().async_flush(handler); + } + + /// Write the given data to the stream. Returns the number of bytes written. + /// Throws an exception on failure. + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + return stream_impl_.write_some(buffers); + } + + /// Write the given data to the stream. Returns the number of bytes written, + /// or 0 if an error occurred. + template + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) + { + return stream_impl_.write_some(buffers, ec); + } + + /// Start an asynchronous write. The data being written must be valid for the + /// lifetime of the asynchronous operation. + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + stream_impl_.async_write_some(buffers, handler); + } + + /// Fill the buffer with some data. Returns the number of bytes placed in the + /// buffer as a result of the operation. Throws an exception on failure. + std::size_t fill() + { + return stream_impl_.fill(); + } + + /// Fill the buffer with some data. Returns the number of bytes placed in the + /// buffer as a result of the operation, or 0 if an error occurred. + std::size_t fill(asio::error_code& ec) + { + return stream_impl_.fill(ec); + } + + /// Start an asynchronous fill. + template + void async_fill(ReadHandler handler) + { + stream_impl_.async_fill(handler); + } + + /// Read some data from the stream. Returns the number of bytes read. Throws + /// an exception on failure. + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + return stream_impl_.read_some(buffers); + } + + /// Read some data from the stream. Returns the number of bytes read or 0 if + /// an error occurred. + template + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return stream_impl_.read_some(buffers, ec); + } + + /// Start an asynchronous read. The buffer into which the data will be read + /// must be valid for the lifetime of the asynchronous operation. + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + stream_impl_.async_read_some(buffers, handler); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read. + /// Throws an exception on failure. + template + std::size_t peek(const MutableBufferSequence& buffers) + { + return stream_impl_.peek(buffers); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read, + /// or 0 if an error occurred. + template + std::size_t peek(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return stream_impl_.peek(buffers, ec); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail() + { + return stream_impl_.in_avail(); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail(asio::error_code& ec) + { + return stream_impl_.in_avail(ec); + } + +private: + // The buffered write stream. + typedef buffered_write_stream write_stream_type; + write_stream_type inner_stream_impl_; + + // The buffered read stream. + typedef buffered_read_stream read_stream_type; + read_stream_type stream_impl_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BUFFERED_STREAM_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/buffered_stream_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/buffered_stream_fwd.hpp new file mode 100644 index 00000000..f26cd43c --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/buffered_stream_fwd.hpp @@ -0,0 +1,29 @@ +// +// buffered_stream_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BUFFERED_STREAM_FWD_HPP +#define ASIO_BUFFERED_STREAM_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +class buffered_stream; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BUFFERED_STREAM_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/buffered_write_stream.hpp b/src/libs/resiprocate/contrib/asio/asio/buffered_write_stream.hpp new file mode 100644 index 00000000..30a92ce6 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/buffered_write_stream.hpp @@ -0,0 +1,415 @@ +// +// buffered_write_stream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BUFFERED_WRITE_STREAM_HPP +#define ASIO_BUFFERED_WRITE_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffered_write_stream_fwd.hpp" +#include "asio/buffer.hpp" +#include "asio/completion_condition.hpp" +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/write.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffered_stream_storage.hpp" +#include "asio/detail/noncopyable.hpp" + +namespace asio { + +/// Adds buffering to the write-related operations of a stream. +/** + * The buffered_write_stream class template can be used to add buffering to the + * synchronous and asynchronous write operations of a stream. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template +class buffered_write_stream + : private noncopyable +{ +public: + /// The type of the next layer. + typedef typename boost::remove_reference::type next_layer_type; + + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + +#if defined(GENERATING_DOCUMENTATION) + /// The default buffer size. + static const std::size_t default_buffer_size = implementation_defined; +#else + BOOST_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024); +#endif + + /// Construct, passing the specified argument to initialise the next layer. + template + explicit buffered_write_stream(Arg& a) + : next_layer_(a), + storage_(default_buffer_size) + { + } + + /// Construct, passing the specified argument to initialise the next layer. + template + buffered_write_stream(Arg& a, std::size_t buffer_size) + : next_layer_(a), + storage_(buffer_size) + { + } + + /// Get a reference to the next layer. + next_layer_type& next_layer() + { + return next_layer_; + } + + /// Get a reference to the lowest layer. + lowest_layer_type& lowest_layer() + { + return next_layer_.lowest_layer(); + } + + /// Get a const reference to the lowest layer. + const lowest_layer_type& lowest_layer() const + { + return next_layer_.lowest_layer(); + } + + /// (Deprecated: use get_io_service().) Get the io_service associated with + /// the object. + asio::io_service& io_service() + { + return next_layer_.get_io_service(); + } + + /// Get the io_service associated with the object. + asio::io_service& get_io_service() + { + return next_layer_.get_io_service(); + } + + /// Close the stream. + void close() + { + next_layer_.close(); + } + + /// Close the stream. + asio::error_code close(asio::error_code& ec) + { + return next_layer_.close(ec); + } + + /// Flush all data from the buffer to the next layer. Returns the number of + /// bytes written to the next layer on the last write operation. Throws an + /// exception on failure. + std::size_t flush() + { + std::size_t bytes_written = write(next_layer_, + buffer(storage_.data(), storage_.size())); + storage_.consume(bytes_written); + return bytes_written; + } + + /// Flush all data from the buffer to the next layer. Returns the number of + /// bytes written to the next layer on the last write operation, or 0 if an + /// error occurred. + std::size_t flush(asio::error_code& ec) + { + std::size_t bytes_written = write(next_layer_, + buffer(storage_.data(), storage_.size()), + transfer_all(), ec); + storage_.consume(bytes_written); + return bytes_written; + } + + template + class flush_handler + { + public: + flush_handler(asio::io_service& io_service, + detail::buffered_stream_storage& storage, WriteHandler handler) + : io_service_(io_service), + storage_(storage), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_written) + { + storage_.consume(bytes_written); + io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_written)); + } + + private: + asio::io_service& io_service_; + detail::buffered_stream_storage& storage_; + WriteHandler handler_; + }; + + /// Start an asynchronous flush. + template + void async_flush(WriteHandler handler) + { + async_write(next_layer_, buffer(storage_.data(), storage_.size()), + flush_handler(get_io_service(), storage_, handler)); + } + + /// Write the given data to the stream. Returns the number of bytes written. + /// Throws an exception on failure. + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + typename ConstBufferSequence::const_iterator iter = buffers.begin(); + typename ConstBufferSequence::const_iterator end = buffers.end(); + size_t total_buffer_size = 0; + for (; iter != end; ++iter) + { + asio::const_buffer buffer(*iter); + total_buffer_size += asio::buffer_size(buffer); + } + + if (total_buffer_size == 0) + return 0; + + if (storage_.size() == storage_.capacity()) + flush(); + + return copy(buffers); + } + + /// Write the given data to the stream. Returns the number of bytes written, + /// or 0 if an error occurred and the error handler did not throw. + template + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) + { + ec = asio::error_code(); + + typename ConstBufferSequence::const_iterator iter = buffers.begin(); + typename ConstBufferSequence::const_iterator end = buffers.end(); + size_t total_buffer_size = 0; + for (; iter != end; ++iter) + { + asio::const_buffer buffer(*iter); + total_buffer_size += asio::buffer_size(buffer); + } + + if (total_buffer_size == 0) + return 0; + + if (storage_.size() == storage_.capacity() && !flush(ec)) + return 0; + + return copy(buffers); + } + + template + class write_some_handler + { + public: + write_some_handler(asio::io_service& io_service, + detail::buffered_stream_storage& storage, + const ConstBufferSequence& buffers, WriteHandler handler) + : io_service_(io_service), + storage_(storage), + buffers_(buffers), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, std::size_t) + { + if (ec) + { + std::size_t length = 0; + io_service_.dispatch(detail::bind_handler(handler_, ec, length)); + } + else + { + using namespace std; // For memcpy. + + std::size_t orig_size = storage_.size(); + std::size_t space_avail = storage_.capacity() - orig_size; + std::size_t bytes_copied = 0; + + typename ConstBufferSequence::const_iterator iter = buffers_.begin(); + typename ConstBufferSequence::const_iterator end = buffers_.end(); + for (; iter != end && space_avail > 0; ++iter) + { + std::size_t bytes_avail = buffer_size(*iter); + std::size_t length = (bytes_avail < space_avail) + ? bytes_avail : space_avail; + storage_.resize(orig_size + bytes_copied + length); + memcpy(storage_.data() + orig_size + bytes_copied, + buffer_cast(*iter), length); + bytes_copied += length; + space_avail -= length; + } + + io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied)); + } + } + + private: + asio::io_service& io_service_; + detail::buffered_stream_storage& storage_; + ConstBufferSequence buffers_; + WriteHandler handler_; + }; + + /// Start an asynchronous write. The data being written must be valid for the + /// lifetime of the asynchronous operation. + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + typename ConstBufferSequence::const_iterator iter = buffers.begin(); + typename ConstBufferSequence::const_iterator end = buffers.end(); + size_t total_buffer_size = 0; + for (; iter != end; ++iter) + { + asio::const_buffer buffer(*iter); + total_buffer_size += asio::buffer_size(buffer); + } + + if (total_buffer_size == 0) + { + get_io_service().post(detail::bind_handler( + handler, asio::error_code(), 0)); + } + else if (storage_.size() == storage_.capacity()) + { + async_flush(write_some_handler( + get_io_service(), storage_, buffers, handler)); + } + else + { + std::size_t bytes_copied = copy(buffers); + get_io_service().post(detail::bind_handler( + handler, asio::error_code(), bytes_copied)); + } + } + + /// Read some data from the stream. Returns the number of bytes read. Throws + /// an exception on failure. + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + return next_layer_.read_some(buffers); + } + + /// Read some data from the stream. Returns the number of bytes read or 0 if + /// an error occurred. + template + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return next_layer_.read_some(buffers, ec); + } + + /// Start an asynchronous read. The buffer into which the data will be read + /// must be valid for the lifetime of the asynchronous operation. + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + next_layer_.async_read_some(buffers, handler); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read. + /// Throws an exception on failure. + template + std::size_t peek(const MutableBufferSequence& buffers) + { + return next_layer_.peek(buffers); + } + + /// Peek at the incoming data on the stream. Returns the number of bytes read, + /// or 0 if an error occurred. + template + std::size_t peek(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return next_layer_.peek(buffers, ec); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail() + { + return next_layer_.in_avail(); + } + + /// Determine the amount of data that may be read without blocking. + std::size_t in_avail(asio::error_code& ec) + { + return next_layer_.in_avail(ec); + } + +private: + /// Copy data into the internal buffer from the specified source buffer. + /// Returns the number of bytes copied. + template + std::size_t copy(const ConstBufferSequence& buffers) + { + using namespace std; // For memcpy. + + std::size_t orig_size = storage_.size(); + std::size_t space_avail = storage_.capacity() - orig_size; + std::size_t bytes_copied = 0; + + typename ConstBufferSequence::const_iterator iter = buffers.begin(); + typename ConstBufferSequence::const_iterator end = buffers.end(); + for (; iter != end && space_avail > 0; ++iter) + { + std::size_t bytes_avail = buffer_size(*iter); + std::size_t length = (bytes_avail < space_avail) + ? bytes_avail : space_avail; + storage_.resize(orig_size + bytes_copied + length); + memcpy(storage_.data() + orig_size + bytes_copied, + buffer_cast(*iter), length); + bytes_copied += length; + space_avail -= length; + } + + return bytes_copied; + } + + /// The next layer. + Stream next_layer_; + + // The data in the buffer. + detail::buffered_stream_storage storage_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BUFFERED_WRITE_STREAM_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/buffered_write_stream_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/buffered_write_stream_fwd.hpp new file mode 100644 index 00000000..dc0e0147 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/buffered_write_stream_fwd.hpp @@ -0,0 +1,29 @@ +// +// buffered_write_stream_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BUFFERED_WRITE_STREAM_FWD_HPP +#define ASIO_BUFFERED_WRITE_STREAM_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +class buffered_write_stream; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BUFFERED_WRITE_STREAM_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/buffers_iterator.hpp b/src/libs/resiprocate/contrib/asio/asio/buffers_iterator.hpp new file mode 100644 index 00000000..7da55f2f --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/buffers_iterator.hpp @@ -0,0 +1,447 @@ +// +// buffers_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_BUFFERS_ITERATOR_HPP +#define ASIO_BUFFERS_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffer.hpp" + +namespace asio { + +namespace detail +{ + template + struct buffers_iterator_types_helper; + + template <> + struct buffers_iterator_types_helper + { + typedef const_buffer buffer_type; + template + struct byte_type + { + typedef typename boost::add_const::type type; + }; + }; + + template <> + struct buffers_iterator_types_helper + { + typedef mutable_buffer buffer_type; + template + struct byte_type + { + typedef ByteType type; + }; + }; + + template + struct buffers_iterator_types + { + enum + { + is_mutable = boost::is_convertible< + typename BufferSequence::value_type, mutable_buffer>::value + }; + typedef buffers_iterator_types_helper helper; + typedef typename helper::buffer_type buffer_type; + typedef typename helper::template byte_type::type byte_type; + }; +} + +/// A random access iterator over the bytes in a buffer sequence. +template +class buffers_iterator + : public boost::iterator< + std::random_access_iterator_tag, + typename detail::buffers_iterator_types< + BufferSequence, ByteType>::byte_type> +{ +private: + typedef typename detail::buffers_iterator_types< + BufferSequence, ByteType>::buffer_type buffer_type; + typedef typename detail::buffers_iterator_types< + BufferSequence, ByteType>::byte_type byte_type; + +public: + /// Default constructor. Creates an iterator in an undefined state. + buffers_iterator() + : current_buffer_(), + current_buffer_position_(0), + begin_(), + current_(), + end_(), + position_(0) + { + } + + /// Construct an iterator representing the beginning of the buffers' data. + static buffers_iterator begin(const BufferSequence& buffers) +#if BOOST_WORKAROUND(__GNUC__, == 4) && BOOST_WORKAROUND(__GNUC_MINOR__, == 3) + __attribute__ ((noinline)) +#endif + { + buffers_iterator new_iter; + new_iter.begin_ = buffers.begin(); + new_iter.current_ = buffers.begin(); + new_iter.end_ = buffers.end(); + while (new_iter.current_ != new_iter.end_) + { + new_iter.current_buffer_ = *new_iter.current_; + if (asio::buffer_size(new_iter.current_buffer_) > 0) + break; + ++new_iter.current_; + } + return new_iter; + } + + /// Construct an iterator representing the end of the buffers' data. + static buffers_iterator end(const BufferSequence& buffers) +#if BOOST_WORKAROUND(__GNUC__, == 4) && BOOST_WORKAROUND(__GNUC_MINOR__, == 3) + __attribute__ ((noinline)) +#endif + { + buffers_iterator new_iter; + new_iter.begin_ = buffers.begin(); + new_iter.current_ = buffers.begin(); + new_iter.end_ = buffers.end(); + while (new_iter.current_ != new_iter.end_) + { + buffer_type buffer = *new_iter.current_; + new_iter.position_ += asio::buffer_size(buffer); + ++new_iter.current_; + } + return new_iter; + } + + /// Dereference an iterator. + byte_type& operator*() const + { + return dereference(); + } + + /// Dereference an iterator. + byte_type* operator->() const + { + return &dereference(); + } + + /// Access an individual element. + byte_type& operator[](std::ptrdiff_t difference) const + { + buffers_iterator tmp(*this); + tmp.advance(difference); + return *tmp; + } + + /// Increment operator (prefix). + buffers_iterator& operator++() + { + increment(); + return *this; + } + + /// Increment operator (postfix). + buffers_iterator operator++(int) + { + buffers_iterator tmp(*this); + ++*this; + return tmp; + } + + /// Decrement operator (prefix). + buffers_iterator& operator--() + { + decrement(); + return *this; + } + + /// Decrement operator (postfix). + buffers_iterator operator--(int) + { + buffers_iterator tmp(*this); + --*this; + return tmp; + } + + /// Addition operator. + buffers_iterator& operator+=(std::ptrdiff_t difference) + { + advance(difference); + return *this; + } + + /// Subtraction operator. + buffers_iterator& operator-=(std::ptrdiff_t difference) + { + advance(-difference); + return *this; + } + + /// Addition operator. + friend buffers_iterator operator+(const buffers_iterator& iter, + std::ptrdiff_t difference) + { + buffers_iterator tmp(iter); + tmp.advance(difference); + return tmp; + } + + /// Subtraction operator. + friend buffers_iterator operator-(const buffers_iterator& iter, + std::ptrdiff_t difference) + { + buffers_iterator tmp(iter); + tmp.advance(-difference); + return tmp; + } + + /// Subtraction operator. + friend std::ptrdiff_t operator-(const buffers_iterator& a, + const buffers_iterator& b) + { + return b.distance_to(a); + } + + /// Test two iterators for equality. + friend bool operator==(const buffers_iterator& a, const buffers_iterator& b) + { + return a.equal(b); + } + + /// Test two iterators for inequality. + friend bool operator!=(const buffers_iterator& a, const buffers_iterator& b) + { + return !a.equal(b); + } + + /// Compare two iterators. + friend bool operator<(const buffers_iterator& a, const buffers_iterator& b) + { + return a.distance_to(b) > 0; + } + + /// Compare two iterators. + friend bool operator<=(const buffers_iterator& a, const buffers_iterator& b) + { + return !(b < a); + } + + /// Compare two iterators. + friend bool operator>(const buffers_iterator& a, const buffers_iterator& b) + { + return b < a; + } + + /// Compare two iterators. + friend bool operator>=(const buffers_iterator& a, const buffers_iterator& b) + { + return !(a < b); + } + +private: + // Dereference the iterator. + byte_type& dereference() const + { + return buffer_cast(current_buffer_)[current_buffer_position_]; + } + + // Compare two iterators for equality. + bool equal(const buffers_iterator& other) const + { + return position_ == other.position_; + } + + // Increment the iterator. + void increment() + { + BOOST_ASSERT(current_ != end_ && "iterator out of bounds"); + ++position_; + + // Check if the increment can be satisfied by the current buffer. + ++current_buffer_position_; + if (current_buffer_position_ != asio::buffer_size(current_buffer_)) + return; + + // Find the next non-empty buffer. + ++current_; + current_buffer_position_ = 0; + while (current_ != end_) + { + current_buffer_ = *current_; + if (asio::buffer_size(current_buffer_) > 0) + return; + ++current_; + } + } + + // Decrement the iterator. + void decrement() + { + BOOST_ASSERT(position_ > 0 && "iterator out of bounds"); + --position_; + + // Check if the decrement can be satisfied by the current buffer. + if (current_buffer_position_ != 0) + { + --current_buffer_position_; + return; + } + + // Find the previous non-empty buffer. + typename BufferSequence::const_iterator iter = current_; + while (iter != begin_) + { + --iter; + buffer_type buffer = *iter; + std::size_t buffer_size = asio::buffer_size(buffer); + if (buffer_size > 0) + { + current_ = iter; + current_buffer_ = buffer; + current_buffer_position_ = buffer_size - 1; + return; + } + } + } + + // Advance the iterator by the specified distance. + void advance(std::ptrdiff_t n) + { + if (n > 0) + { + BOOST_ASSERT(current_ != end_ && "iterator out of bounds"); + for (;;) + { + std::ptrdiff_t current_buffer_balance + = asio::buffer_size(current_buffer_) + - current_buffer_position_; + + // Check if the advance can be satisfied by the current buffer. + if (current_buffer_balance > n) + { + position_ += n; + current_buffer_position_ += n; + return; + } + + // Update position. + n -= current_buffer_balance; + position_ += current_buffer_balance; + + // Move to next buffer. If it is empty then it will be skipped on the + // next iteration of this loop. + if (++current_ == end_) + { + BOOST_ASSERT(n == 0 && "iterator out of bounds"); + current_buffer_ = buffer_type(); + current_buffer_position_ = 0; + return; + } + current_buffer_ = *current_; + current_buffer_position_ = 0; + } + } + else if (n < 0) + { + std::size_t abs_n = -n; + BOOST_ASSERT(position_ >= abs_n && "iterator out of bounds"); + for (;;) + { + // Check if the advance can be satisfied by the current buffer. + if (current_buffer_position_ >= abs_n) + { + position_ -= abs_n; + current_buffer_position_ -= abs_n; + return; + } + + // Update position. + abs_n -= current_buffer_position_; + position_ -= current_buffer_position_; + + // Check if we've reached the beginning of the buffers. + if (current_ == begin_) + { + BOOST_ASSERT(abs_n == 0 && "iterator out of bounds"); + current_buffer_position_ = 0; + return; + } + + // Find the previous non-empty buffer. + typename BufferSequence::const_iterator iter = current_; + while (iter != begin_) + { + --iter; + buffer_type buffer = *iter; + std::size_t buffer_size = asio::buffer_size(buffer); + if (buffer_size > 0) + { + current_ = iter; + current_buffer_ = buffer; + current_buffer_position_ = buffer_size; + break; + } + } + } + } + } + + // Determine the distance between two iterators. + std::ptrdiff_t distance_to(const buffers_iterator& other) const + { + return other.position_ - position_; + } + + buffer_type current_buffer_; + std::size_t current_buffer_position_; + typename BufferSequence::const_iterator begin_; + typename BufferSequence::const_iterator current_; + typename BufferSequence::const_iterator end_; + std::size_t position_; +}; + +/// Construct an iterator representing the beginning of the buffers' data. +template +inline buffers_iterator buffers_begin( + const BufferSequence& buffers) +{ + return buffers_iterator::begin(buffers); +} + +/// Construct an iterator representing the end of the buffers' data. +template +inline buffers_iterator buffers_end( + const BufferSequence& buffers) +{ + return buffers_iterator::end(buffers); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_BUFFERS_ITERATOR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/completion_condition.hpp b/src/libs/resiprocate/contrib/asio/asio/completion_condition.hpp new file mode 100644 index 00000000..d4e631d0 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/completion_condition.hpp @@ -0,0 +1,164 @@ +// +// completion_condition.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_COMPLETION_CONDITION_HPP +#define ASIO_COMPLETION_CONDITION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { + +namespace detail { + +// The default maximum number of bytes to transfer in a single operation. +enum { default_max_transfer_size = 65536 }; + +// Adapt result of old-style completion conditions (which had a bool result +// where true indicated that the operation was complete). +inline std::size_t adapt_completion_condition_result(bool result) +{ + return result ? 0 : default_max_transfer_size; +} + +// Adapt result of current completion conditions (which have a size_t result +// where 0 means the operation is complete, and otherwise the result is the +// maximum number of bytes to transfer on the next underlying operation). +inline std::size_t adapt_completion_condition_result(std::size_t result) +{ + return result; +} + +class transfer_all_t +{ +public: + typedef std::size_t result_type; + + template + std::size_t operator()(const Error& err, std::size_t) + { + return !!err ? 0 : default_max_transfer_size; + } +}; + +class transfer_at_least_t +{ +public: + typedef std::size_t result_type; + + explicit transfer_at_least_t(std::size_t minimum) + : minimum_(minimum) + { + } + + template + std::size_t operator()(const Error& err, std::size_t bytes_transferred) + { + return (!!err || bytes_transferred >= minimum_) + ? 0 : default_max_transfer_size; + } + +private: + std::size_t minimum_; +}; + +} // namespace detail + +/** + * @defgroup completion_condition Completion Condition Function Objects + * + * Function objects used for determining when a read or write operation should + * complete. + */ +/*@{*/ + +/// Return a completion condition function object that indicates that a read or +/// write operation should continue until all of the data has been transferred, +/// or until an error occurs. +/** + * This function is used to create an object, of unspecified type, that meets + * CompletionCondition requirements. + * + * @par Example + * Reading until a buffer is full: + * @code + * boost::array buf; + * asio::error_code ec; + * std::size_t n = asio::read( + * sock, asio::buffer(buf), + * asio::transfer_all(), ec); + * if (ec) + * { + * // An error occurred. + * } + * else + * { + * // n == 128 + * } + * @endcode + */ +#if defined(GENERATING_DOCUMENTATION) +unspecified transfer_all(); +#else +inline detail::transfer_all_t transfer_all() +{ + return detail::transfer_all_t(); +} +#endif + +/// Return a completion condition function object that indicates that a read or +/// write operation should continue until a minimum number of bytes has been +/// transferred, or until an error occurs. +/** + * This function is used to create an object, of unspecified type, that meets + * CompletionCondition requirements. + * + * @par Example + * Reading until a buffer is full or contains at least 64 bytes: + * @code + * boost::array buf; + * asio::error_code ec; + * std::size_t n = asio::read( + * sock, asio::buffer(buf), + * asio::transfer_at_least(64), ec); + * if (ec) + * { + * // An error occurred. + * } + * else + * { + * // n >= 64 && n <= 128 + * } + * @endcode + */ +#if defined(GENERATING_DOCUMENTATION) +unspecified transfer_at_least(std::size_t minimum); +#else +inline detail::transfer_at_least_t transfer_at_least(std::size_t minimum) +{ + return detail::transfer_at_least_t(minimum); +} +#endif + +/*@}*/ + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_COMPLETION_CONDITION_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/datagram_socket_service.hpp b/src/libs/resiprocate/contrib/asio/asio/datagram_socket_service.hpp new file mode 100644 index 00000000..7d135eed --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/datagram_socket_service.hpp @@ -0,0 +1,315 @@ +// +// datagram_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DATAGRAM_SOCKET_SERVICE_HPP +#define ASIO_DATAGRAM_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/service_base.hpp" + +#if defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +#else +# include "asio/detail/reactive_socket_service.hpp" +#endif + +namespace asio { + +/// Default service implementation for a datagram socket. +template +class datagram_socket_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_service::service +#else + : public asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_service::id id; +#endif + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + +private: + // The type of the platform-specific implementation. +#if defined(ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#else + typedef detail::reactive_socket_service service_impl_type; +#endif + +public: + /// The type of a datagram socket. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// The native socket type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef typename service_impl_type::native_type native_type; +#endif + + /// Construct a new datagram socket service for the specified io_service. + explicit datagram_socket_service(asio::io_service& io_service) + : asio::detail::service_base< + datagram_socket_service >(io_service), + service_impl_(io_service) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + service_impl_.shutdown_service(); + } + + /// Construct a new datagram socket implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a datagram socket implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + // Open a new datagram socket implementation. + asio::error_code open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + if (protocol.type() == SOCK_DGRAM) + service_impl_.open(impl, protocol, ec); + else + ec = asio::error::invalid_argument; + return ec; + } + + /// Assign an existing native socket to a datagram socket. + asio::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + asio::error_code& ec) + { + return service_impl_.assign(impl, protocol, native_socket, ec); + } + + /// Determine whether the socket is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a datagram socket implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// Get the native socket implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native(impl); + } + + /// Cancel all asynchronous operations associated with the socket. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Determine whether the socket is at the out-of-band data mark. + bool at_mark(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.at_mark(impl, ec); + } + + /// Determine the number of bytes available for reading. + std::size_t available(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.available(impl, ec); + } + + // Bind the datagram socket to the specified local endpoint. + asio::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + return service_impl_.bind(impl, endpoint, ec); + } + + /// Connect the datagram socket to the specified endpoint. + asio::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, asio::error_code& ec) + { + return service_impl_.connect(impl, peer_endpoint, ec); + } + + /// Start an asynchronous connect. + template + void async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, ConnectHandler handler) + { + service_impl_.async_connect(impl, peer_endpoint, handler); + } + + /// Set a socket option. + template + asio::error_code set_option(implementation_type& impl, + const SettableSocketOption& option, asio::error_code& ec) + { + return service_impl_.set_option(impl, option, ec); + } + + /// Get a socket option. + template + asio::error_code get_option(const implementation_type& impl, + GettableSocketOption& option, asio::error_code& ec) const + { + return service_impl_.get_option(impl, option, ec); + } + + /// Perform an IO control command on the socket. + template + asio::error_code io_control(implementation_type& impl, + IoControlCommand& command, asio::error_code& ec) + { + return service_impl_.io_control(impl, command, ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.remote_endpoint(impl, ec); + } + + /// Disable sends or receives on the socket. + asio::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, asio::error_code& ec) + { + return service_impl_.shutdown(impl, what, ec); + } + + /// Send the given data to the peer. + template + std::size_t send(implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return service_impl_.send(impl, buffers, flags, ec); + } + + /// Start an asynchronous send. + template + void async_send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, WriteHandler handler) + { + service_impl_.async_send(impl, buffers, flags, handler); + } + + /// Send a datagram to the specified endpoint. + template + std::size_t send_to(implementation_type& impl, + const ConstBufferSequence& buffers, const endpoint_type& destination, + socket_base::message_flags flags, asio::error_code& ec) + { + return service_impl_.send_to(impl, buffers, destination, flags, ec); + } + + /// Start an asynchronous send. + template + void async_send_to(implementation_type& impl, + const ConstBufferSequence& buffers, const endpoint_type& destination, + socket_base::message_flags flags, WriteHandler handler) + { + service_impl_.async_send_to(impl, buffers, destination, flags, handler); + } + + /// Receive some data from the peer. + template + std::size_t receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return service_impl_.receive(impl, buffers, flags, ec); + } + + /// Start an asynchronous receive. + template + void async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, ReadHandler handler) + { + service_impl_.async_receive(impl, buffers, flags, handler); + } + + /// Receive a datagram with the endpoint of the sender. + template + std::size_t receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, asio::error_code& ec) + { + return service_impl_.receive_from(impl, buffers, sender_endpoint, flags, + ec); + } + + /// Start an asynchronous receive that will get the endpoint of the sender. + template + void async_receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, ReadHandler handler) + { + service_impl_.async_receive_from(impl, buffers, sender_endpoint, flags, + handler); + } + +private: + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DATAGRAM_SOCKET_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/deadline_timer.hpp b/src/libs/resiprocate/contrib/asio/asio/deadline_timer.hpp new file mode 100644 index 00000000..e0905f28 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/deadline_timer.hpp @@ -0,0 +1,37 @@ +// +// deadline_timer.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DEADLINE_TIMER_HPP +#define ASIO_DEADLINE_TIMER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/socket_types.hpp" // Must come before posix_time. + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_deadline_timer.hpp" + +namespace asio { + +/// Typedef for the typical usage of timer. Uses a UTC clock. +typedef basic_deadline_timer deadline_timer; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DEADLINE_TIMER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/deadline_timer_service.hpp b/src/libs/resiprocate/contrib/asio/asio/deadline_timer_service.hpp new file mode 100644 index 00000000..284a690f --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/deadline_timer_service.hpp @@ -0,0 +1,150 @@ +// +// deadline_timer_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DEADLINE_TIMER_SERVICE_HPP +#define ASIO_DEADLINE_TIMER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/io_service.hpp" +#include "asio/time_traits.hpp" +#include "asio/detail/deadline_timer_service.hpp" +#include "asio/detail/service_base.hpp" + +namespace asio { + +/// Default service implementation for a timer. +template > +class deadline_timer_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_service::service +#else + : public asio::detail::service_base< + deadline_timer_service > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_service::id id; +#endif + + /// The time traits type. + typedef TimeTraits traits_type; + + /// The time type. + typedef typename traits_type::time_type time_type; + + /// The duration type. + typedef typename traits_type::duration_type duration_type; + +private: + // The type of the platform-specific implementation. + typedef detail::deadline_timer_service service_impl_type; + +public: + /// The implementation type of the deadline timer. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// Construct a new timer service for the specified io_service. + explicit deadline_timer_service(asio::io_service& io_service) + : asio::detail::service_base< + deadline_timer_service >(io_service), + service_impl_(io_service) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + service_impl_.shutdown_service(); + } + + /// Construct a new timer implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a timer implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Cancel any asynchronous wait operations associated with the timer. + std::size_t cancel(implementation_type& impl, asio::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Get the expiry time for the timer as an absolute time. + time_type expires_at(const implementation_type& impl) const + { + return service_impl_.expires_at(impl); + } + + /// Set the expiry time for the timer as an absolute time. + std::size_t expires_at(implementation_type& impl, + const time_type& expiry_time, asio::error_code& ec) + { + return service_impl_.expires_at(impl, expiry_time, ec); + } + + /// Get the expiry time for the timer relative to now. + duration_type expires_from_now(const implementation_type& impl) const + { + return service_impl_.expires_from_now(impl); + } + + /// Set the expiry time for the timer relative to now. + std::size_t expires_from_now(implementation_type& impl, + const duration_type& expiry_time, asio::error_code& ec) + { + return service_impl_.expires_from_now(impl, expiry_time, ec); + } + + // Perform a blocking wait on the timer. + void wait(implementation_type& impl, asio::error_code& ec) + { + service_impl_.wait(impl, ec); + } + + // Start an asynchronous wait on the timer. + template + void async_wait(implementation_type& impl, WaitHandler handler) + { + service_impl_.async_wait(impl, handler); + } + +private: + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DEADLINE_TIMER_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/base_from_completion_cond.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/base_from_completion_cond.hpp new file mode 100644 index 00000000..90a11f99 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/base_from_completion_cond.hpp @@ -0,0 +1,65 @@ +// +// base_from_completion_cond.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP +#define ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/completion_condition.hpp" + +namespace asio { +namespace detail { + +template +class base_from_completion_cond +{ +protected: + explicit base_from_completion_cond(CompletionCondition completion_condition) + : completion_condition_(completion_condition) + { + } + + std::size_t check(const asio::error_code& ec, + std::size_t total_transferred) + { + return detail::adapt_completion_condition_result( + completion_condition_(ec, total_transferred)); + } + +private: + CompletionCondition completion_condition_; +}; + +template <> +class base_from_completion_cond +{ +protected: + explicit base_from_completion_cond(transfer_all_t) + { + } + + static std::size_t check(const asio::error_code& ec, + std::size_t total_transferred) + { + return transfer_all_t()(ec, total_transferred); + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/bind_handler.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/bind_handler.hpp new file mode 100644 index 00000000..5d9eb004 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/bind_handler.hpp @@ -0,0 +1,349 @@ +// +// bind_handler.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_BIND_HANDLER_HPP +#define ASIO_DETAIL_BIND_HANDLER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" + +namespace asio { +namespace detail { + +template +class binder1 +{ +public: + binder1(const Handler& handler, const Arg1& arg1) + : handler_(handler), + arg1_(arg1) + { + } + + void operator()() + { + handler_(arg1_); + } + + void operator()() const + { + handler_(arg1_); + } + +//private: + Handler handler_; + Arg1 arg1_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder1* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder1* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder1* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline binder1 bind_handler(const Handler& handler, + const Arg1& arg1) +{ + return binder1(handler, arg1); +} + +template +class binder2 +{ +public: + binder2(const Handler& handler, const Arg1& arg1, const Arg2& arg2) + : handler_(handler), + arg1_(arg1), + arg2_(arg2) + { + } + + void operator()() + { + handler_(arg1_, arg2_); + } + + void operator()() const + { + handler_(arg1_, arg2_); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder2* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder2* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder2* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline binder2 bind_handler(const Handler& handler, + const Arg1& arg1, const Arg2& arg2) +{ + return binder2(handler, arg1, arg2); +} + +template +class binder3 +{ +public: + binder3(const Handler& handler, const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3) + : handler_(handler), + arg1_(arg1), + arg2_(arg2), + arg3_(arg3) + { + } + + void operator()() + { + handler_(arg1_, arg2_, arg3_); + } + + void operator()() const + { + handler_(arg1_, arg2_, arg3_); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; + Arg3 arg3_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder3* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder3* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder3* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline binder3 bind_handler(const Handler& handler, + const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) +{ + return binder3(handler, arg1, arg2, arg3); +} + +template +class binder4 +{ +public: + binder4(const Handler& handler, const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4) + : handler_(handler), + arg1_(arg1), + arg2_(arg2), + arg3_(arg3), + arg4_(arg4) + { + } + + void operator()() + { + handler_(arg1_, arg2_, arg3_, arg4_); + } + + void operator()() const + { + handler_(arg1_, arg2_, arg3_, arg4_); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; + Arg3 arg3_; + Arg4 arg4_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder4* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder4* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder4* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline binder4 bind_handler( + const Handler& handler, const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4) +{ + return binder4(handler, arg1, arg2, arg3, + arg4); +} + +template +class binder5 +{ +public: + binder5(const Handler& handler, const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) + : handler_(handler), + arg1_(arg1), + arg2_(arg2), + arg3_(arg3), + arg4_(arg4), + arg5_(arg5) + { + } + + void operator()() + { + handler_(arg1_, arg2_, arg3_, arg4_, arg5_); + } + + void operator()() const + { + handler_(arg1_, arg2_, arg3_, arg4_, arg5_); + } + +//private: + Handler handler_; + Arg1 arg1_; + Arg2 arg2_; + Arg3 arg3_; + Arg4 arg4_; + Arg5 arg5_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + binder5* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + binder5* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + binder5* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +} + +template +inline binder5 bind_handler( + const Handler& handler, const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) +{ + return binder5(handler, arg1, arg2, + arg3, arg4, arg5); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_BIND_HANDLER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/buffer_resize_guard.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/buffer_resize_guard.hpp new file mode 100644 index 00000000..368de323 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/buffer_resize_guard.hpp @@ -0,0 +1,70 @@ +// +// buffer_resize_guard.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP +#define ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +// Helper class to manage buffer resizing in an exception safe way. +template +class buffer_resize_guard +{ +public: + // Constructor. + buffer_resize_guard(Buffer& buffer) + : buffer_(buffer), + old_size_(buffer.size()) + { + } + + // Destructor rolls back the buffer resize unless commit was called. + ~buffer_resize_guard() + { + if (old_size_ + != std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION()) + { + buffer_.resize(old_size_); + } + } + + // Commit the resize transaction. + void commit() + { + old_size_ + = std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION(); + } + +private: + // The buffer being managed. + Buffer& buffer_; + + // The size of the buffer at the time the guard was constructed. + size_t old_size_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/buffer_sequence_adapter.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/buffer_sequence_adapter.hpp new file mode 100644 index 00000000..6269d6ae --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/buffer_sequence_adapter.hpp @@ -0,0 +1,252 @@ +// +// buffer_sequence_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP +#define ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/buffer.hpp" + +namespace asio { +namespace detail { + +class buffer_sequence_adapter_base +{ +protected: +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + typedef WSABUF native_buffer_type; + + static void init_native_buffer(WSABUF& buf, + const asio::mutable_buffer& buffer) + { + buf.buf = asio::buffer_cast(buffer); + buf.len = asio::buffer_size(buffer); + } + + static void init_native_buffer(WSABUF& buf, + const asio::const_buffer& buffer) + { + buf.buf = const_cast(asio::buffer_cast(buffer)); + buf.len = asio::buffer_size(buffer); + } +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + typedef iovec native_buffer_type; + + static void init_iov_base(void*& base, void* addr) + { + base = addr; + } + + template + static void init_iov_base(T& base, void* addr) + { + base = static_cast(addr); + } + + static void init_native_buffer(iovec& iov, + const asio::mutable_buffer& buffer) + { + init_iov_base(iov.iov_base, asio::buffer_cast(buffer)); + iov.iov_len = asio::buffer_size(buffer); + } + + static void init_native_buffer(iovec& iov, + const asio::const_buffer& buffer) + { + init_iov_base(iov.iov_base, const_cast( + asio::buffer_cast(buffer))); + iov.iov_len = asio::buffer_size(buffer); + } +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +}; + +// Helper class to translate buffers into the native buffer representation. +template +class buffer_sequence_adapter + : buffer_sequence_adapter_base +{ +public: + explicit buffer_sequence_adapter(const Buffers& buffers) + : count_(0), total_buffer_size_(0) + { + typename Buffers::const_iterator iter = buffers.begin(); + typename Buffers::const_iterator end = buffers.end(); + for (; iter != end && count_ < max_buffers; ++iter, ++count_) + { + Buffer buffer(*iter); + init_native_buffer(buffers_[count_], buffer); + total_buffer_size_ += asio::buffer_size(buffer); + } + } + + native_buffer_type* buffers() + { + return buffers_; + } + + std::size_t count() const + { + return count_; + } + + bool all_empty() const + { + return total_buffer_size_ == 0; + } + + static bool all_empty(const Buffers& buffers) + { + typename Buffers::const_iterator iter = buffers.begin(); + typename Buffers::const_iterator end = buffers.end(); + std::size_t i = 0; + for (; iter != end && i < max_buffers; ++iter, ++i) + if (asio::buffer_size(Buffer(*iter)) > 0) + return false; + return true; + } + + static void validate(const Buffers& buffers) + { + typename Buffers::const_iterator iter = buffers.begin(); + typename Buffers::const_iterator end = buffers.end(); + for (; iter != end; ++iter) + { + Buffer buffer(*iter); + asio::buffer_cast(buffer); + } + } + + static Buffer first(const Buffers& buffers) + { + typename Buffers::const_iterator iter = buffers.begin(); + typename Buffers::const_iterator end = buffers.end(); + for (; iter != end; ++iter) + { + Buffer buffer(*iter); + if (asio::buffer_size(buffer) != 0) + return buffer; + } + return Buffer(); + } + +private: + // The maximum number of buffers to support in a single operation. + enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len }; + + native_buffer_type buffers_[max_buffers]; + std::size_t count_; + std::size_t total_buffer_size_; +}; + +template +class buffer_sequence_adapter + : buffer_sequence_adapter_base +{ +public: + explicit buffer_sequence_adapter( + const asio::mutable_buffers_1& buffers) + { + init_native_buffer(buffer_, buffers); + total_buffer_size_ = asio::buffer_size(buffers); + } + + native_buffer_type* buffers() + { + return &buffer_; + } + + std::size_t count() const + { + return 1; + } + + bool all_empty() const + { + return total_buffer_size_ == 0; + } + + static bool all_empty(const asio::mutable_buffers_1& buffers) + { + return asio::buffer_size(buffers) == 0; + } + + static void validate(const asio::mutable_buffers_1& buffers) + { + asio::buffer_cast(buffers); + } + + static Buffer first(const asio::mutable_buffers_1& buffers) + { + return Buffer(buffers); + } + +private: + native_buffer_type buffer_; + std::size_t total_buffer_size_; +}; + +template +class buffer_sequence_adapter + : buffer_sequence_adapter_base +{ +public: + explicit buffer_sequence_adapter( + const asio::const_buffers_1& buffers) + { + init_native_buffer(buffer_, buffers); + total_buffer_size_ = asio::buffer_size(buffers); + } + + native_buffer_type* buffers() + { + return &buffer_; + } + + std::size_t count() const + { + return 1; + } + + bool all_empty() const + { + return total_buffer_size_ == 0; + } + + static bool all_empty(const asio::const_buffers_1& buffers) + { + return asio::buffer_size(buffers) == 0; + } + + static void validate(const asio::const_buffers_1& buffers) + { + asio::buffer_cast(buffers); + } + + static Buffer first(const asio::const_buffers_1& buffers) + { + return Buffer(buffers); + } + +private: + native_buffer_type buffer_; + std::size_t total_buffer_size_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/buffered_stream_storage.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/buffered_stream_storage.hpp new file mode 100644 index 00000000..51f6556f --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/buffered_stream_storage.hpp @@ -0,0 +1,127 @@ +// +// buffered_stream_storage.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP +#define ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +class buffered_stream_storage +{ +public: + // The type of the bytes stored in the buffer. + typedef unsigned char byte_type; + + // The type used for offsets into the buffer. + typedef std::size_t size_type; + + // Constructor. + explicit buffered_stream_storage(std::size_t capacity) + : begin_offset_(0), + end_offset_(0), + buffer_(capacity) + { + } + + /// Clear the buffer. + void clear() + { + begin_offset_ = 0; + end_offset_ = 0; + } + + // Return a pointer to the beginning of the unread data. + byte_type* data() + { + return &buffer_[0] + begin_offset_; + } + + // Return a pointer to the beginning of the unread data. + const byte_type* data() const + { + return &buffer_[0] + begin_offset_; + } + + // Is there no unread data in the buffer. + bool empty() const + { + return begin_offset_ == end_offset_; + } + + // Return the amount of unread data the is in the buffer. + size_type size() const + { + return end_offset_ - begin_offset_; + } + + // Resize the buffer to the specified length. + void resize(size_type length) + { + assert(length <= capacity()); + if (begin_offset_ + length <= capacity()) + { + end_offset_ = begin_offset_ + length; + } + else + { + using namespace std; // For memmove. + memmove(&buffer_[0], &buffer_[0] + begin_offset_, size()); + end_offset_ = length; + begin_offset_ = 0; + } + } + + // Return the maximum size for data in the buffer. + size_type capacity() const + { + return buffer_.size(); + } + + // Consume multiple bytes from the beginning of the buffer. + void consume(size_type count) + { + assert(begin_offset_ + count <= end_offset_); + begin_offset_ += count; + if (empty()) + clear(); + } + +private: + // The offset to the beginning of the unread data. + size_type begin_offset_; + + // The offset to the end of the unread data. + size_type end_offset_; + + // The data in the buffer. + std::vector buffer_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/call_stack.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/call_stack.hpp new file mode 100644 index 00000000..0e9ddafa --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/call_stack.hpp @@ -0,0 +1,90 @@ +// +// call_stack.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_CALL_STACK_HPP +#define ASIO_DETAIL_CALL_STACK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/tss_ptr.hpp" + +namespace asio { +namespace detail { + +// Helper class to determine whether or not the current thread is inside an +// invocation of io_service::run() for a specified io_service object. +template +class call_stack +{ +public: + // Context class automatically pushes an owner on to the stack. + class context + : private noncopyable + { + public: + // Push the owner on to the stack. + explicit context(Owner* d) + : owner_(d), + next_(call_stack::top_) + { + call_stack::top_ = this; + } + + // Pop the owner from the stack. + ~context() + { + call_stack::top_ = next_; + } + + private: + friend class call_stack; + + // The owner associated with the context. + Owner* owner_; + + // The next element in the stack. + context* next_; + }; + + friend class context; + + // Determine whether the specified owner is on the stack. + static bool contains(Owner* d) + { + context* elem = top_; + while (elem) + { + if (elem->owner_ == d) + return true; + elem = elem->next_; + } + return false; + } + +private: + // The top of the stack of calls for the current thread. + static tss_ptr top_; +}; + +template +tss_ptr::context> +call_stack::top_; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_CALL_STACK_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/completion_handler.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/completion_handler.hpp new file mode 100644 index 00000000..16167dfb --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/completion_handler.hpp @@ -0,0 +1,71 @@ +// +// completion_handler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_COMPLETION_HANDLER_HPP +#define ASIO_DETAIL_COMPLETION_HANDLER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/operation.hpp" + +namespace asio { +namespace detail { + +template +class completion_handler : public operation +{ +public: + completion_handler(Handler h) + : operation(&completion_handler::do_complete), + handler_(h) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + completion_handler* h(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(h->handler_, h); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + Handler handler(h->handler_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_COMPLETION_HANDLER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/const_buffers_iterator.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/const_buffers_iterator.hpp new file mode 100644 index 00000000..6ac3ac59 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/const_buffers_iterator.hpp @@ -0,0 +1,151 @@ +// +// const_buffers_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP +#define ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffer.hpp" + +namespace asio { +namespace detail { + +// A proxy iterator for a sub-range in a list of buffers. +template +class const_buffers_iterator + : public boost::iterator_facade, + const char, boost::bidirectional_traversal_tag> +{ +public: + // Default constructor creates an iterator in an undefined state. + const_buffers_iterator() + { + } + + // Create an iterator for the specified position. + const_buffers_iterator(const ConstBufferSequence& buffers, + std::size_t position) + : begin_(buffers.begin()), + current_(buffers.begin()), + end_(buffers.end()), + position_(0) + { + while (current_ != end_) + { + current_buffer_ = *current_; + std::size_t buffer_size = asio::buffer_size(current_buffer_); + if (position - position_ < buffer_size) + { + current_buffer_position_ = position - position_; + position_ = position; + return; + } + position_ += buffer_size; + ++current_; + } + current_buffer_ = asio::const_buffer(); + current_buffer_position_ = 0; + } + + std::size_t position() const + { + return position_; + } + +private: + friend class boost::iterator_core_access; + + void increment() + { + if (current_ == end_) + return; + + ++position_; + + ++current_buffer_position_; + if (current_buffer_position_ != asio::buffer_size(current_buffer_)) + return; + + ++current_; + current_buffer_position_ = 0; + while (current_ != end_) + { + current_buffer_ = *current_; + if (asio::buffer_size(current_buffer_) > 0) + return; + ++current_; + } + } + + void decrement() + { + if (position_ == 0) + return; + + --position_; + + if (current_buffer_position_ != 0) + { + --current_buffer_position_; + return; + } + + typename ConstBufferSequence::const_iterator iter = current_; + while (iter != begin_) + { + --iter; + asio::const_buffer buffer = *iter; + std::size_t buffer_size = asio::buffer_size(buffer); + if (buffer_size > 0) + { + current_ = iter; + current_buffer_ = buffer; + current_buffer_position_ = buffer_size - 1; + return; + } + } + } + + bool equal(const const_buffers_iterator& other) const + { + return position_ == other.position_; + } + + const char& dereference() const + { + return asio::buffer_cast( + current_buffer_)[current_buffer_position_]; + } + + asio::const_buffer current_buffer_; + std::size_t current_buffer_position_; + typename ConstBufferSequence::const_iterator begin_; + typename ConstBufferSequence::const_iterator current_; + typename ConstBufferSequence::const_iterator end_; + std::size_t position_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/consuming_buffers.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/consuming_buffers.hpp new file mode 100644 index 00000000..80b6a8e8 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/consuming_buffers.hpp @@ -0,0 +1,280 @@ +// +// consuming_buffers.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_CONSUMING_BUFFERS_HPP +#define ASIO_DETAIL_CONSUMING_BUFFERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffer.hpp" + +namespace asio { +namespace detail { + +// A proxy iterator for a sub-range in a list of buffers. +template +class consuming_buffers_iterator + : public boost::iterator +{ +public: + // Default constructor creates an end iterator. + consuming_buffers_iterator() + : at_end_(true) + { + } + + // Construct with a buffer for the first entry and an iterator + // range for the remaining entries. + consuming_buffers_iterator(bool at_end, const Buffer& first, + Buffer_Iterator begin_remainder, Buffer_Iterator end_remainder, + std::size_t max_size) + : at_end_(max_size > 0 ? at_end : true), + first_(buffer(first, max_size)), + begin_remainder_(begin_remainder), + end_remainder_(end_remainder), + offset_(0), + max_size_(max_size) + { + } + + // Dereference an iterator. + const Buffer& operator*() const + { + return dereference(); + } + + // Dereference an iterator. + const Buffer* operator->() const + { + return &dereference(); + } + + // Increment operator (prefix). + consuming_buffers_iterator& operator++() + { + increment(); + return *this; + } + + // Increment operator (postfix). + consuming_buffers_iterator operator++(int) + { + consuming_buffers_iterator tmp(*this); + ++*this; + return tmp; + } + + // Test two iterators for equality. + friend bool operator==(const consuming_buffers_iterator& a, + const consuming_buffers_iterator& b) + { + return a.equal(b); + } + + // Test two iterators for inequality. + friend bool operator!=(const consuming_buffers_iterator& a, + const consuming_buffers_iterator& b) + { + return !a.equal(b); + } + +private: + void increment() + { + if (!at_end_) + { + if (begin_remainder_ == end_remainder_ + || offset_ + buffer_size(first_) >= max_size_) + { + at_end_ = true; + } + else + { + offset_ += buffer_size(first_); + first_ = buffer(*begin_remainder_++, max_size_ - offset_); + } + } + } + + bool equal(const consuming_buffers_iterator& other) const + { + if (at_end_ && other.at_end_) + return true; + return !at_end_ && !other.at_end_ + && buffer_cast(first_) + == buffer_cast(other.first_) + && buffer_size(first_) == buffer_size(other.first_) + && begin_remainder_ == other.begin_remainder_ + && end_remainder_ == other.end_remainder_; + } + + const Buffer& dereference() const + { + return first_; + } + + bool at_end_; + Buffer first_; + Buffer_Iterator begin_remainder_; + Buffer_Iterator end_remainder_; + std::size_t offset_; + std::size_t max_size_; +}; + +// A proxy for a sub-range in a list of buffers. +template +class consuming_buffers +{ +public: + // The type for each element in the list of buffers. + typedef Buffer value_type; + + // A forward-only iterator type that may be used to read elements. + typedef consuming_buffers_iterator + const_iterator; + + // Construct to represent the entire list of buffers. + consuming_buffers(const Buffers& buffers) + : buffers_(buffers), + at_end_(buffers_.begin() == buffers_.end()), + first_(*buffers_.begin()), + begin_remainder_(buffers_.begin()), + max_size_((std::numeric_limits::max)()) + { + if (!at_end_) + ++begin_remainder_; + } + + // Copy constructor. + consuming_buffers(const consuming_buffers& other) + : buffers_(other.buffers_), + at_end_(other.at_end_), + first_(other.first_), + begin_remainder_(buffers_.begin()), + max_size_(other.max_size_) + { + typename Buffers::const_iterator first = other.buffers_.begin(); + typename Buffers::const_iterator second = other.begin_remainder_; + std::advance(begin_remainder_, std::distance(first, second)); + } + + // Assignment operator. + consuming_buffers& operator=(const consuming_buffers& other) + { + buffers_ = other.buffers_; + at_end_ = other.at_end_; + first_ = other.first_; + begin_remainder_ = buffers_.begin(); + typename Buffers::const_iterator first = other.buffers_.begin(); + typename Buffers::const_iterator second = other.begin_remainder_; + std::advance(begin_remainder_, std::distance(first, second)); + max_size_ = other.max_size_; + return *this; + } + + // Get a forward-only iterator to the first element. + const_iterator begin() const + { + return const_iterator(at_end_, first_, + begin_remainder_, buffers_.end(), max_size_); + } + + // Get a forward-only iterator for one past the last element. + const_iterator end() const + { + return const_iterator(); + } + + // Set the maximum size for a single transfer. + void prepare(std::size_t max_size) + { + max_size_ = max_size; + } + + // Consume the specified number of bytes from the buffers. + void consume(std::size_t size) + { + // Remove buffers from the start until the specified size is reached. + while (size > 0 && !at_end_) + { + if (buffer_size(first_) <= size) + { + size -= buffer_size(first_); + if (begin_remainder_ == buffers_.end()) + at_end_ = true; + else + first_ = *begin_remainder_++; + } + else + { + first_ = first_ + size; + size = 0; + } + } + + // Remove any more empty buffers at the start. + while (!at_end_ && buffer_size(first_) == 0) + { + if (begin_remainder_ == buffers_.end()) + at_end_ = true; + else + first_ = *begin_remainder_++; + } + } + +private: + Buffers buffers_; + bool at_end_; + Buffer first_; + typename Buffers::const_iterator begin_remainder_; + std::size_t max_size_; +}; + +// Specialisation for null_buffers to ensure that the null_buffers type is +// always passed through to the underlying read or write operation. +template +class consuming_buffers + : public asio::null_buffers +{ +public: + consuming_buffers(const asio::null_buffers&) + { + // No-op. + } + + void prepare(std::size_t) + { + // No-op. + } + + void consume(std::size_t) + { + // No-op. + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_CONSUMING_BUFFERS_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/deadline_timer_service.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/deadline_timer_service.hpp new file mode 100644 index 00000000..6daf7acb --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/deadline_timer_service.hpp @@ -0,0 +1,222 @@ +// +// deadline_timer_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP +#define ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/timer_op.hpp" +#include "asio/detail/timer_queue.hpp" +#include "asio/detail/timer_scheduler.hpp" + +namespace asio { +namespace detail { + +template +class deadline_timer_service +{ +public: + // The time type. + typedef typename Time_Traits::time_type time_type; + + // The duration type. + typedef typename Time_Traits::duration_type duration_type; + + // The implementation type of the timer. This type is dependent on the + // underlying implementation of the timer service. + struct implementation_type + : private asio::detail::noncopyable + { + time_type expiry; + bool might_have_pending_waits; + }; + + // Constructor. + deadline_timer_service(asio::io_service& io_service) + : scheduler_(asio::use_service(io_service)) + { + scheduler_.init_task(); + scheduler_.add_timer_queue(timer_queue_); + } + + // Destructor. + ~deadline_timer_service() + { + scheduler_.remove_timer_queue(timer_queue_); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + // Construct a new timer implementation. + void construct(implementation_type& impl) + { + impl.expiry = time_type(); + impl.might_have_pending_waits = false; + } + + // Destroy a timer implementation. + void destroy(implementation_type& impl) + { + asio::error_code ec; + cancel(impl, ec); + } + + // Cancel any asynchronous wait operations associated with the timer. + std::size_t cancel(implementation_type& impl, asio::error_code& ec) + { + if (!impl.might_have_pending_waits) + { + ec = asio::error_code(); + return 0; + } + std::size_t count = scheduler_.cancel_timer(timer_queue_, &impl); + impl.might_have_pending_waits = false; + ec = asio::error_code(); + return count; + } + + // Get the expiry time for the timer as an absolute time. + time_type expires_at(const implementation_type& impl) const + { + return impl.expiry; + } + + // Set the expiry time for the timer as an absolute time. + std::size_t expires_at(implementation_type& impl, + const time_type& expiry_time, asio::error_code& ec) + { + std::size_t count = cancel(impl, ec); + impl.expiry = expiry_time; + ec = asio::error_code(); + return count; + } + + // Get the expiry time for the timer relative to now. + duration_type expires_from_now(const implementation_type& impl) const + { + return Time_Traits::subtract(expires_at(impl), Time_Traits::now()); + } + + // Set the expiry time for the timer relative to now. + std::size_t expires_from_now(implementation_type& impl, + const duration_type& expiry_time, asio::error_code& ec) + { + return expires_at(impl, + Time_Traits::add(Time_Traits::now(), expiry_time), ec); + } + + // Perform a blocking wait on the timer. + void wait(implementation_type& impl, asio::error_code& ec) + { + time_type now = Time_Traits::now(); + while (Time_Traits::less_than(now, impl.expiry)) + { + boost::posix_time::time_duration timeout = + Time_Traits::to_posix_duration(Time_Traits::subtract(impl.expiry, now)); + ::timeval tv; + tv.tv_sec = timeout.total_seconds(); + tv.tv_usec = timeout.total_microseconds() % 1000000; + asio::error_code ec; + socket_ops::select(0, 0, 0, 0, &tv, ec); + now = Time_Traits::now(); + } + ec = asio::error_code(); + } + + template + class wait_handler : public timer_op + { + public: + wait_handler(Handler handler) + : timer_op(&wait_handler::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + wait_handler* h(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(h->handler_, h); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder1 + handler(h->handler_, h->ec_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + Handler handler_; + }; + + // Start an asynchronous wait on the timer. + template + void async_wait(implementation_type& impl, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef wait_handler value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + impl.might_have_pending_waits = true; + + scheduler_.schedule_timer(timer_queue_, impl.expiry, ptr.get(), &impl); + ptr.release(); + } + +private: + // The queue of timers. + timer_queue timer_queue_; + + // The object that schedules and executes timers. Usually a reactor. + timer_scheduler& scheduler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/descriptor_ops.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/descriptor_ops.hpp new file mode 100644 index 00000000..ea3731e7 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/descriptor_ops.hpp @@ -0,0 +1,176 @@ +// +// descriptor_ops.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_DESCRIPTOR_OPS_HPP +#define ASIO_DETAIL_DESCRIPTOR_OPS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/detail/socket_types.hpp" + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +namespace asio { +namespace detail { +namespace descriptor_ops { + +inline void clear_error(asio::error_code& ec) +{ + errno = 0; + ec = asio::error_code(); +} + +template +inline ReturnType error_wrapper(ReturnType return_value, + asio::error_code& ec) +{ + ec = asio::error_code(errno, + asio::error::get_system_category()); + return return_value; +} + +inline int open(const char* path, int flags, asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::open(path, flags), ec); + if (result >= 0) + clear_error(ec); + return result; +} + +inline int close(int d, asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::close(d), ec); + if (result == 0) + clear_error(ec); + return result; +} + +inline void init_buf_iov_base(void*& base, void* addr) +{ + base = addr; +} + +template +inline void init_buf_iov_base(T& base, void* addr) +{ + base = static_cast(addr); +} + +typedef iovec buf; + +inline void init_buf(buf& b, void* data, size_t size) +{ + init_buf_iov_base(b.iov_base, data); + b.iov_len = size; +} + +inline void init_buf(buf& b, const void* data, size_t size) +{ + init_buf_iov_base(b.iov_base, const_cast(data)); + b.iov_len = size; +} + +inline int scatter_read(int d, buf* bufs, size_t count, + asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::readv(d, bufs, static_cast(count)), ec); + if (result >= 0) + clear_error(ec); + return result; +} + +inline int gather_write(int d, const buf* bufs, size_t count, + asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::writev(d, bufs, static_cast(count)), ec); + if (result >= 0) + clear_error(ec); + return result; +} + +inline int ioctl(int d, long cmd, ioctl_arg_type* arg, + asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::ioctl(d, cmd, arg), ec); + if (result >= 0) + clear_error(ec); + return result; +} + +inline int fcntl(int d, long cmd, asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::fcntl(d, cmd), ec); + if (result != -1) + clear_error(ec); + return result; +} + +inline int fcntl(int d, long cmd, long arg, asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::fcntl(d, cmd, arg), ec); + if (result != -1) + clear_error(ec); + return result; +} + +inline int poll_read(int d, asio::error_code& ec) +{ + clear_error(ec); + pollfd fds; + fds.fd = d; + fds.events = POLLIN; + fds.revents = 0; + clear_error(ec); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + clear_error(ec); + return result; +} + +inline int poll_write(int d, asio::error_code& ec) +{ + clear_error(ec); + pollfd fds; + fds.fd = d; + fds.events = POLLOUT; + fds.revents = 0; + clear_error(ec); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + clear_error(ec); + return result; +} + +} // namespace descriptor_ops +} // namespace detail +} // namespace asio + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_DESCRIPTOR_OPS_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/dev_poll_reactor.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/dev_poll_reactor.hpp new file mode 100644 index 00000000..1367b719 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/dev_poll_reactor.hpp @@ -0,0 +1,453 @@ +// +// dev_poll_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_DEV_POLL_REACTOR_HPP +#define ASIO_DETAIL_DEV_POLL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/dev_poll_reactor_fwd.hpp" + +#if defined(ASIO_HAS_DEV_POLL) + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/hash_map.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/reactor_op_queue.hpp" +#include "asio/detail/select_interrupter.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/timer_op.hpp" +#include "asio/detail/timer_queue_base.hpp" +#include "asio/detail/timer_queue_fwd.hpp" +#include "asio/detail/timer_queue_set.hpp" + +namespace asio { +namespace detail { + +class dev_poll_reactor + : public asio::detail::service_base +{ +public: + enum { read_op = 0, write_op = 1, + connect_op = 1, except_op = 2, max_ops = 3 }; + + // Per-descriptor data. + struct per_descriptor_data + { + }; + + // Constructor. + dev_poll_reactor(asio::io_service& io_service) + : asio::detail::service_base(io_service), + io_service_(use_service(io_service)), + mutex_(), + dev_poll_fd_(do_dev_poll_create()), + interrupter_(), + shutdown_(false) + { + // Add the interrupter's descriptor to /dev/poll. + ::pollfd ev = { 0 }; + ev.fd = interrupter_.read_descriptor(); + ev.events = POLLIN | POLLERR; + ev.revents = 0; + ::write(dev_poll_fd_, &ev, sizeof(ev)); + } + + // Destructor. + ~dev_poll_reactor() + { + shutdown_service(); + ::close(dev_poll_fd_); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + asio::detail::mutex::scoped_lock lock(mutex_); + shutdown_ = true; + lock.unlock(); + + op_queue ops; + + for (int i = 0; i < max_ops; ++i) + op_queue_[i].get_all_operations(ops); + + timer_queues_.get_all_timers(ops); + } + + // Initialise the task. + void init_task() + { + io_service_.init_task(); + } + + // Register a socket with the reactor. Returns 0 on success, system error + // code on failure. + int register_descriptor(socket_type, per_descriptor_data&) + { + return 0; + } + + // Start a new operation. The reactor operation will be performed when the + // given descriptor is flagged as ready, or an error has occurred. + void start_op(int op_type, socket_type descriptor, + per_descriptor_data&, reactor_op* op, bool allow_speculative) + { + asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + return; + + if (allow_speculative) + { + if (op_type != read_op || !op_queue_[except_op].has_operation(descriptor)) + { + if (!op_queue_[op_type].has_operation(descriptor)) + { + if (op->perform()) + { + lock.unlock(); + io_service_.post_immediate_completion(op); + return; + } + } + } + } + + bool first = op_queue_[op_type].enqueue_operation(descriptor, op); + io_service_.work_started(); + if (first) + { + ::pollfd& ev = add_pending_event_change(descriptor); + ev.events = POLLERR | POLLHUP; + if (op_type == read_op + || op_queue_[read_op].has_operation(descriptor)) + ev.events |= POLLIN; + if (op_type == write_op + || op_queue_[write_op].has_operation(descriptor)) + ev.events |= POLLOUT; + if (op_type == except_op + || op_queue_[except_op].has_operation(descriptor)) + ev.events |= POLLPRI; + interrupter_.interrupt(); + } + } + + // Cancel all operations associated with the given descriptor. The + // handlers associated with the descriptor will be invoked with the + // operation_aborted error. + void cancel_ops(socket_type descriptor, per_descriptor_data&) + { + asio::detail::mutex::scoped_lock lock(mutex_); + cancel_ops_unlocked(descriptor, asio::error::operation_aborted); + } + + // Cancel any operations that are running against the descriptor and remove + // its registration from the reactor. + void close_descriptor(socket_type descriptor, per_descriptor_data&) + { + asio::detail::mutex::scoped_lock lock(mutex_); + + // Remove the descriptor from /dev/poll. + ::pollfd& ev = add_pending_event_change(descriptor); + ev.events = POLLREMOVE; + interrupter_.interrupt(); + + // Cancel any outstanding operations associated with the descriptor. + cancel_ops_unlocked(descriptor, asio::error::operation_aborted); + } + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& timer_queue) + { + asio::detail::mutex::scoped_lock lock(mutex_); + timer_queues_.insert(&timer_queue); + } + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& timer_queue) + { + asio::detail::mutex::scoped_lock lock(mutex_); + timer_queues_.erase(&timer_queue); + } + + // Schedule a new operation in the given timer queue to expire at the + // specified absolute time. + template + void schedule_timer(timer_queue& timer_queue, + const typename Time_Traits::time_type& time, timer_op* op, void* token) + { + asio::detail::mutex::scoped_lock lock(mutex_); + if (!shutdown_) + { + bool earliest = timer_queue.enqueue_timer(time, op, token); + io_service_.work_started(); + if (earliest) + interrupter_.interrupt(); + } + } + + // Cancel the timer operations associated with the given token. Returns the + // number of operations that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& timer_queue, void* token) + { + asio::detail::mutex::scoped_lock lock(mutex_); + op_queue ops; + std::size_t n = timer_queue.cancel_timer(token, ops); + lock.unlock(); + io_service_.post_deferred_completions(ops); + return n; + } + + // Run /dev/poll once until interrupted or events are ready to be dispatched. + void run(bool block, op_queue& ops) + { + asio::detail::mutex::scoped_lock lock(mutex_); + + // We can return immediately if there's no work to do and the reactor is + // not supposed to block. + if (!block && op_queue_[read_op].empty() && op_queue_[write_op].empty() + && op_queue_[except_op].empty() && timer_queues_.all_empty()) + return; + + // Write the pending event registration changes to the /dev/poll descriptor. + std::size_t events_size = sizeof(::pollfd) * pending_event_changes_.size(); + if (events_size > 0) + { + errno = 0; + int result = ::write(dev_poll_fd_, + &pending_event_changes_[0], events_size); + if (result != static_cast(events_size)) + { + asio::error_code ec = asio::error_code( + errno, asio::error::get_system_category()); + for (std::size_t i = 0; i < pending_event_changes_.size(); ++i) + { + int descriptor = pending_event_changes_[i].fd; + for (int j = 0; j < max_ops; ++j) + op_queue_[j].cancel_operations(descriptor, ops, ec); + } + } + pending_event_changes_.clear(); + pending_event_change_index_.clear(); + } + + int timeout = block ? get_timeout() : 0; + lock.unlock(); + + // Block on the /dev/poll descriptor. + ::pollfd events[128] = { { 0 } }; + ::dvpoll dp = { 0 }; + dp.dp_fds = events; + dp.dp_nfds = 128; + dp.dp_timeout = timeout; + int num_events = ::ioctl(dev_poll_fd_, DP_POLL, &dp); + + lock.lock(); + + // Dispatch the waiting events. + for (int i = 0; i < num_events; ++i) + { + int descriptor = events[i].fd; + if (descriptor == interrupter_.read_descriptor()) + { + interrupter_.reset(); + } + else + { + bool more_reads = false; + bool more_writes = false; + bool more_except = false; + + // Exception operations must be processed first to ensure that any + // out-of-band data is read before normal data. + if (events[i].events & (POLLPRI | POLLERR | POLLHUP)) + more_except = + op_queue_[except_op].perform_operations(descriptor, ops); + else + more_except = op_queue_[except_op].has_operation(descriptor); + + if (events[i].events & (POLLIN | POLLERR | POLLHUP)) + more_reads = op_queue_[read_op].perform_operations(descriptor, ops); + else + more_reads = op_queue_[read_op].has_operation(descriptor); + + if (events[i].events & (POLLOUT | POLLERR | POLLHUP)) + more_writes = op_queue_[write_op].perform_operations(descriptor, ops); + else + more_writes = op_queue_[write_op].has_operation(descriptor); + + if ((events[i].events & (POLLERR | POLLHUP)) != 0 + && !more_except && !more_reads && !more_writes) + { + // If we have an event and no operations associated with the + // descriptor then we need to delete the descriptor from /dev/poll. + // The poll operation can produce POLLHUP or POLLERR events when there + // is no operation pending, so if we do not remove the descriptor we + // can end up in a tight polling loop. + ::pollfd ev = { 0 }; + ev.fd = descriptor; + ev.events = POLLREMOVE; + ev.revents = 0; + ::write(dev_poll_fd_, &ev, sizeof(ev)); + } + else + { + ::pollfd ev = { 0 }; + ev.fd = descriptor; + ev.events = POLLERR | POLLHUP; + if (more_reads) + ev.events |= POLLIN; + if (more_writes) + ev.events |= POLLOUT; + if (more_except) + ev.events |= POLLPRI; + ev.revents = 0; + int result = ::write(dev_poll_fd_, &ev, sizeof(ev)); + if (result != sizeof(ev)) + { + asio::error_code ec(errno, + asio::error::get_system_category()); + for (int j = 0; j < max_ops; ++j) + op_queue_[j].cancel_operations(descriptor, ops, ec); + } + } + } + } + timer_queues_.get_ready_timers(ops); + } + + // Interrupt the select loop. + void interrupt() + { + interrupter_.interrupt(); + } + +private: + // Create the /dev/poll file descriptor. Throws an exception if the descriptor + // cannot be created. + static int do_dev_poll_create() + { + int fd = ::open("/dev/poll", O_RDWR); + if (fd == -1) + { + boost::throw_exception( + asio::system_error( + asio::error_code(errno, + asio::error::get_system_category()), + "/dev/poll")); + } + return fd; + } + + // Get the timeout value for the /dev/poll DP_POLL operation. The timeout + // value is returned as a number of milliseconds. A return value of -1 + // indicates that the poll should block indefinitely. + int get_timeout() + { + // By default we will wait no longer than 5 minutes. This will ensure that + // any changes to the system clock are detected after no longer than this. + return timer_queues_.wait_duration_msec(5 * 60 * 1000); + } + + // Cancel all operations associated with the given descriptor. The do_cancel + // function of the handler objects will be invoked. This function does not + // acquire the dev_poll_reactor's mutex. + void cancel_ops_unlocked(socket_type descriptor, + const asio::error_code& ec) + { + bool need_interrupt = false; + op_queue ops; + for (int i = 0; i < max_ops; ++i) + need_interrupt = op_queue_[i].cancel_operations( + descriptor, ops, ec) || need_interrupt; + io_service_.post_deferred_completions(ops); + if (need_interrupt) + interrupter_.interrupt(); + } + + // Add a pending event entry for the given descriptor. + ::pollfd& add_pending_event_change(int descriptor) + { + hash_map::iterator iter + = pending_event_change_index_.find(descriptor); + if (iter == pending_event_change_index_.end()) + { + std::size_t index = pending_event_changes_.size(); + pending_event_changes_.reserve(pending_event_changes_.size() + 1); + pending_event_change_index_.insert(std::make_pair(descriptor, index)); + pending_event_changes_.push_back(::pollfd()); + pending_event_changes_[index].fd = descriptor; + pending_event_changes_[index].revents = 0; + return pending_event_changes_[index]; + } + else + { + return pending_event_changes_[iter->second]; + } + } + + // The io_service implementation used to post completions. + io_service_impl& io_service_; + + // Mutex to protect access to internal data. + asio::detail::mutex mutex_; + + // The /dev/poll file descriptor. + int dev_poll_fd_; + + // Vector of /dev/poll events waiting to be written to the descriptor. + std::vector< ::pollfd> pending_event_changes_; + + // Hash map to associate a descriptor with a pending event change index. + hash_map pending_event_change_index_; + + // The interrupter is used to break a blocking DP_POLL operation. + select_interrupter interrupter_; + + // The queues of read, write and except operations. + reactor_op_queue op_queue_[max_ops]; + + // The timer queues. + timer_queue_set timer_queues_; + + // Whether the service has been shut down. + bool shutdown_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(ASIO_HAS_DEV_POLL) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_DEV_POLL_REACTOR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/dev_poll_reactor_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/dev_poll_reactor_fwd.hpp new file mode 100644 index 00000000..f7f1aeba --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/dev_poll_reactor_fwd.hpp @@ -0,0 +1,39 @@ +// +// dev_poll_reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP +#define ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#if !defined(ASIO_DISABLE_DEV_POLL) +#if defined(__sun) // This service is only supported on Solaris. + +// Define this to indicate that /dev/poll is supported on the target platform. +#define ASIO_HAS_DEV_POLL 1 + +namespace asio { +namespace detail { + +class dev_poll_reactor; + +} // namespace detail +} // namespace asio + +#endif // defined(__sun) +#endif // !defined(ASIO_DISABLE_DEV_POLL) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/epoll_reactor.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/epoll_reactor.hpp new file mode 100644 index 00000000..63673986 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/epoll_reactor.hpp @@ -0,0 +1,507 @@ +// +// epoll_reactor.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_EPOLL_REACTOR_HPP +#define ASIO_DETAIL_EPOLL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/epoll_reactor_fwd.hpp" + +#if defined(ASIO_HAS_EPOLL) + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/hash_map.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/select_interrupter.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/timer_op.hpp" +#include "asio/detail/timer_queue_base.hpp" +#include "asio/detail/timer_queue_fwd.hpp" +#include "asio/detail/timer_queue_set.hpp" + +#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) +# define ASIO_HAS_TIMERFD 1 +#endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) + +#if defined(ASIO_HAS_TIMERFD) +# include "asio/detail/push_options.hpp" +# include +# include "asio/detail/pop_options.hpp" +#endif // defined(ASIO_HAS_TIMERFD) + +namespace asio { +namespace detail { + +class epoll_reactor + : public asio::detail::service_base +{ +public: + enum { read_op = 0, write_op = 1, + connect_op = 1, except_op = 2, max_ops = 3 }; + + // Per-descriptor queues. + struct descriptor_state + { + descriptor_state() {} + descriptor_state(const descriptor_state&) {} + void operator=(const descriptor_state&) {} + + mutex mutex_; + op_queue op_queue_[max_ops]; + bool shutdown_; + }; + + // Per-descriptor data. + typedef descriptor_state* per_descriptor_data; + + // Constructor. + epoll_reactor(asio::io_service& io_service) + : asio::detail::service_base(io_service), + io_service_(use_service(io_service)), + mutex_(), + epoll_fd_(do_epoll_create()), +#if defined(ASIO_HAS_TIMERFD) + timer_fd_(timerfd_create(CLOCK_MONOTONIC, 0)), +#else // defined(ASIO_HAS_TIMERFD) + timer_fd_(-1), +#endif // defined(ASIO_HAS_TIMERFD) + interrupter_(), + shutdown_(false) + { + // Add the interrupter's descriptor to epoll. + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLIN | EPOLLERR | EPOLLET; + ev.data.ptr = &interrupter_; + epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev); + interrupter_.interrupt(); + + // Add the timer descriptor to epoll. + if (timer_fd_ != -1) + { + ev.events = EPOLLIN | EPOLLERR; + ev.data.ptr = &timer_fd_; + epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev); + } + } + + // Destructor. + ~epoll_reactor() + { + close(epoll_fd_); + if (timer_fd_ != -1) + close(timer_fd_); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + mutex::scoped_lock lock(mutex_); + shutdown_ = true; + lock.unlock(); + + op_queue ops; + + descriptor_map::iterator iter = registered_descriptors_.begin(); + descriptor_map::iterator end = registered_descriptors_.end(); + while (iter != end) + { + for (int i = 0; i < max_ops; ++i) + ops.push(iter->second.op_queue_[i]); + iter->second.shutdown_ = true; + ++iter; + } + + timer_queues_.get_all_timers(ops); + } + + // Initialise the task. + void init_task() + { + io_service_.init_task(); + } + + // Register a socket with the reactor. Returns 0 on success, system error + // code on failure. + int register_descriptor(socket_type descriptor, + per_descriptor_data& descriptor_data) + { + mutex::scoped_lock lock(registered_descriptors_mutex_); + + descriptor_map::iterator new_entry = registered_descriptors_.insert( + std::make_pair(descriptor, descriptor_state())).first; + descriptor_data = &new_entry->second; + + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLOUT | EPOLLPRI | EPOLLET; + ev.data.ptr = descriptor_data; + int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); + if (result != 0) + return errno; + + descriptor_data->shutdown_ = false; + + return 0; + } + + // Start a new operation. The reactor operation will be performed when the + // given descriptor is flagged as ready, or an error has occurred. + void start_op(int op_type, socket_type descriptor, + per_descriptor_data& descriptor_data, + reactor_op* op, bool allow_speculative) + { + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + if (descriptor_data->shutdown_) + return; + + if (descriptor_data->op_queue_[op_type].empty()) + { + if (allow_speculative + && (op_type != read_op + || descriptor_data->op_queue_[except_op].empty())) + { + if (op->perform()) + { + descriptor_lock.unlock(); + io_service_.post_immediate_completion(op); + return; + } + } + else + { + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLIN | EPOLLERR | EPOLLHUP + | EPOLLOUT | EPOLLPRI | EPOLLET; + ev.data.ptr = descriptor_data; + epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); + } + } + + descriptor_data->op_queue_[op_type].push(op); + io_service_.work_started(); + } + + // Cancel all operations associated with the given descriptor. The + // handlers associated with the descriptor will be invoked with the + // operation_aborted error. + void cancel_ops(socket_type descriptor, per_descriptor_data& descriptor_data) + { + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + + op_queue ops; + for (int i = 0; i < max_ops; ++i) + { + while (reactor_op* op = descriptor_data->op_queue_[i].front()) + { + op->ec_ = asio::error::operation_aborted; + descriptor_data->op_queue_[i].pop(); + ops.push(op); + } + } + + descriptor_lock.unlock(); + + io_service_.post_deferred_completions(ops); + } + + // Cancel any operations that are running against the descriptor and remove + // its registration from the reactor. + void close_descriptor(socket_type descriptor, + per_descriptor_data& descriptor_data) + { + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); + + // Remove the descriptor from the set of known descriptors. The descriptor + // will be automatically removed from the epoll set when it is closed. + descriptor_data->shutdown_ = true; + + op_queue ops; + for (int i = 0; i < max_ops; ++i) + { + while (reactor_op* op = descriptor_data->op_queue_[i].front()) + { + op->ec_ = asio::error::operation_aborted; + descriptor_data->op_queue_[i].pop(); + ops.push(op); + } + } + + descriptor_lock.unlock(); + + registered_descriptors_.erase(descriptor); + + descriptors_lock.unlock(); + + io_service_.post_deferred_completions(ops); + } + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& timer_queue) + { + mutex::scoped_lock lock(mutex_); + timer_queues_.insert(&timer_queue); + } + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& timer_queue) + { + mutex::scoped_lock lock(mutex_); + timer_queues_.erase(&timer_queue); + } + + // Schedule a new operation in the given timer queue to expire at the + // specified absolute time. + template + void schedule_timer(timer_queue& timer_queue, + const typename Time_Traits::time_type& time, timer_op* op, void* token) + { + mutex::scoped_lock lock(mutex_); + if (!shutdown_) + { + bool earliest = timer_queue.enqueue_timer(time, op, token); + io_service_.work_started(); + if (earliest) + { +#if defined(ASIO_HAS_TIMERFD) + if (timer_fd_ != -1) + { + itimerspec new_timeout; + itimerspec old_timeout; + int flags = get_timeout(new_timeout); + timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout); + return; + } +#endif // defined(ASIO_HAS_TIMERFD) + interrupter_.interrupt(); + } + } + } + + // Cancel the timer operations associated with the given token. Returns the + // number of operations that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& timer_queue, void* token) + { + mutex::scoped_lock lock(mutex_); + op_queue ops; + std::size_t n = timer_queue.cancel_timer(token, ops); + lock.unlock(); + io_service_.post_deferred_completions(ops); + return n; + } + + // Run epoll once until interrupted or events are ready to be dispatched. + void run(bool block, op_queue& ops) + { + // Calculate a timeout only if timerfd is not used. + int timeout; + if (timer_fd_ != -1) + timeout = block ? -1 : 0; + else + { + mutex::scoped_lock lock(mutex_); + timeout = block ? get_timeout() : 0; + } + + // Block on the epoll descriptor. + epoll_event events[128]; + int num_events = epoll_wait(epoll_fd_, events, 128, timeout); + +#if defined(ASIO_HAS_TIMERFD) + bool check_timers = (timer_fd_ == -1); +#else // defined(ASIO_HAS_TIMERFD) + bool check_timers = true; +#endif // defined(ASIO_HAS_TIMERFD) + + // Dispatch the waiting events. + for (int i = 0; i < num_events; ++i) + { + void* ptr = events[i].data.ptr; + if (ptr == &interrupter_) + { + // No need to reset the interrupter since we're leaving the descriptor + // in a ready-to-read state and relying on edge-triggered notifications + // to make it so that we only get woken up when the descriptor's epoll + // registration is updated. + +#if defined(ASIO_HAS_TIMERFD) + if (timer_fd_ == -1) + check_timers = true; +#else // defined(ASIO_HAS_TIMERFD) + check_timers = true; +#endif // defined(ASIO_HAS_TIMERFD) + } +#if defined(ASIO_HAS_TIMERFD) + else if (ptr == &timer_fd_) + { + check_timers = true; + } +#endif // defined(ASIO_HAS_TIMERFD) + else + { + descriptor_state* descriptor_data = static_cast(ptr); + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + + // Exception operations must be processed first to ensure that any + // out-of-band data is read before normal data. + static const int flag[max_ops] = { EPOLLIN, EPOLLOUT, EPOLLPRI }; + for (int j = max_ops - 1; j >= 0; --j) + { + if (events[i].events & (flag[j] | EPOLLERR | EPOLLHUP)) + { + while (reactor_op* op = descriptor_data->op_queue_[j].front()) + { + if (op->perform()) + { + descriptor_data->op_queue_[j].pop(); + ops.push(op); + } + else + break; + } + } + } + } + } + + if (check_timers) + { + mutex::scoped_lock common_lock(mutex_); + timer_queues_.get_ready_timers(ops); + +#if defined(ASIO_HAS_TIMERFD) + if (timer_fd_ != -1) + { + itimerspec new_timeout; + itimerspec old_timeout; + int flags = get_timeout(new_timeout); + timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout); + } +#endif // defined(ASIO_HAS_TIMERFD) + } + } + + // Interrupt the select loop. + void interrupt() + { + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLIN | EPOLLERR | EPOLLET; + ev.data.ptr = &interrupter_; + epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, interrupter_.read_descriptor(), &ev); + } + +private: + // The hint to pass to epoll_create to size its data structures. + enum { epoll_size = 20000 }; + + // Create the epoll file descriptor. Throws an exception if the descriptor + // cannot be created. + static int do_epoll_create() + { + int fd = epoll_create(epoll_size); + if (fd == -1) + { + boost::throw_exception( + asio::system_error( + asio::error_code(errno, + asio::error::get_system_category()), + "epoll")); + } + return fd; + } + + // Get the timeout value for the epoll_wait call. The timeout value is + // returned as a number of milliseconds. A return value of -1 indicates + // that epoll_wait should block indefinitely. + int get_timeout() + { + // By default we will wait no longer than 5 minutes. This will ensure that + // any changes to the system clock are detected after no longer than this. + return timer_queues_.wait_duration_msec(5 * 60 * 1000); + } + +#if defined(ASIO_HAS_TIMERFD) + // Get the timeout value for the timer descriptor. The return value is the + // flag argument to be used when calling timerfd_settime. + int get_timeout(itimerspec& ts) + { + ts.it_interval.tv_sec = 0; + ts.it_interval.tv_nsec = 0; + + long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000); + ts.it_value.tv_sec = usec / 1000000; + ts.it_value.tv_nsec = usec ? (usec % 1000000) * 1000 : 1; + + return usec ? 0 : TFD_TIMER_ABSTIME; + } +#endif // defined(ASIO_HAS_TIMERFD) + + // The io_service implementation used to post completions. + io_service_impl& io_service_; + + // Mutex to protect access to internal data. + mutex mutex_; + + // The epoll file descriptor. + int epoll_fd_; + + // The timer file descriptor. + int timer_fd_; + + // The interrupter is used to break a blocking epoll_wait call. + select_interrupter interrupter_; + + // The timer queues. + timer_queue_set timer_queues_; + + // Whether the service has been shut down. + bool shutdown_; + + // Mutex to protect access to the registered descriptors. + mutex registered_descriptors_mutex_; + + // Keep track of all registered descriptors. This code relies on the fact that + // the hash_map implementation pools deleted nodes, meaning that we can assume + // our descriptor_state pointer remains valid even after the entry is removed. + // Technically this is not true for C++98, as that standard says that spliced + // elements in a list are invalidated. However, C++0x fixes this shortcoming + // so we'll just assume that C++98 std::list implementations will do the right + // thing anyway. + typedef detail::hash_map descriptor_map; + descriptor_map registered_descriptors_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(ASIO_HAS_EPOLL) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_EPOLL_REACTOR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/epoll_reactor_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/epoll_reactor_fwd.hpp new file mode 100644 index 00000000..266bccda --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/epoll_reactor_fwd.hpp @@ -0,0 +1,46 @@ +// +// epoll_reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_EPOLL_REACTOR_FWD_HPP +#define ASIO_DETAIL_EPOLL_REACTOR_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#if !defined(ASIO_DISABLE_EPOLL) +#if defined(__linux__) // This service is only supported on Linux. + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if LINUX_VERSION_CODE >= KERNEL_VERSION (2,5,45) // Only kernels >= 2.5.45. + +// Define this to indicate that epoll is supported on the target platform. +#define ASIO_HAS_EPOLL 1 + +namespace asio { +namespace detail { + +class epoll_reactor; + +} // namespace detail +} // namespace asio + +#endif // LINUX_VERSION_CODE >= KERNEL_VERSION (2,5,45) +#endif // defined(__linux__) +#endif // !defined(ASIO_DISABLE_EPOLL) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_EPOLL_REACTOR_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/event.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/event.hpp new file mode 100644 index 00000000..65aa4cba --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/event.hpp @@ -0,0 +1,50 @@ +// +// event.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_EVENT_HPP +#define ASIO_DETAIL_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) +# include "asio/detail/null_event.hpp" +#elif defined(BOOST_WINDOWS) +# include "asio/detail/win_event.hpp" +#elif defined(BOOST_HAS_PTHREADS) +# include "asio/detail/posix_event.hpp" +#else +# error Only Windows and POSIX are supported! +#endif + +namespace asio { +namespace detail { + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) +typedef null_event event; +#elif defined(BOOST_WINDOWS) +typedef win_event event; +#elif defined(BOOST_HAS_PTHREADS) +typedef posix_event event; +#endif + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_EVENT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/eventfd_select_interrupter.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/eventfd_select_interrupter.hpp new file mode 100644 index 00000000..63b7ac4f --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/eventfd_select_interrupter.hpp @@ -0,0 +1,166 @@ +// +// eventfd_select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP +#define ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#if defined(__linux__) +# if !defined(ASIO_DISABLE_EVENTFD) +# include +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +# define ASIO_HAS_EVENTFD +# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +# endif // !defined(ASIO_DISABLE_EVENTFD) +#endif // defined(__linux__) + +#if defined(ASIO_HAS_EVENTFD) + +#include "asio/detail/push_options.hpp" +#include +#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 +# include +#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 +# include +#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace detail { + +class eventfd_select_interrupter +{ +public: + // Constructor. + eventfd_select_interrupter() + { +#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 + write_descriptor_ = read_descriptor_ = syscall(__NR_eventfd, 0); +#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 + write_descriptor_ = read_descriptor_ = ::eventfd(0, 0); +#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 + if (read_descriptor_ != -1) + { + ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); + } + else + { + int pipe_fds[2]; + if (pipe(pipe_fds) == 0) + { + read_descriptor_ = pipe_fds[0]; + ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); + write_descriptor_ = pipe_fds[1]; + ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK); + } + else + { + asio::error_code ec(errno, + asio::error::get_system_category()); + asio::system_error e(ec, "eventfd_select_interrupter"); + boost::throw_exception(e); + } + } + } + + // Destructor. + ~eventfd_select_interrupter() + { + if (write_descriptor_ != -1 && write_descriptor_ != read_descriptor_) + ::close(write_descriptor_); + if (read_descriptor_ != -1) + ::close(read_descriptor_); + } + + // Interrupt the select call. + void interrupt() + { + uint64_t counter(1UL); + int result = ::write(write_descriptor_, &counter, sizeof(uint64_t)); + (void)result; + } + + // Reset the select interrupt. Returns true if the call was interrupted. + bool reset() + { + if (write_descriptor_ == read_descriptor_) + { + for (;;) + { + // Only perform one read. The kernel maintains an atomic counter. + uint64_t counter(0); + errno = 0; + int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t)); + if (bytes_read < 0 && errno == EINTR) + continue; + bool was_interrupted = (bytes_read > 0); + return was_interrupted; + } + } + else + { + for (;;) + { + // Clear all data from the pipe. + char data[1024]; + int bytes_read = ::read(read_descriptor_, data, sizeof(data)); + if (bytes_read < 0 && errno == EINTR) + continue; + bool was_interrupted = (bytes_read > 0); + while (bytes_read == sizeof(data)) + bytes_read = ::read(read_descriptor_, data, sizeof(data)); + return was_interrupted; + } + } + } + + // Get the read descriptor to be passed to select. + int read_descriptor() const + { + return read_descriptor_; + } + +private: + // The read end of a connection used to interrupt the select call. This file + // descriptor is passed to select such that when it is time to stop, a single + // 64bit value will be written on the other end of the connection and this + // descriptor will become readable. + int read_descriptor_; + + // The write end of a connection used to interrupt the select call. A single + // 64bit non-zero value may be written to this to wake up the select which is + // waiting for the other end to become readable. This descriptor will only + // differ from the read descriptor when a pipe is used. + int write_descriptor_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(ASIO_HAS_EVENTFD) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/fd_set_adapter.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/fd_set_adapter.hpp new file mode 100644 index 00000000..a575491b --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/fd_set_adapter.hpp @@ -0,0 +1,41 @@ +// +// fd_set_adapter.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_FD_SET_ADAPTER_HPP +#define ASIO_DETAIL_FD_SET_ADAPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/posix_fd_set_adapter.hpp" +#include "asio/detail/win_fd_set_adapter.hpp" + +namespace asio { +namespace detail { + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef win_fd_set_adapter fd_set_adapter; +#else +typedef posix_fd_set_adapter fd_set_adapter; +#endif + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_FD_SET_ADAPTER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/fenced_block.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/fenced_block.hpp new file mode 100644 index 00000000..60198bc6 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/fenced_block.hpp @@ -0,0 +1,70 @@ +// +// fenced_block.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_FENCED_BLOCK_HPP +#define ASIO_DETAIL_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) +# include "asio/detail/null_fenced_block.hpp" +#elif defined(__MACH__) && defined(__APPLE__) +# include "asio/detail/macos_fenced_block.hpp" +#elif defined(__sun) +# include "asio/detail/solaris_fenced_block.hpp" +#elif defined(__GNUC__) \ + && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \ + && !defined(__INTEL_COMPILER) && !defined(__ICL) \ + && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) +# include "asio/detail/gcc_fenced_block.hpp" +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +# include "asio/detail/gcc_x86_fenced_block.hpp" +#elif defined(BOOST_WINDOWS) && !defined(UNDER_CE) +# include "asio/detail/win_fenced_block.hpp" +#else +# include "asio/detail/null_fenced_block.hpp" +#endif + +namespace asio { +namespace detail { + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) +typedef null_fenced_block fenced_block; +#elif defined(__MACH__) && defined(__APPLE__) +typedef macos_fenced_block fenced_block; +#elif defined(__sun) +typedef solaris_fenced_block fenced_block; +#elif defined(__GNUC__) \ + && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \ + && !defined(__INTEL_COMPILER) && !defined(__ICL) \ + && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) +typedef gcc_fenced_block fenced_block; +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +typedef gcc_x86_fenced_block fenced_block; +#elif defined(BOOST_WINDOWS) && !defined(UNDER_CE) +typedef win_fenced_block fenced_block; +#else +typedef null_fenced_block fenced_block; +#endif + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_FENCED_BLOCK_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/gcc_fenced_block.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/gcc_fenced_block.hpp new file mode 100644 index 00000000..23303fbf --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/gcc_fenced_block.hpp @@ -0,0 +1,63 @@ +// +// gcc_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_GCC_FENCED_BLOCK_HPP +#define ASIO_DETAIL_GCC_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(__GNUC__) \ + && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \ + && !defined(__INTEL_COMPILER) && !defined(__ICL) \ + && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) + +namespace asio { +namespace detail { + +class gcc_fenced_block + : private noncopyable +{ +public: + // Constructor. + gcc_fenced_block() + : value_(0) + { + __sync_lock_test_and_set(&value_, 1); + } + + // Destructor. + ~gcc_fenced_block() + { + __sync_lock_release(&value_); + } + +private: + int value_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(__GNUC__) + // && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) + // && !defined(__INTEL_COMPILER) && !defined(__ICL) + // && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_GCC_FENCED_BLOCK_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/gcc_x86_fenced_block.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/gcc_x86_fenced_block.hpp new file mode 100644 index 00000000..48119f4c --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/gcc_x86_fenced_block.hpp @@ -0,0 +1,61 @@ +// +// gcc_x86_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP +#define ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + +namespace asio { +namespace detail { + +class gcc_x86_fenced_block + : private noncopyable +{ +public: + // Constructor. + gcc_x86_fenced_block() + { + barrier(); + } + + // Destructor. + ~gcc_x86_fenced_block() + { + barrier(); + } + +private: + static int barrier() + { + int r = 0; + __asm__ __volatile__ ("xchgl %%eax, %0" : "=m" (r) : : "memory", "cc"); + return r; + } +}; + +} // namespace detail +} // namespace asio + +#endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/handler_alloc_helpers.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/handler_alloc_helpers.hpp new file mode 100644 index 00000000..0ac42a7b --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/handler_alloc_helpers.hpp @@ -0,0 +1,259 @@ +// +// handler_alloc_helpers.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP +#define ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/handler_alloc_hook.hpp" +#include "asio/detail/noncopyable.hpp" + +// Calls to asio_handler_allocate and asio_handler_deallocate must be made from +// a namespace that does not contain any overloads of these functions. The +// asio_handler_alloc_helpers namespace is defined here for that purpose. +namespace asio_handler_alloc_helpers { + +template +inline void* allocate(std::size_t s, Handler& h) +{ +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \ + || BOOST_WORKAROUND(__GNUC__, < 3) + return ::operator new(s); +#else + using namespace asio; + return asio_handler_allocate(s, boost::addressof(h)); +#endif +} + +template +inline void deallocate(void* p, std::size_t s, Handler& h) +{ +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \ + || BOOST_WORKAROUND(__GNUC__, < 3) + ::operator delete(p); +#else + using namespace asio; + asio_handler_deallocate(p, s, boost::addressof(h)); +#endif +} + +} // namespace asio_handler_alloc_helpers + +namespace asio { +namespace detail { + +// Traits for handler allocation. +template +struct handler_alloc_traits +{ + typedef Handler handler_type; + typedef Object value_type; + typedef Object* pointer_type; + BOOST_STATIC_CONSTANT(std::size_t, value_size = sizeof(Object)); +}; + +template +class handler_ptr; + +// Helper class to provide RAII on uninitialised handler memory. +template +class raw_handler_ptr + : private noncopyable +{ +public: + typedef typename Alloc_Traits::handler_type handler_type; + typedef typename Alloc_Traits::value_type value_type; + typedef typename Alloc_Traits::pointer_type pointer_type; + BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size); + + // Constructor allocates the memory. + raw_handler_ptr(handler_type& handler) + : handler_(handler), + pointer_(static_cast( + asio_handler_alloc_helpers::allocate(value_size, handler_))) + { + } + + // Destructor automatically deallocates memory, unless it has been stolen by + // a handler_ptr object. + ~raw_handler_ptr() + { + if (pointer_) + asio_handler_alloc_helpers::deallocate( + pointer_, value_size, handler_); + } + +private: + friend class handler_ptr; + handler_type& handler_; + pointer_type pointer_; +}; + +// Helper class to provide RAII on uninitialised handler memory. +template +class handler_ptr + : private noncopyable +{ +public: + typedef typename Alloc_Traits::handler_type handler_type; + typedef typename Alloc_Traits::value_type value_type; + typedef typename Alloc_Traits::pointer_type pointer_type; + BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size); + typedef raw_handler_ptr raw_ptr_type; + + // Take ownership of existing memory. + handler_ptr(handler_type& handler, pointer_type pointer) + : handler_(handler), + pointer_(pointer) + { + } + + // Construct object in raw memory and take ownership if construction succeeds. + handler_ptr(raw_ptr_type& raw_ptr) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1, a2)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, + Arg5& a5) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, + Arg5& a5, Arg6& a6) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, + Arg5& a5, Arg6& a6, Arg7& a7) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6, a7)) + { + raw_ptr.pointer_ = 0; + } + + // Construct object in raw memory and take ownership if construction succeeds. + template + handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, + Arg5& a5, Arg6& a6, Arg7& a7, Arg8& a8) + : handler_(raw_ptr.handler_), + pointer_(new (raw_ptr.pointer_) value_type( + a1, a2, a3, a4, a5, a6, a7, a8)) + { + raw_ptr.pointer_ = 0; + } + + // Destructor automatically deallocates memory, unless it has been released. + ~handler_ptr() + { + reset(); + } + + // Get the memory. + pointer_type get() const + { + return pointer_; + } + + // Release ownership of the memory. + pointer_type release() + { + pointer_type tmp = pointer_; + pointer_ = 0; + return tmp; + } + + // Explicitly destroy and deallocate the memory. + void reset() + { + if (pointer_) + { + pointer_->value_type::~value_type(); + asio_handler_alloc_helpers::deallocate( + pointer_, value_size, handler_); + pointer_ = 0; + } + } + +private: + handler_type& handler_; + pointer_type pointer_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/handler_base_from_member.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/handler_base_from_member.hpp new file mode 100644 index 00000000..87e16c14 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/handler_base_from_member.hpp @@ -0,0 +1,76 @@ +// +// handler_base_from_member.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_HANDLER_BASE_FROM_MEMBER_HPP +#define ASIO_DETAIL_HANDLER_BASE_FROM_MEMBER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" + +namespace asio { +namespace detail { + +// Base class for classes that need a handler data member. Forwards the custom +// allocation and invocation hooks to the contained handler. +template +class handler_base_from_member +{ +public: + handler_base_from_member(Handler handler) + : handler_(handler) + { + } + +//protected: + Handler handler_; + +protected: + // Protected destructor to prevent deletion through this type. + ~handler_base_from_member() + { + } +}; + +template +inline void* asio_handler_allocate(std::size_t size, + handler_base_from_member* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, &this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + handler_base_from_member* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, &this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + handler_base_from_member* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, &this_handler->handler_); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_HANDLER_BASE_FROM_MEMBER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/handler_invoke_helpers.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/handler_invoke_helpers.hpp new file mode 100644 index 00000000..8332567c --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/handler_invoke_helpers.hpp @@ -0,0 +1,49 @@ +// +// handler_invoke_helpers.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP +#define ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/handler_invoke_hook.hpp" + +// Calls to asio_handler_invoke must be made from a namespace that does not +// contain overloads of this function. The asio_handler_invoke_helpers +// namespace is defined here for that purpose. +namespace asio_handler_invoke_helpers { + +template +inline void invoke(const Function& function, Context& context) +{ +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \ + || BOOST_WORKAROUND(__GNUC__, < 3) + Function tmp(function); + tmp(); +#else + using namespace asio; + asio_handler_invoke(function, boost::addressof(context)); +#endif +} + +} // namespace asio_handler_invoke_helpers + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/handler_queue.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/handler_queue.hpp new file mode 100644 index 00000000..989f976b --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/handler_queue.hpp @@ -0,0 +1,229 @@ +// +// handler_queue.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_HANDLER_QUEUE_HPP +#define ASIO_DETAIL_HANDLER_QUEUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/noncopyable.hpp" + +namespace asio { +namespace detail { + +class handler_queue + : private noncopyable +{ +public: + // Base class for handlers in the queue. + class handler + : private noncopyable + { + public: + void invoke() + { + invoke_func_(this); + } + + void destroy() + { + destroy_func_(this); + } + + protected: + typedef void (*invoke_func_type)(handler*); + typedef void (*destroy_func_type)(handler*); + + handler(invoke_func_type invoke_func, + destroy_func_type destroy_func) + : next_(0), + invoke_func_(invoke_func), + destroy_func_(destroy_func) + { + } + + ~handler() + { + } + + private: + friend class handler_queue; + handler* next_; + invoke_func_type invoke_func_; + destroy_func_type destroy_func_; + }; + + // Smart point to manager handler lifetimes. + class scoped_ptr + : private noncopyable + { + public: + explicit scoped_ptr(handler* h) + : handler_(h) + { + } + + ~scoped_ptr() + { + if (handler_) + handler_->destroy(); + } + + handler* get() const + { + return handler_; + } + + handler* release() + { + handler* tmp = handler_; + handler_ = 0; + return tmp; + } + + private: + handler* handler_; + }; + + // Constructor. + handler_queue() + : front_(0), + back_(0) + { + } + + // Wrap a handler to be pushed into the queue. + template + static handler* wrap(Handler h) + { + // Allocate and construct an object to wrap the handler. + typedef handler_wrapper value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(h); + handler_ptr ptr(raw_ptr, h); + return ptr.release(); + } + + // Get the handler at the front of the queue. + handler* front() + { + return front_; + } + + // Pop a handler from the front of the queue. + void pop() + { + if (front_) + { + handler* tmp = front_; + front_ = front_->next_; + if (front_ == 0) + back_ = 0; + tmp->next_= 0; + } + } + + // Push a handler on to the back of the queue. + void push(handler* h) + { + h->next_ = 0; + if (back_) + { + back_->next_ = h; + back_ = h; + } + else + { + front_ = back_ = h; + } + } + + // Whether the queue is empty. + bool empty() const + { + return front_ == 0; + } + +private: + // Template wrapper for handlers. + template + class handler_wrapper + : public handler + { + public: + handler_wrapper(Handler h) + : handler( + &handler_wrapper::do_call, + &handler_wrapper::do_destroy), + handler_(h) + { + } + + static void do_call(handler* base) + { + // Take ownership of the handler object. + typedef handler_wrapper this_type; + this_type* h(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(h->handler_, h); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. + Handler handler(h->handler_); + + // Free the memory associated with the handler. + ptr.reset(); + + // Make the upcall. + asio_handler_invoke_helpers::invoke(handler, &handler); + } + + static void do_destroy(handler* base) + { + // Take ownership of the handler object. + typedef handler_wrapper this_type; + this_type* h(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(h->handler_, h); + + // A sub-object of the handler may be the true owner of the memory + // associated with the handler. Consequently, a local copy of the handler + // is required to ensure that any owning sub-object remains valid until + // after we have deallocated the memory here. + Handler handler(h->handler_); + (void)handler; + + // Free the memory associated with the handler. + ptr.reset(); + } + + private: + Handler handler_; + }; + + // The front of the queue. + handler* front_; + + // The back of the queue. + handler* back_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_HANDLER_QUEUE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/hash_map.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/hash_map.hpp new file mode 100644 index 00000000..b2a15178 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/hash_map.hpp @@ -0,0 +1,324 @@ +// +// hash_map.hpp +// ~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_HASH_MAP_HPP +#define ASIO_DETAIL_HASH_MAP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace detail { + +template +inline std::size_t calculate_hash_value(const T& t) +{ + return boost::hash_value(t); +} + +#if defined(_WIN64) +inline std::size_t calculate_hash_value(SOCKET s) +{ + return static_cast(s); +} +#endif // defined(_WIN64) + +// Note: assumes K and V are POD types. +template +class hash_map + : private noncopyable +{ +public: + // The type of a value in the map. + typedef std::pair value_type; + + // The type of a non-const iterator over the hash map. + typedef typename std::list::iterator iterator; + + // The type of a const iterator over the hash map. + typedef typename std::list::const_iterator const_iterator; + + // Constructor. + hash_map() + : size_(0), + buckets_(0), + num_buckets_(0) + { + } + + // Destructor. + ~hash_map() + { + delete[] buckets_; + } + + // Get an iterator for the beginning of the map. + iterator begin() + { + return values_.begin(); + } + + // Get an iterator for the beginning of the map. + const_iterator begin() const + { + return values_.begin(); + } + + // Get an iterator for the end of the map. + iterator end() + { + return values_.end(); + } + + // Get an iterator for the end of the map. + const_iterator end() const + { + return values_.end(); + } + + // Check whether the map is empty. + bool empty() const + { + return values_.empty(); + } + + // Find an entry in the map. + iterator find(const K& k) + { + if (num_buckets_) + { + size_t bucket = calculate_hash_value(k) % num_buckets_; + iterator it = buckets_[bucket].first; + if (it == values_.end()) + return values_.end(); + iterator end = buckets_[bucket].last; + ++end; + while (it != end) + { + if (it->first == k) + return it; + ++it; + } + } + return values_.end(); + } + + // Find an entry in the map. + const_iterator find(const K& k) const + { + if (num_buckets_) + { + size_t bucket = calculate_hash_value(k) % num_buckets_; + const_iterator it = buckets_[bucket].first; + if (it == values_.end()) + return it; + const_iterator end = buckets_[bucket].last; + ++end; + while (it != end) + { + if (it->first == k) + return it; + ++it; + } + } + return values_.end(); + } + + // Insert a new entry into the map. + std::pair insert(const value_type& v) + { + if (size_ + 1 >= num_buckets_) + rehash(hash_size(size_ + 1)); + size_t bucket = calculate_hash_value(v.first) % num_buckets_; + iterator it = buckets_[bucket].first; + if (it == values_.end()) + { + buckets_[bucket].first = buckets_[bucket].last = + values_insert(values_.end(), v); + ++size_; + return std::pair(buckets_[bucket].last, true); + } + iterator end = buckets_[bucket].last; + ++end; + while (it != end) + { + if (it->first == v.first) + return std::pair(it, false); + ++it; + } + buckets_[bucket].last = values_insert(end, v); + ++size_; + return std::pair(buckets_[bucket].last, true); + } + + // Erase an entry from the map. + void erase(iterator it) + { + assert(it != values_.end()); + + size_t bucket = calculate_hash_value(it->first) % num_buckets_; + bool is_first = (it == buckets_[bucket].first); + bool is_last = (it == buckets_[bucket].last); + if (is_first && is_last) + buckets_[bucket].first = buckets_[bucket].last = values_.end(); + else if (is_first) + ++buckets_[bucket].first; + else if (is_last) + --buckets_[bucket].last; + + values_erase(it); + --size_; + } + + // Erase a key from the map. + void erase(const K& k) + { + iterator it = find(k); + if (it != values_.end()) + erase(it); + } + + // Remove all entries from the map. + void clear() + { + // Clear the values. + values_.clear(); + size_ = 0; + + // Initialise all buckets to empty. + iterator end = values_.end(); + for (size_t i = 0; i < num_buckets_; ++i) + buckets_[i].first = buckets_[i].last = end; + } + +private: + // Calculate the hash size for the specified number of elements. + static std::size_t hash_size(std::size_t num_elems) + { + static std::size_t sizes[] = + { +#if defined(ASIO_HASH_MAP_BUCKETS) + ASIO_HASH_MAP_BUCKETS +#else // ASIO_HASH_MAP_BUCKETS + 3, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, + 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, + 12582917, 25165843 +#endif // ASIO_HASH_MAP_BUCKETS + }; + const std::size_t nth_size = sizeof(sizes) / sizeof(std::size_t) - 1; + for (std::size_t i = 0; i < nth_size; ++i) + if (num_elems < sizes[i]) + return sizes[i]; + return sizes[nth_size]; + } + + // Re-initialise the hash from the values already contained in the list. + void rehash(std::size_t num_buckets) + { + if (num_buckets == num_buckets_) + return; + num_buckets_ = num_buckets; + + iterator end = values_.end(); + + // Update number of buckets and initialise all buckets to empty. + bucket_type* tmp = new bucket_type[num_buckets_]; + delete[] buckets_; + buckets_ = tmp; + for (std::size_t i = 0; i < num_buckets_; ++i) + buckets_[i].first = buckets_[i].last = end; + + // Put all values back into the hash. + iterator iter = values_.begin(); + while (iter != end) + { + std::size_t bucket = calculate_hash_value(iter->first) % num_buckets_; + if (buckets_[bucket].last == end) + { + buckets_[bucket].first = buckets_[bucket].last = iter++; + } + else if (++buckets_[bucket].last == iter) + { + ++iter; + } + else + { + values_.splice(buckets_[bucket].last, values_, iter++); + --buckets_[bucket].last; + } + } + } + + // Insert an element into the values list by splicing from the spares list, + // if a spare is available, and otherwise by inserting a new element. + iterator values_insert(iterator it, const value_type& v) + { + if (spares_.empty()) + { + return values_.insert(it, v); + } + else + { + spares_.front() = v; + values_.splice(it, spares_, spares_.begin()); + return --it; + } + } + + // Erase an element from the values list by splicing it to the spares list. + void values_erase(iterator it) + { + *it = value_type(); + spares_.splice(spares_.begin(), values_, it); + } + + // The number of elements in the hash. + std::size_t size_; + + // The list of all values in the hash map. + std::list values_; + + // The list of spare nodes waiting to be recycled. Assumes that POD types only + // are stored in the hash map. + std::list spares_; + + // The type for a bucket in the hash table. + struct bucket_type + { + iterator first; + iterator last; + }; + + // The buckets in the hash. + bucket_type* buckets_; + + // The number of buckets in the hash. + std::size_t num_buckets_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_HASH_MAP_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/indirect_handler_queue.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/indirect_handler_queue.hpp new file mode 100644 index 00000000..d08a7df4 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/indirect_handler_queue.hpp @@ -0,0 +1,291 @@ +// +// indirect_handler_queue.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_INDIRECT_HANDLER_QUEUE_HPP +#define ASIO_DETAIL_INDIRECT_HANDLER_QUEUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/noncopyable.hpp" + +#if defined(_MSC_VER) && (_MSC_VER >= 1310) +extern "C" void _ReadWriteBarrier(); +# pragma intrinsic(_ReadWriteBarrier) +#endif // defined(_MSC_VER) && (_MSC_VER >= 1310) + +namespace asio { +namespace detail { + +class indirect_handler_queue + : private noncopyable +{ +public: + class handler; + + // Element for a node in the queue. + class node + { + public: + node() + : version_(0), + handler_(0), + next_(0) + { + } + + private: + friend class indirect_handler_queue; + unsigned long version_; + handler* handler_; + node* next_; + }; + + // Base class for handlers in the queue. + class handler + : private noncopyable + { + public: + void invoke() + { + invoke_func_(this); + } + + void destroy() + { + destroy_func_(this); + } + + protected: + typedef void (*invoke_func_type)(handler*); + typedef void (*destroy_func_type)(handler*); + + handler(invoke_func_type invoke_func, + destroy_func_type destroy_func) + : node_(new node), + invoke_func_(invoke_func), + destroy_func_(destroy_func) + { + } + + ~handler() + { + if (node_) + delete node_; + } + + private: + friend class indirect_handler_queue; + node* node_; + invoke_func_type invoke_func_; + destroy_func_type destroy_func_; + }; + + // Smart point to manager handler lifetimes. + class scoped_ptr + : private noncopyable + { + public: + explicit scoped_ptr(handler* h) + : handler_(h) + { + } + + ~scoped_ptr() + { + if (handler_) + handler_->destroy(); + } + + handler* get() const + { + return handler_; + } + + handler* release() + { + handler* tmp = handler_; + handler_ = 0; + return tmp; + } + + private: + handler* handler_; + }; + + // Constructor. + indirect_handler_queue() + : front_(new node), + back_(front_), + next_version_(1) + { + } + + // Destructor. + ~indirect_handler_queue() + { + while (front_) + { + node* tmp = front_; + front_ = front_->next_; + delete tmp; + } + } + + // Wrap a handler to be pushed into the queue. + template + static handler* wrap(Handler h) + { + // Allocate and construct an object to wrap the handler. + typedef handler_wrapper value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(h); + handler_ptr ptr(raw_ptr, h); + return ptr.release(); + } + + // Determine whether the queue has something ready to pop. + bool poppable() + { + return front_->next_ != 0; + } + + // The version number at the front of the queue. + unsigned long front_version() + { + return front_->version_; + } + + // The version number at the back of the queue. + unsigned long back_version() + { + return back_->version_; + } + + // Pop a handler from the front of the queue. + handler* pop() + { + node* n = front_; + node* new_front = n->next_; + if (new_front) + { + handler* h = new_front->handler_; + h->node_ = n; + new_front->handler_ = 0; + front_ = new_front; + return h; + } + return 0; + } + + // Push a handler on to the back of the queue. + void push(handler* h) + { + node* n = h->node_; + h->node_ = 0; + n->version_ = next_version_; + next_version_ += 2; + n->handler_ = h; + n->next_ = 0; + memory_barrier(); + back_->next_ = n; + back_ = n; + } + +private: + // Template wrapper for handlers. + template + class handler_wrapper + : public handler + { + public: + handler_wrapper(Handler h) + : handler( + &handler_wrapper::do_call, + &handler_wrapper::do_destroy), + handler_(h) + { + } + + static void do_call(handler* base) + { + // Take ownership of the handler object. + typedef handler_wrapper this_type; + this_type* h(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(h->handler_, h); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. + Handler handler(h->handler_); + + // Free the memory associated with the handler. + ptr.reset(); + + // Make the upcall. + asio_handler_invoke_helpers::invoke(handler, &handler); + } + + static void do_destroy(handler* base) + { + // Take ownership of the handler object. + typedef handler_wrapper this_type; + this_type* h(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(h->handler_, h); + + // A sub-object of the handler may be the true owner of the memory + // associated with the handler. Consequently, a local copy of the handler + // is required to ensure that any owning sub-object remains valid until + // after we have deallocated the memory here. + Handler handler(h->handler_); + (void)handler; + + // Free the memory associated with the handler. + ptr.reset(); + } + + private: + Handler handler_; + }; + + // Helper function to create a memory barrier. + static void memory_barrier() + { +#if defined(_GLIBCXX_WRITE_MEM_BARRIER) + _GLIBCXX_WRITE_MEM_BARRIER; +#elif defined(_MSC_VER) && (_MSC_VER >= 1310) + _ReadWriteBarrier(); +#else +# error memory barrier required +#endif + } + + // The front of the queue. + node* front_; + + // The back of the queue. + node* back_; + + // The next version counter to be assigned to a node. + unsigned long next_version_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_INDIRECT_HANDLER_QUEUE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/io_control.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/io_control.hpp new file mode 100644 index 00000000..df7171cb --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/io_control.hpp @@ -0,0 +1,137 @@ +// +// io_control.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_IO_CONTROL_HPP +#define ASIO_DETAIL_IO_CONTROL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace detail { +namespace io_control { + +// IO control command for non-blocking I/O. +class non_blocking_io +{ +public: + // Default constructor. + non_blocking_io() + : value_(0) + { + } + + // Construct with a specific command value. + non_blocking_io(bool value) + : value_(value ? 1 : 0) + { + } + + // Get the name of the IO control command. + int name() const + { + return FIONBIO; + } + + // Set the value of the I/O control command. + void set(bool value) + { + value_ = value ? 1 : 0; + } + + // Get the current value of the I/O control command. + bool get() const + { + return value_ != 0; + } + + // Get the address of the command data. + detail::ioctl_arg_type* data() + { + return &value_; + } + + // Get the address of the command data. + const detail::ioctl_arg_type* data() const + { + return &value_; + } + +private: + detail::ioctl_arg_type value_; +}; + +// I/O control command for getting number of bytes available. +class bytes_readable +{ +public: + // Default constructor. + bytes_readable() + : value_(0) + { + } + + // Construct with a specific command value. + bytes_readable(std::size_t value) + : value_(static_cast(value)) + { + } + + // Get the name of the IO control command. + int name() const + { + return FIONREAD; + } + + // Set the value of the I/O control command. + void set(std::size_t value) + { + value_ = static_cast(value); + } + + // Get the current value of the I/O control command. + std::size_t get() const + { + return static_cast(value_); + } + + // Get the address of the command data. + detail::ioctl_arg_type* data() + { + return &value_; + } + + // Get the address of the command data. + const detail::ioctl_arg_type* data() const + { + return &value_; + } + +private: + detail::ioctl_arg_type value_; +}; + +} // namespace io_control +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_IO_CONTROL_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/kqueue_reactor.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/kqueue_reactor.hpp new file mode 100644 index 00000000..1e118b31 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/kqueue_reactor.hpp @@ -0,0 +1,485 @@ +// +// kqueue_reactor.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_KQUEUE_REACTOR_HPP +#define ASIO_DETAIL_KQUEUE_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/kqueue_reactor_fwd.hpp" + +#if defined(ASIO_HAS_KQUEUE) + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/hash_map.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/select_interrupter.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/timer_op.hpp" +#include "asio/detail/timer_queue_base.hpp" +#include "asio/detail/timer_queue_fwd.hpp" +#include "asio/detail/timer_queue_set.hpp" + +// Older versions of Mac OS X may not define EV_OOBAND. +#if !defined(EV_OOBAND) +# define EV_OOBAND EV_FLAG1 +#endif // !defined(EV_OOBAND) + +namespace asio { +namespace detail { + +class kqueue_reactor + : public asio::detail::service_base +{ +public: + enum op_types { read_op = 0, write_op = 1, + connect_op = 1, except_op = 2, max_ops = 3 }; + + // Per-descriptor queues. + struct descriptor_state + { + descriptor_state() {} + descriptor_state(const descriptor_state&) {} + void operator=(const descriptor_state&) {} + + mutex mutex_; + op_queue op_queue_[max_ops]; + bool shutdown_; + }; + + // Per-descriptor data. + typedef descriptor_state* per_descriptor_data; + + // Constructor. + kqueue_reactor(asio::io_service& io_service) + : asio::detail::service_base(io_service), + io_service_(use_service(io_service)), + mutex_(), + kqueue_fd_(do_kqueue_create()), + interrupter_(), + shutdown_(false) + { + // The interrupter is put into a permanently readable state. Whenever we + // want to interrupt the blocked kevent call we register a one-shot read + // operation against the descriptor. + interrupter_.interrupt(); + } + + // Destructor. + ~kqueue_reactor() + { + close(kqueue_fd_); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + mutex::scoped_lock lock(mutex_); + shutdown_ = true; + lock.unlock(); + + op_queue ops; + + descriptor_map::iterator iter = registered_descriptors_.begin(); + descriptor_map::iterator end = registered_descriptors_.end(); + while (iter != end) + { + for (int i = 0; i < max_ops; ++i) + ops.push(iter->second.op_queue_[i]); + iter->second.shutdown_ = true; + ++iter; + } + + timer_queues_.get_all_timers(ops); + } + + // Initialise the task. + void init_task() + { + io_service_.init_task(); + } + + // Register a socket with the reactor. Returns 0 on success, system error + // code on failure. + int register_descriptor(socket_type descriptor, + per_descriptor_data& descriptor_data) + { + mutex::scoped_lock lock(registered_descriptors_mutex_); + + descriptor_map::iterator new_entry = registered_descriptors_.insert( + std::make_pair(descriptor, descriptor_state())).first; + descriptor_data = &new_entry->second; + + descriptor_data->shutdown_ = false; + + return 0; + } + + // Start a new operation. The reactor operation will be performed when the + // given descriptor is flagged as ready, or an error has occurred. + void start_op(int op_type, socket_type descriptor, + per_descriptor_data& descriptor_data, + reactor_op* op, bool allow_speculative) + { + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + if (descriptor_data->shutdown_) + return; + + bool first = descriptor_data->op_queue_[op_type].empty(); + if (first) + { + if (allow_speculative) + { + if (op_type != read_op || descriptor_data->op_queue_[except_op].empty()) + { + if (op->perform()) + { + descriptor_lock.unlock(); + io_service_.post_immediate_completion(op); + return; + } + } + } + } + + descriptor_data->op_queue_[op_type].push(op); + io_service_.work_started(); + + if (first) + { + struct kevent event; + switch (op_type) + { + case read_op: + EV_SET(&event, descriptor, EVFILT_READ, + EV_ADD | EV_ONESHOT, 0, 0, descriptor_data); + break; + case write_op: + EV_SET(&event, descriptor, EVFILT_WRITE, + EV_ADD | EV_ONESHOT, 0, 0, descriptor_data); + break; + case except_op: + if (!descriptor_data->op_queue_[read_op].empty()) + return; // Already registered for read events. + EV_SET(&event, descriptor, EVFILT_READ, + EV_ADD | EV_ONESHOT, EV_OOBAND, 0, descriptor_data); + break; + } + + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + op->ec_ = asio::error_code(errno, + asio::error::get_system_category()); + descriptor_data->op_queue_[op_type].pop(); + io_service_.post_deferred_completion(op); + } + } + } + + // Cancel all operations associated with the given descriptor. The + // handlers associated with the descriptor will be invoked with the + // operation_aborted error. + void cancel_ops(socket_type descriptor, per_descriptor_data& descriptor_data) + { + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + + op_queue ops; + for (int i = 0; i < max_ops; ++i) + { + while (reactor_op* op = descriptor_data->op_queue_[i].front()) + { + op->ec_ = asio::error::operation_aborted; + descriptor_data->op_queue_[i].pop(); + ops.push(op); + } + } + + descriptor_lock.unlock(); + + io_service_.post_deferred_completions(ops); + } + + // Cancel any operations that are running against the descriptor and remove + // its registration from the reactor. + void close_descriptor(socket_type descriptor, + per_descriptor_data& descriptor_data) + { + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); + + // Remove the descriptor from the set of known descriptors. The descriptor + // will be automatically removed from the kqueue set when it is closed. + descriptor_data->shutdown_ = true; + + op_queue ops; + for (int i = 0; i < max_ops; ++i) + { + while (reactor_op* op = descriptor_data->op_queue_[i].front()) + { + op->ec_ = asio::error::operation_aborted; + descriptor_data->op_queue_[i].pop(); + ops.push(op); + } + } + + descriptor_lock.unlock(); + + registered_descriptors_.erase(descriptor); + + descriptors_lock.unlock(); + + io_service_.post_deferred_completions(ops); + } + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& timer_queue) + { + mutex::scoped_lock lock(mutex_); + timer_queues_.insert(&timer_queue); + } + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& timer_queue) + { + mutex::scoped_lock lock(mutex_); + timer_queues_.erase(&timer_queue); + } + + // Schedule a new operation in the given timer queue to expire at the + // specified absolute time. + template + void schedule_timer(timer_queue& timer_queue, + const typename Time_Traits::time_type& time, timer_op* op, void* token) + { + mutex::scoped_lock lock(mutex_); + if (!shutdown_) + { + bool earliest = timer_queue.enqueue_timer(time, op, token); + io_service_.work_started(); + if (earliest) + interrupt(); + } + } + + // Cancel the timer operations associated with the given token. Returns the + // number of operations that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& timer_queue, void* token) + { + mutex::scoped_lock lock(mutex_); + op_queue ops; + std::size_t n = timer_queue.cancel_timer(token, ops); + lock.unlock(); + io_service_.post_deferred_completions(ops); + return n; + } + + // Run the kqueue loop. + void run(bool block, op_queue& ops) + { + mutex::scoped_lock lock(mutex_); + + // Determine how long to block while waiting for events. + timespec timeout_buf = { 0, 0 }; + timespec* timeout = block ? get_timeout(timeout_buf) : &timeout_buf; + + lock.unlock(); + + // Block on the kqueue descriptor. + struct kevent events[128]; + int num_events = kevent(kqueue_fd_, 0, 0, events, 128, timeout); + + // Dispatch the waiting events. + for (int i = 0; i < num_events; ++i) + { + int descriptor = events[i].ident; + void* ptr = events[i].udata; + if (ptr == &interrupter_) + { + // No need to reset the interrupter since we're leaving the descriptor + // in a ready-to-read state and relying on one-shot notifications. + } + else + { + descriptor_state* descriptor_data = static_cast(ptr); + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + + // Exception operations must be processed first to ensure that any + // out-of-band data is read before normal data. + static const int filter[max_ops] = + { EVFILT_READ, EVFILT_WRITE, EVFILT_READ }; + for (int j = max_ops - 1; j >= 0; --j) + { + if (events[i].filter == filter[j]) + { + if (j != except_op || events[i].flags & EV_OOBAND) + { + while (reactor_op* op = descriptor_data->op_queue_[j].front()) + { + if (events[i].flags & EV_ERROR) + { + op->ec_ = asio::error_code(events[i].data, + asio::error::get_system_category()); + descriptor_data->op_queue_[j].pop(); + ops.push(op); + } + if (op->perform()) + { + descriptor_data->op_queue_[j].pop(); + ops.push(op); + } + else + break; + } + } + } + } + + // Renew registration for event notifications. + struct kevent event; + switch (events[i].filter) + { + case EVFILT_READ: + if (!descriptor_data->op_queue_[read_op].empty()) + EV_SET(&event, descriptor, EVFILT_READ, + EV_ADD | EV_ONESHOT, 0, 0, descriptor_data); + else if (!descriptor_data->op_queue_[except_op].empty()) + EV_SET(&event, descriptor, EVFILT_READ, + EV_ADD | EV_ONESHOT, EV_OOBAND, 0, descriptor_data); + else + continue; + case EVFILT_WRITE: + if (!descriptor_data->op_queue_[write_op].empty()) + EV_SET(&event, descriptor, EVFILT_WRITE, + EV_ADD | EV_ONESHOT, 0, 0, descriptor_data); + else + continue; + default: + break; + } + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + asio::error_code error(errno, + asio::error::get_system_category()); + for (int j = 0; j < max_ops; ++j) + { + while (reactor_op* op = descriptor_data->op_queue_[j].front()) + { + op->ec_ = error; + descriptor_data->op_queue_[j].pop(); + ops.push(op); + } + } + } + } + } + + lock.lock(); + timer_queues_.get_ready_timers(ops); + } + + // Interrupt the kqueue loop. + void interrupt() + { + struct kevent event; + EV_SET(&event, interrupter_.read_descriptor(), + EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &interrupter_); + ::kevent(kqueue_fd_, &event, 1, 0, 0, 0); + } + +private: + // Create the kqueue file descriptor. Throws an exception if the descriptor + // cannot be created. + static int do_kqueue_create() + { + int fd = kqueue(); + if (fd == -1) + { + boost::throw_exception( + asio::system_error( + asio::error_code(errno, + asio::error::get_system_category()), + "kqueue")); + } + return fd; + } + + // Get the timeout value for the kevent call. + timespec* get_timeout(timespec& ts) + { + // By default we will wait no longer than 5 minutes. This will ensure that + // any changes to the system clock are detected after no longer than this. + long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000); + ts.tv_sec = usec / 1000000; + ts.tv_nsec = (usec % 1000000) * 1000; + return &ts; + } + + // The io_service implementation used to post completions. + io_service_impl& io_service_; + + // Mutex to protect access to internal data. + mutex mutex_; + + // The kqueue file descriptor. + int kqueue_fd_; + + // The interrupter is used to break a blocking kevent call. + select_interrupter interrupter_; + + // The timer queues. + timer_queue_set timer_queues_; + + // Whether the service has been shut down. + bool shutdown_; + + // Mutex to protect access to the registered descriptors. + mutex registered_descriptors_mutex_; + + // Keep track of all registered descriptors. This code relies on the fact that + // the hash_map implementation pools deleted nodes, meaning that we can assume + // our descriptor_state pointer remains valid even after the entry is removed. + // Technically this is not true for C++98, as that standard says that spliced + // elements in a list are invalidated. However, C++0x fixes this shortcoming + // so we'll just assume that C++98 std::list implementations will do the right + // thing anyway. + typedef detail::hash_map descriptor_map; + descriptor_map registered_descriptors_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(ASIO_HAS_KQUEUE) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_KQUEUE_REACTOR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/kqueue_reactor_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/kqueue_reactor_fwd.hpp new file mode 100644 index 00000000..abbc0c7d --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/kqueue_reactor_fwd.hpp @@ -0,0 +1,44 @@ +// +// kqueue_reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP +#define ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#if !defined(ASIO_DISABLE_KQUEUE) + +#if (defined(__MACH__) && defined(__APPLE__)) \ + || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + +// Define this to indicate that kqueue is supported on the target platform. +#define ASIO_HAS_KQUEUE 1 + +namespace asio { +namespace detail { + +class kqueue_reactor; + +} // namespace detail +} // namespace asio + +#endif // (defined(__MACH__) && defined(__APPLE__)) + // || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + +#endif // !defined(ASIO_DISABLE_KQUEUE) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/local_free_on_block_exit.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/local_free_on_block_exit.hpp new file mode 100644 index 00000000..554943c8 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/local_free_on_block_exit.hpp @@ -0,0 +1,59 @@ +// +// local_free_on_block_exit.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP +#define ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace detail { + +class local_free_on_block_exit + : private noncopyable +{ +public: + // Constructor blocks all signals for the calling thread. + explicit local_free_on_block_exit(void* p) + : p_(p) + { + } + + // Destructor restores the previous signal mask. + ~local_free_on_block_exit() + { + ::LocalFree(p_); + } + +private: + void* p_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/macos_fenced_block.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/macos_fenced_block.hpp new file mode 100644 index 00000000..3c303d62 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/macos_fenced_block.hpp @@ -0,0 +1,57 @@ +// +// macos_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP +#define ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(__MACH__) && defined(__APPLE__) + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +class macos_fenced_block + : private noncopyable +{ +public: + // Constructor. + macos_fenced_block() + { + OSMemoryBarrier(); + } + + // Destructor. + ~macos_fenced_block() + { + OSMemoryBarrier(); + } +}; + +} // namespace detail +} // namespace asio + +#endif // defined(__MACH__) && defined(__APPLE__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/mutex.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/mutex.hpp new file mode 100644 index 00000000..024ec7f4 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/mutex.hpp @@ -0,0 +1,50 @@ +// +// mutex.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_MUTEX_HPP +#define ASIO_DETAIL_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) +# include "asio/detail/null_mutex.hpp" +#elif defined(BOOST_WINDOWS) +# include "asio/detail/win_mutex.hpp" +#elif defined(BOOST_HAS_PTHREADS) +# include "asio/detail/posix_mutex.hpp" +#else +# error Only Windows and POSIX are supported! +#endif + +namespace asio { +namespace detail { + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) +typedef null_mutex mutex; +#elif defined(BOOST_WINDOWS) +typedef win_mutex mutex; +#elif defined(BOOST_HAS_PTHREADS) +typedef posix_mutex mutex; +#endif + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_MUTEX_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/noncopyable.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/noncopyable.hpp new file mode 100644 index 00000000..8b73ff04 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/noncopyable.hpp @@ -0,0 +1,55 @@ +// +// noncopyable.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_NONCOPYABLE_HPP +#define ASIO_DETAIL_NONCOPYABLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +// Redefine the noncopyable class for Borland C++ since that compiler does not +// apply the empty base optimisation unless the base class contains a dummy +// char data member. +class noncopyable +{ +protected: + noncopyable() {} + ~noncopyable() {} +private: + noncopyable(const noncopyable&); + const noncopyable& operator=(const noncopyable&); + char dummy_; +}; +#else +using boost::noncopyable; +#endif + +} // namespace detail + +using asio::detail::noncopyable; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_NONCOPYABLE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/null_buffers_op.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/null_buffers_op.hpp new file mode 100644 index 00000000..b44de2f0 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/null_buffers_op.hpp @@ -0,0 +1,77 @@ +// +// null_buffers_op.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_NULL_BUFFERS_OP_HPP +#define ASIO_DETAIL_NULL_BUFFERS_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/reactor_op.hpp" + +namespace asio { +namespace detail { + +template +class null_buffers_op : public reactor_op +{ +public: + null_buffers_op(Handler handler) + : reactor_op(&null_buffers_op::do_perform, &null_buffers_op::do_complete), + handler_(handler) + { + } + + static bool do_perform(reactor_op*) + { + return true; + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + null_buffers_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an upcall, + // a sub-object of the handler may be the true owner of the memory + // associated with the handler. Consequently, a local copy of the handler + // is required to ensure that any owning sub-object remains valid until + // after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_NULL_BUFFERS_OP_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/null_event.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/null_event.hpp new file mode 100644 index 00000000..bcea31b8 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/null_event.hpp @@ -0,0 +1,77 @@ +// +// null_event.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_NULL_EVENT_HPP +#define ASIO_DETAIL_NULL_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) + +#include "asio/detail/noncopyable.hpp" + +namespace asio { +namespace detail { + +class null_event + : private noncopyable +{ +public: + // Constructor. + null_event() + { + } + + // Destructor. + ~null_event() + { + } + + // Signal the event. + template + void signal(Lock&) + { + } + + // Signal the event and unlock the mutex. + template + void signal_and_unlock(Lock&) + { + } + + // Reset the event. + template + void clear(Lock&) + { + } + + // Wait for the event to become signalled. + template + void wait(Lock&) + { + } +}; + +} // namespace detail +} // namespace asio + +#endif // !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_NULL_EVENT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/null_fenced_block.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/null_fenced_block.hpp new file mode 100644 index 00000000..dd9a095a --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/null_fenced_block.hpp @@ -0,0 +1,43 @@ +// +// null_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_NULL_FENCED_BLOCK_HPP +#define ASIO_DETAIL_NULL_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class null_fenced_block + : private noncopyable +{ +public: + // Constructor. + null_fenced_block() + { + } + + // Destructor. + ~null_fenced_block() + { + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_NULL_FENCED_BLOCK_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/null_mutex.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/null_mutex.hpp new file mode 100644 index 00000000..6661ef83 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/null_mutex.hpp @@ -0,0 +1,66 @@ +// +// null_mutex.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_NULL_MUTEX_HPP +#define ASIO_DETAIL_NULL_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/scoped_lock.hpp" + +namespace asio { +namespace detail { + +class null_mutex + : private noncopyable +{ +public: + typedef asio::detail::scoped_lock scoped_lock; + + // Constructor. + null_mutex() + { + } + + // Destructor. + ~null_mutex() + { + } + + // Lock the mutex. + void lock() + { + } + + // Unlock the mutex. + void unlock() + { + } +}; + +} // namespace detail +} // namespace asio + +#endif // !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_NULL_MUTEX_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/null_signal_blocker.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/null_signal_blocker.hpp new file mode 100644 index 00000000..a5db315a --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/null_signal_blocker.hpp @@ -0,0 +1,63 @@ +// +// null_signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP +#define ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) + +#include "asio/detail/noncopyable.hpp" + +namespace asio { +namespace detail { + +class null_signal_blocker + : private noncopyable +{ +public: + // Constructor blocks all signals for the calling thread. + null_signal_blocker() + { + } + + // Destructor restores the previous signal mask. + ~null_signal_blocker() + { + } + + // Block all signals for the calling thread. + void block() + { + } + + // Restore the previous signal mask. + void unblock() + { + } +}; + +} // namespace detail +} // namespace asio + +#endif // !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/null_thread.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/null_thread.hpp new file mode 100644 index 00000000..d96883f3 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/null_thread.hpp @@ -0,0 +1,68 @@ +// +// null_thread.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_NULL_THREAD_HPP +#define ASIO_DETAIL_NULL_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/noncopyable.hpp" + +namespace asio { +namespace detail { + +class null_thread + : private noncopyable +{ +public: + // Constructor. + template + null_thread(Function f) + { + asio::system_error e( + asio::error::operation_not_supported, "thread"); + boost::throw_exception(e); + } + + // Destructor. + ~null_thread() + { + } + + // Wait for the thread to exit. + void join() + { + } +}; + +} // namespace detail +} // namespace asio + +#endif // !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_NULL_THREAD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/null_tss_ptr.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/null_tss_ptr.hpp new file mode 100644 index 00000000..112b4761 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/null_tss_ptr.hpp @@ -0,0 +1,70 @@ +// +// null_tss_ptr.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_NULL_TSS_PTR_HPP +#define ASIO_DETAIL_NULL_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) + +#include "asio/detail/noncopyable.hpp" + +namespace asio { +namespace detail { + +template +class null_tss_ptr + : private noncopyable +{ +public: + // Constructor. + null_tss_ptr() + : value_(0) + { + } + + // Destructor. + ~null_tss_ptr() + { + } + + // Get the value. + operator T*() const + { + return value_; + } + + // Set the value. + void operator=(T* value) + { + value_ = value; + } + +private: + T* value_; +}; + +} // namespace detail +} // namespace asio + +#endif // !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_NULL_TSS_PTR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/old_win_sdk_compat.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/old_win_sdk_compat.hpp new file mode 100644 index 00000000..70e5916d --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/old_win_sdk_compat.hpp @@ -0,0 +1,340 @@ +// +// old_win_sdk_compat.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP +#define ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +// Guess whether we are building against on old Platform SDK. +#if !defined(IN6ADDR_ANY_INIT) +#define ASIO_HAS_OLD_WIN_SDK 1 +#endif // !defined(IN6ADDR_ANY_INIT) + +#if defined(ASIO_HAS_OLD_WIN_SDK) + +// Emulation of types that are missing from old Platform SDKs. +// +// N.B. this emulation is also used if building for a Windows 2000 target with +// a recent (i.e. Vista or later) SDK, as the SDK does not provide IPv6 support +// in that case. + +namespace asio { +namespace detail { + +enum +{ + sockaddr_storage_maxsize = 128, // Maximum size. + sockaddr_storage_alignsize = (sizeof(__int64)), // Desired alignment. + sockaddr_storage_pad1size = (sockaddr_storage_alignsize - sizeof(short)), + sockaddr_storage_pad2size = (sockaddr_storage_maxsize - + (sizeof(short) + sockaddr_storage_pad1size + sockaddr_storage_alignsize)) +}; + +struct sockaddr_storage_emulation +{ + short ss_family; + char __ss_pad1[sockaddr_storage_pad1size]; + __int64 __ss_align; + char __ss_pad2[sockaddr_storage_pad2size]; +}; + +struct in6_addr_emulation +{ + union + { + u_char Byte[16]; + u_short Word[8]; + } u; +}; + +#if !defined(s6_addr) +# define _S6_un u +# define _S6_u8 Byte +# define s6_addr _S6_un._S6_u8 +#endif // !defined(s6_addr) + +struct sockaddr_in6_emulation +{ + short sin6_family; + u_short sin6_port; + u_long sin6_flowinfo; + in6_addr_emulation sin6_addr; + u_long sin6_scope_id; +}; + +struct ipv6_mreq_emulation +{ + in6_addr_emulation ipv6mr_multiaddr; + unsigned int ipv6mr_interface; +}; + +#if !defined(IN6ADDR_ANY_INIT) +# define IN6ADDR_ANY_INIT { 0 } +#endif + +#if !defined(IN6ADDR_LOOPBACK_INIT) +# define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } +#endif + +struct addrinfo_emulation +{ + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + char* ai_canonname; + sockaddr* ai_addr; + addrinfo_emulation* ai_next; +}; + +#if !defined(AI_PASSIVE) +# define AI_PASSIVE 0x1 +#endif + +#if !defined(AI_CANONNAME) +# define AI_CANONNAME 0x2 +#endif + +#if !defined(AI_NUMERICHOST) +# define AI_NUMERICHOST 0x4 +#endif + +#if !defined(EAI_AGAIN) +# define EAI_AGAIN WSATRY_AGAIN +#endif + +#if !defined(EAI_BADFLAGS) +# define EAI_BADFLAGS WSAEINVAL +#endif + +#if !defined(EAI_FAIL) +# define EAI_FAIL WSANO_RECOVERY +#endif + +#if !defined(EAI_FAMILY) +# define EAI_FAMILY WSAEAFNOSUPPORT +#endif + +#if !defined(EAI_MEMORY) +# define EAI_MEMORY WSA_NOT_ENOUGH_MEMORY +#endif + +#if !defined(EAI_NODATA) +# define EAI_NODATA WSANO_DATA +#endif + +#if !defined(EAI_NONAME) +# define EAI_NONAME WSAHOST_NOT_FOUND +#endif + +#if !defined(EAI_SERVICE) +# define EAI_SERVICE WSATYPE_NOT_FOUND +#endif + +#if !defined(EAI_SOCKTYPE) +# define EAI_SOCKTYPE WSAESOCKTNOSUPPORT +#endif + +#if !defined(NI_NOFQDN) +# define NI_NOFQDN 0x01 +#endif + +#if !defined(NI_NUMERICHOST) +# define NI_NUMERICHOST 0x02 +#endif + +#if !defined(NI_NAMEREQD) +# define NI_NAMEREQD 0x04 +#endif + +#if !defined(NI_NUMERICSERV) +# define NI_NUMERICSERV 0x08 +#endif + +#if !defined(NI_DGRAM) +# define NI_DGRAM 0x10 +#endif + +#if !defined(IPPROTO_IPV6) +# define IPPROTO_IPV6 41 +#endif + +#if !defined(IPV6_UNICAST_HOPS) +# define IPV6_UNICAST_HOPS 4 +#endif + +#if !defined(IPV6_MULTICAST_IF) +# define IPV6_MULTICAST_IF 9 +#endif + +#if !defined(IPV6_MULTICAST_HOPS) +# define IPV6_MULTICAST_HOPS 10 +#endif + +#if !defined(IPV6_MULTICAST_LOOP) +# define IPV6_MULTICAST_LOOP 11 +#endif + +#if !defined(IPV6_JOIN_GROUP) +# define IPV6_JOIN_GROUP 12 +#endif + +#if !defined(IPV6_LEAVE_GROUP) +# define IPV6_LEAVE_GROUP 13 +#endif + +inline int IN6_IS_ADDR_UNSPECIFIED(const in6_addr_emulation* a) +{ + return ((a->s6_addr[0] == 0) + && (a->s6_addr[1] == 0) + && (a->s6_addr[2] == 0) + && (a->s6_addr[3] == 0) + && (a->s6_addr[4] == 0) + && (a->s6_addr[5] == 0) + && (a->s6_addr[6] == 0) + && (a->s6_addr[7] == 0) + && (a->s6_addr[8] == 0) + && (a->s6_addr[9] == 0) + && (a->s6_addr[10] == 0) + && (a->s6_addr[11] == 0) + && (a->s6_addr[12] == 0) + && (a->s6_addr[13] == 0) + && (a->s6_addr[14] == 0) + && (a->s6_addr[15] == 0)); +} + +inline int IN6_IS_ADDR_LOOPBACK(const in6_addr_emulation* a) +{ + return ((a->s6_addr[0] == 0) + && (a->s6_addr[1] == 0) + && (a->s6_addr[2] == 0) + && (a->s6_addr[3] == 0) + && (a->s6_addr[4] == 0) + && (a->s6_addr[5] == 0) + && (a->s6_addr[6] == 0) + && (a->s6_addr[7] == 0) + && (a->s6_addr[8] == 0) + && (a->s6_addr[9] == 0) + && (a->s6_addr[10] == 0) + && (a->s6_addr[11] == 0) + && (a->s6_addr[12] == 0) + && (a->s6_addr[13] == 0) + && (a->s6_addr[14] == 0) + && (a->s6_addr[15] == 1)); +} + +inline int IN6_IS_ADDR_MULTICAST(const in6_addr_emulation* a) +{ + return (a->s6_addr[0] == 0xff); +} + +inline int IN6_IS_ADDR_LINKLOCAL(const in6_addr_emulation* a) +{ + return ((a->s6_addr[0] == 0xfe) && ((a->s6_addr[1] & 0xc0) == 0x80)); +} + +inline int IN6_IS_ADDR_SITELOCAL(const in6_addr_emulation* a) +{ + return ((a->s6_addr[0] == 0xfe) && ((a->s6_addr[1] & 0xc0) == 0xc0)); +} + +inline int IN6_IS_ADDR_V4MAPPED(const in6_addr_emulation* a) +{ + return ((a->s6_addr[0] == 0) + && (a->s6_addr[1] == 0) + && (a->s6_addr[2] == 0) + && (a->s6_addr[3] == 0) + && (a->s6_addr[4] == 0) + && (a->s6_addr[5] == 0) + && (a->s6_addr[6] == 0) + && (a->s6_addr[7] == 0) + && (a->s6_addr[8] == 0) + && (a->s6_addr[9] == 0) + && (a->s6_addr[10] == 0xff) + && (a->s6_addr[11] == 0xff)); +} + +inline int IN6_IS_ADDR_V4COMPAT(const in6_addr_emulation* a) +{ + return ((a->s6_addr[0] == 0) + && (a->s6_addr[1] == 0) + && (a->s6_addr[2] == 0) + && (a->s6_addr[3] == 0) + && (a->s6_addr[4] == 0) + && (a->s6_addr[5] == 0) + && (a->s6_addr[6] == 0) + && (a->s6_addr[7] == 0) + && (a->s6_addr[8] == 0) + && (a->s6_addr[9] == 0) + && (a->s6_addr[10] == 0xff) + && (a->s6_addr[11] == 0xff) + && !((a->s6_addr[12] == 0) + && (a->s6_addr[13] == 0) + && (a->s6_addr[14] == 0) + && ((a->s6_addr[15] == 0) || (a->s6_addr[15] == 1)))); +} + +inline int IN6_IS_ADDR_MC_NODELOCAL(const in6_addr_emulation* a) +{ + return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 1); +} + +inline int IN6_IS_ADDR_MC_LINKLOCAL(const in6_addr_emulation* a) +{ + return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 2); +} + +inline int IN6_IS_ADDR_MC_SITELOCAL(const in6_addr_emulation* a) +{ + return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 5); +} + +inline int IN6_IS_ADDR_MC_ORGLOCAL(const in6_addr_emulation* a) +{ + return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 8); +} + +inline int IN6_IS_ADDR_MC_GLOBAL(const in6_addr_emulation* a) +{ + return IN6_IS_ADDR_MULTICAST(a) && ((a->s6_addr[1] & 0xf) == 0xe); +} + +} // namespace detail +} // namespace asio + +#endif // defined(ASIO_HAS_OLD_WIN_SDK) + +// Even newer Platform SDKs that support IPv6 may not define IPV6_V6ONLY. +#if !defined(IPV6_V6ONLY) +# define IPV6_V6ONLY 27 +#endif + +// Some SDKs (e.g. Windows CE) don't define IPPROTO_ICMPV6. +#if !defined(IPPROTO_ICMPV6) +# define IPPROTO_ICMPV6 58 +#endif + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/op_queue.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/op_queue.hpp new file mode 100644 index 00000000..ccf8b9a5 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/op_queue.hpp @@ -0,0 +1,156 @@ +// +// op_queue.hpp +// ~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_OP_QUEUE_HPP +#define ASIO_DETAIL_OP_QUEUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/noncopyable.hpp" + +namespace asio { +namespace detail { + +template +class op_queue; + +class op_queue_access +{ +public: + template + static Operation* next(Operation* o) + { + return static_cast(o->next_); + } + + template + static void next(Operation1*& o1, Operation2* o2) + { + o1->next_ = o2; + } + + template + static void destroy(Operation* o) + { + o->destroy(); + } + + template + static Operation*& front(op_queue& q) + { + return q.front_; + } + + template + static Operation*& back(op_queue& q) + { + return q.back_; + } +}; + +template +class op_queue + : private noncopyable +{ +public: + // Constructor. + op_queue() + : front_(0), + back_(0) + { + } + + // Destructor destroys all operations. + ~op_queue() + { + while (Operation* op = front_) + { + pop(); + op_queue_access::destroy(op); + } + } + + // Get the operation at the front of the queue. + Operation* front() + { + return front_; + } + + // Pop an operation from the front of the queue. + void pop() + { + if (front_) + { + Operation* tmp = front_; + front_ = op_queue_access::next(front_); + if (front_ == 0) + back_ = 0; + op_queue_access::next(tmp, static_cast(0)); + } + } + + // Push an operation on to the back of the queue. + void push(Operation* h) + { + op_queue_access::next(h, static_cast(0)); + if (back_) + { + op_queue_access::next(back_, h); + back_ = h; + } + else + { + front_ = back_ = h; + } + } + + // Push all operations from another queue on to the back of the queue. The + // source queue may contain operations of a derived type. + template + void push(op_queue& q) + { + if (Operation* other_front = op_queue_access::front(q)) + { + if (back_) + op_queue_access::next(back_, other_front); + else + front_ = other_front; + back_ = op_queue_access::back(q); + op_queue_access::front(q) = 0; + op_queue_access::back(q) = 0; + } + } + + // Whether the queue is empty. + bool empty() const + { + return front_ == 0; + } + +private: + friend class op_queue_access; + + // The front of the queue. + Operation* front_; + + // The back of the queue. + Operation* back_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_OP_QUEUE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/operation.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/operation.hpp new file mode 100644 index 00000000..6aba3612 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/operation.hpp @@ -0,0 +1,43 @@ +// +// operation.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_OPERATION_HPP +#define ASIO_DETAIL_OPERATION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/win_iocp_io_service_fwd.hpp" + +#if defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_operation.hpp" +#else +# include "asio/detail/reactor_fwd.hpp" +# include "asio/detail/task_io_service_operation.hpp" +#endif + +namespace asio { +namespace detail { + +#if defined(ASIO_HAS_IOCP) +typedef win_iocp_operation operation; +#else +typedef task_io_service_operation operation; +#endif + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_OPERATION_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/pipe_select_interrupter.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/pipe_select_interrupter.hpp new file mode 100644 index 00000000..74695994 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/pipe_select_interrupter.hpp @@ -0,0 +1,120 @@ +// +// pipe_select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP +#define ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace detail { + +class pipe_select_interrupter +{ +public: + // Constructor. + pipe_select_interrupter() + { + int pipe_fds[2]; + if (pipe(pipe_fds) == 0) + { + read_descriptor_ = pipe_fds[0]; + ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); + write_descriptor_ = pipe_fds[1]; + ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK); + } + else + { + asio::error_code ec(errno, + asio::error::get_system_category()); + asio::system_error e(ec, "pipe_select_interrupter"); + boost::throw_exception(e); + } + } + + // Destructor. + ~pipe_select_interrupter() + { + if (read_descriptor_ != -1) + ::close(read_descriptor_); + if (write_descriptor_ != -1) + ::close(write_descriptor_); + } + + // Interrupt the select call. + void interrupt() + { + char byte = 0; + int result = ::write(write_descriptor_, &byte, 1); + (void)result; + } + + // Reset the select interrupt. Returns true if the call was interrupted. + bool reset() + { + for (;;) + { + char data[1024]; + int bytes_read = ::read(read_descriptor_, data, sizeof(data)); + if (bytes_read < 0 && errno == EINTR) + continue; + bool was_interrupted = (bytes_read > 0); + while (bytes_read == sizeof(data)) + bytes_read = ::read(read_descriptor_, data, sizeof(data)); + return was_interrupted; + } + } + + // Get the read descriptor to be passed to select. + int read_descriptor() const + { + return read_descriptor_; + } + +private: + // The read end of a connection used to interrupt the select call. This file + // descriptor is passed to select such that when it is time to stop, a single + // byte will be written on the other end of the connection and this + // descriptor will become readable. + int read_descriptor_; + + // The write end of a connection used to interrupt the select call. A single + // byte may be written to this to wake up the select which is waiting for the + // other end to become readable. + int write_descriptor_; +}; + +} // namespace detail +} // namespace asio + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/pop_options.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/pop_options.hpp new file mode 100644 index 00000000..a26b2039 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/pop_options.hpp @@ -0,0 +1,88 @@ +// +// pop_options.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// No header guard + +#if defined(__COMO__) + +// Comeau C++ + +#elif defined(__DMC__) + +// Digital Mars C++ + +#elif defined(__INTEL_COMPILER) || defined(__ICL) \ + || defined(__ICC) || defined(__ECC) + +// Intel C++ + +#elif defined(__GNUC__) + +// GNU C++ + +# if defined(__MINGW32__) || defined(__CYGWIN__) +# pragma pack (pop) +# endif + +#elif defined(__KCC) + +// Kai C++ + +#elif defined(__sgi) + +// SGI MIPSpro C++ + +#elif defined(__DECCXX) + +// Compaq Tru64 Unix cxx + +#elif defined(__ghs) + +// Greenhills C++ + +#elif defined(__BORLANDC__) + +// Borland C++ + +# pragma option pop +# pragma nopushoptwarn +# pragma nopackwarning + +#elif defined(__MWERKS__) + +// Metrowerks CodeWarrior + +#elif defined(__SUNPRO_CC) + +// Sun Workshop Compiler C++ + +#elif defined(__HP_aCC) + +// HP aCC + +#elif defined(__MRC__) || defined(__SC__) + +// MPW MrCpp or SCpp + +#elif defined(__IBMCPP__) + +// IBM Visual Age + +#elif defined(_MSC_VER) + +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for example) +// also #define _MSC_VER + +# pragma warning (pop) +# pragma pack (pop) + +#endif diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/posix_event.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/posix_event.hpp new file mode 100644 index 00000000..49c15aa5 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/posix_event.hpp @@ -0,0 +1,114 @@ +// +// posix_event.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_POSIX_EVENT_HPP +#define ASIO_DETAIL_POSIX_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_HAS_PTHREADS) + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/noncopyable.hpp" + +namespace asio { +namespace detail { + +class posix_event + : private noncopyable +{ +public: + // Constructor. + posix_event() + : signalled_(false) + { + int error = ::pthread_cond_init(&cond_, 0); + if (error != 0) + { + asio::system_error e( + asio::error_code(error, + asio::error::get_system_category()), + "event"); + boost::throw_exception(e); + } + } + + // Destructor. + ~posix_event() + { + ::pthread_cond_destroy(&cond_); + } + + // Signal the event. + template + void signal(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + (void)lock; + signalled_ = true; + ::pthread_cond_signal(&cond_); // Ignore EINVAL. + } + + // Signal the event and unlock the mutex. + template + void signal_and_unlock(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + signalled_ = true; + lock.unlock(); + ::pthread_cond_signal(&cond_); // Ignore EINVAL. + } + + // Reset the event. + template + void clear(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + (void)lock; + signalled_ = false; + } + + // Wait for the event to become signalled. + template + void wait(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + while (!signalled_) + ::pthread_cond_wait(&cond_, &lock.mutex().mutex_); // Ignore EINVAL. + } + +private: + ::pthread_cond_t cond_; + bool signalled_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_HAS_PTHREADS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_POSIX_EVENT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/posix_fd_set_adapter.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/posix_fd_set_adapter.hpp new file mode 100644 index 00000000..17ef269c --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/posix_fd_set_adapter.hpp @@ -0,0 +1,81 @@ +// +// posix_fd_set_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP +#define ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/socket_types.hpp" + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +namespace asio { +namespace detail { + +// Adapts the FD_SET type to meet the Descriptor_Set concept's requirements. +class posix_fd_set_adapter +{ +public: + posix_fd_set_adapter() + : max_descriptor_(invalid_socket) + { + using namespace std; // Needed for memset on Solaris. + FD_ZERO(&fd_set_); + } + + bool set(socket_type descriptor) + { + if (descriptor < (socket_type)FD_SETSIZE) + { + if (max_descriptor_ == invalid_socket || descriptor > max_descriptor_) + max_descriptor_ = descriptor; + FD_SET(descriptor, &fd_set_); + return true; + } + return false; + } + + bool is_set(socket_type descriptor) const + { + return FD_ISSET(descriptor, &fd_set_) != 0; + } + + operator fd_set*() + { + return &fd_set_; + } + + socket_type max_descriptor() const + { + return max_descriptor_; + } + +private: + mutable fd_set fd_set_; + socket_type max_descriptor_; +}; + +} // namespace detail +} // namespace asio + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/posix_mutex.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/posix_mutex.hpp new file mode 100644 index 00000000..230b83a3 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/posix_mutex.hpp @@ -0,0 +1,91 @@ +// +// posix_mutex.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_POSIX_MUTEX_HPP +#define ASIO_DETAIL_POSIX_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_HAS_PTHREADS) + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/scoped_lock.hpp" + +namespace asio { +namespace detail { + +class posix_event; + +class posix_mutex + : private noncopyable +{ +public: + typedef asio::detail::scoped_lock scoped_lock; + + // Constructor. + posix_mutex() + { + int error = ::pthread_mutex_init(&mutex_, 0); + if (error != 0) + { + asio::system_error e( + asio::error_code(error, + asio::error::get_system_category()), + "mutex"); + boost::throw_exception(e); + } + } + + // Destructor. + ~posix_mutex() + { + ::pthread_mutex_destroy(&mutex_); // Ignore EBUSY. + } + + // Lock the mutex. + void lock() + { + (void)::pthread_mutex_lock(&mutex_); // Ignore EINVAL. + } + + // Unlock the mutex. + void unlock() + { + (void)::pthread_mutex_unlock(&mutex_); // Ignore EINVAL. + } + +private: + friend class posix_event; + ::pthread_mutex_t mutex_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_HAS_PTHREADS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_POSIX_MUTEX_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/posix_signal_blocker.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/posix_signal_blocker.hpp new file mode 100644 index 00000000..135ca41b --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/posix_signal_blocker.hpp @@ -0,0 +1,90 @@ +// +// posix_signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP +#define ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_HAS_PTHREADS) + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/noncopyable.hpp" + +namespace asio { +namespace detail { + +class posix_signal_blocker + : private noncopyable +{ +public: + // Constructor blocks all signals for the calling thread. + posix_signal_blocker() + : blocked_(false) + { + sigset_t new_mask; + sigfillset(&new_mask); + blocked_ = (pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask_) == 0); + } + + // Destructor restores the previous signal mask. + ~posix_signal_blocker() + { + if (blocked_) + pthread_sigmask(SIG_SETMASK, &old_mask_, 0); + } + + // Block all signals for the calling thread. + void block() + { + if (!blocked_) + { + sigset_t new_mask; + sigfillset(&new_mask); + blocked_ = (pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask_) == 0); + } + } + + // Restore the previous signal mask. + void unblock() + { + if (blocked_) + blocked_ = (pthread_sigmask(SIG_SETMASK, &old_mask_, 0) != 0); + } + +private: + // Have signals been blocked. + bool blocked_; + + // The previous signal mask. + sigset_t old_mask_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_HAS_PTHREADS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/posix_thread.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/posix_thread.hpp new file mode 100644 index 00000000..e0fea751 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/posix_thread.hpp @@ -0,0 +1,129 @@ +// +// posix_thread.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_POSIX_THREAD_HPP +#define ASIO_DETAIL_POSIX_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_HAS_PTHREADS) + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/noncopyable.hpp" + +namespace asio { +namespace detail { + +extern "C" void* asio_detail_posix_thread_function(void* arg); + +class posix_thread + : private noncopyable +{ +public: + // Constructor. + template + posix_thread(Function f) + : joined_(false) + { + std::auto_ptr arg(new func(f)); + int error = ::pthread_create(&thread_, 0, + asio_detail_posix_thread_function, arg.get()); + if (error != 0) + { + asio::system_error e( + asio::error_code(error, + asio::error::get_system_category()), + "thread"); + boost::throw_exception(e); + } + arg.release(); + } + + // Destructor. + ~posix_thread() + { + if (!joined_) + ::pthread_detach(thread_); + } + + // Wait for the thread to exit. + void join() + { + if (!joined_) + { + ::pthread_join(thread_, 0); + joined_ = true; + } + } + +private: + friend void* asio_detail_posix_thread_function(void* arg); + + class func_base + { + public: + virtual ~func_base() {} + virtual void run() = 0; + }; + + template + class func + : public func_base + { + public: + func(Function f) + : f_(f) + { + } + + virtual void run() + { + f_(); + } + + private: + Function f_; + }; + + ::pthread_t thread_; + bool joined_; +}; + +inline void* asio_detail_posix_thread_function(void* arg) +{ + std::auto_ptr f( + static_cast(arg)); + f->run(); + return 0; +} + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_HAS_PTHREADS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_POSIX_THREAD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/posix_tss_ptr.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/posix_tss_ptr.hpp new file mode 100644 index 00000000..3b4ba07b --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/posix_tss_ptr.hpp @@ -0,0 +1,88 @@ +// +// posix_tss_ptr.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_POSIX_TSS_PTR_HPP +#define ASIO_DETAIL_POSIX_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_HAS_PTHREADS) + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/noncopyable.hpp" + +namespace asio { +namespace detail { + +template +class posix_tss_ptr + : private noncopyable +{ +public: + // Constructor. + posix_tss_ptr() + { + int error = ::pthread_key_create(&tss_key_, 0); + if (error != 0) + { + asio::system_error e( + asio::error_code(error, + asio::error::get_system_category()), + "tss"); + boost::throw_exception(e); + } + } + + // Destructor. + ~posix_tss_ptr() + { + ::pthread_key_delete(tss_key_); + } + + // Get the value. + operator T*() const + { + return static_cast(::pthread_getspecific(tss_key_)); + } + + // Set the value. + void operator=(T* value) + { + ::pthread_setspecific(tss_key_, value); + } + +private: + // Thread-specific storage to allow unlocked access to determine whether a + // thread is a member of the pool. + pthread_key_t tss_key_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_HAS_PTHREADS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_POSIX_TSS_PTR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/push_options.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/push_options.hpp new file mode 100644 index 00000000..cb0e9024 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/push_options.hpp @@ -0,0 +1,114 @@ +// +// push_options.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// No header guard + +#if defined(__COMO__) + +// Comeau C++ + +#elif defined(__DMC__) + +// Digital Mars C++ + +#elif defined(__INTEL_COMPILER) || defined(__ICL) \ + || defined(__ICC) || defined(__ECC) + +// Intel C++ + +#elif defined(__GNUC__) + +// GNU C++ + +# if defined(__MINGW32__) || defined(__CYGWIN__) +# pragma pack (push, 8) +# endif + +#elif defined(__KCC) + +// Kai C++ + +#elif defined(__sgi) + +// SGI MIPSpro C++ + +#elif defined(__DECCXX) + +// Compaq Tru64 Unix cxx + +#elif defined(__ghs) + +// Greenhills C++ + +#elif defined(__BORLANDC__) + +// Borland C++ + +# pragma option push -a8 -b -Ve- -Vx- -w-inl -vi- +# pragma nopushoptwarn +# pragma nopackwarning +# if !defined(__MT__) +# error Multithreaded RTL must be selected. +# endif // !defined(__MT__) + +#elif defined(__MWERKS__) + +// Metrowerks CodeWarrior + +#elif defined(__SUNPRO_CC) + +// Sun Workshop Compiler C++ + +#elif defined(__HP_aCC) + +// HP aCC + +#elif defined(__MRC__) || defined(__SC__) + +// MPW MrCpp or SCpp + +#elif defined(__IBMCPP__) + +// IBM Visual Age + +#elif defined(_MSC_VER) + +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for example) +// also #define _MSC_VER + +# pragma warning (disable:4103) +# pragma warning (push) +# pragma warning (disable:4127) +# pragma warning (disable:4244) +# pragma warning (disable:4355) +# pragma warning (disable:4512) +# pragma warning (disable:4675) +# if defined(_M_IX86) && defined(_Wp64) +// The /Wp64 option is broken. If you want to check 64 bit portability, use a +// 64 bit compiler! +# pragma warning (disable:4311) +# pragma warning (disable:4312) +# endif // defined(_M_IX86) && defined(_Wp64) +# pragma pack (push, 8) +// Note that if the /Og optimisation flag is enabled with MSVC6, the compiler +// has a tendency to incorrectly optimise away some calls to member template +// functions, even though those functions contain code that should not be +// optimised away! Therefore we will always disable this optimisation option +// for the MSVC6 compiler. +# if (_MSC_VER < 1300) +# pragma optimize ("g", off) +# endif +# if !defined(_MT) +# error Multithreaded RTL must be selected. +# endif // !defined(_MT) + +#endif diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/reactive_descriptor_service.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/reactive_descriptor_service.hpp new file mode 100644 index 00000000..7ad368d7 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/reactive_descriptor_service.hpp @@ -0,0 +1,668 @@ +// +// reactive_descriptor_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_REACTIVE_DESCRIPTOR_SERVICE_HPP +#define ASIO_DETAIL_REACTIVE_DESCRIPTOR_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/buffer.hpp" +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/descriptor_ops.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/null_buffers_op.hpp" +#include "asio/detail/reactor.hpp" +#include "asio/detail/reactor_op.hpp" + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +namespace asio { +namespace detail { + +class reactive_descriptor_service +{ +public: + // The native type of a descriptor. + typedef int native_type; + + // The implementation type of the descriptor. + class implementation_type + : private asio::detail::noncopyable + { + public: + // Default constructor. + implementation_type() + : descriptor_(-1), + flags_(0) + { + } + + private: + // Only this service will have access to the internal values. + friend class reactive_descriptor_service; + + // The native descriptor representation. + int descriptor_; + + enum + { + // The user wants a non-blocking descriptor. + user_set_non_blocking = 1, + + // The descriptor has been set non-blocking. + internal_non_blocking = 2, + + // Helper "flag" used to determine whether the descriptor is non-blocking. + non_blocking = user_set_non_blocking | internal_non_blocking + }; + + // Flags indicating the current state of the descriptor. + unsigned char flags_; + + // Per-descriptor data used by the reactor. + reactor::per_descriptor_data reactor_data_; + }; + + // The maximum number of buffers to support in a single operation. + enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len }; + + // Constructor. + reactive_descriptor_service(asio::io_service& io_service) + : io_service_impl_(asio::use_service(io_service)), + reactor_(asio::use_service(io_service)) + { + reactor_.init_task(); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + // Construct a new descriptor implementation. + void construct(implementation_type& impl) + { + impl.descriptor_ = -1; + impl.flags_ = 0; + } + + // Destroy a descriptor implementation. + void destroy(implementation_type& impl) + { + if (impl.descriptor_ != -1) + { + reactor_.close_descriptor(impl.descriptor_, impl.reactor_data_); + + if (impl.flags_ & implementation_type::internal_non_blocking) + { + ioctl_arg_type non_blocking = 0; + asio::error_code ignored_ec; + descriptor_ops::ioctl(impl.descriptor_, + FIONBIO, &non_blocking, ignored_ec); + impl.flags_ &= ~implementation_type::internal_non_blocking; + } + + asio::error_code ignored_ec; + descriptor_ops::close(impl.descriptor_, ignored_ec); + + impl.descriptor_ = -1; + } + } + + // Assign a native descriptor to a descriptor implementation. + asio::error_code assign(implementation_type& impl, + const native_type& native_descriptor, asio::error_code& ec) + { + if (is_open(impl)) + { + ec = asio::error::already_open; + return ec; + } + + if (int err = reactor_.register_descriptor( + native_descriptor, impl.reactor_data_)) + { + ec = asio::error_code(err, + asio::error::get_system_category()); + return ec; + } + + impl.descriptor_ = native_descriptor; + impl.flags_ = 0; + ec = asio::error_code(); + return ec; + } + + // Determine whether the descriptor is open. + bool is_open(const implementation_type& impl) const + { + return impl.descriptor_ != -1; + } + + // Destroy a descriptor implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + if (is_open(impl)) + { + reactor_.close_descriptor(impl.descriptor_, impl.reactor_data_); + + if (impl.flags_ & implementation_type::internal_non_blocking) + { + ioctl_arg_type non_blocking = 0; + asio::error_code ignored_ec; + descriptor_ops::ioctl(impl.descriptor_, + FIONBIO, &non_blocking, ignored_ec); + impl.flags_ &= ~implementation_type::internal_non_blocking; + } + + if (descriptor_ops::close(impl.descriptor_, ec) == -1) + return ec; + + impl.descriptor_ = -1; + } + + ec = asio::error_code(); + return ec; + } + + // Get the native descriptor representation. + native_type native(const implementation_type& impl) const + { + return impl.descriptor_; + } + + // Cancel all operations associated with the descriptor. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + reactor_.cancel_ops(impl.descriptor_, impl.reactor_data_); + ec = asio::error_code(); + return ec; + } + + // Perform an IO control command on the descriptor. + template + asio::error_code io_control(implementation_type& impl, + IO_Control_Command& command, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + descriptor_ops::ioctl(impl.descriptor_, command.name(), + static_cast(command.data()), ec); + + // When updating the non-blocking mode we always perform the ioctl syscall, + // even if the flags would otherwise indicate that the descriptor is + // already in the correct state. This ensures that the underlying + // descriptor is put into the state that has been requested by the user. If + // the ioctl syscall was successful then we need to update the flags to + // match. + if (!ec && command.name() == static_cast(FIONBIO)) + { + if (*static_cast(command.data())) + { + impl.flags_ |= implementation_type::user_set_non_blocking; + } + else + { + // Clearing the non-blocking mode always overrides any internally-set + // non-blocking flag. Any subsequent asynchronous operations will need + // to re-enable non-blocking I/O. + impl.flags_ &= ~(implementation_type::user_set_non_blocking + | implementation_type::internal_non_blocking); + } + } + + return ec; + } + + // Write some data to the descriptor. + template + size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + buffer_sequence_adapter bufs(buffers); + + // A request to read_some 0 bytes on a stream is a no-op. + if (bufs.all_empty()) + { + ec = asio::error_code(); + return 0; + } + + // Send the data. + for (;;) + { + // Try to complete the operation without blocking. + int bytes_sent = descriptor_ops::gather_write( + impl.descriptor_, bufs.buffers(), bufs.count(), ec); + + // Check if operation succeeded. + if (bytes_sent >= 0) + return bytes_sent; + + // Operation failed. + if ((impl.flags_ & implementation_type::user_set_non_blocking) + || (ec != asio::error::would_block + && ec != asio::error::try_again)) + return 0; + + // Wait for descriptor to become ready. + if (descriptor_ops::poll_write(impl.descriptor_, ec) < 0) + return 0; + } + } + + // Wait until data can be written without blocking. + size_t write_some(implementation_type& impl, + const null_buffers&, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + // Wait for descriptor to become ready. + descriptor_ops::poll_write(impl.descriptor_, ec); + + return 0; + } + + template + class write_op_base : public reactor_op + { + public: + write_op_base(int descriptor, + const ConstBufferSequence& buffers, func_type complete_func) + : reactor_op(&write_op_base::do_perform, complete_func), + descriptor_(descriptor), + buffers_(buffers) + { + } + + static bool do_perform(reactor_op* base) + { + write_op_base* o(static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + for (;;) + { + // Write the data. + asio::error_code ec; + int bytes = descriptor_ops::gather_write( + o->descriptor_, bufs.buffers(), bufs.count(), ec); + + // Retry operation if interrupted by signal. + if (ec == asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == asio::error::would_block + || ec == asio::error::try_again) + return false; + + o->ec_ = ec; + o->bytes_transferred_ = (bytes < 0 ? 0 : bytes); + return true; + } + } + + private: + int descriptor_; + ConstBufferSequence buffers_; + }; + + template + class write_op : public write_op_base + { + public: + write_op(int descriptor, + const ConstBufferSequence& buffers, Handler handler) + : write_op_base( + descriptor, buffers, &write_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + write_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + Handler handler_; + }; + + // Start an asynchronous write. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef write_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, impl.descriptor_, buffers, handler); + + start_op(impl, reactor::write_op, ptr.get(), true, + buffer_sequence_adapter::all_empty(buffers)); + ptr.release(); + } + + // Start an asynchronous wait until data can be written without blocking. + template + void async_write_some(implementation_type& impl, + const null_buffers&, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef null_buffers_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + start_op(impl, reactor::write_op, ptr.get(), false, false); + ptr.release(); + } + + // Read some data from the stream. Returns the number of bytes read. + template + size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + buffer_sequence_adapter bufs(buffers); + + // A request to read_some 0 bytes on a stream is a no-op. + if (bufs.all_empty()) + { + ec = asio::error_code(); + return 0; + } + + // Read some data. + for (;;) + { + // Try to complete the operation without blocking. + int bytes_read = descriptor_ops::scatter_read( + impl.descriptor_, bufs.buffers(), bufs.count(), ec); + + // Check if operation succeeded. + if (bytes_read > 0) + return bytes_read; + + // Check for EOF. + if (bytes_read == 0) + { + ec = asio::error::eof; + return 0; + } + + // Operation failed. + if ((impl.flags_ & implementation_type::user_set_non_blocking) + || (ec != asio::error::would_block + && ec != asio::error::try_again)) + return 0; + + // Wait for descriptor to become ready. + if (descriptor_ops::poll_read(impl.descriptor_, ec) < 0) + return 0; + } + } + + // Wait until data can be read without blocking. + size_t read_some(implementation_type& impl, + const null_buffers&, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + // Wait for descriptor to become ready. + descriptor_ops::poll_read(impl.descriptor_, ec); + + return 0; + } + + template + class read_op_base : public reactor_op + { + public: + read_op_base(int descriptor, + const MutableBufferSequence& buffers, func_type complete_func) + : reactor_op(&read_op_base::do_perform, complete_func), + descriptor_(descriptor), + buffers_(buffers) + { + } + + static bool do_perform(reactor_op* base) + { + read_op_base* o(static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + for (;;) + { + // Read some data. + asio::error_code ec; + int bytes = descriptor_ops::scatter_read( + o->descriptor_, bufs.buffers(), bufs.count(), ec); + if (bytes == 0) + ec = asio::error::eof; + + // Retry operation if interrupted by signal. + if (ec == asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == asio::error::would_block + || ec == asio::error::try_again) + return false; + + o->ec_ = ec; + o->bytes_transferred_ = (bytes < 0 ? 0 : bytes); + return true; + } + } + + private: + int descriptor_; + MutableBufferSequence buffers_; + }; + + template + class read_op : public read_op_base + { + public: + read_op(int descriptor, + const MutableBufferSequence& buffers, Handler handler) + : read_op_base( + descriptor, buffers, &read_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + read_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + Handler handler_; + }; + + // Start an asynchronous read. The buffer for the data being read must be + // valid for the lifetime of the asynchronous operation. + template + void async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef read_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, + impl.descriptor_, buffers, handler); + + start_op(impl, reactor::read_op, ptr.get(), true, + buffer_sequence_adapter::all_empty(buffers)); + ptr.release(); + } + + // Wait until data can be read without blocking. + template + void async_read_some(implementation_type& impl, + const null_buffers&, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef null_buffers_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + start_op(impl, reactor::read_op, ptr.get(), false, false); + ptr.release(); + } + +private: + // Start the asynchronous operation. + void start_op(implementation_type& impl, int op_type, + reactor_op* op, bool non_blocking, bool noop) + { + if (!noop) + { + if (is_open(impl)) + { + if (is_non_blocking(impl) || set_non_blocking(impl, op->ec_)) + { + reactor_.start_op(op_type, impl.descriptor_, + impl.reactor_data_, op, non_blocking); + return; + } + } + else + op->ec_ = asio::error::bad_descriptor; + } + + io_service_impl_.post_immediate_completion(op); + } + + // Determine whether the descriptor has been set non-blocking. + bool is_non_blocking(implementation_type& impl) const + { + return (impl.flags_ & implementation_type::non_blocking); + } + + // Set the internal non-blocking flag. + bool set_non_blocking(implementation_type& impl, + asio::error_code& ec) + { + ioctl_arg_type non_blocking = 1; + if (descriptor_ops::ioctl(impl.descriptor_, FIONBIO, &non_blocking, ec)) + return false; + impl.flags_ |= implementation_type::internal_non_blocking; + return true; + } + + // The io_service implementation used to post completions. + io_service_impl& io_service_impl_; + + // The selector that performs event demultiplexing for the service. + reactor& reactor_; +}; + +} // namespace detail +} // namespace asio + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTIVE_DESCRIPTOR_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/reactive_serial_port_service.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/reactive_serial_port_service.hpp new file mode 100644 index 00000000..186460fe --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/reactive_serial_port_service.hpp @@ -0,0 +1,261 @@ +// +// reactive_serial_port_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP +#define ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/serial_port_base.hpp" + +#if defined(ASIO_HAS_SERIAL_PORT) \ + && !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/descriptor_ops.hpp" +#include "asio/detail/reactive_descriptor_service.hpp" + +namespace asio { +namespace detail { + +// Extend reactive_descriptor_service to provide serial port support. +class reactive_serial_port_service +{ +public: + // The native type of a serial port. + typedef reactive_descriptor_service::native_type native_type; + + // The implementation type of the serial port. + typedef reactive_descriptor_service::implementation_type implementation_type; + + reactive_serial_port_service(asio::io_service& io_service) + : descriptor_service_(io_service) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + descriptor_service_.shutdown_service(); + } + + // Construct a new handle implementation. + void construct(implementation_type& impl) + { + descriptor_service_.construct(impl); + } + + // Destroy a handle implementation. + void destroy(implementation_type& impl) + { + descriptor_service_.destroy(impl); + } + + // Open the serial port using the specified device name. + asio::error_code open(implementation_type& impl, + const std::string& device, asio::error_code& ec) + { + if (is_open(impl)) + { + ec = asio::error::already_open; + return ec; + } + + int fd = descriptor_ops::open(device.c_str(), + O_RDWR | O_NONBLOCK | O_NOCTTY, ec); + if (fd < 0) + return ec; + + int s = descriptor_ops::fcntl(fd, F_GETFL, ec); + if (s >= 0) + s = descriptor_ops::fcntl(fd, F_SETFL, s | O_NONBLOCK, ec); + if (s < 0) + { + asio::error_code ignored_ec; + descriptor_ops::close(fd, ignored_ec); + return ec; + } + + // Set up default serial port options. + termios ios; + descriptor_ops::clear_error(ec); + s = descriptor_ops::error_wrapper(::tcgetattr(fd, &ios), ec); + if (s >= 0) + { +#if defined(_BSD_SOURCE) + ::cfmakeraw(&ios); +#else + ios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK + | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + ios.c_oflag &= ~OPOST; + ios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + ios.c_cflag &= ~(CSIZE | PARENB); + ios.c_cflag |= CS8; +#endif + ios.c_iflag |= IGNPAR; + ios.c_cflag |= CREAD | CLOCAL; + descriptor_ops::clear_error(ec); + s = descriptor_ops::error_wrapper(::tcsetattr(fd, TCSANOW, &ios), ec); + } + if (s < 0) + { + asio::error_code ignored_ec; + descriptor_ops::close(fd, ignored_ec); + return ec; + } + + // We're done. Take ownership of the serial port descriptor. + if (descriptor_service_.assign(impl, fd, ec)) + { + asio::error_code ignored_ec; + descriptor_ops::close(fd, ignored_ec); + } + + return ec; + } + + // Assign a native handle to a handle implementation. + asio::error_code assign(implementation_type& impl, + const native_type& native_descriptor, asio::error_code& ec) + { + return descriptor_service_.assign(impl, native_descriptor, ec); + } + + // Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return descriptor_service_.is_open(impl); + } + + // Destroy a handle implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + return descriptor_service_.close(impl, ec); + } + + // Get the native handle representation. + native_type native(implementation_type& impl) + { + return descriptor_service_.native(impl); + } + + // Cancel all operations associated with the handle. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + return descriptor_service_.cancel(impl, ec); + } + + // Set an option on the serial port. + template + asio::error_code set_option(implementation_type& impl, + const SettableSerialPortOption& option, asio::error_code& ec) + { + termios ios; + descriptor_ops::clear_error(ec); + descriptor_ops::error_wrapper(::tcgetattr( + descriptor_service_.native(impl), &ios), ec); + if (ec) + return ec; + + if (option.store(ios, ec)) + return ec; + + descriptor_ops::clear_error(ec); + descriptor_ops::error_wrapper(::tcsetattr( + descriptor_service_.native(impl), TCSANOW, &ios), ec); + return ec; + } + + // Get an option from the serial port. + template + asio::error_code get_option(const implementation_type& impl, + GettableSerialPortOption& option, asio::error_code& ec) const + { + termios ios; + descriptor_ops::clear_error(ec); + descriptor_ops::error_wrapper(::tcgetattr( + descriptor_service_.native(impl), &ios), ec); + if (ec) + return ec; + + return option.load(ios, ec); + } + + // Send a break sequence to the serial port. + asio::error_code send_break(implementation_type& impl, + asio::error_code& ec) + { + descriptor_ops::clear_error(ec); + descriptor_ops::error_wrapper(::tcsendbreak( + descriptor_service_.native(impl), 0), ec); + return ec; + } + + // Write the given data. Returns the number of bytes sent. + template + size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return descriptor_service_.write_some(impl, buffers, ec); + } + + // Start an asynchronous write. The data being written must be valid for the + // lifetime of the asynchronous operation. + template + void async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, Handler handler) + { + descriptor_service_.async_write_some(impl, buffers, handler); + } + + // Read some data. Returns the number of bytes received. + template + size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return descriptor_service_.read_some(impl, buffers, ec); + } + + // Start an asynchronous read. The buffer for the data being received must be + // valid for the lifetime of the asynchronous operation. + template + void async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, Handler handler) + { + descriptor_service_.async_read_some(impl, buffers, handler); + } + +private: + // The implementation used for initiating asynchronous operations. + reactive_descriptor_service descriptor_service_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(ASIO_HAS_SERIAL_PORT) + // && !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/reactive_socket_service.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/reactive_socket_service.hpp new file mode 100644 index 00000000..20bd512e --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/reactive_socket_service.hpp @@ -0,0 +1,1744 @@ +// +// reactive_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP +#define ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/buffer.hpp" +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/socket_base.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/null_buffers_op.hpp" +#include "asio/detail/reactor.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_holder.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace detail { + +template +class reactive_socket_service +{ +public: + // The protocol type. + typedef Protocol protocol_type; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + // The native type of a socket. + typedef socket_type native_type; + + // The implementation type of the socket. + class implementation_type + : private asio::detail::noncopyable + { + public: + // Default constructor. + implementation_type() + : socket_(invalid_socket), + flags_(0), + protocol_(endpoint_type().protocol()) + { + } + + private: + // Only this service will have access to the internal values. + friend class reactive_socket_service; + + // The native socket representation. + socket_type socket_; + + enum + { + // The user wants a non-blocking socket. + user_set_non_blocking = 1, + + // The implementation wants a non-blocking socket (in order to be able to + // perform asynchronous read and write operations). + internal_non_blocking = 2, + + // Helper "flag" used to determine whether the socket is non-blocking. + non_blocking = user_set_non_blocking | internal_non_blocking, + + // User wants connection_aborted errors, which are disabled by default. + enable_connection_aborted = 4, + + // The user set the linger option. Needs to be checked when closing. + user_set_linger = 8 + }; + + // Flags indicating the current state of the socket. + unsigned char flags_; + + // The protocol associated with the socket. + protocol_type protocol_; + + // Per-descriptor data used by the reactor. + reactor::per_descriptor_data reactor_data_; + }; + + // Constructor. + reactive_socket_service(asio::io_service& io_service) + : io_service_impl_(use_service(io_service)), + reactor_(use_service(io_service)) + { + reactor_.init_task(); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + // Construct a new socket implementation. + void construct(implementation_type& impl) + { + impl.socket_ = invalid_socket; + impl.flags_ = 0; + } + + // Destroy a socket implementation. + void destroy(implementation_type& impl) + { + if (impl.socket_ != invalid_socket) + { + reactor_.close_descriptor(impl.socket_, impl.reactor_data_); + + if (impl.flags_ & implementation_type::non_blocking) + { + ioctl_arg_type non_blocking = 0; + asio::error_code ignored_ec; + socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ignored_ec); + impl.flags_ &= ~implementation_type::non_blocking; + } + + if (impl.flags_ & implementation_type::user_set_linger) + { + ::linger opt; + opt.l_onoff = 0; + opt.l_linger = 0; + asio::error_code ignored_ec; + socket_ops::setsockopt(impl.socket_, + SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec); + } + + asio::error_code ignored_ec; + socket_ops::close(impl.socket_, ignored_ec); + + impl.socket_ = invalid_socket; + } + } + + // Open a new socket implementation. + asio::error_code open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + if (is_open(impl)) + { + ec = asio::error::already_open; + return ec; + } + + socket_holder sock(socket_ops::socket(protocol.family(), + protocol.type(), protocol.protocol(), ec)); + if (sock.get() == invalid_socket) + return ec; + + if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) + { + ec = asio::error_code(err, + asio::error::get_system_category()); + return ec; + } + + impl.socket_ = sock.release(); + impl.flags_ = 0; + impl.protocol_ = protocol; + ec = asio::error_code(); + return ec; + } + + // Assign a native socket to a socket implementation. + asio::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + asio::error_code& ec) + { + if (is_open(impl)) + { + ec = asio::error::already_open; + return ec; + } + + if (int err = reactor_.register_descriptor( + native_socket, impl.reactor_data_)) + { + ec = asio::error_code(err, + asio::error::get_system_category()); + return ec; + } + + impl.socket_ = native_socket; + impl.flags_ = 0; + impl.protocol_ = protocol; + ec = asio::error_code(); + return ec; + } + + // Determine whether the socket is open. + bool is_open(const implementation_type& impl) const + { + return impl.socket_ != invalid_socket; + } + + // Destroy a socket implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + if (is_open(impl)) + { + reactor_.close_descriptor(impl.socket_, impl.reactor_data_); + + if (impl.flags_ & implementation_type::non_blocking) + { + ioctl_arg_type non_blocking = 0; + asio::error_code ignored_ec; + socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ignored_ec); + impl.flags_ &= ~implementation_type::non_blocking; + } + + if (socket_ops::close(impl.socket_, ec) == socket_error_retval) + return ec; + + impl.socket_ = invalid_socket; + } + + ec = asio::error_code(); + return ec; + } + + // Get the native socket representation. + native_type native(implementation_type& impl) + { + return impl.socket_; + } + + // Cancel all operations associated with the socket. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + reactor_.cancel_ops(impl.socket_, impl.reactor_data_); + ec = asio::error_code(); + return ec; + } + + // Determine whether the socket is at the out-of-band data mark. + bool at_mark(const implementation_type& impl, + asio::error_code& ec) const + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return false; + } + +#if defined(SIOCATMARK) + asio::detail::ioctl_arg_type value = 0; + socket_ops::ioctl(impl.socket_, SIOCATMARK, &value, ec); +# if defined(ENOTTY) + if (ec.value() == ENOTTY) + ec = asio::error::not_socket; +# endif // defined(ENOTTY) +#else // defined(SIOCATMARK) + int value = sockatmark(impl.socket_); + if (value == -1) + ec = asio::error_code(errno, + asio::error::get_system_category()); + else + ec = asio::error_code(); +#endif // defined(SIOCATMARK) + return ec ? false : value != 0; + } + + // Determine the number of bytes available for reading. + std::size_t available(const implementation_type& impl, + asio::error_code& ec) const + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + asio::detail::ioctl_arg_type value = 0; + socket_ops::ioctl(impl.socket_, FIONREAD, &value, ec); +#if defined(ENOTTY) + if (ec.value() == ENOTTY) + ec = asio::error::not_socket; +#endif // defined(ENOTTY) + return ec ? static_cast(0) : static_cast(value); + } + + // Bind the socket to the specified local endpoint. + asio::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); + return ec; + } + + // Place the socket into the state where it will listen for new connections. + asio::error_code listen(implementation_type& impl, int backlog, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + socket_ops::listen(impl.socket_, backlog, ec); + return ec; + } + + // Set a socket option. + template + asio::error_code set_option(implementation_type& impl, + const Option& option, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + if (option.level(impl.protocol_) == custom_socket_option_level + && option.name(impl.protocol_) == enable_connection_aborted_option) + { + if (option.size(impl.protocol_) != sizeof(int)) + { + ec = asio::error::invalid_argument; + } + else + { + if (*reinterpret_cast(option.data(impl.protocol_))) + impl.flags_ |= implementation_type::enable_connection_aborted; + else + impl.flags_ &= ~implementation_type::enable_connection_aborted; + ec = asio::error_code(); + } + return ec; + } + else + { + if (option.level(impl.protocol_) == SOL_SOCKET + && option.name(impl.protocol_) == SO_LINGER) + { + impl.flags_ |= implementation_type::user_set_linger; + } + + socket_ops::setsockopt(impl.socket_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), option.size(impl.protocol_), ec); + +#if defined(__MACH__) && defined(__APPLE__) \ +|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + // To implement portable behaviour for SO_REUSEADDR with UDP sockets we + // need to also set SO_REUSEPORT on BSD-based platforms. + if (!ec && impl.protocol_.type() == SOCK_DGRAM + && option.level(impl.protocol_) == SOL_SOCKET + && option.name(impl.protocol_) == SO_REUSEADDR) + { + asio::error_code ignored_ec; + socket_ops::setsockopt(impl.socket_, SOL_SOCKET, SO_REUSEPORT, + option.data(impl.protocol_), option.size(impl.protocol_), + ignored_ec); + } +#endif + + return ec; + } + } + + // Set a socket option. + template + asio::error_code get_option(const implementation_type& impl, + Option& option, asio::error_code& ec) const + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + if (option.level(impl.protocol_) == custom_socket_option_level + && option.name(impl.protocol_) == enable_connection_aborted_option) + { + if (option.size(impl.protocol_) != sizeof(int)) + { + ec = asio::error::invalid_argument; + } + else + { + int* target = reinterpret_cast(option.data(impl.protocol_)); + if (impl.flags_ & implementation_type::enable_connection_aborted) + *target = 1; + else + *target = 0; + option.resize(impl.protocol_, sizeof(int)); + ec = asio::error_code(); + } + return ec; + } + else + { + size_t size = option.size(impl.protocol_); + socket_ops::getsockopt(impl.socket_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), &size, ec); + if (!ec) + option.resize(impl.protocol_, size); + return ec; + } + } + + // Perform an IO control command on the socket. + template + asio::error_code io_control(implementation_type& impl, + IO_Control_Command& command, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + socket_ops::ioctl(impl.socket_, command.name(), + static_cast(command.data()), ec); + + // When updating the non-blocking mode we always perform the ioctl + // syscall, even if the flags would otherwise indicate that the socket is + // already in the correct state. This ensures that the underlying socket + // is put into the state that has been requested by the user. If the ioctl + // syscall was successful then we need to update the flags to match. + if (!ec && command.name() == static_cast(FIONBIO)) + { + if (*static_cast(command.data())) + { + impl.flags_ |= implementation_type::user_set_non_blocking; + } + else + { + // Clearing the non-blocking mode always overrides any internally-set + // non-blocking flag. Any subsequent asynchronous operations will need + // to re-enable non-blocking I/O. + impl.flags_ &= ~(implementation_type::user_set_non_blocking + | implementation_type::internal_non_blocking); + } + } + + return ec; + } + + // Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return endpoint_type(); + } + + endpoint_type endpoint; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + + // Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return endpoint_type(); + } + + endpoint_type endpoint; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + + /// Disable sends or receives on the socket. + asio::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + socket_ops::shutdown(impl.socket_, what, ec); + return ec; + } + + // Send the given data to the peer. + template + size_t send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + buffer_sequence_adapter bufs(buffers); + + // A request to receive 0 bytes on a stream socket is a no-op. + if (impl.protocol_.type() == SOCK_STREAM && bufs.all_empty()) + { + ec = asio::error_code(); + return 0; + } + + // Send the data. + for (;;) + { + // Try to complete the operation without blocking. + int bytes_sent = socket_ops::send(impl.socket_, + bufs.buffers(), bufs.count(), flags, ec); + + // Check if operation succeeded. + if (bytes_sent >= 0) + return bytes_sent; + + // Operation failed. + if ((impl.flags_ & implementation_type::user_set_non_blocking) + || (ec != asio::error::would_block + && ec != asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_write(impl.socket_, ec) < 0) + return 0; + } + } + + // Wait until data can be sent without blocking. + size_t send(implementation_type& impl, const null_buffers&, + socket_base::message_flags, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + // Wait for socket to become ready. + socket_ops::poll_write(impl.socket_, ec); + + return 0; + } + + template + class send_op_base : public reactor_op + { + public: + send_op_base(socket_type socket, const ConstBufferSequence& buffers, + socket_base::message_flags flags, func_type complete_func) + : reactor_op(&send_op_base::do_perform, complete_func), + socket_(socket), + buffers_(buffers), + flags_(flags) + { + } + + static bool do_perform(reactor_op* base) + { + send_op_base* o(static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + for (;;) + { + // Send the data. + asio::error_code ec; + int bytes = socket_ops::send(o->socket_, + bufs.buffers(), bufs.count(), o->flags_, ec); + + // Retry operation if interrupted by signal. + if (ec == asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == asio::error::would_block + || ec == asio::error::try_again) + return false; + + o->ec_ = ec; + o->bytes_transferred_ = (bytes < 0 ? 0 : bytes); + return true; + } + } + + private: + socket_type socket_; + ConstBufferSequence buffers_; + socket_base::message_flags flags_; + }; + + template + class send_op : public send_op_base + { + public: + send_op(socket_type socket, const ConstBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + : send_op_base(socket, + buffers, flags, &send_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + send_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + Handler handler_; + }; + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef send_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, + impl.socket_, buffers, flags, handler); + + start_op(impl, reactor::write_op, ptr.get(), true, + (impl.protocol_.type() == SOCK_STREAM + && buffer_sequence_adapter::all_empty(buffers))); + ptr.release(); + } + + // Start an asynchronous wait until data can be sent without blocking. + template + void async_send(implementation_type& impl, const null_buffers&, + socket_base::message_flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef null_buffers_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + start_op(impl, reactor::write_op, ptr.get(), false, false); + ptr.release(); + } + + // Send a datagram to the specified endpoint. Returns the number of bytes + // sent. + template + size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + buffer_sequence_adapter bufs(buffers); + + // Send the data. + for (;;) + { + // Try to complete the operation without blocking. + int bytes_sent = socket_ops::sendto(impl.socket_, bufs.buffers(), + bufs.count(), flags, destination.data(), destination.size(), ec); + + // Check if operation succeeded. + if (bytes_sent >= 0) + return bytes_sent; + + // Operation failed. + if ((impl.flags_ & implementation_type::user_set_non_blocking) + || (ec != asio::error::would_block + && ec != asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_write(impl.socket_, ec) < 0) + return 0; + } + } + + // Wait until data can be sent without blocking. + size_t send_to(implementation_type& impl, const null_buffers&, + socket_base::message_flags, const endpoint_type&, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + // Wait for socket to become ready. + socket_ops::poll_write(impl.socket_, ec); + + return 0; + } + + template + class send_to_op_base : public reactor_op + { + public: + send_to_op_base(socket_type socket, const ConstBufferSequence& buffers, + const endpoint_type& endpoint, socket_base::message_flags flags, + func_type complete_func) + : reactor_op(&send_to_op_base::do_perform, complete_func), + socket_(socket), + buffers_(buffers), + destination_(endpoint), + flags_(flags) + { + } + + static bool do_perform(reactor_op* base) + { + send_to_op_base* o(static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + for (;;) + { + // Send the data. + asio::error_code ec; + int bytes = socket_ops::sendto(o->socket_, bufs.buffers(), bufs.count(), + o->flags_, o->destination_.data(), o->destination_.size(), ec); + + // Retry operation if interrupted by signal. + if (ec == asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == asio::error::would_block + || ec == asio::error::try_again) + return false; + + o->ec_ = ec; + o->bytes_transferred_ = (bytes < 0 ? 0 : bytes); + return true; + } + } + + private: + socket_type socket_; + ConstBufferSequence buffers_; + endpoint_type destination_; + socket_base::message_flags flags_; + }; + + template + class send_to_op : public send_to_op_base + { + public: + send_to_op(socket_type socket, const ConstBufferSequence& buffers, + const endpoint_type& endpoint, socket_base::message_flags flags, + Handler handler) + : send_to_op_base(socket, + buffers, endpoint, flags, &send_to_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + send_to_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + Handler handler_; + }; + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send_to(implementation_type& impl, + const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef send_to_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, impl.socket_, + buffers, destination, flags, handler); + + start_op(impl, reactor::write_op, ptr.get(), true, false); + ptr.release(); + } + + // Start an asynchronous wait until data can be sent without blocking. + template + void async_send_to(implementation_type& impl, const null_buffers&, + socket_base::message_flags, const endpoint_type&, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef null_buffers_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + start_op(impl, reactor::write_op, ptr.get(), false, false); + ptr.release(); + } + + // Receive some data from the peer. Returns the number of bytes received. + template + size_t receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + buffer_sequence_adapter bufs(buffers); + + // A request to receive 0 bytes on a stream socket is a no-op. + if (impl.protocol_.type() == SOCK_STREAM && bufs.all_empty()) + { + ec = asio::error_code(); + return 0; + } + + // Receive some data. + for (;;) + { + // Try to complete the operation without blocking. + int bytes_recvd = socket_ops::recv(impl.socket_, + bufs.buffers(), bufs.count(), flags, ec); + + // Check if operation succeeded. + if (bytes_recvd > 0) + return bytes_recvd; + + // Check for EOF. + if (bytes_recvd == 0 && impl.protocol_.type() == SOCK_STREAM) + { + ec = asio::error::eof; + return 0; + } + + // Operation failed. + if ((impl.flags_ & implementation_type::user_set_non_blocking) + || (ec != asio::error::would_block + && ec != asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_read(impl.socket_, ec) < 0) + return 0; + } + } + + // Wait until data can be received without blocking. + size_t receive(implementation_type& impl, const null_buffers&, + socket_base::message_flags, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + // Wait for socket to become ready. + socket_ops::poll_read(impl.socket_, ec); + + return 0; + } + + template + class receive_op_base : public reactor_op + { + public: + receive_op_base(socket_type socket, int protocol_type, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, func_type complete_func) + : reactor_op(&receive_op_base::do_perform, complete_func), + socket_(socket), + protocol_type_(protocol_type), + buffers_(buffers), + flags_(flags) + { + } + + static bool do_perform(reactor_op* base) + { + receive_op_base* o(static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + for (;;) + { + // Receive some data. + asio::error_code ec; + int bytes = socket_ops::recv(o->socket_, + bufs.buffers(), bufs.count(), o->flags_, ec); + if (bytes == 0 && o->protocol_type_ == SOCK_STREAM) + ec = asio::error::eof; + + // Retry operation if interrupted by signal. + if (ec == asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == asio::error::would_block + || ec == asio::error::try_again) + return false; + + o->ec_ = ec; + o->bytes_transferred_ = (bytes < 0 ? 0 : bytes); + return true; + } + } + + private: + socket_type socket_; + int protocol_type_; + MutableBufferSequence buffers_; + socket_base::message_flags flags_; + }; + + template + class receive_op : public receive_op_base + { + public: + receive_op(socket_type socket, int protocol_type, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + : receive_op_base(socket, + protocol_type, buffers, flags, &receive_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + receive_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + Handler handler_; + }; + + // Start an asynchronous receive. The buffer for the data being received + // must be valid for the lifetime of the asynchronous operation. + template + void async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef receive_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + int protocol_type = impl.protocol_.type(); + handler_ptr ptr(raw_ptr, impl.socket_, + protocol_type, buffers, flags, handler); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + ptr.get(), (flags & socket_base::message_out_of_band) == 0, + (impl.protocol_.type() == SOCK_STREAM + && buffer_sequence_adapter::all_empty(buffers))); + ptr.release(); + } + + // Wait until data can be received without blocking. + template + void async_receive(implementation_type& impl, const null_buffers&, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef null_buffers_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + ptr.get(), false, false); + ptr.release(); + } + + // Receive a datagram with the endpoint of the sender. Returns the number of + // bytes received. + template + size_t receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + buffer_sequence_adapter bufs(buffers); + + // Receive some data. + for (;;) + { + // Try to complete the operation without blocking. + std::size_t addr_len = sender_endpoint.capacity(); + int bytes_recvd = socket_ops::recvfrom(impl.socket_, bufs.buffers(), + bufs.count(), flags, sender_endpoint.data(), &addr_len, ec); + + // Check if operation succeeded. + if (bytes_recvd > 0) + { + sender_endpoint.resize(addr_len); + return bytes_recvd; + } + + // Check for EOF. + if (bytes_recvd == 0 && impl.protocol_.type() == SOCK_STREAM) + { + ec = asio::error::eof; + return 0; + } + + // Operation failed. + if ((impl.flags_ & implementation_type::user_set_non_blocking) + || (ec != asio::error::would_block + && ec != asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_read(impl.socket_, ec) < 0) + return 0; + } + } + + // Wait until data can be received without blocking. + size_t receive_from(implementation_type& impl, const null_buffers&, + endpoint_type& sender_endpoint, socket_base::message_flags, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + // Wait for socket to become ready. + socket_ops::poll_read(impl.socket_, ec); + + // Reset endpoint since it can be given no sensible value at this time. + sender_endpoint = endpoint_type(); + + return 0; + } + + template + class receive_from_op_base : public reactor_op + { + public: + receive_from_op_base(socket_type socket, int protocol_type, + const MutableBufferSequence& buffers, endpoint_type& endpoint, + socket_base::message_flags flags, func_type complete_func) + : reactor_op(&receive_from_op_base::do_perform, complete_func), + socket_(socket), + protocol_type_(protocol_type), + buffers_(buffers), + sender_endpoint_(endpoint), + flags_(flags) + { + } + + static bool do_perform(reactor_op* base) + { + receive_from_op_base* o(static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + for (;;) + { + // Receive some data. + asio::error_code ec; + std::size_t addr_len = o->sender_endpoint_.capacity(); + int bytes = socket_ops::recvfrom(o->socket_, bufs.buffers(), + bufs.count(), o->flags_, o->sender_endpoint_.data(), &addr_len, ec); + if (bytes == 0 && o->protocol_type_ == SOCK_STREAM) + ec = asio::error::eof; + + // Retry operation if interrupted by signal. + if (ec == asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == asio::error::would_block + || ec == asio::error::try_again) + return false; + + o->sender_endpoint_.resize(addr_len); + o->ec_ = ec; + o->bytes_transferred_ = (bytes < 0 ? 0 : bytes); + return true; + } + } + + private: + socket_type socket_; + int protocol_type_; + MutableBufferSequence buffers_; + endpoint_type& sender_endpoint_; + socket_base::message_flags flags_; + }; + + template + class receive_from_op : public receive_from_op_base + { + public: + receive_from_op(socket_type socket, int protocol_type, + const MutableBufferSequence& buffers, endpoint_type& endpoint, + socket_base::message_flags flags, Handler handler) + : receive_from_op_base(socket, protocol_type, + buffers, endpoint, flags, &receive_from_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + receive_from_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, o->ec_, o->bytes_transferred_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + Handler handler_; + }; + + // Start an asynchronous receive. The buffer for the data being received and + // the sender_endpoint object must both be valid for the lifetime of the + // asynchronous operation. + template + void async_receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef receive_from_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + int protocol_type = impl.protocol_.type(); + handler_ptr ptr(raw_ptr, impl.socket_, + protocol_type, buffers, sender_endpoint, flags, handler); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + ptr.get(), true, false); + ptr.release(); + } + + // Wait until data can be received without blocking. + template + void async_receive_from(implementation_type& impl, + const null_buffers&, endpoint_type& sender_endpoint, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef null_buffers_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + // Reset endpoint since it can be given no sensible value at this time. + sender_endpoint = endpoint_type(); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + ptr.get(), false, false); + ptr.release(); + } + + // Accept a new connection. + template + asio::error_code accept(implementation_type& impl, + Socket& peer, endpoint_type* peer_endpoint, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + // We cannot accept a socket that is already open. + if (peer.is_open()) + { + ec = asio::error::already_open; + return ec; + } + + // Accept a socket. + for (;;) + { + // Try to complete the operation without blocking. + socket_holder new_socket; + std::size_t addr_len = 0; + if (peer_endpoint) + { + addr_len = peer_endpoint->capacity(); + new_socket.reset(socket_ops::accept(impl.socket_, + peer_endpoint->data(), &addr_len, ec)); + } + else + { + new_socket.reset(socket_ops::accept(impl.socket_, 0, 0, ec)); + } + + // Check if operation succeeded. + if (new_socket.get() >= 0) + { + if (peer_endpoint) + peer_endpoint->resize(addr_len); + peer.assign(impl.protocol_, new_socket.get(), ec); + if (!ec) + new_socket.release(); + return ec; + } + + // Operation failed. + if (ec == asio::error::would_block + || ec == asio::error::try_again) + { + if (impl.flags_ & implementation_type::user_set_non_blocking) + return ec; + // Fall through to retry operation. + } + else if (ec == asio::error::connection_aborted) + { + if (impl.flags_ & implementation_type::enable_connection_aborted) + return ec; + // Fall through to retry operation. + } +#if defined(EPROTO) + else if (ec.value() == EPROTO) + { + if (impl.flags_ & implementation_type::enable_connection_aborted) + return ec; + // Fall through to retry operation. + } +#endif // defined(EPROTO) + else + return ec; + + // Wait for socket to become ready. + if (socket_ops::poll_read(impl.socket_, ec) < 0) + return ec; + } + } + + template + class accept_op_base : public reactor_op + { + public: + accept_op_base(socket_type socket, Socket& peer, + const protocol_type& protocol, endpoint_type* peer_endpoint, + bool enable_connection_aborted, func_type complete_func) + : reactor_op(&accept_op_base::do_perform, complete_func), + socket_(socket), + peer_(peer), + protocol_(protocol), + peer_endpoint_(peer_endpoint), + enable_connection_aborted_(enable_connection_aborted) + { + } + + static bool do_perform(reactor_op* base) + { + accept_op_base* o(static_cast(base)); + + for (;;) + { + // Accept the waiting connection. + asio::error_code ec; + socket_holder new_socket; + std::size_t addr_len = 0; + std::size_t* addr_len_p = 0; + socket_addr_type* addr = 0; + if (o->peer_endpoint_) + { + addr_len = o->peer_endpoint_->capacity(); + addr_len_p = &addr_len; + addr = o->peer_endpoint_->data(); + } + new_socket.reset(socket_ops::accept(o->socket_, addr, addr_len_p, ec)); + + // Retry operation if interrupted by signal. + if (ec == asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == asio::error::would_block + || ec == asio::error::try_again) + return false; + if (ec == asio::error::connection_aborted + && !o->enable_connection_aborted_) + return false; +#if defined(EPROTO) + if (ec.value() == EPROTO && !o->enable_connection_aborted_) + return false; +#endif // defined(EPROTO) + + // Transfer ownership of the new socket to the peer object. + if (!ec) + { + if (o->peer_endpoint_) + o->peer_endpoint_->resize(addr_len); + o->peer_.assign(o->protocol_, new_socket.get(), ec); + if (!ec) + new_socket.release(); + } + + o->ec_ = ec; + return true; + } + } + + private: + socket_type socket_; + Socket& peer_; + protocol_type protocol_; + endpoint_type* peer_endpoint_; + bool enable_connection_aborted_; + }; + + template + class accept_op : public accept_op_base + { + public: + accept_op(socket_type socket, Socket& peer, const protocol_type& protocol, + endpoint_type* peer_endpoint, bool enable_connection_aborted, + Handler handler) + : accept_op_base(socket, peer, protocol, peer_endpoint, + enable_connection_aborted, &accept_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + accept_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder1 + handler(o->handler_, o->ec_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + Handler handler_; + }; + + // Start an asynchronous accept. The peer and peer_endpoint objects + // must be valid until the accept's handler is invoked. + template + void async_accept(implementation_type& impl, Socket& peer, + endpoint_type* peer_endpoint, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef accept_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + bool enable_connection_aborted = + (impl.flags_ & implementation_type::enable_connection_aborted) != 0; + handler_ptr ptr(raw_ptr, impl.socket_, peer, + impl.protocol_, peer_endpoint, enable_connection_aborted, handler); + + start_accept_op(impl, ptr.get(), peer.is_open()); + ptr.release(); + } + + // Connect the socket to the specified endpoint. + asio::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + // Perform the connect operation. + socket_ops::connect(impl.socket_, + peer_endpoint.data(), peer_endpoint.size(), ec); + if (ec != asio::error::in_progress + && ec != asio::error::would_block) + { + // The connect operation finished immediately. + return ec; + } + + // Wait for socket to become ready. + if (socket_ops::poll_connect(impl.socket_, ec) < 0) + return ec; + + // Get the error code from the connect operation. + int connect_error = 0; + size_t connect_error_len = sizeof(connect_error); + if (socket_ops::getsockopt(impl.socket_, SOL_SOCKET, SO_ERROR, + &connect_error, &connect_error_len, ec) == socket_error_retval) + return ec; + + // Return the result of the connect operation. + ec = asio::error_code(connect_error, + asio::error::get_system_category()); + return ec; + } + + class connect_op_base : public reactor_op + { + public: + connect_op_base(socket_type socket, func_type complete_func) + : reactor_op(&connect_op_base::do_perform, complete_func), + socket_(socket) + { + } + + static bool do_perform(reactor_op* base) + { + connect_op_base* o(static_cast(base)); + + // Get the error code from the connect operation. + int connect_error = 0; + size_t connect_error_len = sizeof(connect_error); + if (socket_ops::getsockopt(o->socket_, SOL_SOCKET, SO_ERROR, + &connect_error, &connect_error_len, o->ec_) == socket_error_retval) + return true; + + // The connection failed so the handler will be posted with an error code. + if (connect_error) + { + o->ec_ = asio::error_code(connect_error, + asio::error::get_system_category()); + } + + return true; + } + + private: + socket_type socket_; + }; + + template + class connect_op : public connect_op_base + { + public: + connect_op(socket_type socket, Handler handler) + : connect_op_base(socket, &connect_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + connect_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder1 + handler(o->handler_, o->ec_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + Handler handler_; + }; + + // Start an asynchronous connect. + template + void async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef connect_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, impl.socket_, handler); + + start_connect_op(impl, ptr.get(), peer_endpoint); + ptr.release(); + } + +private: + // Start the asynchronous read or write operation. + void start_op(implementation_type& impl, int op_type, + reactor_op* op, bool non_blocking, bool noop) + { + if (!noop) + { + if (is_open(impl)) + { + if (!non_blocking || is_non_blocking(impl) + || set_non_blocking(impl, op->ec_)) + { + reactor_.start_op(op_type, impl.socket_, + impl.reactor_data_, op, non_blocking); + return; + } + } + else + op->ec_ = asio::error::bad_descriptor; + } + + io_service_impl_.post_immediate_completion(op); + } + + // Start the asynchronous accept operation. + void start_accept_op(implementation_type& impl, + reactor_op* op, bool peer_is_open) + { + if (!peer_is_open) + start_op(impl, reactor::read_op, op, true, false); + else + { + op->ec_ = asio::error::already_open; + io_service_impl_.post_immediate_completion(op); + } + } + + // Start the asynchronous connect operation. + void start_connect_op(implementation_type& impl, + reactor_op* op, const endpoint_type& peer_endpoint) + { + if (is_open(impl)) + { + if (is_non_blocking(impl) || set_non_blocking(impl, op->ec_)) + { + if (socket_ops::connect(impl.socket_, peer_endpoint.data(), + peer_endpoint.size(), op->ec_) != 0) + { + if (op->ec_ == asio::error::in_progress + || op->ec_ == asio::error::would_block) + { + op->ec_ = asio::error_code(); + reactor_.start_op(reactor::connect_op, + impl.socket_, impl.reactor_data_, op, false); + return; + } + } + } + } + else + op->ec_ = asio::error::bad_descriptor; + + io_service_impl_.post_immediate_completion(op); + } + + // Determine whether the socket has been set non-blocking. + bool is_non_blocking(implementation_type& impl) const + { + return (impl.flags_ & implementation_type::non_blocking); + } + + // Set the internal non-blocking flag. + bool set_non_blocking(implementation_type& impl, + asio::error_code& ec) + { + ioctl_arg_type non_blocking = 1; + if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) + return false; + impl.flags_ |= implementation_type::internal_non_blocking; + return true; + } + + // The io_service implementation used to post completions. + io_service_impl& io_service_impl_; + + // The selector that performs event demultiplexing for the service. + reactor& reactor_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/reactor.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/reactor.hpp new file mode 100644 index 00000000..98ac360b --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/reactor.hpp @@ -0,0 +1,34 @@ +// +// reactor.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_REACTOR_HPP +#define ASIO_DETAIL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/reactor_fwd.hpp" + +#if defined(ASIO_HAS_EPOLL) +# include "asio/detail/epoll_reactor.hpp" +#elif defined(ASIO_HAS_KQUEUE) +# include "asio/detail/kqueue_reactor.hpp" +#elif defined(ASIO_HAS_DEV_POLL) +# include "asio/detail/dev_poll_reactor.hpp" +#else +# include "asio/detail/select_reactor.hpp" +#endif + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTOR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/reactor_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/reactor_fwd.hpp new file mode 100644 index 00000000..9c33be54 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/reactor_fwd.hpp @@ -0,0 +1,46 @@ +// +// reactor_fwd.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_REACTOR_FWD_HPP +#define ASIO_DETAIL_REACTOR_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/dev_poll_reactor_fwd.hpp" +#include "asio/detail/epoll_reactor_fwd.hpp" +#include "asio/detail/kqueue_reactor_fwd.hpp" +#include "asio/detail/select_reactor_fwd.hpp" +#include "asio/detail/win_iocp_io_service_fwd.hpp" + +namespace asio { +namespace detail { + +#if defined(ASIO_HAS_IOCP) +typedef select_reactor reactor; +#elif defined(ASIO_HAS_EPOLL) +typedef epoll_reactor reactor; +#elif defined(ASIO_HAS_KQUEUE) +typedef kqueue_reactor reactor; +#elif defined(ASIO_HAS_DEV_POLL) +typedef dev_poll_reactor reactor; +#else +typedef select_reactor reactor; +#endif + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTOR_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/reactor_op.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/reactor_op.hpp new file mode 100644 index 00000000..cd557fa6 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/reactor_op.hpp @@ -0,0 +1,60 @@ +// +// reactor_op.hpp +// ~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_REACTOR_OP_HPP +#define ASIO_DETAIL_REACTOR_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/operation.hpp" + +namespace asio { +namespace detail { + +class reactor_op + : public operation +{ +public: + // The error code to be passed to the completion handler. + asio::error_code ec_; + + // The number of bytes transferred, to be passed to the completion handler. + std::size_t bytes_transferred_; + + // Perform the operation. Returns true if it is finished. + bool perform() + { + return perform_func_(this); + } + +protected: + typedef bool (*perform_func_type)(reactor_op*); + + reactor_op(perform_func_type perform_func, func_type complete_func) + : operation(complete_func), + bytes_transferred_(0), + perform_func_(perform_func) + { + } + +private: + perform_func_type perform_func_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTOR_OP_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/reactor_op_queue.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/reactor_op_queue.hpp new file mode 100644 index 00000000..233c0aec --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/reactor_op_queue.hpp @@ -0,0 +1,199 @@ +// +// reactor_op_queue.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_REACTOR_OP_QUEUE_HPP +#define ASIO_DETAIL_REACTOR_OP_QUEUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/error.hpp" +#include "asio/detail/hash_map.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/reactor_op.hpp" + +namespace asio { +namespace detail { + +template +class reactor_op_queue + : private noncopyable +{ +public: + // Constructor. + reactor_op_queue() + : operations_() + { + } + + // Add a new operation to the queue. Returns true if this is the only + // operation for the given descriptor, in which case the reactor's event + // demultiplexing function call may need to be interrupted and restarted. + bool enqueue_operation(Descriptor descriptor, reactor_op* op) + { + typedef typename operations_map::iterator iterator; + typedef typename operations_map::value_type value_type; + std::pair entry = + operations_.insert(value_type(descriptor, operations())); + entry.first->second.op_queue_.push(op); + return entry.second; + } + + // Cancel all operations associated with the descriptor. Any operations + // pending for the descriptor will be notified that they have been cancelled + // next time perform_cancellations is called. Returns true if any operations + // were cancelled, in which case the reactor's event demultiplexing function + // may need to be interrupted and restarted. + bool cancel_operations(Descriptor descriptor, op_queue& ops, + const asio::error_code& ec = + asio::error::operation_aborted) + { + typename operations_map::iterator i = operations_.find(descriptor); + if (i != operations_.end()) + { + while (reactor_op* op = i->second.op_queue_.front()) + { + op->ec_ = ec; + i->second.op_queue_.pop(); + ops.push(op); + } + operations_.erase(i); + return true; + } + + return false; + } + + // Whether there are no operations in the queue. + bool empty() const + { + return operations_.empty(); + } + + // Determine whether there are any operations associated with the descriptor. + bool has_operation(Descriptor descriptor) const + { + return operations_.find(descriptor) != operations_.end(); + } + + // Perform the operations corresponding to the descriptor. Returns true if + // there are still unfinished operations queued for the descriptor. + bool perform_operations(Descriptor descriptor, op_queue& ops) + { + typename operations_map::iterator i = operations_.find(descriptor); + if (i != operations_.end()) + { + while (reactor_op* op = i->second.op_queue_.front()) + { + if (op->perform()) + { + i->second.op_queue_.pop(); + ops.push(op); + } + else + { + return true; + } + } + operations_.erase(i); + } + return false; + } + + // Fill a descriptor set with the descriptors corresponding to each active + // operation. The op_queue is used only when descriptors fail to be added to + // the descriptor set. + template + void get_descriptors(Descriptor_Set& descriptors, op_queue& ops) + { + typename operations_map::iterator i = operations_.begin(); + while (i != operations_.end()) + { + Descriptor descriptor = i->first; + ++i; + if (!descriptors.set(descriptor)) + { + asio::error_code ec(error::fd_set_failure); + cancel_operations(descriptor, ops, ec); + } + } + } + + // Perform the operations corresponding to the ready file descriptors + // contained in the given descriptor set. + template + void perform_operations_for_descriptors( + const Descriptor_Set& descriptors, op_queue& ops) + { + typename operations_map::iterator i = operations_.begin(); + while (i != operations_.end()) + { + typename operations_map::iterator op_iter = i++; + if (descriptors.is_set(op_iter->first)) + { + while (reactor_op* op = op_iter->second.op_queue_.front()) + { + if (op->perform()) + { + op_iter->second.op_queue_.pop(); + ops.push(op); + } + else + { + break; + } + } + + if (op_iter->second.op_queue_.empty()) + operations_.erase(op_iter); + } + } + } + + // Get all operations owned by the queue. + void get_all_operations(op_queue& ops) + { + typename operations_map::iterator i = operations_.begin(); + while (i != operations_.end()) + { + typename operations_map::iterator op_iter = i++; + ops.push(op_iter->second.op_queue_); + operations_.erase(op_iter); + } + } + +private: + struct operations + { + operations() {} + operations(const operations&) {} + void operator=(const operations&) {} + + // The operations waiting on the desccriptor. + op_queue op_queue_; + }; + + // The type for a map of operations. + typedef hash_map operations_map; + + // The operations that are currently executing asynchronously. + operations_map operations_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_REACTOR_OP_QUEUE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/resolver_service.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/resolver_service.hpp new file mode 100644 index 00000000..562dc104 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/resolver_service.hpp @@ -0,0 +1,442 @@ +// +// resolver_service.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_RESOLVER_SERVICE_HPP +#define ASIO_DETAIL_RESOLVER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/thread.hpp" + +namespace asio { +namespace detail { + +template +class resolver_service + : public asio::detail::service_base > +{ +private: + // Helper class to perform exception-safe cleanup of addrinfo objects. + class auto_addrinfo + : private asio::detail::noncopyable + { + public: + explicit auto_addrinfo(asio::detail::addrinfo_type* ai) + : ai_(ai) + { + } + + ~auto_addrinfo() + { + if (ai_) + socket_ops::freeaddrinfo(ai_); + } + + operator asio::detail::addrinfo_type*() + { + return ai_; + } + + private: + asio::detail::addrinfo_type* ai_; + }; + +public: + // The implementation type of the resolver. The shared pointer is used as a + // cancellation token to indicate to the background thread that the operation + // has been cancelled. + typedef boost::shared_ptr implementation_type; + struct noop_deleter { void operator()(void*) {} }; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + // The query type. + typedef asio::ip::basic_resolver_query query_type; + + // The iterator type. + typedef asio::ip::basic_resolver_iterator iterator_type; + + // Constructor. + resolver_service(asio::io_service& io_service) + : asio::detail::service_base< + resolver_service >(io_service), + mutex_(), + io_service_impl_(asio::use_service(io_service)), + work_io_service_(new asio::io_service), + work_io_service_impl_(asio::use_service< + io_service_impl>(*work_io_service_)), + work_(new asio::io_service::work(*work_io_service_)), + work_thread_(0) + { + } + + // Destructor. + ~resolver_service() + { + shutdown_service(); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + work_.reset(); + if (work_io_service_) + { + work_io_service_->stop(); + if (work_thread_) + { + work_thread_->join(); + work_thread_.reset(); + } + work_io_service_.reset(); + } + } + + // Construct a new resolver implementation. + void construct(implementation_type& impl) + { + impl.reset(static_cast(0), noop_deleter()); + } + + // Destroy a resolver implementation. + void destroy(implementation_type&) + { + } + + // Cancel pending asynchronous operations. + void cancel(implementation_type& impl) + { + impl.reset(static_cast(0), noop_deleter()); + } + + // Resolve a query to a list of entries. + iterator_type resolve(implementation_type&, const query_type& query, + asio::error_code& ec) + { + asio::detail::addrinfo_type* address_info = 0; + std::string host_name = query.host_name(); + std::string service_name = query.service_name(); + asio::detail::addrinfo_type hints = query.hints(); + + socket_ops::getaddrinfo(!host_name.empty() ? host_name.c_str() : 0, + service_name.c_str(), &hints, &address_info, ec); + auto_addrinfo auto_address_info(address_info); + + if (ec) + return iterator_type(); + + return iterator_type::create(address_info, host_name, service_name); + } + + template + class resolve_op + : public operation + { + public: + resolve_op(implementation_type impl, const query_type& query, + io_service_impl& io_service_impl, Handler handler) + : operation(&resolve_op::do_complete), + impl_(impl), + query_(query), + io_service_impl_(io_service_impl), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the operation object. + resolve_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + if (owner) + { + if (owner != &o->io_service_impl_) + { + // The operation is being run on the worker io_service. Time to + // perform the resolver operation. + + if (o->impl_.expired()) + { + // THe operation has been cancelled. + o->ec_ = asio::error::operation_aborted; + } + else + { + // Perform the blocking host resolution operation. + asio::detail::addrinfo_type* address_info = 0; + std::string host_name = o->query_.host_name(); + std::string service_name = o->query_.service_name(); + asio::detail::addrinfo_type hints = o->query_.hints(); + socket_ops::getaddrinfo(!host_name.empty() ? host_name.c_str() : 0, + service_name.c_str(), &hints, &address_info, o->ec_); + auto_addrinfo auto_address_info(address_info); + o->iter_ = iterator_type::create( + address_info, host_name, service_name); + } + + o->io_service_impl_.post_deferred_completion(o); + ptr.release(); + } + else + { + // The operation has been returned to the main io_serice. The + // completion handler is ready to be delivered. + + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object + // remains valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, o->ec_, o->iter_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + } + + private: + boost::weak_ptr impl_; + query_type query_; + io_service_impl& io_service_impl_; + Handler handler_; + asio::error_code ec_; + iterator_type iter_; + }; + + // Asynchronously resolve a query to a list of entries. + template + void async_resolve(implementation_type& impl, const query_type& query, + Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef resolve_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, + impl, query, io_service_impl_, handler); + + if (work_io_service_) + { + start_work_thread(); + io_service_impl_.work_started(); + work_io_service_impl_.post_immediate_completion(ptr.get()); + ptr.release(); + } + } + + // Resolve an endpoint to a list of entries. + iterator_type resolve(implementation_type&, + const endpoint_type& endpoint, asio::error_code& ec) + { + // First try resolving with the service name. If that fails try resolving + // but allow the service to be returned as a number. + char host_name[NI_MAXHOST]; + char service_name[NI_MAXSERV]; + int flags = endpoint.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0; + socket_ops::getnameinfo(endpoint.data(), endpoint.size(), + host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec); + if (ec) + { + flags |= NI_NUMERICSERV; + socket_ops::getnameinfo(endpoint.data(), endpoint.size(), + host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec); + } + + if (ec) + return iterator_type(); + + return iterator_type::create(endpoint, host_name, service_name); + } + + template + class resolve_endpoint_op + : public operation + { + public: + resolve_endpoint_op(implementation_type impl, const endpoint_type& ep, + io_service_impl& io_service_impl, Handler handler) + : operation(&resolve_endpoint_op::do_complete), + impl_(impl), + ep_(ep), + io_service_impl_(io_service_impl), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the operation object. + resolve_endpoint_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + if (owner) + { + if (owner != &o->io_service_impl_) + { + // The operation is being run on the worker io_service. Time to + // perform the resolver operation. + + if (o->impl_.expired()) + { + // THe operation has been cancelled. + o->ec_ = asio::error::operation_aborted; + } + else + { + // Perform the blocking endoint resolution operation. + char host_name[NI_MAXHOST]; + char service_name[NI_MAXSERV]; + int flags = o->ep_.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0; + socket_ops::getnameinfo(o->ep_.data(), o->ep_.size(), + host_name, NI_MAXHOST, service_name, + NI_MAXSERV, flags, o->ec_); + if (o->ec_) + { + flags |= NI_NUMERICSERV; + socket_ops::getnameinfo(o->ep_.data(), o->ep_.size(), + host_name, NI_MAXHOST, service_name, + NI_MAXSERV, flags, o->ec_); + } + o->iter_ = iterator_type::create(o->ep_, host_name, service_name); + } + + o->io_service_impl_.post_deferred_completion(o); + ptr.release(); + } + else + { + // The operation has been returned to the main io_serice. The + // completion handler is ready to be delivered. + + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object + // remains valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, o->ec_, o->iter_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + } + + private: + boost::weak_ptr impl_; + endpoint_type ep_; + io_service_impl& io_service_impl_; + Handler handler_; + asio::error_code ec_; + iterator_type iter_; + }; + + // Asynchronously resolve an endpoint to a list of entries. + template + void async_resolve(implementation_type& impl, const endpoint_type& endpoint, + Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef resolve_endpoint_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, + impl, endpoint, io_service_impl_, handler); + + if (work_io_service_) + { + start_work_thread(); + io_service_impl_.work_started(); + work_io_service_impl_.post_immediate_completion(ptr.get()); + ptr.release(); + } + } + +private: + // Helper class to run the work io_service in a thread. + class work_io_service_runner + { + public: + work_io_service_runner(asio::io_service& io_service) + : io_service_(io_service) {} + void operator()() { io_service_.run(); } + private: + asio::io_service& io_service_; + }; + + // Start the work thread if it's not already running. + void start_work_thread() + { + asio::detail::mutex::scoped_lock lock(mutex_); + if (!work_thread_) + { + work_thread_.reset(new asio::detail::thread( + work_io_service_runner(*work_io_service_))); + } + } + + // Mutex to protect access to internal data. + asio::detail::mutex mutex_; + + // The io_service implementation used to post completions. + io_service_impl& io_service_impl_; + + // Private io_service used for performing asynchronous host resolution. + boost::scoped_ptr work_io_service_; + + // The work io_service implementation used to post completions. + io_service_impl& work_io_service_impl_; + + // Work for the private io_service to perform. + boost::scoped_ptr work_; + + // Thread used for running the work io_service's run loop. + boost::scoped_ptr work_thread_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_RESOLVER_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/scoped_lock.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/scoped_lock.hpp new file mode 100644 index 00000000..e6f6ba59 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/scoped_lock.hpp @@ -0,0 +1,91 @@ +// +// scoped_lock.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SCOPED_LOCK_HPP +#define ASIO_DETAIL_SCOPED_LOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/noncopyable.hpp" + +namespace asio { +namespace detail { + +// Helper class to lock and unlock a mutex automatically. +template +class scoped_lock + : private noncopyable +{ +public: + // Constructor acquires the lock. + scoped_lock(Mutex& m) + : mutex_(m) + { + mutex_.lock(); + locked_ = true; + } + + // Destructor releases the lock. + ~scoped_lock() + { + if (locked_) + mutex_.unlock(); + } + + // Explicitly acquire the lock. + void lock() + { + if (!locked_) + { + mutex_.lock(); + locked_ = true; + } + } + + // Explicitly release the lock. + void unlock() + { + if (locked_) + { + mutex_.unlock(); + locked_ = false; + } + } + + // Test whether the lock is held. + bool locked() const + { + return locked_; + } + + // Get the underlying mutex. + Mutex& mutex() + { + return mutex_; + } + +private: + // The underlying mutex. + Mutex& mutex_; + + // Whether the mutex is currently locked or unlocked. + bool locked_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SCOPED_LOCK_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/select_interrupter.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/select_interrupter.hpp new file mode 100644 index 00000000..ff5505be --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/select_interrupter.hpp @@ -0,0 +1,47 @@ +// +// select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SELECT_INTERRUPTER_HPP +#define ASIO_DETAIL_SELECT_INTERRUPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# include "asio/detail/socket_select_interrupter.hpp" +#else +# include "asio/detail/eventfd_select_interrupter.hpp" +# include "asio/detail/pipe_select_interrupter.hpp" +#endif + +namespace asio { +namespace detail { + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef socket_select_interrupter select_interrupter; +#elif defined(ASIO_HAS_EVENTFD) +typedef eventfd_select_interrupter select_interrupter; +#else +typedef pipe_select_interrupter select_interrupter; +#endif + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SELECT_INTERRUPTER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/select_reactor.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/select_reactor.hpp new file mode 100644 index 00000000..798611b2 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/select_reactor.hpp @@ -0,0 +1,374 @@ +// +// select_reactor.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SELECT_REACTOR_HPP +#define ASIO_DETAIL_SELECT_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/socket_types.hpp" // Must come before posix_time. + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/io_service.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/fd_set_adapter.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/reactor_op_queue.hpp" +#include "asio/detail/select_interrupter.hpp" +#include "asio/detail/select_reactor_fwd.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/detail/signal_blocker.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/thread.hpp" +#include "asio/detail/timer_op.hpp" +#include "asio/detail/timer_queue_base.hpp" +#include "asio/detail/timer_queue_fwd.hpp" +#include "asio/detail/timer_queue_set.hpp" + +namespace asio { +namespace detail { + +template +class select_reactor + : public asio::detail::service_base > +{ +public: +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + enum { read_op = 0, write_op = 1, except_op = 2, + max_select_ops = 3, connect_op = 3, max_ops = 4 }; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + enum { read_op = 0, write_op = 1, except_op = 2, + max_select_ops = 3, connect_op = 1, max_ops = 3 }; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + + // Per-descriptor data. + struct per_descriptor_data + { + }; + + // Constructor. + select_reactor(asio::io_service& io_service) + : asio::detail::service_base< + select_reactor >(io_service), + io_service_(use_service(io_service)), + mutex_(), + interrupter_(), + stop_thread_(false), + thread_(0), + shutdown_(false) + { + if (Own_Thread) + { + asio::detail::signal_blocker sb; + thread_ = new asio::detail::thread( + bind_handler(&select_reactor::call_run_thread, this)); + } + } + + // Destructor. + ~select_reactor() + { + shutdown_service(); + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + asio::detail::mutex::scoped_lock lock(mutex_); + shutdown_ = true; + stop_thread_ = true; + lock.unlock(); + + if (Own_Thread) + { + if (thread_) + { + interrupter_.interrupt(); + thread_->join(); + delete thread_; + thread_ = 0; + } + } + + op_queue ops; + + for (int i = 0; i < max_ops; ++i) + op_queue_[i].get_all_operations(ops); + + timer_queues_.get_all_timers(ops); + } + + // Initialise the task, but only if the reactor is not in its own thread. + void init_task() + { + io_service_.init_task(); + } + + // Register a socket with the reactor. Returns 0 on success, system error + // code on failure. + int register_descriptor(socket_type, per_descriptor_data&) + { + return 0; + } + + // Start a new operation. The reactor operation will be performed when the + // given descriptor is flagged as ready, or an error has occurred. + void start_op(int op_type, socket_type descriptor, + per_descriptor_data&, reactor_op* op, bool) + { + asio::detail::mutex::scoped_lock lock(mutex_); + if (!shutdown_) + { + bool first = op_queue_[op_type].enqueue_operation(descriptor, op); + io_service_.work_started(); + if (first) + interrupter_.interrupt(); + } + } + + // Cancel all operations associated with the given descriptor. The + // handlers associated with the descriptor will be invoked with the + // operation_aborted error. + void cancel_ops(socket_type descriptor, per_descriptor_data&) + { + asio::detail::mutex::scoped_lock lock(mutex_); + cancel_ops_unlocked(descriptor, asio::error::operation_aborted); + } + + // Cancel any operations that are running against the descriptor and remove + // its registration from the reactor. + void close_descriptor(socket_type descriptor, per_descriptor_data&) + { + asio::detail::mutex::scoped_lock lock(mutex_); + cancel_ops_unlocked(descriptor, asio::error::operation_aborted); + } + + // Add a new timer queue to the reactor. + template + void add_timer_queue(timer_queue& timer_queue) + { + asio::detail::mutex::scoped_lock lock(mutex_); + timer_queues_.insert(&timer_queue); + } + + // Remove a timer queue from the reactor. + template + void remove_timer_queue(timer_queue& timer_queue) + { + asio::detail::mutex::scoped_lock lock(mutex_); + timer_queues_.erase(&timer_queue); + } + + // Schedule a new operation in the given timer queue to expire at the + // specified absolute time. + template + void schedule_timer(timer_queue& timer_queue, + const typename Time_Traits::time_type& time, timer_op* op, void* token) + { + asio::detail::mutex::scoped_lock lock(mutex_); + if (!shutdown_) + { + bool earliest = timer_queue.enqueue_timer(time, op, token); + io_service_.work_started(); + if (earliest) + interrupter_.interrupt(); + } + } + + // Cancel the timer operations associated with the given token. Returns the + // number of operations that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& timer_queue, void* token) + { + asio::detail::mutex::scoped_lock lock(mutex_); + op_queue ops; + std::size_t n = timer_queue.cancel_timer(token, ops); + lock.unlock(); + io_service_.post_deferred_completions(ops); + return n; + } + + // Run select once until interrupted or events are ready to be dispatched. + void run(bool block, op_queue& ops) + { + asio::detail::mutex::scoped_lock lock(mutex_); + + // Check if the thread is supposed to stop. + if (Own_Thread) + if (stop_thread_) + return; + + // Set up the descriptor sets. + fd_set_adapter fds[max_select_ops]; + fds[read_op].set(interrupter_.read_descriptor()); + socket_type max_fd = 0; + bool have_work_to_do = !timer_queues_.all_empty(); + for (int i = 0; i < max_select_ops; ++i) + { + have_work_to_do = have_work_to_do || !op_queue_[i].empty(); + op_queue_[i].get_descriptors(fds[i], ops); + if (fds[i].max_descriptor() > max_fd) + max_fd = fds[i].max_descriptor(); + } + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Connection operations on Windows use both except and write fd_sets. + have_work_to_do = have_work_to_do || !op_queue_[connect_op].empty(); + op_queue_[connect_op].get_descriptors(fds[write_op], ops); + if (fds[write_op].max_descriptor() > max_fd) + max_fd = fds[write_op].max_descriptor(); + op_queue_[connect_op].get_descriptors(fds[except_op], ops); + if (fds[except_op].max_descriptor() > max_fd) + max_fd = fds[except_op].max_descriptor(); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + + // We can return immediately if there's no work to do and the reactor is + // not supposed to block. + if (!block && !have_work_to_do) + return; + + // Determine how long to block while waiting for events. + timeval tv_buf = { 0, 0 }; + timeval* tv = block ? get_timeout(tv_buf) : &tv_buf; + + lock.unlock(); + + // Block on the select call until descriptors become ready. + asio::error_code ec; + int retval = socket_ops::select(static_cast(max_fd + 1), + fds[read_op], fds[write_op], fds[except_op], tv, ec); + + // Reset the interrupter. + if (retval > 0 && fds[read_op].is_set(interrupter_.read_descriptor())) + interrupter_.reset(); + + lock.lock(); + + // Dispatch all ready operations. + if (retval > 0) + { +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Connection operations on Windows use both except and write fd_sets. + op_queue_[connect_op].perform_operations_for_descriptors( + fds[except_op], ops); + op_queue_[connect_op].perform_operations_for_descriptors( + fds[write_op], ops); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + + // Exception operations must be processed first to ensure that any + // out-of-band data is read before normal data. + for (int i = max_select_ops - 1; i >= 0; --i) + op_queue_[i].perform_operations_for_descriptors(fds[i], ops); + } + timer_queues_.get_ready_timers(ops); + } + + // Interrupt the select loop. + void interrupt() + { + interrupter_.interrupt(); + } + +private: + // Run the select loop in the thread. + void run_thread() + { + if (Own_Thread) + { + asio::detail::mutex::scoped_lock lock(mutex_); + while (!stop_thread_) + { + lock.unlock(); + op_queue ops; + run(true, ops); + io_service_.post_deferred_completions(ops); + lock.lock(); + } + } + } + + // Entry point for the select loop thread. + static void call_run_thread(select_reactor* reactor) + { + if (Own_Thread) + { + reactor->run_thread(); + } + } + + // Get the timeout value for the select call. + timeval* get_timeout(timeval& tv) + { + // By default we will wait no longer than 5 minutes. This will ensure that + // any changes to the system clock are detected after no longer than this. + long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000); + tv.tv_sec = usec / 1000000; + tv.tv_usec = usec % 1000000; + return &tv; + } + + // Cancel all operations associated with the given descriptor. This function + // does not acquire the select_reactor's mutex. + void cancel_ops_unlocked(socket_type descriptor, + const asio::error_code& ec) + { + bool need_interrupt = false; + op_queue ops; + for (int i = 0; i < max_ops; ++i) + need_interrupt = op_queue_[i].cancel_operations( + descriptor, ops, ec) || need_interrupt; + io_service_.post_deferred_completions(ops); + if (need_interrupt) + interrupter_.interrupt(); + } + + // The io_service implementation used to post completions. + io_service_impl& io_service_; + + // Mutex to protect access to internal data. + asio::detail::mutex mutex_; + + // The interrupter is used to break a blocking select call. + select_interrupter interrupter_; + + // The queues of read, write and except operations. + reactor_op_queue op_queue_[max_ops]; + + // The timer queues. + timer_queue_set timer_queues_; + + // Does the reactor loop thread need to stop. + bool stop_thread_; + + // The thread that is running the reactor loop. + asio::detail::thread* thread_; + + // Whether the service has been shut down. + bool shutdown_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SELECT_REACTOR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/select_reactor_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/select_reactor_fwd.hpp new file mode 100644 index 00000000..0b72e7e8 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/select_reactor_fwd.hpp @@ -0,0 +1,31 @@ +// +// select_reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SELECT_REACTOR_FWD_HPP +#define ASIO_DETAIL_SELECT_REACTOR_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class select_reactor; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SELECT_REACTOR_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/service_base.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/service_base.hpp new file mode 100644 index 00000000..45000c3f --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/service_base.hpp @@ -0,0 +1,49 @@ +// +// service_base.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SERVICE_BASE_HPP +#define ASIO_DETAIL_SERVICE_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/io_service.hpp" +#include "asio/detail/service_id.hpp" + +namespace asio { +namespace detail { + +// Special service base class to keep classes header-file only. +template +class service_base + : public asio::io_service::service +{ +public: + static asio::detail::service_id id; + + // Constructor. + service_base(asio::io_service& io_service) + : asio::io_service::service(io_service) + { + } +}; + +template +asio::detail::service_id service_base::id; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SERVICE_BASE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/service_id.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/service_id.hpp new file mode 100644 index 00000000..baf6cce2 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/service_id.hpp @@ -0,0 +1,37 @@ +// +// service_id.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SERVICE_ID_HPP +#define ASIO_DETAIL_SERVICE_ID_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/io_service.hpp" + +namespace asio { +namespace detail { + +// Special derived service id type to keep classes header-file only. +template +class service_id + : public asio::io_service::id +{ +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SERVICE_ID_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/service_registry.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/service_registry.hpp new file mode 100644 index 00000000..f80b4b69 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/service_registry.hpp @@ -0,0 +1,275 @@ +// +// service_registry.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SERVICE_REGISTRY_HPP +#define ASIO_DETAIL_SERVICE_REGISTRY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/io_service.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/service_id.hpp" + +#if defined(BOOST_NO_TYPEID) +# if !defined(ASIO_NO_TYPEID) +# define ASIO_NO_TYPEID +# endif // !defined(ASIO_NO_TYPEID) +#endif // defined(BOOST_NO_TYPEID) + +namespace asio { +namespace detail { + +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +#endif // defined(__GNUC__) + +template +class typeid_wrapper {}; + +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +#endif // defined(__GNUC__) + +class service_registry + : private noncopyable +{ +public: + // Constructor. + service_registry(asio::io_service& o) + : owner_(o), + first_service_(0) + { + } + + // Destructor. + ~service_registry() + { + // Shutdown all services. This must be done in a separate loop before the + // services are destroyed since the destructors of user-defined handler + // objects may try to access other service objects. + asio::io_service::service* service = first_service_; + while (service) + { + service->shutdown_service(); + service = service->next_; + } + + // Destroy all services. + while (first_service_) + { + asio::io_service::service* next_service = first_service_->next_; + destroy(first_service_); + first_service_ = next_service; + } + } + + // Get the service object corresponding to the specified service type. Will + // create a new service object automatically if no such object already + // exists. Ownership of the service object is not transferred to the caller. + template + Service& use_service() + { + asio::io_service::service::key key; + init_key(key, Service::id); + factory_type factory = &service_registry::create; + return *static_cast(do_use_service(key, factory)); + } + + // Add a service object. Returns false on error, in which case ownership of + // the object is retained by the caller. + template + bool add_service(Service* new_service) + { + asio::io_service::service::key key; + init_key(key, Service::id); + return do_add_service(key, new_service); + } + + // Check whether a service object of the specified type already exists. + template + bool has_service() const + { + asio::io_service::service::key key; + init_key(key, Service::id); + return do_has_service(key); + } + +private: + // Initialise a service's key based on its id. + void init_key(asio::io_service::service::key& key, + const asio::io_service::id& id) + { + key.type_info_ = 0; + key.id_ = &id; + } + +#if !defined(ASIO_NO_TYPEID) + // Initialise a service's key based on its id. + template + void init_key(asio::io_service::service::key& key, + const asio::detail::service_id& /*id*/) + { + key.type_info_ = &typeid(typeid_wrapper); + key.id_ = 0; + } +#endif // !defined(ASIO_NO_TYPEID) + + // Check if a service matches the given id. + static bool keys_match( + const asio::io_service::service::key& key1, + const asio::io_service::service::key& key2) + { + if (key1.id_ && key2.id_) + if (key1.id_ == key2.id_) + return true; + if (key1.type_info_ && key2.type_info_) + if (*key1.type_info_ == *key2.type_info_) + return true; + return false; + } + + // The type of a factory function used for creating a service instance. + typedef asio::io_service::service* + (*factory_type)(asio::io_service&); + + // Factory function for creating a service instance. + template + static asio::io_service::service* create( + asio::io_service& owner) + { + return new Service(owner); + } + + // Destroy a service instance. + static void destroy(asio::io_service::service* service) + { + delete service; + } + + // Helper class to manage service pointers. + struct auto_service_ptr + { + asio::io_service::service* ptr_; + ~auto_service_ptr() { destroy(ptr_); } + }; + + // Get the service object corresponding to the specified service key. Will + // create a new service object automatically if no such object already + // exists. Ownership of the service object is not transferred to the caller. + asio::io_service::service* do_use_service( + const asio::io_service::service::key& key, + factory_type factory) + { + asio::detail::mutex::scoped_lock lock(mutex_); + + // First see if there is an existing service object with the given key. + asio::io_service::service* service = first_service_; + while (service) + { + if (keys_match(service->key_, key)) + return service; + service = service->next_; + } + + // Create a new service object. The service registry's mutex is not locked + // at this time to allow for nested calls into this function from the new + // service's constructor. + lock.unlock(); + auto_service_ptr new_service = { factory(owner_) }; + new_service.ptr_->key_ = key; + lock.lock(); + + // Check that nobody else created another service object of the same type + // while the lock was released. + service = first_service_; + while (service) + { + if (keys_match(service->key_, key)) + return service; + service = service->next_; + } + + // Service was successfully initialised, pass ownership to registry. + new_service.ptr_->next_ = first_service_; + first_service_ = new_service.ptr_; + new_service.ptr_ = 0; + return first_service_; + } + + // Add a service object. Returns false on error, in which case ownership of + // the object is retained by the caller. + bool do_add_service( + const asio::io_service::service::key& key, + asio::io_service::service* new_service) + { + asio::detail::mutex::scoped_lock lock(mutex_); + + // Check if there is an existing service object with the given key. + asio::io_service::service* service = first_service_; + while (service) + { + if (keys_match(service->key_, key)) + return false; + service = service->next_; + } + + // Take ownership of the service object. + new_service->key_ = key; + new_service->next_ = first_service_; + first_service_ = new_service; + + return true; + } + + // Check whether a service object with the specified key already exists. + bool do_has_service(const asio::io_service::service::key& key) const + { + asio::detail::mutex::scoped_lock lock(mutex_); + + asio::io_service::service* service = first_service_; + while (service) + { + if (keys_match(service->key_, key)) + return true; + service = service->next_; + } + + return false; + } + + // Mutex to protect access to internal data. + mutable asio::detail::mutex mutex_; + + // The owner of this service registry and the services it contains. + asio::io_service& owner_; + + // The first service in the list of contained services. + asio::io_service::service* first_service_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SERVICE_REGISTRY_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/service_registry_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/service_registry_fwd.hpp new file mode 100644 index 00000000..423bb4be --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/service_registry_fwd.hpp @@ -0,0 +1,30 @@ +// +// service_registry_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP +#define ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +class service_registry; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/signal_blocker.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/signal_blocker.hpp new file mode 100644 index 00000000..52f70c85 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/signal_blocker.hpp @@ -0,0 +1,50 @@ +// +// signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SIGNAL_BLOCKER_HPP +#define ASIO_DETAIL_SIGNAL_BLOCKER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) +# include "asio/detail/null_signal_blocker.hpp" +#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# include "asio/detail/win_signal_blocker.hpp" +#elif defined(BOOST_HAS_PTHREADS) +# include "asio/detail/posix_signal_blocker.hpp" +#else +# error Only Windows and POSIX are supported! +#endif + +namespace asio { +namespace detail { + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) +typedef null_signal_blocker signal_blocker; +#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef win_signal_blocker signal_blocker; +#elif defined(BOOST_HAS_PTHREADS) +typedef posix_signal_blocker signal_blocker; +#endif + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SIGNAL_BLOCKER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/signal_init.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/signal_init.hpp new file mode 100644 index 00000000..12f17d37 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/signal_init.hpp @@ -0,0 +1,51 @@ +// +// signal_init.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SIGNAL_INIT_HPP +#define ASIO_DETAIL_SIGNAL_INIT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +template +class signal_init +{ +public: + // Constructor. + signal_init() + { + std::signal(Signal, SIG_IGN); + } +}; + +} // namespace detail +} // namespace asio + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SIGNAL_INIT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/socket_holder.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/socket_holder.hpp new file mode 100644 index 00000000..82a38848 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/socket_holder.hpp @@ -0,0 +1,95 @@ +// +// socket_holder.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SOCKET_HOLDER_HPP +#define ASIO_DETAIL_SOCKET_HOLDER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_ops.hpp" + +namespace asio { +namespace detail { + +// Implement the resource acquisition is initialisation idiom for sockets. +class socket_holder + : private noncopyable +{ +public: + // Construct as an uninitialised socket. + socket_holder() + : socket_(invalid_socket) + { + } + + // Construct to take ownership of the specified socket. + explicit socket_holder(socket_type s) + : socket_(s) + { + } + + // Destructor. + ~socket_holder() + { + if (socket_ != invalid_socket) + { + asio::error_code ec; + socket_ops::close(socket_, ec); + } + } + + // Get the underlying socket. + socket_type get() const + { + return socket_; + } + + // Reset to an uninitialised socket. + void reset() + { + if (socket_ != invalid_socket) + { + asio::error_code ec; + socket_ops::close(socket_, ec); + socket_ = invalid_socket; + } + } + + // Reset to take ownership of the specified socket. + void reset(socket_type s) + { + reset(); + socket_ = s; + } + + // Release ownership of the socket. + socket_type release() + { + socket_type tmp = socket_; + socket_ = invalid_socket; + return tmp; + } + +private: + // The underlying socket. + socket_type socket_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SOCKET_HOLDER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/socket_ops.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/socket_ops.hpp new file mode 100644 index 00000000..1a863a91 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/socket_ops.hpp @@ -0,0 +1,1912 @@ +// +// socket_ops.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SOCKET_OPS_HPP +#define ASIO_DETAIL_SOCKET_OPS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace detail { +namespace socket_ops { + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +struct msghdr { int msg_namelen; }; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#if defined(__hpux) +// HP-UX doesn't declare these functions extern "C", so they are declared again +// here to avoid linker errors about undefined symbols. +extern "C" char* if_indextoname(unsigned int, char*); +extern "C" unsigned int if_nametoindex(const char*); +#endif // defined(__hpux) + +inline void clear_error(asio::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + WSASetLastError(0); +#else + errno = 0; +#endif + ec = asio::error_code(); +} + +template +inline ReturnType error_wrapper(ReturnType return_value, + asio::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + ec = asio::error_code(WSAGetLastError(), + asio::error::get_system_category()); +#else + ec = asio::error_code(errno, + asio::error::get_system_category()); +#endif + return return_value; +} + +template +inline socket_type call_accept(SockLenType msghdr::*, + socket_type s, socket_addr_type* addr, std::size_t* addrlen) +{ + SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0; + socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0); + if (addrlen) + *addrlen = (std::size_t)tmp_addrlen; + return result; +} + +inline socket_type accept(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, asio::error_code& ec) +{ + clear_error(ec); + + socket_type new_s = error_wrapper(call_accept( + &msghdr::msg_namelen, s, addr, addrlen), ec); + if (new_s == invalid_socket) + return new_s; + +#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__) + int optval = 1; + int result = error_wrapper(::setsockopt(new_s, + SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec); + if (result != 0) + { + ::close(new_s); + return invalid_socket; + } +#endif + + clear_error(ec); + return new_s; +} + +template +inline int call_bind(SockLenType msghdr::*, + socket_type s, const socket_addr_type* addr, std::size_t addrlen) +{ + return ::bind(s, addr, (SockLenType)addrlen); +} + +inline int bind(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(call_bind( + &msghdr::msg_namelen, s, addr, addrlen), ec); + if (result == 0) + clear_error(ec); + return result; +} + +inline int close(socket_type s, asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::closesocket(s), ec); +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::close(s), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (result == 0) + clear_error(ec); + return result; +} + +inline int shutdown(socket_type s, int what, asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::shutdown(s, what), ec); + if (result == 0) + clear_error(ec); + return result; +} + +template +inline int call_connect(SockLenType msghdr::*, + socket_type s, const socket_addr_type* addr, std::size_t addrlen) +{ + return ::connect(s, addr, (SockLenType)addrlen); +} + +inline int connect(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(call_connect( + &msghdr::msg_namelen, s, addr, addrlen), ec); + if (result == 0) + clear_error(ec); + return result; +} + +inline int socketpair(int af, int type, int protocol, + socket_type sv[2], asio::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + (void)(af); + (void)(type); + (void)(protocol); + (void)(sv); + ec = asio::error::operation_not_supported; + return -1; +#else + clear_error(ec); + int result = error_wrapper(::socketpair(af, type, protocol, sv), ec); + if (result == 0) + clear_error(ec); + return result; +#endif +} + +inline int listen(socket_type s, int backlog, asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::listen(s, backlog), ec); + if (result == 0) + clear_error(ec); + return result; +} + +inline void init_buf_iov_base(void*& base, void* addr) +{ + base = addr; +} + +template +inline void init_buf_iov_base(T& base, void* addr) +{ + base = static_cast(addr); +} + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef WSABUF buf; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef iovec buf; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +inline void init_buf(buf& b, void* data, size_t size) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + b.buf = static_cast(data); + b.len = static_cast(size); +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + init_buf_iov_base(b.iov_base, data); + b.iov_len = size; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline void init_buf(buf& b, const void* data, size_t size) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + b.buf = static_cast(const_cast(data)); + b.len = static_cast(size); +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + init_buf_iov_base(b.iov_base, const_cast(data)); + b.iov_len = size; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr) +{ + name = addr; +} + +inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr) +{ + name = const_cast(addr); +} + +template +inline void init_msghdr_msg_name(T& name, socket_addr_type* addr) +{ + name = reinterpret_cast(addr); +} + +template +inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr) +{ + name = reinterpret_cast(const_cast(addr)); +} + +inline int recv(socket_type s, buf* bufs, size_t count, int flags, + asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Receive some data. + DWORD recv_buf_count = static_cast(count); + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int result = error_wrapper(::WSARecv(s, bufs, + recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); + if (result != 0) + return -1; + clear_error(ec); + return bytes_transferred; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + msg.msg_iov = bufs; + msg.msg_iovlen = count; + int result = error_wrapper(::recvmsg(s, &msg, flags), ec); + if (result >= 0) + clear_error(ec); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags, + socket_addr_type* addr, std::size_t* addrlen, + asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Receive some data. + DWORD recv_buf_count = static_cast(count); + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int tmp_addrlen = (int)*addrlen; + int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, + &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec); + *addrlen = (std::size_t)tmp_addrlen; + if (result != 0) + return -1; + clear_error(ec); + return bytes_transferred; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + init_msghdr_msg_name(msg.msg_name, addr); + msg.msg_namelen = *addrlen; + msg.msg_iov = bufs; + msg.msg_iovlen = count; + int result = error_wrapper(::recvmsg(s, &msg, flags), ec); + *addrlen = msg.msg_namelen; + if (result >= 0) + clear_error(ec); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int send(socket_type s, const buf* bufs, size_t count, int flags, + asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Send the data. + DWORD send_buf_count = static_cast(count); + DWORD bytes_transferred = 0; + DWORD send_flags = flags; + int result = error_wrapper(::WSASend(s, const_cast(bufs), + send_buf_count, &bytes_transferred, send_flags, 0, 0), ec); + if (result != 0) + return -1; + clear_error(ec); + return bytes_transferred; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + msg.msg_iov = const_cast(bufs); + msg.msg_iovlen = count; +#if defined(__linux__) + flags |= MSG_NOSIGNAL; +#endif // defined(__linux__) + int result = error_wrapper(::sendmsg(s, &msg, flags), ec); + if (result >= 0) + clear_error(ec); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int sendto(socket_type s, const buf* bufs, size_t count, int flags, + const socket_addr_type* addr, std::size_t addrlen, + asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Send the data. + DWORD send_buf_count = static_cast(count); + DWORD bytes_transferred = 0; + int result = error_wrapper(::WSASendTo(s, const_cast(bufs), + send_buf_count, &bytes_transferred, flags, addr, + static_cast(addrlen), 0, 0), ec); + if (result != 0) + return -1; + clear_error(ec); + return bytes_transferred; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + init_msghdr_msg_name(msg.msg_name, addr); + msg.msg_namelen = addrlen; + msg.msg_iov = const_cast(bufs); + msg.msg_iovlen = count; +#if defined(__linux__) + flags |= MSG_NOSIGNAL; +#endif // defined(__linux__) + int result = error_wrapper(::sendmsg(s, &msg, flags), ec); + if (result >= 0) + clear_error(ec); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline socket_type socket(int af, int type, int protocol, + asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + socket_type s = error_wrapper(::WSASocket(af, type, protocol, 0, 0, + WSA_FLAG_OVERLAPPED), ec); + if (s == invalid_socket) + return s; + + if (af == AF_INET6) + { + // Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to + // false. This will only succeed on Windows Vista and later versions of + // Windows, where a dual-stack IPv4/v6 implementation is available. + DWORD optval = 0; + ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, + reinterpret_cast(&optval), sizeof(optval)); + } + + clear_error(ec); + + return s; +#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__) + socket_type s = error_wrapper(::socket(af, type, protocol), ec); + if (s == invalid_socket) + return s; + + int optval = 1; + int result = error_wrapper(::setsockopt(s, + SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec); + if (result != 0) + { + ::close(s); + return invalid_socket; + } + + return s; +#else + int s = error_wrapper(::socket(af, type, protocol), ec); + if (s >= 0) + clear_error(ec); + return s; +#endif +} + +template +inline int call_setsockopt(SockLenType msghdr::*, + socket_type s, int level, int optname, + const void* optval, std::size_t optlen) +{ + return ::setsockopt(s, level, optname, + (const char*)optval, (SockLenType)optlen); +} + +inline int setsockopt(socket_type s, int level, int optname, + const void* optval, std::size_t optlen, asio::error_code& ec) +{ + if (level == custom_socket_option_level && optname == always_fail_option) + { + ec = asio::error::invalid_argument; + return -1; + } + +#if defined(__BORLANDC__) + // Mysteriously, using the getsockopt and setsockopt functions directly with + // Borland C++ results in incorrect values being set and read. The bug can be + // worked around by using function addresses resolved with GetProcAddress. + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + typedef int (WSAAPI *sso_t)(SOCKET, int, int, const char*, int); + if (sso_t sso = (sso_t)::GetProcAddress(winsock_module, "setsockopt")) + { + clear_error(ec); + return error_wrapper(sso(s, level, optname, + reinterpret_cast(optval), + static_cast(optlen)), ec); + } + } + ec = asio::error::fault; + return -1; +#else // defined(__BORLANDC__) + clear_error(ec); + int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen, + s, level, optname, optval, optlen), ec); + if (result == 0) + clear_error(ec); + return result; +#endif // defined(__BORLANDC__) +} + +template +inline int call_getsockopt(SockLenType msghdr::*, + socket_type s, int level, int optname, + void* optval, std::size_t* optlen) +{ + SockLenType tmp_optlen = (SockLenType)*optlen; + int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen); + *optlen = (std::size_t)tmp_optlen; + return result; +} + +inline int getsockopt(socket_type s, int level, int optname, void* optval, + size_t* optlen, asio::error_code& ec) +{ + if (level == custom_socket_option_level && optname == always_fail_option) + { + ec = asio::error::invalid_argument; + return -1; + } + +#if defined(__BORLANDC__) + // Mysteriously, using the getsockopt and setsockopt functions directly with + // Borland C++ results in incorrect values being set and read. The bug can be + // worked around by using function addresses resolved with GetProcAddress. + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + typedef int (WSAAPI *gso_t)(SOCKET, int, int, char*, int*); + if (gso_t gso = (gso_t)::GetProcAddress(winsock_module, "getsockopt")) + { + clear_error(ec); + int tmp_optlen = static_cast(*optlen); + int result = error_wrapper(gso(s, level, optname, + reinterpret_cast(optval), &tmp_optlen), ec); + *optlen = static_cast(tmp_optlen); + if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY + && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD)) + { + // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are + // only supported on Windows Vista and later. To simplify program logic + // we will fake success of getting this option and specify that the + // value is non-zero (i.e. true). This corresponds to the behavior of + // IPv6 sockets on Windows platforms pre-Vista. + *static_cast(optval) = 1; + clear_error(ec); + } + return result; + } + } + ec = asio::error::fault; + return -1; +#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) + clear_error(ec); + int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, + s, level, optname, optval, optlen), ec); + if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY + && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD)) + { + // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are only + // supported on Windows Vista and later. To simplify program logic we will + // fake success of getting this option and specify that the value is + // non-zero (i.e. true). This corresponds to the behavior of IPv6 sockets + // on Windows platforms pre-Vista. + *static_cast(optval) = 1; + clear_error(ec); + } + if (result == 0) + clear_error(ec); + return result; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + clear_error(ec); + int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, + s, level, optname, optval, optlen), ec); +#if defined(__linux__) + if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int) + && (optname == SO_SNDBUF || optname == SO_RCVBUF)) + { + // On Linux, setting SO_SNDBUF or SO_RCVBUF to N actually causes the kernel + // to set the buffer size to N*2. Linux puts additional stuff into the + // buffers so that only about half is actually available to the application. + // The retrieved value is divided by 2 here to make it appear as though the + // correct value has been set. + *static_cast(optval) /= 2; + } +#endif // defined(__linux__) + if (result == 0) + clear_error(ec); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +template +inline int call_getpeername(SockLenType msghdr::*, + socket_type s, socket_addr_type* addr, std::size_t* addrlen) +{ + SockLenType tmp_addrlen = (SockLenType)*addrlen; + int result = ::getpeername(s, addr, &tmp_addrlen); + *addrlen = (std::size_t)tmp_addrlen; + return result; +} + +inline int getpeername(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(call_getpeername( + &msghdr::msg_namelen, s, addr, addrlen), ec); + if (result == 0) + clear_error(ec); + return result; +} + +template +inline int call_getsockname(SockLenType msghdr::*, + socket_type s, socket_addr_type* addr, std::size_t* addrlen) +{ + SockLenType tmp_addrlen = (SockLenType)*addrlen; + int result = ::getsockname(s, addr, &tmp_addrlen); + *addrlen = (std::size_t)tmp_addrlen; + return result; +} + +inline int getsockname(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(call_getsockname( + &msghdr::msg_namelen, s, addr, addrlen), ec); + if (result == 0) + clear_error(ec); + return result; +} + +inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg, + asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec); +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::ioctl(s, cmd, arg), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (result >= 0) + clear_error(ec); + return result; +} + +inline int select(int nfds, fd_set* readfds, fd_set* writefds, + fd_set* exceptfds, timeval* timeout, asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (!readfds && !writefds && !exceptfds && timeout) + { + DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; + if (milliseconds == 0) + milliseconds = 1; // Force context switch. + ::Sleep(milliseconds); + ec = asio::error_code(); + return 0; + } + + // The select() call allows timeout values measured in microseconds, but the + // system clock (as wrapped by boost::posix_time::microsec_clock) typically + // has a resolution of 10 milliseconds. This can lead to a spinning select + // reactor, meaning increased CPU usage, when waiting for the earliest + // scheduled timeout if it's less than 10 milliseconds away. To avoid a tight + // spin we'll use a minimum timeout of 1 millisecond. + if (timeout && timeout->tv_sec == 0 + && timeout->tv_usec > 0 && timeout->tv_usec < 1000) + timeout->tv_usec = 1000; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#if defined(__hpux) && defined(__HP_aCC) + timespec ts; + ts.tv_sec = timeout ? timeout->tv_sec : 0; + ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0; + return error_wrapper(::pselect(nfds, readfds, + writefds, exceptfds, timeout ? &ts : 0, 0), ec); +#else + int result = error_wrapper(::select(nfds, readfds, + writefds, exceptfds, timeout), ec); + if (result >= 0) + clear_error(ec); + return result; +#endif +} + +inline int poll_read(socket_type s, asio::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + FD_SET fds; + FD_ZERO(&fds); + FD_SET(s, &fds); + clear_error(ec); + int result = error_wrapper(::select(s, &fds, 0, 0, 0), ec); + if (result >= 0) + clear_error(ec); + return result; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + pollfd fds; + fds.fd = s; + fds.events = POLLIN; + fds.revents = 0; + clear_error(ec); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + clear_error(ec); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int poll_write(socket_type s, asio::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + FD_SET fds; + FD_ZERO(&fds); + FD_SET(s, &fds); + clear_error(ec); + int result = error_wrapper(::select(s, 0, &fds, 0, 0), ec); + if (result >= 0) + clear_error(ec); + return result; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + pollfd fds; + fds.fd = s; + fds.events = POLLOUT; + fds.revents = 0; + clear_error(ec); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + clear_error(ec); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int poll_connect(socket_type s, asio::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + FD_SET write_fds; + FD_ZERO(&write_fds); + FD_SET(s, &write_fds); + FD_SET except_fds; + FD_ZERO(&except_fds); + FD_SET(s, &except_fds); + clear_error(ec); + int result = error_wrapper(::select(s, 0, &write_fds, &except_fds, 0), ec); + if (result >= 0) + clear_error(ec); + return result; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + pollfd fds; + fds.fd = s; + fds.events = POLLOUT; + fds.revents = 0; + clear_error(ec); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + clear_error(ec); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline const char* inet_ntop(int af, const void* src, char* dest, size_t length, + unsigned long scope_id, asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + using namespace std; // For memcpy. + + if (af != AF_INET && af != AF_INET6) + { + ec = asio::error::address_family_not_supported; + return 0; + } + + union + { + socket_addr_type base; + sockaddr_storage_type storage; + sockaddr_in4_type v4; + sockaddr_in6_type v6; + } address; + DWORD address_length; + if (af == AF_INET) + { + address_length = sizeof(sockaddr_in4_type); + address.v4.sin_family = AF_INET; + address.v4.sin_port = 0; + memcpy(&address.v4.sin_addr, src, sizeof(in4_addr_type)); + } + else // AF_INET6 + { + address_length = sizeof(sockaddr_in6_type); + address.v6.sin6_family = AF_INET6; + address.v6.sin6_port = 0; + address.v6.sin6_flowinfo = 0; + address.v6.sin6_scope_id = scope_id; + memcpy(&address.v6.sin6_addr, src, sizeof(in6_addr_type)); + } + + DWORD string_length = static_cast(length); +#if defined(BOOST_NO_ANSI_APIS) + LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR)); + int result = error_wrapper(::WSAAddressToStringW(&address.base, + address_length, 0, string_buffer, &string_length), ec); + ::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, length, 0, 0); +#else + int result = error_wrapper(::WSAAddressToStringA( + &address.base, address_length, 0, dest, &string_length), ec); +#endif + + // Windows may set error code on success. + if (result != socket_error_retval) + clear_error(ec); + + // Windows may not set an error code on failure. + else if (result == socket_error_retval && !ec) + ec = asio::error::invalid_argument; + + return result == socket_error_retval ? 0 : dest; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + const char* result = error_wrapper(::inet_ntop(af, src, dest, length), ec); + if (result == 0 && !ec) + ec = asio::error::invalid_argument; + if (result != 0 && af == AF_INET6 && scope_id != 0) + { + using namespace std; // For strcat and sprintf. + char if_name[IF_NAMESIZE + 1] = "%"; + const in6_addr_type* ipv6_address = static_cast(src); + bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address); + if (!is_link_local || if_indextoname(scope_id, if_name + 1) == 0) + sprintf(if_name + 1, "%lu", scope_id); + strcat(dest, if_name); + } + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int inet_pton(int af, const char* src, void* dest, + unsigned long* scope_id, asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + using namespace std; // For memcpy and strcmp. + + if (af != AF_INET && af != AF_INET6) + { + ec = asio::error::address_family_not_supported; + return -1; + } + + union + { + socket_addr_type base; + sockaddr_storage_type storage; + sockaddr_in4_type v4; + sockaddr_in6_type v6; + } address; + int address_length = sizeof(sockaddr_storage_type); +#if defined(BOOST_NO_ANSI_APIS) + int num_wide_chars = strlen(src) + 1; + LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR)); + ::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars); + int result = error_wrapper(::WSAStringToAddressW( + wide_buffer, af, 0, &address.base, &address_length), ec); +#else + int result = error_wrapper(::WSAStringToAddressA( + const_cast(src), af, 0, &address.base, &address_length), ec); +#endif + + if (af == AF_INET) + { + if (result != socket_error_retval) + { + memcpy(dest, &address.v4.sin_addr, sizeof(in4_addr_type)); + clear_error(ec); + } + else if (strcmp(src, "255.255.255.255") == 0) + { + static_cast(dest)->s_addr = INADDR_NONE; + clear_error(ec); + } + } + else // AF_INET6 + { + if (result != socket_error_retval) + { + memcpy(dest, &address.v6.sin6_addr, sizeof(in6_addr_type)); + if (scope_id) + *scope_id = address.v6.sin6_scope_id; + clear_error(ec); + } + } + + // Windows may not set an error code on failure. + if (result == socket_error_retval && !ec) + ec = asio::error::invalid_argument; + + if (result != socket_error_retval) + clear_error(ec); + + return result == socket_error_retval ? -1 : 1; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::inet_pton(af, src, dest), ec); + if (result <= 0 && !ec) + ec = asio::error::invalid_argument; + if (result > 0 && af == AF_INET6 && scope_id) + { + using namespace std; // For strchr and atoi. + *scope_id = 0; + if (const char* if_name = strchr(src, '%')) + { + in6_addr_type* ipv6_address = static_cast(dest); + bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address); + if (is_link_local) + *scope_id = if_nametoindex(if_name + 1); + if (*scope_id == 0) + *scope_id = atoi(if_name + 1); + } + } + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline int gethostname(char* name, int namelen, asio::error_code& ec) +{ + clear_error(ec); + int result = error_wrapper(::gethostname(name, namelen), ec); +#if defined(BOOST_WINDOWS) + if (result == 0) + clear_error(ec); +#endif + return result; +} + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \ + || defined(__MACH__) && defined(__APPLE__) + +// The following functions are only needed for emulation of getaddrinfo and +// getnameinfo. + +inline asio::error_code translate_netdb_error(int error) +{ + switch (error) + { + case 0: + return asio::error_code(); + case HOST_NOT_FOUND: + return asio::error::host_not_found; + case TRY_AGAIN: + return asio::error::host_not_found_try_again; + case NO_RECOVERY: + return asio::error::no_recovery; + case NO_DATA: + return asio::error::no_data; + default: + BOOST_ASSERT(false); + return asio::error::invalid_argument; + } +} + +inline hostent* gethostbyaddr(const char* addr, int length, int af, + hostent* result, char* buffer, int buflength, asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + (void)(buffer); + (void)(buflength); + hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec); + if (!retval) + return 0; + clear_error(ec); + *result = *retval; + return retval; +#elif defined(__sun) || defined(__QNX__) + int error = 0; + hostent* retval = error_wrapper(::gethostbyaddr_r(addr, length, af, result, + buffer, buflength, &error), ec); + if (error) + ec = translate_netdb_error(error); + return retval; +#elif defined(__MACH__) && defined(__APPLE__) + (void)(buffer); + (void)(buflength); + int error = 0; + hostent* retval = error_wrapper(::getipnodebyaddr( + addr, length, af, &error), ec); + if (error) + ec = translate_netdb_error(error); + if (!retval) + return 0; + *result = *retval; + return retval; +#else + hostent* retval = 0; + int error = 0; + error_wrapper(::gethostbyaddr_r(addr, length, af, result, buffer, + buflength, &retval, &error), ec); + if (error) + ec = translate_netdb_error(error); + return retval; +#endif +} + +inline hostent* gethostbyname(const char* name, int af, struct hostent* result, + char* buffer, int buflength, int ai_flags, asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + (void)(buffer); + (void)(buflength); + (void)(ai_flags); + if (af != AF_INET) + { + ec = asio::error::address_family_not_supported; + return 0; + } + hostent* retval = error_wrapper(::gethostbyname(name), ec); + if (!retval) + return 0; + clear_error(ec); + *result = *retval; + return result; +#elif defined(__sun) || defined(__QNX__) + (void)(ai_flags); + if (af != AF_INET) + { + ec = asio::error::address_family_not_supported; + return 0; + } + int error = 0; + hostent* retval = error_wrapper(::gethostbyname_r(name, result, buffer, + buflength, &error), ec); + if (error) + ec = translate_netdb_error(error); + return retval; +#elif defined(__MACH__) && defined(__APPLE__) + (void)(buffer); + (void)(buflength); + int error = 0; + hostent* retval = error_wrapper(::getipnodebyname( + name, af, ai_flags, &error), ec); + if (error) + ec = translate_netdb_error(error); + if (!retval) + return 0; + *result = *retval; + return retval; +#else + (void)(ai_flags); + if (af != AF_INET) + { + ec = asio::error::address_family_not_supported; + return 0; + } + hostent* retval = 0; + int error = 0; + error_wrapper(::gethostbyname_r(name, result, + buffer, buflength, &retval, &error), ec); + if (error) + ec = translate_netdb_error(error); + return retval; +#endif +} + +inline void freehostent(hostent* h) +{ +#if defined(__MACH__) && defined(__APPLE__) + if (h) + ::freehostent(h); +#else + (void)(h); +#endif +} + +// Emulation of getaddrinfo based on implementation in: +// Stevens, W. R., UNIX Network Programming Vol. 1, 2nd Ed., Prentice-Hall 1998. + +struct gai_search +{ + const char* host; + int family; +}; + +inline int gai_nsearch(const char* host, + const addrinfo_type* hints, gai_search (&search)[2]) +{ + int search_count = 0; + if (host == 0 || host[0] == '\0') + { + if (hints->ai_flags & AI_PASSIVE) + { + // No host and AI_PASSIVE implies wildcard bind. + switch (hints->ai_family) + { + case AF_INET: + search[search_count].host = "0.0.0.0"; + search[search_count].family = AF_INET; + ++search_count; + break; + case AF_INET6: + search[search_count].host = "0::0"; + search[search_count].family = AF_INET6; + ++search_count; + break; + case AF_UNSPEC: + search[search_count].host = "0::0"; + search[search_count].family = AF_INET6; + ++search_count; + search[search_count].host = "0.0.0.0"; + search[search_count].family = AF_INET; + ++search_count; + break; + default: + break; + } + } + else + { + // No host and not AI_PASSIVE means connect to local host. + switch (hints->ai_family) + { + case AF_INET: + search[search_count].host = "localhost"; + search[search_count].family = AF_INET; + ++search_count; + break; + case AF_INET6: + search[search_count].host = "localhost"; + search[search_count].family = AF_INET6; + ++search_count; + break; + case AF_UNSPEC: + search[search_count].host = "localhost"; + search[search_count].family = AF_INET6; + ++search_count; + search[search_count].host = "localhost"; + search[search_count].family = AF_INET; + ++search_count; + break; + default: + break; + } + } + } + else + { + // Host is specified. + switch (hints->ai_family) + { + case AF_INET: + search[search_count].host = host; + search[search_count].family = AF_INET; + ++search_count; + break; + case AF_INET6: + search[search_count].host = host; + search[search_count].family = AF_INET6; + ++search_count; + break; + case AF_UNSPEC: + search[search_count].host = host; + search[search_count].family = AF_INET6; + ++search_count; + search[search_count].host = host; + search[search_count].family = AF_INET; + ++search_count; + break; + default: + break; + } + } + return search_count; +} + +template +inline T* gai_alloc(std::size_t size = sizeof(T)) +{ + using namespace std; + T* p = static_cast(::operator new(size, std::nothrow)); + if (p) + memset(p, 0, size); + return p; +} + +inline void gai_free(void* p) +{ + ::operator delete(p); +} + +inline void gai_strcpy(char* target, const char* source, std::size_t max_size) +{ + using namespace std; +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) + strcpy_s(target, max_size, source); +#else + *target = 0; + strncat(target, source, max_size); +#endif +} + +enum { gai_clone_flag = 1 << 30 }; + +inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints, + const void* addr, int family) +{ + using namespace std; + + addrinfo_type* ai = gai_alloc(); + if (ai == 0) + return EAI_MEMORY; + + ai->ai_next = 0; + **next = ai; + *next = &ai->ai_next; + + ai->ai_canonname = 0; + ai->ai_socktype = hints->ai_socktype; + if (ai->ai_socktype == 0) + ai->ai_flags |= gai_clone_flag; + ai->ai_protocol = hints->ai_protocol; + ai->ai_family = family; + + switch (ai->ai_family) + { + case AF_INET: + { + sockaddr_in4_type* sinptr = gai_alloc(); + if (sinptr == 0) + return EAI_MEMORY; + sinptr->sin_family = AF_INET; + memcpy(&sinptr->sin_addr, addr, sizeof(in4_addr_type)); + ai->ai_addr = reinterpret_cast(sinptr); + ai->ai_addrlen = sizeof(sockaddr_in4_type); + break; + } + case AF_INET6: + { + sockaddr_in6_type* sin6ptr = gai_alloc(); + if (sin6ptr == 0) + return EAI_MEMORY; + sin6ptr->sin6_family = AF_INET6; + memcpy(&sin6ptr->sin6_addr, addr, sizeof(in6_addr_type)); + ai->ai_addr = reinterpret_cast(sin6ptr); + ai->ai_addrlen = sizeof(sockaddr_in6_type); + break; + } + default: + break; + } + + return 0; +} + +inline addrinfo_type* gai_clone(addrinfo_type* ai) +{ + using namespace std; + + addrinfo_type* new_ai = gai_alloc(); + if (new_ai == 0) + return new_ai; + + new_ai->ai_next = ai->ai_next; + ai->ai_next = new_ai; + + new_ai->ai_flags = 0; + new_ai->ai_family = ai->ai_family; + new_ai->ai_socktype = ai->ai_socktype; + new_ai->ai_protocol = ai->ai_protocol; + new_ai->ai_canonname = 0; + new_ai->ai_addrlen = ai->ai_addrlen; + new_ai->ai_addr = gai_alloc(ai->ai_addrlen); + memcpy(new_ai->ai_addr, ai->ai_addr, ai->ai_addrlen); + + return new_ai; +} + +inline int gai_port(addrinfo_type* aihead, int port, int socktype) +{ + int num_found = 0; + + for (addrinfo_type* ai = aihead; ai; ai = ai->ai_next) + { + if (ai->ai_flags & gai_clone_flag) + { + if (ai->ai_socktype != 0) + { + ai = gai_clone(ai); + if (ai == 0) + return -1; + // ai now points to newly cloned entry. + } + } + else if (ai->ai_socktype != socktype) + { + // Ignore if mismatch on socket type. + continue; + } + + ai->ai_socktype = socktype; + + switch (ai->ai_family) + { + case AF_INET: + { + sockaddr_in4_type* sinptr = + reinterpret_cast(ai->ai_addr); + sinptr->sin_port = port; + ++num_found; + break; + } + case AF_INET6: + { + sockaddr_in6_type* sin6ptr = + reinterpret_cast(ai->ai_addr); + sin6ptr->sin6_port = port; + ++num_found; + break; + } + default: + break; + } + } + + return num_found; +} + +inline int gai_serv(addrinfo_type* aihead, + const addrinfo_type* hints, const char* serv) +{ + using namespace std; + + int num_found = 0; + + if ( +#if defined(AI_NUMERICSERV) + (hints->ai_flags & AI_NUMERICSERV) || +#endif + isdigit(serv[0])) + { + int port = htons(atoi(serv)); + if (hints->ai_socktype) + { + // Caller specifies socket type. + int rc = gai_port(aihead, port, hints->ai_socktype); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + } + else + { + // Caller does not specify socket type. + int rc = gai_port(aihead, port, SOCK_STREAM); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + rc = gai_port(aihead, port, SOCK_DGRAM); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + } + } + else + { + // Try service name with TCP first, then UDP. + if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_STREAM) + { + servent* sptr = getservbyname(serv, "tcp"); + if (sptr != 0) + { + int rc = gai_port(aihead, sptr->s_port, SOCK_STREAM); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + } + } + if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_DGRAM) + { + servent* sptr = getservbyname(serv, "udp"); + if (sptr != 0) + { + int rc = gai_port(aihead, sptr->s_port, SOCK_DGRAM); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + } + } + } + + if (num_found == 0) + { + if (hints->ai_socktype == 0) + { + // All calls to getservbyname() failed. + return EAI_NONAME; + } + else + { + // Service not supported for socket type. + return EAI_SERVICE; + } + } + + return 0; +} + +inline int gai_echeck(const char* host, const char* service, + int flags, int family, int socktype, int protocol) +{ + (void)(flags); + (void)(protocol); + + // Host or service must be specified. + if (host == 0 || host[0] == '\0') + if (service == 0 || service[0] == '\0') + return EAI_NONAME; + + // Check combination of family and socket type. + switch (family) + { + case AF_UNSPEC: + break; + case AF_INET: + case AF_INET6: + if (service != 0 && service[0] != '\0') + if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM) + return EAI_SOCKTYPE; + break; + default: + return EAI_FAMILY; + } + + return 0; +} + +inline void freeaddrinfo_emulation(addrinfo_type* aihead) +{ + addrinfo_type* ai = aihead; + while (ai) + { + gai_free(ai->ai_addr); + gai_free(ai->ai_canonname); + addrinfo_type* ainext = ai->ai_next; + gai_free(ai); + ai = ainext; + } +} + +inline int getaddrinfo_emulation(const char* host, const char* service, + const addrinfo_type* hintsp, addrinfo_type** result) +{ + // Set up linked list of addrinfo structures. + addrinfo_type* aihead = 0; + addrinfo_type** ainext = &aihead; + char* canon = 0; + + // Supply default hints if not specified by caller. + addrinfo_type hints = addrinfo_type(); + hints.ai_family = AF_UNSPEC; + if (hintsp) + hints = *hintsp; + + // If the resolution is not specifically for AF_INET6, remove the AI_V4MAPPED + // and AI_ALL flags. +#if defined(AI_V4MAPPED) + if (hints.ai_family != AF_INET6) + hints.ai_flags &= ~AI_V4MAPPED; +#endif +#if defined(AI_ALL) + if (hints.ai_family != AF_INET6) + hints.ai_flags &= ~AI_ALL; +#endif + + // Basic error checking. + int rc = gai_echeck(host, service, hints.ai_flags, hints.ai_family, + hints.ai_socktype, hints.ai_protocol); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + return rc; + } + + gai_search search[2]; + int search_count = gai_nsearch(host, &hints, search); + for (gai_search* sptr = search; sptr < search + search_count; ++sptr) + { + // Check for IPv4 dotted decimal string. + in4_addr_type inaddr; + asio::error_code ec; + if (socket_ops::inet_pton(AF_INET, sptr->host, &inaddr, 0, ec) == 1) + { + if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + return EAI_FAMILY; + } + if (sptr->family == AF_INET) + { + rc = gai_aistruct(&ainext, &hints, &inaddr, AF_INET); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + return rc; + } + } + continue; + } + + // Check for IPv6 hex string. + in6_addr_type in6addr; + if (socket_ops::inet_pton(AF_INET6, sptr->host, &in6addr, 0, ec) == 1) + { + if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET6) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + return EAI_FAMILY; + } + if (sptr->family == AF_INET6) + { + rc = gai_aistruct(&ainext, &hints, &in6addr, AF_INET6); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + return rc; + } + } + continue; + } + + // Look up hostname. + hostent hent; + char hbuf[8192] = ""; + hostent* hptr = socket_ops::gethostbyname(sptr->host, + sptr->family, &hent, hbuf, sizeof(hbuf), hints.ai_flags, ec); + if (hptr == 0) + { + if (search_count == 2) + { + // Failure is OK if there are multiple searches. + continue; + } + freeaddrinfo_emulation(aihead); + gai_free(canon); + if (ec == asio::error::host_not_found) + return EAI_NONAME; + if (ec == asio::error::host_not_found_try_again) + return EAI_AGAIN; + if (ec == asio::error::no_recovery) + return EAI_FAIL; + if (ec == asio::error::no_data) + return EAI_NONAME; + return EAI_NONAME; + } + + // Check for address family mismatch if one was specified. + if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + socket_ops::freehostent(hptr); + return EAI_FAMILY; + } + + // Save canonical name first time. + if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0] + && (hints.ai_flags & AI_CANONNAME) && canon == 0) + { + std::size_t canon_len = strlen(hptr->h_name) + 1; + canon = gai_alloc(canon_len); + if (canon == 0) + { + freeaddrinfo_emulation(aihead); + socket_ops::freehostent(hptr); + return EAI_MEMORY; + } + gai_strcpy(canon, hptr->h_name, canon_len); + } + + // Create an addrinfo structure for each returned address. + for (char** ap = hptr->h_addr_list; *ap; ++ap) + { + rc = gai_aistruct(&ainext, &hints, *ap, hptr->h_addrtype); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + socket_ops::freehostent(hptr); + return EAI_FAMILY; + } + } + + socket_ops::freehostent(hptr); + } + + // Check if we found anything. + if (aihead == 0) + { + gai_free(canon); + return EAI_NONAME; + } + + // Return canonical name in first entry. + if (host != 0 && host[0] != '\0' && (hints.ai_flags & AI_CANONNAME)) + { + if (canon) + { + aihead->ai_canonname = canon; + canon = 0; + } + else + { + std::size_t canonname_len = strlen(search[0].host) + 1; + aihead->ai_canonname = gai_alloc(canonname_len); + if (aihead->ai_canonname == 0) + { + freeaddrinfo_emulation(aihead); + return EAI_MEMORY; + } + gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len); + } + } + gai_free(canon); + + // Process the service name. + if (service != 0 && service[0] != '\0') + { + rc = gai_serv(aihead, &hints, service); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + return rc; + } + } + + // Return result to caller. + *result = aihead; + return 0; +} + +inline asio::error_code getnameinfo_emulation( + const socket_addr_type* sa, std::size_t salen, char* host, + std::size_t hostlen, char* serv, std::size_t servlen, int flags, + asio::error_code& ec) +{ + using namespace std; + + const char* addr; + size_t addr_len; + unsigned short port; + switch (sa->sa_family) + { + case AF_INET: + if (salen != sizeof(sockaddr_in4_type)) + { + return ec = asio::error::invalid_argument; + } + addr = reinterpret_cast( + &reinterpret_cast(sa)->sin_addr); + addr_len = sizeof(in4_addr_type); + port = reinterpret_cast(sa)->sin_port; + break; + case AF_INET6: + if (salen != sizeof(sockaddr_in6_type)) + { + return ec = asio::error::invalid_argument; + } + addr = reinterpret_cast( + &reinterpret_cast(sa)->sin6_addr); + addr_len = sizeof(in6_addr_type); + port = reinterpret_cast(sa)->sin6_port; + break; + default: + return ec = asio::error::address_family_not_supported; + } + + if (host && hostlen > 0) + { + if (flags & NI_NUMERICHOST) + { + if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen, 0, ec) == 0) + { + return ec; + } + } + else + { + hostent hent; + char hbuf[8192] = ""; + hostent* hptr = socket_ops::gethostbyaddr(addr, + static_cast(addr_len), sa->sa_family, + &hent, hbuf, sizeof(hbuf), ec); + if (hptr && hptr->h_name && hptr->h_name[0] != '\0') + { + if (flags & NI_NOFQDN) + { + char* dot = strchr(hptr->h_name, '.'); + if (dot) + { + *dot = 0; + } + } + gai_strcpy(host, hptr->h_name, hostlen); + socket_ops::freehostent(hptr); + } + else + { + socket_ops::freehostent(hptr); + if (flags & NI_NAMEREQD) + { + return ec = asio::error::host_not_found; + } + if (socket_ops::inet_ntop(sa->sa_family, + addr, host, hostlen, 0, ec) == 0) + { + return ec; + } + } + } + } + + if (serv && servlen > 0) + { + if (flags & NI_NUMERICSERV) + { + if (servlen < 6) + { + return ec = asio::error::no_buffer_space; + } +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) + sprintf_s(serv, servlen, "%u", ntohs(port)); +#else + sprintf(serv, "%u", ntohs(port)); +#endif + } + else + { +#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) + static ::pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + ::pthread_mutex_lock(&mutex); +#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) + servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0); + if (sptr && sptr->s_name && sptr->s_name[0] != '\0') + { + gai_strcpy(serv, sptr->s_name, servlen); + } + else + { + if (servlen < 6) + { + return ec = asio::error::no_buffer_space; + } +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) + sprintf_s(serv, servlen, "%u", ntohs(port)); +#else + sprintf(serv, "%u", ntohs(port)); +#endif + } +#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) + ::pthread_mutex_unlock(&mutex); +#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) + } + } + + clear_error(ec); + return ec; +} + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // || defined(__MACH__) && defined(__APPLE__) + +inline asio::error_code translate_addrinfo_error(int error) +{ + switch (error) + { + case 0: + return asio::error_code(); + case EAI_AGAIN: + return asio::error::host_not_found_try_again; + case EAI_BADFLAGS: + return asio::error::invalid_argument; + case EAI_FAIL: + return asio::error::no_recovery; + case EAI_FAMILY: + return asio::error::address_family_not_supported; + case EAI_MEMORY: + return asio::error::no_memory; + case EAI_NONAME: +#if defined(EAI_ADDRFAMILY) + case EAI_ADDRFAMILY: +#endif +#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) + case EAI_NODATA: +#endif + return asio::error::host_not_found; + case EAI_SERVICE: + return asio::error::service_not_found; + case EAI_SOCKTYPE: + return asio::error::socket_type_not_supported; + default: // Possibly the non-portable EAI_SYSTEM. +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + return asio::error_code( + WSAGetLastError(), asio::error::get_system_category()); +#else + return asio::error_code( + errno, asio::error::get_system_category()); +#endif + } +} + +inline asio::error_code getaddrinfo(const char* host, + const char* service, const addrinfo_type* hints, addrinfo_type** result, + asio::error_code& ec) +{ + clear_error(ec); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) + // Building for Windows XP, Windows Server 2003, or later. + int error = ::getaddrinfo(host, service, hints, result); + return ec = translate_addrinfo_error(error); +# else + // Building for Windows 2000 or earlier. + typedef int (WSAAPI *gai_t)(const char*, + const char*, const addrinfo_type*, addrinfo_type**); + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + if (gai_t gai = (gai_t)::GetProcAddress(winsock_module, "getaddrinfo")) + { + int error = gai(host, service, hints, result); + return ec = translate_addrinfo_error(error); + } + } + int error = getaddrinfo_emulation(host, service, hints, result); + return ec = translate_addrinfo_error(error); +# endif +#elif defined(__MACH__) && defined(__APPLE__) + int error = getaddrinfo_emulation(host, service, hints, result); + return ec = translate_addrinfo_error(error); +#else + int error = ::getaddrinfo(host, service, hints, result); + return ec = translate_addrinfo_error(error); +#endif +} + +inline void freeaddrinfo(addrinfo_type* ai) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) + // Building for Windows XP, Windows Server 2003, or later. + ::freeaddrinfo(ai); +# else + // Building for Windows 2000 or earlier. + typedef int (WSAAPI *fai_t)(addrinfo_type*); + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + if (fai_t fai = (fai_t)::GetProcAddress(winsock_module, "freeaddrinfo")) + { + fai(ai); + return; + } + } + freeaddrinfo_emulation(ai); +# endif +#elif defined(__MACH__) && defined(__APPLE__) + freeaddrinfo_emulation(ai); +#else + ::freeaddrinfo(ai); +#endif +} + +inline asio::error_code getnameinfo(const socket_addr_type* addr, + std::size_t addrlen, char* host, std::size_t hostlen, + char* serv, std::size_t servlen, int flags, asio::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) + // Building for Windows XP, Windows Server 2003, or later. + clear_error(ec); + int error = ::getnameinfo(addr, static_cast(addrlen), + host, static_cast(hostlen), + serv, static_cast(servlen), flags); + return ec = translate_addrinfo_error(error); +# else + // Building for Windows 2000 or earlier. + typedef int (WSAAPI *gni_t)(const socket_addr_type*, + int, char*, DWORD, char*, DWORD, int); + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo")) + { + clear_error(ec); + int error = gni(addr, static_cast(addrlen), + host, static_cast(hostlen), + serv, static_cast(servlen), flags); + return ec = translate_addrinfo_error(error); + } + } + clear_error(ec); + return getnameinfo_emulation(addr, addrlen, + host, hostlen, serv, servlen, flags, ec); +# endif +#elif defined(__MACH__) && defined(__APPLE__) + using namespace std; // For memcpy. + sockaddr_storage_type tmp_addr; + memcpy(&tmp_addr, addr, addrlen); + tmp_addr.ss_len = addrlen; + addr = reinterpret_cast(&tmp_addr); + clear_error(ec); + return getnameinfo_emulation(addr, addrlen, + host, hostlen, serv, servlen, flags, ec); +#else + clear_error(ec); + int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags); + return ec = translate_addrinfo_error(error); +#endif +} + +inline u_long_type network_to_host_long(u_long_type value) +{ + return ntohl(value); +} + +inline u_long_type host_to_network_long(u_long_type value) +{ + return htonl(value); +} + +inline u_short_type network_to_host_short(u_short_type value) +{ + return ntohs(value); +} + +inline u_short_type host_to_network_short(u_short_type value) +{ + return htons(value); +} + +} // namespace socket_ops +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/socket_option.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/socket_option.hpp new file mode 100644 index 00000000..ac070b70 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/socket_option.hpp @@ -0,0 +1,319 @@ +// +// socket_option.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SOCKET_OPTION_HPP +#define ASIO_DETAIL_SOCKET_OPTION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace detail { +namespace socket_option { + +// Helper template for implementing boolean-based options. +template +class boolean +{ +public: + // Default constructor. + boolean() + : value_(0) + { + } + + // Construct with a specific option value. + explicit boolean(bool v) + : value_(v ? 1 : 0) + { + } + + // Set the current value of the boolean. + boolean& operator=(bool v) + { + value_ = v ? 1 : 0; + return *this; + } + + // Get the current value of the boolean. + bool value() const + { + return !!value_; + } + + // Convert to bool. + operator bool() const + { + return !!value_; + } + + // Test for false. + bool operator!() const + { + return !value_; + } + + // Get the level of the socket option. + template + int level(const Protocol&) const + { + return Level; + } + + // Get the name of the socket option. + template + int name(const Protocol&) const + { + return Name; + } + + // Get the address of the boolean data. + template + int* data(const Protocol&) + { + return &value_; + } + + // Get the address of the boolean data. + template + const int* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the boolean data. + template + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the boolean data. + template + void resize(const Protocol&, std::size_t s) + { + // On some platforms (e.g. Windows Vista), the getsockopt function will + // return the size of a boolean socket option as one byte, even though a + // four byte integer was passed in. + switch (s) + { + case sizeof(char): + value_ = *reinterpret_cast(&value_) ? 1 : 0; + break; + case sizeof(value_): + break; + default: + { + std::length_error ex("boolean socket option resize"); + boost::throw_exception(ex); + } + } + } + +private: + int value_; +}; + +// Helper template for implementing integer options. +template +class integer +{ +public: + // Default constructor. + integer() + : value_(0) + { + } + + // Construct with a specific option value. + explicit integer(int v) + : value_(v) + { + } + + // Set the value of the int option. + integer& operator=(int v) + { + value_ = v; + return *this; + } + + // Get the current value of the int option. + int value() const + { + return value_; + } + + // Get the level of the socket option. + template + int level(const Protocol&) const + { + return Level; + } + + // Get the name of the socket option. + template + int name(const Protocol&) const + { + return Name; + } + + // Get the address of the int data. + template + int* data(const Protocol&) + { + return &value_; + } + + // Get the address of the int data. + template + const int* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the int data. + template + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the int data. + template + void resize(const Protocol&, std::size_t s) + { + if (s != sizeof(value_)) + { + std::length_error ex("integer socket option resize"); + boost::throw_exception(ex); + } + } + +private: + int value_; +}; + +// Helper template for implementing linger options. +template +class linger +{ +public: + // Default constructor. + linger() + { + value_.l_onoff = 0; + value_.l_linger = 0; + } + + // Construct with specific option values. + linger(bool e, int t) + { + enabled(e); + timeout BOOST_PREVENT_MACRO_SUBSTITUTION(t); + } + + // Set the value for whether linger is enabled. + void enabled(bool value) + { + value_.l_onoff = value ? 1 : 0; + } + + // Get the value for whether linger is enabled. + bool enabled() const + { + return value_.l_onoff != 0; + } + + // Set the value for the linger timeout. + void timeout BOOST_PREVENT_MACRO_SUBSTITUTION(int value) + { +#if defined(WIN32) + value_.l_linger = static_cast(value); +#else + value_.l_linger = value; +#endif + } + + // Get the value for the linger timeout. + int timeout BOOST_PREVENT_MACRO_SUBSTITUTION() const + { + return static_cast(value_.l_linger); + } + + // Get the level of the socket option. + template + int level(const Protocol&) const + { + return Level; + } + + // Get the name of the socket option. + template + int name(const Protocol&) const + { + return Name; + } + + // Get the address of the linger data. + template + ::linger* data(const Protocol&) + { + return &value_; + } + + // Get the address of the linger data. + template + const ::linger* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the linger data. + template + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the int data. + template + void resize(const Protocol&, std::size_t s) + { + if (s != sizeof(value_)) + { + std::length_error ex("linger socket option resize"); + boost::throw_exception(ex); + } + } + +private: + ::linger value_; +}; + +} // namespace socket_option +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SOCKET_OPTION_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/socket_select_interrupter.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/socket_select_interrupter.hpp new file mode 100644 index 00000000..62e1063e --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/socket_select_interrupter.hpp @@ -0,0 +1,192 @@ +// +// socket_select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP +#define ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/socket_holder.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace detail { + +class socket_select_interrupter +{ +public: + // Constructor. + socket_select_interrupter() + { + asio::error_code ec; + socket_holder acceptor(socket_ops::socket( + AF_INET, SOCK_STREAM, IPPROTO_TCP, ec)); + if (acceptor.get() == invalid_socket) + { + asio::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + int opt = 1; + socket_ops::setsockopt(acceptor.get(), + SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt), ec); + + using namespace std; // For memset. + sockaddr_in4_type addr; + std::size_t addr_len = sizeof(addr); + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = 0; + if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr, + addr_len, ec) == socket_error_retval) + { + asio::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + if (socket_ops::getsockname(acceptor.get(), (socket_addr_type*)&addr, + &addr_len, ec) == socket_error_retval) + { + asio::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + // Some broken firewalls on Windows will intermittently cause getsockname to + // return 0.0.0.0 when the socket is actually bound to 127.0.0.1. We + // explicitly specify the target address here to work around this problem. + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + + if (socket_ops::listen(acceptor.get(), + SOMAXCONN, ec) == socket_error_retval) + { + asio::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + socket_holder client(socket_ops::socket( + AF_INET, SOCK_STREAM, IPPROTO_TCP, ec)); + if (client.get() == invalid_socket) + { + asio::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr, + addr_len, ec) == socket_error_retval) + { + asio::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec)); + if (server.get() == invalid_socket) + { + asio::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + ioctl_arg_type non_blocking = 1; + if (socket_ops::ioctl(client.get(), FIONBIO, &non_blocking, ec)) + { + asio::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + opt = 1; + socket_ops::setsockopt(client.get(), + IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec); + + non_blocking = 1; + if (socket_ops::ioctl(server.get(), FIONBIO, &non_blocking, ec)) + { + asio::system_error e(ec, "socket_select_interrupter"); + boost::throw_exception(e); + } + + opt = 1; + socket_ops::setsockopt(server.get(), + IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec); + + read_descriptor_ = server.release(); + write_descriptor_ = client.release(); + } + + // Destructor. + ~socket_select_interrupter() + { + asio::error_code ec; + if (read_descriptor_ != invalid_socket) + socket_ops::close(read_descriptor_, ec); + if (write_descriptor_ != invalid_socket) + socket_ops::close(write_descriptor_, ec); + } + + // Interrupt the select call. + void interrupt() + { + char byte = 0; + socket_ops::buf b; + socket_ops::init_buf(b, &byte, 1); + asio::error_code ec; + socket_ops::send(write_descriptor_, &b, 1, 0, ec); + } + + // Reset the select interrupt. Returns true if the call was interrupted. + bool reset() + { + char data[1024]; + socket_ops::buf b; + socket_ops::init_buf(b, data, sizeof(data)); + asio::error_code ec; + int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec); + bool was_interrupted = (bytes_read > 0); + while (bytes_read == sizeof(data)) + bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec); + return was_interrupted; + } + + // Get the read descriptor to be passed to select. + socket_type read_descriptor() const + { + return read_descriptor_; + } + +private: + // The read end of a connection used to interrupt the select call. This file + // descriptor is passed to select such that when it is time to stop, a single + // byte will be written on the other end of the connection and this + // descriptor will become readable. + socket_type read_descriptor_; + + // The write end of a connection used to interrupt the select call. A single + // byte may be written to this to wake up the select which is waiting for the + // other end to become readable. + socket_type write_descriptor_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/socket_types.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/socket_types.hpp new file mode 100644 index 00000000..34b3d3e6 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/socket_types.hpp @@ -0,0 +1,216 @@ +// +// socket_types.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SOCKET_TYPES_HPP +#define ASIO_DETAIL_SOCKET_TYPES_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/push_options.hpp" +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) +# error WinSock.h has already been included +# endif // defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) +# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) +# if defined(_MSC_VER) || defined(__BORLANDC__) +# pragma message( \ + "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\ + "- add -D_WIN32_WINNT=0x0501 to the compiler command line; or\n"\ + "- add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.\n"\ + "Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).") +# else // defined(_MSC_VER) || defined(__BORLANDC__) +# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. +# warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line. +# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target). +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +# define _WIN32_WINNT 0x0501 +# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) +# if defined(_MSC_VER) +# if defined(_WIN32) && !defined(WIN32) +# if !defined(_WINSOCK2API_) +# define WIN32 // Needed for correct types in winsock2.h +# else // !defined(_WINSOCK2API_) +# error Please define the macro WIN32 in your compiler options +# endif // !defined(_WINSOCK2API_) +# endif // defined(_WIN32) && !defined(WIN32) +# endif // defined(_MSC_VER) +# if defined(__BORLANDC__) +# include // Needed for __errno +# if defined(__WIN32__) && !defined(WIN32) +# if !defined(_WINSOCK2API_) +# define WIN32 // Needed for correct types in winsock2.h +# else // !defined(_WINSOCK2API_) +# error Please define the macro WIN32 in your compiler options +# endif // !defined(_WINSOCK2API_) +# endif // defined(__WIN32__) && !defined(WIN32) +# if !defined(_WSPIAPI_H_) +# define _WSPIAPI_H_ +# define ASIO_WSPIAPI_H_DEFINED +# endif // !defined(_WSPIAPI_H_) +# endif // defined(__BORLANDC__) +# if !defined(ASIO_NO_WIN32_LEAN_AND_MEAN) +# if !defined(WIN32_LEAN_AND_MEAN) +# define WIN32_LEAN_AND_MEAN +# endif // !defined(WIN32_LEAN_AND_MEAN) +# endif // !defined(ASIO_NO_WIN32_LEAN_AND_MEAN) +# if !defined(ASIO_NO_NOMINMAX) +# if !defined(NOMINMAX) +# define NOMINMAX 1 +# endif // !defined(NOMINMAX) +# endif // !defined(ASIO_NO_NOMINMAX) +# if defined(__CYGWIN__) +# if !defined(__USE_W32_SOCKETS) +# error You must add -D__USE_W32_SOCKETS to your compiler options. +# endif // !defined(__USE_W32_SOCKETS) +# endif // defined(__CYGWIN__) +# include +# include +# include +# if defined(ASIO_WSPIAPI_H_DEFINED) +# undef _WSPIAPI_H_ +# undef ASIO_WSPIAPI_H_DEFINED +# endif // defined(ASIO_WSPIAPI_H_DEFINED) +# if !defined(ASIO_NO_DEFAULT_LINKED_LIBS) +# if defined(UNDER_CE) +# pragma comment(lib, "ws2.lib") +# elif defined(_MSC_VER) || defined(__BORLANDC__) +# pragma comment(lib, "ws2_32.lib") +# pragma comment(lib, "mswsock.lib") +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +# endif // !defined(ASIO_NO_DEFAULT_LINKED_LIBS) +# include "asio/detail/old_win_sdk_compat.hpp" +#else +# include +# include +# include +# if defined(__hpux) && !defined(__HP_aCC) +# include +# else +# include +# endif +# include +# include +# include +# include +# include +# include +# include +# include +# include +# if defined(__sun) +# include +# include +# endif +#endif +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef SOCKET socket_type; +const SOCKET invalid_socket = INVALID_SOCKET; +const int socket_error_retval = SOCKET_ERROR; +const int max_addr_v4_str_len = 256; +const int max_addr_v6_str_len = 256; +typedef sockaddr socket_addr_type; +typedef in_addr in4_addr_type; +typedef ip_mreq in4_mreq_type; +typedef sockaddr_in sockaddr_in4_type; +# if defined(ASIO_HAS_OLD_WIN_SDK) +typedef in6_addr_emulation in6_addr_type; +typedef ipv6_mreq_emulation in6_mreq_type; +typedef sockaddr_in6_emulation sockaddr_in6_type; +typedef sockaddr_storage_emulation sockaddr_storage_type; +typedef addrinfo_emulation addrinfo_type; +# else +typedef in6_addr in6_addr_type; +typedef ipv6_mreq in6_mreq_type; +typedef sockaddr_in6 sockaddr_in6_type; +typedef sockaddr_storage sockaddr_storage_type; +typedef addrinfo addrinfo_type; +# endif +typedef unsigned long ioctl_arg_type; +typedef u_long u_long_type; +typedef u_short u_short_type; +const int shutdown_receive = SD_RECEIVE; +const int shutdown_send = SD_SEND; +const int shutdown_both = SD_BOTH; +const int message_peek = MSG_PEEK; +const int message_out_of_band = MSG_OOB; +const int message_do_not_route = MSG_DONTROUTE; +# if defined (_WIN32_WINNT) +const int max_iov_len = 64; +# else +const int max_iov_len = 16; +# endif +#else +typedef int socket_type; +const int invalid_socket = -1; +const int socket_error_retval = -1; +const int max_addr_v4_str_len = INET_ADDRSTRLEN; +#if defined(INET6_ADDRSTRLEN) +const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE; +#else // defined(INET6_ADDRSTRLEN) +const int max_addr_v6_str_len = 256; +#endif // defined(INET6_ADDRSTRLEN) +typedef sockaddr socket_addr_type; +typedef in_addr in4_addr_type; +# if defined(__hpux) +// HP-UX doesn't provide ip_mreq when _XOPEN_SOURCE_EXTENDED is defined. +struct in4_mreq_type +{ + struct in_addr imr_multiaddr; + struct in_addr imr_interface; +}; +# else +typedef ip_mreq in4_mreq_type; +# endif +typedef sockaddr_in sockaddr_in4_type; +typedef in6_addr in6_addr_type; +typedef ipv6_mreq in6_mreq_type; +typedef sockaddr_in6 sockaddr_in6_type; +typedef sockaddr_storage sockaddr_storage_type; +typedef sockaddr_un sockaddr_un_type; +typedef addrinfo addrinfo_type; +typedef int ioctl_arg_type; +typedef uint32_t u_long_type; +typedef uint16_t u_short_type; +const int shutdown_receive = SHUT_RD; +const int shutdown_send = SHUT_WR; +const int shutdown_both = SHUT_RDWR; +const int message_peek = MSG_PEEK; +const int message_out_of_band = MSG_OOB; +const int message_do_not_route = MSG_DONTROUTE; +# if defined(IOV_MAX) +const int max_iov_len = IOV_MAX; +# else +// POSIX platforms are not required to define IOV_MAX. +const int max_iov_len = 16; +# endif +#endif +const int custom_socket_option_level = 0xA5100000; +const int enable_connection_aborted_option = 1; +const int always_fail_option = 2; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SOCKET_TYPES_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/solaris_fenced_block.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/solaris_fenced_block.hpp new file mode 100644 index 00000000..d337f3b6 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/solaris_fenced_block.hpp @@ -0,0 +1,57 @@ +// +// solaris_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP +#define ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(__sun) + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +class solaris_fenced_block + : private noncopyable +{ +public: + // Constructor. + solaris_fenced_block() + { + membar_consumer(); + } + + // Destructor. + ~solaris_fenced_block() + { + membar_producer(); + } +}; + +} // namespace detail +} // namespace asio + +#endif // defined(__sun) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/strand_service.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/strand_service.hpp new file mode 100644 index 00000000..ea50f412 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/strand_service.hpp @@ -0,0 +1,276 @@ +// +// strand_service.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_STRAND_SERVICE_HPP +#define ASIO_DETAIL_STRAND_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/io_service.hpp" +#include "asio/detail/call_stack.hpp" +#include "asio/detail/completion_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/service_base.hpp" + +namespace asio { +namespace detail { + +// Default service implementation for a strand. +class strand_service + : public asio::detail::service_base +{ +private: + struct on_do_complete_exit; + struct on_dispatch_exit; + +public: + + // The underlying implementation of a strand. + class strand_impl + : public operation + { + public: + strand_impl() + : operation(&strand_service::do_complete), + count_(0) + { + } + + private: + // Only this service will have access to the internal values. + friend class strand_service; + friend struct on_do_complete_exit; + friend struct on_dispatch_exit; + + // Mutex to protect access to internal data. + asio::detail::mutex mutex_; + + // The count of handlers in the strand, including the upcall (if any). + std::size_t count_; + + // The handlers waiting on the strand. + op_queue queue_; + }; + + typedef strand_impl* implementation_type; + + // Construct a new strand service for the specified io_service. + explicit strand_service(asio::io_service& io_service) + : asio::detail::service_base(io_service), + io_service_(asio::use_service(io_service)), + mutex_(), + salt_(0) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + op_queue ops; + + asio::detail::mutex::scoped_lock lock(mutex_); + + for (std::size_t i = 0; i < num_implementations; ++i) + if (strand_impl* impl = implementations_[i].get()) + ops.push(impl->queue_); + } + + // Construct a new strand implementation. + void construct(implementation_type& impl) + { + std::size_t index = boost::hash_value(&impl); + boost::hash_combine(index, salt_++); + index = index % num_implementations; + + asio::detail::mutex::scoped_lock lock(mutex_); + + if (!implementations_[index]) + implementations_[index].reset(new strand_impl); + impl = implementations_[index].get(); + } + + // Destroy a strand implementation. + void destroy(implementation_type& impl) + { + impl = 0; + } + + // Request the io_service to invoke the given handler. + template + void dispatch(implementation_type& impl, Handler handler) + { + // If we are already in the strand then the handler can run immediately. + if (call_stack::contains(impl)) + { + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + return; + } + + // Allocate and construct an object to wrap the handler. + typedef completion_handler value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + // If we are running inside the io_service, and no other handler is queued + // or running, then the handler can run immediately. + bool can_dispatch = call_stack::contains(&io_service_); + impl->mutex_.lock(); + bool first = (++impl->count_ == 1); + if (can_dispatch && first) + { + // Immediate invocation is allowed. + impl->mutex_.unlock(); + + // Memory must be releaesed before any upcall is made. + ptr.reset(); + + // Indicate that this strand is executing on the current thread. + call_stack::context ctx(impl); + + // Ensure the next handler, if any, is scheduled on block exit. + on_dispatch_exit on_exit = { &io_service_, impl }; + (void)on_exit; + + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + return; + } + + // Immediate invocation is not allowed, so enqueue for later. + impl->queue_.push(ptr.get()); + impl->mutex_.unlock(); + ptr.release(); + + // The first handler to be enqueued is responsible for scheduling the + // strand. + if (first) + io_service_.post_immediate_completion(impl); + } + + // Request the io_service to invoke the given handler and return immediately. + template + void post(implementation_type& impl, Handler handler) + { + // Allocate and construct an object to wrap the handler. + typedef completion_handler value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + // Add the handler to the queue. + impl->mutex_.lock(); + bool first = (++impl->count_ == 1); + impl->queue_.push(ptr.get()); + impl->mutex_.unlock(); + ptr.release(); + + // The first handler to be enqueue is responsible for scheduling the strand. + if (first) + io_service_.post_immediate_completion(impl); + } + +private: + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + if (owner) + { + strand_impl* impl = static_cast(base); + + // Get the next handler to be executed. + impl->mutex_.lock(); + operation* o = impl->queue_.front(); + impl->queue_.pop(); + impl->mutex_.unlock(); + + // Indicate that this strand is executing on the current thread. + call_stack::context ctx(impl); + + // Ensure the next handler, if any, is scheduled on block exit. + on_do_complete_exit on_exit = { owner, impl }; + (void)on_exit; + + o->complete(*owner); + } + } + + // Helper class to re-post the strand on exit. + struct on_do_complete_exit + { + io_service_impl* owner_; + strand_impl* impl_; + + ~on_do_complete_exit() + { + impl_->mutex_.lock(); + bool more_handlers = (--impl_->count_ > 0); + impl_->mutex_.unlock(); + + if (more_handlers) + owner_->post_immediate_completion(impl_); + } + }; + + // Helper class to re-post the strand on exit. + struct on_dispatch_exit + { + io_service_impl* io_service_; + strand_impl* impl_; + + ~on_dispatch_exit() + { + impl_->mutex_.lock(); + bool more_handlers = (--impl_->count_ > 0); + impl_->mutex_.unlock(); + + if (more_handlers) + io_service_->post_immediate_completion(impl_); + } + }; + + // The io_service implementation used to post completions. + io_service_impl& io_service_; + + // Mutex to protect access to the array of implementations. + asio::detail::mutex mutex_; + + // Number of implementations shared between all strand objects. + enum { num_implementations = 193 }; + + // The head of a linked list of all implementations. + boost::scoped_ptr implementations_[num_implementations]; + + // Extra value used when hashing to prevent recycled memory locations from + // getting the same strand implementation. + std::size_t salt_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_STRAND_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/task_io_service.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/task_io_service.hpp new file mode 100644 index 00000000..eb77c1d8 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/task_io_service.hpp @@ -0,0 +1,465 @@ +// +// task_io_service.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_TASK_IO_SERVICE_HPP +#define ASIO_DETAIL_TASK_IO_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/error_code.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/call_stack.hpp" +#include "asio/detail/completion_handler.hpp" +#include "asio/detail/event.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/detail/task_io_service_fwd.hpp" +#include "asio/detail/task_io_service_operation.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +template +class task_io_service + : public asio::detail::service_base > +{ +public: + typedef task_io_service_operation operation; + + // Constructor. + task_io_service(asio::io_service& io_service) + : asio::detail::service_base >(io_service), + mutex_(), + task_(0), + task_interrupted_(true), + outstanding_work_(0), + stopped_(false), + shutdown_(false), + first_idle_thread_(0) + { + } + + void init(size_t /*concurrency_hint*/) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + asio::detail::mutex::scoped_lock lock(mutex_); + shutdown_ = true; + lock.unlock(); + + // Destroy handler objects. + while (!op_queue_.empty()) + { + operation* o = op_queue_.front(); + op_queue_.pop(); + if (o != &task_operation_) + o->destroy(); + } + + // Reset to initial state. + task_ = 0; + } + + // Initialise the task, if required. + void init_task() + { + asio::detail::mutex::scoped_lock lock(mutex_); + if (!shutdown_ && !task_) + { + task_ = &use_service(this->get_io_service()); + op_queue_.push(&task_operation_); + wake_one_thread_and_unlock(lock); + } + } + + // Run the event loop until interrupted or no more work. + size_t run(asio::error_code& ec) + { + ec = asio::error_code(); + if (outstanding_work_ == 0) + { + stop(); + return 0; + } + + typename call_stack::context ctx(this); + + idle_thread_info this_idle_thread; + this_idle_thread.next = 0; + + asio::detail::mutex::scoped_lock lock(mutex_); + + size_t n = 0; + for (; do_one(lock, &this_idle_thread); lock.lock()) + if (n != (std::numeric_limits::max)()) + ++n; + return n; + } + + // Run until interrupted or one operation is performed. + size_t run_one(asio::error_code& ec) + { + ec = asio::error_code(); + if (outstanding_work_ == 0) + { + stop(); + return 0; + } + + typename call_stack::context ctx(this); + + idle_thread_info this_idle_thread; + this_idle_thread.next = 0; + + asio::detail::mutex::scoped_lock lock(mutex_); + + return do_one(lock, &this_idle_thread); + } + + // Poll for operations without blocking. + size_t poll(asio::error_code& ec) + { + if (outstanding_work_ == 0) + { + stop(); + ec = asio::error_code(); + return 0; + } + + typename call_stack::context ctx(this); + + asio::detail::mutex::scoped_lock lock(mutex_); + + size_t n = 0; + for (; do_one(lock, 0); lock.lock()) + if (n != (std::numeric_limits::max)()) + ++n; + return n; + } + + // Poll for one operation without blocking. + size_t poll_one(asio::error_code& ec) + { + ec = asio::error_code(); + if (outstanding_work_ == 0) + { + stop(); + return 0; + } + + typename call_stack::context ctx(this); + + asio::detail::mutex::scoped_lock lock(mutex_); + + return do_one(lock, 0); + } + + // Interrupt the event processing loop. + void stop() + { + asio::detail::mutex::scoped_lock lock(mutex_); + stop_all_threads(lock); + } + + // Reset in preparation for a subsequent run invocation. + void reset() + { + asio::detail::mutex::scoped_lock lock(mutex_); + stopped_ = false; + } + + // Notify that some work has started. + void work_started() + { + ++outstanding_work_; + } + + // Notify that some work has finished. + void work_finished() + { + if (--outstanding_work_ == 0) + stop(); + } + + // Request invocation of the given handler. + template + void dispatch(Handler handler) + { + if (call_stack::contains(this)) + { + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + else + post(handler); + } + + // Request invocation of the given handler and return immediately. + template + void post(Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef completion_handler value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + post_immediate_completion(ptr.get()); + ptr.release(); + } + + // Request invocation of the given operation and return immediately. Assumes + // that work_started() has not yet been called for the operation. + void post_immediate_completion(operation* op) + { + work_started(); + post_deferred_completion(op); + } + + // Request invocation of the given operation and return immediately. Assumes + // that work_started() was previously called for the operation. + void post_deferred_completion(operation* op) + { + asio::detail::mutex::scoped_lock lock(mutex_); + op_queue_.push(op); + wake_one_thread_and_unlock(lock); + } + + // Request invocation of the given operations and return immediately. Assumes + // that work_started() was previously called for each operation. + void post_deferred_completions(op_queue& ops) + { + if (!ops.empty()) + { + asio::detail::mutex::scoped_lock lock(mutex_); + op_queue_.push(ops); + wake_one_thread_and_unlock(lock); + } + } + +private: + struct idle_thread_info; + + size_t do_one(asio::detail::mutex::scoped_lock& lock, + idle_thread_info* this_idle_thread) + { + bool polling = !this_idle_thread; + bool task_has_run = false; + while (!stopped_) + { + if (!op_queue_.empty()) + { + // Prepare to execute first handler from queue. + operation* o = op_queue_.front(); + op_queue_.pop(); + bool more_handlers = (!op_queue_.empty()); + + if (o == &task_operation_) + { + task_interrupted_ = more_handlers || polling; + + // If the task has already run and we're polling then we're done. + if (task_has_run && polling) + { + task_interrupted_ = true; + op_queue_.push(&task_operation_); + return 0; + } + task_has_run = true; + + if (!more_handlers || !wake_one_idle_thread_and_unlock(lock)) + lock.unlock(); + + op_queue completed_ops; + task_cleanup c = { this, &lock, &completed_ops }; + (void)c; + + // Run the task. May throw an exception. Only block if the operation + // queue is empty and we're not polling, otherwise we want to return + // as soon as possible. + task_->run(!more_handlers && !polling, completed_ops); + } + else + { + if (more_handlers) + wake_one_thread_and_unlock(lock); + else + lock.unlock(); + + // Ensure the count of outstanding work is decremented on block exit. + work_finished_on_block_exit on_exit = { this }; + (void)on_exit; + + // Complete the operation. May throw an exception. + o->complete(*this); // deletes the operation object + + return 1; + } + } + else if (this_idle_thread) + { + // Nothing to run right now, so just wait for work to do. + this_idle_thread->next = first_idle_thread_; + first_idle_thread_ = this_idle_thread; + this_idle_thread->wakeup_event.clear(lock); + this_idle_thread->wakeup_event.wait(lock); + } + else + { + return 0; + } + } + + return 0; + } + + // Stop the task and all idle threads. + void stop_all_threads( + asio::detail::mutex::scoped_lock& lock) + { + stopped_ = true; + + while (first_idle_thread_) + { + idle_thread_info* idle_thread = first_idle_thread_; + first_idle_thread_ = idle_thread->next; + idle_thread->next = 0; + idle_thread->wakeup_event.signal(lock); + } + + if (!task_interrupted_ && task_) + { + task_interrupted_ = true; + task_->interrupt(); + } + } + + // Wakes a single idle thread and unlocks the mutex. Returns true if an idle + // thread was found. If there is no idle thread, returns false and leaves the + // mutex locked. + bool wake_one_idle_thread_and_unlock( + asio::detail::mutex::scoped_lock& lock) + { + if (first_idle_thread_) + { + idle_thread_info* idle_thread = first_idle_thread_; + first_idle_thread_ = idle_thread->next; + idle_thread->next = 0; + idle_thread->wakeup_event.signal_and_unlock(lock); + return true; + } + return false; + } + + // Wake a single idle thread, or the task, and always unlock the mutex. + void wake_one_thread_and_unlock( + asio::detail::mutex::scoped_lock& lock) + { + if (!wake_one_idle_thread_and_unlock(lock)) + { + if (!task_interrupted_ && task_) + { + task_interrupted_ = true; + task_->interrupt(); + } + lock.unlock(); + } + } + + // Helper class to perform task-related operations on block exit. + struct task_cleanup; + friend struct task_cleanup; + struct task_cleanup + { + ~task_cleanup() + { + // Enqueue the completed operations and reinsert the task at the end of + // the operation queue. + lock_->lock(); + task_io_service_->task_interrupted_ = true; + task_io_service_->op_queue_.push(*ops_); + task_io_service_->op_queue_.push(&task_io_service_->task_operation_); + } + + task_io_service* task_io_service_; + asio::detail::mutex::scoped_lock* lock_; + op_queue* ops_; + }; + + // Helper class to call work_finished() on block exit. + struct work_finished_on_block_exit + { + ~work_finished_on_block_exit() + { + task_io_service_->work_finished(); + } + + task_io_service* task_io_service_; + }; + + // Mutex to protect access to internal data. + asio::detail::mutex mutex_; + + // The task to be run by this service. + Task* task_; + + // Operation object to represent the position of the task in the queue. + struct task_operation : public operation + { + task_operation() : operation(0) {} + } task_operation_; + + // Whether the task has been interrupted. + bool task_interrupted_; + + // The count of unfinished work. + boost::detail::atomic_count outstanding_work_; + + // The queue of handlers that are ready to be delivered. + op_queue op_queue_; + + // Flag to indicate that the dispatcher has been stopped. + bool stopped_; + + // Flag to indicate that the dispatcher has been shut down. + bool shutdown_; + + // Structure containing information about an idle thread. + struct idle_thread_info + { + event wakeup_event; + idle_thread_info* next; + }; + + // The threads that are currently idle. + idle_thread_info* first_idle_thread_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TASK_IO_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/task_io_service_2lock.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/task_io_service_2lock.hpp new file mode 100644 index 00000000..9b0221bb --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/task_io_service_2lock.hpp @@ -0,0 +1,462 @@ +// +// task_io_service_2lock.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_TASK_IO_SERVICE_2LOCK_HPP +#define ASIO_DETAIL_TASK_IO_SERVICE_2LOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/error_code.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/call_stack.hpp" +#include "asio/detail/event.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/indirect_handler_queue.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/detail/task_io_service_fwd.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +// An alternative task_io_service implementation based on a two-lock queue. + +template +class task_io_service + : public asio::detail::service_base > +{ +public: + typedef indirect_handler_queue handler_queue; + + // Constructor. + task_io_service(asio::io_service& io_service) + : asio::detail::service_base >(io_service), + front_mutex_(), + back_mutex_(), + task_(use_service(io_service)), + outstanding_work_(0), + front_stopped_(false), + back_stopped_(false), + back_shutdown_(false), + back_first_idle_thread_(0), + back_task_thread_(0) + { + handler_queue_.push(&task_handler_); + } + + void init(size_t /*concurrency_hint*/) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + asio::detail::mutex::scoped_lock back_lock(back_mutex_); + back_shutdown_ = true; + back_lock.unlock(); + + // Destroy handler objects. + while (handler_queue::handler* h = handler_queue_.pop()) + if (h != &task_handler_) + h->destroy(); + + // Reset handler queue to initial state. + handler_queue_.push(&task_handler_); + } + + // Run the event loop until interrupted or no more work. + size_t run(asio::error_code& ec) + { + if (outstanding_work_ == 0) + { + stop(); + ec = asio::error_code(); + return 0; + } + + typename call_stack::context ctx(this); + + idle_thread_info this_idle_thread; + this_idle_thread.next = 0; + + size_t n = 0; + while (do_one(&this_idle_thread, ec)) + if (n != (std::numeric_limits::max)()) + ++n; + return n; + } + + // Run until interrupted or one operation is performed. + size_t run_one(asio::error_code& ec) + { + if (outstanding_work_ == 0) + { + stop(); + ec = asio::error_code(); + return 0; + } + + typename call_stack::context ctx(this); + + idle_thread_info this_idle_thread; + this_idle_thread.next = 0; + + return do_one(&this_idle_thread, ec); + } + + // Poll for operations without blocking. + size_t poll(asio::error_code& ec) + { + if (outstanding_work_ == 0) + { + stop(); + ec = asio::error_code(); + return 0; + } + + typename call_stack::context ctx(this); + + size_t n = 0; + while (do_one(0, ec)) + if (n != (std::numeric_limits::max)()) + ++n; + return n; + } + + // Poll for one operation without blocking. + size_t poll_one(asio::error_code& ec) + { + if (outstanding_work_ == 0) + { + stop(); + ec = asio::error_code(); + return 0; + } + + typename call_stack::context ctx(this); + + return do_one(0, ec); + } + + // Interrupt the event processing loop. + void stop() + { + asio::detail::mutex::scoped_lock front_lock(front_mutex_); + front_stopped_ = true; + front_lock.unlock(); + + asio::detail::mutex::scoped_lock back_lock(back_mutex_); + back_stopped_ = true; + interrupt_all_idle_threads(back_lock); + } + + // Reset in preparation for a subsequent run invocation. + void reset() + { + asio::detail::mutex::scoped_lock front_lock(front_mutex_); + front_stopped_ = false; + front_lock.unlock(); + + asio::detail::mutex::scoped_lock back_lock(back_mutex_); + back_stopped_ = false; + } + + // Notify that some work has started. + void work_started() + { + ++outstanding_work_; + } + + // Notify that some work has finished. + void work_finished() + { + if (--outstanding_work_ == 0) + stop(); + } + + // Request invocation of the given handler. + template + void dispatch(Handler handler) + { + if (call_stack::contains(this)) + asio_handler_invoke_helpers::invoke(handler, &handler); + else + post(handler); + } + + // Request invocation of the given handler and return immediately. + template + void post(Handler handler) + { + // Allocate and construct an operation to wrap the handler. + handler_queue::scoped_ptr ptr(handler_queue::wrap(handler)); + + asio::detail::mutex::scoped_lock back_lock(back_mutex_); + + // If the service has been shut down we silently discard the handler. + if (back_shutdown_) + return; + + // Add the handler to the end of the queue. + handler_queue_.push(ptr.get()); + ptr.release(); + + // An undelivered handler is treated as unfinished work. + ++outstanding_work_; + + // Wake up a thread to execute the handler. + interrupt_one_idle_thread(back_lock); + } + +private: + struct idle_thread_info; + + size_t do_one(idle_thread_info* this_idle_thread, + asio::error_code& ec) + { + bool task_has_run = false; + for (;;) + { + // The front lock must be held before we can pop items from the queue. + asio::detail::mutex::scoped_lock front_lock(front_mutex_); + if (front_stopped_) + { + ec = asio::error_code(); + return 0; + } + + if (handler_queue::handler* h = handler_queue_.pop()) + { + if (h == &task_handler_) + { + bool more_handlers = handler_queue_.poppable(); + unsigned long front_version = handler_queue_.front_version(); + front_lock.unlock(); + + // The task is always added to the back of the queue when we exit + // this block. + task_cleanup c(*this); + + // If we're polling and the task has already run then we're done. + bool polling = !this_idle_thread; + if (task_has_run && polling) + { + ec = asio::error_code(); + return 0; + } + + // If we're considering going idle we need to check whether the queue + // is still empty. If it is, add the thread to the list of idle + // threads. + if (!more_handlers && !polling) + { + asio::detail::mutex::scoped_lock back_lock(back_mutex_); + if (back_stopped_) + { + ec = asio::error_code(); + return 0; + } + else if (front_version == handler_queue_.back_version()) + { + back_task_thread_ = this_idle_thread; + } + else + { + more_handlers = true; + } + } + + // Run the task. May throw an exception. Only block if the handler + // queue is empty and we're not polling, otherwise we want to return + // as soon as possible. + task_has_run = true; + task_.run(!more_handlers && !polling); + } + else + { + front_lock.unlock(); + handler_cleanup c(*this); + + // Invoke the handler. May throw an exception. + h->invoke(); // invoke() deletes the handler object + + ec = asio::error_code(); + return 1; + } + } + else if (this_idle_thread) + { + unsigned long front_version = handler_queue_.front_version(); + front_lock.unlock(); + + // If we're considering going idle we need to check whether the queue + // is still empty. If it is, add the thread to the list of idle + // threads. + asio::detail::mutex::scoped_lock back_lock(back_mutex_); + if (back_stopped_) + { + ec = asio::error_code(); + return 0; + } + else if (front_version == handler_queue_.back_version()) + { + this_idle_thread->next = back_first_idle_thread_; + back_first_idle_thread_ = this_idle_thread; + this_idle_thread->wakeup_event.clear(back_lock); + this_idle_thread->wakeup_event.wait(back_lock); + } + } + else + { + ec = asio::error_code(); + return 0; + } + } + } + + // Interrupt a single idle thread. + void interrupt_one_idle_thread( + asio::detail::mutex::scoped_lock& back_lock) + { + if (back_first_idle_thread_) + { + idle_thread_info* idle_thread = back_first_idle_thread_; + back_first_idle_thread_ = idle_thread->next; + idle_thread->next = 0; + idle_thread->wakeup_event.signal(back_lock); + } + else if (back_task_thread_) + { + back_task_thread_ = 0; + task_.interrupt(); + } + } + + // Interrupt all idle threads. + void interrupt_all_idle_threads( + asio::detail::mutex::scoped_lock& back_lock) + { + while (back_first_idle_thread_) + { + idle_thread_info* idle_thread = back_first_idle_thread_; + back_first_idle_thread_ = idle_thread->next; + idle_thread->next = 0; + idle_thread->wakeup_event.signal(back_lock); + } + + if (back_task_thread_) + { + back_task_thread_ = 0; + task_.interrupt(); + } + } + + // Helper class to perform task-related operations on block exit. + class task_cleanup; + friend class task_cleanup; + class task_cleanup + { + public: + task_cleanup(task_io_service& task_io_svc) + : task_io_service_(task_io_svc) + { + } + + ~task_cleanup() + { + // Reinsert the task at the end of the handler queue. + asio::detail::mutex::scoped_lock back_lock( + task_io_service_.back_mutex_); + task_io_service_.back_task_thread_ = 0; + task_io_service_.handler_queue_.push(&task_io_service_.task_handler_); + } + + private: + task_io_service& task_io_service_; + }; + + // Helper class to perform handler-related operations on block exit. + class handler_cleanup + { + public: + handler_cleanup(task_io_service& task_io_svc) + : task_io_service_(task_io_svc) + { + } + + ~handler_cleanup() + { + task_io_service_.work_finished(); + } + + private: + task_io_service& task_io_service_; + }; + + // Mutexes to protect access to internal data. + asio::detail::mutex front_mutex_; + asio::detail::mutex back_mutex_; + + // The task to be run by this service. + Task& task_; + + // Handler object to represent the position of the task in the queue. + class task_handler + : public handler_queue::handler + { + public: + task_handler() + : handler_queue::handler(0, 0) + { + } + } task_handler_; + + // The count of unfinished work. + boost::detail::atomic_count outstanding_work_; + + // The queue of handlers that are ready to be delivered. + handler_queue handler_queue_; + + // Flag to indicate that the dispatcher has been stopped. + bool front_stopped_; + bool back_stopped_; + + // Flag to indicate that the dispatcher has been shut down. + bool back_shutdown_; + + // Structure containing information about an idle thread. + struct idle_thread_info + { + event wakeup_event; + idle_thread_info* next; + }; + + // The number of threads that are currently idle. + idle_thread_info* back_first_idle_thread_; + + // The thread that is currently blocked on the task. + idle_thread_info* back_task_thread_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TASK_IO_SERVICE_2LOCK_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/task_io_service_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/task_io_service_fwd.hpp new file mode 100644 index 00000000..5b18d1d7 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/task_io_service_fwd.hpp @@ -0,0 +1,31 @@ +// +// task_io_service_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_TASK_IO_SERVICE_FWD_HPP +#define ASIO_DETAIL_TASK_IO_SERVICE_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class task_io_service; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TASK_IO_SERVICE_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/task_io_service_operation.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/task_io_service_operation.hpp new file mode 100644 index 00000000..6776f699 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/task_io_service_operation.hpp @@ -0,0 +1,69 @@ +// +// task_io_service_operation.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_TASK_IO_SERVICE_OPERATION_HPP +#define ASIO_DETAIL_TASK_IO_SERVICE_OPERATION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/error_code.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/task_io_service_fwd.hpp" + +namespace asio { +namespace detail { + +// Base class for all operations. A function pointer is used instead of virtual +// functions to avoid the associated overhead. +template +class task_io_service_operation +{ +public: + void complete(task_io_service& owner) + { + func_(&owner, this, asio::error_code(), 0); + } + + void destroy() + { + func_(0, this, asio::error_code(), 0); + } + +protected: + typedef void (*func_type)(task_io_service*, + task_io_service_operation*, asio::error_code, std::size_t); + + task_io_service_operation(func_type func) + : next_(0), + func_(func) + { + } + + // Prevents deletion through this type. + ~task_io_service_operation() + { + } + +private: + friend class op_queue_access; + task_io_service_operation* next_; + func_type func_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TASK_IO_SERVICE_OPERATION_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/thread.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/thread.hpp new file mode 100644 index 00000000..3c9280bc --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/thread.hpp @@ -0,0 +1,58 @@ +// +// thread.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_THREAD_HPP +#define ASIO_DETAIL_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) +# include "asio/detail/null_thread.hpp" +#elif defined(BOOST_WINDOWS) +# if defined(UNDER_CE) +# include "asio/detail/wince_thread.hpp" +# else +# include "asio/detail/win_thread.hpp" +# endif +#elif defined(BOOST_HAS_PTHREADS) +# include "asio/detail/posix_thread.hpp" +#else +# error Only Windows and POSIX are supported! +#endif + +namespace asio { +namespace detail { + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) +typedef null_thread thread; +#elif defined(BOOST_WINDOWS) +# if defined(UNDER_CE) +typedef wince_thread thread; +# else +typedef win_thread thread; +# endif +#elif defined(BOOST_HAS_PTHREADS) +typedef posix_thread thread; +#endif + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_THREAD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/throw_error.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/throw_error.hpp new file mode 100644 index 00000000..51d6e48f --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/throw_error.hpp @@ -0,0 +1,44 @@ +// +// throw_error.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_THROW_ERROR_HPP +#define ASIO_DETAIL_THROW_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error_code.hpp" +#include "asio/system_error.hpp" + +namespace asio { +namespace detail { + +inline void throw_error(const asio::error_code& err) +{ + if (err) + { + asio::system_error e(err); + boost::throw_exception(e); + } +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_THROW_ERROR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/timer_op.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/timer_op.hpp new file mode 100644 index 00000000..bf3c3ae5 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/timer_op.hpp @@ -0,0 +1,44 @@ +// +// timer_op.hpp +// ~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_TIMER_OP_HPP +#define ASIO_DETAIL_TIMER_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/operation.hpp" + +namespace asio { +namespace detail { + +class timer_op + : public operation +{ +public: + // The error code to be passed to the completion handler. + asio::error_code ec_; + +protected: + timer_op(func_type func) + : operation(func) + { + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TIMER_OP_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/timer_queue.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/timer_queue.hpp new file mode 100644 index 00000000..2e4d2d5d --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/timer_queue.hpp @@ -0,0 +1,276 @@ +// +// timer_queue.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_TIMER_QUEUE_HPP +#define ASIO_DETAIL_TIMER_QUEUE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/detail/hash_map.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/timer_op.hpp" +#include "asio/detail/timer_queue_base.hpp" + +namespace asio { +namespace detail { + +template +class timer_queue + : public timer_queue_base +{ +public: + // The time type. + typedef typename Time_Traits::time_type time_type; + + // The duration type. + typedef typename Time_Traits::duration_type duration_type; + + // Constructor. + timer_queue() + : timers_(), + heap_() + { + } + + // Add a new timer to the queue. Returns true if this is the timer that is + // earliest in the queue, in which case the reactor's event demultiplexing + // function call may need to be interrupted and restarted. + bool enqueue_timer(const time_type& time, timer_op* op, void* token) + { + // Ensure that there is space for the timer in the heap. We reserve here so + // that the push_back below will not throw due to a reallocation failure. + heap_.reserve(heap_.size() + 1); + + // Insert the new timer into the hash. + typedef typename hash_map::iterator iterator; + typedef typename hash_map::value_type value_type; + std::pair result = + timers_.insert(value_type(token, timer())); + result.first->second.op_queue_.push(op); + if (result.second) + { + // Put the new timer at the correct position in the heap. + result.first->second.time_ = time; + result.first->second.heap_index_ = heap_.size(); + result.first->second.token_ = token; + heap_.push_back(&result.first->second); + up_heap(heap_.size() - 1); + } + + return (heap_[0] == &result.first->second); + } + + // Whether there are no timers in the queue. + virtual bool empty() const + { + return heap_.empty(); + } + + // Get the time for the timer that is earliest in the queue. + virtual long wait_duration_msec(long max_duration) const + { + if (heap_.empty()) + return max_duration; + + boost::posix_time::time_duration duration = Time_Traits::to_posix_duration( + Time_Traits::subtract(heap_[0]->time_, Time_Traits::now())); + + if (duration > boost::posix_time::milliseconds(max_duration)) + duration = boost::posix_time::milliseconds(max_duration); + else if (duration < boost::posix_time::milliseconds(0)) + duration = boost::posix_time::milliseconds(0); + + return duration.total_milliseconds(); + } + + // Get the time for the timer that is earliest in the queue. + virtual long wait_duration_usec(long max_duration) const + { + if (heap_.empty()) + return max_duration; + + boost::posix_time::time_duration duration = Time_Traits::to_posix_duration( + Time_Traits::subtract(heap_[0]->time_, Time_Traits::now())); + + if (duration > boost::posix_time::microseconds(max_duration)) + duration = boost::posix_time::microseconds(max_duration); + else if (duration < boost::posix_time::microseconds(0)) + duration = boost::posix_time::microseconds(0); + + return duration.total_microseconds(); + } + + // Dequeue all timers not later than the current time. + virtual void get_ready_timers(op_queue& ops) + { + const time_type now = Time_Traits::now(); + while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0]->time_)) + { + timer* t = heap_[0]; + ops.push(t->op_queue_); + remove_timer(t); + } + } + + // Dequeue all timers. + virtual void get_all_timers(op_queue& ops) + { + typename hash_map::iterator i = timers_.begin(); + typename hash_map::iterator end = timers_.end(); + while (i != end) + { + ops.push(i->second.op_queue_); + typename hash_map::iterator old_i = i++; + timers_.erase(old_i); + } + + heap_.clear(); + timers_.clear(); + } + + // Cancel and dequeue the timers with the given token. + std::size_t cancel_timer(void* timer_token, op_queue& ops) + { + std::size_t num_cancelled = 0; + typedef typename hash_map::iterator iterator; + iterator it = timers_.find(timer_token); + if (it != timers_.end()) + { + while (timer_op* op = it->second.op_queue_.front()) + { + op->ec_ = asio::error::operation_aborted; + it->second.op_queue_.pop(); + ops.push(op); + ++num_cancelled; + } + remove_timer(&it->second); + } + return num_cancelled; + } + +private: + // Structure representing a single outstanding timer. + struct timer + { + timer() {} + timer(const timer&) {} + void operator=(const timer&) {} + + // The time when the timer should fire. + time_type time_; + + // The operations waiting on the timer. + op_queue op_queue_; + + // The index of the timer in the heap. + size_t heap_index_; + + // The token associated with the timer. + void* token_; + }; + + // Move the item at the given index up the heap to its correct position. + void up_heap(size_t index) + { + size_t parent = (index - 1) / 2; + while (index > 0 + && Time_Traits::less_than(heap_[index]->time_, heap_[parent]->time_)) + { + swap_heap(index, parent); + index = parent; + parent = (index - 1) / 2; + } + } + + // Move the item at the given index down the heap to its correct position. + void down_heap(size_t index) + { + size_t child = index * 2 + 1; + while (child < heap_.size()) + { + size_t min_child = (child + 1 == heap_.size() + || Time_Traits::less_than( + heap_[child]->time_, heap_[child + 1]->time_)) + ? child : child + 1; + if (Time_Traits::less_than(heap_[index]->time_, heap_[min_child]->time_)) + break; + swap_heap(index, min_child); + index = min_child; + child = index * 2 + 1; + } + } + + // Swap two entries in the heap. + void swap_heap(size_t index1, size_t index2) + { + timer* tmp = heap_[index1]; + heap_[index1] = heap_[index2]; + heap_[index2] = tmp; + heap_[index1]->heap_index_ = index1; + heap_[index2]->heap_index_ = index2; + } + + // Remove a timer from the heap and list of timers. + void remove_timer(timer* t) + { + // Remove the timer from the heap. + size_t index = t->heap_index_; + if (!heap_.empty() && index < heap_.size()) + { + if (index == heap_.size() - 1) + { + heap_.pop_back(); + } + else + { + swap_heap(index, heap_.size() - 1); + heap_.pop_back(); + size_t parent = (index - 1) / 2; + if (index > 0 && Time_Traits::less_than( + heap_[index]->time_, heap_[parent]->time_)) + up_heap(index); + else + down_heap(index); + } + } + + // Remove the timer from the hash. + typedef typename hash_map::iterator iterator; + iterator it = timers_.find(t->token_); + if (it != timers_.end()) + timers_.erase(it); + } + + // A hash of timer token to linked lists of timers. + hash_map timers_; + + // The heap of timers, with the earliest timer at the front. + std::vector heap_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TIMER_QUEUE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/timer_queue_base.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/timer_queue_base.hpp new file mode 100644 index 00000000..f9786675 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/timer_queue_base.hpp @@ -0,0 +1,64 @@ +// +// timer_queue_base.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_TIMER_QUEUE_BASE_HPP +#define ASIO_DETAIL_TIMER_QUEUE_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/operation.hpp" + +namespace asio { +namespace detail { + +class timer_queue_base + : private noncopyable +{ +public: + // Constructor. + timer_queue_base() : next_(0) {} + + // Destructor. + virtual ~timer_queue_base() {} + + // Whether there are no timers in the queue. + virtual bool empty() const = 0; + + // Get the time to wait until the next timer. + virtual long wait_duration_msec(long max_duration) const = 0; + + // Get the time to wait until the next timer. + virtual long wait_duration_usec(long max_duration) const = 0; + + // Dequeue all ready timers. + virtual void get_ready_timers(op_queue& ops) = 0; + + // Dequeue all timers. + virtual void get_all_timers(op_queue& ops) = 0; + +private: + friend class timer_queue_set; + + // Next timer queue in the set. + timer_queue_base* next_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TIMER_QUEUE_BASE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/timer_queue_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/timer_queue_fwd.hpp new file mode 100644 index 00000000..53172448 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/timer_queue_fwd.hpp @@ -0,0 +1,31 @@ +// +// timer_queue_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_TIMER_QUEUE_FWD_HPP +#define ASIO_DETAIL_TIMER_QUEUE_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +class timer_queue; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TIMER_QUEUE_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/timer_queue_set.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/timer_queue_set.hpp new file mode 100644 index 00000000..68608670 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/timer_queue_set.hpp @@ -0,0 +1,115 @@ +// +// timer_queue_set.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_TIMER_QUEUE_SET_HPP +#define ASIO_DETAIL_TIMER_QUEUE_SET_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/timer_queue_base.hpp" + +namespace asio { +namespace detail { + +class timer_queue_set +{ +public: + // Constructor. + timer_queue_set() + : first_(0) + { + } + + // Add a timer queue to the set. + void insert(timer_queue_base* q) + { + q->next_ = first_; + first_ = q; + } + + // Remove a timer queue from the set. + void erase(timer_queue_base* q) + { + if (first_) + { + if (q == first_) + { + first_ = q->next_; + q->next_ = 0; + return; + } + + for (timer_queue_base* p = first_; p->next_; p = p->next_) + { + if (p->next_ == q) + { + p->next_ = q->next_; + q->next_ = 0; + return; + } + } + } + } + + // Determine whether all queues are empty. + bool all_empty() const + { + for (timer_queue_base* p = first_; p; p = p->next_) + if (!p->empty()) + return false; + return true; + } + + // Get the wait duration in milliseconds. + long wait_duration_msec(long max_duration) const + { + long min_duration = max_duration; + for (timer_queue_base* p = first_; p; p = p->next_) + min_duration = p->wait_duration_msec(min_duration); + return min_duration; + } + + // Get the wait duration in microseconds. + long wait_duration_usec(long max_duration) const + { + long min_duration = max_duration; + for (timer_queue_base* p = first_; p; p = p->next_) + min_duration = p->wait_duration_usec(min_duration); + return min_duration; + } + + // Dequeue all ready timers. + void get_ready_timers(op_queue& ops) + { + for (timer_queue_base* p = first_; p; p = p->next_) + p->get_ready_timers(ops); + } + + // Dequeue all timers. + void get_all_timers(op_queue& ops) + { + for (timer_queue_base* p = first_; p; p = p->next_) + p->get_all_timers(ops); + } + +private: + timer_queue_base* first_; +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TIMER_QUEUE_SET_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/timer_scheduler.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/timer_scheduler.hpp new file mode 100644 index 00000000..6822d3f7 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/timer_scheduler.hpp @@ -0,0 +1,36 @@ +// +// timer_scheduler.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_TIMER_SCHEDULER_HPP +#define ASIO_DETAIL_TIMER_SCHEDULER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/timer_scheduler_fwd.hpp" + +#if defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_io_service.hpp" +#elif defined(ASIO_HAS_EPOLL) +# include "asio/detail/epoll_reactor.hpp" +#elif defined(ASIO_HAS_KQUEUE) +# include "asio/detail/kqueue_reactor.hpp" +#elif defined(ASIO_HAS_DEV_POLL) +# include "asio/detail/dev_poll_reactor.hpp" +#else +# include "asio/detail/select_reactor.hpp" +#endif + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TIMER_SCHEDULER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/timer_scheduler_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/timer_scheduler_fwd.hpp new file mode 100644 index 00000000..d766a87f --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/timer_scheduler_fwd.hpp @@ -0,0 +1,46 @@ +// +// timer_scheduler_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_TIMER_SCHEDULER_FWD_HPP +#define ASIO_DETAIL_TIMER_SCHEDULER_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/dev_poll_reactor_fwd.hpp" +#include "asio/detail/epoll_reactor_fwd.hpp" +#include "asio/detail/kqueue_reactor_fwd.hpp" +#include "asio/detail/select_reactor_fwd.hpp" +#include "asio/detail/win_iocp_io_service_fwd.hpp" + +namespace asio { +namespace detail { + +#if defined(ASIO_HAS_IOCP) +typedef win_iocp_io_service timer_scheduler; +#elif defined(ASIO_HAS_EPOLL) +typedef epoll_reactor timer_scheduler; +#elif defined(ASIO_HAS_KQUEUE) +typedef kqueue_reactor timer_scheduler; +#elif defined(ASIO_HAS_DEV_POLL) +typedef dev_poll_reactor timer_scheduler; +#else +typedef select_reactor timer_scheduler; +#endif + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TIMER_SCHEDULER_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/tss_ptr.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/tss_ptr.hpp new file mode 100644 index 00000000..ac67d9f0 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/tss_ptr.hpp @@ -0,0 +1,65 @@ +// +// tss_ptr.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_TSS_PTR_HPP +#define ASIO_DETAIL_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) +# include "asio/detail/null_tss_ptr.hpp" +#elif defined(BOOST_WINDOWS) +# include "asio/detail/win_tss_ptr.hpp" +#elif defined(BOOST_HAS_PTHREADS) +# include "asio/detail/posix_tss_ptr.hpp" +#else +# error Only Windows and POSIX are supported! +#endif + +namespace asio { +namespace detail { + +template +class tss_ptr +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) + : public null_tss_ptr +#elif defined(BOOST_WINDOWS) + : public win_tss_ptr +#elif defined(BOOST_HAS_PTHREADS) + : public posix_tss_ptr +#endif +{ +public: + void operator=(T* value) + { +#if !defined(BOOST_HAS_THREADS) || defined(ASIO_DISABLE_THREADS) + null_tss_ptr::operator=(value); +#elif defined(BOOST_WINDOWS) + win_tss_ptr::operator=(value); +#elif defined(BOOST_HAS_PTHREADS) + posix_tss_ptr::operator=(value); +#endif + } +}; + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_TSS_PTR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_event.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_event.hpp new file mode 100644 index 00000000..cabb2c38 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_event.hpp @@ -0,0 +1,112 @@ +// +// win_event.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_EVENT_HPP +#define ASIO_DETAIL_WIN_EVENT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_WINDOWS) + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +class win_event + : private noncopyable +{ +public: + // Constructor. + win_event() + : event_(::CreateEvent(0, true, false, 0)) + { + if (!event_) + { + DWORD last_error = ::GetLastError(); + asio::system_error e( + asio::error_code(last_error, + asio::error::get_system_category()), + "event"); + boost::throw_exception(e); + } + } + + // Destructor. + ~win_event() + { + ::CloseHandle(event_); + } + + // Signal the event. + template + void signal(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + (void)lock; + ::SetEvent(event_); + } + + // Signal the event and unlock the mutex. + template + void signal_and_unlock(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + lock.unlock(); + ::SetEvent(event_); + } + + // Reset the event. + template + void clear(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + (void)lock; + ::ResetEvent(event_); + } + + // Wait for the event to become signalled. + template + void wait(Lock& lock) + { + BOOST_ASSERT(lock.locked()); + lock.unlock(); + ::WaitForSingleObject(event_, INFINITE); + lock.lock(); + } + +private: + HANDLE event_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_WINDOWS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_EVENT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_fd_set_adapter.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_fd_set_adapter.hpp new file mode 100644 index 00000000..012a10ff --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_fd_set_adapter.hpp @@ -0,0 +1,88 @@ +// +// win_fd_set_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP +#define ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/socket_types.hpp" + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +namespace asio { +namespace detail { + +// Adapts the FD_SET type to meet the Descriptor_Set concept's requirements. +class win_fd_set_adapter +{ +public: + enum { win_fd_set_size = 1024 }; + + win_fd_set_adapter() + : max_descriptor_(invalid_socket) + { + fd_set_.fd_count = 0; + } + + bool set(socket_type descriptor) + { + for (u_int i = 0; i < fd_set_.fd_count; ++i) + if (fd_set_.fd_array[i] == descriptor) + return true; + if (fd_set_.fd_count < win_fd_set_size) + { + fd_set_.fd_array[fd_set_.fd_count++] = descriptor; + return true; + } + return false; + } + + bool is_set(socket_type descriptor) const + { + return !!__WSAFDIsSet(descriptor, + const_cast(reinterpret_cast(&fd_set_))); + } + + operator fd_set*() + { + return reinterpret_cast(&fd_set_); + } + + socket_type max_descriptor() const + { + return max_descriptor_; + } + +private: + // This structure is defined to be compatible with the Windows API fd_set + // structure, but without being dependent on the value of FD_SETSIZE. + struct win_fd_set + { + u_int fd_count; + SOCKET fd_array[win_fd_set_size]; + }; + + win_fd_set fd_set_; + socket_type max_descriptor_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_fenced_block.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_fenced_block.hpp new file mode 100644 index 00000000..6338488f --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_fenced_block.hpp @@ -0,0 +1,75 @@ +// +// win_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_FENCED_BLOCK_HPP +#define ASIO_DETAIL_WIN_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_WINDOWS) && !defined(UNDER_CE) + +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace detail { + +class win_fenced_block + : private noncopyable +{ +public: + // Constructor. + win_fenced_block() + { +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1400) +# if defined(_M_IX86) +# pragma warning(push) +# pragma warning(disable:4793) + LONG barrier; + __asm { xchg barrier, eax } +# pragma warning(pop) +# endif // defined(_M_IX86) +#else // defined(BOOST_MSVC) && (BOOST_MSVC < 1400) + MemoryBarrier(); +#endif // defined(BOOST_MSVC) && (BOOST_MSVC < 1400) + } + + // Destructor. + ~win_fenced_block() + { +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1400) +# if defined(_M_IX86) +# pragma warning(push) +# pragma warning(disable:4793) + LONG barrier; + __asm { xchg barrier, eax } +# pragma warning(pop) +# endif // defined(_M_IX86) +#else // defined(BOOST_MSVC) && (BOOST_MSVC < 1400) + MemoryBarrier(); +#endif // defined(BOOST_MSVC) && (BOOST_MSVC < 1400) + } +}; + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_FENCED_BLOCK_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_handle_service.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_handle_service.hpp new file mode 100644 index 00000000..bfc159ce --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_handle_service.hpp @@ -0,0 +1,735 @@ +// +// win_iocp_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP +#define ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/win_iocp_io_service_fwd.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/win_iocp_io_service.hpp" + +namespace asio { +namespace detail { + +class win_iocp_handle_service +{ +public: + // The native type of a stream handle. + typedef HANDLE native_type; + + // The implementation type of the stream handle. + class implementation_type + { + public: + // Default constructor. + implementation_type() + : handle_(INVALID_HANDLE_VALUE), + safe_cancellation_thread_id_(0), + next_(0), + prev_(0) + { + } + + private: + // Only this service will have access to the internal values. + friend class win_iocp_handle_service; + + // The native stream handle representation. + native_type handle_; + + // The ID of the thread from which it is safe to cancel asynchronous + // operations. 0 means no asynchronous operations have been started yet. + // ~0 means asynchronous operations have been started from more than one + // thread, and cancellation is not supported for the handle. + DWORD safe_cancellation_thread_id_; + + // Pointers to adjacent handle implementations in linked list. + implementation_type* next_; + implementation_type* prev_; + }; + + win_iocp_handle_service(asio::io_service& io_service) + : iocp_service_(asio::use_service(io_service)), + mutex_(), + impl_list_(0) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + // Close all implementations, causing all operations to complete. + asio::detail::mutex::scoped_lock lock(mutex_); + implementation_type* impl = impl_list_; + while (impl) + { + close_for_destruction(*impl); + impl = impl->next_; + } + } + + // Construct a new handle implementation. + void construct(implementation_type& impl) + { + impl.handle_ = INVALID_HANDLE_VALUE; + impl.safe_cancellation_thread_id_ = 0; + + // Insert implementation into linked list of all implementations. + asio::detail::mutex::scoped_lock lock(mutex_); + impl.next_ = impl_list_; + impl.prev_ = 0; + if (impl_list_) + impl_list_->prev_ = &impl; + impl_list_ = &impl; + } + + // Destroy a handle implementation. + void destroy(implementation_type& impl) + { + close_for_destruction(impl); + + // Remove implementation from linked list of all implementations. + asio::detail::mutex::scoped_lock lock(mutex_); + if (impl_list_ == &impl) + impl_list_ = impl.next_; + if (impl.prev_) + impl.prev_->next_ = impl.next_; + if (impl.next_) + impl.next_->prev_= impl.prev_; + impl.next_ = 0; + impl.prev_ = 0; + } + + // Assign a native handle to a handle implementation. + asio::error_code assign(implementation_type& impl, + const native_type& native_handle, asio::error_code& ec) + { + if (is_open(impl)) + { + ec = asio::error::already_open; + return ec; + } + + if (iocp_service_.register_handle(native_handle, ec)) + return ec; + + impl.handle_ = native_handle; + ec = asio::error_code(); + return ec; + } + + // Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return impl.handle_ != INVALID_HANDLE_VALUE; + } + + // Destroy a handle implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + if (is_open(impl)) + { + if (!::CloseHandle(impl.handle_)) + { + DWORD last_error = ::GetLastError(); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return ec; + } + + impl.handle_ = INVALID_HANDLE_VALUE; + impl.safe_cancellation_thread_id_ = 0; + } + + ec = asio::error_code(); + return ec; + } + + // Get the native handle representation. + native_type native(const implementation_type& impl) const + { + return impl.handle_; + } + + // Cancel all operations associated with the handle. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + } + else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress( + ::GetModuleHandleA("KERNEL32"), "CancelIoEx")) + { + // The version of Windows supports cancellation from any thread. + typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED); + cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr; + if (!cancel_io_ex(impl.handle_, 0)) + { + DWORD last_error = ::GetLastError(); + if (last_error == ERROR_NOT_FOUND) + { + // ERROR_NOT_FOUND means that there were no operations to be + // cancelled. We swallow this error to match the behaviour on other + // platforms. + ec = asio::error_code(); + } + else + { + ec = asio::error_code(last_error, + asio::error::get_system_category()); + } + } + else + { + ec = asio::error_code(); + } + } + else if (impl.safe_cancellation_thread_id_ == 0) + { + // No operations have been started, so there's nothing to cancel. + ec = asio::error_code(); + } + else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId()) + { + // Asynchronous operations have been started from the current thread only, + // so it is safe to try to cancel them using CancelIo. + if (!::CancelIo(impl.handle_)) + { + DWORD last_error = ::GetLastError(); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + } + else + { + ec = asio::error_code(); + } + } + else + { + // Asynchronous operations have been started from more than one thread, + // so cancellation is not safe. + ec = asio::error::operation_not_supported; + } + + return ec; + } + + class overlapped_wrapper + : public OVERLAPPED + { + public: + explicit overlapped_wrapper(asio::error_code& ec) + { + Internal = 0; + InternalHigh = 0; + Offset = 0; + OffsetHigh = 0; + + // Create a non-signalled manual-reset event, for GetOverlappedResult. + hEvent = ::CreateEvent(0, TRUE, FALSE, 0); + if (hEvent) + { + // As documented in GetQueuedCompletionStatus, setting the low order + // bit of this event prevents our synchronous writes from being treated + // as completion port events. + *reinterpret_cast(&hEvent) |= 1; + } + else + { + DWORD last_error = ::GetLastError(); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + } + } + + ~overlapped_wrapper() + { + if (hEvent) + { + ::CloseHandle(hEvent); + } + } + }; + + // Write the given data. Returns the number of bytes written. + template + size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return write_some_at(impl, 0, buffers, ec); + } + + // Write the given data at the specified offset. Returns the number of bytes + // written. + template + size_t write_some_at(implementation_type& impl, boost::uint64_t offset, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + asio::const_buffer buffer = + buffer_sequence_adapter::first(buffers); + + // A request to write 0 bytes on a handle is a no-op. + if (asio::buffer_size(buffer) == 0) + { + ec = asio::error_code(); + return 0; + } + + overlapped_wrapper overlapped(ec); + if (ec) + { + return 0; + } + + // Write the data. + overlapped.Offset = offset & 0xFFFFFFFF; + overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; + BOOL ok = ::WriteFile(impl.handle_, + asio::buffer_cast(buffer), + static_cast(asio::buffer_size(buffer)), 0, &overlapped); + if (!ok) + { + DWORD last_error = ::GetLastError(); + if (last_error != ERROR_IO_PENDING) + { + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return 0; + } + } + + // Wait for the operation to complete. + DWORD bytes_transferred = 0; + ok = ::GetOverlappedResult(impl.handle_, + &overlapped, &bytes_transferred, TRUE); + if (!ok) + { + DWORD last_error = ::GetLastError(); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return 0; + } + + ec = asio::error_code(); + return bytes_transferred; + } + + template + class write_op : public operation + { + public: + write_op(const ConstBufferSequence& buffers, Handler handler) + : operation(&write_op::do_complete), + buffers_(buffers), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + write_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + buffer_sequence_adapter::validate(o->buffers_); +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, ec, bytes_transferred); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + ConstBufferSequence buffers_; + Handler handler_; + }; + + // Start an asynchronous write. The data being written must be valid for the + // lifetime of the asynchronous operation. + template + void async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, Handler handler) + { + async_write_some_at(impl, 0, buffers, handler); + } + + // Start an asynchronous write at a specified offset. The data being written + // must be valid for the lifetime of the asynchronous operation. + template + void async_write_some_at(implementation_type& impl, boost::uint64_t offset, + const ConstBufferSequence& buffers, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef write_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, buffers, handler); + + start_write_op(impl, offset, + buffer_sequence_adapter::first(buffers), ptr.get()); + ptr.release(); + } + + // Read some data. Returns the number of bytes received. + template + size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return read_some_at(impl, 0, buffers, ec); + } + + // Read some data at a specified offset. Returns the number of bytes received. + template + size_t read_some_at(implementation_type& impl, boost::uint64_t offset, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + asio::mutable_buffer buffer = + buffer_sequence_adapter::first(buffers); + + // A request to read 0 bytes on a stream handle is a no-op. + if (asio::buffer_size(buffer) == 0) + { + ec = asio::error_code(); + return 0; + } + + overlapped_wrapper overlapped(ec); + if (ec) + { + return 0; + } + + // Read some data. + overlapped.Offset = offset & 0xFFFFFFFF; + overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; + BOOL ok = ::ReadFile(impl.handle_, + asio::buffer_cast(buffer), + static_cast(asio::buffer_size(buffer)), 0, &overlapped); + if (!ok) + { + DWORD last_error = ::GetLastError(); + if (last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA) + { + if (last_error == ERROR_HANDLE_EOF) + { + ec = asio::error::eof; + } + else + { + ec = asio::error_code(last_error, + asio::error::get_system_category()); + } + return 0; + } + } + + // Wait for the operation to complete. + DWORD bytes_transferred = 0; + ok = ::GetOverlappedResult(impl.handle_, + &overlapped, &bytes_transferred, TRUE); + if (!ok) + { + DWORD last_error = ::GetLastError(); + if (last_error == ERROR_HANDLE_EOF) + { + ec = asio::error::eof; + } + else + { + ec = asio::error_code(last_error, + asio::error::get_system_category()); + } + return 0; + } + + ec = asio::error_code(); + return bytes_transferred; + } + + template + class read_op : public operation + { + public: + read_op(const MutableBufferSequence& buffers, Handler handler) + : operation(&read_op::do_complete), + buffers_(buffers), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + read_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + buffer_sequence_adapter::validate(o->buffers_); +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_HANDLE_EOF) + { + ec = asio::error::eof; + } + + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, ec, bytes_transferred); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + MutableBufferSequence buffers_; + Handler handler_; + }; + + // Start an asynchronous read. The buffer for the data being received must be + // valid for the lifetime of the asynchronous operation. + template + void async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, Handler handler) + { + async_read_some_at(impl, 0, buffers, handler); + } + + // Start an asynchronous read at a specified offset. The buffer for the data + // being received must be valid for the lifetime of the asynchronous + // operation. + template + void async_read_some_at(implementation_type& impl, boost::uint64_t offset, + const MutableBufferSequence& buffers, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef read_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, buffers, handler); + + start_read_op(impl, offset, + buffer_sequence_adapter::first(buffers), ptr.get()); + ptr.release(); + } + +private: + // Prevent the use of the null_buffers type with this service. + size_t write_some(implementation_type& impl, + const null_buffers& buffers, asio::error_code& ec); + size_t write_some_at(implementation_type& impl, boost::uint64_t offset, + const null_buffers& buffers, asio::error_code& ec); + template + void async_write_some(implementation_type& impl, + const null_buffers& buffers, Handler handler); + template + void async_write_some_at(implementation_type& impl, boost::uint64_t offset, + const null_buffers& buffers, Handler handler); + size_t read_some(implementation_type& impl, + const null_buffers& buffers, asio::error_code& ec); + size_t read_some_at(implementation_type& impl, boost::uint64_t offset, + const null_buffers& buffers, asio::error_code& ec); + template + void async_read_some(implementation_type& impl, + const null_buffers& buffers, Handler handler); + template + void async_read_some_at(implementation_type& impl, boost::uint64_t offset, + const null_buffers& buffers, Handler handler); + + // Helper function to start a write operation. + void start_write_op(implementation_type& impl, boost::uint64_t offset, + const asio::const_buffer& buffer, operation* op) + { + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (!is_open(impl)) + { + iocp_service_.on_completion(op, asio::error::bad_descriptor); + } + else if (asio::buffer_size(buffer) == 0) + { + // A request to write 0 bytes on a handle is a no-op. + iocp_service_.on_completion(op); + } + else + { + DWORD bytes_transferred = 0; + op->Offset = offset & 0xFFFFFFFF; + op->OffsetHigh = (offset >> 32) & 0xFFFFFFFF; + BOOL ok = ::WriteFile(impl.handle_, + asio::buffer_cast(buffer), + static_cast(asio::buffer_size(buffer)), + &bytes_transferred, op); + DWORD last_error = ::GetLastError(); + if (!ok && last_error != ERROR_IO_PENDING + && last_error != ERROR_MORE_DATA) + { + iocp_service_.on_completion(op, last_error, bytes_transferred); + } + else + { + iocp_service_.on_pending(op); + } + } + } + + // Helper function to start a read operation. + void start_read_op(implementation_type& impl, boost::uint64_t offset, + const asio::mutable_buffer& buffer, operation* op) + { + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (!is_open(impl)) + { + iocp_service_.on_completion(op, asio::error::bad_descriptor); + } + else if (asio::buffer_size(buffer) == 0) + { + // A request to read 0 bytes on a handle is a no-op. + iocp_service_.on_completion(op); + } + else + { + DWORD bytes_transferred = 0; + op->Offset = offset & 0xFFFFFFFF; + op->OffsetHigh = (offset >> 32) & 0xFFFFFFFF; + BOOL ok = ::ReadFile(impl.handle_, + asio::buffer_cast(buffer), + static_cast(asio::buffer_size(buffer)), + &bytes_transferred, op); + DWORD last_error = ::GetLastError(); + if (!ok && last_error != ERROR_IO_PENDING + && last_error != ERROR_MORE_DATA) + { + iocp_service_.on_completion(op, last_error, bytes_transferred); + } + else + { + iocp_service_.on_pending(op); + } + } + } + + // Update the ID of the thread from which cancellation is safe. + void update_cancellation_thread_id(implementation_type& impl) + { +#if defined(ASIO_ENABLE_CANCELIO) + if (impl.safe_cancellation_thread_id_ == 0) + impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); + else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) + impl.safe_cancellation_thread_id_ = ~DWORD(0); +#else // defined(ASIO_ENABLE_CANCELIO) + (void)impl; +#endif // defined(ASIO_ENABLE_CANCELIO) + } + + // Helper function to close a handle when the associated object is being + // destroyed. + void close_for_destruction(implementation_type& impl) + { + if (is_open(impl)) + { + ::CloseHandle(impl.handle_); + impl.handle_ = INVALID_HANDLE_VALUE; + impl.safe_cancellation_thread_id_ = 0; + } + } + + // The IOCP service used for running asynchronous operations and dispatching + // handlers. + win_iocp_io_service& iocp_service_; + + // Mutex to protect access to the linked list of implementations. + asio::detail::mutex mutex_; + + // The head of a linked list of all implementations. + implementation_type* impl_list_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(ASIO_HAS_IOCP) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_io_service.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_io_service.hpp new file mode 100644 index 00000000..fd899c11 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_io_service.hpp @@ -0,0 +1,686 @@ +// +// win_iocp_io_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_IOCP_IO_SERVICE_HPP +#define ASIO_DETAIL_WIN_IOCP_IO_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/win_iocp_io_service_fwd.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/io_service.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/call_stack.hpp" +#include "asio/detail/completion_handler.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/op_queue.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/timer_op.hpp" +#include "asio/detail/timer_queue_base.hpp" +#include "asio/detail/timer_queue_fwd.hpp" +#include "asio/detail/timer_queue_set.hpp" +#include "asio/detail/win_iocp_operation.hpp" + +namespace asio { +namespace detail { + +class timer_op; + +class win_iocp_io_service + : public asio::detail::service_base +{ +public: + typedef win_iocp_operation operation; + + // Constructor. + win_iocp_io_service(asio::io_service& io_service) + : asio::detail::service_base(io_service), + iocp_(), + outstanding_work_(0), + stopped_(0), + shutdown_(0), + timer_thread_(0), + timer_interrupt_issued_(false) + { + } + + void init(size_t concurrency_hint) + { + iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, + static_cast((std::min)(concurrency_hint, DWORD(~0)))); + if (!iocp_.handle) + { + DWORD last_error = ::GetLastError(); + asio::system_error e( + asio::error_code(last_error, + asio::error::get_system_category()), + "iocp"); + boost::throw_exception(e); + } + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + ::InterlockedExchange(&shutdown_, 1); + + while (::InterlockedExchangeAdd(&outstanding_work_, 0) > 0) + { + op_queue ops; + timer_queues_.get_all_timers(ops); + ops.push(completed_ops_); + if (!ops.empty()) + { + while (operation* op = ops.front()) + { + ops.pop(); + ::InterlockedDecrement(&outstanding_work_); + op->destroy(); + } + } + else + { + DWORD bytes_transferred = 0; + dword_ptr_t completion_key = 0; + LPOVERLAPPED overlapped = 0; + ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, + &completion_key, &overlapped, max_timeout); + if (overlapped) + { + ::InterlockedDecrement(&outstanding_work_); + static_cast(overlapped)->destroy(); + } + } + } + } + + // Initialise the task. Nothing to do here. + void init_task() + { + } + + // Register a handle with the IO completion port. + asio::error_code register_handle( + HANDLE handle, asio::error_code& ec) + { + if (::CreateIoCompletionPort(handle, iocp_.handle, 0, 0) == 0) + { + DWORD last_error = ::GetLastError(); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + } + else + { + ec = asio::error_code(); + } + return ec; + } + + // Run the event loop until stopped or no more work. + size_t run(asio::error_code& ec) + { + if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) + { + stop(); + ec = asio::error_code(); + return 0; + } + + call_stack::context ctx(this); + + size_t n = 0; + while (do_one(true, ec)) + if (n != (std::numeric_limits::max)()) + ++n; + return n; + } + + // Run until stopped or one operation is performed. + size_t run_one(asio::error_code& ec) + { + if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) + { + stop(); + ec = asio::error_code(); + return 0; + } + + call_stack::context ctx(this); + + return do_one(true, ec); + } + + // Poll for operations without blocking. + size_t poll(asio::error_code& ec) + { + if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) + { + stop(); + ec = asio::error_code(); + return 0; + } + + call_stack::context ctx(this); + + size_t n = 0; + while (do_one(false, ec)) + if (n != (std::numeric_limits::max)()) + ++n; + return n; + } + + // Poll for one operation without blocking. + size_t poll_one(asio::error_code& ec) + { + if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) + { + stop(); + ec = asio::error_code(); + return 0; + } + + call_stack::context ctx(this); + + return do_one(false, ec); + } + + // Stop the event processing loop. + void stop() + { + if (::InterlockedExchange(&stopped_, 1) == 0) + { + if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) + { + DWORD last_error = ::GetLastError(); + asio::system_error e( + asio::error_code(last_error, + asio::error::get_system_category()), + "pqcs"); + boost::throw_exception(e); + } + } + } + + // Reset in preparation for a subsequent run invocation. + void reset() + { + ::InterlockedExchange(&stopped_, 0); + } + + // Notify that some work has started. + void work_started() + { + ::InterlockedIncrement(&outstanding_work_); + } + + // Notify that some work has finished. + void work_finished() + { + if (::InterlockedDecrement(&outstanding_work_) == 0) + stop(); + } + + // Request invocation of the given handler. + template + void dispatch(Handler handler) + { + if (call_stack::contains(this)) + { + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + else + post(handler); + } + + // Request invocation of the given handler and return immediately. + template + void post(Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef completion_handler value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + post_immediate_completion(ptr.get()); + ptr.release(); + } + + // Request invocation of the given operation and return immediately. Assumes + // that work_started() has not yet been called for the operation. + void post_immediate_completion(operation* op) + { + work_started(); + post_deferred_completion(op); + } + + // Request invocation of the given operation and return immediately. Assumes + // that work_started() was previously called for the operation. + void post_deferred_completion(operation* op) + { + // Flag the operation as ready. + op->ready_ = 1; + + // Enqueue the operation on the I/O completion port. + if (!::PostQueuedCompletionStatus(iocp_.handle, + 0, overlapped_contains_result, op)) + { + // Out of resources. Put on completed queue instead. + asio::detail::mutex::scoped_lock lock(timer_mutex_); + completed_ops_.push(op); + } + } + + // Request invocation of the given operation and return immediately. Assumes + // that work_started() was previously called for the operations. + void post_deferred_completions(op_queue& ops) + { + while (operation* op = ops.front()) + { + ops.pop(); + + // Flag the operation as ready. + op->ready_ = 1; + + // Enqueue the operation on the I/O completion port. + if (!::PostQueuedCompletionStatus(iocp_.handle, + 0, overlapped_contains_result, op)) + { + // Out of resources. Put on completed queue instead. + asio::detail::mutex::scoped_lock lock(timer_mutex_); + completed_ops_.push(op); + completed_ops_.push(ops); + } + } + } + + // Called after starting an overlapped I/O operation that did not complete + // immediately. The caller must have already called work_started() prior to + // starting the operation. + void on_pending(operation* op) + { + if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1) + { + // Enqueue the operation on the I/O completion port. + if (!::PostQueuedCompletionStatus(iocp_.handle, + 0, overlapped_contains_result, op)) + { + // Out of resources. Put on completed queue instead. + asio::detail::mutex::scoped_lock lock(timer_mutex_); + completed_ops_.push(op); + } + } + } + + // Called after starting an overlapped I/O operation that completed + // immediately. The caller must have already called work_started() prior to + // starting the operation. + void on_completion(operation* op, + DWORD last_error = 0, DWORD bytes_transferred = 0) + { + // Flag that the operation is ready for invocation. + op->ready_ = 1; + + // Store results in the OVERLAPPED structure. + op->Internal = asio::error::get_system_category(); + op->Offset = last_error; + op->OffsetHigh = bytes_transferred; + + // Enqueue the operation on the I/O completion port. + if (!::PostQueuedCompletionStatus(iocp_.handle, + 0, overlapped_contains_result, op)) + { + // Out of resources. Put on completed queue instead. + asio::detail::mutex::scoped_lock lock(timer_mutex_); + completed_ops_.push(op); + } + } + + // Called after starting an overlapped I/O operation that completed + // immediately. The caller must have already called work_started() prior to + // starting the operation. + void on_completion(operation* op, + const asio::error_code& ec, DWORD bytes_transferred = 0) + { + // Flag that the operation is ready for invocation. + op->ready_ = 1; + + // Store results in the OVERLAPPED structure. + op->Internal = ec.category(); + op->Offset = ec.value(); + op->OffsetHigh = bytes_transferred; + + // Enqueue the operation on the I/O completion port. + if (!::PostQueuedCompletionStatus(iocp_.handle, + 0, overlapped_contains_result, op)) + { + // Out of resources. Put on completed queue instead. + asio::detail::mutex::scoped_lock lock(timer_mutex_); + completed_ops_.push(op); + } + } + + // Add a new timer queue to the service. + template + void add_timer_queue(timer_queue& timer_queue) + { + asio::detail::mutex::scoped_lock lock(timer_mutex_); + timer_queues_.insert(&timer_queue); + } + + // Remove a timer queue from the service. + template + void remove_timer_queue(timer_queue& timer_queue) + { + asio::detail::mutex::scoped_lock lock(timer_mutex_); + timer_queues_.erase(&timer_queue); + } + + // Schedule a new operation in the given timer queue to expire at the + // specified absolute time. + template + void schedule_timer(timer_queue& timer_queue, + const typename Time_Traits::time_type& time, timer_op* op, void* token) + { + // If the service has been shut down we silently discard the timer. + if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) + return; + + asio::detail::mutex::scoped_lock lock(timer_mutex_); + bool interrupt = timer_queue.enqueue_timer(time, op, token); + work_started(); + if (interrupt && !timer_interrupt_issued_) + { + timer_interrupt_issued_ = true; + lock.unlock(); + ::PostQueuedCompletionStatus(iocp_.handle, + 0, steal_timer_dispatching, 0); + } + } + + // Cancel the timer associated with the given token. Returns the number of + // handlers that have been posted or dispatched. + template + std::size_t cancel_timer(timer_queue& timer_queue, void* token) + { + // If the service has been shut down we silently ignore the cancellation. + if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) + return 0; + + asio::detail::mutex::scoped_lock lock(timer_mutex_); + op_queue ops; + std::size_t n = timer_queue.cancel_timer(token, ops); + post_deferred_completions(ops); + if (n > 0 && !timer_interrupt_issued_) + { + timer_interrupt_issued_ = true; + lock.unlock(); + ::PostQueuedCompletionStatus(iocp_.handle, + 0, steal_timer_dispatching, 0); + } + return n; + } + +private: +#if defined(WINVER) && (WINVER < 0x0500) + typedef DWORD dword_ptr_t; + typedef ULONG ulong_ptr_t; +#else // defined(WINVER) && (WINVER < 0x0500) + typedef DWORD_PTR dword_ptr_t; + typedef ULONG_PTR ulong_ptr_t; +#endif // defined(WINVER) && (WINVER < 0x0500) + + // Dequeues at most one operation from the I/O completion port, and then + // executes it. Returns the number of operations that were dequeued (i.e. + // either 0 or 1). + size_t do_one(bool block, asio::error_code& ec) + { + long this_thread_id = static_cast(::GetCurrentThreadId()); + + for (;;) + { + // Try to acquire responsibility for dispatching timers. + bool dispatching_timers = (::InterlockedCompareExchange( + &timer_thread_, this_thread_id, 0) == 0); + + // Calculate timeout for GetQueuedCompletionStatus call. + DWORD timeout = max_timeout; + if (dispatching_timers) + { + asio::detail::mutex::scoped_lock lock(timer_mutex_); + timer_interrupt_issued_ = false; + timeout = get_timeout(); + } + + // Get the next operation from the queue. + DWORD bytes_transferred = 0; + dword_ptr_t completion_key = 0; + LPOVERLAPPED overlapped = 0; + ::SetLastError(0); + BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, + &completion_key, &overlapped, block ? timeout : 0); + DWORD last_error = ::GetLastError(); + + // Dispatch any pending timers. + if (dispatching_timers) + { + asio::detail::mutex::scoped_lock lock(timer_mutex_); + op_queue ops; + ops.push(completed_ops_); + timer_queues_.get_ready_timers(ops); + post_deferred_completions(ops); + } + + if (!ok && overlapped == 0) + { + if (block && last_error == WAIT_TIMEOUT) + { + // Relinquish responsibility for dispatching timers. + if (dispatching_timers) + { + ::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id); + } + + continue; + } + + // Transfer responsibility for dispatching timers to another thread. + if (dispatching_timers && ::InterlockedCompareExchange( + &timer_thread_, 0, this_thread_id) == this_thread_id) + { + ::PostQueuedCompletionStatus(iocp_.handle, + 0, transfer_timer_dispatching, 0); + } + + ec = asio::error_code(); + return 0; + } + else if (overlapped) + { + operation* op = static_cast(overlapped); + asio::error_code result_ec(last_error, + asio::error::get_system_category()); + + // Transfer responsibility for dispatching timers to another thread. + if (dispatching_timers && ::InterlockedCompareExchange( + &timer_thread_, 0, this_thread_id) == this_thread_id) + { + ::PostQueuedCompletionStatus(iocp_.handle, + 0, transfer_timer_dispatching, 0); + } + + // We may have been passed the last_error and bytes_transferred in the + // OVERLAPPED structure itself. + if (completion_key == overlapped_contains_result) + { + result_ec = asio::error_code(static_cast(op->Offset), + static_cast(op->Internal)); + bytes_transferred = op->OffsetHigh; + } + + // Otherwise ensure any result has been saved into the OVERLAPPED + // structure. + else + { + op->Internal = result_ec.category(); + op->Offset = result_ec.value(); + op->OffsetHigh = bytes_transferred; + } + + // Dispatch the operation only if ready. The operation may not be ready + // if the initiating function (e.g. a call to WSARecv) has not yet + // returned. This is because the initiating function still wants access + // to the operation's OVERLAPPED structure. + if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1) + { + // Ensure the count of outstanding work is decremented on block exit. + work_finished_on_block_exit on_exit = { this }; + (void)on_exit; + + op->complete(*this, result_ec, bytes_transferred); + ec = asio::error_code(); + return 1; + } + } + else if (completion_key == transfer_timer_dispatching) + { + // Woken up to try to acquire responsibility for dispatching timers. + ::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id); + } + else if (completion_key == steal_timer_dispatching) + { + // Woken up to steal responsibility for dispatching timers. + ::InterlockedExchange(&timer_thread_, 0); + } + else + { + // Relinquish responsibility for dispatching timers. If the io_service + // is not being stopped then the thread will get an opportunity to + // reacquire timer responsibility on the next loop iteration. + if (dispatching_timers) + { + ::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id); + } + + // The stopped_ flag is always checked to ensure that any leftover + // interrupts from a previous run invocation are ignored. + if (::InterlockedExchangeAdd(&stopped_, 0) != 0) + { + // Wake up next thread that is blocked on GetQueuedCompletionStatus. + if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) + { + last_error = ::GetLastError(); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return 0; + } + + ec = asio::error_code(); + return 0; + } + } + } + } + + // Get the timeout value for the GetQueuedCompletionStatus call. The timeout + // value is returned as a number of milliseconds. We will wait no longer than + // 1000 milliseconds. + DWORD get_timeout() + { + return timer_queues_.wait_duration_msec(max_timeout); + } + + // Helper class to call work_finished() on block exit. + struct work_finished_on_block_exit + { + ~work_finished_on_block_exit() + { + io_service_->work_finished(); + } + + win_iocp_io_service* io_service_; + }; + + // The IO completion port used for queueing operations. + struct iocp_holder + { + HANDLE handle; + iocp_holder() : handle(0) {} + ~iocp_holder() { if (handle) ::CloseHandle(handle); } + } iocp_; + + // The count of unfinished work. + long outstanding_work_; + + // Flag to indicate whether the event loop has been stopped. + long stopped_; + + // Flag to indicate whether the service has been shut down. + long shutdown_; + + enum + { + // Maximum GetQueuedCompletionStatus timeout, in milliseconds. + max_timeout = 500, + + // Completion key value to indicate that responsibility for dispatching + // timers is being cooperatively transferred from one thread to another. + transfer_timer_dispatching = 1, + + // Completion key value to indicate that responsibility for dispatching + // timers should be stolen from another thread. + steal_timer_dispatching = 2, + + // Completion key value to indicate that an operation has posted with the + // original last_error and bytes_transferred values stored in the fields of + // the OVERLAPPED structure. + overlapped_contains_result = 3 + }; + + // The thread that's currently in charge of dispatching timers. + long timer_thread_; + + // Mutex for protecting access to the timer queues. + mutex timer_mutex_; + + // Whether a thread has been interrupted to process a new timeout. + bool timer_interrupt_issued_; + + // The timer queues. + timer_queue_set timer_queues_; + + // The operations that are ready to dispatch. + op_queue completed_ops_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(ASIO_HAS_IOCP) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_IOCP_IO_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_io_service_fwd.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_io_service_fwd.hpp new file mode 100644 index 00000000..29d2a054 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_io_service_fwd.hpp @@ -0,0 +1,51 @@ +// +// win_iocp_io_service_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_IOCP_IO_SERVICE_FWD_HPP +#define ASIO_DETAIL_WIN_IOCP_IO_SERVICE_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/socket_types.hpp" + +// This service is only supported on Win32 (NT4 and later). +#if !defined(ASIO_DISABLE_IOCP) +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400) +#if !defined(UNDER_CE) + +// Define this to indicate that IOCP is supported on the target platform. +#define ASIO_HAS_IOCP 1 + +namespace asio { +namespace detail { + +class win_iocp_io_service; +class win_iocp_overlapped_ptr; + +} // namespace detail +} // namespace asio + +#endif // !defined(UNDER_CE) +#endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400) +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // !defined(ASIO_DISABLE_IOCP) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_IOCP_IO_SERVICE_FWD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_operation.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_operation.hpp new file mode 100644 index 00000000..ac810625 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_operation.hpp @@ -0,0 +1,89 @@ +// +// win_iocp_operation.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_IOCP_OPERATION_HPP +#define ASIO_DETAIL_WIN_IOCP_OPERATION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/win_iocp_io_service_fwd.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/error_code.hpp" +#include "asio/detail/op_queue.hpp" + +namespace asio { +namespace detail { + +// Base class for all operations. A function pointer is used instead of virtual +// functions to avoid the associated overhead. +class win_iocp_operation + : public OVERLAPPED +{ +public: + void complete(win_iocp_io_service& owner, + const asio::error_code& ec = asio::error_code(), + std::size_t bytes_transferred = 0) + { + func_(&owner, this, ec, bytes_transferred); + } + + void destroy() + { + func_(0, this, asio::error_code(), 0); + } + +protected: + typedef void (*func_type)(win_iocp_io_service*, + win_iocp_operation*, asio::error_code, std::size_t); + + win_iocp_operation(func_type func) + : next_(0), + func_(func) + { + reset(); + } + + // Prevents deletion through this type. + ~win_iocp_operation() + { + } + + void reset() + { + Internal = 0; + InternalHigh = 0; + Offset = 0; + OffsetHigh = 0; + hEvent = 0; + ready_ = 0; + } + +private: + friend class op_queue_access; + friend class win_iocp_io_service; + win_iocp_operation* next_; + func_type func_; + long ready_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(ASIO_HAS_IOCP) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_IOCP_OPERATION_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_overlapped_ptr.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_overlapped_ptr.hpp new file mode 100644 index 00000000..47a3f70c --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_overlapped_ptr.hpp @@ -0,0 +1,174 @@ +// +// win_iocp_overlapped_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP +#define ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/win_iocp_io_service_fwd.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/win_iocp_io_service.hpp" +#include "asio/detail/win_iocp_operation.hpp" + +namespace asio { +namespace detail { + +// Wraps a handler to create an OVERLAPPED object for use with overlapped I/O. +class win_iocp_overlapped_ptr + : private noncopyable +{ +public: + // Construct an empty win_iocp_overlapped_ptr. + win_iocp_overlapped_ptr() + : ptr_(0), + iocp_service_(0) + { + } + + // Construct an win_iocp_overlapped_ptr to contain the specified handler. + template + explicit win_iocp_overlapped_ptr( + asio::io_service& io_service, Handler handler) + : ptr_(0), + iocp_service_(0) + { + this->reset(io_service, handler); + } + + // Destructor automatically frees the OVERLAPPED object unless released. + ~win_iocp_overlapped_ptr() + { + reset(); + } + + // Reset to empty. + void reset() + { + if (ptr_) + { + ptr_->destroy(); + ptr_ = 0; + iocp_service_->work_finished(); + iocp_service_ = 0; + } + } + + // Reset to contain the specified handler, freeing any current OVERLAPPED + // object. + template + void reset(asio::io_service& io_service, Handler handler) + { + typedef overlapped_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + io_service.impl_.work_started(); + reset(); + ptr_ = ptr.release(); + iocp_service_ = &io_service.impl_; + } + + // Get the contained OVERLAPPED object. + OVERLAPPED* get() + { + return ptr_; + } + + // Get the contained OVERLAPPED object. + const OVERLAPPED* get() const + { + return ptr_; + } + + // Release ownership of the OVERLAPPED object. + OVERLAPPED* release() + { + if (ptr_) + iocp_service_->on_pending(ptr_); + + OVERLAPPED* tmp = ptr_; + ptr_ = 0; + iocp_service_ = 0; + return tmp; + } + + // Post completion notification for overlapped operation. Releases ownership. + void complete(const asio::error_code& ec, + std::size_t bytes_transferred) + { + if (ptr_) + { + iocp_service_->on_completion(ptr_, ec, + static_cast(bytes_transferred)); + ptr_ = 0; + iocp_service_ = 0; + } + } + +private: + template + struct overlapped_op : public win_iocp_operation + { + overlapped_op(Handler handler) + : win_iocp_operation(&overlapped_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + overlapped_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, ec, bytes_transferred); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + Handler handler_; + }; + + win_iocp_operation* ptr_; + win_iocp_io_service* iocp_service_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(ASIO_HAS_IOCP) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_serial_port_service.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_serial_port_service.hpp new file mode 100644 index 00000000..ed5f75e9 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_serial_port_service.hpp @@ -0,0 +1,288 @@ +// +// win_iocp_serial_port_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP +#define ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/win_iocp_io_service_fwd.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/win_iocp_handle_service.hpp" + +namespace asio { +namespace detail { + +// Extend win_iocp_handle_service to provide serial port support. +class win_iocp_serial_port_service +{ +public: + // The native type of a stream handle. + typedef win_iocp_handle_service::native_type native_type; + + // The implementation type of the stream handle. + typedef win_iocp_handle_service::implementation_type implementation_type; + + win_iocp_serial_port_service(asio::io_service& io_service) + : handle_service_(io_service) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + // Construct a new handle implementation. + void construct(implementation_type& impl) + { + handle_service_.construct(impl); + } + + // Destroy a handle implementation. + void destroy(implementation_type& impl) + { + handle_service_.destroy(impl); + } + + // Open the serial port using the specified device name. + asio::error_code open(implementation_type& impl, + const std::string& device, asio::error_code& ec) + { + if (is_open(impl)) + { + ec = asio::error::already_open; + return ec; + } + + // For convenience, add a leading \\.\ sequence if not already present. + std::string name = (device[0] == '\\') ? device : "\\\\.\\" + device; + + // Open a handle to the serial port. + ::HANDLE handle = ::CreateFileA(name.c_str(), + GENERIC_READ | GENERIC_WRITE, 0, 0, + OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); + if (handle == INVALID_HANDLE_VALUE) + { + DWORD last_error = ::GetLastError(); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return ec; + } + + // Determine the initial serial port parameters. + using namespace std; // For memcpy. + ::DCB dcb; + memset(&dcb, 0, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + if (!::GetCommState(handle, &dcb)) + { + DWORD last_error = ::GetLastError(); + ::CloseHandle(handle); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return ec; + } + + // Set some default serial port parameters. This implementation does not + // support changing these, so they might as well be in a known state. + dcb.fBinary = TRUE; // Win32 only supports binary mode. + dcb.fDsrSensitivity = FALSE; + dcb.fNull = FALSE; // Do not ignore NULL characters. + dcb.fAbortOnError = FALSE; // Ignore serial framing errors. + if (!::SetCommState(handle, &dcb)) + { + DWORD last_error = ::GetLastError(); + ::CloseHandle(handle); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return ec; + } + + // Set up timeouts so that the serial port will behave similarly to a + // network socket. Reads wait for at least one byte, then return with + // whatever they have. Writes return once everything is out the door. + ::COMMTIMEOUTS timeouts; + timeouts.ReadIntervalTimeout = 1; + timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.ReadTotalTimeoutConstant = 0; + timeouts.WriteTotalTimeoutMultiplier = 0; + timeouts.WriteTotalTimeoutConstant = 0; + if (!::SetCommTimeouts(handle, &timeouts)) + { + DWORD last_error = ::GetLastError(); + ::CloseHandle(handle); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return ec; + } + + // We're done. Take ownership of the serial port handle. + if (handle_service_.assign(impl, handle, ec)) + ::CloseHandle(handle); + return ec; + } + + // Assign a native handle to a handle implementation. + asio::error_code assign(implementation_type& impl, + const native_type& native_handle, asio::error_code& ec) + { + return handle_service_.assign(impl, native_handle, ec); + } + + // Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return handle_service_.is_open(impl); + } + + // Destroy a handle implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + return handle_service_.close(impl, ec); + } + + // Get the native handle representation. + native_type native(implementation_type& impl) + { + return handle_service_.native(impl); + } + + // Cancel all operations associated with the handle. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + return handle_service_.cancel(impl, ec); + } + + // Set an option on the serial port. + template + asio::error_code set_option(implementation_type& impl, + const SettableSerialPortOption& option, asio::error_code& ec) + { + using namespace std; // For memcpy. + + ::DCB dcb; + memset(&dcb, 0, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + if (!::GetCommState(handle_service_.native(impl), &dcb)) + { + DWORD last_error = ::GetLastError(); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return ec; + } + + if (option.store(dcb, ec)) + return ec; + + if (!::SetCommState(handle_service_.native(impl), &dcb)) + { + DWORD last_error = ::GetLastError(); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return ec; + } + + ec = asio::error_code(); + return ec; + } + + // Get an option from the serial port. + template + asio::error_code get_option(const implementation_type& impl, + GettableSerialPortOption& option, asio::error_code& ec) const + { + using namespace std; // For memcpy. + + ::DCB dcb; + memset(&dcb, 0, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + if (!::GetCommState(handle_service_.native(impl), &dcb)) + { + DWORD last_error = ::GetLastError(); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return ec; + } + + return option.load(dcb, ec); + } + + // Send a break sequence to the serial port. + asio::error_code send_break(implementation_type&, + asio::error_code& ec) + { + ec = asio::error::operation_not_supported; + return ec; + } + + // Write the given data. Returns the number of bytes sent. + template + size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return handle_service_.write_some(impl, buffers, ec); + } + + // Start an asynchronous write. The data being written must be valid for the + // lifetime of the asynchronous operation. + template + void async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, Handler handler) + { + handle_service_.async_write_some(impl, buffers, handler); + } + + // Read some data. Returns the number of bytes received. + template + size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return handle_service_.read_some(impl, buffers, ec); + } + + // Start an asynchronous read. The buffer for the data being received must be + // valid for the lifetime of the asynchronous operation. + template + void async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, Handler handler) + { + handle_service_.async_read_some(impl, buffers, handler); + } + +private: + // The implementation used for initiating asynchronous operations. + win_iocp_handle_service handle_service_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(ASIO_HAS_IOCP) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_socket_service.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_socket_service.hpp new file mode 100644 index 00000000..cb1d2037 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_iocp_socket_service.hpp @@ -0,0 +1,2010 @@ +// +// win_iocp_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP +#define ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/win_iocp_io_service_fwd.hpp" + +#if defined(ASIO_HAS_IOCP) + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/socket_base.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/fenced_block.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/mutex.hpp" +#include "asio/detail/null_buffers_op.hpp" +#include "asio/detail/operation.hpp" +#include "asio/detail/reactor.hpp" +#include "asio/detail/reactor_op.hpp" +#include "asio/detail/socket_holder.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/win_iocp_io_service.hpp" + +namespace asio { +namespace detail { + +template +class win_iocp_socket_service +{ +public: + // The protocol type. + typedef Protocol protocol_type; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + struct noop_deleter { void operator()(void*) {} }; + typedef boost::shared_ptr shared_cancel_token_type; + typedef boost::weak_ptr weak_cancel_token_type; + + // The native type of a socket. + class native_type + { + public: + native_type(socket_type s) + : socket_(s), + have_remote_endpoint_(false) + { + } + + native_type(socket_type s, const endpoint_type& ep) + : socket_(s), + have_remote_endpoint_(true), + remote_endpoint_(ep) + { + } + + void operator=(socket_type s) + { + socket_ = s; + have_remote_endpoint_ = false; + remote_endpoint_ = endpoint_type(); + } + + operator socket_type() const + { + return socket_; + } + + HANDLE as_handle() const + { + return reinterpret_cast(socket_); + } + + bool have_remote_endpoint() const + { + return have_remote_endpoint_; + } + + endpoint_type remote_endpoint() const + { + return remote_endpoint_; + } + + private: + socket_type socket_; + bool have_remote_endpoint_; + endpoint_type remote_endpoint_; + }; + + // The implementation type of the socket. + class implementation_type + { + public: + // Default constructor. + implementation_type() + : socket_(invalid_socket), + flags_(0), + cancel_token_(), + protocol_(endpoint_type().protocol()), + next_(0), + prev_(0) + { + } + + private: + // Only this service will have access to the internal values. + friend class win_iocp_socket_service; + + // The native socket representation. + native_type socket_; + + enum + { + enable_connection_aborted = 1, // User wants connection_aborted errors. + close_might_block = 2, // User set linger option for blocking close. + user_set_non_blocking = 4 // The user wants a non-blocking socket. + }; + + // Flags indicating the current state of the socket. + unsigned char flags_; + + // We use a shared pointer as a cancellation token here to work around the + // broken Windows support for cancellation. MSDN says that when you call + // closesocket any outstanding WSARecv or WSASend operations will complete + // with the error ERROR_OPERATION_ABORTED. In practice they complete with + // ERROR_NETNAME_DELETED, which means you can't tell the difference between + // a local cancellation and the socket being hard-closed by the peer. + shared_cancel_token_type cancel_token_; + + // The protocol associated with the socket. + protocol_type protocol_; + + // Per-descriptor data used by the reactor. + reactor::per_descriptor_data reactor_data_; + +#if defined(ASIO_ENABLE_CANCELIO) + // The ID of the thread from which it is safe to cancel asynchronous + // operations. 0 means no asynchronous operations have been started yet. + // ~0 means asynchronous operations have been started from more than one + // thread, and cancellation is not supported for the socket. + DWORD safe_cancellation_thread_id_; +#endif // defined(ASIO_ENABLE_CANCELIO) + + // Pointers to adjacent socket implementations in linked list. + implementation_type* next_; + implementation_type* prev_; + }; + + // Constructor. + win_iocp_socket_service(asio::io_service& io_service) + : io_service_(io_service), + iocp_service_(use_service(io_service)), + reactor_(0), + mutex_(), + impl_list_(0) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + // Close all implementations, causing all operations to complete. + asio::detail::mutex::scoped_lock lock(mutex_); + implementation_type* impl = impl_list_; + while (impl) + { + asio::error_code ignored_ec; + close_for_destruction(*impl); + impl = impl->next_; + } + } + + // Construct a new socket implementation. + void construct(implementation_type& impl) + { + impl.socket_ = invalid_socket; + impl.flags_ = 0; + impl.cancel_token_.reset(); +#if defined(ASIO_ENABLE_CANCELIO) + impl.safe_cancellation_thread_id_ = 0; +#endif // defined(ASIO_ENABLE_CANCELIO) + + // Insert implementation into linked list of all implementations. + asio::detail::mutex::scoped_lock lock(mutex_); + impl.next_ = impl_list_; + impl.prev_ = 0; + if (impl_list_) + impl_list_->prev_ = &impl; + impl_list_ = &impl; + } + + // Destroy a socket implementation. + void destroy(implementation_type& impl) + { + close_for_destruction(impl); + + // Remove implementation from linked list of all implementations. + asio::detail::mutex::scoped_lock lock(mutex_); + if (impl_list_ == &impl) + impl_list_ = impl.next_; + if (impl.prev_) + impl.prev_->next_ = impl.next_; + if (impl.next_) + impl.next_->prev_= impl.prev_; + impl.next_ = 0; + impl.prev_ = 0; + } + + // Open a new socket implementation. + asio::error_code open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + if (is_open(impl)) + { + ec = asio::error::already_open; + return ec; + } + + socket_holder sock(socket_ops::socket(protocol.family(), protocol.type(), + protocol.protocol(), ec)); + if (sock.get() == invalid_socket) + return ec; + + HANDLE sock_as_handle = reinterpret_cast(sock.get()); + if (iocp_service_.register_handle(sock_as_handle, ec)) + return ec; + + impl.socket_ = sock.release(); + impl.flags_ = 0; + impl.cancel_token_.reset(static_cast(0), noop_deleter()); + impl.protocol_ = protocol; + ec = asio::error_code(); + return ec; + } + + // Assign a native socket to a socket implementation. + asio::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + asio::error_code& ec) + { + if (is_open(impl)) + { + ec = asio::error::already_open; + return ec; + } + + if (iocp_service_.register_handle(native_socket.as_handle(), ec)) + return ec; + + impl.socket_ = native_socket; + impl.flags_ = 0; + impl.cancel_token_.reset(static_cast(0), noop_deleter()); + impl.protocol_ = protocol; + ec = asio::error_code(); + return ec; + } + + // Determine whether the socket is open. + bool is_open(const implementation_type& impl) const + { + return impl.socket_ != invalid_socket; + } + + // Destroy a socket implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + if (is_open(impl)) + { + // Check if the reactor was created, in which case we need to close the + // socket on the reactor as well to cancel any operations that might be + // running there. + reactor* r = static_cast( + interlocked_compare_exchange_pointer( + reinterpret_cast(&reactor_), 0, 0)); + if (r) + r->close_descriptor(impl.socket_, impl.reactor_data_); + + if (socket_ops::close(impl.socket_, ec) == socket_error_retval) + return ec; + + impl.socket_ = invalid_socket; + impl.flags_ = 0; + impl.cancel_token_.reset(); +#if defined(ASIO_ENABLE_CANCELIO) + impl.safe_cancellation_thread_id_ = 0; +#endif // defined(ASIO_ENABLE_CANCELIO) + } + + ec = asio::error_code(); + return ec; + } + + // Get the native socket representation. + native_type native(implementation_type& impl) + { + return impl.socket_; + } + + // Cancel all operations associated with the socket. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress( + ::GetModuleHandleA("KERNEL32"), "CancelIoEx")) + { + // The version of Windows supports cancellation from any thread. + typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED); + cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr; + socket_type sock = impl.socket_; + HANDLE sock_as_handle = reinterpret_cast(sock); + if (!cancel_io_ex(sock_as_handle, 0)) + { + DWORD last_error = ::GetLastError(); + if (last_error == ERROR_NOT_FOUND) + { + // ERROR_NOT_FOUND means that there were no operations to be + // cancelled. We swallow this error to match the behaviour on other + // platforms. + ec = asio::error_code(); + } + else + { + ec = asio::error_code(last_error, + asio::error::get_system_category()); + } + } + else + { + ec = asio::error_code(); + } + } +#if defined(ASIO_ENABLE_CANCELIO) + else if (impl.safe_cancellation_thread_id_ == 0) + { + // No operations have been started, so there's nothing to cancel. + ec = asio::error_code(); + } + else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId()) + { + // Asynchronous operations have been started from the current thread only, + // so it is safe to try to cancel them using CancelIo. + socket_type sock = impl.socket_; + HANDLE sock_as_handle = reinterpret_cast(sock); + if (!::CancelIo(sock_as_handle)) + { + DWORD last_error = ::GetLastError(); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + } + else + { + ec = asio::error_code(); + } + } + else + { + // Asynchronous operations have been started from more than one thread, + // so cancellation is not safe. + ec = asio::error::operation_not_supported; + } +#else // defined(ASIO_ENABLE_CANCELIO) + else + { + // Cancellation is not supported as CancelIo may not be used. + ec = asio::error::operation_not_supported; + } +#endif // defined(ASIO_ENABLE_CANCELIO) + + return ec; + } + + // Determine whether the socket is at the out-of-band data mark. + bool at_mark(const implementation_type& impl, + asio::error_code& ec) const + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return false; + } + + asio::detail::ioctl_arg_type value = 0; + socket_ops::ioctl(impl.socket_, SIOCATMARK, &value, ec); + return ec ? false : value != 0; + } + + // Determine the number of bytes available for reading. + std::size_t available(const implementation_type& impl, + asio::error_code& ec) const + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + asio::detail::ioctl_arg_type value = 0; + socket_ops::ioctl(impl.socket_, FIONREAD, &value, ec); + return ec ? static_cast(0) : static_cast(value); + } + + // Bind the socket to the specified local endpoint. + asio::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); + return ec; + } + + // Place the socket into the state where it will listen for new connections. + asio::error_code listen(implementation_type& impl, int backlog, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + socket_ops::listen(impl.socket_, backlog, ec); + return ec; + } + + // Set a socket option. + template + asio::error_code set_option(implementation_type& impl, + const Option& option, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + if (option.level(impl.protocol_) == custom_socket_option_level + && option.name(impl.protocol_) == enable_connection_aborted_option) + { + if (option.size(impl.protocol_) != sizeof(int)) + { + ec = asio::error::invalid_argument; + } + else + { + if (*reinterpret_cast(option.data(impl.protocol_))) + impl.flags_ |= implementation_type::enable_connection_aborted; + else + impl.flags_ &= ~implementation_type::enable_connection_aborted; + ec = asio::error_code(); + } + return ec; + } + else + { + if (option.level(impl.protocol_) == SOL_SOCKET + && option.name(impl.protocol_) == SO_LINGER) + { + const ::linger* linger_option = + reinterpret_cast(option.data(impl.protocol_)); + if (linger_option->l_onoff != 0 && linger_option->l_linger != 0) + impl.flags_ |= implementation_type::close_might_block; + else + impl.flags_ &= ~implementation_type::close_might_block; + } + + socket_ops::setsockopt(impl.socket_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), option.size(impl.protocol_), ec); + return ec; + } + } + + // Set a socket option. + template + asio::error_code get_option(const implementation_type& impl, + Option& option, asio::error_code& ec) const + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + if (option.level(impl.protocol_) == custom_socket_option_level + && option.name(impl.protocol_) == enable_connection_aborted_option) + { + if (option.size(impl.protocol_) != sizeof(int)) + { + ec = asio::error::invalid_argument; + } + else + { + int* target = reinterpret_cast(option.data(impl.protocol_)); + if (impl.flags_ & implementation_type::enable_connection_aborted) + *target = 1; + else + *target = 0; + option.resize(impl.protocol_, sizeof(int)); + ec = asio::error_code(); + } + return ec; + } + else + { + size_t size = option.size(impl.protocol_); + socket_ops::getsockopt(impl.socket_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), &size, ec); + if (!ec) + option.resize(impl.protocol_, size); + return ec; + } + } + + // Perform an IO control command on the socket. + template + asio::error_code io_control(implementation_type& impl, + IO_Control_Command& command, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + socket_ops::ioctl(impl.socket_, command.name(), + static_cast(command.data()), ec); + + if (!ec && command.name() == static_cast(FIONBIO)) + { + if (*static_cast(command.data())) + impl.flags_ |= implementation_type::user_set_non_blocking; + else + impl.flags_ &= ~implementation_type::user_set_non_blocking; + } + + return ec; + } + + // Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return endpoint_type(); + } + + endpoint_type endpoint; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + + // Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return endpoint_type(); + } + + if (impl.socket_.have_remote_endpoint()) + { + // Check if socket is still connected. + DWORD connect_time = 0; + size_t connect_time_len = sizeof(connect_time); + if (socket_ops::getsockopt(impl.socket_, SOL_SOCKET, SO_CONNECT_TIME, + &connect_time, &connect_time_len, ec) == socket_error_retval) + { + return endpoint_type(); + } + if (connect_time == 0xFFFFFFFF) + { + ec = asio::error::not_connected; + return endpoint_type(); + } + + ec = asio::error_code(); + return impl.socket_.remote_endpoint(); + } + else + { + endpoint_type endpoint; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + } + + /// Disable sends or receives on the socket. + asio::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + socket_ops::shutdown(impl.socket_, what, ec); + return ec; + } + + // Send the given data to the peer. Returns the number of bytes sent. + template + size_t send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + buffer_sequence_adapter bufs(buffers); + + // A request to receive 0 bytes on a stream socket is a no-op. + if (impl.protocol_.type() == SOCK_STREAM && bufs.all_empty()) + { + ec = asio::error_code(); + return 0; + } + + // Send the data. + DWORD bytes_transferred = 0; + int result = ::WSASend(impl.socket_, bufs.buffers(), + bufs.count(), &bytes_transferred, flags, 0, 0); + if (result != 0) + { + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_NETNAME_DELETED) + last_error = WSAECONNRESET; + else if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return 0; + } + + ec = asio::error_code(); + return bytes_transferred; + } + + // Wait until data can be sent without blocking. + size_t send(implementation_type& impl, const null_buffers&, + socket_base::message_flags, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + // Wait for socket to become ready. + socket_ops::poll_write(impl.socket_, ec); + + return 0; + } + + template + class send_op : public operation + { + public: + send_op(weak_cancel_token_type cancel_token, + const ConstBufferSequence& buffers, Handler handler) + : operation(&send_op::do_complete), + cancel_token_(cancel_token), + buffers_(buffers), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + send_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + buffer_sequence_adapter::validate(o->buffers_); +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_NETNAME_DELETED) + { + if (o->cancel_token_.expired()) + ec = asio::error::operation_aborted; + else + ec = asio::error::connection_reset; + } + else if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = asio::error::connection_refused; + } + + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, ec, bytes_transferred); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + weak_cancel_token_type cancel_token_; + ConstBufferSequence buffers_; + Handler handler_; + }; + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef send_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, + impl.cancel_token_, buffers, handler); + + buffer_sequence_adapter bufs(buffers); + + start_send_op(impl, bufs.buffers(), bufs.count(), flags, + impl.protocol_.type() == SOCK_STREAM && bufs.all_empty(), ptr.get()); + ptr.release(); + } + + // Start an asynchronous wait until data can be sent without blocking. + template + void async_send(implementation_type& impl, const null_buffers&, + socket_base::message_flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef null_buffers_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + start_reactor_op(impl, reactor::write_op, ptr.get()); + ptr.release(); + } + + // Send a datagram to the specified endpoint. Returns the number of bytes + // sent. + template + size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + buffer_sequence_adapter bufs(buffers); + + // Send the data. + DWORD bytes_transferred = 0; + int result = ::WSASendTo(impl.socket_, bufs.buffers(), bufs.count(), + &bytes_transferred, flags, destination.data(), + static_cast(destination.size()), 0, 0); + if (result != 0) + { + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return 0; + } + + ec = asio::error_code(); + return bytes_transferred; + } + + // Wait until data can be sent without blocking. + size_t send_to(implementation_type& impl, const null_buffers&, + socket_base::message_flags, const endpoint_type&, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + // Wait for socket to become ready. + socket_ops::poll_write(impl.socket_, ec); + + return 0; + } + + template + class send_to_op : public operation + { + public: + send_to_op(weak_cancel_token_type cancel_token, + const ConstBufferSequence& buffers, Handler handler) + : operation(&send_to_op::do_complete), + cancel_token_(cancel_token), + buffers_(buffers), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + send_to_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + buffer_sequence_adapter::validate(o->buffers_); +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = asio::error::connection_refused; + } + + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, ec, bytes_transferred); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + weak_cancel_token_type cancel_token_; + ConstBufferSequence buffers_; + Handler handler_; + }; + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send_to(implementation_type& impl, + const ConstBufferSequence& buffers, const endpoint_type& destination, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef send_to_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, + impl.cancel_token_, buffers, handler); + + buffer_sequence_adapter bufs(buffers); + + start_send_to_op(impl, bufs.buffers(), + bufs.count(), destination, flags, ptr.get()); + ptr.release(); + } + + // Start an asynchronous wait until data can be sent without blocking. + template + void async_send_to(implementation_type& impl, const null_buffers&, + socket_base::message_flags, const endpoint_type&, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef null_buffers_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + start_reactor_op(impl, reactor::write_op, ptr.get()); + ptr.release(); + } + + // Receive some data from the peer. Returns the number of bytes received. + template + size_t receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + buffer_sequence_adapter bufs(buffers); + + // A request to receive 0 bytes on a stream socket is a no-op. + if (impl.protocol_.type() == SOCK_STREAM && bufs.all_empty()) + { + ec = asio::error_code(); + return 0; + } + + // Receive some data. + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int result = ::WSARecv(impl.socket_, bufs.buffers(), + bufs.count(), &bytes_transferred, &recv_flags, 0, 0); + if (result != 0) + { + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_NETNAME_DELETED) + last_error = WSAECONNRESET; + else if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return 0; + } + if (bytes_transferred == 0 && impl.protocol_.type() == SOCK_STREAM) + { + ec = asio::error::eof; + return 0; + } + + ec = asio::error_code(); + return bytes_transferred; + } + + // Wait until data can be received without blocking. + size_t receive(implementation_type& impl, const null_buffers&, + socket_base::message_flags, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + // Wait for socket to become ready. + socket_ops::poll_read(impl.socket_, ec); + + return 0; + } + + template + class receive_op : public operation + { + public: + receive_op(int protocol_type, weak_cancel_token_type cancel_token, + const MutableBufferSequence& buffers, Handler handler) + : operation(&receive_op::do_complete), + protocol_type_(protocol_type), + cancel_token_(cancel_token), + buffers_(buffers), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + receive_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + buffer_sequence_adapter::validate(o->buffers_); +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_NETNAME_DELETED) + { + if (o->cancel_token_.expired()) + ec = asio::error::operation_aborted; + else + ec = asio::error::connection_reset; + } + else if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = asio::error::connection_refused; + } + + // Check for connection closed. + else if (!ec && bytes_transferred == 0 + && o->protocol_type_ == SOCK_STREAM + && !buffer_sequence_adapter::all_empty(o->buffers_) + && !boost::is_same::value) + { + ec = asio::error::eof; + } + + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, ec, bytes_transferred); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + int protocol_type_; + weak_cancel_token_type cancel_token_; + MutableBufferSequence buffers_; + Handler handler_; + }; + + // Start an asynchronous receive. The buffer for the data being received + // must be valid for the lifetime of the asynchronous operation. + template + void async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef receive_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + int protocol_type = impl.protocol_.type(); + handler_ptr ptr(raw_ptr, protocol_type, + impl.cancel_token_, buffers, handler); + + buffer_sequence_adapter bufs(buffers); + + start_receive_op(impl, bufs.buffers(), bufs.count(), flags, + protocol_type == SOCK_STREAM && bufs.all_empty(), ptr.get()); + ptr.release(); + } + + // Wait until data can be received without blocking. + template + void async_receive(implementation_type& impl, const null_buffers& buffers, + socket_base::message_flags flags, Handler handler) + { + if (impl.protocol_.type() == SOCK_STREAM) + { + // For stream sockets on Windows, we may issue a 0-byte overlapped + // WSARecv to wait until there is data available on the socket. + + // Allocate and construct an operation to wrap the handler. + typedef receive_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + int protocol_type = impl.protocol_.type(); + handler_ptr ptr(raw_ptr, protocol_type, + impl.cancel_token_, buffers, handler); + + ::WSABUF buf = { 0, 0 }; + start_receive_op(impl, &buf, 1, flags, false, ptr.get()); + ptr.release(); + } + else + { + // Allocate and construct an operation to wrap the handler. + typedef null_buffers_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + start_reactor_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + ptr.get()); + ptr.release(); + } + } + + // Receive a datagram with the endpoint of the sender. Returns the number of + // bytes received. + template + size_t receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + buffer_sequence_adapter bufs(buffers); + + // Receive some data. + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int endpoint_size = static_cast(sender_endpoint.capacity()); + int result = ::WSARecvFrom(impl.socket_, bufs.buffers(), + bufs.count(), &bytes_transferred, &recv_flags, + sender_endpoint.data(), &endpoint_size, 0, 0); + if (result != 0) + { + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + ec = asio::error_code(last_error, + asio::error::get_system_category()); + return 0; + } + if (bytes_transferred == 0 && impl.protocol_.type() == SOCK_STREAM) + { + ec = asio::error::eof; + return 0; + } + + sender_endpoint.resize(static_cast(endpoint_size)); + + ec = asio::error_code(); + return bytes_transferred; + } + + // Wait until data can be received without blocking. + size_t receive_from(implementation_type& impl, + const null_buffers&, endpoint_type& sender_endpoint, + socket_base::message_flags, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return 0; + } + + // Wait for socket to become ready. + socket_ops::poll_read(impl.socket_, ec); + + // Reset endpoint since it can be given no sensible value at this time. + sender_endpoint = endpoint_type(); + + return 0; + } + + template + class receive_from_op : public operation + { + public: + receive_from_op(int protocol_type, endpoint_type& endpoint, + const MutableBufferSequence& buffers, Handler handler) + : operation(&receive_from_op::do_complete), + protocol_type_(protocol_type), + endpoint_(endpoint), + endpoint_size_(static_cast(endpoint.capacity())), + buffers_(buffers), + handler_(handler) + { + } + + int& endpoint_size() + { + return endpoint_size_; + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + receive_from_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + buffer_sequence_adapter::validate(o->buffers_); +#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING) + + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = asio::error::connection_refused; + } + + // Record the size of the endpoint returned by the operation. + o->endpoint_.resize(o->endpoint_size_); + + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2 + handler(o->handler_, ec, bytes_transferred); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + int protocol_type_; + endpoint_type& endpoint_; + int endpoint_size_; + weak_cancel_token_type cancel_token_; + MutableBufferSequence buffers_; + Handler handler_; + }; + + // Start an asynchronous receive. The buffer for the data being received and + // the sender_endpoint object must both be valid for the lifetime of the + // asynchronous operation. + template + void async_receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endp, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef receive_from_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + int protocol_type = impl.protocol_.type(); + handler_ptr ptr(raw_ptr, + protocol_type, sender_endp, buffers, handler); + + buffer_sequence_adapter bufs(buffers); + + start_receive_from_op(impl, bufs.buffers(), bufs.count(), + sender_endp, flags, &ptr.get()->endpoint_size(), ptr.get()); + ptr.release(); + } + + // Wait until data can be received without blocking. + template + void async_receive_from(implementation_type& impl, + const null_buffers&, endpoint_type& sender_endpoint, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef null_buffers_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, handler); + + // Reset endpoint since it can be given no sensible value at this time. + sender_endpoint = endpoint_type(); + + start_reactor_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + ptr.get()); + ptr.release(); + } + + // Accept a new connection. + template + asio::error_code accept(implementation_type& impl, Socket& peer, + endpoint_type* peer_endpoint, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + // We cannot accept a socket that is already open. + if (peer.is_open()) + { + ec = asio::error::already_open; + return ec; + } + + for (;;) + { + socket_holder new_socket; + std::size_t addr_len = 0; + if (peer_endpoint) + { + addr_len = peer_endpoint->capacity(); + new_socket.reset(socket_ops::accept(impl.socket_, + peer_endpoint->data(), &addr_len, ec)); + } + else + { + new_socket.reset(socket_ops::accept(impl.socket_, 0, 0, ec)); + } + + if (ec) + { + if (ec == asio::error::connection_aborted + && !(impl.flags_ & implementation_type::enable_connection_aborted)) + { + // Retry accept operation. + continue; + } + else + { + return ec; + } + } + + if (peer_endpoint) + peer_endpoint->resize(addr_len); + + peer.assign(impl.protocol_, new_socket.get(), ec); + if (!ec) + new_socket.release(); + return ec; + } + } + + template + class accept_op : public operation + { + public: + accept_op(win_iocp_io_service& iocp_service, socket_type socket, + Socket& peer, const protocol_type& protocol, + endpoint_type* peer_endpoint, bool enable_connection_aborted, + Handler handler) + : operation(&accept_op::do_complete), + iocp_service_(iocp_service), + socket_(socket), + peer_(peer), + protocol_(protocol), + peer_endpoint_(peer_endpoint), + enable_connection_aborted_(enable_connection_aborted), + handler_(handler) + { + } + + socket_holder& new_socket() + { + return new_socket_; + } + + void* output_buffer() + { + return output_buffer_; + } + + DWORD address_length() + { + return sizeof(sockaddr_storage_type) + 16; + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code ec, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + accept_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Map Windows error ERROR_NETNAME_DELETED to connection_aborted. + if (ec.value() == ERROR_NETNAME_DELETED) + { + ec = asio::error::connection_aborted; + } + + // Restart the accept operation if we got the connection_aborted error + // and the enable_connection_aborted socket option is not set. + if (ec == asio::error::connection_aborted + && !o->enable_connection_aborted_) + { + // Reset OVERLAPPED structure. + o->reset(); + + // Create a new socket for the next connection, since the AcceptEx + // call fails with WSAEINVAL if we try to reuse the same socket. + o->new_socket_.reset(); + o->new_socket_.reset(socket_ops::socket(o->protocol_.family(), + o->protocol_.type(), o->protocol_.protocol(), ec)); + if (o->new_socket_.get() != invalid_socket) + { + // Accept a connection. + DWORD bytes_read = 0; + BOOL result = ::AcceptEx(o->socket_, o->new_socket_.get(), + o->output_buffer(), 0, o->address_length(), + o->address_length(), &bytes_read, o); + DWORD last_error = ::WSAGetLastError(); + ec = asio::error_code(last_error, + asio::error::get_system_category()); + + // Check if the operation completed immediately. + if (!result && last_error != WSA_IO_PENDING) + { + if (last_error == ERROR_NETNAME_DELETED + || last_error == WSAECONNABORTED) + { + // Post this handler so that operation will be restarted again. + o->iocp_service_.work_started(); + o->iocp_service_.on_completion(o, ec); + ptr.release(); + return; + } + else + { + // Operation already complete. Continue with rest of this + // handler. + } + } + else + { + // Asynchronous operation has been successfully restarted. + o->iocp_service_.work_started(); + o->iocp_service_.on_pending(o); + ptr.release(); + return; + } + } + } + + // Get the address of the peer. + endpoint_type peer_endpoint; + if (!ec) + { + LPSOCKADDR local_addr = 0; + int local_addr_length = 0; + LPSOCKADDR remote_addr = 0; + int remote_addr_length = 0; + GetAcceptExSockaddrs(o->output_buffer(), 0, o->address_length(), + o->address_length(), &local_addr, &local_addr_length, + &remote_addr, &remote_addr_length); + if (static_cast(remote_addr_length) + > peer_endpoint.capacity()) + { + ec = asio::error::invalid_argument; + } + else + { + using namespace std; // For memcpy. + memcpy(peer_endpoint.data(), remote_addr, remote_addr_length); + peer_endpoint.resize(static_cast(remote_addr_length)); + } + } + + // Need to set the SO_UPDATE_ACCEPT_CONTEXT option so that getsockname + // and getpeername will work on the accepted socket. + if (!ec) + { + SOCKET update_ctx_param = o->socket_; + socket_ops::setsockopt(o->new_socket_.get(), + SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, + &update_ctx_param, sizeof(SOCKET), ec); + } + + // If the socket was successfully accepted, transfer ownership of the + // socket to the peer object. + if (!ec) + { + o->peer_.assign(o->protocol_, + native_type(o->new_socket_.get(), peer_endpoint), ec); + if (!ec) + o->new_socket_.release(); + } + + // Pass endpoint back to caller. + if (o->peer_endpoint_) + *o->peer_endpoint_ = peer_endpoint; + + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder1 + handler(o->handler_, ec); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + win_iocp_io_service& iocp_service_; + socket_type socket_; + socket_holder new_socket_; + Socket& peer_; + protocol_type protocol_; + endpoint_type* peer_endpoint_; + unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2]; + bool enable_connection_aborted_; + Handler handler_; + }; + + // Start an asynchronous accept. The peer and peer_endpoint objects + // must be valid until the accept's handler is invoked. + template + void async_accept(implementation_type& impl, Socket& peer, + endpoint_type* peer_endpoint, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef accept_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + bool enable_connection_aborted = + (impl.flags_ & implementation_type::enable_connection_aborted); + handler_ptr ptr(raw_ptr, iocp_service_, impl.socket_, peer, + impl.protocol_, peer_endpoint, enable_connection_aborted, handler); + + start_accept_op(impl, peer.is_open(), ptr.get()->new_socket(), + ptr.get()->output_buffer(), ptr.get()->address_length(), ptr.get()); + ptr.release(); + } + + // Connect the socket to the specified endpoint. + asio::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, asio::error_code& ec) + { + if (!is_open(impl)) + { + ec = asio::error::bad_descriptor; + return ec; + } + + // Perform the connect operation. + socket_ops::connect(impl.socket_, + peer_endpoint.data(), peer_endpoint.size(), ec); + return ec; + } + + class connect_op_base : public reactor_op + { + public: + connect_op_base(socket_type socket, func_type complete_func) + : reactor_op(&connect_op_base::do_perform, complete_func), + socket_(socket) + { + } + + static bool do_perform(reactor_op* base) + { + connect_op_base* o(static_cast(base)); + + // Get the error code from the connect operation. + int connect_error = 0; + size_t connect_error_len = sizeof(connect_error); + if (socket_ops::getsockopt(o->socket_, SOL_SOCKET, SO_ERROR, + &connect_error, &connect_error_len, o->ec_) == socket_error_retval) + return true; + + // The connection failed so the handler will be posted with an error code. + if (connect_error) + { + o->ec_ = asio::error_code(connect_error, + asio::error::get_system_category()); + } + + return true; + } + + private: + socket_type socket_; + }; + + template + class connect_op : public connect_op_base + { + public: + connect_op(socket_type socket, Handler handler) + : connect_op_base(socket, &connect_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + asio::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + connect_op* o(static_cast(base)); + typedef handler_alloc_traits alloc_traits; + handler_ptr ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder1 + handler(o->handler_, o->ec_); + ptr.reset(); + asio::detail::fenced_block b; + asio_handler_invoke_helpers::invoke(handler, handler); + } + } + + private: + Handler handler_; + }; + + // Start an asynchronous connect. + template + void async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef connect_op value_type; + typedef handler_alloc_traits alloc_traits; + raw_handler_ptr raw_ptr(handler); + handler_ptr ptr(raw_ptr, impl.socket_, handler); + + start_connect_op(impl, ptr.get(), peer_endpoint); + ptr.release(); + } + +private: + // Helper function to start an asynchronous send operation. + void start_send_op(implementation_type& impl, WSABUF* buffers, + std::size_t buffer_count, socket_base::message_flags flags, + bool noop, operation* op) + { + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (noop) + iocp_service_.on_completion(op); + else if (!is_open(impl)) + iocp_service_.on_completion(op, asio::error::bad_descriptor); + else + { + DWORD bytes_transferred = 0; + int result = ::WSASend(impl.socket_, buffers, + buffer_count, &bytes_transferred, flags, op, 0); + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + if (result != 0 && last_error != WSA_IO_PENDING) + iocp_service_.on_completion(op, last_error, bytes_transferred); + else + iocp_service_.on_pending(op); + } + } + + // Helper function to start an asynchronous send_to operation. + void start_send_to_op(implementation_type& impl, WSABUF* buffers, + std::size_t buffer_count, const endpoint_type& destination, + socket_base::message_flags flags, operation* op) + { + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (!is_open(impl)) + iocp_service_.on_completion(op, asio::error::bad_descriptor); + else + { + DWORD bytes_transferred = 0; + int result = ::WSASendTo(impl.socket_, buffers, buffer_count, + &bytes_transferred, flags, destination.data(), + static_cast(destination.size()), op, 0); + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + if (result != 0 && last_error != WSA_IO_PENDING) + iocp_service_.on_completion(op, last_error, bytes_transferred); + else + iocp_service_.on_pending(op); + } + } + + // Helper function to start an asynchronous receive operation. + void start_receive_op(implementation_type& impl, WSABUF* buffers, + std::size_t buffer_count, socket_base::message_flags flags, + bool noop, operation* op) + { + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (noop) + iocp_service_.on_completion(op); + else if (!is_open(impl)) + iocp_service_.on_completion(op, asio::error::bad_descriptor); + else + { + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int result = ::WSARecv(impl.socket_, buffers, buffer_count, + &bytes_transferred, &recv_flags, op, 0); + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_NETNAME_DELETED) + last_error = WSAECONNRESET; + else if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + if (result != 0 && last_error != WSA_IO_PENDING) + iocp_service_.on_completion(op, last_error, bytes_transferred); + else + iocp_service_.on_pending(op); + } + } + + // Helper function to start an asynchronous receive_from operation. + void start_receive_from_op(implementation_type& impl, WSABUF* buffers, + std::size_t buffer_count, endpoint_type& sender_endpoint, + socket_base::message_flags flags, int* endpoint_size, operation* op) + { + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (!is_open(impl)) + iocp_service_.on_completion(op, asio::error::bad_descriptor); + else + { + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int result = ::WSARecvFrom(impl.socket_, buffers, + buffer_count, &bytes_transferred, &recv_flags, + sender_endpoint.data(), endpoint_size, op, 0); + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + if (result != 0 && last_error != WSA_IO_PENDING) + iocp_service_.on_completion(op, last_error, bytes_transferred); + else + iocp_service_.on_pending(op); + } + } + + // Helper function to start an asynchronous receive_from operation. + void start_accept_op(implementation_type& impl, + bool peer_is_open, socket_holder& new_socket, + void* output_buffer, DWORD address_length, operation* op) + { + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (!is_open(impl)) + iocp_service_.on_completion(op, asio::error::bad_descriptor); + else if (peer_is_open) + iocp_service_.on_completion(op, asio::error::already_open); + else + { + asio::error_code ec; + new_socket.reset(socket_ops::socket(impl.protocol_.family(), + impl.protocol_.type(), impl.protocol_.protocol(), ec)); + if (new_socket.get() == invalid_socket) + iocp_service_.on_completion(op, ec); + else + { + DWORD bytes_read = 0; + BOOL result = ::AcceptEx(impl.socket_, new_socket.get(), output_buffer, + 0, address_length, address_length, &bytes_read, op); + DWORD last_error = ::WSAGetLastError(); + if (!result && last_error != WSA_IO_PENDING) + iocp_service_.on_completion(op, last_error); + else + iocp_service_.on_pending(op); + } + } + } + + // Start an asynchronous read or write operation using the the reactor. + void start_reactor_op(implementation_type& impl, int op_type, reactor_op* op) + { + reactor& r = get_reactor(); + update_cancellation_thread_id(impl); + + if (is_open(impl)) + { + r.start_op(op_type, impl.socket_, impl.reactor_data_, op, false); + return; + } + else + op->ec_ = asio::error::bad_descriptor; + + iocp_service_.post_immediate_completion(op); + } + + // Start the asynchronous connect operation using the reactor. + void start_connect_op(implementation_type& impl, + reactor_op* op, const endpoint_type& peer_endpoint) + { + reactor& r = get_reactor(); + update_cancellation_thread_id(impl); + + if (is_open(impl)) + { + ioctl_arg_type non_blocking = 1; + if (!socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, op->ec_)) + { + if (socket_ops::connect(impl.socket_, peer_endpoint.data(), + peer_endpoint.size(), op->ec_) != 0) + { + if (!op->ec_ + && !(impl.flags_ & implementation_type::user_set_non_blocking)) + { + non_blocking = 0; + socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, op->ec_); + } + + if (op->ec_ == asio::error::in_progress + || op->ec_ == asio::error::would_block) + { + op->ec_ = asio::error_code(); + r.start_op(reactor::connect_op, impl.socket_, + impl.reactor_data_, op, true); + return; + } + } + } + } + else + op->ec_ = asio::error::bad_descriptor; + + iocp_service_.post_immediate_completion(op); + } + + // Helper function to close a socket when the associated object is being + // destroyed. + void close_for_destruction(implementation_type& impl) + { + if (is_open(impl)) + { + // Check if the reactor was created, in which case we need to close the + // socket on the reactor as well to cancel any operations that might be + // running there. + reactor* r = static_cast( + interlocked_compare_exchange_pointer( + reinterpret_cast(&reactor_), 0, 0)); + if (r) + r->close_descriptor(impl.socket_, impl.reactor_data_); + + // The socket destructor must not block. If the user has changed the + // linger option to block in the foreground, we will change it back to the + // default so that the closure is performed in the background. + if (impl.flags_ & implementation_type::close_might_block) + { + ::linger opt; + opt.l_onoff = 0; + opt.l_linger = 0; + asio::error_code ignored_ec; + socket_ops::setsockopt(impl.socket_, + SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec); + } + + asio::error_code ignored_ec; + socket_ops::close(impl.socket_, ignored_ec); + impl.socket_ = invalid_socket; + impl.flags_ = 0; + impl.cancel_token_.reset(); +#if defined(ASIO_ENABLE_CANCELIO) + impl.safe_cancellation_thread_id_ = 0; +#endif // defined(ASIO_ENABLE_CANCELIO) + } + } + + // Update the ID of the thread from which cancellation is safe. + void update_cancellation_thread_id(implementation_type& impl) + { +#if defined(ASIO_ENABLE_CANCELIO) + if (impl.safe_cancellation_thread_id_ == 0) + impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); + else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) + impl.safe_cancellation_thread_id_ = ~DWORD(0); +#else // defined(ASIO_ENABLE_CANCELIO) + (void)impl; +#endif // defined(ASIO_ENABLE_CANCELIO) + } + + // Helper function to get the reactor. If no reactor has been created yet, a + // new one is obtained from the io_service and a pointer to it is cached in + // this service. + reactor& get_reactor() + { + reactor* r = static_cast( + interlocked_compare_exchange_pointer( + reinterpret_cast(&reactor_), 0, 0)); + if (!r) + { + r = &(use_service(io_service_)); + interlocked_exchange_pointer(reinterpret_cast(&reactor_), r); + } + return *r; + } + + // Helper function to emulate InterlockedCompareExchangePointer functionality + // for: + // - very old Platform SDKs; and + // - platform SDKs where MSVC's /Wp64 option causes spurious warnings. + void* interlocked_compare_exchange_pointer(void** dest, void* exch, void* cmp) + { +#if defined(_M_IX86) + return reinterpret_cast(InterlockedCompareExchange( + reinterpret_cast(dest), reinterpret_cast(exch), + reinterpret_cast(cmp))); +#else + return InterlockedCompareExchangePointer(dest, exch, cmp); +#endif + } + + // Helper function to emulate InterlockedExchangePointer functionality for: + // - very old Platform SDKs; and + // - platform SDKs where MSVC's /Wp64 option causes spurious warnings. + void* interlocked_exchange_pointer(void** dest, void* val) + { +#if defined(_M_IX86) + return reinterpret_cast(InterlockedExchange( + reinterpret_cast(dest), reinterpret_cast(val))); +#else + return InterlockedExchangePointer(dest, val); +#endif + } + + // The io_service used to obtain the reactor, if required. + asio::io_service& io_service_; + + // The IOCP service used for running asynchronous operations and dispatching + // handlers. + win_iocp_io_service& iocp_service_; + + // The reactor used for performing connect operations. This object is created + // only if needed. + reactor* reactor_; + + // Mutex to protect access to the linked list of implementations. + asio::detail::mutex mutex_; + + // The head of a linked list of all implementations. + implementation_type* impl_list_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(ASIO_HAS_IOCP) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_mutex.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_mutex.hpp new file mode 100644 index 00000000..1280a4e4 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_mutex.hpp @@ -0,0 +1,121 @@ +// +// win_mutex.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_MUTEX_HPP +#define ASIO_DETAIL_WIN_MUTEX_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_WINDOWS) + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/scoped_lock.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +class win_mutex + : private noncopyable +{ +public: + typedef asio::detail::scoped_lock scoped_lock; + + // Constructor. + win_mutex() + { + int error = do_init(); + if (error != 0) + { + asio::system_error e( + asio::error_code(error, + asio::error::get_system_category()), + "mutex"); + boost::throw_exception(e); + } + } + + // Destructor. + ~win_mutex() + { + ::DeleteCriticalSection(&crit_section_); + } + + // Lock the mutex. + void lock() + { + ::EnterCriticalSection(&crit_section_); + } + + // Unlock the mutex. + void unlock() + { + ::LeaveCriticalSection(&crit_section_); + } + +private: + // Initialisation must be performed in a separate function to the constructor + // since the compiler does not support the use of structured exceptions and + // C++ exceptions in the same function. + int do_init() + { +#if defined(__MINGW32__) + // Not sure if MinGW supports structured exception handling, so for now + // we'll just call the Windows API and hope. +# if defined(UNDER_CE) + ::InitializeCriticalSection(&crit_section_); +# else + ::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000); +# endif + return 0; +#else + __try + { +# if defined(UNDER_CE) + ::InitializeCriticalSection(&crit_section_); +# else + ::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000); +# endif + } + __except(GetExceptionCode() == STATUS_NO_MEMORY + ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { + return ERROR_OUTOFMEMORY; + } + + return 0; +#endif + } + + ::CRITICAL_SECTION crit_section_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_WINDOWS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_MUTEX_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_signal_blocker.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_signal_blocker.hpp new file mode 100644 index 00000000..50d16b8a --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_signal_blocker.hpp @@ -0,0 +1,67 @@ +// +// win_signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_SIGNAL_BLOCKER_HPP +#define ASIO_DETAIL_WIN_SIGNAL_BLOCKER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include "asio/detail/noncopyable.hpp" + +namespace asio { +namespace detail { + +class win_signal_blocker + : private noncopyable +{ +public: + // Constructor blocks all signals for the calling thread. + win_signal_blocker() + { + // No-op. + } + + // Destructor restores the previous signal mask. + ~win_signal_blocker() + { + // No-op. + } + + // Block all signals for the calling thread. + void block() + { + // No-op. + } + + // Restore the previous signal mask. + void unblock() + { + // No-op. + } +}; + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_SIGNAL_BLOCKER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_thread.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_thread.hpp new file mode 100644 index 00000000..9bf0665c --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_thread.hpp @@ -0,0 +1,232 @@ +// +// win_thread.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_THREAD_HPP +#define ASIO_DETAIL_WIN_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_WINDOWS) && !defined(UNDER_CE) + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +unsigned int __stdcall win_thread_function(void* arg); + +#if defined(WINVER) && (WINVER < 0x0500) +void __stdcall apc_function(ULONG data); +#else +void __stdcall apc_function(ULONG_PTR data); +#endif + +template +class win_thread_base +{ +public: + static bool terminate_threads() + { + return ::InterlockedExchangeAdd(&terminate_threads_, 0) != 0; + } + + static void set_terminate_threads(bool b) + { + ::InterlockedExchange(&terminate_threads_, b ? 1 : 0); + } + +private: + static long terminate_threads_; +}; + +template +long win_thread_base::terminate_threads_ = 0; + +class win_thread + : private noncopyable, + public win_thread_base +{ +public: + // Constructor. + template + win_thread(Function f) + : exit_event_(0) + { + std::auto_ptr arg(new func(f)); + + ::HANDLE entry_event = 0; + arg->entry_event_ = entry_event = ::CreateEvent(0, true, false, 0); + if (!entry_event) + { + DWORD last_error = ::GetLastError(); + asio::system_error e( + asio::error_code(last_error, + asio::error::get_system_category()), + "thread.entry_event"); + boost::throw_exception(e); + } + + arg->exit_event_ = exit_event_ = ::CreateEvent(0, true, false, 0); + if (!exit_event_) + { + DWORD last_error = ::GetLastError(); + ::CloseHandle(entry_event); + asio::system_error e( + asio::error_code(last_error, + asio::error::get_system_category()), + "thread.exit_event"); + boost::throw_exception(e); + } + + unsigned int thread_id = 0; + thread_ = reinterpret_cast(::_beginthreadex(0, 0, + win_thread_function, arg.get(), 0, &thread_id)); + if (!thread_) + { + DWORD last_error = ::GetLastError(); + if (entry_event) + ::CloseHandle(entry_event); + if (exit_event_) + ::CloseHandle(exit_event_); + asio::system_error e( + asio::error_code(last_error, + asio::error::get_system_category()), + "thread"); + boost::throw_exception(e); + } + arg.release(); + + if (entry_event) + { + ::WaitForSingleObject(entry_event, INFINITE); + ::CloseHandle(entry_event); + } + } + + // Destructor. + ~win_thread() + { + ::CloseHandle(thread_); + + // The exit_event_ handle is deliberately allowed to leak here since it + // is an error for the owner of an internal thread not to join() it. + } + + // Wait for the thread to exit. + void join() + { + ::WaitForSingleObject(exit_event_, INFINITE); + ::CloseHandle(exit_event_); + if (terminate_threads()) + { + ::TerminateThread(thread_, 0); + } + else + { + ::QueueUserAPC(apc_function, thread_, 0); + ::WaitForSingleObject(thread_, INFINITE); + } + } + +private: + friend unsigned int __stdcall win_thread_function(void* arg); + +#if defined(WINVER) && (WINVER < 0x0500) + friend void __stdcall apc_function(ULONG); +#else + friend void __stdcall apc_function(ULONG_PTR); +#endif + + class func_base + { + public: + virtual ~func_base() {} + virtual void run() = 0; + ::HANDLE entry_event_; + ::HANDLE exit_event_; + }; + + template + class func + : public func_base + { + public: + func(Function f) + : f_(f) + { + } + + virtual void run() + { + f_(); + } + + private: + Function f_; + }; + + ::HANDLE thread_; + ::HANDLE exit_event_; +}; + +inline unsigned int __stdcall win_thread_function(void* arg) +{ + std::auto_ptr func( + static_cast(arg)); + + ::SetEvent(func->entry_event_); + + func->run(); + + // Signal that the thread has finished its work, but rather than returning go + // to sleep to put the thread into a well known state. If the thread is being + // joined during global object destruction then it may be killed using + // TerminateThread (to avoid a deadlock in DllMain). Otherwise, the SleepEx + // call will be interrupted using QueueUserAPC and the thread will shut down + // cleanly. + HANDLE exit_event = func->exit_event_; + func.reset(); + ::SetEvent(exit_event); + ::SleepEx(INFINITE, TRUE); + + return 0; +} + +#if defined(WINVER) && (WINVER < 0x0500) +inline void __stdcall apc_function(ULONG) {} +#else +inline void __stdcall apc_function(ULONG_PTR) {} +#endif + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_THREAD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/win_tss_ptr.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/win_tss_ptr.hpp new file mode 100644 index 00000000..5a4ed33c --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/win_tss_ptr.hpp @@ -0,0 +1,95 @@ +// +// win_tss_ptr.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WIN_TSS_PTR_HPP +#define ASIO_DETAIL_WIN_TSS_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_WINDOWS) + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +template +class win_tss_ptr + : private noncopyable +{ +public: +#if defined(UNDER_CE) + enum { out_of_indexes = 0xFFFFFFFF }; +#else + enum { out_of_indexes = TLS_OUT_OF_INDEXES }; +#endif + + // Constructor. + win_tss_ptr() + { + tss_key_ = ::TlsAlloc(); + if (tss_key_ == out_of_indexes) + { + DWORD last_error = ::GetLastError(); + asio::system_error e( + asio::error_code(last_error, + asio::error::get_system_category()), + "tss"); + boost::throw_exception(e); + } + } + + // Destructor. + ~win_tss_ptr() + { + ::TlsFree(tss_key_); + } + + // Get the value. + operator T*() const + { + return static_cast(::TlsGetValue(tss_key_)); + } + + // Set the value. + void operator=(T* value) + { + ::TlsSetValue(tss_key_, value); + } + +private: + // Thread-specific storage to allow unlocked access to determine whether a + // thread is a member of the pool. + DWORD tss_key_; +}; + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_WINDOWS) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WIN_TSS_PTR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/wince_thread.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/wince_thread.hpp new file mode 100644 index 00000000..0b6de488 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/wince_thread.hpp @@ -0,0 +1,124 @@ +// +// wince_thread.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WINCE_THREAD_HPP +#define ASIO_DETAIL_WINCE_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_WINDOWS) && defined(UNDER_CE) + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace detail { + +DWORD WINAPI wince_thread_function(LPVOID arg); + +class wince_thread + : private noncopyable +{ +public: + // Constructor. + template + wince_thread(Function f) + { + std::auto_ptr arg(new func(f)); + DWORD thread_id = 0; + thread_ = ::CreateThread(0, 0, wince_thread_function, + arg.get(), 0, &thread_id); + if (!thread_) + { + DWORD last_error = ::GetLastError(); + asio::system_error e( + asio::error_code(last_error, + asio::error::get_system_category()), + "thread"); + boost::throw_exception(e); + } + arg.release(); + } + + // Destructor. + ~wince_thread() + { + ::CloseHandle(thread_); + } + + // Wait for the thread to exit. + void join() + { + ::WaitForSingleObject(thread_, INFINITE); + } + +private: + friend DWORD WINAPI wince_thread_function(LPVOID arg); + + class func_base + { + public: + virtual ~func_base() {} + virtual void run() = 0; + }; + + template + class func + : public func_base + { + public: + func(Function f) + : f_(f) + { + } + + virtual void run() + { + f_(); + } + + private: + Function f_; + }; + + ::HANDLE thread_; +}; + +inline DWORD WINAPI wince_thread_function(LPVOID arg) +{ + std::auto_ptr func( + static_cast(arg)); + func->run(); + return 0; +} + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_WINDOWS) && defined(UNDER_CE) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WINCE_THREAD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/winsock_init.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/winsock_init.hpp new file mode 100644 index 00000000..ae5c4bf5 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/winsock_init.hpp @@ -0,0 +1,120 @@ +// +// winsock_init.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WINSOCK_INIT_HPP +#define ASIO_DETAIL_WINSOCK_INIT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace detail { + +template +class winsock_init + : private noncopyable +{ +private: + // Structure to perform the actual initialisation. + struct do_init + { + do_init() + { + WSADATA wsa_data; + result_ = ::WSAStartup(MAKEWORD(Major, Minor), &wsa_data); + } + + ~do_init() + { + ::WSACleanup(); + } + + int result() const + { + return result_; + } + + // Helper function to manage a do_init singleton. The static instance of the + // winsock_init object ensures that this function is always called before + // main, and therefore before any other threads can get started. The do_init + // instance must be static in this function to ensure that it gets + // initialised before any other global objects try to use it. + static boost::shared_ptr instance() + { + static boost::shared_ptr init(new do_init); + return init; + } + + private: + int result_; + }; + +public: + // Constructor. + winsock_init() + : ref_(do_init::instance()) + { + // Check whether winsock was successfully initialised. This check is not + // performed for the global instance since there will be nobody around to + // catch the exception. + if (this != &instance_ && ref_->result() != 0) + { + asio::system_error e( + asio::error_code(ref_->result(), + asio::error::get_system_category()), + "winsock"); + boost::throw_exception(e); + } + } + + // Destructor. + ~winsock_init() + { + } + +private: + // Instance to force initialisation of winsock at global scope. + static winsock_init instance_; + + // Reference to singleton do_init object to ensure that winsock does not get + // cleaned up until the last user has finished with it. + boost::shared_ptr ref_; +}; + +template +winsock_init winsock_init::instance_; + +} // namespace detail +} // namespace asio + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WINSOCK_INIT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/detail/wrapped_handler.hpp b/src/libs/resiprocate/contrib/asio/asio/detail/wrapped_handler.hpp new file mode 100644 index 00000000..e40a7f15 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/detail/wrapped_handler.hpp @@ -0,0 +1,209 @@ +// +// wrapped_handler.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_DETAIL_WRAPPED_HANDLER_HPP +#define ASIO_DETAIL_WRAPPED_HANDLER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" + +namespace asio { +namespace detail { + +template +class wrapped_handler +{ +public: + typedef void result_type; + + wrapped_handler( + typename boost::add_reference::type dispatcher, + Handler handler) + : dispatcher_(dispatcher), + handler_(handler) + { + } + + void operator()() + { + dispatcher_.dispatch(handler_); + } + + void operator()() const + { + dispatcher_.dispatch(handler_); + } + + template + void operator()(const Arg1& arg1) + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1)); + } + + template + void operator()(const Arg1& arg1) const + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2) + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2) const + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) const + { + dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, + const Arg4& arg4) + { + dispatcher_.dispatch( + detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, + const Arg4& arg4) const + { + dispatcher_.dispatch( + detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, + const Arg4& arg4, const Arg5& arg5) + { + dispatcher_.dispatch( + detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); + } + + template + void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, + const Arg4& arg4, const Arg5& arg5) const + { + dispatcher_.dispatch( + detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); + } + +//private: + Dispatcher dispatcher_; + Handler handler_; +}; + +template +class rewrapped_handler +{ +public: + explicit rewrapped_handler(const Handler& handler, const Context& context) + : handler_(handler), + context_(context) + { + } + + void operator()() + { + handler_(); + } + + void operator()() const + { + handler_(); + } + +//private: + Handler handler_; + Context context_; +}; + +template +inline void* asio_handler_allocate(std::size_t size, + wrapped_handler* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + wrapped_handler* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +} + +template +inline void asio_handler_invoke(const Function& function, + wrapped_handler* this_handler) +{ + this_handler->dispatcher_.dispatch( + rewrapped_handler( + function, this_handler->handler_)); +} + +template +inline void* asio_handler_allocate(std::size_t size, + rewrapped_handler* this_handler) +{ + return asio_handler_alloc_helpers::allocate( + size, this_handler->context_); +} + +template +inline void asio_handler_deallocate(void* pointer, std::size_t size, + rewrapped_handler* this_handler) +{ + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->context_); +} + +template +inline void asio_handler_invoke(const Function& function, + rewrapped_handler* this_handler) +{ + asio_handler_invoke_helpers::invoke( + function, this_handler->context_); +} + +} // namespace detail +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_DETAIL_WRAPPED_HANDLER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/error.hpp b/src/libs/resiprocate/contrib/asio/asio/error.hpp new file mode 100644 index 00000000..73caac6a --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/error.hpp @@ -0,0 +1,260 @@ +// +// error.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_ERROR_HPP +#define ASIO_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error_code.hpp" +#include "asio/detail/socket_types.hpp" + +#if defined(GENERATING_DOCUMENTATION) +/// INTERNAL ONLY. +# define ASIO_NATIVE_ERROR(e) implementation_defined +/// INTERNAL ONLY. +# define ASIO_SOCKET_ERROR(e) implementation_defined +/// INTERNAL ONLY. +# define ASIO_NETDB_ERROR(e) implementation_defined +/// INTERNAL ONLY. +# define ASIO_GETADDRINFO_ERROR(e) implementation_defined +/// INTERNAL ONLY. +# define ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined +#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# define ASIO_NATIVE_ERROR(e) e +# define ASIO_SOCKET_ERROR(e) WSA ## e +# define ASIO_NETDB_ERROR(e) WSA ## e +# define ASIO_GETADDRINFO_ERROR(e) WSA ## e +# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win +#else +# define ASIO_NATIVE_ERROR(e) e +# define ASIO_SOCKET_ERROR(e) e +# define ASIO_NETDB_ERROR(e) e +# define ASIO_GETADDRINFO_ERROR(e) e +# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix +#endif + +namespace asio { +namespace error { + +enum basic_errors +{ + /// Permission denied. + access_denied = ASIO_SOCKET_ERROR(EACCES), + + /// Address family not supported by protocol. + address_family_not_supported = ASIO_SOCKET_ERROR(EAFNOSUPPORT), + + /// Address already in use. + address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE), + + /// Transport endpoint is already connected. + already_connected = ASIO_SOCKET_ERROR(EISCONN), + + /// Operation already in progress. + already_started = ASIO_SOCKET_ERROR(EALREADY), + + /// Broken pipe. + broken_pipe = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(ERROR_BROKEN_PIPE), + ASIO_NATIVE_ERROR(EPIPE)), + + /// A connection has been aborted. + connection_aborted = ASIO_SOCKET_ERROR(ECONNABORTED), + + /// Connection refused. + connection_refused = ASIO_SOCKET_ERROR(ECONNREFUSED), + + /// Connection reset by peer. + connection_reset = ASIO_SOCKET_ERROR(ECONNRESET), + + /// Bad file descriptor. + bad_descriptor = ASIO_SOCKET_ERROR(EBADF), + + /// Bad address. + fault = ASIO_SOCKET_ERROR(EFAULT), + + /// No route to host. + host_unreachable = ASIO_SOCKET_ERROR(EHOSTUNREACH), + + /// Operation now in progress. + in_progress = ASIO_SOCKET_ERROR(EINPROGRESS), + + /// Interrupted system call. + interrupted = ASIO_SOCKET_ERROR(EINTR), + + /// Invalid argument. + invalid_argument = ASIO_SOCKET_ERROR(EINVAL), + + /// Message too long. + message_size = ASIO_SOCKET_ERROR(EMSGSIZE), + + /// The name was too long. + name_too_long = ASIO_SOCKET_ERROR(ENAMETOOLONG), + + /// Network is down. + network_down = ASIO_SOCKET_ERROR(ENETDOWN), + + /// Network dropped connection on reset. + network_reset = ASIO_SOCKET_ERROR(ENETRESET), + + /// Network is unreachable. + network_unreachable = ASIO_SOCKET_ERROR(ENETUNREACH), + + /// Too many open files. + no_descriptors = ASIO_SOCKET_ERROR(EMFILE), + + /// No buffer space available. + no_buffer_space = ASIO_SOCKET_ERROR(ENOBUFS), + + /// Cannot allocate memory. + no_memory = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(ERROR_OUTOFMEMORY), + ASIO_NATIVE_ERROR(ENOMEM)), + + /// Operation not permitted. + no_permission = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(ERROR_ACCESS_DENIED), + ASIO_NATIVE_ERROR(EPERM)), + + /// Protocol not available. + no_protocol_option = ASIO_SOCKET_ERROR(ENOPROTOOPT), + + /// Transport endpoint is not connected. + not_connected = ASIO_SOCKET_ERROR(ENOTCONN), + + /// Socket operation on non-socket. + not_socket = ASIO_SOCKET_ERROR(ENOTSOCK), + + /// Operation cancelled. + operation_aborted = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(ERROR_OPERATION_ABORTED), + ASIO_NATIVE_ERROR(ECANCELED)), + + /// Operation not supported. + operation_not_supported = ASIO_SOCKET_ERROR(EOPNOTSUPP), + + /// Cannot send after transport endpoint shutdown. + shut_down = ASIO_SOCKET_ERROR(ESHUTDOWN), + + /// Connection timed out. + timed_out = ASIO_SOCKET_ERROR(ETIMEDOUT), + + /// Resource temporarily unavailable. + try_again = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(ERROR_RETRY), + ASIO_NATIVE_ERROR(EAGAIN)), + + /// The socket is marked non-blocking and the requested operation would block. + would_block = ASIO_SOCKET_ERROR(EWOULDBLOCK) +}; + +enum netdb_errors +{ + /// Host not found (authoritative). + host_not_found = ASIO_NETDB_ERROR(HOST_NOT_FOUND), + + /// Host not found (non-authoritative). + host_not_found_try_again = ASIO_NETDB_ERROR(TRY_AGAIN), + + /// The query is valid but does not have associated address data. + no_data = ASIO_NETDB_ERROR(NO_DATA), + + /// A non-recoverable error occurred. + no_recovery = ASIO_NETDB_ERROR(NO_RECOVERY) +}; + +enum addrinfo_errors +{ + /// The service is not supported for the given socket type. + service_not_found = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(WSATYPE_NOT_FOUND), + ASIO_GETADDRINFO_ERROR(EAI_SERVICE)), + + /// The socket type is not supported. + socket_type_not_supported = ASIO_WIN_OR_POSIX( + ASIO_NATIVE_ERROR(WSAESOCKTNOSUPPORT), + ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE)) +}; + +enum misc_errors +{ + /// Already open. + already_open = 1, + + /// End of file or stream. + eof, + + /// Element not found. + not_found, + + /// The descriptor cannot fit into the select system call's fd_set. + fd_set_failure +}; + +enum ssl_errors +{ +}; + +// boostify: error category definitions go here. + +inline asio::error_code make_error_code(basic_errors e) +{ + return asio::error_code( + static_cast(e), get_system_category()); +} + +inline asio::error_code make_error_code(netdb_errors e) +{ + return asio::error_code( + static_cast(e), get_netdb_category()); +} + +inline asio::error_code make_error_code(addrinfo_errors e) +{ + return asio::error_code( + static_cast(e), get_addrinfo_category()); +} + +inline asio::error_code make_error_code(misc_errors e) +{ + return asio::error_code( + static_cast(e), get_misc_category()); +} + +inline asio::error_code make_error_code(ssl_errors e) +{ + return asio::error_code( + static_cast(e), get_ssl_category()); +} + +} // namespace error +} // namespace asio + +#undef ASIO_NATIVE_ERROR +#undef ASIO_SOCKET_ERROR +#undef ASIO_NETDB_ERROR +#undef ASIO_GETADDRINFO_ERROR +#undef ASIO_WIN_OR_POSIX + +#include "asio/impl/error_code.ipp" + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_ERROR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/error_code.hpp b/src/libs/resiprocate/contrib/asio/asio/error_code.hpp new file mode 100644 index 00000000..6657f3f2 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/error_code.hpp @@ -0,0 +1,164 @@ +// +// error_code.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_ERROR_CODE_HPP +#define ASIO_ERROR_CODE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#if defined(GENERATING_DOCUMENTATION) +# define ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined +#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win +#else +# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix +#endif + +namespace asio { + +namespace error +{ + /// Available error code categories. + enum error_category + { + /// System error codes. + system_category = ASIO_WIN_OR_POSIX(0, 0), + + /// Error codes from NetDB functions. + netdb_category = ASIO_WIN_OR_POSIX(system_category, 1), + + /// Error codes from getaddrinfo. + addrinfo_category = ASIO_WIN_OR_POSIX(system_category, 2), + + /// Miscellaneous error codes. + misc_category = ASIO_WIN_OR_POSIX(3, 3), + + /// SSL error codes. + ssl_category = ASIO_WIN_OR_POSIX(4, 4) + }; + + // Category getters. + inline error_category get_system_category() { return system_category; } + inline error_category get_netdb_category() { return netdb_category; } + inline error_category get_addrinfo_category() { return addrinfo_category; } + inline error_category get_misc_category() { return misc_category; } + inline error_category get_ssl_category() { return ssl_category; } + +} // namespace error + +/// Bring error category type into the asio namespace. +typedef asio::error::error_category error_category; + +/// Class to represent an error code value. +class error_code +{ +public: + /// The underlying representation of an error code. + typedef int value_type; + + /// Default constructor. + error_code() + : value_(0), + category_(error::system_category) + { + } + + /// Construct with specific error code and category. + error_code(value_type v, error_category c) + : value_(v), + category_(c) + { + } + + /// Construct from an error code enum. + template + error_code(ErrorEnum e) + { + *this = make_error_code(e); + } + + /// Get the error value. + value_type value() const + { + return value_; + } + + /// Get the error category. + error_category category() const + { + return category_; + } + + /// Get the message associated with the error. + std::string message() const; + + struct unspecified_bool_type_t + { + }; + + typedef void (*unspecified_bool_type)(unspecified_bool_type_t); + + static void unspecified_bool_true(unspecified_bool_type_t) + { + } + + /// Operator returns non-null if there is a non-success error code. + operator unspecified_bool_type() const + { + if (value_ == 0) + return 0; + else + return &error_code::unspecified_bool_true; + } + + /// Operator to test if the error represents success. + bool operator!() const + { + return value_ == 0; + } + + /// Equality operator to compare two error objects. + friend bool operator==(const error_code& e1, const error_code& e2) + { + return e1.value_ == e2.value_ && e1.category_ == e2.category_; + } + + /// Inequality operator to compare two error objects. + friend bool operator!=(const error_code& e1, const error_code& e2) + { + return e1.value_ != e2.value_ || e1.category_ != e2.category_; + } + +private: + // The value associated with the error code. + value_type value_; + + // The category associated with the error code. + error_category category_; +}; + +} // namespace asio + +#undef ASIO_WIN_OR_POSIX + +#include "asio/error.hpp" + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_ERROR_CODE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/handler_alloc_hook.hpp b/src/libs/resiprocate/contrib/asio/asio/handler_alloc_hook.hpp new file mode 100644 index 00000000..87783cdf --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/handler_alloc_hook.hpp @@ -0,0 +1,88 @@ +// +// handler_alloc_hook.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_HANDLER_ALLOC_HOOK_HPP +#define ASIO_HANDLER_ALLOC_HOOK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { + +/// Default allocation function for handlers. +/** + * Asynchronous operations may need to allocate temporary objects. Since + * asynchronous operations have a handler function object, these temporary + * objects can be said to be associated with the handler. + * + * Implement asio_handler_allocate and asio_handler_deallocate for your own + * handlers to provide custom allocation for these temporary objects. + * + * This default implementation is simply: + * @code + * return ::operator new(size); + * @endcode + * + * @note All temporary objects associated with a handler will be deallocated + * before the upcall to the handler is performed. This allows the same memory to + * be reused for a subsequent asynchronous operation initiated by the handler. + * + * @par Example + * @code + * class my_handler; + * + * void* asio_handler_allocate(std::size_t size, my_handler* context) + * { + * return ::operator new(size); + * } + * + * void asio_handler_deallocate(void* pointer, std::size_t size, + * my_handler* context) + * { + * ::operator delete(pointer); + * } + * @endcode + */ +inline void* asio_handler_allocate(std::size_t size, ...) +{ + return ::operator new(size); +} + +/// Default deallocation function for handlers. +/** + * Implement asio_handler_allocate and asio_handler_deallocate for your own + * handlers to provide custom allocation for the associated temporary objects. + * + * This default implementation is simply: + * @code + * ::operator delete(pointer); + * @endcode + * + * @sa asio_handler_allocate. + */ +inline void asio_handler_deallocate(void* pointer, std::size_t size, ...) +{ + (void)(size); + ::operator delete(pointer); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_HANDLER_ALLOC_HOOK_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/handler_invoke_hook.hpp b/src/libs/resiprocate/contrib/asio/asio/handler_invoke_hook.hpp new file mode 100644 index 00000000..b3d7e454 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/handler_invoke_hook.hpp @@ -0,0 +1,68 @@ +// +// handler_invoke_hook.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_HANDLER_INVOKE_HOOK_HPP +#define ASIO_HANDLER_INVOKE_HOOK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +namespace asio { + +/// Default invoke function for handlers. +/** + * Completion handlers for asynchronous operations are invoked by the + * io_service associated with the corresponding object (e.g. a socket or + * deadline_timer). Certain guarantees are made on when the handler may be + * invoked, in particular that a handler can only be invoked from a thread that + * is currently calling @c run() on the corresponding io_service object. + * Handlers may subsequently be invoked through other objects (such as + * io_service::strand objects) that provide additional guarantees. + * + * When asynchronous operations are composed from other asynchronous + * operations, all intermediate handlers should be invoked using the same + * method as the final handler. This is required to ensure that user-defined + * objects are not accessed in a way that may violate the guarantees. This + * hooking function ensures that the invoked method used for the final handler + * is accessible at each intermediate step. + * + * Implement asio_handler_invoke for your own handlers to specify a custom + * invocation strategy. + * + * This default implementation is simply: + * @code + * function(); + * @endcode + * + * @par Example + * @code + * class my_handler; + * + * template + * void asio_handler_invoke(Function function, my_handler* context) + * { + * context->strand_.dispatch(function); + * } + * @endcode + */ +template +inline void asio_handler_invoke(Function function, ...) +{ + function(); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_HANDLER_INVOKE_HOOK_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/impl/error_code.ipp b/src/libs/resiprocate/contrib/asio/asio/impl/error_code.ipp new file mode 100644 index 00000000..614925dd --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/impl/error_code.ipp @@ -0,0 +1,105 @@ +// +// error_code.ipp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_ERROR_CODE_IPP +#define ASIO_ERROR_CODE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/detail/local_free_on_block_exit.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { + +inline std::string error_code::message() const +{ + if (*this == error::already_open) + return "Already open."; + if (*this == error::not_found) + return "Not found."; + if (*this == error::fd_set_failure) + return "The descriptor does not fit into the select call's fd_set."; + if (category_ == error::get_ssl_category()) + return "SSL error."; +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + value_type value = value_; + if (category() != error::get_system_category() && *this != error::eof) + return "asio error"; + if (*this == error::eof) + value = ERROR_HANDLE_EOF; + char* msg = 0; + DWORD length = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS, 0, value, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + detail::local_free_on_block_exit local_free_obj(msg); + if (length && msg[length - 1] == '\n') + msg[--length] = '\0'; + if (length && msg[length - 1] == '\r') + msg[--length] = '\0'; + if (length) + return msg; + else + return "asio error"; +#else // defined(BOOST_WINDOWS) + if (*this == error::eof) + return "End of file."; + if (*this == error::host_not_found) + return "Host not found (authoritative)."; + if (*this == error::host_not_found_try_again) + return "Host not found (non-authoritative), try again later."; + if (*this == error::no_recovery) + return "A non-recoverable error occurred during database lookup."; + if (*this == error::no_data) + return "The query is valid, but it does not have associated data."; + if (*this == error::not_found) + return "Element not found."; +#if !defined(__sun) + if (*this == error::operation_aborted) + return "Operation aborted."; +#endif // !defined(__sun) + if (*this == error::service_not_found) + return "Service not found."; + if (*this == error::socket_type_not_supported) + return "Socket type not supported."; + if (category() != error::get_system_category()) + return "asio error"; +#if defined(__sun) || defined(__QNX__) + using namespace std; + return strerror(value_); +#elif defined(__MACH__) && defined(__APPLE__) \ +|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) \ +|| defined(_AIX) || defined(__hpux) || defined(__osf__) + char buf[256] = ""; + strerror_r(value_, buf, sizeof(buf)); + return buf; +#else + char buf[256] = ""; + return strerror_r(value_, buf, sizeof(buf)); +#endif +#endif // defined(BOOST_WINDOWS) +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_ERROR_CODE_IPP diff --git a/src/libs/resiprocate/contrib/asio/asio/impl/io_service.ipp b/src/libs/resiprocate/contrib/asio/asio/impl/io_service.ipp new file mode 100644 index 00000000..c3fed3b8 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/impl/io_service.ipp @@ -0,0 +1,224 @@ +// +// io_service.ipp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IO_SERVICE_IPP +#define ASIO_IO_SERVICE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/service_registry.hpp" +#include "asio/detail/throw_error.hpp" + +#if defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_io_service.hpp" +#else +# include "asio/detail/task_io_service.hpp" +# include "asio/detail/reactor.hpp" +#endif + +namespace asio { + +inline io_service::io_service() + : service_registry_(new asio::detail::service_registry(*this)), + impl_(service_registry_->use_service()) +{ + impl_.init((std::numeric_limits::max)()); +} + +inline io_service::io_service(std::size_t concurrency_hint) + : service_registry_(new asio::detail::service_registry(*this)), + impl_(service_registry_->use_service()) +{ + impl_.init(concurrency_hint); +} + +inline io_service::~io_service() +{ + delete service_registry_; +} + +inline std::size_t io_service::run() +{ + asio::error_code ec; + std::size_t s = impl_.run(ec); + asio::detail::throw_error(ec); + return s; +} + +inline std::size_t io_service::run(asio::error_code& ec) +{ + return impl_.run(ec); +} + +inline std::size_t io_service::run_one() +{ + asio::error_code ec; + std::size_t s = impl_.run_one(ec); + asio::detail::throw_error(ec); + return s; +} + +inline std::size_t io_service::run_one(asio::error_code& ec) +{ + return impl_.run_one(ec); +} + +inline std::size_t io_service::poll() +{ + asio::error_code ec; + std::size_t s = impl_.poll(ec); + asio::detail::throw_error(ec); + return s; +} + +inline std::size_t io_service::poll(asio::error_code& ec) +{ + return impl_.poll(ec); +} + +inline std::size_t io_service::poll_one() +{ + asio::error_code ec; + std::size_t s = impl_.poll_one(ec); + asio::detail::throw_error(ec); + return s; +} + +inline std::size_t io_service::poll_one(asio::error_code& ec) +{ + return impl_.poll_one(ec); +} + +inline void io_service::stop() +{ + impl_.stop(); +} + +inline void io_service::reset() +{ + impl_.reset(); +} + +template +inline void io_service::dispatch(Handler handler) +{ + impl_.dispatch(handler); +} + +template +inline void io_service::post(Handler handler) +{ + impl_.post(handler); +} + +template +#if defined(GENERATING_DOCUMENTATION) +unspecified +#else +inline detail::wrapped_handler +#endif +io_service::wrap(Handler handler) +{ + return detail::wrapped_handler(*this, handler); +} + +inline io_service::work::work(asio::io_service& io_service) + : io_service_(io_service) +{ + io_service_.impl_.work_started(); +} + +inline io_service::work::work(const work& other) + : io_service_(other.io_service_) +{ + io_service_.impl_.work_started(); +} + +inline io_service::work::~work() +{ + io_service_.impl_.work_finished(); +} + +inline asio::io_service& io_service::work::io_service() +{ + return io_service_; +} + +inline asio::io_service& io_service::work::get_io_service() +{ + return io_service_; +} + +inline io_service::service::service(asio::io_service& owner) + : owner_(owner), + next_(0) +{ +} + +inline io_service::service::~service() +{ +} + +inline asio::io_service& io_service::service::io_service() +{ + return owner_; +} + +inline asio::io_service& io_service::service::get_io_service() +{ + return owner_; +} + +template +inline Service& use_service(io_service& ios) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast(static_cast(0)); + (void)static_cast(&Service::id); + + return ios.service_registry_->template use_service(); +} + +template +void add_service(io_service& ios, Service* svc) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast(static_cast(0)); + (void)static_cast(&Service::id); + + if (&ios != &svc->io_service()) + boost::throw_exception(invalid_service_owner()); + if (!ios.service_registry_->template add_service(svc)) + boost::throw_exception(service_already_exists()); +} + +template +bool has_service(io_service& ios) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast(static_cast(0)); + (void)static_cast(&Service::id); + + return ios.service_registry_->template has_service(); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IO_SERVICE_IPP diff --git a/src/libs/resiprocate/contrib/asio/asio/impl/read.ipp b/src/libs/resiprocate/contrib/asio/asio/impl/read.ipp new file mode 100644 index 00000000..85f651b8 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/impl/read.ipp @@ -0,0 +1,401 @@ +// +// read.ipp +// ~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_READ_IPP +#define ASIO_READ_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffer.hpp" +#include "asio/completion_condition.hpp" +#include "asio/error.hpp" +#include "asio/detail/base_from_completion_cond.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/consuming_buffers.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { + +template +std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec) +{ + ec = asio::error_code(); + asio::detail::consuming_buffers< + mutable_buffer, MutableBufferSequence> tmp(buffers); + std::size_t total_transferred = 0; + tmp.prepare(detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred))); + while (tmp.begin() != tmp.end()) + { + std::size_t bytes_transferred = s.read_some(tmp, ec); + tmp.consume(bytes_transferred); + total_transferred += bytes_transferred; + tmp.prepare(detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred))); + } + return total_transferred; +} + +template +inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers) +{ + asio::error_code ec; + std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition) +{ + asio::error_code ec; + std::size_t bytes_transferred = read(s, buffers, completion_condition, ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +#if !defined(BOOST_NO_IOSTREAM) + +template +std::size_t read(SyncReadStream& s, + asio::basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec) +{ + ec = asio::error_code(); + std::size_t total_transferred = 0; + std::size_t max_size = detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred)); + std::size_t bytes_available = std::min(512, + std::min(max_size, b.max_size() - b.size())); + while (bytes_available > 0) + { + std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec); + b.commit(bytes_transferred); + total_transferred += bytes_transferred; + max_size = detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred)); + bytes_available = std::min(512, + std::min(max_size, b.max_size() - b.size())); + } + return total_transferred; +} + +template +inline std::size_t read(SyncReadStream& s, + asio::basic_streambuf& b) +{ + asio::error_code ec; + std::size_t bytes_transferred = read(s, b, transfer_all(), ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +inline std::size_t read(SyncReadStream& s, + asio::basic_streambuf& b, + CompletionCondition completion_condition) +{ + asio::error_code ec; + std::size_t bytes_transferred = read(s, b, completion_condition, ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +#endif // !defined(BOOST_NO_IOSTREAM) + +namespace detail +{ + template + class read_op + : detail::base_from_completion_cond + { + public: + read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, ReadHandler handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffers_(buffers), + total_transferred_(0), + handler_(handler), + start_(true) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + switch (start_) + { + case true: start_ = false; + buffers_.prepare(this->check(ec, total_transferred_)); + for (;;) + { + stream_.async_read_some(buffers_, *this); + return; default: + total_transferred_ += bytes_transferred; + buffers_.consume(bytes_transferred); + buffers_.prepare(this->check(ec, total_transferred_)); + if ((!ec && bytes_transferred == 0) + || buffers_.begin() == buffers_.end()) + break; + } + + handler_(ec, total_transferred_); + } + } + + //private: + AsyncReadStream& stream_; + asio::detail::consuming_buffers< + mutable_buffer, MutableBufferSequence> buffers_; + std::size_t total_transferred_; + ReadHandler handler_; + bool start_; + }; + + template + class read_op + : detail::base_from_completion_cond + { + public: + read_op(AsyncReadStream& stream, + const asio::mutable_buffers_1& buffers, + CompletionCondition completion_condition, + ReadHandler handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffer_(buffers), + total_transferred_(0), + handler_(handler), + start_(true) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + std::size_t n = 0; + switch (start_) + { + case true: start_ = false; + n = this->check(ec, total_transferred_); + for (;;) + { + stream_.async_read_some(asio::buffer( + buffer_ + total_transferred_, n), *this); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check(ec, total_transferred_)) == 0 + || total_transferred_ == asio::buffer_size(buffer_)) + break; + } + + handler_(ec, total_transferred_); + } + } + + //private: + AsyncReadStream& stream_; + asio::mutable_buffer buffer_; + std::size_t total_transferred_; + ReadHandler handler_; + bool start_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, ReadHandler handler) +{ + detail::read_op( + s, buffers, completion_condition, handler)( + asio::error_code(), 0); +} + +template +inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, + ReadHandler handler) +{ + async_read(s, buffers, transfer_all(), handler); +} + +#if !defined(BOOST_NO_IOSTREAM) + +namespace detail +{ + template + class read_streambuf_op + : detail::base_from_completion_cond + { + public: + read_streambuf_op(AsyncReadStream& stream, + basic_streambuf& streambuf, + CompletionCondition completion_condition, ReadHandler handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + streambuf_(streambuf), + total_transferred_(0), + handler_(handler), + start_(true) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + std::size_t max_size, bytes_available; + switch (start_) + { + case true: start_ = false; + max_size = this->check(ec, total_transferred_); + bytes_available = std::min(512, + std::min(max_size, + streambuf_.max_size() - streambuf_.size())); + for (;;) + { + stream_.async_read_some(streambuf_.prepare(bytes_available), *this); + return; default: + total_transferred_ += bytes_transferred; + streambuf_.commit(bytes_transferred); + max_size = this->check(ec, total_transferred_); + bytes_available = std::min(512, + std::min(max_size, + streambuf_.max_size() - streambuf_.size())); + if ((!ec && bytes_transferred == 0) || bytes_available == 0) + break; + } + + handler_(ec, total_transferred_); + } + } + + //private: + AsyncReadStream& stream_; + asio::basic_streambuf& streambuf_; + std::size_t total_transferred_; + ReadHandler handler_; + bool start_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_streambuf_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_streambuf_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_streambuf_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +inline void async_read(AsyncReadStream& s, + asio::basic_streambuf& b, + CompletionCondition completion_condition, ReadHandler handler) +{ + detail::read_streambuf_op( + s, b, completion_condition, handler)( + asio::error_code(), 0); +} + +template +inline void async_read(AsyncReadStream& s, + asio::basic_streambuf& b, ReadHandler handler) +{ + async_read(s, b, transfer_all(), handler); +} + +#endif // !defined(BOOST_NO_IOSTREAM) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_READ_IPP diff --git a/src/libs/resiprocate/contrib/asio/asio/impl/read_at.ipp b/src/libs/resiprocate/contrib/asio/asio/impl/read_at.ipp new file mode 100644 index 00000000..7f35750c --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/impl/read_at.ipp @@ -0,0 +1,373 @@ +// +// read_at.ipp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_READ_AT_IPP +#define ASIO_READ_AT_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffer.hpp" +#include "asio/completion_condition.hpp" +#include "asio/error.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/consuming_buffers.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { + +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec) +{ + ec = asio::error_code(); + asio::detail::consuming_buffers< + mutable_buffer, MutableBufferSequence> tmp(buffers); + std::size_t total_transferred = 0; + tmp.prepare(detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred))); + while (tmp.begin() != tmp.end()) + { + std::size_t bytes_transferred = d.read_some_at( + offset + total_transferred, tmp, ec); + tmp.consume(bytes_transferred); + total_transferred += bytes_transferred; + tmp.prepare(detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred))); + } + return total_transferred; +} + +template +inline std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, const MutableBufferSequence& buffers) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_at( + d, offset, buffers, transfer_all(), ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +inline std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_at( + d, offset, buffers, completion_condition, ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +#if !defined(BOOST_NO_IOSTREAM) + +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, asio::basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec) +{ + std::size_t total_transferred = 0; + for (;;) + { + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + std::size_t bytes_transferred = d.read_some_at( + offset + total_transferred, b.prepare(bytes_available), ec); + b.commit(bytes_transferred); + total_transferred += bytes_transferred; + if (b.size() == b.max_size() + || completion_condition(ec, total_transferred)) + return total_transferred; + } +} + +template +inline std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, asio::basic_streambuf& b) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_at( + d, offset, b, transfer_all(), ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +inline std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, asio::basic_streambuf& b, + CompletionCondition completion_condition) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_at( + d, offset, b, completion_condition, ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +#endif // !defined(BOOST_NO_IOSTREAM) + +namespace detail +{ + template + class read_at_handler + { + public: + typedef asio::detail::consuming_buffers< + mutable_buffer, MutableBufferSequence> buffers_type; + + read_at_handler(AsyncRandomAccessReadDevice& stream, + boost::uint64_t offset, const buffers_type& buffers, + CompletionCondition completion_condition, ReadHandler handler) + : stream_(stream), + offset_(offset), + buffers_(buffers), + total_transferred_(0), + completion_condition_(completion_condition), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + total_transferred_ += bytes_transferred; + buffers_.consume(bytes_transferred); + buffers_.prepare(detail::adapt_completion_condition_result( + completion_condition_(ec, total_transferred_))); + if (buffers_.begin() == buffers_.end()) + { + handler_(ec, total_transferred_); + } + else + { + stream_.async_read_some_at( + offset_ + total_transferred_, buffers_, *this); + } + } + + //private: + AsyncRandomAccessReadDevice& stream_; + boost::uint64_t offset_; + buffers_type buffers_; + std::size_t total_transferred_; + CompletionCondition completion_condition_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_at_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_at_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_at_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +inline void async_read_at(AsyncRandomAccessReadDevice& d, + boost::uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, ReadHandler handler) +{ + asio::detail::consuming_buffers< + mutable_buffer, MutableBufferSequence> tmp(buffers); + + asio::error_code ec; + std::size_t total_transferred = 0; + tmp.prepare(detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred))); + if (tmp.begin() == tmp.end()) + { + d.get_io_service().post(detail::bind_handler( + handler, ec, total_transferred)); + return; + } + + d.async_read_some_at(offset, tmp, + detail::read_at_handler( + d, offset, tmp, completion_condition, handler)); +} + +template +inline void async_read_at(AsyncRandomAccessReadDevice& d, + boost::uint64_t offset, const MutableBufferSequence& buffers, + ReadHandler handler) +{ + async_read_at(d, offset, buffers, transfer_all(), handler); +} + +#if !defined(BOOST_NO_IOSTREAM) + +namespace detail +{ + template + class read_at_streambuf_handler + { + public: + read_at_streambuf_handler(AsyncRandomAccessReadDevice& stream, + boost::uint64_t offset, basic_streambuf& streambuf, + CompletionCondition completion_condition, ReadHandler handler) + : stream_(stream), + offset_(offset), + streambuf_(streambuf), + total_transferred_(0), + completion_condition_(completion_condition), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + total_transferred_ += bytes_transferred; + streambuf_.commit(bytes_transferred); + std::size_t max_size = detail::adapt_completion_condition_result( + completion_condition_(ec, total_transferred_)); + std::size_t bytes_available = std::min(512, + std::min(max_size, + streambuf_.max_size() - streambuf_.size())); + if (bytes_available == 0) + { + handler_(ec, total_transferred_); + } + else + { + stream_.async_read_some_at(offset_ + total_transferred_, + streambuf_.prepare(bytes_available), *this); + } + } + + //private: + AsyncRandomAccessReadDevice& stream_; + boost::uint64_t offset_; + asio::basic_streambuf& streambuf_; + std::size_t total_transferred_; + CompletionCondition completion_condition_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_at_streambuf_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_at_streambuf_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_at_streambuf_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +inline void async_read_at(AsyncRandomAccessReadDevice& d, + boost::uint64_t offset, asio::basic_streambuf& b, + CompletionCondition completion_condition, ReadHandler handler) +{ + asio::error_code ec; + std::size_t total_transferred = 0; + std::size_t max_size = detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred)); + std::size_t bytes_available = std::min(512, + std::min(max_size, b.max_size() - b.size())); + if (bytes_available == 0) + { + d.get_io_service().post(detail::bind_handler( + handler, ec, total_transferred)); + return; + } + + d.async_read_some_at(offset, b.prepare(bytes_available), + detail::read_at_streambuf_handler( + d, offset, b, completion_condition, handler)); +} + +template +inline void async_read_at(AsyncRandomAccessReadDevice& d, + boost::uint64_t offset, asio::basic_streambuf& b, + ReadHandler handler) +{ + async_read_at(d, offset, b, transfer_all(), handler); +} + +#endif // !defined(BOOST_NO_IOSTREAM) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_READ_AT_IPP diff --git a/src/libs/resiprocate/contrib/asio/asio/impl/read_until.ipp b/src/libs/resiprocate/contrib/asio/asio/impl/read_until.ipp new file mode 100644 index 00000000..df5130af --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/impl/read_until.ipp @@ -0,0 +1,987 @@ +// +// read_until.ipp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_READ_UNTIL_IPP +#define ASIO_READ_UNTIL_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffer.hpp" +#include "asio/buffers_iterator.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { + +template +inline std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, char delim) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_until(s, b, delim, ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, char delim, + asio::error_code& ec) +{ + std::size_t next_search_start = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef asio::buffers_iterator iterator; + const_buffers_type buffers = b.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + next_search_start; + iterator end = iterator::end(buffers); + + // Look for a match. + iterator iter = std::find(start, end, delim); + if (iter != end) + { + // Found a match. We're done. + ec = asio::error_code(); + return iter - begin + 1; + } + else + { + // No match. Next search can start with the new data. + next_search_start = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + b.commit(s.read_some(b.prepare(bytes_available), ec)); + if (ec) + return 0; + } +} + +template +inline std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, const std::string& delim) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_until(s, b, delim, ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +namespace detail +{ + // Algorithm that finds a subsequence of equal values in a sequence. Returns + // (iterator,true) if a full match was found, in which case the iterator + // points to the beginning of the match. Returns (iterator,false) if a + // partial match was found at the end of the first sequence, in which case + // the iterator points to the beginning of the partial match. Returns + // (last1,false) if no full or partial match was found. + template + std::pair partial_search( + Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) + { + for (Iterator1 iter1 = first1; iter1 != last1; ++iter1) + { + Iterator1 test_iter1 = iter1; + Iterator2 test_iter2 = first2; + for (;; ++test_iter1, ++test_iter2) + { + if (test_iter2 == last2) + return std::make_pair(iter1, true); + if (test_iter1 == last1) + { + if (test_iter2 != first2) + return std::make_pair(iter1, false); + else + break; + } + if (*test_iter1 != *test_iter2) + break; + } + } + return std::make_pair(last1, false); + } +} // namespace detail + +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, const std::string& delim, + asio::error_code& ec) +{ + std::size_t next_search_start = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef asio::buffers_iterator iterator; + const_buffers_type buffers = b.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + next_search_start; + iterator end = iterator::end(buffers); + + // Look for a match. + std::pair result = asio::detail::partial_search( + start, end, delim.begin(), delim.end()); + if (result.first != end) + { + if (result.second) + { + // Full match. We're done. + ec = asio::error_code(); + return result.first - begin + delim.length(); + } + else + { + // Partial match. Next search needs to start from beginning of match. + next_search_start = result.first - begin; + } + } + else + { + // No match. Next search can start with the new data. + next_search_start = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + b.commit(s.read_some(b.prepare(bytes_available), ec)); + if (ec) + return 0; + } +} + +template +inline std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, const boost::regex& expr) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_until(s, b, expr, ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, const boost::regex& expr, + asio::error_code& ec) +{ + std::size_t next_search_start = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef asio::buffers_iterator iterator; + const_buffers_type buffers = b.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + next_search_start; + iterator end = iterator::end(buffers); + + // Look for a match. + boost::match_results match_results; + if (boost::regex_search(start, end, match_results, expr, + boost::match_default | boost::match_partial)) + { + if (match_results[0].matched) + { + // Full match. We're done. + ec = asio::error_code(); + return match_results[0].second - begin; + } + else + { + // Partial match. Next search needs to start from beginning of match. + next_search_start = match_results[0].first - begin; + } + } + else + { + // No match. Next search can start with the new data. + next_search_start = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + b.commit(s.read_some(b.prepare(bytes_available), ec)); + if (ec) + return 0; + } +} + +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, + MatchCondition match_condition, asio::error_code& ec, + typename boost::enable_if >::type*) +{ + std::size_t next_search_start = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef asio::buffers_iterator iterator; + const_buffers_type buffers = b.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + next_search_start; + iterator end = iterator::end(buffers); + + // Look for a match. + std::pair result = match_condition(start, end); + if (result.second) + { + // Full match. We're done. + ec = asio::error_code(); + return result.first - begin; + } + else if (result.first != end) + { + // Partial match. Next search needs to start from beginning of match. + next_search_start = result.first - begin; + } + else + { + // No match. Next search can start with the new data. + next_search_start = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + b.commit(s.read_some(b.prepare(bytes_available), ec)); + if (ec) + return 0; + } +} + +template +inline std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, MatchCondition match_condition, + typename boost::enable_if >::type*) +{ + asio::error_code ec; + std::size_t bytes_transferred = read_until(s, b, match_condition, ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +namespace detail +{ + template + class read_until_delim_handler + { + public: + read_until_delim_handler(AsyncReadStream& stream, + asio::basic_streambuf& streambuf, char delim, + std::size_t next_search_start, ReadHandler handler) + : stream_(stream), + streambuf_(streambuf), + delim_(delim), + next_search_start_(next_search_start), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + // Check for errors. + if (ec) + { + std::size_t bytes = 0; + handler_(ec, bytes); + return; + } + + // Commit received data to streambuf's get area. + streambuf_.commit(bytes_transferred); + + // Determine the range of the data to be searched. + typedef typename asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef asio::buffers_iterator iterator; + const_buffers_type buffers = streambuf_.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + next_search_start_; + iterator end = iterator::end(buffers); + + // Look for a match. + iterator iter = std::find(start, end, delim_); + if (iter != end) + { + // Found a match. We're done. + std::size_t bytes = iter - begin + 1; + handler_(ec, bytes); + return; + } + + // No match. Check if buffer is full. + if (streambuf_.size() == streambuf_.max_size()) + { + std::size_t bytes = 0; + asio::error_code ec(error::not_found); + handler_(ec, bytes); + return; + } + + // Next search can start with the new data. + next_search_start_ = end - begin; + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, streambuf_.max_size() - streambuf_.size()); + stream_.async_read_some(streambuf_.prepare(bytes_available), *this); + } + + //private: + AsyncReadStream& stream_; + asio::basic_streambuf& streambuf_; + char delim_; + std::size_t next_search_start_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_until_delim_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_delim_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_until_delim_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +void async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, char delim, ReadHandler handler) +{ + // Determine the range of the data to be searched. + typedef typename asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef asio::buffers_iterator iterator; + const_buffers_type buffers = b.data(); + iterator begin = iterator::begin(buffers); + iterator end = iterator::end(buffers); + + // Look for a match. + iterator iter = std::find(begin, end, delim); + if (iter != end) + { + // Found a match. We're done. + asio::error_code ec; + std::size_t bytes = iter - begin + 1; + s.get_io_service().post(detail::bind_handler(handler, ec, bytes)); + return; + } + + // No match. Check if buffer is full. + if (b.size() == b.max_size()) + { + asio::error_code ec(error::not_found); + s.get_io_service().post(detail::bind_handler(handler, ec, 0)); + return; + } + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + s.async_read_some(b.prepare(bytes_available), + detail::read_until_delim_handler( + s, b, delim, end - begin, handler)); +} + +namespace detail +{ + template + class read_until_delim_string_handler + { + public: + read_until_delim_string_handler(AsyncReadStream& stream, + asio::basic_streambuf& streambuf, + const std::string& delim, std::size_t next_search_start, + ReadHandler handler) + : stream_(stream), + streambuf_(streambuf), + delim_(delim), + next_search_start_(next_search_start), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + // Check for errors. + if (ec) + { + std::size_t bytes = 0; + handler_(ec, bytes); + return; + } + + // Commit received data to streambuf's get area. + streambuf_.commit(bytes_transferred); + + // Determine the range of the data to be searched. + typedef typename asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef asio::buffers_iterator iterator; + const_buffers_type buffers = streambuf_.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + next_search_start_; + iterator end = iterator::end(buffers); + + // Look for a match. + std::pair result = asio::detail::partial_search( + start, end, delim_.begin(), delim_.end()); + if (result.first != end) + { + if (result.second) + { + // Full match. We're done. + std::size_t bytes = result.first - begin + delim_.length(); + handler_(ec, bytes); + return; + } + else + { + // Partial match. Next search needs to start from beginning of match. + next_search_start_ = result.first - begin; + } + } + else + { + // No match. Next search can start with the new data. + next_search_start_ = end - begin; + } + + // Check if buffer is full. + if (streambuf_.size() == streambuf_.max_size()) + { + std::size_t bytes = 0; + asio::error_code ec2(error::not_found); + handler_(ec2, bytes); + return; + } + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, streambuf_.max_size() - streambuf_.size()); + stream_.async_read_some(streambuf_.prepare(bytes_available), *this); + } + + //private: + AsyncReadStream& stream_; + asio::basic_streambuf& streambuf_; + std::string delim_; + std::size_t next_search_start_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_until_delim_string_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_delim_string_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_until_delim_string_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +void async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, const std::string& delim, + ReadHandler handler) +{ + // Determine the range of the data to be searched. + typedef typename asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef asio::buffers_iterator iterator; + const_buffers_type buffers = b.data(); + iterator begin = iterator::begin(buffers); + iterator end = iterator::end(buffers); + + // Look for a match. + std::size_t next_search_start; + std::pair result = asio::detail::partial_search( + begin, end, delim.begin(), delim.end()); + if (result.first != end) + { + if (result.second) + { + // Full match. We're done. + asio::error_code ec; + std::size_t bytes = result.first - begin + delim.length(); + s.get_io_service().post(detail::bind_handler(handler, ec, bytes)); + return; + } + else + { + // Partial match. Next search needs to start from beginning of match. + next_search_start = result.first - begin; + } + } + else + { + // No match. Next search can start with the new data. + next_search_start = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + asio::error_code ec(error::not_found); + s.get_io_service().post(detail::bind_handler(handler, ec, 0)); + return; + } + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + s.async_read_some(b.prepare(bytes_available), + detail::read_until_delim_string_handler< + AsyncReadStream, Allocator, ReadHandler>( + s, b, delim, next_search_start, handler)); +} + +namespace detail +{ + template + class read_until_expr_handler + { + public: + read_until_expr_handler(AsyncReadStream& stream, + asio::basic_streambuf& streambuf, + const boost::regex& expr, std::size_t next_search_start, + ReadHandler handler) + : stream_(stream), + streambuf_(streambuf), + expr_(expr), + next_search_start_(next_search_start), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + // Check for errors. + if (ec) + { + std::size_t bytes = 0; + handler_(ec, bytes); + return; + } + + // Commit received data to streambuf's get area. + streambuf_.commit(bytes_transferred); + + // Determine the range of the data to be searched. + typedef typename asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef asio::buffers_iterator iterator; + const_buffers_type buffers = streambuf_.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + next_search_start_; + iterator end = iterator::end(buffers); + + // Look for a match. + boost::match_results match_results; + if (boost::regex_search(start, end, match_results, expr_, + boost::match_default | boost::match_partial)) + { + if (match_results[0].matched) + { + // Full match. We're done. + std::size_t bytes = match_results[0].second - begin; + handler_(ec, bytes); + return; + } + else + { + // Partial match. Next search needs to start from beginning of match. + next_search_start_ = match_results[0].first - begin; + } + } + else + { + // No match. Next search can start with the new data. + next_search_start_ = end - begin; + } + + // Check if buffer is full. + if (streambuf_.size() == streambuf_.max_size()) + { + std::size_t bytes = 0; + asio::error_code ec(error::not_found); + handler_(ec, bytes); + return; + } + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, streambuf_.max_size() - streambuf_.size()); + stream_.async_read_some(streambuf_.prepare(bytes_available), *this); + } + + //private: + AsyncReadStream& stream_; + asio::basic_streambuf& streambuf_; + boost::regex expr_; + std::size_t next_search_start_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_until_expr_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_expr_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_until_expr_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +void async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, const boost::regex& expr, + ReadHandler handler) +{ + // Determine the range of the data to be searched. + typedef typename asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef asio::buffers_iterator iterator; + const_buffers_type buffers = b.data(); + iterator begin = iterator::begin(buffers); + iterator end = iterator::end(buffers); + + // Look for a match. + std::size_t next_search_start; + boost::match_results match_results; + if (boost::regex_search(begin, end, match_results, expr, + boost::match_default | boost::match_partial)) + { + if (match_results[0].matched) + { + // Full match. We're done. + asio::error_code ec; + std::size_t bytes = match_results[0].second - begin; + s.get_io_service().post(detail::bind_handler(handler, ec, bytes)); + return; + } + else + { + // Partial match. Next search needs to start from beginning of match. + next_search_start = match_results[0].first - begin; + } + } + else + { + // No match. Next search can start with the new data. + next_search_start = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + asio::error_code ec(error::not_found); + s.get_io_service().post(detail::bind_handler(handler, ec, 0)); + return; + } + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + s.async_read_some(b.prepare(bytes_available), + detail::read_until_expr_handler( + s, b, expr, next_search_start, handler)); +} + +namespace detail +{ + template + class read_until_match_handler + { + public: + read_until_match_handler(AsyncReadStream& stream, + asio::basic_streambuf& streambuf, + MatchCondition match_condition, std::size_t next_search_start, + ReadHandler handler) + : stream_(stream), + streambuf_(streambuf), + match_condition_(match_condition), + next_search_start_(next_search_start), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + // Check for errors. + if (ec) + { + std::size_t bytes = 0; + handler_(ec, bytes); + return; + } + + // Commit received data to streambuf's get area. + streambuf_.commit(bytes_transferred); + + // Determine the range of the data to be searched. + typedef typename asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef asio::buffers_iterator iterator; + const_buffers_type buffers = streambuf_.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + next_search_start_; + iterator end = iterator::end(buffers); + + // Look for a match. + std::pair result = match_condition_(start, end); + if (result.second) + { + // Full match. We're done. + std::size_t bytes = result.first - begin; + handler_(ec, bytes); + return; + } + else if (result.first != end) + { + // Partial match. Next search needs to start from beginning of match. + next_search_start_ = result.first - begin; + } + else + { + // No match. Next search can start with the new data. + next_search_start_ = end - begin; + } + + // Check if buffer is full. + if (streambuf_.size() == streambuf_.max_size()) + { + std::size_t bytes = 0; + asio::error_code ec(error::not_found); + handler_(ec, bytes); + return; + } + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, streambuf_.max_size() - streambuf_.size()); + stream_.async_read_some(streambuf_.prepare(bytes_available), *this); + } + + //private: + AsyncReadStream& stream_; + asio::basic_streambuf& streambuf_; + MatchCondition match_condition_; + std::size_t next_search_start_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + read_until_match_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_match_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + read_until_match_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +void async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, + MatchCondition match_condition, ReadHandler handler, + typename boost::enable_if >::type*) +{ + // Determine the range of the data to be searched. + typedef typename asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef asio::buffers_iterator iterator; + const_buffers_type buffers = b.data(); + iterator begin = iterator::begin(buffers); + iterator end = iterator::end(buffers); + + // Look for a match. + std::size_t next_search_start; + std::pair result = match_condition(begin, end); + if (result.second) + { + // Full match. We're done. + asio::error_code ec; + std::size_t bytes = result.first - begin; + s.get_io_service().post(detail::bind_handler(handler, ec, bytes)); + return; + } + else if (result.first != end) + { + // Partial match. Next search needs to start from beginning of match. + next_search_start = result.first - begin; + } + else + { + // No match. Next search can start with the new data. + next_search_start = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + asio::error_code ec(error::not_found); + s.get_io_service().post(detail::bind_handler(handler, ec, 0)); + return; + } + + // Start a new asynchronous read operation to obtain more data. + std::size_t bytes_available = + std::min(512, b.max_size() - b.size()); + s.async_read_some(b.prepare(bytes_available), + detail::read_until_match_handler< + AsyncReadStream, Allocator, MatchCondition, ReadHandler>( + s, b, match_condition, next_search_start, handler)); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_READ_UNTIL_IPP diff --git a/src/libs/resiprocate/contrib/asio/asio/impl/serial_port_base.ipp b/src/libs/resiprocate/contrib/asio/asio/impl/serial_port_base.ipp new file mode 100644 index 00000000..64ab6a45 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/impl/serial_port_base.ipp @@ -0,0 +1,557 @@ +// +// serial_port_base.ipp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SERIAL_PORT_BASE_IPP +#define ASIO_SERIAL_PORT_BASE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { + +inline serial_port_base::baud_rate::baud_rate(unsigned int rate) + : value_(rate) +{ +} + +inline unsigned int serial_port_base::baud_rate::value() const +{ + return value_; +} + +inline asio::error_code serial_port_base::baud_rate::store( + ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + storage.BaudRate = value_; +#else + speed_t baud; + switch (value_) + { + // Do POSIX-specified rates first. + case 0: baud = B0; break; + case 50: baud = B50; break; + case 75: baud = B75; break; + case 110: baud = B110; break; + case 134: baud = B134; break; + case 150: baud = B150; break; + case 200: baud = B200; break; + case 300: baud = B300; break; + case 600: baud = B600; break; + case 1200: baud = B1200; break; + case 1800: baud = B1800; break; + case 2400: baud = B2400; break; + case 4800: baud = B4800; break; + case 9600: baud = B9600; break; + case 19200: baud = B19200; break; + case 38400: baud = B38400; break; + // And now the extended ones conditionally. +# ifdef B7200 + case 7200: baud = B7200; break; +# endif +# ifdef B14400 + case 14400: baud = B14400; break; +# endif +# ifdef B57600 + case 57600: baud = B57600; break; +# endif +# ifdef B115200 + case 115200: baud = B115200; break; +# endif +# ifdef B230400 + case 230400: baud = B230400; break; +# endif +# ifdef B460800 + case 460800: baud = B460800; break; +# endif +# ifdef B500000 + case 500000: baud = B500000; break; +# endif +# ifdef B576000 + case 576000: baud = B576000; break; +# endif +# ifdef B921600 + case 921600: baud = B921600; break; +# endif +# ifdef B1000000 + case 1000000: baud = B1000000; break; +# endif +# ifdef B1152000 + case 1152000: baud = B1152000; break; +# endif +# ifdef B2000000 + case 2000000: baud = B2000000; break; +# endif +# ifdef B3000000 + case 3000000: baud = B3000000; break; +# endif +# ifdef B3500000 + case 3500000: baud = B3500000; break; +# endif +# ifdef B4000000 + case 4000000: baud = B4000000; break; +# endif + default: + baud = B0; + ec = asio::error::invalid_argument; + return ec; + } +# if defined(_BSD_SOURCE) + ::cfsetspeed(&storage, baud); +# else + ::cfsetispeed(&storage, baud); + ::cfsetospeed(&storage, baud); +# endif +#endif + ec = asio::error_code(); + return ec; +} + +inline asio::error_code serial_port_base::baud_rate::load( + const ASIO_OPTION_STORAGE& storage, asio::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + value_ = storage.BaudRate; +#else + speed_t baud = ::cfgetospeed(&storage); + switch (baud) + { + // First do those specified by POSIX. + case B0: value_ = 0; break; + case B50: value_ = 50; break; + case B75: value_ = 75; break; + case B110: value_ = 110; break; + case B134: value_ = 134; break; + case B150: value_ = 150; break; + case B200: value_ = 200; break; + case B300: value_ = 300; break; + case B600: value_ = 600; break; + case B1200: value_ = 1200; break; + case B1800: value_ = 1800; break; + case B2400: value_ = 2400; break; + case B4800: value_ = 4800; break; + case B9600: value_ = 9600; break; + case B19200: value_ = 19200; break; + case B38400: value_ = 38400; break; + // Now conditionally handle a bunch of extended rates. +# ifdef B7200 + case B7200: value_ = 7200; break; +# endif +# ifdef B14400 + case B14400: value_ = 14400; break; +# endif +# ifdef B57600 + case B57600: value_ = 57600; break; +# endif +# ifdef B115200 + case B115200: value_ = 115200; break; +# endif +# ifdef B230400 + case B230400: value_ = 230400; break; +# endif +# ifdef B460800 + case B460800: value_ = 460800; break; +# endif +# ifdef B500000 + case B500000: value_ = 500000; break; +# endif +# ifdef B576000 + case B576000: value_ = 576000; break; +# endif +# ifdef B921600 + case B921600: value_ = 921600; break; +# endif +# ifdef B1000000 + case B1000000: value_ = 1000000; break; +# endif +# ifdef B1152000 + case B1152000: value_ = 1152000; break; +# endif +# ifdef B2000000 + case B2000000: value_ = 2000000; break; +# endif +# ifdef B3000000 + case B3000000: value_ = 3000000; break; +# endif +# ifdef B3500000 + case B3500000: value_ = 3500000; break; +# endif +# ifdef B4000000 + case B4000000: value_ = 4000000; break; +# endif + default: + value_ = 0; + ec = asio::error::invalid_argument; + return ec; + } +#endif + ec = asio::error_code(); + return ec; +} + +inline serial_port_base::flow_control::flow_control( + serial_port_base::flow_control::type t) + : value_(t) +{ + if (t != none && t != software && t != hardware) + { + std::out_of_range ex("invalid flow_control value"); + boost::throw_exception(ex); + } +} + +inline serial_port_base::flow_control::type +serial_port_base::flow_control::value() const +{ + return value_; +} + +inline asio::error_code serial_port_base::flow_control::store( + ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + storage.fOutxCtsFlow = FALSE; + storage.fOutxDsrFlow = FALSE; + storage.fTXContinueOnXoff = TRUE; + storage.fDtrControl = DTR_CONTROL_ENABLE; + storage.fDsrSensitivity = FALSE; + storage.fOutX = FALSE; + storage.fInX = FALSE; + storage.fRtsControl = RTS_CONTROL_ENABLE; + switch (value_) + { + case none: + break; + case software: + storage.fOutX = TRUE; + storage.fInX = TRUE; + break; + case hardware: + storage.fOutxCtsFlow = TRUE; + storage.fRtsControl = RTS_CONTROL_HANDSHAKE; + break; + default: + break; + } +#else + switch (value_) + { + case none: + storage.c_iflag &= ~(IXOFF | IXON); +# if defined(_BSD_SOURCE) + storage.c_cflag &= ~CRTSCTS; +# endif + break; + case software: + storage.c_iflag |= IXOFF | IXON; +# if defined(_BSD_SOURCE) + storage.c_cflag &= ~CRTSCTS; +# endif + break; + case hardware: +# if defined(_BSD_SOURCE) + storage.c_iflag &= ~(IXOFF | IXON); + storage.c_cflag |= CRTSCTS; + break; +# else + ec = asio::error::operation_not_supported; + return ec; +# endif + default: + break; + } +#endif + ec = asio::error_code(); + return ec; +} + +inline asio::error_code serial_port_base::flow_control::load( + const ASIO_OPTION_STORAGE& storage, asio::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (storage.fOutX && storage.fInX) + { + value_ = software; + } + else if (storage.fOutxCtsFlow && storage.fRtsControl == RTS_CONTROL_HANDSHAKE) + { + value_ = hardware; + } + else + { + value_ = none; + } +#else + if (storage.c_iflag & (IXOFF | IXON)) + { + value_ = software; + } +# if defined(_BSD_SOURCE) + else if (storage.c_cflag & CRTSCTS) + { + value_ = hardware; + } +# endif + else + { + value_ = none; + } +#endif + ec = asio::error_code(); + return ec; +} + +inline serial_port_base::parity::parity(serial_port_base::parity::type t) + : value_(t) +{ + if (t != none && t != odd && t != even) + { + std::out_of_range ex("invalid parity value"); + boost::throw_exception(ex); + } +} + +inline serial_port_base::parity::type serial_port_base::parity::value() const +{ + return value_; +} + +inline asio::error_code serial_port_base::parity::store( + ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + switch (value_) + { + case none: + storage.fParity = FALSE; + storage.Parity = NOPARITY; + break; + case odd: + storage.fParity = TRUE; + storage.Parity = ODDPARITY; + break; + case even: + storage.fParity = TRUE; + storage.Parity = EVENPARITY; + break; + default: + break; + } +#else + switch (value_) + { + case none: + storage.c_iflag |= IGNPAR; + storage.c_cflag &= ~(PARENB | PARODD); + break; + case even: + storage.c_iflag &= ~(IGNPAR | PARMRK); + storage.c_iflag |= INPCK; + storage.c_cflag |= PARENB; + storage.c_cflag &= ~PARODD; + break; + case odd: + storage.c_iflag &= ~(IGNPAR | PARMRK); + storage.c_iflag |= INPCK; + storage.c_cflag |= (PARENB | PARODD); + break; + default: + break; + } +#endif + ec = asio::error_code(); + return ec; +} + +inline asio::error_code serial_port_base::parity::load( + const ASIO_OPTION_STORAGE& storage, asio::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (storage.Parity == EVENPARITY) + { + value_ = even; + } + else if (storage.Parity == ODDPARITY) + { + value_ = odd; + } + else + { + value_ = none; + } +#else + if (storage.c_cflag & PARENB) + { + if (storage.c_cflag & PARODD) + { + value_ = odd; + } + else + { + value_ = even; + } + } + else + { + value_ = none; + } +#endif + ec = asio::error_code(); + return ec; +} + +inline serial_port_base::stop_bits::stop_bits( + serial_port_base::stop_bits::type t) + : value_(t) +{ + if (t != one && t != onepointfive && t != two) + { + std::out_of_range ex("invalid stop_bits value"); + boost::throw_exception(ex); + } +} + +inline serial_port_base::stop_bits::type +serial_port_base::stop_bits::value() const +{ + return value_; +} + +inline asio::error_code serial_port_base::stop_bits::store( + ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + switch (value_) + { + case one: + storage.StopBits = ONESTOPBIT; + break; + case onepointfive: + storage.StopBits = ONE5STOPBITS; + break; + case two: + storage.StopBits = TWOSTOPBITS; + break; + default: + break; + } +#else + switch (value_) + { + case one: + storage.c_cflag &= ~CSTOPB; + break; + case two: + storage.c_cflag |= CSTOPB; + break; + default: + ec = asio::error::operation_not_supported; + return ec; + } +#endif + ec = asio::error_code(); + return ec; +} + +inline asio::error_code serial_port_base::stop_bits::load( + const ASIO_OPTION_STORAGE& storage, asio::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (storage.StopBits == ONESTOPBIT) + { + value_ = one; + } + else if (storage.StopBits == ONE5STOPBITS) + { + value_ = onepointfive; + } + else if (storage.StopBits == TWOSTOPBITS) + { + value_ = two; + } + else + { + value_ = one; + } +#else + value_ = (storage.c_cflag & CSTOPB) ? two : one; +#endif + ec = asio::error_code(); + return ec; +} + +inline serial_port_base::character_size::character_size(unsigned int t) + : value_(t) +{ + if (t < 5 || t > 8) + { + std::out_of_range ex("invalid character_size value"); + boost::throw_exception(ex); + } +} + +inline unsigned int serial_port_base::character_size::value() const +{ + return value_; +} + +inline asio::error_code serial_port_base::character_size::store( + ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + storage.ByteSize = value_; +#else + storage.c_cflag &= ~CSIZE; + switch (value_) + { + case 5: storage.c_cflag |= CS5; break; + case 6: storage.c_cflag |= CS6; break; + case 7: storage.c_cflag |= CS7; break; + case 8: storage.c_cflag |= CS8; break; + default: break; + } +#endif + ec = asio::error_code(); + return ec; +} + +inline asio::error_code serial_port_base::character_size::load( + const ASIO_OPTION_STORAGE& storage, asio::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + value_ = storage.ByteSize; +#else + if ((storage.c_cflag & CSIZE) == CS5) { value_ = 5; } + else if ((storage.c_cflag & CSIZE) == CS6) { value_ = 6; } + else if ((storage.c_cflag & CSIZE) == CS7) { value_ = 7; } + else if ((storage.c_cflag & CSIZE) == CS8) { value_ = 8; } + else + { + // Hmmm, use 8 for now. + value_ = 8; + } +#endif + ec = asio::error_code(); + return ec; +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SERIAL_PORT_BASE_IPP diff --git a/src/libs/resiprocate/contrib/asio/asio/impl/write.ipp b/src/libs/resiprocate/contrib/asio/asio/impl/write.ipp new file mode 100644 index 00000000..82e7a3eb --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/impl/write.ipp @@ -0,0 +1,402 @@ +// +// write.ipp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WRITE_IPP +#define ASIO_WRITE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/buffer.hpp" +#include "asio/completion_condition.hpp" +#include "asio/detail/base_from_completion_cond.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/consuming_buffers.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { + +template +std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec) +{ + ec = asio::error_code(); + asio::detail::consuming_buffers< + const_buffer, ConstBufferSequence> tmp(buffers); + std::size_t total_transferred = 0; + tmp.prepare(detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred))); + while (tmp.begin() != tmp.end()) + { + std::size_t bytes_transferred = s.write_some(tmp, ec); + tmp.consume(bytes_transferred); + total_transferred += bytes_transferred; + tmp.prepare(detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred))); + } + return total_transferred; +} + +template +inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers) +{ + asio::error_code ec; + std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition) +{ + asio::error_code ec; + std::size_t bytes_transferred = write(s, buffers, completion_condition, ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +#if !defined(BOOST_NO_IOSTREAM) + +template +std::size_t write(SyncWriteStream& s, + asio::basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec) +{ + std::size_t bytes_transferred = write(s, b.data(), completion_condition, ec); + b.consume(bytes_transferred); + return bytes_transferred; +} + +template +inline std::size_t write(SyncWriteStream& s, + asio::basic_streambuf& b) +{ + asio::error_code ec; + std::size_t bytes_transferred = write(s, b, transfer_all(), ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +inline std::size_t write(SyncWriteStream& s, + asio::basic_streambuf& b, + CompletionCondition completion_condition) +{ + asio::error_code ec; + std::size_t bytes_transferred = write(s, b, completion_condition, ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +#endif // !defined(BOOST_NO_IOSTREAM) + +namespace detail +{ + template + class write_op + : detail::base_from_completion_cond + { + public: + write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, WriteHandler handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffers_(buffers), + total_transferred_(0), + handler_(handler), + start_(true) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + switch (start_) + { + case true: start_ = false; + buffers_.prepare(this->check(ec, total_transferred_)); + for (;;) + { + stream_.async_write_some(buffers_, *this); + return; default: + total_transferred_ += bytes_transferred; + buffers_.consume(bytes_transferred); + buffers_.prepare(this->check(ec, total_transferred_)); + if ((!ec && bytes_transferred == 0) + || buffers_.begin() == buffers_.end()) + break; + } + + handler_(ec, total_transferred_); + } + } + + //private: + AsyncWriteStream& stream_; + asio::detail::consuming_buffers< + const_buffer, ConstBufferSequence> buffers_; + std::size_t total_transferred_; + WriteHandler handler_; + bool start_; + }; + + template + class write_op + : detail::base_from_completion_cond + { + public: + write_op(AsyncWriteStream& stream, + const asio::mutable_buffers_1& buffers, + CompletionCondition completion_condition, + WriteHandler handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffer_(buffers), + total_transferred_(0), + handler_(handler), + start_(true) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + std::size_t n = 0; + switch (start_) + { + case true: start_ = false; + n = this->check(ec, total_transferred_); + for (;;) + { + stream_.async_write_some(asio::buffer( + buffer_ + total_transferred_, n), *this); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check(ec, total_transferred_)) == 0 + || total_transferred_ == asio::buffer_size(buffer_)) + break; + } + + handler_(ec, total_transferred_); + } + } + + //private: + AsyncWriteStream& stream_; + asio::mutable_buffer buffer_; + std::size_t total_transferred_; + WriteHandler handler_; + bool start_; + }; + + template + class write_op + : detail::base_from_completion_cond + { + public: + write_op(AsyncWriteStream& stream, + const asio::const_buffers_1& buffers, + CompletionCondition completion_condition, + WriteHandler handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffer_(buffers), + total_transferred_(0), + handler_(handler), + start_(true) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + std::size_t n = 0; + switch (start_) + { + case true: start_ = false; + n = this->check(ec, total_transferred_); + for (;;) + { + stream_.async_write_some(asio::buffer( + buffer_ + total_transferred_, n), *this); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check(ec, total_transferred_)) == 0 + || total_transferred_ == asio::buffer_size(buffer_)) + break; + } + + handler_(ec, total_transferred_); + } + } + + //private: + AsyncWriteStream& stream_; + asio::const_buffer buffer_; + std::size_t total_transferred_; + WriteHandler handler_; + bool start_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + write_op* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + write_op* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + write_op* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, WriteHandler handler) +{ + detail::write_op( + s, buffers, completion_condition, handler)( + asio::error_code(), 0); +} + +template +inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, + WriteHandler handler) +{ + async_write(s, buffers, transfer_all(), handler); +} + +#if !defined(BOOST_NO_IOSTREAM) + +namespace detail +{ + template + class write_streambuf_handler + { + public: + write_streambuf_handler(asio::basic_streambuf& streambuf, + WriteHandler handler) + : streambuf_(streambuf), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + streambuf_.consume(bytes_transferred); + handler_(ec, bytes_transferred); + } + + //private: + asio::basic_streambuf& streambuf_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + write_streambuf_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + write_streambuf_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + write_streambuf_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +inline void async_write(AsyncWriteStream& s, + asio::basic_streambuf& b, + CompletionCondition completion_condition, WriteHandler handler) +{ + async_write(s, b.data(), completion_condition, + detail::write_streambuf_handler< + AsyncWriteStream, Allocator, WriteHandler>(b, handler)); +} + +template +inline void async_write(AsyncWriteStream& s, + asio::basic_streambuf& b, WriteHandler handler) +{ + async_write(s, b, transfer_all(), handler); +} + +#endif // !defined(BOOST_NO_IOSTREAM) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WRITE_IPP diff --git a/src/libs/resiprocate/contrib/asio/asio/impl/write_at.ipp b/src/libs/resiprocate/contrib/asio/asio/impl/write_at.ipp new file mode 100644 index 00000000..12fb3f45 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/impl/write_at.ipp @@ -0,0 +1,319 @@ +// +// write_at.ipp +// ~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WRITE_AT_IPP +#define ASIO_WRITE_AT_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/buffer.hpp" +#include "asio/completion_condition.hpp" +#include "asio/detail/bind_handler.hpp" +#include "asio/detail/consuming_buffers.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { + +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + boost::uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec) +{ + ec = asio::error_code(); + asio::detail::consuming_buffers< + const_buffer, ConstBufferSequence> tmp(buffers); + std::size_t total_transferred = 0; + tmp.prepare(detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred))); + while (tmp.begin() != tmp.end()) + { + std::size_t bytes_transferred = d.write_some_at( + offset + total_transferred, tmp, ec); + tmp.consume(bytes_transferred); + total_transferred += bytes_transferred; + tmp.prepare(detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred))); + } + return total_transferred; +} + +template +inline std::size_t write_at(SyncRandomAccessWriteDevice& d, + boost::uint64_t offset, const ConstBufferSequence& buffers) +{ + asio::error_code ec; + std::size_t bytes_transferred = write_at( + d, offset, buffers, transfer_all(), ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +inline std::size_t write_at(SyncRandomAccessWriteDevice& d, + boost::uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition) +{ + asio::error_code ec; + std::size_t bytes_transferred = write_at( + d, offset, buffers, completion_condition, ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +#if !defined(BOOST_NO_IOSTREAM) + +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + boost::uint64_t offset, asio::basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec) +{ + std::size_t bytes_transferred = write_at( + d, offset, b.data(), completion_condition, ec); + b.consume(bytes_transferred); + return bytes_transferred; +} + +template +inline std::size_t write_at(SyncRandomAccessWriteDevice& d, + boost::uint64_t offset, asio::basic_streambuf& b) +{ + asio::error_code ec; + std::size_t bytes_transferred = write_at(d, offset, b, transfer_all(), ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +template +inline std::size_t write_at(SyncRandomAccessWriteDevice& d, + boost::uint64_t offset, asio::basic_streambuf& b, + CompletionCondition completion_condition) +{ + asio::error_code ec; + std::size_t bytes_transferred = write_at( + d, offset, b, completion_condition, ec); + asio::detail::throw_error(ec); + return bytes_transferred; +} + +#endif // !defined(BOOST_NO_IOSTREAM) + +namespace detail +{ + template + class write_at_handler + { + public: + typedef asio::detail::consuming_buffers< + const_buffer, ConstBufferSequence> buffers_type; + + write_at_handler(AsyncRandomAccessWriteDevice& stream, + boost::uint64_t offset, const buffers_type& buffers, + CompletionCondition completion_condition, WriteHandler handler) + : stream_(stream), + buffers_(buffers), + offset_(offset), + total_transferred_(0), + completion_condition_(completion_condition), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + total_transferred_ += bytes_transferred; + buffers_.consume(bytes_transferred); + buffers_.prepare(detail::adapt_completion_condition_result( + completion_condition_(ec, total_transferred_))); + if (buffers_.begin() == buffers_.end()) + { + handler_(ec, total_transferred_); + } + else + { + stream_.async_write_some_at( + offset_ + total_transferred_, buffers_, *this); + } + } + + //private: + AsyncRandomAccessWriteDevice& stream_; + buffers_type buffers_; + boost::uint64_t offset_; + std::size_t total_transferred_; + CompletionCondition completion_condition_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + write_at_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + write_at_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + write_at_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +inline void async_write_at(AsyncRandomAccessWriteDevice& d, + boost::uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, WriteHandler handler) +{ + asio::detail::consuming_buffers< + const_buffer, ConstBufferSequence> tmp(buffers); + + asio::error_code ec; + std::size_t total_transferred = 0; + tmp.prepare(detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred))); + if (tmp.begin() == tmp.end()) + { + d.get_io_service().post(detail::bind_handler( + handler, ec, total_transferred)); + return; + } + + d.async_write_some_at(offset, tmp, + detail::write_at_handler( + d, offset, tmp, completion_condition, handler)); +} + +template +inline void async_write_at(AsyncRandomAccessWriteDevice& d, + boost::uint64_t offset, const ConstBufferSequence& buffers, + WriteHandler handler) +{ + async_write_at(d, offset, buffers, transfer_all(), handler); +} + +#if !defined(BOOST_NO_IOSTREAM) + +namespace detail +{ + template + class write_at_streambuf_handler + { + public: + write_at_streambuf_handler( + asio::basic_streambuf& streambuf, + WriteHandler handler) + : streambuf_(streambuf), + handler_(handler) + { + } + + void operator()(const asio::error_code& ec, + std::size_t bytes_transferred) + { + streambuf_.consume(bytes_transferred); + handler_(ec, bytes_transferred); + } + + //private: + asio::basic_streambuf& streambuf_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + write_at_streambuf_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + write_at_streambuf_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + write_at_streambuf_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +inline void async_write_at(AsyncRandomAccessWriteDevice& d, + boost::uint64_t offset, asio::basic_streambuf& b, + CompletionCondition completion_condition, WriteHandler handler) +{ + async_write_at(d, offset, b.data(), completion_condition, + detail::write_at_streambuf_handler< + AsyncRandomAccessWriteDevice, Allocator, WriteHandler>(b, handler)); +} + +template +inline void async_write_at(AsyncRandomAccessWriteDevice& d, + boost::uint64_t offset, asio::basic_streambuf& b, + WriteHandler handler) +{ + async_write_at(d, offset, b, transfer_all(), handler); +} + +#endif // !defined(BOOST_NO_IOSTREAM) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WRITE_AT_IPP diff --git a/src/libs/resiprocate/contrib/asio/asio/io_service.hpp b/src/libs/resiprocate/contrib/asio/asio/io_service.hpp new file mode 100644 index 00000000..62d9e54f --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/io_service.hpp @@ -0,0 +1,658 @@ +// +// io_service.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IO_SERVICE_HPP +#define ASIO_IO_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error_code.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/reactor_fwd.hpp" +#include "asio/detail/service_registry_fwd.hpp" +#include "asio/detail/signal_init.hpp" +#include "asio/detail/task_io_service_fwd.hpp" +#include "asio/detail/win_iocp_io_service_fwd.hpp" +#include "asio/detail/winsock_init.hpp" +#include "asio/detail/wrapped_handler.hpp" + +namespace asio { + +class io_service; +template Service& use_service(io_service& ios); +template void add_service(io_service& ios, Service* svc); +template bool has_service(io_service& ios); + +#if defined(ASIO_HAS_IOCP) +namespace detail { typedef win_iocp_io_service io_service_impl; } +#else +namespace detail { typedef task_io_service io_service_impl; } +#endif + +/// Provides core I/O functionality. +/** + * The io_service class provides the core I/O functionality for users of the + * asynchronous I/O objects, including: + * + * @li asio::ip::tcp::socket + * @li asio::ip::tcp::acceptor + * @li asio::ip::udp::socket + * @li asio::deadline_timer. + * + * The io_service class also includes facilities intended for developers of + * custom asynchronous services. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe, with the exception that calling reset() while + * there are unfinished run(), run_one(), poll() or poll_one() calls results in + * undefined behaviour. + * + * @par Concepts: + * Dispatcher. + * + * @par Synchronous and asynchronous operations + * + * Synchronous operations on I/O objects implicitly run the io_service object + * for an individual operation. The io_service functions run(), run_one(), + * poll() or poll_one() must be called for the io_service to perform + * asynchronous operations on behalf of a C++ program. Notification that an + * asynchronous operation has completed is delivered by invocation of the + * associated handler. Handlers are invoked only by a thread that is currently + * calling any overload of run(), run_one(), poll() or poll_one() for the + * io_service. + * + * @par Effect of exceptions thrown from handlers + * + * If an exception is thrown from a handler, the exception is allowed to + * propagate through the throwing thread's invocation of run(), run_one(), + * poll() or poll_one(). No other threads that are calling any of these + * functions are affected. It is then the responsibility of the application to + * catch the exception. + * + * After the exception has been caught, the run(), run_one(), poll() or + * poll_one() call may be restarted @em without the need for an intervening + * call to reset(). This allows the thread to rejoin the io_service object's + * thread pool without impacting any other threads in the pool. + * + * For example: + * + * @code + * asio::io_service io_service; + * ... + * for (;;) + * { + * try + * { + * io_service.run(); + * break; // run() exited normally + * } + * catch (my_exception& e) + * { + * // Deal with exception as appropriate. + * } + * } + * @endcode + * + * @par Stopping the io_service from running out of work + * + * Some applications may need to prevent an io_service object's run() call from + * returning when there is no more work to do. For example, the io_service may + * be being run in a background thread that is launched prior to the + * application's asynchronous operations. The run() call may be kept running by + * creating an object of type asio::io_service::work: + * + * @code asio::io_service io_service; + * asio::io_service::work work(io_service); + * ... @endcode + * + * To effect a shutdown, the application will then need to call the io_service + * object's stop() member function. This will cause the io_service run() call + * to return as soon as possible, abandoning unfinished operations and without + * permitting ready handlers to be dispatched. + * + * Alternatively, if the application requires that all operations and handlers + * be allowed to finish normally, the work object may be explicitly destroyed. + * + * @code asio::io_service io_service; + * auto_ptr work( + * new asio::io_service::work(io_service)); + * ... + * work.reset(); // Allow run() to exit. @endcode + * + * @par The io_service class and I/O services + * + * Class io_service implements an extensible, type-safe, polymorphic set of I/O + * services, indexed by service type. An object of class io_service must be + * initialised before I/O objects such as sockets, resolvers and timers can be + * used. These I/O objects are distinguished by having constructors that accept + * an @c io_service& parameter. + * + * I/O services exist to manage the logical interface to the operating system on + * behalf of the I/O objects. In particular, there are resources that are shared + * across a class of I/O objects. For example, timers may be implemented in + * terms of a single timer queue. The I/O services manage these shared + * resources. + * + * Access to the services of an io_service is via three function templates, + * use_service(), add_service() and has_service(). + * + * In a call to @c use_service(), the type argument chooses a service, + * making available all members of the named type. If @c Service is not present + * in an io_service, an object of type @c Service is created and added to the + * io_service. A C++ program can check if an io_service implements a + * particular service with the function template @c has_service(). + * + * Service objects may be explicitly added to an io_service using the function + * template @c add_service(). If the @c Service is already present, the + * service_already_exists exception is thrown. If the owner of the service is + * not the same object as the io_service parameter, the invalid_service_owner + * exception is thrown. + * + * Once a service reference is obtained from an io_service object by calling + * use_service(), that reference remains usable as long as the owning io_service + * object exists. + * + * All I/O service implementations have io_service::service as a public base + * class. Custom I/O services may be implemented by deriving from this class and + * then added to an io_service using the facilities described above. + */ +class io_service + : private noncopyable +{ +private: + typedef detail::io_service_impl impl_type; +#if defined(ASIO_HAS_IOCP) + friend class detail::win_iocp_overlapped_ptr; +#endif + +public: + class work; + friend class work; + + class id; + + class service; + + class strand; + + /// Constructor. + io_service(); + + /// Constructor. + /** + * Construct with a hint about the required level of concurrency. + * + * @param concurrency_hint A suggestion to the implementation on how many + * threads it should allow to run simultaneously. + */ + explicit io_service(std::size_t concurrency_hint); + + /// Destructor. + /** + * On destruction, the io_service performs the following sequence of + * operations: + * + * @li For each service object @c svc in the io_service set, in reverse order + * of the beginning of service object lifetime, performs + * @c svc->shutdown_service(). + * + * @li Uninvoked handler objects that were scheduled for deferred invocation + * on the io_service, or any associated strand, are destroyed. + * + * @li For each service object @c svc in the io_service set, in reverse order + * of the beginning of service object lifetime, performs + * delete static_cast(svc). + * + * @note The destruction sequence described above permits programs to + * simplify their resource management by using @c shared_ptr<>. Where an + * object's lifetime is tied to the lifetime of a connection (or some other + * sequence of asynchronous operations), a @c shared_ptr to the object would + * be bound into the handlers for all asynchronous operations associated with + * it. This works as follows: + * + * @li When a single connection ends, all associated asynchronous operations + * complete. The corresponding handler objects are destroyed, and all + * @c shared_ptr references to the objects are destroyed. + * + * @li To shut down the whole program, the io_service function stop() is + * called to terminate any run() calls as soon as possible. The io_service + * destructor defined above destroys all handlers, causing all @c shared_ptr + * references to all connection objects to be destroyed. + */ + ~io_service(); + + /// Run the io_service object's event processing loop. + /** + * The run() function blocks until all work has finished and there are no + * more handlers to be dispatched, or until the io_service has been stopped. + * + * Multiple threads may call the run() function to set up a pool of threads + * from which the io_service may execute handlers. All threads that are + * waiting in the pool are equivalent and the io_service may choose any one + * of them to invoke a handler. + * + * The run() function may be safely called again once it has completed only + * after a call to reset(). + * + * @return The number of handlers that were executed. + * + * @throws asio::system_error Thrown on failure. + * + * @note The run() function must not be called from a thread that is currently + * calling one of run(), run_one(), poll() or poll_one() on the same + * io_service object. + * + * The poll() function may also be used to dispatch ready handlers, but + * without blocking. + */ + std::size_t run(); + + /// Run the io_service object's event processing loop. + /** + * The run() function blocks until all work has finished and there are no + * more handlers to be dispatched, or until the io_service has been stopped. + * + * Multiple threads may call the run() function to set up a pool of threads + * from which the io_service may execute handlers. All threads that are + * waiting in the pool are equivalent and the io_service may choose any one + * of them to invoke a handler. + * + * The run() function may be safely called again once it has completed only + * after a call to reset(). + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of handlers that were executed. + * + * @note The run() function must not be called from a thread that is currently + * calling one of run(), run_one(), poll() or poll_one() on the same + * io_service object. + * + * The poll() function may also be used to dispatch ready handlers, but + * without blocking. + */ + std::size_t run(asio::error_code& ec); + + /// Run the io_service object's event processing loop to execute at most one + /// handler. + /** + * The run_one() function blocks until one handler has been dispatched, or + * until the io_service has been stopped. + * + * @return The number of handlers that were executed. + * + * @throws asio::system_error Thrown on failure. + */ + std::size_t run_one(); + + /// Run the io_service object's event processing loop to execute at most one + /// handler. + /** + * The run_one() function blocks until one handler has been dispatched, or + * until the io_service has been stopped. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of handlers that were executed. + */ + std::size_t run_one(asio::error_code& ec); + + /// Run the io_service object's event processing loop to execute ready + /// handlers. + /** + * The poll() function runs handlers that are ready to run, without blocking, + * until the io_service has been stopped or there are no more ready handlers. + * + * @return The number of handlers that were executed. + * + * @throws asio::system_error Thrown on failure. + */ + std::size_t poll(); + + /// Run the io_service object's event processing loop to execute ready + /// handlers. + /** + * The poll() function runs handlers that are ready to run, without blocking, + * until the io_service has been stopped or there are no more ready handlers. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of handlers that were executed. + */ + std::size_t poll(asio::error_code& ec); + + /// Run the io_service object's event processing loop to execute one ready + /// handler. + /** + * The poll_one() function runs at most one handler that is ready to run, + * without blocking. + * + * @return The number of handlers that were executed. + * + * @throws asio::system_error Thrown on failure. + */ + std::size_t poll_one(); + + /// Run the io_service object's event processing loop to execute one ready + /// handler. + /** + * The poll_one() function runs at most one handler that is ready to run, + * without blocking. + * + * @param ec Set to indicate what error occurred, if any. + * + * @return The number of handlers that were executed. + */ + std::size_t poll_one(asio::error_code& ec); + + /// Stop the io_service object's event processing loop. + /** + * This function does not block, but instead simply signals the io_service to + * stop. All invocations of its run() or run_one() member functions should + * return as soon as possible. Subsequent calls to run(), run_one(), poll() + * or poll_one() will return immediately until reset() is called. + */ + void stop(); + + /// Reset the io_service in preparation for a subsequent run() invocation. + /** + * This function must be called prior to any second or later set of + * invocations of the run(), run_one(), poll() or poll_one() functions when a + * previous invocation of these functions returned due to the io_service + * being stopped or running out of work. This function allows the io_service + * to reset any internal state, such as a "stopped" flag. + * + * This function must not be called while there are any unfinished calls to + * the run(), run_one(), poll() or poll_one() functions. + */ + void reset(); + + /// Request the io_service to invoke the given handler. + /** + * This function is used to ask the io_service to execute the given handler. + * + * The io_service guarantees that the handler will only be called in a thread + * in which the run(), run_one(), poll() or poll_one() member functions is + * currently being invoked. The handler may be executed inside this function + * if the guarantee can be met. + * + * @param handler The handler to be called. The io_service will make + * a copy of the handler object as required. The function signature of the + * handler must be: @code void handler(); @endcode + * + * @note This function throws an exception only if: + * + * @li the handler's @c asio_handler_allocate function; or + * + * @li the handler's copy constructor + * + * throws an exception. + */ + template + void dispatch(CompletionHandler handler); + + /// Request the io_service to invoke the given handler and return immediately. + /** + * This function is used to ask the io_service to execute the given handler, + * but without allowing the io_service to call the handler from inside this + * function. + * + * The io_service guarantees that the handler will only be called in a thread + * in which the run(), run_one(), poll() or poll_one() member functions is + * currently being invoked. + * + * @param handler The handler to be called. The io_service will make + * a copy of the handler object as required. The function signature of the + * handler must be: @code void handler(); @endcode + * + * @note This function throws an exception only if: + * + * @li the handler's @c asio_handler_allocate function; or + * + * @li the handler's copy constructor + * + * throws an exception. + */ + template + void post(CompletionHandler handler); + + /// Create a new handler that automatically dispatches the wrapped handler + /// on the io_service. + /** + * This function is used to create a new handler function object that, when + * invoked, will automatically pass the wrapped handler to the io_service + * object's dispatch function. + * + * @param handler The handler to be wrapped. The io_service will make a copy + * of the handler object as required. The function signature of the handler + * must be: @code void handler(A1 a1, ... An an); @endcode + * + * @return A function object that, when invoked, passes the wrapped handler to + * the io_service object's dispatch function. Given a function object with the + * signature: + * @code R f(A1 a1, ... An an); @endcode + * If this function object is passed to the wrap function like so: + * @code io_service.wrap(f); @endcode + * then the return value is a function object with the signature + * @code void g(A1 a1, ... An an); @endcode + * that, when invoked, executes code equivalent to: + * @code io_service.dispatch(boost::bind(f, a1, ... an)); @endcode + */ + template +#if defined(GENERATING_DOCUMENTATION) + unspecified +#else + detail::wrapped_handler +#endif + wrap(Handler handler); + + /// Obtain the service object corresponding to the given type. + /** + * This function is used to locate a service object that corresponds to + * the given service type. If there is no existing implementation of the + * service, then the io_service will create a new instance of the service. + * + * @param ios The io_service object that owns the service. + * + * @return The service interface implementing the specified service type. + * Ownership of the service interface is not transferred to the caller. + */ + template + friend Service& use_service(io_service& ios); + + /// Add a service object to the io_service. + /** + * This function is used to add a service to the io_service. + * + * @param ios The io_service object that owns the service. + * + * @param svc The service object. On success, ownership of the service object + * is transferred to the io_service. When the io_service object is destroyed, + * it will destroy the service object by performing: + * @code delete static_cast(svc) @endcode + * + * @throws asio::service_already_exists Thrown if a service of the + * given type is already present in the io_service. + * + * @throws asio::invalid_service_owner Thrown if the service's owning + * io_service is not the io_service object specified by the ios parameter. + */ + template + friend void add_service(io_service& ios, Service* svc); + + /// Determine if an io_service contains a specified service type. + /** + * This function is used to determine whether the io_service contains a + * service object corresponding to the given service type. + * + * @param ios The io_service object that owns the service. + * + * @return A boolean indicating whether the io_service contains the service. + */ + template + friend bool has_service(io_service& ios); + +private: +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + detail::winsock_init<> init_; +#elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \ + || defined(__osf__) + detail::signal_init<> init_; +#endif + + // The service registry. + asio::detail::service_registry* service_registry_; + + // The implementation. + impl_type& impl_; +}; + +/// Class to inform the io_service when it has work to do. +/** + * The work class is used to inform the io_service when work starts and + * finishes. This ensures that the io_service object's run() function will not + * exit while work is underway, and that it does exit when there is no + * unfinished work remaining. + * + * The work class is copy-constructible so that it may be used as a data member + * in a handler class. It is not assignable. + */ +class io_service::work +{ +public: + /// Constructor notifies the io_service that work is starting. + /** + * The constructor is used to inform the io_service that some work has begun. + * This ensures that the io_service object's run() function will not exit + * while the work is underway. + */ + explicit work(asio::io_service& io_service); + + /// Copy constructor notifies the io_service that work is starting. + /** + * The constructor is used to inform the io_service that some work has begun. + * This ensures that the io_service object's run() function will not exit + * while the work is underway. + */ + work(const work& other); + + /// Destructor notifies the io_service that the work is complete. + /** + * The destructor is used to inform the io_service that some work has + * finished. Once the count of unfinished work reaches zero, the io_service + * object's run() function is permitted to exit. + */ + ~work(); + + /// (Deprecated: use get_io_service().) Get the io_service associated with the + /// work. + asio::io_service& io_service(); + + /// Get the io_service associated with the work. + asio::io_service& get_io_service(); + +private: + // Prevent assignment. + void operator=(const work& other); + + // The io_service. + asio::io_service& io_service_; +}; + +/// Class used to uniquely identify a service. +class io_service::id + : private noncopyable +{ +public: + /// Constructor. + id() {} +}; + +/// Base class for all io_service services. +class io_service::service + : private noncopyable +{ +public: + /// (Deprecated: use get_io_service().) Get the io_service object that owns + /// the service. + asio::io_service& io_service(); + + /// Get the io_service object that owns the service. + asio::io_service& get_io_service(); + +protected: + /// Constructor. + /** + * @param owner The io_service object that owns the service. + */ + service(asio::io_service& owner); + + /// Destructor. + virtual ~service(); + +private: + /// Destroy all user-defined handler objects owned by the service. + virtual void shutdown_service() = 0; + + friend class asio::detail::service_registry; + struct key + { + key() : type_info_(0), id_(0) {} + const std::type_info* type_info_; + const asio::io_service::id* id_; + } key_; + + asio::io_service& owner_; + service* next_; +}; + +/// Exception thrown when trying to add a duplicate service to an io_service. +class service_already_exists + : public std::logic_error +{ +public: + service_already_exists() + : std::logic_error("Service already exists.") + { + } +}; + +/// Exception thrown when trying to add a service object to an io_service where +/// the service has a different owner. +class invalid_service_owner + : public std::logic_error +{ +public: + invalid_service_owner() + : std::logic_error("Invalid service owner.") + { + } +}; + +} // namespace asio + +#include "asio/impl/io_service.ipp" + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IO_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/address.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/address.hpp new file mode 100644 index 00000000..92ee4ae4 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/address.hpp @@ -0,0 +1,284 @@ +// +// address.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_ADDRESS_HPP +#define ASIO_IP_ADDRESS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#if !defined(BOOST_NO_IOSTREAM) +# include +#endif // !defined(BOOST_NO_IOSTREAM) +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/ip/address_v4.hpp" +#include "asio/ip/address_v6.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { +namespace ip { + +/// Implements version-independent IP addresses. +/** + * The asio::ip::address class provides the ability to use either IP + * version 4 or version 6 addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address +{ +public: + /// Default constructor. + address() + : type_(ipv4), + ipv4_address_(), + ipv6_address_() + { + } + + /// Construct an address from an IPv4 address. + address(const asio::ip::address_v4& ipv4_address) + : type_(ipv4), + ipv4_address_(ipv4_address), + ipv6_address_() + { + } + + /// Construct an address from an IPv6 address. + address(const asio::ip::address_v6& ipv6_address) + : type_(ipv6), + ipv4_address_(), + ipv6_address_(ipv6_address) + { + } + + /// Copy constructor. + address(const address& other) + : type_(other.type_), + ipv4_address_(other.ipv4_address_), + ipv6_address_(other.ipv6_address_) + { + } + + /// Assign from another address. + address& operator=(const address& other) + { + type_ = other.type_; + ipv4_address_ = other.ipv4_address_; + ipv6_address_ = other.ipv6_address_; + return *this; + } + + /// Assign from an IPv4 address. + address& operator=(const asio::ip::address_v4& ipv4_address) + { + type_ = ipv4; + ipv4_address_ = ipv4_address; + ipv6_address_ = asio::ip::address_v6(); + return *this; + } + + /// Assign from an IPv6 address. + address& operator=(const asio::ip::address_v6& ipv6_address) + { + type_ = ipv6; + ipv4_address_ = asio::ip::address_v4(); + ipv6_address_ = ipv6_address; + return *this; + } + + /// Get whether the address is an IP version 4 address. + bool is_v4() const + { + return type_ == ipv4; + } + + /// Get whether the address is an IP version 6 address. + bool is_v6() const + { + return type_ == ipv6; + } + + /// Get the address as an IP version 4 address. + asio::ip::address_v4 to_v4() const + { + if (type_ != ipv4) + { + asio::system_error e( + asio::error::address_family_not_supported); + boost::throw_exception(e); + } + return ipv4_address_; + } + + /// Get the address as an IP version 6 address. + asio::ip::address_v6 to_v6() const + { + if (type_ != ipv6) + { + asio::system_error e( + asio::error::address_family_not_supported); + boost::throw_exception(e); + } + return ipv6_address_; + } + + /// Get the address as a string in dotted decimal format. + std::string to_string() const + { + if (type_ == ipv6) + return ipv6_address_.to_string(); + return ipv4_address_.to_string(); + } + + /// Get the address as a string in dotted decimal format. + std::string to_string(asio::error_code& ec) const + { + if (type_ == ipv6) + return ipv6_address_.to_string(ec); + return ipv4_address_.to_string(ec); + } + + /// Create an address from an IPv4 address string in dotted decimal form, + /// or from an IPv6 address in hexadecimal notation. + static address from_string(const char* str) + { + asio::error_code ec; + address addr = from_string(str, ec); + asio::detail::throw_error(ec); + return addr; + } + + /// Create an address from an IPv4 address string in dotted decimal form, + /// or from an IPv6 address in hexadecimal notation. + static address from_string(const char* str, asio::error_code& ec) + { + asio::ip::address_v6 ipv6_address = + asio::ip::address_v6::from_string(str, ec); + if (!ec) + { + address tmp; + tmp.type_ = ipv6; + tmp.ipv6_address_ = ipv6_address; + return tmp; + } + + asio::ip::address_v4 ipv4_address = + asio::ip::address_v4::from_string(str, ec); + if (!ec) + { + address tmp; + tmp.type_ = ipv4; + tmp.ipv4_address_ = ipv4_address; + return tmp; + } + + return address(); + } + + /// Create an address from an IPv4 address string in dotted decimal form, + /// or from an IPv6 address in hexadecimal notation. + static address from_string(const std::string& str) + { + return from_string(str.c_str()); + } + + /// Create an address from an IPv4 address string in dotted decimal form, + /// or from an IPv6 address in hexadecimal notation. + static address from_string(const std::string& str, + asio::error_code& ec) + { + return from_string(str.c_str(), ec); + } + + /// Compare two addresses for equality. + friend bool operator==(const address& a1, const address& a2) + { + if (a1.type_ != a2.type_) + return false; + if (a1.type_ == ipv6) + return a1.ipv6_address_ == a2.ipv6_address_; + return a1.ipv4_address_ == a2.ipv4_address_; + } + + /// Compare two addresses for inequality. + friend bool operator!=(const address& a1, const address& a2) + { + if (a1.type_ != a2.type_) + return true; + if (a1.type_ == ipv6) + return a1.ipv6_address_ != a2.ipv6_address_; + return a1.ipv4_address_ != a2.ipv4_address_; + } + + /// Compare addresses for ordering. + friend bool operator<(const address& a1, const address& a2) + { + if (a1.type_ < a2.type_) + return true; + if (a1.type_ > a2.type_) + return false; + if (a1.type_ == ipv6) + return a1.ipv6_address_ < a2.ipv6_address_; + return a1.ipv4_address_ < a2.ipv4_address_; + } + +private: + // The type of the address. + enum { ipv4, ipv6 } type_; + + // The underlying IPv4 address. + asio::ip::address_v4 ipv4_address_; + + // The underlying IPv6 address. + asio::ip::address_v6 ipv6_address_; +}; + +#if !defined(BOOST_NO_IOSTREAM) + +/// Output an address as a string. +/** + * Used to output a human-readable string for a specified address. + * + * @param os The output stream to which the string will be written. + * + * @param addr The address to be written. + * + * @return The output stream. + * + * @relates asio::ip::address + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address& addr) +{ + os << addr.to_string(); + return os; +} + +#endif // !defined(BOOST_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/address_v4.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/address_v4.hpp new file mode 100644 index 00000000..1b495560 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/address_v4.hpp @@ -0,0 +1,315 @@ +// +// address_v4.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_ADDRESS_V4_HPP +#define ASIO_IP_ADDRESS_V4_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#if !defined(BOOST_NO_IOSTREAM) +# include +#endif // !defined(BOOST_NO_IOSTREAM) +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { +namespace ip { + +/// Implements IP version 4 style addresses. +/** + * The asio::ip::address_v4 class provides the ability to use and + * manipulate IP version 4 addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address_v4 +{ +public: + /// The type used to represent an address as an array of bytes. + typedef boost::array bytes_type; + + /// Default constructor. + address_v4() + { + addr_.s_addr = 0; + } + + /// Construct an address from raw bytes. + explicit address_v4(const bytes_type& bytes) + { +#if UCHAR_MAX > 0xFF + if (bytes[0] > 0xFF || bytes[1] > 0xFF + || bytes[2] > 0xFF || bytes[3] > 0xFF) + { + std::out_of_range ex("address_v4 from bytes_type"); + boost::throw_exception(ex); + } +#endif // UCHAR_MAX > 0xFF + + using namespace std; // For memcpy. + memcpy(&addr_.s_addr, bytes.elems, 4); + } + + /// Construct an address from a unsigned long in host byte order. + explicit address_v4(unsigned long addr) + { +#if ULONG_MAX > 0xFFFFFFFF + if (addr > 0xFFFFFFFF) + { + std::out_of_range ex("address_v4 from unsigned long"); + boost::throw_exception(ex); + } +#endif // ULONG_MAX > 0xFFFFFFFF + + addr_.s_addr = asio::detail::socket_ops::host_to_network_long(addr); + } + + /// Copy constructor. + address_v4(const address_v4& other) + : addr_(other.addr_) + { + } + + /// Assign from another address. + address_v4& operator=(const address_v4& other) + { + addr_ = other.addr_; + return *this; + } + + /// Get the address in bytes, in network byte order. + bytes_type to_bytes() const + { + using namespace std; // For memcpy. + bytes_type bytes; + memcpy(bytes.elems, &addr_.s_addr, 4); + return bytes; + } + + /// Get the address as an unsigned long in host byte order + unsigned long to_ulong() const + { + return asio::detail::socket_ops::network_to_host_long(addr_.s_addr); + } + + /// Get the address as a string in dotted decimal format. + std::string to_string() const + { + asio::error_code ec; + std::string addr = to_string(ec); + asio::detail::throw_error(ec); + return addr; + } + + /// Get the address as a string in dotted decimal format. + std::string to_string(asio::error_code& ec) const + { + char addr_str[asio::detail::max_addr_v4_str_len]; + const char* addr = + asio::detail::socket_ops::inet_ntop(AF_INET, &addr_, addr_str, + asio::detail::max_addr_v4_str_len, 0, ec); + if (addr == 0) + return std::string(); + return addr; + } + + /// Create an address from an IP address string in dotted decimal form. + static address_v4 from_string(const char* str) + { + asio::error_code ec; + address_v4 addr = from_string(str, ec); + asio::detail::throw_error(ec); + return addr; + } + + /// Create an address from an IP address string in dotted decimal form. + static address_v4 from_string(const char* str, asio::error_code& ec) + { + address_v4 tmp; + if (asio::detail::socket_ops::inet_pton( + AF_INET, str, &tmp.addr_, 0, ec) <= 0) + return address_v4(); + return tmp; + } + + /// Create an address from an IP address string in dotted decimal form. + static address_v4 from_string(const std::string& str) + { + return from_string(str.c_str()); + } + + /// Create an address from an IP address string in dotted decimal form. + static address_v4 from_string(const std::string& str, + asio::error_code& ec) + { + return from_string(str.c_str(), ec); + } + + /// Determine whether the address is a class A address. + bool is_class_a() const + { + return IN_CLASSA(to_ulong()); + } + + /// Determine whether the address is a class B address. + bool is_class_b() const + { + return IN_CLASSB(to_ulong()); + } + + /// Determine whether the address is a class C address. + bool is_class_c() const + { + return IN_CLASSC(to_ulong()); + } + + /// Determine whether the address is a multicast address. + bool is_multicast() const + { + return IN_MULTICAST(to_ulong()); + } + + /// Compare two addresses for equality. + friend bool operator==(const address_v4& a1, const address_v4& a2) + { + return a1.addr_.s_addr == a2.addr_.s_addr; + } + + /// Compare two addresses for inequality. + friend bool operator!=(const address_v4& a1, const address_v4& a2) + { + return a1.addr_.s_addr != a2.addr_.s_addr; + } + + /// Compare addresses for ordering. + friend bool operator<(const address_v4& a1, const address_v4& a2) + { + return a1.to_ulong() < a2.to_ulong(); + } + + /// Compare addresses for ordering. + friend bool operator>(const address_v4& a1, const address_v4& a2) + { + return a1.to_ulong() > a2.to_ulong(); + } + + /// Compare addresses for ordering. + friend bool operator<=(const address_v4& a1, const address_v4& a2) + { + return a1.to_ulong() <= a2.to_ulong(); + } + + /// Compare addresses for ordering. + friend bool operator>=(const address_v4& a1, const address_v4& a2) + { + return a1.to_ulong() >= a2.to_ulong(); + } + + /// Obtain an address object that represents any address. + static address_v4 any() + { + return address_v4(static_cast(INADDR_ANY)); + } + + /// Obtain an address object that represents the loopback address. + static address_v4 loopback() + { + return address_v4(static_cast(INADDR_LOOPBACK)); + } + + /// Obtain an address object that represents the broadcast address. + static address_v4 broadcast() + { + return address_v4(static_cast(INADDR_BROADCAST)); + } + + /// Obtain an address object that represents the broadcast address that + /// corresponds to the specified address and netmask. + static address_v4 broadcast(const address_v4& addr, const address_v4& mask) + { + return address_v4(addr.to_ulong() | ~mask.to_ulong()); + } + + /// Obtain the netmask that corresponds to the address, based on its address + /// class. + static address_v4 netmask(const address_v4& addr) + { + if (addr.is_class_a()) + return address_v4(0xFF000000); + if (addr.is_class_b()) + return address_v4(0xFFFF0000); + if (addr.is_class_c()) + return address_v4(0xFFFFFF00); + return address_v4(0xFFFFFFFF); + } + +private: + // The underlying IPv4 address. + asio::detail::in4_addr_type addr_; +}; + +#if !defined(BOOST_NO_IOSTREAM) + +/// Output an address as a string. +/** + * Used to output a human-readable string for a specified address. + * + * @param os The output stream to which the string will be written. + * + * @param addr The address to be written. + * + * @return The output stream. + * + * @relates asio::ip::address_v4 + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address_v4& addr) +{ + asio::error_code ec; + std::string s = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::ios::failbit) + asio::detail::throw_error(ec); + else + os.setstate(std::ios_base::failbit); + } + else + for (std::string::iterator i = s.begin(); i != s.end(); ++i) + os << os.widen(*i); + return os; +} + +#endif // !defined(BOOST_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_V4_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/address_v6.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/address_v6.hpp new file mode 100644 index 00000000..8d2c0839 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/address_v6.hpp @@ -0,0 +1,429 @@ +// +// address_v6.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_ADDRESS_V6_HPP +#define ASIO_IP_ADDRESS_V6_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#if !defined(BOOST_NO_IOSTREAM) +# include +#endif // !defined(BOOST_NO_IOSTREAM) +#include +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/ip/address_v4.hpp" + +namespace asio { +namespace ip { + +/// Implements IP version 6 style addresses. +/** + * The asio::ip::address_v6 class provides the ability to use and + * manipulate IP version 6 addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address_v6 +{ +public: + /// The type used to represent an address as an array of bytes. + typedef boost::array bytes_type; + + /// Default constructor. + address_v6() + : scope_id_(0) + { + asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; + addr_ = tmp_addr; + } + + /// Construct an address from raw bytes and scope ID. + explicit address_v6(const bytes_type& bytes, unsigned long scope_id = 0) + : scope_id_(scope_id) + { +#if UCHAR_MAX > 0xFF + for (std::size_t i = 0; i < bytes.size(); ++i) + { + if (bytes[i] > 0xFF) + { + std::out_of_range ex("address_v6 from bytes_type"); + boost::throw_exception(ex); + } + } +#endif // UCHAR_MAX > 0xFF + + using namespace std; // For memcpy. + memcpy(addr_.s6_addr, bytes.elems, 16); + } + + /// Copy constructor. + address_v6(const address_v6& other) + : addr_(other.addr_), + scope_id_(other.scope_id_) + { + } + + /// Assign from another address. + address_v6& operator=(const address_v6& other) + { + addr_ = other.addr_; + scope_id_ = other.scope_id_; + return *this; + } + + /// The scope ID of the address. + /** + * Returns the scope ID associated with the IPv6 address. + */ + unsigned long scope_id() const + { + return scope_id_; + } + + /// The scope ID of the address. + /** + * Modifies the scope ID associated with the IPv6 address. + */ + void scope_id(unsigned long id) + { + scope_id_ = id; + } + + /// Get the address in bytes, in network byte order. + bytes_type to_bytes() const + { + using namespace std; // For memcpy. + bytes_type bytes; + memcpy(bytes.elems, addr_.s6_addr, 16); + return bytes; + } + + /// Get the address as a string. + std::string to_string() const + { + asio::error_code ec; + std::string addr = to_string(ec); + asio::detail::throw_error(ec); + return addr; + } + + /// Get the address as a string. + std::string to_string(asio::error_code& ec) const + { + char addr_str[asio::detail::max_addr_v6_str_len]; + const char* addr = + asio::detail::socket_ops::inet_ntop(AF_INET6, &addr_, addr_str, + asio::detail::max_addr_v6_str_len, scope_id_, ec); + if (addr == 0) + return std::string(); + return addr; + } + + /// Create an address from an IP address string. + static address_v6 from_string(const char* str) + { + asio::error_code ec; + address_v6 addr = from_string(str, ec); + asio::detail::throw_error(ec); + return addr; + } + + /// Create an address from an IP address string. + static address_v6 from_string(const char* str, asio::error_code& ec) + { + address_v6 tmp; + if (asio::detail::socket_ops::inet_pton( + AF_INET6, str, &tmp.addr_, &tmp.scope_id_, ec) <= 0) + return address_v6(); + return tmp; + } + + /// Create an address from an IP address string. + static address_v6 from_string(const std::string& str) + { + return from_string(str.c_str()); + } + + /// Create an address from an IP address string. + static address_v6 from_string(const std::string& str, + asio::error_code& ec) + { + return from_string(str.c_str(), ec); + } + + /// Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address. + address_v4 to_v4() const + { + if (!is_v4_mapped() && !is_v4_compatible()) + { + std::bad_cast ex; + boost::throw_exception(ex); + } + + address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12], + addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } }; + return address_v4(v4_bytes); + } + + /// Determine whether the address is a loopback address. + bool is_loopback() const + { +#if defined(__BORLANDC__) + return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) + && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) + && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) + && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) + && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) + && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) + && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) + && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1)); +#else + using namespace asio::detail; + return IN6_IS_ADDR_LOOPBACK(&addr_) != 0; +#endif + } + + /// Determine whether the address is unspecified. + bool is_unspecified() const + { +#if defined(__BORLANDC__) + return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) + && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) + && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) + && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) + && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) + && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) + && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) + && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0)); +#else + using namespace asio::detail; + return IN6_IS_ADDR_UNSPECIFIED(&addr_) != 0; +#endif + } + + /// Determine whether the address is link local. + bool is_link_local() const + { + using namespace asio::detail; + return IN6_IS_ADDR_LINKLOCAL(&addr_) != 0; + } + + /// Determine whether the address is site local. + bool is_site_local() const + { + using namespace asio::detail; + return IN6_IS_ADDR_SITELOCAL(&addr_) != 0; + } + + /// Determine whether the address is a mapped IPv4 address. + bool is_v4_mapped() const + { + using namespace asio::detail; + return IN6_IS_ADDR_V4MAPPED(&addr_) != 0; + } + + /// Determine whether the address is an IPv4-compatible address. + bool is_v4_compatible() const + { + using namespace asio::detail; + return IN6_IS_ADDR_V4COMPAT(&addr_) != 0; + } + + /// Determine whether the address is a multicast address. + bool is_multicast() const + { + using namespace asio::detail; + return IN6_IS_ADDR_MULTICAST(&addr_) != 0; + } + + /// Determine whether the address is a global multicast address. + bool is_multicast_global() const + { + using namespace asio::detail; + return IN6_IS_ADDR_MC_GLOBAL(&addr_) != 0; + } + + /// Determine whether the address is a link-local multicast address. + bool is_multicast_link_local() const + { + using namespace asio::detail; + return IN6_IS_ADDR_MC_LINKLOCAL(&addr_) != 0; + } + + /// Determine whether the address is a node-local multicast address. + bool is_multicast_node_local() const + { + using namespace asio::detail; + return IN6_IS_ADDR_MC_NODELOCAL(&addr_) != 0; + } + + /// Determine whether the address is a org-local multicast address. + bool is_multicast_org_local() const + { + using namespace asio::detail; + return IN6_IS_ADDR_MC_ORGLOCAL(&addr_) != 0; + } + + /// Determine whether the address is a site-local multicast address. + bool is_multicast_site_local() const + { + using namespace asio::detail; + return IN6_IS_ADDR_MC_SITELOCAL(&addr_) != 0; + } + + /// Compare two addresses for equality. + friend bool operator==(const address_v6& a1, const address_v6& a2) + { + using namespace std; // For memcmp. + return memcmp(&a1.addr_, &a2.addr_, + sizeof(asio::detail::in6_addr_type)) == 0 + && a1.scope_id_ == a2.scope_id_; + } + + /// Compare two addresses for inequality. + friend bool operator!=(const address_v6& a1, const address_v6& a2) + { + using namespace std; // For memcmp. + return memcmp(&a1.addr_, &a2.addr_, + sizeof(asio::detail::in6_addr_type)) != 0 + || a1.scope_id_ != a2.scope_id_; + } + + /// Compare addresses for ordering. + friend bool operator<(const address_v6& a1, const address_v6& a2) + { + using namespace std; // For memcmp. + int memcmp_result = memcmp(&a1.addr_, &a2.addr_, + sizeof(asio::detail::in6_addr_type)); + if (memcmp_result < 0) + return true; + if (memcmp_result > 0) + return false; + return a1.scope_id_ < a2.scope_id_; + } + + /// Compare addresses for ordering. + friend bool operator>(const address_v6& a1, const address_v6& a2) + { + return a2 < a1; + } + + /// Compare addresses for ordering. + friend bool operator<=(const address_v6& a1, const address_v6& a2) + { + return !(a2 < a1); + } + + /// Compare addresses for ordering. + friend bool operator>=(const address_v6& a1, const address_v6& a2) + { + return !(a1 < a2); + } + + /// Obtain an address object that represents any address. + static address_v6 any() + { + return address_v6(); + } + + /// Obtain an address object that represents the loopback address. + static address_v6 loopback() + { + address_v6 tmp; + asio::detail::in6_addr_type tmp_addr = IN6ADDR_LOOPBACK_INIT; + tmp.addr_ = tmp_addr; + return tmp; + } + + /// Create an IPv4-mapped IPv6 address. + static address_v6 v4_mapped(const address_v4& addr) + { + address_v4::bytes_type v4_bytes = addr.to_bytes(); + bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, + v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; + return address_v6(v6_bytes); + } + + /// Create an IPv4-compatible IPv6 address. + static address_v6 v4_compatible(const address_v4& addr) + { + address_v4::bytes_type v4_bytes = addr.to_bytes(); + bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; + return address_v6(v6_bytes); + } + +private: + // The underlying IPv6 address. + asio::detail::in6_addr_type addr_; + + // The scope ID associated with the address. + unsigned long scope_id_; +}; + +#if !defined(BOOST_NO_IOSTREAM) + +/// Output an address as a string. +/** + * Used to output a human-readable string for a specified address. + * + * @param os The output stream to which the string will be written. + * + * @param addr The address to be written. + * + * @return The output stream. + * + * @relates asio::ip::address_v6 + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, const address_v6& addr) +{ + asio::error_code ec; + std::string s = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::ios::failbit) + asio::detail::throw_error(ec); + else + os.setstate(std::ios_base::failbit); + } + else + for (std::string::iterator i = s.begin(); i != s.end(); ++i) + os << os.widen(*i); + return os; +} + +#endif // !defined(BOOST_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_V6_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/basic_endpoint.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/basic_endpoint.hpp new file mode 100644 index 00000000..4ad3f682 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/basic_endpoint.hpp @@ -0,0 +1,382 @@ +// +// basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_BASIC_ENDPOINT_HPP +#define ASIO_IP_BASIC_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#if !defined(BOOST_NO_IOSTREAM) +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# include +# endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# include +#endif // !defined(BOOST_NO_IOSTREAM) +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/ip/address.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace ip { + +/// Describes an endpoint for a version-independent IP socket. +/** + * The asio::ip::basic_endpoint class template describes an endpoint that + * may be associated with a particular socket. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * Endpoint. + */ +template +class basic_endpoint +{ +public: + /// The protocol type associated with the endpoint. + typedef InternetProtocol protocol_type; + + /// The type of the endpoint structure. This type is dependent on the + /// underlying implementation of the socket layer. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined data_type; +#else + typedef asio::detail::socket_addr_type data_type; +#endif + + /// Default constructor. + basic_endpoint() + : data_() + { + data_.v4.sin_family = AF_INET; + data_.v4.sin_port = 0; + data_.v4.sin_addr.s_addr = INADDR_ANY; + } + + /// Construct an endpoint using a port number, specified in the host's byte + /// order. The IP address will be the any address (i.e. INADDR_ANY or + /// in6addr_any). This constructor would typically be used for accepting new + /// connections. + /** + * @par Examples + * To initialise an IPv4 TCP endpoint for port 1234, use: + * @code + * asio::ip::tcp::endpoint ep(asio::ip::tcp::v4(), 1234); + * @endcode + * + * To specify an IPv6 UDP endpoint for port 9876, use: + * @code + * asio::ip::udp::endpoint ep(asio::ip::udp::v6(), 9876); + * @endcode + */ + basic_endpoint(const InternetProtocol& protocol, unsigned short port_num) + : data_() + { + using namespace std; // For memcpy. + if (protocol.family() == PF_INET) + { + data_.v4.sin_family = AF_INET; + data_.v4.sin_port = + asio::detail::socket_ops::host_to_network_short(port_num); + data_.v4.sin_addr.s_addr = INADDR_ANY; + } + else + { + data_.v6.sin6_family = AF_INET6; + data_.v6.sin6_port = + asio::detail::socket_ops::host_to_network_short(port_num); + data_.v6.sin6_flowinfo = 0; + asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; + data_.v6.sin6_addr = tmp_addr; + data_.v6.sin6_scope_id = 0; + } + } + + /// Construct an endpoint using a port number and an IP address. This + /// constructor may be used for accepting connections on a specific interface + /// or for making a connection to a remote endpoint. + basic_endpoint(const asio::ip::address& addr, unsigned short port_num) + : data_() + { + using namespace std; // For memcpy. + if (addr.is_v4()) + { + data_.v4.sin_family = AF_INET; + data_.v4.sin_port = + asio::detail::socket_ops::host_to_network_short(port_num); + data_.v4.sin_addr.s_addr = + asio::detail::socket_ops::host_to_network_long( + addr.to_v4().to_ulong()); + } + else + { + data_.v6.sin6_family = AF_INET6; + data_.v6.sin6_port = + asio::detail::socket_ops::host_to_network_short(port_num); + data_.v6.sin6_flowinfo = 0; + asio::ip::address_v6 v6_addr = addr.to_v6(); + asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes(); + memcpy(data_.v6.sin6_addr.s6_addr, bytes.elems, 16); + data_.v6.sin6_scope_id = v6_addr.scope_id(); + } + } + + /// Copy constructor. + basic_endpoint(const basic_endpoint& other) + : data_(other.data_) + { + } + + /// Assign from another endpoint. + basic_endpoint& operator=(const basic_endpoint& other) + { + data_ = other.data_; + return *this; + } + + /// The protocol associated with the endpoint. + protocol_type protocol() const + { + if (is_v4()) + return InternetProtocol::v4(); + return InternetProtocol::v6(); + } + + /// Get the underlying endpoint in the native type. + data_type* data() + { + return &data_.base; + } + + /// Get the underlying endpoint in the native type. + const data_type* data() const + { + return &data_.base; + } + + /// Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + if (is_v4()) + return sizeof(asio::detail::sockaddr_in4_type); + else + return sizeof(asio::detail::sockaddr_in6_type); + } + + /// Set the underlying size of the endpoint in the native type. + void resize(std::size_t size) + { + if (size > sizeof(asio::detail::sockaddr_storage_type)) + { + asio::system_error e(asio::error::invalid_argument); + boost::throw_exception(e); + } + } + + /// Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return sizeof(asio::detail::sockaddr_storage_type); + } + + /// Get the port associated with the endpoint. The port number is always in + /// the host's byte order. + unsigned short port() const + { + if (is_v4()) + { + return asio::detail::socket_ops::network_to_host_short( + data_.v4.sin_port); + } + else + { + return asio::detail::socket_ops::network_to_host_short( + data_.v6.sin6_port); + } + } + + /// Set the port associated with the endpoint. The port number is always in + /// the host's byte order. + void port(unsigned short port_num) + { + if (is_v4()) + { + data_.v4.sin_port + = asio::detail::socket_ops::host_to_network_short(port_num); + } + else + { + data_.v6.sin6_port + = asio::detail::socket_ops::host_to_network_short(port_num); + } + } + + /// Get the IP address associated with the endpoint. + asio::ip::address address() const + { + using namespace std; // For memcpy. + if (is_v4()) + { + return asio::ip::address_v4( + asio::detail::socket_ops::network_to_host_long( + data_.v4.sin_addr.s_addr)); + } + else + { + asio::ip::address_v6::bytes_type bytes; + memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16); + return asio::ip::address_v6(bytes, data_.v6.sin6_scope_id); + } + } + + /// Set the IP address associated with the endpoint. + void address(const asio::ip::address& addr) + { + basic_endpoint tmp_endpoint(addr, port()); + data_ = tmp_endpoint.data_; + } + + /// Compare two endpoints for equality. + friend bool operator==(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.address() == e2.address() && e1.port() == e2.port(); + } + + /// Compare two endpoints for inequality. + friend bool operator!=(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.address() != e2.address() || e1.port() != e2.port(); + } + + /// Compare endpoints for ordering. + friend bool operator<(const basic_endpoint& e1, + const basic_endpoint& e2) + { + if (e1.address() < e2.address()) + return true; + if (e1.address() != e2.address()) + return false; + return e1.port() < e2.port(); + } + +private: + // Helper function to determine whether the endpoint is IPv4. + bool is_v4() const + { + return data_.base.sa_family == AF_INET; + } + + // The underlying IP socket address. + union data_union + { + asio::detail::socket_addr_type base; + asio::detail::sockaddr_storage_type storage; + asio::detail::sockaddr_in4_type v4; + asio::detail::sockaddr_in6_type v6; + } data_; +}; + +#if !defined(BOOST_NO_IOSTREAM) + +/// Output an endpoint as a string. +/** + * Used to output a human-readable string for a specified endpoint. + * + * @param os The output stream to which the string will be written. + * + * @param endpoint The endpoint to be written. + * + * @return The output stream. + * + * @relates asio::ip::basic_endpoint + */ +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template +std::ostream& operator<<(std::ostream& os, + const basic_endpoint& endpoint) +{ + const address& addr = endpoint.address(); + asio::error_code ec; + std::string a = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::ios::failbit) + asio::detail::throw_error(ec); + else + os.setstate(std::ios_base::failbit); + } + else + { + std::ostringstream tmp_os; + tmp_os.imbue(std::locale::classic()); + if (addr.is_v4()) + tmp_os << a; + else + tmp_os << '[' << a << ']'; + tmp_os << ':' << endpoint.port(); + os << tmp_os.str(); + } + return os; +} +#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const basic_endpoint& endpoint) +{ + const address& addr = endpoint.address(); + asio::error_code ec; + std::string a = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::ios::failbit) + asio::detail::throw_error(ec); + else + os.setstate(std::ios_base::failbit); + } + else + { + std::ostringstream tmp_os; + tmp_os.imbue(std::locale::classic()); + if (addr.is_v4()) + tmp_os << a; + else + tmp_os << '[' << a << ']'; + tmp_os << ':' << endpoint.port(); + os << tmp_os.str(); + } + return os; +} +#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + +#endif // !defined(BOOST_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_ENDPOINT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/basic_resolver.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/basic_resolver.hpp new file mode 100644 index 00000000..43a37af3 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/basic_resolver.hpp @@ -0,0 +1,248 @@ +// +// basic_resolver.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_BASIC_RESOLVER_HPP +#define ASIO_IP_BASIC_RESOLVER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/basic_io_object.hpp" +#include "asio/error.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/ip/resolver_service.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { +namespace ip { + +/// Provides endpoint resolution functionality. +/** + * The basic_resolver class template provides the ability to resolve a query + * to a list of endpoints. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template > +class basic_resolver + : public basic_io_object +{ +public: + /// The protocol type. + typedef InternetProtocol protocol_type; + + /// The endpoint type. + typedef typename InternetProtocol::endpoint endpoint_type; + + /// The query type. + typedef basic_resolver_query query; + + /// The iterator type. + typedef basic_resolver_iterator iterator; + + /// Constructor. + /** + * This constructor creates a basic_resolver. + * + * @param io_service The io_service object that the resolver will use to + * dispatch handlers for any asynchronous operations performed on the timer. + */ + explicit basic_resolver(asio::io_service& io_service) + : basic_io_object(io_service) + { + } + + /// Cancel any asynchronous operations that are waiting on the resolver. + /** + * This function forces the completion of any pending asynchronous + * operations on the host resolver. The handler for each cancelled operation + * will be invoked with the asio::error::operation_aborted error code. + */ + void cancel() + { + return this->service.cancel(this->implementation); + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve a query into a list of endpoint entries. + * + * @param q A query object that determines what endpoints will be returned. + * + * @returns A forward-only iterator that can be used to traverse the list + * of endpoint entries. + * + * @throws asio::system_error Thrown on failure. + * + * @note A default constructed iterator represents the end of the list. + * + * A successful call to this function is guaranteed to return at least one + * entry. + */ + iterator resolve(const query& q) + { + asio::error_code ec; + iterator i = this->service.resolve(this->implementation, q, ec); + asio::detail::throw_error(ec); + return i; + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve a query into a list of endpoint entries. + * + * @param q A query object that determines what endpoints will be returned. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A forward-only iterator that can be used to traverse the list + * of endpoint entries. Returns a default constructed iterator if an error + * occurs. + * + * @note A default constructed iterator represents the end of the list. + * + * A successful call to this function is guaranteed to return at least one + * entry. + */ + iterator resolve(const query& q, asio::error_code& ec) + { + return this->service.resolve(this->implementation, q, ec); + } + + /// Asynchronously perform forward resolution of a query to a list of entries. + /** + * This function is used to asynchronously resolve a query into a list of + * endpoint entries. + * + * @param q A query object that determines what endpoints will be returned. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::iterator iterator // Forward-only iterator that can + * // be used to traverse the list + * // of endpoint entries. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note A default constructed iterator represents the end of the list. + * + * A successful resolve operation is guaranteed to pass at least one entry to + * the handler. + */ + template + void async_resolve(const query& q, ResolveHandler handler) + { + return this->service.async_resolve(this->implementation, q, handler); + } + + /// Perform reverse resolution of an endpoint to a list of entries. + /** + * This function is used to resolve an endpoint into a list of endpoint + * entries. + * + * @param e An endpoint object that determines what endpoints will be + * returned. + * + * @returns A forward-only iterator that can be used to traverse the list + * of endpoint entries. + * + * @throws asio::system_error Thrown on failure. + * + * @note A default constructed iterator represents the end of the list. + * + * A successful call to this function is guaranteed to return at least one + * entry. + */ + iterator resolve(const endpoint_type& e) + { + asio::error_code ec; + iterator i = this->service.resolve(this->implementation, e, ec); + asio::detail::throw_error(ec); + return i; + } + + /// Perform reverse resolution of an endpoint to a list of entries. + /** + * This function is used to resolve an endpoint into a list of endpoint + * entries. + * + * @param e An endpoint object that determines what endpoints will be + * returned. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A forward-only iterator that can be used to traverse the list + * of endpoint entries. Returns a default constructed iterator if an error + * occurs. + * + * @note A default constructed iterator represents the end of the list. + * + * A successful call to this function is guaranteed to return at least one + * entry. + */ + iterator resolve(const endpoint_type& e, asio::error_code& ec) + { + return this->service.resolve(this->implementation, e, ec); + } + + /// Asynchronously perform reverse resolution of an endpoint to a list of + /// entries. + /** + * This function is used to asynchronously resolve an endpoint into a list of + * endpoint entries. + * + * @param e An endpoint object that determines what endpoints will be + * returned. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::iterator iterator // Forward-only iterator that can + * // be used to traverse the list + * // of endpoint entries. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note A default constructed iterator represents the end of the list. + * + * A successful resolve operation is guaranteed to pass at least one entry to + * the handler. + */ + template + void async_resolve(const endpoint_type& e, ResolveHandler handler) + { + return this->service.async_resolve(this->implementation, e, handler); + } +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_RESOLVER_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/basic_resolver_entry.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/basic_resolver_entry.hpp new file mode 100644 index 00000000..09b144b1 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/basic_resolver_entry.hpp @@ -0,0 +1,95 @@ +// +// basic_resolver_entry.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_BASIC_RESOLVER_ENTRY_HPP +#define ASIO_IP_BASIC_RESOLVER_ENTRY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace ip { + +/// An entry produced by a resolver. +/** + * The asio::ip::basic_resolver_entry class template describes an entry + * as returned by a resolver. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_resolver_entry +{ +public: + /// The protocol type associated with the endpoint entry. + typedef InternetProtocol protocol_type; + + /// The endpoint type associated with the endpoint entry. + typedef typename InternetProtocol::endpoint endpoint_type; + + /// Default constructor. + basic_resolver_entry() + { + } + + /// Construct with specified endpoint, host name and service name. + basic_resolver_entry(const endpoint_type& endpoint, + const std::string& host_name, const std::string& service_name) + : endpoint_(endpoint), + host_name_(host_name), + service_name_(service_name) + { + } + + /// Get the endpoint associated with the entry. + endpoint_type endpoint() const + { + return endpoint_; + } + + /// Convert to the endpoint associated with the entry. + operator endpoint_type() const + { + return endpoint_; + } + + /// Get the host name associated with the entry. + std::string host_name() const + { + return host_name_; + } + + /// Get the service name associated with the entry. + std::string service_name() const + { + return service_name_; + } + +private: + endpoint_type endpoint_; + std::string host_name_; + std::string service_name_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_RESOLVER_ENTRY_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/basic_resolver_iterator.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/basic_resolver_iterator.hpp new file mode 100644 index 00000000..1982d625 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/basic_resolver_iterator.hpp @@ -0,0 +1,188 @@ +// +// basic_resolver_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP +#define ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/ip/basic_resolver_entry.hpp" + +namespace asio { +namespace ip { + +/// An iterator over the entries produced by a resolver. +/** + * The asio::ip::basic_resolver_iterator class template is used to define + * iterators over the results returned by a resolver. + * + * The iterator's value_type, obtained when the iterator is dereferenced, is: + * @code const basic_resolver_entry @endcode + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_resolver_iterator +#if defined(GENERATING_DOCUMENTATION) + : public std::iterator< +#else // defined(GENERATING_DOCUMENTATION) + : public boost::iterator< +#endif // defined(GENERATING_DOCUMENTATION) + std::forward_iterator_tag, + const basic_resolver_entry > +{ +public: + /// Default constructor creates an end iterator. + basic_resolver_iterator() + : index_(0) + { + } + + /// Create an iterator from an addrinfo list returned by getaddrinfo. + static basic_resolver_iterator create( + asio::detail::addrinfo_type* address_info, + const std::string& host_name, const std::string& service_name) + { + basic_resolver_iterator iter; + if (!address_info) + return iter; + + std::string actual_host_name = host_name; + if (address_info->ai_canonname) + actual_host_name = address_info->ai_canonname; + + iter.values_.reset(new values_type); + + while (address_info) + { + if (address_info->ai_family == PF_INET + || address_info->ai_family == PF_INET6) + { + using namespace std; // For memcpy. + typename InternetProtocol::endpoint endpoint; + endpoint.resize(static_cast(address_info->ai_addrlen)); + memcpy(endpoint.data(), address_info->ai_addr, + address_info->ai_addrlen); + iter.values_->push_back( + basic_resolver_entry(endpoint, + actual_host_name, service_name)); + } + address_info = address_info->ai_next; + } + + return iter; + } + + /// Create an iterator from an endpoint, host name and service name. + static basic_resolver_iterator create( + const typename InternetProtocol::endpoint& endpoint, + const std::string& host_name, const std::string& service_name) + { + basic_resolver_iterator iter; + iter.values_.reset(new values_type); + iter.values_->push_back( + basic_resolver_entry( + endpoint, host_name, service_name)); + return iter; + } + + /// Dereference an iterator. + const basic_resolver_entry& operator*() const + { + return dereference(); + } + + /// Dereference an iterator. + const basic_resolver_entry* operator->() const + { + return &dereference(); + } + + /// Increment operator (prefix). + basic_resolver_iterator& operator++() + { + increment(); + return *this; + } + + /// Increment operator (postfix). + basic_resolver_iterator operator++(int) + { + basic_resolver_iterator tmp(*this); + ++*this; + return tmp; + } + + /// Test two iterators for equality. + friend bool operator==(const basic_resolver_iterator& a, + const basic_resolver_iterator& b) + { + return a.equal(b); + } + + /// Test two iterators for inequality. + friend bool operator!=(const basic_resolver_iterator& a, + const basic_resolver_iterator& b) + { + return !a.equal(b); + } + +private: + void increment() + { + if (++index_ == values_->size()) + { + // Reset state to match a default constructed end iterator. + values_.reset(); + index_ = 0; + } + } + + bool equal(const basic_resolver_iterator& other) const + { + if (!values_ && !other.values_) + return true; + if (values_ != other.values_) + return false; + return index_ == other.index_; + } + + const basic_resolver_entry& dereference() const + { + return (*values_)[index_]; + } + + typedef std::vector > values_type; + boost::shared_ptr values_; + std::size_t index_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/basic_resolver_query.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/basic_resolver_query.hpp new file mode 100644 index 00000000..3cbb335c --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/basic_resolver_query.hpp @@ -0,0 +1,248 @@ +// +// basic_resolver_query.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_BASIC_RESOLVER_QUERY_HPP +#define ASIO_IP_BASIC_RESOLVER_QUERY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/socket_ops.hpp" +#include "asio/ip/resolver_query_base.hpp" + +namespace asio { +namespace ip { + +/// An query to be passed to a resolver. +/** + * The asio::ip::basic_resolver_query class template describes a query + * that can be passed to a resolver. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_resolver_query + : public resolver_query_base +{ +public: + /// The protocol type associated with the endpoint query. + typedef InternetProtocol protocol_type; + + /// Construct with specified service name for any protocol. + /** + * This constructor is typically used to perform name resolution for local + * service binding. + * + * @param service_name A string identifying the requested service. This may + * be a descriptive name or a numeric string corresponding to a port number. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for local service + * binding. + * + * @note On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + basic_resolver_query(const std::string& service_name, + resolver_query_base::flags resolve_flags = passive | address_configured) + : hints_(), + host_name_(), + service_name_(service_name) + { + typename InternetProtocol::endpoint endpoint; + hints_.ai_flags = static_cast(resolve_flags); + hints_.ai_family = PF_UNSPEC; + hints_.ai_socktype = endpoint.protocol().type(); + hints_.ai_protocol = endpoint.protocol().protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Construct with specified service name for a given protocol. + /** + * This constructor is typically used to perform name resolution for local + * service binding with a specific protocol version. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param service_name A string identifying the requested service. This may + * be a descriptive name or a numeric string corresponding to a port number. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for local service + * binding. + * + * @note On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + basic_resolver_query(const protocol_type& protocol, + const std::string& service_name, + resolver_query_base::flags resolve_flags = passive | address_configured) + : hints_(), + host_name_(), + service_name_(service_name) + { + hints_.ai_flags = static_cast(resolve_flags); + hints_.ai_family = protocol.family(); + hints_.ai_socktype = protocol.type(); + hints_.ai_protocol = protocol.protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Construct with specified host name and service name for any protocol. + /** + * This constructor is typically used to perform name resolution for + * communication with remote hosts. + * + * @param host_name A string identifying a location. May be a descriptive name + * or a numeric address string. If an empty string and the passive flag has + * been specified, the resolved endpoints are suitable for local service + * binding. If an empty string and passive is not specified, the resolved + * endpoints will use the loopback address. + * + * @param service_name A string identifying the requested service. This may + * be a descriptive name or a numeric string corresponding to a port number. + * May be an empty string, in which case all resolved endpoints will have a + * port number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + basic_resolver_query(const std::string& host_name, + const std::string& service_name, + resolver_query_base::flags resolve_flags = address_configured) + : hints_(), + host_name_(host_name), + service_name_(service_name) + { + typename InternetProtocol::endpoint endpoint; + hints_.ai_flags = static_cast(resolve_flags); + hints_.ai_family = PF_UNSPEC; + hints_.ai_socktype = endpoint.protocol().type(); + hints_.ai_protocol = endpoint.protocol().protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Construct with specified host name and service name for a given protocol. + /** + * This constructor is typically used to perform name resolution for + * communication with remote hosts. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host_name A string identifying a location. May be a descriptive name + * or a numeric address string. If an empty string and the passive flag has + * been specified, the resolved endpoints are suitable for local service + * binding. If an empty string and passive is not specified, the resolved + * endpoints will use the loopback address. + * + * @param service_name A string identifying the requested service. This may + * be a descriptive name or a numeric string corresponding to a port number. + * May be an empty string, in which case all resolved endpoints will have a + * port number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @note On POSIX systems, host names may be locally defined in the file + * /etc/hosts. On Windows, host names may be defined in the file + * c:\\windows\\system32\\drivers\\etc\\hosts. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * /etc/services. On Windows, service names may be found in the file + * c:\\windows\\system32\\drivers\\etc\\services. Operating systems + * may use additional locations when resolving service names. + */ + basic_resolver_query(const protocol_type& protocol, + const std::string& host_name, const std::string& service_name, + resolver_query_base::flags resolve_flags = address_configured) + : hints_(), + host_name_(host_name), + service_name_(service_name) + { + hints_.ai_flags = static_cast(resolve_flags); + hints_.ai_family = protocol.family(); + hints_.ai_socktype = protocol.type(); + hints_.ai_protocol = protocol.protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Get the hints associated with the query. + const asio::detail::addrinfo_type& hints() const + { + return hints_; + } + + /// Get the host name associated with the query. + std::string host_name() const + { + return host_name_; + } + + /// Get the service name associated with the query. + std::string service_name() const + { + return service_name_; + } + +private: + asio::detail::addrinfo_type hints_; + std::string host_name_; + std::string service_name_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_RESOLVER_QUERY_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/detail/socket_option.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/detail/socket_option.hpp new file mode 100644 index 00000000..00045f86 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/detail/socket_option.hpp @@ -0,0 +1,594 @@ +// +// socket_option.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_DETAIL_SOCKET_OPTION_HPP +#define ASIO_IP_DETAIL_SOCKET_OPTION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/address.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace ip { +namespace detail { +namespace socket_option { + +// Helper template for implementing multicast enable loopback options. +template +class multicast_enable_loopback +{ +public: +#if defined(__sun) || defined(__osf__) + typedef unsigned char ipv4_value_type; + typedef unsigned char ipv6_value_type; +#elif defined(_AIX) || defined(__hpux) || defined(__QNXNTO__) + typedef unsigned char ipv4_value_type; + typedef unsigned int ipv6_value_type; +#else + typedef int ipv4_value_type; + typedef int ipv6_value_type; +#endif + + // Default constructor. + multicast_enable_loopback() + : ipv4_value_(0), + ipv6_value_(0) + { + } + + // Construct with a specific option value. + explicit multicast_enable_loopback(bool v) + : ipv4_value_(v ? 1 : 0), + ipv6_value_(v ? 1 : 0) + { + } + + // Set the value of the boolean. + multicast_enable_loopback& operator=(bool v) + { + ipv4_value_ = v ? 1 : 0; + ipv6_value_ = v ? 1 : 0; + return *this; + } + + // Get the current value of the boolean. + bool value() const + { + return !!ipv4_value_; + } + + // Convert to bool. + operator bool() const + { + return !!ipv4_value_; + } + + // Test for false. + bool operator!() const + { + return !ipv4_value_; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the boolean data. + template + void* data(const Protocol& protocol) + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the address of the boolean data. + template + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the boolean data. + template + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + + // Set the size of the boolean data. + template + void resize(const Protocol& protocol, std::size_t s) + { + if (protocol.family() == PF_INET6) + { + if (s != sizeof(ipv6_value_)) + { + std::length_error ex("multicast_enable_loopback socket option resize"); + boost::throw_exception(ex); + } + ipv4_value_ = ipv6_value_ ? 1 : 0; + } + else + { + if (s != sizeof(ipv4_value_)) + { + std::length_error ex("multicast_enable_loopback socket option resize"); + boost::throw_exception(ex); + } + ipv6_value_ = ipv4_value_ ? 1 : 0; + } + } + +private: + ipv4_value_type ipv4_value_; + ipv6_value_type ipv6_value_; +}; + +// Helper template for implementing unicast hops options. +template +class unicast_hops +{ +public: + // Default constructor. + unicast_hops() + : value_(0) + { + } + + // Construct with a specific option value. + explicit unicast_hops(int v) + : value_(v) + { + } + + // Set the value of the option. + unicast_hops& operator=(int v) + { + value_ = v; + return *this; + } + + // Get the current value of the option. + int value() const + { + return value_; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the data. + template + int* data(const Protocol&) + { + return &value_; + } + + // Get the address of the data. + template + const int* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the data. + template + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the data. + template + void resize(const Protocol&, std::size_t s) + { + if (s != sizeof(value_)) + { + std::length_error ex("unicast hops socket option resize"); + boost::throw_exception(ex); + } +#if defined(__hpux) + if (value_ < 0) + value_ = value_ & 0xFF; +#endif + } + +private: + int value_; +}; + +// Helper template for implementing multicast hops options. +template +class multicast_hops +{ +public: +#if defined(BOOST_WINDOWS) && defined(UNDER_CE) + typedef int ipv4_value_type; +#else + typedef unsigned char ipv4_value_type; +#endif + typedef int ipv6_value_type; + + // Default constructor. + multicast_hops() + : ipv4_value_(0), + ipv6_value_(0) + { + } + + // Construct with a specific option value. + explicit multicast_hops(int v) + { + if (v < 0 || v > 255) + { + std::out_of_range ex("multicast hops value out of range"); + boost::throw_exception(ex); + } + ipv4_value_ = (ipv4_value_type)v; + ipv6_value_ = v; + } + + // Set the value of the option. + multicast_hops& operator=(int v) + { + if (v < 0 || v > 255) + { + std::out_of_range ex("multicast hops value out of range"); + boost::throw_exception(ex); + } + ipv4_value_ = (ipv4_value_type)v; + ipv6_value_ = v; + return *this; + } + + // Get the current value of the option. + int value() const + { + return ipv6_value_; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the data. + template + void* data(const Protocol& protocol) + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the address of the data. + template + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the data. + template + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + + // Set the size of the data. + template + void resize(const Protocol& protocol, std::size_t s) + { + if (protocol.family() == PF_INET6) + { + if (s != sizeof(ipv6_value_)) + { + std::length_error ex("multicast hops socket option resize"); + boost::throw_exception(ex); + } + if (ipv6_value_ < 0) + ipv4_value_ = 0; + else if (ipv6_value_ > 255) + ipv4_value_ = 255; + else + ipv4_value_ = (ipv4_value_type)ipv6_value_; + } + else + { + if (s != sizeof(ipv4_value_)) + { + std::length_error ex("multicast hops socket option resize"); + boost::throw_exception(ex); + } + ipv6_value_ = ipv4_value_; + } + } + +private: + ipv4_value_type ipv4_value_; + ipv6_value_type ipv6_value_; +}; + +// Helper template for implementing ip_mreq-based options. +template +class multicast_request +{ +public: + // Default constructor. + multicast_request() + { + ipv4_value_.imr_multiaddr.s_addr = + asio::detail::socket_ops::host_to_network_long( + asio::ip::address_v4::any().to_ulong()); + ipv4_value_.imr_interface.s_addr = + asio::detail::socket_ops::host_to_network_long( + asio::ip::address_v4::any().to_ulong()); + + asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; + ipv6_value_.ipv6mr_multiaddr = tmp_addr; + ipv6_value_.ipv6mr_interface = 0; + } + + // Construct with multicast address only. + explicit multicast_request(const asio::ip::address& multicast_address) + { + if (multicast_address.is_v6()) + { + ipv4_value_.imr_multiaddr.s_addr = + asio::detail::socket_ops::host_to_network_long( + asio::ip::address_v4::any().to_ulong()); + ipv4_value_.imr_interface.s_addr = + asio::detail::socket_ops::host_to_network_long( + asio::ip::address_v4::any().to_ulong()); + + using namespace std; // For memcpy. + asio::ip::address_v6 ipv6_address = multicast_address.to_v6(); + asio::ip::address_v6::bytes_type bytes = ipv6_address.to_bytes(); + memcpy(ipv6_value_.ipv6mr_multiaddr.s6_addr, bytes.elems, 16); + ipv6_value_.ipv6mr_interface = 0; + } + else + { + ipv4_value_.imr_multiaddr.s_addr = + asio::detail::socket_ops::host_to_network_long( + multicast_address.to_v4().to_ulong()); + ipv4_value_.imr_interface.s_addr = + asio::detail::socket_ops::host_to_network_long( + asio::ip::address_v4::any().to_ulong()); + + asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; + ipv6_value_.ipv6mr_multiaddr = tmp_addr; + ipv6_value_.ipv6mr_interface = 0; + } + } + + // Construct with multicast address and IPv4 address specifying an interface. + explicit multicast_request( + const asio::ip::address_v4& multicast_address, + const asio::ip::address_v4& network_interface + = asio::ip::address_v4::any()) + { + ipv4_value_.imr_multiaddr.s_addr = + asio::detail::socket_ops::host_to_network_long( + multicast_address.to_ulong()); + ipv4_value_.imr_interface.s_addr = + asio::detail::socket_ops::host_to_network_long( + network_interface.to_ulong()); + + asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; + ipv6_value_.ipv6mr_multiaddr = tmp_addr; + ipv6_value_.ipv6mr_interface = 0; + } + + // Construct with multicast address and IPv6 network interface index. + explicit multicast_request( + const asio::ip::address_v6& multicast_address, + unsigned long network_interface = 0) + { + ipv4_value_.imr_multiaddr.s_addr = + asio::detail::socket_ops::host_to_network_long( + asio::ip::address_v4::any().to_ulong()); + ipv4_value_.imr_interface.s_addr = + asio::detail::socket_ops::host_to_network_long( + asio::ip::address_v4::any().to_ulong()); + + using namespace std; // For memcpy. + asio::ip::address_v6::bytes_type bytes = + multicast_address.to_bytes(); + memcpy(ipv6_value_.ipv6mr_multiaddr.s6_addr, bytes.elems, 16); + ipv6_value_.ipv6mr_interface = network_interface; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the option data. + template + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the option data. + template + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + +private: + asio::detail::in4_mreq_type ipv4_value_; + asio::detail::in6_mreq_type ipv6_value_; +}; + +// Helper template for implementing options that specify a network interface. +template +class network_interface +{ +public: + // Default constructor. + network_interface() + { + ipv4_value_.s_addr = + asio::detail::socket_ops::host_to_network_long( + asio::ip::address_v4::any().to_ulong()); + ipv6_value_ = 0; + } + + // Construct with IPv4 interface. + explicit network_interface(const asio::ip::address_v4& ipv4_interface) + { + ipv4_value_.s_addr = + asio::detail::socket_ops::host_to_network_long( + ipv4_interface.to_ulong()); + ipv6_value_ = 0; + } + + // Construct with IPv6 interface. + explicit network_interface(unsigned int ipv6_interface) + { + ipv4_value_.s_addr = + asio::detail::socket_ops::host_to_network_long( + asio::ip::address_v4::any().to_ulong()); + ipv6_value_ = ipv6_interface; + } + + // Get the level of the socket option. + template + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the option data. + template + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the option data. + template + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + +private: + asio::detail::in4_addr_type ipv4_value_; + unsigned int ipv6_value_; +}; + +} // namespace socket_option +} // namespace detail +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_DETAIL_SOCKET_OPTION_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/host_name.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/host_name.hpp new file mode 100644 index 00000000..f24ce1a2 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/host_name.hpp @@ -0,0 +1,62 @@ +// +// host_name.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_HOST_NAME_HPP +#define ASIO_IP_HOST_NAME_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { +namespace ip { + +/// Get the current host name. +std::string host_name(); + +/// Get the current host name. +std::string host_name(asio::error_code& ec); + +inline std::string host_name() +{ + char name[1024]; + asio::error_code ec; + if (asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) + { + asio::detail::throw_error(ec); + return std::string(); + } + return std::string(name); +} + +inline std::string host_name(asio::error_code& ec) +{ + char name[1024]; + if (asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) + return std::string(); + return std::string(name); +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_HOST_NAME_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/icmp.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/icmp.hpp new file mode 100644 index 00000000..d76b4d1a --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/icmp.hpp @@ -0,0 +1,118 @@ +// +// icmp.hpp +// ~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_ICMP_HPP +#define ASIO_IP_ICMP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/basic_raw_socket.hpp" +#include "asio/ip/basic_endpoint.hpp" +#include "asio/ip/basic_resolver.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace ip { + +/// Encapsulates the flags needed for ICMP. +/** + * The asio::ip::icmp class contains flags necessary for ICMP sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol, InternetProtocol. + */ +class icmp +{ +public: + /// The type of a ICMP endpoint. + typedef basic_endpoint endpoint; + + /// (Deprecated: use resolver::query.) The type of a resolver query. + typedef basic_resolver_query resolver_query; + + /// (Deprecated: use resolver::iterator.) The type of a resolver iterator. + typedef basic_resolver_iterator resolver_iterator; + + /// Construct to represent the IPv4 ICMP protocol. + static icmp v4() + { + return icmp(IPPROTO_ICMP, PF_INET); + } + + /// Construct to represent the IPv6 ICMP protocol. + static icmp v6() + { + return icmp(IPPROTO_ICMPV6, PF_INET6); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_RAW; + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return protocol_; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// The ICMP socket type. + typedef basic_raw_socket socket; + + /// The ICMP resolver type. + typedef basic_resolver resolver; + + /// Compare two protocols for equality. + friend bool operator==(const icmp& p1, const icmp& p2) + { + return p1.protocol_ == p2.protocol_ && p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const icmp& p1, const icmp& p2) + { + return p1.protocol_ != p2.protocol_ || p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit icmp(int protocol, int family) + : protocol_(protocol), + family_(family) + { + } + + int protocol_; + int family_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ICMP_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/multicast.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/multicast.hpp new file mode 100644 index 00000000..eeedc6ce --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/multicast.hpp @@ -0,0 +1,181 @@ +// +// multicast.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_MULTICAST_HPP +#define ASIO_IP_MULTICAST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/detail/socket_option.hpp" + +namespace asio { +namespace ip { +namespace multicast { + +/// Socket option to join a multicast group on a specified interface. +/** + * Implements the IPPROTO_IP/IP_ADD_MEMBERSHIP socket option. + * + * @par Examples + * Setting the option to join a multicast group: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::ip::address multicast_address = + * asio::ip::address::from_string("225.0.0.1"); + * asio::ip::multicast::join_group option(multicast_address); + * socket.set_option(option); + * @endcode + * + * @par Concepts: + * SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined join_group; +#else +typedef asio::ip::detail::socket_option::multicast_request< + IPPROTO_IP, IP_ADD_MEMBERSHIP, IPPROTO_IPV6, IPV6_JOIN_GROUP> join_group; +#endif + +/// Socket option to leave a multicast group on a specified interface. +/** + * Implements the IPPROTO_IP/IP_DROP_MEMBERSHIP socket option. + * + * @par Examples + * Setting the option to leave a multicast group: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::ip::address multicast_address = + * asio::ip::address::from_string("225.0.0.1"); + * asio::ip::multicast::leave_group option(multicast_address); + * socket.set_option(option); + * @endcode + * + * @par Concepts: + * SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined leave_group; +#else +typedef asio::ip::detail::socket_option::multicast_request< + IPPROTO_IP, IP_DROP_MEMBERSHIP, IPPROTO_IPV6, IPV6_LEAVE_GROUP> leave_group; +#endif + +/// Socket option for local interface to use for outgoing multicast packets. +/** + * Implements the IPPROTO_IP/IP_MULTICAST_IF socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::ip::address_v4 local_interface = + * asio::ip::address_v4::from_string("1.2.3.4"); + * asio::ip::multicast::outbound_interface option(local_interface); + * socket.set_option(option); + * @endcode + * + * @par Concepts: + * SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined outbound_interface; +#else +typedef asio::ip::detail::socket_option::network_interface< + IPPROTO_IP, IP_MULTICAST_IF, IPPROTO_IPV6, IPV6_MULTICAST_IF> + outbound_interface; +#endif + +/// Socket option for time-to-live associated with outgoing multicast packets. +/** + * Implements the IPPROTO_IP/IP_MULTICAST_TTL socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::ip::multicast::hops option(4); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::ip::multicast::hops option; + * socket.get_option(option); + * int ttl = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined hops; +#else +typedef asio::ip::detail::socket_option::multicast_hops< + IPPROTO_IP, IP_MULTICAST_TTL, IPPROTO_IPV6, IPV6_MULTICAST_HOPS> hops; +#endif + +/// Socket option determining whether outgoing multicast packets will be +/// received on the same socket if it is a member of the multicast group. +/** + * Implements the IPPROTO_IP/IP_MULTICAST_LOOP socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::ip::multicast::enable_loopback option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::ip::multicast::enable_loopback option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined enable_loopback; +#else +typedef asio::ip::detail::socket_option::multicast_enable_loopback< + IPPROTO_IP, IP_MULTICAST_LOOP, IPPROTO_IPV6, IPV6_MULTICAST_LOOP> + enable_loopback; +#endif + +} // namespace multicast +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_MULTICAST_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/resolver_query_base.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/resolver_query_base.hpp new file mode 100644 index 00000000..5a0acea8 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/resolver_query_base.hpp @@ -0,0 +1,158 @@ +// +// resolver_query_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_RESOLVER_QUERY_BASE_HPP +#define ASIO_IP_RESOLVER_QUERY_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace ip { + +/// The resolver_query_base class is used as a base for the +/// basic_resolver_query class templates to provide a common place to define +/// the flag constants. +class resolver_query_base +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// A bitmask type (C++ Std [lib.bitmask.types]). + typedef unspecified flags; + + /// Determine the canonical name of the host specified in the query. + static const flags canonical_name = implementation_defined; + + /// Indicate that returned endpoint is intended for use as a locally bound + /// socket endpoint. + static const flags passive = implementation_defined; + + /// Host name should be treated as a numeric string defining an IPv4 or IPv6 + /// address and no name resolution should be attempted. + static const flags numeric_host = implementation_defined; + + /// Service name should be treated as a numeric string defining a port number + /// and no name resolution should be attempted. + static const flags numeric_service = implementation_defined; + + /// If the query protocol family is specified as IPv6, return IPv4-mapped + /// IPv6 addresses on finding no IPv6 addresses. + static const flags v4_mapped = implementation_defined; + + /// If used with v4_mapped, return all matching IPv6 and IPv4 addresses. + static const flags all_matching = implementation_defined; + + /// Only return IPv4 addresses if a non-loopback IPv4 address is configured + /// for the system. Only return IPv6 addresses if a non-loopback IPv6 address + /// is configured for the system. + static const flags address_configured = implementation_defined; +#else + enum flags + { + canonical_name = AI_CANONNAME, + passive = AI_PASSIVE, + numeric_host = AI_NUMERICHOST, +# if defined(AI_NUMERICSERV) + numeric_service = AI_NUMERICSERV, +# else + numeric_service = 0, +# endif + // Note: QNX Neutrino 6.3 defines AI_V4MAPPED, AI_ALL and AI_ADDRCONFIG but + // does not implement them. Therefore they are specifically excluded here. +# if defined(AI_V4MAPPED) && !defined(__QNXNTO__) + v4_mapped = AI_V4MAPPED, +# else + v4_mapped = 0, +# endif +# if defined(AI_ALL) && !defined(__QNXNTO__) + all_matching = AI_ALL, +# else + all_matching = 0, +# endif +# if defined(AI_ADDRCONFIG) && !defined(__QNXNTO__) + address_configured = AI_ADDRCONFIG +# else + address_configured = 0 +# endif + }; + + // Implement bitmask operations as shown in C++ Std [lib.bitmask.types]. + + friend flags operator&(flags x, flags y) + { + return static_cast( + static_cast(x) & static_cast(y)); + } + + friend flags operator|(flags x, flags y) + { + return static_cast( + static_cast(x) | static_cast(y)); + } + + friend flags operator^(flags x, flags y) + { + return static_cast( + static_cast(x) ^ static_cast(y)); + } + + friend flags operator~(flags x) + { + return static_cast(static_cast(~x)); + } + + friend flags& operator&=(flags& x, flags y) + { + x = x & y; + return x; + } + + friend flags& operator|=(flags& x, flags y) + { + x = x | y; + return x; + } + + friend flags& operator^=(flags& x, flags y) + { + x = x ^ y; + return x; + } +#endif + +protected: + /// Protected destructor to prevent deletion through this type. + ~resolver_query_base() + { + } + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +private: + // Workaround to enable the empty base optimisation with Borland C++. + char dummy_; +#endif +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_RESOLVER_QUERY_BASE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/resolver_service.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/resolver_service.hpp new file mode 100644 index 00000000..75f6b2c3 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/resolver_service.hpp @@ -0,0 +1,142 @@ +// +// resolver_service.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_RESOLVER_SERVICE_HPP +#define ASIO_IP_RESOLVER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/detail/resolver_service.hpp" +#include "asio/detail/service_base.hpp" + +namespace asio { +namespace ip { + +/// Default service implementation for a resolver. +template +class resolver_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_service::service +#else + : public asio::detail::service_base< + resolver_service > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_service::id id; +#endif + + /// The protocol type. + typedef InternetProtocol protocol_type; + + /// The endpoint type. + typedef typename InternetProtocol::endpoint endpoint_type; + + /// The query type. + typedef basic_resolver_query query_type; + + /// The iterator type. + typedef basic_resolver_iterator iterator_type; + +private: + // The type of the platform-specific implementation. + typedef asio::detail::resolver_service + service_impl_type; + +public: + /// The type of a resolver implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// Construct a new resolver service for the specified io_service. + explicit resolver_service(asio::io_service& io_service) + : asio::detail::service_base< + resolver_service >(io_service), + service_impl_(asio::use_service(io_service)) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + /// Construct a new resolver implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a resolver implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Cancel pending asynchronous operations. + void cancel(implementation_type& impl) + { + service_impl_.cancel(impl); + } + + /// Resolve a query to a list of entries. + iterator_type resolve(implementation_type& impl, const query_type& query, + asio::error_code& ec) + { + return service_impl_.resolve(impl, query, ec); + } + + /// Asynchronously resolve a query to a list of entries. + template + void async_resolve(implementation_type& impl, const query_type& query, + Handler handler) + { + service_impl_.async_resolve(impl, query, handler); + } + + /// Resolve an endpoint to a list of entries. + iterator_type resolve(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + return service_impl_.resolve(impl, endpoint, ec); + } + + /// Asynchronously resolve an endpoint to a list of entries. + template + void async_resolve(implementation_type& impl, const endpoint_type& endpoint, + ResolveHandler handler) + { + return service_impl_.async_resolve(impl, endpoint, handler); + } + +private: + // The service that provides the platform-specific implementation. + service_impl_type& service_impl_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_RESOLVER_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/tcp.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/tcp.hpp new file mode 100644 index 00000000..a2e9ac9c --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/tcp.hpp @@ -0,0 +1,160 @@ +// +// tcp.hpp +// ~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_TCP_HPP +#define ASIO_IP_TCP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/basic_socket_acceptor.hpp" +#include "asio/basic_socket_iostream.hpp" +#include "asio/basic_stream_socket.hpp" +#include "asio/ip/basic_endpoint.hpp" +#include "asio/ip/basic_resolver.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/detail/socket_option.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace ip { + +/// Encapsulates the flags needed for TCP. +/** + * The asio::ip::tcp class contains flags necessary for TCP sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol, InternetProtocol. + */ +class tcp +{ +public: + /// The type of a TCP endpoint. + typedef basic_endpoint endpoint; + + /// (Deprecated: use resolver::query.) The type of a resolver query. + typedef basic_resolver_query resolver_query; + + /// (Deprecated: use resolver::iterator.) The type of a resolver iterator. + typedef basic_resolver_iterator resolver_iterator; + + /// Construct to represent the IPv4 TCP protocol. + static tcp v4() + { + return tcp(PF_INET); + } + + /// Construct to represent the IPv6 TCP protocol. + static tcp v6() + { + return tcp(PF_INET6); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_STREAM; + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return IPPROTO_TCP; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// The TCP socket type. + typedef basic_stream_socket socket; + + /// The TCP acceptor type. + typedef basic_socket_acceptor acceptor; + + /// The TCP resolver type. + typedef basic_resolver resolver; + +#if !defined(BOOST_NO_IOSTREAM) + /// The TCP iostream type. + typedef basic_socket_iostream iostream; +#endif // !defined(BOOST_NO_IOSTREAM) + + /// Socket option for disabling the Nagle algorithm. + /** + * Implements the IPPROTO_TCP/TCP_NODELAY socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::ip::tcp::no_delay option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::ip::tcp::no_delay option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined no_delay; +#else + typedef asio::detail::socket_option::boolean< + IPPROTO_TCP, TCP_NODELAY> no_delay; +#endif + + /// Compare two protocols for equality. + friend bool operator==(const tcp& p1, const tcp& p2) + { + return p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const tcp& p1, const tcp& p2) + { + return p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit tcp(int family) + : family_(family) + { + } + + int family_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_TCP_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/udp.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/udp.hpp new file mode 100644 index 00000000..fb261187 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/udp.hpp @@ -0,0 +1,116 @@ +// +// udp.hpp +// ~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_UDP_HPP +#define ASIO_IP_UDP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/basic_datagram_socket.hpp" +#include "asio/ip/basic_endpoint.hpp" +#include "asio/ip/basic_resolver.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { +namespace ip { + +/// Encapsulates the flags needed for UDP. +/** + * The asio::ip::udp class contains flags necessary for UDP sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol, InternetProtocol. + */ +class udp +{ +public: + /// The type of a UDP endpoint. + typedef basic_endpoint endpoint; + + /// (Deprecated: use resolver::query.) The type of a resolver query. + typedef basic_resolver_query resolver_query; + + /// (Deprecated: use resolver::iterator.) The type of a resolver iterator. + typedef basic_resolver_iterator resolver_iterator; + + /// Construct to represent the IPv4 UDP protocol. + static udp v4() + { + return udp(PF_INET); + } + + /// Construct to represent the IPv6 UDP protocol. + static udp v6() + { + return udp(PF_INET6); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_DGRAM; + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return IPPROTO_UDP; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// The UDP socket type. + typedef basic_datagram_socket socket; + + /// The UDP resolver type. + typedef basic_resolver resolver; + + /// Compare two protocols for equality. + friend bool operator==(const udp& p1, const udp& p2) + { + return p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const udp& p1, const udp& p2) + { + return p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit udp(int family) + : family_(family) + { + } + + int family_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_UDP_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/unicast.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/unicast.hpp new file mode 100644 index 00000000..46d7239c --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/unicast.hpp @@ -0,0 +1,70 @@ +// +// unicast.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_UNICAST_HPP +#define ASIO_IP_UNICAST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/detail/socket_option.hpp" + +namespace asio { +namespace ip { +namespace unicast { + +/// Socket option for time-to-live associated with outgoing unicast packets. +/** + * Implements the IPPROTO_IP/IP_UNICAST_TTL socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::ip::unicast::hops option(4); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::ip::unicast::hops option; + * socket.get_option(option); + * int ttl = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined hops; +#else +typedef asio::ip::detail::socket_option::unicast_hops< + IPPROTO_IP, IP_TTL, IPPROTO_IPV6, IPV6_UNICAST_HOPS> hops; +#endif + +} // namespace unicast +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_UNICAST_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ip/v6_only.hpp b/src/libs/resiprocate/contrib/asio/asio/ip/v6_only.hpp new file mode 100644 index 00000000..928caff0 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ip/v6_only.hpp @@ -0,0 +1,68 @@ +// +// v6_only.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_V6_ONLY_HPP +#define ASIO_IP_V6_ONLY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/socket_option.hpp" + +namespace asio { +namespace ip { + +/// Socket option for determining whether an IPv6 socket supports IPv6 +/// communication only. +/** + * Implements the IPPROTO_IPV6/IP_V6ONLY socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::ip::v6_only option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::ip::v6_only option; + * socket.get_option(option); + * bool v6_only = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined v6_only; +#elif defined(IPV6_V6ONLY) +typedef asio::detail::socket_option::boolean< + IPPROTO_IPV6, IPV6_V6ONLY> v6_only; +#else +typedef asio::detail::socket_option::boolean< + asio::detail::custom_socket_option_level, + asio::detail::always_fail_option> v6_only; +#endif + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_V6_ONLY_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/is_read_buffered.hpp b/src/libs/resiprocate/contrib/asio/asio/is_read_buffered.hpp new file mode 100644 index 00000000..8d971747 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/is_read_buffered.hpp @@ -0,0 +1,62 @@ +// +// is_read_buffered.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IS_READ_BUFFERED_HPP +#define ASIO_IS_READ_BUFFERED_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffered_read_stream_fwd.hpp" +#include "asio/buffered_stream_fwd.hpp" + +namespace asio { + +namespace detail { + +template +char is_read_buffered_helper(buffered_stream* s); + +template +char is_read_buffered_helper(buffered_read_stream* s); + +struct is_read_buffered_big_type { char data[10]; }; +is_read_buffered_big_type is_read_buffered_helper(...); + +} // namespace detail + +/// The is_read_buffered class is a traits class that may be used to determine +/// whether a stream type supports buffering of read data. +template +class is_read_buffered +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The value member is true only if the Stream type supports buffering of + /// read data. + static const bool value; +#else + BOOST_STATIC_CONSTANT(bool, + value = sizeof(detail::is_read_buffered_helper((Stream*)0)) == 1); +#endif +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IS_READ_BUFFERED_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/is_write_buffered.hpp b/src/libs/resiprocate/contrib/asio/asio/is_write_buffered.hpp new file mode 100644 index 00000000..5d16b1c5 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/is_write_buffered.hpp @@ -0,0 +1,62 @@ +// +// is_write_buffered.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IS_WRITE_BUFFERED_HPP +#define ASIO_IS_WRITE_BUFFERED_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffered_stream_fwd.hpp" +#include "asio/buffered_write_stream_fwd.hpp" + +namespace asio { + +namespace detail { + +template +char is_write_buffered_helper(buffered_stream* s); + +template +char is_write_buffered_helper(buffered_write_stream* s); + +struct is_write_buffered_big_type { char data[10]; }; +is_write_buffered_big_type is_write_buffered_helper(...); + +} // namespace detail + +/// The is_write_buffered class is a traits class that may be used to determine +/// whether a stream type supports buffering of written data. +template +class is_write_buffered +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The value member is true only if the Stream type supports buffering of + /// written data. + static const bool value; +#else + BOOST_STATIC_CONSTANT(bool, + value = sizeof(detail::is_write_buffered_helper((Stream*)0)) == 1); +#endif +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IS_WRITE_BUFFERED_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/local/basic_endpoint.hpp b/src/libs/resiprocate/contrib/asio/asio/local/basic_endpoint.hpp new file mode 100644 index 00000000..81e6a7ed --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/local/basic_endpoint.hpp @@ -0,0 +1,265 @@ +// +// basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Derived from a public domain implementation written by Daniel Casimiro. +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_LOCAL_BASIC_ENDPOINT_HPP +#define ASIO_LOCAL_BASIC_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/system_error.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_error.hpp" + +#if !defined(ASIO_DISABLE_LOCAL_SOCKETS) +# if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +# define ASIO_HAS_LOCAL_SOCKETS 1 +# endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(ASIO_DISABLE_LOCAL_SOCKETS) + +#if defined(ASIO_HAS_LOCAL_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) + + +namespace asio { +namespace local { + +/// Describes an endpoint for a UNIX socket. +/** + * The asio::local::basic_endpoint class template describes an endpoint + * that may be associated with a particular UNIX socket. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * Endpoint. + */ +template +class basic_endpoint +{ +public: + /// The protocol type associated with the endpoint. + typedef Protocol protocol_type; + + /// The type of the endpoint structure. This type is dependent on the + /// underlying implementation of the socket layer. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined data_type; +#else + typedef asio::detail::socket_addr_type data_type; +#endif + + /// Default constructor. + basic_endpoint() + { + init("", 0); + } + + /// Construct an endpoint using the specified path name. + basic_endpoint(const char* path) + { + using namespace std; // For strlen. + init(path, strlen(path)); + } + + /// Construct an endpoint using the specified path name. + basic_endpoint(const std::string& path) + { + init(path.data(), path.length()); + } + + /// Copy constructor. + basic_endpoint(const basic_endpoint& other) + : data_(other.data_), + path_length_(other.path_length_) + { + } + + /// Assign from another endpoint. + basic_endpoint& operator=(const basic_endpoint& other) + { + data_ = other.data_; + path_length_ = other.path_length_; + return *this; + } + + /// The protocol associated with the endpoint. + protocol_type protocol() const + { + return protocol_type(); + } + + /// Get the underlying endpoint in the native type. + data_type* data() + { + return &data_.base; + } + + /// Get the underlying endpoint in the native type. + const data_type* data() const + { + return &data_.base; + } + + /// Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + return path_length_ + + offsetof(asio::detail::sockaddr_un_type, sun_path); + } + + /// Set the underlying size of the endpoint in the native type. + void resize(std::size_t size) + { + if (size > sizeof(asio::detail::sockaddr_un_type)) + { + asio::system_error e(asio::error::invalid_argument); + boost::throw_exception(e); + } + else if (size == 0) + { + path_length_ = 0; + } + else + { + path_length_ = size + - offsetof(asio::detail::sockaddr_un_type, sun_path); + + // The path returned by the operating system may be NUL-terminated. + if (path_length_ > 0 && data_.local.sun_path[path_length_ - 1] == 0) + --path_length_; + } + } + + /// Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return sizeof(asio::detail::sockaddr_un_type); + } + + /// Get the path associated with the endpoint. + std::string path() const + { + return std::string(data_.local.sun_path, path_length_); + } + + /// Set the path associated with the endpoint. + void path(const char* p) + { + using namespace std; // For strlen. + init(p, strlen(p)); + } + + /// Set the path associated with the endpoint. + void path(const std::string& p) + { + init(p.data(), p.length()); + } + + /// Compare two endpoints for equality. + friend bool operator==(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.path() == e2.path(); + } + + /// Compare two endpoints for inequality. + friend bool operator!=(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.path() != e2.path(); + } + + /// Compare endpoints for ordering. + friend bool operator<(const basic_endpoint& e1, + const basic_endpoint& e2) + { + return e1.path() < e2.path(); + } + +private: + // The underlying UNIX socket address. + union data_union + { + asio::detail::socket_addr_type base; + asio::detail::sockaddr_un_type local; + } data_; + + // The length of the path associated with the endpoint. + std::size_t path_length_; + + // Initialise with a specified path. + void init(const char* path, std::size_t path_length) + { + if (path_length > sizeof(data_.local.sun_path) - 1) + { + // The buffer is not large enough to store this address. + asio::error_code ec(asio::error::name_too_long); + asio::detail::throw_error(ec); + } + + using namespace std; // For memcpy. + data_.local = asio::detail::sockaddr_un_type(); + data_.local.sun_family = AF_UNIX; + memcpy(data_.local.sun_path, path, path_length); + path_length_ = path_length; + + // NUL-terminate normal path names. Names that start with a NUL are in the + // UNIX domain protocol's "abstract namespace" and are not NUL-terminated. + if (path_length > 0 && data_.local.sun_path[0] == 0) + data_.local.sun_path[path_length] = 0; + } +}; + +/// Output an endpoint as a string. +/** + * Used to output a human-readable string for a specified endpoint. + * + * @param os The output stream to which the string will be written. + * + * @param endpoint The endpoint to be written. + * + * @return The output stream. + * + * @relates asio::local::basic_endpoint + */ +template +std::basic_ostream& operator<<( + std::basic_ostream& os, + const basic_endpoint& endpoint) +{ + os << endpoint.path(); + return os; +} + +} // namespace local +} // namespace asio + +#endif // defined(ASIO_HAS_LOCAL_SOCKETS) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_LOCAL_BASIC_ENDPOINT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/local/connect_pair.hpp b/src/libs/resiprocate/contrib/asio/asio/local/connect_pair.hpp new file mode 100644 index 00000000..da1d4fc5 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/local/connect_pair.hpp @@ -0,0 +1,100 @@ +// +// connect_pair.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_LOCAL_CONNECT_PAIR_HPP +#define ASIO_LOCAL_CONNECT_PAIR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/basic_socket.hpp" +#include "asio/error.hpp" +#include "asio/local/basic_endpoint.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/throw_error.hpp" + +#if defined(ASIO_HAS_LOCAL_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { +namespace local { + +/// Create a pair of connected sockets. +template +void connect_pair( + basic_socket& socket1, + basic_socket& socket2); + +/// Create a pair of connected sockets. +template +asio::error_code connect_pair( + basic_socket& socket1, + basic_socket& socket2, + asio::error_code& ec); + +template +inline void connect_pair( + basic_socket& socket1, + basic_socket& socket2) +{ + asio::error_code ec; + connect_pair(socket1, socket2, ec); + asio::detail::throw_error(ec); +} + +template +inline asio::error_code connect_pair( + basic_socket& socket1, + basic_socket& socket2, + asio::error_code& ec) +{ + // Check that this function is only being used with a UNIX domain socket. + asio::local::basic_endpoint* tmp + = static_cast(0); + (void)tmp; + + Protocol protocol; + asio::detail::socket_type sv[2]; + if (asio::detail::socket_ops::socketpair(protocol.family(), + protocol.type(), protocol.protocol(), sv, ec) + == asio::detail::socket_error_retval) + return ec; + + if (socket1.assign(protocol, sv[0], ec)) + { + asio::error_code temp_ec; + asio::detail::socket_ops::close(sv[0], temp_ec); + asio::detail::socket_ops::close(sv[1], temp_ec); + return ec; + } + + if (socket2.assign(protocol, sv[1], ec)) + { + asio::error_code temp_ec; + socket1.close(temp_ec); + asio::detail::socket_ops::close(sv[1], temp_ec); + return ec; + } + + return ec; +} + +} // namespace local +} // namespace asio + +#endif // defined(ASIO_HAS_LOCAL_SOCKETS) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_LOCAL_CONNECT_PAIR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/local/datagram_protocol.hpp b/src/libs/resiprocate/contrib/asio/asio/local/datagram_protocol.hpp new file mode 100644 index 00000000..03401805 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/local/datagram_protocol.hpp @@ -0,0 +1,78 @@ +// +// datagram_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP +#define ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/basic_datagram_socket.hpp" +#include "asio/local/basic_endpoint.hpp" +#include "asio/detail/socket_types.hpp" + +#if defined(ASIO_HAS_LOCAL_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { +namespace local { + +/// Encapsulates the flags needed for datagram-oriented UNIX sockets. +/** + * The asio::local::datagram_protocol class contains flags necessary for + * datagram-oriented UNIX domain sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol. + */ +class datagram_protocol +{ +public: + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_DGRAM; + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return 0; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return AF_UNIX; + } + + /// The type of a UNIX domain endpoint. + typedef basic_endpoint endpoint; + + /// The UNIX domain socket type. + typedef basic_datagram_socket socket; +}; + +} // namespace local +} // namespace asio + +#endif // defined(ASIO_HAS_LOCAL_SOCKETS) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/local/stream_protocol.hpp b/src/libs/resiprocate/contrib/asio/asio/local/stream_protocol.hpp new file mode 100644 index 00000000..47fe42f1 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/local/stream_protocol.hpp @@ -0,0 +1,88 @@ +// +// stream_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_LOCAL_STREAM_PROTOCOL_HPP +#define ASIO_LOCAL_STREAM_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/basic_socket_acceptor.hpp" +#include "asio/basic_socket_iostream.hpp" +#include "asio/basic_stream_socket.hpp" +#include "asio/local/basic_endpoint.hpp" +#include "asio/detail/socket_types.hpp" + +#if defined(ASIO_HAS_LOCAL_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { +namespace local { + +/// Encapsulates the flags needed for stream-oriented UNIX sockets. +/** + * The asio::local::stream_protocol class contains flags necessary for + * stream-oriented UNIX domain sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol. + */ +class stream_protocol +{ +public: + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_STREAM; + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return 0; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return AF_UNIX; + } + + /// The type of a UNIX domain endpoint. + typedef basic_endpoint endpoint; + + /// The UNIX domain socket type. + typedef basic_stream_socket socket; + + /// The UNIX domain acceptor type. + typedef basic_socket_acceptor acceptor; + +#if !defined(BOOST_NO_IOSTREAM) + /// The UNIX domain iostream type. + typedef basic_socket_iostream iostream; +#endif // !defined(BOOST_NO_IOSTREAM) +}; + +} // namespace local +} // namespace asio + +#endif // defined(ASIO_HAS_LOCAL_SOCKETS) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_LOCAL_STREAM_PROTOCOL_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/placeholders.hpp b/src/libs/resiprocate/contrib/asio/asio/placeholders.hpp new file mode 100644 index 00000000..70e69fca --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/placeholders.hpp @@ -0,0 +1,107 @@ +// +// placeholders.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_PLACEHOLDERS_HPP +#define ASIO_PLACEHOLDERS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace placeholders { + +#if defined(GENERATING_DOCUMENTATION) + +/// An argument placeholder, for use with boost::bind(), that corresponds to +/// the error argument of a handler for any of the asynchronous functions. +unspecified error; + +/// An argument placeholder, for use with boost::bind(), that corresponds to +/// the bytes_transferred argument of a handler for asynchronous functions such +/// as asio::basic_stream_socket::async_write_some or +/// asio::async_write. +unspecified bytes_transferred; + +/// An argument placeholder, for use with boost::bind(), that corresponds to +/// the iterator argument of a handler for asynchronous functions such as +/// asio::basic_resolver::resolve. +unspecified iterator; + +#elif defined(__BORLANDC__) || defined(__GNUC__) + +inline boost::arg<1> error() +{ + return boost::arg<1>(); +} + +inline boost::arg<2> bytes_transferred() +{ + return boost::arg<2>(); +} + +inline boost::arg<2> iterator() +{ + return boost::arg<2>(); +} + +#else + +namespace detail +{ + template + struct placeholder + { + static boost::arg& get() + { + static boost::arg result; + return result; + } + }; +} + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1400) + +static boost::arg<1>& error + = asio::placeholders::detail::placeholder<1>::get(); +static boost::arg<2>& bytes_transferred + = asio::placeholders::detail::placeholder<2>::get(); +static boost::arg<2>& iterator + = asio::placeholders::detail::placeholder<2>::get(); + +#else + +namespace +{ + boost::arg<1>& error + = asio::placeholders::detail::placeholder<1>::get(); + boost::arg<2>& bytes_transferred + = asio::placeholders::detail::placeholder<2>::get(); + boost::arg<2>& iterator + = asio::placeholders::detail::placeholder<2>::get(); +} // namespace + +#endif + +#endif + +} // namespace placeholders +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_PLACEHOLDERS_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/posix/basic_descriptor.hpp b/src/libs/resiprocate/contrib/asio/asio/posix/basic_descriptor.hpp new file mode 100644 index 00000000..37bcc94d --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/posix/basic_descriptor.hpp @@ -0,0 +1,294 @@ +// +// basic_descriptor.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_POSIX_BASIC_DESCRIPTOR_HPP +#define ASIO_POSIX_BASIC_DESCRIPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_io_object.hpp" +#include "asio/error.hpp" +#include "asio/posix/descriptor_base.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { +namespace posix { + +/// Provides POSIX descriptor functionality. +/** + * The posix::basic_descriptor class template provides the ability to wrap a + * POSIX descriptor. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_descriptor + : public basic_io_object, + public descriptor_base +{ +public: + /// The native representation of a descriptor. + typedef typename DescriptorService::native_type native_type; + + /// A basic_descriptor is always the lowest layer. + typedef basic_descriptor lowest_layer_type; + + /// Construct a basic_descriptor without opening it. + /** + * This constructor creates a descriptor without opening it. + * + * @param io_service The io_service object that the descriptor will use to + * dispatch handlers for any asynchronous operations performed on the + * descriptor. + */ + explicit basic_descriptor(asio::io_service& io_service) + : basic_io_object(io_service) + { + } + + /// Construct a basic_descriptor on an existing native descriptor. + /** + * This constructor creates a descriptor object to hold an existing native + * descriptor. + * + * @param io_service The io_service object that the descriptor will use to + * dispatch handlers for any asynchronous operations performed on the + * descriptor. + * + * @param native_descriptor A native descriptor. + * + * @throws asio::system_error Thrown on failure. + */ + basic_descriptor(asio::io_service& io_service, + const native_type& native_descriptor) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.assign(this->implementation, native_descriptor, ec); + asio::detail::throw_error(ec); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since a basic_descriptor cannot contain any further layers, it + * simply returns a reference to itself. + * + * @return A reference to the lowest layer in the stack of layers. Ownership + * is not transferred to the caller. + */ + lowest_layer_type& lowest_layer() + { + return *this; + } + + /// Get a const reference to the lowest layer. + /** + * This function returns a const reference to the lowest layer in a stack of + * layers. Since a basic_descriptor cannot contain any further layers, it + * simply returns a reference to itself. + * + * @return A const reference to the lowest layer in the stack of layers. + * Ownership is not transferred to the caller. + */ + const lowest_layer_type& lowest_layer() const + { + return *this; + } + + /// Assign an existing native descriptor to the descriptor. + /* + * This function opens the descriptor to hold an existing native descriptor. + * + * @param native_descriptor A native descriptor. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_type& native_descriptor) + { + asio::error_code ec; + this->service.assign(this->implementation, native_descriptor, ec); + asio::detail::throw_error(ec); + } + + /// Assign an existing native descriptor to the descriptor. + /* + * This function opens the descriptor to hold an existing native descriptor. + * + * @param native_descriptor A native descriptor. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code assign(const native_type& native_descriptor, + asio::error_code& ec) + { + return this->service.assign(this->implementation, native_descriptor, ec); + } + + /// Determine whether the descriptor is open. + bool is_open() const + { + return this->service.is_open(this->implementation); + } + + /// Close the descriptor. + /** + * This function is used to close the descriptor. Any asynchronous read or + * write operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->service.close(this->implementation, ec); + asio::detail::throw_error(ec); + } + + /// Close the descriptor. + /** + * This function is used to close the descriptor. Any asynchronous read or + * write operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code close(asio::error_code& ec) + { + return this->service.close(this->implementation, ec); + } + + /// Get the native descriptor representation. + /** + * This function may be used to obtain the underlying representation of the + * descriptor. This is intended to allow access to native descriptor + * functionality that is not otherwise provided. + */ + native_type native() + { + return this->service.native(this->implementation); + } + + /// Cancel all asynchronous operations associated with the descriptor. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->service.cancel(this->implementation, ec); + asio::detail::throw_error(ec); + } + + /// Cancel all asynchronous operations associated with the descriptor. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code cancel(asio::error_code& ec) + { + return this->service.cancel(this->implementation, ec); + } + + /// Perform an IO control command on the descriptor. + /** + * This function is used to execute an IO control command on the descriptor. + * + * @param command The IO control command to be performed on the descriptor. + * + * @throws asio::system_error Thrown on failure. + * + * @sa IoControlCommand @n + * asio::posix::descriptor_base::bytes_readable @n + * asio::posix::descriptor_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * asio::posix::stream_descriptor descriptor(io_service); + * ... + * asio::posix::stream_descriptor::bytes_readable command; + * descriptor.io_control(command); + * std::size_t bytes_readable = command.get(); + * @endcode + */ + template + void io_control(IoControlCommand& command) + { + asio::error_code ec; + this->service.io_control(this->implementation, command, ec); + asio::detail::throw_error(ec); + } + + /// Perform an IO control command on the descriptor. + /** + * This function is used to execute an IO control command on the descriptor. + * + * @param command The IO control command to be performed on the descriptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa IoControlCommand @n + * asio::posix::descriptor_base::bytes_readable @n + * asio::posix::descriptor_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * asio::posix::stream_descriptor descriptor(io_service); + * ... + * asio::posix::stream_descriptor::bytes_readable command; + * asio::error_code ec; + * descriptor.io_control(command, ec); + * if (ec) + * { + * // An error occurred. + * } + * std::size_t bytes_readable = command.get(); + * @endcode + */ + template + asio::error_code io_control(IoControlCommand& command, + asio::error_code& ec) + { + return this->service.io_control(this->implementation, command, ec); + } + +protected: + /// Protected destructor to prevent deletion through this type. + ~basic_descriptor() + { + } +}; + +} // namespace posix +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_POSIX_BASIC_DESCRIPTOR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/posix/basic_stream_descriptor.hpp b/src/libs/resiprocate/contrib/asio/asio/posix/basic_stream_descriptor.hpp new file mode 100644 index 00000000..21e2287d --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/posix/basic_stream_descriptor.hpp @@ -0,0 +1,304 @@ +// +// basic_stream_descriptor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP +#define ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/posix/basic_descriptor.hpp" +#include "asio/posix/stream_descriptor_service.hpp" +#include "asio/detail/throw_error.hpp" + +#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { +namespace posix { + +/// Provides stream-oriented descriptor functionality. +/** + * The posix::basic_stream_descriptor class template provides asynchronous and + * blocking stream-oriented descriptor functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template +class basic_stream_descriptor + : public basic_descriptor +{ +public: + /// The native representation of a descriptor. + typedef typename StreamDescriptorService::native_type native_type; + + /// Construct a basic_stream_descriptor without opening it. + /** + * This constructor creates a stream descriptor without opening it. The + * descriptor needs to be opened and then connected or accepted before data + * can be sent or received on it. + * + * @param io_service The io_service object that the stream descriptor will + * use to dispatch handlers for any asynchronous operations performed on the + * descriptor. + */ + explicit basic_stream_descriptor(asio::io_service& io_service) + : basic_descriptor(io_service) + { + } + + /// Construct a basic_stream_descriptor on an existing native descriptor. + /** + * This constructor creates a stream descriptor object to hold an existing + * native descriptor. + * + * @param io_service The io_service object that the stream descriptor will + * use to dispatch handlers for any asynchronous operations performed on the + * descriptor. + * + * @param native_descriptor The new underlying descriptor implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_stream_descriptor(asio::io_service& io_service, + const native_type& native_descriptor) + : basic_descriptor(io_service, native_descriptor) + { + } + + /// Write some data to the descriptor. + /** + * This function is used to write data to the stream descriptor. The function + * call will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the descriptor. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * descriptor.write_some(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.write_some(this->implementation, buffers, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Write some data to the descriptor. + /** + * This function is used to write data to the stream descriptor. The function + * call will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the descriptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. Returns 0 if an error occurred. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) + { + return this->service.write_some(this->implementation, buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the stream + * descriptor. The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the descriptor. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * descriptor.async_write_some(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + this->service.async_write_some(this->implementation, buffers, handler); + } + + /// Read some data from the descriptor. + /** + * This function is used to read data from the stream descriptor. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * descriptor.read_some(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.read_some(this->implementation, buffers, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Read some data from the descriptor. + /** + * This function is used to read data from the stream descriptor. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. Returns 0 if an error occurred. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return this->service.read_some(this->implementation, buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the stream + * descriptor. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be read. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read function if you need to ensure that the + * requested amount of data is read before the asynchronous operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * descriptor.async_read_some(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + this->service.async_read_some(this->implementation, buffers, handler); + } +}; + +} // namespace posix +} // namespace asio + +#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/posix/descriptor_base.hpp b/src/libs/resiprocate/contrib/asio/asio/posix/descriptor_base.hpp new file mode 100644 index 00000000..29e17469 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/posix/descriptor_base.hpp @@ -0,0 +1,93 @@ +// +// descriptor_base.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_POSIX_DESCRIPTOR_BASE_HPP +#define ASIO_POSIX_DESCRIPTOR_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/io_control.hpp" +#include "asio/detail/socket_option.hpp" + +namespace asio { +namespace posix { + +/// The descriptor_base class is used as a base for the basic_stream_descriptor +/// class template so that we have a common place to define the associated +/// IO control commands. +class descriptor_base +{ +public: + /// IO control command to set the blocking mode of the descriptor. + /** + * Implements the FIONBIO IO control command. + * + * @par Example + * @code + * asio::posix::stream_descriptor descriptor(io_service); + * ... + * asio::descriptor_base::non_blocking_io command(true); + * descriptor.io_control(command); + * @endcode + * + * @par Concepts: + * IoControlCommand. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined non_blocking_io; +#else + typedef asio::detail::io_control::non_blocking_io non_blocking_io; +#endif + + /// IO control command to get the amount of data that can be read without + /// blocking. + /** + * Implements the FIONREAD IO control command. + * + * @par Example + * @code + * asio::posix::stream_descriptor descriptor(io_service); + * ... + * asio::descriptor_base::bytes_readable command(true); + * descriptor.io_control(command); + * std::size_t bytes_readable = command.get(); + * @endcode + * + * @par Concepts: + * IoControlCommand. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined bytes_readable; +#else + typedef asio::detail::io_control::bytes_readable bytes_readable; +#endif + +protected: + /// Protected destructor to prevent deletion through this type. + ~descriptor_base() + { + } +}; + +} // namespace posix +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_POSIX_DESCRIPTOR_BASE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/posix/stream_descriptor.hpp b/src/libs/resiprocate/contrib/asio/asio/posix/stream_descriptor.hpp new file mode 100644 index 00000000..72fbbed2 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/posix/stream_descriptor.hpp @@ -0,0 +1,39 @@ +// +// stream_descriptor.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_POSIX_STREAM_DESCRIPTOR_HPP +#define ASIO_POSIX_STREAM_DESCRIPTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/posix/basic_stream_descriptor.hpp" + +#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { +namespace posix { + +/// Typedef for the typical usage of a stream-oriented descriptor. +typedef basic_stream_descriptor<> stream_descriptor; + +} // namespace posix +} // namespace asio + +#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_POSIX_STREAM_DESCRIPTOR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/posix/stream_descriptor_service.hpp b/src/libs/resiprocate/contrib/asio/asio/posix/stream_descriptor_service.hpp new file mode 100644 index 00000000..61cee1b5 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/posix/stream_descriptor_service.hpp @@ -0,0 +1,187 @@ +// +// stream_descriptor_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_POSIX_STREAM_DESCRIPTOR_SERVICE_HPP +#define ASIO_POSIX_STREAM_DESCRIPTOR_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/service_base.hpp" + +#if !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR) +# if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +# define ASIO_HAS_POSIX_STREAM_DESCRIPTOR 1 +# endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR) + +#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/reactive_descriptor_service.hpp" + +namespace asio { +namespace posix { + +/// Default service implementation for a stream descriptor. +class stream_descriptor_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_service::service +#else + : public asio::detail::service_base +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_service::id id; +#endif + +private: + // The type of the platform-specific implementation. + typedef detail::reactive_descriptor_service service_impl_type; + +public: + /// The type of a stream descriptor implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef service_impl_type::implementation_type implementation_type; +#endif + + /// The native descriptor type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef service_impl_type::native_type native_type; +#endif + + /// Construct a new stream descriptor service for the specified io_service. + explicit stream_descriptor_service(asio::io_service& io_service) + : asio::detail::service_base(io_service), + service_impl_(io_service) + { + } + + /// Destroy all user-defined descriptorr objects owned by the service. + void shutdown_service() + { + service_impl_.shutdown_service(); + } + + /// Construct a new stream descriptor implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a stream descriptor implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Assign an existing native descriptor to a stream descriptor. + asio::error_code assign(implementation_type& impl, + const native_type& native_descriptor, asio::error_code& ec) + { + return service_impl_.assign(impl, native_descriptor, ec); + } + + /// Determine whether the descriptor is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a stream descriptor implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// Get the native descriptor implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native(impl); + } + + /// Cancel all asynchronous operations associated with the descriptor. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Perform an IO control command on the descriptor. + template + asio::error_code io_control(implementation_type& impl, + IoControlCommand& command, asio::error_code& ec) + { + return service_impl_.io_control(impl, command, ec); + } + + /// Write the given data to the stream. + template + std::size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.write_some(impl, buffers, ec); + } + + /// Start an asynchronous write. + template + void async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, WriteHandler descriptorr) + { + service_impl_.async_write_some(impl, buffers, descriptorr); + } + + /// Read some data from the stream. + template + std::size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.read_some(impl, buffers, ec); + } + + /// Start an asynchronous read. + template + void async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, ReadHandler descriptorr) + { + service_impl_.async_read_some(impl, buffers, descriptorr); + } + +private: + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace posix +} // namespace asio + +#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_POSIX_STREAM_DESCRIPTOR_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/raw_socket_service.hpp b/src/libs/resiprocate/contrib/asio/asio/raw_socket_service.hpp new file mode 100644 index 00000000..a8973d34 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/raw_socket_service.hpp @@ -0,0 +1,315 @@ +// +// raw_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_RAW_SOCKET_SERVICE_HPP +#define ASIO_RAW_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/service_base.hpp" + +#if defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +#else +# include "asio/detail/reactive_socket_service.hpp" +#endif + +namespace asio { + +/// Default service implementation for a raw socket. +template +class raw_socket_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_service::service +#else + : public asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_service::id id; +#endif + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + +private: + // The type of the platform-specific implementation. +#if defined(ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#else + typedef detail::reactive_socket_service service_impl_type; +#endif + +public: + /// The type of a raw socket. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// The native socket type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef typename service_impl_type::native_type native_type; +#endif + + /// Construct a new raw socket service for the specified io_service. + explicit raw_socket_service(asio::io_service& io_service) + : asio::detail::service_base< + raw_socket_service >(io_service), + service_impl_(io_service) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + service_impl_.shutdown_service(); + } + + /// Construct a new raw socket implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a raw socket implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + // Open a new raw socket implementation. + asio::error_code open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + if (protocol.type() == SOCK_RAW) + service_impl_.open(impl, protocol, ec); + else + ec = asio::error::invalid_argument; + return ec; + } + + /// Assign an existing native socket to a raw socket. + asio::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + asio::error_code& ec) + { + return service_impl_.assign(impl, protocol, native_socket, ec); + } + + /// Determine whether the socket is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a raw socket implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// Get the native socket implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native(impl); + } + + /// Cancel all asynchronous operations associated with the socket. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Determine whether the socket is at the out-of-band data mark. + bool at_mark(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.at_mark(impl, ec); + } + + /// Determine the number of bytes available for reading. + std::size_t available(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.available(impl, ec); + } + + // Bind the raw socket to the specified local endpoint. + asio::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + return service_impl_.bind(impl, endpoint, ec); + } + + /// Connect the raw socket to the specified endpoint. + asio::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, asio::error_code& ec) + { + return service_impl_.connect(impl, peer_endpoint, ec); + } + + /// Start an asynchronous connect. + template + void async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, ConnectHandler handler) + { + service_impl_.async_connect(impl, peer_endpoint, handler); + } + + /// Set a socket option. + template + asio::error_code set_option(implementation_type& impl, + const SettableSocketOption& option, asio::error_code& ec) + { + return service_impl_.set_option(impl, option, ec); + } + + /// Get a socket option. + template + asio::error_code get_option(const implementation_type& impl, + GettableSocketOption& option, asio::error_code& ec) const + { + return service_impl_.get_option(impl, option, ec); + } + + /// Perform an IO control command on the socket. + template + asio::error_code io_control(implementation_type& impl, + IoControlCommand& command, asio::error_code& ec) + { + return service_impl_.io_control(impl, command, ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.remote_endpoint(impl, ec); + } + + /// Disable sends or receives on the socket. + asio::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, asio::error_code& ec) + { + return service_impl_.shutdown(impl, what, ec); + } + + /// Send the given data to the peer. + template + std::size_t send(implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return service_impl_.send(impl, buffers, flags, ec); + } + + /// Start an asynchronous send. + template + void async_send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, WriteHandler handler) + { + service_impl_.async_send(impl, buffers, flags, handler); + } + + /// Send raw data to the specified endpoint. + template + std::size_t send_to(implementation_type& impl, + const ConstBufferSequence& buffers, const endpoint_type& destination, + socket_base::message_flags flags, asio::error_code& ec) + { + return service_impl_.send_to(impl, buffers, destination, flags, ec); + } + + /// Start an asynchronous send. + template + void async_send_to(implementation_type& impl, + const ConstBufferSequence& buffers, const endpoint_type& destination, + socket_base::message_flags flags, WriteHandler handler) + { + service_impl_.async_send_to(impl, buffers, destination, flags, handler); + } + + /// Receive some data from the peer. + template + std::size_t receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return service_impl_.receive(impl, buffers, flags, ec); + } + + /// Start an asynchronous receive. + template + void async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, ReadHandler handler) + { + service_impl_.async_receive(impl, buffers, flags, handler); + } + + /// Receive raw data with the endpoint of the sender. + template + std::size_t receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, asio::error_code& ec) + { + return service_impl_.receive_from(impl, buffers, sender_endpoint, flags, + ec); + } + + /// Start an asynchronous receive that will get the endpoint of the sender. + template + void async_receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, ReadHandler handler) + { + service_impl_.async_receive_from(impl, buffers, sender_endpoint, flags, + handler); + } + +private: + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_RAW_SOCKET_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/read.hpp b/src/libs/resiprocate/contrib/asio/asio/read.hpp new file mode 100644 index 00000000..859c05a0 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/read.hpp @@ -0,0 +1,543 @@ +// +// read.hpp +// ~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_READ_HPP +#define ASIO_READ_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_streambuf.hpp" +#include "asio/error.hpp" + +namespace asio { + +/** + * @defgroup read asio::read + * + * @brief Attempt to read a certain amount of data from a stream before + * returning. + */ +/*@{*/ + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::read(s, asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + * + * @note This overload is equivalent to calling: + * @code asio::read( + * s, buffers, + * asio::transfer_all()); @endcode + */ +template +std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's read_some function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::read(s, asio::buffer(data, size), + * asio::transfer_at_least(32)); @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's read_some function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec); + +#if !defined(BOOST_NO_IOSTREAM) + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @note This overload is equivalent to calling: + * @code asio::read( + * s, b, + * asio::transfer_all()); @endcode + */ +template +std::size_t read(SyncReadStream& s, basic_streambuf& b); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's read_some function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + */ +template +std::size_t read(SyncReadStream& s, basic_streambuf& b, + CompletionCondition completion_condition); + +/// Attempt to read a certain amount of data from a stream before returning. +/** + * This function is used to read a certain number of bytes of data from a + * stream. The call will block until one of the following conditions is true: + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's read_some function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t read(SyncReadStream& s, basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec); + +#endif // !defined(BOOST_NO_IOSTREAM) + +/*@}*/ +/** + * @defgroup async_read asio::async_read + * + * @brief Start an asynchronous operation to read a certain amount of data from + * a stream. + */ +/*@{*/ + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other read operations (such + * as async_read, the stream's async_read_some function, or any other composed + * operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. Although the buffers object may be copied as necessary, ownership of + * the underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * asio::async_read(s, asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + * + * @note This overload is equivalent to calling: + * @code asio::async_read( + * s, buffers, + * asio::transfer_all(), + * handler); @endcode + */ +template +void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, + ReadHandler handler); + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * stream. Although the buffers object may be copied as necessary, ownership of + * the underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's async_read_some function. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::async_read(s, + * asio::buffer(data, size), + * asio::transfer_at_least(32), + * handler); @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, ReadHandler handler); + +#if !defined(BOOST_NO_IOSTREAM) + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other read operations (such + * as async_read, the stream's async_read_some function, or any other composed + * operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A basic_streambuf object into which the data will be read. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note This overload is equivalent to calling: + * @code asio::async_read( + * s, b, + * asio::transfer_all(), + * handler); @endcode + */ +template +void async_read(AsyncReadStream& s, basic_streambuf& b, + ReadHandler handler); + +/// Start an asynchronous operation to read a certain amount of data from a +/// stream. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions is + * true: + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other read operations (such + * as async_read, the stream's async_read_some function, or any other composed + * operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A basic_streambuf object into which the data will be read. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_read_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the stream's async_read_some function. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes copied into the + * // buffers. If an error occurred, + * // this will be the number of + * // bytes successfully transferred + * // prior to the error. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + */ +template +void async_read(AsyncReadStream& s, basic_streambuf& b, + CompletionCondition completion_condition, ReadHandler handler); + +#endif // !defined(BOOST_NO_IOSTREAM) + +/*@}*/ + +} // namespace asio + +#include "asio/impl/read.ipp" + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_READ_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/read_at.hpp b/src/libs/resiprocate/contrib/asio/asio/read_at.hpp new file mode 100644 index 00000000..6bb3fe12 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/read_at.hpp @@ -0,0 +1,576 @@ +// +// read_at.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_READ_AT_HPP +#define ASIO_READ_AT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_streambuf.hpp" +#include "asio/error.hpp" + +namespace asio { + +/** + * @defgroup read_at asio::read_at + * + * @brief Attempt to read a certain amount of data at the specified offset + * before returning. + */ +/*@{*/ + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * device. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::read_at(d, 42, asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + * + * @note This overload is equivalent to calling: + * @code asio::read_at( + * d, 42, buffers, + * asio::transfer_all()); @endcode + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, const MutableBufferSequence& buffers); + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * device. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the device's read_some_at function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::read_at(d, 42, asio::buffer(data, size), + * asio::transfer_at_least(32)); @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition); + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * device. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the device's read_some_at function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec); + +#if !defined(BOOST_NO_IOSTREAM) + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @note This overload is equivalent to calling: + * @code asio::read_at( + * d, 42, b, + * asio::transfer_all()); @endcode + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, basic_streambuf& b); + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the device's read_some_at function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, basic_streambuf& b, + CompletionCondition completion_condition); + +/// Attempt to read a certain amount of data at the specified offset before +/// returning. +/** + * This function is used to read a certain number of bytes of data from a + * random access device at the specified offset. The call will block until one + * of the following conditions is true: + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the SyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param b The basic_streambuf object into which the data will be read. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest read_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the device's read_some_at function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec); + +#endif // !defined(BOOST_NO_IOSTREAM) + +/*@}*/ +/** + * @defgroup async_read_at asio::async_read_at + * + * @brief Start an asynchronous operation to read a certain amount of data at + * the specified offset. + */ +/*@{*/ + +/// Start an asynchronous operation to read a certain amount of data at the +/// specified offset. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a random access device at the specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the AsyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * device. Although the buffers object may be copied as necessary, ownership of + * the underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes copied into the buffers. If an error + * // occurred, this will be the number of bytes successfully + * // transferred prior to the error. + * std::size_t bytes_transferred + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * asio::async_read_at(d, 42, asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + * + * @note This overload is equivalent to calling: + * @code asio::async_read_at( + * d, 42, buffers, + * asio::transfer_all(), + * handler); @endcode + */ +template +void async_read_at(AsyncRandomAccessReadDevice& d, boost::uint64_t offset, + const MutableBufferSequence& buffers, ReadHandler handler); + +/// Start an asynchronous operation to read a certain amount of data at the +/// specified offset. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a random access device at the specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li The supplied buffers are full. That is, the bytes transferred is equal to + * the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * @param d The device from which the data is to be read. The type must support + * the AsyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. The sum + * of the buffer sizes indicates the maximum number of bytes to read from the + * device. Although the buffers object may be copied as necessary, ownership of + * the underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_read_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the device's async_read_some_at function. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes copied into the buffers. If an error + * // occurred, this will be the number of bytes successfully + * // transferred prior to the error. + * std::size_t bytes_transferred + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code asio::async_read_at(d, 42, + * asio::buffer(data, size), + * asio::transfer_at_least(32), + * handler); @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +void async_read_at(AsyncRandomAccessReadDevice& d, + boost::uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, ReadHandler handler); + +#if !defined(BOOST_NO_IOSTREAM) + +/// Start an asynchronous operation to read a certain amount of data at the +/// specified offset. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a random access device at the specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the AsyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param b A basic_streambuf object into which the data will be read. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes copied into the buffers. If an error + * // occurred, this will be the number of bytes successfully + * // transferred prior to the error. + * std::size_t bytes_transferred + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note This overload is equivalent to calling: + * @code asio::async_read_at( + * d, 42, b, + * asio::transfer_all(), + * handler); @endcode + */ +template +void async_read_at(AsyncRandomAccessReadDevice& d, boost::uint64_t offset, + basic_streambuf& b, ReadHandler handler); + +/// Start an asynchronous operation to read a certain amount of data at the +/// specified offset. +/** + * This function is used to asynchronously read a certain number of bytes of + * data from a random access device at the specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_read_some_at function. + * + * @param d The device from which the data is to be read. The type must support + * the AsyncRandomAccessReadDevice concept. + * + * @param offset The offset at which the data will be read. + * + * @param b A basic_streambuf object into which the data will be read. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the read operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_read_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the read operation is complete. A non-zero + * return value indicates the maximum number of bytes to be read on the next + * call to the device's async_read_some_at function. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes copied into the buffers. If an error + * // occurred, this will be the number of bytes successfully + * // transferred prior to the error. + * std::size_t bytes_transferred + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + */ +template +void async_read_at(AsyncRandomAccessReadDevice& d, + boost::uint64_t offset, basic_streambuf& b, + CompletionCondition completion_condition, ReadHandler handler); + +#endif // !defined(BOOST_NO_IOSTREAM) + +/*@}*/ + +} // namespace asio + +#include "asio/impl/read_at.ipp" + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_READ_AT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/read_until.hpp b/src/libs/resiprocate/contrib/asio/asio/read_until.hpp new file mode 100644 index 00000000..5df71ce2 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/read_until.hpp @@ -0,0 +1,923 @@ +// +// read_until.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_READ_UNTIL_HPP +#define ASIO_READ_UNTIL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(BOOST_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_streambuf.hpp" +#include "asio/error.hpp" + +namespace asio { + +namespace detail +{ +#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610)) + template + struct has_result_type + { + template struct inner + { + struct big { char a[100]; }; + static big helper(U, ...); + static char helper(U, typename U::result_type* = 0); + }; + static const T& ref(); + enum { value = (sizeof((inner::helper)((ref)())) == 1) }; + }; +#else // BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610)) + template + struct has_result_type + { + struct big { char a[100]; }; + template static big helper(U, ...); + template static char helper(U, typename U::result_type* = 0); + static const T& ref(); + enum { value = (sizeof((helper)((ref)())) == 1) }; + }; +#endif // BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610)) +} // namespace detail + +/// Type trait used to determine whether a type can be used as a match condition +/// function with read_until and async_read_until. +template +struct is_match_condition +{ +#if defined(GENERATING_DOCUMENTATION) + /// The value member is true if the type may be used as a match condition. + static const bool value; +#else + enum + { + value = boost::is_function::type>::value + || detail::has_result_type::value + }; +#endif +}; + +/** + * @defgroup read_until asio::read_until + * + * @brief Read data into a streambuf until it contains a delimiter, matches a + * regular expression, or a function object indicates a match. + */ +/*@{*/ + +/// Read data into a streambuf until it contains a specified delimiter. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains the specified delimiter. The call will block + * until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains the + * delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param delim The delimiter character. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the delimiter. + * + * @throws asio::system_error Thrown on failure. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond the delimiter. An application will typically leave + * that data in the streambuf for a subsequent read_until operation to examine. + * + * @par Example + * To read data into a streambuf until a newline is encountered: + * @code asio::streambuf b; + * asio::read_until(s, b, '\n'); + * std::istream is(&b); + * std::string line; + * std::getline(is, line); @endcode + * After the @c read_until operation completes successfully, the buffer @c b + * contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode + * The call to @c std::getline then extracts the data up to and including the + * delimiter, so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\n' } @endcode + * The remaining data is left in the buffer @c b as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c read_until operation. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, char delim); + +/// Read data into a streambuf until it contains a specified delimiter. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains the specified delimiter. The call will block + * until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains the + * delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param delim The delimiter character. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the delimiter. Returns 0 if an error occurred. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond the delimiter. An application will typically leave + * that data in the streambuf for a subsequent read_until operation to examine. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, char delim, + asio::error_code& ec); + +/// Read data into a streambuf until it contains a specified delimiter. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains the specified delimiter. The call will block + * until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains the + * delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param delim The delimiter string. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the delimiter. + * + * @throws asio::system_error Thrown on failure. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond the delimiter. An application will typically leave + * that data in the streambuf for a subsequent read_until operation to examine. + * + * @par Example + * To read data into a streambuf until a newline is encountered: + * @code asio::streambuf b; + * asio::read_until(s, b, "\r\n"); + * std::istream is(&b); + * std::string line; + * std::getline(is, line); @endcode + * After the @c read_until operation completes successfully, the buffer @c b + * contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode + * The call to @c std::getline then extracts the data up to and including the + * delimiter, so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode + * The remaining data is left in the buffer @c b as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c read_until operation. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, const std::string& delim); + +/// Read data into a streambuf until it contains a specified delimiter. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains the specified delimiter. The call will block + * until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains the + * delimiter, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param delim The delimiter string. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the delimiter. Returns 0 if an error occurred. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond the delimiter. An application will typically leave + * that data in the streambuf for a subsequent read_until operation to examine. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, const std::string& delim, + asio::error_code& ec); + +/// Read data into a streambuf until some part of the data it contains matches +/// a regular expression. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains some data that matches a regular expression. + * The call will block until one of the following conditions is true: + * + * @li A substring of the streambuf's get area matches the regular expression. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains data that + * matches the regular expression, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param expr The regular expression. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the substring that matches the regular expression. + * + * @throws asio::system_error Thrown on failure. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond that which matched the regular expression. An + * application will typically leave that data in the streambuf for a subsequent + * read_until operation to examine. + * + * @par Example + * To read data into a streambuf until a CR-LF sequence is encountered: + * @code asio::streambuf b; + * asio::read_until(s, b, boost::regex("\r\n")); + * std::istream is(&b); + * std::string line; + * std::getline(is, line); @endcode + * After the @c read_until operation completes successfully, the buffer @c b + * contains the data which matched the regular expression: + * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode + * The call to @c std::getline then extracts the data up to and including the + * match, so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode + * The remaining data is left in the buffer @c b as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c read_until operation. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, const boost::regex& expr); + +/// Read data into a streambuf until some part of the data it contains matches +/// a regular expression. +/** + * This function is used to read data into the specified streambuf until the + * streambuf's get area contains some data that matches a regular expression. + * The call will block until one of the following conditions is true: + * + * @li A substring of the streambuf's get area matches the regular expression. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the streambuf's get area already contains data that + * matches the regular expression, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param expr The regular expression. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the streambuf's get area up to and including + * the substring that matches the regular expression. Returns 0 if an error + * occurred. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond that which matched the regular expression. An + * application will typically leave that data in the streambuf for a subsequent + * read_until operation to examine. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, const boost::regex& expr, + asio::error_code& ec); + +/// Read data into a streambuf until a function object indicates a match. +/** + * This function is used to read data into the specified streambuf until a + * user-defined match condition function object, when applied to the data + * contained in the streambuf, indicates a successful match. The call will + * block until one of the following conditions is true: + * + * @li The match condition function object returns a std::pair where the second + * element evaluates to true. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the match condition function object already indicates + * a match, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param match_condition The function object to be called to determine whether + * a match exists. The signature of the function object must be: + * @code pair match_condition(iterator begin, iterator end); + * @endcode + * where @c iterator represents the type: + * @code buffers_iterator::const_buffers_type> + * @endcode + * The iterator parameters @c begin and @c end define the range of bytes to be + * scanned to determine whether there is a match. The @c first member of the + * return value is an iterator marking one-past-the-end of the bytes that have + * been consumed by the match function. This iterator is used to calculate the + * @c begin parameter for any subsequent invocation of the match condition. The + * @c second member of the return value is true if a match has been found, false + * otherwise. + * + * @returns The number of bytes in the streambuf's get area that have been fully + * consumed by the match function. + * + * @throws asio::system_error Thrown on failure. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond that which matched the function object. An application + * will typically leave that data in the streambuf for a subsequent + * + * @note The default implementation of the @c is_match_condition type trait + * evaluates to true for function pointers and function objects with a + * @c result_type typedef. It must be specialised for other user-defined + * function objects. + * + * @par Examples + * To read data into a streambuf until whitespace is encountered: + * @code typedef asio::buffers_iterator< + * asio::streambuf::const_buffers_type> iterator; + * + * std::pair + * match_whitespace(iterator begin, iterator end) + * { + * iterator i = begin; + * while (i != end) + * if (std::isspace(*i++)) + * return std::make_pair(i, true); + * return std::make_pair(i, false); + * } + * ... + * asio::streambuf b; + * asio::read_until(s, b, match_whitespace); + * @endcode + * + * To read data into a streambuf until a matching character is found: + * @code class match_char + * { + * public: + * explicit match_char(char c) : c_(c) {} + * + * template + * std::pair operator()( + * Iterator begin, Iterator end) const + * { + * Iterator i = begin; + * while (i != end) + * if (c_ == *i++) + * return std::make_pair(i, true); + * return std::make_pair(i, false); + * } + * + * private: + * char c_; + * }; + * + * namespace asio { + * template <> struct is_match_condition + * : public boost::true_type {}; + * } // namespace asio + * ... + * asio::streambuf b; + * asio::read_until(s, b, match_char('a')); + * @endcode + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, MatchCondition match_condition, + typename boost::enable_if >::type* = 0); + +/// Read data into a streambuf until a function object indicates a match. +/** + * This function is used to read data into the specified streambuf until a + * user-defined match condition function object, when applied to the data + * contained in the streambuf, indicates a successful match. The call will + * block until one of the following conditions is true: + * + * @li The match condition function object returns a std::pair where the second + * element evaluates to true. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * read_some function. If the match condition function object already indicates + * a match, the function returns immediately. + * + * @param s The stream from which the data is to be read. The type must support + * the SyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param match_condition The function object to be called to determine whether + * a match exists. The signature of the function object must be: + * @code pair match_condition(iterator begin, iterator end); + * @endcode + * where @c iterator represents the type: + * @code buffers_iterator::const_buffers_type> + * @endcode + * The iterator parameters @c begin and @c end define the range of bytes to be + * scanned to determine whether there is a match. The @c first member of the + * return value is an iterator marking one-past-the-end of the bytes that have + * been consumed by the match function. This iterator is used to calculate the + * @c begin parameter for any subsequent invocation of the match condition. The + * @c second member of the return value is true if a match has been found, false + * otherwise. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes in the streambuf's get area that have been fully + * consumed by the match function. Returns 0 if an error occurred. + * + * @note After a successful read_until operation, the streambuf may contain + * additional data beyond that which matched the function object. An application + * will typically leave that data in the streambuf for a subsequent + * + * @note The default implementation of the @c is_match_condition type trait + * evaluates to true for function pointers and function objects with a + * @c result_type typedef. It must be specialised for other user-defined + * function objects. + */ +template +std::size_t read_until(SyncReadStream& s, + asio::basic_streambuf& b, + MatchCondition match_condition, asio::error_code& ec, + typename boost::enable_if >::type* = 0); + +/*@}*/ +/** + * @defgroup async_read_until asio::async_read_until + * + * @brief Start an asynchronous operation to read data into a streambuf until it + * contains a delimiter, matches a regular expression, or a function object + * indicates a match. + */ +/*@{*/ + +/// Start an asynchronous operation to read data into a streambuf until it +/// contains a specified delimiter. +/** + * This function is used to asynchronously read data into the specified + * streambuf until the streambuf's get area contains the specified delimiter. + * The function call always returns immediately. The asynchronous operation + * will continue until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. If + * the streambuf's get area already contains the delimiter, this asynchronous + * operation completes immediately. The program must ensure that the stream + * performs no other read operations (such as async_read, async_read_until, the + * stream's async_read_some function, or any other composed operations that + * perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. Ownership of + * the streambuf is retained by the caller, which must guarantee that it remains + * valid until the handler is called. + * + * @param delim The delimiter character. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * // Result of operation. + * const asio::error_code& error, + * + * // The number of bytes in the streambuf's get + * // area up to and including the delimiter. + * // 0 if an error occurred. + * std::size_t bytes_transferred + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note After a successful async_read_until operation, the streambuf may + * contain additional data beyond the delimiter. An application will typically + * leave that data in the streambuf for a subsequent async_read_until operation + * to examine. + * + * @par Example + * To asynchronously read data into a streambuf until a newline is encountered: + * @code asio::streambuf b; + * ... + * void handler(const asio::error_code& e, std::size_t size) + * { + * if (!e) + * { + * std::istream is(&b); + * std::string line; + * std::getline(is, line); + * ... + * } + * } + * ... + * asio::async_read_until(s, b, '\n', handler); @endcode + * After the @c async_read_until operation completes successfully, the buffer + * @c b contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode + * The call to @c std::getline then extracts the data up to and including the + * delimiter, so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\n' } @endcode + * The remaining data is left in the buffer @c b as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c async_read_until operation. + */ +template +void async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, + char delim, ReadHandler handler); + +/// Start an asynchronous operation to read data into a streambuf until it +/// contains a specified delimiter. +/** + * This function is used to asynchronously read data into the specified + * streambuf until the streambuf's get area contains the specified delimiter. + * The function call always returns immediately. The asynchronous operation + * will continue until one of the following conditions is true: + * + * @li The get area of the streambuf contains the specified delimiter. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. If + * the streambuf's get area already contains the delimiter, this asynchronous + * operation completes immediately. The program must ensure that the stream + * performs no other read operations (such as async_read, async_read_until, the + * stream's async_read_some function, or any other composed operations that + * perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. Ownership of + * the streambuf is retained by the caller, which must guarantee that it remains + * valid until the handler is called. + * + * @param delim The delimiter string. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * // Result of operation. + * const asio::error_code& error, + * + * // The number of bytes in the streambuf's get + * // area up to and including the delimiter. + * // 0 if an error occurred. + * std::size_t bytes_transferred + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note After a successful async_read_until operation, the streambuf may + * contain additional data beyond the delimiter. An application will typically + * leave that data in the streambuf for a subsequent async_read_until operation + * to examine. + * + * @par Example + * To asynchronously read data into a streambuf until a newline is encountered: + * @code asio::streambuf b; + * ... + * void handler(const asio::error_code& e, std::size_t size) + * { + * if (!e) + * { + * std::istream is(&b); + * std::string line; + * std::getline(is, line); + * ... + * } + * } + * ... + * asio::async_read_until(s, b, "\r\n", handler); @endcode + * After the @c async_read_until operation completes successfully, the buffer + * @c b contains the delimiter: + * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode + * The call to @c std::getline then extracts the data up to and including the + * delimiter, so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode + * The remaining data is left in the buffer @c b as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c async_read_until operation. + */ +template +void async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, const std::string& delim, + ReadHandler handler); + +/// Start an asynchronous operation to read data into a streambuf until some +/// part of its data matches a regular expression. +/** + * This function is used to asynchronously read data into the specified + * streambuf until the streambuf's get area contains some data that matches a + * regular expression. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li A substring of the streambuf's get area matches the regular expression. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. If + * the streambuf's get area already contains data that matches the regular + * expression, this asynchronous operation completes immediately. The program + * must ensure that the stream performs no other read operations (such as + * async_read, async_read_until, the stream's async_read_some function, or any + * other composed operations that perform reads) until this operation + * completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. Ownership of + * the streambuf is retained by the caller, which must guarantee that it remains + * valid until the handler is called. + * + * @param expr The regular expression. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * // Result of operation. + * const asio::error_code& error, + * + * // The number of bytes in the streambuf's get + * // area up to and including the substring + * // that matches the regular. expression. + * // 0 if an error occurred. + * std::size_t bytes_transferred + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note After a successful async_read_until operation, the streambuf may + * contain additional data beyond that which matched the regular expression. An + * application will typically leave that data in the streambuf for a subsequent + * async_read_until operation to examine. + * + * @par Example + * To asynchronously read data into a streambuf until a CR-LF sequence is + * encountered: + * @code asio::streambuf b; + * ... + * void handler(const asio::error_code& e, std::size_t size) + * { + * if (!e) + * { + * std::istream is(&b); + * std::string line; + * std::getline(is, line); + * ... + * } + * } + * ... + * asio::async_read_until(s, b, boost::regex("\r\n"), handler); @endcode + * After the @c async_read_until operation completes successfully, the buffer + * @c b contains the data which matched the regular expression: + * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode + * The call to @c std::getline then extracts the data up to and including the + * match, so that the string @c line contains: + * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode + * The remaining data is left in the buffer @c b as follows: + * @code { 'd', 'e', ... } @endcode + * This data may be the start of a new line, to be extracted by a subsequent + * @c async_read_until operation. + */ +template +void async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, const boost::regex& expr, + ReadHandler handler); + +/// Start an asynchronous operation to read data into a streambuf until a +/// function object indicates a match. +/** + * This function is used to asynchronously read data into the specified + * streambuf until a user-defined match condition function object, when applied + * to the data contained in the streambuf, indicates a successful match. The + * function call always returns immediately. The asynchronous operation will + * continue until one of the following conditions is true: + * + * @li The match condition function object returns a std::pair where the second + * element evaluates to true. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_read_some function, and is known as a composed operation. If + * the match condition function object already indicates a match, this + * asynchronous operation completes immediately. The program must ensure that + * the stream performs no other read operations (such as async_read, + * async_read_until, the stream's async_read_some function, or any other + * composed operations that perform reads) until this operation completes. + * + * @param s The stream from which the data is to be read. The type must support + * the AsyncReadStream concept. + * + * @param b A streambuf object into which the data will be read. + * + * @param match_condition The function object to be called to determine whether + * a match exists. The signature of the function object must be: + * @code pair match_condition(iterator begin, iterator end); + * @endcode + * where @c iterator represents the type: + * @code buffers_iterator::const_buffers_type> + * @endcode + * The iterator parameters @c begin and @c end define the range of bytes to be + * scanned to determine whether there is a match. The @c first member of the + * return value is an iterator marking one-past-the-end of the bytes that have + * been consumed by the match function. This iterator is used to calculate the + * @c begin parameter for any subsequent invocation of the match condition. The + * @c second member of the return value is true if a match has been found, false + * otherwise. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * // Result of operation. + * const asio::error_code& error, + * + * // The number of bytes in the streambuf's get + * // area that have been fully consumed by the + * // match function. O if an error occurred. + * std::size_t bytes_transferred + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note After a successful async_read_until operation, the streambuf may + * contain additional data beyond that which matched the function object. An + * application will typically leave that data in the streambuf for a subsequent + * async_read_until operation to examine. + * + * @note The default implementation of the @c is_match_condition type trait + * evaluates to true for function pointers and function objects with a + * @c result_type typedef. It must be specialised for other user-defined + * function objects. + * + * @par Examples + * To asynchronously read data into a streambuf until whitespace is encountered: + * @code typedef asio::buffers_iterator< + * asio::streambuf::const_buffers_type> iterator; + * + * std::pair + * match_whitespace(iterator begin, iterator end) + * { + * iterator i = begin; + * while (i != end) + * if (std::isspace(*i++)) + * return std::make_pair(i, true); + * return std::make_pair(i, false); + * } + * ... + * void handler(const asio::error_code& e, std::size_t size); + * ... + * asio::streambuf b; + * asio::async_read_until(s, b, match_whitespace, handler); + * @endcode + * + * To asynchronously read data into a streambuf until a matching character is + * found: + * @code class match_char + * { + * public: + * explicit match_char(char c) : c_(c) {} + * + * template + * std::pair operator()( + * Iterator begin, Iterator end) const + * { + * Iterator i = begin; + * while (i != end) + * if (c_ == *i++) + * return std::make_pair(i, true); + * return std::make_pair(i, false); + * } + * + * private: + * char c_; + * }; + * + * namespace asio { + * template <> struct is_match_condition + * : public boost::true_type {}; + * } // namespace asio + * ... + * void handler(const asio::error_code& e, std::size_t size); + * ... + * asio::streambuf b; + * asio::async_read_until(s, b, match_char('a'), handler); + * @endcode + */ +template +void async_read_until(AsyncReadStream& s, + asio::basic_streambuf& b, + MatchCondition match_condition, ReadHandler handler, + typename boost::enable_if >::type* = 0); + +/*@}*/ + +} // namespace asio + +#include "asio/impl/read_until.ipp" + +#endif // !defined(BOOST_NO_IOSTREAM) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_READ_UNTIL_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/serial_port.hpp b/src/libs/resiprocate/contrib/asio/asio/serial_port.hpp new file mode 100644 index 00000000..a55a03aa --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/serial_port.hpp @@ -0,0 +1,38 @@ +// +// serial_port.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SERIAL_PORT_HPP +#define ASIO_SERIAL_PORT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/basic_serial_port.hpp" + +#if defined(ASIO_HAS_SERIAL_PORT) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { + +/// Typedef for the typical usage of a serial port. +typedef basic_serial_port<> serial_port; + +} // namespace asio + +#endif // defined(ASIO_HAS_SERIAL_PORT) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SERIAL_PORT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/serial_port_base.hpp b/src/libs/resiprocate/contrib/asio/asio/serial_port_base.hpp new file mode 100644 index 00000000..28e51a08 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/serial_port_base.hpp @@ -0,0 +1,173 @@ +// +// serial_port_base.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SERIAL_PORT_BASE_HPP +#define ASIO_SERIAL_PORT_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#if !defined(ASIO_DISABLE_SERIAL_PORT) +# if defined(ASIO_HAS_IOCP) \ + || !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +# define ASIO_HAS_SERIAL_PORT 1 +# endif // defined(ASIO_HAS_IOCP) +#endif // !defined(ASIO_DISABLE_STREAM_HANDLE) + +#if defined(ASIO_HAS_SERIAL_PORT) \ + || defined(GENERATING_DOCUMENTATION) + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +# include "asio/detail/push_options.hpp" +# include +# include "asio/detail/pop_options.hpp" +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include "asio/error_code.hpp" +#include "asio/detail/socket_types.hpp" + +#if defined(GENERATING_DOCUMENTATION) +# define ASIO_OPTION_STORAGE implementation_defined +#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# define ASIO_OPTION_STORAGE DCB +#else +# define ASIO_OPTION_STORAGE termios +#endif + +namespace asio { + +/// The serial_port_base class is used as a base for the basic_serial_port class +/// template so that we have a common place to define the serial port options. +class serial_port_base +{ +public: + /// Serial port option to permit changing the baud rate. + /** + * Implements changing the baud rate for a given serial port. + */ + class baud_rate + { + public: + explicit baud_rate(unsigned int rate = 0); + unsigned int value() const; + asio::error_code store(ASIO_OPTION_STORAGE& storage, + asio::error_code& ec) const; + asio::error_code load(const ASIO_OPTION_STORAGE& storage, + asio::error_code& ec); + private: + unsigned int value_; + }; + + /// Serial port option to permit changing the flow control. + /** + * Implements changing the flow control for a given serial port. + */ + class flow_control + { + public: + enum type { none, software, hardware }; + explicit flow_control(type t = none); + type value() const; + asio::error_code store(ASIO_OPTION_STORAGE& storage, + asio::error_code& ec) const; + asio::error_code load(const ASIO_OPTION_STORAGE& storage, + asio::error_code& ec); + private: + type value_; + }; + + /// Serial port option to permit changing the parity. + /** + * Implements changing the parity for a given serial port. + */ + class parity + { + public: + enum type { none, odd, even }; + explicit parity(type t = none); + type value() const; + asio::error_code store(ASIO_OPTION_STORAGE& storage, + asio::error_code& ec) const; + asio::error_code load(const ASIO_OPTION_STORAGE& storage, + asio::error_code& ec); + private: + type value_; + }; + + /// Serial port option to permit changing the number of stop bits. + /** + * Implements changing the number of stop bits for a given serial port. + */ + class stop_bits + { + public: + enum type { one, onepointfive, two }; + explicit stop_bits(type t = one); + type value() const; + asio::error_code store(ASIO_OPTION_STORAGE& storage, + asio::error_code& ec) const; + asio::error_code load(const ASIO_OPTION_STORAGE& storage, + asio::error_code& ec); + private: + type value_; + }; + + /// Serial port option to permit changing the character size. + /** + * Implements changing the character size for a given serial port. + */ + class character_size + { + public: + explicit character_size(unsigned int t = 8); + unsigned int value() const; + asio::error_code store(ASIO_OPTION_STORAGE& storage, + asio::error_code& ec) const; + asio::error_code load(const ASIO_OPTION_STORAGE& storage, + asio::error_code& ec); + private: + unsigned int value_; + }; + +protected: + /// Protected destructor to prevent deletion through this type. + ~serial_port_base() + { + } + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +private: + // Workaround to enable the empty base optimisation with Borland C++. + char dummy_; +#endif +}; + +} // namespace asio + +#include "asio/impl/serial_port_base.ipp" + +#undef ASIO_OPTION_STORAGE + +#endif // defined(ASIO_HAS_SERIAL_PORT) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SERIAL_PORT_BASE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/serial_port_service.hpp b/src/libs/resiprocate/contrib/asio/asio/serial_port_service.hpp new file mode 100644 index 00000000..5847c293 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/serial_port_service.hpp @@ -0,0 +1,207 @@ +// +// serial_port_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SERIAL_PORT_SERVICE_HPP +#define ASIO_SERIAL_PORT_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/serial_port_base.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/detail/reactive_serial_port_service.hpp" +#include "asio/detail/win_iocp_serial_port_service.hpp" + +#if defined(ASIO_HAS_SERIAL_PORT) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { + +/// Default service implementation for a serial port. +class serial_port_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_service::service +#else + : public asio::detail::service_base +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_service::id id; +#endif + +private: + // The type of the platform-specific implementation. +#if defined(ASIO_HAS_IOCP) + typedef detail::win_iocp_serial_port_service service_impl_type; +#else + typedef detail::reactive_serial_port_service service_impl_type; +#endif + +public: + /// The type of a serial port implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef service_impl_type::implementation_type implementation_type; +#endif + + /// The native handle type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef service_impl_type::native_type native_type; +#endif + + /// Construct a new serial port service for the specified io_service. + explicit serial_port_service(asio::io_service& io_service) + : asio::detail::service_base(io_service), + service_impl_(io_service) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + service_impl_.shutdown_service(); + } + + /// Construct a new serial port implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a serial port implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Open a serial port. + asio::error_code open(implementation_type& impl, + const std::string& device, asio::error_code& ec) + { + return service_impl_.open(impl, device, ec); + } + + /// Assign an existing native handle to a serial port. + asio::error_code assign(implementation_type& impl, + const native_type& native_handle, asio::error_code& ec) + { + return service_impl_.assign(impl, native_handle, ec); + } + + /// Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a serial port implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// Get the native handle implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native(impl); + } + + /// Cancel all asynchronous operations associated with the handle. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Set a serial port option. + template + asio::error_code set_option(implementation_type& impl, + const SettableSerialPortOption& option, asio::error_code& ec) + { + return service_impl_.set_option(impl, option, ec); + } + + /// Get a serial port option. + template + asio::error_code get_option(const implementation_type& impl, + GettableSerialPortOption& option, asio::error_code& ec) const + { + return service_impl_.get_option(impl, option, ec); + } + + /// Send a break sequence to the serial port. + asio::error_code send_break(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.send_break(impl, ec); + } + + /// Write the given data to the stream. + template + std::size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.write_some(impl, buffers, ec); + } + + /// Start an asynchronous write. + template + void async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, WriteHandler handler) + { + service_impl_.async_write_some(impl, buffers, handler); + } + + /// Read some data from the stream. + template + std::size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.read_some(impl, buffers, ec); + } + + /// Start an asynchronous read. + template + void async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, ReadHandler handler) + { + service_impl_.async_read_some(impl, buffers, handler); + } + +private: + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace asio + +#endif // defined(ASIO_HAS_SERIAL_PORT) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SERIAL_PORT_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/socket_acceptor_service.hpp b/src/libs/resiprocate/contrib/asio/asio/socket_acceptor_service.hpp new file mode 100644 index 00000000..b2e2c6d2 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/socket_acceptor_service.hpp @@ -0,0 +1,217 @@ +// +// socket_acceptor_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SOCKET_ACCEPTOR_SERVICE_HPP +#define ASIO_SOCKET_ACCEPTOR_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/basic_socket.hpp" +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/service_base.hpp" + +#if defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +#else +# include "asio/detail/reactive_socket_service.hpp" +#endif + +namespace asio { + +/// Default service implementation for a socket acceptor. +template +class socket_acceptor_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_service::service +#else + : public asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_service::id id; +#endif + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename protocol_type::endpoint endpoint_type; + +private: + // The type of the platform-specific implementation. +#if defined(ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#else + typedef detail::reactive_socket_service service_impl_type; +#endif + +public: + /// The native type of the socket acceptor. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// The native acceptor type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef typename service_impl_type::native_type native_type; +#endif + + /// Construct a new socket acceptor service for the specified io_service. + explicit socket_acceptor_service(asio::io_service& io_service) + : asio::detail::service_base< + socket_acceptor_service >(io_service), + service_impl_(io_service) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + service_impl_.shutdown_service(); + } + + /// Construct a new socket acceptor implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a socket acceptor implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Open a new socket acceptor implementation. + asio::error_code open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + return service_impl_.open(impl, protocol, ec); + } + + /// Assign an existing native acceptor to a socket acceptor. + asio::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_acceptor, + asio::error_code& ec) + { + return service_impl_.assign(impl, protocol, native_acceptor, ec); + } + + /// Determine whether the acceptor is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Cancel all asynchronous operations associated with the acceptor. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Bind the socket acceptor to the specified local endpoint. + asio::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + return service_impl_.bind(impl, endpoint, ec); + } + + /// Place the socket acceptor into the state where it will listen for new + /// connections. + asio::error_code listen(implementation_type& impl, int backlog, + asio::error_code& ec) + { + return service_impl_.listen(impl, backlog, ec); + } + + /// Close a socket acceptor implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// Get the native acceptor implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native(impl); + } + + /// Set a socket option. + template + asio::error_code set_option(implementation_type& impl, + const SettableSocketOption& option, asio::error_code& ec) + { + return service_impl_.set_option(impl, option, ec); + } + + /// Get a socket option. + template + asio::error_code get_option(const implementation_type& impl, + GettableSocketOption& option, asio::error_code& ec) const + { + return service_impl_.get_option(impl, option, ec); + } + + /// Perform an IO control command on the socket. + template + asio::error_code io_control(implementation_type& impl, + IoControlCommand& command, asio::error_code& ec) + { + return service_impl_.io_control(impl, command, ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Accept a new connection. + template + asio::error_code accept(implementation_type& impl, + basic_socket& peer, + endpoint_type* peer_endpoint, asio::error_code& ec) + { + return service_impl_.accept(impl, peer, peer_endpoint, ec); + } + + /// Start an asynchronous accept. + template + void async_accept(implementation_type& impl, + basic_socket& peer, + endpoint_type* peer_endpoint, AcceptHandler handler) + { + service_impl_.async_accept(impl, peer, peer_endpoint, handler); + } + +private: + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SOCKET_ACCEPTOR_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/socket_base.hpp b/src/libs/resiprocate/contrib/asio/asio/socket_base.hpp new file mode 100644 index 00000000..d82cd22e --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/socket_base.hpp @@ -0,0 +1,515 @@ +// +// socket_base.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SOCKET_BASE_HPP +#define ASIO_SOCKET_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/io_control.hpp" +#include "asio/detail/socket_option.hpp" +#include "asio/detail/socket_types.hpp" + +namespace asio { + +/// The socket_base class is used as a base for the basic_stream_socket and +/// basic_datagram_socket class templates so that we have a common place to +/// define the shutdown_type and enum. +class socket_base +{ +public: + /// Different ways a socket may be shutdown. + enum shutdown_type + { +#if defined(GENERATING_DOCUMENTATION) + /// Shutdown the receive side of the socket. + shutdown_receive = implementation_defined, + + /// Shutdown the send side of the socket. + shutdown_send = implementation_defined, + + /// Shutdown both send and receive on the socket. + shutdown_both = implementation_defined +#else + shutdown_receive = asio::detail::shutdown_receive, + shutdown_send = asio::detail::shutdown_send, + shutdown_both = asio::detail::shutdown_both +#endif + }; + + /// Bitmask type for flags that can be passed to send and receive operations. + typedef int message_flags; + +#if defined(GENERATING_DOCUMENTATION) + /// Peek at incoming data without removing it from the input queue. + static const int message_peek = implementation_defined; + + /// Process out-of-band data. + static const int message_out_of_band = implementation_defined; + + /// Specify that the data should not be subject to routing. + static const int message_do_not_route = implementation_defined; +#else + BOOST_STATIC_CONSTANT(int, + message_peek = asio::detail::message_peek); + BOOST_STATIC_CONSTANT(int, + message_out_of_band = asio::detail::message_out_of_band); + BOOST_STATIC_CONSTANT(int, + message_do_not_route = asio::detail::message_do_not_route); +#endif + + /// Socket option to permit sending of broadcast messages. + /** + * Implements the SOL_SOCKET/SO_BROADCAST socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::socket_base::broadcast option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::socket_base::broadcast option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined broadcast; +#else + typedef asio::detail::socket_option::boolean< + SOL_SOCKET, SO_BROADCAST> broadcast; +#endif + + /// Socket option to enable socket-level debugging. + /** + * Implements the SOL_SOCKET/SO_DEBUG socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::debug option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::debug option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined debug; +#else + typedef asio::detail::socket_option::boolean< + SOL_SOCKET, SO_DEBUG> debug; +#endif + + /// Socket option to prevent routing, use local interfaces only. + /** + * Implements the SOL_SOCKET/SO_DONTROUTE socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::socket_base::do_not_route option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_service); + * ... + * asio::socket_base::do_not_route option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined do_not_route; +#else + typedef asio::detail::socket_option::boolean< + SOL_SOCKET, SO_DONTROUTE> do_not_route; +#endif + + /// Socket option to send keep-alives. + /** + * Implements the SOL_SOCKET/SO_KEEPALIVE socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::keep_alive option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::keep_alive option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined keep_alive; +#else + typedef asio::detail::socket_option::boolean< + SOL_SOCKET, SO_KEEPALIVE> keep_alive; +#endif + + /// Socket option for the send buffer size of a socket. + /** + * Implements the SOL_SOCKET/SO_SNDBUF socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::send_buffer_size option(8192); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::send_buffer_size option; + * socket.get_option(option); + * int size = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Integer_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined send_buffer_size; +#else + typedef asio::detail::socket_option::integer< + SOL_SOCKET, SO_SNDBUF> send_buffer_size; +#endif + + /// Socket option for the send low watermark. + /** + * Implements the SOL_SOCKET/SO_SNDLOWAT socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::send_low_watermark option(1024); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::send_low_watermark option; + * socket.get_option(option); + * int size = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Integer_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined send_low_watermark; +#else + typedef asio::detail::socket_option::integer< + SOL_SOCKET, SO_SNDLOWAT> send_low_watermark; +#endif + + /// Socket option for the receive buffer size of a socket. + /** + * Implements the SOL_SOCKET/SO_RCVBUF socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::receive_buffer_size option(8192); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::receive_buffer_size option; + * socket.get_option(option); + * int size = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Integer_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined receive_buffer_size; +#else + typedef asio::detail::socket_option::integer< + SOL_SOCKET, SO_RCVBUF> receive_buffer_size; +#endif + + /// Socket option for the receive low watermark. + /** + * Implements the SOL_SOCKET/SO_RCVLOWAT socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::receive_low_watermark option(1024); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::receive_low_watermark option; + * socket.get_option(option); + * int size = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Integer_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined receive_low_watermark; +#else + typedef asio::detail::socket_option::integer< + SOL_SOCKET, SO_RCVLOWAT> receive_low_watermark; +#endif + + /// Socket option to allow the socket to be bound to an address that is + /// already in use. + /** + * Implements the SOL_SOCKET/SO_REUSEADDR socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::socket_base::reuse_address option(true); + * acceptor.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::socket_base::reuse_address option; + * acceptor.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined reuse_address; +#else + typedef asio::detail::socket_option::boolean< + SOL_SOCKET, SO_REUSEADDR> reuse_address; +#endif + + /// Socket option to specify whether the socket lingers on close if unsent + /// data is present. + /** + * Implements the SOL_SOCKET/SO_LINGER socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::linger option(true, 30); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::linger option; + * socket.get_option(option); + * bool is_set = option.enabled(); + * unsigned short timeout = option.timeout(); + * @endcode + * + * @par Concepts: + * Socket_Option, Linger_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined linger; +#else + typedef asio::detail::socket_option::linger< + SOL_SOCKET, SO_LINGER> linger; +#endif + + /// Socket option to report aborted connections on accept. + /** + * Implements a custom socket option that determines whether or not an accept + * operation is permitted to fail with asio::error::connection_aborted. + * By default the option is false. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::socket_base::enable_connection_aborted option(true); + * acceptor.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::acceptor acceptor(io_service); + * ... + * asio::socket_base::enable_connection_aborted option; + * acceptor.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined enable_connection_aborted; +#else + typedef asio::detail::socket_option::boolean< + asio::detail::custom_socket_option_level, + asio::detail::enable_connection_aborted_option> + enable_connection_aborted; +#endif + + /// IO control command to set the blocking mode of the socket. + /** + * Implements the FIONBIO IO control command. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::non_blocking_io command(true); + * socket.io_control(command); + * @endcode + * + * @par Concepts: + * IO_Control_Command, Boolean_IO_Control_Command. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined non_blocking_io; +#else + typedef asio::detail::io_control::non_blocking_io non_blocking_io; +#endif + + /// IO control command to get the amount of data that can be read without + /// blocking. + /** + * Implements the FIONREAD IO control command. + * + * @par Example + * @code + * asio::ip::tcp::socket socket(io_service); + * ... + * asio::socket_base::bytes_readable command(true); + * socket.io_control(command); + * std::size_t bytes_readable = command.get(); + * @endcode + * + * @par Concepts: + * IO_Control_Command, Size_IO_Control_Command. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined bytes_readable; +#else + typedef asio::detail::io_control::bytes_readable bytes_readable; +#endif + + /// The maximum length of the queue of pending incoming connections. +#if defined(GENERATING_DOCUMENTATION) + static const int max_connections = implementation_defined; +#else + BOOST_STATIC_CONSTANT(int, max_connections = SOMAXCONN); +#endif + +protected: + /// Protected destructor to prevent deletion through this type. + ~socket_base() + { + } + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +private: + // Workaround to enable the empty base optimisation with Borland C++. + char dummy_; +#endif +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SOCKET_BASE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl.hpp new file mode 100644 index 00000000..a9fff5e6 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl.hpp @@ -0,0 +1,26 @@ +// +// ssl.hpp +// ~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_HPP +#define ASIO_SSL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/ssl/basic_context.hpp" +#include "asio/ssl/context.hpp" +#include "asio/ssl/context_base.hpp" +#include "asio/ssl/context_service.hpp" +#include "asio/ssl/stream.hpp" +#include "asio/ssl/stream_base.hpp" +#include "asio/ssl/stream_service.hpp" + +#endif // ASIO_SSL_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl/basic_context.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl/basic_context.hpp new file mode 100644 index 00000000..ea3893ed --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl/basic_context.hpp @@ -0,0 +1,434 @@ +// +// basic_context.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_BASIC_CONTEXT_HPP +#define ASIO_SSL_BASIC_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/ssl/context_base.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { +namespace ssl { + +/// SSL context. +template +class basic_context + : public context_base, + private boost::noncopyable +{ +public: + /// The type of the service that will be used to provide context operations. + typedef Service service_type; + + /// The native implementation type of the locking dispatcher. + typedef typename service_type::impl_type impl_type; + + /// Constructor. + basic_context(asio::io_service& io_service, method m) + : service_(asio::use_service(io_service)), + impl_(service_.null()) + { + service_.create(impl_, m); + } + + /// Destructor. + ~basic_context() + { + service_.destroy(impl_); + } + + /// Get the underlying implementation in the native type. + /** + * This function may be used to obtain the underlying implementation of the + * context. This is intended to allow access to context functionality that is + * not otherwise provided. + */ + impl_type impl() + { + return impl_; + } + + /// Set options on the context. + /** + * This function may be used to configure the SSL options used by the context. + * + * @param o A bitmask of options. The available option values are defined in + * the context_base class. The options are bitwise-ored with any existing + * value for the options. + * + * @throws asio::system_error Thrown on failure. + */ + void set_options(options o) + { + asio::error_code ec; + service_.set_options(impl_, o, ec); + asio::detail::throw_error(ec); + } + + /// Set options on the context. + /** + * This function may be used to configure the SSL options used by the context. + * + * @param o A bitmask of options. The available option values are defined in + * the context_base class. The options are bitwise-ored with any existing + * value for the options. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code set_options(options o, + asio::error_code& ec) + { + return service_.set_options(impl_, o, ec); + } + + /// Set the peer verification mode. + /** + * This function may be used to configure the peer verification mode used by + * the context. + * + * @param v A bitmask of peer verification modes. The available verify_mode + * values are defined in the context_base class. + * + * @throws asio::system_error Thrown on failure. + */ + void set_verify_mode(verify_mode v) + { + asio::error_code ec; + service_.set_verify_mode(impl_, v, ec); + asio::detail::throw_error(ec); + } + + /// Set the peer verification mode. + /** + * This function may be used to configure the peer verification mode used by + * the context. + * + * @param v A bitmask of peer verification modes. The available verify_mode + * values are defined in the context_base class. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code set_verify_mode(verify_mode v, + asio::error_code& ec) + { + return service_.set_verify_mode(impl_, v, ec); + } + + /// Load a certification authority file for performing verification. + /** + * This function is used to load one or more trusted certification authorities + * from a file. + * + * @param filename The name of a file containing certification authority + * certificates in PEM format. + * + * @throws asio::system_error Thrown on failure. + */ + void load_verify_file(const std::string& filename) + { + asio::error_code ec; + service_.load_verify_file(impl_, filename, ec); + asio::detail::throw_error(ec); + } + + /// Load a certification authority file for performing verification. + /** + * This function is used to load the certificates for one or more trusted + * certification authorities from a file. + * + * @param filename The name of a file containing certification authority + * certificates in PEM format. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code load_verify_file(const std::string& filename, + asio::error_code& ec) + { + return service_.load_verify_file(impl_, filename, ec); + } + + /// Add a directory containing certificate authority files to be used for + /// performing verification. + /** + * This function is used to specify the name of a directory containing + * certification authority certificates. Each file in the directory must + * contain a single certificate. The files must be named using the subject + * name's hash and an extension of ".0". + * + * @param path The name of a directory containing the certificates. + * + * @throws asio::system_error Thrown on failure. + */ + void add_verify_path(const std::string& path) + { + asio::error_code ec; + service_.add_verify_path(impl_, path, ec); + asio::detail::throw_error(ec); + } + + /// Add a directory containing certificate authority files to be used for + /// performing verification. + /** + * This function is used to specify the name of a directory containing + * certification authority certificates. Each file in the directory must + * contain a single certificate. The files must be named using the subject + * name's hash and an extension of ".0". + * + * @param path The name of a directory containing the certificates. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code add_verify_path(const std::string& path, + asio::error_code& ec) + { + return service_.add_verify_path(impl_, path, ec); + } + + /// Use a certificate from a file. + /** + * This function is used to load a certificate into the context from a file. + * + * @param filename The name of the file containing the certificate. + * + * @param format The file format (ASN.1 or PEM). + * + * @throws asio::system_error Thrown on failure. + */ + void use_certificate_file(const std::string& filename, file_format format) + { + asio::error_code ec; + service_.use_certificate_file(impl_, filename, format, ec); + asio::detail::throw_error(ec); + } + + /// Use a certificate from a file. + /** + * This function is used to load a certificate into the context from a file. + * + * @param filename The name of the file containing the certificate. + * + * @param format The file format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code use_certificate_file(const std::string& filename, + file_format format, asio::error_code& ec) + { + return service_.use_certificate_file(impl_, filename, format, ec); + } + + /// Use a certificate chain from a file. + /** + * This function is used to load a certificate chain into the context from a + * file. + * + * @param filename The name of the file containing the certificate. The file + * must use the PEM format. + * + * @throws asio::system_error Thrown on failure. + */ + void use_certificate_chain_file(const std::string& filename) + { + asio::error_code ec; + service_.use_certificate_chain_file(impl_, filename, ec); + asio::detail::throw_error(ec); + } + + /// Use a certificate chain from a file. + /** + * This function is used to load a certificate chain into the context from a + * file. + * + * @param filename The name of the file containing the certificate. The file + * must use the PEM format. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code use_certificate_chain_file( + const std::string& filename, asio::error_code& ec) + { + return service_.use_certificate_chain_file(impl_, filename, ec); + } + + /// Use a private key from a file. + /** + * This function is used to load a private key into the context from a file. + * + * @param filename The name of the file containing the private key. + * + * @param format The file format (ASN.1 or PEM). + * + * @throws asio::system_error Thrown on failure. + */ + void use_private_key_file(const std::string& filename, file_format format) + { + asio::error_code ec; + service_.use_private_key_file(impl_, filename, format, ec); + asio::detail::throw_error(ec); + } + + /// Use a private key from a file. + /** + * This function is used to load a private key into the context from a file. + * + * @param filename The name of the file containing the private key. + * + * @param format The file format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code use_private_key_file(const std::string& filename, + file_format format, asio::error_code& ec) + { + return service_.use_private_key_file(impl_, filename, format, ec); + } + + /// Use an RSA private key from a file. + /** + * This function is used to load an RSA private key into the context from a + * file. + * + * @param filename The name of the file containing the RSA private key. + * + * @param format The file format (ASN.1 or PEM). + * + * @throws asio::system_error Thrown on failure. + */ + void use_rsa_private_key_file(const std::string& filename, file_format format) + { + asio::error_code ec; + service_.use_rsa_private_key_file(impl_, filename, format, ec); + asio::detail::throw_error(ec); + } + + /// Use an RSA private key from a file. + /** + * This function is used to load an RSA private key into the context from a + * file. + * + * @param filename The name of the file containing the RSA private key. + * + * @param format The file format (ASN.1 or PEM). + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code use_rsa_private_key_file( + const std::string& filename, file_format format, + asio::error_code& ec) + { + return service_.use_rsa_private_key_file(impl_, filename, format, ec); + } + + /// Use the specified file to obtain the temporary Diffie-Hellman parameters. + /** + * This function is used to load Diffie-Hellman parameters into the context + * from a file. + * + * @param filename The name of the file containing the Diffie-Hellman + * parameters. The file must use the PEM format. + * + * @throws asio::system_error Thrown on failure. + */ + void use_tmp_dh_file(const std::string& filename) + { + asio::error_code ec; + service_.use_tmp_dh_file(impl_, filename, ec); + asio::detail::throw_error(ec); + } + + /// Use the specified file to obtain the temporary Diffie-Hellman parameters. + /** + * This function is used to load Diffie-Hellman parameters into the context + * from a file. + * + * @param filename The name of the file containing the Diffie-Hellman + * parameters. The file must use the PEM format. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code use_tmp_dh_file(const std::string& filename, + asio::error_code& ec) + { + return service_.use_tmp_dh_file(impl_, filename, ec); + } + + /// Set the password callback. + /** + * This function is used to specify a callback function to obtain password + * information about an encrypted key in PEM format. + * + * @param callback The function object to be used for obtaining the password. + * The function signature of the handler must be: + * @code std::string password_callback( + * std::size_t max_length, // The maximum size for a password. + * password_purpose purpose // Whether password is for reading or writing. + * ); @endcode + * The return value of the callback is a string containing the password. + * + * @throws asio::system_error Thrown on failure. + */ + template + void set_password_callback(PasswordCallback callback) + { + asio::error_code ec; + service_.set_password_callback(impl_, callback, ec); + asio::detail::throw_error(ec); + } + + /// Set the password callback. + /** + * This function is used to specify a callback function to obtain password + * information about an encrypted key in PEM format. + * + * @param callback The function object to be used for obtaining the password. + * The function signature of the handler must be: + * @code std::string password_callback( + * std::size_t max_length, // The maximum size for a password. + * password_purpose purpose // Whether password is for reading or writing. + * ); @endcode + * The return value of the callback is a string containing the password. + * + * @param ec Set to indicate what error occurred, if any. + */ + template + asio::error_code set_password_callback(PasswordCallback callback, + asio::error_code& ec) + { + return service_.set_password_callback(impl_, callback, ec); + } + +private: + /// The backend service implementation. + service_type& service_; + + /// The underlying native implementation. + impl_type impl_; +}; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_BASIC_CONTEXT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl/context.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl/context.hpp new file mode 100644 index 00000000..d53882af --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl/context.hpp @@ -0,0 +1,35 @@ +// +// context.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_CONTEXT_HPP +#define ASIO_SSL_CONTEXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/ssl/basic_context.hpp" +#include "asio/ssl/context_service.hpp" + +namespace asio { +namespace ssl { + +/// Typedef for the typical usage of context. +typedef basic_context context; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_CONTEXT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl/context_base.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl/context_base.hpp new file mode 100644 index 00000000..a0700ca2 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl/context_base.hpp @@ -0,0 +1,164 @@ +// +// context_base.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_CONTEXT_BASE_HPP +#define ASIO_SSL_CONTEXT_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/ssl/detail/openssl_types.hpp" + +namespace asio { +namespace ssl { + +/// The context_base class is used as a base for the basic_context class +/// template so that we have a common place to define various enums. +class context_base +{ +public: + /// Different methods supported by a context. + enum method + { + /// Generic SSL version 2. + sslv2, + + /// SSL version 2 client. + sslv2_client, + + /// SSL version 2 server. + sslv2_server, + + /// Generic SSL version 3. + sslv3, + + /// SSL version 3 client. + sslv3_client, + + /// SSL version 3 server. + sslv3_server, + + /// Generic TLS version 1. + tlsv1, + + /// TLS version 1 client. + tlsv1_client, + + /// TLS version 1 server. + tlsv1_server, + + /// Generic SSL/TLS. + sslv23, + + /// SSL/TLS client. + sslv23_client, + + /// SSL/TLS server. + sslv23_server + }; + + /// Bitmask type for SSL options. + typedef int options; + +#if defined(GENERATING_DOCUMENTATION) + /// Implement various bug workarounds. + static const int default_workarounds = implementation_defined; + + /// Always create a new key when using tmp_dh parameters. + static const int single_dh_use = implementation_defined; + + /// Disable SSL v2. + static const int no_sslv2 = implementation_defined; + + /// Disable SSL v3. + static const int no_sslv3 = implementation_defined; + + /// Disable TLS v1. + static const int no_tlsv1 = implementation_defined; +#else + BOOST_STATIC_CONSTANT(int, default_workarounds = SSL_OP_ALL); + BOOST_STATIC_CONSTANT(int, single_dh_use = SSL_OP_SINGLE_DH_USE); + BOOST_STATIC_CONSTANT(int, no_sslv2 = SSL_OP_NO_SSLv2); + BOOST_STATIC_CONSTANT(int, no_sslv3 = SSL_OP_NO_SSLv3); + BOOST_STATIC_CONSTANT(int, no_tlsv1 = SSL_OP_NO_TLSv1); +#endif + + /// File format types. + enum file_format + { + /// ASN.1 file. + asn1, + + /// PEM file. + pem + }; + + /// Bitmask type for peer verification. + typedef int verify_mode; + +#if defined(GENERATING_DOCUMENTATION) + /// No verification. + static const int verify_none = implementation_defined; + + /// Verify the peer. + static const int verify_peer = implementation_defined; + + /// Fail verification if the peer has no certificate. Ignored unless + /// verify_peer is set. + static const int verify_fail_if_no_peer_cert = implementation_defined; + + /// Do not request client certificate on renegotiation. Ignored unless + /// verify_peer is set. + static const int verify_client_once = implementation_defined; +#else + BOOST_STATIC_CONSTANT(int, verify_none = SSL_VERIFY_NONE); + BOOST_STATIC_CONSTANT(int, verify_peer = SSL_VERIFY_PEER); + BOOST_STATIC_CONSTANT(int, + verify_fail_if_no_peer_cert = SSL_VERIFY_FAIL_IF_NO_PEER_CERT); + BOOST_STATIC_CONSTANT(int, verify_client_once = SSL_VERIFY_CLIENT_ONCE); +#endif + + /// Purpose of PEM password. + enum password_purpose + { + /// The password is needed for reading/decryption. + for_reading, + + /// The password is needed for writing/encryption. + for_writing + }; + +protected: + /// Protected destructor to prevent deletion through this type. + ~context_base() + { + } + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +private: + // Workaround to enable the empty base optimisation with Borland C++. + char dummy_; +#endif +}; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_CONTEXT_BASE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl/context_service.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl/context_service.hpp new file mode 100644 index 00000000..e9cfef7e --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl/context_service.hpp @@ -0,0 +1,175 @@ +// +// context_service.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_CONTEXT_SERVICE_HPP +#define ASIO_SSL_CONTEXT_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/ssl/context_base.hpp" +#include "asio/ssl/detail/openssl_context_service.hpp" + +namespace asio { +namespace ssl { + +/// Default service implementation for a context. +class context_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_service::service +#else + : public asio::detail::service_base +#endif +{ +private: + // The type of the platform-specific implementation. + typedef detail::openssl_context_service service_impl_type; + +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_service::id id; +#endif + + /// The type of the context. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined impl_type; +#else + typedef service_impl_type::impl_type impl_type; +#endif + + /// Constructor. + explicit context_service(asio::io_service& io_service) + : asio::detail::service_base(io_service), + service_impl_(asio::use_service(io_service)) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + /// Return a null context implementation. + impl_type null() const + { + return service_impl_.null(); + } + + /// Create a new context implementation. + void create(impl_type& impl, context_base::method m) + { + service_impl_.create(impl, m); + } + + /// Destroy a context implementation. + void destroy(impl_type& impl) + { + service_impl_.destroy(impl); + } + + /// Set options on the context. + asio::error_code set_options(impl_type& impl, + context_base::options o, asio::error_code& ec) + { + return service_impl_.set_options(impl, o, ec); + } + + /// Set peer verification mode. + asio::error_code set_verify_mode(impl_type& impl, + context_base::verify_mode v, asio::error_code& ec) + { + return service_impl_.set_verify_mode(impl, v, ec); + } + + /// Load a certification authority file for performing verification. + asio::error_code load_verify_file(impl_type& impl, + const std::string& filename, asio::error_code& ec) + { + return service_impl_.load_verify_file(impl, filename, ec); + } + + /// Add a directory containing certification authority files to be used for + /// performing verification. + asio::error_code add_verify_path(impl_type& impl, + const std::string& path, asio::error_code& ec) + { + return service_impl_.add_verify_path(impl, path, ec); + } + + /// Use a certificate from a file. + asio::error_code use_certificate_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + asio::error_code& ec) + { + return service_impl_.use_certificate_file(impl, filename, format, ec); + } + + /// Use a certificate chain from a file. + asio::error_code use_certificate_chain_file(impl_type& impl, + const std::string& filename, asio::error_code& ec) + { + return service_impl_.use_certificate_chain_file(impl, filename, ec); + } + + /// Use a private key from a file. + asio::error_code use_private_key_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + asio::error_code& ec) + { + return service_impl_.use_private_key_file(impl, filename, format, ec); + } + + /// Use an RSA private key from a file. + asio::error_code use_rsa_private_key_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + asio::error_code& ec) + { + return service_impl_.use_rsa_private_key_file(impl, filename, format, ec); + } + + /// Use the specified file to obtain the temporary Diffie-Hellman parameters. + asio::error_code use_tmp_dh_file(impl_type& impl, + const std::string& filename, asio::error_code& ec) + { + return service_impl_.use_tmp_dh_file(impl, filename, ec); + } + + /// Set the password callback. + template + asio::error_code set_password_callback(impl_type& impl, + PasswordCallback callback, asio::error_code& ec) + { + return service_impl_.set_password_callback(impl, callback, ec); + } + +private: + // The service that provides the platform-specific implementation. + service_impl_type& service_impl_; +}; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_CONTEXT_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_context_service.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_context_service.hpp new file mode 100644 index 00000000..aa2e16b9 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_context_service.hpp @@ -0,0 +1,381 @@ +// +// openssl_context_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP +#define ASIO_SSL_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/ssl/context_base.hpp" +#include "asio/ssl/detail/openssl_init.hpp" +#include "asio/ssl/detail/openssl_types.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +class openssl_context_service + : public asio::detail::service_base +{ +public: + // The native type of the context. + typedef ::SSL_CTX* impl_type; + + // The type for the password callback function object. + typedef boost::function password_callback_type; + + // Constructor. + openssl_context_service(asio::io_service& io_service) + : asio::detail::service_base(io_service) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + // Return a null context implementation. + static impl_type null() + { + return 0; + } + + // Create a new context implementation. + void create(impl_type& impl, context_base::method m) + { + switch (m) + { + +#if (OPENSSL_VERSION_NUMBER < 0x10000000L) // OpenSSL versions 1 and above deprecated support for v2) + case context_base::sslv2: + impl = ::SSL_CTX_new(::SSLv2_method()); + break; + case context_base::sslv2_client: + impl = ::SSL_CTX_new(::SSLv2_client_method()); + break; + case context_base::sslv2_server: + impl = ::SSL_CTX_new(::SSLv2_server_method()); + break; +#endif + case context_base::sslv3: + impl = ::SSL_CTX_new(::SSLv3_method()); + break; + case context_base::sslv3_client: + impl = ::SSL_CTX_new(::SSLv3_client_method()); + break; + case context_base::sslv3_server: + impl = ::SSL_CTX_new(::SSLv3_server_method()); + break; + case context_base::tlsv1: + impl = ::SSL_CTX_new(::TLSv1_method()); + break; + case context_base::tlsv1_client: + impl = ::SSL_CTX_new(::TLSv1_client_method()); + break; + case context_base::tlsv1_server: + impl = ::SSL_CTX_new(::TLSv1_server_method()); + break; + case context_base::sslv23: + impl = ::SSL_CTX_new(::SSLv23_method()); + break; + case context_base::sslv23_client: + impl = ::SSL_CTX_new(::SSLv23_client_method()); + break; + case context_base::sslv23_server: + impl = ::SSL_CTX_new(::SSLv23_server_method()); + break; + default: + impl = ::SSL_CTX_new(0); + break; + } + } + + // Destroy a context implementation. + void destroy(impl_type& impl) + { + if (impl != null()) + { + if (impl->default_passwd_callback_userdata) + { + password_callback_type* callback = + static_cast( + impl->default_passwd_callback_userdata); + delete callback; + impl->default_passwd_callback_userdata = 0; + } + + ::SSL_CTX_free(impl); + impl = null(); + } + } + + // Set options on the context. + asio::error_code set_options(impl_type& impl, + context_base::options o, asio::error_code& ec) + { + ::SSL_CTX_set_options(impl, o); + + ec = asio::error_code(); + return ec; + } + + // Set peer verification mode. + asio::error_code set_verify_mode(impl_type& impl, + context_base::verify_mode v, asio::error_code& ec) + { + ::SSL_CTX_set_verify(impl, v, 0); + + ec = asio::error_code(); + return ec; + } + + // Load a certification authority file for performing verification. + asio::error_code load_verify_file(impl_type& impl, + const std::string& filename, asio::error_code& ec) + { + if (::SSL_CTX_load_verify_locations(impl, filename.c_str(), 0) != 1) + { + ec = asio::error::invalid_argument; + return ec; + } + + ec = asio::error_code(); + return ec; + } + + // Add a directory containing certification authority files to be used for + // performing verification. + asio::error_code add_verify_path(impl_type& impl, + const std::string& path, asio::error_code& ec) + { + if (::SSL_CTX_load_verify_locations(impl, 0, path.c_str()) != 1) + { + ec = asio::error::invalid_argument; + return ec; + } + + ec = asio::error_code(); + return ec; + } + + // Use a certificate from a file. + asio::error_code use_certificate_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + asio::error_code& ec) + { + int file_type; + switch (format) + { + case context_base::asn1: + file_type = SSL_FILETYPE_ASN1; + break; + case context_base::pem: + file_type = SSL_FILETYPE_PEM; + break; + default: + { + ec = asio::error::invalid_argument; + return ec; + } + } + + if (::SSL_CTX_use_certificate_file(impl, filename.c_str(), file_type) != 1) + { + ec = asio::error::invalid_argument; + return ec; + } + + ec = asio::error_code(); + return ec; + } + + // Use a certificate chain from a file. + asio::error_code use_certificate_chain_file(impl_type& impl, + const std::string& filename, asio::error_code& ec) + { + if (::SSL_CTX_use_certificate_chain_file(impl, filename.c_str()) != 1) + { + ec = asio::error::invalid_argument; + return ec; + } + + ec = asio::error_code(); + return ec; + } + + // Use a private key from a file. + asio::error_code use_private_key_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + asio::error_code& ec) + { + int file_type; + switch (format) + { + case context_base::asn1: + file_type = SSL_FILETYPE_ASN1; + break; + case context_base::pem: + file_type = SSL_FILETYPE_PEM; + break; + default: + { + ec = asio::error::invalid_argument; + return ec; + } + } + + if (::SSL_CTX_use_PrivateKey_file(impl, filename.c_str(), file_type) != 1) + { + ec = asio::error::invalid_argument; + return ec; + } + + ec = asio::error_code(); + return ec; + } + + // Use an RSA private key from a file. + asio::error_code use_rsa_private_key_file(impl_type& impl, + const std::string& filename, context_base::file_format format, + asio::error_code& ec) + { + int file_type; + switch (format) + { + case context_base::asn1: + file_type = SSL_FILETYPE_ASN1; + break; + case context_base::pem: + file_type = SSL_FILETYPE_PEM; + break; + default: + { + ec = asio::error::invalid_argument; + return ec; + } + } + + if (::SSL_CTX_use_RSAPrivateKey_file( + impl, filename.c_str(), file_type) != 1) + { + ec = asio::error::invalid_argument; + return ec; + } + + ec = asio::error_code(); + return ec; + } + + // Use the specified file to obtain the temporary Diffie-Hellman parameters. + asio::error_code use_tmp_dh_file(impl_type& impl, + const std::string& filename, asio::error_code& ec) + { + ::BIO* bio = ::BIO_new_file(filename.c_str(), "r"); + if (!bio) + { + ec = asio::error::invalid_argument; + return ec; + } + + ::DH* dh = ::PEM_read_bio_DHparams(bio, 0, 0, 0); + if (!dh) + { + ::BIO_free(bio); + ec = asio::error::invalid_argument; + return ec; + } + + ::BIO_free(bio); + int result = ::SSL_CTX_set_tmp_dh(impl, dh); + ::DH_free(dh); + if (result != 1) + { + ec = asio::error::invalid_argument; + return ec; + } + + ec = asio::error_code(); + return ec; + } + + static int password_callback(char* buf, int size, int purpose, void* data) + { + using namespace std; // For strncat and strlen. + + if (data) + { + password_callback_type* callback = + static_cast(data); + std::string passwd = (*callback)(static_cast(size), + purpose ? context_base::for_writing : context_base::for_reading); + *buf = '\0'; + strncat(buf, passwd.c_str(), size); + return strlen(buf); + } + + return 0; + } + + // Set the password callback. + template + asio::error_code set_password_callback(impl_type& impl, + Password_Callback callback, asio::error_code& ec) + { + // Allocate callback function object if not already present. + if (impl->default_passwd_callback_userdata) + { + password_callback_type* callback_function = + static_cast( + impl->default_passwd_callback_userdata); + *callback_function = callback; + } + else + { + password_callback_type* callback_function = + new password_callback_type(callback); + impl->default_passwd_callback_userdata = callback_function; + } + + // Set the password callback. + SSL_CTX_set_default_passwd_cb(impl, + &openssl_context_service::password_callback); + + ec = asio::error_code(); + return ec; + } + +private: + // Ensure openssl is initialised. + openssl_init<> init_; +}; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_OPENSSL_CONTEXT_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_init.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_init.hpp new file mode 100644 index 00000000..9ecbb78f --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_init.hpp @@ -0,0 +1,155 @@ +// +// openssl_init.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_DETAIL_OPENSSL_INIT_HPP +#define ASIO_SSL_DETAIL_OPENSSL_INIT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/mutex.hpp" +#include "asio/detail/tss_ptr.hpp" +#include "asio/ssl/detail/openssl_types.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +template +class openssl_init + : private boost::noncopyable +{ +private: + // Structure to perform the actual initialisation. + class do_init + { + public: + do_init() + { + if (Do_Init) + { + ::SSL_library_init(); + ::SSL_load_error_strings(); + ::OpenSSL_add_ssl_algorithms(); + + mutexes_.resize(::CRYPTO_num_locks()); + for (size_t i = 0; i < mutexes_.size(); ++i) + mutexes_[i].reset(new asio::detail::mutex); + ::CRYPTO_set_locking_callback(&do_init::openssl_locking_func); + ::CRYPTO_set_id_callback(&do_init::openssl_id_func); + } + } + + ~do_init() + { + if (Do_Init) + { + ::CRYPTO_set_id_callback(0); + ::CRYPTO_set_locking_callback(0); + ::ERR_free_strings(); + ::ERR_remove_state(0); + ::EVP_cleanup(); + ::CRYPTO_cleanup_all_ex_data(); + ::CONF_modules_unload(1); + ::ENGINE_cleanup(); + } + } + + // Helper function to manage a do_init singleton. The static instance of the + // openssl_init object ensures that this function is always called before + // main, and therefore before any other threads can get started. The do_init + // instance must be static in this function to ensure that it gets + // initialised before any other global objects try to use it. + static boost::shared_ptr instance() + { + static boost::shared_ptr init(new do_init); + return init; + } + + private: + static unsigned long openssl_id_func() + { +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + return ::GetCurrentThreadId(); +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + void* id = instance()->thread_id_; + if (id == 0) + instance()->thread_id_ = id = &id; // Ugh. + BOOST_ASSERT(sizeof(unsigned long) >= sizeof(void*)); + return reinterpret_cast(id); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + } + + static void openssl_locking_func(int mode, int n, + const char* /*file*/, int /*line*/) + { + if (mode & CRYPTO_LOCK) + instance()->mutexes_[n]->lock(); + else + instance()->mutexes_[n]->unlock(); + } + + // Mutexes to be used in locking callbacks. + std::vector > mutexes_; + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + // The thread identifiers to be used by openssl. + asio::detail::tss_ptr thread_id_; +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + }; + +public: + // Constructor. + openssl_init() + : ref_(do_init::instance()) + { + using namespace std; // For memmove. + + // Ensure openssl_init::instance_ is linked in. + openssl_init* tmp = &instance_; + memmove(&tmp, &tmp, sizeof(openssl_init*)); + } + + // Destructor. + ~openssl_init() + { + } + +private: + // Instance to force initialisation of openssl at global scope. + static openssl_init instance_; + + // Reference to singleton do_init object to ensure that openssl does not get + // cleaned up until the last user has finished with it. + boost::shared_ptr ref_; +}; + +template +openssl_init openssl_init::instance_; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_OPENSSL_INIT_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_operation.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_operation.hpp new file mode 100644 index 00000000..8d237e36 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_operation.hpp @@ -0,0 +1,521 @@ +// +// openssl_operation.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_DETAIL_OPENSSL_OPERATION_HPP +#define ASIO_SSL_DETAIL_OPENSSL_OPERATION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/buffer.hpp" +#include "asio/placeholders.hpp" +#include "asio/write.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/ssl/detail/openssl_types.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +typedef boost::function ssl_primitive_func; +typedef boost::function + user_handler_func; + +// Network send_/recv buffer implementation +// +// +class net_buffer +{ + static const int NET_BUF_SIZE = 16*1024 + 256; // SSL record size + spare + + unsigned char buf_[NET_BUF_SIZE]; + unsigned char* data_start_; + unsigned char* data_end_; + +public: + net_buffer() + { + data_start_ = data_end_ = buf_; + } + unsigned char* get_unused_start() { return data_end_; } + unsigned char* get_data_start() { return data_start_; } + size_t get_unused_len() { return (NET_BUF_SIZE - (data_end_ - buf_)); } + size_t get_data_len() { return (data_end_ - data_start_); } + void data_added(size_t count) + { + data_end_ += count; + data_end_ = data_end_ > (buf_ + NET_BUF_SIZE)? + (buf_ + NET_BUF_SIZE): + data_end_; + } + void data_removed(size_t count) + { + data_start_ += count; + if (data_start_ >= data_end_) reset(); + } + void reset() { data_start_ = buf_; data_end_ = buf_; } + bool has_data() { return (data_start_ < data_end_); } +}; // class net_buffer + +// +// Operation class +// +// +template +class openssl_operation +{ +public: + + // Constructor for asynchronous operations + openssl_operation(ssl_primitive_func primitive, + Stream& socket, + net_buffer& recv_buf, + SSL* session, + BIO* ssl_bio, + user_handler_func handler, + asio::io_service::strand& strand + ) + : primitive_(primitive) + , user_handler_(handler) + , strand_(&strand) + , recv_buf_(recv_buf) + , socket_(socket) + , ssl_bio_(ssl_bio) + , session_(session) + { + write_ = boost::bind( + &openssl_operation::do_async_write, + this, boost::arg<1>(), boost::arg<2>() + ); + read_ = boost::bind( + &openssl_operation::do_async_read, + this + ); + handler_= boost::bind( + &openssl_operation::async_user_handler, + this, boost::arg<1>(), boost::arg<2>() + ); + } + + // Constructor for synchronous operations + openssl_operation(ssl_primitive_func primitive, + Stream& socket, + net_buffer& recv_buf, + SSL* session, + BIO* ssl_bio) + : primitive_(primitive) + , strand_(0) + , recv_buf_(recv_buf) + , socket_(socket) + , ssl_bio_(ssl_bio) + , session_(session) + { + write_ = boost::bind( + &openssl_operation::do_sync_write, + this, boost::arg<1>(), boost::arg<2>() + ); + read_ = boost::bind( + &openssl_operation::do_sync_read, + this + ); + handler_ = boost::bind( + &openssl_operation::sync_user_handler, + this, boost::arg<1>(), boost::arg<2>() + ); + } + + // Start operation + // In case of asynchronous it returns 0, in sync mode returns success code + // or throws an error... + int start() + { + int rc = primitive_( session_ ); + + bool is_operation_done = (rc > 0); + // For connect/accept/shutdown, the operation + // is done, when return code is 1 + // for write, it is done, when is retcode > 0 + // for read, is is done when retcode > 0 + + int error_code = !is_operation_done ? + ::SSL_get_error( session_, rc ) : + 0; + int sys_error_code = ERR_get_error(); + + if (error_code == SSL_ERROR_SSL) + return handler_(asio::error_code( + error_code, asio::error::get_ssl_category()), rc); + + bool is_read_needed = (error_code == SSL_ERROR_WANT_READ); + bool is_write_needed = (error_code == SSL_ERROR_WANT_WRITE || + ::BIO_ctrl_pending( ssl_bio_ )); + bool is_shut_down_received = + ((::SSL_get_shutdown( session_ ) & SSL_RECEIVED_SHUTDOWN) == + SSL_RECEIVED_SHUTDOWN); + bool is_shut_down_sent = + ((::SSL_get_shutdown( session_ ) & SSL_SENT_SHUTDOWN) == + SSL_SENT_SHUTDOWN); + + if (is_shut_down_sent && is_shut_down_received + && is_operation_done && !is_write_needed) + // SSL connection is shut down cleanly + return handler_(asio::error_code(), 1); + + if (is_shut_down_received && !is_operation_done) + // Shutdown has been requested, while we were reading or writing... + // abort our action... + return handler_(asio::error::shut_down, 0); + + if (!is_operation_done && !is_read_needed && !is_write_needed + && !is_shut_down_sent) + { + // The operation has failed... It is not completed and does + // not want network communication nor does want to send shutdown out... + if (error_code == SSL_ERROR_SYSCALL) + { + return handler_(asio::error_code( + sys_error_code, asio::error::system_category), rc); + } + else + { + return handler_(asio::error_code( + error_code, asio::error::get_ssl_category()), rc); + } + } + + if (!is_operation_done && !is_write_needed) + { + // We may have left over data that we can pass to SSL immediately + if (recv_buf_.get_data_len() > 0) + { + // Pass the buffered data to SSL + int written = ::BIO_write + ( + ssl_bio_, + recv_buf_.get_data_start(), + recv_buf_.get_data_len() + ); + + if (written > 0) + { + recv_buf_.data_removed(written); + } + else if (written < 0) + { + if (!BIO_should_retry(ssl_bio_)) + { + // Some serios error with BIO.... + return handler_(asio::error::no_recovery, 0); + } + } + + return start(); + } + else if (is_read_needed || (is_shut_down_sent && !is_shut_down_received)) + { + return read_(); + } + } + + // Continue with operation, flush any SSL data out to network... + return write_(is_operation_done, rc); + } + +// Private implementation +private: + typedef boost::function + int_handler_func; + typedef boost::function write_func; + typedef boost::function read_func; + + ssl_primitive_func primitive_; + user_handler_func user_handler_; + asio::io_service::strand* strand_; + write_func write_; + read_func read_; + int_handler_func handler_; + + net_buffer send_buf_; // buffers for network IO + + // The recv buffer is owned by the stream, not the operation, since there can + // be left over bytes after passing the data up to the application, and these + // bytes need to be kept around for the next read operation issued by the + // application. + net_buffer& recv_buf_; + + Stream& socket_; + BIO* ssl_bio_; + SSL* session_; + + // + int sync_user_handler(const asio::error_code& error, int rc) + { + if (!error) + return rc; + + throw asio::system_error(error); + } + + int async_user_handler(asio::error_code error, int rc) + { + if (rc < 0) + { + if (!error) + error = asio::error::no_recovery; + rc = 0; + } + + user_handler_(error, rc); + return 0; + } + + // Writes bytes asynchronously from SSL to NET + int do_async_write(bool is_operation_done, int rc) + { + int len = ::BIO_ctrl_pending( ssl_bio_ ); + if ( len ) + { + // There is something to write into net, do it... + len = (int)send_buf_.get_unused_len() > len? + len: + send_buf_.get_unused_len(); + + if (len == 0) + { + // In case our send buffer is full, we have just to wait until + // previous send to complete... + return 0; + } + + // Read outgoing data from bio + len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len); + + if (len > 0) + { + unsigned char *data_start = send_buf_.get_unused_start(); + send_buf_.data_added(len); + + BOOST_ASSERT(strand_); + asio::async_write + ( + socket_, + asio::buffer(data_start, len), + strand_->wrap + ( + boost::bind + ( + &openssl_operation::async_write_handler, + this, + is_operation_done, + rc, + asio::placeholders::error, + asio::placeholders::bytes_transferred + ) + ) + ); + + return 0; + } + else if (!BIO_should_retry(ssl_bio_)) + { + // Seems like fatal error + // reading from SSL BIO has failed... + handler_(asio::error::no_recovery, 0); + return 0; + } + } + + if (is_operation_done) + { + // Finish the operation, with success + handler_(asio::error_code(), rc); + return 0; + } + + // OPeration is not done and writing to net has been made... + // start operation again + start(); + + return 0; + } + + void async_write_handler(bool is_operation_done, int rc, + const asio::error_code& error, size_t bytes_sent) + { + if (!error) + { + // Remove data from send buffer + send_buf_.data_removed(bytes_sent); + + if (is_operation_done) + handler_(asio::error_code(), rc); + else + // Since the operation was not completed, try it again... + start(); + } + else + handler_(error, rc); + } + + int do_async_read() + { + // Wait for new data + BOOST_ASSERT(strand_); + socket_.async_read_some + ( + asio::buffer(recv_buf_.get_unused_start(), + recv_buf_.get_unused_len()), + strand_->wrap + ( + boost::bind + ( + &openssl_operation::async_read_handler, + this, + asio::placeholders::error, + asio::placeholders::bytes_transferred + ) + ) + ); + return 0; + } + + void async_read_handler(const asio::error_code& error, + size_t bytes_recvd) + { + if (!error) + { + recv_buf_.data_added(bytes_recvd); + + // Pass the received data to SSL + int written = ::BIO_write + ( + ssl_bio_, + recv_buf_.get_data_start(), + recv_buf_.get_data_len() + ); + + if (written > 0) + { + recv_buf_.data_removed(written); + } + else if (written < 0) + { + if (!BIO_should_retry(ssl_bio_)) + { + // Some serios error with BIO.... + handler_(asio::error::no_recovery, 0); + return; + } + } + + // and try the SSL primitive again + start(); + } + else + { + // Error in network level... + // SSL can't continue either... + handler_(error, 0); + } + } + + // Syncronous functions... + int do_sync_write(bool is_operation_done, int rc) + { + int len = ::BIO_ctrl_pending( ssl_bio_ ); + if ( len ) + { + // There is something to write into net, do it... + len = (int)send_buf_.get_unused_len() > len? + len: + send_buf_.get_unused_len(); + + // Read outgoing data from bio + len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len); + + if (len > 0) + { + size_t sent_len = asio::write( + socket_, + asio::buffer(send_buf_.get_unused_start(), len) + ); + + send_buf_.data_added(len); + send_buf_.data_removed(sent_len); + } + else if (!BIO_should_retry(ssl_bio_)) + { + // Seems like fatal error + // reading from SSL BIO has failed... + throw asio::system_error(asio::error::no_recovery); + } + } + + if (is_operation_done) + // Finish the operation, with success + return rc; + + // Operation is not finished, start again. + return start(); + } + + int do_sync_read() + { + size_t len = socket_.read_some + ( + asio::buffer(recv_buf_.get_unused_start(), + recv_buf_.get_unused_len()) + ); + + // Write data to ssl + recv_buf_.data_added(len); + + // Pass the received data to SSL + int written = ::BIO_write + ( + ssl_bio_, + recv_buf_.get_data_start(), + recv_buf_.get_data_len() + ); + + if (written > 0) + { + recv_buf_.data_removed(written); + } + else if (written < 0) + { + if (!BIO_should_retry(ssl_bio_)) + { + // Some serios error with BIO.... + throw asio::system_error(asio::error::no_recovery); + } + } + + // Try the operation again + return start(); + } +}; // class openssl_operation + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_OPENSSL_OPERATION_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_stream_service.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_stream_service.hpp new file mode 100644 index 00000000..d7bb457a --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_stream_service.hpp @@ -0,0 +1,571 @@ +// +// stream_service.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_DETAIL_OPENSSL_STREAM_SERVICE_HPP +#define ASIO_SSL_DETAIL_OPENSSL_STREAM_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/strand.hpp" +#include "asio/detail/buffer_sequence_adapter.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/ssl/basic_context.hpp" +#include "asio/ssl/stream_base.hpp" +#include "asio/ssl/detail/openssl_operation.hpp" +#include "asio/ssl/detail/openssl_types.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +class openssl_stream_service + : public asio::detail::service_base +{ +private: + enum { max_buffer_size = INT_MAX }; + + //Base handler for asyncrhonous operations + template + class base_handler + { + public: + typedef boost::function< + void (const asio::error_code&, size_t)> func_t; + + base_handler(asio::io_service& io_service) + : op_(NULL) + , io_service_(io_service) + , work_(io_service) + {} + + void do_func(const asio::error_code& error, size_t size) + { + func_(error, size); + } + + void set_operation(openssl_operation* op) { op_ = op; } + void set_func(func_t func) { func_ = func; } + + ~base_handler() + { + delete op_; + } + + private: + func_t func_; + openssl_operation* op_; + asio::io_service& io_service_; + asio::io_service::work work_; + }; // class base_handler + + // Handler for asynchronous IO (write/read) operations + template + class io_handler + : public base_handler + { + public: + io_handler(Handler handler, asio::io_service& io_service) + : base_handler(io_service) + , handler_(handler) + { + set_func(boost::bind( + &io_handler::handler_impl, + this, boost::arg<1>(), boost::arg<2>() )); + } + + private: + Handler handler_; + void handler_impl(const asio::error_code& error, size_t size) + { + std::auto_ptr > this_ptr(this); + handler_(error, size); + } + }; // class io_handler + + // Handler for asyncrhonous handshake (connect, accept) functions + template + class handshake_handler + : public base_handler + { + public: + handshake_handler(Handler handler, asio::io_service& io_service) + : base_handler(io_service) + , handler_(handler) + { + set_func(boost::bind( + &handshake_handler::handler_impl, + this, boost::arg<1>(), boost::arg<2>() )); + } + + private: + Handler handler_; + void handler_impl(const asio::error_code& error, size_t) + { + std::auto_ptr > this_ptr(this); + handler_(error); + } + + }; // class handshake_handler + + // Handler for asyncrhonous shutdown + template + class shutdown_handler + : public base_handler + { + public: + shutdown_handler(Handler handler, asio::io_service& io_service) + : base_handler(io_service), + handler_(handler) + { + set_func(boost::bind( + &shutdown_handler::handler_impl, + this, boost::arg<1>(), boost::arg<2>() )); + } + + private: + Handler handler_; + void handler_impl(const asio::error_code& error, size_t) + { + std::auto_ptr > this_ptr(this); + handler_(error); + } + }; // class shutdown_handler + +public: + // The implementation type. + typedef struct impl_struct + { + ::SSL* ssl; + ::BIO* ext_bio; + net_buffer recv_buf; + } * impl_type; + + // Construct a new stream socket service for the specified io_service. + explicit openssl_stream_service(asio::io_service& io_service) + : asio::detail::service_base(io_service), + strand_(io_service) + { + } + + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + // Return a null stream implementation. + impl_type null() const + { + return 0; + } + + // Create a new stream implementation. + template + void create(impl_type& impl, Stream& /*next_layer*/, + basic_context& context) + { + impl = new impl_struct; + impl->ssl = ::SSL_new(context.impl()); + ::SSL_set_mode(impl->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE); + ::SSL_set_mode(impl->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + ::BIO* int_bio = 0; + impl->ext_bio = 0; + ::BIO_new_bio_pair(&int_bio, 8192, &impl->ext_bio, 8192); + ::SSL_set_bio(impl->ssl, int_bio, int_bio); + } + + // Destroy a stream implementation. + template + void destroy(impl_type& impl, Stream& /*next_layer*/) + { + if (impl != 0) + { + ::BIO_free(impl->ext_bio); + ::SSL_free(impl->ssl); + delete impl; + impl = 0; + } + } + + // Perform SSL handshaking. + template + asio::error_code handshake(impl_type& impl, Stream& next_layer, + stream_base::handshake_type type, asio::error_code& ec) + { + try + { + openssl_operation op( + type == stream_base::client ? + &ssl_wrap::SSL_connect: + &ssl_wrap::SSL_accept, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio); + op.start(); + } + catch (asio::system_error& e) + { + ec = e.code(); + return ec; + } + + ec = asio::error_code(); + return ec; + } + + // Start an asynchronous SSL handshake. + template + void async_handshake(impl_type& impl, Stream& next_layer, + stream_base::handshake_type type, Handler handler) + { + typedef handshake_handler connect_handler; + + connect_handler* local_handler = + new connect_handler(handler, get_io_service()); + + openssl_operation* op = new openssl_operation + ( + type == stream_base::client ? + &ssl_wrap::SSL_connect: + &ssl_wrap::SSL_accept, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio, + boost::bind + ( + &base_handler::do_func, + local_handler, + boost::arg<1>(), + boost::arg<2>() + ), + strand_ + ); + local_handler->set_operation(op); + + strand_.post(boost::bind(&openssl_operation::start, op)); + } + + // Shut down SSL on the stream. + template + asio::error_code shutdown(impl_type& impl, Stream& next_layer, + asio::error_code& ec) + { + try + { + openssl_operation op( + &ssl_wrap::SSL_shutdown, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio); + op.start(); + } + catch (asio::system_error& e) + { + ec = e.code(); + return ec; + } + + ec = asio::error_code(); + return ec; + } + + // Asynchronously shut down SSL on the stream. + template + void async_shutdown(impl_type& impl, Stream& next_layer, Handler handler) + { + typedef shutdown_handler disconnect_handler; + + disconnect_handler* local_handler = + new disconnect_handler(handler, get_io_service()); + + openssl_operation* op = new openssl_operation + ( + &ssl_wrap::SSL_shutdown, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio, + boost::bind + ( + &base_handler::do_func, + local_handler, + boost::arg<1>(), + boost::arg<2>() + ), + strand_ + ); + local_handler->set_operation(op); + + strand_.post(boost::bind(&openssl_operation::start, op)); + } + + // Write some data to the stream. + template + std::size_t write_some(impl_type& impl, Stream& next_layer, + const Const_Buffers& buffers, asio::error_code& ec) + { + size_t bytes_transferred = 0; + try + { + asio::const_buffer buffer = + asio::detail::buffer_sequence_adapter< + asio::const_buffer, Const_Buffers>::first(buffers); + + std::size_t buffer_size = asio::buffer_size(buffer); + if (buffer_size > max_buffer_size) + buffer_size = max_buffer_size; + else if (buffer_size == 0) + { + ec = asio::error_code(); + return 0; + } + + boost::function send_func = + boost::bind(boost::type(), &::SSL_write, boost::arg<1>(), + asio::buffer_cast(buffer), + static_cast(buffer_size)); + openssl_operation op( + send_func, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio + ); + bytes_transferred = static_cast(op.start()); + } + catch (asio::system_error& e) + { + ec = e.code(); + return 0; + } + + ec = asio::error_code(); + return bytes_transferred; + } + + // Start an asynchronous write. + template + void async_write_some(impl_type& impl, Stream& next_layer, + const Const_Buffers& buffers, Handler handler) + { + typedef io_handler send_handler; + + asio::const_buffer buffer = + asio::detail::buffer_sequence_adapter< + asio::const_buffer, Const_Buffers>::first(buffers); + + std::size_t buffer_size = asio::buffer_size(buffer); + if (buffer_size > max_buffer_size) + buffer_size = max_buffer_size; + else if (buffer_size == 0) + { + get_io_service().post(asio::detail::bind_handler( + handler, asio::error_code(), 0)); + return; + } + + send_handler* local_handler = new send_handler(handler, get_io_service()); + + boost::function send_func = + boost::bind(boost::type(), &::SSL_write, boost::arg<1>(), + asio::buffer_cast(buffer), + static_cast(buffer_size)); + + openssl_operation* op = new openssl_operation + ( + send_func, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio, + boost::bind + ( + &base_handler::do_func, + local_handler, + boost::arg<1>(), + boost::arg<2>() + ), + strand_ + ); + local_handler->set_operation(op); + + strand_.post(boost::bind(&openssl_operation::start, op)); + } + + // Read some data from the stream. + template + std::size_t read_some(impl_type& impl, Stream& next_layer, + const Mutable_Buffers& buffers, asio::error_code& ec) + { + size_t bytes_transferred = 0; + try + { + asio::mutable_buffer buffer = + asio::detail::buffer_sequence_adapter< + asio::mutable_buffer, Mutable_Buffers>::first(buffers); + + std::size_t buffer_size = asio::buffer_size(buffer); + if (buffer_size > max_buffer_size) + buffer_size = max_buffer_size; + else if (buffer_size == 0) + { + ec = asio::error_code(); + return 0; + } + + boost::function recv_func = + boost::bind(boost::type(), &::SSL_read, boost::arg<1>(), + asio::buffer_cast(buffer), + static_cast(buffer_size)); + openssl_operation op(recv_func, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio + ); + + bytes_transferred = static_cast(op.start()); + } + catch (asio::system_error& e) + { + ec = e.code(); + return 0; + } + + ec = asio::error_code(); + return bytes_transferred; + } + + // Start an asynchronous read. + template + void async_read_some(impl_type& impl, Stream& next_layer, + const Mutable_Buffers& buffers, Handler handler) + { + typedef io_handler recv_handler; + + asio::mutable_buffer buffer = + asio::detail::buffer_sequence_adapter< + asio::mutable_buffer, Mutable_Buffers>::first(buffers); + + std::size_t buffer_size = asio::buffer_size(buffer); + if (buffer_size > max_buffer_size) + buffer_size = max_buffer_size; + else if (buffer_size == 0) + { + get_io_service().post(asio::detail::bind_handler( + handler, asio::error_code(), 0)); + return; + } + + recv_handler* local_handler = new recv_handler(handler, get_io_service()); + + boost::function recv_func = + boost::bind(boost::type(), &::SSL_read, boost::arg<1>(), + asio::buffer_cast(buffer), + static_cast(buffer_size)); + + openssl_operation* op = new openssl_operation + ( + recv_func, + next_layer, + impl->recv_buf, + impl->ssl, + impl->ext_bio, + boost::bind + ( + &base_handler::do_func, + local_handler, + boost::arg<1>(), + boost::arg<2>() + ), + strand_ + ); + local_handler->set_operation(op); + + strand_.post(boost::bind(&openssl_operation::start, op)); + } + + // Peek at the incoming data on the stream. + template + std::size_t peek(impl_type& /*impl*/, Stream& /*next_layer*/, + const Mutable_Buffers& /*buffers*/, asio::error_code& ec) + { + ec = asio::error_code(); + return 0; + } + + // Determine the amount of data that may be read without blocking. + template + std::size_t in_avail(impl_type& /*impl*/, Stream& /*next_layer*/, + asio::error_code& ec) + { + ec = asio::error_code(); + return 0; + } + +private: + asio::io_service::strand strand_; + + typedef asio::detail::mutex mutex_type; + + template + struct ssl_wrap + { + static Mutex ssl_mutex_; + + static int SSL_accept(SSL *ssl) + { + typename Mutex::scoped_lock lock(ssl_mutex_); + return ::SSL_accept(ssl); + } + + static int SSL_connect(SSL *ssl) + { + typename Mutex::scoped_lock lock(ssl_mutex_); + return ::SSL_connect(ssl); + } + + static int SSL_shutdown(SSL *ssl) + { + typename Mutex::scoped_lock lock(ssl_mutex_); + return ::SSL_shutdown(ssl); + } + }; +}; + +template +Mutex openssl_stream_service::ssl_wrap::ssl_mutex_; + +} // namespace detail +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_OPENSSL_STREAM_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_types.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_types.hpp new file mode 100644 index 00000000..c697d740 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl/detail/openssl_types.hpp @@ -0,0 +1,31 @@ +// +// openssl_types.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP +#define ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl/stream.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl/stream.hpp new file mode 100644 index 00000000..e800e626 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl/stream.hpp @@ -0,0 +1,516 @@ +// +// stream.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_STREAM_HPP +#define ASIO_SSL_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/ssl/basic_context.hpp" +#include "asio/ssl/stream_base.hpp" +#include "asio/ssl/stream_service.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { +namespace ssl { + +/// Provides stream-oriented functionality using SSL. +/** + * The stream class template provides asynchronous and blocking stream-oriented + * functionality using SSL. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Example + * To use the SSL stream template with an ip::tcp::socket, you would write: + * @code + * asio::io_service io_service; + * asio::ssl::context context(io_service, asio::ssl::context::sslv23); + * asio::ssl::stream sock(io_service, context); + * @endcode + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncRead_Stream, SyncWriteStream. + */ +template +class stream + : public stream_base, + private boost::noncopyable +{ +public: + /// The type of the next layer. + typedef typename boost::remove_reference::type next_layer_type; + + /// The type of the lowest layer. + typedef typename next_layer_type::lowest_layer_type lowest_layer_type; + + /// The type of the service that will be used to provide stream operations. + typedef Service service_type; + + /// The native implementation type of the stream. + typedef typename service_type::impl_type impl_type; + + /// Construct a stream. + /** + * This constructor creates a stream and initialises the underlying stream + * object. + * + * @param arg The argument to be passed to initialise the underlying stream. + * + * @param context The SSL context to be used for the stream. + */ + template + explicit stream(Arg& arg, basic_context& context) + : next_layer_(arg), + service_(asio::use_service(next_layer_.get_io_service())), + impl_(service_.null()) + { + service_.create(impl_, next_layer_, context); + } + + /// Destructor. + ~stream() + { + service_.destroy(impl_, next_layer_); + } + + /// (Deprecated: use get_io_service().) Get the io_service associated with + /// the object. + /** + * This function may be used to obtain the io_service object that the stream + * uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_service object that stream will use to + * dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_service& io_service() + { + return next_layer_.get_io_service(); + } + + /// Get the io_service associated with the object. + /** + * This function may be used to obtain the io_service object that the stream + * uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_service object that stream will use to + * dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_service& get_io_service() + { + return next_layer_.get_io_service(); + } + + /// Get a reference to the next layer. + /** + * This function returns a reference to the next layer in a stack of stream + * layers. + * + * @return A reference to the next layer in the stack of stream layers. + * Ownership is not transferred to the caller. + */ + next_layer_type& next_layer() + { + return next_layer_; + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * stream layers. + * + * @return A reference to the lowest layer in the stack of stream layers. + * Ownership is not transferred to the caller. + */ + lowest_layer_type& lowest_layer() + { + return next_layer_.lowest_layer(); + } + + /// Get a const reference to the lowest layer. + /** + * This function returns a const reference to the lowest layer in a stack of + * stream layers. + * + * @return A const reference to the lowest layer in the stack of stream + * layers. Ownership is not transferred to the caller. + */ + const lowest_layer_type& lowest_layer() const + { + return next_layer_.lowest_layer(); + } + + /// Get the underlying implementation in the native type. + /** + * This function may be used to obtain the underlying implementation of the + * context. This is intended to allow access to stream functionality that is + * not otherwise provided. + */ + impl_type impl() + { + return impl_; + } + + /// Perform SSL handshaking. + /** + * This function is used to perform SSL handshaking on the stream. The + * function call will block until handshaking is complete or an error occurs. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @throws asio::system_error Thrown on failure. + */ + void handshake(handshake_type type) + { + asio::error_code ec; + service_.handshake(impl_, next_layer_, type, ec); + asio::detail::throw_error(ec); + } + + /// Perform SSL handshaking. + /** + * This function is used to perform SSL handshaking on the stream. The + * function call will block until handshaking is complete or an error occurs. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code handshake(handshake_type type, + asio::error_code& ec) + { + return service_.handshake(impl_, next_layer_, type, ec); + } + + /// Start an asynchronous SSL handshake. + /** + * This function is used to asynchronously perform an SSL handshake on the + * stream. This function call always returns immediately. + * + * @param type The type of handshaking to be performed, i.e. as a client or as + * a server. + * + * @param handler The handler to be called when the handshake operation + * completes. Copies will be made of the handler as required. The equivalent + * function signature of the handler must be: + * @code void handler( + * const asio::error_code& error // Result of operation. + * ); @endcode + */ + template + void async_handshake(handshake_type type, HandshakeHandler handler) + { + service_.async_handshake(impl_, next_layer_, type, handler); + } + + /// Shut down SSL on the stream. + /** + * This function is used to shut down SSL on the stream. The function call + * will block until SSL has been shut down or an error occurs. + * + * @throws asio::system_error Thrown on failure. + */ + void shutdown() + { + asio::error_code ec; + service_.shutdown(impl_, next_layer_, ec); + asio::detail::throw_error(ec); + } + + /// Shut down SSL on the stream. + /** + * This function is used to shut down SSL on the stream. The function call + * will block until SSL has been shut down or an error occurs. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code shutdown(asio::error_code& ec) + { + return service_.shutdown(impl_, next_layer_, ec); + } + + /// Asynchronously shut down SSL on the stream. + /** + * This function is used to asynchronously shut down SSL on the stream. This + * function call always returns immediately. + * + * @param handler The handler to be called when the handshake operation + * completes. Copies will be made of the handler as required. The equivalent + * function signature of the handler must be: + * @code void handler( + * const asio::error_code& error // Result of operation. + * ); @endcode + */ + template + void async_shutdown(ShutdownHandler handler) + { + service_.async_shutdown(impl_, next_layer_, handler); + } + + /// Write some data to the stream. + /** + * This function is used to write data on the stream. The function call will + * block until one or more bytes of data has been written successfully, or + * until an error occurs. + * + * @param buffers The data to be written. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that all + * data is written before the blocking operation completes. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = service_.write_some(impl_, next_layer_, buffers, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Write some data to the stream. + /** + * This function is used to write data on the stream. The function call will + * block until one or more bytes of data has been written successfully, or + * until an error occurs. + * + * @param buffers The data to be written to the stream. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. Returns 0 if an error occurred. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that all + * data is written before the blocking operation completes. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) + { + return service_.write_some(impl_, next_layer_, buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write one or more bytes of data to + * the stream. The function call always returns immediately. + * + * @param buffers The data to be written to the stream. Although the buffers + * object may be copied as necessary, ownership of the underlying buffers is + * retained by the caller, which must guarantee that they remain valid until + * the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The equivalent function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. + * ); @endcode + * + * @note The async_write_some operation may not transmit all of the data to + * the peer. Consider using the @ref async_write function if you need to + * ensure that all data is written before the blocking operation completes. + */ + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + service_.async_write_some(impl_, next_layer_, buffers, handler); + } + + /// Read some data from the stream. + /** + * This function is used to read data from the stream. The function call will + * block until one or more bytes of data has been read successfully, or until + * an error occurs. + * + * @param buffers The buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = service_.read_some(impl_, next_layer_, buffers, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Read some data from the stream. + /** + * This function is used to read data from the stream. The function call will + * block until one or more bytes of data has been read successfully, or until + * an error occurs. + * + * @param buffers The buffers into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. Returns 0 if an error occurred. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return service_.read_some(impl_, next_layer_, buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read one or more bytes of data from + * the stream. The function call always returns immediately. + * + * @param buffers The buffers into which the data will be read. Although the + * buffers object may be copied as necessary, ownership of the underlying + * buffers is retained by the caller, which must guarantee that they remain + * valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The equivalent function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. + * ); @endcode + * + * @note The async_read_some operation may not read all of the requested + * number of bytes. Consider using the @ref async_read function if you need to + * ensure that the requested amount of data is read before the asynchronous + * operation completes. + */ + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + service_.async_read_some(impl_, next_layer_, buffers, handler); + } + + /// Peek at the incoming data on the stream. + /** + * This function is used to peek at the incoming data on the stream, without + * removing it from the input queue. The function call will block until data + * has been read successfully or an error occurs. + * + * @param buffers The buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. + */ + template + std::size_t peek(const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = service_.peek(impl_, next_layer_, buffers, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Peek at the incoming data on the stream. + /** + * This function is used to peek at the incoming data on the stream, withoutxi + * removing it from the input queue. The function call will block until data + * has been read successfully or an error occurs. + * + * @param buffers The buffers into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. Returns 0 if an error occurred. + */ + template + std::size_t peek(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return service_.peek(impl_, next_layer_, buffers, ec); + } + + /// Determine the amount of data that may be read without blocking. + /** + * This function is used to determine the amount of data, in bytes, that may + * be read from the stream without blocking. + * + * @returns The number of bytes of data that can be read without blocking. + * + * @throws asio::system_error Thrown on failure. + */ + std::size_t in_avail() + { + asio::error_code ec; + std::size_t s = service_.in_avail(impl_, next_layer_, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Determine the amount of data that may be read without blocking. + /** + * This function is used to determine the amount of data, in bytes, that may + * be read from the stream without blocking. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes of data that can be read without blocking. + */ + std::size_t in_avail(asio::error_code& ec) + { + return service_.in_avail(impl_, next_layer_, ec); + } + +private: + /// The next layer. + Stream next_layer_; + + /// The backend service implementation. + service_type& service_; + + /// The underlying native implementation. + impl_type impl_; +}; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_STREAM_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl/stream_base.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl/stream_base.hpp new file mode 100644 index 00000000..d62d386a --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl/stream_base.hpp @@ -0,0 +1,60 @@ +// +// stream_base.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_STREAM_BASE_HPP +#define ASIO_SSL_STREAM_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { +namespace ssl { + +/// The stream_base class is used as a base for the asio::ssl::stream +/// class template so that we have a common place to define various enums. +class stream_base +{ +public: + /// Different handshake types. + enum handshake_type + { + /// Perform handshaking as a client. + client, + + /// Perform handshaking as a server. + server + }; + +protected: + /// Protected destructor to prevent deletion through this type. + ~stream_base() + { + } + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +private: + // Workaround to enable the empty base optimisation with Borland C++. + char dummy_; +#endif +}; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_STREAM_BASE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/ssl/stream_service.hpp b/src/libs/resiprocate/contrib/asio/asio/ssl/stream_service.hpp new file mode 100644 index 00000000..1f1e6ad9 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/ssl/stream_service.hpp @@ -0,0 +1,186 @@ +// +// stream_service.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com +// Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SSL_STREAM_SERVICE_HPP +#define ASIO_SSL_STREAM_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/io_service.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/ssl/basic_context.hpp" +#include "asio/ssl/stream_base.hpp" +#include "asio/ssl/detail/openssl_stream_service.hpp" + +namespace asio { +namespace ssl { + +/// Default service implementation for an SSL stream. +class stream_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_service::service +#else + : public asio::detail::service_base +#endif +{ +private: + // The type of the platform-specific implementation. + typedef detail::openssl_stream_service service_impl_type; + +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_service::id id; +#endif + + /// The type of a stream implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined impl_type; +#else + typedef service_impl_type::impl_type impl_type; +#endif + + /// Construct a new stream service for the specified io_service. + explicit stream_service(asio::io_service& io_service) + : asio::detail::service_base(io_service), + service_impl_(asio::use_service(io_service)) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + } + + /// Return a null stream implementation. + impl_type null() const + { + return service_impl_.null(); + } + + /// Create a new stream implementation. + template + void create(impl_type& impl, Stream& next_layer, + basic_context& context) + { + service_impl_.create(impl, next_layer, context); + } + + /// Destroy a stream implementation. + template + void destroy(impl_type& impl, Stream& next_layer) + { + service_impl_.destroy(impl, next_layer); + } + + /// Perform SSL handshaking. + template + asio::error_code handshake(impl_type& impl, Stream& next_layer, + stream_base::handshake_type type, asio::error_code& ec) + { + return service_impl_.handshake(impl, next_layer, type, ec); + } + + /// Start an asynchronous SSL handshake. + template + void async_handshake(impl_type& impl, Stream& next_layer, + stream_base::handshake_type type, HandshakeHandler handler) + { + service_impl_.async_handshake(impl, next_layer, type, handler); + } + + /// Shut down SSL on the stream. + template + asio::error_code shutdown(impl_type& impl, Stream& next_layer, + asio::error_code& ec) + { + return service_impl_.shutdown(impl, next_layer, ec); + } + + /// Asynchronously shut down SSL on the stream. + template + void async_shutdown(impl_type& impl, Stream& next_layer, + ShutdownHandler handler) + { + service_impl_.async_shutdown(impl, next_layer, handler); + } + + /// Write some data to the stream. + template + std::size_t write_some(impl_type& impl, Stream& next_layer, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.write_some(impl, next_layer, buffers, ec); + } + + /// Start an asynchronous write. + template + void async_write_some(impl_type& impl, Stream& next_layer, + const ConstBufferSequence& buffers, WriteHandler handler) + { + service_impl_.async_write_some(impl, next_layer, buffers, handler); + } + + /// Read some data from the stream. + template + std::size_t read_some(impl_type& impl, Stream& next_layer, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.read_some(impl, next_layer, buffers, ec); + } + + /// Start an asynchronous read. + template + void async_read_some(impl_type& impl, Stream& next_layer, + const MutableBufferSequence& buffers, ReadHandler handler) + { + service_impl_.async_read_some(impl, next_layer, buffers, handler); + } + + /// Peek at the incoming data on the stream. + template + std::size_t peek(impl_type& impl, Stream& next_layer, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.peek(impl, next_layer, buffers, ec); + } + + /// Determine the amount of data that may be read without blocking. + template + std::size_t in_avail(impl_type& impl, Stream& next_layer, + asio::error_code& ec) + { + return service_impl_.in_avail(impl, next_layer, ec); + } + +private: + // The service that provides the platform-specific implementation. + service_impl_type& service_impl_; +}; + +} // namespace ssl +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SSL_STREAM_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/strand.hpp b/src/libs/resiprocate/contrib/asio/asio/strand.hpp new file mode 100644 index 00000000..6b321513 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/strand.hpp @@ -0,0 +1,226 @@ +// +// strand.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_STRAND_HPP +#define ASIO_STRAND_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/io_service.hpp" +#include "asio/detail/strand_service.hpp" +#include "asio/detail/wrapped_handler.hpp" + +namespace asio { + +/// Provides serialised handler execution. +/** + * The io_service::strand class provides the ability to post and dispatch + * handlers with the guarantee that none of those handlers will execute + * concurrently. + * + * @par Order of handler invocation + * Given: + * + * @li a strand object @c s + * + * @li an object @c a meeting completion handler requirements + * + * @li an object @c a1 which is an arbitrary copy of @c a made by the + * implementation + * + * @li an object @c b meeting completion handler requirements + * + * @li an object @c b1 which is an arbitrary copy of @c b made by the + * implementation + * + * if any of the following conditions are true: + * + * @li @c s.post(a) happens-before @c s.post(b) + * + * @li @c s.post(a) happens-before @c s.dispatch(b), where the latter is + * performed outside the strand + * + * @li @c s.dispatch(a) happens-before @c s.post(b), where the former is + * performed outside the strand + * + * @li @c s.dispatch(a) happens-before @c s.dispatch(b), where both are + * performed outside the strand + * + * then @c asio_handler_invoke(a1, &a1) happens-before + * @c asio_handler_invoke(b1, &b1). + * + * Note that in the following case: + * @code async_op_1(..., s.wrap(a)); + * async_op_2(..., s.wrap(b)); @endcode + * the completion of the first async operation will perform @c s.dispatch(a), + * and the second will perform @c s.dispatch(b), but the order in which those + * are performed is unspecified. That is, you cannot state whether one + * happens-before the other. Therefore none of the above conditions are met and + * no ordering guarantee is made. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Dispatcher. + */ +class io_service::strand +{ +public: + /// Constructor. + /** + * Constructs the strand. + * + * @param io_service The io_service object that the strand will use to + * dispatch handlers that are ready to be run. + */ + explicit strand(asio::io_service& io_service) + : service_(asio::use_service< + asio::detail::strand_service>(io_service)) + { + service_.construct(impl_); + } + + /// Destructor. + /** + * Destroys a strand. + * + * Handlers posted through the strand that have not yet been invoked will + * still be dispatched in a way that meets the guarantee of non-concurrency. + */ + ~strand() + { + service_.destroy(impl_); + } + + /// (Deprecated: use get_io_service().) Get the io_service associated with + /// the strand. + /** + * This function may be used to obtain the io_service object that the strand + * uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_service object that the strand will use to + * dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_service& io_service() + { + return service_.get_io_service(); + } + + /// Get the io_service associated with the strand. + /** + * This function may be used to obtain the io_service object that the strand + * uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_service object that the strand will use to + * dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_service& get_io_service() + { + return service_.get_io_service(); + } + + /// Request the strand to invoke the given handler. + /** + * This function is used to ask the strand to execute the given handler. + * + * The strand object guarantees that handlers posted or dispatched through + * the strand will not be executed concurrently. The handler may be executed + * inside this function if the guarantee can be met. If this function is + * called from within a handler that was posted or dispatched through the same + * strand, then the new handler will be executed immediately. + * + * The strand's guarantee is in addition to the guarantee provided by the + * underlying io_service. The io_service guarantees that the handler will only + * be called in a thread in which the io_service's run member function is + * currently being invoked. + * + * @param handler The handler to be called. The strand will make a copy of the + * handler object as required. The function signature of the handler must be: + * @code void handler(); @endcode + */ + template + void dispatch(Handler handler) + { + service_.dispatch(impl_, handler); + } + + /// Request the strand to invoke the given handler and return + /// immediately. + /** + * This function is used to ask the strand to execute the given handler, but + * without allowing the strand to call the handler from inside this function. + * + * The strand object guarantees that handlers posted or dispatched through + * the strand will not be executed concurrently. The strand's guarantee is in + * addition to the guarantee provided by the underlying io_service. The + * io_service guarantees that the handler will only be called in a thread in + * which the io_service's run member function is currently being invoked. + * + * @param handler The handler to be called. The strand will make a copy of the + * handler object as required. The function signature of the handler must be: + * @code void handler(); @endcode + */ + template + void post(Handler handler) + { + service_.post(impl_, handler); + } + + /// Create a new handler that automatically dispatches the wrapped handler + /// on the strand. + /** + * This function is used to create a new handler function object that, when + * invoked, will automatically pass the wrapped handler to the strand's + * dispatch function. + * + * @param handler The handler to be wrapped. The strand will make a copy of + * the handler object as required. The function signature of the handler must + * be: @code void handler(A1 a1, ... An an); @endcode + * + * @return A function object that, when invoked, passes the wrapped handler to + * the strand's dispatch function. Given a function object with the signature: + * @code R f(A1 a1, ... An an); @endcode + * If this function object is passed to the wrap function like so: + * @code strand.wrap(f); @endcode + * then the return value is a function object with the signature + * @code void g(A1 a1, ... An an); @endcode + * that, when invoked, executes code equivalent to: + * @code strand.dispatch(boost::bind(f, a1, ... an)); @endcode + */ + template +#if defined(GENERATING_DOCUMENTATION) + unspecified +#else + detail::wrapped_handler +#endif + wrap(Handler handler) + { + return detail::wrapped_handler(*this, handler); + } + +private: + asio::detail::strand_service& service_; + asio::detail::strand_service::implementation_type impl_; +}; + +/// Typedef for backwards compatibility. +typedef asio::io_service::strand strand; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_STRAND_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/stream_socket_service.hpp b/src/libs/resiprocate/contrib/asio/asio/stream_socket_service.hpp new file mode 100644 index 00000000..1c4935c1 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/stream_socket_service.hpp @@ -0,0 +1,278 @@ +// +// stream_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_STREAM_SOCKET_SERVICE_HPP +#define ASIO_STREAM_SOCKET_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/service_base.hpp" + +#if defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +#else +# include "asio/detail/reactive_socket_service.hpp" +#endif + +namespace asio { + +/// Default service implementation for a stream socket. +template +class stream_socket_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_service::service +#else + : public asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_service::id id; +#endif + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + +private: + // The type of the platform-specific implementation. +#if defined(ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#else + typedef detail::reactive_socket_service service_impl_type; +#endif + +public: + /// The type of a stream socket implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// The native socket type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef typename service_impl_type::native_type native_type; +#endif + + /// Construct a new stream socket service for the specified io_service. + explicit stream_socket_service(asio::io_service& io_service) + : asio::detail::service_base< + stream_socket_service >(io_service), + service_impl_(io_service) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + service_impl_.shutdown_service(); + } + + /// Construct a new stream socket implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a stream socket implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Open a stream socket. + asio::error_code open(implementation_type& impl, + const protocol_type& protocol, asio::error_code& ec) + { + if (protocol.type() == SOCK_STREAM) + service_impl_.open(impl, protocol, ec); + else + ec = asio::error::invalid_argument; + return ec; + } + + /// Assign an existing native socket to a stream socket. + asio::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_type& native_socket, + asio::error_code& ec) + { + return service_impl_.assign(impl, protocol, native_socket, ec); + } + + /// Determine whether the socket is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a stream socket implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// Get the native socket implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native(impl); + } + + /// Cancel all asynchronous operations associated with the socket. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Determine whether the socket is at the out-of-band data mark. + bool at_mark(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.at_mark(impl, ec); + } + + /// Determine the number of bytes available for reading. + std::size_t available(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.available(impl, ec); + } + + /// Bind the stream socket to the specified local endpoint. + asio::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + return service_impl_.bind(impl, endpoint, ec); + } + + /// Connect the stream socket to the specified endpoint. + asio::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, asio::error_code& ec) + { + return service_impl_.connect(impl, peer_endpoint, ec); + } + + /// Start an asynchronous connect. + template + void async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, ConnectHandler handler) + { + service_impl_.async_connect(impl, peer_endpoint, handler); + } + + /// Set a socket option. + template + asio::error_code set_option(implementation_type& impl, + const SettableSocketOption& option, asio::error_code& ec) + { + return service_impl_.set_option(impl, option, ec); + } + + /// Get a socket option. + template + asio::error_code get_option(const implementation_type& impl, + GettableSocketOption& option, asio::error_code& ec) const + { + return service_impl_.get_option(impl, option, ec); + } + + /// Perform an IO control command on the socket. + template + asio::error_code io_control(implementation_type& impl, + IoControlCommand& command, asio::error_code& ec) + { + return service_impl_.io_control(impl, command, ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + asio::error_code& ec) const + { + return service_impl_.remote_endpoint(impl, ec); + } + + /// Disable sends or receives on the socket. + asio::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, asio::error_code& ec) + { + return service_impl_.shutdown(impl, what, ec); + } + + /// Send the given data to the peer. + template + std::size_t send(implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return service_impl_.send(impl, buffers, flags, ec); + } + + /// Start an asynchronous send. + template + void async_send(implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, WriteHandler handler) + { + service_impl_.async_send(impl, buffers, flags, handler); + } + + /// Receive some data from the peer. + template + std::size_t receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, asio::error_code& ec) + { + return service_impl_.receive(impl, buffers, flags, ec); + } + + /// Start an asynchronous receive. + template + void async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, ReadHandler handler) + { + service_impl_.async_receive(impl, buffers, flags, handler); + } + +private: + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_STREAM_SOCKET_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/streambuf.hpp b/src/libs/resiprocate/contrib/asio/asio/streambuf.hpp new file mode 100644 index 00000000..665155be --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/streambuf.hpp @@ -0,0 +1,35 @@ +// +// streambuf.hpp +// ~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_STREAMBUF_HPP +#define ASIO_STREAMBUF_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/basic_streambuf.hpp" + +#if !defined(BOOST_NO_IOSTREAM) + +namespace asio { + +/// Typedef for the typical usage of basic_streambuf. +typedef basic_streambuf<> streambuf; + +} // namespace asio + +#endif // !defined(BOOST_NO_IOSTREAM) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_STREAMBUF_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/system_error.hpp b/src/libs/resiprocate/contrib/asio/asio/system_error.hpp new file mode 100644 index 00000000..e704b3fb --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/system_error.hpp @@ -0,0 +1,121 @@ +// +// system_error.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_SYSTEM_ERROR_HPP +#define ASIO_SYSTEM_ERROR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error_code.hpp" + +namespace asio { + +/// The system_error class is used to represent system conditions that +/// prevent the library from operating correctly. +class system_error + : public std::exception +{ +public: + /// Construct with an error code. + system_error(const error_code& code) + : code_(code), + context_() + { + } + + /// Construct with an error code and context. + system_error(const error_code& code, const std::string& context) + : code_(code), + context_(context) + { + } + + /// Copy constructor. + system_error(const system_error& other) + : std::exception(other), + code_(other.code_), + context_(other.context_), + what_() + { + } + + /// Destructor. + virtual ~system_error() throw () + { + } + + /// Assignment operator. + system_error& operator=(const system_error& e) + { + context_ = e.context_; + code_ = e.code_; + what_.reset(); + return *this; + } + + /// Get a string representation of the exception. + virtual const char* what() const throw () + { +#if !defined(BOOST_NO_EXCEPTIONS) + try +#endif // !defined(BOOST_NO_EXCEPTIONS) + { + if (!what_) + { + std::string tmp(context_); + if (tmp.length()) + tmp += ": "; + tmp += code_.message(); + what_.reset(new std::string(tmp)); + } + return what_->c_str(); + } +#if !defined(BOOST_NO_EXCEPTIONS) + catch (std::exception&) + { + return "system_error"; + } +#endif // !defined(BOOST_NO_EXCEPTIONS) + } + + /// Get the error code associated with the exception. + error_code code() const + { + return code_; + } + +private: + // The code associated with the error. + error_code code_; + + // The context associated with the error. + std::string context_; + + // The string representation of the error. + mutable boost::scoped_ptr what_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_SYSTEM_ERROR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/thread.hpp b/src/libs/resiprocate/contrib/asio/asio/thread.hpp new file mode 100644 index 00000000..9e578bc5 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/thread.hpp @@ -0,0 +1,91 @@ +// +// thread.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_THREAD_HPP +#define ASIO_THREAD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/thread.hpp" + +namespace asio { + +/// A simple abstraction for starting threads. +/** + * The asio::thread class implements the smallest possible subset of the + * functionality of boost::thread. It is intended to be used only for starting + * a thread and waiting for it to exit. If more extensive threading + * capabilities are required, you are strongly advised to use something else. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Example + * A typical use of asio::thread would be to launch a thread to run an + * io_service's event processing loop: + * + * @par + * @code asio::io_service io_service; + * // ... + * asio::thread t(boost::bind(&asio::io_service::run, &io_service)); + * // ... + * t.join(); @endcode + */ +class thread + : private noncopyable +{ +public: + /// Start a new thread that executes the supplied function. + /** + * This constructor creates a new thread that will execute the given function + * or function object. + * + * @param f The function or function object to be run in the thread. The + * function signature must be: @code void f(); @endcode + */ + template + explicit thread(Function f) + : impl_(f) + { + } + + /// Destructor. + ~thread() + { + } + + /// Wait for the thread to exit. + /** + * This function will block until the thread has exited. + * + * If this function is not called before the thread object is destroyed, the + * thread itself will continue to run until completion. You will, however, + * no longer have the ability to wait for it to exit. + */ + void join() + { + impl_.join(); + } + +private: + detail::thread impl_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_THREAD_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/time_traits.hpp b/src/libs/resiprocate/contrib/asio/asio/time_traits.hpp new file mode 100644 index 00000000..03713736 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/time_traits.hpp @@ -0,0 +1,82 @@ +// +// time_traits.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_TIME_TRAITS_HPP +#define ASIO_TIME_TRAITS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/socket_types.hpp" // Must come before posix_time. + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +namespace asio { + +/// Time traits suitable for use with the deadline timer. +template +struct time_traits; + +/// Time traits specialised for posix_time. +template <> +struct time_traits +{ + /// The time type. + typedef boost::posix_time::ptime time_type; + + /// The duration type. + typedef boost::posix_time::time_duration duration_type; + + /// Get the current time. + static time_type now() + { +#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) + return boost::posix_time::microsec_clock::universal_time(); +#else // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) + return boost::posix_time::second_clock::universal_time(); +#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) + } + + /// Add a duration to a time. + static time_type add(const time_type& t, const duration_type& d) + { + return t + d; + } + + /// Subtract one time from another. + static duration_type subtract(const time_type& t1, const time_type& t2) + { + return t1 - t2; + } + + /// Test whether one time is less than another. + static bool less_than(const time_type& t1, const time_type& t2) + { + return t1 < t2; + } + + /// Convert to POSIX duration type. + static boost::posix_time::time_duration to_posix_duration( + const duration_type& d) + { + return d; + } +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_TIME_TRAITS_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/version.hpp b/src/libs/resiprocate/contrib/asio/asio/version.hpp new file mode 100644 index 00000000..198f5086 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/version.hpp @@ -0,0 +1,23 @@ +// +// version.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_VERSION_HPP +#define ASIO_VERSION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +// ASIO_VERSION % 100 is the sub-minor version +// ASIO_VERSION / 100 % 1000 is the minor version +// ASIO_VERSION / 100000 is the major version +#define ASIO_VERSION 100405 // 1.4.5 + +#endif // ASIO_VERSION_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/windows/basic_handle.hpp b/src/libs/resiprocate/contrib/asio/asio/windows/basic_handle.hpp new file mode 100644 index 00000000..8c2ee60e --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/windows/basic_handle.hpp @@ -0,0 +1,225 @@ +// +// basic_handle.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_BASIC_HANDLE_HPP +#define ASIO_WINDOWS_BASIC_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_io_object.hpp" +#include "asio/error.hpp" +#include "asio/detail/throw_error.hpp" + +namespace asio { +namespace windows { + +/// Provides Windows handle functionality. +/** + * The windows::basic_handle class template provides the ability to wrap a + * Windows handle. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_handle + : public basic_io_object +{ +public: + /// The native representation of a handle. + typedef typename HandleService::native_type native_type; + + /// A basic_handle is always the lowest layer. + typedef basic_handle lowest_layer_type; + + /// Construct a basic_handle without opening it. + /** + * This constructor creates a handle without opening it. + * + * @param io_service The io_service object that the handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit basic_handle(asio::io_service& io_service) + : basic_io_object(io_service) + { + } + + /// Construct a basic_handle on an existing native handle. + /** + * This constructor creates a handle object to hold an existing native handle. + * + * @param io_service The io_service object that the handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param native_handle A native handle. + * + * @throws asio::system_error Thrown on failure. + */ + basic_handle(asio::io_service& io_service, + const native_type& native_handle) + : basic_io_object(io_service) + { + asio::error_code ec; + this->service.assign(this->implementation, native_handle, ec); + asio::detail::throw_error(ec); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since a basic_handle cannot contain any further layers, it simply + * returns a reference to itself. + * + * @return A reference to the lowest layer in the stack of layers. Ownership + * is not transferred to the caller. + */ + lowest_layer_type& lowest_layer() + { + return *this; + } + + /// Get a const reference to the lowest layer. + /** + * This function returns a const reference to the lowest layer in a stack of + * layers. Since a basic_handle cannot contain any further layers, it simply + * returns a reference to itself. + * + * @return A const reference to the lowest layer in the stack of layers. + * Ownership is not transferred to the caller. + */ + const lowest_layer_type& lowest_layer() const + { + return *this; + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param native_handle A native handle. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_type& native_handle) + { + asio::error_code ec; + this->service.assign(this->implementation, native_handle, ec); + asio::detail::throw_error(ec); + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param native_handle A native handle. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code assign(const native_type& native_handle, + asio::error_code& ec) + { + return this->service.assign(this->implementation, native_handle, ec); + } + + /// Determine whether the handle is open. + bool is_open() const + { + return this->service.is_open(this->implementation); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->service.close(this->implementation, ec); + asio::detail::throw_error(ec); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code close(asio::error_code& ec) + { + return this->service.close(this->implementation, ec); + } + + /// Get the native handle representation. + /** + * This function may be used to obtain the underlying representation of the + * handle. This is intended to allow access to native handle functionality + * that is not otherwise provided. + */ + native_type native() + { + return this->service.native(this->implementation); + } + + /// Cancel all asynchronous operations associated with the handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->service.cancel(this->implementation, ec); + asio::detail::throw_error(ec); + } + + /// Cancel all asynchronous operations associated with the handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + asio::error_code cancel(asio::error_code& ec) + { + return this->service.cancel(this->implementation, ec); + } + +protected: + /// Protected destructor to prevent deletion through this type. + ~basic_handle() + { + } +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WINDOWS_BASIC_HANDLE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/windows/basic_random_access_handle.hpp b/src/libs/resiprocate/contrib/asio/asio/windows/basic_random_access_handle.hpp new file mode 100644 index 00000000..2e6b994e --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/windows/basic_random_access_handle.hpp @@ -0,0 +1,320 @@ +// +// basic_random_access_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP +#define ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/windows/basic_handle.hpp" +#include "asio/windows/random_access_handle_service.hpp" +#include "asio/detail/throw_error.hpp" + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { +namespace windows { + +/// Provides random-access handle functionality. +/** + * The windows::basic_random_access_handle class template provides asynchronous + * and blocking random-access handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template +class basic_random_access_handle + : public basic_handle +{ +public: + /// The native representation of a handle. + typedef typename RandomAccessHandleService::native_type native_type; + + /// Construct a basic_random_access_handle without opening it. + /** + * This constructor creates a random-access handle without opening it. The + * handle needs to be opened before data can be written to or or read from it. + * + * @param io_service The io_service object that the random-access handle will + * use to dispatch handlers for any asynchronous operations performed on the + * handle. + */ + explicit basic_random_access_handle(asio::io_service& io_service) + : basic_handle(io_service) + { + } + + /// Construct a basic_random_access_handle on an existing native handle. + /** + * This constructor creates a random-access handle object to hold an existing + * native handle. + * + * @param io_service The io_service object that the random-access handle will + * use to dispatch handlers for any asynchronous operations performed on the + * handle. + * + * @param native_handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_random_access_handle(asio::io_service& io_service, + const native_type& native_handle) + : basic_handle(io_service, native_handle) + { + } + + /// Write some data to the handle at the specified offset. + /** + * This function is used to write data to the random-access handle. The + * function call will block until one or more bytes of the data has been + * written successfully, or until an error occurs. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some_at operation may not write all of the data. Consider + * using the @ref write_at function if you need to ensure that all data is + * written before the blocking operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * handle.write_some_at(42, asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t write_some_at(boost::uint64_t offset, + const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.write_some_at( + this->implementation, offset, buffers, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Write some data to the handle at the specified offset. + /** + * This function is used to write data to the random-access handle. The + * function call will block until one or more bytes of the data has been + * written successfully, or until an error occurs. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. Returns 0 if an error occurred. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write_at function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template + std::size_t write_some_at(boost::uint64_t offset, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return this->service.write_some_at( + this->implementation, offset, buffers, ec); + } + + /// Start an asynchronous write at the specified offset. + /** + * This function is used to asynchronously write data to the random-access + * handle. The function call always returns immediately. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write_at function if you need to ensure that + * all data is written before the asynchronous operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * handle.async_write_some_at(42, asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_write_some_at(boost::uint64_t offset, + const ConstBufferSequence& buffers, WriteHandler handler) + { + this->service.async_write_some_at( + this->implementation, offset, buffers, handler); + } + + /// Read some data from the handle at the specified offset. + /** + * This function is used to read data from the random-access handle. The + * function call will block until one or more bytes of data has been read + * successfully, or until an error occurs. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read_at function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * handle.read_some_at(42, asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t read_some_at(boost::uint64_t offset, + const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.read_some_at( + this->implementation, offset, buffers, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Read some data from the handle at the specified offset. + /** + * This function is used to read data from the random-access handle. The + * function call will block until one or more bytes of data has been read + * successfully, or until an error occurs. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. Returns 0 if an error occurred. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read_at function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + */ + template + std::size_t read_some_at(boost::uint64_t offset, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return this->service.read_some_at( + this->implementation, offset, buffers, ec); + } + + /// Start an asynchronous read at the specified offset. + /** + * This function is used to asynchronously read data from the random-access + * handle. The function call always returns immediately. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read_at function if you need to ensure that + * the requested amount of data is read before the asynchronous operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * handle.async_read_some_at(42, asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_read_some_at(boost::uint64_t offset, + const MutableBufferSequence& buffers, ReadHandler handler) + { + this->service.async_read_some_at( + this->implementation, offset, buffers, handler); + } +}; + +} // namespace windows +} // namespace asio + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/windows/basic_stream_handle.hpp b/src/libs/resiprocate/contrib/asio/asio/windows/basic_stream_handle.hpp new file mode 100644 index 00000000..48e7153d --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/windows/basic_stream_handle.hpp @@ -0,0 +1,302 @@ +// +// basic_stream_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP +#define ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/windows/basic_handle.hpp" +#include "asio/windows/stream_handle_service.hpp" +#include "asio/detail/throw_error.hpp" + +#if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { +namespace windows { + +/// Provides stream-oriented handle functionality. +/** + * The windows::basic_stream_handle class template provides asynchronous and + * blocking stream-oriented handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template +class basic_stream_handle + : public basic_handle +{ +public: + /// The native representation of a handle. + typedef typename StreamHandleService::native_type native_type; + + /// Construct a basic_stream_handle without opening it. + /** + * This constructor creates a stream handle without opening it. The handle + * needs to be opened and then connected or accepted before data can be sent + * or received on it. + * + * @param io_service The io_service object that the stream handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit basic_stream_handle(asio::io_service& io_service) + : basic_handle(io_service) + { + } + + /// Construct a basic_stream_handle on an existing native handle. + /** + * This constructor creates a stream handle object to hold an existing native + * handle. + * + * @param io_service The io_service object that the stream handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param native_handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_stream_handle(asio::io_service& io_service, + const native_type& native_handle) + : basic_handle(io_service, native_handle) + { + } + + /// Write some data to the handle. + /** + * This function is used to write data to the stream handle. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * handle.write_some(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.write_some(this->implementation, buffers, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Write some data to the handle. + /** + * This function is used to write data to the stream handle. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. Returns 0 if an error occurred. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) + { + return this->service.write_some(this->implementation, buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the stream handle. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the handle. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * handle.async_write_some(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_write_some(const ConstBufferSequence& buffers, + WriteHandler handler) + { + this->service.async_write_some(this->implementation, buffers, handler); + } + + /// Read some data from the handle. + /** + * This function is used to read data from the stream handle. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * handle.read_some(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->service.read_some(this->implementation, buffers, ec); + asio::detail::throw_error(ec); + return s; + } + + /// Read some data from the handle. + /** + * This function is used to read data from the stream handle. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. Returns 0 if an error occurred. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return this->service.read_some(this->implementation, buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the stream handle. + * The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be read. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read function if you need to ensure that the + * requested amount of data is read before the asynchronous operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * handle.async_read_some(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + void async_read_some(const MutableBufferSequence& buffers, + ReadHandler handler) + { + this->service.async_read_some(this->implementation, buffers, handler); + } +}; + +} // namespace windows +} // namespace asio + +#endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/windows/overlapped_ptr.hpp b/src/libs/resiprocate/contrib/asio/asio/windows/overlapped_ptr.hpp new file mode 100644 index 00000000..087170b5 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/windows/overlapped_ptr.hpp @@ -0,0 +1,118 @@ +// +// overlapped_ptr.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_OVERLAPPED_PTR_HPP +#define ASIO_WINDOWS_OVERLAPPED_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/io_service.hpp" +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/win_iocp_overlapped_ptr.hpp" + +#if !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR) +# if defined(ASIO_HAS_IOCP) +# define ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1 +# endif // defined(ASIO_HAS_IOCP) +#endif // !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR) + +#if defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { +namespace windows { + +/// Wraps a handler to create an OVERLAPPED object for use with overlapped I/O. +/** + * A special-purpose smart pointer used to wrap an application handler so that + * it can be passed as the LPOVERLAPPED argument to overlapped I/O functions. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class overlapped_ptr + : private noncopyable +{ +public: + /// Construct an empty overlapped_ptr. + overlapped_ptr() + : impl_() + { + } + + /// Construct an overlapped_ptr to contain the specified handler. + template + explicit overlapped_ptr(asio::io_service& io_service, Handler handler) + : impl_(io_service, handler) + { + } + + /// Destructor automatically frees the OVERLAPPED object unless released. + ~overlapped_ptr() + { + } + + /// Reset to empty. + void reset() + { + impl_.reset(); + } + + /// Reset to contain the specified handler, freeing any current OVERLAPPED + /// object. + template + void reset(asio::io_service& io_service, Handler handler) + { + impl_.reset(io_service, handler); + } + + /// Get the contained OVERLAPPED object. + OVERLAPPED* get() + { + return impl_.get(); + } + + /// Get the contained OVERLAPPED object. + const OVERLAPPED* get() const + { + return impl_.get(); + } + + /// Release ownership of the OVERLAPPED object. + OVERLAPPED* release() + { + return impl_.release(); + } + + /// Post completion notification for overlapped operation. Releases ownership. + void complete(const asio::error_code& ec, + std::size_t bytes_transferred) + { + impl_.complete(ec, bytes_transferred); + } + +private: + detail::win_iocp_overlapped_ptr impl_; +}; + +} // namespace windows +} // namespace asio + +#endif // defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WINDOWS_OVERLAPPED_PTR_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/windows/random_access_handle.hpp b/src/libs/resiprocate/contrib/asio/asio/windows/random_access_handle.hpp new file mode 100644 index 00000000..6e5dd7b6 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/windows/random_access_handle.hpp @@ -0,0 +1,39 @@ +// +// random_access_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP +#define ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/windows/basic_random_access_handle.hpp" + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { +namespace windows { + +/// Typedef for the typical usage of a random-access handle. +typedef basic_random_access_handle<> random_access_handle; + +} // namespace windows +} // namespace asio + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/windows/random_access_handle_service.hpp b/src/libs/resiprocate/contrib/asio/asio/windows/random_access_handle_service.hpp new file mode 100644 index 00000000..2e579f82 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/windows/random_access_handle_service.hpp @@ -0,0 +1,180 @@ +// +// random_access_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP +#define ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/detail/win_iocp_handle_service.hpp" + +#if !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE) +# if defined(ASIO_HAS_IOCP) +# define ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1 +# endif // defined(ASIO_HAS_IOCP) +#endif // !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE) + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { +namespace windows { + +/// Default service implementation for a random-access handle. +class random_access_handle_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_service::service +#else + : public asio::detail::service_base +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_service::id id; +#endif + +private: + // The type of the platform-specific implementation. + typedef detail::win_iocp_handle_service service_impl_type; + +public: + /// The type of a random-access handle implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef service_impl_type::implementation_type implementation_type; +#endif + + /// The native handle type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef service_impl_type::native_type native_type; +#endif + + /// Construct a new random-access handle service for the specified io_service. + explicit random_access_handle_service(asio::io_service& io_service) + : asio::detail::service_base< + random_access_handle_service>(io_service), + service_impl_(io_service) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + service_impl_.shutdown_service(); + } + + /// Construct a new random-access handle implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a random-access handle implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Assign an existing native handle to a random-access handle. + asio::error_code assign(implementation_type& impl, + const native_type& native_handle, asio::error_code& ec) + { + return service_impl_.assign(impl, native_handle, ec); + } + + /// Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a random-access handle implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// Get the native handle implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native(impl); + } + + /// Cancel all asynchronous operations associated with the handle. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Write the given data at the specified offset. + template + std::size_t write_some_at(implementation_type& impl, boost::uint64_t offset, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.write_some_at(impl, offset, buffers, ec); + } + + /// Start an asynchronous write at the specified offset. + template + void async_write_some_at(implementation_type& impl, boost::uint64_t offset, + const ConstBufferSequence& buffers, WriteHandler handler) + { + service_impl_.async_write_some_at(impl, offset, buffers, handler); + } + + /// Read some data from the specified offset. + template + std::size_t read_some_at(implementation_type& impl, boost::uint64_t offset, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.read_some_at(impl, offset, buffers, ec); + } + + /// Start an asynchronous read at the specified offset. + template + void async_read_some_at(implementation_type& impl, boost::uint64_t offset, + const MutableBufferSequence& buffers, ReadHandler handler) + { + service_impl_.async_read_some_at(impl, offset, buffers, handler); + } + +private: + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace windows +} // namespace asio + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/windows/stream_handle.hpp b/src/libs/resiprocate/contrib/asio/asio/windows/stream_handle.hpp new file mode 100644 index 00000000..d55dc317 --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/windows/stream_handle.hpp @@ -0,0 +1,39 @@ +// +// stream_handle.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_STREAM_HANDLE_HPP +#define ASIO_WINDOWS_STREAM_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/windows/basic_stream_handle.hpp" + +#if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { +namespace windows { + +/// Typedef for the typical usage of a stream-oriented handle. +typedef basic_stream_handle<> stream_handle; + +} // namespace windows +} // namespace asio + +#endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WINDOWS_STREAM_HANDLE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/windows/stream_handle_service.hpp b/src/libs/resiprocate/contrib/asio/asio/windows/stream_handle_service.hpp new file mode 100644 index 00000000..75eff60a --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/windows/stream_handle_service.hpp @@ -0,0 +1,178 @@ +// +// stream_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_STREAM_HANDLE_SERVICE_HPP +#define ASIO_WINDOWS_STREAM_HANDLE_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/error.hpp" +#include "asio/io_service.hpp" +#include "asio/detail/service_base.hpp" +#include "asio/detail/win_iocp_handle_service.hpp" + +#if !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE) +# if defined(ASIO_HAS_IOCP) +# define ASIO_HAS_WINDOWS_STREAM_HANDLE 1 +# endif // defined(ASIO_HAS_IOCP) +#endif // !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE) + +#if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +namespace asio { +namespace windows { + +/// Default service implementation for a stream handle. +class stream_handle_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_service::service +#else + : public asio::detail::service_base +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_service::id id; +#endif + +private: + // The type of the platform-specific implementation. + typedef detail::win_iocp_handle_service service_impl_type; + +public: + /// The type of a stream handle implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef service_impl_type::implementation_type implementation_type; +#endif + + /// The native handle type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef service_impl_type::native_type native_type; +#endif + + /// Construct a new stream handle service for the specified io_service. + explicit stream_handle_service(asio::io_service& io_service) + : asio::detail::service_base(io_service), + service_impl_(io_service) + { + } + + /// Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + service_impl_.shutdown_service(); + } + + /// Construct a new stream handle implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + + /// Destroy a stream handle implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Assign an existing native handle to a stream handle. + asio::error_code assign(implementation_type& impl, + const native_type& native_handle, asio::error_code& ec) + { + return service_impl_.assign(impl, native_handle, ec); + } + + /// Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a stream handle implementation. + asio::error_code close(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// Get the native handle implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native(impl); + } + + /// Cancel all asynchronous operations associated with the handle. + asio::error_code cancel(implementation_type& impl, + asio::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Write the given data to the stream. + template + std::size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.write_some(impl, buffers, ec); + } + + /// Start an asynchronous write. + template + void async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, WriteHandler handler) + { + service_impl_.async_write_some(impl, buffers, handler); + } + + /// Read some data from the stream. + template + std::size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.read_some(impl, buffers, ec); + } + + /// Start an asynchronous read. + template + void async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, ReadHandler handler) + { + service_impl_.async_read_some(impl, buffers, handler); + } + +private: + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace windows +} // namespace asio + +#endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WINDOWS_STREAM_HANDLE_SERVICE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/write.hpp b/src/libs/resiprocate/contrib/asio/asio/write.hpp new file mode 100644 index 00000000..2b188cde --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/write.hpp @@ -0,0 +1,540 @@ +// +// write.hpp +// ~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WRITE_HPP +#define ASIO_WRITE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_streambuf.hpp" +#include "asio/error.hpp" + +namespace asio { + +/** + * @defgroup write asio::write + * + * @brief Write a certain amount of data to a stream before returning. + */ +/*@{*/ + +/// Write all of the supplied data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * stream. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::write(s, asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + * + * @note This overload is equivalent to calling: + * @code asio::write( + * s, buffers, + * asio::transfer_all()); @endcode + */ +template +std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * stream. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's write_some function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::write(s, asio::buffer(data, size), + * asio::transfer_at_least(32)); @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * stream. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's write_some function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec); + +#if !defined(BOOST_NO_IOSTREAM) + +/// Write all of the supplied data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param b The basic_streambuf object from which data will be written. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @note This overload is equivalent to calling: + * @code asio::write( + * s, b, + * asio::transfer_all()); @endcode + */ +template +std::size_t write(SyncWriteStream& s, basic_streambuf& b); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param b The basic_streambuf object from which data will be written. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's write_some function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + */ +template +std::size_t write(SyncWriteStream& s, basic_streambuf& b, + CompletionCondition completion_condition); + +/// Write a certain amount of data to a stream before returning. +/** + * This function is used to write a certain number of bytes of data to a stream. + * The call will block until one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * write_some function. + * + * @param s The stream to which the data is to be written. The type must support + * the SyncWriteStream concept. + * + * @param b The basic_streambuf object from which data will be written. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's write_some function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t write(SyncWriteStream& s, basic_streambuf& b, + CompletionCondition completion_condition, asio::error_code& ec); + +#endif // !defined(BOOST_NO_IOSTREAM) + +/*@}*/ +/** + * @defgroup async_write asio::async_write + * + * @brief Start an asynchronous operation to write a certain amount of data to a + * stream. + */ +/*@{*/ + +/// Start an asynchronous operation to write all of the supplied data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_write_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other write operations (such + * as async_write, the stream's async_write_some function, or any other composed + * operations that perform writes) until this operation completes. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * asio::async_write(s, asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, + WriteHandler handler); + +/// Start an asynchronous operation to write a certain amount of data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_write_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other write operations (such + * as async_write, the stream's async_write_some function, or any other composed + * operations that perform writes) until this operation completes. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param buffers One or more buffers containing the data to be written. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's async_write_some function. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::async_write(s, + * asio::buffer(data, size), + * asio::transfer_at_least(32), + * handler); @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, WriteHandler handler); + +#if !defined(BOOST_NO_IOSTREAM) + +/// Start an asynchronous operation to write all of the supplied data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_write_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other write operations (such + * as async_write, the stream's async_write_some function, or any other composed + * operations that perform writes) until this operation completes. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param b A basic_streambuf object from which data will be written. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + */ +template +void async_write(AsyncWriteStream& s, basic_streambuf& b, + WriteHandler handler); + +/// Start an asynchronous operation to write a certain amount of data to a +/// stream. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a stream. The function call always returns immediately. The + * asynchronous operation will continue until one of the following conditions + * is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the stream's + * async_write_some function, and is known as a composed operation. The + * program must ensure that the stream performs no other write operations (such + * as async_write, the stream's async_write_some function, or any other composed + * operations that perform writes) until this operation completes. + * + * @param s The stream to which the data is to be written. The type must support + * the AsyncWriteStream concept. + * + * @param b A basic_streambuf object from which data will be written. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_write_some operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the stream's async_write_some function. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * + * std::size_t bytes_transferred // Number of bytes written from the + * // buffers. If an error occurred, + * // this will be less than the sum + * // of the buffer sizes. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + */ +template +void async_write(AsyncWriteStream& s, basic_streambuf& b, + CompletionCondition completion_condition, WriteHandler handler); + +#endif // !defined(BOOST_NO_IOSTREAM) + +/*@}*/ + +} // namespace asio + +#include "asio/impl/write.ipp" + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WRITE_HPP diff --git a/src/libs/resiprocate/contrib/asio/asio/write_at.hpp b/src/libs/resiprocate/contrib/asio/asio/write_at.hpp new file mode 100644 index 00000000..5690bcfd --- /dev/null +++ b/src/libs/resiprocate/contrib/asio/asio/write_at.hpp @@ -0,0 +1,563 @@ +// +// write_at.hpp +// ~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WRITE_AT_HPP +#define ASIO_WRITE_AT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/push_options.hpp" + +#include "asio/detail/push_options.hpp" +#include +#include +#include +#include "asio/detail/pop_options.hpp" + +#include "asio/basic_streambuf.hpp" +#include "asio/error.hpp" + +namespace asio { + +/** + * @defgroup write_at asio::write_at + * + * @brief Write a certain amount of data at a specified offset before returning. + */ +/*@{*/ + +/// Write all of the supplied data at the specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * device. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::write_at(d, 42, asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + * + * @note This overload is equivalent to calling: + * @code asio::write_at( + * d, offset, buffers, + * asio::transfer_all()); @endcode + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + boost::uint64_t offset, const ConstBufferSequence& buffers); + +/// Write a certain amount of data at a specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * device. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the device's write_some_at function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::write_at(d, 42, asio::buffer(data, size), + * asio::transfer_at_least(32)); @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + boost::uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition); + +/// Write a certain amount of data at a specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more buffers containing the data to be written. The sum + * of the buffer sizes indicates the maximum number of bytes to write to the + * device. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the device's write_some_at function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + boost::uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, asio::error_code& ec); + +#if !defined(BOOST_NO_IOSTREAM) + +/// Write all of the supplied data at the specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param b The basic_streambuf object from which data will be written. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + * + * @note This overload is equivalent to calling: + * @code asio::write_at( + * d, 42, b, + * asio::transfer_all()); @endcode + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, + boost::uint64_t offset, basic_streambuf& b); + +/// Write a certain amount of data at a specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param b The basic_streambuf object from which data will be written. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the device's write_some_at function. + * + * @returns The number of bytes transferred. + * + * @throws asio::system_error Thrown on failure. + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, boost::uint64_t offset, + basic_streambuf& b, CompletionCondition completion_condition); + +/// Write a certain amount of data at a specified offset before returning. +/** + * This function is used to write a certain number of bytes of data to a random + * access device at a specified offset. The call will block until one of the + * following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the SyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param b The basic_streambuf object from which data will be written. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest write_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the device's write_some_at function. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. If an error occurs, returns the total + * number of bytes successfully transferred prior to the error. + */ +template +std::size_t write_at(SyncRandomAccessWriteDevice& d, boost::uint64_t offset, + basic_streambuf& b, CompletionCondition completion_condition, + asio::error_code& ec); + +#endif // !defined(BOOST_NO_IOSTREAM) + +/*@}*/ +/** + * @defgroup async_write_at asio::async_write_at + * + * @brief Start an asynchronous operation to write a certain amount of data at + * the specified offset. + */ +/*@{*/ + +/// Start an asynchronous operation to write all of the supplied data at the +/// specified offset. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a random access device at a specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the AsyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more buffers containing the data to be written. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes written from the buffers. If an error + * // occurred, this will be less than the sum of the buffer sizes. + * std::size_t bytes_transferred + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * asio::async_write_at(d, 42, asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +void async_write_at(AsyncRandomAccessWriteDevice& d, boost::uint64_t offset, + const ConstBufferSequence& buffers, WriteHandler handler); + +/// Start an asynchronous operation to write a certain amount of data at the +/// specified offset. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a random access device at a specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li All of the data in the supplied buffers has been written. That is, the + * bytes transferred is equal to the sum of the buffer sizes. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the AsyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more buffers containing the data to be written. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_write_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the device's async_write_some_at function. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes written from the buffers. If an error + * // occurred, this will be less than the sum of the buffer sizes. + * std::size_t bytes_transferred + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code asio::async_write_at(d, 42, + * asio::buffer(data, size), + * asio::transfer_at_least(32), + * handler); @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ +template +void async_write_at(AsyncRandomAccessWriteDevice& d, + boost::uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, WriteHandler handler); + +#if !defined(BOOST_NO_IOSTREAM) + +/// Start an asynchronous operation to write all of the supplied data at the +/// specified offset. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a random access device at a specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li An error occurred. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the AsyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param b A basic_streambuf object from which data will be written. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes written from the buffers. If an error + * // occurred, this will be less than the sum of the buffer sizes. + * std::size_t bytes_transferred + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + */ +template +void async_write_at(AsyncRandomAccessWriteDevice& d, boost::uint64_t offset, + basic_streambuf& b, WriteHandler handler); + +/// Start an asynchronous operation to write a certain amount of data at the +/// specified offset. +/** + * This function is used to asynchronously write a certain number of bytes of + * data to a random access device at a specified offset. The function call + * always returns immediately. The asynchronous operation will continue until + * one of the following conditions is true: + * + * @li All of the data in the supplied basic_streambuf has been written. + * + * @li The completion_condition function object returns 0. + * + * This operation is implemented in terms of zero or more calls to the device's + * async_write_some_at function. + * + * @param d The device to which the data is to be written. The type must support + * the AsyncRandomAccessWriteDevice concept. + * + * @param offset The offset at which the data will be written. + * + * @param b A basic_streambuf object from which data will be written. Ownership + * of the streambuf is retained by the caller, which must guarantee that it + * remains valid until the handler is called. + * + * @param completion_condition The function object to be called to determine + * whether the write operation is complete. The signature of the function object + * must be: + * @code std::size_t completion_condition( + * // Result of latest async_write_some_at operation. + * const asio::error_code& error, + * + * // Number of bytes transferred so far. + * std::size_t bytes_transferred + * ); @endcode + * A return value of 0 indicates that the write operation is complete. A + * non-zero return value indicates the maximum number of bytes to be written on + * the next call to the device's async_write_some_at function. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of the + * handler must be: + * @code void handler( + * // Result of operation. + * const asio::error_code& error, + * + * // Number of bytes written from the buffers. If an error + * // occurred, this will be less than the sum of the buffer sizes. + * std::size_t bytes_transferred + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation of + * the handler will be performed in a manner equivalent to using + * asio::io_service::post(). + */ +template +void async_write_at(AsyncRandomAccessWriteDevice& d, boost::uint64_t offset, + basic_streambuf& b, CompletionCondition completion_condition, + WriteHandler handler); + +#endif // !defined(BOOST_NO_IOSTREAM) + +/*@}*/ + +} // namespace asio + +#include "asio/impl/write_at.ipp" + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_WRITE_AT_HPP diff --git a/src/libs/resiprocate/contrib/db/LICENSE b/src/libs/resiprocate/contrib/db/LICENSE new file mode 100644 index 00000000..a52521af --- /dev/null +++ b/src/libs/resiprocate/contrib/db/LICENSE @@ -0,0 +1,130 @@ +/*- + * $Id$ + */ + +The following is the license that applies to this copy of the Berkeley DB +software. For a license to use the Berkeley DB software under conditions +other than those described here, or to purchase support for this software, +please contact Oracle at berkeleydb-info_us@oracle.com. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +/* + * Copyright (c) 1990-2009 Oracle. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Redistributions in any form must be accompanied by information on + * how to obtain complete source code for the DB software and any + * accompanying software that uses the DB software. The source code + * must either be included in the distribution or be available for no + * more than the cost of distribution plus a nominal fee, and must be + * freely redistributable under reasonable conditions. For an + * executable file, complete source code means the source code for all + * modules it contains. It does not include source code for modules or + * files that typically accompany the major components of the operating + * system on which the executable file runs. + * + * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * Copyright (c) 1995, 1996 + * The President and Fellows of Harvard University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2005 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/src/libs/resiprocate/contrib/db/README b/src/libs/resiprocate/contrib/db/README new file mode 100644 index 00000000..5c2dd9aa --- /dev/null +++ b/src/libs/resiprocate/contrib/db/README @@ -0,0 +1,5 @@ +Berkeley DB 4.8.30: (April 9, 2010) + +This is version 4.8.30 of Berkeley DB from Oracle. To view release and +installation documentation, load the distribution file docs/index.html +into your web browser. diff --git a/src/libs/resiprocate/contrib/db/btree/bt_compare.c b/src/libs/resiprocate/contrib/db/btree/bt_compare.c new file mode 100644 index 00000000..bc340f2d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_compare.c @@ -0,0 +1,213 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" + +/* + * __bam_cmp -- + * Compare a key to a given record. + * + * PUBLIC: int __bam_cmp __P((DBC *, const DBT *, PAGE *, u_int32_t, + * PUBLIC: int (*)(DB *, const DBT *, const DBT *), int *)); + */ +int +__bam_cmp(dbc, dbt, h, indx, func, cmpp) + DBC *dbc; + const DBT *dbt; + PAGE *h; + u_int32_t indx; + int (*func)__P((DB *, const DBT *, const DBT *)); + int *cmpp; +{ + BINTERNAL *bi; + BKEYDATA *bk; + BOVERFLOW *bo; + DB *dbp; + DBT pg_dbt; + + dbp = dbc->dbp; + + /* + * Returns: + * < 0 if dbt is < page record + * = 0 if dbt is = page record + * > 0 if dbt is > page record + * + * !!! + * We do not clear the pg_dbt DBT even though it's likely to contain + * random bits. That should be okay, because the app's comparison + * routine had better not be looking at fields other than data, size + * and app_data. We don't clear it because we go through this path a + * lot and it's expensive. + */ + switch (TYPE(h)) { + case P_LBTREE: + case P_LDUP: + case P_LRECNO: + bk = GET_BKEYDATA(dbp, h, indx); + if (B_TYPE(bk->type) == B_OVERFLOW) + bo = (BOVERFLOW *)bk; + else { + pg_dbt.app_data = NULL; + pg_dbt.data = bk->data; + pg_dbt.size = bk->len; + *cmpp = func(dbp, dbt, &pg_dbt); + return (0); + } + break; + case P_IBTREE: + /* + * The following code guarantees that the left-most key on an + * internal page at any place in the tree sorts less than any + * user-specified key. The reason is that if we have reached + * this internal page, we know the user key must sort greater + * than the key we're storing for this page in any internal + * pages at levels above us in the tree. It then follows that + * any user-specified key cannot sort less than the first page + * which we reference, and so there's no reason to call the + * comparison routine. While this may save us a comparison + * routine call or two, the real reason for this is because + * we don't maintain a copy of the smallest key in the tree, + * so that we don't have to update all the levels of the tree + * should the application store a new smallest key. And, so, + * we may not have a key to compare, which makes doing the + * comparison difficult and error prone. + */ + if (indx == 0) { + *cmpp = 1; + return (0); + } + + bi = GET_BINTERNAL(dbp, h, indx); + if (B_TYPE(bi->type) == B_OVERFLOW) + bo = (BOVERFLOW *)(bi->data); + else { + pg_dbt.app_data = NULL; + pg_dbt.data = bi->data; + pg_dbt.size = bi->len; + *cmpp = func(dbp, dbt, &pg_dbt); + return (0); + } + break; + default: + return (__db_pgfmt(dbp->env, PGNO(h))); + } + + /* + * Overflow. + */ + return (__db_moff(dbc, dbt, bo->pgno, bo->tlen, + func == __bam_defcmp ? NULL : func, cmpp)); +} + +/* + * __bam_defcmp -- + * Default comparison routine. + * + * PUBLIC: int __bam_defcmp __P((DB *, const DBT *, const DBT *)); + */ +int +__bam_defcmp(dbp, a, b) + DB *dbp; + const DBT *a, *b; +{ + size_t len; + u_int8_t *p1, *p2; + + COMPQUIET(dbp, NULL); + + /* + * Returns: + * < 0 if a is < b + * = 0 if a is = b + * > 0 if a is > b + * + * XXX + * If a size_t doesn't fit into a long, or if the difference between + * any two characters doesn't fit into an int, this routine can lose. + * What we need is a signed integral type that's guaranteed to be at + * least as large as a size_t, and there is no such thing. + */ + len = a->size > b->size ? b->size : a->size; + for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2) + if (*p1 != *p2) + return ((long)*p1 - (long)*p2); + return ((long)a->size - (long)b->size); +} + +/* + * __bam_defpfx -- + * Default prefix routine. + * + * PUBLIC: size_t __bam_defpfx __P((DB *, const DBT *, const DBT *)); + */ +size_t +__bam_defpfx(dbp, a, b) + DB *dbp; + const DBT *a, *b; +{ + size_t cnt, len; + u_int8_t *p1, *p2; + + COMPQUIET(dbp, NULL); + + cnt = 1; + len = a->size > b->size ? b->size : a->size; + for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt) + if (*p1 != *p2) + return (cnt); + + /* + * They match up to the smaller of the two sizes. + * Collate the longer after the shorter. + */ + if (a->size < b->size) + return (a->size + 1); + if (b->size < a->size) + return (b->size + 1); + return (b->size); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_conv.c b/src/libs/resiprocate/contrib/db/btree/bt_conv.c new file mode 100644 index 00000000..aa14173f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_conv.c @@ -0,0 +1,95 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_swap.h" +#include "dbinc/btree.h" + +/* + * __bam_pgin -- + * Convert host-specific page layout from the host-independent format + * stored on disk. + * + * PUBLIC: int __bam_pgin __P((DB *, db_pgno_t, void *, DBT *)); + */ +int +__bam_pgin(dbp, pg, pp, cookie) + DB *dbp; + db_pgno_t pg; + void *pp; + DBT *cookie; +{ + DB_PGINFO *pginfo; + PAGE *h; + + pginfo = (DB_PGINFO *)cookie->data; + if (!F_ISSET(pginfo, DB_AM_SWAP)) + return (0); + + h = pp; + return (TYPE(h) == P_BTREEMETA ? __bam_mswap(dbp->env, pp) : + __db_byteswap(dbp, pg, pp, pginfo->db_pagesize, 1)); +} + +/* + * __bam_pgout -- + * Convert host-specific page layout to the host-independent format + * stored on disk. + * + * PUBLIC: int __bam_pgout __P((DB *, db_pgno_t, void *, DBT *)); + */ +int +__bam_pgout(dbp, pg, pp, cookie) + DB *dbp; + db_pgno_t pg; + void *pp; + DBT *cookie; +{ + DB_PGINFO *pginfo; + PAGE *h; + + pginfo = (DB_PGINFO *)cookie->data; + if (!F_ISSET(pginfo, DB_AM_SWAP)) + return (0); + + h = pp; + return (TYPE(h) == P_BTREEMETA ? __bam_mswap(dbp->env, pp) : + __db_byteswap(dbp, pg, pp, pginfo->db_pagesize, 0)); +} + +/* + * __bam_mswap -- + * Swap the bytes on the btree metadata page. + * + * PUBLIC: int __bam_mswap __P((ENV *, PAGE *)); + */ +int +__bam_mswap(env, pg) + ENV *env; + PAGE *pg; +{ + u_int8_t *p; + + COMPQUIET(env, NULL); + + __db_metaswap(pg); + p = (u_int8_t *)pg + sizeof(DBMETA); + + p += sizeof(u_int32_t); /* unused */ + SWAP32(p); /* minkey */ + SWAP32(p); /* re_len */ + SWAP32(p); /* re_pad */ + SWAP32(p); /* root */ + p += 92 * sizeof(u_int32_t); /* unused */ + SWAP32(p); /* crypto_magic */ + + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_curadj.c b/src/libs/resiprocate/contrib/db/btree/bt_curadj.c new file mode 100644 index 00000000..3f6077de --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_curadj.c @@ -0,0 +1,620 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/mp.h" + +static int __bam_opd_cursor __P((DB *, DBC *, db_pgno_t, u_int32_t, u_int32_t)); + +/* + * Cursor adjustments are logged if they are for subtransactions. This is + * because it's possible for a subtransaction to adjust cursors which will + * still be active after the subtransaction aborts, and so which must be + * restored to their previous locations. Cursors that can be both affected + * by our cursor adjustments and active after our transaction aborts can + * only be found in our parent transaction -- cursors in other transactions, + * including other child transactions of our parent, must have conflicting + * locker IDs, and so cannot be affected by adjustments in this transaction. + */ + +/* + * __bam_ca_delete -- + * Update the cursors when items are deleted and when already deleted + * items are overwritten. Return the number of relevant cursors found. + * + * PUBLIC: int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, int, int *)); + */ +int +__bam_ca_delete(dbp, pgno, indx, delete, countp) + DB *dbp; + db_pgno_t pgno; + u_int32_t indx; + int delete, *countp; +{ + BTREE_CURSOR *cp; + DB *ldbp; + DBC *dbc; + ENV *env; + int count; /* !!!: Has to contain max number of cursors. */ + + env = dbp->env; + + /* + * Adjust the cursors. We have the page write locked, so the + * only other cursors that can be pointing at a page are + * those in the same thread of control. Unfortunately, we don't + * know that they're using the same DB handle, so traverse + * all matching DB handles in the same ENV, then all cursors + * on each matching DB handle. + * + * Each cursor is single-threaded, so we only need to lock the + * list of DBs and then the list of cursors in each DB. + */ + MUTEX_LOCK(env, env->mtx_dblist); + FIND_FIRST_DB_MATCH(env, dbp, ldbp); + for (count = 0; + ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; + ldbp = TAILQ_NEXT(ldbp, dblistlinks)) { + MUTEX_LOCK(env, dbp->mutex); + TAILQ_FOREACH(dbc, &ldbp->active_queue, links) { + cp = (BTREE_CURSOR *)dbc->internal; + if (cp->pgno == pgno && cp->indx == indx && + !MVCC_SKIP_CURADJ(dbc, pgno)) { + /* + * [#8032] This assert is checking + * for possible race conditions where we + * hold a cursor position without a lock. + * Unfortunately, there are paths in the + * Btree code that do not satisfy these + * conditions. None of them are known to + * be a problem, but this assert should + * be re-activated when the Btree stack + * code is re-written. + DB_ASSERT(env, !STD_LOCKING(dbc) || + cp->lock_mode != DB_LOCK_NG); + */ + if (delete) { + F_SET(cp, C_DELETED); + /* + * If we're deleting the item, we can't + * keep a streaming offset cached. + */ + cp->stream_start_pgno = PGNO_INVALID; + } else + F_CLR(cp, C_DELETED); + +#ifdef HAVE_COMPRESSION + /* + * We also set the C_COMPRESS_MODIFIED flag, + * which prompts the compression code to look + * for it's current entry again if it needs to. + * + * The flag isn't cleared, because the + * compression code still needs to do that even + * for an entry that becomes undeleted. + * + * This flag also needs to be set if an entry is + * updated, but since the compression code + * always deletes before an update, setting it + * here is sufficient. + */ + F_SET(cp, C_COMPRESS_MODIFIED); +#endif + + ++count; + } + } + MUTEX_UNLOCK(env, dbp->mutex); + } + MUTEX_UNLOCK(env, env->mtx_dblist); + + if (countp != NULL) + *countp = count; + return (0); +} + +/* + * __ram_ca_delete -- + * Return if any relevant cursors found. + * + * PUBLIC: int __ram_ca_delete __P((DB *, db_pgno_t, int *)); + */ +int +__ram_ca_delete(dbp, root_pgno, foundp) + DB *dbp; + db_pgno_t root_pgno; + int *foundp; +{ + DB *ldbp; + DBC *dbc; + ENV *env; + int found; + + env = dbp->env; + + /* + * Review the cursors. See the comment in __bam_ca_delete(). + */ + MUTEX_LOCK(env, env->mtx_dblist); + FIND_FIRST_DB_MATCH(env, dbp, ldbp); + for (found = 0; + found == 0 && ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; + ldbp = TAILQ_NEXT(ldbp, dblistlinks)) { + MUTEX_LOCK(env, dbp->mutex); + TAILQ_FOREACH(dbc, &ldbp->active_queue, links) + if (dbc->internal->root == root_pgno && + !MVCC_SKIP_CURADJ(dbc, root_pgno)) { + found = 1; + break; + } + MUTEX_UNLOCK(env, dbp->mutex); + } + MUTEX_UNLOCK(env, env->mtx_dblist); + + *foundp = found; + return (0); +} + +/* + * __bam_ca_di -- + * Adjust the cursors during a delete or insert. + * + * PUBLIC: int __bam_ca_di __P((DBC *, db_pgno_t, u_int32_t, int)); + */ +int +__bam_ca_di(my_dbc, pgno, indx, adjust) + DBC *my_dbc; + db_pgno_t pgno; + u_int32_t indx; + int adjust; +{ + DB *dbp, *ldbp; + DBC *dbc; + DBC_INTERNAL *cp; + DB_LSN lsn; + DB_TXN *my_txn; + ENV *env; + int found, ret; + + dbp = my_dbc->dbp; + env = dbp->env; + + my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL; + + /* + * Adjust the cursors. See the comment in __bam_ca_delete(). + */ + MUTEX_LOCK(env, env->mtx_dblist); + FIND_FIRST_DB_MATCH(env, dbp, ldbp); + for (found = 0; + ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; + ldbp = TAILQ_NEXT(ldbp, dblistlinks)) { + MUTEX_LOCK(env, dbp->mutex); + TAILQ_FOREACH(dbc, &ldbp->active_queue, links) { + if (dbc->dbtype == DB_RECNO) + continue; + cp = dbc->internal; + if (cp->pgno == pgno && cp->indx >= indx && + (dbc == my_dbc || !MVCC_SKIP_CURADJ(dbc, pgno))) { + /* Cursor indices should never be negative. */ + DB_ASSERT(env, cp->indx != 0 || adjust > 0); + /* [#8032] + DB_ASSERT(env, !STD_LOCKING(dbc) || + cp->lock_mode != DB_LOCK_NG); + */ + cp->indx += adjust; + if (my_txn != NULL && dbc->txn != my_txn) + found = 1; + } + } + MUTEX_UNLOCK(env, dbp->mutex); + } + MUTEX_UNLOCK(env, env->mtx_dblist); + + if (found != 0 && DBC_LOGGING(my_dbc)) { + if ((ret = __bam_curadj_log(dbp, my_dbc->txn, &lsn, 0, + DB_CA_DI, pgno, 0, 0, (u_int32_t)adjust, indx, 0)) != 0) + return (ret); + } + + return (0); +} + +/* + * __bam_opd_cursor -- create a new opd cursor. + */ +static int +__bam_opd_cursor(dbp, dbc, first, tpgno, ti) + DB *dbp; + DBC *dbc; + db_pgno_t tpgno; + u_int32_t first, ti; +{ + BTREE_CURSOR *cp, *orig_cp; + DBC *dbc_nopd; + int ret; + + orig_cp = (BTREE_CURSOR *)dbc->internal; + dbc_nopd = NULL; + + /* + * Allocate a new cursor and create the stack. If duplicates + * are sorted, we've just created an off-page duplicate Btree. + * If duplicates aren't sorted, we've just created a Recno tree. + * + * Note that in order to get here at all, there shouldn't be + * an old off-page dup cursor--to augment the checking dbc_newopd + * will do, assert this. + */ + DB_ASSERT(dbp->env, orig_cp->opd == NULL); + if ((ret = __dbc_newopd(dbc, tpgno, orig_cp->opd, &dbc_nopd)) != 0) + return (ret); + + cp = (BTREE_CURSOR *)dbc_nopd->internal; + cp->pgno = tpgno; + cp->indx = ti; + + if (dbp->dup_compare == NULL) { + /* + * Converting to off-page Recno trees is tricky. The + * record number for the cursor is the index + 1 (to + * convert to 1-based record numbers). + */ + cp->recno = ti + 1; + } + + /* + * Transfer the deleted flag from the top-level cursor to the + * created one. + */ + if (F_ISSET(orig_cp, C_DELETED)) { + F_SET(cp, C_DELETED); + F_CLR(orig_cp, C_DELETED); + } + + /* Stack the cursors and reset the initial cursor's index. */ + orig_cp->opd = dbc_nopd; + orig_cp->indx = first; + return (0); +} + +/* + * __bam_ca_dup -- + * Adjust the cursors when moving items from a leaf page to a duplicates + * page. + * + * PUBLIC: int __bam_ca_dup __P((DBC *, + * PUBLIC: u_int32_t, db_pgno_t, u_int32_t, db_pgno_t, u_int32_t)); + */ +int +__bam_ca_dup(my_dbc, first, fpgno, fi, tpgno, ti) + DBC *my_dbc; + db_pgno_t fpgno, tpgno; + u_int32_t first, fi, ti; +{ + BTREE_CURSOR *orig_cp; + DB *dbp, *ldbp; + DBC *dbc; + DB_LSN lsn; + DB_TXN *my_txn; + ENV *env; + int found, ret, t_ret; + + dbp = my_dbc->dbp; + env = dbp->env; + my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL; + ret = 0; + + /* + * Adjust the cursors. See the comment in __bam_ca_delete(). + */ + MUTEX_LOCK(env, env->mtx_dblist); + FIND_FIRST_DB_MATCH(env, dbp, ldbp); + for (found = 0; + ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; + ldbp = TAILQ_NEXT(ldbp, dblistlinks)) { +loop: MUTEX_LOCK(env, dbp->mutex); + TAILQ_FOREACH(dbc, &ldbp->active_queue, links) { + /* Find cursors pointing to this record. */ + orig_cp = (BTREE_CURSOR *)dbc->internal; + if (orig_cp->pgno != fpgno || orig_cp->indx != fi || + MVCC_SKIP_CURADJ(dbc, fpgno)) + continue; + + /* + * Since we rescan the list see if this is already + * converted. + */ + if (orig_cp->opd != NULL) + continue; + + MUTEX_UNLOCK(env, dbp->mutex); + /* [#8032] + DB_ASSERT(env, !STD_LOCKING(dbc) || + orig_cp->lock_mode != DB_LOCK_NG); + */ + if ((ret = __bam_opd_cursor(dbp, + dbc, first, tpgno, ti)) != 0) + goto err; + if (my_txn != NULL && dbc->txn != my_txn) + found = 1; + /* We released the mutex to get a cursor, start over. */ + goto loop; + } + MUTEX_UNLOCK(env, dbp->mutex); + } +err: MUTEX_UNLOCK(env, env->mtx_dblist); + + if (found != 0 && DBC_LOGGING(my_dbc)) { + if ((t_ret = __bam_curadj_log(dbp, my_dbc->txn, + &lsn, 0, DB_CA_DUP, fpgno, tpgno, 0, first, fi, ti)) != 0 && + ret == 0) + ret = t_ret; + } + + return (ret); +} + +/* + * __bam_ca_undodup -- + * Adjust the cursors when returning items to a leaf page + * from a duplicate page. + * Called only during undo processing. + * + * PUBLIC: int __bam_ca_undodup __P((DB *, + * PUBLIC: u_int32_t, db_pgno_t, u_int32_t, u_int32_t)); + */ +int +__bam_ca_undodup(dbp, first, fpgno, fi, ti) + DB *dbp; + db_pgno_t fpgno; + u_int32_t first, fi, ti; +{ + BTREE_CURSOR *orig_cp; + DB *ldbp; + DBC *dbc; + ENV *env; + int ret; + + env = dbp->env; + ret = 0; + + /* + * Adjust the cursors. See the comment in __bam_ca_delete(). + */ + MUTEX_LOCK(env, env->mtx_dblist); + FIND_FIRST_DB_MATCH(env, dbp, ldbp); + for (; + ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; + ldbp = TAILQ_NEXT(ldbp, dblistlinks)) { +loop: MUTEX_LOCK(env, dbp->mutex); + TAILQ_FOREACH(dbc, &ldbp->active_queue, links) { + orig_cp = (BTREE_CURSOR *)dbc->internal; + + /* + * A note on the orig_cp->opd != NULL requirement here: + * it's possible that there's a cursor that refers to + * the same duplicate set, but which has no opd cursor, + * because it refers to a different item and we took + * care of it while processing a previous record. + */ + if (orig_cp->pgno != fpgno || + orig_cp->indx != first || + orig_cp->opd == NULL || ((BTREE_CURSOR *) + orig_cp->opd->internal)->indx != ti || + MVCC_SKIP_CURADJ(dbc, fpgno)) + continue; + MUTEX_UNLOCK(env, dbp->mutex); + if ((ret = __dbc_close(orig_cp->opd)) != 0) + goto err; + orig_cp->opd = NULL; + orig_cp->indx = fi; + /* + * We released the mutex to free a cursor, + * start over. + */ + goto loop; + } + MUTEX_UNLOCK(env, dbp->mutex); + } +err: MUTEX_UNLOCK(env, env->mtx_dblist); + + return (ret); +} + +/* + * __bam_ca_rsplit -- + * Adjust the cursors when doing reverse splits. + * + * PUBLIC: int __bam_ca_rsplit __P((DBC *, db_pgno_t, db_pgno_t)); + */ +int +__bam_ca_rsplit(my_dbc, fpgno, tpgno) + DBC* my_dbc; + db_pgno_t fpgno, tpgno; +{ + DB *dbp, *ldbp; + DBC *dbc; + DB_LSN lsn; + DB_TXN *my_txn; + ENV *env; + int found, ret; + + dbp = my_dbc->dbp; + env = dbp->env; + my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL; + + /* + * Adjust the cursors. See the comment in __bam_ca_delete(). + */ + MUTEX_LOCK(env, env->mtx_dblist); + FIND_FIRST_DB_MATCH(env, dbp, ldbp); + for (found = 0; + ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; + ldbp = TAILQ_NEXT(ldbp, dblistlinks)) { + MUTEX_LOCK(env, dbp->mutex); + TAILQ_FOREACH(dbc, &ldbp->active_queue, links) { + if (dbc->dbtype == DB_RECNO) + continue; + if (dbc->internal->pgno == fpgno && + !MVCC_SKIP_CURADJ(dbc, fpgno)) { + dbc->internal->pgno = tpgno; + /* [#8032] + DB_ASSERT(env, !STD_LOCKING(dbc) || + dbc->internal->lock_mode != DB_LOCK_NG); + */ + if (my_txn != NULL && dbc->txn != my_txn) + found = 1; + } + } + MUTEX_UNLOCK(env, dbp->mutex); + } + MUTEX_UNLOCK(env, env->mtx_dblist); + + if (found != 0 && DBC_LOGGING(my_dbc)) { + if ((ret = __bam_curadj_log(dbp, my_dbc->txn, + &lsn, 0, DB_CA_RSPLIT, fpgno, tpgno, 0, 0, 0, 0)) != 0) + return (ret); + } + return (0); +} + +/* + * __bam_ca_split -- + * Adjust the cursors when splitting a page. + * + * PUBLIC: int __bam_ca_split __P((DBC *, + * PUBLIC: db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t, int)); + */ +int +__bam_ca_split(my_dbc, ppgno, lpgno, rpgno, split_indx, cleft) + DBC *my_dbc; + db_pgno_t ppgno, lpgno, rpgno; + u_int32_t split_indx; + int cleft; +{ + DB *dbp, *ldbp; + DBC *dbc; + DBC_INTERNAL *cp; + DB_LSN lsn; + DB_TXN *my_txn; + ENV *env; + int found, ret; + + dbp = my_dbc->dbp; + env = dbp->env; + my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL; + + /* + * Adjust the cursors. See the comment in __bam_ca_delete(). + * + * If splitting the page that a cursor was on, the cursor has to be + * adjusted to point to the same record as before the split. Most + * of the time we don't adjust pointers to the left page, because + * we're going to copy its contents back over the original page. If + * the cursor is on the right page, it is decremented by the number of + * records split to the left page. + */ + MUTEX_LOCK(env, env->mtx_dblist); + FIND_FIRST_DB_MATCH(env, dbp, ldbp); + for (found = 0; + ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; + ldbp = TAILQ_NEXT(ldbp, dblistlinks)) { + MUTEX_LOCK(env, dbp->mutex); + TAILQ_FOREACH(dbc, &ldbp->active_queue, links) { + if (dbc->dbtype == DB_RECNO) + continue; + cp = dbc->internal; + if (cp->pgno == ppgno && + !MVCC_SKIP_CURADJ(dbc, ppgno)) { + /* [#8032] + DB_ASSERT(env, !STD_LOCKING(dbc) || + cp->lock_mode != DB_LOCK_NG); + */ + if (my_txn != NULL && dbc->txn != my_txn) + found = 1; + if (cp->indx < split_indx) { + if (cleft) + cp->pgno = lpgno; + } else { + cp->pgno = rpgno; + cp->indx -= split_indx; + } + } + } + MUTEX_UNLOCK(env, dbp->mutex); + } + MUTEX_UNLOCK(env, env->mtx_dblist); + + if (found != 0 && DBC_LOGGING(my_dbc)) { + if ((ret = __bam_curadj_log(dbp, + my_dbc->txn, &lsn, 0, DB_CA_SPLIT, ppgno, rpgno, + cleft ? lpgno : PGNO_INVALID, 0, split_indx, 0)) != 0) + return (ret); + } + + return (0); +} + +/* + * __bam_ca_undosplit -- + * Adjust the cursors when undoing a split of a page. + * If we grew a level we will execute this for both the + * left and the right pages. + * Called only during undo processing. + * + * PUBLIC: int __bam_ca_undosplit __P((DB *, + * PUBLIC: db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t)); + */ +int +__bam_ca_undosplit(dbp, frompgno, topgno, lpgno, split_indx) + DB *dbp; + db_pgno_t frompgno, topgno, lpgno; + u_int32_t split_indx; +{ + DB *ldbp; + DBC *dbc; + DBC_INTERNAL *cp; + ENV *env; + + env = dbp->env; + + /* + * Adjust the cursors. See the comment in __bam_ca_delete(). + * + * When backing out a split, we move the cursor back + * to the original offset and bump it by the split_indx. + */ + MUTEX_LOCK(env, env->mtx_dblist); + FIND_FIRST_DB_MATCH(env, dbp, ldbp); + for (; + ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; + ldbp = TAILQ_NEXT(ldbp, dblistlinks)) { + MUTEX_LOCK(env, dbp->mutex); + TAILQ_FOREACH(dbc, &ldbp->active_queue, links) { + if (dbc->dbtype == DB_RECNO) + continue; + cp = dbc->internal; + if (cp->pgno == topgno && + !MVCC_SKIP_CURADJ(dbc, topgno)) { + cp->pgno = frompgno; + cp->indx += split_indx; + } else if (cp->pgno == lpgno && + !MVCC_SKIP_CURADJ(dbc, lpgno)) + cp->pgno = frompgno; + } + MUTEX_UNLOCK(env, dbp->mutex); + } + MUTEX_UNLOCK(env, env->mtx_dblist); + + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_cursor.c b/src/libs/resiprocate/contrib/db/btree/bt_cursor.c new file mode 100644 index 00000000..b0d6f7d6 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_cursor.c @@ -0,0 +1,3055 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" + +static int __bam_bulk __P((DBC *, DBT *, u_int32_t)); +static int __bamc_close __P((DBC *, db_pgno_t, int *)); +static int __bamc_del __P((DBC *, u_int32_t)); +static int __bamc_destroy __P((DBC *)); +static int __bamc_get __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); +static int __bamc_getstack __P((DBC *)); +static int __bamc_next __P((DBC *, int, int)); +static int __bamc_physdel __P((DBC *)); +static int __bamc_prev __P((DBC *)); +static int __bamc_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); +static int __bamc_search __P((DBC *, + db_pgno_t, const DBT *, u_int32_t, int *)); +static int __bamc_writelock __P((DBC *)); +static int __bam_getboth_finddatum __P((DBC *, DBT *, u_int32_t)); +static int __bam_getbothc __P((DBC *, DBT *)); +static int __bam_get_prev __P((DBC *)); +static int __bam_isopd __P((DBC *, db_pgno_t *)); +#ifdef HAVE_COMPRESSION +static int __bam_getlte __P((DBC *, DBT *, DBT *)); +#endif + +/* + * Acquire a new page/lock. If we hold a page/lock, discard the page, and + * lock-couple the lock. + * + * !!! + * We have to handle both where we have a lock to lock-couple and where we + * don't -- we don't duplicate locks when we duplicate cursors if we are + * running in a transaction environment as there's no point if locks are + * never discarded. This means that the cursor may or may not hold a lock. + * In the case where we are descending the tree we always want to unlock + * the held interior page so we use ACQUIRE_COUPLE. + */ +#undef ACQUIRE +#define ACQUIRE(dbc, mode, lpgno, lock, fpgno, pagep, flags, ret) do { \ + DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf; \ + if ((pagep) != NULL) { \ + ret = __memp_fput(__mpf, \ + (dbc)->thread_info, pagep, dbc->priority); \ + pagep = NULL; \ + } else \ + ret = 0; \ + if ((ret) == 0 && STD_LOCKING(dbc)) \ + ret = __db_lget( \ + dbc, LCK_COUPLE, lpgno, mode, flags, &(lock)); \ + if ((ret) == 0) \ + ret = __memp_fget(__mpf, &(fpgno), \ + (dbc)->thread_info, (dbc)->txn, 0, &(pagep)); \ +} while (0) + +/* Acquire a new page/lock for a cursor. */ +#undef ACQUIRE_CUR +#define ACQUIRE_CUR(dbc, mode, p, flags, ret) do { \ + BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal; \ + if (p != __cp->pgno) \ + __cp->pgno = PGNO_INVALID; \ + ACQUIRE(dbc, mode, p, __cp->lock, p, __cp->page, flags, ret); \ + if ((ret) == 0) { \ + __cp->pgno = p; \ + __cp->lock_mode = (mode); \ + } \ +} while (0) + +/* + * Acquire a write lock if we don't already have one. + * + * !!! + * See ACQUIRE macro on why we handle cursors that don't have locks. + */ +#undef ACQUIRE_WRITE_LOCK +#define ACQUIRE_WRITE_LOCK(dbc, ret) do { \ + BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal; \ + DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf; \ + int __get_page = 0; \ + ret = 0; \ + if (STD_LOCKING(dbc) && __cp->lock_mode != DB_LOCK_WRITE) { \ + if (__cp->page != NULL) { \ + (ret) = __memp_fput(__mpf, (dbc)->thread_info, \ + __cp->page, (dbc)->priority); \ + __cp->page = NULL; \ + __get_page = 1; \ + if ((ret) !=0) \ + break; \ + } \ + if (((ret) = __db_lget((dbc), \ + LOCK_ISSET(__cp->lock) ? LCK_COUPLE : 0, \ + __cp->pgno, DB_LOCK_WRITE, 0, &__cp->lock)) != 0) \ + break; \ + __cp->lock_mode = DB_LOCK_WRITE; \ + if (__get_page == 0) \ + break; \ + (ret) = __memp_fget(__mpf, &__cp->pgno, \ + (dbc)->thread_info, \ + (dbc)->txn, DB_MPOOL_DIRTY, &__cp->page); \ + } \ +} while (0) + +/* Discard the current page/lock for a cursor. */ +#undef DISCARD_CUR +#define DISCARD_CUR(dbc, ret) do { \ + BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal; \ + DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf; \ + int __t_ret; \ + if ((__cp->page) != NULL) { \ + __t_ret = __memp_fput(__mpf, \ + (dbc)->thread_info, __cp->page, dbc->priority);\ + __cp->page = NULL; \ + } else \ + __t_ret = 0; \ + if (__t_ret != 0 && (ret) == 0) \ + ret = __t_ret; \ + __t_ret = __TLPUT((dbc), __cp->lock); \ + if (__t_ret != 0 && (ret) == 0) \ + ret = __t_ret; \ + if ((ret) == 0 && !LOCK_ISSET(__cp->lock)) \ + __cp->lock_mode = DB_LOCK_NG; \ + __cp->stream_start_pgno = PGNO_INVALID; \ +} while (0) + +/* If on-page item is a deleted record. */ +#undef IS_DELETED +#define IS_DELETED(dbp, page, indx) \ + B_DISSET(GET_BKEYDATA(dbp, page, \ + (indx) + (TYPE(page) == P_LBTREE ? O_INDX : 0))->type) +#undef IS_CUR_DELETED +#define IS_CUR_DELETED(dbc) \ + IS_DELETED((dbc)->dbp, (dbc)->internal->page, (dbc)->internal->indx) + +/* + * Test to see if two cursors could point to duplicates of the same key. + * In the case of off-page duplicates they are they same, as the cursors + * will be in the same off-page duplicate tree. In the case of on-page + * duplicates, the key index offsets must be the same. For the last test, + * as the original cursor may not have a valid page pointer, we use the + * current cursor's. + */ +#undef IS_DUPLICATE +#define IS_DUPLICATE(dbc, i1, i2) \ + (P_INP((dbc)->dbp,((PAGE *)(dbc)->internal->page))[i1] == \ + P_INP((dbc)->dbp,((PAGE *)(dbc)->internal->page))[i2]) +#undef IS_CUR_DUPLICATE +#define IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx) \ + (F_ISSET(dbc, DBC_OPD) || \ + (orig_pgno == (dbc)->internal->pgno && \ + IS_DUPLICATE(dbc, (dbc)->internal->indx, orig_indx))) + +/* + * __bamc_init -- + * Initialize the access private portion of a cursor + * + * PUBLIC: int __bamc_init __P((DBC *, DBTYPE)); + */ +int +__bamc_init(dbc, dbtype) + DBC *dbc; + DBTYPE dbtype; +{ + ENV *env; + int ret; +#ifdef HAVE_COMPRESSION + BTREE_CURSOR *cp; +#endif + + env = dbc->env; + + /* Allocate/initialize the internal structure. */ + if (dbc->internal == NULL) { + if ((ret = __os_calloc( + env, 1, sizeof(BTREE_CURSOR), &dbc->internal)) != 0) + return (ret); + +#ifdef HAVE_COMPRESSION + cp = (BTREE_CURSOR*)dbc->internal; + cp->compressed.flags = DB_DBT_USERMEM; + cp->key1.flags = DB_DBT_USERMEM; + cp->key2.flags = DB_DBT_USERMEM; + cp->data1.flags = DB_DBT_USERMEM; + cp->data2.flags = DB_DBT_USERMEM; + cp->del_key.flags = DB_DBT_USERMEM; + cp->del_data.flags = DB_DBT_USERMEM; +#endif + } + + /* Initialize methods. */ + dbc->close = dbc->c_close = __dbc_close_pp; + dbc->cmp = __dbc_cmp_pp; + dbc->count = dbc->c_count = __dbc_count_pp; + dbc->del = dbc->c_del = __dbc_del_pp; + dbc->dup = dbc->c_dup = __dbc_dup_pp; + dbc->get = dbc->c_get = __dbc_get_pp; + dbc->pget = dbc->c_pget = __dbc_pget_pp; + dbc->put = dbc->c_put = __dbc_put_pp; + if (dbtype == DB_BTREE) { + dbc->am_bulk = __bam_bulk; + dbc->am_close = __bamc_close; + dbc->am_del = __bamc_del; + dbc->am_destroy = __bamc_destroy; + dbc->am_get = __bamc_get; + dbc->am_put = __bamc_put; + dbc->am_writelock = __bamc_writelock; + } else { + dbc->am_bulk = __bam_bulk; + dbc->am_close = __bamc_close; + dbc->am_del = __ramc_del; + dbc->am_destroy = __bamc_destroy; + dbc->am_get = __ramc_get; + dbc->am_put = __ramc_put; + dbc->am_writelock = __bamc_writelock; + } + + return (0); +} + +/* + * __bamc_refresh + * Set things up properly for cursor re-use. + * + * PUBLIC: int __bamc_refresh __P((DBC *)); + */ +int +__bamc_refresh(dbc) + DBC *dbc; +{ + BTREE *t; + BTREE_CURSOR *cp; + DB *dbp; + + dbp = dbc->dbp; + t = dbp->bt_internal; + cp = (BTREE_CURSOR *)dbc->internal; + + /* + * If our caller set the root page number, it's because the root was + * known. This is always the case for off page dup cursors. Else, + * pull it out of our internal information. + */ + if (cp->root == PGNO_INVALID) + cp->root = t->bt_root; + + LOCK_INIT(cp->lock); + cp->lock_mode = DB_LOCK_NG; + + if (cp->sp == NULL) { + cp->sp = cp->stack; + cp->esp = cp->stack + sizeof(cp->stack) / sizeof(cp->stack[0]); + } + BT_STK_CLR(cp); + +#ifdef HAVE_COMPRESSION + /* Initialize compression */ + cp->prevKey = 0; + cp->prevData = 0; + cp->currentKey = 0; + cp->currentData = 0; + cp->compcursor = 0; + cp->compend = 0; + cp->prevcursor = 0; + cp->prev2cursor = 0; +#endif + + /* + * The btree leaf page data structures require that two key/data pairs + * (or four items) fit on a page, but other than that there's no fixed + * requirement. The btree off-page duplicates only require two items, + * to be exact, but requiring four for them as well seems reasonable. + * + * Recno uses the btree bt_ovflsize value -- it's close enough. + */ + cp->ovflsize = B_MINKEY_TO_OVFLSIZE( + dbp, F_ISSET(dbc, DBC_OPD) ? 2 : t->bt_minkey, dbp->pgsize); + + cp->recno = RECNO_OOB; + cp->order = INVALID_ORDER; + cp->flags = 0; + + /* Initialize for record numbers. */ + if (F_ISSET(dbc, DBC_OPD) || + dbc->dbtype == DB_RECNO || F_ISSET(dbp, DB_AM_RECNUM)) { + F_SET(cp, C_RECNUM); + + /* + * All btrees that support record numbers, optionally standard + * recno trees, and all off-page duplicate recno trees have + * mutable record numbers. + */ + if ((F_ISSET(dbc, DBC_OPD) && dbc->dbtype == DB_RECNO) || + F_ISSET(dbp, DB_AM_RECNUM | DB_AM_RENUMBER)) + F_SET(cp, C_RENUMBER); + } + + return (0); +} + +/* + * __bamc_close -- + * Close down the cursor. + */ +static int +__bamc_close(dbc, root_pgno, rmroot) + DBC *dbc; + db_pgno_t root_pgno; + int *rmroot; +{ + BTREE_CURSOR *cp, *cp_opd, *cp_c; + DB *dbp; + DBC *dbc_opd, *dbc_c; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *h; + int cdb_lock, count, ret; + + dbp = dbc->dbp; + env = dbp->env; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + cp_opd = (dbc_opd = cp->opd) == NULL ? + NULL : (BTREE_CURSOR *)dbc_opd->internal; + cdb_lock = ret = 0; + + /* + * There are 3 ways this function is called: + * + * 1. Closing a primary cursor: we get called with a pointer to a + * primary cursor that has a NULL opd field. This happens when + * closing a btree/recno database cursor without an associated + * off-page duplicate tree. + * + * 2. Closing a primary and an off-page duplicate cursor stack: we + * get called with a pointer to the primary cursor which has a + * non-NULL opd field. This happens when closing a btree cursor + * into database with an associated off-page btree/recno duplicate + * tree. (It can't be a primary recno database, recno databases + * don't support duplicates.) + * + * 3. Closing an off-page duplicate cursor stack: we get called with + * a pointer to the off-page duplicate cursor. This happens when + * closing a non-btree database that has an associated off-page + * btree/recno duplicate tree or for a btree database when the + * opd tree is not empty (root_pgno == PGNO_INVALID). + * + * If either the primary or off-page duplicate cursor deleted a btree + * key/data pair, check to see if the item is still referenced by a + * different cursor. If it is, confirm that cursor's delete flag is + * set and leave it to that cursor to do the delete. + * + * NB: The test for == 0 below is correct. Our caller already removed + * our cursor argument from the active queue, we won't find it when we + * search the queue in __bam_ca_delete(). + * NB: It can't be true that both the primary and off-page duplicate + * cursors have deleted a btree key/data pair. Either the primary + * cursor may have deleted an item and there's no off-page duplicate + * cursor, or there's an off-page duplicate cursor and it may have + * deleted an item. + * + * Primary recno databases aren't an issue here. Recno keys are either + * deleted immediately or never deleted, and do not have to be handled + * here. + * + * Off-page duplicate recno databases are an issue here, cases #2 and + * #3 above can both be off-page recno databases. The problem is the + * same as the final problem for off-page duplicate btree databases. + * If we no longer need the off-page duplicate tree, we want to remove + * it. For off-page duplicate btrees, we are done with the tree when + * we delete the last item it contains, i.e., there can be no further + * references to it when it's empty. For off-page duplicate recnos, + * we remove items from the tree as the application calls the remove + * function, so we are done with the tree when we close the last cursor + * that references it. + * + * We optionally take the root page number from our caller. If the + * primary database is a btree, we can get it ourselves because dbc + * is the primary cursor. If the primary database is not a btree, + * the problem is that we may be dealing with a stack of pages. The + * cursor we're using to do the delete points at the bottom of that + * stack and we need the top of the stack. + */ + if (F_ISSET(cp, C_DELETED)) { + dbc_c = dbc; + switch (dbc->dbtype) { + case DB_BTREE: /* Case #1, #3. */ + if ((ret = __bam_ca_delete( + dbp, cp->pgno, cp->indx, 1, &count)) != 0) + goto err; + if (count == 0) + goto lock; + goto done; + case DB_RECNO: + if (!F_ISSET(dbc, DBC_OPD)) /* Case #1. */ + goto done; + /* Case #3. */ + if ((ret = __ram_ca_delete(dbp, cp->root, &count)) != 0) + goto err; + if (count == 0) + goto lock; + goto done; + case DB_HASH: + case DB_QUEUE: + case DB_UNKNOWN: + default: + ret = __db_unknown_type( + env, "DbCursor.close", dbc->dbtype); + goto err; + } + } + + if (dbc_opd == NULL) + goto done; + + if (F_ISSET(cp_opd, C_DELETED)) { /* Case #2. */ + /* + * We will not have been provided a root page number. Acquire + * one from the primary database. + */ + if ((h = cp->page) == NULL && (ret = __memp_fget(mpf, &cp->pgno, + dbc->thread_info, dbc->txn, 0, &h)) != 0) + goto err; + root_pgno = GET_BOVERFLOW(dbp, h, cp->indx + O_INDX)->pgno; + if ((ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0) + goto err; + cp->page = NULL; + + dbc_c = dbc_opd; + switch (dbc_opd->dbtype) { + case DB_BTREE: + if ((ret = __bam_ca_delete( + dbp, cp_opd->pgno, cp_opd->indx, 1, &count)) != 0) + goto err; + if (count == 0) + goto lock; + goto done; + case DB_RECNO: + if ((ret = + __ram_ca_delete(dbp, cp_opd->root, &count)) != 0) + goto err; + if (count == 0) + goto lock; + goto done; + case DB_HASH: + case DB_QUEUE: + case DB_UNKNOWN: + default: + ret = __db_unknown_type( + env, "DbCursor.close", dbc->dbtype); + goto err; + } + } + goto done; + +lock: cp_c = (BTREE_CURSOR *)dbc_c->internal; + + /* + * If this is CDB, upgrade the lock if necessary. While we acquired + * the write lock to logically delete the record, we released it when + * we returned from that call, and so may not be holding a write lock + * at the moment. + */ + if (CDB_LOCKING(env)) { + if (F_ISSET(dbc, DBC_WRITECURSOR)) { + if ((ret = __lock_get(env, + dbc->locker, DB_LOCK_UPGRADE, &dbc->lock_dbt, + DB_LOCK_WRITE, &dbc->mylock)) != 0) + goto err; + cdb_lock = 1; + } + goto delete; + } + + /* + * The variable dbc_c has been initialized to reference the cursor in + * which we're going to do the delete. Initialize the cursor's lock + * structures as necessary. + * + * First, we may not need to acquire any locks. If we're in case #3, + * that is, the primary database isn't a btree database, our caller + * is responsible for acquiring any necessary locks before calling us. + */ + if (F_ISSET(dbc, DBC_OPD)) + goto delete; + + /* + * Otherwise, acquire a write lock on the primary database's page. + * + * Lock the primary database page, regardless of whether we're deleting + * an item on a primary database page or an off-page duplicates page. + * + * If the cursor that did the initial logical deletion (and had a write + * lock) is not the same cursor doing the physical deletion (which may + * have only ever had a read lock on the item), we need to upgrade to a + * write lock. The confusion comes as follows: + * + * C1 created, acquires item read lock + * C2 dup C1, create C2, also has item read lock. + * C1 acquire write lock, delete item + * C1 close + * C2 close, needs a write lock to physically delete item. + * + * If we're in a TXN, we know that C2 will be able to acquire the write + * lock, because no locker other than the one shared by C1 and C2 can + * acquire a write lock -- the original write lock C1 acquired was never + * discarded. + * + * If we're not in a TXN, it's nastier. Other cursors might acquire + * read locks on the item after C1 closed, discarding its write lock, + * and such locks would prevent C2 from acquiring a read lock. That's + * OK, though, we'll simply wait until we can acquire a write lock, or + * we'll deadlock. (Which better not happen, since we're not in a TXN.) + * + * There are similar scenarios with dirty reads, where the cursor may + * have downgraded its write lock to a was-write lock. + */ + if (STD_LOCKING(dbc)) + if ((ret = __db_lget(dbc, + LCK_COUPLE, cp->pgno, DB_LOCK_WRITE, 0, &cp->lock)) != 0) + goto err; + +delete: /* + * If the delete occurred in a Btree, we're going to look at the page + * to see if the item has to be physically deleted. Otherwise, we do + * not need the actual page (and it may not even exist, it might have + * been truncated from the file after an allocation aborted). + * + * Delete the on-page physical item referenced by the cursor. + */ + if (dbc_c->dbtype == DB_BTREE) { + if ((ret = __memp_fget(mpf, &cp_c->pgno, dbc->thread_info, + dbc->txn, DB_MPOOL_DIRTY, &cp_c->page)) != 0) + goto err; + if ((ret = __bamc_physdel(dbc_c)) != 0) + goto err; + } + + /* + * If we're not working in an off-page duplicate tree, then we're + * done. + */ + if (!F_ISSET(dbc_c, DBC_OPD) || root_pgno == PGNO_INVALID) + goto done; + + /* + * We may have just deleted the last element in the off-page duplicate + * tree, and closed the last cursor in the tree. For an off-page btree + * there are no other cursors in the tree by definition, if the tree is + * empty. For an off-page recno we know we have closed the last cursor + * in the tree because the __ram_ca_delete call above returned 0 only + * in that case. So, if the off-page duplicate tree is empty at this + * point, we want to remove it. + */ + if (((h = dbc_c->internal->page) == NULL || h->pgno != root_pgno) && + (ret = __memp_fget(mpf, + &root_pgno, dbc->thread_info, dbc->txn, 0, &h)) != 0) + goto err; + if (NUM_ENT(h) == 0) { + if (h != dbc_c->internal->page) + DISCARD_CUR(dbc_c, ret); + else + dbc_c->internal->page = NULL; + if (ret != 0) + goto err; + if ((ret = __db_free(dbc, h)) != 0) + goto err; + } else { + if (h != dbc_c->internal->page && (ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0) + goto err; + goto done; + } + + /* + * When removing the tree, we have to do one of two things. If this is + * case #2, that is, the primary tree is a btree, delete the key that's + * associated with the tree from the btree leaf page. We know we are + * the only reference to it and we already have the correct lock. We + * detect this case because the cursor that was passed to us references + * an off-page duplicate cursor. + * + * If this is case #3, that is, the primary tree isn't a btree, pass + * the information back to our caller, it's their job to do cleanup on + * the primary page. + */ + if (dbc_opd != NULL) { + if ((ret = __memp_fget(mpf, &cp->pgno, dbc->thread_info, + dbc->txn, DB_MPOOL_DIRTY, &cp->page)) != 0) + goto err; + if ((ret = __bamc_physdel(dbc)) != 0) + goto err; + } else + *rmroot = 1; +err: +done: /* + * Discard the page references and locks, and confirm that the stack + * has been emptied. + */ + if (dbc_opd != NULL) + DISCARD_CUR(dbc_opd, ret); + DISCARD_CUR(dbc, ret); + + /* Downgrade any CDB lock we acquired. */ + if (cdb_lock) + (void)__lock_downgrade(env, &dbc->mylock, DB_LOCK_IWRITE, 0); + + return (ret); +} + +/* + * __bamc_cmp -- + * Compare two btree cursors for equality. + * + * This function is only called with two cursors that point to the same item. + * It only distinguishes cursors pointing to deleted and undeleted items at + * the same location. + * + * PUBLIC: int __bamc_cmp __P((DBC *, DBC *, int *)); + */ +int +__bamc_cmp(dbc, other_dbc, result) + DBC *dbc, *other_dbc; + int *result; +{ + ENV *env; + BTREE_CURSOR *bcp, *obcp; + + env = dbc->env; + bcp = (BTREE_CURSOR *)dbc->internal; + obcp = (BTREE_CURSOR *)other_dbc->internal; + + DB_ASSERT (env, bcp->pgno == obcp->pgno); + DB_ASSERT (env, bcp->indx == obcp->indx); + + /* Check to see if both cursors have the same deleted flag. */ + *result = + ((F_ISSET(bcp, C_DELETED)) == F_ISSET(obcp, C_DELETED)) ? 0 : 1; + return (0); +} + +/* + * __bamc_destroy -- + * Close a single cursor -- internal version. + */ +static int +__bamc_destroy(dbc) + DBC *dbc; +{ + BTREE_CURSOR *cp; + ENV *env; + + cp = (BTREE_CURSOR *)dbc->internal; + env = dbc->env; + + /* Discard the structures. */ + if (cp->sp != cp->stack) + __os_free(env, cp->sp); + +#ifdef HAVE_COMPRESSION + /* Free the memory used for compression */ + __os_free(env, cp->compressed.data); + __os_free(env, cp->key1.data); + __os_free(env, cp->key2.data); + __os_free(env, cp->data1.data); + __os_free(env, cp->data2.data); + __os_free(env, cp->del_key.data); + __os_free(env, cp->del_data.data); +#endif + + __os_free(env, cp); + + return (0); +} + +/* + * __bamc_count -- + * Return a count of on and off-page duplicates. + * + * PUBLIC: int __bamc_count __P((DBC *, db_recno_t *)); + */ +int +__bamc_count(dbc, recnop) + DBC *dbc; + db_recno_t *recnop; +{ + BTREE_CURSOR *cp; + DB *dbp; + DB_MPOOLFILE *mpf; + db_indx_t indx, top; + db_recno_t recno; + int ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + + /* + * Called with the top-level cursor that may reference an off-page + * duplicates tree. We don't have to acquire any new locks, we have + * to have a read lock to even get here. + */ + if (cp->opd == NULL) { + /* + * On-page duplicates, get the page and count. + */ + DB_ASSERT(dbp->env, cp->page == NULL); + if ((ret = __memp_fget(mpf, &cp->pgno, + dbc->thread_info, dbc->txn, 0, &cp->page)) != 0) + return (ret); + + /* + * Move back to the beginning of the set of duplicates and + * then count forward. + */ + for (indx = cp->indx;; indx -= P_INDX) + if (indx == 0 || + !IS_DUPLICATE(dbc, indx, indx - P_INDX)) + break; + for (recno = 0, + top = NUM_ENT(cp->page) - P_INDX;; indx += P_INDX) { + if (!IS_DELETED(dbp, cp->page, indx)) + ++recno; + if (indx == top || + !IS_DUPLICATE(dbc, indx, indx + P_INDX)) + break; + } + } else { + /* + * Off-page duplicates tree, get the root page of the off-page + * duplicate tree. + */ + if ((ret = __memp_fget(mpf, &cp->opd->internal->root, + dbc->thread_info, dbc->txn, 0, &cp->page)) != 0) + return (ret); + + /* + * If the page is an internal page use the page's count as it's + * up-to-date and reflects the status of cursors in the tree. + * If the page is a leaf page for unsorted duplicates, use the + * page's count as cursors don't mark items deleted on the page + * and wait, cursor delete items immediately. + * If the page is a leaf page for sorted duplicates, there may + * be cursors on the page marking deleted items -- count. + */ + if (TYPE(cp->page) == P_LDUP) + for (recno = 0, indx = 0, + top = NUM_ENT(cp->page) - O_INDX;; indx += O_INDX) { + if (!IS_DELETED(dbp, cp->page, indx)) + ++recno; + if (indx == top) + break; + } + else + recno = RE_NREC(cp->page); + } + + *recnop = recno; + + ret = __memp_fput(mpf, dbc->thread_info, cp->page, dbc->priority); + cp->page = NULL; + + return (ret); +} + +/* + * __bamc_del -- + * Delete using a cursor. + */ +static int +__bamc_del(dbc, flags) + DBC *dbc; + u_int32_t flags; +{ + BTREE_CURSOR *cp; + DB *dbp; + DB_MPOOLFILE *mpf; + int count, ret, t_ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + ret = 0; + COMPQUIET(flags, 0); + + /* If the item was already deleted, return failure. */ + if (F_ISSET(cp, C_DELETED)) + return (DB_KEYEMPTY); + + /* + * This code is always called with a page lock but no page. + */ + DB_ASSERT(dbp->env, cp->page == NULL); + + /* + * We don't physically delete the record until the cursor moves, so + * we have to have a long-lived write lock on the page instead of a + * a long-lived read lock. Note, we have to have a read lock to even + * get here. + * + * If we're maintaining record numbers, we lock the entire tree, else + * we lock the single page. + */ + if (F_ISSET(cp, C_RECNUM)) { + if ((ret = __bamc_getstack(dbc)) != 0) + goto err; + cp->page = cp->csp->page; + } else { + ACQUIRE_CUR(dbc, DB_LOCK_WRITE, cp->pgno, 0, ret); + if (ret != 0) + goto err; + } + + /* Mark the page dirty. */ + if ((ret = __memp_dirty(mpf, + &cp->page, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + goto err; + + /* Log the change. */ + if (DBC_LOGGING(dbc)) { + if ((ret = __bam_cdel_log(dbp, dbc->txn, &LSN(cp->page), 0, + PGNO(cp->page), &LSN(cp->page), cp->indx)) != 0) + goto err; + } else + LSN_NOT_LOGGED(LSN(cp->page)); + + /* Set the intent-to-delete flag on the page. */ + if (TYPE(cp->page) == P_LBTREE) + B_DSET(GET_BKEYDATA(dbp, cp->page, cp->indx + O_INDX)->type); + else + B_DSET(GET_BKEYDATA(dbp, cp->page, cp->indx)->type); + +err: /* + * If we've been successful so far and the tree has record numbers, + * adjust the record counts. Either way, release acquired page(s). + */ + if (F_ISSET(cp, C_RECNUM)) { + cp->csp->page = cp->page; + if (ret == 0) + ret = __bam_adjust(dbc, -1); + (void)__bam_stkrel(dbc, 0); + } else + if (cp->page != NULL && + (t_ret = __memp_fput(mpf, dbc->thread_info, + cp->page, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + + cp->page = NULL; + + /* + * Update the cursors last, after all chance of recoverable failure + * is past. + */ + if (ret == 0) + ret = __bam_ca_delete(dbp, cp->pgno, cp->indx, 1, &count); + + return (ret); +} + +/* + * __bamc_dup -- + * Duplicate a btree cursor, such that the new one holds appropriate + * locks for the position of the original. + * + * PUBLIC: int __bamc_dup __P((DBC *, DBC *, u_int32_t)); + */ +int +__bamc_dup(orig_dbc, new_dbc, flags) + DBC *orig_dbc, *new_dbc; + u_int32_t flags; +{ + BTREE_CURSOR *orig, *new; + + orig = (BTREE_CURSOR *)orig_dbc->internal; + new = (BTREE_CURSOR *)new_dbc->internal; + + new->ovflsize = orig->ovflsize; + new->recno = orig->recno; + new->flags = orig->flags; + +#ifdef HAVE_COMPRESSION + /* Copy the compression state */ + return (__bamc_compress_dup(orig_dbc, new_dbc, flags)); +#else + COMPQUIET(flags, 0); + + return (0); +#endif +} + +/* + * __bamc_get -- + * Get using a cursor (btree). + */ +static int +__bamc_get(dbc, key, data, flags, pgnop) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; + db_pgno_t *pgnop; +{ + BTREE_CURSOR *cp; + DB *dbp; + DB_MPOOLFILE *mpf; + db_pgno_t orig_pgno; + db_indx_t orig_indx; + int exact, newopd, ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + orig_pgno = cp->pgno; + orig_indx = cp->indx; + + newopd = 0; + switch (flags) { + case DB_CURRENT: + /* It's not possible to return a deleted record. */ + if (F_ISSET(cp, C_DELETED)) { + ret = DB_KEYEMPTY; + goto err; + } + + /* + * Acquire the current page. We have at least a read-lock + * already. The caller may have set DB_RMW asking for a + * write lock, but upgrading to a write lock has no better + * chance of succeeding now instead of later, so don't try. + */ + if ((ret = __memp_fget(mpf, &cp->pgno, + dbc->thread_info, dbc->txn, 0, &cp->page)) != 0) + goto err; + break; + case DB_FIRST: + newopd = 1; + if ((ret = __bamc_search(dbc, + PGNO_INVALID, NULL, flags, &exact)) != 0) + goto err; + break; + case DB_GET_BOTH: + case DB_GET_BOTH_RANGE: + /* + * There are two ways to get here based on DBcursor->get + * with the DB_GET_BOTH/DB_GET_BOTH_RANGE flags set: + * + * 1. Searching a sorted off-page duplicate tree: do a tree + * search. + * + * 2. Searching btree: do a tree search. If it returns a + * reference to off-page duplicate tree, return immediately + * and let our caller deal with it. If the search doesn't + * return a reference to off-page duplicate tree, continue + * with an on-page search. + */ + if (F_ISSET(dbc, DBC_OPD)) { + if ((ret = __bamc_search( + dbc, PGNO_INVALID, data, flags, &exact)) != 0) + goto err; + if (flags == DB_GET_BOTH) { + if (!exact) { + ret = DB_NOTFOUND; + goto err; + } + break; + } + + /* + * We didn't require an exact match, so the search may + * may have returned an entry past the end of the page, + * or we may be referencing a deleted record. If so, + * move to the next entry. + */ + if ((cp->indx == NUM_ENT(cp->page) || + IS_CUR_DELETED(dbc)) && + (ret = __bamc_next(dbc, 1, 0)) != 0) + goto err; + } else { + if ((ret = __bamc_search( + dbc, PGNO_INVALID, key, flags, &exact)) != 0) + return (ret); + if (!exact) { + ret = DB_NOTFOUND; + goto err; + } + + if (pgnop != NULL && __bam_isopd(dbc, pgnop)) { + newopd = 1; + break; + } + if ((ret = + __bam_getboth_finddatum(dbc, data, flags)) != 0) + goto err; + } + break; +#ifdef HAVE_COMPRESSION + case DB_SET_LTE: + if ((ret = __bam_getlte(dbc, key, NULL)) != 0) + goto err; + break; + case DB_GET_BOTH_LTE: + if ((ret = __bam_getlte(dbc, key, data)) != 0) + goto err; + break; +#endif + case DB_GET_BOTHC: + if ((ret = __bam_getbothc(dbc, data)) != 0) + goto err; + break; + case DB_LAST: + newopd = 1; + if ((ret = __bamc_search(dbc, + PGNO_INVALID, NULL, flags, &exact)) != 0) + goto err; + break; + case DB_NEXT: + newopd = 1; + if (cp->pgno == PGNO_INVALID) { + if ((ret = __bamc_search(dbc, + PGNO_INVALID, NULL, DB_FIRST, &exact)) != 0) + goto err; + } else + if ((ret = __bamc_next(dbc, 1, 0)) != 0) + goto err; + break; + case DB_NEXT_DUP: + if ((ret = __bamc_next(dbc, 1, 0)) != 0) + goto err; + if (!IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx)) { + ret = DB_NOTFOUND; + goto err; + } + break; + case DB_NEXT_NODUP: + newopd = 1; + if (cp->pgno == PGNO_INVALID) { + if ((ret = __bamc_search(dbc, + PGNO_INVALID, NULL, DB_FIRST, &exact)) != 0) + goto err; + } else + do { + if ((ret = __bamc_next(dbc, 1, 0)) != 0) + goto err; + } while (IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx)); + break; + case DB_PREV: + newopd = 1; + if (cp->pgno == PGNO_INVALID) { + if ((ret = __bamc_search(dbc, + PGNO_INVALID, NULL, DB_LAST, &exact)) != 0) + goto err; + } else + if ((ret = __bamc_prev(dbc)) != 0) + goto err; + break; + case DB_PREV_DUP: + if ((ret = __bamc_prev(dbc)) != 0) + goto err; + if (!IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx)) { + ret = DB_NOTFOUND; + goto err; + } + break; + case DB_PREV_NODUP: + newopd = 1; + if (cp->pgno == PGNO_INVALID) { + if ((ret = __bamc_search(dbc, + PGNO_INVALID, NULL, DB_LAST, &exact)) != 0) + goto err; + } else + do { + if ((ret = __bamc_prev(dbc)) != 0) + goto err; + } while (IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx)); + break; + case DB_SET: + case DB_SET_RECNO: + newopd = 1; + if ((ret = __bamc_search(dbc, + PGNO_INVALID, key, flags, &exact)) != 0) + goto err; + break; + case DB_SET_RANGE: + newopd = 1; + if ((ret = __bamc_search(dbc, + PGNO_INVALID, key, flags, &exact)) != 0) + goto err; + + /* + * As we didn't require an exact match, the search function + * may have returned an entry past the end of the page. Or, + * we may be referencing a deleted record. If so, move to + * the next entry. + */ + if (cp->indx == NUM_ENT(cp->page) || IS_CUR_DELETED(dbc)) + if ((ret = __bamc_next(dbc, 0, 0)) != 0) + goto err; + break; + default: + ret = __db_unknown_flag(dbp->env, "__bamc_get", flags); + goto err; + } + + /* + * We may have moved to an off-page duplicate tree. Return that + * information to our caller. + */ + if (newopd && pgnop != NULL) + (void)__bam_isopd(dbc, pgnop); + +err: /* + * Regardless of whether we were successful or not, if the cursor + * moved, clear the delete flag, DBcursor->get never references a + * deleted key, if it moved at all. + */ + if (F_ISSET(cp, C_DELETED) && + (cp->pgno != orig_pgno || cp->indx != orig_indx)) + F_CLR(cp, C_DELETED); + + return (ret); +} + +static int +__bam_get_prev(dbc) + DBC *dbc; +{ + BTREE_CURSOR *cp; + DBT key, data; + db_pgno_t pgno; + int ret; + + if ((ret = __bamc_prev(dbc)) != 0) + return (ret); + + if (__bam_isopd(dbc, &pgno)) { + cp = (BTREE_CURSOR *)dbc->internal; + if ((ret = __dbc_newopd(dbc, pgno, cp->opd, &cp->opd)) != 0) + return (ret); + if ((ret = cp->opd->am_get(cp->opd, + &key, &data, DB_LAST, NULL)) != 0) + return (ret); + } + + return (0); +} + +/* + * __bam_bulk -- Return bulk data from a btree. + */ +static int +__bam_bulk(dbc, data, flags) + DBC *dbc; + DBT *data; + u_int32_t flags; +{ + BKEYDATA *bk; + BOVERFLOW *bo; + BTREE_CURSOR *cp; + PAGE *pg; + db_indx_t *inp, indx, pg_keyoff; + int32_t *endp, key_off, *offp, *saveoffp; + u_int8_t *dbuf, *dp, *np; + u_int32_t key_size, pagesize, size, space; + int adj, is_key, need_pg, next_key, no_dup, rec_key, ret; + + ret = 0; + key_off = 0; + size = 0; + pagesize = dbc->dbp->pgsize; + cp = (BTREE_CURSOR *)dbc->internal; + + /* + * dp tracks the beginning of the page in the buffer. + * np is the next place to copy things into the buffer. + * dbuf always stays at the beginning of the buffer. + */ + dbuf = data->data; + np = dp = dbuf; + + /* Keep track of space that is left. There is a termination entry */ + space = data->ulen; + space -= sizeof(*offp); + + /* Build the offset/size table from the end up. */ + endp = (int32_t *)((u_int8_t *)dbuf + data->ulen); + endp--; + offp = endp; + + key_size = 0; + + /* + * Distinguish between BTREE and RECNO. + * There are no keys in RECNO. If MULTIPLE_KEY is specified + * then we return the record numbers. + * is_key indicates that multiple btree keys are returned. + * rec_key is set if we are returning record numbers. + * next_key is set if we are going after the next key rather than dup. + */ + if (dbc->dbtype == DB_BTREE) { + is_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1: 0; + rec_key = 0; + next_key = is_key && LF_ISSET(DB_OPFLAGS_MASK) != DB_NEXT_DUP; + adj = 2; + } else { + is_key = 0; + rec_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1 : 0; + next_key = LF_ISSET(DB_OPFLAGS_MASK) != DB_NEXT_DUP; + adj = 1; + } + no_dup = LF_ISSET(DB_OPFLAGS_MASK) == DB_NEXT_NODUP; + +next_pg: + indx = cp->indx; + pg = cp->page; + + inp = P_INP(dbc->dbp, pg); + /* The current page is not yet in the buffer. */ + need_pg = 1; + + /* + * Keep track of the offset of the current key on the page. + * If we are returning keys, set it to 0 first so we force + * the copy of the key to the buffer. + */ + pg_keyoff = 0; + if (is_key == 0) + pg_keyoff = inp[indx]; + + do { + if (IS_DELETED(dbc->dbp, pg, indx)) { + if (dbc->dbtype != DB_RECNO) + continue; + + cp->recno++; + /* + * If we are not returning recnos then we + * need to fill in every slot so the user + * can calculate the record numbers. + */ + if (rec_key != 0) + continue; + + space -= 2 * sizeof(*offp); + /* Check if space as underflowed. */ + if (space > data->ulen) + goto back_up; + + /* Just mark the empty recno slots. */ + *offp-- = 0; + *offp-- = 0; + continue; + } + + /* + * Check to see if we have a new key. + * If so, then see if we need to put the + * key on the page. If its already there + * then we just point to it. + */ + if (is_key && pg_keyoff != inp[indx]) { + bk = GET_BKEYDATA(dbc->dbp, pg, indx); + if (B_TYPE(bk->type) == B_OVERFLOW) { + bo = (BOVERFLOW *)bk; + size = key_size = bo->tlen; + if (key_size > space) + goto get_key_space; + if ((ret = __bam_bulk_overflow(dbc, + bo->tlen, bo->pgno, np)) != 0) + return (ret); + space -= key_size; + key_off = (int32_t)(np - dbuf); + np += key_size; + } else { + if (need_pg) { + dp = np; + size = pagesize - HOFFSET(pg); + if (space < size) { +get_key_space: + /* Nothing added, then error. */ + if (offp == endp) { + data->size = (u_int32_t) + DB_ALIGN(size + + pagesize, 1024); + return + (DB_BUFFER_SMALL); + } + /* + * We need to back up to the + * last record put into the + * buffer so that it is + * CURRENT. + */ + if (indx != 0) + indx -= P_INDX; + else { + if ((ret = + __bam_get_prev( + dbc)) != 0) + return (ret); + indx = cp->indx; + pg = cp->page; + } + break; + } + /* + * Move the data part of the page + * to the buffer. + */ + memcpy(dp, + (u_int8_t *)pg + HOFFSET(pg), size); + need_pg = 0; + space -= size; + np += size; + } + key_size = bk->len; + key_off = (int32_t)((inp[indx] - HOFFSET(pg)) + + (dp - dbuf) + SSZA(BKEYDATA, data)); + pg_keyoff = inp[indx]; + } + } + + /* + * Reserve space for the pointers and sizes. + * Either key/data pair or just for a data item. + */ + space -= (is_key ? 4 : 2) * sizeof(*offp); + if (rec_key) + space -= sizeof(*offp); + + /* Check to see if space has underflowed. */ + if (space > data->ulen) + goto back_up; + + /* + * Determine if the next record is in the + * buffer already or if it needs to be copied in. + * If we have an off page dup, then copy as many + * as will fit into the buffer. + */ + bk = GET_BKEYDATA(dbc->dbp, pg, indx + adj - 1); + if (B_TYPE(bk->type) == B_DUPLICATE) { + bo = (BOVERFLOW *)bk; + if (is_key) { + *offp-- = (int32_t)key_off; + *offp-- = (int32_t)key_size; + } + /* + * We pass the offset of the current key. + * On return we check to see if offp has + * moved to see if any data fit. + */ + saveoffp = offp; + if ((ret = __bam_bulk_duplicates(dbc, bo->pgno, + dbuf, is_key ? offp + P_INDX : NULL, + &offp, &np, &space, no_dup)) != 0) { + if (ret == DB_BUFFER_SMALL) { + size = space; + space = 0; + /* If nothing was added, then error. */ + if (offp == saveoffp) { + offp += 2; + goto back_up; + } + goto get_space; + } + return (ret); + } + } else if (B_TYPE(bk->type) == B_OVERFLOW) { + bo = (BOVERFLOW *)bk; + size = bo->tlen; + if (size > space) + goto back_up; + if ((ret = + __bam_bulk_overflow(dbc, + bo->tlen, bo->pgno, np)) != 0) + return (ret); + space -= size; + if (is_key) { + *offp-- = (int32_t)key_off; + *offp-- = (int32_t)key_size; + } else if (rec_key) + *offp-- = (int32_t)cp->recno; + *offp-- = (int32_t)(np - dbuf); + np += size; + *offp-- = (int32_t)size; + } else { + if (need_pg) { + dp = np; + size = pagesize - HOFFSET(pg); + if (space < size) { +back_up: + /* + * Back up the index so that the + * last record in the buffer is CURRENT + */ + if (indx >= adj) + indx -= adj; + else { + if ((ret = + __bam_get_prev(dbc)) != 0 && + ret != DB_NOTFOUND) + return (ret); + indx = cp->indx; + pg = cp->page; + } + if (dbc->dbtype == DB_RECNO) + cp->recno--; +get_space: + /* + * See if we put anything in the + * buffer or if we are doing a DBP->get + * did we get all of the data. + */ + if (offp >= + (is_key ? &endp[-1] : endp) || + F_ISSET(dbc, DBC_FROM_DB_GET)) { + data->size = (u_int32_t) + DB_ALIGN(size + + data->ulen - space, 1024); + return (DB_BUFFER_SMALL); + } + break; + } + memcpy(dp, (u_int8_t *)pg + HOFFSET(pg), size); + need_pg = 0; + space -= size; + np += size; + } + /* + * Add the offsets and sizes to the end of the buffer. + * First add the key info then the data info. + */ + if (is_key) { + *offp-- = (int32_t)key_off; + *offp-- = (int32_t)key_size; + } else if (rec_key) + *offp-- = (int32_t)cp->recno; + *offp-- = (int32_t)((inp[indx + adj - 1] - HOFFSET(pg)) + + (dp - dbuf) + SSZA(BKEYDATA, data)); + *offp-- = bk->len; + } + if (dbc->dbtype == DB_RECNO) + cp->recno++; + else if (no_dup) { + while (indx + adj < NUM_ENT(pg) && + pg_keyoff == inp[indx + adj]) + indx += adj; + } + /* + * Stop when we either run off the page or we move to the next key and + * we are not returning multiple keys. + */ + } while ((indx += adj) < NUM_ENT(pg) && + (next_key || pg_keyoff == inp[indx])); + + /* If we are off the page then try to the next page. */ + if (ret == 0 && next_key && indx >= NUM_ENT(pg)) { + cp->indx = indx; + ret = __bamc_next(dbc, 0, 1); + if (ret == 0) + goto next_pg; + if (ret != DB_NOTFOUND) + return (ret); + } + + /* + * If we did a DBP->get we must error if we did not return + * all the data for the current key because there is + * no way to know if we did not get it all, nor any + * interface to fetch the balance. + */ + + if (ret == 0 && indx < pg->entries && + F_ISSET(dbc, DBC_TRANSIENT) && pg_keyoff == inp[indx]) { + data->size = (data->ulen - space) + size; + return (DB_BUFFER_SMALL); + } + /* + * Must leave the index pointing at the last record fetched. + * If we are not fetching keys, we may have stepped to the + * next key. + */ + if (ret == DB_BUFFER_SMALL || next_key || pg_keyoff == inp[indx]) + cp->indx = indx; + else + cp->indx = indx - P_INDX; + + if (rec_key == 1) + *offp = RECNO_OOB; + else + *offp = -1; + return (0); +} + +/* + * __bam_bulk_overflow -- + * Dump overflow record into the buffer. + * The space requirements have already been checked. + * PUBLIC: int __bam_bulk_overflow + * PUBLIC: __P((DBC *, u_int32_t, db_pgno_t, u_int8_t *)); + */ +int +__bam_bulk_overflow(dbc, len, pgno, dp) + DBC *dbc; + u_int32_t len; + db_pgno_t pgno; + u_int8_t *dp; +{ + DBT dbt; + + memset(&dbt, 0, sizeof(dbt)); + F_SET(&dbt, DB_DBT_USERMEM); + dbt.ulen = len; + dbt.data = (void *)dp; + return (__db_goff(dbc, &dbt, len, pgno, NULL, NULL)); +} + +/* + * __bam_bulk_duplicates -- + * Put as many off page duplicates as will fit into the buffer. + * This routine will adjust the cursor to reflect the position in + * the overflow tree. + * PUBLIC: int __bam_bulk_duplicates __P((DBC *, + * PUBLIC: db_pgno_t, u_int8_t *, int32_t *, + * PUBLIC: int32_t **, u_int8_t **, u_int32_t *, int)); + */ +int +__bam_bulk_duplicates(dbc, pgno, dbuf, keyoff, offpp, dpp, spacep, no_dup) + DBC *dbc; + db_pgno_t pgno; + u_int8_t *dbuf; + int32_t *keyoff, **offpp; + u_int8_t **dpp; + u_int32_t *spacep; + int no_dup; +{ + BKEYDATA *bk; + BOVERFLOW *bo; + BTREE_CURSOR *cp; + DB *dbp; + DBC *opd; + DBT key, data; + PAGE *pg; + db_indx_t indx, *inp; + int32_t *offp; + u_int32_t pagesize, size, space; + u_int8_t *dp, *np; + int first, need_pg, ret, t_ret; + + ret = 0; + + dbp = dbc->dbp; + cp = (BTREE_CURSOR *)dbc->internal; + opd = cp->opd; + + if (opd == NULL) { + if ((ret = __dbc_newopd(dbc, pgno, NULL, &opd)) != 0) + return (ret); + cp->opd = opd; + if ((ret = opd->am_get(opd, + &key, &data, DB_FIRST, NULL)) != 0) + goto close_opd; + } + + pagesize = opd->dbp->pgsize; + cp = (BTREE_CURSOR *)opd->internal; + space = *spacep; + /* Get current offset slot. */ + offp = *offpp; + + /* + * np is the next place to put data. + * dp is the beginning of the current page in the buffer. + */ + np = dp = *dpp; + first = 1; + indx = cp->indx; + + do { + /* Fetch the current record. No initial move. */ + if ((ret = __bamc_next(opd, 0, 0)) != 0) + break; + pg = cp->page; + indx = cp->indx; + inp = P_INP(dbp, pg); + /* We need to copy the page to the buffer. */ + need_pg = 1; + + do { + if (IS_DELETED(dbp, pg, indx)) + goto contin; + bk = GET_BKEYDATA(dbp, pg, indx); + space -= 2 * sizeof(*offp); + /* Allocate space for key if needed. */ + if (first == 0 && keyoff != NULL) + space -= 2 * sizeof(*offp); + + /* Did space underflow? */ + if (space > *spacep) { + ret = DB_BUFFER_SMALL; + if (first == 1) { + /* Get the absolute value. */ + space = -(int32_t)space; + space = *spacep + space; + if (need_pg) + space += pagesize - HOFFSET(pg); + } + break; + } + if (B_TYPE(bk->type) == B_OVERFLOW) { + bo = (BOVERFLOW *)bk; + size = bo->tlen; + if (size > space) { + ret = DB_BUFFER_SMALL; + space = *spacep + size; + break; + } + if (first == 0 && keyoff != NULL) { + *offp-- = keyoff[0]; + *offp-- = keyoff[-1]; + } + if ((ret = __bam_bulk_overflow(dbc, + bo->tlen, bo->pgno, np)) != 0) + return (ret); + space -= size; + *offp-- = (int32_t)(np - dbuf); + np += size; + } else { + if (need_pg) { + dp = np; + size = pagesize - HOFFSET(pg); + if (space < size) { + ret = DB_BUFFER_SMALL; + /* Return space required. */ + space = *spacep + size; + break; + } + memcpy(dp, + (u_int8_t *)pg + HOFFSET(pg), size); + need_pg = 0; + space -= size; + np += size; + } + if (first == 0 && keyoff != NULL) { + *offp-- = keyoff[0]; + *offp-- = keyoff[-1]; + } + size = bk->len; + *offp-- = (int32_t)((inp[indx] - HOFFSET(pg)) + + (dp - dbuf) + SSZA(BKEYDATA, data)); + } + *offp-- = (int32_t)size; + first = 0; + if (no_dup) + break; +contin: + indx++; + if (opd->dbtype == DB_RECNO) + cp->recno++; + } while (indx < NUM_ENT(pg)); + if (no_dup) + break; + cp->indx = indx; + + } while (ret == 0); + + /* Return the updated information. */ + *spacep = space; + *offpp = offp; + *dpp = np; + + /* + * If we ran out of space back up the pointer. + * If we did not return any dups or reached the end, close the opd. + */ + if (ret == DB_BUFFER_SMALL) { + if (opd->dbtype == DB_RECNO) { + if (--cp->recno == 0) + goto close_opd; + } else if (indx != 0) + cp->indx--; + else { + t_ret = __bamc_prev(opd); + if (t_ret == DB_NOTFOUND) + goto close_opd; + if (t_ret != 0) + ret = t_ret; + } + } else if (keyoff == NULL && ret == DB_NOTFOUND) { + cp->indx--; + if (opd->dbtype == DB_RECNO) + --cp->recno; + } else if (indx == 0 || ret == DB_NOTFOUND) { +close_opd: + if (ret == DB_NOTFOUND) + ret = 0; + if ((t_ret = __dbc_close(opd)) != 0 && ret == 0) + ret = t_ret; + ((BTREE_CURSOR *)dbc->internal)->opd = NULL; + } + if (ret == DB_NOTFOUND) + ret = 0; + + return (ret); +} + +/* + * __bam_getbothc -- + * Search for a matching data item on a join. + */ +static int +__bam_getbothc(dbc, data) + DBC *dbc; + DBT *data; +{ + BTREE_CURSOR *cp; + DB *dbp; + DB_MPOOLFILE *mpf; + int cmp, exact, ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + + /* + * Acquire the current page. We have at least a read-lock + * already. The caller may have set DB_RMW asking for a + * write lock, but upgrading to a write lock has no better + * chance of succeeding now instead of later, so don't try. + */ + if ((ret = __memp_fget(mpf, &cp->pgno, + dbc->thread_info, dbc->txn, 0, &cp->page)) != 0) + return (ret); + + /* + * An off-page duplicate cursor. Search the remaining duplicates + * for one which matches (do a normal btree search, then verify + * that the retrieved record is greater than the original one). + */ + if (F_ISSET(dbc, DBC_OPD)) { + /* + * Check to make sure the desired item comes strictly after + * the current position; if it doesn't, return DB_NOTFOUND. + */ + if ((ret = __bam_cmp(dbc, data, cp->page, cp->indx, + dbp->dup_compare == NULL ? __bam_defcmp : dbp->dup_compare, + &cmp)) != 0) + return (ret); + + if (cmp <= 0) + return (DB_NOTFOUND); + + /* Discard the current page, we're going to do a full search. */ + if ((ret = __memp_fput(mpf, + dbc->thread_info, cp->page, dbc->priority)) != 0) + return (ret); + cp->page = NULL; + + return (__bamc_search(dbc, + PGNO_INVALID, data, DB_GET_BOTH, &exact)); + } + + /* + * We're doing a DBC->get(DB_GET_BOTHC) and we're already searching + * a set of on-page duplicates (either sorted or unsorted). Continue + * a linear search from after the current position. + * + * (Note that we could have just finished a "set" of one duplicate, + * i.e. not a duplicate at all, but the following check will always + * return DB_NOTFOUND in this case, which is the desired behavior.) + */ + if (cp->indx + P_INDX >= NUM_ENT(cp->page) || + !IS_DUPLICATE(dbc, cp->indx, cp->indx + P_INDX)) + return (DB_NOTFOUND); + cp->indx += P_INDX; + + return (__bam_getboth_finddatum(dbc, data, DB_GET_BOTH)); +} + +#ifdef HAVE_COMPRESSION +/* + * __bam_getlte -- + * Search for the largest entry <= key/data - used by compression. + * + * data == NULL indicates the DB_SET_LTE flag + * data != NULL indicates the DB_GET_BOTH_LTE flag + * + * Only works for a primary cursor - not an OPD cursor. Handles the + * OPD manipulation as well - no need to return to the caller to + * perform more OPD movements. + */ +static int +__bam_getlte(dbc, key, data) + DBC *dbc; + DBT *key, *data; +{ + BTREE_CURSOR *cp, *ocp; + DB *dbp; + db_pgno_t pgno; + int exact, ret; + + dbp = dbc->dbp; + cp = (BTREE_CURSOR *)dbc->internal; + + /* Begin by searching for the key */ + ret = __bamc_search(dbc, PGNO_INVALID, key, DB_SET_RANGE, &exact); + if (ret == DB_NOTFOUND) + goto find_last; + if (ret != 0) + goto end; + + if (cp->indx == NUM_ENT(cp->page) || IS_CUR_DELETED(dbc)) { + /* + * Move to the next entry if we're past the end of the + * page or on a deleted entry. + */ + ret = __bamc_next(dbc, 0, 0); + if (ret == DB_NOTFOUND) + goto find_last; + if (ret != 0) + goto end; + + /* Check if we're still on the correct key */ + if ((ret = __bam_cmp(dbc, key, cp->page, cp->indx, + ((BTREE*)dbp->bt_internal)->bt_compare, &exact)) != 0) + goto end; + exact = (exact == 0); + } + + if (exact == 0) { + ret = __bam_get_prev(dbc); + goto end; + } + + if (__bam_isopd(dbc, &pgno)) { + /* + * We want to do unusual things with off-page duplicates, so + * deal with them here rather than returning to handle them. + */ + if ((ret = __dbc_newopd(dbc, pgno, cp->opd, &cp->opd)) != 0) + goto end; + + /* Search for the correct duplicate */ + ret = __bamc_search(cp->opd, PGNO_INVALID, data, + data == NULL ? DB_FIRST : DB_SET_RANGE, &exact); + if (ret == DB_NOTFOUND) + goto find_last_dup; + if (ret != 0) + goto end; + + ocp = (BTREE_CURSOR *)cp->opd->internal; + if (ocp->indx == NUM_ENT(ocp->page) || + IS_CUR_DELETED(cp->opd)) { + /* + * Move to the next entry if we're past the end of the + * page or on a deleted entry. + */ + ret = __bamc_next(cp->opd, 0, 0); + if (ret == DB_NOTFOUND) + goto find_last_dup; + if (ret != 0) + goto end; + + if (data != NULL) { + /* Check if we're still on the correct data */ + if ((ret = __bam_cmp( + dbc, data, ocp->page, ocp->indx, + dbp->dup_compare, &exact)) != 0) + goto end; + exact = (exact == 0); + } else + exact = 1; + } + + if (exact == 0) { + /* Move to the previous entry */ + ret = __bamc_prev(cp->opd); + if (ret == DB_NOTFOUND) { + if ((ret = __dbc_close(cp->opd)) != 0) + goto end; + cp->opd = NULL; + ret = __bam_get_prev(dbc); + } + } + } else if(data != NULL) { + /* + * If we got an exact match with on-page duplicates, we need to + * search in them. + */ + ret = __bam_getboth_finddatum(dbc, data, DB_GET_BOTH_RANGE); + if (ret == DB_NOTFOUND) + exact = 0; + else if (ret != 0) + goto end; + else { + /* Check if we're still on the correct data */ + if ((ret = __bam_cmp(dbc, data, cp->page, + cp->indx + O_INDX, dbp->dup_compare, &exact)) != 0) + goto end; + exact = (exact == 0); + } + + if (exact == 0) { + ret = __bam_get_prev(dbc); + } + } + + end: + return (ret); + + find_last: + if ((ret = __bamc_search( + dbc, PGNO_INVALID, NULL, DB_LAST, &exact)) != 0) + return (ret); + + if (__bam_isopd(dbc, &pgno)) { + if ((ret = __dbc_newopd(dbc, pgno, cp->opd, &cp->opd)) != 0) + return (ret); + find_last_dup: + if ((ret = __bamc_search( + cp->opd, PGNO_INVALID, NULL, DB_LAST, &exact)) != 0) + return (ret); + } + + return (ret); +} +#endif + +/* + * __bam_getboth_finddatum -- + * Find a matching on-page data item. + */ +static int +__bam_getboth_finddatum(dbc, data, flags) + DBC *dbc; + DBT *data; + u_int32_t flags; +{ + BTREE_CURSOR *cp; + DB *dbp; + db_indx_t base, lim, top; + int cmp, ret; + + COMPQUIET(cmp, 0); + + dbp = dbc->dbp; + cp = (BTREE_CURSOR *)dbc->internal; + + /* + * Called (sometimes indirectly) from DBC->get to search on-page data + * item(s) for a matching value. If the original flag was DB_GET_BOTH + * or DB_GET_BOTH_RANGE, the cursor is set to the first undeleted data + * item for the key. If the original flag was DB_GET_BOTHC, the cursor + * argument is set to the first data item we can potentially return. + * In both cases, there may or may not be additional duplicate data + * items to search. + * + * If the duplicates are not sorted, do a linear search. + */ + if (dbp->dup_compare == NULL) { + for (;; cp->indx += P_INDX) { + if (!IS_CUR_DELETED(dbc) && + (ret = __bam_cmp(dbc, data, cp->page, + cp->indx + O_INDX, __bam_defcmp, &cmp)) != 0) + return (ret); + if (cmp == 0) + return (0); + + if (cp->indx + P_INDX >= NUM_ENT(cp->page) || + !IS_DUPLICATE(dbc, cp->indx, cp->indx + P_INDX)) + break; + } + return (DB_NOTFOUND); + } + + /* + * If the duplicates are sorted, do a binary search. The reason for + * this is that large pages and small key/data pairs result in large + * numbers of on-page duplicates before they get pushed off-page. + * + * Find the top and bottom of the duplicate set. Binary search + * requires at least two items, don't loop if there's only one. + */ + for (base = top = cp->indx; top < NUM_ENT(cp->page); top += P_INDX) + if (!IS_DUPLICATE(dbc, cp->indx, top)) + break; + if (base == (top - P_INDX)) { + if ((ret = __bam_cmp(dbc, data, cp->page, + cp->indx + O_INDX, dbp->dup_compare, &cmp)) != 0) + return (ret); + if (cmp == 0 || (cmp < 0 && flags == DB_GET_BOTH_RANGE)) + return 0; + cp->indx = top; + return DB_NOTFOUND; + } + + for (lim = (top - base) / (db_indx_t)P_INDX; lim != 0; lim >>= 1) { + cp->indx = base + ((lim >> 1) * P_INDX); + if ((ret = __bam_cmp(dbc, data, cp->page, + cp->indx + O_INDX, dbp->dup_compare, &cmp)) != 0) + return (ret); + if (cmp == 0) { + /* + * XXX + * No duplicate duplicates in sorted duplicate sets, + * so there can be only one. + */ + if (!IS_CUR_DELETED(dbc)) + return (0); + break; + } + if (cmp > 0) { + base = cp->indx + P_INDX; + --lim; + } + } + + /* No match found; if we're looking for an exact match, we're done. */ + if (flags == DB_GET_BOTH) + return (DB_NOTFOUND); + + /* + * Base is the smallest index greater than the data item, may be zero + * or a last + O_INDX index, and may be deleted. Find an undeleted + * item. + */ + cp->indx = base; + while (cp->indx < top && IS_CUR_DELETED(dbc)) + cp->indx += P_INDX; + return (cp->indx < top ? 0 : DB_NOTFOUND); +} + +/* + * __bamc_put -- + * Put using a cursor. + */ +static int +__bamc_put(dbc, key, data, flags, pgnop) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; + db_pgno_t *pgnop; +{ + BTREE *t; + BTREE_CURSOR *cp; + DB *dbp; + DBT dbt; + DB_MPOOLFILE *mpf; + db_pgno_t root_pgno; + int cmp, exact, own, ret, stack; + u_int32_t iiop; + void *arg; + + dbp = dbc->dbp; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + root_pgno = cp->root; + +split: ret = stack = 0; + switch (flags) { + case DB_CURRENT: + if (F_ISSET(cp, C_DELETED)) + return (DB_NOTFOUND); + /* FALLTHROUGH */ + case DB_AFTER: + case DB_BEFORE: + iiop = flags; + own = 1; + + /* Acquire the current page with a write lock. */ + ACQUIRE_WRITE_LOCK(dbc, ret); + if (ret != 0) + goto err; + if (cp->page == NULL && (ret = __memp_fget(mpf, &cp->pgno, + dbc->thread_info, dbc->txn, 0, &cp->page)) != 0) + goto err; + break; + case DB_KEYFIRST: + case DB_KEYLAST: + case DB_NODUPDATA: + case DB_NOOVERWRITE: + case DB_OVERWRITE_DUP: + own = 0; + /* + * Searching off-page, sorted duplicate tree: do a tree search + * for the correct item; __bamc_search returns the smallest + * slot greater than the key, use it. + * + * See comment below regarding where we can start the search. + */ + if (F_ISSET(dbc, DBC_OPD)) { + if ((ret = __bamc_search(dbc, + F_ISSET(cp, C_RECNUM) ? cp->root : root_pgno, + data, flags, &exact)) != 0) + goto err; + stack = 1; + + /* Disallow "sorted" duplicate duplicates. */ + if (exact != 0) { + if (flags == DB_OVERWRITE_DUP || + IS_DELETED(dbp, cp->page, cp->indx)) { + iiop = DB_CURRENT; + break; + } + ret = __db_duperr(dbp, flags); + goto err; + } + iiop = DB_BEFORE; + break; + } + + /* + * Searching a btree. + * + * If we've done a split, we can start the search from the + * parent of the split page, which __bam_split returned + * for us in root_pgno, unless we're in a Btree with record + * numbering. In that case, we'll need the true root page + * in order to adjust the record count. + */ + if ((ret = __bamc_search(dbc, + F_ISSET(cp, C_RECNUM) ? cp->root : root_pgno, key, + flags == DB_KEYFIRST || dbp->dup_compare != NULL ? + DB_KEYFIRST : DB_KEYLAST, &exact)) != 0) + goto err; + stack = 1; + + /* + * If we don't have an exact match, __bamc_search returned + * the smallest slot greater than the key, use it. + */ + if (!exact) { + iiop = DB_KEYFIRST; + break; + + /* + * Check for NOOVERWRITE. It is possible that there + * is a key with an empty duplicate page attached. + */ + } else if (flags == DB_NOOVERWRITE && !IS_CUR_DELETED(dbc)) { + if (pgnop != NULL && __bam_isopd(dbc, pgnop)) + ret = __bam_opd_exists(dbc, *pgnop); + else + ret = DB_KEYEXIST; + if (ret != 0) + goto err; + } + + /* + * If duplicates aren't supported, replace the current item. + */ + if (!F_ISSET(dbp, DB_AM_DUP)) { + iiop = DB_CURRENT; + break; + } + + /* + * If we find a matching entry, it may be an off-page duplicate + * tree. Return the page number to our caller, we need a new + * cursor. + */ + if (pgnop != NULL && __bam_isopd(dbc, pgnop)) + goto done; + + /* If the duplicates aren't sorted, move to the right slot. */ + if (dbp->dup_compare == NULL) { + if (flags == DB_KEYFIRST) + iiop = DB_BEFORE; + else + for (;; cp->indx += P_INDX) + if (cp->indx + P_INDX >= + NUM_ENT(cp->page) || + !IS_DUPLICATE(dbc, cp->indx, + cp->indx + P_INDX)) { + iiop = DB_AFTER; + break; + } + break; + } + + /* + * We know that we're looking at the first of a set of sorted + * on-page duplicates. Walk the list to find the right slot. + */ + for (;; cp->indx += P_INDX) { + if ((ret = __bam_cmp(dbc, data, cp->page, + cp->indx + O_INDX, dbp->dup_compare, &cmp)) != 0) + goto err; + if (cmp < 0) { + iiop = DB_BEFORE; + break; + } + + /* Disallow "sorted" duplicate duplicates. */ + if (cmp == 0) { + if (flags == DB_OVERWRITE_DUP || + IS_DELETED(dbp, cp->page, cp->indx)) { + iiop = DB_CURRENT; + break; + } + ret = __db_duperr(dbp, flags); + goto err; + } + + if (cp->indx + P_INDX >= NUM_ENT(cp->page) || + P_INP(dbp, ((PAGE *)cp->page))[cp->indx] != + P_INP(dbp, ((PAGE *)cp->page))[cp->indx + P_INDX]) { + iiop = DB_AFTER; + break; + } + } + break; + default: + ret = __db_unknown_flag(dbp->env, "__bamc_put", flags); + goto err; + } + + switch (ret = __bam_iitem(dbc, key, data, iiop, 0)) { + case 0: + break; + case DB_NEEDSPLIT: + /* + * To split, we need a key for the page. Either use the key + * argument or get a copy of the key from the page. + */ + if (flags == DB_AFTER || + flags == DB_BEFORE || flags == DB_CURRENT) { + memset(&dbt, 0, sizeof(DBT)); + if ((ret = __db_ret(dbc, cp->page, 0, &dbt, + &dbc->my_rkey.data, &dbc->my_rkey.ulen)) != 0) + goto err; + arg = &dbt; + } else + arg = F_ISSET(dbc, DBC_OPD) ? data : key; + + /* + * Discard any locks and pinned pages (the locks are discarded + * even if we're running with transactions, as they lock pages + * that we're sorry we ever acquired). If stack is set and the + * cursor entries are valid, they point to the same entries as + * the stack, don't free them twice. + */ + if (stack) + ret = __bam_stkrel(dbc, STK_CLRDBC | STK_NOLOCK); + else + DISCARD_CUR(dbc, ret); + if (ret != 0) + goto err; + + /* + * SR [#6059] + * If we do not own a lock on the page any more, then clear the + * cursor so we don't point at it. Even if we call __bam_stkrel + * above we still may have entered the routine with the cursor + * positioned to a particular record. This is in the case + * where C_RECNUM is set. + */ + if (own == 0) { + cp->pgno = PGNO_INVALID; + cp->indx = 0; + } + + /* Split the tree. */ + if ((ret = __bam_split(dbc, arg, &root_pgno)) != 0) + return (ret); + + goto split; + default: + goto err; + } + +err: +done: /* + * If we inserted a key into the first or last slot of the tree, + * remember where it was so we can do it more quickly next time. + * If the tree has record numbers, we need a complete stack so + * that we can adjust the record counts, so skipping the tree search + * isn't possible. For subdatabases we need to be careful that the + * page does not move from one db to another, so we track its LSN. + * + * If there are duplicates and we are inserting into the last slot, + * the cursor will point _to_ the last item, not after it, which + * is why we subtract P_INDX below. + */ + + t = dbp->bt_internal; + if (ret == 0 && TYPE(cp->page) == P_LBTREE && + (flags == DB_KEYFIRST || flags == DB_KEYLAST) && + !F_ISSET(cp, C_RECNUM) && + (!F_ISSET(dbp, DB_AM_SUBDB) || + (LOGGING_ON(dbp->env) && !F_ISSET(dbp, DB_AM_NOT_DURABLE))) && + ((NEXT_PGNO(cp->page) == PGNO_INVALID && + cp->indx >= NUM_ENT(cp->page) - P_INDX) || + (PREV_PGNO(cp->page) == PGNO_INVALID && cp->indx == 0))) { + t->bt_lpgno = cp->pgno; + if (F_ISSET(dbp, DB_AM_SUBDB)) + t->bt_llsn = LSN(cp->page); + } else + t->bt_lpgno = PGNO_INVALID; + /* + * Discard any pages pinned in the tree and their locks, except for + * the leaf page. Note, the leaf page participated in any stack we + * acquired, and so we have to adjust the stack as necessary. If + * there was only a single page on the stack, we don't have to free + * further stack pages. + */ + if (stack && BT_STK_POP(cp) != NULL) + (void)__bam_stkrel(dbc, 0); + + /* + * Regardless of whether we were successful or not, clear the delete + * flag. If we're successful, we either moved the cursor or the item + * is no longer deleted. If we're not successful, then we're just a + * copy, no need to have the flag set. + * + * We may have instantiated off-page duplicate cursors during the put, + * so clear the deleted bit from the off-page duplicate cursor as well. + */ + F_CLR(cp, C_DELETED); + if (cp->opd != NULL) { + cp = (BTREE_CURSOR *)cp->opd->internal; + F_CLR(cp, C_DELETED); + } + + return (ret); +} + +/* + * __bamc_rget -- + * Return the record number for a cursor. + * + * PUBLIC: int __bamc_rget __P((DBC *, DBT *)); + */ +int +__bamc_rget(dbc, data) + DBC *dbc; + DBT *data; +{ + BTREE_CURSOR *cp; + DB *dbp; + DBT dbt; + DB_MPOOLFILE *mpf; + db_recno_t recno; + int exact, ret, t_ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + + /* + * Get the page with the current item on it. + * Get a copy of the key. + * Release the page, making sure we don't release it twice. + */ + if ((ret = __memp_fget(mpf, &cp->pgno, + dbc->thread_info, dbc->txn, 0, &cp->page)) != 0) + return (ret); + memset(&dbt, 0, sizeof(DBT)); + if ((ret = __db_ret(dbc, cp->page, cp->indx, &dbt, + &dbc->my_rkey.data, &dbc->my_rkey.ulen)) != 0) + goto err; + ret = __memp_fput(mpf, dbc->thread_info, cp->page, dbc->priority); + cp->page = NULL; + if (ret != 0) + return (ret); + + if ((ret = __bam_search(dbc, PGNO_INVALID, &dbt, + F_ISSET(dbc, DBC_RMW) ? SR_FIND_WR : SR_FIND, + 1, &recno, &exact)) != 0) + goto err; + + ret = __db_retcopy(dbc->env, data, + &recno, sizeof(recno), &dbc->rdata->data, &dbc->rdata->ulen); + + /* Release the stack. */ +err: if ((t_ret = __bam_stkrel(dbc, 0)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __bamc_writelock -- + * Upgrade the cursor to a write lock. + */ +static int +__bamc_writelock(dbc) + DBC *dbc; +{ + BTREE_CURSOR *cp; + int ret; + + cp = (BTREE_CURSOR *)dbc->internal; + + if (cp->lock_mode == DB_LOCK_WRITE) + return (0); + + /* + * When writing to an off-page duplicate tree, we need to have the + * appropriate page in the primary tree locked. The general DBC + * code calls us first with the primary cursor so we can acquire the + * appropriate lock. + */ + ACQUIRE_WRITE_LOCK(dbc, ret); + return (ret); +} + +/* + * __bamc_next -- + * Move to the next record. + */ +static int +__bamc_next(dbc, initial_move, deleted_okay) + DBC *dbc; + int initial_move, deleted_okay; +{ + BTREE_CURSOR *cp; + db_indx_t adjust; + db_lockmode_t lock_mode; + db_pgno_t pgno; + int ret; + + cp = (BTREE_CURSOR *)dbc->internal; + ret = 0; + + /* + * We're either moving through a page of duplicates or a btree leaf + * page. + * + * !!! + * This code handles empty pages and pages with only deleted entries. + */ + if (F_ISSET(dbc, DBC_OPD)) { + adjust = O_INDX; + lock_mode = DB_LOCK_NG; + } else { + adjust = dbc->dbtype == DB_BTREE ? P_INDX : O_INDX; + lock_mode = + F_ISSET(dbc, DBC_RMW) ? DB_LOCK_WRITE : DB_LOCK_READ; + } + if (cp->page == NULL) { + ACQUIRE_CUR(dbc, lock_mode, cp->pgno, 0, ret); + if (ret != 0) + return (ret); + } + + if (initial_move) + cp->indx += adjust; + + for (;;) { + /* + * If at the end of the page, move to a subsequent page. + * + * !!! + * Check for >= NUM_ENT. If the original search landed us on + * NUM_ENT, we may have incremented indx before the test. + */ + if (cp->indx >= NUM_ENT(cp->page)) { + if ((pgno = NEXT_PGNO(cp->page)) == PGNO_INVALID) + return (DB_NOTFOUND); + + ACQUIRE_CUR(dbc, lock_mode, pgno, 0, ret); + if (ret != 0) + return (ret); + cp->indx = 0; + continue; + } + if (!deleted_okay && IS_CUR_DELETED(dbc)) { + cp->indx += adjust; + continue; + } + break; + } + return (0); +} + +/* + * __bamc_prev -- + * Move to the previous record. + */ +static int +__bamc_prev(dbc) + DBC *dbc; +{ + BTREE_CURSOR *cp; + db_indx_t adjust; + db_lockmode_t lock_mode; + db_pgno_t pgno; + int ret; + + cp = (BTREE_CURSOR *)dbc->internal; + ret = 0; + + /* + * We're either moving through a page of duplicates or a btree leaf + * page. + * + * !!! + * This code handles empty pages and pages with only deleted entries. + */ + if (F_ISSET(dbc, DBC_OPD)) { + adjust = O_INDX; + lock_mode = DB_LOCK_NG; + } else { + adjust = dbc->dbtype == DB_BTREE ? P_INDX : O_INDX; + lock_mode = + F_ISSET(dbc, DBC_RMW) ? DB_LOCK_WRITE : DB_LOCK_READ; + } + if (cp->page == NULL) { + ACQUIRE_CUR(dbc, lock_mode, cp->pgno, 0, ret); + if (ret != 0) + return (ret); + } + + for (;;) { + /* If at the beginning of the page, move to a previous one. */ + if (cp->indx == 0) { + if ((pgno = + PREV_PGNO(cp->page)) == PGNO_INVALID) + return (DB_NOTFOUND); + + ACQUIRE_CUR(dbc, lock_mode, pgno, 0, ret); + if (ret != 0) + return (ret); + + if ((cp->indx = NUM_ENT(cp->page)) == 0) + continue; + } + + /* Ignore deleted records. */ + cp->indx -= adjust; + if (IS_CUR_DELETED(dbc)) + continue; + + break; + } + return (0); +} + +/* + * __bamc_search -- + * Move to a specified record. + */ +static int +__bamc_search(dbc, root_pgno, key, flags, exactp) + DBC *dbc; + db_pgno_t root_pgno; + const DBT *key; + u_int32_t flags; + int *exactp; +{ + BTREE *t; + BTREE_CURSOR *cp; + DB *dbp; + PAGE *h; + db_indx_t base, indx, *inp, lim; + db_pgno_t bt_lpgno; + db_recno_t recno; + u_int32_t sflags; + int bulk, cmp, ret, t_ret; + + COMPQUIET(cmp, 0); + dbp = dbc->dbp; + cp = (BTREE_CURSOR *)dbc->internal; + t = dbp->bt_internal; + ret = 0; + bulk = (F_ISSET(dbc, DBC_BULK) && cp->pgno != PGNO_INVALID); + + /* + * Find an entry in the database. Discard any lock we currently hold, + * we're going to search the tree. + */ + DISCARD_CUR(dbc, ret); + if (ret != 0) + return (ret); + + switch (flags) { + case DB_FIRST: + sflags = (F_ISSET(dbc, DBC_RMW) ? SR_WRITE : SR_READ) | SR_MIN; + goto search; + case DB_LAST: + sflags = (F_ISSET(dbc, DBC_RMW) ? SR_WRITE : SR_READ) | SR_MAX; + goto search; + case DB_SET_RECNO: + if ((ret = __ram_getno(dbc, key, &recno, 0)) != 0) + return (ret); + sflags = + (F_ISSET(dbc, DBC_RMW) ? SR_FIND_WR : SR_FIND) | SR_EXACT; + if ((ret = __bam_rsearch(dbc, &recno, sflags, 1, exactp)) != 0) + return (ret); + goto done; + case DB_SET: + case DB_GET_BOTH: + sflags = + (F_ISSET(dbc, DBC_RMW) ? SR_FIND_WR : SR_FIND) | SR_EXACT; + if (bulk) + break; + goto search; + case DB_GET_BOTH_RANGE: + sflags = (F_ISSET(dbc, DBC_RMW) ? SR_FIND_WR : SR_FIND); + goto search; + case DB_SET_RANGE: + sflags = + (F_ISSET(dbc, DBC_RMW) ? SR_WRITE : SR_READ) | SR_DUPFIRST; + goto search; + case DB_KEYFIRST: + case DB_NOOVERWRITE: + sflags = SR_KEYFIRST; + break; + case DB_KEYLAST: + case DB_NODUPDATA: + case DB_OVERWRITE_DUP: + sflags = SR_KEYLAST; + break; + default: + return (__db_unknown_flag(dbp->env, "__bamc_search", flags)); + } + + /* + * If the application has a history of inserting into the first or last + * pages of the database, we check those pages first to avoid doing a + * full search. Similarly, if the cursor is configured as a bulk + * cursor, check whether this operation belongs on the same page as the + * last one. + */ + if (bulk) + bt_lpgno = cp->pgno; + else { + if (F_ISSET(dbc, DBC_OPD)) + goto search; + + /* + * !!! + * We do not mutex protect the t->bt_lpgno field, which means + * that it can only be used in an advisory manner. If we find + * page we can use, great. If we don't, we don't care, we do + * it the slow way instead. Regardless, copy it into a local + * variable, otherwise we might acquire a lock for a page and + * then read a different page because it changed underfoot. + */ + bt_lpgno = t->bt_lpgno; + } + + /* + * If the tree has no history of insertion, do it the slow way. + */ + if (bt_lpgno == PGNO_INVALID) + goto search; + + /* + * Lock and retrieve the page on which we last inserted. + * + * The page may not exist: if a transaction created the page + * and then aborted, the page might have been truncated from + * the end of the file. We don't want to wait on the lock. + * The page may not even be relevant to this search. + */ + h = NULL; + ACQUIRE_CUR(dbc, DB_LOCK_WRITE, bt_lpgno, DB_LOCK_NOWAIT, ret); + if (ret != 0) { + if (ret == DB_LOCK_DEADLOCK || + ret == DB_LOCK_NOTGRANTED || + ret == DB_PAGE_NOTFOUND) + ret = 0; + goto fast_miss; + } + + h = cp->page; + inp = P_INP(dbp, h); + + /* + * It's okay if the page type isn't right or it's empty, it + * just means that the world changed. + */ + if (TYPE(h) != P_LBTREE || NUM_ENT(h) == 0) + goto fast_miss; + + /* Verify that this page cannot have moved to another db. */ + if (F_ISSET(dbp, DB_AM_SUBDB) && + LOG_COMPARE(&t->bt_llsn, &LSN(h)) != 0) + goto fast_miss; + + /* + * What we do here is test to see if we're at the beginning or + * end of the tree and if the new item sorts before/after the + * first/last page entry. We only try to catch inserts into + * the middle of the tree for bulk cursors. + */ + if (h->next_pgno == PGNO_INVALID) { + indx = NUM_ENT(h) - P_INDX; + if ((ret = __bam_cmp(dbc, key, h, indx, + t->bt_compare, &cmp)) != 0) + goto fast_miss; + if (cmp > 0) + indx += P_INDX; + if (cmp >= 0) + goto fast_hit; + } + if (h->prev_pgno == PGNO_INVALID) { + indx = 0; + if ((ret = __bam_cmp(dbc, key, h, indx, + t->bt_compare, &cmp)) != 0) + goto fast_miss; + if (cmp <= 0) + goto fast_hit; + } + if (bulk) { + DB_BINARY_SEARCH_FOR(base, lim, NUM_ENT(h), P_INDX) { + DB_BINARY_SEARCH_INCR(indx, base, lim, P_INDX); + if ((ret = __bam_cmp(dbc, key, h, indx, + t->bt_compare, &cmp)) != 0) + goto fast_miss; + + if (cmp == 0) + goto fast_hit; + if (cmp > 0) + DB_BINARY_SEARCH_SHIFT_BASE(indx, base, + lim, P_INDX); + } + /* + * No match found: base is the smallest index greater than + * the key and may be zero or NUM_ENT(h). + */ + indx = base; + if (indx > 0 && indx < NUM_ENT(h)) { + if (FLD_ISSET(sflags, SR_EXACT)) + return (DB_NOTFOUND); + goto fast_hit; + } + } + goto fast_miss; + +fast_hit: + if (cmp == 0) { + /* + * Found a duplicate. Deal with DB_KEYFIRST / DB_KEYLAST. + */ + if (FLD_ISSET(sflags, SR_DUPFIRST)) + while (indx > 0 && inp[indx - P_INDX] == inp[indx]) + indx -= P_INDX; + else if (FLD_ISSET(sflags, SR_DUPLAST)) + while (indx < (db_indx_t)(NUM_ENT(h) - P_INDX) && + inp[indx] == inp[indx + P_INDX]) + indx += P_INDX; + } + + /* Set the exact match flag, we may have found a duplicate. */ + *exactp = (cmp == 0); + + /* + * Insert the entry in the stack. (Our caller is likely to + * call __bam_stkrel() after our return.) + */ + BT_STK_CLR(cp); + BT_STK_ENTER(dbp->env, + cp, h, indx, cp->lock, cp->lock_mode, ret); + if (ret != 0) + return (ret); + goto done; + +fast_miss: + /* + * This was not the right page, so we do not need to retain + * the lock even in the presence of transactions. + * + * This is also an error path, so ret may have been set. + */ + DISCARD_CUR(dbc, ret); + cp->pgno = PGNO_INVALID; + if ((t_ret = __LPUT(dbc, cp->lock)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + return (ret); + +search: + if ((ret = __bam_search(dbc, root_pgno, + key, sflags, 1, NULL, exactp)) != 0) + return (ret); + +done: /* Initialize the cursor from the stack. */ + cp->page = cp->csp->page; + cp->pgno = cp->csp->page->pgno; + cp->indx = cp->csp->indx; + cp->lock = cp->csp->lock; + cp->lock_mode = cp->csp->lock_mode; + + /* If on an empty page or a deleted record, move to the next one. */ + if (flags == DB_FIRST && + (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc))) + if ((ret = __bamc_next(dbc, 0, 0)) != 0) + return (ret); + if (flags == DB_LAST && + (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc))) + if ((ret = __bamc_prev(dbc)) != 0) + return (ret); + + return (0); +} + +/* + * __bamc_physdel -- + * Physically remove an item from the page. + */ +static int +__bamc_physdel(dbc) + DBC *dbc; +{ + BTREE_CURSOR *cp; + DB *dbp; + DBT key; + DB_LOCK next_lock, prev_lock; + db_pgno_t pgno; + int delete_page, empty_page, exact, ret; + + dbp = dbc->dbp; + memset(&key, 0, sizeof(DBT)); + cp = (BTREE_CURSOR *)dbc->internal; + delete_page = empty_page = ret = 0; + LOCK_INIT(next_lock); + LOCK_INIT(prev_lock); + + /* If the page is going to be emptied, consider deleting it. */ + delete_page = empty_page = + NUM_ENT(cp->page) == (TYPE(cp->page) == P_LBTREE ? 2 : 1); + + /* + * Check if the application turned off reverse splits. Applications + * can't turn off reverse splits in off-page duplicate trees, that + * space will never be reused unless the exact same key is specified. + */ + if (delete_page && + !F_ISSET(dbc, DBC_OPD) && F_ISSET(dbp, DB_AM_REVSPLITOFF)) + delete_page = 0; + + /* + * We never delete the last leaf page. (Not really true -- we delete + * the last leaf page of off-page duplicate trees, but that's handled + * by our caller, not down here.) + */ + if (delete_page && cp->pgno == cp->root) + delete_page = 0; + + /* + * To delete a leaf page other than an empty root page, we need a + * copy of a key from the page. Use the 0th page index since it's + * the last key the page held. + * + * !!! + * Note that because __bamc_physdel is always called from a cursor + * close, it should be safe to use the cursor's own "my_rkey" memory + * to temporarily hold this key. We shouldn't own any returned-data + * memory of interest--if we do, we're in trouble anyway. + */ + if (delete_page) { + if ((ret = __db_ret(dbc, cp->page, 0, &key, + &dbc->my_rkey.data, &dbc->my_rkey.ulen)) != 0) + return (ret); + } + + /* + * Delete the items. If page isn't empty, we adjust the cursors. + * + * !!! + * The following operations to delete a page may deadlock. The easy + * scenario is if we're deleting an item because we're closing cursors + * because we've already deadlocked and want to call txn->abort. If + * we fail due to deadlock, we'll leave a locked, possibly empty page + * in the tree, which won't be empty long because we'll undo the delete + * when we undo the transaction's modifications. + * + * !!! + * Delete the key item first, otherwise the on-page duplicate checks + * in __bam_ditem() won't work! + */ + if ((ret = __memp_dirty(dbp->mpf, + &cp->page, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + return (ret); + if (TYPE(cp->page) == P_LBTREE) { + if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0) + return (ret); + if (!empty_page) + if ((ret = __bam_ca_di(dbc, + PGNO(cp->page), cp->indx, -1)) != 0) + return (ret); + } + if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0) + return (ret); + + /* Clear the deleted flag, the item is gone. */ + F_CLR(cp, C_DELETED); + + if (!empty_page) + if ((ret = __bam_ca_di(dbc, PGNO(cp->page), cp->indx, -1)) != 0) + return (ret); + + /* + * Need to downgrade write locks here or non-txn locks will get stuck. + */ + if (F_ISSET(dbc->dbp, DB_AM_READ_UNCOMMITTED)) { + if ((ret = __TLPUT(dbc, cp->lock)) != 0) + return (ret); + cp->lock_mode = DB_LOCK_WWRITE; + if (cp->page != NULL && + (ret = __memp_shared(dbp->mpf, cp->page)) != 0) + return (ret); + } + /* If we're not going to try and delete the page, we're done. */ + if (!delete_page) + return (0); + + /* + * Lock the previous and next pages before latching the parent + * sub tree. + */ + if (STD_LOCKING(dbc)) { + if ((pgno = PREV_PGNO(cp->page)) != PGNO_INVALID && + (ret = __db_lget(dbc, + 0, pgno, DB_LOCK_WRITE, 0, &prev_lock)) != 0) + return (ret); + if ((pgno = NEXT_PGNO(cp->page)) != PGNO_INVALID && + (ret = __db_lget(dbc, + 0, pgno, DB_LOCK_WRITE, 0, &next_lock)) != 0) { + (void)__TLPUT(dbc, next_lock); + return (ret); + } + } + DISCARD_CUR(dbc, ret); + if (ret != 0) + goto err; + ret = __bam_search(dbc, PGNO_INVALID, &key, SR_DEL, 0, NULL, &exact); + + /* + * If everything worked, delete the stack, otherwise, release the + * stack and page locks without further damage. + */ + if (ret == 0) + ret = __bam_dpages(dbc, 1, BTD_RELINK); + else + (void)__bam_stkrel(dbc, 0); + +err: (void)__TLPUT(dbc, prev_lock); + (void)__TLPUT(dbc, next_lock); + return (ret); +} + +/* + * __bamc_getstack -- + * Acquire a full stack for a cursor. + */ +static int +__bamc_getstack(dbc) + DBC *dbc; +{ + BTREE_CURSOR *cp; + DB *dbp; + DBT dbt; + DB_MPOOLFILE *mpf; + PAGE *h; + int exact, ret, t_ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + + /* + * Get the page with the current item on it. The caller of this + * routine has to already hold a read lock on the page, so there + * is no additional lock to acquire. + */ + if ((ret = __memp_fget(mpf, &cp->pgno, + dbc->thread_info, dbc->txn, 0, &h)) != 0) + return (ret); + + /* Get a copy of a key from the page. */ + memset(&dbt, 0, sizeof(DBT)); + ret = __db_ret(dbc, h, 0, &dbt, + &dbc->my_rkey.data, &dbc->my_rkey.ulen); + if ((t_ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + return (ret); + + /* Get a write-locked stack for the page. */ + exact = 0; + ret = __bam_search(dbc, PGNO_INVALID, + &dbt, SR_KEYFIRST, 1, NULL, &exact); + + return (ret); +} + +/* + * __bam_isopd -- + * Return if the cursor references an off-page duplicate tree via its + * page number. + */ +static int +__bam_isopd(dbc, pgnop) + DBC *dbc; + db_pgno_t *pgnop; +{ + BOVERFLOW *bo; + + if (TYPE(dbc->internal->page) != P_LBTREE) + return (0); + + bo = GET_BOVERFLOW(dbc->dbp, + dbc->internal->page, dbc->internal->indx + O_INDX); + if (B_TYPE(bo->type) == B_DUPLICATE) { + *pgnop = bo->pgno; + return (1); + } + return (0); +} + +/* + * __bam_opd_exists -- + * Return if the current position has any data. + * PUBLIC: int __bam_opd_exists __P((DBC *, db_pgno_t)); + */ +int +__bam_opd_exists(dbc, pgno) + DBC *dbc; + db_pgno_t pgno; +{ + PAGE *h; + int ret; + + if ((ret = __memp_fget(dbc->dbp->mpf, &pgno, + dbc->thread_info, dbc->txn, 0, &h)) != 0) + return (ret); + + /* + * We always collapse OPD trees so we only need to check + * the number of entries on the root. If there is a non-empty + * tree then there will be duplicates. + */ + if (NUM_ENT(h) == 0) + ret = 0; + else + ret = DB_KEYEXIST; + + (void)__memp_fput(dbc->dbp->mpf, dbc->thread_info, h, dbc->priority); + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_delete.c b/src/libs/resiprocate/contrib/db/btree/bt_delete.c new file mode 100644 index 00000000..f76aa05a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_delete.c @@ -0,0 +1,647 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" + +/* + * __bam_ditem -- + * Delete one or more entries from a page. + * + * PUBLIC: int __bam_ditem __P((DBC *, PAGE *, u_int32_t)); + */ +int +__bam_ditem(dbc, h, indx) + DBC *dbc; + PAGE *h; + u_int32_t indx; +{ + BINTERNAL *bi; + BKEYDATA *bk; + DB *dbp; + u_int32_t nbytes; + int ret; + db_indx_t *inp; + + dbp = dbc->dbp; + inp = P_INP(dbp, h); + + /* The page should already have been dirtied by our caller. */ + DB_ASSERT(dbp->env, IS_DIRTY(h)); + + switch (TYPE(h)) { + case P_IBTREE: + bi = GET_BINTERNAL(dbp, h, indx); + switch (B_TYPE(bi->type)) { + case B_DUPLICATE: + case B_KEYDATA: + nbytes = BINTERNAL_SIZE(bi->len); + break; + case B_OVERFLOW: + nbytes = BINTERNAL_SIZE(bi->len); + if ((ret = + __db_doff(dbc, ((BOVERFLOW *)bi->data)->pgno)) != 0) + return (ret); + break; + default: + return (__db_pgfmt(dbp->env, PGNO(h))); + } + break; + case P_IRECNO: + nbytes = RINTERNAL_SIZE; + break; + case P_LBTREE: + /* + * If it's a duplicate key, discard the index and don't touch + * the actual page item. + * + * !!! + * This works because no data item can have an index matching + * any other index so even if the data item is in a key "slot", + * it won't match any other index. + */ + if ((indx % 2) == 0) { + /* + * Check for a duplicate after us on the page. NOTE: + * we have to delete the key item before deleting the + * data item, otherwise the "indx + P_INDX" calculation + * won't work! + */ + if (indx + P_INDX < (u_int32_t)NUM_ENT(h) && + inp[indx] == inp[indx + P_INDX]) + return (__bam_adjindx(dbc, + h, indx, indx + O_INDX, 0)); + /* + * Check for a duplicate before us on the page. It + * doesn't matter if we delete the key item before or + * after the data item for the purposes of this one. + */ + if (indx > 0 && inp[indx] == inp[indx - P_INDX]) + return (__bam_adjindx(dbc, + h, indx, indx - P_INDX, 0)); + } + /* FALLTHROUGH */ + case P_LDUP: + case P_LRECNO: + bk = GET_BKEYDATA(dbp, h, indx); + switch (B_TYPE(bk->type)) { + case B_DUPLICATE: + nbytes = BOVERFLOW_SIZE; + break; + case B_OVERFLOW: + nbytes = BOVERFLOW_SIZE; + if ((ret = __db_doff( + dbc, (GET_BOVERFLOW(dbp, h, indx))->pgno)) != 0) + return (ret); + break; + case B_KEYDATA: + nbytes = BKEYDATA_SIZE(bk->len); + break; + default: + return (__db_pgfmt(dbp->env, PGNO(h))); + } + break; + default: + return (__db_pgfmt(dbp->env, PGNO(h))); + } + + /* Delete the item and mark the page dirty. */ + if ((ret = __db_ditem(dbc, h, indx, nbytes)) != 0) + return (ret); + + return (0); +} + +/* + * __bam_adjindx -- + * Adjust an index on the page. + * + * PUBLIC: int __bam_adjindx __P((DBC *, PAGE *, u_int32_t, u_int32_t, int)); + */ +int +__bam_adjindx(dbc, h, indx, indx_copy, is_insert) + DBC *dbc; + PAGE *h; + u_int32_t indx, indx_copy; + int is_insert; +{ + DB *dbp; + db_indx_t copy, *inp; + int ret; + + dbp = dbc->dbp; + inp = P_INP(dbp, h); + + /* Log the change. */ + if (DBC_LOGGING(dbc)) { + if ((ret = __bam_adj_log(dbp, dbc->txn, &LSN(h), 0, + PGNO(h), &LSN(h), indx, indx_copy, (u_int32_t)is_insert)) != 0) + return (ret); + } else + LSN_NOT_LOGGED(LSN(h)); + + /* Shuffle the indices and mark the page dirty. */ + if (is_insert) { + copy = inp[indx_copy]; + if (indx != NUM_ENT(h)) + memmove(&inp[indx + O_INDX], &inp[indx], + sizeof(db_indx_t) * (NUM_ENT(h) - indx)); + inp[indx] = copy; + ++NUM_ENT(h); + } else { + --NUM_ENT(h); + if (indx != NUM_ENT(h)) + memmove(&inp[indx], &inp[indx + O_INDX], + sizeof(db_indx_t) * (NUM_ENT(h) - indx)); + } + + return (0); +} + +/* + * __bam_dpages -- + * Delete a set of locked pages. + * + * PUBLIC: int __bam_dpages __P((DBC *, int, int)); + */ +int +__bam_dpages(dbc, use_top, flags) + DBC *dbc; + int use_top; + int flags; +{ + BINTERNAL *bi; + BTREE_CURSOR *cp; + DB *dbp; + DBT a, b; + DB_LOCK c_lock, p_lock; + DB_MPOOLFILE *mpf; + EPG *epg, *save_sp, *stack_epg; + PAGE *child, *parent; + db_indx_t nitems; + db_pgno_t pgno, root_pgno; + db_recno_t rcnt; + int done, ret, t_ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + nitems = 0; + pgno = PGNO_INVALID; + + /* + * We have the entire stack of deletable pages locked. + * + * Btree calls us with the first page in the stack is to have a + * single item deleted, and the rest of the pages are to be removed. + * + * Recno always has a stack to the root and __bam_merge operations + * may have unneeded items in the sack. We find the lowest page + * in the stack that has more than one record in it and start there. + */ + ret = 0; + if (use_top) + stack_epg = cp->sp; + else + for (stack_epg = cp->csp; stack_epg > cp->sp; --stack_epg) + if (NUM_ENT(stack_epg->page) > 1) + break; + epg = stack_epg; + /* + * !!! + * There is an interesting deadlock situation here. We have to relink + * the leaf page chain around the leaf page being deleted. Consider + * a cursor walking through the leaf pages, that has the previous page + * read-locked and is waiting on a lock for the page we're deleting. + * It will deadlock here. Before we unlink the subtree, we relink the + * leaf page chain. + */ + if (LF_ISSET(BTD_RELINK) && LEVEL(cp->csp->page) == 1 && + (ret = __bam_relink(dbc, cp->csp->page, NULL, PGNO_INVALID)) != 0) + goto discard; + + /* + * Delete the last item that references the underlying pages that are + * to be deleted, and adjust cursors that reference that page. Then, + * save that page's page number and item count and release it. If + * the application isn't retaining locks because it's running without + * transactions, this lets the rest of the tree get back to business + * immediately. + */ + if ((ret = __memp_dirty(mpf, + &epg->page, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + goto discard; + if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0) + goto discard; + if ((ret = __bam_ca_di(dbc, PGNO(epg->page), epg->indx, -1)) != 0) + goto discard; + + if (LF_ISSET(BTD_UPDATE) && epg->indx == 0) { + save_sp = cp->csp; + cp->csp = epg; + ret = __bam_pupdate(dbc, epg->page); + cp->csp = save_sp; + if (ret != 0) + goto discard; + } + + pgno = PGNO(epg->page); + nitems = NUM_ENT(epg->page); + + ret = __memp_fput(mpf, dbc->thread_info, epg->page, dbc->priority); + epg->page = NULL; + if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + goto err_inc; + + /* Then, discard any pages that we don't care about. */ +discard: for (epg = cp->sp; epg < stack_epg; ++epg) { + if ((t_ret = __memp_fput(mpf, dbc->thread_info, + epg->page, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + epg->page = NULL; + if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0) + ret = t_ret; + } + if (ret != 0) + goto err; + + /* Free the rest of the pages in the stack. */ + while (++epg <= cp->csp) { + if ((ret = __memp_dirty(mpf, &epg->page, + dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + goto err; + /* + * Delete page entries so they will be restored as part of + * recovery. We don't need to do cursor adjustment here as + * the pages are being emptied by definition and so cannot + * be referenced by a cursor. + */ + if (NUM_ENT(epg->page) != 0) { + DB_ASSERT(dbp->env, LEVEL(epg->page) != 1); + + if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0) + goto err; + /* + * Sheer paranoia: if we find any pages that aren't + * emptied by the delete, someone else added an item + * while we were walking the tree, and we discontinue + * the delete. Shouldn't be possible, but we check + * regardless. + */ + if (NUM_ENT(epg->page) != 0) + goto err; + } + + ret = __db_free(dbc, epg->page); + if (cp->page == epg->page) + cp->page = NULL; + epg->page = NULL; + if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + goto err_inc; + } + + if (0) { +err_inc: ++epg; +err: for (; epg <= cp->csp; ++epg) { + if (epg->page != NULL) { + (void)__memp_fput(mpf, dbc->thread_info, + epg->page, dbc->priority); + epg->page = NULL; + } + (void)__TLPUT(dbc, epg->lock); + } + BT_STK_CLR(cp); + return (ret); + } + BT_STK_CLR(cp); + + /* + * If we just deleted the next-to-last item from the root page, the + * tree can collapse one or more levels. While there remains only a + * single item on the root page, write lock the last page referenced + * by the root page and copy it over the root page. + */ + root_pgno = cp->root; + if (pgno != root_pgno || nitems != 1) + return (0); + + for (done = 0; !done;) { + /* Initialize. */ + parent = child = NULL; + LOCK_INIT(p_lock); + LOCK_INIT(c_lock); + + /* Lock the root. */ + pgno = root_pgno; + if ((ret = + __db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, &p_lock)) != 0) + goto stop; + if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn, + DB_MPOOL_DIRTY, &parent)) != 0) + goto stop; + + if (NUM_ENT(parent) != 1) + goto stop; + + switch (TYPE(parent)) { + case P_IBTREE: + /* + * If this is overflow, then try to delete it. + * The child may or may not still point at it. + */ + bi = GET_BINTERNAL(dbp, parent, 0); + if (B_TYPE(bi->type) == B_OVERFLOW) + if ((ret = __db_doff(dbc, + ((BOVERFLOW *)bi->data)->pgno)) != 0) + goto stop; + pgno = bi->pgno; + break; + case P_IRECNO: + pgno = GET_RINTERNAL(dbp, parent, 0)->pgno; + break; + default: + goto stop; + } + + /* Lock the child page. */ + if ((ret = + __db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, &c_lock)) != 0) + goto stop; + if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn, + DB_MPOOL_DIRTY, &child)) != 0) + goto stop; + + /* Log the change. */ + if (DBC_LOGGING(dbc)) { + memset(&a, 0, sizeof(a)); + a.data = child; + a.size = dbp->pgsize; + memset(&b, 0, sizeof(b)); + b.data = P_ENTRY(dbp, parent, 0); + b.size = TYPE(parent) == P_IRECNO ? RINTERNAL_SIZE : + BINTERNAL_SIZE(((BINTERNAL *)b.data)->len); + if ((ret = __bam_rsplit_log(dbp, dbc->txn, + &child->lsn, 0, PGNO(child), &a, PGNO(parent), + RE_NREC(parent), &b, &parent->lsn)) != 0) + goto stop; + } else + LSN_NOT_LOGGED(child->lsn); + + /* + * Make the switch. + * + * One fixup -- internal pages below the top level do not store + * a record count, so we have to preserve it if we're not + * converting to a leaf page. Note also that we are about to + * overwrite the parent page, including its LSN. This is OK + * because the log message we wrote describing this update + * stores its LSN on the child page. When the child is copied + * onto the parent, the correct LSN is copied into place. + */ + COMPQUIET(rcnt, 0); + if (F_ISSET(cp, C_RECNUM) && LEVEL(child) > LEAFLEVEL) + rcnt = RE_NREC(parent); + memcpy(parent, child, dbp->pgsize); + PGNO(parent) = root_pgno; + if (F_ISSET(cp, C_RECNUM) && LEVEL(child) > LEAFLEVEL) + RE_NREC_SET(parent, rcnt); + + /* Adjust the cursors. */ + if ((ret = __bam_ca_rsplit(dbc, PGNO(child), root_pgno)) != 0) + goto stop; + + /* + * Free the page copied onto the root page and discard its + * lock. (The call to __db_free() discards our reference + * to the page.) + */ + if ((ret = __db_free(dbc, child)) != 0) { + child = NULL; + goto stop; + } + child = NULL; + + if (0) { +stop: done = 1; + } + if ((t_ret = __TLPUT(dbc, p_lock)) != 0 && ret == 0) + ret = t_ret; + if (parent != NULL && + (t_ret = __memp_fput(mpf, dbc->thread_info, + parent, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __TLPUT(dbc, c_lock)) != 0 && ret == 0) + ret = t_ret; + if (child != NULL && + (t_ret = __memp_fput(mpf, dbc->thread_info, + child, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + } + + return (ret); +} + +/* + * __bam_relink -- + * Relink around a deleted page. + * + * PUBLIC: int __bam_relink __P((DBC *, PAGE *, PAGE *, db_pgno_t)); + * Otherp can be either the previous or the next page to use if + * the caller already holds that page. + */ +int +__bam_relink(dbc, pagep, otherp, new_pgno) + DBC *dbc; + PAGE *pagep, *otherp; + db_pgno_t new_pgno; +{ + DB *dbp; + DB_LOCK npl, ppl; + DB_LSN *nlsnp, *plsnp, ret_lsn; + DB_MPOOLFILE *mpf; + PAGE *np, *pp; + int ret, t_ret; + + dbp = dbc->dbp; + np = pp = NULL; + LOCK_INIT(npl); + LOCK_INIT(ppl); + nlsnp = plsnp = NULL; + mpf = dbp->mpf; + ret = 0; + + /* + * Retrieve the one/two pages. The caller must have them locked + * because the parent is latched. For a remove, we may need + * two pages (the before and after). For an add, we only need one + * because, the split took care of the prev. + */ + if (pagep->next_pgno != PGNO_INVALID) { + if (((np = otherp) == NULL || + PGNO(otherp) != pagep->next_pgno) && + (ret = __memp_fget(mpf, &pagep->next_pgno, + dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &np)) != 0) { + ret = __db_pgerr(dbp, pagep->next_pgno, ret); + goto err; + } + nlsnp = &np->lsn; + } + if (pagep->prev_pgno != PGNO_INVALID) { + if (((pp = otherp) == NULL || + PGNO(otherp) != pagep->prev_pgno) && + (ret = __memp_fget(mpf, &pagep->prev_pgno, + dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &pp)) != 0) { + ret = __db_pgerr(dbp, pagep->prev_pgno, ret); + goto err; + } + plsnp = &pp->lsn; + } + + /* Log the change. */ + if (DBC_LOGGING(dbc)) { + if ((ret = __bam_relink_log(dbp, dbc->txn, &ret_lsn, 0, + pagep->pgno, new_pgno, pagep->prev_pgno, plsnp, + pagep->next_pgno, nlsnp)) != 0) + goto err; + } else + LSN_NOT_LOGGED(ret_lsn); + if (np != NULL) + np->lsn = ret_lsn; + if (pp != NULL) + pp->lsn = ret_lsn; + + /* + * Modify and release the two pages. + */ + if (np != NULL) { + if (new_pgno == PGNO_INVALID) + np->prev_pgno = pagep->prev_pgno; + else + np->prev_pgno = new_pgno; + if (np != otherp) + ret = __memp_fput(mpf, + dbc->thread_info, np, dbc->priority); + if ((t_ret = __TLPUT(dbc, npl)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + goto err; + } + + if (pp != NULL) { + if (new_pgno == PGNO_INVALID) + pp->next_pgno = pagep->next_pgno; + else + pp->next_pgno = new_pgno; + if (pp != otherp) + ret = __memp_fput(mpf, + dbc->thread_info, pp, dbc->priority); + if ((t_ret = __TLPUT(dbc, ppl)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + goto err; + } + return (0); + +err: if (np != NULL && np != otherp) + (void)__memp_fput(mpf, dbc->thread_info, np, dbc->priority); + if (pp != NULL && pp != otherp) + (void)__memp_fput(mpf, dbc->thread_info, pp, dbc->priority); + return (ret); +} + +/* + * __bam_pupdate -- + * Update parent key pointers up the tree. + * + * PUBLIC: int __bam_pupdate __P((DBC *, PAGE *)); + */ +int +__bam_pupdate(dbc, lpg) + DBC *dbc; + PAGE *lpg; +{ + BTREE_CURSOR *cp; + ENV *env; + EPG *epg; + int ret; + + env = dbc->env; + cp = (BTREE_CURSOR *)dbc->internal; + ret = 0; + + /* + * Update the parents up the tree. __bam_pinsert only looks at the + * left child if is a leaf page, so we don't need to change it. We + * just do a delete and insert; a replace is possible but reusing + * pinsert is better. + */ + for (epg = &cp->csp[-1]; epg >= cp->sp; epg--) { + if ((ret = __memp_dirty(dbc->dbp->mpf, &epg->page, + dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + return (ret); + epg->indx--; + if ((ret = __bam_pinsert(dbc, epg, 0, + lpg, epg[1].page, BPI_NORECNUM | BPI_REPLACE)) != 0) { + if (ret == DB_NEEDSPLIT) { + /* This should not happen. */ + __db_errx(env, + "Not enough room in parent: %s: page %lu", + dbc->dbp->fname, (u_long)PGNO(epg->page)); + ret = __env_panic(env, EINVAL); + } + epg->indx++; + return (ret); + } + epg->indx++; + } + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_method.c b/src/libs/resiprocate/contrib/db/btree/bt_method.c new file mode 100644 index 00000000..d27fe3dc --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_method.c @@ -0,0 +1,734 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1999-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/qam.h" + +static int __bam_set_bt_minkey __P((DB *, u_int32_t)); +static int __bam_get_bt_compare + __P((DB *, int (**)(DB *, const DBT *, const DBT *))); +static int __bam_get_bt_prefix + __P((DB *, size_t(**)(DB *, const DBT *, const DBT *))); +static int __bam_set_bt_prefix + __P((DB *, size_t(*)(DB *, const DBT *, const DBT *))); +static int __bam_get_bt_compress __P((DB *, + int (**)(DB *, const DBT *, const DBT *, const DBT *, const DBT *, DBT *), + int (**)(DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *))); +static int __ram_get_re_delim __P((DB *, int *)); +static int __ram_set_re_delim __P((DB *, int)); +static int __ram_set_re_len __P((DB *, u_int32_t)); +static int __ram_set_re_pad __P((DB *, int)); +static int __ram_get_re_source __P((DB *, const char **)); +static int __ram_set_re_source __P((DB *, const char *)); + +/* + * __bam_db_create -- + * Btree specific initialization of the DB structure. + * + * PUBLIC: int __bam_db_create __P((DB *)); + */ +int +__bam_db_create(dbp) + DB *dbp; +{ + BTREE *t; + int ret; + + /* Allocate and initialize the private btree structure. */ + if ((ret = __os_calloc(dbp->env, 1, sizeof(BTREE), &t)) != 0) + return (ret); + dbp->bt_internal = t; + + t->bt_minkey = DEFMINKEYPAGE; /* Btree */ + t->bt_compare = __bam_defcmp; + t->bt_prefix = __bam_defpfx; +#ifdef HAVE_COMPRESSION + t->bt_compress = NULL; + t->bt_decompress = NULL; + t->compress_dup_compare = NULL; + + /* + * DB_AM_COMPRESS may have been set in __bam_metachk before the + * bt_internal structure existed. + */ + if (F_ISSET(dbp, DB_AM_COMPRESS) && + (ret = __bam_set_bt_compress(dbp, NULL, NULL)) != 0) + return (ret); +#endif + + dbp->get_bt_compare = __bam_get_bt_compare; + dbp->set_bt_compare = __bam_set_bt_compare; + dbp->get_bt_minkey = __bam_get_bt_minkey; + dbp->set_bt_minkey = __bam_set_bt_minkey; + dbp->get_bt_prefix = __bam_get_bt_prefix; + dbp->set_bt_prefix = __bam_set_bt_prefix; + dbp->get_bt_compress = __bam_get_bt_compress; + dbp->set_bt_compress = __bam_set_bt_compress; + + t->re_pad = ' '; /* Recno */ + t->re_delim = '\n'; + t->re_eof = 1; + + dbp->get_re_delim = __ram_get_re_delim; + dbp->set_re_delim = __ram_set_re_delim; + dbp->get_re_len = __ram_get_re_len; + dbp->set_re_len = __ram_set_re_len; + dbp->get_re_pad = __ram_get_re_pad; + dbp->set_re_pad = __ram_set_re_pad; + dbp->get_re_source = __ram_get_re_source; + dbp->set_re_source = __ram_set_re_source; + + return (0); +} + +/* + * __bam_db_close -- + * Btree specific discard of the DB structure. + * + * PUBLIC: int __bam_db_close __P((DB *)); + */ +int +__bam_db_close(dbp) + DB *dbp; +{ + BTREE *t; + + if ((t = dbp->bt_internal) == NULL) + return (0); + /* Recno */ + /* Close any backing source file descriptor. */ + if (t->re_fp != NULL) + (void)fclose(t->re_fp); + + /* Free any backing source file name. */ + if (t->re_source != NULL) + __os_free(dbp->env, t->re_source); + + __os_free(dbp->env, t); + dbp->bt_internal = NULL; + + return (0); +} + +/* + * __bam_map_flags -- + * Map Btree specific flags from public to the internal values. + * + * PUBLIC: void __bam_map_flags __P((DB *, u_int32_t *, u_int32_t *)); + */ +void +__bam_map_flags(dbp, inflagsp, outflagsp) + DB *dbp; + u_int32_t *inflagsp, *outflagsp; +{ + COMPQUIET(dbp, NULL); + + if (FLD_ISSET(*inflagsp, DB_DUP)) { + FLD_SET(*outflagsp, DB_AM_DUP); + FLD_CLR(*inflagsp, DB_DUP); + } + if (FLD_ISSET(*inflagsp, DB_DUPSORT)) { + FLD_SET(*outflagsp, DB_AM_DUP | DB_AM_DUPSORT); + FLD_CLR(*inflagsp, DB_DUPSORT); + } + if (FLD_ISSET(*inflagsp, DB_RECNUM)) { + FLD_SET(*outflagsp, DB_AM_RECNUM); + FLD_CLR(*inflagsp, DB_RECNUM); + } + if (FLD_ISSET(*inflagsp, DB_REVSPLITOFF)) { + FLD_SET(*outflagsp, DB_AM_REVSPLITOFF); + FLD_CLR(*inflagsp, DB_REVSPLITOFF); + } +} + +/* + * __bam_set_flags -- + * Set Btree specific flags. + * + * PUBLIC: int __bam_set_flags __P((DB *, u_int32_t *flagsp)); + */ +int +__bam_set_flags(dbp, flagsp) + DB *dbp; + u_int32_t *flagsp; +{ + BTREE *t; + u_int32_t flags; + + t = dbp->bt_internal; + + flags = *flagsp; + if (LF_ISSET(DB_DUP | DB_DUPSORT | DB_RECNUM | DB_REVSPLITOFF)) + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags"); + + /* + * The DB_DUP and DB_DUPSORT flags are shared by the Hash + * and Btree access methods. + */ + if (LF_ISSET(DB_DUP | DB_DUPSORT)) + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH); + + if (LF_ISSET(DB_RECNUM | DB_REVSPLITOFF)) + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); + + /* DB_DUP/DB_DUPSORT is incompatible with DB_RECNUM. */ + if (LF_ISSET(DB_DUP | DB_DUPSORT) && F_ISSET(dbp, DB_AM_RECNUM)) + goto incompat; + + /* DB_RECNUM is incompatible with DB_DUP/DB_DUPSORT. */ + if (LF_ISSET(DB_RECNUM) && F_ISSET(dbp, DB_AM_DUP)) + goto incompat; + + /* DB_RECNUM is incompatible with DB_DUP/DB_DUPSORT. */ + if (LF_ISSET(DB_RECNUM) && LF_ISSET(DB_DUP | DB_DUPSORT)) + goto incompat; + +#ifdef HAVE_COMPRESSION + /* DB_RECNUM is incompatible with compression */ + if (LF_ISSET(DB_RECNUM) && DB_IS_COMPRESSED(dbp)) { + __db_errx(dbp->env, + "DB_RECNUM cannot be used with compression"); + return (EINVAL); + } + + /* DB_DUP without DB_DUPSORT is incompatible with compression */ + if (LF_ISSET(DB_DUP) && !LF_ISSET(DB_DUPSORT) && + !F_ISSET(dbp, DB_AM_DUPSORT) && DB_IS_COMPRESSED(dbp)) { + __db_errx(dbp->env, + "DB_DUP cannot be used with compression without DB_DUPSORT"); + return (EINVAL); + } +#endif + + if (LF_ISSET(DB_DUPSORT) && dbp->dup_compare == NULL) { +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp)) { + dbp->dup_compare = __bam_compress_dupcmp; + t->compress_dup_compare = __bam_defcmp; + } else +#endif + dbp->dup_compare = __bam_defcmp; + } + + __bam_map_flags(dbp, flagsp, &dbp->flags); + return (0); + +incompat: + return (__db_ferr(dbp->env, "DB->set_flags", 1)); +} + +/* + * __bam_get_bt_compare -- + * Get the comparison function. + */ +static int +__bam_get_bt_compare(dbp, funcp) + DB *dbp; + int (**funcp) __P((DB *, const DBT *, const DBT *)); +{ + BTREE *t; + + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); + + t = dbp->bt_internal; + + if (funcp != NULL) + *funcp = t->bt_compare; + + return (0); +} + +/* + * __bam_set_bt_compare -- + * Set the comparison function. + * + * PUBLIC: int __bam_set_bt_compare + * PUBLIC: __P((DB *, int (*)(DB *, const DBT *, const DBT *))); + */ +int +__bam_set_bt_compare(dbp, func) + DB *dbp; + int (*func) __P((DB *, const DBT *, const DBT *)); +{ + BTREE *t; + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_compare"); + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); + + t = dbp->bt_internal; + + /* + * Can't default the prefix routine if the user supplies a comparison + * routine; shortening the keys can break their comparison algorithm. + */ + t->bt_compare = func; + if (t->bt_prefix == __bam_defpfx) + t->bt_prefix = NULL; + + return (0); +} + +/* + * __bam_get_bt_compress -- + * Get the compression functions. + */ +static int +__bam_get_bt_compress(dbp, compressp, decompressp) + DB *dbp; + int (**compressp) __P((DB *, const DBT *, const DBT *, const DBT *, + const DBT *, DBT *)); + int (**decompressp) __P((DB *, const DBT *, const DBT *, DBT *, DBT *, + DBT *)); +{ +#ifdef HAVE_COMPRESSION + BTREE *t; + + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); + + t = dbp->bt_internal; + + if (compressp != NULL) + *compressp = t->bt_compress; + if (decompressp != NULL) + *decompressp = t->bt_decompress; + + return (0); +#else + COMPQUIET(compressp, NULL); + COMPQUIET(decompressp, NULL); + + __db_errx(dbp->env, "compression support has not been compiled in"); + return (EINVAL); +#endif +} + +/* + * __bam_set_bt_compress -- + * Set the compression functions. + * + * PUBLIC: int __bam_set_bt_compress __P((DB *, + * PUBLIC: int (*)(DB *, const DBT *, const DBT *, + * PUBLIC: const DBT *, const DBT *, DBT *), + * PUBLIC: int (*)(DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *))); + */ +int +__bam_set_bt_compress(dbp, compress, decompress) + DB *dbp; + int (*compress) __P((DB *, const DBT *, const DBT *, const DBT *, + const DBT *, DBT *)); + int (*decompress) __P((DB *, const DBT *, const DBT *, DBT *, DBT *, + DBT *)); +{ +#ifdef HAVE_COMPRESSION + BTREE *t; + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_compress"); + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); + + t = dbp->bt_internal; + + /* compression is incompatible with DB_RECNUM */ + if (F_ISSET(dbp, DB_AM_RECNUM)) { + __db_errx(dbp->env, + "compression cannot be used with DB_RECNUM"); + return (EINVAL); + } + + /* compression is incompatible with DB_DUP without DB_DUPSORT */ + if (F_ISSET(dbp, DB_AM_DUP) && !F_ISSET(dbp, DB_AM_DUPSORT)) { + __db_errx(dbp->env, + "compression cannot be used with DB_DUP without DB_DUPSORT"); + return (EINVAL); + } + + if (compress != 0 && decompress != 0) { + t->bt_compress = compress; + t->bt_decompress = decompress; + } else if (compress == 0 && decompress == 0) { + t->bt_compress = __bam_defcompress; + t->bt_decompress = __bam_defdecompress; + } else { + __db_errx(dbp->env, + "to enable compression you need to supply both function arguments"); + return (EINVAL); + } + F_SET(dbp, DB_AM_COMPRESS); + + /* Copy dup_compare to compress_dup_compare, and use the compression + duplicate compare */ + if (F_ISSET(dbp, DB_AM_DUPSORT)) { + t->compress_dup_compare = dbp->dup_compare; + dbp->dup_compare = __bam_compress_dupcmp; + } + + return (0); +#else + COMPQUIET(compress, NULL); + COMPQUIET(decompress, NULL); + + __db_errx(dbp->env, "compression support has not been compiled in"); + return (EINVAL); +#endif +} + +/* + * __db_get_bt_minkey -- + * Get the minimum keys per page. + * + * PUBLIC: int __bam_get_bt_minkey __P((DB *, u_int32_t *)); + */ +int +__bam_get_bt_minkey(dbp, bt_minkeyp) + DB *dbp; + u_int32_t *bt_minkeyp; +{ + BTREE *t; + + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); + + t = dbp->bt_internal; + *bt_minkeyp = t->bt_minkey; + return (0); +} + +/* + * __bam_set_bt_minkey -- + * Set the minimum keys per page. + */ +static int +__bam_set_bt_minkey(dbp, bt_minkey) + DB *dbp; + u_int32_t bt_minkey; +{ + BTREE *t; + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_minkey"); + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); + + t = dbp->bt_internal; + + if (bt_minkey < 2) { + __db_errx(dbp->env, "minimum bt_minkey value is 2"); + return (EINVAL); + } + + t->bt_minkey = bt_minkey; + return (0); +} + +/* + * __bam_get_bt_prefix -- + * Get the prefix function. + */ +static int +__bam_get_bt_prefix(dbp, funcp) + DB *dbp; + size_t (**funcp) __P((DB *, const DBT *, const DBT *)); +{ + BTREE *t; + + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); + + t = dbp->bt_internal; + if (funcp != NULL) + *funcp = t->bt_prefix; + return (0); +} + +/* + * __bam_set_bt_prefix -- + * Set the prefix function. + */ +static int +__bam_set_bt_prefix(dbp, func) + DB *dbp; + size_t (*func) __P((DB *, const DBT *, const DBT *)); +{ + BTREE *t; + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_prefix"); + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); + + t = dbp->bt_internal; + + t->bt_prefix = func; + return (0); +} + +/* + * __bam_copy_config + * Copy the configuration of one DB handle to another. + * PUBLIC: void __bam_copy_config __P((DB *, DB*, u_int32_t)); + */ +void +__bam_copy_config(src, dst, nparts) + DB *src, *dst; + u_int32_t nparts; +{ + BTREE *s, *d; + + COMPQUIET(nparts, 0); + + s = src->bt_internal; + d = dst->bt_internal; + d->bt_compare = s->bt_compare; + d->bt_minkey = s->bt_minkey; + d->bt_minkey = s->bt_minkey; + d->bt_prefix = s->bt_prefix; +#ifdef HAVE_COMPRESSION + d->bt_compress = s->bt_compress; + d->bt_decompress = s->bt_decompress; + d->compress_dup_compare = s->compress_dup_compare; +#endif +} + +/* + * __ram_map_flags -- + * Map Recno specific flags from public to the internal values. + * + * PUBLIC: void __ram_map_flags __P((DB *, u_int32_t *, u_int32_t *)); + */ +void +__ram_map_flags(dbp, inflagsp, outflagsp) + DB *dbp; + u_int32_t *inflagsp, *outflagsp; +{ + COMPQUIET(dbp, NULL); + + if (FLD_ISSET(*inflagsp, DB_RENUMBER)) { + FLD_SET(*outflagsp, DB_AM_RENUMBER); + FLD_CLR(*inflagsp, DB_RENUMBER); + } + if (FLD_ISSET(*inflagsp, DB_SNAPSHOT)) { + FLD_SET(*outflagsp, DB_AM_SNAPSHOT); + FLD_CLR(*inflagsp, DB_SNAPSHOT); + } +} + +/* + * __ram_set_flags -- + * Set Recno specific flags. + * + * PUBLIC: int __ram_set_flags __P((DB *, u_int32_t *flagsp)); + */ +int +__ram_set_flags(dbp, flagsp) + DB *dbp; + u_int32_t *flagsp; +{ + u_int32_t flags; + + flags = *flagsp; + if (LF_ISSET(DB_RENUMBER | DB_SNAPSHOT)) { + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags"); + DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); + } + + __ram_map_flags(dbp, flagsp, &dbp->flags); + return (0); +} + +/* + * __db_get_re_delim -- + * Get the variable-length input record delimiter. + */ +static int +__ram_get_re_delim(dbp, re_delimp) + DB *dbp; + int *re_delimp; +{ + BTREE *t; + + DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); + t = dbp->bt_internal; + *re_delimp = t->re_delim; + return (0); +} + +/* + * __ram_set_re_delim -- + * Set the variable-length input record delimiter. + */ +static int +__ram_set_re_delim(dbp, re_delim) + DB *dbp; + int re_delim; +{ + BTREE *t; + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_delim"); + DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); + + t = dbp->bt_internal; + + t->re_delim = re_delim; + F_SET(dbp, DB_AM_DELIMITER); + + return (0); +} + +/* + * __db_get_re_len -- + * Get the variable-length input record length. + * + * PUBLIC: int __ram_get_re_len __P((DB *, u_int32_t *)); + */ +int +__ram_get_re_len(dbp, re_lenp) + DB *dbp; + u_int32_t *re_lenp; +{ + BTREE *t; + QUEUE *q; + + DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); + + /* + * This has to work for all access methods, before or after opening the + * database. When the record length is set with __ram_set_re_len, the + * value in both the BTREE and QUEUE structs will be correct. + * Otherwise, this only makes sense after the database in opened, in + * which case we know the type. + */ + if (dbp->type == DB_QUEUE) { + q = dbp->q_internal; + *re_lenp = q->re_len; + } else { + t = dbp->bt_internal; + *re_lenp = t->re_len; + } + + return (0); +} + +/* + * __ram_set_re_len -- + * Set the variable-length input record length. + */ +static int +__ram_set_re_len(dbp, re_len) + DB *dbp; + u_int32_t re_len; +{ + BTREE *t; + QUEUE *q; + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_len"); + DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); + + t = dbp->bt_internal; + t->re_len = re_len; + + q = dbp->q_internal; + q->re_len = re_len; + + F_SET(dbp, DB_AM_FIXEDLEN); + + return (0); +} + +/* + * __db_get_re_pad -- + * Get the fixed-length record pad character. + * + * PUBLIC: int __ram_get_re_pad __P((DB *, int *)); + */ +int +__ram_get_re_pad(dbp, re_padp) + DB *dbp; + int *re_padp; +{ + BTREE *t; + QUEUE *q; + + DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); + + /* + * This has to work for all access methods, before or after opening the + * database. When the record length is set with __ram_set_re_pad, the + * value in both the BTREE and QUEUE structs will be correct. + * Otherwise, this only makes sense after the database in opened, in + * which case we know the type. + */ + if (dbp->type == DB_QUEUE) { + q = dbp->q_internal; + *re_padp = q->re_pad; + } else { + t = dbp->bt_internal; + *re_padp = t->re_pad; + } + + return (0); +} + +/* + * __ram_set_re_pad -- + * Set the fixed-length record pad character. + */ +static int +__ram_set_re_pad(dbp, re_pad) + DB *dbp; + int re_pad; +{ + BTREE *t; + QUEUE *q; + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_pad"); + DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); + + t = dbp->bt_internal; + t->re_pad = re_pad; + + q = dbp->q_internal; + q->re_pad = re_pad; + + F_SET(dbp, DB_AM_PAD); + + return (0); +} + +/* + * __db_get_re_source -- + * Get the backing source file name. + */ +static int +__ram_get_re_source(dbp, re_sourcep) + DB *dbp; + const char **re_sourcep; +{ + BTREE *t; + + DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); + + t = dbp->bt_internal; + *re_sourcep = t->re_source; + return (0); +} + +/* + * __ram_set_re_source -- + * Set the backing source file name. + */ +static int +__ram_set_re_source(dbp, re_source) + DB *dbp; + const char *re_source; +{ + BTREE *t; + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_source"); + DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); + + t = dbp->bt_internal; + + return (__os_strdup(dbp->env, re_source, &t->re_source)); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_open.c b/src/libs/resiprocate/contrib/db/btree/bt_open.c new file mode 100644 index 00000000..1fdfea53 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_open.c @@ -0,0 +1,669 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/crypto.h" +#include "dbinc/db_page.h" +#include "dbinc/db_swap.h" +#include "dbinc/btree.h" +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/partition.h" +#include "dbinc/fop.h" + +static void __bam_init_meta __P((DB *, BTMETA *, db_pgno_t, DB_LSN *)); + +/* + * __bam_open -- + * Open a btree. + * + * PUBLIC: int __bam_open __P((DB *, DB_THREAD_INFO *, + * PUBLIC: DB_TXN *, const char *, db_pgno_t, u_int32_t)); + */ +int +__bam_open(dbp, ip, txn, name, base_pgno, flags) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + const char *name; + db_pgno_t base_pgno; + u_int32_t flags; +{ + BTREE *t; + + COMPQUIET(name, NULL); + t = dbp->bt_internal; + + /* + * We don't permit the user to specify a prefix routine if they didn't + * also specify a comparison routine, they can't know enough about our + * comparison routine to get it right. + */ + if (t->bt_compare == __bam_defcmp && t->bt_prefix != __bam_defpfx) { + __db_errx(dbp->env, +"prefix comparison may not be specified for default comparison routine"); + return (EINVAL); + } + + /* + * Verify that the bt_minkey value specified won't cause the + * calculation of ovflsize to underflow [#2406] for this pagesize. + */ + if (B_MINKEY_TO_OVFLSIZE(dbp, t->bt_minkey, dbp->pgsize) > + B_MINKEY_TO_OVFLSIZE(dbp, DEFMINKEYPAGE, dbp->pgsize)) { + __db_errx(dbp->env, + "bt_minkey value of %lu too high for page size of %lu", + (u_long)t->bt_minkey, (u_long)dbp->pgsize); + return (EINVAL); + } + + /* Start up the tree. */ + return (__bam_read_root(dbp, ip, txn, base_pgno, flags)); +} + +/* + * __bam_metachk -- + * + * PUBLIC: int __bam_metachk __P((DB *, const char *, BTMETA *)); + */ +int +__bam_metachk(dbp, name, btm) + DB *dbp; + const char *name; + BTMETA *btm; +{ + ENV *env; + u_int32_t vers; + int ret; + + env = dbp->env; + + /* + * At this point, all we know is that the magic number is for a Btree. + * Check the version, the database may be out of date. + */ + vers = btm->dbmeta.version; + if (F_ISSET(dbp, DB_AM_SWAP)) + M_32_SWAP(vers); + switch (vers) { + case 6: + case 7: + __db_errx(env, + "%s: btree version %lu requires a version upgrade", + name, (u_long)vers); + return (DB_OLD_VERSION); + case 8: + case 9: + break; + default: + __db_errx(env, + "%s: unsupported btree version: %lu", name, (u_long)vers); + return (EINVAL); + } + + /* Swap the page if we need to. */ + if (F_ISSET(dbp, DB_AM_SWAP) && + (ret = __bam_mswap(env, (PAGE *)btm)) != 0) + return (ret); + + /* + * Check application info against metadata info, and set info, flags, + * and type based on metadata info. + */ + if ((ret = + __db_fchk(env, "DB->open", btm->dbmeta.flags, BTM_MASK)) != 0) + return (ret); + + if (F_ISSET(&btm->dbmeta, BTM_RECNO)) { + if (dbp->type == DB_BTREE) + goto wrong_type; + dbp->type = DB_RECNO; + DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); + } else { + if (dbp->type == DB_RECNO) + goto wrong_type; + dbp->type = DB_BTREE; + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); + } + + if (F_ISSET(&btm->dbmeta, BTM_DUP)) + F_SET(dbp, DB_AM_DUP); + else + if (F_ISSET(dbp, DB_AM_DUP)) { + __db_errx(env, + "%s: DB_DUP specified to open method but not set in database", + name); + return (EINVAL); + } + + if (F_ISSET(&btm->dbmeta, BTM_RECNUM)) { + if (dbp->type != DB_BTREE) + goto wrong_type; + F_SET(dbp, DB_AM_RECNUM); + + if ((ret = __db_fcchk(env, + "DB->open", dbp->flags, DB_AM_DUP, DB_AM_RECNUM)) != 0) + return (ret); + } else + if (F_ISSET(dbp, DB_AM_RECNUM)) { + __db_errx(env, + "%s: DB_RECNUM specified to open method but not set in database", + name); + return (EINVAL); + } + + if (F_ISSET(&btm->dbmeta, BTM_FIXEDLEN)) { + if (dbp->type != DB_RECNO) + goto wrong_type; + F_SET(dbp, DB_AM_FIXEDLEN); + } else + if (F_ISSET(dbp, DB_AM_FIXEDLEN)) { + __db_errx(env, + "%s: DB_FIXEDLEN specified to open method but not set in database", + name); + return (EINVAL); + } + + if (F_ISSET(&btm->dbmeta, BTM_RENUMBER)) { + if (dbp->type != DB_RECNO) + goto wrong_type; + F_SET(dbp, DB_AM_RENUMBER); + } else + if (F_ISSET(dbp, DB_AM_RENUMBER)) { + __db_errx(env, + "%s: DB_RENUMBER specified to open method but not set in database", + name); + return (EINVAL); + } + + if (F_ISSET(&btm->dbmeta, BTM_SUBDB)) + F_SET(dbp, DB_AM_SUBDB); + else + if (F_ISSET(dbp, DB_AM_SUBDB)) { + __db_errx(env, + "%s: multiple databases specified but not supported by file", + name); + return (EINVAL); + } + + if (F_ISSET(&btm->dbmeta, BTM_DUPSORT)) { + if (dbp->dup_compare == NULL) + dbp->dup_compare = __bam_defcmp; + F_SET(dbp, DB_AM_DUPSORT); + } else + if (dbp->dup_compare != NULL) { + __db_errx(env, + "%s: duplicate sort specified but not supported in database", + name); + return (EINVAL); + } + +#ifdef HAVE_COMPRESSION + if (F_ISSET(&btm->dbmeta, BTM_COMPRESS)) { + F_SET(dbp, DB_AM_COMPRESS); + if ((BTREE *)dbp->bt_internal != NULL && + !DB_IS_COMPRESSED(dbp) && + (ret = __bam_set_bt_compress(dbp, NULL, NULL)) != 0) + return (ret); + } else { + if ((BTREE *)dbp->bt_internal != NULL && + DB_IS_COMPRESSED(dbp)) { + __db_errx(env, + "%s: compresssion specified to open method but not set in database", + name); + return (EINVAL); + } + } +#else + if (F_ISSET(&btm->dbmeta, BTM_COMPRESS)) { + __db_errx(env, + "%s: compression support has not been compiled in", + name); + return (EINVAL); + } +#endif + + /* Set the page size. */ + dbp->pgsize = btm->dbmeta.pagesize; + + /* Copy the file's ID. */ + memcpy(dbp->fileid, btm->dbmeta.uid, DB_FILE_ID_LEN); + + return (0); + +wrong_type: + if (dbp->type == DB_BTREE) + __db_errx(env, + "open method type is Btree, database type is Recno"); + else + __db_errx(env, + "open method type is Recno, database type is Btree"); + return (EINVAL); +} + +/* + * __bam_read_root -- + * Read the root page and check a tree. + * + * PUBLIC: int __bam_read_root __P((DB *, + * PUBLIC: DB_THREAD_INFO *, DB_TXN *, db_pgno_t, u_int32_t)); + */ +int +__bam_read_root(dbp, ip, txn, base_pgno, flags) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + db_pgno_t base_pgno; + u_int32_t flags; +{ + BTMETA *meta; + BTREE *t; + DBC *dbc; + DB_LOCK metalock; + DB_MPOOLFILE *mpf; + int ret, t_ret; + + COMPQUIET(flags, 0); + + meta = NULL; + t = dbp->bt_internal; + LOCK_INIT(metalock); + mpf = dbp->mpf; + ret = 0; + + /* Get a cursor. */ + if ((ret = __db_cursor(dbp, ip, txn, &dbc, 0)) != 0) + return (ret); + + /* Get the metadata page. */ + if ((ret = + __db_lget(dbc, 0, base_pgno, DB_LOCK_READ, 0, &metalock)) != 0) + goto err; + if ((ret = __memp_fget(mpf, &base_pgno, ip, dbc->txn, 0, &meta)) != 0) + goto err; + + /* + * If the magic number is set, the tree has been created. Correct + * any fields that may not be right. Note, all of the local flags + * were set by DB->open. + * + * Otherwise, we'd better be in recovery or abort, in which case the + * metadata page will be created/initialized elsewhere. + */ + if (meta->dbmeta.magic == DB_BTREEMAGIC) { + t->bt_minkey = meta->minkey; + t->re_pad = (int)meta->re_pad; + t->re_len = meta->re_len; + + t->bt_meta = base_pgno; + t->bt_root = meta->root; +#ifndef HAVE_FTRUNCATE + if (PGNO(meta) == PGNO_BASE_MD && + !F_ISSET(dbp, DB_AM_RECOVER) && !IS_VERSION(dbp, meta)) + __memp_set_last_pgno(mpf, meta->dbmeta.last_pgno); +#endif + } else { + DB_ASSERT(dbp->env, + IS_RECOVERING(dbp->env) || F_ISSET(dbp, DB_AM_RECOVER)); + } + + /* + * !!! + * If creating a subdatabase, we've already done an insert when + * we put the subdatabase's entry into the master database, so + * our last-page-inserted value is wrongly initialized for the + * master database, not the subdatabase we're creating. I'm not + * sure where the *right* place to clear this value is, it's not + * intuitively obvious that it belongs here. + */ + t->bt_lpgno = PGNO_INVALID; + +err: /* Put the metadata page back. */ + if (meta != NULL && (t_ret = __memp_fput(mpf, + ip, meta, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) + ret = t_ret; + + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +/* + * __bam_init_meta -- + * + * Initialize a btree meta-data page. The following fields may need + * to be updated later: last_pgno, root. + */ +static void +__bam_init_meta(dbp, meta, pgno, lsnp) + DB *dbp; + BTMETA *meta; + db_pgno_t pgno; + DB_LSN *lsnp; +{ + BTREE *t; +#ifdef HAVE_PARTITION + DB_PARTITION *part; +#endif + ENV *env; + + env = dbp->env; + t = dbp->bt_internal; + + memset(meta, 0, sizeof(BTMETA)); + meta->dbmeta.lsn = *lsnp; + meta->dbmeta.pgno = pgno; + meta->dbmeta.magic = DB_BTREEMAGIC; + meta->dbmeta.version = DB_BTREEVERSION; + meta->dbmeta.pagesize = dbp->pgsize; + if (F_ISSET(dbp, DB_AM_CHKSUM)) + FLD_SET(meta->dbmeta.metaflags, DBMETA_CHKSUM); + if (F_ISSET(dbp, DB_AM_ENCRYPT)) { + meta->dbmeta.encrypt_alg = env->crypto_handle->alg; + DB_ASSERT(env, meta->dbmeta.encrypt_alg != 0); + meta->crypto_magic = meta->dbmeta.magic; + } + meta->dbmeta.type = P_BTREEMETA; + meta->dbmeta.free = PGNO_INVALID; + meta->dbmeta.last_pgno = pgno; + if (F_ISSET(dbp, DB_AM_DUP)) + F_SET(&meta->dbmeta, BTM_DUP); + if (F_ISSET(dbp, DB_AM_FIXEDLEN)) + F_SET(&meta->dbmeta, BTM_FIXEDLEN); + if (F_ISSET(dbp, DB_AM_RECNUM)) + F_SET(&meta->dbmeta, BTM_RECNUM); + if (F_ISSET(dbp, DB_AM_RENUMBER)) + F_SET(&meta->dbmeta, BTM_RENUMBER); + if (F_ISSET(dbp, DB_AM_SUBDB)) + F_SET(&meta->dbmeta, BTM_SUBDB); + if (dbp->dup_compare != NULL) + F_SET(&meta->dbmeta, BTM_DUPSORT); +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp)) + F_SET(&meta->dbmeta, BTM_COMPRESS); +#endif + if (dbp->type == DB_RECNO) + F_SET(&meta->dbmeta, BTM_RECNO); + memcpy(meta->dbmeta.uid, dbp->fileid, DB_FILE_ID_LEN); + + meta->minkey = t->bt_minkey; + meta->re_len = t->re_len; + meta->re_pad = (u_int32_t)t->re_pad; + +#ifdef HAVE_PARTITION + if ((part = dbp->p_internal) != NULL) { + meta->dbmeta.nparts = part->nparts; + if (F_ISSET(part, PART_CALLBACK)) + FLD_SET(meta->dbmeta.metaflags, DBMETA_PART_CALLBACK); + if (F_ISSET(part, PART_RANGE)) + FLD_SET(meta->dbmeta.metaflags, DBMETA_PART_RANGE); + } +#endif +} + +/* + * __bam_new_file -- + * Create the necessary pages to begin a new database file. + * + * This code appears more complex than it is because of the two cases (named + * and unnamed). The way to read the code is that for each page being created, + * there are three parts: 1) a "get page" chunk (which either uses malloc'd + * memory or calls __memp_fget), 2) the initialization, and 3) the "put page" + * chunk which either does a fop write or an __memp_fput. + * + * PUBLIC: int __bam_new_file __P((DB *, + * PUBLIC: DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *)); + */ +int +__bam_new_file(dbp, ip, txn, fhp, name) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + DB_FH *fhp; + const char *name; +{ + BTMETA *meta; + DBT pdbt; + DB_LSN lsn; + DB_MPOOLFILE *mpf; + DB_PGINFO pginfo; + ENV *env; + PAGE *root; + db_pgno_t pgno; + int ret, t_ret; + void *buf; + + env = dbp->env; + mpf = dbp->mpf; + root = NULL; + meta = NULL; + buf = NULL; + + if (F_ISSET(dbp, DB_AM_INMEM)) { + /* Build the meta-data page. */ + pgno = PGNO_BASE_MD; + if ((ret = __memp_fget(mpf, &pgno, ip, txn, + DB_MPOOL_CREATE | DB_MPOOL_DIRTY, &meta)) != 0) + return (ret); + LSN_NOT_LOGGED(lsn); + __bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn); + meta->root = 1; + meta->dbmeta.last_pgno = 1; + if ((ret = + __db_log_page(dbp, txn, &lsn, pgno, (PAGE *)meta)) != 0) + goto err; + ret = __memp_fput(mpf, ip, meta, dbp->priority); + meta = NULL; + if (ret != 0) + goto err; + + /* Build the root page. */ + pgno = 1; + if ((ret = __memp_fget(mpf, &pgno, + ip, txn, DB_MPOOL_CREATE, &root)) != 0) + goto err; + P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID, + LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE); + LSN_NOT_LOGGED(root->lsn); + if ((ret = + __db_log_page(dbp, txn, &root->lsn, pgno, root)) != 0) + goto err; + ret = __memp_fput(mpf, ip, root, dbp->priority); + root = NULL; + if (ret != 0) + goto err; + } else { + memset(&pdbt, 0, sizeof(pdbt)); + + /* Build the meta-data page. */ + pginfo.db_pagesize = dbp->pgsize; + pginfo.flags = + F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP)); + pginfo.type = dbp->type; + pdbt.data = &pginfo; + pdbt.size = sizeof(pginfo); + if ((ret = __os_calloc(env, 1, dbp->pgsize, &buf)) != 0) + return (ret); + meta = (BTMETA *)buf; + LSN_NOT_LOGGED(lsn); + __bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn); + meta->root = 1; + meta->dbmeta.last_pgno = 1; + if ((ret = __db_pgout( + dbp->dbenv, PGNO_BASE_MD, meta, &pdbt)) != 0) + goto err; + if ((ret = __fop_write(env, txn, name, dbp->dirname, + DB_APP_DATA, fhp, + dbp->pgsize, 0, 0, buf, dbp->pgsize, 1, F_ISSET( + dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0) + goto err; + meta = NULL; + + /* Build the root page. */ +#ifdef DIAGNOSTIC + memset(buf, CLEAR_BYTE, dbp->pgsize); +#endif + root = (PAGE *)buf; + P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID, + LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE); + LSN_NOT_LOGGED(root->lsn); + if ((ret = + __db_pgout(dbp->dbenv, root->pgno, root, &pdbt)) != 0) + goto err; + if ((ret = + __fop_write(env, txn, name, dbp->dirname, DB_APP_DATA, + fhp, dbp->pgsize, 1, 0, buf, dbp->pgsize, 1, F_ISSET( + dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0) + goto err; + root = NULL; + } + +err: if (buf != NULL) + __os_free(env, buf); + else { + if (meta != NULL && + (t_ret = __memp_fput(mpf, ip, + meta, dbp->priority)) != 0 && ret == 0) + ret = t_ret; + if (root != NULL && + (t_ret = __memp_fput(mpf, ip, + root, dbp->priority)) != 0 && ret == 0) + ret = t_ret; + } + return (ret); +} + +/* + * __bam_new_subdb -- + * Create a metadata page and a root page for a new btree. + * + * PUBLIC: int __bam_new_subdb __P((DB *, DB *, DB_THREAD_INFO *, DB_TXN *)); + */ +int +__bam_new_subdb(mdbp, dbp, ip, txn) + DB *mdbp, *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; +{ + BTMETA *meta; + DBC *dbc; + DB_LOCK metalock; + DB_LSN lsn; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *root; + int ret, t_ret; + + env = mdbp->env; + mpf = mdbp->mpf; + dbc = NULL; + meta = NULL; + root = NULL; + + if ((ret = __db_cursor(mdbp, ip, txn, + &dbc, CDB_LOCKING(env) ? DB_WRITECURSOR : 0)) != 0) + return (ret); + + /* Get, and optionally create the metadata page. */ + if ((ret = __db_lget(dbc, + 0, dbp->meta_pgno, DB_LOCK_WRITE, 0, &metalock)) != 0) + goto err; + if ((ret = __memp_fget(mpf, &dbp->meta_pgno, + ip, txn, DB_MPOOL_CREATE, &meta)) != 0) + goto err; + + /* Build meta-data page. */ + lsn = meta->dbmeta.lsn; + __bam_init_meta(dbp, meta, dbp->meta_pgno, &lsn); + if ((ret = __db_log_page(mdbp, + txn, &meta->dbmeta.lsn, dbp->meta_pgno, (PAGE *)meta)) != 0) + goto err; + + /* Create and initialize a root page. */ + if ((ret = __db_new(dbc, + dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE, NULL, &root)) != 0) + goto err; + root->level = LEAFLEVEL; + + if (DBENV_LOGGING(env) && +#if !defined(DEBUG_WOP) + txn != NULL && +#endif + + (ret = __bam_root_log(mdbp, txn, &meta->dbmeta.lsn, 0, + meta->dbmeta.pgno, root->pgno, &meta->dbmeta.lsn)) != 0) + goto err; + + meta->root = root->pgno; + if ((ret = + __db_log_page(mdbp, txn, &root->lsn, root->pgno, root)) != 0) + goto err; + + /* Release the metadata and root pages. */ + if ((ret = __memp_fput(mpf, ip, meta, dbc->priority)) != 0) + goto err; + meta = NULL; + if ((ret = __memp_fput(mpf, ip, root, dbc->priority)) != 0) + goto err; + root = NULL; +err: + if (meta != NULL) + if ((t_ret = __memp_fput(mpf, ip, + meta, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + if (root != NULL) + if ((t_ret = __memp_fput(mpf, ip, + root, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) + ret = t_ret; + if (dbc != NULL) + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_put.c b/src/libs/resiprocate/contrib/db/btree/bt_put.c new file mode 100644 index 00000000..683b09c7 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_put.c @@ -0,0 +1,1069 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" + +static int __bam_build + __P((DBC *, u_int32_t, DBT *, PAGE *, u_int32_t, u_int32_t)); +static int __bam_dup_check __P((DBC *, u_int32_t, + PAGE *, u_int32_t, u_int32_t, db_indx_t *)); +static int __bam_dup_convert __P((DBC *, PAGE *, u_int32_t, u_int32_t)); +static int __bam_ovput + __P((DBC *, u_int32_t, db_pgno_t, PAGE *, u_int32_t, DBT *)); +static u_int32_t + __bam_partsize __P((DB *, u_int32_t, DBT *, PAGE *, u_int32_t)); + +/* + * __bam_iitem -- + * Insert an item into the tree. + * + * PUBLIC: int __bam_iitem __P((DBC *, DBT *, DBT *, u_int32_t, u_int32_t)); + */ +int +__bam_iitem(dbc, key, data, op, flags) + DBC *dbc; + DBT *key, *data; + u_int32_t op, flags; +{ + BKEYDATA *bk, bk_tmp; + BTREE *t; + BTREE_CURSOR *cp; + DB *dbp; + DBT bk_hdr, tdbt; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *h; + db_indx_t cnt, indx; + u_int32_t data_size, have_bytes, need_bytes, needed, pages, pagespace; + char tmp_ch; + int cmp, bigkey, bigdata, del, dupadjust; + int padrec, replace, ret, t_ret, was_deleted; + + COMPQUIET(cnt, 0); + + dbp = dbc->dbp; + env = dbp->env; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + t = dbp->bt_internal; + h = cp->page; + indx = cp->indx; + del = dupadjust = replace = was_deleted = 0; + + /* + * Fixed-length records with partial puts: it's an error to specify + * anything other simple overwrite. + */ + if (F_ISSET(dbp, DB_AM_FIXEDLEN) && + F_ISSET(data, DB_DBT_PARTIAL) && data->size != data->dlen) + return (__db_rec_repl(env, data->size, data->dlen)); + + /* + * Figure out how much space the data will take, including if it's a + * partial record. + * + * Fixed-length records: it's an error to specify a record that's + * longer than the fixed-length, and we never require less than + * the fixed-length record size. + */ + data_size = F_ISSET(data, DB_DBT_PARTIAL) ? + __bam_partsize(dbp, op, data, h, indx) : data->size; + padrec = 0; + if (F_ISSET(dbp, DB_AM_FIXEDLEN)) { + if (data_size > t->re_len) + return (__db_rec_toobig(env, data_size, t->re_len)); + + /* Records that are deleted anyway needn't be padded out. */ + if (!LF_ISSET(BI_DELETED) && data_size < t->re_len) { + padrec = 1; + data_size = t->re_len; + } + } + + /* + * Handle partial puts or short fixed-length records: check whether we + * can just append the data or else build the real record. We can't + * append if there are secondaries: we need the whole data item for the + * application's secondary callback. + */ + if (op == DB_CURRENT && dbp->dup_compare == NULL && + F_ISSET(data, DB_DBT_PARTIAL) && !DB_IS_PRIMARY(dbp)) { + bk = GET_BKEYDATA( + dbp, h, indx + (TYPE(h) == P_LBTREE ? O_INDX : 0)); + /* + * If the item is an overflow type, and the input DBT is + * partial, and begins at the length of the current item then + * it is an append. Avoid deleting and re-creating the entire + * offpage item. + */ + if (B_TYPE(bk->type) == B_OVERFLOW && + data->doff == ((BOVERFLOW *)bk)->tlen) { + /* + * If the cursor has not already cached the last page + * in the offpage chain. We need to walk the chain + * to be sure that the page has been read. + */ + if (cp->stream_start_pgno != ((BOVERFLOW *)bk)->pgno || + cp->stream_off > data->doff || data->doff > + cp->stream_off + P_MAXSPACE(dbp, dbp->pgsize)) { + memset(&tdbt, 0, sizeof(DBT)); + tdbt.doff = data->doff - 1; + /* + * Set the length to 1, to force __db_goff + * to do the traversal. + */ + tdbt.dlen = tdbt.ulen = 1; + tdbt.data = &tmp_ch; + tdbt.flags = DB_DBT_PARTIAL | DB_DBT_USERMEM; + + /* + * Read to the last page. It will be cached + * in the cursor. + */ + if ((ret = __db_goff( + dbc, &tdbt, ((BOVERFLOW *)bk)->tlen, + ((BOVERFLOW *)bk)->pgno, NULL, NULL)) != 0) + return (ret); + } + + /* + * Since this is an append, dlen is irrelevant (there + * are no bytes to overwrite). We need the caller's + * DBT size to end up with the total size of the item. + * From now on, use dlen as the length of the user's + * data that we are going to append. + * Don't futz with the caller's DBT any more than we + * have to in order to send back the size. + */ + tdbt = *data; + tdbt.dlen = data->size; + tdbt.size = data_size; + data = &tdbt; + F_SET(data, DB_DBT_STREAMING); + } + } + if (!F_ISSET(data, DB_DBT_STREAMING) && + (padrec || F_ISSET(data, DB_DBT_PARTIAL))) { + tdbt = *data; + if ((ret = + __bam_build(dbc, op, &tdbt, h, indx, data_size)) != 0) + return (ret); + data = &tdbt; + } + + /* + * If the user has specified a duplicate comparison function, return + * an error if DB_CURRENT was specified and the replacement data + * doesn't compare equal to the current data. This stops apps from + * screwing up the duplicate sort order. We have to do this after + * we build the real record so that we're comparing the real items. + */ + if (op == DB_CURRENT && dbp->dup_compare != NULL) { + if ((ret = __bam_cmp(dbc, data, h, + indx + (TYPE(h) == P_LBTREE ? O_INDX : 0), + dbp->dup_compare, &cmp)) != 0) + return (ret); + if (cmp != 0) { + __db_errx(env, + "Existing data sorts differently from put data"); + return (EINVAL); + } + } + + /* + * If the key or data item won't fit on a page, we'll have to store + * them on overflow pages. + */ + needed = 0; + bigdata = data_size > cp->ovflsize; + switch (op) { + case DB_KEYFIRST: + /* We're adding a new key and data pair. */ + bigkey = key->size > cp->ovflsize; + if (bigkey) + needed += BOVERFLOW_PSIZE; + else + needed += BKEYDATA_PSIZE(key->size); + if (bigdata) + needed += BOVERFLOW_PSIZE; + else + needed += BKEYDATA_PSIZE(data_size); + break; + case DB_AFTER: + case DB_BEFORE: + case DB_CURRENT: + /* + * We're either overwriting the data item of a key/data pair + * or we're creating a new on-page duplicate and only adding + * a data item. + * + * !!! + * We're not currently correcting for space reclaimed from + * already deleted items, but I don't think it's worth the + * complexity. + */ + bigkey = 0; + if (op == DB_CURRENT) { + bk = GET_BKEYDATA(dbp, h, + indx + (TYPE(h) == P_LBTREE ? O_INDX : 0)); + if (B_TYPE(bk->type) == B_KEYDATA) + have_bytes = BKEYDATA_PSIZE(bk->len); + else + have_bytes = BOVERFLOW_PSIZE; + need_bytes = 0; + } else { + have_bytes = 0; + need_bytes = sizeof(db_indx_t); + } + if (bigdata) + need_bytes += BOVERFLOW_PSIZE; + else + need_bytes += BKEYDATA_PSIZE(data_size); + + if (have_bytes < need_bytes) + needed += need_bytes - have_bytes; + break; + default: + return (__db_unknown_flag(env, "DB->put", op)); + } + + /* Split the page if there's not enough room. */ + if (P_FREESPACE(dbp, h) < needed) + return (DB_NEEDSPLIT); + + /* + * Check to see if we will convert to off page duplicates -- if + * so, we'll need a page. + */ + if (F_ISSET(dbp, DB_AM_DUP) && + TYPE(h) == P_LBTREE && op != DB_KEYFIRST && + P_FREESPACE(dbp, h) - needed <= dbp->pgsize / 2 && + __bam_dup_check(dbc, op, h, indx, needed, &cnt)) { + pages = 1; + dupadjust = 1; + } else + pages = 0; + + /* + * If we are not using transactions and there is a page limit + * set on the file, then figure out if things will fit before + * taking action. + */ + if (dbc->txn == NULL && mpf->mfp->maxpgno != 0) { + pagespace = P_MAXSPACE(dbp, dbp->pgsize); + if (bigdata) + pages += ((data_size - 1) / pagespace) + 1; + if (bigkey) + pages += ((key->size - 1) / pagespace) + 1; + + if (pages > (mpf->mfp->maxpgno - mpf->mfp->last_pgno)) + return (__db_space_err(dbp)); + } + + ret = __memp_dirty(mpf, &h, + dbc->thread_info, dbc->txn, dbc->priority, 0); + if (cp->csp->page == cp->page) + cp->csp->page = h; + cp->page = h; + if (ret != 0) + return (ret); + + /* + * The code breaks it up into five cases: + * + * 1. Insert a new key/data pair. + * 2. Append a new data item (a new duplicate). + * 3. Insert a new data item (a new duplicate). + * 4. Delete and re-add the data item (overflow item). + * 5. Overwrite the data item. + */ + switch (op) { + case DB_KEYFIRST: /* 1. Insert a new key/data pair. */ + if (bigkey) { + if ((ret = __bam_ovput(dbc, + B_OVERFLOW, PGNO_INVALID, h, indx, key)) != 0) + return (ret); + } else + if ((ret = __db_pitem(dbc, h, indx, + BKEYDATA_SIZE(key->size), NULL, key)) != 0) + return (ret); + + if ((ret = __bam_ca_di(dbc, PGNO(h), indx, 1)) != 0) + return (ret); + ++indx; + break; + case DB_AFTER: /* 2. Append a new data item. */ + if (TYPE(h) == P_LBTREE) { + /* Copy the key for the duplicate and adjust cursors. */ + if ((ret = + __bam_adjindx(dbc, h, indx + P_INDX, indx, 1)) != 0) + return (ret); + if ((ret = + __bam_ca_di(dbc, PGNO(h), indx + P_INDX, 1)) != 0) + return (ret); + + indx += 3; + + cp->indx += 2; + } else { + ++indx; + cp->indx += 1; + } + break; + case DB_BEFORE: /* 3. Insert a new data item. */ + if (TYPE(h) == P_LBTREE) { + /* Copy the key for the duplicate and adjust cursors. */ + if ((ret = __bam_adjindx(dbc, h, indx, indx, 1)) != 0) + return (ret); + if ((ret = __bam_ca_di(dbc, PGNO(h), indx, 1)) != 0) + return (ret); + + ++indx; + } + break; + case DB_CURRENT: + /* + * Clear the cursor's deleted flag. The problem is that if + * we deadlock or fail while deleting the overflow item or + * replacing the non-overflow item, a subsequent cursor close + * will try and remove the item because the cursor's delete + * flag is set. + */ + if ((ret = __bam_ca_delete(dbp, PGNO(h), indx, 0, NULL)) != 0) + return (ret); + + if (TYPE(h) == P_LBTREE) + ++indx; + bk = GET_BKEYDATA(dbp, h, indx); + + /* + * In a Btree deleted records aren't counted (deleted records + * are counted in a Recno because all accesses are based on + * record number). If it's a Btree and it's a DB_CURRENT + * operation overwriting a previously deleted record, increment + * the record count. + */ + if (TYPE(h) == P_LBTREE || TYPE(h) == P_LDUP) + was_deleted = B_DISSET(bk->type); + + /* + * 4. Delete and re-add the data item. + * + * If we're changing the type of the on-page structure, or we + * are referencing offpage items, we have to delete and then + * re-add the item. We do not do any cursor adjustments here + * because we're going to immediately re-add the item into the + * same slot. + */ + if (bigdata || B_TYPE(bk->type) != B_KEYDATA) { + /* + * If streaming, don't delete the overflow item, + * just delete the item pointing to the overflow item. + * It will be added back in later, with the new size. + * We can't simply adjust the size of the item on the + * page, because there is no easy way to log a + * modification. + */ + if (F_ISSET(data, DB_DBT_STREAMING)) { + if ((ret = __db_ditem( + dbc, h, indx, BOVERFLOW_SIZE)) != 0) + return (ret); + } else if ((ret = __bam_ditem(dbc, h, indx)) != 0) + return (ret); + del = 1; + break; + } + + /* 5. Overwrite the data item. */ + replace = 1; + break; + default: + return (__db_unknown_flag(env, "DB->put", op)); + } + + /* Add the data. */ + if (bigdata) { + /* + * We do not have to handle deleted (BI_DELETED) records + * in this case; the actual records should never be created. + */ + DB_ASSERT(env, !LF_ISSET(BI_DELETED)); + ret = __bam_ovput(dbc, + B_OVERFLOW, PGNO_INVALID, h, indx, data); + } else { + if (LF_ISSET(BI_DELETED)) { + B_TSET_DELETED(bk_tmp.type, B_KEYDATA); + bk_tmp.len = data->size; + bk_hdr.data = &bk_tmp; + bk_hdr.size = SSZA(BKEYDATA, data); + ret = __db_pitem(dbc, h, indx, + BKEYDATA_SIZE(data->size), &bk_hdr, data); + } else if (replace) + ret = __bam_ritem(dbc, h, indx, data, 0); + else + ret = __db_pitem(dbc, h, indx, + BKEYDATA_SIZE(data->size), NULL, data); + } + if (ret != 0) { + if (del == 1 && (t_ret = + __bam_ca_di(dbc, PGNO(h), indx + 1, -1)) != 0) { + __db_err(env, t_ret, + "cursor adjustment after delete failed"); + return (__env_panic(env, t_ret)); + } + return (ret); + } + + /* + * Re-position the cursors if necessary and reset the current cursor + * to point to the new item. + */ + if (op != DB_CURRENT) { + if ((ret = __bam_ca_di(dbc, PGNO(h), indx, 1)) != 0) + return (ret); + cp->indx = TYPE(h) == P_LBTREE ? indx - O_INDX : indx; + } + + /* + * If we've changed the record count, update the tree. There's no + * need to adjust the count if the operation not performed on the + * current record or when the current record was previously deleted. + */ + if (F_ISSET(cp, C_RECNUM) && (op != DB_CURRENT || was_deleted)) + if ((ret = __bam_adjust(dbc, 1)) != 0) + return (ret); + + /* + * If a Btree leaf page is at least 50% full and we may have added or + * modified a duplicate data item, see if the set of duplicates takes + * up at least 25% of the space on the page. If it does, move it onto + * its own page. + */ + if (dupadjust && + (ret = __bam_dup_convert(dbc, h, indx - O_INDX, cnt)) != 0) + return (ret); + + /* If we've modified a recno file, set the flag. */ + if (dbc->dbtype == DB_RECNO) + t->re_modified = 1; + + return (ret); +} + +/* + * __bam_partsize -- + * Figure out how much space a partial data item is in total. + */ +static u_int32_t +__bam_partsize(dbp, op, data, h, indx) + DB *dbp; + u_int32_t op, indx; + DBT *data; + PAGE *h; +{ + BKEYDATA *bk; + u_int32_t nbytes; + + /* + * If the record doesn't already exist, it's simply the data we're + * provided. + */ + if (op != DB_CURRENT) + return (data->doff + data->size); + + /* + * Otherwise, it's the data provided plus any already existing data + * that we're not replacing. + */ + bk = GET_BKEYDATA(dbp, h, indx + (TYPE(h) == P_LBTREE ? O_INDX : 0)); + nbytes = + B_TYPE(bk->type) == B_OVERFLOW ? ((BOVERFLOW *)bk)->tlen : bk->len; + + return (__db_partsize(nbytes, data)); +} + +/* + * __bam_build -- + * Build the real record for a partial put, or short fixed-length record. + */ +static int +__bam_build(dbc, op, dbt, h, indx, nbytes) + DBC *dbc; + u_int32_t op, indx, nbytes; + DBT *dbt; + PAGE *h; +{ + BKEYDATA *bk, tbk; + BOVERFLOW *bo; + BTREE *t; + DB *dbp; + DBT copy, *rdata; + u_int32_t len, tlen; + u_int8_t *p; + int ret; + + COMPQUIET(bo, NULL); + + dbp = dbc->dbp; + t = dbp->bt_internal; + + /* We use the record data return memory, it's only a short-term use. */ + rdata = &dbc->my_rdata; + if (rdata->ulen < nbytes) { + if ((ret = __os_realloc(dbp->env, + nbytes, &rdata->data)) != 0) { + rdata->ulen = 0; + rdata->data = NULL; + return (ret); + } + rdata->ulen = nbytes; + } + + /* + * We use nul or pad bytes for any part of the record that isn't + * specified; get it over with. + */ + memset(rdata->data, + F_ISSET(dbp, DB_AM_FIXEDLEN) ? t->re_pad : 0, nbytes); + + /* + * In the next clauses, we need to do three things: a) set p to point + * to the place at which to copy the user's data, b) set tlen to the + * total length of the record, not including the bytes contributed by + * the user, and c) copy any valid data from an existing record. If + * it's not a partial put (this code is called for both partial puts + * and fixed-length record padding) or it's a new key, we can cut to + * the chase. + */ + if (!F_ISSET(dbt, DB_DBT_PARTIAL) || op != DB_CURRENT) { + p = (u_int8_t *)rdata->data + dbt->doff; + tlen = dbt->doff; + goto user_copy; + } + + /* Find the current record. */ + if (indx < NUM_ENT(h)) { + bk = GET_BKEYDATA(dbp, h, indx + (TYPE(h) == P_LBTREE ? + O_INDX : 0)); + bo = (BOVERFLOW *)bk; + } else { + bk = &tbk; + B_TSET(bk->type, B_KEYDATA); + bk->len = 0; + } + if (B_TYPE(bk->type) == B_OVERFLOW) { + /* + * In the case of an overflow record, we shift things around + * in the current record rather than allocate a separate copy. + */ + memset(©, 0, sizeof(copy)); + if ((ret = __db_goff(dbc, ©, bo->tlen, bo->pgno, + &rdata->data, &rdata->ulen)) != 0) + return (ret); + + /* Skip any leading data from the original record. */ + tlen = dbt->doff; + p = (u_int8_t *)rdata->data + dbt->doff; + + /* + * Copy in any trailing data from the original record. + * + * If the original record was larger than the original offset + * plus the bytes being deleted, there is trailing data in the + * original record we need to preserve. If we aren't deleting + * the same number of bytes as we're inserting, copy it up or + * down, into place. + * + * Use memmove(), the regions may overlap. + */ + if (bo->tlen > dbt->doff + dbt->dlen) { + len = bo->tlen - (dbt->doff + dbt->dlen); + if (dbt->dlen != dbt->size) + memmove(p + dbt->size, p + dbt->dlen, len); + tlen += len; + } + } else { + /* Copy in any leading data from the original record. */ + memcpy(rdata->data, + bk->data, dbt->doff > bk->len ? bk->len : dbt->doff); + tlen = dbt->doff; + p = (u_int8_t *)rdata->data + dbt->doff; + + /* Copy in any trailing data from the original record. */ + len = dbt->doff + dbt->dlen; + if (bk->len > len) { + memcpy(p + dbt->size, bk->data + len, bk->len - len); + tlen += bk->len - len; + } + } + +user_copy: + /* + * Copy in the application provided data -- p and tlen must have been + * initialized above. + */ + memcpy(p, dbt->data, dbt->size); + tlen += dbt->size; + + /* Set the DBT to reference our new record. */ + rdata->size = F_ISSET(dbp, DB_AM_FIXEDLEN) ? t->re_len : tlen; + rdata->dlen = 0; + rdata->doff = 0; + rdata->flags = 0; + *dbt = *rdata; + return (0); +} + +/* + * __bam_ritem -- + * Replace an item on a page. + * + * PUBLIC: int __bam_ritem __P((DBC *, PAGE *, u_int32_t, DBT *, u_int32_t)); + */ +int +__bam_ritem(dbc, h, indx, data, typeflag) + DBC *dbc; + PAGE *h; + u_int32_t indx; + DBT *data; + u_int32_t typeflag; +{ + BKEYDATA *bk; + BINTERNAL *bi; + DB *dbp; + DBT orig, repl; + db_indx_t cnt, lo, ln, min, off, prefix, suffix; + int32_t nbytes; + u_int32_t len; + int ret; + db_indx_t *inp; + u_int8_t *dp, *p, *t, type; + + dbp = dbc->dbp; + bi = NULL; + bk = NULL; + + /* + * Replace a single item onto a page. The logic figuring out where + * to insert and whether it fits is handled in the caller. All we do + * here is manage the page shuffling. + */ + if (TYPE(h) == P_IBTREE) { + /* Point at the part of the internal struct past the type. */ + bi = GET_BINTERNAL(dbp, h, indx); + if (B_TYPE(bi->type) == B_OVERFLOW) + len = BOVERFLOW_SIZE; + else + len = bi->len; + len += SSZA(BINTERNAL, data) - SSZ(BINTERNAL, unused); + dp = &bi->unused; + type = typeflag == 0 ? bi->type : + (bi->type == B_KEYDATA ? B_OVERFLOW : B_KEYDATA); + } else { + bk = GET_BKEYDATA(dbp, h, indx); + len = bk->len; + dp = bk->data; + type = bk->type; + typeflag = B_DISSET(type); + } + + /* Log the change. */ + if (DBC_LOGGING(dbc)) { + /* + * We might as well check to see if the two data items share + * a common prefix and suffix -- it can save us a lot of log + * message if they're large. + */ + min = data->size < len ? data->size : len; + for (prefix = 0, + p = dp, t = data->data; + prefix < min && *p == *t; ++prefix, ++p, ++t) + ; + + min -= prefix; + for (suffix = 0, + p = (u_int8_t *)dp + len - 1, + t = (u_int8_t *)data->data + data->size - 1; + suffix < min && *p == *t; ++suffix, --p, --t) + ; + + /* We only log the parts of the keys that have changed. */ + orig.data = (u_int8_t *)dp + prefix; + orig.size = len - (prefix + suffix); + repl.data = (u_int8_t *)data->data + prefix; + repl.size = data->size - (prefix + suffix); + if ((ret = __bam_repl_log(dbp, dbc->txn, &LSN(h), 0, PGNO(h), + &LSN(h), (u_int32_t)indx, typeflag, + &orig, &repl, (u_int32_t)prefix, (u_int32_t)suffix)) != 0) + return (ret); + } else + LSN_NOT_LOGGED(LSN(h)); + + /* + * Set references to the first in-use byte on the page and the + * first byte of the item being replaced. + */ + inp = P_INP(dbp, h); + p = (u_int8_t *)h + HOFFSET(h); + if (TYPE(h) == P_IBTREE) { + t = (u_int8_t *)bi; + lo = (db_indx_t)BINTERNAL_SIZE(bi->len); + ln = (db_indx_t)BINTERNAL_SIZE(data->size - + (SSZA(BINTERNAL, data) - SSZ(BINTERNAL, unused))); + } else { + t = (u_int8_t *)bk; + lo = (db_indx_t)BKEYDATA_SIZE(bk->len); + ln = (db_indx_t)BKEYDATA_SIZE(data->size); + } + + /* + * If the entry is growing in size, shift the beginning of the data + * part of the page down. If the entry is shrinking in size, shift + * the beginning of the data part of the page up. Use memmove(3), + * the regions overlap. + */ + if (lo != ln) { + nbytes = lo - ln; /* Signed difference. */ + if (p == t) /* First index is fast. */ + inp[indx] += nbytes; + else { /* Else, shift the page. */ + memmove(p + nbytes, p, (size_t)(t - p)); + + /* Adjust the indices' offsets. */ + off = inp[indx]; + for (cnt = 0; cnt < NUM_ENT(h); ++cnt) + if (inp[cnt] <= off) + inp[cnt] += nbytes; + } + + /* Clean up the page and adjust the item's reference. */ + HOFFSET(h) += nbytes; + t += nbytes; + } + + /* Copy the new item onto the page. */ + bk = (BKEYDATA *)t; + bk->len = data->size; + B_TSET(bk->type, type); + memcpy(bk->data, data->data, bk->len); + + /* Remove the length of the internal header elements. */ + if (TYPE(h) == P_IBTREE) + bk->len -= SSZA(BINTERNAL, data) - SSZ(BINTERNAL, unused); + + return (0); +} + +/* + * __bam_irep -- + * Replace an item on an internal page. + * + * PUBLIC: int __bam_irep __P((DBC *, PAGE *, u_int32_t, DBT *, DBT *)); + */ +int +__bam_irep(dbc, h, indx, hdr, data) + DBC *dbc; + PAGE *h; + u_int32_t indx; + DBT *hdr; + DBT *data; +{ + BINTERNAL *bi, *bn; + DB *dbp; + DBT dbt; + int ret; + + dbp = dbc->dbp; + + bi = GET_BINTERNAL(dbp, h, indx); + bn = (BINTERNAL *) hdr->data; + + if (B_TYPE(bi->type) == B_OVERFLOW && + (ret = __db_doff(dbc, ((BOVERFLOW *)bi->data)->pgno)) != 0) + return (ret); + + memset(&dbt, 0, sizeof(dbt)); + dbt.size = hdr->size + data->size - SSZ(BINTERNAL, unused); + if ((ret = __os_malloc(dbp->env, dbt.size, &dbt.data)) != 0) + return (ret); + memcpy(dbt.data, + (u_int8_t *)hdr->data + SSZ(BINTERNAL, unused), + hdr->size - SSZ(BINTERNAL, unused)); + memcpy((u_int8_t *)dbt.data + + hdr->size - SSZ(BINTERNAL, unused), data->data, data->size); + + ret = __bam_ritem(dbc, h, indx, &dbt, bi->type != bn->type); + + __os_free(dbp->env, dbt.data); + return (ret); +} + +/* + * __bam_dup_check -- + * Check to see if the duplicate set at indx should have its own page. + */ +static int +__bam_dup_check(dbc, op, h, indx, sz, cntp) + DBC *dbc; + u_int32_t op; + PAGE *h; + u_int32_t indx, sz; + db_indx_t *cntp; +{ + BKEYDATA *bk; + DB *dbp; + db_indx_t cnt, first, *inp; + + dbp = dbc->dbp; + inp = P_INP(dbp, h); + + /* + * Count the duplicate records and calculate how much room they're + * using on the page. + */ + while (indx > 0 && inp[indx] == inp[indx - P_INDX]) + indx -= P_INDX; + + /* Count the key once. */ + bk = GET_BKEYDATA(dbp, h, indx); + sz += B_TYPE(bk->type) == B_KEYDATA ? + BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE; + + /* Sum up all the data items. */ + first = indx; + + /* + * Account for the record being inserted. If we are replacing it, + * don't count it twice. + * + * We execute the loop with first == indx to get the size of the + * first record. + */ + cnt = op == DB_CURRENT ? 0 : 1; + for (first = indx; + indx < NUM_ENT(h) && inp[first] == inp[indx]; + ++cnt, indx += P_INDX) { + bk = GET_BKEYDATA(dbp, h, indx + O_INDX); + sz += B_TYPE(bk->type) == B_KEYDATA ? + BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE; + } + + /* + * We have to do these checks when the user is replacing the cursor's + * data item -- if the application replaces a duplicate item with a + * larger data item, it can increase the amount of space used by the + * duplicates, requiring this check. But that means we may have done + * this check when it wasn't a duplicate item after all. + */ + if (cnt == 1) + return (0); + + /* + * If this set of duplicates is using more than 25% of the page, move + * them off. The choice of 25% is a WAG, but the value must be small + * enough that we can always split a page without putting duplicates + * on two different pages. + */ + if (sz < dbp->pgsize / 4) + return (0); + + *cntp = cnt; + return (1); +} + +/* + * __bam_dup_convert -- + * Move a set of duplicates off-page and into their own tree. + */ +static int +__bam_dup_convert(dbc, h, indx, cnt) + DBC *dbc; + PAGE *h; + u_int32_t indx, cnt; +{ + BKEYDATA *bk; + DB *dbp; + DBT hdr; + DB_LOCK lock; + DB_MPOOLFILE *mpf; + PAGE *dp; + db_indx_t cpindx, dindx, first, *inp; + int ret, t_ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + inp = P_INP(dbp, h); + + /* Move to the beginning of the dup set. */ + while (indx > 0 && inp[indx] == inp[indx - P_INDX]) + indx -= P_INDX; + + /* Get a new page. */ + if ((ret = __db_new(dbc, + dbp->dup_compare == NULL ? P_LRECNO : P_LDUP, &lock, &dp)) != 0) + return (ret); + P_INIT(dp, dbp->pgsize, dp->pgno, + PGNO_INVALID, PGNO_INVALID, LEAFLEVEL, TYPE(dp)); + + /* + * Move this set of duplicates off the page. First points to the first + * key of the first duplicate key/data pair, cnt is the number of pairs + * we're dealing with. + */ + memset(&hdr, 0, sizeof(hdr)); + first = indx; + dindx = indx; + cpindx = 0; + do { + /* Move cursors referencing the old entry to the new entry. */ + if ((ret = __bam_ca_dup(dbc, first, + PGNO(h), indx, PGNO(dp), cpindx)) != 0) + goto err; + + /* + * Copy the entry to the new page. If the off-duplicate page + * If the off-duplicate page is a Btree page (i.e. dup_compare + * will be non-NULL, we use Btree pages for sorted dups, + * and Recno pages for unsorted dups), move all entries + * normally, even deleted ones. If it's a Recno page, + * deleted entries are discarded (if the deleted entry is + * overflow, then free up those pages). + */ + bk = GET_BKEYDATA(dbp, h, dindx + 1); + hdr.data = bk; + hdr.size = B_TYPE(bk->type) == B_KEYDATA ? + BKEYDATA_SIZE(bk->len) : BOVERFLOW_SIZE; + if (dbp->dup_compare == NULL && B_DISSET(bk->type)) { + /* + * Unsorted dups, i.e. recno page, and we have + * a deleted entry, don't move it, but if it was + * an overflow entry, we need to free those pages. + */ + if (B_TYPE(bk->type) == B_OVERFLOW && + (ret = __db_doff(dbc, + (GET_BOVERFLOW(dbp, h, dindx + 1))->pgno)) != 0) + goto err; + } else { + if ((ret = __db_pitem( + dbc, dp, cpindx, hdr.size, &hdr, NULL)) != 0) + goto err; + ++cpindx; + } + /* Delete all but the last reference to the key. */ + if (cnt != 1) { + if ((ret = __bam_adjindx(dbc, + h, dindx, first + 1, 0)) != 0) + goto err; + } else + dindx++; + + /* Delete the data item. */ + if ((ret = __db_ditem(dbc, h, dindx, hdr.size)) != 0) + goto err; + indx += P_INDX; + } while (--cnt); + + /* Put in a new data item that points to the duplicates page. */ + if ((ret = __bam_ovput(dbc, + B_DUPLICATE, dp->pgno, h, first + 1, NULL)) != 0) + goto err; + + /* Adjust cursors for all the above movements. */ + ret = __bam_ca_di(dbc, + PGNO(h), first + P_INDX, (int)(first + P_INDX - indx)); + +err: if ((t_ret = __memp_fput(mpf, + dbc->thread_info, dp, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + + (void)__TLPUT(dbc, lock); + return (ret); +} + +/* + * __bam_ovput -- + * Build an item for an off-page duplicates page or overflow page and + * insert it on the page. + */ +static int +__bam_ovput(dbc, type, pgno, h, indx, item) + DBC *dbc; + u_int32_t type, indx; + db_pgno_t pgno; + PAGE *h; + DBT *item; +{ + BOVERFLOW bo; + DBT hdr; + int ret; + + UMRW_SET(bo.unused1); + B_TSET(bo.type, type); + UMRW_SET(bo.unused2); + + /* + * If we're creating an overflow item, do so and acquire the page + * number for it. If we're creating an off-page duplicates tree, + * we are giving the page number as an argument. + */ + if (type == B_OVERFLOW) { + if ((ret = __db_poff(dbc, item, &bo.pgno)) != 0) + return (ret); + bo.tlen = item->size; + } else { + bo.pgno = pgno; + bo.tlen = 0; + } + + /* Store the new record on the page. */ + memset(&hdr, 0, sizeof(hdr)); + hdr.data = &bo; + hdr.size = BOVERFLOW_SIZE; + return (__db_pitem(dbc, h, indx, BOVERFLOW_SIZE, &hdr, NULL)); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_rec.c b/src/libs/resiprocate/contrib/db/btree/bt_rec.c new file mode 100644 index 00000000..9650d922 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_rec.c @@ -0,0 +1,2035 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" + +#define IS_BTREE_PAGE(pagep) \ + (TYPE(pagep) == P_IBTREE || \ + TYPE(pagep) == P_LBTREE || TYPE(pagep) == P_LDUP) + +/* + * __bam_split_recover -- + * Recovery function for split. + * + * PUBLIC: int __bam_split_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_split_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_split_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_LSN *plsnp; + DB_MPOOLFILE *mpf; + PAGE *_lp, *lp, *np, *pp, *_rp, *rp, *sp; + db_pgno_t pgno, parent_pgno; + u_int32_t ptype, size; + int cmp, l_update, p_update, r_update, ret, rootsplit, t_ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__bam_split_print); + + _lp = lp = np = pp = _rp = rp = NULL; + sp = NULL; + + REC_INTRO(__bam_split_read, ip, 0); + + if ((ret = __db_cursor_int(file_dbp, ip, NULL, + (argp->opflags & SPL_RECNO) ? DB_RECNO : DB_BTREE, + PGNO_INVALID, 0, NULL, &dbc)) != 0) + goto out; + if (argp->opflags & SPL_NRECS) + F_SET((BTREE_CURSOR *)dbc->internal, C_RECNUM); + F_SET(dbc, DBC_RECOVER); + + /* + * There are two kinds of splits that we have to recover from. The + * first is a root-page split, where the root page is split from a + * leaf page into an internal page and two new leaf pages are created. + * The second is where a page is split into two pages, and a new key + * is inserted into the parent page. + * + * DBTs are not aligned in log records, so we need to copy the page + * so that we can access fields within it throughout this routine. + * Although we could hardcode the unaligned copies in this routine, + * we will be calling into regular btree functions with this page, + * so it's got to be aligned. Copying it into allocated memory is + * the only way to guarantee this. + */ + if ((ret = __os_malloc(env, argp->pg.size, &sp)) != 0) + goto out; + memcpy(sp, argp->pg.data, argp->pg.size); + + pgno = PGNO(sp); + parent_pgno = argp->ppgno; + rootsplit = parent_pgno == pgno; + + /* Get the pages going down the tree. */ + REC_FGET(mpf, ip, parent_pgno, &pp, left); +left: REC_FGET(mpf, ip, argp->left, &lp, right); +right: REC_FGET(mpf, ip, argp->right, &rp, redo); + +redo: if (DB_REDO(op)) { + l_update = r_update = p_update = 0; + /* + * Decide if we need to resplit the page. + * + * If this is a root split, then the root has to exist unless + * we have truncated it due to a future deallocation. + */ + if (pp != NULL) { + if (rootsplit) + plsnp = &LSN(argp->pg.data); + else + plsnp = &argp->plsn; + cmp = LOG_COMPARE(&LSN(pp), plsnp); + CHECK_LSN(env, op, cmp, &LSN(pp), plsnp); + if (cmp == 0) + p_update = 1; + } + + if (lp != NULL) { + cmp = LOG_COMPARE(&LSN(lp), &argp->llsn); + CHECK_LSN(env, op, cmp, &LSN(lp), &argp->llsn); + if (cmp == 0) + l_update = 1; + } + + if (rp != NULL) { + cmp = LOG_COMPARE(&LSN(rp), &argp->rlsn); + CHECK_LSN(env, op, cmp, &LSN(rp), &argp->rlsn); + if (cmp == 0) + r_update = 1; + } + + if (!p_update && !l_update && !r_update) + goto check_next; + + /* Allocate and initialize new left/right child pages. */ + if ((ret = __os_malloc(env, file_dbp->pgsize, &_lp)) != 0 || + (ret = __os_malloc(env, file_dbp->pgsize, &_rp)) != 0) + goto out; + if (rootsplit) { + P_INIT(_lp, file_dbp->pgsize, argp->left, + PGNO_INVALID, + ISINTERNAL(sp) ? PGNO_INVALID : argp->right, + LEVEL(sp), TYPE(sp)); + P_INIT(_rp, file_dbp->pgsize, argp->right, + ISINTERNAL(sp) ? PGNO_INVALID : argp->left, + PGNO_INVALID, LEVEL(sp), TYPE(sp)); + } else { + P_INIT(_lp, file_dbp->pgsize, PGNO(sp), + ISINTERNAL(sp) ? PGNO_INVALID : PREV_PGNO(sp), + ISINTERNAL(sp) ? PGNO_INVALID : argp->right, + LEVEL(sp), TYPE(sp)); + P_INIT(_rp, file_dbp->pgsize, argp->right, + ISINTERNAL(sp) ? PGNO_INVALID : sp->pgno, + ISINTERNAL(sp) ? PGNO_INVALID : NEXT_PGNO(sp), + LEVEL(sp), TYPE(sp)); + } + + /* Split the page. */ + if ((ret = __bam_copy(file_dbp, sp, _lp, 0, argp->indx)) != 0 || + (ret = __bam_copy(file_dbp, sp, _rp, argp->indx, + NUM_ENT(sp))) != 0) + goto out; + + if (l_update) { + REC_DIRTY(mpf, ip, file_dbp->priority, &lp); + memcpy(lp, _lp, file_dbp->pgsize); + lp->lsn = *lsnp; + } + + if (r_update) { + REC_DIRTY(mpf, ip, file_dbp->priority, &rp); + memcpy(rp, _rp, file_dbp->pgsize); + rp->lsn = *lsnp; + } + + /* + * Drop the latches on the lower level pages before + * getting an exclusive latch on the higher level page. + */ + if (lp != NULL && (ret = __memp_fput(mpf, + ip, lp, file_dbp->priority)) && ret == 0) + goto out; + lp = NULL; + if (rp != NULL && (ret = __memp_fput(mpf, + ip, rp, file_dbp->priority)) && ret == 0) + goto out; + rp = NULL; + /* + * If the parent page is wrong, update it. + * Initialize the page. If it is a root page update + * the record counts if needed and put the first record in. + * Then insert the record for the right hand child page. + */ + if (p_update) { + REC_DIRTY(mpf, ip, file_dbp->priority, &pp); + if (argp->opflags & SPL_RECNO) + ptype = P_IRECNO; + else + ptype = P_IBTREE; + + if (rootsplit) { + P_INIT(pp, file_dbp->pgsize, pgno, PGNO_INVALID, + PGNO_INVALID, _lp->level + 1, ptype); + if (argp->opflags & SPL_NRECS) { + RE_NREC_SET(pp, + __bam_total(file_dbp, _lp) + + __bam_total(file_dbp, _rp)); + } + if ((ret = __db_pitem_nolog(dbc, pp, + argp->pindx, argp->pentry.size, + &argp->pentry, NULL)) != 0) + goto out; + + } + if ((ret = __db_pitem_nolog(dbc, pp, argp->pindx + 1, + argp->rentry.size, &argp->rentry, NULL)) != 0) + goto out; + pp->lsn = *lsnp; + } + +check_next: /* + * Finally, redo the next-page link if necessary. This is of + * interest only if it wasn't a root split -- inserting a new + * page in the tree requires that any following page have its + * previous-page pointer updated to our new page. The next + * page must exist because we're redoing the operation. + */ + if (!rootsplit && argp->npgno != PGNO_INVALID) { + REC_FGET(mpf, ip, argp->npgno, &np, done); + cmp = LOG_COMPARE(&LSN(np), &argp->nlsn); + CHECK_LSN(env, op, cmp, &LSN(np), &argp->nlsn); + if (cmp == 0) { + REC_DIRTY(mpf, ip, file_dbp->priority, &np); + PREV_PGNO(np) = argp->right; + np->lsn = *lsnp; + } + } + } else { + /* + * If it's a root split and the left child ever existed, update + * its LSN. Otherwise its the split page. If + * right child ever existed, root split or not, update its LSN. + * The undo of the page allocation(s) will restore them to the + * free list. + */ + if (rootsplit && lp != NULL && + LOG_COMPARE(lsnp, &LSN(lp)) == 0) { + REC_DIRTY(mpf, ip, file_dbp->priority, &lp); + lp->lsn = argp->llsn; + } + if (rp != NULL && + LOG_COMPARE(lsnp, &LSN(rp)) == 0) { + REC_DIRTY(mpf, ip, file_dbp->priority, &rp); + rp->lsn = argp->rlsn; + } + /* + * Drop the lower level pages before getting an exclusive + * latch on the parent. + */ + if (rp != NULL && (ret = __memp_fput(mpf, + ip, rp, file_dbp->priority))) + goto out; + rp = NULL; + + /* + * Check the state of the split page. If its a rootsplit + * then thats the rootpage otherwise its the left page. + */ + if (rootsplit) { + DB_ASSERT(env, pgno == argp->ppgno); + if (lp != NULL && (ret = __memp_fput(mpf, ip, + lp, file_dbp->priority)) != 0) + goto out; + lp = pp; + pp = NULL; + } + if (lp != NULL) { + cmp = LOG_COMPARE(lsnp, &LSN(lp)); + CHECK_ABORT(env, op, cmp, &LSN(lp), lsnp); + if (cmp == 0) { + REC_DIRTY(mpf, ip, file_dbp->priority, &lp); + memcpy(lp, argp->pg.data, argp->pg.size); + if ((ret = __memp_fput(mpf, + ip, lp, file_dbp->priority))) + goto out; + lp = NULL; + } + } + + /* + * Next we can update the parent removing the new index. + */ + if (pp != NULL) { + DB_ASSERT(env, !rootsplit); + cmp = LOG_COMPARE(lsnp, &LSN(pp)); + CHECK_ABORT(env, op, cmp, &LSN(pp), lsnp); + if (cmp == 0) { + REC_DIRTY(mpf, ip, file_dbp->priority, &pp); + if (argp->opflags & SPL_RECNO) + size = RINTERNAL_SIZE; + else + size = BINTERNAL_SIZE( + GET_BINTERNAL(file_dbp, + pp, argp->pindx + 1)->len); + + if ((ret = __db_ditem(dbc, pp, + argp->pindx + 1, size)) != 0) + goto out; + pp->lsn = argp->plsn; + } + } + + /* + * Finally, undo the next-page link if necessary. This is of + * interest only if it wasn't a root split -- inserting a new + * page in the tree requires that any following page have its + * previous-page pointer updated to our new page. Since it's + * possible that the next-page never existed, we ignore it as + * if there's nothing to undo. + */ + if (!rootsplit && argp->npgno != PGNO_INVALID) { + if ((ret = __memp_fget(mpf, &argp->npgno, + ip, NULL, DB_MPOOL_EDIT, &np)) != 0) { + np = NULL; + goto done; + } + if (LOG_COMPARE(lsnp, &LSN(np)) == 0) { + REC_DIRTY(mpf, ip, file_dbp->priority, &np); + PREV_PGNO(np) = argp->left; + np->lsn = argp->nlsn; + } + } + } + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: /* Free any pages that are left. */ + if (lp != NULL && (t_ret = __memp_fput(mpf, + ip, lp, file_dbp->priority)) != 0 && ret == 0) + ret = t_ret; + if (np != NULL && (t_ret = __memp_fput(mpf, + ip, np, file_dbp->priority)) != 0 && ret == 0) + ret = t_ret; + if (rp != NULL && (t_ret = __memp_fput(mpf, + ip, rp, file_dbp->priority)) != 0 && ret == 0) + ret = t_ret; + if (pp != NULL && (t_ret = __memp_fput(mpf, + ip, pp, file_dbp->priority)) != 0 && ret == 0) + ret = t_ret; + + /* Free any allocated space. */ + if (_lp != NULL) + __os_free(env, _lp); + if (_rp != NULL) + __os_free(env, _rp); + if (sp != NULL) + __os_free(env, sp); + + REC_CLOSE; +} +/* + * __bam_split_recover -- + * Recovery function for split. + * + * PUBLIC: int __bam_split_42_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_split_42_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_split_42_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *_lp, *lp, *np, *pp, *_rp, *rp, *sp; + db_pgno_t pgno, root_pgno; + u_int32_t ptype; + int cmp, l_update, p_update, r_update, rc, ret, rootsplit, t_ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__bam_split_print); + + _lp = lp = np = pp = _rp = rp = NULL; + sp = NULL; + + REC_INTRO(__bam_split_42_read, ip, 0); + + /* + * There are two kinds of splits that we have to recover from. The + * first is a root-page split, where the root page is split from a + * leaf page into an internal page and two new leaf pages are created. + * The second is where a page is split into two pages, and a new key + * is inserted into the parent page. + * + * DBTs are not aligned in log records, so we need to copy the page + * so that we can access fields within it throughout this routine. + * Although we could hardcode the unaligned copies in this routine, + * we will be calling into regular btree functions with this page, + * so it's got to be aligned. Copying it into allocated memory is + * the only way to guarantee this. + */ + if ((ret = __os_malloc(env, argp->pg.size, &sp)) != 0) + goto out; + memcpy(sp, argp->pg.data, argp->pg.size); + + pgno = PGNO(sp); + root_pgno = argp->root_pgno; + rootsplit = root_pgno != PGNO_INVALID; + REC_FGET(mpf, ip, argp->left, &lp, right); +right: REC_FGET(mpf, ip, argp->right, &rp, redo); + +redo: if (DB_REDO(op)) { + l_update = r_update = p_update = 0; + /* + * Decide if we need to resplit the page. + * + * If this is a root split, then the root has to exist unless + * we have truncated it due to a future deallocation. + */ + if (rootsplit) { + REC_FGET(mpf, ip, root_pgno, &pp, do_left); + cmp = LOG_COMPARE(&LSN(pp), &LSN(argp->pg.data)); + CHECK_LSN(env, op, + cmp, &LSN(pp), &LSN(argp->pg.data)); + p_update = cmp == 0; + } + +do_left: if (lp != NULL) { + cmp = LOG_COMPARE(&LSN(lp), &argp->llsn); + CHECK_LSN(env, op, cmp, &LSN(lp), &argp->llsn); + if (cmp == 0) + l_update = 1; + } + + if (rp != NULL) { + cmp = LOG_COMPARE(&LSN(rp), &argp->rlsn); + CHECK_LSN(env, op, cmp, &LSN(rp), &argp->rlsn); + if (cmp == 0) + r_update = 1; + } + + if (!p_update && !l_update && !r_update) + goto check_next; + + /* Allocate and initialize new left/right child pages. */ + if ((ret = __os_malloc(env, file_dbp->pgsize, &_lp)) != 0 || + (ret = __os_malloc(env, file_dbp->pgsize, &_rp)) != 0) + goto out; + if (rootsplit) { + P_INIT(_lp, file_dbp->pgsize, argp->left, + PGNO_INVALID, + ISINTERNAL(sp) ? PGNO_INVALID : argp->right, + LEVEL(sp), TYPE(sp)); + P_INIT(_rp, file_dbp->pgsize, argp->right, + ISINTERNAL(sp) ? PGNO_INVALID : argp->left, + PGNO_INVALID, LEVEL(sp), TYPE(sp)); + } else { + P_INIT(_lp, file_dbp->pgsize, PGNO(sp), + ISINTERNAL(sp) ? PGNO_INVALID : PREV_PGNO(sp), + ISINTERNAL(sp) ? PGNO_INVALID : argp->right, + LEVEL(sp), TYPE(sp)); + P_INIT(_rp, file_dbp->pgsize, argp->right, + ISINTERNAL(sp) ? PGNO_INVALID : sp->pgno, + ISINTERNAL(sp) ? PGNO_INVALID : NEXT_PGNO(sp), + LEVEL(sp), TYPE(sp)); + } + + /* Split the page. */ + if ((ret = __bam_copy(file_dbp, sp, _lp, 0, argp->indx)) != 0 || + (ret = __bam_copy(file_dbp, sp, _rp, argp->indx, + NUM_ENT(sp))) != 0) + goto out; + + if (l_update) { + REC_DIRTY(mpf, ip, file_dbp->priority, &lp); + memcpy(lp, _lp, file_dbp->pgsize); + lp->lsn = *lsnp; + if ((ret = __memp_fput(mpf, + ip, lp, file_dbp->priority)) != 0) + goto out; + lp = NULL; + } + + if (r_update) { + REC_DIRTY(mpf, ip, file_dbp->priority, &rp); + memcpy(rp, _rp, file_dbp->pgsize); + rp->lsn = *lsnp; + if ((ret = __memp_fput(mpf, + ip, rp, file_dbp->priority)) != 0) + goto out; + rp = NULL; + } + + /* + * If the parent page is wrong, update it. This is of interest + * only if it was a root split, since root splits create parent + * pages. All other splits modify a parent page, but those are + * separately logged and recovered. + */ + if (rootsplit && p_update) { + if (IS_BTREE_PAGE(sp)) { + ptype = P_IBTREE; + rc = argp->opflags & SPL_NRECS ? 1 : 0; + } else { + ptype = P_IRECNO; + rc = 1; + } + + REC_DIRTY(mpf, ip, file_dbp->priority, &pp); + P_INIT(pp, file_dbp->pgsize, root_pgno, + PGNO_INVALID, PGNO_INVALID, _lp->level + 1, ptype); + RE_NREC_SET(pp, rc ? __bam_total(file_dbp, _lp) + + __bam_total(file_dbp, _rp) : 0); + + pp->lsn = *lsnp; + if ((ret = __memp_fput(mpf, + ip, pp, file_dbp->priority)) != 0) + goto out; + pp = NULL; + } + +check_next: /* + * Finally, redo the next-page link if necessary. This is of + * interest only if it wasn't a root split -- inserting a new + * page in the tree requires that any following page have its + * previous-page pointer updated to our new page. The next + * page must exist because we're redoing the operation. + */ + if (!rootsplit && argp->npgno != PGNO_INVALID) { + if ((ret = __memp_fget(mpf, &argp->npgno, + ip, NULL, 0, &np)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr( + file_dbp, argp->npgno, ret); + goto out; + } else + goto done; + } + cmp = LOG_COMPARE(&LSN(np), &argp->nlsn); + CHECK_LSN(env, op, cmp, &LSN(np), &argp->nlsn); + if (cmp == 0) { + REC_DIRTY(mpf, ip, file_dbp->priority, &np); + PREV_PGNO(np) = argp->right; + np->lsn = *lsnp; + if ((ret = __memp_fput(mpf, ip, + np, file_dbp->priority)) != 0) + goto out; + np = NULL; + } + } + } else { + /* + * If the split page is wrong, replace its contents with the + * logged page contents. If the page doesn't exist, it means + * that the create of the page never happened, nor did any of + * the adds onto the page that caused the split, and there's + * really no undo-ing to be done. + */ + if ((ret = __memp_fget(mpf, &pgno, ip, NULL, + DB_MPOOL_EDIT, &pp)) != 0) { + pp = NULL; + goto lrundo; + } + if (LOG_COMPARE(lsnp, &LSN(pp)) == 0) { + REC_DIRTY(mpf, ip, file_dbp->priority, &pp); + memcpy(pp, argp->pg.data, argp->pg.size); + if ((ret = __memp_fput(mpf, + ip, pp, file_dbp->priority)) != 0) + goto out; + pp = NULL; + } + + /* + * If it's a root split and the left child ever existed, update + * its LSN. (If it's not a root split, we've updated the left + * page already -- it's the same as the split page.) If the + * right child ever existed, root split or not, update its LSN. + * The undo of the page allocation(s) will restore them to the + * free list. + */ +lrundo: if ((rootsplit && lp != NULL) || rp != NULL) { + if (rootsplit && lp != NULL && + LOG_COMPARE(lsnp, &LSN(lp)) == 0) { + REC_DIRTY(mpf, ip, file_dbp->priority, &lp); + lp->lsn = argp->llsn; + if ((ret = __memp_fput(mpf, ip, + lp, file_dbp->priority)) != 0) + goto out; + lp = NULL; + } + if (rp != NULL && + LOG_COMPARE(lsnp, &LSN(rp)) == 0) { + REC_DIRTY(mpf, ip, file_dbp->priority, &rp); + rp->lsn = argp->rlsn; + if ((ret = __memp_fput(mpf, ip, + rp, file_dbp->priority)) != 0) + goto out; + rp = NULL; + } + } + + /* + * Finally, undo the next-page link if necessary. This is of + * interest only if it wasn't a root split -- inserting a new + * page in the tree requires that any following page have its + * previous-page pointer updated to our new page. Since it's + * possible that the next-page never existed, we ignore it as + * if there's nothing to undo. + */ + if (!rootsplit && argp->npgno != PGNO_INVALID) { + if ((ret = __memp_fget(mpf, &argp->npgno, + ip, NULL, DB_MPOOL_EDIT, &np)) != 0) { + np = NULL; + goto done; + } + if (LOG_COMPARE(lsnp, &LSN(np)) == 0) { + REC_DIRTY(mpf, ip, file_dbp->priority, &np); + PREV_PGNO(np) = argp->left; + np->lsn = argp->nlsn; + if (__memp_fput(mpf, + ip, np, file_dbp->priority)) + goto out; + np = NULL; + } + } + } + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: /* Free any pages that weren't dirtied. */ + if (pp != NULL && (t_ret = __memp_fput(mpf, + ip, pp, file_dbp->priority)) != 0 && ret == 0) + ret = t_ret; + if (lp != NULL && (t_ret = __memp_fput(mpf, + ip, lp, file_dbp->priority)) != 0 && ret == 0) + ret = t_ret; + if (np != NULL && (t_ret = __memp_fput(mpf, + ip, np, file_dbp->priority)) != 0 && ret == 0) + ret = t_ret; + if (rp != NULL && (t_ret = __memp_fput(mpf, + ip, rp, file_dbp->priority)) != 0 && ret == 0) + ret = t_ret; + + /* Free any allocated space. */ + if (_lp != NULL) + __os_free(env, _lp); + if (_rp != NULL) + __os_free(env, _rp); + if (sp != NULL) + __os_free(env, sp); + + REC_CLOSE; +} + +/* + * __bam_rsplit_recover -- + * Recovery function for a reverse split. + * + * PUBLIC: int __bam_rsplit_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_rsplit_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_rsplit_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_LSN copy_lsn; + DB_MPOOLFILE *mpf; + PAGE *pagep; + db_pgno_t pgno, root_pgno; + db_recno_t rcnt; + int cmp_n, cmp_p, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__bam_rsplit_print); + REC_INTRO(__bam_rsplit_read, ip, 1); + + /* Fix the root page. */ + pgno = root_pgno = argp->root_pgno; + if ((ret = __memp_fget(mpf, &pgno, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, pgno, ret); + goto out; + } else + goto do_page; + } + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->rootlsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->rootlsn); + CHECK_ABORT(env, op, cmp_n, &LSN(pagep), lsnp); + if (cmp_p == 0 && DB_REDO(op)) { + /* + * Copy the new data to the root page. If it is not now a + * leaf page we need to restore the record number. We could + * try to determine if C_RECNUM was set in the btree, but + * that's not really necessary since the field is not used + * otherwise. + */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + rcnt = RE_NREC(pagep); + memcpy(pagep, argp->pgdbt.data, argp->pgdbt.size); + if (LEVEL(pagep) > LEAFLEVEL) + RE_NREC_SET(pagep, rcnt); + pagep->pgno = root_pgno; + pagep->lsn = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Need to undo update described. */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + P_INIT(pagep, file_dbp->pgsize, root_pgno, + argp->nrec, PGNO_INVALID, pagep->level + 1, + IS_BTREE_PAGE(pagep) ? P_IBTREE : P_IRECNO); + if ((ret = __db_pitem(dbc, pagep, 0, + argp->rootent.size, &argp->rootent, NULL)) != 0) + goto out; + pagep->lsn = argp->rootlsn; + } + if ((ret = __memp_fput(mpf, ip, pagep, dbc->priority)) != 0) + goto out; + +do_page: + /* + * Fix the page copied over the root page. It's possible that the + * page never made it to disk, or was truncated so if the page + * doesn't exist, it's okay and there's nothing further to do. + */ + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } else + goto done; + } + (void)__ua_memcpy(©_lsn, &LSN(argp->pgdbt.data), sizeof(DB_LSN)); + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), ©_lsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), ©_lsn); + CHECK_ABORT(env, op, cmp_n, &LSN(pagep), lsnp); + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + pagep->lsn = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Need to undo update described. */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + memcpy(pagep, argp->pgdbt.data, argp->pgdbt.size); + } + if ((ret = __memp_fput(mpf, ip, pagep, dbc->priority)) != 0) + goto out; + pagep = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, dbc->priority); + REC_CLOSE; +} + +/* + * __bam_adj_recover -- + * Recovery function for adj. + * + * PUBLIC: int __bam_adj_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_adj_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_adj_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int cmp_n, cmp_p, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__bam_adj_print); + REC_INTRO(__bam_adj_read, ip, 1); + + /* Get the page; if it never existed and we're undoing, we're done. */ + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } else + goto done; + } + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn); + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + if ((ret = __bam_adjindx(dbc, + pagep, argp->indx, argp->indx_copy, argp->is_insert)) != 0) + goto out; + + LSN(pagep) = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Need to undo update described. */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + if ((ret = __bam_adjindx(dbc, + pagep, argp->indx, argp->indx_copy, !argp->is_insert)) != 0) + goto out; + + LSN(pagep) = argp->lsn; + } + if ((ret = __memp_fput(mpf, ip, pagep, dbc->priority)) != 0) + goto out; + pagep = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, dbc->priority); + REC_CLOSE; +} + +/* + * __bam_cadjust_recover -- + * Recovery function for the adjust of a count change in an internal + * page. + * + * PUBLIC: int __bam_cadjust_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_cadjust_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_cadjust_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int cmp_n, cmp_p, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__bam_cadjust_print); + REC_INTRO(__bam_cadjust_read, ip, 0); + + /* Get the page; if it never existed and we're undoing, we're done. */ + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } else + goto done; + } + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn); + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + if (IS_BTREE_PAGE(pagep)) { + GET_BINTERNAL(file_dbp, pagep, argp->indx)->nrecs += + argp->adjust; + if (argp->opflags & CAD_UPDATEROOT) + RE_NREC_ADJ(pagep, argp->adjust); + } else { + GET_RINTERNAL(file_dbp, pagep, argp->indx)->nrecs += + argp->adjust; + if (argp->opflags & CAD_UPDATEROOT) + RE_NREC_ADJ(pagep, argp->adjust); + } + + LSN(pagep) = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Need to undo update described. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + if (IS_BTREE_PAGE(pagep)) { + GET_BINTERNAL(file_dbp, pagep, argp->indx)->nrecs -= + argp->adjust; + if (argp->opflags & CAD_UPDATEROOT) + RE_NREC_ADJ(pagep, -(argp->adjust)); + } else { + GET_RINTERNAL(file_dbp, pagep, argp->indx)->nrecs -= + argp->adjust; + if (argp->opflags & CAD_UPDATEROOT) + RE_NREC_ADJ(pagep, -(argp->adjust)); + } + LSN(pagep) = argp->lsn; + } + if ((ret = __memp_fput(mpf, ip, pagep, file_dbp->priority)) != 0) + goto out; + pagep = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, file_dbp->priority); + REC_CLOSE; +} + +/* + * __bam_cdel_recover -- + * Recovery function for the intent-to-delete of a cursor record. + * + * PUBLIC: int __bam_cdel_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_cdel_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_cdel_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + u_int32_t indx; + int cmp_n, cmp_p, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__bam_cdel_print); + REC_INTRO(__bam_cdel_read, ip, 0); + + /* Get the page; if it never existed and we're undoing, we're done. */ + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } else + goto done; + } + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn); + CHECK_ABORT(env, op, cmp_n, &LSN(pagep), lsnp); + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + indx = argp->indx + (TYPE(pagep) == P_LBTREE ? O_INDX : 0); + B_DSET(GET_BKEYDATA(file_dbp, pagep, indx)->type); + + LSN(pagep) = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Need to undo update described. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + indx = argp->indx + (TYPE(pagep) == P_LBTREE ? O_INDX : 0); + B_DCLR(GET_BKEYDATA(file_dbp, pagep, indx)->type); + + if ((ret = __bam_ca_delete( + file_dbp, argp->pgno, argp->indx, 0, NULL)) != 0) + goto out; + + LSN(pagep) = argp->lsn; + } + if ((ret = __memp_fput(mpf, ip, pagep, file_dbp->priority)) != 0) + goto out; + pagep = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, file_dbp->priority); + REC_CLOSE; +} + +/* + * __bam_repl_recover -- + * Recovery function for page item replacement. + * + * PUBLIC: int __bam_repl_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_repl_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_repl_args *argp; + DB_THREAD_INFO *ip; + BKEYDATA *bk; + BINTERNAL *bi; + DB *file_dbp; + DBC *dbc; + DBT dbt; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int cmp_n, cmp_p, ret; + u_int32_t len; + u_int8_t *dp, *p; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__bam_repl_print); + REC_INTRO(__bam_repl_read, ip, 1); + + /* Get the page; if it never existed and we're undoing, we're done. */ + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } else + goto done; + } + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn); + CHECK_ABORT(env, op, cmp_n, &LSN(pagep), lsnp); + if (cmp_p == 0 && DB_REDO(op)) { + /* + * Need to redo update described. + * + * Re-build the replacement item. + */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + if (TYPE(pagep) == P_IBTREE) { + /* Point at the internal struct past the type. */ + bi = GET_BINTERNAL(file_dbp, pagep, argp->indx); + dp = &bi->unused; + len = bi->len + + SSZA(BINTERNAL, data) - SSZ(BINTERNAL, unused); + } else { + bk = GET_BKEYDATA(file_dbp, pagep, argp->indx); + dp = bk->data; + len = bk->len; + } + memset(&dbt, 0, sizeof(dbt)); + dbt.size = argp->prefix + argp->suffix + argp->repl.size; + if ((ret = __os_malloc(env, dbt.size, &dbt.data)) != 0) + goto out; + p = dbt.data; + memcpy(p, dp, argp->prefix); + p += argp->prefix; + memcpy(p, argp->repl.data, argp->repl.size); + p += argp->repl.size; + memcpy(p, dp + (len - argp->suffix), argp->suffix); + + /* isdeleted has become the type flag for non-leaf replace */ + ret = __bam_ritem(dbc, + pagep, argp->indx, &dbt, argp->isdeleted); + __os_free(env, dbt.data); + if (ret != 0) + goto out; + + LSN(pagep) = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* + * Need to undo update described. + * + * Re-build the original item. + */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + if (TYPE(pagep) == P_IBTREE) { + /* Point at the internal struct past the type. */ + bi = GET_BINTERNAL(file_dbp, pagep, argp->indx); + dp = &bi->unused; + len = bi->len + + SSZA(BINTERNAL, data) - SSZ(BINTERNAL, unused); + } else { + bk = GET_BKEYDATA(file_dbp, pagep, argp->indx); + dp = bk->data; + len = bk->len; + } + memset(&dbt, 0, sizeof(dbt)); + dbt.size = argp->prefix + argp->suffix + argp->orig.size; + if ((ret = __os_malloc(env, dbt.size, &dbt.data)) != 0) + goto out; + p = dbt.data; + memcpy(p, dp, argp->prefix); + p += argp->prefix; + memcpy(p, argp->orig.data, argp->orig.size); + p += argp->orig.size; + memcpy(p, dp + (len - argp->suffix), argp->suffix); + + ret = __bam_ritem(dbc, + pagep, argp->indx, &dbt, argp->isdeleted); + __os_free(env, dbt.data); + if (ret != 0) + goto out; + + /* Reset the deleted flag, if necessary. */ + if (argp->isdeleted && LEVEL(pagep) == LEAFLEVEL) + B_DSET(GET_BKEYDATA(file_dbp, pagep, argp->indx)->type); + + LSN(pagep) = argp->lsn; + } + if ((ret = __memp_fput(mpf, ip, pagep, dbc->priority)) != 0) + goto out; + pagep = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, dbc->priority); + REC_CLOSE; +} + +/* + * __bam_root_recover -- + * Recovery function for setting the root page on the meta-data page. + * + * PUBLIC: int __bam_root_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_root_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_root_args *argp; + DB_THREAD_INFO *ip; + BTMETA *meta; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + int cmp_n, cmp_p, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + meta = NULL; + REC_PRINT(__bam_root_print); + REC_INTRO(__bam_root_read, ip, 0); + + if ((ret = __memp_fget(mpf, &argp->meta_pgno, ip, NULL, + 0, &meta)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->meta_pgno, ret); + goto out; + } else + goto done; + } + + cmp_n = LOG_COMPARE(lsnp, &LSN(meta)); + cmp_p = LOG_COMPARE(&LSN(meta), &argp->meta_lsn); + CHECK_LSN(env, op, cmp_p, &LSN(meta), &argp->meta_lsn); + CHECK_ABORT(env, op, cmp_n, &LSN(meta), lsnp); + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &meta); + meta->root = argp->root_pgno; + meta->dbmeta.lsn = *lsnp; + ((BTREE *)file_dbp->bt_internal)->bt_root = meta->root; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Nothing to undo except lsn. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &meta); + meta->dbmeta.lsn = argp->meta_lsn; + } + if ((ret = __memp_fput(mpf, ip, meta, file_dbp->priority)) != 0) + goto out; + meta = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (meta != NULL) + (void)__memp_fput(mpf, ip, meta, file_dbp->priority); + REC_CLOSE; +} + +/* + * __bam_curadj_recover -- + * Transaction abort function to undo cursor adjustments. + * This should only be triggered by subtransaction aborts. + * + * PUBLIC: int __bam_curadj_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_curadj_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_curadj_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + int ret; + + COMPQUIET(mpf, NULL); + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__bam_curadj_print); + REC_INTRO(__bam_curadj_read, ip, 1); + + ret = 0; + if (op != DB_TXN_ABORT) + goto done; + + switch (argp->mode) { + case DB_CA_DI: + if ((ret = __bam_ca_di(dbc, argp->from_pgno, + argp->from_indx, -(int)argp->first_indx)) != 0) + goto out; + break; + case DB_CA_DUP: + if ((ret = __bam_ca_undodup(file_dbp, argp->first_indx, + argp->from_pgno, argp->from_indx, argp->to_indx)) != 0) + goto out; + break; + + case DB_CA_RSPLIT: + if ((ret = + __bam_ca_rsplit(dbc, argp->to_pgno, argp->from_pgno)) != 0) + goto out; + break; + + case DB_CA_SPLIT: + if ((ret = __bam_ca_undosplit(file_dbp, argp->from_pgno, + argp->to_pgno, argp->left_pgno, argp->from_indx)) != 0) + goto out; + break; + } + +done: *lsnp = argp->prev_lsn; +out: REC_CLOSE; +} + +/* + * __bam_rcuradj_recover -- + * Transaction abort function to undo cursor adjustments in rrecno. + * This should only be triggered by subtransaction aborts. + * + * PUBLIC: int __bam_rcuradj_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_rcuradj_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_rcuradj_args *argp; + DB_THREAD_INFO *ip; + BTREE_CURSOR *cp; + DB *file_dbp; + DBC *dbc, *rdbc; + DB_MPOOLFILE *mpf; + int ret, t_ret; + + COMPQUIET(mpf, NULL); + + ip = ((DB_TXNHEAD *)info)->thread_info; + rdbc = NULL; + REC_PRINT(__bam_rcuradj_print); + REC_INTRO(__bam_rcuradj_read, ip, 1); + + ret = t_ret = 0; + + if (op != DB_TXN_ABORT) + goto done; + + /* + * We don't know whether we're in an offpage dup set, and + * thus don't know whether the dbc REC_INTRO has handed us is + * of a reasonable type. It's certainly unset, so if this is + * an offpage dup set, we don't have an OPD cursor. The + * simplest solution is just to allocate a whole new cursor + * for our use; we're only really using it to hold pass some + * state into __ram_ca, and this way we don't need to make + * this function know anything about how offpage dups work. + */ + if ((ret = __db_cursor_int(file_dbp, NULL, + NULL, DB_RECNO, argp->root, 0, NULL, &rdbc)) != 0) + goto out; + + cp = (BTREE_CURSOR *)rdbc->internal; + F_SET(cp, C_RENUMBER); + cp->recno = argp->recno; + + switch (argp->mode) { + case CA_DELETE: + /* + * The way to undo a delete is with an insert. Since + * we're undoing it, the delete flag must be set. + */ + F_SET(cp, C_DELETED); + F_SET(cp, C_RENUMBER); /* Just in case. */ + cp->order = argp->order; + if ((ret = __ram_ca(rdbc, CA_ICURRENT, NULL)) != 0) + goto out; + break; + case CA_IAFTER: + case CA_IBEFORE: + case CA_ICURRENT: + /* + * The way to undo an insert is with a delete. The delete + * flag is unset to start with. + */ + F_CLR(cp, C_DELETED); + cp->order = INVALID_ORDER; + if ((ret = __ram_ca(rdbc, CA_DELETE, NULL)) != 0) + goto out; + break; + } + +done: *lsnp = argp->prev_lsn; +out: if (rdbc != NULL && (t_ret = __dbc_close(rdbc)) != 0 && ret == 0) + ret = t_ret; + REC_CLOSE; +} + +/* + * __bam_relink_recover -- + * Recovery function for relink. + * + * PUBLIC: int __bam_relink_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_relink_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_relink_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int cmp_n, cmp_p, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__bam_relink_print); + REC_INTRO(__bam_relink_read, ip, 0); + + /* + * There are up to three pages we need to check -- the page, and the + * previous and next pages, if they existed. For a page add operation, + * the current page is the result of a split and is being recovered + * elsewhere, so all we need do is recover the next page. + */ + if (argp->next == PGNO_INVALID) + goto prev; + if ((ret = __memp_fget(mpf, &argp->next, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->next, ret); + goto out; + } else + goto prev; + } + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn_next); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn_next); + CHECK_ABORT(env, op, cmp_n, &LSN(pagep), lsnp); + if (cmp_p == 0 && DB_REDO(op)) { + /* Redo the remove or replace. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + if (argp->new_pgno == PGNO_INVALID) + pagep->prev_pgno = argp->prev; + else + pagep->prev_pgno = argp->new_pgno; + + pagep->lsn = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Undo the remove or replace. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->prev_pgno = argp->pgno; + + pagep->lsn = argp->lsn_next; + } + + if ((ret = __memp_fput(mpf, ip, pagep, file_dbp->priority)) != 0) + goto out; + pagep = NULL; + +prev: if (argp->prev == PGNO_INVALID) + goto done; + if ((ret = __memp_fget(mpf, &argp->prev, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->prev, ret); + goto out; + } else + goto done; + } + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn_prev); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn_prev); + CHECK_ABORT(env, op, cmp_n, &LSN(pagep), lsnp); + if (cmp_p == 0 && DB_REDO(op)) { + /* Redo the relink. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + if (argp->new_pgno == PGNO_INVALID) + pagep->next_pgno = argp->next; + else + pagep->next_pgno = argp->new_pgno; + + pagep->lsn = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Undo the relink. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->next_pgno = argp->pgno; + pagep->lsn = argp->lsn_prev; + } + + if ((ret = __memp_fput(mpf, + ip, pagep, file_dbp->priority)) != 0) + goto out; + pagep = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, file_dbp->priority); + REC_CLOSE; +} + +/* + * __bam_merge_44_recover -- + * Recovery function for merge. + * + * PUBLIC: int __bam_merge_44_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_merge_44_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_merge_44_args *argp; + DB_THREAD_INFO *ip; + BKEYDATA *bk; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + db_indx_t indx, *ninp, *pinp; + u_int32_t size; + u_int8_t *bp; + int cmp_n, cmp_p, i, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__bam_merge_44_print); + REC_INTRO(__bam_merge_44_read, ip, 1); + + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } else + goto next; + } + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn); + CHECK_LSN(file_dbp->env, op, cmp_p, &LSN(pagep), &argp->lsn); + + if (cmp_p == 0 && DB_REDO(op)) { + /* + * If the header is provided the page is empty, copy the + * needed data. + */ + DB_ASSERT(env, argp->hdr.size == 0 || NUM_ENT(pagep) == 0); + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + if (argp->hdr.size != 0) { + P_INIT(pagep, file_dbp->pgsize, pagep->pgno, + PREV_PGNO(argp->hdr.data), + NEXT_PGNO(argp->hdr.data), + LEVEL(argp->hdr.data), TYPE(argp->hdr.data)); + } + if (TYPE(pagep) == P_OVERFLOW) { + OV_REF(pagep) = OV_REF(argp->hdr.data); + OV_LEN(pagep) = OV_LEN(argp->hdr.data); + bp = (u_int8_t *) pagep + P_OVERHEAD(file_dbp); + memcpy(bp, argp->data.data, argp->data.size); + } else { + /* Copy the data segment. */ + bp = (u_int8_t *)pagep + + (db_indx_t)(HOFFSET(pagep) - argp->data.size); + memcpy(bp, argp->data.data, argp->data.size); + + /* Copy index table offset past the current entries. */ + pinp = P_INP(file_dbp, pagep) + NUM_ENT(pagep); + ninp = argp->ind.data; + for (i = 0; + i < (int)(argp->ind.size / sizeof(*ninp)); i++) + *pinp++ = *ninp++ + - (file_dbp->pgsize - HOFFSET(pagep)); + HOFFSET(pagep) -= argp->data.size; + NUM_ENT(pagep) += i; + } + pagep->lsn = *lsnp; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* + * Since logging is logical at the page level + * we cannot just truncate the data space. Delete + * the proper number of items from the logical end + * of the page. + */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + for (i = 0; i < (int)(argp->ind.size / sizeof(*ninp)); i++) { + indx = NUM_ENT(pagep) - 1; + if (P_INP(file_dbp, pagep)[indx] == + P_INP(file_dbp, pagep)[indx - P_INDX]) { + NUM_ENT(pagep)--; + continue; + } + switch (TYPE(pagep)) { + case P_LBTREE: + case P_LRECNO: + case P_LDUP: + bk = GET_BKEYDATA(file_dbp, pagep, indx); + size = BITEM_SIZE(bk); + break; + + case P_IBTREE: + size = BINTERNAL_SIZE( + GET_BINTERNAL(file_dbp, pagep, indx)->len); + break; + case P_IRECNO: + size = RINTERNAL_SIZE; + break; + + default: + ret = __db_pgfmt(env, PGNO(pagep)); + goto out; + } + if ((ret = + __db_ditem(dbc, pagep, indx, size)) != 0) + goto out; + } + if (argp->ind.size == 0) + HOFFSET(pagep) = file_dbp->pgsize; + pagep->lsn = argp->lsn; + } + + if ((ret = __memp_fput(mpf, ip, pagep, dbc->priority)) != 0) + goto out; + +next: if ((ret = __memp_fget(mpf, &argp->npgno, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } else + goto done; + } + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->nlsn); + CHECK_LSN(file_dbp->env, op, cmp_p, &LSN(pagep), &argp->nlsn); + + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to truncate the page. */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + HOFFSET(pagep) = file_dbp->pgsize; + NUM_ENT(pagep) = 0; + pagep->lsn = *lsnp; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to put the data back on the page. */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + if (TYPE(pagep) == P_OVERFLOW) { + OV_REF(pagep) = OV_REF(argp->hdr.data); + OV_LEN(pagep) = OV_LEN(argp->hdr.data); + bp = (u_int8_t *) pagep + P_OVERHEAD(file_dbp); + memcpy(bp, argp->data.data, argp->data.size); + } else { + bp = (u_int8_t *)pagep + + (db_indx_t)(HOFFSET(pagep) - argp->data.size); + memcpy(bp, argp->data.data, argp->data.size); + + /* Copy index table. */ + pinp = P_INP(file_dbp, pagep) + NUM_ENT(pagep); + ninp = argp->ind.data; + for (i = 0; + i < (int)(argp->ind.size / sizeof(*ninp)); i++) + *pinp++ = *ninp++; + HOFFSET(pagep) -= argp->data.size; + NUM_ENT(pagep) = i; + } + pagep->lsn = argp->nlsn; + } + + if ((ret = __memp_fput(mpf, + ip, pagep, dbc->priority)) != 0) + goto out; +done: + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_merge_recover -- + * Recovery function for merge. + * + * PUBLIC: int __bam_merge_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_merge_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_merge_args *argp; + DB_THREAD_INFO *ip; + BKEYDATA *bk; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + db_indx_t indx, *ninp, *pinp; + u_int32_t size; + u_int8_t *bp; + int cmp_n, cmp_p, i, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__bam_merge_print); + REC_INTRO(__bam_merge_read, ip, 1); + + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } else + goto next; + } + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn); + CHECK_LSN(file_dbp->env, op, cmp_p, &LSN(pagep), &argp->lsn); + CHECK_ABORT(file_dbp->env, op, cmp_n, &LSN(pagep), lsnp); + + if (cmp_p == 0 && DB_REDO(op)) { + /* + * When pg_copy is set, we are copying onto a new page. + */ + DB_ASSERT(env, !argp->pg_copy || NUM_ENT(pagep) == 0); + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + if (argp->pg_copy) { + P_INIT(pagep, file_dbp->pgsize, pagep->pgno, + PREV_PGNO(argp->hdr.data), + NEXT_PGNO(argp->hdr.data), + LEVEL(argp->hdr.data), TYPE(argp->hdr.data)); + } + if (TYPE(pagep) == P_OVERFLOW) { + OV_REF(pagep) = OV_REF(argp->hdr.data); + OV_LEN(pagep) = OV_LEN(argp->hdr.data); + bp = (u_int8_t *)pagep + P_OVERHEAD(file_dbp); + memcpy(bp, argp->data.data, argp->data.size); + } else { + /* Copy the data segment. */ + bp = (u_int8_t *)pagep + + (db_indx_t)(HOFFSET(pagep) - argp->data.size); + memcpy(bp, argp->data.data, argp->data.size); + + /* Copy index table offset past the current entries. */ + pinp = P_INP(file_dbp, pagep) + NUM_ENT(pagep); + ninp = P_INP(file_dbp, argp->hdr.data); + for (i = 0; i < NUM_ENT(argp->hdr.data); i++) + *pinp++ = *ninp++ + - (file_dbp->pgsize - HOFFSET(pagep)); + HOFFSET(pagep) -= argp->data.size; + NUM_ENT(pagep) += i; + } + pagep->lsn = *lsnp; + } else if (cmp_n == 0 && !DB_REDO(op)) { + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + if (TYPE(pagep) == P_OVERFLOW) { + HOFFSET(pagep) = file_dbp->pgsize; + goto setlsn; + } + + /* + * Since logging is logical at the page level we cannot just + * truncate the data space. Delete the proper number of items + * from the logical end of the page. + */ + for (i = 0; i < NUM_ENT(argp->hdr.data); i++) { + indx = NUM_ENT(pagep) - 1; + if (P_INP(file_dbp, pagep)[indx] == + P_INP(file_dbp, pagep)[indx - P_INDX]) { + NUM_ENT(pagep)--; + continue; + } + switch (TYPE(pagep)) { + case P_LBTREE: + case P_LRECNO: + case P_LDUP: + bk = GET_BKEYDATA(file_dbp, pagep, indx); + size = BITEM_SIZE(bk); + break; + + case P_IBTREE: + size = BINTERNAL_SIZE( + GET_BINTERNAL(file_dbp, pagep, indx)->len); + break; + case P_IRECNO: + size = RINTERNAL_SIZE; + break; + + default: + ret = __db_pgfmt(env, PGNO(pagep)); + goto out; + } + if ((ret = __db_ditem(dbc, pagep, indx, size)) != 0) + goto out; + } +setlsn: pagep->lsn = argp->lsn; + } + + if ((ret = __memp_fput(mpf, ip, pagep, dbc->priority)) != 0) + goto out; + +next: if ((ret = __memp_fget(mpf, &argp->npgno, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } else + goto done; + } + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->nlsn); + CHECK_LSN(file_dbp->env, op, cmp_p, &LSN(pagep), &argp->nlsn); + + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to truncate the page. */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + HOFFSET(pagep) = file_dbp->pgsize; + NUM_ENT(pagep) = 0; + pagep->lsn = *lsnp; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to put the data back on the page. */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + if (TYPE(pagep) == P_OVERFLOW) { + OV_REF(pagep) = OV_REF(argp->hdr.data); + OV_LEN(pagep) = OV_LEN(argp->hdr.data); + bp = (u_int8_t *)pagep + P_OVERHEAD(file_dbp); + memcpy(bp, argp->data.data, argp->data.size); + } else { + bp = (u_int8_t *)pagep + + (db_indx_t)(HOFFSET(pagep) - argp->data.size); + memcpy(bp, argp->data.data, argp->data.size); + + /* Copy index table. */ + pinp = P_INP(file_dbp, pagep) + NUM_ENT(pagep); + ninp = P_INP(file_dbp, argp->hdr.data); + for (i = 0; i < NUM_ENT(argp->hdr.data); i++) + *pinp++ = *ninp++; + HOFFSET(pagep) -= argp->data.size; + NUM_ENT(pagep) += i; + } + pagep->lsn = argp->nlsn; + } + + if ((ret = __memp_fput(mpf, + ip, pagep, dbc->priority)) != 0) + goto out; +done: + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_pgno_recover -- + * Recovery function for page number replacment. + * + * PUBLIC: int __bam_pgno_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_pgno_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + BINTERNAL *bi; + __bam_pgno_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep, *npagep; + db_pgno_t *pgnop; + int cmp_n, cmp_p, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__bam_pgno_print); + REC_INTRO(__bam_pgno_read, ip, 0); + + REC_FGET(mpf, ip, argp->pgno, &pagep, done); + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn); + CHECK_LSN(file_dbp->env, op, cmp_p, &LSN(pagep), &argp->lsn); + CHECK_ABORT(file_dbp->env, op, cmp_n, &LSN(pagep), lsnp); + + if ((cmp_p == 0 && DB_REDO(op)) || (cmp_n == 0 && !DB_REDO(op))) { + switch (TYPE(pagep)) { + case P_IBTREE: + /* + * An internal record can have both a overflow + * and child pointer. Fetch the page to see + * which it is. + */ + bi = GET_BINTERNAL(file_dbp, pagep, argp->indx); + if (B_TYPE(bi->type) == B_OVERFLOW) { + REC_FGET(mpf, ip, argp->npgno, &npagep, out); + + if (TYPE(npagep) == P_OVERFLOW) + pgnop = + &((BOVERFLOW *)(bi->data))->pgno; + else + pgnop = &bi->pgno; + if ((ret = __memp_fput(mpf, ip, + npagep, file_dbp->priority)) != 0) + goto out; + break; + } + pgnop = &bi->pgno; + break; + case P_IRECNO: + pgnop = + &GET_RINTERNAL(file_dbp, pagep, argp->indx)->pgno; + break; + default: + pgnop = + &GET_BOVERFLOW(file_dbp, pagep, argp->indx)->pgno; + break; + } + + if (DB_REDO(op)) { + /* Need to redo update described. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + *pgnop = argp->npgno; + pagep->lsn = *lsnp; + } else { + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + *pgnop = argp->opgno; + pagep->lsn = argp->lsn; + } + } + + if ((ret = __memp_fput(mpf, ip, pagep, file_dbp->priority)) != 0) + goto out; + +done: + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_relink_43_recover -- + * Recovery function for relink. + * + * PUBLIC: int __bam_relink_43_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_relink_43_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_relink_43_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__bam_relink_43_print); + REC_INTRO(__bam_relink_43_read, ip, 0); + + /* + * There are up to three pages we need to check -- the page, and the + * previous and next pages, if they existed. For a page add operation, + * the current page is the result of a split and is being recovered + * elsewhere, so all we need do is recover the next page. + */ + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } else + goto next2; + } + + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn); + if (cmp_p == 0 && DB_REDO(op)) { + /* Redo the relink. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->lsn = *lsnp; + } else if (LOG_COMPARE(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) { + /* Undo the relink. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->next_pgno = argp->next; + pagep->prev_pgno = argp->prev; + pagep->lsn = argp->lsn; + } + if ((ret = __memp_fput(mpf, + ip, pagep, file_dbp->priority)) != 0) + goto out; + pagep = NULL; + +next2: if ((ret = __memp_fget(mpf, &argp->next, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->next, ret); + goto out; + } else + goto prev; + } + + modified = 0; + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn_next); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn_next); + if (cmp_p == 0 && DB_REDO(op)) { + /* Redo the remove or undo the add. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->prev_pgno = argp->prev; + modified = 1; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Undo the remove or redo the add. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->prev_pgno = argp->pgno; + modified = 1; + } + if (modified) { + if (DB_UNDO(op)) + pagep->lsn = argp->lsn_next; + else + pagep->lsn = *lsnp; + } + if ((ret = __memp_fput(mpf, + ip, pagep, file_dbp->priority)) != 0) + goto out; + pagep = NULL; + +prev: if ((ret = __memp_fget(mpf, &argp->prev, ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) { + ret = __db_pgerr(file_dbp, argp->prev, ret); + goto out; + } else + goto done; + } + + modified = 0; + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn_prev); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn_prev); + if (cmp_p == 0 && DB_REDO(op)) { + /* Redo the relink. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->next_pgno = argp->next; + modified = 1; + } else if (LOG_COMPARE(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) { + /* Undo the relink. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->next_pgno = argp->pgno; + modified = 1; + } + if (modified) { + if (DB_UNDO(op)) + pagep->lsn = argp->lsn_prev; + else + pagep->lsn = *lsnp; + } + if ((ret = __memp_fput(mpf, + ip, pagep, file_dbp->priority)) != 0) + goto out; + pagep = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, file_dbp->priority); + REC_CLOSE; +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_reclaim.c b/src/libs/resiprocate/contrib/db/btree/bt_reclaim.c new file mode 100644 index 00000000..835bf9f1 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_reclaim.c @@ -0,0 +1,97 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1998-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/lock.h" + +/* + * __bam_reclaim -- + * Free a database. + * + * PUBLIC: int __bam_reclaim __P((DB *, DB_THREAD_INFO *, DB_TXN *)); + */ +int +__bam_reclaim(dbp, ip, txn) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; +{ + DBC *dbc; + DB_LOCK meta_lock; + int ret, t_ret; + + /* Acquire a cursor. */ + if ((ret = __db_cursor(dbp, ip, txn, &dbc, 0)) != 0) + return (ret); + + /* Write lock the metapage for deallocations. */ + if ((ret = __db_lget(dbc, + 0, PGNO_BASE_MD, DB_LOCK_WRITE, 0, &meta_lock)) != 0) + goto err; + + /* Avoid locking every page, we have the handle locked exclusive. */ + F_SET(dbc, DBC_DONTLOCK); + + /* Walk the tree, freeing pages. */ + ret = __bam_traverse(dbc, + DB_LOCK_WRITE, dbc->internal->root, __db_reclaim_callback, NULL); + + if ((t_ret = __TLPUT(dbc, meta_lock)) != 0 && ret == 0) + ret = t_ret; + + /* Discard the cursor. */ +err: if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __bam_truncate -- + * Truncate a database. + * + * PUBLIC: int __bam_truncate __P((DBC *, u_int32_t *)); + */ +int +__bam_truncate(dbc, countp) + DBC *dbc; + u_int32_t *countp; +{ + u_int32_t count; + int ret; + +#ifdef HAVE_COMPRESSION + u_int32_t comp_count; + + comp_count = 0; + if (DB_IS_COMPRESSED(dbc->dbp) && + (ret = __bam_compress_count(dbc, NULL, &comp_count)) != 0) + return (ret); +#endif + + count = 0; + + /* Walk the tree, freeing pages. */ + ret = __bam_traverse(dbc, + DB_LOCK_WRITE, dbc->internal->root, __db_truncate_callback, &count); + +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbc->dbp)) { + if (countp != NULL) + *countp = comp_count; + } else +#endif + if (countp != NULL) + *countp = count; + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_recno.c b/src/libs/resiprocate/contrib/db/btree/bt_recno.c new file mode 100644 index 00000000..524de465 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_recno.c @@ -0,0 +1,1385 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" + +static int __ram_add __P((DBC *, db_recno_t *, DBT *, u_int32_t, u_int32_t)); +static int __ram_source __P((DB *)); +static int __ram_sread __P((DBC *, db_recno_t)); +static int __ram_update __P((DBC *, db_recno_t, int)); + +/* + * In recno, there are two meanings to the on-page "deleted" flag. If we're + * re-numbering records, it means the record was implicitly created. We skip + * over implicitly created records if doing a cursor "next" or "prev", and + * return DB_KEYEMPTY if they're explicitly requested.. If not re-numbering + * records, it means that the record was implicitly created, or was deleted. + * We skip over implicitly created or deleted records if doing a cursor "next" + * or "prev", and return DB_KEYEMPTY if they're explicitly requested. + * + * If we're re-numbering records, then we have to detect in the cursor that + * a record was deleted, and adjust the cursor as necessary on the next get. + * If we're not re-numbering records, then we can detect that a record has + * been deleted by looking at the actual on-page record, so we completely + * ignore the cursor's delete flag. This is different from the B+tree code. + * It also maintains whether the cursor references a deleted record in the + * cursor, and it doesn't always check the on-page value. + */ +#define CD_SET(cp) { \ + if (F_ISSET(cp, C_RENUMBER)) \ + F_SET(cp, C_DELETED); \ +} +#define CD_CLR(cp) { \ + if (F_ISSET(cp, C_RENUMBER)) { \ + F_CLR(cp, C_DELETED); \ + cp->order = INVALID_ORDER; \ + } \ +} +#define CD_ISSET(cp) \ + (F_ISSET(cp, C_RENUMBER) && F_ISSET(cp, C_DELETED) ? 1 : 0) + +/* + * Macros for comparing the ordering of two cursors. + * cp1 comes before cp2 iff one of the following holds: + * cp1's recno is less than cp2's recno + * recnos are equal, both deleted, and cp1's order is less than cp2's + * recnos are equal, cp1 deleted, and cp2 not deleted + */ +#define C_LESSTHAN(cp1, cp2) \ + (((cp1)->recno < (cp2)->recno) || \ + (((cp1)->recno == (cp2)->recno) && \ + ((CD_ISSET((cp1)) && CD_ISSET((cp2)) && (cp1)->order < (cp2)->order) || \ + (CD_ISSET((cp1)) && !CD_ISSET((cp2)))))) + +/* + * cp1 is equal to cp2 iff their recnos and delete flags are identical, + * and if the delete flag is set their orders are also identical. + */ +#define C_EQUAL(cp1, cp2) \ + ((cp1)->recno == (cp2)->recno && CD_ISSET((cp1)) == CD_ISSET((cp2)) && \ + (!CD_ISSET((cp1)) || (cp1)->order == (cp2)->order)) + +/* + * Do we need to log the current cursor adjustment? + */ +#define CURADJ_LOG(dbc) \ + (DBC_LOGGING((dbc)) && (dbc)->txn != NULL && (dbc)->txn->parent != NULL) + +/* + * After a search, copy the found page into the cursor, discarding any + * currently held lock. + */ +#define STACK_TO_CURSOR(cp, ret) { \ + int __t_ret; \ + (cp)->page = (cp)->csp->page; \ + (cp)->pgno = (cp)->csp->page->pgno; \ + (cp)->indx = (cp)->csp->indx; \ + if ((__t_ret = __TLPUT(dbc, (cp)->lock)) != 0 && (ret) == 0) \ + ret = __t_ret; \ + (cp)->lock = (cp)->csp->lock; \ + (cp)->lock_mode = (cp)->csp->lock_mode; \ +} + +/* + * __ram_open -- + * Recno open function. + * + * PUBLIC: int __ram_open __P((DB *, DB_THREAD_INFO *, + * PUBLIC: DB_TXN *, const char *, db_pgno_t, u_int32_t)); + */ +int +__ram_open(dbp, ip, txn, name, base_pgno, flags) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + const char *name; + db_pgno_t base_pgno; + u_int32_t flags; +{ + BTREE *t; + DBC *dbc; + int ret, t_ret; + + COMPQUIET(name, NULL); + t = dbp->bt_internal; + + /* Start up the tree. */ + if ((ret = __bam_read_root(dbp, ip, txn, base_pgno, flags)) != 0) + return (ret); + + /* + * If the user specified a source tree, open it and map it in. + * + * !!! + * We don't complain if the user specified transactions or threads. + * It's possible to make it work, but you'd better know what you're + * doing! + */ + if (t->re_source != NULL && (ret = __ram_source(dbp)) != 0) + return (ret); + + /* If we're snapshotting an underlying source file, do it now. */ + if (F_ISSET(dbp, DB_AM_SNAPSHOT)) { + /* Allocate a cursor. */ + if ((ret = __db_cursor(dbp, ip, NULL, &dbc, 0)) != 0) + return (ret); + + /* Do the snapshot. */ + if ((ret = __ram_update(dbc, + DB_MAX_RECORDS, 0)) != 0 && ret == DB_NOTFOUND) + ret = 0; + + /* Discard the cursor. */ + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + } + + return (ret); +} + +/* + * __ram_append -- + * Recno append function. + * + * PUBLIC: int __ram_append __P((DBC *, DBT *, DBT *)); + */ +int +__ram_append(dbc, key, data) + DBC *dbc; + DBT *key, *data; +{ + BTREE_CURSOR *cp; + int ret; + + cp = (BTREE_CURSOR *)dbc->internal; + + /* + * Make sure we've read in all of the backing source file. If + * we found the record or it simply didn't exist, add the + * user's record. + */ + ret = __ram_update(dbc, DB_MAX_RECORDS, 0); + if (ret == 0 || ret == DB_NOTFOUND) + ret = __ram_add(dbc, &cp->recno, data, DB_APPEND, 0); + + /* Return the record number. */ + if (ret == 0 && key != NULL) + ret = __db_retcopy(dbc->env, key, &cp->recno, + sizeof(cp->recno), &dbc->rkey->data, &dbc->rkey->ulen); + + return (ret); +} + +/* + * __ramc_del -- + * Recno DBC->del function. + * + * PUBLIC: int __ramc_del __P((DBC *, u_int32_t)); + */ +int +__ramc_del(dbc, flags) + DBC *dbc; + u_int32_t flags; +{ + BKEYDATA bk; + BTREE *t; + BTREE_CURSOR *cp; + DB *dbp; + DBT hdr, data; + DB_LOCK next_lock, prev_lock; + DB_LSN lsn; + db_pgno_t npgno, ppgno, save_npgno, save_ppgno; + int exact, nc, ret, stack, t_ret; + + dbp = dbc->dbp; + cp = (BTREE_CURSOR *)dbc->internal; + t = dbp->bt_internal; + stack = 0; + save_npgno = save_ppgno = PGNO_INVALID; + LOCK_INIT(next_lock); + LOCK_INIT(prev_lock); + COMPQUIET(flags, 0); + + /* + * The semantics of cursors during delete are as follows: in + * non-renumbering recnos, records are replaced with a marker + * containing a delete flag. If the record referenced by this cursor + * has already been deleted, we will detect that as part of the delete + * operation, and fail. + * + * In renumbering recnos, cursors which represent deleted items + * are flagged with the C_DELETED flag, and it is an error to + * call c_del a second time without an intervening cursor motion. + */ + if (CD_ISSET(cp)) + return (DB_KEYEMPTY); + + /* Search the tree for the key; delete only deletes exact matches. */ +retry: if ((ret = __bam_rsearch(dbc, &cp->recno, SR_DELETE, 1, &exact)) != 0) + goto err; + if (!exact) { + ret = DB_NOTFOUND; + goto err; + } + stack = 1; + + /* Copy the page into the cursor. */ + STACK_TO_CURSOR(cp, ret); + if (ret != 0) + goto err; + + /* + * If re-numbering records, the on-page deleted flag can only mean + * that this record was implicitly created. Applications aren't + * permitted to delete records they never created, return an error. + * + * If not re-numbering records, the on-page deleted flag means that + * this record was implicitly created, or, was deleted at some time. + * The former is an error because applications aren't permitted to + * delete records they never created, the latter is an error because + * if the record was "deleted", we could never have found it. + */ + if (B_DISSET(GET_BKEYDATA(dbp, cp->page, cp->indx)->type)) { + ret = DB_KEYEMPTY; + goto err; + } + + if (F_ISSET(cp, C_RENUMBER)) { + /* If we are going to drop the page, lock its neighbors. */ + if (STD_LOCKING(dbc) && + NUM_ENT(cp->page) == 1 && PGNO(cp->page) != cp->root) { + if ((npgno = NEXT_PGNO(cp->page)) != PGNO_INVALID) + TRY_LOCK(dbc, npgno, save_npgno, + next_lock, DB_LOCK_WRITE, retry); + if (ret != 0) + goto err; + if ((ppgno = PREV_PGNO(cp->page)) != PGNO_INVALID) + TRY_LOCK(dbc, ppgno, save_ppgno, + prev_lock, DB_LOCK_WRITE, retry); + if (ret != 0) + goto err; + } + /* Delete the item, adjust the counts, adjust the cursors. */ + if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0) + goto err; + if ((ret = __bam_adjust(dbc, -1)) != 0) + goto err; + if ((ret = __ram_ca(dbc, CA_DELETE, &nc)) != 0) + goto err; + if (nc > 0 && + CURADJ_LOG(dbc) && (ret = __bam_rcuradj_log(dbp, dbc->txn, + &lsn, 0, CA_DELETE, cp->root, cp->recno, cp->order)) != 0) + goto err; + + /* + * If the page is empty, delete it. + * + * We never delete a root page. First, root pages of primary + * databases never go away, recno or otherwise. However, if + * it's the root page of an off-page duplicates database, then + * it can be deleted. We don't delete it here because we have + * no way of telling the primary database page holder (e.g., + * the hash access method) that its page element should cleaned + * up because the underlying tree is gone. So, we keep the page + * around until the last cursor referencing the empty tree is + * are closed, and then clean it up. + */ + if (NUM_ENT(cp->page) == 0 && PGNO(cp->page) != cp->root) { + /* + * We want to delete a single item out of the last page + * that we're not deleting. + */ + ret = __bam_dpages(dbc, 0, BTD_RELINK); + + /* + * Regardless of the return from __bam_dpages, it will + * discard our stack and pinned page. + */ + stack = 0; + cp->page = NULL; + LOCK_INIT(cp->lock); + cp->lock_mode = DB_LOCK_NG; + } + } else { + /* Use a delete/put pair to replace the record with a marker. */ + if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0) + goto err; + + B_TSET_DELETED(bk.type, B_KEYDATA); + bk.len = 0; + DB_INIT_DBT(hdr, &bk, SSZA(BKEYDATA, data)); + DB_INIT_DBT(data, "", 0); + if ((ret = __db_pitem(dbc, + cp->page, cp->indx, BKEYDATA_SIZE(0), &hdr, &data)) != 0) + goto err; + } + + t->re_modified = 1; + +err: if (stack && (t_ret = __bam_stkrel(dbc, STK_CLRDBC)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __TLPUT(dbc, next_lock)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __TLPUT(dbc, prev_lock)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __ramc_get -- + * Recno DBC->get function. + * + * PUBLIC: int __ramc_get + * PUBLIC: __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); + */ +int +__ramc_get(dbc, key, data, flags, pgnop) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; + db_pgno_t *pgnop; +{ + BTREE_CURSOR *cp; + DB *dbp; + int cmp, exact, ret; + + COMPQUIET(pgnop, NULL); + + dbp = dbc->dbp; + cp = (BTREE_CURSOR *)dbc->internal; + + LF_CLR(DB_MULTIPLE|DB_MULTIPLE_KEY); +retry: switch (flags) { + case DB_CURRENT: + /* + * If we're using mutable records and the deleted flag is + * set, the cursor is pointing at a nonexistent record; + * return an error. + */ + if (CD_ISSET(cp)) + return (DB_KEYEMPTY); + break; + case DB_NEXT_DUP: + /* + * If we're not in an off-page dup set, we know there's no + * next duplicate since recnos don't have them. If we + * are in an off-page dup set, the next item assuredly is + * a dup, so we set flags to DB_NEXT and keep going. + */ + if (!F_ISSET(dbc, DBC_OPD)) + return (DB_NOTFOUND); + /* FALLTHROUGH */ + case DB_NEXT_NODUP: + /* + * Recno databases don't have duplicates, set flags to DB_NEXT + * and keep going. + */ + /* FALLTHROUGH */ + case DB_NEXT: + flags = DB_NEXT; + /* + * If record numbers are mutable: if we just deleted a record, + * we have to avoid incrementing the record number so that we + * return the right record by virtue of renumbering the tree. + */ + if (CD_ISSET(cp)) { + /* + * Clear the flag, we've moved off the deleted record. + */ + CD_CLR(cp); + break; + } + + if (cp->recno != RECNO_OOB) { + ++cp->recno; + break; + } + /* FALLTHROUGH */ + case DB_FIRST: + flags = DB_NEXT; + cp->recno = 1; + break; + case DB_PREV_DUP: + /* + * If we're not in an off-page dup set, we know there's no + * previous duplicate since recnos don't have them. If we + * are in an off-page dup set, the previous item assuredly + * is a dup, so we set flags to DB_PREV and keep going. + */ + if (!F_ISSET(dbc, DBC_OPD)) + return (DB_NOTFOUND); + /* FALLTHROUGH */ + case DB_PREV_NODUP: + /* + * Recno databases don't have duplicates, set flags to DB_PREV + * and keep going. + */ + /* FALLTHROUGH */ + case DB_PREV: + flags = DB_PREV; + if (cp->recno != RECNO_OOB) { + if (cp->recno == 1) { + ret = DB_NOTFOUND; + goto err; + } + --cp->recno; + break; + } + /* FALLTHROUGH */ + case DB_LAST: + flags = DB_PREV; + if (((ret = __ram_update(dbc, + DB_MAX_RECORDS, 0)) != 0) && ret != DB_NOTFOUND) + goto err; + if ((ret = __bam_nrecs(dbc, &cp->recno)) != 0) + goto err; + if (cp->recno == 0) { + ret = DB_NOTFOUND; + goto err; + } + break; + case DB_GET_BOTHC: + /* + * If we're doing a join and these are offpage dups, + * we want to keep searching forward from after the + * current cursor position. Increment the recno by 1, + * then proceed as for a DB_SET. + * + * Otherwise, we know there are no additional matching + * data, as recnos don't have dups. return DB_NOTFOUND. + */ + if (F_ISSET(dbc, DBC_OPD)) { + cp->recno++; + break; + } + ret = DB_NOTFOUND; + goto err; + /* NOTREACHED */ + case DB_GET_BOTH: + case DB_GET_BOTH_RANGE: + /* + * If we're searching a set of off-page dups, we start + * a new linear search from the first record. Otherwise, + * we compare the single data item associated with the + * requested record for a match. + */ + if (F_ISSET(dbc, DBC_OPD)) { + cp->recno = 1; + break; + } + /* FALLTHROUGH */ + case DB_SET: + case DB_SET_RANGE: + if ((ret = __ram_getno(dbc, key, &cp->recno, 0)) != 0) + goto err; + break; + default: + ret = __db_unknown_flag(dbp->env, "__ramc_get", flags); + goto err; + } + + /* + * For DB_PREV, DB_LAST, DB_SET and DB_SET_RANGE, we have already + * called __ram_update() to make sure sufficient records have been + * read from the backing source file. Do it now for DB_CURRENT (if + * the current record was deleted we may need more records from the + * backing file for a DB_CURRENT operation), DB_FIRST and DB_NEXT. + * (We don't have to test for flags == DB_FIRST, because the switch + * statement above re-set flags to DB_NEXT in that case.) + */ + if ((flags == DB_NEXT || flags == DB_CURRENT) && ((ret = + __ram_update(dbc, cp->recno, 0)) != 0) && ret != DB_NOTFOUND) + goto err; + + for (;; ++cp->recno) { + /* Search the tree for the record. */ + if ((ret = __bam_rsearch(dbc, &cp->recno, + F_ISSET(dbc, DBC_RMW) ? SR_FIND_WR : SR_FIND, + 1, &exact)) != 0) + goto err; + if (!exact) { + ret = DB_NOTFOUND; + goto err; + } + + /* Copy the page into the cursor. */ + STACK_TO_CURSOR(cp, ret); + if (ret != 0) + goto err; + + /* + * If re-numbering records, the on-page deleted flag means this + * record was implicitly created. If not re-numbering records, + * the on-page deleted flag means this record was implicitly + * created, or, it was deleted at some time. Regardless, we + * skip such records if doing cursor next/prev operations or + * walking through off-page duplicates, and fail if they were + * requested explicitly by the application. + */ + if (B_DISSET(GET_BKEYDATA(dbp, cp->page, cp->indx)->type)) + switch (flags) { + case DB_NEXT: + case DB_PREV: + (void)__bam_stkrel(dbc, STK_CLRDBC); + goto retry; + case DB_GET_BOTH: + case DB_GET_BOTH_RANGE: + /* + * If we're an OPD tree, we don't care about + * matching a record number on a DB_GET_BOTH + * -- everything belongs to the same tree. A + * normal recno should give up and return + * DB_NOTFOUND if the matching recno is deleted. + */ + if (F_ISSET(dbc, DBC_OPD)) { + (void)__bam_stkrel(dbc, STK_CLRDBC); + continue; + } + ret = DB_NOTFOUND; + goto err; + default: + ret = DB_KEYEMPTY; + goto err; + } + + if (flags == DB_GET_BOTH || + flags == DB_GET_BOTHC || flags == DB_GET_BOTH_RANGE) { + if ((ret = __bam_cmp(dbc, data, cp->page, cp->indx, + __bam_defcmp, &cmp)) != 0) + return (ret); + if (cmp == 0) + break; + if (!F_ISSET(dbc, DBC_OPD)) { + ret = DB_NOTFOUND; + goto err; + } + (void)__bam_stkrel(dbc, STK_CLRDBC); + } else + break; + } + + /* Return the key if the user didn't give us one. */ + if (!F_ISSET(dbc, DBC_OPD) && !F_ISSET(key, DB_DBT_ISSET)) { + ret = __db_retcopy(dbp->env, + key, &cp->recno, sizeof(cp->recno), + &dbc->rkey->data, &dbc->rkey->ulen); + F_SET(key, DB_DBT_ISSET); + } + + /* The cursor was reset, no further delete adjustment is necessary. */ +err: CD_CLR(cp); + + return (ret); +} + +/* + * __ramc_put -- + * Recno DBC->put function. + * + * PUBLIC: int __ramc_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); + */ +int +__ramc_put(dbc, key, data, flags, pgnop) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; + db_pgno_t *pgnop; +{ + BTREE_CURSOR *cp; + DB *dbp; + DB_LSN lsn; + ENV *env; + u_int32_t iiflags; + int exact, nc, ret, t_ret; + void *arg; + + COMPQUIET(pgnop, NULL); + + dbp = dbc->dbp; + env = dbp->env; + cp = (BTREE_CURSOR *)dbc->internal; + + /* + * DB_KEYFIRST and DB_KEYLAST mean different things if they're + * used in an off-page duplicate tree. If we're an off-page + * duplicate tree, they really mean "put at the beginning of the + * tree" and "put at the end of the tree" respectively, so translate + * them to something else. + */ + if (F_ISSET(dbc, DBC_OPD)) + switch (flags) { + case DB_KEYFIRST: + cp->recno = 1; + flags = DB_BEFORE; + break; + case DB_KEYLAST: + if ((ret = __ram_add(dbc, + &cp->recno, data, DB_APPEND, 0)) != 0) + return (ret); + if (CURADJ_LOG(dbc) && + (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, + CA_ICURRENT, cp->root, cp->recno, cp->order)) != 0) + return (ret); + return (0); + default: + break; + } + + /* + * Handle normal DB_KEYFIRST/DB_KEYLAST; for a recno, which has + * no duplicates, these are identical and mean "put the given + * datum at the given recno". + */ + if (flags == DB_KEYFIRST || flags == DB_KEYLAST || + flags == DB_NOOVERWRITE || flags == DB_OVERWRITE_DUP) { + ret = __ram_getno(dbc, key, &cp->recno, 1); + if (ret == 0 || ret == DB_NOTFOUND) + ret = __ram_add(dbc, &cp->recno, data, flags, 0); + return (ret); + } + + /* + * If we're putting with a cursor that's marked C_DELETED, we need to + * take special care; the cursor doesn't "really" reference the item + * corresponding to its current recno, but instead is "between" that + * record and the current one. Translate the actual insert into + * DB_BEFORE, and let the __ram_ca work out the gory details of what + * should wind up pointing where. + */ + if (CD_ISSET(cp)) + iiflags = DB_BEFORE; + else + iiflags = flags; + +split: if ((ret = __bam_rsearch(dbc, &cp->recno, SR_INSERT, 1, &exact)) != 0) + goto err; + /* + * An inexact match is okay; it just means we're one record past the + * end, which is reasonable if we're marked deleted. + */ + DB_ASSERT(env, exact || CD_ISSET(cp)); + + /* Copy the page into the cursor. */ + STACK_TO_CURSOR(cp, ret); + if (ret != 0) + goto err; + + ret = __bam_iitem(dbc, key, data, iiflags, 0); + t_ret = __bam_stkrel(dbc, STK_CLRDBC); + + if (t_ret != 0 && (ret == 0 || ret == DB_NEEDSPLIT)) + ret = t_ret; + else if (ret == DB_NEEDSPLIT) { + arg = &cp->recno; + if ((ret = __bam_split(dbc, arg, NULL)) != 0) + goto err; + goto split; + } + if (ret != 0) + goto err; + + switch (flags) { /* Adjust the cursors. */ + case DB_AFTER: + if ((ret = __ram_ca(dbc, CA_IAFTER, &nc)) != 0) + goto err; + + /* + * We only need to adjust this cursor forward if we truly added + * the item after the current recno, rather than remapping it + * to DB_BEFORE. + */ + if (iiflags == DB_AFTER) + ++cp->recno; + + /* Only log if __ram_ca found any relevant cursors. */ + if (nc > 0 && CURADJ_LOG(dbc) && + (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, CA_IAFTER, + cp->root, cp->recno, cp->order)) != 0) + goto err; + break; + case DB_BEFORE: + if ((ret = __ram_ca(dbc, CA_IBEFORE, &nc)) != 0) + goto err; + --cp->recno; + + /* Only log if __ram_ca found any relevant cursors. */ + if (nc > 0 && CURADJ_LOG(dbc) && + (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, CA_IBEFORE, + cp->root, cp->recno, cp->order)) != 0) + goto err; + break; + case DB_CURRENT: + /* + * We only need to do an adjustment if we actually + * added an item, which we only would have done if the + * cursor was marked deleted. + */ + if (!CD_ISSET(cp)) + break; + + /* Only log if __ram_ca found any relevant cursors. */ + if ((ret = __ram_ca(dbc, CA_ICURRENT, &nc)) != 0) + goto err; + if (nc > 0 && CURADJ_LOG(dbc) && + (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, + CA_ICURRENT, cp->root, cp->recno, cp->order)) != 0) + goto err; + break; + default: + break; + } + + /* Return the key if we've created a new record. */ + if (!F_ISSET(dbc, DBC_OPD) && + (flags == DB_AFTER || flags == DB_BEFORE) && key != NULL) + ret = __db_retcopy(env, key, &cp->recno, + sizeof(cp->recno), &dbc->rkey->data, &dbc->rkey->ulen); + + /* The cursor was reset, no further delete adjustment is necessary. */ +err: CD_CLR(cp); + + return (ret); +} + +/* + * __ram_ca -- + * Adjust cursors. Returns the number of relevant cursors. + * + * PUBLIC: int __ram_ca __P((DBC *, ca_recno_arg, int *)); + */ +int +__ram_ca(dbc_arg, op, foundp) + DBC *dbc_arg; + ca_recno_arg op; + int *foundp; +{ + BTREE_CURSOR *cp, *cp_arg; + DB *dbp, *ldbp; + DBC *dbc; + ENV *env; + db_recno_t recno; + u_int32_t order; + int adjusted, found; + + dbp = dbc_arg->dbp; + env = dbp->env; + cp_arg = (BTREE_CURSOR *)dbc_arg->internal; + recno = cp_arg->recno; + + /* + * It only makes sense to adjust cursors if we're a renumbering + * recno; we should only be called if this is one. + */ + DB_ASSERT(env, F_ISSET(cp_arg, C_RENUMBER)); + + MUTEX_LOCK(env, env->mtx_dblist); + /* + * Adjust the cursors. See the comment in __bam_ca_delete(). + * + * If we're doing a delete, we need to find the highest + * order of any cursor currently pointing at this item, + * so we can assign a higher order to the newly deleted + * cursor. Unfortunately, this requires a second pass through + * the cursor list. + */ + if (op == CA_DELETE) { + FIND_FIRST_DB_MATCH(env, dbp, ldbp); + for (order = 1; + ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; + ldbp = TAILQ_NEXT(ldbp, dblistlinks)) { + MUTEX_LOCK(env, dbp->mutex); + TAILQ_FOREACH(dbc, &ldbp->active_queue, links) { + cp = (BTREE_CURSOR *)dbc->internal; + if (cp_arg->root == cp->root && + recno == cp->recno && CD_ISSET(cp) && + order <= cp->order && + !MVCC_SKIP_CURADJ(dbc, cp->root)) + order = cp->order + 1; + } + MUTEX_UNLOCK(env, dbp->mutex); + } + } else + order = INVALID_ORDER; + + /* Now go through and do the actual adjustments. */ + FIND_FIRST_DB_MATCH(env, dbp, ldbp); + for (found = 0; + ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; + ldbp = TAILQ_NEXT(ldbp, dblistlinks)) { + MUTEX_LOCK(env, dbp->mutex); + TAILQ_FOREACH(dbc, &ldbp->active_queue, links) { + cp = (BTREE_CURSOR *)dbc->internal; + if (cp_arg->root != cp->root || + MVCC_SKIP_CURADJ(dbc, cp->root)) + continue; + ++found; + adjusted = 0; + switch (op) { + case CA_DELETE: + if (recno < cp->recno) { + --cp->recno; + /* + * If the adjustment made them equal, + * we have to merge the orders. + */ + if (recno == cp->recno && CD_ISSET(cp)) + cp->order += order; + } else if (recno == cp->recno && + !CD_ISSET(cp)) { + CD_SET(cp); + cp->order = order; + /* + * If we're deleting the item, we can't + * keep a streaming offset cached. + */ + cp->stream_start_pgno = PGNO_INVALID; + } + break; + case CA_IBEFORE: + /* + * IBEFORE is just like IAFTER, except that we + * adjust cursors on the current record too. + */ + if (C_EQUAL(cp_arg, cp)) { + ++cp->recno; + adjusted = 1; + } + goto iafter; + case CA_ICURRENT: + + /* + * If the original cursor wasn't deleted, we + * just did a replacement and so there's no + * need to adjust anything--we shouldn't have + * gotten this far. Otherwise, we behave + * much like an IAFTER, except that all + * cursors pointing to the current item get + * marked undeleted and point to the new + * item. + */ + DB_ASSERT(env, CD_ISSET(cp_arg)); + if (C_EQUAL(cp_arg, cp)) { + CD_CLR(cp); + break; + } + /* FALLTHROUGH */ + case CA_IAFTER: +iafter: if (!adjusted && C_LESSTHAN(cp_arg, cp)) { + ++cp->recno; + adjusted = 1; + } + if (recno == cp->recno && adjusted) + /* + * If we've moved this cursor's recno, + * split its order number--i.e., + * decrement it by enough so that + * the lowest cursor moved has order 1. + * cp_arg->order is the split point, + * so decrement by one less than that. + */ + cp->order -= (cp_arg->order - 1); + break; + } + } + MUTEX_UNLOCK(dbp->env, dbp->mutex); + } + MUTEX_UNLOCK(env, env->mtx_dblist); + + if (foundp != NULL) + *foundp = found; + return (0); +} + +/* + * __ram_getno -- + * Check the user's record number, and make sure we've seen it. + * + * PUBLIC: int __ram_getno __P((DBC *, const DBT *, db_recno_t *, int)); + */ +int +__ram_getno(dbc, key, rep, can_create) + DBC *dbc; + const DBT *key; + db_recno_t *rep; + int can_create; +{ + DB *dbp; + db_recno_t recno; + + dbp = dbc->dbp; + + /* If passed an empty DBT from Java, key->data may be NULL */ + if (key->size != sizeof(db_recno_t)) { + __db_errx(dbp->env, "illegal record number size"); + return (EINVAL); + } + + /* Check the user's record number. */ + if ((recno = *(db_recno_t *)key->data) == 0) { + __db_errx(dbp->env, "illegal record number of 0"); + return (EINVAL); + } + if (rep != NULL) + *rep = recno; + + /* + * Btree can neither create records nor read them in. Recno can + * do both, see if we can find the record. + */ + return (dbc->dbtype == DB_RECNO ? + __ram_update(dbc, recno, can_create) : 0); +} + +/* + * __ram_update -- + * Ensure the tree has records up to and including the specified one. + */ +static int +__ram_update(dbc, recno, can_create) + DBC *dbc; + db_recno_t recno; + int can_create; +{ + BTREE *t; + DB *dbp; + DBT *rdata; + db_recno_t nrecs; + int ret; + + dbp = dbc->dbp; + t = dbp->bt_internal; + + /* + * If we can't create records and we've read the entire backing input + * file, we're done. + */ + if (!can_create && t->re_eof) + return (0); + + /* + * If we haven't seen this record yet, try to get it from the original + * file. + */ + if ((ret = __bam_nrecs(dbc, &nrecs)) != 0) + return (ret); + if (!t->re_eof && recno > nrecs) { + if ((ret = __ram_sread(dbc, recno)) != 0 && ret != DB_NOTFOUND) + return (ret); + if ((ret = __bam_nrecs(dbc, &nrecs)) != 0) + return (ret); + } + + /* + * If we can create records, create empty ones up to the requested + * record. + */ + if (!can_create || recno <= nrecs + 1) + return (0); + + rdata = &dbc->my_rdata; + rdata->flags = 0; + rdata->size = 0; + + while (recno > ++nrecs) + if ((ret = __ram_add(dbc, + &nrecs, rdata, 0, BI_DELETED)) != 0) + return (ret); + return (0); +} + +/* + * __ram_source -- + * Load information about the backing file. + */ +static int +__ram_source(dbp) + DB *dbp; +{ + BTREE *t; + ENV *env; + char *source; + int ret; + + env = dbp->env; + t = dbp->bt_internal; + + /* Find the real name, and swap out the one we had before. */ + if ((ret = __db_appname(env, + DB_APP_DATA, t->re_source, NULL, &source)) != 0) + return (ret); + __os_free(env, t->re_source); + t->re_source = source; + + /* + * !!! + * It's possible that the backing source file is read-only. We don't + * much care other than we'll complain if there are any modifications + * when it comes time to write the database back to the source. + */ + if ((t->re_fp = fopen(t->re_source, "rb")) == NULL) { + ret = __os_get_errno(); + __db_err(env, ret, "%s", t->re_source); + return (ret); + } + + t->re_eof = 0; + return (0); +} + +/* + * __ram_writeback -- + * Rewrite the backing file. + * + * PUBLIC: int __ram_writeback __P((DB *)); + */ +int +__ram_writeback(dbp) + DB *dbp; +{ + BTREE *t; + DBC *dbc; + DBT key, data; + DB_THREAD_INFO *ip; + ENV *env; + FILE *fp; + db_recno_t keyno; + int ret, t_ret; + u_int8_t delim, *pad; + + t = dbp->bt_internal; + env = dbp->env; + fp = NULL; + pad = NULL; + + /* If the file wasn't modified, we're done. */ + if (!t->re_modified) + return (0); + + /* If there's no backing source file, we're done. */ + if (t->re_source == NULL) { + t->re_modified = 0; + return (0); + } + + /* + * We step through the records, writing each one out. Use the record + * number and the dbp->get() function, instead of a cursor, so we find + * and write out "deleted" or non-existent records. The DB handle may + * be threaded, so allocate memory as we go. + */ + memset(&key, 0, sizeof(key)); + key.size = sizeof(db_recno_t); + key.data = &keyno; + memset(&data, 0, sizeof(data)); + F_SET(&data, DB_DBT_REALLOC); + + /* Allocate a cursor. */ + ENV_GET_THREAD_INFO(env, ip); + if ((ret = __db_cursor(dbp, ip, NULL, &dbc, 0)) != 0) + return (ret); + + /* + * Read any remaining records into the tree. + * + * !!! + * This is why we can't support transactions when applications specify + * backing (re_source) files. At this point we have to read in the + * rest of the records from the file so that we can write all of the + * records back out again, which could modify a page for which we'd + * have to log changes and which we don't have locked. This could be + * partially fixed by taking a snapshot of the entire file during the + * DB->open as DB->open is transaction protected. But, if a checkpoint + * occurs then, the part of the log holding the copy of the file could + * be discarded, and that would make it impossible to recover in the + * face of disaster. This could all probably be fixed, but it would + * require transaction protecting the backing source file. + * + * XXX + * This could be made to work now that we have transactions protecting + * file operations. Margo has specifically asked for the privilege of + * doing this work. + */ + if ((ret = + __ram_update(dbc, DB_MAX_RECORDS, 0)) != 0 && ret != DB_NOTFOUND) + goto err; + + /* + * Close any existing file handle and re-open the file, truncating it. + */ + if (t->re_fp != NULL) { + if (fclose(t->re_fp) != 0) { + ret = __os_get_errno(); + __db_err(env, ret, "%s", t->re_source); + goto err; + } + t->re_fp = NULL; + } + if ((fp = fopen(t->re_source, "wb")) == NULL) { + ret = __os_get_errno(); + __db_err(env, ret, "%s", t->re_source); + goto err; + } + + /* + * We'll need the delimiter if we're doing variable-length records, + * and the pad character if we're doing fixed-length records. + */ + delim = t->re_delim; + for (keyno = 1;; ++keyno) { + switch (ret = __db_get(dbp, ip, NULL, &key, &data, 0)) { + case 0: + if (data.size != 0 && + fwrite(data.data, 1, data.size, fp) != data.size) + goto write_err; + break; + case DB_KEYEMPTY: + if (F_ISSET(dbp, DB_AM_FIXEDLEN)) { + if (pad == NULL) { + if ((ret = __os_malloc( + env, t->re_len, &pad)) != 0) + goto err; + memset(pad, t->re_pad, t->re_len); + } + if (fwrite(pad, 1, t->re_len, fp) != t->re_len) + goto write_err; + } + break; + case DB_NOTFOUND: + ret = 0; + goto done; + default: + goto err; + } + if (!F_ISSET(dbp, DB_AM_FIXEDLEN) && + fwrite(&delim, 1, 1, fp) != 1) { +write_err: ret = __os_get_errno(); + __db_err(env, ret, + "%s: write failed to backing file", t->re_source); + goto err; + } + } + +err: +done: /* Close the file descriptor. */ + if (fp != NULL && fclose(fp) != 0) { + t_ret = __os_get_errno(); + __db_err(env, t_ret, "%s", t->re_source); + if (ret == 0) + ret = t_ret; + } + + /* Discard the cursor. */ + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + + /* Discard memory allocated to hold the data items. */ + if (data.data != NULL) + __os_ufree(env, data.data); + if (pad != NULL) + __os_free(env, pad); + + if (ret == 0) + t->re_modified = 0; + + return (ret); +} + +/* + * __ram_sread -- + * Read records from a source file. + */ +static int +__ram_sread(dbc, top) + DBC *dbc; + db_recno_t top; +{ + BTREE *t; + DB *dbp; + DBT data, *rdata; + db_recno_t recno; + size_t len; + int ch, ret, was_modified; + + t = dbc->dbp->bt_internal; + dbp = dbc->dbp; + was_modified = t->re_modified; + + if ((ret = __bam_nrecs(dbc, &recno)) != 0) + return (ret); + + /* + * Use the record key return memory, it's only a short-term use. + * The record data return memory is used by __bam_iitem, which + * we'll indirectly call, so use the key so as not to collide. + */ + len = F_ISSET(dbp, DB_AM_FIXEDLEN) ? t->re_len : 256; + rdata = &dbc->my_rkey; + if (rdata->ulen < len) { + if ((ret = __os_realloc( + dbp->env, len, &rdata->data)) != 0) { + rdata->ulen = 0; + rdata->data = NULL; + return (ret); + } + rdata->ulen = (u_int32_t)len; + } + + memset(&data, 0, sizeof(data)); + while (recno < top) { + data.data = rdata->data; + data.size = 0; + if (F_ISSET(dbp, DB_AM_FIXEDLEN)) + for (len = t->re_len; len > 0; --len) { + if ((ch = fgetc(t->re_fp)) == EOF) { + if (data.size == 0) + goto eof; + break; + } + ((u_int8_t *)data.data)[data.size++] = ch; + } + else + for (;;) { + if ((ch = fgetc(t->re_fp)) == EOF) { + if (data.size == 0) + goto eof; + break; + } + if (ch == t->re_delim) + break; + + ((u_int8_t *)data.data)[data.size++] = ch; + if (data.size == rdata->ulen) { + if ((ret = __os_realloc(dbp->env, + rdata->ulen *= 2, + &rdata->data)) != 0) { + rdata->ulen = 0; + rdata->data = NULL; + return (ret); + } else + data.data = rdata->data; + } + } + + /* + * Another process may have read this record from the input + * file and stored it into the database already, in which + * case we don't need to repeat that operation. We detect + * this by checking if the last record we've read is greater + * or equal to the number of records in the database. + */ + if (t->re_last >= recno) { + ++recno; + if ((ret = __ram_add(dbc, &recno, &data, 0, 0)) != 0) + goto err; + } + ++t->re_last; + } + + if (0) { +eof: t->re_eof = 1; + ret = DB_NOTFOUND; + } +err: if (!was_modified) + t->re_modified = 0; + + return (ret); +} + +/* + * __ram_add -- + * Add records into the tree. + */ +static int +__ram_add(dbc, recnop, data, flags, bi_flags) + DBC *dbc; + db_recno_t *recnop; + DBT *data; + u_int32_t flags, bi_flags; +{ + BTREE_CURSOR *cp; + int exact, ret, stack, t_ret; + + cp = (BTREE_CURSOR *)dbc->internal; + +retry: /* Find the slot for insertion. */ + if ((ret = __bam_rsearch(dbc, recnop, + SR_INSERT | (flags == DB_APPEND ? SR_APPEND : 0), 1, &exact)) != 0) + return (ret); + stack = 1; + + /* Copy the page into the cursor. */ + STACK_TO_CURSOR(cp, ret); + if (ret != 0) + goto err; + + if (exact && flags == DB_NOOVERWRITE && !CD_ISSET(cp) && + !B_DISSET(GET_BKEYDATA(dbc->dbp, cp->page, cp->indx)->type)) { + ret = DB_KEYEXIST; + goto err; + } + + /* + * The application may modify the data based on the selected record + * number. + */ + if (flags == DB_APPEND && dbc->dbp->db_append_recno != NULL && + (ret = dbc->dbp->db_append_recno(dbc->dbp, data, *recnop)) != 0) + goto err; + + /* + * Select the arguments for __bam_iitem() and do the insert. If the + * key is an exact match, or we're replacing the data item with a + * new data item, replace the current item. If the key isn't an exact + * match, we're inserting a new key/data pair, before the search + * location. + */ + switch (ret = __bam_iitem(dbc, + NULL, data, exact ? DB_CURRENT : DB_BEFORE, bi_flags)) { + case 0: + /* + * Don't adjust anything. + * + * If we inserted a record, no cursors need adjusting because + * the only new record it's possible to insert is at the very + * end of the tree. The necessary adjustments to the internal + * page counts were made by __bam_iitem(). + * + * If we overwrote a record, no cursors need adjusting because + * future DBcursor->get calls will simply return the underlying + * record (there's no adjustment made for the DB_CURRENT flag + * when a cursor get operation immediately follows a cursor + * delete operation, and the normal adjustment for the DB_NEXT + * flag is still correct). + */ + break; + case DB_NEEDSPLIT: + /* Discard the stack of pages and split the page. */ + (void)__bam_stkrel(dbc, STK_CLRDBC); + stack = 0; + + if ((ret = __bam_split(dbc, recnop, NULL)) != 0) + goto err; + + goto retry; + /* NOTREACHED */ + default: + goto err; + } + +err: if (stack && (t_ret = __bam_stkrel(dbc, STK_CLRDBC)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_rsearch.c b/src/libs/resiprocate/contrib/db/btree/bt_rsearch.c new file mode 100644 index 00000000..1d5581a5 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_rsearch.c @@ -0,0 +1,502 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" + +/* + * __bam_rsearch -- + * Search a btree for a record number. + * + * PUBLIC: int __bam_rsearch __P((DBC *, db_recno_t *, u_int32_t, int, int *)); + */ +int +__bam_rsearch(dbc, recnop, flags, stop, exactp) + DBC *dbc; + db_recno_t *recnop; + u_int32_t flags; + int stop, *exactp; +{ + BINTERNAL *bi; + BTREE_CURSOR *cp; + DB *dbp; + DB_LOCK lock; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *h; + RINTERNAL *ri; + db_indx_t adjust, deloffset, indx, top; + db_lockmode_t lock_mode; + db_pgno_t pg; + db_recno_t recno, t_recno, total; + u_int32_t get_mode; + int ret, stack, t_ret; + + dbp = dbc->dbp; + env = dbp->env; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + h = NULL; + + BT_STK_CLR(cp); + + /* + * There are several ways we search a btree tree. The flags argument + * specifies if we're acquiring read or write locks and if we are + * locking pairs of pages. In addition, if we're adding or deleting + * an item, we have to lock the entire tree, regardless. See btree.h + * for more details. + * + * If write-locking pages, we need to know whether or not to acquire a + * write lock on a page before getting it. This depends on how deep it + * is in tree, which we don't know until we acquire the root page. So, + * if we need to lock the root page we may have to upgrade it later, + * because we won't get the correct lock initially. + * + * Retrieve the root page. + */ + + if ((ret = __bam_get_root(dbc, cp->root, stop, flags, &stack)) != 0) + return (ret); + lock_mode = cp->csp->lock_mode; + get_mode = lock_mode == DB_LOCK_WRITE ? DB_MPOOL_DIRTY : 0; + lock = cp->csp->lock; + h = cp->csp->page; + + BT_STK_CLR(cp); + /* + * If appending to the tree, set the record number now -- we have the + * root page locked. + * + * Delete only deletes exact matches, read only returns exact matches. + * Note, this is different from __bam_search(), which returns non-exact + * matches for read. + * + * The record may not exist. We can only return the correct location + * for the record immediately after the last record in the tree, so do + * a fast check now. + */ + total = RE_NREC(h); + if (LF_ISSET(SR_APPEND)) { + *exactp = 0; + *recnop = recno = total + 1; + } else { + recno = *recnop; + if (recno <= total) + *exactp = 1; + else { + *exactp = 0; + if (!LF_ISSET(SR_PAST_EOF) || recno > total + 1) { + /* + * Keep the page locked for serializability. + * + * XXX + * This leaves the root page locked, which will + * eliminate any concurrency. A possible fix + * would be to lock the last leaf page instead. + */ + ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority); + if ((t_ret = + __TLPUT(dbc, lock)) != 0 && ret == 0) + ret = t_ret; + return (ret == 0 ? DB_NOTFOUND : ret); + } + } + } + + /* + * !!! + * Record numbers in the tree are 0-based, but the recno is + * 1-based. All of the calculations below have to take this + * into account. + */ + for (total = 0;;) { + switch (TYPE(h)) { + case P_LBTREE: + if (LF_ISSET(SR_MAX)) { + indx = NUM_ENT(h) - 2; + goto enter; + } + /* FALLTHROUGH */ + case P_LDUP: + if (LF_ISSET(SR_MAX)) { + indx = NUM_ENT(h) - 1; + goto enter; + } + recno -= total; + /* + * There may be logically deleted records on the page. + * If there are enough, the record may not exist. + */ + if (TYPE(h) == P_LBTREE) { + adjust = P_INDX; + deloffset = O_INDX; + } else { + adjust = O_INDX; + deloffset = 0; + } + for (t_recno = 0, indx = 0;; indx += adjust) { + if (indx >= NUM_ENT(h)) { + *exactp = 0; + if (!LF_ISSET(SR_PAST_EOF) || + recno > t_recno + 1) { + ret = __memp_fput(mpf, + dbc->thread_info, + h, dbc->priority); + h = NULL; + if ((t_ret = __TLPUT(dbc, + lock)) != 0 && ret == 0) + ret = t_ret; + if (ret == 0) + ret = DB_NOTFOUND; + goto err; + } + } + if (!B_DISSET(GET_BKEYDATA(dbp, h, + indx + deloffset)->type) && + ++t_recno == recno) + break; + } + + BT_STK_ENTER(env, cp, h, indx, lock, lock_mode, ret); + if (ret != 0) + goto err; + if (LF_ISSET(SR_BOTH)) + goto get_prev; + return (0); + case P_IBTREE: + if (LF_ISSET(SR_MAX)) { + indx = NUM_ENT(h); + bi = GET_BINTERNAL(dbp, h, indx - 1); + } else for (indx = 0, top = NUM_ENT(h);;) { + bi = GET_BINTERNAL(dbp, h, indx); + if (++indx == top || total + bi->nrecs >= recno) + break; + total += bi->nrecs; + } + pg = bi->pgno; + break; + case P_LRECNO: + if (LF_ISSET(SR_MAX)) + recno = NUM_ENT(h); + else + recno -= total; + + /* Correct from 1-based to 0-based for a page offset. */ + --recno; +enter: BT_STK_ENTER(env, cp, h, recno, lock, lock_mode, ret); + if (ret != 0) + goto err; + if (LF_ISSET(SR_BOTH)) { +get_prev: DB_ASSERT(env, LF_ISSET(SR_NEXT)); + /* + * We have a NEXT tree, now add the sub tree + * that points gets to the previous page. + */ + cp->csp++; + indx = cp->sp->indx - 1; + h = cp->sp->page; + if (TYPE(h) == P_IRECNO) { + ri = GET_RINTERNAL(dbp, h, indx); + pg = ri->pgno; + } else { + DB_ASSERT(env, TYPE(h) == P_IBTREE); + bi = GET_BINTERNAL(dbp, h, indx); + pg = bi->pgno; + } + LF_CLR(SR_NEXT | SR_BOTH); + LF_SET(SR_MAX); + stack = 1; + h = NULL; + goto lock_next; + } + return (0); + case P_IRECNO: + if (LF_ISSET(SR_MAX)) { + indx = NUM_ENT(h); + ri = GET_RINTERNAL(dbp, h, indx - 1); + } else for (indx = 0, top = NUM_ENT(h);;) { + ri = GET_RINTERNAL(dbp, h, indx); + if (++indx == top || total + ri->nrecs >= recno) + break; + total += ri->nrecs; + } + pg = ri->pgno; + break; + default: + return (__db_pgfmt(env, h->pgno)); + } + --indx; + + /* Return if this is the lowest page wanted. */ + if (stop == LEVEL(h)) { + BT_STK_ENTER(env, cp, h, indx, lock, lock_mode, ret); + if (ret != 0) + goto err; + return (0); + } + if (stack) { + BT_STK_PUSH(env, cp, h, indx, lock, lock_mode, ret); + if (ret != 0) + goto err; + h = NULL; + + lock_mode = DB_LOCK_WRITE; + get_mode = DB_MPOOL_DIRTY; + if ((ret = + __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0) + goto err; + } else if (LF_ISSET(SR_NEXT)) { + /* + * For RECNO if we are doing a NEXT search the + * search recno is the one we are looking for + * but we want to keep the stack from the spanning + * node on down. We only know we have the spanning + * node when its child's index is 0, so save + * each node and discard the tree when we find out + * its not needed. + */ + if (indx != 0 && cp->sp->page != NULL) { + BT_STK_POP(cp); + if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0) + goto err; + } + + BT_STK_PUSH(env, cp, h, indx, lock, lock_mode, ret); + h = NULL; + if (ret != 0) + goto err; +lock_next: if ((ret = + __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0) + goto err; + } else { + /* + * Decide if we want to return a pointer to the next + * page in the stack. If we do, write lock it and + * never unlock it. + */ + if ((LF_ISSET(SR_PARENT) && + (u_int8_t)(stop + 1) >= (u_int8_t)(LEVEL(h) - 1)) || + (LEVEL(h) - 1) == LEAFLEVEL) + stack = 1; + + if ((ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0) + goto err; + h = NULL; + + lock_mode = stack && + LF_ISSET(SR_WRITE) ? DB_LOCK_WRITE : DB_LOCK_READ; + if (lock_mode == DB_LOCK_WRITE) + get_mode = DB_MPOOL_DIRTY; + if ((ret = __db_lget(dbc, + LCK_COUPLE_ALWAYS, pg, lock_mode, 0, &lock)) != 0) { + /* + * If we fail, discard the lock we held. This + * is OK because this only happens when we are + * descending the tree holding read-locks. + */ + (void)__LPUT(dbc, lock); + goto err; + } + } + + if ((ret = __memp_fget(mpf, &pg, + dbc->thread_info, dbc->txn, get_mode, &h)) != 0) + goto err; + } + /* NOTREACHED */ + +err: if (h != NULL && (t_ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + + BT_STK_POP(cp); + (void)__bam_stkrel(dbc, 0); + + return (ret); +} + +/* + * __bam_adjust -- + * Adjust the tree after adding or deleting a record. + * + * PUBLIC: int __bam_adjust __P((DBC *, int32_t)); + */ +int +__bam_adjust(dbc, adjust) + DBC *dbc; + int32_t adjust; +{ + BTREE_CURSOR *cp; + DB *dbp; + DB_MPOOLFILE *mpf; + EPG *epg; + PAGE *h; + db_pgno_t root_pgno; + int ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + root_pgno = cp->root; + + /* Update the record counts for the tree. */ + for (epg = cp->sp; epg <= cp->csp; ++epg) { + h = epg->page; + if (TYPE(h) == P_IBTREE || TYPE(h) == P_IRECNO) { + ret = __memp_dirty(mpf, &h, + dbc->thread_info, dbc->txn, dbc->priority, 0); + epg->page = h; + if (ret != 0) + return (ret); + if (DBC_LOGGING(dbc)) { + if ((ret = __bam_cadjust_log(dbp, dbc->txn, + &LSN(h), 0, PGNO(h), &LSN(h), + (u_int32_t)epg->indx, adjust, + PGNO(h) == root_pgno ? + CAD_UPDATEROOT : 0)) != 0) + return (ret); + } else + LSN_NOT_LOGGED(LSN(h)); + + if (TYPE(h) == P_IBTREE) + GET_BINTERNAL(dbp, h, epg->indx)->nrecs += + adjust; + else + GET_RINTERNAL(dbp, h, epg->indx)->nrecs += + adjust; + + if (PGNO(h) == root_pgno) + RE_NREC_ADJ(h, adjust); + } + } + return (0); +} + +/* + * __bam_nrecs -- + * Return the number of records in the tree. + * + * PUBLIC: int __bam_nrecs __P((DBC *, db_recno_t *)); + */ +int +__bam_nrecs(dbc, rep) + DBC *dbc; + db_recno_t *rep; +{ + DB *dbp; + DB_LOCK lock; + DB_MPOOLFILE *mpf; + PAGE *h; + db_pgno_t pgno; + int ret, t_ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + + pgno = dbc->internal->root; + if ((ret = __db_lget(dbc, 0, pgno, DB_LOCK_READ, 0, &lock)) != 0) + return (ret); + if ((ret = __memp_fget(mpf, &pgno, + dbc->thread_info, dbc->txn, 0, &h)) != 0) + return (ret); + + *rep = RE_NREC(h); + + ret = __memp_fput(mpf, dbc->thread_info, h, dbc->priority); + if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __bam_total -- + * Return the number of records below a page. + * + * PUBLIC: db_recno_t __bam_total __P((DB *, PAGE *)); + */ +db_recno_t +__bam_total(dbp, h) + DB *dbp; + PAGE *h; +{ + db_recno_t nrecs; + db_indx_t indx, top; + + nrecs = 0; + top = NUM_ENT(h); + + switch (TYPE(h)) { + case P_LBTREE: + /* Check for logically deleted records. */ + for (indx = 0; indx < top; indx += P_INDX) + if (!B_DISSET( + GET_BKEYDATA(dbp, h, indx + O_INDX)->type)) + ++nrecs; + break; + case P_LDUP: + /* Check for logically deleted records. */ + for (indx = 0; indx < top; indx += O_INDX) + if (!B_DISSET(GET_BKEYDATA(dbp, h, indx)->type)) + ++nrecs; + break; + case P_IBTREE: + for (indx = 0; indx < top; indx += O_INDX) + nrecs += GET_BINTERNAL(dbp, h, indx)->nrecs; + break; + case P_LRECNO: + nrecs = NUM_ENT(h); + break; + case P_IRECNO: + for (indx = 0; indx < top; indx += O_INDX) + nrecs += GET_RINTERNAL(dbp, h, indx)->nrecs; + break; + } + + return (nrecs); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_search.c b/src/libs/resiprocate/contrib/db/btree/bt_search.c new file mode 100644 index 00000000..6176b86f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_search.c @@ -0,0 +1,965 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" + +/* + * __bam_get_root -- + * Fetch the root of a tree and see if we want to keep + * it in the stack. + * + * PUBLIC: int __bam_get_root __P((DBC *, db_pgno_t, int, u_int32_t, int *)); + */ +int +__bam_get_root(dbc, pg, slevel, flags, stack) + DBC *dbc; + db_pgno_t pg; + int slevel; + u_int32_t flags; + int *stack; +{ + BTREE_CURSOR *cp; + DB *dbp; + DB_LOCK lock; + DB_MPOOLFILE *mpf; + PAGE *h; + db_lockmode_t lock_mode; + u_int32_t get_mode; + int ret, t_ret; + + LOCK_INIT(lock); + dbp = dbc->dbp; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + /* + * If write-locking pages, we need to know whether or not to acquire a + * write lock on a page before getting it. This depends on how deep it + * is in tree, which we don't know until we acquire the root page. So, + * if we need to lock the root page we may have to upgrade it later, + * because we won't get the correct lock initially. + * + * Retrieve the root page. + */ +try_again: + *stack = LF_ISSET(SR_STACK) && + (dbc->dbtype == DB_RECNO || F_ISSET(cp, C_RECNUM)); + lock_mode = DB_LOCK_READ; + if (*stack || + LF_ISSET(SR_DEL) || (LF_ISSET(SR_NEXT) && LF_ISSET(SR_WRITE))) + lock_mode = DB_LOCK_WRITE; + if ((lock_mode == DB_LOCK_WRITE || F_ISSET(dbc, DBC_DOWNREV) || + dbc->dbtype == DB_RECNO || F_ISSET(cp, C_RECNUM))) { +lock_it: if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0) + return (ret); + } + + /* + * Get the root. If the root happens to be a leaf page then + * we are supposed to get a read lock on it before latching + * it. So if we have not locked it do a try get first. + * If we can't get the root shared, then get a lock on it and + * then wait for the latch. + */ + if (lock_mode == DB_LOCK_WRITE) + get_mode = DB_MPOOL_DIRTY; + else if (LOCK_ISSET(lock) || !STD_LOCKING(dbc)) + get_mode = 0; + else + get_mode = DB_MPOOL_TRY; + + if ((ret = __memp_fget(mpf, &pg, + dbc->thread_info, dbc->txn, get_mode, &h)) != 0) { + if (ret == DB_LOCK_NOTGRANTED) + goto lock_it; + /* Did not read it, so we can release the lock */ + (void)__LPUT(dbc, lock); + return (ret); + } + + /* + * Decide if we need to dirty and/or lock this page. + * We must not hold the latch while we get the lock. + */ + if (!*stack && + ((LF_ISSET(SR_PARENT) && (u_int8_t)(slevel + 1) >= LEVEL(h)) || + LEVEL(h) == LEAFLEVEL || + (LF_ISSET(SR_START) && slevel == LEVEL(h)))) { + *stack = 1; + /* If we already have the write lock, we are done. */ + if (dbc->dbtype == DB_RECNO || F_ISSET(cp, C_RECNUM)) { + if (lock_mode == DB_LOCK_WRITE) + goto done; + if ((ret = __LPUT(dbc, lock)) != 0) + return (ret); + } + + /* + * Now that we know what level the root is at, do we need a + * write lock? If not and we got the lock before latching + * we are done. + */ + if (LEVEL(h) != LEAFLEVEL || LF_ISSET(SR_WRITE)) { + lock_mode = DB_LOCK_WRITE; + /* Drop the read lock if we got it above. */ + if ((ret = __LPUT(dbc, lock)) != 0) + return (ret); + } else if (LOCK_ISSET(lock)) + goto done; + if (!STD_LOCKING(dbc)) { + if (lock_mode != DB_LOCK_WRITE) + goto done; + if ((ret = __memp_dirty(mpf, &h, dbc->thread_info, + dbc->txn, dbc->priority, 0)) != 0) { + if (h != NULL) + (void)__memp_fput(mpf, + dbc->thread_info, h, dbc->priority); + return (ret); + } + } else { + /* Try to lock the page without waiting first. */ + if ((ret = __db_lget(dbc, + 0, pg, lock_mode, DB_LOCK_NOWAIT, &lock)) == 0) { + if (lock_mode == DB_LOCK_WRITE && (ret = + __memp_dirty(mpf, &h, dbc->thread_info, + dbc->txn, dbc->priority, 0)) != 0) { + if (h != NULL) + (void)__memp_fput(mpf, + dbc->thread_info, h, + dbc->priority); + return (ret); + } + goto done; + } + + t_ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority); + + if (ret == DB_LOCK_DEADLOCK || + ret == DB_LOCK_NOTGRANTED) + ret = 0; + if (ret == 0) + ret = t_ret; + + if (ret != 0) + return (ret); + + if ((ret = __db_lget(dbc, + 0, pg, lock_mode, 0, &lock)) != 0) + return (ret); + if ((ret = __memp_fget(mpf, + &pg, dbc->thread_info, dbc->txn, + lock_mode == DB_LOCK_WRITE ? DB_MPOOL_DIRTY : 0, + &h)) != 0) { + /* Did not read it, release the lock */ + (void)__LPUT(dbc, lock); + return (ret); + } + } + /* + * While getting dirty or locked we need to drop the mutex + * so someone else could get in and split the root. + */ + if (!((LF_ISSET(SR_PARENT) && + (u_int8_t)(slevel + 1) >= LEVEL(h)) || + LEVEL(h) == LEAFLEVEL || + (LF_ISSET(SR_START) && slevel == LEVEL(h)))) { + /* Someone else split the root, start over. */ + ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority); + if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + return (ret); + goto try_again; + } + } + +done: BT_STK_ENTER(dbp->env, cp, h, 0, lock, lock_mode, ret); + + return (ret); +} + +/* + * __bam_search -- + * Search a btree for a key. + * + * PUBLIC: int __bam_search __P((DBC *, db_pgno_t, + * PUBLIC: const DBT *, u_int32_t, int, db_recno_t *, int *)); + */ +int +__bam_search(dbc, root_pgno, key, flags, slevel, recnop, exactp) + DBC *dbc; + db_pgno_t root_pgno; + const DBT *key; + u_int32_t flags; + int slevel, *exactp; + db_recno_t *recnop; +{ + BTREE *t; + BTREE_CURSOR *cp; + DB *dbp; + DB_LOCK lock, saved_lock; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *h, *parent_h; + db_indx_t base, i, indx, *inp, lim; + db_lockmode_t lock_mode; + db_pgno_t pg, saved_pg; + db_recno_t recno; + int adjust, cmp, deloffset, ret, set_stack, stack, t_ret; + int getlock, was_next; + int (*func) __P((DB *, const DBT *, const DBT *)); + u_int32_t get_mode, wait; + u_int8_t level, saved_level; + + dbp = dbc->dbp; + env = dbp->env; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + h = NULL; + parent_h = NULL; + t = dbp->bt_internal; + recno = 0; + t_ret = 0; + + BT_STK_CLR(cp); + LOCK_INIT(saved_lock); + LOCK_INIT(lock); + was_next = LF_ISSET(SR_NEXT); + wait = DB_LOCK_NOWAIT; + + /* + * There are several ways we search a btree tree. The flags argument + * specifies if we're acquiring read or write latches, if we position + * to the first or last item in a set of duplicates, if we return + * deleted items, and if we are latching pairs of pages. In addition, + * if we're modifying record numbers, we have to latch the entire tree + * regardless. See btree.h for more details. + */ + + if (root_pgno == PGNO_INVALID) + root_pgno = cp->root; + saved_pg = root_pgno; + saved_level = MAXBTREELEVEL; +retry: if ((ret = __bam_get_root(dbc, root_pgno, slevel, flags, &stack)) != 0) + goto err; + lock_mode = cp->csp->lock_mode; + get_mode = lock_mode == DB_LOCK_WRITE ? DB_MPOOL_DIRTY : 0; + h = cp->csp->page; + pg = PGNO(h); + lock = cp->csp->lock; + set_stack = stack; + /* + * Determine if we need to lock interiror nodes. + * If we have record numbers we always lock. Otherwise we only + * need to do this if we are write locking and we are returning + * a stack of nodes. SR_NEXT will eventually get a stack and + * release the locks above that level. + */ + if (F_ISSET(dbc, DBC_DOWNREV)) { + getlock = 1; + wait = 0; + } else + getlock = F_ISSET(cp, C_RECNUM) || + (lock_mode == DB_LOCK_WRITE && + (stack || LF_ISSET(SR_NEXT | SR_DEL))); + + /* + * If we are asked a level that is above the root, + * just return the root. This can happen if the tree + * collapses while we are trying to lock the root. + */ + if (!LF_ISSET(SR_START) && LEVEL(h) < slevel) + goto done; + + BT_STK_CLR(cp); + + /* Choose a comparison function. */ + func = F_ISSET(dbc, DBC_OPD) ? + (dbp->dup_compare == NULL ? __bam_defcmp : dbp->dup_compare) : + t->bt_compare; + + for (;;) { + if (TYPE(h) == P_LBTREE) + adjust = P_INDX; + else { + /* + * It is possible to catch an internal page as a change + * is being backed out. Its leaf pages will be locked + * but we must be sure we get to one. If the page + * is not populated enough lock it. + */ + if (TYPE(h) != P_LDUP && NUM_ENT(h) == 0) { + getlock = 1; + level = LEVEL(h) + 1; + if ((ret = __memp_fput(mpf, dbc->thread_info, + h, dbc->priority)) != 0) + goto err; + goto lock_next; + } + adjust = O_INDX; + } + inp = P_INP(dbp, h); + if (LF_ISSET(SR_MIN | SR_MAX)) { + if (LF_ISSET(SR_MIN) || NUM_ENT(h) == 0) + indx = 0; + else if (TYPE(h) == P_LBTREE) + indx = NUM_ENT(h) - 2; + else + indx = NUM_ENT(h) - 1; + + if (LEVEL(h) == LEAFLEVEL || + (!LF_ISSET(SR_START) && LEVEL(h) == slevel)) { + if (LF_ISSET(SR_NEXT)) + goto get_next; + goto found; + } + goto next; + } + /* + * Do a binary search on the current page. If we're searching + * a Btree leaf page, we have to walk the indices in groups of + * two. If we're searching an internal page or a off-page dup + * page, they're an index per page item. If we find an exact + * match on a leaf page, we're done. + */ + DB_BINARY_SEARCH_FOR(base, lim, NUM_ENT(h), adjust) { + DB_BINARY_SEARCH_INCR(indx, base, lim, adjust); + if ((ret = __bam_cmp(dbc, key, h, indx, + func, &cmp)) != 0) + goto err; + if (cmp == 0) { + if (LEVEL(h) == LEAFLEVEL || + (!LF_ISSET(SR_START) && + LEVEL(h) == slevel)) { + if (LF_ISSET(SR_NEXT)) + goto get_next; + goto found; + } + goto next; + } + if (cmp > 0) + DB_BINARY_SEARCH_SHIFT_BASE(indx, base, + lim, adjust); + } + + /* + * No match found. Base is the smallest index greater than + * key and may be zero or a last + O_INDX index. + * + * If it's a leaf page or the stopping point, + * return base as the "found" value. + * Delete only deletes exact matches. + */ + if (LEVEL(h) == LEAFLEVEL || + (!LF_ISSET(SR_START) && LEVEL(h) == slevel)) { + *exactp = 0; + + if (LF_ISSET(SR_EXACT)) { + ret = DB_NOTFOUND; + goto err; + } + + if (LF_ISSET(SR_STK_ONLY)) { + BT_STK_NUM(env, cp, h, base, ret); + if ((t_ret = + __LPUT(dbc, lock)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __memp_fput(mpf, dbc->thread_info, + h, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + h = NULL; + if (ret != 0) + goto err; + goto done; + } + if (LF_ISSET(SR_NEXT)) { +get_next: /* + * The caller could have asked for a NEXT + * at the root if the tree recently collapsed. + */ + if (PGNO(h) == root_pgno) { + ret = DB_NOTFOUND; + goto err; + } + + indx = cp->sp->indx + 1; + if (indx == NUM_ENT(cp->sp->page)) { + ret = DB_NOTFOUND; + cp->csp++; + goto err; + } + /* + * If we want both the key page and the next + * page, push the key page on the stack + * otherwise save the root of the subtree + * and drop the rest of the subtree. + * Search down again starting at the + * next child of the root of this subtree. + */ + LF_SET(SR_MIN); + LF_CLR(SR_NEXT); + set_stack = stack = 1; + if (LF_ISSET(SR_BOTH)) { + cp->csp++; + BT_STK_PUSH(env, + cp, h, indx, lock, lock_mode, ret); + if (ret != 0) + goto err; + LOCK_INIT(lock); + h = cp->sp->page; + pg = GET_BINTERNAL(dbp, h, indx)->pgno; + level = LEVEL(h); + h = NULL; + goto lock_next; + } else { + if ((ret = __LPUT(dbc, lock)) != 0) + goto err; + if ((ret = __memp_fput(mpf, + dbc->thread_info, + h, dbc->priority)) != 0) + goto err; + h = cp->sp->page; + cp->sp->page = NULL; + lock = cp->sp->lock; + LOCK_INIT(cp->sp->lock); + if ((ret = __bam_stkrel(dbc, + STK_NOLOCK)) != 0) + goto err; + goto next; + } + } + + /* + * !!! + * Possibly returning a deleted record -- DB_SET_RANGE, + * DB_KEYFIRST and DB_KEYLAST don't require an exact + * match, and we don't want to walk multiple pages here + * to find an undeleted record. This is handled by the + * calling routine. + */ + if (LF_ISSET(SR_DEL) && cp->csp == cp->sp) + cp->csp++; + BT_STK_ENTER(env, cp, h, base, lock, lock_mode, ret); + if (ret != 0) + goto err; + goto done; + } + + /* + * If it's not a leaf page, record the internal page (which is + * a parent page for the key). Decrement the base by 1 if it's + * non-zero so that if a split later occurs, the inserted page + * will be to the right of the saved page. + */ + indx = base > 0 ? base - O_INDX : base; + + /* + * If we're trying to calculate the record number, sum up + * all the record numbers on this page up to the indx point. + */ +next: if (recnop != NULL) + for (i = 0; i < indx; ++i) + recno += GET_BINTERNAL(dbp, h, i)->nrecs; + + pg = GET_BINTERNAL(dbp, h, indx)->pgno; + level = LEVEL(h); + + /* See if we are at the level to start stacking. */ + if (LF_ISSET(SR_START) && slevel == level) + set_stack = stack = 1; + + if (LF_ISSET(SR_STK_ONLY)) { + if (slevel == LEVEL(h)) { + BT_STK_NUM(env, cp, h, indx, ret); + if ((t_ret = __memp_fput(mpf, dbc->thread_info, + h, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + h = NULL; + if (ret != 0) + goto err; + goto done; + } + BT_STK_NUMPUSH(env, cp, h, indx, ret); + (void)__memp_fput(mpf, + dbc->thread_info, h, dbc->priority); + h = NULL; + } else if (stack) { + /* Return if this is the lowest page wanted. */ + if (LF_ISSET(SR_PARENT) && slevel == level) { + BT_STK_ENTER(env, + cp, h, indx, lock, lock_mode, ret); + if (ret != 0) + goto err; + goto done; + } + if (LF_ISSET(SR_DEL) && NUM_ENT(h) > 1) { + /* + * There was a page with a singleton pointer + * to a non-empty subtree. + */ + cp->csp--; + if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0) + goto err; + set_stack = stack = 0; + goto do_del; + } + BT_STK_PUSH(env, + cp, h, indx, lock, lock_mode, ret); + if (ret != 0) + goto err; + + LOCK_INIT(lock); + get_mode = DB_MPOOL_DIRTY; + lock_mode = DB_LOCK_WRITE; + goto lock_next; + } else { + /* + * Decide if we want to return a reference to the next + * page in the return stack. If so, latch it and don't + * unlatch it. We will want to stack things on the + * next iteration. The stack variable cannot be + * set until we leave this clause. If we are locking + * then we must lock this level before getting the page. + */ + if ((LF_ISSET(SR_PARENT) && + (u_int8_t)(slevel + 1) >= (level - 1)) || + (level - 1) == LEAFLEVEL) + set_stack = 1; + + /* + * Check for a normal search. If so, we need to + * latch couple the parent/chid buffers. + */ + if (!LF_ISSET(SR_DEL | SR_NEXT)) { + parent_h = h; + goto lock_next; + } + + /* + * Returning a subtree. See if we have hit the start + * point if so save the parent and set stack. + * Otherwise free the parent and temporarily + * save this one. + * For SR_DEL we need to find a page with 1 entry. + * For SR_NEXT we want find the minimal subtree + * that contains the key and the next page. + * We save pages as long as we are at the right + * edge of the subtree. When we leave the right + * edge, then drop the subtree. + */ + + if ((LF_ISSET(SR_DEL) && NUM_ENT(h) == 1)) { + /* + * We are pushing the things on the stack, + * set the stack variable now to indicate this + * has happened. + */ + stack = set_stack = 1; + LF_SET(SR_WRITE); + /* Push the parent. */ + cp->csp++; + /* Push this node. */ + BT_STK_PUSH(env, cp, h, + indx, lock, DB_LOCK_NG, ret); + if (ret != 0) + goto err; + LOCK_INIT(lock); + } else { + /* + * See if we want to save the tree so far. + * If we are looking for the next key, + * then we must save this node if we are + * at the end of the page. If not then + * discard anything we have saved so far. + * For delete only keep one node until + * we find a singleton. + */ +do_del: if (cp->csp->page != NULL) { + if (LF_ISSET(SR_NEXT) && + indx == NUM_ENT(h) - 1) + cp->csp++; + else if ((ret = + __bam_stkrel(dbc, STK_NOLOCK)) != 0) + goto err; + } + /* Save this node. */ + BT_STK_ENTER(env, cp, + h, indx, lock, lock_mode, ret); + if (ret != 0) + goto err; + LOCK_INIT(lock); + } + +lock_next: h = NULL; + + if (set_stack && LF_ISSET(SR_WRITE)) { + lock_mode = DB_LOCK_WRITE; + get_mode = DB_MPOOL_DIRTY; + getlock = 1; + } + /* + * If we are retrying and we are back at the same + * page then we already have it locked. If we are + * at a different page we want to lock couple and + * release that lock. + */ + if (level - 1 == saved_level) { + if ((ret = __LPUT(dbc, lock)) != 0) + goto err; + lock = saved_lock; + LOCK_INIT(saved_lock); + saved_level = MAXBTREELEVEL; + if (pg == saved_pg) + goto skip_lock; + } + if ((getlock || level - 1 == LEAFLEVEL) && + (ret = __db_lget(dbc, LCK_COUPLE_ALWAYS, + pg, lock_mode, wait, &lock)) != 0) { + /* + * If we are doing DEL or NEXT then we + * have an extra level saved in the stack, + * push it so it will get freed. + */ + if (LF_ISSET(SR_DEL | SR_NEXT) && !stack) + cp->csp++; + /* + * If we fail, discard the lock we held. + * This is ok because we will either search + * again or exit without actually looking + * at the data. + */ + if ((t_ret = __LPUT(dbc, lock)) != 0 && + ret == 0) + ret = t_ret; + /* + * If we blocked at a different level release + * the previous saved lock. + */ + if ((t_ret = __LPUT(dbc, saved_lock)) != 0 && + ret == 0) + ret = t_ret; + if (wait == 0 || (ret != DB_LOCK_NOTGRANTED && + ret != DB_LOCK_DEADLOCK)) + goto err; + + /* Relase the parent if we are holding it. */ + if (parent_h != NULL && + (ret = __memp_fput(mpf, dbc->thread_info, + parent_h, dbc->priority)) != 0) + goto err; + parent_h = NULL; + + BT_STK_POP(cp); + if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0) + goto err; + if ((ret = __db_lget(dbc, + 0, pg, lock_mode, 0, &saved_lock)) != 0) + goto err; + /* + * A very strange case: if this page was + * freed while we wait then we cannot hold + * the lock on it while we reget the root + * latch because allocation is one place + * we lock while holding a latch. + * Noone can have a free page locked, so + * check for that case. We do this by + * checking the level, since it will be 0 + * if free and we might as well see if this + * page moved and drop the lock in that case. + */ + if ((ret = __memp_fget(mpf, &pg, + dbc->thread_info, + dbc->txn, get_mode, &h)) != 0 && + ret != DB_PAGE_NOTFOUND) + goto err; + + if (ret != 0 || LEVEL(h) != level - 1) { + ret = __LPUT(dbc, saved_lock); + if (ret != 0) + goto err; + pg = root_pgno; + saved_level = MAXBTREELEVEL; + } + if (h != NULL && (ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0) + goto err; + h = NULL; + + if (was_next) { + LF_CLR(SR_MIN); + LF_SET(SR_NEXT); + } + /* + * We have the lock but we dropped the + * latch so we need to search again. If + * we get back to the same page then all + * is good, otherwise we need to try to + * lock the new page. + */ + saved_pg = pg; + saved_level = level - 1; + goto retry; + } +skip_lock: stack = set_stack; + } + /* Get the child page. */ + if ((ret = __memp_fget(mpf, &pg, + dbc->thread_info, dbc->txn, get_mode, &h)) != 0) + goto err; + /* Release the parent. */ + if (parent_h != NULL && (ret = __memp_fput(mpf, + dbc->thread_info, parent_h, dbc->priority)) != 0) + goto err; + parent_h = NULL; + } + /* NOTREACHED */ + +found: *exactp = 1; + + /* + * If we got here, we know that we have a Btree leaf or off-page + * duplicates page. If it's a Btree leaf page, we have to handle + * on-page duplicates. + * + * If there are duplicates, go to the first/last one. This is + * safe because we know that we're not going to leave the page, + * all duplicate sets that are not on overflow pages exist on a + * single leaf page. + */ + if (TYPE(h) == P_LBTREE && NUM_ENT(h) > P_INDX) { + if (LF_ISSET(SR_DUPLAST)) + while (indx < (db_indx_t)(NUM_ENT(h) - P_INDX) && + inp[indx] == inp[indx + P_INDX]) + indx += P_INDX; + else if (LF_ISSET(SR_DUPFIRST)) + while (indx > 0 && + inp[indx] == inp[indx - P_INDX]) + indx -= P_INDX; + } + + /* + * Now check if we are allowed to return deleted items; if not, then + * find the next (or previous) non-deleted duplicate entry. (We do + * not move from the original found key on the basis of the SR_DELNO + * flag.) + */ + DB_ASSERT(env, recnop == NULL || LF_ISSET(SR_DELNO)); + if (LF_ISSET(SR_DELNO)) { + deloffset = TYPE(h) == P_LBTREE ? O_INDX : 0; + if (LF_ISSET(SR_DUPLAST)) + while (B_DISSET(GET_BKEYDATA(dbp, + h, indx + deloffset)->type) && indx > 0 && + inp[indx] == inp[indx - adjust]) + indx -= adjust; + else + while (B_DISSET(GET_BKEYDATA(dbp, + h, indx + deloffset)->type) && + indx < (db_indx_t)(NUM_ENT(h) - adjust) && + inp[indx] == inp[indx + adjust]) + indx += adjust; + + /* + * If we weren't able to find a non-deleted duplicate, return + * DB_NOTFOUND. + */ + if (B_DISSET(GET_BKEYDATA(dbp, h, indx + deloffset)->type)) { + ret = DB_NOTFOUND; + goto err; + } + + /* + * Increment the record counter to point to the found element. + * Ignore any deleted key/data pairs. There doesn't need to + * be any correction for duplicates, as Btree doesn't support + * duplicates and record numbers in the same tree. + */ + if (recnop != NULL) { + DB_ASSERT(env, TYPE(h) == P_LBTREE); + + for (i = 0; i < indx; i += P_INDX) + if (!B_DISSET( + GET_BKEYDATA(dbp, h, i + O_INDX)->type)) + ++recno; + + /* Correct the number for a 0-base. */ + *recnop = recno + 1; + } + } + + if (LF_ISSET(SR_STK_ONLY)) { + BT_STK_NUM(env, cp, h, indx, ret); + if ((t_ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + } else { + if (LF_ISSET(SR_DEL) && cp->csp == cp->sp) + cp->csp++; + BT_STK_ENTER(env, cp, h, indx, lock, lock_mode, ret); + } + if (ret != 0) + goto err; + + cp->csp->lock = lock; + DB_ASSERT(env, parent_h == NULL); + +done: if ((ret = __LPUT(dbc, saved_lock)) != 0) + return (ret); + + return (0); + +err: if (ret == 0) + ret = t_ret; + if (h != NULL && (t_ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + if (parent_h != NULL && (t_ret = __memp_fput(mpf, + dbc->thread_info, parent_h, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + + /* Keep any not-found page locked for serializability. */ + if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0) + ret = t_ret; + + (void)__LPUT(dbc, saved_lock); + + BT_STK_POP(cp); + (void)__bam_stkrel(dbc, 0); + + return (ret); +} + +/* + * __bam_stkrel -- + * Release all pages currently held in the stack. + * + * PUBLIC: int __bam_stkrel __P((DBC *, u_int32_t)); + */ +int +__bam_stkrel(dbc, flags) + DBC *dbc; + u_int32_t flags; +{ + BTREE_CURSOR *cp; + DB *dbp; + DB_MPOOLFILE *mpf; + EPG *epg; + int ret, t_ret; + + DB_ASSERT(NULL, dbc != NULL); + dbp = dbc->dbp; + mpf = dbp->mpf; + cp = (BTREE_CURSOR *)dbc->internal; + + /* + * Release inner pages first. + * + * The caller must be sure that setting STK_NOLOCK will not effect + * either serializability or recoverability. + */ + for (ret = 0, epg = cp->sp; epg <= cp->csp; ++epg) { + if (epg->page != NULL) { + if (LF_ISSET(STK_CLRDBC) && cp->page == epg->page) { + cp->page = NULL; + LOCK_INIT(cp->lock); + } + if ((t_ret = __memp_fput(mpf, dbc->thread_info, + epg->page, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + epg->page = NULL; + } + /* + * We set this if we need to release our pins, + * but are not logically ready to have the pages + * visible. + */ + if (LF_ISSET(STK_PGONLY)) + continue; + if (LF_ISSET(STK_NOLOCK)) { + if ((t_ret = __LPUT(dbc, epg->lock)) != 0 && ret == 0) + ret = t_ret; + } else + if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0) + ret = t_ret; + } + + /* Clear the stack, all pages have been released. */ + if (!LF_ISSET(STK_PGONLY)) + BT_STK_CLR(cp); + + return (ret); +} + +/* + * __bam_stkgrow -- + * Grow the stack. + * + * PUBLIC: int __bam_stkgrow __P((ENV *, BTREE_CURSOR *)); + */ +int +__bam_stkgrow(env, cp) + ENV *env; + BTREE_CURSOR *cp; +{ + EPG *p; + size_t entries; + int ret; + + entries = cp->esp - cp->sp; + + if ((ret = __os_calloc(env, entries * 2, sizeof(EPG), &p)) != 0) + return (ret); + memcpy(p, cp->sp, entries * sizeof(EPG)); + if (cp->sp != cp->stack) + __os_free(env, cp->sp); + cp->sp = p; + cp->csp = p + entries; + cp->esp = p + entries * 2; + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_split.c b/src/libs/resiprocate/contrib/db/btree/bt_split.c new file mode 100644 index 00000000..fcf9aab5 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_split.c @@ -0,0 +1,1310 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" +#include "dbinc/btree.h" + +static int __bam_page __P((DBC *, EPG *, EPG *)); +static int __bam_psplit __P((DBC *, EPG *, PAGE *, PAGE *, db_indx_t *)); +static int __bam_root __P((DBC *, EPG *)); + +/* + * __bam_split -- + * Split a page. + * + * PUBLIC: int __bam_split __P((DBC *, void *, db_pgno_t *)); + */ +int +__bam_split(dbc, arg, root_pgnop) + DBC *dbc; + void *arg; + db_pgno_t *root_pgnop; +{ + BTREE_CURSOR *cp; + DB_LOCK metalock, next_lock; + enum { UP, DOWN } dir; + db_pgno_t pgno, next_pgno, root_pgno; + int exact, level, ret; + + cp = (BTREE_CURSOR *)dbc->internal; + root_pgno = cp->root; + LOCK_INIT(next_lock); + next_pgno = PGNO_INVALID; + + /* + * First get a lock on the metadata page, we will have to allocate + * pages and cannot get a lock while we have the search tree pinnned. + */ + + pgno = PGNO_BASE_MD; + if ((ret = __db_lget(dbc, + 0, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0) + goto err; + + /* + * The locking protocol we use to avoid deadlock to acquire locks by + * walking down the tree, but we do it as lazily as possible, locking + * the root only as a last resort. We expect all stack pages to have + * been discarded before we're called; we discard all short-term locks. + * + * When __bam_split is first called, we know that a leaf page was too + * full for an insert. We don't know what leaf page it was, but we + * have the key/recno that caused the problem. We call XX_search to + * reacquire the leaf page, but this time get both the leaf page and + * its parent, locked. We then split the leaf page and see if the new + * internal key will fit into the parent page. If it will, we're done. + * + * If it won't, we discard our current locks and repeat the process, + * only this time acquiring the parent page and its parent, locked. + * This process repeats until we succeed in the split, splitting the + * root page as the final resort. The entire process then repeats, + * as necessary, until we split a leaf page. + * + * XXX + * A traditional method of speeding this up is to maintain a stack of + * the pages traversed in the original search. You can detect if the + * stack is correct by storing the page's LSN when it was searched and + * comparing that LSN with the current one when it's locked during the + * split. This would be an easy change for this code, but I have no + * numbers that indicate it's worthwhile. + */ + for (dir = UP, level = LEAFLEVEL;; dir == UP ? ++level : --level) { + /* + * Acquire a page and its parent, locked. + */ +retry: if ((ret = (dbc->dbtype == DB_BTREE ? + __bam_search(dbc, PGNO_INVALID, + arg, SR_WRPAIR, level, NULL, &exact) : + __bam_rsearch(dbc, + (db_recno_t *)arg, SR_WRPAIR, level, &exact))) != 0) + break; + + if (cp->csp[0].page->pgno == root_pgno) { + /* we can overshoot the top of the tree. */ + level = cp->csp[0].page->level; + if (root_pgnop != NULL) + *root_pgnop = root_pgno; + } else if (root_pgnop != NULL) + *root_pgnop = cp->csp[-1].page->pgno; + + /* + * Split the page if it still needs it (it's possible another + * thread of control has already split the page). If we are + * guaranteed that two items will fit on the page, the split + * is no longer necessary. + */ + if (2 * B_MAXSIZEONPAGE(cp->ovflsize) + <= (db_indx_t)P_FREESPACE(dbc->dbp, cp->csp[0].page)) { + if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0) + goto err; + goto no_split; + } + + /* + * We need to try to lock the next page so we can update + * its PREV. + */ + if (dbc->dbtype == DB_BTREE && ISLEAF(cp->csp->page) && + (pgno = NEXT_PGNO(cp->csp->page)) != PGNO_INVALID) { + TRY_LOCK(dbc, pgno, + next_pgno, next_lock, DB_LOCK_WRITE, retry); + if (ret != 0) + goto err; + } + ret = cp->csp[0].page->pgno == root_pgno ? + __bam_root(dbc, &cp->csp[0]) : + __bam_page(dbc, &cp->csp[-1], &cp->csp[0]); + BT_STK_CLR(cp); + + switch (ret) { + case 0: +no_split: /* Once we've split the leaf page, we're done. */ + if (level == LEAFLEVEL) + goto done; + + /* Switch directions. */ + if (dir == UP) + dir = DOWN; + break; + case DB_NEEDSPLIT: + /* + * It's possible to fail to split repeatedly, as other + * threads may be modifying the tree, or the page usage + * is sufficiently bad that we don't get enough space + * the first time. + */ + if (dir == DOWN) + dir = UP; + break; + default: + goto err; + } + } + +err: if (root_pgnop != NULL) + *root_pgnop = cp->root; +done: (void)__LPUT(dbc, metalock); + (void)__TLPUT(dbc, next_lock); + return (ret); +} + +/* + * __bam_root -- + * Split the root page of a btree. + */ +static int +__bam_root(dbc, cp) + DBC *dbc; + EPG *cp; +{ + DB *dbp; + DBT log_dbt, rootent[2]; + DB_LOCK llock, rlock; + DB_LSN log_lsn; + DB_MPOOLFILE *mpf; + PAGE *lp, *rp; + db_indx_t split; + u_int32_t opflags; + int ret, t_ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + lp = rp = NULL; + LOCK_INIT(llock); + LOCK_INIT(rlock); + COMPQUIET(log_dbt.data, NULL); + + /* Yeah, right. */ + if (cp->page->level >= MAXBTREELEVEL) { + __db_errx(dbp->env, + "Too many btree levels: %d", cp->page->level); + return (ENOSPC); + } + + if ((ret = __memp_dirty(mpf, + &cp->page, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + goto err; + + /* Create new left and right pages for the split. */ + if ((ret = __db_new(dbc, TYPE(cp->page), &llock, &lp)) != 0 || + (ret = __db_new(dbc, TYPE(cp->page), &rlock, &rp)) != 0) + goto err; + P_INIT(lp, dbp->pgsize, lp->pgno, + PGNO_INVALID, ISINTERNAL(cp->page) ? PGNO_INVALID : rp->pgno, + cp->page->level, TYPE(cp->page)); + P_INIT(rp, dbp->pgsize, rp->pgno, + ISINTERNAL(cp->page) ? PGNO_INVALID : lp->pgno, PGNO_INVALID, + cp->page->level, TYPE(cp->page)); + + /* Split the page. */ + if ((ret = __bam_psplit(dbc, cp, lp, rp, &split)) != 0) + goto err; + + if (DBC_LOGGING(dbc)) { + memset(&log_dbt, 0, sizeof(log_dbt)); + if ((ret = + __os_malloc(dbp->env, dbp->pgsize, &log_dbt.data)) != 0) + goto err; + log_dbt.size = dbp->pgsize; + memcpy(log_dbt.data, cp->page, dbp->pgsize); + } + + /* Clean up the new root page. */ + if ((ret = (dbc->dbtype == DB_RECNO ? + __ram_root(dbc, cp->page, lp, rp) : + __bam_broot(dbc, cp->page, split, lp, rp))) != 0) { + if (DBC_LOGGING(dbc)) + __os_free(dbp->env, log_dbt.data); + goto err; + } + + /* Log the change. */ + if (DBC_LOGGING(dbc)) { + memset(rootent, 0, sizeof(rootent)); + rootent[0].data = GET_BINTERNAL(dbp, cp->page, 0); + rootent[1].data = GET_BINTERNAL(dbp, cp->page, 1); + if (dbc->dbtype == DB_RECNO) + rootent[0].size = rootent[1].size = RINTERNAL_SIZE; + else { + rootent[0].size = BINTERNAL_SIZE( + ((BINTERNAL *)rootent[0].data)->len); + rootent[1].size = BINTERNAL_SIZE( + ((BINTERNAL *)rootent[1].data)->len); + } + ZERO_LSN(log_lsn); + opflags = F_ISSET( + (BTREE_CURSOR *)dbc->internal, C_RECNUM) ? SPL_NRECS : 0; + if (dbc->dbtype == DB_RECNO) + opflags |= SPL_RECNO; + ret = __bam_split_log(dbp, + dbc->txn, &LSN(cp->page), 0, PGNO(lp), &LSN(lp), PGNO(rp), + &LSN(rp), (u_int32_t)NUM_ENT(lp), PGNO_INVALID, &log_lsn, + dbc->internal->root, &LSN(cp->page), 0, + &log_dbt, &rootent[0], &rootent[1], opflags); + + __os_free(dbp->env, log_dbt.data); + + if (ret != 0) + goto err; + } else + LSN_NOT_LOGGED(LSN(cp->page)); + LSN(lp) = LSN(cp->page); + LSN(rp) = LSN(cp->page); + + /* Adjust any cursors. */ + ret = __bam_ca_split(dbc, cp->page->pgno, lp->pgno, rp->pgno, split, 1); + + /* Success or error: release pages and locks. */ +err: if (cp->page != NULL && (t_ret = __memp_fput(mpf, + dbc->thread_info, cp->page, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + cp->page = NULL; + + /* + * We are done. Put or downgrade all our locks and release + * the pages. + */ + if ((t_ret = __TLPUT(dbc, llock)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __TLPUT(dbc, rlock)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __TLPUT(dbc, cp->lock)) != 0 && ret == 0) + ret = t_ret; + if (lp != NULL && (t_ret = __memp_fput(mpf, + dbc->thread_info, lp, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + if (rp != NULL && (t_ret = __memp_fput(mpf, + dbc->thread_info, rp, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __bam_page -- + * Split the non-root page of a btree. + */ +static int +__bam_page(dbc, pp, cp) + DBC *dbc; + EPG *pp, *cp; +{ + BTREE_CURSOR *bc; + DB *dbp; + DBT log_dbt, rentry; + DB_LOCK rplock; + DB_LSN log_lsn; + DB_LSN save_lsn; + DB_MPOOLFILE *mpf; + PAGE *lp, *rp, *alloc_rp, *tp; + db_indx_t split; + u_int32_t opflags; + int ret, t_ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + alloc_rp = lp = rp = tp = NULL; + LOCK_INIT(rplock); + ret = -1; + + /* + * Create new left page for the split, and fill in everything + * except its LSN and next-page page number. + * + * Create a new right page for the split, and fill in everything + * except its LSN and page number. + * + * We malloc space for both the left and right pages, so we don't get + * a new page from the underlying buffer pool until we know the split + * is going to succeed. The reason is that we can't release locks + * acquired during the get-a-new-page process because metadata page + * locks can't be discarded on failure since we may have modified the + * free list. So, if you assume that we're holding a write lock on the + * leaf page which ran out of space and started this split (e.g., we + * have already written records to the page, or we retrieved a record + * from it with the DB_RMW flag set), failing in a split with both a + * leaf page locked and the metadata page locked can potentially lock + * up the tree badly, because we've violated the rule of always locking + * down the tree, and never up. + */ + if ((ret = __os_malloc(dbp->env, dbp->pgsize * 2, &lp)) != 0) + goto err; + P_INIT(lp, dbp->pgsize, PGNO(cp->page), + ISINTERNAL(cp->page) ? PGNO_INVALID : PREV_PGNO(cp->page), + ISINTERNAL(cp->page) ? PGNO_INVALID : 0, + cp->page->level, TYPE(cp->page)); + + rp = (PAGE *)((u_int8_t *)lp + dbp->pgsize); + P_INIT(rp, dbp->pgsize, 0, + ISINTERNAL(cp->page) ? PGNO_INVALID : PGNO(cp->page), + ISINTERNAL(cp->page) ? PGNO_INVALID : NEXT_PGNO(cp->page), + cp->page->level, TYPE(cp->page)); + + /* + * Split right. + * + * Only the indices are sorted on the page, i.e., the key/data pairs + * aren't, so it's simpler to copy the data from the split page onto + * two new pages instead of copying half the data to a new right page + * and compacting the left page in place. Since the left page can't + * change, we swap the original and the allocated left page after the + * split. + */ + if ((ret = __bam_psplit(dbc, cp, lp, rp, &split)) != 0) + goto err; + + /* + * Test to see if we are going to be able to insert the new pages into + * the parent page. The interesting failure here is that the parent + * page can't hold the new keys, and has to be split in turn, in which + * case we want to release all the locks we can. + */ + if ((ret = __bam_pinsert(dbc, pp, split, lp, rp, BPI_SPACEONLY)) != 0) + goto err; + + /* + * We've got everything locked down we need, and we know the split + * is going to succeed. Go and get the additional page we'll need. + */ + if ((ret = __db_new(dbc, TYPE(cp->page), &rplock, &alloc_rp)) != 0) + goto err; + + /* + * Prepare to fix up the previous pointer of any leaf page following + * the split page. Our caller has already write locked the page so + * we can get it without deadlocking on the parent latch. + */ + if (ISLEAF(cp->page) && NEXT_PGNO(cp->page) != PGNO_INVALID && + (ret = __memp_fget(mpf, &NEXT_PGNO(cp->page), + dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &tp)) != 0) + goto err; + + /* + * Fix up the page numbers we didn't have before. We have to do this + * before calling __bam_pinsert because it may copy a page number onto + * the parent page and it takes the page number from its page argument. + */ + PGNO(rp) = NEXT_PGNO(lp) = PGNO(alloc_rp); + + DB_ASSERT(dbp->env, IS_DIRTY(cp->page)); + DB_ASSERT(dbp->env, IS_DIRTY(pp->page)); + + /* Actually update the parent page. */ + if ((ret = __bam_pinsert(dbc, pp, split, lp, rp, BPI_NOLOGGING)) != 0) + goto err; + + bc = (BTREE_CURSOR *)dbc->internal; + /* Log the change. */ + if (DBC_LOGGING(dbc)) { + memset(&log_dbt, 0, sizeof(log_dbt)); + log_dbt.data = cp->page; + log_dbt.size = dbp->pgsize; + memset(&rentry, 0, sizeof(rentry)); + rentry.data = GET_BINTERNAL(dbp, pp->page, pp->indx + 1); + opflags = F_ISSET(bc, C_RECNUM) ? SPL_NRECS : 0; + if (dbc->dbtype == DB_RECNO) { + opflags |= SPL_RECNO; + rentry.size = RINTERNAL_SIZE; + } else + rentry.size = + BINTERNAL_SIZE(((BINTERNAL *)rentry.data)->len); + if (tp == NULL) + ZERO_LSN(log_lsn); + if ((ret = __bam_split_log(dbp, dbc->txn, &LSN(cp->page), 0, + PGNO(cp->page), &LSN(cp->page), PGNO(alloc_rp), + &LSN(alloc_rp), (u_int32_t)NUM_ENT(lp), + tp == NULL ? 0 : PGNO(tp), tp == NULL ? &log_lsn : &LSN(tp), + PGNO(pp->page), &LSN(pp->page), pp->indx, + &log_dbt, NULL, &rentry, opflags)) != 0) { + /* + * Undo the update to the parent page, which has not + * been logged yet. This must succeed. + */ + t_ret = __db_ditem_nolog(dbc, pp->page, + pp->indx + 1, rentry.size); + DB_ASSERT(dbp->env, t_ret == 0); + + goto err; + } + + } else + LSN_NOT_LOGGED(LSN(cp->page)); + + /* Update the LSNs for all involved pages. */ + LSN(alloc_rp) = LSN(cp->page); + LSN(lp) = LSN(cp->page); + LSN(rp) = LSN(cp->page); + LSN(pp->page) = LSN(cp->page); + if (tp != NULL) { + /* Log record has been written; now it is safe to update next page. */ + PREV_PGNO(tp) = PGNO(rp); + LSN(tp) = LSN(cp->page); + } + + /* + * Copy the left and right pages into place. There are two paths + * through here. Either we are logging and we set the LSNs in the + * logging path. However, if we are not logging, then we do not + * have valid LSNs on lp or rp. The correct LSNs to use are the + * ones on the page we got from __db_new or the one that was + * originally on cp->page. In both cases, we save the LSN from the + * real database page (not a malloc'd one) and reapply it after we + * do the copy. + */ + save_lsn = alloc_rp->lsn; + memcpy(alloc_rp, rp, LOFFSET(dbp, rp)); + memcpy((u_int8_t *)alloc_rp + HOFFSET(rp), + (u_int8_t *)rp + HOFFSET(rp), dbp->pgsize - HOFFSET(rp)); + alloc_rp->lsn = save_lsn; + + save_lsn = cp->page->lsn; + memcpy(cp->page, lp, LOFFSET(dbp, lp)); + memcpy((u_int8_t *)cp->page + HOFFSET(lp), + (u_int8_t *)lp + HOFFSET(lp), dbp->pgsize - HOFFSET(lp)); + cp->page->lsn = save_lsn; + + /* Adjust any cursors. */ + if ((ret = __bam_ca_split(dbc, + PGNO(cp->page), PGNO(cp->page), PGNO(rp), split, 0)) != 0) + goto err; + + __os_free(dbp->env, lp); + + /* + * Success -- write the real pages back to the store. + */ + if ((t_ret = __memp_fput(mpf, + dbc->thread_info, alloc_rp, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __TLPUT(dbc, rplock)) != 0 && ret == 0) + ret = t_ret; + if (tp != NULL) { + if ((t_ret = __memp_fput(mpf, + dbc->thread_info, tp, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + } + if ((t_ret = __bam_stkrel(dbc, STK_CLRDBC)) != 0 && ret == 0) + ret = t_ret; + return (ret); + +err: if (lp != NULL) + __os_free(dbp->env, lp); + if (alloc_rp != NULL) + (void)__memp_fput(mpf, + dbc->thread_info, alloc_rp, dbc->priority); + if (tp != NULL) + (void)__memp_fput(mpf, dbc->thread_info, tp, dbc->priority); + + if (pp->page != NULL) + (void)__memp_fput(mpf, + dbc->thread_info, pp->page, dbc->priority); + + if (ret == DB_NEEDSPLIT) + (void)__LPUT(dbc, pp->lock); + else + (void)__TLPUT(dbc, pp->lock); + + (void)__memp_fput(mpf, dbc->thread_info, cp->page, dbc->priority); + + /* + * We don't drop the left and right page locks. If we doing dirty + * reads then we need to hold the locks until we abort the transaction. + * If we are not transactional, we are hosed anyway as the tree + * is trashed. It may be better not to leak the locks. + */ + + if (dbc->txn == NULL) + (void)__LPUT(dbc, rplock); + + if (dbc->txn == NULL || ret == DB_NEEDSPLIT) + (void)__LPUT(dbc, cp->lock); + + return (ret); +} + +/* + * __bam_broot -- + * Fix up the btree root page after it has been split. + * PUBLIC: int __bam_broot __P((DBC *, PAGE *, u_int32_t, PAGE *, PAGE *)); + */ +int +__bam_broot(dbc, rootp, split, lp, rp) + DBC *dbc; + u_int32_t split; + PAGE *rootp, *lp, *rp; +{ + BINTERNAL bi, bi0, *child_bi; + BKEYDATA *child_bk; + BOVERFLOW bo, *child_bo; + BTREE_CURSOR *cp; + DB *dbp; + DBT hdr, hdr0, data; + db_pgno_t root_pgno; + int ret; + + dbp = dbc->dbp; + cp = (BTREE_CURSOR *)dbc->internal; + child_bo = NULL; + data.data = NULL; + memset(&bi, 0, sizeof(bi)); + + switch (TYPE(rootp)) { + case P_IBTREE: + /* Copy the first key of the child page onto the root page. */ + child_bi = GET_BINTERNAL(dbp, rootp, split); + switch (B_TYPE(child_bi->type)) { + case B_KEYDATA: + bi.len = child_bi->len; + B_TSET(bi.type, B_KEYDATA); + bi.pgno = rp->pgno; + DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data)); + if ((ret = __os_malloc(dbp->env, + child_bi->len, &data.data)) != 0) + return (ret); + memcpy(data.data, child_bi->data, child_bi->len); + data.size = child_bi->len; + break; + case B_OVERFLOW: + /* Reuse the overflow key. */ + child_bo = (BOVERFLOW *)child_bi->data; + memset(&bo, 0, sizeof(bo)); + bo.type = B_OVERFLOW; + bo.tlen = child_bo->tlen; + bo.pgno = child_bo->pgno; + bi.len = BOVERFLOW_SIZE; + B_TSET(bi.type, B_OVERFLOW); + bi.pgno = rp->pgno; + DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data)); + DB_SET_DBT(data, &bo, BOVERFLOW_SIZE); + break; + case B_DUPLICATE: + default: + goto pgfmt; + } + break; + case P_LDUP: + case P_LBTREE: + /* Copy the first key of the child page onto the root page. */ + child_bk = GET_BKEYDATA(dbp, rootp, split); + switch (B_TYPE(child_bk->type)) { + case B_KEYDATA: + bi.len = child_bk->len; + B_TSET(bi.type, B_KEYDATA); + bi.pgno = rp->pgno; + DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data)); + if ((ret = __os_malloc(dbp->env, + child_bk->len, &data.data)) != 0) + return (ret); + memcpy(data.data, child_bk->data, child_bk->len); + data.size = child_bk->len; + break; + case B_OVERFLOW: + /* Copy the overflow key. */ + child_bo = (BOVERFLOW *)child_bk; + memset(&bo, 0, sizeof(bo)); + bo.type = B_OVERFLOW; + bo.tlen = child_bo->tlen; + memset(&hdr, 0, sizeof(hdr)); + if ((ret = __db_goff(dbc, &hdr, child_bo->tlen, + child_bo->pgno, &hdr.data, &hdr.size)) == 0) + ret = __db_poff(dbc, &hdr, &bo.pgno); + + if (hdr.data != NULL) + __os_free(dbp->env, hdr.data); + if (ret != 0) + return (ret); + + bi.len = BOVERFLOW_SIZE; + B_TSET(bi.type, B_OVERFLOW); + bi.pgno = rp->pgno; + DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data)); + DB_SET_DBT(data, &bo, BOVERFLOW_SIZE); + break; + case B_DUPLICATE: + default: + goto pgfmt; + } + break; + default: +pgfmt: return (__db_pgfmt(dbp->env, rp->pgno)); + } + /* + * If the root page was a leaf page, change it into an internal page. + * We copy the key we split on (but not the key's data, in the case of + * a leaf page) to the new root page. + */ + root_pgno = cp->root; + P_INIT(rootp, dbp->pgsize, + root_pgno, PGNO_INVALID, PGNO_INVALID, lp->level + 1, P_IBTREE); + + /* + * The btree comparison code guarantees that the left-most key on any + * internal btree page is never used, so it doesn't need to be filled + * in. Set the record count if necessary. + */ + memset(&bi0, 0, sizeof(bi0)); + B_TSET(bi0.type, B_KEYDATA); + bi0.pgno = lp->pgno; + if (F_ISSET(cp, C_RECNUM)) { + bi0.nrecs = __bam_total(dbp, lp); + RE_NREC_SET(rootp, bi0.nrecs); + bi.nrecs = __bam_total(dbp, rp); + RE_NREC_ADJ(rootp, bi.nrecs); + } + DB_SET_DBT(hdr0, &bi0, SSZA(BINTERNAL, data)); + if ((ret = __db_pitem_nolog(dbc, rootp, + 0, BINTERNAL_SIZE(0), &hdr0, NULL)) != 0) + goto err; + ret = __db_pitem_nolog(dbc, rootp, 1, + BINTERNAL_SIZE(data.size), &hdr, &data); + +err: if (data.data != NULL && child_bo == NULL) + __os_free(dbp->env, data.data); + return (ret); +} + +/* + * __ram_root -- + * Fix up the recno root page after it has been split. + * PUBLIC: int __ram_root __P((DBC *, PAGE *, PAGE *, PAGE *)); + */ +int +__ram_root(dbc, rootp, lp, rp) + DBC *dbc; + PAGE *rootp, *lp, *rp; +{ + DB *dbp; + DBT hdr; + RINTERNAL ri; + db_pgno_t root_pgno; + int ret; + + dbp = dbc->dbp; + root_pgno = dbc->internal->root; + + /* Initialize the page. */ + P_INIT(rootp, dbp->pgsize, + root_pgno, PGNO_INVALID, PGNO_INVALID, lp->level + 1, P_IRECNO); + + /* Initialize the header. */ + DB_SET_DBT(hdr, &ri, RINTERNAL_SIZE); + + /* Insert the left and right keys, set the header information. */ + ri.pgno = lp->pgno; + ri.nrecs = __bam_total(dbp, lp); + if ((ret = __db_pitem_nolog(dbc, + rootp, 0, RINTERNAL_SIZE, &hdr, NULL)) != 0) + return (ret); + RE_NREC_SET(rootp, ri.nrecs); + ri.pgno = rp->pgno; + ri.nrecs = __bam_total(dbp, rp); + if ((ret = __db_pitem_nolog(dbc, + rootp, 1, RINTERNAL_SIZE, &hdr, NULL)) != 0) + return (ret); + RE_NREC_ADJ(rootp, ri.nrecs); + return (0); +} + +/* + * __bam_pinsert -- + * Insert a new key into a parent page, completing the split. + * + * PUBLIC: int __bam_pinsert + * PUBLIC: __P((DBC *, EPG *, u_int32_t, PAGE *, PAGE *, int)); + */ +int +__bam_pinsert(dbc, parent, split, lchild, rchild, flags) + DBC *dbc; + EPG *parent; + u_int32_t split; + PAGE *lchild, *rchild; + int flags; +{ + BINTERNAL bi, *child_bi; + BKEYDATA *child_bk, *tmp_bk; + BOVERFLOW bo, *child_bo; + BTREE *t; + BTREE_CURSOR *cp; + DB *dbp; + DBT a, b, hdr, data; + EPG *child; + PAGE *ppage; + RINTERNAL ri; + db_indx_t off; + db_recno_t nrecs; + size_t (*func) __P((DB *, const DBT *, const DBT *)); + int (*pitem) __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *)); + u_int32_t n, nbytes, nksize, oldsize, size; + int ret; + + dbp = dbc->dbp; + cp = (BTREE_CURSOR *)dbc->internal; + t = dbp->bt_internal; + ppage = parent->page; + child = parent + 1; + + /* If handling record numbers, count records split to the right page. */ + nrecs = F_ISSET(cp, C_RECNUM) && + !LF_ISSET(BPI_SPACEONLY) ? __bam_total(dbp, rchild) : 0; + + /* + * Now we insert the new page's first key into the parent page, which + * completes the split. The parent points to a PAGE and a page index + * offset, where the new key goes ONE AFTER the index, because we split + * to the right. + * + * XXX + * Some btree algorithms replace the key for the old page as well as + * the new page. We don't, as there's no reason to believe that the + * first key on the old page is any better than the key we have, and, + * in the case of a key being placed at index 0 causing the split, the + * key is unavailable. + */ + off = parent->indx + O_INDX; + if (LF_ISSET(BPI_REPLACE)) + oldsize = TYPE(ppage) == P_IRECNO ? RINTERNAL_PSIZE : + BINTERNAL_PSIZE(GET_BINTERNAL(dbp, ppage, off)->len); + else + oldsize = 0; + + /* + * Calculate the space needed on the parent page. + * + * Prefix trees: space hack used when inserting into BINTERNAL pages. + * Retain only what's needed to distinguish between the new entry and + * the LAST entry on the page to its left. If the keys compare equal, + * retain the entire key. We ignore overflow keys, and the entire key + * must be retained for the next-to-leftmost key on the leftmost page + * of each level, or the search will fail. Applicable ONLY to internal + * pages that have leaf pages as children. Further reduction of the + * key between pairs of internal pages loses too much information. + */ + switch (TYPE(child->page)) { + case P_IBTREE: + child_bi = GET_BINTERNAL(dbp, child->page, split); + nbytes = BINTERNAL_PSIZE(child_bi->len); + + if (P_FREESPACE(dbp, ppage) + oldsize < nbytes) + return (DB_NEEDSPLIT); + if (LF_ISSET(BPI_SPACEONLY)) + return (0); + + switch (B_TYPE(child_bi->type)) { + case B_KEYDATA: + /* Add a new record for the right page. */ + memset(&bi, 0, sizeof(bi)); + bi.len = child_bi->len; + B_TSET(bi.type, B_KEYDATA); + bi.pgno = rchild->pgno; + bi.nrecs = nrecs; + DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data)); + DB_SET_DBT(data, child_bi->data, child_bi->len); + size = BINTERNAL_SIZE(child_bi->len); + break; + case B_OVERFLOW: + /* Reuse the overflow key. */ + child_bo = (BOVERFLOW *)child_bi->data; + memset(&bo, 0, sizeof(bo)); + bo.type = B_OVERFLOW; + bo.tlen = child_bo->tlen; + bo.pgno = child_bo->pgno; + bi.len = BOVERFLOW_SIZE; + B_TSET(bi.type, B_OVERFLOW); + bi.pgno = rchild->pgno; + bi.nrecs = nrecs; + DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data)); + DB_SET_DBT(data, &bo, BOVERFLOW_SIZE); + size = BINTERNAL_SIZE(BOVERFLOW_SIZE); + break; + case B_DUPLICATE: + default: + goto pgfmt; + } + break; + case P_LDUP: + case P_LBTREE: + child_bk = GET_BKEYDATA(dbp, child->page, split); + switch (B_TYPE(child_bk->type)) { + case B_KEYDATA: + nbytes = BINTERNAL_PSIZE(child_bk->len); + nksize = child_bk->len; + + /* + * Prefix compression: + * We set t->bt_prefix to NULL if we have a comparison + * callback but no prefix compression callback. But, + * if we're splitting in an off-page duplicates tree, + * we still have to do some checking. If using the + * default off-page duplicates comparison routine we + * can use the default prefix compression callback. If + * not using the default off-page duplicates comparison + * routine, we can't do any kind of prefix compression + * as there's no way for an application to specify a + * prefix compression callback that corresponds to its + * comparison callback. + * + * No prefix compression if we don't have a compression + * function, or the key we'd compress isn't a normal + * key (for example, it references an overflow page). + * + * Generate a parent page key for the right child page + * from a comparison of the last key on the left child + * page and the first key on the right child page. + */ + if (F_ISSET(dbc, DBC_OPD)) { + if (dbp->dup_compare == __bam_defcmp) + func = __bam_defpfx; + else + func = NULL; + } else + func = t->bt_prefix; + if (func == NULL) + goto noprefix; + tmp_bk = GET_BKEYDATA(dbp, lchild, NUM_ENT(lchild) - + (TYPE(lchild) == P_LDUP ? O_INDX : P_INDX)); + if (B_TYPE(tmp_bk->type) != B_KEYDATA) + goto noprefix; + DB_INIT_DBT(a, tmp_bk->data, tmp_bk->len); + DB_INIT_DBT(b, child_bk->data, child_bk->len); + nksize = (u_int32_t)func(dbp, &a, &b); + if ((n = BINTERNAL_PSIZE(nksize)) < nbytes) + nbytes = n; + else + nksize = child_bk->len; + +noprefix: if (P_FREESPACE(dbp, ppage) + oldsize < nbytes) + return (DB_NEEDSPLIT); + if (LF_ISSET(BPI_SPACEONLY)) + return (0); + + memset(&bi, 0, sizeof(bi)); + bi.len = nksize; + B_TSET(bi.type, B_KEYDATA); + bi.pgno = rchild->pgno; + bi.nrecs = nrecs; + DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data)); + DB_SET_DBT(data, child_bk->data, nksize); + size = BINTERNAL_SIZE(nksize); + break; + case B_OVERFLOW: + nbytes = BINTERNAL_PSIZE(BOVERFLOW_SIZE); + + if (P_FREESPACE(dbp, ppage) + oldsize < nbytes) + return (DB_NEEDSPLIT); + if (LF_ISSET(BPI_SPACEONLY)) + return (0); + + /* Copy the overflow key. */ + child_bo = (BOVERFLOW *)child_bk; + memset(&bo, 0, sizeof(bo)); + bo.type = B_OVERFLOW; + bo.tlen = child_bo->tlen; + memset(&hdr, 0, sizeof(hdr)); + if ((ret = __db_goff(dbc, &hdr, child_bo->tlen, + child_bo->pgno, &hdr.data, &hdr.size)) == 0) + ret = __db_poff(dbc, &hdr, &bo.pgno); + + if (hdr.data != NULL) + __os_free(dbp->env, hdr.data); + if (ret != 0) + return (ret); + + memset(&bi, 0, sizeof(bi)); + bi.len = BOVERFLOW_SIZE; + B_TSET(bi.type, B_OVERFLOW); + bi.pgno = rchild->pgno; + bi.nrecs = nrecs; + DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data)); + DB_SET_DBT(data, &bo, BOVERFLOW_SIZE); + size = BINTERNAL_SIZE(BOVERFLOW_SIZE); + + break; + case B_DUPLICATE: + default: + goto pgfmt; + } + break; + case P_IRECNO: + case P_LRECNO: + nbytes = RINTERNAL_PSIZE; + + if (P_FREESPACE(dbp, ppage) + oldsize < nbytes) + return (DB_NEEDSPLIT); + if (LF_ISSET(BPI_SPACEONLY)) + return (0); + + /* Add a new record for the right page. */ + DB_SET_DBT(hdr, &ri, RINTERNAL_SIZE); + ri.pgno = rchild->pgno; + ri.nrecs = nrecs; + size = RINTERNAL_SIZE; + data.size = 0; + /* + * For now, we are locking internal recno nodes so + * use two steps. + */ + if (LF_ISSET(BPI_REPLACE)) { + if ((ret = __bam_ditem(dbc, ppage, off)) != 0) + return (ret); + LF_CLR(BPI_REPLACE); + } + break; + default: +pgfmt: return (__db_pgfmt(dbp->env, PGNO(child->page))); + } + + if (LF_ISSET(BPI_REPLACE)) { + DB_ASSERT(dbp->env, !LF_ISSET(BPI_NOLOGGING)); + if ((ret = __bam_irep(dbc, ppage, + off, &hdr, data.size != 0 ? &data : NULL)) != 0) + return (ret); + } else { + if (LF_ISSET(BPI_NOLOGGING)) + pitem = __db_pitem_nolog; + else + pitem = __db_pitem; + + if ((ret = pitem(dbc, ppage, + off, size, &hdr, data.size != 0 ? &data : NULL)) != 0) + return (ret); + } + + /* + * If a Recno or Btree with record numbers AM page, or an off-page + * duplicates tree, adjust the parent page's left page record count. + */ + if (F_ISSET(cp, C_RECNUM) && !LF_ISSET(BPI_NORECNUM)) { + /* Log the change. */ + if (DBC_LOGGING(dbc)) { + if ((ret = __bam_cadjust_log(dbp, dbc->txn, + &LSN(ppage), 0, PGNO(ppage), &LSN(ppage), + parent->indx, -(int32_t)nrecs, 0)) != 0) + return (ret); + } else + LSN_NOT_LOGGED(LSN(ppage)); + + /* Update the left page count. */ + if (dbc->dbtype == DB_RECNO) + GET_RINTERNAL(dbp, ppage, parent->indx)->nrecs -= nrecs; + else + GET_BINTERNAL(dbp, ppage, parent->indx)->nrecs -= nrecs; + } + + return (0); +} + +/* + * __bam_psplit -- + * Do the real work of splitting the page. + */ +static int +__bam_psplit(dbc, cp, lp, rp, splitret) + DBC *dbc; + EPG *cp; + PAGE *lp, *rp; + db_indx_t *splitret; +{ + DB *dbp; + PAGE *pp; + db_indx_t half, *inp, nbytes, off, splitp, top; + int adjust, cnt, iflag, isbigkey, ret; + + dbp = dbc->dbp; + pp = cp->page; + inp = P_INP(dbp, pp); + adjust = TYPE(pp) == P_LBTREE ? P_INDX : O_INDX; + + /* + * If we're splitting the first (last) page on a level because we're + * inserting (appending) a key to it, it's likely that the data is + * sorted. Moving a single item to the new page is less work and can + * push the fill factor higher than normal. This is trivial when we + * are splitting a new page before the beginning of the tree, all of + * the interesting tests are against values of 0. + * + * Catching appends to the tree is harder. In a simple append, we're + * inserting an item that sorts past the end of the tree; the cursor + * will point past the last element on the page. But, in trees with + * duplicates, the cursor may point to the last entry on the page -- + * in this case, the entry will also be the last element of a duplicate + * set (the last because the search call specified the SR_DUPLAST flag). + * The only way to differentiate between an insert immediately before + * the last item in a tree or an append after a duplicate set which is + * also the last item in the tree is to call the comparison function. + * When splitting internal pages during an append, the search code + * guarantees the cursor always points to the largest page item less + * than the new internal entry. To summarize, we want to catch three + * possible index values: + * + * NUM_ENT(page) Btree/Recno leaf insert past end-of-tree + * NUM_ENT(page) - O_INDX Btree or Recno internal insert past EOT + * NUM_ENT(page) - P_INDX Btree leaf insert past EOT after a set + * of duplicates + * + * two of which, (NUM_ENT(page) - O_INDX or P_INDX) might be an insert + * near the end of the tree, and not after the end of the tree at all. + * Do a simple test which might be wrong because calling the comparison + * functions is expensive. Regardless, it's not a big deal if we're + * wrong, we'll do the split the right way next time. + */ + off = 0; + if (NEXT_PGNO(pp) == PGNO_INVALID && cp->indx >= NUM_ENT(pp) - adjust) + off = NUM_ENT(pp) - adjust; + else if (PREV_PGNO(pp) == PGNO_INVALID && cp->indx == 0) + off = adjust; + if (off != 0) + goto sort; + + /* + * Split the data to the left and right pages. Try not to split on + * an overflow key. (Overflow keys on internal pages will slow down + * searches.) Refuse to split in the middle of a set of duplicates. + * + * First, find the optimum place to split. + * + * It's possible to try and split past the last record on the page if + * there's a very large record at the end of the page. Make sure this + * doesn't happen by bounding the check at the next-to-last entry on + * the page. + * + * Note, we try and split half the data present on the page. This is + * because another process may have already split the page and left + * it half empty. We don't try and skip the split -- we don't know + * how much space we're going to need on the page, and we may need up + * to half the page for a big item, so there's no easy test to decide + * if we need to split or not. Besides, if two threads are inserting + * data into the same place in the database, we're probably going to + * need more space soon anyway. + */ + top = NUM_ENT(pp) - adjust; + half = (dbp->pgsize - HOFFSET(pp)) / 2; + for (nbytes = 0, off = 0; off < top && nbytes < half; ++off) + switch (TYPE(pp)) { + case P_IBTREE: + if (B_TYPE( + GET_BINTERNAL(dbp, pp, off)->type) == B_KEYDATA) + nbytes += BINTERNAL_SIZE( + GET_BINTERNAL(dbp, pp, off)->len); + else + nbytes += BINTERNAL_SIZE(BOVERFLOW_SIZE); + break; + case P_LBTREE: + if (B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) == + B_KEYDATA) + nbytes += BKEYDATA_SIZE(GET_BKEYDATA(dbp, + pp, off)->len); + else + nbytes += BOVERFLOW_SIZE; + + ++off; + /* FALLTHROUGH */ + case P_LDUP: + case P_LRECNO: + if (B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) == + B_KEYDATA) + nbytes += BKEYDATA_SIZE(GET_BKEYDATA(dbp, + pp, off)->len); + else + nbytes += BOVERFLOW_SIZE; + break; + case P_IRECNO: + nbytes += RINTERNAL_SIZE; + break; + default: + return (__db_pgfmt(dbp->env, pp->pgno)); + } +sort: splitp = off; + + /* + * Splitp is either at or just past the optimum split point. If the + * tree type is such that we're going to promote a key to an internal + * page, and our current choice is an overflow key, look for something + * close by that's smaller. + */ + switch (TYPE(pp)) { + case P_IBTREE: + iflag = 1; + isbigkey = + B_TYPE(GET_BINTERNAL(dbp, pp, off)->type) != B_KEYDATA; + break; + case P_LBTREE: + case P_LDUP: + iflag = 0; + isbigkey = B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) != + B_KEYDATA; + break; + default: + iflag = isbigkey = 0; + } + if (isbigkey) + for (cnt = 1; cnt <= 3; ++cnt) { + off = splitp + cnt * adjust; + if (off < (db_indx_t)NUM_ENT(pp) && + ((iflag && B_TYPE( + GET_BINTERNAL(dbp, pp,off)->type) == B_KEYDATA) || + B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) == + B_KEYDATA)) { + splitp = off; + break; + } + if (splitp <= (db_indx_t)(cnt * adjust)) + continue; + off = splitp - cnt * adjust; + if (iflag ? B_TYPE( + GET_BINTERNAL(dbp, pp, off)->type) == B_KEYDATA : + B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) == + B_KEYDATA) { + splitp = off; + break; + } + } + + /* + * We can't split in the middle a set of duplicates. We know that + * no duplicate set can take up more than about 25% of the page, + * because that's the point where we push it off onto a duplicate + * page set. So, this loop can't be unbounded. + */ + if (TYPE(pp) == P_LBTREE && + inp[splitp] == inp[splitp - adjust]) + for (cnt = 1;; ++cnt) { + off = splitp + cnt * adjust; + if (off < NUM_ENT(pp) && + inp[splitp] != inp[off]) { + splitp = off; + break; + } + if (splitp <= (db_indx_t)(cnt * adjust)) + continue; + off = splitp - cnt * adjust; + if (inp[splitp] != inp[off]) { + splitp = off + adjust; + break; + } + } + + /* We're going to split at splitp. */ + if ((ret = __bam_copy(dbp, pp, lp, 0, splitp)) != 0) + return (ret); + if ((ret = __bam_copy(dbp, pp, rp, splitp, NUM_ENT(pp))) != 0) + return (ret); + + *splitret = splitp; + return (0); +} + +/* + * __bam_copy -- + * Copy a set of records from one page to another. + * + * PUBLIC: int __bam_copy __P((DB *, PAGE *, PAGE *, u_int32_t, u_int32_t)); + */ +int +__bam_copy(dbp, pp, cp, nxt, stop) + DB *dbp; + PAGE *pp, *cp; + u_int32_t nxt, stop; +{ + BINTERNAL internal; + db_indx_t *cinp, nbytes, off, *pinp; + + cinp = P_INP(dbp, cp); + pinp = P_INP(dbp, pp); + /* + * Nxt is the offset of the next record to be placed on the target page. + */ + for (off = 0; nxt < stop; ++nxt, ++NUM_ENT(cp), ++off) { + switch (TYPE(pp)) { + case P_IBTREE: + if (off == 0 && nxt != 0) + nbytes = BINTERNAL_SIZE(0); + else if (B_TYPE( + GET_BINTERNAL(dbp, pp, nxt)->type) == B_KEYDATA) + nbytes = BINTERNAL_SIZE( + GET_BINTERNAL(dbp, pp, nxt)->len); + else + nbytes = BINTERNAL_SIZE(BOVERFLOW_SIZE); + break; + case P_LBTREE: + /* + * If we're on a key and it's a duplicate, just copy + * the offset. + */ + if (off != 0 && (nxt % P_INDX) == 0 && + pinp[nxt] == pinp[nxt - P_INDX]) { + cinp[off] = cinp[off - P_INDX]; + continue; + } + /* FALLTHROUGH */ + case P_LDUP: + case P_LRECNO: + if (B_TYPE(GET_BKEYDATA(dbp, pp, nxt)->type) == + B_KEYDATA) + nbytes = BKEYDATA_SIZE(GET_BKEYDATA(dbp, + pp, nxt)->len); + else + nbytes = BOVERFLOW_SIZE; + break; + case P_IRECNO: + nbytes = RINTERNAL_SIZE; + break; + default: + return (__db_pgfmt(dbp->env, pp->pgno)); + } + cinp[off] = HOFFSET(cp) -= nbytes; + if (off == 0 && nxt != 0 && TYPE(pp) == P_IBTREE) { + internal.len = 0; + UMRW_SET(internal.unused); + internal.type = B_KEYDATA; + internal.pgno = GET_BINTERNAL(dbp, pp, nxt)->pgno; + internal.nrecs = GET_BINTERNAL(dbp, pp, nxt)->nrecs; + memcpy(P_ENTRY(dbp, cp, off), &internal, nbytes); + } + else + memcpy(P_ENTRY(dbp, cp, off), + P_ENTRY(dbp, pp, nxt), nbytes); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_stat.c b/src/libs/resiprocate/contrib/db/btree/bt_stat.c new file mode 100644 index 00000000..912a1667 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_stat.c @@ -0,0 +1,669 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" +#include "dbinc/partition.h" + +#ifdef HAVE_STATISTICS +/* + * __bam_stat -- + * Gather/print the btree statistics + * + * PUBLIC: int __bam_stat __P((DBC *, void *, u_int32_t)); + */ +int +__bam_stat(dbc, spp, flags) + DBC *dbc; + void *spp; + u_int32_t flags; +{ + BTMETA *meta; + BTREE *t; + BTREE_CURSOR *cp; + DB *dbp; + DB_BTREE_STAT *sp; + DB_LOCK lock, metalock; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *h; + db_pgno_t pgno; + int ret, t_ret, write_meta; + + dbp = dbc->dbp; + env = dbp->env; + + meta = NULL; + t = dbp->bt_internal; + sp = NULL; + LOCK_INIT(metalock); + LOCK_INIT(lock); + mpf = dbp->mpf; + h = NULL; + ret = write_meta = 0; + + cp = (BTREE_CURSOR *)dbc->internal; + + /* Allocate and clear the structure. */ + if ((ret = __os_umalloc(env, sizeof(*sp), &sp)) != 0) + goto err; + memset(sp, 0, sizeof(*sp)); + + /* Get the metadata page for the entire database. */ + pgno = PGNO_BASE_MD; + if ((ret = __db_lget(dbc, 0, pgno, DB_LOCK_READ, 0, &metalock)) != 0) + goto err; + if ((ret = __memp_fget(mpf, &pgno, + dbc->thread_info, dbc->txn, 0, &meta)) != 0) + goto err; + + if (flags == DB_FAST_STAT) + goto meta_only; + + /* Walk the metadata free list, counting pages. */ + for (sp->bt_free = 0, pgno = meta->dbmeta.free; pgno != PGNO_INVALID;) { + ++sp->bt_free; + + if ((ret = __memp_fget(mpf, &pgno, + dbc->thread_info, dbc->txn, 0, &h)) != 0) + goto err; + + pgno = h->next_pgno; + if ((ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0) + goto err; + h = NULL; + } + + /* Get the root page. */ + pgno = cp->root; + if ((ret = __db_lget(dbc, 0, pgno, DB_LOCK_READ, 0, &lock)) != 0) + goto err; + if ((ret = __memp_fget(mpf, &pgno, + dbc->thread_info, dbc->txn, 0, &h)) != 0) + goto err; + + /* Get the levels from the root page. */ + sp->bt_levels = h->level; + + /* Discard the root page. */ + ret = __memp_fput(mpf, dbc->thread_info, h, dbc->priority); + h = NULL; + if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + goto err; + + /* Walk the tree. */ + if ((ret = __bam_traverse(dbc, + DB_LOCK_READ, cp->root, __bam_stat_callback, sp)) != 0) + goto err; + +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp) && (ret = __bam_compress_count(dbc, + &sp->bt_nkeys, &sp->bt_ndata)) != 0) + goto err; +#endif + + /* + * Get the subdatabase metadata page if it's not the same as the + * one we already have. + */ + write_meta = !F_ISSET(dbp, DB_AM_RDONLY) && + (!MULTIVERSION(dbp) || dbc->txn != NULL); +meta_only: + if (t->bt_meta != PGNO_BASE_MD || write_meta) { + ret = __memp_fput(mpf, dbc->thread_info, meta, dbc->priority); + meta = NULL; + if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + goto err; + + if ((ret = __db_lget(dbc, + 0, t->bt_meta, write_meta ? DB_LOCK_WRITE : DB_LOCK_READ, + 0, &metalock)) != 0) + goto err; + if ((ret = __memp_fget(mpf, &t->bt_meta, + dbc->thread_info, dbc->txn, + write_meta ? DB_MPOOL_DIRTY : 0, &meta)) != 0) + goto err; + } + if (flags == DB_FAST_STAT) { + if (dbp->type == DB_RECNO || + (dbp->type == DB_BTREE && F_ISSET(dbp, DB_AM_RECNUM))) { + if ((ret = __db_lget(dbc, 0, + cp->root, DB_LOCK_READ, 0, &lock)) != 0) + goto err; + if ((ret = __memp_fget(mpf, &cp->root, + dbc->thread_info, dbc->txn, 0, &h)) != 0) + goto err; + + sp->bt_nkeys = RE_NREC(h); + } else + sp->bt_nkeys = meta->dbmeta.key_count; + + sp->bt_ndata = dbp->type == DB_RECNO ? + sp->bt_nkeys : meta->dbmeta.record_count; + } + + /* Get metadata page statistics. */ + sp->bt_metaflags = meta->dbmeta.flags; + sp->bt_minkey = meta->minkey; + sp->bt_re_len = meta->re_len; + sp->bt_re_pad = meta->re_pad; + /* + * Don't take the page number from the meta-data page -- that value is + * only maintained in the primary database, we may have been called on + * a subdatabase. (Yes, I read the primary database meta-data page + * earlier in this function, but I'm asking the underlying cache so the + * code for the Hash and Btree methods is the same.) + */ + if ((ret = __memp_get_last_pgno(dbp->mpf, &pgno)) != 0) + goto err; + sp->bt_pagecnt = pgno + 1; + sp->bt_pagesize = meta->dbmeta.pagesize; + sp->bt_magic = meta->dbmeta.magic; + sp->bt_version = meta->dbmeta.version; + + if (write_meta != 0) { + meta->dbmeta.key_count = sp->bt_nkeys; + meta->dbmeta.record_count = sp->bt_ndata; + } + + *(DB_BTREE_STAT **)spp = sp; + +err: /* Discard the second page. */ + if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) + ret = t_ret; + if (h != NULL && (t_ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + + /* Discard the metadata page. */ + if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) + ret = t_ret; + if (meta != NULL && (t_ret = __memp_fput(mpf, + dbc->thread_info, meta, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + + if (ret != 0 && sp != NULL) { + __os_ufree(env, sp); + *(DB_BTREE_STAT **)spp = NULL; + } + + return (ret); +} + +/* + * __bam_stat_print -- + * Display btree/recno statistics. + * + * PUBLIC: int __bam_stat_print __P((DBC *, u_int32_t)); + */ +int +__bam_stat_print(dbc, flags) + DBC *dbc; + u_int32_t flags; +{ + static const FN fn[] = { + { BTM_DUP, "duplicates" }, + { BTM_RECNO, "recno" }, + { BTM_RECNUM, "record-numbers" }, + { BTM_FIXEDLEN, "fixed-length" }, + { BTM_RENUMBER, "renumber" }, + { BTM_SUBDB, "multiple-databases" }, + { BTM_DUPSORT, "sorted duplicates" }, + { BTM_COMPRESS, "compressed" }, + { 0, NULL } + }; + DB *dbp; + DB_BTREE_STAT *sp; + ENV *env; + int lorder, ret; + const char *s; + + dbp = dbc->dbp; + env = dbp->env; +#ifdef HAVE_PARTITION + if (DB_IS_PARTITIONED(dbp)) { + if ((ret = __partition_stat(dbc, &sp, flags)) != 0) + return (ret); + } else +#endif + if ((ret = __bam_stat(dbc, &sp, LF_ISSET(DB_FAST_STAT))) != 0) + return (ret); + + if (LF_ISSET(DB_STAT_ALL)) { + __db_msg(env, "%s", DB_GLOBAL(db_line)); + __db_msg(env, "Default Btree/Recno database information:"); + } + + __db_msg(env, "%lx\tBtree magic number", (u_long)sp->bt_magic); + __db_msg(env, "%lu\tBtree version number", (u_long)sp->bt_version); + + (void)__db_get_lorder(dbp, &lorder); + switch (lorder) { + case 1234: + s = "Little-endian"; + break; + case 4321: + s = "Big-endian"; + break; + default: + s = "Unrecognized byte order"; + break; + } + __db_msg(env, "%s\tByte order", s); + __db_prflags(env, NULL, sp->bt_metaflags, fn, NULL, "\tFlags"); + if (dbp->type == DB_BTREE) + __db_dl(env, "Minimum keys per-page", (u_long)sp->bt_minkey); + if (dbp->type == DB_RECNO) { + __db_dl(env, + "Fixed-length record size", (u_long)sp->bt_re_len); + __db_msg(env, + "%#x\tFixed-length record pad", (u_int)sp->bt_re_pad); + } + __db_dl(env, + "Underlying database page size", (u_long)sp->bt_pagesize); + if (dbp->type == DB_BTREE) + __db_dl(env, "Overflow key/data size", + ((BTREE_CURSOR *)dbc->internal)->ovflsize); + __db_dl(env, "Number of levels in the tree", (u_long)sp->bt_levels); + __db_dl(env, dbp->type == DB_BTREE ? + "Number of unique keys in the tree" : + "Number of records in the tree", (u_long)sp->bt_nkeys); + __db_dl(env, + "Number of data items in the tree", (u_long)sp->bt_ndata); + + __db_dl(env, + "Number of tree internal pages", (u_long)sp->bt_int_pg); + __db_dl_pct(env, + "Number of bytes free in tree internal pages", + (u_long)sp->bt_int_pgfree, + DB_PCT_PG(sp->bt_int_pgfree, sp->bt_int_pg, sp->bt_pagesize), "ff"); + + __db_dl(env, + "Number of tree leaf pages", (u_long)sp->bt_leaf_pg); + __db_dl_pct(env, "Number of bytes free in tree leaf pages", + (u_long)sp->bt_leaf_pgfree, DB_PCT_PG( + sp->bt_leaf_pgfree, sp->bt_leaf_pg, sp->bt_pagesize), "ff"); + + __db_dl(env, + "Number of tree duplicate pages", (u_long)sp->bt_dup_pg); + __db_dl_pct(env, + "Number of bytes free in tree duplicate pages", + (u_long)sp->bt_dup_pgfree, + DB_PCT_PG(sp->bt_dup_pgfree, sp->bt_dup_pg, sp->bt_pagesize), "ff"); + + __db_dl(env, + "Number of tree overflow pages", (u_long)sp->bt_over_pg); + __db_dl_pct(env, "Number of bytes free in tree overflow pages", + (u_long)sp->bt_over_pgfree, DB_PCT_PG( + sp->bt_over_pgfree, sp->bt_over_pg, sp->bt_pagesize), "ff"); + __db_dl(env, "Number of empty pages", (u_long)sp->bt_empty_pg); + + __db_dl(env, "Number of pages on the free list", (u_long)sp->bt_free); + + __os_ufree(env, sp); + + return (0); +} + +/* + * __bam_stat_callback -- + * Statistics callback. + * + * PUBLIC: int __bam_stat_callback __P((DBC *, PAGE *, void *, int *)); + */ +int +__bam_stat_callback(dbc, h, cookie, putp) + DBC *dbc; + PAGE *h; + void *cookie; + int *putp; +{ + DB *dbp; + DB_BTREE_STAT *sp; + db_indx_t indx, *inp, top; + u_int8_t type; + + dbp = dbc->dbp; + sp = cookie; + *putp = 0; + top = NUM_ENT(h); + inp = P_INP(dbp, h); + + switch (TYPE(h)) { + case P_IBTREE: + case P_IRECNO: + ++sp->bt_int_pg; + sp->bt_int_pgfree += P_FREESPACE(dbp, h); + break; + case P_LBTREE: + if (top == 0) + ++sp->bt_empty_pg; + + /* Correct for on-page duplicates and deleted items. */ + for (indx = 0; indx < top; indx += P_INDX) { + type = GET_BKEYDATA(dbp, h, indx + O_INDX)->type; + /* Ignore deleted items. */ + if (B_DISSET(type)) + continue; + + /* Ignore duplicate keys. */ + if (indx + P_INDX >= top || + inp[indx] != inp[indx + P_INDX]) + ++sp->bt_nkeys; + + /* Ignore off-page duplicates. */ + if (B_TYPE(type) != B_DUPLICATE) + ++sp->bt_ndata; + } + + ++sp->bt_leaf_pg; + sp->bt_leaf_pgfree += P_FREESPACE(dbp, h); + break; + case P_LRECNO: + if (top == 0) + ++sp->bt_empty_pg; + + /* + * If walking a recno tree, then each of these items is a key. + * Otherwise, we're walking an off-page duplicate set. + */ + if (dbp->type == DB_RECNO) { + /* + * Correct for deleted items in non-renumbering Recno + * databases. + */ + if (F_ISSET(dbp, DB_AM_RENUMBER)) { + sp->bt_nkeys += top; + sp->bt_ndata += top; + } else + for (indx = 0; indx < top; indx += O_INDX) { + type = GET_BKEYDATA(dbp, h, indx)->type; + if (!B_DISSET(type)) { + ++sp->bt_ndata; + ++sp->bt_nkeys; + } + } + + ++sp->bt_leaf_pg; + sp->bt_leaf_pgfree += P_FREESPACE(dbp, h); + } else { + sp->bt_ndata += top; + + ++sp->bt_dup_pg; + sp->bt_dup_pgfree += P_FREESPACE(dbp, h); + } + break; + case P_LDUP: + if (top == 0) + ++sp->bt_empty_pg; + + /* Correct for deleted items. */ + for (indx = 0; indx < top; indx += O_INDX) + if (!B_DISSET(GET_BKEYDATA(dbp, h, indx)->type)) + ++sp->bt_ndata; + + ++sp->bt_dup_pg; + sp->bt_dup_pgfree += P_FREESPACE(dbp, h); + break; + case P_OVERFLOW: + ++sp->bt_over_pg; + sp->bt_over_pgfree += P_OVFLSPACE(dbp, dbp->pgsize, h); + break; + default: + return (__db_pgfmt(dbp->env, h->pgno)); + } + return (0); +} + +/* + * __bam_print_cursor -- + * Display the current internal cursor. + * + * PUBLIC: void __bam_print_cursor __P((DBC *)); + */ +void +__bam_print_cursor(dbc) + DBC *dbc; +{ + static const FN fn[] = { + { C_DELETED, "C_DELETED" }, + { C_RECNUM, "C_RECNUM" }, + { C_RENUMBER, "C_RENUMBER" }, + { 0, NULL } + }; + ENV *env; + BTREE_CURSOR *cp; + + env = dbc->env; + cp = (BTREE_CURSOR *)dbc->internal; + + STAT_ULONG("Overflow size", cp->ovflsize); + if (dbc->dbtype == DB_RECNO) + STAT_ULONG("Recno", cp->recno); + STAT_ULONG("Order", cp->order); + __db_prflags(env, NULL, cp->flags, fn, NULL, "\tInternal Flags"); +} + +#else /* !HAVE_STATISTICS */ + +int +__bam_stat(dbc, spp, flags) + DBC *dbc; + void *spp; + u_int32_t flags; +{ + COMPQUIET(spp, NULL); + COMPQUIET(flags, 0); + + return (__db_stat_not_built(dbc->env)); +} + +int +__bam_stat_print(dbc, flags) + DBC *dbc; + u_int32_t flags; +{ + COMPQUIET(flags, 0); + + return (__db_stat_not_built(dbc->env)); +} +#endif + +#ifndef HAVE_BREW +/* + * __bam_key_range -- + * Return proportion of keys relative to given key. The numbers are + * slightly skewed due to on page duplicates. + * + * PUBLIC: int __bam_key_range __P((DBC *, DBT *, DB_KEY_RANGE *, u_int32_t)); + */ +int +__bam_key_range(dbc, dbt, kp, flags) + DBC *dbc; + DBT *dbt; + DB_KEY_RANGE *kp; + u_int32_t flags; +{ + BTREE_CURSOR *cp; + EPG *sp; + double factor; + int exact, ret; + + COMPQUIET(flags, 0); + + if ((ret = __bam_search(dbc, PGNO_INVALID, + dbt, SR_STK_ONLY, 1, NULL, &exact)) != 0) + return (ret); + + cp = (BTREE_CURSOR *)dbc->internal; + kp->less = kp->greater = 0.0; + + factor = 1.0; + + /* Correct the leaf page. */ + cp->csp->entries /= 2; + cp->csp->indx /= 2; + for (sp = cp->sp; sp <= cp->csp; ++sp) { + /* + * At each level we know that pages greater than indx contain + * keys greater than what we are looking for and those less + * than indx are less than. The one pointed to by indx may + * have some less, some greater or even equal. If indx is + * equal to the number of entries, then the key is out of range + * and everything is less. + */ + if (sp->indx == 0) + kp->greater += factor * (sp->entries - 1)/sp->entries; + else if (sp->indx == sp->entries) + kp->less += factor; + else { + kp->less += factor * sp->indx / sp->entries; + kp->greater += factor * + ((sp->entries - sp->indx) - 1) / sp->entries; + } + factor *= 1.0/sp->entries; + } + + /* + * If there was an exact match then assign 1 n'th to the key itself. + * Otherwise that factor belongs to those greater than the key, unless + * the key was out of range. + */ + if (exact) + kp->equal = factor; + else { + if (kp->less != 1) + kp->greater += factor; + kp->equal = 0; + } + + BT_STK_CLR(cp); + + return (0); +} +#endif + +/* + * __bam_traverse -- + * Walk a Btree database. + * + * PUBLIC: int __bam_traverse __P((DBC *, db_lockmode_t, + * PUBLIC: db_pgno_t, int (*)(DBC *, PAGE *, void *, int *), void *)); + */ +int +__bam_traverse(dbc, mode, root_pgno, callback, cookie) + DBC *dbc; + db_lockmode_t mode; + db_pgno_t root_pgno; + int (*callback)__P((DBC *, PAGE *, void *, int *)); + void *cookie; +{ + BINTERNAL *bi; + BKEYDATA *bk; + DB *dbp; + DB_LOCK lock; + DB_MPOOLFILE *mpf; + PAGE *h; + RINTERNAL *ri; + db_indx_t indx, *inp; + int already_put, ret, t_ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + already_put = 0; + + if ((ret = __db_lget(dbc, 0, root_pgno, mode, 0, &lock)) != 0) + return (ret); + if ((ret = __memp_fget(mpf, &root_pgno, + dbc->thread_info, dbc->txn, 0, &h)) != 0) { + (void)__TLPUT(dbc, lock); + return (ret); + } + + switch (TYPE(h)) { + case P_IBTREE: + for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) { + bi = GET_BINTERNAL(dbp, h, indx); + if (B_TYPE(bi->type) == B_OVERFLOW && + (ret = __db_traverse_big(dbc, + ((BOVERFLOW *)bi->data)->pgno, + callback, cookie)) != 0) + goto err; + if ((ret = __bam_traverse( + dbc, mode, bi->pgno, callback, cookie)) != 0) + goto err; + } + break; + case P_IRECNO: + for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) { + ri = GET_RINTERNAL(dbp, h, indx); + if ((ret = __bam_traverse( + dbc, mode, ri->pgno, callback, cookie)) != 0) + goto err; + } + break; + case P_LBTREE: + inp = P_INP(dbp, h); + for (indx = 0; indx < NUM_ENT(h); indx += P_INDX) { + bk = GET_BKEYDATA(dbp, h, indx); + if (B_TYPE(bk->type) == B_OVERFLOW && + (indx + P_INDX >= NUM_ENT(h) || + inp[indx] != inp[indx + P_INDX])) { + if ((ret = __db_traverse_big(dbc, + GET_BOVERFLOW(dbp, h, indx)->pgno, + callback, cookie)) != 0) + goto err; + } + bk = GET_BKEYDATA(dbp, h, indx + O_INDX); + if (B_TYPE(bk->type) == B_DUPLICATE && + (ret = __bam_traverse(dbc, mode, + GET_BOVERFLOW(dbp, h, indx + O_INDX)->pgno, + callback, cookie)) != 0) + goto err; + if (B_TYPE(bk->type) == B_OVERFLOW && + (ret = __db_traverse_big(dbc, + GET_BOVERFLOW(dbp, h, indx + O_INDX)->pgno, + callback, cookie)) != 0) + goto err; + } + break; + case P_LDUP: + case P_LRECNO: + for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) { + bk = GET_BKEYDATA(dbp, h, indx); + if (B_TYPE(bk->type) == B_OVERFLOW && + (ret = __db_traverse_big(dbc, + GET_BOVERFLOW(dbp, h, indx)->pgno, + callback, cookie)) != 0) + goto err; + } + break; + default: + return (__db_pgfmt(dbp->env, h->pgno)); + } + + ret = callback(dbc, h, cookie, &already_put); + +err: if (!already_put && (t_ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_upgrade.c b/src/libs/resiprocate/contrib/db/btree/bt_upgrade.c new file mode 100644 index 00000000..edf67188 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_upgrade.c @@ -0,0 +1,153 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_upgrade.h" +#include "dbinc/btree.h" + +/* + * __bam_30_btreemeta -- + * Upgrade the metadata pages from version 6 to version 7. + * + * PUBLIC: int __bam_30_btreemeta __P((DB *, char *, u_int8_t *)); + */ +int +__bam_30_btreemeta(dbp, real_name, buf) + DB *dbp; + char *real_name; + u_int8_t *buf; +{ + BTMETA2X *oldmeta; + BTMETA30 *newmeta; + ENV *env; + int ret; + + env = dbp->env; + + newmeta = (BTMETA30 *)buf; + oldmeta = (BTMETA2X *)buf; + + /* + * Move things from the end up, so we do not overwrite things. + * We are going to create a new uid, so we can move the stuff + * at the end of the structure first, overwriting the uid. + */ + + newmeta->re_pad = oldmeta->re_pad; + newmeta->re_len = oldmeta->re_len; + newmeta->minkey = oldmeta->minkey; + newmeta->maxkey = oldmeta->maxkey; + newmeta->dbmeta.free = oldmeta->free; + newmeta->dbmeta.flags = oldmeta->flags; + newmeta->dbmeta.type = P_BTREEMETA; + + newmeta->dbmeta.version = 7; + /* Replace the unique ID. */ + if ((ret = __os_fileid(env, real_name, 1, buf + 36)) != 0) + return (ret); + + newmeta->root = 1; + + return (0); +} + +/* + * __bam_31_btreemeta -- + * Upgrade the database from version 7 to version 8. + * + * PUBLIC: int __bam_31_btreemeta + * PUBLIC: __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); + */ +int +__bam_31_btreemeta(dbp, real_name, flags, fhp, h, dirtyp) + DB *dbp; + char *real_name; + u_int32_t flags; + DB_FH *fhp; + PAGE *h; + int *dirtyp; +{ + BTMETA30 *oldmeta; + BTMETA31 *newmeta; + + COMPQUIET(dbp, NULL); + COMPQUIET(real_name, NULL); + COMPQUIET(fhp, NULL); + + newmeta = (BTMETA31 *)h; + oldmeta = (BTMETA30 *)h; + + /* + * Copy the effected fields down the page. + * The fields may overlap each other so we + * start at the bottom and use memmove. + */ + newmeta->root = oldmeta->root; + newmeta->re_pad = oldmeta->re_pad; + newmeta->re_len = oldmeta->re_len; + newmeta->minkey = oldmeta->minkey; + newmeta->maxkey = oldmeta->maxkey; + memmove(newmeta->dbmeta.uid, + oldmeta->dbmeta.uid, sizeof(oldmeta->dbmeta.uid)); + newmeta->dbmeta.flags = oldmeta->dbmeta.flags; + newmeta->dbmeta.record_count = 0; + newmeta->dbmeta.key_count = 0; + ZERO_LSN(newmeta->dbmeta.unused3); + + /* Set the version number. */ + newmeta->dbmeta.version = 8; + + /* Upgrade the flags. */ + if (LF_ISSET(DB_DUPSORT)) + F_SET(&newmeta->dbmeta, BTM_DUPSORT); + + *dirtyp = 1; + return (0); +} + +/* + * __bam_31_lbtree -- + * Upgrade the database btree leaf pages. + * + * PUBLIC: int __bam_31_lbtree + * PUBLIC: __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); + */ +int +__bam_31_lbtree(dbp, real_name, flags, fhp, h, dirtyp) + DB *dbp; + char *real_name; + u_int32_t flags; + DB_FH *fhp; + PAGE *h; + int *dirtyp; +{ + BKEYDATA *bk; + db_pgno_t pgno; + db_indx_t indx; + int ret; + + ret = 0; + for (indx = O_INDX; indx < NUM_ENT(h); indx += P_INDX) { + bk = GET_BKEYDATA(dbp, h, indx); + if (B_TYPE(bk->type) == B_DUPLICATE) { + pgno = GET_BOVERFLOW(dbp, h, indx)->pgno; + if ((ret = __db_31_offdup(dbp, real_name, fhp, + LF_ISSET(DB_DUPSORT) ? 1 : 0, &pgno)) != 0) + break; + if (pgno != GET_BOVERFLOW(dbp, h, indx)->pgno) { + *dirtyp = 1; + GET_BOVERFLOW(dbp, h, indx)->pgno = pgno; + } + } + } + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/btree/bt_verify.c b/src/libs/resiprocate/contrib/db/btree/bt_verify.c new file mode 100644 index 00000000..1c561d24 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/bt_verify.c @@ -0,0 +1,2746 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1999-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_verify.h" +#include "dbinc/btree.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" + +static int __bam_safe_getdata __P((DB *, DB_THREAD_INFO *, + PAGE *, u_int32_t, int, DBT *, int *)); +static int __bam_vrfy_inp __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, + db_indx_t *, u_int32_t)); +static int __bam_vrfy_treeorder __P((DB *, DB_THREAD_INFO *, PAGE *, + BINTERNAL *, BINTERNAL *, int (*)(DB *, const DBT *, const DBT *), + u_int32_t)); +static int __ram_vrfy_inp __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, + db_indx_t *, u_int32_t)); + +/* + * __bam_vrfy_meta -- + * Verify the btree-specific part of a metadata page. + * + * PUBLIC: int __bam_vrfy_meta __P((DB *, VRFY_DBINFO *, BTMETA *, + * PUBLIC: db_pgno_t, u_int32_t)); + */ +int +__bam_vrfy_meta(dbp, vdp, meta, pgno, flags) + DB *dbp; + VRFY_DBINFO *vdp; + BTMETA *meta; + db_pgno_t pgno; + u_int32_t flags; +{ + ENV *env; + VRFY_PAGEINFO *pip; + int isbad, t_ret, ret; + db_indx_t ovflsize; + + env = dbp->env; + isbad = 0; + + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + + /* + * If VRFY_INCOMPLETE is not set, then we didn't come through + * __db_vrfy_pagezero and didn't incompletely + * check this page--we haven't checked it at all. + * Thus we need to call __db_vrfy_meta and check the common fields. + * + * If VRFY_INCOMPLETE is set, we've already done all the same work + * in __db_vrfy_pagezero, so skip the check. + */ + if (!F_ISSET(pip, VRFY_INCOMPLETE) && + (ret = __db_vrfy_meta(dbp, vdp, &meta->dbmeta, pgno, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + + /* bt_minkey: must be >= 2; must produce sensible ovflsize */ + + /* avoid division by zero */ + ovflsize = meta->minkey > 0 ? + B_MINKEY_TO_OVFLSIZE(dbp, meta->minkey, dbp->pgsize) : 0; + + if (meta->minkey < 2 || + ovflsize > B_MINKEY_TO_OVFLSIZE(dbp, DEFMINKEYPAGE, dbp->pgsize)) { + pip->bt_minkey = 0; + isbad = 1; + EPRINT((env, + "Page %lu: nonsensical bt_minkey value %lu on metadata page", + (u_long)pgno, (u_long)meta->minkey)); + } else + pip->bt_minkey = meta->minkey; + + /* re_len: no constraints on this (may be zero or huge--we make rope) */ + pip->re_pad = meta->re_pad; + pip->re_len = meta->re_len; + + /* + * The root must not be current page or 0 and it must be within + * database. If this metadata page is the master meta data page + * of the file, then the root page had better be page 1. + */ + pip->root = 0; + if (meta->root == PGNO_INVALID || + meta->root == pgno || !IS_VALID_PGNO(meta->root) || + (pgno == PGNO_BASE_MD && meta->root != 1)) { + isbad = 1; + EPRINT((env, + "Page %lu: nonsensical root page %lu on metadata page", + (u_long)pgno, (u_long)meta->root)); + } else + pip->root = meta->root; + + /* Flags. */ + if (F_ISSET(&meta->dbmeta, BTM_RENUMBER)) + F_SET(pip, VRFY_IS_RRECNO); + + if (F_ISSET(&meta->dbmeta, BTM_SUBDB)) { + /* + * If this is a master db meta page, it had better not have + * duplicates. + */ + if (F_ISSET(&meta->dbmeta, BTM_DUP) && pgno == PGNO_BASE_MD) { + isbad = 1; + EPRINT((env, +"Page %lu: Btree metadata page has both duplicates and multiple databases", + (u_long)pgno)); + } + F_SET(pip, VRFY_HAS_SUBDBS); + } + + if (F_ISSET(&meta->dbmeta, BTM_DUP)) + F_SET(pip, VRFY_HAS_DUPS); + if (F_ISSET(&meta->dbmeta, BTM_DUPSORT)) + F_SET(pip, VRFY_HAS_DUPSORT); + if (F_ISSET(&meta->dbmeta, BTM_RECNUM)) + F_SET(pip, VRFY_HAS_RECNUMS); + if (F_ISSET(pip, VRFY_HAS_RECNUMS) && F_ISSET(pip, VRFY_HAS_DUPS)) { + EPRINT((env, + "Page %lu: Btree metadata page illegally has both recnums and dups", + (u_long)pgno)); + isbad = 1; + } + + if (F_ISSET(&meta->dbmeta, BTM_RECNO)) { + F_SET(pip, VRFY_IS_RECNO); + dbp->type = DB_RECNO; + } else if (F_ISSET(pip, VRFY_IS_RRECNO)) { + isbad = 1; + EPRINT((env, + "Page %lu: metadata page has renumber flag set but is not recno", + (u_long)pgno)); + } + +#ifdef HAVE_COMPRESSION + if (F_ISSET(&meta->dbmeta, BTM_COMPRESS)) { + F_SET(pip, VRFY_HAS_COMPRESS); + if (!DB_IS_COMPRESSED(dbp)) { + ((BTREE *)dbp->bt_internal)->bt_compress = + __bam_defcompress; + ((BTREE *)dbp->bt_internal)->bt_decompress = + __bam_defdecompress; + } + /* + * Copy dup_compare to compress_dup_compare, and use the + * compression duplicate compare. + */ + if (F_ISSET(pip, VRFY_HAS_DUPSORT)) { + if (dbp->dup_compare == NULL) + dbp->dup_compare = __bam_defcmp; + if (((BTREE *)dbp->bt_internal)->compress_dup_compare + == NULL) { + ((BTREE *)dbp->bt_internal)-> + compress_dup_compare = dbp->dup_compare; + dbp->dup_compare = __bam_compress_dupcmp; + } + } + } + + if (F_ISSET(pip, VRFY_HAS_RECNUMS) && F_ISSET(pip, VRFY_HAS_COMPRESS)) { + EPRINT((env, + "Page %lu: Btree metadata page illegally has both recnums and compression", + (u_long)pgno)); + isbad = 1; + } + if (F_ISSET(pip, VRFY_HAS_DUPS) && !F_ISSET(pip, VRFY_HAS_DUPSORT) && + F_ISSET(pip, VRFY_HAS_COMPRESS)) { + EPRINT((env, + "Page %lu: Btree metadata page illegally has both unsorted duplicates%s", + (u_long)pgno, + " and compression")); + isbad = 1; + } +#endif + + if (F_ISSET(pip, VRFY_IS_RECNO) && F_ISSET(pip, VRFY_HAS_DUPS)) { + EPRINT((env, + "Page %lu: recno metadata page specifies duplicates", + (u_long)pgno)); + isbad = 1; + } + + if (F_ISSET(&meta->dbmeta, BTM_FIXEDLEN)) + F_SET(pip, VRFY_IS_FIXEDLEN); + else if (pip->re_len > 0) { + /* + * It's wrong to have an re_len if it's not a fixed-length + * database + */ + isbad = 1; + EPRINT((env, + "Page %lu: re_len of %lu in non-fixed-length database", + (u_long)pgno, (u_long)pip->re_len)); + } + + /* + * We do not check that the rest of the page is 0, because it may + * not be and may still be correct. + */ + +err: if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + if (LF_ISSET(DB_SALVAGE) && + (t_ret = __db_salvage_markdone(vdp, pgno)) != 0 && ret == 0) + ret = t_ret; + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); +} + +/* + * __ram_vrfy_leaf -- + * Verify a recno leaf page. + * + * PUBLIC: int __ram_vrfy_leaf __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, + * PUBLIC: u_int32_t)); + */ +int +__ram_vrfy_leaf(dbp, vdp, h, pgno, flags) + DB *dbp; + VRFY_DBINFO *vdp; + PAGE *h; + db_pgno_t pgno; + u_int32_t flags; +{ + BKEYDATA *bk; + ENV *env; + VRFY_PAGEINFO *pip; + db_indx_t i; + int ret, t_ret, isbad; + u_int32_t re_len_guess, len; + + env = dbp->env; + isbad = 0; + + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + + if (TYPE(h) != P_LRECNO) { + ret = __db_unknown_path(env, "__ram_vrfy_leaf"); + goto err; + } + + /* + * Verify (and, if relevant, save off) page fields common to + * all PAGEs. + */ + if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + + /* + * Verify inp[]. Return immediately if it returns DB_VERIFY_BAD; + * further checks are dangerous. + */ + if ((ret = __bam_vrfy_inp(dbp, + vdp, h, pgno, &pip->entries, flags)) != 0) + goto err; + + if (F_ISSET(pip, VRFY_HAS_DUPS)) { + EPRINT((env, + "Page %lu: Recno database has dups", (u_long)pgno)); + ret = DB_VERIFY_BAD; + goto err; + } + + /* + * Walk through inp and see if the lengths of all the records are the + * same--if so, this may be a fixed-length database, and we want to + * save off this value. We know inp to be safe if we've gotten this + * far. + */ + re_len_guess = 0; + for (i = 0; i < NUM_ENT(h); i++) { + bk = GET_BKEYDATA(dbp, h, i); + /* KEYEMPTY. Go on. */ + if (B_DISSET(bk->type)) + continue; + if (bk->type == B_OVERFLOW) + len = ((BOVERFLOW *)bk)->tlen; + else if (bk->type == B_KEYDATA) + len = bk->len; + else { + isbad = 1; + EPRINT((env, + "Page %lu: nonsensical type for item %lu", + (u_long)pgno, (u_long)i)); + continue; + } + if (re_len_guess == 0) + re_len_guess = len; + + /* + * Is this item's len the same as the last one's? If not, + * reset to 0 and break--we don't have a single re_len. + * Otherwise, go on to the next item. + */ + if (re_len_guess != len) { + re_len_guess = 0; + break; + } + } + pip->re_len = re_len_guess; + + /* Save off record count. */ + pip->rec_cnt = NUM_ENT(h); + +err: if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); +} + +/* + * __bam_vrfy -- + * Verify a btree leaf or internal page. + * + * PUBLIC: int __bam_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, + * PUBLIC: u_int32_t)); + */ +int +__bam_vrfy(dbp, vdp, h, pgno, flags) + DB *dbp; + VRFY_DBINFO *vdp; + PAGE *h; + db_pgno_t pgno; + u_int32_t flags; +{ + ENV *env; + VRFY_PAGEINFO *pip; + int ret, t_ret, isbad; + + env = dbp->env; + isbad = 0; + + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + + switch (TYPE(h)) { + case P_IBTREE: + case P_IRECNO: + case P_LBTREE: + case P_LDUP: + break; + default: + ret = __db_unknown_path(env, "__bam_vrfy"); + goto err; + } + + /* + * Verify (and, if relevant, save off) page fields common to + * all PAGEs. + */ + if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + + /* + * The record count is, on internal pages, stored in an overloaded + * next_pgno field. Save it off; we'll verify it when we check + * overall database structure. We could overload the field + * in VRFY_PAGEINFO, too, but this seems gross, and space + * is not at such a premium. + */ + pip->rec_cnt = RE_NREC(h); + + /* + * Verify inp[]. + */ + if (TYPE(h) == P_IRECNO) { + if ((ret = __ram_vrfy_inp(dbp, + vdp, h, pgno, &pip->entries, flags)) != 0) + goto err; + } else if ((ret = __bam_vrfy_inp(dbp, + vdp, h, pgno, &pip->entries, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + EPRINT((env, + "Page %lu: item order check unsafe: skipping", + (u_long)pgno)); + } else if (!LF_ISSET(DB_NOORDERCHK) && (ret = + __bam_vrfy_itemorder(dbp, + vdp, vdp->thread_info, h, pgno, 0, 0, 0, flags)) != 0) { + /* + * We know that the elements of inp are reasonable. + * + * Check that elements fall in the proper order. + */ + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + +err: if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); +} + +/* + * __ram_vrfy_inp -- + * Verify that all entries in a P_IRECNO inp[] array are reasonable, + * and count them. Note that P_LRECNO uses __bam_vrfy_inp; + * P_IRECNOs are a special, and simpler, case, since they have + * RINTERNALs rather than BKEYDATA/BINTERNALs. + */ +static int +__ram_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) + DB *dbp; + VRFY_DBINFO *vdp; + PAGE *h; + db_pgno_t pgno; + db_indx_t *nentriesp; + u_int32_t flags; +{ + ENV *env; + RINTERNAL *ri; + VRFY_CHILDINFO child; + VRFY_PAGEINFO *pip; + int ret, t_ret, isbad; + u_int32_t himark, i, offset, nentries; + db_indx_t *inp; + u_int8_t *pagelayout, *p; + + env = dbp->env; + isbad = 0; + memset(&child, 0, sizeof(VRFY_CHILDINFO)); + nentries = 0; + pagelayout = NULL; + + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + + if (TYPE(h) != P_IRECNO) { + ret = __db_unknown_path(env, "__ram_vrfy_inp"); + goto err; + } + + himark = dbp->pgsize; + if ((ret = __os_malloc(env, dbp->pgsize, &pagelayout)) != 0) + goto err; + memset(pagelayout, 0, dbp->pgsize); + inp = P_INP(dbp, h); + for (i = 0; i < NUM_ENT(h); i++) { + if ((u_int8_t *)inp + i >= (u_int8_t *)h + himark) { + EPRINT((env, + "Page %lu: entries listing %lu overlaps data", + (u_long)pgno, (u_long)i)); + ret = DB_VERIFY_BAD; + goto err; + } + offset = inp[i]; + /* + * Check that the item offset is reasonable: it points + * somewhere after the inp array and before the end of the + * page. + */ + if (offset <= (u_int32_t)((u_int8_t *)inp + i - + (u_int8_t *)h) || + offset > (u_int32_t)(dbp->pgsize - RINTERNAL_SIZE)) { + isbad = 1; + EPRINT((env, + "Page %lu: bad offset %lu at index %lu", + (u_long)pgno, (u_long)offset, (u_long)i)); + continue; + } + + /* Update the high-water mark (what HOFFSET should be) */ + if (offset < himark) + himark = offset; + + nentries++; + + /* Make sure this RINTERNAL is not multiply referenced. */ + ri = GET_RINTERNAL(dbp, h, i); + if (pagelayout[offset] == 0) { + pagelayout[offset] = 1; + child.pgno = ri->pgno; + child.type = V_RECNO; + child.nrecs = ri->nrecs; + if ((ret = __db_vrfy_childput(vdp, pgno, &child)) != 0) + goto err; + } else { + EPRINT((env, + "Page %lu: RINTERNAL structure at offset %lu referenced twice", + (u_long)pgno, (u_long)offset)); + isbad = 1; + } + } + + for (p = pagelayout + himark; + p < pagelayout + dbp->pgsize; + p += RINTERNAL_SIZE) + if (*p != 1) { + EPRINT((env, + "Page %lu: gap between items at offset %lu", + (u_long)pgno, (u_long)(p - pagelayout))); + isbad = 1; + } + + if ((db_indx_t)himark != HOFFSET(h)) { + EPRINT((env, + "Page %lu: bad HOFFSET %lu, appears to be %lu", + (u_long)pgno, (u_long)(HOFFSET(h)), (u_long)himark)); + isbad = 1; + } + + *nentriesp = nentries; + +err: if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + if (pagelayout != NULL) + __os_free(env, pagelayout); + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); +} + +typedef enum { VRFY_ITEM_NOTSET=0, VRFY_ITEM_BEGIN, VRFY_ITEM_END } VRFY_ITEM; + +/* + * __bam_vrfy_inp -- + * Verify that all entries in inp[] array are reasonable; + * count them. + */ +static int +__bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) + DB *dbp; + VRFY_DBINFO *vdp; + PAGE *h; + db_pgno_t pgno; + db_indx_t *nentriesp; + u_int32_t flags; +{ + BKEYDATA *bk; + BOVERFLOW *bo; + ENV *env; + VRFY_CHILDINFO child; + VRFY_ITEM *pagelayout; + VRFY_PAGEINFO *pip; + u_int32_t himark, offset; /* + * These would be db_indx_ts + * but for alignment. + */ + u_int32_t i, endoff, nentries; + int isbad, initem, isdupitem, ret, t_ret; + + env = dbp->env; + isbad = isdupitem = 0; + nentries = 0; + memset(&child, 0, sizeof(VRFY_CHILDINFO)); + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + + switch (TYPE(h)) { + case P_IBTREE: + case P_LBTREE: + case P_LDUP: + case P_LRECNO: + break; + default: + /* + * In the salvager, we might call this from a page which + * we merely suspect is a btree page. Otherwise, it + * shouldn't get called--if it is, that's a verifier bug. + */ + if (LF_ISSET(DB_SALVAGE)) + break; + ret = __db_unknown_path(env, "__bam_vrfy_inp"); + goto err; + } + + /* + * Loop through inp[], the array of items, until we either + * run out of entries or collide with the data. Keep track + * of h_offset in himark. + * + * For each element in inp[i], make sure it references a region + * that starts after the end of the inp array (as defined by + * NUM_ENT(h)), ends before the beginning of the page, doesn't + * overlap any other regions, and doesn't have a gap between + * it and the region immediately after it. + */ + himark = dbp->pgsize; + if ((ret = __os_calloc( + env, dbp->pgsize, sizeof(pagelayout[0]), &pagelayout)) != 0) + goto err; + for (i = 0; i < NUM_ENT(h); i++) { + switch (ret = __db_vrfy_inpitem(dbp, + h, pgno, i, 1, flags, &himark, &offset)) { + case 0: + break; + case DB_VERIFY_BAD: + isbad = 1; + continue; + case DB_VERIFY_FATAL: + isbad = 1; + goto err; + default: + DB_ASSERT(env, ret != 0); + break; + } + + /* + * We now have a plausible beginning for the item, and we know + * its length is safe. + * + * Mark the beginning and end in pagelayout so we can make sure + * items have no overlaps or gaps. + */ + bk = GET_BKEYDATA(dbp, h, i); + if (pagelayout[offset] == VRFY_ITEM_NOTSET) + pagelayout[offset] = VRFY_ITEM_BEGIN; + else if (pagelayout[offset] == VRFY_ITEM_BEGIN) { + /* + * Having two inp entries that point at the same patch + * of page is legal if and only if the page is + * a btree leaf and they're onpage duplicate keys-- + * that is, if (i % P_INDX) == 0. + */ + if ((i % P_INDX == 0) && (TYPE(h) == P_LBTREE)) { + /* Flag for later. */ + F_SET(pip, VRFY_HAS_DUPS); + + /* Bump up nentries so we don't undercount. */ + nentries++; + + /* + * We'll check to make sure the end is + * equal, too. + */ + isdupitem = 1; + } else { + isbad = 1; + EPRINT((env, "Page %lu: duplicated item %lu", + (u_long)pgno, (u_long)i)); + } + } + + /* + * Mark the end. Its location varies with the page type + * and the item type. + * + * If the end already has a sign other than 0, do nothing-- + * it's an overlap that we'll catch later. + */ + switch (B_TYPE(bk->type)) { + case B_KEYDATA: + if (TYPE(h) == P_IBTREE) + /* It's a BINTERNAL. */ + endoff = offset + BINTERNAL_SIZE(bk->len) - 1; + else + endoff = offset + BKEYDATA_SIZE(bk->len) - 1; + break; + case B_DUPLICATE: + /* + * Flag that we have dups; we'll check whether + * that's okay during the structure check. + */ + F_SET(pip, VRFY_HAS_DUPS); + /* FALLTHROUGH */ + case B_OVERFLOW: + /* + * Overflow entries on internal pages are stored + * as the _data_ of a BINTERNAL; overflow entries + * on leaf pages are stored as the entire entry. + */ + endoff = offset + + ((TYPE(h) == P_IBTREE) ? + BINTERNAL_SIZE(BOVERFLOW_SIZE) : + BOVERFLOW_SIZE) - 1; + break; + default: + /* + * We'll complain later; for now, just mark + * a minimum. + */ + endoff = offset + BKEYDATA_SIZE(0) - 1; + break; + } + + /* + * If this is an onpage duplicate key we've seen before, + * the end had better coincide too. + */ + if (isdupitem && pagelayout[endoff] != VRFY_ITEM_END) { + EPRINT((env, "Page %lu: duplicated item %lu", + (u_long)pgno, (u_long)i)); + isbad = 1; + } else if (pagelayout[endoff] == VRFY_ITEM_NOTSET) + pagelayout[endoff] = VRFY_ITEM_END; + isdupitem = 0; + + /* + * There should be no deleted items in a quiescent tree, + * except in recno. + */ + if (B_DISSET(bk->type) && TYPE(h) != P_LRECNO) { + isbad = 1; + EPRINT((env, "Page %lu: item %lu marked deleted", + (u_long)pgno, (u_long)i)); + } + + /* + * Check the type and such of bk--make sure it's reasonable + * for the pagetype. + */ + switch (B_TYPE(bk->type)) { + case B_KEYDATA: + /* + * This is a normal, non-overflow BKEYDATA or BINTERNAL. + * The only thing to check is the len, and that's + * already been done. + */ + break; + case B_DUPLICATE: + if (TYPE(h) == P_IBTREE) { + isbad = 1; + EPRINT((env, + "Page %lu: duplicate page referenced by internal btree page at item %lu", + (u_long)pgno, (u_long)i)); + break; + } else if (TYPE(h) == P_LRECNO) { + isbad = 1; + EPRINT((env, + "Page %lu: duplicate page referenced by recno page at item %lu", + (u_long)pgno, (u_long)i)); + break; + } + /* FALLTHROUGH */ + case B_OVERFLOW: + bo = (TYPE(h) == P_IBTREE) ? + (BOVERFLOW *)(((BINTERNAL *)bk)->data) : + (BOVERFLOW *)bk; + + if (B_TYPE(bk->type) == B_OVERFLOW) + /* Make sure tlen is reasonable. */ + if (bo->tlen > dbp->pgsize * vdp->last_pgno) { + isbad = 1; + EPRINT((env, + "Page %lu: impossible tlen %lu, item %lu", + (u_long)pgno, + (u_long)bo->tlen, (u_long)i)); + /* Don't save as a child. */ + break; + } + + if (!IS_VALID_PGNO(bo->pgno) || bo->pgno == pgno || + bo->pgno == PGNO_INVALID) { + isbad = 1; + EPRINT((env, + "Page %lu: offpage item %lu has bad pgno %lu", + (u_long)pgno, (u_long)i, (u_long)bo->pgno)); + /* Don't save as a child. */ + break; + } + + child.pgno = bo->pgno; + child.type = (B_TYPE(bk->type) == B_OVERFLOW ? + V_OVERFLOW : V_DUPLICATE); + child.tlen = bo->tlen; + if ((ret = __db_vrfy_childput(vdp, pgno, &child)) != 0) + goto err; + break; + default: + isbad = 1; + EPRINT((env, "Page %lu: item %lu of invalid type %lu", + (u_long)pgno, (u_long)i, (u_long)B_TYPE(bk->type))); + break; + } + } + + /* + * Now, loop through and make sure the items are contiguous and + * non-overlapping. + */ + initem = 0; + for (i = himark; i < dbp->pgsize; i++) + if (initem == 0) + switch (pagelayout[i]) { + case VRFY_ITEM_NOTSET: + /* May be just for alignment. */ + if (i != DB_ALIGN(i, sizeof(u_int32_t))) + continue; + + isbad = 1; + EPRINT((env, + "Page %lu: gap between items at offset %lu", + (u_long)pgno, (u_long)i)); + /* Find the end of the gap */ + for (; pagelayout[i + 1] == VRFY_ITEM_NOTSET && + (size_t)(i + 1) < dbp->pgsize; i++) + ; + break; + case VRFY_ITEM_BEGIN: + /* We've found an item. Check its alignment. */ + if (i != DB_ALIGN(i, sizeof(u_int32_t))) { + isbad = 1; + EPRINT((env, + "Page %lu: offset %lu unaligned", + (u_long)pgno, (u_long)i)); + } + initem = 1; + nentries++; + break; + case VRFY_ITEM_END: + /* + * We've hit the end of an item even though + * we don't think we're in one; must + * be an overlap. + */ + isbad = 1; + EPRINT((env, + "Page %lu: overlapping items at offset %lu", + (u_long)pgno, (u_long)i)); + break; + } + else + switch (pagelayout[i]) { + case VRFY_ITEM_NOTSET: + /* In the middle of an item somewhere. Okay. */ + break; + case VRFY_ITEM_END: + /* End of an item; switch to out-of-item mode.*/ + initem = 0; + break; + case VRFY_ITEM_BEGIN: + /* + * Hit a second item beginning without an + * end. Overlap. + */ + isbad = 1; + EPRINT((env, + "Page %lu: overlapping items at offset %lu", + (u_long)pgno, (u_long)i)); + break; + } + + __os_free(env, pagelayout); + + /* Verify HOFFSET. */ + if ((db_indx_t)himark != HOFFSET(h)) { + EPRINT((env, "Page %lu: bad HOFFSET %lu, appears to be %lu", + (u_long)pgno, (u_long)HOFFSET(h), (u_long)himark)); + isbad = 1; + } + +err: if (nentriesp != NULL) + *nentriesp = nentries; + + if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + + return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret); +} + +/* + * __bam_vrfy_itemorder -- + * Make sure the items on a page sort correctly. + * + * Assumes that NUM_ENT(h) and inp[0]..inp[NUM_ENT(h) - 1] are + * reasonable; be sure that __bam_vrfy_inp has been called first. + * + * If ovflok is set, it also assumes that overflow page chains + * hanging off the current page have been sanity-checked, and so we + * can use __bam_cmp to verify their ordering. If it is not set, + * and we run into an overflow page, carp and return DB_VERIFY_BAD; + * we shouldn't be called if any exist. + * + * PUBLIC: int __bam_vrfy_itemorder __P((DB *, VRFY_DBINFO *, DB_THREAD_INFO *, + * PUBLIC: PAGE *, db_pgno_t, u_int32_t, int, int, u_int32_t)); + */ +int +__bam_vrfy_itemorder(dbp, vdp, ip, h, pgno, nentries, ovflok, hasdups, flags) + DB *dbp; + VRFY_DBINFO *vdp; + DB_THREAD_INFO *ip; + PAGE *h; + db_pgno_t pgno; + u_int32_t nentries; + int ovflok, hasdups; + u_int32_t flags; +{ + BINTERNAL *bi; + BKEYDATA *bk; + BOVERFLOW *bo; + BTREE *bt; + DBC *dbc; + DBT dbta, dbtb, dup_1, dup_2, *p1, *p2, *tmp; + ENV *env; + VRFY_PAGEINFO *pip; + db_indx_t i, *inp; + int adj, cmp, freedup_1, freedup_2, isbad, ret, t_ret; + int (*dupfunc) __P((DB *, const DBT *, const DBT *)); + int (*func) __P((DB *, const DBT *, const DBT *)); + void *buf1, *buf2, *tmpbuf; + + /* + * We need to work in the ORDERCHKONLY environment where we might + * not have a pip, but we also may need to work in contexts where + * NUM_ENT isn't safe. + */ + if (vdp != NULL) { + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + nentries = pip->entries; + } else + pip = NULL; + + env = dbp->env; + ret = isbad = 0; + bo = NULL; /* Shut up compiler. */ + + memset(&dbta, 0, sizeof(DBT)); + F_SET(&dbta, DB_DBT_REALLOC); + + memset(&dbtb, 0, sizeof(DBT)); + F_SET(&dbtb, DB_DBT_REALLOC); + + buf1 = buf2 = NULL; + + DB_ASSERT(env, !LF_ISSET(DB_NOORDERCHK)); + + dupfunc = (dbp->dup_compare == NULL) ? __bam_defcmp : dbp->dup_compare; + if (TYPE(h) == P_LDUP) + func = dupfunc; + else { + func = __bam_defcmp; + if (dbp->bt_internal != NULL) { + bt = (BTREE *)dbp->bt_internal; + if (bt->bt_compare != NULL) + func = bt->bt_compare; + } + } + + /* + * We alternate our use of dbta and dbtb so that we can walk + * through the page key-by-key without copying a dbt twice. + * p1 is always the dbt for index i - 1, and p2 for index i. + * Reset the data pointers in case we are retrying. + */ +retry: p1 = &dbta; + p1->data = NULL; + p2 = &dbtb; + p2->data = NULL; + + /* + * Loop through the entries. nentries ought to contain the + * actual count, and so is a safe way to terminate the loop; whether + * we inc. by one or two depends on whether we're a leaf page-- + * on a leaf page, we care only about keys. On internal pages + * and LDUP pages, we want to check the order of all entries. + * + * Note that on IBTREE pages or the index page of a partitioned + * database, we start with item 1, since item 0 doesn't get looked + * at by __bam_cmp. + */ + inp = P_INP(dbp, h); + adj = (TYPE(h) == P_LBTREE) ? P_INDX : O_INDX; + for (i = (TYPE(h) == P_IBTREE || dbp->p_internal != NULL) ? adj : 0; + i < nentries; i += adj) { + /* + * Put key i-1, now in p2, into p1, by swapping DBTs and bufs. + */ + tmp = p1; + p1 = p2; + p2 = tmp; + tmpbuf = buf1; + buf1 = buf2; + buf2 = tmpbuf; + + /* + * Get key i into p2. + */ + switch (TYPE(h)) { + case P_IBTREE: + bi = GET_BINTERNAL(dbp, h, i); + if (B_TYPE(bi->type) == B_OVERFLOW) { + bo = (BOVERFLOW *)(bi->data); + goto overflow; + } else { + p2->data = bi->data; + p2->size = bi->len; + } + + /* + * The leftmost key on an internal page must be + * len 0, since it's just a placeholder and + * automatically sorts less than all keys. + * + * XXX + * This criterion does not currently hold! + * See todo list item #1686. Meanwhile, it's harmless + * to just not check for it. + */ +#if 0 + if (i == 0 && bi->len != 0) { + isbad = 1; + EPRINT((env, + "Page %lu: lowest key on internal page of nonzero length", + (u_long)pgno)); + } +#endif + break; + case P_LBTREE: + case P_LDUP: + bk = GET_BKEYDATA(dbp, h, i); + if (B_TYPE(bk->type) == B_OVERFLOW) { + bo = (BOVERFLOW *)bk; + goto overflow; + } else { + p2->data = bk->data; + p2->size = bk->len; + } + break; + default: + /* + * This means our caller screwed up and sent us + * an inappropriate page. + */ + ret = __db_unknown_path(env, "__bam_vrfy_itemorder"); + goto err; + } + + if (0) { + /* + * If ovflok != 1, we can't safely go chasing + * overflow pages with the normal routines now; + * they might be unsafe or nonexistent. Mark this + * page as incomplete and return. + * + * Note that we don't need to worry about freeing + * buffers, since they can't have been allocated + * if overflow items are unsafe. + */ +overflow: if (!ovflok) { + F_SET(pip, VRFY_INCOMPLETE); + goto err; + } + + /* + * Overflow items are safe to chase. Do so. + * Fetch the overflow item into p2->data, + * NULLing it or reallocing it as appropriate. + * + * (We set p2->data to buf2 before the call + * so we're sure to realloc if we can and if p2 + * was just pointing at a non-overflow item.) + */ + p2->data = buf2; + if ((ret = __db_cursor_int(dbp, ip, NULL, DB_BTREE, + PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0) + goto err; + if ((ret = __db_goff(dbc, + p2, bo->tlen, bo->pgno, NULL, NULL)) != 0) { + isbad = 1; + EPRINT((env, + "Page %lu: error %lu in fetching overflow item %lu", + (u_long)pgno, (u_long)ret, (u_long)i)); + } + /* In case it got realloc'ed and thus changed. */ + buf2 = p2->data; + } + + /* Compare with the last key. */ + if (p1->data != NULL && p2->data != NULL) { + cmp = inp[i] == inp[i - adj] ? 0 : func(dbp, p1, p2); + + /* comparison succeeded */ + if (cmp > 0) { + /* + * If we are looking at an internal page, we + * don't know whether it is part of the main + * database or in an off-page-duplicate tree. + * If the main comparator fails, retry with + * the duplicate comparator. + */ + if (TYPE(h) == P_IBTREE && func != dupfunc) { + func = dupfunc; + goto retry; + } + + isbad = 1; + EPRINT((env, + "Page %lu: out-of-order key at entry %lu", + (u_long)pgno, (u_long)i)); + /* proceed */ + } else if (cmp == 0) { + if (inp[i] != inp[i - adj]) { + /* See above. */ + if (TYPE(h) == P_IBTREE && + func != dupfunc) { + func = dupfunc; + goto retry; + } + isbad = 1; + EPRINT((env, + "Page %lu: non-dup dup key at entry %lu", + (u_long)pgno, (u_long)i)); + } + /* + * If they compared equally, this + * had better be a (sub)database with dups. + * Mark it so we can check during the + * structure check. + */ + if (pip != NULL) + F_SET(pip, VRFY_HAS_DUPS); + else if (hasdups == 0) { + /* See above. */ + if (TYPE(h) == P_IBTREE && + func != dupfunc) { + func = dupfunc; + goto retry; + } + isbad = 1; + EPRINT((env, + "Page %lu: database with no duplicates has duplicated keys", + (u_long)pgno)); + } + + /* + * If we're a btree leaf, check to see + * if the data items of these on-page dups are + * in sorted order. If not, flag this, so + * that we can make sure during the + * structure checks that the DUPSORT flag + * is unset. + * + * At this point i points to a duplicate key. + * Compare the datum before it (same key) + * to the datum after it, i.e. i-1 to i+1. + */ + if (TYPE(h) == P_LBTREE) { + /* + * Unsafe; continue and we'll pick + * up the bogus nentries later. + */ + if (i + 1 >= (db_indx_t)nentries) + continue; + + /* + * We don't bother with clever memory + * management with on-page dups, + * as it's only really a big win + * in the overflow case, and overflow + * dups are probably (?) rare. + */ + if (((ret = __bam_safe_getdata(dbp, + ip, h, i - 1, ovflok, + &dup_1, &freedup_1)) != 0) || + ((ret = __bam_safe_getdata(dbp, + ip, h, i + 1, ovflok, + &dup_2, &freedup_2)) != 0)) + goto err; + + /* + * If either of the data are NULL, + * it's because they're overflows and + * it's not safe to chase them now. + * Mark an incomplete and return. + */ + if (dup_1.data == NULL || + dup_2.data == NULL) { + DB_ASSERT(env, !ovflok); + F_SET(pip, VRFY_INCOMPLETE); + goto err; + } + + /* + * If the dups are out of order, + * flag this. It's not an error + * until we do the structure check + * and see whether DUPSORT is set. + */ + if (dupfunc(dbp, &dup_1, &dup_2) > 0) + F_SET(pip, VRFY_DUPS_UNSORTED); + + if (freedup_1) + __os_ufree(env, dup_1.data); + if (freedup_2) + __os_ufree(env, dup_2.data); + } + } + } + } + +err: if (pip != NULL && ((t_ret = + __db_vrfy_putpageinfo(env, vdp, pip)) != 0) && ret == 0) + ret = t_ret; + + if (buf1 != NULL) + __os_ufree(env, buf1); + if (buf2 != NULL) + __os_ufree(env, buf2); + + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); +} + +/* + * __bam_vrfy_structure -- + * Verify the tree structure of a btree database (including the master + * database containing subdbs). + * + * PUBLIC: int __bam_vrfy_structure __P((DB *, VRFY_DBINFO *, db_pgno_t, + * PUBLIC: void *, void *, u_int32_t)); + */ +int +__bam_vrfy_structure(dbp, vdp, meta_pgno, lp, rp, flags) + DB *dbp; + VRFY_DBINFO *vdp; + db_pgno_t meta_pgno; + void *lp, *rp; + u_int32_t flags; +{ + DB *pgset; + ENV *env; + VRFY_PAGEINFO *mip, *rip; + db_pgno_t root, p; + int t_ret, ret; + u_int32_t nrecs, level, relen, stflags; + + env = dbp->env; + mip = rip = 0; + pgset = vdp->pgset; + + if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &mip)) != 0) + return (ret); + + if ((ret = __db_vrfy_pgset_get(pgset, + vdp->thread_info, meta_pgno, (int *)&p)) != 0) + goto err; + if (p != 0) { + EPRINT((env, + "Page %lu: btree metadata page observed twice", + (u_long)meta_pgno)); + ret = DB_VERIFY_BAD; + goto err; + } + if ((ret = + __db_vrfy_pgset_inc(pgset, vdp->thread_info, meta_pgno)) != 0) + goto err; + + root = mip->root; + + if (root == 0) { + EPRINT((env, + "Page %lu: btree metadata page has no root", + (u_long)meta_pgno)); + ret = DB_VERIFY_BAD; + goto err; + } + + if ((ret = __db_vrfy_getpageinfo(vdp, root, &rip)) != 0) + goto err; + + switch (rip->type) { + case P_IBTREE: + case P_LBTREE: + stflags = flags | DB_ST_TOPLEVEL; + if (F_ISSET(mip, VRFY_HAS_DUPS)) + stflags |= DB_ST_DUPOK; + if (F_ISSET(mip, VRFY_HAS_DUPSORT)) + stflags |= DB_ST_DUPSORT; + if (F_ISSET(mip, VRFY_HAS_RECNUMS)) + stflags |= DB_ST_RECNUM; + ret = __bam_vrfy_subtree(dbp, + vdp, root, lp, rp, stflags, NULL, NULL, NULL); + break; + case P_IRECNO: + case P_LRECNO: + stflags = + flags | DB_ST_RECNUM | DB_ST_IS_RECNO | DB_ST_TOPLEVEL; + if (mip->re_len > 0) + stflags |= DB_ST_RELEN; + if ((ret = __bam_vrfy_subtree(dbp, vdp, + root, NULL, NULL, stflags, &level, &nrecs, &relen)) != 0) + goto err; + /* + * Even if mip->re_len > 0, re_len may come back zero if the + * tree is empty. It should be okay to just skip the check in + * this case, as if there are any non-deleted keys at all, + * that should never happen. + */ + if (mip->re_len > 0 && relen > 0 && mip->re_len != relen) { + EPRINT((env, + "Page %lu: recno database has bad re_len %lu", + (u_long)meta_pgno, (u_long)relen)); + ret = DB_VERIFY_BAD; + goto err; + } + ret = 0; + break; + case P_LDUP: + EPRINT((env, + "Page %lu: duplicate tree referenced from metadata page", + (u_long)meta_pgno)); + ret = DB_VERIFY_BAD; + break; + default: + EPRINT((env, + "Page %lu: btree root of incorrect type %lu on metadata page", + (u_long)meta_pgno, (u_long)rip->type)); + ret = DB_VERIFY_BAD; + break; + } + +err: if (mip != NULL && ((t_ret = + __db_vrfy_putpageinfo(env, vdp, mip)) != 0) && ret == 0) + ret = t_ret; + if (rip != NULL && ((t_ret = + __db_vrfy_putpageinfo(env, vdp, rip)) != 0) && ret == 0) + ret = t_ret; + return (ret); +} + +/* + * __bam_vrfy_subtree-- + * Verify a subtree (or entire) btree with specified root. + * + * Note that this is public because it must be called to verify + * offpage dup trees, including from hash. + * + * PUBLIC: int __bam_vrfy_subtree __P((DB *, VRFY_DBINFO *, db_pgno_t, void *, + * PUBLIC: void *, u_int32_t, u_int32_t *, u_int32_t *, u_int32_t *)); + */ +int +__bam_vrfy_subtree(dbp, vdp, pgno, l, r, flags, levelp, nrecsp, relenp) + DB *dbp; + VRFY_DBINFO *vdp; + db_pgno_t pgno; + void *l, *r; + u_int32_t flags, *levelp, *nrecsp, *relenp; +{ + BINTERNAL *li, *ri; + DB *pgset; + DBC *cc; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *h; + VRFY_CHILDINFO *child; + VRFY_PAGEINFO *pip; + db_indx_t i; + db_pgno_t next_pgno, prev_pgno; + db_recno_t child_nrecs, nrecs; + u_int32_t child_level, child_relen, j, level, relen, stflags; + u_int8_t leaf_type; + int (*func) __P((DB *, const DBT *, const DBT *)); + int isbad, p, ret, t_ret, toplevel; + + if (levelp != NULL) /* Don't leave uninitialized on error. */ + *levelp = 0; + if (nrecsp != NULL) + *nrecsp = 0; + + env = dbp->env; + mpf = dbp->mpf; + h = NULL; + next_pgno = prev_pgno = PGNO_INVALID; + nrecs = 0; + relen = 0; + leaf_type = P_INVALID; + isbad = ret = 0; + + /* Provide feedback on our progress to the application. */ + if (!LF_ISSET(DB_SALVAGE)) + __db_vrfy_struct_feedback(dbp, vdp); + + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + + cc = NULL; + level = pip->bt_level; + + toplevel = LF_ISSET(DB_ST_TOPLEVEL) ? 1 : 0; + LF_CLR(DB_ST_TOPLEVEL); + + /* + * If this is the root, initialize the vdp's prev- and next-pgno + * accounting. + * + * For each leaf page we hit, we'll want to make sure that + * vdp->prev_pgno is the same as pip->prev_pgno and vdp->next_pgno is + * our page number. Then, we'll set vdp->next_pgno to pip->next_pgno + * and vdp->prev_pgno to our page number, and the next leaf page in + * line should be able to do the same verification. + */ + if (toplevel) { + /* + * Cache the values stored in the vdp so that if we're an + * auxiliary tree such as an off-page duplicate set, our + * caller's leaf page chain doesn't get lost. + */ + prev_pgno = vdp->prev_pgno; + next_pgno = vdp->next_pgno; + leaf_type = vdp->leaf_type; + vdp->next_pgno = vdp->prev_pgno = PGNO_INVALID; + vdp->leaf_type = P_INVALID; + } + + /* + * We are recursively descending a btree, starting from the root + * and working our way out to the leaves. + * + * There are four cases we need to deal with: + * 1. pgno is a recno leaf page. Any children are overflows. + * 2. pgno is a duplicate leaf page. Any children + * are overflow pages; traverse them, and then return + * level and nrecs. + * 3. pgno is an ordinary leaf page. Check whether dups are + * allowed, and if so, traverse any off-page dups or + * overflows. Then return nrecs and level. + * 4. pgno is a recno internal page. Recursively check any + * child pages, making sure their levels are one lower + * and their nrecs sum to ours. + * 5. pgno is a btree internal page. Same as #4, plus we + * must verify that for each pair of BINTERNAL entries + * N and N+1, the leftmost item on N's child sorts + * greater than N, and the rightmost item on N's child + * sorts less than N+1. + * + * Furthermore, in any sorted page type (P_LDUP, P_LBTREE, P_IBTREE), + * we need to verify the internal sort order is correct if, + * due to overflow items, we were not able to do so earlier. + */ + switch (pip->type) { + case P_LRECNO: + case P_LDUP: + case P_LBTREE: + /* + * Cases 1, 2 and 3. + * + * We're some sort of leaf page; verify + * that our linked list of leaves is consistent. + */ + if (vdp->leaf_type == P_INVALID) { + /* + * First leaf page. Set the type that all its + * successors should be, and verify that our prev_pgno + * is PGNO_INVALID. + */ + vdp->leaf_type = pip->type; + if (pip->prev_pgno != PGNO_INVALID) + goto bad_prev; + } else { + /* + * Successor leaf page. Check our type, the previous + * page's next_pgno, and our prev_pgno. + */ + if (pip->type != vdp->leaf_type) { + isbad = 1; + EPRINT((env, + "Page %lu: unexpected page type %lu found in leaf chain (expected %lu)", + (u_long)pip->pgno, (u_long)pip->type, + (u_long)vdp->leaf_type)); + } + + /* + * Don't do the prev/next_pgno checks if we've lost + * leaf pages due to another corruption. + */ + if (!F_ISSET(vdp, VRFY_LEAFCHAIN_BROKEN)) { + if (pip->pgno != vdp->next_pgno) { + isbad = 1; + EPRINT((env, + "Page %lu: incorrect next_pgno %lu found in leaf chain (should be %lu)", + (u_long)vdp->prev_pgno, + (u_long)vdp->next_pgno, + (u_long)pip->pgno)); + } + if (pip->prev_pgno != vdp->prev_pgno) { +bad_prev: isbad = 1; + EPRINT((env, + "Page %lu: incorrect prev_pgno %lu found in leaf chain (should be %lu)", + (u_long)pip->pgno, + (u_long)pip->prev_pgno, + (u_long)vdp->prev_pgno)); + } + } + } + vdp->prev_pgno = pip->pgno; + vdp->next_pgno = pip->next_pgno; + F_CLR(vdp, VRFY_LEAFCHAIN_BROKEN); + + /* + * Overflow pages are common to all three leaf types; + * traverse the child list, looking for overflows. + */ + if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0) + goto err; + for (ret = __db_vrfy_ccset(cc, pgno, &child); ret == 0; + ret = __db_vrfy_ccnext(cc, &child)) + if (child->type == V_OVERFLOW && + (ret = __db_vrfy_ovfl_structure(dbp, vdp, + child->pgno, child->tlen, + flags | DB_ST_OVFL_LEAF)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto done; + } + + if ((ret = __db_vrfy_ccclose(cc)) != 0) + goto err; + cc = NULL; + + /* Case 1 */ + if (pip->type == P_LRECNO) { + if (!LF_ISSET(DB_ST_IS_RECNO) && + !(LF_ISSET(DB_ST_DUPOK) && + !LF_ISSET(DB_ST_DUPSORT))) { + isbad = 1; + EPRINT((env, + "Page %lu: recno leaf page non-recno tree", + (u_long)pgno)); + goto done; + } + goto leaf; + } else if (LF_ISSET(DB_ST_IS_RECNO)) { + /* + * It's a non-recno leaf. Had better not be a recno + * subtree. + */ + isbad = 1; + EPRINT((env, + "Page %lu: non-recno leaf page in recno tree", + (u_long)pgno)); + goto done; + } + + /* Case 2--no more work. */ + if (pip->type == P_LDUP) + goto leaf; + + /* Case 3 */ + + /* Check if we have any dups. */ + if (F_ISSET(pip, VRFY_HAS_DUPS)) { + /* If dups aren't allowed in this btree, trouble. */ + if (!LF_ISSET(DB_ST_DUPOK)) { + isbad = 1; + EPRINT((env, + "Page %lu: duplicates in non-dup btree", + (u_long)pgno)); + } else { + /* + * We correctly have dups. If any are off-page, + * traverse those btrees recursively. + */ + if ((ret = + __db_vrfy_childcursor(vdp, &cc)) != 0) + goto err; + for (ret = __db_vrfy_ccset(cc, pgno, &child); + ret == 0; + ret = __db_vrfy_ccnext(cc, &child)) { + stflags = + flags | DB_ST_RECNUM | DB_ST_DUPSET; + /* Skip any overflow entries. */ + if (child->type == V_DUPLICATE) { + if ((ret = __db_vrfy_duptype( + dbp, vdp, child->pgno, + stflags)) != 0) { + isbad = 1; + /* Next child. */ + continue; + } + if ((ret = __bam_vrfy_subtree( + dbp, vdp, child->pgno, + NULL, NULL, + stflags | DB_ST_TOPLEVEL, + NULL, NULL, NULL)) != 0) { + if (ret == + DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + } + } + + if ((ret = __db_vrfy_ccclose(cc)) != 0) + goto err; + cc = NULL; + + /* + * If VRFY_DUPS_UNSORTED is set, + * DB_ST_DUPSORT had better not be. + */ + if (F_ISSET(pip, VRFY_DUPS_UNSORTED) && + LF_ISSET(DB_ST_DUPSORT)) { + isbad = 1; + EPRINT((env, + "Page %lu: unsorted duplicate set in sorted-dup database", + (u_long)pgno)); + } + } + } + goto leaf; + case P_IBTREE: + case P_IRECNO: + /* We handle these below. */ + break; + default: + /* + * If a P_IBTREE or P_IRECNO contains a reference to an + * invalid page, we'll wind up here; handle it gracefully. + * Note that the code at the "done" label assumes that the + * current page is a btree/recno one of some sort; this + * is not the case here, so we goto err. + * + * If the page is entirely zeroed, its pip->type will be a lie + * (we assumed it was a hash page, as they're allowed to be + * zeroed); handle this case specially. + */ + if (F_ISSET(pip, VRFY_IS_ALLZEROES)) + ZEROPG_ERR_PRINT(env, pgno, "btree or recno page"); + else + EPRINT((env, + "Page %lu: btree or recno page is of inappropriate type %lu", + (u_long)pgno, (u_long)pip->type)); + + /* + * We probably lost a leaf page (or more if this was an + * internal page) from our prev/next_pgno chain. Flag + * that this is expected; we don't want or need to + * spew error messages about erroneous prev/next_pgnos, + * since that's probably not the real problem. + */ + F_SET(vdp, VRFY_LEAFCHAIN_BROKEN); + + ret = DB_VERIFY_BAD; + goto err; + } + + /* + * Cases 4 & 5: This is a btree or recno internal page. For each child, + * recurse, keeping a running count of nrecs and making sure the level + * is always reasonable. + */ + if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0) + goto err; + for (ret = __db_vrfy_ccset(cc, pgno, &child); ret == 0; + ret = __db_vrfy_ccnext(cc, &child)) + if (child->type == V_RECNO) { + if (pip->type != P_IRECNO) { + ret = __db_unknown_path( + env, "__bam_vrfy_subtree"); + goto err; + } + if ((ret = __bam_vrfy_subtree(dbp, vdp, child->pgno, + NULL, NULL, flags, &child_level, &child_nrecs, + &child_relen)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto done; + } + + if (LF_ISSET(DB_ST_RELEN)) { + if (relen == 0) + relen = child_relen; + /* + * child_relen may be zero if the child subtree + * is empty. + */ + else if (child_relen > 0 && + relen != child_relen) { + isbad = 1; + EPRINT((env, + "Page %lu: recno page returned bad re_len %lu", + (u_long)child->pgno, + (u_long)child_relen)); + } + if (relenp) + *relenp = relen; + } + if (LF_ISSET(DB_ST_RECNUM)) { + if (child->nrecs != child_nrecs) { + isbad = 1; + EPRINT((env, + "Page %lu: record count incorrect: actual %lu, in record %lu", + (u_long)child->pgno, + (u_long)child_nrecs, + (u_long)child->nrecs)); + } + nrecs += child_nrecs; + } + if (isbad == 0 && level != child_level + 1) { + isbad = 1; + EPRINT((env, + "Page %lu: recno level incorrect: got %lu, expected %lu", + (u_long)child->pgno, (u_long)child_level, + (u_long)(level - 1))); + } + } else if (child->type == V_OVERFLOW) { + /* + * It is possible for one internal page to reference + * a single overflow page twice, if all the items + * in the subtree referenced by slot 0 are deleted, + * then a similar number of items are put back + * before the key that formerly had been in slot 1. + * + * (Btree doesn't look at the key in slot 0, so the + * fact that the key formerly at slot 1 is the "wrong" + * parent of the stuff in the slot 0 subtree isn't + * really incorrect.) + * + * __db_vrfy_ovfl_structure is designed to be + * efficiently called multiple times for multiple + * references; call it here as many times as is + * appropriate. + */ + + /* Otherwise, __db_vrfy_childput would be broken. */ + DB_ASSERT(env, child->refcnt >= 1); + + /* + * An overflow referenced more than twice here + * shouldn't happen. + */ + if (child->refcnt > 2) { + isbad = 1; + EPRINT((env, + "Page %lu: overflow page %lu referenced more than twice from internal page", + (u_long)pgno, (u_long)child->pgno)); + } else + for (j = 0; j < child->refcnt; j++) + if ((ret = __db_vrfy_ovfl_structure(dbp, + vdp, child->pgno, child->tlen, + flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto done; + } + } + + if ((ret = __db_vrfy_ccclose(cc)) != 0) + goto err; + cc = NULL; + + /* We're done with case 4. */ + if (pip->type == P_IRECNO) + goto done; + + /* + * Case 5. Btree internal pages. + * As described above, we need to iterate through all the + * items on the page and make sure that our children sort appropriately + * with respect to them. + * + * For each entry, li will be the "left-hand" key for the entry + * itself, which must sort lower than all entries on its child; + * ri will be the key to its right, which must sort greater. + */ + if (h == NULL && + (ret = __memp_fget(mpf, &pgno, vdp->thread_info, NULL, 0, &h)) != 0) + goto err; + for (i = 0; i < pip->entries; i += O_INDX) { + li = GET_BINTERNAL(dbp, h, i); + ri = (i + O_INDX < pip->entries) ? + GET_BINTERNAL(dbp, h, i + O_INDX) : r; + + /* + * The leftmost key is forcibly sorted less than all entries, + * so don't bother passing it. + */ + if ((ret = __bam_vrfy_subtree(dbp, vdp, li->pgno, + i == 0 ? NULL : li, ri, flags, &child_level, + &child_nrecs, NULL)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto done; + } + + if (LF_ISSET(DB_ST_RECNUM)) { + /* + * Keep a running tally on the actual record count so + * we can return it to our parent (if we have one) or + * compare it to the NRECS field if we're a root page. + */ + nrecs += child_nrecs; + + /* + * Make sure the actual record count of the child + * is equal to the value in the BINTERNAL structure. + */ + if (li->nrecs != child_nrecs) { + isbad = 1; + EPRINT((env, + "Page %lu: item %lu has incorrect record count of %lu, should be %lu", + (u_long)pgno, (u_long)i, (u_long)li->nrecs, + (u_long)child_nrecs)); + } + } + + if (level != child_level + 1) { + isbad = 1; + EPRINT((env, + "Page %lu: Btree level incorrect: got %lu, expected %lu", + (u_long)li->pgno, + (u_long)child_level, (u_long)(level - 1))); + } + } + + if (0) { +leaf: level = LEAFLEVEL; + if (LF_ISSET(DB_ST_RECNUM)) + nrecs = pip->rec_cnt; + + /* XXX + * We should verify that the record count on a leaf page + * is the sum of the number of keys and the number of + * records in its off-page dups. This requires looking + * at the page again, however, and it may all be changing + * soon, so for now we don't bother. + */ + + if (LF_ISSET(DB_ST_RELEN) && relenp) + *relenp = pip->re_len; + } +done: if (F_ISSET(pip, VRFY_INCOMPLETE) && isbad == 0 && ret == 0) { + /* + * During the page-by-page pass, item order verification was + * not finished due to the presence of overflow items. If + * isbad == 0, though, it's now safe to do so, as we've + * traversed any child overflow pages. Do it. + */ + if (h == NULL && (ret = __memp_fget(mpf, &pgno, + vdp->thread_info, NULL, 0, &h)) != 0) + goto err; + if ((ret = __bam_vrfy_itemorder(dbp, + vdp, vdp->thread_info, h, pgno, 0, 1, 0, flags)) != 0) + goto err; + F_CLR(pip, VRFY_INCOMPLETE); + } + + /* + * It's possible to get to this point with a page that has no + * items, but without having detected any sort of failure yet. + * Having zero items is legal if it's a leaf--it may be the + * root page in an empty tree, or the tree may have been + * modified with the DB_REVSPLITOFF flag set (there's no way + * to tell from what's on disk). For an internal page, + * though, having no items is a problem (all internal pages + * must have children). + */ + if (isbad == 0 && ret == 0) { + if (h == NULL && (ret = __memp_fget(mpf, &pgno, + vdp->thread_info, NULL, 0, &h)) != 0) + goto err; + + if (NUM_ENT(h) == 0 && ISINTERNAL(h)) { + isbad = 1; + EPRINT((env, + "Page %lu: internal page is empty and should not be", + (u_long)pgno)); + goto err; + } + } + + /* + * Our parent has sent us BINTERNAL pointers to parent records + * so that we can verify our place with respect to them. If it's + * appropriate--we have a default sort function--verify this. + */ + if (isbad == 0 && ret == 0 && !LF_ISSET(DB_NOORDERCHK) && + pip->type != P_IRECNO && pip->type != P_LRECNO) { + if (h == NULL && (ret = __memp_fget(mpf, &pgno, + vdp->thread_info, NULL, 0, &h)) != 0) + goto err; + + /* + * __bam_vrfy_treeorder needs to know what comparison function + * to use. If DB_ST_DUPSET is set, we're in a duplicate tree + * and we use the duplicate comparison function; otherwise, + * use the btree one. If unset, use the default, of course. + */ + func = LF_ISSET(DB_ST_DUPSET) ? dbp->dup_compare : + ((BTREE *)dbp->bt_internal)->bt_compare; + if (func == NULL) + func = __bam_defcmp; + + if ((ret = __bam_vrfy_treeorder(dbp, + vdp->thread_info, h, l, r, func, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + } + + /* + * This is guaranteed to succeed for leaf pages, but no harm done. + * + * Internal pages below the top level do not store their own + * record numbers, so we skip them. + */ + if (LF_ISSET(DB_ST_RECNUM) && nrecs != pip->rec_cnt && toplevel) { + isbad = 1; + EPRINT((env, + "Page %lu: bad record count: has %lu records, claims %lu", + (u_long)pgno, (u_long)nrecs, (u_long)pip->rec_cnt)); + } + + if (levelp) + *levelp = level; + if (nrecsp) + *nrecsp = nrecs; + + pgset = vdp->pgset; + if ((ret = __db_vrfy_pgset_get(pgset, + vdp->thread_info, pgno, &p)) != 0) + goto err; + if (p != 0) { + isbad = 1; + EPRINT((env, "Page %lu: linked twice", (u_long)pgno)); + } else if ((ret = + __db_vrfy_pgset_inc(pgset, vdp->thread_info, pgno)) != 0) + goto err; + + if (toplevel) + /* + * The last page's next_pgno in the leaf chain should have been + * PGNO_INVALID. + */ + if (vdp->next_pgno != PGNO_INVALID) { + isbad = 1; + EPRINT((env, "Page %lu: unterminated leaf chain", + (u_long)vdp->prev_pgno)); + } + +err: if (toplevel) { + /* Restore our caller's settings. */ + vdp->next_pgno = next_pgno; + vdp->prev_pgno = prev_pgno; + vdp->leaf_type = leaf_type; + } + + if (h != NULL && (t_ret = __memp_fput(mpf, + vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + if (cc != NULL && ((t_ret = __db_vrfy_ccclose(cc)) != 0) && ret == 0) + ret = t_ret; + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); +} + +/* + * __bam_vrfy_treeorder -- + * Verify that the lowest key on a page sorts greater than the + * BINTERNAL which points to it (lp), and the highest key + * sorts less than the BINTERNAL above that (rp). + * + * If lp is NULL, this means that it was the leftmost key on the + * parent, which (regardless of sort function) sorts less than + * all keys. No need to check it. + * + * If rp is NULL, lp was the highest key on the parent, so there's + * no higher key we must sort less than. + */ +static int +__bam_vrfy_treeorder(dbp, ip, h, lp, rp, func, flags) + DB *dbp; + DB_THREAD_INFO *ip; + PAGE *h; + BINTERNAL *lp, *rp; + int (*func) __P((DB *, const DBT *, const DBT *)); + u_int32_t flags; +{ + BOVERFLOW *bo; + DBC *dbc; + DBT dbt; + ENV *env; + db_indx_t last; + int ret, cmp; + + env = dbp->env; + memset(&dbt, 0, sizeof(DBT)); + F_SET(&dbt, DB_DBT_MALLOC); + ret = 0; + + /* + * Empty pages are sorted correctly by definition. We check + * to see whether they ought to be empty elsewhere; leaf + * pages legally may be. + */ + if (NUM_ENT(h) == 0) + return (0); + + switch (TYPE(h)) { + case P_IBTREE: + case P_LDUP: + last = NUM_ENT(h) - O_INDX; + break; + case P_LBTREE: + last = NUM_ENT(h) - P_INDX; + break; + default: + return (__db_unknown_path(env, "__bam_vrfy_treeorder")); + } + + /* Populate a dummy cursor. */ + if ((ret = __db_cursor_int(dbp, ip, NULL, DB_BTREE, + PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0) + return (ret); + /* + * The key on page h, the child page, is more likely to be + * an overflow page, so we pass its offset, rather than lp/rp's, + * into __bam_cmp. This will take advantage of __db_moff. + */ + + /* + * Skip first-item check if we're an internal page--the first + * entry on an internal page is treated specially by __bam_cmp, + * so what's on the page shouldn't matter. (Plus, since we're passing + * our page and item 0 as to __bam_cmp, we'll sort before our + * parent and falsely report a failure.) + */ + if (lp != NULL && TYPE(h) != P_IBTREE) { + if ((ret = __db_cursor_int(dbp, ip, NULL, DB_BTREE, + PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0) + return (ret); + if (lp->type == B_KEYDATA) { + dbt.data = lp->data; + dbt.size = lp->len; + } else if (lp->type == B_OVERFLOW) { + bo = (BOVERFLOW *)lp->data; + if ((ret = __db_goff(dbc, &dbt, + bo->tlen, bo->pgno, NULL, NULL)) != 0) + return (ret); + } else + return ( + __db_unknown_path(env, "__bam_vrfy_treeorder")); + + /* On error, fall through, free if needed, and return. */ + if ((ret = __bam_cmp(dbc, &dbt, h, 0, func, &cmp)) == 0) { + if (cmp > 0) { + EPRINT((env, + "Page %lu: first item on page sorted greater than parent entry", + (u_long)PGNO(h))); + ret = DB_VERIFY_BAD; + } + } else + EPRINT((env, + "Page %lu: first item on page had comparison error", + (u_long)PGNO(h))); + + if (dbt.data != lp->data) + __os_ufree(env, dbt.data); + if (ret != 0) + return (ret); + } + + if (rp != NULL) { + if (rp->type == B_KEYDATA) { + dbt.data = rp->data; + dbt.size = rp->len; + } else if (rp->type == B_OVERFLOW) { + bo = (BOVERFLOW *)rp->data; + if ((ret = __db_goff(dbc, &dbt, + bo->tlen, bo->pgno, NULL, NULL)) != 0) + return (ret); + } else + return ( + __db_unknown_path(env, "__bam_vrfy_treeorder")); + + /* On error, fall through, free if needed, and return. */ + if ((ret = __bam_cmp(dbc, &dbt, h, last, func, &cmp)) == 0) { + if (cmp < 0) { + EPRINT((env, + "Page %lu: last item on page sorted greater than parent entry", + (u_long)PGNO(h))); + ret = DB_VERIFY_BAD; + } + } else + EPRINT((env, + "Page %lu: last item on page had comparison error", + (u_long)PGNO(h))); + + if (dbt.data != rp->data) + __os_ufree(env, dbt.data); + } + + return (ret); +} + +/* + * __bam_salvage -- + * Safely dump out anything that looks like a key on an alleged + * btree leaf page, also mark overflow pages as seen. For internal btree + * pages, just mark any overflow pages as seen. + * + * PUBLIC: int __bam_salvage __P((DB *, VRFY_DBINFO *, + * PUBLIC: db_pgno_t, u_int32_t, PAGE *, void *, + * PUBLIC: int (*)(void *, const void *), DBT *, u_int32_t)); + */ +int +__bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags) + DB *dbp; + VRFY_DBINFO *vdp; + db_pgno_t pgno; + u_int32_t pgtype; + PAGE *h; + void *handle; + int (*callback) __P((void *, const void *)); + DBT *key; + u_int32_t flags; +{ + BKEYDATA *bk; + BOVERFLOW *bo; + DBT dbt, repldbt, unknown_key, unknown_data; + ENV *env; + VRFY_ITEM *pgmap; + db_indx_t i, last, beg, end, *inp; + db_pgno_t ovflpg; + u_int32_t himark, ovfl_bufsz; + void *ovflbuf; + int adj, ret, t_ret, t2_ret; +#ifdef HAVE_COMPRESSION + DBT kcpy, *last_key; + int unknown_dup_key; +#endif + + env = dbp->env; + ovflbuf = pgmap = NULL; + inp = P_INP(dbp, h); + + memset(&dbt, 0, sizeof(DBT)); + dbt.flags = DB_DBT_REALLOC; + memset(&repldbt, 0, sizeof(DBT)); + +#ifdef HAVE_COMPRESSION + memset(&kcpy, 0, sizeof(DBT)); + unknown_dup_key = LF_ISSET(DB_SA_UNKNOWNKEY); + last_key = unknown_dup_key ? NULL : key; +#endif + LF_CLR(DB_SA_UNKNOWNKEY); + + DB_INIT_DBT(unknown_key, "UNKNOWN_KEY", sizeof("UNKNOWN_KEY") - 1); + DB_INIT_DBT(unknown_data, "UNKNOWN_DATA", sizeof("UNKNOWN_DATA") - 1); + + /* + * Allocate a buffer for overflow items. Start at one page; + * __db_safe_goff will realloc as needed. + */ + if ((ret = __os_malloc(env, dbp->pgsize, &ovflbuf)) != 0) + goto err; + ovfl_bufsz = dbp->pgsize; + + if (LF_ISSET(DB_AGGRESSIVE) && (ret = + __os_calloc(env, dbp->pgsize, sizeof(pgmap[0]), &pgmap)) != 0) + goto err; + + /* + * Loop through the inp array, spitting out key/data pairs. + * + * If we're salvaging normally, loop from 0 through NUM_ENT(h). If + * we're being aggressive, loop until we hit the end of the page -- + * NUM_ENT() may be bogus. + */ + himark = dbp->pgsize; + for (i = 0, last = UINT16_MAX;; i += O_INDX) { + /* + * If we're not aggressive, or if we're on an internal page, + * break when we hit NUM_ENT(h). + */ + if ((!LF_ISSET(DB_AGGRESSIVE) || + pgtype == P_IBTREE) && i >= NUM_ENT(h)) + break; + + /* Verify the current item. */ + t_ret = + __db_vrfy_inpitem(dbp, h, pgno, i, 1, flags, &himark, NULL); + + if (t_ret != 0) { + /* + * If this is a btree leaf and we've printed out a key + * but not its associated data item, fix this imbalance + * by printing an "UNKNOWN_DATA". + */ + if (pgtype == P_LBTREE && i % P_INDX == 1 && + last == i - 1 && (t2_ret = __db_vrfy_prdbt( + &unknown_data, + 0, " ", handle, callback, 0, vdp)) != 0) { + if (ret == 0) + ret = t2_ret; + goto err; + } + + /* + * Don't return DB_VERIFY_FATAL; it's private and means + * only that we can't go on with this page, not with + * the whole database. It's not even an error if we've + * run into it after NUM_ENT(h). + */ + if (t_ret == DB_VERIFY_FATAL) { + if (i < NUM_ENT(h) && ret == 0) + ret = DB_VERIFY_BAD; + break; + } + continue; + } + + /* + * If this returned 0, it's safe to print or (carefully) + * try to fetch. + * + * We only print deleted items if DB_AGGRESSIVE is set. + */ + bk = GET_BKEYDATA(dbp, h, i); + if (!LF_ISSET(DB_AGGRESSIVE) && B_DISSET(bk->type)) + continue; + + /* + * If this is a btree leaf and we're about to print out a data + * item for which we didn't print out a key, fix this imbalance + * by printing an "UNKNOWN_KEY". + */ + if (pgtype == P_LBTREE && i % P_INDX == 1 && last != i - 1) { +#ifdef HAVE_COMPRESSION + last_key = NULL; +#endif + if ((t_ret = __db_vrfy_prdbt(&unknown_key, + 0, " ", handle, callback, 0, vdp)) != 0) { + if (ret == 0) + ret = t_ret; + goto err; + } + } + last = i; + + /* + * We're going to go try to print the next item. If key is + * non-NULL, we're a dup page, so we've got to print the key + * first, unless DB_SA_SKIPFIRSTKEY is set and we're on the + * first entry. + */ + if (key != NULL && (i != 0 || !LF_ISSET(DB_SA_SKIPFIRSTKEY))) { +#ifdef HAVE_COMPRESSION + last_key = unknown_dup_key ? NULL : key; +#endif + if ((t_ret = __db_vrfy_prdbt(key, + 0, " ", handle, callback, 0, vdp)) != 0) { + if (ret == 0) + ret = t_ret; + goto err; + } + } + + beg = end = inp[i]; + switch (B_TYPE(bk->type)) { + case B_DUPLICATE: + if (pgtype == P_IBTREE) + break; + + end = beg + BOVERFLOW_SIZE - 1; + /* + * If we're not on a normal btree leaf page, there + * shouldn't be off-page dup sets. Something's + * confused; just drop it, and the code to pick up + * unlinked offpage dup sets will print it out + * with key "UNKNOWN" later. + */ + if (pgtype != P_LBTREE) + break; + + bo = (BOVERFLOW *)bk; + + /* + * If the page number is unreasonable, or if this is + * supposed to be a key item, output "UNKNOWN_KEY" -- + * the best we can do is run into the data items in + * the unlinked offpage dup pass. + */ + if (!IS_VALID_PGNO(bo->pgno) || (i % P_INDX == 0)) { + /* Not much to do on failure. */ +#ifdef HAVE_COMPRESSION + if (key == NULL && i % P_INDX == 0) + last_key = NULL; +#endif + if ((t_ret = __db_vrfy_prdbt( + i % P_INDX == 0 ? &unknown_key : &unknown_data, + 0, " ", handle, callback, 0, vdp)) != 0) { + if (ret == 0) + ret = t_ret; + goto err; + } + break; + } + + /* Don't stop on error. */ + if ((t_ret = __db_salvage_duptree(dbp, + vdp, bo->pgno, &dbt, handle, callback, + flags | DB_SA_SKIPFIRSTKEY +#ifdef HAVE_COMPRESSION + | (last_key == NULL ? DB_SA_UNKNOWNKEY : 0) +#endif + )) != 0 && ret == 0) + ret = t_ret; + + break; + case B_KEYDATA: + if (pgtype == P_IBTREE) + break; + + end = (db_indx_t)DB_ALIGN( + beg + bk->len, sizeof(u_int32_t)) - 1; + + dbt.data = bk->data; + dbt.size = bk->len; + +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp) && last_key != NULL && + (key != NULL || (i % P_INDX == 1))) { + /* Decompress the key/data pair - the key + is in last_key, and the data is in dbt */ + if ((t_ret = __bam_compress_salvage(dbp, vdp, + handle, callback, last_key, &dbt)) != 0) { + if (t_ret == DB_VERIFY_FATAL) { + if (ret == 0) + ret = DB_VERIFY_BAD; + if (!LF_ISSET(DB_AGGRESSIVE)) + goto err; + } else if (ret == 0) { + ret = t_ret; + goto err; + } + } + } else { + if (key == NULL && i % P_INDX == 0) { + if ((ret = __os_realloc( + env, dbt.size, &kcpy.data)) != 0) + goto err; + memcpy(kcpy.data, dbt.data, dbt.size); + kcpy.size = dbt.size; + last_key = &kcpy; + } +#endif + + if ((t_ret = __db_vrfy_prdbt(&dbt, + 0, " ", handle, callback, 0, vdp)) != 0) { + if (ret == 0) + ret = t_ret; + goto err; + } +#ifdef HAVE_COMPRESSION + } +#endif + break; + case B_OVERFLOW: + if (pgtype != P_IBTREE) + end = beg + BOVERFLOW_SIZE - 1; + bo = (BOVERFLOW *)bk; + + /* + * Check for replicated overflow keys, so that we only + * call __db_safe_goff once per overflow page. If we + * get the same offset as the previous key just re-use + * the previous dbt. + * + * P_IBTREE pages will never have replicated overflow + * keys. + */ + adj = pgtype == P_IBTREE ? O_INDX : P_INDX; + if (pgtype == P_IBTREE) { + /* + * If we're looking at a P_IBTREE, we just want + * to mark the overflow page as seen. + * + * Note that this call to __db_safe_goff differs + * from the non-P_IBTREE call. + * + * Only call __db_safe_goff if the overflow page + * hasn't been seen. + */ + ovflpg = ((BOVERFLOW *) + ((BINTERNAL *)bk)->data)->pgno; + if (__db_salvage_isdone(vdp, ovflpg) == 0 && + (t_ret =__db_safe_goff(dbp, vdp, ovflpg, + &dbt, &ovflbuf, + &ovfl_bufsz, flags)) != 0 && ret == 0) + ret = t_ret; + break; + } else if (i > adj - 1 && + i % adj == 0 && inp[i] == inp[i - adj]) + dbt = repldbt; + else { + /* Don't stop on error. */ + if ((t_ret = __db_safe_goff(dbp, vdp, + bo->pgno, &dbt, &ovflbuf, + &ovfl_bufsz, flags)) != 0 && ret == 0) + ret = t_ret; + + /* + * If this is a key, save it in case the next + * key is a replicated overflow, so we don't + * call __db_safe_goff again. Copy out dbt.data + * in case that pointer gets realloc'd when + * getting a data item. + */ + if (i % P_INDX == 0) { + if (t_ret == 0) { + if ((t_ret = __os_realloc(env, + dbt.size, + &repldbt.data)) != 0) { + if (ret == 0) + ret = t_ret; + goto err; + } + memcpy(repldbt.data, + dbt.data, dbt.size); + repldbt.size = dbt.size; + } else { + if (__os_realloc(env, + unknown_key.size, + &repldbt.data) != 0) + goto err; + memcpy(repldbt.data, + unknown_key.data, + unknown_key.size); + repldbt.size = unknown_key.size; + } + } + + } + +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp) && last_key && t_ret == 0 && + (key != NULL || (i % P_INDX == 1))) { + /* Decompress the key/data pair - the key + is in last_key, and the data is in dbt */ + if ((t_ret = __bam_compress_salvage(dbp, vdp, + handle, callback, last_key, &dbt)) != 0) { + if (t_ret == DB_VERIFY_FATAL) { + if (ret == 0) + ret = DB_VERIFY_BAD; + if (!LF_ISSET(DB_AGGRESSIVE)) + goto err; + } else if (ret == 0) { + ret = t_ret; + goto err; + } + } + } else { + if (key == NULL && i % P_INDX == 0) { + if (t_ret == 0) { + if ((ret = __os_realloc(env, + dbt.size, &kcpy.data)) != 0) + goto err; + memcpy(kcpy.data, dbt.data, + dbt.size); + kcpy.size = dbt.size; + last_key = &kcpy; + } else + last_key = NULL; + } +#endif + + if ((t_ret = __db_vrfy_prdbt( + t_ret == 0 ? &dbt : &unknown_key, + 0, " ", handle, callback, 0, vdp)) + != 0 && ret == 0) + ret = t_ret; +#ifdef HAVE_COMPRESSION + } +#endif + break; + default: + /* + * We should never get here; __db_vrfy_inpitem should + * not be returning 0 if bk->type is unrecognizable. + */ + t_ret = __db_unknown_path(env, "__bam_salvage"); + if (ret == 0) + ret = t_ret; + goto err; + } + + /* + * If we're being aggressive, mark the beginning and end of + * the item; we'll come back and print whatever "junk" is in + * the gaps in case we had any bogus inp elements and thereby + * missed stuff. + */ + if (LF_ISSET(DB_AGGRESSIVE) && pgtype != P_IBTREE) { + pgmap[beg] = VRFY_ITEM_BEGIN; + pgmap[end] = VRFY_ITEM_END; + } + } + +err: if (pgmap != NULL) + __os_free(env, pgmap); + if (ovflbuf != NULL) + __os_free(env, ovflbuf); + if (repldbt.data != NULL) + __os_free(env, repldbt.data); +#ifdef HAVE_COMPRESSION + if (kcpy.data != NULL) + __os_free(env, kcpy.data); +#endif + + /* Mark this page as done. */ + if ((t_ret = __db_salvage_markdone(vdp, pgno)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __bam_salvage_walkdupint -- + * Walk a known-good btree or recno internal page which is part of + * a dup tree, calling __db_salvage_duptree on each child page. + * + * PUBLIC: int __bam_salvage_walkdupint __P((DB *, VRFY_DBINFO *, PAGE *, + * PUBLIC: DBT *, void *, int (*)(void *, const void *), u_int32_t)); + */ +int +__bam_salvage_walkdupint(dbp, vdp, h, key, handle, callback, flags) + DB *dbp; + VRFY_DBINFO *vdp; + PAGE *h; + DBT *key; + void *handle; + int (*callback) __P((void *, const void *)); + u_int32_t flags; +{ + BINTERNAL *bi; + ENV *env; + RINTERNAL *ri; + int ret, t_ret; + db_indx_t i; + + env = dbp->env; + ret = 0; + + for (i = 0; i < NUM_ENT(h); i++) { + switch (TYPE(h)) { + case P_IBTREE: + bi = GET_BINTERNAL(dbp, h, i); + if ((t_ret = __db_salvage_duptree(dbp, + vdp, bi->pgno, key, handle, callback, flags)) != 0) + ret = t_ret; + break; + case P_IRECNO: + ri = GET_RINTERNAL(dbp, h, i); + if ((t_ret = __db_salvage_duptree(dbp, + vdp, ri->pgno, key, handle, callback, flags)) != 0) + ret = t_ret; + break; + default: + return (__db_unknown_path( + env, "__bam_salvage_walkdupint")); + } + /* Pass DB_SA_SKIPFIRSTKEY, if set, on to the 0th child only. */ + flags &= ~LF_ISSET(DB_SA_SKIPFIRSTKEY); + } + + return (ret); +} + +/* + * __bam_meta2pgset -- + * Given a known-good meta page, return in pgsetp a 0-terminated list of + * db_pgno_t's corresponding to the pages in the btree. + * + * We do this by a somewhat sleazy method, to avoid having to traverse the + * btree structure neatly: we walk down the left side to the very + * first leaf page, then we mark all the pages in the chain of + * NEXT_PGNOs (being wary of cycles and invalid ones), then we + * consolidate our scratch array into a nice list, and return. This + * avoids the memory management hassles of recursion and the + * trouble of walking internal pages--they just don't matter, except + * for the left branch. + * + * PUBLIC: int __bam_meta2pgset __P((DB *, VRFY_DBINFO *, BTMETA *, + * PUBLIC: u_int32_t, DB *)); + */ +int +__bam_meta2pgset(dbp, vdp, btmeta, flags, pgset) + DB *dbp; + VRFY_DBINFO *vdp; + BTMETA *btmeta; + u_int32_t flags; + DB *pgset; +{ + BINTERNAL *bi; + DB_MPOOLFILE *mpf; + PAGE *h; + RINTERNAL *ri; + db_pgno_t current, p; + int err_ret, ret; + + DB_ASSERT(dbp->env, pgset != NULL); + + mpf = dbp->mpf; + h = NULL; + ret = err_ret = 0; + + for (current = btmeta->root;;) { + if (!IS_VALID_PGNO(current) || current == PGNO(btmeta)) { + err_ret = DB_VERIFY_BAD; + goto err; + } + if ((ret = __memp_fget(mpf, ¤t, + vdp->thread_info, NULL, 0, &h)) != 0) { + err_ret = ret; + goto err; + } + + switch (TYPE(h)) { + case P_IBTREE: + case P_IRECNO: + if ((ret = __bam_vrfy(dbp, + vdp, h, current, flags | DB_NOORDERCHK)) != 0) { + err_ret = ret; + goto err; + } + if (TYPE(h) == P_IBTREE) { + bi = GET_BINTERNAL(dbp, h, 0); + current = bi->pgno; + } else { /* P_IRECNO */ + ri = GET_RINTERNAL(dbp, h, 0); + current = ri->pgno; + } + break; + case P_LBTREE: + case P_LRECNO: + goto traverse; + default: + err_ret = DB_VERIFY_BAD; + goto err; + } + + if ((ret = __memp_fput(mpf, + vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0) + err_ret = ret; + h = NULL; + } + + /* + * At this point, current is the pgno of leaf page h, the 0th in the + * tree we're concerned with. + */ +traverse: + while (IS_VALID_PGNO(current) && current != PGNO_INVALID) { + if (h == NULL && (ret = __memp_fget(mpf, + ¤t, vdp->thread_info, NULL, 0, &h)) != 0) { + err_ret = ret; + break; + } + + if ((ret = __db_vrfy_pgset_get(pgset, + vdp->thread_info, current, (int *)&p)) != 0) + goto err; + + if (p != 0) { + /* + * We've found a cycle. Return success anyway-- + * our caller may as well use however much of + * the pgset we've come up with. + */ + break; + } + if ((ret = + __db_vrfy_pgset_inc(pgset, vdp->thread_info, current)) != 0) + goto err; + + current = NEXT_PGNO(h); + if ((ret = __memp_fput(mpf, + vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0) + err_ret = ret; + h = NULL; + } + +err: if (h != NULL) + (void)__memp_fput(mpf, + vdp->thread_info, h, DB_PRIORITY_UNCHANGED); + + return (ret == 0 ? err_ret : ret); +} + +/* + * __bam_safe_getdata -- + * + * Utility function for __bam_vrfy_itemorder. Safely gets the datum at + * index i, page h, and sticks it in DBT dbt. If ovflok is 1 and i's an + * overflow item, we do a safe_goff to get the item and signal that we need + * to free dbt->data; if ovflok is 0, we leaves the DBT zeroed. + */ +static int +__bam_safe_getdata(dbp, ip, h, i, ovflok, dbt, freedbtp) + DB *dbp; + DB_THREAD_INFO *ip; + PAGE *h; + u_int32_t i; + int ovflok; + DBT *dbt; + int *freedbtp; +{ + BKEYDATA *bk; + BOVERFLOW *bo; + DBC *dbc; + int ret; + + memset(dbt, 0, sizeof(DBT)); + *freedbtp = 0; + + bk = GET_BKEYDATA(dbp, h, i); + if (B_TYPE(bk->type) == B_OVERFLOW) { + if (!ovflok) + return (0); + + if ((ret = __db_cursor_int(dbp, ip, NULL, DB_BTREE, + PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0) + return (ret); + bo = (BOVERFLOW *)bk; + F_SET(dbt, DB_DBT_MALLOC); + + *freedbtp = 1; + return (__db_goff(dbc, dbt, bo->tlen, bo->pgno, NULL, NULL)); + } else { + dbt->data = bk->data; + dbt->size = bk->len; + } + + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/btree/btree.src b/src/libs/resiprocate/contrib/db/btree/btree.src new file mode 100644 index 00000000..b6198e18 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/btree.src @@ -0,0 +1,291 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +DBPRIVATE +PREFIX __bam + +INCLUDE #include "db_int.h" +INCLUDE #include "dbinc/crypto.h" +INCLUDE #include "dbinc/db_page.h" +INCLUDE #include "dbinc/db_am.h" +INCLUDE #include "dbinc/btree.h" +INCLUDE #include "dbinc/log.h" +INCLUDE #include "dbinc/txn.h" +INCLUDE + +/* + * BTREE-split: used to log a page split. + * + * left: the page number for the low-order contents. + * llsn: the left page's original LSN. + * right: the page number for the high-order contents. + * rlsn: the right page's original LSN. + * indx: the number of entries that went to the left page. + * npgno: the next page number + * nlsn: the next page's original LSN (or 0 if no next page). + * pgno: the parent page number + * plsn: the parent page's original LSN. + * pg: the split page's contents before the split. + * opflags: SPL_NRECS: if splitting a tree that maintains a record count. + * pindx: index of new record in parent page. + */ +BEGIN split 48 62 +DB fileid int32_t ld +ARG left db_pgno_t lu +POINTER llsn DB_LSN * lu +ARG right db_pgno_t lu +POINTER rlsn DB_LSN * lu +ARG indx u_int32_t lu +ARG npgno db_pgno_t lu +POINTER nlsn DB_LSN * lu +ARG ppgno db_pgno_t lu +POINTER plsn DB_LSN * lu +ARG pindx u_int32_t lu +PGDBT pg DBT s +DBT pentry DBT s +DBT rentry DBT s +ARG opflags u_int32_t lu +END + +BEGIN_COMPAT split 42 62 +DB fileid int32_t ld +ARG left db_pgno_t lu +POINTER llsn DB_LSN * lu +ARG right db_pgno_t lu +POINTER rlsn DB_LSN * lu +ARG indx u_int32_t lu +ARG npgno db_pgno_t lu +POINTER nlsn DB_LSN * lu +ARG root_pgno db_pgno_t lu +PGDBT pg DBT s +ARG opflags u_int32_t lu +END + +/* + * BTREE-rsplit: used to log a reverse-split + * + * pgno: the page number of the page copied over the root. + * pgdbt: the page being copied on the root page. + * root_pgno: the root page number. + * nrec: the tree's record count. + * rootent: last entry on the root page. + * rootlsn: the root page's original lsn. + */ +BEGIN rsplit 42 63 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +PGDBT pgdbt DBT s +ARG root_pgno db_pgno_t lu +ARG nrec db_pgno_t lu +DBT rootent DBT s +POINTER rootlsn DB_LSN * lu +END + +/* + * BTREE-adj: used to log the adjustment of an index. + * + * pgno: the page modified. + * lsn: the page's original lsn. + * indx: the index adjusted. + * indx_copy: the index to copy if inserting. + * is_insert: 0 if a delete, 1 if an insert. + */ +BEGIN adj 42 55 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER lsn DB_LSN * lu +ARG indx u_int32_t lu +ARG indx_copy u_int32_t lu +ARG is_insert u_int32_t lu +END + +/* + * BTREE-cadjust: used to adjust the count change in an internal page. + * + * pgno: the page modified. + * lsn: the page's original lsn. + * indx: the index to be adjusted. + * adjust: the signed adjustment. + * opflags: CAD_UPDATEROOT: if root page count was adjusted. + */ +BEGIN cadjust 42 56 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER lsn DB_LSN * lu +ARG indx u_int32_t lu +ARG adjust int32_t ld +ARG opflags u_int32_t lu +END + +/* + * BTREE-cdel: used to log the intent-to-delete of a cursor record. + * + * pgno: the page modified. + * lsn: the page's original lsn. + * indx: the index to be deleted. + */ +BEGIN cdel 42 57 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER lsn DB_LSN * lu +ARG indx u_int32_t lu +END + +/* + * BTREE-repl: used to log the replacement of an item. + * + * pgno: the page modified. + * lsn: the page's original lsn. + * indx: the index to be replaced. + * isdeleted: set if the record was previously deleted. + * orig: the original data. + * repl: the replacement data. + * prefix: the prefix of the replacement that matches the original. + * suffix: the suffix of the replacement that matches the original. + */ +BEGIN repl 42 58 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER lsn DB_LSN * lu +ARG indx u_int32_t lu +ARG isdeleted u_int32_t lu +DBT orig DBT s +DBT repl DBT s +ARG prefix u_int32_t lu +ARG suffix u_int32_t lu +END + +/* + * BTREE-root: log the assignment of a root btree page. + */ +BEGIN root 42 59 +DB fileid int32_t ld +ARG meta_pgno db_pgno_t lu +ARG root_pgno db_pgno_t lu +POINTER meta_lsn DB_LSN * lu +END + +/* + * BTREE-curadj: undo cursor adjustments on txn abort. + * Should only be processed during DB_TXN_ABORT. + * NOTE: the first_indx field gets used to hold + * signed index adjustment in one case. + * care should be taken if its size is changed. + */ +BEGIN curadj 42 64 +/* Fileid of db affected. */ +DB fileid int32_t ld +/* Which adjustment. */ +ARG mode db_ca_mode ld +/* Page entry is from. */ +ARG from_pgno db_pgno_t lu +/* Page entry went to. */ +ARG to_pgno db_pgno_t lu +/* Left page of root split. */ +ARG left_pgno db_pgno_t lu +/* First index of dup set. Also used as adjustment. */ +ARG first_indx u_int32_t lu +/* Index entry is from. */ +ARG from_indx u_int32_t lu +/* Index where entry went. */ +ARG to_indx u_int32_t lu +END + +/* + * BTREE-rcuradj: undo cursor adjustments on txn abort in + * renumbering recno trees. + * Should only be processed during DB_TXN_ABORT. + */ +BEGIN rcuradj 42 65 +/* Fileid of db affected. */ +DB fileid int32_t ld +/* Which adjustment. */ +ARG mode ca_recno_arg ld +/* Root page number. */ +ARG root db_pgno_t ld +/* Recno of the adjustment. */ +ARG recno db_recno_t ld +/* Order number of the adjustment. */ +ARG order u_int32_t lu +END + +/* + * BTREE-relink -- Handles relinking around a deleted leaf page. + * + */ +BEGIN_COMPAT relink 43 147 +/* Fileid of db affected. */ +DB fileid int32_t ld +/* The page being removed. */ +ARG pgno db_pgno_t lu +/* The page's original lsn. */ +POINTER lsn DB_LSN * lu +/* The previous page. */ +ARG prev db_pgno_t lu +/* The previous page's original lsn. */ +POINTER lsn_prev DB_LSN * lu +/* The next page. */ +ARG next db_pgno_t lu +/* The previous page's original lsn. */ +POINTER lsn_next DB_LSN * lu +END + +BEGIN relink 44 147 +/* Fileid of db affected. */ +DB fileid int32_t ld +/* The page being removed. */ +ARG pgno db_pgno_t lu +/* The new page number, if any. */ +ARG new_pgno db_pgno_t lu +/* The previous page. */ +ARG prev db_pgno_t lu +/* The previous page's original lsn. */ +POINTER lsn_prev DB_LSN * lu +/* The next page. */ +ARG next db_pgno_t lu +/* The previous page's original lsn. */ +POINTER lsn_next DB_LSN * lu +END + +/* + * BTREE-merge -- Handles merging of pages during a compaction. + */ +BEGIN_COMPAT merge 44 148 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER lsn DB_LSN * lu +ARG npgno db_pgno_t lu +POINTER nlsn DB_LSN * lu +DBT hdr DBT s +DBT data DBT s +DBT ind DBT s +END + +BEGIN merge 47 148 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER lsn DB_LSN * lu +ARG npgno db_pgno_t lu +POINTER nlsn DB_LSN * lu +PGDBT hdr DBT s +PGDDBT data DBT s +ARG pg_copy int32_t lu +END + +/* + * BTREE-pgno -- Handles replacing a page number in the record + * reference on pgno by indx. + */ +BEGIN pgno 44 149 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER lsn DB_LSN * lu +ARG indx u_int32_t lu +ARG opgno db_pgno_t lu +ARG npgno db_pgno_t lu +END diff --git a/src/libs/resiprocate/contrib/db/btree/btree_auto.c b/src/libs/resiprocate/contrib/db/btree/btree_auto.c new file mode 100644 index 00000000..460f0383 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/btree_auto.c @@ -0,0 +1,3547 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#include "db_config.h" +#include "db_int.h" +#include "dbinc/crypto.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/btree.h" +#include "dbinc/log.h" +#include "dbinc/txn.h" + +/* + * PUBLIC: int __bam_split_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __bam_split_args **)); + */ +int +__bam_split_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_split_args **argpp; +{ + __bam_split_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_split_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->left = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->llsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->right = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->rlsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &argp->indx, bp); + bp += sizeof(argp->indx); + + LOGCOPY_32(env, &uinttmp, bp); + argp->npgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->nlsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->ppgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->plsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &argp->pindx, bp); + bp += sizeof(argp->pindx); + + memset(&argp->pg, 0, sizeof(argp->pg)); + LOGCOPY_32(env,&argp->pg.size, bp); + bp += sizeof(u_int32_t); + argp->pg.data = bp; + bp += argp->pg.size; + if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { + int t_ret; + if ((t_ret = __db_pageswap(*dbpp, (PAGE *)argp->pg.data, + (size_t)argp->pg.size, NULL, 1)) != 0) + return (t_ret); + } + + memset(&argp->pentry, 0, sizeof(argp->pentry)); + LOGCOPY_32(env,&argp->pentry.size, bp); + bp += sizeof(u_int32_t); + argp->pentry.data = bp; + bp += argp->pentry.size; + + memset(&argp->rentry, 0, sizeof(argp->rentry)); + LOGCOPY_32(env,&argp->rentry.size, bp); + bp += sizeof(u_int32_t); + argp->rentry.data = bp; + bp += argp->rentry.size; + + LOGCOPY_32(env, &argp->opflags, bp); + bp += sizeof(argp->opflags); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_split_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, u_int32_t, + * PUBLIC: db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, u_int32_t, const DBT *, + * PUBLIC: const DBT *, const DBT *, u_int32_t)); + */ +int +__bam_split_log(dbp, txnp, ret_lsnp, flags, left, llsn, right, rlsn, indx, + npgno, nlsn, ppgno, plsn, pindx, pg, + pentry, rentry, opflags) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t left; + DB_LSN * llsn; + db_pgno_t right; + DB_LSN * rlsn; + u_int32_t indx; + db_pgno_t npgno; + DB_LSN * nlsn; + db_pgno_t ppgno; + DB_LSN * plsn; + u_int32_t pindx; + const DBT *pg; + const DBT *pentry; + const DBT *rentry; + u_int32_t opflags; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___bam_split; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*llsn) + + sizeof(u_int32_t) + + sizeof(*rlsn) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*nlsn) + + sizeof(u_int32_t) + + sizeof(*plsn) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (pg == NULL ? 0 : pg->size) + + sizeof(u_int32_t) + (pentry == NULL ? 0 : pentry->size) + + sizeof(u_int32_t) + (rentry == NULL ? 0 : rentry->size) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)left; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (llsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(llsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, llsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, llsn); + } else + memset(bp, 0, sizeof(*llsn)); + bp += sizeof(*llsn); + + uinttmp = (u_int32_t)right; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (rlsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(rlsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, rlsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, rlsn); + } else + memset(bp, 0, sizeof(*rlsn)); + bp += sizeof(*rlsn); + + LOGCOPY_32(env, bp, &indx); + bp += sizeof(indx); + + uinttmp = (u_int32_t)npgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (nlsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(nlsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, nlsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, nlsn); + } else + memset(bp, 0, sizeof(*nlsn)); + bp += sizeof(*nlsn); + + uinttmp = (u_int32_t)ppgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (plsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(plsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, plsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, plsn); + } else + memset(bp, 0, sizeof(*plsn)); + bp += sizeof(*plsn); + + LOGCOPY_32(env, bp, &pindx); + bp += sizeof(pindx); + + if (pg == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &pg->size); + bp += sizeof(pg->size); + memcpy(bp, pg->data, pg->size); + if (LOG_SWAPPED(env)) + if ((ret = __db_pageswap(dbp, + (PAGE *)bp, (size_t)pg->size, (DBT *)NULL, 0)) != 0) + return (ret); + bp += pg->size; + } + + if (pentry == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &pentry->size); + bp += sizeof(pentry->size); + memcpy(bp, pentry->data, pentry->size); + bp += pentry->size; + } + + if (rentry == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &rentry->size); + bp += sizeof(rentry->size); + memcpy(bp, rentry->data, rentry->size); + bp += rentry->size; + } + + LOGCOPY_32(env, bp, &opflags); + bp += sizeof(opflags); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__bam_split_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __bam_split_42_read __P((ENV *, DB **, void *, + * PUBLIC: void *, __bam_split_42_args **)); + */ +int +__bam_split_42_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_split_42_args **argpp; +{ + __bam_split_42_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_split_42_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->left = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->llsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->right = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->rlsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &argp->indx, bp); + bp += sizeof(argp->indx); + + LOGCOPY_32(env, &uinttmp, bp); + argp->npgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->nlsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->root_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->pg, 0, sizeof(argp->pg)); + LOGCOPY_32(env,&argp->pg.size, bp); + bp += sizeof(u_int32_t); + argp->pg.data = bp; + bp += argp->pg.size; + + LOGCOPY_32(env, &argp->opflags, bp); + bp += sizeof(argp->opflags); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_rsplit_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __bam_rsplit_args **)); + */ +int +__bam_rsplit_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_rsplit_args **argpp; +{ + __bam_rsplit_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_rsplit_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->pgdbt, 0, sizeof(argp->pgdbt)); + LOGCOPY_32(env,&argp->pgdbt.size, bp); + bp += sizeof(u_int32_t); + argp->pgdbt.data = bp; + bp += argp->pgdbt.size; + if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { + int t_ret; + if ((t_ret = __db_pageswap(*dbpp, (PAGE *)argp->pgdbt.data, + (size_t)argp->pgdbt.size, NULL, 1)) != 0) + return (t_ret); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->root_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->nrec = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->rootent, 0, sizeof(argp->rootent)); + LOGCOPY_32(env,&argp->rootent.size, bp); + bp += sizeof(u_int32_t); + argp->rootent.data = bp; + bp += argp->rootent.size; + + LOGCOPY_TOLSN(env, &argp->rootlsn, bp); + bp += sizeof(DB_LSN); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_rsplit_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, const DBT *, db_pgno_t, db_pgno_t, + * PUBLIC: const DBT *, DB_LSN *)); + */ +int +__bam_rsplit_log(dbp, txnp, ret_lsnp, flags, pgno, pgdbt, root_pgno, nrec, rootent, + rootlsn) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + const DBT *pgdbt; + db_pgno_t root_pgno; + db_pgno_t nrec; + const DBT *rootent; + DB_LSN * rootlsn; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___bam_rsplit; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (pgdbt == NULL ? 0 : pgdbt->size) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (rootent == NULL ? 0 : rootent->size) + + sizeof(*rootlsn); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (pgdbt == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &pgdbt->size); + bp += sizeof(pgdbt->size); + memcpy(bp, pgdbt->data, pgdbt->size); + if (LOG_SWAPPED(env)) + if ((ret = __db_pageswap(dbp, + (PAGE *)bp, (size_t)pgdbt->size, (DBT *)NULL, 0)) != 0) + return (ret); + bp += pgdbt->size; + } + + uinttmp = (u_int32_t)root_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)nrec; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (rootent == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &rootent->size); + bp += sizeof(rootent->size); + memcpy(bp, rootent->data, rootent->size); + bp += rootent->size; + } + + if (rootlsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(rootlsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, rootlsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, rootlsn); + } else + memset(bp, 0, sizeof(*rootlsn)); + bp += sizeof(*rootlsn); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__bam_rsplit_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __bam_adj_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __bam_adj_args **)); + */ +int +__bam_adj_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_adj_args **argpp; +{ + __bam_adj_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_adj_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &argp->indx, bp); + bp += sizeof(argp->indx); + + LOGCOPY_32(env, &argp->indx_copy, bp); + bp += sizeof(argp->indx_copy); + + LOGCOPY_32(env, &argp->is_insert, bp); + bp += sizeof(argp->is_insert); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_adj_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, u_int32_t, u_int32_t, + * PUBLIC: u_int32_t)); + */ +int +__bam_adj_log(dbp, txnp, ret_lsnp, flags, pgno, lsn, indx, indx_copy, is_insert) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + DB_LSN * lsn; + u_int32_t indx; + u_int32_t indx_copy; + u_int32_t is_insert; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___bam_adj; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*lsn) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, lsn); + } else + memset(bp, 0, sizeof(*lsn)); + bp += sizeof(*lsn); + + LOGCOPY_32(env, bp, &indx); + bp += sizeof(indx); + + LOGCOPY_32(env, bp, &indx_copy); + bp += sizeof(indx_copy); + + LOGCOPY_32(env, bp, &is_insert); + bp += sizeof(is_insert); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__bam_adj_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __bam_cadjust_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __bam_cadjust_args **)); + */ +int +__bam_cadjust_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_cadjust_args **argpp; +{ + __bam_cadjust_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_cadjust_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &argp->indx, bp); + bp += sizeof(argp->indx); + + LOGCOPY_32(env, &uinttmp, bp); + argp->adjust = (int32_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &argp->opflags, bp); + bp += sizeof(argp->opflags); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_cadjust_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, u_int32_t, int32_t, u_int32_t)); + */ +int +__bam_cadjust_log(dbp, txnp, ret_lsnp, flags, pgno, lsn, indx, adjust, opflags) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + DB_LSN * lsn; + u_int32_t indx; + int32_t adjust; + u_int32_t opflags; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___bam_cadjust; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*lsn) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, lsn); + } else + memset(bp, 0, sizeof(*lsn)); + bp += sizeof(*lsn); + + LOGCOPY_32(env, bp, &indx); + bp += sizeof(indx); + + uinttmp = (u_int32_t)adjust; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + LOGCOPY_32(env, bp, &opflags); + bp += sizeof(opflags); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__bam_cadjust_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __bam_cdel_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __bam_cdel_args **)); + */ +int +__bam_cdel_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_cdel_args **argpp; +{ + __bam_cdel_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_cdel_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &argp->indx, bp); + bp += sizeof(argp->indx); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_cdel_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, u_int32_t)); + */ +int +__bam_cdel_log(dbp, txnp, ret_lsnp, flags, pgno, lsn, indx) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + DB_LSN * lsn; + u_int32_t indx; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___bam_cdel; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*lsn) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, lsn); + } else + memset(bp, 0, sizeof(*lsn)); + bp += sizeof(*lsn); + + LOGCOPY_32(env, bp, &indx); + bp += sizeof(indx); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__bam_cdel_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __bam_repl_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __bam_repl_args **)); + */ +int +__bam_repl_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_repl_args **argpp; +{ + __bam_repl_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_repl_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &argp->indx, bp); + bp += sizeof(argp->indx); + + LOGCOPY_32(env, &argp->isdeleted, bp); + bp += sizeof(argp->isdeleted); + + memset(&argp->orig, 0, sizeof(argp->orig)); + LOGCOPY_32(env,&argp->orig.size, bp); + bp += sizeof(u_int32_t); + argp->orig.data = bp; + bp += argp->orig.size; + + memset(&argp->repl, 0, sizeof(argp->repl)); + LOGCOPY_32(env,&argp->repl.size, bp); + bp += sizeof(u_int32_t); + argp->repl.data = bp; + bp += argp->repl.size; + + LOGCOPY_32(env, &argp->prefix, bp); + bp += sizeof(argp->prefix); + + LOGCOPY_32(env, &argp->suffix, bp); + bp += sizeof(argp->suffix); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_repl_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, u_int32_t, u_int32_t, + * PUBLIC: const DBT *, const DBT *, u_int32_t, u_int32_t)); + */ +int +__bam_repl_log(dbp, txnp, ret_lsnp, flags, pgno, lsn, indx, isdeleted, orig, + repl, prefix, suffix) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + DB_LSN * lsn; + u_int32_t indx; + u_int32_t isdeleted; + const DBT *orig; + const DBT *repl; + u_int32_t prefix; + u_int32_t suffix; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___bam_repl; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*lsn) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (orig == NULL ? 0 : orig->size) + + sizeof(u_int32_t) + (repl == NULL ? 0 : repl->size) + + sizeof(u_int32_t) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, lsn); + } else + memset(bp, 0, sizeof(*lsn)); + bp += sizeof(*lsn); + + LOGCOPY_32(env, bp, &indx); + bp += sizeof(indx); + + LOGCOPY_32(env, bp, &isdeleted); + bp += sizeof(isdeleted); + + if (orig == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &orig->size); + bp += sizeof(orig->size); + memcpy(bp, orig->data, orig->size); + bp += orig->size; + } + + if (repl == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &repl->size); + bp += sizeof(repl->size); + memcpy(bp, repl->data, repl->size); + bp += repl->size; + } + + LOGCOPY_32(env, bp, &prefix); + bp += sizeof(prefix); + + LOGCOPY_32(env, bp, &suffix); + bp += sizeof(suffix); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__bam_repl_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __bam_root_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __bam_root_args **)); + */ +int +__bam_root_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_root_args **argpp; +{ + __bam_root_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_root_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->meta_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->root_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); + bp += sizeof(DB_LSN); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_root_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, db_pgno_t, DB_LSN *)); + */ +int +__bam_root_log(dbp, txnp, ret_lsnp, flags, meta_pgno, root_pgno, meta_lsn) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t meta_pgno; + db_pgno_t root_pgno; + DB_LSN * meta_lsn; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___bam_root; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*meta_lsn); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)meta_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)root_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (meta_lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, meta_lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, meta_lsn); + } else + memset(bp, 0, sizeof(*meta_lsn)); + bp += sizeof(*meta_lsn); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__bam_root_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __bam_curadj_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __bam_curadj_args **)); + */ +int +__bam_curadj_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_curadj_args **argpp; +{ + __bam_curadj_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_curadj_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->mode = (db_ca_mode)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->from_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->to_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->left_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &argp->first_indx, bp); + bp += sizeof(argp->first_indx); + + LOGCOPY_32(env, &argp->from_indx, bp); + bp += sizeof(argp->from_indx); + + LOGCOPY_32(env, &argp->to_indx, bp); + bp += sizeof(argp->to_indx); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_curadj_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_ca_mode, db_pgno_t, db_pgno_t, db_pgno_t, + * PUBLIC: u_int32_t, u_int32_t, u_int32_t)); + */ +int +__bam_curadj_log(dbp, txnp, ret_lsnp, flags, mode, from_pgno, to_pgno, left_pgno, first_indx, + from_indx, to_indx) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_ca_mode mode; + db_pgno_t from_pgno; + db_pgno_t to_pgno; + db_pgno_t left_pgno; + u_int32_t first_indx; + u_int32_t from_indx; + u_int32_t to_indx; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___bam_curadj; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)mode; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)from_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)to_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)left_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + LOGCOPY_32(env, bp, &first_indx); + bp += sizeof(first_indx); + + LOGCOPY_32(env, bp, &from_indx); + bp += sizeof(from_indx); + + LOGCOPY_32(env, bp, &to_indx); + bp += sizeof(to_indx); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__bam_curadj_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __bam_rcuradj_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __bam_rcuradj_args **)); + */ +int +__bam_rcuradj_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_rcuradj_args **argpp; +{ + __bam_rcuradj_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_rcuradj_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->mode = (ca_recno_arg)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->root = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->recno = (db_recno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &argp->order, bp); + bp += sizeof(argp->order); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_rcuradj_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, ca_recno_arg, db_pgno_t, db_recno_t, u_int32_t)); + */ +int +__bam_rcuradj_log(dbp, txnp, ret_lsnp, flags, mode, root, recno, order) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + ca_recno_arg mode; + db_pgno_t root; + db_recno_t recno; + u_int32_t order; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___bam_rcuradj; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)mode; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)root; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)recno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + LOGCOPY_32(env, bp, &order); + bp += sizeof(order); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__bam_rcuradj_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __bam_relink_43_read __P((ENV *, DB **, void *, + * PUBLIC: void *, __bam_relink_43_args **)); + */ +int +__bam_relink_43_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_relink_43_args **argpp; +{ + __bam_relink_43_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_relink_43_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->prev = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn_prev, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->next = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn_next, bp); + bp += sizeof(DB_LSN); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_relink_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __bam_relink_args **)); + */ +int +__bam_relink_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_relink_args **argpp; +{ + __bam_relink_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_relink_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->new_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->prev = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn_prev, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->next = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn_next, bp); + bp += sizeof(DB_LSN); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_relink_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, db_pgno_t, db_pgno_t, DB_LSN *, db_pgno_t, + * PUBLIC: DB_LSN *)); + */ +int +__bam_relink_log(dbp, txnp, ret_lsnp, flags, pgno, new_pgno, prev, lsn_prev, next, + lsn_next) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + db_pgno_t new_pgno; + db_pgno_t prev; + DB_LSN * lsn_prev; + db_pgno_t next; + DB_LSN * lsn_next; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___bam_relink; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*lsn_prev) + + sizeof(u_int32_t) + + sizeof(*lsn_next); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)new_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)prev; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (lsn_prev != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(lsn_prev, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, lsn_prev)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, lsn_prev); + } else + memset(bp, 0, sizeof(*lsn_prev)); + bp += sizeof(*lsn_prev); + + uinttmp = (u_int32_t)next; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (lsn_next != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(lsn_next, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, lsn_next)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, lsn_next); + } else + memset(bp, 0, sizeof(*lsn_next)); + bp += sizeof(*lsn_next); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__bam_relink_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __bam_merge_44_read __P((ENV *, DB **, void *, + * PUBLIC: void *, __bam_merge_44_args **)); + */ +int +__bam_merge_44_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_merge_44_args **argpp; +{ + __bam_merge_44_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_merge_44_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->npgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->nlsn, bp); + bp += sizeof(DB_LSN); + + memset(&argp->hdr, 0, sizeof(argp->hdr)); + LOGCOPY_32(env,&argp->hdr.size, bp); + bp += sizeof(u_int32_t); + argp->hdr.data = bp; + bp += argp->hdr.size; + + memset(&argp->data, 0, sizeof(argp->data)); + LOGCOPY_32(env,&argp->data.size, bp); + bp += sizeof(u_int32_t); + argp->data.data = bp; + bp += argp->data.size; + + memset(&argp->ind, 0, sizeof(argp->ind)); + LOGCOPY_32(env,&argp->ind.size, bp); + bp += sizeof(u_int32_t); + argp->ind.data = bp; + bp += argp->ind.size; + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_merge_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __bam_merge_args **)); + */ +int +__bam_merge_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_merge_args **argpp; +{ + __bam_merge_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_merge_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->npgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->nlsn, bp); + bp += sizeof(DB_LSN); + + memset(&argp->hdr, 0, sizeof(argp->hdr)); + LOGCOPY_32(env,&argp->hdr.size, bp); + bp += sizeof(u_int32_t); + argp->hdr.data = bp; + bp += argp->hdr.size; + + memset(&argp->data, 0, sizeof(argp->data)); + LOGCOPY_32(env,&argp->data.size, bp); + bp += sizeof(u_int32_t); + argp->data.data = bp; + bp += argp->data.size; + if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { + int t_ret; + if ((t_ret = __db_pageswap(*dbpp, + (PAGE *)argp->hdr.data, (size_t)argp->hdr.size, + &argp->data, 1)) != 0) + return (t_ret); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pg_copy = (int32_t)uinttmp; + bp += sizeof(uinttmp); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_merge_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, const DBT *, + * PUBLIC: const DBT *, int32_t)); + */ +int +__bam_merge_log(dbp, txnp, ret_lsnp, flags, pgno, lsn, npgno, nlsn, hdr, + data, pg_copy) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + DB_LSN * lsn; + db_pgno_t npgno; + DB_LSN * nlsn; + const DBT *hdr; + const DBT *data; + int32_t pg_copy; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___bam_merge; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*lsn) + + sizeof(u_int32_t) + + sizeof(*nlsn) + + sizeof(u_int32_t) + (hdr == NULL ? 0 : hdr->size) + + sizeof(u_int32_t) + (data == NULL ? 0 : data->size) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, lsn); + } else + memset(bp, 0, sizeof(*lsn)); + bp += sizeof(*lsn); + + uinttmp = (u_int32_t)npgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (nlsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(nlsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, nlsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, nlsn); + } else + memset(bp, 0, sizeof(*nlsn)); + bp += sizeof(*nlsn); + + if (hdr == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &hdr->size); + bp += sizeof(hdr->size); + memcpy(bp, hdr->data, hdr->size); + if (LOG_SWAPPED(env)) + if ((ret = __db_pageswap(dbp, + (PAGE *)bp, (size_t)hdr->size, (DBT *)data, 0)) != 0) + return (ret); + bp += hdr->size; + } + + if (data == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &data->size); + bp += sizeof(data->size); + memcpy(bp, data->data, data->size); + if (LOG_SWAPPED(env) && F_ISSET(data, DB_DBT_APPMALLOC)) + __os_free(env, data->data); + bp += data->size; + } + + uinttmp = (u_int32_t)pg_copy; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__bam_merge_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __bam_pgno_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __bam_pgno_args **)); + */ +int +__bam_pgno_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __bam_pgno_args **argpp; +{ + __bam_pgno_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__bam_pgno_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &argp->indx, bp); + bp += sizeof(argp->indx); + + LOGCOPY_32(env, &uinttmp, bp); + argp->opgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->npgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __bam_pgno_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, u_int32_t, db_pgno_t, + * PUBLIC: db_pgno_t)); + */ +int +__bam_pgno_log(dbp, txnp, ret_lsnp, flags, pgno, lsn, indx, opgno, npgno) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + DB_LSN * lsn; + u_int32_t indx; + db_pgno_t opgno; + db_pgno_t npgno; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___bam_pgno; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*lsn) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, lsn); + } else + memset(bp, 0, sizeof(*lsn)); + bp += sizeof(*lsn); + + LOGCOPY_32(env, bp, &indx); + bp += sizeof(indx); + + uinttmp = (u_int32_t)opgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)npgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__bam_pgno_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __bam_init_recover __P((ENV *, DB_DISTAB *)); + */ +int +__bam_init_recover(env, dtabp) + ENV *env; + DB_DISTAB *dtabp; +{ + int ret; + + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_split_recover, DB___bam_split)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_rsplit_recover, DB___bam_rsplit)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_adj_recover, DB___bam_adj)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_cadjust_recover, DB___bam_cadjust)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_cdel_recover, DB___bam_cdel)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_repl_recover, DB___bam_repl)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_root_recover, DB___bam_root)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_curadj_recover, DB___bam_curadj)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_rcuradj_recover, DB___bam_rcuradj)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_relink_recover, DB___bam_relink)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_merge_recover, DB___bam_merge)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_pgno_recover, DB___bam_pgno)) != 0) + return (ret); + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/btree/btree_autop.c b/src/libs/resiprocate/contrib/db/btree/btree_autop.c new file mode 100644 index 00000000..54cb501e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/btree/btree_autop.c @@ -0,0 +1,766 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/crypto.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/btree.h" +#include "dbinc/log.h" +#include "dbinc/txn.h" + +/* + * PUBLIC: int __bam_split_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_split_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_split_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_split_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_split%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tleft: %lu\n", (u_long)argp->left); + (void)printf("\tllsn: [%lu][%lu]\n", + (u_long)argp->llsn.file, (u_long)argp->llsn.offset); + (void)printf("\tright: %lu\n", (u_long)argp->right); + (void)printf("\trlsn: [%lu][%lu]\n", + (u_long)argp->rlsn.file, (u_long)argp->rlsn.offset); + (void)printf("\tindx: %lu\n", (u_long)argp->indx); + (void)printf("\tnpgno: %lu\n", (u_long)argp->npgno); + (void)printf("\tnlsn: [%lu][%lu]\n", + (u_long)argp->nlsn.file, (u_long)argp->nlsn.offset); + (void)printf("\tppgno: %lu\n", (u_long)argp->ppgno); + (void)printf("\tplsn: [%lu][%lu]\n", + (u_long)argp->plsn.file, (u_long)argp->plsn.offset); + (void)printf("\tpindx: %lu\n", (u_long)argp->pindx); + (void)printf("\tpg: "); + for (i = 0; i < argp->pg.size; i++) { + ch = ((u_int8_t *)argp->pg.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tpentry: "); + for (i = 0; i < argp->pentry.size; i++) { + ch = ((u_int8_t *)argp->pentry.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\trentry: "); + for (i = 0; i < argp->rentry.size; i++) { + ch = ((u_int8_t *)argp->rentry.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\topflags: %lu\n", (u_long)argp->opflags); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_split_42_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_split_42_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_split_42_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_split_42_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_split_42%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tleft: %lu\n", (u_long)argp->left); + (void)printf("\tllsn: [%lu][%lu]\n", + (u_long)argp->llsn.file, (u_long)argp->llsn.offset); + (void)printf("\tright: %lu\n", (u_long)argp->right); + (void)printf("\trlsn: [%lu][%lu]\n", + (u_long)argp->rlsn.file, (u_long)argp->rlsn.offset); + (void)printf("\tindx: %lu\n", (u_long)argp->indx); + (void)printf("\tnpgno: %lu\n", (u_long)argp->npgno); + (void)printf("\tnlsn: [%lu][%lu]\n", + (u_long)argp->nlsn.file, (u_long)argp->nlsn.offset); + (void)printf("\troot_pgno: %lu\n", (u_long)argp->root_pgno); + (void)printf("\tpg: "); + for (i = 0; i < argp->pg.size; i++) { + ch = ((u_int8_t *)argp->pg.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\topflags: %lu\n", (u_long)argp->opflags); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_rsplit_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_rsplit_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_rsplit_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_rsplit_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_rsplit%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tpgdbt: "); + for (i = 0; i < argp->pgdbt.size; i++) { + ch = ((u_int8_t *)argp->pgdbt.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\troot_pgno: %lu\n", (u_long)argp->root_pgno); + (void)printf("\tnrec: %lu\n", (u_long)argp->nrec); + (void)printf("\trootent: "); + for (i = 0; i < argp->rootent.size; i++) { + ch = ((u_int8_t *)argp->rootent.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\trootlsn: [%lu][%lu]\n", + (u_long)argp->rootlsn.file, (u_long)argp->rootlsn.offset); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_adj_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_adj_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_adj_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_adj_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_adj%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tlsn: [%lu][%lu]\n", + (u_long)argp->lsn.file, (u_long)argp->lsn.offset); + (void)printf("\tindx: %lu\n", (u_long)argp->indx); + (void)printf("\tindx_copy: %lu\n", (u_long)argp->indx_copy); + (void)printf("\tis_insert: %lu\n", (u_long)argp->is_insert); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_cadjust_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_cadjust_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_cadjust_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_cadjust_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_cadjust%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tlsn: [%lu][%lu]\n", + (u_long)argp->lsn.file, (u_long)argp->lsn.offset); + (void)printf("\tindx: %lu\n", (u_long)argp->indx); + (void)printf("\tadjust: %ld\n", (long)argp->adjust); + (void)printf("\topflags: %lu\n", (u_long)argp->opflags); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_cdel_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_cdel_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_cdel_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_cdel_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_cdel%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tlsn: [%lu][%lu]\n", + (u_long)argp->lsn.file, (u_long)argp->lsn.offset); + (void)printf("\tindx: %lu\n", (u_long)argp->indx); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_repl_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_repl_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_repl_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_repl_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_repl%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tlsn: [%lu][%lu]\n", + (u_long)argp->lsn.file, (u_long)argp->lsn.offset); + (void)printf("\tindx: %lu\n", (u_long)argp->indx); + (void)printf("\tisdeleted: %lu\n", (u_long)argp->isdeleted); + (void)printf("\torig: "); + for (i = 0; i < argp->orig.size; i++) { + ch = ((u_int8_t *)argp->orig.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\trepl: "); + for (i = 0; i < argp->repl.size; i++) { + ch = ((u_int8_t *)argp->repl.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tprefix: %lu\n", (u_long)argp->prefix); + (void)printf("\tsuffix: %lu\n", (u_long)argp->suffix); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_root_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_root_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_root_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_root_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_root%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tmeta_pgno: %lu\n", (u_long)argp->meta_pgno); + (void)printf("\troot_pgno: %lu\n", (u_long)argp->root_pgno); + (void)printf("\tmeta_lsn: [%lu][%lu]\n", + (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_curadj_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_curadj_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_curadj_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_curadj_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_curadj%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tmode: %ld\n", (long)argp->mode); + (void)printf("\tfrom_pgno: %lu\n", (u_long)argp->from_pgno); + (void)printf("\tto_pgno: %lu\n", (u_long)argp->to_pgno); + (void)printf("\tleft_pgno: %lu\n", (u_long)argp->left_pgno); + (void)printf("\tfirst_indx: %lu\n", (u_long)argp->first_indx); + (void)printf("\tfrom_indx: %lu\n", (u_long)argp->from_indx); + (void)printf("\tto_indx: %lu\n", (u_long)argp->to_indx); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_rcuradj_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_rcuradj_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_rcuradj_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_rcuradj_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_rcuradj%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tmode: %ld\n", (long)argp->mode); + (void)printf("\troot: %ld\n", (long)argp->root); + (void)printf("\trecno: %ld\n", (long)argp->recno); + (void)printf("\torder: %lu\n", (u_long)argp->order); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_relink_43_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_relink_43_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_relink_43_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_relink_43_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_relink_43%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tlsn: [%lu][%lu]\n", + (u_long)argp->lsn.file, (u_long)argp->lsn.offset); + (void)printf("\tprev: %lu\n", (u_long)argp->prev); + (void)printf("\tlsn_prev: [%lu][%lu]\n", + (u_long)argp->lsn_prev.file, (u_long)argp->lsn_prev.offset); + (void)printf("\tnext: %lu\n", (u_long)argp->next); + (void)printf("\tlsn_next: [%lu][%lu]\n", + (u_long)argp->lsn_next.file, (u_long)argp->lsn_next.offset); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_relink_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_relink_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_relink_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_relink_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_relink%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tnew_pgno: %lu\n", (u_long)argp->new_pgno); + (void)printf("\tprev: %lu\n", (u_long)argp->prev); + (void)printf("\tlsn_prev: [%lu][%lu]\n", + (u_long)argp->lsn_prev.file, (u_long)argp->lsn_prev.offset); + (void)printf("\tnext: %lu\n", (u_long)argp->next); + (void)printf("\tlsn_next: [%lu][%lu]\n", + (u_long)argp->lsn_next.file, (u_long)argp->lsn_next.offset); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_merge_44_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_merge_44_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_merge_44_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_merge_44_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_merge_44%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tlsn: [%lu][%lu]\n", + (u_long)argp->lsn.file, (u_long)argp->lsn.offset); + (void)printf("\tnpgno: %lu\n", (u_long)argp->npgno); + (void)printf("\tnlsn: [%lu][%lu]\n", + (u_long)argp->nlsn.file, (u_long)argp->nlsn.offset); + (void)printf("\thdr: "); + for (i = 0; i < argp->hdr.size; i++) { + ch = ((u_int8_t *)argp->hdr.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tdata: "); + for (i = 0; i < argp->data.size; i++) { + ch = ((u_int8_t *)argp->data.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tind: "); + for (i = 0; i < argp->ind.size; i++) { + ch = ((u_int8_t *)argp->ind.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_merge_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_merge_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_merge_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_merge_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_merge%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tlsn: [%lu][%lu]\n", + (u_long)argp->lsn.file, (u_long)argp->lsn.offset); + (void)printf("\tnpgno: %lu\n", (u_long)argp->npgno); + (void)printf("\tnlsn: [%lu][%lu]\n", + (u_long)argp->nlsn.file, (u_long)argp->nlsn.offset); + (void)printf("\thdr: "); + for (i = 0; i < argp->hdr.size; i++) { + ch = ((u_int8_t *)argp->hdr.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tdata: "); + for (i = 0; i < argp->data.size; i++) { + ch = ((u_int8_t *)argp->data.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tpg_copy: %lu\n", (u_long)argp->pg_copy); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_pgno_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__bam_pgno_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __bam_pgno_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __bam_pgno_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__bam_pgno%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tlsn: [%lu][%lu]\n", + (u_long)argp->lsn.file, (u_long)argp->lsn.offset); + (void)printf("\tindx: %lu\n", (u_long)argp->indx); + (void)printf("\topgno: %lu\n", (u_long)argp->opgno); + (void)printf("\tnpgno: %lu\n", (u_long)argp->npgno); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __bam_init_print __P((ENV *, DB_DISTAB *)); + */ +int +__bam_init_print(env, dtabp) + ENV *env; + DB_DISTAB *dtabp; +{ + int ret; + + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_split_print, DB___bam_split)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_rsplit_print, DB___bam_rsplit)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_adj_print, DB___bam_adj)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_cadjust_print, DB___bam_cadjust)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_cdel_print, DB___bam_cdel)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_repl_print, DB___bam_repl)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_root_print, DB___bam_root)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_curadj_print, DB___bam_curadj)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_rcuradj_print, DB___bam_rcuradj)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_relink_print, DB___bam_relink)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_merge_print, DB___bam_merge)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_pgno_print, DB___bam_pgno)) != 0) + return (ret); + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/build_unix/.IGNORE_ME b/src/libs/resiprocate/contrib/db/build_unix/.IGNORE_ME new file mode 100644 index 00000000..558fd496 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_unix/.IGNORE_ME @@ -0,0 +1,3 @@ +Some combinations of the gzip and tar archive exploders found +on Linux systems ignore directories that don't have any files +(other than symbolic links) in them. So, here's a file. diff --git a/src/libs/resiprocate/contrib/db/build_win32/Berkeley_DB.dsw b/src/libs/resiprocate/contrib/db/build_win32/Berkeley_DB.dsw new file mode 100644 index 00000000..8e39c20e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/Berkeley_DB.dsw @@ -0,0 +1,539 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "build_all"=.\build_all.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_archive + End Project Dependency + Begin Project Dependency + Project_Dep_Name db_checkpoint + End Project Dependency + Begin Project Dependency + Project_Dep_Name db_deadlock + End Project Dependency + Begin Project Dependency + Project_Dep_Name DB_DLL + End Project Dependency + Begin Project Dependency + Project_Dep_Name db_dump + End Project Dependency + Begin Project Dependency + Project_Dep_Name db_load + End Project Dependency + Begin Project Dependency + Project_Dep_Name db_printlog + End Project Dependency + Begin Project Dependency + Project_Dep_Name db_recover + End Project Dependency + Begin Project Dependency + Project_Dep_Name db_stat + End Project Dependency + Begin Project Dependency + Project_Dep_Name db_upgrade + End Project Dependency + Begin Project Dependency + Project_Dep_Name db_verify + End Project Dependency + Begin Project Dependency + Project_Dep_Name DB_Static + End Project Dependency + Begin Project Dependency + Project_Dep_Name ex_access + End Project Dependency + Begin Project Dependency + Project_Dep_Name ex_btrec + End Project Dependency + Begin Project Dependency + Project_Dep_Name ex_env + End Project Dependency + Begin Project Dependency + Project_Dep_Name ex_lock + End Project Dependency + Begin Project Dependency + Project_Dep_Name ex_mpool + End Project Dependency + Begin Project Dependency + Project_Dep_Name ex_tpcb + End Project Dependency + Begin Project Dependency + Project_Dep_Name excxx_access + End Project Dependency + Begin Project Dependency + Project_Dep_Name excxx_btrec + End Project Dependency + Begin Project Dependency + Project_Dep_Name excxx_env + End Project Dependency + Begin Project Dependency + Project_Dep_Name excxx_lock + End Project Dependency + Begin Project Dependency + Project_Dep_Name excxx_mpool + End Project Dependency + Begin Project Dependency + Project_Dep_Name excxx_tpcb + End Project Dependency + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "db_archive"=.\db_archive.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "db_checkpoint"=.\db_checkpoint.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "db_deadlock"=.\db_deadlock.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name DB_DLL + End Project Dependency +}}} + +############################################################################### + +Project: "db_dll"=.\db_dll.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "db_dump"=.\db_dump.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "db_java"=.\db_java.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name DB_DLL + End Project Dependency +}}} + +############################################################################### + +Project: "db_lib"=.\db_lib.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_dll + End Project Dependency + Begin Project Dependency + Project_Dep_Name db_static + End Project Dependency +}}} + +############################################################################### + +Project: "db_load"=.\db_load.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "db_printlog"=.\db_printlog.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "db_recover"=.\db_recover.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "db_stat"=.\db_stat.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "db_static"=.\db_static.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "db_tcl"=.\db_tcl.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name DB_DLL + End Project Dependency +}}} + +############################################################################### + +Project: "db_test"=.\db_test.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name build_all + End Project Dependency + Begin Project Dependency + Project_Dep_Name db_tcl + End Project Dependency +}}} + +############################################################################### + +Project: "db_upgrade"=.\db_upgrade.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "db_verify"=.\db_verify.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "ex_access"=.\ex_access.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "ex_btrec"=.\ex_btrec.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "ex_env"=.\ex_env.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "ex_lock"=.\ex_lock.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "ex_mpool"=.\ex_mpool.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "ex_repquote"=.\ex_repquote.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "ex_tpcb"=.\ex_tpcb.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "excxx_access"=.\excxx_access.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "excxx_btrec"=.\excxx_btrec.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "excxx_env"=.\excxx_env.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "excxx_lock"=.\excxx_lock.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "excxx_mpool"=.\excxx_mpool.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Project: "excxx_tpcb"=.\excxx_tpcb.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name db_lib + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/src/libs/resiprocate/contrib/db/build_win32/Berkeley_DB.sln b/src/libs/resiprocate/contrib/db/build_win32/Berkeley_DB.sln new file mode 100644 index 00000000..3ddafaf7 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/Berkeley_DB.sln @@ -0,0 +1,371 @@ +Microsoft Visual Studio Solution File, Format Version 7.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "build_all", "build_all.vcproj", "{DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_archive", "db_archive.vcproj", "{1630D1E0-070A-4B2A-B103-2D3A1D207200}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_checkpoint", "db_checkpoint.vcproj", "{B8BBA6BA-5BC2-4271-BFC4-AF3DB95598D9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_deadlock", "db_deadlock.vcproj", "{A308D79C-9740-4606-B396-6FE5E6E91251}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_dll", "db_dll.vcproj", "{F3C2785D-A358-47B1-B818-F5411FB2CB94}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_dump", "db_dump.vcproj", "{E3BE79CF-6872-41DD-8272-A97A1310421A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_java", "db_java.vcproj", "{A507571D-8904-4621-BB44-29D5ED632ACE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_lib", "db_lib.vcproj", "{A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_load", "db_load.vcproj", "{C99A8B5E-5C40-40BE-83EF-9FB1049025AD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_printlog", "db_printlog.vcproj", "{7CCAE778-C613-4C83-B1EF-97B77FD41316}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_recover", "db_recover.vcproj", "{48ADBC48-D55C-4093-BDC3-3146D5580B67}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_stat", "db_stat.vcproj", "{1321D847-2516-4339-A5D1-84582755766D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_static", "db_static.vcproj", "{E37383A4-BC15-4416-B0D1-D7715470F351}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_tcl", "db_tcl.vcproj", "{3BBAC089-ED28-4DE6-AE85-B55F2A84CFBB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_test", "db_test.vcproj", "{EA3BF4FA-D85A-4132-9EC5-991A83F279B3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_upgrade", "db_upgrade.vcproj", "{6D2A35F5-B7E8-4156-BA10-EEA3DEFD8FD8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_verify", "db_verify.vcproj", "{913669D3-CB3A-4EA3-A110-0DDB08BDD8B5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ex_access", "ex_access.vcproj", "{342E52CB-EBD0-4AE8-9195-C170329622F7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ex_btrec", "ex_btrec.vcproj", "{7B93303C-96FC-4EDF-A138-AFFF7FB47387}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ex_env", "ex_env.vcproj", "{6A9CC71A-378D-4867-A1A0-4F8F02F58514}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ex_lock", "ex_lock.vcproj", "{2B888D16-EC66-4EC3-8EB3-DC88C6B959E5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ex_mpool", "ex_mpool.vcproj", "{45D65648-E766-4202-AFE8-BE7109BF50EF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ex_repquote", "ex_repquote.vcproj", "{E44CEDB8-E7BE-4841-B4F3-FF1781299320}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ex_tpcb", "ex_tpcb.vcproj", "{294338EC-1E7F-43A0-840D-35E6B8ECF583}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "excxx_access", "excxx_access.vcproj", "{6FE52929-FD0C-4673-9386-E872096EAD48}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "excxx_btrec", "excxx_btrec.vcproj", "{8AA09CA2-AB79-4478-A013-D9128980D44F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "excxx_env", "excxx_env.vcproj", "{D95697E8-C637-4201-A7AA-AC38A01568A1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "excxx_lock", "excxx_lock.vcproj", "{A56D9942-B2C9-47C9-9C8D-32415A0B0E53}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "excxx_mpool", "excxx_mpool.vcproj", "{D2AF694E-09F5-4E47-8664-29BFBDB6AC29}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "excxx_tpcb", "excxx_tpcb.vcproj", "{5F59567D-43B0-424D-B46D-FF6F311669FE}" +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + ConfigName.0 = Debug + ConfigName.1 = Debug Static + ConfigName.2 = Release + ConfigName.3 = Release Static + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.1 = {5F59567D-43B0-424D-B46D-FF6F311669FE} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.2 = {D2AF694E-09F5-4E47-8664-29BFBDB6AC29} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.3 = {A56D9942-B2C9-47C9-9C8D-32415A0B0E53} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.4 = {D95697E8-C637-4201-A7AA-AC38A01568A1} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.5 = {8AA09CA2-AB79-4478-A013-D9128980D44F} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.6 = {6FE52929-FD0C-4673-9386-E872096EAD48} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.7 = {294338EC-1E7F-43A0-840D-35E6B8ECF583} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.8 = {45D65648-E766-4202-AFE8-BE7109BF50EF} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.9 = {2B888D16-EC66-4EC3-8EB3-DC88C6B959E5} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.10 = {6A9CC71A-378D-4867-A1A0-4F8F02F58514} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.11 = {7B93303C-96FC-4EDF-A138-AFFF7FB47387} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.12 = {342E52CB-EBD0-4AE8-9195-C170329622F7} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.13 = {E37383A4-BC15-4416-B0D1-D7715470F351} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.14 = {913669D3-CB3A-4EA3-A110-0DDB08BDD8B5} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.15 = {6D2A35F5-B7E8-4156-BA10-EEA3DEFD8FD8} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.16 = {1321D847-2516-4339-A5D1-84582755766D} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.17 = {48ADBC48-D55C-4093-BDC3-3146D5580B67} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.18 = {7CCAE778-C613-4C83-B1EF-97B77FD41316} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.19 = {C99A8B5E-5C40-40BE-83EF-9FB1049025AD} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.20 = {E3BE79CF-6872-41DD-8272-A97A1310421A} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.21 = {F3C2785D-A358-47B1-B818-F5411FB2CB94} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.22 = {A308D79C-9740-4606-B396-6FE5E6E91251} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.23 = {B8BBA6BA-5BC2-4271-BFC4-AF3DB95598D9} + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.24 = {1630D1E0-070A-4B2A-B103-2D3A1D207200} + {1630D1E0-070A-4B2A-B103-2D3A1D207200}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {B8BBA6BA-5BC2-4271-BFC4-AF3DB95598D9}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {A308D79C-9740-4606-B396-6FE5E6E91251}.0 = {F3C2785D-A358-47B1-B818-F5411FB2CB94} + {E3BE79CF-6872-41DD-8272-A97A1310421A}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {A507571D-8904-4621-BB44-29D5ED632ACE}.0 = {F3C2785D-A358-47B1-B818-F5411FB2CB94} + {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9}.0 = {E37383A4-BC15-4416-B0D1-D7715470F351} + {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9}.1 = {F3C2785D-A358-47B1-B818-F5411FB2CB94} + {C99A8B5E-5C40-40BE-83EF-9FB1049025AD}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {7CCAE778-C613-4C83-B1EF-97B77FD41316}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {48ADBC48-D55C-4093-BDC3-3146D5580B67}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {1321D847-2516-4339-A5D1-84582755766D}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {3BBAC089-ED28-4DE6-AE85-B55F2A84CFBB}.0 = {F3C2785D-A358-47B1-B818-F5411FB2CB94} + {EA3BF4FA-D85A-4132-9EC5-991A83F279B3}.0 = {3BBAC089-ED28-4DE6-AE85-B55F2A84CFBB} + {EA3BF4FA-D85A-4132-9EC5-991A83F279B3}.1 = {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208} + {6D2A35F5-B7E8-4156-BA10-EEA3DEFD8FD8}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {913669D3-CB3A-4EA3-A110-0DDB08BDD8B5}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {342E52CB-EBD0-4AE8-9195-C170329622F7}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {7B93303C-96FC-4EDF-A138-AFFF7FB47387}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {6A9CC71A-378D-4867-A1A0-4F8F02F58514}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {2B888D16-EC66-4EC3-8EB3-DC88C6B959E5}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {45D65648-E766-4202-AFE8-BE7109BF50EF}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {E44CEDB8-E7BE-4841-B4F3-FF1781299320}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {294338EC-1E7F-43A0-840D-35E6B8ECF583}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {6FE52929-FD0C-4673-9386-E872096EAD48}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {8AA09CA2-AB79-4478-A013-D9128980D44F}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {D95697E8-C637-4201-A7AA-AC38A01568A1}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {A56D9942-B2C9-47C9-9C8D-32415A0B0E53}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {D2AF694E-09F5-4E47-8664-29BFBDB6AC29}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + {5F59567D-43B0-424D-B46D-FF6F311669FE}.0 = {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9} + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.Debug.ActiveCfg = Debug|Win32 + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.Debug.Build.0 = Debug|Win32 + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.Debug Static.ActiveCfg = Debug Static|Win32 + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.Debug Static.Build.0 = Debug Static|Win32 + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.Release.ActiveCfg = Release|Win32 + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.Release.Build.0 = Release|Win32 + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.Release Static.ActiveCfg = Release Static|Win32 + {DDB8ABA9-3307-4AAA-BEDC-0A3E31339208}.Release Static.Build.0 = Release Static|Win32 + {1630D1E0-070A-4B2A-B103-2D3A1D207200}.Debug.ActiveCfg = Debug|Win32 + {1630D1E0-070A-4B2A-B103-2D3A1D207200}.Debug.Build.0 = Debug|Win32 + {1630D1E0-070A-4B2A-B103-2D3A1D207200}.Debug Static.ActiveCfg = Debug Static|Win32 + {1630D1E0-070A-4B2A-B103-2D3A1D207200}.Debug Static.Build.0 = Debug Static|Win32 + {1630D1E0-070A-4B2A-B103-2D3A1D207200}.Release.ActiveCfg = Release|Win32 + {1630D1E0-070A-4B2A-B103-2D3A1D207200}.Release.Build.0 = Release|Win32 + {1630D1E0-070A-4B2A-B103-2D3A1D207200}.Release Static.ActiveCfg = Release Static|Win32 + {1630D1E0-070A-4B2A-B103-2D3A1D207200}.Release Static.Build.0 = Release Static|Win32 + {B8BBA6BA-5BC2-4271-BFC4-AF3DB95598D9}.Debug.ActiveCfg = Debug|Win32 + {B8BBA6BA-5BC2-4271-BFC4-AF3DB95598D9}.Debug.Build.0 = Debug|Win32 + {B8BBA6BA-5BC2-4271-BFC4-AF3DB95598D9}.Debug Static.ActiveCfg = Debug Static|Win32 + {B8BBA6BA-5BC2-4271-BFC4-AF3DB95598D9}.Debug Static.Build.0 = Debug Static|Win32 + {B8BBA6BA-5BC2-4271-BFC4-AF3DB95598D9}.Release.ActiveCfg = Release|Win32 + {B8BBA6BA-5BC2-4271-BFC4-AF3DB95598D9}.Release.Build.0 = Release|Win32 + {B8BBA6BA-5BC2-4271-BFC4-AF3DB95598D9}.Release Static.ActiveCfg = Release Static|Win32 + {B8BBA6BA-5BC2-4271-BFC4-AF3DB95598D9}.Release Static.Build.0 = Release Static|Win32 + {A308D79C-9740-4606-B396-6FE5E6E91251}.Debug.ActiveCfg = Debug|Win32 + {A308D79C-9740-4606-B396-6FE5E6E91251}.Debug.Build.0 = Debug|Win32 + {A308D79C-9740-4606-B396-6FE5E6E91251}.Debug Static.ActiveCfg = Debug Static|Win32 + {A308D79C-9740-4606-B396-6FE5E6E91251}.Debug Static.Build.0 = Debug Static|Win32 + {A308D79C-9740-4606-B396-6FE5E6E91251}.Release.ActiveCfg = Release|Win32 + {A308D79C-9740-4606-B396-6FE5E6E91251}.Release.Build.0 = Release|Win32 + {A308D79C-9740-4606-B396-6FE5E6E91251}.Release Static.ActiveCfg = Release Static|Win32 + {A308D79C-9740-4606-B396-6FE5E6E91251}.Release Static.Build.0 = Release Static|Win32 + {F3C2785D-A358-47B1-B818-F5411FB2CB94}.Debug.ActiveCfg = Debug|Win32 + {F3C2785D-A358-47B1-B818-F5411FB2CB94}.Debug.Build.0 = Debug|Win32 + {F3C2785D-A358-47B1-B818-F5411FB2CB94}.Debug Static.ActiveCfg = Debug|Win32 + {F3C2785D-A358-47B1-B818-F5411FB2CB94}.Debug Static.Build.0 = Debug|Win32 + {F3C2785D-A358-47B1-B818-F5411FB2CB94}.Release.ActiveCfg = Release|Win32 + {F3C2785D-A358-47B1-B818-F5411FB2CB94}.Release.Build.0 = Release|Win32 + {F3C2785D-A358-47B1-B818-F5411FB2CB94}.Release Static.ActiveCfg = Release|Win32 + {F3C2785D-A358-47B1-B818-F5411FB2CB94}.Release Static.Build.0 = Release|Win32 + {E3BE79CF-6872-41DD-8272-A97A1310421A}.Debug.ActiveCfg = Debug|Win32 + {E3BE79CF-6872-41DD-8272-A97A1310421A}.Debug.Build.0 = Debug|Win32 + {E3BE79CF-6872-41DD-8272-A97A1310421A}.Debug Static.ActiveCfg = Debug Static|Win32 + {E3BE79CF-6872-41DD-8272-A97A1310421A}.Debug Static.Build.0 = Debug Static|Win32 + {E3BE79CF-6872-41DD-8272-A97A1310421A}.Release.ActiveCfg = Release|Win32 + {E3BE79CF-6872-41DD-8272-A97A1310421A}.Release.Build.0 = Release|Win32 + {E3BE79CF-6872-41DD-8272-A97A1310421A}.Release Static.ActiveCfg = Release Static|Win32 + {E3BE79CF-6872-41DD-8272-A97A1310421A}.Release Static.Build.0 = Release Static|Win32 + {A507571D-8904-4621-BB44-29D5ED632ACE}.Debug.ActiveCfg = Debug|Win32 + {A507571D-8904-4621-BB44-29D5ED632ACE}.Debug.Build.0 = Debug|Win32 + {A507571D-8904-4621-BB44-29D5ED632ACE}.Debug Static.ActiveCfg = Debug|Win32 + {A507571D-8904-4621-BB44-29D5ED632ACE}.Debug Static.Build.0 = Debug|Win32 + {A507571D-8904-4621-BB44-29D5ED632ACE}.Release.ActiveCfg = Release|Win32 + {A507571D-8904-4621-BB44-29D5ED632ACE}.Release.Build.0 = Release|Win32 + {A507571D-8904-4621-BB44-29D5ED632ACE}.Release Static.ActiveCfg = Release|Win32 + {A507571D-8904-4621-BB44-29D5ED632ACE}.Release Static.Build.0 = Release|Win32 + {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9}.Debug.ActiveCfg = Debug|Win32 + {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9}.Debug.Build.0 = Debug|Win32 + {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9}.Debug Static.ActiveCfg = Debug Static|Win32 + {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9}.Debug Static.Build.0 = Debug Static|Win32 + {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9}.Release.ActiveCfg = Release|Win32 + {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9}.Release.Build.0 = Release|Win32 + {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9}.Release Static.ActiveCfg = Release Static|Win32 + {A6D2C77C-68F1-4DA7-8D90-97DDAD9639C9}.Release Static.Build.0 = Release Static|Win32 + {C99A8B5E-5C40-40BE-83EF-9FB1049025AD}.Debug.ActiveCfg = Debug|Win32 + {C99A8B5E-5C40-40BE-83EF-9FB1049025AD}.Debug.Build.0 = Debug|Win32 + {C99A8B5E-5C40-40BE-83EF-9FB1049025AD}.Debug Static.ActiveCfg = Debug Static|Win32 + {C99A8B5E-5C40-40BE-83EF-9FB1049025AD}.Debug Static.Build.0 = Debug Static|Win32 + {C99A8B5E-5C40-40BE-83EF-9FB1049025AD}.Release.ActiveCfg = Release|Win32 + {C99A8B5E-5C40-40BE-83EF-9FB1049025AD}.Release.Build.0 = Release|Win32 + {C99A8B5E-5C40-40BE-83EF-9FB1049025AD}.Release Static.ActiveCfg = Release Static|Win32 + {C99A8B5E-5C40-40BE-83EF-9FB1049025AD}.Release Static.Build.0 = Release Static|Win32 + {7CCAE778-C613-4C83-B1EF-97B77FD41316}.Debug.ActiveCfg = Debug|Win32 + {7CCAE778-C613-4C83-B1EF-97B77FD41316}.Debug.Build.0 = Debug|Win32 + {7CCAE778-C613-4C83-B1EF-97B77FD41316}.Debug Static.ActiveCfg = Debug Static|Win32 + {7CCAE778-C613-4C83-B1EF-97B77FD41316}.Debug Static.Build.0 = Debug Static|Win32 + {7CCAE778-C613-4C83-B1EF-97B77FD41316}.Release.ActiveCfg = Release|Win32 + {7CCAE778-C613-4C83-B1EF-97B77FD41316}.Release.Build.0 = Release|Win32 + {7CCAE778-C613-4C83-B1EF-97B77FD41316}.Release Static.ActiveCfg = Release Static|Win32 + {7CCAE778-C613-4C83-B1EF-97B77FD41316}.Release Static.Build.0 = Release Static|Win32 + {48ADBC48-D55C-4093-BDC3-3146D5580B67}.Debug.ActiveCfg = Debug|Win32 + {48ADBC48-D55C-4093-BDC3-3146D5580B67}.Debug.Build.0 = Debug|Win32 + {48ADBC48-D55C-4093-BDC3-3146D5580B67}.Debug Static.ActiveCfg = Debug Static|Win32 + {48ADBC48-D55C-4093-BDC3-3146D5580B67}.Debug Static.Build.0 = Debug Static|Win32 + {48ADBC48-D55C-4093-BDC3-3146D5580B67}.Release.ActiveCfg = Release|Win32 + {48ADBC48-D55C-4093-BDC3-3146D5580B67}.Release.Build.0 = Release|Win32 + {48ADBC48-D55C-4093-BDC3-3146D5580B67}.Release Static.ActiveCfg = Release Static|Win32 + {48ADBC48-D55C-4093-BDC3-3146D5580B67}.Release Static.Build.0 = Release Static|Win32 + {1321D847-2516-4339-A5D1-84582755766D}.Debug.ActiveCfg = Debug|Win32 + {1321D847-2516-4339-A5D1-84582755766D}.Debug.Build.0 = Debug|Win32 + {1321D847-2516-4339-A5D1-84582755766D}.Debug Static.ActiveCfg = Debug Static|Win32 + {1321D847-2516-4339-A5D1-84582755766D}.Debug Static.Build.0 = Debug Static|Win32 + {1321D847-2516-4339-A5D1-84582755766D}.Release.ActiveCfg = Release|Win32 + {1321D847-2516-4339-A5D1-84582755766D}.Release.Build.0 = Release|Win32 + {1321D847-2516-4339-A5D1-84582755766D}.Release Static.ActiveCfg = Release Static|Win32 + {1321D847-2516-4339-A5D1-84582755766D}.Release Static.Build.0 = Release Static|Win32 + {E37383A4-BC15-4416-B0D1-D7715470F351}.Debug.ActiveCfg = Debug Static|Win32 + {E37383A4-BC15-4416-B0D1-D7715470F351}.Debug.Build.0 = Debug Static|Win32 + {E37383A4-BC15-4416-B0D1-D7715470F351}.Debug Static.ActiveCfg = Debug Static|Win32 + {E37383A4-BC15-4416-B0D1-D7715470F351}.Debug Static.Build.0 = Debug Static|Win32 + {E37383A4-BC15-4416-B0D1-D7715470F351}.Release.ActiveCfg = Release Static|Win32 + {E37383A4-BC15-4416-B0D1-D7715470F351}.Release.Build.0 = Release Static|Win32 + {E37383A4-BC15-4416-B0D1-D7715470F351}.Release Static.ActiveCfg = Release Static|Win32 + {E37383A4-BC15-4416-B0D1-D7715470F351}.Release Static.Build.0 = Release Static|Win32 + {3BBAC089-ED28-4DE6-AE85-B55F2A84CFBB}.Debug.ActiveCfg = Debug|Win32 + {3BBAC089-ED28-4DE6-AE85-B55F2A84CFBB}.Debug.Build.0 = Debug|Win32 + {3BBAC089-ED28-4DE6-AE85-B55F2A84CFBB}.Debug Static.ActiveCfg = Debug|Win32 + {3BBAC089-ED28-4DE6-AE85-B55F2A84CFBB}.Debug Static.Build.0 = Debug|Win32 + {3BBAC089-ED28-4DE6-AE85-B55F2A84CFBB}.Release.ActiveCfg = Release|Win32 + {3BBAC089-ED28-4DE6-AE85-B55F2A84CFBB}.Release.Build.0 = Release|Win32 + {3BBAC089-ED28-4DE6-AE85-B55F2A84CFBB}.Release Static.ActiveCfg = Release|Win32 + {3BBAC089-ED28-4DE6-AE85-B55F2A84CFBB}.Release Static.Build.0 = Release|Win32 + {EA3BF4FA-D85A-4132-9EC5-991A83F279B3}.Debug.ActiveCfg = Debug|Win32 + {EA3BF4FA-D85A-4132-9EC5-991A83F279B3}.Debug.Build.0 = Debug|Win32 + {EA3BF4FA-D85A-4132-9EC5-991A83F279B3}.Debug Static.ActiveCfg = Debug|Win32 + {EA3BF4FA-D85A-4132-9EC5-991A83F279B3}.Debug Static.Build.0 = Debug|Win32 + {EA3BF4FA-D85A-4132-9EC5-991A83F279B3}.Release.ActiveCfg = Release|Win32 + {EA3BF4FA-D85A-4132-9EC5-991A83F279B3}.Release.Build.0 = Release|Win32 + {EA3BF4FA-D85A-4132-9EC5-991A83F279B3}.Release Static.ActiveCfg = Release|Win32 + {EA3BF4FA-D85A-4132-9EC5-991A83F279B3}.Release Static.Build.0 = Release|Win32 + {6D2A35F5-B7E8-4156-BA10-EEA3DEFD8FD8}.Debug.ActiveCfg = Debug|Win32 + {6D2A35F5-B7E8-4156-BA10-EEA3DEFD8FD8}.Debug.Build.0 = Debug|Win32 + {6D2A35F5-B7E8-4156-BA10-EEA3DEFD8FD8}.Debug Static.ActiveCfg = Debug Static|Win32 + {6D2A35F5-B7E8-4156-BA10-EEA3DEFD8FD8}.Debug Static.Build.0 = Debug Static|Win32 + {6D2A35F5-B7E8-4156-BA10-EEA3DEFD8FD8}.Release.ActiveCfg = Release|Win32 + {6D2A35F5-B7E8-4156-BA10-EEA3DEFD8FD8}.Release.Build.0 = Release|Win32 + {6D2A35F5-B7E8-4156-BA10-EEA3DEFD8FD8}.Release Static.ActiveCfg = Release Static|Win32 + {6D2A35F5-B7E8-4156-BA10-EEA3DEFD8FD8}.Release Static.Build.0 = Release Static|Win32 + {913669D3-CB3A-4EA3-A110-0DDB08BDD8B5}.Debug.ActiveCfg = Debug|Win32 + {913669D3-CB3A-4EA3-A110-0DDB08BDD8B5}.Debug.Build.0 = Debug|Win32 + {913669D3-CB3A-4EA3-A110-0DDB08BDD8B5}.Debug Static.ActiveCfg = Debug Static|Win32 + {913669D3-CB3A-4EA3-A110-0DDB08BDD8B5}.Debug Static.Build.0 = Debug Static|Win32 + {913669D3-CB3A-4EA3-A110-0DDB08BDD8B5}.Release.ActiveCfg = Release|Win32 + {913669D3-CB3A-4EA3-A110-0DDB08BDD8B5}.Release.Build.0 = Release|Win32 + {913669D3-CB3A-4EA3-A110-0DDB08BDD8B5}.Release Static.ActiveCfg = Release Static|Win32 + {913669D3-CB3A-4EA3-A110-0DDB08BDD8B5}.Release Static.Build.0 = Release Static|Win32 + {342E52CB-EBD0-4AE8-9195-C170329622F7}.Debug.ActiveCfg = Debug|Win32 + {342E52CB-EBD0-4AE8-9195-C170329622F7}.Debug.Build.0 = Debug|Win32 + {342E52CB-EBD0-4AE8-9195-C170329622F7}.Debug Static.ActiveCfg = Debug Static|Win32 + {342E52CB-EBD0-4AE8-9195-C170329622F7}.Debug Static.Build.0 = Debug Static|Win32 + {342E52CB-EBD0-4AE8-9195-C170329622F7}.Release.ActiveCfg = Release|Win32 + {342E52CB-EBD0-4AE8-9195-C170329622F7}.Release.Build.0 = Release|Win32 + {342E52CB-EBD0-4AE8-9195-C170329622F7}.Release Static.ActiveCfg = Release Static|Win32 + {342E52CB-EBD0-4AE8-9195-C170329622F7}.Release Static.Build.0 = Release Static|Win32 + {7B93303C-96FC-4EDF-A138-AFFF7FB47387}.Debug.ActiveCfg = Debug|Win32 + {7B93303C-96FC-4EDF-A138-AFFF7FB47387}.Debug.Build.0 = Debug|Win32 + {7B93303C-96FC-4EDF-A138-AFFF7FB47387}.Debug Static.ActiveCfg = Debug Static|Win32 + {7B93303C-96FC-4EDF-A138-AFFF7FB47387}.Debug Static.Build.0 = Debug Static|Win32 + {7B93303C-96FC-4EDF-A138-AFFF7FB47387}.Release.ActiveCfg = Release|Win32 + {7B93303C-96FC-4EDF-A138-AFFF7FB47387}.Release.Build.0 = Release|Win32 + {7B93303C-96FC-4EDF-A138-AFFF7FB47387}.Release Static.ActiveCfg = Release Static|Win32 + {7B93303C-96FC-4EDF-A138-AFFF7FB47387}.Release Static.Build.0 = Release Static|Win32 + {6A9CC71A-378D-4867-A1A0-4F8F02F58514}.Debug.ActiveCfg = Debug|Win32 + {6A9CC71A-378D-4867-A1A0-4F8F02F58514}.Debug.Build.0 = Debug|Win32 + {6A9CC71A-378D-4867-A1A0-4F8F02F58514}.Debug Static.ActiveCfg = Debug Static|Win32 + {6A9CC71A-378D-4867-A1A0-4F8F02F58514}.Debug Static.Build.0 = Debug Static|Win32 + {6A9CC71A-378D-4867-A1A0-4F8F02F58514}.Release.ActiveCfg = Release|Win32 + {6A9CC71A-378D-4867-A1A0-4F8F02F58514}.Release.Build.0 = Release|Win32 + {6A9CC71A-378D-4867-A1A0-4F8F02F58514}.Release Static.ActiveCfg = Release Static|Win32 + {6A9CC71A-378D-4867-A1A0-4F8F02F58514}.Release Static.Build.0 = Release Static|Win32 + {2B888D16-EC66-4EC3-8EB3-DC88C6B959E5}.Debug.ActiveCfg = Debug|Win32 + {2B888D16-EC66-4EC3-8EB3-DC88C6B959E5}.Debug.Build.0 = Debug|Win32 + {2B888D16-EC66-4EC3-8EB3-DC88C6B959E5}.Debug Static.ActiveCfg = Debug Static|Win32 + {2B888D16-EC66-4EC3-8EB3-DC88C6B959E5}.Debug Static.Build.0 = Debug Static|Win32 + {2B888D16-EC66-4EC3-8EB3-DC88C6B959E5}.Release.ActiveCfg = Release|Win32 + {2B888D16-EC66-4EC3-8EB3-DC88C6B959E5}.Release.Build.0 = Release|Win32 + {2B888D16-EC66-4EC3-8EB3-DC88C6B959E5}.Release Static.ActiveCfg = Release Static|Win32 + {2B888D16-EC66-4EC3-8EB3-DC88C6B959E5}.Release Static.Build.0 = Release Static|Win32 + {45D65648-E766-4202-AFE8-BE7109BF50EF}.Debug.ActiveCfg = Debug|Win32 + {45D65648-E766-4202-AFE8-BE7109BF50EF}.Debug.Build.0 = Debug|Win32 + {45D65648-E766-4202-AFE8-BE7109BF50EF}.Debug Static.ActiveCfg = Debug Static|Win32 + {45D65648-E766-4202-AFE8-BE7109BF50EF}.Debug Static.Build.0 = Debug Static|Win32 + {45D65648-E766-4202-AFE8-BE7109BF50EF}.Release.ActiveCfg = Release|Win32 + {45D65648-E766-4202-AFE8-BE7109BF50EF}.Release.Build.0 = Release|Win32 + {45D65648-E766-4202-AFE8-BE7109BF50EF}.Release Static.ActiveCfg = Release Static|Win32 + {45D65648-E766-4202-AFE8-BE7109BF50EF}.Release Static.Build.0 = Release Static|Win32 + {E44CEDB8-E7BE-4841-B4F3-FF1781299320}.Debug.ActiveCfg = Debug|Win32 + {E44CEDB8-E7BE-4841-B4F3-FF1781299320}.Debug.Build.0 = Debug|Win32 + {E44CEDB8-E7BE-4841-B4F3-FF1781299320}.Debug Static.ActiveCfg = Debug Static|Win32 + {E44CEDB8-E7BE-4841-B4F3-FF1781299320}.Debug Static.Build.0 = Debug Static|Win32 + {E44CEDB8-E7BE-4841-B4F3-FF1781299320}.Release.ActiveCfg = Release|Win32 + {E44CEDB8-E7BE-4841-B4F3-FF1781299320}.Release.Build.0 = Release|Win32 + {E44CEDB8-E7BE-4841-B4F3-FF1781299320}.Release Static.ActiveCfg = Release Static|Win32 + {E44CEDB8-E7BE-4841-B4F3-FF1781299320}.Release Static.Build.0 = Release Static|Win32 + {294338EC-1E7F-43A0-840D-35E6B8ECF583}.Debug.ActiveCfg = Debug|Win32 + {294338EC-1E7F-43A0-840D-35E6B8ECF583}.Debug.Build.0 = Debug|Win32 + {294338EC-1E7F-43A0-840D-35E6B8ECF583}.Debug Static.ActiveCfg = Debug Static|Win32 + {294338EC-1E7F-43A0-840D-35E6B8ECF583}.Debug Static.Build.0 = Debug Static|Win32 + {294338EC-1E7F-43A0-840D-35E6B8ECF583}.Release.ActiveCfg = Release|Win32 + {294338EC-1E7F-43A0-840D-35E6B8ECF583}.Release.Build.0 = Release|Win32 + {294338EC-1E7F-43A0-840D-35E6B8ECF583}.Release Static.ActiveCfg = Release Static|Win32 + {294338EC-1E7F-43A0-840D-35E6B8ECF583}.Release Static.Build.0 = Release Static|Win32 + {6FE52929-FD0C-4673-9386-E872096EAD48}.Debug.ActiveCfg = Debug|Win32 + {6FE52929-FD0C-4673-9386-E872096EAD48}.Debug.Build.0 = Debug|Win32 + {6FE52929-FD0C-4673-9386-E872096EAD48}.Debug Static.ActiveCfg = Debug Static|Win32 + {6FE52929-FD0C-4673-9386-E872096EAD48}.Debug Static.Build.0 = Debug Static|Win32 + {6FE52929-FD0C-4673-9386-E872096EAD48}.Release.ActiveCfg = Release|Win32 + {6FE52929-FD0C-4673-9386-E872096EAD48}.Release.Build.0 = Release|Win32 + {6FE52929-FD0C-4673-9386-E872096EAD48}.Release Static.ActiveCfg = Release Static|Win32 + {6FE52929-FD0C-4673-9386-E872096EAD48}.Release Static.Build.0 = Release Static|Win32 + {8AA09CA2-AB79-4478-A013-D9128980D44F}.Debug.ActiveCfg = Debug|Win32 + {8AA09CA2-AB79-4478-A013-D9128980D44F}.Debug.Build.0 = Debug|Win32 + {8AA09CA2-AB79-4478-A013-D9128980D44F}.Debug Static.ActiveCfg = Debug Static|Win32 + {8AA09CA2-AB79-4478-A013-D9128980D44F}.Debug Static.Build.0 = Debug Static|Win32 + {8AA09CA2-AB79-4478-A013-D9128980D44F}.Release.ActiveCfg = Release|Win32 + {8AA09CA2-AB79-4478-A013-D9128980D44F}.Release.Build.0 = Release|Win32 + {8AA09CA2-AB79-4478-A013-D9128980D44F}.Release Static.ActiveCfg = Release Static|Win32 + {8AA09CA2-AB79-4478-A013-D9128980D44F}.Release Static.Build.0 = Release Static|Win32 + {D95697E8-C637-4201-A7AA-AC38A01568A1}.Debug.ActiveCfg = Debug|Win32 + {D95697E8-C637-4201-A7AA-AC38A01568A1}.Debug.Build.0 = Debug|Win32 + {D95697E8-C637-4201-A7AA-AC38A01568A1}.Debug Static.ActiveCfg = Debug Static|Win32 + {D95697E8-C637-4201-A7AA-AC38A01568A1}.Debug Static.Build.0 = Debug Static|Win32 + {D95697E8-C637-4201-A7AA-AC38A01568A1}.Release.ActiveCfg = Release|Win32 + {D95697E8-C637-4201-A7AA-AC38A01568A1}.Release.Build.0 = Release|Win32 + {D95697E8-C637-4201-A7AA-AC38A01568A1}.Release Static.ActiveCfg = Release Static|Win32 + {D95697E8-C637-4201-A7AA-AC38A01568A1}.Release Static.Build.0 = Release Static|Win32 + {A56D9942-B2C9-47C9-9C8D-32415A0B0E53}.Debug.ActiveCfg = Debug|Win32 + {A56D9942-B2C9-47C9-9C8D-32415A0B0E53}.Debug.Build.0 = Debug|Win32 + {A56D9942-B2C9-47C9-9C8D-32415A0B0E53}.Debug Static.ActiveCfg = Debug Static|Win32 + {A56D9942-B2C9-47C9-9C8D-32415A0B0E53}.Debug Static.Build.0 = Debug Static|Win32 + {A56D9942-B2C9-47C9-9C8D-32415A0B0E53}.Release.ActiveCfg = Release|Win32 + {A56D9942-B2C9-47C9-9C8D-32415A0B0E53}.Release.Build.0 = Release|Win32 + {A56D9942-B2C9-47C9-9C8D-32415A0B0E53}.Release Static.ActiveCfg = Release Static|Win32 + {A56D9942-B2C9-47C9-9C8D-32415A0B0E53}.Release Static.Build.0 = Release Static|Win32 + {D2AF694E-09F5-4E47-8664-29BFBDB6AC29}.Debug.ActiveCfg = Debug|Win32 + {D2AF694E-09F5-4E47-8664-29BFBDB6AC29}.Debug.Build.0 = Debug|Win32 + {D2AF694E-09F5-4E47-8664-29BFBDB6AC29}.Debug Static.ActiveCfg = Debug Static|Win32 + {D2AF694E-09F5-4E47-8664-29BFBDB6AC29}.Debug Static.Build.0 = Debug Static|Win32 + {D2AF694E-09F5-4E47-8664-29BFBDB6AC29}.Release.ActiveCfg = Release|Win32 + {D2AF694E-09F5-4E47-8664-29BFBDB6AC29}.Release.Build.0 = Release|Win32 + {D2AF694E-09F5-4E47-8664-29BFBDB6AC29}.Release Static.ActiveCfg = Release Static|Win32 + {D2AF694E-09F5-4E47-8664-29BFBDB6AC29}.Release Static.Build.0 = Release Static|Win32 + {5F59567D-43B0-424D-B46D-FF6F311669FE}.Debug.ActiveCfg = Debug|Win32 + {5F59567D-43B0-424D-B46D-FF6F311669FE}.Debug.Build.0 = Debug|Win32 + {5F59567D-43B0-424D-B46D-FF6F311669FE}.Debug Static.ActiveCfg = Debug Static|Win32 + {5F59567D-43B0-424D-B46D-FF6F311669FE}.Debug Static.Build.0 = Debug Static|Win32 + {5F59567D-43B0-424D-B46D-FF6F311669FE}.Release.ActiveCfg = Release|Win32 + {5F59567D-43B0-424D-B46D-FF6F311669FE}.Release.Build.0 = Release|Win32 + {5F59567D-43B0-424D-B46D-FF6F311669FE}.Release Static.ActiveCfg = Release Static|Win32 + {5F59567D-43B0-424D-B46D-FF6F311669FE}.Release Static.Build.0 = Release Static|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/contrib/db/build_win32/Makefile.MinGW b/src/libs/resiprocate/contrib/db/build_win32/Makefile.MinGW new file mode 100644 index 00000000..84ba7fa5 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/Makefile.MinGW @@ -0,0 +1,253 @@ +SOURCE += ../btree/bt_compare.c +SOURCE += ../btree/bt_conv.c +SOURCE += ../btree/bt_curadj.c +SOURCE += ../btree/bt_cursor.c +SOURCE += ../btree/bt_delete.c +SOURCE += ../btree/bt_method.c +SOURCE += ../btree/bt_open.c +SOURCE += ../btree/bt_put.c +SOURCE += ../btree/bt_rec.c +SOURCE += ../btree/bt_reclaim.c +SOURCE += ../btree/bt_recno.c +SOURCE += ../btree/bt_rsearch.c +SOURCE += ../btree/bt_search.c +SOURCE += ../btree/bt_split.c +SOURCE += ../btree/bt_stat.c +SOURCE += ../btree/bt_upgrade.c +SOURCE += ../btree/bt_verify.c +SOURCE += ../btree/btree_auto.c +SOURCE += ../clib/strcasecmp.c +SOURCE += ../common/crypto_stub.c +SOURCE += ../common/db_byteorder.c +SOURCE += ../common/db_err.c +SOURCE += ../common/db_getlong.c +SOURCE += ../common/db_idspace.c +SOURCE += ../common/db_log2.c +SOURCE += ../common/util_cache.c +SOURCE += ../common/util_log.c +SOURCE += ../common/util_sig.c +SOURCE += ../cxx/cxx_db.cpp +SOURCE += ../cxx/cxx_dbc.cpp +SOURCE += ../cxx/cxx_dbt.cpp +SOURCE += ../cxx/cxx_env.cpp +SOURCE += ../cxx/cxx_except.cpp +SOURCE += ../cxx/cxx_lock.cpp +SOURCE += ../cxx/cxx_logc.cpp +SOURCE += ../cxx/cxx_mpool.cpp +SOURCE += ../cxx/cxx_multi.cpp +SOURCE += ../cxx/cxx_seq.cpp +SOURCE += ../cxx/cxx_txn.cpp +SOURCE += ../db/crdel_auto.c +SOURCE += ../db/crdel_rec.c +SOURCE += ../db/db.c +SOURCE += ../db/db_am.c +SOURCE += ../db/db_auto.c +SOURCE += ../db/db_cam.c +SOURCE += ../db/db_conv.c +SOURCE += ../db/db_dispatch.c +SOURCE += ../db/db_dup.c +SOURCE += ../db/db_iface.c +SOURCE += ../db/db_join.c +SOURCE += ../db/db_meta.c +SOURCE += ../db/db_method.c +SOURCE += ../db/db_open.c +SOURCE += ../db/db_overflow.c +SOURCE += ../db/db_ovfl_vrfy.c +SOURCE += ../db/db_pr.c +SOURCE += ../db/db_rec.c +SOURCE += ../db/db_reclaim.c +SOURCE += ../db/db_remove.c +SOURCE += ../db/db_rename.c +SOURCE += ../db/db_ret.c +SOURCE += ../db/db_setid.c +SOURCE += ../db/db_setlsn.c +SOURCE += ../db/db_stati.c +SOURCE += ../db/db_truncate.c +SOURCE += ../db/db_upg.c +SOURCE += ../db/db_upg_opd.c +SOURCE += ../db/db_vrfy.c +SOURCE += ../db/db_vrfyutil.c +SOURCE += ../dbm/dbm.c +SOURCE += ../dbreg/dbreg.c +SOURCE += ../dbreg/dbreg_auto.c +SOURCE += ../dbreg/dbreg_rec.c +SOURCE += ../dbreg/dbreg_stat.c +SOURCE += ../dbreg/dbreg_util.c +SOURCE += ../env/db_salloc.c +SOURCE += ../env/db_shash.c +SOURCE += ../env/env_file.c +SOURCE += ../env/env_method.c +SOURCE += ../env/env_open.c +SOURCE += ../env/env_recover.c +SOURCE += ../env/env_region.c +SOURCE += ../env/env_stat.c +SOURCE += ../fileops/fileops_auto.c +SOURCE += ../fileops/fop_basic.c +SOURCE += ../fileops/fop_rec.c +SOURCE += ../fileops/fop_util.c +SOURCE += ../hash/hash.c +SOURCE += ../hash/hash_auto.c +SOURCE += ../hash/hash_conv.c +SOURCE += ../hash/hash_dup.c +SOURCE += ../hash/hash_func.c +SOURCE += ../hash/hash_meta.c +SOURCE += ../hash/hash_method.c +SOURCE += ../hash/hash_open.c +SOURCE += ../hash/hash_page.c +SOURCE += ../hash/hash_rec.c +SOURCE += ../hash/hash_reclaim.c +SOURCE += ../hash/hash_stat.c +SOURCE += ../hash/hash_upgrade.c +SOURCE += ../hash/hash_verify.c +SOURCE += ../hmac/hmac.c +SOURCE += ../hmac/sha1.c +SOURCE += ../hsearch/hsearch.c +SOURCE += ../lock/lock.c +SOURCE += ../lock/lock_deadlock.c +SOURCE += ../lock/lock_id.c +SOURCE += ../lock/lock_list.c +SOURCE += ../lock/lock_method.c +SOURCE += ../lock/lock_region.c +SOURCE += ../lock/lock_stat.c +SOURCE += ../lock/lock_timer.c +SOURCE += ../lock/lock_util.c +SOURCE += ../log/log.c +SOURCE += ../log/log_archive.c +SOURCE += ../log/log_compare.c +SOURCE += ../log/log_get.c +SOURCE += ../log/log_method.c +SOURCE += ../log/log_put.c +SOURCE += ../log/log_stat.c +SOURCE += ../mp/mp_alloc.c +SOURCE += ../mp/mp_bh.c +SOURCE += ../mp/mp_fget.c +SOURCE += ../mp/mp_fmethod.c +SOURCE += ../mp/mp_fopen.c +SOURCE += ../mp/mp_fput.c +SOURCE += ../mp/mp_fset.c +SOURCE += ../mp/mp_method.c +SOURCE += ../mp/mp_region.c +SOURCE += ../mp/mp_register.c +SOURCE += ../mp/mp_stat.c +SOURCE += ../mp/mp_sync.c +SOURCE += ../mp/mp_trickle.c +SOURCE += ../mutex/mut_win32.c +SOURCE += ../mutex/mutex.c +SOURCE += ../os/os_alloc.c +SOURCE += ../os/os_id.c +SOURCE += ../os/os_method.c +SOURCE += ../os/os_oflags.c +SOURCE += ../os/os_region.c +SOURCE += ../os/os_root.c +SOURCE += ../os/os_rpath.c +SOURCE += ../os/os_tmpdir.c +SOURCE += ../os_win32/os_abs.c +SOURCE += ../os_win32/os_clock.c +SOURCE += ../os_win32/os_config.c +SOURCE += ../os_win32/os_dir.c +SOURCE += ../os_win32/os_errno.c +SOURCE += ../os_win32/os_fid.c +SOURCE += ../os_win32/os_fsync.c +SOURCE += ../os_win32/os_handle.c +SOURCE += ../os_win32/os_map.c +SOURCE += ../os_win32/os_open.c +SOURCE += ../os_win32/os_rename.c +SOURCE += ../os_win32/os_rw.c +SOURCE += ../os_win32/os_seek.c +SOURCE += ../os_win32/os_sleep.c +SOURCE += ../os_win32/os_spin.c +SOURCE += ../os_win32/os_stat.c +SOURCE += ../os_win32/os_truncate.c +SOURCE += ../os_win32/os_unlink.c +SOURCE += ../qam/qam.c +SOURCE += ../qam/qam_auto.c +SOURCE += ../qam/qam_conv.c +SOURCE += ../qam/qam_files.c +SOURCE += ../qam/qam_method.c +SOURCE += ../qam/qam_open.c +SOURCE += ../qam/qam_rec.c +SOURCE += ../qam/qam_stat.c +SOURCE += ../qam/qam_upgrade.c +SOURCE += ../qam/qam_verify.c +SOURCE += ../rep/rep_auto.c +SOURCE += ../rep/rep_backup.c +SOURCE += ../rep/rep_method.c +SOURCE += ../rep/rep_record.c +SOURCE += ../rep/rep_region.c +SOURCE += ../rep/rep_stat.c +SOURCE += ../rep/rep_util.c +SOURCE += ../sequence/seq_stat.c +SOURCE += ../sequence/sequence.c +SOURCE += ../txn/txn.c +SOURCE += ../txn/txn_auto.c +SOURCE += ../txn/txn_method.c +SOURCE += ../txn/txn_rec.c +SOURCE += ../txn/txn_recover.c +SOURCE += ../txn/txn_region.c +SOURCE += ../txn/txn_stat.c +SOURCE += ../txn/txn_util.c +SOURCE += ../xa/xa.c +SOURCE += ../xa/xa_db.c +SOURCE += ../xa/xa_map.c + +OBJS := $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SOURCE))) +CFLAGS := -finline -I. -I.. -DWIN32 -DNDEBUG -D_WINDOWS -Wall +CFLAGS += -DHAVE_MUTEX_WIN32_GCC +CPPFLAGS := $(CFLAGS) + +libdb-4.2.a: $(OBJS) + $(AR) r $@ $^ + ranlib $@ + +clean: + $(RM) $(OBJS) libdb-4.2.a + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# . +# +############################################################################## diff --git a/src/libs/resiprocate/contrib/db/build_win32/app_dsp.src b/src/libs/resiprocate/contrib/db/build_win32/app_dsp.src new file mode 100644 index 00000000..cc4d0bab --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/app_dsp.src @@ -0,0 +1,145 @@ +# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=@project_name@ - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "@project_name@ - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "@project_name@ - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "@project_name@ - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "@project_name@ - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "@project_name@ - Win32 Release" +# Name "@project_name@ - Win32 Debug" +# Name "@project_name@ - Win32 Release Static" +# Name "@project_name@ - Win32 Debug Static" +@SOURCE_FILES@ +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/build_all.dsp b/src/libs/resiprocate/contrib/db/build_win32/build_all.dsp new file mode 100644 index 00000000..e9029b07 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/build_all.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="build_all" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Generic Project" 0x010a + +CFG=build_all - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "build_all.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "build_all.mak" CFG="build_all - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "build_all - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "build_all - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE "build_all - Win32 Release Static" (based on "Win32 (x86) External Target") +!MESSAGE "build_all - Win32 Debug Static" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "build_all - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "echo DB Release version built." +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "build_all - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "echo DB Debug version built." +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "build_all - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_static" +# PROP BASE Intermediate_Dir "Release_static" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Cmd_Line "echo DB Release Static version built." +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "build_all - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_static" +# PROP BASE Intermediate_Dir "Debug_Static" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_Static" +# PROP Cmd_Line "echo DB Debug Static version built." +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "build_all - Win32 Release" +# Name "build_all - Win32 Debug" +# Name "build_all - Win32 Release Static" +# Name "build_all - Win32 Debug Static" +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/build_all.vcproj b/src/libs/resiprocate/contrib/db/build_win32/build_all.vcproj new file mode 100644 index 00000000..2e3c2755 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/build_all.vcproj @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db.h b/src/libs/resiprocate/contrib/db/build_win32/db.h new file mode 100644 index 00000000..6ab40b6b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db.h @@ -0,0 +1,2245 @@ +/* DO NOT EDIT: automatically built by dist/s_win32. */ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2004 + * Sleepycat Software. All rights reserved. + * + * $Id: db.in,v 11.463 2004/10/11 18:47:50 bostic Exp $ + * + * db.h include file layout: + * General. + * Database Environment. + * Locking subsystem. + * Logging subsystem. + * Shared buffer cache (mpool) subsystem. + * Transaction subsystem. + * Access methods. + * Access method cursors. + * Dbm/Ndbm, Hsearch historic interfaces. + */ + +#ifndef _DB_H_ +#define _DB_H_ + +#ifndef __NO_SYSTEM_INCLUDES +#include +#include +#include +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + +#undef __P +#define __P(protos) protos + +/* + * Berkeley DB version information. + */ +#define DB_VERSION_MAJOR 4 +#define DB_VERSION_MINOR 3 +#define DB_VERSION_PATCH 27 +#define DB_VERSION_STRING "Sleepycat Software: Berkeley DB 4.3.27: (December 22, 2004)" + +/* + * !!! + * Berkeley DB uses specifically sized types. If they're not provided by + * the system, typedef them here. + * + * We protect them against multiple inclusion using __BIT_TYPES_DEFINED__, + * as does BIND and Kerberos, since we don't know for sure what #include + * files the user is using. + * + * !!! + * We also provide the standard u_int, u_long etc., if they're not provided + * by the system. + */ +#ifndef __BIT_TYPES_DEFINED__ +#define __BIT_TYPES_DEFINED__ +typedef unsigned char u_int8_t; +typedef short int16_t; +typedef unsigned short u_int16_t; +typedef int int32_t; +typedef unsigned int u_int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 u_int64_t; +#endif + +#ifndef _WINSOCKAPI_ +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; +#endif + +#ifndef __GNUC__ +#ifdef _WIN64 +typedef int64_t ssize_t; +#else +typedef int32_t ssize_t; +#endif +#endif + +/* + * uintmax_t -- + * Largest unsigned type, used to align structures in memory. We don't store + * floating point types in structures, so integral types should be sufficient + * (and we don't have to worry about systems that store floats in other than + * power-of-2 numbers of bytes). Additionally this fixes compilers that rewrite + * structure assignments and ANSI C memcpy calls to be in-line instructions + * that happen to require alignment. Note: this alignment isn't sufficient for + * mutexes, which depend on things like cache line alignment. Mutex alignment + * is handled separately, in mutex.h. + * + * uintptr_t -- + * Unsigned type that's the same size as a pointer. There are places where + * DB modifies pointers by discarding the bottom bits to guarantee alignment. + * We can't use uintmax_t, it may be larger than the pointer, and compilers + * get upset about that. So far we haven't run on any machine where there's + * no unsigned type the same size as a pointer -- here's hoping. + */ +typedef u_int64_t uintmax_t; +#ifdef _WIN64 +typedef u_int64_t uintptr_t; +#else +typedef u_int32_t uintptr_t; +#endif + +/* + * Sequences are only available on machines with 64-bit integral types. + */ +typedef int64_t db_seq_t; + +/* Basic types that are exported or quasi-exported. */ +typedef u_int32_t db_pgno_t; /* Page number type. */ +typedef u_int16_t db_indx_t; /* Page offset type. */ +#define DB_MAX_PAGES 0xffffffff /* >= # of pages in a file */ + +typedef u_int32_t db_recno_t; /* Record number type. */ +#define DB_MAX_RECORDS 0xffffffff /* >= # of records in a tree */ + +typedef u_int32_t db_timeout_t; /* Type of a timeout. */ + +/* + * Region offsets are the difference between a pointer in a region and the + * region's base address. With private environments, both addresses are the + * result of calling malloc, and we can't assume anything about what malloc + * will return, so region offsets have to be able to hold differences between + * arbitrary pointers. + */ +typedef uintptr_t roff_t; + +/* + * Forward structure declarations, so we can declare pointers and + * applications can get type checking. + */ +struct __db; typedef struct __db DB; +struct __db_bt_stat; typedef struct __db_bt_stat DB_BTREE_STAT; +struct __db_cipher; typedef struct __db_cipher DB_CIPHER; +struct __db_dbt; typedef struct __db_dbt DBT; +struct __db_env; typedef struct __db_env DB_ENV; +struct __db_h_stat; typedef struct __db_h_stat DB_HASH_STAT; +struct __db_ilock; typedef struct __db_ilock DB_LOCK_ILOCK; +struct __db_lock_stat; typedef struct __db_lock_stat DB_LOCK_STAT; +struct __db_lock_u; typedef struct __db_lock_u DB_LOCK; +struct __db_lockreq; typedef struct __db_lockreq DB_LOCKREQ; +struct __db_log_cursor; typedef struct __db_log_cursor DB_LOGC; +struct __db_log_stat; typedef struct __db_log_stat DB_LOG_STAT; +struct __db_lsn; typedef struct __db_lsn DB_LSN; +struct __db_mpool; typedef struct __db_mpool DB_MPOOL; +struct __db_mpool_fstat;typedef struct __db_mpool_fstat DB_MPOOL_FSTAT; +struct __db_mpool_stat; typedef struct __db_mpool_stat DB_MPOOL_STAT; +struct __db_mpoolfile; typedef struct __db_mpoolfile DB_MPOOLFILE; +struct __db_preplist; typedef struct __db_preplist DB_PREPLIST; +struct __db_qam_stat; typedef struct __db_qam_stat DB_QUEUE_STAT; +struct __db_rep; typedef struct __db_rep DB_REP; +struct __db_rep_stat; typedef struct __db_rep_stat DB_REP_STAT; +struct __db_sequence; typedef struct __db_sequence DB_SEQUENCE; +struct __db_seq_record; typedef struct __db_seq_record DB_SEQ_RECORD; +struct __db_seq_stat; typedef struct __db_seq_stat DB_SEQUENCE_STAT; +struct __db_txn; typedef struct __db_txn DB_TXN; +struct __db_txn_active; typedef struct __db_txn_active DB_TXN_ACTIVE; +struct __db_txn_stat; typedef struct __db_txn_stat DB_TXN_STAT; +struct __db_txnmgr; typedef struct __db_txnmgr DB_TXNMGR; +struct __dbc; typedef struct __dbc DBC; +struct __dbc_internal; typedef struct __dbc_internal DBC_INTERNAL; +struct __fh_t; typedef struct __fh_t DB_FH; +struct __fname; typedef struct __fname FNAME; +struct __key_range; typedef struct __key_range DB_KEY_RANGE; +struct __mpoolfile; typedef struct __mpoolfile MPOOLFILE; +struct __mutex_t; typedef struct __mutex_t DB_MUTEX; + +/* Key/data structure -- a Data-Base Thang. */ +struct __db_dbt { + /* + * data/size must be fields 1 and 2 for DB 1.85 compatibility. + */ + void *data; /* Key/data */ + u_int32_t size; /* key/data length */ + + u_int32_t ulen; /* RO: length of user buffer. */ + u_int32_t dlen; /* RO: get/put record length. */ + u_int32_t doff; /* RO: get/put record offset. */ + +#define DB_DBT_APPMALLOC 0x001 /* Callback allocated memory. */ +#define DB_DBT_ISSET 0x002 /* Lower level calls set value. */ +#define DB_DBT_MALLOC 0x004 /* Return in malloc'd memory. */ +#define DB_DBT_PARTIAL 0x008 /* Partial put/get. */ +#define DB_DBT_REALLOC 0x010 /* Return in realloc'd memory. */ +#define DB_DBT_USERMEM 0x020 /* Return in user's memory. */ +#define DB_DBT_DUPOK 0x040 /* Insert if duplicate. */ + u_int32_t flags; +}; + +/* + * Common flags -- + * Interfaces which use any of these common flags should never have + * interface specific flags in this range. + */ +#define DB_CREATE 0x0000001 /* Create file as necessary. */ +#define DB_CXX_NO_EXCEPTIONS 0x0000002 /* C++: return error values. */ +#define DB_FORCE 0x0000004 /* Force (anything). */ +#define DB_NOMMAP 0x0000008 /* Don't mmap underlying file. */ +#define DB_RDONLY 0x0000010 /* Read-only (O_RDONLY). */ +#define DB_RECOVER 0x0000020 /* Run normal recovery. */ +#define DB_THREAD 0x0000040 /* Applications are threaded. */ +#define DB_TRUNCATE 0x0000080 /* Discard existing DB (O_TRUNC). */ +#define DB_TXN_NOSYNC 0x0000100 /* Do not sync log on commit. */ +#define DB_TXN_NOT_DURABLE 0x0000200 /* Do not log changes. */ +#define DB_USE_ENVIRON 0x0000400 /* Use the environment. */ +#define DB_USE_ENVIRON_ROOT 0x0000800 /* Use the environment if root. */ + +/* + * Common flags -- + * Interfaces which use any of these common flags should never have + * interface specific flags in this range. + * + * DB_AUTO_COMMIT: + * DB_ENV->set_flags, DB->associate, DB->del, DB->put, DB->open, + * DB->remove, DB->rename, DB->truncate + * DB_DEGREE_2: + * DB->cursor, DB->get, DB->join, DBcursor->c_get, DB_ENV->txn_begin + * DB_DIRTY_READ: + * DB->cursor, DB->get, DB->join, DB->open, DBcursor->c_get, + * DB_ENV->txn_begin + * DB_NOAUTO_COMMIT + * DB->associate, DB->del, DB->put, DB->open, + * DB->remove, DB->rename, DB->truncate + * + * !!! + * The DB_DIRTY_READ and DB_DEGREE_2 bit masks can't be changed without + * also changing the masks for the flags that can be OR'd into DB + * access method and cursor operation values. + */ +#define DB_AUTO_COMMIT 0x01000000/* Implied transaction. */ +#define DB_DEGREE_2 0x02000000/* Degree 2. */ +#define DB_DIRTY_READ 0x04000000/* Dirty Read. */ +#define DB_NO_AUTO_COMMIT 0x08000000/* Override env-wide AUTOCOMMIT. */ + +/* + * Flags private to db_env_create. + */ +#define DB_RPCCLIENT 0x0000001 /* An RPC client environment. */ + +/* + * Flags private to db_create. + */ +#define DB_REP_CREATE 0x0000001 /* Open of an internal rep database. */ +#define DB_XA_CREATE 0x0000002 /* Open in an XA environment. */ + +/* + * Flags private to DB_ENV->open. + * Shared flags up to 0x0000800 */ +#define DB_INIT_CDB 0x0001000 /* Concurrent Access Methods. */ +#define DB_INIT_LOCK 0x0002000 /* Initialize locking. */ +#define DB_INIT_LOG 0x0004000 /* Initialize logging. */ +#define DB_INIT_MPOOL 0x0008000 /* Initialize mpool. */ +#define DB_INIT_REP 0x0010000 /* Initialize replication. */ +#define DB_INIT_TXN 0x0020000 /* Initialize transactions. */ +#define DB_JOINENV 0x0040000 /* Initialize all subsystems present. */ +#define DB_LOCKDOWN 0x0080000 /* Lock memory into physical core. */ +#define DB_PRIVATE 0x0100000 /* DB_ENV is process local. */ +#define DB_RECOVER_FATAL 0x0200000 /* Run catastrophic recovery. */ +#define DB_SYSTEM_MEM 0x0400000 /* Use system-backed memory. */ + +/* + * Flags private to DB->open. + * Shared flags up to 0x0000800 */ +#define DB_EXCL 0x0001000 /* Exclusive open (O_EXCL). */ +#define DB_FCNTL_LOCKING 0x0002000 /* UNDOC: fcntl(2) locking. */ +#define DB_RDWRMASTER 0x0004000 /* UNDOC: allow subdb master open R/W */ +#define DB_WRITEOPEN 0x0008000 /* UNDOC: open with write lock. */ + +/* + * Flags private to DB_ENV->txn_begin. + * Shared flags up to 0x0000800 */ +#define DB_TXN_NOWAIT 0x0001000 /* Do not wait for locks in this TXN. */ +#define DB_TXN_SYNC 0x0002000 /* Always sync log on commit. */ + +/* + * Flags private to DB_ENV->set_encrypt. + */ +#define DB_ENCRYPT_AES 0x0000001 /* AES, assumes SHA1 checksum */ + +/* + * Flags private to DB_ENV->set_flags. + * Shared flags up to 0x00000800 */ +#define DB_CDB_ALLDB 0x00001000/* Set CDB locking per environment. */ +#define DB_DIRECT_DB 0x00002000/* Don't buffer databases in the OS. */ +#define DB_DIRECT_LOG 0x00004000/* Don't buffer log files in the OS. */ +#define DB_DSYNC_LOG 0x00008000/* Set O_DSYNC on the log. */ +#define DB_LOG_AUTOREMOVE 0x00010000/* Automatically remove log files. */ +#define DB_LOG_INMEMORY 0x00020000/* Store logs in buffers in memory. */ +#define DB_NOLOCKING 0x00040000/* Set locking/mutex behavior. */ +#define DB_NOPANIC 0x00080000/* Set panic state per DB_ENV. */ +#define DB_OVERWRITE 0x00100000/* Overwrite unlinked region files. */ +#define DB_PANIC_ENVIRONMENT 0x00200000/* Set panic state per environment. */ +#define DB_REGION_INIT 0x00400000/* Page-fault regions on open. */ +#define DB_TIME_NOTGRANTED 0x00800000/* Return NOTGRANTED on timeout. */ +/* Shared flags at 0x01000000 */ +/* Shared flags at 0x02000000 */ +/* Shared flags at 0x04000000 */ +/* Shared flags at 0x08000000 */ +#define DB_TXN_WRITE_NOSYNC 0x10000000/* Write, don't sync, on txn commit. */ +#define DB_YIELDCPU 0x20000000/* Yield the CPU (a lot). */ + +/* + * Flags private to DB->set_feedback's callback. + */ +#define DB_UPGRADE 0x0000001 /* Upgrading. */ +#define DB_VERIFY 0x0000002 /* Verifying. */ + +/* + * Flags private to DB_MPOOLFILE->open. + * Shared flags up to 0x0000800 */ +#define DB_DIRECT 0x0001000 /* Don't buffer the file in the OS. */ +#define DB_DURABLE_UNKNOWN 0x0002000 /* internal: durability on open. */ +#define DB_EXTENT 0x0004000 /* internal: dealing with an extent. */ +#define DB_ODDFILESIZE 0x0008000 /* Truncate file to N * pgsize. */ + +/* + * Flags private to DB->set_flags. + */ +#define DB_CHKSUM 0x0000001 /* Do checksumming */ +#define DB_DUP 0x0000002 /* Btree, Hash: duplicate keys. */ +#define DB_DUPSORT 0x0000004 /* Btree, Hash: duplicate keys. */ +#define DB_ENCRYPT 0x0000008 /* Btree, Hash: duplicate keys. */ +#define DB_INORDER 0x0000010 /* Queue: strict ordering on consume. */ +#define DB_RECNUM 0x0000020 /* Btree: record numbers. */ +#define DB_RENUMBER 0x0000040 /* Recno: renumber on insert/delete. */ +#define DB_REVSPLITOFF 0x0000080 /* Btree: turn off reverse splits. */ +#define DB_SNAPSHOT 0x0000100 /* Recno: snapshot the input. */ + +/* + * Flags private to the DB_ENV->stat_print, DB->stat and DB->stat_print methods. + */ +#define DB_STAT_ALL 0x0000001 /* Print: Everything. */ +#define DB_STAT_CLEAR 0x0000002 /* Clear stat after returning values. */ +#define DB_STAT_LOCK_CONF 0x0000004 /* Print: Lock conflict matrix. */ +#define DB_STAT_LOCK_LOCKERS 0x0000008 /* Print: Lockers. */ +#define DB_STAT_LOCK_OBJECTS 0x0000010 /* Print: Lock objects. */ +#define DB_STAT_LOCK_PARAMS 0x0000020 /* Print: Lock parameters. */ +#define DB_STAT_MEMP_HASH 0x0000040 /* Print: Mpool hash buckets. */ +#define DB_STAT_SUBSYSTEM 0x0000080 /* Print: Subsystems too. */ + +/* + * Flags private to DB->join. + */ +#define DB_JOIN_NOSORT 0x0000001 /* Don't try to optimize join. */ + +/* + * Flags private to DB->verify. + */ +#define DB_AGGRESSIVE 0x0000001 /* Salvage whatever could be data.*/ +#define DB_NOORDERCHK 0x0000002 /* Skip sort order/hashing check. */ +#define DB_ORDERCHKONLY 0x0000004 /* Only perform the order check. */ +#define DB_PR_PAGE 0x0000008 /* Show page contents (-da). */ +#define DB_PR_RECOVERYTEST 0x0000010 /* Recovery test (-dr). */ +#define DB_PRINTABLE 0x0000020 /* Use printable format for salvage. */ +#define DB_SALVAGE 0x0000040 /* Salvage what looks like data. */ +#define DB_UNREF 0x0000080 /* Report unreferenced pages. */ +/* + * !!! + * These must not go over 0x8000, or they will collide with the flags + * used by __bam_vrfy_subtree. + */ + +/* + * Flags private to DB->set_rep_transport's send callback. + */ +#define DB_REP_NOBUFFER 0x0000001 /* Do not buffer this message. */ +#define DB_REP_PERMANENT 0x0000002 /* Important--app. may want to flush. */ + +/******************************************************* + * Locking. + *******************************************************/ +#define DB_LOCKVERSION 1 + +#define DB_FILE_ID_LEN 20 /* Unique file ID length. */ + +/* + * Deadlock detector modes; used in the DB_ENV structure to configure the + * locking subsystem. + */ +#define DB_LOCK_NORUN 0 +#define DB_LOCK_DEFAULT 1 /* Default policy. */ +#define DB_LOCK_EXPIRE 2 /* Only expire locks, no detection. */ +#define DB_LOCK_MAXLOCKS 3 /* Select locker with max locks. */ +#define DB_LOCK_MAXWRITE 4 /* Select locker with max writelocks. */ +#define DB_LOCK_MINLOCKS 5 /* Select locker with min locks. */ +#define DB_LOCK_MINWRITE 6 /* Select locker with min writelocks. */ +#define DB_LOCK_OLDEST 7 /* Select oldest locker. */ +#define DB_LOCK_RANDOM 8 /* Select random locker. */ +#define DB_LOCK_YOUNGEST 9 /* Select youngest locker. */ + +/* Flag values for lock_vec(), lock_get(). */ +#define DB_LOCK_ABORT 0x001 /* Internal: Lock during abort. */ +#define DB_LOCK_NOWAIT 0x002 /* Don't wait on unavailable lock. */ +#define DB_LOCK_RECORD 0x004 /* Internal: record lock. */ +#define DB_LOCK_REMOVE 0x008 /* Internal: flag object removed. */ +#define DB_LOCK_SET_TIMEOUT 0x010 /* Internal: set lock timeout. */ +#define DB_LOCK_SWITCH 0x020 /* Internal: switch existing lock. */ +#define DB_LOCK_UPGRADE 0x040 /* Internal: upgrade existing lock. */ + +/* + * Simple R/W lock modes and for multi-granularity intention locking. + * + * !!! + * These values are NOT random, as they are used as an index into the lock + * conflicts arrays, i.e., DB_LOCK_IWRITE must be == 3, and DB_LOCK_IREAD + * must be == 4. + */ +typedef enum { + DB_LOCK_NG=0, /* Not granted. */ + DB_LOCK_READ=1, /* Shared/read. */ + DB_LOCK_WRITE=2, /* Exclusive/write. */ + DB_LOCK_WAIT=3, /* Wait for event */ + DB_LOCK_IWRITE=4, /* Intent exclusive/write. */ + DB_LOCK_IREAD=5, /* Intent to share/read. */ + DB_LOCK_IWR=6, /* Intent to read and write. */ + DB_LOCK_DIRTY=7, /* Dirty Read. */ + DB_LOCK_WWRITE=8 /* Was Written. */ +} db_lockmode_t; + +/* + * Request types. + */ +typedef enum { + DB_LOCK_DUMP=0, /* Display held locks. */ + DB_LOCK_GET=1, /* Get the lock. */ + DB_LOCK_GET_TIMEOUT=2, /* Get lock with a timeout. */ + DB_LOCK_INHERIT=3, /* Pass locks to parent. */ + DB_LOCK_PUT=4, /* Release the lock. */ + DB_LOCK_PUT_ALL=5, /* Release locker's locks. */ + DB_LOCK_PUT_OBJ=6, /* Release locker's locks on obj. */ + DB_LOCK_PUT_READ=7, /* Release locker's read locks. */ + DB_LOCK_TIMEOUT=8, /* Force a txn to timeout. */ + DB_LOCK_TRADE=9, /* Trade locker ids on a lock. */ + DB_LOCK_UPGRADE_WRITE=10 /* Upgrade writes for dirty reads. */ +} db_lockop_t; + +/* + * Status of a lock. + */ +typedef enum { + DB_LSTAT_ABORTED=1, /* Lock belongs to an aborted txn. */ + DB_LSTAT_EXPIRED=2, /* Lock has expired. */ + DB_LSTAT_FREE=3, /* Lock is unallocated. */ + DB_LSTAT_HELD=4, /* Lock is currently held. */ + DB_LSTAT_NOTEXIST=5, /* Object on which lock was waiting + * was removed */ + DB_LSTAT_PENDING=6, /* Lock was waiting and has been + * promoted; waiting for the owner + * to run and upgrade it to held. */ + DB_LSTAT_WAITING=7 /* Lock is on the wait queue. */ +}db_status_t; + +/* Lock statistics structure. */ +struct __db_lock_stat { + u_int32_t st_id; /* Last allocated locker ID. */ + u_int32_t st_cur_maxid; /* Current maximum unused ID. */ + u_int32_t st_maxlocks; /* Maximum number of locks in table. */ + u_int32_t st_maxlockers; /* Maximum num of lockers in table. */ + u_int32_t st_maxobjects; /* Maximum num of objects in table. */ + int st_nmodes; /* Number of lock modes. */ + u_int32_t st_nlocks; /* Current number of locks. */ + u_int32_t st_maxnlocks; /* Maximum number of locks so far. */ + u_int32_t st_nlockers; /* Current number of lockers. */ + u_int32_t st_maxnlockers; /* Maximum number of lockers so far. */ + u_int32_t st_nobjects; /* Current number of objects. */ + u_int32_t st_maxnobjects; /* Maximum number of objects so far. */ + u_int32_t st_nconflicts; /* Number of lock conflicts. */ + u_int32_t st_nrequests; /* Number of lock gets. */ + u_int32_t st_nreleases; /* Number of lock puts. */ + u_int32_t st_nnowaits; /* Number of requests that would have + waited, but NOWAIT was set. */ + u_int32_t st_ndeadlocks; /* Number of lock deadlocks. */ + db_timeout_t st_locktimeout; /* Lock timeout. */ + u_int32_t st_nlocktimeouts; /* Number of lock timeouts. */ + db_timeout_t st_txntimeout; /* Transaction timeout. */ + u_int32_t st_ntxntimeouts; /* Number of transaction timeouts. */ + u_int32_t st_region_wait; /* Region lock granted after wait. */ + u_int32_t st_region_nowait; /* Region lock granted without wait. */ + roff_t st_regsize; /* Region size. */ +}; + +/* + * DB_LOCK_ILOCK -- + * Internal DB access method lock. + */ +struct __db_ilock { + db_pgno_t pgno; /* Page being locked. */ + u_int8_t fileid[DB_FILE_ID_LEN];/* File id. */ +#define DB_HANDLE_LOCK 1 +#define DB_RECORD_LOCK 2 +#define DB_PAGE_LOCK 3 + u_int32_t type; /* Type of lock. */ +}; + +/* + * DB_LOCK -- + * The structure is allocated by the caller and filled in during a + * lock_get request (or a lock_vec/DB_LOCK_GET). + */ +struct __db_lock_u { + roff_t off; /* Offset of the lock in the region */ + u_int32_t ndx; /* Index of the object referenced by + * this lock; used for locking. */ + u_int32_t gen; /* Generation number of this lock. */ + db_lockmode_t mode; /* mode of this lock. */ +}; + +/* Lock request structure. */ +struct __db_lockreq { + db_lockop_t op; /* Operation. */ + db_lockmode_t mode; /* Requested mode. */ + db_timeout_t timeout; /* Time to expire lock. */ + DBT *obj; /* Object being locked. */ + DB_LOCK lock; /* Lock returned. */ +}; + +/******************************************************* + * Logging. + *******************************************************/ +#define DB_LOGVERSION 10 /* Current log version. */ +#define DB_LOGOLDVER 10 /* Oldest log version supported. */ +#define DB_LOGMAGIC 0x040988 + +/* Flag values for DB_ENV->log_archive(). */ +#define DB_ARCH_ABS 0x001 /* Absolute pathnames. */ +#define DB_ARCH_DATA 0x002 /* Data files. */ +#define DB_ARCH_LOG 0x004 /* Log files. */ +#define DB_ARCH_REMOVE 0x008 /* Remove log files. */ + +/* Flag values for DB_ENV->log_put(). */ +#define DB_FLUSH 0x001 /* Flush data to disk (public). */ +#define DB_LOG_CHKPNT 0x002 /* Flush supports a checkpoint */ +#define DB_LOG_COMMIT 0x004 /* Flush supports a commit */ +#define DB_LOG_NOCOPY 0x008 /* Don't copy data */ +#define DB_LOG_NOT_DURABLE 0x010 /* Do not log; keep in memory */ +#define DB_LOG_PERM 0x020 /* Flag record with REP_PERMANENT */ +#define DB_LOG_RESEND 0x040 /* Resent log record */ +#define DB_LOG_WRNOSYNC 0x080 /* Write, don't sync log_put */ + +/* + * A DB_LSN has two parts, a fileid which identifies a specific file, and an + * offset within that file. The fileid is an unsigned 4-byte quantity that + * uniquely identifies a file within the log directory -- currently a simple + * counter inside the log. The offset is also an unsigned 4-byte value. The + * log manager guarantees the offset is never more than 4 bytes by switching + * to a new log file before the maximum length imposed by an unsigned 4-byte + * offset is reached. + */ +struct __db_lsn { + u_int32_t file; /* File ID. */ + u_int32_t offset; /* File offset. */ +}; + +/* + * Application-specified log record types start at DB_user_BEGIN, and must not + * equal or exceed DB_debug_FLAG. + * + * DB_debug_FLAG is the high-bit of the u_int32_t that specifies a log record + * type. If the flag is set, it's a log record that was logged for debugging + * purposes only, even if it reflects a database change -- the change was part + * of a non-durable transaction. + */ +#define DB_user_BEGIN 10000 +#define DB_debug_FLAG 0x80000000 + +/* + * DB_LOGC -- + * Log cursor. + */ +struct __db_log_cursor { + DB_ENV *dbenv; /* Enclosing dbenv. */ + + DB_FH *c_fhp; /* File handle. */ + DB_LSN c_lsn; /* Cursor: LSN */ + u_int32_t c_len; /* Cursor: record length */ + u_int32_t c_prev; /* Cursor: previous record's offset */ + + DBT c_dbt; /* Return DBT. */ + +#define DB_LOGC_BUF_SIZE (32 * 1024) + u_int8_t *bp; /* Allocated read buffer. */ + u_int32_t bp_size; /* Read buffer length in bytes. */ + u_int32_t bp_rlen; /* Read buffer valid data length. */ + DB_LSN bp_lsn; /* Read buffer first byte LSN. */ + + u_int32_t bp_maxrec; /* Max record length in the log file. */ + + /* Methods. */ + int (*close) __P((DB_LOGC *, u_int32_t)); + int (*get) __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t)); + +#define DB_LOG_DISK 0x01 /* Log record came from disk. */ +#define DB_LOG_LOCKED 0x02 /* Log region already locked */ +#define DB_LOG_SILENT_ERR 0x04 /* Turn-off error messages. */ + u_int32_t flags; +}; + +/* Log statistics structure. */ +struct __db_log_stat { + u_int32_t st_magic; /* Log file magic number. */ + u_int32_t st_version; /* Log file version number. */ + int st_mode; /* Log file mode. */ + u_int32_t st_lg_bsize; /* Log buffer size. */ + u_int32_t st_lg_size; /* Log file size. */ + u_int32_t st_w_bytes; /* Bytes to log. */ + u_int32_t st_w_mbytes; /* Megabytes to log. */ + u_int32_t st_wc_bytes; /* Bytes to log since checkpoint. */ + u_int32_t st_wc_mbytes; /* Megabytes to log since checkpoint. */ + u_int32_t st_wcount; /* Total writes to the log. */ + u_int32_t st_wcount_fill; /* Overflow writes to the log. */ + u_int32_t st_scount; /* Total syncs to the log. */ + u_int32_t st_region_wait; /* Region lock granted after wait. */ + u_int32_t st_region_nowait; /* Region lock granted without wait. */ + u_int32_t st_cur_file; /* Current log file number. */ + u_int32_t st_cur_offset; /* Current log file offset. */ + u_int32_t st_disk_file; /* Known on disk log file number. */ + u_int32_t st_disk_offset; /* Known on disk log file offset. */ + roff_t st_regsize; /* Region size. */ + u_int32_t st_maxcommitperflush; /* Max number of commits in a flush. */ + u_int32_t st_mincommitperflush; /* Min number of commits in a flush. */ +}; + +/* + * We need to record the first log record of a transaction. + * For user defined logging this macro returns the place to + * put that information, if it is need in rlsnp, otherwise it + * leaves it unchanged. + */ +#define DB_SET_BEGIN_LSNP(txn, rlsnp) ((txn)->set_begin_lsnp(txn, rlsnp)) + +/******************************************************* + * Shared buffer cache (mpool). + *******************************************************/ +/* Flag values for DB_MPOOLFILE->get. */ +#define DB_MPOOL_CREATE 0x001 /* Create a page. */ +#define DB_MPOOL_LAST 0x002 /* Return the last page. */ +#define DB_MPOOL_NEW 0x004 /* Create a new page. */ + +/* Flag values for DB_MPOOLFILE->put, DB_MPOOLFILE->set. */ +#define DB_MPOOL_CLEAN 0x001 /* Page is not modified. */ +#define DB_MPOOL_DIRTY 0x002 /* Page is modified. */ +#define DB_MPOOL_DISCARD 0x004 /* Don't cache the page. */ +#define DB_MPOOL_FREE 0x008 /* Free page if present. */ + +/* Flags values for DB_MPOOLFILE->set_flags. */ +#define DB_MPOOL_NOFILE 0x001 /* Never open a backing file. */ +#define DB_MPOOL_UNLINK 0x002 /* Unlink the file on last close. */ + +/* Priority values for DB_MPOOLFILE->set_priority. */ +typedef enum { + DB_PRIORITY_VERY_LOW=1, + DB_PRIORITY_LOW=2, + DB_PRIORITY_DEFAULT=3, + DB_PRIORITY_HIGH=4, + DB_PRIORITY_VERY_HIGH=5 +} DB_CACHE_PRIORITY; + +/* Per-process DB_MPOOLFILE information. */ +struct __db_mpoolfile { + DB_FH *fhp; /* Underlying file handle. */ + + /* + * !!! + * The ref, pinref and q fields are protected by the region lock. + */ + u_int32_t ref; /* Reference count. */ + + u_int32_t pinref; /* Pinned block reference count. */ + + /* + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_ENTRY(__db_mpoolfile) q; + */ + struct { + struct __db_mpoolfile *tqe_next; + struct __db_mpoolfile **tqe_prev; + } q; /* Linked list of DB_MPOOLFILE's. */ + + /* + * !!! + * The rest of the fields (with the exception of the MP_FLUSH flag) + * are not thread-protected, even when they may be modified at any + * time by the application. The reason is the DB_MPOOLFILE handle + * is single-threaded from the viewpoint of the application, and so + * the only fields needing to be thread-protected are those accessed + * by checkpoint or sync threads when using DB_MPOOLFILE structures + * to flush buffers from the cache. + */ + DB_ENV *dbenv; /* Overlying DB_ENV. */ + MPOOLFILE *mfp; /* Underlying MPOOLFILE. */ + + u_int32_t clear_len; /* Cleared length on created pages. */ + u_int8_t /* Unique file ID. */ + fileid[DB_FILE_ID_LEN]; + int ftype; /* File type. */ + int32_t lsn_offset; /* LSN offset in page. */ + u_int32_t gbytes, bytes; /* Maximum file size. */ + DBT *pgcookie; /* Byte-string passed to pgin/pgout. */ + DB_CACHE_PRIORITY /* Cache priority. */ + priority; + + void *addr; /* Address of mmap'd region. */ + size_t len; /* Length of mmap'd region. */ + + u_int32_t config_flags; /* Flags to DB_MPOOLFILE->set_flags. */ + + /* Methods. */ + int (*close) __P((DB_MPOOLFILE *, u_int32_t)); + int (*get) __P((DB_MPOOLFILE *, db_pgno_t *, u_int32_t, void *)); + int (*open) __P((DB_MPOOLFILE *, const char *, u_int32_t, int, size_t)); + int (*put) __P((DB_MPOOLFILE *, void *, u_int32_t)); + int (*set) __P((DB_MPOOLFILE *, void *, u_int32_t)); + int (*get_clear_len) __P((DB_MPOOLFILE *, u_int32_t *)); + int (*set_clear_len) __P((DB_MPOOLFILE *, u_int32_t)); + int (*get_fileid) __P((DB_MPOOLFILE *, u_int8_t *)); + int (*set_fileid) __P((DB_MPOOLFILE *, u_int8_t *)); + int (*get_flags) __P((DB_MPOOLFILE *, u_int32_t *)); + int (*set_flags) __P((DB_MPOOLFILE *, u_int32_t, int)); + int (*get_ftype) __P((DB_MPOOLFILE *, int *)); + int (*set_ftype) __P((DB_MPOOLFILE *, int)); + int (*get_lsn_offset) __P((DB_MPOOLFILE *, int32_t *)); + int (*set_lsn_offset) __P((DB_MPOOLFILE *, int32_t)); + int (*get_maxsize) __P((DB_MPOOLFILE *, u_int32_t *, u_int32_t *)); + int (*set_maxsize) __P((DB_MPOOLFILE *, u_int32_t, u_int32_t)); + int (*get_pgcookie) __P((DB_MPOOLFILE *, DBT *)); + int (*set_pgcookie) __P((DB_MPOOLFILE *, DBT *)); + int (*get_priority) __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY *)); + int (*set_priority) __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY)); + int (*sync) __P((DB_MPOOLFILE *)); + + /* + * MP_FILEID_SET, MP_OPEN_CALLED and MP_READONLY do not need to be + * thread protected because they are initialized before the file is + * linked onto the per-process lists, and never modified. + * + * MP_FLUSH is thread protected because it is potentially read/set by + * multiple threads of control. + */ +#define MP_FILEID_SET 0x001 /* Application supplied a file ID. */ +#define MP_FLUSH 0x002 /* Was opened to flush a buffer. */ +#define MP_OPEN_CALLED 0x004 /* File opened. */ +#define MP_READONLY 0x008 /* File is readonly. */ + u_int32_t flags; +}; + +/* Mpool statistics structure. */ +struct __db_mpool_stat { + u_int32_t st_gbytes; /* Total cache size: GB. */ + u_int32_t st_bytes; /* Total cache size: B. */ + u_int32_t st_ncache; /* Number of caches. */ + roff_t st_regsize; /* Region size. */ + size_t st_mmapsize; /* Maximum file size for mmap. */ + int st_maxopenfd; /* Maximum number of open fd's. */ + int st_maxwrite; /* Maximum buffers to write. */ + int st_maxwrite_sleep; /* Sleep after writing max buffers. */ + u_int32_t st_map; /* Pages from mapped files. */ + u_int32_t st_cache_hit; /* Pages found in the cache. */ + u_int32_t st_cache_miss; /* Pages not found in the cache. */ + u_int32_t st_page_create; /* Pages created in the cache. */ + u_int32_t st_page_in; /* Pages read in. */ + u_int32_t st_page_out; /* Pages written out. */ + u_int32_t st_ro_evict; /* Clean pages forced from the cache. */ + u_int32_t st_rw_evict; /* Dirty pages forced from the cache. */ + u_int32_t st_page_trickle; /* Pages written by memp_trickle. */ + u_int32_t st_pages; /* Total number of pages. */ + u_int32_t st_page_clean; /* Clean pages. */ + u_int32_t st_page_dirty; /* Dirty pages. */ + u_int32_t st_hash_buckets; /* Number of hash buckets. */ + u_int32_t st_hash_searches; /* Total hash chain searches. */ + u_int32_t st_hash_longest; /* Longest hash chain searched. */ + u_int32_t st_hash_examined; /* Total hash entries searched. */ + u_int32_t st_hash_nowait; /* Hash lock granted with nowait. */ + u_int32_t st_hash_wait; /* Hash lock granted after wait. */ + u_int32_t st_hash_max_wait; /* Max hash lock granted after wait. */ + u_int32_t st_region_nowait; /* Region lock granted with nowait. */ + u_int32_t st_region_wait; /* Region lock granted after wait. */ + u_int32_t st_alloc; /* Number of page allocations. */ + u_int32_t st_alloc_buckets; /* Buckets checked during allocation. */ + u_int32_t st_alloc_max_buckets; /* Max checked during allocation. */ + u_int32_t st_alloc_pages; /* Pages checked during allocation. */ + u_int32_t st_alloc_max_pages; /* Max checked during allocation. */ +}; + +/* Mpool file statistics structure. */ +struct __db_mpool_fstat { + char *file_name; /* File name. */ + u_int32_t st_pagesize; /* Page size. */ + u_int32_t st_map; /* Pages from mapped files. */ + u_int32_t st_cache_hit; /* Pages found in the cache. */ + u_int32_t st_cache_miss; /* Pages not found in the cache. */ + u_int32_t st_page_create; /* Pages created in the cache. */ + u_int32_t st_page_in; /* Pages read in. */ + u_int32_t st_page_out; /* Pages written out. */ +}; + +/******************************************************* + * Transactions and recovery. + *******************************************************/ +#define DB_TXNVERSION 1 + +typedef enum { + DB_TXN_ABORT=0, /* Public. */ + DB_TXN_APPLY=1, /* Public. */ + DB_TXN_BACKWARD_ALLOC=2, /* Internal. */ + DB_TXN_BACKWARD_ROLL=3, /* Public. */ + DB_TXN_FORWARD_ROLL=4, /* Public. */ + DB_TXN_OPENFILES=5, /* Internal. */ + DB_TXN_POPENFILES=6, /* Internal. */ + DB_TXN_PRINT=7 /* Public. */ +} db_recops; + +/* + * BACKWARD_ALLOC is used during the forward pass to pick up any aborted + * allocations for files that were created during the forward pass. + * The main difference between _ALLOC and _ROLL is that the entry for + * the file not exist during the rollforward pass. + */ +#define DB_UNDO(op) ((op) == DB_TXN_ABORT || \ + (op) == DB_TXN_BACKWARD_ROLL || (op) == DB_TXN_BACKWARD_ALLOC) +#define DB_REDO(op) ((op) == DB_TXN_FORWARD_ROLL || (op) == DB_TXN_APPLY) + +struct __db_txn { + DB_TXNMGR *mgrp; /* Pointer to transaction manager. */ + DB_TXN *parent; /* Pointer to transaction's parent. */ + DB_LSN last_lsn; /* Lsn of last log write. */ + u_int32_t txnid; /* Unique transaction id. */ + u_int32_t tid; /* Thread id for use in MT XA. */ + roff_t off; /* Detail structure within region. */ + db_timeout_t lock_timeout; /* Timeout for locks for this txn. */ + db_timeout_t expire; /* Time this txn expires. */ + void *txn_list; /* Undo information for parent. */ + + /* + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_ENTRY(__db_txn) links; + * TAILQ_ENTRY(__db_txn) xalinks; + */ + struct { + struct __db_txn *tqe_next; + struct __db_txn **tqe_prev; + } links; /* Links transactions off manager. */ + struct { + struct __db_txn *tqe_next; + struct __db_txn **tqe_prev; + } xalinks; /* Links active XA transactions. */ + + /* + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_HEAD(__events, __txn_event) events; + */ + struct { + struct __txn_event *tqh_first; + struct __txn_event **tqh_last; + } events; + + /* + * !!! + * Explicit representations of structures from queue.h. + * STAILQ_HEAD(__logrec, __txn_logrec) logs; + */ + struct { + struct __txn_logrec *stqh_first; + struct __txn_logrec **stqh_last; + } logs; /* Links deferred events. */ + + /* + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_HEAD(__kids, __db_txn) kids; + */ + struct __kids { + struct __db_txn *tqh_first; + struct __db_txn **tqh_last; + } kids; + + /* + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_ENTRY(__db_txn) klinks; + */ + struct { + struct __db_txn *tqe_next; + struct __db_txn **tqe_prev; + } klinks; + + void *api_internal; /* C++ API private. */ + void *xml_internal; /* XML API private. */ + + u_int32_t cursors; /* Number of cursors open for txn */ + + /* Methods. */ + int (*abort) __P((DB_TXN *)); + int (*commit) __P((DB_TXN *, u_int32_t)); + int (*discard) __P((DB_TXN *, u_int32_t)); + u_int32_t (*id) __P((DB_TXN *)); + int (*prepare) __P((DB_TXN *, u_int8_t *)); + void (*set_begin_lsnp) __P((DB_TXN *txn, DB_LSN **)); + int (*set_timeout) __P((DB_TXN *, db_timeout_t, u_int32_t)); + +#define TXN_CHILDCOMMIT 0x001 /* Transaction that has committed. */ +#define TXN_COMPENSATE 0x002 /* Compensating transaction. */ +#define TXN_DEADLOCK 0x004 /* Transaction has deadlocked. */ +#define TXN_DEGREE_2 0x008 /* Has degree 2 isolation. */ +#define TXN_DIRTY_READ 0x010 /* Transaction does dirty reads. */ +#define TXN_LOCKTIMEOUT 0x020 /* Transaction has a lock timeout. */ +#define TXN_MALLOC 0x040 /* Structure allocated by TXN system. */ +#define TXN_NOSYNC 0x080 /* Do not sync on prepare and commit. */ +#define TXN_NOWAIT 0x100 /* Do not wait on locks. */ +#define TXN_RESTORED 0x200 /* Transaction has been restored. */ +#define TXN_SYNC 0x400 /* Sync on prepare and commit. */ + u_int32_t flags; +}; + +/* + * Structure used for two phase commit interface. Berkeley DB support for two + * phase commit is compatible with the X/open XA interface. + * + * The XA #define XIDDATASIZE defines the size of a global transaction ID. We + * have our own version here (for name space reasons) which must have the same + * value. + */ +#define DB_XIDDATASIZE 128 +struct __db_preplist { + DB_TXN *txn; + u_int8_t gid[DB_XIDDATASIZE]; +}; + +/* Transaction statistics structure. */ +struct __db_txn_active { + u_int32_t txnid; /* Transaction ID */ + u_int32_t parentid; /* Transaction ID of parent */ + DB_LSN lsn; /* LSN when transaction began */ + u_int32_t xa_status; /* XA status */ + u_int8_t xid[DB_XIDDATASIZE]; /* XA global transaction ID */ +}; + +struct __db_txn_stat { + DB_LSN st_last_ckp; /* lsn of the last checkpoint */ + time_t st_time_ckp; /* time of last checkpoint */ + u_int32_t st_last_txnid; /* last transaction id given out */ + u_int32_t st_maxtxns; /* maximum txns possible */ + u_int32_t st_naborts; /* number of aborted transactions */ + u_int32_t st_nbegins; /* number of begun transactions */ + u_int32_t st_ncommits; /* number of committed transactions */ + u_int32_t st_nactive; /* number of active transactions */ + u_int32_t st_nrestores; /* number of restored transactions + after recovery. */ + u_int32_t st_maxnactive; /* maximum active transactions */ + DB_TXN_ACTIVE *st_txnarray; /* array of active transactions */ + u_int32_t st_region_wait; /* Region lock granted after wait. */ + u_int32_t st_region_nowait; /* Region lock granted without wait. */ + roff_t st_regsize; /* Region size. */ +}; + +/******************************************************* + * Replication. + *******************************************************/ +/* Special, out-of-band environment IDs. */ +#define DB_EID_BROADCAST -1 +#define DB_EID_INVALID -2 + +/* rep_start flags values */ +#define DB_REP_CLIENT 0x001 +#define DB_REP_MASTER 0x002 + +/* Replication statistics. */ +struct __db_rep_stat { + /* !!! + * Many replication statistics fields cannot be protected by a mutex + * without an unacceptable performance penalty, since most message + * processing is done without the need to hold a region-wide lock. + * Fields whose comments end with a '+' may be updated without holding + * the replication or log mutexes (as appropriate), and thus may be + * off somewhat (or, on unreasonable architectures under unlucky + * circumstances, garbaged). + */ + u_int32_t st_status; /* Current replication status. */ + DB_LSN st_next_lsn; /* Next LSN to use or expect. */ + DB_LSN st_waiting_lsn; /* LSN we're awaiting, if any. */ + db_pgno_t st_next_pg; /* Next pg we expect. */ + db_pgno_t st_waiting_pg; /* pg we're awaiting, if any. */ + + u_int32_t st_dupmasters; /* # of times a duplicate master + condition was detected.+ */ + int st_env_id; /* Current environment ID. */ + int st_env_priority; /* Current environment priority. */ + u_int32_t st_gen; /* Current generation number. */ + u_int32_t st_egen; /* Current election gen number. */ + u_int32_t st_log_duplicated; /* Log records received multiply.+ */ + u_int32_t st_log_queued; /* Log records currently queued.+ */ + u_int32_t st_log_queued_max; /* Max. log records queued at once.+ */ + u_int32_t st_log_queued_total; /* Total # of log recs. ever queued.+ */ + u_int32_t st_log_records; /* Log records received and put.+ */ + u_int32_t st_log_requested; /* Log recs. missed and requested.+ */ + int st_master; /* Env. ID of the current master. */ + u_int32_t st_master_changes; /* # of times we've switched masters. */ + u_int32_t st_msgs_badgen; /* Messages with a bad generation #.+ */ + u_int32_t st_msgs_processed; /* Messages received and processed.+ */ + u_int32_t st_msgs_recover; /* Messages ignored because this site + was a client in recovery.+ */ + u_int32_t st_msgs_send_failures;/* # of failed message sends.+ */ + u_int32_t st_msgs_sent; /* # of successful message sends.+ */ + u_int32_t st_newsites; /* # of NEWSITE msgs. received.+ */ + int st_nsites; /* Current number of sites we will + assume during elections. */ + u_int32_t st_nthrottles; /* # of times we were throttled. */ + u_int32_t st_outdated; /* # of times we detected and returned + an OUTDATED condition.+ */ + u_int32_t st_pg_duplicated; /* Pages received multiply.+ */ + u_int32_t st_pg_records; /* Pages received and stored.+ */ + u_int32_t st_pg_requested; /* Pages missed and requested.+ */ + u_int32_t st_startup_complete; /* Site completed client sync-up. */ + u_int32_t st_txns_applied; /* # of transactions applied.+ */ + + /* Elections generally. */ + u_int32_t st_elections; /* # of elections held.+ */ + u_int32_t st_elections_won; /* # of elections won by this site.+ */ + + /* Statistics about an in-progress election. */ + int st_election_cur_winner; /* Current front-runner. */ + u_int32_t st_election_gen; /* Election generation number. */ + DB_LSN st_election_lsn; /* Max. LSN of current winner. */ + int st_election_nsites; /* # of "registered voters". */ + int st_election_nvotes; /* # of "registered voters" needed. */ + int st_election_priority; /* Current election priority. */ + int st_election_status; /* Current election status. */ + u_int32_t st_election_tiebreaker;/* Election tiebreaker value. */ + int st_election_votes; /* Votes received in this round. */ +}; +/* + * The storage record for a sequence. + */ +struct __db_seq_record { + u_int32_t seq_version; /* Version size/number. */ +#define DB_SEQ_DEC 0x00000001 /* Decrement sequence. */ +#define DB_SEQ_INC 0x00000002 /* Increment sequence. */ +#define DB_SEQ_RANGE_SET 0x00000004 /* Range set (internal). */ +#define DB_SEQ_WRAP 0x00000008 /* Wrap sequence at min/max. */ + u_int32_t flags; /* Flags. */ + db_seq_t seq_value; /* Current value. */ + db_seq_t seq_max; /* Max permitted. */ + db_seq_t seq_min; /* Min permitted. */ +}; + +/* + * Handle for a sequence object. + */ +struct __db_sequence { + DB *seq_dbp; /* DB handle for this sequence. */ + DB_MUTEX *seq_mutexp; /* Mutex if sequence is threaded. */ + DB_SEQ_RECORD *seq_rp; /* Pointer to current data. */ + DB_SEQ_RECORD seq_record; /* Data from DB_SEQUENCE. */ + int32_t seq_cache_size; /* Number of values cached. */ + db_seq_t seq_last_value; /* Last value cached. */ + DBT seq_key; /* DBT pointing to sequence key. */ + DBT seq_data; /* DBT pointing to seq_record. */ + + /* API-private structure: used by C++ and Java. */ + void *api_internal; + + int (*close) __P((DB_SEQUENCE *, u_int32_t)); + int (*get) __P((DB_SEQUENCE *, + DB_TXN *, int32_t, db_seq_t *, u_int32_t)); + int (*get_cachesize) __P((DB_SEQUENCE *, int32_t *)); + int (*get_db) __P((DB_SEQUENCE *, DB **)); + int (*get_flags) __P((DB_SEQUENCE *, u_int32_t *)); + int (*get_key) __P((DB_SEQUENCE *, DBT *)); + int (*get_range) __P((DB_SEQUENCE *, + db_seq_t *, db_seq_t *)); + int (*initial_value) __P((DB_SEQUENCE *, db_seq_t)); + int (*open) __P((DB_SEQUENCE *, + DB_TXN *, DBT *, u_int32_t)); + int (*remove) __P((DB_SEQUENCE *, DB_TXN *, u_int32_t)); + int (*set_cachesize) __P((DB_SEQUENCE *, int32_t)); + int (*set_flags) __P((DB_SEQUENCE *, u_int32_t)); + int (*set_range) __P((DB_SEQUENCE *, db_seq_t, db_seq_t)); + int (*stat) __P((DB_SEQUENCE *, + DB_SEQUENCE_STAT **, u_int32_t)); + int (*stat_print) __P((DB_SEQUENCE *, u_int32_t)); +}; + +struct __db_seq_stat { + u_int32_t st_wait; /* Sequence lock granted without wait. */ + u_int32_t st_nowait; /* Sequence lock granted after wait. */ + db_seq_t st_current; /* Current value in db. */ + db_seq_t st_value; /* Current cached value. */ + db_seq_t st_last_value; /* Last cached value. */ + db_seq_t st_min; /* Minimum value. */ + db_seq_t st_max; /* Maximum value. */ + int32_t st_cache_size; /* Cache size. */ + u_int32_t st_flags; /* Flag value. */ +}; + +/******************************************************* + * Access methods. + *******************************************************/ +typedef enum { + DB_BTREE=1, + DB_HASH=2, + DB_RECNO=3, + DB_QUEUE=4, + DB_UNKNOWN=5 /* Figure it out on open. */ +} DBTYPE; + +#define DB_RENAMEMAGIC 0x030800 /* File has been renamed. */ + +#define DB_BTREEVERSION 9 /* Current btree version. */ +#define DB_BTREEOLDVER 8 /* Oldest btree version supported. */ +#define DB_BTREEMAGIC 0x053162 + +#define DB_HASHVERSION 8 /* Current hash version. */ +#define DB_HASHOLDVER 7 /* Oldest hash version supported. */ +#define DB_HASHMAGIC 0x061561 + +#define DB_QAMVERSION 4 /* Current queue version. */ +#define DB_QAMOLDVER 3 /* Oldest queue version supported. */ +#define DB_QAMMAGIC 0x042253 + +#define DB_SEQUENCE_VERSION 1 /* Current sequence version. */ + +/* + * DB access method and cursor operation values. Each value is an operation + * code to which additional bit flags are added. + */ +#define DB_AFTER 1 /* c_put() */ +#define DB_APPEND 2 /* put() */ +#define DB_BEFORE 3 /* c_put() */ +#define DB_CACHED_COUNTS 4 /* stat() */ +#define DB_CONSUME 5 /* get() */ +#define DB_CONSUME_WAIT 6 /* get() */ +#define DB_CURRENT 7 /* c_get(), c_put(), DB_LOGC->get() */ +#define DB_FAST_STAT 8 /* stat() */ +#define DB_FIRST 9 /* c_get(), DB_LOGC->get() */ +#define DB_GET_BOTH 10 /* get(), c_get() */ +#define DB_GET_BOTHC 11 /* c_get() (internal) */ +#define DB_GET_BOTH_RANGE 12 /* get(), c_get() */ +#define DB_GET_RECNO 13 /* c_get() */ +#define DB_JOIN_ITEM 14 /* c_get(); do not do primary lookup */ +#define DB_KEYFIRST 15 /* c_put() */ +#define DB_KEYLAST 16 /* c_put() */ +#define DB_LAST 17 /* c_get(), DB_LOGC->get() */ +#define DB_NEXT 18 /* c_get(), DB_LOGC->get() */ +#define DB_NEXT_DUP 19 /* c_get() */ +#define DB_NEXT_NODUP 20 /* c_get() */ +#define DB_NODUPDATA 21 /* put(), c_put() */ +#define DB_NOOVERWRITE 22 /* put() */ +#define DB_NOSYNC 23 /* close() */ +#define DB_POSITION 24 /* c_dup() */ +#define DB_PREV 25 /* c_get(), DB_LOGC->get() */ +#define DB_PREV_NODUP 26 /* c_get(), DB_LOGC->get() */ +#define DB_RECORDCOUNT 27 /* stat() */ +#define DB_SET 28 /* c_get(), DB_LOGC->get() */ +#define DB_SET_LOCK_TIMEOUT 29 /* set_timout() */ +#define DB_SET_RANGE 30 /* c_get() */ +#define DB_SET_RECNO 31 /* get(), c_get() */ +#define DB_SET_TXN_NOW 32 /* set_timout() (internal) */ +#define DB_SET_TXN_TIMEOUT 33 /* set_timout() */ +#define DB_UPDATE_SECONDARY 34 /* c_get(), c_del() (internal) */ +#define DB_WRITECURSOR 35 /* cursor() */ +#define DB_WRITELOCK 36 /* cursor() (internal) */ + +/* This has to change when the max opcode hits 255. */ +#define DB_OPFLAGS_MASK 0x000000ff /* Mask for operations flags. */ + +/* + * Masks for flags that can be OR'd into DB access method and cursor + * operation values. + * + * DB_DIRTY_READ 0x04000000 Dirty Read. */ +#define DB_MULTIPLE 0x08000000 /* Return multiple data values. */ +#define DB_MULTIPLE_KEY 0x10000000 /* Return multiple data/key pairs. */ +#define DB_RMW 0x20000000 /* Acquire write flag immediately. */ + +/* + * DB (user visible) error return codes. + * + * !!! + * For source compatibility with DB 2.X deadlock return (EAGAIN), use the + * following: + * #include + * #define DB_LOCK_DEADLOCK EAGAIN + * + * !!! + * We don't want our error returns to conflict with other packages where + * possible, so pick a base error value that's hopefully not common. We + * document that we own the error name space from -30,800 to -30,999. + */ +/* DB (public) error return codes. */ +#define DB_BUFFER_SMALL (-30999)/* User memory too small for return. */ +#define DB_DONOTINDEX (-30998)/* "Null" return from 2ndary callbk. */ +#define DB_KEYEMPTY (-30997)/* Key/data deleted or never created. */ +#define DB_KEYEXIST (-30996)/* The key/data pair already exists. */ +#define DB_LOCK_DEADLOCK (-30995)/* Deadlock. */ +#define DB_LOCK_NOTGRANTED (-30994)/* Lock unavailable. */ +#define DB_LOG_BUFFER_FULL (-30993)/* In-memory log buffer full. */ +#define DB_NOSERVER (-30992)/* Server panic return. */ +#define DB_NOSERVER_HOME (-30991)/* Bad home sent to server. */ +#define DB_NOSERVER_ID (-30990)/* Bad ID sent to server. */ +#define DB_NOTFOUND (-30989)/* Key/data pair not found (EOF). */ +#define DB_OLD_VERSION (-30988)/* Out-of-date version. */ +#define DB_PAGE_NOTFOUND (-30987)/* Requested page not found. */ +#define DB_REP_DUPMASTER (-30986)/* There are two masters. */ +#define DB_REP_HANDLE_DEAD (-30985)/* Rolled back a commit. */ +#define DB_REP_HOLDELECTION (-30984)/* Time to hold an election. */ +#define DB_REP_ISPERM (-30983)/* Cached not written perm written.*/ +#define DB_REP_NEWMASTER (-30982)/* We have learned of a new master. */ +#define DB_REP_NEWSITE (-30981)/* New site entered system. */ +#define DB_REP_NOTPERM (-30980)/* Permanent log record not written. */ +#define DB_REP_STARTUPDONE (-30979)/* Client startup complete. */ +#define DB_REP_UNAVAIL (-30978)/* Site cannot currently be reached. */ +#define DB_RUNRECOVERY (-30977)/* Panic return. */ +#define DB_SECONDARY_BAD (-30976)/* Secondary index corrupt. */ +#define DB_VERIFY_BAD (-30975)/* Verify failed; bad format. */ +#define DB_VERSION_MISMATCH (-30974)/* Environment version mismatch. */ + +/* DB (private) error return codes. */ +#define DB_ALREADY_ABORTED (-30899) +#define DB_DELETED (-30898)/* Recovery file marked deleted. */ +#define DB_LOCK_NOTEXIST (-30897)/* Object to lock is gone. */ +#define DB_NEEDSPLIT (-30896)/* Page needs to be split. */ +#define DB_REP_EGENCHG (-30895)/* Egen changed while in election. */ +#define DB_REP_LOGREADY (-30894)/* Rep log ready for recovery. */ +#define DB_REP_PAGEDONE (-30893)/* This page was already done. */ +#define DB_SURPRISE_KID (-30892)/* Child commit where parent + didn't know it was a parent. */ +#define DB_SWAPBYTES (-30891)/* Database needs byte swapping. */ +#define DB_TIMEOUT (-30890)/* Timed out waiting for election. */ +#define DB_TXN_CKP (-30889)/* Encountered ckp record in log. */ +#define DB_VERIFY_FATAL (-30888)/* DB->verify cannot proceed. */ + +/* Database handle. */ +struct __db { + /******************************************************* + * Public: owned by the application. + *******************************************************/ + u_int32_t pgsize; /* Database logical page size. */ + + /* Callbacks. */ + int (*db_append_recno) __P((DB *, DBT *, db_recno_t)); + void (*db_feedback) __P((DB *, int, int)); + int (*dup_compare) __P((DB *, const DBT *, const DBT *)); + + void *app_private; /* Application-private handle. */ + + /******************************************************* + * Private: owned by DB. + *******************************************************/ + DB_ENV *dbenv; /* Backing environment. */ + + DBTYPE type; /* DB access method type. */ + + DB_MPOOLFILE *mpf; /* Backing buffer pool. */ + + DB_MUTEX *mutexp; /* Synchronization for free threading */ + + char *fname, *dname; /* File/database passed to DB->open. */ + u_int32_t open_flags; /* Flags passed to DB->open. */ + + u_int8_t fileid[DB_FILE_ID_LEN];/* File's unique ID for locking. */ + + u_int32_t adj_fileid; /* File's unique ID for curs. adj. */ + +#define DB_LOGFILEID_INVALID -1 + FNAME *log_filename; /* File's naming info for logging. */ + + db_pgno_t meta_pgno; /* Meta page number */ + u_int32_t lid; /* Locker id for handle locking. */ + u_int32_t cur_lid; /* Current handle lock holder. */ + u_int32_t associate_lid; /* Locker id for DB->associate call. */ + DB_LOCK handle_lock; /* Lock held on this handle. */ + + u_int cl_id; /* RPC: remote client id. */ + + time_t timestamp; /* Handle timestamp for replication. */ + + /* + * Returned data memory for DB->get() and friends. + */ + DBT my_rskey; /* Secondary key. */ + DBT my_rkey; /* [Primary] key. */ + DBT my_rdata; /* Data. */ + + /* + * !!! + * Some applications use DB but implement their own locking outside of + * DB. If they're using fcntl(2) locking on the underlying database + * file, and we open and close a file descriptor for that file, we will + * discard their locks. The DB_FCNTL_LOCKING flag to DB->open is an + * undocumented interface to support this usage which leaves any file + * descriptors we open until DB->close. This will only work with the + * DB->open interface and simple caches, e.g., creating a transaction + * thread may open/close file descriptors this flag doesn't protect. + * Locking with fcntl(2) on a file that you don't own is a very, very + * unsafe thing to do. 'Nuff said. + */ + DB_FH *saved_open_fhp; /* Saved file handle. */ + + /* + * Linked list of DBP's, linked from the DB_ENV, used to keep track + * of all open db handles for cursor adjustment. + * + * !!! + * Explicit representations of structures from queue.h. + * LIST_ENTRY(__db) dblistlinks; + */ + struct { + struct __db *le_next; + struct __db **le_prev; + } dblistlinks; + + /* + * Cursor queues. + * + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_HEAD(__cq_fq, __dbc) free_queue; + * TAILQ_HEAD(__cq_aq, __dbc) active_queue; + * TAILQ_HEAD(__cq_jq, __dbc) join_queue; + */ + struct __cq_fq { + struct __dbc *tqh_first; + struct __dbc **tqh_last; + } free_queue; + struct __cq_aq { + struct __dbc *tqh_first; + struct __dbc **tqh_last; + } active_queue; + struct __cq_jq { + struct __dbc *tqh_first; + struct __dbc **tqh_last; + } join_queue; + + /* + * Secondary index support. + * + * Linked list of secondary indices -- set in the primary. + * + * !!! + * Explicit representations of structures from queue.h. + * LIST_HEAD(s_secondaries, __db); + */ + struct { + struct __db *lh_first; + } s_secondaries; + + /* + * List entries for secondaries, and reference count of how + * many threads are updating this secondary (see __db_c_put). + * + * !!! + * Note that these are synchronized by the primary's mutex, but + * filled in in the secondaries. + * + * !!! + * Explicit representations of structures from queue.h. + * LIST_ENTRY(__db) s_links; + */ + struct { + struct __db *le_next; + struct __db **le_prev; + } s_links; + u_int32_t s_refcnt; + + /* Secondary callback and free functions -- set in the secondary. */ + int (*s_callback) __P((DB *, const DBT *, const DBT *, DBT *)); + + /* Reference to primary -- set in the secondary. */ + DB *s_primary; + + /* API-private structure: used by DB 1.85, C++, Java, Perl and Tcl */ + void *api_internal; + + /* Subsystem-private structure. */ + void *bt_internal; /* Btree/Recno access method. */ + void *h_internal; /* Hash access method. */ + void *q_internal; /* Queue access method. */ + void *xa_internal; /* XA. */ + + /* Methods. */ + int (*associate) __P((DB *, DB_TXN *, DB *, int (*)(DB *, const DBT *, + const DBT *, DBT *), u_int32_t)); + int (*close) __P((DB *, u_int32_t)); + int (*cursor) __P((DB *, DB_TXN *, DBC **, u_int32_t)); + int (*del) __P((DB *, DB_TXN *, DBT *, u_int32_t)); + int (*dump) __P((DB *, + const char *, int (*)(void *, const void *), void *, int, int)); + void (*err) __P((DB *, int, const char *, ...)); + void (*errx) __P((DB *, const char *, ...)); + int (*fd) __P((DB *, int *)); + int (*get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); + int (*pget) __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t)); + int (*get_byteswapped) __P((DB *, int *)); + int (*get_cachesize) __P((DB *, u_int32_t *, u_int32_t *, int *)); + int (*get_dbname) __P((DB *, const char **, const char **)); + int (*get_encrypt_flags) __P((DB *, u_int32_t *)); + DB_ENV *(*get_env) __P((DB *)); + void (*get_errfile) __P((DB *, FILE **)); + void (*get_errpfx) __P((DB *, const char **)); + int (*get_flags) __P((DB *, u_int32_t *)); + int (*get_lorder) __P((DB *, int *)); + int (*get_open_flags) __P((DB *, u_int32_t *)); + int (*get_pagesize) __P((DB *, u_int32_t *)); + int (*get_transactional) __P((DB *)); + int (*get_type) __P((DB *, DBTYPE *)); + int (*join) __P((DB *, DBC **, DBC **, u_int32_t)); + int (*key_range) __P((DB *, + DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t)); + int (*open) __P((DB *, DB_TXN *, + const char *, const char *, DBTYPE, u_int32_t, int)); + int (*put) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); + int (*remove) __P((DB *, const char *, const char *, u_int32_t)); + int (*rename) __P((DB *, + const char *, const char *, const char *, u_int32_t)); + int (*truncate) __P((DB *, DB_TXN *, u_int32_t *, u_int32_t)); + int (*set_append_recno) __P((DB *, int (*)(DB *, DBT *, db_recno_t))); + int (*set_alloc) __P((DB *, void *(*)(size_t), + void *(*)(void *, size_t), void (*)(void *))); + int (*set_cachesize) __P((DB *, u_int32_t, u_int32_t, int)); + int (*set_dup_compare) __P((DB *, + int (*)(DB *, const DBT *, const DBT *))); + int (*set_encrypt) __P((DB *, const char *, u_int32_t)); + void (*set_errcall) __P((DB *, + void (*)(const DB_ENV *, const char *, const char *))); + void (*set_errfile) __P((DB *, FILE *)); + void (*set_errpfx) __P((DB *, const char *)); + int (*set_feedback) __P((DB *, void (*)(DB *, int, int))); + int (*set_flags) __P((DB *, u_int32_t)); + int (*set_lorder) __P((DB *, int)); + void (*set_msgcall) __P((DB *, void (*)(const DB_ENV *, const char *))); + void (*get_msgfile) __P((DB *, FILE **)); + void (*set_msgfile) __P((DB *, FILE *)); + int (*set_pagesize) __P((DB *, u_int32_t)); + int (*set_paniccall) __P((DB *, void (*)(DB_ENV *, int))); + int (*stat) __P((DB *, DB_TXN *, void *, u_int32_t)); + int (*stat_print) __P((DB *, u_int32_t)); + int (*sync) __P((DB *, u_int32_t)); + int (*upgrade) __P((DB *, const char *, u_int32_t)); + int (*verify) __P((DB *, + const char *, const char *, FILE *, u_int32_t)); + + int (*get_bt_minkey) __P((DB *, u_int32_t *)); + int (*set_bt_compare) __P((DB *, + int (*)(DB *, const DBT *, const DBT *))); + int (*set_bt_maxkey) __P((DB *, u_int32_t)); + int (*set_bt_minkey) __P((DB *, u_int32_t)); + int (*set_bt_prefix) __P((DB *, + size_t (*)(DB *, const DBT *, const DBT *))); + + int (*get_h_ffactor) __P((DB *, u_int32_t *)); + int (*get_h_nelem) __P((DB *, u_int32_t *)); + int (*set_h_ffactor) __P((DB *, u_int32_t)); + int (*set_h_hash) __P((DB *, + u_int32_t (*)(DB *, const void *, u_int32_t))); + int (*set_h_nelem) __P((DB *, u_int32_t)); + + int (*get_re_delim) __P((DB *, int *)); + int (*get_re_len) __P((DB *, u_int32_t *)); + int (*get_re_pad) __P((DB *, int *)); + int (*get_re_source) __P((DB *, const char **)); + int (*set_re_delim) __P((DB *, int)); + int (*set_re_len) __P((DB *, u_int32_t)); + int (*set_re_pad) __P((DB *, int)); + int (*set_re_source) __P((DB *, const char *)); + + int (*get_q_extentsize) __P((DB *, u_int32_t *)); + int (*set_q_extentsize) __P((DB *, u_int32_t)); + + int (*db_am_remove) __P((DB *, DB_TXN *, const char *, const char *)); + int (*db_am_rename) __P((DB *, DB_TXN *, + const char *, const char *, const char *)); + + /* + * Never called; these are a place to save function pointers + * so that we can undo an associate. + */ + int (*stored_get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); + int (*stored_close) __P((DB *, u_int32_t)); + +#define DB_OK_BTREE 0x01 +#define DB_OK_HASH 0x02 +#define DB_OK_QUEUE 0x04 +#define DB_OK_RECNO 0x08 + u_int32_t am_ok; /* Legal AM choices. */ + +#define DB_AM_CHKSUM 0x00000001 /* Checksumming. */ +#define DB_AM_CL_WRITER 0x00000002 /* Allow writes in client replica. */ +#define DB_AM_COMPENSATE 0x00000004 /* Created by compensating txn. */ +#define DB_AM_CREATED 0x00000008 /* Database was created upon open. */ +#define DB_AM_CREATED_MSTR 0x00000010 /* Encompassing file was created. */ +#define DB_AM_DBM_ERROR 0x00000020 /* Error in DBM/NDBM database. */ +#define DB_AM_DELIMITER 0x00000040 /* Variable length delimiter set. */ +#define DB_AM_DIRTY 0x00000080 /* Support Dirty Reads. */ +#define DB_AM_DISCARD 0x00000100 /* Discard any cached pages. */ +#define DB_AM_DUP 0x00000200 /* DB_DUP. */ +#define DB_AM_DUPSORT 0x00000400 /* DB_DUPSORT. */ +#define DB_AM_ENCRYPT 0x00000800 /* Encryption. */ +#define DB_AM_FIXEDLEN 0x00001000 /* Fixed-length records. */ +#define DB_AM_INMEM 0x00002000 /* In-memory; no sync on close. */ +#define DB_AM_INORDER 0x00004000 /* DB_INORDER. */ +#define DB_AM_IN_RENAME 0x00008000 /* File is being renamed. */ +#define DB_AM_NOT_DURABLE 0x00010000 /* Do not log changes. */ +#define DB_AM_OPEN_CALLED 0x00020000 /* DB->open called. */ +#define DB_AM_PAD 0x00040000 /* Fixed-length record pad. */ +#define DB_AM_PGDEF 0x00080000 /* Page size was defaulted. */ +#define DB_AM_RDONLY 0x00100000 /* Database is readonly. */ +#define DB_AM_RECNUM 0x00200000 /* DB_RECNUM. */ +#define DB_AM_RECOVER 0x00400000 /* DB opened by recovery routine. */ +#define DB_AM_RENUMBER 0x00800000 /* DB_RENUMBER. */ +#define DB_AM_REPLICATION 0x01000000 /* An internal replication file. */ +#define DB_AM_REVSPLITOFF 0x02000000 /* DB_REVSPLITOFF. */ +#define DB_AM_SECONDARY 0x04000000 /* Database is a secondary index. */ +#define DB_AM_SNAPSHOT 0x08000000 /* DB_SNAPSHOT. */ +#define DB_AM_SUBDB 0x10000000 /* Subdatabases supported. */ +#define DB_AM_SWAP 0x20000000 /* Pages need to be byte-swapped. */ +#define DB_AM_TXN 0x40000000 /* Opened in a transaction. */ +#define DB_AM_VERIFYING 0x80000000 /* DB handle is in the verifier. */ + u_int32_t orig_flags; /* Flags at open, for refresh. */ + u_int32_t flags; +}; + +/* + * Macros for bulk get. These are only intended for the C API. + * For C++, use DbMultiple*Iterator. + */ +#define DB_MULTIPLE_INIT(pointer, dbt) \ + (pointer = (u_int8_t *)(dbt)->data + \ + (dbt)->ulen - sizeof(u_int32_t)) +#define DB_MULTIPLE_NEXT(pointer, dbt, retdata, retdlen) \ + do { \ + if (*((u_int32_t *)(pointer)) == (u_int32_t)-1) { \ + retdata = NULL; \ + pointer = NULL; \ + break; \ + } \ + retdata = (u_int8_t *) \ + (dbt)->data + *(u_int32_t *)(pointer); \ + (pointer) = (u_int32_t *)(pointer) - 1; \ + retdlen = *(u_int32_t *)(pointer); \ + (pointer) = (u_int32_t *)(pointer) - 1; \ + if (retdlen == 0 && \ + retdata == (u_int8_t *)(dbt)->data) \ + retdata = NULL; \ + } while (0) +#define DB_MULTIPLE_KEY_NEXT(pointer, dbt, retkey, retklen, retdata, retdlen) \ + do { \ + if (*((u_int32_t *)(pointer)) == (u_int32_t)-1) { \ + retdata = NULL; \ + retkey = NULL; \ + pointer = NULL; \ + break; \ + } \ + retkey = (u_int8_t *) \ + (dbt)->data + *(u_int32_t *)(pointer); \ + (pointer) = (u_int32_t *)(pointer) - 1; \ + retklen = *(u_int32_t *)(pointer); \ + (pointer) = (u_int32_t *)(pointer) - 1; \ + retdata = (u_int8_t *) \ + (dbt)->data + *(u_int32_t *)(pointer); \ + (pointer) = (u_int32_t *)(pointer) - 1; \ + retdlen = *(u_int32_t *)(pointer); \ + (pointer) = (u_int32_t *)(pointer) - 1; \ + } while (0) + +#define DB_MULTIPLE_RECNO_NEXT(pointer, dbt, recno, retdata, retdlen) \ + do { \ + if (*((u_int32_t *)(pointer)) == (u_int32_t)0) { \ + recno = 0; \ + retdata = NULL; \ + pointer = NULL; \ + break; \ + } \ + recno = *(u_int32_t *)(pointer); \ + (pointer) = (u_int32_t *)(pointer) - 1; \ + retdata = (u_int8_t *) \ + (dbt)->data + *(u_int32_t *)(pointer); \ + (pointer) = (u_int32_t *)(pointer) - 1; \ + retdlen = *(u_int32_t *)(pointer); \ + (pointer) = (u_int32_t *)(pointer) - 1; \ + } while (0) + +/******************************************************* + * Access method cursors. + *******************************************************/ +struct __dbc { + DB *dbp; /* Related DB access method. */ + DB_TXN *txn; /* Associated transaction. */ + + /* + * Active/free cursor queues. + * + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_ENTRY(__dbc) links; + */ + struct { + DBC *tqe_next; + DBC **tqe_prev; + } links; + + /* + * The DBT *'s below are used by the cursor routines to return + * data to the user when DBT flags indicate that DB should manage + * the returned memory. They point at a DBT containing the buffer + * and length that will be used, and "belonging" to the handle that + * should "own" this memory. This may be a "my_*" field of this + * cursor--the default--or it may be the corresponding field of + * another cursor, a DB handle, a join cursor, etc. In general, it + * will be whatever handle the user originally used for the current + * DB interface call. + */ + DBT *rskey; /* Returned secondary key. */ + DBT *rkey; /* Returned [primary] key. */ + DBT *rdata; /* Returned data. */ + + DBT my_rskey; /* Space for returned secondary key. */ + DBT my_rkey; /* Space for returned [primary] key. */ + DBT my_rdata; /* Space for returned data. */ + + u_int32_t lid; /* Default process' locker id. */ + u_int32_t locker; /* Locker for this operation. */ + DBT lock_dbt; /* DBT referencing lock. */ + DB_LOCK_ILOCK lock; /* Object to be locked. */ + DB_LOCK mylock; /* CDB lock held on this cursor. */ + + u_int cl_id; /* Remote client id. */ + + DBTYPE dbtype; /* Cursor type. */ + + DBC_INTERNAL *internal; /* Access method private. */ + + int (*c_close) __P((DBC *)); /* Methods: public. */ + int (*c_count) __P((DBC *, db_recno_t *, u_int32_t)); + int (*c_del) __P((DBC *, u_int32_t)); + int (*c_dup) __P((DBC *, DBC **, u_int32_t)); + int (*c_get) __P((DBC *, DBT *, DBT *, u_int32_t)); + int (*c_pget) __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); + int (*c_put) __P((DBC *, DBT *, DBT *, u_int32_t)); + + /* Methods: private. */ + int (*c_am_bulk) __P((DBC *, DBT *, u_int32_t)); + int (*c_am_close) __P((DBC *, db_pgno_t, int *)); + int (*c_am_del) __P((DBC *)); + int (*c_am_destroy) __P((DBC *)); + int (*c_am_get) __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); + int (*c_am_put) __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); + int (*c_am_writelock) __P((DBC *)); + +#define DBC_ACTIVE 0x0001 /* Cursor in use. */ +#define DBC_COMPENSATE 0x0002 /* Cursor compensating, don't lock. */ +#define DBC_DEGREE_2 0x0004 /* Cursor has degree 2 isolation. */ +#define DBC_DIRTY_READ 0x0008 /* Cursor supports dirty reads. */ +#define DBC_OPD 0x0010 /* Cursor references off-page dups. */ +#define DBC_RECOVER 0x0020 /* Recovery cursor; don't log/lock. */ +#define DBC_RMW 0x0040 /* Acquire write flag in read op. */ +#define DBC_TRANSIENT 0x0080 /* Cursor is transient. */ +#define DBC_WRITECURSOR 0x0100 /* Cursor may be used to write (CDB). */ +#define DBC_WRITER 0x0200 /* Cursor immediately writing (CDB). */ +#define DBC_MULTIPLE 0x0400 /* Return Multiple data. */ +#define DBC_MULTIPLE_KEY 0x0800 /* Return Multiple keys and data. */ +#define DBC_OWN_LID 0x1000 /* Free lock id on destroy. */ + u_int32_t flags; +}; + +/* Key range statistics structure */ +struct __key_range { + double less; + double equal; + double greater; +}; + +/* Btree/Recno statistics structure. */ +struct __db_bt_stat { + u_int32_t bt_magic; /* Magic number. */ + u_int32_t bt_version; /* Version number. */ + u_int32_t bt_metaflags; /* Metadata flags. */ + u_int32_t bt_nkeys; /* Number of unique keys. */ + u_int32_t bt_ndata; /* Number of data items. */ + u_int32_t bt_pagesize; /* Page size. */ + u_int32_t bt_maxkey; /* Maxkey value. */ + u_int32_t bt_minkey; /* Minkey value. */ + u_int32_t bt_re_len; /* Fixed-length record length. */ + u_int32_t bt_re_pad; /* Fixed-length record pad. */ + u_int32_t bt_levels; /* Tree levels. */ + u_int32_t bt_int_pg; /* Internal pages. */ + u_int32_t bt_leaf_pg; /* Leaf pages. */ + u_int32_t bt_dup_pg; /* Duplicate pages. */ + u_int32_t bt_over_pg; /* Overflow pages. */ + u_int32_t bt_empty_pg; /* Empty pages. */ + u_int32_t bt_free; /* Pages on the free list. */ + u_int32_t bt_int_pgfree; /* Bytes free in internal pages. */ + u_int32_t bt_leaf_pgfree; /* Bytes free in leaf pages. */ + u_int32_t bt_dup_pgfree; /* Bytes free in duplicate pages. */ + u_int32_t bt_over_pgfree; /* Bytes free in overflow pages. */ +}; + +/* Hash statistics structure. */ +struct __db_h_stat { + u_int32_t hash_magic; /* Magic number. */ + u_int32_t hash_version; /* Version number. */ + u_int32_t hash_metaflags; /* Metadata flags. */ + u_int32_t hash_nkeys; /* Number of unique keys. */ + u_int32_t hash_ndata; /* Number of data items. */ + u_int32_t hash_pagesize; /* Page size. */ + u_int32_t hash_ffactor; /* Fill factor specified at create. */ + u_int32_t hash_buckets; /* Number of hash buckets. */ + u_int32_t hash_free; /* Pages on the free list. */ + u_int32_t hash_bfree; /* Bytes free on bucket pages. */ + u_int32_t hash_bigpages; /* Number of big key/data pages. */ + u_int32_t hash_big_bfree; /* Bytes free on big item pages. */ + u_int32_t hash_overflows; /* Number of overflow pages. */ + u_int32_t hash_ovfl_free; /* Bytes free on ovfl pages. */ + u_int32_t hash_dup; /* Number of dup pages. */ + u_int32_t hash_dup_free; /* Bytes free on duplicate pages. */ +}; + +/* Queue statistics structure. */ +struct __db_qam_stat { + u_int32_t qs_magic; /* Magic number. */ + u_int32_t qs_version; /* Version number. */ + u_int32_t qs_metaflags; /* Metadata flags. */ + u_int32_t qs_nkeys; /* Number of unique keys. */ + u_int32_t qs_ndata; /* Number of data items. */ + u_int32_t qs_pagesize; /* Page size. */ + u_int32_t qs_extentsize; /* Pages per extent. */ + u_int32_t qs_pages; /* Data pages. */ + u_int32_t qs_re_len; /* Fixed-length record length. */ + u_int32_t qs_re_pad; /* Fixed-length record pad. */ + u_int32_t qs_pgfree; /* Bytes free in data pages. */ + u_int32_t qs_first_recno; /* First not deleted record. */ + u_int32_t qs_cur_recno; /* Next available record number. */ +}; + +/******************************************************* + * Environment. + *******************************************************/ +#define DB_REGION_MAGIC 0x120897 /* Environment magic number. */ + +/* Database Environment handle. */ +struct __db_env { + /******************************************************* + * Public: owned by the application. + *******************************************************/ + /* Error message callback. */ + void (*db_errcall) __P((const DB_ENV *, const char *, const char *)); + FILE *db_errfile; /* Error message file stream. */ + const char *db_errpfx; /* Error message prefix. */ + + FILE *db_msgfile; /* Statistics message file stream. */ + /* Statistics message callback. */ + void (*db_msgcall) __P((const DB_ENV *, const char *)); + + /* Other Callbacks. */ + void (*db_feedback) __P((DB_ENV *, int, int)); + void (*db_paniccall) __P((DB_ENV *, int)); + + /* App-specified alloc functions. */ + void *(*db_malloc) __P((size_t)); + void *(*db_realloc) __P((void *, size_t)); + void (*db_free) __P((void *)); + + /* + * Currently, the verbose list is a bit field with room for 32 + * entries. There's no reason that it needs to be limited, if + * there are ever more than 32 entries, convert to a bit array. + */ +#define DB_VERB_DEADLOCK 0x0001 /* Deadlock detection information. */ +#define DB_VERB_RECOVERY 0x0002 /* Recovery information. */ +#define DB_VERB_REPLICATION 0x0004 /* Replication information. */ +#define DB_VERB_WAITSFOR 0x0008 /* Dump waits-for table. */ + u_int32_t verbose; /* Verbose output. */ + + void *app_private; /* Application-private handle. */ + + int (*app_dispatch) /* User-specified recovery dispatch. */ + __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); + + /* Locking. */ + u_int8_t *lk_conflicts; /* Two dimensional conflict matrix. */ + int lk_modes; /* Number of lock modes in table. */ + u_int32_t lk_max; /* Maximum number of locks. */ + u_int32_t lk_max_lockers;/* Maximum number of lockers. */ + u_int32_t lk_max_objects;/* Maximum number of locked objects. */ + u_int32_t lk_detect; /* Deadlock detect on all conflicts. */ + db_timeout_t lk_timeout; /* Lock timeout period. */ + + /* Logging. */ + u_int32_t lg_bsize; /* Buffer size. */ + u_int32_t lg_size; /* Log file size. */ + u_int32_t lg_regionmax; /* Region size. */ + + /* Memory pool. */ + u_int32_t mp_gbytes; /* Cachesize: GB. */ + u_int32_t mp_bytes; /* Cachesize: Bytes. */ + u_int mp_ncache; /* Number of cache regions. */ + size_t mp_mmapsize; /* Maximum file size for mmap. */ + int mp_maxopenfd; /* Maximum open file descriptors. */ + int mp_maxwrite; /* Maximum buffers to write. */ + int /* Sleep after writing max buffers. */ + mp_maxwrite_sleep; + + /* Replication */ + int rep_eid; /* environment id. */ + int (*rep_send) /* Send function. */ + __P((DB_ENV *, const DBT *, const DBT *, + const DB_LSN *, int, u_int32_t)); + + /* Transactions. */ + u_int32_t tx_max; /* Maximum number of transactions. */ + time_t tx_timestamp; /* Recover to specific timestamp. */ + db_timeout_t tx_timeout; /* Timeout for transactions. */ + + /******************************************************* + * Private: owned by DB. + *******************************************************/ + /* User files, paths. */ + char *db_home; /* Database home. */ + char *db_log_dir; /* Database log file directory. */ + char *db_tmp_dir; /* Database tmp file directory. */ + + char **db_data_dir; /* Database data file directories. */ + int data_cnt; /* Database data file slots. */ + int data_next; /* Next Database data file slot. */ + + int db_mode; /* Default open permissions. */ + int dir_mode; /* Intermediate directory perms. */ + u_int32_t env_lid; /* Locker ID in non-threaded handles. */ + u_int32_t open_flags; /* Flags passed to DB_ENV->open. */ + + void *reginfo; /* REGINFO structure reference. */ + DB_FH *lockfhp; /* fcntl(2) locking file handle. */ + + int (**recover_dtab) /* Dispatch table for recover funcs. */ + __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); + size_t recover_dtab_size; + /* Slots in the dispatch table. */ + + void *cl_handle; /* RPC: remote client handle. */ + u_int cl_id; /* RPC: remote client env id. */ + + int db_ref; /* DB reference count. */ + + long shm_key; /* shmget(2) key. */ + u_int32_t tas_spins; /* test-and-set spins. */ + + /* + * List of open DB handles for this DB_ENV, used for cursor + * adjustment. Must be protected for multi-threaded support. + * + * !!! + * As this structure is allocated in per-process memory, the + * mutex may need to be stored elsewhere on architectures unable + * to support mutexes in heap memory, e.g. HP/UX 9. + * + * !!! + * Explicit representation of structure in queue.h. + * LIST_HEAD(dblist, __db); + */ + DB_MUTEX *dblist_mutexp; /* Mutex. */ + struct { + struct __db *lh_first; + } dblist; + + /* + * XA support. + * + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_ENTRY(__db_env) links; + * TAILQ_HEAD(xa_txn, __db_txn); + */ + struct { + struct __db_env *tqe_next; + struct __db_env **tqe_prev; + } links; + struct __xa_txn { /* XA Active Transactions. */ + struct __db_txn *tqh_first; + struct __db_txn **tqh_last; + } xa_txn; + int xa_rmid; /* XA Resource Manager ID. */ + + /* API-private structure. */ + void *api1_internal; /* C++, Perl API private */ + void *api2_internal; /* Java API private */ + + char *passwd; /* Cryptography support. */ + size_t passwd_len; + void *crypto_handle; /* Primary handle. */ + DB_MUTEX *mt_mutexp; /* Mersenne Twister mutex. */ + int mti; /* Mersenne Twister index. */ + u_long *mt; /* Mersenne Twister state vector. */ + + /* DB_ENV Methods. */ + int (*close) __P((DB_ENV *, u_int32_t)); + int (*dbremove) __P((DB_ENV *, + DB_TXN *, const char *, const char *, u_int32_t)); + int (*dbrename) __P((DB_ENV *, DB_TXN *, + const char *, const char *, const char *, u_int32_t)); + void (*err) __P((const DB_ENV *, int, const char *, ...)); + void (*errx) __P((const DB_ENV *, const char *, ...)); + int (*open) __P((DB_ENV *, const char *, u_int32_t, int)); + int (*remove) __P((DB_ENV *, const char *, u_int32_t)); + int (*stat_print) __P((DB_ENV *, u_int32_t)); + + /* House-keeping. */ + int (*fileid_reset) __P((DB_ENV *, char *, int)); + int (*is_bigendian) __P((void)); + int (*lsn_reset) __P((DB_ENV *, char *, int)); + int (*prdbt) __P((DBT *, + int, const char *, void *, int (*)(void *, const void *), int)); + + /* Setters/getters. */ + int (*set_alloc) __P((DB_ENV *, void *(*)(size_t), + void *(*)(void *, size_t), void (*)(void *))); + int (*set_app_dispatch) __P((DB_ENV *, + int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops))); + int (*get_data_dirs) __P((DB_ENV *, const char ***)); + int (*set_data_dir) __P((DB_ENV *, const char *)); + int (*get_encrypt_flags) __P((DB_ENV *, u_int32_t *)); + int (*set_encrypt) __P((DB_ENV *, const char *, u_int32_t)); + void (*set_errcall) __P((DB_ENV *, + void (*)(const DB_ENV *, const char *, const char *))); + void (*get_errfile) __P((DB_ENV *, FILE **)); + void (*set_errfile) __P((DB_ENV *, FILE *)); + void (*get_errpfx) __P((DB_ENV *, const char **)); + void (*set_errpfx) __P((DB_ENV *, const char *)); + int (*set_feedback) __P((DB_ENV *, void (*)(DB_ENV *, int, int))); + int (*get_flags) __P((DB_ENV *, u_int32_t *)); + int (*set_flags) __P((DB_ENV *, u_int32_t, int)); + int (*get_home) __P((DB_ENV *, const char **)); + int (*set_intermediate_dir) __P((DB_ENV *, int, u_int32_t)); + int (*get_open_flags) __P((DB_ENV *, u_int32_t *)); + int (*set_paniccall) __P((DB_ENV *, void (*)(DB_ENV *, int))); + int (*set_rpc_server) __P((DB_ENV *, + void *, const char *, long, long, u_int32_t)); + int (*get_shm_key) __P((DB_ENV *, long *)); + int (*set_shm_key) __P((DB_ENV *, long)); + void (*set_msgcall) __P((DB_ENV *, + void (*)(const DB_ENV *, const char *))); + void (*get_msgfile) __P((DB_ENV *, FILE **)); + void (*set_msgfile) __P((DB_ENV *, FILE *)); + int (*get_tas_spins) __P((DB_ENV *, u_int32_t *)); + int (*set_tas_spins) __P((DB_ENV *, u_int32_t)); + int (*get_tmp_dir) __P((DB_ENV *, const char **)); + int (*set_tmp_dir) __P((DB_ENV *, const char *)); + int (*get_verbose) __P((DB_ENV *, u_int32_t, int *)); + int (*set_verbose) __P((DB_ENV *, u_int32_t, int)); + + void *lg_handle; /* Log handle and methods. */ + int (*get_lg_bsize) __P((DB_ENV *, u_int32_t *)); + int (*set_lg_bsize) __P((DB_ENV *, u_int32_t)); + int (*get_lg_dir) __P((DB_ENV *, const char **)); + int (*set_lg_dir) __P((DB_ENV *, const char *)); + int (*get_lg_max) __P((DB_ENV *, u_int32_t *)); + int (*set_lg_max) __P((DB_ENV *, u_int32_t)); + int (*get_lg_regionmax) __P((DB_ENV *, u_int32_t *)); + int (*set_lg_regionmax) __P((DB_ENV *, u_int32_t)); + int (*log_archive) __P((DB_ENV *, char **[], u_int32_t)); + int (*log_cursor) __P((DB_ENV *, DB_LOGC **, u_int32_t)); + int (*log_file) __P((DB_ENV *, const DB_LSN *, char *, size_t)); + int (*log_flush) __P((DB_ENV *, const DB_LSN *)); + int (*log_put) __P((DB_ENV *, DB_LSN *, const DBT *, u_int32_t)); + int (*log_stat) __P((DB_ENV *, DB_LOG_STAT **, u_int32_t)); + int (*log_stat_print) __P((DB_ENV *, u_int32_t)); + + void *lk_handle; /* Lock handle and methods. */ + int (*get_lk_conflicts) __P((DB_ENV *, const u_int8_t **, int *)); + int (*set_lk_conflicts) __P((DB_ENV *, u_int8_t *, int)); + int (*get_lk_detect) __P((DB_ENV *, u_int32_t *)); + int (*set_lk_detect) __P((DB_ENV *, u_int32_t)); + int (*set_lk_max) __P((DB_ENV *, u_int32_t)); + int (*get_lk_max_locks) __P((DB_ENV *, u_int32_t *)); + int (*set_lk_max_locks) __P((DB_ENV *, u_int32_t)); + int (*get_lk_max_lockers) __P((DB_ENV *, u_int32_t *)); + int (*set_lk_max_lockers) __P((DB_ENV *, u_int32_t)); + int (*get_lk_max_objects) __P((DB_ENV *, u_int32_t *)); + int (*set_lk_max_objects) __P((DB_ENV *, u_int32_t)); + int (*lock_detect) __P((DB_ENV *, u_int32_t, u_int32_t, int *)); + int (*lock_get) __P((DB_ENV *, + u_int32_t, u_int32_t, const DBT *, db_lockmode_t, DB_LOCK *)); + int (*lock_put) __P((DB_ENV *, DB_LOCK *)); + int (*lock_id) __P((DB_ENV *, u_int32_t *)); + int (*lock_id_free) __P((DB_ENV *, u_int32_t)); + int (*lock_stat) __P((DB_ENV *, DB_LOCK_STAT **, u_int32_t)); + int (*lock_stat_print) __P((DB_ENV *, u_int32_t)); + int (*lock_vec) __P((DB_ENV *, + u_int32_t, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **)); + + void *mp_handle; /* Mpool handle and methods. */ + int (*get_cachesize) __P((DB_ENV *, u_int32_t *, u_int32_t *, int *)); + int (*set_cachesize) __P((DB_ENV *, u_int32_t, u_int32_t, int)); + int (*get_mp_mmapsize) __P((DB_ENV *, size_t *)); + int (*set_mp_mmapsize) __P((DB_ENV *, size_t)); + int (*get_mp_max_openfd) __P((DB_ENV *, int *)); + int (*set_mp_max_openfd) __P((DB_ENV *, int)); + int (*get_mp_max_write) __P((DB_ENV *, int *, int *)); + int (*set_mp_max_write) __P((DB_ENV *, int, int)); + int (*memp_fcreate) __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t)); + int (*memp_register) __P((DB_ENV *, int, + int (*)(DB_ENV *, db_pgno_t, void *, DBT *), + int (*)(DB_ENV *, db_pgno_t, void *, DBT *))); + int (*memp_stat) __P((DB_ENV *, + DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t)); + int (*memp_stat_print) __P((DB_ENV *, u_int32_t)); + int (*memp_sync) __P((DB_ENV *, DB_LSN *)); + int (*memp_trickle) __P((DB_ENV *, int, int *)); + + void *rep_handle; /* Replication handle and methods. */ + int (*rep_elect) __P((DB_ENV *, int, int, int, + u_int32_t, int *, u_int32_t)); + int (*rep_flush) __P((DB_ENV *)); + int (*rep_process_message) __P((DB_ENV *, DBT *, DBT *, + int *, DB_LSN *)); + int (*rep_start) __P((DB_ENV *, DBT *, u_int32_t)); + int (*rep_stat) __P((DB_ENV *, DB_REP_STAT **, u_int32_t)); + int (*rep_stat_print) __P((DB_ENV *, u_int32_t)); + int (*get_rep_limit) __P((DB_ENV *, u_int32_t *, u_int32_t *)); + int (*set_rep_limit) __P((DB_ENV *, u_int32_t, u_int32_t)); + int (*set_rep_request) __P((DB_ENV *, u_int32_t, u_int32_t)); + int (*set_rep_transport) __P((DB_ENV *, int, + int (*) (DB_ENV *, const DBT *, const DBT *, const DB_LSN *, + int, u_int32_t))); + + void *tx_handle; /* Txn handle and methods. */ + int (*get_tx_max) __P((DB_ENV *, u_int32_t *)); + int (*set_tx_max) __P((DB_ENV *, u_int32_t)); + int (*get_tx_timestamp) __P((DB_ENV *, time_t *)); + int (*set_tx_timestamp) __P((DB_ENV *, time_t *)); + int (*txn_begin) __P((DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t)); + int (*txn_checkpoint) __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t)); + int (*txn_recover) __P((DB_ENV *, + DB_PREPLIST *, long, long *, u_int32_t)); + int (*txn_stat) __P((DB_ENV *, DB_TXN_STAT **, u_int32_t)); + int (*txn_stat_print) __P((DB_ENV *, u_int32_t)); + int (*get_timeout) __P((DB_ENV *, db_timeout_t *, u_int32_t)); + int (*set_timeout) __P((DB_ENV *, db_timeout_t, u_int32_t)); + +#define DB_TEST_ELECTINIT 1 /* after __rep_elect_init */ +#define DB_TEST_ELECTVOTE1 2 /* after sending VOTE1 */ +#define DB_TEST_POSTDESTROY 3 /* after destroy op */ +#define DB_TEST_POSTLOG 4 /* after logging all pages */ +#define DB_TEST_POSTLOGMETA 5 /* after logging meta in btree */ +#define DB_TEST_POSTOPEN 6 /* after __os_open */ +#define DB_TEST_POSTSYNC 7 /* after syncing the log */ +#define DB_TEST_PREDESTROY 8 /* before destroy op */ +#define DB_TEST_PREOPEN 9 /* before __os_open */ +#define DB_TEST_SUBDB_LOCKS 10 /* subdb locking tests */ + int test_abort; /* Abort value for testing. */ + int test_check; /* Checkpoint value for testing. */ + int test_copy; /* Copy value for testing. */ + +#define DB_ENV_AUTO_COMMIT 0x0000001 /* DB_AUTO_COMMIT. */ +#define DB_ENV_CDB 0x0000002 /* DB_INIT_CDB. */ +#define DB_ENV_CDB_ALLDB 0x0000004 /* CDB environment wide locking. */ +#define DB_ENV_CREATE 0x0000008 /* DB_CREATE set. */ +#define DB_ENV_DBLOCAL 0x0000010 /* DB_ENV allocated for private DB. */ +#define DB_ENV_DIRECT_DB 0x0000020 /* DB_DIRECT_DB set. */ +#define DB_ENV_DIRECT_LOG 0x0000040 /* DB_DIRECT_LOG set. */ +#define DB_ENV_DSYNC_LOG 0x0000080 /* DB_DSYNC_LOG set. */ +#define DB_ENV_FATAL 0x0000100 /* Doing fatal recovery in env. */ +#define DB_ENV_LOCKDOWN 0x0000200 /* DB_LOCKDOWN set. */ +#define DB_ENV_LOG_AUTOREMOVE 0x0000400 /* DB_LOG_AUTOREMOVE set. */ +#define DB_ENV_LOG_INMEMORY 0x0000800 /* DB_LOG_INMEMORY set. */ +#define DB_ENV_NOLOCKING 0x0001000 /* DB_NOLOCKING set. */ +#define DB_ENV_NOMMAP 0x0002000 /* DB_NOMMAP set. */ +#define DB_ENV_NOPANIC 0x0004000 /* Okay if panic set. */ +#define DB_ENV_OPEN_CALLED 0x0008000 /* DB_ENV->open called. */ +#define DB_ENV_OVERWRITE 0x0010000 /* DB_OVERWRITE set. */ +#define DB_ENV_PRIVATE 0x0020000 /* DB_PRIVATE set. */ +#define DB_ENV_REGION_INIT 0x0040000 /* DB_REGION_INIT set. */ +#define DB_ENV_RPCCLIENT 0x0080000 /* DB_RPCCLIENT set. */ +#define DB_ENV_RPCCLIENT_GIVEN 0x0100000 /* User-supplied RPC client struct */ +#define DB_ENV_SYSTEM_MEM 0x0200000 /* DB_SYSTEM_MEM set. */ +#define DB_ENV_THREAD 0x0400000 /* DB_THREAD set. */ +#define DB_ENV_TIME_NOTGRANTED 0x0800000 /* DB_TIME_NOTGRANTED set. */ +#define DB_ENV_TXN_NOSYNC 0x1000000 /* DB_TXN_NOSYNC set. */ +#define DB_ENV_TXN_WRITE_NOSYNC 0x2000000 /* DB_TXN_WRITE_NOSYNC set. */ +#define DB_ENV_YIELDCPU 0x4000000 /* DB_YIELDCPU set. */ + u_int32_t flags; +}; + +#ifndef DB_DBM_HSEARCH +#define DB_DBM_HSEARCH 0 /* No historic interfaces by default. */ +#endif +#if DB_DBM_HSEARCH != 0 +/******************************************************* + * Dbm/Ndbm historic interfaces. + *******************************************************/ +typedef struct __db DBM; + +#define DBM_INSERT 0 /* Flags to dbm_store(). */ +#define DBM_REPLACE 1 + +/* + * The DB support for ndbm(3) always appends this suffix to the + * file name to avoid overwriting the user's original database. + */ +#define DBM_SUFFIX ".db" + +#if defined(_XPG4_2) +typedef struct { + char *dptr; + size_t dsize; +} datum; +#else +typedef struct { + char *dptr; + int dsize; +} datum; +#endif + +/* + * Translate NDBM calls into DB calls so that DB doesn't step on the + * application's name space. + */ +#define dbm_clearerr(a) __db_ndbm_clearerr(a) +#define dbm_close(a) __db_ndbm_close(a) +#define dbm_delete(a, b) __db_ndbm_delete(a, b) +#define dbm_dirfno(a) __db_ndbm_dirfno(a) +#define dbm_error(a) __db_ndbm_error(a) +#define dbm_fetch(a, b) __db_ndbm_fetch(a, b) +#define dbm_firstkey(a) __db_ndbm_firstkey(a) +#define dbm_nextkey(a) __db_ndbm_nextkey(a) +#define dbm_open(a, b, c) __db_ndbm_open(a, b, c) +#define dbm_pagfno(a) __db_ndbm_pagfno(a) +#define dbm_rdonly(a) __db_ndbm_rdonly(a) +#define dbm_store(a, b, c, d) \ + __db_ndbm_store(a, b, c, d) + +/* + * Translate DBM calls into DB calls so that DB doesn't step on the + * application's name space. + * + * The global variables dbrdonly, dirf and pagf were not retained when 4BSD + * replaced the dbm interface with ndbm, and are not supported here. + */ +#define dbminit(a) __db_dbm_init(a) +#define dbmclose __db_dbm_close +#if !defined(__cplusplus) +#define delete(a) __db_dbm_delete(a) +#endif +#define fetch(a) __db_dbm_fetch(a) +#define firstkey __db_dbm_firstkey +#define nextkey(a) __db_dbm_nextkey(a) +#define store(a, b) __db_dbm_store(a, b) + +/******************************************************* + * Hsearch historic interface. + *******************************************************/ +typedef enum { + FIND, ENTER +} ACTION; + +typedef struct entry { + char *key; + char *data; +} ENTRY; + +#define hcreate(a) __db_hcreate(a) +#define hdestroy __db_hdestroy +#define hsearch(a, b) __db_hsearch(a, b) + +#endif /* DB_DBM_HSEARCH */ + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_H_ */ + +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _DB_EXT_PROT_IN_ +#define _DB_EXT_PROT_IN_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int db_create __P((DB **, DB_ENV *, u_int32_t)); +char *db_strerror __P((int)); +int db_env_create __P((DB_ENV **, u_int32_t)); +char *db_version __P((int *, int *, int *)); +int log_compare __P((const DB_LSN *, const DB_LSN *)); +int db_env_set_func_close __P((int (*)(int))); +int db_env_set_func_dirfree __P((void (*)(char **, int))); +int db_env_set_func_dirlist __P((int (*)(const char *, char ***, int *))); +int db_env_set_func_exists __P((int (*)(const char *, int *))); +int db_env_set_func_free __P((void (*)(void *))); +int db_env_set_func_fsync __P((int (*)(int))); +int db_env_set_func_ftruncate __P((int (*)(int, off_t))); +int db_env_set_func_ioinfo __P((int (*)(const char *, int, u_int32_t *, u_int32_t *, u_int32_t *))); +int db_env_set_func_malloc __P((void *(*)(size_t))); +int db_env_set_func_map __P((int (*)(char *, size_t, int, int, void **))); +int db_env_set_func_pread __P((ssize_t (*)(int, void *, size_t, off_t))); +int db_env_set_func_pwrite __P((ssize_t (*)(int, const void *, size_t, off_t))); +int db_env_set_func_open __P((int (*)(const char *, int, ...))); +int db_env_set_func_read __P((ssize_t (*)(int, void *, size_t))); +int db_env_set_func_realloc __P((void *(*)(void *, size_t))); +int db_env_set_func_rename __P((int (*)(const char *, const char *))); +int db_env_set_func_seek __P((int (*)(int, off_t, int))); +int db_env_set_func_sleep __P((int (*)(u_long, u_long))); +int db_env_set_func_unlink __P((int (*)(const char *))); +int db_env_set_func_unmap __P((int (*)(void *, size_t))); +int db_env_set_func_write __P((ssize_t (*)(int, const void *, size_t))); +int db_env_set_func_yield __P((int (*)(void))); +int db_sequence_create __P((DB_SEQUENCE **, DB *, u_int32_t)); +#if DB_DBM_HSEARCH != 0 +int __db_ndbm_clearerr __P((DBM *)); +void __db_ndbm_close __P((DBM *)); +int __db_ndbm_delete __P((DBM *, datum)); +int __db_ndbm_dirfno __P((DBM *)); +int __db_ndbm_error __P((DBM *)); +datum __db_ndbm_fetch __P((DBM *, datum)); +datum __db_ndbm_firstkey __P((DBM *)); +datum __db_ndbm_nextkey __P((DBM *)); +DBM *__db_ndbm_open __P((const char *, int, int)); +int __db_ndbm_pagfno __P((DBM *)); +int __db_ndbm_rdonly __P((DBM *)); +int __db_ndbm_store __P((DBM *, datum, datum, int)); +int __db_dbm_close __P((void)); +int __db_dbm_delete __P((datum)); +datum __db_dbm_fetch __P((datum)); +datum __db_dbm_firstkey __P((void)); +int __db_dbm_init __P((char *)); +datum __db_dbm_nextkey __P((datum)); +int __db_dbm_store __P((datum, datum)); +#endif +#if DB_DBM_HSEARCH != 0 +int __db_hcreate __P((size_t)); +ENTRY *__db_hsearch __P((ENTRY, ACTION)); +void __db_hdestroy __P((void)); +#endif + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_EXT_PROT_IN_ */ diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_archive.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_archive.dsp new file mode 100644 index 00000000..feef949d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_archive.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="db_archive" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=db_archive - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_archive.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_archive.mak" CFG="db_archive - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_archive - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "db_archive - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "db_archive - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "db_archive - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_archive - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "db_archive - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "db_archive - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "db_archive - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_archive - Win32 Release" +# Name "db_archive - Win32 Debug" +# Name "db_archive - Win32 Release Static" +# Name "db_archive - Win32 Debug Static" +# Begin Source File + +SOURCE=..\db_archive\db_archive.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_archive.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_archive.vcproj new file mode 100644 index 00000000..8054eb78 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_archive.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_checkpoint.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_checkpoint.dsp new file mode 100644 index 00000000..12a48bcf --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_checkpoint.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="db_checkpoint" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=db_checkpoint - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_checkpoint.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_checkpoint.mak" CFG="db_checkpoint - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_checkpoint - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "db_checkpoint - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "db_checkpoint - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "db_checkpoint - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_checkpoint - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "db_checkpoint - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "db_checkpoint - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "db_checkpoint - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_checkpoint - Win32 Release" +# Name "db_checkpoint - Win32 Debug" +# Name "db_checkpoint - Win32 Release Static" +# Name "db_checkpoint - Win32 Debug Static" +# Begin Source File + +SOURCE=..\db_checkpoint\db_checkpoint.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_checkpoint.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_checkpoint.vcproj new file mode 100644 index 00000000..24f2d79d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_checkpoint.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_config.h b/src/libs/resiprocate/contrib/db/build_win32/db_config.h new file mode 100644 index 00000000..db3a52c8 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_config.h @@ -0,0 +1,443 @@ +/* DO NOT EDIT: automatically built by dist/s_win32. */ +/* Define to 1 if you want to build a version for running the test suite. */ +/* #undef CONFIG_TEST */ + +/* We use DB_WIN32 much as one would use _WIN32 -- to specify that we're using + an operating system environment that supports Win32 calls and semantics. We + don't use _WIN32 because Cygwin/GCC also defines _WIN32, even though + Cygwin/GCC closely emulates the Unix environment. */ +#define DB_WIN32 1 + +/* Define to 1 if you want a debugging version. */ +/* #undef DEBUG */ +#if defined(_DEBUG) +#if !defined(DEBUG) +#define DEBUG 1 +#endif +#endif + +/* Define to 1 if you want a version that logs read operations. */ +/* #undef DEBUG_ROP */ + +/* Define to 1 if you want a version that logs write operations. */ +/* #undef DEBUG_WOP */ + +/* Define to 1 if you want a version with run-time diagnostic checking. */ +/* #undef DIAGNOSTIC */ + +/* Define to 1 if you have the `clock_gettime' function. */ +/* #undef HAVE_CLOCK_GETTIME */ + +/* Define to 1 if Berkeley DB release includes strong cryptography. */ +#ifndef HAVE_SMALLBUILD +/* #undef HAVE_CRYPTO */ +#endif + +/* Define to 1 if you have the `directio' function. */ +/* #undef HAVE_DIRECTIO */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_DIRENT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have EXIT_SUCCESS/EXIT_FAILURE #defines. */ +#define HAVE_EXIT_SUCCESS 1 + +/* Define to 1 if fcntl/F_SETFD denies child access to file descriptors. */ +/* #undef HAVE_FCNTL_F_SETFD */ + +/* Define to 1 if you have the `fdatasync' function. */ +/* #undef HAVE_FDATASYNC */ + +/* Define to 1 if allocated filesystem blocks are not zeroed. */ +#define HAVE_FILESYSTEM_NOTZERO 1 + +/* Define to 1 if you have the `ftruncate' function. */ +#define HAVE_FTRUNCATE 1 + +/* Define to 1 if you have the `getcwd' function. */ +#define HAVE_GETCWD 1 + +/* Define to 1 if you have the `getopt' function. */ +/* #undef HAVE_GETOPT */ + +/* Define to 1 if you have the `getrusage' function. */ +/* #undef HAVE_GETRUSAGE */ + +/* Define to 1 if you have the `gettimeofday' function. */ +/* #undef HAVE_GETTIMEOFDAY */ + +/* Define to 1 if you have the `getuid' function. */ +/* #undef HAVE_GETUID */ + +/* Define to 1 if building Hash access method. */ +#ifndef HAVE_SMALLBUILD +#define HAVE_HASH 1 +#endif + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTTYPES_H */ + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define to 1 if the system has the type `long long'. */ +#define HAVE_LONG_LONG 1 + +/* Define to 1 if you have the `memcmp' function. */ +#define HAVE_MEMCMP 1 + +/* Define to 1 if you have the `memcpy' function. */ +#define HAVE_MEMCPY 1 + +/* Define to 1 if you have the `memmove' function. */ +#define HAVE_MEMMOVE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `mlock' function. */ +/* #undef HAVE_MLOCK */ + +/* Define to 1 if you have the `mmap' function. */ +/* #undef HAVE_MMAP */ + +/* Define to 1 if you have the `munlock' function. */ +/* #undef HAVE_MUNLOCK */ + +/* Define to 1 if you have the `munmap' function. */ +/* #undef HAVE_MUNMAP */ + +/* Define to 1 to use the GCC compiler and 68K assembly language mutexes. */ +/* #undef HAVE_MUTEX_68K_GCC_ASSEMBLY */ + +/* Define to 1 to use the AIX _check_lock mutexes. */ +/* #undef HAVE_MUTEX_AIX_CHECK_LOCK */ + +/* Define to 1 to use the GCC compiler and Alpha assembly language mutexes. */ +/* #undef HAVE_MUTEX_ALPHA_GCC_ASSEMBLY */ + +/* Define to 1 to use the GCC compiler and ARM assembly language mutexes. */ +/* #undef HAVE_MUTEX_ARM_GCC_ASSEMBLY */ + +/* Define to 1 to use the Apple/Darwin _spin_lock_try mutexes. */ +/* #undef HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY */ + +/* Define to 1 to use the UNIX fcntl system call mutexes. */ +/* #undef HAVE_MUTEX_FCNTL */ + +/* Define to 1 to use the GCC compiler and PaRisc assembly language mutexes. + */ +/* #undef HAVE_MUTEX_HPPA_GCC_ASSEMBLY */ + +/* Define to 1 to use the msem_XXX mutexes on HP-UX. */ +/* #undef HAVE_MUTEX_HPPA_MSEM_INIT */ + +/* Define to 1 to use the GCC compiler and IA64 assembly language mutexes. */ +/* #undef HAVE_MUTEX_IA64_GCC_ASSEMBLY */ + +/* Define to 1 to use the msem_XXX mutexes on systems other than HP-UX. */ +/* #undef HAVE_MUTEX_MSEM_INIT */ + +/* Define to 1 to use the GCC compiler and PowerPC assembly language mutexes. + */ +/* #undef HAVE_MUTEX_PPC_GCC_ASSEMBLY */ + +/* Define to 1 to use POSIX 1003.1 pthread_XXX mutexes. */ +/* #undef HAVE_MUTEX_PTHREADS */ + +/* Define to 1 to use Reliant UNIX initspin mutexes. */ +/* #undef HAVE_MUTEX_RELIANTUNIX_INITSPIN */ + +/* Define to 1 to use the IBM C compiler and S/390 assembly language mutexes. + */ +/* #undef HAVE_MUTEX_S390_CC_ASSEMBLY */ + +/* Define to 1 to use the GCC compiler and S/390 assembly language mutexes. */ +/* #undef HAVE_MUTEX_S390_GCC_ASSEMBLY */ + +/* Define to 1 to use the SCO compiler and x86 assembly language mutexes. */ +/* #undef HAVE_MUTEX_SCO_X86_CC_ASSEMBLY */ + +/* Define to 1 to use the obsolete POSIX 1003.1 sema_XXX mutexes. */ +/* #undef HAVE_MUTEX_SEMA_INIT */ + +/* Define to 1 to use the SGI XXX_lock mutexes. */ +/* #undef HAVE_MUTEX_SGI_INIT_LOCK */ + +/* Define to 1 to use the Solaris _lock_XXX mutexes. */ +/* #undef HAVE_MUTEX_SOLARIS_LOCK_TRY */ + +/* Define to 1 to use the Solaris lwp threads mutexes. */ +/* #undef HAVE_MUTEX_SOLARIS_LWP */ + +/* Define to 1 to use the GCC compiler and Sparc assembly language mutexes. */ +/* #undef HAVE_MUTEX_SPARC_GCC_ASSEMBLY */ + +/* Define to 1 if mutexes hold system resources. */ +/* #undef HAVE_MUTEX_SYSTEM_RESOURCES */ + +/* Define to 1 if fast mutexes are available. */ +#define HAVE_MUTEX_THREADS 1 + +/* Define to 1 to configure mutexes intra-process only. */ +/* #undef HAVE_MUTEX_THREAD_ONLY */ + +/* Define to 1 to use the CC compiler and Tru64 assembly language mutexes. */ +/* #undef HAVE_MUTEX_TRU64_CC_ASSEMBLY */ + +/* Define to 1 to use the UNIX International mutexes. */ +/* #undef HAVE_MUTEX_UI_THREADS */ + +/* Define to 1 to use the UTS compiler and assembly language mutexes. */ +/* #undef HAVE_MUTEX_UTS_CC_ASSEMBLY */ + +/* Define to 1 to use VMS mutexes. */ +/* #undef HAVE_MUTEX_VMS */ + +/* Define to 1 to use VxWorks mutexes. */ +/* #undef HAVE_MUTEX_VXWORKS */ + +/* Define to 1 to use the MSVC compiler and Windows mutexes. */ +#define HAVE_MUTEX_WIN32 1 + +/* Define to 1 to use the GCC compiler and Windows mutexes. */ +/* #undef HAVE_MUTEX_WIN32_GCC */ + +/* Define to 1 to use the GCC compiler and x86 assembly language mutexes. */ +/* #undef HAVE_MUTEX_X86_GCC_ASSEMBLY */ + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the O_DIRECT flag. */ +/* #undef HAVE_O_DIRECT */ + +/* Define to 1 if you have the `pread' function. */ +/* #undef HAVE_PREAD */ + +/* Define to 1 if you have the `pstat_getdynamic' function. */ +/* #undef HAVE_PSTAT_GETDYNAMIC */ + +/* Define to 1 if you have the `pwrite' function. */ +/* #undef HAVE_PWRITE */ + +/* Define to 1 if building on QNX. */ +/* #undef HAVE_QNX */ + +/* Define to 1 if building Queue access method. */ +#ifndef HAVE_SMALLBUILD +#define HAVE_QUEUE 1 +#endif + +/* Define to 1 if you have the `raise' function. */ +#define HAVE_RAISE 1 + +/* Define to 1 if you have the `rand' function. */ +#define HAVE_RAND 1 + +/* Define to 1 if building replication support. */ +#ifndef HAVE_SMALLBUILD +#define HAVE_REPLICATION 1 +#endif + +/* Define to 1 if building RPC client/server. */ +/* #undef HAVE_RPC */ + +/* Define to 1 if you have the `sched_yield' function. */ +/* #undef HAVE_SCHED_YIELD */ + +/* Define to 1 if you have the `select' function. */ +/* #undef HAVE_SELECT */ + +/* Define to 1 if building sequence support. */ +#define HAVE_SEQUENCE 1 + +/* Define to 1 if you have the `shmget' function. */ +/* #undef HAVE_SHMGET */ + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* Define to 1 if you have the `srand' function. */ +#define HAVE_SRAND 1 + +/* Define to 1 if building statistics support. */ +#define HAVE_STATISTICS 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDINT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strcasecmp' function. */ +/* #undef HAVE_STRCASECMP */ + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strtol' function. */ +#define HAVE_STRTOL 1 + +/* Define to 1 if you have the `strtoul' function. */ +#define HAVE_STRTOUL 1 + +/* Define to 1 if `st_blksize' is member of `struct stat'. */ +/* #undef HAVE_STRUCT_STAT_ST_BLKSIZE */ + +/* Define to 1 if you have the `sysconf' function. */ +/* #undef HAVE_SYSCONF */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FCNTL_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SELECT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TIME_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UNISTD_H */ + +/* Define to 1 if unlink of file with open file descriptors will fail. */ +/* #undef HAVE_UNLINK_WITH_OPEN_FAILURE */ + +/* Define to 1 if the system has the type `unsigned long long'. */ +#define HAVE_UNSIGNED_LONG_LONG 1 + +/* Define to 1 if building access method verification support. */ +#ifndef HAVE_SMALLBUILD +#define HAVE_VERIFY 1 +#endif + +/* Define to 1 if you have the `vsnprintf' function. */ +#define HAVE_VSNPRINTF 1 + +/* Define to 1 if building VxWorks. */ +/* #undef HAVE_VXWORKS */ + +/* Define to 1 if you have the `yield' function. */ +/* #undef HAVE_YIELD */ + +/* Define to 1 if you have the `_fstati64' function. */ +#define HAVE__FSTATI64 1 + +/* Define to a value if using non-standard mutex alignment. */ +/* #undef MUTEX_ALIGN */ + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "support@sleepycat.com" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "Berkeley DB" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "Berkeley DB 4.3.27" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "db-4.3.27" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "4.3.27" + +/* Define to 1 if the `S_IS*' macros in do not work properly. */ +/* #undef STAT_MACROS_BROKEN */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +/* #undef TIME_WITH_SYS_TIME */ + +/* Define to 1 to mask harmless uninitialized memory read/writes. */ +/* #undef UMRW */ + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* + * Exit success/failure macros. + */ +#ifndef HAVE_EXIT_SUCCESS +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 +#endif + +/* + * Don't step on the namespace. Other libraries may have their own + * implementations of these functions, we don't want to use their + * implementations or force them to use ours based on the load order. + */ +#ifndef HAVE_GETCWD +#define getcwd __db_Cgetcwd +#endif +#ifndef HAVE_MEMCMP +#define memcmp __db_Cmemcmp +#endif +#ifndef HAVE_MEMCPY +#define memcpy __db_Cmemcpy +#endif +#ifndef HAVE_MEMMOVE +#define memmove __db_Cmemmove +#endif +#ifndef HAVE_RAISE +#define raise __db_Craise +#endif +#ifndef HAVE_SNPRINTF +#define snprintf __db_Csnprintf +#endif +#ifndef HAVE_STRCASECMP +#define strcasecmp __db_Cstrcasecmp +#define strncasecmp __db_Cstrncasecmp +#endif +#ifndef HAVE_STRERROR +#define strerror __db_Cstrerror +#endif +#ifndef HAVE_VSNPRINTF +#define vsnprintf __db_Cvsnprintf +#endif + +#include "win_db.h" + +/* + * Microsoft's compiler _doesn't_ define __STDC__ unless you invoke it with + * arguments turning OFF all vendor extensions. Even more unfortunately, if + * we do that, it fails to parse windows.h!!!!! So, we define __STDC__ here, + * after windows.h comes in. Note: the compiler knows we've defined it, and + * starts enforcing strict ANSI compliance from this point on. + */ +#define __STDC__ 1 diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_cxx.h b/src/libs/resiprocate/contrib/db/build_win32/db_cxx.h new file mode 100644 index 00000000..abba7b63 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_cxx.h @@ -0,0 +1,1089 @@ +/* DO NOT EDIT: automatically built by dist/s_win32. */ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2004 + * Sleepycat Software. All rights reserved. + * + * $Id: db_cxx.in,v 11.147 2004/10/07 21:39:48 bostic Exp $ + */ + +#ifndef _DB_CXX_H_ +#define _DB_CXX_H_ +// +// C++ assumptions: +// +// To ensure portability to many platforms, both new and old, we make +// few assumptions about the C++ compiler and library. For example, +// we do not expect STL, templates or namespaces to be available. The +// "newest" C++ feature used is exceptions, which are used liberally +// to transmit error information. Even the use of exceptions can be +// disabled at runtime, to do so, use the DB_CXX_NO_EXCEPTIONS flags +// with the DbEnv or Db constructor. +// +// C++ naming conventions: +// +// - All top level class names start with Db. +// - All class members start with lower case letter. +// - All private data members are suffixed with underscore. +// - Use underscores to divide names into multiple words. +// - Simple data accessors are named with get_ or set_ prefix. +// - All method names are taken from names of functions in the C +// layer of db (usually by dropping a prefix like "db_"). +// These methods have the same argument types and order, +// other than dropping the explicit arg that acts as "this". +// +// As a rule, each DbFoo object has exactly one underlying DB_FOO struct +// (defined in db.h) associated with it. In some cases, we inherit directly +// from the DB_FOO structure to make this relationship explicit. Often, +// the underlying C layer allocates and deallocates these structures, so +// there is no easy way to add any data to the DbFoo class. When you see +// a comment about whether data is permitted to be added, this is what +// is going on. Of course, if we need to add data to such C++ classes +// in the future, we will arrange to have an indirect pointer to the +// DB_FOO struct (as some of the classes already have). +// + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +// +// Forward declarations +// + +#include + +#define HAVE_CXX_STDHEADERS 1 +#ifdef HAVE_CXX_STDHEADERS +#include +#include +#define __DB_STD(x) std::x +#else +#include +#include +#define __DB_STD(x) x +#endif + +#include "db.h" + +class Db; // forward +class Dbc; // forward +class DbEnv; // forward +class DbInfo; // forward +class DbLock; // forward +class DbLogc; // forward +class DbLsn; // forward +class DbMpoolFile; // forward +class DbPreplist; // forward +class Dbt; // forward +class DbTxn; // forward +class DbLock; // forward +class DbSequence; // forward +class Dbt; // forward + +class DbMultipleIterator; // forward +class DbMultipleKeyDataIterator; // forward +class DbMultipleRecnoDataIterator; // forward +class DbMultipleDataIterator; // forward + +class DbException; // forward +class DbDeadlockException; // forward +class DbLockNotGrantedException; // forward +class DbMemoryException; // forward +class DbRunRecoveryException; // forward + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +// +// Turn off inappropriate compiler warnings +// + +#ifdef _MSC_VER + +// These are level 4 warnings that are explicitly disabled. +// With Visual C++, by default you do not see above level 3 unless +// you use /W4. But we like to compile with the highest level +// warnings to catch other errors. +// +// 4201: nameless struct/union +// triggered by standard include file +// +// 4514: unreferenced inline function has been removed +// certain include files in MSVC define methods that are not called +// +#pragma warning(disable: 4201 4514) + +#endif + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +// +// Mechanisms for declaring classes +// + +// +// Every class defined in this file has an _exported next to the class name. +// This is needed for WinTel machines so that the class methods can +// be exported or imported in a DLL as appropriate. Users of the DLL +// use the define DB_USE_DLL. When the DLL is built, DB_CREATE_DLL +// must be defined. +// +#if defined(_MSC_VER) + +# if defined(DB_CREATE_DLL) +# define _exported __declspec(dllexport) // creator of dll +# elif defined(DB_USE_DLL) +# define _exported __declspec(dllimport) // user of dll +# else +# define _exported // static lib creator or user +# endif + +#else /* _MSC_VER */ + +# define _exported + +#endif /* _MSC_VER */ + +// Some interfaces can be customized by allowing users to define +// callback functions. For performance and logistical reasons, some +// callback functions must be declared in extern "C" blocks. For others, +// we allow you to declare the callbacks in C++ or C (or an extern "C" +// block) as you wish. See the set methods for the callbacks for +// the choices. +// +extern "C" { + typedef void * (*db_malloc_fcn_type) + (size_t); + typedef void * (*db_realloc_fcn_type) + (void *, size_t); + typedef void (*db_free_fcn_type) + (void *); + typedef int (*bt_compare_fcn_type) /*C++ version available*/ + (DB *, const DBT *, const DBT *); + typedef size_t (*bt_prefix_fcn_type) /*C++ version available*/ + (DB *, const DBT *, const DBT *); + typedef int (*dup_compare_fcn_type) /*C++ version available*/ + (DB *, const DBT *, const DBT *); + typedef u_int32_t (*h_hash_fcn_type) /*C++ version available*/ + (DB *, const void *, u_int32_t); + typedef int (*pgin_fcn_type) + (DB_ENV *dbenv, db_pgno_t pgno, void *pgaddr, DBT *pgcookie); + typedef int (*pgout_fcn_type) + (DB_ENV *dbenv, db_pgno_t pgno, void *pgaddr, DBT *pgcookie); +} + +// +// Represents a database table = a set of keys with associated values. +// +class _exported Db +{ + friend class DbEnv; + +public: + Db(DbEnv*, u_int32_t); // create a Db object, then call open() + virtual ~Db(); // does *not* call close. + + // These methods exactly match those in the C interface. + // + virtual int associate(DbTxn *txn, Db *secondary, + int (*callback)(Db *, const Dbt *, const Dbt *, Dbt *), + u_int32_t flags); + virtual int close(u_int32_t flags); + virtual int cursor(DbTxn *txnid, Dbc **cursorp, u_int32_t flags); + virtual int del(DbTxn *txnid, Dbt *key, u_int32_t flags); + virtual void err(int, const char *, ...); + virtual void errx(const char *, ...); + virtual int fd(int *fdp); + virtual int get(DbTxn *txnid, Dbt *key, Dbt *data, u_int32_t flags); + virtual void *get_app_private() const; + virtual int get_byteswapped(int *); + virtual int get_dbname(const char **, const char **); + virtual int get_open_flags(u_int32_t *); + virtual int get_type(DBTYPE *); + virtual int get_transactional(); + virtual int join(Dbc **curslist, Dbc **dbcp, u_int32_t flags); + virtual int key_range(DbTxn *, Dbt *, DB_KEY_RANGE *, u_int32_t); + virtual int open(DbTxn *txnid, + const char *, const char *subname, DBTYPE, u_int32_t, int); + virtual int pget(DbTxn *txnid, Dbt *key, Dbt *pkey, Dbt *data, + u_int32_t flags); + virtual int put(DbTxn *, Dbt *, Dbt *, u_int32_t); + virtual int remove(const char *, const char *, u_int32_t); + virtual int rename(const char *, const char *, const char *, u_int32_t); + virtual int set_alloc(db_malloc_fcn_type, db_realloc_fcn_type, + db_free_fcn_type); + virtual void set_app_private(void *); + virtual int set_append_recno(int (*)(Db *, Dbt *, db_recno_t)); + virtual int set_bt_compare(bt_compare_fcn_type); /*deprecated*/ + virtual int set_bt_compare(int (*)(Db *, const Dbt *, const Dbt *)); + virtual int set_bt_maxkey(u_int32_t); + virtual int get_bt_minkey(u_int32_t *); + virtual int set_bt_minkey(u_int32_t); + virtual int set_bt_prefix(bt_prefix_fcn_type); /*deprecated*/ + virtual int set_bt_prefix(size_t (*)(Db *, const Dbt *, const Dbt *)); + virtual int get_cachesize(u_int32_t *, u_int32_t *, int *); + virtual int set_cachesize(u_int32_t, u_int32_t, int); + virtual int set_dup_compare(dup_compare_fcn_type); /*deprecated*/ + virtual int set_dup_compare(int (*)(Db *, const Dbt *, const Dbt *)); + virtual int get_encrypt_flags(u_int32_t *); + virtual int set_encrypt(const char *, u_int32_t); + virtual void set_errcall( + void (*)(const DbEnv *, const char *, const char *)); + virtual void get_errfile(FILE **); + virtual void set_errfile(FILE *); + virtual void get_errpfx(const char **); + virtual void set_errpfx(const char *); + virtual int set_feedback(void (*)(Db *, int, int)); + virtual int get_flags(u_int32_t *); + virtual int set_flags(u_int32_t); + virtual int get_h_ffactor(u_int32_t *); + virtual int set_h_ffactor(u_int32_t); + virtual int set_h_hash(h_hash_fcn_type); /*deprecated*/ + virtual int set_h_hash(u_int32_t (*)(Db *, const void *, u_int32_t)); + virtual int get_h_nelem(u_int32_t *); + virtual int set_h_nelem(u_int32_t); + virtual int get_lorder(int *); + virtual int set_lorder(int); + virtual void set_msgcall(void (*)(const DbEnv *, const char *)); + virtual void get_msgfile(FILE **); + virtual void set_msgfile(FILE *); + virtual int get_pagesize(u_int32_t *); + virtual int set_pagesize(u_int32_t); + virtual int set_paniccall(void (*)(DbEnv *, int)); + virtual int get_re_delim(int *); + virtual int set_re_delim(int); + virtual int get_re_len(u_int32_t *); + virtual int set_re_len(u_int32_t); + virtual int get_re_pad(int *); + virtual int set_re_pad(int); + virtual int get_re_source(const char **); + virtual int set_re_source(const char *); + virtual int get_q_extentsize(u_int32_t *); + virtual int set_q_extentsize(u_int32_t); + virtual int stat(DbTxn *, void *sp, u_int32_t flags); + virtual int stat_print(u_int32_t flags); + virtual int sync(u_int32_t flags); + virtual int truncate(DbTxn *, u_int32_t *, u_int32_t); + virtual int upgrade(const char *name, u_int32_t flags); + virtual int verify(const char *, const char *, __DB_STD(ostream) *, + u_int32_t); + + // These additional methods are not in the C interface, and + // are only available for C++. + // + virtual __DB_STD(ostream) *get_error_stream(); + virtual void set_error_stream(__DB_STD(ostream) *); + virtual __DB_STD(ostream) *get_message_stream(); + virtual void set_message_stream(__DB_STD(ostream) *); + + virtual DbEnv *get_env(); + virtual DbMpoolFile *get_mpf(); + + virtual DB *get_DB() + { + return imp_; + } + + virtual const DB *get_const_DB() const + { + return imp_; + } + + static Db* get_Db(DB *db) + { + return (Db *)db->api_internal; + } + + static const Db* get_const_Db(const DB *db) + { + return (const Db *)db->api_internal; + } + +private: + // no copying + Db(const Db &); + Db &operator = (const Db &); + + void cleanup(); + int initialize(); + int error_policy(); + + // instance data + DB *imp_; + DbEnv *env_; + DbMpoolFile *mpf_; + int construct_error_; + u_int32_t flags_; + u_int32_t construct_flags_; + +public: + // These are public only because they need to be called + // via C callback functions. They should never be used by + // external users of this class. + // + int (*append_recno_callback_)(Db *, Dbt *, db_recno_t); + int (*associate_callback_)(Db *, const Dbt *, const Dbt *, Dbt *); + int (*bt_compare_callback_)(Db *, const Dbt *, const Dbt *); + size_t (*bt_prefix_callback_)(Db *, const Dbt *, const Dbt *); + int (*dup_compare_callback_)(Db *, const Dbt *, const Dbt *); + void (*feedback_callback_)(Db *, int, int); + u_int32_t (*h_hash_callback_)(Db *, const void *, u_int32_t); +}; + +// +// Cursor +// +class _exported Dbc : protected DBC +{ + friend class Db; + +public: + int close(); + int count(db_recno_t *countp, u_int32_t flags); + int del(u_int32_t flags); + int dup(Dbc** cursorp, u_int32_t flags); + int get(Dbt* key, Dbt *data, u_int32_t flags); + int pget(Dbt* key, Dbt* pkey, Dbt *data, u_int32_t flags); + int put(Dbt* key, Dbt *data, u_int32_t flags); + +private: + // No data is permitted in this class (see comment at top) + + // Note: use Db::cursor() to get pointers to a Dbc, + // and call Dbc::close() rather than delete to release them. + // + Dbc(); + ~Dbc(); + + // no copying + Dbc(const Dbc &); + Dbc &operator = (const Dbc &); +}; + +// +// Berkeley DB environment class. Provides functions for opening databases. +// User of this library can use this class as a starting point for +// developing a DB application - derive their application class from +// this one, add application control logic. +// +// Note that if you use the default constructor, you must explicitly +// call appinit() before any other db activity (e.g. opening files) +// +class _exported DbEnv +{ + friend class Db; + friend class DbLock; + friend class DbMpoolFile; + +public: + // After using this constructor, you can set any needed + // parameters for the environment using the set_* methods. + // Then call open() to finish initializing the environment + // and attaching it to underlying files. + // + DbEnv(u_int32_t flags); + + virtual ~DbEnv(); + + // These methods match those in the C interface. + // + virtual int close(u_int32_t); + virtual int dbremove(DbTxn *txn, const char *name, const char *subdb, + u_int32_t flags); + virtual int dbrename(DbTxn *txn, const char *name, const char *subdb, + const char *newname, u_int32_t flags); + virtual void err(int, const char *, ...); + virtual void errx(const char *, ...); + virtual void *get_app_private() const; + virtual int get_home(const char **); + virtual int get_open_flags(u_int32_t *); + virtual int open(const char *, u_int32_t, int); + virtual int remove(const char *, u_int32_t); + virtual int set_alloc(db_malloc_fcn_type, db_realloc_fcn_type, + db_free_fcn_type); + virtual void set_app_private(void *); + virtual int get_cachesize(u_int32_t *, u_int32_t *, int *); + virtual int set_cachesize(u_int32_t, u_int32_t, int); + virtual int get_data_dirs(const char ***); + virtual int set_data_dir(const char *); + virtual int get_encrypt_flags(u_int32_t *); + virtual int set_encrypt(const char *, u_int32_t); + virtual void set_errcall( + void (*)(const DbEnv *, const char *, const char *)); + virtual void get_errfile(FILE **); + virtual void set_errfile(FILE *); + virtual void get_errpfx(const char **); + virtual void set_errpfx(const char *); + virtual int get_flags(u_int32_t *); + virtual int set_flags(u_int32_t, int); + virtual int set_feedback(void (*)(DbEnv *, int, int)); + virtual int get_lg_bsize(u_int32_t *); + virtual int set_lg_bsize(u_int32_t); + virtual int get_lg_dir(const char **); + virtual int set_lg_dir(const char *); + virtual int get_lg_max(u_int32_t *); + virtual int set_lg_max(u_int32_t); + virtual int get_lg_regionmax(u_int32_t *); + virtual int set_lg_regionmax(u_int32_t); + virtual int get_lk_conflicts(const u_int8_t **, int *); + virtual int set_lk_conflicts(u_int8_t *, int); + virtual int get_lk_detect(u_int32_t *); + virtual int set_lk_detect(u_int32_t); + virtual int set_lk_max(u_int32_t); + virtual int get_lk_max_lockers(u_int32_t *); + virtual int set_lk_max_lockers(u_int32_t); + virtual int get_lk_max_locks(u_int32_t *); + virtual int set_lk_max_locks(u_int32_t); + virtual int get_lk_max_objects(u_int32_t *); + virtual int set_lk_max_objects(u_int32_t); + virtual int get_mp_mmapsize(size_t *); + virtual int set_mp_mmapsize(size_t); + virtual void set_msgcall(void (*)(const DbEnv *, const char *)); + virtual void get_msgfile(FILE **); + virtual void set_msgfile(FILE *); + virtual int set_paniccall(void (*)(DbEnv *, int)); + virtual int set_rpc_server(void *, char *, long, long, u_int32_t); + virtual int get_shm_key(long *); + virtual int set_shm_key(long); + virtual int get_timeout(db_timeout_t *, u_int32_t); + virtual int set_timeout(db_timeout_t, u_int32_t); + virtual int get_tmp_dir(const char **); + virtual int set_tmp_dir(const char *); + virtual int get_tas_spins(u_int32_t *); + virtual int set_tas_spins(u_int32_t); + virtual int get_tx_max(u_int32_t *); + virtual int set_tx_max(u_int32_t); + virtual int set_app_dispatch(int (*)(DbEnv *, + Dbt *, DbLsn *, db_recops)); + virtual int get_tx_timestamp(time_t *); + virtual int set_tx_timestamp(time_t *); + virtual int get_verbose(u_int32_t which, int *); + virtual int set_verbose(u_int32_t which, int); + + // Version information. A static method so it can be obtained anytime. + // + static char *version(int *major, int *minor, int *patch); + + // Convert DB errors to strings + static char *strerror(int); + + // If an error is detected and the error call function + // or stream is set, a message is dispatched or printed. + // If a prefix is set, each message is prefixed. + // + // You can use set_errcall() or set_errfile() above to control + // error functionality. Alternatively, you can call + // set_error_stream() to force all errors to a C++ stream. + // It is unwise to mix these approaches. + // + virtual __DB_STD(ostream) *get_error_stream(); + virtual void set_error_stream(__DB_STD(ostream) *); + virtual __DB_STD(ostream) *get_message_stream(); + virtual void set_message_stream(__DB_STD(ostream) *); + + // used internally + static void runtime_error(DbEnv *env, const char *caller, int err, + int error_policy); + static void runtime_error_dbt(DbEnv *env, const char *caller, Dbt *dbt, + int error_policy); + static void runtime_error_lock_get(DbEnv *env, const char *caller, + int err, db_lockop_t op, db_lockmode_t mode, + const Dbt *obj, DbLock lock, int index, + int error_policy); + + // Lock functions + // + virtual int lock_detect(u_int32_t flags, u_int32_t atype, int *aborted); + virtual int lock_get(u_int32_t locker, u_int32_t flags, const Dbt *obj, + db_lockmode_t lock_mode, DbLock *lock); + virtual int lock_id(u_int32_t *idp); + virtual int lock_id_free(u_int32_t id); + virtual int lock_put(DbLock *lock); + virtual int lock_stat(DB_LOCK_STAT **statp, u_int32_t flags); + virtual int lock_stat_print(u_int32_t flags); + virtual int lock_vec(u_int32_t locker, u_int32_t flags, + DB_LOCKREQ list[], int nlist, DB_LOCKREQ **elistp); + + // Log functions + // + virtual int log_archive(char **list[], u_int32_t flags); + static int log_compare(const DbLsn *lsn0, const DbLsn *lsn1); + virtual int log_cursor(DbLogc **cursorp, u_int32_t flags); + virtual int log_file(DbLsn *lsn, char *namep, size_t len); + virtual int log_flush(const DbLsn *lsn); + virtual int log_put(DbLsn *lsn, const Dbt *data, u_int32_t flags); + + virtual int log_stat(DB_LOG_STAT **spp, u_int32_t flags); + virtual int log_stat_print(u_int32_t flags); + + // Mpool functions + // + virtual int memp_fcreate(DbMpoolFile **dbmfp, u_int32_t flags); + virtual int memp_register(int ftype, + pgin_fcn_type pgin_fcn, + pgout_fcn_type pgout_fcn); + virtual int memp_stat(DB_MPOOL_STAT + **gsp, DB_MPOOL_FSTAT ***fsp, u_int32_t flags); + virtual int memp_stat_print(u_int32_t flags); + virtual int memp_sync(DbLsn *lsn); + virtual int memp_trickle(int pct, int *nwrotep); + + // Transaction functions + // + virtual int txn_begin(DbTxn *pid, DbTxn **tid, u_int32_t flags); + virtual int txn_checkpoint(u_int32_t kbyte, u_int32_t min, + u_int32_t flags); + virtual int txn_recover(DbPreplist *preplist, long count, + long *retp, u_int32_t flags); + virtual int txn_stat(DB_TXN_STAT **statp, u_int32_t flags); + virtual int txn_stat_print(u_int32_t flags); + + // Replication functions + // + virtual int rep_elect(int, int, int, u_int32_t, int *, u_int32_t); + virtual int rep_process_message(Dbt *, Dbt *, int *, DbLsn *); + virtual int rep_start(Dbt *, u_int32_t); + virtual int rep_stat(DB_REP_STAT **statp, u_int32_t flags); + virtual int rep_stat_print(u_int32_t flags); + virtual int get_rep_limit(u_int32_t *, u_int32_t *); + virtual int set_rep_limit(u_int32_t, u_int32_t); + virtual int set_rep_transport(int, int (*)(DbEnv *, + const Dbt *, const Dbt *, const DbLsn *, int, u_int32_t)); + + // Conversion functions + // + virtual DB_ENV *get_DB_ENV() + { + return imp_; + } + + virtual const DB_ENV *get_const_DB_ENV() const + { + return imp_; + } + + static DbEnv* get_DbEnv(DB_ENV *dbenv) + { + return dbenv ? (DbEnv *)dbenv->api1_internal : 0; + } + + static const DbEnv* get_const_DbEnv(const DB_ENV *dbenv) + { + return dbenv ? (const DbEnv *)dbenv->api1_internal : 0; + } + + // For internal use only. + static DbEnv* wrap_DB_ENV(DB_ENV *dbenv); + + // These are public only because they need to be called + // via C functions. They should never be called by users + // of this class. + // + static int _app_dispatch_intercept(DB_ENV *env, DBT *dbt, DB_LSN *lsn, + db_recops op); + static void _paniccall_intercept(DB_ENV *env, int errval); + static void _feedback_intercept(DB_ENV *env, int opcode, int pct); + static int _rep_send_intercept(DB_ENV *env, + const DBT *cntrl, const DBT *data, + const DB_LSN *lsn, int id, + u_int32_t flags); + static void _stream_error_function(const DB_ENV *env, + const char *prefix, + const char *message); + static void _stream_message_function(const DB_ENV *env, + const char *message); + +private: + void cleanup(); + int initialize(DB_ENV *env); + int error_policy(); + + // For internal use only. + DbEnv(DB_ENV *, u_int32_t flags); + + // no copying + DbEnv(const DbEnv &); + void operator = (const DbEnv &); + + // instance data + DB_ENV *imp_; + int construct_error_; + u_int32_t construct_flags_; + __DB_STD(ostream) *error_stream_; + __DB_STD(ostream) *message_stream_; + + int (*app_dispatch_callback_)(DbEnv *, Dbt *, DbLsn *, db_recops); + void (*error_callback_)(const DbEnv *, const char *, const char *); + void (*feedback_callback_)(DbEnv *, int, int); + void (*message_callback_)(const DbEnv *, const char *); + void (*paniccall_callback_)(DbEnv *, int); + int (*pgin_callback_)(DbEnv *dbenv, db_pgno_t pgno, + void *pgaddr, Dbt *pgcookie); + int (*pgout_callback_)(DbEnv *dbenv, db_pgno_t pgno, + void *pgaddr, Dbt *pgcookie); + int (*rep_send_callback_)(DbEnv *, + const Dbt *, const Dbt *, const DbLsn *, int, u_int32_t); +}; + +// +// Lock +// +class _exported DbLock +{ + friend class DbEnv; + +public: + DbLock(); + DbLock(const DbLock &); + DbLock &operator = (const DbLock &); + +protected: + // We can add data to this class if needed + // since its contained class is not allocated by db. + // (see comment at top) + + DbLock(DB_LOCK); + DB_LOCK lock_; +}; + +// +// Log cursor +// +class _exported DbLogc : protected DB_LOGC +{ + friend class DbEnv; + +public: + int close(u_int32_t _flags); + int get(DbLsn *lsn, Dbt *data, u_int32_t _flags); + +private: + // No data is permitted in this class (see comment at top) + + // Note: use Db::cursor() to get pointers to a Dbc, + // and call Dbc::close() rather than delete to release them. + // + DbLogc(); + ~DbLogc(); + + // no copying + DbLogc(const Dbc &); + DbLogc &operator = (const Dbc &); +}; + +// +// Log sequence number +// +class _exported DbLsn : public DB_LSN +{ + friend class DbEnv; // friendship needed to cast to base class + friend class DbLogc; // friendship needed to cast to base class +}; + +// +// Memory pool file +// +class _exported DbMpoolFile +{ + friend class DbEnv; + friend class Db; + +public: + int close(u_int32_t flags); + int get(db_pgno_t *pgnoaddr, u_int32_t flags, void *pagep); + int open(const char *file, u_int32_t flags, int mode, size_t pagesize); + int get_transactional(void); + int put(void *pgaddr, u_int32_t flags); + int set(void *pgaddr, u_int32_t flags); + int get_clear_len(u_int32_t *len); + int set_clear_len(u_int32_t len); + int get_fileid(u_int8_t *fileid); + int set_fileid(u_int8_t *fileid); + int get_flags(u_int32_t *flagsp); + int set_flags(u_int32_t flags, int onoff); + int get_ftype(int *ftype); + int set_ftype(int ftype); + int get_lsn_offset(int32_t *offsetp); + int set_lsn_offset(int32_t offset); + int get_maxsize(u_int32_t *gbytes, u_int32_t *bytes); + int set_maxsize(u_int32_t gbytes, u_int32_t bytes); + int get_pgcookie(DBT *dbt); + int set_pgcookie(DBT *dbt); + int get_priority(DB_CACHE_PRIORITY *priorityp); + int set_priority(DB_CACHE_PRIORITY priority); + int sync(); + + virtual DB_MPOOLFILE *get_DB_MPOOLFILE() + { + return imp_; + } + + virtual const DB_MPOOLFILE *get_const_DB_MPOOLFILE() const + { + return imp_; + } + +private: + DB_MPOOLFILE *imp_; + + // We can add data to this class if needed + // since it is implemented via a pointer. + // (see comment at top) + + // Note: use DbEnv::memp_fcreate() to get pointers to a DbMpoolFile, + // and call DbMpoolFile::close() rather than delete to release them. + // + DbMpoolFile(); + + // Shut g++ up. +protected: + virtual ~DbMpoolFile(); + +private: + // no copying + DbMpoolFile(const DbMpoolFile &); + void operator = (const DbMpoolFile &); +}; + +// +// This is filled in and returned by the DbEnv::txn_recover() method. +// +class _exported DbPreplist +{ +public: + DbTxn *txn; + u_int8_t gid[DB_XIDDATASIZE]; +}; + +// +// A sequence record in a database +// +class _exported DbSequence +{ +public: + DbSequence(Db *db, u_int32_t flags); + virtual ~DbSequence(); + + int open(DbTxn *txnid, Dbt *key, u_int32_t flags); + int initial_value(db_seq_t value); + int close(u_int32_t flags); + int remove(DbTxn *txnid, u_int32_t flags); + int stat(DB_SEQUENCE_STAT **sp, u_int32_t flags); + int stat_print(u_int32_t flags); + + int get(DbTxn *txnid, int32_t delta, db_seq_t *retp, u_int32_t flags); + int get_cachesize(int32_t *sizep); + int set_cachesize(int32_t size); + int get_flags(u_int32_t *flagsp); + int set_flags(u_int32_t flags); + int get_range(db_seq_t *minp, db_seq_t *maxp); + int set_range(db_seq_t min, db_seq_t max); + + Db *get_db(); + Dbt *get_key(); + + virtual DB_SEQUENCE *get_DB_SEQUENCE() + { + return imp_; + } + + virtual const DB_SEQUENCE *get_const_DB_SEQUENCE() const + { + return imp_; + } + + static DbSequence* get_DbSequence(DB_SEQUENCE *seq) + { + return (DbSequence *)seq->api_internal; + } + + static const DbSequence* get_const_DbSequence(const DB_SEQUENCE *seq) + { + return (const DbSequence *)seq->api_internal; + } + + // For internal use only. + static DbSequence* wrap_DB_SEQUENCE(DB_SEQUENCE *seq); + +private: + DbSequence(DB_SEQUENCE *seq); + // no copying + DbSequence(const DbSequence &); + DbSequence &operator = (const DbSequence &); + + DB_SEQUENCE *imp_; + DBT key_; +}; + +// +// Transaction +// +class _exported DbTxn +{ + friend class DbEnv; + +public: + int abort(); + int commit(u_int32_t flags); + int discard(u_int32_t flags); + u_int32_t id(); + int prepare(u_int8_t *gid); + int set_timeout(db_timeout_t timeout, u_int32_t flags); + + virtual DB_TXN *get_DB_TXN() + { + return imp_; + } + + virtual const DB_TXN *get_const_DB_TXN() const + { + return imp_; + } + + static DbTxn* get_DbTxn(DB_TXN *txn) + { + return (DbTxn *)txn->api_internal; + } + + static const DbTxn* get_const_DbTxn(const DB_TXN *txn) + { + return (const DbTxn *)txn->api_internal; + } + + // For internal use only. + static DbTxn* wrap_DB_TXN(DB_TXN *txn); + +private: + DB_TXN *imp_; + + // We can add data to this class if needed + // since it is implemented via a pointer. + // (see comment at top) + + // Note: use DbEnv::txn_begin() to get pointers to a DbTxn, + // and call DbTxn::abort() or DbTxn::commit rather than + // delete to release them. + // + DbTxn(); + // For internal use only. + DbTxn(DB_TXN *txn); + virtual ~DbTxn(); + + // no copying + DbTxn(const DbTxn &); + void operator = (const DbTxn &); +}; + +// +// A chunk of data, maybe a key or value. +// +class _exported Dbt : private DBT +{ + friend class Db; + friend class Dbc; + friend class DbEnv; + friend class DbLogc; + friend class DbSequence; + +public: + // key/data + void *get_data() const { return data; } + void set_data(void *value) { data = value; } + + // key/data length + u_int32_t get_size() const { return size; } + void set_size(u_int32_t value) { size = value; } + + // RO: length of user buffer. + u_int32_t get_ulen() const { return ulen; } + void set_ulen(u_int32_t value) { ulen = value; } + + // RO: get/put record length. + u_int32_t get_dlen() const { return dlen; } + void set_dlen(u_int32_t value) { dlen = value; } + + // RO: get/put record offset. + u_int32_t get_doff() const { return doff; } + void set_doff(u_int32_t value) { doff = value; } + + // flags + u_int32_t get_flags() const { return flags; } + void set_flags(u_int32_t value) { flags = value; } + + // Conversion functions + DBT *get_DBT() { return (DBT *)this; } + const DBT *get_const_DBT() const { return (const DBT *)this; } + + static Dbt* get_Dbt(DBT *dbt) { return (Dbt *)dbt; } + static const Dbt* get_const_Dbt(const DBT *dbt) + { return (const Dbt *)dbt; } + + Dbt(void *data, u_int32_t size); + Dbt(); + ~Dbt(); + Dbt(const Dbt &); + Dbt &operator = (const Dbt &); + +private: + // Note: no extra data appears in this class (other than + // inherited from DBT) since we need DBT and Dbt objects + // to have interchangable pointers. + // + // When subclassing this class, remember that callback + // methods like bt_compare, bt_prefix, dup_compare may + // internally manufacture DBT objects (which later are + // cast to Dbt), so such callbacks might receive objects + // not of your subclassed type. +}; + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +// +// multiple key/data/reco iterator classes +// + +// DbMultipleIterator is a shared private base class for the three types +// of bulk-return Iterator; it should never be instantiated directly, +// but it handles the functionality shared by its subclasses. +class _exported DbMultipleIterator +{ +public: + DbMultipleIterator(const Dbt &dbt); +protected: + u_int8_t *data_; + u_int32_t *p_; +}; + +class _exported DbMultipleKeyDataIterator : private DbMultipleIterator +{ +public: + DbMultipleKeyDataIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {} + bool next(Dbt &key, Dbt &data); +}; + +class _exported DbMultipleRecnoDataIterator : private DbMultipleIterator +{ +public: + DbMultipleRecnoDataIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {} + bool next(db_recno_t &recno, Dbt &data); +}; + +class _exported DbMultipleDataIterator : private DbMultipleIterator +{ +public: + DbMultipleDataIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {} + bool next(Dbt &data); +}; + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +// +// Exception classes +// + +// Almost any error in the DB library throws a DbException. +// Every exception should be considered an abnormality +// (e.g. bug, misuse of DB, file system error). +// +class _exported DbException : public __DB_STD(exception) +{ +public: + virtual ~DbException() throw(); + DbException(int err); + DbException(const char *description); + DbException(const char *description, int err); + DbException(const char *prefix, const char *description, int err); + int get_errno() const; + virtual const char *what() const throw(); + DbEnv *get_env() const; + void set_env(DbEnv *env); + + DbException(const DbException &); + DbException &operator = (const DbException &); + +private: + void describe(const char *prefix, const char *description); + + char *what_; + int err_; // errno + DbEnv *env_; +}; + +// +// A specific sort of exception that occurs when +// an operation is aborted to resolve a deadlock. +// +class _exported DbDeadlockException : public DbException +{ +public: + virtual ~DbDeadlockException() throw(); + DbDeadlockException(const char *description); + + DbDeadlockException(const DbDeadlockException &); + DbDeadlockException &operator = (const DbDeadlockException &); +}; + +// +// A specific sort of exception that occurs when +// a lock is not granted, e.g. by lock_get or lock_vec. +// Note that the Dbt is only live as long as the Dbt used +// in the offending call. +// +class _exported DbLockNotGrantedException : public DbException +{ +public: + virtual ~DbLockNotGrantedException() throw(); + DbLockNotGrantedException(const char *prefix, db_lockop_t op, + db_lockmode_t mode, const Dbt *obj, const DbLock lock, int index); + DbLockNotGrantedException(const char *description); + + DbLockNotGrantedException(const DbLockNotGrantedException &); + DbLockNotGrantedException &operator = + (const DbLockNotGrantedException &); + + db_lockop_t get_op() const; + db_lockmode_t get_mode() const; + const Dbt* get_obj() const; + DbLock *get_lock() const; + int get_index() const; + +private: + db_lockop_t op_; + db_lockmode_t mode_; + const Dbt *obj_; + DbLock *lock_; + int index_; +}; + +// +// A specific sort of exception that occurs when +// user declared memory is insufficient in a Dbt. +// +class _exported DbMemoryException : public DbException +{ +public: + virtual ~DbMemoryException() throw(); + DbMemoryException(Dbt *dbt); + DbMemoryException(const char *prefix, Dbt *dbt); + + DbMemoryException(const DbMemoryException &); + DbMemoryException &operator = (const DbMemoryException &); + + Dbt *get_dbt() const; +private: + Dbt *dbt_; +}; + +// +// A specific sort of exception that occurs when +// recovery is required before continuing DB activity. +// +class _exported DbRunRecoveryException : public DbException +{ +public: + virtual ~DbRunRecoveryException() throw(); + DbRunRecoveryException(const char *description); + + DbRunRecoveryException(const DbRunRecoveryException &); + DbRunRecoveryException &operator = (const DbRunRecoveryException &); +}; +#endif /* !_DB_CXX_H_ */ diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_deadlock.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_deadlock.dsp new file mode 100644 index 00000000..52feec43 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_deadlock.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="db_deadlock" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=db_deadlock - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_deadlock.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_deadlock.mak" CFG="db_deadlock - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_deadlock - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "db_deadlock - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "db_deadlock - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "db_deadlock - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_deadlock - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "db_deadlock - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "db_deadlock - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "db_deadlock - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_deadlock - Win32 Release" +# Name "db_deadlock - Win32 Debug" +# Name "db_deadlock - Win32 Release Static" +# Name "db_deadlock - Win32 Debug Static" +# Begin Source File + +SOURCE=..\db_deadlock\db_deadlock.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_deadlock.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_deadlock.vcproj new file mode 100644 index 00000000..bdaae5b5 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_deadlock.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_dll.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_dll.dsp new file mode 100644 index 00000000..1cfcac5d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_dll.dsp @@ -0,0 +1,864 @@ +# Microsoft Developer Studio Project File - Name="db_dll" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=db_dll - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_dll.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_dll.mak" CFG="db_dll - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "db_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_dll - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"Release/libdb43.dll" + +!ELSEIF "$(CFG)" == "db_dll - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DB_CREATE_DLL" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"Debug/libdb43d.dll" /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_dll - Win32 Release" +# Name "db_dll - Win32 Debug" +# Begin Source File + +SOURCE=..\btree\bt_compare.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_conv.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_curadj.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_cursor.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_delete.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_method.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_open.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_put.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_rec.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_reclaim.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_recno.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_rsearch.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_search.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_split.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_stat.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_upgrade.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_verify.c +# End Source File +# Begin Source File + +SOURCE=..\btree\btree_auto.c +# End Source File +# Begin Source File + +SOURCE=.\libdb.def +# End Source File +# Begin Source File + +SOURCE=.\libdb.rc +# End Source File +# Begin Source File + +SOURCE=..\clib\strcasecmp.c +# End Source File +# Begin Source File + +SOURCE=..\common\crypto_stub.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_byteorder.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_err.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_getlong.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_idspace.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_log2.c +# End Source File +# Begin Source File + +SOURCE=..\common\util_cache.c +# End Source File +# Begin Source File + +SOURCE=..\common\util_log.c +# End Source File +# Begin Source File + +SOURCE=..\common\util_sig.c +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_db.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_dbc.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_dbt.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_env.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_except.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_lock.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_logc.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_mpool.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_multi.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_seq.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_txn.cpp +# End Source File +# Begin Source File + +SOURCE=..\db\crdel_auto.c +# End Source File +# Begin Source File + +SOURCE=..\db\crdel_rec.c +# End Source File +# Begin Source File + +SOURCE=..\db\db.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_am.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_auto.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_cam.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_conv.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_dispatch.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_dup.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_iface.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_join.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_meta.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_method.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_open.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_overflow.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_ovfl_vrfy.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_pr.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_rec.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_reclaim.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_remove.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_rename.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_ret.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_setid.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_setlsn.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_stati.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_truncate.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_upg.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_upg_opd.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_vrfy.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_vrfyutil.c +# End Source File +# Begin Source File + +SOURCE=..\dbm\dbm.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_auto.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_rec.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_stat.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_util.c +# End Source File +# Begin Source File + +SOURCE=..\env\db_salloc.c +# End Source File +# Begin Source File + +SOURCE=..\env\db_shash.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_file.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_method.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_open.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_recover.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_region.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_stat.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fileops_auto.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fop_basic.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fop_rec.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fop_util.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_auto.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_conv.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_dup.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_func.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_meta.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_method.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_open.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_page.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_rec.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_reclaim.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_stat.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_upgrade.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_verify.c +# End Source File +# Begin Source File + +SOURCE=..\hmac\hmac.c +# End Source File +# Begin Source File + +SOURCE=..\hmac\sha1.c +# End Source File +# Begin Source File + +SOURCE=..\hsearch\hsearch.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_deadlock.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_id.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_list.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_method.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_region.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_stat.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_timer.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_util.c +# End Source File +# Begin Source File + +SOURCE=..\log\log.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_archive.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_compare.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_get.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_method.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_put.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_stat.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_alloc.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_bh.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fget.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fmethod.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fopen.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fput.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fset.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_method.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_region.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_register.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_stat.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_sync.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_trickle.c +# End Source File +# Begin Source File + +SOURCE=..\mutex\mut_win32.c +# End Source File +# Begin Source File + +SOURCE=..\mutex\mutex.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_alloc.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_id.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_method.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_oflags.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_region.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_root.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_rpath.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_tmpdir.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_abs.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_clock.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_config.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_dir.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_errno.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_fid.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_fsync.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_handle.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_map.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_open.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_rename.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_rw.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_seek.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_sleep.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_spin.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_stat.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_truncate.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_unlink.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_auto.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_conv.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_files.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_method.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_open.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_rec.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_stat.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_upgrade.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_verify.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_auto.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_backup.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_method.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_record.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_region.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_stat.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_util.c +# End Source File +# Begin Source File + +SOURCE=..\sequence\seq_stat.c +# End Source File +# Begin Source File + +SOURCE=..\sequence\sequence.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_auto.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_method.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_rec.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_recover.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_region.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_stat.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_util.c +# End Source File +# Begin Source File + +SOURCE=..\xa\xa.c +# End Source File +# Begin Source File + +SOURCE=..\xa\xa_db.c +# End Source File +# Begin Source File + +SOURCE=..\xa\xa_map.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_dll.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_dll.vcproj new file mode 100644 index 00000000..a36f0037 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_dll.vcproj @@ -0,0 +1,718 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_dump.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_dump.dsp new file mode 100644 index 00000000..34d926b4 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_dump.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="db_dump" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=db_dump - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_dump.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_dump.mak" CFG="db_dump - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_dump - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "db_dump - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "db_dump - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "db_dump - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_dump - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "db_dump - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "db_dump - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "db_dump - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_dump - Win32 Release" +# Name "db_dump - Win32 Debug" +# Name "db_dump - Win32 Release Static" +# Name "db_dump - Win32 Debug Static" +# Begin Source File + +SOURCE=..\db_dump\db_dump.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_dump.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_dump.vcproj new file mode 100644 index 00000000..c99450c0 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_dump.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_int.h b/src/libs/resiprocate/contrib/db/build_win32/db_int.h new file mode 100644 index 00000000..046e3de5 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_int.h @@ -0,0 +1,592 @@ +/* DO NOT EDIT: automatically built by dist/s_win32. */ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2004 + * Sleepycat Software. All rights reserved. + * + * $Id: db_int.in,v 11.155 2004/10/28 16:07:38 ubell Exp $ + */ + +#ifndef _DB_INTERNAL_H_ +#define _DB_INTERNAL_H_ + +/******************************************************* + * System includes, db.h, a few general DB includes. The DB includes are + * here because it's OK if db_int.h includes queue structure declarations. + *******************************************************/ +#ifndef NO_SYSTEM_INCLUDES +#if defined(STDC_HEADERS) || defined(__cplusplus) +#include +#else +#include +#endif +#include +#endif + +#include "db.h" + +#include "dbinc/queue.h" +#include "dbinc/shqueue.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************* + * General purpose constants and macros. + *******************************************************/ +#ifndef UINT16_MAX +#define UINT16_MAX 65535 /* Maximum 16-bit unsigned. */ +#endif +#ifndef UINT32_MAX +#ifdef __STDC__ +#define UINT32_MAX 4294967295U /* Maximum 32-bit unsigned. */ +#else +#define UINT32_MAX 0xffffffff /* Maximum 32-bit unsigned. */ +#endif +#endif + +#if defined(HAVE_LONG_LONG) && defined(HAVE_UNSIGNED_LONG_LONG) +#undef INT64_MAX +#undef INT64_MIN +#undef UINT64_MAX + +#ifdef DB_WIN32 +#define INT64_MAX _I64_MAX +#define INT64_MIN _I64_MIN +#define UINT64_MAX _UI64_MAX + +#define INT64_FMT "%l64d" +#define UINT64_FMT "%l64u" +#else +/* + * Override the system's 64-bit min/max constants. AIX's 32-bit compiler can + * handle 64-bit values, but the system's constants don't include the LL/ULL + * suffix, and so can't be compiled using the 32-bit compiler. + */ +#define INT64_MAX 9223372036854775807LL +#define INT64_MIN (-INT64_MAX-1) +#define UINT64_MAX 18446744073709551615ULL + +#define INT64_FMT "%lld" +#define UINT64_FMT "%llu" +#endif /* DB_WIN32 */ +#endif /* HAVE_LONG_LONG && HAVE_UNSIGNED_LONG_LONG */ + +#define MEGABYTE 1048576 +#define GIGABYTE 1073741824 + +#define MS_PER_SEC 1000 /* Milliseconds in a second. */ +#define USEC_PER_MS 1000 /* Microseconds in a millisecond. */ + +#define RECNO_OOB 0 /* Illegal record number. */ + +/* Test for a power-of-two (tests true for zero, which doesn't matter here). */ +#define POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0) + +/* Test for valid page sizes. */ +#define DB_MIN_PGSIZE 0x000200 /* Minimum page size (512). */ +#define DB_MAX_PGSIZE 0x010000 /* Maximum page size (65536). */ +#define IS_VALID_PAGESIZE(x) \ + (POWER_OF_TWO(x) && (x) >= DB_MIN_PGSIZE && ((x) <= DB_MAX_PGSIZE)) + +/* Minimum number of pages cached, by default. */ +#define DB_MINPAGECACHE 16 + +/* + * If we are unable to determine the underlying filesystem block size, use + * 8K on the grounds that most OS's use less than 8K for a VM page size. + */ +#define DB_DEF_IOSIZE (8 * 1024) + +/* Align an integer to a specific boundary. */ +#undef DB_ALIGN +#define DB_ALIGN(v, bound) \ + (((v) + (bound) - 1) & ~(((uintmax_t)bound) - 1)) + +/* Increment a pointer to a specific boundary. */ +#undef ALIGNP_INC +#define ALIGNP_INC(p, bound) \ + (void *)(((uintptr_t)(p) + (bound) - 1) & ~(((uintptr_t)bound) - 1)) + +/* Decrement a pointer to a specific boundary. */ +#undef ALIGNP_DEC +#define ALIGNP_DEC(p, bound) \ + (void *)((uintptr_t)(p) & ~(((uintptr_t)bound) - 1)) + +/* + * Print an address as a u_long (a u_long is the largest type we can print + * portably). Most 64-bit systems have made longs 64-bits, so this should + * work. + */ +#define P_TO_ULONG(p) ((u_long)(uintptr_t)(p)) + +/* + * Convert a pointer to a small integral value. + * + * The (u_int16_t)(uintptr_t) cast avoids warnings: the (uintptr_t) cast + * converts the value to an integral type, and the (u_int16_t) cast converts + * it to a small integral type so we don't get complaints when we assign the + * final result to an integral type smaller than uintptr_t. + */ +#define P_TO_UINT32(p) ((u_int32_t)(uintptr_t)(p)) +#define P_TO_UINT16(p) ((u_int16_t)(uintptr_t)(p)) + +/* + * There are several on-page structures that are declared to have a number of + * fields followed by a variable length array of items. The structure size + * without including the variable length array or the address of the first of + * those elements can be found using SSZ. + * + * This macro can also be used to find the offset of a structure element in a + * structure. This is used in various places to copy structure elements from + * unaligned memory references, e.g., pointers into a packed page. + * + * There are two versions because compilers object if you take the address of + * an array. + */ +#undef SSZ +#define SSZ(name, field) P_TO_UINT16(&(((name *)0)->field)) + +#undef SSZA +#define SSZA(name, field) P_TO_UINT16(&(((name *)0)->field[0])) + +/* Structure used to print flag values. */ +typedef struct __fn { + u_int32_t mask; /* Flag value. */ + const char *name; /* Flag name. */ +} FN; + +/* Set, clear and test flags. */ +#define FLD_CLR(fld, f) (fld) &= ~(f) +#define FLD_ISSET(fld, f) ((fld) & (f)) +#define FLD_SET(fld, f) (fld) |= (f) +#define F_CLR(p, f) (p)->flags &= ~(f) +#define F_ISSET(p, f) ((p)->flags & (f)) +#define F_SET(p, f) (p)->flags |= (f) +#define LF_CLR(f) ((flags) &= ~(f)) +#define LF_ISSET(f) ((flags) & (f)) +#define LF_SET(f) ((flags) |= (f)) + +/* + * Calculate a percentage. The values can overflow 32-bit integer arithmetic + * so we use floating point. + * + * When calculating a bytes-vs-page size percentage, we're getting the inverse + * of the percentage in all cases, that is, we want 100 minus the percentage we + * calculate. + */ +#define DB_PCT(v, total) \ + ((int)((total) == 0 ? 0 : ((double)(v) * 100) / (total))) +#define DB_PCT_PG(v, total, pgsize) \ + ((int)((total) == 0 ? 0 : \ + 100 - ((double)(v) * 100) / ((total) * (pgsize)))) + +/* + * Structure used for callback message aggregation. + * + * Display values in XXX_stat_print calls. + */ +typedef struct __db_msgbuf { + char *buf; /* Heap allocated buffer. */ + char *cur; /* Current end of message. */ + size_t len; /* Allocated length of buffer. */ +} DB_MSGBUF; +#define DB_MSGBUF_INIT(a) do { \ + (a)->buf = (a)->cur = NULL; \ + (a)->len = 0; \ +} while (0) +#define DB_MSGBUF_FLUSH(dbenv, a) do { \ + if ((a)->buf != NULL) { \ + if ((a)->cur != (a)->buf) \ + __db_msg(dbenv, "%s", (a)->buf); \ + __os_free(dbenv, (a)->buf); \ + DB_MSGBUF_INIT(a); \ + } \ +} while (0) +#define STAT_FMT(msg, fmt, type, v) do { \ + DB_MSGBUF __mb; \ + DB_MSGBUF_INIT(&__mb); \ + __db_msgadd(dbenv, &__mb, fmt, (type)(v)); \ + __db_msgadd(dbenv, &__mb, "\t%s", msg); \ + DB_MSGBUF_FLUSH(dbenv, &__mb); \ +} while (0) +#define STAT_HEX(msg, v) \ + __db_msg(dbenv, "%#lx\t%s", (u_long)(v), msg) +#define STAT_ISSET(msg, p) \ + __db_msg(dbenv, "%sSet\t%s", (p) == NULL ? "!" : " ", msg) +#define STAT_LONG(msg, v) \ + __db_msg(dbenv, "%ld\t%s", (long)(v), msg) +#define STAT_LSN(msg, lsnp) \ + __db_msg(dbenv, "%lu/%lu\t%s", \ + (u_long)(lsnp)->file, (u_long)(lsnp)->offset, msg) +#define STAT_STRING(msg, p) do { \ + const char *__p = p; /* p may be a function call. */ \ + __db_msg(dbenv, "%s\t%s", __p == NULL ? "!Set" : __p, msg); \ +} while (0) +#define STAT_ULONG(msg, v) \ + __db_msg(dbenv, "%lu\t%s", (u_long)(v), msg) + +/******************************************************* + * API return values + *******************************************************/ +/* + * Return values that are OK for each different call. Most calls have a + * standard 'return of 0 is only OK value', but some, like db->get have + * DB_NOTFOUND as a return value, but it really isn't an error. + */ +#define DB_RETOK_STD(ret) ((ret) == 0) +#define DB_RETOK_DBCDEL(ret) ((ret) == 0 || (ret) == DB_KEYEMPTY || \ + (ret) == DB_NOTFOUND) +#define DB_RETOK_DBCGET(ret) ((ret) == 0 || (ret) == DB_KEYEMPTY || \ + (ret) == DB_NOTFOUND) +#define DB_RETOK_DBCPUT(ret) ((ret) == 0 || (ret) == DB_KEYEXIST || \ + (ret) == DB_NOTFOUND) +#define DB_RETOK_DBDEL(ret) DB_RETOK_DBCDEL(ret) +#define DB_RETOK_DBGET(ret) DB_RETOK_DBCGET(ret) +#define DB_RETOK_DBPUT(ret) ((ret) == 0 || (ret) == DB_KEYEXIST) +#define DB_RETOK_LGGET(ret) ((ret) == 0 || (ret) == DB_NOTFOUND) +#define DB_RETOK_MPGET(ret) ((ret) == 0 || (ret) == DB_PAGE_NOTFOUND) +#define DB_RETOK_REPPMSG(ret) ((ret) == 0 || \ + (ret) == DB_REP_ISPERM || \ + (ret) == DB_REP_NEWMASTER || \ + (ret) == DB_REP_NEWSITE || \ + (ret) == DB_REP_NOTPERM || \ + (ret) == DB_REP_STARTUPDONE) + +/* Find a reasonable operation-not-supported error. */ +#ifdef EOPNOTSUPP +#define DB_OPNOTSUP EOPNOTSUPP +#else +#ifdef ENOTSUP +#define DB_OPNOTSUP ENOTSUP +#else +#define DB_OPNOTSUP EINVAL +#endif +#endif + +/******************************************************* + * Files. + *******************************************************/ +/* + * We use 1024 as the maximum path length. It's too hard to figure out what + * the real path length is, as it was traditionally stored in , + * and that file isn't always available. + */ +#undef MAXPATHLEN +#define MAXPATHLEN 1024 + +#define PATH_DOT "." /* Current working directory. */ + /* Path separator character(s). */ +#define PATH_SEPARATOR "\\/:" + +/******************************************************* + * Environment. + *******************************************************/ +/* Type passed to __db_appname(). */ +typedef enum { + DB_APP_NONE=0, /* No type (region). */ + DB_APP_DATA, /* Data file. */ + DB_APP_LOG, /* Log file. */ + DB_APP_TMP /* Temporary file. */ +} APPNAME; + +/* + * CDB_LOCKING CDB product locking. + * CRYPTO_ON Security has been configured. + * LOCKING_ON Locking has been configured. + * LOGGING_ON Logging has been configured. + * MPOOL_ON Memory pool has been configured. + * REP_ON Replication has been configured. + * RPC_ON RPC has been configured. + * TXN_ON Transactions have been configured. + */ +#define CDB_LOCKING(dbenv) F_ISSET(dbenv, DB_ENV_CDB) +#define CRYPTO_ON(dbenv) ((dbenv)->crypto_handle != NULL) +#define LOCKING_ON(dbenv) ((dbenv)->lk_handle != NULL) +#define LOGGING_ON(dbenv) ((dbenv)->lg_handle != NULL) +#define MPOOL_ON(dbenv) ((dbenv)->mp_handle != NULL) +#define REP_ON(dbenv) ((dbenv)->rep_handle != NULL) +#define RPC_ON(dbenv) ((dbenv)->cl_handle != NULL) +#define TXN_ON(dbenv) ((dbenv)->tx_handle != NULL) + +/* + * STD_LOCKING Standard locking, that is, locking was configured and CDB + * was not. We do not do locking in off-page duplicate trees, + * so we check for that in the cursor first. + */ +#define STD_LOCKING(dbc) \ + (!F_ISSET(dbc, DBC_OPD) && \ + !CDB_LOCKING((dbc)->dbp->dbenv) && LOCKING_ON((dbc)->dbp->dbenv)) + +/* + * IS_RECOVERING: The system is running recovery. + */ +#define IS_RECOVERING(dbenv) \ + (LOGGING_ON(dbenv) && \ + F_ISSET((DB_LOG *)(dbenv)->lg_handle, DBLOG_RECOVER)) + +/* Initialization methods are often illegal before/after open is called. */ +#define ENV_ILLEGAL_AFTER_OPEN(dbenv, name) \ + if (F_ISSET((dbenv), DB_ENV_OPEN_CALLED)) \ + return (__db_mi_open(dbenv, name, 1)); +#define ENV_ILLEGAL_BEFORE_OPEN(dbenv, name) \ + if (!F_ISSET((dbenv), DB_ENV_OPEN_CALLED)) \ + return (__db_mi_open(dbenv, name, 0)); + +/* We're not actually user hostile, honest. */ +#define ENV_REQUIRES_CONFIG(dbenv, handle, i, flags) \ + if (handle == NULL) \ + return (__db_env_config(dbenv, i, flags)); +#define ENV_NOT_CONFIGURED(dbenv, handle, i, flags) \ + if (F_ISSET((dbenv), DB_ENV_OPEN_CALLED)) \ + ENV_REQUIRES_CONFIG(dbenv, handle, i, flags) + +/******************************************************* + * Database Access Methods. + *******************************************************/ +/* + * DB_IS_THREADED -- + * The database handle is free-threaded (was opened with DB_THREAD). + */ +#define DB_IS_THREADED(dbp) \ + ((dbp)->mutexp != NULL) + +/* Initialization methods are often illegal before/after open is called. */ +#define DB_ILLEGAL_AFTER_OPEN(dbp, name) \ + if (F_ISSET((dbp), DB_AM_OPEN_CALLED)) \ + return (__db_mi_open((dbp)->dbenv, name, 1)); +#define DB_ILLEGAL_BEFORE_OPEN(dbp, name) \ + if (!F_ISSET((dbp), DB_AM_OPEN_CALLED)) \ + return (__db_mi_open((dbp)->dbenv, name, 0)); +/* Some initialization methods are illegal if environment isn't local. */ +#define DB_ILLEGAL_IN_ENV(dbp, name) \ + if (!F_ISSET((dbp)->dbenv, DB_ENV_DBLOCAL)) \ + return (__db_mi_env((dbp)->dbenv, name)); +#define DB_ILLEGAL_METHOD(dbp, flags) { \ + int __ret; \ + if ((__ret = __dbh_am_chk(dbp, flags)) != 0) \ + return (__ret); \ +} + +/* + * Common DBC->internal fields. Each access method adds additional fields + * to this list, but the initial fields are common. + */ +#define __DBC_INTERNAL \ + DBC *opd; /* Off-page duplicate cursor. */\ + \ + void *page; /* Referenced page. */ \ + db_pgno_t root; /* Tree root. */ \ + db_pgno_t pgno; /* Referenced page number. */ \ + db_indx_t indx; /* Referenced key item index. */\ + \ + DB_LOCK lock; /* Cursor lock. */ \ + db_lockmode_t lock_mode; /* Lock mode. */ + +struct __dbc_internal { + __DBC_INTERNAL +}; + +/* Actions that __db_master_update can take. */ +typedef enum { MU_REMOVE, MU_RENAME, MU_OPEN } mu_action; + +/* + * Access-method-common macro for determining whether a cursor + * has been initialized. + */ +#define IS_INITIALIZED(dbc) ((dbc)->internal->pgno != PGNO_INVALID) + +/* Free the callback-allocated buffer, if necessary, hanging off of a DBT. */ +#define FREE_IF_NEEDED(sdbp, dbt) \ + if (F_ISSET((dbt), DB_DBT_APPMALLOC)) { \ + __os_ufree((sdbp)->dbenv, (dbt)->data); \ + F_CLR((dbt), DB_DBT_APPMALLOC); \ + } + +/* + * Use memory belonging to object "owner" to return the results of + * any no-DBT-flag get ops on cursor "dbc". + */ +#define SET_RET_MEM(dbc, owner) \ + do { \ + (dbc)->rskey = &(owner)->my_rskey; \ + (dbc)->rkey = &(owner)->my_rkey; \ + (dbc)->rdata = &(owner)->my_rdata; \ + } while (0) + +/* Use the return-data memory src is currently set to use in dest as well. */ +#define COPY_RET_MEM(src, dest) \ + do { \ + (dest)->rskey = (src)->rskey; \ + (dest)->rkey = (src)->rkey; \ + (dest)->rdata = (src)->rdata; \ + } while (0) + +/* Reset the returned-memory pointers to their defaults. */ +#define RESET_RET_MEM(dbc) \ + do { \ + (dbc)->rskey = &(dbc)->my_rskey; \ + (dbc)->rkey = &(dbc)->my_rkey; \ + (dbc)->rdata = &(dbc)->my_rdata; \ + } while (0) + +/******************************************************* + * Mpool. + *******************************************************/ +/* + * File types for DB access methods. Negative numbers are reserved to DB. + */ +#define DB_FTYPE_SET -1 /* Call pgin/pgout functions. */ +#define DB_FTYPE_NOTSET 0 /* Don't call... */ + +/* Structure used as the DB pgin/pgout pgcookie. */ +typedef struct __dbpginfo { + size_t db_pagesize; /* Underlying page size. */ + u_int32_t flags; /* Some DB_AM flags needed. */ + DBTYPE type; /* DB type */ +} DB_PGINFO; + +/******************************************************* + * Log. + *******************************************************/ +/* Initialize an LSN to 'zero'. */ +#define ZERO_LSN(LSN) do { \ + (LSN).file = 0; \ + (LSN).offset = 0; \ +} while (0) +#define IS_ZERO_LSN(LSN) ((LSN).file == 0 && (LSN).offset == 0) + +#define IS_INIT_LSN(LSN) ((LSN).file == 1 && (LSN).offset == 0) +#define INIT_LSN(LSN) do { \ + (LSN).file = 1; \ + (LSN).offset = 0; \ +} while (0) + +#define MAX_LSN(LSN) do { \ + (LSN).file = UINT32_MAX; \ + (LSN).offset = UINT32_MAX; \ +} while (0) +#define IS_MAX_LSN(LSN) \ + ((LSN).file == UINT32_MAX && (LSN).offset == UINT32_MAX) + +/* If logging is turned off, smash the lsn. */ +#define LSN_NOT_LOGGED(LSN) do { \ + (LSN).file = 0; \ + (LSN).offset = 1; \ +} while (0) +#define IS_NOT_LOGGED_LSN(LSN) \ + ((LSN).file == 0 && (LSN).offset == 1) + +/******************************************************* + * Txn. + *******************************************************/ +#define DB_NONBLOCK(C) ((C)->txn != NULL && F_ISSET((C)->txn, TXN_NOWAIT)) +#define NOWAIT_FLAG(txn) \ + ((txn) != NULL && F_ISSET((txn), TXN_NOWAIT) ? DB_LOCK_NOWAIT : 0) +#define IS_SUBTRANSACTION(txn) \ + ((txn) != NULL && (txn)->parent != NULL) + +/******************************************************* + * Crypto. + *******************************************************/ +#define DB_IV_BYTES 16 /* Bytes per IV */ +#define DB_MAC_KEY 20 /* Bytes per MAC checksum */ + +/******************************************************* + * Secondaries over RPC. + *******************************************************/ +#ifdef CONFIG_TEST +/* + * These are flags passed to DB->associate calls by the Tcl API if running + * over RPC. The RPC server will mask out these flags before making the real + * DB->associate call. + * + * These flags must coexist with the valid flags to DB->associate (currently + * DB_AUTO_COMMIT and DB_CREATE). DB_AUTO_COMMIT is in the group of + * high-order shared flags (0xff000000), and DB_CREATE is in the low-order + * group (0x00000fff), so we pick a range in between. + */ +#define DB_RPC2ND_MASK 0x00f00000 /* Reserved bits. */ + +#define DB_RPC2ND_REVERSEDATA 0x00100000 /* callback_n(0) _s_reversedata. */ +#define DB_RPC2ND_NOOP 0x00200000 /* callback_n(1) _s_noop */ +#define DB_RPC2ND_CONCATKEYDATA 0x00300000 /* callback_n(2) _s_concatkeydata */ +#define DB_RPC2ND_CONCATDATAKEY 0x00400000 /* callback_n(3) _s_concatdatakey */ +#define DB_RPC2ND_REVERSECONCAT 0x00500000 /* callback_n(4) _s_reverseconcat */ +#define DB_RPC2ND_TRUNCDATA 0x00600000 /* callback_n(5) _s_truncdata */ +#define DB_RPC2ND_CONSTANT 0x00700000 /* callback_n(6) _s_constant */ +#define DB_RPC2ND_GETZIP 0x00800000 /* sj_getzip */ +#define DB_RPC2ND_GETNAME 0x00900000 /* sj_getname */ +#endif + +/******************************************************* + * Forward structure declarations. + *******************************************************/ +struct __db_reginfo_t; typedef struct __db_reginfo_t REGINFO; +struct __db_txnhead; typedef struct __db_txnhead DB_TXNHEAD; +struct __db_txnlist; typedef struct __db_txnlist DB_TXNLIST; +struct __vrfy_childinfo; typedef struct __vrfy_childinfo VRFY_CHILDINFO; +struct __vrfy_dbinfo; typedef struct __vrfy_dbinfo VRFY_DBINFO; +struct __vrfy_pageinfo; typedef struct __vrfy_pageinfo VRFY_PAGEINFO; + +#if defined(__cplusplus) +} +#endif + +/******************************************************* + * Remaining general DB includes. + *******************************************************/ + + +#include "dbinc/globals.h" +#include "dbinc/debug.h" +#include "dbinc/mutex.h" +#include "dbinc/region.h" +#include "dbinc_auto/mutex_ext.h" /* XXX: Include after region.h. */ +#include "dbinc_auto/env_ext.h" +#include "dbinc/os.h" +#include "dbinc/rep.h" +#include "dbinc_auto/clib_ext.h" +#include "dbinc_auto/common_ext.h" + +/******************************************************* + * Remaining Log. + * These need to be defined after the general includes + * because they need rep.h from above. + *******************************************************/ +/* + * Test if the environment is currently logging changes. If we're in recovery + * or we're a replication client, we don't need to log changes because they're + * already in the log, even though we have a fully functional log system. + */ +#define DBENV_LOGGING(dbenv) \ + (LOGGING_ON(dbenv) && !IS_REP_CLIENT(dbenv) && \ + (!IS_RECOVERING(dbenv))) + +/* + * Test if we need to log a change. By default, we don't log operations without + * associated transactions, unless DIAGNOSTIC, DEBUG_ROP or DEBUG_WOP are on. + * This is because we want to get log records for read/write operations, and, if + * we trying to debug something, more information is always better. + * + * The DBC_RECOVER flag is set when we're in abort, as well as during recovery; + * thus DBC_LOGGING may be false for a particular dbc even when DBENV_LOGGING + * is true. + * + * We explicitly use LOGGING_ON/IS_REP_CLIENT here because we don't want to pull + * in the log headers, which IS_RECOVERING (and thus DBENV_LOGGING) rely on, and + * because DBC_RECOVER should be set anytime IS_RECOVERING would be true. + */ +#if defined(DIAGNOSTIC) || defined(DEBUG_ROP) || defined(DEBUG_WOP) +#define DBC_LOGGING(dbc) \ + (LOGGING_ON((dbc)->dbp->dbenv) && \ + !F_ISSET((dbc), DBC_RECOVER) && !IS_REP_CLIENT((dbc)->dbp->dbenv)) +#else +#define DBC_LOGGING(dbc) \ + ((dbc)->txn != NULL && LOGGING_ON((dbc)->dbp->dbenv) && \ + !F_ISSET((dbc), DBC_RECOVER) && !IS_REP_CLIENT((dbc)->dbp->dbenv)) +#endif + +#endif /* !_DB_INTERNAL_H_ */ diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_java.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_java.dsp new file mode 100644 index 00000000..5370877b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_java.dsp @@ -0,0 +1,132 @@ +# Microsoft Developer Studio Project File - Name="db_java" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=db_java - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_java.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_java.mak" CFG="db_java - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_java - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "db_java - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_java - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"Release/libdb_java43.dll" +# Begin Custom Build - Compiling java files using javac +ProjDir=. +InputPath=.\Release\libdb_java43.dll +SOURCE="$(InputPath)" + +"force_compilation.txt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo compiling Berkeley DB classes + mkdir "$(OUTDIR)\classes" + javac -O -d "$(OUTDIR)\classes" -classpath "$(OUTDIR)/classes" ..\java\src\com\sleepycat\db\*.java ..\java\src\com\sleepycat\db\internal\*.java ..\java\src\com\sleepycat\bind\*.java ..\java\src\com\sleepycat\bind\serial\*.java ..\java\src\com\sleepycat\bind\tuple\*.java ..\java\src\com\sleepycat\collections\*.java ..\java\src\com\sleepycat\compat\*.java ..\java\src\com\sleepycat\util\*.java + echo compiling examples + mkdir "$(OUTDIR)\classes.ex" + javac -O -d "$(OUTDIR)\classes.ex" -classpath "$(OUTDIR)\classes;$(OUTDIR)\classes.ex" ..\examples_java\src\com\sleepycat\examples\db\*.java ..\examples_java\src\com\sleepycat\examples\db\GettingStarted\*.java ..\examples_java\src\com\sleepycat\examples\collections\access\*.java ..\examples_java\src\com\sleepycat\examples\collections\hello\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\basic\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\entity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\tuple\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\sentity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\marshal\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\factory\*.java + echo creating jar files + jar cf "$(OUTDIR)\db.jar" -C "$(OUTDIR)\classes" . + jar cf "$(OUTDIR)\dbexamples.jar" -C "$(OUTDIR)\classes.ex" . + echo Java build finished + +# End Custom Build + +!ELSEIF "$(CFG)" == "db_java - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /D "_WINDLL" /D "_AFXDLL" /YX"config.h" /FD /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"Debug/libdb_java43d.dll" /fixed:no +# Begin Custom Build - Compiling java files using javac +ProjDir=. +InputPath=.\Debug\libdb_java43d.dll +SOURCE="$(InputPath)" + +"force_compilation.txt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo compiling Berkeley DB classes + mkdir "$(OUTDIR)\classes" + javac -g -d "$(OUTDIR)\classes" -classpath "$(OUTDIR)/classes" ..\java\src\com\sleepycat\db\*.java ..\java\src\com\sleepycat\db\internal\*.java ..\java\src\com\sleepycat\bind\*.java ..\java\src\com\sleepycat\bind\serial\*.java ..\java\src\com\sleepycat\bind\tuple\*.java ..\java\src\com\sleepycat\collections\*.java ..\java\src\com\sleepycat\compat\*.java ..\java\src\com\sleepycat\util\*.java + echo compiling examples + mkdir "$(OUTDIR)\classes.ex" + javac -g -d "$(OUTDIR)\classes.ex" -classpath "$(OUTDIR)\classes;$(OUTDIR)\classes.ex" ..\examples_java\src\com\sleepycat\examples\db\*.java ..\examples_java\src\com\sleepycat\examples\db\GettingStarted\*.java ..\examples_java\src\com\sleepycat\examples\collections\access\*.java ..\examples_java\src\com\sleepycat\examples\collections\hello\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\basic\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\entity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\tuple\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\sentity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\marshal\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\factory\*.java + echo creating jar files + jar cf "$(OUTDIR)\db.jar" -C "$(OUTDIR)\classes" . + jar cf "$(OUTDIR)\dbexamples.jar" -C "$(OUTDIR)\classes.ex" . + echo Java build finished + +# End Custom Build + +!ENDIF + +# Begin Target + +# Name "db_java - Win32 Release" +# Name "db_java - Win32 Debug" +# Begin Source File + +SOURCE=..\libdb_java\db_java_wrap.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_java.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_java.vcproj new file mode 100644 index 00000000..0b4c45bd --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_java.vcproj @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_java_xa.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_java_xa.dsp new file mode 100644 index 00000000..b855a18f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_java_xa.dsp @@ -0,0 +1,85 @@ +# Microsoft Developer Studio Project File - Name="db_java_xa" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=db_java_xa - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_java_xa.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_java_xa.mak" CFG="db_java_xa - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_java_xa - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "db_java_xa - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "db_java_xa - Win32 Release" + +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f db_java_xaj.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "db_java_xaj.exe" +# PROP BASE Bsc_Name "db_java_xaj.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "NMAKE /f db_java_xaj.mak Release/dbxa.jar" +# PROP Rebuild_Opt "/a" +# PROP Target_File "Release/dbxa.jar" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "db_java_xa - Win32 Debug" + +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f db_java_xaj.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "db_java_xaj.exe" +# PROP BASE Bsc_Name "db_java_xaj.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "NMAKE /f db_java_xaj.mak Debug/dbxa.jar" +# PROP Rebuild_Opt "/a" +# PROP Target_File "Debug/dbxa.jar" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "db_java_xa - Win32 Release" +# Name "db_java_xa - Win32 Debug" + +!IF "$(CFG)" == "db_java_xa - Win32 Release" + +!ELSEIF "$(CFG)" == "db_java_xa - Win32 Debug" + +!ENDIF + +# Begin Source File + +SOURCE=.\db_java_xaj.mak +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_java_xaj.mak b/src/libs/resiprocate/contrib/db/build_win32/db_java_xaj.mak new file mode 100644 index 00000000..f9a77a3a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_java_xaj.mak @@ -0,0 +1,21 @@ +JAVA_XADIR=../java/src/com/sleepycat/db/xa + +JAVA_XASRCS=\ + $(JAVA_XADIR)/DbXAResource.java \ + $(JAVA_XADIR)/DbXid.java + +Release/dbxa.jar : $(JAVA_XASRCS) + @echo compiling Berkeley DB XA classes + @javac -g -d ./Release/classes -classpath "$(CLASSPATH);./Release/classes" $(JAVA_XASRCS) + @echo creating jar file + @cd .\Release\classes + @jar cf ../dbxa.jar com\sleepycat\db\xa\*.class + @echo Java XA build finished + +Debug/dbxa.jar : $(JAVA_XASRCS) + @echo compiling Berkeley DB XA classes + @javac -g -d ./Debug/classes -classpath "$(CLASSPATH);./Debug/classes" $(JAVA_XASRCS) + @echo creating jar file + @cd .\Debug\classes + @jar cf ../dbxa.jar com\sleepycat\db\xa\*.class + @echo Java XA build finished diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_lib.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_lib.dsp new file mode 100644 index 00000000..cb8a79dd --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_lib.dsp @@ -0,0 +1,92 @@ +# Microsoft Developer Studio Project File - Name="db_lib" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Generic Project" 0x010a + +CFG=db_lib - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_lib.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_lib.mak" CFG="db_lib - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_lib - Win32 Release" (based on "Win32 (x86) Generic Project") +!MESSAGE "db_lib - Win32 Debug" (based on "Win32 (x86) Generic Project") +!MESSAGE "db_lib - Win32 Release Static" (based on "Win32 (x86) Generic Project") +!MESSAGE "db_lib - Win32 Debug Static" (based on "Win32 (x86) Generic Project") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "db_lib - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "db_lib - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "db_lib - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_static" +# PROP BASE Intermediate_Dir "Release_static" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "db_lib - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_static" +# PROP BASE Intermediate_Dir "Debug_Static" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_Static" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "db_lib - Win32 Release" +# Name "db_lib - Win32 Debug" +# Name "db_lib - Win32 Release Static" +# Name "db_lib - Win32 Debug Static" +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_lib.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_lib.vcproj new file mode 100644 index 00000000..9cc31532 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_lib.vcproj @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_load.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_load.dsp new file mode 100644 index 00000000..ded08b03 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_load.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="db_load" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=db_load - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_load.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_load.mak" CFG="db_load - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_load - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "db_load - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "db_load - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "db_load - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_load - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "db_load - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "db_load - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "db_load - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_load - Win32 Release" +# Name "db_load - Win32 Debug" +# Name "db_load - Win32 Release Static" +# Name "db_load - Win32 Debug Static" +# Begin Source File + +SOURCE=..\db_load\db_load.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_load.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_load.vcproj new file mode 100644 index 00000000..6af1a33b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_load.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_perf.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_perf.dsp new file mode 100644 index 00000000..dd43a0d2 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_perf.dsp @@ -0,0 +1,224 @@ +# Microsoft Developer Studio Project File - Name="db_perf" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=db_perf - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_perf.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_perf.mak" CFG="db_perf - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_perf - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "db_perf - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "db_perf - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "db_perf - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_perf - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "db_perf - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "db_perf - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "db_perf - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_perf - Win32 Release" +# Name "db_perf - Win32 Debug" +# Name "db_perf - Win32 Release Static" +# Name "db_perf - Win32 Debug Static" +# Begin Source File + +SOURCE=..\test_perf\db_perf.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_checkpoint.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_config.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_dbs.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_dead.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_debug.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_file.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_key.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_log.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_misc.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_op.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_parse.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_rand.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_spawn.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_stat.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_sync.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_thread.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_trickle.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_txn.c +# End Source File +# Begin Source File + +SOURCE=..\test_perf\perf_util.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_printlog.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_printlog.dsp new file mode 100644 index 00000000..28fbdf76 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_printlog.dsp @@ -0,0 +1,184 @@ +# Microsoft Developer Studio Project File - Name="db_printlog" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=db_printlog - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_printlog.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_printlog.mak" CFG="db_printlog - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_printlog - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "db_printlog - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "db_printlog - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "db_printlog - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_printlog - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "db_printlog - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "db_printlog - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "db_printlog - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_printlog - Win32 Release" +# Name "db_printlog - Win32 Debug" +# Name "db_printlog - Win32 Release Static" +# Name "db_printlog - Win32 Debug Static" +# Begin Source File + +SOURCE=..\btree\btree_autop.c +# End Source File +# Begin Source File + +SOURCE=..\db\crdel_autop.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_autop.c +# End Source File +# Begin Source File + +SOURCE=..\db_printlog\db_printlog.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_autop.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fileops_autop.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_autop.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_autop.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_autop.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_autop.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_printlog.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_printlog.vcproj new file mode 100644 index 00000000..9797a1f7 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_printlog.vcproj @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_recover.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_recover.dsp new file mode 100644 index 00000000..95d6659c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_recover.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="db_recover" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=db_recover - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_recover.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_recover.mak" CFG="db_recover - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_recover - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "db_recover - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "db_recover - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "db_recover - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_recover - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "db_recover - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "db_recover - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "db_recover - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_recover - Win32 Release" +# Name "db_recover - Win32 Debug" +# Name "db_recover - Win32 Release Static" +# Name "db_recover - Win32 Debug Static" +# Begin Source File + +SOURCE=..\db_recover\db_recover.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_recover.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_recover.vcproj new file mode 100644 index 00000000..64dc7799 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_recover.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_small.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_small.dsp new file mode 100644 index 00000000..f2627fa6 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_small.dsp @@ -0,0 +1,720 @@ +# Microsoft Developer Studio Project File - Name="db_small" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=db_small - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_small.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_small.mak" CFG="db_small - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_small - Win32 Release Static" (based on "Win32 (x86) Static Library") +!MESSAGE "db_small - Win32 Debug Static" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_small - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_small" +# PROP BASE Intermediate_Dir "Release_small" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_small" +# PROP Intermediate_Dir "Release_small" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX"config.h" /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c +# ADD BASE RSC /l 0xc09 +# ADD RSC /l 0xc09 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo /out:"Release_small/libdb43s.lib" +# ADD LIB32 /nologo /out:"Release_small/libdb43s.lib" + +!ELSEIF "$(CFG)" == "db_small - Win32 Debug Static" + +# PROP BASE Use_MFC 1 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_small" +# PROP BASE Intermediate_Dir "Debug_small" +# PROP BASE Target_Dir "" +# PROP Use_MFC 1 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_small" +# PROP Intermediate_Dir "Debug_small" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX"config.h" /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c +# ADD BASE RSC /l 0xc09 +# ADD RSC /l 0xc09 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo /out:"Debug_small/libdb43sd.lib" +# ADD LIB32 /nologo /out:"Debug_small/libdb43sd.lib" + +!ENDIF + +# Begin Target + +# Name "db_small - Win32 Release Static" +# Name "db_small - Win32 Debug Static" +# Begin Source File + +SOURCE=..\btree\bt_compare.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_conv.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_curadj.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_cursor.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_delete.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_method.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_open.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_put.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_rec.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_reclaim.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_recno.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_rsearch.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_search.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_split.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_stat.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_upgrade.c +# End Source File +# Begin Source File + +SOURCE=..\btree\btree_auto.c +# End Source File +# Begin Source File + +SOURCE=..\clib\strcasecmp.c +# End Source File +# Begin Source File + +SOURCE=..\common\crypto_stub.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_byteorder.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_err.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_getlong.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_idspace.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_log2.c +# End Source File +# Begin Source File + +SOURCE=..\common\util_cache.c +# End Source File +# Begin Source File + +SOURCE=..\common\util_log.c +# End Source File +# Begin Source File + +SOURCE=..\common\util_sig.c +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_db.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_dbc.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_dbt.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_env.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_except.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_lock.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_logc.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_mpool.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_multi.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_seq.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_txn.cpp +# End Source File +# Begin Source File + +SOURCE=..\db\crdel_auto.c +# End Source File +# Begin Source File + +SOURCE=..\db\crdel_rec.c +# End Source File +# Begin Source File + +SOURCE=..\db\db.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_am.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_auto.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_cam.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_conv.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_dispatch.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_dup.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_iface.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_join.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_meta.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_method.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_open.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_overflow.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_pr.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_rec.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_reclaim.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_remove.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_rename.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_ret.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_setid.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_setlsn.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_stati.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_truncate.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_upg.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_upg_opd.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_vrfy_stub.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_auto.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_rec.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_stat.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_util.c +# End Source File +# Begin Source File + +SOURCE=..\env\db_salloc.c +# End Source File +# Begin Source File + +SOURCE=..\env\db_shash.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_file.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_method.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_open.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_recover.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_region.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_stat.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fileops_auto.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fop_basic.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fop_rec.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fop_util.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_func.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_stub.c +# End Source File +# Begin Source File + +SOURCE=..\hmac\hmac.c +# End Source File +# Begin Source File + +SOURCE=..\hmac\sha1.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_deadlock.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_id.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_list.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_method.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_region.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_stat.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_timer.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_util.c +# End Source File +# Begin Source File + +SOURCE=..\log\log.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_archive.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_compare.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_get.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_method.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_put.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_stat.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_alloc.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_bh.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fget.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fmethod.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fopen.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fput.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fset.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_method.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_region.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_register.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_stat.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_sync.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_trickle.c +# End Source File +# Begin Source File + +SOURCE=..\mutex\mut_win32.c +# End Source File +# Begin Source File + +SOURCE=..\mutex\mutex.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_alloc.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_id.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_method.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_oflags.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_region.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_root.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_rpath.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_tmpdir.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_abs.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_clock.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_config.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_dir.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_errno.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_fid.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_fsync.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_handle.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_map.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_open.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_rename.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_rw.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_seek.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_sleep.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_spin.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_stat.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_truncate.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_unlink.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_stub.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_stub.c +# End Source File +# Begin Source File + +SOURCE=..\sequence\seq_stat.c +# End Source File +# Begin Source File + +SOURCE=..\sequence\sequence.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_auto.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_method.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_rec.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_recover.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_region.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_stat.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_util.c +# End Source File +# Begin Source File + +SOURCE=..\xa\xa.c +# End Source File +# Begin Source File + +SOURCE=..\xa\xa_db.c +# End Source File +# Begin Source File + +SOURCE=..\xa\xa_map.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_stat.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_stat.dsp new file mode 100644 index 00000000..32414a24 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_stat.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="db_stat" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=db_stat - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_stat.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_stat.mak" CFG="db_stat - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_stat - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "db_stat - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "db_stat - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "db_stat - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_stat - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "db_stat - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "db_stat - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "db_stat - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_stat - Win32 Release" +# Name "db_stat - Win32 Debug" +# Name "db_stat - Win32 Release Static" +# Name "db_stat - Win32 Debug Static" +# Begin Source File + +SOURCE=..\db_stat\db_stat.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_stat.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_stat.vcproj new file mode 100644 index 00000000..fed46963 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_stat.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_static.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_static.dsp new file mode 100644 index 00000000..df482898 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_static.dsp @@ -0,0 +1,848 @@ +# Microsoft Developer Studio Project File - Name="db_static" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=db_static - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_static.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_static.mak" CFG="db_static - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_static - Win32 Release Static" (based on "Win32 (x86) Static Library") +!MESSAGE "db_static - Win32 Debug Static" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_static - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_static" +# PROP BASE Intermediate_Dir "Release_static" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX"config.h" /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c +# ADD BASE RSC /l 0xc09 +# ADD RSC /l 0xc09 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo /out:"Release/libdb43s.lib" +# ADD LIB32 /nologo /out:"Release_static/libdb43s.lib" + +!ELSEIF "$(CFG)" == "db_static - Win32 Debug Static" + +# PROP BASE Use_MFC 1 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_static" +# PROP BASE Intermediate_Dir "Debug_static" +# PROP BASE Target_Dir "" +# PROP Use_MFC 1 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX"config.h" /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c +# ADD BASE RSC /l 0xc09 +# ADD RSC /l 0xc09 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo /out:"Debug/libdb43sd.lib" +# ADD LIB32 /nologo /out:"Debug_static/libdb43sd.lib" + +!ENDIF + +# Begin Target + +# Name "db_static - Win32 Release Static" +# Name "db_static - Win32 Debug Static" +# Begin Source File + +SOURCE=..\btree\bt_compare.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_conv.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_curadj.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_cursor.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_delete.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_method.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_open.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_put.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_rec.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_reclaim.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_recno.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_rsearch.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_search.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_split.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_stat.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_upgrade.c +# End Source File +# Begin Source File + +SOURCE=..\btree\bt_verify.c +# End Source File +# Begin Source File + +SOURCE=..\btree\btree_auto.c +# End Source File +# Begin Source File + +SOURCE=..\clib\strcasecmp.c +# End Source File +# Begin Source File + +SOURCE=..\common\crypto_stub.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_byteorder.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_err.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_getlong.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_idspace.c +# End Source File +# Begin Source File + +SOURCE=..\common\db_log2.c +# End Source File +# Begin Source File + +SOURCE=..\common\util_cache.c +# End Source File +# Begin Source File + +SOURCE=..\common\util_log.c +# End Source File +# Begin Source File + +SOURCE=..\common\util_sig.c +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_db.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_dbc.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_dbt.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_env.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_except.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_lock.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_logc.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_mpool.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_multi.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_seq.cpp +# End Source File +# Begin Source File + +SOURCE=..\cxx\cxx_txn.cpp +# End Source File +# Begin Source File + +SOURCE=..\db\crdel_auto.c +# End Source File +# Begin Source File + +SOURCE=..\db\crdel_rec.c +# End Source File +# Begin Source File + +SOURCE=..\db\db.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_am.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_auto.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_cam.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_conv.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_dispatch.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_dup.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_iface.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_join.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_meta.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_method.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_open.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_overflow.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_ovfl_vrfy.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_pr.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_rec.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_reclaim.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_remove.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_rename.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_ret.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_setid.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_setlsn.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_stati.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_truncate.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_upg.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_upg_opd.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_vrfy.c +# End Source File +# Begin Source File + +SOURCE=..\db\db_vrfyutil.c +# End Source File +# Begin Source File + +SOURCE=..\dbm\dbm.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_auto.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_rec.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_stat.c +# End Source File +# Begin Source File + +SOURCE=..\dbreg\dbreg_util.c +# End Source File +# Begin Source File + +SOURCE=..\env\db_salloc.c +# End Source File +# Begin Source File + +SOURCE=..\env\db_shash.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_file.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_method.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_open.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_recover.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_region.c +# End Source File +# Begin Source File + +SOURCE=..\env\env_stat.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fileops_auto.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fop_basic.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fop_rec.c +# End Source File +# Begin Source File + +SOURCE=..\fileops\fop_util.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_auto.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_conv.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_dup.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_func.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_meta.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_method.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_open.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_page.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_rec.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_reclaim.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_stat.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_upgrade.c +# End Source File +# Begin Source File + +SOURCE=..\hash\hash_verify.c +# End Source File +# Begin Source File + +SOURCE=..\hmac\hmac.c +# End Source File +# Begin Source File + +SOURCE=..\hmac\sha1.c +# End Source File +# Begin Source File + +SOURCE=..\hsearch\hsearch.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_deadlock.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_id.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_list.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_method.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_region.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_stat.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_timer.c +# End Source File +# Begin Source File + +SOURCE=..\lock\lock_util.c +# End Source File +# Begin Source File + +SOURCE=..\log\log.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_archive.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_compare.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_get.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_method.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_put.c +# End Source File +# Begin Source File + +SOURCE=..\log\log_stat.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_alloc.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_bh.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fget.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fmethod.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fopen.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fput.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_fset.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_method.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_region.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_register.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_stat.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_sync.c +# End Source File +# Begin Source File + +SOURCE=..\mp\mp_trickle.c +# End Source File +# Begin Source File + +SOURCE=..\mutex\mut_win32.c +# End Source File +# Begin Source File + +SOURCE=..\mutex\mutex.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_alloc.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_id.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_method.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_oflags.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_region.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_root.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_rpath.c +# End Source File +# Begin Source File + +SOURCE=..\os\os_tmpdir.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_abs.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_clock.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_config.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_dir.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_errno.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_fid.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_fsync.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_handle.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_map.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_open.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_rename.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_rw.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_seek.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_sleep.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_spin.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_stat.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_truncate.c +# End Source File +# Begin Source File + +SOURCE=..\os_win32\os_unlink.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_auto.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_conv.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_files.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_method.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_open.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_rec.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_stat.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_upgrade.c +# End Source File +# Begin Source File + +SOURCE=..\qam\qam_verify.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_auto.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_backup.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_method.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_record.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_region.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_stat.c +# End Source File +# Begin Source File + +SOURCE=..\rep\rep_util.c +# End Source File +# Begin Source File + +SOURCE=..\sequence\seq_stat.c +# End Source File +# Begin Source File + +SOURCE=..\sequence\sequence.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_auto.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_method.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_rec.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_recover.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_region.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_stat.c +# End Source File +# Begin Source File + +SOURCE=..\txn\txn_util.c +# End Source File +# Begin Source File + +SOURCE=..\xa\xa.c +# End Source File +# Begin Source File + +SOURCE=..\xa\xa_db.c +# End Source File +# Begin Source File + +SOURCE=..\xa\xa_map.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_static.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_static.vcproj new file mode 100644 index 00000000..41e37529 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_static.vcproj @@ -0,0 +1,681 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_static_10_0.vcxproj b/src/libs/resiprocate/contrib/db/build_win32/db_static_10_0.vcxproj new file mode 100644 index 00000000..e1e283ac --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_static_10_0.vcxproj @@ -0,0 +1,305 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + db_static + {9E5A7645-1502-4467-91F8-BCF2EB06EF72} + MFCProj + + + + StaticLibrary + false + MultiByte + + + StaticLibrary + Static + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.21006.1 + Debug_static\ + Debug_static\ + Release_static\ + Release_static\ + AllRules.ruleset + + + AllRules.ruleset + + + libdb43sd + libdb43s + + + + Disabled + .;..;%(AdditionalIncludeDirectories) + CONFIG_TEST;WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + config.h + .\Debug_static/db_static.pch + .\Debug_static/ + .\Debug_static/ + .\Debug_static/ + Level3 + true + OldStyle + Default + + + 0x0c09 + + + $(OutDir)$(TargetName)$(TargetExt) + true + + + + + OnlyExplicitInline + .;..;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + + + config.h + .\Release_static/db_static.pch + .\Release_static/ + .\Release_static/ + .\Release_static/ + Level3 + true + Default + + + 0x0c09 + + + $(OutDir)$(TargetName)$(TargetExt) + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_static_7_1.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_static_7_1.vcproj new file mode 100644 index 00000000..aa45fc53 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_static_7_1.vcproj @@ -0,0 +1,746 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_static_8_0.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_static_8_0.vcproj new file mode 100644 index 00000000..ea3e6e9a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_static_8_0.vcproj @@ -0,0 +1,935 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_static_9_0.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_static_9_0.vcproj new file mode 100644 index 00000000..559a7b00 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_static_9_0.vcproj @@ -0,0 +1,936 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_static_lib_7_1.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_static_lib_7_1.vcproj new file mode 100644 index 00000000..d326ca25 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_static_lib_7_1.vcproj @@ -0,0 +1,696 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_tcl.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_tcl.dsp new file mode 100644 index 00000000..94fb4928 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_tcl.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="db_tcl" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=db_tcl - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_tcl.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_tcl.mak" CFG="db_tcl - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_tcl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "db_tcl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_tcl - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_TCL_SUPPORT" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 Release/libdb43.lib tcl84.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"Release/libdb_tcl43.dll" + +!ELSEIF "$(CFG)" == "db_tcl - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DB_TCL_SUPPORT" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /D "_WINDLL" /D "_AFXDLL" /YX"config.h" /FD /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib tcl84g.lib /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"Debug/libdb_tcl43d.dll" /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_tcl - Win32 Release" +# Name "db_tcl - Win32 Debug" +# Begin Source File + +SOURCE=.\libdb_tcl.def +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_compat.c +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_db.c +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_db_pkg.c +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_dbcursor.c +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_env.c +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_internal.c +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_lock.c +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_log.c +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_mp.c +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_rep.c +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_seq.c +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_txn.c +# End Source File +# Begin Source File + +SOURCE=..\tcl\tcl_util.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_tcl.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_tcl.vcproj new file mode 100644 index 00000000..2f433138 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_tcl.vcproj @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_test.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_test.dsp new file mode 100644 index 00000000..2e72eeb2 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_test.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="db_test" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=db_test - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_test.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_test.mak" CFG="db_test - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_test - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "db_test - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_test - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Desc=Copy built executable files. +PostBuild_Cmds=copy Release\*.exe . +# End Special Build Tool + +!ELSEIF "$(CFG)" == "db_test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /out:"Debug/dbkill.exe" /fixed:no +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Desc=Copy built executable files. +PostBuild_Cmds=copy Debug\*.exe . +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "db_test - Win32 Release" +# Name "db_test - Win32 Debug" +# Begin Source File + +SOURCE=.\dbkill.cpp +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_test.src b/src/libs/resiprocate/contrib/db/build_win32/db_test.src new file mode 100644 index 00000000..6bc287a0 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_test.src @@ -0,0 +1,97 @@ +# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=@project_name@ - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "@project_name@ - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /subsystem:console /machine:I386 +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Desc=Copy built executable files. +PostBuild_Cmds=copy Release\*.exe . +# End Special Build Tool + +!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /out:"Debug/dbkill.exe" /fixed:no +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Desc=Copy built executable files. +PostBuild_Cmds=copy Debug\*.exe . +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "@project_name@ - Win32 Release" +# Name "@project_name@ - Win32 Debug" +@SOURCE_FILES@ +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_test.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_test.vcproj new file mode 100644 index 00000000..1eb43c5d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_test.vcproj @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_upgrade.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_upgrade.dsp new file mode 100644 index 00000000..7a61782c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_upgrade.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="db_upgrade" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=db_upgrade - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_upgrade.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_upgrade.mak" CFG="db_upgrade - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_upgrade - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "db_upgrade - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "db_upgrade - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "db_upgrade - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_upgrade - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "db_upgrade - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "db_upgrade - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "db_upgrade - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_upgrade - Win32 Release" +# Name "db_upgrade - Win32 Debug" +# Name "db_upgrade - Win32 Release Static" +# Name "db_upgrade - Win32 Debug Static" +# Begin Source File + +SOURCE=..\db_upgrade\db_upgrade.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_upgrade.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_upgrade.vcproj new file mode 100644 index 00000000..b8902e3a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_upgrade.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_verify.dsp b/src/libs/resiprocate/contrib/db/build_win32/db_verify.dsp new file mode 100644 index 00000000..52f3a6b4 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_verify.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="db_verify" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=db_verify - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "db_verify.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "db_verify.mak" CFG="db_verify - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "db_verify - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "db_verify - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "db_verify - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "db_verify - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "db_verify - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "db_verify - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "db_verify - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "db_verify - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "db_verify - Win32 Release" +# Name "db_verify - Win32 Debug" +# Name "db_verify - Win32 Release Static" +# Name "db_verify - Win32 Debug Static" +# Begin Source File + +SOURCE=..\db_verify\db_verify.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/db_verify.vcproj b/src/libs/resiprocate/contrib/db/build_win32/db_verify.vcproj new file mode 100644 index 00000000..51367983 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/db_verify.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/dbkill.cpp b/src/libs/resiprocate/contrib/db/build_win32/dbkill.cpp new file mode 100644 index 00000000..7be76135 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/dbkill.cpp @@ -0,0 +1,131 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1999-2004 + * Sleepycat Software. All rights reserved. + * + * $Id: dbkill.cpp,v 11.9 2004/01/28 03:35:52 bostic Exp $ + */ +/* + * Kill - + * Simulate Unix kill on Windows/NT and Windows/9X. + * This good enough to support the Berkeley DB test suite, + * but may be missing some favorite features. + * + * Would have used MKS kill, but it didn't seem to work well + * on Win/9X. Cygnus kill works within the Gnu/Cygnus environment + * (where processes are given small pids, with presumably a translation + * table between small pids and actual process handles), but our test + * environment, via Tcl, does not use the Cygnus environment. + * + * Compile this and install it as c:/tools/kill.exe (or as indicated + * by build_win32/include.tcl ). + */ + +#include +#include +#include +#include + +/* + * Like atol, with specified base. Would use stdlib, but + * strtol("0xFFFF1234", NULL, 16) returns 0x7FFFFFFF and + * strtol("4294712487", NULL, 16) returns 0x7FFFFFFF w/ VC++ + */ +long +myatol(char *s, int base) +{ + long result = 0; + char ch; + int sign = 1; /* + */ + if (base == 0) + base = 10; + if (base != 10 && base != 16) + return LONG_MAX; + while ((ch = *s++) != '\0') { + if (ch == '-') { + sign = -sign; + } + else if (ch >= '0' && ch <= '9') { + result = result * base + (ch - '0'); + } + else if (ch == 'x' || ch == 'X') { + /* Allow leading 0x..., and switch to base 16 */ + base = 16; + } + else if (base == 16 && ch >= 'a' && ch <= 'f') { + result = result * base + (ch - 'a' + 10); + } + else if (base == 16 && ch >= 'A' && ch <= 'F') { + result = result * base + (ch - 'A' + 10); + } + else { + if (sign > 1) + return LONG_MAX; + else + return LONG_MIN; + } + } + return sign * result; +} + +void +usage_exit() +{ + fprintf(stderr, "Usage: kill [ -sig ] pid\n"); + fprintf(stderr, " for win32, sig must be or 0, 15 (TERM)\n"); + exit(EXIT_FAILURE); +} + +int +main(int argc, char **argv) +{ + HANDLE hProcess ; + DWORD accessflag; + long pid; + int sig = 15; + + if (argc > 2) { + if (argv[1][0] != '-') + usage_exit(); + + if (strcmp(argv[1], "-TERM") == 0) + sig = 15; + else { + /* currently sig is more or less ignored, + * we only care if it is zero or not + */ + sig = atoi(&argv[1][1]); + if (sig < 0) + usage_exit(); + } + argc--; + argv++; + } + if (argc < 2) + usage_exit(); + + pid = myatol(argv[1], 10); + /*printf("pid = %ld (0x%lx) (command line %s)\n", pid, pid, argv[1]);*/ + if (pid == LONG_MAX || pid == LONG_MIN) + usage_exit(); + + if (sig == 0) + accessflag = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ; + else + accessflag = STANDARD_RIGHTS_REQUIRED | PROCESS_TERMINATE; + hProcess = OpenProcess(accessflag, FALSE, pid); + if (hProcess == NULL) { + fprintf(stderr, "dbkill: %s: no such process\n", argv[1]); + exit(EXIT_FAILURE); + } + if (sig == 0) + exit(EXIT_SUCCESS); + if (!TerminateProcess(hProcess, 99)) { + DWORD err = GetLastError(); + fprintf(stderr, + "dbkill: cannot kill process: error %d (0x%lx)\n", err, err); + exit(EXIT_FAILURE); + } + return EXIT_SUCCESS; +} diff --git a/src/libs/resiprocate/contrib/db/build_win32/dynamic_dsp.src b/src/libs/resiprocate/contrib/db/build_win32/dynamic_dsp.src new file mode 100644 index 00000000..2229edd3 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/dynamic_dsp.src @@ -0,0 +1,93 @@ +# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=@project_name@ - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "@project_name@ - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" + +!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DB_CREATE_DLL" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no + +!ENDIF + +# Begin Target + +# Name "@project_name@ - Win32 Release" +# Name "@project_name@ - Win32 Debug" +@SOURCE_FILES@ +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_access.dsp b/src/libs/resiprocate/contrib/db/build_win32/ex_access.dsp new file mode 100644 index 00000000..afe411eb --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_access.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="ex_access" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=ex_access - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ex_access.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ex_access.mak" CFG="ex_access - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ex_access - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_access - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_access - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_access - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ex_access - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "ex_access - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "ex_access - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "ex_access - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "ex_access - Win32 Release" +# Name "ex_access - Win32 Debug" +# Name "ex_access - Win32 Release Static" +# Name "ex_access - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_c\ex_access.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_access.vcproj b/src/libs/resiprocate/contrib/db/build_win32/ex_access.vcproj new file mode 100644 index 00000000..a99442dc --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_access.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_btrec.dsp b/src/libs/resiprocate/contrib/db/build_win32/ex_btrec.dsp new file mode 100644 index 00000000..91bb12ae --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_btrec.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="ex_btrec" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=ex_btrec - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ex_btrec.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ex_btrec.mak" CFG="ex_btrec - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ex_btrec - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_btrec - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_btrec - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_btrec - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ex_btrec - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "ex_btrec - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "ex_btrec - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "ex_btrec - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "ex_btrec - Win32 Release" +# Name "ex_btrec - Win32 Debug" +# Name "ex_btrec - Win32 Release Static" +# Name "ex_btrec - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_c\ex_btrec.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_btrec.vcproj b/src/libs/resiprocate/contrib/db/build_win32/ex_btrec.vcproj new file mode 100644 index 00000000..4d90018c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_btrec.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_env.dsp b/src/libs/resiprocate/contrib/db/build_win32/ex_env.dsp new file mode 100644 index 00000000..f745991d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_env.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="ex_env" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=ex_env - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ex_env.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ex_env.mak" CFG="ex_env - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ex_env - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_env - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_env - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_env - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ex_env - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "ex_env - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "ex_env - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "ex_env - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "ex_env - Win32 Release" +# Name "ex_env - Win32 Debug" +# Name "ex_env - Win32 Release Static" +# Name "ex_env - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_c\ex_env.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_env.vcproj b/src/libs/resiprocate/contrib/db/build_win32/ex_env.vcproj new file mode 100644 index 00000000..93691c51 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_env.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_lock.dsp b/src/libs/resiprocate/contrib/db/build_win32/ex_lock.dsp new file mode 100644 index 00000000..f64aff4c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_lock.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="ex_lock" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=ex_lock - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ex_lock.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ex_lock.mak" CFG="ex_lock - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ex_lock - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_lock - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_lock - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_lock - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ex_lock - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "ex_lock - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "ex_lock - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "ex_lock - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "ex_lock - Win32 Release" +# Name "ex_lock - Win32 Debug" +# Name "ex_lock - Win32 Release Static" +# Name "ex_lock - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_c\ex_lock.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_lock.vcproj b/src/libs/resiprocate/contrib/db/build_win32/ex_lock.vcproj new file mode 100644 index 00000000..8abe6e36 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_lock.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_mpool.dsp b/src/libs/resiprocate/contrib/db/build_win32/ex_mpool.dsp new file mode 100644 index 00000000..5e478a01 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_mpool.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="ex_mpool" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=ex_mpool - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ex_mpool.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ex_mpool.mak" CFG="ex_mpool - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ex_mpool - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_mpool - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_mpool - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_mpool - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ex_mpool - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "ex_mpool - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "ex_mpool - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "ex_mpool - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "ex_mpool - Win32 Release" +# Name "ex_mpool - Win32 Debug" +# Name "ex_mpool - Win32 Release Static" +# Name "ex_mpool - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_c\ex_mpool.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_mpool.vcproj b/src/libs/resiprocate/contrib/db/build_win32/ex_mpool.vcproj new file mode 100644 index 00000000..8af18b49 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_mpool.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_repquote.dsp b/src/libs/resiprocate/contrib/db/build_win32/ex_repquote.dsp new file mode 100644 index 00000000..cf56f2b7 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_repquote.dsp @@ -0,0 +1,164 @@ +# Microsoft Developer Studio Project File - Name="ex_repquote" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=ex_repquote - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ex_repquote.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ex_repquote.mak" CFG="ex_repquote - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ex_repquote - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_repquote - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_repquote - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_repquote - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ex_repquote - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "ex_repquote - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib ws2_32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "ex_repquote - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib ws2_32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib ws2_32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "ex_repquote - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "ex_repquote - Win32 Release" +# Name "ex_repquote - Win32 Debug" +# Name "ex_repquote - Win32 Release Static" +# Name "ex_repquote - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_c\ex_repquote\ex_rq_client.c +# End Source File +# Begin Source File + +SOURCE=..\examples_c\ex_repquote\ex_rq_main.c +# End Source File +# Begin Source File + +SOURCE=..\examples_c\ex_repquote\ex_rq_master.c +# End Source File +# Begin Source File + +SOURCE=..\examples_c\ex_repquote\ex_rq_net.c +# End Source File +# Begin Source File + +SOURCE=..\examples_c\ex_repquote\ex_rq_util.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_repquote.src b/src/libs/resiprocate/contrib/db/build_win32/ex_repquote.src new file mode 100644 index 00000000..99c8a751 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_repquote.src @@ -0,0 +1,145 @@ +# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=@project_name@ - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "@project_name@ - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "@project_name@ - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "@project_name@ - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib ws2_32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "@project_name@ - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib ws2_32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib ws2_32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "@project_name@ - Win32 Release" +# Name "@project_name@ - Win32 Debug" +# Name "@project_name@ - Win32 Release Static" +# Name "@project_name@ - Win32 Debug Static" +@SOURCE_FILES@ +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_repquote.vcproj b/src/libs/resiprocate/contrib/db/build_win32/ex_repquote.vcproj new file mode 100644 index 00000000..894f1178 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_repquote.vcproj @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_tpcb.dsp b/src/libs/resiprocate/contrib/db/build_win32/ex_tpcb.dsp new file mode 100644 index 00000000..91436d2d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_tpcb.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="ex_tpcb" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=ex_tpcb - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ex_tpcb.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ex_tpcb.mak" CFG="ex_tpcb - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ex_tpcb - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_tpcb - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_tpcb - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "ex_tpcb - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ex_tpcb - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "ex_tpcb - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "ex_tpcb - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "ex_tpcb - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "ex_tpcb - Win32 Release" +# Name "ex_tpcb - Win32 Debug" +# Name "ex_tpcb - Win32 Release Static" +# Name "ex_tpcb - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_c\ex_tpcb.c +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/ex_tpcb.vcproj b/src/libs/resiprocate/contrib/db/build_win32/ex_tpcb.vcproj new file mode 100644 index 00000000..513cbb58 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/ex_tpcb.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/excxx_access.dsp b/src/libs/resiprocate/contrib/db/build_win32/excxx_access.dsp new file mode 100644 index 00000000..d787c63d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/excxx_access.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="excxx_access" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=excxx_access - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "excxx_access.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "excxx_access.mak" CFG="excxx_access - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "excxx_access - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_access - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_access - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_access - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "excxx_access - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "excxx_access - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "excxx_access - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "excxx_access - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "excxx_access - Win32 Release" +# Name "excxx_access - Win32 Debug" +# Name "excxx_access - Win32 Release Static" +# Name "excxx_access - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_cxx\AccessExample.cpp +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/excxx_access.vcproj b/src/libs/resiprocate/contrib/db/build_win32/excxx_access.vcproj new file mode 100644 index 00000000..557cfcf9 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/excxx_access.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/excxx_btrec.dsp b/src/libs/resiprocate/contrib/db/build_win32/excxx_btrec.dsp new file mode 100644 index 00000000..2ad96a46 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/excxx_btrec.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="excxx_btrec" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=excxx_btrec - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "excxx_btrec.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "excxx_btrec.mak" CFG="excxx_btrec - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "excxx_btrec - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_btrec - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_btrec - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_btrec - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "excxx_btrec - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "excxx_btrec - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "excxx_btrec - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "excxx_btrec - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "excxx_btrec - Win32 Release" +# Name "excxx_btrec - Win32 Debug" +# Name "excxx_btrec - Win32 Release Static" +# Name "excxx_btrec - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_cxx\BtRecExample.cpp +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/excxx_btrec.vcproj b/src/libs/resiprocate/contrib/db/build_win32/excxx_btrec.vcproj new file mode 100644 index 00000000..9ba13701 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/excxx_btrec.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/excxx_env.dsp b/src/libs/resiprocate/contrib/db/build_win32/excxx_env.dsp new file mode 100644 index 00000000..eae5c9b9 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/excxx_env.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="excxx_env" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=excxx_env - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "excxx_env.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "excxx_env.mak" CFG="excxx_env - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "excxx_env - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_env - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_env - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_env - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "excxx_env - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "excxx_env - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "excxx_env - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "excxx_env - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "excxx_env - Win32 Release" +# Name "excxx_env - Win32 Debug" +# Name "excxx_env - Win32 Release Static" +# Name "excxx_env - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_cxx\EnvExample.cpp +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/excxx_env.vcproj b/src/libs/resiprocate/contrib/db/build_win32/excxx_env.vcproj new file mode 100644 index 00000000..4c08071d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/excxx_env.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/excxx_lock.dsp b/src/libs/resiprocate/contrib/db/build_win32/excxx_lock.dsp new file mode 100644 index 00000000..943d6bb3 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/excxx_lock.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="excxx_lock" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=excxx_lock - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "excxx_lock.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "excxx_lock.mak" CFG="excxx_lock - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "excxx_lock - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_lock - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_lock - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_lock - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "excxx_lock - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "excxx_lock - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "excxx_lock - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "excxx_lock - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "excxx_lock - Win32 Release" +# Name "excxx_lock - Win32 Debug" +# Name "excxx_lock - Win32 Release Static" +# Name "excxx_lock - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_cxx\LockExample.cpp +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/excxx_lock.vcproj b/src/libs/resiprocate/contrib/db/build_win32/excxx_lock.vcproj new file mode 100644 index 00000000..ca871a57 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/excxx_lock.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/excxx_mpool.dsp b/src/libs/resiprocate/contrib/db/build_win32/excxx_mpool.dsp new file mode 100644 index 00000000..20819f4b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/excxx_mpool.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="excxx_mpool" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=excxx_mpool - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "excxx_mpool.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "excxx_mpool.mak" CFG="excxx_mpool - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "excxx_mpool - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_mpool - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_mpool - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_mpool - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "excxx_mpool - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "excxx_mpool - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "excxx_mpool - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "excxx_mpool - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "excxx_mpool - Win32 Release" +# Name "excxx_mpool - Win32 Debug" +# Name "excxx_mpool - Win32 Release Static" +# Name "excxx_mpool - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_cxx\MpoolExample.cpp +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/excxx_mpool.vcproj b/src/libs/resiprocate/contrib/db/build_win32/excxx_mpool.vcproj new file mode 100644 index 00000000..cff83afc --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/excxx_mpool.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/excxx_tpcb.dsp b/src/libs/resiprocate/contrib/db/build_win32/excxx_tpcb.dsp new file mode 100644 index 00000000..1976b91a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/excxx_tpcb.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="excxx_tpcb" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=excxx_tpcb - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "excxx_tpcb.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "excxx_tpcb.mak" CFG="excxx_tpcb - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "excxx_tpcb - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_tpcb - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_tpcb - Win32 Release Static" (based on "Win32 (x86) Console Application") +!MESSAGE "excxx_tpcb - Win32 Debug Static" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "excxx_tpcb - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release/libdb43.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" + +!ELSEIF "$(CFG)" == "excxx_tpcb - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb43d.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no + +!ELSEIF "$(CFG)" == "excxx_tpcb - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Release_static/libdb43.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release_static/libdb43s.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "excxx_tpcb - Win32 Debug Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 Debug_static/libdb43d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no +# ADD LINK32 Debug_static/libdb43sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no + +!ENDIF + +# Begin Target + +# Name "excxx_tpcb - Win32 Release" +# Name "excxx_tpcb - Win32 Debug" +# Name "excxx_tpcb - Win32 Release Static" +# Name "excxx_tpcb - Win32 Debug Static" +# Begin Source File + +SOURCE=..\examples_cxx\TpcbExample.cpp +# End Source File +# Begin Source File + +SOURCE=..\clib\getopt.c +# End Source File +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/excxx_tpcb.vcproj b/src/libs/resiprocate/contrib/db/build_win32/excxx_tpcb.vcproj new file mode 100644 index 00000000..e76a378a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/excxx_tpcb.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/db/build_win32/include.tcl b/src/libs/resiprocate/contrib/db/build_win32/include.tcl new file mode 100644 index 00000000..fd0e69f2 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/include.tcl @@ -0,0 +1,20 @@ +# Automatically built by dist/s_test; may require local editing. + +set tclsh_path SET_YOUR_TCLSH_PATH +set tcllib ./Debug/libdb_tcl43d.dll + +set src_root .. +set test_path ../test +set je_root ../../je + +global testdir +set testdir ./TESTDIR + +global dict +global util_path + +global is_hp_test +global is_qnx_test +global is_windows_test + +set KILL ./dbkill.exe diff --git a/src/libs/resiprocate/contrib/db/build_win32/java_dsp.src b/src/libs/resiprocate/contrib/db/build_win32/java_dsp.src new file mode 100644 index 00000000..c06cb2b3 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/java_dsp.src @@ -0,0 +1,129 @@ +# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=@project_name@ - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "@project_name@ - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"Release/libdb_java@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" +# Begin Custom Build - Compiling java files using javac +ProjDir=. +InputPath=.\Release\libdb_java@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll +SOURCE="$(InputPath)" + +"force_compilation.txt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo compiling Berkeley DB classes + mkdir "$(OUTDIR)\classes" + javac -O -d "$(OUTDIR)\classes" -classpath "$(OUTDIR)/classes" ..\java\src\com\sleepycat\db\*.java ..\java\src\com\sleepycat\db\internal\*.java ..\java\src\com\sleepycat\bind\*.java ..\java\src\com\sleepycat\bind\serial\*.java ..\java\src\com\sleepycat\bind\tuple\*.java ..\java\src\com\sleepycat\collections\*.java ..\java\src\com\sleepycat\compat\*.java ..\java\src\com\sleepycat\util\*.java + echo compiling examples + mkdir "$(OUTDIR)\classes.ex" + javac -O -d "$(OUTDIR)\classes.ex" -classpath "$(OUTDIR)\classes;$(OUTDIR)\classes.ex" ..\examples_java\src\com\sleepycat\examples\db\*.java ..\examples_java\src\com\sleepycat\examples\db\GettingStarted\*.java ..\examples_java\src\com\sleepycat\examples\collections\access\*.java ..\examples_java\src\com\sleepycat\examples\collections\hello\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\basic\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\entity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\tuple\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\sentity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\marshal\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\factory\*.java + echo creating jar files + jar cf "$(OUTDIR)\db.jar" -C "$(OUTDIR)\classes" . + jar cf "$(OUTDIR)\dbexamples.jar" -C "$(OUTDIR)\classes.ex" . + echo Java build finished + +# End Custom Build + +!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /D "_WINDLL" /D "_AFXDLL" /YX"config.h" /FD /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"Debug/libdb_java@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no +# Begin Custom Build - Compiling java files using javac +ProjDir=. +InputPath=.\Debug\libdb_java@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll +SOURCE="$(InputPath)" + +"force_compilation.txt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + echo compiling Berkeley DB classes + mkdir "$(OUTDIR)\classes" + javac -g -d "$(OUTDIR)\classes" -classpath "$(OUTDIR)/classes" ..\java\src\com\sleepycat\db\*.java ..\java\src\com\sleepycat\db\internal\*.java ..\java\src\com\sleepycat\bind\*.java ..\java\src\com\sleepycat\bind\serial\*.java ..\java\src\com\sleepycat\bind\tuple\*.java ..\java\src\com\sleepycat\collections\*.java ..\java\src\com\sleepycat\compat\*.java ..\java\src\com\sleepycat\util\*.java + echo compiling examples + mkdir "$(OUTDIR)\classes.ex" + javac -g -d "$(OUTDIR)\classes.ex" -classpath "$(OUTDIR)\classes;$(OUTDIR)\classes.ex" ..\examples_java\src\com\sleepycat\examples\db\*.java ..\examples_java\src\com\sleepycat\examples\db\GettingStarted\*.java ..\examples_java\src\com\sleepycat\examples\collections\access\*.java ..\examples_java\src\com\sleepycat\examples\collections\hello\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\basic\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\entity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\tuple\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\sentity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\marshal\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\factory\*.java + echo creating jar files + jar cf "$(OUTDIR)\db.jar" -C "$(OUTDIR)\classes" . + jar cf "$(OUTDIR)\dbexamples.jar" -C "$(OUTDIR)\classes.ex" . + echo Java build finished + +# End Custom Build + +!ENDIF + +# Begin Target + +# Name "@project_name@ - Win32 Release" +# Name "@project_name@ - Win32 Debug" +@SOURCE_FILES@ +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/libdb.def b/src/libs/resiprocate/contrib/db/build_win32/libdb.def new file mode 100644 index 00000000..f519ad54 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/libdb.def @@ -0,0 +1,171 @@ +; DO NOT EDIT: automatically built by dist/s_win32. + +EXPORTS + db_create @1 + db_env_create @2 + db_sequence_create @3 + db_strerror @4 + db_version @5 + db_xa_switch @6 + log_compare @7 + db_env_set_func_close @8 + db_env_set_func_dirfree @9 + db_env_set_func_dirlist @10 + db_env_set_func_exists @11 + db_env_set_func_free @12 + db_env_set_func_fsync @13 + db_env_set_func_ftruncate @14 + db_env_set_func_ioinfo @15 + db_env_set_func_malloc @16 + db_env_set_func_map @17 + db_env_set_func_open @18 + db_env_set_func_pread @19 + db_env_set_func_pwrite @20 + db_env_set_func_read @21 + db_env_set_func_realloc @22 + db_env_set_func_rename @23 + db_env_set_func_seek @24 + db_env_set_func_sleep @25 + db_env_set_func_unlink @26 + db_env_set_func_unmap @27 + db_env_set_func_write @28 + db_env_set_func_yield @29 + __db_add_recovery @30 + __db_dbm_close @31 + __db_dbm_delete @32 + __db_dbm_fetch @33 + __db_dbm_firstkey @34 + __db_dbm_init @35 + __db_dbm_nextkey @36 + __db_dbm_store @37 + __db_get_flags_fn @38 + __db_get_seq_flags_fn @39 + __db_hcreate @40 + __db_hdestroy @41 + __db_hsearch @42 + __db_loadme @43 + __db_ndbm_clearerr @44 + __db_ndbm_close @45 + __db_ndbm_delete @46 + __db_ndbm_dirfno @47 + __db_ndbm_error @48 + __db_ndbm_fetch @49 + __db_ndbm_firstkey @50 + __db_ndbm_nextkey @51 + __db_ndbm_open @52 + __db_ndbm_pagfno @53 + __db_ndbm_rdonly @54 + __db_ndbm_store @55 + __db_panic @56 + __db_r_attach @57 + __db_r_detach @58 + __db_win32_mutex_init @59 + __db_win32_mutex_lock @60 + __db_win32_mutex_unlock @61 + __ham_func2 @62 + __ham_func3 @63 + __ham_func4 @64 + __ham_func5 @65 + __ham_test @66 + __lock_id_set @67 + __os_calloc @68 + __os_closehandle @69 + __os_free @70 + __os_ioinfo @71 + __os_malloc @72 + __os_open @73 + __os_openhandle @74 + __os_read @75 + __os_realloc @76 + __os_strdup @77 + __os_umalloc @78 + __os_write @79 + __txn_id_set @80 + __bam_adj_read @81 + __bam_cadjust_read @82 + __bam_cdel_read @83 + __bam_curadj_read @84 + __bam_pgin @85 + __bam_pgout @86 + __bam_rcuradj_read @87 + __bam_relink_read @88 + __bam_repl_read @89 + __bam_root_read @90 + __bam_rsplit_read @91 + __bam_split_read @92 + __crdel_metasub_read @93 + __db_addrem_read @94 + __db_big_read @95 + __db_cksum_read @96 + __db_debug_read @97 + __db_dispatch @98 + __db_dumptree @99 + __db_err @100 + __db_fileid_reset @101 + __db_getlong @102 + __db_getulong @103 + __db_global_values @104 + __db_isbigendian @105 + __db_lsn_reset @106 + __db_noop_read @107 + __db_omode @108 + __db_overwrite @109 + __db_ovref_read @110 + __db_pg_alloc_read @111 + __db_pg_free_read @112 + __db_pg_freedata_read @113 + __db_pg_init_read @114 + __db_pg_new_read @115 + __db_pg_prepare_read @116 + __db_pgin @117 + __db_pgout @118 + __db_pr_callback @119 + __db_rpath @120 + __db_stat_pp @121 + __db_stat_print_pp @122 + __db_util_cache @123 + __db_util_interrupted @124 + __db_util_logset @125 + __db_util_siginit @126 + __db_util_sigresend @127 + __db_verify_internal @128 + __dbreg_register_read @129 + __fop_create_read @130 + __fop_file_remove_read @131 + __fop_remove_read @132 + __fop_rename_read @133 + __fop_write_read @134 + __ham_chgpg_read @135 + __ham_copypage_read @136 + __ham_curadj_read @137 + __ham_get_meta @138 + __ham_groupalloc_read @139 + __ham_insdel_read @140 + __ham_metagroup_read @141 + __ham_newpage_read @142 + __ham_pgin @143 + __ham_pgout @144 + __ham_release_meta @145 + __ham_replace_read @146 + __ham_splitdata_read @147 + __lock_list_print @148 + __log_stat_pp @149 + __os_clock @150 + __os_get_errno @151 + __os_id @152 + __os_set_errno @153 + __os_sleep @154 + __os_ufree @155 + __os_yield @156 + __qam_add_read @157 + __qam_del_read @158 + __qam_delext_read @159 + __qam_incfirst_read @160 + __qam_mvptr_read @161 + __qam_pgin_out @162 + __rep_stat_print @163 + __txn_child_read @164 + __txn_ckp_read @165 + __txn_recycle_read @166 + __txn_regop_read @167 + __txn_xa_regop_read @168 diff --git a/src/libs/resiprocate/contrib/db/build_win32/libdb.rc b/src/libs/resiprocate/contrib/db/build_win32/libdb.rc new file mode 100644 index 00000000..bdd74de1 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/libdb.rc @@ -0,0 +1,33 @@ +1 VERSIONINFO + FILEVERSION 4,0,3,27 + PRODUCTVERSION 4,0,3,27 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Sleepycat Software\0" + VALUE "FileDescription", "Berkeley DB 3.0 DLL\0" + VALUE "FileVersion", "4.3.27\0" + VALUE "InternalName", "libdb.dll\0" + VALUE "LegalCopyright", "Copyright Sleepycat Software Inc. 1997-2004\0" + VALUE "OriginalFilename", "libdb.dll\0" + VALUE "ProductName", "Sleepycat Software libdb\0" + VALUE "ProductVersion", "4.3.27\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/src/libs/resiprocate/contrib/db/build_win32/libdb_tcl.def b/src/libs/resiprocate/contrib/db/build_win32/libdb_tcl.def new file mode 100644 index 00000000..5e8386a3 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/libdb_tcl.def @@ -0,0 +1,7 @@ +; $Id: libdb_tcl.def,v 11.7 2002/10/14 23:44:20 mjc Exp $ + +DESCRIPTION 'Berkeley DB TCL interface Library' +EXPORTS + Db_tcl_Init + _NameToPtr + diff --git a/src/libs/resiprocate/contrib/db/build_win32/libdbrc.src b/src/libs/resiprocate/contrib/db/build_win32/libdbrc.src new file mode 100644 index 00000000..4c644ea9 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/libdbrc.src @@ -0,0 +1,33 @@ +1 VERSIONINFO + FILEVERSION %MAJOR%,0,%MINOR%,%PATCH% + PRODUCTVERSION %MAJOR%,0,%MINOR%,%PATCH% + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Sleepycat Software\0" + VALUE "FileDescription", "Berkeley DB 3.0 DLL\0" + VALUE "FileVersion", "%MAJOR%.%MINOR%.%PATCH%\0" + VALUE "InternalName", "libdb.dll\0" + VALUE "LegalCopyright", "Copyright Sleepycat Software Inc. 1997-2004\0" + VALUE "OriginalFilename", "libdb.dll\0" + VALUE "ProductName", "Sleepycat Software libdb\0" + VALUE "ProductVersion", "%MAJOR%.%MINOR%.%PATCH%\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/src/libs/resiprocate/contrib/db/build_win32/small_dsp.src b/src/libs/resiprocate/contrib/db/build_win32/small_dsp.src new file mode 100644 index 00000000..a54160f6 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/small_dsp.src @@ -0,0 +1,85 @@ +# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=@project_name@ - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "@project_name@ - Win32 Release Static" (based on "Win32 (x86) Static Library") +!MESSAGE "@project_name@ - Win32 Debug Static" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "@project_name@ - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_small" +# PROP BASE Intermediate_Dir "Release_small" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_small" +# PROP Intermediate_Dir "Release_small" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX"config.h" /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c +# ADD BASE RSC /l 0xc09 +# ADD RSC /l 0xc09 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo /out:"Release_small/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" +# ADD LIB32 /nologo /out:"Release_small/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" + +!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug Static" + +# PROP BASE Use_MFC 1 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_small" +# PROP BASE Intermediate_Dir "Debug_small" +# PROP BASE Target_Dir "" +# PROP Use_MFC 1 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_small" +# PROP Intermediate_Dir "Debug_small" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX"config.h" /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c +# ADD BASE RSC /l 0xc09 +# ADD RSC /l 0xc09 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo /out:"Debug_small/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" +# ADD LIB32 /nologo /out:"Debug_small/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" + +!ENDIF + +# Begin Target + +# Name "@project_name@ - Win32 Release Static" +# Name "@project_name@ - Win32 Debug Static" +@SOURCE_FILES@ +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/srcfile_dsp.src b/src/libs/resiprocate/contrib/db/build_win32/srcfile_dsp.src new file mode 100644 index 00000000..572350e6 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/srcfile_dsp.src @@ -0,0 +1,4 @@ +# Begin Source File + +SOURCE=@srcdir@\@srcfile@ +# End Source File diff --git a/src/libs/resiprocate/contrib/db/build_win32/static_dsp.src b/src/libs/resiprocate/contrib/db/build_win32/static_dsp.src new file mode 100644 index 00000000..411e8df8 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/static_dsp.src @@ -0,0 +1,85 @@ +# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=@project_name@ - Win32 Debug Static +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug Static" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "@project_name@ - Win32 Release Static" (based on "Win32 (x86) Static Library") +!MESSAGE "@project_name@ - Win32 Debug Static" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "@project_name@ - Win32 Release Static" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_static" +# PROP BASE Intermediate_Dir "Release_static" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_static" +# PROP Intermediate_Dir "Release_static" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX"config.h" /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c +# ADD BASE RSC /l 0xc09 +# ADD RSC /l 0xc09 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo /out:"Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" +# ADD LIB32 /nologo /out:"Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" + +!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug Static" + +# PROP BASE Use_MFC 1 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_static" +# PROP BASE Intermediate_Dir "Debug_static" +# PROP BASE Target_Dir "" +# PROP Use_MFC 1 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_static" +# PROP Intermediate_Dir "Debug_static" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX"config.h" /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c +# ADD BASE RSC /l 0xc09 +# ADD RSC /l 0xc09 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo /out:"Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" +# ADD LIB32 /nologo /out:"Debug_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" + +!ENDIF + +# Begin Target + +# Name "@project_name@ - Win32 Release Static" +# Name "@project_name@ - Win32 Debug Static" +@SOURCE_FILES@ +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/tcl_dsp.src b/src/libs/resiprocate/contrib/db/build_win32/tcl_dsp.src new file mode 100644 index 00000000..fc7b2177 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/tcl_dsp.src @@ -0,0 +1,93 @@ +# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=@project_name@ - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "@project_name@ - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_TCL_SUPPORT" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib tcl84.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"Release/libdb_tcl@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" + +!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 2 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DB_TCL_SUPPORT" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /D "_WINDLL" /D "_AFXDLL" /YX"config.h" /FD /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib tcl84g.lib /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"Debug/libdb_tcl@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no + +!ENDIF + +# Begin Target + +# Name "@project_name@ - Win32 Release" +# Name "@project_name@ - Win32 Debug" +@SOURCE_FILES@ +# End Target +# End Project diff --git a/src/libs/resiprocate/contrib/db/build_win32/win_db.h b/src/libs/resiprocate/contrib/db/build_win32/win_db.h new file mode 100644 index 00000000..d623610f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/build_win32/win_db.h @@ -0,0 +1,94 @@ +/*- + * $Id: win_db.in,v 11.4 2004/10/07 13:59:24 carol Exp $ + * + * The following provides the information necessary to build Berkeley + * DB on native Windows, and other Windows environments such as MinGW. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * To build Tcl interface libraries, the include path must be configured to + * use the directory containing , usually the include directory in + * the Tcl distribution. + */ +#ifdef DB_TCL_SUPPORT +#include +#endif + +#define WIN32_LEAN_AND_MEAN +#include + +/* + * All of the necessary includes have been included, ignore the #includes + * in the Berkeley DB source files. + */ +#define NO_SYSTEM_INCLUDES + +/* + * Win32 has getcwd, snprintf and vsnprintf, but under different names. + */ +#define getcwd(buf, size) _getcwd(buf, size) +#define snprintf _snprintf +#define vsnprintf _vsnprintf + +/* + * Win32 does not define getopt and friends in any header file, so we must. + */ +#if defined(__cplusplus) +extern "C" { +#endif +extern int optind; +extern char *optarg; +extern int getopt(int, char * const *, const char *); +#if defined(__cplusplus) +} +#endif + +#ifdef _UNICODE +#define TO_TSTRING(dbenv, s, ts, ret) do { \ + int __len = strlen(s) + 1; \ + ts = NULL; \ + if ((ret = __os_malloc((dbenv), \ + __len * sizeof (_TCHAR), &(ts))) == 0 && \ + MultiByteToWideChar(CP_UTF8, 0, \ + (s), -1, (ts), __len) == 0) \ + ret = __os_get_errno(); \ + } while (0) + +#define FROM_TSTRING(dbenv, ts, s, ret) { \ + int __len = WideCharToMultiByte(CP_UTF8, 0, ts, -1, \ + NULL, 0, NULL, NULL); \ + s = NULL; \ + if ((ret = __os_malloc((dbenv), __len, &(s))) == 0 && \ + WideCharToMultiByte(CP_UTF8, 0, \ + (ts), -1, (s), __len, NULL, NULL) == 0) \ + ret = __os_get_errno(); \ + } while (0) + +#define FREE_STRING(dbenv, s) do { \ + if ((s) != NULL) { \ + __os_free((dbenv), (s)); \ + (s) = NULL; \ + } \ + } while (0) + +#else +#define TO_TSTRING(dbenv, s, ts, ret) (ret) = 0, (ts) = (_TCHAR *)(s) +#define FROM_TSTRING(dbenv, ts, s, ret) (ret) = 0, (s) = (char *)(ts) +#define FREE_STRING(dbenv, ts) +#endif diff --git a/src/libs/resiprocate/contrib/db/clib/getcwd.c b/src/libs/resiprocate/contrib/db/clib/getcwd.c new file mode 100644 index 00000000..4d482225 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/clib/getcwd.c @@ -0,0 +1,261 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1989, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#ifdef HAVE_SYSTEM_INCLUDE_FILES +#if HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +#endif +#endif + +#define ISDOT(dp) \ + (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + +#ifndef dirfd +#define dirfd(dirp) ((dirp)->dd_fd) +#endif + +/* + * getcwd -- + * Get the current working directory. + * + * PUBLIC: #ifndef HAVE_GETCWD + * PUBLIC: char *getcwd __P((char *, size_t)); + * PUBLIC: #endif + */ +char * +getcwd(pt, size) + char *pt; + size_t size; +{ + register struct dirent *dp; + register DIR *dir; + register dev_t dev; + register ino_t ino; + register int first; + register char *bpt, *bup; + struct stat s; + dev_t root_dev; + ino_t root_ino; + size_t ptsize, upsize; + int ret, save_errno; + char *ept, *eup, *up; + + /* + * If no buffer specified by the user, allocate one as necessary. + * If a buffer is specified, the size has to be non-zero. The path + * is built from the end of the buffer backwards. + */ + if (pt) { + ptsize = 0; + if (!size) { + __os_set_errno(EINVAL); + return (NULL); + } + if (size == 1) { + __os_set_errno(ERANGE); + return (NULL); + } + ept = pt + size; + } else { + if ((ret = + __os_malloc(NULL, ptsize = 1024 - 4, &pt)) != 0) { + __os_set_errno(ret); + return (NULL); + } + ept = pt + ptsize; + } + bpt = ept - 1; + *bpt = '\0'; + + /* + * Allocate bytes (1024 - malloc space) for the string of "../"'s. + * Should always be enough (it's 340 levels). If it's not, allocate + * as necessary. Special case the first stat, it's ".", not "..". + */ + if ((ret = __os_malloc(NULL, upsize = 1024 - 4, &up)) != 0) + goto err; + eup = up + 1024; + bup = up; + up[0] = '.'; + up[1] = '\0'; + + /* Save root values, so know when to stop. */ + if (stat("/", &s)) + goto err; + root_dev = s.st_dev; + root_ino = s.st_ino; + + __os_set_errno(0); /* XXX readdir has no error return. */ + + for (first = 1;; first = 0) { + /* Stat the current level. */ + if (lstat(up, &s)) + goto err; + + /* Save current node values. */ + ino = s.st_ino; + dev = s.st_dev; + + /* Check for reaching root. */ + if (root_dev == dev && root_ino == ino) { + *--bpt = PATH_SEPARATOR[0]; + /* + * It's unclear that it's a requirement to copy the + * path to the beginning of the buffer, but it's always + * been that way and stuff would probably break. + */ + bcopy(bpt, pt, ept - bpt); + __os_free(NULL, up); + return (pt); + } + + /* + * Build pointer to the parent directory, allocating memory + * as necessary. Max length is 3 for "../", the largest + * possible component name, plus a trailing NULL. + */ + if (bup + 3 + MAXNAMLEN + 1 >= eup) { + if (__os_realloc(NULL, upsize *= 2, &up) != 0) + goto err; + bup = up; + eup = up + upsize; + } + *bup++ = '.'; + *bup++ = '.'; + *bup = '\0'; + + /* Open and stat parent directory. */ + if (!(dir = opendir(up)) || fstat(dirfd(dir), &s)) + goto err; + + /* Add trailing slash for next directory. */ + *bup++ = PATH_SEPARATOR[0]; + + /* + * If it's a mount point, have to stat each element because + * the inode number in the directory is for the entry in the + * parent directory, not the inode number of the mounted file. + */ + save_errno = 0; + if (s.st_dev == dev) { + for (;;) { + if (!(dp = readdir(dir))) + goto notfound; + if (dp->d_fileno == ino) + break; + } + } else + for (;;) { + if (!(dp = readdir(dir))) + goto notfound; + if (ISDOT(dp)) + continue; + bcopy(dp->d_name, bup, dp->d_namlen + 1); + + /* Save the first error for later. */ + if (lstat(up, &s)) { + if (save_errno == 0) + save_errno = __os_get_errno(); + __os_set_errno(0); + continue; + } + if (s.st_dev == dev && s.st_ino == ino) + break; + } + + /* + * Check for length of the current name, preceding slash, + * leading slash. + */ + if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { + size_t len, off; + + if (!ptsize) { + __os_set_errno(ERANGE); + goto err; + } + off = bpt - pt; + len = ept - bpt; + if (__os_realloc(NULL, ptsize *= 2, &pt) != 0) + goto err; + bpt = pt + off; + ept = pt + ptsize; + bcopy(bpt, ept - len, len); + bpt = ept - len; + } + if (!first) + *--bpt = PATH_SEPARATOR[0]; + bpt -= dp->d_namlen; + bcopy(dp->d_name, bpt, dp->d_namlen); + (void)closedir(dir); + + /* Truncate any file name. */ + *bup = '\0'; + } + +notfound: + /* + * If readdir set errno, use it, not any saved error; otherwise, + * didn't find the current directory in its parent directory, set + * errno to ENOENT. + */ + if (__os_get_errno_ret_zero() == 0) + __os_set_errno(save_errno == 0 ? ENOENT : save_errno); + /* FALLTHROUGH */ +err: + if (ptsize) + __os_free(NULL, pt); + __os_free(NULL, up); + return (NULL); +} diff --git a/src/libs/resiprocate/contrib/db/clib/getopt.c b/src/libs/resiprocate/contrib/db/clib/getopt.c new file mode 100644 index 00000000..6dce03ca --- /dev/null +++ b/src/libs/resiprocate/contrib/db/clib/getopt.c @@ -0,0 +1,145 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +int __db_getopt_reset; /* global reset for VxWorks. */ + +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#undef BADCH +#define BADCH (int)'?' +#undef BADARG +#define BADARG (int)':' +#undef EMSG +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + * + * PUBLIC: #ifndef HAVE_GETOPT + * PUBLIC: int getopt __P((int, char * const *, const char *)); + * PUBLIC: #endif + */ +int +getopt(nargc, nargv, ostr) + int nargc; + char * const *nargv; + const char *ostr; +{ + static char *progname; + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + /* + * VxWorks needs to be able to repeatedly call getopt from multiple + * programs within its global name space. + */ + if (__db_getopt_reset) { + __db_getopt_reset = 0; + + opterr = optind = 1; + optopt = optreset = 0; + optarg = NULL; + progname = NULL; + place = EMSG; + } + if (!progname) { + if ((progname = __db_rpath(*nargv)) == NULL) + progname = *nargv; + else + ++progname; + } + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (EOF); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = EMSG; + return (EOF); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means EOF. + */ + if (optopt == (int)'-') + return (EOF); + if (!*place) + ++optind; + if (opterr && *ostr != ':') + (void)fprintf(stderr, + "%s: illegal option -- %c\n", progname, optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", + progname, optopt); + return (BADCH); + } + else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} diff --git a/src/libs/resiprocate/contrib/db/clib/memcmp.c b/src/libs/resiprocate/contrib/db/clib/memcmp.c new file mode 100644 index 00000000..6b161570 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/clib/memcmp.c @@ -0,0 +1,62 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * memcmp -- + * + * PUBLIC: #ifndef HAVE_MEMCMP + * PUBLIC: int memcmp __P((const void *, const void *, size_t)); + * PUBLIC: #endif + */ +int +memcmp(s1, s2, n) + const void *s1, *s2; + size_t n; +{ + if (n != 0) { + unsigned char *p1 = (unsigned char *)s1, + *p2 = (unsigned char *)s2; + do { + if (*p1++ != *p2++) + return (*--p1 - *--p2); + } while (--n != 0); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/clib/memmove.c b/src/libs/resiprocate/contrib/db/clib/memmove.c new file mode 100644 index 00000000..650f70a8 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/clib/memmove.c @@ -0,0 +1,150 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * sizeof(word) MUST BE A POWER OF TWO + * SO THAT wmask BELOW IS ALL ONES + */ +typedef int word; /* "word" used for optimal copy speed */ + +#undef wsize +#define wsize sizeof(word) +#undef wmask +#define wmask (wsize - 1) + +/* + * Copy a block of memory, handling overlap. + * This is the routine that actually implements + * (the portable versions of) bcopy, memcpy, and memmove. + */ +#ifdef MEMCOPY +/* + * PUBLIC: #ifndef HAVE_MEMCPY + * PUBLIC: void *memcpy __P((void *, const void *, size_t)); + * PUBLIC: #endif + */ +void * +memcpy(dst0, src0, length) +#else +#ifdef MEMMOVE +/* + * PUBLIC: #ifndef HAVE_MEMMOVE + * PUBLIC: void *memmove __P((void *, const void *, size_t)); + * PUBLIC: #endif + */ +void * +memmove(dst0, src0, length) +#else +void +bcopy(src0, dst0, length) +#endif +#endif + void *dst0; + const void *src0; + register size_t length; +{ + register char *dst = dst0; + register const char *src = src0; + register size_t t; + + if (length == 0 || dst == src) /* nothing to do */ + goto done; + + /* + * Macros: loop-t-times; and loop-t-times, t>0 + */ +#undef TLOOP +#define TLOOP(s) if (t) TLOOP1(s) +#undef TLOOP1 +#define TLOOP1(s) do { s; } while (--t) + + if ((unsigned long)dst < (unsigned long)src) { + /* + * Copy forward. + */ + t = (size_t)src; /* only need low bits */ + if ((t | (size_t)dst) & wmask) { + /* + * Try to align operands. This cannot be done + * unless the low bits match. + */ + if ((t ^ (size_t)dst) & wmask || length < wsize) + t = length; + else + t = wsize - (t & wmask); + length -= t; + TLOOP1(*dst++ = *src++); + } + /* + * Copy whole words, then mop up any trailing bytes. + */ + t = length / wsize; + TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); + t = length & wmask; + TLOOP(*dst++ = *src++); + } else { + /* + * Copy backwards. Otherwise essentially the same. + * Alignment works as before, except that it takes + * (t&wmask) bytes to align, not wsize-(t&wmask). + */ + src += length; + dst += length; + t = (size_t)src; + if ((t | (size_t)dst) & wmask) { + if ((t ^ (size_t)dst) & wmask || length <= wsize) + t = length; + else + t &= wmask; + length -= t; + TLOOP1(*--dst = *--src); + } + t = length / wsize; + TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); + t = length & wmask; + TLOOP(*--dst = *--src); + } +done: +#if defined(MEMCOPY) || defined(MEMMOVE) + return (dst0); +#else + return; +#endif +} diff --git a/src/libs/resiprocate/contrib/db/clib/raise.c b/src/libs/resiprocate/contrib/db/clib/raise.c new file mode 100644 index 00000000..74eada16 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/clib/raise.c @@ -0,0 +1,26 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * raise -- + * Send a signal to the current process. + * + * PUBLIC: #ifndef HAVE_RAISE + * PUBLIC: int raise __P((int)); + * PUBLIC: #endif + */ +int +raise(s) + int s; +{ + return (kill(getpid(), s)); +} diff --git a/src/libs/resiprocate/contrib/db/clib/snprintf.c b/src/libs/resiprocate/contrib/db/clib/snprintf.c new file mode 100644 index 00000000..b6fe79b6 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/clib/snprintf.c @@ -0,0 +1,149 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) +static void sprintf_overflow __P((void)); +static int sprintf_retcharpnt __P((void)); +#endif + +/* + * snprintf -- + * Bounded version of sprintf. + * + * PUBLIC: #ifndef HAVE_SNPRINTF + * PUBLIC: int snprintf __P((char *, size_t, const char *, ...)); + * PUBLIC: #endif + */ +#ifndef HAVE_SNPRINTF +int +#ifdef STDC_HEADERS +snprintf(char *str, size_t n, const char *fmt, ...) +#else +snprintf(str, n, fmt, va_alist) + char *str; + size_t n; + const char *fmt; + va_dcl +#endif +{ + static int ret_charpnt = -1; + va_list ap; + size_t len; + + if (ret_charpnt == -1) + ret_charpnt = sprintf_retcharpnt(); + +#ifdef STDC_HEADERS + va_start(ap, fmt); +#else + va_start(ap); +#endif + len = (size_t)vsprintf(str, fmt, ap); + if (ret_charpnt) + len = strlen(str); + + va_end(ap); + + if (len >= n) { + sprintf_overflow(); + /* NOTREACHED */ + } + return ((int)len); +} +#endif + +/* + * vsnprintf -- + * Bounded version of vsprintf. + * + * PUBLIC: #ifndef HAVE_VSNPRINTF + * PUBLIC: int vsnprintf __P((char *, size_t, const char *, va_list)); + * PUBLIC: #endif + */ +#ifndef HAVE_VSNPRINTF +int +vsnprintf(str, n, fmt, ap) + char *str; + size_t n; + const char *fmt; + va_list ap; +{ + static int ret_charpnt = -1; + size_t len; + + if (ret_charpnt == -1) + ret_charpnt = sprintf_retcharpnt(); + + len = (size_t)vsprintf(str, fmt, ap); + if (ret_charpnt) + len = strlen(str); + + if (len >= n) { + sprintf_overflow(); + /* NOTREACHED */ + } + return ((int)len); +} +#endif + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) +static void +sprintf_overflow() +{ + /* + * !!! + * We're potentially manipulating strings handed us by the application, + * and on systems without a real snprintf() the sprintf() calls could + * have overflowed the buffer. We can't do anything about it now, but + * we don't want to return control to the application, we might have + * overwritten the stack with a Trojan horse. We're not trying to do + * anything recoverable here because systems without snprintf support + * are pretty rare anymore. + */ +#define OVERFLOW_ERROR "internal buffer overflow, process ended\n" +#ifndef STDERR_FILENO +#define STDERR_FILENO 2 +#endif + (void)write(STDERR_FILENO, OVERFLOW_ERROR, sizeof(OVERFLOW_ERROR) - 1); + + /* Be polite. */ + exit(1); + + /* But firm. */ + __os_abort(NULL); + + /* NOTREACHED */ +} + +static int +sprintf_retcharpnt() +{ + int ret_charpnt; + char buf[10]; + + /* + * Some old versions of sprintf return a pointer to the first argument + * instead of a character count. Assume the return value of snprintf, + * vsprintf, etc. will be the same as sprintf, and check the easy one. + * + * We do this test at run-time because it's not a test we can do in a + * cross-compilation environment. + */ + + ret_charpnt = + (int)sprintf(buf, "123") != 3 || + (int)sprintf(buf, "123456789") != 9 || + (int)sprintf(buf, "1234") != 4; + + return (ret_charpnt); +} +#endif diff --git a/src/libs/resiprocate/contrib/db/clib/strcasecmp.c b/src/libs/resiprocate/contrib/db/clib/strcasecmp.c new file mode 100644 index 00000000..287895ce --- /dev/null +++ b/src/libs/resiprocate/contrib/db/clib/strcasecmp.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * strcasecmp -- + * Do strcmp(3) in a case-insensitive manner. + * + * PUBLIC: #ifndef HAVE_STRCASECMP + * PUBLIC: int strcasecmp __P((const char *, const char *)); + * PUBLIC: #endif + */ +int +strcasecmp(s1, s2) + const char *s1, *s2; +{ + u_char s1ch, s2ch; + + for (;;) { + s1ch = *s1++; + s2ch = *s2++; + if (s1ch >= 'A' && s1ch <= 'Z') /* tolower() */ + s1ch += 32; + if (s2ch >= 'A' && s2ch <= 'Z') /* tolower() */ + s2ch += 32; + if (s1ch != s2ch) + return (s1ch - s2ch); + if (s1ch == '\0') + return (0); + } + /* NOTREACHED */ +} + +/* + * strncasecmp -- + * Do strncmp(3) in a case-insensitive manner. + * + * PUBLIC: #ifndef HAVE_STRCASECMP + * PUBLIC: int strncasecmp __P((const char *, const char *, size_t)); + * PUBLIC: #endif + */ +int +strncasecmp(s1, s2, n) + const char *s1, *s2; + register size_t n; +{ + u_char s1ch, s2ch; + + for (; n != 0; --n) { + s1ch = *s1++; + s2ch = *s2++; + if (s1ch >= 'A' && s1ch <= 'Z') /* tolower() */ + s1ch += 32; + if (s2ch >= 'A' && s2ch <= 'Z') /* tolower() */ + s2ch += 32; + if (s1ch != s2ch) + return (s1ch - s2ch); + if (s1ch == '\0') + return (0); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/clib/strdup.c b/src/libs/resiprocate/contrib/db/clib/strdup.c new file mode 100644 index 00000000..5863340c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/clib/strdup.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * strdup -- + * + * PUBLIC: #ifndef HAVE_STRDUP + * PUBLIC: char *strdup __P((const char *)); + * PUBLIC: #endif + */ +char * +strdup(str) + const char *str; +{ + size_t len; + char *copy; + + len = strlen(str) + 1; + if (!(copy = malloc((u_int)len))) + return (NULL); + memcpy(copy, str, len); + return (copy); +} diff --git a/src/libs/resiprocate/contrib/db/clib/strerror.c b/src/libs/resiprocate/contrib/db/clib/strerror.c new file mode 100644 index 00000000..1d20a5fe --- /dev/null +++ b/src/libs/resiprocate/contrib/db/clib/strerror.c @@ -0,0 +1,225 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +/* + * Copyright (c) 1982, 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * __FBSDID("FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/errlst.c,v 1.8 2005/04/02 12:33:28 das Exp $"); + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * __db_strerror -- + * Return the string associated with an errno. + * + * PUBLIC: #ifndef HAVE_STRERROR + * PUBLIC: char *strerror __P((int)); + * PUBLIC: #endif + */ +char * +strerror(num) + int num; +{ +#define ERRSTR(v, s) do { \ + if (num == (v)) \ + return (s); \ +} while (0) + ERRSTR(0, "Undefined error: 0"); + ERRSTR(EPERM, "Operation not permitted"); + ERRSTR(ENOENT, "No such file or directory"); + ERRSTR(ESRCH, "No such process"); + ERRSTR(EINTR, "Interrupted system call"); + ERRSTR(EIO, "Input/output error"); + ERRSTR(ENXIO, "Device not configured"); + ERRSTR(E2BIG, "Argument list too long"); + ERRSTR(ENOEXEC, "Exec format error"); + ERRSTR(EBADF, "Bad file descriptor"); + ERRSTR(ECHILD, "No child processes"); + ERRSTR(EDEADLK, "Resource deadlock avoided"); + ERRSTR(ENOMEM, "Cannot allocate memory"); + ERRSTR(EACCES, "Permission denied"); + ERRSTR(EFAULT, "Bad address"); + ERRSTR(ENOTBLK, "Block device required"); + ERRSTR(EBUSY, "Device busy"); + ERRSTR(EEXIST, "File exists"); + ERRSTR(EXDEV, "Cross-device link"); + ERRSTR(ENODEV, "Operation not supported by device"); + ERRSTR(ENOTDIR, "Not a directory"); + ERRSTR(EISDIR, "Is a directory"); + ERRSTR(EINVAL, "Invalid argument"); + ERRSTR(ENFILE, "Too many open files in system"); + ERRSTR(EMFILE, "Too many open files"); + ERRSTR(ENOTTY, "Inappropriate ioctl for device"); + ERRSTR(ETXTBSY, "Text file busy"); + ERRSTR(EFBIG, "File too large"); + ERRSTR(ENOSPC, "No space left on device"); + ERRSTR(ESPIPE, "Illegal seek"); + ERRSTR(EROFS, "Read-only file system"); + ERRSTR(EMLINK, "Too many links"); + ERRSTR(EPIPE, "Broken pipe"); + +/* math software */ + ERRSTR(EDOM, "Numerical argument out of domain"); + ERRSTR(ERANGE, "Result too large"); + +/* non-blocking and interrupt i/o */ + ERRSTR(EAGAIN, "Resource temporarily unavailable"); + ERRSTR(EWOULDBLOCK, "Resource temporarily unavailable"); + ERRSTR(EINPROGRESS, "Operation now in progress"); + ERRSTR(EALREADY, "Operation already in progress"); + +/* ipc/network software -- argument errors */ + ERRSTR(ENOTSOCK, "Socket operation on non-socket"); + ERRSTR(EDESTADDRREQ, "Destination address required"); + ERRSTR(EMSGSIZE, "Message too long"); + ERRSTR(EPROTOTYPE, "Protocol wrong type for socket"); + ERRSTR(ENOPROTOOPT, "Protocol not available"); + ERRSTR(EPROTONOSUPPORT, "Protocol not supported"); + ERRSTR(ESOCKTNOSUPPORT, "Socket type not supported"); + ERRSTR(EOPNOTSUPP, "Operation not supported"); + ERRSTR(EPFNOSUPPORT, "Protocol family not supported"); + ERRSTR(EAFNOSUPPORT, "Address family not supported by protocol family"); + ERRSTR(EADDRINUSE, "Address already in use"); + ERRSTR(EADDRNOTAVAIL, "Can't assign requested address"); + +/* ipc/network software -- operational errors */ + ERRSTR(ENETDOWN, "Network is down"); + ERRSTR(ENETUNREACH, "Network is unreachable"); + ERRSTR(ENETRESET, "Network dropped connection on reset"); + ERRSTR(ECONNABORTED, "Software caused connection abort"); + ERRSTR(ECONNRESET, "Connection reset by peer"); + ERRSTR(ENOBUFS, "No buffer space available"); + ERRSTR(EISCONN, "Socket is already connected"); + ERRSTR(ENOTCONN, "Socket is not connected"); + ERRSTR(ESHUTDOWN, "Can't send after socket shutdown"); + ERRSTR(ETOOMANYREFS, "Too many references: can't splice"); + ERRSTR(ETIMEDOUT, "Operation timed out"); + ERRSTR(ECONNREFUSED, "Connection refused"); + + ERRSTR(ELOOP, "Too many levels of symbolic links"); + ERRSTR(ENAMETOOLONG, "File name too long"); + +/* should be rearranged */ + ERRSTR(EHOSTDOWN, "Host is down"); + ERRSTR(EHOSTUNREACH, "No route to host"); + ERRSTR(ENOTEMPTY, "Directory not empty"); + +/* quotas & mush */ + ERRSTR(EPROCLIM, "Too many processes"); + ERRSTR(EUSERS, "Too many users"); + ERRSTR(EDQUOT, "Disc quota exceeded"); + +/* Network File System */ + ERRSTR(ESTALE, "Stale NFS file handle"); + ERRSTR(EREMOTE, "Too many levels of remote in path"); + ERRSTR(EBADRPC, "RPC struct is bad"); + ERRSTR(ERPCMISMATCH, "RPC version wrong"); + ERRSTR(EPROGUNAVAIL, "RPC prog. not avail"); + ERRSTR(EPROGMISMATCH, "Program version wrong"); + ERRSTR(EPROCUNAVAIL, "Bad procedure for program"); + + ERRSTR(ENOLCK, "No locks available"); + ERRSTR(ENOSYS, "Function not implemented"); + ERRSTR(EFTYPE, "Inappropriate file type or format"); +#ifdef EAUTH + ERRSTR(EAUTH, "Authentication error"); +#endif +#ifdef ENEEDAUTH + ERRSTR(ENEEDAUTH, "Need authenticator"); +#endif + ERRSTR(EIDRM, "Identifier removed"); + ERRSTR(ENOMSG, "No message of desired type"); +#ifdef EOVERFLOW + ERRSTR(EOVERFLOW, "Value too large to be stored in data type"); +#endif + ERRSTR(ECANCELED, "Operation canceled"); + ERRSTR(EILSEQ, "Illegal byte sequence"); +#ifdef ENOATTR + ERRSTR(ENOATTR, "Attribute not found"); +#endif + +/* General */ +#ifdef EDOOFUS + ERRSTR(EDOOFUS, "Programming error"); +#endif + +#ifdef EBADMSG + ERRSTR(EBADMSG, "Bad message"); +#endif +#ifdef EMULTIHOP + ERRSTR(EMULTIHOP, "Multihop attempted"); +#endif +#ifdef ENOLINK + ERRSTR(ENOLINK, "Link has been severed"); +#endif +#ifdef EPROTO + ERRSTR(EPROTO, "Protocol error"); +#endif + + return (__db_unknown_error(num)); +} diff --git a/src/libs/resiprocate/contrib/db/clib/strtol.c b/src/libs/resiprocate/contrib/db/clib/strtol.c new file mode 100644 index 00000000..eb76b8f4 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/clib/strtol.c @@ -0,0 +1,142 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * Convert a string to a long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + * + * PUBLIC: #ifndef HAVE_STRTOL + * PUBLIC: long strtol __P((const char *, char **, int)); + * PUBLIC: #endif + */ +long +strtol(nptr, endptr, base) + const char * nptr; + char ** endptr; + int base; +{ + const char *s; + unsigned long acc; + char c; + unsigned long cutoff; + int neg, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace((unsigned char)c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set 'any' if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX + : LONG_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LONG_MIN : LONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -(long)acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/src/libs/resiprocate/contrib/db/clib/strtoul.c b/src/libs/resiprocate/contrib/db/clib/strtoul.c new file mode 100644 index 00000000..d0495a33 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/clib/strtoul.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * Convert a string to an unsigned long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + * + * PUBLIC: #ifndef HAVE_STRTOUL + * PUBLIC: unsigned long strtoul __P((const char *, char **, int)); + * PUBLIC: #endif + */ +unsigned long +strtoul(nptr, endptr, base) + const char * nptr; + char ** endptr; + int base; +{ + const char *s; + unsigned long acc; + char c; + unsigned long cutoff; + int neg, any, cutlim; + + /* + * See strtol for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace((unsigned char)c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = ULONG_MAX / base; + cutlim = ULONG_MAX % base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/src/libs/resiprocate/contrib/db/common/crypto_stub.c b/src/libs/resiprocate/contrib/db/common/crypto_stub.c new file mode 100644 index 00000000..f062a7e1 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/common/crypto_stub.c @@ -0,0 +1,44 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * __crypto_region_init -- + * Initialize crypto. + * + * + * !!! + * We don't put this stub file in the crypto/ directory of the distribution + * because that entire directory is removed for non-crypto distributions. + * + * PUBLIC: int __crypto_region_init __P((ENV *)); + */ +int +__crypto_region_init(env) + ENV *env; +{ + REGENV *renv; + REGINFO *infop; + int ret; + + infop = env->reginfo; + renv = infop->primary; + MUTEX_LOCK(env, renv->mtx_regenv); + ret = !(renv->cipher_off == INVALID_ROFF); + MUTEX_UNLOCK(env, renv->mtx_regenv); + + if (ret == 0) + return (0); + + __db_errx(env, +"Encrypted environment: library build did not include cryptography support"); + return (DB_OPNOTSUP); +} diff --git a/src/libs/resiprocate/contrib/db/common/db_byteorder.c b/src/libs/resiprocate/contrib/db/common/db_byteorder.c new file mode 100644 index 00000000..f162dbe9 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/common/db_byteorder.c @@ -0,0 +1,63 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * __db_isbigendian -- + * Return 1 if big-endian (Motorola and Sparc), not little-endian + * (Intel and Vax). We do this work at run-time, rather than at + * configuration time so cross-compilation and general embedded + * system support is simpler. + * + * PUBLIC: int __db_isbigendian __P((void)); + */ +int +__db_isbigendian() +{ + union { /* From Harbison & Steele. */ + long l; + char c[sizeof(long)]; + } u; + + u.l = 1; + return (u.c[sizeof(long) - 1] == 1); +} + +/* + * __db_byteorder -- + * Return if we need to do byte swapping, checking for illegal + * values. + * + * PUBLIC: int __db_byteorder __P((ENV *, int)); + */ +int +__db_byteorder(env, lorder) + ENV *env; + int lorder; +{ + switch (lorder) { + case 0: + break; + case 1234: + if (!F_ISSET(env, ENV_LITTLEENDIAN)) + return (DB_SWAPBYTES); + break; + case 4321: + if (F_ISSET(env, ENV_LITTLEENDIAN)) + return (DB_SWAPBYTES); + break; + default: + __db_errx(env, + "unsupported byte order, only big and little-endian supported"); + return (EINVAL); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/common/db_err.c b/src/libs/resiprocate/contrib/db/common/db_err.c new file mode 100644 index 00000000..8d74bce9 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/common/db_err.c @@ -0,0 +1,1040 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/txn.h" + +static void __db_msgcall __P((const DB_ENV *, const char *, va_list)); +static void __db_msgfile __P((const DB_ENV *, const char *, va_list)); + +/* + * __db_fchk -- + * General flags checking routine. + * + * PUBLIC: int __db_fchk __P((ENV *, const char *, u_int32_t, u_int32_t)); + */ +int +__db_fchk(env, name, flags, ok_flags) + ENV *env; + const char *name; + u_int32_t flags, ok_flags; +{ + return (LF_ISSET(~ok_flags) ? __db_ferr(env, name, 0) : 0); +} + +/* + * __db_fcchk -- + * General combination flags checking routine. + * + * PUBLIC: int __db_fcchk + * PUBLIC: __P((ENV *, const char *, u_int32_t, u_int32_t, u_int32_t)); + */ +int +__db_fcchk(env, name, flags, flag1, flag2) + ENV *env; + const char *name; + u_int32_t flags, flag1, flag2; +{ + return (LF_ISSET(flag1) && + LF_ISSET(flag2) ? __db_ferr(env, name, 1) : 0); +} + +/* + * __db_ferr -- + * Common flag errors. + * + * PUBLIC: int __db_ferr __P((const ENV *, const char *, int)); + */ +int +__db_ferr(env, name, iscombo) + const ENV *env; + const char *name; + int iscombo; +{ + __db_errx(env, "illegal flag %sspecified to %s", + iscombo ? "combination " : "", name); + return (EINVAL); +} + +/* + * __db_fnl -- + * Common flag-needs-locking message. + * + * PUBLIC: int __db_fnl __P((const ENV *, const char *)); + */ +int +__db_fnl(env, name) + const ENV *env; + const char *name; +{ + __db_errx(env, + "%s: DB_READ_COMMITTED, DB_READ_UNCOMMITTED and DB_RMW require locking", + name); + return (EINVAL); +} + +/* + * __db_pgerr -- + * Error when unable to retrieve a specified page. + * + * PUBLIC: int __db_pgerr __P((DB *, db_pgno_t, int)); + */ +int +__db_pgerr(dbp, pgno, errval) + DB *dbp; + db_pgno_t pgno; + int errval; +{ + /* + * Three things are certain: + * Death, taxes, and lost data. + * Guess which has occurred. + */ + __db_errx(dbp->env, + "unable to create/retrieve page %lu", (u_long)pgno); + return (__env_panic(dbp->env, errval)); +} + +/* + * __db_pgfmt -- + * Error when a page has the wrong format. + * + * PUBLIC: int __db_pgfmt __P((ENV *, db_pgno_t)); + */ +int +__db_pgfmt(env, pgno) + ENV *env; + db_pgno_t pgno; +{ + __db_errx(env, "page %lu: illegal page type or format", (u_long)pgno); + return (__env_panic(env, EINVAL)); +} + +#ifdef DIAGNOSTIC +/* + * __db_assert -- + * Error when an assertion fails. Only checked if #DIAGNOSTIC defined. + * + * PUBLIC: #ifdef DIAGNOSTIC + * PUBLIC: void __db_assert __P((ENV *, const char *, const char *, int)); + * PUBLIC: #endif + */ +void +__db_assert(env, e, file, line) + ENV *env; + const char *e, *file; + int line; +{ + __db_errx(env, "assert failure: %s/%d: \"%s\"", file, line, e); + + __os_abort(env); + /* NOTREACHED */ +} +#endif + +/* + * __env_panic_msg -- + * Just report that someone else paniced. + * + * PUBLIC: int __env_panic_msg __P((ENV *)); + */ +int +__env_panic_msg(env) + ENV *env; +{ + DB_ENV *dbenv; + int ret; + + dbenv = env->dbenv; + + ret = DB_RUNRECOVERY; + + __db_errx(env, "PANIC: fatal region error detected; run recovery"); + + if (dbenv->db_paniccall != NULL) /* Deprecated */ + dbenv->db_paniccall(dbenv, ret); + + /* Must check for DB_EVENT_REG_PANIC panic first because it is never + * set by itself. If set, it means panic came from DB_REGISTER code + * only, otherwise it could be from many possible places in the code. + */ + if ((env->reginfo != NULL) && + (((REGENV *)env->reginfo->primary)->reg_panic)) + DB_EVENT(env, DB_EVENT_REG_PANIC, &ret); + else + DB_EVENT(env, DB_EVENT_PANIC, &ret); + + return (ret); +} + +/* + * __env_panic -- + * Lock out the database environment due to unrecoverable error. + * + * PUBLIC: int __env_panic __P((ENV *, int)); + */ +int +__env_panic(env, errval) + ENV *env; + int errval; +{ + DB_ENV *dbenv; + + dbenv = env->dbenv; + + if (env != NULL) { + __env_panic_set(env, 1); + + __db_err(env, errval, "PANIC"); + + if (dbenv->db_paniccall != NULL) /* Deprecated */ + dbenv->db_paniccall(dbenv, errval); + + /* Must check for DB_EVENT_REG_PANIC first because it is never + * set by itself. If set, it means panic came from DB_REGISTER + * code only, otherwise it could be from many possible places + * in the code. + */ + if ((env->reginfo != NULL) && + (((REGENV *)env->reginfo->primary)->reg_panic)) + DB_EVENT(env, DB_EVENT_REG_PANIC, &errval); + else + DB_EVENT(env, DB_EVENT_PANIC, &errval); + } + +#if defined(DIAGNOSTIC) && !defined(CONFIG_TEST) + /* + * We want a stack trace of how this could possibly happen. + * + * Don't drop core if it's the test suite -- it's reasonable for the + * test suite to check to make sure that DB_RUNRECOVERY is returned + * under certain conditions. + */ + __os_abort(env); + /* NOTREACHED */ +#endif + + /* + * Chaos reigns within. + * Reflect, repent, and reboot. + * Order shall return. + */ + return (DB_RUNRECOVERY); +} + +/* + * db_strerror -- + * ANSI C strerror(3) for DB. + * + * EXTERN: char *db_strerror __P((int)); + */ +char * +db_strerror(error) + int error; +{ + char *p; + + if (error == 0) + return ("Successful return: 0"); + if (error > 0) { + if ((p = strerror(error)) != NULL) + return (p); + return (__db_unknown_error(error)); + } + + /* + * !!! + * The Tcl API requires that some of these return strings be compared + * against strings stored in application scripts. So, any of these + * errors that do not invariably result in a Tcl exception may not be + * altered. + */ + switch (error) { + case DB_BUFFER_SMALL: + return + ("DB_BUFFER_SMALL: User memory too small for return value"); + case DB_DONOTINDEX: + return ("DB_DONOTINDEX: Secondary index callback returns null"); + case DB_FOREIGN_CONFLICT: + return + ("DB_FOREIGN_CONFLICT: A foreign database constraint has been violated"); + case DB_KEYEMPTY: + return ("DB_KEYEMPTY: Non-existent key/data pair"); + case DB_KEYEXIST: + return ("DB_KEYEXIST: Key/data pair already exists"); + case DB_LOCK_DEADLOCK: + return + ("DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock"); + case DB_LOCK_NOTGRANTED: + return ("DB_LOCK_NOTGRANTED: Lock not granted"); + case DB_LOG_BUFFER_FULL: + return ("DB_LOG_BUFFER_FULL: In-memory log buffer is full"); + case DB_NOSERVER: + return ("DB_NOSERVER: Fatal error, no RPC server"); + case DB_NOSERVER_HOME: + return ("DB_NOSERVER_HOME: Home unrecognized at server"); + case DB_NOSERVER_ID: + return ("DB_NOSERVER_ID: Identifier unrecognized at server"); + case DB_NOTFOUND: + return ("DB_NOTFOUND: No matching key/data pair found"); + case DB_OLD_VERSION: + return ("DB_OLDVERSION: Database requires a version upgrade"); + case DB_PAGE_NOTFOUND: + return ("DB_PAGE_NOTFOUND: Requested page not found"); + case DB_REP_DUPMASTER: + return ("DB_REP_DUPMASTER: A second master site appeared"); + case DB_REP_HANDLE_DEAD: + return ("DB_REP_HANDLE_DEAD: Handle is no longer valid"); + case DB_REP_HOLDELECTION: + return ("DB_REP_HOLDELECTION: Need to hold an election"); + case DB_REP_IGNORE: + return ("DB_REP_IGNORE: Replication record/operation ignored"); + case DB_REP_ISPERM: + return ("DB_REP_ISPERM: Permanent record written"); + case DB_REP_JOIN_FAILURE: + return + ("DB_REP_JOIN_FAILURE: Unable to join replication group"); + case DB_REP_LEASE_EXPIRED: + return + ("DB_REP_LEASE_EXPIRED: Replication leases have expired"); + case DB_REP_LOCKOUT: + return + ("DB_REP_LOCKOUT: Waiting for replication recovery to complete"); + case DB_REP_NEWSITE: + return ("DB_REP_NEWSITE: A new site has entered the system"); + case DB_REP_NOTPERM: + return ("DB_REP_NOTPERM: Permanent log record not written"); + case DB_REP_UNAVAIL: + return ("DB_REP_UNAVAIL: Unable to elect a master"); + case DB_RUNRECOVERY: + return ("DB_RUNRECOVERY: Fatal error, run database recovery"); + case DB_SECONDARY_BAD: + return + ("DB_SECONDARY_BAD: Secondary index inconsistent with primary"); + case DB_VERIFY_BAD: + return ("DB_VERIFY_BAD: Database verification failed"); + case DB_VERSION_MISMATCH: + return + ("DB_VERSION_MISMATCH: Database environment version mismatch"); + default: + break; + } + + return (__db_unknown_error(error)); +} + +/* + * __db_unknown_error -- + * Format an unknown error value into a static buffer. + * + * PUBLIC: char *__db_unknown_error __P((int)); + */ +char * +__db_unknown_error(error) + int error; +{ + /* + * !!! + * Room for a 64-bit number + slop. This buffer is only used + * if we're given an unknown error number, which should never + * happen. + * + * We're no longer thread-safe if it does happen, but the worst + * result is a corrupted error string because there will always + * be a trailing nul byte since the error buffer is nul filled + * and longer than any error message. + */ + (void)snprintf(DB_GLOBAL(error_buf), + sizeof(DB_GLOBAL(error_buf)), "Unknown error: %d", error); + return (DB_GLOBAL(error_buf)); +} + +/* + * __db_syserr -- + * Standard error routine. + * + * PUBLIC: void __db_syserr __P((const ENV *, int, const char *, ...)) + * PUBLIC: __attribute__ ((__format__ (__printf__, 3, 4))); + */ +void +#ifdef STDC_HEADERS +__db_syserr(const ENV *env, int error, const char *fmt, ...) +#else +__db_syserr(env, error, fmt, va_alist) + const ENV *env; + int error; + const char *fmt; + va_dcl +#endif +{ + DB_ENV *dbenv; + + dbenv = env == NULL ? NULL : env->dbenv; + + /* + * The same as DB->err, except we don't default to writing to stderr + * after any output channel has been configured, and we use a system- + * specific function to translate errors to strings. + */ + DB_REAL_ERR(dbenv, error, DB_ERROR_SYSTEM, 0, fmt); +} + +/* + * __db_err -- + * Standard error routine. + * + * PUBLIC: void __db_err __P((const ENV *, int, const char *, ...)) + * PUBLIC: __attribute__ ((__format__ (__printf__, 3, 4))); + */ +void +#ifdef STDC_HEADERS +__db_err(const ENV *env, int error, const char *fmt, ...) +#else +__db_err(env, error, fmt, va_alist) + const ENV *env; + int error; + const char *fmt; + va_dcl +#endif +{ + DB_ENV *dbenv; + + dbenv = env == NULL ? NULL : env->dbenv; + + /* + * The same as DB->err, except we don't default to writing to stderr + * once an output channel has been configured. + */ + DB_REAL_ERR(dbenv, error, DB_ERROR_SET, 0, fmt); +} + +/* + * __db_errx -- + * Standard error routine. + * + * PUBLIC: void __db_errx __P((const ENV *, const char *, ...)) + * PUBLIC: __attribute__ ((__format__ (__printf__, 2, 3))); + */ +void +#ifdef STDC_HEADERS +__db_errx(const ENV *env, const char *fmt, ...) +#else +__db_errx(env, fmt, va_alist) + const ENV *env; + const char *fmt; + va_dcl +#endif +{ + DB_ENV *dbenv; + + dbenv = env == NULL ? NULL : env->dbenv; + + /* + * The same as DB->errx, except we don't default to writing to stderr + * once an output channel has been configured. + */ + DB_REAL_ERR(dbenv, 0, DB_ERROR_NOT_SET, 0, fmt); +} + +/* + * __db_errcall -- + * Do the error message work for callback functions. + * + * PUBLIC: void __db_errcall + * PUBLIC: __P((const DB_ENV *, int, db_error_set_t, const char *, va_list)); + */ +void +__db_errcall(dbenv, error, error_set, fmt, ap) + const DB_ENV *dbenv; + int error; + db_error_set_t error_set; + const char *fmt; + va_list ap; +{ + char *p; + char buf[2048]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ + char sysbuf[1024]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ + + p = buf; + if (fmt != NULL) + p += vsnprintf(buf, sizeof(buf), fmt, ap); + if (error_set != DB_ERROR_NOT_SET) + p += snprintf(p, + sizeof(buf) - (size_t)(p - buf), ": %s", + error_set == DB_ERROR_SET ? db_strerror(error) : + __os_strerror(error, sysbuf, sizeof(sysbuf))); + + dbenv->db_errcall(dbenv, dbenv->db_errpfx, buf); +} + +/* + * __db_errfile -- + * Do the error message work for FILE *s. + * + * PUBLIC: void __db_errfile + * PUBLIC: __P((const DB_ENV *, int, db_error_set_t, const char *, va_list)); + */ +void +__db_errfile(dbenv, error, error_set, fmt, ap) + const DB_ENV *dbenv; + int error; + db_error_set_t error_set; + const char *fmt; + va_list ap; +{ + FILE *fp; + int need_sep; + char sysbuf[1024]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ + + fp = dbenv == NULL || + dbenv->db_errfile == NULL ? stderr : dbenv->db_errfile; + need_sep = 0; + + if (dbenv != NULL && dbenv->db_errpfx != NULL) { + (void)fprintf(fp, "%s", dbenv->db_errpfx); + need_sep = 1; + } + if (fmt != NULL && fmt[0] != '\0') { + if (need_sep) + (void)fprintf(fp, ": "); + need_sep = 1; + (void)vfprintf(fp, fmt, ap); + } + if (error_set != DB_ERROR_NOT_SET) + (void)fprintf(fp, "%s%s", + need_sep ? ": " : "", + error_set == DB_ERROR_SET ? db_strerror(error) : + __os_strerror(error, sysbuf, sizeof(sysbuf))); + (void)fprintf(fp, "\n"); + (void)fflush(fp); +} + +/* + * __db_msgadd -- + * Aggregate a set of strings into a buffer for the callback API. + * + * PUBLIC: void __db_msgadd __P((ENV *, DB_MSGBUF *, const char *, ...)) + * PUBLIC: __attribute__ ((__format__ (__printf__, 3, 4))); + */ +void +#ifdef STDC_HEADERS +__db_msgadd(ENV *env, DB_MSGBUF *mbp, const char *fmt, ...) +#else +__db_msgadd(env, mbp, fmt, va_alist) + ENV *env; + DB_MSGBUF *mbp; + const char *fmt; + va_dcl +#endif +{ + va_list ap; + +#ifdef STDC_HEADERS + va_start(ap, fmt); +#else + va_start(ap); +#endif + __db_msgadd_ap(env, mbp, fmt, ap); + va_end(ap); +} + +/* + * __db_msgadd_ap -- + * Aggregate a set of strings into a buffer for the callback API. + * + * PUBLIC: void __db_msgadd_ap + * PUBLIC: __P((ENV *, DB_MSGBUF *, const char *, va_list)); + */ +void +__db_msgadd_ap(env, mbp, fmt, ap) + ENV *env; + DB_MSGBUF *mbp; + const char *fmt; + va_list ap; +{ + size_t len, olen; + char buf[2048]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ + + len = (size_t)vsnprintf(buf, sizeof(buf), fmt, ap); + + /* + * There's a heap buffer in the ENV handle we use to aggregate the + * message chunks. We maintain a pointer to the buffer, the next slot + * to be filled in in the buffer, and a total buffer length. + */ + olen = (size_t)(mbp->cur - mbp->buf); + if (olen + len >= mbp->len) { + if (__os_realloc(env, mbp->len + len + 256, &mbp->buf)) + return; + mbp->len += (len + 256); + mbp->cur = mbp->buf + olen; + } + + memcpy(mbp->cur, buf, len + 1); + mbp->cur += len; +} + +/* + * __db_msg -- + * Standard DB stat message routine. + * + * PUBLIC: void __db_msg __P((const ENV *, const char *, ...)) + * PUBLIC: __attribute__ ((__format__ (__printf__, 2, 3))); + */ +void +#ifdef STDC_HEADERS +__db_msg(const ENV *env, const char *fmt, ...) +#else +__db_msg(env, fmt, va_alist) + const ENV *env; + const char *fmt; + va_dcl +#endif +{ + DB_ENV *dbenv; + + dbenv = env == NULL ? NULL : env->dbenv; + + DB_REAL_MSG(dbenv, fmt); +} + +/* + * __db_msgcall -- + * Do the message work for callback functions. + */ +static void +__db_msgcall(dbenv, fmt, ap) + const DB_ENV *dbenv; + const char *fmt; + va_list ap; +{ + char buf[2048]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ + + (void)vsnprintf(buf, sizeof(buf), fmt, ap); + + dbenv->db_msgcall(dbenv, buf); +} + +/* + * __db_msgfile -- + * Do the message work for FILE *s. + */ +static void +__db_msgfile(dbenv, fmt, ap) + const DB_ENV *dbenv; + const char *fmt; + va_list ap; +{ + FILE *fp; + + fp = dbenv == NULL || + dbenv->db_msgfile == NULL ? stdout : dbenv->db_msgfile; + (void)vfprintf(fp, fmt, ap); + + (void)fprintf(fp, "\n"); + (void)fflush(fp); +} + +/* + * __db_unknown_flag -- report internal error + * + * PUBLIC: int __db_unknown_flag __P((ENV *, char *, u_int32_t)); + */ +int +__db_unknown_flag(env, routine, flag) + ENV *env; + char *routine; + u_int32_t flag; +{ + __db_errx(env, "%s: Unknown flag: %#x", routine, (u_int)flag); + +#ifdef DIAGNOSTIC + __os_abort(env); + /* NOTREACHED */ +#endif + return (EINVAL); +} + +/* + * __db_unknown_type -- report internal database type error + * + * PUBLIC: int __db_unknown_type __P((ENV *, char *, DBTYPE)); + */ +int +__db_unknown_type(env, routine, type) + ENV *env; + char *routine; + DBTYPE type; +{ + __db_errx(env, + "%s: Unexpected database type: %s", + routine, __db_dbtype_to_string(type)); + +#ifdef DIAGNOSTIC + __os_abort(env); + /* NOTREACHED */ +#endif + return (EINVAL); +} + +/* + * __db_unknown_path -- report unexpected database code path error. + * + * PUBLIC: int __db_unknown_path __P((ENV *, char *)); + */ +int +__db_unknown_path(env, routine) + ENV *env; + char *routine; +{ + __db_errx(env, "%s: Unexpected code path error", routine); + +#ifdef DIAGNOSTIC + __os_abort(env); + /* NOTREACHED */ +#endif + return (EINVAL); +} + +/* + * __db_check_txn -- + * Check for common transaction errors. + * + * PUBLIC: int __db_check_txn __P((DB *, DB_TXN *, DB_LOCKER *, int)); + */ +int +__db_check_txn(dbp, txn, assoc_locker, read_op) + DB *dbp; + DB_TXN *txn; + DB_LOCKER *assoc_locker; + int read_op; +{ + ENV *env; + int isp, ret; + + env = dbp->env; + + /* + * If we are in recovery or aborting a transaction, then we + * don't need to enforce the rules about dbp's not allowing + * transactional operations in non-transactional dbps and + * vica-versa. This happens all the time as the dbp during + * an abort may be transactional, but we undo operations + * outside a transaction since we're aborting. + */ + if (IS_RECOVERING(env) || F_ISSET(dbp, DB_AM_RECOVER)) + return (0); + + /* + * Check for common transaction errors: + * an operation on a handle whose open commit hasn't completed. + * a transaction handle in a non-transactional environment + * a transaction handle for a non-transactional database + */ + if (txn == NULL || F_ISSET(txn, TXN_PRIVATE)) { + if (dbp->cur_locker != NULL && + dbp->cur_locker->id >= TXN_MINIMUM) + goto open_err; + + if (!read_op && F_ISSET(dbp, DB_AM_TXN)) { + __db_errx(env, + "Transaction not specified for a transactional database"); + return (EINVAL); + } + } else if (F_ISSET(txn, TXN_CDSGROUP)) { + if (!CDB_LOCKING(env)) { + __db_errx(env, + "CDS groups can only be used in a CDS environment"); + return (EINVAL); + } + /* + * CDS group handles can be passed to any method, since they + * only determine locker IDs. + */ + return (0); + } else { + if (!TXN_ON(env)) + return (__db_not_txn_env(env)); + + if (!F_ISSET(dbp, DB_AM_TXN)) { + __db_errx(env, + "Transaction specified for a non-transactional database"); + return (EINVAL); + } + + if (F_ISSET(txn, TXN_DEADLOCK)) + return (__db_txn_deadlock_err(env, txn)); + if (dbp->cur_locker != NULL && + dbp->cur_locker->id >= TXN_MINIMUM && + dbp->cur_locker->id != txn->txnid) { + if ((ret = __lock_locker_is_parent(env, + dbp->cur_locker, txn->locker, &isp)) != 0) + return (ret); + if (!isp) + goto open_err; + } + } + + /* + * If dbp->associate_locker is not NULL, that means we're in + * the middle of a DB->associate with DB_CREATE (i.e., a secondary index + * creation). + * + * In addition to the usual transaction rules, we need to lock out + * non-transactional updates that aren't part of the associate (and + * thus are using some other locker ID). + * + * Transactional updates should simply block; from the time we + * decide to build the secondary until commit, we'll hold a write + * lock on all of its pages, so it should be safe to attempt to update + * the secondary in another transaction (presumably by updating the + * primary). + */ + if (!read_op && dbp->associate_locker != NULL && + txn != NULL && dbp->associate_locker != assoc_locker) { + __db_errx(env, + "Operation forbidden while secondary index is being created"); + return (EINVAL); + } + + /* + * Check the txn and dbp are from the same env. + */ + if (txn != NULL && env != txn->mgrp->env) { + __db_errx(env, + "Transaction and database from different environments"); + return (EINVAL); + } + + return (0); +open_err: + __db_errx(env, + "Transaction that opened the DB handle is still active"); + return (EINVAL); +} + +/* + * __db_txn_deadlock_err -- + * Transaction has allready been deadlocked. + * + * PUBLIC: int __db_txn_deadlock_err __P((ENV *, DB_TXN *)); + */ +int +__db_txn_deadlock_err(env, txn) + ENV *env; + DB_TXN *txn; +{ + const char *name; + + name = NULL; + (void)__txn_get_name(txn, &name); + + __db_errx(env, + "%s%sprevious transaction deadlock return not resolved", + name == NULL ? "" : name, name == NULL ? "" : ": "); + + return (EINVAL); +} + +/* + * __db_not_txn_env -- + * DB handle must be in an environment that supports transactions. + * + * PUBLIC: int __db_not_txn_env __P((ENV *)); + */ +int +__db_not_txn_env(env) + ENV *env; +{ + __db_errx(env, "DB environment not configured for transactions"); + return (EINVAL); +} + +/* + * __db_rec_toobig -- + * Fixed record length exceeded error message. + * + * PUBLIC: int __db_rec_toobig __P((ENV *, u_int32_t, u_int32_t)); + */ +int +__db_rec_toobig(env, data_len, fixed_rec_len) + ENV *env; + u_int32_t data_len, fixed_rec_len; +{ + __db_errx(env, + "%lu larger than database's maximum record length %lu", + (u_long)data_len, (u_long)fixed_rec_len); + return (EINVAL); +} + +/* + * __db_rec_repl -- + * Fixed record replacement length error message. + * + * PUBLIC: int __db_rec_repl __P((ENV *, u_int32_t, u_int32_t)); + */ +int +__db_rec_repl(env, data_size, data_dlen) + ENV *env; + u_int32_t data_size, data_dlen; +{ + __db_errx(env, + "%s: replacement length %lu differs from replaced length %lu", + "Record length error", (u_long)data_size, (u_long)data_dlen); + return (EINVAL); +} + +#if defined(DIAGNOSTIC) || defined(DEBUG_ROP) || defined(DEBUG_WOP) +/* + * __dbc_logging -- + * In DIAGNOSTIC mode, check for bad replication combinations. + * + * PUBLIC: int __dbc_logging __P((DBC *)); + */ +int +__dbc_logging(dbc) + DBC *dbc; +{ + DB_REP *db_rep; + ENV *env; + int ret; + + env = dbc->env; + db_rep = env->rep_handle; + + ret = LOGGING_ON(env) && + !F_ISSET(dbc, DBC_RECOVER) && !IS_REP_CLIENT(env); + + /* + * If we're not using replication or running recovery, return. + */ + if (db_rep == NULL || F_ISSET(dbc, DBC_RECOVER)) + return (ret); + +#ifndef DEBUG_ROP + /* + * Only check when DEBUG_ROP is not configured. People often do + * non-transactional reads, and debug_rop is going to write + * a log record. + */ + { + REP *rep; + + rep = db_rep->region; + + /* + * If we're a client and not running recovery or non durably, error. + */ + if (IS_REP_CLIENT(env) && !F_ISSET(dbc->dbp, DB_AM_NOT_DURABLE)) { + __db_errx(env, "dbc_logging: Client update"); + goto err; + } + +#ifndef DEBUG_WOP + /* + * If DEBUG_WOP is enabled, then we'll generate debugging log records + * that are non-transactional. This is OK. + */ + if (IS_REP_MASTER(env) && + dbc->txn == NULL && !F_ISSET(dbc->dbp, DB_AM_NOT_DURABLE)) { + __db_errx(env, "Dbc_logging: Master non-txn update"); + goto err; + } +#endif + + if (0) { +err: __db_errx(env, "Rep: flags 0x%lx msg_th %lu", + (u_long)rep->flags, (u_long)rep->msg_th); + __db_errx(env, "Rep: handle %lu, opcnt %lu", + (u_long)rep->handle_cnt, (u_long)rep->op_cnt); + __os_abort(env); + /* NOTREACHED */ + } + } +#endif + return (ret); +} +#endif + +/* + * __db_check_lsn -- + * Display the log sequence error message. + * + * PUBLIC: int __db_check_lsn __P((ENV *, DB_LSN *, DB_LSN *)); + */ +int +__db_check_lsn(env, lsn, prev) + ENV *env; + DB_LSN *lsn, *prev; +{ + __db_errx(env, + "Log sequence error: page LSN %lu %lu; previous LSN %lu %lu", + (u_long)(lsn)->file, (u_long)(lsn)->offset, + (u_long)(prev)->file, (u_long)(prev)->offset); + return (EINVAL); +} + +/* + * __db_rdonly -- + * Common readonly message. + * PUBLIC: int __db_rdonly __P((const ENV *, const char *)); + */ +int +__db_rdonly(env, name) + const ENV *env; + const char *name; +{ + __db_errx(env, "%s: attempt to modify a read-only database", name); + return (EACCES); +} + +/* + * __db_space_err -- + * Common out of space message. + * PUBLIC: int __db_space_err __P((const DB *)); + */ +int +__db_space_err(dbp) + const DB *dbp; +{ + __db_errx(dbp->env, + "%s: file limited to %lu pages", + dbp->fname, (u_long)dbp->mpf->mfp->maxpgno); + return (ENOSPC); +} + +/* + * __db_failed -- + * Common failed thread message. + * + * PUBLIC: int __db_failed __P((const ENV *, + * PUBLIC: const char *, pid_t, db_threadid_t)); + */ +int +__db_failed(env, msg, pid, tid) + const ENV *env; + const char *msg; + pid_t pid; + db_threadid_t tid; +{ + DB_ENV *dbenv; + char buf[DB_THREADID_STRLEN]; + + dbenv = env->dbenv; + + __db_errx(env, "Thread/process %s failed: %s", + dbenv->thread_id_string(dbenv, pid, tid, buf), msg); + return (DB_RUNRECOVERY); +} diff --git a/src/libs/resiprocate/contrib/db/common/db_getlong.c b/src/libs/resiprocate/contrib/db/common/db_getlong.c new file mode 100644 index 00000000..5549141e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/common/db_getlong.c @@ -0,0 +1,137 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * __db_getlong -- + * Return a long value inside of basic parameters. + * + * PUBLIC: int __db_getlong + * PUBLIC: __P((DB_ENV *, const char *, char *, long, long, long *)); + */ +int +__db_getlong(dbenv, progname, p, min, max, storep) + DB_ENV *dbenv; + const char *progname; + char *p; + long min, max, *storep; +{ + long val; + char *end; + + __os_set_errno(0); + val = strtol(p, &end, 10); + if ((val == LONG_MIN || val == LONG_MAX) && + __os_get_errno() == ERANGE) { + if (dbenv == NULL) + fprintf(stderr, + "%s: %s: %s\n", progname, p, strerror(ERANGE)); + else + dbenv->err(dbenv, ERANGE, "%s", p); + return (ERANGE); + } + if (p[0] == '\0' || (end[0] != '\0' && end[0] != '\n')) { + if (dbenv == NULL) + fprintf(stderr, + "%s: %s: Invalid numeric argument\n", progname, p); + else + dbenv->errx(dbenv, "%s: Invalid numeric argument", p); + return (EINVAL); + } + if (val < min) { + if (dbenv == NULL) + fprintf(stderr, + "%s: %s: Less than minimum value (%ld)\n", + progname, p, min); + else + dbenv->errx(dbenv, + "%s: Less than minimum value (%ld)", p, min); + return (ERANGE); + } + if (val > max) { + if (dbenv == NULL) + fprintf(stderr, + "%s: %s: Greater than maximum value (%ld)\n", + progname, p, max); + else + dbenv->errx(dbenv, + "%s: Greater than maximum value (%ld)", p, max); + return (ERANGE); + } + *storep = val; + return (0); +} + +/* + * __db_getulong -- + * Return an unsigned long value inside of basic parameters. + * + * PUBLIC: int __db_getulong + * PUBLIC: __P((DB_ENV *, const char *, char *, u_long, u_long, u_long *)); + */ +int +__db_getulong(dbenv, progname, p, min, max, storep) + DB_ENV *dbenv; + const char *progname; + char *p; + u_long min, max, *storep; +{ + u_long val; + char *end; + + __os_set_errno(0); + val = strtoul(p, &end, 10); + if (val == ULONG_MAX && __os_get_errno() == ERANGE) { + if (dbenv == NULL) + fprintf(stderr, + "%s: %s: %s\n", progname, p, strerror(ERANGE)); + else + dbenv->err(dbenv, ERANGE, "%s", p); + return (ERANGE); + } + if (p[0] == '\0' || (end[0] != '\0' && end[0] != '\n')) { + if (dbenv == NULL) + fprintf(stderr, + "%s: %s: Invalid numeric argument\n", progname, p); + else + dbenv->errx(dbenv, "%s: Invalid numeric argument", p); + return (EINVAL); + } + if (val < min) { + if (dbenv == NULL) + fprintf(stderr, + "%s: %s: Less than minimum value (%lu)\n", + progname, p, min); + else + dbenv->errx(dbenv, + "%s: Less than minimum value (%lu)", p, min); + return (ERANGE); + } + + /* + * We allow a 0 to substitute as a max value for ULONG_MAX because + * 1) accepting only a 0 value is unlikely to be necessary, and 2) + * we don't want callers to have to use ULONG_MAX explicitly, as it + * may not exist on all platforms. + */ + if (max != 0 && val > max) { + if (dbenv == NULL) + fprintf(stderr, + "%s: %s: Greater than maximum value (%lu)\n", + progname, p, max); + else + dbenv->errx(dbenv, + "%s: Greater than maximum value (%lu)", p, max); + return (ERANGE); + } + *storep = val; + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/common/db_idspace.c b/src/libs/resiprocate/contrib/db/common/db_idspace.c new file mode 100644 index 00000000..8bae7594 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/common/db_idspace.c @@ -0,0 +1,85 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2001-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +static int __db_idcmp __P((const void *, const void *)); + +static int +__db_idcmp(a, b) + const void *a; + const void *b; +{ + u_int32_t i, j; + + i = *(u_int32_t *)a; + j = *(u_int32_t *)b; + + if (i < j) + return (-1); + else if (i > j) + return (1); + else + return (0); +} + +/* + * __db_idspace -- + * + * On input, minp and maxp contain the minimum and maximum valid values for + * the name space and on return, they contain the minimum and maximum ids + * available (by finding the biggest gap). The minimum can be an inuse + * value, but the maximum cannot be. + * + * PUBLIC: void __db_idspace __P((u_int32_t *, int, u_int32_t *, u_int32_t *)); + */ +void +__db_idspace(inuse, n, minp, maxp) + u_int32_t *inuse; + int n; + u_int32_t *minp, *maxp; +{ + int i, low; + u_int32_t gap, t; + + /* A single locker ID is a special case. */ + if (n == 1) { + /* + * If the single item in use is the last one in the range, + * then we've got to perform wrap which means that we set + * the min to the minimum ID, which is what we came in with, + * so we don't do anything. + */ + if (inuse[0] != *maxp) + *minp = inuse[0]; + *maxp = inuse[0] - 1; + return; + } + + gap = 0; + low = 0; + qsort(inuse, (size_t)n, sizeof(u_int32_t), __db_idcmp); + for (i = 0; i < n - 1; i++) + if ((t = (inuse[i + 1] - inuse[i])) > gap) { + gap = t; + low = i; + } + + /* Check for largest gap at the end of the space. */ + if ((*maxp - inuse[n - 1]) + (inuse[0] - *minp) > gap) { + /* Do same check as we do in the n == 1 case. */ + if (inuse[n - 1] != *maxp) + *minp = inuse[n - 1]; + *maxp = inuse[0] - 1; + } else { + *minp = inuse[low]; + *maxp = inuse[low + 1] - 1; + } +} diff --git a/src/libs/resiprocate/contrib/db/common/db_log2.c b/src/libs/resiprocate/contrib/db/common/db_log2.c new file mode 100644 index 00000000..c29e0d30 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/common/db_log2.c @@ -0,0 +1,57 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * PUBLIC: u_int32_t __db_log2 __P((u_int32_t)); + */ +u_int32_t +__db_log2(num) + u_int32_t num; +{ + u_int32_t i, limit; + + limit = 1; + for (i = 0; limit < num; limit = limit << 1) + ++i; + return (i); +} diff --git a/src/libs/resiprocate/contrib/db/common/util_arg.c b/src/libs/resiprocate/contrib/db/common/util_arg.c new file mode 100644 index 00000000..61bdb5bd --- /dev/null +++ b/src/libs/resiprocate/contrib/db/common/util_arg.c @@ -0,0 +1,56 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2001-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 5 +/* + * !!! + * We build this file in old versions of Berkeley DB when we're doing test + * runs using the test_micro tool. Without a prototype in place, we get + * warnings, and there's no simple workaround. + */ +char *strsep(); +#endif + +/* + * __db_util_arg -- + * Convert a string into an argc/argv pair. + * + * PUBLIC: int __db_util_arg __P((char *, char *, int *, char ***)); + */ +int +__db_util_arg(arg0, str, argcp, argvp) + char *arg0, *str, ***argvp; + int *argcp; +{ + int n, ret; + char **ap, **argv; + +#define MAXARGS 25 + if ((ret = + __os_malloc(NULL, (MAXARGS + 1) * sizeof(char **), &argv)) != 0) + return (ret); + + ap = argv; + *ap++ = arg0; + for (n = 1; (*ap = strsep(&str, " \t")) != NULL;) + if (**ap != '\0') { + ++ap; + if (++n == MAXARGS) + break; + } + *ap = NULL; + + *argcp = ap - argv; + *argvp = argv; + + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/common/util_cache.c b/src/libs/resiprocate/contrib/db/common/util_cache.c new file mode 100644 index 00000000..03475f55 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/common/util_cache.c @@ -0,0 +1,47 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * __db_util_cache -- + * Compute if we have enough cache. + * + * PUBLIC: int __db_util_cache __P((DB *, u_int32_t *, int *)); + */ +int +__db_util_cache(dbp, cachep, resizep) + DB *dbp; + u_int32_t *cachep; + int *resizep; +{ + u_int32_t pgsize; + int ret; + + /* Get the current page size. */ + if ((ret = dbp->get_pagesize(dbp, &pgsize)) != 0) + return (ret); + + /* + * The current cache size is in cachep. If it's insufficient, set the + * the memory referenced by resizep to 1 and set cachep to the minimum + * size needed. + * + * Make sure our current cache is big enough. We want at least + * DB_MINPAGECACHE pages in the cache. + */ + if ((*cachep / pgsize) < DB_MINPAGECACHE) { + *resizep = 1; + *cachep = pgsize * DB_MINPAGECACHE; + } else + *resizep = 0; + + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/common/util_log.c b/src/libs/resiprocate/contrib/db/common/util_log.c new file mode 100644 index 00000000..cb2cfa46 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/common/util_log.c @@ -0,0 +1,45 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * __db_util_logset -- + * Log that we're running. + * + * PUBLIC: int __db_util_logset __P((const char *, char *)); + */ +int +__db_util_logset(progname, fname) + const char *progname; + char *fname; +{ + pid_t pid; + FILE *fp; + time_t now; + char time_buf[CTIME_BUFLEN]; + + if ((fp = fopen(fname, "w")) == NULL) + goto err; + + (void)time(&now); + + __os_id(NULL, &pid, NULL); + fprintf(fp, + "%s: %lu %s", progname, (u_long)pid, __os_ctime(&now, time_buf)); + + if (fclose(fp) == EOF) + goto err; + + return (0); + +err: fprintf(stderr, "%s: %s: %s\n", progname, fname, strerror(errno)); + return (1); +} diff --git a/src/libs/resiprocate/contrib/db/common/util_sig.c b/src/libs/resiprocate/contrib/db/common/util_sig.c new file mode 100644 index 00000000..9eacbc3b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/common/util_sig.c @@ -0,0 +1,110 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +static int interrupt; +static void set_signal __P((int, int)); +static void signal_handler __P((int)); + +/* + * signal_handler -- + * Interrupt signal handler. + */ +static void +signal_handler(signo) + int signo; +{ +#ifndef HAVE_SIGACTION + /* Assume signal() is unreliable and reset it, first thing. */ + set_signal(signo, 0); +#endif + /* Some systems don't pass in the correct signal value -- check. */ + if ((interrupt = signo) == 0) + interrupt = SIGINT; +} + +/* + * set_signal + */ +static void +set_signal(s, is_dflt) + int s, is_dflt; +{ + /* + * Use sigaction if it's available, otherwise use signal(). + */ +#ifdef HAVE_SIGACTION + struct sigaction sa, osa; + + sa.sa_handler = is_dflt ? SIG_DFL : signal_handler; + (void)sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + (void)sigaction(s, &sa, &osa); +#else + (void)signal(s, is_dflt ? SIG_DFL : signal_handler); +#endif +} + +/* + * __db_util_siginit -- + * + * PUBLIC: void __db_util_siginit __P((void)); + */ +void +__db_util_siginit() +{ + /* + * Initialize the set of signals for which we want to clean up. + * Generally, we try not to leave the shared regions locked if + * we can. + */ +#ifdef SIGHUP + set_signal(SIGHUP, 0); +#endif +#ifdef SIGINT + set_signal(SIGINT, 0); +#endif +#ifdef SIGPIPE + set_signal(SIGPIPE, 0); +#endif +#ifdef SIGTERM + set_signal(SIGTERM, 0); +#endif +} + +/* + * __db_util_interrupted -- + * Return if interrupted. + * + * PUBLIC: int __db_util_interrupted __P((void)); + */ +int +__db_util_interrupted() +{ + return (interrupt != 0); +} + +/* + * __db_util_sigresend -- + * + * PUBLIC: void __db_util_sigresend __P((void)); + */ +void +__db_util_sigresend() +{ + /* Resend any caught signal. */ + if (interrupt != 0) { + set_signal(interrupt, 1); + + (void)raise(interrupt); + /* NOTREACHED */ + } +} diff --git a/src/libs/resiprocate/contrib/db/cxx/cxx_db.cpp b/src/libs/resiprocate/contrib/db/cxx/cxx_db.cpp new file mode 100644 index 00000000..a6e6ac53 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/cxx/cxx_db.cpp @@ -0,0 +1,810 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +#include "dbinc/db_page.h" +#include "dbinc_auto/db_auto.h" +#include "dbinc_auto/crdel_auto.h" +#include "dbinc/db_dispatch.h" +#include "dbinc_auto/db_ext.h" +#include "dbinc_auto/common_ext.h" + +// Helper macros for simple methods that pass through to the +// underlying C method. It may return an error or raise an exception. +// Note this macro expects that input _argspec is an argument +// list element (e.g., "char *arg") and that _arglist is the arguments +// that should be passed through to the C method (e.g., "(db, arg)") +// +#define DB_METHOD(_name, _argspec, _arglist, _retok) \ +int Db::_name _argspec \ +{ \ + int ret; \ + DB *db = unwrap(this); \ + \ + ret = db->_name _arglist; \ + if (!_retok(ret)) \ + DB_ERROR(dbenv_, "Db::" # _name, ret, error_policy()); \ + return (ret); \ +} + +#define DB_DESTRUCTOR(_name, _argspec, _arglist, _retok) \ +int Db::_name _argspec \ +{ \ + int ret; \ + DB *db = unwrap(this); \ + \ + if (!db) { \ + DB_ERROR(dbenv_, "Db::" # _name, EINVAL, error_policy()); \ + return (EINVAL); \ + } \ + ret = db->_name _arglist; \ + cleanup(); \ + if (!_retok(ret)) \ + DB_ERROR(dbenv_, "Db::" # _name, ret, error_policy()); \ + return (ret); \ +} + +#define DB_METHOD_QUIET(_name, _argspec, _arglist) \ +int Db::_name _argspec \ +{ \ + DB *db = unwrap(this); \ + \ + return (db->_name _arglist); \ +} + +#define DB_METHOD_VOID(_name, _argspec, _arglist) \ +void Db::_name _argspec \ +{ \ + DB *db = unwrap(this); \ + \ + db->_name _arglist; \ +} + +// A truism for the Db object is that there is a valid +// DB handle from the constructor until close(). +// After the close, the DB handle is invalid and +// no operations are permitted on the Db (other than +// destructor). Leaving the Db handle open and not +// doing a close is generally considered an error. +// +// We used to allow Db objects to be closed and reopened. +// This implied always keeping a valid DB object, and +// coordinating the open objects between Db/DbEnv turned +// out to be overly complicated. Now we do not allow this. + +Db::Db(DbEnv *dbenv, u_int32_t flags) +: imp_(0) +, dbenv_(dbenv) +, mpf_(0) +, construct_error_(0) +, flags_(0) +, construct_flags_(flags) +, append_recno_callback_(0) +, associate_callback_(0) +, associate_foreign_callback_(0) +, bt_compare_callback_(0) +, bt_compress_callback_(0) +, bt_decompress_callback_(0) +, bt_prefix_callback_(0) +, db_partition_callback_(0) +, dup_compare_callback_(0) +, feedback_callback_(0) +, h_compare_callback_(0) +, h_hash_callback_(0) +{ + if (dbenv_ == 0) + flags_ |= DB_CXX_PRIVATE_ENV; + + if ((construct_error_ = initialize()) != 0) + DB_ERROR(dbenv_, "Db::Db", construct_error_, error_policy()); +} + +// If the DB handle is still open, we close it. This is to make stack +// allocation of Db objects easier so that they are cleaned up in the error +// path. If the environment was closed prior to this, it may cause a trap, but +// an error message is generated during the environment close. Applications +// should call close explicitly in normal (non-exceptional) cases to check the +// return value. +// +Db::~Db() +{ + DB *db; + + db = unwrap(this); + if (db != NULL) { + (void)db->close(db, 0); + cleanup(); + } +} + +// private method to initialize during constructor. +// initialize must create a backing DB object, +// and if that creates a new DB_ENV, it must be tied to a new DbEnv. +// +int Db::initialize() +{ + DB *db; + DB_ENV *cenv = unwrap(dbenv_); + int ret; + u_int32_t cxx_flags; + + cxx_flags = construct_flags_ & DB_CXX_NO_EXCEPTIONS; + + // Create a new underlying DB object. + // We rely on the fact that if a NULL DB_ENV* is given, + // one is allocated by DB. + // + if ((ret = db_create(&db, cenv, + construct_flags_ & ~cxx_flags)) != 0) + return (ret); + + // Associate the DB with this object + imp_ = db; + db->api_internal = this; + + // Create a new DbEnv from a DB_ENV* if it was created locally. + // It is deleted in Db::close(). + // + if ((flags_ & DB_CXX_PRIVATE_ENV) != 0) + dbenv_ = new DbEnv(db->dbenv, cxx_flags); + + // Create a DbMpoolFile from the DB_MPOOLFILE* in the DB handle. + mpf_ = new DbMpoolFile(); + mpf_->imp_ = db->mpf; + + return (0); +} + +// private method to cleanup after destructor or during close. +// If the environment was created by this Db object, we need to delete it. +// +void Db::cleanup() +{ + if (imp_ != 0) { + imp_ = 0; + + // we must dispose of the DbEnv object if + // we created it. This will be the case + // if a NULL DbEnv was passed into the constructor. + // The underlying DB_ENV object will be inaccessible + // after the close, so we must clean it up now. + // + if ((flags_ & DB_CXX_PRIVATE_ENV) != 0) { + dbenv_->cleanup(); + delete dbenv_; + dbenv_ = 0; + } + + delete mpf_; + } +} + +// Return a tristate value corresponding to whether we should +// throw exceptions on errors: +// ON_ERROR_RETURN +// ON_ERROR_THROW +// ON_ERROR_UNKNOWN +// +int Db::error_policy() +{ + if (dbenv_ != NULL) + return (dbenv_->error_policy()); + else { + // If the dbenv_ is null, that means that the user + // did not attach an environment, so the correct error + // policy can be deduced from constructor flags + // for this Db. + // + if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) { + return (ON_ERROR_RETURN); + } + else { + return (ON_ERROR_THROW); + } + } +} + +DB_DESTRUCTOR(close, (u_int32_t flags), (db, flags), DB_RETOK_STD) +DB_METHOD(compact, (DbTxn *txnid, Dbt *start, Dbt *stop, + DB_COMPACT *c_data, u_int32_t flags, Dbt *end), + (db, unwrap(txnid), start, stop, c_data, flags, end), DB_RETOK_STD) + +// The following cast implies that Dbc can be no larger than DBC +DB_METHOD(cursor, (DbTxn *txnid, Dbc **cursorp, u_int32_t flags), + (db, unwrap(txnid), (DBC **)cursorp, flags), + DB_RETOK_STD) + +DB_METHOD(del, (DbTxn *txnid, Dbt *key, u_int32_t flags), + (db, unwrap(txnid), key, flags), + DB_RETOK_DBDEL) + +void Db::err(int error, const char *format, ...) +{ + DB *db = unwrap(this); + + DB_REAL_ERR(db->dbenv, error, DB_ERROR_SET, 1, format); +} + +void Db::errx(const char *format, ...) +{ + DB *db = unwrap(this); + + DB_REAL_ERR(db->dbenv, 0, DB_ERROR_NOT_SET, 1, format); +} + +DB_METHOD(exists, (DbTxn *txnid, Dbt *key, u_int32_t flags), + (db, unwrap(txnid), key, flags), DB_RETOK_EXISTS) + +DB_METHOD(fd, (int *fdp), (db, fdp), DB_RETOK_STD) + +int Db::get(DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags) +{ + DB *db = unwrap(this); + int ret; + + ret = db->get(db, unwrap(txnid), key, value, flags); + + if (!DB_RETOK_DBGET(ret)) { + if (ret == DB_BUFFER_SMALL) + DB_ERROR_DBT(dbenv_, "Db::get", value, error_policy()); + else + DB_ERROR(dbenv_, "Db::get", ret, error_policy()); + } + + return (ret); +} + +int Db::get_byteswapped(int *isswapped) +{ + DB *db = (DB *)unwrapConst(this); + return (db->get_byteswapped(db, isswapped)); +} + +DbEnv *Db::get_env() +{ + DB *db = (DB *)unwrapConst(this); + DB_ENV *dbenv = db->get_env(db); + return (dbenv != NULL ? DbEnv::get_DbEnv(dbenv) : NULL); +} + +DbMpoolFile *Db::get_mpf() +{ + return (mpf_); +} + +DB_METHOD(get_dbname, (const char **filenamep, const char **dbnamep), + (db, filenamep, dbnamep), DB_RETOK_STD) + +DB_METHOD(get_open_flags, (u_int32_t *flagsp), (db, flagsp), DB_RETOK_STD) + +int Db::get_type(DBTYPE *dbtype) +{ + DB *db = (DB *)unwrapConst(this); + return (db->get_type(db, dbtype)); +} + +// Dbc is a "compatible" subclass of DBC - that is, no virtual functions +// or even extra data members, so these casts, although technically +// non-portable, "should" always be okay. +DB_METHOD(join, (Dbc **curslist, Dbc **cursorp, u_int32_t flags), + (db, (DBC **)curslist, (DBC **)cursorp, flags), DB_RETOK_STD) + +DB_METHOD(key_range, + (DbTxn *txnid, Dbt *key, DB_KEY_RANGE *results, u_int32_t flags), + (db, unwrap(txnid), key, results, flags), DB_RETOK_STD) + +// If an error occurred during the constructor, report it now. +// Otherwise, call the underlying DB->open method. +// +int Db::open(DbTxn *txnid, const char *file, const char *database, + DBTYPE type, u_int32_t flags, int mode) +{ + int ret; + DB *db = unwrap(this); + + if (construct_error_ != 0) + ret = construct_error_; + else + ret = db->open(db, unwrap(txnid), file, database, type, flags, + mode); + + if (!DB_RETOK_STD(ret)) + DB_ERROR(dbenv_, "Db::open", ret, error_policy()); + + return (ret); +} + +int Db::pget(DbTxn *txnid, Dbt *key, Dbt *pkey, Dbt *value, u_int32_t flags) +{ + DB *db = unwrap(this); + int ret; + + ret = db->pget(db, unwrap(txnid), key, pkey, value, flags); + + /* The logic here is identical to Db::get - reuse the macro. */ + if (!DB_RETOK_DBGET(ret)) { + if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(value)) + DB_ERROR_DBT(dbenv_, "Db::pget", value, error_policy()); + else + DB_ERROR(dbenv_, "Db::pget", ret, error_policy()); + } + + return (ret); +} + +DB_METHOD(put, (DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags), + (db, unwrap(txnid), key, value, flags), DB_RETOK_DBPUT) + +DB_DESTRUCTOR(rename, + (const char *file, const char *database, const char *newname, + u_int32_t flags), + (db, file, database, newname, flags), DB_RETOK_STD) + +DB_DESTRUCTOR(remove, (const char *file, const char *database, u_int32_t flags), + (db, file, database, flags), DB_RETOK_STD) + +DB_METHOD(truncate, (DbTxn *txnid, u_int32_t *countp, u_int32_t flags), + (db, unwrap(txnid), countp, flags), DB_RETOK_STD) + +DB_METHOD(stat, (DbTxn *txnid, void *sp, u_int32_t flags), + (db, unwrap(txnid), sp, flags), DB_RETOK_STD) + +DB_METHOD(stat_print, (u_int32_t flags), (db, flags), DB_RETOK_STD) + +DB_METHOD(sync, (u_int32_t flags), (db, flags), DB_RETOK_STD) + +DB_METHOD(upgrade, + (const char *name, u_int32_t flags), (db, name, flags), DB_RETOK_STD) + +//////////////////////////////////////////////////////////////////////// +// +// callbacks +// +// *_intercept_c are 'glue' functions that must be declared +// as extern "C" so to be typesafe. Using a C++ method, even +// a static class method with 'correct' arguments, will not pass +// the test; some picky compilers do not allow mixing of function +// pointers to 'C' functions with function pointers to C++ functions. +// +// One wart with this scheme is that the *_callback_ method pointer +// must be declared public to be accessible by the C intercept. +// It's possible to accomplish the goal without this, and with +// another public transfer method, but it's just too much overhead. +// These callbacks are supposed to be *fast*. +// +// The DBTs we receive in these callbacks from the C layer may be +// manufactured there, but we want to treat them as a Dbts. +// Technically speaking, these DBTs were not constructed as a Dbts, +// but it should be safe to cast them as such given that Dbt is a +// *very* thin extension of the DBT. That is, Dbt has no additional +// data elements, does not use virtual functions, virtual inheritance, +// multiple inheritance, RTI, or any other language feature that +// causes the structure to grow or be displaced. Although this may +// sound risky, a design goal of C++ is complete structure +// compatibility with C, and has the philosophy 'if you don't use it, +// you shouldn't incur the overhead'. If the C/C++ compilers you're +// using on a given machine do not have matching struct layouts, then +// a lot more things will be broken than just this. +// +// The alternative, creating a Dbt here in the callback, and populating +// it from the DBT, is just too slow and cumbersome to be very useful. + +// These macros avoid a lot of boilerplate code for callbacks + +#define DB_CALLBACK_C_INTERCEPT(_name, _rettype, _cargspec, \ + _return, _cxxargs) \ +extern "C" _rettype _db_##_name##_intercept_c _cargspec \ +{ \ + Db *cxxthis; \ + \ + /* We don't have a dbenv handle at this point. */ \ + DB_ASSERT(NULL, cthis != NULL); \ + cxxthis = Db::get_Db(cthis); \ + DB_ASSERT(cthis->dbenv->env, cxxthis != NULL); \ + DB_ASSERT(cthis->dbenv->env, cxxthis->_name##_callback_ != 0); \ + \ + _return (*cxxthis->_name##_callback_) _cxxargs; \ +} + +#define DB_SET_CALLBACK(_cxxname, _name, _cxxargspec, _cb) \ +int Db::_cxxname _cxxargspec \ +{ \ + DB *cthis = unwrap(this); \ + \ + _name##_callback_ = _cb; \ + return ((*(cthis->_cxxname))(cthis, \ + (_cb) ? _db_##_name##_intercept_c : NULL)); \ +} + +#define DB_GET_CALLBACK(_cxxname, _name, _cxxargspec, _cbp) \ +int Db::_cxxname _cxxargspec \ +{ \ + if (_cbp != NULL) \ + *(_cbp) = _name##_callback_; \ + return 0; \ +} + +/* associate callback - doesn't quite fit the pattern because of the flags */ +DB_CALLBACK_C_INTERCEPT(associate, + int, (DB *cthis, const DBT *key, const DBT *data, DBT *retval), + return, (cxxthis, Dbt::get_const_Dbt(key), Dbt::get_const_Dbt(data), + Dbt::get_Dbt(retval))) + +int Db::associate(DbTxn *txn, Db *secondary, int (*callback)(Db *, const Dbt *, + const Dbt *, Dbt *), u_int32_t flags) +{ + DB *cthis = unwrap(this); + + /* Since the secondary Db is used as the first argument + * to the callback, we store the C++ callback on it + * rather than on 'this'. + */ + secondary->associate_callback_ = callback; + return ((*(cthis->associate))(cthis, unwrap(txn), unwrap(secondary), + (callback) ? _db_associate_intercept_c : NULL, flags)); +} + +/* associate callback - doesn't quite fit the pattern because of the flags */ +DB_CALLBACK_C_INTERCEPT(associate_foreign, int, + (DB *cthis, const DBT *key, DBT *data, const DBT *fkey, int *changed), + return, (cxxthis, Dbt::get_const_Dbt(key), + Dbt::get_Dbt(data), Dbt::get_const_Dbt(fkey), changed)) + +int Db::associate_foreign(Db *secondary, int (*callback)(Db *, + const Dbt *, Dbt *, const Dbt *, int *), u_int32_t flags) +{ + DB *cthis = unwrap(this); + + secondary->associate_foreign_callback_ = callback; + return ((*(cthis->associate_foreign))(cthis, unwrap(secondary), + (callback) ? _db_associate_foreign_intercept_c : NULL, flags)); +} + +DB_CALLBACK_C_INTERCEPT(feedback, + void, (DB *cthis, int opcode, int pct), + /* no return */ (void), (cxxthis, opcode, pct)) + +DB_GET_CALLBACK(get_feedback, feedback, + (void (**argp)(Db *cxxthis, int opcode, int pct)), argp) + +DB_SET_CALLBACK(set_feedback, feedback, + (void (*arg)(Db *cxxthis, int opcode, int pct)), arg) + +DB_CALLBACK_C_INTERCEPT(append_recno, + int, (DB *cthis, DBT *data, db_recno_t recno), + return, (cxxthis, Dbt::get_Dbt(data), recno)) + +DB_GET_CALLBACK(get_append_recno, append_recno, + (int (**argp)(Db *cxxthis, Dbt *data, db_recno_t recno)), argp) + +DB_SET_CALLBACK(set_append_recno, append_recno, + (int (*arg)(Db *cxxthis, Dbt *data, db_recno_t recno)), arg) + +DB_CALLBACK_C_INTERCEPT(bt_compare, + int, (DB *cthis, const DBT *data1, const DBT *data2), + return, + (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) + +DB_GET_CALLBACK(get_bt_compare, bt_compare, + (int (**argp)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), argp) + +DB_SET_CALLBACK(set_bt_compare, bt_compare, + (int (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) + +DB_CALLBACK_C_INTERCEPT(bt_compress, + int, (DB *cthis, const DBT *data1, const DBT *data2, const DBT *data3, + const DBT *data4, DBT *data5), return, + (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2), + Dbt::get_const_Dbt(data3), Dbt::get_const_Dbt(data4), Dbt::get_Dbt(data5))) + +DB_CALLBACK_C_INTERCEPT(bt_decompress, + int, (DB *cthis, const DBT *data1, const DBT *data2, DBT *data3, + DBT *data4, DBT *data5), return, + (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2), + Dbt::get_Dbt(data3), Dbt::get_Dbt(data4), Dbt::get_Dbt(data5))) + +// The {g|s}et_bt_compress methods don't fit into the standard macro templates +// since they take two callback functions. +int Db::get_bt_compress( + int (**bt_compress) + (Db *, const Dbt *, const Dbt *, const Dbt *, const Dbt *, Dbt *), + int (**bt_decompress) + (Db *, const Dbt *, const Dbt *, Dbt *, Dbt *, Dbt *)) +{ + if (bt_compress != NULL) + *(bt_compress) = bt_compress_callback_; + if (bt_decompress != NULL) + *(bt_decompress) = bt_decompress_callback_; + return 0; +} + +int Db::set_bt_compress( + int (*bt_compress) + (Db *, const Dbt *, const Dbt *, const Dbt *, const Dbt *, Dbt *), + int (*bt_decompress)(Db *, const Dbt *, const Dbt *, Dbt *, Dbt *, Dbt *)) +{ + DB *cthis = unwrap(this); + + bt_compress_callback_ = bt_compress; + bt_decompress_callback_ = bt_decompress; + return ((*(cthis->set_bt_compress))(cthis, + (bt_compress ? _db_bt_compress_intercept_c : NULL), + (bt_decompress ? _db_bt_decompress_intercept_c : NULL))); + +} + +DB_CALLBACK_C_INTERCEPT(bt_prefix, + size_t, (DB *cthis, const DBT *data1, const DBT *data2), + return, + (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) + +DB_GET_CALLBACK(get_bt_prefix, bt_prefix, + (size_t (**argp)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), argp) + +DB_SET_CALLBACK(set_bt_prefix, bt_prefix, + (size_t (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) + +DB_CALLBACK_C_INTERCEPT(dup_compare, + int, (DB *cthis, const DBT *data1, const DBT *data2), + return, + (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) + +DB_GET_CALLBACK(get_dup_compare, dup_compare, + (int (**argp)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), argp) + +DB_SET_CALLBACK(set_dup_compare, dup_compare, + (int (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) + +DB_CALLBACK_C_INTERCEPT(h_compare, + int, (DB *cthis, const DBT *data1, const DBT *data2), + return, + (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) + +DB_GET_CALLBACK(get_h_compare, h_compare, + (int (**argp)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), argp) + +DB_SET_CALLBACK(set_h_compare, h_compare, + (int (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) + +DB_CALLBACK_C_INTERCEPT(h_hash, + u_int32_t, (DB *cthis, const void *data, u_int32_t len), + return, (cxxthis, data, len)) + +DB_GET_CALLBACK(get_h_hash, h_hash, + (u_int32_t (**argp)(Db *cxxthis, const void *data, u_int32_t len)), argp) + +DB_SET_CALLBACK(set_h_hash, h_hash, + (u_int32_t (*arg)(Db *cxxthis, const void *data, u_int32_t len)), arg) + +// This is a 'glue' function declared as extern "C" so it will +// be compatible with picky compilers that do not allow mixing +// of function pointers to 'C' functions with function pointers +// to C++ functions. +// +extern "C" +int _verify_callback_c(void *handle, const void *str_arg) +{ + char *str; + __DB_STD(ostream) *out; + + str = (char *)str_arg; + out = (__DB_STD(ostream) *)handle; + + (*out) << str; + if (out->fail()) + return (EIO); + + return (0); +} + +int Db::verify(const char *name, const char *subdb, + __DB_STD(ostream) *ostr, u_int32_t flags) +{ + DB *db = unwrap(this); + int ret; + + if (!db) + ret = EINVAL; + else { + ret = __db_verify_internal(db, name, subdb, ostr, + _verify_callback_c, flags); + + // After a DB->verify (no matter if success or failure), + // the underlying DB object must not be accessed. + // + cleanup(); + } + + if (!DB_RETOK_STD(ret)) + DB_ERROR(dbenv_, "Db::verify", ret, error_policy()); + + return (ret); +} + +DB_METHOD(set_bt_compare, (bt_compare_fcn_type func), + (db, func), DB_RETOK_STD) +DB_METHOD(get_bt_minkey, (u_int32_t *bt_minkeyp), + (db, bt_minkeyp), DB_RETOK_STD) +DB_METHOD(set_bt_minkey, (u_int32_t bt_minkey), + (db, bt_minkey), DB_RETOK_STD) +DB_METHOD(set_bt_prefix, (bt_prefix_fcn_type func), + (db, func), DB_RETOK_STD) +DB_METHOD(set_dup_compare, (dup_compare_fcn_type func), + (db, func), DB_RETOK_STD) +DB_METHOD(get_encrypt_flags, (u_int32_t *flagsp), + (db, flagsp), DB_RETOK_STD) +DB_METHOD(set_encrypt, (const char *passwd, u_int32_t flags), + (db, passwd, flags), DB_RETOK_STD) +DB_METHOD_VOID(get_errfile, (FILE **errfilep), (db, errfilep)) +DB_METHOD_VOID(set_errfile, (FILE *errfile), (db, errfile)) +DB_METHOD_VOID(get_errpfx, (const char **errpfx), (db, errpfx)) +DB_METHOD_VOID(set_errpfx, (const char *errpfx), (db, errpfx)) +DB_METHOD(get_flags, (u_int32_t *flagsp), (db, flagsp), + DB_RETOK_STD) +DB_METHOD(set_flags, (u_int32_t flags), (db, flags), + DB_RETOK_STD) +DB_METHOD(set_h_compare, (h_compare_fcn_type func), + (db, func), DB_RETOK_STD) +DB_METHOD(get_h_ffactor, (u_int32_t *h_ffactorp), + (db, h_ffactorp), DB_RETOK_STD) +DB_METHOD(set_h_ffactor, (u_int32_t h_ffactor), + (db, h_ffactor), DB_RETOK_STD) +DB_METHOD(set_h_hash, (h_hash_fcn_type func), + (db, func), DB_RETOK_STD) +DB_METHOD(get_h_nelem, (u_int32_t *h_nelemp), + (db, h_nelemp), DB_RETOK_STD) +DB_METHOD(set_h_nelem, (u_int32_t h_nelem), + (db, h_nelem), DB_RETOK_STD) +DB_METHOD(get_lorder, (int *db_lorderp), (db, db_lorderp), + DB_RETOK_STD) +DB_METHOD(set_lorder, (int db_lorder), (db, db_lorder), + DB_RETOK_STD) +DB_METHOD_VOID(get_msgfile, (FILE **msgfilep), (db, msgfilep)) +DB_METHOD_VOID(set_msgfile, (FILE *msgfile), (db, msgfile)) +DB_METHOD_QUIET(get_multiple, (), (db)) +DB_METHOD(get_pagesize, (u_int32_t *db_pagesizep), + (db, db_pagesizep), DB_RETOK_STD) +DB_METHOD(set_pagesize, (u_int32_t db_pagesize), + (db, db_pagesize), DB_RETOK_STD) + +DB_CALLBACK_C_INTERCEPT(db_partition, + u_int32_t, (DB *cthis, DBT *key), + return, (cxxthis, Dbt::get_Dbt(key))) + +// set_partition and get_partition_callback do not fit into the macro +// templates, since there is an additional argument in the API calls. +int Db::set_partition(u_int32_t parts, Dbt *keys, + u_int32_t (*arg)(Db *cxxthis, Dbt *key)) +{ + DB *cthis = unwrap(this); + + db_partition_callback_ = arg; + return ((*(cthis->set_partition))(cthis, parts, keys, + arg ? _db_db_partition_intercept_c : NULL)); +} + +int Db::get_partition_callback(u_int32_t *parts, + u_int32_t (**argp)(Db *cxxthis, Dbt *key)) +{ + DB *cthis = unwrap(this); + if (argp != NULL) + *(argp) = db_partition_callback_; + if (parts != NULL) + (cthis->get_partition_callback)(cthis, parts, NULL); + return 0; +} + +DB_METHOD(set_partition_dirs, (const char **dirp), (db, dirp), DB_RETOK_STD) +DB_METHOD(get_partition_dirs, (const char ***dirpp), (db, dirpp), DB_RETOK_STD) +DB_METHOD(get_partition_keys, (u_int32_t *parts, Dbt **keys), + (db, parts, (DBT **)keys), DB_RETOK_STD) +DB_METHOD(get_priority, (DB_CACHE_PRIORITY *priorityp), + (db, priorityp), DB_RETOK_STD) +DB_METHOD(set_priority, (DB_CACHE_PRIORITY priority), + (db, priority), DB_RETOK_STD) +DB_METHOD(get_re_delim, (int *re_delimp), + (db, re_delimp), DB_RETOK_STD) +DB_METHOD(set_re_delim, (int re_delim), + (db, re_delim), DB_RETOK_STD) +DB_METHOD(get_re_len, (u_int32_t *re_lenp), + (db, re_lenp), DB_RETOK_STD) +DB_METHOD(set_re_len, (u_int32_t re_len), + (db, re_len), DB_RETOK_STD) +DB_METHOD(get_re_pad, (int *re_padp), + (db, re_padp), DB_RETOK_STD) +DB_METHOD(set_re_pad, (int re_pad), + (db, re_pad), DB_RETOK_STD) +DB_METHOD(get_re_source, (const char **re_source), + (db, re_source), DB_RETOK_STD) +DB_METHOD(set_re_source, (const char *re_source), + (db, re_source), DB_RETOK_STD) +DB_METHOD(sort_multiple, (Dbt *key, Dbt *data, u_int32_t flags), + (db, key, data, flags), DB_RETOK_STD) +DB_METHOD(get_q_extentsize, (u_int32_t *extentsizep), + (db, extentsizep), DB_RETOK_STD) +DB_METHOD(set_q_extentsize, (u_int32_t extentsize), + (db, extentsize), DB_RETOK_STD) + +DB_METHOD_QUIET(get_alloc, (db_malloc_fcn_type *malloc_fcnp, + db_realloc_fcn_type *realloc_fcnp, db_free_fcn_type *free_fcnp), + (db, malloc_fcnp, realloc_fcnp, free_fcnp)) + +DB_METHOD_QUIET(set_alloc, (db_malloc_fcn_type malloc_fcn, + db_realloc_fcn_type realloc_fcn, db_free_fcn_type free_fcn), + (db, malloc_fcn, realloc_fcn, free_fcn)) + +void Db::get_errcall(void (**argp)(const DbEnv *, const char *, const char *)) +{ + dbenv_->get_errcall(argp); +} + +void Db::set_errcall(void (*arg)(const DbEnv *, const char *, const char *)) +{ + dbenv_->set_errcall(arg); +} + +void Db::get_msgcall(void (**argp)(const DbEnv *, const char *)) +{ + dbenv_->get_msgcall(argp); +} + +void Db::set_msgcall(void (*arg)(const DbEnv *, const char *)) +{ + dbenv_->set_msgcall(arg); +} + +void *Db::get_app_private() const +{ + return unwrapConst(this)->app_private; +} + +void Db::set_app_private(void *value) +{ + unwrap(this)->app_private = value; +} + +DB_METHOD(get_cachesize, (u_int32_t *gbytesp, u_int32_t *bytesp, int *ncachep), + (db, gbytesp, bytesp, ncachep), DB_RETOK_STD) +DB_METHOD(set_cachesize, (u_int32_t gbytes, u_int32_t bytes, int ncache), + (db, gbytes, bytes, ncache), DB_RETOK_STD) + +DB_METHOD(get_create_dir, (const char **dirp), (db, dirp), DB_RETOK_STD) +DB_METHOD(set_create_dir, (const char *dir), (db, dir), DB_RETOK_STD) + +int Db::set_paniccall(void (*callback)(DbEnv *, int)) +{ + return (dbenv_->set_paniccall(callback)); +} + +__DB_STD(ostream) *Db::get_error_stream() +{ + return dbenv_->get_error_stream(); +} + +void Db::set_error_stream(__DB_STD(ostream) *error_stream) +{ + dbenv_->set_error_stream(error_stream); +} + +__DB_STD(ostream) *Db::get_message_stream() +{ + return dbenv_->get_message_stream(); +} + +void Db::set_message_stream(__DB_STD(ostream) *message_stream) +{ + dbenv_->set_message_stream(message_stream); +} + +DB_METHOD_QUIET(get_transactional, (), (db)) diff --git a/src/libs/resiprocate/contrib/db/cxx/cxx_dbc.cpp b/src/libs/resiprocate/contrib/db/cxx/cxx_dbc.cpp new file mode 100644 index 00000000..d4d461d5 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/cxx/cxx_dbc.cpp @@ -0,0 +1,123 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +#include "dbinc/db_page.h" +#include "dbinc_auto/db_auto.h" +#include "dbinc_auto/crdel_auto.h" +#include "dbinc/db_dispatch.h" +#include "dbinc_auto/db_ext.h" +#include "dbinc_auto/common_ext.h" + +// Helper macro for simple methods that pass through to the +// underlying C method. It may return an error or raise an exception. +// Note this macro expects that input _argspec is an argument +// list element (e.g., "char *arg") and that _arglist is the arguments +// that should be passed through to the C method (e.g., "(db, arg)") +// +#define DBC_METHOD(_name, _argspec, _arglist, _retok) \ +int Dbc::_name _argspec \ +{ \ + int ret; \ + DBC *dbc = this; \ + \ + ret = dbc->_name _arglist; \ + if (!_retok(ret)) \ + DB_ERROR(DbEnv::get_DbEnv(dbc->dbenv), \ + "Dbc::" # _name, ret, ON_ERROR_UNKNOWN); \ + return (ret); \ +} + +// It's private, and should never be called, but VC4.0 needs it resolved +// +Dbc::~Dbc() +{ +} + +DBC_METHOD(close, (void), (dbc), DB_RETOK_STD) +DBC_METHOD(cmp, (Dbc *other_cursor, int *result, u_int32_t _flags), + (dbc, other_cursor, result, _flags), DB_RETOK_STD) +DBC_METHOD(count, (db_recno_t *countp, u_int32_t _flags), + (dbc, countp, _flags), DB_RETOK_STD) +DBC_METHOD(del, (u_int32_t _flags), + (dbc, _flags), DB_RETOK_DBCDEL) + +int Dbc::dup(Dbc** cursorp, u_int32_t _flags) +{ + int ret; + DBC *dbc = this; + DBC *new_cursor = 0; + + ret = dbc->dup(dbc, &new_cursor, _flags); + + if (DB_RETOK_STD(ret)) + // The following cast implies that Dbc can be no larger than DBC + *cursorp = (Dbc*)new_cursor; + else + DB_ERROR(DbEnv::get_DbEnv(dbc->dbenv), + "Dbc::dup", ret, ON_ERROR_UNKNOWN); + + return (ret); +} + +int Dbc::get(Dbt* key, Dbt *data, u_int32_t _flags) +{ + int ret; + DBC *dbc = this; + + ret = dbc->get(dbc, key, data, _flags); + + if (!DB_RETOK_DBCGET(ret)) { + if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(key)) + DB_ERROR_DBT(DbEnv::get_DbEnv(dbc->dbenv), + "Dbc::get", key, ON_ERROR_UNKNOWN); + else if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(data)) + DB_ERROR_DBT(DbEnv::get_DbEnv(dbc->dbenv), + "Dbc::get", data, ON_ERROR_UNKNOWN); + else + DB_ERROR(DbEnv::get_DbEnv(dbc->dbenv), + "Dbc::get", ret, ON_ERROR_UNKNOWN); + } + + return (ret); +} + +int Dbc::pget(Dbt* key, Dbt *pkey, Dbt *data, u_int32_t _flags) +{ + int ret; + DBC *dbc = this; + + ret = dbc->pget(dbc, key, pkey, data, _flags); + + /* Logic is the same as for Dbc::get - reusing macro. */ + if (!DB_RETOK_DBCGET(ret)) { + if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(key)) + DB_ERROR_DBT(DbEnv::get_DbEnv(dbc->dbenv), + "Dbc::pget", key, ON_ERROR_UNKNOWN); + else if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(data)) + DB_ERROR_DBT(DbEnv::get_DbEnv(dbc->dbenv), + "Dbc::pget", data, ON_ERROR_UNKNOWN); + else + DB_ERROR(DbEnv::get_DbEnv(dbc->dbenv), + "Dbc::pget", ret, ON_ERROR_UNKNOWN); + } + + return (ret); +} + +DBC_METHOD(put, (Dbt* key, Dbt *data, u_int32_t _flags), + (dbc, key, data, _flags), DB_RETOK_DBCPUT) +DBC_METHOD(get_priority, (DB_CACHE_PRIORITY *priorityp), + (dbc, priorityp), DB_RETOK_STD) +DBC_METHOD(set_priority, (DB_CACHE_PRIORITY pri), (dbc, pri), DB_RETOK_STD) diff --git a/src/libs/resiprocate/contrib/db/cxx/cxx_dbt.cpp b/src/libs/resiprocate/contrib/db/cxx/cxx_dbt.cpp new file mode 100644 index 00000000..a3dbf9dc --- /dev/null +++ b/src/libs/resiprocate/contrib/db/cxx/cxx_dbt.cpp @@ -0,0 +1,56 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +#include "dbinc/db_page.h" +#include "dbinc_auto/db_auto.h" +#include "dbinc_auto/crdel_auto.h" +#include "dbinc/db_dispatch.h" +#include "dbinc_auto/db_ext.h" +#include "dbinc_auto/common_ext.h" + +Dbt::Dbt() +{ + DBT *dbt = this; + memset(dbt, 0, sizeof(DBT)); +} + +Dbt::Dbt(void *data_arg, u_int32_t size_arg) +{ + DBT *dbt = this; + memset(dbt, 0, sizeof(DBT)); + set_data(data_arg); + set_size(size_arg); +} + +Dbt::~Dbt() +{ +} + +Dbt::Dbt(const Dbt &that) +{ + const DBT *from = &that; + DBT *to = this; + memcpy(to, from, sizeof(DBT)); +} + +Dbt &Dbt::operator = (const Dbt &that) +{ + if (this != &that) { + const DBT *from = &that; + DBT *to = this; + memcpy(to, from, sizeof(DBT)); + } + return (*this); +} diff --git a/src/libs/resiprocate/contrib/db/cxx/cxx_env.cpp b/src/libs/resiprocate/contrib/db/cxx/cxx_env.cpp new file mode 100644 index 00000000..4276c0a3 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/cxx/cxx_env.cpp @@ -0,0 +1,1217 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/log.h" +#include "dbinc_auto/common_ext.h" +#include "dbinc_auto/log_ext.h" + +#ifdef HAVE_CXX_STDHEADERS +using std::cerr; +#endif + +// Helper macros for simple methods that pass through to the +// underlying C method. They may return an error or raise an exception. +// These macros expect that input _argspec is an argument +// list element (e.g., "char *arg") and that _arglist is the arguments +// that should be passed through to the C method (e.g., "(dbenv, arg)") +// +#define DBENV_METHOD_ERR(_name, _argspec, _arglist, _on_err) \ +int DbEnv::_name _argspec \ +{ \ + DB_ENV *dbenv = unwrap(this); \ + int ret; \ + \ + if ((ret = dbenv->_name _arglist) != 0) { \ + _on_err; \ + } \ + return (ret); \ +} + +#define DBENV_METHOD(_name, _argspec, _arglist) \ + DBENV_METHOD_ERR(_name, _argspec, _arglist, \ + DB_ERROR(this, "DbEnv::" # _name, ret, error_policy())) + +#define DBENV_METHOD_QUIET(_name, _argspec, _arglist) \ +int DbEnv::_name _argspec \ +{ \ + DB_ENV *dbenv = unwrap(this); \ + \ + return (dbenv->_name _arglist); \ +} + +#define DBENV_METHOD_VOID(_name, _argspec, _arglist) \ +void DbEnv::_name _argspec \ +{ \ + DB_ENV *dbenv = unwrap(this); \ + \ + dbenv->_name _arglist; \ +} + +// The reason for a static variable is that some structures +// (like Dbts) have no connection to any Db or DbEnv, so when +// errors occur in their methods, we must have some reasonable +// way to determine whether to throw or return errors. +// +// This variable is taken from flags whenever a DbEnv is constructed. +// Normally there is only one DbEnv per program, and even if not, +// there is typically a single policy of throwing or returning. +// +static int last_known_error_policy = ON_ERROR_UNKNOWN; + +// These 'glue' function are declared as extern "C" so they will +// be compatible with picky compilers that do not allow mixing +// of function pointers to 'C' functions with function pointers +// to C++ functions. +// +extern "C" +void _feedback_intercept_c(DB_ENV *dbenv, int opcode, int pct) +{ + DbEnv::_feedback_intercept(dbenv, opcode, pct); +} + +extern "C" +void _paniccall_intercept_c(DB_ENV *dbenv, int errval) +{ + DbEnv::_paniccall_intercept(dbenv, errval); +} + +extern "C" +void _event_func_intercept_c(DB_ENV *dbenv, u_int32_t event, void *event_info) +{ + DbEnv::_event_func_intercept(dbenv, event, event_info); +} + +extern "C" +void _stream_error_function_c(const DB_ENV *dbenv, + const char *prefix, const char *message) +{ + DbEnv::_stream_error_function(dbenv, prefix, message); +} + +extern "C" +void _stream_message_function_c(const DB_ENV *dbenv, const char *message) +{ + DbEnv::_stream_message_function(dbenv, message); +} + +extern "C" +int _app_dispatch_intercept_c(DB_ENV *dbenv, DBT *dbt, DB_LSN *lsn, db_recops op) +{ + return (DbEnv::_app_dispatch_intercept(dbenv, dbt, lsn, op)); +} + +extern "C" +int _rep_send_intercept_c(DB_ENV *dbenv, const DBT *cntrl, const DBT *data, + const DB_LSN *lsn, int id, u_int32_t flags) +{ + return (DbEnv::_rep_send_intercept(dbenv, + cntrl, data, lsn, id, flags)); +} + +extern "C" +int _isalive_intercept_c( + DB_ENV *dbenv, pid_t pid, db_threadid_t thrid, u_int32_t flags) +{ + return (DbEnv::_isalive_intercept(dbenv, pid, thrid, flags)); +} + +extern "C" +void _thread_id_intercept_c(DB_ENV *dbenv, pid_t *pidp, db_threadid_t *thridp) +{ + DbEnv::_thread_id_intercept(dbenv, pidp, thridp); +} + +extern "C" +char *_thread_id_string_intercept_c(DB_ENV *dbenv, pid_t pid, + db_threadid_t thrid, char *buf) +{ + return (DbEnv::_thread_id_string_intercept(dbenv, pid, thrid, buf)); +} + +void DbEnv::_feedback_intercept(DB_ENV *dbenv, int opcode, int pct) +{ + DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(0, + "DbEnv::feedback_callback", EINVAL, ON_ERROR_UNKNOWN); + return; + } + if (cxxenv->feedback_callback_ == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), + "DbEnv::feedback_callback", EINVAL, cxxenv->error_policy()); + return; + } + (*cxxenv->feedback_callback_)(cxxenv, opcode, pct); +} + +void DbEnv::_paniccall_intercept(DB_ENV *dbenv, int errval) +{ + DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(0, + "DbEnv::paniccall_callback", EINVAL, ON_ERROR_UNKNOWN); + return; + } + if (cxxenv->paniccall_callback_ == 0) { + DB_ERROR(cxxenv, "DbEnv::paniccall_callback", EINVAL, + cxxenv->error_policy()); + return; + } + (*cxxenv->paniccall_callback_)(cxxenv, errval); +} + +void DbEnv::_event_func_intercept( + DB_ENV *dbenv, u_int32_t event, void *event_info) +{ + DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(0, + "DbEnv::event_func_callback", EINVAL, ON_ERROR_UNKNOWN); + return; + } + if (cxxenv->event_func_callback_ == 0) { + DB_ERROR(cxxenv, "DbEnv::event_func_callback", EINVAL, + cxxenv->error_policy()); + return; + } + (*cxxenv->event_func_callback_)(cxxenv, event, event_info); +} + +int DbEnv::_app_dispatch_intercept(DB_ENV *dbenv, DBT *dbt, DB_LSN *lsn, + db_recops op) +{ + DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), + "DbEnv::app_dispatch_callback", EINVAL, ON_ERROR_UNKNOWN); + return (EINVAL); + } + if (cxxenv->app_dispatch_callback_ == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), + "DbEnv::app_dispatch_callback", EINVAL, + cxxenv->error_policy()); + return (EINVAL); + } + Dbt *cxxdbt = (Dbt *)dbt; + DbLsn *cxxlsn = (DbLsn *)lsn; + return ((*cxxenv->app_dispatch_callback_)(cxxenv, cxxdbt, cxxlsn, op)); +} + +int DbEnv::_isalive_intercept( + DB_ENV *dbenv, pid_t pid, db_threadid_t thrid, u_int32_t flags) +{ + DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), + "DbEnv::isalive_callback", EINVAL, ON_ERROR_UNKNOWN); + return (0); + } + return ((*cxxenv->isalive_callback_)(cxxenv, pid, thrid, flags)); +} + +int DbEnv::_rep_send_intercept(DB_ENV *dbenv, const DBT *cntrl, const DBT *data, + const DB_LSN *lsn, int id, u_int32_t flags) +{ + DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), + "DbEnv::rep_send_callback", EINVAL, ON_ERROR_UNKNOWN); + return (EINVAL); + } + const Dbt *cxxcntrl = (const Dbt *)cntrl; + const DbLsn *cxxlsn = (const DbLsn *)lsn; + Dbt *cxxdata = (Dbt *)data; + return ((*cxxenv->rep_send_callback_)(cxxenv, + cxxcntrl, cxxdata, cxxlsn, id, flags)); +} + +void DbEnv::_thread_id_intercept(DB_ENV *dbenv, + pid_t *pidp, db_threadid_t *thridp) +{ + DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), + "DbEnv::thread_id_callback", EINVAL, ON_ERROR_UNKNOWN); + } else + cxxenv->thread_id_callback_(cxxenv, pidp, thridp); +} + +char *DbEnv::_thread_id_string_intercept(DB_ENV *dbenv, + pid_t pid, db_threadid_t thrid, char *buf) +{ + DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), + "DbEnv::thread_id_string_callback", EINVAL, + ON_ERROR_UNKNOWN); + return (NULL); + } + return (cxxenv->thread_id_string_callback_(cxxenv, pid, thrid, buf)); +} + +// A truism for the DbEnv object is that there is a valid +// DB_ENV handle from the constructor until close(). +// After the close, the DB_ENV handle is invalid and +// no operations are permitted on the DbEnv (other than +// destructor). Leaving the DbEnv handle open and not +// doing a close is generally considered an error. +// +// We used to allow DbEnv objects to be closed and reopened. +// This implied always keeping a valid DB_ENV object, and +// coordinating the open objects between Db/DbEnv turned +// out to be overly complicated. Now we do not allow this. + +DbEnv::DbEnv(u_int32_t flags) +: imp_(0) +, construct_error_(0) +, construct_flags_(flags) +, error_stream_(0) +, message_stream_(0) +, app_dispatch_callback_(0) +, feedback_callback_(0) +, paniccall_callback_(0) +, event_func_callback_(0) +, rep_send_callback_(0) +{ + if ((construct_error_ = initialize(0)) != 0) + DB_ERROR(this, "DbEnv::DbEnv", construct_error_, + error_policy()); +} + +DbEnv::DbEnv(DB_ENV *dbenv, u_int32_t flags) +: imp_(0) +, construct_error_(0) +, construct_flags_(flags) +, error_stream_(0) +, message_stream_(0) +, app_dispatch_callback_(0) +, feedback_callback_(0) +, paniccall_callback_(0) +, event_func_callback_(0) +, rep_send_callback_(0) +{ + if ((construct_error_ = initialize(dbenv)) != 0) + DB_ERROR(this, "DbEnv::DbEnv", construct_error_, + error_policy()); +} + +// If the DB_ENV handle is still open, we close it. This is to make stack +// allocation of DbEnv objects easier so that they are cleaned up in the error +// path. Note that the C layer catches cases where handles are open in the +// environment at close time and reports an error. Applications should call +// close explicitly in normal (non-exceptional) cases to check the return +// value. +// +DbEnv::~DbEnv() +{ + DB_ENV *dbenv = unwrap(this); + + if (dbenv != NULL) { + (void)dbenv->close(dbenv, 0); + cleanup(); + } +} + +// called by destructors before the DB_ENV is destroyed. +void DbEnv::cleanup() +{ + imp_ = 0; +} + +int DbEnv::close(u_int32_t flags) +{ + int ret; + DB_ENV *dbenv = unwrap(this); + + ret = dbenv->close(dbenv, flags); + + // after a close (no matter if success or failure), + // the underlying DB_ENV object must not be accessed. + cleanup(); + + // It's safe to throw an error after the close, + // since our error mechanism does not peer into + // the DB* structures. + // + if (ret != 0) + DB_ERROR(this, "DbEnv::close", ret, error_policy()); + + return (ret); +} + +DBENV_METHOD(dbremove, + (DbTxn *txn, const char *name, const char *subdb, u_int32_t flags), + (dbenv, unwrap(txn), name, subdb, flags)) +DBENV_METHOD(dbrename, (DbTxn *txn, const char *name, const char *subdb, + const char *newname, u_int32_t flags), + (dbenv, unwrap(txn), name, subdb, newname, flags)) + +void DbEnv::err(int error, const char *format, ...) +{ + DB_ENV *dbenv = unwrap(this); + + DB_REAL_ERR(dbenv, error, DB_ERROR_SET, 1, format); +} + +// Return a tristate value corresponding to whether we should +// throw exceptions on errors: +// ON_ERROR_RETURN +// ON_ERROR_THROW +// ON_ERROR_UNKNOWN +// +int DbEnv::error_policy() +{ + if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) { + return (ON_ERROR_RETURN); + } + else { + return (ON_ERROR_THROW); + } +} + +void DbEnv::errx(const char *format, ...) +{ + DB_ENV *dbenv = unwrap(this); + + DB_REAL_ERR(dbenv, 0, DB_ERROR_NOT_SET, 1, format); +} + +void *DbEnv::get_app_private() const +{ + return unwrapConst(this)->app_private; +} + +DBENV_METHOD(failchk, (u_int32_t flags), (dbenv, flags)) +DBENV_METHOD(fileid_reset, (const char *file, u_int32_t flags), + (dbenv, file, flags)) +DBENV_METHOD(get_home, (const char **homep), (dbenv, homep)) +DBENV_METHOD(get_open_flags, (u_int32_t *flagsp), (dbenv, flagsp)) +DBENV_METHOD(get_data_dirs, (const char ***dirspp), (dbenv, dirspp)) + +bool DbEnv::is_bigendian() +{ + return unwrap(this)->is_bigendian() ? true : false; +} + +DBENV_METHOD(get_thread_count, (u_int32_t *count), (dbenv, count)) +DBENV_METHOD(set_thread_count, (u_int32_t count), (dbenv, count)) + +// used internally during constructor +// to associate an existing DB_ENV with this DbEnv, +// or create a new one. +// +int DbEnv::initialize(DB_ENV *dbenv) +{ + int ret; + + last_known_error_policy = error_policy(); + + if (dbenv == 0) { + // Create a new DB_ENV environment. + if ((ret = ::db_env_create(&dbenv, + construct_flags_ & ~DB_CXX_NO_EXCEPTIONS)) != 0) + return (ret); + } + imp_ = dbenv; + dbenv->api1_internal = this; // for DB_ENV* to DbEnv* conversion + return (0); +} + +// lock methods +DBENV_METHOD(lock_detect, (u_int32_t flags, u_int32_t atype, int *aborted), + (dbenv, flags, atype, aborted)) +DBENV_METHOD_ERR(lock_get, + (u_int32_t locker, u_int32_t flags, Dbt *obj, + db_lockmode_t lock_mode, DbLock *lock), + (dbenv, locker, flags, obj, lock_mode, &lock->lock_), + DbEnv::runtime_error_lock_get(this, "DbEnv::lock_get", ret, + DB_LOCK_GET, lock_mode, obj, *lock, + -1, error_policy())) +DBENV_METHOD(lock_id, (u_int32_t *idp), (dbenv, idp)) +DBENV_METHOD(lock_id_free, (u_int32_t id), (dbenv, id)) +DBENV_METHOD(lock_put, (DbLock *lock), (dbenv, &lock->lock_)) +DBENV_METHOD(lock_stat, (DB_LOCK_STAT **statp, u_int32_t flags), + (dbenv, statp, flags)) +DBENV_METHOD(lock_stat_print, (u_int32_t flags), (dbenv, flags)) +DBENV_METHOD_ERR(lock_vec, + (u_int32_t locker, u_int32_t flags, DB_LOCKREQ list[], + int nlist, DB_LOCKREQ **elist_returned), + (dbenv, locker, flags, list, nlist, elist_returned), + DbEnv::runtime_error_lock_get(this, "DbEnv::lock_vec", ret, + (*elist_returned)->op, (*elist_returned)->mode, + Dbt::get_Dbt((*elist_returned)->obj), DbLock((*elist_returned)->lock), + (int)((*elist_returned) - list), error_policy())) +// log methods +DBENV_METHOD(log_archive, (char **list[], u_int32_t flags), + (dbenv, list, flags)) + +int DbEnv::log_compare(const DbLsn *lsn0, const DbLsn *lsn1) +{ + return (::log_compare(lsn0, lsn1)); +} + +// The following cast implies that DbLogc can be no larger than DB_LOGC +DBENV_METHOD(log_cursor, (DbLogc **cursorp, u_int32_t flags), + (dbenv, (DB_LOGC **)cursorp, flags)) +DBENV_METHOD(log_file, (DbLsn *lsn, char *namep, size_t len), + (dbenv, lsn, namep, len)) +DBENV_METHOD(log_flush, (const DbLsn *lsn), (dbenv, lsn)) +DBENV_METHOD(log_get_config, (u_int32_t which, int *onoffp), + (dbenv, which, onoffp)) +DBENV_METHOD(log_put, (DbLsn *lsn, const Dbt *data, u_int32_t flags), + (dbenv, lsn, data, flags)) + +int DbEnv::log_printf(DbTxn *txn, const char *fmt, ...) +{ + DB_ENV *dbenv = unwrap(this); + va_list ap; + int ret; + + va_start(ap, fmt); + ret = __log_printf_pp(dbenv, unwrap(txn), fmt, ap); + va_end(ap); + + return (ret); +} + +DBENV_METHOD(log_set_config, (u_int32_t which, int onoff), + (dbenv, which, onoff)) +DBENV_METHOD(log_stat, (DB_LOG_STAT **spp, u_int32_t flags), + (dbenv, spp, flags)) +DBENV_METHOD(log_stat_print, (u_int32_t flags), (dbenv, flags)) + +DBENV_METHOD(lsn_reset, (const char *file, u_int32_t flags), + (dbenv, file, flags)) + +int DbEnv::memp_fcreate(DbMpoolFile **dbmfp, u_int32_t flags) +{ + DB_ENV *dbenv = unwrap(this); + int ret; + DB_MPOOLFILE *mpf; + + if (dbenv == NULL) + ret = EINVAL; + else + ret = dbenv->memp_fcreate(dbenv, &mpf, flags); + + if (DB_RETOK_STD(ret)) { + *dbmfp = new DbMpoolFile(); + (*dbmfp)->imp_ = mpf; + } else + DB_ERROR(this, "DbMpoolFile::f_create", ret, ON_ERROR_UNKNOWN); + + return (ret); +} + +DBENV_METHOD(memp_register, + (int ftype, pgin_fcn_type pgin_fcn, pgout_fcn_type pgout_fcn), + (dbenv, ftype, pgin_fcn, pgout_fcn)) + +// memory pool methods +DBENV_METHOD(memp_stat, + (DB_MPOOL_STAT **gsp, DB_MPOOL_FSTAT ***fsp, u_int32_t flags), + (dbenv, gsp, fsp, flags)) +DBENV_METHOD(memp_stat_print, (u_int32_t flags), (dbenv, flags)) +DBENV_METHOD(memp_sync, (DbLsn *sn), (dbenv, sn)) +DBENV_METHOD(memp_trickle, (int pct, int *nwrotep), (dbenv, pct, nwrotep)) + +// If an error occurred during the constructor, report it now. +// Otherwise, call the underlying DB->open method. +// +int DbEnv::open(const char *db_home, u_int32_t flags, int mode) +{ + int ret; + DB_ENV *dbenv = unwrap(this); + + if (construct_error_ != 0) + ret = construct_error_; + else + ret = dbenv->open(dbenv, db_home, flags, mode); + + if (!DB_RETOK_STD(ret)) + DB_ERROR(this, "DbEnv::open", ret, error_policy()); + + return (ret); +} + +int DbEnv::remove(const char *db_home, u_int32_t flags) +{ + int ret; + DB_ENV *dbenv = unwrap(this); + + ret = dbenv->remove(dbenv, db_home, flags); + + // after a remove (no matter if success or failure), + // the underlying DB_ENV object must not be accessed, + // so we clean up in advance. + // + cleanup(); + + if (ret != 0) + DB_ERROR(this, "DbEnv::remove", ret, error_policy()); + + return (ret); +} + +// Report an error associated with the DbEnv. +// error_policy is one of: +// ON_ERROR_THROW throw an error +// ON_ERROR_RETURN do nothing here, the caller will return an error +// ON_ERROR_UNKNOWN defer the policy to policy saved in DbEnv::DbEnv +// +void DbEnv::runtime_error(DbEnv *dbenv, + const char *caller, int error, int error_policy) +{ + if (error_policy == ON_ERROR_UNKNOWN) + error_policy = last_known_error_policy; + if (error_policy == ON_ERROR_THROW) { + // Creating and throwing the object in two separate + // statements seems to be necessary for HP compilers. + switch (error) { + case DB_LOCK_DEADLOCK: + { + DbDeadlockException dl_except(caller); + dl_except.set_env(dbenv); + throw dl_except; + } + case DB_LOCK_NOTGRANTED: + { + DbLockNotGrantedException lng_except(caller); + lng_except.set_env(dbenv); + throw lng_except; + } + case DB_REP_HANDLE_DEAD: + { + DbRepHandleDeadException hd_except(caller); + hd_except.set_env(dbenv); + throw hd_except; + } + case DB_RUNRECOVERY: + { + DbRunRecoveryException rr_except(caller); + rr_except.set_env(dbenv); + throw rr_except; + } + default: + { + DbException except(caller, error); + except.set_env(dbenv); + throw except; + } + } + } +} + +// Like DbEnv::runtime_error, but issue a DbMemoryException +// based on the fact that this Dbt is not large enough. +void DbEnv::runtime_error_dbt(DbEnv *dbenv, + const char *caller, Dbt *dbt, int error_policy) +{ + if (error_policy == ON_ERROR_UNKNOWN) + error_policy = last_known_error_policy; + if (error_policy == ON_ERROR_THROW) { + // Creating and throwing the object in two separate + // statements seems to be necessary for HP compilers. + DbMemoryException except(caller, dbt); + except.set_env(dbenv); + throw except; + } +} + +// Like DbEnv::runtime_error, but issue a DbLockNotGrantedException, +// or a regular runtime error. +// call regular runtime_error if it +void DbEnv::runtime_error_lock_get(DbEnv *dbenv, + const char *caller, int error, + db_lockop_t op, db_lockmode_t mode, Dbt *obj, + DbLock lock, int index, int error_policy) +{ + if (error != DB_LOCK_NOTGRANTED) { + runtime_error(dbenv, caller, error, error_policy); + return; + } + + if (error_policy == ON_ERROR_UNKNOWN) + error_policy = last_known_error_policy; + if (error_policy == ON_ERROR_THROW) { + // Creating and throwing the object in two separate + // statements seems to be necessary for HP compilers. + DbLockNotGrantedException except(caller, op, mode, + obj, lock, index); + except.set_env(dbenv); + throw except; + } +} + +void DbEnv::_stream_error_function( + const DB_ENV *dbenv, const char *prefix, const char *message) +{ + const DbEnv *cxxenv = DbEnv::get_const_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(0, + "DbEnv::stream_error", EINVAL, ON_ERROR_UNKNOWN); + return; + } + + if (cxxenv->error_callback_) + cxxenv->error_callback_(cxxenv, prefix, message); + else if (cxxenv->error_stream_) { + // HP compilers need the extra casts, we don't know why. + if (prefix) { + (*cxxenv->error_stream_) << prefix; + (*cxxenv->error_stream_) << (const char *)": "; + } + if (message) + (*cxxenv->error_stream_) << (const char *)message; + (*cxxenv->error_stream_) << (const char *)"\n"; + } +} + +void DbEnv::_stream_message_function(const DB_ENV *dbenv, const char *message) +{ + const DbEnv *cxxenv = DbEnv::get_const_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(0, + "DbEnv::stream_message", EINVAL, ON_ERROR_UNKNOWN); + return; + } + + if (cxxenv->message_callback_) + cxxenv->message_callback_(cxxenv, message); + else if (cxxenv->message_stream_) { + // HP compilers need the extra casts, we don't know why. + (*cxxenv->message_stream_) << (const char *)message; + (*cxxenv->message_stream_) << (const char *)"\n"; + } +} + +// static method +char *DbEnv::strerror(int error) +{ + return (db_strerror(error)); +} + +// We keep these alphabetical by field name, +// for comparison with Java's list. +// +DBENV_METHOD(set_data_dir, (const char *dir), (dbenv, dir)) +DBENV_METHOD(get_encrypt_flags, (u_int32_t *flagsp), + (dbenv, flagsp)) +DBENV_METHOD(set_encrypt, (const char *passwd, u_int32_t flags), + (dbenv, passwd, flags)) +DBENV_METHOD_VOID(get_errfile, (FILE **errfilep), (dbenv, errfilep)) +DBENV_METHOD_VOID(set_errfile, (FILE *errfile), (dbenv, errfile)) +DBENV_METHOD_VOID(get_errpfx, (const char **errpfxp), (dbenv, errpfxp)) +DBENV_METHOD_VOID(set_errpfx, (const char *errpfx), (dbenv, errpfx)) +DBENV_METHOD(get_intermediate_dir_mode, (const char **modep), (dbenv, modep)) +DBENV_METHOD(set_intermediate_dir_mode, (const char *mode), (dbenv, mode)) +DBENV_METHOD(get_lg_bsize, (u_int32_t *bsizep), (dbenv, bsizep)) +DBENV_METHOD(set_lg_bsize, (u_int32_t bsize), (dbenv, bsize)) +DBENV_METHOD(get_lg_dir, (const char **dirp), (dbenv, dirp)) +DBENV_METHOD(set_lg_dir, (const char *dir), (dbenv, dir)) +DBENV_METHOD(get_lg_filemode, (int *modep), (dbenv, modep)) +DBENV_METHOD(set_lg_filemode, (int mode), (dbenv, mode)) +DBENV_METHOD(get_lg_max, (u_int32_t *maxp), (dbenv, maxp)) +DBENV_METHOD(set_lg_max, (u_int32_t max), (dbenv, max)) +DBENV_METHOD(get_lg_regionmax, (u_int32_t *regionmaxp), (dbenv, regionmaxp)) +DBENV_METHOD(set_lg_regionmax, (u_int32_t regionmax), (dbenv, regionmax)) +DBENV_METHOD(get_lk_conflicts, (const u_int8_t **lk_conflictsp, int *lk_maxp), + (dbenv, lk_conflictsp, lk_maxp)) +DBENV_METHOD(set_lk_conflicts, (u_int8_t *lk_conflicts, int lk_max), + (dbenv, lk_conflicts, lk_max)) +DBENV_METHOD(get_lk_detect, (u_int32_t *detectp), (dbenv, detectp)) +DBENV_METHOD(set_lk_detect, (u_int32_t detect), (dbenv, detect)) +DBENV_METHOD(get_lk_max_lockers, (u_int32_t *max_lockersp), + (dbenv, max_lockersp)) +DBENV_METHOD(set_lk_max_lockers, (u_int32_t max_lockers), (dbenv, max_lockers)) +DBENV_METHOD(get_lk_max_locks, (u_int32_t *max_locksp), (dbenv, max_locksp)) +DBENV_METHOD(set_lk_max_locks, (u_int32_t max_locks), (dbenv, max_locks)) +DBENV_METHOD(get_lk_max_objects, (u_int32_t *max_objectsp), + (dbenv, max_objectsp)) +DBENV_METHOD(set_lk_max_objects, (u_int32_t max_objects), (dbenv, max_objects)) +DBENV_METHOD(get_lk_partitions, (u_int32_t *partitionsp), (dbenv, partitionsp)) +DBENV_METHOD(set_lk_partitions, (u_int32_t partitions), (dbenv, partitions)) +DBENV_METHOD(get_mp_max_openfd, (int *maxopenfdp), (dbenv, maxopenfdp)) +DBENV_METHOD(set_mp_max_openfd, (int maxopenfd), (dbenv, maxopenfd)) +DBENV_METHOD(get_mp_max_write, (int *maxwritep, db_timeout_t *maxwrite_sleepp), + (dbenv, maxwritep, maxwrite_sleepp)) +DBENV_METHOD(set_mp_max_write, (int maxwrite, db_timeout_t maxwrite_sleep), + (dbenv, maxwrite, maxwrite_sleep)) +DBENV_METHOD(get_mp_mmapsize, (size_t *mmapsizep), (dbenv, mmapsizep)) +DBENV_METHOD(set_mp_mmapsize, (size_t mmapsize), (dbenv, mmapsize)) +DBENV_METHOD(get_mp_pagesize, (u_int32_t *pagesizep), (dbenv, pagesizep)) +DBENV_METHOD(set_mp_pagesize, (u_int32_t pagesize), (dbenv, pagesize)) +DBENV_METHOD(get_mp_tablesize, (u_int32_t *tablesizep), (dbenv, tablesizep)) +DBENV_METHOD(set_mp_tablesize, (u_int32_t tablesize), (dbenv, tablesize)) +DBENV_METHOD_VOID(get_msgfile, (FILE **msgfilep), (dbenv, msgfilep)) +DBENV_METHOD_VOID(set_msgfile, (FILE *msgfile), (dbenv, msgfile)) +DBENV_METHOD(get_tmp_dir, (const char **tmp_dirp), (dbenv, tmp_dirp)) +DBENV_METHOD(set_tmp_dir, (const char *tmp_dir), (dbenv, tmp_dir)) +DBENV_METHOD(get_tx_max, (u_int32_t *tx_maxp), (dbenv, tx_maxp)) +DBENV_METHOD(set_tx_max, (u_int32_t tx_max), (dbenv, tx_max)) + +DBENV_METHOD(stat_print, (u_int32_t flags), (dbenv, flags)) + +DBENV_METHOD_QUIET(get_alloc, + (db_malloc_fcn_type *malloc_fcnp, db_realloc_fcn_type *realloc_fcnp, + db_free_fcn_type *free_fcnp), + (dbenv, malloc_fcnp, realloc_fcnp, free_fcnp)) + +DBENV_METHOD_QUIET(set_alloc, + (db_malloc_fcn_type malloc_fcn, db_realloc_fcn_type realloc_fcn, + db_free_fcn_type free_fcn), + (dbenv, malloc_fcn, realloc_fcn, free_fcn)) + +void DbEnv::set_app_private(void *value) +{ + unwrap(this)->app_private = value; +} + +DBENV_METHOD(get_cachesize, + (u_int32_t *gbytesp, u_int32_t *bytesp, int *ncachep), + (dbenv, gbytesp, bytesp, ncachep)) +DBENV_METHOD(set_cachesize, + (u_int32_t gbytes, u_int32_t bytes, int ncache), + (dbenv, gbytes, bytes, ncache)) +DBENV_METHOD(get_cache_max, (u_int32_t *gbytesp, u_int32_t *bytesp), + (dbenv, gbytesp, bytesp)) +DBENV_METHOD(set_cache_max, (u_int32_t gbytes, u_int32_t bytes), + (dbenv, gbytes, bytes)) +DBENV_METHOD(get_create_dir, (const char **dirp), (dbenv, dirp)) +DBENV_METHOD(set_create_dir, (const char *dir), (dbenv, dir)) + +void DbEnv::get_errcall(void (**argp)(const DbEnv *, const char *, const char *)) +{ + if (argp != NULL) + *argp = error_callback_; + return; +} + +void DbEnv::set_errcall(void (*arg)(const DbEnv *, const char *, const char *)) +{ + DB_ENV *dbenv = unwrap(this); + + error_callback_ = arg; + error_stream_ = 0; + + dbenv->set_errcall(dbenv, (arg == 0) ? 0 : + _stream_error_function_c); +} + +__DB_STD(ostream) *DbEnv::get_error_stream() +{ + return (error_stream_); +} + +void DbEnv::set_error_stream(__DB_STD(ostream) *stream) +{ + DB_ENV *dbenv = unwrap(this); + + error_stream_ = stream; + error_callback_ = 0; + + dbenv->set_errcall(dbenv, (stream == 0) ? 0 : + _stream_error_function_c); +} + +int DbEnv::get_feedback(void (**argp)(DbEnv *, int, int)) +{ + if (argp != NULL) + *argp = feedback_callback_; + return 0; +} + +int DbEnv::set_feedback(void (*arg)(DbEnv *, int, int)) +{ + DB_ENV *dbenv = unwrap(this); + + feedback_callback_ = arg; + + return (dbenv->set_feedback(dbenv, + arg == 0 ? 0 : _feedback_intercept_c)); +} + +DBENV_METHOD(get_flags, (u_int32_t *flagsp), (dbenv, flagsp)) +DBENV_METHOD(set_flags, (u_int32_t flags, int onoff), (dbenv, flags, onoff)) + +void DbEnv::get_msgcall(void (**argp)(const DbEnv *, const char *)) +{ + if (argp != NULL) + *argp = message_callback_; +} + +void DbEnv::set_msgcall(void (*arg)(const DbEnv *, const char *)) +{ + DB_ENV *dbenv = unwrap(this); + + message_callback_ = arg; + message_stream_ = 0; + + dbenv->set_msgcall(dbenv, (arg == 0) ? 0 : + _stream_message_function_c); +} + +__DB_STD(ostream) *DbEnv::get_message_stream() +{ + return (message_stream_); +} + +void DbEnv::set_message_stream(__DB_STD(ostream) *stream) +{ + DB_ENV *dbenv = unwrap(this); + + message_stream_ = stream; + message_callback_ = 0; + + dbenv->set_msgcall(dbenv, (stream == 0) ? 0 : + _stream_message_function_c); +} + +int DbEnv::set_paniccall(void (*arg)(DbEnv *, int)) +{ + DB_ENV *dbenv = unwrap(this); + + paniccall_callback_ = arg; + + return (dbenv->set_paniccall(dbenv, + arg == 0 ? 0 : _paniccall_intercept_c)); +} + +int DbEnv::set_event_notify(void (*arg)(DbEnv *, u_int32_t, void *)) +{ + DB_ENV *dbenv = unwrap(this); + + event_func_callback_ = arg; + + return (dbenv->set_event_notify(dbenv, + arg == 0 ? 0 : _event_func_intercept_c)); +} + +DBENV_METHOD(set_rpc_server, + (void *cl, char *host, long tsec, long ssec, u_int32_t flags), + (dbenv, cl, host, tsec, ssec, flags)) +DBENV_METHOD(get_shm_key, (long *shm_keyp), (dbenv, shm_keyp)) +DBENV_METHOD(set_shm_key, (long shm_key), (dbenv, shm_key)) + +int DbEnv::get_app_dispatch + (int (**argp)(DbEnv *, Dbt *, DbLsn *, db_recops)) +{ + if (argp != NULL) + *argp = app_dispatch_callback_; + return 0; +} + +int DbEnv::set_app_dispatch + (int (*arg)(DbEnv *, Dbt *, DbLsn *, db_recops)) +{ + DB_ENV *dbenv = unwrap(this); + int ret; + + app_dispatch_callback_ = arg; + if ((ret = dbenv->set_app_dispatch(dbenv, + arg == 0 ? 0 : _app_dispatch_intercept_c)) != 0) + DB_ERROR(this, "DbEnv::set_app_dispatch", ret, error_policy()); + + return (ret); +} + +int DbEnv::get_isalive + (int (**argp)(DbEnv *, pid_t, db_threadid_t, u_int32_t)) +{ + if (argp != NULL) + *argp = isalive_callback_; + return 0; +} + +int DbEnv::set_isalive + (int (*arg)(DbEnv *, pid_t, db_threadid_t, u_int32_t)) +{ + DB_ENV *dbenv = unwrap(this); + int ret; + + isalive_callback_ = arg; + if ((ret = dbenv->set_isalive(dbenv, + arg == 0 ? 0 : _isalive_intercept_c)) != 0) + DB_ERROR(this, "DbEnv::set_isalive", ret, error_policy()); + + return (ret); +} + +DBENV_METHOD(get_tx_timestamp, (time_t *timestamp), (dbenv, timestamp)) +DBENV_METHOD(set_tx_timestamp, (time_t *timestamp), (dbenv, timestamp)) +DBENV_METHOD(get_verbose, (u_int32_t which, int *onoffp), + (dbenv, which, onoffp)) +DBENV_METHOD(set_verbose, (u_int32_t which, int onoff), (dbenv, which, onoff)) + +DBENV_METHOD(mutex_alloc, + (u_int32_t flags, db_mutex_t *mutexp), (dbenv, flags, mutexp)) +DBENV_METHOD(mutex_free, (db_mutex_t mutex), (dbenv, mutex)) +DBENV_METHOD(mutex_get_align, (u_int32_t *argp), (dbenv, argp)) +DBENV_METHOD(mutex_get_increment, (u_int32_t *argp), (dbenv, argp)) +DBENV_METHOD(mutex_get_max, (u_int32_t *argp), (dbenv, argp)) +DBENV_METHOD(mutex_get_tas_spins, (u_int32_t *argp), (dbenv, argp)) +DBENV_METHOD(mutex_lock, (db_mutex_t mutex), (dbenv, mutex)) +DBENV_METHOD(mutex_set_align, (u_int32_t arg), (dbenv, arg)) +DBENV_METHOD(mutex_set_increment, (u_int32_t arg), (dbenv, arg)) +DBENV_METHOD(mutex_set_max, (u_int32_t arg), (dbenv, arg)) +DBENV_METHOD(mutex_set_tas_spins, (u_int32_t arg), (dbenv, arg)) +DBENV_METHOD(mutex_stat, + (DB_MUTEX_STAT **statp, u_int32_t flags), (dbenv, statp, flags)) +DBENV_METHOD(mutex_stat_print, (u_int32_t flags), (dbenv, flags)) +DBENV_METHOD(mutex_unlock, (db_mutex_t mutex), (dbenv, mutex)) + +int DbEnv::get_thread_id_fn(void (**argp)(DbEnv *, pid_t *, db_threadid_t *)) +{ + if (argp != NULL) + *argp = thread_id_callback_; + return 0; +} + +int DbEnv::set_thread_id(void (*arg)(DbEnv *, pid_t *, db_threadid_t *)) +{ + DB_ENV *dbenv = unwrap(this); + int ret; + + thread_id_callback_ = arg; + if ((ret = dbenv->set_thread_id(dbenv, + arg == 0 ? 0 : _thread_id_intercept_c)) != 0) + DB_ERROR(this, "DbEnv::set_thread_id", ret, error_policy()); + + return (ret); +} + +int DbEnv::get_thread_id_string_fn( + char *(**argp)(DbEnv *, pid_t, db_threadid_t, char *)) +{ + if (argp != NULL) + *argp = thread_id_string_callback_; + return 0; +} + +int DbEnv::set_thread_id_string( + char *(*arg)(DbEnv *, pid_t, db_threadid_t, char *)) +{ + DB_ENV *dbenv = unwrap(this); + int ret; + + thread_id_string_callback_ = arg; + if ((ret = dbenv->set_thread_id_string(dbenv, + arg == 0 ? 0 : _thread_id_string_intercept_c)) != 0) + DB_ERROR(this, "DbEnv::set_thread_id_string", ret, + error_policy()); + + return (ret); +} + +DBENV_METHOD(add_data_dir, (const char *dir), (dbenv, dir)) + +int DbEnv::cdsgroup_begin(DbTxn **tid) +{ + DB_ENV *dbenv = unwrap(this); + DB_TXN *txn; + int ret; + + ret = dbenv->cdsgroup_begin(dbenv, &txn); + if (DB_RETOK_STD(ret)) + *tid = new DbTxn(txn, NULL); + else + DB_ERROR(this, "DbEnv::cdsgroup_begin", ret, error_policy()); + + return (ret); +} + +int DbEnv::txn_begin(DbTxn *pid, DbTxn **tid, u_int32_t flags) +{ + DB_ENV *dbenv = unwrap(this); + DB_TXN *txn; + int ret; + + ret = dbenv->txn_begin(dbenv, unwrap(pid), &txn, flags); + if (DB_RETOK_STD(ret)) + *tid = new DbTxn(txn, pid); + else + DB_ERROR(this, "DbEnv::txn_begin", ret, error_policy()); + + return (ret); +} + +DBENV_METHOD(txn_checkpoint, (u_int32_t kbyte, u_int32_t min, u_int32_t flags), + (dbenv, kbyte, min, flags)) + +int DbEnv::txn_recover(DbPreplist *preplist, u_int32_t count, + u_int32_t *retp, u_int32_t flags) +{ + DB_ENV *dbenv = unwrap(this); + DB_PREPLIST *c_preplist; + u_int32_t i; + int ret; + + /* + * We need to allocate some local storage for the + * returned preplist, and that requires us to do + * our own argument validation. + */ + if (count <= 0) + ret = EINVAL; + else + ret = __os_malloc(dbenv->env, sizeof(DB_PREPLIST) * count, + &c_preplist); + + if (ret != 0) { + DB_ERROR(this, "DbEnv::txn_recover", ret, error_policy()); + return (ret); + } + + if ((ret = + dbenv->txn_recover(dbenv, c_preplist, count, retp, flags)) != 0) { + __os_free(dbenv->env, c_preplist); + DB_ERROR(this, "DbEnv::txn_recover", ret, error_policy()); + return (ret); + } + + for (i = 0; i < *retp; i++) { + preplist[i].txn = new DbTxn(NULL); + preplist[i].txn->imp_ = c_preplist[i].txn; + memcpy(preplist[i].gid, c_preplist[i].gid, + sizeof(preplist[i].gid)); + } + + __os_free(dbenv->env, c_preplist); + + return (0); +} + +DBENV_METHOD(txn_stat, (DB_TXN_STAT **statp, u_int32_t flags), + (dbenv, statp, flags)) +DBENV_METHOD(txn_stat_print, (u_int32_t flags), (dbenv, flags)) + +int DbEnv::rep_set_transport(int myid, int (*arg)(DbEnv *, + const Dbt *, const Dbt *, const DbLsn *, int, u_int32_t)) +{ + DB_ENV *dbenv = unwrap(this); + int ret; + + rep_send_callback_ = arg; + if ((ret = dbenv->rep_set_transport(dbenv, myid, + arg == 0 ? 0 : _rep_send_intercept_c)) != 0) + DB_ERROR(this, "DbEnv::rep_set_transport", ret, error_policy()); + + return (ret); +} + +DBENV_METHOD(rep_elect, (u_int32_t nsites, u_int32_t nvotes, u_int32_t flags), + (dbenv, nsites, nvotes, flags)) +DBENV_METHOD(rep_flush, (), (dbenv)) +DBENV_METHOD(rep_get_config, (u_int32_t which, int *onoffp), + (dbenv, which, onoffp)) +DBENV_METHOD(rep_get_request, (u_int32_t *min, u_int32_t *max), + (dbenv, min, max)) +DBENV_METHOD(rep_set_request, (u_int32_t min, u_int32_t max), (dbenv, min, max)) + +int DbEnv::rep_process_message(Dbt *control, + Dbt *rec, int id, DbLsn *ret_lsnp) +{ + DB_ENV *dbenv = unwrap(this); + int ret; + + ret = dbenv->rep_process_message(dbenv, control, rec, id, ret_lsnp); + if (!DB_RETOK_REPPMSG(ret)) + DB_ERROR(this, "DbEnv::rep_process_message", ret, + error_policy()); + + return (ret); +} + +DBENV_METHOD(rep_set_config, + (u_int32_t which, int onoff), (dbenv, which, onoff)) +DBENV_METHOD(rep_start, + (Dbt *cookie, u_int32_t flags), + (dbenv, (DBT *)cookie, flags)) + +DBENV_METHOD(rep_stat, (DB_REP_STAT **statp, u_int32_t flags), + (dbenv, statp, flags)) +DBENV_METHOD(rep_stat_print, (u_int32_t flags), (dbenv, flags)) +DBENV_METHOD(rep_sync, (u_int32_t flags), (dbenv, flags)) + +DBENV_METHOD(rep_get_clockskew, (u_int32_t *fast_clockp, u_int32_t *slow_clockp), + (dbenv, fast_clockp, slow_clockp)) +DBENV_METHOD(rep_set_clockskew, (u_int32_t fast_clock, u_int32_t slow_clock), + (dbenv, fast_clock, slow_clock)) +DBENV_METHOD(rep_get_limit, (u_int32_t *gbytesp, u_int32_t *bytesp), + (dbenv, gbytesp, bytesp)) +DBENV_METHOD(rep_set_limit, (u_int32_t gbytes, u_int32_t bytes), + (dbenv, gbytes, bytes)) + +// +// Begin advanced replication API method implementations +DBENV_METHOD(rep_get_nsites, (u_int32_t *n), (dbenv, n)) +DBENV_METHOD(rep_set_nsites, (u_int32_t n), (dbenv, n)) +DBENV_METHOD(rep_get_priority, (u_int32_t *priority), + (dbenv, priority)) +DBENV_METHOD(rep_set_priority, (u_int32_t priority), + (dbenv, priority)) +DBENV_METHOD(rep_get_timeout, (int which, db_timeout_t * timeout), + (dbenv, which, timeout)) +DBENV_METHOD(rep_set_timeout, (int which, db_timeout_t timeout), + (dbenv, which, timeout)) +DBENV_METHOD(repmgr_add_remote_site, (const char* host, u_int16_t port, + int * eidp, u_int32_t flags), (dbenv, host, port, eidp, flags)) +DBENV_METHOD(repmgr_get_ack_policy, (int *policy), (dbenv, policy)) +DBENV_METHOD(repmgr_set_ack_policy, (int policy), (dbenv, policy)) +DBENV_METHOD(repmgr_set_local_site, (const char* host, u_int16_t port, + u_int32_t flags), (dbenv, host, port, flags)) +DBENV_METHOD(repmgr_site_list, (u_int *countp, DB_REPMGR_SITE **listp), + (dbenv, countp, listp)) + +int DbEnv::repmgr_start(int nthreads, u_int32_t flags) +{ + DB_ENV *dbenv = unwrap(this); + int ret; + + ret = dbenv->repmgr_start(dbenv, nthreads, flags); + if (!DB_RETOK_REPMGR_START(ret)) + DB_ERROR(this, "DbEnv::repmgr_start", ret, + error_policy()); + + return (ret); +} + +DBENV_METHOD(repmgr_stat, (DB_REPMGR_STAT **statp, u_int32_t flags), + (dbenv, statp, flags)) +DBENV_METHOD(repmgr_stat_print, (u_int32_t flags), (dbenv, flags)) + +// End advanced replication API method implementations. + +DBENV_METHOD(get_timeout, + (db_timeout_t *timeoutp, u_int32_t flags), + (dbenv, timeoutp, flags)) +DBENV_METHOD(set_timeout, + (db_timeout_t timeout, u_int32_t flags), + (dbenv, timeout, flags)) + +// static method +char *DbEnv::version(int *major, int *minor, int *patch) +{ + return (db_version(major, minor, patch)); +} + +// static method +DbEnv *DbEnv::wrap_DB_ENV(DB_ENV *dbenv) +{ + DbEnv *wrapped_env = get_DbEnv(dbenv); + return (wrapped_env != NULL) ? wrapped_env : new DbEnv(dbenv, 0); +} diff --git a/src/libs/resiprocate/contrib/db/cxx/cxx_except.cpp b/src/libs/resiprocate/contrib/db/cxx/cxx_except.cpp new file mode 100644 index 00000000..a2e73d55 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/cxx/cxx_except.cpp @@ -0,0 +1,356 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +static const int MAX_DESCRIPTION_LENGTH = 1024; + +// Note: would not be needed if we can inherit from exception +// It does not appear to be possible to inherit from exception +// with the current Microsoft library (VC5.0). +// +static char *dupString(const char *s) +{ + char *r = new char[strlen(s)+1]; + strcpy(r, s); + return (r); +} + +//////////////////////////////////////////////////////////////////////// +// // +// DbException // +// // +//////////////////////////////////////////////////////////////////////// + +DbException::~DbException() throw() +{ + delete [] what_; +} + +DbException::DbException(int err) +: err_(err) +, dbenv_(0) +{ + describe(0, 0); +} + +DbException::DbException(const char *description) +: err_(0) +, dbenv_(0) +{ + describe(0, description); +} + +DbException::DbException(const char *description, int err) +: err_(err) +, dbenv_(0) +{ + describe(0, description); +} + +DbException::DbException(const char *prefix, const char *description, int err) +: err_(err) +, dbenv_(0) +{ + describe(prefix, description); +} + +DbException::DbException(const DbException &that) +: __DB_STD(exception)() +, what_(dupString(that.what_)) +, err_(that.err_) +, dbenv_(0) +{ +} + +DbException &DbException::operator = (const DbException &that) +{ + if (this != &that) { + err_ = that.err_; + delete [] what_; + what_ = dupString(that.what_); + } + return (*this); +} + +void DbException::describe(const char *prefix, const char *description) +{ + char *msgbuf, *p, *end; + + msgbuf = new char[MAX_DESCRIPTION_LENGTH]; + p = msgbuf; + end = msgbuf + MAX_DESCRIPTION_LENGTH - 1; + + if (prefix != NULL) { + strncpy(p, prefix, (p < end) ? end - p: 0); + p += strlen(prefix); + strncpy(p, ": ", (p < end) ? end - p: 0); + p += 2; + } + if (description != NULL) { + strncpy(p, description, (p < end) ? end - p: 0); + p += strlen(description); + if (err_ != 0) { + strncpy(p, ": ", (p < end) ? end - p: 0); + p += 2; + } + } + if (err_ != 0) { + strncpy(p, db_strerror(err_), (p < end) ? end - p: 0); + p += strlen(db_strerror(err_)); + } + + /* + * If the result was too long, the buffer will not be null-terminated, + * so we need to fix that here before duplicating it. + */ + if (p >= end) + *end = '\0'; + + what_ = dupString(msgbuf); + delete [] msgbuf; +} + +int DbException::get_errno() const +{ + return (err_); +} + +const char *DbException::what() const throw() +{ + return (what_); +} + +DbEnv *DbException::get_env() const +{ + return dbenv_; +} + +void DbException::set_env(DbEnv *dbenv) +{ + dbenv_= dbenv; +} + +//////////////////////////////////////////////////////////////////////// +// // +// DbMemoryException // +// // +//////////////////////////////////////////////////////////////////////// + +static const char *memory_err_desc = "Dbt not large enough for available data"; +DbMemoryException::~DbMemoryException() throw() +{ +} + +DbMemoryException::DbMemoryException(Dbt *dbt) +: DbException(memory_err_desc, DB_BUFFER_SMALL) +, dbt_(dbt) +{ +} + +DbMemoryException::DbMemoryException(const char *prefix, Dbt *dbt) +: DbException(prefix, memory_err_desc, DB_BUFFER_SMALL) +, dbt_(dbt) +{ +} + +DbMemoryException::DbMemoryException(const DbMemoryException &that) +: DbException(that) +, dbt_(that.dbt_) +{ +} + +DbMemoryException +&DbMemoryException::operator =(const DbMemoryException &that) +{ + if (this != &that) { + DbException::operator=(that); + dbt_ = that.dbt_; + } + return (*this); +} + +Dbt *DbMemoryException::get_dbt() const +{ + return (dbt_); +} + +//////////////////////////////////////////////////////////////////////// +// // +// DbDeadlockException // +// // +//////////////////////////////////////////////////////////////////////// + +DbDeadlockException::~DbDeadlockException() throw() +{ +} + +DbDeadlockException::DbDeadlockException(const char *description) +: DbException(description, DB_LOCK_DEADLOCK) +{ +} + +DbDeadlockException::DbDeadlockException(const DbDeadlockException &that) +: DbException(that) +{ +} + +DbDeadlockException +&DbDeadlockException::operator =(const DbDeadlockException &that) +{ + if (this != &that) + DbException::operator=(that); + return (*this); +} + +//////////////////////////////////////////////////////////////////////// +// // +// DbLockNotGrantedException // +// // +//////////////////////////////////////////////////////////////////////// + +DbLockNotGrantedException::~DbLockNotGrantedException() throw() +{ + delete lock_; +} + +DbLockNotGrantedException::DbLockNotGrantedException(const char *prefix, + db_lockop_t op, db_lockmode_t mode, const Dbt *obj, const DbLock lock, + int index) +: DbException(prefix, DbEnv::strerror(DB_LOCK_NOTGRANTED), + DB_LOCK_NOTGRANTED) +, op_(op) +, mode_(mode) +, obj_(obj) +, lock_(new DbLock(lock)) +, index_(index) +{ +} + +DbLockNotGrantedException::DbLockNotGrantedException(const char *description) +: DbException(description, DB_LOCK_NOTGRANTED) +, op_(DB_LOCK_GET) +, mode_(DB_LOCK_NG) +, obj_(NULL) +, lock_(NULL) +, index_(0) +{ +} + +DbLockNotGrantedException::DbLockNotGrantedException + (const DbLockNotGrantedException &that) +: DbException(that) +{ + op_ = that.op_; + mode_ = that.mode_; + obj_ = that.obj_; + lock_ = (that.lock_ != NULL) ? new DbLock(*that.lock_) : NULL; + index_ = that.index_; +} + +DbLockNotGrantedException +&DbLockNotGrantedException::operator =(const DbLockNotGrantedException &that) +{ + if (this != &that) { + DbException::operator=(that); + op_ = that.op_; + mode_ = that.mode_; + obj_ = that.obj_; + lock_ = (that.lock_ != NULL) ? new DbLock(*that.lock_) : NULL; + index_ = that.index_; + } + return (*this); +} + +db_lockop_t DbLockNotGrantedException::get_op() const +{ + return op_; +} + +db_lockmode_t DbLockNotGrantedException::get_mode() const +{ + return mode_; +} + +const Dbt* DbLockNotGrantedException::get_obj() const +{ + return obj_; +} + +DbLock* DbLockNotGrantedException::get_lock() const +{ + return lock_; +} + +int DbLockNotGrantedException::get_index() const +{ + return index_; +} + +//////////////////////////////////////////////////////////////////////// +// // +// DbRepHandleDeadException // +// // +//////////////////////////////////////////////////////////////////////// + +DbRepHandleDeadException::~DbRepHandleDeadException() throw() +{ +} + +DbRepHandleDeadException::DbRepHandleDeadException(const char *description) +: DbException(description, DB_REP_HANDLE_DEAD) +{ +} + +DbRepHandleDeadException::DbRepHandleDeadException + (const DbRepHandleDeadException &that) +: DbException(that) +{ +} + +DbRepHandleDeadException +&DbRepHandleDeadException::operator =(const DbRepHandleDeadException &that) +{ + if (this != &that) + DbException::operator=(that); + return (*this); +} + +//////////////////////////////////////////////////////////////////////// +// // +// DbRunRecoveryException // +// // +//////////////////////////////////////////////////////////////////////// + +DbRunRecoveryException::~DbRunRecoveryException() throw() +{ +} + +DbRunRecoveryException::DbRunRecoveryException(const char *description) +: DbException(description, DB_RUNRECOVERY) +{ +} + +DbRunRecoveryException::DbRunRecoveryException + (const DbRunRecoveryException &that) +: DbException(that) +{ +} + +DbRunRecoveryException +&DbRunRecoveryException::operator =(const DbRunRecoveryException &that) +{ + if (this != &that) + DbException::operator=(that); + return (*this); +} diff --git a/src/libs/resiprocate/contrib/db/cxx/cxx_lock.cpp b/src/libs/resiprocate/contrib/db/cxx/cxx_lock.cpp new file mode 100644 index 00000000..b48aa60d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/cxx/cxx_lock.cpp @@ -0,0 +1,41 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +//////////////////////////////////////////////////////////////////////// +// // +// DbLock // +// // +//////////////////////////////////////////////////////////////////////// + +DbLock::DbLock(DB_LOCK value) +: lock_(value) +{ +} + +DbLock::DbLock() +{ + memset(&lock_, 0, sizeof(DB_LOCK)); +} + +DbLock::DbLock(const DbLock &that) +: lock_(that.lock_) +{ +} + +DbLock &DbLock::operator = (const DbLock &that) +{ + lock_ = that.lock_; + return (*this); +} diff --git a/src/libs/resiprocate/contrib/db/cxx/cxx_logc.cpp b/src/libs/resiprocate/contrib/db/cxx/cxx_logc.cpp new file mode 100644 index 00000000..cdc6eb18 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/cxx/cxx_logc.cpp @@ -0,0 +1,78 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +#include "dbinc/db_page.h" +#include "dbinc_auto/db_auto.h" +#include "dbinc_auto/crdel_auto.h" +#include "dbinc/db_dispatch.h" +#include "dbinc_auto/db_ext.h" +#include "dbinc_auto/common_ext.h" + +// It's private, and should never be called, +// but some compilers need it resolved +// +DbLogc::~DbLogc() +{ +} + +// The name _flags prevents a name clash with __db_log_cursor::flags +int DbLogc::close(u_int32_t _flags) +{ + DB_LOGC *logc = this; + int ret; + DbEnv *dbenv2 = DbEnv::get_DbEnv(logc->env->dbenv); + + ret = logc->close(logc, _flags); + + if (!DB_RETOK_STD(ret)) + DB_ERROR(dbenv2, "DbLogc::close", ret, ON_ERROR_UNKNOWN); + + return (ret); +} + +// The name _flags prevents a name clash with __db_log_cursor::flags +int DbLogc::get(DbLsn *get_lsn, Dbt *data, u_int32_t _flags) +{ + DB_LOGC *logc = this; + int ret; + + ret = logc->get(logc, get_lsn, data, _flags); + + if (!DB_RETOK_LGGET(ret)) { + if (ret == DB_BUFFER_SMALL) + DB_ERROR_DBT(DbEnv::get_DbEnv(logc->env->dbenv), + "DbLogc::get", data, ON_ERROR_UNKNOWN); + else + DB_ERROR(DbEnv::get_DbEnv(logc->env->dbenv), + "DbLogc::get", ret, ON_ERROR_UNKNOWN); + } + + return (ret); +} + +// The name _flags prevents a name clash with __db_log_cursor::flags +int DbLogc::version(u_int32_t *versionp, u_int32_t _flags) +{ + DB_LOGC *logc = this; + int ret; + + ret = logc->version(logc, versionp, _flags); + + if (!DB_RETOK_LGGET(ret)) + DB_ERROR(DbEnv::get_DbEnv(logc->env->dbenv), + "DbLogc::version", ret, ON_ERROR_UNKNOWN); + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/cxx/cxx_mpool.cpp b/src/libs/resiprocate/contrib/db/cxx/cxx_mpool.cpp new file mode 100644 index 00000000..21124525 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/cxx/cxx_mpool.cpp @@ -0,0 +1,128 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +// Helper macros for simple methods that pass through to the +// underlying C method. It may return an error or raise an exception. +// Note this macro expects that input _argspec is an argument +// list element (e.g., "char *arg") and that _arglist is the arguments +// that should be passed through to the C method (e.g., "(mpf, arg)") +// +#define DB_MPOOLFILE_METHOD(_name, _argspec, _arglist, _retok) \ +int DbMpoolFile::_name _argspec \ +{ \ + int ret; \ + DB_MPOOLFILE *mpf = unwrap(this); \ + \ + if (mpf == NULL) \ + ret = EINVAL; \ + else \ + ret = mpf->_name _arglist; \ + if (!_retok(ret)) \ + DB_ERROR(DbEnv::get_DbEnv(mpf->env->dbenv), \ + "DbMpoolFile::"#_name, ret, ON_ERROR_UNKNOWN); \ + return (ret); \ +} + +#define DB_MPOOLFILE_METHOD_VOID(_name, _argspec, _arglist) \ +void DbMpoolFile::_name _argspec \ +{ \ + DB_MPOOLFILE *mpf = unwrap(this); \ + \ + mpf->_name _arglist; \ +} + +//////////////////////////////////////////////////////////////////////// +// // +// DbMpoolFile // +// // +//////////////////////////////////////////////////////////////////////// + +DbMpoolFile::DbMpoolFile() +: imp_(0) +{ +} + +DbMpoolFile::~DbMpoolFile() +{ +} + +int DbMpoolFile::close(u_int32_t flags) +{ + DB_MPOOLFILE *mpf = unwrap(this); + int ret; + DbEnv *dbenv = DbEnv::get_DbEnv(mpf->env->dbenv); + + if (mpf == NULL) + ret = EINVAL; + else + ret = mpf->close(mpf, flags); + + imp_ = 0; // extra safety + + // This may seem weird, but is legal as long as we don't access + // any data before returning. + delete this; + + if (!DB_RETOK_STD(ret)) + DB_ERROR(dbenv, "DbMpoolFile::close", ret, ON_ERROR_UNKNOWN); + + return (ret); +} + +DB_MPOOLFILE_METHOD(get, + (db_pgno_t *pgnoaddr, DbTxn *txn, u_int32_t flags, void *pagep), + (mpf, pgnoaddr, unwrap(txn), flags, pagep), DB_RETOK_MPGET) +DB_MPOOLFILE_METHOD(open, + (const char *file, u_int32_t flags, int mode, size_t pagesize), + (mpf, file, flags, mode, pagesize), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(put, + (void *pgaddr, DB_CACHE_PRIORITY priority, u_int32_t flags), + (mpf, pgaddr, priority, flags), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(get_clear_len, (u_int32_t *lenp), + (mpf, lenp), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_clear_len, (u_int32_t len), + (mpf, len), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(get_fileid, (u_int8_t *fileid), + (mpf, fileid), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_fileid, (u_int8_t *fileid), + (mpf, fileid), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(get_flags, (u_int32_t *flagsp), + (mpf, flagsp), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_flags, (u_int32_t flags, int onoff), + (mpf, flags, onoff), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(get_ftype, (int *ftypep), + (mpf, ftypep), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_ftype, (int ftype), + (mpf, ftype), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(get_last_pgno, (db_pgno_t *pgnop), + (mpf, pgnop), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(get_lsn_offset, (int32_t *offsetp), + (mpf, offsetp), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_lsn_offset, (int32_t offset), + (mpf, offset), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(get_maxsize, (u_int32_t *gbytesp, u_int32_t *bytesp), + (mpf, gbytesp, bytesp), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_maxsize, (u_int32_t gbytes, u_int32_t bytes), + (mpf, gbytes, bytes), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(get_pgcookie, (DBT *dbt), + (mpf, dbt), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_pgcookie, (DBT *dbt), + (mpf, dbt), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(get_priority, (DB_CACHE_PRIORITY *priorityp), + (mpf, priorityp), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(set_priority, (DB_CACHE_PRIORITY priority), + (mpf, priority), DB_RETOK_STD) +DB_MPOOLFILE_METHOD(sync, (), + (mpf), DB_RETOK_STD) diff --git a/src/libs/resiprocate/contrib/db/cxx/cxx_multi.cpp b/src/libs/resiprocate/contrib/db/cxx/cxx_multi.cpp new file mode 100644 index 00000000..6e1a361e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/cxx/cxx_multi.cpp @@ -0,0 +1,123 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#include "db_cxx.h" + +DbMultipleIterator::DbMultipleIterator(const Dbt &dbt) + : data_((u_int8_t*)dbt.get_data()), + p_((u_int32_t*)(data_ + dbt.get_ulen() - sizeof(u_int32_t))) +{ +} + +bool DbMultipleDataIterator::next(Dbt &data) +{ + if (*p_ == (u_int32_t)-1) { + data.set_data(0); + data.set_size(0); + p_ = 0; + } else { + data.set_data(data_ + *p_--); + data.set_size(*p_--); + if (data.get_size() == 0 && data.get_data() == data_) + data.set_data(0); + } + return (p_ != 0); +} + +bool DbMultipleKeyDataIterator::next(Dbt &key, Dbt &data) +{ + if (*p_ == (u_int32_t)-1) { + key.set_data(0); + key.set_size(0); + data.set_data(0); + data.set_size(0); + p_ = 0; + } else { + key.set_data(data_ + *p_--); + key.set_size(*p_--); + data.set_data(data_ + *p_--); + data.set_size(*p_--); + } + return (p_ != 0); +} + +bool DbMultipleRecnoDataIterator::next(db_recno_t &recno, Dbt &data) +{ + if (*p_ == (u_int32_t)0) { + recno = 0; + data.set_data(0); + data.set_size(0); + p_ = 0; + } else { + recno = *p_--; + data.set_data(data_ + *p_--); + data.set_size(*p_--); + } + return (p_ != 0); +} + + +DbMultipleBuilder::DbMultipleBuilder(Dbt &dbt) : dbt_(dbt) +{ + DB_MULTIPLE_WRITE_INIT(p_, dbt_.get_DBT()); +} + + +bool DbMultipleDataBuilder::append(void *dbuf, size_t dlen) +{ + DB_MULTIPLE_WRITE_NEXT(p_, dbt_.get_DBT(), dbuf, dlen); + return (p_ != 0); +} + +bool DbMultipleDataBuilder::reserve(void *&ddest, size_t dlen) +{ + DB_MULTIPLE_RESERVE_NEXT(p_, dbt_.get_DBT(), ddest, dlen); + return (ddest != 0); +} + +bool DbMultipleKeyDataBuilder::append( + void *kbuf, size_t klen, void *dbuf, size_t dlen) +{ + DB_MULTIPLE_KEY_WRITE_NEXT(p_, dbt_.get_DBT(), + kbuf, klen, dbuf, dlen); + return (p_ != 0); +} + +bool DbMultipleKeyDataBuilder::reserve( + void *&kdest, size_t klen, void *&ddest, size_t dlen) +{ + DB_MULTIPLE_KEY_RESERVE_NEXT(p_, dbt_.get_DBT(), + kdest, klen, ddest, dlen); + return (kdest != 0 && ddest != 0); +} + + +DbMultipleRecnoDataBuilder::DbMultipleRecnoDataBuilder(Dbt &dbt) : dbt_(dbt) +{ + DB_MULTIPLE_RECNO_WRITE_INIT(p_, dbt_.get_DBT()); +} + +bool DbMultipleRecnoDataBuilder::append( + db_recno_t recno, void *dbuf, size_t dlen) +{ + DB_MULTIPLE_RECNO_WRITE_NEXT(p_, dbt_.get_DBT(), + recno, dbuf, dlen); + return (p_ != 0); +} + +bool DbMultipleRecnoDataBuilder::reserve( + db_recno_t recno, void *&ddest, size_t dlen) +{ + DB_MULTIPLE_RECNO_RESERVE_NEXT(p_, dbt_.get_DBT(), + recno, ddest, dlen); + return (ddest != 0); +} diff --git a/src/libs/resiprocate/contrib/db/cxx/cxx_seq.cpp b/src/libs/resiprocate/contrib/db/cxx/cxx_seq.cpp new file mode 100644 index 00000000..1a7a5dfb --- /dev/null +++ b/src/libs/resiprocate/contrib/db/cxx/cxx_seq.cpp @@ -0,0 +1,109 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +// Helper macro for simple methods that pass through to the +// underlying C method. It may return an error or raise an exception. +// Note this macro expects that input _argspec is an argument +// list element (e.g., "char *arg") and that _arglist is the arguments +// that should be passed through to the C method (e.g., "(db, arg)") +// +#define DBSEQ_METHOD(_name, _argspec, _arglist, _destructor) \ +int DbSequence::_name _argspec \ +{ \ + int ret; \ + DB_SEQUENCE *seq = unwrap(this); \ + DbEnv *dbenv = DbEnv::get_DbEnv(seq->seq_dbp->dbenv); \ + \ + ret = seq->_name _arglist; \ + if (_destructor) \ + imp_ = 0; \ + if (!DB_RETOK_STD(ret)) \ + DB_ERROR(dbenv, \ + "DbSequence::" # _name, ret, ON_ERROR_UNKNOWN); \ + return (ret); \ +} + +DbSequence::DbSequence(Db *db, u_int32_t flags) +: imp_(0) +{ + DB_SEQUENCE *seq; + int ret; + + if ((ret = db_sequence_create(&seq, unwrap(db), flags)) != 0) + DB_ERROR(db->get_env(), "DbSequence::DbSequence", ret, + ON_ERROR_UNKNOWN); + else { + imp_ = seq; + seq->api_internal = this; + } +} + +DbSequence::DbSequence(DB_SEQUENCE *seq) +: imp_(seq) +{ + seq->api_internal = this; +} + +DbSequence::~DbSequence() +{ + DB_SEQUENCE *seq; + + seq = unwrap(this); + if (seq != NULL) + (void)seq->close(seq, 0); +} + +DBSEQ_METHOD(open, (DbTxn *txnid, Dbt *key, u_int32_t flags), + (seq, unwrap(txnid), key, flags), 0) +DBSEQ_METHOD(initial_value, (db_seq_t value), (seq, value), 0) +DBSEQ_METHOD(close, (u_int32_t flags), (seq, flags), 1) +DBSEQ_METHOD(remove, (DbTxn *txnid, u_int32_t flags), + (seq, unwrap(txnid), flags), 1) +DBSEQ_METHOD(stat, (DB_SEQUENCE_STAT **sp, u_int32_t flags), + (seq, sp, flags), 0) +DBSEQ_METHOD(stat_print, (u_int32_t flags), (seq, flags), 0) + +DBSEQ_METHOD(get, + (DbTxn *txnid, int32_t delta, db_seq_t *retp, u_int32_t flags), + (seq, unwrap(txnid), delta, retp, flags), 0) +DBSEQ_METHOD(get_cachesize, (int32_t *sizep), (seq, sizep), 0) +DBSEQ_METHOD(set_cachesize, (int32_t size), (seq, size), 0) +DBSEQ_METHOD(get_flags, (u_int32_t *flagsp), (seq, flagsp), 0) +DBSEQ_METHOD(set_flags, (u_int32_t flags), (seq, flags), 0) +DBSEQ_METHOD(get_range, (db_seq_t *minp, db_seq_t *maxp), (seq, minp, maxp), 0) +DBSEQ_METHOD(set_range, (db_seq_t min, db_seq_t max), (seq, min, max), 0) + +Db *DbSequence::get_db() +{ + DB_SEQUENCE *seq = unwrap(this); + DB *db; + (void)seq->get_db(seq, &db); + return Db::get_Db(db); +} + +Dbt *DbSequence::get_key() +{ + DB_SEQUENCE *seq = unwrap(this); + memset(&key_, 0, sizeof(DBT)); + (void)seq->get_key(seq, &key_); + return Dbt::get_Dbt(&key_); +} + +// static method +DbSequence *DbSequence::wrap_DB_SEQUENCE(DB_SEQUENCE *seq) +{ + DbSequence *wrapped_seq = get_DbSequence(seq); + return (wrapped_seq != NULL) ? wrapped_seq : new DbSequence(seq); +} diff --git a/src/libs/resiprocate/contrib/db/cxx/cxx_txn.cpp b/src/libs/resiprocate/contrib/db/cxx/cxx_txn.cpp new file mode 100644 index 00000000..28b9344d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/cxx/cxx_txn.cpp @@ -0,0 +1,115 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#include "db_cxx.h" +#include "dbinc/cxx_int.h" + +#include "dbinc/txn.h" + +// Helper macro for simple methods that pass through to the +// underlying C method. It may return an error or raise an exception. +// Note this macro expects that input _argspec is an argument +// list element (e.g., "char *arg") and that _arglist is the arguments +// that should be passed through to the C method (e.g., "(db, arg)") +// +#define DBTXN_METHOD(_name, _delete, _argspec, _arglist) \ +int DbTxn::_name _argspec \ +{ \ + int ret; \ + DB_TXN *txn = unwrap(this); \ + DbEnv *dbenv = DbEnv::get_DbEnv(txn->mgrp->env->dbenv); \ + \ + ret = txn->_name _arglist; \ + /* Weird, but safe if we don't access this again. */ \ + if (_delete) { \ + /* Can't do this in the destructor. */ \ + if (parent_txn_ != NULL) \ + parent_txn_->remove_child_txn(this); \ + delete this; \ + } \ + if (!DB_RETOK_STD(ret)) \ + DB_ERROR(dbenv, "DbTxn::" # _name, ret, ON_ERROR_UNKNOWN); \ + return (ret); \ +} + +// private constructor, never called but needed by some C++ linkers +DbTxn::DbTxn(DbTxn *ptxn) +: imp_(0) +{ + TAILQ_INIT(&children); + memset(&child_entry, 0, sizeof(child_entry)); + parent_txn_ = ptxn; + if (parent_txn_ != NULL) + parent_txn_->add_child_txn(this); +} + +DbTxn::DbTxn(DB_TXN *txn, DbTxn *ptxn) +: imp_(txn) +{ + txn->api_internal = this; + TAILQ_INIT(&children); + memset(&child_entry, 0, sizeof(child_entry)); + parent_txn_ = ptxn; + if (parent_txn_ != NULL) + parent_txn_->add_child_txn(this); +} + +DbTxn::~DbTxn() +{ + DbTxn *txn, *pnext; + + for(txn = TAILQ_FIRST(&children); txn != NULL;) { + pnext = TAILQ_NEXT(txn, child_entry); + delete txn; + txn = pnext; + } +} + +DBTXN_METHOD(abort, 1, (), (txn)) +DBTXN_METHOD(commit, 1, (u_int32_t flags), (txn, flags)) +DBTXN_METHOD(discard, 1, (u_int32_t flags), (txn, flags)) + +void DbTxn::remove_child_txn(DbTxn *kid) +{ + TAILQ_REMOVE(&children, kid, child_entry); + kid->set_parent(NULL); +} + +void DbTxn::add_child_txn(DbTxn *kid) +{ + TAILQ_INSERT_HEAD(&children, kid, child_entry); + kid->set_parent(this); +} + +u_int32_t DbTxn::id() +{ + DB_TXN *txn; + + txn = unwrap(this); + return (txn->id(txn)); // no error +} + +DBTXN_METHOD(get_name, 0, (const char **namep), (txn, namep)) +DBTXN_METHOD(prepare, 0, (u_int8_t *gid), (txn, gid)) +DBTXN_METHOD(set_name, 0, (const char *name), (txn, name)) +DBTXN_METHOD(set_timeout, 0, (db_timeout_t timeout, u_int32_t flags), + (txn, timeout, flags)) + +// static method +DbTxn *DbTxn::wrap_DB_TXN(DB_TXN *txn) +{ + DbTxn *wrapped_txn = get_DbTxn(txn); + // txn may have a valid parent transaction, but here we don't care. + // We maintain parent-kid relationship in DbTxn only to make sure + // unresolved kids of DbTxn objects are deleted. + return (wrapped_txn != NULL) ? wrapped_txn : new DbTxn(txn, NULL); +} diff --git a/src/libs/resiprocate/contrib/db/db/crdel.src b/src/libs/resiprocate/contrib/db/db/crdel.src new file mode 100644 index 00000000..cd0b02f0 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/crdel.src @@ -0,0 +1,72 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +DBPRIVATE +PREFIX __crdel + +INCLUDE #include "db_int.h" +INCLUDE #include "dbinc/crypto.h" +INCLUDE #include "dbinc/db_page.h" +INCLUDE #include "dbinc/db_dispatch.h" +INCLUDE #include "dbinc/db_am.h" +INCLUDE #include "dbinc/log.h" +INCLUDE #include "dbinc/txn.h" +INCLUDE + +/* + * Metasub: log the creation of a subdatabase meta data page. + * + * fileid: identifies the file being acted upon. + * pgno: page number on which to write this meta-data page + * page: the actual meta-data page + * lsn: lsn of the page. + */ +BEGIN metasub 42 142 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +PGDBT page DBT s +POINTER lsn DB_LSN * lu +END + +/* + * Inmem_create: Log the creation of an in-memory database. + * + * name: Name of the database + * fid: File id of the database + */ +BEGIN inmem_create 44 138 +ARG fileid int32_t ld +DBT name DBT s +DBT fid DBT s +ARG pgsize u_int32_t lu +END + +/* + * Inmem_rename: Log the renaming of an in-memory only database. + * + * oldname: database's starting name + * newname: database's ending name + * fid: fileid + */ +BEGIN inmem_rename 44 139 +DBT oldname DBT s +DBT newname DBT s +DBT fid DBT s +END + +/* + * Inmem_remove: Log the removal of an in-memory only database. + * + * name: database's ending name + * fid: fileid + */ +BEGIN inmem_remove 44 140 +DBT name DBT s +DBT fid DBT s +END + diff --git a/src/libs/resiprocate/contrib/db/db/crdel_auto.c b/src/libs/resiprocate/contrib/db/db/crdel_auto.c new file mode 100644 index 00000000..801a0a5c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/crdel_auto.c @@ -0,0 +1,945 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#include "db_config.h" +#include "db_int.h" +#include "dbinc/crypto.h" +#include "dbinc/db_page.h" +#include "dbinc/db_dispatch.h" +#include "dbinc/db_am.h" +#include "dbinc/log.h" +#include "dbinc/txn.h" + +/* + * PUBLIC: int __crdel_metasub_read __P((ENV *, DB **, void *, + * PUBLIC: void *, __crdel_metasub_args **)); + */ +int +__crdel_metasub_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __crdel_metasub_args **argpp; +{ + __crdel_metasub_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__crdel_metasub_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->page, 0, sizeof(argp->page)); + LOGCOPY_32(env,&argp->page.size, bp); + bp += sizeof(u_int32_t); + argp->page.data = bp; + bp += argp->page.size; + if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { + int t_ret; + if ((t_ret = __db_pageswap(*dbpp, (PAGE *)argp->page.data, + (size_t)argp->page.size, NULL, 1)) != 0) + return (t_ret); + } + + LOGCOPY_TOLSN(env, &argp->lsn, bp); + bp += sizeof(DB_LSN); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __crdel_metasub_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, const DBT *, DB_LSN *)); + */ +int +__crdel_metasub_log(dbp, txnp, ret_lsnp, flags, pgno, page, lsn) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + const DBT *page; + DB_LSN * lsn; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___crdel_metasub; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (page == NULL ? 0 : page->size) + + sizeof(*lsn); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (page == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &page->size); + bp += sizeof(page->size); + memcpy(bp, page->data, page->size); + if (LOG_SWAPPED(env)) + if ((ret = __db_pageswap(dbp, + (PAGE *)bp, (size_t)page->size, (DBT *)NULL, 0)) != 0) + return (ret); + bp += page->size; + } + + if (lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, lsn); + } else + memset(bp, 0, sizeof(*lsn)); + bp += sizeof(*lsn); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__crdel_metasub_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __crdel_inmem_create_read __P((ENV *, void *, + * PUBLIC: __crdel_inmem_create_args **)); + */ +int +__crdel_inmem_create_read(env, recbuf, argpp) + ENV *env; + void *recbuf; + __crdel_inmem_create_args **argpp; +{ + __crdel_inmem_create_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__crdel_inmem_create_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->name, 0, sizeof(argp->name)); + LOGCOPY_32(env,&argp->name.size, bp); + bp += sizeof(u_int32_t); + argp->name.data = bp; + bp += argp->name.size; + + memset(&argp->fid, 0, sizeof(argp->fid)); + LOGCOPY_32(env,&argp->fid.size, bp); + bp += sizeof(u_int32_t); + argp->fid.data = bp; + bp += argp->fid.size; + + LOGCOPY_32(env, &argp->pgsize, bp); + bp += sizeof(argp->pgsize); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __crdel_inmem_create_log __P((ENV *, DB_TXN *, + * PUBLIC: DB_LSN *, u_int32_t, int32_t, const DBT *, const DBT *, + * PUBLIC: u_int32_t)); + */ +int +__crdel_inmem_create_log(env, txnp, ret_lsnp, flags, + fileid, name, fid, pgsize) + ENV *env; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + int32_t fileid; + const DBT *name; + const DBT *fid; + u_int32_t pgsize; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + rlsnp = ret_lsnp; + rectype = DB___crdel_inmem_create; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (name == NULL ? 0 : name->size) + + sizeof(u_int32_t) + (fid == NULL ? 0 : fid->size) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)fileid; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (name == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &name->size); + bp += sizeof(name->size); + memcpy(bp, name->data, name->size); + bp += name->size; + } + + if (fid == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &fid->size); + bp += sizeof(fid->size); + memcpy(bp, fid->data, fid->size); + bp += fid->size; + } + + LOGCOPY_32(env, bp, &pgsize); + bp += sizeof(pgsize); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__crdel_inmem_create_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __crdel_inmem_rename_read __P((ENV *, void *, + * PUBLIC: __crdel_inmem_rename_args **)); + */ +int +__crdel_inmem_rename_read(env, recbuf, argpp) + ENV *env; + void *recbuf; + __crdel_inmem_rename_args **argpp; +{ + __crdel_inmem_rename_args *argp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__crdel_inmem_rename_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + memset(&argp->oldname, 0, sizeof(argp->oldname)); + LOGCOPY_32(env,&argp->oldname.size, bp); + bp += sizeof(u_int32_t); + argp->oldname.data = bp; + bp += argp->oldname.size; + + memset(&argp->newname, 0, sizeof(argp->newname)); + LOGCOPY_32(env,&argp->newname.size, bp); + bp += sizeof(u_int32_t); + argp->newname.data = bp; + bp += argp->newname.size; + + memset(&argp->fid, 0, sizeof(argp->fid)); + LOGCOPY_32(env,&argp->fid.size, bp); + bp += sizeof(u_int32_t); + argp->fid.data = bp; + bp += argp->fid.size; + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __crdel_inmem_rename_log __P((ENV *, DB_TXN *, + * PUBLIC: DB_LSN *, u_int32_t, const DBT *, const DBT *, const DBT *)); + */ +int +__crdel_inmem_rename_log(env, txnp, ret_lsnp, flags, + oldname, newname, fid) + ENV *env; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + const DBT *oldname; + const DBT *newname; + const DBT *fid; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + u_int32_t zero, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + rlsnp = ret_lsnp; + rectype = DB___crdel_inmem_rename; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + (oldname == NULL ? 0 : oldname->size) + + sizeof(u_int32_t) + (newname == NULL ? 0 : newname->size) + + sizeof(u_int32_t) + (fid == NULL ? 0 : fid->size); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + if (oldname == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &oldname->size); + bp += sizeof(oldname->size); + memcpy(bp, oldname->data, oldname->size); + bp += oldname->size; + } + + if (newname == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &newname->size); + bp += sizeof(newname->size); + memcpy(bp, newname->data, newname->size); + bp += newname->size; + } + + if (fid == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &fid->size); + bp += sizeof(fid->size); + memcpy(bp, fid->data, fid->size); + bp += fid->size; + } + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__crdel_inmem_rename_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __crdel_inmem_remove_read __P((ENV *, void *, + * PUBLIC: __crdel_inmem_remove_args **)); + */ +int +__crdel_inmem_remove_read(env, recbuf, argpp) + ENV *env; + void *recbuf; + __crdel_inmem_remove_args **argpp; +{ + __crdel_inmem_remove_args *argp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__crdel_inmem_remove_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + memset(&argp->name, 0, sizeof(argp->name)); + LOGCOPY_32(env,&argp->name.size, bp); + bp += sizeof(u_int32_t); + argp->name.data = bp; + bp += argp->name.size; + + memset(&argp->fid, 0, sizeof(argp->fid)); + LOGCOPY_32(env,&argp->fid.size, bp); + bp += sizeof(u_int32_t); + argp->fid.data = bp; + bp += argp->fid.size; + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __crdel_inmem_remove_log __P((ENV *, DB_TXN *, + * PUBLIC: DB_LSN *, u_int32_t, const DBT *, const DBT *)); + */ +int +__crdel_inmem_remove_log(env, txnp, ret_lsnp, flags, + name, fid) + ENV *env; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + const DBT *name; + const DBT *fid; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + u_int32_t zero, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + rlsnp = ret_lsnp; + rectype = DB___crdel_inmem_remove; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + (name == NULL ? 0 : name->size) + + sizeof(u_int32_t) + (fid == NULL ? 0 : fid->size); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + if (name == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &name->size); + bp += sizeof(name->size); + memcpy(bp, name->data, name->size); + bp += name->size; + } + + if (fid == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &fid->size); + bp += sizeof(fid->size); + memcpy(bp, fid->data, fid->size); + bp += fid->size; + } + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__crdel_inmem_remove_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __crdel_init_recover __P((ENV *, DB_DISTAB *)); + */ +int +__crdel_init_recover(env, dtabp) + ENV *env; + DB_DISTAB *dtabp; +{ + int ret; + + if ((ret = __db_add_recovery_int(env, dtabp, + __crdel_metasub_recover, DB___crdel_metasub)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __crdel_inmem_create_recover, DB___crdel_inmem_create)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __crdel_inmem_rename_recover, DB___crdel_inmem_rename)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __crdel_inmem_remove_recover, DB___crdel_inmem_remove)) != 0) + return (ret); + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db/crdel_autop.c b/src/libs/resiprocate/contrib/db/db/crdel_autop.c new file mode 100644 index 00000000..6bf4bb63 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/crdel_autop.c @@ -0,0 +1,227 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/crypto.h" +#include "dbinc/db_page.h" +#include "dbinc/db_dispatch.h" +#include "dbinc/db_am.h" +#include "dbinc/log.h" +#include "dbinc/txn.h" + +/* + * PUBLIC: int __crdel_metasub_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__crdel_metasub_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __crdel_metasub_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __crdel_metasub_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__crdel_metasub%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tpage: "); + for (i = 0; i < argp->page.size; i++) { + ch = ((u_int8_t *)argp->page.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tlsn: [%lu][%lu]\n", + (u_long)argp->lsn.file, (u_long)argp->lsn.offset); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __crdel_inmem_create_print __P((ENV *, DBT *, + * PUBLIC: DB_LSN *, db_recops, void *)); + */ +int +__crdel_inmem_create_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __crdel_inmem_create_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = __crdel_inmem_create_read(env, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__crdel_inmem_create%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tname: "); + for (i = 0; i < argp->name.size; i++) { + ch = ((u_int8_t *)argp->name.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tfid: "); + for (i = 0; i < argp->fid.size; i++) { + ch = ((u_int8_t *)argp->fid.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tpgsize: %lu\n", (u_long)argp->pgsize); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __crdel_inmem_rename_print __P((ENV *, DBT *, + * PUBLIC: DB_LSN *, db_recops, void *)); + */ +int +__crdel_inmem_rename_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __crdel_inmem_rename_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = __crdel_inmem_rename_read(env, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__crdel_inmem_rename%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\toldname: "); + for (i = 0; i < argp->oldname.size; i++) { + ch = ((u_int8_t *)argp->oldname.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tnewname: "); + for (i = 0; i < argp->newname.size; i++) { + ch = ((u_int8_t *)argp->newname.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tfid: "); + for (i = 0; i < argp->fid.size; i++) { + ch = ((u_int8_t *)argp->fid.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __crdel_inmem_remove_print __P((ENV *, DBT *, + * PUBLIC: DB_LSN *, db_recops, void *)); + */ +int +__crdel_inmem_remove_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __crdel_inmem_remove_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = __crdel_inmem_remove_read(env, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__crdel_inmem_remove%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tname: "); + for (i = 0; i < argp->name.size; i++) { + ch = ((u_int8_t *)argp->name.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tfid: "); + for (i = 0; i < argp->fid.size; i++) { + ch = ((u_int8_t *)argp->fid.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __crdel_init_print __P((ENV *, DB_DISTAB *)); + */ +int +__crdel_init_print(env, dtabp) + ENV *env; + DB_DISTAB *dtabp; +{ + int ret; + + if ((ret = __db_add_recovery_int(env, dtabp, + __crdel_metasub_print, DB___crdel_metasub)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __crdel_inmem_create_print, DB___crdel_inmem_create)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __crdel_inmem_rename_print, DB___crdel_inmem_rename)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __crdel_inmem_remove_print, DB___crdel_inmem_remove)) != 0) + return (ret); + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db/crdel_rec.c b/src/libs/resiprocate/contrib/db/db/crdel_rec.c new file mode 100644 index 00000000..285b9652 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/crdel_rec.c @@ -0,0 +1,298 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/fop.h" +#include "dbinc/hash.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/txn.h" + +/* + * __crdel_metasub_recover -- + * Recovery function for metasub. + * + * PUBLIC: int __crdel_metasub_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__crdel_metasub_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __crdel_metasub_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int cmp_p, ret, t_ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__crdel_metasub_print); + REC_INTRO(__crdel_metasub_read, ip, 0); + + /* + * If we are undoing this operation, but the DB that we got back + * was never really opened, then this open was an in-memory open + * that did not finish. We can let the file creation take care + * of any necessary undo/cleanup. + */ + if (DB_UNDO(op) && !F_ISSET(file_dbp, DB_AM_OPEN_CALLED)) + goto done; + + if ((ret = __memp_fget(mpf, &argp->pgno, + ip, NULL, 0, &pagep)) != 0) { + /* If this is an in-memory file, this might be OK. */ + if (F_ISSET(file_dbp, DB_AM_INMEM) && + (ret = __memp_fget(mpf, &argp->pgno, ip, NULL, + DB_MPOOL_CREATE | DB_MPOOL_DIRTY, &pagep)) == 0) { + LSN_NOT_LOGGED(LSN(pagep)); + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + } + + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn); + + if (cmp_p == 0 && DB_REDO(op)) { + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + memcpy(pagep, argp->page.data, argp->page.size); + LSN(pagep) = *lsnp; + + /* + * If this was an in-memory database and we are re-creating + * and this is the meta-data page, then we need to set up a + * bunch of fields in the dbo as well. + */ + if (F_ISSET(file_dbp, DB_AM_INMEM) && + argp->pgno == PGNO_BASE_MD && + (ret = __db_meta_setup(file_dbp->env, file_dbp, + file_dbp->dname, (DBMETA *)pagep, 0, DB_CHK_META)) != 0) + goto out; + } else if (DB_UNDO(op)) { + /* + * We want to undo this page creation. The page creation + * happened in two parts. First, we called __db_pg_alloc which + * was logged separately. Then we wrote the meta-data onto + * the page. So long as we restore the LSN, then the recovery + * for __db_pg_alloc will do everything else. + * + * Don't bother checking the lsn on the page. If we are + * rolling back the next thing is that this page will get + * freed. Opening the subdb will have reinitialized the + * page, but not the lsn. + */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + LSN(pagep) = argp->lsn; + } + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL && (t_ret = __memp_fput(mpf, + ip, pagep, file_dbp->priority)) != 0 && + ret == 0) + ret = t_ret; + + REC_CLOSE; +} + +/* + * __crdel_inmem_create_recover -- + * Recovery function for inmem_create. + * + * PUBLIC: int __crdel_inmem_create_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__crdel_inmem_create_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __crdel_inmem_create_args *argp; + DB *dbp; + int do_close, ret, t_ret; + + COMPQUIET(info, NULL); + + dbp = NULL; + do_close = 0; + REC_PRINT(__crdel_inmem_create_print); + REC_NOOP_INTRO(__crdel_inmem_create_read); + + /* First, see if the DB handle already exists. */ + if (argp->fileid == DB_LOGFILEID_INVALID) { + if (DB_REDO(op)) + ret = ENOENT; + else + ret = 0; + } else + ret = __dbreg_id_to_db(env, argp->txnp, &dbp, argp->fileid, 0); + + if (DB_REDO(op)) { + /* + * If the dbreg failed, that means that we're creating a + * tmp file. + */ + if (ret != 0) { + if ((ret = __db_create_internal(&dbp, env, 0)) != 0) + goto out; + + F_SET(dbp, DB_AM_RECOVER | DB_AM_INMEM); + memcpy(dbp->fileid, argp->fid.data, DB_FILE_ID_LEN); + if (((ret = __os_strdup(env, + argp->name.data, &dbp->dname)) != 0)) + goto out; + + /* + * This DBP is never going to be entered into the + * dbentry table, so if we leave it open here, + * then we're going to lose it. + */ + do_close = 1; + } + + /* Now, set the fileid. */ + memcpy(dbp->fileid, argp->fid.data, argp->fid.size); + if ((ret = __memp_set_fileid(dbp->mpf, dbp->fileid)) != 0) + goto out; + dbp->preserve_fid = 1; + MAKE_INMEM(dbp); + if ((ret = __env_setup(dbp, + NULL, NULL, argp->name.data, TXN_INVALID, 0)) != 0) + goto out; + ret = __env_mpool(dbp, argp->name.data, 0); + + if (ret == ENOENT) { + dbp->pgsize = argp->pgsize; + if ((ret = __env_mpool(dbp, + argp->name.data, DB_CREATE)) != 0) + goto out; + } else if (ret != 0) + goto out; + } + + if (DB_UNDO(op)) { + if (ret == 0) + ret = __memp_nameop(env, argp->fid.data, NULL, + (const char *)argp->name.data, NULL, 1); + + if (ret == ENOENT || ret == DB_DELETED) + ret = 0; + else + goto out; + } + + *lsnp = argp->prev_lsn; + +out: if (dbp != NULL) { + t_ret = 0; + + if (do_close || ret != 0) + t_ret = __db_close(dbp, NULL, DB_NOSYNC); + if (t_ret != 0 && ret == 0) + ret = t_ret; + } + REC_NOOP_CLOSE; +} + +/* + * __crdel_inmem_rename_recover -- + * Recovery function for inmem_rename. + * + * PUBLIC: int __crdel_inmem_rename_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__crdel_inmem_rename_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __crdel_inmem_rename_args *argp; + u_int8_t *fileid; + int ret; + + COMPQUIET(info, NULL); + + REC_PRINT(__crdel_inmem_rename_print); + REC_NOOP_INTRO(__crdel_inmem_rename_read); + fileid = argp->fid.data; + + /* Void out errors because the files may or may not still exist. */ + if (DB_REDO(op)) + (void)__memp_nameop(env, fileid, + (const char *)argp->newname.data, + (const char *)argp->oldname.data, + (const char *)argp->newname.data, 1); + + if (DB_UNDO(op)) + (void)__memp_nameop(env, fileid, + (const char *)argp->oldname.data, + (const char *)argp->newname.data, + (const char *)argp->oldname.data, 1); + + *lsnp = argp->prev_lsn; + ret = 0; + + REC_NOOP_CLOSE; +} + +/* + * __crdel_inmem_remove_recover -- + * Recovery function for inmem_remove. + * + * PUBLIC: int __crdel_inmem_remove_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__crdel_inmem_remove_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __crdel_inmem_remove_args *argp; + int ret; + + COMPQUIET(info, NULL); + + REC_PRINT(__crdel_inmem_remove_print); + REC_NOOP_INTRO(__crdel_inmem_remove_read); + + /* + * Since removes are delayed; there is no undo for a remove; only redo. + * The remove may fail, which is OK. + */ + if (DB_REDO(op)) { + (void)__memp_nameop(env, + argp->fid.data, NULL, argp->name.data, NULL, 1); + } + + *lsnp = argp->prev_lsn; + ret = 0; + + REC_NOOP_CLOSE; +} diff --git a/src/libs/resiprocate/contrib/db/db/db.c b/src/libs/resiprocate/contrib/db/db/db.c new file mode 100644 index 00000000..9caa1aa1 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db.c @@ -0,0 +1,1539 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_swap.h" +#include "dbinc/btree.h" +#include "dbinc/fop.h" +#include "dbinc/hash.h" +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/partition.h" +#include "dbinc/qam.h" +#include "dbinc/txn.h" + +static int __db_disassociate __P((DB *)); +static int __db_disassociate_foreign __P ((DB *)); + +#ifdef CONFIG_TEST +static int __db_makecopy __P((ENV *, const char *, const char *)); +static int __qam_testdocopy __P((DB *, const char *)); +#endif + +/* + * DB.C -- + * This file contains the utility functions for the DBP layer. + */ + +/* + * __db_master_open -- + * Open up a handle on a master database. + * + * PUBLIC: int __db_master_open __P((DB *, DB_THREAD_INFO *, + * PUBLIC: DB_TXN *, const char *, u_int32_t, int, DB **)); + */ +int +__db_master_open(subdbp, ip, txn, name, flags, mode, dbpp) + DB *subdbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + const char *name; + u_int32_t flags; + int mode; + DB **dbpp; +{ + DB *dbp; + int ret; + + *dbpp = NULL; + + /* Open up a handle on the main database. */ + if ((ret = __db_create_internal(&dbp, subdbp->env, 0)) != 0) + return (ret); + + /* + * It's always a btree. + * Run in the transaction we've created. + * Set the pagesize in case we're creating a new database. + * Flag that we're creating a database with subdatabases. + */ + dbp->pgsize = subdbp->pgsize; + F_SET(dbp, DB_AM_SUBDB); + F_SET(dbp, F_ISSET(subdbp, + DB_AM_RECOVER | DB_AM_SWAP | + DB_AM_ENCRYPT | DB_AM_CHKSUM | DB_AM_NOT_DURABLE)); + + /* + * If there was a subdb specified, then we only want to apply + * DB_EXCL to the subdb, not the actual file. We only got here + * because there was a subdb specified. + */ + LF_CLR(DB_EXCL); + LF_SET(DB_RDWRMASTER); + if ((ret = __db_open(dbp, ip, + txn, name, NULL, DB_BTREE, flags, mode, PGNO_BASE_MD)) != 0) + goto err; + + /* + * The items in dbp are initialized from the master file's meta page. + * Other items such as checksum and encryption are checked when we + * read the meta-page, so we do not check those here. However, if + * the meta-page caused checksumming to be turned on and it wasn't + * already, set it here. + */ + if (F_ISSET(dbp, DB_AM_CHKSUM)) + F_SET(subdbp, DB_AM_CHKSUM); + + /* + * The user may have specified a page size for an existing file, + * which we want to ignore. + */ + subdbp->pgsize = dbp->pgsize; + *dbpp = dbp; + + if (0) { +err: if (!F_ISSET(dbp, DB_AM_DISCARD)) + (void)__db_close(dbp, txn, 0); + } + + return (ret); +} + +/* + * __db_master_update -- + * Add/Open/Remove a subdatabase from a master database. + * + * PUBLIC: int __db_master_update __P((DB *, DB *, DB_THREAD_INFO *, DB_TXN *, + * PUBLIC: const char *, DBTYPE, mu_action, const char *, u_int32_t)); + */ +int +__db_master_update(mdbp, sdbp, ip, txn, subdb, type, action, newname, flags) + DB *mdbp, *sdbp; + DB_TXN *txn; + DB_THREAD_INFO *ip; + const char *subdb; + DBTYPE type; + mu_action action; + const char *newname; + u_int32_t flags; +{ + DBC *dbc, *ndbc; + DBT key, data, ndata; + ENV *env; + PAGE *p, *r; + db_pgno_t t_pgno; + int modify, ret, t_ret; + + env = mdbp->env; + dbc = ndbc = NULL; + p = NULL; + + /* + * Open up a cursor. If this is CDB and we're creating the database, + * make it an update cursor. + * + * Might we modify the master database? If so, we'll need to lock. + */ + modify = (action != MU_OPEN || LF_ISSET(DB_CREATE)) ? 1 : 0; + + if ((ret = __db_cursor(mdbp, ip, txn, &dbc, + (CDB_LOCKING(env) && modify) ? DB_WRITECURSOR : 0)) != 0) + return (ret); + + /* + * Point the cursor at the record. + * + * If we're removing or potentially creating an entry, lock the page + * with DB_RMW. + * + * We do multiple cursor operations with the cursor in some cases and + * subsequently access the data DBT information. Set DB_DBT_MALLOC so + * we don't risk modification of the data between our uses of it. + * + * !!! + * We don't include the name's nul termination in the database. + */ + DB_INIT_DBT(key, subdb, strlen(subdb)); + memset(&data, 0, sizeof(data)); + F_SET(&data, DB_DBT_MALLOC); + + ret = __dbc_get(dbc, &key, &data, + DB_SET | ((STD_LOCKING(dbc) && modify) ? DB_RMW : 0)); + + /* + * What we do next--whether or not we found a record for the + * specified subdatabase--depends on what the specified action is. + * Handle ret appropriately as the first statement of each case. + */ + switch (action) { + case MU_REMOVE: + /* + * We should have found something if we're removing it. Note + * that in the common case where the DB we're asking to remove + * doesn't exist, we won't get this far; __db_subdb_remove + * will already have returned an error from __db_open. + */ + if (ret != 0) + goto err; + + /* + * Delete the subdatabase entry first; if this fails, + * we don't want to touch the actual subdb pages. + */ + if ((ret = __dbc_del(dbc, 0)) != 0) + goto err; + + /* + * We're handling actual data, not on-page meta-data, + * so it hasn't been converted to/from opposite + * endian architectures. Do it explicitly, now. + */ + memcpy(&sdbp->meta_pgno, data.data, sizeof(db_pgno_t)); + DB_NTOHL_SWAP(env, &sdbp->meta_pgno); + if ((ret = __memp_fget(mdbp->mpf, &sdbp->meta_pgno, + ip, dbc->txn, DB_MPOOL_DIRTY, &p)) != 0) + goto err; + + /* Free the root on the master db if it was created. */ + if (TYPE(p) == P_BTREEMETA && + ((BTMETA *)p)->root != PGNO_INVALID) { + if ((ret = __memp_fget(mdbp->mpf, + &((BTMETA *)p)->root, ip, dbc->txn, + DB_MPOOL_DIRTY, &r)) != 0) + goto err; + + /* Free and put the page. */ + if ((ret = __db_free(dbc, r)) != 0) { + r = NULL; + goto err; + } + } + /* Free and put the page. */ + if ((ret = __db_free(dbc, p)) != 0) { + p = NULL; + goto err; + } + p = NULL; + break; + case MU_RENAME: + /* We should have found something if we're renaming it. */ + if (ret != 0) + goto err; + + /* + * Before we rename, we need to make sure we're not + * overwriting another subdatabase, or else this operation + * won't be undoable. Open a second cursor and check + * for the existence of newname; it shouldn't appear under + * us since we hold the metadata lock. + */ + if ((ret = __db_cursor(mdbp, ip, txn, &ndbc, + CDB_LOCKING(env) ? DB_WRITECURSOR : 0)) != 0) + goto err; + DB_SET_DBT(key, newname, strlen(newname)); + + /* + * We don't actually care what the meta page of the potentially- + * overwritten DB is; we just care about existence. + */ + memset(&ndata, 0, sizeof(ndata)); + F_SET(&ndata, DB_DBT_USERMEM | DB_DBT_PARTIAL); + + if ((ret = __dbc_get(ndbc, &key, &ndata, DB_SET)) == 0) { + /* A subdb called newname exists. Bail. */ + ret = EEXIST; + __db_errx(env, "rename: database %s exists", newname); + goto err; + } else if (ret != DB_NOTFOUND) + goto err; + + /* + * Now do the put first; we don't want to lose our only + * reference to the subdb. Use the second cursor so the + * first one continues to point to the old record. + */ + if ((ret = __dbc_put(ndbc, &key, &data, DB_KEYFIRST)) != 0) + goto err; + if ((ret = __dbc_del(dbc, 0)) != 0) { + /* + * If the delete fails, try to delete the record + * we just put, in case we're not txn-protected. + */ + (void)__dbc_del(ndbc, 0); + goto err; + } + + break; + case MU_OPEN: + /* + * Get the subdatabase information. If it already exists, + * copy out the page number and we're done. + */ + switch (ret) { + case 0: + if (LF_ISSET(DB_CREATE) && LF_ISSET(DB_EXCL)) { + ret = EEXIST; + goto err; + } + memcpy(&sdbp->meta_pgno, data.data, sizeof(db_pgno_t)); + DB_NTOHL_SWAP(env, &sdbp->meta_pgno); + goto done; + case DB_NOTFOUND: + if (LF_ISSET(DB_CREATE)) + break; + /* + * No db_err, it is reasonable to remove a + * nonexistent db. + */ + ret = ENOENT; + goto err; + default: + goto err; + } + + /* Create a subdatabase. */ + if ((ret = __db_new(dbc, + type == DB_HASH ? P_HASHMETA : P_BTREEMETA, NULL, &p)) != 0) + goto err; + sdbp->meta_pgno = PGNO(p); + + /* + * XXX + * We're handling actual data, not on-page meta-data, so it + * hasn't been converted to/from opposite endian architectures. + * Do it explicitly, now. + */ + t_pgno = PGNO(p); + DB_HTONL_SWAP(env, &t_pgno); + memset(&ndata, 0, sizeof(ndata)); + ndata.data = &t_pgno; + ndata.size = sizeof(db_pgno_t); + if ((ret = __dbc_put(dbc, &key, &ndata, 0)) != 0) + goto err; + F_SET(sdbp, DB_AM_CREATED); + break; + } + +err: +done: /* + * If we allocated a page: if we're successful, mark the page dirty + * and return it to the cache, otherwise, discard/free it. + */ + if (p != NULL && (t_ret = __memp_fput(mdbp->mpf, + dbc->thread_info, p, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + + /* Discard the cursor(s) and data. */ + if (data.data != NULL) + __os_ufree(env, data.data); + if (dbc != NULL && (t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + if (ndbc != NULL && (t_ret = __dbc_close(ndbc)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __env_setup -- + * Set up the underlying environment during a db_open. + * + * PUBLIC: int __env_setup __P((DB *, + * PUBLIC: DB_TXN *, const char *, const char *, u_int32_t, u_int32_t)); + */ +int +__env_setup(dbp, txn, fname, dname, id, flags) + DB *dbp; + DB_TXN *txn; + const char *fname, *dname; + u_int32_t id, flags; +{ + DB *ldbp; + DB_ENV *dbenv; + ENV *env; + u_int32_t maxid; + int ret; + + env = dbp->env; + dbenv = env->dbenv; + + /* If we don't yet have an environment, it's time to create it. */ + if (!F_ISSET(env, ENV_OPEN_CALLED)) { + /* Make sure we have at least DB_MINCACHE pages in our cache. */ + if (dbenv->mp_gbytes == 0 && + dbenv->mp_bytes < dbp->pgsize * DB_MINPAGECACHE && + (ret = __memp_set_cachesize( + dbenv, 0, dbp->pgsize * DB_MINPAGECACHE, 0)) != 0) + return (ret); + + if ((ret = __env_open(dbenv, NULL, DB_CREATE | + DB_INIT_MPOOL | DB_PRIVATE | LF_ISSET(DB_THREAD), 0)) != 0) + return (ret); + } + + /* Join the underlying cache. */ + if ((!F_ISSET(dbp, DB_AM_INMEM) || dname == NULL) && + (ret = __env_mpool(dbp, fname, flags)) != 0) + return (ret); + + /* We may need a per-thread mutex. */ + if (LF_ISSET(DB_THREAD) && (ret = __mutex_alloc( + env, MTX_DB_HANDLE, DB_MUTEX_PROCESS_ONLY, &dbp->mutex)) != 0) + return (ret); + + /* + * Set up a bookkeeping entry for this database in the log region, + * if such a region exists. Note that even if we're in recovery + * or a replication client, where we won't log registries, we'll + * still need an FNAME struct, so LOGGING_ON is the correct macro. + */ + if (LOGGING_ON(env) && dbp->log_filename == NULL +#if !defined(DEBUG_ROP) && !defined(DEBUG_WOP) && !defined(DIAGNOSTIC) + && (txn != NULL || F_ISSET(dbp, DB_AM_RECOVER)) +#endif +#if !defined(DEBUG_ROP) + && !F_ISSET(dbp, DB_AM_RDONLY) +#endif + ) { + if ((ret = __dbreg_setup(dbp, + F_ISSET(dbp, DB_AM_INMEM) ? dname : fname, + F_ISSET(dbp, DB_AM_INMEM) ? NULL : dname, id)) != 0) + return (ret); + + /* + * If we're actively logging and our caller isn't a + * recovery function that already did so, then assign + * this dbp a log fileid. + */ + if (DBENV_LOGGING(env) && !F_ISSET(dbp, DB_AM_RECOVER) && + (ret = __dbreg_new_id(dbp, txn)) != 0) + return (ret); + } + + /* + * Insert ourselves into the ENV's dblist. We allocate a + * unique ID to each {fileid, meta page number} pair, and to + * each temporary file (since they all have a zero fileid). + * This ID gives us something to use to tell which DB handles + * go with which databases in all the cursor adjustment + * routines, where we don't want to do a lot of ugly and + * expensive memcmps. + */ + MUTEX_LOCK(env, env->mtx_dblist); + maxid = 0; + TAILQ_FOREACH(ldbp, &env->dblist, dblistlinks) { + /* + * There are three cases: on-disk database (first clause), + * named in-memory database (second clause), temporary database + * (never matches; no clause). + */ + if (!F_ISSET(dbp, DB_AM_INMEM)) { + if (memcmp(ldbp->fileid, dbp->fileid, DB_FILE_ID_LEN) + == 0 && ldbp->meta_pgno == dbp->meta_pgno) + break; + } else if (dname != NULL) { + if (F_ISSET(ldbp, DB_AM_INMEM) && + ldbp->dname != NULL && + strcmp(ldbp->dname, dname) == 0) + break; + } + if (ldbp->adj_fileid > maxid) + maxid = ldbp->adj_fileid; + } + + /* + * If ldbp is NULL, we didn't find a match. Assign the dbp an + * adj_fileid one higher than the largest we found, and + * insert it at the head of the master dbp list. + * + * If ldbp is not NULL, it is a match for our dbp. Give dbp + * the same ID that ldbp has, and add it after ldbp so they're + * together in the list. + */ + if (ldbp == NULL) { + dbp->adj_fileid = maxid + 1; + TAILQ_INSERT_HEAD(&env->dblist, dbp, dblistlinks); + } else { + dbp->adj_fileid = ldbp->adj_fileid; + TAILQ_INSERT_AFTER(&env->dblist, ldbp, dbp, dblistlinks); + } + MUTEX_UNLOCK(env, env->mtx_dblist); + + return (0); +} + +/* + * __env_mpool -- + * Set up the underlying environment cache during a db_open. + * + * PUBLIC: int __env_mpool __P((DB *, const char *, u_int32_t)); + */ +int +__env_mpool(dbp, fname, flags) + DB *dbp; + const char *fname; + u_int32_t flags; +{ + DBT pgcookie; + DB_MPOOLFILE *mpf; + DB_PGINFO pginfo; + ENV *env; + int fidset, ftype, ret; + int32_t lsn_off; + u_int8_t nullfid[DB_FILE_ID_LEN]; + u_int32_t clear_len; + + env = dbp->env; + + /* The LSN is the first entry on a DB page, byte offset 0. */ + lsn_off = F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LSN_OFF_NOTSET : 0; + + /* It's possible that this database is already open. */ + if (F_ISSET(dbp, DB_AM_OPEN_CALLED)) + return (0); + + /* + * If we need to pre- or post-process a file's pages on I/O, set the + * file type. If it's a hash file, always call the pgin and pgout + * routines. This means that hash files can never be mapped into + * process memory. If it's a btree file and requires swapping, we + * need to page the file in and out. This has to be right -- we can't + * mmap files that are being paged in and out. + */ + switch (dbp->type) { + case DB_BTREE: + case DB_RECNO: + ftype = F_ISSET(dbp, DB_AM_SWAP | DB_AM_ENCRYPT | DB_AM_CHKSUM) + ? DB_FTYPE_SET : DB_FTYPE_NOTSET; + clear_len = CRYPTO_ON(env) ? + (dbp->pgsize != 0 ? dbp->pgsize : DB_CLEARLEN_NOTSET) : + DB_PAGE_DB_LEN; + break; + case DB_HASH: + ftype = DB_FTYPE_SET; + clear_len = CRYPTO_ON(env) ? + (dbp->pgsize != 0 ? dbp->pgsize : DB_CLEARLEN_NOTSET) : + DB_PAGE_DB_LEN; + break; + case DB_QUEUE: + ftype = F_ISSET(dbp, + DB_AM_SWAP | DB_AM_ENCRYPT | DB_AM_CHKSUM) ? + DB_FTYPE_SET : DB_FTYPE_NOTSET; + + /* + * If we came in here without a pagesize set, then we need + * to mark the in-memory handle as having clear_len not + * set, because we don't really know the clear length or + * the page size yet (since the file doesn't yet exist). + */ + clear_len = dbp->pgsize != 0 ? dbp->pgsize : DB_CLEARLEN_NOTSET; + break; + case DB_UNKNOWN: + /* + * If we're running in the verifier, our database might + * be corrupt and we might not know its type--but we may + * still want to be able to verify and salvage. + * + * If we can't identify the type, it's not going to be safe + * to call __db_pgin--we pretty much have to give up all + * hope of salvaging cross-endianness. Proceed anyway; + * at worst, the database will just appear more corrupt + * than it actually is, but at best, we may be able + * to salvage some data even with no metadata page. + */ + if (F_ISSET(dbp, DB_AM_VERIFYING)) { + ftype = DB_FTYPE_NOTSET; + clear_len = DB_PAGE_DB_LEN; + break; + } + + /* + * This might be an in-memory file and we won't know its + * file type until after we open it and read the meta-data + * page. + */ + if (F_ISSET(dbp, DB_AM_INMEM)) { + clear_len = DB_CLEARLEN_NOTSET; + ftype = DB_FTYPE_NOTSET; + lsn_off = DB_LSN_OFF_NOTSET; + break; + } + /* FALLTHROUGH */ + default: + return (__db_unknown_type(env, "DB->open", dbp->type)); + } + + mpf = dbp->mpf; + + memset(nullfid, 0, DB_FILE_ID_LEN); + fidset = memcmp(nullfid, dbp->fileid, DB_FILE_ID_LEN); + if (fidset) + (void)__memp_set_fileid(mpf, dbp->fileid); + + (void)__memp_set_clear_len(mpf, clear_len); + (void)__memp_set_ftype(mpf, ftype); + (void)__memp_set_lsn_offset(mpf, lsn_off); + + pginfo.db_pagesize = dbp->pgsize; + pginfo.flags = + F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP)); + pginfo.type = dbp->type; + pgcookie.data = &pginfo; + pgcookie.size = sizeof(DB_PGINFO); + (void)__memp_set_pgcookie(mpf, &pgcookie); + +#ifndef DIAG_MVCC + if (F_ISSET(env->dbenv, DB_ENV_MULTIVERSION)) +#endif + if (F_ISSET(dbp, DB_AM_TXN) && + dbp->type != DB_QUEUE && dbp->type != DB_UNKNOWN) + LF_SET(DB_MULTIVERSION); + + if ((ret = __memp_fopen(mpf, NULL, fname, &dbp->dirname, + LF_ISSET(DB_CREATE | DB_DURABLE_UNKNOWN | DB_MULTIVERSION | + DB_NOMMAP | DB_ODDFILESIZE | DB_RDONLY | DB_TRUNCATE) | + (F_ISSET(env->dbenv, DB_ENV_DIRECT_DB) ? DB_DIRECT : 0) | + (F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_TXN_NOT_DURABLE : 0), + 0, dbp->pgsize)) != 0) { + /* + * The open didn't work; we need to reset the mpf, + * retaining the in-memory semantics (if any). + */ + (void)__memp_fclose(dbp->mpf, 0); + (void)__memp_fcreate(env, &dbp->mpf); + if (F_ISSET(dbp, DB_AM_INMEM)) + MAKE_INMEM(dbp); + return (ret); + } + + /* + * Set the open flag. We use it to mean that the dbp has gone + * through mpf setup, including dbreg_register. Also, below, + * the underlying access method open functions may want to do + * things like acquire cursors, so the open flag has to be set + * before calling them. + */ + F_SET(dbp, DB_AM_OPEN_CALLED); + if (!fidset && fname != NULL) { + (void)__memp_get_fileid(dbp->mpf, dbp->fileid); + dbp->preserve_fid = 1; + } + + return (0); +} + +/* + * __db_close -- + * DB->close method. + * + * PUBLIC: int __db_close __P((DB *, DB_TXN *, u_int32_t)); + */ +int +__db_close(dbp, txn, flags) + DB *dbp; + DB_TXN *txn; + u_int32_t flags; +{ + ENV *env; + int db_ref, deferred_close, ret, t_ret; + + env = dbp->env; + deferred_close = ret = 0; + + /* + * Validate arguments, but as a DB handle destructor, we can't fail. + * + * Check for consistent transaction usage -- ignore errors. Only + * internal callers specify transactions, so it's a serious problem + * if we get error messages. + */ + if (txn != NULL) + (void)__db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0); + + /* Refresh the structure and close any underlying resources. */ + ret = __db_refresh(dbp, txn, flags, &deferred_close, 0); + + /* + * If we've deferred the close because the logging of the close failed, + * return our failure right away without destroying the handle. + */ + if (deferred_close) + return (ret); + + /* !!! + * This code has an apparent race between the moment we read and + * decrement env->db_ref and the moment we check whether it's 0. + * However, if the environment is DBLOCAL, the user shouldn't have a + * reference to the env handle anyway; the only way we can get + * multiple dbps sharing a local env is if we open them internally + * during something like a subdatabase open. If any such thing is + * going on while the user is closing the original dbp with a local + * env, someone's already badly screwed up, so there's no reason + * to bother engineering around this possibility. + */ + MUTEX_LOCK(env, env->mtx_dblist); + db_ref = --env->db_ref; + MUTEX_UNLOCK(env, env->mtx_dblist); + if (F_ISSET(env, ENV_DBLOCAL) && db_ref == 0 && + (t_ret = __env_close(env->dbenv, 0)) != 0 && ret == 0) + ret = t_ret; + + /* Free the database handle. */ + memset(dbp, CLEAR_BYTE, sizeof(*dbp)); + __os_free(env, dbp); + + return (ret); +} + +/* + * __db_refresh -- + * Refresh the DB structure, releasing any allocated resources. + * This does most of the work of closing files now because refresh + * is what is used during abort processing (since we can't destroy + * the actual handle) and during abort processing, we may have a + * fully opened handle. + * + * PUBLIC: int __db_refresh __P((DB *, DB_TXN *, u_int32_t, int *, int)); + */ +int +__db_refresh(dbp, txn, flags, deferred_closep, reuse) + DB *dbp; + DB_TXN *txn; + u_int32_t flags; + int *deferred_closep, reuse; +{ + DB *sdbp; + DBC *dbc; + DB_FOREIGN_INFO *f_info, *tmp; + DB_LOCKER *locker; + DB_LOCKREQ lreq; + ENV *env; + REGENV *renv; + REGINFO *infop; + u_int32_t save_flags; + int resync, ret, t_ret; + + ret = 0; + + env = dbp->env; + infop = env->reginfo; + if (infop != NULL) + renv = infop->primary; + else + renv = NULL; + + /* + * If this dbp is not completely open, avoid trapping by trying to + * sync without an mpool file. + */ + if (dbp->mpf == NULL) + LF_SET(DB_NOSYNC); + + /* If never opened, or not currently open, it's easy. */ + if (!F_ISSET(dbp, DB_AM_OPEN_CALLED)) + goto never_opened; + + /* + * If we have any secondary indices, disassociate them from us. + * We don't bother with the mutex here; it only protects some + * of the ops that will make us core-dump mid-close anyway, and + * if you're trying to do something with a secondary *while* you're + * closing the primary, you deserve what you get. The disassociation + * is mostly done just so we can close primaries and secondaries in + * any order--but within one thread of control. + */ + LIST_FOREACH(sdbp, &dbp->s_secondaries, s_links) { + LIST_REMOVE(sdbp, s_links); + if ((t_ret = __db_disassociate(sdbp)) != 0 && ret == 0) + ret = t_ret; + } + + /* + * Disassociate ourself from any databases using us as a foreign key + * database by clearing the referring db's pointer. Reclaim memory. + */ + f_info = LIST_FIRST(&dbp->f_primaries); + while (f_info != NULL) { + tmp = LIST_NEXT(f_info, f_links); + LIST_REMOVE(f_info, f_links); + f_info->dbp->s_foreign = NULL; + __os_free(env, f_info); + f_info = tmp; + } + + if (dbp->s_foreign != NULL && + (t_ret = __db_disassociate_foreign(dbp)) != 0 && ret == 0) + ret = t_ret; + + /* + * Sync the underlying access method. Do before closing the cursors + * because DB->sync allocates cursors in order to write Recno backing + * source text files. + * + * Sync is slow on some systems, notably Solaris filesystems where the + * entire buffer cache is searched. If we're in recovery, don't flush + * the file, it's not necessary. + */ + if (!LF_ISSET(DB_NOSYNC) && + !F_ISSET(dbp, DB_AM_DISCARD | DB_AM_RECOVER) && + (t_ret = __db_sync(dbp)) != 0 && ret == 0) + ret = t_ret; + + /* + * Go through the active cursors and call the cursor recycle routine, + * which resolves pending operations and moves the cursors onto the + * free list. Then, walk the free list and call the cursor destroy + * routine. Note that any failure on a close is considered "really + * bad" and we just break out of the loop and force forward. + */ + resync = TAILQ_FIRST(&dbp->active_queue) == NULL ? 0 : 1; + while ((dbc = TAILQ_FIRST(&dbp->active_queue)) != NULL) + if ((t_ret = __dbc_close(dbc)) != 0) { + if (ret == 0) + ret = t_ret; + break; + } + + while ((dbc = TAILQ_FIRST(&dbp->free_queue)) != NULL) + if ((t_ret = __dbc_destroy(dbc)) != 0) { + if (ret == 0) + ret = t_ret; + break; + } + + /* + * Close any outstanding join cursors. Join cursors destroy themselves + * on close and have no separate destroy routine. We don't have to set + * the resync flag here, because join cursors aren't write cursors. + */ + while ((dbc = TAILQ_FIRST(&dbp->join_queue)) != NULL) + if ((t_ret = __db_join_close(dbc)) != 0) { + if (ret == 0) + ret = t_ret; + break; + } + + /* + * Sync the memory pool, even though we've already called DB->sync, + * because closing cursors can dirty pages by deleting items they + * referenced. + * + * Sync is slow on some systems, notably Solaris filesystems where the + * entire buffer cache is searched. If we're in recovery, don't flush + * the file, it's not necessary. + */ + if (resync && !LF_ISSET(DB_NOSYNC) && + !F_ISSET(dbp, DB_AM_DISCARD | DB_AM_RECOVER) && + (t_ret = __memp_fsync(dbp->mpf)) != 0 && ret == 0) + ret = t_ret; + +never_opened: + /* + * At this point, we haven't done anything to render the DB handle + * unusable, at least by a transaction abort. Take the opportunity + * now to log the file close if we have initialized the logging + * information. If this log fails and we're in a transaction, + * we have to bail out of the attempted close; we'll need a dbp in + * order to successfully abort the transaction, and we can't conjure + * a new one up because we haven't gotten out the dbreg_register + * record that represents the close. In this case, we put off + * actually closing the dbp until we've performed the abort. + */ + if (!reuse && LOGGING_ON(dbp->env) && dbp->log_filename != NULL) { + /* + * Discard the log file id, if any. We want to log the close + * if and only if this is not a recovery dbp or a client dbp, + * or a dead dbp handle. + */ + DB_ASSERT(env, renv != NULL); + if (F_ISSET(dbp, DB_AM_RECOVER) || IS_REP_CLIENT(env) || + dbp->timestamp != renv->rep_timestamp) { + if ((t_ret = __dbreg_revoke_id(dbp, + 0, DB_LOGFILEID_INVALID)) == 0 && ret == 0) + ret = t_ret; + if ((t_ret = __dbreg_teardown(dbp)) != 0 && ret == 0) + ret = t_ret; + } else { + if ((t_ret = __dbreg_close_id(dbp, + txn, DBREG_CLOSE)) != 0 && txn != NULL) { + /* + * We're in a txn and the attempt to log the + * close failed; let the txn subsystem know + * that we need to destroy this dbp once we're + * done with the abort, then bail from the + * close. + * + * Note that if the attempt to put off the + * close -also- fails--which it won't unless + * we're out of heap memory--we're really + * screwed. Panic. + */ + if ((ret = + __txn_closeevent(env, txn, dbp)) != 0) + return (__env_panic(env, ret)); + if (deferred_closep != NULL) + *deferred_closep = 1; + return (t_ret); + } + /* + * If dbreg_close_id failed and we were not in a + * transaction, then we need to finish this close + * because the caller can't do anything with the + * handle after we return an error. We rely on + * dbreg_close_id to mark the entry in some manner + * so that we do not do a clean shutdown of this + * environment. If shutdown isn't clean, then the + * application *must* run recovery and that will + * generate the RCLOSE record. + */ + } + + } + + /* Close any handle we've been holding since the open. */ + if (dbp->saved_open_fhp != NULL && + (t_ret = __os_closehandle(env, dbp->saved_open_fhp)) != 0 && + ret == 0) + ret = t_ret; + + /* + * Remove this DB handle from the ENV's dblist, if it's been added. + * + * Close our reference to the underlying cache while locked, we don't + * want to race with a thread searching for our underlying cache link + * while opening a DB handle. + * + * The DB handle may not yet have been added to the ENV list, don't + * blindly call the underlying TAILQ_REMOVE macro. Explicitly reset + * the field values to NULL so that we can't call TAILQ_REMOVE twice. + */ + MUTEX_LOCK(env, env->mtx_dblist); + if (!reuse && + (dbp->dblistlinks.tqe_next != NULL || + dbp->dblistlinks.tqe_prev != NULL)) { + TAILQ_REMOVE(&env->dblist, dbp, dblistlinks); + dbp->dblistlinks.tqe_next = NULL; + dbp->dblistlinks.tqe_prev = NULL; + } + + /* Close the memory pool file handle. */ + if (dbp->mpf != NULL) { + if ((t_ret = __memp_fclose(dbp->mpf, + F_ISSET(dbp, DB_AM_DISCARD) ? DB_MPOOL_DISCARD : 0)) != 0 && + ret == 0) + ret = t_ret; + dbp->mpf = NULL; + if (reuse && + (t_ret = __memp_fcreate(env, &dbp->mpf)) != 0 && + ret == 0) + ret = t_ret; + } + + MUTEX_UNLOCK(env, env->mtx_dblist); + + /* + * Call the access specific close function. + * + * We do this here rather than in __db_close as we need to do this when + * aborting an open so that file descriptors are closed and abort of + * renames can succeed on platforms that lock open files (such as + * Windows). In particular, we need to ensure that all the extents + * associated with a queue are closed so that queue renames can be + * aborted. + * + * It is also important that we do this before releasing the handle + * lock, because dbremove and dbrename assume that once they have the + * handle lock, it is safe to modify the underlying file(s). + * + * !!! + * Because of where these functions are called in the DB handle close + * process, these routines can't do anything that would dirty pages or + * otherwise affect closing down the database. Specifically, we can't + * abort and recover any of the information they control. + */ +#ifdef HAVE_PARTITION + if (dbp->p_internal != NULL && + (t_ret = __partition_close(dbp, txn, flags)) != 0 && ret == 0) + ret = t_ret; +#endif + if ((t_ret = __bam_db_close(dbp)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __ham_db_close(dbp)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __qam_db_close(dbp, dbp->flags)) != 0 && ret == 0) + ret = t_ret; + + /* + * !!! + * At this point, the access-method specific information has been + * freed. From now on, we can use the dbp, but not touch any + * access-method specific data. + */ + + if (!reuse && dbp->locker != NULL) { + /* We may have pending trade operations on this dbp. */ + if (txn == NULL) + txn = dbp->cur_txn; + if (IS_REAL_TXN(txn)) + __txn_remlock(env, + txn, &dbp->handle_lock, dbp->locker); + + /* We may be holding the handle lock; release it. */ + lreq.op = DB_LOCK_PUT_ALL; + lreq.obj = NULL; + if ((t_ret = __lock_vec(env, + dbp->locker, 0, &lreq, 1, NULL)) != 0 && ret == 0) + ret = t_ret; + + if ((t_ret = + __lock_id_free(env, dbp->locker)) != 0 && ret == 0) + ret = t_ret; + dbp->locker = NULL; + LOCK_INIT(dbp->handle_lock); + } + + /* + * If this is a temporary file (un-named in-memory file), then + * discard the locker ID allocated as the fileid. + */ + if (LOCKING_ON(env) && + F_ISSET(dbp, DB_AM_INMEM) && !dbp->preserve_fid && + *(u_int32_t *)dbp->fileid != DB_LOCK_INVALIDID) { + if ((t_ret = __lock_getlocker(env->lk_handle, + *(u_int32_t *)dbp->fileid, 0, &locker)) == 0) + t_ret = __lock_id_free(env, locker); + if (ret == 0) + ret = t_ret; + } + + if (reuse) { + /* + * If we are reusing this dbp, then we're done now. Re-init + * the handle, preserving important flags, and then return. + * This code is borrowed from __db_init, which does more + * than we can do here. + */ + save_flags = F_ISSET(dbp, DB_AM_INMEM | DB_AM_TXN); + + if ((ret = __bam_db_create(dbp)) != 0) + return (ret); + if ((ret = __ham_db_create(dbp)) != 0) + return (ret); + if ((ret = __qam_db_create(dbp)) != 0) + return (ret); + + /* Restore flags */ + dbp->flags = dbp->orig_flags | save_flags; + + if (FLD_ISSET(save_flags, DB_AM_INMEM)) { + /* + * If this is inmem, then it may have a fileid + * even if it was never opened, and we need to + * clear out that fileid. + */ + memset(dbp->fileid, 0, sizeof(dbp->fileid)); + MAKE_INMEM(dbp); + } + return (ret); + } + + dbp->type = DB_UNKNOWN; + + /* + * The thread mutex may have been invalidated in __dbreg_close_id if the + * fname refcount did not go to 0. If not, discard the thread mutex. + */ + if ((t_ret = __mutex_free(env, &dbp->mutex)) != 0 && ret == 0) + ret = t_ret; + + /* Discard any memory allocated for the file and database names. */ + if (dbp->fname != NULL) { + __os_free(dbp->env, dbp->fname); + dbp->fname = NULL; + } + if (dbp->dname != NULL) { + __os_free(dbp->env, dbp->dname); + dbp->dname = NULL; + } + + /* Discard any memory used to store returned data. */ + if (dbp->my_rskey.data != NULL) + __os_free(dbp->env, dbp->my_rskey.data); + if (dbp->my_rkey.data != NULL) + __os_free(dbp->env, dbp->my_rkey.data); + if (dbp->my_rdata.data != NULL) + __os_free(dbp->env, dbp->my_rdata.data); + + /* For safety's sake; we may refresh twice. */ + memset(&dbp->my_rskey, 0, sizeof(DBT)); + memset(&dbp->my_rkey, 0, sizeof(DBT)); + memset(&dbp->my_rdata, 0, sizeof(DBT)); + + /* Clear out fields that normally get set during open. */ + memset(dbp->fileid, 0, sizeof(dbp->fileid)); + dbp->adj_fileid = 0; + dbp->meta_pgno = 0; + dbp->cur_locker = NULL; + dbp->cur_txn = NULL; + dbp->associate_locker = NULL; + dbp->cl_id = 0; + dbp->open_flags = 0; + + /* + * If we are being refreshed with a txn specified, then we need + * to make sure that we clear out the lock handle field, because + * releasing all the locks for this transaction will release this + * lock and we don't want close to stumble upon this handle and + * try to close it. + */ + if (txn != NULL) + LOCK_INIT(dbp->handle_lock); + + /* Reset flags to whatever the user configured. */ + dbp->flags = dbp->orig_flags; + + return (ret); +} + +/* + * __db_disassociate -- + * Destroy the association between a given secondary and its primary. + */ +static int +__db_disassociate(sdbp) + DB *sdbp; +{ + DBC *dbc; + int ret, t_ret; + + ret = 0; + + sdbp->s_callback = NULL; + sdbp->s_primary = NULL; + sdbp->get = sdbp->stored_get; + sdbp->close = sdbp->stored_close; + + /* + * Complain, but proceed, if we have any active cursors. (We're in + * the middle of a close, so there's really no turning back.) + */ + if (sdbp->s_refcnt != 1 || + TAILQ_FIRST(&sdbp->active_queue) != NULL || + TAILQ_FIRST(&sdbp->join_queue) != NULL) { + __db_errx(sdbp->env, + "Closing a primary DB while a secondary DB has active cursors is unsafe"); + ret = EINVAL; + } + sdbp->s_refcnt = 0; + + while ((dbc = TAILQ_FIRST(&sdbp->free_queue)) != NULL) + if ((t_ret = __dbc_destroy(dbc)) != 0 && ret == 0) + ret = t_ret; + + F_CLR(sdbp, DB_AM_SECONDARY); + return (ret); +} + +/* + * __db_disassociate_foreign -- + * Destroy the association between a given secondary and its foreign. + */ +static int +__db_disassociate_foreign(sdbp) + DB *sdbp; +{ + DB *fdbp; + DB_FOREIGN_INFO *f_info, *tmp; + int ret; + + if (sdbp->s_foreign == NULL) + return (0); + if ((ret = __os_malloc(sdbp->env, sizeof(DB_FOREIGN_INFO), &tmp)) != 0) + return (ret); + + fdbp = sdbp->s_foreign; + ret = 0; + f_info = LIST_FIRST(&fdbp->f_primaries); + while (f_info != NULL) { + tmp = LIST_NEXT(f_info, f_links); + if (f_info ->dbp == sdbp) { + LIST_REMOVE(f_info, f_links); + __os_free(sdbp->env, f_info); + } + f_info = tmp; + } + + return (ret); +} + +/* + * __db_log_page + * Log a meta-data or root page during a subdatabase create operation. + * + * PUBLIC: int __db_log_page __P((DB *, DB_TXN *, DB_LSN *, db_pgno_t, PAGE *)); + */ +int +__db_log_page(dbp, txn, lsn, pgno, page) + DB *dbp; + DB_TXN *txn; + DB_LSN *lsn; + db_pgno_t pgno; + PAGE *page; +{ + DBT page_dbt; + DB_LSN new_lsn; + int ret; + + if (!LOGGING_ON(dbp->env) || txn == NULL) + return (0); + + memset(&page_dbt, 0, sizeof(page_dbt)); + page_dbt.size = dbp->pgsize; + page_dbt.data = page; + + ret = __crdel_metasub_log(dbp, txn, &new_lsn, 0, pgno, &page_dbt, lsn); + + if (ret == 0) + page->lsn = new_lsn; + return (ret); +} + +/* + * __db_backup_name + * Create the backup file name for a given file. + * + * PUBLIC: int __db_backup_name __P((ENV *, + * PUBLIC: const char *, DB_TXN *, char **)); + */ +#undef BACKUP_PREFIX +#define BACKUP_PREFIX "__db." + +#undef MAX_INT_TO_HEX +#define MAX_INT_TO_HEX 8 + +int +__db_backup_name(env, name, txn, backup) + ENV *env; + const char *name; + DB_TXN *txn; + char **backup; +{ + u_int32_t id; + size_t len; + int ret; + char *p, *retp; + + *backup = NULL; + + /* + * Part of the name may be a full path, so we need to make sure that + * we allocate enough space for it, even in the case where we don't + * use the entire filename for the backup name. + */ + len = strlen(name) + strlen(BACKUP_PREFIX) + 2 * MAX_INT_TO_HEX + 1; + if ((ret = __os_malloc(env, len, &retp)) != 0) + return (ret); + + /* + * Create the name. Backup file names are in one of 2 forms: in a + * transactional env "__db.TXNID.ID", where ID is a random number, + * and in any other env "__db.FILENAME". + * + * In addition, the name passed may contain an env-relative path. + * In that case, put the "__db." in the right place (in the last + * component of the pathname). + * + * There are four cases here: + * 1. simple path w/out transaction + * 2. simple path + transaction + * 3. multi-component path w/out transaction + * 4. multi-component path + transaction + */ + p = __db_rpath(name); + if (IS_REAL_TXN(txn)) { + __os_unique_id(env, &id); + if (p == NULL) /* Case 2. */ + snprintf(retp, len, "%s%x.%x", + BACKUP_PREFIX, txn->txnid, id); + else /* Case 4. */ + snprintf(retp, len, "%.*s%x.%x", + (int)(p - name) + 1, name, txn->txnid, id); + } else { + if (p == NULL) /* Case 1. */ + snprintf(retp, len, "%s%s", BACKUP_PREFIX, name); + else /* Case 3. */ + snprintf(retp, len, "%.*s%s%s", + (int)(p - name) + 1, name, BACKUP_PREFIX, p + 1); + } + + *backup = retp; + return (0); +} + +#ifdef CONFIG_TEST +/* + * __db_testcopy + * Create a copy of all backup files and our "main" DB. + * + * PUBLIC: #ifdef CONFIG_TEST + * PUBLIC: int __db_testcopy __P((ENV *, DB *, const char *)); + * PUBLIC: #endif + */ +int +__db_testcopy(env, dbp, name) + ENV *env; + DB *dbp; + const char *name; +{ + DB_MPOOL *dbmp; + DB_MPOOLFILE *mpf; + + DB_ASSERT(env, dbp != NULL || name != NULL); + + if (name == NULL) { + dbmp = env->mp_handle; + mpf = dbp->mpf; + name = R_ADDR(dbmp->reginfo, mpf->mfp->path_off); + } + + if (dbp != NULL && dbp->type == DB_QUEUE) + return (__qam_testdocopy(dbp, name)); + else +#ifdef HAVE_PARTITION + if (dbp != NULL && DB_IS_PARTITIONED(dbp)) + return (__part_testdocopy(dbp, name)); + else +#endif + return (__db_testdocopy(env, name)); +} + +static int +__qam_testdocopy(dbp, name) + DB *dbp; + const char *name; +{ + DB_THREAD_INFO *ip; + QUEUE_FILELIST *filelist, *fp; + int ret; + char buf[DB_MAXPATHLEN], *dir; + + filelist = NULL; + if ((ret = __db_testdocopy(dbp->env, name)) != 0) + return (ret); + + /* Call ENV_GET_THREAD_INFO to get a valid DB_THREAD_INFO */ + ENV_GET_THREAD_INFO(dbp->env, ip); + if (dbp->mpf != NULL && + (ret = __qam_gen_filelist(dbp, ip, &filelist)) != 0) + goto done; + + if (filelist == NULL) + return (0); + dir = ((QUEUE *)dbp->q_internal)->dir; + for (fp = filelist; fp->mpf != NULL; fp++) { + snprintf(buf, sizeof(buf), + QUEUE_EXTENT, dir, PATH_SEPARATOR[0], name, fp->id); + if ((ret = __db_testdocopy(dbp->env, buf)) != 0) + return (ret); + } + +done: __os_free(dbp->env, filelist); + return (0); +} + +/* + * __db_testdocopy + * Create a copy of all backup files and our "main" DB. + * PUBLIC: int __db_testdocopy __P((ENV *, const char *)); + */ +int +__db_testdocopy(env, name) + ENV *env; + const char *name; +{ + size_t len; + int dircnt, i, ret; + char *copy, **namesp, *p, *real_name; + + dircnt = 0; + copy = NULL; + namesp = NULL; + + /* Create the real backing file name. */ + if ((ret = __db_appname(env, + DB_APP_DATA, name, NULL, &real_name)) != 0) + return (ret); + + /* + * !!! + * There are tests that attempt to copy non-existent files. I'd guess + * it's a testing bug, but I don't have time to figure it out. Block + * the case here. + */ + if (__os_exists(env, real_name, NULL) != 0) { + __os_free(env, real_name); + return (0); + } + + /* + * Copy the file itself. + * + * Allocate space for the file name, including adding an ".afterop" and + * trailing nul byte. + */ + len = strlen(real_name) + sizeof(".afterop"); + if ((ret = __os_malloc(env, len, ©)) != 0) + goto err; + snprintf(copy, len, "%s.afterop", real_name); + if ((ret = __db_makecopy(env, real_name, copy)) != 0) + goto err; + + /* + * Get the directory path to call __os_dirlist(). + */ + if ((p = __db_rpath(real_name)) != NULL) + *p = '\0'; + if ((ret = __os_dirlist(env, real_name, 0, &namesp, &dircnt)) != 0) + goto err; + + /* + * Walk the directory looking for backup files. Backup file names in + * transactional environments are of the form: + * + * BACKUP_PREFIX.TXNID.ID + */ + for (i = 0; i < dircnt; i++) { + /* Check for a related backup file name. */ + if (strncmp( + namesp[i], BACKUP_PREFIX, sizeof(BACKUP_PREFIX) - 1) != 0) + continue; + p = namesp[i] + sizeof(BACKUP_PREFIX); + p += strspn(p, "0123456789ABCDEFabcdef"); + if (*p != '.') + continue; + ++p; + p += strspn(p, "0123456789ABCDEFabcdef"); + if (*p != '\0') + continue; + + /* + * Copy the backup file. + * + * Allocate space for the file name, including adding a + * ".afterop" and trailing nul byte. + */ + if (real_name != NULL) { + __os_free(env, real_name); + real_name = NULL; + } + if ((ret = __db_appname(env, + DB_APP_DATA, namesp[i], NULL, &real_name)) != 0) + goto err; + if (copy != NULL) { + __os_free(env, copy); + copy = NULL; + } + len = strlen(real_name) + sizeof(".afterop"); + if ((ret = __os_malloc(env, len, ©)) != 0) + goto err; + snprintf(copy, len, "%s.afterop", real_name); + if ((ret = __db_makecopy(env, real_name, copy)) != 0) + goto err; + } + +err: if (namesp != NULL) + __os_dirfree(env, namesp, dircnt); + if (copy != NULL) + __os_free(env, copy); + if (real_name != NULL) + __os_free(env, real_name); + return (ret); +} + +static int +__db_makecopy(env, src, dest) + ENV *env; + const char *src, *dest; +{ + DB_FH *rfhp, *wfhp; + size_t rcnt, wcnt; + int ret; + char *buf; + + rfhp = wfhp = NULL; + + if ((ret = __os_malloc(env, 64 * 1024, &buf)) != 0) + goto err; + + if ((ret = __os_open(env, src, 0, + DB_OSO_RDONLY, DB_MODE_600, &rfhp)) != 0) + goto err; + if ((ret = __os_open(env, dest, 0, + DB_OSO_CREATE | DB_OSO_TRUNC, DB_MODE_600, &wfhp)) != 0) + goto err; + + for (;;) { + if ((ret = + __os_read(env, rfhp, buf, sizeof(buf), &rcnt)) != 0) + goto err; + if (rcnt == 0) + break; + if ((ret = + __os_write(env, wfhp, buf, sizeof(buf), &wcnt)) != 0) + goto err; + } + + if (0) { +err: __db_err(env, ret, "__db_makecopy: %s -> %s", src, dest); + } + + if (buf != NULL) + __os_free(env, buf); + if (rfhp != NULL) + (void)__os_closehandle(env, rfhp); + if (wfhp != NULL) + (void)__os_closehandle(env, wfhp); + return (ret); +} +#endif diff --git a/src/libs/resiprocate/contrib/db/db/db.src b/src/libs/resiprocate/contrib/db/db/db.src new file mode 100644 index 00000000..2136b79f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db.src @@ -0,0 +1,328 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +DBPRIVATE +PREFIX __db + +INCLUDE #include "db_int.h" +INCLUDE #include "dbinc/crypto.h" +INCLUDE #include "dbinc/db_page.h" +INCLUDE #include "dbinc/db_dispatch.h" +INCLUDE #include "dbinc/db_am.h" +INCLUDE #include "dbinc/log.h" +INCLUDE #include "dbinc/txn.h" +INCLUDE + +/* + * addrem -- Add or remove an entry from a duplicate page. + * + * opcode: identifies if this is an add or delete. + * fileid: file identifier of the file being modified. + * pgno: duplicate page number. + * indx: location at which to insert or delete. + * nbytes: number of bytes added/removed to/from the page. + * hdr: header for the data item. + * dbt: data that is deleted or is to be added. + * pagelsn: former lsn of the page. + * + * If the hdr was NULL then, the dbt is a regular B_KEYDATA. + * If the dbt was NULL then the hdr is a complete item to be + * pasted on the page. + */ +BEGIN addrem 42 41 +ARG opcode u_int32_t lu +DB fileid int32_t ld +ARG pgno db_pgno_t lu +ARG indx u_int32_t lu +ARG nbytes u_int32_t lu +DBT hdr DBT s +DBT dbt DBT s +POINTER pagelsn DB_LSN * lu +END + +/* + * big -- Handles addition and deletion of big key/data items. + * + * opcode: identifies get/put. + * fileid: file identifier of the file being modified. + * pgno: page onto which data is being added/removed. + * prev_pgno: the page before the one we are logging. + * next_pgno: the page after the one we are logging. + * dbt: data being written onto the page. + * pagelsn: former lsn of the orig_page. + * prevlsn: former lsn of the prev_pgno. + * nextlsn: former lsn of the next_pgno. This is not currently used, but + * may be used later if we actually do overwrites of big key/ + * data items in place. + */ +BEGIN big 42 43 +ARG opcode u_int32_t lu +DB fileid int32_t ld +ARG pgno db_pgno_t lu +ARG prev_pgno db_pgno_t lu +ARG next_pgno db_pgno_t lu +DBT dbt DBT s +POINTER pagelsn DB_LSN * lu +POINTER prevlsn DB_LSN * lu +POINTER nextlsn DB_LSN * lu +END + +/* + * ovref -- Handles increment/decrement of overflow page reference count. + * + * fileid: identifies the file being modified. + * pgno: page number whose ref count is being incremented/decremented. + * adjust: the adjustment being made. + * lsn: the page's original lsn. + */ +BEGIN ovref 42 44 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +ARG adjust int32_t ld +POINTER lsn DB_LSN * lu +END + +/* + * relink -- Handles relinking around a page. + * + * opcode: indicates if this is an addpage or delete page + * pgno: the page being changed. + * lsn the page's original lsn. + * prev: the previous page. + * lsn_prev: the previous page's original lsn. + * next: the next page. + * lsn_next: the previous page's original lsn. + */ +BEGIN_COMPAT relink 42 45 +ARG opcode u_int32_t lu +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER lsn DB_LSN * lu +ARG prev db_pgno_t lu +POINTER lsn_prev DB_LSN * lu +ARG next db_pgno_t lu +POINTER lsn_next DB_LSN * lu +END + +/* + * Debug -- log an operation upon entering an access method. + * op: Operation (cursor, c_close, c_get, c_put, c_del, + * get, put, delete). + * fileid: identifies the file being acted upon. + * key: key paramater + * data: data parameter + * flags: flags parameter + */ +BEGIN debug 42 47 +DBT op DBT s +ARG fileid int32_t ld +DBT key DBT s +DBT data DBT s +ARG arg_flags u_int32_t lu +END + +/* + * noop -- do nothing, but get an LSN. + */ +BEGIN noop 42 48 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER prevlsn DB_LSN * lu +END + +/* + * pg_alloc: used to record allocating a new page. + * + * meta_lsn: the original lsn of the page reference by meta_pgno. + * meta_pgno the page pointing at the allocated page in the free list. + * If the list is unsorted this is the metadata page. + * page_lsn: the allocated page's original lsn. + * pgno: the page allocated. + * ptype: the type of the page allocated. + * next: the next page on the free list. + * last_pgno: the last page in the file after this op (4.3+). + */ +BEGIN_COMPAT pg_alloc 42 49 +DB fileid int32_t ld +POINTER meta_lsn DB_LSN * lu +ARG meta_pgno db_pgno_t lu +POINTER page_lsn DB_LSN * lu +ARG pgno db_pgno_t lu +ARG ptype u_int32_t lu +ARG next db_pgno_t lu +END + +BEGIN pg_alloc 43 49 +DB fileid int32_t ld +POINTER meta_lsn DB_LSN * lu +ARG meta_pgno db_pgno_t lu +POINTER page_lsn DB_LSN * lu +ARG pgno db_pgno_t lu +ARG ptype u_int32_t lu +ARG next db_pgno_t lu +ARG last_pgno db_pgno_t lu +END + +/* + * pg_free: used to record freeing a page. + * If we are maintaining a sorted free list (during compact) meta_pgno + * will be non-zero and refer to the page that preceeds the one we are freeing + * in the free list. Meta_lsn will then be the lsn of that page. + * + * pgno: the page being freed. + * meta_lsn: the meta-data page's original lsn. + * meta_pgno: the meta-data page number. + * header: the header from the free'd page. + * next: the previous next pointer on the metadata page. + * last_pgno: the last page in the file before this op (4.3+). + */ +BEGIN_COMPAT pg_free 42 50 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER meta_lsn DB_LSN * lu +ARG meta_pgno db_pgno_t lu +PGDBT header DBT s +ARG next db_pgno_t lu +END + +BEGIN pg_free 43 50 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER meta_lsn DB_LSN * lu +ARG meta_pgno db_pgno_t lu +PGDBT header DBT s +ARG next db_pgno_t lu +ARG last_pgno db_pgno_t lu +END + +/* + * cksum -- + * This log record is written when we're unable to checksum a page, + * before returning DB_RUNRECOVERY. This log record causes normal + * recovery to itself return DB_RUNRECOVERY, as only catastrophic + * recovery can fix things. + */ +BEGIN cksum 42 51 +END + +/* + * pg_freedata: used to record freeing a page with data on it. + * + * pgno: the page being freed. + * meta_lsn: the meta-data page's original lsn. + * meta_pgno: the meta-data page number. + * header: the header and index entries from the free'd page. + * data: the data from the free'd page. + * next: the previous next pointer on the metadata page. + * last_pgno: the last page in the file before this op (4.3+). + */ +BEGIN_COMPAT pg_freedata 42 52 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER meta_lsn DB_LSN * lu +ARG meta_pgno db_pgno_t lu +PGDBT header DBT s +ARG next db_pgno_t lu +PGDDBT data DBT s +END + +BEGIN pg_freedata 43 52 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +POINTER meta_lsn DB_LSN * lu +ARG meta_pgno db_pgno_t lu +PGDBT header DBT s +ARG next db_pgno_t lu +ARG last_pgno db_pgno_t lu +PGDDBT data DBT s +END + +/* + * pg_prepare: used to record an aborted page in a prepared transaction. + * + * pgno: the page being freed. + */ +X BEGIN pg_prepare 42 53 +X DB fileid int32_t ld +X ARG pgno db_pgno_t lu +X END + +/* + * pg_new: used to record a new page put on the free list. + * + * pgno: the page being freed. + * meta_lsn: the meta-data page's original lsn. + * meta_pgno: the meta-data page number. + * header: the header from the free'd page. + * next: the previous next pointer on the metadata page. + */ +X BEGIN pg_new 42 54 +X DB fileid int32_t ld +X ARG pgno db_pgno_t lu +X POINTER meta_lsn DB_LSN * lu +X ARG meta_pgno db_pgno_t lu +X PGDBT header DBT s +X ARG next db_pgno_t lu +X END + +/* + * pg_init: used to reinitialize a page during truncate. + * + * pgno: the page being initialized. + * header: the header from the page. + * data: data that used to be on the page. + */ +BEGIN pg_init 43 60 +DB fileid int32_t ld +ARG pgno db_pgno_t lu +PGDBT header DBT s +PGDDBT data DBT s +END + +/* + * pg_sort: sort the free list + * + * meta: meta page number + * meta_lsn: lsn on meta page. + * last_free: page number of new last free page. + * last_lsn; lsn of last free page. + * last_pgno: current last page number. + * list: list of pages and lsns to sort. + */ +BEGIN_COMPAT pg_sort 44 61 +DB fileid int32_t ld +ARG meta db_pgno_t lu +POINTER meta_lsn DB_LSN * lu +ARG last_free db_pgno_t lu +POINTER last_lsn DB_LSN * lu +ARG last_pgno db_pgno_t lu +DBT list DBT s +END + + +/* + * pg_truc: truncate the free list + * + * meta: meta page number + * meta_lsn: lsn on meta page. + * last_free: page number of new last free page. + * last_lsn; lsn of last free page. + * last_pgno: current last page number. + * list: list of pages and lsns on free list. + */ +BEGIN pg_trunc 49 66 +DB fileid int32_t ld +ARG meta db_pgno_t lu +POINTER meta_lsn DB_LSN * lu +ARG last_free db_pgno_t lu +POINTER last_lsn DB_LSN * lu +ARG next_free db_pgno_t lu +ARG last_pgno db_pgno_t lu +DBT list DBT s +END + diff --git a/src/libs/resiprocate/contrib/db/db/db_am.c b/src/libs/resiprocate/contrib/db/db/db_am.c new file mode 100644 index 00000000..c453ea99 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_am.c @@ -0,0 +1,1015 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1998-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/hash.h" +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/partition.h" +#include "dbinc/qam.h" +#include "dbinc/txn.h" + +static int __db_secondary_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); +static int __dbc_set_priority __P((DBC *, DB_CACHE_PRIORITY)); +static int __dbc_get_priority __P((DBC *, DB_CACHE_PRIORITY* )); + +/* + * __db_cursor_int -- + * Internal routine to create a cursor. + * + * PUBLIC: int __db_cursor_int __P((DB *, DB_THREAD_INFO *, + * PUBLIC: DB_TXN *, DBTYPE, db_pgno_t, int, DB_LOCKER *, DBC **)); + */ +int +__db_cursor_int(dbp, ip, txn, dbtype, root, flags, locker, dbcp) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + DBTYPE dbtype; + db_pgno_t root; + int flags; + DB_LOCKER *locker; + DBC **dbcp; +{ + DBC *dbc; + DBC_INTERNAL *cp; + ENV *env; + db_threadid_t tid; + int allocated, ret; + pid_t pid; + + env = dbp->env; + allocated = 0; + + /* + * If dbcp is non-NULL it is assumed to point to an area to initialize + * as a cursor. + * + * Take one from the free list if it's available. Take only the + * right type. With off page dups we may have different kinds + * of cursors on the queue for a single database. + */ + MUTEX_LOCK(env, dbp->mutex); + +#ifndef HAVE_NO_DB_REFCOUNT + /* + * If this DBP is being logged then refcount the log filename + * relative to this transaction. We do this here because we have + * the dbp->mutex which protects the refcount. We want to avoid + * calling the function if we are duplicating a cursor. This includes + * the case of creating an off page duplicate cursor. If we know this + * cursor will not be used in an update, we could avoid this, + * but we don't have that information. + */ + if (txn != NULL && !LF_ISSET(DBC_OPD | DBC_DUPLICATE) + && !F_ISSET(dbp, DB_AM_RECOVER) && + dbp->log_filename != NULL && !IS_REP_CLIENT(env) && + (ret = __txn_record_fname(env, txn, dbp->log_filename)) != 0) { + MUTEX_UNLOCK(env, dbp->mutex); + return (ret); + } + +#endif + + TAILQ_FOREACH(dbc, &dbp->free_queue, links) + if (dbtype == dbc->dbtype) { + TAILQ_REMOVE(&dbp->free_queue, dbc, links); + F_CLR(dbc, ~DBC_OWN_LID); + break; + } + MUTEX_UNLOCK(env, dbp->mutex); + + if (dbc == NULL) { + if ((ret = __os_calloc(env, 1, sizeof(DBC), &dbc)) != 0) + return (ret); + allocated = 1; + dbc->flags = 0; + + dbc->dbp = dbp; + dbc->dbenv = dbp->dbenv; + dbc->env = dbp->env; + + /* Set up locking information. */ + if (LOCKING_ON(env)) { + /* + * If we are not threaded, we share a locker ID among + * all cursors opened in the environment handle, + * allocating one if this is the first cursor. + * + * This relies on the fact that non-threaded DB handles + * always have non-threaded environment handles, since + * we set DB_THREAD on DB handles created with threaded + * environment handles. + */ + if (!DB_IS_THREADED(dbp)) { + if (env->env_lref == NULL && (ret = + __lock_id(env, NULL, &env->env_lref)) != 0) + goto err; + dbc->lref = env->env_lref; + } else { + if ((ret = + __lock_id(env, NULL, &dbc->lref)) != 0) + goto err; + F_SET(dbc, DBC_OWN_LID); + } + + /* + * In CDB, secondary indices should share a lock file + * ID with the primary; otherwise we're susceptible + * to deadlocks. We also use __db_cursor_int rather + * than __db_cursor to create secondary update cursors + * in c_put and c_del; these won't acquire a new lock. + * + * !!! + * Since this is in the one-time cursor allocation + * code, we need to be sure to destroy, not just + * close, all cursors in the secondary when we + * associate. + */ + if (CDB_LOCKING(env) && + F_ISSET(dbp, DB_AM_SECONDARY)) + memcpy(dbc->lock.fileid, + dbp->s_primary->fileid, DB_FILE_ID_LEN); + else + memcpy(dbc->lock.fileid, + dbp->fileid, DB_FILE_ID_LEN); + + if (CDB_LOCKING(env)) { + if (F_ISSET(env->dbenv, DB_ENV_CDB_ALLDB)) { + /* + * If we are doing a single lock per + * environment, set up the global + * lock object just like we do to + * single thread creates. + */ + DB_ASSERT(env, sizeof(db_pgno_t) == + sizeof(u_int32_t)); + dbc->lock_dbt.size = sizeof(u_int32_t); + dbc->lock_dbt.data = &dbc->lock.pgno; + dbc->lock.pgno = 0; + } else { + dbc->lock_dbt.size = DB_FILE_ID_LEN; + dbc->lock_dbt.data = dbc->lock.fileid; + } + } else { + dbc->lock.type = DB_PAGE_LOCK; + dbc->lock_dbt.size = sizeof(dbc->lock); + dbc->lock_dbt.data = &dbc->lock; + } + } + /* Init the DBC internal structure. */ +#ifdef HAVE_PARTITION + if (DB_IS_PARTITIONED(dbp)) { + if ((ret = __partc_init(dbc)) != 0) + goto err; + } else +#endif + switch (dbtype) { + case DB_BTREE: + case DB_RECNO: + if ((ret = __bamc_init(dbc, dbtype)) != 0) + goto err; + break; + case DB_HASH: + if ((ret = __hamc_init(dbc)) != 0) + goto err; + break; + case DB_QUEUE: + if ((ret = __qamc_init(dbc)) != 0) + goto err; + break; + case DB_UNKNOWN: + default: + ret = __db_unknown_type(env, "DB->cursor", dbtype); + goto err; + } + + cp = dbc->internal; + } + + /* Refresh the DBC structure. */ + dbc->dbtype = dbtype; + RESET_RET_MEM(dbc); + dbc->set_priority = __dbc_set_priority; + dbc->get_priority = __dbc_get_priority; + dbc->priority = dbp->priority; + + if ((dbc->txn = txn) != NULL) + dbc->locker = txn->locker; + else if (LOCKING_ON(env)) { + /* + * There are certain cases in which we want to create a + * new cursor with a particular locker ID that is known + * to be the same as (and thus not conflict with) an + * open cursor. + * + * The most obvious case is cursor duplication; when we + * call DBC->dup or __dbc_idup, we want to use the original + * cursor's locker ID. + * + * Another case is when updating secondary indices. Standard + * CDB locking would mean that we might block ourself: we need + * to open an update cursor in the secondary while an update + * cursor in the primary is open, and when the secondary and + * primary are subdatabases or we're using env-wide locking, + * this is disastrous. + * + * In these cases, our caller will pass a nonzero locker + * ID into this function. Use this locker ID instead of + * the default as the locker ID for our new cursor. + */ + if (locker != NULL) + dbc->locker = locker; + else { + /* + * If we are threaded then we need to set the + * proper thread id into the locker. + */ + if (DB_IS_THREADED(dbp)) { + env->dbenv->thread_id(env->dbenv, &pid, &tid); + __lock_set_thread_id(dbc->lref, pid, tid); + } + dbc->locker = dbc->lref; + } + } + + /* + * These fields change when we are used as a secondary index, so + * if the DB is a secondary, make sure they're set properly just + * in case we opened some cursors before we were associated. + * + * __dbc_get is used by all access methods, so this should be safe. + */ + if (F_ISSET(dbp, DB_AM_SECONDARY)) + dbc->get = dbc->c_get = __dbc_secondary_get_pp; + + if (LF_ISSET(DB_CURSOR_BULK) && dbtype == DB_BTREE) + F_SET(dbc, DBC_BULK); + if (LF_ISSET(DB_CURSOR_TRANSIENT)) + F_SET(dbc, DBC_TRANSIENT); + if (LF_ISSET(DBC_OPD)) + F_SET(dbc, DBC_OPD); + if (F_ISSET(dbp, DB_AM_RECOVER)) + F_SET(dbc, DBC_RECOVER); + if (F_ISSET(dbp, DB_AM_COMPENSATE)) + F_SET(dbc, DBC_DONTLOCK); +#ifdef HAVE_REPLICATION + /* + * If we are replicating from a down rev version then we must + * use old locking protocols. + */ + if (LOGGING_ON(env) && + ((LOG *)env->lg_handle-> + reginfo.primary)->persist.version < DB_LOGVERSION_LATCHING) + F_SET(dbc, DBC_DOWNREV); +#endif + + /* Refresh the DBC internal structure. */ + cp = dbc->internal; + cp->opd = NULL; + cp->pdbc = NULL; + + cp->indx = 0; + cp->page = NULL; + cp->pgno = PGNO_INVALID; + cp->root = root; + cp->stream_start_pgno = cp->stream_curr_pgno = PGNO_INVALID; + cp->stream_off = 0; + + if (DB_IS_PARTITIONED(dbp)) { + DBC_PART_REFRESH(dbc); + } else switch (dbtype) { + case DB_BTREE: + case DB_RECNO: + if ((ret = __bamc_refresh(dbc)) != 0) + goto err; + break; + case DB_HASH: + case DB_QUEUE: + break; + case DB_UNKNOWN: + default: + ret = __db_unknown_type(env, "DB->cursor", dbp->type); + goto err; + } + + /* + * The transaction keeps track of how many cursors were opened within + * it to catch application errors where the cursor isn't closed when + * the transaction is resolved. + */ + if (txn != NULL) + ++txn->cursors; + if (ip != NULL) + dbc->thread_info = ip; + else if (txn != NULL) + dbc->thread_info = txn->thread_info; + else + ENV_GET_THREAD_INFO(env, dbc->thread_info); + + MUTEX_LOCK(env, dbp->mutex); + TAILQ_INSERT_TAIL(&dbp->active_queue, dbc, links); + F_SET(dbc, DBC_ACTIVE); + MUTEX_UNLOCK(env, dbp->mutex); + + *dbcp = dbc; + return (0); + +err: if (allocated) + __os_free(env, dbc); + return (ret); +} + +/* + * __db_put -- + * Store a key/data pair. + * + * PUBLIC: int __db_put __P((DB *, + * PUBLIC: DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, u_int32_t)); + */ +int +__db_put(dbp, ip, txn, key, data, flags) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + DBT *key, *data; + u_int32_t flags; +{ + DBC *dbc; + DBT tdata, tkey; + ENV *env; + void *bulk_kptr, *bulk_ptr; + db_recno_t recno; + u_int32_t cursor_flags; + int ret, t_ret; + + env = dbp->env; + + /* + * See the comment in __db_get() regarding DB_CURSOR_TRANSIENT. + * + * Note that the get in the DB_NOOVERWRITE case is safe to do with this + * flag set; if it errors in any way other than DB_NOTFOUND, we're + * going to close the cursor without doing anything else, and if it + * returns DB_NOTFOUND then it's safe to do a c_put(DB_KEYLAST) even if + * an access method moved the cursor, since that's not + * position-dependent. + */ + cursor_flags = DB_WRITELOCK; + if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) + cursor_flags |= DB_CURSOR_BULK; + else + cursor_flags |= DB_CURSOR_TRANSIENT; + if ((ret = __db_cursor(dbp, ip, txn, &dbc, cursor_flags)) != 0) + return (ret); + + DEBUG_LWRITE(dbc, txn, "DB->put", key, data, flags); + + SET_RET_MEM(dbc, dbp); + + if (flags == DB_APPEND && !DB_IS_PRIMARY(dbp)) { + /* + * If there is an append callback, the value stored in + * data->data may be replaced and then freed. To avoid + * passing a freed pointer back to the user, just operate + * on a copy of the data DBT. + */ + tdata = *data; + + /* + * Append isn't a normal put operation; call the appropriate + * access method's append function. + */ + switch (dbp->type) { + case DB_QUEUE: + if ((ret = __qam_append(dbc, key, &tdata)) != 0) + goto err; + break; + case DB_RECNO: + if ((ret = __ram_append(dbc, key, &tdata)) != 0) + goto err; + break; + case DB_BTREE: + case DB_HASH: + case DB_UNKNOWN: + default: + /* The interface should prevent this. */ + DB_ASSERT(env, + dbp->type == DB_QUEUE || dbp->type == DB_RECNO); + + ret = __db_ferr(env, "DB->put", 0); + goto err; + } + + /* + * The append callback, if one exists, may have allocated + * a new tdata.data buffer. If so, free it. + */ + FREE_IF_NEEDED(env, &tdata); + + /* No need for a cursor put; we're done. */ +#ifdef HAVE_COMPRESSION + } else if (DB_IS_COMPRESSED(dbp) && !F_ISSET(dbp, DB_AM_SECONDARY) && + !DB_IS_PRIMARY(dbp) && LIST_FIRST(&dbp->f_primaries) == NULL) { + ret = __dbc_put(dbc, key, data, flags); +#endif + } else if (LF_ISSET(DB_MULTIPLE)) { + ret = 0; + memset(&tkey, 0, sizeof(tkey)); + if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO) { + tkey.data = &recno; + tkey.size = sizeof(recno); + } + memset(&tdata, 0, sizeof(tdata)); + DB_MULTIPLE_INIT(bulk_kptr, key); + DB_MULTIPLE_INIT(bulk_ptr, data); + key->doff = 0; + while (ret == 0) { + if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO) + DB_MULTIPLE_RECNO_NEXT(bulk_kptr, key, + recno, tdata.data, tdata.size); + else + DB_MULTIPLE_NEXT(bulk_kptr, key, + tkey.data, tkey.size); + DB_MULTIPLE_NEXT(bulk_ptr, data, + tdata.data, tdata.size); + if (bulk_kptr == NULL || bulk_ptr == NULL) + break; + ret = __dbc_put(dbc, &tkey, &tdata, + LF_ISSET(DB_OPFLAGS_MASK)); + if (ret == 0) + ++key->doff; + } + } else if (LF_ISSET(DB_MULTIPLE_KEY)) { + ret = 0; + memset(&tkey, 0, sizeof(tkey)); + if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO) { + tkey.data = &recno; + tkey.size = sizeof(recno); + } + memset(&tdata, 0, sizeof(tdata)); + DB_MULTIPLE_INIT(bulk_ptr, key); + while (ret == 0) { + if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO) + DB_MULTIPLE_RECNO_NEXT(bulk_ptr, key, recno, + tdata.data, tdata.size); + else + DB_MULTIPLE_KEY_NEXT(bulk_ptr, key, tkey.data, + tkey.size, tdata.data, tdata.size); + if (bulk_ptr == NULL) + break; + ret = __dbc_put(dbc, &tkey, &tdata, + LF_ISSET(DB_OPFLAGS_MASK)); + if (ret == 0) + ++key->doff; + } + } else + ret = __dbc_put(dbc, key, data, flags); + +err: /* Close the cursor. */ + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __db_del -- + * Delete the items referenced by a key. + * + * PUBLIC: int __db_del __P((DB *, + * PUBLIC: DB_THREAD_INFO *, DB_TXN *, DBT *, u_int32_t)); + */ +int +__db_del(dbp, ip, txn, key, flags) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + DBT *key; + u_int32_t flags; +{ + DBC *dbc; + DBT data, tkey; + void *bulk_ptr; + db_recno_t recno; + u_int32_t cursor_flags, f_init, f_next; + int ret, t_ret; + + COMPQUIET(bulk_ptr, NULL); + /* Allocate a cursor. */ + cursor_flags = DB_WRITELOCK; + if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) + cursor_flags |= DB_CURSOR_BULK; + if ((ret = __db_cursor(dbp, ip, txn, &dbc, cursor_flags)) != 0) + goto err; + + DEBUG_LWRITE(dbc, txn, "DB->del", key, NULL, flags); + +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp) && !F_ISSET(dbp, DB_AM_SECONDARY) && + !DB_IS_PRIMARY(dbp) && LIST_FIRST(&dbp->f_primaries) == NULL) { + F_SET(dbc, DBC_TRANSIENT); + ret = __dbc_bulk_del(dbc, key, flags); + goto err; + } +#endif + + /* + * Walk a cursor through the key/data pairs, deleting as we go. Set + * the DB_DBT_USERMEM flag, as this might be a threaded application + * and the flags checking will catch us. We don't actually want the + * keys or data, set DB_DBT_ISSET. We rely on __dbc_get to clear + * this. + */ + memset(&data, 0, sizeof(data)); + F_SET(&data, DB_DBT_USERMEM); + tkey = *key; + + f_init = LF_ISSET(DB_MULTIPLE_KEY) ? DB_GET_BOTH : DB_SET; + f_next = DB_NEXT_DUP; + + /* + * If locking (and we haven't already acquired CDB locks), set the + * read-modify-write flag. + */ + if (STD_LOCKING(dbc)) { + f_init |= DB_RMW; + f_next |= DB_RMW; + } + + if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) { + if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO) { + memset(&tkey, 0, sizeof(tkey)); + tkey.data = &recno; + tkey.size = sizeof(recno); + } + DB_MULTIPLE_INIT(bulk_ptr, key); + /* We return the number of keys deleted in doff. */ + key->doff = 0; +bulk_next: if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO) + DB_MULTIPLE_RECNO_NEXT(bulk_ptr, key, + recno, data.data, data.size); + else if (LF_ISSET(DB_MULTIPLE)) + DB_MULTIPLE_NEXT(bulk_ptr, key, tkey.data, tkey.size); + else + DB_MULTIPLE_KEY_NEXT(bulk_ptr, key, + tkey.data, tkey.size, data.data, data.size); + if (bulk_ptr == NULL) + goto err; + } + + /* We're not interested in the data -- do not return it. */ + F_SET(&tkey, DB_DBT_ISSET); + F_SET(&data, DB_DBT_ISSET); + + /* + * Optimize the simple cases. For all AMs if we don't have secondaries + * and are not a secondary and we aren't a foreign database and there + * are no dups then we can avoid a bunch of overhead. For queue we + * don't need to fetch the record since we delete by direct calculation + * from the record number. + * + * Hash permits an optimization in DB->del: since on-page duplicates are + * stored in a single HKEYDATA structure, it's possible to delete an + * entire set of them at once, and as the HKEYDATA has to be rebuilt + * and re-put each time it changes, this is much faster than deleting + * the duplicates one by one. Thus, if not pointing at an off-page + * duplicate set, and we're not using secondary indices (in which case + * we'd have to examine the items one by one anyway), let hash do this + * "quick delete". + * + * !!! + * Note that this is the only application-executed delete call in + * Berkeley DB that does not go through the __dbc_del function. + * If anything other than the delete itself (like a secondary index + * update) has to happen there in a particular situation, the + * conditions here should be modified not to use these optimizations. + * The ordinary AM-independent alternative will work just fine; + * it'll just be slower. + */ + if (!F_ISSET(dbp, DB_AM_SECONDARY) && !DB_IS_PRIMARY(dbp) && + LIST_FIRST(&dbp->f_primaries) == NULL) { +#ifdef HAVE_QUEUE + if (dbp->type == DB_QUEUE) { + ret = __qam_delete(dbc, &tkey, flags); + goto next; + } +#endif + + /* Fetch the first record. */ + if ((ret = __dbc_get(dbc, &tkey, &data, f_init)) != 0) + goto err; + +#ifdef HAVE_HASH + /* + * Hash "quick delete" removes all on-page duplicates. We + * can't do that if deleting specific key/data pairs. + */ + if (dbp->type == DB_HASH && !LF_ISSET(DB_MULTIPLE_KEY)) { + DBC *sdbc; + sdbc = dbc; +#ifdef HAVE_PARTITION + if (F_ISSET(dbc, DBC_PARTITIONED)) + sdbc = + ((PART_CURSOR*)dbc->internal)->sub_cursor; +#endif + if (sdbc->internal->opd == NULL) { + ret = __ham_quick_delete(sdbc); + goto next; + } + } +#endif + + if (!F_ISSET(dbp, DB_AM_DUP)) { + ret = dbc->am_del(dbc, 0); + goto next; + } + } else if ((ret = __dbc_get(dbc, &tkey, &data, f_init)) != 0) + goto err; + + /* Walk through the set of key/data pairs, deleting as we go. */ + for (;;) { + if ((ret = __dbc_del(dbc, flags)) != 0) + break; + /* + * With DB_MULTIPLE_KEY, the application has specified the + * exact records they want deleted. We don't need to walk + * through a set of duplicates. + */ + if (LF_ISSET(DB_MULTIPLE_KEY)) + break; + + F_SET(&tkey, DB_DBT_ISSET); + F_SET(&data, DB_DBT_ISSET); + if ((ret = __dbc_get(dbc, &tkey, &data, f_next)) != 0) { + if (ret == DB_NOTFOUND) + ret = 0; + break; + } + } + +next: if (ret == 0 && LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) { + ++key->doff; + goto bulk_next; + } +err: /* Discard the cursor. */ + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __db_sync -- + * Flush the database cache. + * + * PUBLIC: int __db_sync __P((DB *)); + */ +int +__db_sync(dbp) + DB *dbp; +{ + int ret, t_ret; + + ret = 0; + + /* If the database was read-only, we're done. */ + if (F_ISSET(dbp, DB_AM_RDONLY)) + return (0); + + /* If it's a Recno tree, write the backing source text file. */ + if (dbp->type == DB_RECNO) + ret = __ram_writeback(dbp); + + /* If the database was never backed by a database file, we're done. */ + if (F_ISSET(dbp, DB_AM_INMEM)) + return (ret); +#ifdef HAVE_PARTITION + if (DB_IS_PARTITIONED(dbp)) + ret = __partition_sync(dbp); + else +#endif + if (dbp->type == DB_QUEUE) + ret = __qam_sync(dbp); + else + /* Flush any dirty pages from the cache to the backing file. */ + if ((t_ret = __memp_fsync(dbp->mpf)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __db_associate -- + * Associate another database as a secondary index to this one. + * + * PUBLIC: int __db_associate __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB *, + * PUBLIC: int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); + */ +int +__db_associate(dbp, ip, txn, sdbp, callback, flags) + DB *dbp, *sdbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + int (*callback) __P((DB *, const DBT *, const DBT *, DBT *)); + u_int32_t flags; +{ + DBC *pdbc, *sdbc; + DBT key, data, skey, *tskeyp; + ENV *env; + int build, ret, t_ret; + u_int32_t nskey; + + env = dbp->env; + pdbc = sdbc = NULL; + ret = 0; + + memset(&skey, 0, sizeof(DBT)); + nskey = 0; + tskeyp = NULL; + + /* + * Check to see if the secondary is empty -- and thus if we should + * build it -- before we link it in and risk making it show up in other + * threads. Do this first so that the databases remain unassociated on + * error. + */ + build = 0; + if (LF_ISSET(DB_CREATE)) { + if ((ret = __db_cursor(sdbp, ip, txn, &sdbc, 0)) != 0) + goto err; + + /* + * We don't care about key or data; we're just doing + * an existence check. + */ + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + F_SET(&key, DB_DBT_PARTIAL | DB_DBT_USERMEM); + F_SET(&data, DB_DBT_PARTIAL | DB_DBT_USERMEM); + if ((ret = __dbc_get(sdbc, &key, &data, + (STD_LOCKING(sdbc) ? DB_RMW : 0) | + DB_FIRST)) == DB_NOTFOUND) { + build = 1; + ret = 0; + } + + if ((t_ret = __dbc_close(sdbc)) != 0 && ret == 0) + ret = t_ret; + + /* Reset for later error check. */ + sdbc = NULL; + + if (ret != 0) + goto err; + } + + /* + * Set up the database handle as a secondary. + */ + sdbp->s_callback = callback; + sdbp->s_primary = dbp; + + sdbp->stored_get = sdbp->get; + sdbp->get = __db_secondary_get; + + sdbp->stored_close = sdbp->close; + sdbp->close = __db_secondary_close_pp; + + F_SET(sdbp, DB_AM_SECONDARY); + + if (LF_ISSET(DB_IMMUTABLE_KEY)) + FLD_SET(sdbp->s_assoc_flags, DB_ASSOC_IMMUTABLE_KEY); + + /* + * Add the secondary to the list on the primary. Do it here + * so that we see any updates that occur while we're walking + * the primary. + */ + MUTEX_LOCK(env, dbp->mutex); + + /* See __db_s_next for an explanation of secondary refcounting. */ + DB_ASSERT(env, sdbp->s_refcnt == 0); + sdbp->s_refcnt = 1; + LIST_INSERT_HEAD(&dbp->s_secondaries, sdbp, s_links); + MUTEX_UNLOCK(env, dbp->mutex); + + if (build) { + /* + * We loop through the primary, putting each item we + * find into the new secondary. + * + * If we're using CDB, opening these two cursors puts us + * in a bit of a locking tangle: CDB locks are done on the + * primary, so that we stay deadlock-free, but that means + * that updating the secondary while we have a read cursor + * open on the primary will self-block. To get around this, + * we force the primary cursor to use the same locker ID + * as the secondary, so they won't conflict. This should + * be harmless even if we're not using CDB. + */ + if ((ret = __db_cursor(sdbp, ip, txn, &sdbc, + CDB_LOCKING(sdbp->env) ? DB_WRITECURSOR : 0)) != 0) + goto err; + if ((ret = __db_cursor_int(dbp, ip, + txn, dbp->type, PGNO_INVALID, 0, sdbc->locker, &pdbc)) != 0) + goto err; + + /* Lock out other threads, now that we have a locker. */ + dbp->associate_locker = sdbc->locker; + + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + while ((ret = __dbc_get(pdbc, &key, &data, DB_NEXT)) == 0) { + if ((ret = callback(sdbp, &key, &data, &skey)) != 0) { + if (ret == DB_DONOTINDEX) + continue; + goto err; + } + if (F_ISSET(&skey, DB_DBT_MULTIPLE)) { +#ifdef DIAGNOSTIC + __db_check_skeyset(sdbp, &skey); +#endif + nskey = skey.size; + tskeyp = (DBT *)skey.data; + } else { + nskey = 1; + tskeyp = &skey; + } + SWAP_IF_NEEDED(sdbp, &key); + for (; nskey > 0; nskey--, tskeyp++) { + if ((ret = __dbc_put(sdbc, + tskeyp, &key, DB_UPDATE_SECONDARY)) != 0) + goto err; + FREE_IF_NEEDED(env, tskeyp); + } + SWAP_IF_NEEDED(sdbp, &key); + FREE_IF_NEEDED(env, &skey); + } + if (ret == DB_NOTFOUND) + ret = 0; + } + +err: if (sdbc != NULL && (t_ret = __dbc_close(sdbc)) != 0 && ret == 0) + ret = t_ret; + + if (pdbc != NULL && (t_ret = __dbc_close(pdbc)) != 0 && ret == 0) + ret = t_ret; + + dbp->associate_locker = NULL; + + for (; nskey > 0; nskey--, tskeyp++) + FREE_IF_NEEDED(env, tskeyp); + FREE_IF_NEEDED(env, &skey); + + return (ret); +} + +/* + * __db_secondary_get -- + * This wrapper function for DB->pget() is the DB->get() function + * on a database which has been made into a secondary index. + */ +static int +__db_secondary_get(sdbp, txn, skey, data, flags) + DB *sdbp; + DB_TXN *txn; + DBT *skey, *data; + u_int32_t flags; +{ + DB_ASSERT(sdbp->env, F_ISSET(sdbp, DB_AM_SECONDARY)); + return (__db_pget_pp(sdbp, txn, skey, NULL, data, flags)); +} + +/* + * __db_secondary_close -- + * Wrapper function for DB->close() which we use on secondaries to + * manage refcounting and make sure we don't close them underneath + * a primary that is updating. + * + * PUBLIC: int __db_secondary_close __P((DB *, u_int32_t)); + */ +int +__db_secondary_close(sdbp, flags) + DB *sdbp; + u_int32_t flags; +{ + DB *primary; + ENV *env; + int doclose; + + doclose = 0; + primary = sdbp->s_primary; + env = primary->env; + + MUTEX_LOCK(env, primary->mutex); + /* + * Check the refcount--if it was at 1 when we were called, no + * thread is currently updating this secondary through the primary, + * so it's safe to close it for real. + * + * If it's not safe to do the close now, we do nothing; the + * database will actually be closed when the refcount is decremented, + * which can happen in either __db_s_next or __db_s_done. + */ + DB_ASSERT(env, sdbp->s_refcnt != 0); + if (--sdbp->s_refcnt == 0) { + LIST_REMOVE(sdbp, s_links); + /* We don't want to call close while the mutex is held. */ + doclose = 1; + } + MUTEX_UNLOCK(env, primary->mutex); + + /* + * sdbp->close is this function; call the real one explicitly if + * need be. + */ + return (doclose ? __db_close(sdbp, NULL, flags) : 0); +} + +/* + * __db_associate_foreign -- + * Associate this database (fdbp) as a foreign constraint to another + * database (pdbp). That is, dbp's keys appear as foreign key values in + * pdbp. + * + * PUBLIC: int __db_associate_foreign __P((DB *, DB *, + * PUBLIC: int (*)(DB *, const DBT *, DBT *, const DBT *, int *), + * PUBLIC: u_int32_t)); + */ +int +__db_associate_foreign(fdbp, pdbp, callback, flags) + DB *fdbp, *pdbp; + int (*callback)(DB *, const DBT *, DBT *, const DBT *, int *); + u_int32_t flags; +{ + DB_FOREIGN_INFO *f_info; + ENV *env; + int ret; + + env = fdbp->env; + ret = 0; + + if ((ret = __os_malloc(env, sizeof(DB_FOREIGN_INFO), &f_info)) != 0) { + return ret; + } + memset(f_info, 0, sizeof(DB_FOREIGN_INFO)); + + f_info->dbp = pdbp; + f_info->callback = callback; + + /* + * It might be wise to filter this, but for now the flags only + * set the delete action type. + */ + FLD_SET(f_info->flags, flags); + + /* + * Add f_info to the foreign database's list of primaries. That is to + * say, fdbp->f_primaries lists all databases for which fdbp is a + * foreign constraint. + */ + MUTEX_LOCK(env, fdbp->mutex); + LIST_INSERT_HEAD(&fdbp->f_primaries, f_info, f_links); + MUTEX_UNLOCK(env, fdbp->mutex); + + /* + * Associate fdbp as pdbp's foreign db, for referential integrity + * checks. We don't allow the foreign db to be changed, because we + * currently have no way of removing pdbp from the old foreign db's list + * of primaries. + */ + if (pdbp->s_foreign != NULL) + return (EINVAL); + pdbp->s_foreign = fdbp; + + return (ret); +} + +static int +__dbc_set_priority(dbc, priority) + DBC *dbc; + DB_CACHE_PRIORITY priority; +{ + dbc->priority = priority; + return (0); +} + +static int +__dbc_get_priority(dbc, priority) + DBC *dbc; + DB_CACHE_PRIORITY *priority; +{ + *priority = dbc->priority; + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_auto.c b/src/libs/resiprocate/contrib/db/db/db_auto.c new file mode 100644 index 00000000..2ce41994 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_auto.c @@ -0,0 +1,3267 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#include "db_config.h" +#include "db_int.h" +#include "dbinc/crypto.h" +#include "dbinc/db_page.h" +#include "dbinc/db_dispatch.h" +#include "dbinc/db_am.h" +#include "dbinc/log.h" +#include "dbinc/txn.h" + +/* + * PUBLIC: int __db_addrem_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __db_addrem_args **)); + */ +int +__db_addrem_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_addrem_args **argpp; +{ + __db_addrem_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_addrem_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &argp->opcode, bp); + bp += sizeof(argp->opcode); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &argp->indx, bp); + bp += sizeof(argp->indx); + + LOGCOPY_32(env, &argp->nbytes, bp); + bp += sizeof(argp->nbytes); + + memset(&argp->hdr, 0, sizeof(argp->hdr)); + LOGCOPY_32(env,&argp->hdr.size, bp); + bp += sizeof(u_int32_t); + argp->hdr.data = bp; + bp += argp->hdr.size; + + memset(&argp->dbt, 0, sizeof(argp->dbt)); + LOGCOPY_32(env,&argp->dbt.size, bp); + bp += sizeof(u_int32_t); + argp->dbt.data = bp; + bp += argp->dbt.size; + + LOGCOPY_TOLSN(env, &argp->pagelsn, bp); + bp += sizeof(DB_LSN); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_addrem_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, u_int32_t, u_int32_t, + * PUBLIC: const DBT *, const DBT *, DB_LSN *)); + */ +int +__db_addrem_log(dbp, txnp, ret_lsnp, flags, + opcode, pgno, indx, nbytes, hdr, + dbt, pagelsn) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + u_int32_t opcode; + db_pgno_t pgno; + u_int32_t indx; + u_int32_t nbytes; + const DBT *hdr; + const DBT *dbt; + DB_LSN * pagelsn; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___db_addrem; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (hdr == NULL ? 0 : hdr->size) + + sizeof(u_int32_t) + (dbt == NULL ? 0 : dbt->size) + + sizeof(*pagelsn); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, bp, &opcode); + bp += sizeof(opcode); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + LOGCOPY_32(env, bp, &indx); + bp += sizeof(indx); + + LOGCOPY_32(env, bp, &nbytes); + bp += sizeof(nbytes); + + if (hdr == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &hdr->size); + bp += sizeof(hdr->size); + memcpy(bp, hdr->data, hdr->size); + bp += hdr->size; + } + + if (dbt == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &dbt->size); + bp += sizeof(dbt->size); + memcpy(bp, dbt->data, dbt->size); + bp += dbt->size; + } + + if (pagelsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(pagelsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, pagelsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, pagelsn); + } else + memset(bp, 0, sizeof(*pagelsn)); + bp += sizeof(*pagelsn); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__db_addrem_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __db_big_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __db_big_args **)); + */ +int +__db_big_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_big_args **argpp; +{ + __db_big_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_big_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &argp->opcode, bp); + bp += sizeof(argp->opcode); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->prev_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->next_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->dbt, 0, sizeof(argp->dbt)); + LOGCOPY_32(env,&argp->dbt.size, bp); + bp += sizeof(u_int32_t); + argp->dbt.data = bp; + bp += argp->dbt.size; + + LOGCOPY_TOLSN(env, &argp->pagelsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_TOLSN(env, &argp->prevlsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_TOLSN(env, &argp->nextlsn, bp); + bp += sizeof(DB_LSN); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_big_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, u_int32_t, db_pgno_t, db_pgno_t, db_pgno_t, + * PUBLIC: const DBT *, DB_LSN *, DB_LSN *, DB_LSN *)); + */ +int +__db_big_log(dbp, txnp, ret_lsnp, flags, + opcode, pgno, prev_pgno, next_pgno, dbt, + pagelsn, prevlsn, nextlsn) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + u_int32_t opcode; + db_pgno_t pgno; + db_pgno_t prev_pgno; + db_pgno_t next_pgno; + const DBT *dbt; + DB_LSN * pagelsn; + DB_LSN * prevlsn; + DB_LSN * nextlsn; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___db_big; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (dbt == NULL ? 0 : dbt->size) + + sizeof(*pagelsn) + + sizeof(*prevlsn) + + sizeof(*nextlsn); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, bp, &opcode); + bp += sizeof(opcode); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)prev_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)next_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (dbt == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &dbt->size); + bp += sizeof(dbt->size); + memcpy(bp, dbt->data, dbt->size); + bp += dbt->size; + } + + if (pagelsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(pagelsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, pagelsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, pagelsn); + } else + memset(bp, 0, sizeof(*pagelsn)); + bp += sizeof(*pagelsn); + + if (prevlsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(prevlsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, prevlsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, prevlsn); + } else + memset(bp, 0, sizeof(*prevlsn)); + bp += sizeof(*prevlsn); + + if (nextlsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(nextlsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, nextlsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, nextlsn); + } else + memset(bp, 0, sizeof(*nextlsn)); + bp += sizeof(*nextlsn); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__db_big_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __db_ovref_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __db_ovref_args **)); + */ +int +__db_ovref_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_ovref_args **argpp; +{ + __db_ovref_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_ovref_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->adjust = (int32_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn, bp); + bp += sizeof(DB_LSN); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_ovref_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, int32_t, DB_LSN *)); + */ +int +__db_ovref_log(dbp, txnp, ret_lsnp, flags, pgno, adjust, lsn) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + int32_t adjust; + DB_LSN * lsn; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___db_ovref; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*lsn); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)adjust; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, lsn); + } else + memset(bp, 0, sizeof(*lsn)); + bp += sizeof(*lsn); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__db_ovref_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __db_relink_42_read __P((ENV *, DB **, void *, + * PUBLIC: void *, __db_relink_42_args **)); + */ +int +__db_relink_42_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_relink_42_args **argpp; +{ + __db_relink_42_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_relink_42_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &argp->opcode, bp); + bp += sizeof(argp->opcode); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->prev = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn_prev, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->next = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->lsn_next, bp); + bp += sizeof(DB_LSN); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_debug_read __P((ENV *, void *, __db_debug_args **)); + */ +int +__db_debug_read(env, recbuf, argpp) + ENV *env; + void *recbuf; + __db_debug_args **argpp; +{ + __db_debug_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_debug_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + memset(&argp->op, 0, sizeof(argp->op)); + LOGCOPY_32(env,&argp->op.size, bp); + bp += sizeof(u_int32_t); + argp->op.data = bp; + bp += argp->op.size; + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->key, 0, sizeof(argp->key)); + LOGCOPY_32(env,&argp->key.size, bp); + bp += sizeof(u_int32_t); + argp->key.data = bp; + bp += argp->key.size; + + memset(&argp->data, 0, sizeof(argp->data)); + LOGCOPY_32(env,&argp->data.size, bp); + bp += sizeof(u_int32_t); + argp->data.data = bp; + bp += argp->data.size; + + LOGCOPY_32(env, &argp->arg_flags, bp); + bp += sizeof(argp->arg_flags); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_debug_log __P((ENV *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, const DBT *, int32_t, const DBT *, const DBT *, + * PUBLIC: u_int32_t)); + */ +int +__db_debug_log(env, txnp, ret_lsnp, flags, + op, fileid, key, data, arg_flags) + ENV *env; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + const DBT *op; + int32_t fileid; + const DBT *key; + const DBT *data; + u_int32_t arg_flags; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + rlsnp = ret_lsnp; + rectype = DB___db_debug; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + (op == NULL ? 0 : op->size) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (key == NULL ? 0 : key->size) + + sizeof(u_int32_t) + (data == NULL ? 0 : data->size) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + if (op == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &op->size); + bp += sizeof(op->size); + memcpy(bp, op->data, op->size); + bp += op->size; + } + + uinttmp = (u_int32_t)fileid; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (key == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &key->size); + bp += sizeof(key->size); + memcpy(bp, key->data, key->size); + bp += key->size; + } + + if (data == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &data->size); + bp += sizeof(data->size); + memcpy(bp, data->data, data->size); + bp += data->size; + } + + LOGCOPY_32(env, bp, &arg_flags); + bp += sizeof(arg_flags); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__db_debug_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __db_noop_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __db_noop_args **)); + */ +int +__db_noop_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_noop_args **argpp; +{ + __db_noop_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_noop_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->prevlsn, bp); + bp += sizeof(DB_LSN); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_noop_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *)); + */ +int +__db_noop_log(dbp, txnp, ret_lsnp, flags, pgno, prevlsn) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + DB_LSN * prevlsn; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___db_noop; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*prevlsn); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (prevlsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(prevlsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, prevlsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, prevlsn); + } else + memset(bp, 0, sizeof(*prevlsn)); + bp += sizeof(*prevlsn); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__db_noop_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __db_pg_alloc_42_read __P((ENV *, DB **, void *, + * PUBLIC: void *, __db_pg_alloc_42_args **)); + */ +int +__db_pg_alloc_42_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_pg_alloc_42_args **argpp; +{ + __db_pg_alloc_42_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_pg_alloc_42_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->meta_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->page_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &argp->ptype, bp); + bp += sizeof(argp->ptype); + + LOGCOPY_32(env, &uinttmp, bp); + argp->next = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_pg_alloc_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __db_pg_alloc_args **)); + */ +int +__db_pg_alloc_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_pg_alloc_args **argpp; +{ + __db_pg_alloc_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_pg_alloc_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->meta_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->page_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &argp->ptype, bp); + bp += sizeof(argp->ptype); + + LOGCOPY_32(env, &uinttmp, bp); + argp->next = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->last_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_pg_alloc_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, u_int32_t, + * PUBLIC: db_pgno_t, db_pgno_t)); + */ +int +__db_pg_alloc_log(dbp, txnp, ret_lsnp, flags, meta_lsn, meta_pgno, page_lsn, pgno, ptype, + next, last_pgno) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + DB_LSN * meta_lsn; + db_pgno_t meta_pgno; + DB_LSN * page_lsn; + db_pgno_t pgno; + u_int32_t ptype; + db_pgno_t next; + db_pgno_t last_pgno; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___db_pg_alloc; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(*meta_lsn) + + sizeof(u_int32_t) + + sizeof(*page_lsn) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + if (meta_lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, meta_lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, meta_lsn); + } else + memset(bp, 0, sizeof(*meta_lsn)); + bp += sizeof(*meta_lsn); + + uinttmp = (u_int32_t)meta_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (page_lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(page_lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, page_lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, page_lsn); + } else + memset(bp, 0, sizeof(*page_lsn)); + bp += sizeof(*page_lsn); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + LOGCOPY_32(env, bp, &ptype); + bp += sizeof(ptype); + + uinttmp = (u_int32_t)next; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)last_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__db_pg_alloc_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __db_pg_free_42_read __P((ENV *, DB **, void *, + * PUBLIC: void *, __db_pg_free_42_args **)); + */ +int +__db_pg_free_42_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_pg_free_42_args **argpp; +{ + __db_pg_free_42_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_pg_free_42_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->meta_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->header, 0, sizeof(argp->header)); + LOGCOPY_32(env,&argp->header.size, bp); + bp += sizeof(u_int32_t); + argp->header.data = bp; + bp += argp->header.size; + + LOGCOPY_32(env, &uinttmp, bp); + argp->next = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_pg_free_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __db_pg_free_args **)); + */ +int +__db_pg_free_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_pg_free_args **argpp; +{ + __db_pg_free_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_pg_free_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->meta_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->header, 0, sizeof(argp->header)); + LOGCOPY_32(env,&argp->header.size, bp); + bp += sizeof(u_int32_t); + argp->header.data = bp; + bp += argp->header.size; + if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { + int t_ret; + if ((t_ret = __db_pageswap(*dbpp, (PAGE *)argp->header.data, + (size_t)argp->header.size, NULL, 1)) != 0) + return (t_ret); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->next = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->last_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_pg_free_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, const DBT *, + * PUBLIC: db_pgno_t, db_pgno_t)); + */ +int +__db_pg_free_log(dbp, txnp, ret_lsnp, flags, pgno, meta_lsn, meta_pgno, header, next, + last_pgno) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + DB_LSN * meta_lsn; + db_pgno_t meta_pgno; + const DBT *header; + db_pgno_t next; + db_pgno_t last_pgno; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___db_pg_free; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*meta_lsn) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (header == NULL ? 0 : header->size) + + sizeof(u_int32_t) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (meta_lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, meta_lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, meta_lsn); + } else + memset(bp, 0, sizeof(*meta_lsn)); + bp += sizeof(*meta_lsn); + + uinttmp = (u_int32_t)meta_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (header == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &header->size); + bp += sizeof(header->size); + memcpy(bp, header->data, header->size); + if (LOG_SWAPPED(env)) + if ((ret = __db_pageswap(dbp, + (PAGE *)bp, (size_t)header->size, (DBT *)NULL, 0)) != 0) + return (ret); + bp += header->size; + } + + uinttmp = (u_int32_t)next; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)last_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__db_pg_free_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __db_cksum_read __P((ENV *, void *, __db_cksum_args **)); + */ +int +__db_cksum_read(env, recbuf, argpp) + ENV *env; + void *recbuf; + __db_cksum_args **argpp; +{ + __db_cksum_args *argp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_cksum_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_cksum_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t)); + */ +int +__db_cksum_log(env, txnp, ret_lsnp, flags) + ENV *env; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + u_int32_t rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + rlsnp = ret_lsnp; + rectype = DB___db_cksum; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__db_cksum_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __db_pg_freedata_42_read __P((ENV *, DB **, void *, + * PUBLIC: void *, __db_pg_freedata_42_args **)); + */ +int +__db_pg_freedata_42_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_pg_freedata_42_args **argpp; +{ + __db_pg_freedata_42_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_pg_freedata_42_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->meta_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->header, 0, sizeof(argp->header)); + LOGCOPY_32(env,&argp->header.size, bp); + bp += sizeof(u_int32_t); + argp->header.data = bp; + bp += argp->header.size; + + LOGCOPY_32(env, &uinttmp, bp); + argp->next = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->data, 0, sizeof(argp->data)); + LOGCOPY_32(env,&argp->data.size, bp); + bp += sizeof(u_int32_t); + argp->data.data = bp; + bp += argp->data.size; + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_pg_freedata_read __P((ENV *, DB **, void *, + * PUBLIC: void *, __db_pg_freedata_args **)); + */ +int +__db_pg_freedata_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_pg_freedata_args **argpp; +{ + __db_pg_freedata_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_pg_freedata_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->meta_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->header, 0, sizeof(argp->header)); + LOGCOPY_32(env,&argp->header.size, bp); + bp += sizeof(u_int32_t); + argp->header.data = bp; + bp += argp->header.size; + + LOGCOPY_32(env, &uinttmp, bp); + argp->next = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->last_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->data, 0, sizeof(argp->data)); + LOGCOPY_32(env,&argp->data.size, bp); + bp += sizeof(u_int32_t); + argp->data.data = bp; + bp += argp->data.size; + if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { + int t_ret; + if ((t_ret = __db_pageswap(*dbpp, + (PAGE *)argp->header.data, (size_t)argp->header.size, + &argp->data, 1)) != 0) + return (t_ret); + } + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_pg_freedata_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, const DBT *, + * PUBLIC: db_pgno_t, db_pgno_t, const DBT *)); + */ +int +__db_pg_freedata_log(dbp, txnp, ret_lsnp, flags, pgno, meta_lsn, meta_pgno, header, next, + last_pgno, data) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + DB_LSN * meta_lsn; + db_pgno_t meta_pgno; + const DBT *header; + db_pgno_t next; + db_pgno_t last_pgno; + const DBT *data; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___db_pg_freedata; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*meta_lsn) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (header == NULL ? 0 : header->size) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (data == NULL ? 0 : data->size); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (meta_lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, meta_lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, meta_lsn); + } else + memset(bp, 0, sizeof(*meta_lsn)); + bp += sizeof(*meta_lsn); + + uinttmp = (u_int32_t)meta_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (header == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &header->size); + bp += sizeof(header->size); + memcpy(bp, header->data, header->size); + if (LOG_SWAPPED(env)) + if ((ret = __db_pageswap(dbp, + (PAGE *)bp, (size_t)header->size, (DBT *)data, 0)) != 0) + return (ret); + bp += header->size; + } + + uinttmp = (u_int32_t)next; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)last_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (data == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &data->size); + bp += sizeof(data->size); + memcpy(bp, data->data, data->size); + if (LOG_SWAPPED(env) && F_ISSET(data, DB_DBT_APPMALLOC)) + __os_free(env, data->data); + bp += data->size; + } + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__db_pg_freedata_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __db_pg_init_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __db_pg_init_args **)); + */ +int +__db_pg_init_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_pg_init_args **argpp; +{ + __db_pg_init_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_pg_init_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->header, 0, sizeof(argp->header)); + LOGCOPY_32(env,&argp->header.size, bp); + bp += sizeof(u_int32_t); + argp->header.data = bp; + bp += argp->header.size; + + memset(&argp->data, 0, sizeof(argp->data)); + LOGCOPY_32(env,&argp->data.size, bp); + bp += sizeof(u_int32_t); + argp->data.data = bp; + bp += argp->data.size; + if (LOG_SWAPPED(env) && dbpp != NULL && *dbpp != NULL) { + int t_ret; + if ((t_ret = __db_pageswap(*dbpp, + (PAGE *)argp->header.data, (size_t)argp->header.size, + &argp->data, 1)) != 0) + return (t_ret); + } + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_pg_init_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, const DBT *, const DBT *)); + */ +int +__db_pg_init_log(dbp, txnp, ret_lsnp, flags, pgno, header, data) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t pgno; + const DBT *header; + const DBT *data; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___db_pg_init; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (header == NULL ? 0 : header->size) + + sizeof(u_int32_t) + (data == NULL ? 0 : data->size); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (header == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &header->size); + bp += sizeof(header->size); + memcpy(bp, header->data, header->size); + if (LOG_SWAPPED(env)) + if ((ret = __db_pageswap(dbp, + (PAGE *)bp, (size_t)header->size, (DBT *)data, 0)) != 0) + return (ret); + bp += header->size; + } + + if (data == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &data->size); + bp += sizeof(data->size); + memcpy(bp, data->data, data->size); + if (LOG_SWAPPED(env) && F_ISSET(data, DB_DBT_APPMALLOC)) + __os_free(env, data->data); + bp += data->size; + } + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__db_pg_init_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __db_pg_sort_44_read __P((ENV *, DB **, void *, + * PUBLIC: void *, __db_pg_sort_44_args **)); + */ +int +__db_pg_sort_44_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_pg_sort_44_args **argpp; +{ + __db_pg_sort_44_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_pg_sort_44_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->meta = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->last_free = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->last_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->last_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->list, 0, sizeof(argp->list)); + LOGCOPY_32(env,&argp->list.size, bp); + bp += sizeof(u_int32_t); + argp->list.data = bp; + bp += argp->list.size; + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_pg_trunc_read __P((ENV *, DB **, void *, void *, + * PUBLIC: __db_pg_trunc_args **)); + */ +int +__db_pg_trunc_read(env, dbpp, td, recbuf, argpp) + ENV *env; + DB **dbpp; + void *td; + void *recbuf; + __db_pg_trunc_args **argpp; +{ + __db_pg_trunc_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__db_pg_trunc_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + argp->txnp->td = td; + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + if (dbpp != NULL) { + *dbpp = NULL; + ret = __dbreg_id_to_db( + env, argp->txnp, dbpp, argp->fileid, 1); + } + + LOGCOPY_32(env, &uinttmp, bp); + argp->meta = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->meta_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->last_free = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_TOLSN(env, &argp->last_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &uinttmp, bp); + argp->next_free = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->last_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + memset(&argp->list, 0, sizeof(argp->list)); + LOGCOPY_32(env,&argp->list.size, bp); + bp += sizeof(u_int32_t); + argp->list.data = bp; + bp += argp->list.size; + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __db_pg_trunc_log __P((DB *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, + * PUBLIC: db_pgno_t, const DBT *)); + */ +int +__db_pg_trunc_log(dbp, txnp, ret_lsnp, flags, meta, meta_lsn, last_free, last_lsn, next_free, + last_pgno, list) + DB *dbp; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + db_pgno_t meta; + DB_LSN * meta_lsn; + db_pgno_t last_free; + DB_LSN * last_lsn; + db_pgno_t next_free; + db_pgno_t last_pgno; + const DBT *list; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + ENV *env; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + env = dbp->env; + rlsnp = ret_lsnp; + rectype = DB___db_pg_trunc; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE) || + F_ISSET(dbp, DB_AM_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + DB_ASSERT(env, dbp->log_filename != NULL); + if (dbp->log_filename->id == DB_LOGFILEID_INVALID && + (ret = __dbreg_lazy_id(dbp)) != 0) + return (ret); + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(*meta_lsn) + + sizeof(u_int32_t) + + sizeof(*last_lsn) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (list == NULL ? 0 : list->size); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + uinttmp = (u_int32_t)dbp->log_filename->id; + LOGCOPY_32(env, bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)meta; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (meta_lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(meta_lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, meta_lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, meta_lsn); + } else + memset(bp, 0, sizeof(*meta_lsn)); + bp += sizeof(*meta_lsn); + + uinttmp = (u_int32_t)last_free; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (last_lsn != NULL) { + if (txnp != NULL) { + LOG *lp = env->lg_handle->reginfo.primary; + if (LOG_COMPARE(last_lsn, &lp->lsn) >= 0 && (ret = + __log_check_page_lsn(env, dbp, last_lsn)) != 0) + return (ret); + } + LOGCOPY_FROMLSN(env, bp, last_lsn); + } else + memset(bp, 0, sizeof(*last_lsn)); + bp += sizeof(*last_lsn); + + uinttmp = (u_int32_t)next_free; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)last_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + if (list == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &list->size); + bp += sizeof(list->size); + memcpy(bp, list->data, list->size); + bp += list->size; + } + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__db_pg_trunc_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __db_init_recover __P((ENV *, DB_DISTAB *)); + */ +int +__db_init_recover(env, dtabp) + ENV *env; + DB_DISTAB *dtabp; +{ + int ret; + + if ((ret = __db_add_recovery_int(env, dtabp, + __db_addrem_recover, DB___db_addrem)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_big_recover, DB___db_big)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_ovref_recover, DB___db_ovref)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_debug_recover, DB___db_debug)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_noop_recover, DB___db_noop)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_alloc_recover, DB___db_pg_alloc)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_free_recover, DB___db_pg_free)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_cksum_recover, DB___db_cksum)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_freedata_recover, DB___db_pg_freedata)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_init_recover, DB___db_pg_init)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_trunc_recover, DB___db_pg_trunc)) != 0) + return (ret); + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_autop.c b/src/libs/resiprocate/contrib/db/db/db_autop.c new file mode 100644 index 00000000..f3b06351 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_autop.c @@ -0,0 +1,802 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/crypto.h" +#include "dbinc/db_page.h" +#include "dbinc/db_dispatch.h" +#include "dbinc/db_am.h" +#include "dbinc/log.h" +#include "dbinc/txn.h" + +/* + * PUBLIC: int __db_addrem_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_addrem_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_addrem_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_addrem_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_addrem%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\topcode: %lu\n", (u_long)argp->opcode); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tindx: %lu\n", (u_long)argp->indx); + (void)printf("\tnbytes: %lu\n", (u_long)argp->nbytes); + (void)printf("\thdr: "); + for (i = 0; i < argp->hdr.size; i++) { + ch = ((u_int8_t *)argp->hdr.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tdbt: "); + for (i = 0; i < argp->dbt.size; i++) { + ch = ((u_int8_t *)argp->dbt.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tpagelsn: [%lu][%lu]\n", + (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_big_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_big_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_big_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_big_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_big%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\topcode: %lu\n", (u_long)argp->opcode); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tprev_pgno: %lu\n", (u_long)argp->prev_pgno); + (void)printf("\tnext_pgno: %lu\n", (u_long)argp->next_pgno); + (void)printf("\tdbt: "); + for (i = 0; i < argp->dbt.size; i++) { + ch = ((u_int8_t *)argp->dbt.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tpagelsn: [%lu][%lu]\n", + (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset); + (void)printf("\tprevlsn: [%lu][%lu]\n", + (u_long)argp->prevlsn.file, (u_long)argp->prevlsn.offset); + (void)printf("\tnextlsn: [%lu][%lu]\n", + (u_long)argp->nextlsn.file, (u_long)argp->nextlsn.offset); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_ovref_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_ovref_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_ovref_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_ovref_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_ovref%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tadjust: %ld\n", (long)argp->adjust); + (void)printf("\tlsn: [%lu][%lu]\n", + (u_long)argp->lsn.file, (u_long)argp->lsn.offset); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_relink_42_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_relink_42_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_relink_42_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_relink_42_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_relink_42%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\topcode: %lu\n", (u_long)argp->opcode); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tlsn: [%lu][%lu]\n", + (u_long)argp->lsn.file, (u_long)argp->lsn.offset); + (void)printf("\tprev: %lu\n", (u_long)argp->prev); + (void)printf("\tlsn_prev: [%lu][%lu]\n", + (u_long)argp->lsn_prev.file, (u_long)argp->lsn_prev.offset); + (void)printf("\tnext: %lu\n", (u_long)argp->next); + (void)printf("\tlsn_next: [%lu][%lu]\n", + (u_long)argp->lsn_next.file, (u_long)argp->lsn_next.offset); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_debug_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_debug_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_debug_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = __db_debug_read(env, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_debug%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\top: "); + for (i = 0; i < argp->op.size; i++) { + ch = ((u_int8_t *)argp->op.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tkey: "); + for (i = 0; i < argp->key.size; i++) { + ch = ((u_int8_t *)argp->key.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tdata: "); + for (i = 0; i < argp->data.size; i++) { + ch = ((u_int8_t *)argp->data.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\targ_flags: %lu\n", (u_long)argp->arg_flags); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_noop_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_noop_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_noop_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_noop_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_noop%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tprevlsn: [%lu][%lu]\n", + (u_long)argp->prevlsn.file, (u_long)argp->prevlsn.offset); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_pg_alloc_42_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_pg_alloc_42_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_pg_alloc_42_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_pg_alloc_42_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_pg_alloc_42%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tmeta_lsn: [%lu][%lu]\n", + (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset); + (void)printf("\tmeta_pgno: %lu\n", (u_long)argp->meta_pgno); + (void)printf("\tpage_lsn: [%lu][%lu]\n", + (u_long)argp->page_lsn.file, (u_long)argp->page_lsn.offset); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tptype: %lu\n", (u_long)argp->ptype); + (void)printf("\tnext: %lu\n", (u_long)argp->next); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_pg_alloc_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_pg_alloc_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_pg_alloc_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_pg_alloc_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_pg_alloc%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tmeta_lsn: [%lu][%lu]\n", + (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset); + (void)printf("\tmeta_pgno: %lu\n", (u_long)argp->meta_pgno); + (void)printf("\tpage_lsn: [%lu][%lu]\n", + (u_long)argp->page_lsn.file, (u_long)argp->page_lsn.offset); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tptype: %lu\n", (u_long)argp->ptype); + (void)printf("\tnext: %lu\n", (u_long)argp->next); + (void)printf("\tlast_pgno: %lu\n", (u_long)argp->last_pgno); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_pg_free_42_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_pg_free_42_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_pg_free_42_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_pg_free_42_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_pg_free_42%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tmeta_lsn: [%lu][%lu]\n", + (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset); + (void)printf("\tmeta_pgno: %lu\n", (u_long)argp->meta_pgno); + (void)printf("\theader: "); + for (i = 0; i < argp->header.size; i++) { + ch = ((u_int8_t *)argp->header.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tnext: %lu\n", (u_long)argp->next); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_pg_free_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_pg_free_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_pg_free_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_pg_free_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_pg_free%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tmeta_lsn: [%lu][%lu]\n", + (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset); + (void)printf("\tmeta_pgno: %lu\n", (u_long)argp->meta_pgno); + (void)printf("\theader: "); + for (i = 0; i < argp->header.size; i++) { + ch = ((u_int8_t *)argp->header.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tnext: %lu\n", (u_long)argp->next); + (void)printf("\tlast_pgno: %lu\n", (u_long)argp->last_pgno); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_cksum_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_cksum_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_cksum_args *argp; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = __db_cksum_read(env, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_cksum%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_pg_freedata_42_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_pg_freedata_42_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_pg_freedata_42_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_pg_freedata_42_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_pg_freedata_42%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tmeta_lsn: [%lu][%lu]\n", + (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset); + (void)printf("\tmeta_pgno: %lu\n", (u_long)argp->meta_pgno); + (void)printf("\theader: "); + for (i = 0; i < argp->header.size; i++) { + ch = ((u_int8_t *)argp->header.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tnext: %lu\n", (u_long)argp->next); + (void)printf("\tdata: "); + for (i = 0; i < argp->data.size; i++) { + ch = ((u_int8_t *)argp->data.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_pg_freedata_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_pg_freedata_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_pg_freedata_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_pg_freedata_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_pg_freedata%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\tmeta_lsn: [%lu][%lu]\n", + (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset); + (void)printf("\tmeta_pgno: %lu\n", (u_long)argp->meta_pgno); + (void)printf("\theader: "); + for (i = 0; i < argp->header.size; i++) { + ch = ((u_int8_t *)argp->header.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tnext: %lu\n", (u_long)argp->next); + (void)printf("\tlast_pgno: %lu\n", (u_long)argp->last_pgno); + (void)printf("\tdata: "); + for (i = 0; i < argp->data.size; i++) { + ch = ((u_int8_t *)argp->data.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_pg_init_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_pg_init_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_pg_init_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_pg_init_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_pg_init%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tpgno: %lu\n", (u_long)argp->pgno); + (void)printf("\theader: "); + for (i = 0; i < argp->header.size; i++) { + ch = ((u_int8_t *)argp->header.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tdata: "); + for (i = 0; i < argp->data.size; i++) { + ch = ((u_int8_t *)argp->data.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_pg_sort_44_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_pg_sort_44_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_pg_sort_44_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_pg_sort_44_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_pg_sort_44%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tmeta: %lu\n", (u_long)argp->meta); + (void)printf("\tmeta_lsn: [%lu][%lu]\n", + (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset); + (void)printf("\tlast_free: %lu\n", (u_long)argp->last_free); + (void)printf("\tlast_lsn: [%lu][%lu]\n", + (u_long)argp->last_lsn.file, (u_long)argp->last_lsn.offset); + (void)printf("\tlast_pgno: %lu\n", (u_long)argp->last_pgno); + (void)printf("\tlist: "); + for (i = 0; i < argp->list.size; i++) { + ch = ((u_int8_t *)argp->list.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_pg_trunc_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__db_pg_trunc_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __db_pg_trunc_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = + __db_pg_trunc_read(env, NULL, NULL, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__db_pg_trunc%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tmeta: %lu\n", (u_long)argp->meta); + (void)printf("\tmeta_lsn: [%lu][%lu]\n", + (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset); + (void)printf("\tlast_free: %lu\n", (u_long)argp->last_free); + (void)printf("\tlast_lsn: [%lu][%lu]\n", + (u_long)argp->last_lsn.file, (u_long)argp->last_lsn.offset); + (void)printf("\tnext_free: %lu\n", (u_long)argp->next_free); + (void)printf("\tlast_pgno: %lu\n", (u_long)argp->last_pgno); + (void)printf("\tlist: "); + for (i = 0; i < argp->list.size; i++) { + ch = ((u_int8_t *)argp->list.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __db_init_print __P((ENV *, DB_DISTAB *)); + */ +int +__db_init_print(env, dtabp) + ENV *env; + DB_DISTAB *dtabp; +{ + int ret; + + if ((ret = __db_add_recovery_int(env, dtabp, + __db_addrem_print, DB___db_addrem)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_big_print, DB___db_big)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_ovref_print, DB___db_ovref)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_debug_print, DB___db_debug)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_noop_print, DB___db_noop)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_alloc_print, DB___db_pg_alloc)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_free_print, DB___db_pg_free)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_cksum_print, DB___db_cksum)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_freedata_print, DB___db_pg_freedata)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_init_print, DB___db_pg_init)) != 0) + return (ret); + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_trunc_print, DB___db_pg_trunc)) != 0) + return (ret); + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_cam.c b/src/libs/resiprocate/contrib/db/db/db_cam.c new file mode 100644 index 00000000..4c1322dc --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_cam.c @@ -0,0 +1,3460 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/hash.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" +#include "dbinc/partition.h" +#include "dbinc/qam.h" +#include "dbinc/txn.h" + +static int __db_s_count __P((DB *)); +static int __db_wrlock_err __P((ENV *)); +static int __dbc_del_foreign __P((DBC *)); +static int __dbc_del_oldskey __P((DB *, DBC *, DBT *, DBT *, DBT *)); +static int __dbc_del_secondary __P((DBC *)); +static int __dbc_pget_recno __P((DBC *, DBT *, DBT *, u_int32_t)); +static inline int __dbc_put_append __P((DBC *, + DBT *, DBT *, u_int32_t *, u_int32_t)); +static inline int __dbc_put_fixed_len __P((DBC *, DBT *, DBT *)); +static inline int __dbc_put_partial __P((DBC *, + DBT *, DBT *, DBT *, DBT *, u_int32_t *, u_int32_t)); +static int __dbc_put_primary __P((DBC *, DBT *, DBT *, u_int32_t)); +static inline int __dbc_put_resolve_key __P((DBC *, + DBT *, DBT *, u_int32_t *, u_int32_t)); +static inline int __dbc_put_secondaries __P((DBC *, + DBT *, DBT *, DBT *, int, DBT *, u_int32_t *)); + +#define CDB_LOCKING_INIT(env, dbc) \ + /* \ + * If we are running CDB, this had better be either a write \ + * cursor or an immediate writer. If it's a regular writer, \ + * that means we have an IWRITE lock and we need to upgrade \ + * it to a write lock. \ + */ \ + if (CDB_LOCKING(env)) { \ + if (!F_ISSET(dbc, DBC_WRITECURSOR | DBC_WRITER)) \ + return (__db_wrlock_err(env)); \ + \ + if (F_ISSET(dbc, DBC_WRITECURSOR) && \ + (ret = __lock_get(env, \ + (dbc)->locker, DB_LOCK_UPGRADE, &(dbc)->lock_dbt, \ + DB_LOCK_WRITE, &(dbc)->mylock)) != 0) \ + return (ret); \ + } +#define CDB_LOCKING_DONE(env, dbc) \ + /* Release the upgraded lock. */ \ + if (F_ISSET(dbc, DBC_WRITECURSOR)) \ + (void)__lock_downgrade( \ + env, &(dbc)->mylock, DB_LOCK_IWRITE, 0); + +#define SET_READ_LOCKING_FLAGS(dbc, var) do { \ + var = 0; \ + if (!F_ISSET(dbc, DBC_READ_COMMITTED | DBC_READ_UNCOMMITTED)) { \ + if (LF_ISSET(DB_READ_COMMITTED)) \ + var = DBC_READ_COMMITTED | DBC_WAS_READ_COMMITTED; \ + if (LF_ISSET(DB_READ_UNCOMMITTED)) \ + var = DBC_READ_UNCOMMITTED; \ + } \ + LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED); \ +} while (0) + +/* + * __dbc_close -- + * DBC->close. + * + * PUBLIC: int __dbc_close __P((DBC *)); + */ +int +__dbc_close(dbc) + DBC *dbc; +{ + DB *dbp; + DBC *opd; + DBC_INTERNAL *cp; + DB_TXN *txn; + ENV *env; + int ret, t_ret; + + dbp = dbc->dbp; + env = dbp->env; + cp = dbc->internal; + opd = cp->opd; + ret = 0; + + /* + * Remove the cursor(s) from the active queue. We may be closing two + * cursors at once here, a top-level one and a lower-level, off-page + * duplicate one. The access-method specific cursor close routine must + * close both of them in a single call. + * + * !!! + * Cursors must be removed from the active queue before calling the + * access specific cursor close routine, btree depends on having that + * order of operations. + */ + MUTEX_LOCK(env, dbp->mutex); + + if (opd != NULL) { + DB_ASSERT(env, F_ISSET(opd, DBC_ACTIVE)); + F_CLR(opd, DBC_ACTIVE); + TAILQ_REMOVE(&dbp->active_queue, opd, links); + } + DB_ASSERT(env, F_ISSET(dbc, DBC_ACTIVE)); + F_CLR(dbc, DBC_ACTIVE); + TAILQ_REMOVE(&dbp->active_queue, dbc, links); + + MUTEX_UNLOCK(env, dbp->mutex); + + /* Call the access specific cursor close routine. */ + if ((t_ret = + dbc->am_close(dbc, PGNO_INVALID, NULL)) != 0 && ret == 0) + ret = t_ret; + + /* + * Release the lock after calling the access method specific close + * routine, a Btree cursor may have had pending deletes. + */ + if (CDB_LOCKING(env)) { + /* + * Also, be sure not to free anything if mylock.off is + * INVALID; in some cases, such as idup'ed read cursors + * and secondary update cursors, a cursor in a CDB + * environment may not have a lock at all. + */ + if ((t_ret = __LPUT(dbc, dbc->mylock)) != 0 && ret == 0) + ret = t_ret; + + /* For safety's sake, since this is going on the free queue. */ + memset(&dbc->mylock, 0, sizeof(dbc->mylock)); + if (opd != NULL) + memset(&opd->mylock, 0, sizeof(opd->mylock)); + } + + if ((txn = dbc->txn) != NULL) + txn->cursors--; + + /* Move the cursor(s) to the free queue. */ + MUTEX_LOCK(env, dbp->mutex); + if (opd != NULL) { + if (txn != NULL) + txn->cursors--; + TAILQ_INSERT_TAIL(&dbp->free_queue, opd, links); + opd = NULL; + } + TAILQ_INSERT_TAIL(&dbp->free_queue, dbc, links); + MUTEX_UNLOCK(env, dbp->mutex); + + if (txn != NULL && F_ISSET(txn, TXN_PRIVATE) && txn->cursors == 0 && + (t_ret = __txn_commit(txn, 0)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __dbc_destroy -- + * Destroy the cursor, called after DBC->close. + * + * PUBLIC: int __dbc_destroy __P((DBC *)); + */ +int +__dbc_destroy(dbc) + DBC *dbc; +{ + DB *dbp; + ENV *env; + int ret, t_ret; + + dbp = dbc->dbp; + env = dbp->env; + + /* Remove the cursor from the free queue. */ + MUTEX_LOCK(env, dbp->mutex); + TAILQ_REMOVE(&dbp->free_queue, dbc, links); + MUTEX_UNLOCK(env, dbp->mutex); + + /* Free up allocated memory. */ + if (dbc->my_rskey.data != NULL) + __os_free(env, dbc->my_rskey.data); + if (dbc->my_rkey.data != NULL) + __os_free(env, dbc->my_rkey.data); + if (dbc->my_rdata.data != NULL) + __os_free(env, dbc->my_rdata.data); + + /* Call the access specific cursor destroy routine. */ + ret = dbc->am_destroy == NULL ? 0 : dbc->am_destroy(dbc); + + /* + * Release the lock id for this cursor. + */ + if (LOCKING_ON(env) && + F_ISSET(dbc, DBC_OWN_LID) && + (t_ret = __lock_id_free(env, dbc->lref)) != 0 && ret == 0) + ret = t_ret; + + __os_free(env, dbc); + + return (ret); +} + +/* + * __dbc_cmp -- + * Compare the position of two cursors. Return whether two cursors are + * pointing to the same key/data pair. + * + * result == 0 if both cursors refer to the same item. + * result == 1 otherwise + * + * PUBLIC: int __dbc_cmp __P((DBC *, DBC *, int *)); + */ +int +__dbc_cmp(dbc, other_dbc, result) + DBC *dbc, *other_dbc; + int *result; +{ + DBC *curr_dbc, *curr_odbc; + DBC_INTERNAL *dbc_int, *odbc_int; + ENV *env; + int ret; + + env = dbc->env; + ret = 0; + +#ifdef HAVE_PARTITION + if (DB_IS_PARTITIONED(dbc->dbp)) { + dbc = ((PART_CURSOR *)dbc->internal)->sub_cursor; + other_dbc = ((PART_CURSOR *)other_dbc->internal)->sub_cursor; + } + /* Both cursors must still be valid. */ + if (dbc == NULL || other_dbc == NULL) { + __db_errx(env, +"Both cursors must be initialized before calling DBC->cmp."); + return (EINVAL); + } + + if (dbc->dbp != other_dbc->dbp) { + *result = 1; + return (0); + } +#endif + +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbc->dbp)) + return (__bamc_compress_cmp(dbc, other_dbc, result)); +#endif + + curr_dbc = dbc; + curr_odbc = other_dbc; + dbc_int = dbc->internal; + odbc_int = other_dbc->internal; + + /* Both cursors must be on valid positions. */ + if (dbc_int->pgno == PGNO_INVALID || odbc_int->pgno == PGNO_INVALID) { + __db_errx(env, +"Both cursors must be initialized before calling DBC->cmp."); + return (EINVAL); + } + + /* + * Use a loop since cursors can be nested. Off page duplicate + * sets can only be nested one level deep, so it is safe to use a + * while (true) loop. + */ + while (1) { + if (dbc_int->pgno == odbc_int->pgno && + dbc_int->indx == odbc_int->indx) { + /* + * If one cursor is sitting on an off page duplicate + * set, the other will be pointing to the same set. Be + * careful, and check anyway. + */ + if (dbc_int->opd != NULL && odbc_int->opd != NULL) { + curr_dbc = dbc_int->opd; + curr_odbc = odbc_int->opd; + dbc_int = dbc_int->opd->internal; + odbc_int= odbc_int->opd->internal; + continue; + } else if (dbc_int->opd == NULL && + odbc_int->opd == NULL) + *result = 0; + else { + __db_errx(env, + "DBCursor->cmp mismatched off page duplicate cursor pointers."); + return (EINVAL); + } + + switch (curr_dbc->dbtype) { + case DB_HASH: + /* + * Make sure that on-page duplicate data + * indexes match, and that the deleted + * flags are consistent. + */ + ret = __hamc_cmp(curr_dbc, curr_odbc, result); + break; + case DB_BTREE: + case DB_RECNO: + /* + * Check for consisted deleted flags on btree + * specific cursors. + */ + ret = __bamc_cmp(curr_dbc, curr_odbc, result); + break; + default: + /* NO-OP break out. */ + break; + } + } else + *result = 1; + return (ret); + } + /* NOTREACHED. */ + return (ret); +} + +/* + * __dbc_count -- + * Return a count of duplicate data items. + * + * PUBLIC: int __dbc_count __P((DBC *, db_recno_t *)); + */ +int +__dbc_count(dbc, recnop) + DBC *dbc; + db_recno_t *recnop; +{ + ENV *env; + int ret; + + env = dbc->env; + +#ifdef HAVE_PARTITION + if (DB_IS_PARTITIONED(dbc->dbp)) + dbc = ((PART_CURSOR *)dbc->internal)->sub_cursor; +#endif + /* + * Cursor Cleanup Note: + * All of the cursors passed to the underlying access methods by this + * routine are not duplicated and will not be cleaned up on return. + * So, pages/locks that the cursor references must be resolved by the + * underlying functions. + */ + switch (dbc->dbtype) { + case DB_QUEUE: + case DB_RECNO: + *recnop = 1; + break; + case DB_HASH: + if (dbc->internal->opd == NULL) { + if ((ret = __hamc_count(dbc, recnop)) != 0) + return (ret); + break; + } + /* FALLTHROUGH */ + case DB_BTREE: +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbc->dbp)) + return (__bamc_compress_count(dbc, recnop)); +#endif + if ((ret = __bamc_count(dbc, recnop)) != 0) + return (ret); + break; + case DB_UNKNOWN: + default: + return (__db_unknown_type(env, "__dbc_count", dbc->dbtype)); + } + return (0); +} + +/* + * __dbc_del -- + * DBC->del. + * + * PUBLIC: int __dbc_del __P((DBC *, u_int32_t)); + */ +int +__dbc_del(dbc, flags) + DBC *dbc; + u_int32_t flags; +{ + DB *dbp; + ENV *env; + int ret; + + dbp = dbc->dbp; + env = dbp->env; + + CDB_LOCKING_INIT(env, dbc); + + /* + * If we're a secondary index, and DB_UPDATE_SECONDARY isn't set + * (which it only is if we're being called from a primary update), + * then we need to call through to the primary and delete the item. + * + * Note that this will delete the current item; we don't need to + * delete it ourselves as well, so we can just goto done. + */ + if (flags != DB_UPDATE_SECONDARY && F_ISSET(dbp, DB_AM_SECONDARY)) { + ret = __dbc_del_secondary(dbc); + goto done; + } + + /* + * If we are a foreign db, go through and check any foreign key + * constraints first, which will make rolling back changes on an abort + * simpler. + */ + if (LIST_FIRST(&dbp->f_primaries) != NULL && + (ret = __dbc_del_foreign(dbc)) != 0) + goto done; + + /* + * If we are a primary and have secondary indices, go through + * and delete any secondary keys that point at the current record. + */ + if (DB_IS_PRIMARY(dbp) && + (ret = __dbc_del_primary(dbc)) != 0) + goto done; + +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp)) + ret = __bamc_compress_del(dbc, flags); + else +#endif + ret = __dbc_idel(dbc, flags); + +done: CDB_LOCKING_DONE(env, dbc); + + return (ret); +} + +/* + * __dbc_del -- + * Implemenation of DBC->del. + * + * PUBLIC: int __dbc_idel __P((DBC *, u_int32_t)); + */ +int +__dbc_idel(dbc, flags) + DBC *dbc; + u_int32_t flags; +{ + DB *dbp; + DBC *opd; + int ret, t_ret; + + COMPQUIET(flags, 0); + + dbp = dbc->dbp; + + /* + * Cursor Cleanup Note: + * All of the cursors passed to the underlying access methods by this + * routine are not duplicated and will not be cleaned up on return. + * So, pages/locks that the cursor references must be resolved by the + * underlying functions. + */ + + /* + * Off-page duplicate trees are locked in the primary tree, that is, + * we acquire a write lock in the primary tree and no locks in the + * off-page dup tree. If the del operation is done in an off-page + * duplicate tree, call the primary cursor's upgrade routine first. + */ + opd = dbc->internal->opd; + if (opd == NULL) + ret = dbc->am_del(dbc, flags); + else if ((ret = dbc->am_writelock(dbc)) == 0) + ret = opd->am_del(opd, flags); + + /* + * If this was an update that is supporting dirty reads + * then we may have just swapped our read for a write lock + * which is held by the surviving cursor. We need + * to explicitly downgrade this lock. The closed cursor + * may only have had a read lock. + */ + if (F_ISSET(dbp, DB_AM_READ_UNCOMMITTED) && + dbc->internal->lock_mode == DB_LOCK_WRITE) { + if ((t_ret = + __TLPUT(dbc, dbc->internal->lock)) != 0 && ret == 0) + ret = t_ret; + if (t_ret == 0) + dbc->internal->lock_mode = DB_LOCK_WWRITE; + if (dbc->internal->page != NULL && (t_ret = + __memp_shared(dbp->mpf, dbc->internal->page)) != 0 && + ret == 0) + ret = t_ret; + } + + return (ret); +} + +#ifdef HAVE_COMPRESSION +/* + * __dbc_bulk_del -- + * Bulk del for a cursor. + * + * Only implemented for compressed BTrees. In this file in order to + * use the CDB_LOCKING_* macros. + * + * PUBLIC: #ifdef HAVE_COMPRESSION + * PUBLIC: int __dbc_bulk_del __P((DBC *, DBT *, u_int32_t)); + * PUBLIC: #endif + */ +int +__dbc_bulk_del(dbc, key, flags) + DBC *dbc; + DBT *key; + u_int32_t flags; +{ + ENV *env; + int ret; + + env = dbc->env; + + DB_ASSERT(env, DB_IS_COMPRESSED(dbc->dbp)); + + CDB_LOCKING_INIT(env, dbc); + + ret = __bamc_compress_bulk_del(dbc, key, flags); + + CDB_LOCKING_DONE(env, dbc); + + return (ret); +} +#endif + +/* + * __dbc_dup -- + * Duplicate a cursor + * + * PUBLIC: int __dbc_dup __P((DBC *, DBC **, u_int32_t)); + */ +int +__dbc_dup(dbc_orig, dbcp, flags) + DBC *dbc_orig; + DBC **dbcp; + u_int32_t flags; +{ + DBC *dbc_n, *dbc_nopd; + int ret; + + dbc_n = dbc_nopd = NULL; + + /* Allocate a new cursor and initialize it. */ + if ((ret = __dbc_idup(dbc_orig, &dbc_n, flags)) != 0) + goto err; + *dbcp = dbc_n; + + /* + * If the cursor references an off-page duplicate tree, allocate a + * new cursor for that tree and initialize it. + */ + if (dbc_orig->internal->opd != NULL) { + if ((ret = + __dbc_idup(dbc_orig->internal->opd, &dbc_nopd, flags)) != 0) + goto err; + dbc_n->internal->opd = dbc_nopd; + dbc_nopd->internal->pdbc = dbc_n; + } + return (0); + +err: if (dbc_n != NULL) + (void)__dbc_close(dbc_n); + if (dbc_nopd != NULL) + (void)__dbc_close(dbc_nopd); + + return (ret); +} + +/* + * __dbc_idup -- + * Internal version of __dbc_dup. + * + * PUBLIC: int __dbc_idup __P((DBC *, DBC **, u_int32_t)); + */ +int +__dbc_idup(dbc_orig, dbcp, flags) + DBC *dbc_orig, **dbcp; + u_int32_t flags; +{ + DB *dbp; + DBC *dbc_n; + DBC_INTERNAL *int_n, *int_orig; + ENV *env; + int ret; + + dbp = dbc_orig->dbp; + dbc_n = *dbcp; + env = dbp->env; + + if ((ret = __db_cursor_int(dbp, dbc_orig->thread_info, + dbc_orig->txn, dbc_orig->dbtype, dbc_orig->internal->root, + F_ISSET(dbc_orig, DBC_OPD) | DBC_DUPLICATE, + dbc_orig->locker, &dbc_n)) != 0) + return (ret); + + /* Position the cursor if requested, acquiring the necessary locks. */ + if (LF_ISSET(DB_POSITION)) { + int_n = dbc_n->internal; + int_orig = dbc_orig->internal; + + dbc_n->flags |= dbc_orig->flags & ~DBC_OWN_LID; + + int_n->indx = int_orig->indx; + int_n->pgno = int_orig->pgno; + int_n->root = int_orig->root; + int_n->lock_mode = int_orig->lock_mode; + + int_n->stream_start_pgno = int_orig->stream_start_pgno; + int_n->stream_off = int_orig->stream_off; + int_n->stream_curr_pgno = int_orig->stream_curr_pgno; + + switch (dbc_orig->dbtype) { + case DB_QUEUE: + if ((ret = __qamc_dup(dbc_orig, dbc_n)) != 0) + goto err; + break; + case DB_BTREE: + case DB_RECNO: + if ((ret = __bamc_dup(dbc_orig, dbc_n, flags)) != 0) + goto err; + break; + case DB_HASH: + if ((ret = __hamc_dup(dbc_orig, dbc_n)) != 0) + goto err; + break; + case DB_UNKNOWN: + default: + ret = __db_unknown_type(env, + "__dbc_idup", dbc_orig->dbtype); + goto err; + } + } else if (F_ISSET(dbc_orig, DBC_BULK)) { + /* + * For bulk cursors, remember what page were on, even if we + * don't know that the next operation will be nearby. + */ + dbc_n->internal->pgno = dbc_orig->internal->pgno; + } + + /* Copy the locking flags to the new cursor. */ + F_SET(dbc_n, F_ISSET(dbc_orig, DBC_BULK | + DBC_READ_COMMITTED | DBC_READ_UNCOMMITTED | DBC_WRITECURSOR)); + + /* + * If we're in CDB and this isn't an offpage dup cursor, then + * we need to get a lock for the duplicated cursor. + */ + if (CDB_LOCKING(env) && !F_ISSET(dbc_n, DBC_OPD) && + (ret = __lock_get(env, dbc_n->locker, 0, + &dbc_n->lock_dbt, F_ISSET(dbc_orig, DBC_WRITECURSOR) ? + DB_LOCK_IWRITE : DB_LOCK_READ, &dbc_n->mylock)) != 0) + goto err; + + dbc_n->priority = dbc_orig->priority; + dbc_n->internal->pdbc = dbc_orig->internal->pdbc; + *dbcp = dbc_n; + return (0); + +err: (void)__dbc_close(dbc_n); + return (ret); +} + +/* + * __dbc_newopd -- + * Create a new off-page duplicate cursor. + * + * PUBLIC: int __dbc_newopd __P((DBC *, db_pgno_t, DBC *, DBC **)); + */ +int +__dbc_newopd(dbc_parent, root, oldopd, dbcp) + DBC *dbc_parent; + db_pgno_t root; + DBC *oldopd; + DBC **dbcp; +{ + DB *dbp; + DBC *opd; + DBTYPE dbtype; + int ret; + + dbp = dbc_parent->dbp; + dbtype = (dbp->dup_compare == NULL) ? DB_RECNO : DB_BTREE; + + /* + * On failure, we want to default to returning the old off-page dup + * cursor, if any; our caller can't be left with a dangling pointer + * to a freed cursor. On error the only allowable behavior is to + * close the cursor (and the old OPD cursor it in turn points to), so + * this should be safe. + */ + *dbcp = oldopd; + + if ((ret = __db_cursor_int(dbp, dbc_parent->thread_info, + dbc_parent->txn, + dbtype, root, DBC_OPD, dbc_parent->locker, &opd)) != 0) + return (ret); + + opd->priority = dbc_parent->priority; + opd->internal->pdbc = dbc_parent; + *dbcp = opd; + + /* + * Check to see if we already have an off-page dup cursor that we've + * passed in. If we do, close it. It'd be nice to use it again + * if it's a cursor belonging to the right tree, but if we're doing + * a cursor-relative operation this might not be safe, so for now + * we'll take the easy way out and always close and reopen. + * + * Note that under no circumstances do we want to close the old + * cursor without returning a valid new one; we don't want to + * leave the main cursor in our caller with a non-NULL pointer + * to a freed off-page dup cursor. + */ + if (oldopd != NULL && (ret = __dbc_close(oldopd)) != 0) + return (ret); + + return (0); +} + +/* + * __dbc_get -- + * Get using a cursor. + * + * PUBLIC: int __dbc_get __P((DBC *, DBT *, DBT *, u_int32_t)); + */ +int +__dbc_get(dbc, key, data, flags) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; +{ +#ifdef HAVE_PARTITION + if (F_ISSET(dbc, DBC_PARTITIONED)) + return (__partc_get(dbc, key, data, flags)); +#endif + +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbc->dbp)) + return (__bamc_compress_get(dbc, key, data, flags)); +#endif + + return (__dbc_iget(dbc, key, data, flags)); +} + +/* + * __dbc_iget -- + * Implementation of get using a cursor. + * + * PUBLIC: int __dbc_iget __P((DBC *, DBT *, DBT *, u_int32_t)); + */ +int +__dbc_iget(dbc, key, data, flags) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; +{ + DB *dbp; + DBC *ddbc, *dbc_n, *opd; + DBC_INTERNAL *cp, *cp_n; + DB_MPOOLFILE *mpf; + ENV *env; + db_pgno_t pgno; + db_indx_t indx_off; + u_int32_t multi, orig_ulen, tmp_flags, tmp_read_locking, tmp_rmw; + u_int8_t type; + int key_small, ret, t_ret; + + COMPQUIET(orig_ulen, 0); + + key_small = 0; + + /* + * Cursor Cleanup Note: + * All of the cursors passed to the underlying access methods by this + * routine are duplicated cursors. On return, any referenced pages + * will be discarded, and, if the cursor is not intended to be used + * again, the close function will be called. So, pages/locks that + * the cursor references do not need to be resolved by the underlying + * functions. + */ + dbp = dbc->dbp; + env = dbp->env; + mpf = dbp->mpf; + dbc_n = NULL; + opd = NULL; + + /* Clear OR'd in additional bits so we can check for flag equality. */ + tmp_rmw = LF_ISSET(DB_RMW); + LF_CLR(DB_RMW); + + SET_READ_LOCKING_FLAGS(dbc, tmp_read_locking); + + multi = LF_ISSET(DB_MULTIPLE|DB_MULTIPLE_KEY); + LF_CLR(DB_MULTIPLE|DB_MULTIPLE_KEY); + + /* + * Return a cursor's record number. It has nothing to do with the + * cursor get code except that it was put into the interface. + */ + if (flags == DB_GET_RECNO) { + if (tmp_rmw) + F_SET(dbc, DBC_RMW); + F_SET(dbc, tmp_read_locking); + ret = __bamc_rget(dbc, data); + if (tmp_rmw) + F_CLR(dbc, DBC_RMW); + /* Clear the temp flags, but leave WAS_READ_COMMITTED. */ + F_CLR(dbc, tmp_read_locking & ~DBC_WAS_READ_COMMITTED); + return (ret); + } + + if (flags == DB_CONSUME || flags == DB_CONSUME_WAIT) + CDB_LOCKING_INIT(env, dbc); + + /* Don't return the key or data if it was passed to us. */ + if (!DB_RETURNS_A_KEY(dbp, flags)) + F_SET(key, DB_DBT_ISSET); + if (flags == DB_GET_BOTH && + (dbp->dup_compare == NULL || dbp->dup_compare == __bam_defcmp)) + F_SET(data, DB_DBT_ISSET); + + /* + * If we have an off-page duplicates cursor, and the operation applies + * to it, perform the operation. Duplicate the cursor and call the + * underlying function. + * + * Off-page duplicate trees are locked in the primary tree, that is, + * we acquire a write lock in the primary tree and no locks in the + * off-page dup tree. If the DB_RMW flag was specified and the get + * operation is done in an off-page duplicate tree, call the primary + * cursor's upgrade routine first. + */ + cp = dbc->internal; + if (cp->opd != NULL && + (flags == DB_CURRENT || flags == DB_GET_BOTHC || + flags == DB_NEXT || flags == DB_NEXT_DUP || + flags == DB_PREV || flags == DB_PREV_DUP)) { + if (tmp_rmw && (ret = dbc->am_writelock(dbc)) != 0) + goto err; + if (F_ISSET(dbc, DBC_TRANSIENT)) + opd = cp->opd; + else if ((ret = __dbc_idup(cp->opd, &opd, DB_POSITION)) != 0) + goto err; + + if ((ret = opd->am_get(opd, key, data, flags, NULL)) == 0) + goto done; + /* + * Another cursor may have deleted all of the off-page + * duplicates, so for operations that are moving a cursor, we + * need to skip the empty tree and retry on the parent cursor. + */ + if (ret == DB_NOTFOUND && + (flags == DB_PREV || flags == DB_NEXT)) { + ret = __dbc_close(opd); + opd = NULL; + if (F_ISSET(dbc, DBC_TRANSIENT)) + cp->opd = NULL; + } + if (ret != 0) + goto err; + } else if (cp->opd != NULL && F_ISSET(dbc, DBC_TRANSIENT)) { + if ((ret = __dbc_close(cp->opd)) != 0) + goto err; + cp->opd = NULL; + } + + /* + * Perform an operation on the main cursor. Duplicate the cursor, + * upgrade the lock as required, and call the underlying function. + */ + switch (flags) { + case DB_CURRENT: + case DB_GET_BOTHC: + case DB_NEXT: + case DB_NEXT_DUP: + case DB_NEXT_NODUP: + case DB_PREV: + case DB_PREV_DUP: + case DB_PREV_NODUP: + tmp_flags = DB_POSITION; + break; + default: + tmp_flags = 0; + break; + } + + /* + * If this cursor is going to be closed immediately, we don't + * need to take precautions to clean it up on error. + */ + if (F_ISSET(dbc, DBC_TRANSIENT | DBC_PARTITIONED)) + dbc_n = dbc; + else { + ret = __dbc_idup(dbc, &dbc_n, tmp_flags); + + if (ret != 0) + goto err; + COPY_RET_MEM(dbc, dbc_n); + } + + if (tmp_rmw) + F_SET(dbc_n, DBC_RMW); + F_SET(dbc_n, tmp_read_locking); + + switch (multi) { + case DB_MULTIPLE: + F_SET(dbc_n, DBC_MULTIPLE); + break; + case DB_MULTIPLE_KEY: + F_SET(dbc_n, DBC_MULTIPLE_KEY); + break; + case DB_MULTIPLE | DB_MULTIPLE_KEY: + F_SET(dbc_n, DBC_MULTIPLE|DBC_MULTIPLE_KEY); + break; + case 0: + default: + break; + } + +retry: pgno = PGNO_INVALID; + ret = dbc_n->am_get(dbc_n, key, data, flags, &pgno); + if (tmp_rmw) + F_CLR(dbc_n, DBC_RMW); + /* + * Clear the temporary locking flags in the new cursor. The user's + * (old) cursor needs to have the WAS_READ_COMMITTED flag because this + * is used on the next call on that cursor. + */ + F_CLR(dbc_n, tmp_read_locking); + F_SET(dbc, tmp_read_locking & DBC_WAS_READ_COMMITTED); + F_CLR(dbc_n, DBC_MULTIPLE|DBC_MULTIPLE_KEY); + if (ret != 0) + goto err; + + cp_n = dbc_n->internal; + + /* + * We may be referencing a new off-page duplicates tree. Acquire + * a new cursor and call the underlying function. + */ + if (pgno != PGNO_INVALID) { + if ((ret = __dbc_newopd(dbc, + pgno, cp_n->opd, &cp_n->opd)) != 0) + goto err; + + switch (flags) { + case DB_FIRST: + case DB_NEXT: + case DB_NEXT_NODUP: + case DB_SET: + case DB_SET_RECNO: + case DB_SET_RANGE: + tmp_flags = DB_FIRST; + break; + case DB_LAST: + case DB_PREV: + case DB_PREV_NODUP: + tmp_flags = DB_LAST; + break; + case DB_GET_BOTH: + case DB_GET_BOTHC: + case DB_GET_BOTH_RANGE: + tmp_flags = flags; + break; + default: + ret = __db_unknown_flag(env, "__dbc_get", flags); + goto err; + } + ret = cp_n->opd->am_get(cp_n->opd, key, data, tmp_flags, NULL); + /* + * Another cursor may have deleted all of the off-page + * duplicates, so for operations that are moving a cursor, we + * need to skip the empty tree and retry on the parent cursor. + */ + if (ret == DB_NOTFOUND) { + switch (flags) { + case DB_FIRST: + case DB_NEXT: + case DB_NEXT_NODUP: + flags = DB_NEXT; + break; + case DB_LAST: + case DB_PREV: + case DB_PREV_NODUP: + flags = DB_PREV; + break; + default: + goto err; + } + + ret = __dbc_close(cp_n->opd); + cp_n->opd = NULL; + if (ret == 0) + goto retry; + } + if (ret != 0) + goto err; + } + +done: /* + * Return a key/data item. The only exception is that we don't return + * a key if the user already gave us one, that is, if the DB_SET flag + * was set. The DB_SET flag is necessary. In a Btree, the user's key + * doesn't have to be the same as the key stored the tree, depending on + * the magic performed by the comparison function. As we may not have + * done any key-oriented operation here, the page reference may not be + * valid. Fill it in as necessary. We don't have to worry about any + * locks, the cursor must already be holding appropriate locks. + * + * XXX + * If not a Btree and DB_SET_RANGE is set, we shouldn't return a key + * either, should we? + */ + cp_n = dbc_n == NULL ? dbc->internal : dbc_n->internal; + if (!F_ISSET(key, DB_DBT_ISSET)) { + if (cp_n->page == NULL && (ret = __memp_fget(mpf, &cp_n->pgno, + dbc->thread_info, dbc->txn, 0, &cp_n->page)) != 0) + goto err; + + if ((ret = __db_ret(dbc, cp_n->page, cp_n->indx, key, + &dbc->rkey->data, &dbc->rkey->ulen)) != 0) { + /* + * If the key DBT is too small, we still want to return + * the size of the data. Otherwise applications are + * forced to check each one with a separate call. We + * don't want to copy the data, so we set the ulen to + * zero before calling __db_ret. + */ + if (ret == DB_BUFFER_SMALL && + F_ISSET(data, DB_DBT_USERMEM)) { + key_small = 1; + orig_ulen = data->ulen; + data->ulen = 0; + } else + goto err; + } + } + if (multi != 0 && dbc->am_bulk != NULL) { + /* + * Even if fetching from the OPD cursor we need a duplicate + * primary cursor if we are going after multiple keys. + */ + if (dbc_n == NULL) { + /* + * Non-"_KEY" DB_MULTIPLE doesn't move the main cursor, + * so it's safe to just use dbc, unless the cursor + * has an open off-page duplicate cursor whose state + * might need to be preserved. + */ + if ((!(multi & DB_MULTIPLE_KEY) && + dbc->internal->opd == NULL) || + F_ISSET(dbc, DBC_TRANSIENT | DBC_PARTITIONED)) + dbc_n = dbc; + else { + if ((ret = __dbc_idup(dbc, + &dbc_n, DB_POSITION)) != 0) + goto err; + if ((ret = dbc_n->am_get(dbc_n, + key, data, DB_CURRENT, &pgno)) != 0) + goto err; + } + cp_n = dbc_n->internal; + } + + /* + * If opd is set then we dupped the opd that we came in with. + * When we return we may have a new opd if we went to another + * key. + */ + if (opd != NULL) { + DB_ASSERT(env, cp_n->opd == NULL); + cp_n->opd = opd; + opd = NULL; + } + + /* + * Bulk get doesn't use __db_retcopy, so data.size won't + * get set up unless there is an error. Assume success + * here. This is the only call to am_bulk, and it avoids + * setting it exactly the same everywhere. If we have an + * DB_BUFFER_SMALL error, it'll get overwritten with the + * needed value. + */ + data->size = data->ulen; + ret = dbc_n->am_bulk(dbc_n, data, flags | multi); + } else if (!F_ISSET(data, DB_DBT_ISSET)) { + ddbc = opd != NULL ? opd : + cp_n->opd != NULL ? cp_n->opd : dbc_n; + cp = ddbc->internal; + if (cp->page == NULL && + (ret = __memp_fget(mpf, &cp->pgno, + dbc->thread_info, ddbc->txn, 0, &cp->page)) != 0) + goto err; + + type = TYPE(cp->page); + indx_off = ((type == P_LBTREE || + type == P_HASH || type == P_HASH_UNSORTED) ? O_INDX : 0); + ret = __db_ret(ddbc, cp->page, cp->indx + indx_off, + data, &dbc->rdata->data, &dbc->rdata->ulen); + } + +err: /* Don't pass DB_DBT_ISSET back to application level, error or no. */ + F_CLR(key, DB_DBT_ISSET); + F_CLR(data, DB_DBT_ISSET); + + /* Cleanup and cursor resolution. */ + if (opd != NULL) { + /* + * To support dirty reads we must reget the write lock + * if we have just stepped off a deleted record. + * Since the OPD cursor does not know anything + * about the referencing page or cursor we need + * to peek at the OPD cursor and get the lock here. + */ + if (F_ISSET(dbp, DB_AM_READ_UNCOMMITTED) && + F_ISSET((BTREE_CURSOR *) + dbc->internal->opd->internal, C_DELETED)) + if ((t_ret = + dbc->am_writelock(dbc)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __dbc_cleanup( + dbc->internal->opd, opd, ret)) != 0 && ret == 0) + ret = t_ret; + } + + if (key_small) { + data->ulen = orig_ulen; + if (ret == 0) + ret = DB_BUFFER_SMALL; + } + + if ((t_ret = __dbc_cleanup(dbc, dbc_n, ret)) != 0 && + (ret == 0 || ret == DB_BUFFER_SMALL)) + ret = t_ret; + + if (flags == DB_CONSUME || flags == DB_CONSUME_WAIT) + CDB_LOCKING_DONE(env, dbc); + return (ret); +} + +/* Internal flags shared by the dbc_put functions. */ +#define DBC_PUT_RMW 0x001 +#define DBC_PUT_NODEL 0x002 +#define DBC_PUT_HAVEREC 0x004 + +/* + * __dbc_put_resolve_key -- + * Get the current key and data so that we can correctly update the + * secondary and foreign databases. + */ +static inline int +__dbc_put_resolve_key(dbc, oldkey, olddata, put_statep, flags) + DBC *dbc; + DBT *oldkey, *olddata; + u_int32_t flags, *put_statep; +{ + DB *dbp; + ENV *env; + int ret, rmw; + + dbp = dbc->dbp; + env = dbp->env; + rmw = FLD_ISSET(*put_statep, DBC_PUT_RMW) ? DB_RMW : 0; + + DB_ASSERT(env, flags == DB_CURRENT); + COMPQUIET(flags, 0); + + /* + * This is safe to do on the cursor we already have; + * error or no, it won't move. + * + * We use DB_RMW for all of these gets because we'll be + * writing soon enough in the "normal" put code. In + * transactional databases we'll hold those write locks + * even if we close the cursor we're reading with. + * + * The DB_KEYEMPTY return needs special handling -- if the + * cursor is on a deleted key, we return DB_NOTFOUND. + */ + memset(oldkey, 0, sizeof(DBT)); + if ((ret = __dbc_get(dbc, oldkey, olddata, rmw | DB_CURRENT)) != 0) + return (ret == DB_KEYEMPTY ? DB_NOTFOUND : ret); + + /* Record that we've looked for the old record. */ + FLD_SET(*put_statep, DBC_PUT_HAVEREC); + return (0); +} + +/* + * __dbc_put_append -- + * Handle an append to a primary. + */ +static inline int +__dbc_put_append(dbc, key, data, put_statep, flags) + DBC *dbc; + DBT *key, *data; + u_int32_t flags, *put_statep; +{ + DB *dbp; + ENV *env; + DBC *dbc_n; + DBT tdata; + int ret, t_ret; + + dbp = dbc->dbp; + env = dbp->env; + ret = 0; + dbc_n = NULL; + + DB_ASSERT(env, flags == DB_APPEND); + COMPQUIET(flags, 0); + + /* + * With DB_APPEND, we need to do the insert to populate the key value. + * So we swap the 'normal' order of updating secondary / verifying + * foreign databases and inserting. + * + * If there is an append callback, the value stored in data->data may + * be replaced and then freed. To avoid passing a freed pointer back + * to the user, just operate on a copy of the data DBT. + */ + tdata = *data; + + /* + * If this cursor is going to be closed immediately, we don't + * need to take precautions to clean it up on error. + */ + if (F_ISSET(dbc, DBC_TRANSIENT)) + dbc_n = dbc; + else if ((ret = __dbc_idup(dbc, &dbc_n, 0)) != 0) + goto err; + + /* + * Append isn't a normal put operation; call the appropriate access + * method's append function. + */ + switch (dbp->type) { + case DB_QUEUE: + if ((ret = __qam_append(dbc_n, key, &tdata)) != 0) + goto err; + break; + case DB_RECNO: + if ((ret = __ram_append(dbc_n, key, &tdata)) != 0) + goto err; + break; + default: + /* The interface should prevent this. */ + DB_ASSERT(env, + dbp->type == DB_QUEUE || dbp->type == DB_RECNO); + + ret = __db_ferr(env, "DBC->put", 0); + goto err; + } + + /* + * The append callback, if one exists, may have allocated a new + * tdata.data buffer. If so, free it. + */ + FREE_IF_NEEDED(env, &tdata); + + /* + * The key value may have been generated by the above operation, but + * not set in the data buffer. Make sure it is there so that secondary + * updates can complete. + */ + if ((ret = __dbt_usercopy(env, key)) != 0) + goto err; + + /* An append cannot be replacing an existing item. */ + FLD_SET(*put_statep, DBC_PUT_NODEL); + +err: if (dbc_n != NULL && + (t_ret = __dbc_cleanup(dbc, dbc_n, ret)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +/* + * __dbc_put_partial -- + * Ensure that the data item we are using is complete and correct. + * Otherwise we could break the secondary constraints. + */ +static inline int +__dbc_put_partial(dbc, pkey, data, orig_data, out_data, put_statep, flags) + DBC *dbc; + DBT *pkey, *data, *orig_data, *out_data; + u_int32_t *put_statep, flags; +{ + DB *dbp; + DBC *pdbc; + ENV *env; + int ret, rmw, t_ret; + + dbp = dbc->dbp; + env = dbp->env; + ret = t_ret = 0; + rmw = FLD_ISSET(*put_statep, DBC_PUT_RMW) ? DB_RMW : 0; + + if (!FLD_ISSET(*put_statep, DBC_PUT_HAVEREC) && + !FLD_ISSET(*put_statep, DBC_PUT_NODEL)) { + /* + * We're going to have to search the tree for the + * specified key. Dup a cursor (so we have the same + * locking info) and do a c_get. + */ + if ((ret = __dbc_idup(dbc, &pdbc, 0)) != 0) + return (ret); + + /* + * When doing a put with DB_CURRENT, partial data items have + * already been resolved. + */ + DB_ASSERT(env, flags != DB_CURRENT); + + F_SET(pkey, DB_DBT_ISSET); + ret = __dbc_get(pdbc, pkey, orig_data, rmw | DB_SET); + if (ret == DB_KEYEMPTY || ret == DB_NOTFOUND) { + FLD_SET(*put_statep, DBC_PUT_NODEL); + ret = 0; + } + if ((t_ret = __dbc_close(pdbc)) != 0) + ret = t_ret; + if (ret != 0) + return (ret); + + FLD_SET(*put_statep, DBC_PUT_HAVEREC); + } + + COMPQUIET(flags, 0); + + /* + * Now build the new datum from orig_data and the partial data + * we were given. It's okay to do this if no record was + * returned above: a partial put on an empty record is allowed, + * if a little strange. The data is zero-padded. + */ + return (__db_buildpartial(dbp, orig_data, data, out_data)); +} + +/* + * __dbc_put_fixed_len -- + * Handle padding for fixed-length records. + */ +static inline int +__dbc_put_fixed_len(dbc, data, out_data) + DBC *dbc; + DBT *data, *out_data; +{ + DB *dbp; + ENV *env; + int re_pad, ret; + u_int32_t re_len, size; + + dbp = dbc->dbp; + env = dbp->env; + ret = 0; + + /* + * Handle fixed-length records. If the primary database has + * fixed-length records, we need to pad out the datum before + * we pass it into the callback function; we always index the + * "real" record. + */ + if (dbp->type == DB_QUEUE) { + re_len = ((QUEUE *)dbp->q_internal)->re_len; + re_pad = ((QUEUE *)dbp->q_internal)->re_pad; + } else { + re_len = ((BTREE *)dbp->bt_internal)->re_len; + re_pad = ((BTREE *)dbp->bt_internal)->re_pad; + } + + size = data->size; + if (size > re_len) { + ret = __db_rec_toobig(env, size, re_len); + return (ret); + } else if (size < re_len) { + /* + * If we're not doing a partial put, copy data->data into + * out_data->data, then pad out out_data->data. This overrides + * the assignment made above, which is used in the more common + * case when padding is not needed. + * + * If we're doing a partial put, the data we want are already + * in out_data.data; we just need to pad. + */ + if (F_ISSET(data, DB_DBT_PARTIAL)) { + if ((ret = __os_realloc( + env, re_len, &out_data->data)) != 0) + return (ret); + /* + * In the partial case, we have built the item into + * out_data already using __db_buildpartial. Just need + * to pad from the end of out_data, not from data->size. + */ + size = out_data->size; + } else { + if ((ret = __os_malloc( + env, re_len, &out_data->data)) != 0) + return (ret); + memcpy(out_data->data, data->data, size); + } + memset((u_int8_t *)out_data->data + size, re_pad, + re_len - size); + out_data->size = re_len; + } + + return (ret); +} + +/* + * __dbc_put_secondaries -- + * Insert the secondary keys, and validate the foreign key constraints. + */ +static inline int +__dbc_put_secondaries(dbc, + pkey, data, orig_data, s_count, s_keys_buf, put_statep) + DBC *dbc; + DBT *pkey, *data, *orig_data, *s_keys_buf; + int s_count; + u_int32_t *put_statep; +{ + DB *dbp, *sdbp; + DBC *fdbc, *sdbc; + DBT fdata, oldpkey, *skeyp, temppkey, tempskey, *tskeyp; + ENV *env; + int cmp, ret, rmw, t_ret; + u_int32_t nskey; + + dbp = dbc->dbp; + env = dbp->env; + fdbc = sdbc = NULL; + sdbp = NULL; + ret = t_ret = 0; + rmw = FLD_ISSET(*put_statep, DBC_PUT_RMW) ? DB_RMW : 0; + + /* + * Loop through the secondaries. (Step 3.) + * + * Note that __db_s_first and __db_s_next will take care of + * thread-locking and refcounting issues. + */ + for (ret = __db_s_first(dbp, &sdbp), skeyp = s_keys_buf; + sdbp != NULL && ret == 0; + ret = __db_s_next(&sdbp, dbc->txn), ++skeyp) { + DB_ASSERT(env, skeyp - s_keys_buf < s_count); + /* + * Don't process this secondary if the key is immutable and we + * know that the old record exists. This optimization can't be + * used if we have not checked for the old record yet. + */ + if (FLD_ISSET(*put_statep, DBC_PUT_HAVEREC) && + !FLD_ISSET(*put_statep, DBC_PUT_NODEL) && + FLD_ISSET(sdbp->s_assoc_flags, DB_ASSOC_IMMUTABLE_KEY)) + continue; + + /* + * Call the callback for this secondary, to get the + * appropriate secondary key. + */ + if ((ret = sdbp->s_callback(sdbp, + pkey, data, skeyp)) != 0) { + /* Not indexing is equivalent to an empty key set. */ + if (ret == DB_DONOTINDEX) { + F_SET(skeyp, DB_DBT_MULTIPLE); + skeyp->size = 0; + ret = 0; + } else + goto err; + } + + if (sdbp->s_foreign != NULL && + (ret = __db_cursor_int(sdbp->s_foreign, + dbc->thread_info, dbc->txn, sdbp->s_foreign->type, + PGNO_INVALID, 0, dbc->locker, &fdbc)) != 0) + goto err; + + /* + * Mark the secondary key DBT(s) as set -- that is, the + * callback returned at least one secondary key. + * + * Also, if this secondary index is associated with a foreign + * database, check that the foreign db contains the key(s) to + * maintain referential integrity. Set flags in fdata to avoid + * mem copying, we just need to know existence. We need to do + * this check before setting DB_DBT_ISSET, otherwise __dbc_get + * will overwrite the flag values. + */ + if (F_ISSET(skeyp, DB_DBT_MULTIPLE)) { +#ifdef DIAGNOSTIC + __db_check_skeyset(sdbp, skeyp); +#endif + for (tskeyp = (DBT *)skeyp->data, nskey = skeyp->size; + nskey > 0; nskey--, tskeyp++) { + if (fdbc != NULL) { + memset(&fdata, 0, sizeof(DBT)); + F_SET(&fdata, + DB_DBT_PARTIAL | DB_DBT_USERMEM); + if ((ret = __dbc_get( + fdbc, tskeyp, &fdata, + DB_SET | rmw)) == DB_NOTFOUND || + ret == DB_KEYEMPTY) { + ret = DB_FOREIGN_CONFLICT; + break; + } + } + F_SET(tskeyp, DB_DBT_ISSET); + } + tskeyp = (DBT *)skeyp->data; + nskey = skeyp->size; + } else { + if (fdbc != NULL) { + memset(&fdata, 0, sizeof(DBT)); + F_SET(&fdata, DB_DBT_PARTIAL | DB_DBT_USERMEM); + if ((ret = __dbc_get(fdbc, skeyp, &fdata, + DB_SET | rmw)) == DB_NOTFOUND || + ret == DB_KEYEMPTY) + ret = DB_FOREIGN_CONFLICT; + } + F_SET(skeyp, DB_DBT_ISSET); + tskeyp = skeyp; + nskey = 1; + } + if (fdbc != NULL && (t_ret = __dbc_close(fdbc)) != 0 && + ret == 0) + ret = t_ret; + fdbc = NULL; + if (ret != 0) + goto err; + + /* + * If we have the old record, we can generate and remove any + * old secondary key(s) now. We can also skip the secondary + * put if there is no change. + */ + if (FLD_ISSET(*put_statep, DBC_PUT_HAVEREC)) { + if ((ret = __dbc_del_oldskey(sdbp, dbc, + skeyp, pkey, orig_data)) == DB_KEYEXIST) + continue; + else if (ret != 0) + goto err; + } + if (nskey == 0) + continue; + + /* + * Open a cursor in this secondary. + * + * Use the same locker ID as our primary cursor, so that + * we're guaranteed that the locks don't conflict (e.g. in CDB + * or if we're subdatabases that share and want to lock a + * metadata page). + */ + if ((ret = __db_cursor_int(sdbp, dbc->thread_info, dbc->txn, + sdbp->type, PGNO_INVALID, 0, dbc->locker, &sdbc)) != 0) + goto err; + + /* + * If we're in CDB, updates will fail since the new cursor + * isn't a writer. However, we hold the WRITE lock in the + * primary and will for as long as our new cursor lasts, + * and the primary and secondary share a lock file ID, + * so it's safe to consider this a WRITER. The close + * routine won't try to put anything because we don't + * really have a lock. + */ + if (CDB_LOCKING(env)) { + DB_ASSERT(env, sdbc->mylock.off == LOCK_INVALID); + F_SET(sdbc, DBC_WRITER); + } + + /* + * Swap the primary key to the byte order of this secondary, if + * necessary. By doing this now, we can compare directly + * against the data already in the secondary without having to + * swap it after reading. + */ + SWAP_IF_NEEDED(sdbp, pkey); + + for (; nskey > 0 && ret == 0; nskey--, tskeyp++) { + /* Skip this key if it is already in the database. */ + if (!F_ISSET(tskeyp, DB_DBT_ISSET)) + continue; + + /* + * There are three cases here-- + * 1) The secondary supports sorted duplicates. + * If we attempt to put a secondary/primary pair + * that already exists, that's a duplicate + * duplicate, and c_put will return DB_KEYEXIST + * (see __db_duperr). This will leave us with + * exactly one copy of the secondary/primary pair, + * and this is just right--we'll avoid deleting it + * later, as the old and new secondaries will + * match (since the old secondary is the dup dup + * that's already there). + * 2) The secondary supports duplicates, but they're not + * sorted. We need to avoid putting a duplicate + * duplicate, because the matching old and new + * secondaries will prevent us from deleting + * anything and we'll wind up with two secondary + * records that point to the same primary key. Do + * a c_get(DB_GET_BOTH); only do the put if the + * secondary doesn't exist. + * 3) The secondary doesn't support duplicates at all. + * In this case, secondary keys must be unique; + * if another primary key already exists for this + * secondary key, we have to either overwrite it + * or not put this one, and in either case we've + * corrupted the secondary index. Do a + * c_get(DB_SET). If the secondary/primary pair + * already exists, do nothing; if the secondary + * exists with a different primary, return an + * error; and if the secondary does not exist, + * put it. + */ + if (!F_ISSET(sdbp, DB_AM_DUP)) { + /* Case 3. */ + memset(&oldpkey, 0, sizeof(DBT)); + F_SET(&oldpkey, DB_DBT_MALLOC); + ret = __dbc_get(sdbc, + tskeyp, &oldpkey, rmw | DB_SET); + if (ret == 0) { + cmp = __bam_defcmp(sdbp, + &oldpkey, pkey); + __os_ufree(env, oldpkey.data); + /* + * If the secondary key is unchanged, + * skip the put and go on to the next + * one. + */ + if (cmp == 0) + continue; + + __db_errx(env, "%s%s", + "Put results in a non-unique secondary key in an ", + "index not configured to support duplicates"); + ret = EINVAL; + } + if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY) + break; + } else if (!F_ISSET(sdbp, DB_AM_DUPSORT)) { + /* Case 2. */ + DB_INIT_DBT(tempskey, + tskeyp->data, tskeyp->size); + DB_INIT_DBT(temppkey, + pkey->data, pkey->size); + ret = __dbc_get(sdbc, &tempskey, &temppkey, + rmw | DB_GET_BOTH); + if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY) + break; + } + + ret = __dbc_put(sdbc, tskeyp, pkey, + DB_UPDATE_SECONDARY); + + /* + * We don't know yet whether this was a put-overwrite + * that in fact changed nothing. If it was, we may get + * DB_KEYEXIST. This is not an error. + */ + if (ret == DB_KEYEXIST) + ret = 0; + } + + /* Make sure the primary key is back in native byte-order. */ + SWAP_IF_NEEDED(sdbp, pkey); + + if ((t_ret = __dbc_close(sdbc)) != 0 && ret == 0) + ret = t_ret; + + if (ret != 0) + goto err; + + /* + * Mark that we have a key for this secondary so we can check + * it later before deleting the old one. We can't set it + * earlier or it would be cleared in the calls above. + */ + F_SET(skeyp, DB_DBT_ISSET); + } +err: if (sdbp != NULL && + (t_ret = __db_s_done(sdbp, dbc->txn)) != 0 && ret == 0) + ret = t_ret; + COMPQUIET(s_count, 0); + return (ret); +} + +static int +__dbc_put_primary(dbc, key, data, flags) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; +{ + DB *dbp, *sdbp; + DBC *dbc_n, *pdbc; + DBT oldkey, olddata, newdata; + DBT *all_skeys, *skeyp, *tskeyp; + ENV *env; + int ret, t_ret, s_count; + u_int32_t nskey, put_state, rmw; + + dbp = dbc->dbp; + env = dbp->env; + ret = t_ret = s_count = 0; + put_state = 0; + sdbp = NULL; + pdbc = dbc_n = NULL; + all_skeys = NULL; + memset(&newdata, 0, sizeof(DBT)); + memset(&olddata, 0, sizeof(DBT)); + + /* + * We do multiple cursor operations in some cases and subsequently + * access the data DBT information. Set DB_DBT_MALLOC so we don't risk + * modification of the data between our uses of it. + */ + F_SET(&olddata, DB_DBT_MALLOC); + + /* + * We have at least one secondary which we may need to update. + * + * There is a rather vile locking issue here. Secondary gets + * will always involve acquiring a read lock in the secondary, + * then acquiring a read lock in the primary. Ideally, we + * would likewise perform puts by updating all the secondaries + * first, then doing the actual put in the primary, to avoid + * deadlock (since having multiple threads doing secondary + * gets and puts simultaneously is probably a common case). + * + * However, if this put is a put-overwrite--and we have no way to + * tell in advance whether it will be--we may need to delete + * an outdated secondary key. In order to find that old + * secondary key, we need to get the record we're overwriting, + * before we overwrite it. + * + * (XXX: It would be nice to avoid this extra get, and have the + * underlying put routines somehow pass us the old record + * since they need to traverse the tree anyway. I'm saving + * this optimization for later, as it's a lot of work, and it + * would be hard to fit into this locking paradigm anyway.) + * + * The simple thing to do would be to go get the old record before + * we do anything else. Unfortunately, though, doing so would + * violate our "secondary, then primary" lock acquisition + * ordering--even in the common case where no old primary record + * exists, we'll still acquire and keep a lock on the page where + * we're about to do the primary insert. + * + * To get around this, we do the following gyrations, which + * hopefully solve this problem in the common case: + * + * 1) If this is a c_put(DB_CURRENT), go ahead and get the + * old record. We already hold the lock on this page in + * the primary, so no harm done, and we'll need the primary + * key (which we weren't passed in this case) to do any + * secondary puts anyway. + * If this is a put(DB_APPEND), then we need to insert the item, + * so that we can know the key value. So go ahead and insert. In + * the case of a put(DB_APPEND) without secondaries it is + * implemented in the __db_put method as an optimization. + * + * 2) If we're doing a partial put, we need to perform the + * get on the primary key right away, since we don't have + * the whole datum that the secondary key is based on. + * We may also need to pad out the record if the primary + * has a fixed record length. + * + * 3) Loop through the secondary indices, putting into each a + * new secondary key that corresponds to the new record. + * + * 4) If we haven't done so in (1) or (2), get the old primary + * key/data pair. If one does not exist--the common case--we're + * done with secondary indices, and can go straight on to the + * primary put. + * + * 5) If we do have an old primary key/data pair, however, we need + * to loop through all the secondaries a second time and delete + * the old secondary in each. + */ + s_count = __db_s_count(dbp); + if ((ret = __os_calloc(env, + (u_int)s_count, sizeof(DBT), &all_skeys)) != 0) + goto err; + + /* + * Primary indices can't have duplicates, so only DB_APPEND, + * DB_CURRENT, DB_KEYFIRST, and DB_KEYLAST make any sense. Other flags + * should have been caught by the checking routine, but + * add a sprinkling of paranoia. + */ + DB_ASSERT(env, flags == DB_APPEND || flags == DB_CURRENT || + flags == DB_KEYFIRST || flags == DB_KEYLAST || + flags == DB_NOOVERWRITE || flags == DB_OVERWRITE_DUP); + + /* + * We'll want to use DB_RMW in a few places, but it's only legal + * when locking is on. + */ + rmw = STD_LOCKING(dbc) ? DB_RMW : 0; + if (rmw) + FLD_SET(put_state, DBC_PUT_RMW); + + /* Resolve the primary key if required (Step 1). */ + if (flags == DB_CURRENT) { + if ((ret = __dbc_put_resolve_key(dbc, + &oldkey, &olddata, &put_state, flags)) != 0) + goto err; + key = &oldkey; + } else if (flags == DB_APPEND) { + if ((ret = __dbc_put_append(dbc, + key, data, &put_state, flags)) != 0) + goto err; + } + + /* + * PUT_NOOVERWRITE with secondaries is a troublesome case. We need + * to check that the insert will work prior to making any changes + * to secondaries. Try to work within the locking constraints outlined + * above. + * + * This is DB->put (DB_NOOVERWRITE). DBC->put(DB_NODUPDATA) is not + * relevant since it is only valid on DBs that support duplicates, + * which primaries with secondaries can't have. + */ + if (flags == DB_NOOVERWRITE) { + /* Don't bother retrieving the data. */ + F_SET(key, DB_DBT_ISSET); + olddata.dlen = 0; + olddata.flags = DB_DBT_PARTIAL | DB_DBT_USERMEM; + if (__dbc_get(dbc, key, &olddata, DB_SET) != DB_NOTFOUND) { + ret = DB_KEYEXIST; + goto done; + } + } + + /* + * Check for partial puts using DB_DBT_PARTIAL (Step 2). + */ + if (F_ISSET(data, DB_DBT_PARTIAL)) { + if ((ret = __dbc_put_partial(dbc, + key, data, &olddata, &newdata, &put_state, flags)) != 0) + goto err; + } else { + newdata = *data; + } + + /* + * Check for partial puts, with fixed length record databases (Step 2). + */ + if ((dbp->type == DB_RECNO && F_ISSET(dbp, DB_AM_FIXEDLEN)) || + (dbp->type == DB_QUEUE)) { + if ((ret = __dbc_put_fixed_len(dbc, data, &newdata)) != 0) + goto err; + } + + /* Validate any foreign databases, and update secondaries. (Step 3). */ + if ((ret = __dbc_put_secondaries(dbc, key, &newdata, + &olddata, s_count, all_skeys, &put_state)) + != 0) + goto err; + /* + * If we've already got the old primary key/data pair, the secondary + * updates are already done. + */ + if (FLD_ISSET(put_state, DBC_PUT_HAVEREC)) + goto done; + + /* + * If still necessary, go get the old primary key/data. (Step 4.) + * + * See the comments in step 2. This is real familiar. + */ + if ((ret = __dbc_idup(dbc, &pdbc, 0)) != 0) + goto err; + DB_ASSERT(env, flags != DB_CURRENT); + F_SET(key, DB_DBT_ISSET); + ret = __dbc_get(pdbc, key, &olddata, rmw | DB_SET); + if (ret == DB_KEYEMPTY || ret == DB_NOTFOUND) { + FLD_SET(put_state, DBC_PUT_NODEL); + ret = 0; + } + if ((t_ret = __dbc_close(pdbc)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + goto err; + + /* + * Check whether we do in fact have an old record we may need to + * delete. (Step 5). + */ + if (FLD_ISSET(put_state, DBC_PUT_NODEL)) + goto done; + + for (ret = __db_s_first(dbp, &sdbp), skeyp = all_skeys; + sdbp != NULL && ret == 0; + ret = __db_s_next(&sdbp, dbc->txn), skeyp++) { + DB_ASSERT(env, skeyp - all_skeys < s_count); + /* + * Don't process this secondary if the key is immutable. We + * know that the old record exists, so this optimization can + * always be used. + */ + if (FLD_ISSET(sdbp->s_assoc_flags, DB_ASSOC_IMMUTABLE_KEY)) + continue; + + if ((ret = __dbc_del_oldskey(sdbp, dbc, + skeyp, key, &olddata)) != 0 && ret != DB_KEYEXIST) + goto err; + } + if (ret != 0) + goto err; + +done: +err: + if ((t_ret = __dbc_cleanup(dbc, dbc_n, ret)) != 0 && ret == 0) + ret = t_ret; + + /* If newdata or olddata were used, free their buffers. */ + if (newdata.data != NULL && newdata.data != data->data) + __os_free(env, newdata.data); + if (olddata.data != NULL) + __os_ufree(env, olddata.data); + + CDB_LOCKING_DONE(env, dbc); + + if (sdbp != NULL && + (t_ret = __db_s_done(sdbp, dbc->txn)) != 0 && ret == 0) + ret = t_ret; + + for (skeyp = all_skeys; skeyp - all_skeys < s_count; skeyp++) { + if (F_ISSET(skeyp, DB_DBT_MULTIPLE)) { + for (nskey = skeyp->size, tskeyp = (DBT *)skeyp->data; + nskey > 0; + nskey--, tskeyp++) + FREE_IF_NEEDED(env, tskeyp); + } + FREE_IF_NEEDED(env, skeyp); + } + if (all_skeys != NULL) + __os_free(env, all_skeys); + return (ret); +} + +/* + * __dbc_put -- + * Put using a cursor. + * + * PUBLIC: int __dbc_put __P((DBC *, DBT *, DBT *, u_int32_t)); + */ +int +__dbc_put(dbc, key, data, flags) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; +{ + DB *dbp; + int ret; + + dbp = dbc->dbp; + ret = 0; + + /* + * Putting to secondary indices is forbidden; when we need to + * internally update one, we're called with a private flag, + * DB_UPDATE_SECONDARY, which does the right thing but won't return an + * error during flag checking. + * + * As a convenience, many places that want the default DB_KEYLAST + * behavior call DBC->put with flags == 0. Protect lower-level code + * here by translating that. + * + * Lastly, the DB_OVERWRITE_DUP flag is equivalent to DB_KEYLAST unless + * there are sorted duplicates. Limit the number of places that need + * to test for it explicitly. + */ + if (flags == DB_UPDATE_SECONDARY || flags == 0 || + (flags == DB_OVERWRITE_DUP && !F_ISSET(dbp, DB_AM_DUPSORT))) + flags = DB_KEYLAST; + + CDB_LOCKING_INIT(dbc->env, dbc); + + /* + * Check to see if we are a primary and have secondary indices. + * If we are not, we save ourselves a good bit of trouble and + * just skip to the "normal" put. + */ + if (DB_IS_PRIMARY(dbp) && + ((ret = __dbc_put_primary(dbc, key, data, flags)) != 0)) + return (ret); + + /* + * If this is an append operation, the insert was done prior to the + * secondary updates, so we are finished. + */ + if (flags == DB_APPEND) + return (ret); + +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp)) + return (__bamc_compress_put(dbc, key, data, flags)); +#endif + + return (__dbc_iput(dbc, key, data, flags)); +} + +/* + * __dbc_iput -- + * Implementation of put using a cursor. + * + * PUBLIC: int __dbc_iput __P((DBC *, DBT *, DBT *, u_int32_t)); + */ +int +__dbc_iput(dbc, key, data, flags) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; +{ + DBC *dbc_n, *oldopd, *opd; + db_pgno_t pgno; + int ret, t_ret; + u_int32_t tmp_flags; + + /* + * Cursor Cleanup Note: + * All of the cursors passed to the underlying access methods by this + * routine are duplicated cursors. On return, any referenced pages + * will be discarded, and, if the cursor is not intended to be used + * again, the close function will be called. So, pages/locks that + * the cursor references do not need to be resolved by the underlying + * functions. + */ + dbc_n = NULL; + ret = t_ret = 0; + + /* + * If we have an off-page duplicates cursor, and the operation applies + * to it, perform the operation. Duplicate the cursor and call the + * underlying function. + * + * Off-page duplicate trees are locked in the primary tree, that is, + * we acquire a write lock in the primary tree and no locks in the + * off-page dup tree. If the put operation is done in an off-page + * duplicate tree, call the primary cursor's upgrade routine first. + */ + if (dbc->internal->opd != NULL && + (flags == DB_AFTER || flags == DB_BEFORE || flags == DB_CURRENT)) { + /* + * A special case for hash off-page duplicates. Hash doesn't + * support (and is documented not to support) put operations + * relative to a cursor which references an already deleted + * item. For consistency, apply the same criteria to off-page + * duplicates as well. + */ + if (dbc->dbtype == DB_HASH && F_ISSET( + ((BTREE_CURSOR *)(dbc->internal->opd->internal)), + C_DELETED)) { + ret = DB_NOTFOUND; + goto err; + } + + if ((ret = dbc->am_writelock(dbc)) != 0 || + (ret = __dbc_dup(dbc, &dbc_n, DB_POSITION)) != 0) + goto err; + opd = dbc_n->internal->opd; + if ((ret = opd->am_put( + opd, key, data, flags, NULL)) != 0) + goto err; + goto done; + } + + /* + * Perform an operation on the main cursor. Duplicate the cursor, + * and call the underlying function. + */ + if (flags == DB_AFTER || flags == DB_BEFORE || flags == DB_CURRENT) + tmp_flags = DB_POSITION; + else + tmp_flags = 0; + + /* + * If this cursor is going to be closed immediately, we don't + * need to take precautions to clean it up on error. + */ + if (F_ISSET(dbc, DBC_TRANSIENT | DBC_PARTITIONED)) + dbc_n = dbc; + else if ((ret = __dbc_idup(dbc, &dbc_n, tmp_flags)) != 0) + goto err; + + pgno = PGNO_INVALID; + if ((ret = dbc_n->am_put(dbc_n, key, data, flags, &pgno)) != 0) + goto err; + + /* + * We may be referencing a new off-page duplicates tree. Acquire + * a new cursor and call the underlying function. + */ + if (pgno != PGNO_INVALID) { + oldopd = dbc_n->internal->opd; + if ((ret = __dbc_newopd(dbc, pgno, oldopd, &opd)) != 0) { + dbc_n->internal->opd = opd; + goto err; + } + + dbc_n->internal->opd = opd; + opd->internal->pdbc = dbc_n; + + if (flags == DB_NOOVERWRITE) + flags = DB_KEYLAST; + if ((ret = opd->am_put( + opd, key, data, flags, NULL)) != 0) + goto err; + } + +done: +err: /* Cleanup and cursor resolution. */ + if ((t_ret = __dbc_cleanup(dbc, dbc_n, ret)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +/* + * __dbc_del_oldskey -- + * Delete an old secondary key, if necessary. + * Returns DB_KEYEXIST if the new and old keys match.. + */ +static int +__dbc_del_oldskey(sdbp, dbc, skey, pkey, olddata) + DB *sdbp; + DBC *dbc; + DBT *skey, *pkey, *olddata; +{ + DB *dbp; + DBC *sdbc; + DBT *toldskeyp, *tskeyp; + DBT oldskey, temppkey, tempskey; + ENV *env; + int ret, t_ret; + u_int32_t i, noldskey, nsame, nskey, rmw; + + sdbc = NULL; + dbp = sdbp->s_primary; + env = dbp->env; + nsame = 0; + rmw = STD_LOCKING(dbc) ? DB_RMW : 0; + + /* + * Get the old secondary key. + */ + memset(&oldskey, 0, sizeof(DBT)); + if ((ret = sdbp->s_callback(sdbp, pkey, olddata, &oldskey)) != 0) { + if (ret == DB_DONOTINDEX || + (F_ISSET(&oldskey, DB_DBT_MULTIPLE) && oldskey.size == 0)) + /* There's no old key to delete. */ + ret = 0; + return (ret); + } + + if (F_ISSET(&oldskey, DB_DBT_MULTIPLE)) { +#ifdef DIAGNOSTIC + __db_check_skeyset(sdbp, &oldskey); +#endif + toldskeyp = (DBT *)oldskey.data; + noldskey = oldskey.size; + } else { + toldskeyp = &oldskey; + noldskey = 1; + } + + if (F_ISSET(skey, DB_DBT_MULTIPLE)) { + nskey = skey->size; + skey = (DBT *)skey->data; + } else + nskey = F_ISSET(skey, DB_DBT_ISSET) ? 1 : 0; + + for (; noldskey > 0 && ret == 0; noldskey--, toldskeyp++) { + /* + * Check whether this old secondary key is also a new key + * before we delete it. Note that bt_compare is (and must be) + * set no matter what access method we're in. + */ + for (i = 0, tskeyp = skey; i < nskey; i++, tskeyp++) + if (((BTREE *)sdbp->bt_internal)->bt_compare(sdbp, + toldskeyp, tskeyp) == 0) { + nsame++; + F_CLR(tskeyp, DB_DBT_ISSET); + break; + } + + if (i < nskey) { + FREE_IF_NEEDED(env, toldskeyp); + continue; + } + + if (sdbc == NULL) { + if ((ret = __db_cursor_int(sdbp, + dbc->thread_info, dbc->txn, sdbp->type, + PGNO_INVALID, 0, dbc->locker, &sdbc)) != 0) + goto err; + if (CDB_LOCKING(env)) { + DB_ASSERT(env, + sdbc->mylock.off == LOCK_INVALID); + F_SET(sdbc, DBC_WRITER); + } + } + + /* + * Don't let c_get(DB_GET_BOTH) stomp on our data. Use + * temporary DBTs instead. + */ + SWAP_IF_NEEDED(sdbp, pkey); + DB_INIT_DBT(temppkey, pkey->data, pkey->size); + DB_INIT_DBT(tempskey, toldskeyp->data, toldskeyp->size); + if ((ret = __dbc_get(sdbc, + &tempskey, &temppkey, rmw | DB_GET_BOTH)) == 0) + ret = __dbc_del(sdbc, DB_UPDATE_SECONDARY); + else if (ret == DB_NOTFOUND) + ret = __db_secondary_corrupt(dbp); + SWAP_IF_NEEDED(sdbp, pkey); + FREE_IF_NEEDED(env, toldskeyp); + } + +err: for (; noldskey > 0; noldskey--, toldskeyp++) + FREE_IF_NEEDED(env, toldskeyp); + FREE_IF_NEEDED(env, &oldskey); + if (sdbc != NULL && (t_ret = __dbc_close(sdbc)) != 0 && ret == 0) + ret = t_ret; + if (ret == 0 && nsame == nskey) + return (DB_KEYEXIST); + return (ret); +} + +/* + * __db_duperr() + * Error message: we don't currently support sorted duplicate duplicates. + * PUBLIC: int __db_duperr __P((DB *, u_int32_t)); + */ +int +__db_duperr(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + /* + * If we run into this error while updating a secondary index, + * don't yell--there's no clean way to pass DB_NODUPDATA in along + * with DB_UPDATE_SECONDARY, but we may run into this problem + * in a normal, non-error course of events. + * + * !!! + * If and when we ever permit duplicate duplicates in sorted-dup + * databases, we need to either change the secondary index code + * to check for dup dups, or we need to maintain the implicit + * "DB_NODUPDATA" behavior for databases with DB_AM_SECONDARY set. + */ + if (flags != DB_NODUPDATA && !F_ISSET(dbp, DB_AM_SECONDARY)) + __db_errx(dbp->env, + "Duplicate data items are not supported with sorted data"); + return (DB_KEYEXIST); +} + +/* + * __dbc_cleanup -- + * Clean up duplicate cursors. + * + * PUBLIC: int __dbc_cleanup __P((DBC *, DBC *, int)); + */ +int +__dbc_cleanup(dbc, dbc_n, failed) + DBC *dbc, *dbc_n; + int failed; +{ + DB *dbp; + DBC *opd; + DBC_INTERNAL *internal; + DB_MPOOLFILE *mpf; + int ret, t_ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + internal = dbc->internal; + ret = 0; + + /* Discard any pages we're holding. */ + if (internal->page != NULL) { + if ((t_ret = __memp_fput(mpf, dbc->thread_info, + internal->page, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + internal->page = NULL; + } + opd = internal->opd; + if (opd != NULL && opd->internal->page != NULL) { + if ((t_ret = __memp_fput(mpf, dbc->thread_info, + opd->internal->page, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + opd->internal->page = NULL; + } + + /* + * If dbc_n is NULL, there's no internal cursor swapping to be done + * and no dbc_n to close--we probably did the entire operation on an + * offpage duplicate cursor. Just return. + * + * If dbc and dbc_n are the same, we're either inside a DB->{put/get} + * operation, and as an optimization we performed the operation on + * the main cursor rather than on a duplicated one, or we're in a + * bulk get that can't have moved the cursor (DB_MULTIPLE with the + * initial c_get operation on an off-page dup cursor). Just + * return--either we know we didn't move the cursor, or we're going + * to close it before we return to application code, so we're sure + * not to visibly violate the "cursor stays put on error" rule. + */ + if (dbc_n == NULL || dbc == dbc_n) + return (ret); + + if (dbc_n->internal->page != NULL) { + if ((t_ret = __memp_fput(mpf, dbc->thread_info, + dbc_n->internal->page, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + dbc_n->internal->page = NULL; + } + opd = dbc_n->internal->opd; + if (opd != NULL && opd->internal->page != NULL) { + if ((t_ret = __memp_fput(mpf, dbc->thread_info, + opd->internal->page, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + opd->internal->page = NULL; + } + + /* + * If we didn't fail before entering this routine or just now when + * freeing pages, swap the interesting contents of the old and new + * cursors. + */ + if (!failed && ret == 0) { + if (opd != NULL) + opd->internal->pdbc = dbc; + if (internal->opd != NULL) + internal->opd->internal->pdbc = dbc_n; + dbc->internal = dbc_n->internal; + dbc_n->internal = internal; + } + + /* + * Close the cursor we don't care about anymore. The close can fail, + * but we only expect DB_LOCK_DEADLOCK failures. This violates our + * "the cursor is unchanged on error" semantics, but since all you can + * do with a DB_LOCK_DEADLOCK failure is close the cursor, I believe + * that's OK. + * + * XXX + * There's no way to recover from failure to close the old cursor. + * All we can do is move to the new position and return an error. + * + * XXX + * We might want to consider adding a flag to the cursor, so that any + * subsequent operations other than close just return an error? + */ + if ((t_ret = __dbc_close(dbc_n)) != 0 && ret == 0) + ret = t_ret; + + /* + * If this was an update that is supporting dirty reads + * then we may have just swapped our read for a write lock + * which is held by the surviving cursor. We need + * to explicitly downgrade this lock. The closed cursor + * may only have had a read lock. + */ + if (F_ISSET(dbp, DB_AM_READ_UNCOMMITTED) && + dbc->internal->lock_mode == DB_LOCK_WRITE) { + if ((t_ret = + __TLPUT(dbc, dbc->internal->lock)) != 0 && ret == 0) + ret = t_ret; + if (t_ret == 0) + dbc->internal->lock_mode = DB_LOCK_WWRITE; + if (dbc->internal->page != NULL && (t_ret = + __memp_shared(dbp->mpf, dbc->internal->page)) != 0 && + ret == 0) + ret = t_ret; + } + + return (ret); +} + +/* + * __dbc_secondary_get_pp -- + * This wrapper function for DBC->pget() is the DBC->get() function + * for a secondary index cursor. + * + * PUBLIC: int __dbc_secondary_get_pp __P((DBC *, DBT *, DBT *, u_int32_t)); + */ +int +__dbc_secondary_get_pp(dbc, skey, data, flags) + DBC *dbc; + DBT *skey, *data; + u_int32_t flags; +{ + DB_ASSERT(dbc->env, F_ISSET(dbc->dbp, DB_AM_SECONDARY)); + return (__dbc_pget_pp(dbc, skey, NULL, data, flags)); +} + +/* + * __dbc_pget -- + * Get a primary key/data pair through a secondary index. + * + * PUBLIC: int __dbc_pget __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); + */ +int +__dbc_pget(dbc, skey, pkey, data, flags) + DBC *dbc; + DBT *skey, *pkey, *data; + u_int32_t flags; +{ + DB *pdbp, *sdbp; + DBC *dbc_n, *pdbc; + DBT nullpkey; + u_int32_t save_pkey_flags, tmp_flags, tmp_read_locking, tmp_rmw; + int pkeymalloc, ret, t_ret; + + sdbp = dbc->dbp; + pdbp = sdbp->s_primary; + dbc_n = NULL; + pkeymalloc = t_ret = 0; + + /* + * The challenging part of this function is getting the behavior + * right for all the various permutations of DBT flags. The + * next several blocks handle the various cases we need to + * deal with specially. + */ + + /* + * We may be called with a NULL pkey argument, if we've been + * wrapped by a 2-DBT get call. If so, we need to use our + * own DBT. + */ + if (pkey == NULL) { + memset(&nullpkey, 0, sizeof(DBT)); + pkey = &nullpkey; + } + + /* Clear OR'd in additional bits so we can check for flag equality. */ + tmp_rmw = LF_ISSET(DB_RMW); + LF_CLR(DB_RMW); + + SET_READ_LOCKING_FLAGS(dbc, tmp_read_locking); + /* + * DB_GET_RECNO is a special case, because we're interested not in + * the primary key/data pair, but rather in the primary's record + * number. + */ + if (flags == DB_GET_RECNO) { + if (tmp_rmw) + F_SET(dbc, DBC_RMW); + F_SET(dbc, tmp_read_locking); + ret = __dbc_pget_recno(dbc, pkey, data, flags); + if (tmp_rmw) + F_CLR(dbc, DBC_RMW); + /* Clear the temp flags, but leave WAS_READ_COMMITTED. */ + F_CLR(dbc, tmp_read_locking & ~DBC_WAS_READ_COMMITTED); + return (ret); + } + + /* + * If the DBTs we've been passed don't have any of the + * user-specified memory management flags set, we want to make sure + * we return values using the DBTs dbc->rskey, dbc->rkey, and + * dbc->rdata, respectively. + * + * There are two tricky aspects to this: first, we need to pass + * skey and pkey *in* to the initial c_get on the secondary key, + * since either or both may be looked at by it (depending on the + * get flag). Second, we must not use a normal DB->get call + * on the secondary, even though that's what we want to accomplish, + * because the DB handle may be free-threaded. Instead, + * we open a cursor, then take steps to ensure that we actually use + * the rkey/rdata from the *secondary* cursor. + * + * We accomplish all this by passing in the DBTs we started out + * with to the c_get, but swapping the contents of rskey and rkey, + * respectively, into rkey and rdata; __db_ret will treat them like + * the normal key/data pair in a c_get call, and will realloc them as + * need be (this is "step 1"). Then, for "step 2", we swap back + * rskey/rkey/rdata to normal, and do a get on the primary with the + * secondary dbc appointed as the owner of the returned-data memory. + * + * Note that in step 2, we copy the flags field in case we need to + * pass down a DB_DBT_PARTIAL or other flag that is compatible with + * letting DB do the memory management. + */ + + /* + * It is correct, though slightly sick, to attempt a partial get of a + * primary key. However, if we do so here, we'll never find the + * primary record; clear the DB_DBT_PARTIAL field of pkey just for the + * duration of the next call. + */ + save_pkey_flags = pkey->flags; + F_CLR(pkey, DB_DBT_PARTIAL); + + /* + * Now we can go ahead with the meat of this call. First, get the + * primary key from the secondary index. (What exactly we get depends + * on the flags, but the underlying cursor get will take care of the + * dirty work.) Duplicate the cursor, in case the later get on the + * primary fails. + */ + switch (flags) { + case DB_CURRENT: + case DB_GET_BOTHC: + case DB_NEXT: + case DB_NEXT_DUP: + case DB_NEXT_NODUP: + case DB_PREV: + case DB_PREV_DUP: + case DB_PREV_NODUP: + tmp_flags = DB_POSITION; + break; + default: + tmp_flags = 0; + break; + } + + if (F_ISSET(dbc, DBC_PARTITIONED | DBC_TRANSIENT)) + dbc_n = dbc; + else if ((ret = __dbc_dup(dbc, &dbc_n, tmp_flags)) != 0) + return (ret); + + F_SET(dbc_n, DBC_TRANSIENT); + + if (tmp_rmw) + F_SET(dbc_n, DBC_RMW); + F_SET(dbc_n, tmp_read_locking); + + /* + * If we've been handed a primary key, it will be in native byte order, + * so we need to swap it before reading from the secondary. + */ + if (flags == DB_GET_BOTH || flags == DB_GET_BOTHC || + flags == DB_GET_BOTH_RANGE) + SWAP_IF_NEEDED(sdbp, pkey); + +retry: /* Step 1. */ + dbc_n->rdata = dbc->rkey; + dbc_n->rkey = dbc->rskey; + ret = __dbc_get(dbc_n, skey, pkey, flags); + /* Restore pkey's flags in case we stomped the PARTIAL flag. */ + pkey->flags = save_pkey_flags; + + /* + * We need to swap the primary key to native byte order if we read it + * successfully, or if we swapped it on entry above. We can't return + * with the application's data modified. + */ + if (ret == 0 || flags == DB_GET_BOTH || flags == DB_GET_BOTHC || + flags == DB_GET_BOTH_RANGE) + SWAP_IF_NEEDED(sdbp, pkey); + + if (ret != 0) + goto err; + + /* + * Now we're ready for "step 2". If either or both of pkey and data do + * not have memory management flags set--that is, if DB is managing + * their memory--we need to swap around the rkey/rdata structures so + * that we don't wind up trying to use memory managed by the primary + * database cursor, which we'll close before we return. + * + * !!! + * If you're carefully following the bouncing ball, you'll note that in + * the DB-managed case, the buffer hanging off of pkey is the same as + * dbc->rkey->data. This is just fine; we may well realloc and stomp + * on it when we return, if we're doing a DB_GET_BOTH and need to + * return a different partial or key (depending on the comparison + * function), but this is safe. + * + * !!! + * We need to use __db_cursor_int here rather than simply calling + * pdbp->cursor, because otherwise, if we're in CDB, we'll allocate a + * new locker ID and leave ourselves open to deadlocks. (Even though + * we're only acquiring read locks, we'll still block if there are any + * waiters.) + */ + if ((ret = __db_cursor_int(pdbp, dbc->thread_info, + dbc->txn, pdbp->type, PGNO_INVALID, 0, dbc->locker, &pdbc)) != 0) + goto err; + + F_SET(pdbc, tmp_read_locking | + F_ISSET(dbc, DBC_READ_UNCOMMITTED | DBC_READ_COMMITTED | DBC_RMW)); + + /* + * We're about to use pkey a second time. If DB_DBT_MALLOC is set on + * it, we'll leak the memory we allocated the first time. Thus, set + * DB_DBT_REALLOC instead so that we reuse that memory instead of + * leaking it. + * + * Alternatively, if the application is handling copying for pkey, we + * need to take a copy now. The copy will be freed on exit from + * __dbc_pget_pp (and we must be coming through there if DB_DBT_USERCOPY + * is set). In the case of DB_GET_BOTH_RANGE, the pkey supplied by + * the application has already been copied in but the value may have + * changed in the search. In that case, free the original copy and get + * a new one. + * + * !!! + * This assumes that the user must always specify a compatible realloc + * function if a malloc function is specified. I think this is a + * reasonable requirement. + */ + if (F_ISSET(pkey, DB_DBT_MALLOC)) { + F_CLR(pkey, DB_DBT_MALLOC); + F_SET(pkey, DB_DBT_REALLOC); + pkeymalloc = 1; + } else if (F_ISSET(pkey, DB_DBT_USERCOPY)) { + if (flags == DB_GET_BOTH_RANGE) + __dbt_userfree(sdbp->env, NULL, pkey, NULL); + if ((ret = __dbt_usercopy(sdbp->env, pkey)) != 0) + goto err; + } + + /* + * Do the actual get. Set DBC_TRANSIENT since we don't care about + * preserving the position on error, and it's faster. SET_RET_MEM so + * that the secondary DBC owns any returned-data memory. + */ + F_SET(pdbc, DBC_TRANSIENT); + SET_RET_MEM(pdbc, dbc); + ret = __dbc_get(pdbc, pkey, data, DB_SET); + + /* + * If the item wasn't found in the primary, this is a bug; our + * secondary has somehow gotten corrupted, and contains elements that + * don't correspond to anything in the primary. Complain. + */ + + /* Now close the primary cursor. */ + if ((t_ret = __dbc_close(pdbc)) != 0 && ret == 0) + ret = t_ret; + + else if (ret == DB_NOTFOUND) { + if (!F_ISSET(pdbc, DBC_READ_UNCOMMITTED)) + ret = __db_secondary_corrupt(pdbp); + else switch (flags) { + case DB_GET_BOTHC: + case DB_NEXT: + case DB_NEXT_DUP: + case DB_NEXT_NODUP: + case DB_PREV: + case DB_PREV_DUP: + case DB_PREV_NODUP: + goto retry; + default: + break; + } + } + +err: /* Cleanup and cursor resolution. */ + if ((t_ret = __dbc_cleanup(dbc, dbc_n, ret)) != 0 && ret == 0) + ret = t_ret; + if (pkeymalloc) { + /* + * If pkey had a MALLOC flag, we need to restore it; otherwise, + * if the user frees the buffer but reuses the DBT without + * NULL'ing its data field or changing the flags, we may drop + * core. + */ + F_CLR(pkey, DB_DBT_REALLOC); + F_SET(pkey, DB_DBT_MALLOC); + } + + return (ret); +} + +/* + * __dbc_pget_recno -- + * Perform a DB_GET_RECNO c_pget on a secondary index. Returns + * the secondary's record number in the pkey field and the primary's + * in the data field. + */ +static int +__dbc_pget_recno(sdbc, pkey, data, flags) + DBC *sdbc; + DBT *pkey, *data; + u_int32_t flags; +{ + DB *pdbp, *sdbp; + DBC *pdbc; + DBT discardme, primary_key; + ENV *env; + db_recno_t oob; + u_int32_t rmw; + int ret, t_ret; + + sdbp = sdbc->dbp; + pdbp = sdbp->s_primary; + env = sdbp->env; + pdbc = NULL; + ret = t_ret = 0; + + rmw = LF_ISSET(DB_RMW); + + memset(&discardme, 0, sizeof(DBT)); + F_SET(&discardme, DB_DBT_USERMEM | DB_DBT_PARTIAL); + + oob = RECNO_OOB; + + /* + * If the primary is an rbtree, we want its record number, whether + * or not the secondary is one too. Fetch the recno into "data". + * + * If it's not an rbtree, return RECNO_OOB in "data". + */ + if (F_ISSET(pdbp, DB_AM_RECNUM)) { + /* + * Get the primary key, so we can find the record number + * in the primary. (We're uninterested in the secondary key.) + */ + memset(&primary_key, 0, sizeof(DBT)); + F_SET(&primary_key, DB_DBT_MALLOC); + if ((ret = __dbc_get(sdbc, + &discardme, &primary_key, rmw | DB_CURRENT)) != 0) + return (ret); + + /* + * Open a cursor on the primary, set it to the right record, + * and fetch its recno into "data". + * + * (See __dbc_pget for comments on the use of __db_cursor_int.) + * + * SET_RET_MEM so that the secondary DBC owns any returned-data + * memory. + */ + if ((ret = __db_cursor_int(pdbp, sdbc->thread_info, sdbc->txn, + pdbp->type, PGNO_INVALID, 0, sdbc->locker, &pdbc)) != 0) + goto perr; + SET_RET_MEM(pdbc, sdbc); + if ((ret = __dbc_get(pdbc, + &primary_key, &discardme, rmw | DB_SET)) != 0) + goto perr; + + ret = __dbc_get(pdbc, &discardme, data, rmw | DB_GET_RECNO); + +perr: __os_ufree(env, primary_key.data); + if (pdbc != NULL && + (t_ret = __dbc_close(pdbc)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + return (ret); + } else if ((ret = __db_retcopy(env, data, &oob, + sizeof(oob), &sdbc->rkey->data, &sdbc->rkey->ulen)) != 0) + return (ret); + + /* + * If the secondary is an rbtree, we want its record number, whether + * or not the primary is one too. Fetch the recno into "pkey". + * + * If it's not an rbtree, return RECNO_OOB in "pkey". + */ + if (F_ISSET(sdbp, DB_AM_RECNUM)) + return (__dbc_get(sdbc, &discardme, pkey, flags)); + else + return (__db_retcopy(env, pkey, &oob, + sizeof(oob), &sdbc->rdata->data, &sdbc->rdata->ulen)); +} + +/* + * __db_wrlock_err -- do not have a write lock. + */ +static int +__db_wrlock_err(env) + ENV *env; +{ + __db_errx(env, "Write attempted on read-only cursor"); + return (EPERM); +} + +/* + * __dbc_del_secondary -- + * Perform a delete operation on a secondary index: call through + * to the primary and delete the primary record that this record + * points to. + * + * Note that deleting the primary record will call c_del on all + * the secondaries, including this one; thus, it is not necessary + * to execute both this function and an actual delete. + */ +static int +__dbc_del_secondary(dbc) + DBC *dbc; +{ + DB *pdbp; + DBC *pdbc; + DBT skey, pkey; + ENV *env; + int ret, t_ret; + u_int32_t rmw; + + pdbp = dbc->dbp->s_primary; + env = pdbp->env; + rmw = STD_LOCKING(dbc) ? DB_RMW : 0; + + /* + * Get the current item that we're pointing at. + * We don't actually care about the secondary key, just + * the primary. + */ + memset(&skey, 0, sizeof(DBT)); + memset(&pkey, 0, sizeof(DBT)); + F_SET(&skey, DB_DBT_PARTIAL | DB_DBT_USERMEM); + if ((ret = __dbc_get(dbc, &skey, &pkey, DB_CURRENT)) != 0) + return (ret); + + SWAP_IF_NEEDED(dbc->dbp, &pkey); + + /* + * Create a cursor on the primary with our locker ID, + * so that when it calls back, we don't conflict. + * + * We create a cursor explicitly because there's no + * way to specify the same locker ID if we're using + * locking but not transactions if we use the DB->del + * interface. This shouldn't be any less efficient + * anyway. + */ + if ((ret = __db_cursor_int(pdbp, dbc->thread_info, dbc->txn, + pdbp->type, PGNO_INVALID, 0, dbc->locker, &pdbc)) != 0) + return (ret); + + /* + * See comment in __dbc_put--if we're in CDB, + * we already hold the locks we need, and we need to flag + * the cursor as a WRITER so we don't run into errors + * when we try to delete. + */ + if (CDB_LOCKING(env)) { + DB_ASSERT(env, pdbc->mylock.off == LOCK_INVALID); + F_SET(pdbc, DBC_WRITER); + } + + /* + * Set the new cursor to the correct primary key. Then + * delete it. We don't really care about the datum; + * just reuse our skey DBT. + * + * If the primary get returns DB_NOTFOUND, something is amiss-- + * every record in the secondary should correspond to some record + * in the primary. + */ + if ((ret = __dbc_get(pdbc, &pkey, &skey, DB_SET | rmw)) == 0) + ret = __dbc_del(pdbc, 0); + else if (ret == DB_NOTFOUND) + ret = __db_secondary_corrupt(pdbp); + + if ((t_ret = __dbc_close(pdbc)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __dbc_del_primary -- + * Perform a delete operation on a primary index. Loop through + * all the secondary indices which correspond to this primary + * database, and delete any secondary keys that point at the current + * record. + * + * PUBLIC: int __dbc_del_primary __P((DBC *)); + */ +int +__dbc_del_primary(dbc) + DBC *dbc; +{ + DB *dbp, *sdbp; + DBC *sdbc; + DBT *tskeyp; + DBT data, pkey, skey, temppkey, tempskey; + ENV *env; + u_int32_t nskey, rmw; + int ret, t_ret; + + dbp = dbc->dbp; + env = dbp->env; + sdbp = NULL; + rmw = STD_LOCKING(dbc) ? DB_RMW : 0; + + /* + * If we're called at all, we have at least one secondary. + * (Unfortunately, we can't assert this without grabbing the mutex.) + * Get the current record so that we can construct appropriate + * secondary keys as needed. + */ + memset(&pkey, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + if ((ret = __dbc_get(dbc, &pkey, &data, DB_CURRENT)) != 0) + return (ret); + + memset(&skey, 0, sizeof(DBT)); + for (ret = __db_s_first(dbp, &sdbp); + sdbp != NULL && ret == 0; + ret = __db_s_next(&sdbp, dbc->txn)) { + /* + * Get the secondary key for this secondary and the current + * item. + */ + if ((ret = sdbp->s_callback(sdbp, &pkey, &data, &skey)) != 0) { + /* Not indexing is equivalent to an empty key set. */ + if (ret == DB_DONOTINDEX) { + F_SET(&skey, DB_DBT_MULTIPLE); + skey.size = 0; + } else /* We had a substantive error. Bail. */ + goto err; + } + +#ifdef DIAGNOSTIC + if (F_ISSET(&skey, DB_DBT_MULTIPLE)) + __db_check_skeyset(sdbp, &skey); +#endif + + if (F_ISSET(&skey, DB_DBT_MULTIPLE)) { + tskeyp = (DBT *)skey.data; + nskey = skey.size; + if (nskey == 0) + continue; + } else { + tskeyp = &skey; + nskey = 1; + } + + /* Open a secondary cursor. */ + if ((ret = __db_cursor_int(sdbp, + dbc->thread_info, dbc->txn, sdbp->type, + PGNO_INVALID, 0, dbc->locker, &sdbc)) != 0) + goto err; + /* See comment above and in __dbc_put. */ + if (CDB_LOCKING(env)) { + DB_ASSERT(env, sdbc->mylock.off == LOCK_INVALID); + F_SET(sdbc, DBC_WRITER); + } + + for (; nskey > 0; nskey--, tskeyp++) { + /* + * Set the secondary cursor to the appropriate item. + * Delete it. + * + * We want to use DB_RMW if locking is on; it's only + * legal then, though. + * + * !!! + * Don't stomp on any callback-allocated buffer in skey + * when we do a c_get(DB_GET_BOTH); use a temp DBT + * instead. Similarly, don't allow pkey to be + * invalidated when the cursor is closed. + */ + DB_INIT_DBT(tempskey, tskeyp->data, tskeyp->size); + SWAP_IF_NEEDED(sdbp, &pkey); + DB_INIT_DBT(temppkey, pkey.data, pkey.size); + if ((ret = __dbc_get(sdbc, &tempskey, &temppkey, + DB_GET_BOTH | rmw)) == 0) + ret = __dbc_del(sdbc, DB_UPDATE_SECONDARY); + else if (ret == DB_NOTFOUND) + ret = __db_secondary_corrupt(dbp); + SWAP_IF_NEEDED(sdbp, &pkey); + FREE_IF_NEEDED(env, tskeyp); + } + + if ((t_ret = __dbc_close(sdbc)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + goto err; + + /* + * In the common case where there is a single secondary key, we + * will have freed any application-allocated data in skey + * already. In the multiple key case, we need to free it here. + * It is safe to do this twice as the macro resets the data + * field. + */ + FREE_IF_NEEDED(env, &skey); + } + +err: if (sdbp != NULL && + (t_ret = __db_s_done(sdbp, dbc->txn)) != 0 && ret == 0) + ret = t_ret; + FREE_IF_NEEDED(env, &skey); + return (ret); +} + +/* + * __dbc_del_foreign -- + * Apply the foreign database constraints for a particular foreign + * database when an item is being deleted (dbc points at item being deleted + * in the foreign database.) + * + * Delete happens in dbp, check for occurrences of key in pdpb. + * Terminology: + * Foreign db = Where delete occurs (dbp). + * Secondary db = Where references to dbp occur (sdbp, a secondary) + * Primary db = sdbp's primary database, references to dbp are secondary + * keys here + * Foreign Key = Key being deleted in dbp (fkey) + * Primary Key = Key of the corresponding entry in sdbp's primary (pkey). + */ +static int +__dbc_del_foreign(dbc) + DBC *dbc; +{ + DB_FOREIGN_INFO *f_info; + DB *dbp, *pdbp, *sdbp; + DBC *pdbc, *sdbc; + DBT data, fkey, pkey; + ENV *env; + u_int32_t flags, rmw; + int changed, ret, t_ret; + + dbp = dbc->dbp; + env = dbp->env; + + memset(&fkey, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + if ((ret = __dbc_get(dbc, &fkey, &data, DB_CURRENT)) != 0) + return (ret); + + LIST_FOREACH(f_info, &(dbp->f_primaries), f_links) { + sdbp = f_info->dbp; + pdbp = sdbp->s_primary; + flags = f_info->flags; + + rmw = (STD_LOCKING(dbc) && + !LF_ISSET(DB_FOREIGN_ABORT)) ? DB_RMW : 0; + + /* + * Handle CDB locking. Some of this is copied from + * __dbc_del_primary, but a bit more acrobatics are required. + * If we're not going to abort, then we need to get a write + * cursor. If CDB_ALLDB is set, then only one write cursor is + * allowed and we hold it, so we fudge things and promote the + * cursor on the other DBs manually, it won't cause a problem. + * If CDB_ALLDB is not set, then we go through the usual route + * to make sure we block as necessary. If there are any open + * read cursors on sdbp, the delete or put call later will + * block. + * + * If NULLIFY is set, we'll need a cursor on the primary to + * update it with the nullified data. Because primary and + * secondary dbs share a lock file ID in CDB, we open a cursor + * on the secondary and then get another writeable cursor on the + * primary via __db_cursor_int to avoid deadlocking. + */ + sdbc = pdbc = NULL; + if (!LF_ISSET(DB_FOREIGN_ABORT) && CDB_LOCKING(env) && + !F_ISSET(env->dbenv, DB_ENV_CDB_ALLDB)) { + ret = __db_cursor(sdbp, + dbc->thread_info, dbc->txn, &sdbc, DB_WRITECURSOR); + if (LF_ISSET(DB_FOREIGN_NULLIFY) && ret == 0) { + ret = __db_cursor_int(pdbp, + dbc->thread_info, dbc->txn, pdbp->type, + PGNO_INVALID, 0, dbc->locker, &pdbc); + F_SET(pdbc, DBC_WRITER); + } + } else { + ret = __db_cursor_int(sdbp, dbc->thread_info, dbc->txn, + sdbp->type, PGNO_INVALID, 0, dbc->locker, &sdbc); + if (LF_ISSET(DB_FOREIGN_NULLIFY) && ret == 0) + ret = __db_cursor_int(pdbp, dbc->thread_info, + dbc->txn, pdbp->type, PGNO_INVALID, 0, + dbc->locker, &pdbc); + } + if (ret != 0) { + if (sdbc != NULL) + (void)__dbc_close(sdbc); + return (ret); + } + if (CDB_LOCKING(env) && F_ISSET(env->dbenv, DB_ENV_CDB_ALLDB)) { + DB_ASSERT(env, sdbc->mylock.off == LOCK_INVALID); + F_SET(sdbc, DBC_WRITER); + if (LF_ISSET(DB_FOREIGN_NULLIFY) && pdbc != NULL) { + DB_ASSERT(env, + pdbc->mylock.off == LOCK_INVALID); + F_SET(pdbc, DBC_WRITER); + } + } + + /* + * There are three actions possible when a foreign database has + * items corresponding to a deleted item: + * DB_FOREIGN_ABORT - The delete operation should be aborted. + * DB_FOREIGN_CASCADE - All corresponding foreign items should + * be deleted. + * DB_FOREIGN_NULLIFY - A callback needs to be made, allowing + * the application to modify the data DBT from the + * associated database. If the callback makes a + * modification, the updated item needs to replace the + * original item in the foreign db + */ + memset(&pkey, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + ret = __dbc_pget(sdbc, &fkey, &pkey, &data, DB_SET|rmw); + + if (ret == DB_NOTFOUND) { + /* No entry means no constraint */ + ret = __dbc_close(sdbc); + if (LF_ISSET(DB_FOREIGN_NULLIFY) && + (t_ret = __dbc_close(pdbc)) != 0) + ret = t_ret; + if (ret != 0) + return (ret); + continue; + } else if (ret != 0) { + /* Just return the error code from the pget */ + (void)__dbc_close(sdbc); + if (LF_ISSET(DB_FOREIGN_NULLIFY)) + (void)__dbc_close(pdbc); + return (ret); + } else if (LF_ISSET(DB_FOREIGN_ABORT)) { + /* If the record exists and ABORT is set, we're done */ + if ((ret = __dbc_close(sdbc)) != 0) + return (ret); + return (DB_FOREIGN_CONFLICT); + } + + /* + * There were matching items in the primary DB, and the action + * is either DB_FOREIGN_CASCADE or DB_FOREIGN_NULLIFY. + */ + while (ret == 0) { + if (LF_ISSET(DB_FOREIGN_CASCADE)) { + /* + * Don't use the DB_UPDATE_SECONDARY flag, + * since we want the delete to cascade into the + * secondary's primary. + */ + if ((ret = __dbc_del(sdbc, 0)) != 0) { + __db_err(env, ret, + "Attempt to execute cascading delete in a foreign index failed"); + break; + } + } else if (LF_ISSET(DB_FOREIGN_NULLIFY)) { + changed = 0; + if ((ret = f_info->callback(sdbp, + &pkey, &data, &fkey, &changed)) != 0) { + __db_err(env, ret, + "Foreign database application callback"); + break; + } + + /* + * If the user callback modified the DBT and + * a put on the primary failed. + */ + if (changed && (ret = __dbc_put(pdbc, + &pkey, &data, DB_KEYFIRST)) != 0) { + __db_err(env, ret, + "Attempt to overwrite item in foreign database with nullified value failed"); + break; + } + } + /* retrieve the next matching item from the prim. db */ + memset(&pkey, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + ret = __dbc_pget(sdbc, + &fkey, &pkey, &data, DB_NEXT_DUP|rmw); + } + + if (ret == DB_NOTFOUND) + ret = 0; + if ((t_ret = __dbc_close(sdbc)) != 0 && ret == 0) + ret = t_ret; + if (LF_ISSET(DB_FOREIGN_NULLIFY) && + (t_ret = __dbc_close(pdbc)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + return (ret); + } + + return (ret); +} + +/* + * __db_s_first -- + * Get the first secondary, if any are present, from the primary. + * + * PUBLIC: int __db_s_first __P((DB *, DB **)); + */ +int +__db_s_first(pdbp, sdbpp) + DB *pdbp, **sdbpp; +{ + DB *sdbp; + + MUTEX_LOCK(pdbp->env, pdbp->mutex); + sdbp = LIST_FIRST(&pdbp->s_secondaries); + + /* See __db_s_next. */ + if (sdbp != NULL) + sdbp->s_refcnt++; + MUTEX_UNLOCK(pdbp->env, pdbp->mutex); + + *sdbpp = sdbp; + + return (0); +} + +/* + * __db_s_next -- + * Get the next secondary in the list. + * + * PUBLIC: int __db_s_next __P((DB **, DB_TXN *)); + */ +int +__db_s_next(sdbpp, txn) + DB **sdbpp; + DB_TXN *txn; +{ + DB *sdbp, *pdbp, *closeme; + ENV *env; + int ret; + + /* + * Secondary indices are kept in a linked list, s_secondaries, + * off each primary DB handle. If a primary is free-threaded, + * this list may only be traversed or modified while the primary's + * thread mutex is held. + * + * The tricky part is that we don't want to hold the thread mutex + * across the full set of secondary puts necessary for each primary + * put, or we'll wind up essentially single-threading all the puts + * to the handle; the secondary puts will each take about as + * long as the primary does, and may require I/O. So we instead + * hold the thread mutex only long enough to follow one link to the + * next secondary, and then we release it before performing the + * actual secondary put. + * + * The only danger here is that we might legitimately close a + * secondary index in one thread while another thread is performing + * a put and trying to update that same secondary index. To + * prevent this from happening, we refcount the secondary handles. + * If close is called on a secondary index handle while we're putting + * to it, it won't really be closed--the refcount will simply drop, + * and we'll be responsible for closing it here. + */ + sdbp = *sdbpp; + pdbp = sdbp->s_primary; + env = pdbp->env; + closeme = NULL; + + MUTEX_LOCK(env, pdbp->mutex); + DB_ASSERT(env, sdbp->s_refcnt != 0); + if (--sdbp->s_refcnt == 0) { + LIST_REMOVE(sdbp, s_links); + closeme = sdbp; + } + sdbp = LIST_NEXT(sdbp, s_links); + if (sdbp != NULL) + sdbp->s_refcnt++; + MUTEX_UNLOCK(env, pdbp->mutex); + + *sdbpp = sdbp; + + /* + * closeme->close() is a wrapper; call __db_close explicitly. + */ + if (closeme == NULL) + ret = 0; + else + ret = __db_close(closeme, txn, 0); + + return (ret); +} + +/* + * __db_s_done -- + * Properly decrement the refcount on a secondary database handle we're + * using, without calling __db_s_next. + * + * PUBLIC: int __db_s_done __P((DB *, DB_TXN *)); + */ +int +__db_s_done(sdbp, txn) + DB *sdbp; + DB_TXN *txn; +{ + DB *pdbp; + ENV *env; + int doclose, ret; + + pdbp = sdbp->s_primary; + env = pdbp->env; + doclose = 0; + + MUTEX_LOCK(env, pdbp->mutex); + DB_ASSERT(env, sdbp->s_refcnt != 0); + if (--sdbp->s_refcnt == 0) { + LIST_REMOVE(sdbp, s_links); + doclose = 1; + } + MUTEX_UNLOCK(env, pdbp->mutex); + + if (doclose == 0) + ret = 0; + else + ret = __db_close(sdbp, txn, 0); + return (ret); +} + +/* + * __db_s_count -- + * Count the number of secondaries associated with a given primary. + */ +static int +__db_s_count(pdbp) + DB *pdbp; +{ + DB *sdbp; + ENV *env; + int count; + + env = pdbp->env; + count = 0; + + MUTEX_LOCK(env, pdbp->mutex); + for (sdbp = LIST_FIRST(&pdbp->s_secondaries); + sdbp != NULL; + sdbp = LIST_NEXT(sdbp, s_links)) + ++count; + MUTEX_UNLOCK(env, pdbp->mutex); + + return (count); +} + +/* + * __db_buildpartial -- + * Build the record that will result after a partial put is applied to + * an existing record. + * + * This should probably be merged with __bam_build, but that requires + * a little trickery if we plan to keep the overflow-record optimization + * in that function. + * + * PUBLIC: int __db_buildpartial __P((DB *, DBT *, DBT *, DBT *)); + */ +int +__db_buildpartial(dbp, oldrec, partial, newrec) + DB *dbp; + DBT *oldrec, *partial, *newrec; +{ + ENV *env; + u_int32_t len, nbytes; + u_int8_t *buf; + int ret; + + env = dbp->env; + + DB_ASSERT(env, F_ISSET(partial, DB_DBT_PARTIAL)); + + memset(newrec, 0, sizeof(DBT)); + + nbytes = __db_partsize(oldrec->size, partial); + newrec->size = nbytes; + + if ((ret = __os_malloc(env, nbytes, &buf)) != 0) + return (ret); + newrec->data = buf; + + /* Nul or pad out the buffer, for any part that isn't specified. */ + memset(buf, + F_ISSET(dbp, DB_AM_FIXEDLEN) ? ((BTREE *)dbp->bt_internal)->re_pad : + 0, nbytes); + + /* Copy in any leading data from the original record. */ + memcpy(buf, oldrec->data, + partial->doff > oldrec->size ? oldrec->size : partial->doff); + + /* Copy the data from partial. */ + memcpy(buf + partial->doff, partial->data, partial->size); + + /* Copy any trailing data from the original record. */ + len = partial->doff + partial->dlen; + if (oldrec->size > len) + memcpy(buf + partial->doff + partial->size, + (u_int8_t *)oldrec->data + len, oldrec->size - len); + + return (0); +} + +/* + * __db_partsize -- + * Given the number of bytes in an existing record and a DBT that + * is about to be partial-put, calculate the size of the record + * after the put. + * + * This code is called from __bam_partsize. + * + * PUBLIC: u_int32_t __db_partsize __P((u_int32_t, DBT *)); + */ +u_int32_t +__db_partsize(nbytes, data) + u_int32_t nbytes; + DBT *data; +{ + + /* + * There are really two cases here: + * + * Case 1: We are replacing some bytes that do not exist (i.e., they + * are past the end of the record). In this case the number of bytes + * we are replacing is irrelevant and all we care about is how many + * bytes we are going to add from offset. So, the new record length + * is going to be the size of the new bytes (size) plus wherever those + * new bytes begin (doff). + * + * Case 2: All the bytes we are replacing exist. Therefore, the new + * size is the oldsize (nbytes) minus the bytes we are replacing (dlen) + * plus the bytes we are adding (size). + */ + if (nbytes < data->doff + data->dlen) /* Case 1 */ + return (data->doff + data->size); + + return (nbytes + data->size - data->dlen); /* Case 2 */ +} + +#ifdef DIAGNOSTIC +/* + * __db_check_skeyset -- + * Diagnostic check that the application's callback returns a set of + * secondary keys without repeats. + * + * PUBLIC: #ifdef DIAGNOSTIC + * PUBLIC: void __db_check_skeyset __P((DB *, DBT *)); + * PUBLIC: #endif + */ +void +__db_check_skeyset(sdbp, skeyp) + DB *sdbp; + DBT *skeyp; +{ + DBT *firstkey, *lastkey, *key1, *key2; + ENV *env; + + env = sdbp->env; + + firstkey = (DBT *)skeyp->data; + lastkey = firstkey + skeyp->size; + for (key1 = firstkey; key1 < lastkey; key1++) + for (key2 = key1 + 1; key2 < lastkey; key2++) + DB_ASSERT(env, + ((BTREE *)sdbp->bt_internal)->bt_compare(sdbp, + key1, key2) != 0); +} +#endif diff --git a/src/libs/resiprocate/contrib/db/db/db_conv.c b/src/libs/resiprocate/contrib/db/db/db_conv.c new file mode 100644 index 00000000..45726839 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_conv.c @@ -0,0 +1,733 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/crypto.h" +#include "dbinc/hmac.h" +#include "dbinc/db_page.h" +#include "dbinc/db_swap.h" +#include "dbinc/btree.h" +#include "dbinc/hash.h" +#include "dbinc/log.h" +#include "dbinc/qam.h" + +/* + * __db_pgin -- + * Primary page-swap routine. + * + * PUBLIC: int __db_pgin __P((DB_ENV *, db_pgno_t, void *, DBT *)); + */ +int +__db_pgin(dbenv, pg, pp, cookie) + DB_ENV *dbenv; + db_pgno_t pg; + void *pp; + DBT *cookie; +{ + DB dummydb, *dbp; + DB_CIPHER *db_cipher; + DB_LSN not_used; + DB_PGINFO *pginfo; + ENV *env; + PAGE *pagep; + size_t sum_len; + int is_hmac, ret; + u_int8_t *chksum; + + pginfo = (DB_PGINFO *)cookie->data; + env = dbenv->env; + pagep = (PAGE *)pp; + + ret = is_hmac = 0; + chksum = NULL; + memset(&dummydb, 0, sizeof(DB)); + dbp = &dummydb; + dbp->dbenv = dbenv; + dbp->env = env; + dbp->flags = pginfo->flags; + dbp->pgsize = pginfo->db_pagesize; + db_cipher = env->crypto_handle; + switch (pagep->type) { + case P_HASHMETA: + case P_BTREEMETA: + case P_QAMMETA: + /* + * If checksumming is set on the meta-page, we must set + * it in the dbp. + */ + if (FLD_ISSET(((DBMETA *)pp)->metaflags, DBMETA_CHKSUM)) + F_SET(dbp, DB_AM_CHKSUM); + else + F_CLR(dbp, DB_AM_CHKSUM); + if (((DBMETA *)pp)->encrypt_alg != 0 || + F_ISSET(dbp, DB_AM_ENCRYPT)) + is_hmac = 1; + /* + * !!! + * For all meta pages it is required that the chksum + * be at the same location. Use BTMETA to get to it + * for any meta type. + */ + chksum = ((BTMETA *)pp)->chksum; + sum_len = DBMETASIZE; + break; + case P_INVALID: + /* + * We assume that we've read a file hole if we have + * a zero LSN, zero page number and P_INVALID. Otherwise + * we have an invalid page that might contain real data. + */ + if (IS_ZERO_LSN(LSN(pagep)) && pagep->pgno == PGNO_INVALID) { + sum_len = 0; + break; + } + /* FALLTHROUGH */ + default: + chksum = P_CHKSUM(dbp, pagep); + sum_len = pginfo->db_pagesize; + /* + * If we are reading in a non-meta page, then if we have + * a db_cipher then we are using hmac. + */ + is_hmac = CRYPTO_ON(env) ? 1 : 0; + break; + } + + /* + * We expect a checksum error if there was a configuration problem. + * If there is no configuration problem and we don't get a match, + * it's fatal: panic the system. + */ + if (F_ISSET(dbp, DB_AM_CHKSUM) && sum_len != 0) { + if (F_ISSET(dbp, DB_AM_SWAP) && is_hmac == 0) + P_32_SWAP(chksum); + switch (ret = __db_check_chksum( + env, NULL, db_cipher, chksum, pp, sum_len, is_hmac)) { + case 0: + break; + case -1: + if (DBENV_LOGGING(env)) + (void)__db_cksum_log( + env, NULL, ¬_used, DB_FLUSH); + __db_errx(env, + "checksum error: page %lu: catastrophic recovery required", + (u_long)pg); + return (__env_panic(env, DB_RUNRECOVERY)); + default: + return (ret); + } + } + if ((ret = __db_decrypt_pg(env, dbp, pagep)) != 0) + return (ret); + switch (pagep->type) { + case P_INVALID: + if (pginfo->type == DB_QUEUE) + return (__qam_pgin_out(env, pg, pp, cookie)); + else + return (__ham_pgin(dbp, pg, pp, cookie)); + case P_HASH_UNSORTED: + case P_HASH: + case P_HASHMETA: + return (__ham_pgin(dbp, pg, pp, cookie)); + case P_BTREEMETA: + case P_IBTREE: + case P_IRECNO: + case P_LBTREE: + case P_LDUP: + case P_LRECNO: + case P_OVERFLOW: + return (__bam_pgin(dbp, pg, pp, cookie)); + case P_QAMMETA: + case P_QAMDATA: + return (__qam_pgin_out(env, pg, pp, cookie)); + default: + break; + } + return (__db_pgfmt(env, pg)); +} + +/* + * __db_pgout -- + * Primary page-swap routine. + * + * PUBLIC: int __db_pgout __P((DB_ENV *, db_pgno_t, void *, DBT *)); + */ +int +__db_pgout(dbenv, pg, pp, cookie) + DB_ENV *dbenv; + db_pgno_t pg; + void *pp; + DBT *cookie; +{ + DB dummydb, *dbp; + DB_PGINFO *pginfo; + ENV *env; + PAGE *pagep; + int ret; + + pginfo = (DB_PGINFO *)cookie->data; + env = dbenv->env; + pagep = (PAGE *)pp; + + memset(&dummydb, 0, sizeof(DB)); + dbp = &dummydb; + dbp->dbenv = dbenv; + dbp->env = env; + dbp->flags = pginfo->flags; + dbp->pgsize = pginfo->db_pagesize; + ret = 0; + switch (pagep->type) { + case P_INVALID: + if (pginfo->type == DB_QUEUE) + ret = __qam_pgin_out(env, pg, pp, cookie); + else + ret = __ham_pgout(dbp, pg, pp, cookie); + break; + case P_HASH: + case P_HASH_UNSORTED: + /* + * Support pgout of unsorted hash pages - since online + * replication upgrade can cause pages of this type to be + * written out. + * + * FALLTHROUGH + */ + case P_HASHMETA: + ret = __ham_pgout(dbp, pg, pp, cookie); + break; + case P_BTREEMETA: + case P_IBTREE: + case P_IRECNO: + case P_LBTREE: + case P_LDUP: + case P_LRECNO: + case P_OVERFLOW: + ret = __bam_pgout(dbp, pg, pp, cookie); + break; + case P_QAMMETA: + case P_QAMDATA: + ret = __qam_pgin_out(env, pg, pp, cookie); + break; + default: + return (__db_pgfmt(env, pg)); + } + if (ret) + return (ret); + + return (__db_encrypt_and_checksum_pg(env, dbp, pagep)); +} + +/* + * __db_decrypt_pg -- + * Utility function to decrypt a db page. + * + * PUBLIC: int __db_decrypt_pg __P((ENV *, DB *, PAGE *)); + */ +int +__db_decrypt_pg (env, dbp, pagep) + ENV *env; + DB *dbp; + PAGE *pagep; +{ + DB_CIPHER *db_cipher; + size_t pg_len, pg_off; + u_int8_t *iv; + int ret; + + db_cipher = env->crypto_handle; + ret = 0; + iv = NULL; + if (F_ISSET(dbp, DB_AM_ENCRYPT)) { + DB_ASSERT(env, db_cipher != NULL); + DB_ASSERT(env, F_ISSET(dbp, DB_AM_CHKSUM)); + + pg_off = P_OVERHEAD(dbp); + DB_ASSERT(env, db_cipher->adj_size(pg_off) == 0); + + switch (pagep->type) { + case P_HASHMETA: + case P_BTREEMETA: + case P_QAMMETA: + /* + * !!! + * For all meta pages it is required that the iv + * be at the same location. Use BTMETA to get to it + * for any meta type. + */ + iv = ((BTMETA *)pagep)->iv; + pg_len = DBMETASIZE; + break; + case P_INVALID: + if (IS_ZERO_LSN(LSN(pagep)) && + pagep->pgno == PGNO_INVALID) { + pg_len = 0; + break; + } + /* FALLTHROUGH */ + default: + iv = P_IV(dbp, pagep); + pg_len = dbp->pgsize; + break; + } + if (pg_len != 0) + ret = db_cipher->decrypt(env, db_cipher->data, + iv, ((u_int8_t *)pagep) + pg_off, + pg_len - pg_off); + } + return (ret); +} + +/* + * __db_encrypt_and_checksum_pg -- + * Utility function to encrypt and checksum a db page. + * + * PUBLIC: int __db_encrypt_and_checksum_pg + * PUBLIC: __P((ENV *, DB *, PAGE *)); + */ +int +__db_encrypt_and_checksum_pg (env, dbp, pagep) + ENV *env; + DB *dbp; + PAGE *pagep; +{ + DB_CIPHER *db_cipher; + int ret; + size_t pg_off, pg_len, sum_len; + u_int8_t *chksum, *iv, *key; + + chksum = iv = key = NULL; + db_cipher = env->crypto_handle; + + if (F_ISSET(dbp, DB_AM_ENCRYPT)) { + DB_ASSERT(env, db_cipher != NULL); + DB_ASSERT(env, F_ISSET(dbp, DB_AM_CHKSUM)); + + pg_off = P_OVERHEAD(dbp); + DB_ASSERT(env, db_cipher->adj_size(pg_off) == 0); + + key = db_cipher->mac_key; + + switch (pagep->type) { + case P_HASHMETA: + case P_BTREEMETA: + case P_QAMMETA: + /* + * !!! + * For all meta pages it is required that the iv + * be at the same location. Use BTMETA to get to it + * for any meta type. + */ + iv = ((BTMETA *)pagep)->iv; + pg_len = DBMETASIZE; + break; + default: + iv = P_IV(dbp, pagep); + pg_len = dbp->pgsize; + break; + } + if ((ret = db_cipher->encrypt(env, db_cipher->data, + iv, ((u_int8_t *)pagep) + pg_off, pg_len - pg_off)) != 0) + return (ret); + } + if (F_ISSET(dbp, DB_AM_CHKSUM)) { + switch (pagep->type) { + case P_HASHMETA: + case P_BTREEMETA: + case P_QAMMETA: + /* + * !!! + * For all meta pages it is required that the chksum + * be at the same location. Use BTMETA to get to it + * for any meta type. + */ + chksum = ((BTMETA *)pagep)->chksum; + sum_len = DBMETASIZE; + break; + default: + chksum = P_CHKSUM(dbp, pagep); + sum_len = dbp->pgsize; + break; + } + __db_chksum(NULL, (u_int8_t *)pagep, sum_len, key, chksum); + if (F_ISSET(dbp, DB_AM_SWAP) && !F_ISSET(dbp, DB_AM_ENCRYPT)) + P_32_SWAP(chksum); + } + return (0); +} + +/* + * __db_metaswap -- + * Byteswap the common part of the meta-data page. + * + * PUBLIC: void __db_metaswap __P((PAGE *)); + */ +void +__db_metaswap(pg) + PAGE *pg; +{ + u_int8_t *p; + + p = (u_int8_t *)pg; + + /* Swap the meta-data information. */ + SWAP32(p); /* lsn.file */ + SWAP32(p); /* lsn.offset */ + SWAP32(p); /* pgno */ + SWAP32(p); /* magic */ + SWAP32(p); /* version */ + SWAP32(p); /* pagesize */ + p += 4; /* unused, page type, unused, unused */ + SWAP32(p); /* free */ + SWAP32(p); /* alloc_lsn part 1 */ + SWAP32(p); /* alloc_lsn part 2 */ + SWAP32(p); /* cached key count */ + SWAP32(p); /* cached record count */ + SWAP32(p); /* flags */ +} + +/* + * __db_byteswap -- + * Byteswap an ordinary database page. + * + * PUBLIC: int __db_byteswap + * PUBLIC: __P((DB *, db_pgno_t, PAGE *, size_t, int)); + */ +int +__db_byteswap(dbp, pg, h, pagesize, pgin) + DB *dbp; + db_pgno_t pg; + PAGE *h; + size_t pagesize; + int pgin; +{ + ENV *env; + BINTERNAL *bi; + BKEYDATA *bk; + BOVERFLOW *bo; + RINTERNAL *ri; + db_indx_t i, *inp, len, tmp; + u_int8_t *end, *p, *pgend; + + if (pagesize == 0) + return (0); + + env = dbp->env; + + if (pgin) { + M_32_SWAP(h->lsn.file); + M_32_SWAP(h->lsn.offset); + M_32_SWAP(h->pgno); + M_32_SWAP(h->prev_pgno); + M_32_SWAP(h->next_pgno); + M_16_SWAP(h->entries); + M_16_SWAP(h->hf_offset); + } + + pgend = (u_int8_t *)h + pagesize; + + inp = P_INP(dbp, h); + if ((u_int8_t *)inp >= pgend) + goto out; + + switch (TYPE(h)) { + case P_HASH_UNSORTED: + case P_HASH: + for (i = 0; i < NUM_ENT(h); i++) { + if (pgin) + M_16_SWAP(inp[i]); + + if (P_ENTRY(dbp, h, i) >= pgend) + continue; + + switch (HPAGE_TYPE(dbp, h, i)) { + case H_KEYDATA: + break; + case H_DUPLICATE: + len = LEN_HKEYDATA(dbp, h, pagesize, i); + p = HKEYDATA_DATA(P_ENTRY(dbp, h, i)); + for (end = p + len; p < end;) { + if (pgin) { + P_16_SWAP(p); + memcpy(&tmp, + p, sizeof(db_indx_t)); + p += sizeof(db_indx_t); + } else { + memcpy(&tmp, + p, sizeof(db_indx_t)); + SWAP16(p); + } + p += tmp; + SWAP16(p); + } + break; + case H_OFFDUP: + p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i)); + SWAP32(p); /* pgno */ + break; + case H_OFFPAGE: + p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i)); + SWAP32(p); /* pgno */ + SWAP32(p); /* tlen */ + break; + default: + return (__db_pgfmt(env, pg)); + } + + } + + /* + * The offsets in the inp array are used to determine + * the size of entries on a page; therefore they + * cannot be converted until we've done all the + * entries. + */ + if (!pgin) + for (i = 0; i < NUM_ENT(h); i++) + M_16_SWAP(inp[i]); + break; + case P_LBTREE: + case P_LDUP: + case P_LRECNO: + for (i = 0; i < NUM_ENT(h); i++) { + if (pgin) + M_16_SWAP(inp[i]); + + /* + * In the case of on-page duplicates, key information + * should only be swapped once. + */ + if (h->type == P_LBTREE && i > 1) { + if (pgin) { + if (inp[i] == inp[i - 2]) + continue; + } else { + M_16_SWAP(inp[i]); + if (inp[i] == inp[i - 2]) + continue; + M_16_SWAP(inp[i]); + } + } + + bk = GET_BKEYDATA(dbp, h, i); + if ((u_int8_t *)bk >= pgend) + continue; + switch (B_TYPE(bk->type)) { + case B_KEYDATA: + M_16_SWAP(bk->len); + break; + case B_DUPLICATE: + case B_OVERFLOW: + bo = (BOVERFLOW *)bk; + M_32_SWAP(bo->pgno); + M_32_SWAP(bo->tlen); + break; + default: + return (__db_pgfmt(env, pg)); + } + + if (!pgin) + M_16_SWAP(inp[i]); + } + break; + case P_IBTREE: + for (i = 0; i < NUM_ENT(h); i++) { + if (pgin) + M_16_SWAP(inp[i]); + + bi = GET_BINTERNAL(dbp, h, i); + if ((u_int8_t *)bi >= pgend) + continue; + + M_16_SWAP(bi->len); + M_32_SWAP(bi->pgno); + M_32_SWAP(bi->nrecs); + + switch (B_TYPE(bi->type)) { + case B_KEYDATA: + break; + case B_DUPLICATE: + case B_OVERFLOW: + bo = (BOVERFLOW *)bi->data; + M_32_SWAP(bo->pgno); + M_32_SWAP(bo->tlen); + break; + default: + return (__db_pgfmt(env, pg)); + } + + if (!pgin) + M_16_SWAP(inp[i]); + } + break; + case P_IRECNO: + for (i = 0; i < NUM_ENT(h); i++) { + if (pgin) + M_16_SWAP(inp[i]); + + ri = GET_RINTERNAL(dbp, h, i); + if ((u_int8_t *)ri >= pgend) + continue; + + M_32_SWAP(ri->pgno); + M_32_SWAP(ri->nrecs); + + if (!pgin) + M_16_SWAP(inp[i]); + } + break; + case P_INVALID: + case P_OVERFLOW: + case P_QAMDATA: + /* Nothing to do. */ + break; + default: + return (__db_pgfmt(env, pg)); + } + +out: if (!pgin) { + /* Swap the header information. */ + M_32_SWAP(h->lsn.file); + M_32_SWAP(h->lsn.offset); + M_32_SWAP(h->pgno); + M_32_SWAP(h->prev_pgno); + M_32_SWAP(h->next_pgno); + M_16_SWAP(h->entries); + M_16_SWAP(h->hf_offset); + } + return (0); +} + +/* + * __db_pageswap -- + * Byteswap any database page. Normally, the page to be swapped will be + * referenced by the "pp" argument and the pdata argument will be NULL. + * This function is also called by automatically generated log functions, + * where the page may be split into separate header and data parts. In + * that case, pdata is not NULL we reconsitute + * + * PUBLIC: int __db_pageswap + * PUBLIC: __P((DB *, void *, size_t, DBT *, int)); + */ +int +__db_pageswap(dbp, pp, len, pdata, pgin) + DB *dbp; + void *pp; + size_t len; + DBT *pdata; + int pgin; +{ + ENV *env; + db_pgno_t pg; + size_t pgsize; + void *pgcopy; + int ret; + u_int16_t hoffset; + + env = dbp->env; + + switch (TYPE(pp)) { + case P_BTREEMETA: + return (__bam_mswap(env, pp)); + + case P_HASHMETA: + return (__ham_mswap(env, pp)); + + case P_QAMMETA: + return (__qam_mswap(env, pp)); + + case P_INVALID: + case P_OVERFLOW: + case P_QAMDATA: + /* + * We may have been passed an invalid page, or a queue data + * page, or an overflow page where fields like hoffset have a + * special meaning. In that case, no swapping of the page data + * is required, just the fields in the page header. + */ + pdata = NULL; + break; + + default: + break; + } + + if (pgin) { + P_32_COPYSWAP(&PGNO(pp), &pg); + P_16_COPYSWAP(&HOFFSET(pp), &hoffset); + } else { + pg = PGNO(pp); + hoffset = HOFFSET(pp); + } + + if (pdata == NULL) + ret = __db_byteswap(dbp, pg, (PAGE *)pp, len, pgin); + else { + pgsize = hoffset + pdata->size; + if ((ret = __os_malloc(env, pgsize, &pgcopy)) != 0) + return (ret); + memset(pgcopy, 0, pgsize); + memcpy(pgcopy, pp, len); + memcpy((u_int8_t *)pgcopy + hoffset, pdata->data, pdata->size); + + ret = __db_byteswap(dbp, pg, (PAGE *)pgcopy, pgsize, pgin); + memcpy(pp, pgcopy, len); + + /* + * If we are swapping data to be written to the log, we can't + * overwrite the buffer that was passed in: it may be a pointer + * into a page in cache. We set DB_DBT_APPMALLOC here so that + * the calling code can free the memory we allocate here. + */ + if (!pgin) { + if ((ret = + __os_malloc(env, pdata->size, &pdata->data)) != 0) { + __os_free(env, pgcopy); + return (ret); + } + F_SET(pdata, DB_DBT_APPMALLOC); + } + memcpy(pdata->data, (u_int8_t *)pgcopy + hoffset, pdata->size); + __os_free(env, pgcopy); + } + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_dispatch.c b/src/libs/resiprocate/contrib/db/db/db_dispatch.c new file mode 100644 index 00000000..65dc260d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_dispatch.c @@ -0,0 +1,953 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1995, 1996 + * The President and Fellows of Harvard University. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/hash.h" +#include "dbinc/fop.h" +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/txn.h" + +static int __db_txnlist_find_internal __P((ENV *, DB_TXNHEAD *, + db_txnlist_type, u_int32_t, DB_TXNLIST **, + int, u_int32_t *)); + +/* + * __db_dispatch -- + * + * This is the transaction dispatch function used by the db access methods. + * It is designed to handle the record format used by all the access + * methods (the one automatically generated by the db_{h,log,read}.sh + * scripts in the tools directory). An application using a different + * recovery paradigm will supply a different dispatch function to txn_open. + * + * PUBLIC: int __db_dispatch __P((ENV *, + * PUBLIC: DB_DISTAB *, DBT *, DB_LSN *, db_recops, DB_TXNHEAD *)); + */ +int +__db_dispatch(env, dtab, db, lsnp, redo, info) + ENV *env; /* The environment. */ + DB_DISTAB *dtab; + DBT *db; /* The log record upon which to dispatch. */ + DB_LSN *lsnp; /* The lsn of the record being dispatched. */ + db_recops redo; /* Redo this op (or undo it). */ + DB_TXNHEAD *info; /* Transaction list. */ +{ + DB_ENV *dbenv; + DB_LSN prev_lsn; + u_int32_t rectype, status, txnid, urectype; + int make_call, ret; + + dbenv = env->dbenv; + LOGCOPY_32(env, &rectype, db->data); + LOGCOPY_32(env, &txnid, (u_int8_t *)db->data + sizeof(rectype)); + + make_call = ret = 0; + + /* If we don't have a dispatch table, it's hard to dispatch. */ + DB_ASSERT(env, dtab != NULL); + + /* + * If we find a record that is in the user's number space and they + * have specified a recovery routine, let them handle it. If they + * didn't specify a recovery routine, then we expect that they've + * followed all our rules and registered new recovery functions. + */ + switch (redo) { + case DB_TXN_ABORT: + case DB_TXN_APPLY: + case DB_TXN_PRINT: + make_call = 1; + break; + case DB_TXN_OPENFILES: + /* + * We collect all the transactions that have + * "begin" records, those with no previous LSN, + * so that we do not abort partial transactions. + * These are known to be undone, otherwise the + * log would not have been freeable. + */ + LOGCOPY_TOLSN(env, &prev_lsn, (u_int8_t *)db->data + + sizeof(rectype) + sizeof(txnid)); + if (txnid != 0 && prev_lsn.file == 0 && (ret = + __db_txnlist_add(env, info, txnid, TXN_OK, NULL)) != 0) + return (ret); + + /* FALLTHROUGH */ + case DB_TXN_POPENFILES: + if (rectype == DB___dbreg_register || + rectype == DB___txn_child || + rectype == DB___txn_ckp || rectype == DB___txn_recycle) + return ((dtab->int_dispatch[rectype])(env, + db, lsnp, redo, info)); + break; + case DB_TXN_BACKWARD_ROLL: + /* + * Running full recovery in the backward pass. In general, + * we only process records during this pass that belong + * to aborted transactions. Unfortunately, there are several + * exceptions: + * 1. If this is a meta-record, one not associated with + * a transaction, then we must always process it. + * 2. If this is a transaction commit/abort, we must + * always process it, so that we know the status of + * every transaction. + * 3. If this is a child commit, we need to process it + * because the outcome of the child transaction depends + * on the outcome of the parent. + * 4. If this is a dbreg_register record, we must always + * process is because they contain non-transactional + * closes that must be properly handled. + * 5. If this is a noop, we must always undo it so that we + * properly handle any aborts before a file was closed. + * 6. If this a file remove, we need to process it to + * determine if the on-disk file is the same as the + * one being described. + */ + switch (rectype) { + /* + * These either do not belong to a transaction or (regop) + * must be processed regardless of the status of the + * transaction. + */ + case DB___txn_regop: + case DB___txn_recycle: + case DB___txn_ckp: + make_call = 1; + break; + /* + * These belong to a transaction whose status must be + * checked. + */ + case DB___txn_child: + case DB___db_noop: + case DB___fop_file_remove: + case DB___dbreg_register: + make_call = 1; + + /* FALLTHROUGH */ + default: + if (txnid == 0) + break; + + ret = __db_txnlist_find(env, info, txnid, &status); + + /* If not found, this is an incomplete abort. */ + if (ret == DB_NOTFOUND) + return (__db_txnlist_add(env, + info, txnid, TXN_IGNORE, lsnp)); + if (ret != 0) + return (ret); + + /* + * If we ignore the transaction, ignore the operation + * UNLESS this is a child commit in which case we need + * to make sure that the child also gets marked as + * ignore. + */ + if (status == TXN_IGNORE && rectype != DB___txn_child) { + make_call = 0; + break; + } + if (status == TXN_COMMIT) + break; + + /* Set make_call in case we came through default */ + make_call = 1; + if (status == TXN_OK && + (ret = __db_txnlist_update(env, + info, txnid, rectype == DB___txn_prepare ? + TXN_PREPARE : TXN_ABORT, NULL, &status, 0)) != 0) + return (ret); + } + break; + case DB_TXN_FORWARD_ROLL: + /* + * In the forward pass, if we haven't seen the transaction, + * do nothing, else recover it. + * + * We need to always redo DB___db_noop records, so that we + * properly handle any commits after the file was closed. + */ + switch (rectype) { + case DB___txn_recycle: + case DB___txn_ckp: + case DB___db_noop: + case DB___dbreg_register: + make_call = 1; + break; + + default: + if (txnid == 0) + status = 0; + else { + ret = __db_txnlist_find(env, + info, txnid, &status); + + if (ret == DB_NOTFOUND) + /* Break out out of if clause. */ + ; + else if (ret != 0) + return (ret); + else if (status == TXN_COMMIT) { + make_call = 1; + break; + } + } + + } + break; + default: + return (__db_unknown_flag( + env, "__db_dispatch", (u_int32_t)redo)); + } + + if (make_call) { + /* + * If the debug flag is set then we are logging + * records for a non-durable update so that they + * may be examined for diagnostic purposes. + * So only make the call if we are printing, + * otherwise we need to extract the previous + * lsn so undo will work properly. + */ + if (rectype & DB_debug_FLAG) { + if (redo == DB_TXN_PRINT) + rectype &= ~DB_debug_FLAG; + else { + LOGCOPY_TOLSN(env, lsnp, + (u_int8_t *)db->data + + sizeof(rectype) + + sizeof(txnid)); + return (0); + } + } + if (rectype >= DB_user_BEGIN) { + if (dbenv->app_dispatch != NULL) + return (dbenv->app_dispatch(dbenv, + db, lsnp, redo)); + + /* No application-specific dispatch */ + urectype = rectype - DB_user_BEGIN; + if (urectype > dtab->ext_size || + dtab->ext_dispatch[urectype] == NULL) { + __db_errx(env, + "Illegal application-specific record type %lu in log", + (u_long)rectype); + return (EINVAL); + } + return ((dtab->ext_dispatch[urectype])(dbenv, + db, lsnp, redo)); + } else { + if (rectype > dtab->int_size || + dtab->int_dispatch[rectype] == NULL) { + __db_errx(env, + "Illegal record type %lu in log", + (u_long)rectype); + return (EINVAL); + } + return ((dtab->int_dispatch[rectype])(env, + db, lsnp, redo, info)); + } + } + + return (0); +} + +/* + * __db_add_recovery -- Add recovery functions to the dispatch table. + * + * We have two versions of this, an external one and an internal one, + * because application-specific functions take different arguments + * for dispatch (ENV versus DB_ENV). + * + * This is the external version. + * + * PUBLIC: int __db_add_recovery __P((DB_ENV *, DB_DISTAB *, + * PUBLIC: int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops), u_int32_t)); + */ +int +__db_add_recovery(dbenv, dtab, func, ndx) + DB_ENV *dbenv; + DB_DISTAB *dtab; + int (*func) __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); + u_int32_t ndx; +{ + size_t i, nsize; + int ret; + + /* Make sure this is an application-specific record. */ + if (ndx < DB_user_BEGIN) { + __db_errx(dbenv->env, + "Attempting to add application-specific record with invalid type %lu", + (u_long)ndx); + return (EINVAL); + } + ndx -= DB_user_BEGIN; + + /* Check if we have to grow the table. */ + if (ndx >= dtab->ext_size) { + nsize = ndx + 40; + if ((ret = + __os_realloc(dbenv->env, nsize * + sizeof((dtab->ext_dispatch)[0]), &dtab->ext_dispatch)) + != 0) + return (ret); + for (i = dtab->ext_size; i < nsize; ++i) + (dtab->ext_dispatch)[i] = NULL; + dtab->ext_size = nsize; + } + + (dtab->ext_dispatch)[ndx] = func; + return (0); +} + +/* + * __db_add_recovery_int -- + * + * Internal version of dispatch addition function. + * + * + * PUBLIC: int __db_add_recovery_int __P((ENV *, DB_DISTAB *, + * PUBLIC: int (*)(ENV *, DBT *, DB_LSN *, db_recops, void *), u_int32_t)); + */ +int +__db_add_recovery_int(env, dtab, func, ndx) + ENV *env; + DB_DISTAB *dtab; + int (*func) __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + u_int32_t ndx; +{ + size_t i, nsize; + int ret; + + if (ndx >= DB_user_BEGIN) { + __db_errx(env, + "Attempting to add internal record with invalid type %lu", + (u_long)ndx); + return (EINVAL); + } + + /* Check if we have to grow the table. */ + if (ndx >= dtab->int_size) { + nsize = ndx + 40; + if ((ret = + __os_realloc(env, nsize * sizeof((dtab->int_dispatch)[0]), + &dtab->int_dispatch)) != 0) + return (ret); + for (i = dtab->int_size; i < nsize; ++i) + (dtab->int_dispatch)[i] = NULL; + dtab->int_size = nsize; + } + + (dtab->int_dispatch)[ndx] = func; + return (0); +} + +/* + * __db_txnlist_init -- + * Initialize transaction linked list. + * + * PUBLIC: int __db_txnlist_init __P((ENV *, DB_THREAD_INFO *, + * PUBLIC: u_int32_t, u_int32_t, DB_LSN *, DB_TXNHEAD **)); + */ +int +__db_txnlist_init(env, ip, low_txn, hi_txn, trunc_lsn, retp) + ENV *env; + DB_THREAD_INFO *ip; + u_int32_t low_txn, hi_txn; + DB_LSN *trunc_lsn; + DB_TXNHEAD **retp; +{ + DB_TXNHEAD *headp; + u_int32_t size, tmp; + int ret; + + /* + * Size a hash table. + * If low is zero then we are being called during rollback + * and we need only one slot. + * Hi maybe lower than low if we have recycled txnid's. + * The numbers here are guesses about txn density, we can afford + * to look at a few entries in each slot. + */ + if (low_txn == 0) + size = 1; + else { + if (hi_txn < low_txn) { + tmp = hi_txn; + hi_txn = low_txn; + low_txn = tmp; + } + tmp = hi_txn - low_txn; + /* See if we wrapped around. */ + if (tmp > (TXN_MAXIMUM - TXN_MINIMUM) / 2) + tmp = (low_txn - TXN_MINIMUM) + (TXN_MAXIMUM - hi_txn); + size = tmp / 5; + if (size < 100) + size = 100; + } + if ((ret = __os_malloc(env, + sizeof(DB_TXNHEAD) + size * sizeof(headp->head), &headp)) != 0) + return (ret); + + memset(headp, 0, sizeof(DB_TXNHEAD) + size * sizeof(headp->head)); + headp->maxid = hi_txn; + headp->generation = 0; + headp->nslots = size; + headp->gen_alloc = 8; + headp->thread_info = ip; + if ((ret = __os_malloc(env, headp->gen_alloc * + sizeof(headp->gen_array[0]), &headp->gen_array)) != 0) { + __os_free(env, headp); + return (ret); + } + headp->gen_array[0].generation = 0; + headp->gen_array[0].txn_min = TXN_MINIMUM; + headp->gen_array[0].txn_max = TXN_MAXIMUM; + if (trunc_lsn != NULL) { + headp->trunc_lsn = *trunc_lsn; + headp->maxlsn = *trunc_lsn; + } else { + ZERO_LSN(headp->trunc_lsn); + ZERO_LSN(headp->maxlsn); + } + ZERO_LSN(headp->ckplsn); + + *retp = headp; + return (0); +} + +#define FIND_GENERATION(hp, txnid, gen) do { \ + u_int32_t __i; \ + for (__i = 0; __i <= (hp)->generation; __i++) \ + /* The range may wrap around the end. */ \ + if ((hp)->gen_array[__i].txn_min < \ + (hp)->gen_array[__i].txn_max ? \ + ((txnid) >= (hp)->gen_array[__i].txn_min && \ + (txnid) <= (hp)->gen_array[__i].txn_max) : \ + ((txnid) >= (hp)->gen_array[__i].txn_min || \ + (txnid) <= (hp)->gen_array[__i].txn_max)) \ + break; \ + DB_ASSERT(env, __i <= (hp)->generation); \ + gen = (hp)->gen_array[__i].generation; \ +} while (0) + +/* + * __db_txnlist_add -- + * Add an element to our transaction linked list. + * + * PUBLIC: int __db_txnlist_add __P((ENV *, + * PUBLIC: DB_TXNHEAD *, u_int32_t, u_int32_t, DB_LSN *)); + */ +int +__db_txnlist_add(env, hp, txnid, status, lsn) + ENV *env; + DB_TXNHEAD *hp; + u_int32_t txnid, status; + DB_LSN *lsn; +{ + DB_TXNLIST *elp; + int ret; + + if ((ret = __os_malloc(env, sizeof(DB_TXNLIST), &elp)) != 0) + return (ret); + + LIST_INSERT_HEAD(&hp->head[DB_TXNLIST_MASK(hp, txnid)], elp, links); + + /* Find the most recent generation containing this ID */ + FIND_GENERATION(hp, txnid, elp->u.t.generation); + elp->type = TXNLIST_TXNID; + elp->u.t.txnid = txnid; + elp->u.t.status = status; + if (txnid > hp->maxid) + hp->maxid = txnid; + if (lsn != NULL && IS_ZERO_LSN(hp->maxlsn) && status == TXN_COMMIT) + hp->maxlsn = *lsn; + + DB_ASSERT(env, lsn == NULL || + status != TXN_COMMIT || LOG_COMPARE(&hp->maxlsn, lsn) >= 0); + + return (0); +} + +/* + * __db_txnlist_remove -- + * Remove an element from our transaction linked list. + * + * PUBLIC: int __db_txnlist_remove __P((ENV *, DB_TXNHEAD *, u_int32_t)); + */ +int +__db_txnlist_remove(env, hp, txnid) + ENV *env; + DB_TXNHEAD *hp; + u_int32_t txnid; +{ + DB_TXNLIST *entry; + u_int32_t status; + + return (__db_txnlist_find_internal(env, + hp, TXNLIST_TXNID, txnid, &entry, 1, &status)); +} + +/* + * __db_txnlist_ckp -- + * Used to record the maximum checkpoint that will be retained + * after recovery. Typically this is simply the max checkpoint, but + * if we are doing client replication recovery or timestamp-based + * recovery, we are going to virtually truncate the log and we need + * to retain the last checkpoint before the truncation point. + * + * PUBLIC: void __db_txnlist_ckp __P((ENV *, DB_TXNHEAD *, DB_LSN *)); + */ +void +__db_txnlist_ckp(env, hp, ckp_lsn) + ENV *env; + DB_TXNHEAD *hp; + DB_LSN *ckp_lsn; +{ + + COMPQUIET(env, NULL); + + if (IS_ZERO_LSN(hp->ckplsn) && !IS_ZERO_LSN(hp->maxlsn) && + LOG_COMPARE(&hp->maxlsn, ckp_lsn) >= 0) + hp->ckplsn = *ckp_lsn; +} + +/* + * __db_txnlist_end -- + * Discard transaction linked list. + * + * PUBLIC: void __db_txnlist_end __P((ENV *, DB_TXNHEAD *)); + */ +void +__db_txnlist_end(env, hp) + ENV *env; + DB_TXNHEAD *hp; +{ + u_int32_t i; + DB_TXNLIST *p; + + if (hp == NULL) + return; + + for (i = 0; i < hp->nslots; i++) + while (hp != NULL && (p = LIST_FIRST(&hp->head[i])) != NULL) { + switch (p->type) { + case TXNLIST_LSN: + __os_free(env, p->u.l.lsn_stack); + break; + case TXNLIST_DELETE: + case TXNLIST_TXNID: + default: + /* + * Possibly an incomplete DB_TXNLIST; just + * free it. + */ + break; + } + LIST_REMOVE(p, links); + __os_free(env, p); + } + + if (hp->gen_array != NULL) + __os_free(env, hp->gen_array); + __os_free(env, hp); +} + +/* + * __db_txnlist_find -- + * Checks to see if a txnid with the current generation is in the + * txnid list. This returns DB_NOTFOUND if the item isn't in the + * list otherwise it returns (like __db_txnlist_find_internal) + * the status of the transaction. A txnid of 0 means the record + * was generated while not in a transaction. + * + * PUBLIC: int __db_txnlist_find __P((ENV *, + * PUBLIC: DB_TXNHEAD *, u_int32_t, u_int32_t *)); + */ +int +__db_txnlist_find(env, hp, txnid, statusp) + ENV *env; + DB_TXNHEAD *hp; + u_int32_t txnid, *statusp; +{ + DB_TXNLIST *entry; + + if (txnid == 0) + return (DB_NOTFOUND); + + return (__db_txnlist_find_internal(env, hp, + TXNLIST_TXNID, txnid, &entry, 0, statusp)); +} + +/* + * __db_txnlist_update -- + * Change the status of an existing transaction entry. + * Returns DB_NOTFOUND if no such entry exists. + * + * PUBLIC: int __db_txnlist_update __P((ENV *, DB_TXNHEAD *, + * PUBLIC: u_int32_t, u_int32_t, DB_LSN *, u_int32_t *, int)); + */ +int +__db_txnlist_update(env, hp, txnid, status, lsn, ret_status, add_ok) + ENV *env; + DB_TXNHEAD *hp; + u_int32_t txnid, status; + DB_LSN *lsn; + u_int32_t *ret_status; + int add_ok; +{ + DB_TXNLIST *elp; + int ret; + + if (txnid == 0) + return (DB_NOTFOUND); + + ret = __db_txnlist_find_internal(env, + hp, TXNLIST_TXNID, txnid, &elp, 0, ret_status); + + if (ret == DB_NOTFOUND && add_ok) { + *ret_status = status; + return (__db_txnlist_add(env, hp, txnid, status, lsn)); + } + if (ret != 0) + return (ret); + + if (*ret_status == TXN_IGNORE) + return (0); + + elp->u.t.status = status; + + if (lsn != NULL && IS_ZERO_LSN(hp->maxlsn) && status == TXN_COMMIT) + hp->maxlsn = *lsn; + + return (ret); +} + +/* + * __db_txnlist_find_internal -- + * Find an entry on the transaction list. If the entry is not there or + * the list pointer is not initialized we return DB_NOTFOUND. If the + * item is found, we return the status. Currently we always call this + * with an initialized list pointer but checking for NULL keeps it general. + */ +static int +__db_txnlist_find_internal(env, + hp, type, txnid, txnlistp, delete, statusp) + ENV *env; + DB_TXNHEAD *hp; + db_txnlist_type type; + u_int32_t txnid; + DB_TXNLIST **txnlistp; + int delete; + u_int32_t *statusp; +{ + struct __db_headlink *head; + DB_TXNLIST *p; + u_int32_t generation, hash; + int ret; + + ret = 0; + + if (hp == NULL) + return (DB_NOTFOUND); + + switch (type) { + case TXNLIST_TXNID: + hash = txnid; + FIND_GENERATION(hp, txnid, generation); + break; + case TXNLIST_DELETE: + case TXNLIST_LSN: + default: + return (__env_panic(env, EINVAL)); + } + + head = &hp->head[DB_TXNLIST_MASK(hp, hash)]; + LIST_FOREACH(p, head, links) { + if (p->type != type) + continue; + switch (type) { + case TXNLIST_TXNID: + if (p->u.t.txnid != txnid || + generation != p->u.t.generation) + continue; + *statusp = p->u.t.status; + break; + + case TXNLIST_DELETE: + case TXNLIST_LSN: + default: + return (__env_panic(env, EINVAL)); + } + if (delete == 1) { + LIST_REMOVE(p, links); + __os_free(env, p); + *txnlistp = NULL; + } else if (p != LIST_FIRST(head)) { + /* Move it to head of list. */ + LIST_REMOVE(p, links); + LIST_INSERT_HEAD(head, p, links); + *txnlistp = p; + } else + *txnlistp = p; + return (ret); + } + + return (DB_NOTFOUND); +} + +/* + * __db_txnlist_gen -- + * Change the current generation number. + * + * PUBLIC: int __db_txnlist_gen __P((ENV *, + * PUBLIC: DB_TXNHEAD *, int, u_int32_t, u_int32_t)); + */ +int +__db_txnlist_gen(env, hp, incr, min, max) + ENV *env; + DB_TXNHEAD *hp; + int incr; + u_int32_t min, max; +{ + int ret; + + /* + * During recovery generation numbers keep track of "restart" + * checkpoints and recycle records. Restart checkpoints occur + * whenever we take a checkpoint and there are no outstanding + * transactions. When that happens, we can reset transaction IDs + * back to TXNID_MINIMUM. Currently we only do the reset + * at then end of recovery. Recycle records occur when txnids + * are exhausted during runtime. A free range of ids is identified + * and logged. This code maintains a stack of ranges. A txnid + * is given the generation number of the first range it falls into + * in the stack. + */ + if (incr < 0) { + --hp->generation; + memmove(hp->gen_array, &hp->gen_array[1], + (hp->generation + 1) * sizeof(hp->gen_array[0])); + } else { + ++hp->generation; + if (hp->generation >= hp->gen_alloc) { + hp->gen_alloc *= 2; + if ((ret = __os_realloc(env, hp->gen_alloc * + sizeof(hp->gen_array[0]), &hp->gen_array)) != 0) + return (ret); + } + memmove(&hp->gen_array[1], &hp->gen_array[0], + hp->generation * sizeof(hp->gen_array[0])); + hp->gen_array[0].generation = hp->generation; + hp->gen_array[0].txn_min = min; + hp->gen_array[0].txn_max = max; + } + return (0); +} + +/* + * __db_txnlist_lsnadd -- + * Save the prev_lsn from a txn_child record. + * + * PUBLIC: int __db_txnlist_lsnadd __P((ENV *, DB_TXNHEAD *, DB_LSN *)); + */ +int +__db_txnlist_lsnadd(env, hp, lsnp) + ENV *env; + DB_TXNHEAD *hp; + DB_LSN *lsnp; +{ + DB_TXNLIST *elp; + int ret; + + if (IS_ZERO_LSN(*lsnp)) + return (0); + + LIST_FOREACH(elp, &hp->head[0], links) + if (elp->type == TXNLIST_LSN) + break; + + if (elp == NULL) { + if ((ret = __db_txnlist_lsninit(env, hp, lsnp)) != 0) + return (ret); + return (DB_SURPRISE_KID); + } + + if (elp->u.l.stack_indx == elp->u.l.stack_size) { + elp->u.l.stack_size <<= 1; + if ((ret = __os_realloc(env, sizeof(DB_LSN) * + elp->u.l.stack_size, &elp->u.l.lsn_stack)) != 0) { + __db_txnlist_end(env, hp); + return (ret); + } + } + elp->u.l.lsn_stack[elp->u.l.stack_indx++] = *lsnp; + + return (0); +} + +/* + * __db_txnlist_lsnget -- + * + * PUBLIC: int __db_txnlist_lsnget __P((ENV *, + * PUBLIC: DB_TXNHEAD *, DB_LSN *, u_int32_t)); + * Get the lsn saved from a txn_child record. + */ +int +__db_txnlist_lsnget(env, hp, lsnp, flags) + ENV *env; + DB_TXNHEAD *hp; + DB_LSN *lsnp; + u_int32_t flags; +{ + DB_TXNLIST *elp; + + COMPQUIET(env, NULL); + COMPQUIET(flags, 0); + + LIST_FOREACH(elp, &hp->head[0], links) + if (elp->type == TXNLIST_LSN) + break; + + if (elp == NULL || elp->u.l.stack_indx == 0) { + ZERO_LSN(*lsnp); + return (0); + } + + *lsnp = elp->u.l.lsn_stack[--elp->u.l.stack_indx]; + + return (0); +} + +/* + * __db_txnlist_lsninit -- + * Initialize a transaction list with an lsn array entry. + * + * PUBLIC: int __db_txnlist_lsninit __P((ENV *, DB_TXNHEAD *, DB_LSN *)); + */ +int +__db_txnlist_lsninit(env, hp, lsnp) + ENV *env; + DB_TXNHEAD *hp; + DB_LSN *lsnp; +{ + DB_TXNLIST *elp; + int ret; + + elp = NULL; + + if ((ret = __os_malloc(env, sizeof(DB_TXNLIST), &elp)) != 0) + goto err; + LIST_INSERT_HEAD(&hp->head[0], elp, links); + + elp->type = TXNLIST_LSN; + if ((ret = __os_malloc(env, + sizeof(DB_LSN) * DB_LSN_STACK_SIZE, &elp->u.l.lsn_stack)) != 0) + goto err; + elp->u.l.stack_indx = 1; + elp->u.l.stack_size = DB_LSN_STACK_SIZE; + elp->u.l.lsn_stack[0] = *lsnp; + + return (0); + +err: __db_txnlist_end(env, hp); + return (ret); +} + +#ifdef DEBUG +/* + * __db_txnlist_print -- + * Print out the transaction list. + * + * PUBLIC: void __db_txnlist_print __P((DB_TXNHEAD *)); + */ +void +__db_txnlist_print(hp) + DB_TXNHEAD *hp; +{ + DB_TXNLIST *p; + u_int32_t i; + char *txntype; + + printf("Maxid: %lu Generation: %lu\n", + (u_long)hp->maxid, (u_long)hp->generation); + for (i = 0; i < hp->nslots; i++) + LIST_FOREACH(p, &hp->head[i], links) { + if (p->type != TXNLIST_TXNID) { + printf("Unrecognized type: %d\n", p->type); + continue; + } + switch (p->u.t.status) { + case TXN_OK: + txntype = "OK"; + break; + case TXN_COMMIT: + txntype = "commit"; + break; + case TXN_PREPARE: + txntype = "prepare"; + break; + case TXN_ABORT: + txntype = "abort"; + break; + case TXN_IGNORE: + txntype = "ignore"; + break; + case TXN_EXPECTED: + txntype = "expected"; + break; + case TXN_UNEXPECTED: + txntype = "unexpected"; + break; + default: + txntype = "UNKNOWN"; + break; + } + printf("TXNID: %lx(%lu): %s\n", + (u_long)p->u.t.txnid, + (u_long)p->u.t.generation, txntype); + } +} +#endif diff --git a/src/libs/resiprocate/contrib/db/db/db_dup.c b/src/libs/resiprocate/contrib/db/db/db_dup.c new file mode 100644 index 00000000..b789e036 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_dup.c @@ -0,0 +1,203 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/mp.h" +#include "dbinc/db_am.h" + +/* + * __db_ditem_nolog -- + * Remove an item from a page without affecting its recoverability. + * + * PUBLIC: int __db_ditem_nolog __P((DBC *, PAGE *, u_int32_t, u_int32_t)); + */ +int +__db_ditem_nolog(dbc, pagep, indx, nbytes) + DBC *dbc; + PAGE *pagep; + u_int32_t indx, nbytes; +{ + DB *dbp; + db_indx_t cnt, *inp, offset; + u_int8_t *from; + + dbp = dbc->dbp; + DB_ASSERT(dbp->env, IS_DIRTY(pagep)); + DB_ASSERT(dbp->env, indx < NUM_ENT(pagep)); + + /* + * If there's only a single item on the page, we don't have to + * work hard. + */ + if (NUM_ENT(pagep) == 1) { + NUM_ENT(pagep) = 0; + HOFFSET(pagep) = dbp->pgsize; + return (0); + } + + inp = P_INP(dbp, pagep); + /* + * Pack the remaining key/data items at the end of the page. Use + * memmove(3), the regions may overlap. + */ + from = (u_int8_t *)pagep + HOFFSET(pagep); + DB_ASSERT(dbp->env, inp[indx] >= HOFFSET(pagep)); + memmove(from + nbytes, from, inp[indx] - HOFFSET(pagep)); + HOFFSET(pagep) += nbytes; + + /* Adjust the indices' offsets. */ + offset = inp[indx]; + for (cnt = 0; cnt < NUM_ENT(pagep); ++cnt) + if (inp[cnt] < offset) + inp[cnt] += nbytes; + + /* Shift the indices down. */ + --NUM_ENT(pagep); + if (indx != NUM_ENT(pagep)) + memmove(&inp[indx], &inp[indx + 1], + sizeof(db_indx_t) * (NUM_ENT(pagep) - indx)); + + return (0); +} + +/* + * __db_ditem -- + * Remove an item from a page, logging it if enabled. + * + * PUBLIC: int __db_ditem __P((DBC *, PAGE *, u_int32_t, u_int32_t)); + */ +int +__db_ditem(dbc, pagep, indx, nbytes) + DBC *dbc; + PAGE *pagep; + u_int32_t indx, nbytes; +{ + DB *dbp; + DBT ldbt; + int ret; + + dbp = dbc->dbp; + + if (DBC_LOGGING(dbc)) { + ldbt.data = P_ENTRY(dbp, pagep, indx); + ldbt.size = nbytes; + if ((ret = __db_addrem_log(dbp, dbc->txn, + &LSN(pagep), 0, DB_REM_DUP, PGNO(pagep), + (u_int32_t)indx, nbytes, &ldbt, NULL, &LSN(pagep))) != 0) + return (ret); + } else + LSN_NOT_LOGGED(LSN(pagep)); + + return (__db_ditem_nolog(dbc, pagep, indx, nbytes)); +} + +/* + * __db_pitem_nolog -- + * Put an item on a page without logging. + * + * PUBLIC: int __db_pitem_nolog + * PUBLIC: __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *)); + */ +int +__db_pitem_nolog(dbc, pagep, indx, nbytes, hdr, data) + DBC *dbc; + PAGE *pagep; + u_int32_t indx; + u_int32_t nbytes; + DBT *hdr, *data; +{ + BKEYDATA bk; + DB *dbp; + DBT thdr; + db_indx_t *inp; + u_int8_t *p; + + dbp = dbc->dbp; + + DB_ASSERT(dbp->env, IS_DIRTY(pagep)); + + if (nbytes > P_FREESPACE(dbp, pagep)) { + DB_ASSERT(dbp->env, nbytes <= P_FREESPACE(dbp, pagep)); + return (EINVAL); + } + + if (hdr == NULL) { + B_TSET(bk.type, B_KEYDATA); + bk.len = data == NULL ? 0 : data->size; + + thdr.data = &bk; + thdr.size = SSZA(BKEYDATA, data); + hdr = &thdr; + } + inp = P_INP(dbp, pagep); + + /* Adjust the index table, then put the item on the page. */ + if (indx != NUM_ENT(pagep)) + memmove(&inp[indx + 1], &inp[indx], + sizeof(db_indx_t) * (NUM_ENT(pagep) - indx)); + HOFFSET(pagep) -= nbytes; + inp[indx] = HOFFSET(pagep); + ++NUM_ENT(pagep); + + p = P_ENTRY(dbp, pagep, indx); + memcpy(p, hdr->data, hdr->size); + if (data != NULL) + memcpy(p + hdr->size, data->data, data->size); + + return (0); +} + +/* + * __db_pitem -- + * Put an item on a page. + * + * PUBLIC: int __db_pitem + * PUBLIC: __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *)); + */ +int +__db_pitem(dbc, pagep, indx, nbytes, hdr, data) + DBC *dbc; + PAGE *pagep; + u_int32_t indx; + u_int32_t nbytes; + DBT *hdr, *data; +{ + DB *dbp; + int ret; + + dbp = dbc->dbp; + /* + * Put a single item onto a page. The logic figuring out where to + * insert and whether it fits is handled in the caller. All we do + * here is manage the page shuffling. We cheat a little bit in that + * we don't want to copy the dbt on a normal put twice. If hdr is + * NULL, we create a BKEYDATA structure on the page, otherwise, just + * copy the caller's information onto the page. + * + * This routine is also used to put entries onto the page where the + * entry is pre-built, e.g., during recovery. In this case, the hdr + * will point to the entry, and the data argument will be NULL. + * + * !!! + * There's a tremendous potential for off-by-one errors here, since + * the passed in header sizes must be adjusted for the structure's + * placeholder for the trailing variable-length data field. + */ + if (DBC_LOGGING(dbc)) { + if ((ret = __db_addrem_log(dbp, dbc->txn, + &LSN(pagep), 0, DB_ADD_DUP, PGNO(pagep), + (u_int32_t)indx, nbytes, hdr, data, &LSN(pagep))) != 0) + return (ret); + } else + LSN_NOT_LOGGED(LSN(pagep)); + + return (__db_pitem_nolog(dbc, pagep, indx, nbytes, hdr, data)); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_iface.c b/src/libs/resiprocate/contrib/db/db/db_iface.c new file mode 100644 index 00000000..55f3e2a6 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_iface.c @@ -0,0 +1,2817 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/hash.h" +#ifndef HAVE_QUEUE +#include "dbinc/qam.h" /* For __db_no_queue_am(). */ +#endif +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/partition.h" +#include "dbinc/txn.h" + +static int __db_associate_arg __P((DB *, DB *, + int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); +static int __dbc_del_arg __P((DBC *, u_int32_t)); +static int __dbc_pget_arg __P((DBC *, DBT *, u_int32_t)); +static int __dbc_put_arg __P((DBC *, DBT *, DBT *, u_int32_t)); +static int __db_curinval __P((const ENV *)); +static int __db_cursor_arg __P((DB *, u_int32_t)); +static int __db_del_arg __P((DB *, DBT *, u_int32_t)); +static int __db_get_arg __P((const DB *, DBT *, DBT *, u_int32_t)); +static int __db_join_arg __P((DB *, DBC **, u_int32_t)); +static int __db_open_arg __P((DB *, + DB_TXN *, const char *, const char *, DBTYPE, u_int32_t)); +static int __db_pget_arg __P((DB *, DBT *, u_int32_t)); +static int __db_put_arg __P((DB *, DBT *, DBT *, u_int32_t)); +static int __dbt_ferr __P((const DB *, const char *, const DBT *, int)); +static int __db_associate_foreign_arg __P((DB *, DB *, + int (*)(DB *, const DBT *, DBT *, const DBT *, int *), + u_int32_t)); + +/* + * These functions implement the Berkeley DB API. They are organized in a + * layered fashion. The interface functions (XXX_pp) perform all generic + * error checks (for example, PANIC'd region, replication state change + * in progress, inconsistent transaction usage), call function-specific + * check routines (_arg) to check for proper flag usage, etc., do pre-amble + * processing (incrementing handle counts, handling local transactions), + * call the function and then do post-amble processing (local transactions, + * decrement handle counts). + * + * The basic structure is: + * Check for simple/generic errors (PANIC'd region) + * Check if replication is changing state (increment handle count). + * Call function-specific argument checking routine + * Create internal transaction if necessary + * Call underlying worker function + * Commit/abort internal transaction if necessary + * Decrement handle count + */ + +/* + * __db_associate_pp -- + * DB->associate pre/post processing. + * + * PUBLIC: int __db_associate_pp __P((DB *, DB_TXN *, DB *, + * PUBLIC: int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); + */ +int +__db_associate_pp(dbp, txn, sdbp, callback, flags) + DB *dbp, *sdbp; + DB_TXN *txn; + int (*callback) __P((DB *, const DBT *, const DBT *, DBT *)); + u_int32_t flags; +{ + DBC *sdbc; + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret, txn_local; + + env = dbp->env; + txn_local = 0; + + STRIP_AUTO_COMMIT(flags); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && + (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + /* + * Secondary cursors may have the primary's lock file ID, so we need + * to make sure that no older cursors are lying around when we make + * the transition. + */ + if (TAILQ_FIRST(&sdbp->active_queue) != NULL || + TAILQ_FIRST(&sdbp->join_queue) != NULL) { + __db_errx(env, + "Databases may not become secondary indices while cursors are open"); + ret = EINVAL; + goto err; + } + + if ((ret = __db_associate_arg(dbp, sdbp, callback, flags)) != 0) + goto err; + + /* + * Create a local transaction as necessary, check for consistent + * transaction usage, and, if we have no transaction but do have + * locking on, acquire a locker id for the handle lock acquisition. + */ + if (IS_DB_AUTO_COMMIT(dbp, txn)) { + if ((ret = __txn_begin(env, ip, NULL, &txn, 0)) != 0) + goto err; + txn_local = 1; + } + + /* Check for consistent transaction usage. */ + if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0) + goto err; + + while ((sdbc = TAILQ_FIRST(&sdbp->free_queue)) != NULL) + if ((ret = __dbc_destroy(sdbc)) != 0) + goto err; + + ret = __db_associate(dbp, ip, txn, sdbp, callback, flags); + +err: if (txn_local && + (t_ret = __db_txn_auto_resolve(env, txn, 0, ret)) && ret == 0) + ret = t_ret; + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_associate_arg -- + * Check DB->associate arguments. + */ +static int +__db_associate_arg(dbp, sdbp, callback, flags) + DB *dbp, *sdbp; + int (*callback) __P((DB *, const DBT *, const DBT *, DBT *)); + u_int32_t flags; +{ + ENV *env; + int ret; + + env = dbp->env; + + if (F_ISSET(sdbp, DB_AM_SECONDARY)) { + __db_errx(env, + "Secondary index handles may not be re-associated"); + return (EINVAL); + } + if (F_ISSET(dbp, DB_AM_SECONDARY)) { + __db_errx(env, + "Secondary indices may not be used as primary databases"); + return (EINVAL); + } + if (F_ISSET(dbp, DB_AM_DUP)) { + __db_errx(env, + "Primary databases may not be configured with duplicates"); + return (EINVAL); + } + if (F_ISSET(dbp, DB_AM_RENUMBER)) { + __db_errx(env, + "Renumbering recno databases may not be used as primary databases"); + return (EINVAL); + } + + /* + * It's OK for the primary and secondary to not share an environment IFF + * the environments are local to the DB handle. (Specifically, cursor + * adjustment will work correctly in this case.) The environment being + * local implies the environment is not configured for either locking or + * transactions, as neither of those could work correctly. + */ + if (dbp->env != sdbp->env && + (!F_ISSET(dbp->env, ENV_DBLOCAL) || + !F_ISSET(sdbp->env, ENV_DBLOCAL))) { + __db_errx(env, + "The primary and secondary must be opened in the same environment"); + return (EINVAL); + } + if ((DB_IS_THREADED(dbp) && !DB_IS_THREADED(sdbp)) || + (!DB_IS_THREADED(dbp) && DB_IS_THREADED(sdbp))) { + __db_errx(env, + "The DB_THREAD setting must be the same for primary and secondary"); + return (EINVAL); + } + if (callback == NULL && + (!F_ISSET(dbp, DB_AM_RDONLY) || !F_ISSET(sdbp, DB_AM_RDONLY))) { + __db_errx(env, + "Callback function may be NULL only when database handles are read-only"); + return (EINVAL); + } + + if ((ret = __db_fchk(env, "DB->associate", flags, DB_CREATE | + DB_IMMUTABLE_KEY)) != 0) + return (ret); + + return (0); +} + +/* + * __db_close_pp -- + * DB->close pre/post processing. + * + * PUBLIC: int __db_close_pp __P((DB *, u_int32_t)); + */ +int +__db_close_pp(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = dbp->env; + ret = 0; + + /* + * Close a DB handle -- as a handle destructor, we can't fail. + * + * !!! + * The actual argument checking is simple, do it inline, outside of + * the replication block. + */ + if (flags != 0 && flags != DB_NOSYNC) + ret = __db_ferr(env, "DB->close", 0); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (t_ret = __db_rep_enter(dbp, 0, 0, 0)) != 0) { + handle_check = 0; + if (ret == 0) + ret = t_ret; + } + + if ((t_ret = __db_close(dbp, NULL, flags)) != 0 && ret == 0) + ret = t_ret; + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_cursor_pp -- + * DB->cursor pre/post processing. + * + * PUBLIC: int __db_cursor_pp __P((DB *, DB_TXN *, DBC **, u_int32_t)); + */ +int +__db_cursor_pp(dbp, txn, dbcp, flags) + DB *dbp; + DB_TXN *txn; + DBC **dbcp; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + REGENV *renv; + int rep_blocked, ret; + + env = dbp->env; + + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->cursor"); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + rep_blocked = 0; + if (txn == NULL && IS_ENV_REPLICATED(env)) { + if ((ret = __op_rep_enter(env)) != 0) + goto err; + rep_blocked = 1; + renv = env->reginfo->primary; + if (dbp->timestamp != renv->rep_timestamp) { + __db_errx(env, "%s %s", + "replication recovery unrolled committed transactions;", + "open DB and DBcursor handles must be closed"); + ret = DB_REP_HANDLE_DEAD; + goto err; + } + } + if ((ret = __db_cursor_arg(dbp, flags)) != 0) + goto err; + + /* + * Check for consistent transaction usage. For now, assume this + * cursor might be used for read operations only (in which case + * it may not require a txn). We'll check more stringently in + * c_del and c_put. (Note this means the read-op txn tests have + * to be a subset of the write-op ones.) + */ + if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 1)) != 0) + goto err; + + ret = __db_cursor(dbp, ip, txn, dbcp, flags); + +err: /* Release replication block on error. */ + if (ret != 0 && rep_blocked) + (void)__op_rep_exit(env); + + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_cursor -- + * DB->cursor. + * + * PUBLIC: int __db_cursor __P((DB *, + * PUBLIC: DB_THREAD_INFO *, DB_TXN *, DBC **, u_int32_t)); + */ +int +__db_cursor(dbp, ip, txn, dbcp, flags) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + DBC **dbcp; + u_int32_t flags; +{ + DBC *dbc; + ENV *env; + db_lockmode_t mode; + int ret; + + env = dbp->env; + + if (MULTIVERSION(dbp) && txn == NULL && (LF_ISSET(DB_TXN_SNAPSHOT) || + F_ISSET(env->dbenv, DB_ENV_TXN_SNAPSHOT))) { + if ((ret = + __txn_begin(env, ip, NULL, &txn, DB_TXN_SNAPSHOT)) != 0) + return (ret); + F_SET(txn, TXN_PRIVATE); + } + + if ((ret = __db_cursor_int(dbp, ip, txn, dbp->type, PGNO_INVALID, + LF_ISSET(DB_CURSOR_BULK | DB_CURSOR_TRANSIENT), NULL, &dbc)) != 0) + return (ret); + + /* + * If this is CDB, do all the locking in the interface, which is + * right here. + */ + if (CDB_LOCKING(env)) { + mode = (LF_ISSET(DB_WRITELOCK)) ? DB_LOCK_WRITE : + ((LF_ISSET(DB_WRITECURSOR) || txn != NULL) ? + DB_LOCK_IWRITE : DB_LOCK_READ); + if ((ret = __lock_get(env, dbc->locker, 0, + &dbc->lock_dbt, mode, &dbc->mylock)) != 0) + goto err; + if (LF_ISSET(DB_WRITECURSOR)) + F_SET(dbc, DBC_WRITECURSOR); + if (LF_ISSET(DB_WRITELOCK)) + F_SET(dbc, DBC_WRITER); + } + + if (LF_ISSET(DB_READ_UNCOMMITTED) || + (txn != NULL && F_ISSET(txn, TXN_READ_UNCOMMITTED))) + F_SET(dbc, DBC_READ_UNCOMMITTED); + + if (LF_ISSET(DB_READ_COMMITTED) || + (txn != NULL && F_ISSET(txn, TXN_READ_COMMITTED))) + F_SET(dbc, DBC_READ_COMMITTED); + + *dbcp = dbc; + return (0); + +err: (void)__dbc_close(dbc); + return (ret); +} + +/* + * __db_cursor_arg -- + * Check DB->cursor arguments. + */ +static int +__db_cursor_arg(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + ENV *env; + + env = dbp->env; + + /* + * DB_READ_COMMITTED and DB_READ_UNCOMMITTED require locking. + */ + if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED)) { + if (!LOCKING_ON(env)) + return (__db_fnl(env, "DB->cursor")); + } + + LF_CLR(DB_CURSOR_BULK | + DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_TXN_SNAPSHOT); + + /* Check for invalid function flags. */ + if (LF_ISSET(DB_WRITECURSOR)) { + if (DB_IS_READONLY(dbp)) + return (__db_rdonly(env, "DB->cursor")); + if (!CDB_LOCKING(env)) + return (__db_ferr(env, "DB->cursor", 0)); + LF_CLR(DB_WRITECURSOR); + } else if (LF_ISSET(DB_WRITELOCK)) { + if (DB_IS_READONLY(dbp)) + return (__db_rdonly(env, "DB->cursor")); + LF_CLR(DB_WRITELOCK); + } + + if (flags != 0) + return (__db_ferr(env, "DB->cursor", 0)); + + return (0); +} + +/* + * __db_del_pp -- + * DB->del pre/post processing. + * + * PUBLIC: int __db_del_pp __P((DB *, DB_TXN *, DBT *, u_int32_t)); + */ +int +__db_del_pp(dbp, txn, key, flags) + DB *dbp; + DB_TXN *txn; + DBT *key; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret, txn_local; + + env = dbp->env; + txn_local = 0; + + STRIP_AUTO_COMMIT(flags); + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->del"); + +#ifdef CONFIG_TEST + if (IS_REP_MASTER(env)) + DB_TEST_WAIT(env, env->test_check); +#endif + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && + (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + if ((ret = __db_del_arg(dbp, key, flags)) != 0) + goto err; + + /* Create local transaction as necessary. */ + if (IS_DB_AUTO_COMMIT(dbp, txn)) { + if ((ret = __txn_begin(env, ip, NULL, &txn, 0)) != 0) + goto err; + txn_local = 1; + } + + /* Check for consistent transaction usage. */ + if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0) + goto err; + + ret = __db_del(dbp, ip, txn, key, flags); + +err: if (txn_local && + (t_ret = __db_txn_auto_resolve(env, txn, 0, ret)) && ret == 0) + ret = t_ret; + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + ENV_LEAVE(env, ip); + __dbt_userfree(env, key, NULL, NULL); + return (ret); +} + +/* + * __db_del_arg -- + * Check DB->delete arguments. + */ +static int +__db_del_arg(dbp, key, flags) + DB *dbp; + DBT *key; + u_int32_t flags; +{ + ENV *env; + int ret; + + env = dbp->env; + + /* Check for changes to a read-only tree. */ + if (DB_IS_READONLY(dbp)) + return (__db_rdonly(env, "DB->del")); + + /* Check for invalid function flags. */ + switch (flags) { + case DB_CONSUME: + if (dbp->type != DB_QUEUE) + return (__db_ferr(env, "DB->del", 0)); + goto copy; + case DB_MULTIPLE: + case DB_MULTIPLE_KEY: + if (!F_ISSET(key, DB_DBT_BULK)) { + __db_errx(env, + "DB->del with DB_MULTIPLE(_KEY) requires multiple key records"); + return (EINVAL); + } + /* FALL THROUGH */ + case 0: +copy: if ((ret = __dbt_usercopy(env, key)) != 0) + return (ret); + break; + default: + return (__db_ferr(env, "DB->del", 0)); + } + + return (0); +} + +/* + * __db_exists -- + * DB->exists implementation. + * + * PUBLIC: int __db_exists __P((DB *, DB_TXN *, DBT *, u_int32_t)); + */ +int +__db_exists(dbp, txn, key, flags) + DB *dbp; + DB_TXN *txn; + DBT *key; + u_int32_t flags; +{ + DBT data; + int ret; + + /* + * Most flag checking is done in the DB->get call, we only check for + * specific incompatibilities here. This saves making __get_arg + * aware of the exist method's API constraints. + */ + STRIP_AUTO_COMMIT(flags); + if ((ret = __db_fchk(dbp->env, "DB->exists", flags, + DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW)) != 0) + return (ret); + + /* + * Configure a data DBT that returns no bytes so there's no copy + * of the data. + */ + memset(&data, 0, sizeof(data)); + data.dlen = 0; + data.flags = DB_DBT_PARTIAL | DB_DBT_USERMEM; + + return (dbp->get(dbp, txn, key, &data, flags)); +} + +/* + * db_fd_pp -- + * DB->fd pre/post processing. + * + * PUBLIC: int __db_fd_pp __P((DB *, int *)); + */ +int +__db_fd_pp(dbp, fdp) + DB *dbp; + int *fdp; +{ + DB_FH *fhp; + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = dbp->env; + + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->fd"); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) + goto err; + + /* + * !!! + * There's no argument checking to be done. + * + * !!! + * The actual method call is simple, do it inline. + * + * XXX + * Truly spectacular layering violation. + */ + if ((ret = __mp_xxx_fh(dbp->mpf, &fhp)) == 0) { + if (fhp == NULL) { + *fdp = -1; + __db_errx(env, + "Database does not have a valid file handle"); + ret = ENOENT; + } else + *fdp = fhp->fd; + } + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + +err: ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_get_pp -- + * DB->get pre/post processing. + * + * PUBLIC: int __db_get_pp __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); + */ +int +__db_get_pp(dbp, txn, key, data, flags) + DB *dbp; + DB_TXN *txn; + DBT *key, *data; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + u_int32_t mode; + int handle_check, ignore_lease, ret, t_ret, txn_local; + + env = dbp->env; + mode = 0; + txn_local = 0; + + STRIP_AUTO_COMMIT(flags); + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get"); + + ignore_lease = LF_ISSET(DB_IGNORE_LEASE) ? 1 : 0; + LF_CLR(DB_IGNORE_LEASE); + + if ((ret = __db_get_arg(dbp, key, data, flags)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && + (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + if (LF_ISSET(DB_READ_UNCOMMITTED)) + mode = DB_READ_UNCOMMITTED; + else if ((flags & DB_OPFLAGS_MASK) == DB_CONSUME || + (flags & DB_OPFLAGS_MASK) == DB_CONSUME_WAIT) { + mode = DB_WRITELOCK; + if (IS_DB_AUTO_COMMIT(dbp, txn)) { + if ((ret = __txn_begin(env, ip, NULL, &txn, 0)) != 0) + goto err; + txn_local = 1; + } + } + + /* Check for consistent transaction usage. */ + if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, + mode == DB_WRITELOCK || LF_ISSET(DB_RMW) ? 0 : 1)) != 0) + goto err; + + ret = __db_get(dbp, ip, txn, key, data, flags); + /* + * Check for master leases. + */ + if (ret == 0 && + IS_REP_MASTER(env) && IS_USING_LEASES(env) && !ignore_lease) + ret = __rep_lease_check(env, 1); + +err: if (txn_local && + (t_ret = __db_txn_auto_resolve(env, txn, 0, ret)) && ret == 0) + ret = t_ret; + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + __dbt_userfree(env, key, NULL, data); + return (ret); +} + +/* + * __db_get -- + * DB->get. + * + * PUBLIC: int __db_get __P((DB *, + * PUBLIC: DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, u_int32_t)); + */ +int +__db_get(dbp, ip, txn, key, data, flags) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + DBT *key, *data; + u_int32_t flags; +{ + DBC *dbc; + u_int32_t mode; + int ret, t_ret; + + /* + * The DB_CURSOR_TRANSIENT flag indicates that we're just doing a single + * operation with this cursor, and that in case of error we don't need + * to restore it to its old position. Thus, we can perform the get + * without duplicating the cursor, saving some cycles in this common + * case. + */ + mode = DB_CURSOR_TRANSIENT; + if (LF_ISSET(DB_READ_UNCOMMITTED)) { + mode |= DB_READ_UNCOMMITTED; + LF_CLR(DB_READ_UNCOMMITTED); + } else if (LF_ISSET(DB_READ_COMMITTED)) { + mode |= DB_READ_COMMITTED; + LF_CLR(DB_READ_COMMITTED); + } else if ((flags & DB_OPFLAGS_MASK) == DB_CONSUME || + (flags & DB_OPFLAGS_MASK) == DB_CONSUME_WAIT) + mode |= DB_WRITELOCK; + + if ((ret = __db_cursor(dbp, ip, txn, &dbc, mode)) != 0) + return (ret); + + DEBUG_LREAD(dbc, txn, "DB->get", key, NULL, flags); + + /* + * The semantics of bulk gets are different for DB->get vs DBC->get. + * Mark the cursor so the low-level bulk get routines know which + * behavior we want. + */ + F_SET(dbc, DBC_FROM_DB_GET); + + /* + * SET_RET_MEM indicates that if key and/or data have no DBT + * flags set and DB manages the returned-data memory, that memory + * will belong to this handle, not to the underlying cursor. + */ + SET_RET_MEM(dbc, dbp); + + if (LF_ISSET(~(DB_RMW | DB_MULTIPLE)) == 0) + LF_SET(DB_SET); + +#ifdef HAVE_PARTITION + if (F_ISSET(dbc, DBC_PARTITIONED)) + ret = __partc_get(dbc, key, data, flags); + else +#endif + ret = __dbc_get(dbc, key, data, flags); + + if (dbc != NULL && (t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __db_get_arg -- + * DB->get argument checking, used by both DB->get and DB->pget. + */ +static int +__db_get_arg(dbp, key, data, flags) + const DB *dbp; + DBT *key, *data; + u_int32_t flags; +{ + ENV *env; + int dirty, multi, ret; + + env = dbp->env; + + /* + * Check for read-modify-write validity. DB_RMW doesn't make sense + * with CDB cursors since if you're going to write the cursor, you + * had to create it with DB_WRITECURSOR. Regardless, we check for + * LOCKING_ON and not STD_LOCKING, as we don't want to disallow it. + * If this changes, confirm that DB does not itself set the DB_RMW + * flag in a path where CDB may have been configured. + */ + dirty = 0; + if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW)) { + if (!LOCKING_ON(env)) + return (__db_fnl(env, "DB->get")); + if ((ret = __db_fcchk(env, "DB->get", + flags, DB_READ_UNCOMMITTED, DB_READ_COMMITTED)) != 0) + return (ret); + if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED)) + dirty = 1; + LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW); + } + + multi = 0; + if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) { + if (LF_ISSET(DB_MULTIPLE_KEY)) + goto multi_err; + multi = LF_ISSET(DB_MULTIPLE) ? 1 : 0; + LF_CLR(DB_MULTIPLE); + } + + /* Check for invalid function flags. */ + switch (flags) { + case DB_GET_BOTH: + if ((ret = __dbt_usercopy(env, data)) != 0) + return (ret); + /* FALLTHROUGH */ + case 0: + if ((ret = __dbt_usercopy(env, key)) != 0) { + __dbt_userfree(env, key, NULL, data); + return (ret); + } + break; + case DB_SET_RECNO: + if (!F_ISSET(dbp, DB_AM_RECNUM)) + goto err; + if ((ret = __dbt_usercopy(env, key)) != 0) + return (ret); + break; + case DB_CONSUME: + case DB_CONSUME_WAIT: + if (dirty) { + __db_errx(env, + "%s is not supported with DB_CONSUME or DB_CONSUME_WAIT", + LF_ISSET(DB_READ_UNCOMMITTED) ? + "DB_READ_UNCOMMITTED" : "DB_READ_COMMITTED"); + return (EINVAL); + } + if (multi) +multi_err: return (__db_ferr(env, "DB->get", 1)); + if (dbp->type == DB_QUEUE) + break; + /* FALLTHROUGH */ + default: +err: return (__db_ferr(env, "DB->get", 0)); + } + + /* + * Check for invalid key/data flags. + */ + if ((ret = + __dbt_ferr(dbp, "key", key, DB_RETURNS_A_KEY(dbp, flags))) != 0) + return (ret); + if ((ret = __dbt_ferr(dbp, "data", data, 1)) != 0) + return (ret); + + if (multi) { + if (!F_ISSET(data, DB_DBT_USERMEM)) { + __db_errx(env, + "DB_MULTIPLE requires DB_DBT_USERMEM be set"); + return (EINVAL); + } + if (F_ISSET(key, DB_DBT_PARTIAL) || + F_ISSET(data, DB_DBT_PARTIAL)) { + __db_errx(env, + "DB_MULTIPLE does not support DB_DBT_PARTIAL"); + return (EINVAL); + } + if (data->ulen < 1024 || + data->ulen < dbp->pgsize || data->ulen % 1024 != 0) { + __db_errx(env, "%s%s", + "DB_MULTIPLE buffers must be ", + "aligned, at least page size and multiples of 1KB"); + return (EINVAL); + } + } + + return (0); +} + +/* + * __db_join_pp -- + * DB->join pre/post processing. + * + * PUBLIC: int __db_join_pp __P((DB *, DBC **, DBC **, u_int32_t)); + */ +int +__db_join_pp(primary, curslist, dbcp, flags) + DB *primary; + DBC **curslist, **dbcp; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = primary->env; + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (ret = + __db_rep_enter(primary, 1, 0, curslist[0]->txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + if ((ret = __db_join_arg(primary, curslist, flags)) == 0) + ret = __db_join(primary, curslist, dbcp, flags); + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + +err: ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_join_arg -- + * Check DB->join arguments. + */ +static int +__db_join_arg(primary, curslist, flags) + DB *primary; + DBC **curslist; + u_int32_t flags; +{ + DB_TXN *txn; + ENV *env; + int i; + + env = primary->env; + + switch (flags) { + case 0: + case DB_JOIN_NOSORT: + break; + default: + return (__db_ferr(env, "DB->join", 0)); + } + + if (curslist == NULL || curslist[0] == NULL) { + __db_errx(env, + "At least one secondary cursor must be specified to DB->join"); + return (EINVAL); + } + + txn = curslist[0]->txn; + for (i = 1; curslist[i] != NULL; i++) + if (curslist[i]->txn != txn) { + __db_errx(env, + "All secondary cursors must share the same transaction"); + return (EINVAL); + } + + return (0); +} + +/* + * __db_key_range_pp -- + * DB->key_range pre/post processing. + * + * PUBLIC: int __db_key_range_pp + * PUBLIC: __P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t)); + */ +int +__db_key_range_pp(dbp, txn, key, kr, flags) + DB *dbp; + DB_TXN *txn; + DBT *key; + DB_KEY_RANGE *kr; + u_int32_t flags; +{ + DBC *dbc; + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = dbp->env; + + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->key_range"); + + /* + * !!! + * The actual argument checking is simple, do it inline, outside of + * the replication block. + */ + if (flags != 0) + return (__db_ferr(env, "DB->key_range", 0)); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && + (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + /* Check for consistent transaction usage. */ + if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 1)) != 0) + goto err; + + /* + * !!! + * The actual method call is simple, do it inline. + */ + switch (dbp->type) { + case DB_BTREE: +#ifndef HAVE_BREW + if ((ret = __dbt_usercopy(env, key)) != 0) + goto err; + + /* Acquire a cursor. */ + if ((ret = __db_cursor(dbp, ip, txn, &dbc, 0)) != 0) + break; + + DEBUG_LWRITE(dbc, NULL, "bam_key_range", NULL, NULL, 0); +#ifdef HAVE_PARTITION + if (DB_IS_PARTITIONED(dbp)) + ret = __part_key_range(dbc, key, kr, flags); + else +#endif + ret = __bam_key_range(dbc, key, kr, flags); + + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + __dbt_userfree(env, key, NULL, NULL); + break; +#else + COMPQUIET(dbc, NULL); + COMPQUIET(key, NULL); + COMPQUIET(kr, NULL); + /* FALLTHROUGH */ +#endif + case DB_HASH: + case DB_QUEUE: + case DB_RECNO: + ret = __dbh_am_chk(dbp, DB_OK_BTREE); + break; + case DB_UNKNOWN: + default: + ret = __db_unknown_type(env, "DB->key_range", dbp->type); + break; + } + +err: /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_open_pp -- + * DB->open pre/post processing. + * + * PUBLIC: int __db_open_pp __P((DB *, DB_TXN *, + * PUBLIC: const char *, const char *, DBTYPE, u_int32_t, int)); + */ +int +__db_open_pp(dbp, txn, fname, dname, type, flags, mode) + DB *dbp; + DB_TXN *txn; + const char *fname, *dname; + DBTYPE type; + u_int32_t flags; + int mode; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, nosync, remove_me, ret, t_ret, txn_local; + + env = dbp->env; + nosync = 1; + handle_check = remove_me = txn_local = 0; + + ENV_ENTER(env, ip); + + /* + * Save the file and database names and flags. We do this here + * because we don't pass all of the flags down into the actual + * DB->open method call, we strip DB_AUTO_COMMIT at this layer. + */ + if ((fname != NULL && + (ret = __os_strdup(env, fname, &dbp->fname)) != 0)) + goto err; + if ((dname != NULL && + (ret = __os_strdup(env, dname, &dbp->dname)) != 0)) + goto err; + dbp->open_flags = flags; + + /* Save the current DB handle flags for refresh. */ + dbp->orig_flags = dbp->flags; + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && + (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + /* + * Create local transaction as necessary, check for consistent + * transaction usage. + */ + if (IS_ENV_AUTO_COMMIT(env, txn, flags)) { + if ((ret = __db_txn_auto_init(env, ip, &txn)) != 0) + goto err; + txn_local = 1; + } else if (txn != NULL && !TXN_ON(env) && + (!CDB_LOCKING(env) || !F_ISSET(txn, TXN_CDSGROUP))) { + ret = __db_not_txn_env(env); + goto err; + } + LF_CLR(DB_AUTO_COMMIT); + + /* + * We check arguments after possibly creating a local transaction, + * which is unusual -- the reason is some flags are illegal if any + * kind of transaction is in effect. + */ + if ((ret = __db_open_arg(dbp, txn, fname, dname, type, flags)) == 0) + if ((ret = __db_open(dbp, ip, txn, fname, dname, type, + flags, mode, PGNO_BASE_MD)) != 0) + goto txnerr; + + /* + * You can open the database that describes the subdatabases in the + * rest of the file read-only. The content of each key's data is + * unspecified and applications should never be adding new records + * or updating existing records. However, during recovery, we need + * to open these databases R/W so we can redo/undo changes in them. + * Likewise, we need to open master databases read/write during + * rename and remove so we can be sure they're fully sync'ed, so + * we provide an override flag for the purpose. + */ + if (dname == NULL && !IS_RECOVERING(env) && !LF_ISSET(DB_RDONLY) && + !LF_ISSET(DB_RDWRMASTER) && F_ISSET(dbp, DB_AM_SUBDB)) { + __db_errx(env, + "files containing multiple databases may only be opened read-only"); + ret = EINVAL; + goto txnerr; + } + + /* + * Success: file creations have to be synchronous, otherwise we don't + * care. + */ + if (F_ISSET(dbp, DB_AM_CREATED | DB_AM_CREATED_MSTR)) + nosync = 0; + + /* Success: don't discard the file on close. */ + F_CLR(dbp, DB_AM_DISCARD | DB_AM_CREATED | DB_AM_CREATED_MSTR); + + /* + * If not transactional, remove the databases/subdatabases if it is + * persistent. If we're transactional, the child transaction abort + * cleans up. + */ +txnerr: if (ret != 0 && !IS_REAL_TXN(txn)) { + remove_me = (F_ISSET(dbp, DB_AM_CREATED) && + (fname != NULL || dname != NULL)) ? 1 : 0; + if (F_ISSET(dbp, DB_AM_CREATED_MSTR) || + (dname == NULL && remove_me)) + /* Remove file. */ + (void)__db_remove_int(dbp, + ip, txn, fname, NULL, DB_FORCE); + else if (remove_me) + /* Remove subdatabase. */ + (void)__db_remove_int(dbp, + ip, txn, fname, dname, DB_FORCE); + } + + if (txn_local && (t_ret = + __db_txn_auto_resolve(env, txn, nosync, ret)) && ret == 0) + ret = t_ret; + +err: /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_open_arg -- + * Check DB->open arguments. + */ +static int +__db_open_arg(dbp, txn, fname, dname, type, flags) + DB *dbp; + DB_TXN *txn; + const char *fname, *dname; + DBTYPE type; + u_int32_t flags; +{ + ENV *env; + u_int32_t ok_flags; + int ret; + + env = dbp->env; + + /* Validate arguments. */ +#undef OKFLAGS +#define OKFLAGS \ + (DB_AUTO_COMMIT | DB_CREATE | DB_EXCL | DB_FCNTL_LOCKING | \ + DB_MULTIVERSION | DB_NOMMAP | DB_NO_AUTO_COMMIT | DB_RDONLY | \ + DB_RDWRMASTER | DB_READ_UNCOMMITTED | DB_THREAD | DB_TRUNCATE) + if ((ret = __db_fchk(env, "DB->open", flags, OKFLAGS)) != 0) + return (ret); + if (LF_ISSET(DB_EXCL) && !LF_ISSET(DB_CREATE)) + return (__db_ferr(env, "DB->open", 1)); + if (LF_ISSET(DB_RDONLY) && LF_ISSET(DB_CREATE)) + return (__db_ferr(env, "DB->open", 1)); + +#ifdef HAVE_VXWORKS + if (LF_ISSET(DB_TRUNCATE)) { + __db_errx(env, "DB_TRUNCATE not supported on VxWorks"); + return (DB_OPNOTSUP); + } +#endif + switch (type) { + case DB_UNKNOWN: + if (LF_ISSET(DB_CREATE|DB_TRUNCATE)) { + __db_errx(env, + "DB_UNKNOWN type specified with DB_CREATE or DB_TRUNCATE"); + return (EINVAL); + } + ok_flags = 0; + break; + case DB_BTREE: + ok_flags = DB_OK_BTREE; + break; + case DB_HASH: +#ifndef HAVE_HASH + return (__db_no_hash_am(env)); +#endif + ok_flags = DB_OK_HASH; + break; + case DB_QUEUE: +#ifndef HAVE_QUEUE + return (__db_no_queue_am(env)); +#endif + ok_flags = DB_OK_QUEUE; + break; + case DB_RECNO: + ok_flags = DB_OK_RECNO; + break; + default: + __db_errx(env, "unknown type: %lu", (u_long)type); + return (EINVAL); + } + if (ok_flags) + DB_ILLEGAL_METHOD(dbp, ok_flags); + + /* The environment may have been created, but never opened. */ + if (!F_ISSET(env, ENV_DBLOCAL | ENV_OPEN_CALLED)) { + __db_errx(env, "database environment not yet opened"); + return (EINVAL); + } + + /* + * Historically, you could pass in an environment that didn't have a + * mpool, and DB would create a private one behind the scenes. This + * no longer works. + */ + if (!F_ISSET(env, ENV_DBLOCAL) && !MPOOL_ON(env)) { + __db_errx(env, "environment did not include a memory pool"); + return (EINVAL); + } + + /* + * You can't specify threads during DB->open if subsystems in the + * environment weren't configured with them. + */ + if (LF_ISSET(DB_THREAD) && !F_ISSET(env, ENV_DBLOCAL | ENV_THREAD)) { + __db_errx(env, "environment not created using DB_THREAD"); + return (EINVAL); + } + + /* DB_MULTIVERSION requires a database configured for transactions. */ + if (LF_ISSET(DB_MULTIVERSION) && !IS_REAL_TXN(txn)) { + __db_errx(env, + "DB_MULTIVERSION illegal without a transaction specified"); + return (EINVAL); + } + + if (LF_ISSET(DB_MULTIVERSION) && type == DB_QUEUE) { + __db_errx(env, + "DB_MULTIVERSION illegal with queue databases"); + return (EINVAL); + } + + /* DB_TRUNCATE is neither transaction recoverable nor lockable. */ + if (LF_ISSET(DB_TRUNCATE) && (LOCKING_ON(env) || txn != NULL)) { + __db_errx(env, + "DB_TRUNCATE illegal with %s specified", + LOCKING_ON(env) ? "locking" : "transactions"); + return (EINVAL); + } + + /* Subdatabase checks. */ + if (dname != NULL) { + /* QAM can only be done on in-memory subdatabases. */ + if (type == DB_QUEUE && fname != NULL) { + __db_errx( + env, "Queue databases must be one-per-file"); + return (EINVAL); + } + + /* + * Named in-memory databases can't support certain flags, + * so check here. + */ + if (fname == NULL) + F_CLR(dbp, DB_AM_CHKSUM | DB_AM_ENCRYPT); + } + + return (0); +} + +/* + * __db_pget_pp -- + * DB->pget pre/post processing. + * + * PUBLIC: int __db_pget_pp + * PUBLIC: __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t)); + */ +int +__db_pget_pp(dbp, txn, skey, pkey, data, flags) + DB *dbp; + DB_TXN *txn; + DBT *skey, *pkey, *data; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ignore_lease, ret, t_ret; + + env = dbp->env; + + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->pget"); + + ignore_lease = LF_ISSET(DB_IGNORE_LEASE) ? 1 : 0; + LF_CLR(DB_IGNORE_LEASE); + + if ((ret = __db_pget_arg(dbp, pkey, flags)) != 0 || + (ret = __db_get_arg(dbp, skey, data, flags)) != 0) { + __dbt_userfree(env, skey, pkey, data); + return (ret); + } + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && + (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + ret = __db_pget(dbp, ip, txn, skey, pkey, data, flags); + /* + * Check for master leases. + */ + if (ret == 0 && + IS_REP_MASTER(env) && IS_USING_LEASES(env) && !ignore_lease) + ret = __rep_lease_check(env, 1); + +err: /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + __dbt_userfree(env, skey, pkey, data); + return (ret); +} + +/* + * __db_pget -- + * DB->pget. + * + * PUBLIC: int __db_pget __P((DB *, + * PUBLIC: DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t)); + */ +int +__db_pget(dbp, ip, txn, skey, pkey, data, flags) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + DBT *skey, *pkey, *data; + u_int32_t flags; +{ + DBC *dbc; + u_int32_t mode; + int ret, t_ret; + + mode = DB_CURSOR_TRANSIENT; + if (LF_ISSET(DB_READ_UNCOMMITTED)) { + mode |= DB_READ_UNCOMMITTED; + LF_CLR(DB_READ_UNCOMMITTED); + } else if (LF_ISSET(DB_READ_COMMITTED)) { + mode |= DB_READ_COMMITTED; + LF_CLR(DB_READ_COMMITTED); + } + + if ((ret = __db_cursor(dbp, ip, txn, &dbc, mode)) != 0) + return (ret); + + SET_RET_MEM(dbc, dbp); + + DEBUG_LREAD(dbc, txn, "__db_pget", skey, NULL, flags); + + /* + * !!! + * The actual method call is simple, do it inline. + * + * The underlying cursor pget will fill in a default DBT for null + * pkeys, and use the cursor's returned-key memory internally to + * store any intermediate primary keys. However, we've just set + * the returned-key memory to the DB handle's key memory, which + * is unsafe to use if the DB handle is threaded. If the pkey + * argument is NULL, use the DBC-owned returned-key memory + * instead; it'll go away when we close the cursor before we + * return, but in this case that's just fine, as we're not + * returning the primary key. + */ + if (pkey == NULL) + dbc->rkey = &dbc->my_rkey; + + /* + * The cursor is just a perfectly ordinary secondary database cursor. + * Call its c_pget() method to do the dirty work. + */ + if (flags == 0 || flags == DB_RMW) + flags |= DB_SET; + + ret = __dbc_pget(dbc, skey, pkey, data, flags); + + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __db_pget_arg -- + * Check DB->pget arguments. + */ +static int +__db_pget_arg(dbp, pkey, flags) + DB *dbp; + DBT *pkey; + u_int32_t flags; +{ + ENV *env; + int ret; + + env = dbp->env; + + if (!F_ISSET(dbp, DB_AM_SECONDARY)) { + __db_errx(env, + "DB->pget may only be used on secondary indices"); + return (EINVAL); + } + + if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) { + __db_errx(env, + "DB_MULTIPLE and DB_MULTIPLE_KEY may not be used on secondary indices"); + return (EINVAL); + } + + /* DB_CONSUME makes no sense on a secondary index. */ + LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW); + switch (flags) { + case DB_CONSUME: + case DB_CONSUME_WAIT: + return (__db_ferr(env, "DB->pget", 0)); + default: + /* __db_get_arg will catch the rest. */ + break; + } + + /* + * We allow the pkey field to be NULL, so that we can make the + * two-DBT get calls into wrappers for the three-DBT ones. + */ + if (pkey != NULL && + (ret = __dbt_ferr(dbp, "primary key", pkey, 1)) != 0) + return (ret); + + if (flags == DB_GET_BOTH) { + /* The pkey field can't be NULL if we're doing a DB_GET_BOTH. */ + if (pkey == NULL) { + __db_errx(env, + "DB_GET_BOTH on a secondary index requires a primary key"); + return (EINVAL); + } + if ((ret = __dbt_usercopy(env, pkey)) != 0) + return (ret); + } + + return (0); +} + +/* + * __db_put_pp -- + * DB->put pre/post processing. + * + * PUBLIC: int __db_put_pp __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); + */ +int +__db_put_pp(dbp, txn, key, data, flags) + DB *dbp; + DB_TXN *txn; + DBT *key, *data; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, txn_local, t_ret; + + env = dbp->env; + txn_local = 0; + + STRIP_AUTO_COMMIT(flags); + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->put"); + + if ((ret = __db_put_arg(dbp, key, data, flags)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && + (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + /* Create local transaction as necessary. */ + if (IS_DB_AUTO_COMMIT(dbp, txn)) { + if ((ret = __txn_begin(env, ip, NULL, &txn, 0)) != 0) + goto err; + txn_local = 1; + } + + /* Check for consistent transaction usage. */ + if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0) + goto err; + + ret = __db_put(dbp, ip, txn, key, data, flags); + +err: if (txn_local && + (t_ret = __db_txn_auto_resolve(env, txn, 0, ret)) && ret == 0) + ret = t_ret; + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + __dbt_userfree(env, key, NULL, data); + return (ret); +} + +/* + * __db_put_arg -- + * Check DB->put arguments. + */ +static int +__db_put_arg(dbp, key, data, flags) + DB *dbp; + DBT *key, *data; + u_int32_t flags; +{ + ENV *env; + int ret, returnkey; + + env = dbp->env; + returnkey = 0; + + /* Check for changes to a read-only tree. */ + if (DB_IS_READONLY(dbp)) + return (__db_rdonly(env, "DB->put")); + + /* Check for puts on a secondary. */ + if (F_ISSET(dbp, DB_AM_SECONDARY)) { + __db_errx(env, "DB->put forbidden on secondary indices"); + return (EINVAL); + } + + if (LF_ISSET(DB_MULTIPLE_KEY | DB_MULTIPLE)) { + if (LF_ISSET(DB_MULTIPLE) && LF_ISSET(DB_MULTIPLE_KEY)) + goto err; + + switch (LF_ISSET(DB_OPFLAGS_MASK)) { + case 0: + case DB_OVERWRITE_DUP: + break; + default: + __db_errx(env, + "DB->put: DB_MULTIPLE(_KEY) can only be combined with DB_OVERWRITE_DUP"); + return (EINVAL); + } + + if (!F_ISSET(key, DB_DBT_BULK)) { + __db_errx(env, + "DB->put with DB_MULTIPLE(_KEY) requires a bulk key buffer"); + return (EINVAL); + } + } + if (LF_ISSET(DB_MULTIPLE)) { + if (!F_ISSET(data, DB_DBT_BULK)) { + __db_errx(env, + "DB->put with DB_MULTIPLE requires a bulk data buffer"); + return (EINVAL); + } + } + + /* Check for invalid function flags. */ + switch (LF_ISSET(DB_OPFLAGS_MASK)) { + case 0: + case DB_NOOVERWRITE: + case DB_OVERWRITE_DUP: + break; + case DB_APPEND: + if (dbp->type != DB_RECNO && dbp->type != DB_QUEUE) + goto err; + returnkey = 1; + break; + case DB_NODUPDATA: + if (F_ISSET(dbp, DB_AM_DUPSORT)) + break; + /* FALLTHROUGH */ + default: +err: return (__db_ferr(env, "DB->put", 0)); + } + + /* + * Check for invalid key/data flags. The key may reasonably be NULL + * if DB_APPEND is set and the application doesn't care about the + * returned key. + */ + if (((returnkey && key != NULL) || !returnkey) && + (ret = __dbt_ferr(dbp, "key", key, returnkey)) != 0) + return (ret); + if (!LF_ISSET(DB_MULTIPLE_KEY) && + (ret = __dbt_ferr(dbp, "data", data, 0)) != 0) + return (ret); + + /* + * The key parameter should not be NULL or have the "partial" flag set + * in a put call unless the user doesn't care about a key value we'd + * return. The user tells us they don't care about the returned key by + * setting the key parameter to NULL or configuring the key DBT to not + * return any information. (Returned keys from a put are always record + * numbers, and returning part of a record number doesn't make sense: + * only accept a partial return if the length returned is 0.) + */ + if ((returnkey && + key != NULL && F_ISSET(key, DB_DBT_PARTIAL) && key->dlen != 0) || + (!returnkey && F_ISSET(key, DB_DBT_PARTIAL))) + return (__db_ferr(env, "key DBT", 0)); + + /* Check for partial puts in the presence of duplicates. */ + if (data != NULL && F_ISSET(data, DB_DBT_PARTIAL) && + (F_ISSET(dbp, DB_AM_DUP) || F_ISSET(key, DB_DBT_DUPOK))) { + __db_errx(env, +"a partial put in the presence of duplicates requires a cursor operation"); + return (EINVAL); + } + + if ((flags != DB_APPEND && (ret = __dbt_usercopy(env, key)) != 0) || + (!LF_ISSET(DB_MULTIPLE_KEY) && + (ret = __dbt_usercopy(env, data)) != 0)) + return (ret); + + return (0); +} + +/* + * __db_compact_pp -- + * DB->compact pre/post processing. + * + * PUBLIC: int __db_compact_pp __P((DB *, DB_TXN *, + * PUBLIC: DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *)); + */ +int +__db_compact_pp(dbp, txn, start, stop, c_data, flags, end) + DB *dbp; + DB_TXN *txn; + DBT *start, *stop; + DB_COMPACT *c_data; + u_int32_t flags; + DBT *end; +{ + DB_COMPACT *dp, l_data; + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = dbp->env; + + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->compact"); + + /* + * !!! + * The actual argument checking is simple, do it inline, outside of + * the replication block. + */ + if ((ret = __db_fchk( + env, "DB->compact", flags, DB_FREELIST_ONLY | DB_FREE_SPACE)) != 0) + return (ret); + + /* Check for changes to a read-only database. */ + if (DB_IS_READONLY(dbp)) + return (__db_rdonly(env, "DB->compact")); + + if (start != NULL && (ret = __dbt_usercopy(env, start)) != 0) + return (ret); + if (stop != NULL && (ret = __dbt_usercopy(env, stop)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, + txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + if (c_data == NULL) { + dp = &l_data; + memset(dp, 0, sizeof(*dp)); + } else + dp = c_data; +#ifdef HAVE_PARTITION + if (DB_IS_PARTITIONED(dbp)) + ret = __part_compact(dbp, ip, txn, start, stop, dp, flags, end); + else +#endif + switch (dbp->type) { + case DB_HASH: + if (!LF_ISSET(DB_FREELIST_ONLY)) + goto err; + /* FALLTHROUGH */ + case DB_BTREE: + case DB_RECNO: + ret = __bam_compact(dbp, ip, txn, start, stop, dp, flags, end); + break; + + default: +err: ret = __dbh_am_chk(dbp, DB_OK_BTREE); + break; + } + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + __dbt_userfree(env, start, stop, NULL); + return (ret); +} + +/* + * __db_associate_foreign_pp -- + * DB->associate_foreign pre/post processing. + * + * PUBLIC: int __db_associate_foreign_pp __P((DB *, DB *, + * PUBLIC: int (*)(DB *, const DBT *, DBT *, const DBT *, int *), + * PUBLIC: u_int32_t)); + */ +int +__db_associate_foreign_pp(fdbp, dbp, callback, flags) + DB *dbp, *fdbp; + int (*callback) __P((DB *, const DBT *, DBT *, const DBT *, int *)); + u_int32_t flags; +{ + /* Most of this is based on the implementation of associate */ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = dbp->env; + + PANIC_CHECK(env); + STRIP_AUTO_COMMIT(flags); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && + (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) { + handle_check = 0; + goto err; + } + + if ((ret = __db_associate_foreign_arg(fdbp, dbp, callback, flags)) != 0) + goto err; + + ret = __db_associate_foreign(fdbp, dbp, callback, flags); + +err: /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_associate_foreign_arg -- + * DB->associate_foreign argument checking. + */ +static int +__db_associate_foreign_arg(fdbp, dbp, callback, flags) + DB *dbp, *fdbp; + int (*callback) __P((DB *, const DBT *, DBT *, const DBT *, int *)); + u_int32_t flags; +{ + ENV *env; + + env = fdbp->env; + + if (F_ISSET(fdbp, DB_AM_SECONDARY)) { + __db_errx(env, + "Secondary indices may not be used as foreign databases"); + return (EINVAL); + } + if (F_ISSET(fdbp, DB_AM_DUP)) { + __db_errx(env, + "Foreign databases may not be configured with duplicates"); + return (EINVAL); + } + if (F_ISSET(fdbp, DB_AM_RENUMBER)) { + __db_errx(env, + "Renumbering recno databases may not be used as foreign databases"); + return (EINVAL); + } + if (!F_ISSET(dbp, DB_AM_SECONDARY)) { + __db_errx(env, + "The associating database must be a secondary index."); + return (EINVAL); + } + if (LF_ISSET(DB_FOREIGN_NULLIFY) && callback == NULL) { + __db_errx(env, + "When specifying a delete action of nullify, a callback%s", + " function needs to be configured"); + return (EINVAL); + } else if (!LF_ISSET(DB_FOREIGN_NULLIFY) && callback != NULL) { + __db_errx(env, + "When not specifying a delete action of nullify, a%s", + " callback function cannot be configured"); + return (EINVAL); + } + + return (0); +} + +/* + * __db_sync_pp -- + * DB->sync pre/post processing. + * + * PUBLIC: int __db_sync_pp __P((DB *, u_int32_t)); + */ +int +__db_sync_pp(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = dbp->env; + + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->sync"); + + /* + * !!! + * The actual argument checking is simple, do it inline, outside of + * the replication block. + */ + if (flags != 0) + return (__db_ferr(env, "DB->sync", 0)); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) { + handle_check = 0; + goto err; + } + + ret = __db_sync(dbp); + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + +err: ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __dbc_close_pp -- + * DBC->close pre/post processing. + * + * PUBLIC: int __dbc_close_pp __P((DBC *)); + */ +int +__dbc_close_pp(dbc) + DBC *dbc; +{ + DB *dbp; + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + dbp = dbc->dbp; + env = dbp->env; + + /* + * If the cursor is already closed we have a serious problem, and we + * assume that the cursor isn't on the active queue. Don't do any of + * the remaining cursor close processing. + */ + if (!F_ISSET(dbc, DBC_ACTIVE)) { + __db_errx(env, "Closing already-closed cursor"); + return (EINVAL); + } + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = dbc->txn == NULL && IS_ENV_REPLICATED(env); + ret = __dbc_close(dbc); + + /* Release replication block. */ + if (handle_check && + (t_ret = __op_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __dbc_cmp_pp -- + * DBC->cmp pre/post processing. + * + * PUBLIC: int __dbc_cmp_pp __P((DBC *, DBC *, int*, u_int32_t)); + */ +int +__dbc_cmp_pp(dbc, other_cursor, result, flags) + DBC *dbc, *other_cursor; + int *result; + u_int32_t flags; +{ + DB *dbp, *odbp; + DB_THREAD_INFO *ip; + ENV *env; + int ret; + + dbp = dbc->dbp; + odbp = other_cursor->dbp; + env = dbp->env; + + if (flags != 0) + return (__db_ferr(env, "DBcursor->cmp", 0)); + + if (other_cursor == NULL) { + __db_errx(env, "DBcursor->cmp dbc pointer must not be null"); + return (EINVAL); + } + + if (dbp != odbp) { + __db_errx(env, +"DBcursor->cmp both cursors must refer to the same database."); + return (EINVAL); + } + + ENV_ENTER(env, ip); + ret = __dbc_cmp(dbc, other_cursor, result); + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __dbc_count_pp -- + * DBC->count pre/post processing. + * + * PUBLIC: int __dbc_count_pp __P((DBC *, db_recno_t *, u_int32_t)); + */ +int +__dbc_count_pp(dbc, recnop, flags) + DBC *dbc; + db_recno_t *recnop; + u_int32_t flags; +{ + DB *dbp; + DB_THREAD_INFO *ip; + ENV *env; + int ret; + + dbp = dbc->dbp; + env = dbp->env; + + /* + * !!! + * The actual argument checking is simple, do it inline, outside of + * the replication block. + * + * The cursor must be initialized, return EINVAL for an invalid cursor. + */ + if (flags != 0) + return (__db_ferr(env, "DBcursor->count", 0)); + + if (!IS_INITIALIZED(dbc)) + return (__db_curinval(env)); + + ENV_ENTER(env, ip); + ret = __dbc_count(dbc, recnop); + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __dbc_del_pp -- + * DBC->del pre/post processing. + * + * PUBLIC: int __dbc_del_pp __P((DBC *, u_int32_t)); + */ +int +__dbc_del_pp(dbc, flags) + DBC *dbc; + u_int32_t flags; +{ + DB *dbp; + DB_THREAD_INFO *ip; + ENV *env; + int ret; + + dbp = dbc->dbp; + env = dbp->env; + + if ((ret = __dbc_del_arg(dbc, flags)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + /* Check for consistent transaction usage. */ + if ((ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0) + goto err; + + DEBUG_LWRITE(dbc, dbc->txn, "DBcursor->del", NULL, NULL, flags); + ret = __dbc_del(dbc, flags); + +err: ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __dbc_del_arg -- + * Check DBC->del arguments. + */ +static int +__dbc_del_arg(dbc, flags) + DBC *dbc; + u_int32_t flags; +{ + DB *dbp; + ENV *env; + + dbp = dbc->dbp; + env = dbp->env; + + /* Check for changes to a read-only tree. */ + if (DB_IS_READONLY(dbp)) + return (__db_rdonly(env, "DBcursor->del")); + + /* Check for invalid function flags. */ + switch (flags) { + case 0: + break; + case DB_CONSUME: + if (dbp->type != DB_QUEUE) + return (__db_ferr(env, "DBC->del", 0)); + break; + case DB_UPDATE_SECONDARY: + DB_ASSERT(env, F_ISSET(dbp, DB_AM_SECONDARY)); + break; + default: + return (__db_ferr(env, "DBcursor->del", 0)); + } + + /* + * The cursor must be initialized, return EINVAL for an invalid cursor, + * otherwise 0. + */ + if (!IS_INITIALIZED(dbc)) + return (__db_curinval(env)); + + return (0); +} + +/* + * __dbc_dup_pp -- + * DBC->dup pre/post processing. + * + * PUBLIC: int __dbc_dup_pp __P((DBC *, DBC **, u_int32_t)); + */ +int +__dbc_dup_pp(dbc, dbcp, flags) + DBC *dbc, **dbcp; + u_int32_t flags; +{ + DB *dbp; + DB_THREAD_INFO *ip; + ENV *env; + int ret; + + dbp = dbc->dbp; + env = dbp->env; + + /* + * !!! + * The actual argument checking is simple, do it inline, outside of + * the replication block. + */ + if (flags != 0 && flags != DB_POSITION) + return (__db_ferr(env, "DBcursor->dup", 0)); + + ENV_ENTER(env, ip); + ret = __dbc_dup(dbc, dbcp, flags); + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __dbc_get_pp -- + * DBC->get pre/post processing. + * + * PUBLIC: int __dbc_get_pp __P((DBC *, DBT *, DBT *, u_int32_t)); + */ +int +__dbc_get_pp(dbc, key, data, flags) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; +{ + DB *dbp; + DB_THREAD_INFO *ip; + ENV *env; + int ignore_lease, ret; + + dbp = dbc->dbp; + env = dbp->env; + + ignore_lease = LF_ISSET(DB_IGNORE_LEASE) ? 1 : 0; + LF_CLR(DB_IGNORE_LEASE); + if ((ret = __dbc_get_arg(dbc, key, data, flags)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + DEBUG_LREAD(dbc, dbc->txn, "DBcursor->get", + flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, NULL, flags); + ret = __dbc_get(dbc, key, data, flags); + + /* + * Check for master leases. + */ + if (ret == 0 && + IS_REP_MASTER(env) && IS_USING_LEASES(env) && !ignore_lease) + ret = __rep_lease_check(env, 1); + + ENV_LEAVE(env, ip); + __dbt_userfree(env, key, NULL, data); + return (ret); +} + +/* + * __dbc_get_arg -- + * Common DBC->get argument checking, used by both DBC->get and DBC->pget. + * PUBLIC: int __dbc_get_arg __P((DBC *, DBT *, DBT *, u_int32_t)); + */ +int +__dbc_get_arg(dbc, key, data, flags) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; +{ + DB *dbp; + ENV *env; + int dirty, multi, ret; + + dbp = dbc->dbp; + env = dbp->env; + + /* + * Typically in checking routines that modify the flags, we have + * to save them and restore them, because the checking routine + * calls the work routine. However, this is a pure-checking + * routine which returns to a function that calls the work routine, + * so it's OK that we do not save and restore the flags, even though + * we modify them. + * + * Check for read-modify-write validity. DB_RMW doesn't make sense + * with CDB cursors since if you're going to write the cursor, you + * had to create it with DB_WRITECURSOR. Regardless, we check for + * LOCKING_ON and not STD_LOCKING, as we don't want to disallow it. + * If this changes, confirm that DB does not itself set the DB_RMW + * flag in a path where CDB may have been configured. + */ + dirty = 0; + if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW)) { + if (!LOCKING_ON(env)) + return (__db_fnl(env, "DBcursor->get")); + if (LF_ISSET(DB_READ_UNCOMMITTED)) + dirty = 1; + LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW); + } + + multi = 0; + if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) { + multi = 1; + if (LF_ISSET(DB_MULTIPLE) && LF_ISSET(DB_MULTIPLE_KEY)) + goto multi_err; + LF_CLR(DB_MULTIPLE | DB_MULTIPLE_KEY); + } + + /* Check for invalid function flags. */ + switch (flags) { + case DB_CONSUME: + case DB_CONSUME_WAIT: + if (dirty) { + __db_errx(env, + "DB_READ_UNCOMMITTED is not supported with DB_CONSUME or DB_CONSUME_WAIT"); + return (EINVAL); + } + if (dbp->type != DB_QUEUE) + goto err; + break; + case DB_CURRENT: + case DB_FIRST: + case DB_NEXT: + case DB_NEXT_DUP: + case DB_NEXT_NODUP: + break; + case DB_LAST: + case DB_PREV: + case DB_PREV_DUP: + case DB_PREV_NODUP: + if (multi) +multi_err: return (__db_ferr(env, "DBcursor->get", 1)); + break; + case DB_GET_BOTHC: + if (dbp->type == DB_QUEUE) + goto err; + /* FALLTHROUGH */ + case DB_GET_BOTH: + case DB_GET_BOTH_RANGE: + if ((ret = __dbt_usercopy(env, data)) != 0) + goto err; + /* FALLTHROUGH */ + case DB_SET: + case DB_SET_RANGE: + if ((ret = __dbt_usercopy(env, key)) != 0) + goto err; + break; + case DB_GET_RECNO: + /* + * The one situation in which this might be legal with a + * non-RECNUM dbp is if dbp is a secondary and its primary is + * DB_AM_RECNUM. + */ + if (!F_ISSET(dbp, DB_AM_RECNUM) && + (!F_ISSET(dbp, DB_AM_SECONDARY) || + !F_ISSET(dbp->s_primary, DB_AM_RECNUM))) + goto err; + break; + case DB_SET_RECNO: + if (!F_ISSET(dbp, DB_AM_RECNUM)) + goto err; + if ((ret = __dbt_usercopy(env, key)) != 0) + goto err; + break; + default: +err: __dbt_userfree(env, key, NULL, data); + return (__db_ferr(env, "DBcursor->get", 0)); + } + + /* Check for invalid key/data flags. */ + if ((ret = __dbt_ferr(dbp, "key", key, 0)) != 0) + return (ret); + if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0) + return (ret); + + if (multi) { + if (!F_ISSET(data, DB_DBT_USERMEM)) { + __db_errx(env, + "DB_MULTIPLE/DB_MULTIPLE_KEY require DB_DBT_USERMEM be set"); + return (EINVAL); + } + if (F_ISSET(key, DB_DBT_PARTIAL) || + F_ISSET(data, DB_DBT_PARTIAL)) { + __db_errx(env, + "DB_MULTIPLE/DB_MULTIPLE_KEY do not support DB_DBT_PARTIAL"); + return (EINVAL); + } + if (data->ulen < 1024 || + data->ulen < dbp->pgsize || data->ulen % 1024 != 0) { + __db_errx(env, "%s%s", + "DB_MULTIPLE/DB_MULTIPLE_KEY buffers must be ", + "aligned, at least page size and multiples of 1KB"); + return (EINVAL); + } + } + + /* + * The cursor must be initialized for DB_CURRENT, DB_GET_RECNO, + * DB_PREV_DUP and DB_NEXT_DUP. Return EINVAL for an invalid + * cursor, otherwise 0. + */ + if (!IS_INITIALIZED(dbc) && (flags == DB_CURRENT || + flags == DB_GET_RECNO || + flags == DB_NEXT_DUP || flags == DB_PREV_DUP)) + return (__db_curinval(env)); + + /* Check for consistent transaction usage. */ + if (LF_ISSET(DB_RMW) && + (ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0) + return (ret); + + return (0); +} + +/* + * __db_secondary_close_pp -- + * DB->close for secondaries + * + * PUBLIC: int __db_secondary_close_pp __P((DB *, u_int32_t)); + */ +int +__db_secondary_close_pp(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = dbp->env; + ret = 0; + + /* + * As a DB handle destructor, we can't fail. + * + * !!! + * The actual argument checking is simple, do it inline, outside of + * the replication block. + */ + if (flags != 0 && flags != DB_NOSYNC) + ret = __db_ferr(env, "DB->close", 0); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (t_ret = __db_rep_enter(dbp, 0, 0, 0)) != 0) { + handle_check = 0; + if (ret == 0) + ret = t_ret; + } + + if ((t_ret = __db_secondary_close(dbp, flags)) != 0 && ret == 0) + ret = t_ret; + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __dbc_pget_pp -- + * DBC->pget pre/post processing. + * + * PUBLIC: int __dbc_pget_pp __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); + */ +int +__dbc_pget_pp(dbc, skey, pkey, data, flags) + DBC *dbc; + DBT *skey, *pkey, *data; + u_int32_t flags; +{ + DB *dbp; + DB_THREAD_INFO *ip; + ENV *env; + int ignore_lease, ret; + + dbp = dbc->dbp; + env = dbp->env; + + ignore_lease = LF_ISSET(DB_IGNORE_LEASE) ? 1 : 0; + LF_CLR(DB_IGNORE_LEASE); + if ((ret = __dbc_pget_arg(dbc, pkey, flags)) != 0 || + (ret = __dbc_get_arg(dbc, skey, data, flags)) != 0) + return (ret); + + ENV_ENTER(env, ip); + ret = __dbc_pget(dbc, skey, pkey, data, flags); + /* + * Check for master leases. + */ + if (ret == 0 && + IS_REP_MASTER(env) && IS_USING_LEASES(env) && !ignore_lease) + ret = __rep_lease_check(env, 1); + + ENV_LEAVE(env, ip); + + __dbt_userfree(env, skey, pkey, data); + return (ret); +} + +/* + * __dbc_pget_arg -- + * Check DBC->pget arguments. + */ +static int +__dbc_pget_arg(dbc, pkey, flags) + DBC *dbc; + DBT *pkey; + u_int32_t flags; +{ + DB *dbp; + ENV *env; + int ret; + + dbp = dbc->dbp; + env = dbp->env; + + if (!F_ISSET(dbp, DB_AM_SECONDARY)) { + __db_errx(env, + "DBcursor->pget may only be used on secondary indices"); + return (EINVAL); + } + + if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) { + __db_errx(env, + "DB_MULTIPLE and DB_MULTIPLE_KEY may not be used on secondary indices"); + return (EINVAL); + } + + switch (LF_ISSET(DB_OPFLAGS_MASK)) { + case DB_CONSUME: + case DB_CONSUME_WAIT: + /* These flags make no sense on a secondary index. */ + return (__db_ferr(env, "DBcursor->pget", 0)); + case DB_GET_BOTH: + case DB_GET_BOTH_RANGE: + /* BOTH is "get both the primary and the secondary". */ + if (pkey == NULL) { + __db_errx(env, + "%s requires both a secondary and a primary key", + LF_ISSET(DB_GET_BOTH) ? + "DB_GET_BOTH" : "DB_GET_BOTH_RANGE"); + return (EINVAL); + } + if ((ret = __dbt_usercopy(env, pkey)) != 0) + return (ret); + break; + default: + /* __dbc_get_arg will catch the rest. */ + break; + } + + /* + * We allow the pkey field to be NULL, so that we can make the + * two-DBT get calls into wrappers for the three-DBT ones. + */ + if (pkey != NULL && + (ret = __dbt_ferr(dbp, "primary key", pkey, 0)) != 0) + return (ret); + + /* But the pkey field can't be NULL if we're doing a DB_GET_BOTH. */ + if (pkey == NULL && (flags & DB_OPFLAGS_MASK) == DB_GET_BOTH) { + __db_errx(env, + "DB_GET_BOTH on a secondary index requires a primary key"); + return (EINVAL); + } + return (0); +} + +/* + * __dbc_put_pp -- + * DBC->put pre/post processing. + * + * PUBLIC: int __dbc_put_pp __P((DBC *, DBT *, DBT *, u_int32_t)); + */ +int +__dbc_put_pp(dbc, key, data, flags) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; +{ + DB *dbp; + DB_THREAD_INFO *ip; + ENV *env; + int ret; + + dbp = dbc->dbp; + env = dbp->env; + + if ((ret = __dbc_put_arg(dbc, key, data, flags)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + /* Check for consistent transaction usage. */ + if ((ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0) + goto err; + + DEBUG_LWRITE(dbc, dbc->txn, "DBcursor->put", + flags == DB_KEYFIRST || flags == DB_KEYLAST || + flags == DB_NODUPDATA || flags == DB_UPDATE_SECONDARY ? + key : NULL, data, flags); + ret = __dbc_put(dbc, key, data, flags); + +err: ENV_LEAVE(env, ip); + __dbt_userfree(env, key, NULL, data); + return (ret); +} + +/* + * __dbc_put_arg -- + * Check DBC->put arguments. + */ +static int +__dbc_put_arg(dbc, key, data, flags) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; +{ + DB *dbp; + ENV *env; + int key_flags, ret; + + dbp = dbc->dbp; + env = dbp->env; + key_flags = 0; + + /* Check for changes to a read-only tree. */ + if (DB_IS_READONLY(dbp)) + return (__db_rdonly(env, "DBcursor->put")); + + /* Check for puts on a secondary. */ + if (F_ISSET(dbp, DB_AM_SECONDARY)) { + if (flags == DB_UPDATE_SECONDARY) + flags = 0; + else { + __db_errx(env, + "DBcursor->put forbidden on secondary indices"); + return (EINVAL); + } + } + + if ((ret = __dbt_usercopy(env, data)) != 0) + return (ret); + + /* Check for invalid function flags. */ + switch (flags) { + case DB_AFTER: + case DB_BEFORE: + switch (dbp->type) { + case DB_BTREE: + case DB_HASH: /* Only with unsorted duplicates. */ + if (!F_ISSET(dbp, DB_AM_DUP)) + goto err; + if (dbp->dup_compare != NULL) + goto err; + break; + case DB_QUEUE: /* Not permitted. */ + goto err; + case DB_RECNO: /* Only with mutable record numbers. */ + if (!F_ISSET(dbp, DB_AM_RENUMBER)) + goto err; + key_flags = key == NULL ? 0 : 1; + break; + case DB_UNKNOWN: + default: + goto err; + } + break; + case DB_CURRENT: + /* + * If there is a comparison function, doing a DB_CURRENT + * must not change the part of the data item that is used + * for the comparison. + */ + break; + case DB_NODUPDATA: + if (!F_ISSET(dbp, DB_AM_DUPSORT)) + goto err; + /* FALLTHROUGH */ + case DB_KEYFIRST: + case DB_KEYLAST: + case DB_OVERWRITE_DUP: + key_flags = 1; + if ((ret = __dbt_usercopy(env, key)) != 0) + return (ret); + break; + default: +err: return (__db_ferr(env, "DBcursor->put", 0)); + } + + /* + * Check for invalid key/data flags. The key may reasonably be NULL + * if DB_AFTER or DB_BEFORE is set and the application doesn't care + * about the returned key, or if the DB_CURRENT flag is set. + */ + if (key_flags && (ret = __dbt_ferr(dbp, "key", key, 0)) != 0) + return (ret); + if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0) + return (ret); + + /* + * The key parameter should not be NULL or have the "partial" flag set + * in a put call unless the user doesn't care about a key value we'd + * return. The user tells us they don't care about the returned key by + * setting the key parameter to NULL or configuring the key DBT to not + * return any information. (Returned keys from a put are always record + * numbers, and returning part of a record number doesn't make sense: + * only accept a partial return if the length returned is 0.) + */ + if (key_flags && F_ISSET(key, DB_DBT_PARTIAL) && key->dlen != 0) + return (__db_ferr(env, "key DBT", 0)); + + /* + * The cursor must be initialized for anything other than DB_KEYFIRST, + * DB_KEYLAST or zero: return EINVAL for an invalid cursor, otherwise 0. + */ + if (!IS_INITIALIZED(dbc) && flags != 0 && flags != DB_KEYFIRST && + flags != DB_KEYLAST && flags != DB_NODUPDATA && + flags != DB_OVERWRITE_DUP) + return (__db_curinval(env)); + + return (0); +} + +/* + * __dbt_ferr -- + * Check a DBT for flag errors. + */ +static int +__dbt_ferr(dbp, name, dbt, check_thread) + const DB *dbp; + const char *name; + const DBT *dbt; + int check_thread; +{ + ENV *env; + int ret; + + env = dbp->env; + + /* + * Check for invalid DBT flags. We allow any of the flags to be + * specified to any DB or DBcursor call so that applications can + * set DB_DBT_MALLOC when retrieving a data item from a secondary + * database and then specify that same DBT as a key to a primary + * database, without having to clear flags. + */ + if ((ret = __db_fchk(env, name, dbt->flags, DB_DBT_APPMALLOC | + DB_DBT_BULK | DB_DBT_DUPOK | DB_DBT_MALLOC | DB_DBT_REALLOC | + DB_DBT_USERCOPY | DB_DBT_USERMEM | DB_DBT_PARTIAL)) != 0) + return (ret); + switch (F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC | + DB_DBT_USERCOPY | DB_DBT_USERMEM)) { + case 0: + case DB_DBT_MALLOC: + case DB_DBT_REALLOC: + case DB_DBT_USERCOPY: + case DB_DBT_USERMEM: + break; + default: + return (__db_ferr(env, name, 1)); + } + + if (F_ISSET(dbt, DB_DBT_BULK) && F_ISSET(dbt, DB_DBT_PARTIAL)) { + __db_errx(env, + "Bulk and partial operations cannot be combined on %s DBT", name); + return (EINVAL); + } + + if (check_thread && DB_IS_THREADED(dbp) && + !F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC | + DB_DBT_USERCOPY | DB_DBT_USERMEM)) { + __db_errx(env, + "DB_THREAD mandates memory allocation flag on %s DBT", + name); + return (EINVAL); + } + return (0); +} + +/* + * __db_curinval + * Report that a cursor is in an invalid state. + */ +static int +__db_curinval(env) + const ENV *env; +{ + __db_errx(env, + "Cursor position must be set before performing this operation"); + return (EINVAL); +} + +/* + * __db_txn_auto_init -- + * Handle DB_AUTO_COMMIT initialization. + * + * PUBLIC: int __db_txn_auto_init __P((ENV *, DB_THREAD_INFO *, DB_TXN **)); + */ +int +__db_txn_auto_init(env, ip, txnidp) + ENV *env; + DB_THREAD_INFO *ip; + DB_TXN **txnidp; +{ + /* + * Method calls where applications explicitly specify DB_AUTO_COMMIT + * require additional validation: the DB_AUTO_COMMIT flag cannot be + * specified if a transaction cookie is also specified, nor can the + * flag be specified in a non-transactional environment. + */ + if (*txnidp != NULL) { + __db_errx(env, + "DB_AUTO_COMMIT may not be specified along with a transaction handle"); + return (EINVAL); + } + + if (!TXN_ON(env)) { + __db_errx(env, + "DB_AUTO_COMMIT may not be specified in non-transactional environment"); + return (EINVAL); + } + + /* + * Our caller checked to see if replication is making a state change. + * Don't call the user-level API (which would repeat that check). + */ + return (__txn_begin(env, ip, NULL, txnidp, 0)); +} + +/* + * __db_txn_auto_resolve -- + * Resolve local transactions. + * + * PUBLIC: int __db_txn_auto_resolve __P((ENV *, DB_TXN *, int, int)); + */ +int +__db_txn_auto_resolve(env, txn, nosync, ret) + ENV *env; + DB_TXN *txn; + int nosync, ret; +{ + int t_ret; + + /* + * We're resolving a transaction for the user, and must decrement the + * replication handle count. Call the user-level API. + */ + if (ret == 0) + return (__txn_commit(txn, nosync ? DB_TXN_NOSYNC : 0)); + + if ((t_ret = __txn_abort(txn)) != 0) + return (__env_panic(env, t_ret)); + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_join.c b/src/libs/resiprocate/contrib/db/db/db_join.c new file mode 100644 index 00000000..05c11a4b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_join.c @@ -0,0 +1,940 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1998-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_join.h" +#include "dbinc/btree.h" +#include "dbinc/lock.h" + +static int __db_join_close_pp __P((DBC *)); +static int __db_join_cmp __P((const void *, const void *)); +static int __db_join_del __P((DBC *, u_int32_t)); +static int __db_join_get __P((DBC *, DBT *, DBT *, u_int32_t)); +static int __db_join_get_pp __P((DBC *, DBT *, DBT *, u_int32_t)); +static int __db_join_getnext __P((DBC *, DBT *, DBT *, u_int32_t, u_int32_t)); +static int __db_join_primget __P((DB *, DB_THREAD_INFO *, + DB_TXN *, DB_LOCKER *, DBT *, DBT *, u_int32_t)); +static int __db_join_put __P((DBC *, DBT *, DBT *, u_int32_t)); + +/* + * Check to see if the Nth secondary cursor of join cursor jc is pointing + * to a sorted duplicate set. + */ +#define SORTED_SET(jc, n) ((jc)->j_curslist[(n)]->dbp->dup_compare != NULL) + +/* + * This is the duplicate-assisted join functionality. Right now we're + * going to write it such that we return one item at a time, although + * I think we may need to optimize it to return them all at once. + * It should be easier to get it working this way, and I believe that + * changing it should be fairly straightforward. + * + * We optimize the join by sorting cursors from smallest to largest + * cardinality. In most cases, this is indeed optimal. However, if + * a cursor with large cardinality has very few data in common with the + * first cursor, it is possible that the join will be made faster by + * putting it earlier in the cursor list. Since we have no way to detect + * cases like this, we simply provide a flag, DB_JOIN_NOSORT, which retains + * the sort order specified by the caller, who may know more about the + * structure of the data. + * + * The first cursor moves sequentially through the duplicate set while + * the others search explicitly for the duplicate in question. + * + */ + +/* + * __db_join -- + * This is the interface to the duplicate-assisted join functionality. + * In the same way that cursors mark a position in a database, a cursor + * can mark a position in a join. While most cursors are created by the + * cursor method of a DB, join cursors are created through an explicit + * call to DB->join. + * + * The curslist is an array of existing, initialized cursors and primary + * is the DB of the primary file. The data item that joins all the + * cursors in the curslist is used as the key into the primary and that + * key and data are returned. When no more items are left in the join + * set, the c_next operation off the join cursor will return DB_NOTFOUND. + * + * PUBLIC: int __db_join __P((DB *, DBC **, DBC **, u_int32_t)); + */ +int +__db_join(primary, curslist, dbcp, flags) + DB *primary; + DBC **curslist, **dbcp; + u_int32_t flags; +{ + DBC *dbc; + ENV *env; + JOIN_CURSOR *jc; + size_t ncurs, nslots; + u_int32_t i; + int ret; + + env = primary->env; + dbc = NULL; + jc = NULL; + + if ((ret = __os_calloc(env, 1, sizeof(DBC), &dbc)) != 0) + goto err; + + if ((ret = __os_calloc(env, 1, sizeof(JOIN_CURSOR), &jc)) != 0) + goto err; + + if ((ret = __os_malloc(env, 256, &jc->j_key.data)) != 0) + goto err; + jc->j_key.ulen = 256; + F_SET(&jc->j_key, DB_DBT_USERMEM); + + F_SET(&jc->j_rdata, DB_DBT_REALLOC); + + for (jc->j_curslist = curslist; + *jc->j_curslist != NULL; jc->j_curslist++) + ; + + /* + * The number of cursor slots we allocate is one greater than + * the number of cursors involved in the join, because the + * list is NULL-terminated. + */ + ncurs = (size_t)(jc->j_curslist - curslist); + nslots = ncurs + 1; + + /* + * !!! -- A note on the various lists hanging off jc. + * + * j_curslist is the initial NULL-terminated list of cursors passed + * into __db_join. The original cursors are not modified; pristine + * copies are required because, in databases with unsorted dups, we + * must reset all of the secondary cursors after the first each + * time the first one is incremented, or else we will lose data + * which happen to be sorted differently in two different cursors. + * + * j_workcurs is where we put those copies that we're planning to + * work with. They're lazily c_dup'ed from j_curslist as we need + * them, and closed when the join cursor is closed or when we need + * to reset them to their original values (in which case we just + * c_dup afresh). + * + * j_fdupcurs is an array of cursors which point to the first + * duplicate in the duplicate set that contains the data value + * we're currently interested in. We need this to make + * __db_join_get correctly return duplicate duplicates; i.e., if a + * given data value occurs twice in the set belonging to cursor #2, + * and thrice in the set belonging to cursor #3, and once in all + * the other cursors, successive calls to __db_join_get need to + * return that data item six times. To make this happen, each time + * cursor N is allowed to advance to a new datum, all cursors M + * such that M > N have to be reset to the first duplicate with + * that datum, so __db_join_get will return all the dup-dups again. + * We could just reset them to the original cursor from j_curslist, + * but that would be a bit slower in the unsorted case and a LOT + * slower in the sorted one. + * + * j_exhausted is a list of boolean values which represent + * whether or not their corresponding cursors are "exhausted", + * i.e. whether the datum under the corresponding cursor has + * been found not to exist in any unreturned combinations of + * later secondary cursors, in which case they are ready to be + * incremented. + */ + + /* We don't want to free regions whose callocs have failed. */ + jc->j_curslist = NULL; + jc->j_workcurs = NULL; + jc->j_fdupcurs = NULL; + jc->j_exhausted = NULL; + + if ((ret = __os_calloc(env, nslots, sizeof(DBC *), + &jc->j_curslist)) != 0) + goto err; + if ((ret = __os_calloc(env, nslots, sizeof(DBC *), + &jc->j_workcurs)) != 0) + goto err; + if ((ret = __os_calloc(env, nslots, sizeof(DBC *), + &jc->j_fdupcurs)) != 0) + goto err; + if ((ret = __os_calloc(env, nslots, sizeof(u_int8_t), + &jc->j_exhausted)) != 0) + goto err; + for (i = 0; curslist[i] != NULL; i++) { + jc->j_curslist[i] = curslist[i]; + jc->j_workcurs[i] = NULL; + jc->j_fdupcurs[i] = NULL; + jc->j_exhausted[i] = 0; + } + jc->j_ncurs = (u_int32_t)ncurs; + + /* + * If DB_JOIN_NOSORT is not set, optimize secondary cursors by + * sorting in order of increasing cardinality. + */ + if (!LF_ISSET(DB_JOIN_NOSORT)) + qsort(jc->j_curslist, ncurs, sizeof(DBC *), __db_join_cmp); + + /* + * We never need to reset the 0th cursor, so there's no + * solid reason to use workcurs[0] rather than curslist[0] in + * join_get. Nonetheless, it feels cleaner to do it for symmetry, + * and this is the most logical place to copy it. + * + * !!! + * There's no need to close the new cursor if we goto err only + * because this is the last thing that can fail. Modifier of this + * function beware! + */ + if ((ret = + __dbc_dup(jc->j_curslist[0], jc->j_workcurs, DB_POSITION)) != 0) + goto err; + + dbc->close = dbc->c_close = __db_join_close_pp; + dbc->del = dbc->c_del = __db_join_del; + dbc->get = dbc->c_get = __db_join_get_pp; + dbc->put = dbc->c_put = __db_join_put; + dbc->internal = (DBC_INTERNAL *)jc; + dbc->dbp = primary; + jc->j_primary = primary; + + /* Stash the first cursor's transaction here for easy access. */ + dbc->txn = curslist[0]->txn; + + *dbcp = dbc; + + MUTEX_LOCK(env, primary->mutex); + TAILQ_INSERT_TAIL(&primary->join_queue, dbc, links); + MUTEX_UNLOCK(env, primary->mutex); + + return (0); + +err: if (jc != NULL) { + if (jc->j_curslist != NULL) + __os_free(env, jc->j_curslist); + if (jc->j_workcurs != NULL) { + if (jc->j_workcurs[0] != NULL) + (void)__dbc_close(jc->j_workcurs[0]); + __os_free(env, jc->j_workcurs); + } + if (jc->j_fdupcurs != NULL) + __os_free(env, jc->j_fdupcurs); + if (jc->j_exhausted != NULL) + __os_free(env, jc->j_exhausted); + __os_free(env, jc); + } + if (dbc != NULL) + __os_free(env, dbc); + return (ret); +} + +/* + * __db_join_close_pp -- + * DBC->close pre/post processing for join cursors. + */ +static int +__db_join_close_pp(dbc) + DBC *dbc; +{ + DB *dbp; + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + dbp = dbc->dbp; + env = dbp->env; + + ENV_ENTER(env, ip); + + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && + (ret = __db_rep_enter(dbp, 1, 0, dbc->txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + ret = __db_join_close(dbc); + + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + +err: ENV_LEAVE(env, ip); + return (ret); +} + +static int +__db_join_put(dbc, key, data, flags) + DBC *dbc; + DBT *key; + DBT *data; + u_int32_t flags; +{ + COMPQUIET(dbc, NULL); + COMPQUIET(key, NULL); + COMPQUIET(data, NULL); + COMPQUIET(flags, 0); + return (EINVAL); +} + +static int +__db_join_del(dbc, flags) + DBC *dbc; + u_int32_t flags; +{ + COMPQUIET(dbc, NULL); + COMPQUIET(flags, 0); + return (EINVAL); +} + +/* + * __db_join_get_pp -- + * DBjoin->get pre/post processing. + */ +static int +__db_join_get_pp(dbc, key, data, flags) + DBC *dbc; + DBT *key, *data; + u_int32_t flags; +{ + DB *dbp; + DB_THREAD_INFO *ip; + ENV *env; + u_int32_t handle_check, save_flags; + int ret, t_ret; + + dbp = dbc->dbp; + env = dbp->env; + + /* Save the original flags value. */ + save_flags = flags; + + if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW)) { + if (!LOCKING_ON(env)) + return (__db_fnl(env, "DBC->get")); + LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW); + } + + switch (flags) { + case 0: + case DB_JOIN_ITEM: + break; + default: + return (__db_ferr(env, "DBC->get", 0)); + } + + /* + * A partial get of the key of a join cursor don't make much sense; + * the entire key is necessary to query the primary database + * and find the datum, and so regardless of the size of the key + * it would not be a performance improvement. Since it would require + * special handling, we simply disallow it. + * + * A partial get of the data, however, potentially makes sense (if + * all possible data are a predictable large structure, for instance) + * and causes us no headaches, so we permit it. + */ + if (F_ISSET(key, DB_DBT_PARTIAL)) { + __db_errx(env, + "DB_DBT_PARTIAL may not be set on key during join_get"); + return (EINVAL); + } + + ENV_ENTER(env, ip); + + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && + (ret = __db_rep_enter(dbp, 1, 0, dbc->txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + /* Restore the original flags value. */ + flags = save_flags; + + ret = __db_join_get(dbc, key, data, flags); + + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + +err: ENV_LEAVE(env, ip); + __dbt_userfree(env, key, NULL, NULL); + return (ret); +} + +static int +__db_join_get(dbc, key_arg, data_arg, flags) + DBC *dbc; + DBT *key_arg, *data_arg; + u_int32_t flags; +{ + DB *dbp; + DBC *cp; + DBT *key_n, key_n_mem; + ENV *env; + JOIN_CURSOR *jc; + int db_manage_data, ret; + u_int32_t i, j, operation, opmods; + + dbp = dbc->dbp; + env = dbp->env; + jc = (JOIN_CURSOR *)dbc->internal; + + operation = LF_ISSET(DB_OPFLAGS_MASK); + + /* !!! + * If the set of flags here changes, check that __db_join_primget + * is updated to handle them properly. + */ + opmods = LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW); + + /* + * Since we are fetching the key as a datum in the secondary indices, + * we must be careful of caller-specified DB_DBT_* memory + * management flags. If necessary, use a stack-allocated DBT; + * we'll appropriately copy and/or allocate the data later. + */ + if (F_ISSET(key_arg, + DB_DBT_MALLOC | DB_DBT_USERCOPY | DB_DBT_USERMEM)) { + /* We just use the default buffer; no need to go malloc. */ + key_n = &key_n_mem; + memset(key_n, 0, sizeof(DBT)); + } else { + /* + * Either DB_DBT_REALLOC or the default buffer will work + * fine if we have to reuse it, as we do. + */ + key_n = key_arg; + } + if (F_ISSET(key_arg, DB_DBT_USERCOPY)) + key_arg->data = NULL; + + /* + * If our last attempt to do a get on the primary key failed, + * short-circuit the join and try again with the same key. + */ + if (F_ISSET(jc, JOIN_RETRY)) + goto samekey; + F_CLR(jc, JOIN_RETRY); + +retry: ret = __dbc_get(jc->j_workcurs[0], &jc->j_key, key_n, + opmods | (jc->j_exhausted[0] ? DB_NEXT_DUP : DB_CURRENT)); + + if (ret == DB_BUFFER_SMALL) { + jc->j_key.ulen <<= 1; + if ((ret = __os_realloc(env, + jc->j_key.ulen, &jc->j_key.data)) != 0) + goto mem_err; + goto retry; + } + + /* + * If ret == DB_NOTFOUND, we're out of elements of the first + * secondary cursor. This is how we finally finish the join + * if all goes well. + */ + if (ret != 0) + goto err; + + /* + * If jc->j_exhausted[0] == 1, we've just advanced the first cursor, + * and we're going to want to advance all the cursors that point to + * the first member of a duplicate duplicate set (j_fdupcurs[1..N]). + * Close all the cursors in j_fdupcurs; we'll reopen them the + * first time through the upcoming loop. + */ + for (i = 1; i < jc->j_ncurs; i++) { + if (jc->j_fdupcurs[i] != NULL && + (ret = __dbc_close(jc->j_fdupcurs[i])) != 0) + goto err; + jc->j_fdupcurs[i] = NULL; + } + + /* + * If jc->j_curslist[1] == NULL, we have only one cursor in the join. + * Thus, we can safely increment that one cursor on each call + * to __db_join_get, and we signal this by setting jc->j_exhausted[0] + * right away. + * + * Otherwise, reset jc->j_exhausted[0] to 0, so that we don't + * increment it until we know we're ready to. + */ + if (jc->j_curslist[1] == NULL) + jc->j_exhausted[0] = 1; + else + jc->j_exhausted[0] = 0; + + /* We have the first element; now look for it in the other cursors. */ + for (i = 1; i < jc->j_ncurs; i++) { + DB_ASSERT(env, jc->j_curslist[i] != NULL); + if (jc->j_workcurs[i] == NULL) + /* If this is NULL, we need to dup curslist into it. */ + if ((ret = __dbc_dup(jc->j_curslist[i], + &jc->j_workcurs[i], DB_POSITION)) != 0) + goto err; + +retry2: cp = jc->j_workcurs[i]; + + if ((ret = __db_join_getnext(cp, &jc->j_key, key_n, + jc->j_exhausted[i], opmods)) == DB_NOTFOUND) { + /* + * jc->j_workcurs[i] has no more of the datum we're + * interested in. Go back one cursor and get + * a new dup. We can't just move to a new + * element of the outer relation, because that way + * we might miss duplicate duplicates in cursor i-1. + * + * If this takes us back to the first cursor, + * -then- we can move to a new element of the outer + * relation. + */ + --i; + jc->j_exhausted[i] = 1; + + if (i == 0) { + for (j = 1; jc->j_workcurs[j] != NULL; j++) { + /* + * We're moving to a new element of + * the first secondary cursor. If + * that cursor is sorted, then any + * other sorted cursors can be safely + * reset to the first duplicate + * duplicate in the current set if we + * have a pointer to it (we can't just + * leave them be, or we'll miss + * duplicate duplicates in the outer + * relation). + * + * If the first cursor is unsorted, or + * if cursor j is unsorted, we can + * make no assumptions about what + * we're looking for next or where it + * will be, so we reset to the very + * beginning (setting workcurs NULL + * will achieve this next go-round). + * + * XXX: This is likely to break + * horribly if any two cursors are + * both sorted, but have different + * specified sort functions. For, + * now, we dismiss this as pathology + * and let strange things happen--we + * can't make rope childproof. + */ + if ((ret = __dbc_close( + jc->j_workcurs[j])) != 0) + goto err; + if (!SORTED_SET(jc, 0) || + !SORTED_SET(jc, j) || + jc->j_fdupcurs[j] == NULL) + /* + * Unsafe conditions; + * reset fully. + */ + jc->j_workcurs[j] = NULL; + else + /* Partial reset suffices. */ + if ((__dbc_dup( + jc->j_fdupcurs[j], + &jc->j_workcurs[j], + DB_POSITION)) != 0) + goto err; + jc->j_exhausted[j] = 0; + } + goto retry; + /* NOTREACHED */ + } + + /* + * We're about to advance the cursor and need to + * reset all of the workcurs[j] where j>i, so that + * we don't miss any duplicate duplicates. + */ + for (j = i + 1; + jc->j_workcurs[j] != NULL; + j++) { + if ((ret = + __dbc_close(jc->j_workcurs[j])) != 0) + goto err; + jc->j_exhausted[j] = 0; + if (jc->j_fdupcurs[j] == NULL) + jc->j_workcurs[j] = NULL; + else if ((ret = __dbc_dup(jc->j_fdupcurs[j], + &jc->j_workcurs[j], DB_POSITION)) != 0) + goto err; + } + goto retry2; + /* NOTREACHED */ + } + + if (ret == DB_BUFFER_SMALL) { + jc->j_key.ulen <<= 1; + if ((ret = __os_realloc(env, jc->j_key.ulen, + &jc->j_key.data)) != 0) { +mem_err: __db_errx(env, + "Allocation failed for join key, len = %lu", + (u_long)jc->j_key.ulen); + goto err; + } + goto retry2; + } + + if (ret != 0) + goto err; + + /* + * If we made it this far, we've found a matching + * datum in cursor i. Mark the current cursor + * unexhausted, so we don't miss any duplicate + * duplicates the next go-round--unless this is the + * very last cursor, in which case there are none to + * miss, and we'll need that exhausted flag to finally + * get a DB_NOTFOUND and move on to the next datum in + * the outermost cursor. + */ + if (i + 1 != jc->j_ncurs) + jc->j_exhausted[i] = 0; + else + jc->j_exhausted[i] = 1; + + /* + * If jc->j_fdupcurs[i] is NULL and the ith cursor's dups are + * sorted, then we're here for the first time since advancing + * cursor 0, and we have a new datum of interest. + * jc->j_workcurs[i] points to the beginning of a set of + * duplicate duplicates; store this into jc->j_fdupcurs[i]. + */ + if (SORTED_SET(jc, i) && jc->j_fdupcurs[i] == NULL && (ret = + __dbc_dup(cp, &jc->j_fdupcurs[i], DB_POSITION)) != 0) + goto err; + } + +err: if (ret != 0) + return (ret); + + if (0) { +samekey: /* + * Get the key we tried and failed to return last time; + * it should be the current datum of all the secondary cursors. + */ + if ((ret = __dbc_get(jc->j_workcurs[0], + &jc->j_key, key_n, DB_CURRENT | opmods)) != 0) + return (ret); + F_CLR(jc, JOIN_RETRY); + } + + /* + * ret == 0; we have a key to return. + * + * If DB_DBT_USERMEM or DB_DBT_MALLOC is set, we need to copy the key + * back into the dbt we were given for the key; call __db_retcopy. + * Otherwise, assert that we do not need to copy anything and proceed. + */ + DB_ASSERT(env, F_ISSET(key_arg, DB_DBT_USERMEM | DB_DBT_MALLOC | + DB_DBT_USERCOPY) || key_n == key_arg); + + if ((F_ISSET(key_arg, DB_DBT_USERMEM | DB_DBT_MALLOC | + DB_DBT_USERCOPY)) && + (ret = __db_retcopy(env, + key_arg, key_n->data, key_n->size, NULL, NULL)) != 0) { + /* + * The retcopy failed, most commonly because we have a user + * buffer for the key which is too small. Set things up to + * retry next time, and return. + */ + F_SET(jc, JOIN_RETRY); + return (ret); + } + + /* + * If DB_JOIN_ITEM is set, we return it; otherwise we do the lookup + * in the primary and then return. + */ + if (operation == DB_JOIN_ITEM) + return (0); + + /* + * If data_arg->flags == 0--that is, if DB is managing the + * data DBT's memory--it's not safe to just pass the DBT + * through to the primary get call, since we don't want that + * memory to belong to the primary DB handle (and if the primary + * is free-threaded, it can't anyway). + * + * Instead, use memory that is managed by the join cursor, in + * jc->j_rdata. + */ + if (!F_ISSET(data_arg, DB_DBT_MALLOC | DB_DBT_REALLOC | + DB_DBT_USERMEM | DB_DBT_USERCOPY)) + db_manage_data = 1; + else + db_manage_data = 0; + if ((ret = __db_join_primget(jc->j_primary, dbc->thread_info, + jc->j_curslist[0]->txn, jc->j_curslist[0]->locker, key_n, + db_manage_data ? &jc->j_rdata : data_arg, opmods)) != 0) { + if (ret == DB_NOTFOUND) { + if (LF_ISSET(DB_READ_UNCOMMITTED) || + (jc->j_curslist[0]->txn != NULL && F_ISSET( + jc->j_curslist[0]->txn, TXN_READ_UNCOMMITTED))) + goto retry; + /* + * If ret == DB_NOTFOUND, the primary and secondary + * are out of sync; every item in each secondary + * should correspond to something in the primary, + * or we shouldn't have done the join this way. + * Wail. + */ + ret = __db_secondary_corrupt(jc->j_primary); + } else + /* + * The get on the primary failed for some other + * reason, most commonly because we're using a user + * buffer that's not big enough. Flag our failure + * so we can return the same key next time. + */ + F_SET(jc, JOIN_RETRY); + } + if (db_manage_data && ret == 0) { + data_arg->data = jc->j_rdata.data; + data_arg->size = jc->j_rdata.size; + } + + return (ret); +} + +/* + * __db_join_close -- + * DBC->close for join cursors. + * + * PUBLIC: int __db_join_close __P((DBC *)); + */ +int +__db_join_close(dbc) + DBC *dbc; +{ + DB *dbp; + DB_THREAD_INFO *ip; + ENV *env; + JOIN_CURSOR *jc; + int ret, t_ret; + u_int32_t i; + + jc = (JOIN_CURSOR *)dbc->internal; + dbp = dbc->dbp; + env = dbp->env; + ret = t_ret = 0; + + /* + * Remove from active list of join cursors. Note that this + * must happen before any action that can fail and return, or else + * __db_close may loop indefinitely. + */ + MUTEX_LOCK(env, dbp->mutex); + TAILQ_REMOVE(&dbp->join_queue, dbc, links); + MUTEX_UNLOCK(env, dbp->mutex); + + ENV_ENTER(env, ip); + /* + * Close any open scratch cursors. In each case, there may + * not be as many outstanding as there are cursors in + * curslist, but we want to close whatever's there. + * + * If any close fails, there's no reason not to close everything else; + * we'll just return the error code of the last one to fail. There's + * not much the caller can do anyway, since these cursors only exist + * hanging off a db-internal data structure that they shouldn't be + * mucking with. + */ + for (i = 0; i < jc->j_ncurs; i++) { + if (jc->j_workcurs[i] != NULL && + (t_ret = __dbc_close(jc->j_workcurs[i])) != 0) + ret = t_ret; + if (jc->j_fdupcurs[i] != NULL && + (t_ret = __dbc_close(jc->j_fdupcurs[i])) != 0) + ret = t_ret; + } + ENV_LEAVE(env, ip); + + __os_free(env, jc->j_exhausted); + __os_free(env, jc->j_curslist); + __os_free(env, jc->j_workcurs); + __os_free(env, jc->j_fdupcurs); + __os_free(env, jc->j_key.data); + if (jc->j_rdata.data != NULL) + __os_ufree(env, jc->j_rdata.data); + __os_free(env, jc); + __os_free(env, dbc); + + return (ret); +} + +/* + * __db_join_getnext -- + * This function replaces the DBC_CONTINUE and DBC_KEYSET + * functionality inside the various cursor get routines. + * + * If exhausted == 0, we're not done with the current datum; + * return it if it matches "matching", otherwise search + * using DB_GET_BOTHC (which is faster than iteratively doing + * DB_NEXT_DUP) forward until we find one that does. + * + * If exhausted == 1, we are done with the current datum, so just + * leap forward to searching NEXT_DUPs. + * + * If no matching datum exists, returns DB_NOTFOUND, else 0. + */ +static int +__db_join_getnext(dbc, key, data, exhausted, opmods) + DBC *dbc; + DBT *key, *data; + u_int32_t exhausted, opmods; +{ + int ret, cmp; + DB *dbp; + DBT ldata; + int (*func) __P((DB *, const DBT *, const DBT *)); + + dbp = dbc->dbp; + func = (dbp->dup_compare == NULL) ? __bam_defcmp : dbp->dup_compare; + + switch (exhausted) { + case 0: + /* + * We don't want to step on data->data; use a new + * DBT and malloc so we don't step on dbc's rdata memory. + */ + memset(&ldata, 0, sizeof(DBT)); + F_SET(&ldata, DB_DBT_MALLOC); + if ((ret = __dbc_get(dbc, + key, &ldata, opmods | DB_CURRENT)) != 0) + break; + cmp = func(dbp, data, &ldata); + if (cmp == 0) { + /* + * We have to return the real data value. Copy + * it into data, then free the buffer we malloc'ed + * above. + */ + if ((ret = __db_retcopy(dbp->env, data, ldata.data, + ldata.size, &data->data, &data->size)) != 0) + return (ret); + __os_ufree(dbp->env, ldata.data); + return (0); + } + + /* + * Didn't match--we want to fall through and search future + * dups. We just forget about ldata and free + * its buffer--data contains the value we're searching for. + */ + __os_ufree(dbp->env, ldata.data); + /* FALLTHROUGH */ + case 1: + ret = __dbc_get(dbc, key, data, opmods | DB_GET_BOTHC); + break; + default: + ret = EINVAL; + break; + } + + return (ret); +} + +/* + * __db_join_cmp -- + * Comparison function for sorting DBCs in cardinality order. + */ +static int +__db_join_cmp(a, b) + const void *a, *b; +{ + DBC *dbca, *dbcb; + db_recno_t counta, countb; + + dbca = *((DBC * const *)a); + dbcb = *((DBC * const *)b); + + if (__dbc_count(dbca, &counta) != 0 || + __dbc_count(dbcb, &countb) != 0) + return (0); + + return ((long)counta - (long)countb); +} + +/* + * __db_join_primget -- + * Perform a DB->get in the primary, being careful not to use a new + * locker ID if we're doing CDB locking. + */ +static int +__db_join_primget(dbp, ip, txn, locker, key, data, flags) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + DB_LOCKER *locker; + DBT *key, *data; + u_int32_t flags; +{ + DBC *dbc; + u_int32_t rmw; + int ret, t_ret; + + if ((ret = __db_cursor_int(dbp, ip, + txn, dbp->type, PGNO_INVALID, 0, locker, &dbc)) != 0) + return (ret); + + /* + * The only allowable flags here are the two flags copied into "opmods" + * in __db_join_get, DB_RMW and DB_READ_UNCOMMITTED. The former is an + * op on the c_get call, the latter on the cursor call. It's a DB bug + * if we allow any other flags down in here. + */ + rmw = LF_ISSET(DB_RMW); + if (LF_ISSET(DB_READ_UNCOMMITTED) || + (txn != NULL && F_ISSET(txn, TXN_READ_UNCOMMITTED))) + F_SET(dbc, DBC_READ_UNCOMMITTED); + + if (LF_ISSET(DB_READ_COMMITTED) || + (txn != NULL && F_ISSET(txn, TXN_READ_COMMITTED))) + F_SET(dbc, DBC_READ_COMMITTED); + + LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW); + DB_ASSERT(dbp->env, flags == 0); + + F_SET(dbc, DBC_TRANSIENT); + + /* + * This shouldn't be necessary, thanks to the fact that join cursors + * swap in their own DB_DBT_REALLOC'ed buffers, but just for form's + * sake, we mirror what __db_get does. + */ + SET_RET_MEM(dbc, dbp); + + ret = __dbc_get(dbc, key, data, DB_SET | rmw); + + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __db_secondary_corrupt -- + * Report primary/secondary inconsistencies. + * + * PUBLIC: int __db_secondary_corrupt __P((DB *)); + */ +int +__db_secondary_corrupt(dbp) + DB *dbp; +{ + __db_err(dbp->env, DB_SECONDARY_BAD, "%s%s%s", + dbp->fname == NULL ? "unnamed" : dbp->fname, + dbp->dname == NULL ? "" : "/", + dbp->dname == NULL ? "" : dbp->dname); + return (DB_SECONDARY_BAD); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_meta.c b/src/libs/resiprocate/contrib/db/db/db_meta.c new file mode 100644 index 00000000..ef42e44a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_meta.c @@ -0,0 +1,1299 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/txn.h" +#include "dbinc/db_am.h" +#include "dbinc/hash.h" + +static void __db_init_meta __P((DB *, void *, db_pgno_t, u_int32_t)); +#ifdef HAVE_FTRUNCATE +static int __db_pglistcmp __P((const void *, const void *)); +static int __db_truncate_freelist __P((DBC *, DBMETA *, + PAGE *, db_pgno_t *, u_int32_t, u_int32_t)); +#endif + +/* + * __db_init_meta -- + * Helper function for __db_new that initializes the important fields in + * a meta-data page (used instead of P_INIT). We need to make sure that we + * retain the page number and LSN of the existing page. + */ +static void +__db_init_meta(dbp, p, pgno, pgtype) + DB *dbp; + void *p; + db_pgno_t pgno; + u_int32_t pgtype; +{ + DBMETA *meta; + DB_LSN save_lsn; + + meta = (DBMETA *)p; + save_lsn = meta->lsn; + memset(meta, 0, sizeof(DBMETA)); + meta->lsn = save_lsn; + meta->pagesize = dbp->pgsize; + if (F_ISSET(dbp, DB_AM_CHKSUM)) + FLD_SET(meta->metaflags, DBMETA_CHKSUM); + meta->pgno = pgno; + meta->type = (u_int8_t)pgtype; +} + +/* + * __db_new -- + * Get a new page, preferably from the freelist. + * + * PUBLIC: int __db_new __P((DBC *, u_int32_t, DB_LOCK *, PAGE **)); + */ +int +__db_new(dbc, type, lockp, pagepp) + DBC *dbc; + u_int32_t type; + DB_LOCK *lockp; + PAGE **pagepp; +{ + DB *dbp; + DBMETA *meta; + DB_LOCK metalock; + DB_LSN lsn; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *h; + db_pgno_t last, *list, pgno, newnext; + int extend, hash, ret, t_ret; + + meta = NULL; + dbp = dbc->dbp; + env = dbp->env; + mpf = dbp->mpf; + h = NULL; + newnext = PGNO_INVALID; + if (lockp != NULL) + LOCK_INIT(*lockp); + + hash = 0; + ret = 0; + LOCK_INIT(metalock); + +#ifdef HAVE_HASH + if (dbp->type == DB_HASH) { + if ((ret = __ham_return_meta(dbc, DB_MPOOL_DIRTY, &meta)) != 0) + goto err; + if (meta != NULL) + hash = 1; + } +#endif + if (meta == NULL) { + pgno = PGNO_BASE_MD; + if ((ret = __db_lget(dbc, + LCK_ALWAYS, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0) + goto err; + if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn, + DB_MPOOL_DIRTY, &meta)) != 0) + goto err; + } + + last = meta->last_pgno; + if (meta->free == PGNO_INVALID) { + if (FLD_ISSET(type, P_DONTEXTEND)) { + *pagepp = NULL; + goto err; + } + last = pgno = meta->last_pgno + 1; + ZERO_LSN(lsn); + extend = 1; + } else { + pgno = meta->free; + /* + * Lock the new page. Do this here because we must do it + * before getting the page and the caller may need the lock + * to keep readers from seeing the page before the transaction + * commits. We can do this because no one will hold a free + * page locked. + */ + if (lockp != NULL && (ret = + __db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, lockp)) != 0) + goto err; + if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn, + DB_MPOOL_DIRTY, &h)) != 0) + goto err; + + /* + * We want to take the first page off the free list and + * then set meta->free to the that page's next_pgno, but + * we need to log the change first. + */ + newnext = h->next_pgno; + lsn = h->lsn; + extend = 0; + DB_ASSERT(env, TYPE(h) == P_INVALID); + + if (TYPE(h) != P_INVALID) { + __db_errx(env, + "%s page %lu is on free list with type %lu", + dbp->fname, (u_long)PGNO(h), (u_long)TYPE(h)); + return (__env_panic(env, EINVAL)); + } + + } + + FLD_CLR(type, P_DONTEXTEND); + + /* + * Log the allocation before fetching the new page. If we + * don't have room in the log then we don't want to tell + * mpool to extend the file. + */ + if (DBC_LOGGING(dbc)) { + if ((ret = __db_pg_alloc_log(dbp, dbc->txn, &LSN(meta), 0, + &LSN(meta), PGNO_BASE_MD, &lsn, + pgno, (u_int32_t)type, newnext, meta->last_pgno)) != 0) + goto err; + } else + LSN_NOT_LOGGED(LSN(meta)); + + meta->free = newnext; + + if (extend == 1) { + if (lockp != NULL && (ret = + __db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, lockp)) != 0) + goto err; + if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn, + DB_MPOOL_NEW, &h)) != 0) + goto err; + DB_ASSERT(env, last == pgno); + meta->last_pgno = pgno; + ZERO_LSN(h->lsn); + h->pgno = pgno; + } + LSN(h) = LSN(meta); + + if (hash == 0) + ret = __memp_fput(mpf, dbc->thread_info, meta, dbc->priority); + meta = NULL; + if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + goto err; + + switch (type) { + case P_BTREEMETA: + case P_HASHMETA: + case P_QAMMETA: + __db_init_meta(dbp, h, h->pgno, type); + break; + default: + P_INIT(h, dbp->pgsize, + h->pgno, PGNO_INVALID, PGNO_INVALID, 0, type); + break; + } + + /* Fix up the sorted free list if necessary. */ +#ifdef HAVE_FTRUNCATE + if (extend == 0) { + u_int32_t nelems = 0; + + if ((ret = __memp_get_freelist(dbp->mpf, &nelems, &list)) != 0) + goto err; + if (nelems != 0) { + DB_ASSERT(env, h->pgno == list[0]); + memmove(list, &list[1], (nelems - 1) * sizeof(*list)); + if ((ret = __memp_extend_freelist( + dbp->mpf, nelems - 1, &list)) != 0) + goto err; + } + } +#else + COMPQUIET(list, NULL); +#endif + + *pagepp = h; + return (0); + +err: if (h != NULL) + (void)__memp_fput(mpf, dbc->thread_info, h, dbc->priority); + if (meta != NULL && hash == 0) + (void)__memp_fput(mpf, dbc->thread_info, meta, dbc->priority); + (void)__TLPUT(dbc, metalock); + if (lockp != NULL) + (void)__LPUT(dbc, *lockp); + return (ret); +} + +/* + * __db_free -- + * Add a page to the head of the freelist. + * + * PUBLIC: int __db_free __P((DBC *, PAGE *)); + */ +int +__db_free(dbc, h) + DBC *dbc; + PAGE *h; +{ + DB *dbp; + DBMETA *meta; + DBT ddbt, ldbt; + DB_LOCK metalock; + DB_LSN *lsnp; + DB_MPOOLFILE *mpf; + PAGE *prev; + db_pgno_t last_pgno, next_pgno, pgno, prev_pgno; + u_int32_t lflag; + int hash, ret, t_ret; +#ifdef HAVE_FTRUNCATE + db_pgno_t *list, *lp; + u_int32_t nelem, position, start; + int do_truncate; +#endif + + dbp = dbc->dbp; + mpf = dbp->mpf; + prev_pgno = PGNO_INVALID; + meta = NULL; + prev = NULL; + LOCK_INIT(metalock); +#ifdef HAVE_FTRUNCATE + lp = NULL; + nelem = 0; + do_truncate = 0; +#endif + + /* + * Retrieve the metadata page. If we are not keeping a sorted + * free list put the page at the head of the the free list. + * If we are keeping a sorted free list, for truncation, + * then figure out where this page belongs and either + * link it in or truncate the file as much as possible. + * If either the lock get or page get routines + * fail, then we need to put the page with which we were called + * back because our caller assumes we take care of it. + */ + hash = 0; + + pgno = PGNO_BASE_MD; +#ifdef HAVE_HASH + if (dbp->type == DB_HASH) { + if ((ret = __ham_return_meta(dbc, +#ifdef HAVE_FTRUNCATE + 0, +#else + DB_MPOOL_DIRTY, +#endif + &meta)) != 0) + goto err; + if (meta != NULL) + hash = 1; + } +#endif + if (meta == NULL) { + if ((ret = __db_lget(dbc, + LCK_ALWAYS, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0) + goto err; + + /* If we support truncate, we might not dirty the meta page. */ + if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn, +#ifdef HAVE_FTRUNCATE + 0, +#else + DB_MPOOL_DIRTY, +#endif + &meta)) != 0) + goto err1; + } + + last_pgno = meta->last_pgno; + next_pgno = meta->free; + /* + * Assign lsnp here so it always initialized when + * HAVE_FTRUNCATE is not defined. + */ + lsnp = &LSN(meta); + + DB_ASSERT(dbp->env, h->pgno != next_pgno); + +#ifdef HAVE_FTRUNCATE + /* + * If we are maintaining a sorted free list see if we either have a + * new truncation point or the page goes somewhere in the middle of + * the list. If it goes in the middle of the list, we will drop the + * meta page and get the previous page. + */ + if ((ret = __memp_get_freelist(mpf, &nelem, &list)) != 0) + goto err1; + if (list == NULL) + goto no_sort; + + if (h->pgno != last_pgno) { + /* + * Put the page number in the sorted list. + * Finds its position and the previous page, + * extend the list, make room and insert. + */ + position = 0; + if (nelem != 0) { + __db_freelist_pos(h->pgno, list, nelem, &position); + + DB_ASSERT(dbp->env, h->pgno != list[position]); + + /* Get the previous page if this is not the smallest. */ + if (position != 0 || h->pgno > list[0]) + prev_pgno = list[position]; + } + + } else if (nelem != 0) { + /* Find the truncation point. */ + for (lp = &list[nelem - 1]; lp >= list; lp--) + if (--last_pgno != *lp) + break; + if (lp < list || last_pgno < h->pgno - 1) + do_truncate = 1; + last_pgno = meta->last_pgno; + } + +no_sort: + if (prev_pgno == PGNO_INVALID) { +#ifdef HAVE_HASH + if (hash) { + if ((ret = + __ham_return_meta(dbc, DB_MPOOL_DIRTY, &meta)) != 0) + goto err1; + } else +#endif + if ((ret = __memp_dirty(mpf, + &meta, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + goto err1; + lsnp = &LSN(meta); + } else { + pgno = prev_pgno; + if ((ret = __memp_fget(mpf, &pgno, + dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &prev)) != 0) + goto err1; + next_pgno = NEXT_PGNO(prev); + lsnp = &LSN(prev); + } +#endif + + /* + * Log the change. + * We are either logging an update to the metapage or to the + * previous page in the sorted list. + */ + if (DBC_LOGGING(dbc)) { + memset(&ldbt, 0, sizeof(ldbt)); + ldbt.data = h; + ldbt.size = P_OVERHEAD(dbp); + /* + * If we are truncating the file, we need to make sure + * the logging happens before the truncation. If we + * are truncating multiple pages we don't need to flush the + * log here as it will be flushed by __db_truncate_freelist. + * If we are zeroing pages rather than truncating we still + * need to flush since they will not have valid LSNs. + */ + lflag = 0; + + if (h->pgno == last_pgno +#ifdef HAVE_FTRUNCATE + && do_truncate == 0 +#endif + ) + lflag = DB_FLUSH; + switch (h->type) { + case P_HASH: + case P_IBTREE: + case P_IRECNO: + case P_LBTREE: + case P_LRECNO: + case P_LDUP: + if (h->entries > 0) { + ldbt.size += h->entries * sizeof(db_indx_t); + ddbt.data = (u_int8_t *)h + HOFFSET(h); + ddbt.size = dbp->pgsize - HOFFSET(h); + if ((ret = __db_pg_freedata_log(dbp, dbc->txn, + lsnp, lflag, + h->pgno, lsnp, pgno, + &ldbt, next_pgno, last_pgno, &ddbt)) != 0) + goto err1; + goto logged; + } + break; + case P_HASHMETA: + ldbt.size = sizeof(HMETA); + break; + case P_BTREEMETA: + ldbt.size = sizeof(BTMETA); + break; + case P_OVERFLOW: + ldbt.size += OV_LEN(h); + break; + default: + DB_ASSERT(dbp->env, h->type != P_QAMDATA); + } + + if ((ret = __db_pg_free_log(dbp, + dbc->txn, lsnp, lflag, h->pgno, + lsnp, pgno, &ldbt, next_pgno, last_pgno)) != 0) + goto err1; + } else + LSN_NOT_LOGGED(*lsnp); + +logged: +#ifdef HAVE_FTRUNCATE + if (do_truncate) { + start = (u_int32_t) (lp - list) + 1; + meta->last_pgno--; + ret = __db_truncate_freelist( + dbc, meta, h, list, start, nelem); + h = NULL; + } else +#endif + if (h->pgno == last_pgno) { + /* + * We are going to throw this page away, but if we are + * using MVCC then this version may stick around and we + * might have to make a copy. + */ + if (mpf->mfp->multiversion && (ret = __memp_dirty(mpf, + &h, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + goto err1; + LSN(h) = *lsnp; + P_INIT(h, dbp->pgsize, + h->pgno, PGNO_INVALID, next_pgno, 0, P_INVALID); + if ((ret = __memp_fput(mpf, + dbc->thread_info, h, DB_PRIORITY_VERY_LOW)) != 0) + goto err1; + h = NULL; + /* Give the page back to the OS. */ + if ((ret = __memp_ftruncate(mpf, dbc->txn, dbc->thread_info, + last_pgno, 0)) != 0) + goto err1; + DB_ASSERT(dbp->env, meta->pgno == PGNO_BASE_MD); + meta->last_pgno--; + h = NULL; + } else { +#ifdef HAVE_FTRUNCATE + if (list != NULL) { + /* Put the page number into the list. */ + if ((ret = + __memp_extend_freelist(mpf, nelem + 1, &list)) != 0) + goto err1; + if (prev_pgno != PGNO_INVALID) + lp = &list[position + 1]; + else + lp = list; + if (nelem != 0 && position != nelem) + memmove(lp + 1, lp, (size_t) + ((u_int8_t*)&list[nelem] - (u_int8_t*)lp)); + *lp = h->pgno; + } +#endif + /* + * If we are not truncating the page then we + * reinitialize it and put it at the head of + * the free list. + */ + if ((ret = __memp_dirty(mpf, + &h, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + goto err1; + LSN(h) = *lsnp; + P_INIT(h, dbp->pgsize, + h->pgno, PGNO_INVALID, next_pgno, 0, P_INVALID); +#ifdef DIAGNOSTIC + memset((u_int8_t *) h + P_OVERHEAD(dbp), + CLEAR_BYTE, dbp->pgsize - P_OVERHEAD(dbp)); +#endif + if (prev_pgno == PGNO_INVALID) + meta->free = h->pgno; + else + NEXT_PGNO(prev) = h->pgno; + } + + /* Discard the metadata or previous page. */ +err1: if (hash == 0 && meta != NULL && (t_ret = __memp_fput(mpf, + dbc->thread_info, (PAGE *)meta, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0) + ret = t_ret; + if (prev != (PAGE*) meta && prev != NULL && (t_ret = __memp_fput(mpf, + dbc->thread_info, prev, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + + /* Discard the caller's page reference. */ +err: if (h != NULL && (t_ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + + /* + * XXX + * We have to unlock the caller's page in the caller! + */ + return (ret); +} + +#ifdef HAVE_FTRUNCATE +/* + * __db_freelist_pos -- find the position of a page in the freelist. + * The list is sorted, we do a binary search. + * + * PUBLIC: #ifdef HAVE_FTRUNCATE + * PUBLIC: void __db_freelist_pos __P((db_pgno_t, + * PUBLIC: db_pgno_t *, u_int32_t, u_int32_t *)); + * PUBLIC: #endif + */ +void +__db_freelist_pos(pgno, list, nelem, posp) + db_pgno_t pgno; + db_pgno_t *list; + u_int32_t nelem; + u_int32_t *posp; +{ + u_int32_t base, indx, lim; + + indx = 0; + for (base = 0, lim = nelem; lim != 0; lim >>= 1) { + indx = base + (lim >> 1); + if (pgno == list[indx]) { + *posp = indx; + return; + } + if (pgno > list[indx]) { + base = indx + 1; + --lim; + } + } + if (base != 0) + base--; + *posp = base; + return; +} + +static int +__db_pglistcmp(a, b) + const void *a, *b; +{ + db_pglist_t *ap, *bp; + + ap = (db_pglist_t *)a; + bp = (db_pglist_t *)b; + + return ((ap->pgno > bp->pgno) ? 1 : (ap->pgno < bp->pgno) ? -1: 0); +} + +/* + * __db_freelist_sort -- sort a list of free pages. + * PUBLIC: void __db_freelist_sort __P((db_pglist_t *, u_int32_t)); + */ +void +__db_freelist_sort(list, nelems) + db_pglist_t *list; + u_int32_t nelems; +{ + qsort(list, (size_t)nelems, sizeof(db_pglist_t), __db_pglistcmp); +} + +/* + * __db_pg_truncate -- find the truncation point in a sorted freelist. + * + * PUBLIC: #ifdef HAVE_FTRUNCATE + * PUBLIC: int __db_pg_truncate __P((DBC *, DB_TXN *, + * PUBLIC: db_pglist_t *, DB_COMPACT *, u_int32_t *, + * PUBLIC: db_pgno_t , db_pgno_t *, DB_LSN *, int)); + * PUBLIC: #endif + */ +int +__db_pg_truncate(dbc, txn, + list, c_data, nelemp, free_pgno, last_pgno, lsnp, in_recovery) + DBC *dbc; + DB_TXN *txn; + db_pglist_t *list; + DB_COMPACT *c_data; + u_int32_t *nelemp; + db_pgno_t free_pgno, *last_pgno; + DB_LSN *lsnp; + int in_recovery; +{ + DB *dbp; + DBT ddbt; + DB_LSN null_lsn; + DB_MPOOLFILE *mpf; + PAGE *h; + db_pglist_t *lp, *slp; + db_pgno_t lpgno, pgno; + u_int32_t elems, log_size, tpoint; + int last, ret; + + ret = 0; + h = NULL; + + dbp = dbc->dbp; + mpf = dbp->mpf; + elems = tpoint = *nelemp; + + /* + * Figure out what (if any) pages can be truncated immediately and + * record the place from which we can truncate, so we can do the + * memp_ftruncate below. We also use this to avoid ever putting + * these pages on the freelist, which we are about to relink. + */ + pgno = *last_pgno; + lp = &list[elems - 1]; + last = 1; + while (tpoint != 0) { + if (lp->pgno != pgno) + break; + pgno--; + tpoint--; + lp--; + } + + lp = list; + slp = &list[elems]; + /* + * Log the sorted list. We log the whole list so it can be rebuilt. + * Don't overflow the log file. + */ +again: if (DBC_LOGGING(dbc)) { + last = 1; + lpgno = *last_pgno; + ddbt.size = elems * sizeof(*lp); + ddbt.data = lp; + log_size = ((LOG *)dbc->env-> + lg_handle->reginfo.primary)->log_size; + if (ddbt.size > log_size / 2) { + elems = (log_size / 2) / sizeof(*lp); + ddbt.size = elems * sizeof(*lp); + last = 0; + /* + * If we stopped after the truncation point + * then we need to truncate from here. + */ + if (lp + elems >= &list[tpoint]) + lpgno = lp[elems - 1].pgno; + } + /* + * If this is not the begining of the list fetch the end + * of the previous segment. This page becomes the last_free + * page and will link to this segment if it is not truncated. + */ + if (lp != list) { + if ((ret = __memp_fget(mpf, &lp[-1].pgno, + dbc->thread_info, txn, 0, &h)) != 0) + goto err; + } + + slp = &lp[elems]; + + ZERO_LSN(null_lsn); + if ((ret = __db_pg_trunc_log(dbp, dbc->txn, + lsnp, last == 1 ? DB_FLUSH : 0, PGNO_BASE_MD, + lsnp, h != NULL ? PGNO(h) : PGNO_INVALID, + h != NULL ? &LSN(h) : &null_lsn, + free_pgno, lpgno, &ddbt)) != 0) + goto err; + if (h != NULL) { + LSN(h) = *lsnp; + if ((ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0) + goto err; + } + h = NULL; + } else if (!in_recovery) + LSN_NOT_LOGGED(*lsnp); + + for (; lp < slp && lp < &list[tpoint]; lp++) { + if ((ret = __memp_fget(mpf, &lp->pgno, dbc->thread_info, + txn, !in_recovery ? DB_MPOOL_DIRTY : 0, &h)) != 0) { + /* Page may have been truncated later. */ + if (in_recovery && ret == DB_PAGE_NOTFOUND) { + ret = 0; + continue; + } + goto err; + } + if (in_recovery) { + if (LOG_COMPARE(&LSN(h), &lp->lsn) == 0) { + if ((ret = __memp_dirty(mpf, &h, + dbc->thread_info, + txn, dbp->priority, 0)) != 0) { + (void)__memp_fput(mpf, + dbc->thread_info, h, dbp->priority); + goto err; + } + } else + goto skip; + } + + if (lp == &list[tpoint - 1]) + NEXT_PGNO(h) = PGNO_INVALID; + else + NEXT_PGNO(h) = lp[1].pgno; + DB_ASSERT(mpf->env, NEXT_PGNO(h) < *last_pgno); + + LSN(h) = *lsnp; +skip: if ((ret = __memp_fput(mpf, + dbc->thread_info, h, dbp->priority)) != 0) + goto err; + h = NULL; + } + + /* + * If we did not log everything try again. We start from slp and + * try to go to the end of the list. + */ + if (last == 0) { + elems = (u_int32_t)(&list[*nelemp] - slp); + lp = slp; + goto again; + } + + /* + * Truncate the file. Its possible that the last page is the + * only one that got truncated and that's done in the caller. + */ + if (pgno != *last_pgno) { + if (tpoint != *nelemp && + (ret = __memp_ftruncate(mpf, dbc->txn, dbc->thread_info, + pgno + 1, in_recovery ? MP_TRUNC_RECOVER : 0)) != 0) + goto err; + if (c_data) + c_data->compact_pages_truncated += *last_pgno - pgno; + *last_pgno = pgno; + } + *nelemp = tpoint; + + if (0) { +err: if (h != NULL) + (void)__memp_fput(mpf, + dbc->thread_info, h, dbc->priority); + } + return (ret); +} + +/* + * __db_free_truncate -- + * Build a sorted free list and truncate free pages at the end + * of the file. + * + * PUBLIC: #ifdef HAVE_FTRUNCATE + * PUBLIC: int __db_free_truncate __P((DB *, DB_THREAD_INFO *, DB_TXN *, + * PUBLIC: u_int32_t, DB_COMPACT *, db_pglist_t **, u_int32_t *, + * PUBLIC: db_pgno_t *)); + * PUBLIC: #endif + */ +int +__db_free_truncate(dbp, ip, txn, flags, c_data, listp, nelemp, last_pgnop) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + u_int32_t flags; + DB_COMPACT *c_data; + db_pglist_t **listp; + u_int32_t *nelemp; + db_pgno_t *last_pgnop; +{ + DBC *dbc; + DBMETA *meta; + DB_LOCK metalock; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *h; + db_pglist_t *list, *lp; + db_pgno_t pgno; + u_int32_t nelems; + int ret, t_ret; + size_t size; + + COMPQUIET(flags, 0); + list = NULL; + meta = NULL; + env = dbp->env; + mpf = dbp->mpf; + h = NULL; + nelems = 0; + if (listp != NULL) { + *listp = NULL; + DB_ASSERT(env, nelemp != NULL); + *nelemp = 0; + } + + if ((ret = __db_cursor(dbp, ip, txn, &dbc, DB_WRITELOCK)) != 0) + return (ret); + + pgno = PGNO_BASE_MD; + if ((ret = __db_lget(dbc, + LCK_ALWAYS, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0) + goto err; + if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn, 0, + &meta)) != 0) + goto err; + + if (last_pgnop != NULL) + *last_pgnop = meta->last_pgno; + if ((pgno = meta->free) == PGNO_INVALID) + goto done; + + size = 128; + if ((ret = __os_malloc(env, size * sizeof(*list), &list)) != 0) + goto err; + lp = list; + + do { + if (lp == &list[size]) { + size *= 2; + if ((ret = __os_realloc(env, + size * sizeof(*list), &list)) != 0) + goto err; + lp = &list[size / 2]; + } + if ((ret = __memp_fget(mpf, &pgno, + dbc->thread_info, dbc->txn, 0, &h)) != 0) + goto err; + + lp->pgno = pgno; + lp->next_pgno = NEXT_PGNO(h); + lp->lsn = LSN(h); + pgno = NEXT_PGNO(h); + if ((ret = __memp_fput(mpf, + dbc->thread_info, h, dbc->priority)) != 0) + goto err; + lp++; + } while (pgno != PGNO_INVALID); + nelems = (u_int32_t)(lp - list); + + if ((ret = __memp_dirty(mpf, + &meta, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + goto err; + + /* Sort the list */ + __db_freelist_sort(list, nelems); + + if ((ret = __db_pg_truncate(dbc, txn, list, c_data, + &nelems, meta->free, &meta->last_pgno, &LSN(meta), 0)) != 0) + goto err; + + if (nelems == 0) + meta->free = PGNO_INVALID; + else + meta->free = list[0].pgno; + +done: if (last_pgnop != NULL) + *last_pgnop = meta->last_pgno; + + /* + * The truncate point is the number of pages in the free + * list back from the last page. The number of pages + * in the free list are the number that we can swap in. + */ + if (c_data) + c_data->compact_truncate = (u_int32_t)meta->last_pgno - nelems; + + if (nelems != 0 && listp != NULL) { + *listp = list; + *nelemp = nelems; + list = NULL; + } + +err: if (list != NULL) + __os_free(env, list); + if (meta != NULL && (t_ret = __memp_fput(mpf, + dbc->thread_info, (PAGE *)meta, dbc->priority)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0) + ret = t_ret; + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +static int +__db_truncate_freelist(dbc, meta, h, list, start, nelem) + DBC *dbc; + DBMETA *meta; + PAGE *h; + db_pgno_t *list; + u_int32_t start, nelem; +{ + DB *dbp; + DBT ddbt; + DB_LSN null_lsn; + DB_MPOOLFILE *mpf; + PAGE *last_free, *pg; + db_pgno_t *lp, free_pgno, lpgno; + db_pglist_t *plist, *pp, *spp; + u_int32_t elem, log_size; + int last, ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + plist = NULL; + last_free = NULL; + pg = NULL; + + if (start != 0 && + (ret = __memp_fget(mpf, &list[start - 1], + dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &last_free)) != 0) + goto err; + + if (DBC_LOGGING(dbc)) { + if ((ret = __os_malloc(dbp->env, + (nelem - start) * sizeof(*pp), &plist)) != 0) + goto err; + + pp = plist; + for (lp = &list[start]; lp < &list[nelem]; lp++) { + pp->pgno = *lp; + if ((ret = __memp_fget(mpf, lp, + dbc->thread_info, dbc->txn, 0, &pg)) != 0) + goto err; + pp->lsn = LSN(pg); + pp->next_pgno = NEXT_PGNO(pg); + if ((ret = __memp_fput(mpf, + dbc->thread_info, pg, DB_PRIORITY_VERY_LOW)) != 0) + goto err; + pg = NULL; + pp++; + } + ZERO_LSN(null_lsn); + pp = plist; + elem = nelem - start; + log_size = ((LOG *)dbc->env-> + lg_handle->reginfo.primary)->log_size; +again: ddbt.data = spp = pp; + free_pgno = pp->pgno; + lpgno = meta->last_pgno; + ddbt.size = elem * sizeof(*pp); + if (ddbt.size > log_size / 2) { + elem = (log_size / 2) / (u_int32_t)sizeof(*pp); + ddbt.size = elem * sizeof(*pp); + pp += elem; + elem = (nelem - start) - (u_int32_t)(pp - plist); + lpgno = pp[-1].pgno; + last = 0; + } else + last = 1; + /* + * Get the page which will link to this section if we abort. + * If this is the first segment then its last_free. + */ + if (spp == plist) + pg = last_free; + else if ((ret = __memp_fget(mpf, &spp[-1].pgno, + dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &pg)) != 0) + goto err; + + if ((ret = __db_pg_trunc_log(dbp, dbc->txn, + &LSN(meta), last == 1 ? DB_FLUSH : 0, + PGNO(meta), &LSN(meta), + pg != NULL ? PGNO(pg) : PGNO_INVALID, + pg != NULL ? &LSN(pg) : &null_lsn, + free_pgno, lpgno, &ddbt)) != 0) + goto err; + if (pg != NULL) { + LSN(pg) = LSN(meta); + if (pg != last_free && (ret = __memp_fput(mpf, + dbc->thread_info, pg, DB_PRIORITY_VERY_LOW)) != 0) + goto err; + pg = NULL; + } + if (last == 0) + goto again; + } else + LSN_NOT_LOGGED(LSN(meta)); + + if ((ret = __memp_fput(mpf, + dbc->thread_info, h, DB_PRIORITY_VERY_LOW)) != 0) + goto err; + h = NULL; + if ((ret = __memp_ftruncate(mpf, dbc->txn, dbc->thread_info, + list[start], 0)) != 0) + goto err; + meta->last_pgno = list[start] - 1; + + if (start == 0) + meta->free = PGNO_INVALID; + else { + NEXT_PGNO(last_free) = PGNO_INVALID; + if ((ret = __memp_fput(mpf, + dbc->thread_info, last_free, dbc->priority)) != 0) + goto err; + last_free = NULL; + } + + /* Shrink the number of elements in the list. */ + ret = __memp_extend_freelist(mpf, start, &list); + +err: if (plist != NULL) + __os_free(dbp->env, plist); + + /* We need to put the page on error. */ + if (h != NULL) + (void)__memp_fput(mpf, dbc->thread_info, h, dbc->priority); + if (pg != NULL && pg != last_free) + (void)__memp_fput(mpf, dbc->thread_info, pg, dbc->priority); + if (last_free != NULL) + (void)__memp_fput(mpf, + dbc->thread_info, last_free, dbc->priority); + + return (ret); +} +#endif + +#ifdef DEBUG +/* + * __db_lprint -- + * Print out the list of locks currently held by a cursor. + * + * PUBLIC: int __db_lprint __P((DBC *)); + */ +int +__db_lprint(dbc) + DBC *dbc; +{ + DB *dbp; + DB_LOCKREQ req; + ENV *env; + + dbp = dbc->dbp; + env = dbp->env; + + if (LOCKING_ON(env)) { + req.op = DB_LOCK_DUMP; + (void)__lock_vec(env, dbc->locker, 0, &req, 1, NULL); + } + return (0); +} +#endif + +/* + * __db_lget -- + * The standard lock get call. + * + * PUBLIC: int __db_lget __P((DBC *, + * PUBLIC: int, db_pgno_t, db_lockmode_t, u_int32_t, DB_LOCK *)); + */ +int +__db_lget(dbc, action, pgno, mode, lkflags, lockp) + DBC *dbc; + int action; + db_pgno_t pgno; + db_lockmode_t mode; + u_int32_t lkflags; + DB_LOCK *lockp; +{ + DB *dbp; + DB_LOCKREQ couple[3], *reqp; + DB_TXN *txn; + ENV *env; + int has_timeout, i, ret; + + dbp = dbc->dbp; + env = dbp->env; + txn = dbc->txn; + + /* + * We do not always check if we're configured for locking before + * calling __db_lget to acquire the lock. + */ + if (CDB_LOCKING(env) || !LOCKING_ON(env) || + (MULTIVERSION(dbp) && mode == DB_LOCK_READ && + dbc->txn != NULL && F_ISSET(dbc->txn, TXN_SNAPSHOT)) || + F_ISSET(dbc, DBC_DONTLOCK) || (F_ISSET(dbc, DBC_RECOVER) && + (action != LCK_ROLLBACK || IS_REP_CLIENT(env))) || + (action != LCK_ALWAYS && F_ISSET(dbc, DBC_OPD))) { + LOCK_INIT(*lockp); + return (0); + } + + dbc->lock.pgno = pgno; + if (lkflags & DB_LOCK_RECORD) + dbc->lock.type = DB_RECORD_LOCK; + else + dbc->lock.type = DB_PAGE_LOCK; + lkflags &= ~DB_LOCK_RECORD; + + /* + * If the transaction enclosing this cursor has DB_LOCK_NOWAIT set, + * pass that along to the lock call. + */ + if (DB_NONBLOCK(dbc)) + lkflags |= DB_LOCK_NOWAIT; + + if (F_ISSET(dbc, DBC_READ_UNCOMMITTED) && mode == DB_LOCK_READ) + mode = DB_LOCK_READ_UNCOMMITTED; + + has_timeout = F_ISSET(dbc, DBC_RECOVER) || + (txn != NULL && F_ISSET(txn, TXN_LOCKTIMEOUT)); + + /* + * Transactional locking. + * Hold on to the previous read lock only if we are in full isolation. + * COUPLE_ALWAYS indicates we are holding an interior node which need + * not be isolated. + * Downgrade write locks if we are supporting dirty readers. + */ + if ((action != LCK_COUPLE && action != LCK_COUPLE_ALWAYS) || + !LOCK_ISSET(*lockp)) + action = 0; + else if (dbc->txn == NULL || action == LCK_COUPLE_ALWAYS) + action = LCK_COUPLE; + else if (F_ISSET(dbc, DBC_READ_COMMITTED | DBC_WAS_READ_COMMITTED) && + lockp->mode == DB_LOCK_READ) + action = LCK_COUPLE; + else if (lockp->mode == DB_LOCK_READ_UNCOMMITTED) + action = LCK_COUPLE; + else if (F_ISSET(dbc->dbp, + DB_AM_READ_UNCOMMITTED) && lockp->mode == DB_LOCK_WRITE) + action = LCK_DOWNGRADE; + else + action = 0; + + i = 0; + switch (action) { + default: + if (has_timeout) + goto do_couple; + ret = __lock_get(env, + dbc->locker, lkflags, &dbc->lock_dbt, mode, lockp); + break; + + case LCK_DOWNGRADE: + couple[0].op = DB_LOCK_GET; + couple[0].obj = NULL; + couple[0].lock = *lockp; + couple[0].mode = DB_LOCK_WWRITE; + UMRW_SET(couple[0].timeout); + i++; + /* FALLTHROUGH */ + case LCK_COUPLE: +do_couple: couple[i].op = has_timeout? DB_LOCK_GET_TIMEOUT : DB_LOCK_GET; + couple[i].obj = &dbc->lock_dbt; + couple[i].mode = mode; + UMRW_SET(couple[i].timeout); + i++; + if (has_timeout) + couple[0].timeout = + F_ISSET(dbc, DBC_RECOVER) ? 0 : txn->lock_timeout; + if (action == LCK_COUPLE || action == LCK_DOWNGRADE) { + couple[i].op = DB_LOCK_PUT; + couple[i].lock = *lockp; + i++; + } + + ret = __lock_vec(env, + dbc->locker, lkflags, couple, i, &reqp); + if (ret == 0 || reqp == &couple[i - 1]) + *lockp = i == 1 ? couple[0].lock : couple[i - 2].lock; + break; + } + + if (txn != NULL && ret == DB_LOCK_DEADLOCK) + F_SET(txn, TXN_DEADLOCK); + return ((ret == DB_LOCK_NOTGRANTED && !F_ISSET(env->dbenv, + DB_ENV_TIME_NOTGRANTED)) ? DB_LOCK_DEADLOCK : ret); +} + +/* + * __db_lput -- + * The standard lock put call. + * + * PUBLIC: int __db_lput __P((DBC *, DB_LOCK *)); + */ +int +__db_lput(dbc, lockp) + DBC *dbc; + DB_LOCK *lockp; +{ + DB_LOCKREQ couple[2], *reqp; + ENV *env; + int action, ret; + + /* + * Transactional locking. + * Hold on to the read locks only if we are in full isolation. + * Downgrade write locks if we are supporting dirty readers. + */ + if (F_ISSET(dbc->dbp, + DB_AM_READ_UNCOMMITTED) && lockp->mode == DB_LOCK_WRITE) + action = LCK_DOWNGRADE; + else if (dbc->txn == NULL) + action = LCK_COUPLE; + else if (F_ISSET(dbc, DBC_READ_COMMITTED | DBC_WAS_READ_COMMITTED) && + lockp->mode == DB_LOCK_READ) + action = LCK_COUPLE; + else if (lockp->mode == DB_LOCK_READ_UNCOMMITTED) + action = LCK_COUPLE; + else + action = 0; + + env = dbc->env; + switch (action) { + case LCK_COUPLE: + ret = __lock_put(env, lockp); + break; + case LCK_DOWNGRADE: + couple[0].op = DB_LOCK_GET; + couple[0].obj = NULL; + couple[0].mode = DB_LOCK_WWRITE; + couple[0].lock = *lockp; + UMRW_SET(couple[0].timeout); + couple[1].op = DB_LOCK_PUT; + couple[1].lock = *lockp; + ret = __lock_vec(env, dbc->locker, 0, couple, 2, &reqp); + if (ret == 0 || reqp == &couple[1]) + *lockp = couple[0].lock; + break; + default: + ret = 0; + break; + } + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_method.c b/src/libs/resiprocate/contrib/db/db/db_method.c new file mode 100644 index 00000000..1182f97d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_method.c @@ -0,0 +1,1052 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1999-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/crypto.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/hash.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" +#include "dbinc/qam.h" +#include "dbinc/txn.h" + +#ifdef HAVE_RPC +#ifdef HAVE_SYSTEM_INCLUDE_FILES +#include +#endif +#include "db_server.h" +#include "dbinc_auto/rpc_client_ext.h" +#endif + +static int __db_get_byteswapped __P((DB *, int *)); +static int __db_get_dbname __P((DB *, const char **, const char **)); +static DB_ENV *__db_get_env __P((DB *)); +static void __db_get_msgcall + __P((DB *, void (**)(const DB_ENV *, const char *))); +static DB_MPOOLFILE *__db_get_mpf __P((DB *)); +static int __db_get_multiple __P((DB *)); +static int __db_get_transactional __P((DB *)); +static int __db_get_type __P((DB *, DBTYPE *dbtype)); +static int __db_init __P((DB *, u_int32_t)); +static int __db_get_alloc __P((DB *, void *(**)(size_t), + void *(**)(void *, size_t), void (**)(void *))); +static int __db_set_alloc __P((DB *, void *(*)(size_t), + void *(*)(void *, size_t), void (*)(void *))); +static int __db_get_append_recno __P((DB *, + int (**)(DB *, DBT *, db_recno_t))); +static int __db_set_append_recno __P((DB *, int (*)(DB *, DBT *, db_recno_t))); +static int __db_get_cachesize __P((DB *, u_int32_t *, u_int32_t *, int *)); +static int __db_set_cachesize __P((DB *, u_int32_t, u_int32_t, int)); +static int __db_get_create_dir __P((DB *, const char **)); +static int __db_set_create_dir __P((DB *, const char *)); +static int __db_get_dup_compare + __P((DB *, int (**)(DB *, const DBT *, const DBT *))); +static int __db_set_dup_compare + __P((DB *, int (*)(DB *, const DBT *, const DBT *))); +static int __db_get_encrypt_flags __P((DB *, u_int32_t *)); +static int __db_set_encrypt __P((DB *, const char *, u_int32_t)); +static int __db_get_feedback __P((DB *, void (**)(DB *, int, int))); +static int __db_set_feedback __P((DB *, void (*)(DB *, int, int))); +static void __db_map_flags __P((DB *, u_int32_t *, u_int32_t *)); +static int __db_get_pagesize __P((DB *, u_int32_t *)); +static int __db_set_paniccall __P((DB *, void (*)(DB_ENV *, int))); +static int __db_set_priority __P((DB *, DB_CACHE_PRIORITY)); +static int __db_get_priority __P((DB *, DB_CACHE_PRIORITY *)); +static void __db_get_errcall __P((DB *, + void (**)(const DB_ENV *, const char *, const char *))); +static void __db_set_errcall + __P((DB *, void (*)(const DB_ENV *, const char *, const char *))); +static void __db_get_errfile __P((DB *, FILE **)); +static void __db_set_errfile __P((DB *, FILE *)); +static void __db_get_errpfx __P((DB *, const char **)); +static void __db_set_errpfx __P((DB *, const char *)); +static void __db_set_msgcall + __P((DB *, void (*)(const DB_ENV *, const char *))); +static void __db_get_msgfile __P((DB *, FILE **)); +static void __db_set_msgfile __P((DB *, FILE *)); +static void __dbh_err __P((DB *, int, const char *, ...)); +static void __dbh_errx __P((DB *, const char *, ...)); + +/* + * db_create -- + * DB constructor. + * + * EXTERN: int db_create __P((DB **, DB_ENV *, u_int32_t)); + */ +int +db_create(dbpp, dbenv, flags) + DB **dbpp; + DB_ENV *dbenv; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int ret; + + ip = NULL; + env = dbenv == NULL ? NULL : dbenv->env; + + /* Check for invalid function flags. */ + if (flags != 0) + return (__db_ferr(env, "db_create", 0)); + + if (env != NULL) + ENV_ENTER(env, ip); + ret = __db_create_internal(dbpp, env, flags); + if (env != NULL) + ENV_LEAVE(env, ip); + + return (ret); +} + +/* + * __db_create_internal -- + * DB constructor internal routine. + * + * PUBLIC: int __db_create_internal __P((DB **, ENV *, u_int32_t)); + */ +int +__db_create_internal(dbpp, env, flags) + DB **dbpp; + ENV *env; + u_int32_t flags; +{ + DB *dbp; + DB_ENV *dbenv; + DB_REP *db_rep; + int ret; + + *dbpp = NULL; + + /* If we don't have an environment yet, allocate a local one. */ + if (env == NULL) { + if ((ret = db_env_create(&dbenv, 0)) != 0) + return (ret); + env = dbenv->env; + F_SET(env, ENV_DBLOCAL); + } else + dbenv = env->dbenv; + + /* Allocate and initialize the DB handle. */ + if ((ret = __os_calloc(env, 1, sizeof(*dbp), &dbp)) != 0) + goto err; + + dbp->dbenv = env->dbenv; + dbp->env = env; + if ((ret = __db_init(dbp, flags)) != 0) + goto err; + + MUTEX_LOCK(env, env->mtx_dblist); + ++env->db_ref; + MUTEX_UNLOCK(env, env->mtx_dblist); + + /* + * Set the replication timestamp; it's 0 if we're not in a replicated + * environment. Don't acquire a lock to read the value, even though + * it's opaque: all we check later is value equality, nothing else. + */ + dbp->timestamp = REP_ON(env) ? + ((REGENV *)env->reginfo->primary)->rep_timestamp : 0; + /* + * Set the replication generation number for fid management; valid + * replication generations start at 1. Don't acquire a lock to + * read the value. All we check later is value equality. + */ + db_rep = env->rep_handle; + dbp->fid_gen = REP_ON(env) ? ((REP *)db_rep->region)->gen : 0; + + /* If not RPC, open a backing DB_MPOOLFILE handle in the memory pool. */ + if (!RPC_ON(dbenv) && (ret = __memp_fcreate(env, &dbp->mpf)) != 0) + goto err; + + dbp->type = DB_UNKNOWN; + + *dbpp = dbp; + return (0); + +err: if (dbp != NULL) { + if (dbp->mpf != NULL) + (void)__memp_fclose(dbp->mpf, 0); + __os_free(env, dbp); + } + + if (F_ISSET(env, ENV_DBLOCAL)) + (void)__env_close(dbp->dbenv, 0); + + return (ret); +} + +/* + * __db_init -- + * Initialize a DB structure. + */ +static int +__db_init(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + int ret; + + dbp->locker = NULL; + LOCK_INIT(dbp->handle_lock); + + TAILQ_INIT(&dbp->free_queue); + TAILQ_INIT(&dbp->active_queue); + TAILQ_INIT(&dbp->join_queue); + LIST_INIT(&dbp->s_secondaries); + + FLD_SET(dbp->am_ok, + DB_OK_BTREE | DB_OK_HASH | DB_OK_QUEUE | DB_OK_RECNO); + + /* DB PUBLIC HANDLE LIST BEGIN */ + dbp->associate = __db_associate_pp; + dbp->associate_foreign = __db_associate_foreign_pp; + dbp->close = __db_close_pp; + dbp->compact = __db_compact_pp; + dbp->cursor = __db_cursor_pp; + dbp->del = __db_del_pp; + dbp->dump = __db_dump_pp; + dbp->err = __dbh_err; + dbp->errx = __dbh_errx; + dbp->exists = __db_exists; + dbp->fd = __db_fd_pp; + dbp->get = __db_get_pp; + dbp->get_alloc = __db_get_alloc; + dbp->get_append_recno = __db_get_append_recno; + dbp->get_byteswapped = __db_get_byteswapped; + dbp->get_cachesize = __db_get_cachesize; + dbp->get_create_dir = __db_get_create_dir; + dbp->get_dbname = __db_get_dbname; + dbp->get_dup_compare = __db_get_dup_compare; + dbp->get_encrypt_flags = __db_get_encrypt_flags; + dbp->get_env = __db_get_env; + dbp->get_errcall = __db_get_errcall; + dbp->get_errfile = __db_get_errfile; + dbp->get_errpfx = __db_get_errpfx; + dbp->get_feedback = __db_get_feedback; + dbp->get_flags = __db_get_flags; + dbp->get_lorder = __db_get_lorder; + dbp->get_mpf = __db_get_mpf; + dbp->get_msgcall = __db_get_msgcall; + dbp->get_msgfile = __db_get_msgfile; + dbp->get_multiple = __db_get_multiple; + dbp->get_open_flags = __db_get_open_flags; + dbp->get_partition_dirs = __partition_get_dirs; + dbp->get_partition_callback = __partition_get_callback; + dbp->get_partition_keys = __partition_get_keys; + dbp->get_pagesize = __db_get_pagesize; + dbp->get_priority = __db_get_priority; + dbp->get_transactional = __db_get_transactional; + dbp->get_type = __db_get_type; + dbp->join = __db_join_pp; + dbp->key_range = __db_key_range_pp; + dbp->open = __db_open_pp; + dbp->pget = __db_pget_pp; + dbp->put = __db_put_pp; + dbp->remove = __db_remove_pp; + dbp->rename = __db_rename_pp; + dbp->set_alloc = __db_set_alloc; + dbp->set_append_recno = __db_set_append_recno; + dbp->set_cachesize = __db_set_cachesize; + dbp->set_create_dir = __db_set_create_dir; + dbp->set_dup_compare = __db_set_dup_compare; + dbp->set_encrypt = __db_set_encrypt; + dbp->set_errcall = __db_set_errcall; + dbp->set_errfile = __db_set_errfile; + dbp->set_errpfx = __db_set_errpfx; + dbp->set_feedback = __db_set_feedback; + dbp->set_flags = __db_set_flags; + dbp->set_lorder = __db_set_lorder; + dbp->set_msgcall = __db_set_msgcall; + dbp->set_msgfile = __db_set_msgfile; + dbp->set_pagesize = __db_set_pagesize; + dbp->set_paniccall = __db_set_paniccall; + dbp->set_partition = __partition_set; + dbp->set_partition_dirs = __partition_set_dirs; + dbp->set_priority = __db_set_priority; + dbp->sort_multiple = __db_sort_multiple; + dbp->stat = __db_stat_pp; + dbp->stat_print = __db_stat_print_pp; + dbp->sync = __db_sync_pp; + dbp->truncate = __db_truncate_pp; + dbp->upgrade = __db_upgrade_pp; + dbp->verify = __db_verify_pp; + /* DB PUBLIC HANDLE LIST END */ + + /* Access method specific. */ + if ((ret = __bam_db_create(dbp)) != 0) + return (ret); + if ((ret = __ham_db_create(dbp)) != 0) + return (ret); + if ((ret = __qam_db_create(dbp)) != 0) + return (ret); + +#ifdef HAVE_RPC + /* + * RPC specific: must be last, as we replace methods set by the + * access methods. + */ + if (RPC_ON(dbp->dbenv)) { + __dbcl_dbp_init(dbp); + /* + * !!! + * We wrap the DB->open method for RPC, and the rpc.src file + * can't handle that. + */ + dbp->open = __dbcl_db_open_wrap; + if ((ret = __dbcl_db_create(dbp, dbp->dbenv, flags)) != 0) + return (ret); + } +#else + COMPQUIET(flags, 0); +#endif + + return (0); +} + +/* + * __dbh_am_chk -- + * Error if an unreasonable method is called. + * + * PUBLIC: int __dbh_am_chk __P((DB *, u_int32_t)); + */ +int +__dbh_am_chk(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + /* + * We start out allowing any access methods to be called, and as the + * application calls the methods the options become restricted. The + * idea is to quit as soon as an illegal method combination is called. + */ + if ((LF_ISSET(DB_OK_BTREE) && FLD_ISSET(dbp->am_ok, DB_OK_BTREE)) || + (LF_ISSET(DB_OK_HASH) && FLD_ISSET(dbp->am_ok, DB_OK_HASH)) || + (LF_ISSET(DB_OK_QUEUE) && FLD_ISSET(dbp->am_ok, DB_OK_QUEUE)) || + (LF_ISSET(DB_OK_RECNO) && FLD_ISSET(dbp->am_ok, DB_OK_RECNO))) { + FLD_CLR(dbp->am_ok, ~flags); + return (0); + } + + __db_errx(dbp->env, + "call implies an access method which is inconsistent with previous calls"); + return (EINVAL); +} + +/* + * __dbh_err -- + * Db.err method. + */ +static void +#ifdef STDC_HEADERS +__dbh_err(DB *dbp, int error, const char *fmt, ...) +#else +__dbh_err(dbp, error, fmt, va_alist) + DB *dbp; + int error; + const char *fmt; + va_dcl +#endif +{ + /* Message with error string, to stderr by default. */ + DB_REAL_ERR(dbp->dbenv, error, DB_ERROR_SET, 1, fmt); +} + +/* + * __dbh_errx -- + * Db.errx method. + */ +static void +#ifdef STDC_HEADERS +__dbh_errx(DB *dbp, const char *fmt, ...) +#else +__dbh_errx(dbp, fmt, va_alist) + DB *dbp; + const char *fmt; + va_dcl +#endif +{ + /* Message without error string, to stderr by default. */ + DB_REAL_ERR(dbp->dbenv, 0, DB_ERROR_NOT_SET, 1, fmt); +} + +/* + * __db_get_byteswapped -- + * Return if database requires byte swapping. + */ +static int +__db_get_byteswapped(dbp, isswapped) + DB *dbp; + int *isswapped; +{ + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_byteswapped"); + + *isswapped = F_ISSET(dbp, DB_AM_SWAP) ? 1 : 0; + return (0); +} + +/* + * __db_get_dbname -- + * Get the name of the database as passed to DB->open. + */ +static int +__db_get_dbname(dbp, fnamep, dnamep) + DB *dbp; + const char **fnamep, **dnamep; +{ + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_dbname"); + + if (fnamep != NULL) + *fnamep = dbp->fname; + if (dnamep != NULL) + *dnamep = dbp->dname; + return (0); +} + +/* + * __db_get_env -- + * Get the DB_ENV handle that was passed to db_create. + */ +static DB_ENV * +__db_get_env(dbp) + DB *dbp; +{ + return (dbp->dbenv); +} + +/* + * __db_get_mpf -- + * Get the underlying DB_MPOOLFILE handle. + */ +static DB_MPOOLFILE * +__db_get_mpf(dbp) + DB *dbp; +{ + return (dbp->mpf); +} + +/* + * get_multiple -- + * Return whether this DB handle references a physical file with multiple + * databases. + */ +static int +__db_get_multiple(dbp) + DB *dbp; +{ + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_multiple"); + + /* + * Only return TRUE if the handle is for the master database, not for + * any subdatabase in the physical file. If it's a Btree, with the + * subdatabases flag set, and the meta-data page has the right value, + * return TRUE. (We don't need to check it's a Btree, I suppose, but + * it doesn't hurt.) + */ + return (dbp->type == DB_BTREE && + F_ISSET(dbp, DB_AM_SUBDB) && + dbp->meta_pgno == PGNO_BASE_MD ? 1 : 0); +} + +/* + * get_transactional -- + * Return whether this database was created in a transaction. + */ +static int +__db_get_transactional(dbp) + DB *dbp; +{ + return (F_ISSET(dbp, DB_AM_TXN) ? 1 : 0); +} + +/* + * __db_get_type -- + * Return type of underlying database. + */ +static int +__db_get_type(dbp, dbtype) + DB *dbp; + DBTYPE *dbtype; +{ + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_type"); + + *dbtype = dbp->type; + return (0); +} + +/* + * __db_get_append_recno -- + * Get record number append routine. + */ +static int +__db_get_append_recno(dbp, funcp) + DB *dbp; + int (**funcp) __P((DB *, DBT *, db_recno_t)); +{ + DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); + if (funcp) + *funcp = dbp->db_append_recno; + + return (0); +} +/* + * __db_set_append_recno -- + * Set record number append routine. + */ +static int +__db_set_append_recno(dbp, func) + DB *dbp; + int (*func) __P((DB *, DBT *, db_recno_t)); +{ + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_append_recno"); + DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); + + dbp->db_append_recno = func; + + return (0); +} + +/* + * __db_get_cachesize -- + * Get underlying cache size. + */ +static int +__db_get_cachesize(dbp, cache_gbytesp, cache_bytesp, ncachep) + DB *dbp; + u_int32_t *cache_gbytesp, *cache_bytesp; + int *ncachep; +{ + DB_ILLEGAL_IN_ENV(dbp, "DB->get_cachesize"); + + return (__memp_get_cachesize(dbp->dbenv, + cache_gbytesp, cache_bytesp, ncachep)); +} + +/* + * __db_set_cachesize -- + * Set underlying cache size. + */ +static int +__db_set_cachesize(dbp, cache_gbytes, cache_bytes, ncache) + DB *dbp; + u_int32_t cache_gbytes, cache_bytes; + int ncache; +{ + DB_ILLEGAL_IN_ENV(dbp, "DB->set_cachesize"); + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_cachesize"); + + return (__memp_set_cachesize( + dbp->dbenv, cache_gbytes, cache_bytes, ncache)); +} + +static int +__db_set_create_dir(dbp, dir) + DB *dbp; + const char *dir; +{ + DB_ENV *dbenv; + int i; + + dbenv = dbp->dbenv; + + for (i = 0; i < dbenv->data_next; i++) + if (strcmp(dir, dbenv->db_data_dir[i]) == 0) + break; + + if (i == dbenv->data_next) { + __db_errx(dbp->env, + "Directory %s not in environment list.", dir); + return (EINVAL); + } + + dbp->dirname = dbenv->db_data_dir[i]; + return (0); +} + +static int +__db_get_create_dir(dbp, dirp) + DB *dbp; + const char **dirp; +{ + *dirp = dbp->dirname; + return (0); +} + +/* + * __db_get_dup_compare -- + * Get duplicate comparison routine. + */ +static int +__db_get_dup_compare(dbp, funcp) + DB *dbp; + int (**funcp) __P((DB *, const DBT *, const DBT *)); +{ + + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH); + + if (funcp != NULL) { +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp)) { + *funcp = + ((BTREE *)dbp->bt_internal)->compress_dup_compare; + } else +#endif + *funcp = dbp->dup_compare; + } + + return (0); +} + +/* + * __db_set_dup_compare -- + * Set duplicate comparison routine. + */ +static int +__db_set_dup_compare(dbp, func) + DB *dbp; + int (*func) __P((DB *, const DBT *, const DBT *)); +{ + int ret; + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_dup_compare"); + DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH); + + if ((ret = __db_set_flags(dbp, DB_DUPSORT)) != 0) + return (ret); + +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp)) { + dbp->dup_compare = __bam_compress_dupcmp; + ((BTREE *)dbp->bt_internal)->compress_dup_compare = func; + } else +#endif + dbp->dup_compare = func; + + return (0); +} + +/* + * __db_get_encrypt_flags -- + */ +static int +__db_get_encrypt_flags(dbp, flagsp) + DB *dbp; + u_int32_t *flagsp; +{ + DB_ILLEGAL_IN_ENV(dbp, "DB->get_encrypt_flags"); + + return (__env_get_encrypt_flags(dbp->dbenv, flagsp)); +} + +/* + * __db_set_encrypt -- + * Set database passwd. + */ +static int +__db_set_encrypt(dbp, passwd, flags) + DB *dbp; + const char *passwd; + u_int32_t flags; +{ + DB_CIPHER *db_cipher; + int ret; + + DB_ILLEGAL_IN_ENV(dbp, "DB->set_encrypt"); + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_encrypt"); + + if ((ret = __env_set_encrypt(dbp->dbenv, passwd, flags)) != 0) + return (ret); + + /* + * In a real env, this gets initialized with the region. In a local + * env, we must do it here. + */ + db_cipher = dbp->env->crypto_handle; + if (!F_ISSET(db_cipher, CIPHER_ANY) && + (ret = db_cipher->init(dbp->env, db_cipher)) != 0) + return (ret); + + return (__db_set_flags(dbp, DB_ENCRYPT)); +} + +static void +__db_get_errcall(dbp, errcallp) + DB *dbp; + void (**errcallp) __P((const DB_ENV *, const char *, const char *)); +{ + __env_get_errcall(dbp->dbenv, errcallp); +} + +static void +__db_set_errcall(dbp, errcall) + DB *dbp; + void (*errcall) __P((const DB_ENV *, const char *, const char *)); +{ + __env_set_errcall(dbp->dbenv, errcall); +} + +static void +__db_get_errfile(dbp, errfilep) + DB *dbp; + FILE **errfilep; +{ + __env_get_errfile(dbp->dbenv, errfilep); +} + +static void +__db_set_errfile(dbp, errfile) + DB *dbp; + FILE *errfile; +{ + __env_set_errfile(dbp->dbenv, errfile); +} + +static void +__db_get_errpfx(dbp, errpfxp) + DB *dbp; + const char **errpfxp; +{ + __env_get_errpfx(dbp->dbenv, errpfxp); +} + +static void +__db_set_errpfx(dbp, errpfx) + DB *dbp; + const char *errpfx; +{ + __env_set_errpfx(dbp->dbenv, errpfx); +} + +static int +__db_get_feedback(dbp, feedbackp) + DB *dbp; + void (**feedbackp) __P((DB *, int, int)); +{ + if (feedbackp != NULL) + *feedbackp = dbp->db_feedback; + return (0); +} + +static int +__db_set_feedback(dbp, feedback) + DB *dbp; + void (*feedback) __P((DB *, int, int)); +{ + dbp->db_feedback = feedback; + return (0); +} + +/* + * __db_map_flags -- + * Maps between public and internal flag values. + * This function doesn't check for validity, so it can't fail. + */ +static void +__db_map_flags(dbp, inflagsp, outflagsp) + DB *dbp; + u_int32_t *inflagsp, *outflagsp; +{ + COMPQUIET(dbp, NULL); + + if (FLD_ISSET(*inflagsp, DB_CHKSUM)) { + FLD_SET(*outflagsp, DB_AM_CHKSUM); + FLD_CLR(*inflagsp, DB_CHKSUM); + } + if (FLD_ISSET(*inflagsp, DB_ENCRYPT)) { + FLD_SET(*outflagsp, DB_AM_ENCRYPT | DB_AM_CHKSUM); + FLD_CLR(*inflagsp, DB_ENCRYPT); + } + if (FLD_ISSET(*inflagsp, DB_TXN_NOT_DURABLE)) { + FLD_SET(*outflagsp, DB_AM_NOT_DURABLE); + FLD_CLR(*inflagsp, DB_TXN_NOT_DURABLE); + } +} + +/* + * __db_get_flags -- + * The DB->get_flags method. + * + * PUBLIC: int __db_get_flags __P((DB *, u_int32_t *)); + */ +int +__db_get_flags(dbp, flagsp) + DB *dbp; + u_int32_t *flagsp; +{ + static const u_int32_t db_flags[] = { + DB_CHKSUM, + DB_DUP, + DB_DUPSORT, + DB_ENCRYPT, +#ifdef HAVE_QUEUE + DB_INORDER, +#endif + DB_RECNUM, + DB_RENUMBER, + DB_REVSPLITOFF, + DB_SNAPSHOT, + DB_TXN_NOT_DURABLE, + 0 + }; + u_int32_t f, flags, mapped_flag; + int i; + + flags = 0; + for (i = 0; (f = db_flags[i]) != 0; i++) { + mapped_flag = 0; + __db_map_flags(dbp, &f, &mapped_flag); + __bam_map_flags(dbp, &f, &mapped_flag); + __ram_map_flags(dbp, &f, &mapped_flag); +#ifdef HAVE_QUEUE + __qam_map_flags(dbp, &f, &mapped_flag); +#endif + DB_ASSERT(dbp->env, f == 0); + if (F_ISSET(dbp, mapped_flag) == mapped_flag) + LF_SET(db_flags[i]); + } + + *flagsp = flags; + return (0); +} + +/* + * __db_set_flags -- + * DB->set_flags. + * + * PUBLIC: int __db_set_flags __P((DB *, u_int32_t)); + */ +int +__db_set_flags(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + ENV *env; + int ret; + + env = dbp->env; + + if (LF_ISSET(DB_ENCRYPT) && !CRYPTO_ON(env)) { + __db_errx(env, + "Database environment not configured for encryption"); + return (EINVAL); + } + if (LF_ISSET(DB_TXN_NOT_DURABLE)) + ENV_REQUIRES_CONFIG(env, + env->tx_handle, "DB_NOT_DURABLE", DB_INIT_TXN); + + __db_map_flags(dbp, &flags, &dbp->flags); + + if ((ret = __bam_set_flags(dbp, &flags)) != 0) + return (ret); + if ((ret = __ram_set_flags(dbp, &flags)) != 0) + return (ret); +#ifdef HAVE_QUEUE + if ((ret = __qam_set_flags(dbp, &flags)) != 0) + return (ret); +#endif + + return (flags == 0 ? 0 : __db_ferr(env, "DB->set_flags", 0)); +} + +/* + * __db_get_lorder -- + * Get whether lorder is swapped or not. + * + * PUBLIC: int __db_get_lorder __P((DB *, int *)); + */ +int +__db_get_lorder(dbp, db_lorderp) + DB *dbp; + int *db_lorderp; +{ + int ret; + + /* Flag if the specified byte order requires swapping. */ + switch (ret = __db_byteorder(dbp->env, 1234)) { + case 0: + *db_lorderp = F_ISSET(dbp, DB_AM_SWAP) ? 4321 : 1234; + break; + case DB_SWAPBYTES: + *db_lorderp = F_ISSET(dbp, DB_AM_SWAP) ? 1234 : 4321; + break; + default: + return (ret); + /* NOTREACHED */ + } + + return (0); +} + +/* + * __db_set_lorder -- + * Set whether lorder is swapped or not. + * + * PUBLIC: int __db_set_lorder __P((DB *, int)); + */ +int +__db_set_lorder(dbp, db_lorder) + DB *dbp; + int db_lorder; +{ + int ret; + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_lorder"); + + /* Flag if the specified byte order requires swapping. */ + switch (ret = __db_byteorder(dbp->env, db_lorder)) { + case 0: + F_CLR(dbp, DB_AM_SWAP); + break; + case DB_SWAPBYTES: + F_SET(dbp, DB_AM_SWAP); + break; + default: + return (ret); + /* NOTREACHED */ + } + return (0); +} + +static int +__db_get_alloc(dbp, mal_funcp, real_funcp, free_funcp) + DB *dbp; + void *(**mal_funcp) __P((size_t)); + void *(**real_funcp) __P((void *, size_t)); + void (**free_funcp) __P((void *)); +{ + DB_ILLEGAL_IN_ENV(dbp, "DB->get_alloc"); + + return (__env_get_alloc(dbp->dbenv, mal_funcp, + real_funcp, free_funcp)); +} + +static int +__db_set_alloc(dbp, mal_func, real_func, free_func) + DB *dbp; + void *(*mal_func) __P((size_t)); + void *(*real_func) __P((void *, size_t)); + void (*free_func) __P((void *)); +{ + DB_ILLEGAL_IN_ENV(dbp, "DB->set_alloc"); + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_alloc"); + + return (__env_set_alloc(dbp->dbenv, mal_func, real_func, free_func)); +} + +static void +__db_get_msgcall(dbp, msgcallp) + DB *dbp; + void (**msgcallp) __P((const DB_ENV *, const char *)); +{ + __env_get_msgcall(dbp->dbenv, msgcallp); +} + +static void +__db_set_msgcall(dbp, msgcall) + DB *dbp; + void (*msgcall) __P((const DB_ENV *, const char *)); +{ + __env_set_msgcall(dbp->dbenv, msgcall); +} + +static void +__db_get_msgfile(dbp, msgfilep) + DB *dbp; + FILE **msgfilep; +{ + __env_get_msgfile(dbp->dbenv, msgfilep); +} + +static void +__db_set_msgfile(dbp, msgfile) + DB *dbp; + FILE *msgfile; +{ + __env_set_msgfile(dbp->dbenv, msgfile); +} + +static int +__db_get_pagesize(dbp, db_pagesizep) + DB *dbp; + u_int32_t *db_pagesizep; +{ + *db_pagesizep = dbp->pgsize; + return (0); +} + +/* + * __db_set_pagesize -- + * DB->set_pagesize + * + * PUBLIC: int __db_set_pagesize __P((DB *, u_int32_t)); + */ +int +__db_set_pagesize(dbp, db_pagesize) + DB *dbp; + u_int32_t db_pagesize; +{ + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_pagesize"); + + if (db_pagesize < DB_MIN_PGSIZE) { + __db_errx(dbp->env, "page sizes may not be smaller than %lu", + (u_long)DB_MIN_PGSIZE); + return (EINVAL); + } + if (db_pagesize > DB_MAX_PGSIZE) { + __db_errx(dbp->env, "page sizes may not be larger than %lu", + (u_long)DB_MAX_PGSIZE); + return (EINVAL); + } + + /* + * We don't want anything that's not a power-of-2, as we rely on that + * for alignment of various types on the pages. + */ + if (!POWER_OF_TWO(db_pagesize)) { + __db_errx(dbp->env, "page sizes must be a power-of-2"); + return (EINVAL); + } + + /* + * XXX + * Should we be checking for a page size that's not a multiple of 512, + * so that we never try and write less than a disk sector? + */ + dbp->pgsize = db_pagesize; + + return (0); +} + +static int +__db_set_paniccall(dbp, paniccall) + DB *dbp; + void (*paniccall) __P((DB_ENV *, int)); +{ + return (__env_set_paniccall(dbp->dbenv, paniccall)); +} + +static int +__db_set_priority(dbp, priority) + DB *dbp; + DB_CACHE_PRIORITY priority; +{ + dbp->priority = priority; + return (0); +} + +static int +__db_get_priority(dbp, priority) + DB *dbp; + DB_CACHE_PRIORITY *priority; +{ + *priority = dbp->priority; + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_open.c b/src/libs/resiprocate/contrib/db/db/db_open.c new file mode 100644 index 00000000..5c5db09e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_open.c @@ -0,0 +1,628 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_swap.h" +#include "dbinc/btree.h" +#include "dbinc/crypto.h" +#include "dbinc/hmac.h" +#include "dbinc/fop.h" +#include "dbinc/hash.h" +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/qam.h" +#include "dbinc/txn.h" + +/* + * __db_open -- + * DB->open method. + * + * This routine gets called in three different ways: + * + * 1. It can be called to open a file/database. In this case, subdb will + * be NULL and meta_pgno will be PGNO_BASE_MD. + * 2. It can be called to open a subdatabase during normal operation. In + * this case, name and subname will both be non-NULL and meta_pgno will + * be PGNO_BASE_MD (also PGNO_INVALID). + * 3. It can be called to open an in-memory database (name == NULL; + * subname = name). + * 4. It can be called during recovery to open a file/database, in which case + * name will be non-NULL, subname will be NULL, and meta-pgno will be + * PGNO_BASE_MD. + * 5. It can be called during recovery to open a subdatabase, in which case + * name will be non-NULL, subname may be NULL and meta-pgno will be + * a valid pgno (i.e., not PGNO_BASE_MD). + * 6. It can be called during recovery to open an in-memory database. + * + * PUBLIC: int __db_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, + * PUBLIC: const char *, const char *, DBTYPE, u_int32_t, int, db_pgno_t)); + */ +int +__db_open(dbp, ip, txn, fname, dname, type, flags, mode, meta_pgno) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + const char *fname, *dname; + DBTYPE type; + u_int32_t flags; + int mode; + db_pgno_t meta_pgno; +{ + DB *tdbp; + ENV *env; + int ret; + u_int32_t id; + + env = dbp->env; + id = TXN_INVALID; + + /* + * We must flush any existing pages before truncating the file + * since they could age out of mpool and overwrite new pages. + */ + if (LF_ISSET(DB_TRUNCATE)) { + if ((ret = __db_create_internal(&tdbp, dbp->env, 0)) != 0) + goto err; + ret = __db_open(tdbp, ip, txn, fname, dname, DB_UNKNOWN, + DB_NOERROR | (flags & ~(DB_TRUNCATE|DB_CREATE)), + mode, meta_pgno); + if (ret == 0) + ret = __memp_ftruncate(tdbp->mpf, txn, ip, 0, 0); + (void)__db_close(tdbp, txn, DB_NOSYNC); + if (ret != 0 && ret != ENOENT && ret != EINVAL) + goto err; + ret = 0; + } + + DB_TEST_RECOVERY(dbp, DB_TEST_PREOPEN, ret, fname); + + /* + * If the environment was configured with threads, the DB handle + * must also be free-threaded, so we force the DB_THREAD flag on. + * (See SR #2033 for why this is a requirement--recovery needs + * to be able to grab a dbp using __db_fileid_to_dbp, and it has + * no way of knowing which dbp goes with which thread, so whichever + * one it finds has to be usable in any of them.) + */ + if (F_ISSET(env, ENV_THREAD)) + LF_SET(DB_THREAD); + + /* Convert any DB->open flags. */ + if (LF_ISSET(DB_RDONLY)) + F_SET(dbp, DB_AM_RDONLY); + if (LF_ISSET(DB_READ_UNCOMMITTED)) + F_SET(dbp, DB_AM_READ_UNCOMMITTED); + + if (IS_REAL_TXN(txn)) + F_SET(dbp, DB_AM_TXN); + + /* Fill in the type. */ + dbp->type = type; + + /* + * If both fname and subname are NULL, it's always a create, so make + * sure that we have both DB_CREATE and a type specified. It would + * be nice if this checking were done in __db_open where most of the + * interface checking is done, but this interface (__db_dbopen) is + * used by the recovery and limbo system, so we need to safeguard + * this interface as well. + */ + if (fname == NULL) { + if (dbp->p_internal != NULL) { + __db_errx(env, + "Partitioned databases may not be in memory."); + return (ENOENT); + } + if (dname == NULL) { + if (!LF_ISSET(DB_CREATE)) { + __db_errx(env, + "DB_CREATE must be specified to create databases."); + return (ENOENT); + } + + F_SET(dbp, DB_AM_INMEM); + F_SET(dbp, DB_AM_CREATED); + + if (dbp->type == DB_UNKNOWN) { + __db_errx(env, + "DBTYPE of unknown without existing file"); + return (EINVAL); + } + + if (dbp->pgsize == 0) + dbp->pgsize = DB_DEF_IOSIZE; + + /* + * If the file is a temporary file and we're + * doing locking, then we have to create a + * unique file ID. We can't use our normal + * dev/inode pair (or whatever this OS uses + * in place of dev/inode pairs) because no + * backing file will be created until the + * mpool cache is filled forcing the buffers + * to disk. Grab a random locker ID to use + * as a file ID. The created ID must never + * match a potential real file ID -- we know + * it won't because real file IDs contain a + * time stamp after the dev/inode pair, and + * we're simply storing a 4-byte value. + + * !!! + * Store the locker in the file id structure + * -- we can get it from there as necessary, + * and it saves having two copies. + */ + if (LOCKING_ON(env) && (ret = __lock_id(env, + (u_int32_t *)dbp->fileid, NULL)) != 0) + return (ret); + } else + MAKE_INMEM(dbp); + + /* + * Normally we would do handle locking here, however, with + * in-memory files, we cannot do any database manipulation + * until the mpool is open, so it happens later. + */ + } else if (dname == NULL && meta_pgno == PGNO_BASE_MD) { + /* Open/create the underlying file. Acquire locks. */ + if ((ret = __fop_file_setup(dbp, ip, + txn, fname, mode, flags, &id)) != 0) + return (ret); + } else { + if (dbp->p_internal != NULL) { + __db_errx(env, + "Partitioned databases may not be included with multiple databases."); + return (ENOENT); + } + if ((ret = __fop_subdb_setup(dbp, ip, + txn, fname, dname, mode, flags)) != 0) + return (ret); + meta_pgno = dbp->meta_pgno; + } + + /* Set up the underlying environment. */ + if ((ret = __env_setup(dbp, txn, fname, dname, id, flags)) != 0) + return (ret); + + /* For in-memory databases, we now need to open/create the database. */ + if (F_ISSET(dbp, DB_AM_INMEM)) { + if (dname == NULL) + ret = __db_new_file(dbp, ip, txn, NULL, NULL); + else { + id = TXN_INVALID; + if ((ret = __fop_file_setup(dbp, ip, + txn, dname, mode, flags, &id)) == 0 && + DBENV_LOGGING(env) && !F_ISSET(dbp, DB_AM_RECOVER) +#if !defined(DEBUG_ROP) && !defined(DEBUG_WOP) && !defined(DIAGNOSTIC) + && txn != NULL +#endif +#if !defined(DEBUG_ROP) + && !F_ISSET(dbp, DB_AM_RDONLY) +#endif + ) + ret = __dbreg_log_id(dbp, + txn, dbp->log_filename->id, 1); + } + if (ret != 0) + goto err; + } + + switch (dbp->type) { + case DB_BTREE: + ret = __bam_open(dbp, ip, txn, fname, meta_pgno, flags); + break; + case DB_HASH: + ret = __ham_open(dbp, ip, txn, fname, meta_pgno, flags); + break; + case DB_RECNO: + ret = __ram_open(dbp, ip, txn, fname, meta_pgno, flags); + break; + case DB_QUEUE: + ret = __qam_open( + dbp, ip, txn, fname, meta_pgno, mode, flags); + break; + case DB_UNKNOWN: + return ( + __db_unknown_type(env, "__db_dbopen", dbp->type)); + } + if (ret != 0) + goto err; + +#ifdef HAVE_PARTITION + if (dbp->p_internal != NULL && (ret = + __partition_open(dbp, ip, txn, fname, type, flags, mode, 1)) != 0) + goto err; +#endif + DB_TEST_RECOVERY(dbp, DB_TEST_POSTOPEN, ret, fname); + + /* + * Temporary files don't need handle locks, so we only have to check + * for a handle lock downgrade or lockevent in the case of named + * files. + */ + if (!F_ISSET(dbp, DB_AM_RECOVER) && (fname != NULL || dname != NULL) && + LOCK_ISSET(dbp->handle_lock)) { + if (IS_REAL_TXN(txn)) + ret = __txn_lockevent(env, + txn, dbp, &dbp->handle_lock, dbp->locker); + else if (LOCKING_ON(env)) + /* Trade write handle lock for read handle lock. */ + ret = __lock_downgrade(env, + &dbp->handle_lock, DB_LOCK_READ, 0); + } +DB_TEST_RECOVERY_LABEL +err: + return (ret); +} + +/* + * __db_get_open_flags -- + * Accessor for flags passed into DB->open call + * + * PUBLIC: int __db_get_open_flags __P((DB *, u_int32_t *)); + */ +int +__db_get_open_flags(dbp, flagsp) + DB *dbp; + u_int32_t *flagsp; +{ + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_open_flags"); + + *flagsp = dbp->open_flags; + return (0); +} + +/* + * __db_new_file -- + * Create a new database file. + * + * PUBLIC: int __db_new_file __P((DB *, + * PUBLIC: DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *)); + */ +int +__db_new_file(dbp, ip, txn, fhp, name) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + DB_FH *fhp; + const char *name; +{ + int ret; + + switch (dbp->type) { + case DB_BTREE: + case DB_RECNO: + ret = __bam_new_file(dbp, ip, txn, fhp, name); + break; + case DB_HASH: + ret = __ham_new_file(dbp, ip, txn, fhp, name); + break; + case DB_QUEUE: + ret = __qam_new_file(dbp, ip, txn, fhp, name); + break; + case DB_UNKNOWN: + default: + __db_errx(dbp->env, + "%s: Invalid type %d specified", name, dbp->type); + ret = EINVAL; + break; + } + + DB_TEST_RECOVERY(dbp, DB_TEST_POSTLOGMETA, ret, name); + /* Sync the file in preparation for moving it into place. */ + if (ret == 0 && fhp != NULL) + ret = __os_fsync(dbp->env, fhp); + + DB_TEST_RECOVERY(dbp, DB_TEST_POSTSYNC, ret, name); + +DB_TEST_RECOVERY_LABEL + return (ret); +} + +/* + * __db_init_subdb -- + * Initialize the dbp for a subdb. + * + * PUBLIC: int __db_init_subdb __P((DB *, + * PUBLIC: DB *, const char *, DB_THREAD_INFO *, DB_TXN *)); + */ +int +__db_init_subdb(mdbp, dbp, name, ip, txn) + DB *mdbp, *dbp; + const char *name; + DB_THREAD_INFO *ip; + DB_TXN *txn; +{ + DBMETA *meta; + DB_MPOOLFILE *mpf; + int ret, t_ret; + + ret = 0; + if (!F_ISSET(dbp, DB_AM_CREATED)) { + /* Subdb exists; read meta-data page and initialize. */ + mpf = mdbp->mpf; + if ((ret = __memp_fget(mpf, &dbp->meta_pgno, + ip, txn, 0, &meta)) != 0) + goto err; + ret = __db_meta_setup(mdbp->env, dbp, name, meta, 0, 0); + if ((t_ret = __memp_fput(mpf, + ip, meta, dbp->priority)) != 0 && ret == 0) + ret = t_ret; + /* + * If __db_meta_setup found that the meta-page hadn't + * been written out during recovery, we can just return. + */ + if (ret == ENOENT) + ret = 0; + goto err; + } + + /* Handle the create case here. */ + switch (dbp->type) { + case DB_BTREE: + case DB_RECNO: + ret = __bam_new_subdb(mdbp, dbp, ip, txn); + break; + case DB_HASH: + ret = __ham_new_subdb(mdbp, dbp, ip, txn); + break; + case DB_QUEUE: + ret = EINVAL; + break; + case DB_UNKNOWN: + default: + __db_errx(dbp->env, + "Invalid subdatabase type %d specified", dbp->type); + return (EINVAL); + } + +err: return (ret); +} + +/* + * __db_chk_meta -- + * Take a buffer containing a meta-data page and check it for a valid LSN, + * checksum (and verify the checksum if necessary) and possibly decrypt it. + * + * Return 0 on success, >0 (errno) on error, -1 on checksum mismatch. + * + * PUBLIC: int __db_chk_meta __P((ENV *, DB *, DBMETA *, u_int32_t)); + */ +int +__db_chk_meta(env, dbp, meta, flags) + ENV *env; + DB *dbp; + DBMETA *meta; + u_int32_t flags; +{ + DB_LSN swap_lsn; + int is_hmac, ret, swapped; + u_int32_t magic, orig_chk; + u_int8_t *chksum; + + ret = 0; + swapped = 0; + + if (FLD_ISSET(meta->metaflags, DBMETA_CHKSUM)) { + if (dbp != NULL) + F_SET(dbp, DB_AM_CHKSUM); + + is_hmac = meta->encrypt_alg == 0 ? 0 : 1; + chksum = ((BTMETA *)meta)->chksum; + + /* + * If we need to swap, the checksum function overwrites the + * original checksum with 0, so we need to save a copy of the + * original for swapping later. + */ + orig_chk = *(u_int32_t *)chksum; + + /* + * We cannot add this to __db_metaswap because that gets done + * later after we've verified the checksum or decrypted. + */ + if (LF_ISSET(DB_CHK_META)) { + swapped = 0; +chk_retry: if ((ret = + __db_check_chksum(env, NULL, env->crypto_handle, + chksum, meta, DBMETASIZE, is_hmac)) != 0) { + if (is_hmac || swapped) + return (ret); + + M_32_SWAP(orig_chk); + swapped = 1; + *(u_int32_t *)chksum = orig_chk; + goto chk_retry; + } + } + } else if (dbp != NULL) + F_CLR(dbp, DB_AM_CHKSUM); + +#ifdef HAVE_CRYPTO + ret = __crypto_decrypt_meta(env, + dbp, (u_int8_t *)meta, LF_ISSET(DB_CHK_META)); +#endif + + /* Now that we're decrypted, we can check LSN. */ + if (LOGGING_ON(env) && !LF_ISSET(DB_CHK_NOLSN)) { + /* + * This gets called both before and after swapping, so we + * need to check ourselves. If we already swapped it above, + * we'll know that here. + */ + + swap_lsn = meta->lsn; + magic = meta->magic; +lsn_retry: + if (swapped) { + M_32_SWAP(swap_lsn.file); + M_32_SWAP(swap_lsn.offset); + M_32_SWAP(magic); + } + switch (magic) { + case DB_BTREEMAGIC: + case DB_HASHMAGIC: + case DB_QAMMAGIC: + case DB_RENAMEMAGIC: + break; + default: + if (swapped) + return (EINVAL); + swapped = 1; + goto lsn_retry; + } + if (!IS_REP_CLIENT(env) && + !IS_NOT_LOGGED_LSN(swap_lsn) && !IS_ZERO_LSN(swap_lsn)) + /* Need to do check. */ + ret = __log_check_page_lsn(env, dbp, &swap_lsn); + } + return (ret); +} + +/* + * __db_meta_setup -- + * + * Take a buffer containing a meta-data page and figure out if it's + * valid, and if so, initialize the dbp from the meta-data page. + * + * PUBLIC: int __db_meta_setup __P((ENV *, + * PUBLIC: DB *, const char *, DBMETA *, u_int32_t, u_int32_t)); + */ +int +__db_meta_setup(env, dbp, name, meta, oflags, flags) + ENV *env; + DB *dbp; + const char *name; + DBMETA *meta; + u_int32_t oflags; + u_int32_t flags; +{ + u_int32_t magic; + int ret; + + ret = 0; + + /* + * Figure out what access method we're dealing with, and then + * call access method specific code to check error conditions + * based on conflicts between the found file and application + * arguments. A found file overrides some user information -- + * we don't consider it an error, for example, if the user set + * an expected byte order and the found file doesn't match it. + */ + F_CLR(dbp, DB_AM_SWAP | DB_AM_IN_RENAME); + magic = meta->magic; + +swap_retry: + switch (magic) { + case DB_BTREEMAGIC: + case DB_HASHMAGIC: + case DB_QAMMAGIC: + case DB_RENAMEMAGIC: + break; + case 0: + /* + * The only time this should be 0 is if we're in the + * midst of opening a subdb during recovery and that + * subdatabase had its meta-data page allocated, but + * not yet initialized. + */ + if (F_ISSET(dbp, DB_AM_SUBDB) && ((IS_RECOVERING(env) && + F_ISSET(env->lg_handle, DBLOG_FORCE_OPEN)) || + meta->pgno != PGNO_INVALID)) + return (ENOENT); + + goto bad_format; + default: + if (F_ISSET(dbp, DB_AM_SWAP)) + goto bad_format; + + M_32_SWAP(magic); + F_SET(dbp, DB_AM_SWAP); + goto swap_retry; + } + + /* + * We can only check the meta page if we are sure we have a meta page. + * If it is random data, then this check can fail. So only now can we + * checksum and decrypt. Don't distinguish between configuration and + * checksum match errors here, because we haven't opened the database + * and even a checksum error isn't a reason to panic the environment. + */ + if ((ret = __db_chk_meta(env, dbp, meta, flags)) != 0) { + if (ret == -1) + __db_errx(env, + "%s: metadata page checksum error", name); + goto bad_format; + } + + switch (magic) { + case DB_BTREEMAGIC: + if (dbp->type != DB_UNKNOWN && + dbp->type != DB_RECNO && dbp->type != DB_BTREE) + goto bad_format; + + flags = meta->flags; + if (F_ISSET(dbp, DB_AM_SWAP)) + M_32_SWAP(flags); + if (LF_ISSET(BTM_RECNO)) + dbp->type = DB_RECNO; + else + dbp->type = DB_BTREE; + if ((oflags & DB_TRUNCATE) == 0 && (ret = + __bam_metachk(dbp, name, (BTMETA *)meta)) != 0) + return (ret); + break; + case DB_HASHMAGIC: + if (dbp->type != DB_UNKNOWN && dbp->type != DB_HASH) + goto bad_format; + + dbp->type = DB_HASH; + if ((oflags & DB_TRUNCATE) == 0 && (ret = + __ham_metachk(dbp, name, (HMETA *)meta)) != 0) + return (ret); + break; + case DB_QAMMAGIC: + if (dbp->type != DB_UNKNOWN && dbp->type != DB_QUEUE) + goto bad_format; + dbp->type = DB_QUEUE; + if ((oflags & DB_TRUNCATE) == 0 && (ret = + __qam_metachk(dbp, name, (QMETA *)meta)) != 0) + return (ret); + break; + case DB_RENAMEMAGIC: + F_SET(dbp, DB_AM_IN_RENAME); + + /* Copy the file's ID. */ + memcpy(dbp->fileid, ((DBMETA *)meta)->uid, DB_FILE_ID_LEN); + + break; + default: + goto bad_format; + } + + if (FLD_ISSET(meta->metaflags, + DBMETA_PART_RANGE | DBMETA_PART_CALLBACK)) + if ((ret = + __partition_init(dbp, meta->metaflags)) != 0) + return (ret); + return (0); + +bad_format: + if (F_ISSET(dbp, DB_AM_RECOVER)) + ret = ENOENT; + else + __db_errx(env, + "__db_meta_setup: %s: unexpected file type or format", + name); + return (ret == 0 ? EINVAL : ret); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_overflow.c b/src/libs/resiprocate/contrib/db/db/db_overflow.c new file mode 100644 index 00000000..a718182a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_overflow.c @@ -0,0 +1,706 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/mp.h" + +/* + * Big key/data code. + * + * Big key and data entries are stored on linked lists of pages. The initial + * reference is a structure with the total length of the item and the page + * number where it begins. Each entry in the linked list contains a pointer + * to the next page of data, and so on. + */ + +/* + * __db_goff -- + * Get an offpage item. + * + * PUBLIC: int __db_goff __P((DBC *, + * PUBLIC: DBT *, u_int32_t, db_pgno_t, void **, u_int32_t *)); + */ +int +__db_goff(dbc, dbt, tlen, pgno, bpp, bpsz) + DBC *dbc; + DBT *dbt; + u_int32_t tlen; + db_pgno_t pgno; + void **bpp; + u_int32_t *bpsz; +{ + DB *dbp; + DB_MPOOLFILE *mpf; + DB_TXN *txn; + DBC_INTERNAL *cp; + ENV *env; + PAGE *h; + DB_THREAD_INFO *ip; + db_indx_t bytes; + u_int32_t curoff, needed, start; + u_int8_t *p, *src; + int ret; + + dbp = dbc->dbp; + cp = dbc->internal; + env = dbp->env; + ip = dbc->thread_info; + mpf = dbp->mpf; + txn = dbc->txn; + + /* + * Check if the buffer is big enough; if it is not and we are + * allowed to malloc space, then we'll malloc it. If we are + * not (DB_DBT_USERMEM), then we'll set the dbt and return + * appropriately. + */ + if (F_ISSET(dbt, DB_DBT_PARTIAL)) { + start = dbt->doff; + if (start > tlen) + needed = 0; + else if (dbt->dlen > tlen - start) + needed = tlen - start; + else + needed = dbt->dlen; + } else { + start = 0; + needed = tlen; + } + + /* + * If the caller has not requested any data, return success. This + * "early-out" also avoids setting up the streaming optimization when + * no page would be retrieved. If it were removed, the streaming code + * should only initialize when needed is not 0. + */ + if (needed == 0) { + dbt->size = 0; + return (0); + } + + if (F_ISSET(dbt, DB_DBT_USERCOPY)) + goto skip_alloc; + + /* Allocate any necessary memory. */ + if (F_ISSET(dbt, DB_DBT_USERMEM)) { + if (needed > dbt->ulen) { + dbt->size = needed; + return (DB_BUFFER_SMALL); + } + } else if (F_ISSET(dbt, DB_DBT_MALLOC)) { + if ((ret = __os_umalloc(env, needed, &dbt->data)) != 0) + return (ret); + } else if (F_ISSET(dbt, DB_DBT_REALLOC)) { + if ((ret = __os_urealloc(env, needed, &dbt->data)) != 0) + return (ret); + } else if (bpsz != NULL && (*bpsz == 0 || *bpsz < needed)) { + if ((ret = __os_realloc(env, needed, bpp)) != 0) + return (ret); + *bpsz = needed; + dbt->data = *bpp; + } else if (bpp != NULL) + dbt->data = *bpp; + else { + DB_ASSERT(env, + F_ISSET(dbt, + DB_DBT_USERMEM | DB_DBT_MALLOC | DB_DBT_REALLOC) || + bpsz != NULL || bpp != NULL); + return (DB_BUFFER_SMALL); + } + +skip_alloc: + /* Set up a start page in the overflow chain if streaming. */ + if (cp->stream_start_pgno != PGNO_INVALID && + pgno == cp->stream_start_pgno && start >= cp->stream_off && + start < cp->stream_off + P_MAXSPACE(dbp, dbp->pgsize)) { + pgno = cp->stream_curr_pgno; + curoff = cp->stream_off; + } else { + cp->stream_start_pgno = cp->stream_curr_pgno = pgno; + cp->stream_off = curoff = 0; + } + + /* + * Step through the linked list of pages, copying the data on each + * one into the buffer. Never copy more than the total data length. + */ + dbt->size = needed; + for (p = dbt->data; pgno != PGNO_INVALID && needed > 0;) { + if ((ret = __memp_fget(mpf, + &pgno, ip, txn, 0, &h)) != 0) + return (ret); + DB_ASSERT(env, TYPE(h) == P_OVERFLOW); + + /* Check if we need any bytes from this page. */ + if (curoff + OV_LEN(h) >= start) { + bytes = OV_LEN(h); + src = (u_int8_t *)h + P_OVERHEAD(dbp); + if (start > curoff) { + src += start - curoff; + bytes -= start - curoff; + } + if (bytes > needed) + bytes = needed; + if (F_ISSET(dbt, DB_DBT_USERCOPY)) { + /* + * The offset into the DBT is the total size + * less the amount of data still needed. Care + * needs to be taken if doing a partial copy + * beginning at an offset other than 0. + */ + if ((ret = env->dbt_usercopy( + dbt, dbt->size - needed, + src, bytes, DB_USERCOPY_SETDATA)) != 0) { + (void)__memp_fput(mpf, + ip, h, dbp->priority); + return (ret); + } + } else + memcpy(p, src, bytes); + p += bytes; + needed -= bytes; + } + cp->stream_off = curoff; + curoff += OV_LEN(h); + cp->stream_curr_pgno = pgno; + pgno = h->next_pgno; + (void)__memp_fput(mpf, ip, h, dbp->priority); + } + + return (0); +} + +/* + * __db_poff -- + * Put an offpage item. + * + * PUBLIC: int __db_poff __P((DBC *, const DBT *, db_pgno_t *)); + */ +int +__db_poff(dbc, dbt, pgnop) + DBC *dbc; + const DBT *dbt; + db_pgno_t *pgnop; +{ + DB *dbp; + DBT tmp_dbt; + DB_LSN null_lsn; + DB_MPOOLFILE *mpf; + PAGE *pagep, *lastp; + db_indx_t pagespace; + db_pgno_t pgno; + u_int32_t space, sz, tlen; + u_int8_t *p; + int ret, t_ret; + + /* + * Allocate pages and copy the key/data item into them. Calculate the + * number of bytes we get for pages we fill completely with a single + * item. + */ + dbp = dbc->dbp; + lastp = NULL; + mpf = dbp->mpf; + pagespace = P_MAXSPACE(dbp, dbp->pgsize); + p = dbt->data; + sz = dbt->size; + + /* + * Check whether we are streaming at the end of the overflow item. + * If so, the last pgno and offset will be cached in the cursor. + */ + if (F_ISSET(dbt, DB_DBT_STREAMING)) { + tlen = dbt->size - dbt->dlen; + pgno = dbc->internal->stream_curr_pgno; + if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, + dbc->txn, DB_MPOOL_DIRTY, &lastp)) != 0) + return (ret); + + /* + * Calculate how much we can write on the last page of the + * overflow item. + */ + DB_ASSERT(dbp->env, + OV_LEN(lastp) == (tlen - dbc->internal->stream_off)); + space = pagespace - OV_LEN(lastp); + + /* Only copy as much data as we have. */ + if (space > dbt->dlen) + space = dbt->dlen; + + if (DBC_LOGGING(dbc)) { + tmp_dbt.data = dbt->data; + tmp_dbt.size = space; + ZERO_LSN(null_lsn); + if ((ret = __db_big_log(dbp, dbc->txn, + &LSN(lastp), 0, DB_APPEND_BIG, pgno, + PGNO_INVALID, PGNO_INVALID, &tmp_dbt, + &LSN(lastp), &null_lsn, &null_lsn)) != 0) + goto err; + } else + LSN_NOT_LOGGED(LSN(lastp)); + + memcpy((u_int8_t *)lastp + P_OVERHEAD(dbp) + OV_LEN(lastp), + dbt->data, space); + OV_LEN(lastp) += space; + sz -= space + dbt->doff; + p += space; + *pgnop = dbc->internal->stream_start_pgno; + } + + ret = 0; + for (; sz > 0; p += pagespace, sz -= pagespace) { + /* + * Reduce pagespace so we terminate the loop correctly and + * don't copy too much data. + */ + if (sz < pagespace) + pagespace = sz; + + /* + * Allocate and initialize a new page and copy all or part of + * the item onto the page. If sz is less than pagespace, we + * have a partial record. + */ + if ((ret = __db_new(dbc, P_OVERFLOW, NULL, &pagep)) != 0) + break; + if (DBC_LOGGING(dbc)) { + tmp_dbt.data = p; + tmp_dbt.size = pagespace; + ZERO_LSN(null_lsn); + if ((ret = __db_big_log(dbp, dbc->txn, + &LSN(pagep), 0, DB_ADD_BIG, PGNO(pagep), + lastp ? PGNO(lastp) : PGNO_INVALID, + PGNO_INVALID, &tmp_dbt, &LSN(pagep), + lastp == NULL ? &null_lsn : &LSN(lastp), + &null_lsn)) != 0) { + (void)__memp_fput(mpf, dbc->thread_info, + pagep, dbc->priority); + goto err; + } + } else + LSN_NOT_LOGGED(LSN(pagep)); + + /* Move LSN onto page. */ + if (lastp != NULL) + LSN(lastp) = LSN(pagep); + + OV_LEN(pagep) = pagespace; + OV_REF(pagep) = 1; + memcpy((u_int8_t *)pagep + P_OVERHEAD(dbp), p, pagespace); + + /* + * If this is the first entry, update the user's info and + * initialize the cursor to allow for streaming of subsequent + * updates. Otherwise, update the entry on the last page + * filled in and release that page. + */ + if (lastp == NULL) { + *pgnop = PGNO(pagep); + dbc->internal->stream_start_pgno = + dbc->internal->stream_curr_pgno = *pgnop; + dbc->internal->stream_off = 0; + } else { + lastp->next_pgno = PGNO(pagep); + pagep->prev_pgno = PGNO(lastp); + if ((ret = __memp_fput(mpf, + dbc->thread_info, lastp, dbc->priority)) != 0) { + lastp = NULL; + goto err; + } + } + lastp = pagep; + } +err: if (lastp != NULL) { + if (ret == 0) { + dbc->internal->stream_curr_pgno = PGNO(lastp); + dbc->internal->stream_off = dbt->size - OV_LEN(lastp); + } + + if ((t_ret = __memp_fput(mpf, dbc->thread_info, lastp, + dbc->priority)) != 0 && ret == 0) + ret = t_ret; + } + return (ret); +} + +/* + * __db_ovref -- + * Decrement the reference count on an overflow page. + * + * PUBLIC: int __db_ovref __P((DBC *, db_pgno_t)); + */ +int +__db_ovref(dbc, pgno) + DBC *dbc; + db_pgno_t pgno; +{ + DB *dbp; + DB_MPOOLFILE *mpf; + PAGE *h; + int ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + + if ((ret = __memp_fget(mpf, &pgno, + dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &h)) != 0) + return (ret); + + if (DBC_LOGGING(dbc)) { + if ((ret = __db_ovref_log(dbp, + dbc->txn, &LSN(h), 0, h->pgno, -1, &LSN(h))) != 0) { + (void)__memp_fput(mpf, + dbc->thread_info, h, dbc->priority); + return (ret); + } + } else + LSN_NOT_LOGGED(LSN(h)); + + /* + * In BDB releases before 4.5, the overflow reference counts were + * incremented when an overflow item was split onto an internal + * page. There was a lock race in that code, and rather than fix + * the race, we changed BDB to copy overflow items when splitting + * them onto internal pages. The code to decrement reference + * counts remains so databases already in the field continue to + * work. + */ + --OV_REF(h); + + return (__memp_fput(mpf, dbc->thread_info, h, dbc->priority)); +} + +/* + * __db_doff -- + * Delete an offpage chain of overflow pages. + * + * PUBLIC: int __db_doff __P((DBC *, db_pgno_t)); + */ +int +__db_doff(dbc, pgno) + DBC *dbc; + db_pgno_t pgno; +{ + DB *dbp; + DBT tmp_dbt; + DB_LSN null_lsn; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int ret; + + dbp = dbc->dbp; + mpf = dbp->mpf; + + do { + if ((ret = __memp_fget(mpf, &pgno, + dbc->thread_info, dbc->txn, 0, &pagep)) != 0) + return (ret); + + DB_ASSERT(dbp->env, TYPE(pagep) == P_OVERFLOW); + /* + * If it's referenced by more than one key/data item, + * decrement the reference count and return. + */ + if (OV_REF(pagep) > 1) { + (void)__memp_fput(mpf, + dbc->thread_info, pagep, dbc->priority); + return (__db_ovref(dbc, pgno)); + } + + if ((ret = __memp_dirty(mpf, &pagep, + dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) { + if (pagep != NULL) + (void)__memp_fput(mpf, + dbc->thread_info, pagep, dbc->priority); + return (ret); + } + + if (DBC_LOGGING(dbc)) { + tmp_dbt.data = (u_int8_t *)pagep + P_OVERHEAD(dbp); + tmp_dbt.size = OV_LEN(pagep); + ZERO_LSN(null_lsn); + if ((ret = __db_big_log(dbp, dbc->txn, + &LSN(pagep), 0, DB_REM_BIG, + PGNO(pagep), PREV_PGNO(pagep), + NEXT_PGNO(pagep), &tmp_dbt, + &LSN(pagep), &null_lsn, &null_lsn)) != 0) { + (void)__memp_fput(mpf, + dbc->thread_info, pagep, dbc->priority); + return (ret); + } + } else + LSN_NOT_LOGGED(LSN(pagep)); + pgno = pagep->next_pgno; + OV_LEN(pagep) = 0; + if ((ret = __db_free(dbc, pagep)) != 0) + return (ret); + } while (pgno != PGNO_INVALID); + + return (0); +} + +/* + * __db_moff -- + * Match on overflow pages. + * + * Given a starting page number and a key, return <0, 0, >0 to indicate if the + * key on the page is less than, equal to or greater than the key specified. + * We optimize this by doing chunk at a time comparison unless the user has + * specified a comparison function. In this case, we need to materialize + * the entire object and call their comparison routine. + * + * __db_moff and __db_coff are generic functions useful in searching and + * ordering off page items. __db_moff matches an overflow DBT with an offpage + * item. __db_coff compares two offpage items for lexicographic sort order. + * + * PUBLIC: int __db_moff __P((DBC *, const DBT *, db_pgno_t, u_int32_t, + * PUBLIC: int (*)(DB *, const DBT *, const DBT *), int *)); + */ +int +__db_moff(dbc, dbt, pgno, tlen, cmpfunc, cmpp) + DBC *dbc; + const DBT *dbt; + db_pgno_t pgno; + u_int32_t tlen; + int (*cmpfunc) __P((DB *, const DBT *, const DBT *)), *cmpp; +{ + DB *dbp; + DBT local_dbt; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + void *buf; + u_int32_t bufsize, cmp_bytes, key_left; + u_int8_t *p1, *p2; + int ret; + + dbp = dbc->dbp; + ip = dbc->thread_info; + mpf = dbp->mpf; + + /* + * If there is a user-specified comparison function, build a + * contiguous copy of the key, and call it. + */ + if (cmpfunc != NULL) { + memset(&local_dbt, 0, sizeof(local_dbt)); + buf = NULL; + bufsize = 0; + + if ((ret = __db_goff(dbc, + &local_dbt, tlen, pgno, &buf, &bufsize)) != 0) + return (ret); + /* Pass the key as the first argument */ + *cmpp = cmpfunc(dbp, dbt, &local_dbt); + __os_free(dbp->env, buf); + return (0); + } + + /* While there are both keys to compare. */ + for (*cmpp = 0, p1 = dbt->data, + key_left = dbt->size; key_left > 0 && pgno != PGNO_INVALID;) { + if ((ret = + __memp_fget(mpf, &pgno, ip, dbc->txn, 0, &pagep)) != 0) + return (ret); + + cmp_bytes = OV_LEN(pagep) < key_left ? OV_LEN(pagep) : key_left; + tlen -= cmp_bytes; + key_left -= cmp_bytes; + for (p2 = (u_int8_t *)pagep + P_OVERHEAD(dbp); + cmp_bytes-- > 0; ++p1, ++p2) + if (*p1 != *p2) { + *cmpp = (long)*p1 - (long)*p2; + break; + } + pgno = NEXT_PGNO(pagep); + if ((ret = __memp_fput(mpf, ip, pagep, dbp->priority)) != 0) + return (ret); + if (*cmpp != 0) + return (0); + } + if (key_left > 0) /* DBT is longer than the page key. */ + *cmpp = 1; + else if (tlen > 0) /* DBT is shorter than the page key. */ + *cmpp = -1; + else + *cmpp = 0; + + return (0); +} + +/* + * __db_coff -- + * Match two offpage dbts. + * + * The DBTs must both refer to offpage items. + * The match happens a chunk (page) at a time unless a user defined comparison + * function exists. It is not possible to optimize this comparison away when + * a lexicographic sort order is required on mismatch. + * + * NOTE: For now this function only works for H_OFFPAGE type items. It would + * be simple to extend it for use with B_OVERFLOW type items. It would only + * require extracting the total length, and page number, dependent on the + * DBT type. + * + * PUBLIC: int __db_coff __P((DBC *, const DBT *, const DBT *, + * PUBLIC: int (*)(DB *, const DBT *, const DBT *), int *)); + */ +int +__db_coff(dbc, dbt, match, cmpfunc, cmpp) + DBC *dbc; + const DBT *dbt, *match; + int (*cmpfunc) __P((DB *, const DBT *, const DBT *)), *cmpp; +{ + DB *dbp; + DB_THREAD_INFO *ip; + DB_MPOOLFILE *mpf; + DB_TXN *txn; + DBT local_key, local_match; + PAGE *dbt_pagep, *match_pagep; + db_pgno_t dbt_pgno, match_pgno; + u_int32_t cmp_bytes, dbt_bufsz, dbt_len, match_bufsz; + u_int32_t match_len, max_data, page_sz; + u_int8_t *p1, *p2; + int ret; + void *dbt_buf, *match_buf; + + dbp = dbc->dbp; + ip = dbc->thread_info; + txn = dbc->txn; + mpf = dbp->mpf; + page_sz = dbp->pgsize; + *cmpp = 0; + dbt_buf = match_buf = NULL; + + DB_ASSERT(dbp->env, HPAGE_PTYPE(dbt->data) == H_OFFPAGE); + DB_ASSERT(dbp->env, HPAGE_PTYPE(match->data) == H_OFFPAGE); + + /* Extract potentially unaligned length and pgno fields from DBTs */ + memcpy(&dbt_len, HOFFPAGE_TLEN(dbt->data), sizeof(u_int32_t)); + memcpy(&dbt_pgno, HOFFPAGE_PGNO(dbt->data), sizeof(db_pgno_t)); + memcpy(&match_len, HOFFPAGE_TLEN(match->data), sizeof(u_int32_t)); + memcpy(&match_pgno, HOFFPAGE_PGNO(match->data), sizeof(db_pgno_t)); + max_data = (dbt_len < match_len ? dbt_len : match_len); + + /* + * If there is a custom comparator, fully resolve both DBTs. + * Then call the users comparator. + */ + if (cmpfunc != NULL) { + memset(&local_key, 0, sizeof(local_key)); + memset(&local_match, 0, sizeof(local_match)); + dbt_buf = match_buf = NULL; + dbt_bufsz = match_bufsz = 0; + + if ((ret = __db_goff(dbc, &local_key, dbt_len, + dbt_pgno, &dbt_buf, &dbt_bufsz)) != 0) + goto err1; + if ((ret = __db_goff(dbc, &local_match, match_len, + match_pgno, &match_buf, &match_bufsz)) != 0) + goto err1; + /* The key needs to be the first argument for sort order */ + *cmpp = cmpfunc(dbp, &local_key, &local_match); + +err1: if (dbt_buf != NULL) + __os_free(dbp->env, dbt_buf); + if (match_buf != NULL) + __os_free(dbp->env, match_buf); + return (ret); + } + + /* Match the offpage DBTs a page at a time. */ + while (dbt_pgno != PGNO_INVALID && match_pgno != PGNO_INVALID) { + if ((ret = + __memp_fget(mpf, &dbt_pgno, ip, txn, 0, &dbt_pagep)) != 0) + return (ret); + if ((ret = + __memp_fget(mpf, &match_pgno, + ip, txn, 0, &match_pagep)) != 0) { + (void)__memp_fput( + mpf, ip, dbt_pagep, DB_PRIORITY_UNCHANGED); + return (ret); + } + cmp_bytes = page_sz < max_data ? page_sz : max_data; + for (p1 = (u_int8_t *)dbt_pagep + P_OVERHEAD(dbp), + p2 = (u_int8_t *)match_pagep + P_OVERHEAD(dbp); + cmp_bytes-- > 0; ++p1, ++p2) + if (*p1 != *p2) { + *cmpp = (long)*p1 - (long)*p2; + break; + } + + dbt_pgno = NEXT_PGNO(dbt_pagep); + match_pgno = NEXT_PGNO(match_pagep); + max_data -= page_sz; + if ((ret = __memp_fput(mpf, + ip, dbt_pagep, DB_PRIORITY_UNCHANGED)) != 0) { + (void)__memp_fput(mpf, + ip, match_pagep, DB_PRIORITY_UNCHANGED); + return (ret); + } + if ((ret = __memp_fput(mpf, + ip, match_pagep, DB_PRIORITY_UNCHANGED)) != 0) + return (ret); + if (*cmpp != 0) + return (0); + } + + /* If a lexicographic mismatch was found, then the result has already + * been returned. If the DBTs matched, consider the lengths of the + * items, and return appropriately. + */ + if (dbt_len > match_len) /* DBT is longer than the match key. */ + *cmpp = 1; + else if (match_len > dbt_len) /* DBT is shorter than the match key. */ + *cmpp = -1; + else + *cmpp = 0; + + return (0); + +} diff --git a/src/libs/resiprocate/contrib/db/db/db_ovfl_vrfy.c b/src/libs/resiprocate/contrib/db/db/db_ovfl_vrfy.c new file mode 100644 index 00000000..fdd02018 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_ovfl_vrfy.c @@ -0,0 +1,409 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/db_verify.h" +#include "dbinc/mp.h" + +/* + * __db_vrfy_overflow -- + * Verify overflow page. + * + * PUBLIC: int __db_vrfy_overflow __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, + * PUBLIC: u_int32_t)); + */ +int +__db_vrfy_overflow(dbp, vdp, h, pgno, flags) + DB *dbp; + VRFY_DBINFO *vdp; + PAGE *h; + db_pgno_t pgno; + u_int32_t flags; +{ + VRFY_PAGEINFO *pip; + int isbad, ret, t_ret; + + isbad = 0; + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + + if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + + pip->refcount = OV_REF(h); + if (pip->refcount < 1) { + EPRINT((dbp->env, + "Page %lu: overflow page has zero reference count", + (u_long)pgno)); + isbad = 1; + } + + /* Just store for now. */ + pip->olen = HOFFSET(h); + +err: if ((t_ret = __db_vrfy_putpageinfo(dbp->env, vdp, pip)) != 0) + ret = t_ret; + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); +} + +/* + * __db_vrfy_ovfl_structure -- + * Walk a list of overflow pages, avoiding cycles and marking + * pages seen. + * + * PUBLIC: int __db_vrfy_ovfl_structure + * PUBLIC: __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, u_int32_t)); + */ +int +__db_vrfy_ovfl_structure(dbp, vdp, pgno, tlen, flags) + DB *dbp; + VRFY_DBINFO *vdp; + db_pgno_t pgno; + u_int32_t tlen; + u_int32_t flags; +{ + DB *pgset; + ENV *env; + VRFY_PAGEINFO *pip; + db_pgno_t next, prev; + int isbad, ret, seen_cnt, t_ret; + u_int32_t refcount; + + env = dbp->env; + pgset = vdp->pgset; + DB_ASSERT(env, pgset != NULL); + isbad = 0; + + /* This shouldn't happen, but just to be sure. */ + if (!IS_VALID_PGNO(pgno)) + return (DB_VERIFY_BAD); + + /* + * Check the first prev_pgno; it ought to be PGNO_INVALID, + * since there's no prev page. + */ + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + + /* The refcount is stored on the first overflow page. */ + refcount = pip->refcount; + + if (pip->type != P_OVERFLOW) { + EPRINT((env, + "Page %lu: overflow page of invalid type %lu", + (u_long)pgno, (u_long)pip->type)); + ret = DB_VERIFY_BAD; + goto err; /* Unsafe to continue. */ + } + + prev = pip->prev_pgno; + if (prev != PGNO_INVALID) { + EPRINT((env, + "Page %lu: first page in overflow chain has a prev_pgno %lu", + (u_long)pgno, (u_long)prev)); + isbad = 1; + } + + for (;;) { + /* + * We may have seen this page elsewhere, if the overflow entry + * has been promoted to an internal page; we just want to + * make sure that each overflow page is seen exactly as many + * times as its refcount dictates. + * + * Note that this code also serves to keep us from looping + * infinitely if there's a cycle in an overflow chain. + */ + if ((ret = __db_vrfy_pgset_get(pgset, + vdp->thread_info, pgno, &seen_cnt)) != 0) + goto err; + if ((u_int32_t)seen_cnt > refcount) { + EPRINT((env, + "Page %lu: encountered too many times in overflow traversal", + (u_long)pgno)); + ret = DB_VERIFY_BAD; + goto err; + } + if ((ret = + __db_vrfy_pgset_inc(pgset, vdp->thread_info, pgno)) != 0) + goto err; + + /* + * Each overflow page can be referenced multiple times, + * because it's possible for overflow Btree keys to get + * promoted to internal pages. We want to make sure that + * each page is referenced from a Btree leaf (or Hash data + * page, which we consider a "leaf" here) exactly once; if + * the parent was a leaf, set a flag to indicate that we've + * seen this page in a leaf context. + * + * If the parent is not a leaf--in which case it's a Btree + * internal page--we don't need to bother doing any further + * verification, as we'll do it when we hit the leaf (or + * complain that we never saw the leaf). Only the first + * page in an overflow chain should ever have a refcount + * greater than 1, and the combination of the LEAFSEEN check + * and the fact that we bail after the first page for + * non-leaves should ensure this. + * + * Note that each "child" of a page, such as an overflow page, + * is stored and verified in a structure check exactly once, + * so this code does not need to contend with the fact that + * overflow chains used as Btree duplicate keys may be + * referenced multiply from a single Btree leaf page. + */ + if (LF_ISSET(DB_ST_OVFL_LEAF)) { + if (F_ISSET(pip, VRFY_OVFL_LEAFSEEN)) { + EPRINT((env, + "Page %lu: overflow page linked twice from leaf or data page", + (u_long)pgno)); + ret = DB_VERIFY_BAD; + goto err; + } + F_SET(pip, VRFY_OVFL_LEAFSEEN); + } + + /* + * We want to verify each overflow chain only once, and + * although no chain should be linked more than once from a + * leaf page, we can't guarantee that it'll be linked that + * once if it's linked from an internal page and the key + * is gone. + * + * seen_cnt is the number of times we'd encountered this page + * before calling this function. + */ + if (seen_cnt == 0) { + /* + * Keep a running tab on how much of the item we've + * seen. + */ + tlen -= pip->olen; + + /* Send the application feedback about our progress. */ + if (!LF_ISSET(DB_SALVAGE)) + __db_vrfy_struct_feedback(dbp, vdp); + } else + goto done; + + next = pip->next_pgno; + + /* Are we there yet? */ + if (next == PGNO_INVALID) + break; + + /* + * We've already checked this when we saved it, but just + * to be sure... + */ + if (!IS_VALID_PGNO(next)) { + EPRINT((env, + "Page %lu: bad next_pgno %lu on overflow page", + (u_long)pgno, (u_long)next)); + ret = DB_VERIFY_BAD; + goto err; + } + + if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 || + (ret = __db_vrfy_getpageinfo(vdp, next, &pip)) != 0) + return (ret); + if (pip->prev_pgno != pgno) { + EPRINT((env, + "Page %lu: bad prev_pgno %lu on overflow page (should be %lu)", + (u_long)next, (u_long)pip->prev_pgno, + (u_long)pgno)); + isbad = 1; + /* + * It's safe to continue because we have separate + * cycle detection. + */ + } + + pgno = next; + } + + if (tlen > 0) { + isbad = 1; + EPRINT((env, + "Page %lu: overflow item incomplete", (u_long)pgno)); + } + +done: +err: if ((t_ret = + __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); +} + +/* + * __db_safe_goff -- + * Get an overflow item, very carefully, from an untrusted database, + * in the context of the salvager. + * + * PUBLIC: int __db_safe_goff __P((DB *, VRFY_DBINFO *, + * PUBLIC: db_pgno_t, DBT *, void *, u_int32_t *, u_int32_t)); + */ +int +__db_safe_goff(dbp, vdp, pgno, dbt, buf, bufsz, flags) + DB *dbp; + VRFY_DBINFO *vdp; + db_pgno_t pgno; + DBT *dbt; + void *buf; + u_int32_t *bufsz; + u_int32_t flags; +{ + DB_MPOOLFILE *mpf; + PAGE *h; + int ret, t_ret; + u_int32_t bytesgot, bytes; + u_int8_t *src, *dest; + + mpf = dbp->mpf; + h = NULL; + ret = t_ret = 0; + bytesgot = bytes = 0; + + DB_ASSERT(dbp->env, bufsz != NULL); + + /* + * Back up to the start of the overflow chain (if necessary) via the + * prev pointer of the overflow page. This guarantees we transverse the + * longest possible chains of overflow pages and won't be called again + * with a pgno earlier in the chain, stepping on ourselves. + */ + for (;;) { + if ((ret = __memp_fget( + mpf, &pgno, vdp->thread_info, NULL, 0, &h)) != 0) + return (ret); + + if (PREV_PGNO(h) == PGNO_INVALID || + !IS_VALID_PGNO(PREV_PGNO(h))) + break; + + pgno = PREV_PGNO(h); + + if ((ret = __memp_fput(mpf, + vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0) + return (ret); + } + if ((ret = __memp_fput( + mpf, vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0) + return (ret); + + h = NULL; + + while ((pgno != PGNO_INVALID) && (IS_VALID_PGNO(pgno))) { + /* + * Mark that we're looking at this page; if we've seen it + * already, quit. + */ + if ((ret = __db_salvage_markdone(vdp, pgno)) != 0) + break; + + if ((ret = __memp_fget(mpf, &pgno, + vdp->thread_info, NULL, 0, &h)) != 0) + break; + + /* + * Make sure it's really an overflow page, unless we're + * being aggressive, in which case we pretend it is. + */ + if (!LF_ISSET(DB_AGGRESSIVE) && TYPE(h) != P_OVERFLOW) { + ret = DB_VERIFY_BAD; + break; + } + + src = (u_int8_t *)h + P_OVERHEAD(dbp); + bytes = OV_LEN(h); + + if (bytes + P_OVERHEAD(dbp) > dbp->pgsize) + bytes = dbp->pgsize - P_OVERHEAD(dbp); + + /* + * Realloc if buf is too small + */ + if (bytesgot + bytes > *bufsz) { + if ((ret = + __os_realloc(dbp->env, bytesgot + bytes, buf)) != 0) + break; + *bufsz = bytesgot + bytes; + } + + dest = *(u_int8_t **)buf + bytesgot; + bytesgot += bytes; + + memcpy(dest, src, bytes); + + pgno = NEXT_PGNO(h); + + if ((ret = __memp_fput(mpf, + vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0) + break; + h = NULL; + } + + /* + * If we're being aggressive, salvage a partial datum if there + * was an error somewhere along the way. + */ + if (ret == 0 || LF_ISSET(DB_AGGRESSIVE)) { + dbt->size = bytesgot; + dbt->data = *(void **)buf; + } + + /* If we broke out on error, don't leave pages pinned. */ + if (h != NULL && (t_ret = __memp_fput(mpf, + vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_pr.c b/src/libs/resiprocate/contrib/db/db/db_pr.c new file mode 100644 index 00000000..69fb7c70 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_pr.c @@ -0,0 +1,1659 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/hash.h" +#include "dbinc/mp.h" +#include "dbinc/partition.h" +#include "dbinc/qam.h" +#include "dbinc/db_verify.h" + +/* + * __db_loadme -- + * A nice place to put a breakpoint. + * + * PUBLIC: void __db_loadme __P((void)); + */ +void +__db_loadme() +{ + pid_t pid; + + __os_id(NULL, &pid, NULL); +} + +#ifdef HAVE_STATISTICS +static int __db_bmeta __P((DB *, BTMETA *, u_int32_t)); +static int __db_hmeta __P((DB *, HMETA *, u_int32_t)); +static void __db_meta __P((DB *, DBMETA *, FN const *, u_int32_t)); +static const char *__db_pagetype_to_string __P((u_int32_t)); +static void __db_prdb __P((DB *, u_int32_t)); +static void __db_proff __P((ENV *, DB_MSGBUF *, void *)); +static int __db_prtree __P((DB *, DB_TXN *, u_int32_t)); +static int __db_qmeta __P((DB *, QMETA *, u_int32_t)); + +/* + * __db_dumptree -- + * Dump the tree to a file. + * + * PUBLIC: int __db_dumptree __P((DB *, DB_TXN *, char *, char *)); + */ +int +__db_dumptree(dbp, txn, op, name) + DB *dbp; + DB_TXN *txn; + char *op, *name; +{ + ENV *env; + FILE *fp, *orig_fp; + u_int32_t flags; + int ret; + + env = dbp->env; + + for (flags = 0; *op != '\0'; ++op) + switch (*op) { + case 'a': + LF_SET(DB_PR_PAGE); + break; + case 'h': + break; + case 'r': + LF_SET(DB_PR_RECOVERYTEST); + break; + default: + return (EINVAL); + } + + if (name != NULL) { + if ((fp = fopen(name, "w")) == NULL) + return (__os_get_errno()); + + orig_fp = dbp->dbenv->db_msgfile; + dbp->dbenv->db_msgfile = fp; + } else + fp = orig_fp = NULL; + + __db_prdb(dbp, flags); + + __db_msg(env, "%s", DB_GLOBAL(db_line)); + + ret = __db_prtree(dbp, txn, flags); + + if (fp != NULL) { + (void)fclose(fp); + env->dbenv->db_msgfile = orig_fp; + } + + return (ret); +} + +static const FN __db_flags_fn[] = { + { DB_AM_CHKSUM, "checksumming" }, + { DB_AM_COMPENSATE, "created by compensating transaction" }, + { DB_AM_CREATED, "database created" }, + { DB_AM_CREATED_MSTR, "encompassing file created" }, + { DB_AM_DBM_ERROR, "dbm/ndbm error" }, + { DB_AM_DELIMITER, "variable length" }, + { DB_AM_DISCARD, "discard cached pages" }, + { DB_AM_DUP, "duplicates" }, + { DB_AM_DUPSORT, "sorted duplicates" }, + { DB_AM_ENCRYPT, "encrypted" }, + { DB_AM_FIXEDLEN, "fixed-length records" }, + { DB_AM_INMEM, "in-memory" }, + { DB_AM_IN_RENAME, "file is being renamed" }, + { DB_AM_NOT_DURABLE, "changes not logged" }, + { DB_AM_OPEN_CALLED, "open called" }, + { DB_AM_PAD, "pad value" }, + { DB_AM_PGDEF, "default page size" }, + { DB_AM_RDONLY, "read-only" }, + { DB_AM_READ_UNCOMMITTED, "read-uncommitted" }, + { DB_AM_RECNUM, "Btree record numbers" }, + { DB_AM_RECOVER, "opened for recovery" }, + { DB_AM_RENUMBER, "renumber" }, + { DB_AM_REVSPLITOFF, "no reverse splits" }, + { DB_AM_SECONDARY, "secondary" }, + { DB_AM_SNAPSHOT, "load on open" }, + { DB_AM_SUBDB, "subdatabases" }, + { DB_AM_SWAP, "needswap" }, + { DB_AM_TXN, "transactional" }, + { DB_AM_VERIFYING, "verifier" }, + { 0, NULL } +}; + +/* + * __db_get_flags_fn -- + * Return the __db_flags_fn array. + * + * PUBLIC: const FN * __db_get_flags_fn __P((void)); + */ +const FN * +__db_get_flags_fn() +{ + return (__db_flags_fn); +} + +/* + * __db_prdb -- + * Print out the DB structure information. + */ +static void +__db_prdb(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + BTREE *bt; + DB_MSGBUF mb; + ENV *env; + HASH *h; + QUEUE *q; + + env = dbp->env; + + DB_MSGBUF_INIT(&mb); + __db_msg(env, "In-memory DB structure:"); + __db_msgadd(env, &mb, "%s: %#lx", + __db_dbtype_to_string(dbp->type), (u_long)dbp->flags); + __db_prflags(env, &mb, dbp->flags, __db_flags_fn, " (", ")"); + DB_MSGBUF_FLUSH(env, &mb); + + switch (dbp->type) { + case DB_BTREE: + case DB_RECNO: + bt = dbp->bt_internal; + __db_msg(env, "bt_meta: %lu bt_root: %lu", + (u_long)bt->bt_meta, (u_long)bt->bt_root); + __db_msg(env, "bt_minkey: %lu", (u_long)bt->bt_minkey); + if (!LF_ISSET(DB_PR_RECOVERYTEST)) + __db_msg(env, "bt_compare: %#lx bt_prefix: %#lx", + P_TO_ULONG(bt->bt_compare), + P_TO_ULONG(bt->bt_prefix)); +#ifdef HAVE_COMPRESSION + if (!LF_ISSET(DB_PR_RECOVERYTEST)) + __db_msg(env, "bt_compress: %#lx bt_decompress: %#lx", + P_TO_ULONG(bt->bt_compress), + P_TO_ULONG(bt->bt_decompress)); +#endif + __db_msg(env, "bt_lpgno: %lu", (u_long)bt->bt_lpgno); + if (dbp->type == DB_RECNO) { + __db_msg(env, + "re_pad: %#lx re_delim: %#lx re_len: %lu re_source: %s", + (u_long)bt->re_pad, (u_long)bt->re_delim, + (u_long)bt->re_len, + bt->re_source == NULL ? "" : bt->re_source); + __db_msg(env, + "re_modified: %d re_eof: %d re_last: %lu", + bt->re_modified, bt->re_eof, (u_long)bt->re_last); + } + break; + case DB_HASH: + h = dbp->h_internal; + __db_msg(env, "meta_pgno: %lu", (u_long)h->meta_pgno); + __db_msg(env, "h_ffactor: %lu", (u_long)h->h_ffactor); + __db_msg(env, "h_nelem: %lu", (u_long)h->h_nelem); + if (!LF_ISSET(DB_PR_RECOVERYTEST)) + __db_msg(env, "h_hash: %#lx", P_TO_ULONG(h->h_hash)); + break; + case DB_QUEUE: + q = dbp->q_internal; + __db_msg(env, "q_meta: %lu", (u_long)q->q_meta); + __db_msg(env, "q_root: %lu", (u_long)q->q_root); + __db_msg(env, "re_pad: %#lx re_len: %lu", + (u_long)q->re_pad, (u_long)q->re_len); + __db_msg(env, "rec_page: %lu", (u_long)q->rec_page); + __db_msg(env, "page_ext: %lu", (u_long)q->page_ext); + break; + case DB_UNKNOWN: + default: + break; + } +} + +/* + * __db_prtree -- + * Print out the entire tree. + */ +static int +__db_prtree(dbp, txn, flags) + DB *dbp; + DB_TXN *txn; + u_int32_t flags; +{ + DB_MPOOLFILE *mpf; + PAGE *h; + db_pgno_t i, last; + int ret; + + mpf = dbp->mpf; + + if (dbp->type == DB_QUEUE) + return (__db_prqueue(dbp, flags)); + + /* + * Find out the page number of the last page in the database, then + * dump each page. + */ + if ((ret = __memp_get_last_pgno(mpf, &last)) != 0) + return (ret); + for (i = 0; i <= last; ++i) { + if ((ret = __memp_fget(mpf, &i, NULL, txn, 0, &h)) != 0) + return (ret); + (void)__db_prpage(dbp, h, flags); + if ((ret = __memp_fput(mpf, NULL, h, dbp->priority)) != 0) + return (ret); + } + + return (0); +} + +/* + * __db_meta -- + * Print out common metadata information. + */ +static void +__db_meta(dbp, dbmeta, fn, flags) + DB *dbp; + DBMETA *dbmeta; + FN const *fn; + u_int32_t flags; +{ + DB_MPOOLFILE *mpf; + DB_MSGBUF mb; + ENV *env; + PAGE *h; + db_pgno_t pgno; + u_int8_t *p; + int cnt, ret; + const char *sep; + + env = dbp->env; + mpf = dbp->mpf; + DB_MSGBUF_INIT(&mb); + + __db_msg(env, "\tmagic: %#lx", (u_long)dbmeta->magic); + __db_msg(env, "\tversion: %lu", (u_long)dbmeta->version); + __db_msg(env, "\tpagesize: %lu", (u_long)dbmeta->pagesize); + __db_msg(env, "\ttype: %lu", (u_long)dbmeta->type); + __db_msg(env, "\tmetaflags %#lx", (u_long)dbmeta->metaflags); + __db_msg(env, "\tkeys: %lu\trecords: %lu", + (u_long)dbmeta->key_count, (u_long)dbmeta->record_count); + if (dbmeta->nparts) + __db_msg(env, "\tnparts: %lu", (u_long)dbmeta->nparts); + + /* + * If we're doing recovery testing, don't display the free list, + * it may have changed and that makes the dump diff not work. + */ + if (!LF_ISSET(DB_PR_RECOVERYTEST)) { + __db_msgadd( + env, &mb, "\tfree list: %lu", (u_long)dbmeta->free); + for (pgno = dbmeta->free, + cnt = 0, sep = ", "; pgno != PGNO_INVALID;) { + if ((ret = __memp_fget(mpf, + &pgno, NULL, NULL, 0, &h)) != 0) { + DB_MSGBUF_FLUSH(env, &mb); + __db_msg(env, + "Unable to retrieve free-list page: %lu: %s", + (u_long)pgno, db_strerror(ret)); + break; + } + pgno = h->next_pgno; + (void)__memp_fput(mpf, NULL, h, dbp->priority); + __db_msgadd(env, &mb, "%s%lu", sep, (u_long)pgno); + if (++cnt % 10 == 0) { + DB_MSGBUF_FLUSH(env, &mb); + cnt = 0; + sep = "\t"; + } else + sep = ", "; + } + DB_MSGBUF_FLUSH(env, &mb); + __db_msg(env, "\tlast_pgno: %lu", (u_long)dbmeta->last_pgno); + } + + if (fn != NULL) { + DB_MSGBUF_FLUSH(env, &mb); + __db_msgadd(env, &mb, "\tflags: %#lx", (u_long)dbmeta->flags); + __db_prflags(env, &mb, dbmeta->flags, fn, " (", ")"); + } + + DB_MSGBUF_FLUSH(env, &mb); + __db_msgadd(env, &mb, "\tuid: "); + for (p = (u_int8_t *)dbmeta->uid, + cnt = 0; cnt < DB_FILE_ID_LEN; ++cnt) { + __db_msgadd(env, &mb, "%x", *p++); + if (cnt < DB_FILE_ID_LEN - 1) + __db_msgadd(env, &mb, " "); + } + DB_MSGBUF_FLUSH(env, &mb); +} + +/* + * __db_bmeta -- + * Print out the btree meta-data page. + */ +static int +__db_bmeta(dbp, h, flags) + DB *dbp; + BTMETA *h; + u_int32_t flags; +{ + static const FN fn[] = { + { BTM_DUP, "duplicates" }, + { BTM_RECNO, "recno" }, + { BTM_RECNUM, "btree:recnum" }, + { BTM_FIXEDLEN, "recno:fixed-length" }, + { BTM_RENUMBER, "recno:renumber" }, + { BTM_SUBDB, "multiple-databases" }, + { BTM_DUPSORT, "sorted duplicates" }, + { BTM_COMPRESS, "compressed" }, + { 0, NULL } + }; + ENV *env; + + env = dbp->env; + + __db_meta(dbp, (DBMETA *)h, fn, flags); + + __db_msg(env, "\tminkey: %lu", (u_long)h->minkey); + if (dbp->type == DB_RECNO) + __db_msg(env, "\tre_len: %#lx re_pad: %#lx", + (u_long)h->re_len, (u_long)h->re_pad); + __db_msg(env, "\troot: %lu", (u_long)h->root); + + return (0); +} + +/* + * __db_hmeta -- + * Print out the hash meta-data page. + */ +static int +__db_hmeta(dbp, h, flags) + DB *dbp; + HMETA *h; + u_int32_t flags; +{ + static const FN fn[] = { + { DB_HASH_DUP, "duplicates" }, + { DB_HASH_SUBDB, "multiple-databases" }, + { DB_HASH_DUPSORT, "sorted duplicates" }, + { 0, NULL } + }; + ENV *env; + DB_MSGBUF mb; + int i; + + env = dbp->env; + DB_MSGBUF_INIT(&mb); + + __db_meta(dbp, (DBMETA *)h, fn, flags); + + __db_msg(env, "\tmax_bucket: %lu", (u_long)h->max_bucket); + __db_msg(env, "\thigh_mask: %#lx", (u_long)h->high_mask); + __db_msg(env, "\tlow_mask: %#lx", (u_long)h->low_mask); + __db_msg(env, "\tffactor: %lu", (u_long)h->ffactor); + __db_msg(env, "\tnelem: %lu", (u_long)h->nelem); + __db_msg(env, "\th_charkey: %#lx", (u_long)h->h_charkey); + __db_msgadd(env, &mb, "\tspare points: "); + for (i = 0; i < NCACHED; i++) + __db_msgadd(env, &mb, "%lu ", (u_long)h->spares[i]); + DB_MSGBUF_FLUSH(env, &mb); + + return (0); +} + +/* + * __db_qmeta -- + * Print out the queue meta-data page. + */ +static int +__db_qmeta(dbp, h, flags) + DB *dbp; + QMETA *h; + u_int32_t flags; +{ + ENV *env; + + env = dbp->env; + + __db_meta(dbp, (DBMETA *)h, NULL, flags); + + __db_msg(env, "\tfirst_recno: %lu", (u_long)h->first_recno); + __db_msg(env, "\tcur_recno: %lu", (u_long)h->cur_recno); + __db_msg(env, "\tre_len: %#lx re_pad: %lu", + (u_long)h->re_len, (u_long)h->re_pad); + __db_msg(env, "\trec_page: %lu", (u_long)h->rec_page); + __db_msg(env, "\tpage_ext: %lu", (u_long)h->page_ext); + + return (0); +} + +/* + * __db_prnpage + * -- Print out a specific page. + * + * PUBLIC: int __db_prnpage __P((DB *, DB_TXN *, db_pgno_t)); + */ +int +__db_prnpage(dbp, txn, pgno) + DB *dbp; + DB_TXN *txn; + db_pgno_t pgno; +{ + DB_MPOOLFILE *mpf; + PAGE *h; + int ret, t_ret; + + mpf = dbp->mpf; + + if ((ret = __memp_fget(mpf, &pgno, NULL, txn, 0, &h)) != 0) + return (ret); + + ret = __db_prpage(dbp, h, DB_PR_PAGE); + + if ((t_ret = __memp_fput(mpf, NULL, h, dbp->priority)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __db_prpage + * -- Print out a page. + * + * PUBLIC: int __db_prpage __P((DB *, PAGE *, u_int32_t)); + */ +int +__db_prpage(dbp, h, flags) + DB *dbp; + PAGE *h; + u_int32_t flags; +{ + BINTERNAL *bi; + BKEYDATA *bk; + DB_MSGBUF mb; + ENV *env; + HOFFPAGE a_hkd; + QAMDATA *qp, *qep; + RINTERNAL *ri; + db_indx_t dlen, len, i, *inp; + db_pgno_t pgno; + db_recno_t recno; + u_int32_t pagesize, qlen; + u_int8_t *ep, *hk, *p; + int deleted, ret; + const char *s; + void *sp; + + env = dbp->env; + DB_MSGBUF_INIT(&mb); + + /* + * If we're doing recovery testing and this page is P_INVALID, + * assume it's a page that's on the free list, and don't display it. + */ + if (LF_ISSET(DB_PR_RECOVERYTEST) && TYPE(h) == P_INVALID) + return (0); + + if ((s = __db_pagetype_to_string(TYPE(h))) == NULL) { + __db_msg(env, "ILLEGAL PAGE TYPE: page: %lu type: %lu", + (u_long)h->pgno, (u_long)TYPE(h)); + return (EINVAL); + } + + /* + * !!! + * Find out the page size. We don't want to do it the "right" way, + * by reading the value from the meta-data page, that's going to be + * slow. Reach down into the mpool region. + */ + pagesize = (u_int32_t)dbp->mpf->mfp->stat.st_pagesize; + + /* Page number, page type. */ + __db_msgadd(env, &mb, "page %lu: %s:", (u_long)h->pgno, s); + + /* + * LSNs on a metadata page will be different from the original after an + * abort, in some cases. Don't display them if we're testing recovery. + */ + if (!LF_ISSET(DB_PR_RECOVERYTEST) || + (TYPE(h) != P_BTREEMETA && TYPE(h) != P_HASHMETA && + TYPE(h) != P_QAMMETA && TYPE(h) != P_QAMDATA)) + __db_msgadd(env, &mb, " LSN [%lu][%lu]:", + (u_long)LSN(h).file, (u_long)LSN(h).offset); + + /* + * Page level (only applicable for Btree/Recno, but we always display + * it, for no particular reason. + */ + __db_msgadd(env, &mb, " level %lu", (u_long)h->level); + + /* Record count. */ + if (TYPE(h) == P_IBTREE || + TYPE(h) == P_IRECNO || (TYPE(h) == P_LRECNO && + h->pgno == ((BTREE *)dbp->bt_internal)->bt_root)) + __db_msgadd(env, &mb, " records: %lu", (u_long)RE_NREC(h)); + DB_MSGBUF_FLUSH(env, &mb); + + switch (TYPE(h)) { + case P_BTREEMETA: + return (__db_bmeta(dbp, (BTMETA *)h, flags)); + case P_HASHMETA: + return (__db_hmeta(dbp, (HMETA *)h, flags)); + case P_QAMMETA: + return (__db_qmeta(dbp, (QMETA *)h, flags)); + case P_QAMDATA: /* Should be meta->start. */ + if (!LF_ISSET(DB_PR_PAGE)) + return (0); + + qlen = ((QUEUE *)dbp->q_internal)->re_len; + recno = (h->pgno - 1) * QAM_RECNO_PER_PAGE(dbp) + 1; + i = 0; + qep = (QAMDATA *)((u_int8_t *)h + pagesize - qlen); + for (qp = QAM_GET_RECORD(dbp, h, i); qp < qep; + recno++, i++, qp = QAM_GET_RECORD(dbp, h, i)) { + if (!F_ISSET(qp, QAM_SET)) + continue; + + __db_msgadd(env, &mb, "%s", + F_ISSET(qp, QAM_VALID) ? "\t" : " D"); + __db_msgadd(env, &mb, "[%03lu] %4lu ", (u_long)recno, + (u_long)((u_int8_t *)qp - (u_int8_t *)h)); + __db_prbytes(env, &mb, qp->data, qlen); + } + return (0); + default: + break; + } + + s = "\t"; + if (TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO) { + __db_msgadd(env, &mb, "%sprev: %4lu next: %4lu", + s, (u_long)PREV_PGNO(h), (u_long)NEXT_PGNO(h)); + s = " "; + } + if (TYPE(h) == P_OVERFLOW) { + __db_msgadd(env, &mb, + "%sref cnt: %4lu ", s, (u_long)OV_REF(h)); + __db_prbytes(env, + &mb, (u_int8_t *)h + P_OVERHEAD(dbp), OV_LEN(h)); + return (0); + } + __db_msgadd(env, &mb, "%sentries: %4lu", s, (u_long)NUM_ENT(h)); + __db_msgadd(env, &mb, " offset: %4lu", (u_long)HOFFSET(h)); + DB_MSGBUF_FLUSH(env, &mb); + + if (TYPE(h) == P_INVALID || !LF_ISSET(DB_PR_PAGE)) + return (0); + + ret = 0; + inp = P_INP(dbp, h); + for (i = 0; i < NUM_ENT(h); i++) { + if ((uintptr_t)(P_ENTRY(dbp, h, i) - (u_int8_t *)h) < + (uintptr_t)(P_OVERHEAD(dbp)) || + (size_t)(P_ENTRY(dbp, h, i) - (u_int8_t *)h) >= pagesize) { + __db_msg(env, + "ILLEGAL PAGE OFFSET: indx: %lu of %lu", + (u_long)i, (u_long)inp[i]); + ret = EINVAL; + continue; + } + deleted = 0; + switch (TYPE(h)) { + case P_HASH_UNSORTED: + case P_HASH: + case P_IBTREE: + case P_IRECNO: + sp = P_ENTRY(dbp, h, i); + break; + case P_LBTREE: + sp = P_ENTRY(dbp, h, i); + deleted = i % 2 == 0 && + B_DISSET(GET_BKEYDATA(dbp, h, i + O_INDX)->type); + break; + case P_LDUP: + case P_LRECNO: + sp = P_ENTRY(dbp, h, i); + deleted = B_DISSET(GET_BKEYDATA(dbp, h, i)->type); + break; + default: + goto type_err; + } + __db_msgadd(env, &mb, "%s", deleted ? " D" : "\t"); + __db_msgadd( + env, &mb, "[%03lu] %4lu ", (u_long)i, (u_long)inp[i]); + switch (TYPE(h)) { + case P_HASH_UNSORTED: + case P_HASH: + hk = sp; + switch (HPAGE_PTYPE(hk)) { + case H_OFFDUP: + memcpy(&pgno, + HOFFDUP_PGNO(hk), sizeof(db_pgno_t)); + __db_msgadd(env, &mb, + "%4lu [offpage dups]", (u_long)pgno); + DB_MSGBUF_FLUSH(env, &mb); + break; + case H_DUPLICATE: + /* + * If this is the first item on a page, then + * we cannot figure out how long it is, so + * we only print the first one in the duplicate + * set. + */ + if (i != 0) + len = LEN_HKEYDATA(dbp, h, 0, i); + else + len = 1; + + __db_msgadd(env, &mb, "Duplicates:"); + DB_MSGBUF_FLUSH(env, &mb); + for (p = HKEYDATA_DATA(hk), + ep = p + len; p < ep;) { + memcpy(&dlen, p, sizeof(db_indx_t)); + p += sizeof(db_indx_t); + __db_msgadd(env, &mb, "\t\t"); + __db_prbytes(env, &mb, p, dlen); + p += sizeof(db_indx_t) + dlen; + } + break; + case H_KEYDATA: + __db_prbytes(env, &mb, HKEYDATA_DATA(hk), + LEN_HKEYDATA(dbp, h, i == 0 ? + pagesize : 0, i)); + break; + case H_OFFPAGE: + memcpy(&a_hkd, hk, HOFFPAGE_SIZE); + __db_msgadd(env, &mb, + "overflow: total len: %4lu page: %4lu", + (u_long)a_hkd.tlen, (u_long)a_hkd.pgno); + DB_MSGBUF_FLUSH(env, &mb); + break; + default: + DB_MSGBUF_FLUSH(env, &mb); + __db_msg(env, "ILLEGAL HASH PAGE TYPE: %lu", + (u_long)HPAGE_PTYPE(hk)); + ret = EINVAL; + break; + } + break; + case P_IBTREE: + bi = sp; + + if (F_ISSET(dbp, DB_AM_RECNUM)) + __db_msgadd(env, &mb, + "count: %4lu ", (u_long)bi->nrecs); + __db_msgadd(env, &mb, + "pgno: %4lu type: %lu ", + (u_long)bi->pgno, (u_long)bi->type); + switch (B_TYPE(bi->type)) { + case B_KEYDATA: + __db_prbytes(env, &mb, bi->data, bi->len); + break; + case B_DUPLICATE: + case B_OVERFLOW: + __db_proff(env, &mb, bi->data); + break; + default: + DB_MSGBUF_FLUSH(env, &mb); + __db_msg(env, "ILLEGAL BINTERNAL TYPE: %lu", + (u_long)B_TYPE(bi->type)); + ret = EINVAL; + break; + } + break; + case P_IRECNO: + ri = sp; + __db_msgadd(env, &mb, "entries %4lu pgno %4lu", + (u_long)ri->nrecs, (u_long)ri->pgno); + DB_MSGBUF_FLUSH(env, &mb); + break; + case P_LBTREE: + case P_LDUP: + case P_LRECNO: + bk = sp; + switch (B_TYPE(bk->type)) { + case B_KEYDATA: + __db_prbytes(env, &mb, bk->data, bk->len); + break; + case B_DUPLICATE: + case B_OVERFLOW: + __db_proff(env, &mb, bk); + break; + default: + DB_MSGBUF_FLUSH(env, &mb); + __db_msg(env, + "ILLEGAL DUPLICATE/LBTREE/LRECNO TYPE: %lu", + (u_long)B_TYPE(bk->type)); + ret = EINVAL; + break; + } + break; + default: +type_err: DB_MSGBUF_FLUSH(env, &mb); + __db_msg(env, + "ILLEGAL PAGE TYPE: %lu", (u_long)TYPE(h)); + ret = EINVAL; + continue; + } + } + return (ret); +} + +/* + * __db_prbytes -- + * Print out a data element. + * + * PUBLIC: void __db_prbytes __P((ENV *, DB_MSGBUF *, u_int8_t *, u_int32_t)); + */ +void +__db_prbytes(env, mbp, bytes, len) + ENV *env; + DB_MSGBUF *mbp; + u_int8_t *bytes; + u_int32_t len; +{ + u_int8_t *p; + u_int32_t i; + int msg_truncated; + + __db_msgadd(env, mbp, "len: %3lu", (u_long)len); + if (len != 0) { + __db_msgadd(env, mbp, " data: "); + + /* + * Print the first 20 bytes of the data. If that chunk is + * all printable characters, print it as text, else print it + * in hex. We have this heuristic because we're displaying + * things like lock objects that could be either text or data. + */ + if (len > 20) { + len = 20; + msg_truncated = 1; + } else + msg_truncated = 0; + for (p = bytes, i = len; i > 0; --i, ++p) + if (!isprint((int)*p) && *p != '\t' && *p != '\n') + break; + if (i == 0) + for (p = bytes, i = len; i > 0; --i, ++p) + __db_msgadd(env, mbp, "%c", *p); + else + for (p = bytes, i = len; i > 0; --i, ++p) + __db_msgadd(env, mbp, "%#.2x", (u_int)*p); + if (msg_truncated) + __db_msgadd(env, mbp, "..."); + } + DB_MSGBUF_FLUSH(env, mbp); +} + +/* + * __db_proff -- + * Print out an off-page element. + */ +static void +__db_proff(env, mbp, vp) + ENV *env; + DB_MSGBUF *mbp; + void *vp; +{ + BOVERFLOW *bo; + + bo = vp; + switch (B_TYPE(bo->type)) { + case B_OVERFLOW: + __db_msgadd(env, mbp, "overflow: total len: %4lu page: %4lu", + (u_long)bo->tlen, (u_long)bo->pgno); + break; + case B_DUPLICATE: + __db_msgadd( + env, mbp, "duplicate: page: %4lu", (u_long)bo->pgno); + break; + default: + /* NOTREACHED */ + break; + } + DB_MSGBUF_FLUSH(env, mbp); +} + +/* + * __db_prflags -- + * Print out flags values. + * + * PUBLIC: void __db_prflags __P((ENV *, DB_MSGBUF *, + * PUBLIC: u_int32_t, const FN *, const char *, const char *)); + */ +void +__db_prflags(env, mbp, flags, fn, prefix, suffix) + ENV *env; + DB_MSGBUF *mbp; + u_int32_t flags; + FN const *fn; + const char *prefix, *suffix; +{ + DB_MSGBUF mb; + const FN *fnp; + int found, standalone; + const char *sep; + + if (fn == NULL) + return; + + /* + * If it's a standalone message, output the suffix (which will be the + * label), regardless of whether we found anything or not, and flush + * the line. + */ + if (mbp == NULL) { + standalone = 1; + mbp = &mb; + DB_MSGBUF_INIT(mbp); + } else + standalone = 0; + + sep = prefix == NULL ? "" : prefix; + for (found = 0, fnp = fn; fnp->mask != 0; ++fnp) + if (LF_ISSET(fnp->mask)) { + __db_msgadd(env, mbp, "%s%s", sep, fnp->name); + sep = ", "; + found = 1; + } + + if ((standalone || found) && suffix != NULL) + __db_msgadd(env, mbp, "%s", suffix); + if (standalone) + DB_MSGBUF_FLUSH(env, mbp); +} + +/* + * __db_lockmode_to_string -- + * Return the name of the lock mode. + * + * PUBLIC: const char * __db_lockmode_to_string __P((db_lockmode_t)); + */ +const char * +__db_lockmode_to_string(mode) + db_lockmode_t mode; +{ + switch (mode) { + case DB_LOCK_NG: + return ("Not granted"); + case DB_LOCK_READ: + return ("Shared/read"); + case DB_LOCK_WRITE: + return ("Exclusive/write"); + case DB_LOCK_WAIT: + return ("Wait for event"); + case DB_LOCK_IWRITE: + return ("Intent exclusive/write"); + case DB_LOCK_IREAD: + return ("Intent shared/read"); + case DB_LOCK_IWR: + return ("Intent to read/write"); + case DB_LOCK_READ_UNCOMMITTED: + return ("Read uncommitted"); + case DB_LOCK_WWRITE: + return ("Was written"); + default: + break; + } + return ("UNKNOWN LOCK MODE"); +} + +/* + * __db_pagetype_to_string -- + * Return the name of the specified page type. + */ +static const char * +__db_pagetype_to_string(type) + u_int32_t type; +{ + char *s; + + s = NULL; + switch (type) { + case P_BTREEMETA: + s = "btree metadata"; + break; + case P_LDUP: + s = "duplicate"; + break; + case P_HASH_UNSORTED: + s = "hash unsorted"; + break; + case P_HASH: + s = "hash"; + break; + case P_HASHMETA: + s = "hash metadata"; + break; + case P_IBTREE: + s = "btree internal"; + break; + case P_INVALID: + s = "invalid"; + break; + case P_IRECNO: + s = "recno internal"; + break; + case P_LBTREE: + s = "btree leaf"; + break; + case P_LRECNO: + s = "recno leaf"; + break; + case P_OVERFLOW: + s = "overflow"; + break; + case P_QAMMETA: + s = "queue metadata"; + break; + case P_QAMDATA: + s = "queue"; + break; + default: + /* Just return a NULL. */ + break; + } + return (s); +} + +#else /* !HAVE_STATISTICS */ + +/* + * __db_dumptree -- + * Dump the tree to a file. + * + * PUBLIC: int __db_dumptree __P((DB *, DB_TXN *, char *, char *)); + */ +int +__db_dumptree(dbp, txn, op, name) + DB *dbp; + DB_TXN *txn; + char *op, *name; +{ + COMPQUIET(txn, NULL); + COMPQUIET(op, NULL); + COMPQUIET(name, NULL); + + return (__db_stat_not_built(dbp->env)); +} + +/* + * __db_get_flags_fn -- + * Return the __db_flags_fn array. + * + * PUBLIC: const FN * __db_get_flags_fn __P((void)); + */ +const FN * +__db_get_flags_fn() +{ + /* + * !!! + * The Tcl API uses this interface, stub it off. + */ + return (NULL); +} +#endif + +/* + * __db_dump_pp -- + * DB->dump pre/post processing. + * + * PUBLIC: int __db_dump_pp __P((DB *, const char *, + * PUBLIC: int (*)(void *, const void *), void *, int, int)); + */ +int +__db_dump_pp(dbp, subname, callback, handle, pflag, keyflag) + DB *dbp; + const char *subname; + int (*callback) __P((void *, const void *)); + void *handle; + int pflag, keyflag; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = dbp->env; + + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->dump"); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 1)) != 0) { + handle_check = 0; + goto err; + } + + ret = __db_dump(dbp, subname, callback, handle, pflag, keyflag); + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + +err: ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_dump -- + * DB->dump. + * + * PUBLIC: int __db_dump __P((DB *, const char *, + * PUBLIC: int (*)(void *, const void *), void *, int, int)); + */ +int +__db_dump(dbp, subname, callback, handle, pflag, keyflag) + DB *dbp; + const char *subname; + int (*callback) __P((void *, const void *)); + void *handle; + int pflag, keyflag; +{ + DBC *dbcp; + DBT key, data; + DBT keyret, dataret; + ENV *env; + db_recno_t recno; + int is_recno, ret, t_ret; + void *pointer; + + env = dbp->env; + + if ((ret = __db_prheader( + dbp, subname, pflag, keyflag, handle, callback, NULL, 0)) != 0) + return (ret); + + /* + * Get a cursor and step through the database, printing out each + * key/data pair. + */ + if ((ret = __db_cursor(dbp, NULL, NULL, &dbcp, 0)) != 0) + return (ret); + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + if ((ret = __os_malloc(env, 1024 * 1024, &data.data)) != 0) + goto err; + data.ulen = 1024 * 1024; + data.flags = DB_DBT_USERMEM; + is_recno = (dbp->type == DB_RECNO || dbp->type == DB_QUEUE); + keyflag = is_recno ? keyflag : 1; + if (is_recno) { + keyret.data = &recno; + keyret.size = sizeof(recno); + } + +retry: while ((ret = + __dbc_get(dbcp, &key, &data, DB_NEXT | DB_MULTIPLE_KEY)) == 0) { + DB_MULTIPLE_INIT(pointer, &data); + for (;;) { + if (is_recno) + DB_MULTIPLE_RECNO_NEXT(pointer, &data, + recno, dataret.data, dataret.size); + else + DB_MULTIPLE_KEY_NEXT(pointer, + &data, keyret.data, + keyret.size, dataret.data, dataret.size); + + if (dataret.data == NULL) + break; + + if ((keyflag && + (ret = __db_prdbt(&keyret, pflag, " ", + handle, callback, is_recno)) != 0) || + (ret = __db_prdbt(&dataret, pflag, " ", + handle, callback, 0)) != 0) + goto err; + } + } + if (ret == DB_BUFFER_SMALL) { + data.size = (u_int32_t)DB_ALIGN(data.size, 1024); + if ((ret = __os_realloc(env, data.size, &data.data)) != 0) + goto err; + data.ulen = data.size; + goto retry; + } + if (ret == DB_NOTFOUND) + ret = 0; + + if ((t_ret = __db_prfooter(handle, callback)) != 0 && ret == 0) + ret = t_ret; + +err: if ((t_ret = __dbc_close(dbcp)) != 0 && ret == 0) + ret = t_ret; + if (data.data != NULL) + __os_free(env, data.data); + + return (ret); +} + +/* + * __db_prdbt -- + * Print out a DBT data element. + * + * PUBLIC: int __db_prdbt __P((DBT *, int, const char *, void *, + * PUBLIC: int (*)(void *, const void *), int)); + */ +int +__db_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno) + DBT *dbtp; + int checkprint; + const char *prefix; + void *handle; + int (*callback) __P((void *, const void *)); + int is_recno; +{ + static const u_char hex[] = "0123456789abcdef"; + db_recno_t recno; + size_t len; + int ret; +#define DBTBUFLEN 100 + u_int8_t *p, *hp; + char buf[DBTBUFLEN], hbuf[DBTBUFLEN]; + + /* + * !!! + * This routine is the routine that dumps out items in the format + * used by db_dump(1) and db_load(1). This means that the format + * cannot change. + */ + if (prefix != NULL && (ret = callback(handle, prefix)) != 0) + return (ret); + if (is_recno) { + /* + * We're printing a record number, and this has to be done + * in a platform-independent way. So we use the numeral in + * straight ASCII. + */ + (void)__ua_memcpy(&recno, dbtp->data, sizeof(recno)); + snprintf(buf, DBTBUFLEN, "%lu", (u_long)recno); + + /* If we're printing data as hex, print keys as hex too. */ + if (!checkprint) { + for (len = strlen(buf), p = (u_int8_t *)buf, + hp = (u_int8_t *)hbuf; len-- > 0; ++p) { + *hp++ = hex[(u_int8_t)(*p & 0xf0) >> 4]; + *hp++ = hex[*p & 0x0f]; + } + *hp = '\0'; + ret = callback(handle, hbuf); + } else + ret = callback(handle, buf); + + if (ret != 0) + return (ret); + } else if (checkprint) { + for (len = dbtp->size, p = dbtp->data; len--; ++p) + if (isprint((int)*p)) { + if (*p == '\\' && + (ret = callback(handle, "\\")) != 0) + return (ret); + snprintf(buf, DBTBUFLEN, "%c", *p); + if ((ret = callback(handle, buf)) != 0) + return (ret); + } else { + snprintf(buf, DBTBUFLEN, "\\%c%c", + hex[(u_int8_t)(*p & 0xf0) >> 4], + hex[*p & 0x0f]); + if ((ret = callback(handle, buf)) != 0) + return (ret); + } + } else + for (len = dbtp->size, p = dbtp->data; len--; ++p) { + snprintf(buf, DBTBUFLEN, "%c%c", + hex[(u_int8_t)(*p & 0xf0) >> 4], + hex[*p & 0x0f]); + if ((ret = callback(handle, buf)) != 0) + return (ret); + } + + return (callback(handle, "\n")); +} + +/* + * __db_prheader -- + * Write out header information in the format expected by db_load. + * + * PUBLIC: int __db_prheader __P((DB *, const char *, int, int, void *, + * PUBLIC: int (*)(void *, const void *), VRFY_DBINFO *, db_pgno_t)); + */ +int +__db_prheader(dbp, subname, pflag, keyflag, handle, callback, vdp, meta_pgno) + DB *dbp; + const char *subname; + int pflag, keyflag; + void *handle; + int (*callback) __P((void *, const void *)); + VRFY_DBINFO *vdp; + db_pgno_t meta_pgno; +{ + DBT dbt; + DBTYPE dbtype; + ENV *env; + VRFY_PAGEINFO *pip; + u_int32_t flags, tmp_u_int32; + size_t buflen; + char *buf; + int using_vdp, ret, t_ret, tmp_int; + + ret = 0; + buf = NULL; + COMPQUIET(buflen, 0); + + /* + * If dbp is NULL, then pip is guaranteed to be non-NULL; we only ever + * call __db_prheader with a NULL dbp from one case inside __db_prdbt, + * and this is a special subdatabase for "lost" items. In this case + * we have a vdp (from which we'll get a pip). In all other cases, we + * will have a non-NULL dbp (and vdp may or may not be NULL depending + * on whether we're salvaging). + */ + if (dbp == NULL) + env = NULL; + else + env = dbp->env; + DB_ASSERT(env, dbp != NULL || vdp != NULL); + + /* + * If we've been passed a verifier statistics object, use that; we're + * being called in a context where dbp->stat is unsafe. + * + * Also, the verifier may set the pflag on a per-salvage basis. If so, + * respect that. + */ + if (vdp != NULL) { + if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &pip)) != 0) + return (ret); + + if (F_ISSET(vdp, SALVAGE_PRINTABLE)) + pflag = 1; + using_vdp = 1; + } else { + pip = NULL; + using_vdp = 0; + } + + /* + * If dbp is NULL, make it a btree. Otherwise, set dbtype to whatever + * appropriate type for the specified meta page, or the type of the dbp. + */ + if (dbp == NULL) + dbtype = DB_BTREE; + else if (using_vdp) + switch (pip->type) { + case P_BTREEMETA: + if (F_ISSET(pip, VRFY_IS_RECNO)) + dbtype = DB_RECNO; + else + dbtype = DB_BTREE; + break; + case P_HASHMETA: + dbtype = DB_HASH; + break; + case P_QAMMETA: + dbtype = DB_QUEUE; + break; + default: + /* + * If the meta page is of a bogus type, it's because + * we have a badly corrupt database. (We must be in + * the verifier for pip to be non-NULL.) Pretend we're + * a Btree and salvage what we can. + */ + DB_ASSERT(env, F_ISSET(dbp, DB_AM_VERIFYING)); + dbtype = DB_BTREE; + break; + } + else + dbtype = dbp->type; + + if ((ret = callback(handle, "VERSION=3\n")) != 0) + goto err; + if (pflag) { + if ((ret = callback(handle, "format=print\n")) != 0) + goto err; + } else if ((ret = callback(handle, "format=bytevalue\n")) != 0) + goto err; + + /* + * 64 bytes is long enough, as a minimum bound, for any of the + * fields besides subname. Subname uses __db_prdbt and therefore + * does not need buffer space here. + */ + buflen = 64; + if ((ret = __os_malloc(env, buflen, &buf)) != 0) + goto err; + if (subname != NULL) { + snprintf(buf, buflen, "database="); + if ((ret = callback(handle, buf)) != 0) + goto err; + DB_INIT_DBT(dbt, subname, strlen(subname)); + if ((ret = __db_prdbt(&dbt, 1, NULL, handle, callback, 0)) != 0) + goto err; + } + switch (dbtype) { + case DB_BTREE: + if ((ret = callback(handle, "type=btree\n")) != 0) + goto err; + if (using_vdp) + tmp_int = F_ISSET(pip, VRFY_HAS_RECNUMS) ? 1 : 0; + else { + if ((ret = __db_get_flags(dbp, &flags)) != 0) { + __db_err(env, ret, "DB->get_flags"); + goto err; + } + tmp_int = F_ISSET(dbp, DB_AM_RECNUM) ? 1 : 0; + } + if (tmp_int && (ret = callback(handle, "recnum=1\n")) != 0) + goto err; + + if (using_vdp) + tmp_u_int32 = pip->bt_minkey; + else + if ((ret = + __bam_get_bt_minkey(dbp, &tmp_u_int32)) != 0) { + __db_err(env, ret, "DB->get_bt_minkey"); + goto err; + } + if (tmp_u_int32 != 0 && tmp_u_int32 != DEFMINKEYPAGE) { + snprintf(buf, buflen, + "bt_minkey=%lu\n", (u_long)tmp_u_int32); + if ((ret = callback(handle, buf)) != 0) + goto err; + } + break; + case DB_HASH: +#ifdef HAVE_HASH + if ((ret = callback(handle, "type=hash\n")) != 0) + goto err; + if (using_vdp) + tmp_u_int32 = pip->h_ffactor; + else + if ((ret = + __ham_get_h_ffactor(dbp, &tmp_u_int32)) != 0) { + __db_err(env, ret, "DB->get_h_ffactor"); + goto err; + } + if (tmp_u_int32 != 0) { + snprintf(buf, buflen, + "h_ffactor=%lu\n", (u_long)tmp_u_int32); + if ((ret = callback(handle, buf)) != 0) + goto err; + } + + if (using_vdp) + tmp_u_int32 = pip->h_nelem; + else + if ((ret = __ham_get_h_nelem(dbp, &tmp_u_int32)) != 0) { + __db_err(env, ret, "DB->get_h_nelem"); + goto err; + } + /* + * Hash databases have an h_nelem field of 0 or 1, neither + * of those values is interesting. + */ + if (tmp_u_int32 > 1) { + snprintf(buf, buflen, + "h_nelem=%lu\n", (u_long)tmp_u_int32); + if ((ret = callback(handle, buf)) != 0) + goto err; + } + break; +#else + ret = __db_no_hash_am(env); + goto err; +#endif + case DB_QUEUE: +#ifdef HAVE_QUEUE + if ((ret = callback(handle, "type=queue\n")) != 0) + goto err; + if (using_vdp) + tmp_u_int32 = vdp->re_len; + else + if ((ret = __ram_get_re_len(dbp, &tmp_u_int32)) != 0) { + __db_err(env, ret, "DB->get_re_len"); + goto err; + } + snprintf(buf, buflen, "re_len=%lu\n", (u_long)tmp_u_int32); + if ((ret = callback(handle, buf)) != 0) + goto err; + + if (using_vdp) + tmp_int = (int)vdp->re_pad; + else + if ((ret = __ram_get_re_pad(dbp, &tmp_int)) != 0) { + __db_err(env, ret, "DB->get_re_pad"); + goto err; + } + if (tmp_int != 0 && tmp_int != ' ') { + snprintf(buf, buflen, "re_pad=%#x\n", tmp_int); + if ((ret = callback(handle, buf)) != 0) + goto err; + } + + if (using_vdp) + tmp_u_int32 = vdp->page_ext; + else + if ((ret = + __qam_get_extentsize(dbp, &tmp_u_int32)) != 0) { + __db_err(env, ret, "DB->get_q_extentsize"); + goto err; + } + if (tmp_u_int32 != 0) { + snprintf(buf, buflen, + "extentsize=%lu\n", (u_long)tmp_u_int32); + if ((ret = callback(handle, buf)) != 0) + goto err; + } + break; +#else + ret = __db_no_queue_am(env); + goto err; +#endif + case DB_RECNO: + if ((ret = callback(handle, "type=recno\n")) != 0) + goto err; + if (using_vdp) + tmp_int = F_ISSET(pip, VRFY_IS_RRECNO) ? 1 : 0; + else + tmp_int = F_ISSET(dbp, DB_AM_RENUMBER) ? 1 : 0; + if (tmp_int != 0 && + (ret = callback(handle, "renumber=1\n")) != 0) + goto err; + + if (using_vdp) + tmp_int = F_ISSET(pip, VRFY_IS_FIXEDLEN) ? 1 : 0; + else + tmp_int = F_ISSET(dbp, DB_AM_FIXEDLEN) ? 1 : 0; + if (tmp_int) { + if (using_vdp) + tmp_u_int32 = pip->re_len; + else + if ((ret = + __ram_get_re_len(dbp, &tmp_u_int32)) != 0) { + __db_err(env, ret, "DB->get_re_len"); + goto err; + } + snprintf(buf, buflen, + "re_len=%lu\n", (u_long)tmp_u_int32); + if ((ret = callback(handle, buf)) != 0) + goto err; + + if (using_vdp) + tmp_int = (int)pip->re_pad; + else + if ((ret = + __ram_get_re_pad(dbp, &tmp_int)) != 0) { + __db_err(env, ret, "DB->get_re_pad"); + goto err; + } + if (tmp_int != 0 && tmp_int != ' ') { + snprintf(buf, + buflen, "re_pad=%#x\n", (u_int)tmp_int); + if ((ret = callback(handle, buf)) != 0) + goto err; + } + } + break; + case DB_UNKNOWN: /* Impossible. */ + ret = __db_unknown_path(env, "__db_prheader"); + goto err; + } + + if (using_vdp) { + if (F_ISSET(pip, VRFY_HAS_CHKSUM)) + if ((ret = callback(handle, "chksum=1\n")) != 0) + goto err; + if (F_ISSET(pip, VRFY_HAS_DUPS)) + if ((ret = callback(handle, "duplicates=1\n")) != 0) + goto err; + if (F_ISSET(pip, VRFY_HAS_DUPSORT)) + if ((ret = callback(handle, "dupsort=1\n")) != 0) + goto err; +#ifdef HAVE_COMPRESSION + if (F_ISSET(pip, VRFY_HAS_COMPRESS)) + if ((ret = callback(handle, "compressed=1\n")) != 0) + goto err; +#endif + /* + * !!! + * We don't know if the page size was the default if we're + * salvaging. It doesn't seem that interesting to have, so + * we ignore it for now. + */ + } else { + if (F_ISSET(dbp, DB_AM_CHKSUM)) + if ((ret = callback(handle, "chksum=1\n")) != 0) + goto err; + if (F_ISSET(dbp, DB_AM_DUP)) + if ((ret = callback(handle, "duplicates=1\n")) != 0) + goto err; + if (F_ISSET(dbp, DB_AM_DUPSORT)) + if ((ret = callback(handle, "dupsort=1\n")) != 0) + goto err; +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp)) + if ((ret = callback(handle, "compressed=1\n")) != 0) + goto err; +#endif + if (!F_ISSET(dbp, DB_AM_PGDEF)) { + snprintf(buf, buflen, + "db_pagesize=%lu\n", (u_long)dbp->pgsize); + if ((ret = callback(handle, buf)) != 0) + goto err; + } + } + +#ifdef HAVE_PARTITION + if (DB_IS_PARTITIONED(dbp) && + F_ISSET((DB_PARTITION *)dbp->p_internal, PART_RANGE)) { + DBT *keys; + u_int32_t i; + + if ((ret = __partition_get_keys(dbp, &tmp_u_int32, &keys)) != 0) + goto err; + if (tmp_u_int32 != 0) { + snprintf(buf, + buflen, "nparts=%lu\n", (u_long)tmp_u_int32); + if ((ret = callback(handle, buf)) != 0) + goto err; + for (i = 0; i < tmp_u_int32 - 1; i++) + if ((ret = __db_prdbt(&keys[i], + pflag, " ", handle, callback, 0)) != 0) + goto err; + } + } +#endif + + if (keyflag && (ret = callback(handle, "keys=1\n")) != 0) + goto err; + + ret = callback(handle, "HEADER=END\n"); + +err: if (using_vdp && + (t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + if (buf != NULL) + __os_free(env, buf); + + return (ret); +} + +/* + * __db_prfooter -- + * Print the footer that marks the end of a DB dump. This is trivial, + * but for consistency's sake we don't want to put its literal contents + * in multiple places. + * + * PUBLIC: int __db_prfooter __P((void *, int (*)(void *, const void *))); + */ +int +__db_prfooter(handle, callback) + void *handle; + int (*callback) __P((void *, const void *)); +{ + return (callback(handle, "DATA=END\n")); +} + +/* + * __db_pr_callback -- + * Callback function for using pr_* functions from C. + * + * PUBLIC: int __db_pr_callback __P((void *, const void *)); + */ +int +__db_pr_callback(handle, str_arg) + void *handle; + const void *str_arg; +{ + char *str; + FILE *f; + + str = (char *)str_arg; + f = (FILE *)handle; + + if (fprintf(f, "%s", str) != (int)strlen(str)) + return (EIO); + + return (0); +} + +/* + * __db_dbtype_to_string -- + * Return the name of the database type. + * + * PUBLIC: const char * __db_dbtype_to_string __P((DBTYPE)); + */ +const char * +__db_dbtype_to_string(type) + DBTYPE type; +{ + switch (type) { + case DB_BTREE: + return ("btree"); + case DB_HASH: + return ("hash"); + case DB_RECNO: + return ("recno"); + case DB_QUEUE: + return ("queue"); + case DB_UNKNOWN: + default: + break; + } + return ("UNKNOWN TYPE"); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_rec.c b/src/libs/resiprocate/contrib/db/db/db_rec.c new file mode 100644 index 00000000..02fe0960 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_rec.c @@ -0,0 +1,1859 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 2010 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/hash.h" + +static int __db_pg_free_recover_int __P((ENV *, DB_THREAD_INFO *, + __db_pg_freedata_args *, DB *, DB_LSN *, DB_MPOOLFILE *, db_recops, int)); +static int __db_pg_free_recover_42_int __P((ENV *, DB_THREAD_INFO *, + __db_pg_freedata_42_args *, + DB *, DB_LSN *, DB_MPOOLFILE *, db_recops, int)); + +/* + * PUBLIC: int __db_addrem_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + * + * This log message is generated whenever we add or remove a duplicate + * to/from a duplicate page. On recover, we just do the opposite. + */ +int +__db_addrem_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_addrem_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__db_addrem_print); + REC_INTRO(__db_addrem_read, ip, 1); + + REC_FGET(mpf, ip, argp->pgno, &pagep, done); + modified = 0; + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->pagelsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->pagelsn); + CHECK_ABORT(env, op, cmp_n, &LSN(pagep), lsnp); + if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_ADD_DUP) || + (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_REM_DUP)) { + /* Need to redo an add, or undo a delete. */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + if ((ret = __db_pitem(dbc, pagep, argp->indx, argp->nbytes, + argp->hdr.size == 0 ? NULL : &argp->hdr, + argp->dbt.size == 0 ? NULL : &argp->dbt)) != 0) + goto out; + modified = 1; + + } else if ((cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_ADD_DUP) || + (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_REM_DUP)) { + /* Need to undo an add, or redo a delete. */ + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + if ((ret = __db_ditem(dbc, + pagep, argp->indx, argp->nbytes)) != 0) + goto out; + modified = 1; + } + + if (modified) { + if (DB_REDO(op)) + LSN(pagep) = *lsnp; + else + LSN(pagep) = argp->pagelsn; + } + + if ((ret = __memp_fput(mpf, ip, pagep, dbc->priority)) != 0) + goto out; + pagep = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, dbc->priority); + REC_CLOSE; +} + +/* + * PUBLIC: int __db_big_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_big_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_big_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__db_big_print); + REC_INTRO(__db_big_read, ip, 0); + + REC_FGET(mpf, ip, argp->pgno, &pagep, ppage); + modified = 0; + + /* + * There are three pages we need to check. The one on which we are + * adding data, the previous one whose next_pointer may have + * been updated, and the next one whose prev_pointer may have + * been updated. + */ + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->pagelsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->pagelsn); + CHECK_ABORT(env, op, cmp_n, &LSN(pagep), lsnp); + if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_ADD_BIG) || + (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_REM_BIG)) { + /* We are either redo-ing an add, or undoing a delete. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + P_INIT(pagep, file_dbp->pgsize, argp->pgno, argp->prev_pgno, + argp->next_pgno, 0, P_OVERFLOW); + OV_LEN(pagep) = argp->dbt.size; + OV_REF(pagep) = 1; + memcpy((u_int8_t *)pagep + P_OVERHEAD(file_dbp), argp->dbt.data, + argp->dbt.size); + PREV_PGNO(pagep) = argp->prev_pgno; + modified = 1; + } else if ((cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_ADD_BIG) || + (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_REM_BIG)) { + /* + * We are either undo-ing an add or redo-ing a delete. + * The page is about to be reclaimed in either case, so + * there really isn't anything to do here. + */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + modified = 1; + } else if (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_APPEND_BIG) { + /* We are redoing an append. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + memcpy((u_int8_t *)pagep + P_OVERHEAD(file_dbp) + + OV_LEN(pagep), argp->dbt.data, argp->dbt.size); + OV_LEN(pagep) += argp->dbt.size; + modified = 1; + } else if (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_APPEND_BIG) { + /* We are undoing an append. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + OV_LEN(pagep) -= argp->dbt.size; + memset((u_int8_t *)pagep + P_OVERHEAD(file_dbp) + + OV_LEN(pagep), 0, argp->dbt.size); + modified = 1; + } + if (modified) + LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn; + + ret = __memp_fput(mpf, ip, pagep, file_dbp->priority); + pagep = NULL; + if (ret != 0) + goto out; + + /* + * We only delete a whole chain of overflow items, and appends only + * apply to a single page. Adding a page is the only case that + * needs to update the chain. + */ + if (argp->opcode != DB_ADD_BIG) + goto done; + + /* Now check the previous page. */ +ppage: if (argp->prev_pgno != PGNO_INVALID) { + REC_FGET(mpf, ip, argp->prev_pgno, &pagep, npage); + modified = 0; + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->prevlsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->prevlsn); + CHECK_ABORT(env, op, cmp_n, &LSN(pagep), lsnp); + + if (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_ADD_BIG) { + /* Redo add, undo delete. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + NEXT_PGNO(pagep) = argp->pgno; + modified = 1; + } else if (cmp_n == 0 && + DB_UNDO(op) && argp->opcode == DB_ADD_BIG) { + /* Redo delete, undo add. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + NEXT_PGNO(pagep) = argp->next_pgno; + modified = 1; + } + if (modified) + LSN(pagep) = DB_REDO(op) ? *lsnp : argp->prevlsn; + ret = __memp_fput(mpf, ip, pagep, file_dbp->priority); + pagep = NULL; + if (ret != 0) + goto out; + } + pagep = NULL; + + /* Now check the next page. Can only be set on a delete. */ +npage: if (argp->next_pgno != PGNO_INVALID) { + REC_FGET(mpf, ip, argp->next_pgno, &pagep, done); + modified = 0; + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->nextlsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->nextlsn); + CHECK_ABORT(env, op, cmp_n, &LSN(pagep), lsnp); + if (cmp_p == 0 && DB_REDO(op)) { + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + PREV_PGNO(pagep) = PGNO_INVALID; + modified = 1; + } else if (cmp_n == 0 && DB_UNDO(op)) { + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + PREV_PGNO(pagep) = argp->pgno; + modified = 1; + } + if (modified) + LSN(pagep) = DB_REDO(op) ? *lsnp : argp->nextlsn; + ret = __memp_fput(mpf, ip, pagep, file_dbp->priority); + pagep = NULL; + if (ret != 0) + goto out; + } + pagep = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, file_dbp->priority); + REC_CLOSE; +} + +/* + * __db_ovref_recover -- + * Recovery function for __db_ovref(). + * + * PUBLIC: int __db_ovref_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_ovref_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_ovref_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int cmp, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__db_ovref_print); + REC_INTRO(__db_ovref_read, ip, 0); + + REC_FGET(mpf, ip, argp->pgno, &pagep, done); + + cmp = LOG_COMPARE(&LSN(pagep), &argp->lsn); + CHECK_LSN(env, op, cmp, &LSN(pagep), &argp->lsn); + if (cmp == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + OV_REF(pagep) += argp->adjust; + pagep->lsn = *lsnp; + } else if (LOG_COMPARE(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) { + /* Need to undo update described. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + OV_REF(pagep) -= argp->adjust; + pagep->lsn = argp->lsn; + } + ret = __memp_fput(mpf, ip, pagep, file_dbp->priority); + pagep = NULL; + if (ret != 0) + goto out; + pagep = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, file_dbp->priority); + REC_CLOSE; +} + +/* + * __db_debug_recover -- + * Recovery function for debug. + * + * PUBLIC: int __db_debug_recover __P((ENV *, + * PUBLIC: DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_debug_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_debug_args *argp; + int ret; + + COMPQUIET(op, DB_TXN_ABORT); + COMPQUIET(info, NULL); + + REC_PRINT(__db_debug_print); + REC_NOOP_INTRO(__db_debug_read); + + *lsnp = argp->prev_lsn; + ret = 0; + + REC_NOOP_CLOSE; +} + +/* + * __db_noop_recover -- + * Recovery function for noop. + * + * PUBLIC: int __db_noop_recover __P((ENV *, + * PUBLIC: DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_noop_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_noop_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int cmp_n, cmp_p, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__db_noop_print); + REC_INTRO(__db_noop_read, ip, 0); + + REC_FGET(mpf, ip, argp->pgno, &pagep, done); + + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->prevlsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->prevlsn); + CHECK_ABORT(env, op, cmp_n, &LSN(pagep), lsnp); + if (cmp_p == 0 && DB_REDO(op)) { + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + LSN(pagep) = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + LSN(pagep) = argp->prevlsn; + } + ret = __memp_fput(mpf, ip, pagep, file_dbp->priority); + pagep = NULL; + +done: *lsnp = argp->prev_lsn; +out: if (pagep != NULL) + (void)__memp_fput(mpf, + ip, pagep, file_dbp->priority); + REC_CLOSE; +} + +/* + * __db_pg_alloc_recover -- + * Recovery function for pg_alloc. + * + * PUBLIC: int __db_pg_alloc_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_alloc_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_alloc_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DBMETA *meta; + DB_MPOOLFILE *mpf; + PAGE *pagep; + db_pgno_t pgno; + int cmp_n, cmp_p, created, level, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + meta = NULL; + pagep = NULL; + created = 0; + REC_PRINT(__db_pg_alloc_print); + REC_INTRO(__db_pg_alloc_read, ip, 0); + + /* + * Fix up the metadata page. If we're redoing the operation, we have + * to get the metadata page and update its LSN and its free pointer. + * If we're undoing the operation and the page was ever created, we put + * it on the freelist. + */ + pgno = PGNO_BASE_MD; + if ((ret = __memp_fget(mpf, &pgno, ip, NULL, 0, &meta)) != 0) { + /* The metadata page must always exist on redo. */ + if (DB_REDO(op)) { + ret = __db_pgerr(file_dbp, pgno, ret); + goto out; + } else + goto done; + } + cmp_n = LOG_COMPARE(lsnp, &LSN(meta)); + cmp_p = LOG_COMPARE(&LSN(meta), &argp->meta_lsn); + CHECK_LSN(env, op, cmp_p, &LSN(meta), &argp->meta_lsn); + CHECK_ABORT(env, op, cmp_n, &LSN(meta), lsnp); + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &meta); + LSN(meta) = *lsnp; + meta->free = argp->next; + if (argp->pgno > meta->last_pgno) + meta->last_pgno = argp->pgno; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Need to undo update described. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &meta); + LSN(meta) = argp->meta_lsn; + /* + * If the page has a zero LSN then its newly created and + * will be truncated rather than go on the free list. + */ + if (!IS_ZERO_LSN(argp->page_lsn)) + meta->free = argp->pgno; + meta->last_pgno = argp->last_pgno; + } + +#ifdef HAVE_FTRUNCATE + /* + * check to see if we are keeping a sorted freelist, if so put + * this back in the in memory list. It must be the first element. + */ + if (op == DB_TXN_ABORT && !IS_ZERO_LSN(argp->page_lsn)) { + db_pgno_t *list; + u_int32_t nelem; + + if ((ret = __memp_get_freelist(mpf, &nelem, &list)) != 0) + goto out; + if (list != NULL && (nelem == 0 || *list != argp->pgno)) { + if ((ret = + __memp_extend_freelist(mpf, nelem + 1, &list)) != 0) + goto out; + if (nelem != 0) + memmove(list + 1, list, nelem * sizeof(*list)); + *list = argp->pgno; + } + } +#endif + + /* + * Fix up the allocated page. If the page does not exist + * and we can truncate it then don't create it. + * Otherwise if we're redoing the operation, we have + * to get the page (creating it if it doesn't exist), and update its + * LSN. If we're undoing the operation, we have to reset the page's + * LSN and put it on the free list. + */ + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { + /* + * We have to be able to identify if a page was newly + * created so we can recover it properly. We cannot simply + * look for an empty header, because hash uses a pgin + * function that will set the header. Instead, we explicitly + * try for the page without CREATE and if that fails, then + * create it. + */ + if (DB_UNDO(op)) + goto do_truncate; + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, + DB_MPOOL_CREATE, &pagep)) != 0) { + if (DB_UNDO(op) && ret == ENOSPC) + goto do_truncate; + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } + created = 1; + } + + /* Fix up the allocated page. */ + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->page_lsn); + + /* + * If an initial allocation is aborted and then reallocated during + * an archival restore the log record will have an LSN for the page + * but the page will be empty. + */ + if (IS_ZERO_LSN(LSN(pagep))) + cmp_p = 0; + + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->page_lsn); + /* + * Another special case we have to handle is if we ended up with a + * page of all 0's which can happen if we abort between allocating a + * page in mpool and initializing it. In that case, even if we're + * undoing, we need to re-initialize the page. + */ + if (DB_REDO(op) && cmp_p == 0) { + /* Need to redo update described. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + switch (argp->ptype) { + case P_LBTREE: + case P_LRECNO: + case P_LDUP: + level = LEAFLEVEL; + break; + default: + level = 0; + break; + } + P_INIT(pagep, file_dbp->pgsize, + argp->pgno, PGNO_INVALID, PGNO_INVALID, level, argp->ptype); + + pagep->lsn = *lsnp; + } else if (DB_UNDO(op) && (cmp_n == 0 || created)) { + /* + * This is where we handle the case of a 0'd page (pagep->pgno + * is equal to PGNO_INVALID). + * Undo the allocation, reinitialize the page and + * link its next pointer to the free list. + */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + P_INIT(pagep, file_dbp->pgsize, + argp->pgno, PGNO_INVALID, argp->next, 0, P_INVALID); + + pagep->lsn = argp->page_lsn; + } + +do_truncate: + /* + * If the page was newly created, give it back. + */ + if ((pagep == NULL || IS_ZERO_LSN(LSN(pagep))) && + IS_ZERO_LSN(argp->page_lsn) && DB_UNDO(op)) { + /* Discard the page. */ + if (pagep != NULL) { + if ((ret = __memp_fput(mpf, ip, + pagep, DB_PRIORITY_VERY_LOW)) != 0) + goto out; + pagep = NULL; + } + /* Give the page back to the OS. */ + if (meta->last_pgno <= argp->pgno && (ret = __memp_ftruncate( + mpf, NULL, ip, argp->pgno, MP_TRUNC_RECOVER)) != 0) + goto out; + } + + if (pagep != NULL) { + ret = __memp_fput(mpf, ip, pagep, file_dbp->priority); + pagep = NULL; + if (ret != 0) + goto out; + } + + ret = __memp_fput(mpf, ip, meta, file_dbp->priority); + meta = NULL; + if (ret != 0) + goto out; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, file_dbp->priority); + if (meta != NULL) + (void)__memp_fput(mpf, ip, meta, file_dbp->priority); + REC_CLOSE; +} + +/* + * __db_pg_free_recover_int -- + */ +static int +__db_pg_free_recover_int(env, ip, argp, file_dbp, lsnp, mpf, op, data) + ENV *env; + DB_THREAD_INFO *ip; + __db_pg_freedata_args *argp; + DB *file_dbp; + DB_LSN *lsnp; + DB_MPOOLFILE *mpf; + db_recops op; + int data; +{ + DBMETA *meta; + DB_LSN copy_lsn; + PAGE *pagep, *prevp; + int cmp_n, cmp_p, is_meta, ret; + + meta = NULL; + pagep = prevp = NULL; + + /* + * Get the "metapage". This will either be the metapage + * or the previous page in the free list if we are doing + * sorted allocations. If its a previous page then + * we will not be truncating. + */ + is_meta = argp->meta_pgno == PGNO_BASE_MD; + + REC_FGET(mpf, ip, argp->meta_pgno, &meta, check_meta); + + if (argp->meta_pgno != PGNO_BASE_MD) + prevp = (PAGE *)meta; + + cmp_n = LOG_COMPARE(lsnp, &LSN(meta)); + cmp_p = LOG_COMPARE(&LSN(meta), &argp->meta_lsn); + CHECK_LSN(env, op, cmp_p, &LSN(meta), &argp->meta_lsn); + CHECK_ABORT(env, op, cmp_n, &LSN(meta), lsnp); + + /* + * Fix up the metadata page. If we're redoing or undoing the operation + * we get the page and update its LSN, last and free pointer. + */ + if (cmp_p == 0 && DB_REDO(op)) { + REC_DIRTY(mpf, ip, file_dbp->priority, &meta); + /* + * If we are at the end of the file truncate, otherwise + * put on the free list. + */ + if (argp->pgno == argp->last_pgno) + meta->last_pgno = argp->pgno - 1; + else if (is_meta) + meta->free = argp->pgno; + else + NEXT_PGNO(prevp) = argp->pgno; + LSN(meta) = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Need to undo the deallocation. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &meta); + if (is_meta) { + if (meta->last_pgno < argp->pgno) + meta->last_pgno = argp->pgno; + meta->free = argp->next; + } else + NEXT_PGNO(prevp) = argp->next; + LSN(meta) = argp->meta_lsn; + } + +check_meta: + if (ret != 0 && is_meta) { + /* The metadata page must always exist. */ + ret = __db_pgerr(file_dbp, argp->meta_pgno, ret); + goto out; + } + + /* + * Get the freed page. Don't create the page if we are going to + * free it. If we're redoing the operation we get the page and + * explicitly discard its contents, then update its LSN. If we're + * undoing the operation, we get the page and restore its header. + */ + if (DB_REDO(op) || (is_meta && meta->last_pgno < argp->pgno)) { + if ((ret = __memp_fget(mpf, &argp->pgno, + ip, NULL, 0, &pagep)) != 0) { + if (ret != DB_PAGE_NOTFOUND) + goto out; + if (is_meta && + DB_REDO(op) && meta->last_pgno <= argp->pgno) + goto trunc; + goto done; + } + } else if ((ret = __memp_fget(mpf, &argp->pgno, + ip, NULL, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + + (void)__ua_memcpy(©_lsn, &LSN(argp->header.data), sizeof(DB_LSN)); + cmp_n = IS_ZERO_LSN(LSN(pagep)) ? 0 : LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), ©_lsn); + + /* + * This page got extended by a later allocation, + * but its allocation was not in the scope of this + * recovery pass. + */ + if (IS_ZERO_LSN(LSN(pagep))) + cmp_p = 0; + + CHECK_LSN(env, op, cmp_p, &LSN(pagep), ©_lsn); + if (DB_REDO(op) && + (cmp_p == 0 || + (IS_ZERO_LSN(copy_lsn) && + LOG_COMPARE(&LSN(pagep), &argp->meta_lsn) <= 0))) { + /* Need to redo the deallocation. */ + /* + * The page can be truncated if it was truncated at runtime + * and the current metapage reflects the truncation. + */ + if (is_meta && meta->last_pgno <= argp->pgno && + argp->last_pgno <= argp->pgno) { + if ((ret = __memp_fput(mpf, ip, + pagep, DB_PRIORITY_VERY_LOW)) != 0) + goto out; + pagep = NULL; +trunc: if ((ret = __memp_ftruncate(mpf, NULL, ip, + argp->pgno, MP_TRUNC_RECOVER)) != 0) + goto out; + } else if (argp->last_pgno == argp->pgno) { + /* The page was truncated at runtime, zero it out. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + P_INIT(pagep, 0, PGNO_INVALID, + PGNO_INVALID, PGNO_INVALID, 0, P_INVALID); + ZERO_LSN(pagep->lsn); + } else { + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + P_INIT(pagep, file_dbp->pgsize, + argp->pgno, PGNO_INVALID, argp->next, 0, P_INVALID); + pagep->lsn = *lsnp; + + } + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Need to reallocate the page. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + memcpy(pagep, argp->header.data, argp->header.size); + if (data) + memcpy((u_int8_t*)pagep + HOFFSET(pagep), + argp->data.data, argp->data.size); + } + if (pagep != NULL && + (ret = __memp_fput(mpf, ip, pagep, file_dbp->priority)) != 0) + goto out; + + pagep = NULL; +#ifdef HAVE_FTRUNCATE + /* + * If we are keeping an in memory free list remove this + * element from the list. + */ + if (op == DB_TXN_ABORT && argp->pgno != argp->last_pgno) { + db_pgno_t *lp; + u_int32_t nelem, pos; + + if ((ret = __memp_get_freelist(mpf, &nelem, &lp)) != 0) + goto out; + if (lp != NULL) { + pos = 0; + if (!is_meta) { + __db_freelist_pos(argp->pgno, lp, nelem, &pos); + + /* + * If we aborted after logging but before + * updating the free list don't do anything. + */ + if (argp->pgno != lp[pos]) { + DB_ASSERT(env, + argp->meta_pgno == lp[pos]); + goto done; + } + DB_ASSERT(env, + argp->meta_pgno == lp[pos - 1]); + } else if (nelem != 0 && argp->pgno != lp[pos]) + goto done; + + if (pos < nelem) + memmove(&lp[pos], &lp[pos + 1], + ((nelem - pos) - 1) * sizeof(*lp)); + + /* Shrink the list */ + if ((ret = + __memp_extend_freelist(mpf, nelem - 1, &lp)) != 0) + goto out; + } + } +#endif +done: + if (meta != NULL && + (ret = __memp_fput(mpf, ip, meta, file_dbp->priority)) != 0) + goto out; + meta = NULL; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, file_dbp->priority); + if (meta != NULL) + (void)__memp_fput(mpf, ip, meta, file_dbp->priority); + + return (ret); +} + +/* + * __db_pg_free_recover -- + * Recovery function for pg_free. + * + * PUBLIC: int __db_pg_free_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_free_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_free_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + int ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__db_pg_free_print); + REC_INTRO(__db_pg_free_read, ip, 0); + + ret = __db_pg_free_recover_int(env, ip, + (__db_pg_freedata_args *)argp, file_dbp, lsnp, mpf, op, 0); + +done: *lsnp = argp->prev_lsn; +out: + REC_CLOSE; +} + +/* + * __db_pg_freedata_recover -- + * Recovery function for pg_freedata. + * + * PUBLIC: int __db_pg_freedata_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_freedata_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_freedata_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + int ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__db_pg_freedata_print); + REC_INTRO(__db_pg_freedata_read, ip, 0); + + ret = __db_pg_free_recover_int(env, + ip, argp, file_dbp, lsnp, mpf, op, 1); + +done: *lsnp = argp->prev_lsn; +out: + REC_CLOSE; +} + +/* + * __db_cksum_recover -- + * Recovery function for checksum failure log record. + * + * PUBLIC: int __db_cksum_recover __P((ENV *, + * PUBLIC: DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_cksum_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_cksum_args *argp; + int ret; + + COMPQUIET(info, NULL); + COMPQUIET(lsnp, NULL); + COMPQUIET(op, DB_TXN_ABORT); + + REC_PRINT(__db_cksum_print); + + if ((ret = __db_cksum_read(env, dbtp->data, &argp)) != 0) + return (ret); + + /* + * We had a checksum failure -- the only option is to run catastrophic + * recovery. + */ + if (F_ISSET(env, ENV_RECOVER_FATAL)) + ret = 0; + else { + __db_errx(env, + "Checksum failure requires catastrophic recovery"); + ret = __env_panic(env, DB_RUNRECOVERY); + } + + __os_free(env, argp); + return (ret); +} + +/* + * __db_pg_init_recover -- + * Recovery function to reinit pages after truncation. + * + * PUBLIC: int __db_pg_init_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_init_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_init_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_LSN copy_lsn; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int cmp_n, cmp_p, ret, type; + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__db_pg_init_print); + REC_INTRO(__db_pg_init_read, ip, 0); + + mpf = file_dbp->mpf; + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { + if (DB_UNDO(op)) { + if (ret == DB_PAGE_NOTFOUND) + goto done; + else { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } + } + + /* + * This page was truncated and may simply not have + * had an item written to it yet. This should only + * happen on hash databases, so confirm that. + */ + DB_ASSERT(env, file_dbp->type == DB_HASH); + if ((ret = __memp_fget(mpf, &argp->pgno, + ip, NULL, DB_MPOOL_CREATE, &pagep)) != 0) { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } + } + + (void)__ua_memcpy(©_lsn, &LSN(argp->header.data), sizeof(DB_LSN)); + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), ©_lsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), ©_lsn); + CHECK_ABORT(env, op, cmp_n, &LSN(pagep), lsnp); + + if (cmp_p == 0 && DB_REDO(op)) { + if (TYPE(pagep) == P_HASH) + type = P_HASH; + else + type = file_dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE; + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + P_INIT(pagep, file_dbp->pgsize, PGNO(pagep), PGNO_INVALID, + PGNO_INVALID, TYPE(pagep) == P_HASH ? 0 : 1, type); + pagep->lsn = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Put the data back on the page. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + memcpy(pagep, argp->header.data, argp->header.size); + if (argp->data.size > 0) + memcpy((u_int8_t*)pagep + HOFFSET(pagep), + argp->data.data, argp->data.size); + } + if ((ret = __memp_fput(mpf, ip, pagep, file_dbp->priority)) != 0) + goto out; + +done: *lsnp = argp->prev_lsn; +out: + REC_CLOSE; +} + +/* + * __db_pg_trunc_recover -- + * Recovery function for pg_trunc. + * + * PUBLIC: int __db_pg_trunc_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_trunc_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ +#ifdef HAVE_FTRUNCATE + __db_pg_trunc_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DBMETA *meta; + DB_MPOOLFILE *mpf; + PAGE *pagep; + db_pglist_t *pglist, *lp; + db_pgno_t last_pgno, *list; + u_int32_t felem, nelem, pos; + int ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__db_pg_trunc_print); + REC_INTRO(__db_pg_trunc_read, ip, 1); + + pglist = (db_pglist_t *) argp->list.data; + nelem = argp->list.size / sizeof(db_pglist_t); + if (DB_REDO(op)) { + /* + * First call __db_pg_truncate to find the truncation + * point, truncate the file and return the new last_pgno. + */ + last_pgno = argp->last_pgno; + if ((ret = __db_pg_truncate(dbc, NULL, pglist, + NULL, &nelem, argp->next_free, &last_pgno, lsnp, 1)) != 0) + goto out; + + if (argp->last_free != PGNO_INVALID) { + /* + * Update the next pointer of the last page in + * the freelist. If the truncation point is + * beyond next_free then this is still in the freelist + * otherwise the last_free page is at the end. + */ + if ((ret = __memp_fget(mpf, + &argp->last_free, ip, NULL, 0, &meta)) == 0) { + if (LOG_COMPARE(&LSN(meta), + &argp->last_lsn) == 0) { + REC_DIRTY(mpf, + ip, dbc->priority, &meta); + if (pglist->pgno > last_pgno) + NEXT_PGNO(meta) = PGNO_INVALID; + else + NEXT_PGNO(meta) = pglist->pgno; + LSN(meta) = *lsnp; + } + if ((ret = __memp_fput(mpf, ip, + meta, file_dbp->priority)) != 0) + goto out; + meta = NULL; + } else if (ret != DB_PAGE_NOTFOUND) + goto out; + } + if ((ret = __memp_fget(mpf, &argp->meta, ip, NULL, + 0, &meta)) != 0) + goto out; + if (LOG_COMPARE(&LSN(meta), &argp->meta_lsn) == 0) { + REC_DIRTY(mpf, ip, dbc->priority, &meta); + if (argp->last_free == PGNO_INVALID) { + if (nelem == 0) + meta->free = PGNO_INVALID; + else + meta->free = pglist->pgno; + } + meta->last_pgno = last_pgno; + LSN(meta) = *lsnp; + } + } else { + /* Put the free list back in its original order. */ + for (lp = pglist; lp < &pglist[nelem]; lp++) { + if ((ret = __memp_fget(mpf, &lp->pgno, ip, + NULL, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + if (IS_ZERO_LSN(LSN(pagep)) || + LOG_COMPARE(&LSN(pagep), lsnp) == 0) { + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + P_INIT(pagep, file_dbp->pgsize, lp->pgno, + PGNO_INVALID, lp->next_pgno, 0, P_INVALID); + LSN(pagep) = lp->lsn; + } + if ((ret = __memp_fput(mpf, + ip, pagep, file_dbp->priority)) != 0) + goto out; + } + /* + * Link the truncated part back into the free list. + * Its either after the last_free page or direclty + * linked to the metadata page. + */ + if (argp->last_free != PGNO_INVALID) { + if ((ret = __memp_fget(mpf, &argp->last_free, + ip, NULL, DB_MPOOL_EDIT, &meta)) == 0) { + if (LOG_COMPARE(&LSN(meta), lsnp) == 0) { + NEXT_PGNO(meta) = argp->next_free; + LSN(meta) = argp->last_lsn; + } + if ((ret = __memp_fput(mpf, ip, + meta, file_dbp->priority)) != 0) + goto out; + } else if (ret != DB_PAGE_NOTFOUND) + goto out; + meta = NULL; + } + if ((ret = __memp_fget(mpf, &argp->meta, + ip, NULL, DB_MPOOL_EDIT, &meta)) != 0) + goto out; + if (LOG_COMPARE(&LSN(meta), lsnp) == 0) { + REC_DIRTY(mpf, ip, dbc->priority, &meta); + /* + * If we had to break up the list last_pgno + * may only represent the end of the block. + */ + if (meta->last_pgno < argp->last_pgno) + meta->last_pgno = argp->last_pgno; + if (argp->last_free == PGNO_INVALID) + meta->free = argp->next_free; + LSN(meta) = argp->meta_lsn; + } + } + + if ((ret = __memp_fput(mpf, ip, meta, file_dbp->priority)) != 0) + goto out; + + if (op == DB_TXN_ABORT) { + /* + * Put the pages back on the in memory free list. + * If this is part of a multi-record truncate then + * we need to find this batch, it may not be at the end. + * If we aborted while writing one of the log records + * then this set may still be in the list. + */ + if ((ret = __memp_get_freelist(mpf, &felem, &list)) != 0) + goto out; + if (list != NULL) { + if (felem != 0 && list[felem - 1] > pglist->pgno) { + __db_freelist_pos( + pglist->pgno, list, felem, &pos); + DB_ASSERT(env, pos < felem); + if (pglist->pgno == list[pos]) + goto done; + pos++; + } else if (felem != 0 && + list[felem - 1] == pglist->pgno) + goto done; + else + pos = felem; + if ((ret = __memp_extend_freelist( + mpf, felem + nelem, &list)) != 0) + goto out; + if (pos != felem) + memmove(&list[nelem + pos], &list[pos], + sizeof(*list) * (felem - pos)); + for (lp = pglist; lp < &pglist[nelem]; lp++) + list[pos++] = lp->pgno; + } + } + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +#else + /* + * If HAVE_FTRUNCATE is not defined, we'll never see pg_trunc records + * to recover. + */ + COMPQUIET(env, NULL); + COMPQUIET(dbtp, NULL); + COMPQUIET(lsnp, NULL); + COMPQUIET(op, DB_TXN_ABORT); + COMPQUIET(info, NULL); + return (EINVAL); +#endif +} +/* + * __db_pg_sort_44_recover -- + * Recovery function for pg_sort. + * This is deprecated and kept for replication upgrades. + * + * PUBLIC: int __db_pg_sort_44_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_sort_44_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ +#ifdef HAVE_FTRUNCATE + __db_pg_sort_44_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DBMETA *meta; + DB_MPOOLFILE *mpf; + PAGE *pagep; + db_pglist_t *pglist, *lp; + db_pgno_t pgno, *list; + u_int32_t felem, nelem; + int ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__db_pg_sort_44_print); + REC_INTRO(__db_pg_sort_44_read, ip, 1); + + pglist = (db_pglist_t *) argp->list.data; + nelem = argp->list.size / sizeof(db_pglist_t); + if (DB_REDO(op)) { + pgno = argp->last_pgno; + __db_freelist_sort(pglist, nelem); + if ((ret = __db_pg_truncate(dbc, NULL, + pglist, NULL, &nelem, PGNO_INVALID, &pgno, lsnp, 1)) != 0) + goto out; + + if (argp->last_free != PGNO_INVALID) { + if ((ret = __memp_fget(mpf, + &argp->last_free, ip, NULL, 0, &meta)) == 0) { + if (LOG_COMPARE(&LSN(meta), + &argp->last_lsn) == 0) { + REC_DIRTY(mpf, + ip, dbc->priority, &meta); + NEXT_PGNO(meta) = PGNO_INVALID; + LSN(meta) = *lsnp; + } + if ((ret = __memp_fput(mpf, ip, + meta, file_dbp->priority)) != 0) + goto out; + meta = NULL; + } else if (ret != DB_PAGE_NOTFOUND) + goto out; + } + if ((ret = __memp_fget(mpf, &argp->meta, ip, NULL, + 0, &meta)) != 0) + goto out; + if (LOG_COMPARE(&LSN(meta), &argp->meta_lsn) == 0) { + REC_DIRTY(mpf, ip, dbc->priority, &meta); + if (argp->last_free == PGNO_INVALID) { + if (nelem == 0) + meta->free = PGNO_INVALID; + else + meta->free = pglist->pgno; + } + meta->last_pgno = pgno; + LSN(meta) = *lsnp; + } + } else { + /* Put the free list back in its original order. */ + for (lp = pglist; lp < &pglist[nelem]; lp++) { + if ((ret = __memp_fget(mpf, &lp->pgno, ip, + NULL, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + if (IS_ZERO_LSN(LSN(pagep)) || + LOG_COMPARE(&LSN(pagep), lsnp) == 0) { + REC_DIRTY(mpf, ip, dbc->priority, &pagep); + if (lp == &pglist[nelem - 1]) + pgno = PGNO_INVALID; + else + pgno = lp[1].pgno; + + P_INIT(pagep, file_dbp->pgsize, + lp->pgno, PGNO_INVALID, pgno, 0, P_INVALID); + LSN(pagep) = lp->lsn; + } + if ((ret = __memp_fput(mpf, + ip, pagep, file_dbp->priority)) != 0) + goto out; + } + if (argp->last_free != PGNO_INVALID) { + if ((ret = __memp_fget(mpf, &argp->last_free, + ip, NULL, DB_MPOOL_EDIT, &meta)) == 0) { + if (LOG_COMPARE(&LSN(meta), lsnp) == 0) { + NEXT_PGNO(meta) = pglist->pgno; + LSN(meta) = argp->last_lsn; + } + if ((ret = __memp_fput(mpf, ip, + meta, file_dbp->priority)) != 0) + goto out; + } else if (ret != DB_PAGE_NOTFOUND) + goto out; + meta = NULL; + } + if ((ret = __memp_fget(mpf, &argp->meta, + ip, NULL, DB_MPOOL_EDIT, &meta)) != 0) + goto out; + if (LOG_COMPARE(&LSN(meta), lsnp) == 0) { + REC_DIRTY(mpf, ip, dbc->priority, &meta); + meta->last_pgno = argp->last_pgno; + if (argp->last_free == PGNO_INVALID) + meta->free = pglist->pgno; + LSN(meta) = argp->meta_lsn; + } + } + if (op == DB_TXN_ABORT) { + if ((ret = __memp_get_freelist(mpf, &felem, &list)) != 0) + goto out; + if (list != NULL) { + DB_ASSERT(env, felem == 0 || + argp->last_free == list[felem - 1]); + if ((ret = __memp_extend_freelist( + mpf, felem + nelem, &list)) != 0) + goto out; + for (lp = pglist; lp < &pglist[nelem]; lp++) + list[felem++] = lp->pgno; + } + } + + if ((ret = __memp_fput(mpf, ip, meta, file_dbp->priority)) != 0) + goto out; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +#else + /* + * If HAVE_FTRUNCATE is not defined, we'll never see pg_sort records + * to recover. + */ + COMPQUIET(env, NULL); + COMPQUIET(dbtp, NULL); + COMPQUIET(lsnp, NULL); + COMPQUIET(op, DB_TXN_ABORT); + COMPQUIET(info, NULL); + return (EINVAL); +#endif +} + +/* + * __db_pg_alloc_42_recover -- + * Recovery function for pg_alloc. + * + * PUBLIC: int __db_pg_alloc_42_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_alloc_42_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_alloc_42_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DBMETA *meta; + DB_MPOOLFILE *mpf; + PAGE *pagep; + db_pgno_t pgno; + int cmp_n, cmp_p, created, level, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + meta = NULL; + pagep = NULL; + created = 0; + REC_PRINT(__db_pg_alloc_42_print); + REC_INTRO(__db_pg_alloc_42_read, ip, 0); + + /* + * Fix up the metadata page. If we're redoing the operation, we have + * to get the metadata page and update its LSN and its free pointer. + * If we're undoing the operation and the page was ever created, we put + * it on the freelist. + */ + pgno = PGNO_BASE_MD; + if ((ret = __memp_fget(mpf, &pgno, ip, NULL, 0, &meta)) != 0) { + /* The metadata page must always exist on redo. */ + if (DB_REDO(op)) { + ret = __db_pgerr(file_dbp, pgno, ret); + goto out; + } else + goto done; + } + cmp_n = LOG_COMPARE(lsnp, &LSN(meta)); + cmp_p = LOG_COMPARE(&LSN(meta), &argp->meta_lsn); + CHECK_LSN(env, op, cmp_p, &LSN(meta), &argp->meta_lsn); + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &meta); + LSN(meta) = *lsnp; + meta->free = argp->next; + if (argp->pgno > meta->last_pgno) + meta->last_pgno = argp->pgno; + } else if (cmp_n == 0 && DB_UNDO(op)) { + goto no_rollback; + } + + /* + * Fix up the allocated page. If the page does not exist + * and we can truncate it then don't create it. + * Otherwise if we're redoing the operation, we have + * to get the page (creating it if it doesn't exist), and update its + * LSN. If we're undoing the operation, we have to reset the page's + * LSN and put it on the free list, or truncate it. + */ + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { + /* + * We have to be able to identify if a page was newly + * created so we can recover it properly. We cannot simply + * look for an empty header, because hash uses a pgin + * function that will set the header. Instead, we explicitly + * try for the page without CREATE and if that fails, then + * create it. + */ + if ((ret = __memp_fget(mpf, &argp->pgno, + ip, NULL, DB_MPOOL_CREATE, &pagep)) != 0) { + if (DB_UNDO(op) && ret == ENOSPC) + goto do_truncate; + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } + created = 1; + } + + /* Fix up the allocated page. */ + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->page_lsn); + + /* + * If an initial allocation is aborted and then reallocated during + * an archival restore the log record will have an LSN for the page + * but the page will be empty. + */ + if (IS_ZERO_LSN(LSN(pagep)) || + (IS_ZERO_LSN(argp->page_lsn) && IS_INIT_LSN(LSN(pagep)))) + cmp_p = 0; + + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->page_lsn); + /* + * Another special case we have to handle is if we ended up with a + * page of all 0's which can happen if we abort between allocating a + * page in mpool and initializing it. In that case, even if we're + * undoing, we need to re-initialize the page. + */ + if (DB_REDO(op) && cmp_p == 0) { + /* Need to redo update described. */ + switch (argp->ptype) { + case P_LBTREE: + case P_LRECNO: + case P_LDUP: + level = LEAFLEVEL; + break; + default: + level = 0; + break; + } + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + P_INIT(pagep, file_dbp->pgsize, + argp->pgno, PGNO_INVALID, PGNO_INVALID, level, argp->ptype); + + pagep->lsn = *lsnp; + } else if (DB_UNDO(op) && (cmp_n == 0 || created)) { + /* + * This is where we handle the case of a 0'd page (pagep->pgno + * is equal to PGNO_INVALID). + * Undo the allocation, reinitialize the page and + * link its next pointer to the free list. + */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + P_INIT(pagep, file_dbp->pgsize, + argp->pgno, PGNO_INVALID, argp->next, 0, P_INVALID); + + pagep->lsn = argp->page_lsn; + } + +do_truncate: + /* + * We cannot undo things from 4.2 land, because we nolonger + * have limbo processing. + */ + if ((pagep == NULL || IS_ZERO_LSN(LSN(pagep))) && + IS_ZERO_LSN(argp->page_lsn) && DB_UNDO(op)) { +no_rollback: __db_errx(env, +"Cannot replicate prepared transactions from master running release 4.2 "); + ret = __env_panic(env, EINVAL); + } + + if (pagep != NULL && + (ret = __memp_fput(mpf, ip, pagep, file_dbp->priority)) != 0) + goto out; + pagep = NULL; + + if ((ret = __memp_fput(mpf, ip, meta, file_dbp->priority)) != 0) + goto out; + meta = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, file_dbp->priority); + if (meta != NULL) + (void)__memp_fput(mpf, ip, meta, file_dbp->priority); + REC_CLOSE; +} + +/* + * __db_pg_free_recover_42_int -- + */ +static int +__db_pg_free_recover_42_int(env, ip, argp, file_dbp, lsnp, mpf, op, data) + ENV *env; + DB_THREAD_INFO *ip; + __db_pg_freedata_42_args *argp; + DB *file_dbp; + DB_LSN *lsnp; + DB_MPOOLFILE *mpf; + db_recops op; + int data; +{ + DBMETA *meta; + DB_LSN copy_lsn; + PAGE *pagep, *prevp; + int cmp_n, cmp_p, is_meta, ret; + + meta = NULL; + pagep = NULL; + prevp = NULL; + + /* + * Get the "metapage". This will either be the metapage + * or the previous page in the free list if we are doing + * sorted allocations. If its a previous page then + * we will not be truncating. + */ + is_meta = argp->meta_pgno == PGNO_BASE_MD; + + REC_FGET(mpf, ip, argp->meta_pgno, &meta, check_meta); + + if (argp->meta_pgno != PGNO_BASE_MD) + prevp = (PAGE *)meta; + + cmp_n = LOG_COMPARE(lsnp, &LSN(meta)); + cmp_p = LOG_COMPARE(&LSN(meta), &argp->meta_lsn); + CHECK_LSN(env, op, cmp_p, &LSN(meta), &argp->meta_lsn); + + /* + * Fix up the metadata page. If we're redoing or undoing the operation + * we get the page and update its LSN, last and free pointer. + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo the deallocation. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &meta); + if (prevp == NULL) + meta->free = argp->pgno; + else + NEXT_PGNO(prevp) = argp->pgno; + /* + * If this was a compensating transaction and + * we are a replica, then we never executed the + * original allocation which incremented meta->free. + */ + if (prevp == NULL && meta->last_pgno < meta->free) + meta->last_pgno = meta->free; + LSN(meta) = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Need to undo the deallocation. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &meta); + if (prevp == NULL) + meta->free = argp->next; + else + NEXT_PGNO(prevp) = argp->next; + LSN(meta) = argp->meta_lsn; + if (prevp == NULL && meta->last_pgno < argp->pgno) + meta->last_pgno = argp->pgno; + } + +check_meta: + if (ret != 0 && is_meta) { + /* The metadata page must always exist. */ + ret = __db_pgerr(file_dbp, argp->meta_pgno, ret); + goto out; + } + + /* + * Get the freed page. If we support truncate then don't + * create the page if we are going to free it. If we're + * redoing the operation we get the page and explicitly discard + * its contents, then update its LSN. If we're undoing the + * operation, we get the page and restore its header. + * If we don't support truncate, then we must create the page + * and roll it back. + */ + if ((ret = __memp_fget(mpf, &argp->pgno, + ip, NULL, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + + (void)__ua_memcpy(©_lsn, &LSN(argp->header.data), sizeof(DB_LSN)); + cmp_n = IS_ZERO_LSN(LSN(pagep)) ? 0 : LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), ©_lsn); + + CHECK_LSN(env, op, cmp_p, &LSN(pagep), ©_lsn); + if (DB_REDO(op) && + (cmp_p == 0 || + (IS_ZERO_LSN(copy_lsn) && + LOG_COMPARE(&LSN(pagep), &argp->meta_lsn) <= 0))) { + /* Need to redo the deallocation. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + P_INIT(pagep, file_dbp->pgsize, + argp->pgno, PGNO_INVALID, argp->next, 0, P_INVALID); + pagep->lsn = *lsnp; + } else if (cmp_n == 0 && DB_UNDO(op)) { + /* Need to reallocate the page. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + memcpy(pagep, argp->header.data, argp->header.size); + if (data) + memcpy((u_int8_t*)pagep + HOFFSET(pagep), + argp->data.data, argp->data.size); + } + if (pagep != NULL && + (ret = __memp_fput(mpf, ip, pagep, file_dbp->priority)) != 0) + goto out; + + pagep = NULL; + if (meta != NULL && + (ret = __memp_fput(mpf, ip, meta, file_dbp->priority)) != 0) + goto out; + meta = NULL; + + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, file_dbp->priority); + if (meta != NULL) + (void)__memp_fput(mpf, ip, meta, file_dbp->priority); + + return (ret); +} + +/* + * __db_pg_free_42_recover -- + * Recovery function for pg_free. + * + * PUBLIC: int __db_pg_free_42_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_free_42_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_free_42_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + int ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__db_pg_free_42_print); + REC_INTRO(__db_pg_free_42_read, ip, 0); + + ret = __db_pg_free_recover_42_int(env, ip, + (__db_pg_freedata_42_args *)argp, file_dbp, lsnp, mpf, op, 0); + +done: *lsnp = argp->prev_lsn; +out: + REC_CLOSE; +} + +/* + * __db_pg_freedata_42_recover -- + * Recovery function for pg_freedata. + * + * PUBLIC: int __db_pg_freedata_42_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_freedata_42_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_freedata_42_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + int ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + REC_PRINT(__db_pg_freedata_42_print); + REC_INTRO(__db_pg_freedata_42_read, ip, 0); + + ret = __db_pg_free_recover_42_int( + env, ip, argp, file_dbp, lsnp, mpf, op, 1); + +done: *lsnp = argp->prev_lsn; +out: + REC_CLOSE; +} + +/* + * __db_relink_42_recover -- + * Recovery function for relink. + * + * PUBLIC: int __db_relink_42_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_relink_42_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_relink_42_args *argp; + DB_THREAD_INFO *ip; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + pagep = NULL; + REC_PRINT(__db_relink_42_print); + REC_INTRO(__db_relink_42_read, ip, 0); + + /* + * There are up to three pages we need to check -- the page, and the + * previous and next pages, if they existed. For a page add operation, + * the current page is the result of a split and is being recovered + * elsewhere, so all we need do is recover the next page. + */ + if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { + if (DB_REDO(op)) { + ret = __db_pgerr(file_dbp, argp->pgno, ret); + goto out; + } + goto next2; + } + if (argp->opcode == DB_ADD_PAGE_COMPAT) + goto next1; + + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn); + if (cmp_p == 0 && DB_REDO(op)) { + /* Redo the relink. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->lsn = *lsnp; + } else if (LOG_COMPARE(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) { + /* Undo the relink. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->next_pgno = argp->next; + pagep->prev_pgno = argp->prev; + pagep->lsn = argp->lsn; + } +next1: if ((ret = __memp_fput(mpf, ip, pagep, file_dbp->priority)) != 0) + goto out; + pagep = NULL; + +next2: if ((ret = __memp_fget(mpf, &argp->next, ip, NULL, 0, &pagep)) != 0) { + if (DB_REDO(op)) { + ret = __db_pgerr(file_dbp, argp->next, ret); + goto out; + } + goto prev; + } + modified = 0; + cmp_n = LOG_COMPARE(lsnp, &LSN(pagep)); + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn_next); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn_next); + if ((argp->opcode == DB_REM_PAGE_COMPAT && cmp_p == 0 && DB_REDO(op)) || + (argp->opcode == DB_ADD_PAGE_COMPAT && cmp_n == 0 && DB_UNDO(op))) { + /* Redo the remove or undo the add. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->prev_pgno = argp->prev; + modified = 1; + } else if ((argp->opcode == DB_REM_PAGE_COMPAT && + cmp_n == 0 && DB_UNDO(op)) || + (argp->opcode == DB_ADD_PAGE_COMPAT && cmp_p == 0 && DB_REDO(op))) { + /* Undo the remove or redo the add. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->prev_pgno = argp->pgno; + modified = 1; + } + if (modified) { + if (DB_UNDO(op)) + pagep->lsn = argp->lsn_next; + else + pagep->lsn = *lsnp; + } + if ((ret = __memp_fput(mpf, ip, pagep, file_dbp->priority)) != 0) + goto out; + pagep = NULL; + if (argp->opcode == DB_ADD_PAGE_COMPAT) + goto done; + +prev: if ((ret = __memp_fget(mpf, &argp->prev, ip, NULL, 0, &pagep)) != 0) { + if (DB_REDO(op)) { + ret = __db_pgerr(file_dbp, argp->prev, ret); + goto out; + } + goto done; + } + modified = 0; + cmp_p = LOG_COMPARE(&LSN(pagep), &argp->lsn_prev); + CHECK_LSN(env, op, cmp_p, &LSN(pagep), &argp->lsn_prev); + if (cmp_p == 0 && DB_REDO(op)) { + /* Redo the relink. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->next_pgno = argp->next; + modified = 1; + } else if (LOG_COMPARE(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) { + /* Undo the relink. */ + REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); + pagep->next_pgno = argp->pgno; + modified = 1; + } + if (modified) { + if (DB_UNDO(op)) + pagep->lsn = argp->lsn_prev; + else + pagep->lsn = *lsnp; + } + if ((ret = __memp_fput(mpf, ip, pagep, file_dbp->priority)) != 0) + goto out; + pagep = NULL; + +done: *lsnp = argp->prev_lsn; + ret = 0; + +out: if (pagep != NULL) + (void)__memp_fput(mpf, ip, pagep, file_dbp->priority); + REC_CLOSE; +} diff --git a/src/libs/resiprocate/contrib/db/db/db_reclaim.c b/src/libs/resiprocate/contrib/db/db/db_reclaim.c new file mode 100644 index 00000000..a44d0543 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_reclaim.c @@ -0,0 +1,246 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/mp.h" + +/* + * __db_traverse_big + * Traverse a chain of overflow pages and call the callback routine + * on each one. The calling convention for the callback is: + * callback(dbc, page, cookie, did_put), + * where did_put is a return value indicating if the page in question has + * already been returned to the mpool. + * + * PUBLIC: int __db_traverse_big __P((DBC *, db_pgno_t, + * PUBLIC: int (*)(DBC *, PAGE *, void *, int *), void *)); + */ +int +__db_traverse_big(dbc, pgno, callback, cookie) + DBC *dbc; + db_pgno_t pgno; + int (*callback) __P((DBC *, PAGE *, void *, int *)); + void *cookie; +{ + DB_MPOOLFILE *mpf; + PAGE *p; + int did_put, ret; + + mpf = dbc->dbp->mpf; + + do { + did_put = 0; + if ((ret = __memp_fget(mpf, + &pgno, dbc->thread_info, dbc->txn, 0, &p)) != 0) + return (ret); + /* + * If we are freeing pages only process the overflow + * chain if the head of the chain has a refcount of 1. + */ + pgno = NEXT_PGNO(p); + if (callback == __db_truncate_callback && OV_REF(p) != 1) + pgno = PGNO_INVALID; + if ((ret = callback(dbc, p, cookie, &did_put)) == 0 && + !did_put) + ret = __memp_fput(mpf, + dbc->thread_info, p, dbc->priority); + } while (ret == 0 && pgno != PGNO_INVALID); + + return (ret); +} + +/* + * __db_reclaim_callback + * This is the callback routine used during a delete of a subdatabase. + * we are traversing a btree or hash table and trying to free all the + * pages. Since they share common code for duplicates and overflow + * items, we traverse them identically and use this routine to do the + * actual free. The reason that this is callback is because hash uses + * the same traversal code for statistics gathering. + * + * PUBLIC: int __db_reclaim_callback __P((DBC *, PAGE *, void *, int *)); + */ +int +__db_reclaim_callback(dbc, p, cookie, putp) + DBC *dbc; + PAGE *p; + void *cookie; + int *putp; +{ + DB *dbp; + int ret; + + COMPQUIET(cookie, NULL); + dbp = dbc->dbp; + + /* + * We don't want to log the free of the root with the subdb. + * If we abort then the subdb may not be openable to undo + * the free. + */ + if ((dbp->type == DB_BTREE || dbp->type == DB_RECNO) && + PGNO(p) == ((BTREE *)dbp->bt_internal)->bt_root) + return (0); + if ((ret = __db_free(dbc, p)) != 0) + return (ret); + *putp = 1; + + return (0); +} + +/* + * __db_truncate_callback + * This is the callback routine used during a truncate. + * we are traversing a btree or hash table and trying to free all the + * pages. + * + * PUBLIC: int __db_truncate_callback __P((DBC *, PAGE *, void *, int *)); + */ +int +__db_truncate_callback(dbc, p, cookie, putp) + DBC *dbc; + PAGE *p; + void *cookie; + int *putp; +{ + DB *dbp; + DBT ddbt, ldbt; + DB_MPOOLFILE *mpf; + db_indx_t indx, len, off, tlen, top; + u_int8_t *hk, type; + u_int32_t *countp; + int ret; + + top = NUM_ENT(p); + dbp = dbc->dbp; + mpf = dbp->mpf; + countp = cookie; + *putp = 1; + + switch (TYPE(p)) { + case P_LBTREE: + /* Skip for off-page duplicates and deleted items. */ + for (indx = 0; indx < top; indx += P_INDX) { + type = GET_BKEYDATA(dbp, p, indx + O_INDX)->type; + if (!B_DISSET(type) && B_TYPE(type) != B_DUPLICATE) + ++*countp; + } + /* FALLTHROUGH */ + case P_IBTREE: + case P_IRECNO: + case P_INVALID: + if (dbp->type != DB_HASH && + ((BTREE *)dbp->bt_internal)->bt_root == PGNO(p)) { + type = dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE; + goto reinit; + } + break; + case P_OVERFLOW: + if ((ret = __memp_dirty(mpf, + &p, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + return (ret); + if (DBC_LOGGING(dbc)) { + if ((ret = __db_ovref_log(dbp, dbc->txn, + &LSN(p), 0, p->pgno, -1, &LSN(p))) != 0) + return (ret); + } else + LSN_NOT_LOGGED(LSN(p)); + if (--OV_REF(p) != 0) + *putp = 0; + break; + case P_LRECNO: + for (indx = 0; indx < top; indx += O_INDX) { + type = GET_BKEYDATA(dbp, p, indx)->type; + if (!B_DISSET(type)) + ++*countp; + } + + if (((BTREE *)dbp->bt_internal)->bt_root == PGNO(p)) { + type = P_LRECNO; + goto reinit; + } + break; + case P_LDUP: + /* Correct for deleted items. */ + for (indx = 0; indx < top; indx += O_INDX) + if (!B_DISSET(GET_BKEYDATA(dbp, p, indx)->type)) + ++*countp; + + break; + case P_HASH: + /* Correct for on-page duplicates and deleted items. */ + for (indx = 0; indx < top; indx += P_INDX) { + switch (*H_PAIRDATA(dbp, p, indx)) { + case H_OFFDUP: + break; + case H_OFFPAGE: + case H_KEYDATA: + ++*countp; + break; + case H_DUPLICATE: + tlen = LEN_HDATA(dbp, p, 0, indx); + hk = H_PAIRDATA(dbp, p, indx); + for (off = 0; off < tlen; + off += len + 2 * sizeof(db_indx_t)) { + ++*countp; + memcpy(&len, + HKEYDATA_DATA(hk) + + off, sizeof(db_indx_t)); + } + break; + default: + return (__db_pgfmt(dbp->env, p->pgno)); + } + } + /* Don't free the head of the bucket. */ + if (PREV_PGNO(p) == PGNO_INVALID) { + type = P_HASH; + +reinit: if ((ret = __memp_dirty(mpf, &p, + dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + return (ret); + *putp = 0; + if (DBC_LOGGING(dbc)) { + memset(&ldbt, 0, sizeof(ldbt)); + memset(&ddbt, 0, sizeof(ddbt)); + ldbt.data = p; + ldbt.size = P_OVERHEAD(dbp); + ldbt.size += p->entries * sizeof(db_indx_t); + ddbt.data = (u_int8_t *)p + HOFFSET(p); + ddbt.size = dbp->pgsize - HOFFSET(p); + if ((ret = __db_pg_init_log(dbp, + dbc->txn, &LSN(p), 0, + p->pgno, &ldbt, &ddbt)) != 0) + return (ret); + } else + LSN_NOT_LOGGED(LSN(p)); + + P_INIT(p, dbp->pgsize, PGNO(p), PGNO_INVALID, + PGNO_INVALID, type == P_HASH ? 0 : 1, type); + } + break; + default: + return (__db_pgfmt(dbp->env, p->pgno)); + } + + if (*putp == 1) { + if ((ret = __db_free(dbc, p)) != 0) + return (ret); + } else { + if ((ret = __memp_fput(mpf, dbc->thread_info, p, + dbc->priority)) != 0) + return (ret); + *putp = 1; + } + + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_remove.c b/src/libs/resiprocate/contrib/db/db/db_remove.c new file mode 100644 index 00000000..6b59ec37 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_remove.c @@ -0,0 +1,492 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2001, 2010 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/fop.h" +#include "dbinc/btree.h" +#include "dbinc/hash.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" +#include "dbinc/txn.h" + +static int __db_dbtxn_remove __P((DB *, + DB_THREAD_INFO *, DB_TXN *, const char *, const char *)); +static int __db_subdb_remove __P((DB *, + DB_THREAD_INFO *, DB_TXN *, const char *, const char *)); + +/* + * __env_dbremove_pp + * ENV->dbremove pre/post processing. + * + * PUBLIC: int __env_dbremove_pp __P((DB_ENV *, + * PUBLIC: DB_TXN *, const char *, const char *, u_int32_t)); + */ +int +__env_dbremove_pp(dbenv, txn, name, subdb, flags) + DB_ENV *dbenv; + DB_TXN *txn; + const char *name, *subdb; + u_int32_t flags; +{ + DB *dbp; + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret, txn_local; + + dbp = NULL; + env = dbenv->env; + txn_local = 0; + + ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->dbremove"); + + /* + * The actual argument checking is simple, do it inline, outside of + * the replication block. + */ + if ((ret = __db_fchk(env, + "DB->remove", flags, DB_AUTO_COMMIT | DB_TXN_NOT_DURABLE)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (ret = __env_rep_enter(env, 1)) != 0) { + handle_check = 0; + goto err; + } + + /* + * Create local transaction as necessary, check for consistent + * transaction usage. + */ + if (IS_ENV_AUTO_COMMIT(env, txn, flags)) { + if ((ret = __db_txn_auto_init(env, ip, &txn)) != 0) + goto err; + txn_local = 1; + } else + if (txn != NULL && !TXN_ON(env) && + (!CDB_LOCKING(env) || !F_ISSET(txn, TXN_CDSGROUP))) { + ret = __db_not_txn_env(env); + goto err; + } + LF_CLR(DB_AUTO_COMMIT); + + if ((ret = __db_create_internal(&dbp, env, 0)) != 0) + goto err; + if (LF_ISSET(DB_TXN_NOT_DURABLE) && + (ret = __db_set_flags(dbp, DB_TXN_NOT_DURABLE)) != 0) + goto err; + LF_CLR(DB_TXN_NOT_DURABLE); + + ret = __db_remove_int(dbp, ip, txn, name, subdb, flags); + + if (txn_local) { + /* + * We created the DBP here and when we commit/abort, we'll + * release all the transactional locks, including the handle + * lock; mark the handle cleared explicitly. + */ + LOCK_INIT(dbp->handle_lock); + dbp->locker = NULL; + } else if (txn != NULL) { + /* + * We created this handle locally so we need to close it + * and clean it up. Unfortunately, it's holding transactional + * locks that need to persist until the end of transaction. + * If we invalidate the locker id (dbp->locker), then the close + * won't free these locks prematurely. + */ + dbp->locker = NULL; + } + +err: if (txn_local && (t_ret = + __db_txn_auto_resolve(env, txn, 0, ret)) != 0 && ret == 0) + ret = t_ret; + + /* + * We never opened this dbp for real, so don't include a transaction + * handle, and use NOSYNC to avoid calling into mpool. + * + * !!! + * Note we're reversing the order of operations: we started the txn and + * then opened the DB handle; we're resolving the txn and then closing + * closing the DB handle -- a DB handle cannot be closed before + * resolving the txn. + */ + if (dbp != NULL && + (t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0) + ret = t_ret; + + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_remove_pp + * DB->remove pre/post processing. + * + * PUBLIC: int __db_remove_pp + * PUBLIC: __P((DB *, const char *, const char *, u_int32_t)); + */ +int +__db_remove_pp(dbp, name, subdb, flags) + DB *dbp; + const char *name, *subdb; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = dbp->env; + + /* + * Validate arguments, continuing to destroy the handle on failure. + * + * Cannot use DB_ILLEGAL_AFTER_OPEN directly because it returns. + * + * !!! + * We have a serious problem if we're here with a handle used to open + * a database -- we'll destroy the handle, and the application won't + * ever be able to close the database. + */ + if (F_ISSET(dbp, DB_AM_OPEN_CALLED)) + return (__db_mi_open(env, "DB->remove", 1)); + + /* Validate arguments. */ + if ((ret = __db_fchk(env, "DB->remove", flags, 0)) != 0) + return (ret); + + /* Check for consistent transaction usage. */ + if ((ret = __db_check_txn(dbp, NULL, DB_LOCK_INVALIDID, 0)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (ret = __db_rep_enter(dbp, 1, 1, 0)) != 0) { + handle_check = 0; + goto err; + } + + /* Remove the file. */ + ret = __db_remove(dbp, ip, NULL, name, subdb, flags); + + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + +err: ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_remove + * DB->remove method. + * + * PUBLIC: int __db_remove __P((DB *, DB_THREAD_INFO *, + * PUBLIC: DB_TXN *, const char *, const char *, u_int32_t)); + */ +int +__db_remove(dbp, ip, txn, name, subdb, flags) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + const char *name, *subdb; + u_int32_t flags; +{ + int ret, t_ret; + + ret = __db_remove_int(dbp, ip, txn, name, subdb, flags); + + if ((t_ret = __db_close(dbp, txn, DB_NOSYNC)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __db_remove_int + * Worker function for the DB->remove method. + * + * PUBLIC: int __db_remove_int __P((DB *, DB_THREAD_INFO *, + * PUBLIC: DB_TXN *, const char *, const char *, u_int32_t)); + */ +int +__db_remove_int(dbp, ip, txn, name, subdb, flags) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + const char *name, *subdb; + u_int32_t flags; +{ + ENV *env; + int ret; + char *real_name, *tmpname; + + env = dbp->env; + real_name = tmpname = NULL; + + if (name == NULL && subdb == NULL) { + __db_errx(env, "Remove on temporary files invalid"); + ret = EINVAL; + goto err; + } + + if (name == NULL) { + MAKE_INMEM(dbp); + real_name = (char *)subdb; + } else if (subdb != NULL) { + ret = __db_subdb_remove(dbp, ip, txn, name, subdb); + goto err; + } + + /* Handle transactional file removes separately. */ + if (IS_REAL_TXN(txn)) { + ret = __db_dbtxn_remove(dbp, ip, txn, name, subdb); + goto err; + } + + /* + * The remaining case is a non-transactional file remove. + * + * Find the real name of the file. + */ + if (!F_ISSET(dbp, DB_AM_INMEM) && (ret = __db_appname(env, + DB_APP_DATA, name, &dbp->dirname, &real_name)) != 0) + goto err; + + /* + * If this is a file and force is set, remove the temporary file, which + * may have been left around. Ignore errors because the temporary file + * might not exist. + */ + if (!F_ISSET(dbp, DB_AM_INMEM) && LF_ISSET(DB_FORCE) && + (ret = __db_backup_name(env, real_name, NULL, &tmpname)) == 0) + (void)__os_unlink(env, tmpname, 0); + + if ((ret = __fop_remove_setup(dbp, NULL, real_name, 0)) != 0) + goto err; + + if (dbp->db_am_remove != NULL && + (ret = dbp->db_am_remove(dbp, ip, NULL, name, subdb, flags)) != 0) + goto err; + + ret = F_ISSET(dbp, DB_AM_INMEM) ? + __db_inmem_remove(dbp, NULL, real_name) : + __fop_remove(env, + NULL, dbp->fileid, name, &dbp->dirname, DB_APP_DATA, + F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0); + +err: if (!F_ISSET(dbp, DB_AM_INMEM) && real_name != NULL) + __os_free(env, real_name); + if (tmpname != NULL) + __os_free(env, tmpname); + + return (ret); +} + +/* + * __db_inmem_remove -- + * Removal of a named in-memory database. + * + * PUBLIC: int __db_inmem_remove __P((DB *, DB_TXN *, const char *)); + */ +int +__db_inmem_remove(dbp, txn, name) + DB *dbp; + DB_TXN *txn; + const char *name; +{ + DBT fid_dbt, name_dbt; + DB_LOCKER *locker; + DB_LSN lsn; + ENV *env; + int ret; + + env = dbp->env; + locker = NULL; + + DB_ASSERT(env, name != NULL); + + /* This had better exist if we are trying to do a remove. */ + (void)__memp_set_flags(dbp->mpf, DB_MPOOL_NOFILE, 1); + if ((ret = __memp_fopen(dbp->mpf, NULL, + name, &dbp->dirname, 0, 0, 0)) != 0) + return (ret); + if ((ret = __memp_get_fileid(dbp->mpf, dbp->fileid)) != 0) + return (ret); + dbp->preserve_fid = 1; + + if (LOCKING_ON(env)) { + if (dbp->locker == NULL && + (ret = __lock_id(env, NULL, &dbp->locker)) != 0) + return (ret); + locker = txn == NULL ? dbp->locker : txn->locker; + } + + /* + * In a transactional environment, we'll play the same game we play + * for databases in the file system -- create a temporary database + * and put it in with the current name and then rename this one to + * another name. We'll then use a commit-time event to remove the + * entry. + */ + if ((ret = + __fop_lock_handle(env, dbp, locker, DB_LOCK_WRITE, NULL, 0)) != 0) + return (ret); + + if (!IS_REAL_TXN(txn)) + ret = __memp_nameop(env, dbp->fileid, NULL, name, NULL, 1); + else if (LOGGING_ON(env)) { + if (txn != NULL && (ret = + __txn_remevent(env, txn, name, dbp->fileid, 1)) != 0) + return (ret); + + DB_INIT_DBT(name_dbt, name, strlen(name) + 1); + DB_INIT_DBT(fid_dbt, dbp->fileid, DB_FILE_ID_LEN); + ret = __crdel_inmem_remove_log( + env, txn, &lsn, 0, &name_dbt, &fid_dbt); + } + + return (ret); +} + +/* + * __db_subdb_remove -- + * Remove a subdatabase. + */ +static int +__db_subdb_remove(dbp, ip, txn, name, subdb) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + const char *name, *subdb; +{ + DB *mdbp, *sdbp; + int ret, t_ret; + + mdbp = sdbp = NULL; + + /* Open the subdatabase. */ + if ((ret = __db_create_internal(&sdbp, dbp->env, 0)) != 0) + goto err; + if (F_ISSET(dbp, DB_AM_NOT_DURABLE) && + (ret = __db_set_flags(sdbp, DB_TXN_NOT_DURABLE)) != 0) + goto err; + if ((ret = __db_open(sdbp, ip, + txn, name, subdb, DB_UNKNOWN, DB_WRITEOPEN, 0, PGNO_BASE_MD)) != 0) + goto err; + + DB_TEST_RECOVERY(sdbp, DB_TEST_PREDESTROY, ret, name); + + /* Free up the pages in the subdatabase. */ + switch (sdbp->type) { + case DB_BTREE: + case DB_RECNO: + if ((ret = __bam_reclaim(sdbp, ip, txn)) != 0) + goto err; + break; + case DB_HASH: + if ((ret = __ham_reclaim(sdbp, ip, txn)) != 0) + goto err; + break; + case DB_QUEUE: + case DB_UNKNOWN: + default: + ret = __db_unknown_type( + sdbp->env, "__db_subdb_remove", sdbp->type); + goto err; + } + + /* + * Remove the entry from the main database and free the subdatabase + * metadata page. + */ + if ((ret = __db_master_open(sdbp, ip, txn, name, 0, 0, &mdbp)) != 0) + goto err; + + if ((ret = __db_master_update(mdbp, + sdbp, ip, txn, subdb, sdbp->type, MU_REMOVE, NULL, 0)) != 0) + goto err; + + DB_TEST_RECOVERY(sdbp, DB_TEST_POSTDESTROY, ret, name); + +DB_TEST_RECOVERY_LABEL +err: + /* Close the main and subdatabases. */ + if ((t_ret = __db_close(sdbp, txn, DB_NOSYNC)) != 0 && ret == 0) + ret = t_ret; + + if (mdbp != NULL && + (t_ret = __db_close(mdbp, txn, DB_NOSYNC)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +static int +__db_dbtxn_remove(dbp, ip, txn, name, subdb) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + const char *name, *subdb; +{ + ENV *env; + int ret; + char *tmpname; + + env = dbp->env; + tmpname = NULL; + + /* + * This is a transactional remove, so we have to keep the name + * of the file locked until the transaction commits. As a result, + * we implement remove by renaming the file to some other name + * (which creates a dummy named file as a placeholder for the + * file being rename/dremoved) and then deleting that file as + * a delayed remove at commit. + */ + if ((ret = __db_backup_name(env, + F_ISSET(dbp, DB_AM_INMEM) ? subdb : name, txn, &tmpname)) != 0) + return (ret); + + DB_TEST_RECOVERY(dbp, DB_TEST_PREDESTROY, ret, name); + + if ((ret = __db_rename_int(dbp, + txn->thread_info, txn, name, subdb, tmpname)) != 0) + goto err; + + /* + * The internal removes will also translate into delayed removes. + */ + if (dbp->db_am_remove != NULL && + (ret = dbp->db_am_remove(dbp, ip, txn, tmpname, NULL, 0)) != 0) + goto err; + + ret = F_ISSET(dbp, DB_AM_INMEM) ? + __db_inmem_remove(dbp, txn, tmpname) : + __fop_remove(env, + txn, dbp->fileid, tmpname, &dbp->dirname, DB_APP_DATA, + F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0); + + DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, name); + +err: +DB_TEST_RECOVERY_LABEL + if (tmpname != NULL) + __os_free(env, tmpname); + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_rename.c b/src/libs/resiprocate/contrib/db/db/db_rename.c new file mode 100644 index 00000000..1fdf7216 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_rename.c @@ -0,0 +1,372 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2001, 2010 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/fop.h" +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/txn.h" + +static int __db_rename __P((DB *, DB_THREAD_INFO *, + DB_TXN *, const char *, const char *, const char *)); +static int __db_subdb_rename __P((DB *, DB_THREAD_INFO *, + DB_TXN *, const char *, const char *, const char *)); + +/* + * __env_dbrename_pp + * ENV->dbrename pre/post processing. + * + * PUBLIC: int __env_dbrename_pp __P((DB_ENV *, DB_TXN *, + * PUBLIC: const char *, const char *, const char *, u_int32_t)); + */ +int +__env_dbrename_pp(dbenv, txn, name, subdb, newname, flags) + DB_ENV *dbenv; + DB_TXN *txn; + const char *name, *subdb, *newname; + u_int32_t flags; +{ + DB *dbp; + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret, txn_local; + + env = dbenv->env; + dbp = NULL; + txn_local = 0; + + ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->dbrename"); + + /* + * The actual argument checking is simple, do it inline, outside of + * the replication block. + */ + if ((ret = __db_fchk(env, "DB->rename", flags, DB_AUTO_COMMIT)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (ret = __env_rep_enter(env, 1)) != 0) { + handle_check = 0; + goto err; + } + + /* + * Create local transaction as necessary, check for consistent + * transaction usage. + */ + if (IS_ENV_AUTO_COMMIT(env, txn, flags)) { + if ((ret = __db_txn_auto_init(env, ip, &txn)) != 0) + goto err; + txn_local = 1; + } else + if (txn != NULL && !TXN_ON(env) && + (!CDB_LOCKING(env) || !F_ISSET(txn, TXN_CDSGROUP))) { + ret = __db_not_txn_env(env); + goto err; + } + + LF_CLR(DB_AUTO_COMMIT); + + if ((ret = __db_create_internal(&dbp, env, 0)) != 0) + goto err; + + ret = __db_rename_int(dbp, ip, txn, name, subdb, newname); + + if (txn_local) { + /* + * We created the DBP here and when we commit/abort, we'll + * release all the transactional locks, including the handle + * lock; mark the handle cleared explicitly. + */ + LOCK_INIT(dbp->handle_lock); + dbp->locker = NULL; + } else if (txn != NULL) { + /* + * We created this handle locally so we need to close it and + * clean it up. Unfortunately, it's holding transactional + * or CDS group locks that need to persist until the end of + * transaction. If we invalidate the locker (dbp->locker), + * then the close won't free these locks prematurely. + */ + dbp->locker = NULL; + } + +err: if (txn_local && (t_ret = + __db_txn_auto_resolve(env, txn, 0, ret)) != 0 && ret == 0) + ret = t_ret; + + /* + * We never opened this dbp for real, so don't include a transaction + * handle, and use NOSYNC to avoid calling into mpool. + * + * !!! + * Note we're reversing the order of operations: we started the txn and + * then opened the DB handle; we're resolving the txn and then closing + * closing the DB handle -- it's safer. + */ + if (dbp != NULL && + (t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0) + ret = t_ret; + + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_rename_pp + * DB->rename pre/post processing. + * + * PUBLIC: int __db_rename_pp __P((DB *, + * PUBLIC: const char *, const char *, const char *, u_int32_t)); + */ +int +__db_rename_pp(dbp, name, subdb, newname, flags) + DB *dbp; + const char *name, *subdb, *newname; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = dbp->env; + handle_check = 0; + + /* + * Validate arguments, continuing to destroy the handle on failure. + * + * Cannot use DB_ILLEGAL_AFTER_OPEN directly because it returns. + * + * !!! + * We have a serious problem if we're here with a handle used to open + * a database -- we'll destroy the handle, and the application won't + * ever be able to close the database. + */ + if (F_ISSET(dbp, DB_AM_OPEN_CALLED)) + return (__db_mi_open(env, "DB->rename", 1)); + + /* Validate arguments. */ + if ((ret = __db_fchk(env, "DB->rename", flags, 0)) != 0) + return (ret); + + /* Check for consistent transaction usage. */ + if ((ret = __db_check_txn(dbp, NULL, DB_LOCK_INVALIDID, 0)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (ret = __db_rep_enter(dbp, 1, 1, 0)) != 0) { + handle_check = 0; + goto err; + } + + /* Rename the file. */ + ret = __db_rename(dbp, ip, NULL, name, subdb, newname); + + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; +err: ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_rename + * DB->rename method. + * + */ +static int +__db_rename(dbp, ip, txn, name, subdb, newname) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + const char *name, *subdb, *newname; +{ + int ret, t_ret; + + ret = __db_rename_int(dbp, ip, txn, name, subdb, newname); + + if ((t_ret = __db_close(dbp, txn, DB_NOSYNC)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __db_rename_int + * Worker function for DB->rename method; the close of the dbp is + * left in the wrapper routine. + * + * PUBLIC: int __db_rename_int __P((DB *, DB_THREAD_INFO *, + * PUBLIC: DB_TXN *, const char *, const char *, const char *)); + */ +int +__db_rename_int(dbp, ip, txn, name, subdb, newname) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + const char *name, *subdb, *newname; +{ + ENV *env; + int ret; + char *old, *real_name; + + env = dbp->env; + real_name = NULL; + + DB_TEST_RECOVERY(dbp, DB_TEST_PREDESTROY, ret, name); + + if (name == NULL && subdb == NULL) { + __db_errx(env, "Rename on temporary files invalid"); + ret = EINVAL; + goto err; + } + + if (name == NULL) + MAKE_INMEM(dbp); + else if (subdb != NULL) { + ret = __db_subdb_rename(dbp, ip, txn, name, subdb, newname); + goto err; + } + + /* + * From here on down, this pertains to files or in-memory databases. + * + * Find the real name of the file. + */ + if (F_ISSET(dbp, DB_AM_INMEM)) { + old = (char *)subdb; + real_name = (char *)subdb; + } else { + if ((ret = __db_appname(env, DB_APP_DATA, + name, &dbp->dirname, &real_name)) != 0) + goto err; + old = (char *)name; + } + DB_ASSERT(env, old != NULL); + + if ((ret = __fop_remove_setup(dbp, txn, real_name, 0)) != 0) + goto err; + + if (dbp->db_am_rename != NULL && + (ret = dbp->db_am_rename(dbp, ip, txn, name, subdb, newname)) != 0) + goto err; + + /* + * The transactional case and non-transactional case are + * quite different. In the non-transactional case, we simply + * do the rename. In the transactional case, since we need + * the ability to back out and maintain locking, we have to + * create a temporary object as a placeholder. This is all + * taken care of in the fop layer. + */ + if (IS_REAL_TXN(txn)) { + if ((ret = __fop_dummy(dbp, txn, old, newname)) != 0) + goto err; + } else { + if ((ret = __fop_dbrename(dbp, old, newname)) != 0) + goto err; + } + + /* + * I am pretty sure that we haven't gotten a dbreg id, so calling + * dbreg_filelist_update is not necessary. + */ + DB_ASSERT(env, dbp->log_filename == NULL || + dbp->log_filename->id == DB_LOGFILEID_INVALID); + + DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, newname); + +DB_TEST_RECOVERY_LABEL +err: if (!F_ISSET(dbp, DB_AM_INMEM) && real_name != NULL) + __os_free(env, real_name); + + return (ret); +} + +/* + * __db_subdb_rename -- + * Rename a subdatabase. + */ +static int +__db_subdb_rename(dbp, ip, txn, name, subdb, newname) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + const char *name, *subdb, *newname; +{ + DB *mdbp; + ENV *env; + PAGE *meta; + int ret, t_ret; + + mdbp = NULL; + meta = NULL; + env = dbp->env; + + /* + * We have not opened this dbp so it isn't marked as a subdb, + * but it ought to be. + */ + F_SET(dbp, DB_AM_SUBDB); + + /* + * Rename the entry in the main database. We need to first + * get the meta-data page number (via MU_OPEN) so that we can + * read the meta-data page and obtain a handle lock. Once we've + * done that, we can proceed to do the rename in the master. + */ + if ((ret = __db_master_open(dbp, ip, txn, name, 0, 0, &mdbp)) != 0) + goto err; + + if ((ret = __db_master_update(mdbp, dbp, ip, txn, subdb, dbp->type, + MU_OPEN, NULL, 0)) != 0) + goto err; + + if ((ret = __memp_fget(mdbp->mpf, &dbp->meta_pgno, + ip, txn, 0, &meta)) != 0) + goto err; + memcpy(dbp->fileid, ((DBMETA *)meta)->uid, DB_FILE_ID_LEN); + if ((ret = __fop_lock_handle(env, + dbp, mdbp->locker, DB_LOCK_WRITE, NULL, NOWAIT_FLAG(txn))) != 0) + goto err; + + ret = __memp_fput(mdbp->mpf, ip, meta, dbp->priority); + meta = NULL; + if (ret != 0) + goto err; + + if ((ret = __db_master_update(mdbp, dbp, ip, txn, + subdb, dbp->type, MU_RENAME, newname, 0)) != 0) + goto err; + + DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, name); + +DB_TEST_RECOVERY_LABEL +err: + if (meta != NULL && (t_ret = + __memp_fput(mdbp->mpf, ip, meta, dbp->priority)) != 0 && ret == 0) + ret = t_ret; + + if (mdbp != NULL && + (t_ret = __db_close(mdbp, txn, DB_NOSYNC)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_ret.c b/src/libs/resiprocate/contrib/db/db/db_ret.c new file mode 100644 index 00000000..5ff60d12 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_ret.c @@ -0,0 +1,156 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" + +/* + * __db_ret -- + * Build return DBT. + * + * PUBLIC: int __db_ret __P((DBC *, + * PUBLIC: PAGE *, u_int32_t, DBT *, void **, u_int32_t *)); + */ +int +__db_ret(dbc, h, indx, dbt, memp, memsize) + DBC *dbc; + PAGE *h; + u_int32_t indx; + DBT *dbt; + void **memp; + u_int32_t *memsize; +{ + BKEYDATA *bk; + BOVERFLOW *bo; + DB *dbp; + HOFFPAGE ho; + u_int32_t len; + u_int8_t *hk; + void *data; + + dbp = dbc->dbp; + + switch (TYPE(h)) { + case P_HASH_UNSORTED: + case P_HASH: + hk = P_ENTRY(dbp, h, indx); + if (HPAGE_PTYPE(hk) == H_OFFPAGE) { + memcpy(&ho, hk, sizeof(HOFFPAGE)); + return (__db_goff(dbc, dbt, + ho.tlen, ho.pgno, memp, memsize)); + } + len = LEN_HKEYDATA(dbp, h, dbp->pgsize, indx); + data = HKEYDATA_DATA(hk); + break; + case P_LBTREE: + case P_LDUP: + case P_LRECNO: + bk = GET_BKEYDATA(dbp, h, indx); + if (B_TYPE(bk->type) == B_OVERFLOW) { + bo = (BOVERFLOW *)bk; + return (__db_goff(dbc, dbt, + bo->tlen, bo->pgno, memp, memsize)); + } + len = bk->len; + data = bk->data; + break; + default: + return (__db_pgfmt(dbp->env, h->pgno)); + } + + return (__db_retcopy(dbp->env, dbt, data, len, memp, memsize)); +} + +/* + * __db_retcopy -- + * Copy the returned data into the user's DBT, handling special flags. + * + * PUBLIC: int __db_retcopy __P((ENV *, DBT *, + * PUBLIC: void *, u_int32_t, void **, u_int32_t *)); + */ +int +__db_retcopy(env, dbt, data, len, memp, memsize) + ENV *env; + DBT *dbt; + void *data; + u_int32_t len; + void **memp; + u_int32_t *memsize; +{ + int ret; + + ret = 0; + + /* If returning a partial record, reset the length. */ + if (F_ISSET(dbt, DB_DBT_PARTIAL)) { + data = (u_int8_t *)data + dbt->doff; + if (len > dbt->doff) { + len -= dbt->doff; + if (len > dbt->dlen) + len = dbt->dlen; + } else + len = 0; + } + + /* + * Allocate memory to be owned by the application: DB_DBT_MALLOC, + * DB_DBT_REALLOC. + * + * !!! + * We always allocate memory, even if we're copying out 0 bytes. This + * guarantees consistency, i.e., the application can always free memory + * without concern as to how many bytes of the record were requested. + * + * Use the memory specified by the application: DB_DBT_USERMEM. + * + * !!! + * If the length we're going to copy is 0, the application-supplied + * memory pointer is allowed to be NULL. + */ + if (F_ISSET(dbt, DB_DBT_USERCOPY)) { + dbt->size = len; + return (len == 0 ? 0 : env->dbt_usercopy(dbt, 0, data, + len, DB_USERCOPY_SETDATA)); + + } else if (F_ISSET(dbt, DB_DBT_MALLOC)) + ret = __os_umalloc(env, len, &dbt->data); + else if (F_ISSET(dbt, DB_DBT_REALLOC)) { + if (dbt->data == NULL || dbt->size == 0 || dbt->size < len) + ret = __os_urealloc(env, len, &dbt->data); + } else if (F_ISSET(dbt, DB_DBT_USERMEM)) { + if (len != 0 && (dbt->data == NULL || dbt->ulen < len)) + ret = DB_BUFFER_SMALL; + } else if (memp == NULL || memsize == NULL) + ret = EINVAL; + else { + if (len != 0 && (*memsize == 0 || *memsize < len)) { + if ((ret = __os_realloc(env, len, memp)) == 0) + *memsize = len; + else + *memsize = 0; + } + if (ret == 0) + dbt->data = *memp; + } + + if (ret == 0 && len != 0) + memcpy(dbt->data, data, len); + + /* + * Return the length of the returned record in the DBT size field. + * This satisfies the requirement that if we're using user memory + * and insufficient memory was provided, return the amount necessary + * in the size field. + */ + dbt->size = len; + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_setid.c b/src/libs/resiprocate/contrib/db/db/db_setid.c new file mode 100644 index 00000000..a78977e3 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_setid.c @@ -0,0 +1,213 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_swap.h" +#include "dbinc/db_am.h" +#include "dbinc/mp.h" + +/* + * __env_fileid_reset_pp -- + * ENV->fileid_reset pre/post processing. + * + * PUBLIC: int __env_fileid_reset_pp __P((DB_ENV *, const char *, u_int32_t)); + */ +int +__env_fileid_reset_pp(dbenv, name, flags) + DB_ENV *dbenv; + const char *name; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int ret; + + env = dbenv->env; + + ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->fileid_reset"); + + /* + * !!! + * The actual argument checking is simple, do it inline, outside of + * the replication block. + */ + if (flags != 0 && flags != DB_ENCRYPT) + return (__db_ferr(env, "DB_ENV->fileid_reset", 0)); + + ENV_ENTER(env, ip); + REPLICATION_WRAP(env, + (__env_fileid_reset(env, ip, name, LF_ISSET(DB_ENCRYPT) ? 1 : 0)), + 1, ret); + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __env_fileid_reset -- + * Reset the file IDs for every database in the file. + * PUBLIC: int __env_fileid_reset + * PUBLIC: __P((ENV *, DB_THREAD_INFO *, const char *, int)); + */ +int +__env_fileid_reset(env, ip, name, encrypted) + ENV *env; + DB_THREAD_INFO *ip; + const char *name; + int encrypted; +{ + DB *dbp; + DBC *dbcp; + DBMETA *meta; + DBT key, data; + DB_FH *fhp; + DB_MPOOLFILE *mpf; + DB_PGINFO cookie; + db_pgno_t pgno; + int t_ret, ret; + size_t n; + char *real_name; + u_int8_t fileid[DB_FILE_ID_LEN], mbuf[DBMETASIZE]; + void *pagep; + + dbp = NULL; + dbcp = NULL; + fhp = NULL; + real_name = NULL; + + /* Get the real backing file name. */ + if ((ret = __db_appname(env, + DB_APP_DATA, name, NULL, &real_name)) != 0) + return (ret); + + /* Get a new file ID. */ + if ((ret = __os_fileid(env, real_name, 1, fileid)) != 0) + goto err; + + /* + * The user may have physically copied a file currently open in the + * cache, which means if we open this file through the cache before + * updating the file ID on page 0, we might connect to the file from + * which the copy was made. + */ + if ((ret = __os_open(env, real_name, 0, 0, 0, &fhp)) != 0) { + __db_err(env, ret, "%s", real_name); + goto err; + } + if ((ret = __os_read(env, fhp, mbuf, sizeof(mbuf), &n)) != 0) + goto err; + + if (n != sizeof(mbuf)) { + ret = EINVAL; + __db_errx(env, + "__env_fileid_reset: %s: unexpected file type or format", + real_name); + goto err; + } + + /* + * Create the DB object. + */ + if ((ret = __db_create_internal(&dbp, env, 0)) != 0) + goto err; + + /* If configured with a password, the databases are encrypted. */ + if (encrypted && (ret = __db_set_flags(dbp, DB_ENCRYPT)) != 0) + goto err; + + if ((ret = __db_meta_setup(env, + dbp, real_name, (DBMETA *)mbuf, 0, DB_CHK_META)) != 0) + goto err; + + meta = (DBMETA *)mbuf; + if (FLD_ISSET(meta->metaflags, + DBMETA_PART_RANGE | DBMETA_PART_CALLBACK) && (ret = + __part_fileid_reset(env, ip, name, meta->nparts, encrypted)) != 0) + goto err; + + memcpy(meta->uid, fileid, DB_FILE_ID_LEN); + cookie.db_pagesize = sizeof(mbuf); + cookie.flags = dbp->flags; + cookie.type = dbp->type; + key.data = &cookie; + + if ((ret = __db_pgout(env->dbenv, 0, mbuf, &key)) != 0) + goto err; + if ((ret = __os_seek(env, fhp, 0, 0, 0)) != 0) + goto err; + if ((ret = __os_write(env, fhp, mbuf, sizeof(mbuf), &n)) != 0) + goto err; + if ((ret = __os_fsync(env, fhp)) != 0) + goto err; + + /* + * Page 0 of the file has an updated file ID, and we can open it in + * the cache without connecting to a different, existing file. Open + * the file in the cache, and update the file IDs for subdatabases. + * (No existing code, as far as I know, actually uses the file ID of + * a subdatabase, but it's cleaner to get them all.) + */ + + /* + * If the database file doesn't support subdatabases, we only have + * to update a single metadata page. Otherwise, we have to open a + * cursor and step through the master database, and update all of + * the subdatabases' metadata pages. + */ + if (meta->type != P_BTREEMETA || !F_ISSET(meta, BTM_SUBDB)) + goto err; + + /* + * Open the DB file. + * + * !!! + * Note DB_RDWRMASTER flag, we need to open the master database file + * for writing in this case. + */ + if ((ret = __db_open(dbp, ip, NULL, + name, NULL, DB_UNKNOWN, DB_RDWRMASTER, 0, PGNO_BASE_MD)) != 0) + goto err; + + mpf = dbp->mpf; + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + if ((ret = __db_cursor(dbp, ip, NULL, &dbcp, 0)) != 0) + goto err; + while ((ret = __dbc_get(dbcp, &key, &data, DB_NEXT)) == 0) { + /* + * XXX + * We're handling actual data, not on-page meta-data, so it + * hasn't been converted to/from opposite endian architectures. + * Do it explicitly, now. + */ + memcpy(&pgno, data.data, sizeof(db_pgno_t)); + DB_NTOHL_SWAP(env, &pgno); + if ((ret = __memp_fget(mpf, &pgno, ip, NULL, + DB_MPOOL_DIRTY, &pagep)) != 0) + goto err; + memcpy(((DBMETA *)pagep)->uid, fileid, DB_FILE_ID_LEN); + if ((ret = __memp_fput(mpf, ip, pagep, dbcp->priority)) != 0) + goto err; + } + if (ret == DB_NOTFOUND) + ret = 0; + +err: if (dbcp != NULL && (t_ret = __dbc_close(dbcp)) != 0 && ret == 0) + ret = t_ret; + if (dbp != NULL && (t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0) + ret = t_ret; + if (fhp != NULL && + (t_ret = __os_closehandle(env, fhp)) != 0 && ret == 0) + ret = t_ret; + if (real_name != NULL) + __os_free(env, real_name); + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_setlsn.c b/src/libs/resiprocate/contrib/db/db/db_setlsn.c new file mode 100644 index 00000000..51ee7d3f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_setlsn.c @@ -0,0 +1,137 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/mp.h" +#include "dbinc/partition.h" +#include "dbinc/qam.h" + +static int __env_lsn_reset __P((ENV *, DB_THREAD_INFO *, const char *, int)); + +/* + * __env_lsn_reset_pp -- + * ENV->lsn_reset pre/post processing. + * + * PUBLIC: int __env_lsn_reset_pp __P((DB_ENV *, const char *, u_int32_t)); + */ +int +__env_lsn_reset_pp(dbenv, name, flags) + DB_ENV *dbenv; + const char *name; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int ret; + + env = dbenv->env; + + ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->lsn_reset"); + + /* + * !!! + * The actual argument checking is simple, do it inline, outside of + * the replication block. + */ + if (flags != 0 && flags != DB_ENCRYPT) + return (__db_ferr(env, "DB_ENV->lsn_reset", 0)); + + ENV_ENTER(env, ip); + REPLICATION_WRAP(env, + (__env_lsn_reset(env, ip, name, LF_ISSET(DB_ENCRYPT) ? 1 : 0)), + 1, ret); + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __env_lsn_reset -- + * Reset the LSNs for every page in the file. + */ +static int +__env_lsn_reset(env, ip, name, encrypted) + ENV *env; + DB_THREAD_INFO *ip; + const char *name; + int encrypted; +{ + DB *dbp; + int t_ret, ret; + + /* Create the DB object. */ + if ((ret = __db_create_internal(&dbp, env, 0)) != 0) + return (ret); + + /* If configured with a password, the databases are encrypted. */ + if (encrypted && (ret = __db_set_flags(dbp, DB_ENCRYPT)) != 0) + goto err; + + /* + * Open the DB file. + * + * !!! + * Note DB_RDWRMASTER flag, we need to open the master database file + * for writing in this case. + */ + if ((ret = __db_open(dbp, ip, NULL, + name, NULL, DB_UNKNOWN, DB_RDWRMASTER, 0, PGNO_BASE_MD)) != 0) { + __db_err(env, ret, "%s", name); + goto err; + } + + ret = __db_lsn_reset(dbp->mpf, ip); +#ifdef HAVE_PARTITION + if (ret == 0 && DB_IS_PARTITIONED(dbp)) + ret = __part_lsn_reset(dbp, ip); + else +#endif + if (ret == 0 && dbp->type == DB_QUEUE) +#ifdef HAVE_QUEUE + ret = __qam_lsn_reset(dbp, ip); +#else + ret = __db_no_queue_am(env); +#endif + +err: if ((t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +/* + * __db_lsn_reset -- reset the lsn for a db mpool handle. + * PUBLIC: int __db_lsn_reset __P((DB_MPOOLFILE *, DB_THREAD_INFO *)); + */ +int +__db_lsn_reset(mpf, ip) + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; +{ + PAGE *pagep; + db_pgno_t pgno; + int ret; + + /* Reset the LSN on every page of the database file. */ + for (pgno = 0; + (ret = __memp_fget(mpf, + &pgno, ip, NULL, DB_MPOOL_DIRTY, &pagep)) == 0; + ++pgno) { + LSN_NOT_LOGGED(pagep->lsn); + if ((ret = __memp_fput(mpf, + ip, pagep, DB_PRIORITY_UNCHANGED)) != 0) + break; + } + + if (ret == DB_PAGE_NOTFOUND) + ret = 0; + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_stati.c b/src/libs/resiprocate/contrib/db/db/db_stati.c new file mode 100644 index 00000000..b8d3a3fe --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_stati.c @@ -0,0 +1,494 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/hash.h" +#include "dbinc/qam.h" +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/partition.h" + +#ifdef HAVE_STATISTICS +static int __db_print_all __P((DB *, u_int32_t)); +static int __db_print_citem __P((DBC *)); +static int __db_print_cursor __P((DB *)); +static int __db_print_stats __P((DB *, DB_THREAD_INFO *, u_int32_t)); +static int __db_stat __P((DB *, DB_THREAD_INFO *, DB_TXN *, void *, u_int32_t)); +static int __db_stat_arg __P((DB *, u_int32_t)); + +/* + * __db_stat_pp -- + * DB->stat pre/post processing. + * + * PUBLIC: int __db_stat_pp __P((DB *, DB_TXN *, void *, u_int32_t)); + */ +int +__db_stat_pp(dbp, txn, spp, flags) + DB *dbp; + DB_TXN *txn; + void *spp; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = dbp->env; + + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->stat"); + + if ((ret = __db_stat_arg(dbp, flags)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, + txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + ret = __db_stat(dbp, ip, txn, spp, flags); + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + +err: ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_stat -- + * DB->stat. + * + */ +static int +__db_stat(dbp, ip, txn, spp, flags) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + void *spp; + u_int32_t flags; +{ + DBC *dbc; + ENV *env; + int ret, t_ret; + + env = dbp->env; + + /* Acquire a cursor. */ + if ((ret = __db_cursor(dbp, ip, txn, + &dbc, LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED))) != 0) + return (ret); + + DEBUG_LWRITE(dbc, NULL, "DB->stat", NULL, NULL, flags); + LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED); +#ifdef HAVE_PARTITION + if (DB_IS_PARTITIONED(dbp)) + ret = __partition_stat(dbc, spp, flags); + else +#endif + switch (dbp->type) { + case DB_BTREE: + case DB_RECNO: + ret = __bam_stat(dbc, spp, flags); + break; + case DB_HASH: + ret = __ham_stat(dbc, spp, flags); + break; + case DB_QUEUE: + ret = __qam_stat(dbc, spp, flags); + break; + case DB_UNKNOWN: + default: + ret = (__db_unknown_type(env, "DB->stat", dbp->type)); + break; + } + + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __db_stat_arg -- + * Check DB->stat arguments. + */ +static int +__db_stat_arg(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + ENV *env; + + env = dbp->env; + + /* Check for invalid function flags. */ + LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED); + switch (flags) { + case 0: + case DB_FAST_STAT: + break; + default: + return (__db_ferr(env, "DB->stat", 0)); + } + + return (0); +} + +/* + * __db_stat_print_pp -- + * DB->stat_print pre/post processing. + * + * PUBLIC: int __db_stat_print_pp __P((DB *, u_int32_t)); + */ +int +__db_stat_print_pp(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret; + + env = dbp->env; + + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->stat_print"); + + /* + * !!! + * The actual argument checking is simple, do it inline. + */ + if ((ret = __db_fchk(env, + "DB->stat_print", flags, DB_FAST_STAT | DB_STAT_ALL)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) { + handle_check = 0; + goto err; + } + + ret = __db_stat_print(dbp, ip, flags); + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + +err: ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_stat_print -- + * DB->stat_print. + * + * PUBLIC: int __db_stat_print __P((DB *, DB_THREAD_INFO *, u_int32_t)); + */ +int +__db_stat_print(dbp, ip, flags) + DB *dbp; + DB_THREAD_INFO *ip; + u_int32_t flags; +{ + time_t now; + int ret; + char time_buf[CTIME_BUFLEN]; + + (void)time(&now); + __db_msg(dbp->env, "%.24s\tLocal time", __os_ctime(&now, time_buf)); + + if (LF_ISSET(DB_STAT_ALL) && (ret = __db_print_all(dbp, flags)) != 0) + return (ret); + + if ((ret = __db_print_stats(dbp, ip, flags)) != 0) + return (ret); + + return (0); +} + +/* + * __db_print_stats -- + * Display default DB handle statistics. + */ +static int +__db_print_stats(dbp, ip, flags) + DB *dbp; + DB_THREAD_INFO *ip; + u_int32_t flags; +{ + DBC *dbc; + ENV *env; + int ret, t_ret; + + env = dbp->env; + + /* Acquire a cursor. */ + if ((ret = __db_cursor(dbp, ip, NULL, &dbc, 0)) != 0) + return (ret); + + DEBUG_LWRITE(dbc, NULL, "DB->stat_print", NULL, NULL, 0); + + switch (dbp->type) { + case DB_BTREE: + case DB_RECNO: + ret = __bam_stat_print(dbc, flags); + break; + case DB_HASH: + ret = __ham_stat_print(dbc, flags); + break; + case DB_QUEUE: + ret = __qam_stat_print(dbc, flags); + break; + case DB_UNKNOWN: + default: + ret = (__db_unknown_type(env, "DB->stat_print", dbp->type)); + break; + } + + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __db_print_all -- + * Display debugging DB handle statistics. + */ +static int +__db_print_all(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + static const FN fn[] = { + { DB_AM_CHKSUM, "DB_AM_CHKSUM" }, + { DB_AM_COMPENSATE, "DB_AM_COMPENSATE" }, + { DB_AM_CREATED, "DB_AM_CREATED" }, + { DB_AM_CREATED_MSTR, "DB_AM_CREATED_MSTR" }, + { DB_AM_DBM_ERROR, "DB_AM_DBM_ERROR" }, + { DB_AM_DELIMITER, "DB_AM_DELIMITER" }, + { DB_AM_DISCARD, "DB_AM_DISCARD" }, + { DB_AM_DUP, "DB_AM_DUP" }, + { DB_AM_DUPSORT, "DB_AM_DUPSORT" }, + { DB_AM_ENCRYPT, "DB_AM_ENCRYPT" }, + { DB_AM_FIXEDLEN, "DB_AM_FIXEDLEN" }, + { DB_AM_INMEM, "DB_AM_INMEM" }, + { DB_AM_IN_RENAME, "DB_AM_IN_RENAME" }, + { DB_AM_NOT_DURABLE, "DB_AM_NOT_DURABLE" }, + { DB_AM_OPEN_CALLED, "DB_AM_OPEN_CALLED" }, + { DB_AM_PAD, "DB_AM_PAD" }, + { DB_AM_PGDEF, "DB_AM_PGDEF" }, + { DB_AM_RDONLY, "DB_AM_RDONLY" }, + { DB_AM_READ_UNCOMMITTED, "DB_AM_READ_UNCOMMITTED" }, + { DB_AM_RECNUM, "DB_AM_RECNUM" }, + { DB_AM_RECOVER, "DB_AM_RECOVER" }, + { DB_AM_RENUMBER, "DB_AM_RENUMBER" }, + { DB_AM_REVSPLITOFF, "DB_AM_REVSPLITOFF" }, + { DB_AM_SECONDARY, "DB_AM_SECONDARY" }, + { DB_AM_SNAPSHOT, "DB_AM_SNAPSHOT" }, + { DB_AM_SUBDB, "DB_AM_SUBDB" }, + { DB_AM_SWAP, "DB_AM_SWAP" }, + { DB_AM_TXN, "DB_AM_TXN" }, + { DB_AM_VERIFYING, "DB_AM_VERIFYING" }, + { 0, NULL } + }; + ENV *env; + char time_buf[CTIME_BUFLEN]; + + env = dbp->env; + + __db_msg(env, "%s", DB_GLOBAL(db_line)); + __db_msg(env, "DB handle information:"); + STAT_ULONG("Page size", dbp->pgsize); + STAT_ISSET("Append recno", dbp->db_append_recno); + STAT_ISSET("Feedback", dbp->db_feedback); + STAT_ISSET("Dup compare", dbp->dup_compare); + STAT_ISSET("App private", dbp->app_private); + STAT_ISSET("DbEnv", dbp->env); + STAT_STRING("Type", __db_dbtype_to_string(dbp->type)); + + __mutex_print_debug_single(env, "Thread mutex", dbp->mutex, flags); + + STAT_STRING("File", dbp->fname); + STAT_STRING("Database", dbp->dname); + STAT_HEX("Open flags", dbp->open_flags); + + __db_print_fileid(env, dbp->fileid, "\tFile ID"); + + STAT_ULONG("Cursor adjust ID", dbp->adj_fileid); + STAT_ULONG("Meta pgno", dbp->meta_pgno); + if (dbp->locker != NULL) + STAT_ULONG("Locker ID", dbp->locker->id); + if (dbp->cur_locker != NULL) + STAT_ULONG("Handle lock", dbp->cur_locker->id); + if (dbp->associate_locker != NULL) + STAT_ULONG("Associate lock", dbp->associate_locker->id); + STAT_ULONG("RPC remote ID", dbp->cl_id); + + __db_msg(env, + "%.24s\tReplication handle timestamp", + dbp->timestamp == 0 ? "0" : __os_ctime(&dbp->timestamp, time_buf)); + + STAT_ISSET("Secondary callback", dbp->s_callback); + STAT_ISSET("Primary handle", dbp->s_primary); + + STAT_ISSET("api internal", dbp->api_internal); + STAT_ISSET("Btree/Recno internal", dbp->bt_internal); + STAT_ISSET("Hash internal", dbp->h_internal); + STAT_ISSET("Queue internal", dbp->q_internal); + + __db_prflags(env, NULL, dbp->flags, fn, NULL, "\tFlags"); + + if (dbp->log_filename == NULL) + STAT_ISSET("File naming information", dbp->log_filename); + else + __dbreg_print_fname(env, dbp->log_filename); + + (void)__db_print_cursor(dbp); + + return (0); +} + +/* + * __db_print_cursor -- + * Display the cursor active and free queues. + */ +static int +__db_print_cursor(dbp) + DB *dbp; +{ + DBC *dbc; + ENV *env; + int ret, t_ret; + + env = dbp->env; + + __db_msg(env, "%s", DB_GLOBAL(db_line)); + __db_msg(env, "DB handle cursors:"); + + ret = 0; + MUTEX_LOCK(dbp->env, dbp->mutex); + __db_msg(env, "Active queue:"); + TAILQ_FOREACH(dbc, &dbp->active_queue, links) + if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0) + ret = t_ret; + __db_msg(env, "Join queue:"); + TAILQ_FOREACH(dbc, &dbp->join_queue, links) + if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0) + ret = t_ret; + __db_msg(env, "Free queue:"); + TAILQ_FOREACH(dbc, &dbp->free_queue, links) + if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0) + ret = t_ret; + MUTEX_UNLOCK(dbp->env, dbp->mutex); + + return (ret); +} + +static int +__db_print_citem(dbc) + DBC *dbc; +{ + static const FN fn[] = { + { DBC_ACTIVE, "DBC_ACTIVE" }, + { DBC_DONTLOCK, "DBC_DONTLOCK" }, + { DBC_MULTIPLE, "DBC_MULTIPLE" }, + { DBC_MULTIPLE_KEY, "DBC_MULTIPLE_KEY" }, + { DBC_OPD, "DBC_OPD" }, + { DBC_OWN_LID, "DBC_OWN_LID" }, + { DBC_READ_COMMITTED, "DBC_READ_COMMITTED" }, + { DBC_READ_UNCOMMITTED, "DBC_READ_UNCOMMITTED" }, + { DBC_RECOVER, "DBC_RECOVER" }, + { DBC_RMW, "DBC_RMW" }, + { DBC_TRANSIENT, "DBC_TRANSIENT" }, + { DBC_WAS_READ_COMMITTED,"DBC_WAS_READ_COMMITTED" }, + { DBC_WRITECURSOR, "DBC_WRITECURSOR" }, + { DBC_WRITER, "DBC_WRITER" }, + { 0, NULL } + }; + DB *dbp; + DBC_INTERNAL *cp; + ENV *env; + + dbp = dbc->dbp; + env = dbp->env; + cp = dbc->internal; + + STAT_POINTER("DBC", dbc); + STAT_POINTER("Associated dbp", dbc->dbp); + STAT_POINTER("Associated txn", dbc->txn); + STAT_POINTER("Internal", cp); + STAT_HEX("Default locker ID", dbc->lref == NULL ? 0 : dbc->lref->id); + STAT_HEX("Locker", P_TO_ULONG(dbc->locker)); + STAT_STRING("Type", __db_dbtype_to_string(dbc->dbtype)); + + STAT_POINTER("Off-page duplicate cursor", cp->opd); + STAT_POINTER("Referenced page", cp->page); + STAT_ULONG("Root", cp->root); + STAT_ULONG("Page number", cp->pgno); + STAT_ULONG("Page index", cp->indx); + STAT_STRING("Lock mode", __db_lockmode_to_string(cp->lock_mode)); + __db_prflags(env, NULL, dbc->flags, fn, NULL, "\tFlags"); + + switch (dbc->dbtype) { + case DB_BTREE: + case DB_RECNO: + __bam_print_cursor(dbc); + break; + case DB_HASH: + __ham_print_cursor(dbc); + break; + case DB_UNKNOWN: + DB_ASSERT(env, dbp->type != DB_UNKNOWN); + /* FALLTHROUGH */ + case DB_QUEUE: + default: + break; + } + return (0); +} + +#else /* !HAVE_STATISTICS */ + +int +__db_stat_pp(dbp, txn, spp, flags) + DB *dbp; + DB_TXN *txn; + void *spp; + u_int32_t flags; +{ + COMPQUIET(spp, NULL); + COMPQUIET(txn, NULL); + COMPQUIET(flags, 0); + + return (__db_stat_not_built(dbp->env)); +} + +int +__db_stat_print_pp(dbp, flags) + DB *dbp; + u_int32_t flags; +{ + COMPQUIET(flags, 0); + + return (__db_stat_not_built(dbp->env)); +} +#endif diff --git a/src/libs/resiprocate/contrib/db/db/db_truncate.c b/src/libs/resiprocate/contrib/db/db/db_truncate.c new file mode 100644 index 00000000..66f41806 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_truncate.c @@ -0,0 +1,225 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2001-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/hash.h" +#include "dbinc/qam.h" +#include "dbinc/lock.h" +#include "dbinc/log.h" +#include "dbinc/partition.h" +#include "dbinc/txn.h" + +static int __db_cursor_check __P((DB *)); + +/* + * __db_truncate_pp + * DB->truncate pre/post processing. + * + * PUBLIC: int __db_truncate_pp __P((DB *, DB_TXN *, u_int32_t *, u_int32_t)); + */ +int +__db_truncate_pp(dbp, txn, countp, flags) + DB *dbp; + DB_TXN *txn; + u_int32_t *countp, flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int handle_check, ret, t_ret, txn_local; + + env = dbp->env; + handle_check = txn_local = 0; + + STRIP_AUTO_COMMIT(flags); + + /* Check for invalid flags. */ + if (F_ISSET(dbp, DB_AM_SECONDARY)) { + __db_errx(env, "DB->truncate forbidden on secondary indices"); + return (EINVAL); + } + if ((ret = __db_fchk(env, "DB->truncate", flags, 0)) != 0) + return (ret); + + ENV_ENTER(env, ip); + + /* + * Make sure there are no active cursors on this db. Since we drop + * pages we cannot really adjust cursors. + */ + if ((ret = __db_cursor_check(dbp)) != 0) { + __db_errx(env, + "DB->truncate not permitted with active cursors"); + goto err; + } + +#ifdef CONFIG_TEST + if (IS_REP_MASTER(env)) + DB_TEST_WAIT(env, env->test_check); +#endif + /* Check for replication block. */ + handle_check = IS_ENV_REPLICATED(env); + if (handle_check && + (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { + handle_check = 0; + goto err; + } + + /* + * Check for changes to a read-only database. This must be after the + * replication block so that we cannot race master/client state changes. + */ + if (DB_IS_READONLY(dbp)) { + ret = __db_rdonly(env, "DB->truncate"); + goto err; + } + + /* + * Create local transaction as necessary, check for consistent + * transaction usage. + */ + if (IS_DB_AUTO_COMMIT(dbp, txn)) { + if ((ret = __txn_begin(env, ip, NULL, &txn, 0)) != 0) + goto err; + txn_local = 1; + } + + /* Check for consistent transaction usage. */ + if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0) + goto err; + + ret = __db_truncate(dbp, ip, txn, countp); + +err: if (txn_local && + (t_ret = __db_txn_auto_resolve(env, txn, 0, ret)) && ret == 0) + ret = t_ret; + + /* Release replication block. */ + if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_truncate + * DB->truncate. + * + * PUBLIC: int __db_truncate __P((DB *, DB_THREAD_INFO *, DB_TXN *, + * PUBLIC: u_int32_t *)); + */ +int +__db_truncate(dbp, ip, txn, countp) + DB *dbp; + DB_THREAD_INFO *ip; + DB_TXN *txn; + u_int32_t *countp; +{ + DB *sdbp; + DBC *dbc; + ENV *env; + u_int32_t scount; + int ret, t_ret; + + env = dbp->env; + dbc = NULL; + ret = 0; + + /* + * Run through all secondaries and truncate them first. The count + * returned is the count of the primary only. QUEUE uses normal + * processing to truncate so it will update the secondaries normally. + */ + if (dbp->type != DB_QUEUE && DB_IS_PRIMARY(dbp)) { + if ((ret = __db_s_first(dbp, &sdbp)) != 0) + return (ret); + for (; sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp, txn)) + if ((ret = __db_truncate(sdbp, ip, txn, &scount)) != 0) + break; + if (sdbp != NULL) + (void)__db_s_done(sdbp, txn); + if (ret != 0) + return (ret); + } + + DB_TEST_RECOVERY(dbp, DB_TEST_PREDESTROY, ret, NULL); + + /* Acquire a cursor. */ + if ((ret = __db_cursor(dbp, ip, txn, &dbc, 0)) != 0) + return (ret); + + DEBUG_LWRITE(dbc, txn, "DB->truncate", NULL, NULL, 0); +#ifdef HAVE_PARTITION + if (DB_IS_PARTITIONED(dbp)) + ret = __part_truncate(dbc, countp); + else +#endif + switch (dbp->type) { + case DB_BTREE: + case DB_RECNO: + ret = __bam_truncate(dbc, countp); + break; + case DB_HASH: + ret = __ham_truncate(dbc, countp); + break; + case DB_QUEUE: + ret = __qam_truncate(dbc, countp); + break; + case DB_UNKNOWN: + default: + ret = __db_unknown_type(env, "DB->truncate", dbp->type); + break; + } + + /* Discard the cursor. */ + if (dbc != NULL && (t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + + DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, NULL); + +DB_TEST_RECOVERY_LABEL + + return (ret); +} + +/* + * __db_cursor_check -- + * See if there are any active cursors on this db. + */ +static int +__db_cursor_check(dbp) + DB *dbp; +{ + DB *ldbp; + DBC *dbc; + ENV *env; + int found; + + env = dbp->env; + + MUTEX_LOCK(env, env->mtx_dblist); + FIND_FIRST_DB_MATCH(env, dbp, ldbp); + for (found = 0; + !found && ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; + ldbp = TAILQ_NEXT(ldbp, dblistlinks)) { + MUTEX_LOCK(env, dbp->mutex); + TAILQ_FOREACH(dbc, &ldbp->active_queue, links) + if (IS_INITIALIZED(dbc)) { + found = 1; + break; + } + MUTEX_UNLOCK(env, dbp->mutex); + } + MUTEX_UNLOCK(env, env->mtx_dblist); + + return (found ? EINVAL : 0); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_upg.c b/src/libs/resiprocate/contrib/db/db/db_upg.c new file mode 100644 index 00000000..5a6db94f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_upg.c @@ -0,0 +1,510 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_swap.h" +#include "dbinc/btree.h" +#include "dbinc/hash.h" +#include "dbinc/qam.h" + +/* + * __db_upgrade_pp -- + * DB->upgrade pre/post processing. + * + * PUBLIC: int __db_upgrade_pp __P((DB *, const char *, u_int32_t)); + */ +int +__db_upgrade_pp(dbp, fname, flags) + DB *dbp; + const char *fname; + u_int32_t flags; +{ +#ifdef HAVE_UPGRADE_SUPPORT + DB_THREAD_INFO *ip; + ENV *env; + int ret; + + env = dbp->env; + + /* + * !!! + * The actual argument checking is simple, do it inline. + */ + if ((ret = __db_fchk(env, "DB->upgrade", flags, DB_DUPSORT)) != 0) + return (ret); + + ENV_ENTER(env, ip); + ret = __db_upgrade(dbp, fname, flags); + ENV_LEAVE(env, ip); + return (ret); +#else + COMPQUIET(dbp, NULL); + COMPQUIET(fname, NULL); + COMPQUIET(flags, 0); + + __db_errx(dbp->env, "upgrade not supported"); + return (EINVAL); +#endif +} + +#ifdef HAVE_UPGRADE_SUPPORT +static int (* const func_31_list[P_PAGETYPE_MAX]) + __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)) = { + NULL, /* P_INVALID */ + NULL, /* __P_DUPLICATE */ + __ham_31_hash, /* P_HASH_UNSORTED */ + NULL, /* P_IBTREE */ + NULL, /* P_IRECNO */ + __bam_31_lbtree, /* P_LBTREE */ + NULL, /* P_LRECNO */ + NULL, /* P_OVERFLOW */ + __ham_31_hashmeta, /* P_HASHMETA */ + __bam_31_btreemeta, /* P_BTREEMETA */ + NULL, /* P_QAMMETA */ + NULL, /* P_QAMDATA */ + NULL, /* P_LDUP */ + NULL, /* P_HASH */ +}; + +static int (* const func_46_list[P_PAGETYPE_MAX]) + __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)) = { + NULL, /* P_INVALID */ + NULL, /* __P_DUPLICATE */ + __ham_46_hash, /* P_HASH_UNSORTED */ + NULL, /* P_IBTREE */ + NULL, /* P_IRECNO */ + NULL, /* P_LBTREE */ + NULL, /* P_LRECNO */ + NULL, /* P_OVERFLOW */ + __ham_46_hashmeta, /* P_HASHMETA */ + NULL, /* P_BTREEMETA */ + NULL, /* P_QAMMETA */ + NULL, /* P_QAMDATA */ + NULL, /* P_LDUP */ + NULL, /* P_HASH */ +}; + +static int __db_page_pass __P((DB *, char *, u_int32_t, int (* const []) + (DB *, char *, u_int32_t, DB_FH *, PAGE *, int *), DB_FH *)); +static int __db_set_lastpgno __P((DB *, char *, DB_FH *)); + +/* + * __db_upgrade -- + * Upgrade an existing database. + * + * PUBLIC: int __db_upgrade __P((DB *, const char *, u_int32_t)); + */ +int +__db_upgrade(dbp, fname, flags) + DB *dbp; + const char *fname; + u_int32_t flags; +{ + DBMETA *meta; + DB_FH *fhp; + ENV *env; + size_t n; + int ret, t_ret, use_mp_open; + u_int8_t mbuf[256], tmpflags; + char *real_name; + + use_mp_open = 0; + env = dbp->env; + fhp = NULL; + + /* Get the real backing file name. */ + if ((ret = __db_appname(env, + DB_APP_DATA, fname, NULL, &real_name)) != 0) + return (ret); + + /* Open the file. */ + if ((ret = __os_open(env, real_name, 0, 0, 0, &fhp)) != 0) { + __db_err(env, ret, "%s", real_name); + return (ret); + } + + /* Initialize the feedback. */ + if (dbp->db_feedback != NULL) + dbp->db_feedback(dbp, DB_UPGRADE, 0); + + /* + * Read the metadata page. We read 256 bytes, which is larger than + * any access method's metadata page and smaller than any disk sector. + */ + if ((ret = __os_read(env, fhp, mbuf, sizeof(mbuf), &n)) != 0) + goto err; + + switch (((DBMETA *)mbuf)->magic) { + case DB_BTREEMAGIC: + switch (((DBMETA *)mbuf)->version) { + case 6: + /* + * Before V7 not all pages had page types, so we do the + * single meta-data page by hand. + */ + if ((ret = + __bam_30_btreemeta(dbp, real_name, mbuf)) != 0) + goto err; + if ((ret = __os_seek(env, fhp, 0, 0, 0)) != 0) + goto err; + if ((ret = __os_write(env, fhp, mbuf, 256, &n)) != 0) + goto err; + /* FALLTHROUGH */ + case 7: + /* + * We need the page size to do more. Rip it out of + * the meta-data page. + */ + memcpy(&dbp->pgsize, mbuf + 20, sizeof(u_int32_t)); + + if ((ret = __db_page_pass( + dbp, real_name, flags, func_31_list, fhp)) != 0) + goto err; + /* FALLTHROUGH */ + case 8: + if ((ret = + __db_set_lastpgno(dbp, real_name, fhp)) != 0) + goto err; + /* FALLTHROUGH */ + case 9: + break; + default: + __db_errx(env, "%s: unsupported btree version: %lu", + real_name, (u_long)((DBMETA *)mbuf)->version); + ret = DB_OLD_VERSION; + goto err; + } + break; + case DB_HASHMAGIC: + switch (((DBMETA *)mbuf)->version) { + case 4: + case 5: + /* + * Before V6 not all pages had page types, so we do the + * single meta-data page by hand. + */ + if ((ret = + __ham_30_hashmeta(dbp, real_name, mbuf)) != 0) + goto err; + if ((ret = __os_seek(env, fhp, 0, 0, 0)) != 0) + goto err; + if ((ret = __os_write(env, fhp, mbuf, 256, &n)) != 0) + goto err; + + /* + * Before V6, we created hash pages one by one as they + * were needed, using hashhdr.ovfl_point to reserve + * a block of page numbers for them. A consequence + * of this was that, if no overflow pages had been + * created, the current doubling might extend past + * the end of the database file. + * + * In DB 3.X, we now create all the hash pages + * belonging to a doubling atomically; it's not + * safe to just save them for later, because when + * we create an overflow page we'll just create + * a new last page (whatever that may be). Grow + * the database to the end of the current doubling. + */ + if ((ret = + __ham_30_sizefix(dbp, fhp, real_name, mbuf)) != 0) + goto err; + /* FALLTHROUGH */ + case 6: + /* + * We need the page size to do more. Rip it out of + * the meta-data page. + */ + memcpy(&dbp->pgsize, mbuf + 20, sizeof(u_int32_t)); + + if ((ret = __db_page_pass( + dbp, real_name, flags, func_31_list, fhp)) != 0) + goto err; + /* FALLTHROUGH */ + case 7: + if ((ret = + __db_set_lastpgno(dbp, real_name, fhp)) != 0) + goto err; + /* FALLTHROUGH */ + case 8: + /* + * Any upgrade that has proceeded this far has metadata + * pages compatible with hash version 8 metadata pages, + * so casting mbuf to a dbmeta is safe. + * If a newer revision moves the pagesize, checksum or + * encrypt_alg flags in the metadata, then the + * extraction of the fields will need to use hard coded + * offsets. + */ + meta = (DBMETA*)mbuf; + /* + * We need the page size to do more. Extract it from + * the meta-data page. + */ + memcpy(&dbp->pgsize, &meta->pagesize, + sizeof(u_int32_t)); + /* + * Rip out metadata and encrypt_alg fields from the + * metadata page. So the upgrade can know how big + * the page metadata pre-amble is. Any upgrade that has + * proceeded this far has metadata pages compatible + * with hash version 8 metadata pages, so extracting + * the fields is safe. + */ + memcpy(&tmpflags, &meta->metaflags, sizeof(u_int8_t)); + if (FLD_ISSET(tmpflags, DBMETA_CHKSUM)) + F_SET(dbp, DB_AM_CHKSUM); + memcpy(&tmpflags, &meta->encrypt_alg, sizeof(u_int8_t)); + if (tmpflags != 0) { + if (!CRYPTO_ON(dbp->env)) { + __db_errx(env, +"Attempt to upgrade an encrypted database without providing a password."); + ret = EINVAL; + goto err; + } + F_SET(dbp, DB_AM_ENCRYPT); + } + + /* + * This is ugly. It is necessary to have a usable + * mpool in the dbp to upgrade from an unsorted + * to a sorted hash database. The mpool file is used + * to resolve offpage key items, which are needed to + * determine sort order. Having mpool open and access + * the file does not affect the page pass, since the + * page pass only updates DB_HASH_UNSORTED pages + * in-place, and the mpool file is only used to read + * OFFPAGE items. + */ + use_mp_open = 1; + if ((ret = __os_closehandle(env, fhp)) != 0) + return (ret); + dbp->type = DB_HASH; + if ((ret = __env_mpool(dbp, fname, + DB_AM_NOT_DURABLE | DB_AM_VERIFYING)) != 0) + return (ret); + fhp = dbp->mpf->fhp; + + /* Do the actual conversion pass. */ + if ((ret = __db_page_pass( + dbp, real_name, flags, func_46_list, fhp)) != 0) + goto err; + + /* FALLTHROUGH */ + case 9: + break; + default: + __db_errx(env, "%s: unsupported hash version: %lu", + real_name, (u_long)((DBMETA *)mbuf)->version); + ret = DB_OLD_VERSION; + goto err; + } + break; + case DB_QAMMAGIC: + switch (((DBMETA *)mbuf)->version) { + case 1: + /* + * If we're in a Queue database, the only page that + * needs upgrading is the meta-database page, don't + * bother with a full pass. + */ + if ((ret = __qam_31_qammeta(dbp, real_name, mbuf)) != 0) + return (ret); + /* FALLTHROUGH */ + case 2: + if ((ret = __qam_32_qammeta(dbp, real_name, mbuf)) != 0) + return (ret); + if ((ret = __os_seek(env, fhp, 0, 0, 0)) != 0) + goto err; + if ((ret = __os_write(env, fhp, mbuf, 256, &n)) != 0) + goto err; + /* FALLTHROUGH */ + case 3: + case 4: + break; + default: + __db_errx(env, "%s: unsupported queue version: %lu", + real_name, (u_long)((DBMETA *)mbuf)->version); + ret = DB_OLD_VERSION; + goto err; + } + break; + default: + M_32_SWAP(((DBMETA *)mbuf)->magic); + switch (((DBMETA *)mbuf)->magic) { + case DB_BTREEMAGIC: + case DB_HASHMAGIC: + case DB_QAMMAGIC: + __db_errx(env, + "%s: DB->upgrade only supported on native byte-order systems", + real_name); + break; + default: + __db_errx(env, + "%s: unrecognized file type", real_name); + break; + } + ret = EINVAL; + goto err; + } + + ret = __os_fsync(env, fhp); + + /* + * If mp_open was used, then rely on the database close to clean up + * any file handles. + */ +err: if (use_mp_open == 0 && fhp != NULL && + (t_ret = __os_closehandle(env, fhp)) != 0 && ret == 0) + ret = t_ret; + __os_free(env, real_name); + + /* We're done. */ + if (dbp->db_feedback != NULL) + dbp->db_feedback(dbp, DB_UPGRADE, 100); + + return (ret); +} + +/* + * __db_page_pass -- + * Walk the pages of the database, upgrading whatever needs it. + */ +static int +__db_page_pass(dbp, real_name, flags, fl, fhp) + DB *dbp; + char *real_name; + u_int32_t flags; + int (* const fl[P_PAGETYPE_MAX]) + __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); + DB_FH *fhp; +{ + ENV *env; + PAGE *page; + db_pgno_t i, pgno_last; + size_t n; + int dirty, ret; + + env = dbp->env; + + /* Determine the last page of the file. */ + if ((ret = __db_lastpgno(dbp, real_name, fhp, &pgno_last)) != 0) + return (ret); + + /* Allocate memory for a single page. */ + if ((ret = __os_malloc(env, dbp->pgsize, &page)) != 0) + return (ret); + + /* Walk the file, calling the underlying conversion functions. */ + for (i = 0; i < pgno_last; ++i) { + if (dbp->db_feedback != NULL) + dbp->db_feedback( + dbp, DB_UPGRADE, (int)((i * 100)/pgno_last)); + if ((ret = __os_seek(env, fhp, i, dbp->pgsize, 0)) != 0) + break; + if ((ret = __os_read(env, fhp, page, dbp->pgsize, &n)) != 0) + break; + dirty = 0; + /* Always decrypt the page. */ + if ((ret = __db_decrypt_pg(env, dbp, page)) != 0) + break; + if (fl[TYPE(page)] != NULL && (ret = fl[TYPE(page)] + (dbp, real_name, flags, fhp, page, &dirty)) != 0) + break; + if (dirty) { + if ((ret = __db_encrypt_and_checksum_pg( + env, dbp, page)) != 0) + break; + if ((ret = + __os_seek(env, fhp, i, dbp->pgsize, 0)) != 0) + break; + if ((ret = __os_write(env, + fhp, page, dbp->pgsize, &n)) != 0) + break; + } + } + + __os_free(dbp->env, page); + return (ret); +} + +/* + * __db_lastpgno -- + * Return the current last page number of the file. + * + * PUBLIC: int __db_lastpgno __P((DB *, char *, DB_FH *, db_pgno_t *)); + */ +int +__db_lastpgno(dbp, real_name, fhp, pgno_lastp) + DB *dbp; + char *real_name; + DB_FH *fhp; + db_pgno_t *pgno_lastp; +{ + ENV *env; + db_pgno_t pgno_last; + u_int32_t mbytes, bytes; + int ret; + + env = dbp->env; + + if ((ret = __os_ioinfo(env, + real_name, fhp, &mbytes, &bytes, NULL)) != 0) { + __db_err(env, ret, "%s", real_name); + return (ret); + } + + /* Page sizes have to be a power-of-two. */ + if (bytes % dbp->pgsize != 0) { + __db_errx(env, + "%s: file size not a multiple of the pagesize", real_name); + return (EINVAL); + } + pgno_last = mbytes * (MEGABYTE / dbp->pgsize); + pgno_last += bytes / dbp->pgsize; + + *pgno_lastp = pgno_last; + return (0); +} + +/* + * __db_set_lastpgno -- + * Update the meta->last_pgno field. + * + * Code assumes that we do not have checksums/crypto on the page. + */ +static int +__db_set_lastpgno(dbp, real_name, fhp) + DB *dbp; + char *real_name; + DB_FH *fhp; +{ + DBMETA meta; + ENV *env; + int ret; + size_t n; + + env = dbp->env; + if ((ret = __os_seek(env, fhp, 0, 0, 0)) != 0) + return (ret); + if ((ret = __os_read(env, fhp, &meta, sizeof(meta), &n)) != 0) + return (ret); + dbp->pgsize = meta.pagesize; + if ((ret = __db_lastpgno(dbp, real_name, fhp, &meta.last_pgno)) != 0) + return (ret); + if ((ret = __os_seek(env, fhp, 0, 0, 0)) != 0) + return (ret); + if ((ret = __os_write(env, fhp, &meta, sizeof(meta), &n)) != 0) + return (ret); + + return (0); +} +#endif /* HAVE_UPGRADE_SUPPORT */ diff --git a/src/libs/resiprocate/contrib/db/db/db_upg_opd.c b/src/libs/resiprocate/contrib/db/db/db_upg_opd.c new file mode 100644 index 00000000..ea143cfb --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_upg_opd.c @@ -0,0 +1,343 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" + +static int __db_build_bi __P((DB *, DB_FH *, PAGE *, PAGE *, u_int32_t, int *)); +static int __db_build_ri __P((DB *, DB_FH *, PAGE *, PAGE *, u_int32_t, int *)); +static int __db_up_ovref __P((DB *, DB_FH *, db_pgno_t)); + +#define GET_PAGE(dbp, fhp, pgno, page) { \ + if ((ret = __os_seek( \ + dbp->env, fhp, pgno, (dbp)->pgsize, 0)) != 0) \ + goto err; \ + if ((ret = __os_read(dbp->env, \ + fhp, page, (dbp)->pgsize, &n)) != 0) \ + goto err; \ +} +#define PUT_PAGE(dbp, fhp, pgno, page) { \ + if ((ret = __os_seek( \ + dbp->env, fhp, pgno, (dbp)->pgsize, 0)) != 0) \ + goto err; \ + if ((ret = __os_write(dbp->env, \ + fhp, page, (dbp)->pgsize, &n)) != 0) \ + goto err; \ +} + +/* + * __db_31_offdup -- + * Convert 3.0 off-page duplicates to 3.1 off-page duplicates. + * + * PUBLIC: int __db_31_offdup __P((DB *, char *, DB_FH *, int, db_pgno_t *)); + */ +int +__db_31_offdup(dbp, real_name, fhp, sorted, pgnop) + DB *dbp; + char *real_name; + DB_FH *fhp; + int sorted; + db_pgno_t *pgnop; +{ + PAGE *ipage, *page; + db_indx_t indx; + db_pgno_t cur_cnt, i, next_cnt, pgno, *pgno_cur, pgno_last; + db_pgno_t *pgno_next, pgno_max, *tmp; + db_recno_t nrecs; + size_t n; + int level, nomem, ret; + + ipage = page = NULL; + pgno_cur = pgno_next = NULL; + + /* Allocate room to hold a page. */ + if ((ret = __os_malloc(dbp->env, dbp->pgsize, &page)) != 0) + goto err; + + /* + * Walk the chain of 3.0 off-page duplicates. Each one is converted + * in place to a 3.1 off-page duplicate page. If the duplicates are + * sorted, they are converted to a Btree leaf page, otherwise to a + * Recno leaf page. + */ + for (nrecs = 0, cur_cnt = pgno_max = 0, + pgno = *pgnop; pgno != PGNO_INVALID;) { + if (pgno_max == cur_cnt) { + pgno_max += 20; + if ((ret = __os_realloc(dbp->env, pgno_max * + sizeof(db_pgno_t), &pgno_cur)) != 0) + goto err; + } + pgno_cur[cur_cnt++] = pgno; + + GET_PAGE(dbp, fhp, pgno, page); + nrecs += NUM_ENT(page); + LEVEL(page) = LEAFLEVEL; + TYPE(page) = sorted ? P_LDUP : P_LRECNO; + /* + * !!! + * DB didn't zero the LSNs on off-page duplicates pages. + */ + ZERO_LSN(LSN(page)); + PUT_PAGE(dbp, fhp, pgno, page); + + pgno = NEXT_PGNO(page); + } + + /* If we only have a single page, it's easy. */ + if (cur_cnt <= 1) + goto done; + + /* + * pgno_cur is the list of pages we just converted. We're + * going to walk that list, but we'll need to create a new + * list while we do so. + */ + if ((ret = __os_malloc(dbp->env, + cur_cnt * sizeof(db_pgno_t), &pgno_next)) != 0) + goto err; + + /* Figure out where we can start allocating new pages. */ + if ((ret = __db_lastpgno(dbp, real_name, fhp, &pgno_last)) != 0) + goto err; + + /* Allocate room for an internal page. */ + if ((ret = __os_malloc(dbp->env, dbp->pgsize, &ipage)) != 0) + goto err; + PGNO(ipage) = PGNO_INVALID; + + /* + * Repeatedly walk the list of pages, building internal pages, until + * there's only one page at a level. + */ + for (level = LEAFLEVEL + 1; cur_cnt > 1; ++level) { + for (indx = 0, i = next_cnt = 0; i < cur_cnt;) { + if (indx == 0) { + P_INIT(ipage, dbp->pgsize, pgno_last, + PGNO_INVALID, PGNO_INVALID, + level, sorted ? P_IBTREE : P_IRECNO); + ZERO_LSN(LSN(ipage)); + + pgno_next[next_cnt++] = pgno_last++; + } + + GET_PAGE(dbp, fhp, pgno_cur[i], page); + + /* + * If the duplicates are sorted, put the first item on + * the lower-level page onto a Btree internal page. If + * the duplicates are not sorted, create an internal + * Recno structure on the page. If either case doesn't + * fit, push out the current page and start a new one. + */ + nomem = 0; + if (sorted) { + if ((ret = __db_build_bi( + dbp, fhp, ipage, page, indx, &nomem)) != 0) + goto err; + } else + if ((ret = __db_build_ri( + dbp, fhp, ipage, page, indx, &nomem)) != 0) + goto err; + if (nomem) { + indx = 0; + PUT_PAGE(dbp, fhp, PGNO(ipage), ipage); + } else { + ++indx; + ++NUM_ENT(ipage); + ++i; + } + } + + /* + * Push out the last internal page. Set the top-level record + * count if we've reached the top. + */ + if (next_cnt == 1) + RE_NREC_SET(ipage, nrecs); + PUT_PAGE(dbp, fhp, PGNO(ipage), ipage); + + /* Swap the current and next page number arrays. */ + cur_cnt = next_cnt; + tmp = pgno_cur; + pgno_cur = pgno_next; + pgno_next = tmp; + } + +done: *pgnop = pgno_cur[0]; + +err: if (pgno_cur != NULL) + __os_free(dbp->env, pgno_cur); + if (pgno_next != NULL) + __os_free(dbp->env, pgno_next); + if (ipage != NULL) + __os_free(dbp->env, ipage); + if (page != NULL) + __os_free(dbp->env, page); + + return (ret); +} + +/* + * __db_build_bi -- + * Build a BINTERNAL entry for a parent page. + */ +static int +__db_build_bi(dbp, fhp, ipage, page, indx, nomemp) + DB *dbp; + DB_FH *fhp; + PAGE *ipage, *page; + u_int32_t indx; + int *nomemp; +{ + BINTERNAL bi, *child_bi; + BKEYDATA *child_bk; + u_int8_t *p; + int ret; + db_indx_t *inp; + + inp = P_INP(dbp, ipage); + switch (TYPE(page)) { + case P_IBTREE: + child_bi = GET_BINTERNAL(dbp, page, 0); + if (P_FREESPACE(dbp, ipage) < BINTERNAL_PSIZE(child_bi->len)) { + *nomemp = 1; + return (0); + } + inp[indx] = + HOFFSET(ipage) -= BINTERNAL_SIZE(child_bi->len); + p = P_ENTRY(dbp, ipage, indx); + + bi.len = child_bi->len; + B_TSET(bi.type, child_bi->type); + bi.pgno = PGNO(page); + bi.nrecs = __bam_total(dbp, page); + memcpy(p, &bi, SSZA(BINTERNAL, data)); + p += SSZA(BINTERNAL, data); + memcpy(p, child_bi->data, child_bi->len); + + /* Increment the overflow ref count. */ + if (B_TYPE(child_bi->type) == B_OVERFLOW) + if ((ret = __db_up_ovref(dbp, fhp, + ((BOVERFLOW *)(child_bi->data))->pgno)) != 0) + return (ret); + break; + case P_LDUP: + child_bk = GET_BKEYDATA(dbp, page, 0); + switch (B_TYPE(child_bk->type)) { + case B_KEYDATA: + if (P_FREESPACE(dbp, ipage) < + BINTERNAL_PSIZE(child_bk->len)) { + *nomemp = 1; + return (0); + } + inp[indx] = + HOFFSET(ipage) -= BINTERNAL_SIZE(child_bk->len); + p = P_ENTRY(dbp, ipage, indx); + + bi.len = child_bk->len; + B_TSET(bi.type, child_bk->type); + bi.pgno = PGNO(page); + bi.nrecs = __bam_total(dbp, page); + memcpy(p, &bi, SSZA(BINTERNAL, data)); + p += SSZA(BINTERNAL, data); + memcpy(p, child_bk->data, child_bk->len); + break; + case B_OVERFLOW: + if (P_FREESPACE(dbp, ipage) < + BINTERNAL_PSIZE(BOVERFLOW_SIZE)) { + *nomemp = 1; + return (0); + } + inp[indx] = + HOFFSET(ipage) -= BINTERNAL_SIZE(BOVERFLOW_SIZE); + p = P_ENTRY(dbp, ipage, indx); + + bi.len = BOVERFLOW_SIZE; + B_TSET(bi.type, child_bk->type); + bi.pgno = PGNO(page); + bi.nrecs = __bam_total(dbp, page); + memcpy(p, &bi, SSZA(BINTERNAL, data)); + p += SSZA(BINTERNAL, data); + memcpy(p, child_bk, BOVERFLOW_SIZE); + + /* Increment the overflow ref count. */ + if ((ret = __db_up_ovref(dbp, fhp, + ((BOVERFLOW *)child_bk)->pgno)) != 0) + return (ret); + break; + default: + return (__db_pgfmt(dbp->env, PGNO(page))); + } + break; + default: + return (__db_pgfmt(dbp->env, PGNO(page))); + } + + return (0); +} + +/* + * __db_build_ri -- + * Build a RINTERNAL entry for an internal parent page. + */ +static int +__db_build_ri(dbp, fhp, ipage, page, indx, nomemp) + DB *dbp; + DB_FH *fhp; + PAGE *ipage, *page; + u_int32_t indx; + int *nomemp; +{ + RINTERNAL ri; + db_indx_t *inp; + + COMPQUIET(fhp, NULL); + inp = P_INP(dbp, ipage); + if (P_FREESPACE(dbp, ipage) < RINTERNAL_PSIZE) { + *nomemp = 1; + return (0); + } + + ri.pgno = PGNO(page); + ri.nrecs = __bam_total(dbp, page); + inp[indx] = HOFFSET(ipage) -= RINTERNAL_SIZE; + memcpy(P_ENTRY(dbp, ipage, indx), &ri, RINTERNAL_SIZE); + + return (0); +} + +/* + * __db_up_ovref -- + * Increment/decrement the reference count on an overflow page. + */ +static int +__db_up_ovref(dbp, fhp, pgno) + DB *dbp; + DB_FH *fhp; + db_pgno_t pgno; +{ + PAGE *page; + size_t n; + int ret; + + /* Allocate room to hold a page. */ + if ((ret = __os_malloc(dbp->env, dbp->pgsize, &page)) != 0) + return (ret); + + GET_PAGE(dbp, fhp, pgno, page); + ++OV_REF(page); + PUT_PAGE(dbp, fhp, pgno, page); + +err: __os_free(dbp->env, page); + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_vrfy.c b/src/libs/resiprocate/contrib/db/db/db_vrfy.c new file mode 100644 index 00000000..7ea9c625 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_vrfy.c @@ -0,0 +1,2894 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_swap.h" +#include "dbinc/db_verify.h" +#include "dbinc/btree.h" +#include "dbinc/hash.h" +#include "dbinc/lock.h" +#include "dbinc/mp.h" +#include "dbinc/qam.h" +#include "dbinc/txn.h" + +/* + * This is the code for DB->verify, the DB database consistency checker. + * For now, it checks all subdatabases in a database, and verifies + * everything it knows how to (i.e. it's all-or-nothing, and one can't + * check only for a subset of possible problems). + */ + +static u_int __db_guesspgsize __P((ENV *, DB_FH *)); +static int __db_is_valid_magicno __P((u_int32_t, DBTYPE *)); +static int __db_meta2pgset + __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, DB *)); +static int __db_salvage __P((DB *, VRFY_DBINFO *, + db_pgno_t, void *, int (*)(void *, const void *), u_int32_t)); +static int __db_salvage_subdbpg __P((DB *, VRFY_DBINFO *, + PAGE *, void *, int (*)(void *, const void *), u_int32_t)); +static int __db_salvage_all __P((DB *, VRFY_DBINFO *, void *, + int(*)(void *, const void *), u_int32_t, int *)); +static int __db_salvage_unknowns __P((DB *, VRFY_DBINFO *, void *, + int (*)(void *, const void *), u_int32_t)); +static int __db_verify_arg __P((DB *, const char *, void *, u_int32_t)); +static int __db_vrfy_freelist + __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t)); +static int __db_vrfy_invalid + __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); +static int __db_vrfy_orderchkonly __P((DB *, + VRFY_DBINFO *, const char *, const char *, u_int32_t)); +static int __db_vrfy_pagezero __P((DB *, VRFY_DBINFO *, DB_FH *, u_int32_t)); +static int __db_vrfy_subdbs + __P((DB *, VRFY_DBINFO *, const char *, u_int32_t)); +static int __db_vrfy_structure __P((DB *, VRFY_DBINFO *, + const char *, db_pgno_t, void *, void *, u_int32_t)); +static int __db_vrfy_walkpages __P((DB *, VRFY_DBINFO *, + void *, int (*)(void *, const void *), u_int32_t)); + +#define VERIFY_FLAGS \ + (DB_AGGRESSIVE | \ + DB_NOORDERCHK | DB_ORDERCHKONLY | DB_PRINTABLE | DB_SALVAGE | DB_UNREF) + +/* + * __db_verify_pp -- + * DB->verify public interface. + * + * PUBLIC: int __db_verify_pp + * PUBLIC: __P((DB *, const char *, const char *, FILE *, u_int32_t)); + */ +int +__db_verify_pp(dbp, file, database, outfile, flags) + DB *dbp; + const char *file, *database; + FILE *outfile; + u_int32_t flags; +{ + /* + * __db_verify_pp is a wrapper to __db_verify_internal, which lets + * us pass appropriate equivalents to FILE * in from the non-C APIs. + * That's why the usual ENV_ENTER macros are in __db_verify_internal, + * not here. + */ + return (__db_verify_internal(dbp, + file, database, outfile, __db_pr_callback, flags)); +} + +/* + * __db_verify_internal -- + * + * PUBLIC: int __db_verify_internal __P((DB *, const char *, + * PUBLIC: const char *, void *, int (*)(void *, const void *), u_int32_t)); + */ +int +__db_verify_internal(dbp, fname, dname, handle, callback, flags) + DB *dbp; + const char *fname, *dname; + void *handle; + int (*callback) __P((void *, const void *)); + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int ret, t_ret; + + env = dbp->env; + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->verify"); + + if (!LF_ISSET(DB_SALVAGE)) + LF_SET(DB_UNREF); + + ENV_ENTER(env, ip); + + if ((ret = __db_verify_arg(dbp, dname, handle, flags)) == 0) + ret = __db_verify(dbp, ip, + fname, dname, handle, callback, NULL, NULL, flags); + + /* Db.verify is a DB handle destructor. */ + if ((t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0) + ret = t_ret; + + ENV_LEAVE(env, ip); + return (ret); +} + +/* + * __db_verify_arg -- + * Check DB->verify arguments. + */ +static int +__db_verify_arg(dbp, dname, handle, flags) + DB *dbp; + const char *dname; + void *handle; + u_int32_t flags; +{ + ENV *env; + int ret; + + env = dbp->env; + + if ((ret = __db_fchk(env, "DB->verify", flags, VERIFY_FLAGS)) != 0) + return (ret); + + /* + * DB_SALVAGE is mutually exclusive with the other flags except + * DB_AGGRESSIVE, DB_PRINTABLE. + * + * DB_AGGRESSIVE and DB_PRINTABLE are only meaningful when salvaging. + * + * DB_SALVAGE requires an output stream. + */ + if (LF_ISSET(DB_SALVAGE)) { + if (LF_ISSET(~(DB_AGGRESSIVE | DB_PRINTABLE | DB_SALVAGE))) + return (__db_ferr(env, "DB->verify", 1)); + if (handle == NULL) { + __db_errx(env, + "DB_SALVAGE requires a an output handle"); + return (EINVAL); + } + } else + if (LF_ISSET(DB_AGGRESSIVE | DB_PRINTABLE)) + return (__db_ferr(env, "DB->verify", 1)); + + /* + * DB_ORDERCHKONLY is mutually exclusive with DB_SALVAGE and + * DB_NOORDERCHK, and requires a database name. + */ + if ((ret = __db_fcchk(env, "DB->verify", flags, + DB_ORDERCHKONLY, DB_SALVAGE | DB_NOORDERCHK)) != 0) + return (ret); + if (LF_ISSET(DB_ORDERCHKONLY) && dname == NULL) { + __db_errx(env, "DB_ORDERCHKONLY requires a database name"); + return (EINVAL); + } + return (0); +} + +/* + * __db_verify -- + * Walk the entire file page-by-page, either verifying with or without + * dumping in db_dump -d format, or DB_SALVAGE-ing whatever key/data + * pairs can be found and dumping them in standard (db_load-ready) + * dump format. + * + * (Salvaging isn't really a verification operation, but we put it + * here anyway because it requires essentially identical top-level + * code.) + * + * flags may be 0, DB_NOORDERCHK, DB_ORDERCHKONLY, or DB_SALVAGE + * (and optionally DB_AGGRESSIVE). + * PUBLIC: int __db_verify __P((DB *, DB_THREAD_INFO *, const char *, + * PUBLIC: const char *, void *, int (*)(void *, const void *), + * PUBLIC: void *, void *, u_int32_t)); + */ +int +__db_verify(dbp, ip, name, subdb, handle, callback, lp, rp, flags) + DB *dbp; + DB_THREAD_INFO *ip; + const char *name, *subdb; + void *handle; + int (*callback) __P((void *, const void *)); + void *lp, *rp; + u_int32_t flags; +{ + DB_FH *fhp; + ENV *env; + VRFY_DBINFO *vdp; + u_int32_t sflags; + int has_subdbs, isbad, ret, t_ret; + char *real_name; + + env = dbp->env; + fhp = NULL; + vdp = NULL; + real_name = NULL; + has_subdbs = isbad = ret = t_ret = 0; + + F_SET(dbp, DB_AM_VERIFYING); + + /* Initialize any feedback function. */ + if (!LF_ISSET(DB_SALVAGE) && dbp->db_feedback != NULL) + dbp->db_feedback(dbp, DB_VERIFY, 0); + + /* + * We don't know how large the cache is, and if the database + * in question uses a small page size--which we don't know + * yet!--it may be uncomfortably small for the default page + * size [#2143]. However, the things we need temporary + * databases for in dbinfo are largely tiny, so using a + * 1024-byte pagesize is probably not going to be a big hit, + * and will make us fit better into small spaces. + */ + if ((ret = __db_vrfy_dbinfo_create(env, ip, 1024, &vdp)) != 0) + goto err; + + /* + * Note whether the user has requested that we use printable + * chars where possible. We won't get here with this flag if + * we're not salvaging. + */ + if (LF_ISSET(DB_PRINTABLE)) + F_SET(vdp, SALVAGE_PRINTABLE); + + /* Find the real name of the file. */ + if ((ret = __db_appname(env, + DB_APP_DATA, name, &dbp->dirname, &real_name)) != 0) + goto err; + + /* + * Our first order of business is to verify page 0, which is + * the metadata page for the master database of subdatabases + * or of the only database in the file. We want to do this by hand + * rather than just calling __db_open in case it's corrupt--various + * things in __db_open might act funny. + * + * Once we know the metadata page is healthy, I believe that it's + * safe to open the database normally and then use the page swapping + * code, which makes life easier. + */ + if ((ret = __os_open(env, real_name, 0, DB_OSO_RDONLY, 0, &fhp)) != 0) + goto err; + + /* Verify the metadata page 0; set pagesize and type. */ + if ((ret = __db_vrfy_pagezero(dbp, vdp, fhp, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + + /* + * We can assume at this point that dbp->pagesize and dbp->type are + * set correctly, or at least as well as they can be, and that + * locking, logging, and txns are not in use. Thus we can trust + * the memp code not to look at the page, and thus to be safe + * enough to use. + * + * The dbp is not open, but the file is open in the fhp, and we + * cannot assume that __db_open is safe. Call __env_setup, + * the [safe] part of __db_open that initializes the environment-- + * and the mpool--manually. + */ + if ((ret = __env_setup(dbp, NULL, + name, subdb, TXN_INVALID, DB_ODDFILESIZE | DB_RDONLY)) != 0) + goto err; + + /* + * Set our name in the Queue subsystem; we may need it later + * to deal with extents. + */ + if (dbp->type == DB_QUEUE && + (ret = __qam_set_ext_data(dbp, name)) != 0) + goto err; + + /* Mark the dbp as opened, so that we correctly handle its close. */ + F_SET(dbp, DB_AM_OPEN_CALLED); + + /* Find out the page number of the last page in the database. */ + if ((ret = __memp_get_last_pgno(dbp->mpf, &vdp->last_pgno)) != 0) + goto err; + + /* + * DB_ORDERCHKONLY is a special case; our file consists of + * several subdatabases, which use different hash, bt_compare, + * and/or dup_compare functions. Consequently, we couldn't verify + * sorting and hashing simply by calling DB->verify() on the file. + * DB_ORDERCHKONLY allows us to come back and check those things; it + * requires a subdatabase, and assumes that everything but that + * database's sorting/hashing is correct. + */ + if (LF_ISSET(DB_ORDERCHKONLY)) { + ret = __db_vrfy_orderchkonly(dbp, vdp, name, subdb, flags); + goto done; + } + + sflags = flags; + if (dbp->p_internal != NULL) + LF_CLR(DB_SALVAGE); + + /* + * When salvaging, we use a db to keep track of whether we've seen a + * given overflow or dup page in the course of traversing normal data. + * If in the end we have not, we assume its key got lost and print it + * with key "UNKNOWN". + */ + if (LF_ISSET(DB_SALVAGE)) { + if ((ret = __db_salvage_init(vdp)) != 0) + goto err; + + /* + * If we're not being aggressive, salvage by walking the tree + * and only printing the leaves we find. "has_subdbs" will + * indicate whether we found subdatabases. + */ + if (!LF_ISSET(DB_AGGRESSIVE) && __db_salvage_all( + dbp, vdp, handle, callback, flags, &has_subdbs) != 0) + isbad = 1; + + /* + * If we have subdatabases, flag if any keys are found that + * don't belong to a subdatabase -- they'll need to have an + * "__OTHER__" subdatabase header printed first. + */ + if (has_subdbs) { + F_SET(vdp, SALVAGE_PRINTHEADER); + F_SET(vdp, SALVAGE_HASSUBDBS); + } + } + + /* Walk all the pages, if a page cannot be read, verify structure. */ + if ((ret = + __db_vrfy_walkpages(dbp, vdp, handle, callback, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else if (ret != DB_PAGE_NOTFOUND) + goto err; + } + + /* If we're verifying, verify inter-page structure. */ + if (!LF_ISSET(DB_SALVAGE) && isbad == 0) + if ((t_ret = __db_vrfy_structure(dbp, + vdp, name, 0, lp, rp, flags)) != 0) { + if (t_ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + + /* + * If we're salvaging, output with key UNKNOWN any overflow or dup pages + * we haven't been able to put in context. Then destroy the salvager's + * state-saving database. + */ + if (LF_ISSET(DB_SALVAGE)) { + if ((ret = __db_salvage_unknowns(dbp, + vdp, handle, callback, flags)) != 0) + isbad = 1; + } + + flags = sflags; + +#ifdef HAVE_PARTITION + if (t_ret == 0 && dbp->p_internal != NULL) + t_ret = __part_verify(dbp, vdp, name, handle, callback, flags); +#endif + + if (ret == 0) + ret = t_ret; + + /* Don't display a footer for a database holding other databases. */ + if (LF_ISSET(DB_SALVAGE | DB_VERIFY_PARTITION) == DB_SALVAGE && + (!has_subdbs || F_ISSET(vdp, SALVAGE_PRINTFOOTER))) + (void)__db_prfooter(handle, callback); + +done: err: + /* Send feedback that we're done. */ + if (!LF_ISSET(DB_SALVAGE) && dbp->db_feedback != NULL) + dbp->db_feedback(dbp, DB_VERIFY, 100); + + if (LF_ISSET(DB_SALVAGE) && + (t_ret = __db_salvage_destroy(vdp)) != 0 && ret == 0) + ret = t_ret; + if (fhp != NULL && + (t_ret = __os_closehandle(env, fhp)) != 0 && ret == 0) + ret = t_ret; + if (vdp != NULL && + (t_ret = __db_vrfy_dbinfo_destroy(env, vdp)) != 0 && ret == 0) + ret = t_ret; + if (real_name != NULL) + __os_free(env, real_name); + + /* + * DB_VERIFY_FATAL is a private error, translate to a public one. + * + * If we didn't find a page, it's probably a page number was corrupted. + * Return the standard corruption error. + * + * Otherwise, if we found corruption along the way, set the return. + */ + if (ret == DB_VERIFY_FATAL || + ret == DB_PAGE_NOTFOUND || (ret == 0 && isbad == 1)) + ret = DB_VERIFY_BAD; + + /* Make sure there's a public complaint if we found corruption. */ + if (ret != 0) + __db_err(env, ret, "%s", name); + + return (ret); +} + +/* + * __db_vrfy_pagezero -- + * Verify the master metadata page. Use seek, read, and a local buffer + * rather than the DB paging code, for safety. + * + * Must correctly (or best-guess) set dbp->type and dbp->pagesize. + */ +static int +__db_vrfy_pagezero(dbp, vdp, fhp, flags) + DB *dbp; + VRFY_DBINFO *vdp; + DB_FH *fhp; + u_int32_t flags; +{ + DBMETA *meta; + ENV *env; + VRFY_PAGEINFO *pip; + db_pgno_t freelist; + size_t nr; + int isbad, ret, swapped; + u_int8_t mbuf[DBMETASIZE]; + + isbad = ret = swapped = 0; + freelist = 0; + env = dbp->env; + meta = (DBMETA *)mbuf; + dbp->type = DB_UNKNOWN; + + if ((ret = __db_vrfy_getpageinfo(vdp, PGNO_BASE_MD, &pip)) != 0) + return (ret); + + /* + * Seek to the metadata page. + * Note that if we're just starting a verification, dbp->pgsize + * may be zero; this is okay, as we want page zero anyway and + * 0*0 == 0. + */ + if ((ret = __os_seek(env, fhp, 0, 0, 0)) != 0 || + (ret = __os_read(env, fhp, mbuf, DBMETASIZE, &nr)) != 0) { + __db_err(env, ret, + "Metadata page %lu cannot be read", (u_long)PGNO_BASE_MD); + return (ret); + } + + if (nr != DBMETASIZE) { + EPRINT((env, + "Page %lu: Incomplete metadata page", + (u_long)PGNO_BASE_MD)); + return (DB_VERIFY_FATAL); + } + + if ((ret = __db_chk_meta(env, dbp, meta, 1)) != 0) { + EPRINT((env, + "Page %lu: metadata page corrupted", (u_long)PGNO_BASE_MD)); + isbad = 1; + if (ret != -1) { + EPRINT((env, + "Page %lu: could not check metadata page", + (u_long)PGNO_BASE_MD)); + return (DB_VERIFY_FATAL); + } + } + + /* + * Check all of the fields that we can. + * + * 08-11: Current page number. Must == pgno. + * Note that endianness doesn't matter--it's zero. + */ + if (meta->pgno != PGNO_BASE_MD) { + isbad = 1; + EPRINT((env, "Page %lu: pgno incorrectly set to %lu", + (u_long)PGNO_BASE_MD, (u_long)meta->pgno)); + } + + /* 12-15: Magic number. Must be one of valid set. */ + if (__db_is_valid_magicno(meta->magic, &dbp->type)) + swapped = 0; + else { + M_32_SWAP(meta->magic); + if (__db_is_valid_magicno(meta->magic, + &dbp->type)) + swapped = 1; + else { + isbad = 1; + EPRINT((env, + "Page %lu: bad magic number %lu", + (u_long)PGNO_BASE_MD, (u_long)meta->magic)); + } + } + + /* + * 16-19: Version. Must be current; for now, we + * don't support verification of old versions. + */ + if (swapped) + M_32_SWAP(meta->version); + if ((dbp->type == DB_BTREE && + (meta->version > DB_BTREEVERSION || + meta->version < DB_BTREEOLDVER)) || + (dbp->type == DB_HASH && + (meta->version > DB_HASHVERSION || + meta->version < DB_HASHOLDVER)) || + (dbp->type == DB_QUEUE && + (meta->version > DB_QAMVERSION || + meta->version < DB_QAMOLDVER))) { + isbad = 1; + EPRINT((env, + "Page %lu: unsupported DB version %lu; extraneous errors may result", + (u_long)PGNO_BASE_MD, (u_long)meta->version)); + } + + /* + * 20-23: Pagesize. Must be power of two, + * greater than 512, and less than 64K. + */ + if (swapped) + M_32_SWAP(meta->pagesize); + if (IS_VALID_PAGESIZE(meta->pagesize)) + dbp->pgsize = meta->pagesize; + else { + isbad = 1; + EPRINT((env, "Page %lu: bad page size %lu", + (u_long)PGNO_BASE_MD, (u_long)meta->pagesize)); + + /* + * Now try to settle on a pagesize to use. + * If the user-supplied one is reasonable, + * use it; else, guess. + */ + if (!IS_VALID_PAGESIZE(dbp->pgsize)) + dbp->pgsize = __db_guesspgsize(env, fhp); + } + + /* + * 25: Page type. Must be correct for dbp->type, + * which is by now set as well as it can be. + */ + /* Needs no swapping--only one byte! */ + if ((dbp->type == DB_BTREE && meta->type != P_BTREEMETA) || + (dbp->type == DB_HASH && meta->type != P_HASHMETA) || + (dbp->type == DB_QUEUE && meta->type != P_QAMMETA)) { + isbad = 1; + EPRINT((env, "Page %lu: bad page type %lu", + (u_long)PGNO_BASE_MD, (u_long)meta->type)); + } + + /* + * 26: Meta-flags. + */ + if (meta->metaflags != 0) { + if (FLD_ISSET(meta->metaflags, + ~(DBMETA_CHKSUM|DBMETA_PART_RANGE|DBMETA_PART_CALLBACK))) { + isbad = 1; + EPRINT((env, + "Page %lu: bad meta-data flags value %#lx", + (u_long)PGNO_BASE_MD, (u_long)meta->metaflags)); + } + if (FLD_ISSET(meta->metaflags, DBMETA_CHKSUM)) + F_SET(pip, VRFY_HAS_CHKSUM); + if (FLD_ISSET(meta->metaflags, DBMETA_PART_RANGE)) + F_SET(pip, VRFY_HAS_PART_RANGE); + if (FLD_ISSET(meta->metaflags, DBMETA_PART_CALLBACK)) + F_SET(pip, VRFY_HAS_PART_CALLBACK); + + if (FLD_ISSET(meta->metaflags, + DBMETA_PART_RANGE | DBMETA_PART_CALLBACK) && + (ret = __partition_init(dbp, meta->metaflags)) != 0) + return (ret); + } + + /* + * 28-31: Free list page number. + * 32-35: Last page in database file. + * We'll verify its sensibility when we do inter-page + * verification later; for now, just store it. + */ + if (swapped) + M_32_SWAP(meta->free); + freelist = meta->free; + if (swapped) + M_32_SWAP(meta->last_pgno); + vdp->meta_last_pgno = meta->last_pgno; + + /* + * Initialize vdp->pages to fit a single pageinfo structure for + * this one page. We'll realloc later when we know how many + * pages there are. + */ + pip->pgno = PGNO_BASE_MD; + pip->type = meta->type; + + /* + * Signal that we still have to check the info specific to + * a given type of meta page. + */ + F_SET(pip, VRFY_INCOMPLETE); + + pip->free = freelist; + + if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0) + return (ret); + + /* Set up the dbp's fileid. We don't use the regular open path. */ + memcpy(dbp->fileid, meta->uid, DB_FILE_ID_LEN); + + if (swapped == 1) + F_SET(dbp, DB_AM_SWAP); + + return (isbad ? DB_VERIFY_BAD : 0); +} + +/* + * __db_vrfy_walkpages -- + * Main loop of the verifier/salvager. Walks through, + * page by page, and verifies all pages and/or prints all data pages. + */ +static int +__db_vrfy_walkpages(dbp, vdp, handle, callback, flags) + DB *dbp; + VRFY_DBINFO *vdp; + void *handle; + int (*callback) __P((void *, const void *)); + u_int32_t flags; +{ + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *h; + VRFY_PAGEINFO *pip; + db_pgno_t i; + int ret, t_ret, isbad; + + env = dbp->env; + mpf = dbp->mpf; + h = NULL; + ret = isbad = t_ret = 0; + + for (i = 0; i <= vdp->last_pgno; i++) { + /* + * If DB_SALVAGE is set, we inspect our database of completed + * pages, and skip any we've already printed in the subdb pass. + */ + if (LF_ISSET(DB_SALVAGE) && (__db_salvage_isdone(vdp, i) != 0)) + continue; + + /* + * An individual page get can fail if: + * * This is a hash database, it is expected to find + * empty buckets, which don't have allocated pages. Create + * a dummy page so the verification can proceed. + * * We are salvaging, flag the error and continue. + */ + if ((t_ret = __memp_fget(mpf, &i, + vdp->thread_info, NULL, 0, &h)) != 0) { + if (dbp->type == DB_HASH) { + if ((t_ret = + __db_vrfy_getpageinfo(vdp, i, &pip)) != 0) + goto err1; + pip->type = P_INVALID; + pip->pgno = i; + F_CLR(pip, VRFY_IS_ALLZEROES); + if ((t_ret = __db_vrfy_putpageinfo( + env, vdp, pip)) != 0) + goto err1; + continue; + } + if (t_ret == DB_PAGE_NOTFOUND) { + EPRINT((env, + "Page %lu: beyond the end of the file, metadata page has last page as %lu", + (u_long)i, (u_long)vdp->last_pgno)); + if (ret == 0) + return (t_ret); + } + +err1: if (ret == 0) + ret = t_ret; + if (LF_ISSET(DB_SALVAGE)) + continue; + return (ret); + } + + if (LF_ISSET(DB_SALVAGE)) { + /* + * We pretty much don't want to quit unless a + * bomb hits. May as well return that something + * was screwy, however. + */ + if ((t_ret = __db_salvage_pg(dbp, + vdp, i, h, handle, callback, flags)) != 0) { + if (ret == 0) + ret = t_ret; + isbad = 1; + } + } else { + /* + * If we are not salvaging, and we get any error + * other than DB_VERIFY_BAD, return immediately; + * it may not be safe to proceed. If we get + * DB_VERIFY_BAD, keep going; listing more errors + * may make it easier to diagnose problems and + * determine the magnitude of the corruption. + * + * Verify info common to all page types. + */ + if (i != PGNO_BASE_MD) { + ret = __db_vrfy_common(dbp, vdp, h, i, flags); + if (ret == DB_VERIFY_BAD) + isbad = 1; + else if (ret != 0) + goto err; + } + + switch (TYPE(h)) { + case P_INVALID: + ret = __db_vrfy_invalid(dbp, vdp, h, i, flags); + break; + case __P_DUPLICATE: + isbad = 1; + EPRINT((env, + "Page %lu: old-style duplicate page", + (u_long)i)); + break; + case P_HASH_UNSORTED: + case P_HASH: + ret = __ham_vrfy(dbp, vdp, h, i, flags); + break; + case P_IBTREE: + case P_IRECNO: + case P_LBTREE: + case P_LDUP: + ret = __bam_vrfy(dbp, vdp, h, i, flags); + break; + case P_LRECNO: + ret = __ram_vrfy_leaf(dbp, vdp, h, i, flags); + break; + case P_OVERFLOW: + ret = __db_vrfy_overflow(dbp, vdp, h, i, flags); + break; + case P_HASHMETA: + ret = __ham_vrfy_meta(dbp, + vdp, (HMETA *)h, i, flags); + break; + case P_BTREEMETA: + ret = __bam_vrfy_meta(dbp, + vdp, (BTMETA *)h, i, flags); + break; + case P_QAMMETA: + ret = __qam_vrfy_meta(dbp, + vdp, (QMETA *)h, i, flags); + break; + case P_QAMDATA: + ret = __qam_vrfy_data(dbp, + vdp, (QPAGE *)h, i, flags); + break; + default: + EPRINT((env, + "Page %lu: unknown page type %lu", + (u_long)i, (u_long)TYPE(h))); + isbad = 1; + break; + } + + /* + * Set up error return. + */ + if (ret == DB_VERIFY_BAD) + isbad = 1; + else if (ret != 0) + goto err; + + /* + * Provide feedback to the application about our + * progress. The range 0-50% comes from the fact + * that this is the first of two passes through the + * database (front-to-back, then top-to-bottom). + */ + if (dbp->db_feedback != NULL) + dbp->db_feedback(dbp, DB_VERIFY, + (int)((i + 1) * 50 / (vdp->last_pgno + 1))); + } + + /* + * Just as with the page get, bail if and only if we're + * not salvaging. + */ + if ((t_ret = __memp_fput(mpf, + vdp->thread_info, h, dbp->priority)) != 0) { + if (ret == 0) + ret = t_ret; + if (!LF_ISSET(DB_SALVAGE)) + return (ret); + } + } + + /* + * If we've seen a Queue metadata page, we may need to walk Queue + * extent pages that won't show up between 0 and vdp->last_pgno. + */ + if (F_ISSET(vdp, VRFY_QMETA_SET) && (t_ret = + __qam_vrfy_walkqueue(dbp, vdp, handle, callback, flags)) != 0) { + if (ret == 0) + ret = t_ret; + if (t_ret == DB_VERIFY_BAD) + isbad = 1; + else if (!LF_ISSET(DB_SALVAGE)) + return (ret); + } + + if (0) { +err: if (h != NULL && (t_ret = __memp_fput(mpf, + vdp->thread_info, h, dbp->priority)) != 0) + return (ret == 0 ? t_ret : ret); + } + + return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret); +} + +/* + * __db_vrfy_structure-- + * After a beginning-to-end walk through the database has been + * completed, put together the information that has been collected + * to verify the overall database structure. + * + * Should only be called if we want to do a database verification, + * i.e. if DB_SALVAGE is not set. + */ +static int +__db_vrfy_structure(dbp, vdp, dbname, meta_pgno, lp, rp, flags) + DB *dbp; + VRFY_DBINFO *vdp; + const char *dbname; + db_pgno_t meta_pgno; + void *lp, *rp; + u_int32_t flags; +{ + DB *pgset; + ENV *env; + VRFY_PAGEINFO *pip; + db_pgno_t i; + int ret, isbad, hassubs, p; + + isbad = 0; + pip = NULL; + env = dbp->env; + pgset = vdp->pgset; + + /* + * Providing feedback here is tricky; in most situations, + * we fetch each page one more time, but we do so in a top-down + * order that depends on the access method. Worse, we do this + * recursively in btree, such that on any call where we're traversing + * a subtree we don't know where that subtree is in the whole database; + * worse still, any given database may be one of several subdbs. + * + * The solution is to decrement a counter vdp->pgs_remaining each time + * we verify (and call feedback on) a page. We may over- or + * under-count, but the structure feedback function will ensure that we + * never give a percentage under 50 or over 100. (The first pass + * covered the range 0-50%.) + */ + if (dbp->db_feedback != NULL) + vdp->pgs_remaining = vdp->last_pgno + 1; + + /* + * Call the appropriate function to downwards-traverse the db type. + */ + switch (dbp->type) { + case DB_BTREE: + case DB_RECNO: + if ((ret = + __bam_vrfy_structure(dbp, vdp, 0, lp, rp, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + + /* + * If we have subdatabases and we know that the database is, + * thus far, sound, it's safe to walk the tree of subdatabases. + * Do so, and verify the structure of the databases within. + */ + if ((ret = __db_vrfy_getpageinfo(vdp, 0, &pip)) != 0) + goto err; + hassubs = F_ISSET(pip, VRFY_HAS_SUBDBS) ? 1 : 0; + if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0) + goto err; + pip = NULL; + + if (isbad == 0 && hassubs) + if ((ret = + __db_vrfy_subdbs(dbp, vdp, dbname, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + break; + case DB_HASH: + if ((ret = __ham_vrfy_structure(dbp, vdp, 0, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + break; + case DB_QUEUE: + if ((ret = __qam_vrfy_structure(dbp, vdp, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + } + + /* + * Queue pages may be unreferenced and totally zeroed, if + * they're empty; queue doesn't have much structure, so + * this is unlikely to be wrong in any troublesome sense. + * Skip to "err". + */ + goto err; + case DB_UNKNOWN: + default: + ret = __db_unknown_path(env, "__db_vrfy_structure"); + goto err; + } + + /* Walk free list. */ + if ((ret = + __db_vrfy_freelist(dbp, vdp, meta_pgno, flags)) == DB_VERIFY_BAD) + isbad = 1; + + /* + * If structure checks up until now have failed, it's likely that + * checking what pages have been missed will result in oodles of + * extraneous error messages being EPRINTed. Skip to the end + * if this is the case; we're going to be printing at least one + * error anyway, and probably all the more salient ones. + */ + if (ret != 0 || isbad == 1) + goto err; + + /* + * Make sure no page has been missed and that no page is still marked + * "all zeroes" (only certain hash pages can be, and they're unmarked + * in __ham_vrfy_structure). + */ + for (i = 0; i < vdp->last_pgno + 1; i++) { + if ((ret = __db_vrfy_getpageinfo(vdp, i, &pip)) != 0) + goto err; + if ((ret = __db_vrfy_pgset_get(pgset, + vdp->thread_info, i, &p)) != 0) + goto err; + if (pip->type == P_OVERFLOW) { + if ((u_int32_t)p != pip->refcount) { + EPRINT((env, + "Page %lu: overflow refcount %lu, referenced %lu times", + (u_long)i, + (u_long)pip->refcount, (u_long)p)); + isbad = 1; + } + } else if (p == 0 && +#ifndef HAVE_FTRUNCATE + !(i > vdp->meta_last_pgno && + (F_ISSET(pip, VRFY_IS_ALLZEROES) || pip->type == P_HASH)) && +#endif + !(dbp->type == DB_HASH && pip->type == P_INVALID)) { + /* + * It is OK for unreferenced hash buckets to be + * marked invalid and unreferenced. + */ + EPRINT((env, + "Page %lu: unreferenced page", (u_long)i)); + isbad = 1; + } + + if (F_ISSET(pip, VRFY_IS_ALLZEROES) +#ifndef HAVE_FTRUNCATE + && i <= vdp->meta_last_pgno +#endif + ) { + EPRINT((env, + "Page %lu: totally zeroed page", (u_long)i)); + isbad = 1; + } + if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0) + goto err; + pip = NULL; + } + +err: if (pip != NULL) + (void)__db_vrfy_putpageinfo(env, vdp, pip); + + return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret); +} + +/* + * __db_is_valid_magicno + */ +static int +__db_is_valid_magicno(magic, typep) + u_int32_t magic; + DBTYPE *typep; +{ + switch (magic) { + case DB_BTREEMAGIC: + *typep = DB_BTREE; + return (1); + case DB_HASHMAGIC: + *typep = DB_HASH; + return (1); + case DB_QAMMAGIC: + *typep = DB_QUEUE; + return (1); + default: + break; + } + *typep = DB_UNKNOWN; + return (0); +} + +/* + * __db_vrfy_common -- + * Verify info common to all page types. + * + * PUBLIC: int __db_vrfy_common + * PUBLIC: __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); + */ +int +__db_vrfy_common(dbp, vdp, h, pgno, flags) + DB *dbp; + VRFY_DBINFO *vdp; + PAGE *h; + db_pgno_t pgno; + u_int32_t flags; +{ + ENV *env; + VRFY_PAGEINFO *pip; + int ret, t_ret; + u_int8_t *p; + + env = dbp->env; + + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + + pip->pgno = pgno; + F_CLR(pip, VRFY_IS_ALLZEROES); + + /* + * Hash expands the table by leaving some pages between the + * old last and the new last totally zeroed. These pages may + * not be all zero if they were used, freed and then reallocated. + * + * Queue will create sparse files if sparse record numbers are used. + */ + if (pgno != 0 && PGNO(h) == 0) { + F_SET(pip, VRFY_IS_ALLZEROES); + for (p = (u_int8_t *)h; p < (u_int8_t *)h + dbp->pgsize; p++) + if (*p != 0) { + F_CLR(pip, VRFY_IS_ALLZEROES); + break; + } + /* + * Mark it as a hash, and we'll + * check that that makes sense structurally later. + * (The queue verification doesn't care, since queues + * don't really have much in the way of structure.) + */ + pip->type = P_HASH; + ret = 0; + goto err; /* well, not really an err. */ + } + + if (PGNO(h) != pgno) { + EPRINT((env, "Page %lu: bad page number %lu", + (u_long)pgno, (u_long)h->pgno)); + ret = DB_VERIFY_BAD; + } + + switch (h->type) { + case P_INVALID: /* Order matches ordinal value. */ + case P_HASH_UNSORTED: + case P_IBTREE: + case P_IRECNO: + case P_LBTREE: + case P_LRECNO: + case P_OVERFLOW: + case P_HASHMETA: + case P_BTREEMETA: + case P_QAMMETA: + case P_QAMDATA: + case P_LDUP: + case P_HASH: + break; + default: + EPRINT((env, "Page %lu: bad page type %lu", + (u_long)pgno, (u_long)h->type)); + ret = DB_VERIFY_BAD; + } + pip->type = h->type; + +err: if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + + return (ret); +} + +/* + * __db_vrfy_invalid -- + * Verify P_INVALID page. + * (Yes, there's not much to do here.) + */ +static int +__db_vrfy_invalid(dbp, vdp, h, pgno, flags) + DB *dbp; + VRFY_DBINFO *vdp; + PAGE *h; + db_pgno_t pgno; + u_int32_t flags; +{ + ENV *env; + VRFY_PAGEINFO *pip; + int ret, t_ret; + + env = dbp->env; + + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + pip->next_pgno = pip->prev_pgno = 0; + + if (!IS_VALID_PGNO(NEXT_PGNO(h))) { + EPRINT((env, "Page %lu: invalid next_pgno %lu", + (u_long)pgno, (u_long)NEXT_PGNO(h))); + ret = DB_VERIFY_BAD; + } else + pip->next_pgno = NEXT_PGNO(h); + + if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +/* + * __db_vrfy_datapage -- + * Verify elements common to data pages (P_HASH, P_LBTREE, + * P_IBTREE, P_IRECNO, P_LRECNO, P_OVERFLOW, P_DUPLICATE)--i.e., + * those defined in the PAGE structure. + * + * Called from each of the per-page routines, after the + * all-page-type-common elements of pip have been verified and filled + * in. + * + * PUBLIC: int __db_vrfy_datapage + * PUBLIC: __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); + */ +int +__db_vrfy_datapage(dbp, vdp, h, pgno, flags) + DB *dbp; + VRFY_DBINFO *vdp; + PAGE *h; + db_pgno_t pgno; + u_int32_t flags; +{ + ENV *env; + VRFY_PAGEINFO *pip; + u_int32_t smallest_entry; + int isbad, ret, t_ret; + + env = dbp->env; + + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + isbad = 0; + + /* + * prev_pgno and next_pgno: store for inter-page checks, + * verify that they point to actual pages and not to self. + * + * !!! + * Internal btree pages do not maintain these fields (indeed, + * they overload them). Skip. + */ + if (TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO) { + if (!IS_VALID_PGNO(PREV_PGNO(h)) || PREV_PGNO(h) == pip->pgno) { + isbad = 1; + EPRINT((env, "Page %lu: invalid prev_pgno %lu", + (u_long)pip->pgno, (u_long)PREV_PGNO(h))); + } + if (!IS_VALID_PGNO(NEXT_PGNO(h)) || NEXT_PGNO(h) == pip->pgno) { + isbad = 1; + EPRINT((env, "Page %lu: invalid next_pgno %lu", + (u_long)pip->pgno, (u_long)NEXT_PGNO(h))); + } + pip->prev_pgno = PREV_PGNO(h); + pip->next_pgno = NEXT_PGNO(h); + } + + /* + * Verify the number of entries on the page: there's no good way to + * determine if this is accurate. The best we can do is verify that + * it's not more than can, in theory, fit on the page. Then, we make + * sure there are at least this many valid elements in inp[], and + * hope the test catches most cases. + */ + switch (TYPE(h)) { + case P_HASH_UNSORTED: + case P_HASH: + smallest_entry = HKEYDATA_PSIZE(0); + break; + case P_IBTREE: + smallest_entry = BINTERNAL_PSIZE(0); + break; + case P_IRECNO: + smallest_entry = RINTERNAL_PSIZE; + break; + case P_LBTREE: + case P_LDUP: + case P_LRECNO: + smallest_entry = BKEYDATA_PSIZE(0); + break; + default: + smallest_entry = 0; + break; + } + if (smallest_entry * NUM_ENT(h) / 2 > dbp->pgsize) { + isbad = 1; + EPRINT((env, "Page %lu: too many entries: %lu", + (u_long)pgno, (u_long)NUM_ENT(h))); + } + + if (TYPE(h) != P_OVERFLOW) + pip->entries = NUM_ENT(h); + + /* + * btree level. Should be zero unless we're a btree; + * if we are a btree, should be between LEAFLEVEL and MAXBTREELEVEL, + * and we need to save it off. + */ + switch (TYPE(h)) { + case P_IBTREE: + case P_IRECNO: + if (LEVEL(h) < LEAFLEVEL + 1) { + isbad = 1; + EPRINT((env, "Page %lu: bad btree level %lu", + (u_long)pgno, (u_long)LEVEL(h))); + } + pip->bt_level = LEVEL(h); + break; + case P_LBTREE: + case P_LDUP: + case P_LRECNO: + if (LEVEL(h) != LEAFLEVEL) { + isbad = 1; + EPRINT((env, + "Page %lu: btree leaf page has incorrect level %lu", + (u_long)pgno, (u_long)LEVEL(h))); + } + break; + default: + if (LEVEL(h) != 0) { + isbad = 1; + EPRINT((env, + "Page %lu: nonzero level %lu in non-btree database", + (u_long)pgno, (u_long)LEVEL(h))); + } + break; + } + + /* + * Even though inp[] occurs in all PAGEs, we look at it in the + * access-method-specific code, since btree and hash treat + * item lengths very differently, and one of the most important + * things we want to verify is that the data--as specified + * by offset and length--cover the right part of the page + * without overlaps, gaps, or violations of the page boundary. + */ + if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); +} + +/* + * __db_vrfy_meta-- + * Verify the access-method common parts of a meta page, using + * normal mpool routines. + * + * PUBLIC: int __db_vrfy_meta + * PUBLIC: __P((DB *, VRFY_DBINFO *, DBMETA *, db_pgno_t, u_int32_t)); + */ +int +__db_vrfy_meta(dbp, vdp, meta, pgno, flags) + DB *dbp; + VRFY_DBINFO *vdp; + DBMETA *meta; + db_pgno_t pgno; + u_int32_t flags; +{ + DBTYPE dbtype, magtype; + ENV *env; + VRFY_PAGEINFO *pip; + int isbad, ret, t_ret; + + isbad = 0; + env = dbp->env; + + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + + /* type plausible for a meta page */ + switch (meta->type) { + case P_BTREEMETA: + dbtype = DB_BTREE; + break; + case P_HASHMETA: + dbtype = DB_HASH; + break; + case P_QAMMETA: + dbtype = DB_QUEUE; + break; + default: + ret = __db_unknown_path(env, "__db_vrfy_meta"); + goto err; + } + + /* magic number valid */ + if (!__db_is_valid_magicno(meta->magic, &magtype)) { + isbad = 1; + EPRINT((env, + "Page %lu: invalid magic number", (u_long)pgno)); + } + if (magtype != dbtype) { + isbad = 1; + EPRINT((env, + "Page %lu: magic number does not match database type", + (u_long)pgno)); + } + + /* version */ + if ((dbtype == DB_BTREE && + (meta->version > DB_BTREEVERSION || + meta->version < DB_BTREEOLDVER)) || + (dbtype == DB_HASH && + (meta->version > DB_HASHVERSION || + meta->version < DB_HASHOLDVER)) || + (dbtype == DB_QUEUE && + (meta->version > DB_QAMVERSION || + meta->version < DB_QAMOLDVER))) { + isbad = 1; + EPRINT((env, + "Page %lu: unsupported database version %lu; extraneous errors may result", + (u_long)pgno, (u_long)meta->version)); + } + + /* pagesize */ + if (meta->pagesize != dbp->pgsize) { + isbad = 1; + EPRINT((env, "Page %lu: invalid pagesize %lu", + (u_long)pgno, (u_long)meta->pagesize)); + } + + /* Flags */ + if (meta->metaflags != 0) { + if (FLD_ISSET(meta->metaflags, + ~(DBMETA_CHKSUM|DBMETA_PART_RANGE|DBMETA_PART_CALLBACK))) { + isbad = 1; + EPRINT((env, + "Page %lu: bad meta-data flags value %#lx", + (u_long)PGNO_BASE_MD, (u_long)meta->metaflags)); + } + if (FLD_ISSET(meta->metaflags, DBMETA_CHKSUM)) + F_SET(pip, VRFY_HAS_CHKSUM); + if (FLD_ISSET(meta->metaflags, DBMETA_PART_RANGE)) + F_SET(pip, VRFY_HAS_PART_RANGE); + if (FLD_ISSET(meta->metaflags, DBMETA_PART_CALLBACK)) + F_SET(pip, VRFY_HAS_PART_CALLBACK); + } + + /* + * Free list. + * + * If this is not the main, master-database meta page, it + * should not have a free list. + */ + if (pgno != PGNO_BASE_MD && meta->free != PGNO_INVALID) { + isbad = 1; + EPRINT((env, + "Page %lu: nonempty free list on subdatabase metadata page", + (u_long)pgno)); + } + + /* Can correctly be PGNO_INVALID--that's just the end of the list. */ + if (meta->free != PGNO_INVALID && IS_VALID_PGNO(meta->free)) + pip->free = meta->free; + else if (!IS_VALID_PGNO(meta->free)) { + isbad = 1; + EPRINT((env, + "Page %lu: nonsensical free list pgno %lu", + (u_long)pgno, (u_long)meta->free)); + } + + /* + * Check that the meta page agrees with what we got from mpool. + * If we don't have FTRUNCATE then mpool could include some + * zeroed pages at the end of the file, we assume the meta page + * is correct. + */ + if (pgno == PGNO_BASE_MD && meta->last_pgno != vdp->last_pgno) { +#ifdef HAVE_FTRUNCATE + isbad = 1; + EPRINT((env, + "Page %lu: last_pgno is not correct: %lu != %lu", + (u_long)pgno, + (u_long)meta->last_pgno, (u_long)vdp->last_pgno)); +#endif + vdp->meta_last_pgno = meta->last_pgno; + } + + /* + * We have now verified the common fields of the metadata page. + * Clear the flag that told us they had been incompletely checked. + */ + F_CLR(pip, VRFY_INCOMPLETE); + +err: if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); +} + +/* + * __db_vrfy_freelist -- + * Walk free list, checking off pages and verifying absence of + * loops. + */ +static int +__db_vrfy_freelist(dbp, vdp, meta, flags) + DB *dbp; + VRFY_DBINFO *vdp; + db_pgno_t meta; + u_int32_t flags; +{ + DB *pgset; + ENV *env; + VRFY_PAGEINFO *pip; + db_pgno_t cur_pgno, next_pgno; + int p, ret, t_ret; + + env = dbp->env; + pgset = vdp->pgset; + DB_ASSERT(env, pgset != NULL); + + if ((ret = __db_vrfy_getpageinfo(vdp, meta, &pip)) != 0) + return (ret); + for (next_pgno = pip->free; + next_pgno != PGNO_INVALID; next_pgno = pip->next_pgno) { + cur_pgno = pip->pgno; + if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0) + return (ret); + + /* This shouldn't happen, but just in case. */ + if (!IS_VALID_PGNO(next_pgno)) { + EPRINT((env, + "Page %lu: invalid next_pgno %lu on free list page", + (u_long)cur_pgno, (u_long)next_pgno)); + return (DB_VERIFY_BAD); + } + + /* Detect cycles. */ + if ((ret = __db_vrfy_pgset_get(pgset, + vdp->thread_info, next_pgno, &p)) != 0) + return (ret); + if (p != 0) { + EPRINT((env, + "Page %lu: page %lu encountered a second time on free list", + (u_long)cur_pgno, (u_long)next_pgno)); + return (DB_VERIFY_BAD); + } + if ((ret = __db_vrfy_pgset_inc(pgset, + vdp->thread_info, next_pgno)) != 0) + return (ret); + + if ((ret = __db_vrfy_getpageinfo(vdp, next_pgno, &pip)) != 0) + return (ret); + + if (pip->type != P_INVALID) { + EPRINT((env, + "Page %lu: non-invalid page %lu on free list", + (u_long)cur_pgno, (u_long)next_pgno)); + ret = DB_VERIFY_BAD; /* unsafe to continue */ + break; + } + } + + if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0) + ret = t_ret; + return (ret); +} + +/* + * __db_vrfy_subdbs -- + * Walk the known-safe master database of subdbs with a cursor, + * verifying the structure of each subdatabase we encounter. + */ +static int +__db_vrfy_subdbs(dbp, vdp, dbname, flags) + DB *dbp; + VRFY_DBINFO *vdp; + const char *dbname; + u_int32_t flags; +{ + DB *mdbp; + DBC *dbc; + DBT key, data; + ENV *env; + VRFY_PAGEINFO *pip; + db_pgno_t meta_pgno; + int ret, t_ret, isbad; + u_int8_t type; + + isbad = 0; + dbc = NULL; + env = dbp->env; + + if ((ret = __db_master_open(dbp, + vdp->thread_info, NULL, dbname, DB_RDONLY, 0, &mdbp)) != 0) + return (ret); + + if ((ret = __db_cursor_int(mdbp, NULL, + NULL, DB_BTREE, PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0) + goto err; + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + while ((ret = __dbc_get(dbc, &key, &data, DB_NEXT)) == 0) { + if (data.size != sizeof(db_pgno_t)) { + EPRINT((env, + "Subdatabase entry not page-number size")); + isbad = 1; + goto err; + } + memcpy(&meta_pgno, data.data, data.size); + /* + * Subdatabase meta pgnos are stored in network byte + * order for cross-endian compatibility. Swap if appropriate. + */ + DB_NTOHL_SWAP(env, &meta_pgno); + if (meta_pgno == PGNO_INVALID || meta_pgno > vdp->last_pgno) { + EPRINT((env, + "Subdatabase entry references invalid page %lu", + (u_long)meta_pgno)); + isbad = 1; + goto err; + } + if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &pip)) != 0) + goto err; + type = pip->type; + if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0) + goto err; + switch (type) { + case P_BTREEMETA: + if ((ret = __bam_vrfy_structure( + dbp, vdp, meta_pgno, NULL, NULL, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + break; + case P_HASHMETA: + if ((ret = __ham_vrfy_structure( + dbp, vdp, meta_pgno, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + break; + case P_QAMMETA: + default: + EPRINT((env, + "Subdatabase entry references page %lu of invalid type %lu", + (u_long)meta_pgno, (u_long)type)); + ret = DB_VERIFY_BAD; + goto err; + } + } + + if (ret == DB_NOTFOUND) + ret = 0; + +err: if (dbc != NULL && (t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + + if ((t_ret = __db_close(mdbp, NULL, 0)) != 0 && ret == 0) + ret = t_ret; + + return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); +} + +/* + * __db_vrfy_struct_feedback -- + * Provide feedback during top-down database structure traversal. + * (See comment at the beginning of __db_vrfy_structure.) + * + * PUBLIC: void __db_vrfy_struct_feedback __P((DB *, VRFY_DBINFO *)); + */ +void +__db_vrfy_struct_feedback(dbp, vdp) + DB *dbp; + VRFY_DBINFO *vdp; +{ + int progress; + + if (dbp->db_feedback == NULL) + return; + + if (vdp->pgs_remaining > 0) + vdp->pgs_remaining--; + + /* Don't allow a feedback call of 100 until we're really done. */ + progress = 100 - (int)(vdp->pgs_remaining * 50 / (vdp->last_pgno + 1)); + dbp->db_feedback(dbp, DB_VERIFY, progress == 100 ? 99 : progress); +} + +/* + * __db_vrfy_orderchkonly -- + * Do an sort-order/hashing check on a known-otherwise-good subdb. + */ +static int +__db_vrfy_orderchkonly(dbp, vdp, name, subdb, flags) + DB *dbp; + VRFY_DBINFO *vdp; + const char *name, *subdb; + u_int32_t flags; +{ + BTMETA *btmeta; + DB *mdbp, *pgset; + DBC *pgsc; + DBT key, data; + DB_MPOOLFILE *mpf; + ENV *env; + HASH *h_internal; + HMETA *hmeta; + PAGE *h, *currpg; + db_pgno_t meta_pgno, p, pgno; + u_int32_t bucket; + int t_ret, ret; + + pgset = NULL; + pgsc = NULL; + env = dbp->env; + mpf = dbp->mpf; + currpg = h = NULL; + + LF_CLR(DB_NOORDERCHK); + + /* Open the master database and get the meta_pgno for the subdb. */ + if ((ret = __db_master_open(dbp, + vdp->thread_info, NULL, name, DB_RDONLY, 0, &mdbp)) != 0) + goto err; + + DB_INIT_DBT(key, subdb, strlen(subdb)); + memset(&data, 0, sizeof(data)); + if ((ret = __db_get(mdbp, + vdp->thread_info, NULL, &key, &data, 0)) != 0) { + if (ret == DB_NOTFOUND) + ret = ENOENT; + goto err; + } + + if (data.size != sizeof(db_pgno_t)) { + EPRINT((env, "Subdatabase entry of invalid size")); + ret = DB_VERIFY_BAD; + goto err; + } + + memcpy(&meta_pgno, data.data, data.size); + + /* + * Subdatabase meta pgnos are stored in network byte + * order for cross-endian compatibility. Swap if appropriate. + */ + DB_NTOHL_SWAP(env, &meta_pgno); + + if ((ret = __memp_fget(mpf, + &meta_pgno, vdp->thread_info, NULL, 0, &h)) != 0) + goto err; + + if ((ret = __db_vrfy_pgset(env, + vdp->thread_info, dbp->pgsize, &pgset)) != 0) + goto err; + + switch (TYPE(h)) { + case P_BTREEMETA: + btmeta = (BTMETA *)h; + if (F_ISSET(&btmeta->dbmeta, BTM_RECNO)) { + /* Recnos have no order to check. */ + ret = 0; + goto err; + } + if ((ret = + __db_meta2pgset(dbp, vdp, meta_pgno, flags, pgset)) != 0) + goto err; + if ((ret = __db_cursor_int(pgset, NULL, NULL, dbp->type, + PGNO_INVALID, 0, DB_LOCK_INVALIDID, &pgsc)) != 0) + goto err; + while ((ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) { + if ((ret = __memp_fget(mpf, &p, + vdp->thread_info, NULL, 0, &currpg)) != 0) + goto err; + if ((ret = __bam_vrfy_itemorder(dbp, NULL, + vdp->thread_info, currpg, p, NUM_ENT(currpg), 1, + F_ISSET(&btmeta->dbmeta, BTM_DUP), flags)) != 0) + goto err; + if ((ret = __memp_fput(mpf, + vdp->thread_info, currpg, dbp->priority)) != 0) + goto err; + currpg = NULL; + } + + /* + * The normal exit condition for the loop above is DB_NOTFOUND. + * If we see that, zero it and continue on to cleanup. + * Otherwise, it's a real error and will be returned. + */ + if (ret == DB_NOTFOUND) + ret = 0; + break; + case P_HASHMETA: + hmeta = (HMETA *)h; + h_internal = (HASH *)dbp->h_internal; + /* + * Make sure h_charkey is right. + */ + if (h_internal == NULL) { + EPRINT((env, + "Page %lu: DB->h_internal field is NULL", + (u_long)meta_pgno)); + ret = DB_VERIFY_BAD; + goto err; + } + if (h_internal->h_hash == NULL) + h_internal->h_hash = hmeta->dbmeta.version < 5 + ? __ham_func4 : __ham_func5; + if (hmeta->h_charkey != + h_internal->h_hash(dbp, CHARKEY, sizeof(CHARKEY))) { + EPRINT((env, + "Page %lu: incorrect hash function for database", + (u_long)meta_pgno)); + ret = DB_VERIFY_BAD; + goto err; + } + + /* + * Foreach bucket, verify hashing on each page in the + * corresponding chain of pages. + */ + if ((ret = __db_cursor_int(dbp, NULL, NULL, dbp->type, + PGNO_INVALID, 0, DB_LOCK_INVALIDID, &pgsc)) != 0) + goto err; + for (bucket = 0; bucket <= hmeta->max_bucket; bucket++) { + pgno = BS_TO_PAGE(bucket, hmeta->spares); + while (pgno != PGNO_INVALID) { + if ((ret = __memp_fget(mpf, &pgno, + vdp->thread_info, NULL, 0, &currpg)) != 0) + goto err; + if ((ret = __ham_vrfy_hashing(pgsc, + NUM_ENT(currpg), hmeta, bucket, pgno, + flags, h_internal->h_hash)) != 0) + goto err; + pgno = NEXT_PGNO(currpg); + if ((ret = __memp_fput(mpf, vdp->thread_info, + currpg, dbp->priority)) != 0) + goto err; + currpg = NULL; + } + } + break; + default: + EPRINT((env, "Page %lu: database metapage of bad type %lu", + (u_long)meta_pgno, (u_long)TYPE(h))); + ret = DB_VERIFY_BAD; + break; + } + +err: if (pgsc != NULL && (t_ret = __dbc_close(pgsc)) != 0 && ret == 0) + ret = t_ret; + if (pgset != NULL && + (t_ret = __db_close(pgset, NULL, 0)) != 0 && ret == 0) + ret = t_ret; + if (h != NULL && (t_ret = __memp_fput(mpf, + vdp->thread_info, h, dbp->priority)) != 0) + ret = t_ret; + if (currpg != NULL && + (t_ret = __memp_fput(mpf, + vdp->thread_info, currpg, dbp->priority)) != 0) + ret = t_ret; + if ((t_ret = __db_close(mdbp, NULL, 0)) != 0) + ret = t_ret; + return (ret); +} + +/* + * __db_salvage_pg -- + * Walk through a page, salvaging all likely or plausible (w/ + * DB_AGGRESSIVE) key/data pairs and marking seen pages in vdp. + * + * PUBLIC: int __db_salvage_pg __P((DB *, VRFY_DBINFO *, db_pgno_t, + * PUBLIC: PAGE *, void *, int (*)(void *, const void *), u_int32_t)); + */ +int +__db_salvage_pg(dbp, vdp, pgno, h, handle, callback, flags) + DB *dbp; + VRFY_DBINFO *vdp; + db_pgno_t pgno; + PAGE *h; + void *handle; + int (*callback) __P((void *, const void *)); + u_int32_t flags; +{ + ENV *env; + VRFY_PAGEINFO *pip; + int keyflag, ret, t_ret; + + env = dbp->env; + DB_ASSERT(env, LF_ISSET(DB_SALVAGE)); + + /* + * !!! + * We dump record numbers when salvaging Queue databases, but not for + * immutable Recno databases. The problem is we can't figure out the + * record number from the database page in the Recno case, while the + * offset in the file is sufficient for Queue. + */ + keyflag = 0; + + /* If we got this page in the subdb pass, we can safely skip it. */ + if (__db_salvage_isdone(vdp, pgno)) + return (0); + + switch (TYPE(h)) { + case P_BTREEMETA: + ret = __bam_vrfy_meta(dbp, vdp, (BTMETA *)h, pgno, flags); + break; + case P_HASH: + case P_HASH_UNSORTED: + case P_LBTREE: + case P_QAMDATA: + return (__db_salvage_leaf(dbp, + vdp, pgno, h, handle, callback, flags)); + case P_HASHMETA: + ret = __ham_vrfy_meta(dbp, vdp, (HMETA *)h, pgno, flags); + break; + case P_IBTREE: + /* + * We need to mark any overflow keys on internal pages as seen, + * so we don't print them out in __db_salvage_unknowns. But if + * we're an upgraded database, a P_LBTREE page may very well + * have a reference to the same overflow pages (this practice + * stopped somewhere around db4.5). To give P_LBTREEs a chance + * to print out any keys on shared pages, mark the page now and + * deal with it at the end. + */ + return (__db_salvage_markneeded(vdp, pgno, SALVAGE_IBTREE)); + case P_LDUP: + return (__db_salvage_markneeded(vdp, pgno, SALVAGE_LDUP)); + case P_LRECNO: + /* + * Recno leaves are tough, because the leaf could be (1) a dup + * page, or it could be (2) a regular database leaf page. + * Fortunately, RECNO databases are not allowed to have + * duplicates. + * + * If there are no subdatabases, dump the page immediately if + * it's a leaf in a RECNO database, otherwise wait and hopefully + * it will be dumped by the leaf page that refers to it, + * otherwise we'll get it with the unknowns. + * + * If there are subdatabases, there might be mixed types and + * dbp->type can't be trusted. We'll only get here after + * salvaging each database, though, so salvaging this page + * immediately isn't important. If this page is a dup, it might + * get salvaged later on, otherwise the unknowns pass will pick + * it up. Note that SALVAGE_HASSUBDBS won't get set if we're + * salvaging aggressively. + * + * If we're salvaging aggressively, we don't know whether or not + * there's subdatabases, so we wait on all recno pages. + */ + if (!LF_ISSET(DB_AGGRESSIVE) && + !F_ISSET(vdp, SALVAGE_HASSUBDBS) && dbp->type == DB_RECNO) + return (__db_salvage_leaf(dbp, + vdp, pgno, h, handle, callback, flags)); + return (__db_salvage_markneeded(vdp, pgno, SALVAGE_LRECNODUP)); + case P_OVERFLOW: + return (__db_salvage_markneeded(vdp, pgno, SALVAGE_OVERFLOW)); + case P_QAMMETA: + keyflag = 1; + ret = __qam_vrfy_meta(dbp, vdp, (QMETA *)h, pgno, flags); + break; + case P_INVALID: + case P_IRECNO: + case __P_DUPLICATE: + default: + /* + * There's no need to display an error, the page type was + * already checked and reported on. + */ + return (0); + } + if (ret != 0) + return (ret); + + /* + * We have to display the dump header if it's a metadata page. It's + * our last chance as the page was marked "seen" in the vrfy routine, + * and we won't see the page again. We don't display headers for + * the first database in a multi-database file, that database simply + * contains a list of subdatabases. + */ + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + if (!F_ISSET(pip, VRFY_HAS_SUBDBS) && !LF_ISSET(DB_VERIFY_PARTITION)) + ret = __db_prheader( + dbp, NULL, 0, keyflag, handle, callback, vdp, pgno); + if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +/* + * __db_salvage_leaf -- + * Walk through a leaf, salvaging all likely key/data pairs and marking + * seen pages in vdp. + * + * PUBLIC: int __db_salvage_leaf __P((DB *, VRFY_DBINFO *, db_pgno_t, + * PUBLIC: PAGE *, void *, int (*)(void *, const void *), u_int32_t)); + */ +int +__db_salvage_leaf(dbp, vdp, pgno, h, handle, callback, flags) + DB *dbp; + VRFY_DBINFO *vdp; + db_pgno_t pgno; + PAGE *h; + void *handle; + int (*callback) __P((void *, const void *)); + u_int32_t flags; +{ + ENV *env; + + env = dbp->env; + DB_ASSERT(env, LF_ISSET(DB_SALVAGE)); + + /* If we got this page in the subdb pass, we can safely skip it. */ + if (__db_salvage_isdone(vdp, pgno)) + return (0); + + switch (TYPE(h)) { + case P_HASH_UNSORTED: + case P_HASH: + return (__ham_salvage(dbp, vdp, + pgno, h, handle, callback, flags)); + case P_LBTREE: + case P_LRECNO: + return (__bam_salvage(dbp, vdp, + pgno, TYPE(h), h, handle, callback, NULL, flags)); + case P_QAMDATA: + return (__qam_salvage(dbp, vdp, + pgno, h, handle, callback, flags)); + default: + /* + * There's no need to display an error, the page type was + * already checked and reported on. + */ + return (0); + } +} + +/* + * __db_salvage_unknowns -- + * Walk through the salvager database, printing with key "UNKNOWN" + * any pages we haven't dealt with. + */ +static int +__db_salvage_unknowns(dbp, vdp, handle, callback, flags) + DB *dbp; + VRFY_DBINFO *vdp; + void *handle; + int (*callback) __P((void *, const void *)); + u_int32_t flags; +{ + DBC *dbc; + DBT unkdbt, key, *dbt; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *h; + db_pgno_t pgno; + u_int32_t pgtype, ovfl_bufsz, tmp_flags; + int ret, t_ret; + void *ovflbuf; + + dbc = NULL; + env = dbp->env; + mpf = dbp->mpf; + + DB_INIT_DBT(unkdbt, "UNKNOWN", sizeof("UNKNOWN") - 1); + + if ((ret = __os_malloc(env, dbp->pgsize, &ovflbuf)) != 0) + return (ret); + ovfl_bufsz = dbp->pgsize; + + /* + * We make two passes -- in the first pass, skip SALVAGE_OVERFLOW + * pages, because they may be referenced by the standard database + * pages that we're resolving. + */ + while ((t_ret = + __db_salvage_getnext(vdp, &dbc, &pgno, &pgtype, 1)) == 0) { + if ((t_ret = __memp_fget(mpf, + &pgno, vdp->thread_info, NULL, 0, &h)) != 0) { + if (ret == 0) + ret = t_ret; + continue; + } + + dbt = NULL; + tmp_flags = 0; + switch (pgtype) { + case SALVAGE_LDUP: + case SALVAGE_LRECNODUP: + dbt = &unkdbt; + tmp_flags = DB_SA_UNKNOWNKEY; + /* FALLTHROUGH */ + case SALVAGE_IBTREE: + case SALVAGE_LBTREE: + case SALVAGE_LRECNO: + if ((t_ret = __bam_salvage( + dbp, vdp, pgno, pgtype, h, handle, + callback, dbt, tmp_flags | flags)) != 0 && ret == 0) + ret = t_ret; + break; + case SALVAGE_OVERFLOW: + DB_ASSERT(env, 0); /* Shouldn't ever happen. */ + break; + case SALVAGE_HASH: + if ((t_ret = __ham_salvage(dbp, vdp, + pgno, h, handle, callback, flags)) != 0 && ret == 0) + ret = t_ret; + break; + case SALVAGE_INVALID: + case SALVAGE_IGNORE: + default: + /* + * Shouldn't happen, but if it does, just do what the + * nice man says. + */ + DB_ASSERT(env, 0); + break; + } + if ((t_ret = __memp_fput(mpf, + vdp->thread_info, h, dbp->priority)) != 0 && ret == 0) + ret = t_ret; + } + + /* We should have reached the end of the database. */ + if (t_ret == DB_NOTFOUND) + t_ret = 0; + if (t_ret != 0 && ret == 0) + ret = t_ret; + + /* Re-open the cursor so we traverse the database again. */ + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + dbc = NULL; + + /* Now, deal with any remaining overflow pages. */ + while ((t_ret = + __db_salvage_getnext(vdp, &dbc, &pgno, &pgtype, 0)) == 0) { + if ((t_ret = __memp_fget(mpf, + &pgno, vdp->thread_info, NULL, 0, &h)) != 0) { + if (ret == 0) + ret = t_ret; + continue; + } + + switch (pgtype) { + case SALVAGE_OVERFLOW: + /* + * XXX: + * This may generate multiple "UNKNOWN" keys in + * a database with no dups. What to do? + */ + if ((t_ret = __db_safe_goff(dbp, vdp, + pgno, &key, &ovflbuf, &ovfl_bufsz, flags)) != 0 || + ((vdp->type == DB_BTREE || vdp->type == DB_HASH) && + (t_ret = __db_vrfy_prdbt(&unkdbt, + 0, " ", handle, callback, 0, vdp)) != 0) || + (t_ret = __db_vrfy_prdbt( + &key, 0, " ", handle, callback, 0, vdp)) != 0) + if (ret == 0) + ret = t_ret; + break; + default: + DB_ASSERT(env, 0); /* Shouldn't ever happen. */ + break; + } + if ((t_ret = __memp_fput(mpf, + vdp->thread_info, h, dbp->priority)) != 0 && ret == 0) + ret = t_ret; + } + + /* We should have reached the end of the database. */ + if (t_ret == DB_NOTFOUND) + t_ret = 0; + if (t_ret != 0 && ret == 0) + ret = t_ret; + + if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0) + ret = t_ret; + + __os_free(env, ovflbuf); + + return (ret); +} + +/* + * Offset of the ith inp array entry, which we can compare to the offset + * the entry stores. + */ +#define INP_OFFSET(dbp, h, i) \ + ((db_indx_t)((u_int8_t *)((P_INP(dbp,(h))) + (i)) - (u_int8_t *)(h))) + +/* + * __db_vrfy_inpitem -- + * Verify that a single entry in the inp array is sane, and update + * the high water mark and current item offset. (The former of these is + * used for state information between calls, and is required; it must + * be initialized to the pagesize before the first call.) + * + * Returns DB_VERIFY_FATAL if inp has collided with the data, + * since verification can't continue from there; returns DB_VERIFY_BAD + * if anything else is wrong. + * + * PUBLIC: int __db_vrfy_inpitem __P((DB *, PAGE *, + * PUBLIC: db_pgno_t, u_int32_t, int, u_int32_t, u_int32_t *, u_int32_t *)); + */ +int +__db_vrfy_inpitem(dbp, h, pgno, i, is_btree, flags, himarkp, offsetp) + DB *dbp; + PAGE *h; + db_pgno_t pgno; + u_int32_t i; + int is_btree; + u_int32_t flags, *himarkp, *offsetp; +{ + BKEYDATA *bk; + ENV *env; + db_indx_t *inp, offset, len; + + env = dbp->env; + + DB_ASSERT(env, himarkp != NULL); + inp = P_INP(dbp, h); + + /* + * Check that the inp array, which grows from the beginning of the + * page forward, has not collided with the data, which grow from the + * end of the page backward. + */ + if (inp + i >= (db_indx_t *)((u_int8_t *)h + *himarkp)) { + /* We've collided with the data. We need to bail. */ + EPRINT((env, "Page %lu: entries listing %lu overlaps data", + (u_long)pgno, (u_long)i)); + return (DB_VERIFY_FATAL); + } + + offset = inp[i]; + + /* + * Check that the item offset is reasonable: it points somewhere + * after the inp array and before the end of the page. + */ + if (offset <= INP_OFFSET(dbp, h, i) || offset >= dbp->pgsize) { + EPRINT((env, "Page %lu: bad offset %lu at page index %lu", + (u_long)pgno, (u_long)offset, (u_long)i)); + return (DB_VERIFY_BAD); + } + + /* Update the high-water mark (what HOFFSET should be) */ + if (offset < *himarkp) + *himarkp = offset; + + if (is_btree) { + /* + * Check alignment; if it's unaligned, it's unsafe to + * manipulate this item. + */ + if (offset != DB_ALIGN(offset, sizeof(u_int32_t))) { + EPRINT((env, + "Page %lu: unaligned offset %lu at page index %lu", + (u_long)pgno, (u_long)offset, (u_long)i)); + return (DB_VERIFY_BAD); + } + + /* + * Check that the item length remains on-page. + */ + bk = GET_BKEYDATA(dbp, h, i); + + /* + * We need to verify the type of the item here; + * we can't simply assume that it will be one of the + * expected three. If it's not a recognizable type, + * it can't be considered to have a verifiable + * length, so it's not possible to certify it as safe. + */ + switch (B_TYPE(bk->type)) { + case B_KEYDATA: + len = bk->len; + break; + case B_DUPLICATE: + case B_OVERFLOW: + len = BOVERFLOW_SIZE; + break; + default: + EPRINT((env, + "Page %lu: item %lu of unrecognizable type", + (u_long)pgno, (u_long)i)); + return (DB_VERIFY_BAD); + } + + if ((size_t)(offset + len) > dbp->pgsize) { + EPRINT((env, + "Page %lu: item %lu extends past page boundary", + (u_long)pgno, (u_long)i)); + return (DB_VERIFY_BAD); + } + } + + if (offsetp != NULL) + *offsetp = offset; + return (0); +} + +/* + * __db_vrfy_duptype-- + * Given a page number and a set of flags to __bam_vrfy_subtree, + * verify that the dup tree type is correct--i.e., it's a recno + * if DUPSORT is not set and a btree if it is. + * + * PUBLIC: int __db_vrfy_duptype + * PUBLIC: __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t)); + */ +int +__db_vrfy_duptype(dbp, vdp, pgno, flags) + DB *dbp; + VRFY_DBINFO *vdp; + db_pgno_t pgno; + u_int32_t flags; +{ + ENV *env; + VRFY_PAGEINFO *pip; + int ret, isbad; + + env = dbp->env; + isbad = 0; + + if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) + return (ret); + + switch (pip->type) { + case P_IBTREE: + case P_LDUP: + if (!LF_ISSET(DB_ST_DUPSORT)) { + EPRINT((env, + "Page %lu: sorted duplicate set in unsorted-dup database", + (u_long)pgno)); + isbad = 1; + } + break; + case P_IRECNO: + case P_LRECNO: + if (LF_ISSET(DB_ST_DUPSORT)) { + EPRINT((env, + "Page %lu: unsorted duplicate set in sorted-dup database", + (u_long)pgno)); + isbad = 1; + } + break; + default: + /* + * If the page is entirely zeroed, its pip->type will be a lie + * (we assumed it was a hash page, as they're allowed to be + * zeroed); handle this case specially. + */ + if (F_ISSET(pip, VRFY_IS_ALLZEROES)) + ZEROPG_ERR_PRINT(env, pgno, "duplicate page"); + else + EPRINT((env, + "Page %lu: duplicate page of inappropriate type %lu", + (u_long)pgno, (u_long)pip->type)); + isbad = 1; + break; + } + + if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0) + return (ret); + return (isbad == 1 ? DB_VERIFY_BAD : 0); +} + +/* + * __db_salvage_duptree -- + * Attempt to salvage a given duplicate tree, given its alleged root. + * + * The key that corresponds to this dup set has been passed to us + * in DBT *key. Because data items follow keys, though, it has been + * printed once already. + * + * The basic idea here is that pgno ought to be a P_LDUP, a P_LRECNO, a + * P_IBTREE, or a P_IRECNO. If it's an internal page, use the verifier + * functions to make sure it's safe; if it's not, we simply bail and the + * data will have to be printed with no key later on. if it is safe, + * recurse on each of its children. + * + * Whether or not it's safe, if it's a leaf page, __bam_salvage it. + * + * At all times, use the DB hanging off vdp to mark and check what we've + * done, so each page gets printed exactly once and we don't get caught + * in any cycles. + * + * PUBLIC: int __db_salvage_duptree __P((DB *, VRFY_DBINFO *, db_pgno_t, + * PUBLIC: DBT *, void *, int (*)(void *, const void *), u_int32_t)); + */ +int +__db_salvage_duptree(dbp, vdp, pgno, key, handle, callback, flags) + DB *dbp; + VRFY_DBINFO *vdp; + db_pgno_t pgno; + DBT *key; + void *handle; + int (*callback) __P((void *, const void *)); + u_int32_t flags; +{ + DB_MPOOLFILE *mpf; + PAGE *h; + int ret, t_ret; + + mpf = dbp->mpf; + + if (pgno == PGNO_INVALID || !IS_VALID_PGNO(pgno)) + return (DB_VERIFY_BAD); + + /* We have a plausible page. Try it. */ + if ((ret = __memp_fget(mpf, &pgno, vdp->thread_info, NULL, 0, &h)) != 0) + return (ret); + + switch (TYPE(h)) { + case P_IBTREE: + case P_IRECNO: + if ((ret = __db_vrfy_common(dbp, vdp, h, pgno, flags)) != 0) + goto err; + if ((ret = __bam_vrfy(dbp, + vdp, h, pgno, flags | DB_NOORDERCHK)) != 0 || + (ret = __db_salvage_markdone(vdp, pgno)) != 0) + goto err; + /* + * We have a known-healthy internal page. Walk it. + */ + if ((ret = __bam_salvage_walkdupint(dbp, vdp, h, key, + handle, callback, flags)) != 0) + goto err; + break; + case P_LRECNO: + case P_LDUP: + if ((ret = __bam_salvage(dbp, + vdp, pgno, TYPE(h), h, handle, callback, key, flags)) != 0) + goto err; + break; + default: + ret = DB_VERIFY_BAD; + goto err; + } + +err: if ((t_ret = __memp_fput(mpf, + vdp->thread_info, h, dbp->priority)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +/* + * __db_salvage_all -- + * Salvage only the leaves we find by walking the tree. If we have subdbs, + * salvage each of them individually. + */ +static int +__db_salvage_all(dbp, vdp, handle, callback, flags, hassubsp) + DB *dbp; + VRFY_DBINFO *vdp; + void *handle; + int (*callback) __P((void *, const void *)); + u_int32_t flags; + int *hassubsp; +{ + DB *pgset; + DBC *pgsc; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *h; + VRFY_PAGEINFO *pip; + db_pgno_t p, meta_pgno; + int ret, t_ret; + + *hassubsp = 0; + + env = dbp->env; + pgset = NULL; + pgsc = NULL; + mpf = dbp->mpf; + h = NULL; + pip = NULL; + ret = 0; + + /* + * Check to make sure the page is OK and find out if it contains + * subdatabases. + */ + meta_pgno = PGNO_BASE_MD; + if ((t_ret = __memp_fget(mpf, + &meta_pgno, vdp->thread_info, NULL, 0, &h)) == 0 && + (t_ret = __db_vrfy_common(dbp, vdp, h, PGNO_BASE_MD, flags)) == 0 && + (t_ret = __db_salvage_pg( + dbp, vdp, PGNO_BASE_MD, h, handle, callback, flags)) == 0 && + (t_ret = __db_vrfy_getpageinfo(vdp, 0, &pip)) == 0) + if (F_ISSET(pip, VRFY_HAS_SUBDBS)) + *hassubsp = 1; + if (pip != NULL && + (t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) + ret = t_ret; + if (h != NULL) { + if ((t_ret = __memp_fput(mpf, + vdp->thread_info, h, dbp->priority)) != 0 && ret == 0) + ret = t_ret; + h = NULL; + } + if (ret != 0) + return (ret); + + /* Without subdatabases, we can just dump from the meta pgno. */ + if (*hassubsp == 0) + return (__db_salvage(dbp, + vdp, PGNO_BASE_MD, handle, callback, flags)); + + /* + * We have subdbs. Try to crack them. + * + * To do so, get a set of leaf pages in the master database, and then + * walk each of the valid ones, salvaging subdbs as we go. If any + * prove invalid, just drop them; we'll pick them up on a later pass. + */ + if ((ret = __db_vrfy_pgset(env, + vdp->thread_info, dbp->pgsize, &pgset)) != 0) + goto err; + if ((ret = __db_meta2pgset(dbp, vdp, PGNO_BASE_MD, flags, pgset)) != 0) + goto err; + if ((ret = __db_cursor(pgset, vdp->thread_info, NULL, &pgsc, 0)) != 0) + goto err; + while ((t_ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) { + if ((t_ret = __memp_fget(mpf, + &p, vdp->thread_info, NULL, 0, &h)) == 0 && + (t_ret = __db_vrfy_common(dbp, vdp, h, p, flags)) == 0 && + (t_ret = + __bam_vrfy(dbp, vdp, h, p, flags | DB_NOORDERCHK)) == 0) + t_ret = __db_salvage_subdbpg( + dbp, vdp, h, handle, callback, flags); + if (t_ret != 0 && ret == 0) + ret = t_ret; + if (h != NULL) { + if ((t_ret = __memp_fput(mpf, vdp->thread_info, + h, dbp->priority)) != 0 && ret == 0) + ret = t_ret; + h = NULL; + } + } + + if (t_ret != DB_NOTFOUND && ret == 0) + ret = t_ret; + +err: if (pgsc != NULL && (t_ret = __dbc_close(pgsc)) != 0 && ret == 0) + ret = t_ret; + if (pgset != NULL && + (t_ret = __db_close(pgset, NULL, 0)) != 0 && ret ==0) + ret = t_ret; + if (h != NULL && + (t_ret = __memp_fput(mpf, + vdp->thread_info, h, dbp->priority)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +/* + * __db_salvage_subdbpg -- + * Given a known-good leaf page in the master database, salvage all + * leaf pages corresponding to each subdb. + */ +static int +__db_salvage_subdbpg(dbp, vdp, master, handle, callback, flags) + DB *dbp; + VRFY_DBINFO *vdp; + PAGE *master; + void *handle; + int (*callback) __P((void *, const void *)); + u_int32_t flags; +{ + BKEYDATA *bkkey, *bkdata; + BOVERFLOW *bo; + DB *pgset; + DBC *pgsc; + DBT key; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *subpg; + db_indx_t i; + db_pgno_t meta_pgno; + int ret, err_ret, t_ret; + char *subdbname; + u_int32_t ovfl_bufsz; + + env = dbp->env; + mpf = dbp->mpf; + ret = err_ret = 0; + subdbname = NULL; + pgsc = NULL; + pgset = NULL; + ovfl_bufsz = 0; + + /* + * For each entry, get and salvage the set of pages + * corresponding to that entry. + */ + for (i = 0; i < NUM_ENT(master); i += P_INDX) { + bkkey = GET_BKEYDATA(dbp, master, i); + bkdata = GET_BKEYDATA(dbp, master, i + O_INDX); + + /* Get the subdatabase name. */ + if (B_TYPE(bkkey->type) == B_OVERFLOW) { + /* + * We can, in principle anyway, have a subdb + * name so long it overflows. Ick. + */ + bo = (BOVERFLOW *)bkkey; + if ((ret = __db_safe_goff(dbp, vdp, bo->pgno, + &key, &subdbname, &ovfl_bufsz, flags)) != 0) { + err_ret = DB_VERIFY_BAD; + continue; + } + + /* Nul-terminate it. */ + if (ovfl_bufsz < key.size + 1) { + if ((ret = __os_realloc(env, + key.size + 1, &subdbname)) != 0) + goto err; + ovfl_bufsz = key.size + 1; + } + subdbname[key.size] = '\0'; + } else if (B_TYPE(bkkey->type) == B_KEYDATA) { + if (ovfl_bufsz < (u_int32_t)bkkey->len + 1) { + if ((ret = __os_realloc(env, + bkkey->len + 1, &subdbname)) != 0) + goto err; + ovfl_bufsz = bkkey->len + 1; + } + DB_ASSERT(env, subdbname != NULL); + memcpy(subdbname, bkkey->data, bkkey->len); + subdbname[bkkey->len] = '\0'; + } + + /* Get the corresponding pgno. */ + if (bkdata->len != sizeof(db_pgno_t)) { + err_ret = DB_VERIFY_BAD; + continue; + } + memcpy(&meta_pgno, + (db_pgno_t *)bkdata->data, sizeof(db_pgno_t)); + + /* + * Subdatabase meta pgnos are stored in network byte + * order for cross-endian compatibility. Swap if appropriate. + */ + DB_NTOHL_SWAP(env, &meta_pgno); + + /* If we can't get the subdb meta page, just skip the subdb. */ + if (!IS_VALID_PGNO(meta_pgno) || (ret = __memp_fget(mpf, + &meta_pgno, vdp->thread_info, NULL, 0, &subpg)) != 0) { + err_ret = ret; + continue; + } + + /* + * Verify the subdatabase meta page. This has two functions. + * First, if it's bad, we have no choice but to skip the subdb + * and let the pages just get printed on a later pass. Second, + * the access-method-specific meta verification routines record + * the various state info (such as the presence of dups) + * that we need for __db_prheader(). + */ + if ((ret = + __db_vrfy_common(dbp, vdp, subpg, meta_pgno, flags)) != 0) { + err_ret = ret; + (void)__memp_fput(mpf, + vdp->thread_info, subpg, dbp->priority); + continue; + } + switch (TYPE(subpg)) { + case P_BTREEMETA: + if ((ret = __bam_vrfy_meta(dbp, + vdp, (BTMETA *)subpg, meta_pgno, flags)) != 0) { + err_ret = ret; + (void)__memp_fput(mpf, + vdp->thread_info, subpg, dbp->priority); + continue; + } + break; + case P_HASHMETA: + if ((ret = __ham_vrfy_meta(dbp, + vdp, (HMETA *)subpg, meta_pgno, flags)) != 0) { + err_ret = ret; + (void)__memp_fput(mpf, + vdp->thread_info, subpg, dbp->priority); + continue; + } + break; + default: + /* This isn't an appropriate page; skip this subdb. */ + err_ret = DB_VERIFY_BAD; + continue; + } + + if ((ret = __memp_fput(mpf, + vdp->thread_info, subpg, dbp->priority)) != 0) { + err_ret = ret; + continue; + } + + /* Print a subdatabase header. */ + if ((ret = __db_prheader(dbp, + subdbname, 0, 0, handle, callback, vdp, meta_pgno)) != 0) + goto err; + + /* Salvage meta_pgno's tree. */ + if ((ret = __db_salvage(dbp, + vdp, meta_pgno, handle, callback, flags)) != 0) + err_ret = ret; + + /* Print a subdatabase footer. */ + if ((ret = __db_prfooter(handle, callback)) != 0) + goto err; + } + +err: if (subdbname) + __os_free(env, subdbname); + + if (pgsc != NULL && (t_ret = __dbc_close(pgsc)) != 0) + ret = t_ret; + + if (pgset != NULL && (t_ret = __db_close(pgset, NULL, 0)) != 0) + ret = t_ret; + + if ((t_ret = __db_salvage_markdone(vdp, PGNO(master))) != 0) + return (t_ret); + + return ((err_ret != 0) ? err_ret : ret); +} + +/* + * __db_salvage -- + * Given a meta page number, salvage all data from leaf pages found by + * walking the meta page's tree. + */ +static int +__db_salvage(dbp, vdp, meta_pgno, handle, callback, flags) + DB *dbp; + VRFY_DBINFO *vdp; + db_pgno_t meta_pgno; + void *handle; + int (*callback) __P((void *, const void *)); + u_int32_t flags; + +{ + DB *pgset; + DBC *dbc, *pgsc; + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *subpg; + db_pgno_t p; + int err_ret, ret, t_ret; + + env = dbp->env; + mpf = dbp->mpf; + err_ret = ret = t_ret = 0; + pgsc = NULL; + pgset = NULL; + dbc = NULL; + + if ((ret = __db_vrfy_pgset(env, + vdp->thread_info, dbp->pgsize, &pgset)) != 0) + goto err; + + /* Get all page numbers referenced from this meta page. */ + if ((ret = __db_meta2pgset(dbp, vdp, meta_pgno, + flags, pgset)) != 0) { + err_ret = ret; + goto err; + } + + if ((ret = __db_cursor(pgset, + vdp->thread_info, NULL, &pgsc, 0)) != 0) + goto err; + + if (dbp->type == DB_QUEUE && + (ret = __db_cursor(dbp, vdp->thread_info, NULL, &dbc, 0)) != 0) + goto err; + + /* Salvage every page in pgset. */ + while ((ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) { + if (dbp->type == DB_QUEUE) { +#ifdef HAVE_QUEUE + ret = __qam_fget(dbc, &p, 0, &subpg); +#else + ret = __db_no_queue_am(env); +#endif + /* Don't report an error for pages not found in a queue. + * The pgset is a best guess, it doesn't know about + * deleted extents which leads to this error. + */ + if (ret == ENOENT || ret == DB_PAGE_NOTFOUND) + continue; + } else + ret = __memp_fget(mpf, + &p, vdp->thread_info, NULL, 0, &subpg); + if (ret != 0) { + err_ret = ret; + continue; + } + + if ((ret = __db_salvage_pg(dbp, vdp, p, subpg, + handle, callback, flags)) != 0) + err_ret = ret; + + if (dbp->type == DB_QUEUE) +#ifdef HAVE_QUEUE + ret = __qam_fput(dbc, p, subpg, dbp->priority); +#else + ret = __db_no_queue_am(env); +#endif + else + ret = __memp_fput(mpf, + vdp->thread_info, subpg, dbp->priority); + if (ret != 0) + err_ret = ret; + } + + if (ret == DB_NOTFOUND) + ret = 0; + +err: + if (dbc != NULL && (t_ret = __dbc_close(dbc)) != 0) + ret = t_ret; + if (pgsc != NULL && (t_ret = __dbc_close(pgsc)) != 0) + ret = t_ret; + if (pgset != NULL && (t_ret = __db_close(pgset, NULL, 0)) != 0) + ret = t_ret; + + return ((err_ret != 0) ? err_ret : ret); +} + +/* + * __db_meta2pgset -- + * Given a known-safe meta page number, return the set of pages + * corresponding to the database it represents. Return DB_VERIFY_BAD if + * it's not a suitable meta page or is invalid. + */ +static int +__db_meta2pgset(dbp, vdp, pgno, flags, pgset) + DB *dbp; + VRFY_DBINFO *vdp; + db_pgno_t pgno; + u_int32_t flags; + DB *pgset; +{ + DB_MPOOLFILE *mpf; + PAGE *h; + int ret, t_ret; + + mpf = dbp->mpf; + + if ((ret = __memp_fget(mpf, &pgno, vdp->thread_info, NULL, 0, &h)) != 0) + return (ret); + + switch (TYPE(h)) { + case P_BTREEMETA: + ret = __bam_meta2pgset(dbp, vdp, (BTMETA *)h, flags, pgset); + break; + case P_HASHMETA: + ret = __ham_meta2pgset(dbp, vdp, (HMETA *)h, flags, pgset); + break; + case P_QAMMETA: +#ifdef HAVE_QUEUE + ret = __qam_meta2pgset(dbp, vdp, pgset); + break; +#endif + default: + ret = DB_VERIFY_BAD; + break; + } + + if ((t_ret = __memp_fput(mpf, vdp->thread_info, h, dbp->priority)) != 0) + return (t_ret); + return (ret); +} + +/* + * __db_guesspgsize -- + * Try to guess what the pagesize is if the one on the meta page + * and the one in the db are invalid. + */ +static u_int +__db_guesspgsize(env, fhp) + ENV *env; + DB_FH *fhp; +{ + db_pgno_t i; + size_t nr; + u_int32_t guess; + u_int8_t type; + + for (guess = DB_MAX_PGSIZE; guess >= DB_MIN_PGSIZE; guess >>= 1) { + /* + * We try to read three pages ahead after the first one + * and make sure we have plausible types for all of them. + * If the seeks fail, continue with a smaller size; + * we're probably just looking past the end of the database. + * If they succeed and the types are reasonable, also continue + * with a size smaller; we may be looking at pages N, + * 2N, and 3N for some N > 1. + * + * As soon as we hit an invalid type, we stop and return + * our previous guess; that last one was probably the page size. + */ + for (i = 1; i <= 3; i++) { + if (__os_seek( + env, fhp, i, guess, SSZ(DBMETA, type)) != 0) + break; + if (__os_read(env, + fhp, &type, 1, &nr) != 0 || nr == 0) + break; + if (type == P_INVALID || type >= P_PAGETYPE_MAX) + return (guess << 1); + } + } + + /* + * If we're just totally confused--the corruption takes up most of the + * beginning pages of the database--go with the default size. + */ + return (DB_DEF_IOSIZE); +} diff --git a/src/libs/resiprocate/contrib/db/db/db_vrfy_stub.c b/src/libs/resiprocate/contrib/db/db/db_vrfy_stub.c new file mode 100644 index 00000000..9ed5acd1 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_vrfy_stub.c @@ -0,0 +1,117 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef HAVE_VERIFY +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/db_verify.h" + +/* + * If the library wasn't compiled with the verification support, various + * routines aren't available. Stub them here, returning an appropriate + * error. + */ + +static int __db_novrfy __P((ENV *)); + +/* + * __db_novrfy -- + * Error when a Berkeley DB build doesn't include the access method. + */ +static int +__db_novrfy(env) + ENV *env; +{ + __db_errx(env, + "library build did not include support for database verification"); + return (DB_OPNOTSUP); +} + +int +__db_verify_pp(dbp, file, database, outfile, flags) + DB *dbp; + const char *file, *database; + FILE *outfile; + u_int32_t flags; +{ + int ret; + + COMPQUIET(file, NULL); + COMPQUIET(database, NULL); + COMPQUIET(outfile, NULL); + COMPQUIET(flags, 0); + + ret = __db_novrfy(dbp->env); + + /* The verify method is a destructor. */ + (void)__db_close(dbp, NULL, 0); + + return (ret); +} + +int +__db_verify_internal(dbp, name, subdb, handle, callback, flags) + DB *dbp; + const char *name, *subdb; + void *handle; + int (*callback) __P((void *, const void *)); + u_int32_t flags; +{ + COMPQUIET(dbp, NULL); + COMPQUIET(name, NULL); + COMPQUIET(subdb, NULL); + COMPQUIET(handle, NULL); + COMPQUIET(callback, NULL); + COMPQUIET(flags, 0); + return (0); +} + +int +__db_vrfy_getpageinfo(vdp, pgno, pipp) + VRFY_DBINFO *vdp; + db_pgno_t pgno; + VRFY_PAGEINFO **pipp; +{ + COMPQUIET(pgno, 0); + COMPQUIET(pipp, NULL); + return (__db_novrfy(vdp->pgdbp->env)); +} + +int +__db_vrfy_putpageinfo(env, vdp, pip) + ENV *env; + VRFY_DBINFO *vdp; + VRFY_PAGEINFO *pip; +{ + COMPQUIET(vdp, NULL); + COMPQUIET(pip, NULL); + return (__db_novrfy(env)); +} + +int +__db_vrfy_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno, vdp) + DBT *dbtp; + int checkprint; + const char *prefix; + void *handle; + int (*callback) __P((void *, const void *)); + int is_recno; + VRFY_DBINFO *vdp; +{ + COMPQUIET(dbtp, NULL); + COMPQUIET(checkprint, 0); + COMPQUIET(prefix, NULL); + COMPQUIET(handle, NULL); + COMPQUIET(callback, NULL); + COMPQUIET(is_recno, 0); + return (__db_novrfy(vdp->pgdbp->env)); +} +#endif /* !HAVE_VERIFY */ diff --git a/src/libs/resiprocate/contrib/db/db/db_vrfyutil.c b/src/libs/resiprocate/contrib/db/db/db_vrfyutil.c new file mode 100644 index 00000000..04d73d99 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db/db_vrfyutil.c @@ -0,0 +1,916 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_verify.h" +#include "dbinc/db_am.h" + +static int __db_vrfy_childinc __P((DBC *, VRFY_CHILDINFO *)); +static int __db_vrfy_pageinfo_create __P((ENV *, VRFY_PAGEINFO **)); + +/* + * __db_vrfy_dbinfo_create -- + * Allocate and initialize a VRFY_DBINFO structure. + * + * PUBLIC: int __db_vrfy_dbinfo_create + * PUBLIC: __P((ENV *, DB_THREAD_INFO *, u_int32_t, VRFY_DBINFO **)); + */ +int +__db_vrfy_dbinfo_create(env, ip, pgsize, vdpp) + ENV *env; + DB_THREAD_INFO *ip; + u_int32_t pgsize; + VRFY_DBINFO **vdpp; +{ + DB *cdbp, *pgdbp, *pgset; + VRFY_DBINFO *vdp; + int ret; + + vdp = NULL; + cdbp = pgdbp = pgset = NULL; + + if ((ret = __os_calloc(NULL, 1, sizeof(VRFY_DBINFO), &vdp)) != 0) + goto err; + + if ((ret = __db_create_internal(&cdbp, env, 0)) != 0) + goto err; + + if ((ret = __db_set_flags(cdbp, DB_DUP)) != 0) + goto err; + + if ((ret = __db_set_pagesize(cdbp, pgsize)) != 0) + goto err; + + /* If transactional, make sure we don't log. */ + if (TXN_ON(env) && + (ret = __db_set_flags(cdbp, DB_TXN_NOT_DURABLE)) != 0) + goto err; + if ((ret = __db_open(cdbp, ip, + NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) != 0) + goto err; + + if ((ret = __db_create_internal(&pgdbp, env, 0)) != 0) + goto err; + + if ((ret = __db_set_pagesize(pgdbp, pgsize)) != 0) + goto err; + + /* If transactional, make sure we don't log. */ + if (TXN_ON(env) && + (ret = __db_set_flags(pgdbp, DB_TXN_NOT_DURABLE)) != 0) + goto err; + + if ((ret = __db_open(pgdbp, ip, + NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) != 0) + goto err; + + if ((ret = __db_vrfy_pgset(env, ip, pgsize, &pgset)) != 0) + goto err; + + LIST_INIT(&vdp->subdbs); + LIST_INIT(&vdp->activepips); + + vdp->cdbp = cdbp; + vdp->pgdbp = pgdbp; + vdp->pgset = pgset; + vdp->thread_info = ip; + *vdpp = vdp; + return (0); + +err: if (cdbp != NULL) + (void)__db_close(cdbp, NULL, 0); + if (pgdbp != NULL) + (void)__db_close(pgdbp, NULL, 0); + if (vdp != NULL) + __os_free(env, vdp); + return (ret); +} + +/* + * __db_vrfy_dbinfo_destroy -- + * Destructor for VRFY_DBINFO. Destroys VRFY_PAGEINFOs and deallocates + * structure. + * + * PUBLIC: int __db_vrfy_dbinfo_destroy __P((ENV *, VRFY_DBINFO *)); + */ +int +__db_vrfy_dbinfo_destroy(env, vdp) + ENV *env; + VRFY_DBINFO *vdp; +{ + VRFY_CHILDINFO *c; + int t_ret, ret; + + ret = 0; + + /* + * Discard active page structures. Ideally there wouldn't be any, + * but in some error cases we may not have cleared them all out. + */ + while (LIST_FIRST(&vdp->activepips) != NULL) + if ((t_ret = __db_vrfy_putpageinfo( + env, vdp, LIST_FIRST(&vdp->activepips))) != 0) { + if (ret == 0) + ret = t_ret; + break; + } + + /* Discard subdatabase list structures. */ + while ((c = LIST_FIRST(&vdp->subdbs)) != NULL) { + LIST_REMOVE(c, links); + __os_free(NULL, c); + } + + if ((t_ret = __db_close(vdp->pgdbp, NULL, 0)) != 0) + ret = t_ret; + + if ((t_ret = __db_close(vdp->cdbp, NULL, 0)) != 0 && ret == 0) + ret = t_ret; + + if ((t_ret = __db_close(vdp->pgset, NULL, 0)) != 0 && ret == 0) + ret = t_ret; + + if (vdp->extents != NULL) + __os_free(env, vdp->extents); + __os_free(env, vdp); + return (ret); +} + +/* + * __db_vrfy_getpageinfo -- + * Get a PAGEINFO structure for a given page, creating it if necessary. + * + * PUBLIC: int __db_vrfy_getpageinfo + * PUBLIC: __P((VRFY_DBINFO *, db_pgno_t, VRFY_PAGEINFO **)); + */ +int +__db_vrfy_getpageinfo(vdp, pgno, pipp) + VRFY_DBINFO *vdp; + db_pgno_t pgno; + VRFY_PAGEINFO **pipp; +{ + DB *pgdbp; + DBT key, data; + ENV *env; + VRFY_PAGEINFO *pip; + int ret; + + /* + * We want a page info struct. There are three places to get it from, + * in decreasing order of preference: + * + * 1. vdp->activepips. If it's already "checked out", we're + * already using it, we return the same exact structure with a + * bumped refcount. This is necessary because this code is + * replacing array accesses, and it's common for f() to make some + * changes to a pip, and then call g() and h() which each make + * changes to the same pip. vdps are never shared between threads + * (they're never returned to the application), so this is safe. + * 2. The pgdbp. It's not in memory, but it's in the database, so + * get it, give it a refcount of 1, and stick it on activepips. + * 3. malloc. It doesn't exist yet; create it, then stick it on + * activepips. We'll put it in the database when we putpageinfo + * later. + */ + + /* Case 1. */ + LIST_FOREACH(pip, &vdp->activepips, links) + if (pip->pgno == pgno) + goto found; + + /* Case 2. */ + pgdbp = vdp->pgdbp; + env = pgdbp->env; + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + F_SET(&data, DB_DBT_MALLOC); + key.data = &pgno; + key.size = sizeof(db_pgno_t); + + if ((ret = __db_get(pgdbp, + vdp->thread_info, NULL, &key, &data, 0)) == 0) { + /* Found it. */ + DB_ASSERT(env, data.size == sizeof(VRFY_PAGEINFO)); + pip = data.data; + LIST_INSERT_HEAD(&vdp->activepips, pip, links); + goto found; + } else if (ret != DB_NOTFOUND) /* Something nasty happened. */ + return (ret); + + /* Case 3 */ + if ((ret = __db_vrfy_pageinfo_create(env, &pip)) != 0) + return (ret); + + LIST_INSERT_HEAD(&vdp->activepips, pip, links); +found: pip->pi_refcount++; + + *pipp = pip; + return (0); +} + +/* + * __db_vrfy_putpageinfo -- + * Put back a VRFY_PAGEINFO that we're done with. + * + * PUBLIC: int __db_vrfy_putpageinfo __P((ENV *, + * PUBLIC: VRFY_DBINFO *, VRFY_PAGEINFO *)); + */ +int +__db_vrfy_putpageinfo(env, vdp, pip) + ENV *env; + VRFY_DBINFO *vdp; + VRFY_PAGEINFO *pip; +{ + DB *pgdbp; + DBT key, data; + VRFY_PAGEINFO *p; + int ret; + + if (--pip->pi_refcount > 0) + return (0); + + pgdbp = vdp->pgdbp; + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + + key.data = &pip->pgno; + key.size = sizeof(db_pgno_t); + data.data = pip; + data.size = sizeof(VRFY_PAGEINFO); + + if ((ret = __db_put(pgdbp, + vdp->thread_info, NULL, &key, &data, 0)) != 0) + return (ret); + + LIST_FOREACH(p, &vdp->activepips, links) + if (p == pip) + break; + if (p != NULL) + LIST_REMOVE(p, links); + + __os_ufree(env, p); + return (0); +} + +/* + * __db_vrfy_pgset -- + * Create a temporary database for the storing of sets of page numbers. + * (A mapping from page number to int, used by the *_meta2pgset functions, + * as well as for keeping track of which pages the verifier has seen.) + * + * PUBLIC: int __db_vrfy_pgset __P((ENV *, + * PUBLIC: DB_THREAD_INFO *, u_int32_t, DB **)); + */ +int +__db_vrfy_pgset(env, ip, pgsize, dbpp) + ENV *env; + DB_THREAD_INFO *ip; + u_int32_t pgsize; + DB **dbpp; +{ + DB *dbp; + int ret; + + if ((ret = __db_create_internal(&dbp, env, 0)) != 0) + return (ret); + if ((ret = __db_set_pagesize(dbp, pgsize)) != 0) + goto err; + + /* If transactional, make sure we don't log. */ + if (TXN_ON(env) && + (ret = __db_set_flags(dbp, DB_TXN_NOT_DURABLE)) != 0) + goto err; + if ((ret = __db_open(dbp, ip, + NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) == 0) + *dbpp = dbp; + else +err: (void)__db_close(dbp, NULL, 0); + + return (ret); +} + +/* + * __db_vrfy_pgset_get -- + * Get the value associated in a page set with a given pgno. Return + * a 0 value (and succeed) if we've never heard of this page. + * + * PUBLIC: int __db_vrfy_pgset_get __P((DB *, DB_THREAD_INFO *, db_pgno_t, + * PUBLIC: int *)); + */ +int +__db_vrfy_pgset_get(dbp, ip, pgno, valp) + DB *dbp; + DB_THREAD_INFO *ip; + db_pgno_t pgno; + int *valp; +{ + DBT key, data; + int ret, val; + + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + + key.data = &pgno; + key.size = sizeof(db_pgno_t); + data.data = &val; + data.ulen = sizeof(int); + F_SET(&data, DB_DBT_USERMEM); + + if ((ret = __db_get(dbp, ip, NULL, &key, &data, 0)) == 0) { + DB_ASSERT(dbp->env, data.size == sizeof(int)); + } else if (ret == DB_NOTFOUND) + val = 0; + else + return (ret); + + *valp = val; + return (0); +} + +/* + * __db_vrfy_pgset_inc -- + * Increment the value associated with a pgno by 1. + * + * PUBLIC: int __db_vrfy_pgset_inc __P((DB *, DB_THREAD_INFO *, db_pgno_t)); + */ +int +__db_vrfy_pgset_inc(dbp, ip, pgno) + DB *dbp; + DB_THREAD_INFO *ip; + db_pgno_t pgno; +{ + DBT key, data; + int ret; + int val; + + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + + val = 0; + + key.data = &pgno; + key.size = sizeof(db_pgno_t); + data.data = &val; + data.ulen = sizeof(int); + F_SET(&data, DB_DBT_USERMEM); + + if ((ret = __db_get(dbp, ip, NULL, &key, &data, 0)) == 0) { + DB_ASSERT(dbp->env, data.size == sizeof(int)); + } else if (ret != DB_NOTFOUND) + return (ret); + + data.size = sizeof(int); + ++val; + + return (__db_put(dbp, ip, NULL, &key, &data, 0)); +} + +/* + * __db_vrfy_pgset_next -- + * Given a cursor open in a pgset database, get the next page in the + * set. + * + * PUBLIC: int __db_vrfy_pgset_next __P((DBC *, db_pgno_t *)); + */ +int +__db_vrfy_pgset_next(dbc, pgnop) + DBC *dbc; + db_pgno_t *pgnop; +{ + DBT key, data; + db_pgno_t pgno; + int ret; + + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + /* We don't care about the data, just the keys. */ + F_SET(&data, DB_DBT_USERMEM | DB_DBT_PARTIAL); + F_SET(&key, DB_DBT_USERMEM); + key.data = &pgno; + key.ulen = sizeof(db_pgno_t); + + if ((ret = __dbc_get(dbc, &key, &data, DB_NEXT)) != 0) + return (ret); + + DB_ASSERT(dbc->env, key.size == sizeof(db_pgno_t)); + *pgnop = pgno; + + return (0); +} + +/* + * __db_vrfy_childcursor -- + * Create a cursor to walk the child list with. Returns with a nonzero + * final argument if the specified page has no children. + * + * PUBLIC: int __db_vrfy_childcursor __P((VRFY_DBINFO *, DBC **)); + */ +int +__db_vrfy_childcursor(vdp, dbcp) + VRFY_DBINFO *vdp; + DBC **dbcp; +{ + DB *cdbp; + DBC *dbc; + int ret; + + cdbp = vdp->cdbp; + + if ((ret = __db_cursor(cdbp, vdp->thread_info, NULL, &dbc, 0)) == 0) + *dbcp = dbc; + + return (ret); +} + +/* + * __db_vrfy_childput -- + * Add a child structure to the set for a given page. + * + * PUBLIC: int __db_vrfy_childput + * PUBLIC: __P((VRFY_DBINFO *, db_pgno_t, VRFY_CHILDINFO *)); + */ +int +__db_vrfy_childput(vdp, pgno, cip) + VRFY_DBINFO *vdp; + db_pgno_t pgno; + VRFY_CHILDINFO *cip; +{ + DB *cdbp; + DBC *cc; + DBT key, data; + VRFY_CHILDINFO *oldcip; + int ret; + + cdbp = vdp->cdbp; + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + + key.data = &pgno; + key.size = sizeof(db_pgno_t); + + /* + * We want to avoid adding multiple entries for a single child page; + * we only need to verify each child once, even if a child (such + * as an overflow key) is multiply referenced. + * + * However, we also need to make sure that when walking the list + * of children, we encounter them in the order they're referenced + * on a page. (This permits us, for example, to verify the + * prev_pgno/next_pgno chain of Btree leaf pages.) + * + * Check the child database to make sure that this page isn't + * already a child of the specified page number. If it's not, + * put it at the end of the duplicate set. + */ + if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0) + return (ret); + for (ret = __db_vrfy_ccset(cc, pgno, &oldcip); ret == 0; + ret = __db_vrfy_ccnext(cc, &oldcip)) + if (oldcip->pgno == cip->pgno) { + /* + * Found a matching child. Increment its reference + * count--we've run into it again--but don't put it + * again. + */ + if ((ret = __db_vrfy_childinc(cc, oldcip)) != 0 || + (ret = __db_vrfy_ccclose(cc)) != 0) + return (ret); + return (0); + } + if (ret != DB_NOTFOUND) { + (void)__db_vrfy_ccclose(cc); + return (ret); + } + if ((ret = __db_vrfy_ccclose(cc)) != 0) + return (ret); + + cip->refcnt = 1; + data.data = cip; + data.size = sizeof(VRFY_CHILDINFO); + + return (__db_put(cdbp, vdp->thread_info, NULL, &key, &data, 0)); +} + +/* + * __db_vrfy_childinc -- + * Increment the refcount of the VRFY_CHILDINFO struct that the child + * cursor is pointing to. (The caller has just retrieved this struct, and + * passes it in as cip to save us a get.) + */ +static int +__db_vrfy_childinc(dbc, cip) + DBC *dbc; + VRFY_CHILDINFO *cip; +{ + DBT key, data; + + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + + cip->refcnt++; + data.data = cip; + data.size = sizeof(VRFY_CHILDINFO); + + return (__dbc_put(dbc, &key, &data, DB_CURRENT)); +} + +/* + * __db_vrfy_ccset -- + * Sets a cursor created with __db_vrfy_childcursor to the first + * child of the given pgno, and returns it in the third arg. + * + * PUBLIC: int __db_vrfy_ccset __P((DBC *, db_pgno_t, VRFY_CHILDINFO **)); + */ +int +__db_vrfy_ccset(dbc, pgno, cipp) + DBC *dbc; + db_pgno_t pgno; + VRFY_CHILDINFO **cipp; +{ + DBT key, data; + int ret; + + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + + key.data = &pgno; + key.size = sizeof(db_pgno_t); + + if ((ret = __dbc_get(dbc, &key, &data, DB_SET)) != 0) + return (ret); + + DB_ASSERT(dbc->env, data.size == sizeof(VRFY_CHILDINFO)); + *cipp = (VRFY_CHILDINFO *)data.data; + + return (0); +} + +/* + * __db_vrfy_ccnext -- + * Gets the next child of the given cursor created with + * __db_vrfy_childcursor, and returns it in the memory provided in the + * second arg. + * + * PUBLIC: int __db_vrfy_ccnext __P((DBC *, VRFY_CHILDINFO **)); + */ +int +__db_vrfy_ccnext(dbc, cipp) + DBC *dbc; + VRFY_CHILDINFO **cipp; +{ + DBT key, data; + int ret; + + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + + if ((ret = __dbc_get(dbc, &key, &data, DB_NEXT_DUP)) != 0) + return (ret); + + DB_ASSERT(dbc->env, data.size == sizeof(VRFY_CHILDINFO)); + *cipp = (VRFY_CHILDINFO *)data.data; + + return (0); +} + +/* + * __db_vrfy_ccclose -- + * Closes the cursor created with __db_vrfy_childcursor. + * + * This doesn't actually do anything interesting now, but it's + * not inconceivable that we might change the internal database usage + * and keep the interfaces the same, and a function call here or there + * seldom hurts anyone. + * + * PUBLIC: int __db_vrfy_ccclose __P((DBC *)); + */ +int +__db_vrfy_ccclose(dbc) + DBC *dbc; +{ + + return (__dbc_close(dbc)); +} + +/* + * __db_vrfy_pageinfo_create -- + * Constructor for VRFY_PAGEINFO; allocates and initializes. + */ +static int +__db_vrfy_pageinfo_create(env, pipp) + ENV *env; + VRFY_PAGEINFO **pipp; +{ + VRFY_PAGEINFO *pip; + int ret; + + /* + * pageinfo structs are sometimes allocated here and sometimes + * allocated by fetching them from a database with DB_DBT_MALLOC. + * There's no easy way for the destructor to tell which was + * used, and so we always allocate with __os_umalloc so we can free + * with __os_ufree. + */ + if ((ret = __os_umalloc(env, sizeof(VRFY_PAGEINFO), &pip)) != 0) + return (ret); + memset(pip, 0, sizeof(VRFY_PAGEINFO)); + + *pipp = pip; + return (0); +} + +/* + * __db_salvage_init -- + * Set up salvager database. + * + * PUBLIC: int __db_salvage_init __P((VRFY_DBINFO *)); + */ +int +__db_salvage_init(vdp) + VRFY_DBINFO *vdp; +{ + DB *dbp; + int ret; + + if ((ret = __db_create_internal(&dbp, NULL, 0)) != 0) + return (ret); + + if ((ret = __db_set_pagesize(dbp, 1024)) != 0) + goto err; + + if ((ret = __db_open(dbp, vdp->thread_info, + NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0, PGNO_BASE_MD)) != 0) + goto err; + + vdp->salvage_pages = dbp; + return (0); + +err: (void)__db_close(dbp, NULL, 0); + return (ret); +} + +/* + * __db_salvage_destroy -- + * Close salvager database. + * PUBLIC: int __db_salvage_destroy __P((VRFY_DBINFO *)); + */ +int +__db_salvage_destroy(vdp) + VRFY_DBINFO *vdp; +{ + return (vdp->salvage_pages == NULL ? 0 : + __db_close(vdp->salvage_pages, NULL, 0)); +} + +/* + * __db_salvage_getnext -- + * Get the next (first) unprinted page in the database of pages we need to + * print still. Delete entries for any already-printed pages we encounter + * in this search, as well as the page we're returning. + * + * PUBLIC: int __db_salvage_getnext + * PUBLIC: __P((VRFY_DBINFO *, DBC **, db_pgno_t *, u_int32_t *, int)); + */ +int +__db_salvage_getnext(vdp, dbcp, pgnop, pgtypep, skip_overflow) + VRFY_DBINFO *vdp; + DBC **dbcp; + db_pgno_t *pgnop; + u_int32_t *pgtypep; + int skip_overflow; +{ + DB *dbp; + DBT key, data; + int ret; + u_int32_t pgtype; + + dbp = vdp->salvage_pages; + + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + + if (*dbcp == NULL && + (ret = __db_cursor(dbp, vdp->thread_info, NULL, dbcp, 0)) != 0) + return (ret); + + while ((ret = __dbc_get(*dbcp, &key, &data, DB_NEXT)) == 0) { + DB_ASSERT(dbp->env, data.size == sizeof(u_int32_t)); + memcpy(&pgtype, data.data, sizeof(pgtype)); + + if (skip_overflow && pgtype == SALVAGE_OVERFLOW) + continue; + + if ((ret = __dbc_del(*dbcp, 0)) != 0) + return (ret); + if (pgtype != SALVAGE_IGNORE) { + DB_ASSERT(dbp->env, key.size == sizeof(db_pgno_t)); + DB_ASSERT(dbp->env, data.size == sizeof(u_int32_t)); + + *pgnop = *(db_pgno_t *)key.data; + *pgtypep = *(u_int32_t *)data.data; + break; + } + } + + return (ret); +} + +/* + * __db_salvage_isdone -- + * Return whether or not the given pgno is already marked + * SALVAGE_IGNORE (meaning that we don't need to print it again). + * + * Returns DB_KEYEXIST if it is marked, 0 if not, or another error on + * error. + * + * PUBLIC: int __db_salvage_isdone __P((VRFY_DBINFO *, db_pgno_t)); + */ +int +__db_salvage_isdone(vdp, pgno) + VRFY_DBINFO *vdp; + db_pgno_t pgno; +{ + DB *dbp; + DBT key, data; + int ret; + u_int32_t currtype; + + dbp = vdp->salvage_pages; + + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + + currtype = SALVAGE_INVALID; + data.data = &currtype; + data.ulen = sizeof(u_int32_t); + data.flags = DB_DBT_USERMEM; + + key.data = &pgno; + key.size = sizeof(db_pgno_t); + + /* + * Put an entry for this page, with pgno as key and type as data, + * unless it's already there and is marked done. + * If it's there and is marked anything else, that's fine--we + * want to mark it done. + */ + if ((ret = __db_get(dbp, + vdp->thread_info, NULL, &key, &data, 0)) == 0) { + /* + * The key's already here. Check and see if it's already + * marked done. If it is, return DB_KEYEXIST. If it's not, + * return 0. + */ + if (currtype == SALVAGE_IGNORE) + return (DB_KEYEXIST); + else + return (0); + } else if (ret != DB_NOTFOUND) + return (ret); + + /* The pgno is not yet marked anything; return 0. */ + return (0); +} + +/* + * __db_salvage_markdone -- + * Mark as done a given page. + * + * PUBLIC: int __db_salvage_markdone __P((VRFY_DBINFO *, db_pgno_t)); + */ +int +__db_salvage_markdone(vdp, pgno) + VRFY_DBINFO *vdp; + db_pgno_t pgno; +{ + DB *dbp; + DBT key, data; + int pgtype, ret; + u_int32_t currtype; + + pgtype = SALVAGE_IGNORE; + dbp = vdp->salvage_pages; + + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + + currtype = SALVAGE_INVALID; + data.data = &currtype; + data.ulen = sizeof(u_int32_t); + data.flags = DB_DBT_USERMEM; + + key.data = &pgno; + key.size = sizeof(db_pgno_t); + + /* + * Put an entry for this page, with pgno as key and type as data, + * unless it's already there and is marked done. + * If it's there and is marked anything else, that's fine--we + * want to mark it done, but db_salvage_isdone only lets + * us know if it's marked IGNORE. + * + * We don't want to return DB_KEYEXIST, though; this will + * likely get passed up all the way and make no sense to the + * application. Instead, use DB_VERIFY_BAD to indicate that + * we've seen this page already--it probably indicates a + * multiply-linked page. + */ + if ((ret = __db_salvage_isdone(vdp, pgno)) != 0) + return (ret == DB_KEYEXIST ? DB_VERIFY_BAD : ret); + + data.size = sizeof(u_int32_t); + data.data = &pgtype; + + return (__db_put(dbp, vdp->thread_info, NULL, &key, &data, 0)); +} + +/* + * __db_salvage_markneeded -- + * If it has not yet been printed, make note of the fact that a page + * must be dealt with later. + * + * PUBLIC: int __db_salvage_markneeded + * PUBLIC: __P((VRFY_DBINFO *, db_pgno_t, u_int32_t)); + */ +int +__db_salvage_markneeded(vdp, pgno, pgtype) + VRFY_DBINFO *vdp; + db_pgno_t pgno; + u_int32_t pgtype; +{ + DB *dbp; + DBT key, data; + int ret; + + dbp = vdp->salvage_pages; + + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + + key.data = &pgno; + key.size = sizeof(db_pgno_t); + + data.data = &pgtype; + data.size = sizeof(u_int32_t); + + /* + * Put an entry for this page, with pgno as key and type as data, + * unless it's already there, in which case it's presumably + * already been marked done. + */ + ret = __db_put(dbp, + vdp->thread_info, NULL, &key, &data, DB_NOOVERWRITE); + return (ret == DB_KEYEXIST ? 0 : ret); +} + +/* + * __db_vrfy_prdbt -- + * Print out a DBT data element from a verification routine. + * + * PUBLIC: int __db_vrfy_prdbt __P((DBT *, int, const char *, void *, + * PUBLIC: int (*)(void *, const void *), int, VRFY_DBINFO *)); + */ +int +__db_vrfy_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno, vdp) + DBT *dbtp; + int checkprint; + const char *prefix; + void *handle; + int (*callback) __P((void *, const void *)); + int is_recno; + VRFY_DBINFO *vdp; +{ + if (vdp != NULL) { + /* + * If vdp is non-NULL, we might be the first key in the + * "fake" subdatabase used for key/data pairs we can't + * associate with a known subdb. + * + * Check and clear the SALVAGE_PRINTHEADER flag; if + * it was set, print a subdatabase header. + */ + if (F_ISSET(vdp, SALVAGE_PRINTHEADER)) { + (void)__db_prheader( + NULL, "__OTHER__", 0, 0, handle, callback, vdp, 0); + F_CLR(vdp, SALVAGE_PRINTHEADER); + F_SET(vdp, SALVAGE_PRINTFOOTER); + } + + /* + * Even if the printable flag wasn't set by our immediate + * caller, it may be set on a salvage-wide basis. + */ + if (F_ISSET(vdp, SALVAGE_PRINTABLE)) + checkprint = 1; + } + return ( + __db_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno)); +} diff --git a/src/libs/resiprocate/contrib/db/db185/db185.c b/src/libs/resiprocate/contrib/db/db185/db185.c new file mode 100644 index 00000000..70cc2f89 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db185/db185.c @@ -0,0 +1,586 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#ifndef lint +static const char copyright[] = + "Copyright (c) 1996-2009 Oracle. All rights reserved.\n"; +#endif + +#include "db185_int.h" + +static int db185_close __P((DB185 *)); +static int db185_compare __P((DB *, const DBT *, const DBT *)); +static int db185_del __P((const DB185 *, const DBT185 *, u_int)); +static int db185_fd __P((const DB185 *)); +static int db185_get __P((const DB185 *, const DBT185 *, DBT185 *, u_int)); +static u_int32_t + db185_hash __P((DB *, const void *, u_int32_t)); +static size_t db185_prefix __P((DB *, const DBT *, const DBT *)); +static int db185_put __P((const DB185 *, DBT185 *, const DBT185 *, u_int)); +static int db185_seq __P((const DB185 *, DBT185 *, DBT185 *, u_int)); +static int db185_sync __P((const DB185 *, u_int)); + +/* + * EXTERN: #ifdef _DB185_INT_H_ + * EXTERN: DB185 *__db185_open + * EXTERN: __P((const char *, int, int, DBTYPE, const void *)); + * EXTERN: #else + * EXTERN: DB *__db185_open + * EXTERN: __P((const char *, int, int, DBTYPE, const void *)); + * EXTERN: #endif + */ +DB185 * +__db185_open(file, oflags, mode, type, openinfo) + const char *file; + int oflags, mode; + DBTYPE type; + const void *openinfo; +{ + const BTREEINFO *bi; + const HASHINFO *hi; + const RECNOINFO *ri; + DB *dbp; + DB185 *db185p; + DB_FH *fhp; + int ret; + + dbp = NULL; + db185p = NULL; + + if ((ret = db_create(&dbp, NULL, 0)) != 0) + goto err; + + if ((ret = __os_calloc(NULL, 1, sizeof(DB185), &db185p)) != 0) + goto err; + + /* + * !!! + * The DBTYPE enum wasn't initialized in DB 185, so it's off-by-one + * from DB 2.0. + */ + switch (type) { + case 0: /* DB_BTREE */ + type = DB_BTREE; + if ((bi = openinfo) != NULL) { + if (bi->flags & ~R_DUP) + goto einval; + if (bi->flags & R_DUP) + (void)dbp->set_flags(dbp, DB_DUP); + if (bi->cachesize != 0) + (void)dbp->set_cachesize + (dbp, 0, bi->cachesize, 0); + if (bi->minkeypage != 0) + (void)dbp->set_bt_minkey(dbp, bi->minkeypage); + if (bi->psize != 0) + (void)dbp->set_pagesize(dbp, bi->psize); + if (bi->prefix != NULL) { + db185p->prefix = bi->prefix; + dbp->set_bt_prefix(dbp, db185_prefix); + } + if (bi->compare != NULL) { + db185p->compare = bi->compare; + dbp->set_bt_compare(dbp, db185_compare); + } + if (bi->lorder != 0) + dbp->set_lorder(dbp, bi->lorder); + } + break; + case 1: /* DB_HASH */ + type = DB_HASH; + if ((hi = openinfo) != NULL) { + if (hi->bsize != 0) + (void)dbp->set_pagesize(dbp, hi->bsize); + if (hi->ffactor != 0) + (void)dbp->set_h_ffactor(dbp, hi->ffactor); + if (hi->nelem != 0) + (void)dbp->set_h_nelem(dbp, hi->nelem); + if (hi->cachesize != 0) + (void)dbp->set_cachesize + (dbp, 0, hi->cachesize, 0); + if (hi->hash != NULL) { + db185p->hash = hi->hash; + (void)dbp->set_h_hash(dbp, db185_hash); + } + if (hi->lorder != 0) + dbp->set_lorder(dbp, hi->lorder); + } + + break; + case 2: /* DB_RECNO */ + type = DB_RECNO; + + /* DB 1.85 did renumbering by default. */ + (void)dbp->set_flags(dbp, DB_RENUMBER); + + /* + * !!! + * The file name given to DB 1.85 recno is the name of the DB + * 2.0 backing file. If the file doesn't exist, create it if + * the user has the O_CREAT flag set, DB 1.85 did it for you, + * and DB 2.0 doesn't. + * + * !!! + * Setting the file name to NULL specifies that we're creating + * a temporary backing file, in DB 2.X. If we're opening the + * DB file read-only, change the flags to read-write, because + * temporary backing files cannot be opened read-only, and DB + * 2.X will return an error. We are cheating here -- if the + * application does a put on the database, it will succeed -- + * although that would be a stupid thing for the application + * to do. + * + * !!! + * Note, the file name in DB 1.85 was a const -- we don't do + * that in DB 2.0, so do that cast. + */ + if (file != NULL) { + if (oflags & O_CREAT && + __os_exists(NULL, file, NULL) != 0) + if (__os_openhandle(NULL, file, + oflags, mode, &fhp) == 0) + (void)__os_closehandle(NULL, fhp); + (void)dbp->set_re_source(dbp, file); + + if (O_RDONLY) + oflags &= ~O_RDONLY; + oflags |= O_RDWR; + file = NULL; + } + + /* + * !!! + * Set the O_CREAT flag in case the application didn't -- in DB + * 1.85 the backing file was the file being created and it may + * exist, but DB 2.X is creating a temporary Btree database and + * we need the create flag to do that. + */ + oflags |= O_CREAT; + + if ((ri = openinfo) != NULL) { + /* + * !!! + * We can't support the bfname field. + */ +#define BFMSG \ + "Berkeley DB: DB 1.85's recno bfname field is not supported.\n" + if (ri->bfname != NULL) { + dbp->errx(dbp, "%s", BFMSG); + goto einval; + } + + if (ri->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT)) + goto einval; + if (ri->flags & R_FIXEDLEN) { + if (ri->bval != 0) + (void)dbp->set_re_pad(dbp, ri->bval); + if (ri->reclen != 0) + (void)dbp->set_re_len(dbp, ri->reclen); + } else + if (ri->bval != 0) + (void)dbp->set_re_delim(dbp, ri->bval); + + /* + * !!! + * We ignore the R_NOKEY flag, but that's okay, it was + * only an optimization that was never implemented. + */ + if (ri->flags & R_SNAPSHOT) + (void)dbp->set_flags(dbp, DB_SNAPSHOT); + + if (ri->cachesize != 0) + (void)dbp->set_cachesize + (dbp, 0, ri->cachesize, 0); + if (ri->psize != 0) + (void)dbp->set_pagesize(dbp, ri->psize); + if (ri->lorder != 0) + dbp->set_lorder(dbp, ri->lorder); + } + break; + default: + goto einval; + } + + db185p->close = db185_close; + db185p->del = db185_del; + db185p->fd = db185_fd; + db185p->get = db185_get; + db185p->put = db185_put; + db185p->seq = db185_seq; + db185p->sync = db185_sync; + + /* + * Store a reference so we can indirect from the DB 1.85 structure + * to the underlying DB structure, and vice-versa. This has to be + * done BEFORE the DB::open method call because the hash callback + * is exercised as part of hash database initialization. + */ + db185p->dbp = dbp; + dbp->api_internal = db185p; + + /* Open the database. */ + if ((ret = dbp->open(dbp, NULL, + file, NULL, type, __db_openflags(oflags), mode)) != 0) + goto err; + + /* Create the cursor used for sequential ops. */ + if ((ret = dbp->cursor(dbp, NULL, &((DB185 *)db185p)->dbc, 0)) != 0) + goto err; + + return (db185p); + +einval: ret = EINVAL; + +err: if (db185p != NULL) + __os_free(NULL, db185p); + if (dbp != NULL) + (void)dbp->close(dbp, 0); + + __os_set_errno(ret); + return (NULL); +} + +static int +db185_close(db185p) + DB185 *db185p; +{ + DB *dbp; + int ret; + + dbp = db185p->dbp; + + ret = dbp->close(dbp, 0); + + __os_free(NULL, db185p); + + if (ret == 0) + return (0); + + __os_set_errno(ret); + return (-1); +} + +static int +db185_del(db185p, key185, flags) + const DB185 *db185p; + const DBT185 *key185; + u_int flags; +{ + DB *dbp; + DBT key; + int ret; + + dbp = db185p->dbp; + + memset(&key, 0, sizeof(key)); + key.data = key185->data; + key.size = key185->size; + + if (flags & ~R_CURSOR) + goto einval; + if (flags & R_CURSOR) + ret = db185p->dbc->del(db185p->dbc, 0); + else + ret = dbp->del(dbp, NULL, &key, 0); + + switch (ret) { + case 0: + return (0); + case DB_NOTFOUND: + return (1); + } + + if (0) { +einval: ret = EINVAL; + } + __os_set_errno(ret); + return (-1); +} + +static int +db185_fd(db185p) + const DB185 *db185p; +{ + DB *dbp; + int fd, ret; + + dbp = db185p->dbp; + + if ((ret = dbp->fd(dbp, &fd)) == 0) + return (fd); + + __os_set_errno(ret); + return (-1); +} + +static int +db185_get(db185p, key185, data185, flags) + const DB185 *db185p; + const DBT185 *key185; + DBT185 *data185; + u_int flags; +{ + DB *dbp; + DBT key, data; + int ret; + + dbp = db185p->dbp; + + memset(&key, 0, sizeof(key)); + key.data = key185->data; + key.size = key185->size; + memset(&data, 0, sizeof(data)); + data.data = data185->data; + data.size = data185->size; + + if (flags) + goto einval; + + switch (ret = dbp->get(dbp, NULL, &key, &data, 0)) { + case 0: + data185->data = data.data; + data185->size = data.size; + return (0); + case DB_NOTFOUND: + return (1); + } + + if (0) { +einval: ret = EINVAL; + } + __os_set_errno(ret); + return (-1); +} + +static int +db185_put(db185p, key185, data185, flags) + const DB185 *db185p; + DBT185 *key185; + const DBT185 *data185; + u_int flags; +{ + DB *dbp; + DBC *dbcp_put; + DBT key, data; + int ret, t_ret; + + dbp = db185p->dbp; + + memset(&key, 0, sizeof(key)); + key.data = key185->data; + key.size = key185->size; + memset(&data, 0, sizeof(data)); + data.data = data185->data; + data.size = data185->size; + + switch (flags) { + case 0: + ret = dbp->put(dbp, NULL, &key, &data, 0); + break; + case R_CURSOR: + ret = db185p->dbc->put(db185p->dbc, &key, &data, DB_CURRENT); + break; + case R_IAFTER: + case R_IBEFORE: + if (dbp->type != DB_RECNO) + goto einval; + + if ((ret = dbp->cursor(dbp, NULL, &dbcp_put, 0)) != 0) + break; + if ((ret = + dbcp_put->get(dbcp_put, &key, &data, DB_SET)) == 0) { + memset(&data, 0, sizeof(data)); + data.data = data185->data; + data.size = data185->size; + ret = dbcp_put->put(dbcp_put, &key, &data, + flags == R_IAFTER ? DB_AFTER : DB_BEFORE); + } + if ((t_ret = dbcp_put->close(dbcp_put)) != 0 && ret == 0) + ret = t_ret; + break; + case R_NOOVERWRITE: + ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE); + break; + case R_SETCURSOR: + if (dbp->type != DB_BTREE && dbp->type != DB_RECNO) + goto einval; + + if ((ret = dbp->put(dbp, NULL, &key, &data, 0)) != 0) + break; + ret = + db185p->dbc->get(db185p->dbc, &key, &data, DB_SET_RANGE); + break; + default: + goto einval; + } + + switch (ret) { + case 0: + key185->data = key.data; + key185->size = key.size; + return (0); + case DB_KEYEXIST: + return (1); + } + + if (0) { +einval: ret = EINVAL; + } + __os_set_errno(ret); + return (-1); +} + +static int +db185_seq(db185p, key185, data185, flags) + const DB185 *db185p; + DBT185 *key185, *data185; + u_int flags; +{ + DB *dbp; + DBT key, data; + int ret; + + dbp = db185p->dbp; + + memset(&key, 0, sizeof(key)); + key.data = key185->data; + key.size = key185->size; + memset(&data, 0, sizeof(data)); + data.data = data185->data; + data.size = data185->size; + + switch (flags) { + case R_CURSOR: + flags = DB_SET_RANGE; + break; + case R_FIRST: + flags = DB_FIRST; + break; + case R_LAST: + if (dbp->type != DB_BTREE && dbp->type != DB_RECNO) + goto einval; + flags = DB_LAST; + break; + case R_NEXT: + flags = DB_NEXT; + break; + case R_PREV: + if (dbp->type != DB_BTREE && dbp->type != DB_RECNO) + goto einval; + flags = DB_PREV; + break; + default: + goto einval; + } + switch (ret = db185p->dbc->get(db185p->dbc, &key, &data, flags)) { + case 0: + key185->data = key.data; + key185->size = key.size; + data185->data = data.data; + data185->size = data.size; + return (0); + case DB_NOTFOUND: + return (1); + } + + if (0) { +einval: ret = EINVAL; + } + __os_set_errno(ret); + return (-1); +} + +static int +db185_sync(db185p, flags) + const DB185 *db185p; + u_int flags; +{ + DB *dbp; + int ret; + + dbp = db185p->dbp; + + switch (flags) { + case 0: + break; + case R_RECNOSYNC: + /* + * !!! + * We can't support the R_RECNOSYNC flag. + */ +#define RSMSG \ + "Berkeley DB: DB 1.85's R_RECNOSYNC sync flag is not supported.\n" + dbp->errx(dbp, "%s", RSMSG); + /* FALLTHROUGH */ + default: + goto einval; + } + + if ((ret = dbp->sync(dbp, 0)) == 0) + return (0); + + if (0) { +einval: ret = EINVAL; + } + __os_set_errno(ret); + return (-1); +} + +/* + * db185_compare -- + * Cutout routine to call the user's Btree comparison function. + */ +static int +db185_compare(dbp, a, b) + DB *dbp; + const DBT *a, *b; +{ + DBT185 a185, b185; + + a185.data = a->data; + a185.size = a->size; + b185.data = b->data; + b185.size = b->size; + + return (((DB185 *)dbp->api_internal)->compare(&a185, &b185)); +} + +/* + * db185_prefix -- + * Cutout routine to call the user's Btree prefix function. + */ +static size_t +db185_prefix(dbp, a, b) + DB *dbp; + const DBT *a, *b; +{ + DBT185 a185, b185; + + a185.data = a->data; + a185.size = a->size; + b185.data = b->data; + b185.size = b->size; + + return (((DB185 *)dbp->api_internal)->prefix(&a185, &b185)); +} + +/* + * db185_hash -- + * Cutout routine to call the user's hash function. + */ +static u_int32_t +db185_hash(dbp, key, len) + DB *dbp; + const void *key; + u_int32_t len; +{ + return (((DB185 *)dbp->api_internal)->hash(key, (size_t)len)); +} diff --git a/src/libs/resiprocate/contrib/db/db185/db185_int.in b/src/libs/resiprocate/contrib/db/db185/db185_int.in new file mode 100644 index 00000000..4f3587d0 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db185/db185_int.in @@ -0,0 +1,128 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef _DB185_INT_H_ +#define _DB185_INT_H_ + +/* Routine flags. */ +#define R_CURSOR 1 /* del, put, seq */ +#define __R_UNUSED 2 /* UNUSED */ +#define R_FIRST 3 /* seq */ +#define R_IAFTER 4 /* put (RECNO) */ +#define R_IBEFORE 5 /* put (RECNO) */ +#define R_LAST 6 /* seq (BTREE, RECNO) */ +#define R_NEXT 7 /* seq */ +#define R_NOOVERWRITE 8 /* put */ +#define R_PREV 9 /* seq (BTREE, RECNO) */ +#define R_SETCURSOR 10 /* put (RECNO) */ +#define R_RECNOSYNC 11 /* sync (RECNO) */ + +typedef struct { + void *data; /* data */ + size_t size; /* data length */ +} DBT185; + +/* Access method description structure. */ +typedef struct __db185 { + DBTYPE type; /* Underlying db type. */ + int (*close) __P((struct __db185 *)); + int (*del) __P((const struct __db185 *, const DBT185 *, u_int)); + int (*get) + __P((const struct __db185 *, const DBT185 *, DBT185 *, u_int)); + int (*put) + __P((const struct __db185 *, DBT185 *, const DBT185 *, u_int)); + int (*seq) + __P((const struct __db185 *, DBT185 *, DBT185 *, u_int)); + int (*sync) __P((const struct __db185 *, u_int)); + DB *dbp; /* DB structure. Was void *internal. */ + int (*fd) __P((const struct __db185 *)); + + /* + * !!! + * The following elements added to the end of the DB 1.85 DB + * structure. + */ + DBC *dbc; /* DB cursor. */ + /* Various callback functions. */ + int (*compare) __P((const DBT185 *, const DBT185 *)); + size_t (*prefix) __P((const DBT185 *, const DBT185 *)); + u_int32_t (*hash) __P((const void *, size_t)); +} DB185; + +/* Structure used to pass parameters to the btree routines. */ +typedef struct { +#define R_DUP 0x01 /* duplicate keys */ + u_int32_t flags; + u_int32_t cachesize; /* bytes to cache */ + u_int32_t maxkeypage; /* maximum keys per page */ + u_int32_t minkeypage; /* minimum keys per page */ + u_int32_t psize; /* page size */ + int (*compare) /* comparison function */ + __P((const DBT185 *, const DBT185 *)); + size_t (*prefix) /* prefix function */ + __P((const DBT185 *, const DBT185 *)); + int lorder; /* byte order */ +} BTREEINFO; + +/* Structure used to pass parameters to the hashing routines. */ +typedef struct { + u_int32_t bsize; /* bucket size */ + u_int32_t ffactor; /* fill factor */ + u_int32_t nelem; /* number of elements */ + u_int32_t cachesize; /* bytes to cache */ + u_int32_t /* hash function */ + (*hash) __P((const void *, size_t)); + int lorder; /* byte order */ +} HASHINFO; + +/* Structure used to pass parameters to the record routines. */ +typedef struct { +#define R_FIXEDLEN 0x01 /* fixed-length records */ +#define R_NOKEY 0x02 /* key not required */ +#define R_SNAPSHOT 0x04 /* snapshot the input */ + u_int32_t flags; + u_int32_t cachesize; /* bytes to cache */ + u_int32_t psize; /* page size */ + int lorder; /* byte order */ + size_t reclen; /* record length (fixed-length records) */ + u_char bval; /* delimiting byte (variable-length records */ + char *bfname; /* btree file name */ +} RECNOINFO; +#endif /* !_DB185_INT_H_ */ diff --git a/src/libs/resiprocate/contrib/db/db_archive/db_archive.c b/src/libs/resiprocate/contrib/db/db_archive/db_archive.c new file mode 100644 index 00000000..f4c3818f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_archive/db_archive.c @@ -0,0 +1,184 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#ifndef lint +static const char copyright[] = + "Copyright (c) 1996-2009 Oracle. All rights reserved.\n"; +#endif + +int main __P((int, char *[])); +int usage __P((void)); +int version_check __P((void)); + +const char *progname; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB_ENV *dbenv; + u_int32_t flags; + int ch, exitval, ret, verbose; + char **file, *home, **list, *passwd; + + if ((progname = __db_rpath(argv[0])) == NULL) + progname = argv[0]; + else + ++progname; + + if ((ret = version_check()) != 0) + return (ret); + + dbenv = NULL; + flags = 0; + exitval = verbose = 0; + home = passwd = NULL; + file = list = NULL; + while ((ch = getopt(argc, argv, "adh:lP:sVv")) != EOF) + switch (ch) { + case 'a': + LF_SET(DB_ARCH_ABS); + break; + case 'd': + LF_SET(DB_ARCH_REMOVE); + break; + case 'h': + home = optarg; + break; + case 'l': + LF_SET(DB_ARCH_LOG); + break; + case 'P': + passwd = strdup(optarg); + memset(optarg, 0, strlen(optarg)); + if (passwd == NULL) { + fprintf(stderr, "%s: strdup: %s\n", + progname, strerror(errno)); + return (EXIT_FAILURE); + } + break; + case 's': + LF_SET(DB_ARCH_DATA); + break; + case 'V': + printf("%s\n", db_version(NULL, NULL, NULL)); + return (EXIT_SUCCESS); + case 'v': + /* + * !!! + * The verbose flag no longer actually does anything, + * but it's left rather than adding it back at some + * future date. + */ + verbose = 1; + break; + case '?': + default: + return (usage()); + } + argc -= optind; + argv += optind; + + if (argc != 0) + return (usage()); + + /* Handle possible interruptions. */ + __db_util_siginit(); + + /* + * Create an environment object and initialize it for error + * reporting. + */ + if ((ret = db_env_create(&dbenv, 0)) != 0) { + fprintf(stderr, + "%s: db_env_create: %s\n", progname, db_strerror(ret)); + goto shutdown; + } + + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, progname); + + if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, + passwd, DB_ENCRYPT_AES)) != 0) { + dbenv->err(dbenv, ret, "set_passwd"); + goto shutdown; + } + /* + * If attaching to a pre-existing environment fails, create a + * private one and try again. + */ + if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0 && + (ret == DB_VERSION_MISMATCH || + (ret = dbenv->open(dbenv, home, DB_CREATE | + DB_INIT_LOG | DB_PRIVATE | DB_USE_ENVIRON, 0)) != 0)) { + dbenv->err(dbenv, ret, "DB_ENV->open"); + goto shutdown; + } + + /* Get the list of names. */ + if ((ret = dbenv->log_archive(dbenv, &list, flags)) != 0) { + dbenv->err(dbenv, ret, "DB_ENV->log_archive"); + goto shutdown; + } + + /* Print the list of names. */ + if (list != NULL) { + for (file = list; *file != NULL; ++file) + printf("%s\n", *file); + free(list); + } + + if (0) { +shutdown: exitval = 1; + } + if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { + exitval = 1; + fprintf(stderr, + "%s: dbenv->close: %s\n", progname, db_strerror(ret)); + } + + if (passwd != NULL) + free(passwd); + + /* Resend any caught signal. */ + __db_util_sigresend(); + + return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} + +int +usage() +{ + (void)fprintf(stderr, + "usage: %s [-adlsVv] [-h home] [-P password]\n", progname); + return (EXIT_FAILURE); +} + +int +version_check() +{ + int v_major, v_minor, v_patch; + + /* Make sure we're loaded with the right version of the DB library. */ + (void)db_version(&v_major, &v_minor, &v_patch); + if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { + fprintf(stderr, + "%s: version %d.%d doesn't match library version %d.%d\n", + progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, + v_major, v_minor); + return (EXIT_FAILURE); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db_checkpoint/db_checkpoint.c b/src/libs/resiprocate/contrib/db/db_checkpoint/db_checkpoint.c new file mode 100644 index 00000000..ab8c3886 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_checkpoint/db_checkpoint.c @@ -0,0 +1,237 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#ifndef lint +static const char copyright[] = + "Copyright (c) 1996-2009 Oracle. All rights reserved.\n"; +#endif + +int main __P((int, char *[])); +int usage __P((void)); +int version_check __P((void)); + +const char *progname; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB_ENV *dbenv; + time_t now; + long argval; + u_int32_t flags, kbytes, minutes, seconds; + int ch, exitval, once, ret, verbose; + char *home, *logfile, *passwd, time_buf[CTIME_BUFLEN]; + + if ((progname = __db_rpath(argv[0])) == NULL) + progname = argv[0]; + else + ++progname; + + if ((ret = version_check()) != 0) + return (ret); + + /* + * !!! + * Don't allow a fully unsigned 32-bit number, some compilers get + * upset and require it to be specified in hexadecimal and so on. + */ +#define MAX_UINT32_T 2147483647 + + dbenv = NULL; + kbytes = minutes = 0; + exitval = once = verbose = 0; + flags = 0; + home = logfile = passwd = NULL; + while ((ch = getopt(argc, argv, "1h:k:L:P:p:Vv")) != EOF) + switch (ch) { + case '1': + once = 1; + flags = DB_FORCE; + break; + case 'h': + home = optarg; + break; + case 'k': + if (__db_getlong(NULL, progname, + optarg, 1, (long)MAX_UINT32_T, &argval)) + return (EXIT_FAILURE); + kbytes = (u_int32_t)argval; + break; + case 'L': + logfile = optarg; + break; + case 'P': + passwd = strdup(optarg); + memset(optarg, 0, strlen(optarg)); + if (passwd == NULL) { + fprintf(stderr, "%s: strdup: %s\n", + progname, strerror(errno)); + return (EXIT_FAILURE); + } + break; + case 'p': + if (__db_getlong(NULL, progname, + optarg, 1, (long)MAX_UINT32_T, &argval)) + return (EXIT_FAILURE); + minutes = (u_int32_t)argval; + break; + case 'V': + printf("%s\n", db_version(NULL, NULL, NULL)); + return (EXIT_SUCCESS); + case 'v': + verbose = 1; + break; + case '?': + default: + return (usage()); + } + argc -= optind; + argv += optind; + + if (argc != 0) + return (usage()); + + if (once == 0 && kbytes == 0 && minutes == 0) { + (void)fprintf(stderr, + "%s: at least one of -1, -k and -p must be specified\n", + progname); + return (usage()); + } + + /* Handle possible interruptions. */ + __db_util_siginit(); + + /* Log our process ID. */ + if (logfile != NULL && __db_util_logset(progname, logfile)) + goto shutdown; + + /* + * Create an environment object and initialize it for error + * reporting. + */ + if ((ret = db_env_create(&dbenv, 0)) != 0) { + fprintf(stderr, + "%s: db_env_create: %s\n", progname, db_strerror(ret)); + goto shutdown; + } + + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, progname); + + if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, + passwd, DB_ENCRYPT_AES)) != 0) { + dbenv->err(dbenv, ret, "set_passwd"); + goto shutdown; + } + + /* + * If attaching to a pre-existing environment fails, create a + * private one and try again. Turn on DB_THREAD in case a repmgr + * application wants to do checkpointing using this utility: repmgr + * requires DB_THREAD for all env handles. + */ +#ifdef HAVE_REPLICATION_THREADS +#define ENV_FLAGS (DB_THREAD | DB_USE_ENVIRON) +#else +#define ENV_FLAGS DB_USE_ENVIRON +#endif + if ((ret = dbenv->open(dbenv, home, ENV_FLAGS, 0)) != 0 && + (!once || ret == DB_VERSION_MISMATCH || + (ret = dbenv->open(dbenv, home, + DB_CREATE | DB_INIT_TXN | DB_PRIVATE | DB_USE_ENVIRON, 0)) != 0)) { + dbenv->err(dbenv, ret, "DB_ENV->open"); + goto shutdown; + } + + /* + * If we have only a time delay, then we'll sleep the right amount + * to wake up when a checkpoint is necessary. If we have a "kbytes" + * field set, then we'll check every 30 seconds. + */ + seconds = kbytes != 0 ? 30 : minutes * 60; + while (!__db_util_interrupted()) { + if (verbose) { + (void)time(&now); + dbenv->errx(dbenv, + "checkpoint begin: %s", __os_ctime(&now, time_buf)); + } + + if ((ret = dbenv->txn_checkpoint(dbenv, + kbytes, minutes, flags)) != 0) { + dbenv->err(dbenv, ret, "txn_checkpoint"); + goto shutdown; + } + + if (verbose) { + (void)time(&now); + dbenv->errx(dbenv, + "checkpoint complete: %s", __os_ctime(&now, time_buf)); + } + + if (once) + break; + + __os_yield(dbenv->env, seconds, 0); + } + + if (0) { +shutdown: exitval = 1; + } + + /* Clean up the logfile. */ + if (logfile != NULL) + (void)remove(logfile); + + /* Clean up the environment. */ + if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { + exitval = 1; + fprintf(stderr, + "%s: dbenv->close: %s\n", progname, db_strerror(ret)); + } + + if (passwd != NULL) + free(passwd); + + /* Resend any caught signal. */ + __db_util_sigresend(); + + return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} + +int +usage() +{ + (void)fprintf(stderr, "usage: %s [-1Vv]\n\t%s\n", progname, + "[-h home] [-k kbytes] [-L file] [-P password] [-p min]"); + return (EXIT_FAILURE); +} + +int +version_check() +{ + int v_major, v_minor, v_patch; + + /* Make sure we're loaded with the right version of the DB library. */ + (void)db_version(&v_major, &v_minor, &v_patch); + if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { + fprintf(stderr, + "%s: version %d.%d doesn't match library version %d.%d\n", + progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, + v_major, v_minor); + return (EXIT_FAILURE); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db_deadlock/db_deadlock.c b/src/libs/resiprocate/contrib/db/db_deadlock/db_deadlock.c new file mode 100644 index 00000000..f8359ff5 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_deadlock/db_deadlock.c @@ -0,0 +1,234 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#ifndef lint +static const char copyright[] = + "Copyright (c) 1996-2009 Oracle. All rights reserved.\n"; +#endif + +int main __P((int, char *[])); +int usage __P((void)); +int version_check __P((void)); + +const char *progname; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB_ENV *dbenv; + u_int32_t atype; + time_t now; + u_long secs, usecs; + int rejected, ch, exitval, ret, verbose; + char *home, *logfile, *passwd, *str, time_buf[CTIME_BUFLEN]; + + if ((progname = __db_rpath(argv[0])) == NULL) + progname = argv[0]; + else + ++progname; + + if ((ret = version_check()) != 0) + return (ret); + + dbenv = NULL; + atype = DB_LOCK_DEFAULT; + home = logfile = passwd = NULL; + secs = usecs = 0; + exitval = verbose = 0; + while ((ch = getopt(argc, argv, "a:h:L:P:t:Vv")) != EOF) + switch (ch) { + case 'a': + switch (optarg[0]) { + case 'e': + atype = DB_LOCK_EXPIRE; + break; + case 'm': + atype = DB_LOCK_MAXLOCKS; + break; + case 'n': + atype = DB_LOCK_MINLOCKS; + break; + case 'o': + atype = DB_LOCK_OLDEST; + break; + case 'W': + atype = DB_LOCK_MAXWRITE; + break; + case 'w': + atype = DB_LOCK_MINWRITE; + break; + case 'y': + atype = DB_LOCK_YOUNGEST; + break; + default: + return (usage()); + /* NOTREACHED */ + } + if (optarg[1] != '\0') + return (usage()); + break; + case 'h': + home = optarg; + break; + case 'L': + logfile = optarg; + break; + case 'P': + passwd = strdup(optarg); + memset(optarg, 0, strlen(optarg)); + if (passwd == NULL) { + fprintf(stderr, "%s: strdup: %s\n", + progname, strerror(errno)); + return (EXIT_FAILURE); + } + break; + case 't': + if ((str = strchr(optarg, '.')) != NULL) { + *str++ = '\0'; + if (*str != '\0' && __db_getulong( + NULL, progname, str, 0, LONG_MAX, &usecs)) + return (EXIT_FAILURE); + } + if (*optarg != '\0' && __db_getulong( + NULL, progname, optarg, 0, LONG_MAX, &secs)) + return (EXIT_FAILURE); + if (secs == 0 && usecs == 0) + return (usage()); + + break; + case 'V': + printf("%s\n", db_version(NULL, NULL, NULL)); + return (EXIT_SUCCESS); + case 'v': + verbose = 1; + break; + case '?': + default: + return (usage()); + } + argc -= optind; + argv += optind; + + if (argc != 0) + return (usage()); + + /* Handle possible interruptions. */ + __db_util_siginit(); + + /* Log our process ID. */ + if (logfile != NULL && __db_util_logset(progname, logfile)) + goto shutdown; + + /* + * Create an environment object and initialize it for error + * reporting. + */ + if ((ret = db_env_create(&dbenv, 0)) != 0) { + fprintf(stderr, + "%s: db_env_create: %s\n", progname, db_strerror(ret)); + goto shutdown; + } + + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, progname); + + if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, + passwd, DB_ENCRYPT_AES)) != 0) { + dbenv->err(dbenv, ret, "set_passwd"); + goto shutdown; + } + + if (verbose) { + (void)dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK, 1); + (void)dbenv->set_verbose(dbenv, DB_VERB_WAITSFOR, 1); + } + + /* An environment is required. */ + if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0) { + dbenv->err(dbenv, ret, "open"); + goto shutdown; + } + + while (!__db_util_interrupted()) { + if (verbose) { + (void)time(&now); + dbenv->errx(dbenv, + "running at %.24s", __os_ctime(&now, time_buf)); + } + + if ((ret = + dbenv->lock_detect(dbenv, 0, atype, &rejected)) != 0) { + dbenv->err(dbenv, ret, "DB_ENV->lock_detect"); + goto shutdown; + } + if (verbose) + dbenv->errx(dbenv, "rejected %d locks", rejected); + + /* Make a pass every "secs" secs and "usecs" usecs. */ + if (secs == 0 && usecs == 0) + break; + __os_yield(dbenv->env, secs, usecs); + } + + if (0) { +shutdown: exitval = 1; + } + + /* Clean up the logfile. */ + if (logfile != NULL) + (void)remove(logfile); + + /* Clean up the environment. */ + if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { + exitval = 1; + fprintf(stderr, + "%s: dbenv->close: %s\n", progname, db_strerror(ret)); + } + + if (passwd != NULL) + free(passwd); + + /* Resend any caught signal. */ + __db_util_sigresend(); + + return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} + +int +usage() +{ + (void)fprintf(stderr, + "usage: %s [-Vv] [-a e | m | n | o | W | w | y]\n\t%s\n", progname, + "[-h home] [-L file] [-P password] [-t sec.usec]"); + return (EXIT_FAILURE); +} + +int +version_check() +{ + int v_major, v_minor, v_patch; + + /* Make sure we're loaded with the right version of the DB library. */ + (void)db_version(&v_major, &v_minor, &v_patch); + if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { + fprintf(stderr, + "%s: version %d.%d doesn't match library version %d.%d\n", + progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, + v_major, v_minor); + return (EXIT_FAILURE); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db_dump/db_dump.c b/src/libs/resiprocate/contrib/db/db_dump/db_dump.c new file mode 100644 index 00000000..6263e169 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_dump/db_dump.c @@ -0,0 +1,510 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" + +#ifndef lint +static const char copyright[] = + "Copyright (c) 1996-2009 Oracle. All rights reserved.\n"; +#endif + +int db_init __P((DB_ENV *, char *, int, u_int32_t, int *)); +int dump_sub __P((DB_ENV *, DB *, char *, int, int)); +int main __P((int, char *[])); +int show_subs __P((DB *)); +int usage __P((void)); +int version_check __P((void)); + +const char *progname; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB_ENV *dbenv; + DB *dbp; + u_int32_t cache; + int ch; + int exitval, keyflag, lflag, mflag, nflag, pflag, sflag, private; + int ret, Rflag, rflag, resize; + char *dbname, *dopt, *filename, *home, *passwd; + + if ((progname = __db_rpath(argv[0])) == NULL) + progname = argv[0]; + else + ++progname; + + if ((ret = version_check()) != 0) + return (ret); + + dbenv = NULL; + dbp = NULL; + exitval = lflag = mflag = nflag = pflag = rflag = Rflag = sflag = 0; + keyflag = 0; + cache = MEGABYTE; + private = 0; + dbname = dopt = filename = home = passwd = NULL; + while ((ch = getopt(argc, argv, "d:f:h:klm:NpP:rRs:V")) != EOF) + switch (ch) { + case 'd': + dopt = optarg; + break; + case 'f': + if (freopen(optarg, "w", stdout) == NULL) { + fprintf(stderr, "%s: %s: reopen: %s\n", + progname, optarg, strerror(errno)); + return (EXIT_FAILURE); + } + break; + case 'h': + home = optarg; + break; + case 'k': + keyflag = 1; + break; + case 'l': + lflag = 1; + break; + case 'm': + mflag = 1; + dbname = optarg; + break; + case 'N': + nflag = 1; + break; + case 'P': + passwd = strdup(optarg); + memset(optarg, 0, strlen(optarg)); + if (passwd == NULL) { + fprintf(stderr, "%s: strdup: %s\n", + progname, strerror(errno)); + return (EXIT_FAILURE); + } + break; + case 'p': + pflag = 1; + break; + case 's': + sflag = 1; + dbname = optarg; + break; + case 'R': + Rflag = 1; + /* DB_AGGRESSIVE requires DB_SALVAGE */ + /* FALLTHROUGH */ + case 'r': + rflag = 1; + break; + case 'V': + printf("%s\n", db_version(NULL, NULL, NULL)); + return (EXIT_SUCCESS); + case '?': + default: + return (usage()); + } + argc -= optind; + argv += optind; + + /* + * A file name must be specified, unless we're looking for an in-memory + * db, in which case it must not. + */ + if (argc == 0 && mflag) + filename = NULL; + else if (argc == 1 && !mflag) + filename = argv[0]; + else + return (usage()); + + if (dopt != NULL && pflag) { + fprintf(stderr, + "%s: the -d and -p options may not both be specified\n", + progname); + return (EXIT_FAILURE); + } + if (lflag && sflag) { + fprintf(stderr, + "%s: the -l and -s options may not both be specified\n", + progname); + return (EXIT_FAILURE); + } + if ((lflag || sflag) && mflag) { + fprintf(stderr, + "%s: the -m option may not be specified with -l or -s\n", + progname); + return (EXIT_FAILURE); + } + + if (keyflag && rflag) { + fprintf(stderr, "%s: %s", + "the -k and -r or -R options may not both be specified\n", + progname); + return (EXIT_FAILURE); + } + + if ((mflag || sflag) && rflag) { + fprintf(stderr, "%s: %s", + "the -r or R options may not be specified with -m or -s\n", + progname); + return (EXIT_FAILURE); + } + + /* Handle possible interruptions. */ + __db_util_siginit(); + + /* + * Create an environment object and initialize it for error + * reporting. + */ +retry: if ((ret = db_env_create(&dbenv, 0)) != 0) { + fprintf(stderr, + "%s: db_env_create: %s\n", progname, db_strerror(ret)); + goto err; + } + + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, progname); + if (nflag) { + if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) { + dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING"); + goto err; + } + if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) { + dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC"); + goto err; + } + } + if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, + passwd, DB_ENCRYPT_AES)) != 0) { + dbenv->err(dbenv, ret, "set_passwd"); + goto err; + } + + /* Initialize the environment. */ + if (db_init(dbenv, home, rflag, cache, &private) != 0) + goto err; + + /* Create the DB object and open the file. */ + if ((ret = db_create(&dbp, dbenv, 0)) != 0) { + dbenv->err(dbenv, ret, "db_create"); + goto err; + } + +#if 0 + Set application-specific btree compression functions here. For example: + if ((ret = dbp->set_bt_compress( + dbp, local_compress_func, local_decompress_func)) != 0) { + dbp->err(dbp, ret, "DB->set_bt_compress"); + goto err; + } +#endif + + /* + * If we're salvaging, don't do an open; it might not be safe. + * Dispatch now into the salvager. + */ + if (rflag) { + /* The verify method is a destructor. */ + ret = dbp->verify(dbp, filename, NULL, stdout, + DB_SALVAGE | + (Rflag ? DB_AGGRESSIVE : 0) | + (pflag ? DB_PRINTABLE : 0)); + dbp = NULL; + if (ret != 0) + goto err; + goto done; + } + + if ((ret = dbp->open(dbp, NULL, + filename, dbname, DB_UNKNOWN, DB_RDWRMASTER|DB_RDONLY, 0)) != 0) { + dbp->err(dbp, ret, "open: %s", + filename == NULL ? dbname : filename); + goto err; + } + if (private != 0) { + if ((ret = __db_util_cache(dbp, &cache, &resize)) != 0) + goto err; + if (resize) { + (void)dbp->close(dbp, 0); + dbp = NULL; + + (void)dbenv->close(dbenv, 0); + dbenv = NULL; + goto retry; + } + } + + if (dopt != NULL) { + if ((ret = __db_dumptree(dbp, NULL, dopt, NULL)) != 0) { + dbp->err(dbp, ret, "__db_dumptree: %s", filename); + goto err; + } + } else if (lflag) { + if (dbp->get_multiple(dbp)) { + if (show_subs(dbp)) + goto err; + } else { + dbp->errx(dbp, + "%s: does not contain multiple databases", + filename); + goto err; + } + } else { + if (dbname == NULL && dbp->get_multiple(dbp)) { + if (dump_sub(dbenv, dbp, filename, pflag, keyflag)) + goto err; + } else + if (dbp->dump(dbp, NULL, + __db_pr_callback, stdout, pflag, keyflag)) + goto err; + } + + if (0) { +err: exitval = 1; + } +done: if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) { + exitval = 1; + dbenv->err(dbenv, ret, "close"); + } + if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { + exitval = 1; + fprintf(stderr, + "%s: dbenv->close: %s\n", progname, db_strerror(ret)); + } + + if (passwd != NULL) + free(passwd); + + /* Resend any caught signal. */ + __db_util_sigresend(); + + return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} + +/* + * db_init -- + * Initialize the environment. + */ +int +db_init(dbenv, home, is_salvage, cache, is_privatep) + DB_ENV *dbenv; + char *home; + int is_salvage; + u_int32_t cache; + int *is_privatep; +{ + int ret; + + /* + * Try and use the underlying environment when opening a database. + * We wish to use the buffer pool so our information is as up-to-date + * as possible, even if the mpool cache hasn't been flushed. + * + * If we are not doing a salvage, we want to join the environment; + * if a locking system is present, this will let us use it and be + * safe to run concurrently with other threads of control. (We never + * need to use transactions explicitly, as we're read-only.) Note + * that in CDB, too, this will configure our environment + * appropriately, and our cursors will (correctly) do locking as CDB + * read cursors. + * + * If we are doing a salvage, the verification code will protest + * if we initialize transactions, logging, or locking; do an + * explicit DB_INIT_MPOOL to try to join any existing environment + * before we create our own. + */ + *is_privatep = 0; + if ((ret = dbenv->open(dbenv, home, + DB_USE_ENVIRON | (is_salvage ? DB_INIT_MPOOL : 0), 0)) == 0) + return (0); + if (ret == DB_VERSION_MISMATCH) + goto err; + + /* + * An environment is required because we may be trying to look at + * databases in directories other than the current one. We could + * avoid using an environment iff the -h option wasn't specified, + * but that seems like more work than it's worth. + * + * No environment exists (or, at least no environment that includes + * an mpool region exists). Create one, but make it private so that + * no files are actually created. + */ + *is_privatep = 1; + if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) == 0 && + (ret = dbenv->open(dbenv, home, + DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0)) == 0) + return (0); + + /* An environment is required. */ +err: dbenv->err(dbenv, ret, "DB_ENV->open"); + return (1); +} + +/* + * dump_sub -- + * Dump out the records for a DB containing subdatabases. + */ +int +dump_sub(dbenv, parent_dbp, parent_name, pflag, keyflag) + DB_ENV *dbenv; + DB *parent_dbp; + char *parent_name; + int pflag, keyflag; +{ + DB *dbp; + DBC *dbcp; + DBT key, data; + int ret; + char *subdb; + + /* + * Get a cursor and step through the database, dumping out each + * subdatabase. + */ + if ((ret = parent_dbp->cursor(parent_dbp, NULL, &dbcp, 0)) != 0) { + dbenv->err(dbenv, ret, "DB->cursor"); + return (1); + } + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + while ((ret = dbcp->get(dbcp, &key, &data, + DB_IGNORE_LEASE | DB_NEXT)) == 0) { + /* Nul terminate the subdatabase name. */ + if ((subdb = malloc(key.size + 1)) == NULL) { + dbenv->err(dbenv, ENOMEM, NULL); + return (1); + } + memcpy(subdb, key.data, key.size); + subdb[key.size] = '\0'; + + /* Create the DB object and open the file. */ + if ((ret = db_create(&dbp, dbenv, 0)) != 0) { + dbenv->err(dbenv, ret, "db_create"); + free(subdb); + return (1); + } + +#if 0 + Set application-specific btree compression functions here. + For example: + + if ((ret = dbp->set_bt_compress( + dbp, local_compress_func, local_decompress_func)) != 0) { + dbp->err(dbp, ret, "DB->set_bt_compress"); + goto err; + } +#endif + + if ((ret = dbp->open(dbp, NULL, + parent_name, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) + dbp->err(dbp, ret, + "DB->open: %s:%s", parent_name, subdb); + if (ret == 0 && dbp->dump( + dbp, subdb, __db_pr_callback, stdout, pflag, keyflag)) + ret = 1; + (void)dbp->close(dbp, 0); + free(subdb); + if (ret != 0) + return (1); + } + if (ret != DB_NOTFOUND) { + parent_dbp->err(parent_dbp, ret, "DBcursor->get"); + return (1); + } + + if ((ret = dbcp->close(dbcp)) != 0) { + parent_dbp->err(parent_dbp, ret, "DBcursor->close"); + return (1); + } + + return (0); +} + +/* + * show_subs -- + * Display the subdatabases for a database. + */ +int +show_subs(dbp) + DB *dbp; +{ + DBC *dbcp; + DBT key, data; + int ret; + + /* + * Get a cursor and step through the database, printing out the key + * of each key/data pair. + */ + if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) { + dbp->err(dbp, ret, "DB->cursor"); + return (1); + } + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + while ((ret = dbcp->get(dbcp, &key, &data, + DB_IGNORE_LEASE | DB_NEXT)) == 0) { + if ((ret = dbp->dbenv->prdbt( + &key, 1, NULL, stdout, __db_pr_callback, 0)) != 0) { + dbp->errx(dbp, NULL); + return (1); + } + } + if (ret != DB_NOTFOUND) { + dbp->err(dbp, ret, "DBcursor->get"); + return (1); + } + + if ((ret = dbcp->close(dbcp)) != 0) { + dbp->err(dbp, ret, "DBcursor->close"); + return (1); + } + return (0); +} + +/* + * usage -- + * Display the usage message. + */ +int +usage() +{ + (void)fprintf(stderr, "usage: %s [-klNprRV]\n\t%s\n", + progname, + "[-d ahr] [-f output] [-h home] [-P password] [-s database] db_file"); + (void)fprintf(stderr, "usage: %s [-kNpV] %s\n", + progname, "[-d ahr] [-f output] [-h home] -m database"); + return (EXIT_FAILURE); +} + +int +version_check() +{ + int v_major, v_minor, v_patch; + + /* Make sure we're loaded with the right version of the DB library. */ + (void)db_version(&v_major, &v_minor, &v_patch); + if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { + fprintf(stderr, + "%s: version %d.%d doesn't match library version %d.%d\n", + progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, + v_major, v_minor); + return (EXIT_FAILURE); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db_dump185/db_dump185.c b/src/libs/resiprocate/contrib/db/db_dump185/db_dump185.c new file mode 100644 index 00000000..0e71b708 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_dump185/db_dump185.c @@ -0,0 +1,358 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef lint +static const char copyright[] = + "Copyright (c) 1996-2009 Oracle. All rights reserved.\n"; +#endif + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_DB_185_H +#include +#else +#include +#endif + +/* Hash Table Information */ +typedef struct hashhdr185 { /* Disk resident portion */ + int magic; /* Magic NO for hash tables */ + int version; /* Version ID */ + u_int32_t lorder; /* Byte Order */ + int bsize; /* Bucket/Page Size */ + int bshift; /* Bucket shift */ + int dsize; /* Directory Size */ + int ssize; /* Segment Size */ + int sshift; /* Segment shift */ + int ovfl_point; /* Where overflow pages are being + * allocated */ + int last_freed; /* Last overflow page freed */ + int max_bucket; /* ID of Maximum bucket in use */ + int high_mask; /* Mask to modulo into entire table */ + int low_mask; /* Mask to modulo into lower half of + * table */ + int ffactor; /* Fill factor */ + int nkeys; /* Number of keys in hash table */ +} HASHHDR185; +typedef struct htab185 { /* Memory resident data structure */ + HASHHDR185 hdr; /* Header */ +} HTAB185; + +/* Hash Table Information */ +typedef struct hashhdr186 { /* Disk resident portion */ + int32_t magic; /* Magic NO for hash tables */ + int32_t version; /* Version ID */ + int32_t lorder; /* Byte Order */ + int32_t bsize; /* Bucket/Page Size */ + int32_t bshift; /* Bucket shift */ + int32_t ovfl_point; /* Where overflow pages are being allocated */ + int32_t last_freed; /* Last overflow page freed */ + int32_t max_bucket; /* ID of Maximum bucket in use */ + int32_t high_mask; /* Mask to modulo into entire table */ + int32_t low_mask; /* Mask to modulo into lower half of table */ + int32_t ffactor; /* Fill factor */ + int32_t nkeys; /* Number of keys in hash table */ + int32_t hdrpages; /* Size of table header */ + int32_t h_charkey; /* value of hash(CHARKEY) */ +#define NCACHED 32 /* number of bit maps and spare points */ + int32_t spares[NCACHED];/* spare pages for overflow */ + /* address of overflow page bitmaps */ + u_int16_t bitmaps[NCACHED]; +} HASHHDR186; +typedef struct htab186 { /* Memory resident data structure */ + void *unused[2]; + HASHHDR186 hdr; /* Header */ +} HTAB186; + +typedef struct _epgno { + u_int32_t pgno; /* the page number */ + u_int16_t index; /* the index on the page */ +} EPGNO; + +typedef struct _epg { + void *page; /* the (pinned) page */ + u_int16_t index; /* the index on the page */ +} EPG; + +typedef struct _cursor { + EPGNO pg; /* B: Saved tree reference. */ + DBT key; /* B: Saved key, or key.data == NULL. */ + u_int32_t rcursor; /* R: recno cursor (1-based) */ + +#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */ +#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */ +#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */ +#define CURS_INIT 0x08 /* RB: Cursor initialized. */ + u_int8_t flags; +} CURSOR; + +/* The in-memory btree/recno data structure. */ +typedef struct _btree { + void *bt_mp; /* memory pool cookie */ + + void *bt_dbp; /* pointer to enclosing DB */ + + EPG bt_cur; /* current (pinned) page */ + void *bt_pinned; /* page pinned across calls */ + + CURSOR bt_cursor; /* cursor */ + + EPGNO bt_stack[50]; /* stack of parent pages */ + EPGNO *bt_sp; /* current stack pointer */ + + DBT bt_rkey; /* returned key */ + DBT bt_rdata; /* returned data */ + + int bt_fd; /* tree file descriptor */ + + u_int32_t bt_free; /* next free page */ + u_int32_t bt_psize; /* page size */ + u_int16_t bt_ovflsize; /* cut-off for key/data overflow */ + int bt_lorder; /* byte order */ + /* sorted order */ + enum { NOT, BACK, FORWARD } bt_order; + EPGNO bt_last; /* last insert */ + + /* B: key comparison function */ + int (*bt_cmp) __P((DBT *, DBT *)); + /* B: prefix comparison function */ + size_t (*bt_pfx) __P((DBT *, DBT *)); + /* R: recno input function */ + int (*bt_irec) __P((struct _btree *, u_int32_t)); + + FILE *bt_rfp; /* R: record FILE pointer */ + int bt_rfd; /* R: record file descriptor */ + + void *bt_cmap; /* R: current point in mapped space */ + void *bt_smap; /* R: start of mapped space */ + void *bt_emap; /* R: end of mapped space */ + size_t bt_msize; /* R: size of mapped region. */ + + u_int32_t bt_nrecs; /* R: number of records */ + size_t bt_reclen; /* R: fixed record length */ + u_char bt_bval; /* R: delimiting byte/pad character */ + +/* + * NB: + * B_NODUPS and R_RECNO are stored on disk, and may not be changed. + */ +#define B_INMEM 0x00001 /* in-memory tree */ +#define B_METADIRTY 0x00002 /* need to write metadata */ +#define B_MODIFIED 0x00004 /* tree modified */ +#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */ +#define B_RDONLY 0x00010 /* read-only tree */ + +#define B_NODUPS 0x00020 /* no duplicate keys permitted */ +#define R_RECNO 0x00080 /* record oriented tree */ + +#define R_CLOSEFP 0x00040 /* opened a file pointer */ +#define R_EOF 0x00100 /* end of input file reached. */ +#define R_FIXLEN 0x00200 /* fixed length records */ +#define R_MEMMAPPED 0x00400 /* memory mapped file. */ +#define R_INMEM 0x00800 /* in-memory file */ +#define R_MODIFIED 0x01000 /* modified file */ +#define R_RDONLY 0x02000 /* read-only file */ + +#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */ +#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */ +#define B_DB_TXN 0x10000 /* DB_TXN specified. */ + u_int32_t flags; +} BTREE; + +void db_btree __P((DB *, int)); +void db_hash __P((DB *, int)); +void dbt_dump __P((DBT *)); +void dbt_print __P((DBT *)); +int main __P((int, char *[])); +int usage __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB *dbp; + DBT key, data; + int ch, pflag, rval; + + pflag = 0; + while ((ch = getopt(argc, argv, "f:p")) != EOF) + switch (ch) { + case 'f': + if (freopen(optarg, "w", stdout) == NULL) { + fprintf(stderr, "db_dump185: %s: %s\n", + optarg, strerror(errno)); + return (EXIT_FAILURE); + } + break; + case 'p': + pflag = 1; + break; + case '?': + default: + return (usage()); + } + argc -= optind; + argv += optind; + + if (argc != 1) + return (usage()); + + if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_BTREE, NULL)) == NULL) { + if ((dbp = + dbopen(argv[0], O_RDONLY, 0, DB_HASH, NULL)) == NULL) { + fprintf(stderr, + "db_dump185: %s: %s\n", argv[0], strerror(errno)); + return (EXIT_FAILURE); + } + db_hash(dbp, pflag); + } else + db_btree(dbp, pflag); + + /* + * !!! + * DB 1.85 DBTs are a subset of DB 2.0 DBTs, so we just use the + * new dump/print routines. + */ + if (pflag) + while (!(rval = dbp->seq(dbp, &key, &data, R_NEXT))) { + dbt_print(&key); + dbt_print(&data); + } + else + while (!(rval = dbp->seq(dbp, &key, &data, R_NEXT))) { + dbt_dump(&key); + dbt_dump(&data); + } + + if (rval == -1) { + fprintf(stderr, "db_dump185: seq: %s\n", strerror(errno)); + return (EXIT_FAILURE); + } + return (EXIT_SUCCESS); +} + +/* + * db_hash -- + * Dump out hash header information. + */ +void +db_hash(dbp, pflag) + DB *dbp; + int pflag; +{ + HTAB185 *hash185p; + HTAB186 *hash186p; + + printf("format=%s\n", pflag ? "print" : "bytevalue"); + printf("type=hash\n"); + + /* DB 1.85 was version 2, DB 1.86 was version 3. */ + hash185p = dbp->internal; + if (hash185p->hdr.version > 2) { + hash186p = dbp->internal; + printf("h_ffactor=%lu\n", (u_long)hash186p->hdr.ffactor); + if (hash186p->hdr.lorder != 0) + printf("db_lorder=%lu\n", (u_long)hash186p->hdr.lorder); + printf("db_pagesize=%lu\n", (u_long)hash186p->hdr.bsize); + } else { + printf("h_ffactor=%lu\n", (u_long)hash185p->hdr.ffactor); + if (hash185p->hdr.lorder != 0) + printf("db_lorder=%lu\n", (u_long)hash185p->hdr.lorder); + printf("db_pagesize=%lu\n", (u_long)hash185p->hdr.bsize); + } + printf("HEADER=END\n"); +} + +/* + * db_btree -- + * Dump out btree header information. + */ +void +db_btree(dbp, pflag) + DB *dbp; + int pflag; +{ + BTREE *btp; + + btp = dbp->internal; + + printf("format=%s\n", pflag ? "print" : "bytevalue"); + printf("type=btree\n"); +#ifdef NOT_AVAILABLE_IN_185 + printf("bt_minkey=%lu\n", (u_long)XXX); + printf("bt_maxkey=%lu\n", (u_long)XXX); +#endif + if (btp->bt_lorder != 0) + printf("db_lorder=%lu\n", (u_long)btp->bt_lorder); + printf("db_pagesize=%lu\n", (u_long)btp->bt_psize); + if (!(btp->flags & B_NODUPS)) + printf("duplicates=1\n"); + printf("HEADER=END\n"); +} + +static char hex[] = "0123456789abcdef"; + +/* + * dbt_dump -- + * Write out a key or data item using byte values. + */ +void +dbt_dump(dbtp) + DBT *dbtp; +{ + size_t len; + u_int8_t *p; + + for (len = dbtp->size, p = dbtp->data; len--; ++p) + (void)printf("%c%c", + hex[(*p & 0xf0) >> 4], hex[*p & 0x0f]); + printf("\n"); +} + +/* + * dbt_print -- + * Write out a key or data item using printable characters. + */ +void +dbt_print(dbtp) + DBT *dbtp; +{ + size_t len; + u_int8_t *p; + + for (len = dbtp->size, p = dbtp->data; len--; ++p) + if (isprint((int)*p)) { + if (*p == '\\') + (void)printf("\\"); + (void)printf("%c", *p); + } else + (void)printf("\\%c%c", + hex[(*p & 0xf0) >> 4], hex[*p & 0x0f]); + printf("\n"); +} + +/* + * usage -- + * Display the usage message. + */ +int +usage() +{ + (void)fprintf(stderr, "usage: db_dump185 [-p] [-f file] db_file\n"); + return (EXIT_FAILURE); +} diff --git a/src/libs/resiprocate/contrib/db/db_load/db_load.c b/src/libs/resiprocate/contrib/db/db_load/db_load.c new file mode 100644 index 00000000..acc07a32 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_load/db_load.c @@ -0,0 +1,1394 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" + +#ifndef lint +static const char copyright[] = + "Copyright (c) 1996-2009 Oracle. All rights reserved.\n"; +#endif + +typedef struct { /* XXX: Globals. */ + const char *progname; /* Program name. */ + char *hdrbuf; /* Input file header. */ + u_long lineno; /* Input file line number. */ + u_long origline; /* Original file line number. */ + int endodata; /* Reached the end of a database. */ + int endofile; /* Reached the end of the input. */ + int version; /* Input version. */ + char *home; /* Env home. */ + char *passwd; /* Env passwd. */ + int private; /* Private env. */ + u_int32_t cache; /* Env cache size. */ +} LDG; + +int badend __P((DB_ENV *)); +void badnum __P((DB_ENV *)); +int configure __P((DB_ENV *, DB *, char **, char **, int *)); +int convprintable __P((DB_ENV *, char *, char **)); +int db_init __P((DB_ENV *, char *, u_int32_t, int *)); +int dbt_rdump __P((DB_ENV *, DBT *)); +int dbt_rprint __P((DB_ENV *, DBT *)); +int dbt_rrecno __P((DB_ENV *, DBT *, int)); +int dbt_to_recno __P((DB_ENV *, DBT *, db_recno_t *)); +int env_create __P((DB_ENV **, LDG *)); +int load __P((DB_ENV *, char *, DBTYPE, char **, u_int, LDG *, int *)); +int main __P((int, char *[])); +int rheader __P((DB_ENV *, DB *, DBTYPE *, char **, int *, int *)); +int usage __P((void)); +int version_check __P((void)); + +const char *progname; + +#define G(f) ((LDG *)dbenv->app_private)->f + + /* Flags to the load function. */ +#define LDF_NOHEADER 0x01 /* No dump header. */ +#define LDF_NOOVERWRITE 0x02 /* Don't overwrite existing rows. */ +#define LDF_PASSWORD 0x04 /* Encrypt created databases. */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + enum { NOTSET, FILEID_RESET, LSN_RESET, STANDARD_LOAD } mode; + extern char *optarg; + extern int optind; + DBTYPE dbtype; + DB_ENV *dbenv; + LDG ldg; + u_int ldf; + int ch, existed, exitval, ret; + char **clist, **clp; + + if ((progname = __db_rpath(argv[0])) == NULL) + progname = argv[0]; + else + ++progname; + + if ((exitval = version_check()) != 0) + goto done; + + ldg.progname = progname; + ldg.lineno = 0; + ldg.endodata = ldg.endofile = 0; + ldg.version = 1; + ldg.cache = MEGABYTE; + ldg.hdrbuf = NULL; + ldg.home = NULL; + ldg.passwd = NULL; + + mode = NOTSET; + ldf = 0; + exitval = existed = 0; + dbtype = DB_UNKNOWN; + + /* Allocate enough room for configuration arguments. */ + if ((clp = clist = + (char **)calloc((size_t)argc + 1, sizeof(char *))) == NULL) { + fprintf(stderr, "%s: %s\n", ldg.progname, strerror(ENOMEM)); + exitval = 1; + goto done; + } + + /* + * There are two modes for db_load: -r and everything else. The -r + * option zeroes out the database LSN's or resets the file ID, it + * doesn't really "load" a new database. The functionality is in + * db_load because we don't have a better place to put it, and we + * don't want to create a new utility for just that functionality. + */ + while ((ch = getopt(argc, argv, "c:f:h:nP:r:Tt:V")) != EOF) + switch (ch) { + case 'c': + if (mode != NOTSET && mode != STANDARD_LOAD) { + exitval = usage(); + goto done; + } + mode = STANDARD_LOAD; + + *clp++ = optarg; + break; + case 'f': + if (mode != NOTSET && mode != STANDARD_LOAD) { + exitval = usage(); + goto done; + } + mode = STANDARD_LOAD; + + if (freopen(optarg, "r", stdin) == NULL) { + fprintf(stderr, "%s: %s: reopen: %s\n", + ldg.progname, optarg, strerror(errno)); + exitval = usage(); + goto done; + } + break; + case 'h': + ldg.home = optarg; + break; + case 'n': + if (mode != NOTSET && mode != STANDARD_LOAD) { + exitval = usage(); + goto done; + } + mode = STANDARD_LOAD; + + ldf |= LDF_NOOVERWRITE; + break; + case 'P': + ldg.passwd = strdup(optarg); + memset(optarg, 0, strlen(optarg)); + if (ldg.passwd == NULL) { + fprintf(stderr, "%s: strdup: %s\n", + ldg.progname, strerror(errno)); + exitval = usage(); + goto done; + } + ldf |= LDF_PASSWORD; + break; + case 'r': + if (mode == STANDARD_LOAD) { + exitval = usage(); + goto done; + } + if (strcmp(optarg, "lsn") == 0) + mode = LSN_RESET; + else if (strcmp(optarg, "fileid") == 0) + mode = FILEID_RESET; + else { + exitval = usage(); + goto done; + } + break; + case 'T': + if (mode != NOTSET && mode != STANDARD_LOAD) { + exitval = usage(); + goto done; + } + mode = STANDARD_LOAD; + + ldf |= LDF_NOHEADER; + break; + case 't': + if (mode != NOTSET && mode != STANDARD_LOAD) { + exitval = usage(); + goto done; + } + mode = STANDARD_LOAD; + + if (strcmp(optarg, "btree") == 0) { + dbtype = DB_BTREE; + break; + } + if (strcmp(optarg, "hash") == 0) { + dbtype = DB_HASH; + break; + } + if (strcmp(optarg, "recno") == 0) { + dbtype = DB_RECNO; + break; + } + if (strcmp(optarg, "queue") == 0) { + dbtype = DB_QUEUE; + break; + } + exitval = usage(); + goto done; + case 'V': + printf("%s\n", db_version(NULL, NULL, NULL)); + return (EXIT_SUCCESS); + case '?': + default: + exitval = usage(); + goto done; + } + argc -= optind; + argv += optind; + + if (argc != 1) { + exitval = usage(); + goto done; + } + + /* Handle possible interruptions. */ + __db_util_siginit(); + + /* + * Create an environment object initialized for error reporting, and + * then open it. + */ + if (env_create(&dbenv, &ldg) != 0) + goto shutdown; + + /* If we're resetting the LSNs, that's an entirely separate path. */ + switch (mode) { + case FILEID_RESET: + exitval = dbenv->fileid_reset( + dbenv, argv[0], ldf & LDF_PASSWORD ? DB_ENCRYPT : 0); + break; + case LSN_RESET: + exitval = dbenv->lsn_reset( + dbenv, argv[0], ldf & LDF_PASSWORD ? DB_ENCRYPT : 0); + break; + case NOTSET: + case STANDARD_LOAD: + while (!ldg.endofile) + if (load(dbenv, argv[0], dbtype, clist, ldf, + &ldg, &existed) != 0) + goto shutdown; + break; + } + + if (0) { +shutdown: exitval = 1; + } + if ((ret = dbenv->close(dbenv, 0)) != 0) { + exitval = 1; + fprintf(stderr, + "%s: dbenv->close: %s\n", ldg.progname, db_strerror(ret)); + } + + /* Resend any caught signal. */ + __db_util_sigresend(); + free(clist); + if (ldg.passwd != NULL) + free(ldg.passwd); + + /* + * Return 0 on success, 1 if keys existed already, and 2 on failure. + * + * Technically, this is wrong, because exit of anything other than + * 0 is implementation-defined by the ANSI C standard. I don't see + * any good solutions that don't involve API changes. + */ +done: + return (exitval == 0 ? (existed == 0 ? 0 : 1) : 2); +} + +/* + * load -- + * Load a database. + */ +int +load(dbenv, name, argtype, clist, flags, ldg, existedp) + DB_ENV *dbenv; + char *name, **clist; + DBTYPE argtype; + u_int flags; + LDG *ldg; + int *existedp; +{ + DB *dbp; + DBC *dbc; + DBT key, rkey, data, *readp, *writep; + DBTYPE dbtype; + DB_TXN *ctxn, *txn; + db_recno_t recno, datarecno; + u_int32_t put_flags; + int ascii_recno, checkprint, hexkeys, keyflag, keys, resize, ret, rval; + char *subdb; + + put_flags = LF_ISSET(LDF_NOOVERWRITE) ? DB_NOOVERWRITE : 0; + G(endodata) = 0; + + dbc = NULL; + subdb = NULL; + ctxn = txn = NULL; + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + memset(&rkey, 0, sizeof(DBT)); + +retry_db: + dbtype = DB_UNKNOWN; + keys = -1; + hexkeys = -1; + keyflag = -1; + + /* Create the DB object. */ + if ((ret = db_create(&dbp, dbenv, 0)) != 0) { + dbenv->err(dbenv, ret, "db_create"); + goto err; + } + + /* Read the header -- if there's no header, we expect flat text. */ + if (LF_ISSET(LDF_NOHEADER)) { + checkprint = 1; + dbtype = argtype; + } else { + if (rheader(dbenv, + dbp, &dbtype, &subdb, &checkprint, &keys) != 0) + goto err; + if (G(endofile)) + goto done; + } + + /* + * Apply command-line configuration changes. (We apply command-line + * configuration changes to all databases that are loaded, e.g., all + * subdatabases.) + */ + if (configure(dbenv, dbp, clist, &subdb, &keyflag)) + goto err; + + if (keys != 1) { + if (keyflag == 1) { + dbp->err(dbp, EINVAL, "No keys specified in file"); + goto err; + } + } + else if (keyflag == 0) { + dbp->err(dbp, EINVAL, "Keys specified in file"); + goto err; + } + else + keyflag = 1; + + if (dbtype == DB_BTREE || dbtype == DB_HASH) { + if (keyflag == 0) + dbp->err(dbp, + EINVAL, "Btree and Hash must specify keys"); + else + keyflag = 1; + } + + if (argtype != DB_UNKNOWN) { + + if (dbtype == DB_RECNO || dbtype == DB_QUEUE) + if (keyflag != 1 && argtype != DB_RECNO && + argtype != DB_QUEUE) { + dbenv->errx(dbenv, + "improper database type conversion specified"); + goto err; + } + dbtype = argtype; + } + + if (dbtype == DB_UNKNOWN) { + dbenv->errx(dbenv, "no database type specified"); + goto err; + } + + if (keyflag == -1) + keyflag = 0; + + /* + * Recno keys have only been printed in hexadecimal starting + * with db_dump format version 3 (DB 3.2). + * + * !!! + * Note that version is set in rheader(), which must be called before + * this assignment. + */ + hexkeys = (G(version) >= 3 && keyflag == 1 && checkprint == 0); + + if (keyflag == 1 && (dbtype == DB_RECNO || dbtype == DB_QUEUE)) + ascii_recno = 1; + else + ascii_recno = 0; + + /* If configured with a password, encrypt databases we create. */ + if (LF_ISSET(LDF_PASSWORD) && + (ret = dbp->set_flags(dbp, DB_ENCRYPT)) != 0) { + dbp->err(dbp, ret, "DB->set_flags: DB_ENCRYPT"); + goto err; + } + +#if 0 + Set application-specific btree comparison, compression, or hash + functions here. For example: + + if ((ret = dbp->set_bt_compare(dbp, local_comparison_func)) != 0) { + dbp->err(dbp, ret, "DB->set_bt_compare"); + goto err; + } + if ((ret = dbp->set_bt_compress(dbp, local_compress_func, + local_decompress_func)) != 0) { + dbp->err(dbp, ret, "DB->set_bt_compress"); + goto err; + } + if ((ret = dbp->set_h_hash(dbp, local_hash_func)) != 0) { + dbp->err(dbp, ret, "DB->set_h_hash"); + goto err; + } +#endif + + /* Open the DB file. */ + if ((ret = dbp->open(dbp, NULL, name, subdb, dbtype, + DB_CREATE | (TXN_ON(dbenv->env) ? DB_AUTO_COMMIT : 0), + DB_MODE_666)) != 0) { + dbp->err(dbp, ret, "DB->open: %s", name); + goto err; + } + if (ldg->private != 0) { + if ((ret = __db_util_cache(dbp, &ldg->cache, &resize)) != 0) + goto err; + if (resize) { + if ((ret = dbp->close(dbp, 0)) != 0) + goto err; + dbp = NULL; + if ((ret = dbenv->close(dbenv, 0)) != 0) + goto err; + if ((ret = env_create(&dbenv, ldg)) != 0) + goto err; + goto retry_db; + } + } + + /* Initialize the key/data pair. */ + readp = writep = &key; + if (dbtype == DB_RECNO || dbtype == DB_QUEUE) { + key.size = sizeof(recno); + if (keyflag) { + key.data = &datarecno; + if (checkprint) { + readp = &rkey; + goto key_data; + } + } else + key.data = &recno; + } else +key_data: if ((readp->data = malloc(readp->ulen = 1024)) == NULL) { + dbenv->err(dbenv, ENOMEM, NULL); + goto err; + } + if ((data.data = malloc(data.ulen = 1024)) == NULL) { + dbenv->err(dbenv, ENOMEM, NULL); + goto err; + } + + if (TXN_ON(dbenv->env) && + (ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0) + goto err; + + if (put_flags == 0 && (ret = dbp->cursor(dbp, + txn, &dbc, DB_CURSOR_BULK)) != 0) + goto err; + + /* Get each key/data pair and add them to the database. */ + for (recno = 1; !__db_util_interrupted(); ++recno) { + if (!keyflag) { + if (checkprint) { + if (dbt_rprint(dbenv, &data)) + goto err; + } else { + if (dbt_rdump(dbenv, &data)) + goto err; + } + } else { + if (checkprint) { + if (dbt_rprint(dbenv, readp)) + goto err; + if (ascii_recno && + dbt_to_recno(dbenv, readp, &datarecno) != 0) + goto err; + + if (!G(endodata) && dbt_rprint(dbenv, &data)) + goto odd_count; + } else { + if (ascii_recno) { + if (dbt_rrecno(dbenv, readp, hexkeys)) + goto err; + } else + if (dbt_rdump(dbenv, readp)) + goto err; + + if (!G(endodata) && dbt_rdump(dbenv, &data)) { +odd_count: dbenv->errx(dbenv, + "odd number of key/data pairs"); + goto err; + } + } + } + if (G(endodata)) + break; +retry: + if (put_flags != 0 && txn != NULL) + if ((ret = dbenv->txn_begin(dbenv, txn, &ctxn, 0)) != 0) + goto err; + switch (ret = ((put_flags == 0) ? + dbc->put(dbc, writep, &data, DB_KEYLAST) : + dbp->put(dbp, ctxn, writep, &data, put_flags))) { + case 0: + if (ctxn != NULL) { + if ((ret = + ctxn->commit(ctxn, DB_TXN_NOSYNC)) != 0) + goto err; + ctxn = NULL; + } + break; + case DB_KEYEXIST: + *existedp = 1; + dbenv->errx(dbenv, + "%s: line %d: key already exists, not loaded:", + name, + !keyflag ? recno : recno * 2 - 1); + + (void)dbenv->prdbt(&key, + checkprint, 0, stderr, __db_pr_callback, 0); + break; + case DB_LOCK_DEADLOCK: + /* If we have a child txn, retry--else it's fatal. */ + if (ctxn != NULL) { + if ((ret = ctxn->abort(ctxn)) != 0) + goto err; + ctxn = NULL; + goto retry; + } + /* FALLTHROUGH */ + default: + dbenv->err(dbenv, ret, NULL); + if (ctxn != NULL) { + (void)ctxn->abort(ctxn); + ctxn = NULL; + } + goto err; + } + if (ctxn != NULL) { + if ((ret = ctxn->abort(ctxn)) != 0) + goto err; + ctxn = NULL; + } + } +done: rval = 0; + if (dbc != NULL && (ret = dbc->close(dbc)) != 0) { + dbc = NULL; + goto err; + } + if (txn != NULL && (ret = txn->commit(txn, 0)) != 0) { + txn = NULL; + goto err; + } + + if (0) { +err: rval = 1; + if (dbc != NULL) + (void)dbc->close(dbc); + if (txn != NULL) + (void)txn->abort(txn); + } + + /* Close the database. */ + if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) { + dbenv->err(dbenv, ret, "DB->close"); + rval = 1; + } + + if (G(hdrbuf) != NULL) + free(G(hdrbuf)); + G(hdrbuf) = NULL; + /* Free allocated memory. */ + if (subdb != NULL) + free(subdb); + if (dbtype != DB_RECNO && dbtype != DB_QUEUE && key.data != NULL) + free(key.data); + if (rkey.data != NULL) + free(rkey.data); + free(data.data); + + return (rval); +} + +/* + * env_create -- + * Create the environment and initialize it for error reporting. + */ +int +env_create(dbenvp, ldg) + DB_ENV **dbenvp; + LDG *ldg; +{ + DB_ENV *dbenv; + int ret; + + if ((ret = db_env_create(dbenvp, 0)) != 0) { + fprintf(stderr, + "%s: db_env_create: %s\n", ldg->progname, db_strerror(ret)); + return (ret); + } + dbenv = *dbenvp; + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, ldg->progname); + if (ldg->passwd != NULL && (ret = dbenv->set_encrypt(dbenv, + ldg->passwd, DB_ENCRYPT_AES)) != 0) { + dbenv->err(dbenv, ret, "set_passwd"); + return (ret); + } + if ((ret = db_init(dbenv, ldg->home, ldg->cache, &ldg->private)) != 0) + return (ret); + dbenv->app_private = ldg; + + return (0); +} + +/* + * db_init -- + * Initialize the environment. + */ +int +db_init(dbenv, home, cache, is_private) + DB_ENV *dbenv; + char *home; + u_int32_t cache; + int *is_private; +{ + u_int32_t flags; + int ret; + + *is_private = 0; + /* We may be loading into a live environment. Try and join. */ + flags = DB_USE_ENVIRON | + DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN; + if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0) + return (0); + if (ret == DB_VERSION_MISMATCH) + goto err; + + /* + * We're trying to load a database. + * + * An environment is required because we may be trying to look at + * databases in directories other than the current one. We could + * avoid using an environment iff the -h option wasn't specified, + * but that seems like more work than it's worth. + * + * No environment exists (or, at least no environment that includes + * an mpool region exists). Create one, but make it private so that + * no files are actually created. + */ + LF_CLR(DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN); + LF_SET(DB_CREATE | DB_PRIVATE); + *is_private = 1; + if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) { + dbenv->err(dbenv, ret, "set_cachesize"); + return (1); + } + if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0) + return (0); + + /* An environment is required. */ +err: dbenv->err(dbenv, ret, "DB_ENV->open"); + return (1); +} + +#define FLAG(name, value, keyword, flag) \ + if (strcmp(name, keyword) == 0) { \ + switch (*value) { \ + case '1': \ + if ((ret = dbp->set_flags(dbp, flag)) != 0) { \ + dbp->err(dbp, ret, "%s: set_flags: %s", \ + G(progname), name); \ + goto err; \ + } \ + break; \ + case '0': \ + break; \ + default: \ + badnum(dbenv); \ + goto err; \ + } \ + continue; \ + } +#define NUMBER(name, value, keyword, func, t) \ + if (strcmp(name, keyword) == 0) { \ + if ((ret = __db_getlong(dbenv, \ + NULL, value, 0, LONG_MAX, &val)) != 0 || \ + (ret = dbp->func(dbp, (t)val)) != 0) \ + goto nameerr; \ + continue; \ + } +#define STRING(name, value, keyword, func) \ + if (strcmp(name, keyword) == 0) { \ + if ((ret = dbp->func(dbp, value[0])) != 0) \ + goto nameerr; \ + continue; \ + } + +/* + * The code to check a command-line or input header argument against a list + * of configuration options. It's #defined because it's used in two places + * and the two places have gotten out of sync more than once. + */ +#define CONFIGURATION_LIST_COMPARE \ + NUMBER(name, value, "bt_minkey", set_bt_minkey, u_int32_t); \ + FLAG(name, value, "chksum", DB_CHKSUM); \ + NUMBER(name, value, "db_lorder", set_lorder, int); \ + NUMBER(name, value, "db_pagesize", set_pagesize, u_int32_t); \ + FLAG(name, value, "duplicates", DB_DUP); \ + FLAG(name, value, "dupsort", DB_DUPSORT); \ + NUMBER(name, value, "extentsize", set_q_extentsize, u_int32_t); \ + NUMBER(name, value, "h_ffactor", set_h_ffactor, u_int32_t); \ + NUMBER(name, value, "h_nelem", set_h_nelem, u_int32_t); \ + NUMBER(name, value, "re_len", set_re_len, u_int32_t); \ + STRING(name, value, "re_pad", set_re_pad); \ + FLAG(name, value, "recnum", DB_RECNUM); \ + FLAG(name, value, "renumber", DB_RENUMBER); \ + if (strcmp(name, "compressed") == 0) { \ + switch (*value) { \ + case '1': \ + if ((ret = dbp->set_bt_compress(dbp, NULL, \ + NULL)) != 0) \ + goto nameerr; \ + break; \ + case '0': \ + break; \ + default: \ + badnum(dbenv); \ + goto err; \ + } \ + continue; \ + } + +/* + * configure -- + * Handle command-line configuration options. + */ +int +configure(dbenv, dbp, clp, subdbp, keysp) + DB_ENV *dbenv; + DB *dbp; + char **clp, **subdbp; + int *keysp; +{ + long val; + int ret, savech; + char *name, *value; + + for (; (name = *clp) != NULL; *--value = savech, ++clp) { + if ((value = strchr(name, '=')) == NULL) { + dbp->errx(dbp, + "command-line configuration uses name=value format"); + return (1); + } + savech = *value; + *value++ = '\0'; + + if (strcmp(name, "database") == 0 || + strcmp(name, "subdatabase") == 0) { + if (*subdbp != NULL) + free(*subdbp); + if ((*subdbp = strdup(value)) == NULL) { + dbp->err(dbp, ENOMEM, NULL); + return (1); + } + continue; + } + if (strcmp(name, "keys") == 0) { + if (strcmp(value, "1") == 0) + *keysp = 1; + else if (strcmp(value, "0") == 0) + *keysp = 0; + else { + badnum(dbenv); + return (1); + } + continue; + } + + CONFIGURATION_LIST_COMPARE; + + dbp->errx(dbp, + "unknown command-line configuration keyword \"%s\"", name); + return (1); + } + return (0); + +nameerr: + dbp->err(dbp, ret, "%s: %s=%s", G(progname), name, value); +err: return (1); +} + +/* + * rheader -- + * Read the header message. + */ +int +rheader(dbenv, dbp, dbtypep, subdbp, checkprintp, keysp) + DB_ENV *dbenv; + DB *dbp; + DBTYPE *dbtypep; + char **subdbp; + int *checkprintp, *keysp; +{ + DBT *keys, *kp; + size_t buflen, linelen, start; + long val; + int ch, first, hdr, ret; + char *buf, *name, *p, *value; + u_int32_t i, nparts; + + *dbtypep = DB_UNKNOWN; + *checkprintp = 0; + name = NULL; + + /* + * We start with a smallish buffer; most headers are small. + * We may need to realloc it for a large subdatabase name. + */ + buflen = 4096; + if (G(hdrbuf) == NULL) { + hdr = 0; + if ((buf = malloc(buflen)) == NULL) + goto memerr; + G(hdrbuf) = buf; + G(origline) = G(lineno); + } else { + hdr = 1; + buf = G(hdrbuf); + G(lineno) = G(origline); + } + + start = 0; + for (first = 1;; first = 0) { + ++G(lineno); + + /* Read a line, which may be of arbitrary length, into buf. */ + linelen = 0; + buf = &G(hdrbuf)[start]; + if (hdr == 0) { + for (;;) { + if ((ch = getchar()) == EOF) { + if (!first || ferror(stdin)) + goto badfmt; + G(endofile) = 1; + break; + } + + /* + * If the buffer is too small, double it. + */ + if (linelen + start == buflen) { + G(hdrbuf) = + realloc(G(hdrbuf), buflen *= 2); + if (G(hdrbuf) == NULL) + goto memerr; + buf = &G(hdrbuf)[start]; + } + + if (ch == '\n') + break; + + buf[linelen++] = ch; + } + if (G(endofile) == 1) + break; + buf[linelen++] = '\0'; + } else + linelen = strlen(buf) + 1; + start += linelen; + + if (name != NULL) { + free(name); + name = NULL; + } + /* If we don't see the expected information, it's an error. */ + if ((name = strdup(buf)) == NULL) + goto memerr; + if ((p = strchr(name, '=')) == NULL) + goto badfmt; + *p++ = '\0'; + + value = p--; + + if (name[0] == '\0') + goto badfmt; + + /* + * The only values that may be zero-length are database names. + * In the original Berkeley DB code it was possible to create + * zero-length database names, and the db_load code was then + * changed to allow such databases to be be dumped and loaded. + * [#8204] + */ + if (strcmp(name, "database") == 0 || + strcmp(name, "subdatabase") == 0) { + if ((ret = convprintable(dbenv, value, subdbp)) != 0) { + dbp->err(dbp, ret, "error reading db name"); + goto err; + } + continue; + } + + /* No other values may be zero-length. */ + if (value[0] == '\0') + goto badfmt; + + if (strcmp(name, "HEADER") == 0) + break; + if (strcmp(name, "VERSION") == 0) { + /* + * Version 1 didn't have a "VERSION" header line. We + * only support versions 1, 2, and 3 of the dump format. + */ + G(version) = atoi(value); + + if (G(version) > 3) { + dbp->errx(dbp, + "line %lu: VERSION %d is unsupported", + G(lineno), G(version)); + goto err; + } + continue; + } + if (strcmp(name, "format") == 0) { + if (strcmp(value, "bytevalue") == 0) { + *checkprintp = 0; + continue; + } + if (strcmp(value, "print") == 0) { + *checkprintp = 1; + continue; + } + goto badfmt; + } + if (strcmp(name, "type") == 0) { + if (strcmp(value, "btree") == 0) { + *dbtypep = DB_BTREE; + continue; + } + if (strcmp(value, "hash") == 0) { + *dbtypep = DB_HASH; + continue; + } + if (strcmp(value, "recno") == 0) { + *dbtypep = DB_RECNO; + continue; + } + if (strcmp(value, "queue") == 0) { + *dbtypep = DB_QUEUE; + continue; + } + dbp->errx(dbp, "line %lu: unknown type", G(lineno)); + goto err; + } + if (strcmp(name, "keys") == 0) { + if (strcmp(value, "1") == 0) + *keysp = 1; + else if (strcmp(value, "0") == 0) + *keysp = 0; + else { + badnum(dbenv); + goto err; + } + continue; + } + if (strcmp(name, "nparts") == 0) { + if ((ret = __db_getlong(dbenv, + NULL, value, 0, LONG_MAX, &val)) != 0) { + badnum(dbenv); + goto err; + } + nparts = (u_int32_t) val; + if ((keys = + malloc((nparts - 1) * sizeof(DBT))) == NULL) { + dbenv->err(dbenv, ENOMEM, NULL); + goto err; + } + kp = keys; + for (i = 1; i < nparts; kp++, i++) { + if ((kp->data = + malloc(kp->ulen = 1024)) == NULL) { + dbenv->err(dbenv, ENOMEM, NULL); + goto err; + } + if (*checkprintp) { + if (dbt_rprint(dbenv, kp)) + goto err; + } else { + if (dbt_rdump(dbenv, kp)) + goto err; + } + } + if ((ret = dbp->set_partition( + dbp, nparts, keys, NULL)) != 0) + goto err; + + continue; + } + + CONFIGURATION_LIST_COMPARE; + + dbp->errx(dbp, + "unknown input-file header configuration keyword \"%s\"", + name); + goto err; + } + ret = 0; + + if (0) { +nameerr: dbp->err(dbp, ret, "%s: %s=%s", G(progname), name, value); + ret = 1; + } + if (0) { +badfmt: dbp->errx(dbp, "line %lu: unexpected format", G(lineno)); + ret = 1; + } + if (0) { +memerr: dbp->errx(dbp, "unable to allocate memory"); +err: ret = 1; + } + if (name != NULL) + free(name); + return (ret); +} + +/* + * Macro to convert a pair of hex bytes to a decimal value. + * + * !!! + * Note that this macro is side-effect safe. This was done deliberately, + * callers depend on it. + */ +#define DIGITIZE(store, v1, v2) { \ + char _v1, _v2; \ + _v1 = (v1); \ + _v2 = (v2); \ + if ((_v1) > 'f' || (_v2) > 'f') \ + return (badend(dbenv)); \ + (store) = \ + ((_v1) == '0' ? 0 : \ + ((_v1) == '1' ? 1 : \ + ((_v1) == '2' ? 2 : \ + ((_v1) == '3' ? 3 : \ + ((_v1) == '4' ? 4 : \ + ((_v1) == '5' ? 5 : \ + ((_v1) == '6' ? 6 : \ + ((_v1) == '7' ? 7 : \ + ((_v1) == '8' ? 8 : \ + ((_v1) == '9' ? 9 : \ + ((_v1) == 'a' ? 10 : \ + ((_v1) == 'b' ? 11 : \ + ((_v1) == 'c' ? 12 : \ + ((_v1) == 'd' ? 13 : \ + ((_v1) == 'e' ? 14 : 15))))))))))))))) << 4 | \ + ((_v2) == '0' ? 0 : \ + ((_v2) == '1' ? 1 : \ + ((_v2) == '2' ? 2 : \ + ((_v2) == '3' ? 3 : \ + ((_v2) == '4' ? 4 : \ + ((_v2) == '5' ? 5 : \ + ((_v2) == '6' ? 6 : \ + ((_v2) == '7' ? 7 : \ + ((_v2) == '8' ? 8 : \ + ((_v2) == '9' ? 9 : \ + ((_v2) == 'a' ? 10 : \ + ((_v2) == 'b' ? 11 : \ + ((_v2) == 'c' ? 12 : \ + ((_v2) == 'd' ? 13 : \ + ((_v2) == 'e' ? 14 : 15))))))))))))))); \ +} + +/* + * convprintable -- + * Convert a printable-encoded string into a newly allocated string. + * + * In an ideal world, this would probably share code with dbt_rprint, but + * that's set up to read character-by-character (to avoid large memory + * allocations that aren't likely to be a problem here), and this has fewer + * special cases to deal with. + * + * Note that despite the printable encoding, the char * interface to this + * function (which is, not coincidentally, also used for database naming) + * means that outstr cannot contain any nuls. + */ +int +convprintable(dbenv, instr, outstrp) + DB_ENV *dbenv; + char *instr, **outstrp; +{ + char *outstr; + + /* + * Just malloc a string big enough for the whole input string; + * the output string will be smaller (or of equal length). + * + * Note that we may be passed a zero-length string and need to + * be able to duplicate it. + */ + if ((outstr = malloc(strlen(instr) + 1)) == NULL) + return (ENOMEM); + + *outstrp = outstr; + + for ( ; *instr != '\0'; instr++) + if (*instr == '\\') { + if (*++instr == '\\') { + *outstr++ = '\\'; + continue; + } + DIGITIZE(*outstr++, *instr, *++instr); + } else + *outstr++ = *instr; + + *outstr = '\0'; + + return (0); +} + +/* + * dbt_rprint -- + * Read a printable line into a DBT structure. + */ +int +dbt_rprint(dbenv, dbtp) + DB_ENV *dbenv; + DBT *dbtp; +{ + u_int32_t len; + u_int8_t *p; + int c1, c2, escape, first; + char buf[32]; + + ++G(lineno); + + first = 1; + escape = 0; + for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) { + if (c1 == EOF) { + if (len == 0) { + G(endofile) = G(endodata) = 1; + return (0); + } + return (badend(dbenv)); + } + if (first) { + first = 0; + if (G(version) > 1) { + if (c1 != ' ') { + buf[0] = c1; + if (fgets(buf + 1, + sizeof(buf) - 1, stdin) == NULL || + strcmp(buf, "DATA=END\n") != 0) + return (badend(dbenv)); + G(endodata) = 1; + return (0); + } + continue; + } + } + if (escape) { + if (c1 != '\\') { + if ((c2 = getchar()) == EOF) + return (badend(dbenv)); + DIGITIZE(c1, c1, c2); + } + escape = 0; + } else + if (c1 == '\\') { + escape = 1; + continue; + } + if (len >= dbtp->ulen - 10) { + dbtp->ulen *= 2; + if ((dbtp->data = + realloc(dbtp->data, dbtp->ulen)) == NULL) { + dbenv->err(dbenv, ENOMEM, NULL); + return (1); + } + p = (u_int8_t *)dbtp->data + len; + } + ++len; + *p++ = c1; + } + dbtp->size = len; + + return (0); +} + +/* + * dbt_rdump -- + * Read a byte dump line into a DBT structure. + */ +int +dbt_rdump(dbenv, dbtp) + DB_ENV *dbenv; + DBT *dbtp; +{ + u_int32_t len; + u_int8_t *p; + int c1, c2, first; + char buf[32]; + + ++G(lineno); + + first = 1; + for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) { + if (c1 == EOF) { + if (len == 0) { + G(endofile) = G(endodata) = 1; + return (0); + } + return (badend(dbenv)); + } + if (first) { + first = 0; + if (G(version) > 1) { + if (c1 != ' ') { + buf[0] = c1; + if (fgets(buf + 1, + sizeof(buf) - 1, stdin) == NULL || + strcmp(buf, "DATA=END\n") != 0) + return (badend(dbenv)); + G(endodata) = 1; + return (0); + } + continue; + } + } + if ((c2 = getchar()) == EOF) + return (badend(dbenv)); + if (len >= dbtp->ulen - 10) { + dbtp->ulen *= 2; + if ((dbtp->data = + realloc(dbtp->data, dbtp->ulen)) == NULL) { + dbenv->err(dbenv, ENOMEM, NULL); + return (1); + } + p = (u_int8_t *)dbtp->data + len; + } + ++len; + DIGITIZE(*p++, c1, c2); + } + dbtp->size = len; + + return (0); +} + +/* + * dbt_rrecno -- + * Read a record number dump line into a DBT structure. + */ +int +dbt_rrecno(dbenv, dbtp, ishex) + DB_ENV *dbenv; + DBT *dbtp; + int ishex; +{ + char buf[32], *p, *q; + u_long recno; + + ++G(lineno); + + if (fgets(buf, sizeof(buf), stdin) == NULL) { + G(endofile) = G(endodata) = 1; + return (0); + } + + if (strcmp(buf, "DATA=END\n") == 0) { + G(endodata) = 1; + return (0); + } + + if (buf[0] != ' ') + goto err; + + /* + * If we're expecting a hex key, do an in-place conversion + * of hex to straight ASCII before calling __db_getulong(). + */ + if (ishex) { + for (p = q = buf + 1; *q != '\0' && *q != '\n';) { + /* + * 0-9 in hex are 0x30-0x39, so this is easy. + * We should alternate between 3's and [0-9], and + * if the [0-9] are something unexpected, + * __db_getulong will fail, so we only need to catch + * end-of-string conditions. + */ + if (*q++ != '3') + goto err; + if (*q == '\n' || *q == '\0') + goto err; + *p++ = *q++; + } + *p = '\0'; + } + + if (__db_getulong(dbenv, G(progname), buf + 1, 0, 0, &recno)) + goto err; + + *((db_recno_t *)dbtp->data) = recno; + dbtp->size = sizeof(db_recno_t); + return (0); + +err: return (badend(dbenv)); +} + +int +dbt_to_recno(dbenv, dbt, recnop) + DB_ENV *dbenv; + DBT *dbt; + db_recno_t *recnop; +{ + char buf[32]; /* Large enough for 2^64. */ + + memcpy(buf, dbt->data, dbt->size); + buf[dbt->size] = '\0'; + + return (__db_getulong(dbenv, G(progname), buf, 0, 0, (u_long *)recnop)); +} + +/* + * badnum -- + * Display the bad number message. + */ +void +badnum(dbenv) + DB_ENV *dbenv; +{ + dbenv->errx(dbenv, + "boolean name=value pairs require a value of 0 or 1"); +} + +/* + * badend -- + * Display the bad end to input message. + */ +int +badend(dbenv) + DB_ENV *dbenv; +{ + dbenv->errx(dbenv, "unexpected end of input data or key/data pair"); + return (1); +} + +/* + * usage -- + * Display the usage message. + */ +int +usage() +{ + (void)fprintf(stderr, "usage: %s %s\n\t%s\n", progname, + "[-nTV] [-c name=value] [-f file]", + "[-h home] [-P password] [-t btree | hash | recno | queue] db_file"); + (void)fprintf(stderr, "usage: %s %s\n", + progname, "-r lsn | fileid [-h home] [-P password] db_file"); + return (EXIT_FAILURE); +} + +int +version_check() +{ + int v_major, v_minor, v_patch; + + /* Make sure we're loaded with the right version of the DB library. */ + (void)db_version(&v_major, &v_minor, &v_patch); + if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { + fprintf(stderr, + "%s: version %d.%d doesn't match library version %d.%d\n", + progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, + v_major, v_minor); + return (EXIT_FAILURE); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db_printlog/README b/src/libs/resiprocate/contrib/db/db_printlog/README new file mode 100644 index 00000000..8e8279d1 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_printlog/README @@ -0,0 +1,34 @@ +# $Id$ + +Berkeley DB log dump utility. This utility dumps out a DB log in human +readable form, a record at a time, to assist in recovery and transaction +abort debugging. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +commit.awk Output transaction ID of committed transactions. + +count.awk Print out the number of log records for transactions + that we encountered. + +dbname.awk Take a comma-separated list of database names and spit + out all the log records that affect those databases. + +fileid.awk Take a comma-separated list of file numbers and spit out + all the log records that affect those file numbers. + +logstat.awk Display log record count/size statistics. + +pgno.awk Take a comma-separated list of page numbers and spit + out all the log records that affect those page numbers. + +range.awk Print out a range of the log. + +rectype.awk Print out a range of the log -- command line should + set RECTYPE to the a comma separated list of the + rectypes (or partial strings of rectypes) sought. + +status.awk Read through db_printlog output and list the transactions + encountered, and whether they committed or aborted. + +txn.awk Print out all the records for a comma-separated list of + transaction IDs. diff --git a/src/libs/resiprocate/contrib/db/db_printlog/commit.awk b/src/libs/resiprocate/contrib/db/db_printlog/commit.awk new file mode 100644 index 00000000..569d2382 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_printlog/commit.awk @@ -0,0 +1,7 @@ +# $Id$ +# +# Output tid of committed transactions. + +/txn_regop/ { + print $5 +} diff --git a/src/libs/resiprocate/contrib/db/db_printlog/count.awk b/src/libs/resiprocate/contrib/db/db_printlog/count.awk new file mode 100644 index 00000000..a5e87cc6 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_printlog/count.awk @@ -0,0 +1,9 @@ +# $Id$ +# +# Print out the number of log records for transactions that we +# encountered. + +/^\[/{ + if ($5 != 0) + print $5 +} diff --git a/src/libs/resiprocate/contrib/db/db_printlog/db_printlog.c b/src/libs/resiprocate/contrib/db/db_printlog/db_printlog.c new file mode 100644 index 00000000..d81c53fa --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_printlog/db_printlog.c @@ -0,0 +1,648 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/btree.h" +#include "dbinc/fop.h" +#include "dbinc/hash.h" +#include "dbinc/log.h" +#include "dbinc/qam.h" +#include "dbinc/txn.h" + +#ifndef lint +static const char copyright[] = + "Copyright (c) 1996-2009 Oracle. All rights reserved.\n"; +#endif + +int db_printlog_print_app_record __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); +int env_init_print __P((ENV *, u_int32_t, DB_DISTAB *)); +int env_init_print_42 __P((ENV *, DB_DISTAB *)); +int env_init_print_43 __P((ENV *, DB_DISTAB *)); +int env_init_print_47 __P((ENV *, DB_DISTAB *)); +int lsn_arg __P((char *, DB_LSN *)); +int main __P((int, char *[])); +int open_rep_db __P((DB_ENV *, DB **, DBC **)); +int usage __P((void)); +int version_check __P((void)); + +const char *progname; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB *dbp; + DBC *dbc; + DBT data, keydbt; + DB_DISTAB dtab; + DB_ENV *dbenv; + DB_LOGC *logc; + DB_LSN key, start, stop, verslsn; + ENV *env; + u_int32_t logcflag, newversion, version; + int ch, cmp, exitval, nflag, rflag, ret, repflag; + char *home, *passwd; + + if ((progname = __db_rpath(argv[0])) == NULL) + progname = argv[0]; + else + ++progname; + + if ((ret = version_check()) != 0) + return (ret); + + dbp = NULL; + dbc = NULL; + dbenv = NULL; + logc = NULL; + ZERO_LSN(start); + ZERO_LSN(stop); + exitval = nflag = rflag = repflag = 0; + home = passwd = NULL; + + memset(&dtab, 0, sizeof(dtab)); + + while ((ch = getopt(argc, argv, "b:e:h:NP:rRV")) != EOF) + switch (ch) { + case 'b': + /* Don't use getsubopt(3), not all systems have it. */ + if (lsn_arg(optarg, &start)) + return (usage()); + break; + case 'e': + /* Don't use getsubopt(3), not all systems have it. */ + if (lsn_arg(optarg, &stop)) + return (usage()); + break; + case 'h': + home = optarg; + break; + case 'N': + nflag = 1; + break; + case 'P': + passwd = strdup(optarg); + memset(optarg, 0, strlen(optarg)); + if (passwd == NULL) { + fprintf(stderr, "%s: strdup: %s\n", + progname, strerror(errno)); + return (EXIT_FAILURE); + } + break; + case 'r': + rflag = 1; + break; + case 'R': /* Undocumented */ + repflag = 1; + break; + case 'V': + printf("%s\n", db_version(NULL, NULL, NULL)); + return (EXIT_SUCCESS); + case '?': + default: + return (usage()); + } + argc -= optind; + argv += optind; + + if (argc > 0) + return (usage()); + + /* Handle possible interruptions. */ + __db_util_siginit(); + + /* + * Create an environment object and initialize it for error + * reporting. + */ + if ((ret = db_env_create(&dbenv, 0)) != 0) { + fprintf(stderr, + "%s: db_env_create: %s\n", progname, db_strerror(ret)); + goto shutdown; + } + + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, progname); + + if (nflag) { + if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) { + dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING"); + goto shutdown; + } + if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) { + dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC"); + goto shutdown; + } + } + + if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, + passwd, DB_ENCRYPT_AES)) != 0) { + dbenv->err(dbenv, ret, "set_passwd"); + goto shutdown; + } + + /* + * Set up an app-specific dispatch function so that we can gracefully + * handle app-specific log records. + */ + if ((ret = dbenv->set_app_dispatch( + dbenv, db_printlog_print_app_record)) != 0) { + dbenv->err(dbenv, ret, "app_dispatch"); + goto shutdown; + } + + /* + * An environment is required, but as all we're doing is reading log + * files, we create one if it doesn't already exist. If we create + * it, create it private so it automatically goes away when we're done. + * If we are reading the replication database, do not open the env + * with logging, because we don't want to log the opens. + */ + if (repflag) { + if ((ret = dbenv->open(dbenv, home, + DB_INIT_MPOOL | DB_USE_ENVIRON, 0)) != 0 && + (ret == DB_VERSION_MISMATCH || + (ret = dbenv->open(dbenv, home, + DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0)) + != 0)) { + dbenv->err(dbenv, ret, "DB_ENV->open"); + goto shutdown; + } + } else if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0 && + (ret == DB_VERSION_MISMATCH || + (ret = dbenv->open(dbenv, home, + DB_CREATE | DB_INIT_LOG | DB_PRIVATE | DB_USE_ENVIRON, 0)) != 0)) { + dbenv->err(dbenv, ret, "DB_ENV->open"); + goto shutdown; + } + env = dbenv->env; + + /* Allocate a log cursor. */ + if (repflag) { + if ((ret = open_rep_db(dbenv, &dbp, &dbc)) != 0) + goto shutdown; + } else if ((ret = dbenv->log_cursor(dbenv, &logc, 0)) != 0) { + dbenv->err(dbenv, ret, "DB_ENV->log_cursor"); + goto shutdown; + } + + if (IS_ZERO_LSN(start)) { + memset(&keydbt, 0, sizeof(keydbt)); + logcflag = rflag ? DB_PREV : DB_NEXT; + } else { + key = start; + logcflag = DB_SET; + } + memset(&data, 0, sizeof(data)); + + /* + * If we're using the repflag, we're immediately initializing + * the print table. Use the current version. If we're printing + * the log then initialize version to 0 so that we get the + * correct version right away. + */ + if (repflag) + version = DB_LOGVERSION; + else + version = 0; + ZERO_LSN(verslsn); + + /* Initialize print callbacks if repflag. */ + if (repflag && + (ret = env_init_print(env, version, &dtab)) != 0) { + dbenv->err(dbenv, ret, "callback: initialization"); + goto shutdown; + } + for (; !__db_util_interrupted(); logcflag = rflag ? DB_PREV : DB_NEXT) { + if (repflag) { + ret = dbc->get(dbc, &keydbt, &data, logcflag); + if (ret == 0) + key = ((__rep_control_args *)keydbt.data)->lsn; + } else + ret = logc->get(logc, &key, &data, logcflag); + if (ret != 0) { + if (ret == DB_NOTFOUND) + break; + dbenv->err(dbenv, + ret, repflag ? "DBC->get" : "DB_LOGC->get"); + goto shutdown; + } + + /* + * We may have reached the end of the range we're displaying. + */ + if (!IS_ZERO_LSN(stop)) { + cmp = LOG_COMPARE(&key, &stop); + if ((rflag && cmp < 0) || (!rflag && cmp > 0)) + break; + } + if (!repflag && key.file != verslsn.file) { + /* + * If our log file changed, we need to see if the + * version of the log file changed as well. + * If it changed, reset the print table. + */ + if ((ret = logc->version(logc, &newversion, 0)) != 0) { + dbenv->err(dbenv, ret, "DB_LOGC->version"); + goto shutdown; + } + if (version != newversion) { + version = newversion; + if ((ret = env_init_print(env, version, + &dtab)) != 0) { + dbenv->err(dbenv, ret, + "callback: initialization"); + goto shutdown; + } + } + } + + ret = __db_dispatch(dbenv->env, + &dtab, &data, &key, DB_TXN_PRINT, NULL); + + /* + * XXX + * Just in case the underlying routines don't flush. + */ + (void)fflush(stdout); + + if (ret != 0) { + dbenv->err(dbenv, ret, "tx: dispatch"); + goto shutdown; + } + } + + if (0) { +shutdown: exitval = 1; + } + if (logc != NULL && (ret = logc->close(logc, 0)) != 0) + exitval = 1; + + if (dbc != NULL && (ret = dbc->close(dbc)) != 0) + exitval = 1; + + if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) + exitval = 1; + + if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { + exitval = 1; + fprintf(stderr, + "%s: dbenv->close: %s\n", progname, db_strerror(ret)); + } + + if (passwd != NULL) + free(passwd); + + /* Resend any caught signal. */ + __db_util_sigresend(); + + return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} + +/* + * env_init_print -- + */ +int +env_init_print(env, version, dtabp) + ENV *env; + u_int32_t version; + DB_DISTAB *dtabp; +{ + int ret; + + /* + * We need to prime the print table with the current print + * functions. Then we overwrite only specific entries based on + * each previous version we support. + */ + if ((ret = __bam_init_print(env, dtabp)) != 0) + goto err; + if ((ret = __crdel_init_print(env, dtabp)) != 0) + goto err; + if ((ret = __db_init_print(env, dtabp)) != 0) + goto err; + if ((ret = __dbreg_init_print(env, dtabp)) != 0) + goto err; + if ((ret = __fop_init_print(env, dtabp)) != 0) + goto err; +#ifdef HAVE_HASH + if ((ret = __ham_init_print(env, dtabp)) != 0) + goto err; +#endif +#ifdef HAVE_QUEUE + if ((ret = __qam_init_print(env, dtabp)) != 0) + goto err; +#endif + if ((ret = __txn_init_print(env, dtabp)) != 0) + goto err; + + switch (version) { + case DB_LOGVERSION: + ret = 0; + break; + + /* + * There are no log record/recovery differences between + * 4.4 and 4.5. The log version changed due to checksum. + * There are no log recovery differences between + * 4.5 and 4.6. The name of the rep_gen in txn_checkpoint + * changed (to spare, since we don't use it anymore). + */ + case DB_LOGVERSION_48: + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_sort_44_print, DB___db_pg_sort_44)) != 0) + goto err; + break; + case DB_LOGVERSION_47: + case DB_LOGVERSION_46: + case DB_LOGVERSION_45: + case DB_LOGVERSION_44: + ret = env_init_print_47(env, dtabp); + break; + case DB_LOGVERSION_43: + ret = env_init_print_43(env, dtabp); + break; + case DB_LOGVERSION_42: + ret = env_init_print_42(env, dtabp); + break; + default: + env->dbenv->errx(env->dbenv, + "Unknown version %lu", (u_long)version); + ret = EINVAL; + break; + } +err: return (ret); +} + +int +env_init_print_42(env, dtabp) + ENV *env; + DB_DISTAB *dtabp; +{ + int ret; + + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_split_42_print, DB___bam_split_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __db_relink_42_print, DB___db_relink_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_alloc_42_print, DB___db_pg_alloc_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_free_42_print, DB___db_pg_free_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_freedata_42_print, DB___db_pg_freedata_42)) != 0) + goto err; +#if HAVE_HASH + if ((ret = __db_add_recovery_int(env, dtabp, + __ham_metagroup_42_print, DB___ham_metagroup_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __ham_groupalloc_42_print, DB___ham_groupalloc_42)) != 0) + goto err; +#endif + if ((ret = __db_add_recovery_int(env, dtabp, + __txn_ckp_42_print, DB___txn_ckp_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __txn_regop_42_print, DB___txn_regop_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __fop_create_42_print, DB___fop_create_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __fop_write_42_print, DB___fop_write_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __fop_rename_42_print, DB___fop_rename_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __fop_rename_42_print, DB___fop_rename_noundo_46)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __txn_xa_regop_42_print, DB___txn_xa_regop_42)) != 0) + goto err; +err: + return (ret); +} + +int +env_init_print_43(env, dtabp) + ENV *env; + DB_DISTAB *dtabp; +{ + int ret; + + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_relink_43_print, DB___bam_relink_43)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_split_42_print, DB___bam_split_42)) != 0) + goto err; + /* + * We want to use the 4.2-based txn_regop record. + */ + if ((ret = __db_add_recovery_int(env, dtabp, + __txn_regop_42_print, DB___txn_regop_42)) != 0) + goto err; + + if ((ret = __db_add_recovery_int(env, dtabp, + __fop_create_42_print, DB___fop_create_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __fop_write_42_print, DB___fop_write_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __fop_rename_42_print, DB___fop_rename_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __fop_rename_42_print, DB___fop_rename_noundo_46)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __txn_xa_regop_42_print, DB___txn_xa_regop_42)) != 0) + goto err; +err: + return (ret); +} + +/* + * env_init_print_47 -- + * + */ +int +env_init_print_47(env, dtabp) + ENV *env; + DB_DISTAB *dtabp; +{ + int ret; + + if ((ret = __db_add_recovery_int(env, dtabp, + __bam_split_42_print, DB___bam_split_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_sort_44_print, DB___db_pg_sort_44)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __db_pg_sort_44_print, DB___db_pg_sort_44)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __fop_create_42_print, DB___fop_create_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __fop_write_42_print, DB___fop_write_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __fop_rename_42_print, DB___fop_rename_42)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __fop_rename_42_print, DB___fop_rename_noundo_46)) != 0) + goto err; + if ((ret = __db_add_recovery_int(env, dtabp, + __txn_xa_regop_42_print, DB___txn_xa_regop_42)) != 0) + goto err; + +err: + return (ret); +} + +int +usage() +{ + fprintf(stderr, "usage: %s %s\n", progname, + "[-NrV] [-b file/offset] [-e file/offset] [-h home] [-P password]"); + return (EXIT_FAILURE); +} + +int +version_check() +{ + int v_major, v_minor, v_patch; + + /* Make sure we're loaded with the right version of the DB library. */ + (void)db_version(&v_major, &v_minor, &v_patch); + if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { + fprintf(stderr, + "%s: version %d.%d doesn't match library version %d.%d\n", + progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, + v_major, v_minor); + return (EXIT_FAILURE); + } + return (0); +} + +/* Print an unknown, application-specific log record as best we can. */ +int +db_printlog_print_app_record(dbenv, dbt, lsnp, op) + DB_ENV *dbenv; + DBT *dbt; + DB_LSN *lsnp; + db_recops op; +{ + u_int32_t i, rectype; + int ch; + + DB_ASSERT(dbenv->env, op == DB_TXN_PRINT); + + COMPQUIET(dbenv, NULL); + COMPQUIET(op, DB_TXN_PRINT); + + /* + * Fetch the rectype, which always must be at the beginning of the + * record (if dispatching is to work at all). + */ + memcpy(&rectype, dbt->data, sizeof(rectype)); + + /* + * Applications may wish to customize the output here based on the + * rectype. We just print the entire log record in the generic + * mixed-hex-and-printable format we use for binary data. + */ + printf("[%lu][%lu]application specific record: rec: %lu\n", + (u_long)lsnp->file, (u_long)lsnp->offset, (u_long)rectype); + printf("\tdata: "); + for (i = 0; i < dbt->size; i++) { + ch = ((u_int8_t *)dbt->data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + printf("\n\n"); + + return (0); +} + +int +open_rep_db(dbenv, dbpp, dbcp) + DB_ENV *dbenv; + DB **dbpp; + DBC **dbcp; +{ + int ret; + + DB *dbp; + *dbpp = NULL; + *dbcp = NULL; + + if ((ret = db_create(dbpp, dbenv, 0)) != 0) { + dbenv->err(dbenv, ret, "db_create"); + return (ret); + } + + dbp = *dbpp; + if ((ret = + dbp->open(dbp, NULL, REPDBNAME, NULL, DB_BTREE, 0, 0)) != 0) { + dbenv->err(dbenv, ret, "DB->open"); + goto err; + } + + if ((ret = dbp->cursor(dbp, NULL, dbcp, 0)) != 0) { + dbenv->err(dbenv, ret, "DB->cursor"); + goto err; + } + + return (0); + +err: if (*dbpp != NULL) + (void)(*dbpp)->close(*dbpp, 0); + return (ret); +} + +/* + * lsn_arg -- + * Parse a LSN argument. + */ +int +lsn_arg(arg, lsnp) + char *arg; + DB_LSN *lsnp; +{ + u_long uval; + char *p; + + /* + * Expected format is: lsn.file/lsn.offset. + */ + if ((p = strchr(arg, '/')) == NULL) + return (1); + *p = '\0'; + + if (__db_getulong(NULL, progname, arg, 0, UINT32_MAX, &uval)) + return (1); + lsnp->file = uval; + if (__db_getulong(NULL, progname, p + 1, 0, UINT32_MAX, &uval)) + return (1); + lsnp->offset = uval; + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db_printlog/dbname.awk b/src/libs/resiprocate/contrib/db/db_printlog/dbname.awk new file mode 100644 index 00000000..9a715868 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_printlog/dbname.awk @@ -0,0 +1,82 @@ +# $Id$ +# +# Take a comma-separated list of database names and spit out all the +# log records that affect those databases. + +NR == 1 { + nfiles = 0 + while ((ndx = index(DBNAME, ",")) != 0) { + filenames[nfiles] = substr(DBNAME, 1, ndx - 1) 0; + DBNAME = substr(DBNAME, ndx + 1, length(DBNAME) - ndx); + files[nfiles] = -1 + nfiles++ + } + filenames[nfiles] = DBNAME 0; + files[nfiles] = -1 + myfile = -1; + nreg = 0; +} + +/^\[.*dbreg_register/ { + register = 1; +} +/opcode:/ { + if (register == 1) { + if ($2 == 1) + register = 3; + else + register = $2; + } +} +/name:/ { + if (register >= 2) { + myfile = -2; + for (i = 0; i <= nfiles; i++) { + if ($2 == filenames[i]) { + if (register == 2) { + printme = 0; + myfile = -2; + } else { + myfile = i; + } + break; + } + } + } + register = 0; +} +/fileid:/{ + if (myfile == -2) + files[$2] = 0; + else if (myfile != -1) { + files[$2] = 1; + if ($2 > nreg) + nreg = $2; + printme = 1; + register = 0; + myfile = -1; + } else if ($2 <= nreg && files[$2] == 1) { + printme = 1 + } + myfile = -1; +} + +/^\[/{ + if (printme == 1) { + printf("%s\n", rec); + printme = 0 + } + rec = ""; + + rec = $0 +} + +TXN == 1 && /txn_regop/ {printme = 1} +/^ /{ + rec = sprintf("%s\n%s", rec, $0); +} + +END { + if (printme == 1) + printf("%s\n", rec); +} diff --git a/src/libs/resiprocate/contrib/db/db_printlog/fileid.awk b/src/libs/resiprocate/contrib/db/db_printlog/fileid.awk new file mode 100644 index 00000000..fdad2749 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_printlog/fileid.awk @@ -0,0 +1,37 @@ +# $Id$ +# +# Take a comma-separated list of file numbers and spit out all the +# log records that affect those file numbers. + +NR == 1 { + nfiles = 0 + while ((ndx = index(FILEID, ",")) != 0) { + files[nfiles] = substr(FILEID, 1, ndx - 1); + FILEID = substr(FILEID, ndx + 1, length(FILEID) - ndx); + nfiles++ + } + files[nfiles] = FILEID; +} + +/^\[/{ + if (printme == 1) { + printf("%s\n", rec); + printme = 0 + } + rec = ""; + + rec = $0 +} +/^ /{ + rec = sprintf("%s\n%s", rec, $0); +} +/fileid/{ + for (i = 0; i <= nfiles; i++) + if ($2 == files[i]) + printme = 1 +} + +END { + if (printme == 1) + printf("%s\n", rec); +} diff --git a/src/libs/resiprocate/contrib/db/db_printlog/logstat.awk b/src/libs/resiprocate/contrib/db/db_printlog/logstat.awk new file mode 100644 index 00000000..b22a3f15 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_printlog/logstat.awk @@ -0,0 +1,36 @@ +# $Id$ +# +# Output accumulated log record count/size statistics. +BEGIN { + l_file = 0; + l_offset = 0; +} + +/^\[/{ + gsub("[][: ]", " ", $1) + split($1, a) + + if (a[1] == l_file) { + l[a[3]] += a[2] - l_offset + ++n[a[3]] + } else + ++s[a[3]] + + l_file = a[1] + l_offset = a[2] +} + +END { + # We can't figure out the size of the first record in each log file, + # use the average for other records we found as an estimate. + for (i in s) + if (s[i] != 0 && n[i] != 0) { + l[i] += s[i] * (l[i]/n[i]) + n[i] += s[i] + delete s[i] + } + for (i in l) + printf "%s: %d (n: %d, avg: %.2f)\n", i, l[i], n[i], l[i]/n[i] + for (i in s) + printf "%s: unknown (n: %d, unknown)\n", i, s[i] +} diff --git a/src/libs/resiprocate/contrib/db/db_printlog/pgno.awk b/src/libs/resiprocate/contrib/db/db_printlog/pgno.awk new file mode 100644 index 00000000..f5bbdfbd --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_printlog/pgno.awk @@ -0,0 +1,47 @@ +# $Id$ +# +# Take a comma-separated list of page numbers and spit out all the +# log records that affect those page numbers. + +NR == 1 { + npages = 0 + while ((ndx = index(PGNO, ",")) != 0) { + pgno[npages] = substr(PGNO, 1, ndx - 1); + PGNO = substr(PGNO, ndx + 1, length(PGNO) - ndx); + npages++ + } + pgno[npages] = PGNO; +} + +/^\[/{ + if (printme == 1) { + printf("%s\n", rec); + printme = 0 + } + rec = ""; + + rec = $0 +} +/^ /{ + rec = sprintf("%s\n%s", rec, $0); +} +/pgno/{ + for (i = 0; i <= npages; i++) + if ($2 == pgno[i]) + printme = 1 +} +/right/{ + for (i = 0; i <= npages; i++) + if ($2 == pgno[i]) + printme = 1 +} +/left/{ + for (i = 0; i <= npages; i++) + if ($2 == pgno[i]) + printme = 1 +} + +END { + if (printme == 1) + printf("%s\n", rec); +} diff --git a/src/libs/resiprocate/contrib/db/db_printlog/range.awk b/src/libs/resiprocate/contrib/db/db_printlog/range.awk new file mode 100644 index 00000000..e2c01129 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_printlog/range.awk @@ -0,0 +1,27 @@ +# $Id$ +# +# Print out a range of the log + +/^\[/{ + l = length($1) - 1; + i = index($1, "]"); + file = substr($1, 2, i - 2); + file += 0; + start = i + 2; + offset = substr($1, start, l - start + 1); + i = index(offset, "]"); + offset = substr($1, start, i - 1); + offset += 0; + + if ((file == START_FILE && offset >= START_OFFSET || file > START_FILE)\ + && (file < END_FILE || (file == END_FILE && offset < END_OFFSET))) + printme = 1 + else if (file == END_FILE && offset > END_OFFSET || file > END_FILE) + exit + else + printme = 0 +} +{ + if (printme == 1) + print $0 +} diff --git a/src/libs/resiprocate/contrib/db/db_printlog/rectype.awk b/src/libs/resiprocate/contrib/db/db_printlog/rectype.awk new file mode 100644 index 00000000..b5da8fde --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_printlog/rectype.awk @@ -0,0 +1,27 @@ +# $Id$ +# +# Print out a range of the log. +# Command line should set RECTYPE to a comma separated list +# of the rectypes (or partial strings of rectypes) sought. +NR == 1 { + ntypes = 0 + while ((ndx = index(RECTYPE, ",")) != 0) { + types[ntypes] = substr(RECTYPE, 1, ndx - 1); + RECTYPE = substr(RECTYPE, ndx + 1, length(RECTYPE) - ndx); + ntypes++ + } + types[ntypes] = RECTYPE; +} + +/^\[/{ + printme = 0 + for (i = 0; i <= ntypes; i++) + if (index($1, types[i]) != 0) { + printme = 1 + break; + } +} +{ + if (printme == 1) + print $0 +} diff --git a/src/libs/resiprocate/contrib/db/db_printlog/status.awk b/src/libs/resiprocate/contrib/db/db_printlog/status.awk new file mode 100644 index 00000000..7145d979 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_printlog/status.awk @@ -0,0 +1,50 @@ +# $Id$ +# +# Read through db_printlog output and list all the transactions encountered +# and whether they committed or aborted. +# +# 1 = started +# 2 = committed +# 3 = explicitly aborted +# 4 = other +BEGIN { + cur_txn = 0 +} +/^\[.*]\[/{ + in_regop = 0 + if (status[$5] == 0) { + status[$5] = 1; + txns[cur_txn] = $5; + cur_txn++; + } +} +/ child:/ { + txnid = substr($2, 3); + status[txnid] = 2; +} +/txn_regop/ { + txnid = $5 + in_regop = 1 +} +/opcode:/ { + if (in_regop == 1) { + if ($2 == 1) + status[txnid] = 2 + else if ($2 == 3) + status[txnid] = 3 + else + status[txnid] = 4 + } +} +END { + for (i = 0; i < cur_txn; i++) { + if (status[txns[i]] == 1) + printf("%s\tABORT\n", txns[i]); + else if (status[txns[i]] == 2) + printf("%s\tCOMMIT\n", txns[i]); + else if (status[txns[i]] == 3) + printf("%s\tABORT\n", txns[i]); + else if (status[txns[i]] == 4) + printf("%s\tOTHER\n", txns[i]); + } +} diff --git a/src/libs/resiprocate/contrib/db/db_printlog/txn.awk b/src/libs/resiprocate/contrib/db/db_printlog/txn.awk new file mode 100644 index 00000000..914db18e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_printlog/txn.awk @@ -0,0 +1,34 @@ +# $Id$ +# +# Print out all the records for a comma-separated list of transaction ids. +NR == 1 { + ntxns = 0 + while ((ndx = index(TXN, ",")) != 0) { + txn[ntxns] = substr(TXN, 1, ndx - 1); + TXN = substr(TXN, ndx + 1, length(TXN) - ndx); + ntxns++ + } + txn[ntxns] = TXN; +} + +/^\[/{ + if (printme == 1) { + printf("%s\n", rec); + printme = 0 + } + rec = ""; + + for (i = 0; i <= ntxns; i++) + if (txn[i] == $5) { + rec = $0 + printme = 1 + } +} +/^ /{ + rec = sprintf("%s\n%s", rec, $0); +} + +END { + if (printme == 1) + printf("%s\n", rec); +} diff --git a/src/libs/resiprocate/contrib/db/db_recover/db_recover.c b/src/libs/resiprocate/contrib/db/db_recover/db_recover.c new file mode 100644 index 00000000..a00fe1f4 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_recover/db_recover.c @@ -0,0 +1,313 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#ifndef lint +static const char copyright[] = + "Copyright (c) 1996-2009 Oracle. All rights reserved.\n"; +#endif + +void db_recover_feedback __P((DB_ENV *, int, int)); +int main __P((int, char *[])); +int read_timestamp __P((char *, time_t *)); +int usage __P((void)); +int version_check __P((void)); + +const char *progname; +int newline_needed; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB_ENV *dbenv; + time_t timestamp; + u_int32_t flags; + int ch, exitval, fatal_recover, ret, retain_env, set_feedback, verbose; + char *home, *passwd; + + if ((progname = __db_rpath(argv[0])) == NULL) + progname = argv[0]; + else + ++progname; + + if ((ret = version_check()) != 0) + return (ret); + + home = passwd = NULL; + timestamp = 0; + exitval = fatal_recover = retain_env = set_feedback = verbose = 0; + while ((ch = getopt(argc, argv, "cefh:P:t:Vv")) != EOF) + switch (ch) { + case 'c': + fatal_recover = 1; + break; + case 'e': + retain_env = 1; + break; + case 'f': + set_feedback = 1; + break; + case 'h': + home = optarg; + break; + case 'P': + passwd = strdup(optarg); + memset(optarg, 0, strlen(optarg)); + if (passwd == NULL) { + fprintf(stderr, "%s: strdup: %s\n", + progname, strerror(errno)); + return (EXIT_FAILURE); + } + break; + case 't': + if ((ret = read_timestamp(optarg, ×tamp)) != 0) + return (ret); + break; + case 'V': + printf("%s\n", db_version(NULL, NULL, NULL)); + return (EXIT_SUCCESS); + case 'v': + verbose = 1; + break; + case '?': + default: + return (usage()); + } + argc -= optind; + argv += optind; + + if (argc != 0) + return (usage()); + + /* Handle possible interruptions. */ + __db_util_siginit(); + + /* + * Create an environment object and initialize it for error + * reporting. + */ + if ((ret = db_env_create(&dbenv, 0)) != 0) { + fprintf(stderr, + "%s: db_env_create: %s\n", progname, db_strerror(ret)); + return (EXIT_FAILURE); + } + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, progname); + if (set_feedback) + (void)dbenv->set_feedback(dbenv, db_recover_feedback); + if (verbose) + (void)dbenv->set_verbose(dbenv, DB_VERB_RECOVERY, 1); + if (timestamp && + (ret = dbenv->set_tx_timestamp(dbenv, ×tamp)) != 0) { + dbenv->err(dbenv, ret, "DB_ENV->set_timestamp"); + goto shutdown; + } + + if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, + passwd, DB_ENCRYPT_AES)) != 0) { + dbenv->err(dbenv, ret, "set_passwd"); + goto shutdown; + } + + /* + * Initialize the environment -- we don't actually do anything + * else, that all that's needed to run recovery. + * + * Note that unless the caller specified the -e option, we use a + * private environment, as we're about to create a region, and we + * don't want to to leave it around. If we leave the region around, + * the application that should create it will simply join it instead, + * and will then be running with incorrectly sized (and probably + * terribly small) caches. Applications that use -e should almost + * certainly use DB_CONFIG files in the directory. + */ + flags = 0; + LF_SET(DB_CREATE | DB_INIT_LOG | + DB_INIT_MPOOL | DB_INIT_TXN | DB_USE_ENVIRON); + LF_SET(fatal_recover ? DB_RECOVER_FATAL : DB_RECOVER); + LF_SET(retain_env ? DB_INIT_LOCK : DB_PRIVATE); + if ((ret = dbenv->open(dbenv, home, flags, 0)) != 0) { + dbenv->err(dbenv, ret, "DB_ENV->open"); + goto shutdown; + } + + if (0) { +shutdown: exitval = 1; + } + + /* Flush to the next line of the output device. */ + if (newline_needed) + printf("\n"); + + /* Clean up the environment. */ + if ((ret = dbenv->close(dbenv, 0)) != 0) { + exitval = 1; + fprintf(stderr, + "%s: dbenv->close: %s\n", progname, db_strerror(ret)); + } + if (passwd != NULL) + free(passwd); + + /* Resend any caught signal. */ + __db_util_sigresend(); + + return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} + +/* + * db_recover_feedback -- + * Provide feedback on recovery progress. + */ +void +db_recover_feedback(dbenv, opcode, percent) + DB_ENV *dbenv; + int opcode; + int percent; +{ + COMPQUIET(dbenv, NULL); + + if (opcode == DB_RECOVER) { + printf("\rrecovery %d%% complete", percent); + (void)fflush(stdout); + newline_needed = 1; + } +} + +#define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2; + +/* + * read_timestamp -- + * Convert a time argument to Epoch seconds. + * + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +int +read_timestamp(arg, timep) + char *arg; + time_t *timep; +{ + struct tm *t; + time_t now; + int yearset; + char *p; + /* Start with the current time. */ + (void)time(&now); + if ((t = localtime(&now)) == NULL) { + fprintf(stderr, + "%s: localtime: %s\n", progname, strerror(errno)); + return (EXIT_FAILURE); + } + /* [[CC]YY]MMDDhhmm[.SS] */ + if ((p = strchr(arg, '.')) == NULL) + t->tm_sec = 0; /* Seconds defaults to 0. */ + else { + if (strlen(p + 1) != 2) + goto terr; + *p++ = '\0'; + t->tm_sec = ATOI2(p); + } + + yearset = 0; + switch (strlen(arg)) { + case 12: /* CCYYMMDDhhmm */ + t->tm_year = ATOI2(arg); + t->tm_year *= 100; + yearset = 1; + /* FALLTHROUGH */ + case 10: /* YYMMDDhhmm */ + if (yearset) { + yearset = ATOI2(arg); + t->tm_year += yearset; + } else { + yearset = ATOI2(arg); + if (yearset < 69) + t->tm_year = yearset + 2000; + else + t->tm_year = yearset + 1900; + } + t->tm_year -= 1900; /* Convert to UNIX time. */ + /* FALLTHROUGH */ + case 8: /* MMDDhhmm */ + t->tm_mon = ATOI2(arg); + --t->tm_mon; /* Convert from 01-12 to 00-11 */ + t->tm_mday = ATOI2(arg); + t->tm_hour = ATOI2(arg); + t->tm_min = ATOI2(arg); + break; + default: + goto terr; + } + + t->tm_isdst = -1; /* Figure out DST. */ + + *timep = mktime(t); + if (*timep == -1) { +terr: fprintf(stderr, + "%s: out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]", + progname); + return (EXIT_FAILURE); + } + return (0); +} + +int +usage() +{ + (void)fprintf(stderr, "usage: %s %s\n", progname, + "[-cefVv] [-h home] [-P password] [-t [[CC]YY]MMDDhhmm[.SS]]"); + return (EXIT_FAILURE); +} + +int +version_check() +{ + int v_major, v_minor, v_patch; + + /* Make sure we're loaded with the right version of the DB library. */ + (void)db_version(&v_major, &v_minor, &v_patch); + if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { + fprintf(stderr, + "%s: version %d.%d doesn't match library version %d.%d\n", + progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, + v_major, v_minor); + return (EXIT_FAILURE); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db_stat/db_stat.c b/src/libs/resiprocate/contrib/db/db_stat/db_stat.c new file mode 100644 index 00000000..9bd1125f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_stat/db_stat.c @@ -0,0 +1,468 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2001, 2010 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#ifndef lint +static const char copyright[] = + "Copyright (c) 1996, 2010 Oracle and/or its affiliates. All rights reserved.\n"; +#endif + +typedef enum { T_NOTSET, T_DB, + T_ENV, T_LOCK, T_LOG, T_MPOOL, T_MUTEX, T_REP, T_TXN } test_t; + +int db_init __P((DB_ENV *, char *, test_t, u_int32_t, int *)); +int main __P((int, char *[])); +int usage __P((void)); +int version_check __P((void)); + +const char *progname; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB_ENV *dbenv; + DB *dbp; + test_t ttype; + u_int32_t cache, flags; + int ch, exitval; + int nflag, private, resize, ret; + char *db, *home, *p, *passwd, *subdb; + + if ((progname = __db_rpath(argv[0])) == NULL) + progname = argv[0]; + else + ++progname; + + if ((ret = version_check()) != 0) + return (ret); + + dbenv = NULL; + dbp = NULL; + ttype = T_NOTSET; + cache = MEGABYTE; + exitval = flags = nflag = private = 0; + db = home = passwd = subdb = NULL; + + while ((ch = getopt(argc, + argv, "C:cd:Eefgh:L:lM:mNP:R:rs:tVxX:Z")) != EOF) + switch (ch) { + case 'C': case 'c': + if (ttype != T_NOTSET && ttype != T_LOCK) + goto argcombo; + ttype = T_LOCK; + if (ch != 'c') + for (p = optarg; *p; ++p) + switch (*p) { + case 'A': + LF_SET(DB_STAT_ALL); + break; + case 'c': + LF_SET(DB_STAT_LOCK_CONF); + break; + case 'l': + LF_SET(DB_STAT_LOCK_LOCKERS); + break; + case 'm': /* Backward compatible. */ + break; + case 'o': + LF_SET(DB_STAT_LOCK_OBJECTS); + break; + case 'p': + LF_SET(DB_STAT_LOCK_PARAMS); + break; + default: + return (usage()); + } + break; + case 'd': + if (ttype != T_NOTSET && ttype != T_DB) + goto argcombo; + ttype = T_DB; + db = optarg; + break; + case 'E': case 'e': + if (ttype != T_NOTSET && ttype != T_ENV) + goto argcombo; + ttype = T_ENV; + LF_SET(DB_STAT_SUBSYSTEM); + if (ch == 'E') + LF_SET(DB_STAT_ALL); + break; + case 'f': + if (ttype != T_NOTSET && ttype != T_DB) + goto argcombo; + ttype = T_DB; + LF_SET(DB_FAST_STAT); + break; + case 'h': + home = optarg; + break; + case 'L': case 'l': + if (ttype != T_NOTSET && ttype != T_LOG) + goto argcombo; + ttype = T_LOG; + if (ch != 'l') + for (p = optarg; *p; ++p) + switch (*p) { + case 'A': + LF_SET(DB_STAT_ALL); + break; + default: + return (usage()); + } + break; + case 'M': case 'm': + if (ttype != T_NOTSET && ttype != T_MPOOL) + goto argcombo; + ttype = T_MPOOL; + if (ch != 'm') + for (p = optarg; *p; ++p) + switch (*p) { + case 'A': + LF_SET(DB_STAT_ALL); + break; + case 'h': + LF_SET(DB_STAT_MEMP_HASH); + break; + case 'm': /* Backward compatible. */ + break; + default: + return (usage()); + } + break; + case 'N': + nflag = 1; + break; + case 'P': + passwd = strdup(optarg); + memset(optarg, 0, strlen(optarg)); + if (passwd == NULL) { + fprintf(stderr, "%s: strdup: %s\n", + progname, strerror(errno)); + return (EXIT_FAILURE); + } + break; + case 'R': case 'r': + if (ttype != T_NOTSET && ttype != T_REP) + goto argcombo; + ttype = T_REP; + if (ch != 'r') + for (p = optarg; *p; ++p) + switch (*p) { + case 'A': + LF_SET(DB_STAT_ALL); + break; + default: + return (usage()); + } + break; + case 's': + if (ttype != T_NOTSET && ttype != T_DB) + goto argcombo; + ttype = T_DB; + subdb = optarg; + break; + case 't': + if (ttype != T_NOTSET) { +argcombo: fprintf(stderr, + "%s: illegal option combination\n", + progname); + return (usage()); + } + ttype = T_TXN; + break; + case 'V': + printf("%s\n", db_version(NULL, NULL, NULL)); + return (EXIT_SUCCESS); + case 'X': case 'x': + if (ttype != T_NOTSET && ttype != T_MUTEX) + goto argcombo; + ttype = T_MUTEX; + if (ch != 'x') + for (p = optarg; *p; ++p) + switch (*p) { + case 'A': + LF_SET(DB_STAT_ALL); + break; + default: + return (usage()); + } + break; + case 'Z': + LF_SET(DB_STAT_CLEAR); + break; + case '?': + default: + return (usage()); + } + argc -= optind; + argv += optind; + + switch (ttype) { + case T_DB: + if (db == NULL) + return (usage()); + break; + case T_ENV: + case T_LOCK: + case T_LOG: + case T_MPOOL: + case T_MUTEX: + case T_REP: + case T_TXN: + break; + case T_NOTSET: + return (usage()); + } + + /* Handle possible interruptions. */ + __db_util_siginit(); + + /* + * Create an environment object and initialize it for error + * reporting. + */ +retry: if ((ret = db_env_create(&dbenv, 0)) != 0) { + fprintf(stderr, + "%s: db_env_create: %s\n", progname, db_strerror(ret)); + goto err; + } + + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, progname); + + if (nflag) { + if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) { + dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING"); + goto err; + } + if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) { + dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC"); + goto err; + } + } + + if (passwd != NULL && + (ret = dbenv->set_encrypt(dbenv, passwd, DB_ENCRYPT_AES)) != 0) { + dbenv->err(dbenv, ret, "set_passwd"); + goto err; + } + + /* Initialize the environment. */ + if (db_init(dbenv, home, ttype, cache, &private) != 0) + goto err; + + switch (ttype) { + case T_DB: + /* Create the DB object and open the file. */ + if ((ret = db_create(&dbp, dbenv, 0)) != 0) { + dbenv->err(dbenv, ret, "db_create"); + goto err; + } + + /* + * We open the database for writing so we can update the cached + * statistics, but it's OK to fail, we can open read-only and + * proceed. + * + * Turn off error messages for now -- we can't open lots of + * databases read-write (for example, master databases and + * hash databases for which we don't know the hash function). + */ + dbenv->set_errfile(dbenv, NULL); + ret = dbp->open(dbp, NULL, db, subdb, DB_UNKNOWN, 0, 0); + dbenv->set_errfile(dbenv, stderr); + if (ret != 0) { + /* Handles cannot be reused after a failed DB->open. */ + (void)dbp->close(dbp, 0); + if ((ret = db_create(&dbp, dbenv, 0)) != 0) { + dbenv->err(dbenv, ret, "db_create"); + goto err; + } + + if ((ret = dbp->open(dbp, + NULL, db, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) { + dbenv->err(dbenv, ret, "DB->open: %s", db); + goto err; + } + } + + /* Check if cache is too small for this DB's pagesize. */ + if (private) { + if ((ret = __db_util_cache(dbp, &cache, &resize)) != 0) + goto err; + if (resize) { + (void)dbp->close(dbp, DB_NOSYNC); + dbp = NULL; + + (void)dbenv->close(dbenv, 0); + dbenv = NULL; + goto retry; + } + } + + if (dbp->stat_print(dbp, flags)) + goto err; + break; + case T_ENV: + if (dbenv->stat_print(dbenv, flags)) + goto err; + break; + case T_LOCK: + if (dbenv->lock_stat_print(dbenv, flags)) + goto err; + break; + case T_LOG: + if (dbenv->log_stat_print(dbenv, flags)) + goto err; + break; + case T_MPOOL: + if (dbenv->memp_stat_print(dbenv, flags)) + goto err; + break; + case T_MUTEX: + if (dbenv->mutex_stat_print(dbenv, flags)) + goto err; + break; + case T_REP: +#ifdef HAVE_REPLICATION_THREADS + if (dbenv->repmgr_stat_print(dbenv, flags)) + goto err; +#endif + if (dbenv->rep_stat_print(dbenv, flags)) + goto err; + break; + case T_TXN: + if (dbenv->txn_stat_print(dbenv, flags)) + goto err; + break; + case T_NOTSET: + dbenv->errx(dbenv, "Unknown statistics flag"); + goto err; + } + + if (0) { +err: exitval = 1; + } + if (dbp != NULL && (ret = dbp->close(dbp, DB_NOSYNC)) != 0) { + exitval = 1; + dbenv->err(dbenv, ret, "close"); + } + if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { + exitval = 1; + fprintf(stderr, + "%s: dbenv->close: %s\n", progname, db_strerror(ret)); + } + + if (passwd != NULL) + free(passwd); + + /* Resend any caught signal. */ + __db_util_sigresend(); + + return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} + +/* + * db_init -- + * Initialize the environment. + */ +int +db_init(dbenv, home, ttype, cache, is_private) + DB_ENV *dbenv; + char *home; + test_t ttype; + u_int32_t cache; + int *is_private; +{ + u_int32_t oflags; + int ret; + + /* + * If our environment open fails, and we're trying to look at a + * shared region, it's a hard failure. + * + * We will probably just drop core if the environment we join does + * not include a memory pool. This is probably acceptable; trying + * to use an existing environment that does not contain a memory + * pool to look at a database can be safely construed as operator + * error, I think. + */ + *is_private = 0; + if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) == 0) + return (0); + if (ret == DB_VERSION_MISMATCH) + goto err; + if (ttype != T_DB && ttype != T_LOG) { + dbenv->err(dbenv, ret, "DB_ENV->open%s%s", + home == NULL ? "" : ": ", home == NULL ? "" : home); + return (1); + } + + /* + * We're looking at a database or set of log files and no environment + * exists. Create one, but make it private so no files are actually + * created. Declare a reasonably large cache so that we don't fail + * when reporting statistics on large databases. + * + * An environment is required to look at databases because we may be + * trying to look at databases in directories other than the current + * one. + */ + if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) { + dbenv->err(dbenv, ret, "set_cachesize"); + return (1); + } + *is_private = 1; + oflags = DB_CREATE | DB_PRIVATE | DB_USE_ENVIRON; + if (ttype == T_DB) + oflags |= DB_INIT_MPOOL; + if (ttype == T_LOG) + oflags |= DB_INIT_LOG; + if ((ret = dbenv->open(dbenv, home, oflags, 0)) == 0) + return (0); + + /* An environment is required. */ +err: dbenv->err(dbenv, ret, "DB_ENV->open"); + return (1); +} + +int +usage() +{ + fprintf(stderr, "usage: %s %s\n", progname, + "-d file [-fN] [-h home] [-P password] [-s database]"); + fprintf(stderr, "usage: %s %s\n\t%s\n", progname, + "[-cEelmNrtVxZ] [-C Aclop]", + "[-h home] [-L A] [-M A] [-P password] [-R A] [-X A]"); + return (EXIT_FAILURE); +} + +int +version_check() +{ + int v_major, v_minor, v_patch; + + /* Make sure we're loaded with the right version of the DB library. */ + (void)db_version(&v_major, &v_minor, &v_patch); + if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { + fprintf(stderr, + "%s: version %d.%d doesn't match library version %d.%d\n", + progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, + v_major, v_minor); + return (EXIT_FAILURE); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db_stat/dd.sh b/src/libs/resiprocate/contrib/db/db_stat/dd.sh new file mode 100644 index 00000000..3af9bcde --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_stat/dd.sh @@ -0,0 +1,81 @@ +#! /bin/sh +# $Id$ +# +# Display environment's deadlocks based on "db_stat -Co" output. + +t1=__a +t2=__b + +trap 'rm -f $t1 $t2; exit 0' 0 1 2 3 13 15 + +if [ $# -ne 1 ]; then + echo "Usage: dd.sh [db_stat -Co output]" + exit 1 +fi + +if `egrep '\.*\' $1 > /dev/null`; then + n=`egrep '\.*\' $1 | wc -l | awk '{print $1}'` + echo "dd.sh: $1: $n page locks in a WAIT state." +else + echo "dd.sh: $1: No page locks in a WAIT state found." + exit 1 +fi + +# Print out list of node wait states, and output cycles in the graph. +egrep '\.*\' $1 | awk '{print $1 " " $5 " " $7}' | +while read l f p; do + for i in `egrep "\.*\<$f\>.*\.*\<$p\>" $1 | + awk '{print $1}'`; do + echo "$l $i" + done +done | tsort > /dev/null 2>$t1 + +# Display the locks in a single cycle. +c=1 +display_one() { + if [ -s $1 ]; then + echo "Deadlock #$c ============" + c=`expr $c + 1` + cat $1 | sort -n +6 + :> $1 + fi +} + +# Display the locks in all of the cycles. +# +# Requires tsort output some text before each list of nodes in the cycle, +# and the actual node displayed on the line be the second (white-space) +# separated item on the line. For example: +# +# tsort: cycle in data +# tsort: 8000177f +# tsort: 80001792 +# tsort: 80001774 +# tsort: cycle in data +# tsort: 80001776 +# tsort: 80001793 +# tsort: cycle in data +# tsort: 8000176a +# tsort: 8000178a +# +# XXX +# Currently, db_stat doesn't display the implicit wait relationship between +# parent and child transactions, where the parent won't release a lock until +# the child commits/aborts. This means the deadlock where parent holds a +# lock, thread A waits on parent, child waits on thread A won't be shown. +if [ -s $t1 ]; then + :>$t2 + while read a b; do + case $b in + [0-9]*) + egrep $b $1 >> $t2;; + *) + display_one $t2;; + esac + done < $t1 + display_one $t2 +else + echo 'No deadlocks found.' +fi + +exit 0 diff --git a/src/libs/resiprocate/contrib/db/db_upgrade/db_upgrade.c b/src/libs/resiprocate/contrib/db/db_upgrade/db_upgrade.c new file mode 100644 index 00000000..aba767d5 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_upgrade/db_upgrade.c @@ -0,0 +1,197 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#ifndef lint +static const char copyright[] = + "Copyright (c) 1996-2009 Oracle. All rights reserved.\n"; +#endif + +int main __P((int, char *[])); +int usage __P((void)); +int version_check __P((void)); + +const char *progname; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB *dbp; + DB_ENV *dbenv; + u_int32_t flags; + int ch, exitval, nflag, ret, t_ret, verbose; + char *home, *passwd; + + if ((progname = __db_rpath(argv[0])) == NULL) + progname = argv[0]; + else + ++progname; + + if ((ret = version_check()) != 0) + return (ret); + + dbenv = NULL; + flags = nflag = verbose = 0; + exitval = 0; + home = passwd = NULL; + while ((ch = getopt(argc, argv, "h:NP:sVv")) != EOF) + switch (ch) { + case 'h': + home = optarg; + break; + case 'N': + nflag = 1; + break; + case 'P': + passwd = strdup(optarg); + memset(optarg, 0, strlen(optarg)); + if (passwd == NULL) { + fprintf(stderr, "%s: strdup: %s\n", + progname, strerror(errno)); + return (EXIT_FAILURE); + } + break; + case 's': + LF_SET(DB_DUPSORT); + break; + case 'V': + printf("%s\n", db_version(NULL, NULL, NULL)); + return (EXIT_SUCCESS); + case 'v': + verbose = 1; + break; + case '?': + default: + return (usage()); + } + argc -= optind; + argv += optind; + + if (argc <= 0) + return (usage()); + + /* Handle possible interruptions. */ + __db_util_siginit(); + + /* + * Create an environment object and initialize it for error + * reporting. + */ + if ((ret = db_env_create(&dbenv, 0)) != 0) { + fprintf(stderr, "%s: db_env_create: %s\n", + progname, db_strerror(ret)); + goto shutdown; + } + + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, progname); + + if (nflag) { + if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) { + dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING"); + goto shutdown; + } + if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) { + dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC"); + goto shutdown; + } + } + + if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, + passwd, DB_ENCRYPT_AES)) != 0) { + dbenv->err(dbenv, ret, "set_passwd"); + goto shutdown; + } + + /* + * If attaching to a pre-existing environment fails, create a + * private one and try again. + */ + if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0 && + (ret == DB_VERSION_MISMATCH || + (ret = dbenv->open(dbenv, home, + DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, + 0)) != 0)) { + dbenv->err(dbenv, ret, "DB_ENV->open"); + goto shutdown; + } + + for (; !__db_util_interrupted() && argv[0] != NULL; ++argv) { + if ((ret = db_create(&dbp, dbenv, 0)) != 0) { + fprintf(stderr, + "%s: db_create: %s\n", progname, db_strerror(ret)); + goto shutdown; + } + dbp->set_errfile(dbp, stderr); + dbp->set_errpfx(dbp, progname); + if ((ret = dbp->upgrade(dbp, argv[0], flags)) != 0) + dbp->err(dbp, ret, "DB->upgrade: %s", argv[0]); + if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0) { + dbenv->err(dbenv, ret, "DB->close: %s", argv[0]); + ret = t_ret; + } + if (ret != 0) + goto shutdown; + /* + * People get concerned if they don't see a success message. + * If verbose is set, give them one. + */ + if (verbose) + printf("%s: %s upgraded successfully\n", + progname, argv[0]); + } + + if (0) { +shutdown: exitval = 1; + } + if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { + exitval = 1; + fprintf(stderr, + "%s: dbenv->close: %s\n", progname, db_strerror(ret)); + } + + if (passwd != NULL) + free(passwd); + + /* Resend any caught signal. */ + __db_util_sigresend(); + + return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} + +int +usage() +{ + fprintf(stderr, "usage: %s %s\n", progname, + "[-NsVv] [-h home] [-P password] db_file ..."); + return (EXIT_FAILURE); +} + +int +version_check() +{ + int v_major, v_minor, v_patch; + + /* Make sure we're loaded with the right version of the DB library. */ + (void)db_version(&v_major, &v_minor, &v_patch); + if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { + fprintf(stderr, + "%s: version %d.%d doesn't match library version %d.%d\n", + progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, + v_major, v_minor); + return (EXIT_FAILURE); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/db_verify/db_verify.c b/src/libs/resiprocate/contrib/db/db_verify/db_verify.c new file mode 100644 index 00000000..04be11c0 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/db_verify/db_verify.c @@ -0,0 +1,268 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +#ifndef lint +static const char copyright[] = + "Copyright (c) 1996-2009 Oracle. All rights reserved.\n"; +#endif + +int main __P((int, char *[])); +int usage __P((void)); +int version_check __P((void)); + +const char *progname; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + DB *dbp, *dbp1; + DB_ENV *dbenv; + u_int32_t flags, cache; + int ch, exitval, nflag, private; + int quiet, resize, ret; + char *home, *passwd; + + if ((progname = __db_rpath(argv[0])) == NULL) + progname = argv[0]; + else + ++progname; + + if ((ret = version_check()) != 0) + return (ret); + + dbenv = NULL; + dbp = NULL; + cache = MEGABYTE; + exitval = nflag = quiet = 0; + flags = 0; + home = passwd = NULL; + while ((ch = getopt(argc, argv, "h:NoP:quV")) != EOF) + switch (ch) { + case 'h': + home = optarg; + break; + case 'N': + nflag = 1; + break; + case 'P': + passwd = strdup(optarg); + memset(optarg, 0, strlen(optarg)); + if (passwd == NULL) { + fprintf(stderr, "%s: strdup: %s\n", + progname, strerror(errno)); + return (EXIT_FAILURE); + } + break; + case 'o': + LF_SET(DB_NOORDERCHK); + break; + case 'q': + quiet = 1; + break; + case 'u': /* Undocumented. */ + LF_SET(DB_UNREF); + break; + case 'V': + printf("%s\n", db_version(NULL, NULL, NULL)); + return (EXIT_SUCCESS); + case '?': + default: + return (usage()); + } + argc -= optind; + argv += optind; + + if (argc <= 0) + return (usage()); + + /* Handle possible interruptions. */ + __db_util_siginit(); + + /* + * Create an environment object and initialize it for error + * reporting. + */ +retry: if ((ret = db_env_create(&dbenv, 0)) != 0) { + fprintf(stderr, + "%s: db_env_create: %s\n", progname, db_strerror(ret)); + goto shutdown; + } + + if (!quiet) { + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, progname); + } + + if (nflag) { + if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) { + dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING"); + goto shutdown; + } + if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) { + dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC"); + goto shutdown; + } + } + + if (passwd != NULL && + (ret = dbenv->set_encrypt(dbenv, passwd, DB_ENCRYPT_AES)) != 0) { + dbenv->err(dbenv, ret, "set_passwd"); + goto shutdown; + } + /* + * Attach to an mpool if it exists, but if that fails, attach to a + * private region. In the latter case, declare a reasonably large + * cache so that we don't fail when verifying large databases. + */ + private = 0; + if ((ret = + dbenv->open(dbenv, home, DB_INIT_MPOOL | DB_USE_ENVIRON, 0)) != 0) { + if (ret != DB_VERSION_MISMATCH) { + if ((ret = + dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) { + dbenv->err(dbenv, ret, "set_cachesize"); + goto shutdown; + } + private = 1; + ret = dbenv->open(dbenv, home, DB_CREATE | + DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0); + } + if (ret != 0) { + dbenv->err(dbenv, ret, "DB_ENV->open"); + goto shutdown; + } + } + + /* + * Find out if we have a transactional environment so that we can + * make sure that we don't open the verify database with logging + * enabled. + */ + for (; !__db_util_interrupted() && argv[0] != NULL; ++argv) { + if ((ret = db_create(&dbp, dbenv, 0)) != 0) { + dbenv->err(dbenv, ret, "%s: db_create", progname); + goto shutdown; + } + + if (TXN_ON(dbenv->env) && + (ret = dbp->set_flags(dbp, DB_TXN_NOT_DURABLE)) != 0) { + dbenv->err( + dbenv, ret, "%s: db_set_flags", progname); + goto shutdown; + } + + /* + * We create a 2nd dbp to this database to get its pagesize + * because the dbp we're using for verify cannot be opened. + * + * If the database is corrupted, we may not be able to open + * it, of course. In that case, just continue, using the + * cache size we have. + */ + if (private) { + if ((ret = db_create(&dbp1, dbenv, 0)) != 0) { + dbenv->err( + dbenv, ret, "%s: db_create", progname); + goto shutdown; + } + + if (TXN_ON(dbenv->env) && (ret = + dbp1->set_flags(dbp1, DB_TXN_NOT_DURABLE)) != 0) { + dbenv->err( + dbenv, ret, "%s: db_set_flags", progname); + goto shutdown; + } + + ret = dbp1->open(dbp1, + NULL, argv[0], NULL, DB_UNKNOWN, DB_RDONLY, 0); + + /* + * If we get here, we can check the cache/page. + * !!! + * If we have to retry with an env with a larger + * cache, we jump out of this loop. However, we + * will still be working on the same argv when we + * get back into the for-loop. + */ + if (ret == 0) { + if (__db_util_cache( + dbp1, &cache, &resize) == 0 && resize) { + (void)dbp1->close(dbp1, 0); + (void)dbp->close(dbp, 0); + dbp = NULL; + + (void)dbenv->close(dbenv, 0); + dbenv = NULL; + goto retry; + } + } + (void)dbp1->close(dbp1, 0); + } + + /* The verify method is a destructor. */ + ret = dbp->verify(dbp, argv[0], NULL, NULL, flags); + dbp = NULL; + if (ret != 0) + goto shutdown; + } + + if (0) { +shutdown: exitval = 1; + } + + if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) { + exitval = 1; + dbenv->err(dbenv, ret, "close"); + } + if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { + exitval = 1; + fprintf(stderr, + "%s: dbenv->close: %s\n", progname, db_strerror(ret)); + } + + if (passwd != NULL) + free(passwd); + + /* Resend any caught signal. */ + __db_util_sigresend(); + + return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} + +int +usage() +{ + fprintf(stderr, "usage: %s %s\n", progname, + "[-NoqV] [-h home] [-P password] db_file ..."); + return (EXIT_FAILURE); +} + +int +version_check() +{ + int v_major, v_minor, v_patch; + + /* Make sure we're loaded with the right version of the DB library. */ + (void)db_version(&v_major, &v_minor, &v_patch); + if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { + fprintf(stderr, + "%s: version %d.%d doesn't match library version %d.%d\n", + progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, + v_major, v_minor); + return (EXIT_FAILURE); + } + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/dbinc/btree.h b/src/libs/resiprocate/contrib/db/dbinc/btree.h new file mode 100644 index 00000000..afb81b33 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/btree.h @@ -0,0 +1,480 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ +#ifndef _DB_BTREE_H_ +#define _DB_BTREE_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Forward structure declarations. */ +struct __btree; typedef struct __btree BTREE; +struct __cursor; typedef struct __cursor BTREE_CURSOR; +struct __epg; typedef struct __epg EPG; + +#define DEFMINKEYPAGE (2) + +/* + * A recno order of 0 indicates that we don't have an order, not that we've + * an order less than 1. + */ +#define INVALID_ORDER 0 + +#define ISINTERNAL(p) (TYPE(p) == P_IBTREE || TYPE(p) == P_IRECNO) +#define ISLEAF(p) (TYPE(p) == P_LBTREE || \ + TYPE(p) == P_LRECNO || TYPE(p) == P_LDUP) + +/* Flags for __bam_cadjust_log(). */ +#define CAD_UPDATEROOT 0x01 /* Root page count was updated. */ + +/* Flags for __bam_split_log(). */ +#define SPL_NRECS 0x01 /* Split tree has record count. */ +#define SPL_RECNO 0x02 /* This is a Recno cursor. */ + +/* Flags for __bam_iitem(). */ +#define BI_DELETED 0x01 /* Key/data pair only placeholder. */ + +/* Flags for __bam_stkrel(). */ +#define STK_CLRDBC 0x01 /* Clear dbc->page reference. */ +#define STK_NOLOCK 0x02 /* Don't retain locks. */ +#define STK_PGONLY 0x04 + +/* Flags for __ram_ca(). These get logged, so make the values explicit. */ +typedef enum { + CA_DELETE = 0, /* Delete the current record. */ + CA_IAFTER = 1, /* Insert before the current record. */ + CA_IBEFORE = 2, /* Insert after the current record. */ + CA_ICURRENT = 3 /* Overwrite the current record. */ +} ca_recno_arg; + +/* + * Flags for __bam_search() and __bam_rsearch(). + * + * Note, internal page searches must find the largest record less than key in + * the tree so that descents work. Leaf page searches must find the smallest + * record greater than key so that the returned index is the record's correct + * position for insertion. + * + * The flags parameter to the search routines describes three aspects of the + * search: the type of locking required (including if we're locking a pair of + * pages), the item to return in the presence of duplicates and whether or not + * to return deleted entries. To simplify both the mnemonic representation + * and the code that checks for various cases, we construct a set of bitmasks. + */ +#define SR_READ 0x00001 /* Read locks. */ +#define SR_WRITE 0x00002 /* Write locks. */ + +#define SR_APPEND 0x00040 /* Append to the tree. */ +#define SR_DELNO 0x00080 /* Don't return deleted items. */ +#define SR_DUPFIRST 0x00100 /* Return first duplicate. */ +#define SR_DUPLAST 0x00200 /* Return last duplicate. */ +#define SR_EXACT 0x00400 /* Exact items only. */ +#define SR_PARENT 0x00800 /* Lock page pair. */ +#define SR_STACK 0x01000 /* Need a complete stack. */ +#define SR_PAST_EOF 0x02000 /* If doing insert search (or keyfirst + * or keylast operations), or a split + * on behalf of an insert, it's okay to + * return an entry one past end-of-page. + */ +#define SR_STK_ONLY 0x04000 /* Just return info in the stack */ +#define SR_MAX 0x08000 /* Get the right most key */ +#define SR_MIN 0x10000 /* Get the left most key */ +#define SR_NEXT 0x20000 /* Get the page after this key */ +#define SR_DEL 0x40000 /* Get the tree to delete this key. */ +#define SR_START 0x80000 /* Level to start stack. */ +#define SR_BOTH 0x100000 /* Get this and the NEXT page */ + +#define SR_DELETE \ + (SR_WRITE | SR_DUPFIRST | SR_DELNO | SR_EXACT | SR_STACK) +#define SR_FIND (SR_READ | SR_DUPFIRST | SR_DELNO) +#define SR_FIND_WR (SR_WRITE | SR_DUPFIRST | SR_DELNO) +#define SR_INSERT (SR_WRITE | SR_DUPLAST | SR_PAST_EOF | SR_STACK) +#define SR_KEYFIRST (SR_WRITE | SR_DUPFIRST | SR_PAST_EOF | SR_STACK) +#define SR_KEYLAST (SR_WRITE | SR_DUPLAST | SR_PAST_EOF | SR_STACK) +#define SR_WRPAIR (SR_WRITE | SR_DUPLAST | SR_PAST_EOF | SR_PARENT) + +/* + * Various routines pass around page references. A page reference is + * a pointer to the page, and the indx indicates an item on the page. + * Each page reference may include a lock. + */ +struct __epg { + PAGE *page; /* The page. */ + db_indx_t indx; /* The index on the page. */ + db_indx_t entries; /* The number of entries on page */ + DB_LOCK lock; /* The page's lock. */ + db_lockmode_t lock_mode; /* The lock mode. */ +}; + +/* + * We maintain a stack of the pages that we're locking in the tree. Grow + * the stack as necessary. + * + * XXX + * Temporary fix for #3243 -- clear the page and lock from the stack entry. + * The correct fix is to never release a stack that doesn't hold items. + */ +#define BT_STK_CLR(c) do { \ + (c)->csp = (c)->sp; \ + (c)->csp->page = NULL; \ + LOCK_INIT((c)->csp->lock); \ +} while (0) + +#define BT_STK_ENTER(env, c, pagep, page_indx, l, mode, ret) do { \ + if ((ret = ((c)->csp == (c)->esp ? \ + __bam_stkgrow(env, c) : 0)) == 0) { \ + (c)->csp->page = pagep; \ + (c)->csp->indx = (page_indx); \ + (c)->csp->entries = NUM_ENT(pagep); \ + (c)->csp->lock = l; \ + (c)->csp->lock_mode = mode; \ + } \ +} while (0) + +#define BT_STK_PUSH(env, c, pagep, page_indx, lock, mode, ret) do { \ + BT_STK_ENTER(env, c, pagep, page_indx, lock, mode, ret); \ + ++(c)->csp; \ +} while (0) + +#define BT_STK_NUM(env, c, pagep, page_indx, ret) do { \ + if ((ret = ((c)->csp == \ + (c)->esp ? __bam_stkgrow(env, c) : 0)) == 0) { \ + (c)->csp->page = NULL; \ + (c)->csp->indx = (page_indx); \ + (c)->csp->entries = NUM_ENT(pagep); \ + LOCK_INIT((c)->csp->lock); \ + (c)->csp->lock_mode = DB_LOCK_NG; \ + } \ +} while (0) + +#define BT_STK_NUMPUSH(env, c, pagep, page_indx, ret) do { \ + BT_STK_NUM(env, cp, pagep, page_indx, ret); \ + ++(c)->csp; \ +} while (0) + +#define BT_STK_POP(c) \ + ((c)->csp == (c)->sp ? NULL : --(c)->csp) + +/* + * Flags for __bam_dpages. + */ +#define BTD_UPDATE 0x0001 /* Update parents. */ +#define BTD_RELINK 0x0002 /* Relink leaf pages. */ + +/* + * TRY_LOCK + * When holding a stack we have pages latched but not locked so + * we must avoid an undetectable deadlock by not then blocking on a + * lock. + */ +#define TRY_LOCK(dbc, pgno, saved_pgno, saved_lock, lock_mode, label) \ + TRY_LOCK2(dbc, NULL, pgno, saved_pgno, saved_lock, lock_mode, label) +/* + * TRY_LOCK2 + * This is a special call for __bam_compact_int which uses 2 + * overlapping stacks. + */ + +#ifdef BTREE_DEBUG +#define TRY_LOCK2(dbc, ndbc, pgno, \ + saved_pgno, saved_lock, lock_mode, label) do { \ + static int BTcount = 0; \ + if ((pgno) != (saved_pgno) && \ + ((BTcount++ % 5) == 0 || \ + (ret = __db_lget(dbc, LCK_COUPLE_ALWAYS, pgno, \ + lock_mode, DB_LOCK_NOWAIT, &(saved_lock))) != 0)) { \ + if (ret != 0 && ret != DB_LOCK_NOTGRANTED && \ + ret != DB_LOCK_DEADLOCK) \ + break; \ + if ((ndbc) != NULL) { \ + BTREE_CURSOR *__cp; \ + __cp = (BTREE_CURSOR *) (dbc)->internal; \ + __cp->sp->page = NULL; \ + LOCK_INIT(__cp->sp->lock); \ + if ((ret = __bam_stkrel(ndbc, 0)) != 0) \ + break; \ + } \ + if ((ret = __bam_stkrel(dbc, 0)) != 0) \ + break; \ + if ((ret = __db_lget(dbc, LCK_COUPLE_ALWAYS, pgno, \ + lock_mode, 0, &(saved_lock))) != 0) \ + break; \ + saved_pgno = pgno; \ + goto label; \ + } \ + saved_pgno = pgno; \ +} while (0) +#else +#define TRY_LOCK2(dbc, ndbc, pgno, \ + saved_pgno, saved_lock, lock_mode, label) do { \ + if ((pgno) != (saved_pgno) && \ + (ret = __db_lget(dbc, LCK_COUPLE_ALWAYS, pgno, \ + lock_mode, DB_LOCK_NOWAIT, &(saved_lock))) != 0) { \ + if (ret != DB_LOCK_NOTGRANTED && \ + ret != DB_LOCK_DEADLOCK) \ + break; \ + if ((ndbc) != NULL) { \ + BTREE_CURSOR *__cp; \ + __cp = (BTREE_CURSOR *) (dbc)->internal; \ + __cp->sp->page = NULL; \ + LOCK_INIT(__cp->sp->lock); \ + if ((ret = __bam_stkrel(ndbc, 0)) != 0) \ + break; \ + } \ + if ((ret = __bam_stkrel(dbc, 0)) != 0) \ + break; \ + if ((ret = __db_lget(dbc, LCK_COUPLE_ALWAYS, pgno, \ + lock_mode, 0, &(saved_lock))) != 0) \ + break; \ + saved_pgno = pgno; \ + goto label; \ + } \ + saved_pgno = pgno; \ +} while (0) +#endif + +/* Btree/Recno cursor. */ +struct __cursor { + /* struct __dbc_internal */ + __DBC_INTERNAL + + /* btree private part */ + EPG *sp; /* Stack pointer. */ + EPG *csp; /* Current stack entry. */ + EPG *esp; /* End stack pointer. */ + EPG stack[5]; + + db_indx_t ovflsize; /* Maximum key/data on-page size. */ + + db_recno_t recno; /* Current record number. */ + u_int32_t order; /* Relative order among deleted curs. */ + +#ifdef HAVE_COMPRESSION + /* + * Compression: + * + * We need to hold the current compressed chunk, as well as the previous + * key/data, in order to decompress the next key/data. We do that by + * swapping whether prevKey/Data and currentKey/Data point to + * key1/data1, or key2/data2. + * + * We store prevcursor in order to be able to perform one level of + * DB_PREV by returning prevKey/prevData. We need prev2cursor to more + * efficiently do a subsequent DB_PREV with a linear search from the + * begining of the compressed chunk. + * + * When we delete entries, we set the cursor to point to the next entry + * after the last deleted key, and set C_COMPRESS_DELETED. The del_key + * DBT holds the key of the deleted entry supposedly pointed to by a + * compressed cursor, and is used to implement DB_PREV_DUP, + * DB_PREV_NODUP, DB_NEXT_DUP, and DB_NEXT_NODUP on a deleted entry. + */ + DBT compressed; /* Current compressed chunk */ + DBT key1; /* Holds prevKey or currentKey */ + DBT key2; /* Holds prevKey or currentKey */ + DBT data1; /* Holds prevData or currentData */ + DBT data2; /* Holds prevData or currentData */ + DBT del_key; /* Holds key from the deleted entry */ + DBT del_data; /* Holds data from the deleted entry */ + DBT *prevKey; /* Previous key decompressed */ + DBT *prevData; /* Previous data decompressed */ + DBT *currentKey; /* Current key decompressed */ + DBT *currentData; /* Current data decompressed */ + u_int8_t *compcursor; /* Current position in compressed */ + u_int8_t *compend; /* End of compressed */ + u_int8_t *prevcursor; /* Previous current position */ + u_int8_t *prev2cursor; /* Previous previous current position */ +#endif + + /* + * Btree: + * We set a flag in the cursor structure if the underlying object has + * been deleted. It's not strictly necessary, we could get the same + * information by looking at the page itself, but this method doesn't + * require us to retrieve the page on cursor delete. + * + * Recno: + * When renumbering recno databases during deletes, cursors referencing + * "deleted" records end up positioned between two records, and so must + * be specially adjusted on the next operation. + */ +#define C_DELETED 0x0001 /* Record was deleted. */ + /* + * There are three tree types that require maintaining record numbers. + * Recno AM trees, Btree AM trees for which the DB_RECNUM flag was set, + * and Btree off-page duplicate trees. + */ +#define C_RECNUM 0x0002 /* Tree requires record counts. */ + /* + * Recno trees have immutable record numbers by default, but optionally + * support mutable record numbers. Off-page duplicate Recno trees have + * mutable record numbers. All Btrees with record numbers (including + * off-page duplicate trees) are mutable by design, no flag is needed. + */ +#define C_RENUMBER 0x0004 /* Tree records are mutable. */ + /* + * The current compressed key/data could be deleted, as well as the + * key/data that the underlying BTree cursor points to. + */ +#define C_COMPRESS_DELETED 0x0008 /* Compressed record was deleted. */ + /* + * The current compressed chunk has been modified by another DBC. A + * compressed cursor will have to seek it's position again if necessary + * when it is next accessed. + */ +#define C_COMPRESS_MODIFIED 0x0010 /* Compressed record was modified. */ + u_int32_t flags; +}; + +/* + * Threshhold value, as a function of bt_minkey, of the number of + * bytes a key/data pair can use before being placed on an overflow + * page. Assume every item requires the maximum alignment for + * padding, out of sheer paranoia. + */ +#define B_MINKEY_TO_OVFLSIZE(dbp, minkey, pgsize) \ + ((u_int16_t)(((pgsize) - P_OVERHEAD(dbp)) / ((minkey) * P_INDX) -\ + (BKEYDATA_PSIZE(0) + DB_ALIGN(1, sizeof(int32_t))))) + +/* + * The maximum space that a single item can ever take up on one page. + * Used by __bam_split to determine whether a split is still necessary. + */ +#define B_MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define B_MAXSIZEONPAGE(ovflsize) \ + (B_MAX(BOVERFLOW_PSIZE, BKEYDATA_PSIZE(ovflsize))) + +/* + * The in-memory, per-tree btree/recno data structure. + */ +struct __btree { /* Btree access method. */ + /* + * !!! + * These fields are write-once (when the structure is created) and + * so are ignored as far as multi-threading is concerned. + */ + db_pgno_t bt_meta; /* Database meta-data page. */ + db_pgno_t bt_root; /* Database root page. */ + + u_int32_t bt_minkey; /* Minimum keys per page. */ + + /* Btree comparison function. */ + int (*bt_compare) __P((DB *, const DBT *, const DBT *)); + /* Btree prefix function. */ + size_t (*bt_prefix) __P((DB *, const DBT *, const DBT *)); + /* Btree compress function. */ +#ifdef HAVE_COMPRESSION + int (*bt_compress) __P((DB *, const DBT *, const DBT *, const DBT *, + const DBT *, DBT *)); + /* Btree decompress function. */ + int (*bt_decompress) __P((DB *, const DBT *, const DBT *, DBT *, DBT *, + DBT *)); + /* dup_compare for compression */ + int (*compress_dup_compare) __P((DB *, const DBT *, const DBT *)); +#endif + + /* Recno access method. */ + int re_pad; /* Fixed-length padding byte. */ + int re_delim; /* Variable-length delimiting byte. */ + u_int32_t re_len; /* Length for fixed-length records. */ + char *re_source; /* Source file name. */ + + /* + * !!! + * The bt_lpgno field is NOT protected by any mutex, and for this + * reason must be advisory only, so, while it is read/written by + * multiple threads, DB is completely indifferent to the quality + * of its information. + */ + db_pgno_t bt_lpgno; /* Last insert location. */ + DB_LSN bt_llsn; /* Last insert LSN. */ + + /* + * !!! + * The re_modified field is NOT protected by any mutex, and for this + * reason cannot be anything more complicated than a zero/non-zero + * value. The actual writing of the backing source file cannot be + * threaded, so clearing the flag isn't a problem. + */ + int re_modified; /* If the tree was modified. */ + + /* + * !!! + * These fields are ignored as far as multi-threading is concerned. + * There are no transaction semantics associated with backing files, + * nor is there any thread protection. + */ + FILE *re_fp; /* Source file handle. */ + int re_eof; /* Backing source file EOF reached. */ + db_recno_t re_last; /* Last record number read. */ + +}; + +/* + * Modes for the __bam_curadj recovery records (btree_curadj). + * These appear in log records, so we wire the values and + * do not leave it up to the compiler. + */ +typedef enum { + DB_CA_DI = 1, + DB_CA_DUP = 2, + DB_CA_RSPLIT = 3, + DB_CA_SPLIT = 4 +} db_ca_mode; + +/* + * Flags for __bam_pinsert. + */ +#define BPI_SPACEONLY 0x01 /* Only check for space to update. */ +#define BPI_NORECNUM 0x02 /* Not update the recnum on the left. */ +#define BPI_NOLOGGING 0x04 /* Don't log the update. */ +#define BPI_REPLACE 0x08 /* Repleace the record. */ + +#if defined(__cplusplus) +} +#endif + +#include "dbinc_auto/btree_auto.h" +#include "dbinc_auto/btree_ext.h" +#include "dbinc/db_am.h" +#endif /* !_DB_BTREE_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/crypto.h b/src/libs/resiprocate/contrib/db/dbinc/crypto.h new file mode 100644 index 00000000..1e60f725 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/crypto.h @@ -0,0 +1,85 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_CRYPTO_H_ +#define _DB_CRYPTO_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * !!! + * These are the internal representations of the algorithm flags. + * They are used in both the DB_CIPHER structure and the CIPHER + * structure so we can tell if users specified both passwd and alg + * correctly. + * + * CIPHER_ANY is used when an app joins an existing env but doesn't + * know the algorithm originally used. This is only valid in the + * DB_CIPHER structure until we open and can set the alg. + */ +/* + * We store the algorithm in an 8-bit field on the meta-page. So we + * use a numeric value, not bit fields. + * now we are limited to 8 algorithms before we cannot use bits and + * need numeric values. That should be plenty. It is okay for the + * CIPHER_ANY flag to go beyond that since that is never stored on disk. + */ + +/* + * This structure is per-process, not in shared memory. + */ +struct __db_cipher { + u_int (*adj_size) __P((size_t)); + int (*close) __P((ENV *, void *)); + int (*decrypt) __P((ENV *, void *, void *, u_int8_t *, size_t)); + int (*encrypt) __P((ENV *, void *, void *, u_int8_t *, size_t)); + int (*init) __P((ENV *, DB_CIPHER *)); + + u_int8_t mac_key[DB_MAC_KEY]; /* MAC key. */ + void *data; /* Algorithm-specific information */ + +#define CIPHER_AES 1 /* AES algorithm */ + u_int8_t alg; /* Algorithm used - See above */ + u_int8_t spare[3]; /* Spares */ + +#define CIPHER_ANY 0x00000001 /* Only for DB_CIPHER */ + u_int32_t flags; /* Other flags */ +}; + +#ifdef HAVE_CRYPTO + +#include "crypto/rijndael/rijndael-api-fst.h" + +/* + * Shared ciphering structure + * No mutex needed because all information is read-only after creation. + */ +typedef struct __cipher { + roff_t passwd; /* Offset to shared passwd */ + size_t passwd_len; /* Length of passwd */ + u_int32_t flags; /* Algorithm used - see above */ +} CIPHER; + +#define DB_AES_KEYLEN 128 /* AES key length */ +#define DB_AES_CHUNK 16 /* AES byte unit size */ + +typedef struct __aes_cipher { + keyInstance decrypt_ki; /* Decryption key instance */ + keyInstance encrypt_ki; /* Encryption key instance */ + u_int32_t flags; /* AES-specific flags */ +} AES_CIPHER; + +#include "dbinc_auto/crypto_ext.h" +#endif /* HAVE_CRYPTO */ + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_CRYPTO_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/cxx_int.h b/src/libs/resiprocate/contrib/db/dbinc/cxx_int.h new file mode 100644 index 00000000..2e423b4e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/cxx_int.h @@ -0,0 +1,75 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_CXX_INT_H_ +#define _DB_CXX_INT_H_ + +// private data structures known to the implementation only + +// +// Using FooImp classes will allow the implementation to change in the +// future without any modification to user code or even to header files +// that the user includes. FooImp * is just like void * except that it +// provides a little extra protection, since you cannot randomly assign +// any old pointer to a FooImp* as you can with void *. Currently, a +// pointer to such an opaque class is always just a pointer to the +// appropriate underlying implementation struct. These are converted +// back and forth using the various overloaded wrap()/unwrap() methods. +// This is essentially a use of the "Bridge" Design Pattern. +// +// WRAPPED_CLASS implements the appropriate wrap() and unwrap() methods +// for a wrapper class that has an underlying pointer representation. +// +#define WRAPPED_CLASS(_WRAPPER_CLASS, _IMP_CLASS, _WRAPPED_TYPE) \ + class _IMP_CLASS {}; \ + \ + inline _WRAPPED_TYPE *unwrap(_WRAPPER_CLASS *val) \ + { \ + if (!val) return (0); \ + return (val->get_##_WRAPPED_TYPE()); \ + } \ + \ + inline const _WRAPPED_TYPE *unwrapConst(const _WRAPPER_CLASS *val) \ + { \ + if (!val) return (0); \ + return (val->get_const_##_WRAPPED_TYPE()); \ + } + +WRAPPED_CLASS(Db, DbImp, DB) +WRAPPED_CLASS(DbEnv, DbEnvImp, DB_ENV) +WRAPPED_CLASS(DbMpoolFile, DbMpoolFileImp, DB_MPOOLFILE) +WRAPPED_CLASS(DbSequence, DbSequenceImp, DB_SEQUENCE) +WRAPPED_CLASS(DbTxn, DbTxnImp, DB_TXN) + +// A tristate integer value used by the DB_ERROR macro below. +// We chose not to make this an enumerated type so it can +// be kept private, even though methods that return the +// tristate int can be declared in db_cxx.h . +// +#define ON_ERROR_THROW 1 +#define ON_ERROR_RETURN 0 +#define ON_ERROR_UNKNOWN (-1) + +// Macros that handle detected errors, in case we want to +// change the default behavior. The 'policy' is one of +// the tristate values given above. If UNKNOWN is specified, +// the behavior is taken from the last initialized DbEnv. +// +#define DB_ERROR(dbenv, caller, ecode, policy) \ + DbEnv::runtime_error(dbenv, caller, ecode, policy) + +#define DB_ERROR_DBT(dbenv, caller, dbt, policy) \ + DbEnv::runtime_error_dbt(dbenv, caller, dbt, policy) + +#define DB_OVERFLOWED_DBT(dbt) \ + (F_ISSET(dbt, DB_DBT_USERMEM) && dbt->size > dbt->ulen) + +/* values for Db::flags_ */ +#define DB_CXX_PRIVATE_ENV 0x00000001 + +#endif /* !_DB_CXX_INT_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db.in b/src/libs/resiprocate/contrib/db/dbinc/db.in new file mode 100644 index 00000000..9fc6712b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db.in @@ -0,0 +1,2441 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + * + * db.h include file layout: + * General. + * Database Environment. + * Locking subsystem. + * Logging subsystem. + * Shared buffer cache (mpool) subsystem. + * Transaction subsystem. + * Access methods. + * Access method cursors. + * Dbm/Ndbm, Hsearch historic interfaces. + */ + +#ifndef _DB_H_ +#define _DB_H_ + +#ifndef __NO_SYSTEM_INCLUDES +#include +@inttypes_h_decl@ +@stdint_h_decl@ +@stddef_h_decl@ +#include +@unistd_h_decl@ +@thread_h_decl@ +#endif + +@platform_header@ +#if defined(__cplusplus) +extern "C" { +#endif + +@DB_CONST@ +@DB_PROTO1@ +@DB_PROTO2@ + +/* + * Berkeley DB version information. + */ +#define DB_VERSION_MAJOR @DB_VERSION_MAJOR@ +#define DB_VERSION_MINOR @DB_VERSION_MINOR@ +#define DB_VERSION_PATCH @DB_VERSION_PATCH@ +#define DB_VERSION_STRING @DB_VERSION_STRING@ + +/* + * !!! + * Berkeley DB uses specifically sized types. If they're not provided by + * the system, typedef them here. + * + * We protect them against multiple inclusion using __BIT_TYPES_DEFINED__, + * as does BIND and Kerberos, since we don't know for sure what #include + * files the user is using. + * + * !!! + * We also provide the standard u_int, u_long etc., if they're not provided + * by the system. + */ +#ifndef __BIT_TYPES_DEFINED__ +#define __BIT_TYPES_DEFINED__ +@u_int8_decl@ +@int16_decl@ +@u_int16_decl@ +@int32_decl@ +@u_int32_decl@ +@int64_decl@ +@u_int64_decl@ +#endif + +@u_char_decl@ +@u_int_decl@ +@u_long_decl@ +@u_short_decl@ + +/* + * Missing ANSI types. + * + * uintmax_t -- + * Largest unsigned type, used to align structures in memory. We don't store + * floating point types in structures, so integral types should be sufficient + * (and we don't have to worry about systems that store floats in other than + * power-of-2 numbers of bytes). Additionally this fixes compilers that rewrite + * structure assignments and ANSI C memcpy calls to be in-line instructions + * that happen to require alignment. + * + * uintptr_t -- + * Unsigned type that's the same size as a pointer. There are places where + * DB modifies pointers by discarding the bottom bits to guarantee alignment. + * We can't use uintmax_t, it may be larger than the pointer, and compilers + * get upset about that. So far we haven't run on any machine where there's + * no unsigned type the same size as a pointer -- here's hoping. + */ +@uintmax_t_decl@ +@uintptr_t_decl@ + +@FILE_t_decl@ +@off_t_decl@ +@pid_t_decl@ +@size_t_decl@ +@ssize_t_decl@ +@time_t_decl@ + +/* + * Sequences are only available on machines with 64-bit integral types. + */ +@db_seq_decl@ + +/* Thread and process identification. */ +@db_threadid_t_decl@ + +/* Basic types that are exported or quasi-exported. */ +typedef u_int32_t db_pgno_t; /* Page number type. */ +typedef u_int16_t db_indx_t; /* Page offset type. */ +#define DB_MAX_PAGES 0xffffffff /* >= # of pages in a file */ + +typedef u_int32_t db_recno_t; /* Record number type. */ +#define DB_MAX_RECORDS 0xffffffff /* >= # of records in a tree */ + +typedef u_int32_t db_timeout_t; /* Type of a timeout. */ + +/* + * Region offsets are the difference between a pointer in a region and the + * region's base address. With private environments, both addresses are the + * result of calling malloc, and we can't assume anything about what malloc + * will return, so region offsets have to be able to hold differences between + * arbitrary pointers. + */ +typedef uintptr_t roff_t; + +/* + * Forward structure declarations, so we can declare pointers and + * applications can get type checking. + */ +struct __db; typedef struct __db DB; +struct __db_bt_stat; typedef struct __db_bt_stat DB_BTREE_STAT; +struct __db_cipher; typedef struct __db_cipher DB_CIPHER; +struct __db_compact; typedef struct __db_compact DB_COMPACT; +struct __db_dbt; typedef struct __db_dbt DBT; +struct __db_distab; typedef struct __db_distab DB_DISTAB; +struct __db_env; typedef struct __db_env DB_ENV; +struct __db_h_stat; typedef struct __db_h_stat DB_HASH_STAT; +struct __db_ilock; typedef struct __db_ilock DB_LOCK_ILOCK; +struct __db_lock_hstat; typedef struct __db_lock_hstat DB_LOCK_HSTAT; +struct __db_lock_pstat; typedef struct __db_lock_pstat DB_LOCK_PSTAT; +struct __db_lock_stat; typedef struct __db_lock_stat DB_LOCK_STAT; +struct __db_lock_u; typedef struct __db_lock_u DB_LOCK; +struct __db_locker; typedef struct __db_locker DB_LOCKER; +struct __db_lockreq; typedef struct __db_lockreq DB_LOCKREQ; +struct __db_locktab; typedef struct __db_locktab DB_LOCKTAB; +struct __db_log; typedef struct __db_log DB_LOG; +struct __db_log_cursor; typedef struct __db_log_cursor DB_LOGC; +struct __db_log_stat; typedef struct __db_log_stat DB_LOG_STAT; +struct __db_lsn; typedef struct __db_lsn DB_LSN; +struct __db_mpool; typedef struct __db_mpool DB_MPOOL; +struct __db_mpool_fstat;typedef struct __db_mpool_fstat DB_MPOOL_FSTAT; +struct __db_mpool_stat; typedef struct __db_mpool_stat DB_MPOOL_STAT; +struct __db_mpoolfile; typedef struct __db_mpoolfile DB_MPOOLFILE; +struct __db_mutex_stat; typedef struct __db_mutex_stat DB_MUTEX_STAT; +struct __db_mutex_t; typedef struct __db_mutex_t DB_MUTEX; +struct __db_mutexmgr; typedef struct __db_mutexmgr DB_MUTEXMGR; +struct __db_preplist; typedef struct __db_preplist DB_PREPLIST; +struct __db_qam_stat; typedef struct __db_qam_stat DB_QUEUE_STAT; +struct __db_rep; typedef struct __db_rep DB_REP; +struct __db_rep_stat; typedef struct __db_rep_stat DB_REP_STAT; +struct __db_repmgr_site;typedef struct __db_repmgr_site DB_REPMGR_SITE; +struct __db_repmgr_stat;typedef struct __db_repmgr_stat DB_REPMGR_STAT; +struct __db_seq_record; typedef struct __db_seq_record DB_SEQ_RECORD; +struct __db_seq_stat; typedef struct __db_seq_stat DB_SEQUENCE_STAT; +struct __db_sequence; typedef struct __db_sequence DB_SEQUENCE; +struct __db_thread_info;typedef struct __db_thread_info DB_THREAD_INFO; +struct __db_txn; typedef struct __db_txn DB_TXN; +struct __db_txn_active; typedef struct __db_txn_active DB_TXN_ACTIVE; +struct __db_txn_stat; typedef struct __db_txn_stat DB_TXN_STAT; +struct __db_txnmgr; typedef struct __db_txnmgr DB_TXNMGR; +struct __dbc; typedef struct __dbc DBC; +struct __dbc_internal; typedef struct __dbc_internal DBC_INTERNAL; +struct __env; typedef struct __env ENV; +struct __fh_t; typedef struct __fh_t DB_FH; +struct __fname; typedef struct __fname FNAME; +struct __key_range; typedef struct __key_range DB_KEY_RANGE; +struct __mpoolfile; typedef struct __mpoolfile MPOOLFILE; + +/* + * The Berkeley DB API flags are automatically-generated -- the following flag + * names are no longer used, but remain for compatibility reasons. + */ +#define DB_DEGREE_2 DB_READ_COMMITTED +#define DB_DIRTY_READ DB_READ_UNCOMMITTED +#define DB_JOINENV 0x0 + +/* Key/data structure -- a Data-Base Thang. */ +struct __db_dbt { + void *data; /* Key/data */ + u_int32_t size; /* key/data length */ + + u_int32_t ulen; /* RO: length of user buffer. */ + u_int32_t dlen; /* RO: get/put record length. */ + u_int32_t doff; /* RO: get/put record offset. */ + + void *app_data; + +#define DB_DBT_APPMALLOC 0x001 /* Callback allocated memory. */ +#define DB_DBT_BULK 0x002 /* Internal: Insert if duplicate. */ +#define DB_DBT_DUPOK 0x004 /* Internal: Insert if duplicate. */ +#define DB_DBT_ISSET 0x008 /* Lower level calls set value. */ +#define DB_DBT_MALLOC 0x010 /* Return in malloc'd memory. */ +#define DB_DBT_MULTIPLE 0x020 /* References multiple records. */ +#define DB_DBT_PARTIAL 0x040 /* Partial put/get. */ +#define DB_DBT_REALLOC 0x080 /* Return in realloc'd memory. */ +#define DB_DBT_STREAMING 0x100 /* Internal: DBT is being streamed. */ +#define DB_DBT_USERCOPY 0x200 /* Use the user-supplied callback. */ +#define DB_DBT_USERMEM 0x400 /* Return in user's memory. */ + u_int32_t flags; +}; + +/******************************************************* + * Mutexes. + *******************************************************/ +typedef u_int32_t db_mutex_t; + +struct __db_mutex_stat { + /* The following fields are maintained in the region's copy. */ + u_int32_t st_mutex_align; /* Mutex alignment */ + u_int32_t st_mutex_tas_spins; /* Mutex test-and-set spins */ + u_int32_t st_mutex_cnt; /* Mutex count */ + u_int32_t st_mutex_free; /* Available mutexes */ + u_int32_t st_mutex_inuse; /* Mutexes in use */ + u_int32_t st_mutex_inuse_max; /* Maximum mutexes ever in use */ + + /* The following fields are filled-in from other places. */ +#ifndef __TEST_DB_NO_STATISTICS + uintmax_t st_region_wait; /* Region lock granted after wait. */ + uintmax_t st_region_nowait; /* Region lock granted without wait. */ + roff_t st_regsize; /* Region size. */ +#endif +}; + +/* This is the length of the buffer passed to DB_ENV->thread_id_string() */ +#define DB_THREADID_STRLEN 128 + +/******************************************************* + * Locking. + *******************************************************/ +#define DB_LOCKVERSION 1 + +#define DB_FILE_ID_LEN 20 /* Unique file ID length. */ + +/* + * Deadlock detector modes; used in the DB_ENV structure to configure the + * locking subsystem. + */ +#define DB_LOCK_NORUN 0 +#define DB_LOCK_DEFAULT 1 /* Default policy. */ +#define DB_LOCK_EXPIRE 2 /* Only expire locks, no detection. */ +#define DB_LOCK_MAXLOCKS 3 /* Select locker with max locks. */ +#define DB_LOCK_MAXWRITE 4 /* Select locker with max writelocks. */ +#define DB_LOCK_MINLOCKS 5 /* Select locker with min locks. */ +#define DB_LOCK_MINWRITE 6 /* Select locker with min writelocks. */ +#define DB_LOCK_OLDEST 7 /* Select oldest locker. */ +#define DB_LOCK_RANDOM 8 /* Select random locker. */ +#define DB_LOCK_YOUNGEST 9 /* Select youngest locker. */ + +/* + * Simple R/W lock modes and for multi-granularity intention locking. + * + * !!! + * These values are NOT random, as they are used as an index into the lock + * conflicts arrays, i.e., DB_LOCK_IWRITE must be == 3, and DB_LOCK_IREAD + * must be == 4. + */ +typedef enum { + DB_LOCK_NG=0, /* Not granted. */ + DB_LOCK_READ=1, /* Shared/read. */ + DB_LOCK_WRITE=2, /* Exclusive/write. */ + DB_LOCK_WAIT=3, /* Wait for event */ + DB_LOCK_IWRITE=4, /* Intent exclusive/write. */ + DB_LOCK_IREAD=5, /* Intent to share/read. */ + DB_LOCK_IWR=6, /* Intent to read and write. */ + DB_LOCK_READ_UNCOMMITTED=7, /* Degree 1 isolation. */ + DB_LOCK_WWRITE=8 /* Was Written. */ +} db_lockmode_t; + +/* + * Request types. + */ +typedef enum { + DB_LOCK_DUMP=0, /* Display held locks. */ + DB_LOCK_GET=1, /* Get the lock. */ + DB_LOCK_GET_TIMEOUT=2, /* Get lock with a timeout. */ + DB_LOCK_INHERIT=3, /* Pass locks to parent. */ + DB_LOCK_PUT=4, /* Release the lock. */ + DB_LOCK_PUT_ALL=5, /* Release locker's locks. */ + DB_LOCK_PUT_OBJ=6, /* Release locker's locks on obj. */ + DB_LOCK_PUT_READ=7, /* Release locker's read locks. */ + DB_LOCK_TIMEOUT=8, /* Force a txn to timeout. */ + DB_LOCK_TRADE=9, /* Trade locker ids on a lock. */ + DB_LOCK_UPGRADE_WRITE=10 /* Upgrade writes for dirty reads. */ +} db_lockop_t; + +/* + * Status of a lock. + */ +typedef enum { + DB_LSTAT_ABORTED=1, /* Lock belongs to an aborted txn. */ + DB_LSTAT_EXPIRED=2, /* Lock has expired. */ + DB_LSTAT_FREE=3, /* Lock is unallocated. */ + DB_LSTAT_HELD=4, /* Lock is currently held. */ + DB_LSTAT_PENDING=5, /* Lock was waiting and has been + * promoted; waiting for the owner + * to run and upgrade it to held. */ + DB_LSTAT_WAITING=6 /* Lock is on the wait queue. */ +}db_status_t; + +/* Lock statistics structure. */ +struct __db_lock_stat { + u_int32_t st_id; /* Last allocated locker ID. */ + u_int32_t st_cur_maxid; /* Current maximum unused ID. */ + u_int32_t st_maxlocks; /* Maximum number of locks in table. */ + u_int32_t st_maxlockers; /* Maximum num of lockers in table. */ + u_int32_t st_maxobjects; /* Maximum num of objects in table. */ + u_int32_t st_partitions; /* number of partitions. */ + int st_nmodes; /* Number of lock modes. */ + u_int32_t st_nlockers; /* Current number of lockers. */ +#ifndef __TEST_DB_NO_STATISTICS + u_int32_t st_nlocks; /* Current number of locks. */ + u_int32_t st_maxnlocks; /* Maximum number of locks so far. */ + u_int32_t st_maxhlocks; /* Maximum number of locks in any bucket. */ + uintmax_t st_locksteals; /* Number of lock steals so far. */ + uintmax_t st_maxlsteals; /* Maximum number steals in any partition. */ + u_int32_t st_maxnlockers; /* Maximum number of lockers so far. */ + u_int32_t st_nobjects; /* Current number of objects. */ + u_int32_t st_maxnobjects; /* Maximum number of objects so far. */ + u_int32_t st_maxhobjects; /* Maximum number of objectsin any bucket. */ + uintmax_t st_objectsteals; /* Number of objects steals so far. */ + uintmax_t st_maxosteals; /* Maximum number of steals in any partition. */ + uintmax_t st_nrequests; /* Number of lock gets. */ + uintmax_t st_nreleases; /* Number of lock puts. */ + uintmax_t st_nupgrade; /* Number of lock upgrades. */ + uintmax_t st_ndowngrade; /* Number of lock downgrades. */ + uintmax_t st_lock_wait; /* Lock conflicts w/ subsequent wait */ + uintmax_t st_lock_nowait; /* Lock conflicts w/o subsequent wait */ + uintmax_t st_ndeadlocks; /* Number of lock deadlocks. */ + db_timeout_t st_locktimeout; /* Lock timeout. */ + uintmax_t st_nlocktimeouts; /* Number of lock timeouts. */ + db_timeout_t st_txntimeout; /* Transaction timeout. */ + uintmax_t st_ntxntimeouts; /* Number of transaction timeouts. */ + uintmax_t st_part_wait; /* Partition lock granted after wait. */ + uintmax_t st_part_nowait; /* Partition lock granted without wait. */ + uintmax_t st_part_max_wait; /* Max partition lock granted after wait. */ + uintmax_t st_part_max_nowait; /* Max partition lock granted without wait. */ + uintmax_t st_objs_wait; /* Object lock granted after wait. */ + uintmax_t st_objs_nowait; /* Object lock granted without wait. */ + uintmax_t st_lockers_wait; /* Locker lock granted after wait. */ + uintmax_t st_lockers_nowait; /* Locker lock granted without wait. */ + uintmax_t st_region_wait; /* Region lock granted after wait. */ + uintmax_t st_region_nowait; /* Region lock granted without wait. */ + u_int32_t st_hash_len; /* Max length of bucket. */ + roff_t st_regsize; /* Region size. */ +#endif +}; + +struct __db_lock_hstat { + uintmax_t st_nrequests; /* Number of lock gets. */ + uintmax_t st_nreleases; /* Number of lock puts. */ + uintmax_t st_nupgrade; /* Number of lock upgrades. */ + uintmax_t st_ndowngrade; /* Number of lock downgrades. */ + u_int32_t st_nlocks; /* Current number of locks. */ + u_int32_t st_maxnlocks; /* Maximum number of locks so far. */ + u_int32_t st_nobjects; /* Current number of objects. */ + u_int32_t st_maxnobjects; /* Maximum number of objects so far. */ + uintmax_t st_lock_wait; /* Lock conflicts w/ subsequent wait */ + uintmax_t st_lock_nowait; /* Lock conflicts w/o subsequent wait */ + uintmax_t st_nlocktimeouts; /* Number of lock timeouts. */ + uintmax_t st_ntxntimeouts; /* Number of transaction timeouts. */ + u_int32_t st_hash_len; /* Max length of bucket. */ +}; + +struct __db_lock_pstat { + u_int32_t st_nlocks; /* Current number of locks. */ + u_int32_t st_maxnlocks; /* Maximum number of locks so far. */ + u_int32_t st_nobjects; /* Current number of objects. */ + u_int32_t st_maxnobjects; /* Maximum number of objects so far. */ + uintmax_t st_locksteals; /* Number of lock steals so far. */ + uintmax_t st_objectsteals; /* Number of objects steals so far. */ +}; + +/* + * DB_LOCK_ILOCK -- + * Internal DB access method lock. + */ +struct __db_ilock { + db_pgno_t pgno; /* Page being locked. */ + u_int8_t fileid[DB_FILE_ID_LEN];/* File id. */ +#define DB_HANDLE_LOCK 1 +#define DB_RECORD_LOCK 2 +#define DB_PAGE_LOCK 3 + u_int32_t type; /* Type of lock. */ +}; + +/* + * DB_LOCK -- + * The structure is allocated by the caller and filled in during a + * lock_get request (or a lock_vec/DB_LOCK_GET). + */ +struct __db_lock_u { + roff_t off; /* Offset of the lock in the region */ + u_int32_t ndx; /* Index of the object referenced by + * this lock; used for locking. */ + u_int32_t gen; /* Generation number of this lock. */ + db_lockmode_t mode; /* mode of this lock. */ +}; + +/* Lock request structure. */ +struct __db_lockreq { + db_lockop_t op; /* Operation. */ + db_lockmode_t mode; /* Requested mode. */ + db_timeout_t timeout; /* Time to expire lock. */ + DBT *obj; /* Object being locked. */ + DB_LOCK lock; /* Lock returned. */ +}; + +/******************************************************* + * Logging. + *******************************************************/ +#define DB_LOGVERSION 16 /* Current log version. */ +#define DB_LOGVERSION_LATCHING 15 /* Log version using latching. */ +#define DB_LOGCHKSUM 12 /* Check sum headers. */ +#define DB_LOGOLDVER 8 /* Oldest log version supported. */ +#define DB_LOGMAGIC 0x040988 + +/* + * A DB_LSN has two parts, a fileid which identifies a specific file, and an + * offset within that file. The fileid is an unsigned 4-byte quantity that + * uniquely identifies a file within the log directory -- currently a simple + * counter inside the log. The offset is also an unsigned 4-byte value. The + * log manager guarantees the offset is never more than 4 bytes by switching + * to a new log file before the maximum length imposed by an unsigned 4-byte + * offset is reached. + */ +struct __db_lsn { + u_int32_t file; /* File ID. */ + u_int32_t offset; /* File offset. */ +}; + +/* + * Application-specified log record types start at DB_user_BEGIN, and must not + * equal or exceed DB_debug_FLAG. + * + * DB_debug_FLAG is the high-bit of the u_int32_t that specifies a log record + * type. If the flag is set, it's a log record that was logged for debugging + * purposes only, even if it reflects a database change -- the change was part + * of a non-durable transaction. + */ +#define DB_user_BEGIN 10000 +#define DB_debug_FLAG 0x80000000 + +/* + * DB_LOGC -- + * Log cursor. + */ +struct __db_log_cursor { + ENV *env; /* Environment */ + + DB_FH *fhp; /* File handle. */ + DB_LSN lsn; /* Cursor: LSN */ + u_int32_t len; /* Cursor: record length */ + u_int32_t prev; /* Cursor: previous record's offset */ + + DBT dbt; /* Return DBT. */ + DB_LSN p_lsn; /* Persist LSN. */ + u_int32_t p_version; /* Persist version. */ + + u_int8_t *bp; /* Allocated read buffer. */ + u_int32_t bp_size; /* Read buffer length in bytes. */ + u_int32_t bp_rlen; /* Read buffer valid data length. */ + DB_LSN bp_lsn; /* Read buffer first byte LSN. */ + + u_int32_t bp_maxrec; /* Max record length in the log file. */ + + /* DB_LOGC PUBLIC HANDLE LIST BEGIN */ + int (*close) __P((DB_LOGC *, u_int32_t)); + int (*get) __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t)); + int (*version) __P((DB_LOGC *, u_int32_t *, u_int32_t)); + /* DB_LOGC PUBLIC HANDLE LIST END */ + +#define DB_LOG_DISK 0x01 /* Log record came from disk. */ +#define DB_LOG_LOCKED 0x02 /* Log region already locked */ +#define DB_LOG_SILENT_ERR 0x04 /* Turn-off error messages. */ + u_int32_t flags; +}; + +/* Log statistics structure. */ +struct __db_log_stat { + u_int32_t st_magic; /* Log file magic number. */ + u_int32_t st_version; /* Log file version number. */ + int st_mode; /* Log file permissions mode. */ + u_int32_t st_lg_bsize; /* Log buffer size. */ + u_int32_t st_lg_size; /* Log file size. */ + u_int32_t st_wc_bytes; /* Bytes to log since checkpoint. */ + u_int32_t st_wc_mbytes; /* Megabytes to log since checkpoint. */ +#ifndef __TEST_DB_NO_STATISTICS + uintmax_t st_record; /* Records entered into the log. */ + u_int32_t st_w_bytes; /* Bytes to log. */ + u_int32_t st_w_mbytes; /* Megabytes to log. */ + uintmax_t st_wcount; /* Total I/O writes to the log. */ + uintmax_t st_wcount_fill; /* Overflow writes to the log. */ + uintmax_t st_rcount; /* Total I/O reads from the log. */ + uintmax_t st_scount; /* Total syncs to the log. */ + uintmax_t st_region_wait; /* Region lock granted after wait. */ + uintmax_t st_region_nowait; /* Region lock granted without wait. */ + u_int32_t st_cur_file; /* Current log file number. */ + u_int32_t st_cur_offset; /* Current log file offset. */ + u_int32_t st_disk_file; /* Known on disk log file number. */ + u_int32_t st_disk_offset; /* Known on disk log file offset. */ + u_int32_t st_maxcommitperflush; /* Max number of commits in a flush. */ + u_int32_t st_mincommitperflush; /* Min number of commits in a flush. */ + roff_t st_regsize; /* Region size. */ +#endif +}; + +/* + * We need to record the first log record of a transaction. For user + * defined logging this macro returns the place to put that information, + * if it is need in rlsnp, otherwise it leaves it unchanged. We also + * need to track the last record of the transaction, this returns the + * place to put that info. + */ +#define DB_SET_TXN_LSNP(txn, blsnp, llsnp) \ + ((txn)->set_txn_lsnp(txn, blsnp, llsnp)) + +/******************************************************* + * Shared buffer cache (mpool). + *******************************************************/ +/* Priority values for DB_MPOOLFILE->{put,set_priority}. */ +typedef enum { + DB_PRIORITY_UNCHANGED=0, + DB_PRIORITY_VERY_LOW=1, + DB_PRIORITY_LOW=2, + DB_PRIORITY_DEFAULT=3, + DB_PRIORITY_HIGH=4, + DB_PRIORITY_VERY_HIGH=5 +} DB_CACHE_PRIORITY; + +/* Per-process DB_MPOOLFILE information. */ +struct __db_mpoolfile { + DB_FH *fhp; /* Underlying file handle. */ + + /* + * !!! + * The ref, pinref and q fields are protected by the region lock. + */ + u_int32_t ref; /* Reference count. */ + + u_int32_t pinref; /* Pinned block reference count. */ + + /* + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_ENTRY(__db_mpoolfile) q; + */ + struct { + struct __db_mpoolfile *tqe_next; + struct __db_mpoolfile **tqe_prev; + } q; /* Linked list of DB_MPOOLFILE's. */ + + /* + * !!! + * The rest of the fields (with the exception of the MP_FLUSH flag) + * are not thread-protected, even when they may be modified at any + * time by the application. The reason is the DB_MPOOLFILE handle + * is single-threaded from the viewpoint of the application, and so + * the only fields needing to be thread-protected are those accessed + * by checkpoint or sync threads when using DB_MPOOLFILE structures + * to flush buffers from the cache. + */ + ENV *env; /* Environment */ + MPOOLFILE *mfp; /* Underlying MPOOLFILE. */ + + u_int32_t clear_len; /* Cleared length on created pages. */ + u_int8_t /* Unique file ID. */ + fileid[DB_FILE_ID_LEN]; + int ftype; /* File type. */ + int32_t lsn_offset; /* LSN offset in page. */ + u_int32_t gbytes, bytes; /* Maximum file size. */ + DBT *pgcookie; /* Byte-string passed to pgin/pgout. */ + int32_t priority; /* Cache priority. */ + + void *addr; /* Address of mmap'd region. */ + size_t len; /* Length of mmap'd region. */ + + u_int32_t config_flags; /* Flags to DB_MPOOLFILE->set_flags. */ + + /* DB_MPOOLFILE PUBLIC HANDLE LIST BEGIN */ + int (*close) __P((DB_MPOOLFILE *, u_int32_t)); + int (*get) + __P((DB_MPOOLFILE *, db_pgno_t *, DB_TXN *, u_int32_t, void *)); + int (*get_clear_len) __P((DB_MPOOLFILE *, u_int32_t *)); + int (*get_fileid) __P((DB_MPOOLFILE *, u_int8_t *)); + int (*get_flags) __P((DB_MPOOLFILE *, u_int32_t *)); + int (*get_ftype) __P((DB_MPOOLFILE *, int *)); + int (*get_last_pgno) __P((DB_MPOOLFILE *, db_pgno_t *)); + int (*get_lsn_offset) __P((DB_MPOOLFILE *, int32_t *)); + int (*get_maxsize) __P((DB_MPOOLFILE *, u_int32_t *, u_int32_t *)); + int (*get_pgcookie) __P((DB_MPOOLFILE *, DBT *)); + int (*get_priority) __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY *)); + int (*open) __P((DB_MPOOLFILE *, const char *, u_int32_t, int, size_t)); + int (*put) __P((DB_MPOOLFILE *, void *, DB_CACHE_PRIORITY, u_int32_t)); + int (*set_clear_len) __P((DB_MPOOLFILE *, u_int32_t)); + int (*set_fileid) __P((DB_MPOOLFILE *, u_int8_t *)); + int (*set_flags) __P((DB_MPOOLFILE *, u_int32_t, int)); + int (*set_ftype) __P((DB_MPOOLFILE *, int)); + int (*set_lsn_offset) __P((DB_MPOOLFILE *, int32_t)); + int (*set_maxsize) __P((DB_MPOOLFILE *, u_int32_t, u_int32_t)); + int (*set_pgcookie) __P((DB_MPOOLFILE *, DBT *)); + int (*set_priority) __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY)); + int (*sync) __P((DB_MPOOLFILE *)); + /* DB_MPOOLFILE PUBLIC HANDLE LIST END */ + + /* + * MP_FILEID_SET, MP_OPEN_CALLED and MP_READONLY do not need to be + * thread protected because they are initialized before the file is + * linked onto the per-process lists, and never modified. + * + * MP_FLUSH is thread protected because it is potentially read/set by + * multiple threads of control. + */ +#define MP_FILEID_SET 0x001 /* Application supplied a file ID. */ +#define MP_FLUSH 0x002 /* Was opened to flush a buffer. */ +#define MP_MULTIVERSION 0x004 /* Opened for multiversion access. */ +#define MP_OPEN_CALLED 0x008 /* File opened. */ +#define MP_READONLY 0x010 /* File is readonly. */ +#define MP_DUMMY 0x020 /* File is dummy for __memp_fput. */ + u_int32_t flags; +}; + +/* Mpool statistics structure. */ +struct __db_mpool_stat { + u_int32_t st_gbytes; /* Total cache size: GB. */ + u_int32_t st_bytes; /* Total cache size: B. */ + u_int32_t st_ncache; /* Number of cache regions. */ + u_int32_t st_max_ncache; /* Maximum number of regions. */ + size_t st_mmapsize; /* Maximum file size for mmap. */ + int st_maxopenfd; /* Maximum number of open fd's. */ + int st_maxwrite; /* Maximum buffers to write. */ + db_timeout_t st_maxwrite_sleep; /* Sleep after writing max buffers. */ + u_int32_t st_pages; /* Total number of pages. */ +#ifndef __TEST_DB_NO_STATISTICS + u_int32_t st_map; /* Pages from mapped files. */ + uintmax_t st_cache_hit; /* Pages found in the cache. */ + uintmax_t st_cache_miss; /* Pages not found in the cache. */ + uintmax_t st_page_create; /* Pages created in the cache. */ + uintmax_t st_page_in; /* Pages read in. */ + uintmax_t st_page_out; /* Pages written out. */ + uintmax_t st_ro_evict; /* Clean pages forced from the cache. */ + uintmax_t st_rw_evict; /* Dirty pages forced from the cache. */ + uintmax_t st_page_trickle; /* Pages written by memp_trickle. */ + u_int32_t st_page_clean; /* Clean pages. */ + u_int32_t st_page_dirty; /* Dirty pages. */ + u_int32_t st_hash_buckets; /* Number of hash buckets. */ + u_int32_t st_pagesize; /* Assumed page size. */ + u_int32_t st_hash_searches; /* Total hash chain searches. */ + u_int32_t st_hash_longest; /* Longest hash chain searched. */ + uintmax_t st_hash_examined; /* Total hash entries searched. */ + uintmax_t st_hash_nowait; /* Hash lock granted with nowait. */ + uintmax_t st_hash_wait; /* Hash lock granted after wait. */ + uintmax_t st_hash_max_nowait; /* Max hash lock granted with nowait. */ + uintmax_t st_hash_max_wait; /* Max hash lock granted after wait. */ + uintmax_t st_region_nowait; /* Region lock granted with nowait. */ + uintmax_t st_region_wait; /* Region lock granted after wait. */ + uintmax_t st_mvcc_frozen; /* Buffers frozen. */ + uintmax_t st_mvcc_thawed; /* Buffers thawed. */ + uintmax_t st_mvcc_freed; /* Frozen buffers freed. */ + uintmax_t st_alloc; /* Number of page allocations. */ + uintmax_t st_alloc_buckets; /* Buckets checked during allocation. */ + uintmax_t st_alloc_max_buckets;/* Max checked during allocation. */ + uintmax_t st_alloc_pages; /* Pages checked during allocation. */ + uintmax_t st_alloc_max_pages; /* Max checked during allocation. */ + uintmax_t st_io_wait; /* Thread waited on buffer I/O. */ + uintmax_t st_sync_interrupted; /* Number of times sync interrupted. */ + roff_t st_regsize; /* Region size. */ +#endif +}; + +/* Mpool file statistics structure. */ +struct __db_mpool_fstat { + char *file_name; /* File name. */ + u_int32_t st_pagesize; /* Page size. */ +#ifndef __TEST_DB_NO_STATISTICS + u_int32_t st_map; /* Pages from mapped files. */ + uintmax_t st_cache_hit; /* Pages found in the cache. */ + uintmax_t st_cache_miss; /* Pages not found in the cache. */ + uintmax_t st_page_create; /* Pages created in the cache. */ + uintmax_t st_page_in; /* Pages read in. */ + uintmax_t st_page_out; /* Pages written out. */ +#endif +}; + +/******************************************************* + * Transactions and recovery. + *******************************************************/ +#define DB_TXNVERSION 1 + +typedef enum { + DB_TXN_ABORT=0, /* Public. */ + DB_TXN_APPLY=1, /* Public. */ + DB_TXN_BACKWARD_ROLL=3, /* Public. */ + DB_TXN_FORWARD_ROLL=4, /* Public. */ + DB_TXN_OPENFILES=5, /* Internal. */ + DB_TXN_POPENFILES=6, /* Internal. */ + DB_TXN_PRINT=7 /* Public. */ +} db_recops; + +/* + * BACKWARD_ALLOC is used during the forward pass to pick up any aborted + * allocations for files that were created during the forward pass. + * The main difference between _ALLOC and _ROLL is that the entry for + * the file not exist during the rollforward pass. + */ +#define DB_UNDO(op) ((op) == DB_TXN_ABORT || (op) == DB_TXN_BACKWARD_ROLL) +#define DB_REDO(op) ((op) == DB_TXN_FORWARD_ROLL || (op) == DB_TXN_APPLY) + +struct __db_txn { + DB_TXNMGR *mgrp; /* Pointer to transaction manager. */ + DB_TXN *parent; /* Pointer to transaction's parent. */ + DB_THREAD_INFO *thread_info; /* Pointer to thread information. */ + + u_int32_t txnid; /* Unique transaction id. */ + char *name; /* Transaction name. */ + DB_LOCKER *locker; /* Locker for this txn. */ + + void *td; /* Detail structure within region. */ + db_timeout_t lock_timeout; /* Timeout for locks for this txn. */ + db_timeout_t expire; /* Time transaction expires. */ + void *txn_list; /* Undo information for parent. */ + + /* + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_ENTRY(__db_txn) links; + */ + struct { + struct __db_txn *tqe_next; + struct __db_txn **tqe_prev; + } links; /* Links transactions off manager. */ + + /* + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_HEAD(__kids, __db_txn) kids; + */ + struct __kids { + struct __db_txn *tqh_first; + struct __db_txn **tqh_last; + } kids; + + /* + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_HEAD(__events, __txn_event) events; + */ + struct { + struct __txn_event *tqh_first; + struct __txn_event **tqh_last; + } events; /* Links deferred events. */ + + /* + * !!! + * Explicit representations of structures from queue.h. + * STAILQ_HEAD(__logrec, __txn_logrec) logs; + */ + struct { + struct __txn_logrec *stqh_first; + struct __txn_logrec **stqh_last; + } logs; /* Links in memory log records. */ + + /* + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_ENTRY(__db_txn) klinks; + */ + struct { + struct __db_txn *tqe_next; + struct __db_txn **tqe_prev; + } klinks; + + void *api_internal; /* C++ API private. */ + void *xml_internal; /* XML API private. */ + + u_int32_t cursors; /* Number of cursors open for txn */ + + /* DB_TXN PUBLIC HANDLE LIST BEGIN */ + int (*abort) __P((DB_TXN *)); + int (*commit) __P((DB_TXN *, u_int32_t)); + int (*discard) __P((DB_TXN *, u_int32_t)); + int (*get_name) __P((DB_TXN *, const char **)); + u_int32_t (*id) __P((DB_TXN *)); + int (*prepare) __P((DB_TXN *, u_int8_t *)); + int (*set_name) __P((DB_TXN *, const char *)); + int (*set_timeout) __P((DB_TXN *, db_timeout_t, u_int32_t)); + /* DB_TXN PUBLIC HANDLE LIST END */ + + /* DB_TXN PRIVATE HANDLE LIST BEGIN */ + void (*set_txn_lsnp) __P((DB_TXN *txn, DB_LSN **, DB_LSN **)); + /* DB_TXN PRIVATE HANDLE LIST END */ + +#define TXN_CHILDCOMMIT 0x0001 /* Txn has committed. */ +#define TXN_CDSGROUP 0x0002 /* CDS group handle. */ +#define TXN_COMPENSATE 0x0004 /* Compensating transaction. */ +#define TXN_DEADLOCK 0x0008 /* Txn has deadlocked. */ +#define TXN_LOCKTIMEOUT 0x0010 /* Txn has a lock timeout. */ +#define TXN_MALLOC 0x0020 /* Structure allocated by TXN system. */ +#define TXN_NOSYNC 0x0040 /* Do not sync on prepare and commit. */ +#define TXN_NOWAIT 0x0080 /* Do not wait on locks. */ +#define TXN_PRIVATE 0x0100 /* Txn owned by cursor.. */ +#define TXN_READ_COMMITTED 0x0200 /* Txn has degree 2 isolation. */ +#define TXN_READ_UNCOMMITTED 0x0400 /* Txn has degree 1 isolation. */ +#define TXN_RESTORED 0x0800 /* Txn has been restored. */ +#define TXN_SNAPSHOT 0x1000 /* Snapshot Isolation. */ +#define TXN_SYNC 0x2000 /* Write and sync on prepare/commit. */ +#define TXN_WRITE_NOSYNC 0x4000 /* Write only on prepare/commit. */ + u_int32_t flags; +}; + +#define TXN_SYNC_FLAGS (TXN_SYNC | TXN_NOSYNC | TXN_WRITE_NOSYNC) + +/* + * Structure used for two phase commit interface. + * We set the size of our global transaction id (gid) to be 128 in order + * to match that defined by the XA X/Open standard. + */ +#define DB_GID_SIZE 128 +struct __db_preplist { + DB_TXN *txn; + u_int8_t gid[DB_GID_SIZE]; +}; + +/* Transaction statistics structure. */ +struct __db_txn_active { + u_int32_t txnid; /* Transaction ID */ + u_int32_t parentid; /* Transaction ID of parent */ + pid_t pid; /* Process owning txn ID */ + db_threadid_t tid; /* Thread owning txn ID */ + + DB_LSN lsn; /* LSN when transaction began */ + + DB_LSN read_lsn; /* Read LSN for MVCC */ + u_int32_t mvcc_ref; /* MVCC reference count */ + +#define TXN_ABORTED 1 +#define TXN_COMMITTED 2 +#define TXN_PREPARED 3 +#define TXN_RUNNING 4 + u_int32_t status; /* Status of the transaction */ + + u_int8_t gid[DB_GID_SIZE]; /* Global transaction ID */ + char name[51]; /* 50 bytes of name, nul termination */ +}; + +struct __db_txn_stat { + u_int32_t st_nrestores; /* number of restored transactions + after recovery. */ +#ifndef __TEST_DB_NO_STATISTICS + DB_LSN st_last_ckp; /* lsn of the last checkpoint */ + time_t st_time_ckp; /* time of last checkpoint */ + u_int32_t st_last_txnid; /* last transaction id given out */ + u_int32_t st_maxtxns; /* maximum txns possible */ + uintmax_t st_naborts; /* number of aborted transactions */ + uintmax_t st_nbegins; /* number of begun transactions */ + uintmax_t st_ncommits; /* number of committed transactions */ + u_int32_t st_nactive; /* number of active transactions */ + u_int32_t st_nsnapshot; /* number of snapshot transactions */ + u_int32_t st_maxnactive; /* maximum active transactions */ + u_int32_t st_maxnsnapshot; /* maximum snapshot transactions */ + DB_TXN_ACTIVE *st_txnarray; /* array of active transactions */ + uintmax_t st_region_wait; /* Region lock granted after wait. */ + uintmax_t st_region_nowait; /* Region lock granted without wait. */ + roff_t st_regsize; /* Region size. */ +#endif +}; + +/******************************************************* + * Replication. + *******************************************************/ +/* Special, out-of-band environment IDs. */ +#define DB_EID_BROADCAST -1 +#define DB_EID_INVALID -2 + +#define DB_REP_DEFAULT_PRIORITY 100 + +/* Acknowledgement policies. */ +#define DB_REPMGR_ACKS_ALL 1 +#define DB_REPMGR_ACKS_ALL_PEERS 2 +#define DB_REPMGR_ACKS_NONE 3 +#define DB_REPMGR_ACKS_ONE 4 +#define DB_REPMGR_ACKS_ONE_PEER 5 +#define DB_REPMGR_ACKS_QUORUM 6 + +/* Replication timeout configuration values. */ +#define DB_REP_ACK_TIMEOUT 1 /* RepMgr acknowledgements. */ +#define DB_REP_CHECKPOINT_DELAY 2 /* Master checkpoint delay. */ +#define DB_REP_CONNECTION_RETRY 3 /* RepMgr connections. */ +#define DB_REP_ELECTION_RETRY 4 /* RepMgr elect retries. */ +#define DB_REP_ELECTION_TIMEOUT 5 /* Rep normal elections. */ +#define DB_REP_FULL_ELECTION_TIMEOUT 6 /* Rep full elections. */ +#define DB_REP_HEARTBEAT_MONITOR 7 /* RepMgr client HB monitor. */ +#define DB_REP_HEARTBEAT_SEND 8 /* RepMgr master send freq. */ +#define DB_REP_LEASE_TIMEOUT 9 /* Master leases. */ + +/* Event notification types. */ +#define DB_EVENT_NO_SUCH_EVENT 0 /* out-of-band sentinel value */ +#define DB_EVENT_PANIC 1 +#define DB_EVENT_REG_ALIVE 2 +#define DB_EVENT_REG_PANIC 3 +#define DB_EVENT_REP_CLIENT 4 +#define DB_EVENT_REP_ELECTED 5 +#define DB_EVENT_REP_MASTER 6 +#define DB_EVENT_REP_NEWMASTER 7 +#define DB_EVENT_REP_PERM_FAILED 8 +#define DB_EVENT_REP_STARTUPDONE 9 +#define DB_EVENT_WRITE_FAILED 10 + +/* Replication Manager site status. */ +struct __db_repmgr_site { + int eid; + char *host; + u_int port; + +#define DB_REPMGR_CONNECTED 0x01 +#define DB_REPMGR_DISCONNECTED 0x02 + u_int32_t status; +}; + +/* Replication statistics. */ +struct __db_rep_stat { + /* !!! + * Many replication statistics fields cannot be protected by a mutex + * without an unacceptable performance penalty, since most message + * processing is done without the need to hold a region-wide lock. + * Fields whose comments end with a '+' may be updated without holding + * the replication or log mutexes (as appropriate), and thus may be + * off somewhat (or, on unreasonable architectures under unlucky + * circumstances, garbaged). + */ + uintmax_t st_log_queued; /* Log records currently queued.+ */ + u_int32_t st_startup_complete; /* Site completed client sync-up. */ +#ifndef __TEST_DB_NO_STATISTICS + u_int32_t st_status; /* Current replication status. */ + DB_LSN st_next_lsn; /* Next LSN to use or expect. */ + DB_LSN st_waiting_lsn; /* LSN we're awaiting, if any. */ + DB_LSN st_max_perm_lsn; /* Maximum permanent LSN. */ + db_pgno_t st_next_pg; /* Next pg we expect. */ + db_pgno_t st_waiting_pg; /* pg we're awaiting, if any. */ + + u_int32_t st_dupmasters; /* # of times a duplicate master + condition was detected.+ */ + int st_env_id; /* Current environment ID. */ + u_int32_t st_env_priority; /* Current environment priority. */ + uintmax_t st_bulk_fills; /* Bulk buffer fills. */ + uintmax_t st_bulk_overflows; /* Bulk buffer overflows. */ + uintmax_t st_bulk_records; /* Bulk records stored. */ + uintmax_t st_bulk_transfers; /* Transfers of bulk buffers. */ + uintmax_t st_client_rerequests;/* Number of forced rerequests. */ + uintmax_t st_client_svc_req; /* Number of client service requests + received by this client. */ + uintmax_t st_client_svc_miss; /* Number of client service requests + missing on this client. */ + u_int32_t st_gen; /* Current generation number. */ + u_int32_t st_egen; /* Current election gen number. */ + uintmax_t st_log_duplicated; /* Log records received multiply.+ */ + uintmax_t st_log_queued_max; /* Max. log records queued at once.+ */ + uintmax_t st_log_queued_total; /* Total # of log recs. ever queued.+ */ + uintmax_t st_log_records; /* Log records received and put.+ */ + uintmax_t st_log_requested; /* Log recs. missed and requested.+ */ + int st_master; /* Env. ID of the current master. */ + uintmax_t st_master_changes; /* # of times we've switched masters. */ + uintmax_t st_msgs_badgen; /* Messages with a bad generation #.+ */ + uintmax_t st_msgs_processed; /* Messages received and processed.+ */ + uintmax_t st_msgs_recover; /* Messages ignored because this site + was a client in recovery.+ */ + uintmax_t st_msgs_send_failures;/* # of failed message sends.+ */ + uintmax_t st_msgs_sent; /* # of successful message sends.+ */ + uintmax_t st_newsites; /* # of NEWSITE msgs. received.+ */ + u_int32_t st_nsites; /* Current number of sites we will + assume during elections. */ + uintmax_t st_nthrottles; /* # of times we were throttled. */ + uintmax_t st_outdated; /* # of times we detected and returned + an OUTDATED condition.+ */ + uintmax_t st_pg_duplicated; /* Pages received multiply.+ */ + uintmax_t st_pg_records; /* Pages received and stored.+ */ + uintmax_t st_pg_requested; /* Pages missed and requested.+ */ + uintmax_t st_txns_applied; /* # of transactions applied.+ */ + uintmax_t st_startsync_delayed;/* # of STARTSYNC msgs delayed.+ */ + + /* Elections generally. */ + uintmax_t st_elections; /* # of elections held.+ */ + uintmax_t st_elections_won; /* # of elections won by this site.+ */ + + /* Statistics about an in-progress election. */ + int st_election_cur_winner; /* Current front-runner. */ + u_int32_t st_election_gen; /* Election generation number. */ + DB_LSN st_election_lsn; /* Max. LSN of current winner. */ + u_int32_t st_election_nsites; /* # of "registered voters". */ + u_int32_t st_election_nvotes; /* # of "registered voters" needed. */ + u_int32_t st_election_priority; /* Current election priority. */ + int st_election_status; /* Current election status. */ + u_int32_t st_election_tiebreaker;/* Election tiebreaker value. */ + u_int32_t st_election_votes; /* Votes received in this round. */ + u_int32_t st_election_sec; /* Last election time seconds. */ + u_int32_t st_election_usec; /* Last election time useconds. */ + u_int32_t st_max_lease_sec; /* Maximum lease timestamp seconds. */ + u_int32_t st_max_lease_usec; /* Maximum lease timestamp useconds. */ + + /* Undocumented statistics only used by the test system. */ +#ifdef CONFIG_TEST + u_int32_t st_filefail_cleanups; /* # of FILE_FAIL cleanups done. */ +#endif +#endif +}; + +/* Replication Manager statistics. */ +struct __db_repmgr_stat { + uintmax_t st_perm_failed; /* # of insufficiently ack'ed msgs. */ + uintmax_t st_msgs_queued; /* # msgs queued for network delay. */ + uintmax_t st_msgs_dropped; /* # msgs discarded due to excessive + queue length. */ + uintmax_t st_connection_drop; /* Existing connections dropped. */ + uintmax_t st_connect_fail; /* Failed new connection attempts. */ +}; + +/******************************************************* + * Sequences. + *******************************************************/ +/* + * The storage record for a sequence. + */ +struct __db_seq_record { + u_int32_t seq_version; /* Version size/number. */ + u_int32_t flags; /* DB_SEQ_XXX Flags. */ + db_seq_t seq_value; /* Current value. */ + db_seq_t seq_max; /* Max permitted. */ + db_seq_t seq_min; /* Min permitted. */ +}; + +/* + * Handle for a sequence object. + */ +struct __db_sequence { + DB *seq_dbp; /* DB handle for this sequence. */ + db_mutex_t mtx_seq; /* Mutex if sequence is threaded. */ + DB_SEQ_RECORD *seq_rp; /* Pointer to current data. */ + DB_SEQ_RECORD seq_record; /* Data from DB_SEQUENCE. */ + int32_t seq_cache_size; /* Number of values cached. */ + db_seq_t seq_last_value; /* Last value cached. */ + DBT seq_key; /* DBT pointing to sequence key. */ + DBT seq_data; /* DBT pointing to seq_record. */ + + /* API-private structure: used by C++ and Java. */ + void *api_internal; + + /* DB_SEQUENCE PUBLIC HANDLE LIST BEGIN */ + int (*close) __P((DB_SEQUENCE *, u_int32_t)); + int (*get) __P((DB_SEQUENCE *, + DB_TXN *, int32_t, db_seq_t *, u_int32_t)); + int (*get_cachesize) __P((DB_SEQUENCE *, int32_t *)); + int (*get_db) __P((DB_SEQUENCE *, DB **)); + int (*get_flags) __P((DB_SEQUENCE *, u_int32_t *)); + int (*get_key) __P((DB_SEQUENCE *, DBT *)); + int (*get_range) __P((DB_SEQUENCE *, + db_seq_t *, db_seq_t *)); + int (*initial_value) __P((DB_SEQUENCE *, db_seq_t)); + int (*open) __P((DB_SEQUENCE *, + DB_TXN *, DBT *, u_int32_t)); + int (*remove) __P((DB_SEQUENCE *, DB_TXN *, u_int32_t)); + int (*set_cachesize) __P((DB_SEQUENCE *, int32_t)); + int (*set_flags) __P((DB_SEQUENCE *, u_int32_t)); + int (*set_range) __P((DB_SEQUENCE *, db_seq_t, db_seq_t)); + int (*stat) __P((DB_SEQUENCE *, + DB_SEQUENCE_STAT **, u_int32_t)); + int (*stat_print) __P((DB_SEQUENCE *, u_int32_t)); + /* DB_SEQUENCE PUBLIC HANDLE LIST END */ +}; + +struct __db_seq_stat { + uintmax_t st_wait; /* Sequence lock granted w/o wait. */ + uintmax_t st_nowait; /* Sequence lock granted after wait. */ + db_seq_t st_current; /* Current value in db. */ + db_seq_t st_value; /* Current cached value. */ + db_seq_t st_last_value; /* Last cached value. */ + db_seq_t st_min; /* Minimum value. */ + db_seq_t st_max; /* Maximum value. */ + int32_t st_cache_size; /* Cache size. */ + u_int32_t st_flags; /* Flag value. */ +}; + +/******************************************************* + * Access methods. + *******************************************************/ +typedef enum { + DB_BTREE=1, + DB_HASH=2, + DB_RECNO=3, + DB_QUEUE=4, + DB_UNKNOWN=5 /* Figure it out on open. */ +} DBTYPE; + +#define DB_RENAMEMAGIC 0x030800 /* File has been renamed. */ + +#define DB_BTREEVERSION 9 /* Current btree version. */ +#define DB_BTREEOLDVER 8 /* Oldest btree version supported. */ +#define DB_BTREEMAGIC 0x053162 + +#define DB_HASHVERSION 9 /* Current hash version. */ +#define DB_HASHOLDVER 7 /* Oldest hash version supported. */ +#define DB_HASHMAGIC 0x061561 + +#define DB_QAMVERSION 4 /* Current queue version. */ +#define DB_QAMOLDVER 3 /* Oldest queue version supported. */ +#define DB_QAMMAGIC 0x042253 + +#define DB_SEQUENCE_VERSION 2 /* Current sequence version. */ +#define DB_SEQUENCE_OLDVER 1 /* Oldest sequence version supported. */ + +/* + * DB access method and cursor operation values. Each value is an operation + * code to which additional bit flags are added. + */ +#define DB_AFTER 1 /* Dbc.put */ +#define DB_APPEND 2 /* Db.put */ +#define DB_BEFORE 3 /* Dbc.put */ +#define DB_CONSUME 4 /* Db.get */ +#define DB_CONSUME_WAIT 5 /* Db.get */ +#define DB_CURRENT 6 /* Dbc.get, Dbc.put, DbLogc.get */ +#define DB_FIRST 7 /* Dbc.get, DbLogc->get */ +#define DB_GET_BOTH 8 /* Db.get, Dbc.get */ +#define DB_GET_BOTHC 9 /* Dbc.get (internal) */ +#define DB_GET_BOTH_RANGE 10 /* Db.get, Dbc.get */ +#define DB_GET_RECNO 11 /* Dbc.get */ +#define DB_JOIN_ITEM 12 /* Dbc.get; don't do primary lookup */ +#define DB_KEYFIRST 13 /* Dbc.put */ +#define DB_KEYLAST 14 /* Dbc.put */ +#define DB_LAST 15 /* Dbc.get, DbLogc->get */ +#define DB_NEXT 16 /* Dbc.get, DbLogc->get */ +#define DB_NEXT_DUP 17 /* Dbc.get */ +#define DB_NEXT_NODUP 18 /* Dbc.get */ +#define DB_NODUPDATA 19 /* Db.put, Dbc.put */ +#define DB_NOOVERWRITE 20 /* Db.put */ +#define DB_NOSYNC 21 /* Db.close */ +#define DB_OVERWRITE_DUP 22 /* Dbc.put, Db.put; no DB_KEYEXIST */ +#define DB_POSITION 23 /* Dbc.dup */ +#define DB_PREV 24 /* Dbc.get, DbLogc->get */ +#define DB_PREV_DUP 25 /* Dbc.get */ +#define DB_PREV_NODUP 26 /* Dbc.get */ +#define DB_SET 27 /* Dbc.get, DbLogc->get */ +#define DB_SET_RANGE 28 /* Dbc.get */ +#define DB_SET_RECNO 29 /* Db.get, Dbc.get */ +#define DB_UPDATE_SECONDARY 30 /* Dbc.get, Dbc.del (internal) */ +#define DB_SET_LTE 31 /* Dbc.get (internal) */ +#define DB_GET_BOTH_LTE 32 /* Dbc.get (internal) */ + +/* This has to change when the max opcode hits 255. */ +#define DB_OPFLAGS_MASK 0x000000ff /* Mask for operations flags. */ + +/* + * DB (user visible) error return codes. + * + * !!! + * We don't want our error returns to conflict with other packages where + * possible, so pick a base error value that's hopefully not common. We + * document that we own the error name space from -30,800 to -30,999. + */ +/* DB (public) error return codes. */ +#define DB_BUFFER_SMALL (-30999)/* User memory too small for return. */ +#define DB_DONOTINDEX (-30998)/* "Null" return from 2ndary callbk. */ +#define DB_FOREIGN_CONFLICT (-30997)/* A foreign db constraint triggered. */ +#define DB_KEYEMPTY (-30996)/* Key/data deleted or never created. */ +#define DB_KEYEXIST (-30995)/* The key/data pair already exists. */ +#define DB_LOCK_DEADLOCK (-30994)/* Deadlock. */ +#define DB_LOCK_NOTGRANTED (-30993)/* Lock unavailable. */ +#define DB_LOG_BUFFER_FULL (-30992)/* In-memory log buffer full. */ +#define DB_NOSERVER (-30991)/* Server panic return. */ +#define DB_NOSERVER_HOME (-30990)/* Bad home sent to server. */ +#define DB_NOSERVER_ID (-30989)/* Bad ID sent to server. */ +#define DB_NOTFOUND (-30988)/* Key/data pair not found (EOF). */ +#define DB_OLD_VERSION (-30987)/* Out-of-date version. */ +#define DB_PAGE_NOTFOUND (-30986)/* Requested page not found. */ +#define DB_REP_DUPMASTER (-30985)/* There are two masters. */ +#define DB_REP_HANDLE_DEAD (-30984)/* Rolled back a commit. */ +#define DB_REP_HOLDELECTION (-30983)/* Time to hold an election. */ +#define DB_REP_IGNORE (-30982)/* This msg should be ignored.*/ +#define DB_REP_ISPERM (-30981)/* Cached not written perm written.*/ +#define DB_REP_JOIN_FAILURE (-30980)/* Unable to join replication group. */ +#define DB_REP_LEASE_EXPIRED (-30979)/* Master lease has expired. */ +#define DB_REP_LOCKOUT (-30978)/* API/Replication lockout now. */ +#define DB_REP_NEWSITE (-30977)/* New site entered system. */ +#define DB_REP_NOTPERM (-30976)/* Permanent log record not written. */ +#define DB_REP_UNAVAIL (-30975)/* Site cannot currently be reached. */ +#define DB_RUNRECOVERY (-30974)/* Panic return. */ +#define DB_SECONDARY_BAD (-30973)/* Secondary index corrupt. */ +#define DB_VERIFY_BAD (-30972)/* Verify failed; bad format. */ +#define DB_VERSION_MISMATCH (-30971)/* Environment version mismatch. */ + +/* DB (private) error return codes. */ +#define DB_ALREADY_ABORTED (-30899) +#define DB_DELETED (-30898)/* Recovery file marked deleted. */ +#define DB_EVENT_NOT_HANDLED (-30897)/* Forward event to application. */ +#define DB_NEEDSPLIT (-30896)/* Page needs to be split. */ +#define DB_REP_BULKOVF (-30895)/* Rep bulk buffer overflow. */ +#define DB_REP_EGENCHG (-30894)/* Egen changed while in election. */ +#define DB_REP_LOGREADY (-30893)/* Rep log ready for recovery. */ +#define DB_REP_NEWMASTER (-30892)/* We have learned of a new master. */ +#define DB_REP_PAGEDONE (-30891)/* This page was already done. */ +#define DB_REP_PAGELOCKED (-30890)/* Page we want is locked. */ +#define DB_SURPRISE_KID (-30889)/* Child commit where parent + didn't know it was a parent. */ +#define DB_SWAPBYTES (-30888)/* Database needs byte swapping. */ +#define DB_TIMEOUT (-30887)/* Timed out waiting for election. */ +#define DB_TXN_CKP (-30886)/* Encountered ckp record in log. */ +#define DB_VERIFY_FATAL (-30885)/* DB->verify cannot proceed. */ + +/* Database handle. */ +struct __db { + /******************************************************* + * Public: owned by the application. + *******************************************************/ + u_int32_t pgsize; /* Database logical page size. */ + DB_CACHE_PRIORITY priority; /* Database priority in cache. */ + + /* Callbacks. */ + int (*db_append_recno) __P((DB *, DBT *, db_recno_t)); + void (*db_feedback) __P((DB *, int, int)); + int (*dup_compare) __P((DB *, const DBT *, const DBT *)); + + void *app_private; /* Application-private handle. */ + + /******************************************************* + * Private: owned by DB. + *******************************************************/ + DB_ENV *dbenv; /* Backing public environment. */ + ENV *env; /* Backing private environment. */ + + DBTYPE type; /* DB access method type. */ + + DB_MPOOLFILE *mpf; /* Backing buffer pool. */ + + db_mutex_t mutex; /* Synchronization for free threading */ + + char *fname, *dname; /* File/database passed to DB->open. */ + const char *dirname; /* Direcory of DB file. */ + u_int32_t open_flags; /* Flags passed to DB->open. */ + + u_int8_t fileid[DB_FILE_ID_LEN];/* File's unique ID for locking. */ + + u_int32_t adj_fileid; /* File's unique ID for curs. adj. */ + +#define DB_LOGFILEID_INVALID -1 + FNAME *log_filename; /* File's naming info for logging. */ + + db_pgno_t meta_pgno; /* Meta page number */ + DB_LOCKER *locker; /* Locker for handle locking. */ + DB_LOCKER *cur_locker; /* Current handle lock holder. */ + DB_TXN *cur_txn; /* Opening transaction. */ + DB_LOCKER *associate_locker; /* Locker for DB->associate call. */ + DB_LOCK handle_lock; /* Lock held on this handle. */ + + u_int cl_id; /* RPC: remote client id. */ + + time_t timestamp; /* Handle timestamp for replication. */ + u_int32_t fid_gen; /* Rep generation number for fids. */ + + /* + * Returned data memory for DB->get() and friends. + */ + DBT my_rskey; /* Secondary key. */ + DBT my_rkey; /* [Primary] key. */ + DBT my_rdata; /* Data. */ + + /* + * !!! + * Some applications use DB but implement their own locking outside of + * DB. If they're using fcntl(2) locking on the underlying database + * file, and we open and close a file descriptor for that file, we will + * discard their locks. The DB_FCNTL_LOCKING flag to DB->open is an + * undocumented interface to support this usage which leaves any file + * descriptors we open until DB->close. This will only work with the + * DB->open interface and simple caches, e.g., creating a transaction + * thread may open/close file descriptors this flag doesn't protect. + * Locking with fcntl(2) on a file that you don't own is a very, very + * unsafe thing to do. 'Nuff said. + */ + DB_FH *saved_open_fhp; /* Saved file handle. */ + + /* + * Linked list of DBP's, linked from the ENV, used to keep track + * of all open db handles for cursor adjustment. + * + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_ENTRY(__db) dblistlinks; + */ + struct { + struct __db *tqe_next; + struct __db **tqe_prev; + } dblistlinks; + + /* + * Cursor queues. + * + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_HEAD(__cq_fq, __dbc) free_queue; + * TAILQ_HEAD(__cq_aq, __dbc) active_queue; + * TAILQ_HEAD(__cq_jq, __dbc) join_queue; + */ + struct __cq_fq { + struct __dbc *tqh_first; + struct __dbc **tqh_last; + } free_queue; + struct __cq_aq { + struct __dbc *tqh_first; + struct __dbc **tqh_last; + } active_queue; + struct __cq_jq { + struct __dbc *tqh_first; + struct __dbc **tqh_last; + } join_queue; + + /* + * Secondary index support. + * + * Linked list of secondary indices -- set in the primary. + * + * !!! + * Explicit representations of structures from queue.h. + * LIST_HEAD(s_secondaries, __db); + */ + struct { + struct __db *lh_first; + } s_secondaries; + + /* + * List entries for secondaries, and reference count of how many + * threads are updating this secondary (see Dbc.put). + * + * !!! + * Note that these are synchronized by the primary's mutex, but + * filled in in the secondaries. + * + * !!! + * Explicit representations of structures from queue.h. + * LIST_ENTRY(__db) s_links; + */ + struct { + struct __db *le_next; + struct __db **le_prev; + } s_links; + u_int32_t s_refcnt; + + /* Secondary callback and free functions -- set in the secondary. */ + int (*s_callback) __P((DB *, const DBT *, const DBT *, DBT *)); + + /* Reference to primary -- set in the secondary. */ + DB *s_primary; + +#define DB_ASSOC_IMMUTABLE_KEY 0x00000001 /* Secondary key is immutable. */ + + /* Flags passed to associate -- set in the secondary. */ + u_int32_t s_assoc_flags; + + /* + * Foreign key support. + * + * Linked list of primary dbs -- set in the foreign db + * + * !!! + * Explicit representations of structures from queue.h. + * LIST_HEAD(f_primaries, __db); + */ + struct { + struct __db_foreign_info *lh_first; + } f_primaries; + + /* Reference to foreign -- set in the secondary. */ + DB *s_foreign; + + /* API-private structure: used by DB 1.85, C++, Java, Perl and Tcl */ + void *api_internal; + + /* Subsystem-private structure. */ + void *bt_internal; /* Btree/Recno access method. */ + void *h_internal; /* Hash access method. */ + void *p_internal; /* Partition informaiton. */ + void *q_internal; /* Queue access method. */ + + /* DB PUBLIC HANDLE LIST BEGIN */ + int (*associate) __P((DB *, DB_TXN *, DB *, + int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); + int (*associate_foreign) __P((DB *, DB *, + int (*)(DB *, const DBT *, DBT *, const DBT *, int *), + u_int32_t)); + int (*close) __P((DB *, u_int32_t)); + int (*compact) __P((DB *, + DB_TXN *, DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *)); + int (*cursor) __P((DB *, DB_TXN *, DBC **, u_int32_t)); + int (*del) __P((DB *, DB_TXN *, DBT *, u_int32_t)); + void (*err) __P((DB *, int, const char *, ...)); + void (*errx) __P((DB *, const char *, ...)); + int (*exists) __P((DB *, DB_TXN *, DBT *, u_int32_t)); + int (*fd) __P((DB *, int *)); + int (*get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); + int (*get_alloc) __P((DB *, void *(**)(size_t), + void *(**)(void *, size_t), void (**)(void *))); + int (*get_append_recno) __P((DB *, int (**)(DB *, DBT *, db_recno_t))); + int (*get_bt_compare) + __P((DB *, int (**)(DB *, const DBT *, const DBT *))); + int (*get_bt_compress) __P((DB *, + int (**)(DB *, + const DBT *, const DBT *, const DBT *, const DBT *, DBT *), + int (**)(DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *))); + int (*get_bt_minkey) __P((DB *, u_int32_t *)); + int (*get_bt_prefix) + __P((DB *, size_t (**)(DB *, const DBT *, const DBT *))); + int (*get_byteswapped) __P((DB *, int *)); + int (*get_cachesize) __P((DB *, u_int32_t *, u_int32_t *, int *)); + int (*get_create_dir) __P((DB *, const char **)); + int (*get_dbname) __P((DB *, const char **, const char **)); + int (*get_dup_compare) + __P((DB *, int (**)(DB *, const DBT *, const DBT *))); + int (*get_encrypt_flags) __P((DB *, u_int32_t *)); + DB_ENV *(*get_env) __P((DB *)); + void (*get_errcall) __P((DB *, + void (**)(const DB_ENV *, const char *, const char *))); + void (*get_errfile) __P((DB *, FILE **)); + void (*get_errpfx) __P((DB *, const char **)); + int (*get_feedback) __P((DB *, void (**)(DB *, int, int))); + int (*get_flags) __P((DB *, u_int32_t *)); + int (*get_h_compare) + __P((DB *, int (**)(DB *, const DBT *, const DBT *))); + int (*get_h_ffactor) __P((DB *, u_int32_t *)); + int (*get_h_hash) + __P((DB *, u_int32_t (**)(DB *, const void *, u_int32_t))); + int (*get_h_nelem) __P((DB *, u_int32_t *)); + int (*get_lorder) __P((DB *, int *)); + DB_MPOOLFILE *(*get_mpf) __P((DB *)); + void (*get_msgcall) __P((DB *, + void (**)(const DB_ENV *, const char *))); + void (*get_msgfile) __P((DB *, FILE **)); + int (*get_multiple) __P((DB *)); + int (*get_open_flags) __P((DB *, u_int32_t *)); + int (*get_pagesize) __P((DB *, u_int32_t *)); + int (*get_partition_callback) __P((DB *, + u_int32_t *, u_int32_t (**)(DB *, DBT *key))); + int (*get_partition_dirs) __P((DB *, const char ***)); + int (*get_partition_keys) __P((DB *, u_int32_t *, DBT **)); + int (*get_priority) __P((DB *, DB_CACHE_PRIORITY *)); + int (*get_q_extentsize) __P((DB *, u_int32_t *)); + int (*get_re_delim) __P((DB *, int *)); + int (*get_re_len) __P((DB *, u_int32_t *)); + int (*get_re_pad) __P((DB *, int *)); + int (*get_re_source) __P((DB *, const char **)); + int (*get_transactional) __P((DB *)); + int (*get_type) __P((DB *, DBTYPE *)); + int (*join) __P((DB *, DBC **, DBC **, u_int32_t)); + int (*key_range) + __P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t)); + int (*open) __P((DB *, + DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int)); + int (*pget) __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t)); + int (*put) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); + int (*remove) __P((DB *, const char *, const char *, u_int32_t)); + int (*rename) __P((DB *, + const char *, const char *, const char *, u_int32_t)); + int (*set_alloc) __P((DB *, void *(*)(size_t), + void *(*)(void *, size_t), void (*)(void *))); + int (*set_append_recno) __P((DB *, int (*)(DB *, DBT *, db_recno_t))); + int (*set_bt_compare) + __P((DB *, int (*)(DB *, const DBT *, const DBT *))); + int (*set_bt_compress) __P((DB *, + int (*)(DB *, const DBT *, const DBT *, const DBT *, const DBT *, DBT *), + int (*)(DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *))); + int (*set_bt_minkey) __P((DB *, u_int32_t)); + int (*set_bt_prefix) + __P((DB *, size_t (*)(DB *, const DBT *, const DBT *))); + int (*set_cachesize) __P((DB *, u_int32_t, u_int32_t, int)); + int (*set_create_dir) __P((DB *, const char *)); + int (*set_dup_compare) + __P((DB *, int (*)(DB *, const DBT *, const DBT *))); + int (*set_encrypt) __P((DB *, const char *, u_int32_t)); + void (*set_errcall) __P((DB *, + void (*)(const DB_ENV *, const char *, const char *))); + void (*set_errfile) __P((DB *, FILE *)); + void (*set_errpfx) __P((DB *, const char *)); + int (*set_feedback) __P((DB *, void (*)(DB *, int, int))); + int (*set_flags) __P((DB *, u_int32_t)); + int (*set_h_compare) + __P((DB *, int (*)(DB *, const DBT *, const DBT *))); + int (*set_h_ffactor) __P((DB *, u_int32_t)); + int (*set_h_hash) + __P((DB *, u_int32_t (*)(DB *, const void *, u_int32_t))); + int (*set_h_nelem) __P((DB *, u_int32_t)); + int (*set_lorder) __P((DB *, int)); + void (*set_msgcall) __P((DB *, void (*)(const DB_ENV *, const char *))); + void (*set_msgfile) __P((DB *, FILE *)); + int (*set_pagesize) __P((DB *, u_int32_t)); + int (*set_paniccall) __P((DB *, void (*)(DB_ENV *, int))); + int (*set_partition) __P((DB *, + u_int32_t, DBT *, u_int32_t (*)(DB *, DBT *key))); + int (*set_partition_dirs) __P((DB *, const char **)); + int (*set_priority) __P((DB *, DB_CACHE_PRIORITY)); + int (*set_q_extentsize) __P((DB *, u_int32_t)); + int (*set_re_delim) __P((DB *, int)); + int (*set_re_len) __P((DB *, u_int32_t)); + int (*set_re_pad) __P((DB *, int)); + int (*set_re_source) __P((DB *, const char *)); + int (*sort_multiple) __P((DB *, DBT *, DBT *, u_int32_t)); + int (*stat) __P((DB *, DB_TXN *, void *, u_int32_t)); + int (*stat_print) __P((DB *, u_int32_t)); + int (*sync) __P((DB *, u_int32_t)); + int (*truncate) __P((DB *, DB_TXN *, u_int32_t *, u_int32_t)); + int (*upgrade) __P((DB *, const char *, u_int32_t)); + int (*verify) + __P((DB *, const char *, const char *, FILE *, u_int32_t)); + /* DB PUBLIC HANDLE LIST END */ + + /* DB PRIVATE HANDLE LIST BEGIN */ + int (*dump) __P((DB *, const char *, + int (*)(void *, const void *), void *, int, int)); + int (*db_am_remove) __P((DB *, DB_THREAD_INFO *, + DB_TXN *, const char *, const char *, u_int32_t)); + int (*db_am_rename) __P((DB *, DB_THREAD_INFO *, + DB_TXN *, const char *, const char *, const char *)); + /* DB PRIVATE HANDLE LIST END */ + + /* + * Never called; these are a place to save function pointers + * so that we can undo an associate. + */ + int (*stored_get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); + int (*stored_close) __P((DB *, u_int32_t)); + +#define DB_OK_BTREE 0x01 +#define DB_OK_HASH 0x02 +#define DB_OK_QUEUE 0x04 +#define DB_OK_RECNO 0x08 + u_int32_t am_ok; /* Legal AM choices. */ + + /* + * This field really ought to be an AM_FLAG, but we have + * have run out of bits. If/when we decide to split up + * the flags, we can incorporate it. + */ + int preserve_fid; /* Do not free fileid on close. */ + +#define DB_AM_CHKSUM 0x00000001 /* Checksumming */ +#define DB_AM_COMPENSATE 0x00000002 /* Created by compensating txn */ +#define DB_AM_COMPRESS 0x00000004 /* Compressed BTree */ +#define DB_AM_CREATED 0x00000008 /* Database was created upon open */ +#define DB_AM_CREATED_MSTR 0x00000010 /* Encompassing file was created */ +#define DB_AM_DBM_ERROR 0x00000020 /* Error in DBM/NDBM database */ +#define DB_AM_DELIMITER 0x00000040 /* Variable length delimiter set */ +#define DB_AM_DISCARD 0x00000080 /* Discard any cached pages */ +#define DB_AM_DUP 0x00000100 /* DB_DUP */ +#define DB_AM_DUPSORT 0x00000200 /* DB_DUPSORT */ +#define DB_AM_ENCRYPT 0x00000400 /* Encryption */ +#define DB_AM_FIXEDLEN 0x00000800 /* Fixed-length records */ +#define DB_AM_INMEM 0x00001000 /* In-memory; no sync on close */ +#define DB_AM_INORDER 0x00002000 /* DB_INORDER */ +#define DB_AM_IN_RENAME 0x00004000 /* File is being renamed */ +#define DB_AM_NOT_DURABLE 0x00008000 /* Do not log changes */ +#define DB_AM_OPEN_CALLED 0x00010000 /* DB->open called */ +#define DB_AM_PAD 0x00020000 /* Fixed-length record pad */ +#define DB_AM_PGDEF 0x00040000 /* Page size was defaulted */ +#define DB_AM_RDONLY 0x00080000 /* Database is readonly */ +#define DB_AM_READ_UNCOMMITTED 0x00100000 /* Support degree 1 isolation */ +#define DB_AM_RECNUM 0x00200000 /* DB_RECNUM */ +#define DB_AM_RECOVER 0x00400000 /* DB opened by recovery routine */ +#define DB_AM_RENUMBER 0x00800000 /* DB_RENUMBER */ +#define DB_AM_REVSPLITOFF 0x01000000 /* DB_REVSPLITOFF */ +#define DB_AM_SECONDARY 0x02000000 /* Database is a secondary index */ +#define DB_AM_SNAPSHOT 0x04000000 /* DB_SNAPSHOT */ +#define DB_AM_SUBDB 0x08000000 /* Subdatabases supported */ +#define DB_AM_SWAP 0x10000000 /* Pages need to be byte-swapped */ +#define DB_AM_TXN 0x20000000 /* Opened in a transaction */ +#define DB_AM_VERIFYING 0x40000000 /* DB handle is in the verifier */ + u_int32_t orig_flags; /* Flags at open, for refresh */ + u_int32_t flags; +}; + +/* + * Macros for bulk operations. These are only intended for the C API. + * For C++, use DbMultiple*Iterator or DbMultiple*Builder. + * + * Bulk operations store multiple entries into a single DBT structure. The + * following macros assist with creating and reading these Multiple DBTs. + * + * The basic layout for single data items is: + * + * ------------------------------------------------------------------------- + * | data1 | ... | dataN | ..... |-1 | dNLen | dNOff | ... | d1Len | d1Off | + * ------------------------------------------------------------------------- + * + * For the DB_MULTIPLE_KEY* macros, the items are in key/data pairs, so data1 + * would be a key, and data2 its corresponding value (N is always even). + * + * For the DB_MULTIPLE_RECNO* macros, the record number is stored along with + * the len/off pair in the "header" section, and the list is zero terminated + * (since -1 is a valid record number): + * + * -------------------------------------------------------------------------- + * | d1 |..| dN |..| 0 | dNLen | dNOff | recnoN |..| d1Len | d1Off | recno1 | + * -------------------------------------------------------------------------- + */ +#define DB_MULTIPLE_INIT(pointer, dbt) \ + (pointer = (u_int8_t *)(dbt)->data + \ + (dbt)->ulen - sizeof(u_int32_t)) + +#define DB_MULTIPLE_NEXT(pointer, dbt, retdata, retdlen) \ + do { \ + u_int32_t *__p = (u_int32_t *)(pointer); \ + if (*__p == (u_int32_t)-1) { \ + retdata = NULL; \ + pointer = NULL; \ + break; \ + } \ + retdata = (u_int8_t *)(dbt)->data + *__p--; \ + retdlen = *__p--; \ + pointer = __p; \ + if (retdlen == 0 && retdata == (u_int8_t *)(dbt)->data) \ + retdata = NULL; \ + } while (0) + +#define DB_MULTIPLE_KEY_NEXT(pointer, dbt, retkey, retklen, retdata, retdlen) \ + do { \ + u_int32_t *__p = (u_int32_t *)(pointer); \ + if (*__p == (u_int32_t)-1) { \ + retdata = NULL; \ + retkey = NULL; \ + pointer = NULL; \ + break; \ + } \ + retkey = (u_int8_t *)(dbt)->data + *__p--; \ + retklen = *__p--; \ + retdata = (u_int8_t *)(dbt)->data + *__p--; \ + retdlen = *__p--; \ + pointer = __p; \ + } while (0) + +#define DB_MULTIPLE_RECNO_NEXT(pointer, dbt, recno, retdata, retdlen) \ + do { \ + u_int32_t *__p = (u_int32_t *)(pointer); \ + if (*__p == (u_int32_t)0) { \ + recno = 0; \ + retdata = NULL; \ + pointer = NULL; \ + break; \ + } \ + recno = *__p--; \ + retdata = (u_int8_t *)(dbt)->data + *__p--; \ + retdlen = *__p--; \ + pointer = __p; \ + } while (0) + +#define DB_MULTIPLE_WRITE_INIT(pointer, dbt) \ + do { \ + (dbt)->flags |= DB_DBT_BULK; \ + pointer = (u_int8_t *)(dbt)->data + \ + (dbt)->ulen - sizeof(u_int32_t); \ + *(u_int32_t *)(pointer) = (u_int32_t)-1; \ + } while (0) + +#define DB_MULTIPLE_RESERVE_NEXT(pointer, dbt, writedata, writedlen) \ + do { \ + u_int32_t *__p = (u_int32_t *)(pointer); \ + u_int32_t __off = ((pointer) == (u_int8_t *)(dbt)->data +\ + (dbt)->ulen - sizeof(u_int32_t)) ? 0 : __p[1] + __p[2];\ + if ((u_int8_t *)(dbt)->data + __off + (writedlen) > \ + (u_int8_t *)(__p - 2)) \ + writedata = NULL; \ + else { \ + writedata = (u_int8_t *)(dbt)->data + __off; \ + __p[0] = __off; \ + __p[-1] = (writedlen); \ + __p[-2] = (u_int32_t)-1; \ + pointer = __p - 2; \ + } \ + } while (0) + +#define DB_MULTIPLE_WRITE_NEXT(pointer, dbt, writedata, writedlen) \ + do { \ + void *__destd; \ + DB_MULTIPLE_RESERVE_NEXT((pointer), (dbt), \ + __destd, (writedlen)); \ + if (__destd == NULL) \ + pointer = NULL; \ + else \ + memcpy(__destd, (writedata), (writedlen)); \ + } while (0) + +#define DB_MULTIPLE_KEY_RESERVE_NEXT(pointer, dbt, writekey, writeklen, writedata, writedlen) \ + do { \ + u_int32_t *__p = (u_int32_t *)(pointer); \ + u_int32_t __off = ((pointer) == (u_int8_t *)(dbt)->data +\ + (dbt)->ulen - sizeof(u_int32_t)) ? 0 : __p[1] + __p[2];\ + if ((u_int8_t *)(dbt)->data + __off + (writeklen) + \ + (writedlen) > (u_int8_t *)(__p - 4)) { \ + writekey = NULL; \ + writedata = NULL; \ + } else { \ + writekey = (u_int8_t *)(dbt)->data + __off; \ + __p[0] = __off; \ + __p[-1] = (writeklen); \ + __p -= 2; \ + __off += (writeklen); \ + writedata = (u_int8_t *)(dbt)->data + __off; \ + __p[0] = __off; \ + __p[-1] = (writedlen); \ + __p[-2] = (u_int32_t)-1; \ + pointer = __p - 2; \ + } \ + } while (0) + +#define DB_MULTIPLE_KEY_WRITE_NEXT(pointer, dbt, writekey, writeklen, writedata, writedlen) \ + do { \ + void *__destk, *__destd; \ + DB_MULTIPLE_KEY_RESERVE_NEXT((pointer), (dbt), \ + __destk, (writeklen), __destd, (writedlen)); \ + if (__destk == NULL) \ + pointer = NULL; \ + else { \ + memcpy(__destk, (writekey), (writeklen)); \ + if (__destd != NULL) \ + memcpy(__destd, (writedata), (writedlen));\ + } \ + } while (0) + +#define DB_MULTIPLE_RECNO_WRITE_INIT(pointer, dbt) \ + do { \ + (dbt)->flags |= DB_DBT_BULK; \ + pointer = (u_int8_t *)(dbt)->data + \ + (dbt)->ulen - sizeof(u_int32_t); \ + *(u_int32_t *)(pointer) = 0; \ + } while (0) + +#define DB_MULTIPLE_RECNO_RESERVE_NEXT(pointer, dbt, recno, writedata, writedlen) \ + do { \ + u_int32_t *__p = (u_int32_t *)(pointer); \ + u_int32_t __off = ((pointer) == (u_int8_t *)(dbt)->data +\ + (dbt)->ulen - sizeof(u_int32_t)) ? 0 : __p[1] + __p[2]; \ + if (((u_int8_t *)(dbt)->data + __off) + (writedlen) > \ + (u_int8_t *)(__p - 3)) \ + writedata = NULL; \ + else { \ + writedata = (u_int8_t *)(dbt)->data + __off; \ + __p[0] = (u_int32_t)(recno); \ + __p[-1] = __off; \ + __p[-2] = (writedlen); \ + __p[-3] = 0; \ + pointer = __p - 3; \ + } \ + } while (0) + +#define DB_MULTIPLE_RECNO_WRITE_NEXT(pointer, dbt, recno, writedata, writedlen)\ + do { \ + void *__destd; \ + DB_MULTIPLE_RECNO_RESERVE_NEXT((pointer), (dbt), \ + (recno), __destd, (writedlen)); \ + if (__destd == NULL) \ + pointer = NULL; \ + else if ((writedlen) != 0) \ + memcpy(__destd, (writedata), (writedlen)); \ + } while (0) + +/******************************************************* + * Access method cursors. + *******************************************************/ +struct __dbc { + DB *dbp; /* Backing database */ + DB_ENV *dbenv; /* Backing environment */ + ENV *env; /* Backing environment */ + + DB_THREAD_INFO *thread_info; /* Thread that owns this cursor. */ + DB_TXN *txn; /* Associated transaction. */ + DB_CACHE_PRIORITY priority; /* Priority in cache. */ + + /* + * Active/free cursor queues. + * + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_ENTRY(__dbc) links; + */ + struct { + DBC *tqe_next; + DBC **tqe_prev; + } links; + + /* + * The DBT *'s below are used by the cursor routines to return + * data to the user when DBT flags indicate that DB should manage + * the returned memory. They point at a DBT containing the buffer + * and length that will be used, and "belonging" to the handle that + * should "own" this memory. This may be a "my_*" field of this + * cursor--the default--or it may be the corresponding field of + * another cursor, a DB handle, a join cursor, etc. In general, it + * will be whatever handle the user originally used for the current + * DB interface call. + */ + DBT *rskey; /* Returned secondary key. */ + DBT *rkey; /* Returned [primary] key. */ + DBT *rdata; /* Returned data. */ + + DBT my_rskey; /* Space for returned secondary key. */ + DBT my_rkey; /* Space for returned [primary] key. */ + DBT my_rdata; /* Space for returned data. */ + + DB_LOCKER *lref; /* Reference to default locker. */ + DB_LOCKER *locker; /* Locker for this operation. */ + DBT lock_dbt; /* DBT referencing lock. */ + DB_LOCK_ILOCK lock; /* Object to be locked. */ + DB_LOCK mylock; /* CDB lock held on this cursor. */ + + u_int cl_id; /* Remote client id. */ + + DBTYPE dbtype; /* Cursor type. */ + + DBC_INTERNAL *internal; /* Access method private. */ + + /* DBC PUBLIC HANDLE LIST BEGIN */ + int (*close) __P((DBC *)); + int (*cmp) __P((DBC *, DBC *, int *, u_int32_t)); + int (*count) __P((DBC *, db_recno_t *, u_int32_t)); + int (*del) __P((DBC *, u_int32_t)); + int (*dup) __P((DBC *, DBC **, u_int32_t)); + int (*get) __P((DBC *, DBT *, DBT *, u_int32_t)); + int (*get_priority) __P((DBC *, DB_CACHE_PRIORITY *)); + int (*pget) __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); + int (*put) __P((DBC *, DBT *, DBT *, u_int32_t)); + int (*set_priority) __P((DBC *, DB_CACHE_PRIORITY)); + /* DBC PUBLIC HANDLE LIST END */ + + /* The following are the method names deprecated in the 4.6 release. */ + int (*c_close) __P((DBC *)); + int (*c_count) __P((DBC *, db_recno_t *, u_int32_t)); + int (*c_del) __P((DBC *, u_int32_t)); + int (*c_dup) __P((DBC *, DBC **, u_int32_t)); + int (*c_get) __P((DBC *, DBT *, DBT *, u_int32_t)); + int (*c_pget) __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); + int (*c_put) __P((DBC *, DBT *, DBT *, u_int32_t)); + + /* DBC PRIVATE HANDLE LIST BEGIN */ + int (*am_bulk) __P((DBC *, DBT *, u_int32_t)); + int (*am_close) __P((DBC *, db_pgno_t, int *)); + int (*am_del) __P((DBC *, u_int32_t)); + int (*am_destroy) __P((DBC *)); + int (*am_get) __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); + int (*am_put) __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); + int (*am_writelock) __P((DBC *)); + /* DBC PRIVATE HANDLE LIST END */ + +/* + * DBC_DONTLOCK and DBC_RECOVER are used during recovery and transaction + * abort. If a transaction is being aborted or recovered then DBC_RECOVER + * will be set and locking and logging will be disabled on this cursor. If + * we are performing a compensating transaction (e.g. free page processing) + * then DB_DONTLOCK will be set to inhibit locking, but logging will still + * be required. DB_DONTLOCK is also used if the whole database is locked. + */ +#define DBC_ACTIVE 0x00001 /* Cursor in use. */ +#define DBC_BULK 0x00002 /* Bulk update cursor. */ +#define DBC_DONTLOCK 0x00004 /* Don't lock on this cursor. */ +#define DBC_DOWNREV 0x00008 /* Down rev replication master. */ +#define DBC_DUPLICATE 0x00010 /* Create a duplicate cursor. */ +#define DBC_FROM_DB_GET 0x00020 /* Called from the DB->get() method. */ +#define DBC_MULTIPLE 0x00040 /* Return Multiple data. */ +#define DBC_MULTIPLE_KEY 0x00080 /* Return Multiple keys and data. */ +#define DBC_OPD 0x00100 /* Cursor references off-page dups. */ +#define DBC_OWN_LID 0x00200 /* Free lock id on destroy. */ +#define DBC_PARTITIONED 0x00400 /* Cursor for a partitioned db. */ +#define DBC_READ_COMMITTED 0x00800 /* Cursor has degree 2 isolation. */ +#define DBC_READ_UNCOMMITTED 0x01000 /* Cursor has degree 1 isolation. */ +#define DBC_RECOVER 0x02000 /* Recovery cursor; don't log/lock. */ +#define DBC_RMW 0x04000 /* Acquire write flag in read op. */ +#define DBC_TRANSIENT 0x08000 /* Cursor is transient. */ +#define DBC_WAS_READ_COMMITTED 0x10000 /* Cursor holds a read commited lock. */ +#define DBC_WRITECURSOR 0x20000 /* Cursor may be used to write (CDB). */ +#define DBC_WRITER 0x40000 /* Cursor immediately writing (CDB). */ + u_int32_t flags; +}; + +/* Key range statistics structure */ +struct __key_range { + double less; + double equal; + double greater; +}; + +/* Btree/Recno statistics structure. */ +struct __db_bt_stat { + u_int32_t bt_magic; /* Magic number. */ + u_int32_t bt_version; /* Version number. */ + u_int32_t bt_metaflags; /* Metadata flags. */ + u_int32_t bt_nkeys; /* Number of unique keys. */ + u_int32_t bt_ndata; /* Number of data items. */ + u_int32_t bt_pagecnt; /* Page count. */ + u_int32_t bt_pagesize; /* Page size. */ + u_int32_t bt_minkey; /* Minkey value. */ + u_int32_t bt_re_len; /* Fixed-length record length. */ + u_int32_t bt_re_pad; /* Fixed-length record pad. */ + u_int32_t bt_levels; /* Tree levels. */ + u_int32_t bt_int_pg; /* Internal pages. */ + u_int32_t bt_leaf_pg; /* Leaf pages. */ + u_int32_t bt_dup_pg; /* Duplicate pages. */ + u_int32_t bt_over_pg; /* Overflow pages. */ + u_int32_t bt_empty_pg; /* Empty pages. */ + u_int32_t bt_free; /* Pages on the free list. */ + uintmax_t bt_int_pgfree; /* Bytes free in internal pages. */ + uintmax_t bt_leaf_pgfree; /* Bytes free in leaf pages. */ + uintmax_t bt_dup_pgfree; /* Bytes free in duplicate pages. */ + uintmax_t bt_over_pgfree; /* Bytes free in overflow pages. */ +}; + +struct __db_compact { + /* Input Parameters. */ + u_int32_t compact_fillpercent; /* Desired fillfactor: 1-100 */ + db_timeout_t compact_timeout; /* Lock timeout. */ + u_int32_t compact_pages; /* Max pages to process. */ + /* Output Stats. */ + u_int32_t compact_pages_free; /* Number of pages freed. */ + u_int32_t compact_pages_examine; /* Number of pages examine. */ + u_int32_t compact_levels; /* Number of levels removed. */ + u_int32_t compact_deadlock; /* Number of deadlocks. */ + db_pgno_t compact_pages_truncated; /* Pages truncated to OS. */ + /* Internal. */ + db_pgno_t compact_truncate; /* Page number for truncation */ +}; + +/* Hash statistics structure. */ +struct __db_h_stat { + u_int32_t hash_magic; /* Magic number. */ + u_int32_t hash_version; /* Version number. */ + u_int32_t hash_metaflags; /* Metadata flags. */ + u_int32_t hash_nkeys; /* Number of unique keys. */ + u_int32_t hash_ndata; /* Number of data items. */ + u_int32_t hash_pagecnt; /* Page count. */ + u_int32_t hash_pagesize; /* Page size. */ + u_int32_t hash_ffactor; /* Fill factor specified at create. */ + u_int32_t hash_buckets; /* Number of hash buckets. */ + u_int32_t hash_free; /* Pages on the free list. */ + uintmax_t hash_bfree; /* Bytes free on bucket pages. */ + u_int32_t hash_bigpages; /* Number of big key/data pages. */ + uintmax_t hash_big_bfree; /* Bytes free on big item pages. */ + u_int32_t hash_overflows; /* Number of overflow pages. */ + uintmax_t hash_ovfl_free; /* Bytes free on ovfl pages. */ + u_int32_t hash_dup; /* Number of dup pages. */ + uintmax_t hash_dup_free; /* Bytes free on duplicate pages. */ +}; + +/* Queue statistics structure. */ +struct __db_qam_stat { + u_int32_t qs_magic; /* Magic number. */ + u_int32_t qs_version; /* Version number. */ + u_int32_t qs_metaflags; /* Metadata flags. */ + u_int32_t qs_nkeys; /* Number of unique keys. */ + u_int32_t qs_ndata; /* Number of data items. */ + u_int32_t qs_pagesize; /* Page size. */ + u_int32_t qs_extentsize; /* Pages per extent. */ + u_int32_t qs_pages; /* Data pages. */ + u_int32_t qs_re_len; /* Fixed-length record length. */ + u_int32_t qs_re_pad; /* Fixed-length record pad. */ + u_int32_t qs_pgfree; /* Bytes free in data pages. */ + u_int32_t qs_first_recno; /* First not deleted record. */ + u_int32_t qs_cur_recno; /* Next available record number. */ +}; + +/******************************************************* + * Environment. + *******************************************************/ +#define DB_REGION_MAGIC 0x120897 /* Environment magic number. */ + +/* + * Database environment structure. + * + * This is the public database environment handle. The private environment + * handle is the ENV structure. The user owns this structure, the library + * owns the ENV structure. The reason there are two structures is because + * the user's configuration outlives any particular DB_ENV->open call, and + * separate structures allows us to easily discard internal information without + * discarding the user's configuration. + * + * Fields in the DB_ENV structure should normally be set only by application + * DB_ENV handle methods. + */ +struct __db_env { + ENV *env; /* Linked ENV structure */ + + /* + * The DB_ENV structure can be used concurrently, so field access is + * protected. + */ + db_mutex_t mtx_db_env; /* DB_ENV structure mutex */ + + /* Error message callback */ + void (*db_errcall) __P((const DB_ENV *, const char *, const char *)); + FILE *db_errfile; /* Error message file stream */ + const char *db_errpfx; /* Error message prefix */ + + /* Other message callback */ + void (*db_msgcall) __P((const DB_ENV *, const char *)); + FILE *db_msgfile; /* Other message file stream */ + + /* Other application callback functions */ + int (*app_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); + void (*db_event_func) __P((DB_ENV *, u_int32_t, void *)); + void (*db_feedback) __P((DB_ENV *, int, int)); + void (*db_free) __P((void *)); + void (*db_paniccall) __P((DB_ENV *, int)); + void *(*db_malloc) __P((size_t)); + void *(*db_realloc) __P((void *, size_t)); + int (*is_alive) __P((DB_ENV *, pid_t, db_threadid_t, u_int32_t)); + void (*thread_id) __P((DB_ENV *, pid_t *, db_threadid_t *)); + char *(*thread_id_string) __P((DB_ENV *, pid_t, db_threadid_t, char *)); + + /* Application specified paths */ + char *db_log_dir; /* Database log file directory */ + char *db_tmp_dir; /* Database tmp file directory */ + + char *db_create_dir; /* Create directory for data files */ + char **db_data_dir; /* Database data file directories */ + int data_cnt; /* Database data file slots */ + int data_next; /* Next database data file slot */ + + char *intermediate_dir_mode; /* Intermediate directory perms */ + + long shm_key; /* shmget key */ + + char *passwd; /* Cryptography support */ + size_t passwd_len; + + void *cl_handle; /* RPC: remote client handle */ + u_int cl_id; /* RPC: remote client env id */ + + /* Private handle references */ + void *app_private; /* Application-private handle */ + void *api1_internal; /* C++, Perl API private */ + void *api2_internal; /* Java API private */ + + u_int32_t verbose; /* DB_VERB_XXX flags */ + + /* Mutex configuration */ + u_int32_t mutex_align; /* Mutex alignment */ + u_int32_t mutex_cnt; /* Number of mutexes to configure */ + u_int32_t mutex_inc; /* Number of mutexes to add */ + u_int32_t mutex_tas_spins;/* Test-and-set spin count */ + + /* Locking configuration */ + u_int8_t *lk_conflicts; /* Two dimensional conflict matrix */ + int lk_modes; /* Number of lock modes in table */ + u_int32_t lk_detect; /* Deadlock detect on all conflicts */ + u_int32_t lk_max; /* Maximum number of locks */ + u_int32_t lk_max_lockers;/* Maximum number of lockers */ + u_int32_t lk_max_objects;/* Maximum number of locked objects */ + u_int32_t lk_partitions ;/* Number of object partitions */ + db_timeout_t lk_timeout; /* Lock timeout period */ + + /* Logging configuration */ + u_int32_t lg_bsize; /* Buffer size */ + int lg_filemode; /* Log file permission mode */ + u_int32_t lg_regionmax; /* Region size */ + u_int32_t lg_size; /* Log file size */ + u_int32_t lg_flags; /* Log configuration */ + + /* Memory pool configuration */ + u_int32_t mp_gbytes; /* Cache size: GB */ + u_int32_t mp_bytes; /* Cache size: bytes */ + u_int32_t mp_max_gbytes; /* Maximum cache size: GB */ + u_int32_t mp_max_bytes; /* Maximum cache size: bytes */ + size_t mp_mmapsize; /* Maximum file size for mmap */ + int mp_maxopenfd; /* Maximum open file descriptors */ + int mp_maxwrite; /* Maximum buffers to write */ + u_int mp_ncache; /* Initial number of cache regions */ + u_int32_t mp_pagesize; /* Average page size */ + u_int32_t mp_tablesize; /* Approximate hash table size */ + /* Sleep after writing max buffers */ + db_timeout_t mp_maxwrite_sleep; + + /* Transaction configuration */ + u_int32_t tx_max; /* Maximum number of transactions */ + time_t tx_timestamp; /* Recover to specific timestamp */ + db_timeout_t tx_timeout; /* Timeout for transactions */ + + /* Thread tracking configuration */ + u_int32_t thr_max; /* Thread count */ + + /* + * The following fields are not strictly user-owned, but they outlive + * the ENV structure, and so are stored here. + */ + DB_FH *registry; /* DB_REGISTER file handle */ + u_int32_t registry_off; /* + * Offset of our slot. We can't use + * off_t because its size depends on + * build settings. + */ + db_timeout_t envreg_timeout; /* DB_REGISTER wait timeout */ + +#define DB_ENV_AUTO_COMMIT 0x00000001 /* DB_AUTO_COMMIT */ +#define DB_ENV_CDB_ALLDB 0x00000002 /* CDB environment wide locking */ +#define DB_ENV_FAILCHK 0x00000004 /* Failchk is running */ +#define DB_ENV_DIRECT_DB 0x00000008 /* DB_DIRECT_DB set */ +#define DB_ENV_DSYNC_DB 0x00000010 /* DB_DSYNC_DB set */ +#define DB_ENV_MULTIVERSION 0x00000020 /* DB_MULTIVERSION set */ +#define DB_ENV_NOLOCKING 0x00000040 /* DB_NOLOCKING set */ +#define DB_ENV_NOMMAP 0x00000080 /* DB_NOMMAP set */ +#define DB_ENV_NOPANIC 0x00000100 /* Okay if panic set */ +#define DB_ENV_OVERWRITE 0x00000200 /* DB_OVERWRITE set */ +#define DB_ENV_REGION_INIT 0x00000400 /* DB_REGION_INIT set */ +#define DB_ENV_RPCCLIENT 0x00000800 /* DB_RPCCLIENT set */ +#define DB_ENV_RPCCLIENT_GIVEN 0x00001000 /* User-supplied RPC client struct */ +#define DB_ENV_TIME_NOTGRANTED 0x00002000 /* DB_TIME_NOTGRANTED set */ +#define DB_ENV_TXN_NOSYNC 0x00004000 /* DB_TXN_NOSYNC set */ +#define DB_ENV_TXN_NOWAIT 0x00008000 /* DB_TXN_NOWAIT set */ +#define DB_ENV_TXN_SNAPSHOT 0x00010000 /* DB_TXN_SNAPSHOT set */ +#define DB_ENV_TXN_WRITE_NOSYNC 0x00020000 /* DB_TXN_WRITE_NOSYNC set */ +#define DB_ENV_YIELDCPU 0x00040000 /* DB_YIELDCPU set */ + u_int32_t flags; + + /* DB_ENV PUBLIC HANDLE LIST BEGIN */ + int (*add_data_dir) __P((DB_ENV *, const char *)); + int (*cdsgroup_begin) __P((DB_ENV *, DB_TXN **)); + int (*close) __P((DB_ENV *, u_int32_t)); + int (*dbremove) __P((DB_ENV *, + DB_TXN *, const char *, const char *, u_int32_t)); + int (*dbrename) __P((DB_ENV *, + DB_TXN *, const char *, const char *, const char *, u_int32_t)); + void (*err) __P((const DB_ENV *, int, const char *, ...)); + void (*errx) __P((const DB_ENV *, const char *, ...)); + int (*failchk) __P((DB_ENV *, u_int32_t)); + int (*fileid_reset) __P((DB_ENV *, const char *, u_int32_t)); + int (*get_alloc) __P((DB_ENV *, void *(**)(size_t), + void *(**)(void *, size_t), void (**)(void *))); + int (*get_app_dispatch) + __P((DB_ENV *, int (**)(DB_ENV *, DBT *, DB_LSN *, db_recops))); + int (*get_cache_max) __P((DB_ENV *, u_int32_t *, u_int32_t *)); + int (*get_cachesize) __P((DB_ENV *, u_int32_t *, u_int32_t *, int *)); + int (*get_create_dir) __P((DB_ENV *, const char **)); + int (*get_data_dirs) __P((DB_ENV *, const char ***)); + int (*get_encrypt_flags) __P((DB_ENV *, u_int32_t *)); + void (*get_errcall) __P((DB_ENV *, + void (**)(const DB_ENV *, const char *, const char *))); + void (*get_errfile) __P((DB_ENV *, FILE **)); + void (*get_errpfx) __P((DB_ENV *, const char **)); + int (*get_flags) __P((DB_ENV *, u_int32_t *)); + int (*get_feedback) __P((DB_ENV *, void (**)(DB_ENV *, int, int))); + int (*get_home) __P((DB_ENV *, const char **)); + int (*get_intermediate_dir_mode) __P((DB_ENV *, const char **)); + int (*get_isalive) __P((DB_ENV *, + int (**)(DB_ENV *, pid_t, db_threadid_t, u_int32_t))); + int (*get_lg_bsize) __P((DB_ENV *, u_int32_t *)); + int (*get_lg_dir) __P((DB_ENV *, const char **)); + int (*get_lg_filemode) __P((DB_ENV *, int *)); + int (*get_lg_max) __P((DB_ENV *, u_int32_t *)); + int (*get_lg_regionmax) __P((DB_ENV *, u_int32_t *)); + int (*get_lk_conflicts) __P((DB_ENV *, const u_int8_t **, int *)); + int (*get_lk_detect) __P((DB_ENV *, u_int32_t *)); + int (*get_lk_max_lockers) __P((DB_ENV *, u_int32_t *)); + int (*get_lk_max_locks) __P((DB_ENV *, u_int32_t *)); + int (*get_lk_max_objects) __P((DB_ENV *, u_int32_t *)); + int (*get_lk_partitions) __P((DB_ENV *, u_int32_t *)); + int (*get_mp_max_openfd) __P((DB_ENV *, int *)); + int (*get_mp_max_write) __P((DB_ENV *, int *, db_timeout_t *)); + int (*get_mp_mmapsize) __P((DB_ENV *, size_t *)); + int (*get_mp_pagesize) __P((DB_ENV *, u_int32_t *)); + int (*get_mp_tablesize) __P((DB_ENV *, u_int32_t *)); + void (*get_msgcall) + __P((DB_ENV *, void (**)(const DB_ENV *, const char *))); + void (*get_msgfile) __P((DB_ENV *, FILE **)); + int (*get_open_flags) __P((DB_ENV *, u_int32_t *)); + int (*get_shm_key) __P((DB_ENV *, long *)); + int (*get_thread_count) __P((DB_ENV *, u_int32_t *)); + int (*get_thread_id_fn) + __P((DB_ENV *, void (**)(DB_ENV *, pid_t *, db_threadid_t *))); + int (*get_thread_id_string_fn) __P((DB_ENV *, + char *(**)(DB_ENV *, pid_t, db_threadid_t, char *))); + int (*get_timeout) __P((DB_ENV *, db_timeout_t *, u_int32_t)); + int (*get_tmp_dir) __P((DB_ENV *, const char **)); + int (*get_tx_max) __P((DB_ENV *, u_int32_t *)); + int (*get_tx_timestamp) __P((DB_ENV *, time_t *)); + int (*get_verbose) __P((DB_ENV *, u_int32_t, int *)); + int (*is_bigendian) __P((void)); + int (*lock_detect) __P((DB_ENV *, u_int32_t, u_int32_t, int *)); + int (*lock_get) __P((DB_ENV *, + u_int32_t, u_int32_t, DBT *, db_lockmode_t, DB_LOCK *)); + int (*lock_id) __P((DB_ENV *, u_int32_t *)); + int (*lock_id_free) __P((DB_ENV *, u_int32_t)); + int (*lock_put) __P((DB_ENV *, DB_LOCK *)); + int (*lock_stat) __P((DB_ENV *, DB_LOCK_STAT **, u_int32_t)); + int (*lock_stat_print) __P((DB_ENV *, u_int32_t)); + int (*lock_vec) __P((DB_ENV *, + u_int32_t, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **)); + int (*log_archive) __P((DB_ENV *, char **[], u_int32_t)); + int (*log_cursor) __P((DB_ENV *, DB_LOGC **, u_int32_t)); + int (*log_file) __P((DB_ENV *, const DB_LSN *, char *, size_t)); + int (*log_flush) __P((DB_ENV *, const DB_LSN *)); + int (*log_get_config) __P((DB_ENV *, u_int32_t, int *)); + int (*log_printf) __P((DB_ENV *, DB_TXN *, const char *, ...)); + int (*log_put) __P((DB_ENV *, DB_LSN *, const DBT *, u_int32_t)); + int (*log_set_config) __P((DB_ENV *, u_int32_t, int)); + int (*log_stat) __P((DB_ENV *, DB_LOG_STAT **, u_int32_t)); + int (*log_stat_print) __P((DB_ENV *, u_int32_t)); + int (*lsn_reset) __P((DB_ENV *, const char *, u_int32_t)); + int (*memp_fcreate) __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t)); + int (*memp_register) __P((DB_ENV *, int, int (*)(DB_ENV *, db_pgno_t, + void *, DBT *), int (*)(DB_ENV *, db_pgno_t, void *, DBT *))); + int (*memp_stat) __P((DB_ENV *, + DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t)); + int (*memp_stat_print) __P((DB_ENV *, u_int32_t)); + int (*memp_sync) __P((DB_ENV *, DB_LSN *)); + int (*memp_trickle) __P((DB_ENV *, int, int *)); + int (*mutex_alloc) __P((DB_ENV *, u_int32_t, db_mutex_t *)); + int (*mutex_free) __P((DB_ENV *, db_mutex_t)); + int (*mutex_get_align) __P((DB_ENV *, u_int32_t *)); + int (*mutex_get_increment) __P((DB_ENV *, u_int32_t *)); + int (*mutex_get_max) __P((DB_ENV *, u_int32_t *)); + int (*mutex_get_tas_spins) __P((DB_ENV *, u_int32_t *)); + int (*mutex_lock) __P((DB_ENV *, db_mutex_t)); + int (*mutex_set_align) __P((DB_ENV *, u_int32_t)); + int (*mutex_set_increment) __P((DB_ENV *, u_int32_t)); + int (*mutex_set_max) __P((DB_ENV *, u_int32_t)); + int (*mutex_set_tas_spins) __P((DB_ENV *, u_int32_t)); + int (*mutex_stat) __P((DB_ENV *, DB_MUTEX_STAT **, u_int32_t)); + int (*mutex_stat_print) __P((DB_ENV *, u_int32_t)); + int (*mutex_unlock) __P((DB_ENV *, db_mutex_t)); + int (*open) __P((DB_ENV *, const char *, u_int32_t, int)); + int (*remove) __P((DB_ENV *, const char *, u_int32_t)); + int (*rep_elect) __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t)); + int (*rep_flush) __P((DB_ENV *)); + int (*rep_get_clockskew) __P((DB_ENV *, u_int32_t *, u_int32_t *)); + int (*rep_get_config) __P((DB_ENV *, u_int32_t, int *)); + int (*rep_get_limit) __P((DB_ENV *, u_int32_t *, u_int32_t *)); + int (*rep_get_nsites) __P((DB_ENV *, u_int32_t *)); + int (*rep_get_priority) __P((DB_ENV *, u_int32_t *)); + int (*rep_get_request) __P((DB_ENV *, u_int32_t *, u_int32_t *)); + int (*rep_get_timeout) __P((DB_ENV *, int, u_int32_t *)); + int (*rep_process_message) + __P((DB_ENV *, DBT *, DBT *, int, DB_LSN *)); + int (*rep_set_clockskew) __P((DB_ENV *, u_int32_t, u_int32_t)); + int (*rep_set_config) __P((DB_ENV *, u_int32_t, int)); + int (*rep_set_limit) __P((DB_ENV *, u_int32_t, u_int32_t)); + int (*rep_set_nsites) __P((DB_ENV *, u_int32_t)); + int (*rep_set_priority) __P((DB_ENV *, u_int32_t)); + int (*rep_set_request) __P((DB_ENV *, u_int32_t, u_int32_t)); + int (*rep_set_timeout) __P((DB_ENV *, int, db_timeout_t)); + int (*rep_set_transport) __P((DB_ENV *, int, int (*)(DB_ENV *, + const DBT *, const DBT *, const DB_LSN *, int, u_int32_t))); + int (*rep_start) __P((DB_ENV *, DBT *, u_int32_t)); + int (*rep_stat) __P((DB_ENV *, DB_REP_STAT **, u_int32_t)); + int (*rep_stat_print) __P((DB_ENV *, u_int32_t)); + int (*rep_sync) __P((DB_ENV *, u_int32_t)); + int (*repmgr_add_remote_site) + __P((DB_ENV *, const char *, u_int, int *, u_int32_t)); + int (*repmgr_get_ack_policy) __P((DB_ENV *, int *)); + int (*repmgr_set_ack_policy) __P((DB_ENV *, int)); + int (*repmgr_set_local_site) + __P((DB_ENV *, const char *, u_int, u_int32_t)); + int (*repmgr_site_list) + __P((DB_ENV *, u_int *, DB_REPMGR_SITE **)); + int (*repmgr_start) __P((DB_ENV *, int, u_int32_t)); + int (*repmgr_stat) __P((DB_ENV *, DB_REPMGR_STAT **, u_int32_t)); + int (*repmgr_stat_print) __P((DB_ENV *, u_int32_t)); + int (*set_alloc) __P((DB_ENV *, void *(*)(size_t), + void *(*)(void *, size_t), void (*)(void *))); + int (*set_app_dispatch) + __P((DB_ENV *, int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops))); + int (*set_cache_max) __P((DB_ENV *, u_int32_t, u_int32_t)); + int (*set_cachesize) __P((DB_ENV *, u_int32_t, u_int32_t, int)); + int (*set_create_dir) __P((DB_ENV *, const char *)); + int (*set_data_dir) __P((DB_ENV *, const char *)); + int (*set_encrypt) __P((DB_ENV *, const char *, u_int32_t)); + void (*set_errcall) __P((DB_ENV *, + void (*)(const DB_ENV *, const char *, const char *))); + void (*set_errfile) __P((DB_ENV *, FILE *)); + void (*set_errpfx) __P((DB_ENV *, const char *)); + int (*set_event_notify) + __P((DB_ENV *, void (*)(DB_ENV *, u_int32_t, void *))); + int (*set_feedback) __P((DB_ENV *, void (*)(DB_ENV *, int, int))); + int (*set_flags) __P((DB_ENV *, u_int32_t, int)); + int (*set_intermediate_dir_mode) __P((DB_ENV *, const char *)); + int (*set_isalive) __P((DB_ENV *, + int (*)(DB_ENV *, pid_t, db_threadid_t, u_int32_t))); + int (*set_lg_bsize) __P((DB_ENV *, u_int32_t)); + int (*set_lg_dir) __P((DB_ENV *, const char *)); + int (*set_lg_filemode) __P((DB_ENV *, int)); + int (*set_lg_max) __P((DB_ENV *, u_int32_t)); + int (*set_lg_regionmax) __P((DB_ENV *, u_int32_t)); + int (*set_lk_conflicts) __P((DB_ENV *, u_int8_t *, int)); + int (*set_lk_detect) __P((DB_ENV *, u_int32_t)); + int (*set_lk_max_lockers) __P((DB_ENV *, u_int32_t)); + int (*set_lk_max_locks) __P((DB_ENV *, u_int32_t)); + int (*set_lk_max_objects) __P((DB_ENV *, u_int32_t)); + int (*set_lk_partitions) __P((DB_ENV *, u_int32_t)); + int (*set_mp_max_openfd) __P((DB_ENV *, int)); + int (*set_mp_max_write) __P((DB_ENV *, int, db_timeout_t)); + int (*set_mp_mmapsize) __P((DB_ENV *, size_t)); + int (*set_mp_pagesize) __P((DB_ENV *, u_int32_t)); + int (*set_mp_tablesize) __P((DB_ENV *, u_int32_t)); + void (*set_msgcall) + __P((DB_ENV *, void (*)(const DB_ENV *, const char *))); + void (*set_msgfile) __P((DB_ENV *, FILE *)); + int (*set_paniccall) __P((DB_ENV *, void (*)(DB_ENV *, int))); + int (*set_rpc_server) + __P((DB_ENV *, void *, const char *, long, long, u_int32_t)); + int (*set_shm_key) __P((DB_ENV *, long)); + int (*set_thread_count) __P((DB_ENV *, u_int32_t)); + int (*set_thread_id) + __P((DB_ENV *, void (*)(DB_ENV *, pid_t *, db_threadid_t *))); + int (*set_thread_id_string) __P((DB_ENV *, + char *(*)(DB_ENV *, pid_t, db_threadid_t, char *))); + int (*set_timeout) __P((DB_ENV *, db_timeout_t, u_int32_t)); + int (*set_tmp_dir) __P((DB_ENV *, const char *)); + int (*set_tx_max) __P((DB_ENV *, u_int32_t)); + int (*set_tx_timestamp) __P((DB_ENV *, time_t *)); + int (*set_verbose) __P((DB_ENV *, u_int32_t, int)); + int (*stat_print) __P((DB_ENV *, u_int32_t)); + int (*txn_begin) __P((DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t)); + int (*txn_checkpoint) __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t)); + int (*txn_recover) __P((DB_ENV *, + DB_PREPLIST *, u_int32_t, u_int32_t *, u_int32_t)); + int (*txn_stat) __P((DB_ENV *, DB_TXN_STAT **, u_int32_t)); + int (*txn_stat_print) __P((DB_ENV *, u_int32_t)); + /* DB_ENV PUBLIC HANDLE LIST END */ + + /* DB_ENV PRIVATE HANDLE LIST BEGIN */ + int (*prdbt) __P((DBT *, + int, const char *, void *, int (*)(void *, const void *), int)); + /* DB_ENV PRIVATE HANDLE LIST END */ +}; + +/* + * Dispatch structure for recovery and print routines. Since internal and + * external routines take different arguments (ENV versus DB_ENV), we need + * something more elaborate than a single pointer and size. + */ +struct __db_distab { + int (**int_dispatch) __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + size_t int_size; + int (**ext_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); + size_t ext_size; +}; + +#ifndef DB_DBM_HSEARCH +#define DB_DBM_HSEARCH 0 /* No historic interfaces by default. */ +#endif +#if DB_DBM_HSEARCH != 0 +/******************************************************* + * Dbm/Ndbm historic interfaces. + *******************************************************/ +typedef struct __db DBM; + +#define DBM_INSERT 0 /* Flags to dbm_store(). */ +#define DBM_REPLACE 1 + +/* + * The DB support for ndbm(3) always appends this suffix to the + * file name to avoid overwriting the user's original database. + */ +#define DBM_SUFFIX ".db" + +#if defined(_XPG4_2) +typedef struct { + char *dptr; + size_t dsize; +} datum; +#else +typedef struct { + char *dptr; + int dsize; +} datum; +#endif + +/* + * Translate NDBM calls into DB calls so that DB doesn't step on the + * application's name space. + */ +#define dbm_clearerr(a) __db_ndbm_clearerr@DB_VERSION_UNIQUE_NAME@(a) +#define dbm_close(a) __db_ndbm_close@DB_VERSION_UNIQUE_NAME@(a) +#define dbm_delete(a, b) __db_ndbm_delete@DB_VERSION_UNIQUE_NAME@(a, b) +#define dbm_dirfno(a) __db_ndbm_dirfno@DB_VERSION_UNIQUE_NAME@(a) +#define dbm_error(a) __db_ndbm_error@DB_VERSION_UNIQUE_NAME@(a) +#define dbm_fetch(a, b) __db_ndbm_fetch@DB_VERSION_UNIQUE_NAME@(a, b) +#define dbm_firstkey(a) __db_ndbm_firstkey@DB_VERSION_UNIQUE_NAME@(a) +#define dbm_nextkey(a) __db_ndbm_nextkey@DB_VERSION_UNIQUE_NAME@(a) +#define dbm_open(a, b, c) __db_ndbm_open@DB_VERSION_UNIQUE_NAME@(a, b, c) +#define dbm_pagfno(a) __db_ndbm_pagfno@DB_VERSION_UNIQUE_NAME@(a) +#define dbm_rdonly(a) __db_ndbm_rdonly@DB_VERSION_UNIQUE_NAME@(a) +#define dbm_store(a, b, c, d) \ + __db_ndbm_store@DB_VERSION_UNIQUE_NAME@(a, b, c, d) + +/* + * Translate DBM calls into DB calls so that DB doesn't step on the + * application's name space. + * + * The global variables dbrdonly, dirf and pagf were not retained when 4BSD + * replaced the dbm interface with ndbm, and are not supported here. + */ +#define dbminit(a) __db_dbm_init@DB_VERSION_UNIQUE_NAME@(a) +#define dbmclose __db_dbm_close@DB_VERSION_UNIQUE_NAME@ +#if !defined(__cplusplus) +#define delete(a) __db_dbm_delete@DB_VERSION_UNIQUE_NAME@(a) +#endif +#define fetch(a) __db_dbm_fetch@DB_VERSION_UNIQUE_NAME@(a) +#define firstkey __db_dbm_firstkey@DB_VERSION_UNIQUE_NAME@ +#define nextkey(a) __db_dbm_nextkey@DB_VERSION_UNIQUE_NAME@(a) +#define store(a, b) __db_dbm_store@DB_VERSION_UNIQUE_NAME@(a, b) + +/******************************************************* + * Hsearch historic interface. + *******************************************************/ +typedef enum { + FIND, ENTER +} ACTION; + +typedef struct entry { + char *key; + char *data; +} ENTRY; + +#define hcreate(a) __db_hcreate@DB_VERSION_UNIQUE_NAME@(a) +#define hdestroy __db_hdestroy@DB_VERSION_UNIQUE_NAME@ +#define hsearch(a, b) __db_hsearch@DB_VERSION_UNIQUE_NAME@(a, b) + +#endif /* DB_DBM_HSEARCH */ + +#if defined(__cplusplus) +} +#endif + +@platform_footer@ +#endif /* !_DB_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db_185.in b/src/libs/resiprocate/contrib/db/dbinc/db_185.in new file mode 100644 index 00000000..d3da455b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db_185.in @@ -0,0 +1,176 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef _DB_185_H_ +#define _DB_185_H_ + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * XXX + * Handle function prototypes and the keyword "const". This steps on name + * space that DB doesn't control, but all of the other solutions are worse. + */ +#undef __P +#if defined(__STDC__) || defined(__cplusplus) +#define __P(protos) protos /* ANSI C prototypes */ +#else +#define const +#define __P(protos) () /* K&R C preprocessor */ +#endif + +#define RET_ERROR -1 /* Return values. */ +#define RET_SUCCESS 0 +#define RET_SPECIAL 1 + +#ifndef __BIT_TYPES_DEFINED__ +#define __BIT_TYPES_DEFINED__ +@u_int8_decl@ +@int16_decl@ +@u_int16_decl@ +@int32_decl@ +@u_int32_decl@ +#endif + +/* + * XXX + * SGI/IRIX already has a pgno_t. + */ +#ifdef __sgi +#define pgno_t db_pgno_t +#endif + +#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */ +typedef u_int32_t pgno_t; +#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */ +typedef u_int16_t indx_t; +#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */ +typedef u_int32_t recno_t; + +/* Key/data structure -- a Data-Base Thang. */ +typedef struct { + void *data; /* data */ + size_t size; /* data length */ +} DBT; + +/* Routine flags. */ +#define R_CURSOR 1 /* del, put, seq */ +#define __R_UNUSED 2 /* UNUSED */ +#define R_FIRST 3 /* seq */ +#define R_IAFTER 4 /* put (RECNO) */ +#define R_IBEFORE 5 /* put (RECNO) */ +#define R_LAST 6 /* seq (BTREE, RECNO) */ +#define R_NEXT 7 /* seq */ +#define R_NOOVERWRITE 8 /* put */ +#define R_PREV 9 /* seq (BTREE, RECNO) */ +#define R_SETCURSOR 10 /* put (RECNO) */ +#define R_RECNOSYNC 11 /* sync (RECNO) */ + +typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE; + +/* Access method description structure. */ +typedef struct __db { + DBTYPE type; /* Underlying db type. */ + int (*close) __P((struct __db *)); + int (*del) __P((const struct __db *, const DBT *, u_int)); + int (*get) __P((const struct __db *, const DBT *, DBT *, u_int)); + int (*put) __P((const struct __db *, DBT *, const DBT *, u_int)); + int (*seq) __P((const struct __db *, DBT *, DBT *, u_int)); + int (*sync) __P((const struct __db *, u_int)); + void *internal; /* Access method private. */ + int (*fd) __P((const struct __db *)); +} DB; + +#define BTREEMAGIC 0x053162 +#define BTREEVERSION 3 + +/* Structure used to pass parameters to the btree routines. */ +typedef struct { +#define R_DUP 0x01 /* duplicate keys */ + u_int32_t flags; + u_int32_t cachesize; /* bytes to cache */ + u_int32_t maxkeypage; /* maximum keys per page */ + u_int32_t minkeypage; /* minimum keys per page */ + u_int32_t psize; /* page size */ + int (*compare) /* comparison function */ + __P((const DBT *, const DBT *)); + size_t (*prefix) /* prefix function */ + __P((const DBT *, const DBT *)); + int lorder; /* byte order */ +} BTREEINFO; + +#define HASHMAGIC 0x061561 +#define HASHVERSION 2 + +/* Structure used to pass parameters to the hashing routines. */ +typedef struct { + u_int32_t bsize; /* bucket size */ + u_int32_t ffactor; /* fill factor */ + u_int32_t nelem; /* number of elements */ + u_int32_t cachesize; /* bytes to cache */ + u_int32_t /* hash function */ + (*hash) __P((const void *, size_t)); + int lorder; /* byte order */ +} HASHINFO; + +/* Structure used to pass parameters to the record routines. */ +typedef struct { +#define R_FIXEDLEN 0x01 /* fixed-length records */ +#define R_NOKEY 0x02 /* key not required */ +#define R_SNAPSHOT 0x04 /* snapshot the input */ + u_int32_t flags; + u_int32_t cachesize; /* bytes to cache */ + u_int32_t psize; /* page size */ + int lorder; /* byte order */ + size_t reclen; /* record length (fixed-length records) */ + u_char bval; /* delimiting byte (variable-length records */ + char *bfname; /* btree file name */ +} RECNOINFO; + +/* Re-define the user's dbopen calls. */ +#define dbopen __db185_open@DB_VERSION_UNIQUE_NAME@ + +#if defined(__cplusplus) +} +#endif + +#endif /* !_DB_185_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db_am.h b/src/libs/resiprocate/contrib/db/dbinc/db_am.h new file mode 100644 index 00000000..4b2aa228 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db_am.h @@ -0,0 +1,311 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ +#ifndef _DB_AM_H_ +#define _DB_AM_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Temporary for the patch release, define this bit here so it + * does not renumber the other bits for DB->open. + */ +#define DB_NOERROR 0x10000000 + +struct __db_foreign_info; \ + typedef struct __db_foreign_info DB_FOREIGN_INFO; + +/* + * Keep track of information for foreign keys. Used to maintain a linked list + * of 'primary' DBs which reference this 'foreign' DB. + */ +struct __db_foreign_info { + DB *dbp; + u_int32_t flags; + int (*callback) __P((DB *, const DBT *, DBT *, const DBT *, int *)); + + /* + * List entries for foreign key. + * + * !!! + * Explicit representations of structures from queue.h. + * LIST_ENTRY(__db) s_links; + */ + struct { + struct __db_foreign_info *le_next; + struct __db_foreign_info **le_prev; + } f_links; +}; + +/* + * IS_ENV_AUTO_COMMIT -- + * Auto-commit test for enviroment operations: DbEnv::{open,remove,rename} + */ +#define IS_ENV_AUTO_COMMIT(env, txn, flags) \ + (LF_ISSET(DB_AUTO_COMMIT) || ((txn) == NULL && \ + F_ISSET((env)->dbenv, DB_ENV_AUTO_COMMIT) && \ + !LF_ISSET(DB_NO_AUTO_COMMIT))) + +/* + * IS_DB_AUTO_COMMIT -- + * Auto-commit test for database operations. + */ +#define IS_DB_AUTO_COMMIT(dbp, txn) \ + ((txn) == NULL && F_ISSET((dbp), DB_AM_TXN)) + +/* + * STRIP_AUTO_COMMIT -- + * Releases after 4.3 no longer requires DB operations to specify the + * AUTO_COMMIT flag, but the API continues to allow it to be specified. + */ +#define STRIP_AUTO_COMMIT(f) FLD_CLR((f), DB_AUTO_COMMIT) + +/* DB recovery operation codes. */ +#define DB_ADD_DUP 1 +#define DB_REM_DUP 2 +#define DB_ADD_BIG 3 +#define DB_REM_BIG 4 +#define DB_ADD_PAGE_COMPAT 5 /* Compatibility for 4.2 db_relink */ +#define DB_REM_PAGE_COMPAT 6 /* Compatibility for 4.2 db_relink */ +#define DB_APPEND_BIG 7 + +/* + * Standard initialization and shutdown macros for all recovery functions. + */ +#define REC_INTRO(func, ip, do_cursor) do { \ + argp = NULL; \ + dbc = NULL; \ + file_dbp = NULL; \ + COMPQUIET(mpf, NULL); /* Not all recovery routines use mpf. */\ + if ((ret = func(env, &file_dbp, \ + (info != NULL) ? ((DB_TXNHEAD *)info)->td : NULL, \ + dbtp->data, &argp)) != 0) { \ + if (ret == DB_DELETED) { \ + ret = 0; \ + goto done; \ + } \ + goto out; \ + } \ + if (do_cursor) { \ + if ((ret = \ + __db_cursor(file_dbp, ip, NULL, &dbc, 0)) != 0) \ + goto out; \ + F_SET(dbc, DBC_RECOVER); \ + } \ + mpf = file_dbp->mpf; \ +} while (0) + +#define REC_CLOSE { \ + int __t_ret; \ + if (argp != NULL) \ + __os_free(env, argp); \ + if (dbc != NULL && \ + (__t_ret = __dbc_close(dbc)) != 0 && ret == 0) \ + ret = __t_ret; \ + } \ + return (ret) + +/* + * No-op versions of the same macros. + */ +#define REC_NOOP_INTRO(func) do { \ + argp = NULL; \ + if ((ret = func(env, dbtp->data, &argp)) != 0) \ + return (ret); \ +} while (0) +#define REC_NOOP_CLOSE \ + if (argp != NULL) \ + __os_free(env, argp); \ + return (ret) + +/* + * Macro for reading pages during recovery. In most cases we + * want to avoid an error if the page is not found during rollback. + */ +#define REC_FGET(mpf, ip, pgno, pagep, cont) \ + if ((ret = __memp_fget(mpf, \ + &(pgno), ip, NULL, 0, pagep)) != 0) { \ + if (ret != DB_PAGE_NOTFOUND) { \ + ret = __db_pgerr(file_dbp, pgno, ret); \ + goto out; \ + } else \ + goto cont; \ + } +#define REC_DIRTY(mpf, ip, priority, pagep) \ + if ((ret = __memp_dirty(mpf, \ + pagep, ip, NULL, priority, DB_MPOOL_EDIT)) != 0) { \ + ret = __db_pgerr(file_dbp, PGNO(*(pagep)), ret); \ + goto out; \ + } + +/* + * Standard debugging macro for all recovery functions. + */ +#ifdef DEBUG_RECOVER +#define REC_PRINT(func) \ + (void)func(env, dbtp, lsnp, op, info); +#else +#define REC_PRINT(func) +#endif + +/* + * Actions to __db_lget + */ +#define LCK_ALWAYS 1 /* Lock even for off page dup cursors */ +#define LCK_COUPLE 2 /* Lock Couple */ +#define LCK_COUPLE_ALWAYS 3 /* Lock Couple even in txn. */ +#define LCK_DOWNGRADE 4 /* Downgrade the lock. (internal) */ +#define LCK_ROLLBACK 5 /* Lock even if in rollback */ + +/* + * If doing transactions we have to hold the locks associated with a data item + * from a page for the entire transaction. However, we don't have to hold the + * locks associated with walking the tree. Distinguish between the two so that + * we don't tie up the internal pages of the tree longer than necessary. + */ +#define __LPUT(dbc, lock) \ + __ENV_LPUT((dbc)->env, lock) + +#define __ENV_LPUT(env, lock) \ + (LOCK_ISSET(lock) ? __lock_put(env, &(lock)) : 0) + +/* + * __TLPUT -- transactional lock put + * If the lock is valid then + * If we are not in a transaction put the lock. + * Else if the cursor is doing dirty reads and this was a read then + * put the lock. + * Else if the db is supporting dirty reads and this is a write then + * downgrade it. + * Else do nothing. + */ +#define __TLPUT(dbc, lock) \ + (LOCK_ISSET(lock) ? __db_lput(dbc, &(lock)) : 0) + +/* + * Check whether a database is a primary (that is, has associated secondaries). + */ +#define DB_IS_PRIMARY(dbp) (LIST_FIRST(&dbp->s_secondaries) != NULL) +/* + * A database should be required to be readonly if it's been explicitly + * specified as such or if we're a client in a replicated environment + * and the user did not specify DB_TXN_NOT_DURABLE. + */ +#define DB_IS_READONLY(dbp) \ + (F_ISSET(dbp, DB_AM_RDONLY) || \ + (IS_REP_CLIENT((dbp)->env) && !F_ISSET((dbp), DB_AM_NOT_DURABLE))) + +#ifdef HAVE_COMPRESSION +/* + * Check whether a database is compressed (btree only) + */ +#define DB_IS_COMPRESSED(dbp) \ + (((BTREE *)(dbp)->bt_internal)->bt_compress != NULL) +#endif + +/* + * We copy the key out if there's any chance the key in the database is not + * the same as the user-specified key. If there is a custom comparator we + * return a key, as the user-specified key might be a partial key, containing + * only the unique identifier. [#13572] [#15770] + * + * The test for (flags != 0) is necessary for Db.{get,pget}, but it's not + * legal to pass a non-zero flags value to Dbc.{get,pget}. + * + * We need to split out the hash component, since it is possible to build + * without hash support enabled. Which would result in a null pointer access. + */ +#ifdef HAVE_HASH +#define DB_RETURNS_A_KEY_HASH(dbp) \ + ((HASH *)(dbp)->h_internal)->h_compare != NULL +#else +#define DB_RETURNS_A_KEY_HASH(dbp) 0 +#endif +#define DB_RETURNS_A_KEY(dbp, flags) \ + (((flags) != 0 && (flags) != DB_GET_BOTH && \ + (flags) != DB_GET_BOTH_RANGE && (flags) != DB_SET) || \ + ((BTREE *)(dbp)->bt_internal)->bt_compare != __bam_defcmp ||\ + DB_RETURNS_A_KEY_HASH(dbp)) + +/* + * For portability, primary keys that are record numbers are stored in + * secondaries in the same byte order as the secondary database. As a + * consequence, we need to swap the byte order of these keys before attempting + * to use them for lookups in the primary. We also need to swap user-supplied + * primary keys that are used in secondary lookups (for example, with the + * DB_GET_BOTH flag on a secondary get). + */ +#include "dbinc/db_swap.h" + +#define SWAP_IF_NEEDED(sdbp, pkey) \ + do { \ + if (((sdbp)->s_primary->type == DB_QUEUE || \ + (sdbp)->s_primary->type == DB_RECNO) && \ + F_ISSET((sdbp), DB_AM_SWAP)) \ + P_32_SWAP((pkey)->data); \ + } while (0) + +/* + * Cursor adjustment: + * Return the first DB handle in the sorted ENV list of DB + * handles that has a matching file ID. + */ +#define FIND_FIRST_DB_MATCH(env, dbp, tdbp) do { \ + for ((tdbp) = (dbp); \ + TAILQ_PREV((tdbp), __dblist, dblistlinks) != NULL && \ + TAILQ_PREV((tdbp), \ + __dblist, dblistlinks)->adj_fileid == (dbp)->adj_fileid;\ + (tdbp) = TAILQ_PREV((tdbp), __dblist, dblistlinks)) \ + ; \ +} while (0) + +/* + * Macros used to implement a binary search algorithm. Shared between the + * btree and hash implementations. + */ +#define DB_BINARY_SEARCH_FOR(base, limit, nument, adjust) \ + for (base = 0, limit = (nument) / (db_indx_t)(adjust); \ + (limit) != 0; (limit) >>= 1) + +#define DB_BINARY_SEARCH_INCR(index, base, limit, adjust) \ + index = (base) + (((limit) >> 1) * (adjust)) + +#define DB_BINARY_SEARCH_SHIFT_BASE(index, base, limit, adjust) do { \ + base = (index) + (adjust); \ + --(limit); \ +} while (0) + +/* + * Sequence macros, shared between sequence.c and seq_stat.c + */ +#define SEQ_IS_OPEN(seq) ((seq)->seq_key.data != NULL) + +#define SEQ_ILLEGAL_AFTER_OPEN(seq, name) \ + if (SEQ_IS_OPEN(seq)) \ + return (__db_mi_open((seq)->seq_dbp->env, name, 1)); + +#define SEQ_ILLEGAL_BEFORE_OPEN(seq, name) \ + if (!SEQ_IS_OPEN(seq)) \ + return (__db_mi_open((seq)->seq_dbp->env, name, 0)); + +/* + * Flags to __db_chk_meta. + */ +#define DB_CHK_META 0x01 /* Checksum the meta page. */ +#define DB_CHK_NOLSN 0x02 /* Don't check the LSN. */ + +#if defined(__cplusplus) +} +#endif + +#include "dbinc/db_dispatch.h" +#include "dbinc_auto/db_auto.h" +#include "dbinc_auto/crdel_auto.h" +#include "dbinc_auto/db_ext.h" +#endif /* !_DB_AM_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db_cxx.in b/src/libs/resiprocate/contrib/db/dbinc/db_cxx.in new file mode 100644 index 00000000..0d0fd12d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db_cxx.in @@ -0,0 +1,1365 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_CXX_H_ +#define _DB_CXX_H_ +// +// C++ assumptions: +// +// To ensure portability to many platforms, both new and old, we make +// few assumptions about the C++ compiler and library. For example, +// we do not expect STL, templates or namespaces to be available. The +// "newest" C++ feature used is exceptions, which are used liberally +// to transmit error information. Even the use of exceptions can be +// disabled at runtime, to do so, use the DB_CXX_NO_EXCEPTIONS flags +// with the DbEnv or Db constructor. +// +// C++ naming conventions: +// +// - All top level class names start with Db. +// - All class members start with lower case letter. +// - All private data members are suffixed with underscore. +// - Use underscores to divide names into multiple words. +// - Simple data accessors are named with get_ or set_ prefix. +// - All method names are taken from names of functions in the C +// layer of db (usually by dropping a prefix like "db_"). +// These methods have the same argument types and order, +// other than dropping the explicit arg that acts as "this". +// +// As a rule, each DbFoo object has exactly one underlying DB_FOO struct +// (defined in db.h) associated with it. In some cases, we inherit directly +// from the DB_FOO structure to make this relationship explicit. Often, +// the underlying C layer allocates and deallocates these structures, so +// there is no easy way to add any data to the DbFoo class. When you see +// a comment about whether data is permitted to be added, this is what +// is going on. Of course, if we need to add data to such C++ classes +// in the future, we will arrange to have an indirect pointer to the +// DB_FOO struct (as some of the classes already have). +// + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +// +// Forward declarations +// + +#include + +@cxx_have_stdheaders@ +#ifdef HAVE_CXX_STDHEADERS +#include +#include +#define __DB_STD(x) std::x +#else +#include +#include +#define __DB_STD(x) x +#endif + +#include "db.h" + +class Db; // forward +class Dbc; // forward +class DbEnv; // forward +class DbInfo; // forward +class DbLock; // forward +class DbLogc; // forward +class DbLsn; // forward +class DbMpoolFile; // forward +class DbPreplist; // forward +class DbSequence; // forward +class Dbt; // forward +class DbTxn; // forward + +class DbMultipleIterator; // forward +class DbMultipleKeyDataIterator; // forward +class DbMultipleRecnoDataIterator; // forward +class DbMultipleDataIterator; // forward + +class DbException; // forward +class DbDeadlockException; // forward +class DbLockNotGrantedException; // forward +class DbMemoryException; // forward +class DbRepHandleDeadException; // forward +class DbRunRecoveryException; // forward + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +// +// Turn off inappropriate compiler warnings +// + +#ifdef _MSC_VER + +// These are level 4 warnings that are explicitly disabled. +// With Visual C++, by default you do not see above level 3 unless +// you use /W4. But we like to compile with the highest level +// warnings to catch other errors. +// +// 4201: nameless struct/union +// triggered by standard include file +// +// 4514: unreferenced inline function has been removed +// certain include files in MSVC define methods that are not called +// +#pragma warning(push) +#pragma warning(disable: 4201 4514) + +#endif + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +// +// Mechanisms for declaring classes +// + +// +// Every class defined in this file has an _exported next to the class name. +// This is needed for WinTel machines so that the class methods can +// be exported or imported in a DLL as appropriate. Users of the DLL +// use the define DB_USE_DLL. When the DLL is built, DB_CREATE_DLL +// must be defined. +// +#if defined(_MSC_VER) + +# if defined(DB_CREATE_DLL) +# define _exported __declspec(dllexport) // creator of dll +# elif defined(DB_USE_DLL) +# define _exported __declspec(dllimport) // user of dll +# else +# define _exported // static lib creator or user +# endif + +#else /* _MSC_VER */ + +# define _exported + +#endif /* _MSC_VER */ + +// Some interfaces can be customized by allowing users to define +// callback functions. For performance and logistical reasons, some +// callback functions must be declared in extern "C" blocks. For others, +// we allow you to declare the callbacks in C++ or C (or an extern "C" +// block) as you wish. See the set methods for the callbacks for +// the choices. +// +extern "C" { + typedef void * (*db_malloc_fcn_type) + (size_t); + typedef void * (*db_realloc_fcn_type) + (void *, size_t); + typedef void (*db_free_fcn_type) + (void *); + typedef int (*bt_compare_fcn_type) /*C++ version available*/ + (DB *, const DBT *, const DBT *); + typedef size_t (*bt_prefix_fcn_type) /*C++ version available*/ + (DB *, const DBT *, const DBT *); + typedef int (*dup_compare_fcn_type) /*C++ version available*/ + (DB *, const DBT *, const DBT *); + typedef int (*h_compare_fcn_type) /*C++ version available*/ + (DB *, const DBT *, const DBT *); + typedef u_int32_t (*h_hash_fcn_type) /*C++ version available*/ + (DB *, const void *, u_int32_t); + typedef int (*pgin_fcn_type) + (DB_ENV *dbenv, db_pgno_t pgno, void *pgaddr, DBT *pgcookie); + typedef int (*pgout_fcn_type) + (DB_ENV *dbenv, db_pgno_t pgno, void *pgaddr, DBT *pgcookie); +} + +// +// Represents a database table = a set of keys with associated values. +// +class _exported Db +{ + friend class DbEnv; + +public: + Db(DbEnv*, u_int32_t); // Create a Db object. + virtual ~Db(); // Calls close() if the user hasn't. + + // These methods exactly match those in the C interface. + // + virtual int associate(DbTxn *txn, Db *secondary, int (*callback) + (Db *, const Dbt *, const Dbt *, Dbt *), u_int32_t flags); + virtual int associate_foreign(Db *foreign, int (*callback) + (Db *, const Dbt *, Dbt *, const Dbt *, int *), u_int32_t flags); + virtual int close(u_int32_t flags); + virtual int compact(DbTxn *txnid, Dbt *start, + Dbt *stop, DB_COMPACT *c_data, u_int32_t flags, Dbt *end); + virtual int cursor(DbTxn *txnid, Dbc **cursorp, u_int32_t flags); + virtual int del(DbTxn *txnid, Dbt *key, u_int32_t flags); + virtual void err(int, const char *, ...); + virtual void errx(const char *, ...); + virtual int exists(DbTxn *txnid, Dbt *key, u_int32_t flags); + virtual int fd(int *fdp); + virtual int get(DbTxn *txnid, Dbt *key, Dbt *data, u_int32_t flags); + virtual int get_alloc( + db_malloc_fcn_type *, db_realloc_fcn_type *, db_free_fcn_type *); + virtual int get_append_recno(int (**)(Db *, Dbt *, db_recno_t)); + virtual int get_bt_compare(int (**)(Db *, const Dbt *, const Dbt *)); + virtual int get_bt_compress( + int (**)( + Db *, const Dbt *, const Dbt *, const Dbt *, const Dbt *, Dbt *), + int (**)(Db *, const Dbt *, const Dbt *, Dbt *, Dbt *, Dbt *)); + virtual int get_bt_minkey(u_int32_t *); + virtual int get_bt_prefix(size_t (**)(Db *, const Dbt *, const Dbt *)); + virtual int get_byteswapped(int *); + virtual int get_cachesize(u_int32_t *, u_int32_t *, int *); + virtual int get_create_dir(const char **); + virtual int get_dbname(const char **, const char **); + virtual int get_dup_compare(int (**)(Db *, const Dbt *, const Dbt *)); + virtual int get_encrypt_flags(u_int32_t *); + virtual void get_errcall( + void (**)(const DbEnv *, const char *, const char *)); + virtual void get_errfile(FILE **); + virtual void get_errpfx(const char **); + virtual int get_feedback(void (**)(Db *, int, int)); + virtual int get_flags(u_int32_t *); + virtual int get_h_compare(int (**)(Db *, const Dbt *, const Dbt *)); + virtual int get_h_ffactor(u_int32_t *); + virtual int get_h_hash(u_int32_t (**)(Db *, const void *, u_int32_t)); + virtual int get_h_nelem(u_int32_t *); + virtual int get_lorder(int *); + virtual void get_msgcall(void (**)(const DbEnv *, const char *)); + virtual void get_msgfile(FILE **); + virtual int get_multiple(); + virtual int get_open_flags(u_int32_t *); + virtual int get_pagesize(u_int32_t *); + virtual int get_partition_callback( + u_int32_t *, u_int32_t (**)(Db *, Dbt *key)); + virtual int get_partition_dirs(const char ***); + virtual int get_partition_keys(u_int32_t *, Dbt **); + virtual int get_priority(DB_CACHE_PRIORITY *); + virtual int get_q_extentsize(u_int32_t *); + virtual int get_re_delim(int *); + virtual int get_re_len(u_int32_t *); + virtual int get_re_pad(int *); + virtual int get_re_source(const char **); + virtual int get_transactional(); + virtual int get_type(DBTYPE *); + virtual int join(Dbc **curslist, Dbc **dbcp, u_int32_t flags); + virtual int key_range(DbTxn *, Dbt *, DB_KEY_RANGE *, u_int32_t); + virtual int open(DbTxn *txnid, + const char *, const char *subname, DBTYPE, u_int32_t, int); + virtual int pget(DbTxn *txnid, + Dbt *key, Dbt *pkey, Dbt *data, u_int32_t flags); + virtual int put(DbTxn *, Dbt *, Dbt *, u_int32_t); + virtual int remove(const char *, const char *, u_int32_t); + virtual int rename(const char *, const char *, const char *, u_int32_t); + virtual int set_alloc( + db_malloc_fcn_type, db_realloc_fcn_type, db_free_fcn_type); + virtual void set_app_private(void *); + virtual int set_append_recno(int (*)(Db *, Dbt *, db_recno_t)); + virtual int set_bt_compare(bt_compare_fcn_type); /*deprecated*/ + virtual int set_bt_compare(int (*)(Db *, const Dbt *, const Dbt *)); + virtual int set_bt_compress( + int (*) + (Db *, const Dbt *, const Dbt *, const Dbt *, const Dbt *, Dbt *), + int (*)(Db *, const Dbt *, const Dbt *, Dbt *, Dbt *, Dbt *)); + virtual int set_bt_minkey(u_int32_t); + virtual int set_bt_prefix(bt_prefix_fcn_type); /*deprecated*/ + virtual int set_bt_prefix(size_t (*)(Db *, const Dbt *, const Dbt *)); + virtual int set_cachesize(u_int32_t, u_int32_t, int); + virtual int set_create_dir(const char *); + virtual int set_dup_compare(dup_compare_fcn_type); /*deprecated*/ + virtual int set_dup_compare(int (*)(Db *, const Dbt *, const Dbt *)); + virtual int set_encrypt(const char *, u_int32_t); + virtual void set_errcall( + void (*)(const DbEnv *, const char *, const char *)); + virtual void set_errfile(FILE *); + virtual void set_errpfx(const char *); + virtual int set_feedback(void (*)(Db *, int, int)); + virtual int set_flags(u_int32_t); + virtual int set_h_compare(h_compare_fcn_type); /*deprecated*/ + virtual int set_h_compare(int (*)(Db *, const Dbt *, const Dbt *)); + virtual int set_h_ffactor(u_int32_t); + virtual int set_h_hash(h_hash_fcn_type); /*deprecated*/ + virtual int set_h_hash(u_int32_t (*)(Db *, const void *, u_int32_t)); + virtual int set_h_nelem(u_int32_t); + virtual int set_lorder(int); + virtual void set_msgcall(void (*)(const DbEnv *, const char *)); + virtual void set_msgfile(FILE *); + virtual int set_pagesize(u_int32_t); + virtual int set_paniccall(void (*)(DbEnv *, int)); + virtual int set_partition( + u_int32_t, Dbt *, u_int32_t (*)(Db *, Dbt *)); + virtual int set_partition_dirs(const char **); + virtual int set_priority(DB_CACHE_PRIORITY); + virtual int set_q_extentsize(u_int32_t); + virtual int set_re_delim(int); + virtual int set_re_len(u_int32_t); + virtual int set_re_pad(int); + virtual int set_re_source(const char *); + virtual int sort_multiple(Dbt *, Dbt *, u_int32_t); + virtual int stat(DbTxn *, void *sp, u_int32_t flags); + virtual int stat_print(u_int32_t flags); + virtual int sync(u_int32_t flags); + virtual int truncate(DbTxn *, u_int32_t *, u_int32_t); + virtual int upgrade(const char *name, u_int32_t flags); + virtual int verify( + const char *, const char *, __DB_STD(ostream) *, u_int32_t); + + // These additional methods are not in the C interface, and + // are only available for C++. + // + virtual void *get_app_private() const; + virtual __DB_STD(ostream) *get_error_stream(); + virtual void set_error_stream(__DB_STD(ostream) *); + virtual __DB_STD(ostream) *get_message_stream(); + virtual void set_message_stream(__DB_STD(ostream) *); + + virtual DbEnv *get_env(); + virtual DbMpoolFile *get_mpf(); + + virtual ENV *get_ENV() + { + return imp_->env; + } + + virtual DB *get_DB() + { + return imp_; + } + + virtual const DB *get_const_DB() const + { + return imp_; + } + + static Db* get_Db(DB *db) + { + return (Db *)db->api_internal; + } + + static const Db* get_const_Db(const DB *db) + { + return (const Db *)db->api_internal; + } + + u_int32_t get_create_flags() const + { + return construct_flags_; + } + +private: + // no copying + Db(const Db &); + Db &operator = (const Db &); + + void cleanup(); + int initialize(); + int error_policy(); + + // instance data + DB *imp_; + DbEnv *dbenv_; + DbMpoolFile *mpf_; + int construct_error_; + u_int32_t flags_; + u_int32_t construct_flags_; + +public: + // These are public only because they need to be called + // via C callback functions. They should never be used by + // external users of this class. + // + int (*append_recno_callback_)(Db *, Dbt *, db_recno_t); + int (*associate_callback_)(Db *, const Dbt *, const Dbt *, Dbt *); + int (*associate_foreign_callback_) + (Db *, const Dbt *, Dbt *, const Dbt *, int *); + int (*bt_compare_callback_)(Db *, const Dbt *, const Dbt *); + int (*bt_compress_callback_)( + Db *, const Dbt *, const Dbt *, const Dbt *, const Dbt *, Dbt *); + int (*bt_decompress_callback_)( + Db *, const Dbt *, const Dbt *, Dbt *, Dbt *, Dbt *); + size_t (*bt_prefix_callback_)(Db *, const Dbt *, const Dbt *); + u_int32_t (*db_partition_callback_)(Db *, Dbt *); + int (*dup_compare_callback_)(Db *, const Dbt *, const Dbt *); + void (*feedback_callback_)(Db *, int, int); + int (*h_compare_callback_)(Db *, const Dbt *, const Dbt *); + u_int32_t (*h_hash_callback_)(Db *, const void *, u_int32_t); +}; + +// +// Cursor +// +class _exported Dbc : protected DBC +{ + friend class Db; + +public: + int close(); + int cmp(Dbc *other_csr, int *result, u_int32_t flags); + int count(db_recno_t *countp, u_int32_t flags); + int del(u_int32_t flags); + int dup(Dbc** cursorp, u_int32_t flags); + int get(Dbt* key, Dbt *data, u_int32_t flags); + int get_priority(DB_CACHE_PRIORITY *priorityp); + int pget(Dbt* key, Dbt* pkey, Dbt *data, u_int32_t flags); + int put(Dbt* key, Dbt *data, u_int32_t flags); + int set_priority(DB_CACHE_PRIORITY priority); + +private: + // No data is permitted in this class (see comment at top) + + // Note: use Db::cursor() to get pointers to a Dbc, + // and call Dbc::close() rather than delete to release them. + // + Dbc(); + ~Dbc(); + + // no copying + Dbc(const Dbc &); + Dbc &operator = (const Dbc &); +}; + +// +// Berkeley DB environment class. Provides functions for opening databases. +// User of this library can use this class as a starting point for +// developing a DB application - derive their application class from +// this one, add application control logic. +// +// Note that if you use the default constructor, you must explicitly +// call appinit() before any other db activity (e.g. opening files) +// +class _exported DbEnv +{ + friend class Db; + friend class DbLock; + friend class DbMpoolFile; + +public: + // After using this constructor, you can set any needed + // parameters for the environment using the set_* methods. + // Then call open() to finish initializing the environment + // and attaching it to underlying files. + // + DbEnv(u_int32_t flags); + + virtual ~DbEnv(); + + // These methods match those in the C interface. + // + virtual int add_data_dir(const char *); + virtual int cdsgroup_begin(DbTxn **tid); + virtual int close(u_int32_t); + virtual int dbremove(DbTxn *txn, const char *name, const char *subdb, + u_int32_t flags); + virtual int dbrename(DbTxn *txn, const char *name, const char *subdb, + const char *newname, u_int32_t flags); + virtual void err(int, const char *, ...); + virtual void errx(const char *, ...); + virtual int failchk(u_int32_t); + virtual int fileid_reset(const char *, u_int32_t); + virtual int get_alloc(db_malloc_fcn_type *, db_realloc_fcn_type *, + db_free_fcn_type *); + virtual void *get_app_private() const; + virtual int get_home(const char **); + virtual int get_open_flags(u_int32_t *); + virtual int open(const char *, u_int32_t, int); + virtual int remove(const char *, u_int32_t); + virtual int stat_print(u_int32_t flags); + + virtual int set_alloc(db_malloc_fcn_type, db_realloc_fcn_type, + db_free_fcn_type); + virtual void set_app_private(void *); + virtual int get_cachesize(u_int32_t *, u_int32_t *, int *); + virtual int set_cachesize(u_int32_t, u_int32_t, int); + virtual int get_cache_max(u_int32_t *, u_int32_t *); + virtual int set_cache_max(u_int32_t, u_int32_t); + virtual int get_create_dir(const char **); + virtual int set_create_dir(const char *); + virtual int get_data_dirs(const char ***); + virtual int set_data_dir(const char *); + virtual int get_encrypt_flags(u_int32_t *); + virtual int get_intermediate_dir_mode(const char **); + virtual int set_intermediate_dir_mode(const char *); + virtual int get_isalive( + int (**)(DbEnv *, pid_t, db_threadid_t, u_int32_t)); + virtual int set_isalive( + int (*)(DbEnv *, pid_t, db_threadid_t, u_int32_t)); + virtual int set_encrypt(const char *, u_int32_t); + virtual void get_errcall( + void (**)(const DbEnv *, const char *, const char *)); + virtual void set_errcall( + void (*)(const DbEnv *, const char *, const char *)); + virtual void get_errfile(FILE **); + virtual void set_errfile(FILE *); + virtual void get_errpfx(const char **); + virtual void set_errpfx(const char *); + virtual int set_event_notify(void (*)(DbEnv *, u_int32_t, void *)); + virtual int get_flags(u_int32_t *); + virtual int set_flags(u_int32_t, int); + virtual bool is_bigendian(); + virtual int lsn_reset(const char *, u_int32_t); + virtual int get_feedback(void (**)(DbEnv *, int, int)); + virtual int set_feedback(void (*)(DbEnv *, int, int)); + virtual int get_lg_bsize(u_int32_t *); + virtual int set_lg_bsize(u_int32_t); + virtual int get_lg_dir(const char **); + virtual int set_lg_dir(const char *); + virtual int get_lg_filemode(int *); + virtual int set_lg_filemode(int); + virtual int get_lg_max(u_int32_t *); + virtual int set_lg_max(u_int32_t); + virtual int get_lg_regionmax(u_int32_t *); + virtual int set_lg_regionmax(u_int32_t); + virtual int get_lk_conflicts(const u_int8_t **, int *); + virtual int set_lk_conflicts(u_int8_t *, int); + virtual int get_lk_detect(u_int32_t *); + virtual int set_lk_detect(u_int32_t); + virtual int get_lk_max_lockers(u_int32_t *); + virtual int set_lk_max_lockers(u_int32_t); + virtual int get_lk_max_locks(u_int32_t *); + virtual int set_lk_max_locks(u_int32_t); + virtual int get_lk_max_objects(u_int32_t *); + virtual int set_lk_max_objects(u_int32_t); + virtual int get_lk_partitions(u_int32_t *); + virtual int set_lk_partitions(u_int32_t); + virtual int get_mp_mmapsize(size_t *); + virtual int set_mp_mmapsize(size_t); + virtual int get_mp_max_openfd(int *); + virtual int set_mp_max_openfd(int); + virtual int get_mp_max_write(int *, db_timeout_t *); + virtual int set_mp_max_write(int, db_timeout_t); + virtual int get_mp_pagesize(u_int32_t *); + virtual int set_mp_pagesize(u_int32_t); + virtual int get_mp_tablesize(u_int32_t *); + virtual int set_mp_tablesize(u_int32_t); + virtual void get_msgcall(void (**)(const DbEnv *, const char *)); + virtual void set_msgcall(void (*)(const DbEnv *, const char *)); + virtual void get_msgfile(FILE **); + virtual void set_msgfile(FILE *); + virtual int set_paniccall(void (*)(DbEnv *, int)); + virtual int set_rpc_server(void *, char *, long, long, u_int32_t); + virtual int get_shm_key(long *); + virtual int set_shm_key(long); + virtual int get_timeout(db_timeout_t *, u_int32_t); + virtual int set_timeout(db_timeout_t, u_int32_t); + virtual int get_tmp_dir(const char **); + virtual int set_tmp_dir(const char *); + virtual int get_tx_max(u_int32_t *); + virtual int set_tx_max(u_int32_t); + virtual int get_app_dispatch( + int (**)(DbEnv *, Dbt *, DbLsn *, db_recops)); + virtual int set_app_dispatch(int (*)(DbEnv *, + Dbt *, DbLsn *, db_recops)); + virtual int get_tx_timestamp(time_t *); + virtual int set_tx_timestamp(time_t *); + virtual int get_verbose(u_int32_t which, int *); + virtual int set_verbose(u_int32_t which, int); + + // Version information. A static method so it can be obtained anytime. + // + static char *version(int *major, int *minor, int *patch); + + // Convert DB errors to strings + static char *strerror(int); + + // If an error is detected and the error call function + // or stream is set, a message is dispatched or printed. + // If a prefix is set, each message is prefixed. + // + // You can use set_errcall() or set_errfile() above to control + // error functionality. Alternatively, you can call + // set_error_stream() to force all errors to a C++ stream. + // It is unwise to mix these approaches. + // + virtual __DB_STD(ostream) *get_error_stream(); + virtual void set_error_stream(__DB_STD(ostream) *); + virtual __DB_STD(ostream) *get_message_stream(); + virtual void set_message_stream(__DB_STD(ostream) *); + + // used internally + static void runtime_error(DbEnv *dbenv, const char *caller, int err, + int error_policy); + static void runtime_error_dbt(DbEnv *dbenv, const char *caller, Dbt *dbt, + int error_policy); + static void runtime_error_lock_get(DbEnv *dbenv, const char *caller, + int err, db_lockop_t op, db_lockmode_t mode, + Dbt *obj, DbLock lock, int index, + int error_policy); + + // Lock functions + // + virtual int lock_detect(u_int32_t flags, u_int32_t atype, int *aborted); + virtual int lock_get(u_int32_t locker, u_int32_t flags, Dbt *obj, + db_lockmode_t lock_mode, DbLock *lock); + virtual int lock_id(u_int32_t *idp); + virtual int lock_id_free(u_int32_t id); + virtual int lock_put(DbLock *lock); + virtual int lock_stat(DB_LOCK_STAT **statp, u_int32_t flags); + virtual int lock_stat_print(u_int32_t flags); + virtual int lock_vec(u_int32_t locker, u_int32_t flags, + DB_LOCKREQ list[], int nlist, DB_LOCKREQ **elistp); + + // Log functions + // + virtual int log_archive(char **list[], u_int32_t flags); + static int log_compare(const DbLsn *lsn0, const DbLsn *lsn1); + virtual int log_cursor(DbLogc **cursorp, u_int32_t flags); + virtual int log_file(DbLsn *lsn, char *namep, size_t len); + virtual int log_flush(const DbLsn *lsn); + virtual int log_get_config(u_int32_t, int *); + virtual int log_put(DbLsn *lsn, const Dbt *data, u_int32_t flags); + virtual int log_printf(DbTxn *, const char *, ...); + virtual int log_set_config(u_int32_t, int); + virtual int log_stat(DB_LOG_STAT **spp, u_int32_t flags); + virtual int log_stat_print(u_int32_t flags); + + // Mpool functions + // + virtual int memp_fcreate(DbMpoolFile **dbmfp, u_int32_t flags); + virtual int memp_register(int ftype, + pgin_fcn_type pgin_fcn, + pgout_fcn_type pgout_fcn); + virtual int memp_stat(DB_MPOOL_STAT + **gsp, DB_MPOOL_FSTAT ***fsp, u_int32_t flags); + virtual int memp_stat_print(u_int32_t flags); + virtual int memp_sync(DbLsn *lsn); + virtual int memp_trickle(int pct, int *nwrotep); + + // Mpool functions + // + virtual int mutex_alloc(u_int32_t, db_mutex_t *); + virtual int mutex_free(db_mutex_t); + virtual int mutex_get_align(u_int32_t *); + virtual int mutex_get_increment(u_int32_t *); + virtual int mutex_get_max(u_int32_t *); + virtual int mutex_get_tas_spins(u_int32_t *); + virtual int mutex_lock(db_mutex_t); + virtual int mutex_set_align(u_int32_t); + virtual int mutex_set_increment(u_int32_t); + virtual int mutex_set_max(u_int32_t); + virtual int mutex_set_tas_spins(u_int32_t); + virtual int mutex_stat(DB_MUTEX_STAT **, u_int32_t); + virtual int mutex_stat_print(u_int32_t); + virtual int mutex_unlock(db_mutex_t); + + // Transaction functions + // + virtual int txn_begin(DbTxn *pid, DbTxn **tid, u_int32_t flags); + virtual int txn_checkpoint(u_int32_t kbyte, u_int32_t min, + u_int32_t flags); + virtual int txn_recover(DbPreplist *preplist, u_int32_t count, + u_int32_t *retp, u_int32_t flags); + virtual int txn_stat(DB_TXN_STAT **statp, u_int32_t flags); + virtual int txn_stat_print(u_int32_t flags); + + // Replication functions + // + virtual int rep_elect(u_int32_t, u_int32_t, u_int32_t); + virtual int rep_flush(); + virtual int rep_process_message(Dbt *, Dbt *, int, DbLsn *); + virtual int rep_start(Dbt *, u_int32_t); + virtual int rep_stat(DB_REP_STAT **statp, u_int32_t flags); + virtual int rep_stat_print(u_int32_t flags); + virtual int rep_get_clockskew(u_int32_t *, u_int32_t *); + virtual int rep_set_clockskew(u_int32_t, u_int32_t); + virtual int rep_get_limit(u_int32_t *, u_int32_t *); + virtual int rep_set_limit(u_int32_t, u_int32_t); + virtual int rep_set_transport(int, int (*)(DbEnv *, + const Dbt *, const Dbt *, const DbLsn *, int, u_int32_t)); + virtual int rep_set_request(u_int32_t, u_int32_t); + virtual int rep_get_request(u_int32_t *, u_int32_t *); + virtual int get_thread_count(u_int32_t *); + virtual int set_thread_count(u_int32_t); + virtual int get_thread_id_fn( + void (**)(DbEnv *, pid_t *, db_threadid_t *)); + virtual int set_thread_id(void (*)(DbEnv *, pid_t *, db_threadid_t *)); + virtual int get_thread_id_string_fn( + char *(**)(DbEnv *, pid_t, db_threadid_t, char *)); + virtual int set_thread_id_string(char *(*)(DbEnv *, + pid_t, db_threadid_t, char *)); + virtual int rep_set_config(u_int32_t, int); + virtual int rep_get_config(u_int32_t, int *); + virtual int rep_sync(u_int32_t flags); + + // Advanced replication functions + // + virtual int rep_get_nsites(u_int32_t *n); + virtual int rep_set_nsites(u_int32_t n); + virtual int rep_get_priority(u_int32_t *priorityp); + virtual int rep_set_priority(u_int32_t priority); + virtual int rep_get_timeout(int which, db_timeout_t *timeout); + virtual int rep_set_timeout(int which, db_timeout_t timeout); + virtual int repmgr_add_remote_site(const char * host, u_int16_t port, + int *eidp, u_int32_t flags); + virtual int repmgr_get_ack_policy(int *policy); + virtual int repmgr_set_ack_policy(int policy); + virtual int repmgr_set_local_site(const char * host, u_int16_t port, + u_int32_t flags); + virtual int repmgr_site_list(u_int *countp, DB_REPMGR_SITE **listp); + virtual int repmgr_start(int nthreads, u_int32_t flags); + virtual int repmgr_stat(DB_REPMGR_STAT **statp, u_int32_t flags); + virtual int repmgr_stat_print(u_int32_t flags); + + // Conversion functions + // + virtual ENV *get_ENV() + { + return imp_->env; + } + + virtual DB_ENV *get_DB_ENV() + { + return imp_; + } + + virtual const DB_ENV *get_const_DB_ENV() const + { + return imp_; + } + + static DbEnv* get_DbEnv(DB_ENV *dbenv) + { + return dbenv ? (DbEnv *)dbenv->api1_internal : 0; + } + + static const DbEnv* get_const_DbEnv(const DB_ENV *dbenv) + { + return dbenv ? (const DbEnv *)dbenv->api1_internal : 0; + } + + u_int32_t get_create_flags() const + { + return construct_flags_; + } + + // For internal use only. + static DbEnv* wrap_DB_ENV(DB_ENV *dbenv); + + // These are public only because they need to be called + // via C functions. They should never be called by users + // of this class. + // + static int _app_dispatch_intercept(DB_ENV *dbenv, DBT *dbt, DB_LSN *lsn, + db_recops op); + static void _paniccall_intercept(DB_ENV *dbenv, int errval); + static void _feedback_intercept(DB_ENV *dbenv, int opcode, int pct); + static void _event_func_intercept(DB_ENV *dbenv, u_int32_t, void *); + static int _isalive_intercept(DB_ENV *dbenv, pid_t pid, + db_threadid_t thrid, u_int32_t flags); + static int _rep_send_intercept(DB_ENV *dbenv, const DBT *cntrl, + const DBT *data, const DB_LSN *lsn, int id, u_int32_t flags); + static void _stream_error_function(const DB_ENV *dbenv, + const char *prefix, const char *message); + static void _stream_message_function(const DB_ENV *dbenv, + const char *message); + static void _thread_id_intercept(DB_ENV *dbenv, pid_t *pidp, + db_threadid_t *thridp); + static char *_thread_id_string_intercept(DB_ENV *dbenv, pid_t pid, + db_threadid_t thrid, char *buf); + +private: + void cleanup(); + int initialize(DB_ENV *dbenv); + int error_policy(); + + // For internal use only. + DbEnv(DB_ENV *, u_int32_t flags); + + // no copying + DbEnv(const DbEnv &); + void operator = (const DbEnv &); + + // instance data + DB_ENV *imp_; + int construct_error_; + u_int32_t construct_flags_; + __DB_STD(ostream) *error_stream_; + __DB_STD(ostream) *message_stream_; + + int (*app_dispatch_callback_)(DbEnv *, Dbt *, DbLsn *, db_recops); + int (*isalive_callback_)(DbEnv *, pid_t, db_threadid_t, u_int32_t); + void (*error_callback_)(const DbEnv *, const char *, const char *); + void (*feedback_callback_)(DbEnv *, int, int); + void (*message_callback_)(const DbEnv *, const char *); + void (*paniccall_callback_)(DbEnv *, int); + void (*event_func_callback_)(DbEnv *, u_int32_t, void *); + int (*rep_send_callback_)(DbEnv *, const Dbt *, const Dbt *, + const DbLsn *, int, u_int32_t); + void (*thread_id_callback_)(DbEnv *, pid_t *, db_threadid_t *); + char *(*thread_id_string_callback_)(DbEnv *, pid_t, db_threadid_t, + char *); +}; + +// +// Lock +// +class _exported DbLock +{ + friend class DbEnv; + +public: + DbLock(); + DbLock(const DbLock &); + DbLock &operator = (const DbLock &); + +protected: + // We can add data to this class if needed + // since its contained class is not allocated by db. + // (see comment at top) + + DbLock(DB_LOCK); + DB_LOCK lock_; +}; + +// +// Log cursor +// +class _exported DbLogc : protected DB_LOGC +{ + friend class DbEnv; + +public: + int close(u_int32_t _flags); + int get(DbLsn *lsn, Dbt *data, u_int32_t _flags); + int version(u_int32_t *versionp, u_int32_t _flags); + +private: + // No data is permitted in this class (see comment at top) + + // Note: use Db::cursor() to get pointers to a Dbc, + // and call Dbc::close() rather than delete to release them. + // + DbLogc(); + ~DbLogc(); + + // no copying + DbLogc(const Dbc &); + DbLogc &operator = (const Dbc &); +}; + +// +// Log sequence number +// +class _exported DbLsn : public DB_LSN +{ + friend class DbEnv; // friendship needed to cast to base class + friend class DbLogc; // friendship needed to cast to base class +}; + +// +// Memory pool file +// +class _exported DbMpoolFile +{ + friend class DbEnv; + friend class Db; + +public: + int close(u_int32_t flags); + int get(db_pgno_t *pgnoaddr, DbTxn *txn, u_int32_t flags, void *pagep); + int get_clear_len(u_int32_t *len); + int get_fileid(u_int8_t *fileid); + int get_flags(u_int32_t *flagsp); + int get_ftype(int *ftype); + int get_last_pgno(db_pgno_t *pgnop); + int get_lsn_offset(int32_t *offsetp); + int get_maxsize(u_int32_t *gbytes, u_int32_t *bytes); + int get_pgcookie(DBT *dbt); + int get_priority(DB_CACHE_PRIORITY *priorityp); + int get_transactional(void); + int open(const char *file, u_int32_t flags, int mode, size_t pagesize); + int put(void *pgaddr, DB_CACHE_PRIORITY priority, u_int32_t flags); + int set_clear_len(u_int32_t len); + int set_fileid(u_int8_t *fileid); + int set_flags(u_int32_t flags, int onoff); + int set_ftype(int ftype); + int set_lsn_offset(int32_t offset); + int set_maxsize(u_int32_t gbytes, u_int32_t bytes); + int set_pgcookie(DBT *dbt); + int set_priority(DB_CACHE_PRIORITY priority); + int sync(); + + virtual DB_MPOOLFILE *get_DB_MPOOLFILE() + { + return imp_; + } + + virtual const DB_MPOOLFILE *get_const_DB_MPOOLFILE() const + { + return imp_; + } + +private: + DB_MPOOLFILE *imp_; + + // We can add data to this class if needed + // since it is implemented via a pointer. + // (see comment at top) + + // Note: use DbEnv::memp_fcreate() to get pointers to a DbMpoolFile, + // and call DbMpoolFile::close() rather than delete to release them. + // + DbMpoolFile(); + + // Shut g++ up. +protected: + virtual ~DbMpoolFile(); + +private: + // no copying + DbMpoolFile(const DbMpoolFile &); + void operator = (const DbMpoolFile &); +}; + +// +// This is filled in and returned by the DbEnv::txn_recover() method. +// +class _exported DbPreplist +{ +public: + DbTxn *txn; + u_int8_t gid[DB_GID_SIZE]; +}; + +// +// A sequence record in a database +// +class _exported DbSequence +{ +public: + DbSequence(Db *db, u_int32_t flags); + virtual ~DbSequence(); + + int open(DbTxn *txnid, Dbt *key, u_int32_t flags); + int initial_value(db_seq_t value); + int close(u_int32_t flags); + int remove(DbTxn *txnid, u_int32_t flags); + int stat(DB_SEQUENCE_STAT **sp, u_int32_t flags); + int stat_print(u_int32_t flags); + + int get(DbTxn *txnid, int32_t delta, db_seq_t *retp, u_int32_t flags); + int get_cachesize(int32_t *sizep); + int set_cachesize(int32_t size); + int get_flags(u_int32_t *flagsp); + int set_flags(u_int32_t flags); + int get_range(db_seq_t *minp, db_seq_t *maxp); + int set_range(db_seq_t min, db_seq_t max); + + Db *get_db(); + Dbt *get_key(); + + virtual DB_SEQUENCE *get_DB_SEQUENCE() + { + return imp_; + } + + virtual const DB_SEQUENCE *get_const_DB_SEQUENCE() const + { + return imp_; + } + + static DbSequence* get_DbSequence(DB_SEQUENCE *seq) + { + return (DbSequence *)seq->api_internal; + } + + static const DbSequence* get_const_DbSequence(const DB_SEQUENCE *seq) + { + return (const DbSequence *)seq->api_internal; + } + + // For internal use only. + static DbSequence* wrap_DB_SEQUENCE(DB_SEQUENCE *seq); + +private: + DbSequence(DB_SEQUENCE *seq); + // no copying + DbSequence(const DbSequence &); + DbSequence &operator = (const DbSequence &); + + DB_SEQUENCE *imp_; + DBT key_; +}; + +// +// Transaction +// +class _exported DbTxn +{ + friend class DbEnv; + +public: + int abort(); + int commit(u_int32_t flags); + int discard(u_int32_t flags); + u_int32_t id(); + int get_name(const char **namep); + int prepare(u_int8_t *gid); + int set_name(const char *name); + int set_timeout(db_timeout_t timeout, u_int32_t flags); + + virtual DB_TXN *get_DB_TXN() + { + return imp_; + } + + virtual const DB_TXN *get_const_DB_TXN() const + { + return imp_; + } + + static DbTxn* get_DbTxn(DB_TXN *txn) + { + return (DbTxn *)txn->api_internal; + } + + static const DbTxn* get_const_DbTxn(const DB_TXN *txn) + { + return (const DbTxn *)txn->api_internal; + } + + // For internal use only. + static DbTxn* wrap_DB_TXN(DB_TXN *txn); + void remove_child_txn(DbTxn *kid); + void add_child_txn(DbTxn *kid); + + void set_parent(DbTxn *ptxn) + { + parent_txn_ = ptxn; + } + +private: + DB_TXN *imp_; + + // We use a TAILQ to store this object's kids of DbTxn objects, and + // each kid has a "parent_txn_" to point to this DbTxn object. + // + // If imp_ has a parent transaction which is not wrapped by DbTxn + // class, parent_txn_ will be NULL since we don't need to maintain + // this parent-kid relationship. This relationship only helps to + // delete unresolved kids when the parent is resolved. + DbTxn *parent_txn_; + + // We can add data to this class if needed + // since it is implemented via a pointer. + // (see comment at top) + + // Note: use DbEnv::txn_begin() to get pointers to a DbTxn, + // and call DbTxn::abort() or DbTxn::commit rather than + // delete to release them. + // + DbTxn(DbTxn *ptxn); + // For internal use only. + DbTxn(DB_TXN *txn, DbTxn *ptxn); + virtual ~DbTxn(); + + // no copying + DbTxn(const DbTxn &); + void operator = (const DbTxn &); + + /* + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_HEAD(__children, DbTxn) children; + */ + struct __children { + DbTxn *tqh_first; + DbTxn **tqh_last; + } children; + + /* + * !!! + * Explicit representations of structures from queue.h. + * TAILQ_ENTRY(DbTxn) child_entry; + */ + struct { + DbTxn *tqe_next; + DbTxn **tqe_prev; + } child_entry; +}; + +// +// A chunk of data, maybe a key or value. +// +class _exported Dbt : private DBT +{ + friend class Db; + friend class Dbc; + friend class DbEnv; + friend class DbLogc; + friend class DbSequence; + +public: + // key/data + void *get_data() const { return data; } + void set_data(void *value) { data = value; } + + // key/data length + u_int32_t get_size() const { return size; } + void set_size(u_int32_t value) { size = value; } + + // RO: length of user buffer. + u_int32_t get_ulen() const { return ulen; } + void set_ulen(u_int32_t value) { ulen = value; } + + // RO: get/put record length. + u_int32_t get_dlen() const { return dlen; } + void set_dlen(u_int32_t value) { dlen = value; } + + // RO: get/put record offset. + u_int32_t get_doff() const { return doff; } + void set_doff(u_int32_t value) { doff = value; } + + // flags + u_int32_t get_flags() const { return flags; } + void set_flags(u_int32_t value) { flags = value; } + + // Conversion functions + DBT *get_DBT() { return (DBT *)this; } + const DBT *get_const_DBT() const { return (const DBT *)this; } + + static Dbt* get_Dbt(DBT *dbt) { return (Dbt *)dbt; } + static const Dbt* get_const_Dbt(const DBT *dbt) + { return (const Dbt *)dbt; } + + Dbt(void *data, u_int32_t size); + Dbt(); + ~Dbt(); + Dbt(const Dbt &); + Dbt &operator = (const Dbt &); + +private: + // Note: no extra data appears in this class (other than + // inherited from DBT) since we need DBT and Dbt objects + // to have interchangable pointers. + // + // When subclassing this class, remember that callback + // methods like bt_compare, bt_prefix, dup_compare may + // internally manufacture DBT objects (which later are + // cast to Dbt), so such callbacks might receive objects + // not of your subclassed type. +}; + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +// +// multiple key/data/recno iterator classes +// + +// DbMultipleIterator is a shared private base class for the three types +// of bulk-return Iterator; it should never be instantiated directly, +// but it handles the functionality shared by its subclasses. +class _exported DbMultipleIterator +{ +public: + DbMultipleIterator(const Dbt &dbt); +protected: + u_int8_t *data_; + u_int32_t *p_; +}; + +class _exported DbMultipleKeyDataIterator : private DbMultipleIterator +{ +public: + DbMultipleKeyDataIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {} + bool next(Dbt &key, Dbt &data); +}; + +class _exported DbMultipleRecnoDataIterator : private DbMultipleIterator +{ +public: + DbMultipleRecnoDataIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {} + bool next(db_recno_t &recno, Dbt &data); +}; + +class _exported DbMultipleDataIterator : private DbMultipleIterator +{ +public: + DbMultipleDataIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {} + bool next(Dbt &data); +}; + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +// +// multiple key/data/recno builder classes +// + +// DbMultipleBuilder is a shared private base class for the three types +// of bulk buffer builders; it should never be instantiated directly, +// but it handles the functionality shared by its subclasses. +class _exported DbMultipleBuilder +{ +public: + DbMultipleBuilder(Dbt &dbt); +protected: + Dbt &dbt_; + void *p_; +}; + +class _exported DbMultipleDataBuilder : DbMultipleBuilder +{ +public: + DbMultipleDataBuilder(Dbt &dbt) : DbMultipleBuilder(dbt) {} + bool append(void *dbuf, size_t dlen); + bool reserve(void *&ddest, size_t dlen); +}; + +class _exported DbMultipleKeyDataBuilder : DbMultipleBuilder +{ +public: + DbMultipleKeyDataBuilder(Dbt &dbt) : DbMultipleBuilder(dbt) {} + bool append(void *kbuf, size_t klen, void *dbuf, size_t dlen); + bool reserve(void *&kdest, size_t klen, void *&ddest, size_t dlen); +}; + +class _exported DbMultipleRecnoDataBuilder +{ +public: + DbMultipleRecnoDataBuilder(Dbt &dbt); + bool append(db_recno_t recno, void *dbuf, size_t dlen); + bool reserve(db_recno_t recno, void *&ddest, size_t dlen); +protected: + Dbt &dbt_; + void *p_; +}; + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +// +// Exception classes +// + +// Almost any error in the DB library throws a DbException. +// Every exception should be considered an abnormality +// (e.g. bug, misuse of DB, file system error). +// +class _exported DbException : public __DB_STD(exception) +{ +public: + virtual ~DbException() throw(); + DbException(int err); + DbException(const char *description); + DbException(const char *description, int err); + DbException(const char *prefix, const char *description, int err); + int get_errno() const; + virtual const char *what() const throw(); + DbEnv *get_env() const; + void set_env(DbEnv *dbenv); + + DbException(const DbException &); + DbException &operator = (const DbException &); + +private: + void describe(const char *prefix, const char *description); + + char *what_; + int err_; // errno + DbEnv *dbenv_; +}; + +// +// A specific sort of exception that occurs when +// an operation is aborted to resolve a deadlock. +// +class _exported DbDeadlockException : public DbException +{ +public: + virtual ~DbDeadlockException() throw(); + DbDeadlockException(const char *description); + + DbDeadlockException(const DbDeadlockException &); + DbDeadlockException &operator = (const DbDeadlockException &); +}; + +// +// A specific sort of exception that occurs when +// a lock is not granted, e.g. by lock_get or lock_vec. +// Note that the Dbt is only live as long as the Dbt used +// in the offending call. +// +class _exported DbLockNotGrantedException : public DbException +{ +public: + virtual ~DbLockNotGrantedException() throw(); + DbLockNotGrantedException(const char *prefix, db_lockop_t op, + db_lockmode_t mode, const Dbt *obj, const DbLock lock, int index); + DbLockNotGrantedException(const char *description); + + DbLockNotGrantedException(const DbLockNotGrantedException &); + DbLockNotGrantedException &operator = + (const DbLockNotGrantedException &); + + db_lockop_t get_op() const; + db_lockmode_t get_mode() const; + const Dbt* get_obj() const; + DbLock *get_lock() const; + int get_index() const; + +private: + db_lockop_t op_; + db_lockmode_t mode_; + const Dbt *obj_; + DbLock *lock_; + int index_; +}; + +// +// A specific sort of exception that occurs when +// user declared memory is insufficient in a Dbt. +// +class _exported DbMemoryException : public DbException +{ +public: + virtual ~DbMemoryException() throw(); + DbMemoryException(Dbt *dbt); + DbMemoryException(const char *prefix, Dbt *dbt); + + DbMemoryException(const DbMemoryException &); + DbMemoryException &operator = (const DbMemoryException &); + + Dbt *get_dbt() const; +private: + Dbt *dbt_; +}; + +// +// A specific sort of exception that occurs when a change of replication +// master requires that all handles be re-opened. +// +class _exported DbRepHandleDeadException : public DbException +{ +public: + virtual ~DbRepHandleDeadException() throw(); + DbRepHandleDeadException(const char *description); + + DbRepHandleDeadException(const DbRepHandleDeadException &); + DbRepHandleDeadException &operator = (const DbRepHandleDeadException &); +}; + +// +// A specific sort of exception that occurs when +// recovery is required before continuing DB activity. +// +class _exported DbRunRecoveryException : public DbException +{ +public: + virtual ~DbRunRecoveryException() throw(); + DbRunRecoveryException(const char *description); + + DbRunRecoveryException(const DbRunRecoveryException &); + DbRunRecoveryException &operator = (const DbRunRecoveryException &); +}; + +// +// A specific sort of exception that occurs when + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +// +// Restore default compiler warnings +// +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif /* !_DB_CXX_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db_dispatch.h b/src/libs/resiprocate/contrib/db/dbinc/db_dispatch.h new file mode 100644 index 00000000..91f83e6f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db_dispatch.h @@ -0,0 +1,97 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1995, 1996 + * The President and Fellows of Harvard University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef _DB_DISPATCH_H_ +#define _DB_DISPATCH_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Declarations and typedefs for the list of transaction IDs used during + * recovery. This is a generic list used to pass along whatever information + * we need during recovery. + */ +typedef enum { + TXNLIST_DELETE, + TXNLIST_LSN, + TXNLIST_TXNID +} db_txnlist_type; + +#define DB_TXNLIST_MASK(hp, n) (n % hp->nslots) +struct __db_txnhead { + void *td; /* If abort, the detail for the txn. */ + DB_THREAD_INFO *thread_info; /* Thread information. */ + u_int32_t maxid; /* Maximum transaction id. */ + DB_LSN maxlsn; /* Maximum commit lsn. */ + DB_LSN ckplsn; /* LSN of last retained checkpoint. */ + DB_LSN trunc_lsn; /* Lsn to which we are going to truncate; + * make sure we abort anyone after this. */ + u_int32_t generation; /* Current generation number. */ + u_int32_t gen_alloc; /* Number of generations allocated. */ + struct { + u_int32_t generation; + u_int32_t txn_min; + u_int32_t txn_max; + } *gen_array; /* Array of txnids associated with a gen. */ + u_int nslots; + LIST_HEAD(__db_headlink, __db_txnlist) head[1]; +}; + +#define DB_LSN_STACK_SIZE 4 +struct __db_txnlist { + db_txnlist_type type; + LIST_ENTRY(__db_txnlist) links; + union { + struct { + u_int32_t txnid; + u_int32_t generation; + u_int32_t status; + } t; + struct { + u_int32_t stack_size; + u_int32_t stack_indx; + DB_LSN *lsn_stack; + } l; + } u; +}; + +#if defined(__cplusplus) +} +#endif + +#endif /* !_DB_DISPATCH_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db_int.in b/src/libs/resiprocate/contrib/db/dbinc/db_int.in new file mode 100644 index 00000000..744f9cf5 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db_int.in @@ -0,0 +1,933 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_INT_H_ +#define _DB_INT_H_ + +/******************************************************* + * Berkeley DB ANSI/POSIX include files. + *******************************************************/ +#ifdef HAVE_SYSTEM_INCLUDE_FILES +#include +#ifdef DIAG_MVCC +#include +#endif +#include + +#if defined(__INCLUDE_SELECT_H) +#ifdef HAVE_SYS_SELECT_H +#include +#endif +#ifdef HAVE_VXWORKS +#include +#endif +#endif + +#if TIME_WITH_SYS_TIME +#include +#include +#else +#if HAVE_SYS_TIME_H +#include +#else +#include +#endif +#endif + +#ifdef HAVE_VXWORKS +#include +#else +#include +#endif + +#if defined(__INCLUDE_NETWORKING) +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#include +#include +#include +#endif + +#if defined(STDC_HEADERS) || defined(__cplusplus) +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__INCLUDE_DIRECTORY) +#if HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +#endif +#endif /* __INCLUDE_DIRECTORY */ + +#endif /* !HAVE_SYSTEM_INCLUDE_FILES */ + +#ifdef DB_WIN32 +#include "dbinc/win_db.h" +#endif + +#include "db.h" +#include "clib_port.h" + +#include "dbinc/queue.h" +#include "dbinc/shqueue.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************* + * Forward structure declarations. + *******************************************************/ +struct __db_reginfo_t; typedef struct __db_reginfo_t REGINFO; +struct __db_txnhead; typedef struct __db_txnhead DB_TXNHEAD; +struct __db_txnlist; typedef struct __db_txnlist DB_TXNLIST; +struct __vrfy_childinfo;typedef struct __vrfy_childinfo VRFY_CHILDINFO; +struct __vrfy_dbinfo; typedef struct __vrfy_dbinfo VRFY_DBINFO; +struct __vrfy_pageinfo; typedef struct __vrfy_pageinfo VRFY_PAGEINFO; + +typedef SH_TAILQ_HEAD(__hash_head) DB_HASHTAB; + +/******************************************************* + * General purpose constants and macros. + *******************************************************/ +#undef FALSE +#define FALSE 0 +#undef TRUE +#define TRUE (!FALSE) + +#define MEGABYTE 1048576 +#define GIGABYTE 1073741824 + +#define NS_PER_MS 1000000 /* Nanoseconds in a millisecond */ +#define NS_PER_US 1000 /* Nanoseconds in a microsecond */ +#define NS_PER_SEC 1000000000 /* Nanoseconds in a second */ +#define US_PER_MS 1000 /* Microseconds in a millisecond */ +#define US_PER_SEC 1000000 /* Microseconds in a second */ +#define MS_PER_SEC 1000 /* Milliseconds in a second */ + +#define RECNO_OOB 0 /* Illegal record number. */ + +/* Test for a power-of-two (tests true for zero, which doesn't matter here). */ +#define POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0) + +/* Test for valid page sizes. */ +#define DB_MIN_PGSIZE 0x000200 /* Minimum page size (512). */ +#define DB_MAX_PGSIZE 0x010000 /* Maximum page size (65536). */ +#define IS_VALID_PAGESIZE(x) \ + (POWER_OF_TWO(x) && (x) >= DB_MIN_PGSIZE && ((x) <= DB_MAX_PGSIZE)) + +/* Minimum number of pages cached, by default. */ +#define DB_MINPAGECACHE 16 + +/* + * If we are unable to determine the underlying filesystem block size, use + * 8K on the grounds that most OS's use less than 8K for a VM page size. + */ +#define DB_DEF_IOSIZE (8 * 1024) + +/* Align an integer to a specific boundary. */ +#undef DB_ALIGN +#define DB_ALIGN(v, bound) \ + (((v) + (bound) - 1) & ~(((uintmax_t)(bound)) - 1)) + +/* Increment a pointer to a specific boundary. */ +#undef ALIGNP_INC +#define ALIGNP_INC(p, bound) \ + (void *)(((uintptr_t)(p) + (bound) - 1) & ~(((uintptr_t)(bound)) - 1)) + +/* + * Print an address as a u_long (a u_long is the largest type we can print + * portably). Most 64-bit systems have made longs 64-bits, so this should + * work. + */ +#define P_TO_ULONG(p) ((u_long)(uintptr_t)(p)) + +/* + * Convert a pointer to a small integral value. + * + * The (u_int16_t)(uintptr_t) cast avoids warnings: the (uintptr_t) cast + * converts the value to an integral type, and the (u_int16_t) cast converts + * it to a small integral type so we don't get complaints when we assign the + * final result to an integral type smaller than uintptr_t. + */ +#define P_TO_UINT32(p) ((u_int32_t)(uintptr_t)(p)) +#define P_TO_UINT16(p) ((u_int16_t)(uintptr_t)(p)) + +/* + * There are several on-page structures that are declared to have a number of + * fields followed by a variable length array of items. The structure size + * without including the variable length array or the address of the first of + * those elements can be found using SSZ. + * + * This macro can also be used to find the offset of a structure element in a + * structure. This is used in various places to copy structure elements from + * unaligned memory references, e.g., pointers into a packed page. + * + * There are two versions because compilers object if you take the address of + * an array. + */ +#undef SSZ +#define SSZ(name, field) P_TO_UINT16(&(((name *)0)->field)) + +#undef SSZA +#define SSZA(name, field) P_TO_UINT16(&(((name *)0)->field[0])) + +/* Structure used to print flag values. */ +typedef struct __fn { + u_int32_t mask; /* Flag value. */ + const char *name; /* Flag name. */ +} FN; + +/* Set, clear and test flags. */ +#define FLD_CLR(fld, f) (fld) &= ~(f) +#define FLD_ISSET(fld, f) ((fld) & (f)) +#define FLD_SET(fld, f) (fld) |= (f) +#define F_CLR(p, f) (p)->flags &= ~(f) +#define F_ISSET(p, f) ((p)->flags & (f)) +#define F_SET(p, f) (p)->flags |= (f) +#define LF_CLR(f) ((flags) &= ~(f)) +#define LF_ISSET(f) ((flags) & (f)) +#define LF_SET(f) ((flags) |= (f)) + +/* + * Calculate a percentage. The values can overflow 32-bit integer arithmetic + * so we use floating point. + * + * When calculating a bytes-vs-page size percentage, we're getting the inverse + * of the percentage in all cases, that is, we want 100 minus the percentage we + * calculate. + */ +#define DB_PCT(v, total) \ + ((int)((total) == 0 ? 0 : ((double)(v) * 100) / (total))) +#define DB_PCT_PG(v, total, pgsize) \ + ((int)((total) == 0 ? 0 : \ + 100 - ((double)(v) * 100) / (((double)total) * (pgsize)))) + +/* + * Statistics update shared memory and so are expensive -- don't update the + * values unless we're going to display the results. + */ +#undef STAT +#ifdef HAVE_STATISTICS +#define STAT(x) x +#else +#define STAT(x) +#endif + +/* + * Structure used for callback message aggregation. + * + * Display values in XXX_stat_print calls. + */ +typedef struct __db_msgbuf { + char *buf; /* Heap allocated buffer. */ + char *cur; /* Current end of message. */ + size_t len; /* Allocated length of buffer. */ +} DB_MSGBUF; +#define DB_MSGBUF_INIT(a) do { \ + (a)->buf = (a)->cur = NULL; \ + (a)->len = 0; \ +} while (0) +#define DB_MSGBUF_FLUSH(env, a) do { \ + if ((a)->buf != NULL) { \ + if ((a)->cur != (a)->buf) \ + __db_msg(env, "%s", (a)->buf); \ + __os_free(env, (a)->buf); \ + DB_MSGBUF_INIT(a); \ + } \ +} while (0) +#define STAT_FMT(msg, fmt, type, v) do { \ + DB_MSGBUF __mb; \ + DB_MSGBUF_INIT(&__mb); \ + __db_msgadd(env, &__mb, fmt, (type)(v)); \ + __db_msgadd(env, &__mb, "\t%s", msg); \ + DB_MSGBUF_FLUSH(env, &__mb); \ +} while (0) +#define STAT_HEX(msg, v) \ + __db_msg(env, "%#lx\t%s", (u_long)(v), msg) +#define STAT_ISSET(msg, p) \ + __db_msg(env, "%sSet\t%s", (p) == NULL ? "!" : " ", msg) +#define STAT_LONG(msg, v) \ + __db_msg(env, "%ld\t%s", (long)(v), msg) +#define STAT_LSN(msg, lsnp) \ + __db_msg(env, "%lu/%lu\t%s", \ + (u_long)(lsnp)->file, (u_long)(lsnp)->offset, msg) +#define STAT_POINTER(msg, v) \ + __db_msg(env, "%#lx\t%s", P_TO_ULONG(v), msg) +#define STAT_STRING(msg, p) do { \ + const char *__p = p; /* p may be a function call. */ \ + __db_msg(env, "%s\t%s", __p == NULL ? "!Set" : __p, msg); \ +} while (0) +#define STAT_ULONG(msg, v) \ + __db_msg(env, "%lu\t%s", (u_long)(v), msg) + +/* + * There are quite a few places in Berkeley DB where we want to initialize + * a DBT from a string or other random pointer type, using a length typed + * to size_t in most cases. This macro avoids a lot of casting. The macro + * comes in two flavors because we often want to clear the DBT first. + */ +#define DB_SET_DBT(dbt, d, s) do { \ + (dbt).data = (void *)(d); \ + (dbt).size = (u_int32_t)(s); \ +} while (0) +#define DB_INIT_DBT(dbt, d, s) do { \ + memset(&(dbt), 0, sizeof(dbt)); \ + DB_SET_DBT(dbt, d, s); \ +} while (0) + +/******************************************************* + * API return values + *******************************************************/ +/* + * Return values that are OK for each different call. Most calls have a + * standard 'return of 0 is only OK value', but some, like db->get have + * DB_NOTFOUND as a return value, but it really isn't an error. + */ +#define DB_RETOK_STD(ret) ((ret) == 0) +#define DB_RETOK_DBCDEL(ret) ((ret) == 0 || (ret) == DB_KEYEMPTY || \ + (ret) == DB_NOTFOUND) +#define DB_RETOK_DBCGET(ret) ((ret) == 0 || (ret) == DB_KEYEMPTY || \ + (ret) == DB_NOTFOUND) +#define DB_RETOK_DBCPUT(ret) ((ret) == 0 || (ret) == DB_KEYEXIST || \ + (ret) == DB_NOTFOUND) +#define DB_RETOK_DBDEL(ret) DB_RETOK_DBCDEL(ret) +#define DB_RETOK_DBGET(ret) DB_RETOK_DBCGET(ret) +#define DB_RETOK_DBPUT(ret) ((ret) == 0 || (ret) == DB_KEYEXIST) +#define DB_RETOK_EXISTS(ret) DB_RETOK_DBCGET(ret) +#define DB_RETOK_LGGET(ret) ((ret) == 0 || (ret) == DB_NOTFOUND) +#define DB_RETOK_MPGET(ret) ((ret) == 0 || (ret) == DB_PAGE_NOTFOUND) +#define DB_RETOK_REPPMSG(ret) ((ret) == 0 || \ + (ret) == DB_REP_IGNORE || \ + (ret) == DB_REP_ISPERM || \ + (ret) == DB_REP_NEWMASTER || \ + (ret) == DB_REP_NEWSITE || \ + (ret) == DB_REP_NOTPERM) +#define DB_RETOK_REPMGR_START(ret) ((ret) == 0 || (ret) == DB_REP_IGNORE) + +/* Find a reasonable operation-not-supported error. */ +#ifdef EOPNOTSUPP +#define DB_OPNOTSUP EOPNOTSUPP +#else +#ifdef ENOTSUP +#define DB_OPNOTSUP ENOTSUP +#else +#define DB_OPNOTSUP EINVAL +#endif +#endif + +/******************************************************* + * Files. + *******************************************************/ +/* + * We use 1024 as the maximum path length. It's too hard to figure out what + * the real path length is, as it was traditionally stored in , + * and that file isn't always available. + */ +#define DB_MAXPATHLEN 1024 + +#define PATH_DOT "." /* Current working directory. */ + /* Path separator character(s). */ +#define PATH_SEPARATOR "@PATH_SEPARATOR@" + +/******************************************************* + * Environment. + *******************************************************/ +/* Type passed to __db_appname(). */ +typedef enum { + DB_APP_NONE=0, /* No type (region). */ + DB_APP_DATA, /* Data file. */ + DB_APP_LOG, /* Log file. */ + DB_APP_TMP, /* Temporary file. */ + DB_APP_RECOVER /* We are in recovery. */ +} APPNAME; + +/* + * A set of macros to check if various functionality has been configured. + * + * ALIVE_ON The is_alive function is configured. + * CDB_LOCKING CDB product locking. + * CRYPTO_ON Security has been configured. + * LOCKING_ON Locking has been configured. + * LOGGING_ON Logging has been configured. + * MUTEX_ON Mutexes have been configured. + * MPOOL_ON Memory pool has been configured. + * REP_ON Replication has been configured. + * RPC_ON RPC has been configured. + * TXN_ON Transactions have been configured. + * + * REP_ON is more complex than most: if the BDB library was compiled without + * replication support, ENV->rep_handle will be NULL; if the BDB library has + * replication support, but it was not configured, the region reference will + * be NULL. + */ +#define ALIVE_ON(env) ((env)->dbenv->is_alive != NULL) +#define CDB_LOCKING(env) F_ISSET(env, ENV_CDB) +#define CRYPTO_ON(env) ((env)->crypto_handle != NULL) +#define LOCKING_ON(env) ((env)->lk_handle != NULL) +#define LOGGING_ON(env) ((env)->lg_handle != NULL) +#define MPOOL_ON(env) ((env)->mp_handle != NULL) +#define MUTEX_ON(env) ((env)->mutex_handle != NULL) +#define REP_ON(env) \ + ((env)->rep_handle != NULL && (env)->rep_handle->region != NULL) +#define RPC_ON(dbenv) ((dbenv)->cl_handle != NULL) +#define TXN_ON(env) ((env)->tx_handle != NULL) + +/* + * STD_LOCKING Standard locking, that is, locking was configured and CDB + * was not. We do not do locking in off-page duplicate trees, + * so we check for that in the cursor first. + */ +#define STD_LOCKING(dbc) \ + (!F_ISSET(dbc, DBC_OPD) && \ + !CDB_LOCKING((dbc)->env) && LOCKING_ON((dbc)->env)) + +/* + * IS_RECOVERING: The system is running recovery. + */ +#define IS_RECOVERING(env) \ + (LOGGING_ON(env) && F_ISSET((env)->lg_handle, DBLOG_RECOVER)) + +/* Initialization methods are often illegal before/after open is called. */ +#define ENV_ILLEGAL_AFTER_OPEN(env, name) \ + if (F_ISSET((env), ENV_OPEN_CALLED)) \ + return (__db_mi_open(env, name, 1)); +#define ENV_ILLEGAL_BEFORE_OPEN(env, name) \ + if (!F_ISSET((env), ENV_OPEN_CALLED)) \ + return (__db_mi_open(env, name, 0)); + +/* We're not actually user hostile, honest. */ +#define ENV_REQUIRES_CONFIG(env, handle, i, flags) \ + if (handle == NULL) \ + return (__env_not_config(env, i, flags)); +#define ENV_REQUIRES_CONFIG_XX(env, handle, i, flags) \ + if ((env)->handle->region == NULL) \ + return (__env_not_config(env, i, flags)); +#define ENV_NOT_CONFIGURED(env, handle, i, flags) \ + if (F_ISSET((env), ENV_OPEN_CALLED)) \ + ENV_REQUIRES_CONFIG(env, handle, i, flags) + +#define ENV_ENTER(env, ip) do { \ + int __ret; \ + PANIC_CHECK(env); \ + if ((env)->thr_hashtab == NULL) \ + ip = NULL; \ + else { \ + if ((__ret = \ + __env_set_state(env, &(ip), THREAD_ACTIVE)) != 0) \ + return (__ret); \ + } \ +} while (0) + +#define FAILCHK_THREAD(env, ip) do { \ + if ((ip) != NULL) \ + (ip)->dbth_state = THREAD_FAILCHK; \ +} while (0) + +#define ENV_GET_THREAD_INFO(env, ip) ENV_ENTER(env, ip) + +#ifdef DIAGNOSTIC +#define ENV_LEAVE(env, ip) do { \ + if ((ip) != NULL) { \ + DB_ASSERT(env, ((ip)->dbth_state == THREAD_ACTIVE || \ + (ip)->dbth_state == THREAD_FAILCHK)); \ + (ip)->dbth_state = THREAD_OUT; \ + } \ +} while (0) +#else +#define ENV_LEAVE(env, ip) do { \ + if ((ip) != NULL) \ + (ip)->dbth_state = THREAD_OUT; \ +} while (0) +#endif +#ifdef DIAGNOSTIC +#define CHECK_THREAD(env) do { \ + if ((env)->thr_hashtab != NULL) \ + (void)__env_set_state(env, NULL, THREAD_VERIFY); \ +} while (0) +#ifdef HAVE_STATISTICS +#define CHECK_MTX_THREAD(env, mtx) do { \ + if (mtx->alloc_id != MTX_MUTEX_REGION && \ + mtx->alloc_id != MTX_ENV_REGION && \ + mtx->alloc_id != MTX_APPLICATION) \ + CHECK_THREAD(env); \ +} while (0) +#else +#define CHECK_MTX_THREAD(env, mtx) +#endif +#else +#define CHECK_THREAD(env) +#define CHECK_MTX_THREAD(env, mtx) +#endif + +typedef enum { + THREAD_SLOT_NOT_IN_USE=0, + THREAD_OUT, + THREAD_ACTIVE, + THREAD_BLOCKED, + THREAD_BLOCKED_DEAD, + THREAD_FAILCHK, + THREAD_VERIFY +} DB_THREAD_STATE; + +typedef struct __pin_list { + roff_t b_ref; /* offset to buffer. */ + int region; /* region containing buffer. */ +} PIN_LIST; +#define PINMAX 4 + +struct __db_thread_info { + pid_t dbth_pid; + db_threadid_t dbth_tid; + DB_THREAD_STATE dbth_state; + SH_TAILQ_ENTRY dbth_links; + /* + * The following fields track which buffers this thread of + * control has pinned in the mpool buffer cache. + */ + u_int16_t dbth_pincount; /* Number of pins for this thread. */ + u_int16_t dbth_pinmax; /* Number of slots allocated. */ + roff_t dbth_pinlist; /* List of pins. */ + PIN_LIST dbth_pinarray[PINMAX]; /* Initial array of slots. */ +}; + +typedef struct __env_thread_info { + u_int32_t thr_count; + u_int32_t thr_max; + u_int32_t thr_nbucket; + roff_t thr_hashoff; +} THREAD_INFO; + +#define DB_EVENT(env, e, einfo) do { \ + DB_ENV *__dbenv = (env)->dbenv; \ + if (__dbenv->db_event_func != NULL) \ + __dbenv->db_event_func(__dbenv, e, einfo); \ +} while (0) + +typedef struct __flag_map { + u_int32_t inflag, outflag; +} FLAG_MAP; + +/* + * Internal database environment structure. + * + * This is the private database environment handle. The public environment + * handle is the DB_ENV structure. The library owns this structure, the user + * owns the DB_ENV structure. The reason there are two structures is because + * the user's configuration outlives any particular DB_ENV->open call, and + * separate structures allows us to easily discard internal information without + * discarding the user's configuration. + */ +struct __env { + DB_ENV *dbenv; /* Linked DB_ENV structure */ + + /* + * The ENV structure can be used concurrently, so field access is + * protected. + */ + db_mutex_t mtx_env; /* ENV structure mutex */ + + /* + * Some fields are included in the ENV structure rather than in the + * DB_ENV structure because they are only set as arguments to the + * DB_ENV->open method. In other words, because of the historic API, + * not for any rational reason. + * + * Arguments to DB_ENV->open. + */ + char *db_home; /* Database home */ + u_int32_t open_flags; /* Flags */ + int db_mode; /* Default open permissions */ + + pid_t pid_cache; /* Cached process ID */ + + DB_FH *lockfhp; /* fcntl(2) locking file handle */ + + DB_LOCKER *env_lref; /* Locker in non-threaded handles */ + + DB_DISTAB recover_dtab; /* Dispatch table for recover funcs */ + + int dir_mode; /* Intermediate directory perms. */ + + /* Thread tracking */ + u_int32_t thr_nbucket; /* Number of hash buckets */ + DB_HASHTAB *thr_hashtab; /* Hash table of DB_THREAD_INFO */ + + /* Mutex allocation */ + struct { + int alloc_id; /* Allocation ID argument */ + u_int32_t flags; /* Flags argument */ + } *mutex_iq; /* Initial mutexes queue */ + u_int mutex_iq_next; /* Count of initial mutexes */ + u_int mutex_iq_max; /* Maximum initial mutexes */ + + /* + * List of open DB handles for this ENV, used for cursor + * adjustment. Must be protected for multi-threaded support. + */ + db_mutex_t mtx_dblist; + int db_ref; /* DB handle reference count */ + TAILQ_HEAD(__dblist, __db) dblist; + + /* + * List of open file handles for this ENV. Must be protected + * for multi-threaded support. + */ + TAILQ_HEAD(__fdlist, __fh_t) fdlist; + + db_mutex_t mtx_mt; /* Mersenne Twister mutex */ + int mti; /* Mersenne Twister index */ + u_long *mt; /* Mersenne Twister state vector */ + + DB_CIPHER *crypto_handle; /* Crypto handle */ + DB_LOCKTAB *lk_handle; /* Lock handle */ + DB_LOG *lg_handle; /* Log handle */ + DB_MPOOL *mp_handle; /* Mpool handle */ + DB_MUTEXMGR *mutex_handle; /* Mutex handle */ + DB_REP *rep_handle; /* Replication handle */ + DB_TXNMGR *tx_handle; /* Txn handle */ + + /* Application callback to copy data to/from a custom data source */ +#define DB_USERCOPY_GETDATA 0x0001 +#define DB_USERCOPY_SETDATA 0x0002 + int (*dbt_usercopy) + __P((DBT *, u_int32_t, void *, u_int32_t, u_int32_t)); + + REGINFO *reginfo; /* REGINFO structure reference */ + +#define DB_TEST_ELECTINIT 1 /* after __rep_elect_init */ +#define DB_TEST_ELECTVOTE1 2 /* after sending VOTE1 */ +#define DB_TEST_POSTDESTROY 3 /* after destroy op */ +#define DB_TEST_POSTLOG 4 /* after logging all pages */ +#define DB_TEST_POSTLOGMETA 5 /* after logging meta in btree */ +#define DB_TEST_POSTOPEN 6 /* after __os_open */ +#define DB_TEST_POSTSYNC 7 /* after syncing the log */ +#define DB_TEST_PREDESTROY 8 /* before destroy op */ +#define DB_TEST_PREOPEN 9 /* before __os_open */ +#define DB_TEST_SUBDB_LOCKS 10 /* subdb locking tests */ + int test_abort; /* Abort value for testing */ + int test_check; /* Checkpoint value for testing */ + int test_copy; /* Copy value for testing */ + +#define ENV_CDB 0x00000001 /* DB_INIT_CDB */ +#define ENV_DBLOCAL 0x00000002 /* Environment for a private DB */ +#define ENV_LITTLEENDIAN 0x00000004 /* Little endian system. */ +#define ENV_LOCKDOWN 0x00000008 /* DB_LOCKDOWN set */ +#define ENV_NO_OUTPUT_SET 0x00000010 /* No output channel set */ +#define ENV_OPEN_CALLED 0x00000020 /* DB_ENV->open called */ +#define ENV_PRIVATE 0x00000040 /* DB_PRIVATE set */ +#define ENV_RECOVER_FATAL 0x00000080 /* Doing fatal recovery in env */ +#define ENV_REF_COUNTED 0x00000100 /* Region references this handle */ +#define ENV_SYSTEM_MEM 0x00000200 /* DB_SYSTEM_MEM set */ +#define ENV_THREAD 0x00000400 /* DB_THREAD set */ + u_int32_t flags; +}; + +/******************************************************* + * Database Access Methods. + *******************************************************/ +/* + * DB_IS_THREADED -- + * The database handle is free-threaded (was opened with DB_THREAD). + */ +#define DB_IS_THREADED(dbp) \ + ((dbp)->mutex != MUTEX_INVALID) + +/* Initialization methods are often illegal before/after open is called. */ +#define DB_ILLEGAL_AFTER_OPEN(dbp, name) \ + if (F_ISSET((dbp), DB_AM_OPEN_CALLED)) \ + return (__db_mi_open((dbp)->env, name, 1)); +#define DB_ILLEGAL_BEFORE_OPEN(dbp, name) \ + if (!F_ISSET((dbp), DB_AM_OPEN_CALLED)) \ + return (__db_mi_open((dbp)->env, name, 0)); +/* Some initialization methods are illegal if environment isn't local. */ +#define DB_ILLEGAL_IN_ENV(dbp, name) \ + if (!F_ISSET((dbp)->env, ENV_DBLOCAL)) \ + return (__db_mi_env((dbp)->env, name)); +#define DB_ILLEGAL_METHOD(dbp, flags) { \ + int __ret; \ + if ((__ret = __dbh_am_chk(dbp, flags)) != 0) \ + return (__ret); \ +} + +/* + * Common DBC->internal fields. Each access method adds additional fields + * to this list, but the initial fields are common. + */ +#define __DBC_INTERNAL \ + DBC *opd; /* Off-page duplicate cursor. */\ + DBC *pdbc; /* Pointer to parent cursor. */ \ + \ + void *page; /* Referenced page. */ \ + u_int32_t part; /* Partition number. */ \ + db_pgno_t root; /* Tree root. */ \ + db_pgno_t pgno; /* Referenced page number. */ \ + db_indx_t indx; /* Referenced key item index. */\ + \ + /* Streaming -- cache last position. */ \ + db_pgno_t stream_start_pgno; /* Last start pgno. */ \ + u_int32_t stream_off; /* Current offset. */ \ + db_pgno_t stream_curr_pgno; /* Current overflow page. */ \ + \ + DB_LOCK lock; /* Cursor lock. */ \ + db_lockmode_t lock_mode; /* Lock mode. */ + +struct __dbc_internal { + __DBC_INTERNAL +}; + +/* Actions that __db_master_update can take. */ +typedef enum { MU_REMOVE, MU_RENAME, MU_OPEN } mu_action; + +/* + * Access-method-common macro for determining whether a cursor + * has been initialized. + */ +#ifdef HAVE_PARTITION +#define IS_INITIALIZED(dbc) (DB_IS_PARTITIONED((dbc)->dbp) ? \ + ((PART_CURSOR *)(dbc)->internal)->sub_cursor != NULL && \ + ((PART_CURSOR *)(dbc)->internal)->sub_cursor-> \ + internal->pgno != PGNO_INVALID : \ + (dbc)->internal->pgno != PGNO_INVALID) +#else +#define IS_INITIALIZED(dbc) ((dbc)->internal->pgno != PGNO_INVALID) +#endif + +/* Free the callback-allocated buffer, if necessary, hanging off of a DBT. */ +#define FREE_IF_NEEDED(env, dbt) \ + if (F_ISSET((dbt), DB_DBT_APPMALLOC)) { \ + __os_ufree((env), (dbt)->data); \ + F_CLR((dbt), DB_DBT_APPMALLOC); \ + } + +/* + * Use memory belonging to object "owner" to return the results of + * any no-DBT-flag get ops on cursor "dbc". + */ +#define SET_RET_MEM(dbc, owner) \ + do { \ + (dbc)->rskey = &(owner)->my_rskey; \ + (dbc)->rkey = &(owner)->my_rkey; \ + (dbc)->rdata = &(owner)->my_rdata; \ + } while (0) + +/* Use the return-data memory src is currently set to use in dest as well. */ +#define COPY_RET_MEM(src, dest) \ + do { \ + (dest)->rskey = (src)->rskey; \ + (dest)->rkey = (src)->rkey; \ + (dest)->rdata = (src)->rdata; \ + } while (0) + +/* Reset the returned-memory pointers to their defaults. */ +#define RESET_RET_MEM(dbc) \ + do { \ + (dbc)->rskey = &(dbc)->my_rskey; \ + (dbc)->rkey = &(dbc)->my_rkey; \ + (dbc)->rdata = &(dbc)->my_rdata; \ + } while (0) + +/******************************************************* + * Mpool. + *******************************************************/ +/* + * File types for DB access methods. Negative numbers are reserved to DB. + */ +#define DB_FTYPE_SET -1 /* Call pgin/pgout functions. */ +#define DB_FTYPE_NOTSET 0 /* Don't call... */ +#define DB_LSN_OFF_NOTSET -1 /* Not yet set. */ +#define DB_CLEARLEN_NOTSET UINT32_MAX /* Not yet set. */ + +/* Structure used as the DB pgin/pgout pgcookie. */ +typedef struct __dbpginfo { + size_t db_pagesize; /* Underlying page size. */ + u_int32_t flags; /* Some DB_AM flags needed. */ + DBTYPE type; /* DB type */ +} DB_PGINFO; + +/******************************************************* + * Log. + *******************************************************/ +/* Initialize an LSN to 'zero'. */ +#define ZERO_LSN(LSN) do { \ + (LSN).file = 0; \ + (LSN).offset = 0; \ +} while (0) +#define IS_ZERO_LSN(LSN) ((LSN).file == 0 && (LSN).offset == 0) + +#define IS_INIT_LSN(LSN) ((LSN).file == 1 && (LSN).offset == 0) +#define INIT_LSN(LSN) do { \ + (LSN).file = 1; \ + (LSN).offset = 0; \ +} while (0) + +#define MAX_LSN(LSN) do { \ + (LSN).file = UINT32_MAX; \ + (LSN).offset = UINT32_MAX; \ +} while (0) +#define IS_MAX_LSN(LSN) \ + ((LSN).file == UINT32_MAX && (LSN).offset == UINT32_MAX) + +/* If logging is turned off, smash the lsn. */ +#define LSN_NOT_LOGGED(LSN) do { \ + (LSN).file = 0; \ + (LSN).offset = 1; \ +} while (0) +#define IS_NOT_LOGGED_LSN(LSN) \ + ((LSN).file == 0 && (LSN).offset == 1) + +/* + * LOG_COMPARE -- compare two LSNs. + */ + +#define LOG_COMPARE(lsn0, lsn1) \ + ((lsn0)->file != (lsn1)->file ? \ + ((lsn0)->file < (lsn1)->file ? -1 : 1) : \ + ((lsn0)->offset != (lsn1)->offset ? \ + ((lsn0)->offset < (lsn1)->offset ? -1 : 1) : 0)) + +/******************************************************* + * Txn. + *******************************************************/ +#define DB_NONBLOCK(C) ((C)->txn != NULL && F_ISSET((C)->txn, TXN_NOWAIT)) +#define NOWAIT_FLAG(txn) \ + ((txn) != NULL && F_ISSET((txn), TXN_NOWAIT) ? DB_LOCK_NOWAIT : 0) +#define IS_REAL_TXN(txn) \ + ((txn) != NULL && !F_ISSET(txn, TXN_CDSGROUP)) +#define IS_SUBTRANSACTION(txn) \ + ((txn) != NULL && (txn)->parent != NULL) + +/******************************************************* + * Crypto. + *******************************************************/ +#define DB_IV_BYTES 16 /* Bytes per IV */ +#define DB_MAC_KEY 20 /* Bytes per MAC checksum */ + +/******************************************************* + * Compression + *******************************************************/ +#define CMP_INT_SPARE_VAL 0xFC /* Smallest byte value that the integer + compression algorithm doesn't use */ + +/******************************************************* + * Secondaries over RPC. + *******************************************************/ +#ifdef CONFIG_TEST +/* + * These are flags passed to DB->associate calls by the Tcl API if running + * over RPC. The RPC server will mask out these flags before making the real + * DB->associate call. + * + * These flags must coexist with the valid flags to DB->associate (currently + * DB_AUTO_COMMIT and DB_CREATE). DB_AUTO_COMMIT is in the group of + * high-order shared flags (0xff000000), and DB_CREATE is in the low-order + * group (0x00000fff), so we pick a range in between. + */ +#define DB_RPC2ND_MASK 0x00f00000 /* Reserved bits. */ + +#define DB_RPC2ND_REVERSEDATA 0x00100000 /* callback_n(0) _s_reversedata. */ +#define DB_RPC2ND_NOOP 0x00200000 /* callback_n(1) _s_noop */ +#define DB_RPC2ND_CONCATKEYDATA 0x00300000 /* callback_n(2) _s_concatkeydata */ +#define DB_RPC2ND_CONCATDATAKEY 0x00400000 /* callback_n(3) _s_concatdatakey */ +#define DB_RPC2ND_REVERSECONCAT 0x00500000 /* callback_n(4) _s_reverseconcat */ +#define DB_RPC2ND_TRUNCDATA 0x00600000 /* callback_n(5) _s_truncdata */ +#define DB_RPC2ND_CONSTANT 0x00700000 /* callback_n(6) _s_constant */ +#define DB_RPC2ND_GETZIP 0x00800000 /* sj_getzip */ +#define DB_RPC2ND_GETNAME 0x00900000 /* sj_getname */ +#endif + +#if defined(__cplusplus) +} +#endif + +/******************************************************* + * Remaining general DB includes. + *******************************************************/ +@db_int_def@ + +#include "dbinc/globals.h" +#include "dbinc/clock.h" +#include "dbinc/debug.h" +#include "dbinc/region.h" +#include "dbinc_auto/env_ext.h" +#include "dbinc/mutex.h" +#ifdef HAVE_REPLICATION_THREADS +#include "dbinc/repmgr.h" +#endif +#include "dbinc/rep.h" +#include "dbinc/os.h" +#include "dbinc_auto/clib_ext.h" +#include "dbinc_auto/common_ext.h" + +/******************************************************* + * Remaining Log. + * These need to be defined after the general includes + * because they need rep.h from above. + *******************************************************/ +/* + * Test if the environment is currently logging changes. If we're in recovery + * or we're a replication client, we don't need to log changes because they're + * already in the log, even though we have a fully functional log system. + */ +#define DBENV_LOGGING(env) \ + (LOGGING_ON(env) && !IS_REP_CLIENT(env) && (!IS_RECOVERING(env))) + +/* + * Test if we need to log a change. By default, we don't log operations without + * associated transactions, unless DIAGNOSTIC, DEBUG_ROP or DEBUG_WOP are on. + * This is because we want to get log records for read/write operations, and, if + * we are trying to debug something, more information is always better. + * + * The DBC_RECOVER flag is set when we're in abort, as well as during recovery; + * thus DBC_LOGGING may be false for a particular dbc even when DBENV_LOGGING + * is true. + * + * We explicitly use LOGGING_ON/IS_REP_CLIENT here because we don't want to pull + * in the log headers, which IS_RECOVERING (and thus DBENV_LOGGING) rely on, and + * because DBC_RECOVER should be set anytime IS_RECOVERING would be true. + * + * If we're not in recovery (master - doing an abort or a client applying + * a txn), then a client's only path through here is on an internal + * operation, and a master's only path through here is a transactional + * operation. Detect if either is not the case. + */ +#if defined(DIAGNOSTIC) || defined(DEBUG_ROP) || defined(DEBUG_WOP) +#define DBC_LOGGING(dbc) __dbc_logging(dbc) +#else +#define DBC_LOGGING(dbc) \ + ((dbc)->txn != NULL && LOGGING_ON((dbc)->env) && \ + !F_ISSET((dbc), DBC_RECOVER) && !IS_REP_CLIENT((dbc)->env)) +#endif + +#endif /* !_DB_INT_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db_join.h b/src/libs/resiprocate/contrib/db/dbinc/db_join.h new file mode 100644 index 00000000..06bab08e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db_join.h @@ -0,0 +1,37 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1998-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_JOIN_H_ +#define _DB_JOIN_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Joins use a join cursor that is similar to a regular DB cursor except + * that it only supports c_get and c_close functionality. Also, it does + * not support the full range of flags for get. + */ +typedef struct __join_cursor { + u_int8_t *j_exhausted; /* Array of flags; is cursor i exhausted? */ + DBC **j_curslist; /* Array of cursors in the join: constant. */ + DBC **j_fdupcurs; /* Cursors w/ first instances of current dup. */ + DBC **j_workcurs; /* Scratch cursor copies to muck with. */ + DB *j_primary; /* Primary dbp. */ + DBT j_key; /* Used to do lookups. */ + DBT j_rdata; /* Memory used for data return. */ + u_int32_t j_ncurs; /* How many cursors do we have? */ +#define JOIN_RETRY 0x01 /* Error on primary get; re-return same key. */ + u_int32_t flags; +} JOIN_CURSOR; + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_JOIN_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db_page.h b/src/libs/resiprocate/contrib/db/dbinc/db_page.h new file mode 100644 index 00000000..45d06c9e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db_page.h @@ -0,0 +1,672 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_PAGE_H_ +#define _DB_PAGE_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * DB page formats. + * + * !!! + * This implementation requires that values within the following structures + * NOT be padded -- note, ANSI C permits random padding within structures. + * If your compiler pads randomly you can just forget ever making DB run on + * your system. In addition, no data type can require larger alignment than + * its own size, e.g., a 4-byte data element may not require 8-byte alignment. + * + * Note that key/data lengths are often stored in db_indx_t's -- this is + * not accidental, nor does it limit the key/data size. If the key/data + * item fits on a page, it's guaranteed to be small enough to fit into a + * db_indx_t, and storing it in one saves space. + */ + +#define PGNO_INVALID 0 /* Invalid page number in any database. */ +#define PGNO_BASE_MD 0 /* Base database: metadata page number. */ + +/* Page types. */ +#define P_INVALID 0 /* Invalid page type. */ +#define __P_DUPLICATE 1 /* Duplicate. DEPRECATED in 3.1 */ +#define P_HASH_UNSORTED 2 /* Hash pages created pre 4.6. DEPRECATED */ +#define P_IBTREE 3 /* Btree internal. */ +#define P_IRECNO 4 /* Recno internal. */ +#define P_LBTREE 5 /* Btree leaf. */ +#define P_LRECNO 6 /* Recno leaf. */ +#define P_OVERFLOW 7 /* Overflow. */ +#define P_HASHMETA 8 /* Hash metadata page. */ +#define P_BTREEMETA 9 /* Btree metadata page. */ +#define P_QAMMETA 10 /* Queue metadata page. */ +#define P_QAMDATA 11 /* Queue data page. */ +#define P_LDUP 12 /* Off-page duplicate leaf. */ +#define P_HASH 13 /* Sorted hash page. */ +#define P_PAGETYPE_MAX 14 +/* Flag to __db_new */ +#define P_DONTEXTEND 0x8000 /* Don't allocate if there are no free pages. */ + +/* + * When we create pages in mpool, we ask mpool to clear some number of bytes + * in the header. This number must be at least as big as the regular page + * headers and cover enough of the btree and hash meta-data pages to obliterate + * the page type. + */ +#define DB_PAGE_DB_LEN 32 +#define DB_PAGE_QUEUE_LEN 0 + +/************************************************************************ + GENERIC METADATA PAGE HEADER + * + * !!! + * The magic and version numbers have to be in the same place in all versions + * of the metadata page as the application may not have upgraded the database. + ************************************************************************/ +typedef struct _dbmeta33 { + DB_LSN lsn; /* 00-07: LSN. */ + db_pgno_t pgno; /* 08-11: Current page number. */ + u_int32_t magic; /* 12-15: Magic number. */ + u_int32_t version; /* 16-19: Version. */ + u_int32_t pagesize; /* 20-23: Pagesize. */ + u_int8_t encrypt_alg; /* 24: Encryption algorithm. */ + u_int8_t type; /* 25: Page type. */ +#define DBMETA_CHKSUM 0x01 +#define DBMETA_PART_RANGE 0x02 +#define DBMETA_PART_CALLBACK 0x04 + u_int8_t metaflags; /* 26: Meta-only flags */ + u_int8_t unused1; /* 27: Unused. */ + u_int32_t free; /* 28-31: Free list page number. */ + db_pgno_t last_pgno; /* 32-35: Page number of last page in db. */ + u_int32_t nparts; /* 36-39: Number of partitions. */ + u_int32_t key_count; /* 40-43: Cached key count. */ + u_int32_t record_count; /* 44-47: Cached record count. */ + u_int32_t flags; /* 48-51: Flags: unique to each AM. */ + /* 52-71: Unique file ID. */ + u_int8_t uid[DB_FILE_ID_LEN]; +} DBMETA33, DBMETA; + +/************************************************************************ + BTREE METADATA PAGE LAYOUT + ************************************************************************/ +typedef struct _btmeta33 { +#define BTM_DUP 0x001 /* Duplicates. */ +#define BTM_RECNO 0x002 /* Recno tree. */ +#define BTM_RECNUM 0x004 /* Btree: maintain record count. */ +#define BTM_FIXEDLEN 0x008 /* Recno: fixed length records. */ +#define BTM_RENUMBER 0x010 /* Recno: renumber on insert/delete. */ +#define BTM_SUBDB 0x020 /* Subdatabases. */ +#define BTM_DUPSORT 0x040 /* Duplicates are sorted. */ +#define BTM_COMPRESS 0x080 /* Compressed. */ +#define BTM_MASK 0x0ff + DBMETA dbmeta; /* 00-71: Generic meta-data header. */ + + u_int32_t unused1; /* 72-75: Unused space. */ + u_int32_t minkey; /* 76-79: Btree: Minkey. */ + u_int32_t re_len; /* 80-83: Recno: fixed-length record length. */ + u_int32_t re_pad; /* 84-87: Recno: fixed-length record pad. */ + u_int32_t root; /* 88-91: Root page. */ + u_int32_t unused2[92]; /* 92-459: Unused space. */ + u_int32_t crypto_magic; /* 460-463: Crypto magic number */ + u_int32_t trash[3]; /* 464-475: Trash space - Do not use */ + u_int8_t iv[DB_IV_BYTES]; /* 476-495: Crypto IV */ + u_int8_t chksum[DB_MAC_KEY]; /* 496-511: Page chksum */ + + /* + * Minimum page size is 512. + */ +} BTMETA33, BTMETA; + +/************************************************************************ + HASH METADATA PAGE LAYOUT + ************************************************************************/ +typedef struct _hashmeta33 { +#define DB_HASH_DUP 0x01 /* Duplicates. */ +#define DB_HASH_SUBDB 0x02 /* Subdatabases. */ +#define DB_HASH_DUPSORT 0x04 /* Duplicates are sorted. */ + DBMETA dbmeta; /* 00-71: Generic meta-data page header. */ + + u_int32_t max_bucket; /* 72-75: ID of Maximum bucket in use */ + u_int32_t high_mask; /* 76-79: Modulo mask into table */ + u_int32_t low_mask; /* 80-83: Modulo mask into table lower half */ + u_int32_t ffactor; /* 84-87: Fill factor */ + u_int32_t nelem; /* 88-91: Number of keys in hash table */ + u_int32_t h_charkey; /* 92-95: Value of hash(CHARKEY) */ +#define NCACHED 32 /* number of spare points */ + /* 96-223: Spare pages for overflow */ + u_int32_t spares[NCACHED]; + u_int32_t unused[59]; /* 224-459: Unused space */ + u_int32_t crypto_magic; /* 460-463: Crypto magic number */ + u_int32_t trash[3]; /* 464-475: Trash space - Do not use */ + u_int8_t iv[DB_IV_BYTES]; /* 476-495: Crypto IV */ + u_int8_t chksum[DB_MAC_KEY]; /* 496-511: Page chksum */ + + /* + * Minimum page size is 512. + */ +} HMETA33, HMETA; + +/************************************************************************ + QUEUE METADATA PAGE LAYOUT + ************************************************************************/ +/* + * QAM Meta data page structure + * + */ +typedef struct _qmeta33 { + DBMETA dbmeta; /* 00-71: Generic meta-data header. */ + + u_int32_t first_recno; /* 72-75: First not deleted record. */ + u_int32_t cur_recno; /* 76-79: Next recno to be allocated. */ + u_int32_t re_len; /* 80-83: Fixed-length record length. */ + u_int32_t re_pad; /* 84-87: Fixed-length record pad. */ + u_int32_t rec_page; /* 88-91: Records Per Page. */ + u_int32_t page_ext; /* 92-95: Pages per extent */ + + u_int32_t unused[91]; /* 96-459: Unused space */ + u_int32_t crypto_magic; /* 460-463: Crypto magic number */ + u_int32_t trash[3]; /* 464-475: Trash space - Do not use */ + u_int8_t iv[DB_IV_BYTES]; /* 476-495: Crypto IV */ + u_int8_t chksum[DB_MAC_KEY]; /* 496-511: Page chksum */ + /* + * Minimum page size is 512. + */ +} QMETA33, QMETA; + +/* + * DBMETASIZE is a constant used by __db_file_setup and DB->verify + * as a buffer which is guaranteed to be larger than any possible + * metadata page size and smaller than any disk sector. + */ +#define DBMETASIZE 512 + +/************************************************************************ + BTREE/HASH MAIN PAGE LAYOUT + ************************************************************************/ +/* + * +-----------------------------------+ + * | lsn | pgno | prev pgno | + * +-----------------------------------+ + * | next pgno | entries | hf offset | + * +-----------------------------------+ + * | level | type | chksum | + * +-----------------------------------+ + * | iv | index | free --> | + * +-----------+-----------------------+ + * | F R E E A R E A | + * +-----------------------------------+ + * | <-- free | item | + * +-----------------------------------+ + * | item | item | item | + * +-----------------------------------+ + * + * sizeof(PAGE) == 26 bytes + possibly 20 bytes of checksum and possibly + * 16 bytes of IV (+ 2 bytes for alignment), and the following indices + * are guaranteed to be two-byte aligned. If we aren't doing crypto or + * checksumming the bytes are reclaimed for data storage. + * + * For hash and btree leaf pages, index items are paired, e.g., inp[0] is the + * key for inp[1]'s data. All other types of pages only contain single items. + */ +typedef struct __pg_chksum { + u_int8_t unused[2]; /* 26-27: For alignment */ + u_int8_t chksum[4]; /* 28-31: Checksum */ +} PG_CHKSUM; + +typedef struct __pg_crypto { + u_int8_t unused[2]; /* 26-27: For alignment */ + u_int8_t chksum[DB_MAC_KEY]; /* 28-47: Checksum */ + u_int8_t iv[DB_IV_BYTES]; /* 48-63: IV */ + /* !!! + * Must be 16-byte aligned for crypto + */ +} PG_CRYPTO; + +typedef struct _db_page { + DB_LSN lsn; /* 00-07: Log sequence number. */ + db_pgno_t pgno; /* 08-11: Current page number. */ + db_pgno_t prev_pgno; /* 12-15: Previous page number. */ + db_pgno_t next_pgno; /* 16-19: Next page number. */ + db_indx_t entries; /* 20-21: Number of items on the page. */ + db_indx_t hf_offset; /* 22-23: High free byte page offset. */ + + /* + * The btree levels are numbered from the leaf to the root, starting + * with 1, so the leaf is level 1, its parent is level 2, and so on. + * We maintain this level on all btree pages, but the only place that + * we actually need it is on the root page. It would not be difficult + * to hide the byte on the root page once it becomes an internal page, + * so we could get this byte back if we needed it for something else. + */ +#define LEAFLEVEL 1 +#define MAXBTREELEVEL 255 + u_int8_t level; /* 24: Btree tree level. */ + u_int8_t type; /* 25: Page type. */ +} PAGE; + +/* + * With many compilers sizeof(PAGE) == 28, while SIZEOF_PAGE == 26. + * We add in other things directly after the page header and need + * the SIZEOF_PAGE. When giving the sizeof(), many compilers will + * pad it out to the next 4-byte boundary. + */ +#define SIZEOF_PAGE 26 +/* + * !!! + * DB_AM_ENCRYPT always implies DB_AM_CHKSUM so that must come first. + */ +#define P_INP(dbp, pg) \ + ((db_indx_t *)((u_int8_t *)(pg) + SIZEOF_PAGE + \ + (F_ISSET((dbp), DB_AM_ENCRYPT) ? sizeof(PG_CRYPTO) : \ + (F_ISSET((dbp), DB_AM_CHKSUM) ? sizeof(PG_CHKSUM) : 0)))) + +#define P_IV(dbp, pg) \ + (F_ISSET((dbp), DB_AM_ENCRYPT) ? ((u_int8_t *)(pg) + \ + SIZEOF_PAGE + SSZA(PG_CRYPTO, iv)) \ + : NULL) + +#define P_CHKSUM(dbp, pg) \ + (F_ISSET((dbp), DB_AM_ENCRYPT) ? ((u_int8_t *)(pg) + \ + SIZEOF_PAGE + SSZA(PG_CRYPTO, chksum)) : \ + (F_ISSET((dbp), DB_AM_CHKSUM) ? ((u_int8_t *)(pg) + \ + SIZEOF_PAGE + SSZA(PG_CHKSUM, chksum)) \ + : NULL)) + +/* PAGE element macros. */ +#define LSN(p) (((PAGE *)p)->lsn) +#define PGNO(p) (((PAGE *)p)->pgno) +#define PREV_PGNO(p) (((PAGE *)p)->prev_pgno) +#define NEXT_PGNO(p) (((PAGE *)p)->next_pgno) +#define NUM_ENT(p) (((PAGE *)p)->entries) +#define HOFFSET(p) (((PAGE *)p)->hf_offset) +#define LEVEL(p) (((PAGE *)p)->level) +#define TYPE(p) (((PAGE *)p)->type) + +/************************************************************************ + QUEUE MAIN PAGE LAYOUT + ************************************************************************/ +/* + * Sizes of page below. Used to reclaim space if not doing + * crypto or checksumming. If you change the QPAGE below you + * MUST adjust this too. + */ +#define QPAGE_NORMAL 28 +#define QPAGE_CHKSUM 48 +#define QPAGE_SEC 64 + +typedef struct _qpage { + DB_LSN lsn; /* 00-07: Log sequence number. */ + db_pgno_t pgno; /* 08-11: Current page number. */ + u_int32_t unused0[3]; /* 12-23: Unused. */ + u_int8_t unused1[1]; /* 24: Unused. */ + u_int8_t type; /* 25: Page type. */ + u_int8_t unused2[2]; /* 26-27: Unused. */ + u_int8_t chksum[DB_MAC_KEY]; /* 28-47: Checksum */ + u_int8_t iv[DB_IV_BYTES]; /* 48-63: IV */ +} QPAGE; + +#define QPAGE_SZ(dbp) \ + (F_ISSET((dbp), DB_AM_ENCRYPT) ? QPAGE_SEC : \ + F_ISSET((dbp), DB_AM_CHKSUM) ? QPAGE_CHKSUM : QPAGE_NORMAL) +/* + * !!! + * The next_pgno and prev_pgno fields are not maintained for btree and recno + * internal pages. Doing so only provides a minor performance improvement, + * it's hard to do when deleting internal pages, and it increases the chance + * of deadlock during deletes and splits because we have to re-link pages at + * more than the leaf level. + * + * !!! + * The btree/recno access method needs db_recno_t bytes of space on the root + * page to specify how many records are stored in the tree. (The alternative + * is to store the number of records in the meta-data page, which will create + * a second hot spot in trees being actively modified, or recalculate it from + * the BINTERNAL fields on each access.) Overload the PREV_PGNO field. + */ +#define RE_NREC(p) \ + ((TYPE(p) == P_IBTREE || TYPE(p) == P_IRECNO) ? PREV_PGNO(p) : \ + (db_pgno_t)(TYPE(p) == P_LBTREE ? NUM_ENT(p) / 2 : NUM_ENT(p))) +#define RE_NREC_ADJ(p, adj) \ + PREV_PGNO(p) += adj; +#define RE_NREC_SET(p, num) \ + PREV_PGNO(p) = (num); + +/* + * Initialize a page. + * + * !!! + * Don't modify the page's LSN, code depends on it being unchanged after a + * P_INIT call. + */ +#define P_INIT(pg, pg_size, n, pg_prev, pg_next, btl, pg_type) do { \ + PGNO(pg) = (n); \ + PREV_PGNO(pg) = (pg_prev); \ + NEXT_PGNO(pg) = (pg_next); \ + NUM_ENT(pg) = (0); \ + HOFFSET(pg) = (db_indx_t)(pg_size); \ + LEVEL(pg) = (btl); \ + TYPE(pg) = (pg_type); \ +} while (0) + +/* Page header length (offset to first index). */ +#define P_OVERHEAD(dbp) P_TO_UINT16(P_INP(dbp, 0)) + +/* First free byte. */ +#define LOFFSET(dbp, pg) \ + (P_OVERHEAD(dbp) + NUM_ENT(pg) * sizeof(db_indx_t)) + +/* Free space on a regular page. */ +#define P_FREESPACE(dbp, pg) (HOFFSET(pg) - LOFFSET(dbp, pg)) + +/* Get a pointer to the bytes at a specific index. */ +#define P_ENTRY(dbp, pg, indx) ((u_int8_t *)pg + P_INP(dbp, pg)[indx]) + +/************************************************************************ + OVERFLOW PAGE LAYOUT + ************************************************************************/ + +/* + * Overflow items are referenced by HOFFPAGE and BOVERFLOW structures, which + * store a page number (the first page of the overflow item) and a length + * (the total length of the overflow item). The overflow item consists of + * some number of overflow pages, linked by the next_pgno field of the page. + * A next_pgno field of PGNO_INVALID flags the end of the overflow item. + * + * Overflow page overloads: + * The amount of overflow data stored on each page is stored in the + * hf_offset field. + * + * The implementation reference counts overflow items as it's possible + * for them to be promoted onto btree internal pages. The reference + * count is stored in the entries field. + */ +#define OV_LEN(p) (((PAGE *)p)->hf_offset) +#define OV_REF(p) (((PAGE *)p)->entries) + +/* Maximum number of bytes that you can put on an overflow page. */ +#define P_MAXSPACE(dbp, psize) ((psize) - P_OVERHEAD(dbp)) + +/* Free space on an overflow page. */ +#define P_OVFLSPACE(dbp, psize, pg) (P_MAXSPACE(dbp, psize) - HOFFSET(pg)) + +/************************************************************************ + HASH PAGE LAYOUT + ************************************************************************/ + +/* Each index references a group of bytes on the page. */ +#define H_KEYDATA 1 /* Key/data item. */ +#define H_DUPLICATE 2 /* Duplicate key/data item. */ +#define H_OFFPAGE 3 /* Overflow key/data item. */ +#define H_OFFDUP 4 /* Overflow page of duplicates. */ + +/* + * !!! + * Items on hash pages are (potentially) unaligned, so we can never cast the + * (page + offset) pointer to an HKEYDATA, HOFFPAGE or HOFFDUP structure, as + * we do with B+tree on-page structures. Because we frequently want the type + * field, it requires no alignment, and it's in the same location in all three + * structures, there's a pair of macros. + */ +#define HPAGE_PTYPE(p) (*(u_int8_t *)p) +#define HPAGE_TYPE(dbp, pg, indx) (*P_ENTRY(dbp, pg, indx)) + +/* + * The first and second types are H_KEYDATA and H_DUPLICATE, represented + * by the HKEYDATA structure: + * + * +-----------------------------------+ + * | type | key/data ... | + * +-----------------------------------+ + * + * For duplicates, the data field encodes duplicate elements in the data + * field: + * + * +---------------------------------------------------------------+ + * | type | len1 | element1 | len1 | len2 | element2 | len2 | + * +---------------------------------------------------------------+ + * + * Thus, by keeping track of the offset in the element, we can do both + * backward and forward traversal. + */ +typedef struct _hkeydata { + u_int8_t type; /* 00: Page type. */ + u_int8_t data[1]; /* Variable length key/data item. */ +} HKEYDATA; +#define HKEYDATA_DATA(p) (((u_int8_t *)p) + SSZA(HKEYDATA, data)) + +/* + * The length of any HKEYDATA item. Note that indx is an element index, + * not a PAIR index. + */ +#define LEN_HITEM(dbp, pg, pgsize, indx) \ + (((indx) == 0 ? (pgsize) : \ + (P_INP(dbp, pg)[(indx) - 1])) - (P_INP(dbp, pg)[indx])) + +#define LEN_HKEYDATA(dbp, pg, psize, indx) \ + (db_indx_t)(LEN_HITEM(dbp, pg, psize, indx) - HKEYDATA_SIZE(0)) + +/* + * Page space required to add a new HKEYDATA item to the page, with and + * without the index value. + */ +#define HKEYDATA_SIZE(len) \ + ((len) + SSZA(HKEYDATA, data)) +#define HKEYDATA_PSIZE(len) \ + (HKEYDATA_SIZE(len) + sizeof(db_indx_t)) + +/* Put a HKEYDATA item at the location referenced by a page entry. */ +#define PUT_HKEYDATA(pe, kd, len, etype) { \ + ((HKEYDATA *)(pe))->type = etype; \ + memcpy((u_int8_t *)(pe) + sizeof(u_int8_t), kd, len); \ +} + +/* + * Macros the describe the page layout in terms of key-data pairs. + */ +#define H_NUMPAIRS(pg) (NUM_ENT(pg) / 2) +#define H_KEYINDEX(indx) (indx) +#define H_DATAINDEX(indx) ((indx) + 1) +#define H_PAIRKEY(dbp, pg, indx) P_ENTRY(dbp, pg, H_KEYINDEX(indx)) +#define H_PAIRDATA(dbp, pg, indx) P_ENTRY(dbp, pg, H_DATAINDEX(indx)) +#define H_PAIRSIZE(dbp, pg, psize, indx) \ + (LEN_HITEM(dbp, pg, psize, H_KEYINDEX(indx)) + \ + LEN_HITEM(dbp, pg, psize, H_DATAINDEX(indx))) +#define LEN_HDATA(dbp, p, psize, indx) \ + LEN_HKEYDATA(dbp, p, psize, H_DATAINDEX(indx)) +#define LEN_HKEY(dbp, p, psize, indx) \ + LEN_HKEYDATA(dbp, p, psize, H_KEYINDEX(indx)) + +/* + * The third type is the H_OFFPAGE, represented by the HOFFPAGE structure: + */ +typedef struct _hoffpage { + u_int8_t type; /* 00: Page type and delete flag. */ + u_int8_t unused[3]; /* 01-03: Padding, unused. */ + db_pgno_t pgno; /* 04-07: Offpage page number. */ + u_int32_t tlen; /* 08-11: Total length of item. */ +} HOFFPAGE; + +#define HOFFPAGE_PGNO(p) (((u_int8_t *)p) + SSZ(HOFFPAGE, pgno)) +#define HOFFPAGE_TLEN(p) (((u_int8_t *)p) + SSZ(HOFFPAGE, tlen)) + +/* + * Page space required to add a new HOFFPAGE item to the page, with and + * without the index value. + */ +#define HOFFPAGE_SIZE (sizeof(HOFFPAGE)) +#define HOFFPAGE_PSIZE (HOFFPAGE_SIZE + sizeof(db_indx_t)) + +/* + * The fourth type is H_OFFDUP represented by the HOFFDUP structure: + */ +typedef struct _hoffdup { + u_int8_t type; /* 00: Page type and delete flag. */ + u_int8_t unused[3]; /* 01-03: Padding, unused. */ + db_pgno_t pgno; /* 04-07: Offpage page number. */ +} HOFFDUP; +#define HOFFDUP_PGNO(p) (((u_int8_t *)p) + SSZ(HOFFDUP, pgno)) + +/* + * Page space required to add a new HOFFDUP item to the page, with and + * without the index value. + */ +#define HOFFDUP_SIZE (sizeof(HOFFDUP)) + +/************************************************************************ + BTREE PAGE LAYOUT + ************************************************************************/ + +/* Each index references a group of bytes on the page. */ +#define B_KEYDATA 1 /* Key/data item. */ +#define B_DUPLICATE 2 /* Duplicate key/data item. */ +#define B_OVERFLOW 3 /* Overflow key/data item. */ + +/* + * We have to store a deleted entry flag in the page. The reason is complex, + * but the simple version is that we can't delete on-page items referenced by + * a cursor -- the return order of subsequent insertions might be wrong. The + * delete flag is an overload of the top bit of the type byte. + */ +#define B_DELETE (0x80) +#define B_DCLR(t) (t) &= ~B_DELETE +#define B_DSET(t) (t) |= B_DELETE +#define B_DISSET(t) ((t) & B_DELETE) + +#define B_TYPE(t) ((t) & ~B_DELETE) +#define B_TSET(t, type) ((t) = B_TYPE(type)) +#define B_TSET_DELETED(t, type) ((t) = (type) | B_DELETE) + +/* + * The first type is B_KEYDATA, represented by the BKEYDATA structure: + */ +typedef struct _bkeydata { + db_indx_t len; /* 00-01: Key/data item length. */ + u_int8_t type; /* 02: Page type AND DELETE FLAG. */ + u_int8_t data[1]; /* Variable length key/data item. */ +} BKEYDATA; + +/* Get a BKEYDATA item for a specific index. */ +#define GET_BKEYDATA(dbp, pg, indx) \ + ((BKEYDATA *)P_ENTRY(dbp, pg, indx)) + +/* + * Page space required to add a new BKEYDATA item to the page, with and + * without the index value. The (u_int16_t) cast avoids warnings: DB_ALIGN + * casts to uintmax_t, the cast converts it to a small integral type so we + * don't get complaints when we assign the final result to an integral type + * smaller than uintmax_t. + */ +#define BKEYDATA_SIZE(len) \ + (u_int16_t)DB_ALIGN((len) + SSZA(BKEYDATA, data), sizeof(u_int32_t)) +#define BKEYDATA_PSIZE(len) \ + (BKEYDATA_SIZE(len) + sizeof(db_indx_t)) + +/* + * The second and third types are B_DUPLICATE and B_OVERFLOW, represented + * by the BOVERFLOW structure. + */ +typedef struct _boverflow { + db_indx_t unused1; /* 00-01: Padding, unused. */ + u_int8_t type; /* 02: Page type AND DELETE FLAG. */ + u_int8_t unused2; /* 03: Padding, unused. */ + db_pgno_t pgno; /* 04-07: Next page number. */ + u_int32_t tlen; /* 08-11: Total length of item. */ +} BOVERFLOW; + +/* Get a BOVERFLOW item for a specific index. */ +#define GET_BOVERFLOW(dbp, pg, indx) \ + ((BOVERFLOW *)P_ENTRY(dbp, pg, indx)) + +/* + * Page space required to add a new BOVERFLOW item to the page, with and + * without the index value. + */ +#define BOVERFLOW_SIZE \ + ((u_int16_t)DB_ALIGN(sizeof(BOVERFLOW), sizeof(u_int32_t))) +#define BOVERFLOW_PSIZE \ + (BOVERFLOW_SIZE + sizeof(db_indx_t)) + +#define BITEM_SIZE(bk) \ + (B_TYPE((bk)->type) != B_KEYDATA ? BOVERFLOW_SIZE : \ + BKEYDATA_SIZE((bk)->len)) + +#define BITEM_PSIZE(bk) \ + (B_TYPE((bk)->type) != B_KEYDATA ? BOVERFLOW_PSIZE : \ + BKEYDATA_PSIZE((bk)->len)) + +/* + * Btree leaf and hash page layouts group indices in sets of two, one for the + * key and one for the data. Everything else does it in sets of one to save + * space. Use the following macros so that it's real obvious what's going on. + */ +#define O_INDX 1 +#define P_INDX 2 + +/************************************************************************ + BTREE INTERNAL PAGE LAYOUT + ************************************************************************/ + +/* + * Btree internal entry. + */ +typedef struct _binternal { + db_indx_t len; /* 00-01: Key/data item length. */ + u_int8_t type; /* 02: Page type AND DELETE FLAG. */ + u_int8_t unused; /* 03: Padding, unused. */ + db_pgno_t pgno; /* 04-07: Page number of referenced page. */ + db_recno_t nrecs; /* 08-11: Subtree record count. */ + u_int8_t data[1]; /* Variable length key item. */ +} BINTERNAL; + +/* Get a BINTERNAL item for a specific index. */ +#define GET_BINTERNAL(dbp, pg, indx) \ + ((BINTERNAL *)P_ENTRY(dbp, pg, indx)) + +/* + * Page space required to add a new BINTERNAL item to the page, with and + * without the index value. + */ +#define BINTERNAL_SIZE(len) \ + (u_int16_t)DB_ALIGN((len) + SSZA(BINTERNAL, data), sizeof(u_int32_t)) +#define BINTERNAL_PSIZE(len) \ + (BINTERNAL_SIZE(len) + sizeof(db_indx_t)) + +/************************************************************************ + RECNO INTERNAL PAGE LAYOUT + ************************************************************************/ + +/* + * The recno internal entry. + */ +typedef struct _rinternal { + db_pgno_t pgno; /* 00-03: Page number of referenced page. */ + db_recno_t nrecs; /* 04-07: Subtree record count. */ +} RINTERNAL; + +/* Get a RINTERNAL item for a specific index. */ +#define GET_RINTERNAL(dbp, pg, indx) \ + ((RINTERNAL *)P_ENTRY(dbp, pg, indx)) + +/* + * Page space required to add a new RINTERNAL item to the page, with and + * without the index value. + */ +#define RINTERNAL_SIZE \ + (u_int16_t)DB_ALIGN(sizeof(RINTERNAL), sizeof(u_int32_t)) +#define RINTERNAL_PSIZE \ + (RINTERNAL_SIZE + sizeof(db_indx_t)) + +typedef struct __pglist { + db_pgno_t pgno, next_pgno; + DB_LSN lsn; +} db_pglist_t; + +#if defined(__cplusplus) +} +#endif + +#endif /* !_DB_PAGE_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db_server_int.h b/src/libs/resiprocate/contrib/db/dbinc/db_server_int.h new file mode 100644 index 00000000..eba36efc --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db_server_int.h @@ -0,0 +1,148 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000-2004 + * Sleepycat Software. All rights reserved. + * + * $Id: db_server_int.h,v 1.25 2004/01/28 03:36:02 bostic Exp $ + */ + +#ifndef _DB_SERVER_INT_H_ +#define _DB_SERVER_INT_H_ + +#define DB_SERVER_TIMEOUT 300 /* 5 minutes */ +#define DB_SERVER_MAXTIMEOUT 1200 /* 20 minutes */ +#define DB_SERVER_IDLETIMEOUT 86400 /* 1 day */ + +/* + * Ignore/mask off the following env->open flags: + * Most are illegal for a client to specify as they would control + * server resource usage. We will just ignore them. + * DB_LOCKDOWN + * DB_PRIVATE + * DB_RECOVER + * DB_RECOVER_FATAL + * DB_SYSTEM_MEM + * DB_USE_ENVIRON, DB_USE_ENVIRON_ROOT - handled on client + */ +#define DB_SERVER_FLAGMASK ( \ +DB_LOCKDOWN | DB_PRIVATE | DB_RECOVER | DB_RECOVER_FATAL | \ +DB_SYSTEM_MEM | DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT) + +#define CT_CURSOR 0x001 /* Cursor */ +#define CT_DB 0x002 /* Database */ +#define CT_ENV 0x004 /* Env */ +#define CT_TXN 0x008 /* Txn */ + +#define CT_JOIN 0x10000000 /* Join cursor component */ +#define CT_JOINCUR 0x20000000 /* Join cursor */ + +typedef struct home_entry home_entry; +struct home_entry { + LIST_ENTRY(home_entry) entries; + char *home; + char *dir; + char *name; + char *passwd; +}; + +/* + * Data needed for sharing handles. + * To share an env handle, on the open call, they must have matching + * env flags, and matching set_flags. + * + * To share a db handle on the open call, the db, subdb and flags must + * all be the same. + */ +#define DB_SERVER_ENVFLAGS ( \ +DB_INIT_CDB | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | \ +DB_INIT_TXN | DB_JOINENV) + +#define DB_SERVER_DBFLAGS (DB_DIRTY_READ | DB_NOMMAP | DB_RDONLY) +#define DB_SERVER_DBNOSHARE (DB_EXCL | DB_TRUNCATE) + +typedef struct ct_envdata ct_envdata; +typedef struct ct_dbdata ct_dbdata; +struct ct_envdata { + u_int32_t envflags; + u_int32_t onflags; + u_int32_t offflags; + home_entry *home; +}; + +struct ct_dbdata { + u_int32_t dbflags; + u_int32_t setflags; + char *db; + char *subdb; + DBTYPE type; +}; + +/* + * We maintain an activity timestamp for each handle. However, we + * set it to point, possibly to the ct_active field of its own handle + * or it may point to the ct_active field of a parent. In the case + * of nested transactions and any cursors within transactions it must + * point to the ct_active field of the ultimate parent of the transaction + * no matter how deeply it is nested. + */ +typedef struct ct_entry ct_entry; +struct ct_entry { + LIST_ENTRY(ct_entry) entries; /* List of entries */ + union { +#ifdef __cplusplus + DbEnv *envp; /* H_ENV */ + DbTxn *txnp; /* H_TXN */ + Db *dbp; /* H_DB */ + Dbc *dbc; /* H_CURSOR */ +#else + DB_ENV *envp; /* H_ENV */ + DB_TXN *txnp; /* H_TXN */ + DB *dbp; /* H_DB */ + DBC *dbc; /* H_CURSOR */ +#endif + void *anyp; + } handle_u; + union { /* Private data per type */ + ct_envdata envdp; /* Env info */ + ct_dbdata dbdp; /* Db info */ + } private_u; + long ct_id; /* Client ID */ + long *ct_activep; /* Activity timestamp pointer*/ + long *ct_origp; /* Original timestamp pointer*/ + long ct_active; /* Activity timestamp */ + long ct_timeout; /* Resource timeout */ + long ct_idle; /* Idle timeout */ + u_int32_t ct_refcount; /* Ref count for sharing */ + u_int32_t ct_type; /* This entry's type */ + struct ct_entry *ct_parent; /* Its parent */ + struct ct_entry *ct_envparent; /* Its environment */ +}; + +#define ct_envp handle_u.envp +#define ct_txnp handle_u.txnp +#define ct_dbp handle_u.dbp +#define ct_dbc handle_u.dbc +#define ct_anyp handle_u.anyp + +#define ct_envdp private_u.envdp +#define ct_dbdp private_u.dbdp + +extern int __dbsrv_verbose; + +/* + * Get ctp and activate it. + * Assumes local variable 'replyp'. + * NOTE: May 'return' from macro. + */ +#define ACTIVATE_CTP(ctp, id, type) { \ + (ctp) = get_tableent(id); \ + if ((ctp) == NULL) { \ + replyp->status = DB_NOSERVER_ID;\ + return; \ + } \ + DB_ASSERT((ctp)->ct_type & (type)); \ + __dbsrv_active(ctp); \ +} + +#endif /* !_DB_SERVER_INT_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db_shash.h b/src/libs/resiprocate/contrib/db/dbinc/db_shash.h new file mode 100644 index 00000000..51277e5e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db_shash.h @@ -0,0 +1,81 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2004 + * Sleepycat Software. All rights reserved. + * + * $Id: db_shash.h,v 11.13 2004/01/28 03:36:02 bostic Exp $ + */ + +#ifndef _DB_SHASH_H_ +#define _DB_SHASH_H_ + +/* Hash Headers */ +typedef SH_TAILQ_HEAD(__hash_head) DB_HASHTAB; + +/* + * HASHLOOKUP -- + * + * Look up something in a shared memory hash table. The "elt" argument + * should be a key, and cmp_func must know how to compare a key to whatever + * structure it is that appears in the hash table. The comparison function + * + * begin: address of the beginning of the hash table. + * ndx: index into table for this item. + * type: the structure type of the elements that are linked in each bucket. + * field: the name of the field by which the "type" structures are linked. + * elt: the item for which we are searching in the hash table. + * res: the variable into which we'll store the element if we find it. + * cmp: called as: cmp(lookup_elt, table_elt). + * + * If the element is not in the hash table, this macro exits with res set + * to NULL. + */ +#define HASHLOOKUP(begin, ndx, type, field, elt, res, cmp) do { \ + DB_HASHTAB *__bucket; \ + \ + __bucket = &begin[ndx]; \ + for (res = SH_TAILQ_FIRST(__bucket, type); \ + res != NULL; res = SH_TAILQ_NEXT(res, field, type)) \ + if (cmp(elt, res)) \ + break; \ +} while (0) + +/* + * HASHINSERT -- + * + * Insert a new entry into the hash table. This assumes that you already + * have the bucket locked and that lookup has failed; don't call it if you + * haven't already called HASHLOOKUP. If you do, you could get duplicate + * entries. + * + * begin: the beginning address of the hash table. + * ndx: the index for this element. + * type: the structure type of the elements that are linked in each bucket. + * field: the name of the field by which the "type" structures are linked. + * elt: the item to be inserted. + */ +#define HASHINSERT(begin, ndx, type, field, elt) do { \ + DB_HASHTAB *__bucket; \ + \ + __bucket = &begin[ndx]; \ + SH_TAILQ_INSERT_HEAD(__bucket, elt, field, type); \ +} while (0) + +/* + * HASHREMOVE_EL -- + * Given the object "obj" in the table, remove it. + * + * begin: address of the beginning of the hash table. + * ndx: index into hash table of where this element belongs. + * type: the structure type of the elements that are linked in each bucket. + * field: the name of the field by which the "type" structures are linked. + * obj: the object in the table that we with to delete. + */ +#define HASHREMOVE_EL(begin, ndx, type, field, obj) { \ + DB_HASHTAB *__bucket; \ + \ + __bucket = &begin[ndx]; \ + SH_TAILQ_REMOVE(__bucket, obj, field, type); \ +} +#endif /* !_DB_SHASH_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db_swap.h b/src/libs/resiprocate/contrib/db/dbinc/db_swap.h new file mode 100644 index 00000000..dab657c0 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db_swap.h @@ -0,0 +1,262 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef _DB_SWAP_H_ +#define _DB_SWAP_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Little endian <==> big endian 64-bit swap macros. + * M_64_SWAP swap a memory location + * P_64_COPY copy potentially unaligned 4 byte quantities + * P_64_SWAP swap a referenced memory location + */ +#undef M_64_SWAP +#define M_64_SWAP(a) { \ + u_int64_t _tmp; \ + _tmp = (u_int64_t)a; \ + ((u_int8_t *)&a)[0] = ((u_int8_t *)&_tmp)[7]; \ + ((u_int8_t *)&a)[1] = ((u_int8_t *)&_tmp)[6]; \ + ((u_int8_t *)&a)[2] = ((u_int8_t *)&_tmp)[5]; \ + ((u_int8_t *)&a)[3] = ((u_int8_t *)&_tmp)[4]; \ + ((u_int8_t *)&a)[4] = ((u_int8_t *)&_tmp)[3]; \ + ((u_int8_t *)&a)[5] = ((u_int8_t *)&_tmp)[2]; \ + ((u_int8_t *)&a)[6] = ((u_int8_t *)&_tmp)[1]; \ + ((u_int8_t *)&a)[7] = ((u_int8_t *)&_tmp)[0]; \ +} +#undef P_64_COPY +#define P_64_COPY(a, b) { \ + ((u_int8_t *)b)[0] = ((u_int8_t *)a)[0]; \ + ((u_int8_t *)b)[1] = ((u_int8_t *)a)[1]; \ + ((u_int8_t *)b)[2] = ((u_int8_t *)a)[2]; \ + ((u_int8_t *)b)[3] = ((u_int8_t *)a)[3]; \ + ((u_int8_t *)b)[4] = ((u_int8_t *)a)[4]; \ + ((u_int8_t *)b)[5] = ((u_int8_t *)a)[5]; \ + ((u_int8_t *)b)[6] = ((u_int8_t *)a)[6]; \ + ((u_int8_t *)b)[7] = ((u_int8_t *)a)[7]; \ +} +#undef P_64_SWAP +#define P_64_SWAP(a) { \ + u_int64_t _tmp; \ + P_64_COPY(a, &_tmp); \ + ((u_int8_t *)a)[0] = ((u_int8_t *)&_tmp)[7]; \ + ((u_int8_t *)a)[1] = ((u_int8_t *)&_tmp)[6]; \ + ((u_int8_t *)a)[2] = ((u_int8_t *)&_tmp)[5]; \ + ((u_int8_t *)a)[3] = ((u_int8_t *)&_tmp)[4]; \ + ((u_int8_t *)a)[4] = ((u_int8_t *)&_tmp)[3]; \ + ((u_int8_t *)a)[5] = ((u_int8_t *)&_tmp)[2]; \ + ((u_int8_t *)a)[6] = ((u_int8_t *)&_tmp)[1]; \ + ((u_int8_t *)a)[7] = ((u_int8_t *)&_tmp)[0]; \ +} + +/* + * Little endian <==> big endian 32-bit swap macros. + * P_32_COPY copy potentially unaligned 4 byte quantities + * P_32_COPYSWAP copy and swap potentially unaligned 4 byte quantities + * P_32_SWAP swap a referenced memory location + * M_32_SWAP swap a memory location + */ +#undef P_32_COPY +#define P_32_COPY(a, b) do { \ + ((u_int8_t *)b)[0] = ((u_int8_t *)a)[0]; \ + ((u_int8_t *)b)[1] = ((u_int8_t *)a)[1]; \ + ((u_int8_t *)b)[2] = ((u_int8_t *)a)[2]; \ + ((u_int8_t *)b)[3] = ((u_int8_t *)a)[3]; \ +} while (0) +#undef P_32_COPYSWAP +#define P_32_COPYSWAP(a, b) do { \ + ((u_int8_t *)b)[0] = ((u_int8_t *)a)[3]; \ + ((u_int8_t *)b)[1] = ((u_int8_t *)a)[2]; \ + ((u_int8_t *)b)[2] = ((u_int8_t *)a)[1]; \ + ((u_int8_t *)b)[3] = ((u_int8_t *)a)[0]; \ +} while (0) +#undef P_32_SWAP +#define P_32_SWAP(a) do { \ + u_int32_t _tmp; \ + P_32_COPY(a, &_tmp); \ + P_32_COPYSWAP(&_tmp, a); \ +} while (0) +#undef M_32_SWAP +#define M_32_SWAP(a) P_32_SWAP(&a) + +/* + * Little endian <==> big endian 16-bit swap macros. + * P_16_COPY copy potentially unaligned 2 byte quantities + * P_16_COPYSWAP copy and swap potentially unaligned 2 byte quantities + * P_16_SWAP swap a referenced memory location + * M_16_SWAP swap a memory location + */ +#undef P_16_COPY +#define P_16_COPY(a, b) do { \ + ((u_int8_t *)b)[0] = ((u_int8_t *)a)[0]; \ + ((u_int8_t *)b)[1] = ((u_int8_t *)a)[1]; \ +} while (0) +#undef P_16_COPYSWAP +#define P_16_COPYSWAP(a, b) do { \ + ((u_int8_t *)b)[0] = ((u_int8_t *)a)[1]; \ + ((u_int8_t *)b)[1] = ((u_int8_t *)a)[0]; \ +} while (0) +#undef P_16_SWAP +#define P_16_SWAP(a) do { \ + u_int16_t _tmp; \ + P_16_COPY(a, &_tmp); \ + P_16_COPYSWAP(&_tmp, a); \ +} while (0) +#undef M_16_SWAP +#define M_16_SWAP(a) P_16_SWAP(&a) + +#undef SWAP32 +#define SWAP32(p) { \ + P_32_SWAP(p); \ + (p) += sizeof(u_int32_t); \ +} +#undef SWAP16 +#define SWAP16(p) { \ + P_16_SWAP(p); \ + (p) += sizeof(u_int16_t); \ +} + +/* + * Berkeley DB has local versions of htonl() and ntohl() that operate on + * pointers to the right size memory locations; the portability magic for + * finding the real system functions isn't worth the effort. + */ +#undef DB_HTONL_SWAP +#define DB_HTONL_SWAP(env, p) do { \ + if (F_ISSET((env), ENV_LITTLEENDIAN)) \ + P_32_SWAP(p); \ +} while (0) +#undef DB_NTOHL_SWAP +#define DB_NTOHL_SWAP(env, p) do { \ + if (F_ISSET((env), ENV_LITTLEENDIAN)) \ + P_32_SWAP(p); \ +} while (0) + +#undef DB_NTOHL_COPYIN +#define DB_NTOHL_COPYIN(env, i, p) do { \ + u_int8_t *tmp; \ + tmp = (u_int8_t *)&(i); \ + if (F_ISSET(env, ENV_LITTLEENDIAN)) { \ + tmp[3] = *p++; \ + tmp[2] = *p++; \ + tmp[1] = *p++; \ + tmp[0] = *p++; \ + } else { \ + memcpy(&i, p, sizeof(u_int32_t)); \ + p = (u_int8_t *)p + sizeof(u_int32_t); \ + } \ +} while (0) + +#undef DB_NTOHS_COPYIN +#define DB_NTOHS_COPYIN(env, i, p) do { \ + u_int8_t *tmp; \ + tmp = (u_int8_t *)&(i); \ + if (F_ISSET(env, ENV_LITTLEENDIAN)) { \ + tmp[1] = *p++; \ + tmp[0] = *p++; \ + } else { \ + memcpy(&i, p, sizeof(u_int16_t)); \ + p = (u_int8_t *)p + sizeof(u_int16_t); \ + } \ +} while (0) + +#undef DB_HTONL_COPYOUT +#define DB_HTONL_COPYOUT(env, p, i) do { \ + u_int8_t *tmp; \ + tmp = (u_int8_t *)p; \ + if (F_ISSET(env, ENV_LITTLEENDIAN)) { \ + *tmp++ = ((u_int8_t *)&(i))[3]; \ + *tmp++ = ((u_int8_t *)&(i))[2]; \ + *tmp++ = ((u_int8_t *)&(i))[1]; \ + *tmp++ = ((u_int8_t *)&(i))[0]; \ + } else \ + memcpy(p, &i, sizeof(u_int32_t)); \ + p = (u_int8_t *)p + sizeof(u_int32_t); \ +} while (0) + +#undef DB_HTONS_COPYOUT +#define DB_HTONS_COPYOUT(env, p, i) do { \ + u_int8_t *tmp; \ + tmp = (u_int8_t *)p; \ + if (F_ISSET(env, ENV_LITTLEENDIAN)) { \ + *tmp++ = ((u_int8_t *)&(i))[1]; \ + *tmp++ = ((u_int8_t *)&(i))[0]; \ + } else \ + memcpy(p, &i, sizeof(u_int16_t)); \ + p = (u_int8_t *)p + sizeof(u_int16_t); \ +} while (0) + +/* + * Helper macros for swapped logs. We write logs in little endian format to + * minimize disruption on x86 when upgrading from native byte order to + * platform-independent logs. + */ +#define LOG_SWAPPED(env) !F_ISSET(env, ENV_LITTLEENDIAN) + +#define LOGCOPY_32(env, x, p) do { \ + if (LOG_SWAPPED(env)) \ + P_32_COPYSWAP((p), (x)); \ + else \ + memcpy((x), (p), sizeof(u_int32_t)); \ +} while (0) + +#define LOGCOPY_16(env, x, p) do { \ + if (LOG_SWAPPED(env)) \ + P_16_COPYSWAP((p), (x)); \ + else \ + memcpy((x), (p), sizeof(u_int16_t)); \ +} while (0) + +#define LOGCOPY_TOLSN(env, lsnp, p) do { \ + LOGCOPY_32((env), &(lsnp)->file, (p)); \ + LOGCOPY_32((env), &(lsnp)->offset, \ + (u_int8_t *)(p) + sizeof(u_int32_t)); \ +} while (0) + +#define LOGCOPY_FROMLSN(env, p, lsnp) do { \ + LOGCOPY_32((env), (p), &(lsnp)->file); \ + LOGCOPY_32((env), \ + (u_int8_t *)(p) + sizeof(u_int32_t), &(lsnp)->offset); \ +} while (0) + +#if defined(__cplusplus) +} +#endif + +#endif /* !_DB_SWAP_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db_upgrade.h b/src/libs/resiprocate/contrib/db/dbinc/db_upgrade.h new file mode 100644 index 00000000..b9f1c32c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db_upgrade.h @@ -0,0 +1,248 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_UPGRADE_H_ +#define _DB_UPGRADE_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * This file defines the metadata pages from the previous release. + * These structures are only used to upgrade old versions of databases. + */ + +/* Structures from the 3.1 release */ +typedef struct _dbmeta31 { + DB_LSN lsn; /* 00-07: LSN. */ + db_pgno_t pgno; /* 08-11: Current page number. */ + u_int32_t magic; /* 12-15: Magic number. */ + u_int32_t version; /* 16-19: Version. */ + u_int32_t pagesize; /* 20-23: Pagesize. */ + u_int8_t unused1[1]; /* 24: Unused. */ + u_int8_t type; /* 25: Page type. */ + u_int8_t unused2[2]; /* 26-27: Unused. */ + u_int32_t free; /* 28-31: Free list page number. */ + DB_LSN unused3; /* 36-39: Unused. */ + u_int32_t key_count; /* 40-43: Cached key count. */ + u_int32_t record_count; /* 44-47: Cached record count. */ + u_int32_t flags; /* 48-51: Flags: unique to each AM. */ + /* 52-71: Unique file ID. */ + u_int8_t uid[DB_FILE_ID_LEN]; +} DBMETA31; + +typedef struct _btmeta31 { + DBMETA31 dbmeta; /* 00-71: Generic meta-data header. */ + + u_int32_t maxkey; /* 72-75: Btree: Maxkey. */ + u_int32_t minkey; /* 76-79: Btree: Minkey. */ + u_int32_t re_len; /* 80-83: Recno: fixed-length record length. */ + u_int32_t re_pad; /* 84-87: Recno: fixed-length record pad. */ + u_int32_t root; /* 88-92: Root page. */ + + /* + * Minimum page size is 128. + */ +} BTMETA31; + +/************************************************************************ + HASH METADATA PAGE LAYOUT + ************************************************************************/ +typedef struct _hashmeta31 { + DBMETA31 dbmeta; /* 00-71: Generic meta-data page header. */ + + u_int32_t max_bucket; /* 72-75: ID of Maximum bucket in use */ + u_int32_t high_mask; /* 76-79: Modulo mask into table */ + u_int32_t low_mask; /* 80-83: Modulo mask into table lower half */ + u_int32_t ffactor; /* 84-87: Fill factor */ + u_int32_t nelem; /* 88-91: Number of keys in hash table */ + u_int32_t h_charkey; /* 92-95: Value of hash(CHARKEY) */ +#define NCACHED 32 /* number of spare points */ + /* 96-223: Spare pages for overflow */ + u_int32_t spares[NCACHED]; + + /* + * Minimum page size is 256. + */ +} HMETA31; + +/* + * QAM Meta data page structure + * + */ +typedef struct _qmeta31 { + DBMETA31 dbmeta; /* 00-71: Generic meta-data header. */ + + u_int32_t start; /* 72-75: Start offset. */ + u_int32_t first_recno; /* 76-79: First not deleted record. */ + u_int32_t cur_recno; /* 80-83: Last recno allocated. */ + u_int32_t re_len; /* 84-87: Fixed-length record length. */ + u_int32_t re_pad; /* 88-91: Fixed-length record pad. */ + u_int32_t rec_page; /* 92-95: Records Per Page. */ + + /* + * Minimum page size is 128. + */ +} QMETA31; +/* Structures from the 3.2 release */ +typedef struct _qmeta32 { + DBMETA31 dbmeta; /* 00-71: Generic meta-data header. */ + + u_int32_t first_recno; /* 72-75: First not deleted record. */ + u_int32_t cur_recno; /* 76-79: Last recno allocated. */ + u_int32_t re_len; /* 80-83: Fixed-length record length. */ + u_int32_t re_pad; /* 84-87: Fixed-length record pad. */ + u_int32_t rec_page; /* 88-91: Records Per Page. */ + u_int32_t page_ext; /* 92-95: Pages per extent */ + + /* + * Minimum page size is 128. + */ +} QMETA32; + +/* Structures from the 3.0 release */ + +typedef struct _dbmeta30 { + DB_LSN lsn; /* 00-07: LSN. */ + db_pgno_t pgno; /* 08-11: Current page number. */ + u_int32_t magic; /* 12-15: Magic number. */ + u_int32_t version; /* 16-19: Version. */ + u_int32_t pagesize; /* 20-23: Pagesize. */ + u_int8_t unused1[1]; /* 24: Unused. */ + u_int8_t type; /* 25: Page type. */ + u_int8_t unused2[2]; /* 26-27: Unused. */ + u_int32_t free; /* 28-31: Free list page number. */ + u_int32_t flags; /* 32-35: Flags: unique to each AM. */ + /* 36-55: Unique file ID. */ + u_int8_t uid[DB_FILE_ID_LEN]; +} DBMETA30; + +/************************************************************************ + BTREE METADATA PAGE LAYOUT + ************************************************************************/ +typedef struct _btmeta30 { + DBMETA30 dbmeta; /* 00-55: Generic meta-data header. */ + + u_int32_t maxkey; /* 56-59: Btree: Maxkey. */ + u_int32_t minkey; /* 60-63: Btree: Minkey. */ + u_int32_t re_len; /* 64-67: Recno: fixed-length record length. */ + u_int32_t re_pad; /* 68-71: Recno: fixed-length record pad. */ + u_int32_t root; /* 72-75: Root page. */ + + /* + * Minimum page size is 128. + */ +} BTMETA30; + +/************************************************************************ + HASH METADATA PAGE LAYOUT + ************************************************************************/ +typedef struct _hashmeta30 { + DBMETA30 dbmeta; /* 00-55: Generic meta-data page header. */ + + u_int32_t max_bucket; /* 56-59: ID of Maximum bucket in use */ + u_int32_t high_mask; /* 60-63: Modulo mask into table */ + u_int32_t low_mask; /* 64-67: Modulo mask into table lower half */ + u_int32_t ffactor; /* 68-71: Fill factor */ + u_int32_t nelem; /* 72-75: Number of keys in hash table */ + u_int32_t h_charkey; /* 76-79: Value of hash(CHARKEY) */ +#define NCACHED30 32 /* number of spare points */ + /* 80-207: Spare pages for overflow */ + u_int32_t spares[NCACHED30]; + + /* + * Minimum page size is 256. + */ +} HMETA30; + +/************************************************************************ + QUEUE METADATA PAGE LAYOUT + ************************************************************************/ +/* + * QAM Meta data page structure + * + */ +typedef struct _qmeta30 { + DBMETA30 dbmeta; /* 00-55: Generic meta-data header. */ + + u_int32_t start; /* 56-59: Start offset. */ + u_int32_t first_recno; /* 60-63: First not deleted record. */ + u_int32_t cur_recno; /* 64-67: Last recno allocated. */ + u_int32_t re_len; /* 68-71: Fixed-length record length. */ + u_int32_t re_pad; /* 72-75: Fixed-length record pad. */ + u_int32_t rec_page; /* 76-79: Records Per Page. */ + + /* + * Minimum page size is 128. + */ +} QMETA30; + +/* Structures from Release 2.x */ + +/************************************************************************ + BTREE METADATA PAGE LAYOUT + ************************************************************************/ + +/* + * Btree metadata page layout: + */ +typedef struct _btmeta2X { + DB_LSN lsn; /* 00-07: LSN. */ + db_pgno_t pgno; /* 08-11: Current page number. */ + u_int32_t magic; /* 12-15: Magic number. */ + u_int32_t version; /* 16-19: Version. */ + u_int32_t pagesize; /* 20-23: Pagesize. */ + u_int32_t maxkey; /* 24-27: Btree: Maxkey. */ + u_int32_t minkey; /* 28-31: Btree: Minkey. */ + u_int32_t free; /* 32-35: Free list page number. */ + u_int32_t flags; /* 36-39: Flags. */ + u_int32_t re_len; /* 40-43: Recno: fixed-length record length. */ + u_int32_t re_pad; /* 44-47: Recno: fixed-length record pad. */ + /* 48-67: Unique file ID. */ + u_int8_t uid[DB_FILE_ID_LEN]; +} BTMETA2X; + +/************************************************************************ + HASH METADATA PAGE LAYOUT + ************************************************************************/ + +/* + * Hash metadata page layout: + */ +/* Hash Table Information */ +typedef struct hashhdr { /* Disk resident portion */ + DB_LSN lsn; /* 00-07: LSN of the header page */ + db_pgno_t pgno; /* 08-11: Page number (btree compatibility). */ + u_int32_t magic; /* 12-15: Magic NO for hash tables */ + u_int32_t version; /* 16-19: Version ID */ + u_int32_t pagesize; /* 20-23: Bucket/Page Size */ + u_int32_t ovfl_point; /* 24-27: Overflow page allocation location */ + u_int32_t last_freed; /* 28-31: Last freed overflow page pgno */ + u_int32_t max_bucket; /* 32-35: ID of Maximum bucket in use */ + u_int32_t high_mask; /* 36-39: Modulo mask into table */ + u_int32_t low_mask; /* 40-43: Modulo mask into table lower half */ + u_int32_t ffactor; /* 44-47: Fill factor */ + u_int32_t nelem; /* 48-51: Number of keys in hash table */ + u_int32_t h_charkey; /* 52-55: Value of hash(CHARKEY) */ + u_int32_t flags; /* 56-59: Allow duplicates. */ +#define NCACHED2X 32 /* number of spare points */ + /* 60-187: Spare pages for overflow */ + u_int32_t spares[NCACHED2X]; + /* 188-207: Unique file ID. */ + u_int8_t uid[DB_FILE_ID_LEN]; + + /* + * Minimum page size is 256. + */ +} HASHHDR; + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_UPGRADE_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/db_verify.h b/src/libs/resiprocate/contrib/db/dbinc/db_verify.h new file mode 100644 index 00000000..6cfd1d89 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/db_verify.h @@ -0,0 +1,204 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1999-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_VERIFY_H_ +#define _DB_VERIFY_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Structures and macros for the storage and retrieval of all information + * needed for inter-page verification of a database. + */ + +/* + * EPRINT is the macro for error printing. Takes as an arg the arg set + * for DB->err. + */ +#define EPRINT(x) do { \ + if (!LF_ISSET(DB_SALVAGE)) \ + __db_errx x; \ +} while (0) + +/* Complain about a totally zeroed page where we don't expect one. */ +#define ZEROPG_ERR_PRINT(dbenv, pgno, str) do { \ + EPRINT(((dbenv), "Page %lu: %s is of inappropriate type %lu", \ + (u_long)(pgno), str, (u_long)P_INVALID)); \ + EPRINT(((dbenv), "Page %lu: totally zeroed page", \ + (u_long)(pgno))); \ +} while (0) + +/* + * Note that 0 is, in general, a valid pgno, despite equaling PGNO_INVALID; + * we have to test it separately where it's not appropriate. + */ +#define IS_VALID_PGNO(x) ((x) <= vdp->last_pgno) + +/* + * VRFY_DBINFO is the fundamental structure; it either represents the database + * of subdatabases, or the sole database if there are no subdatabases. + */ +struct __vrfy_dbinfo { + DB_THREAD_INFO *thread_info; + /* Info about this database in particular. */ + DBTYPE type; + + /* List of subdatabase meta pages, if any. */ + LIST_HEAD(__subdbs, __vrfy_childinfo) subdbs; + + /* File-global info--stores VRFY_PAGEINFOs for each page. */ + DB *pgdbp; + + /* Child database--stores VRFY_CHILDINFOs of each page. */ + DB *cdbp; + + /* Page info structures currently in use. */ + LIST_HEAD(__activepips, __vrfy_pageinfo) activepips; + + /* + * DB we use to keep track of which pages are linked somehow + * during verification. 0 is the default, "unseen"; 1 is seen. + */ + DB *pgset; + + /* + * This is a database we use during salvaging to keep track of which + * overflow and dup pages we need to come back to at the end and print + * with key "UNKNOWN". Pages which print with a good key get set + * to SALVAGE_IGNORE; others get set, as appropriate, to SALVAGE_LDUP, + * SALVAGE_LRECNODUP, SALVAGE_OVERFLOW for normal db overflow pages, + * and SALVAGE_BTREE, SALVAGE_LRECNO, and SALVAGE_HASH for subdb + * pages. + */ +#define SALVAGE_INVALID 0 +#define SALVAGE_IGNORE 1 +#define SALVAGE_LDUP 2 +#define SALVAGE_IBTREE 3 +#define SALVAGE_OVERFLOW 4 +#define SALVAGE_LBTREE 5 +#define SALVAGE_HASH 6 +#define SALVAGE_LRECNO 7 +#define SALVAGE_LRECNODUP 8 + DB *salvage_pages; + + db_pgno_t last_pgno; + db_pgno_t meta_last_pgno; + db_pgno_t pgs_remaining; /* For dbp->db_feedback(). */ + + /* + * These are used during __bam_vrfy_subtree to keep track, while + * walking up and down the Btree structure, of the prev- and next-page + * chain of leaf pages and verify that it's intact. Also, make sure + * that this chain contains pages of only one type. + */ + db_pgno_t prev_pgno; + db_pgno_t next_pgno; + u_int8_t leaf_type; + + /* Queue needs these to verify data pages in the first pass. */ + u_int32_t re_pad; /* Record pad character. */ + u_int32_t re_len; /* Record length. */ + u_int32_t rec_page; + u_int32_t page_ext; + u_int32_t first_recno; + u_int32_t last_recno; + int nextents; + db_pgno_t *extents; + +#define SALVAGE_PRINTABLE 0x01 /* Output printable chars literally. */ +#define SALVAGE_PRINTHEADER 0x02 /* Print the unknown-key header. */ +#define SALVAGE_PRINTFOOTER 0x04 /* Print the unknown-key footer. */ +#define SALVAGE_HASSUBDBS 0x08 /* There are subdatabases to salvage. */ +#define VRFY_LEAFCHAIN_BROKEN 0x10 /* Lost one or more Btree leaf pgs. */ +#define VRFY_QMETA_SET 0x20 /* We've seen a QUEUE meta page and + set things up for it. */ + u_int32_t flags; +}; /* VRFY_DBINFO */ + +/* + * The amount of state information we need per-page is small enough that + * it's not worth the trouble to define separate structures for each + * possible type of page, and since we're doing verification with these we + * have to be open to the possibility that page N will be of a completely + * unexpected type anyway. So we define one structure here with all the + * info we need for inter-page verification. + */ +struct __vrfy_pageinfo { + u_int8_t type; + u_int8_t bt_level; + u_int8_t unused1; + u_int8_t unused2; + db_pgno_t pgno; + db_pgno_t prev_pgno; + db_pgno_t next_pgno; + + /* meta pages */ + db_pgno_t root; + db_pgno_t free; /* Free list head. */ + + db_indx_t entries; /* Actual number of entries. */ + u_int16_t unused; + db_recno_t rec_cnt; /* Record count. */ + u_int32_t re_pad; /* Record pad character. */ + u_int32_t re_len; /* Record length. */ + u_int32_t bt_minkey; + u_int32_t h_ffactor; + u_int32_t h_nelem; + + /* overflow pages */ + /* + * Note that refcount is the refcount for an overflow page; pi_refcount + * is this structure's own refcount! + */ + u_int32_t refcount; + u_int32_t olen; + +#define VRFY_DUPS_UNSORTED 0x0001 /* Have to flag the negative! */ +#define VRFY_HAS_CHKSUM 0x0002 +#define VRFY_HAS_DUPS 0x0004 +#define VRFY_HAS_DUPSORT 0x0008 /* Has the flag set. */ +#define VRFY_HAS_PART_RANGE 0x0010 /* Has the flag set. */ +#define VRFY_HAS_PART_CALLBACK 0x0020 /* Has the flag set. */ +#define VRFY_HAS_RECNUMS 0x0040 +#define VRFY_HAS_SUBDBS 0x0080 +#define VRFY_INCOMPLETE 0x0100 /* Meta or item order checks incomp. */ +#define VRFY_IS_ALLZEROES 0x0200 /* Hash page we haven't touched? */ +#define VRFY_IS_FIXEDLEN 0x0400 +#define VRFY_IS_RECNO 0x0800 +#define VRFY_IS_RRECNO 0x1000 +#define VRFY_OVFL_LEAFSEEN 0x2000 +#define VRFY_HAS_COMPRESS 0x4000 + u_int32_t flags; + + LIST_ENTRY(__vrfy_pageinfo) links; + u_int32_t pi_refcount; +}; /* VRFY_PAGEINFO */ + +struct __vrfy_childinfo { + /* The following fields are set by the caller of __db_vrfy_childput. */ + db_pgno_t pgno; + +#define V_DUPLICATE 1 /* off-page dup metadata */ +#define V_OVERFLOW 2 /* overflow page */ +#define V_RECNO 3 /* btree internal or leaf page */ + u_int32_t type; + db_recno_t nrecs; /* record count on a btree subtree */ + u_int32_t tlen; /* ovfl. item total size */ + + /* The following field is maintained by __db_vrfy_childput. */ + u_int32_t refcnt; /* # of times parent points to child. */ + + LIST_ENTRY(__vrfy_childinfo) links; +}; /* VRFY_CHILDINFO */ + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_VERIFY_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/debug.h b/src/libs/resiprocate/contrib/db/dbinc/debug.h new file mode 100644 index 00000000..1c8cfd74 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/debug.h @@ -0,0 +1,277 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1998-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_DEBUG_H_ +#define _DB_DEBUG_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Turn on additional error checking in gcc 3.X. + */ +#if !defined(__GNUC__) || __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) +#define __attribute__(s) +#endif + +/* + * When running with #DIAGNOSTIC defined, we smash memory and do memory + * guarding with a special byte value. + */ +#define CLEAR_BYTE 0xdb +#define GUARD_BYTE 0xdc + +/* + * DB assertions. + * + * Use __STDC__ rather than STDC_HEADERS, the #e construct is ANSI C specific. + */ +#if defined(DIAGNOSTIC) && defined(__STDC__) +#define DB_ASSERT(env, e) \ + ((e) ? (void)0 : __db_assert(env, #e, __FILE__, __LINE__)) +#else +#define DB_ASSERT(env, e) +#endif + +/* + * "Shut that bloody compiler up!" + * + * Unused, or not-used-yet variable. We need to write and then read the + * variable, some compilers are too bloody clever by half. + */ +#define COMPQUIET(n, v) do { \ + (n) = (v); \ + (n) = (n); \ +} while (0) + +/* + * Purify and other run-time tools complain about uninitialized reads/writes + * of structure fields whose only purpose is padding, as well as when heap + * memory that was never initialized is written to disk. + */ +#ifdef UMRW +#define UMRW_SET(v) (v) = 0 +#else +#define UMRW_SET(v) +#endif + +/* + * Errors are in one of two areas: a Berkeley DB error, or a system-level + * error. We use db_strerror to translate the former and __os_strerror to + * translate the latter. + */ +typedef enum { + DB_ERROR_NOT_SET=0, + DB_ERROR_SET=1, + DB_ERROR_SYSTEM=2 +} db_error_set_t; + +/* + * Message handling. Use a macro instead of a function because va_list + * references to variadic arguments cannot be reset to the beginning of the + * variadic argument list (and then rescanned), by functions other than the + * original routine that took the variadic list of arguments. + */ +#if defined(STDC_HEADERS) || defined(__cplusplus) +#define DB_REAL_ERR(dbenv, error, error_set, app_call, fmt) { \ + va_list __ap; \ + \ + /* Call the application's callback function, if specified. */ \ + va_start(__ap, fmt); \ + if ((dbenv) != NULL && (dbenv)->db_errcall != NULL) \ + __db_errcall(dbenv, error, error_set, fmt, __ap); \ + va_end(__ap); \ + \ + /* \ + * If the application specified a file descriptor, write to it. \ + * If we wrote to neither the application's callback routine or \ + * its file descriptor, and it's an application error message \ + * using {DbEnv,Db}.{err,errx} or the application has never \ + * configured an output channel, default by writing to stderr. \ + */ \ + va_start(__ap, fmt); \ + if ((dbenv) == NULL || \ + (dbenv)->db_errfile != NULL || \ + ((dbenv)->db_errcall == NULL && \ + ((app_call) || F_ISSET((dbenv)->env, ENV_NO_OUTPUT_SET)))) \ + __db_errfile(dbenv, error, error_set, fmt, __ap); \ + va_end(__ap); \ +} +#else +#define DB_REAL_ERR(dbenv, error, error_set, app_call, fmt) { \ + va_list __ap; \ + \ + /* Call the application's callback function, if specified. */ \ + va_start(__ap); \ + if ((dbenv) != NULL && (dbenv)->db_errcall != NULL) \ + __db_errcall(dbenv, error, error_set, fmt, __ap); \ + va_end(__ap); \ + \ + /* \ + * If the application specified a file descriptor, write to it. \ + * If we wrote to neither the application's callback routine or \ + * its file descriptor, and it's an application error message \ + * using {DbEnv,Db}.{err,errx} or the application has never \ + * configured an output channel, default by writing to stderr. \ + */ \ + va_start(__ap); \ + if ((dbenv) == NULL || \ + (dbenv)->db_errfile != NULL || \ + ((dbenv)->db_errcall == NULL && \ + ((app_call) || F_ISSET((dbenv)->env, ENV_NO_OUTPUT_SET)))) \ + __db_errfile(env, error, error_set, fmt, __ap); \ + va_end(__ap); \ +} +#endif +#if defined(STDC_HEADERS) || defined(__cplusplus) +#define DB_REAL_MSG(dbenv, fmt) { \ + va_list __ap; \ + \ + /* Call the application's callback function, if specified. */ \ + va_start(__ap, fmt); \ + if ((dbenv) != NULL && (dbenv)->db_msgcall != NULL) \ + __db_msgcall(dbenv, fmt, __ap); \ + va_end(__ap); \ + \ + /* \ + * If the application specified a file descriptor, write to it. \ + * If we wrote to neither the application's callback routine or \ + * its file descriptor, write to stdout. \ + */ \ + va_start(__ap, fmt); \ + if ((dbenv) == NULL || \ + (dbenv)->db_msgfile != NULL || \ + (dbenv)->db_msgcall == NULL) { \ + __db_msgfile(dbenv, fmt, __ap); \ + } \ + va_end(__ap); \ +} +#else +#define DB_REAL_MSG(dbenv, fmt) { \ + va_list __ap; \ + \ + /* Call the application's callback function, if specified. */ \ + va_start(__ap); \ + if ((dbenv) != NULL && (dbenv)->db_msgcall != NULL) \ + __db_msgcall(dbenv, fmt, __ap); \ + va_end(__ap); \ + \ + /* \ + * If the application specified a file descriptor, write to it. \ + * If we wrote to neither the application's callback routine or \ + * its file descriptor, write to stdout. \ + */ \ + va_start(__ap); \ + if ((dbenv) == NULL || \ + (dbenv)->db_msgfile != NULL || \ + (dbenv)->db_msgcall == NULL) { \ + __db_msgfile(dbenv, fmt, __ap); \ + } \ + va_end(__ap); \ +} +#endif + +/* + * Debugging macro to log operations. + * If DEBUG_WOP is defined, log operations that modify the database. + * If DEBUG_ROP is defined, log operations that read the database. + * + * D dbp + * T txn + * O operation (string) + * K key + * A data + * F flags + */ +#define LOG_OP(C, T, O, K, A, F) { \ + DB_LSN __lsn; \ + DBT __op; \ + if (DBC_LOGGING((C))) { \ + memset(&__op, 0, sizeof(__op)); \ + __op.data = O; \ + __op.size = strlen(O) + 1; \ + (void)__db_debug_log((C)->env, T, &__lsn, 0, \ + &__op, (C)->dbp->log_filename->id, K, A, F); \ + } \ +} +#ifdef DEBUG_ROP +#define DEBUG_LREAD(C, T, O, K, A, F) LOG_OP(C, T, O, K, A, F) +#else +#define DEBUG_LREAD(C, T, O, K, A, F) +#endif +#ifdef DEBUG_WOP +#define DEBUG_LWRITE(C, T, O, K, A, F) LOG_OP(C, T, O, K, A, F) +#else +#define DEBUG_LWRITE(C, T, O, K, A, F) +#endif + +/* + * Hook for testing recovery at various places in the create/delete paths. + * Hook for testing subdb locks. + */ +#if CONFIG_TEST +#define DB_TEST_SUBLOCKS(env, flags) do { \ + if ((env)->test_abort == DB_TEST_SUBDB_LOCKS) \ + (flags) |= DB_LOCK_NOWAIT; \ +} while (0) + +#define DB_ENV_TEST_RECOVERY(env, val, ret, name) do { \ + int __ret; \ + PANIC_CHECK((env)); \ + if ((env)->test_copy == (val)) { \ + /* COPY the FILE */ \ + if ((__ret = __db_testcopy((env), NULL, (name))) != 0) \ + (ret) = __env_panic((env), __ret); \ + } \ + if ((env)->test_abort == (val)) { \ + /* ABORT the TXN */ \ + (env)->test_abort = 0; \ + (ret) = EINVAL; \ + goto db_tr_err; \ + } \ +} while (0) + +#define DB_TEST_RECOVERY(dbp, val, ret, name) do { \ + ENV *__env = (dbp)->env; \ + int __ret; \ + PANIC_CHECK(__env); \ + if (__env->test_copy == (val)) { \ + /* Copy the file. */ \ + if (F_ISSET((dbp), \ + DB_AM_OPEN_CALLED) && (dbp)->mpf != NULL) \ + (void)__db_sync(dbp); \ + if ((__ret = \ + __db_testcopy(__env, (dbp), (name))) != 0) \ + (ret) = __env_panic(__env, __ret); \ + } \ + if (__env->test_abort == (val)) { \ + /* Abort the transaction. */ \ + __env->test_abort = 0; \ + (ret) = EINVAL; \ + goto db_tr_err; \ + } \ +} while (0) + +#define DB_TEST_RECOVERY_LABEL db_tr_err: + +#define DB_TEST_WAIT(env, val) \ + if ((val) != 0) \ + __os_yield((env), (u_long)(val), 0) +#else +#define DB_TEST_SUBLOCKS(env, flags) +#define DB_ENV_TEST_RECOVERY(env, val, ret, name) +#define DB_TEST_RECOVERY(dbp, val, ret, name) +#define DB_TEST_RECOVERY_LABEL +#define DB_TEST_WAIT(env, val) +#endif + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_DEBUG_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/fop.h b/src/libs/resiprocate/contrib/db/dbinc/fop.h new file mode 100644 index 00000000..69ea61e8 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/fop.h @@ -0,0 +1,32 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2001-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_FOP_H_ +#define _DB_FOP_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +#define MAKE_INMEM(D) do { \ + F_SET((D), DB_AM_INMEM); \ + (void)__memp_set_flags((D)->mpf, DB_MPOOL_NOFILE, 1); \ +} while (0) + +#define CLR_INMEM(D) do { \ + F_CLR((D), DB_AM_INMEM); \ + (void)__memp_set_flags((D)->mpf, DB_MPOOL_NOFILE, 0); \ +} while (0) + +#include "dbinc_auto/fileops_auto.h" +#include "dbinc_auto/fileops_ext.h" + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_FOP_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/globals.h b/src/libs/resiprocate/contrib/db/dbinc/globals.h new file mode 100644 index 00000000..625fdfa7 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/globals.h @@ -0,0 +1,123 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_GLOBALS_H_ +#define _DB_GLOBALS_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************* + * Global variables. + * + * Held in a single structure to minimize the name-space pollution. + *******************************************************/ +#ifdef HAVE_VXWORKS +#include "semLib.h" +#endif + +typedef struct __db_globals { +#ifdef HAVE_BREW + struct tm ltm; /* BREW localtime structure */ +#endif +#ifdef HAVE_VXWORKS + u_int32_t db_global_init; /* VxWorks: inited */ + SEM_ID db_global_lock; /* VxWorks: global semaphore */ +#endif + + char *db_line; /* DB display string. */ + + char error_buf[40]; /* Error string buffer. */ + + int uid_init; /* srand set in UID generator */ + + u_long rand_next; /* rand/srand value */ + + u_int32_t fid_serial; /* file id counter */ + + int db_errno; /* Errno value if not available */ + + int (*j_close) __P((int)); /* Underlying OS interface jump table.*/ + void (*j_dirfree) __P((char **, int)); + int (*j_dirlist) __P((const char *, char ***, int *)); + int (*j_exists) __P((const char *, int *)); + void (*j_free) __P((void *)); + int (*j_fsync) __P((int)); + int (*j_ftruncate) __P((int, off_t)); + int (*j_ioinfo) __P((const char *, + int, u_int32_t *, u_int32_t *, u_int32_t *)); + void *(*j_malloc) __P((size_t)); + int (*j_file_map) __P((DB_ENV *, char *, size_t, int, void **)); + int (*j_file_unmap) __P((DB_ENV *, void *)); + int (*j_open) __P((const char *, int, ...)); + ssize_t (*j_pread) __P((int, void *, size_t, off_t)); + ssize_t (*j_pwrite) __P((int, const void *, size_t, off_t)); + ssize_t (*j_read) __P((int, void *, size_t)); + void *(*j_realloc) __P((void *, size_t)); + int (*j_region_map) __P((DB_ENV *, char *, size_t, int *, void **)); + int (*j_region_unmap) __P((DB_ENV *, void *)); + int (*j_rename) __P((const char *, const char *)); + int (*j_seek) __P((int, off_t, int)); + int (*j_unlink) __P((const char *)); + ssize_t (*j_write) __P((int, const void *, size_t)); + int (*j_yield) __P((u_long, u_long)); +} DB_GLOBALS; + +#ifdef HAVE_BREW +#define DB_GLOBAL(v) \ + ((DB_GLOBALS *)(((BDBApp *)GETAPPINSTANCE())->db_global_values))->v +#else +#ifdef DB_INITIALIZE_DB_GLOBALS +DB_GLOBALS __db_global_values = { +#ifdef HAVE_VXWORKS + 0, /* VxWorks: initialized */ + NULL, /* VxWorks: global semaphore */ +#endif + + "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=", + { 0 }, + 0, + 0, + 0, + 0, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; +#else +extern DB_GLOBALS __db_global_values; +#endif + +#define DB_GLOBAL(v) __db_global_values.v +#endif /* HAVE_BREW */ + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_GLOBALS_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/hash.h b/src/libs/resiprocate/contrib/db/dbinc/hash.h new file mode 100644 index 00000000..ae3fb2ee --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/hash.h @@ -0,0 +1,169 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994 + * Margo Seltzer. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef _DB_HASH_H_ +#define _DB_HASH_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Hash internal structure. */ +typedef struct hash_t { + db_pgno_t meta_pgno; /* Page number of the meta data page. */ + u_int32_t h_ffactor; /* Fill factor. */ + u_int32_t h_nelem; /* Number of elements. */ + /* Hash and compare functions. */ + u_int32_t (*h_hash) __P((DB *, const void *, u_int32_t)); + int (*h_compare) __P((DB *, const DBT *, const DBT *)); +} HASH; + +/* Cursor structure definitions. */ +typedef struct cursor_t { + /* struct __dbc_internal */ + __DBC_INTERNAL + + /* Hash private part */ + + /* Per-thread information */ + DB_LOCK hlock; /* Metadata page lock. */ + HMETA *hdr; /* Pointer to meta-data page. */ + PAGE *split_buf; /* Temporary buffer for splits. */ + + /* Hash cursor information */ + db_pgno_t bucket; /* Bucket we are traversing. */ + db_pgno_t lbucket; /* Bucket for which we are locked. */ + db_indx_t dup_off; /* Offset within a duplicate set. */ + db_indx_t dup_len; /* Length of current duplicate. */ + db_indx_t dup_tlen; /* Total length of duplicate entry. */ + u_int32_t seek_size; /* Number of bytes we need for add. */ + db_pgno_t seek_found_page;/* Page on which we can insert. */ + db_indx_t seek_found_indx;/* Insert position for item. */ + u_int32_t order; /* Relative order among deleted curs. */ + +#define H_CONTINUE 0x0001 /* Join--search strictly fwd for data */ +#define H_DELETED 0x0002 /* Cursor item is deleted. */ +#define H_DUPONLY 0x0004 /* Dups only; do not change key. */ +#define H_EXPAND 0x0008 /* Table expanded. */ +#define H_ISDUP 0x0010 /* Cursor is within duplicate set. */ +#define H_NEXT_NODUP 0x0020 /* Get next non-dup entry. */ +#define H_NOMORE 0x0040 /* No more entries in bucket. */ +#define H_OK 0x0080 /* Request succeeded. */ + u_int32_t flags; +} HASH_CURSOR; + +/* Test string. */ +#define CHARKEY "%$sniglet^&" + +/* Overflow management */ +/* + * The spares table indicates the page number at which each doubling begins. + * From this page number we subtract the number of buckets already allocated + * so that we can do a simple addition to calculate the page number here. + */ +#define BS_TO_PAGE(bucket, spares) \ + ((bucket) + (spares)[__db_log2((bucket) + 1)]) +#define BUCKET_TO_PAGE(I, B) (BS_TO_PAGE((B), (I)->hdr->spares)) + +/* Constraints about much data goes on a page. */ + +#define MINFILL 4 +#define ISBIG(I, N) (((N) > ((I)->hdr->dbmeta.pagesize / MINFILL)) ? 1 : 0) + +/* Shorthands for accessing structure */ +#define NDX_INVALID 0xFFFF +#define BUCKET_INVALID 0xFFFFFFFF + +/* On page duplicates are stored as a string of size-data-size triples. */ +#define DUP_SIZE(len) ((len) + 2 * sizeof(db_indx_t)) + +/* Log messages types (these are subtypes within a record type) */ +#define PAIR_KEYMASK 0x1 +#define PAIR_DATAMASK 0x2 +#define PAIR_DUPMASK 0x4 +#define PAIR_MASK 0xf +#define PAIR_ISKEYBIG(N) (N & PAIR_KEYMASK) +#define PAIR_ISDATABIG(N) (N & PAIR_DATAMASK) +#define PAIR_ISDATADUP(N) (N & PAIR_DUPMASK) +#define OPCODE_OF(N) (N & ~PAIR_MASK) + +#define PUTPAIR 0x20 +#define DELPAIR 0x30 +#define PUTOVFL 0x40 +#define DELOVFL 0x50 +#define HASH_UNUSED1 0x60 +#define HASH_UNUSED2 0x70 +#define SPLITOLD 0x80 +#define SPLITNEW 0x90 +#define SORTPAGE 0x100 + +/* Flags to control behavior of __ham_del_pair */ +#define HAM_DEL_NO_CURSOR 0x01 /* Don't do any cursor adjustment */ +#define HAM_DEL_NO_RECLAIM 0x02 /* Don't reclaim empty pages */ +/* Just delete onpage items (even if they are references to off-page items). */ +#define HAM_DEL_IGNORE_OFFPAGE 0x04 + +typedef enum { + DB_HAM_CURADJ_DEL = 1, + DB_HAM_CURADJ_ADD = 2, + DB_HAM_CURADJ_ADDMOD = 3, + DB_HAM_CURADJ_DELMOD = 4 +} db_ham_curadj; + +typedef enum { + DB_HAM_CHGPG = 1, + DB_HAM_DELFIRSTPG = 2, + DB_HAM_DELMIDPG = 3, + DB_HAM_DELLASTPG = 4, + DB_HAM_DUP = 5, + DB_HAM_SPLIT = 6 +} db_ham_mode; + +#if defined(__cplusplus) +} +#endif + +#include "dbinc_auto/hash_auto.h" +#include "dbinc_auto/hash_ext.h" +#include "dbinc/db_am.h" +#endif /* !_DB_HASH_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/hmac.h b/src/libs/resiprocate/contrib/db/dbinc/hmac.h new file mode 100644 index 00000000..c79abbfb --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/hmac.h @@ -0,0 +1,39 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_HMAC_H_ +#define _DB_HMAC_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Algorithm specific information. + */ +/* + * SHA1 checksumming + */ +typedef struct { + u_int32_t state[5]; + u_int32_t count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +/* + * AES assumes the SHA1 checksumming (also called MAC) + */ +#define DB_MAC_MAGIC "mac derivation key magic value" +#define DB_ENC_MAGIC "encryption and decryption key value magic" + +#if defined(__cplusplus) +} +#endif + +#include "dbinc_auto/hmac_ext.h" +#endif /* !_DB_HMAC_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/lock.h b/src/libs/resiprocate/contrib/db/dbinc/lock.h new file mode 100644 index 00000000..0d00a55d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/lock.h @@ -0,0 +1,310 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_LOCK_H_ +#define _DB_LOCK_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +#define DB_LOCK_DEFAULT_N 1000 /* Default # of locks in region. */ + +/* + * The locker id space is divided between the transaction manager and the lock + * manager. Lock IDs start at 1 and go to DB_LOCK_MAXID. Txn IDs start at + * DB_LOCK_MAXID + 1 and go up to TXN_MAXIMUM. + */ +#define DB_LOCK_INVALIDID 0 +#define DB_LOCK_MAXID 0x7fffffff + +/* + * Out of band value for a lock. Locks contain an offset into a lock region, + * so we use an invalid region offset to indicate an invalid or unset lock. + */ +#define LOCK_INVALID INVALID_ROFF +#define LOCK_ISSET(lock) ((lock).off != LOCK_INVALID) +#define LOCK_INIT(lock) ((lock).off = LOCK_INVALID) + +/* + * Macro to identify a write lock for the purpose of counting locks + * for the NUMWRITES option to deadlock detection. + */ +#define IS_WRITELOCK(m) \ + ((m) == DB_LOCK_WRITE || (m) == DB_LOCK_WWRITE || \ + (m) == DB_LOCK_IWRITE || (m) == DB_LOCK_IWR) + +/* + * Macros to lock/unlock the lock region as a whole. Mostly used for + * initialization. + */ +#define LOCK_REGION_LOCK(env) \ + MUTEX_LOCK(env, ((DB_LOCKREGION *) \ + (env)->lk_handle->reginfo.primary)->mtx_region) +#define LOCK_REGION_UNLOCK(env) \ + MUTEX_UNLOCK(env, ((DB_LOCKREGION *) \ + (env)->lk_handle->reginfo.primary)->mtx_region) + +/* + * DB_LOCKREGION -- + * The lock shared region. + */ + +typedef struct __db_lockregion { + db_mutex_t mtx_region; /* Region mutex. */ + + u_int32_t need_dd; /* flag for deadlock detector */ + u_int32_t detect; /* run dd on every conflict */ + db_timespec next_timeout; /* next time to expire a lock */ + db_mutex_t mtx_dd; /* mutex for lock object dd list. */ + db_mutex_t mtx_lockers; /* mutex for locker allocation. */ + SH_TAILQ_HEAD(__dobj) dd_objs; /* objects with waiters */ + /* free locker header */ + SH_TAILQ_HEAD(__flocker) free_lockers; + SH_TAILQ_HEAD(__lkrs) lockers; /* list of lockers */ + + db_timeout_t lk_timeout; /* timeout for locks. */ + db_timeout_t tx_timeout; /* timeout for txns. */ + + u_int32_t locker_t_size; /* size of locker hash table */ + u_int32_t object_t_size; /* size of object hash table */ + u_int32_t part_t_size; /* number of partitions */ + + roff_t conf_off; /* offset of conflicts array */ + roff_t obj_off; /* offset of object hash table */ + roff_t part_off; /* offset of partition array */ + roff_t stat_off; /* offset to object hash stats */ + roff_t locker_off; /* offset of locker hash table */ + + u_int32_t lock_id; /* Current lock(er) id to allocate. */ + u_int32_t cur_maxid; /* Current max lock(er) id. */ + u_int32_t nlockers; /* Current number of lockers. */ + int nmodes; /* Number of modes in conflict table. */ + DB_LOCK_STAT stat; /* stats about locking. */ +} DB_LOCKREGION; + +/* + * Since we will store DBTs in shared memory, we need the equivalent of a + * DBT that will work in shared memory. + */ +typedef struct __sh_dbt { + u_int32_t size; /* Byte length. */ + roff_t off; /* Region offset. */ +} SH_DBT; + +#define SH_DBT_PTR(p) ((void *)(((u_int8_t *)(p)) + (p)->off)) + +/* + * Object structures; these live in the object hash table. + */ +typedef struct __db_lockobj { + u_int32_t indx; /* Hash index of this object. */ + u_int32_t generation; /* Generation of this object. */ + SH_DBT lockobj; /* Identifies object locked. */ + SH_TAILQ_ENTRY links; /* Links for free list or hash list. */ + SH_TAILQ_ENTRY dd_links; /* Links for dd list. */ + SH_TAILQ_HEAD(__waitl) waiters; /* List of waiting locks. */ + SH_TAILQ_HEAD(__holdl) holders; /* List of held locks. */ + /* Declare room in the object to hold + * typical DB lock structures so that + * we do not have to allocate them from + * shalloc at run-time. */ + u_int8_t objdata[sizeof(struct __db_ilock)]; +} DB_LOCKOBJ; + +/* + * Locker structures; these live in the locker hash table. + */ +struct __db_locker { + u_int32_t id; /* Locker id. */ + + pid_t pid; /* Process owning locker ID */ + db_threadid_t tid; /* Thread owning locker ID */ + + u_int32_t dd_id; /* Deadlock detector id. */ + + u_int32_t nlocks; /* Number of locks held. */ + u_int32_t nwrites; /* Number of write locks held. */ + + roff_t master_locker; /* Locker of master transaction. */ + roff_t parent_locker; /* Parent of this child. */ + SH_LIST_HEAD(_child) child_locker; /* List of descendant txns; + only used in a "master" + txn. */ + SH_LIST_ENTRY child_link; /* Links transactions in the family; + elements of the child_locker + list. */ + SH_TAILQ_ENTRY links; /* Links for free and hash list. */ + SH_TAILQ_ENTRY ulinks; /* Links in-use list. */ + SH_LIST_HEAD(_held) heldby; /* Locks held by this locker. */ + db_timespec lk_expire; /* When current lock expires. */ + db_timespec tx_expire; /* When this txn expires. */ + db_timeout_t lk_timeout; /* How long do we let locks live. */ + +#define DB_LOCKER_DIRTY 0x0001 +#define DB_LOCKER_INABORT 0x0002 +#define DB_LOCKER_TIMEOUT 0x0004 + u_int32_t flags; +}; + +/* + * Map a hash index into a partition. + */ +#define LOCK_PART(reg, ndx) (ndx % (reg)->part_t_size) + +/* + * Structure that contains information about a lock table partition. + */ +typedef struct __db_lockpart{ + db_mutex_t mtx_part; /* mutex for partition*/ + /* free lock header */ + SH_TAILQ_HEAD(__flock) free_locks; + /* free obj header */ + SH_TAILQ_HEAD(__fobj) free_objs; +#ifdef HAVE_STATISTICS + DB_LOCK_PSTAT part_stat; /* Partition stats. */ +#endif +} DB_LOCKPART; + +#define FREE_LOCKS(lt, part) ((lt)->part_array[part].free_locks) +#define FREE_OBJS(lt, part) ((lt)->part_array[part].free_objs) + +/* + * DB_LOCKTAB -- + * The primary library lock data structure (i.e., the one referenced + * by the environment, as opposed to the internal one laid out in the region.) + */ +struct __db_locktab { + ENV *env; /* Environment. */ + REGINFO reginfo; /* Region information. */ + u_int8_t *conflicts; /* Pointer to conflict matrix. */ + DB_LOCKPART *part_array; /* Beginning of partition array. */ +#ifdef HAVE_STATISTICS + DB_LOCK_HSTAT *obj_stat; /* Object hash stats array. */ +#endif + DB_HASHTAB *obj_tab; /* Beginning of object hash table. */ + DB_HASHTAB *locker_tab; /* Beginning of locker hash table. */ +}; + +/* + * Test for conflicts. + * + * Cast HELD and WANTED to ints, they are usually db_lockmode_t enums. + */ +#define CONFLICTS(T, R, HELD, WANTED) \ + (T)->conflicts[((int)HELD) * (R)->nmodes + ((int)WANTED)] + +#define OBJ_LINKS_VALID(L) ((L)->links.stqe_prev != -1) + +struct __db_lock { + /* + * Wait on mutex to wait on lock. You reference your own mutex with + * ID 0 and others reference your mutex with ID 1. + */ + db_mutex_t mtx_lock; + + roff_t holder; /* Who holds this lock. */ + u_int32_t gen; /* Generation count. */ + SH_TAILQ_ENTRY links; /* Free or holder/waiter list. */ + SH_LIST_ENTRY locker_links; /* List of locks held by a locker. */ + u_int32_t refcount; /* Reference count the lock. */ + db_lockmode_t mode; /* What sort of lock. */ + roff_t obj; /* Relative offset of object struct. */ + u_int32_t indx; /* Hash index of this object. */ + db_status_t status; /* Status of this lock. */ +}; + +/* + * Flag values for __lock_put_internal: + * DB_LOCK_DOALL: Unlock all references in this lock (instead of only 1). + * DB_LOCK_FREE: Free the lock (used in checklocker). + * DB_LOCK_NOPROMOTE: Don't bother running promotion when releasing locks + * (used by __lock_put_internal). + * DB_LOCK_UNLINK: Remove from the locker links (used in checklocker). + * Make sure that these do not conflict with the interface flags because + * we pass some of those around. + */ +#define DB_LOCK_DOALL 0x010000 +#define DB_LOCK_FREE 0x040000 +#define DB_LOCK_NOPROMOTE 0x080000 +#define DB_LOCK_UNLINK 0x100000 +#define DB_LOCK_NOWAITERS 0x400000 + +/* + * Macros to get/release different types of mutexes. + */ +/* + * Operations on lock objects must be protected by a mutex, either on their + * partition or on the lock region. Lock structures associated with that + * object are protected as well. Each partition has a free list of objects + * and lock structures protected by that mutex. We want to avoid getting + * multiple mutexes, particularly in __lock_vec, when there is only a + * single partition. If there is only one partition, then all the calls + * to LOCK_SYSTEM_LOCK(UNLOCK) actually acquire(release) a lock system + * wide mutex and MUTEX_LOCK(UNLOCK)_PARTITION are no-ops. If the number + * of partitions is greater than one, then LOCK_SYSTEM_LOCK(UNLOCK) is a + * no-op, and MUTEX_LOCK(UNLOCK)_PARTITION acquire a mutex on a particular + * partition of the lock table. + */ +#define LOCK_SYSTEM_LOCK(lt, reg) do { \ + if ((reg)->part_t_size == 1) \ + MUTEX_LOCK((lt)->env, (reg)->mtx_region); \ +} while (0) +#define LOCK_SYSTEM_UNLOCK(lt, reg) do { \ + if ((reg)->part_t_size == 1) \ + MUTEX_UNLOCK((lt)->env, (reg)->mtx_region); \ +} while (0) +#define MUTEX_LOCK_PARTITION(lt, reg, p) do { \ + if ((reg)->part_t_size != 1) \ + MUTEX_LOCK((lt)->env, (lt)->part_array[p].mtx_part); \ +} while (0) +#define MUTEX_UNLOCK_PARTITION(lt, reg, p) do { \ + if ((reg)->part_t_size != 1) \ + MUTEX_UNLOCK((lt)->env, (lt)->part_array[p].mtx_part); \ +} while (0) + +#define OBJECT_LOCK(lt, reg, obj, ndx) do { \ + ndx = __lock_ohash(obj) % (reg)->object_t_size; \ + MUTEX_LOCK_PARTITION(lt, reg, LOCK_PART(reg, ndx)); \ +} while (0) + +#define OBJECT_LOCK_NDX(lt, reg, ndx) \ + MUTEX_LOCK_PARTITION(lt, reg, LOCK_PART(reg, ndx)); + +#define OBJECT_UNLOCK(lt, reg, ndx) \ + MUTEX_UNLOCK_PARTITION(lt, reg, LOCK_PART(reg, ndx)); + +/* + * Protect the object deadlock detector queue and the locker allocation + * and active queues + */ +#define LOCK_DD(env, region) \ + MUTEX_LOCK(env, (region)->mtx_dd) +#define UNLOCK_DD(env, region) \ + MUTEX_UNLOCK(env, (region)->mtx_dd) +#define LOCK_LOCKERS(env, region) \ + MUTEX_LOCK(env, (region)->mtx_lockers) +#define UNLOCK_LOCKERS(env, region) \ + MUTEX_UNLOCK(env, (region)->mtx_lockers) + +/* + * __lock_locker_hash -- + * Hash function for entering lockers into the locker hash table. + * Since these are simply 32-bit unsigned integers at the moment, + * just return the locker value. + */ +#define __lock_locker_hash(locker) (locker) +#define LOCKER_HASH(lt, reg, locker, ndx) \ + ndx = __lock_locker_hash(locker) % (reg)->locker_t_size; + +#if defined(__cplusplus) +} +#endif + +#include "dbinc_auto/lock_ext.h" +#endif /* !_DB_LOCK_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/log.h b/src/libs/resiprocate/contrib/db/dbinc/log.h new file mode 100644 index 00000000..cc397eb5 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/log.h @@ -0,0 +1,448 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_LOG_H_ +#define _DB_LOG_H_ + +#include "dbinc/db_swap.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************* + * DBREG: + * The DB file register code keeps track of open files. It's stored + * in the log subsystem's shared region, and so appears in the log.h + * header file, but is logically separate. + * The dbp may not be open if we are recovering the abort of a create. + *******************************************************/ +/* + * The per-process table that maps log file-id's to DB structures. + */ +typedef struct __db_entry { + DB *dbp; /* Open dbp for this file id. */ + int deleted; /* File was not found during open. */ +} DB_ENTRY; + +/* + * FNAME -- + * File name and id. + */ +struct __fname { + SH_TAILQ_ENTRY q; /* File name queue. */ + + pid_t pid; /* Process that owns this. */ + int32_t id; /* Logging file id. */ + int32_t old_id; /* Saved logging file id. */ + DBTYPE s_type; /* Saved DB type. */ + + roff_t fname_off; /* File name offset. */ + roff_t dname_off; /* Database name offset. */ + db_pgno_t meta_pgno; /* Page number of the meta page. */ + u_int8_t ufid[DB_FILE_ID_LEN]; /* Unique file id. */ + + u_int32_t create_txnid; /* + * Txn ID of the DB create, stored so + * we can log it at register time. + */ + db_mutex_t mutex; /* mutex from db handle. */ + /* number of txn referencing + 1 for the db handle. */ + u_int32_t txn_ref; + +#define DB_FNAME_CLOSED 0x01 /* DBP was closed. */ +#define DB_FNAME_DURABLE 0x02 /* File is durable. */ +#define DB_FNAME_INMEM 0x04 /* File is in memory. */ +#define DB_FNAME_NOTLOGGED 0x08 /* Log of close failed. */ +#define DB_FNAME_RECOVER 0x10 /* File was opened by recovery code. */ +#define DB_FNAME_RESTORED 0x20 /* File may be in restored txn. */ + u_int32_t flags; +}; + +/* File open/close register log record opcodes. */ +#define DBREG_CHKPNT 1 /* Checkpoint: file name/id dump. */ +#define DBREG_CLOSE 2 /* File close. */ +#define DBREG_OPEN 3 /* File open. */ +#define DBREG_PREOPEN 4 /* Open in mpool only. */ +#define DBREG_RCLOSE 5 /* File close after recovery. */ +#define DBREG_REOPEN 6 /* Open for in-memory database. */ + +/******************************************************* + * LOG: + * The log subsystem information. + *******************************************************/ +struct __hdr; typedef struct __hdr HDR; +struct __log; typedef struct __log LOG; +struct __log_persist; typedef struct __log_persist LOGP; + +#define LFPREFIX "log." /* Log file name prefix. */ +#define LFNAME "log.%010d" /* Log file name template. */ +#define LFNAME_V1 "log.%05d" /* Log file name template, rev 1. */ + +#define LG_MAX_DEFAULT (10 * MEGABYTE) /* 10 MB. */ +#define LG_MAX_INMEM (256 * 1024) /* 256 KB. */ +#define LG_BSIZE_INMEM (1 * MEGABYTE) /* 1 MB. */ + +/* + * Allocate a few bytes under a power-of-two value. BDB doesn't care if it's + * a power-of-two or not, and requesting slightly under a power-of-two allows + * stupid allocators to avoid wasting space. + */ +#define LG_BASE_REGION_SIZE (130000) /* 128KB - 1072B */ +#define LG_BSIZE_DEFAULT (32000) /* 32 KB - 768B */ +#define LG_CURSOR_BUF_SIZE (32000) /* 32 KB - 768B */ + +/* + * DB_LOG + * Per-process log structure. + */ +struct __db_log { + /* + * These fields need to be protected for multi-threaded support. + */ + db_mutex_t mtx_dbreg; /* Mutex for thread protection. */ + + DB_ENTRY *dbentry; /* Recovery file-id mapping. */ +#define DB_GROW_SIZE 64 + int32_t dbentry_cnt; /* Entries. Grows by DB_GROW_SIZE. */ + + /* + * These fields are only accessed when the region lock is held, so + * they do not have to be protected by the thread lock as well. + */ + u_int32_t lfname; /* Log file "name". */ + DB_FH *lfhp; /* Log file handle. */ + time_t lf_timestamp; /* Log file timestamp. */ + + u_int8_t *bufp; /* Region buffer. */ + + /* These fields are not thread protected. */ + ENV *env; /* Environment */ + REGINFO reginfo; /* Region information. */ + +#define DBLOG_AUTOREMOVE 0x01 /* Autoremove log files. */ +#define DBLOG_DIRECT 0x02 /* Do direct I/O on the log. */ +#define DBLOG_DSYNC 0x04 /* Set OS_DSYNC on the log. */ +#define DBLOG_FORCE_OPEN 0x08 /* Force the DB open even if it appears + * to be deleted. */ +#define DBLOG_INMEMORY 0x10 /* Logging is in memory. */ +#define DBLOG_OPENFILES 0x20 /* Prepared files need to be open. */ +#define DBLOG_RECOVER 0x40 /* We are in recovery. */ +#define DBLOG_ZERO 0x80 /* Zero fill the log. */ + u_int32_t flags; +}; + +/* + * HDR -- + * Log record header. + */ +struct __hdr { + u_int32_t prev; /* Previous offset. */ + u_int32_t len; /* Current length. */ + u_int8_t chksum[DB_MAC_KEY]; /* Current checksum. */ + u_int8_t iv[DB_IV_BYTES]; /* IV */ + u_int32_t orig_size; /* Original size of log record */ + /* !!! - 'size' is not written to log, must be last in hdr */ + size_t size; /* Size of header to use */ +}; + +/* + * LOG_HDR_SUM -- XOR in prev and len + * This helps avoids the race misreading the log while it + * it is being updated. + */ +#define LOG_HDR_SUM(crypto, hdr, sum) do { \ + if (crypto) { \ + ((u_int32_t *)sum)[0] ^= ((HDR *)hdr)->prev; \ + ((u_int32_t *)sum)[1] ^= ((HDR *)hdr)->len; \ + } else { \ + ((u_int32_t *)sum)[0] ^= \ + ((HDR *)hdr)->prev ^ ((HDR *)hdr)->len; \ + } \ +} while (0) + +/* + * We use HDR internally, and then when we write out, we write out + * prev, len, and then a 4-byte checksum if normal operation or + * a crypto-checksum and IV and original size if running in crypto + * mode. We must store the original size in case we pad. Set the + * size when we set up the header. We compute a DB_MAC_KEY size + * checksum regardless, but we can safely just use the first 4 bytes. + */ +#define HDR_NORMAL_SZ 12 +#define HDR_CRYPTO_SZ 12 + DB_MAC_KEY + DB_IV_BYTES + +struct __log_persist { + u_int32_t magic; /* DB_LOGMAGIC */ + u_int32_t version; /* DB_LOGVERSION */ + + u_int32_t log_size; /* Log file size. */ + u_int32_t notused; /* Historically the log file mode. */ +}; + +/* Macros to lock/unlock the log region as a whole. */ +#define LOG_SYSTEM_LOCK(env) \ + MUTEX_LOCK(env, ((LOG *) \ + (env)->lg_handle->reginfo.primary)->mtx_region) +#define LOG_SYSTEM_UNLOCK(env) \ + MUTEX_UNLOCK(env, ((LOG *) \ + (env)->lg_handle->reginfo.primary)->mtx_region) + +/* + * LOG -- + * Shared log region. One of these is allocated in shared memory, + * and describes the log. + */ +struct __log { + db_mutex_t mtx_region; /* Region mutex. */ + + db_mutex_t mtx_filelist; /* Mutex guarding file name list. */ + + LOGP persist; /* Persistent information. */ + + SH_TAILQ_HEAD(__fq1) fq; /* List of file names. */ + int32_t fid_max; /* Max fid allocated. */ + roff_t free_fid_stack; /* Stack of free file ids. */ + u_int free_fids; /* Height of free fid stack. */ + u_int free_fids_alloced; /* N free fid slots allocated. */ + + /* + * The lsn LSN is the file offset that we're about to write and which + * we will return to the user. + */ + DB_LSN lsn; /* LSN at current file offset. */ + + /* + * The f_lsn LSN is the LSN (returned to the user) that "owns" the + * first byte of the buffer. If the record associated with the LSN + * spans buffers, it may not reflect the physical file location of + * the first byte of the buffer. + */ + DB_LSN f_lsn; /* LSN of first byte in the buffer. */ + size_t b_off; /* Current offset in the buffer. */ + u_int32_t w_off; /* Current write offset in the file. */ + u_int32_t len; /* Length of the last record. */ + + DB_LSN active_lsn; /* Oldest active LSN in the buffer. */ + size_t a_off; /* Offset in the buffer of first active + file. */ + + /* + * The s_lsn LSN is the last LSN that we know is on disk, not just + * written, but synced. This field is protected by the flush mutex + * rather than by the region mutex. + */ + db_mutex_t mtx_flush; /* Mutex guarding flushing. */ + int in_flush; /* Log flush in progress. */ + DB_LSN s_lsn; /* LSN of the last sync. */ + + DB_LOG_STAT stat; /* Log statistics. */ + + /* + * This timestamp is updated anytime someone unlinks log + * files. This can happen when calling __log_vtruncate + * or replication internal init when it unlinks log files. + * + * The timestamp is used so that other processes that might + * have file handles to log files know to close/reopen them + * so they're not potentially writing to now-removed files. + */ + time_t timestamp; /* Log trunc timestamp. */ + + /* + * !!! + * NOTE: the next group of fields are NOT protected by the log + * region lock. They are protected by REP->mtx_clientdb. If you + * need access to both, you must acquire REP->mtx_clientdb + * before acquiring the log region lock. + * + * The waiting_lsn is used by the replication system. It is the + * first LSN that we are holding without putting in the log, because + * we received one or more log records out of order. Associated with + * the waiting_lsn is the number of log records that we still have to + * receive before we decide that we should request it again. + * + * The max_wait_lsn is used to control retransmission in the face + * of dropped messages. If we are requesting all records from the + * current gap (i.e., chunk of the log that we are missing), then + * the max_wait_lsn contains the first LSN that we are known to have + * in the __db.rep.db. If we requested only a single record, then + * the max_wait_lsn has the LSN of that record we requested. + */ + /* BEGIN fields protected by rep->mtx_clientdb. */ + DB_LSN waiting_lsn; /* First log record after a gap. */ + DB_LSN verify_lsn; /* LSN we are waiting to verify. */ + DB_LSN prev_ckp; /* LSN of ckp preceeding verify_lsn. */ + DB_LSN max_wait_lsn; /* Maximum LSN requested. */ + DB_LSN max_perm_lsn; /* Maximum PERMANENT LSN processed. */ + db_timespec max_lease_ts; /* Maximum Lease timestamp seen. */ + db_timespec wait_ts; /* Time to wait before requesting. */ + db_timespec rcvd_ts; /* Initial received time to wait. */ + db_timespec last_ts; /* Last time of insert in temp db. */ + /* + * The ready_lsn is also used by the replication system. It is the + * next LSN we expect to receive. It's normally equal to "lsn", + * except at the beginning of a log file, at which point it's set + * to the LSN of the first record of the new file (after the + * header), rather than to 0. + */ + DB_LSN ready_lsn; + /* + * The bulk_buf is used by replication for bulk transfer. While this + * is protected by REP->mtx_clientdb, this doesn't contend with the + * above fields because the above are used by clients and the bulk + * fields below are used by a master. + */ + roff_t bulk_buf; /* Bulk transfer buffer in region. */ + uintptr_t bulk_off; /* Current offset into bulk buffer. */ + u_int32_t bulk_len; /* Length of buffer. */ + u_int32_t bulk_flags; /* Bulk buffer flags. */ + /* END fields protected by rep->mtx_clientdb. */ + + /* + * During initialization, the log system walks forward through the + * last log file to find its end. If it runs into a checkpoint + * while it's doing so, it caches it here so that the transaction + * system doesn't need to walk through the file again on its + * initialization. + */ + DB_LSN cached_ckp_lsn; + + u_int32_t regionmax; /* Configured size of the region. */ + + roff_t buffer_off; /* Log buffer offset in the region. */ + u_int32_t buffer_size; /* Log buffer size. */ + + u_int32_t log_size; /* Log file's size. */ + u_int32_t log_nsize; /* Next log file's size. */ + + int filemode; /* Log file permissions mode. */ + + /* + * DB_LOG_AUTOREMOVE and DB_LOG_INMEMORY: not protected by a mutex, + * all we care about is if they're zero or non-zero. + */ + int db_log_autoremove; + int db_log_inmemory; + + u_int32_t ncommit; /* Number of txns waiting to commit. */ + DB_LSN t_lsn; /* LSN of first commit */ + SH_TAILQ_HEAD(__commit) commits;/* list of txns waiting to commit. */ + SH_TAILQ_HEAD(__free) free_commits;/* free list of commit structs. */ + + /* + * In-memory logs maintain a list of the start positions of all log + * files currently active in the in-memory buffer. This is to make the + * lookup from LSN to log buffer offset efficient. + */ + SH_TAILQ_HEAD(__logfile) logfiles; + SH_TAILQ_HEAD(__free_logfile) free_logfiles; +}; + +/* + * __db_commit structure -- + * One of these is allocated for each transaction waiting to commit. + */ +struct __db_commit { + db_mutex_t mtx_txnwait; /* Mutex for txn to wait on. */ + DB_LSN lsn; /* LSN of commit record. */ + SH_TAILQ_ENTRY links; /* Either on free or waiting list. */ + +#define DB_COMMIT_FLUSH 0x0001 /* Flush the log when you wake up. */ + u_int32_t flags; +}; + +/* + * Check for the proper progression of Log Sequence Numbers. + * If we are rolling forward the LSN on the page must be greater + * than or equal to the previous LSN in log record. + * We ignore NOT LOGGED LSNs. The user did an unlogged update. + * We should eventually see a log record that matches and continue + * forward. + * A ZERO LSN implies a page that was allocated prior to the recovery + * start point and then truncated later in the log. An allocation of a + * page after this page will extend the file, leaving a hole. We want to + * ignore this page until it is truncated again. + * + */ + +#define CHECK_LSN(e, redo, cmp, lsn, prev) \ + if (DB_REDO(redo) && (cmp) < 0 && \ + ((!IS_NOT_LOGGED_LSN(*(lsn)) && !IS_ZERO_LSN(*(lsn))) || \ + IS_REP_CLIENT(e))) { \ + ret = __db_check_lsn(e, lsn, prev); \ + goto out; \ + } +#define CHECK_ABORT(e, redo, cmp, lsn, prev) \ + if (redo == DB_TXN_ABORT && (cmp) != 0 && \ + ((!IS_NOT_LOGGED_LSN(*(lsn)) && !IS_ZERO_LSN(*(lsn))) || \ + IS_REP_CLIENT(e))) { \ + ret = __db_check_lsn(e, lsn, prev); \ + goto out; \ + } + +/* + * Helper for in-memory logs -- check whether an offset is in range + * in a ring buffer (inclusive of start, exclusive of end). + */ +struct __db_filestart { + u_int32_t file; + size_t b_off; + + SH_TAILQ_ENTRY links; /* Either on free or waiting list. */ +}; + +#define RINGBUF_LEN(lp, start, end) \ + ((start) < (end) ? \ + (end) - (start) : (lp)->buffer_size - ((start) - (end))) + +/* + * Internal macro to set pointer to the begin_lsn for generated + * logging routines. If begin_lsn is already set then do nothing. + * Return a pointer to the last lsn too. + */ +#undef DB_SET_TXN_LSNP +#define DB_SET_TXN_LSNP(txn, blsnp, llsnp) do { \ + DB_LSN *__lsnp; \ + TXN_DETAIL *__td; \ + __td = (txn)->td; \ + *(llsnp) = &__td->last_lsn; \ + while (__td->parent != INVALID_ROFF) \ + __td = R_ADDR(&(txn)->mgrp->reginfo, __td->parent); \ + __lsnp = &__td->begin_lsn; \ + if (IS_ZERO_LSN(*__lsnp)) \ + *(blsnp) = __lsnp; \ +} while (0) + +/* + * These are used in __log_backup to determine which LSN in the + * checkpoint record to compare and return. + */ +#define CKPLSN_CMP 0 +#define LASTCKP_CMP 1 + +/* + * Status codes indicating the validity of a log file examined by + * __log_valid(). + */ +typedef enum { + DB_LV_INCOMPLETE, + DB_LV_NONEXISTENT, + DB_LV_NORMAL, + DB_LV_OLD_READABLE, + DB_LV_OLD_UNREADABLE +} logfile_validity; + +#if defined(__cplusplus) +} +#endif + +#include "dbinc_auto/dbreg_auto.h" +#include "dbinc_auto/dbreg_ext.h" +#include "dbinc_auto/log_ext.h" +#endif /* !_DB_LOG_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/mp.h b/src/libs/resiprocate/contrib/db/dbinc/mp.h new file mode 100644 index 00000000..4c6f1802 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/mp.h @@ -0,0 +1,647 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_MP_H_ +#define _DB_MP_H_ + +#include "dbinc/atomic.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +struct __bh; typedef struct __bh BH; +struct __bh_frozen_p; typedef struct __bh_frozen_p BH_FROZEN_PAGE; +struct __bh_frozen_a; typedef struct __bh_frozen_a BH_FROZEN_ALLOC; +struct __db_mpool_hash; typedef struct __db_mpool_hash DB_MPOOL_HASH; +struct __db_mpreg; typedef struct __db_mpreg DB_MPREG; +struct __mpool; typedef struct __mpool MPOOL; + + /* We require at least 20KB of cache. */ +#define DB_CACHESIZE_MIN (20 * 1024) + +/* + * DB_MPOOLFILE initialization methods cannot be called after open is called, + * other methods cannot be called before open is called + */ +#define MPF_ILLEGAL_AFTER_OPEN(dbmfp, name) \ + if (F_ISSET(dbmfp, MP_OPEN_CALLED)) \ + return (__db_mi_open((dbmfp)->env, name, 1)); +#define MPF_ILLEGAL_BEFORE_OPEN(dbmfp, name) \ + if (!F_ISSET(dbmfp, MP_OPEN_CALLED)) \ + return (__db_mi_open((dbmfp)->env, name, 0)); + +/* + * Cache flush operations, plus modifiers. + */ +#define DB_SYNC_ALLOC 0x0001 /* Flush for allocation. */ +#define DB_SYNC_CACHE 0x0002 /* Flush entire cache. */ +#define DB_SYNC_CHECKPOINT 0x0004 /* Checkpoint. */ +#define DB_SYNC_FILE 0x0008 /* Flush file. */ +#define DB_SYNC_INTERRUPT_OK 0x0010 /* Allow interrupt and return OK. */ +#define DB_SYNC_QUEUE_EXTENT 0x0020 /* Flush a queue file with extents. */ +#define DB_SYNC_SUPPRESS_WRITE 0x0040 /* Ignore max-write configuration. */ +#define DB_SYNC_TRICKLE 0x0080 /* Trickle sync. */ + +/* + * DB_MPOOL -- + * Per-process memory pool structure. + */ +struct __db_mpool { + /* These fields need to be protected for multi-threaded support. */ + db_mutex_t mutex; /* Thread mutex. */ + + /* + * DB_MPREG structure for the DB pgin/pgout routines. + * + * Linked list of application-specified pgin/pgout routines. + */ + DB_MPREG *pg_inout; + LIST_HEAD(__db_mpregh, __db_mpreg) dbregq; + + /* List of DB_MPOOLFILE's. */ + TAILQ_HEAD(__db_mpoolfileh, __db_mpoolfile) dbmfq; + + /* + * The env and reginfo fields are not thread protected, as they are + * initialized during mpool creation, and not modified again. + */ + ENV *env; /* Enclosing environment. */ + REGINFO *reginfo; /* Underlying cache regions. */ +}; + +/* + * DB_MPREG -- + * DB_MPOOL registry of pgin/pgout functions. + */ +struct __db_mpreg { + LIST_ENTRY(__db_mpreg) q; /* Linked list. */ + + int32_t ftype; /* File type. */ + /* Pgin, pgout routines. */ + int (*pgin) __P((DB_ENV *, db_pgno_t, void *, DBT *)); + int (*pgout) __P((DB_ENV *, db_pgno_t, void *, DBT *)); +}; + +/* + * File hashing -- + * We hash each file to hash bucket based on its fileid + * or, in the case of in memory files, its name. + */ + +/* Number of file hash buckets, a small prime number */ +#define MPOOL_FILE_BUCKETS 17 + +#define FHASH(id, len) __ham_func5(NULL, id, (u_int32_t)(len)) + +#define FNBUCKET(id, len) \ + (FHASH(id, len) % MPOOL_FILE_BUCKETS) + +/* Macros to lock/unlock the mpool region as a whole. */ +#define MPOOL_SYSTEM_LOCK(env) \ + MUTEX_LOCK(env, ((MPOOL *) \ + (env)->mp_handle->reginfo[0].primary)->mtx_region) +#define MPOOL_SYSTEM_UNLOCK(env) \ + MUTEX_UNLOCK(env, ((MPOOL *) \ + (env)->mp_handle->reginfo[0].primary)->mtx_region) + +/* Macros to lock/unlock a specific mpool region. */ +#define MPOOL_REGION_LOCK(env, infop) \ + MUTEX_LOCK(env, ((MPOOL *)(infop)->primary)->mtx_region) +#define MPOOL_REGION_UNLOCK(env, infop) \ + MUTEX_UNLOCK(env, ((MPOOL *)(infop)->primary)->mtx_region) + +/* + * MPOOL -- + * Shared memory pool region. + */ +struct __mpool { + /* + * The memory pool can be broken up into individual pieces/files. + * There are two reasons for this: firstly, on Solaris you can allocate + * only a little more than 2GB of memory in a contiguous chunk, + * and I expect to see more systems with similar issues. Secondly, + * applications can add / remove pieces to dynamically resize the + * cache. + * + * While this structure is duplicated in each piece of the cache, + * the first of these pieces/files describes the entire pool, the + * second only describe a piece of the cache. + */ + db_mutex_t mtx_region; /* Region mutex. */ + db_mutex_t mtx_resize; /* Resizing mutex. */ + + /* + * The lsn field and list of underlying MPOOLFILEs are thread protected + * by the region lock. + */ + DB_LSN lsn; /* Maximum checkpoint LSN. */ + + /* Configuration information: protected by the region lock. */ + u_int32_t max_nreg; /* Maximum number of regions. */ + size_t mp_mmapsize; /* Maximum file size for mmap. */ + int mp_maxopenfd; /* Maximum open file descriptors. */ + int mp_maxwrite; /* Maximum buffers to write. */ + db_timeout_t mp_maxwrite_sleep; /* Sleep after writing max buffers. */ + + /* + * The number of regions and the total number of hash buckets across + * all regions. + * These fields are not protected by a mutex because we assume that we + * can read a 32-bit value atomically. They are only modified by cache + * resizing which holds the mpool resizing mutex to ensure that + * resizing is single-threaded. See the comment in mp_resize.c for + * more information. + */ + u_int32_t nreg; /* Number of underlying REGIONS. */ + u_int32_t nbuckets; /* Total number of hash buckets. */ + + /* + * The regid field is protected by the resize mutex. + */ + roff_t regids; /* Array of underlying REGION Ids. */ + + roff_t ftab; /* Hash table of files. */ + + /* + * The following fields describe the per-cache portion of the region. + * + * The htab and htab_buckets fields are not thread protected as they + * are initialized during mpool creation, and not modified again. + * + * The last_checked and lru_count fields are thread protected by + * the region lock. + */ + roff_t htab; /* Hash table offset. */ + u_int32_t htab_buckets; /* Number of hash table entries. */ + u_int32_t last_checked; /* Last bucket checked for free. */ + u_int32_t lru_count; /* Counter for buffer LRU. */ + int32_t lru_reset; /* Hash bucket lru reset point. */ + + /* + * The stat fields are generally not thread protected, and cannot be + * trusted. Note that st_pages is an exception, and is always updated + * inside a region lock (although it is sometimes read outside of the + * region lock). + */ + DB_MPOOL_STAT stat; /* Per-cache mpool statistics. */ + + /* + * We track page puts so that we can decide when allocation is never + * going to succeed. We don't lock the field, all we care about is + * if it changes. + */ + u_int32_t put_counter; /* Count of page put calls. */ + + /* + * Cache flush operations take a long time... + * + * Some cache flush operations want to ignore the app's configured + * max-write parameters (they are trying to quickly shut down an + * environment, for example). We can't specify that as an argument + * to the cache region functions, because we may decide to ignore + * the max-write configuration after the cache operation has begun. + * If the variable suppress_maxwrite is set, ignore the application + * max-write config. + * + * We may want to interrupt cache flush operations in high-availability + * configurations. + */ +#define DB_MEMP_SUPPRESS_WRITE 0x01 +#define DB_MEMP_SYNC_INTERRUPT 0x02 + u_int32_t config_flags; + + /* Free frozen buffer headers, protected by the region lock. */ + SH_TAILQ_HEAD(__free_frozen) free_frozen; + + /* Allocated blocks of frozen buffer headers. */ + SH_TAILQ_HEAD(__alloc_frozen) alloc_frozen; +}; + +/* + * NREGION -- + * Select a cache region given the bucket number. + */ +#define NREGION(mp, bucket) \ + ((bucket) / (mp)->htab_buckets) + +/* + * MP_HASH -- + * We make the assumption that early pages of the file are more likely + * to be retrieved than the later pages, which means the top bits will + * be more interesting for hashing as they're less likely to collide. + * That said, as 512 8K pages represents a 4MB file, so only reasonably + * large files will have page numbers with any other than the bottom 9 + * bits set. We XOR in the MPOOL offset of the MPOOLFILE that backs the + * page, since that should also be unique for the page. We don't want + * to do anything very fancy -- speed is more important to us than using + * good hashing. + * + * Since moving to a dynamic hash, which boils down to using some of the + * least significant bits of the hash value, we no longer want to use a + * simple shift here, because it's likely with a bit shift that mf_offset + * will be ignored, and pages from different files end up in the same + * hash bucket. Use a nearby prime instead. + */ +#define MP_HASH(mf_offset, pgno) \ + ((((pgno) << 8) ^ (pgno)) ^ (((u_int32_t) mf_offset) * 509)) + +/* + * Inline the calculation of the mask, since we can't reliably store the mask + * with the number of buckets in the region. + * + * This is equivalent to: + * mask = (1 << __db_log2(nbuckets)) - 1; + */ +#define MP_MASK(nbuckets, mask) do { \ + for (mask = 1; mask < (nbuckets); mask = (mask << 1) | 1) \ + ; \ +} while (0) + +#define MP_HASH_BUCKET(hash, nbuckets, mask, bucket) do { \ + (bucket) = (hash) & (mask); \ + if ((bucket) >= (nbuckets)) \ + (bucket) &= ((mask) >> 1); \ +} while (0) + +#define MP_BUCKET(mf_offset, pgno, nbuckets, bucket) do { \ + u_int32_t __mask; \ + MP_MASK(nbuckets, __mask); \ + MP_HASH_BUCKET(MP_HASH(mf_offset, pgno), nbuckets, \ + __mask, bucket); \ +} while (0) + +/* + * MP_GET_REGION -- + * Select the region for a given page. + */ +#define MP_GET_REGION(dbmfp, pgno, infopp, ret) do { \ + DB_MPOOL *__t_dbmp; \ + MPOOL *__t_mp; \ + \ + __t_dbmp = dbmfp->env->mp_handle; \ + __t_mp = __t_dbmp->reginfo[0].primary; \ + if (__t_mp->max_nreg == 1) { \ + *(infopp) = &__t_dbmp->reginfo[0]; \ + } else \ + ret = __memp_get_bucket((dbmfp)->env, \ + (dbmfp)->mfp, (pgno), (infopp), NULL, NULL); \ +} while (0) + +/* + * MP_GET_BUCKET -- + * Select and lock the bucket for a given page. + */ +#define MP_GET_BUCKET(env, mfp, pgno, infopp, hp, bucket, ret) do { \ + DB_MPOOL *__t_dbmp; \ + MPOOL *__t_mp; \ + roff_t __t_mf_offset; \ + \ + __t_dbmp = (env)->mp_handle; \ + __t_mp = __t_dbmp->reginfo[0].primary; \ + if (__t_mp->max_nreg == 1) { \ + *(infopp) = &__t_dbmp->reginfo[0]; \ + __t_mf_offset = R_OFFSET(*(infopp), (mfp)); \ + MP_BUCKET(__t_mf_offset, \ + (pgno), __t_mp->nbuckets, bucket); \ + (hp) = R_ADDR(*(infopp), __t_mp->htab); \ + (hp) = &(hp)[bucket]; \ + MUTEX_READLOCK(env, (hp)->mtx_hash); \ + ret = 0; \ + } else \ + ret = __memp_get_bucket((env), \ + (mfp), (pgno), (infopp), &(hp), &(bucket)); \ +} while (0) + +struct __db_mpool_hash { + db_mutex_t mtx_hash; /* Per-bucket mutex. */ + + DB_HASHTAB hash_bucket; /* Head of bucket. */ + + db_atomic_t hash_page_dirty;/* Count of dirty pages. */ + +#ifndef __TEST_DB_NO_STATISTICS + u_int32_t hash_io_wait; /* Count of I/O waits. */ + u_int32_t hash_frozen; /* Count of frozen buffers. */ + u_int32_t hash_thawed; /* Count of thawed buffers. */ + u_int32_t hash_frozen_freed;/* Count of freed frozen buffers. */ +#endif + + DB_LSN old_reader; /* Oldest snapshot reader (cached). */ + + u_int32_t flags; +}; + +/* + * The base mpool priority is 1/4th of the name space, or just under 2^30. + * When the LRU counter wraps, we shift everybody down to a base-relative + * value. + */ +#define MPOOL_BASE_DECREMENT (UINT32_MAX - (UINT32_MAX / 4)) + +/* + * Mpool priorities from low to high. Defined in terms of fractions of the + * buffers in the pool. + */ +#define MPOOL_PRI_VERY_LOW -1 /* Dead duck. Check and set to 0. */ +#define MPOOL_PRI_LOW -2 /* Low. */ +#define MPOOL_PRI_DEFAULT 0 /* No adjustment -- special case.*/ +#define MPOOL_PRI_HIGH 10 /* With the dirty buffers. */ +#define MPOOL_PRI_DIRTY 10 /* Dirty gets a 10% boost. */ +#define MPOOL_PRI_VERY_HIGH 1 /* Add number of buffers in pool. */ + +/* + * MPOOLFILE -- + * Shared DB_MPOOLFILE information. + */ +struct __mpoolfile { + db_mutex_t mutex; /* MPOOLFILE mutex. */ + + /* Protected by MPOOLFILE mutex. */ + u_int32_t mpf_cnt; /* Ref count: DB_MPOOLFILEs. */ + u_int32_t block_cnt; /* Ref count: blocks in cache. */ + db_pgno_t last_pgno; /* Last page in the file. */ + db_pgno_t last_flushed_pgno; /* Last page flushed to disk. */ + db_pgno_t orig_last_pgno; /* Original last page in the file. */ + db_pgno_t maxpgno; /* Maximum page number. */ + + roff_t path_off; /* File name location. */ + + /* Protected by hash bucket mutex. */ + SH_TAILQ_ENTRY q; /* List of MPOOLFILEs */ + + /* + * The following are used for file compaction processing. + * They are only used when a thread is in the process + * of trying to move free pages to the end of the file. + * Other threads may look here when freeing a page. + * Protected by a lock on the metapage. + */ + u_int32_t free_ref; /* Refcount to freelist. */ + u_int32_t free_cnt; /* Count of free pages. */ + size_t free_size; /* Allocated size of free list. */ + roff_t free_list; /* Offset to free list. */ + + /* + * We normally don't lock the deadfile field when we read it since we + * only care if the field is zero or non-zero. We do lock on read when + * searching for a matching MPOOLFILE -- see that code for more detail. + */ + int32_t deadfile; /* Dirty pages can be discarded. */ + + u_int32_t bucket; /* hash bucket for this file. */ + + /* + * None of the following fields are thread protected. + * + * There are potential races with the ftype field because it's read + * without holding a lock. However, it has to be set before adding + * any buffers to the cache that depend on it being set, so there + * would need to be incorrect operation ordering to have a problem. + */ + int32_t ftype; /* File type. */ + + /* + * There are potential races with the priority field because it's read + * without holding a lock. However, a collision is unlikely and if it + * happens is of little consequence. + */ + int32_t priority; /* Priority when unpinning buffer. */ + + /* + * There are potential races with the file_written field (many threads + * may be writing blocks at the same time), and with no_backing_file + * and unlink_on_close fields, as they may be set while other threads + * are reading them. However, we only care if the field value is zero + * or non-zero, so don't lock the memory. + * + * !!! + * Theoretically, a 64-bit architecture could put two of these fields + * in a single memory operation and we could race. I have never seen + * an architecture where that's a problem, and I believe Java requires + * that to never be the case. + * + * File_written is set whenever a buffer is marked dirty in the cache. + * It can be cleared in some cases, after all dirty buffers have been + * written AND the file has been flushed to disk. + */ + int32_t file_written; /* File was written. */ + int32_t no_backing_file; /* Never open a backing file. */ + int32_t unlink_on_close; /* Unlink file on last close. */ + int32_t multiversion; /* Number of DB_MULTIVERSION handles. */ + + /* + * We do not protect the statistics in "stat" because of the cost of + * the mutex in the get/put routines. There is a chance that a count + * will get lost. + */ + DB_MPOOL_FSTAT stat; /* Per-file mpool statistics. */ + + /* + * The remaining fields are initialized at open and never subsequently + * modified. + */ + int32_t lsn_off; /* Page's LSN offset. */ + u_int32_t clear_len; /* Bytes to clear on page create. */ + + roff_t fileid_off; /* File ID string location. */ + + roff_t pgcookie_len; /* Pgin/pgout cookie length. */ + roff_t pgcookie_off; /* Pgin/pgout cookie location. */ + + /* + * The flags are initialized at open and never subsequently modified. + */ +#define MP_CAN_MMAP 0x001 /* If the file can be mmap'd. */ +#define MP_DIRECT 0x002 /* No OS buffering. */ +#define MP_DURABLE_UNKNOWN 0x004 /* We don't care about durability. */ +#define MP_EXTENT 0x008 /* Extent file. */ +#define MP_FAKE_DEADFILE 0x010 /* Deadfile field: fake flag. */ +#define MP_FAKE_FILEWRITTEN 0x020 /* File_written field: fake flag. */ +#define MP_FAKE_NB 0x040 /* No_backing_file field: fake flag. */ +#define MP_FAKE_UOC 0x080 /* Unlink_on_close field: fake flag. */ +#define MP_NOT_DURABLE 0x100 /* File is not durable. */ +#define MP_TEMP 0x200 /* Backing file is a temporary. */ + u_int32_t flags; +}; + +/* + * Flags to __memp_bh_free. + */ +#define BH_FREE_FREEMEM 0x01 +#define BH_FREE_REUSE 0x02 +#define BH_FREE_UNLOCKED 0x04 + +/* + * BH -- + * Buffer header. + */ +struct __bh { + db_mutex_t mtx_buf; /* Shared/Exclusive mutex */ + db_atomic_t ref; /* Reference count. */ +#define BH_REFCOUNT(bhp) atomic_read(&(bhp)->ref) + +#define BH_CALLPGIN 0x001 /* Convert the page before use. */ +#define BH_DIRTY 0x002 /* Page is modified. */ +#define BH_DIRTY_CREATE 0x004 /* Page is modified. */ +#define BH_DISCARD 0x008 /* Page is useless. */ +#define BH_EXCLUSIVE 0x010 /* Exclusive access acquired. */ +#define BH_FREED 0x020 /* Page was freed. */ +#define BH_FROZEN 0x040 /* Frozen buffer: allocate & re-read. */ +#define BH_TRASH 0x080 /* Page is garbage. */ +#define BH_THAWED 0x100 /* Page was thawed. */ + u_int16_t flags; + + u_int32_t priority; /* Priority. */ + SH_TAILQ_ENTRY hq; /* MPOOL hash bucket queue. */ + + db_pgno_t pgno; /* Underlying MPOOLFILE page number. */ + roff_t mf_offset; /* Associated MPOOLFILE offset. */ + u_int32_t bucket; /* Hash bucket containing header. */ + int region; /* Region containing header. */ + + roff_t td_off; /* MVCC: creating TXN_DETAIL offset. */ + SH_CHAIN_ENTRY vc; /* MVCC: version chain. */ +#ifdef DIAG_MVCC + u_int16_t align_off; /* Alignment offset for diagnostics.*/ +#endif + + /* + * !!! + * This array must be at least size_t aligned -- the DB access methods + * put PAGE and other structures into it, and then access them directly. + * (We guarantee size_t alignment to applications in the documentation, + * too.) + */ + u_int8_t buf[1]; /* Variable length data. */ +}; + +/* + * BH_FROZEN_PAGE -- + * Data used to find a frozen buffer header. + */ +struct __bh_frozen_p { + BH header; + db_pgno_t spgno; /* Page number in freezer file. */ +}; + +/* + * BH_FROZEN_ALLOC -- + * Frozen buffer headers are allocated a page at a time in general. This + * structure is allocated at the beginning of the page so that the + * allocation chunks can be tracked and freed (for private environments). + */ +struct __bh_frozen_a { + SH_TAILQ_ENTRY links; +}; + +#define MULTIVERSION(dbp) ((dbp)->mpf->mfp->multiversion) +#define IS_DIRTY(p) \ + (F_ISSET((BH *)((u_int8_t *) \ + (p) - SSZA(BH, buf)), BH_DIRTY|BH_EXCLUSIVE) == (BH_DIRTY|BH_EXCLUSIVE)) + +#define IS_VERSION(dbp, p) \ + (!F_ISSET(dbp->mpf->mfp, MP_CAN_MMAP) && \ + SH_CHAIN_HASPREV((BH *)((u_int8_t *)(p) - SSZA(BH, buf)), vc)) + +#define BH_OWNER(env, bhp) \ + ((TXN_DETAIL *)R_ADDR(&env->tx_handle->reginfo, bhp->td_off)) + +#define BH_OWNED_BY(env, bhp, txn) ((txn) != NULL && \ + (bhp)->td_off != INVALID_ROFF && \ + (txn)->td == BH_OWNER(env, bhp)) + +#define VISIBLE_LSN(env, bhp) \ + (&BH_OWNER(env, bhp)->visible_lsn) + +/* + * Make a copy of the buffer's visible LSN, one field at a time. We rely on the + * 32-bit operations being atomic. The visible_lsn starts at MAX_LSN and is + * set during commit or abort to the current LSN. + * + * If we race with a commit / abort, we may see either the file or the offset + * still at UINT32_MAX, so vlsn is guaranteed to be in the future. That's OK, + * since we had to take the log region lock to allocate the read LSN so we were + * never going to see this buffer anyway. + */ +#define BH_VISIBLE(env, bhp, read_lsnp, vlsn) \ + (bhp->td_off == INVALID_ROFF || \ + ((vlsn).file = VISIBLE_LSN(env, bhp)->file, \ + (vlsn).offset = VISIBLE_LSN(env, bhp)->offset, \ + LOG_COMPARE((read_lsnp), &(vlsn)) >= 0)) + +#define BH_OBSOLETE(bhp, old_lsn, vlsn) (SH_CHAIN_HASNEXT(bhp, vc) ? \ + BH_VISIBLE(env, SH_CHAIN_NEXTP(bhp, vc, __bh), &(old_lsn), vlsn) :\ + BH_VISIBLE(env, bhp, &(old_lsn), vlsn)) + +#define MVCC_SKIP_CURADJ(dbc, pgno) (dbc->txn != NULL && \ + F_ISSET(dbc->txn, TXN_SNAPSHOT) && MULTIVERSION(dbc->dbp) && \ + dbc->txn->td != NULL && __memp_skip_curadj(dbc, pgno)) + +#if defined(DIAG_MVCC) && defined(HAVE_MPROTECT) +#define VM_PAGESIZE 4096 +#define MVCC_BHSIZE(mfp, sz) do { \ + sz += VM_PAGESIZE + sizeof(BH); \ + if (mfp->stat.st_pagesize < VM_PAGESIZE) \ + sz += VM_PAGESIZE - mfp->stat.st_pagesize; \ +} while (0) + +#define MVCC_BHALIGN(p) do { \ + BH *__bhp; \ + void *__orig = (p); \ + p = ALIGNP_INC(p, VM_PAGESIZE); \ + if ((u_int8_t *)p < (u_int8_t *)__orig + sizeof(BH)) \ + p = (u_int8_t *)p + VM_PAGESIZE; \ + __bhp = (BH *)((u_int8_t *)p - SSZA(BH, buf)); \ + DB_ASSERT(env, \ + ((uintptr_t)__bhp->buf & (VM_PAGESIZE - 1)) == 0); \ + DB_ASSERT(env, \ + (u_int8_t *)__bhp >= (u_int8_t *)__orig); \ + DB_ASSERT(env, (u_int8_t *)p + mfp->stat.st_pagesize < \ + (u_int8_t *)__orig + len); \ + __bhp->align_off = \ + (u_int16_t)((u_int8_t *)__bhp - (u_int8_t *)__orig); \ + p = __bhp; \ +} while (0) + +#define MVCC_BHUNALIGN(bhp) do { \ + (bhp) = (BH *)((u_int8_t *)(bhp) - (bhp)->align_off); \ +} while (0) + +#ifdef linux +#define MVCC_MPROTECT(buf, sz, mode) do { \ + int __ret = mprotect((buf), (sz), (mode)); \ + DB_ASSERT(env, __ret == 0); \ +} while (0) +#else +#define MVCC_MPROTECT(buf, sz, mode) do { \ + if (!F_ISSET(env, ENV_PRIVATE | ENV_SYSTEM_MEM)) { \ + int __ret = mprotect((buf), (sz), (mode)); \ + DB_ASSERT(env, __ret == 0); \ + } \ +} while (0) +#endif /* linux */ + +#else /* defined(DIAG_MVCC) && defined(HAVE_MPROTECT) */ +#define MVCC_BHSIZE(mfp, sz) do {} while (0) +#define MVCC_BHALIGN(p) do {} while (0) +#define MVCC_BHUNALIGN(bhp) do {} while (0) +#define MVCC_MPROTECT(buf, size, mode) do {} while (0) +#endif + +/* + * Flags to __memp_ftruncate. + */ +#define MP_TRUNC_RECOVER 0x01 + +#if defined(__cplusplus) +} +#endif + +#include "dbinc_auto/mp_ext.h" +#endif /* !_DB_MP_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/mutex.h b/src/libs/resiprocate/contrib/db/dbinc/mutex.h new file mode 100644 index 00000000..028cbb36 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/mutex.h @@ -0,0 +1,277 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_MUTEX_H_ +#define _DB_MUTEX_H_ + +#ifdef HAVE_MUTEX_SUPPORT +/* The inlined trylock calls need access to the details of mutexes. */ +#define LOAD_ACTUAL_MUTEX_CODE +#include "dbinc/mutex_int.h" + +#ifndef HAVE_SHARED_LATCHES + #error "Shared latches are required in DB 4.8 and above" +#endif +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * By default, spin 50 times per processor if fail to acquire a test-and-set + * mutex, we have anecdotal evidence it's a reasonable value. + */ +#define MUTEX_SPINS_PER_PROCESSOR 50 + +/* + * Mutexes are represented by unsigned, 32-bit integral values. As the + * OOB value is 0, mutexes can be initialized by zero-ing out the memory + * in which they reside. + */ +#define MUTEX_INVALID 0 + +/* + * We track mutex allocations by ID. + */ +#define MTX_APPLICATION 1 +#define MTX_ATOMIC_EMULATION 2 +#define MTX_DB_HANDLE 3 +#define MTX_ENV_DBLIST 4 +#define MTX_ENV_HANDLE 5 +#define MTX_ENV_REGION 6 +#define MTX_LOCK_REGION 7 +#define MTX_LOGICAL_LOCK 8 +#define MTX_LOG_FILENAME 9 +#define MTX_LOG_FLUSH 10 +#define MTX_LOG_HANDLE 11 +#define MTX_LOG_REGION 12 +#define MTX_MPOOLFILE_HANDLE 13 +#define MTX_MPOOL_BH 14 +#define MTX_MPOOL_FH 15 +#define MTX_MPOOL_FILE_BUCKET 16 +#define MTX_MPOOL_HANDLE 17 +#define MTX_MPOOL_HASH_BUCKET 18 +#define MTX_MPOOL_REGION 19 +#define MTX_MUTEX_REGION 20 +#define MTX_MUTEX_TEST 21 +#define MTX_REP_CHKPT 22 +#define MTX_REP_DATABASE 23 +#define MTX_REP_EVENT 24 +#define MTX_REP_REGION 25 +#define MTX_REPMGR 26 +#define MTX_SEQUENCE 27 +#define MTX_TWISTER 28 +#define MTX_TXN_ACTIVE 29 +#define MTX_TXN_CHKPT 30 +#define MTX_TXN_COMMIT 31 +#define MTX_TXN_MVCC 32 +#define MTX_TXN_REGION 33 + +#define MTX_MAX_ENTRY 33 + +/* Redirect mutex calls to the correct functions. */ +#if !defined(HAVE_MUTEX_HYBRID) && ( \ + defined(HAVE_MUTEX_PTHREADS) || \ + defined(HAVE_MUTEX_SOLARIS_LWP) || \ + defined(HAVE_MUTEX_UI_THREADS)) +#define __mutex_init(a, b, c) __db_pthread_mutex_init(a, b, c) +#define __mutex_lock(a, b) __db_pthread_mutex_lock(a, b) +#define __mutex_unlock(a, b) __db_pthread_mutex_unlock(a, b) +#define __mutex_destroy(a, b) __db_pthread_mutex_destroy(a, b) +#define __mutex_trylock(a, b) __db_pthread_mutex_trylock(a, b) +/* + * These trylock versions do not support DB_ENV_FAILCHK. Callers which loop + * checking mutexes which are held by dead processes or threads might spin. + * These have ANSI-style definitions because this file can be included by + * C++ files, and extern "C" affects linkage only, not argument typing. + */ +static inline int __db_pthread_mutex_trylock(ENV *env, db_mutex_t mutex) +{ + int ret; + DB_MUTEX *mutexp; + if (!MUTEX_ON(env) || F_ISSET(env->dbenv, DB_ENV_NOLOCKING)) + return (0); + mutexp = MUTEXP_SET(env->mutex_handle, mutex); +#ifdef HAVE_SHARED_LATCHES + if (F_ISSET(mutexp, DB_MUTEX_SHARED)) + ret = pthread_rwlock_trywrlock(&mutexp->u.rwlock); + else +#endif + if ((ret = pthread_mutex_trylock(&mutexp->u.m.mutex)) == 0) + F_SET(mutexp, DB_MUTEX_LOCKED); + if (ret == EBUSY) + ret = DB_LOCK_NOTGRANTED; +#ifdef HAVE_STATISTICS + if (ret == 0) + ++mutexp->mutex_set_nowait; +#endif + return (ret); +} +#ifdef HAVE_SHARED_LATCHES +#define __mutex_rdlock(a, b) __db_pthread_mutex_readlock(a, b) +#define __mutex_tryrdlock(a, b) __db_pthread_mutex_tryreadlock(a, b) +static inline int __db_pthread_mutex_tryreadlock(ENV *env, db_mutex_t mutex) +{ + int ret; + DB_MUTEX *mutexp; + if (!MUTEX_ON(env) || F_ISSET(env->dbenv, DB_ENV_NOLOCKING)) + return (0); + mutexp = MUTEXP_SET(env->mutex_handle, mutex); + if (F_ISSET(mutexp, DB_MUTEX_SHARED)) + ret = pthread_rwlock_tryrdlock(&mutexp->u.rwlock); + else + return (EINVAL); + if (ret == EBUSY) + ret = DB_LOCK_NOTGRANTED; +#ifdef HAVE_STATISTICS + if (ret == 0) + ++mutexp->mutex_set_rd_nowait; +#endif + return (ret); +} +#endif +#elif defined(HAVE_MUTEX_WIN32) || defined(HAVE_MUTEX_WIN32_GCC) +#define __mutex_init(a, b, c) __db_win32_mutex_init(a, b, c) +#define __mutex_lock(a, b) __db_win32_mutex_lock(a, b) +#define __mutex_trylock(a, b) __db_win32_mutex_trylock(a, b) +#define __mutex_unlock(a, b) __db_win32_mutex_unlock(a, b) +#define __mutex_destroy(a, b) __db_win32_mutex_destroy(a, b) +#ifdef HAVE_SHARED_LATCHES +#define __mutex_rdlock(a, b) __db_win32_mutex_readlock(a, b) +#define __mutex_tryrdlock(a, b) __db_win32_mutex_tryreadlock(a, b) +#endif +#elif defined(HAVE_MUTEX_FCNTL) +#define __mutex_init(a, b, c) __db_fcntl_mutex_init(a, b, c) +#define __mutex_lock(a, b) __db_fcntl_mutex_lock(a, b) +#define __mutex_trylock(a, b) __db_fcntl_mutex_trylock(a, b) +#define __mutex_unlock(a, b) __db_fcntl_mutex_unlock(a, b) +#define __mutex_destroy(a, b) __db_fcntl_mutex_destroy(a, b) +#else +#define __mutex_init(a, b, c) __db_tas_mutex_init(a, b, c) +#define __mutex_lock(a, b) __db_tas_mutex_lock(a, b) +#define __mutex_trylock(a, b) __db_tas_mutex_trylock(a, b) +#define __mutex_unlock(a, b) __db_tas_mutex_unlock(a, b) +#define __mutex_destroy(a, b) __db_tas_mutex_destroy(a, b) +#if defined(HAVE_SHARED_LATCHES) +#define __mutex_rdlock(a, b) __db_tas_mutex_readlock(a, b) +#define __mutex_tryrdlock(a,b) __db_tas_mutex_tryreadlock(a, b) +#endif +#endif + +/* + * When there is no method to get a shared latch, fall back to + * implementing __mutex_rdlock() as getting an exclusive one. + * This occurs either when !HAVE_SHARED_LATCHES or HAVE_MUTEX_FCNTL. + */ +#ifndef __mutex_rdlock +#define __mutex_rdlock(a, b) __mutex_lock(a, b) +#endif +#ifndef __mutex_tryrdlock +#define __mutex_tryrdlock(a, b) __mutex_trylock(a, b) +#endif + +/* + * Lock/unlock a mutex. If the mutex was never required, the thread of + * control can proceed without it. + * + * We never fail to acquire or release a mutex without panicing. Simplify + * the macros to always return a panic value rather than saving the actual + * return value of the mutex routine. + */ +#ifdef HAVE_MUTEX_SUPPORT +#define MUTEX_LOCK(env, mutex) do { \ + if ((mutex) != MUTEX_INVALID && \ + __mutex_lock(env, mutex) != 0) \ + return (DB_RUNRECOVERY); \ +} while (0) + +/* + * Always check the return value of MUTEX_TRYLOCK()! Expect 0 on success, + * or DB_LOCK_NOTGRANTED, or possibly DB_RUNRECOVERY for failchk. + */ +#define MUTEX_TRYLOCK(env, mutex) \ + (((mutex) == MUTEX_INVALID) ? 0 : __mutex_trylock(env, mutex)) + +/* + * Acquire a DB_MUTEX_SHARED "mutex" in shared mode. + */ +#define MUTEX_READLOCK(env, mutex) do { \ + if ((mutex) != MUTEX_INVALID && \ + __mutex_rdlock(env, mutex) != 0) \ + return (DB_RUNRECOVERY); \ +} while (0) +#define MUTEX_TRY_READLOCK(env, mutex) \ + ((mutex) != MUTEX_INVALID ? __mutex_tryrdlock(env, mutex) : 0) + +#define MUTEX_UNLOCK(env, mutex) do { \ + if ((mutex) != MUTEX_INVALID && \ + __mutex_unlock(env, mutex) != 0) \ + return (DB_RUNRECOVERY); \ +} while (0) +#else +/* + * There are calls to lock/unlock mutexes outside of #ifdef's -- replace + * the call with something the compiler can discard, but which will make + * if-then-else blocks work correctly. + */ +#define MUTEX_LOCK(env, mutex) (mutex) = (mutex) +#define MUTEX_TRYLOCK(env, mutex) (mutex) = (mutex) +#define MUTEX_READLOCK(env, mutex) (mutex) = (mutex) +#define MUTEX_TRY_READLOCK(env, mutex) (mutex) = (mutex) +#define MUTEX_UNLOCK(env, mutex) (mutex) = (mutex) +#define MUTEX_REQUIRED(env, mutex) (mutex) = (mutex) +#define MUTEX_REQUIRED_READ(env, mutex) (mutex) = (mutex) +#endif + +/* + * Berkeley DB ports may require single-threading at places in the code. + */ +#ifdef HAVE_MUTEX_VXWORKS +#include "taskLib.h" +/* + * Use the taskLock() mutex to eliminate a race where two tasks are + * trying to initialize the global lock at the same time. + */ +#define DB_BEGIN_SINGLE_THREAD do { \ + if (DB_GLOBAL(db_global_init)) \ + (void)semTake(DB_GLOBAL(db_global_lock), WAIT_FOREVER); \ + else { \ + taskLock(); \ + if (DB_GLOBAL(db_global_init)) { \ + taskUnlock(); \ + (void)semTake(DB_GLOBAL(db_global_lock), \ + WAIT_FOREVER); \ + continue; \ + } \ + DB_GLOBAL(db_global_lock) = \ + semBCreate(SEM_Q_FIFO, SEM_EMPTY); \ + if (DB_GLOBAL(db_global_lock) != NULL) \ + DB_GLOBAL(db_global_init) = 1; \ + taskUnlock(); \ + } \ +} while (DB_GLOBAL(db_global_init) == 0) +#define DB_END_SINGLE_THREAD (void)semGive(DB_GLOBAL(db_global_lock)) +#endif + +/* + * Single-threading defaults to a no-op. + */ +#ifndef DB_BEGIN_SINGLE_THREAD +#define DB_BEGIN_SINGLE_THREAD +#endif +#ifndef DB_END_SINGLE_THREAD +#define DB_END_SINGLE_THREAD +#endif + +#if defined(__cplusplus) +} +#endif + +#include "dbinc_auto/mutex_ext.h" +#endif /* !_DB_MUTEX_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/os.h b/src/libs/resiprocate/contrib/db/dbinc/os.h new file mode 100644 index 00000000..7a60ef05 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/os.h @@ -0,0 +1,176 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_OS_H_ +#define _DB_OS_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Number of times to retry system calls that return EINTR or EBUSY. */ +#define DB_RETRY 100 + +#ifdef __TANDEM +/* + * OSS Tandem problem: fsync can return a Guardian file system error of 70, + * which has no symbolic name in OSS. HP says to retry the fsync. [#12957] + */ +#define RETRY_CHK(op, ret) do { \ + int __retries, __t_ret; \ + for ((ret) = 0, __retries = DB_RETRY;;) { \ + if ((op) == 0) \ + break; \ + (ret) = __os_get_syserr(); \ + if (((__t_ret = __os_posix_err(ret)) == EAGAIN || \ + __t_ret == EBUSY || __t_ret == EINTR || \ + __t_ret == EIO || __t_ret == 70) && --__retries > 0)\ + continue; \ + break; \ + } \ +} while (0) +#else +#define RETRY_CHK(op, ret) do { \ + int __retries, __t_ret; \ + for ((ret) = 0, __retries = DB_RETRY;;) { \ + if ((op) == 0) \ + break; \ + (ret) = __os_get_syserr(); \ + if (((__t_ret = __os_posix_err(ret)) == EAGAIN || \ + __t_ret == EBUSY || __t_ret == EINTR || \ + __t_ret == EIO) && --__retries > 0) \ + continue; \ + break; \ + } \ +} while (0) +#endif + +#define RETRY_CHK_EINTR_ONLY(op, ret) do { \ + int __retries; \ + for ((ret) = 0, __retries = DB_RETRY;;) { \ + if ((op) == 0) \ + break; \ + (ret) = __os_get_syserr(); \ + if (__os_posix_err(ret) == EINTR && --__retries > 0) \ + continue; \ + break; \ + } \ +} while (0) + +/* + * Flags understood by __os_open. + */ +#define DB_OSO_ABSMODE 0x0001 /* Absolute mode specified. */ +#define DB_OSO_CREATE 0x0002 /* POSIX: O_CREAT */ +#define DB_OSO_DIRECT 0x0004 /* Don't buffer the file in the OS. */ +#define DB_OSO_DSYNC 0x0008 /* POSIX: O_DSYNC. */ +#define DB_OSO_EXCL 0x0010 /* POSIX: O_EXCL */ +#define DB_OSO_RDONLY 0x0020 /* POSIX: O_RDONLY */ +#define DB_OSO_REGION 0x0040 /* Opening a region file. */ +#define DB_OSO_SEQ 0x0080 /* Expected sequential access. */ +#define DB_OSO_TEMP 0x0100 /* Remove after last close. */ +#define DB_OSO_TRUNC 0x0200 /* POSIX: O_TRUNC */ + +/* + * File modes. + */ +#define DB_MODE_400 (S_IRUSR) +#define DB_MODE_600 (S_IRUSR|S_IWUSR) +#define DB_MODE_660 (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) +#define DB_MODE_666 (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#define DB_MODE_700 (S_IRUSR|S_IWUSR|S_IXUSR) + +/* + * We group certain seek/write calls into a single function so that we + * can use pread(2)/pwrite(2) where they're available. + */ +#define DB_IO_READ 1 +#define DB_IO_WRITE 2 + +/* + * Make a last "panic" check. Imagine a thread of control running in Berkeley + * DB, going to sleep. Another thread of control decides to run recovery + * because the environment is broken. The first thing recovery does is panic + * the existing environment, but we only check the panic flag when crossing the + * public API. If the sleeping thread wakes up and writes something, we could + * have two threads of control writing the log files at the same time. So, + * before reading or writing, make a last panic check. Obviously, there's still + * a window, but it's very, very small. + */ +#define LAST_PANIC_CHECK_BEFORE_IO(env) \ + PANIC_CHECK(env); + +/* DB filehandle. */ +struct __fh_t { + /* + * Linked list of DB_FH's, linked from the DB_ENV, used to keep track + * of all open file handles for resource cleanup. + */ + TAILQ_ENTRY(__fh_t) q; + + /* + * The file-handle mutex is only used to protect the handle/fd + * across seek and read/write pairs, it does not protect the + * the reference count, or any other fields in the structure. + */ + db_mutex_t mtx_fh; /* Mutex to lock. */ + + int ref; /* Reference count. */ + +#ifdef HAVE_BREW + IFile *ifp; /* IFile pointer */ +#endif +#if defined(DB_WIN32) + HANDLE handle; /* Windows/32 file handle. */ + HANDLE trunc_handle; /* Handle for truncate calls. */ +#endif + int fd; /* POSIX file descriptor. */ + + char *name; /* File name at open. */ + + /* + * Last seek statistics, used for zero-filling on filesystems + * that don't support it directly. + */ + db_pgno_t pgno; + u_int32_t pgsize; + u_int32_t offset; + +#ifdef HAVE_STATISTICS + u_int32_t seek_count; /* I/O statistics */ + u_int32_t read_count; + u_int32_t write_count; +#endif + +#define DB_FH_ENVLINK 0x01 /* We're linked on the DB_ENV. */ +#define DB_FH_NOSYNC 0x02 /* Handle doesn't need to be sync'd. */ +#define DB_FH_OPENED 0x04 /* Handle is valid. */ +#define DB_FH_UNLINK 0x08 /* Unlink on close */ +#define DB_FH_REGION 0x10 /* Opened to contain a region */ + u_int8_t flags; +}; + +/* Standard buffer size for ctime/ctime_r function calls. */ +#define CTIME_BUFLEN 26 + +/* + * VxWorks requires we cast (const char *) variables to (char *) in order to + * pass them to system calls like stat, read and write. + */ +#ifdef HAVE_VXWORKS +#define CHAR_STAR_CAST (char *) +#else +#define CHAR_STAR_CAST +#endif + +#if defined(__cplusplus) +} +#endif + +#include "dbinc_auto/os_ext.h" +#endif /* !_DB_OS_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/qam.h b/src/libs/resiprocate/contrib/db/dbinc/qam.h new file mode 100644 index 00000000..9c689716 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/qam.h @@ -0,0 +1,180 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1999-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_QAM_H_ +#define _DB_QAM_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * QAM data elements: a status field and the data. + */ +typedef struct _qamdata { + u_int8_t flags; /* 00: delete bit. */ +#define QAM_VALID 0x01 +#define QAM_SET 0x02 + u_int8_t data[1]; /* Record. */ +} QAMDATA; + +struct __queue; typedef struct __queue QUEUE; +struct __qcursor; typedef struct __qcursor QUEUE_CURSOR; + +struct __qcursor { + /* struct __dbc_internal */ + __DBC_INTERNAL + + /* Queue private part */ + + /* Per-thread information: queue private. */ + db_recno_t recno; /* Current record number. */ + + u_int32_t flags; +}; + +typedef struct __mpfarray { + u_int32_t n_extent; /* Number of extents in table. */ + u_int32_t low_extent; /* First extent open. */ + u_int32_t hi_extent; /* Last extent open. */ + struct __qmpf { + int pinref; + DB_MPOOLFILE *mpf; + } *mpfarray; /* Array of open extents. */ +} MPFARRAY; + +/* + * The in-memory, per-tree queue data structure. + */ +struct __queue { + db_pgno_t q_meta; /* Database meta-data page. */ + db_pgno_t q_root; /* Database root page. */ + + int re_pad; /* Fixed-length padding byte. */ + u_int32_t re_len; /* Length for fixed-length records. */ + u_int32_t rec_page; /* records per page */ + u_int32_t page_ext; /* Pages per extent */ + MPFARRAY array1, array2; /* File arrays. */ + + /* Extent file configuration: */ + DBT pgcookie; /* Initialized pgcookie. */ + DB_PGINFO pginfo; /* Initialized pginfo struct. */ + + char *path; /* Space allocated to file pathname. */ + char *name; /* The name of the file. */ + char *dir; /* The dir of the file. */ + int mode; /* Mode to open extents. */ +}; + +/* Format for queue extent names. */ +#define QUEUE_EXTENT "%s%c__dbq.%s.%d" +#define QUEUE_EXTENT_HEAD "__dbq.%s." +#define QUEUE_EXTENT_PREFIX "__dbq." + +typedef struct __qam_filelist { + DB_MPOOLFILE *mpf; + u_int32_t id; +} QUEUE_FILELIST; + +/* + * Calculate the page number of a recno. + * + * Number of records per page = + * Divide the available space on the page by the record len + header. + * + * Page number for record = + * divide the physical record number by the records per page + * add the root page number + * For now the root page will always be 1, but we might want to change + * in the future (e.g. multiple fixed len queues per file). + * + * Index of record on page = + * physical record number, less the logical pno times records/page + */ +#define CALC_QAM_RECNO_PER_PAGE(dbp) \ + (((dbp)->pgsize - QPAGE_SZ(dbp)) / \ + (u_int32_t)DB_ALIGN((uintmax_t)SSZA(QAMDATA, data) + \ + ((QUEUE *)(dbp)->q_internal)->re_len, sizeof(u_int32_t))) + +#define QAM_RECNO_PER_PAGE(dbp) (((QUEUE*)(dbp)->q_internal)->rec_page) + +#define QAM_RECNO_PAGE(dbp, recno) \ + (((QUEUE *)(dbp)->q_internal)->q_root \ + + (((recno) - 1) / QAM_RECNO_PER_PAGE(dbp))) + +#define QAM_PAGE_EXTENT(dbp, pgno) \ + (((pgno) - 1) / ((QUEUE *)(dbp)->q_internal)->page_ext) + +#define QAM_RECNO_EXTENT(dbp, recno) \ + QAM_PAGE_EXTENT(dbp, QAM_RECNO_PAGE(dbp, recno)) + +#define QAM_RECNO_INDEX(dbp, pgno, recno) \ + (((recno) - 1) - (QAM_RECNO_PER_PAGE(dbp) \ + * (pgno - ((QUEUE *)(dbp)->q_internal)->q_root))) + +#define QAM_GET_RECORD(dbp, page, index) \ + ((QAMDATA *)((u_int8_t *)(page) + (QPAGE_SZ(dbp) + \ + (DB_ALIGN((uintmax_t)SSZA(QAMDATA, data) + \ + ((QUEUE *)(dbp)->q_internal)->re_len, sizeof(u_int32_t)) * index)))) + +#define QAM_AFTER_CURRENT(meta, recno) \ + ((recno) >= (meta)->cur_recno && \ + ((meta)->first_recno <= (meta)->cur_recno || \ + ((recno) < (meta)->first_recno && \ + (recno) - (meta)->cur_recno < (meta)->first_recno - (recno)))) + +#define QAM_BEFORE_FIRST(meta, recno) \ + ((recno) < (meta)->first_recno && \ + ((meta)->first_recno <= (meta)->cur_recno || \ + ((recno) > (meta)->cur_recno && \ + (recno) - (meta)->cur_recno > (meta)->first_recno - (recno)))) + +#define QAM_NOT_VALID(meta, recno) \ + (recno == RECNO_OOB || \ + QAM_BEFORE_FIRST(meta, recno) || QAM_AFTER_CURRENT(meta, recno)) + +/* + * Log opcodes for the mvptr routine. + */ +#define QAM_SETFIRST 0x01 +#define QAM_SETCUR 0x02 +#define QAM_TRUNCATE 0x04 + +typedef enum { + QAM_PROBE_GET, + QAM_PROBE_PUT, + QAM_PROBE_DIRTY, + QAM_PROBE_MPF +} qam_probe_mode; + +/* + * Ops for __qam_nameop. + */ +typedef enum { + QAM_NAME_DISCARD, + QAM_NAME_RENAME, + QAM_NAME_REMOVE +} qam_name_op; + +#define __qam_fget(dbc, pgnoaddr, flags, addrp) \ + __qam_fprobe(dbc, *pgnoaddr, \ + addrp, QAM_PROBE_GET, DB_PRIORITY_UNCHANGED, flags) + +#define __qam_fput(dbc, pgno, addrp, priority) \ + __qam_fprobe(dbc, pgno, addrp, QAM_PROBE_PUT, priority, 0) + +#define __qam_dirty(dbc, pgno, pagep, priority) \ + __qam_fprobe(dbc, pgno, pagep, QAM_PROBE_DIRTY, priority, 0) + +#if defined(__cplusplus) +} +#endif + +#include "dbinc_auto/qam_auto.h" +#include "dbinc_auto/qam_ext.h" +#endif /* !_DB_QAM_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/queue.h b/src/libs/resiprocate/contrib/db/dbinc/queue.h new file mode 100644 index 00000000..d76f2019 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/queue.h @@ -0,0 +1,563 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + * $FreeBSD: src/sys/sys/queue.h,v 1.54 2002/08/05 05:18:43 alfred Exp $ + */ + +#ifndef _DB_QUEUE_H_ +#define _DB_QUEUE_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * This file defines four types of data structures: singly-linked lists, + * singly-linked tail queues, lists and tail queues. + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A singly-linked tail queue is headed by a pair of pointers, one to the + * head of the list and the other to the tail of the list. The elements are + * singly linked for minimum space and pointer manipulation overhead at the + * expense of O(n) removal for arbitrary elements. New elements can be added + * to the list after an existing element, at the head of the list, or at the + * end of the list. Elements being removed from the head of the tail queue + * should use the explicit macro for this purpose for optimum efficiency. + * A singly-linked tail queue may only be traversed in the forward direction. + * Singly-linked tail queues are ideal for applications with large datasets + * and few or no removals or for implementing a FIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * For details on the use of these macros, see the queue(3) manual page. + * + * + * SLIST LIST STAILQ TAILQ + * _HEAD + + + + + * _HEAD_INITIALIZER + + + + + * _ENTRY + + + + + * _INIT + + + + + * _EMPTY + + + + + * _FIRST + + + + + * _NEXT + + + + + * _PREV - - - + + * _LAST - - + + + * _FOREACH + + + + + * _FOREACH_REVERSE - - - + + * _INSERT_HEAD + + + + + * _INSERT_BEFORE - + - + + * _INSERT_AFTER + + + + + * _INSERT_TAIL - - + + + * _CONCAT - - + + + * _REMOVE_HEAD + - + - + * _REMOVE + + + + + * + */ + +/* + * XXX + * We #undef all of the macros because there are incompatible versions of this + * file and these macros on various systems. What makes the problem worse is + * they are included and/or defined by system include files which we may have + * already loaded into Berkeley DB before getting here. For example, FreeBSD's + * includes its system , and VxWorks UnixLib.h defines + * several of the LIST_XXX macros. Visual C.NET 7.0 also defines some of these + * same macros in Vc7\PlatformSDK\Include\WinNT.h. Make sure we use ours. + */ +#undef LIST_EMPTY +#undef LIST_ENTRY +#undef LIST_FIRST +#undef LIST_FOREACH +#undef LIST_HEAD +#undef LIST_HEAD_INITIALIZER +#undef LIST_INIT +#undef LIST_INSERT_AFTER +#undef LIST_INSERT_BEFORE +#undef LIST_INSERT_HEAD +#undef LIST_NEXT +#undef LIST_REMOVE +#undef QMD_TRACE_ELEM +#undef QMD_TRACE_HEAD +#undef QUEUE_MACRO_DEBUG +#undef SLIST_EMPTY +#undef SLIST_ENTRY +#undef SLIST_FIRST +#undef SLIST_FOREACH +#undef SLIST_FOREACH_PREVPTR +#undef SLIST_HEAD +#undef SLIST_HEAD_INITIALIZER +#undef SLIST_INIT +#undef SLIST_INSERT_AFTER +#undef SLIST_INSERT_HEAD +#undef SLIST_NEXT +#undef SLIST_REMOVE +#undef SLIST_REMOVE_HEAD +#undef STAILQ_CONCAT +#undef STAILQ_EMPTY +#undef STAILQ_ENTRY +#undef STAILQ_FIRST +#undef STAILQ_FOREACH +#undef STAILQ_HEAD +#undef STAILQ_HEAD_INITIALIZER +#undef STAILQ_INIT +#undef STAILQ_INSERT_AFTER +#undef STAILQ_INSERT_HEAD +#undef STAILQ_INSERT_TAIL +#undef STAILQ_LAST +#undef STAILQ_NEXT +#undef STAILQ_REMOVE +#undef STAILQ_REMOVE_HEAD +#undef STAILQ_REMOVE_HEAD_UNTIL +#undef TAILQ_CONCAT +#undef TAILQ_EMPTY +#undef TAILQ_ENTRY +#undef TAILQ_FIRST +#undef TAILQ_FOREACH +#undef TAILQ_FOREACH_REVERSE +#undef TAILQ_HEAD +#undef TAILQ_HEAD_INITIALIZER +#undef TAILQ_INIT +#undef TAILQ_INSERT_AFTER +#undef TAILQ_INSERT_BEFORE +#undef TAILQ_INSERT_HEAD +#undef TAILQ_INSERT_TAIL +#undef TAILQ_LAST +#undef TAILQ_NEXT +#undef TAILQ_PREV +#undef TAILQ_REMOVE +#undef TRACEBUF +#undef TRASHIT + +#define QUEUE_MACRO_DEBUG 0 +#if QUEUE_MACRO_DEBUG +/* Store the last 2 places the queue element or head was altered */ +struct qm_trace { + char * lastfile; + int lastline; + char * prevfile; + int prevline; +}; + +#define TRACEBUF struct qm_trace trace; +#define TRASHIT(x) do {(x) = (void *)-1;} while (0) + +#define QMD_TRACE_HEAD(head) do { \ + (head)->trace.prevline = (head)->trace.lastline; \ + (head)->trace.prevfile = (head)->trace.lastfile; \ + (head)->trace.lastline = __LINE__; \ + (head)->trace.lastfile = __FILE__; \ +} while (0) + +#define QMD_TRACE_ELEM(elem) do { \ + (elem)->trace.prevline = (elem)->trace.lastline; \ + (elem)->trace.prevfile = (elem)->trace.lastfile; \ + (elem)->trace.lastline = __LINE__; \ + (elem)->trace.lastfile = __FILE__; \ +} while (0) + +#else +#define QMD_TRACE_ELEM(elem) +#define QMD_TRACE_HEAD(head) +#define TRACEBUF +#define TRASHIT(x) +#endif /* QUEUE_MACRO_DEBUG */ + +/* + * Singly-linked List declarations. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) + +#define SLIST_FIRST(head) ((head)->slh_first) + +#define SLIST_FOREACH(var, head, field) \ + for ((var) = SLIST_FIRST((head)); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ + for ((varp) = &SLIST_FIRST((head)); \ + ((var) = *(varp)) != NULL; \ + (varp) = &SLIST_NEXT((var), field)) + +#define SLIST_INIT(head) do { \ + SLIST_FIRST((head)) = NULL; \ +} while (0) + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ + SLIST_NEXT((slistelm), field) = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ + SLIST_FIRST((head)) = (elm); \ +} while (0) + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if (SLIST_FIRST((head)) == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = SLIST_FIRST((head)); \ + while (SLIST_NEXT(curelm, field) != (elm)) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_NEXT(curelm, field) = \ + SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ + } \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ +} while (0) + +/* + * Singly-linked Tail queue declarations. + */ +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first;/* first element */ \ + struct type **stqh_last;/* addr of last next element */ \ +} + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ +} while (0) + +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) + +#define STAILQ_FIRST(head) ((head)->stqh_first) + +#define STAILQ_FOREACH(var, head, field) \ + for ((var) = STAILQ_FIRST((head)); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) + +#define STAILQ_INIT(head) do { \ + STAILQ_FIRST((head)) = NULL; \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_NEXT((tqelm), field) = (elm); \ +} while (0) + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_FIRST((head)) = (elm); \ +} while (0) + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + STAILQ_NEXT((elm), field) = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) + +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head)) ? \ + NULL : \ + ((struct type *) \ + ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) + +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if (STAILQ_FIRST((head)) == (elm)) { \ + STAILQ_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = STAILQ_FIRST((head)); \ + while (STAILQ_NEXT(curelm, field) != (elm)) \ + curelm = STAILQ_NEXT(curelm, field); \ + if ((STAILQ_NEXT(curelm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ + } \ +} while (0) + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if ((STAILQ_FIRST((head)) = \ + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ + if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +/* + * List declarations. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for ((var) = LIST_FIRST((head)); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_INIT(head) do { \ + LIST_FIRST((head)) = NULL; \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ + LIST_NEXT((listelm), field)->field.le_prev = \ + &LIST_NEXT((elm), field); \ + LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + LIST_NEXT((elm), field) = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ + LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &LIST_FIRST((head)); \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL) \ + LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ +} while (0) + +/* + * Tail queue declarations. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ + TRACEBUF \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ + TRACEBUF \ +} + +/* + * Tail queue functions. + */ +#define TAILQ_CONCAT(head1, head2, field) do { \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT((head2)); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_HEAD(head2); \ + } \ +} while (0) + +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_FOREACH(var, head, field) \ + for ((var) = TAILQ_FIRST((head)); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_INIT(head) do { \ + TAILQ_FIRST((head)) = NULL; \ + (head)->tqh_last = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else { \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + } \ + TAILQ_NEXT((listelm), field) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + TAILQ_NEXT((elm), field) = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ + TAILQ_FIRST((head))->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + TAILQ_FIRST((head)) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + TAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field)) != NULL) \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else { \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + QMD_TRACE_HEAD(head); \ + } \ + *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ + TRASHIT((elm)->field.tqe_next); \ + TRASHIT((elm)->field.tqe_prev); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_QUEUE_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/region.h b/src/libs/resiprocate/contrib/db/dbinc/region.h new file mode 100644 index 00000000..62cc79e5 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/region.h @@ -0,0 +1,285 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1998-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_REGION_H_ +#define _DB_REGION_H_ + +/* + * The DB environment consists of some number of "regions", which are described + * by the following four structures: + * + * REGENV -- shared information about the environment + * REGENV_REF -- file describing system memory version of REGENV + * REGION -- shared information about a single region + * REGINFO -- per-process information about a REGION + * + * There are three types of memory that hold regions: + * per-process heap (malloc) + * file mapped into memory (mmap, MapViewOfFile) + * system memory (shmget, CreateFileMapping) + * + * By default, regions are created in filesystem-backed shared memory. They + * can also be created in system shared memory (DB_SYSTEM_MEM), or, if private + * to a process, in heap memory (DB_PRIVATE). + * + * Regions in the filesystem are named "__db.001", "__db.002" and so on. If + * we're not using a private environment allocated in heap, "__db.001" will + * always exist, as we use it to synchronize on the regions, whether they are + * in filesystem-backed memory or system memory. + * + * The file "__db.001" contains a REGENV structure and an array of REGION + * structures. Each REGION structures describes an underlying chunk of + * shared memory. + * + * __db.001 + * +---------+ + * |REGENV | + * +---------+ +----------+ + * |REGION |-> | __db.002 | + * | | +----------+ + * +---------+ +----------+ + * |REGION |-> | __db.003 | + * | | +----------+ + * +---------+ +----------+ + * |REGION |-> | __db.004 | + * | | +----------+ + * +---------+ + * + * The tricky part about manipulating the regions is creating or joining the + * database environment. We have to be sure only a single thread of control + * creates and/or recovers a database environment. All other threads should + * then join without seeing inconsistent data. + * + * We do this in two parts: first, we use the underlying O_EXCL flag to the + * open system call to serialize creation of the __db.001 file. The thread + * of control creating that file then proceeds to create the remaining + * regions in the environment, including the mutex region. Once the mutex + * region has been created, the creating thread of control fills in the + * __db.001 file's magic number. Other threads of control (the ones that + * didn't create the __db.001 file), wait on the initialization of the + * __db.001 file's magic number. After it has been initialized, all threads + * of control can proceed, using normal shared mutex locking procedures for + * exclusion. + * + * REGIONs are not moved or removed during the life of the environment, and + * so processes can have long-lived references to them. + * + * One of the REGION structures describes the environment region itself. + * + * The REGION array is not locked in any way. It's an array so we don't have + * to manipulate data structures after a crash -- on some systems, we have to + * join and clean up the mutex region after application failure. Using an + * array means we don't have to worry about broken links or other nastiness + * after the failure. + * + * All requests to create or join a region return a REGINFO structure, which + * is held by the caller and used to open and subsequently close the reference + * to the region. The REGINFO structure contains the per-process information + * that we need to access the region. + * + * The one remaining complication. If the regions (including the environment + * region) live in system memory, and the system memory isn't "named" somehow + * in the filesystem name space, we need some way of finding it. Do this by + * by writing the REGENV_REF structure into the "__db.001" file. When we find + * a __db.001 file that is too small to be a real, on-disk environment, we use + * the information it contains to redirect to the real "__db.001" file/memory. + * This currently only happens when the REGENV file is in shared system memory. + * + * Although DB does not currently grow regions when they run out of memory, it + * would be possible to do so. To grow a region, allocate a new region of the + * appropriate size, then copy the old region over it and insert the additional + * memory into the already existing shalloc arena. Region users must reset + * their base addresses and any local pointers into the memory, of course. + * This failed in historic versions of DB because the region mutexes lived in + * the mapped memory, and when it was unmapped and remapped (or copied), + * threads could lose track of it. Also, some systems didn't support mutex + * copying, e.g., from OSF1 V4.0: + * + * The address of an msemaphore structure may be significant. If the + * msemaphore structure contains any value copied from an msemaphore + * structure at a different address, the result is undefined. + * + * All mutexes are now maintained in a separate region which is never unmapped, + * so growing regions should be possible. + */ + +#if defined(__cplusplus) +extern "C" { +#endif + +#define DB_REGION_PREFIX "__db" /* DB file name prefix. */ +#define DB_REGION_FMT "__db.%03d" /* Region file name format. */ +#define DB_REGION_ENV "__db.001" /* Primary environment name. */ + +#define INVALID_REGION_ID 0 /* Out-of-band region ID. */ +#define REGION_ID_ENV 1 /* Primary environment ID. */ + +typedef enum { + INVALID_REGION_TYPE=0, /* Region type. */ + REGION_TYPE_ENV, + REGION_TYPE_LOCK, + REGION_TYPE_LOG, + REGION_TYPE_MPOOL, + REGION_TYPE_MUTEX, + REGION_TYPE_TXN } reg_type_t; + +#define INVALID_REGION_SEGID -1 /* Segment IDs are either shmget(2) or + * Win16 segment identifiers. They are + * both stored in a "long", and we need + * an out-of-band value. + */ +/* + * Nothing can live at region offset 0, because, in all cases, that's where + * we store *something*. Lots of code needs an out-of-band value for region + * offsets, so we use 0. + */ +#define INVALID_ROFF 0 + +/* Reference describing system memory version of REGENV. */ +typedef struct __db_reg_env_ref { + roff_t size; /* Region size. */ + long segid; /* UNIX shmget ID, VxWorks ID. */ +} REGENV_REF; + +/* Per-environment region information. */ +typedef struct __db_reg_env { + /* + * !!! + * The magic, panic, version, envid and signature fields of the region + * are fixed in size, the timestamp field is the first field which is + * variable length. These fields must never change in order, to + * guarantee we can always read them, no matter what release we have. + * + * !!! + * The magic and panic fields are NOT protected by any mutex, and for + * this reason cannot be anything more complicated than zero/non-zero. + */ + u_int32_t magic; /* Valid region magic number. */ + u_int32_t panic; /* Environment is dead. */ + + u_int32_t majver; /* Major DB version number. */ + u_int32_t minver; /* Minor DB version number. */ + u_int32_t patchver; /* Patch DB version number. */ + + u_int32_t envid; /* Unique environment ID. */ + + u_int32_t signature; /* Structure signatures. */ + + time_t timestamp; /* Creation time. */ + + u_int32_t init_flags; /* Flags environment initialized with.*/ + + /* + * The mtx_regenv mutex protects the environment reference count and + * memory allocation from the primary shared region (the crypto, thread + * control block and replication implementations allocate memory from + * the primary shared region). + * + * The rest of the fields are initialized at creation time, and don't + * need mutex protection. The flags, op_timestamp and rep_timestamp + * fields are used by replication only and are protected by the + * replication mutex. The rep_timestamp is is not protected when it + * is used in recovery as that is already single threaded. + */ + db_mutex_t mtx_regenv; /* Refcnt, region allocation mutex. */ + u_int32_t refcnt; /* References to the environment. */ + + u_int32_t region_cnt; /* Number of REGIONs. */ + roff_t region_off; /* Offset of region array */ + + roff_t cipher_off; /* Offset of cipher area */ + + roff_t thread_off; /* Offset of the thread area. */ + + roff_t rep_off; /* Offset of the replication area. */ +#define DB_REGENV_REPLOCKED 0x0001 /* Env locked for rep backup. */ + u_int32_t flags; /* Shared environment flags. */ +#define DB_REGENV_TIMEOUT 30 /* Backup timeout. */ + time_t op_timestamp; /* Timestamp for operations. */ + time_t rep_timestamp; /* Timestamp for rep db handles. */ + u_int32_t reg_panic; /* DB_REGISTER triggered panic */ + uintmax_t unused; /* The ALLOC_LAYOUT structure follows + * the REGENV structure in memory and + * contains uintmax_t fields. Force + * proper alignment of that structure. + */ +} REGENV; + +/* Per-region shared region information. */ +typedef struct __db_region { + u_int32_t id; /* Region id. */ + reg_type_t type; /* Region type. */ + + roff_t size; /* Region size in bytes. */ + + roff_t primary; /* Primary data structure offset. */ + + long segid; /* UNIX shmget(2), Win16 segment ID. */ +} REGION; + +/* + * Per-process/per-attachment information about a single region. + */ +struct __db_reginfo_t { /* __env_region_attach IN parameters. */ + ENV *env; /* Enclosing environment. */ + reg_type_t type; /* Region type. */ + u_int32_t id; /* Region id. */ + + /* env_region_attach OUT parameters. */ + REGION *rp; /* Shared region. */ + + char *name; /* Region file name. */ + + void *addr; /* Region address. */ + void *primary; /* Primary data structure address. */ + + size_t max_alloc; /* Maximum bytes allocated. */ + size_t allocated; /* Bytes allocated. */ + + db_mutex_t mtx_alloc; /* number of mutex for allocation. */ + +#ifdef DB_WIN32 + HANDLE wnt_handle; /* Win/NT HANDLE. */ +#endif + +#define REGION_CREATE 0x01 /* Caller created region. */ +#define REGION_CREATE_OK 0x02 /* Caller willing to create region. */ +#define REGION_JOIN_OK 0x04 /* Caller is looking for a match. */ + u_int32_t flags; +}; + +/* + * R_ADDR Return a per-process address for a shared region offset. + * R_OFFSET Return a shared region offset for a per-process address. + */ +#define R_ADDR(reginfop, offset) \ + (F_ISSET((reginfop)->env, ENV_PRIVATE) ? \ + (void *)(offset) : \ + (void *)((u_int8_t *)((reginfop)->addr) + (offset))) +#define R_OFFSET(reginfop, p) \ + (F_ISSET((reginfop)->env, ENV_PRIVATE) ? \ + (roff_t)(p) : \ + (roff_t)((u_int8_t *)(p) - (u_int8_t *)(reginfop)->addr)) + +/* + * PANIC_ISSET, PANIC_CHECK: + * Check to see if the DB environment is dead. + */ +#define PANIC_ISSET(env) \ + ((env) != NULL && (env)->reginfo != NULL && \ + ((REGENV *)(env)->reginfo->primary)->panic != 0 && \ + !F_ISSET((env)->dbenv, DB_ENV_NOPANIC)) + +#define PANIC_CHECK(env) \ + if (PANIC_ISSET(env)) \ + return (__env_panic_msg(env)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_REGION_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/rep.h b/src/libs/resiprocate/contrib/db/dbinc/rep.h new file mode 100644 index 00000000..c11213c8 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/rep.h @@ -0,0 +1,831 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2001-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_REP_H_ +#define _DB_REP_H_ + +#include "dbinc_auto/rep_auto.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Names of client temp databases. + */ +#define REPDBNAME "__db.rep.db" +#define REPPAGENAME "__db.reppg.db" + +/* + * Message types + */ +#define REP_INVALID 0 /* Invalid message type. */ +#define REP_ALIVE 1 /* I am alive message. */ +#define REP_ALIVE_REQ 2 /* Request for alive messages. */ +#define REP_ALL_REQ 3 /* Request all log records greater than LSN. */ +#define REP_BULK_LOG 4 /* Bulk transfer of log records. */ +#define REP_BULK_PAGE 5 /* Bulk transfer of pages. */ +#define REP_DUPMASTER 6 /* Duplicate master detected; propagate. */ +#define REP_FILE 7 /* Page of a database file. NOTUSED */ +#define REP_FILE_FAIL 8 /* File requested does not exist. */ +#define REP_FILE_REQ 9 /* Request for a database file. NOTUSED */ +#define REP_LEASE_GRANT 10 /* Client grants a lease to a master. */ +#define REP_LOG 11 /* Log record. */ +#define REP_LOG_MORE 12 /* There are more log records to request. */ +#define REP_LOG_REQ 13 /* Request for a log record. */ +#define REP_MASTER_REQ 14 /* Who is the master */ +#define REP_NEWCLIENT 15 /* Announces the presence of a new client. */ +#define REP_NEWFILE 16 /* Announce a log file change. */ +#define REP_NEWMASTER 17 /* Announces who the master is. */ +#define REP_NEWSITE 18 /* Announces that a site has heard from a new + * site; like NEWCLIENT, but indirect. A + * NEWCLIENT message comes directly from the new + * client while a NEWSITE comes indirectly from + * someone who heard about a NEWSITE. + */ +#define REP_PAGE 19 /* Database page. */ +#define REP_PAGE_FAIL 20 /* Requested page does not exist. */ +#define REP_PAGE_MORE 21 /* There are more pages to request. */ +#define REP_PAGE_REQ 22 /* Request for a database page. */ +#define REP_REREQUEST 23 /* Force rerequest. */ +#define REP_START_SYNC 24 /* Tell client to begin syncing a ckp.*/ +#define REP_UPDATE 25 /* Environment hotcopy information. */ +#define REP_UPDATE_REQ 26 /* Request for hotcopy information. */ +#define REP_VERIFY 27 /* A log record for verification. */ +#define REP_VERIFY_FAIL 28 /* The client is outdated. */ +#define REP_VERIFY_REQ 29 /* Request for a log record to verify. */ +#define REP_VOTE1 30 /* Send out your information for an election. */ +#define REP_VOTE2 31 /* Send a "you are master" vote. */ +/* + * Maximum message number for conversion tables. Update this + * value as the largest message number above increases. + * + * !!! + * NOTE: When changing messages above, the two tables for upgrade support + * need adjusting. They are in rep_util.c. + */ +#define REP_MAX_MSG 31 + +/* + * This is the list of client-to-client requests messages. + * We use this to decide if we're doing client-to-client and + * might need to send a rerequest. + */ +#define REP_MSG_REQ(rectype) \ + (rectype == REP_ALL_REQ || \ + rectype == REP_LOG_REQ || \ + rectype == REP_PAGE_REQ || \ + rectype == REP_VERIFY_REQ) + +/* + * Note that the version information should be at the beginning of the + * structure, so that we can rearrange the rest of it while letting the + * version checks continue to work. DB_REPVERSION should be revved any time + * the rest of the structure changes or when the message numbers change. + * + * Define also, the corresponding log versions that are tied to the + * replication/release versions. These are only used in replication + * and that is why they're defined here. + */ +#define DB_LOGVERSION_42 8 +#define DB_LOGVERSION_43 10 +#define DB_LOGVERSION_44 11 +#define DB_LOGVERSION_45 12 +#define DB_LOGVERSION_46 13 +#define DB_LOGVERSION_47 14 +#define DB_LOGVERSION_48 15 +#define DB_LOGVERSION_MIN DB_LOGVERSION_44 +#define DB_REPVERSION_INVALID 0 +#define DB_REPVERSION_44 3 +#define DB_REPVERSION_45 3 +#define DB_REPVERSION_46 4 +#define DB_REPVERSION_47 5 +#define DB_REPVERSION_48 5 +#define DB_REPVERSION DB_REPVERSION_48 +#define DB_REPVERSION_MIN DB_REPVERSION_44 + +/* + * RPRINT + * REP_PRINT_MESSAGE + * Macros for verbose replication messages. + */ +#define RPRINT(env, verbose_category, x) do { \ + if (FLD_ISSET((env)->dbenv->verbose, \ + (verbose_category) | DB_VERB_REPLICATION)) { \ + __rep_print x; \ + } \ +} while (0) +#define REP_PRINT_MESSAGE(env, eid, rp, str, fl) do { \ + if (FLD_ISSET((env)->dbenv->verbose, \ + DB_VERB_REP_MSGS | DB_VERB_REPLICATION)) { \ + __rep_print_message(env, eid, rp, str, fl); \ + } \ +} while (0) + +/* + * Election gen file name + * The file contains an egen number for an election this client has NOT + * participated in. I.e. it is the number of a future election. We + * create it when we create the rep region, if it doesn't already exist + * and initialize egen to 1. If it does exist, we read it when we create + * the rep region. We write it immediately before sending our VOTE1 in + * an election. That way, if a client has ever sent a vote for any + * election, the file is already going to be updated to reflect a future + * election, should it crash. + */ +#define REP_EGENNAME "__db.rep.egen" +#define REP_GENNAME "__db.rep.gen" + +/* + * Internal init flag file name: + * The existence of this file serves as an indication that the client is in the + * process of Internal Initialization, in case it crashes before completing. + * During internal init the client's partially reconstructed database pages and + * logs may be in an inconsistent state, so much so that running recovery must + * be avoided. Furthermore, there is no other way to reliably recognize this + * condition. Therefore, when we open an environment, and we're just about to + * run recovery, we check for this file first. If it exists we must discard all + * logs and databases. This avoids the recovery problems, and leads to a fresh + * attempt at internal init if the environment becomes a replication client and + * finds a master. The list of databases which may need to be removed is stored + * in this file. + */ +#define REP_INITNAME "__db.rep.init" +#define REP_INITVERSION_46 1 +#define REP_INITVERSION_47 2 +#define REP_INITVERSION 2 + +#define REP_META_RETRY 3 /* Retry limit to get meta lock. */ + +/* + * Database types for __rep_client_dbinit + */ +typedef enum { + REP_DB, /* Log record database. */ + REP_PG /* Pg database. */ +} repdb_t; + +/* Macros to lock/unlock the replication region as a whole. */ +#define REP_SYSTEM_LOCK(env) \ + MUTEX_LOCK(env, (env)->rep_handle->region->mtx_region) +#define REP_SYSTEM_UNLOCK(env) \ + MUTEX_UNLOCK(env, (env)->rep_handle->region->mtx_region) + +/* + * Macros for manipulating the event synchronization. We use a separate mutex + * so that an application's call-back function can be invoked without locking + * the whole region. + */ +#define REP_EVENT_LOCK(env) \ + MUTEX_LOCK(env, (env)->rep_handle->region->mtx_event) +#define REP_EVENT_UNLOCK(env) \ + MUTEX_UNLOCK(env, (env)->rep_handle->region->mtx_event) + +/* + * REP -- + * Shared replication structure. + */ +typedef struct __rep { + db_mutex_t mtx_region; /* Region mutex. */ + db_mutex_t mtx_clientdb; /* Client database mutex. */ + db_mutex_t mtx_ckp; /* Checkpoint mutex. */ + roff_t lease_off; /* Offset of the lease table. */ + roff_t tally_off; /* Offset of the tally region. */ + roff_t v2tally_off; /* Offset of the vote2 tally region. */ + int eid; /* Environment id. */ + int master_id; /* ID of the master site. */ + u_int32_t version; /* Current replication version. */ + u_int32_t egen; /* Replication election generation. */ + u_int32_t gen; /* Replication generation number. */ + u_int32_t asites; /* Space allocated for sites. */ + u_int32_t nsites; /* Number of sites in group. */ + u_int32_t nvotes; /* Number of votes needed. */ + u_int32_t priority; /* My priority in an election. */ + u_int32_t config_nsites; + + db_timeout_t elect_timeout; /* Normal/full election timeouts. */ + db_timeout_t full_elect_timeout; + + db_timeout_t chkpt_delay; /* Master checkpoint delay. */ + +#define REP_DEFAULT_THROTTLE (10 * MEGABYTE) /* Default value is < 1Gig. */ + u_int32_t gbytes; /* Limit on data sent in single... */ + u_int32_t bytes; /* __rep_process_message call. */ +#define DB_REP_REQUEST_GAP 40000 /* 40 msecs */ +#define DB_REP_MAX_GAP 1280000 /* 1.28 seconds */ + db_timespec request_gap; /* Minimum time to wait before we + * request a missing log record. */ + db_timespec max_gap; /* Maximum time to wait before + * requesting a missing log record. */ + /* Status change information */ + u_int32_t apply_th; /* Number of callers in rep_apply. */ + u_int32_t msg_th; /* Number of callers in rep_proc_msg.*/ + u_int32_t handle_cnt; /* Count of handles in library. */ + u_int32_t op_cnt; /* Multi-step operation count.*/ + DB_LSN ckp_lsn; /* LSN for syncing a checkpoint. */ + DB_LSN max_prep_lsn; /* Max LSN of txn_prepare record. */ + + /* + * Event notification synchronization: the mtx_event and associate + * fields which it protects govern event notification to the + * application. They form a guarantee that no matter how crazy the + * thread scheduling gets, the application sees a sensible, orderly + * progression of events. + */ + db_mutex_t mtx_event; /* Serializes event notification. */ + /* + * Latest generation whose NEWMASTER event the application has been + * notified of. Also serves to force STARTUPDONE to occur after + * NEWMASTER. + */ + u_int32_t newmaster_event_gen; + /* + * Latest local victory of an election that the application has been + * notified of, expressed as the election generation number. This + * ensures we notify the application exactly once when it wins an + * election. + */ + u_int32_t notified_egen; + + /* Internal init information. */ + u_int32_t nfiles; /* Number of files we have info on. */ + u_int32_t curfile; /* Cur file we're getting (0-based). */ + __rep_fileinfo_args *curinfo; /* Current file info ptr. */ + u_int8_t *nextinfo; /* Next file info buffer. */ + u_int8_t *originfo; /* Original file info buffer. */ + u_int32_t infolen; /* Remaining length file info buffer. */ + u_int32_t originfolen; /* Original length file info buffer. */ + u_int32_t infoversion; /* Original file info version. */ + DB_LSN first_lsn; /* Earliest LSN we need. */ + u_int32_t first_vers; /* Log version of first log file. */ + DB_LSN last_lsn; /* Latest LSN we need. */ + /* These are protected by mtx_clientdb. */ + db_pgno_t ready_pg; /* Next pg expected. */ + db_pgno_t waiting_pg; /* First pg after gap. */ + db_pgno_t max_wait_pg; /* Maximum pg requested. */ + u_int32_t npages; /* Num of pages rcvd for this file. */ + DB_MPOOLFILE *file_mpf; /* Mpoolfile for current database. */ + DB *file_dbp; /* This file's page info. */ + DBC *queue_dbc; /* Dbc for a queue file. */ + + /* Vote tallying information. */ + u_int32_t sites; /* Sites heard from. */ + int winner; /* Current winner EID. */ + u_int32_t w_priority; /* Winner priority. */ + u_int32_t w_gen; /* Winner generation. */ + DB_LSN w_lsn; /* Winner LSN. */ + u_int32_t w_tiebreaker; /* Winner tiebreaking value. */ + u_int32_t votes; /* Number of votes for this site. */ + + db_timespec etime; /* Election start timestamp. */ + + /* Leases. */ + db_timeout_t lease_timeout; /* Lease timeout. */ + db_timespec lease_duration; /* Lease timeout with clock skew. */ + u_int32_t clock_skew; /* Clock skew. */ + u_int32_t clock_base; /* Clock scale factor base. */ + db_timespec grant_expire; /* Local grant expiration time. */ + +#ifdef HAVE_REPLICATION_THREADS + /* + * Replication Framework (repmgr) shared config information. + */ + db_mutex_t mtx_repmgr; /* Region mutex. */ + SITEADDR my_addr; /* SITEADDR of local site. */ + + int peer; /* Site to use for C2C sync. */ + roff_t netaddr_off; /* Offset of site addresses region. */ + u_int site_cnt; /* Array slots in use. */ + u_int site_max; /* Total array slots allocated. */ + u_int siteaddr_seq; /* Number of updates to this info. */ + + pid_t listener; + +#endif /* HAVE_REPLICATION_THREADS */ + + /* Statistics. */ + DB_REP_STAT stat; +#if defined(HAVE_REPLICATION_THREADS) && defined(HAVE_STATISTICS) + DB_REPMGR_STAT mstat; +#endif + + /* Configuration. */ +#define REP_C_2SITE_STRICT 0x00001 /* Don't cheat on elections. */ +#define REP_C_BULK 0x00002 /* Bulk transfer. */ +#define REP_C_DELAYCLIENT 0x00004 /* Delay client sync-up. */ +#define REP_C_INMEM 0x00008 /* In-memory replication. */ +#define REP_C_LEASE 0x00010 /* Leases configured. */ +#define REP_C_NOAUTOINIT 0x00020 /* No auto initialization. */ +#define REP_C_NOWAIT 0x00040 /* Immediate error return. */ + u_int32_t config; /* Configuration flags. */ + + /* + * Please change __rep_print_all (rep_stat.c) to track any changes made + * to these flags. + */ +#define REP_F_ABBREVIATED 0x00000001 /* Recover NIMDB pages only. */ +#define REP_F_APP_BASEAPI 0x00000002 /* Base API application. */ +#define REP_F_APP_REPMGR 0x00000004 /* repmgr application. */ +#define REP_F_CLIENT 0x00000008 /* Client replica. */ +#define REP_F_DELAY 0x00000010 /* Delaying client sync-up. */ +#define REP_F_EGENUPDATE 0x00000020 /* Egen updated by ALIVE msg. */ +#define REP_F_EPHASE0 0x00000040 /* In phase 0 of election. */ +#define REP_F_EPHASE1 0x00000080 /* In phase 1 of election. */ +#define REP_F_EPHASE2 0x00000100 /* In phase 2 of election. */ +#define REP_F_GROUP_ESTD 0x00000200 /* Rep group is established. */ +#define REP_F_INREPELECT 0x00000400 /* Thread in rep_elect. */ +#define REP_F_INREPSTART 0x00000800 /* Thread in rep_start. */ +#define REP_F_LEASE_EXPIRED 0x00001000 /* Leases guaranteed expired. */ +#define REP_F_MASTER 0x00002000 /* Master replica. */ +#define REP_F_MASTERELECT 0x00004000 /* Master elect. */ +#define REP_F_NEWFILE 0x00008000 /* Newfile in progress. */ +#define REP_F_NIMDBS_LOADED 0x00010000 /* NIMDBs are materialized. */ +#define REP_F_NOARCHIVE 0x00020000 /* Rep blocks log_archive. */ +#define REP_F_READY_API 0x00040000 /* Need handle_cnt to be 0. */ +#define REP_F_READY_APPLY 0x00080000 /* Need apply_th to be 0. */ +#define REP_F_READY_MSG 0x00100000 /* Need msg_th to be 0. */ +#define REP_F_READY_OP 0x00200000 /* Need op_cnt to be 0. */ +#define REP_F_RECOVER_LOG 0x00400000 /* In recovery - log. */ +#define REP_F_RECOVER_PAGE 0x00800000 /* In recovery - pages. */ +#define REP_F_RECOVER_UPDATE 0x01000000 /* In recovery - files. */ +#define REP_F_RECOVER_VERIFY 0x02000000 /* In recovery - verify. */ +#define REP_F_SKIPPED_APPLY 0x04000000 /* Skipped applying a record. */ +#define REP_F_START_CALLED 0x08000000 /* Rep_start called. */ +#define REP_F_TALLY 0x10000000 /* Tallied vote before elect. */ + u_int32_t flags; +} REP; + +/* + * Recovery flag mask to easily check any/all recovery bits. That is + * REP_F_READY_{API|OP} and all REP_F_RECOVER*. This must change if the values + * of the flags change. NOTE: We do not include REP_F_READY_MSG in + * this mask because it is used frequently in non-recovery related + * areas and we want to manipulate it separately (see especially + * in __rep_new_master). + */ +#define REP_F_RECOVER_MASK \ + (REP_F_READY_API | REP_F_READY_OP | \ + REP_F_RECOVER_LOG | REP_F_RECOVER_PAGE | \ + REP_F_RECOVER_UPDATE | REP_F_RECOVER_VERIFY) + +/* + * These flag bits are "permanent": for each of these bits, once it has been set + * it shouldnever be cleared. When adding a new flag bit, if it should be + * sticky please add it here too. + */ +#define REP_F_STICKY_MASK \ + (REP_F_APP_BASEAPI | REP_F_APP_REPMGR | REP_F_GROUP_ESTD | \ + REP_F_NIMDBS_LOADED | REP_F_START_CALLED) + +/* + * REP_F_EPHASE0 is not a *real* election phase. It is used for + * master leases and allowing the client to find the master or + * expire its lease. However, EPHASE0 is cleared by __rep_elect_done. + */ +#define IN_ELECTION(R) \ + F_ISSET((R), REP_F_EPHASE1 | REP_F_EPHASE2) +#define IN_ELECTION_TALLY(R) \ + F_ISSET((R), REP_F_EPHASE1 | REP_F_EPHASE2 | REP_F_TALLY) +#define ELECTION_MAJORITY(n) (((n) / 2) + 1) + +#define IN_INTERNAL_INIT(R) \ + F_ISSET((R), REP_F_RECOVER_LOG | REP_F_RECOVER_PAGE) + +#define IS_REP_MASTER(env) \ + (REP_ON(env) && \ + F_ISSET(((env)->rep_handle->region), REP_F_MASTER)) + +#define IS_REP_CLIENT(env) \ + (REP_ON(env) && \ + F_ISSET(((env)->rep_handle->region), REP_F_CLIENT)) + +#define IS_REP_STARTED(env) \ + (REP_ON(env) && \ + F_ISSET(((env)->rep_handle->region), REP_F_START_CALLED)) + +#define IS_USING_LEASES(env) \ + (REP_ON(env) && \ + FLD_ISSET(((env)->rep_handle->region)->config, REP_C_LEASE)) + +#define IS_CLIENT_PGRECOVER(env) \ + (IS_REP_CLIENT(env) && \ + F_ISSET(((env)->rep_handle->region), REP_F_RECOVER_PAGE)) + +/* + * Macros to figure out if we need to do replication pre/post-amble processing. + * Skip for specific DB handles owned by the replication layer, either because + * replication is running recovery or because it's a handle entirely owned by + * the replication code (replication opens its own databases to track state). + */ +#define IS_ENV_REPLICATED(env) \ + (REP_ON(env) && (env)->rep_handle->region->flags != 0) + +/* + * Gap processing flags. These provide control over the basic + * gap processing algorithm for some special cases. + */ +#define REP_GAP_FORCE 0x001 /* Force a request for a gap. */ +#define REP_GAP_REREQUEST 0x002 /* Gap request is a forced rerequest. */ + /* REREQUEST is a superset of FORCE. */ + +/* + * Basic pre/post-amble processing. + */ +#define REPLICATION_WRAP(env, func_call, checklock, ret) do { \ + int __rep_check, __t_ret; \ + __rep_check = IS_ENV_REPLICATED(env) ? 1 : 0; \ + (ret) = __rep_check ? __env_rep_enter(env, checklock) : 0; \ + if ((ret) == 0) { \ + (ret) = func_call; \ + if (__rep_check && (__t_ret = \ + __env_db_rep_exit(env)) != 0 && (ret) == 0) \ + (ret) = __t_ret; \ + } \ +} while (0) + +/* + * Per-process replication structure. + * + * There are 2 mutexes used in the Base replication API. (See LOCK_MUTEX in + * repmgr.h for a discussion of repmgr.) + * 1. mtx_region - This protects the fields of the rep region above. + * 2. mtx_clientdb - This protects the per-process flags, and bookkeeping + * database and all of the components that maintain it. Those + * components include the following fields in the log region (see log.h): + * a. ready_lsn + * b. waiting_lsn + * c. verify_lsn + * d. wait_recs + * e. rcvd_recs + * f. max_wait_lsn + * These fields in the log region are NOT protected by the log region lock at + * all. + * + * Note that the per-process flags should truly be protected by a special + * per-process thread mutex, but it is currently set in so isolated a manner + * that it didn't make sense to do so and in most case we're already holding + * the mtx_clientdb anyway. + * + * The lock ordering protocol is that mtx_clientdb must be acquired first and + * then either REP->mtx_region, or the LOG->mtx_region mutex may be acquired if + * necessary. + * + * Note that the appropriate mutex is needed any time one or more related + * values are read or written that could possibly use more than one atomic + * machine instruction. A single 32-bit integer value is safe without a + * mutex, but most other types of value should use a mutex. + * + * Any use of a mutex must be inside a matched pair of ENV_ENTER() and + * ENV_LEAVE() macros. This ensures that if a thread dies while holding + * a lock (i.e. a mutex), recovery can clean it up so that it does not + * indefinitely block other threads. + */ +struct __db_rep { + /* + * Shared configuration information -- copied to and maintained in the + * shared region as soon as the shared region is created. + */ + int eid; /* Environment ID. */ + + u_int32_t gbytes; /* Limit on data sent in single... */ + u_int32_t bytes; /* __rep_process_message call. */ + + db_timespec request_gap; /* Minimum time to wait before we + * request a missing log record. */ + db_timespec max_gap; /* Maximum time to wait before + * requesting a missing log record. */ + + u_int32_t clock_skew; /* Clock skew factor. */ + u_int32_t clock_base; /* Clock skew base. */ + u_int32_t config; /* Configuration flags. */ + u_int32_t config_nsites; + + db_timeout_t elect_timeout; /* Normal/full election timeouts. */ + db_timeout_t full_elect_timeout; + + db_timeout_t chkpt_delay; /* Master checkpoint delay. */ + + u_int32_t my_priority; + db_timeout_t lease_timeout; /* Master leases. */ + /* + * End of shared configuration information. + */ + int (*send) /* Send function. */ + __P((DB_ENV *, const DBT *, const DBT *, + const DB_LSN *, int, u_int32_t)); + + DB *rep_db; /* Bookkeeping database. */ + + REP *region; /* In memory structure. */ + u_int8_t *bulk; /* Shared memory bulk area. */ + + /* + * Please change __rep_print_all (rep_stat.c) to track any changes made + * to these flags. + */ +#define DBREP_APP_BASEAPI 0x0001 /* Base API application. */ +#define DBREP_APP_REPMGR 0x0002 /* repmgr application. */ +#define DBREP_OPENFILES 0x0004 /* This handle has opened files. */ + u_int32_t flags; /* per-process flags. */ + +#ifdef HAVE_REPLICATION_THREADS + /* + * Replication Framework (repmgr) per-process information. + */ + int nthreads; + u_int32_t init_policy; + int perm_policy; + int peer; /* Site to use for C2C sync. */ + db_timeout_t ack_timeout; + db_timeout_t election_retry_wait; + db_timeout_t connection_retry_wait; + db_timeout_t heartbeat_frequency; /* Max period between msgs. */ + db_timeout_t heartbeat_monitor_timeout; + + /* Repmgr's copies of rep stuff. */ + int master_eid; + + /* Thread synchronization. */ + REPMGR_RUNNABLE *selector, **messengers, *elect_thread; + mgr_mutex_t *mutex; + cond_var_t queue_nonempty, check_election; +#ifdef DB_WIN32 + ACK_WAITERS_TABLE *waiters; + HANDLE signaler; +#else + pthread_cond_t ack_condition; + int read_pipe, write_pipe; +#endif + + /* Operational stuff. */ + REPMGR_SITE *sites; /* Array of known sites. */ + u_int site_cnt; /* Array slots in use. */ + u_int site_max; /* Total array slots allocated. */ + u_int siteaddr_seq; /* Last known update to this list. */ + + /* + * The connections list contains only those connections not actively + * associated with a known site (see repmgr.h). + */ + CONNECTION_LIST connections; + RETRY_Q_HEADER retries; /* Sites needing connection retry. */ + struct { + int size; + STAILQ_HEAD(__repmgr_q_header, __repmgr_message) header; + } input_queue; + + socket_t listen_fd; + repmgr_netaddr_t my_addr; + db_timespec last_bcast; /* Time of last broadcast msg. */ + + int finished; /* Repmgr threads should shut down. */ + int done_one; /* TODO: rename */ + int found_master; + int takeover_pending; /* We've been elected master. */ + +/* Operations we can ask election thread to perform (OOB value is 0): */ +#define ELECT_ELECTION 1 /* Call for an election. */ +#define ELECT_FAILURE_ELECTION 2 /* Do election, adjusting nsites to account + for a failed master. */ +#define ELECT_REPSTART 3 /* Call rep_start(CLIENT). */ + int operation_needed; /* Next op for election thread. */ + +#endif /* HAVE_REPLICATION_THREADS */ +}; + +/* + * Determine whether application is repmgr or base replication API. If + * repmgr was configured, base the test on internal replication flags for + * APP_REPMGR and APP_BASEAPI. These flags get set by the appropriate parts + * of the various replication APIs. + */ +#ifdef HAVE_REPLICATION_THREADS +/* + * Application type is set to be repmgr when: + * 1. A local site is defined. + * 2. A remote site is defined. + * 3. An acknowledgement policy is configured. + * 4. 2SITE_STRICT is configured. + * 5. A timeout value is configured for one of the repmgr timeouts. + */ +#define APP_IS_REPMGR(env) \ + (REP_ON(env) ? \ + F_ISSET((env)->rep_handle->region, REP_F_APP_REPMGR) : \ + F_ISSET((env)->rep_handle, DBREP_APP_REPMGR)) + +/* + * Application type is set to be base replication API when: + * 1. Transport send function is defined and is not the repmgr send + * function. + */ +#define APP_IS_BASEAPI(env) \ + (REP_ON(env) ? \ + F_ISSET((env)->rep_handle->region, REP_F_APP_BASEAPI) : \ + F_ISSET((env)->rep_handle, DBREP_APP_BASEAPI)) + +/* + * Set application type. These macros do extra checking to guarantee that + * only one application type is ever set. + */ +#define APP_SET_REPMGR(env) do { \ + if (REP_ON(env)) { \ + if (!F_ISSET((env)->rep_handle->region, \ + REP_F_APP_BASEAPI)) \ + F_SET((env)->rep_handle->region, \ + REP_F_APP_REPMGR); \ + } else if (!F_ISSET((env)->rep_handle, DBREP_APP_BASEAPI)) \ + F_SET((env)->rep_handle, DBREP_APP_REPMGR); \ +} while (0) +#define APP_SET_BASEAPI(env) do { \ + if (REP_ON(env)) { \ + if (!F_ISSET((env)->rep_handle->region, \ + REP_F_APP_REPMGR)) \ + F_SET((env)->rep_handle->region, \ + REP_F_APP_BASEAPI); \ + } else if (!F_ISSET((env)->rep_handle, DBREP_APP_REPMGR)) \ + F_SET((env)->rep_handle, DBREP_APP_BASEAPI); \ +} while (0) + +#else +/* + * We did not configure repmgr, application must be base replication API. + * The APP_SET_* macros are noops in this case, but they must be defined + * with a null body to avoid compiler warnings on some platforms. + */ +#define APP_IS_REPMGR(env) 0 +#define APP_SET_REPMGR(env) do { \ + ; \ +} while (0) +#define APP_IS_BASEAPI(env) 1 +#define APP_SET_BASEAPI(env) do { \ + ; \ +} while (0) +#endif /* HAVE_REPLICATION_THREADS */ + +/* + * Control structure flags for replication communication infrastructure. + */ +/* + * Define old DB_LOG_ values that we must support here. For reasons of + * compatibility with old versions, these values must be reserved explicitly in + * the list of flag values (below) + */ +#define DB_LOG_PERM_42_44 0x20 +#define DB_LOG_RESEND_42_44 0x40 +#define REPCTL_INIT_45 0x02 /* Back compatible flag value. */ + +#define REPCTL_ELECTABLE 0x01 /* Upgraded client is electable. */ +#define REPCTL_FLUSH 0x02 /* Record should be flushed. */ +#define REPCTL_GROUP_ESTD 0x04 /* Message from site in a group. */ +#define REPCTL_INIT 0x08 /* Internal init message. */ +#define REPCTL_LEASE 0x10 /* Lease related message.. */ + /* + * Skip over reserved values 0x20 + * and 0x40, as explained above. + */ +#define REPCTL_LOG_END 0x80 /* Approximate end of group-wide log. */ +#define REPCTL_PERM DB_LOG_PERM_42_44 +#define REPCTL_RESEND DB_LOG_RESEND_42_44 + +/* + * File info flags for internal init. The per-database (i.e., file) flag + * represents the on-disk format of the file, and is conveyed from the master to + * the initializing client in the UPDATE message, so that the client can know + * how to create the file. The per-page flag is conveyed along with each PAGE + * message, describing the format of the page image being transmitted; it is of + * course set by the site serving the PAGE_REQ. The serving site gets the page + * image from its own mpool, and thus the page is in the native format of the + * serving site. This format may be different (i.e., opposite) from the on-disk + * format, and in fact can vary per-page, since with client-to-client sync it is + * possible for various different sites to serve the various PAGE_REQ requests. + */ +#define REPINFO_DB_LITTLEENDIAN 0x0001 /* File is little-endian lorder. */ +#define REPINFO_PG_LITTLEENDIAN 0x0002 /* Page is little-endian lorder. */ + +/* + * Control message format for 4.6 release. The db_timespec_t is + * not a portable structure. Therefore, in 4.6, replication among + * mixed OSs such as Linux and Windows, which have different time_t + * sizes, does not work. + */ +typedef struct { + u_int32_t rep_version; /* Replication version number. */ + u_int32_t log_version; /* Log version number. */ + + DB_LSN lsn; /* Log sequence number. */ + u_int32_t rectype; /* Message type. */ + u_int32_t gen; /* Generation number. */ + db_timespec msg_time; /* Timestamp seconds for leases. */ + u_int32_t flags; /* log_put flag value. */ +} REP_46_CONTROL; + +/* + * Control message format for 4.5 release and earlier. + */ +typedef struct { + u_int32_t rep_version; /* Replication version number. */ + u_int32_t log_version; /* Log version number. */ + + DB_LSN lsn; /* Log sequence number. */ + u_int32_t rectype; /* Message type. */ + u_int32_t gen; /* Generation number. */ + u_int32_t flags; /* log_put flag value. */ +} REP_OLD_CONTROL; + +#define LEASE_REFRESH_TRIES 3 /* Number of times to try refresh. */ + +/* Master granted lease information. */ +typedef struct __rep_lease_entry { + int eid; /* EID of client grantor. */ + db_timespec start_time; /* Start time clients echo back. */ + db_timespec end_time; /* Master lease expiration time. */ + DB_LSN lease_lsn; /* Durable LSN lease applies to. */ +} REP_LEASE_ENTRY; + +/* + * Old vote info where some fields were not fixed size. + */ +typedef struct { + u_int32_t egen; /* Election generation. */ + int nsites; /* Number of sites I've been in + * communication with. */ + int nvotes; /* Number of votes needed to win. */ + int priority; /* My site's priority. */ + u_int32_t tiebreaker; /* Tie-breaking quasi-random value. */ +} REP_OLD_VOTE_INFO; + +typedef struct { + u_int32_t egen; /* Voter's election generation. */ + int eid; /* Voter's ID. */ +} REP_VTALLY; + +/* + * The REP_THROTTLE_ONLY flag is used to do throttle processing only. + * If set, it will only allow sending the REP_*_MORE message, but not + * the normal, non-throttled message. It is used to support throttling + * with bulk transfer. + */ +/* Flags for __rep_send_throttle. */ +#define REP_THROTTLE_ONLY 0x0001 /* Send _MORE message only. */ + +/* Throttled message processing information. */ +typedef struct { + DB_LSN lsn; /* LSN of this record. */ + DBT *data_dbt; /* DBT of this record. */ + u_int32_t gbytes; /* This call's max gbytes sent. */ + u_int32_t bytes; /* This call's max bytes sent. */ + u_int32_t type; /* Record type. */ +} REP_THROTTLE; + +/* Bulk processing information. */ +/* + * !!! + * We use a uintptr_t for the offset. We'd really like to use a ptrdiff_t + * since that really is what it is. But ptrdiff_t is not portable and + * doesn't exist everywhere. + */ +typedef struct { + u_int8_t *addr; /* Address of bulk buffer. */ + uintptr_t *offp; /* Ptr to current offset into buffer. */ + u_int32_t len; /* Bulk buffer length. */ + u_int32_t type; /* Item type in buffer (log, page). */ + DB_LSN lsn; /* First LSN in buffer. */ + int eid; /* ID of potential recipients. */ +#define BULK_XMIT 0x001 /* Buffer in transit. */ + u_int32_t *flagsp; /* Buffer flags. */ +} REP_BULK; + +/* + * This structure takes care of representing a transaction. + * It holds all the records, sorted by page number so that + * we can obtain locks and apply updates in a deadlock free + * order. + */ +typedef struct { + u_int nlsns; + u_int nalloc; + DB_LSN *array; +} LSN_COLLECTION; + +/* + * This is used by the page-prep routines to do the lock_vec call to + * apply the updates for a single transaction or a collection of + * transactions. + */ +typedef struct { + int n; + DB_LOCKREQ *reqs; + DBT *objs; +} linfo_t; + +#if defined(__cplusplus) +} +#endif + +#include "dbinc_auto/rep_ext.h" +#endif /* !_DB_REP_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/shqueue.h b/src/libs/resiprocate/contrib/db/dbinc/shqueue.h new file mode 100644 index 00000000..9b125498 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/shqueue.h @@ -0,0 +1,406 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_SHQUEUE_H_ +#define _DB_SHQUEUE_H_ + +/* + * This file defines three types of data structures: chains, lists and + * tail queues similarly to the include file . + * + * The difference is that this set of macros can be used for structures that + * reside in shared memory that may be mapped at different addresses in each + * process. In most cases, the macros for shared structures exactly mirror + * the normal macros, although the macro calls require an additional type + * parameter, only used by the HEAD and ENTRY macros of the standard macros. + * + * Since we use relative offsets of type ssize_t rather than pointers, 0 + * (aka NULL) is a valid offset and cannot be used to indicate the end + * of a list. Therefore, we use -1 to indicate end of list. + * + * The macros ending in "P" return pointers without checking for end or + * beginning of lists, the others check for end of list and evaluate to + * either a pointer or NULL. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +#if defined(__cplusplus) +extern "C" { +#endif + +#define SH_PTR_TO_OFF(src, dest) \ + ((ssize_t)(((u_int8_t *)(dest)) - ((u_int8_t *)(src)))) + +/* + * Shared memory chain definitions. + */ +#define SH_CHAIN_ENTRY \ +struct { \ + ssize_t sce_next; /* relative offset to next element */ \ + ssize_t sce_prev; /* relative offset of prev element */ \ +} + +#define SH_CHAIN_INIT(elm, field) \ + (elm)->field.sce_next = (elm)->field.sce_prev = -1 + +#define SH_CHAIN_HASNEXT(elm, field) ((elm)->field.sce_next != -1) +#define SH_CHAIN_NEXTP(elm, field, type) \ + ((struct type *)((u_int8_t *)(elm) + (elm)->field.sce_next)) +#define SH_CHAIN_NEXT(elm, field, type) (SH_CHAIN_HASNEXT(elm, field) ? \ + SH_CHAIN_NEXTP(elm, field, type) : (struct type *)NULL) + +#define SH_CHAIN_HASPREV(elm, field) ((elm)->field.sce_prev != -1) +#define SH_CHAIN_PREVP(elm, field, type) \ + ((struct type *)((u_int8_t *)(elm) + (elm)->field.sce_prev)) +#define SH_CHAIN_PREV(elm, field, type) (SH_CHAIN_HASPREV(elm, field) ? \ + SH_CHAIN_PREVP(elm, field, type) : (struct type *)NULL) + +#define SH_CHAIN_SINGLETON(elm, field) \ + (!(SH_CHAIN_HASNEXT(elm, field) || SH_CHAIN_HASPREV(elm, field))) + +#define SH_CHAIN_INSERT_AFTER(listelm, elm, field, type) do { \ + struct type *__next = SH_CHAIN_NEXT(listelm, field, type); \ + if (__next != NULL) { \ + (elm)->field.sce_next = SH_PTR_TO_OFF(elm, __next); \ + __next->field.sce_prev = SH_PTR_TO_OFF(__next, elm); \ + } else \ + (elm)->field.sce_next = -1; \ + (elm)->field.sce_prev = SH_PTR_TO_OFF(elm, listelm); \ + (listelm)->field.sce_next = SH_PTR_TO_OFF(listelm, elm); \ +} while (0) + +#define SH_CHAIN_INSERT_BEFORE(listelm, elm, field, type) do { \ + struct type *__prev = SH_CHAIN_PREV(listelm, field, type); \ + if (__prev != NULL) { \ + (elm)->field.sce_prev = SH_PTR_TO_OFF(elm, __prev); \ + __prev->field.sce_next = SH_PTR_TO_OFF(__prev, elm); \ + } else \ + (elm)->field.sce_prev = -1; \ + (elm)->field.sce_next = SH_PTR_TO_OFF(elm, listelm); \ + (listelm)->field.sce_prev = SH_PTR_TO_OFF(listelm, elm); \ +} while (0) + +#define SH_CHAIN_REMOVE(elm, field, type) do { \ + struct type *__prev = SH_CHAIN_PREV(elm, field, type); \ + struct type *__next = SH_CHAIN_NEXT(elm, field, type); \ + if (__next != NULL) \ + __next->field.sce_prev = (__prev == NULL) ? -1 : \ + SH_PTR_TO_OFF(__next, __prev); \ + if (__prev != NULL) \ + __prev->field.sce_next = (__next == NULL) ? -1 : \ + SH_PTR_TO_OFF(__prev, __next); \ + SH_CHAIN_INIT(elm, field); \ +} while (0) + +/* + * Shared memory list definitions. + */ +#define SH_LIST_HEAD(name) \ +struct name { \ + ssize_t slh_first; /* first element */ \ +} + +#define SH_LIST_HEAD_INITIALIZER(head) \ + { -1 } + +#define SH_LIST_ENTRY \ +struct { \ + ssize_t sle_next; /* relative offset to next element */ \ + ssize_t sle_prev; /* relative offset of prev element */ \ +} + +/* + * Shared memory list functions. + */ +#define SH_LIST_EMPTY(head) \ + ((head)->slh_first == -1) + +#define SH_LIST_FIRSTP(head, type) \ + ((struct type *)(((u_int8_t *)(head)) + (head)->slh_first)) + +#define SH_LIST_FIRST(head, type) \ + (SH_LIST_EMPTY(head) ? NULL : \ + ((struct type *)(((u_int8_t *)(head)) + (head)->slh_first))) + +#define SH_LIST_NEXTP(elm, field, type) \ + ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.sle_next)) + +#define SH_LIST_NEXT(elm, field, type) \ + ((elm)->field.sle_next == -1 ? NULL : \ + ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.sle_next))) + + /* + *__SH_LIST_PREV_OFF is private API. It calculates the address of + * the elm->field.sle_next member of a SH_LIST structure. All offsets + * between elements are relative to that point in SH_LIST structures. + */ +#define __SH_LIST_PREV_OFF(elm, field) \ + ((ssize_t *)(((u_int8_t *)(elm)) + (elm)->field.sle_prev)) + +#define SH_LIST_PREV(elm, field, type) \ + (struct type *)((ssize_t)(elm) - (*__SH_LIST_PREV_OFF(elm, field))) + +#define SH_LIST_FOREACH(var, head, field, type) \ + for ((var) = SH_LIST_FIRST((head), type); \ + (var) != NULL; \ + (var) = SH_LIST_NEXT((var), field, type)) + +/* + * Given correct A.next: B.prev = SH_LIST_NEXT_TO_PREV(A) + * in a list [A, B] + * The prev value is always the offset from an element to its preceding + * element's next location, not the beginning of the structure. To get + * to the beginning of an element structure in memory given an element + * do the following: + * A = B - (B.prev + (&B.next - B)) + * Take the element's next pointer and calculate what the corresponding + * Prev pointer should be -- basically it is the negation plus the offset + * of the next field in the structure. + */ +#define SH_LIST_NEXT_TO_PREV(elm, field) \ + (((elm)->field.sle_next == -1 ? 0 : -(elm)->field.sle_next) + \ + SH_PTR_TO_OFF(elm, &(elm)->field.sle_next)) + +#define SH_LIST_INIT(head) (head)->slh_first = -1 + +#define SH_LIST_INSERT_BEFORE(head, listelm, elm, field, type) do { \ + if (listelm == SH_LIST_FIRST(head, type)) { \ + SH_LIST_INSERT_HEAD(head, elm, field, type); \ + } else { \ + (elm)->field.sle_next = SH_PTR_TO_OFF(elm, listelm); \ + (elm)->field.sle_prev = SH_LIST_NEXT_TO_PREV( \ + SH_LIST_PREV((listelm), field, type), field) + \ + (elm)->field.sle_next; \ + (SH_LIST_PREV(listelm, field, type))->field.sle_next = \ + (SH_PTR_TO_OFF((SH_LIST_PREV(listelm, field, \ + type)), elm)); \ + (listelm)->field.sle_prev = SH_LIST_NEXT_TO_PREV(elm, field); \ + } \ +} while (0) + +#define SH_LIST_INSERT_AFTER(listelm, elm, field, type) do { \ + if ((listelm)->field.sle_next != -1) { \ + (elm)->field.sle_next = SH_PTR_TO_OFF(elm, \ + SH_LIST_NEXTP(listelm, field, type)); \ + SH_LIST_NEXTP(listelm, field, type)->field.sle_prev = \ + SH_LIST_NEXT_TO_PREV(elm, field); \ + } else \ + (elm)->field.sle_next = -1; \ + (listelm)->field.sle_next = SH_PTR_TO_OFF(listelm, elm); \ + (elm)->field.sle_prev = SH_LIST_NEXT_TO_PREV(listelm, field); \ +} while (0) + +#define SH_LIST_INSERT_HEAD(head, elm, field, type) do { \ + if ((head)->slh_first != -1) { \ + (elm)->field.sle_next = \ + (head)->slh_first - SH_PTR_TO_OFF(head, elm); \ + SH_LIST_FIRSTP(head, type)->field.sle_prev = \ + SH_LIST_NEXT_TO_PREV(elm, field); \ + } else \ + (elm)->field.sle_next = -1; \ + (head)->slh_first = SH_PTR_TO_OFF(head, elm); \ + (elm)->field.sle_prev = SH_PTR_TO_OFF(elm, &(head)->slh_first); \ +} while (0) + +#define SH_LIST_REMOVE(elm, field, type) do { \ + if ((elm)->field.sle_next != -1) { \ + SH_LIST_NEXTP(elm, field, type)->field.sle_prev = \ + (elm)->field.sle_prev - (elm)->field.sle_next; \ + *__SH_LIST_PREV_OFF(elm, field) += (elm)->field.sle_next;\ + } else \ + *__SH_LIST_PREV_OFF(elm, field) = -1; \ +} while (0) + +#define SH_LIST_REMOVE_HEAD(head, field, type) do { \ + if (!SH_LIST_EMPTY(head)) { \ + SH_LIST_REMOVE(SH_LIST_FIRSTP(head, type), field, type);\ + } \ +} while (0) + +/* + * Shared memory tail queue definitions. + */ +#define SH_TAILQ_HEAD(name) \ +struct name { \ + ssize_t stqh_first; /* relative offset of first element */ \ + ssize_t stqh_last; /* relative offset of last's next */ \ +} + +#define SH_TAILQ_HEAD_INITIALIZER(head) \ + { -1, 0 } + +#define SH_TAILQ_ENTRY \ +struct { \ + ssize_t stqe_next; /* relative offset of next element */ \ + ssize_t stqe_prev; /* relative offset of prev's next */ \ +} + +/* + * Shared memory tail queue functions. + */ + +#define SH_TAILQ_EMPTY(head) \ + ((head)->stqh_first == -1) + +#define SH_TAILQ_FIRSTP(head, type) \ + ((struct type *)((u_int8_t *)(head) + (head)->stqh_first)) + +#define SH_TAILQ_FIRST(head, type) \ + (SH_TAILQ_EMPTY(head) ? NULL : SH_TAILQ_FIRSTP(head, type)) + +#define SH_TAILQ_NEXTP(elm, field, type) \ + ((struct type *)((u_int8_t *)(elm) + (elm)->field.stqe_next)) + +#define SH_TAILQ_NEXT(elm, field, type) \ + ((elm)->field.stqe_next == -1 ? NULL : \ + ((struct type *)((u_int8_t *)(elm) + (elm)->field.stqe_next))) + + /* + * __SH_TAILQ_PREV_OFF is private API. It calculates the address of + * the elm->field.stqe_next member of a SH_TAILQ structure. All + * offsets between elements are relative to that point in SH_TAILQ + * structures. + */ +#define __SH_TAILQ_PREV_OFF(elm, field) \ + ((ssize_t *)(((u_int8_t *)(elm)) + (elm)->field.stqe_prev)) + +#define SH_TAILQ_PREVP(elm, field, type) \ + (struct type *)((ssize_t)elm - (*__SH_TAILQ_PREV_OFF(elm, field))) + +#define SH_TAILQ_PREV(head, elm, field, type) \ + (((elm) == SH_TAILQ_FIRST(head, type)) ? NULL : \ + (struct type *)((ssize_t)elm - (*__SH_TAILQ_PREV_OFF(elm, field)))) + + /* + * __SH_TAILQ_LAST_OFF is private API. It calculates the address of + * the stqe_next member of a SH_TAILQ structure in the last element + * of this list. All offsets between elements are relative to that + * point in SH_TAILQ structures. + */ +#define __SH_TAILQ_LAST_OFF(head) \ + ((ssize_t *)(((u_int8_t *)(head)) + (head)->stqh_last)) + +#define SH_TAILQ_LASTP(head, field, type) \ + ((struct type *)((ssize_t)(head) + \ + ((ssize_t)((head)->stqh_last) - \ + ((ssize_t)SH_PTR_TO_OFF(SH_TAILQ_FIRST(head, type), \ + &(SH_TAILQ_FIRSTP(head, type)->field.stqe_next)))))) + +#define SH_TAILQ_LAST(head, field, type) \ + (SH_TAILQ_EMPTY(head) ? NULL : SH_TAILQ_LASTP(head, field, type)) + +/* + * Given correct A.next: B.prev = SH_TAILQ_NEXT_TO_PREV(A) + * in a list [A, B] + * The prev value is always the offset from an element to its preceding + * element's next location, not the beginning of the structure. To get + * to the beginning of an element structure in memory given an element + * do the following: + * A = B - (B.prev + (&B.next - B)) + */ +#define SH_TAILQ_NEXT_TO_PREV(elm, field) \ + (((elm)->field.stqe_next == -1 ? 0 : \ + (-(elm)->field.stqe_next) + \ + SH_PTR_TO_OFF(elm, &(elm)->field.stqe_next))) + +#define SH_TAILQ_FOREACH(var, head, field, type) \ + for ((var) = SH_TAILQ_FIRST((head), type); \ + (var) != NULL; \ + (var) = SH_TAILQ_NEXT((var), field, type)) + +#define SH_TAILQ_FOREACH_REVERSE(var, head, field, type) \ + for ((var) = SH_TAILQ_LAST((head), field, type); \ + (var) != NULL; \ + (var) = SH_TAILQ_PREV((head), (var), field, type)) + +#define SH_TAILQ_INIT(head) { \ + (head)->stqh_first = -1; \ + (head)->stqh_last = SH_PTR_TO_OFF(head, &(head)->stqh_first); \ +} + +#define SH_TAILQ_INSERT_HEAD(head, elm, field, type) do { \ + if ((head)->stqh_first != -1) { \ + (elm)->field.stqe_next = \ + (head)->stqh_first - SH_PTR_TO_OFF(head, elm); \ + SH_TAILQ_FIRSTP(head, type)->field.stqe_prev = \ + SH_TAILQ_NEXT_TO_PREV(elm, field); \ + } else { \ + (head)->stqh_last = \ + SH_PTR_TO_OFF(head, &(elm)->field.stqe_next); \ + (elm)->field.stqe_next = -1; \ + } \ + (head)->stqh_first = SH_PTR_TO_OFF(head, elm); \ + (elm)->field.stqe_prev = \ + SH_PTR_TO_OFF(elm, &(head)->stqh_first); \ +} while (0) + +#define SH_TAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.stqe_next = -1; \ + (elm)->field.stqe_prev = \ + -SH_PTR_TO_OFF(head, elm) + (head)->stqh_last; \ + if ((head)->stqh_last == \ + SH_PTR_TO_OFF((head), &(head)->stqh_first)) \ + (head)->stqh_first = SH_PTR_TO_OFF(head, elm); \ + else \ + *__SH_TAILQ_LAST_OFF(head) = -(head)->stqh_last + \ + SH_PTR_TO_OFF((elm), &(elm)->field.stqe_next) + \ + SH_PTR_TO_OFF(head, elm); \ + (head)->stqh_last = \ + SH_PTR_TO_OFF(head, &((elm)->field.stqe_next)); \ +} while (0) + +#define SH_TAILQ_INSERT_BEFORE(head, listelm, elm, field, type) do { \ + if (listelm == SH_TAILQ_FIRST(head, type)) { \ + SH_TAILQ_INSERT_HEAD(head, elm, field, type); \ + } else { \ + (elm)->field.stqe_next = SH_PTR_TO_OFF(elm, listelm); \ + (elm)->field.stqe_prev = SH_TAILQ_NEXT_TO_PREV( \ + SH_TAILQ_PREVP((listelm), field, type), field) + \ + (elm)->field.stqe_next; \ + (SH_TAILQ_PREVP(listelm, field, type))->field.stqe_next =\ + (SH_PTR_TO_OFF((SH_TAILQ_PREVP(listelm, field, type)), \ + elm)); \ + (listelm)->field.stqe_prev = \ + SH_TAILQ_NEXT_TO_PREV(elm, field); \ + } \ +} while (0) + +#define SH_TAILQ_INSERT_AFTER(head, listelm, elm, field, type) do { \ + if ((listelm)->field.stqe_next != -1) { \ + (elm)->field.stqe_next = (listelm)->field.stqe_next - \ + SH_PTR_TO_OFF(listelm, elm); \ + SH_TAILQ_NEXTP(listelm, field, type)->field.stqe_prev = \ + SH_TAILQ_NEXT_TO_PREV(elm, field); \ + } else { \ + (elm)->field.stqe_next = -1; \ + (head)->stqh_last = \ + SH_PTR_TO_OFF(head, &(elm)->field.stqe_next); \ + } \ + (listelm)->field.stqe_next = SH_PTR_TO_OFF(listelm, elm); \ + (elm)->field.stqe_prev = SH_TAILQ_NEXT_TO_PREV(listelm, field); \ +} while (0) + +#define SH_TAILQ_REMOVE(head, elm, field, type) do { \ + if ((elm)->field.stqe_next != -1) { \ + SH_TAILQ_NEXTP(elm, field, type)->field.stqe_prev = \ + (elm)->field.stqe_prev + \ + SH_PTR_TO_OFF(SH_TAILQ_NEXTP(elm, \ + field, type), elm); \ + *__SH_TAILQ_PREV_OFF(elm, field) += (elm)->field.stqe_next;\ + } else { \ + (head)->stqh_last = (elm)->field.stqe_prev + \ + SH_PTR_TO_OFF(head, elm); \ + *__SH_TAILQ_PREV_OFF(elm, field) = -1; \ + } \ +} while (0) + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_SHQUEUE_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/tcl_db.h b/src/libs/resiprocate/contrib/db/dbinc/tcl_db.h new file mode 100644 index 00000000..7a7a734f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/tcl_db.h @@ -0,0 +1,278 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1999-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_TCL_DB_H_ +#define _DB_TCL_DB_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +#define MSG_SIZE 100 /* Message size */ + +enum INFOTYPE { + I_DB, I_DBC, I_ENV, I_LOCK, I_LOGC, I_MP, I_NDBM, I_PG, I_SEQ, I_TXN}; + +#define MAX_ID 8 /* Maximum number of sub-id's we need */ +#define DBTCL_PREP 64 /* Size of txn_recover preplist */ + +#define DBTCL_DBM 1 +#define DBTCL_NDBM 2 + +#define DBTCL_GETCLOCK 0 +#define DBTCL_GETLIMIT 1 +#define DBTCL_GETREQ 2 + +#define DBTCL_MUT_ALIGN 0 +#define DBTCL_MUT_INCR 1 +#define DBTCL_MUT_MAX 2 +#define DBTCL_MUT_TAS 3 + +/* + * Why use a home grown package over the Tcl_Hash functions? + * + * We could have implemented the stuff below without maintaining our + * own list manipulation, efficiently hashing it with the available + * Tcl functions (Tcl_CreateHashEntry, Tcl_GetHashValue, etc). I chose + * not to do so for these reasons: + * + * We still need the information below. Using the hashing only removes + * us from needing the next/prev pointers. We still need the structure + * itself because we need more than one value associated with a widget. + * We need to keep track of parent pointers for sub-widgets (like cursors) + * so we can correctly close. We need to keep track of individual widget's + * id counters for any sub-widgets they may have. We need to be able to + * associate the name/client data outside the scope of the widget. + * + * So, is it better to use the hashing rather than + * the linear list we have now? I decided against it for the simple reason + * that to access the structure would require two calls. The first is + * Tcl_FindHashEntry(table, key) and then, once we have the entry, we'd + * have to do Tcl_GetHashValue(entry) to get the pointer of the structure. + * + * I believe the number of simultaneous DB widgets in existence at one time + * is not going to be that large (more than several dozen) such that + * linearly searching the list is not going to impact performance in a + * noticeable way. Should performance be impacted due to the size of the + * info list, then perhaps it is time to revisit this decision. + */ +typedef struct dbtcl_info { + LIST_ENTRY(dbtcl_info) entries; + Tcl_Interp *i_interp; + char *i_name; + enum INFOTYPE i_type; + union infop { + DB *dbp; + DBC *dbcp; + DB_ENV *envp; + DB_LOCK *lock; + DB_LOGC *logc; + DB_MPOOLFILE *mp; + DB_TXN *txnp; + void *anyp; + } un; + union data { + int anydata; + db_pgno_t pgno; + u_int32_t lockid; + } und; + union data2 { + int anydata; + int pagesz; + DB_COMPACT *c_data; + } und2; + DBT i_lockobj; + FILE *i_err; + char *i_errpfx; + + /* Callbacks--Tcl_Objs containing proc names */ + Tcl_Obj *i_compare; + Tcl_Obj *i_dupcompare; + Tcl_Obj *i_event; + Tcl_Obj *i_hashproc; + Tcl_Obj *i_isalive; + Tcl_Obj *i_part_callback; + Tcl_Obj *i_rep_send; + Tcl_Obj *i_second_call; + + /* Environment ID for the i_rep_send callback. */ + Tcl_Obj *i_rep_eid; + + struct dbtcl_info *i_parent; + int i_otherid[MAX_ID]; +} DBTCL_INFO; + +#define i_anyp un.anyp +#define i_dbp un.dbp +#define i_dbcp un.dbcp +#define i_envp un.envp +#define i_lock un.lock +#define i_logc un.logc +#define i_mp un.mp +#define i_pagep un.anyp +#define i_txnp un.txnp + +#define i_data und.anydata +#define i_pgno und.pgno +#define i_locker und.lockid +#define i_data2 und2.anydata +#define i_pgsz und2.pagesz +#define i_cdata und2.c_data + +#define i_envtxnid i_otherid[0] +#define i_envmpid i_otherid[1] +#define i_envlockid i_otherid[2] +#define i_envlogcid i_otherid[3] + +#define i_mppgid i_otherid[0] + +#define i_dbdbcid i_otherid[0] + +extern int __debug_on, __debug_print, __debug_stop, __debug_test; + +typedef struct dbtcl_global { + LIST_HEAD(infohead, dbtcl_info) g_infohead; +} DBTCL_GLOBAL; +#define __db_infohead __dbtcl_global.g_infohead + +extern DBTCL_GLOBAL __dbtcl_global; + +/* + * Tcl_NewStringObj takes an "int" length argument, when the typical use is to + * call it with a size_t length (for example, returned by strlen). Tcl is in + * the wrong, but that doesn't help us much -- cast the argument. + */ +#define NewStringObj(a, b) \ + Tcl_NewStringObj(a, (int)b) + +#define NAME_TO_DB(name) (DB *)_NameToPtr((name)) +#define NAME_TO_DBC(name) (DBC *)_NameToPtr((name)) +#define NAME_TO_ENV(name) (DB_ENV *)_NameToPtr((name)) +#define NAME_TO_LOCK(name) (DB_LOCK *)_NameToPtr((name)) +#define NAME_TO_MP(name) (DB_MPOOLFILE *)_NameToPtr((name)) +#define NAME_TO_TXN(name) (DB_TXN *)_NameToPtr((name)) +#define NAME_TO_SEQUENCE(name) (DB_SEQUENCE *)_NameToPtr((name)) + +/* + * MAKE_STAT_LIST appends a {name value} pair to a result list that MUST be + * called 'res' that is a Tcl_Obj * in the local function. This macro also + * assumes a label "error" to go to in the event of a Tcl error. For stat + * functions this will typically go before the "free" function to free the + * stat structure returned by DB. + */ +#define MAKE_STAT_LIST(s, v) do { \ + result = _SetListElemInt(interp, res, (s), (long)(v)); \ + if (result != TCL_OK) \ + goto error; \ +} while (0) + +#define MAKE_WSTAT_LIST(s, v) do { \ + result = _SetListElemWideInt(interp, res, (s), (int64_t)(v)); \ + if (result != TCL_OK) \ + goto error; \ +} while (0) + +/* + * MAKE_STAT_LSN appends a {name {LSNfile LSNoffset}} pair to a result list + * that MUST be called 'res' that is a Tcl_Obj * in the local + * function. This macro also assumes a label "error" to go to + * in the even of a Tcl error. For stat functions this will + * typically go before the "free" function to free the stat structure + * returned by DB. + */ +#define MAKE_STAT_LSN(s, lsn) do { \ + myobjc = 2; \ + myobjv[0] = Tcl_NewLongObj((long)(lsn)->file); \ + myobjv[1] = Tcl_NewLongObj((long)(lsn)->offset); \ + lsnlist = Tcl_NewListObj(myobjc, myobjv); \ + myobjc = 2; \ + myobjv[0] = Tcl_NewStringObj((s), (int)strlen(s)); \ + myobjv[1] = lsnlist; \ + thislist = Tcl_NewListObj(myobjc, myobjv); \ + result = Tcl_ListObjAppendElement(interp, res, thislist); \ + if (result != TCL_OK) \ + goto error; \ +} while (0) + +/* + * MAKE_STAT_STRLIST appends a {name string} pair to a result list + * that MUST be called 'res' that is a Tcl_Obj * in the local + * function. This macro also assumes a label "error" to go to + * in the even of a Tcl error. For stat functions this will + * typically go before the "free" function to free the stat structure + * returned by DB. + */ +#define MAKE_STAT_STRLIST(s,s1) do { \ + result = _SetListElem(interp, res, (s), (u_int32_t)strlen(s), \ + (s1), (u_int32_t)strlen(s1)); \ + if (result != TCL_OK) \ + goto error; \ +} while (0) + +/* + * MAKE_SITE_LIST appends a {eid host port status} tuple to a result list + * that MUST be called 'res' that is a Tcl_Obj * in the local function. + * This macro also assumes a label "error" to go to in the event of a Tcl + * error. + */ +#define MAKE_SITE_LIST(e, h, p, s) do { \ + myobjc = 4; \ + myobjv[0] = Tcl_NewIntObj(e); \ + myobjv[1] = Tcl_NewStringObj((h), (int)strlen(h)); \ + myobjv[2] = Tcl_NewIntObj((int)p); \ + myobjv[3] = Tcl_NewStringObj((s), (int)strlen(s)); \ + thislist = Tcl_NewListObj(myobjc, myobjv); \ + result = Tcl_ListObjAppendElement(interp, res, thislist); \ + if (result != TCL_OK) \ + goto error; \ +} while (0) + +/* + * FLAG_CHECK checks that the given flag is not set yet. + * If it is, it sets up an error message. + */ +#define FLAG_CHECK(flag) do { \ + if ((flag) != 0) { \ + Tcl_SetResult(interp, \ + " Only 1 policy can be specified.\n", \ + TCL_STATIC); \ + result = TCL_ERROR; \ + break; \ + } \ +} while (0) + +/* + * FLAG_CHECK2 checks that the given flag is not set yet or is + * only set to the given allowed value. + * If it is, it sets up an error message. + */ +#define FLAG_CHECK2(flag, val) do { \ + if (((flag) & ~(val)) != 0) { \ + Tcl_SetResult(interp, \ + " Only 1 policy can be specified.\n", \ + TCL_STATIC); \ + result = TCL_ERROR; \ + break; \ + } \ +} while (0) + +/* + * IS_HELP checks whether the arg we bombed on is -?, which is a help option. + * If it is, we return TCL_OK (but leave the result set to whatever + * Tcl_GetIndexFromObj says, which lists all the valid options. Otherwise + * return TCL_ERROR. + */ +#define IS_HELP(s) \ + (strcmp(Tcl_GetStringFromObj(s,NULL), "-?") == 0) ? TCL_OK : TCL_ERROR + +#if defined(__cplusplus) +} +#endif + +#include "dbinc_auto/tcl_ext.h" +#endif /* !_DB_TCL_DB_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/txn.h b/src/libs/resiprocate/contrib/db/dbinc/txn.h new file mode 100644 index 00000000..7ee7542f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/txn.h @@ -0,0 +1,227 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_TXN_H_ +#define _DB_TXN_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Operation parameters to the delayed commit processing code. */ +typedef enum { + TXN_CLOSE, /* Close a DB handle whose close had failed. */ + TXN_REMOVE, /* Remove a file. */ + TXN_TRADE, /* Trade lockers. */ + TXN_TRADED /* Already traded; downgrade lock. */ +} TXN_EVENT_T; + +struct __db_txnregion; typedef struct __db_txnregion DB_TXNREGION; +struct __txn_logrec; typedef struct __txn_logrec DB_TXNLOGREC; + +/* + * !!! + * TXN_MINIMUM = (DB_LOCK_MAXID + 1) but this makes compilers complain. + */ +#define TXN_MINIMUM 0x80000000 +#define TXN_MAXIMUM 0xffffffff /* Maximum number of txn ids. */ +#define TXN_INVALID 0 /* Invalid transaction ID. */ + +#define DEF_MAX_TXNS 100 /* Default max transactions. */ +#define TXN_NSLOTS 4 /* Initial slots to hold DB refs */ + +/* + * Internal data maintained in shared memory for each transaction. + */ +typedef struct __txn_detail { + u_int32_t txnid; /* current transaction id + used to link free list also */ + pid_t pid; /* Process owning txn */ + db_threadid_t tid; /* Thread owning txn */ + + DB_LSN last_lsn; /* Last LSN written for this txn. */ + DB_LSN begin_lsn; /* LSN of begin record. */ + roff_t parent; /* Offset of transaction's parent. */ + roff_t name; /* Offset of txn name. */ + + u_int32_t nlog_dbs; /* Number of databases used. */ + u_int32_t nlog_slots; /* Number of allocated slots. */ + roff_t log_dbs; /* Databases used. */ + + DB_LSN read_lsn; /* Read LSN for MVCC. */ + DB_LSN visible_lsn; /* LSN at which this transaction's + changes are visible. */ + db_mutex_t mvcc_mtx; /* Version mutex. */ + u_int32_t mvcc_ref; /* Number of buffers created by this + transaction still in cache. */ + + SH_TAILQ_HEAD(__tdkids) kids; /* Linked list of child txn detail. */ + SH_TAILQ_ENTRY klinks; + + /* TXN_{ABORTED, COMMITTED PREPARED, RUNNING} */ + u_int32_t status; /* status of the transaction */ + +#define TXN_DTL_COLLECTED 0x1 /* collected during txn_recover */ +#define TXN_DTL_RESTORED 0x2 /* prepared txn restored */ +#define TXN_DTL_INMEMORY 0x4 /* uses in memory logs */ +#define TXN_DTL_SNAPSHOT 0x8 /* On the list of snapshot txns. */ + u_int32_t flags; + + SH_TAILQ_ENTRY links; /* active/free/snapshot list */ + + u_int8_t gid[DB_GID_SIZE]; /* global transaction id */ + roff_t slots[TXN_NSLOTS]; /* Initial DB slot allocation. */ +} TXN_DETAIL; + +/* + * DB_TXNMGR -- + * The transaction manager encapsulates the transaction system. + */ +struct __db_txnmgr { + /* + * These fields need to be protected for multi-threaded support. + * + * Lock list of active transactions (including the content of each + * TXN_DETAIL structure on the list). + */ + db_mutex_t mutex; + /* List of active transactions. */ + TAILQ_HEAD(_chain, __db_txn) txn_chain; + + u_int32_t n_discards; /* Number of txns discarded. */ + + /* These fields are never updated after creation, so not protected. */ + ENV *env; /* Environment. */ + REGINFO reginfo; /* Region information. */ +}; + +/* Macros to lock/unlock the transaction region as a whole. */ +#define TXN_SYSTEM_LOCK(env) \ + MUTEX_LOCK(env, ((DB_TXNREGION *) \ + (env)->tx_handle->reginfo.primary)->mtx_region) +#define TXN_SYSTEM_UNLOCK(env) \ + MUTEX_UNLOCK(env, ((DB_TXNREGION *) \ + (env)->tx_handle->reginfo.primary)->mtx_region) + +/* + * DB_TXNREGION -- + * The primary transaction data structure in the shared memory region. + */ +struct __db_txnregion { + db_mutex_t mtx_region; /* Region mutex. */ + + u_int32_t maxtxns; /* maximum number of active TXNs */ + u_int32_t last_txnid; /* last transaction id given out */ + u_int32_t cur_maxid; /* current max unused id. */ + + db_mutex_t mtx_ckp; /* Single thread checkpoints. */ + DB_LSN last_ckp; /* lsn of the last checkpoint */ + time_t time_ckp; /* time of last checkpoint */ + + DB_TXN_STAT stat; /* Statistics for txns. */ + +#define TXN_IN_RECOVERY 0x01 /* environment is being recovered */ + u_int32_t flags; + /* active TXN list */ + SH_TAILQ_HEAD(__active) active_txn; + SH_TAILQ_HEAD(__mvcc) mvcc_txn; +}; + +/* + * DB_TXNLOGREC -- + * An in-memory, linked-list copy of a log record. + */ +struct __txn_logrec { + STAILQ_ENTRY(__txn_logrec) links;/* Linked list. */ + + u_int8_t data[1]; /* Log record. */ +}; + +/* + * Log record types. Note that these are *not* alphabetical. This is + * intentional so that we don't change the meaning of values between + * software upgrades. + * + * EXPECTED, UNEXPECTED, IGNORE, and OK are used in the txnlist functions. + * Here is an explanation of how the statuses are used. + * + * TXN_OK + * BEGIN records for transactions found on the txnlist during + * OPENFILES (BEGIN records are those with a prev_lsn of 0,0) + * + * TXN_COMMIT + * Transaction committed and should be rolled forward. + * + * TXN_ABORT + * This transaction's changes must be undone. Either there was + * never a prepare or commit record for this transaction OR there + * was a commit, but we are recovering to a timestamp or particular + * LSN and that point is before this transaction's commit. + * + * TXN_PREPARE + * Prepare record, but no commit record is in the log. + * + * TXN_IGNORE + * Generic meaning is that this transaction should not be + * processed during later recovery passes. We use it in a + * number of different manners: + * + * 1. We never saw its BEGIN record. Therefore, the logs have + * been reclaimed and we *know* that this transaction doesn't + * need to be aborted, because in order for it to be + * reclaimed, there must have been a subsequent checkpoint + * (and any dirty pages for this transaction made it to + * disk). + * + * 2. This is a child transaction that created a database. + * For some reason, we don't want to recreate that database + * (i.e., it already exists or some other database created + * after it exists). + * + * 3. During recovery open of subdatabases, if the master check fails, + * we use a TXN_IGNORE on the create of the subdb in the nested + * transaction. + * + * 4. During a remove, the file with the name being removed isn't + * the file for which we are recovering a remove. + * + * TXN_EXPECTED + * After a successful open during recovery, we update the + * transaction's status to TXN_EXPECTED. The open was done + * in the parent, but in the open log record, we record the + * child transaction's ID if we also did a create. When there + * is a valid ID in that field, we use it and mark the child's + * status as TXN_EXPECTED (indicating that we don't need to redo + * a create for this file). + * + * When recovering a remove, if we don't find or can't open + * the file, the child (which does the remove) gets marked + * EXPECTED (indicating that we don't need to redo the remove). + * + * TXN_UNEXPECTED + * During recovery, we attempted an open that should have succeeded + * and we got ENOENT, so like with the EXPECTED case, we indicate + * in the child that we got the UNEXPECTED return so that we do redo + * the creating/deleting operation. + * + */ +#define TXN_OK 0 +#define TXN_COMMIT 1 +#define TXN_PREPARE 2 +#define TXN_ABORT 3 +#define TXN_IGNORE 4 +#define TXN_EXPECTED 5 +#define TXN_UNEXPECTED 6 + +#if defined(__cplusplus) +} +#endif + +#include "dbinc_auto/txn_auto.h" +#include "dbinc_auto/txn_ext.h" +#endif /* !_DB_TXN_H_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc/xa.h b/src/libs/resiprocate/contrib/db/dbinc/xa.h new file mode 100644 index 00000000..71333c2c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc/xa.h @@ -0,0 +1,179 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1998-2004 + * Sleepycat Software. All rights reserved. + * + * $Id: xa.h,v 11.7 2004/01/28 03:36:02 bostic Exp $ + */ +/* + * Start of xa.h header + * + * Define a symbol to prevent multiple inclusions of this header file + */ +#ifndef XA_H +#define XA_H + +/* + * Transaction branch identification: XID and NULLXID: + */ +#define XIDDATASIZE 128 /* size in bytes */ +#define MAXGTRIDSIZE 64 /* maximum size in bytes of gtrid */ +#define MAXBQUALSIZE 64 /* maximum size in bytes of bqual */ + +struct xid_t { + long formatID; /* format identifier */ + long gtrid_length; /* value from 1 through 64 */ + long bqual_length; /* value from 1 through 64 */ + char data[XIDDATASIZE]; +}; +typedef struct xid_t XID; +/* + * A value of -1 in formatID means that the XID is null. + */ + +/* + * Declarations of routines by which RMs call TMs: + */ +extern int ax_reg __P((int, XID *, long)); +extern int ax_unreg __P((int, long)); + +/* + * XA Switch Data Structure + */ +#define RMNAMESZ 32 /* length of resource manager name, */ + /* including the null terminator */ +#define MAXINFOSIZE 256 /* maximum size in bytes of xa_info */ + /* strings, including the null + terminator */ +struct xa_switch_t { + char name[RMNAMESZ]; /* name of resource manager */ + long flags; /* resource manager specific options */ + long version; /* must be 0 */ + int (*xa_open_entry) /* xa_open function pointer */ + __P((char *, int, long)); + int (*xa_close_entry) /* xa_close function pointer */ + __P((char *, int, long)); + int (*xa_start_entry) /* xa_start function pointer */ + __P((XID *, int, long)); + int (*xa_end_entry) /* xa_end function pointer */ + __P((XID *, int, long)); + int (*xa_rollback_entry) /* xa_rollback function pointer */ + __P((XID *, int, long)); + int (*xa_prepare_entry) /* xa_prepare function pointer */ + __P((XID *, int, long)); + int (*xa_commit_entry) /* xa_commit function pointer */ + __P((XID *, int, long)); + int (*xa_recover_entry) /* xa_recover function pointer */ + __P((XID *, long, int, long)); + int (*xa_forget_entry) /* xa_forget function pointer */ + __P((XID *, int, long)); + int (*xa_complete_entry) /* xa_complete function pointer */ + __P((int *, int *, int, long)); +}; + +/* + * Flag definitions for the RM switch + */ +#define TMNOFLAGS 0x00000000L /* no resource manager features + selected */ +#define TMREGISTER 0x00000001L /* resource manager dynamically + registers */ +#define TMNOMIGRATE 0x00000002L /* resource manager does not support + association migration */ +#define TMUSEASYNC 0x00000004L /* resource manager supports + asynchronous operations */ +/* + * Flag definitions for xa_ and ax_ routines + */ +/* use TMNOFLAGGS, defined above, when not specifying other flags */ +#define TMASYNC 0x80000000L /* perform routine asynchronously */ +#define TMONEPHASE 0x40000000L /* caller is using one-phase commit + optimisation */ +#define TMFAIL 0x20000000L /* dissociates caller and marks + transaction branch rollback-only */ +#define TMNOWAIT 0x10000000L /* return if blocking condition + exists */ +#define TMRESUME 0x08000000L /* caller is resuming association with + suspended transaction branch */ +#define TMSUCCESS 0x04000000L /* dissociate caller from transaction + branch */ +#define TMSUSPEND 0x02000000L /* caller is suspending, not ending, + association */ +#define TMSTARTRSCAN 0x01000000L /* start a recovery scan */ +#define TMENDRSCAN 0x00800000L /* end a recovery scan */ +#define TMMULTIPLE 0x00400000L /* wait for any asynchronous + operation */ +#define TMJOIN 0x00200000L /* caller is joining existing + transaction branch */ +#define TMMIGRATE 0x00100000L /* caller intends to perform + migration */ + +/* + * ax_() return codes (transaction manager reports to resource manager) + */ +#define TM_JOIN 2 /* caller is joining existing + transaction branch */ +#define TM_RESUME 1 /* caller is resuming association with + suspended transaction branch */ +#define TM_OK 0 /* normal execution */ +#define TMER_TMERR -1 /* an error occurred in the transaction + manager */ +#define TMER_INVAL -2 /* invalid arguments were given */ +#define TMER_PROTO -3 /* routine invoked in an improper + context */ + +/* + * xa_() return codes (resource manager reports to transaction manager) + */ +#define XA_RBBASE 100 /* The inclusive lower bound of the + rollback codes */ +#define XA_RBROLLBACK XA_RBBASE /* The rollback was caused by an + unspecified reason */ +#define XA_RBCOMMFAIL XA_RBBASE+1 /* The rollback was caused by a + communication failure */ +#define XA_RBDEADLOCK XA_RBBASE+2 /* A deadlock was detected */ +#define XA_RBINTEGRITY XA_RBBASE+3 /* A condition that violates the + integrity of the resources was + detected */ +#define XA_RBOTHER XA_RBBASE+4 /* The resource manager rolled back the + transaction branch for a reason not + on this list */ +#define XA_RBPROTO XA_RBBASE+5 /* A protocol error occurred in the + resource manager */ +#define XA_RBTIMEOUT XA_RBBASE+6 /* A transaction branch took too long */ +#define XA_RBTRANSIENT XA_RBBASE+7 /* May retry the transaction branch */ +#define XA_RBEND XA_RBTRANSIENT /* The inclusive upper bound of the + rollback codes */ +#define XA_NOMIGRATE 9 /* resumption must occur where + suspension occurred */ +#define XA_HEURHAZ 8 /* the transaction branch may have + been heuristically completed */ +#define XA_HEURCOM 7 /* the transaction branch has been + heuristically committed */ +#define XA_HEURRB 6 /* the transaction branch has been + heuristically rolled back */ +#define XA_HEURMIX 5 /* the transaction branch has been + heuristically committed and rolled + back */ +#define XA_RETRY 4 /* routine returned with no effect and + may be re-issued */ +#define XA_RDONLY 3 /* the transaction branch was read-only + and has been committed */ +#define XA_OK 0 /* normal execution */ +#define XAER_ASYNC -2 /* asynchronous operation already + outstanding */ +#define XAER_RMERR -3 /* a resource manager error occurred in + the transaction branch */ +#define XAER_NOTA -4 /* the XID is not valid */ +#define XAER_INVAL -5 /* invalid arguments were given */ +#define XAER_PROTO -6 /* routine invoked in an improper + context */ +#define XAER_RMFAIL -7 /* resource manager unavailable */ +#define XAER_DUPID -8 /* the XID already exists */ +#define XAER_OUTSIDE -9 /* resource manager doing work outside + transaction */ +#endif /* ifndef XA_H */ +/* + * End of xa.h header + */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/btree_auto.h b/src/libs/resiprocate/contrib/db/dbinc_auto/btree_auto.h new file mode 100644 index 00000000..a61652b2 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/btree_auto.h @@ -0,0 +1,221 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#ifndef __bam_AUTO_H +#define __bam_AUTO_H +#define DB___bam_split 62 +typedef struct ___bam_split_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t left; + DB_LSN llsn; + db_pgno_t right; + DB_LSN rlsn; + u_int32_t indx; + db_pgno_t npgno; + DB_LSN nlsn; + db_pgno_t ppgno; + DB_LSN plsn; + u_int32_t pindx; + DBT pg; + DBT pentry; + DBT rentry; + u_int32_t opflags; +} __bam_split_args; + +#define DB___bam_split_42 62 +typedef struct ___bam_split_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t left; + DB_LSN llsn; + db_pgno_t right; + DB_LSN rlsn; + u_int32_t indx; + db_pgno_t npgno; + DB_LSN nlsn; + db_pgno_t root_pgno; + DBT pg; + u_int32_t opflags; +} __bam_split_42_args; + +#define DB___bam_rsplit 63 +typedef struct ___bam_rsplit_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DBT pgdbt; + db_pgno_t root_pgno; + db_pgno_t nrec; + DBT rootent; + DB_LSN rootlsn; +} __bam_rsplit_args; + +#define DB___bam_adj 55 +typedef struct ___bam_adj_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN lsn; + u_int32_t indx; + u_int32_t indx_copy; + u_int32_t is_insert; +} __bam_adj_args; + +#define DB___bam_cadjust 56 +typedef struct ___bam_cadjust_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN lsn; + u_int32_t indx; + int32_t adjust; + u_int32_t opflags; +} __bam_cadjust_args; + +#define DB___bam_cdel 57 +typedef struct ___bam_cdel_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN lsn; + u_int32_t indx; +} __bam_cdel_args; + +#define DB___bam_repl 58 +typedef struct ___bam_repl_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN lsn; + u_int32_t indx; + u_int32_t isdeleted; + DBT orig; + DBT repl; + u_int32_t prefix; + u_int32_t suffix; +} __bam_repl_args; + +#define DB___bam_root 59 +typedef struct ___bam_root_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t meta_pgno; + db_pgno_t root_pgno; + DB_LSN meta_lsn; +} __bam_root_args; + +#define DB___bam_curadj 64 +typedef struct ___bam_curadj_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_ca_mode mode; + db_pgno_t from_pgno; + db_pgno_t to_pgno; + db_pgno_t left_pgno; + u_int32_t first_indx; + u_int32_t from_indx; + u_int32_t to_indx; +} __bam_curadj_args; + +#define DB___bam_rcuradj 65 +typedef struct ___bam_rcuradj_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + ca_recno_arg mode; + db_pgno_t root; + db_recno_t recno; + u_int32_t order; +} __bam_rcuradj_args; + +#define DB___bam_relink_43 147 +typedef struct ___bam_relink_43_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN lsn; + db_pgno_t prev; + DB_LSN lsn_prev; + db_pgno_t next; + DB_LSN lsn_next; +} __bam_relink_43_args; + +#define DB___bam_relink 147 +typedef struct ___bam_relink_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + db_pgno_t new_pgno; + db_pgno_t prev; + DB_LSN lsn_prev; + db_pgno_t next; + DB_LSN lsn_next; +} __bam_relink_args; + +#define DB___bam_merge_44 148 +typedef struct ___bam_merge_44_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN lsn; + db_pgno_t npgno; + DB_LSN nlsn; + DBT hdr; + DBT data; + DBT ind; +} __bam_merge_44_args; + +#define DB___bam_merge 148 +typedef struct ___bam_merge_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN lsn; + db_pgno_t npgno; + DB_LSN nlsn; + DBT hdr; + DBT data; + int32_t pg_copy; +} __bam_merge_args; + +#define DB___bam_pgno 149 +typedef struct ___bam_pgno_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN lsn; + u_int32_t indx; + db_pgno_t opgno; + db_pgno_t npgno; +} __bam_pgno_args; + +#endif diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/btree_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/btree_ext.h new file mode 100644 index 00000000..eefaf807 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/btree_ext.h @@ -0,0 +1,174 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _btree_ext_h_ +#define _btree_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __bam_compact __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *)); +int __bam_cmp __P((DBC *, const DBT *, PAGE *, u_int32_t, int (*)(DB *, const DBT *, const DBT *), int *)); +int __bam_defcmp __P((DB *, const DBT *, const DBT *)); +size_t __bam_defpfx __P((DB *, const DBT *, const DBT *)); +int __bam_compress_dupcmp __P((DB *, const DBT *, const DBT *)); +int __bam_defcompress __P((DB *, const DBT *, const DBT *, const DBT *, const DBT *, DBT *)); +int __bam_defdecompress __P((DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *)); +int __bamc_compress_get __P((DBC *, DBT *, DBT *, u_int32_t)); +int __bamc_compress_put __P((DBC *, DBT *, DBT *, u_int32_t)); +int __bamc_compress_del __P((DBC *, u_int32_t)); +int __bamc_compress_bulk_del __P((DBC *, DBT *, u_int32_t)); +int __bamc_compress_count __P((DBC *, db_recno_t *)); +int __bamc_compress_cmp __P((DBC *, DBC *, int *)); +int __bamc_compress_dup __P((DBC *, DBC *, u_int32_t)); +int __bam_compress_salvage __P((DB *, VRFY_DBINFO *, void *, int (*)(void *, const void *), DBT *, DBT *)); +int __bam_compress_count __P((DBC *, u_int32_t *, u_int32_t *)); +int __bam_pgin __P((DB *, db_pgno_t, void *, DBT *)); +int __bam_pgout __P((DB *, db_pgno_t, void *, DBT *)); +int __bam_mswap __P((ENV *, PAGE *)); +int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, int, int *)); +int __ram_ca_delete __P((DB *, db_pgno_t, int *)); +int __bam_ca_di __P((DBC *, db_pgno_t, u_int32_t, int)); +int __bam_ca_dup __P((DBC *, u_int32_t, db_pgno_t, u_int32_t, db_pgno_t, u_int32_t)); +int __bam_ca_undodup __P((DB *, u_int32_t, db_pgno_t, u_int32_t, u_int32_t)); +int __bam_ca_rsplit __P((DBC *, db_pgno_t, db_pgno_t)); +int __bam_ca_split __P((DBC *, db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t, int)); +int __bam_ca_undosplit __P((DB *, db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t)); +int __bamc_init __P((DBC *, DBTYPE)); +int __bamc_refresh __P((DBC *)); +int __bamc_cmp __P((DBC *, DBC *, int *)); +int __bamc_count __P((DBC *, db_recno_t *)); +int __bamc_dup __P((DBC *, DBC *, u_int32_t)); +int __bam_bulk_overflow __P((DBC *, u_int32_t, db_pgno_t, u_int8_t *)); +int __bam_bulk_duplicates __P((DBC *, db_pgno_t, u_int8_t *, int32_t *, int32_t **, u_int8_t **, u_int32_t *, int)); +int __bamc_rget __P((DBC *, DBT *)); +int __bam_opd_exists __P((DBC *, db_pgno_t)); +int __bam_ditem __P((DBC *, PAGE *, u_int32_t)); +int __bam_adjindx __P((DBC *, PAGE *, u_int32_t, u_int32_t, int)); +int __bam_dpages __P((DBC *, int, int)); +int __bam_relink __P((DBC *, PAGE *, PAGE *, db_pgno_t)); +int __bam_pupdate __P((DBC *, PAGE *)); +int __bam_db_create __P((DB *)); +int __bam_db_close __P((DB *)); +void __bam_map_flags __P((DB *, u_int32_t *, u_int32_t *)); +int __bam_set_flags __P((DB *, u_int32_t *flagsp)); +int __bam_set_bt_compare __P((DB *, int (*)(DB *, const DBT *, const DBT *))); +int __bam_set_bt_compress __P((DB *, int (*)(DB *, const DBT *, const DBT *, const DBT *, const DBT *, DBT *), int (*)(DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *))); +int __bam_get_bt_minkey __P((DB *, u_int32_t *)); +void __bam_copy_config __P((DB *, DB*, u_int32_t)); +void __ram_map_flags __P((DB *, u_int32_t *, u_int32_t *)); +int __ram_set_flags __P((DB *, u_int32_t *flagsp)); +int __ram_get_re_len __P((DB *, u_int32_t *)); +int __ram_get_re_pad __P((DB *, int *)); +int __bam_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, db_pgno_t, u_int32_t)); +int __bam_metachk __P((DB *, const char *, BTMETA *)); +int __bam_read_root __P((DB *, DB_THREAD_INFO *, DB_TXN *, db_pgno_t, u_int32_t)); +int __bam_new_file __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *)); +int __bam_new_subdb __P((DB *, DB *, DB_THREAD_INFO *, DB_TXN *)); +int __bam_iitem __P((DBC *, DBT *, DBT *, u_int32_t, u_int32_t)); +int __bam_ritem __P((DBC *, PAGE *, u_int32_t, DBT *, u_int32_t)); +int __bam_irep __P((DBC *, PAGE *, u_int32_t, DBT *, DBT *)); +int __bam_split_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_split_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_rsplit_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_adj_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_cadjust_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_cdel_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_repl_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_root_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_curadj_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_rcuradj_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_relink_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_merge_44_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_merge_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_pgno_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_relink_43_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_reclaim __P((DB *, DB_THREAD_INFO *, DB_TXN *)); +int __bam_truncate __P((DBC *, u_int32_t *)); +int __ram_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, db_pgno_t, u_int32_t)); +int __ram_append __P((DBC *, DBT *, DBT *)); +int __ramc_del __P((DBC *, u_int32_t)); +int __ramc_get __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); +int __ramc_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); +int __ram_ca __P((DBC *, ca_recno_arg, int *)); +int __ram_getno __P((DBC *, const DBT *, db_recno_t *, int)); +int __ram_writeback __P((DB *)); +int __bam_rsearch __P((DBC *, db_recno_t *, u_int32_t, int, int *)); +int __bam_adjust __P((DBC *, int32_t)); +int __bam_nrecs __P((DBC *, db_recno_t *)); +db_recno_t __bam_total __P((DB *, PAGE *)); +int __bam_get_root __P((DBC *, db_pgno_t, int, u_int32_t, int *)); +int __bam_search __P((DBC *, db_pgno_t, const DBT *, u_int32_t, int, db_recno_t *, int *)); +int __bam_stkrel __P((DBC *, u_int32_t)); +int __bam_stkgrow __P((ENV *, BTREE_CURSOR *)); +int __bam_split __P((DBC *, void *, db_pgno_t *)); +int __bam_broot __P((DBC *, PAGE *, u_int32_t, PAGE *, PAGE *)); +int __ram_root __P((DBC *, PAGE *, PAGE *, PAGE *)); +int __bam_pinsert __P((DBC *, EPG *, u_int32_t, PAGE *, PAGE *, int)); +int __bam_copy __P((DB *, PAGE *, PAGE *, u_int32_t, u_int32_t)); +int __bam_stat __P((DBC *, void *, u_int32_t)); +int __bam_stat_print __P((DBC *, u_int32_t)); +int __bam_stat_callback __P((DBC *, PAGE *, void *, int *)); +void __bam_print_cursor __P((DBC *)); +int __bam_key_range __P((DBC *, DBT *, DB_KEY_RANGE *, u_int32_t)); +int __bam_traverse __P((DBC *, db_lockmode_t, db_pgno_t, int (*)(DBC *, PAGE *, void *, int *), void *)); +int __bam_30_btreemeta __P((DB *, char *, u_int8_t *)); +int __bam_31_btreemeta __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); +int __bam_31_lbtree __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); +int __bam_vrfy_meta __P((DB *, VRFY_DBINFO *, BTMETA *, db_pgno_t, u_int32_t)); +int __ram_vrfy_leaf __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); +int __bam_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); +int __bam_vrfy_itemorder __P((DB *, VRFY_DBINFO *, DB_THREAD_INFO *, PAGE *, db_pgno_t, u_int32_t, int, int, u_int32_t)); +int __bam_vrfy_structure __P((DB *, VRFY_DBINFO *, db_pgno_t, void *, void *, u_int32_t)); +int __bam_vrfy_subtree __P((DB *, VRFY_DBINFO *, db_pgno_t, void *, void *, u_int32_t, u_int32_t *, u_int32_t *, u_int32_t *)); +int __bam_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, PAGE *, void *, int (*)(void *, const void *), DBT *, u_int32_t)); +int __bam_salvage_walkdupint __P((DB *, VRFY_DBINFO *, PAGE *, DBT *, void *, int (*)(void *, const void *), u_int32_t)); +int __bam_meta2pgset __P((DB *, VRFY_DBINFO *, BTMETA *, u_int32_t, DB *)); +int __bam_split_read __P((ENV *, DB **, void *, void *, __bam_split_args **)); +int __bam_split_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, u_int32_t, const DBT *, const DBT *, const DBT *, u_int32_t)); +int __bam_split_42_read __P((ENV *, DB **, void *, void *, __bam_split_42_args **)); +int __bam_rsplit_read __P((ENV *, DB **, void *, void *, __bam_rsplit_args **)); +int __bam_rsplit_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, const DBT *, db_pgno_t, db_pgno_t, const DBT *, DB_LSN *)); +int __bam_adj_read __P((ENV *, DB **, void *, void *, __bam_adj_args **)); +int __bam_adj_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *, u_int32_t, u_int32_t, u_int32_t)); +int __bam_cadjust_read __P((ENV *, DB **, void *, void *, __bam_cadjust_args **)); +int __bam_cadjust_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *, u_int32_t, int32_t, u_int32_t)); +int __bam_cdel_read __P((ENV *, DB **, void *, void *, __bam_cdel_args **)); +int __bam_cdel_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *, u_int32_t)); +int __bam_repl_read __P((ENV *, DB **, void *, void *, __bam_repl_args **)); +int __bam_repl_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *, u_int32_t, u_int32_t, const DBT *, const DBT *, u_int32_t, u_int32_t)); +int __bam_root_read __P((ENV *, DB **, void *, void *, __bam_root_args **)); +int __bam_root_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, db_pgno_t, DB_LSN *)); +int __bam_curadj_read __P((ENV *, DB **, void *, void *, __bam_curadj_args **)); +int __bam_curadj_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_ca_mode, db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t, u_int32_t, u_int32_t)); +int __bam_rcuradj_read __P((ENV *, DB **, void *, void *, __bam_rcuradj_args **)); +int __bam_rcuradj_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, ca_recno_arg, db_pgno_t, db_recno_t, u_int32_t)); +int __bam_relink_43_read __P((ENV *, DB **, void *, void *, __bam_relink_43_args **)); +int __bam_relink_read __P((ENV *, DB **, void *, void *, __bam_relink_args **)); +int __bam_relink_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, db_pgno_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *)); +int __bam_merge_44_read __P((ENV *, DB **, void *, void *, __bam_merge_44_args **)); +int __bam_merge_read __P((ENV *, DB **, void *, void *, __bam_merge_args **)); +int __bam_merge_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, const DBT *, const DBT *, int32_t)); +int __bam_pgno_read __P((ENV *, DB **, void *, void *, __bam_pgno_args **)); +int __bam_pgno_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *, u_int32_t, db_pgno_t, db_pgno_t)); +int __bam_init_recover __P((ENV *, DB_DISTAB *)); +int __bam_split_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_split_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_rsplit_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_adj_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_cadjust_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_cdel_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_repl_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_root_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_curadj_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_rcuradj_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_relink_43_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_relink_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_merge_44_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_merge_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_pgno_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __bam_init_print __P((ENV *, DB_DISTAB *)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_btree_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/clib_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/clib_ext.h new file mode 100644 index 00000000..9cef78d6 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/clib_ext.h @@ -0,0 +1,110 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _clib_ext_h_ +#define _clib_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +#ifndef HAVE_ATOI +int atoi __P((const char *)); +#endif +#ifndef HAVE_ATOL +long atol __P((const char *)); +#endif +#ifndef HAVE_GETCWD +char *getcwd __P((char *, size_t)); +#endif +#ifndef HAVE_GETOPT +int getopt __P((int, char * const *, const char *)); +#endif +#ifndef HAVE_ISALPHA +int isalpha __P((int)); +#endif +#ifndef HAVE_ISDIGIT +int isdigit __P((int)); +#endif +#ifndef HAVE_ISPRINT +int isprint __P((int)); +#endif +#ifndef HAVE_ISSPACE +int isspace __P((int)); +#endif +#ifndef HAVE_MEMCMP +int memcmp __P((const void *, const void *, size_t)); +#endif +#ifndef HAVE_MEMCPY +void *memcpy __P((void *, const void *, size_t)); +#endif +#ifndef HAVE_MEMMOVE +void *memmove __P((void *, const void *, size_t)); +#endif +#ifndef HAVE_PRINTF +int printf __P((const char *, ...)); +#endif +#ifndef HAVE_PRINTF +int fprintf __P((FILE *, const char *, ...)); +#endif +#ifndef HAVE_PRINTF +int vfprintf __P((FILE *, const char *, va_list)); +#endif +#ifndef HAVE_QSORT +void qsort __P((void *, size_t, size_t, int(*)(const void *, const void *))); +#endif +#ifndef HAVE_RAISE +int raise __P((int)); +#endif +#ifndef HAVE_RAND +int rand __P((void)); +void srand __P((unsigned int)); +#endif +#ifndef HAVE_SNPRINTF +int snprintf __P((char *, size_t, const char *, ...)); +#endif +#ifndef HAVE_VSNPRINTF +int vsnprintf __P((char *, size_t, const char *, va_list)); +#endif +#ifndef HAVE_STRCASECMP +int strcasecmp __P((const char *, const char *)); +#endif +#ifndef HAVE_STRCASECMP +int strncasecmp __P((const char *, const char *, size_t)); +#endif +#ifndef HAVE_STRCAT +char *strcat __P((char *, const char *)); +#endif +#ifndef HAVE_STRCHR +char *strchr __P((const char *, int)); +#endif +#ifndef HAVE_STRDUP +char *strdup __P((const char *)); +#endif +#ifndef HAVE_STRERROR +char *strerror __P((int)); +#endif +#ifndef HAVE_STRNCAT +char *strncat __P((char *, const char *, size_t)); +#endif +#ifndef HAVE_STRNCMP +int strncmp __P((const char *, const char *, size_t)); +#endif +#ifndef HAVE_STRRCHR +char *strrchr __P((const char *, int)); +#endif +#ifndef HAVE_STRSEP +char *strsep __P((char **, const char *)); +#endif +#ifndef HAVE_STRTOL +long strtol __P((const char *, char **, int)); +#endif +#ifndef HAVE_STRTOUL +unsigned long strtoul __P((const char *, char **, int)); +#endif +#ifndef HAVE_TIME +time_t time __P((time_t *)); +#endif + +#if defined(__cplusplus) +} +#endif +#endif /* !_clib_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/common_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/common_ext.h new file mode 100644 index 00000000..3a76e0dc --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/common_ext.h @@ -0,0 +1,72 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _common_ext_h_ +#define _common_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __crypto_region_init __P((ENV *)); +int __db_isbigendian __P((void)); +int __db_byteorder __P((ENV *, int)); +u_int32_t __db_compress_count_int __P((u_int64_t)); +int __db_compress_int __P((u_int8_t *, u_int64_t)); +u_int32_t __db_decompress_count_int __P((const u_int8_t *)); +int __db_decompress_int __P((const u_int8_t *, u_int64_t *)); +int __db_decompress_int32 __P((const u_int8_t *, u_int32_t *)); +int __db_fchk __P((ENV *, const char *, u_int32_t, u_int32_t)); +int __db_fcchk __P((ENV *, const char *, u_int32_t, u_int32_t, u_int32_t)); +int __db_ferr __P((const ENV *, const char *, int)); +int __db_fnl __P((const ENV *, const char *)); +int __db_pgerr __P((DB *, db_pgno_t, int)); +int __db_pgfmt __P((ENV *, db_pgno_t)); +#ifdef DIAGNOSTIC +void __db_assert __P((ENV *, const char *, const char *, int)); +#endif +int __env_panic_msg __P((ENV *)); +int __env_panic __P((ENV *, int)); +char *__db_unknown_error __P((int)); +void __db_syserr __P((const ENV *, int, const char *, ...)) __attribute__ ((__format__ (__printf__, 3, 4))); +void __db_err __P((const ENV *, int, const char *, ...)) __attribute__ ((__format__ (__printf__, 3, 4))); +void __db_errx __P((const ENV *, const char *, ...)) __attribute__ ((__format__ (__printf__, 2, 3))); +void __db_errcall __P((const DB_ENV *, int, db_error_set_t, const char *, va_list)); +void __db_errfile __P((const DB_ENV *, int, db_error_set_t, const char *, va_list)); +void __db_msgadd __P((ENV *, DB_MSGBUF *, const char *, ...)) __attribute__ ((__format__ (__printf__, 3, 4))); +void __db_msgadd_ap __P((ENV *, DB_MSGBUF *, const char *, va_list)); +void __db_msg __P((const ENV *, const char *, ...)) __attribute__ ((__format__ (__printf__, 2, 3))); +int __db_unknown_flag __P((ENV *, char *, u_int32_t)); +int __db_unknown_type __P((ENV *, char *, DBTYPE)); +int __db_unknown_path __P((ENV *, char *)); +int __db_check_txn __P((DB *, DB_TXN *, DB_LOCKER *, int)); +int __db_txn_deadlock_err __P((ENV *, DB_TXN *)); +int __db_not_txn_env __P((ENV *)); +int __db_rec_toobig __P((ENV *, u_int32_t, u_int32_t)); +int __db_rec_repl __P((ENV *, u_int32_t, u_int32_t)); +int __dbc_logging __P((DBC *)); +int __db_check_lsn __P((ENV *, DB_LSN *, DB_LSN *)); +int __db_rdonly __P((const ENV *, const char *)); +int __db_space_err __P((const DB *)); +int __db_failed __P((const ENV *, const char *, pid_t, db_threadid_t)); +int __db_getlong __P((DB_ENV *, const char *, char *, long, long, long *)); +int __db_getulong __P((DB_ENV *, const char *, char *, u_long, u_long, u_long *)); +void __db_idspace __P((u_int32_t *, int, u_int32_t *, u_int32_t *)); +u_int32_t __db_log2 __P((u_int32_t)); +u_int32_t __db_tablesize __P((u_int32_t)); +void __db_hashinit __P((void *, u_int32_t)); +int __dbt_usercopy __P((ENV *, DBT *)); +void __dbt_userfree __P((ENV *, DBT *, DBT *, DBT *)); +int __db_mkpath __P((ENV *, const char *)); +u_int32_t __db_openflags __P((int)); +int __db_util_arg __P((char *, char *, int *, char ***)); +int __db_util_cache __P((DB *, u_int32_t *, int *)); +int __db_util_logset __P((const char *, char *)); +void __db_util_siginit __P((void)); +int __db_util_interrupted __P((void)); +void __db_util_sigresend __P((void)); +int __db_zero_fill __P((ENV *, DB_FH *)); +int __db_zero_extend __P((ENV *, DB_FH *, db_pgno_t, db_pgno_t, u_int32_t)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_common_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/crdel_auto.h b/src/libs/resiprocate/contrib/db/dbinc_auto/crdel_auto.h new file mode 100644 index 00000000..209dcb0b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/crdel_auto.h @@ -0,0 +1,46 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#ifndef __crdel_AUTO_H +#define __crdel_AUTO_H +#define DB___crdel_metasub 142 +typedef struct ___crdel_metasub_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DBT page; + DB_LSN lsn; +} __crdel_metasub_args; + +#define DB___crdel_inmem_create 138 +typedef struct ___crdel_inmem_create_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + DBT name; + DBT fid; + u_int32_t pgsize; +} __crdel_inmem_create_args; + +#define DB___crdel_inmem_rename 139 +typedef struct ___crdel_inmem_rename_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DBT oldname; + DBT newname; + DBT fid; +} __crdel_inmem_rename_args; + +#define DB___crdel_inmem_remove 140 +typedef struct ___crdel_inmem_remove_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DBT name; + DBT fid; +} __crdel_inmem_remove_args; + +#endif diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/crypto_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/crypto_ext.h new file mode 100644 index 00000000..cd7113d7 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/crypto_ext.h @@ -0,0 +1,38 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _crypto_ext_h_ +#define _crypto_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __aes_setup __P((ENV *, DB_CIPHER *)); +u_int __aes_adj_size __P((size_t)); +int __aes_close __P((ENV *, void *)); +int __aes_decrypt __P((ENV *, void *, void *, u_int8_t *, size_t)); +int __aes_encrypt __P((ENV *, void *, void *, u_int8_t *, size_t)); +int __aes_init __P((ENV *, DB_CIPHER *)); +int __crypto_env_close __P((ENV *)); +int __crypto_env_refresh __P((ENV *)); +int __crypto_algsetup __P((ENV *, DB_CIPHER *, u_int32_t, int)); +int __crypto_decrypt_meta __P((ENV *, DB *, u_int8_t *, int)); +int __crypto_set_passwd __P((ENV *, ENV *)); +int __db_generate_iv __P((ENV *, u_int32_t *)); +int __db_rijndaelKeySetupEnc __P((u32 *, const u8 *, int)); +int __db_rijndaelKeySetupDec __P((u32 *, const u8 *, int)); +void __db_rijndaelEncrypt __P((u32 *, int, const u8 *, u8 *)); +void __db_rijndaelDecrypt __P((u32 *, int, const u8 *, u8 *)); +void __db_rijndaelEncryptRound __P((const u32 *, int, u8 *, int)); +void __db_rijndaelDecryptRound __P((const u32 *, int, u8 *, int)); +int __db_makeKey __P((keyInstance *, int, int, char *)); +int __db_cipherInit __P((cipherInstance *, int, char *)); +int __db_blockEncrypt __P((cipherInstance *, keyInstance *, u_int8_t *, size_t, u_int8_t *)); +int __db_padEncrypt __P((cipherInstance *, keyInstance *, u_int8_t *, int, u_int8_t *)); +int __db_blockDecrypt __P((cipherInstance *, keyInstance *, u_int8_t *, size_t, u_int8_t *)); +int __db_padDecrypt __P((cipherInstance *, keyInstance *, u_int8_t *, int, u_int8_t *)); +int __db_cipherUpdateRounds __P((cipherInstance *, keyInstance *, u_int8_t *, int, u_int8_t *, int)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_crypto_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/db_auto.h b/src/libs/resiprocate/contrib/db/dbinc_auto/db_auto.h new file mode 100644 index 00000000..75d55c06 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/db_auto.h @@ -0,0 +1,216 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#ifndef __db_AUTO_H +#define __db_AUTO_H +#define DB___db_addrem 41 +typedef struct ___db_addrem_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t opcode; + int32_t fileid; + db_pgno_t pgno; + u_int32_t indx; + u_int32_t nbytes; + DBT hdr; + DBT dbt; + DB_LSN pagelsn; +} __db_addrem_args; + +#define DB___db_big 43 +typedef struct ___db_big_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t opcode; + int32_t fileid; + db_pgno_t pgno; + db_pgno_t prev_pgno; + db_pgno_t next_pgno; + DBT dbt; + DB_LSN pagelsn; + DB_LSN prevlsn; + DB_LSN nextlsn; +} __db_big_args; + +#define DB___db_ovref 44 +typedef struct ___db_ovref_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + int32_t adjust; + DB_LSN lsn; +} __db_ovref_args; + +#define DB___db_relink_42 45 +typedef struct ___db_relink_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t opcode; + int32_t fileid; + db_pgno_t pgno; + DB_LSN lsn; + db_pgno_t prev; + DB_LSN lsn_prev; + db_pgno_t next; + DB_LSN lsn_next; +} __db_relink_42_args; + +#define DB___db_debug 47 +typedef struct ___db_debug_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DBT op; + int32_t fileid; + DBT key; + DBT data; + u_int32_t arg_flags; +} __db_debug_args; + +#define DB___db_noop 48 +typedef struct ___db_noop_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN prevlsn; +} __db_noop_args; + +#define DB___db_pg_alloc_42 49 +typedef struct ___db_pg_alloc_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + DB_LSN meta_lsn; + db_pgno_t meta_pgno; + DB_LSN page_lsn; + db_pgno_t pgno; + u_int32_t ptype; + db_pgno_t next; +} __db_pg_alloc_42_args; + +#define DB___db_pg_alloc 49 +typedef struct ___db_pg_alloc_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + DB_LSN meta_lsn; + db_pgno_t meta_pgno; + DB_LSN page_lsn; + db_pgno_t pgno; + u_int32_t ptype; + db_pgno_t next; + db_pgno_t last_pgno; +} __db_pg_alloc_args; + +#define DB___db_pg_free_42 50 +typedef struct ___db_pg_free_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN meta_lsn; + db_pgno_t meta_pgno; + DBT header; + db_pgno_t next; +} __db_pg_free_42_args; + +#define DB___db_pg_free 50 +typedef struct ___db_pg_free_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN meta_lsn; + db_pgno_t meta_pgno; + DBT header; + db_pgno_t next; + db_pgno_t last_pgno; +} __db_pg_free_args; + +#define DB___db_cksum 51 +typedef struct ___db_cksum_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; +} __db_cksum_args; + +#define DB___db_pg_freedata_42 52 +typedef struct ___db_pg_freedata_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN meta_lsn; + db_pgno_t meta_pgno; + DBT header; + db_pgno_t next; + DBT data; +} __db_pg_freedata_42_args; + +#define DB___db_pg_freedata 52 +typedef struct ___db_pg_freedata_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN meta_lsn; + db_pgno_t meta_pgno; + DBT header; + db_pgno_t next; + db_pgno_t last_pgno; + DBT data; +} __db_pg_freedata_args; + +#define DB___db_pg_init 60 +typedef struct ___db_pg_init_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DBT header; + DBT data; +} __db_pg_init_args; + +#define DB___db_pg_sort_44 61 +typedef struct ___db_pg_sort_44_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t meta; + DB_LSN meta_lsn; + db_pgno_t last_free; + DB_LSN last_lsn; + db_pgno_t last_pgno; + DBT list; +} __db_pg_sort_44_args; + +#define DB___db_pg_trunc 66 +typedef struct ___db_pg_trunc_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t meta; + DB_LSN meta_lsn; + db_pgno_t last_free; + DB_LSN last_lsn; + db_pgno_t next_free; + db_pgno_t last_pgno; + DBT list; +} __db_pg_trunc_args; + +#endif diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/db_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/db_ext.h new file mode 100644 index 00000000..5fb388f8 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/db_ext.h @@ -0,0 +1,343 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _db_ext_h_ +#define _db_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __crdel_metasub_read __P((ENV *, DB **, void *, void *, __crdel_metasub_args **)); +int __crdel_metasub_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, const DBT *, DB_LSN *)); +int __crdel_inmem_create_read __P((ENV *, void *, __crdel_inmem_create_args **)); +int __crdel_inmem_create_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, int32_t, const DBT *, const DBT *, u_int32_t)); +int __crdel_inmem_rename_read __P((ENV *, void *, __crdel_inmem_rename_args **)); +int __crdel_inmem_rename_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, const DBT *, const DBT *, const DBT *)); +int __crdel_inmem_remove_read __P((ENV *, void *, __crdel_inmem_remove_args **)); +int __crdel_inmem_remove_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, const DBT *, const DBT *)); +int __crdel_init_recover __P((ENV *, DB_DISTAB *)); +int __crdel_metasub_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __crdel_inmem_create_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __crdel_inmem_rename_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __crdel_inmem_remove_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __crdel_init_print __P((ENV *, DB_DISTAB *)); +int __crdel_metasub_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __crdel_inmem_create_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __crdel_inmem_rename_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __crdel_inmem_remove_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_master_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, u_int32_t, int, DB **)); +int __db_master_update __P((DB *, DB *, DB_THREAD_INFO *, DB_TXN *, const char *, DBTYPE, mu_action, const char *, u_int32_t)); +int __env_setup __P((DB *, DB_TXN *, const char *, const char *, u_int32_t, u_int32_t)); +int __env_mpool __P((DB *, const char *, u_int32_t)); +int __db_close __P((DB *, DB_TXN *, u_int32_t)); +int __db_refresh __P((DB *, DB_TXN *, u_int32_t, int *, int)); +int __db_log_page __P((DB *, DB_TXN *, DB_LSN *, db_pgno_t, PAGE *)); +int __db_backup_name __P((ENV *, const char *, DB_TXN *, char **)); +#ifdef CONFIG_TEST +int __db_testcopy __P((ENV *, DB *, const char *)); +#endif +int __db_testdocopy __P((ENV *, const char *)); +int __db_cursor_int __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBTYPE, db_pgno_t, int, DB_LOCKER *, DBC **)); +int __db_put __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, u_int32_t)); +int __db_del __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBT *, u_int32_t)); +int __db_sync __P((DB *)); +int __db_associate __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB *, int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); +int __db_secondary_close __P((DB *, u_int32_t)); +int __db_associate_foreign __P((DB *, DB *, int (*)(DB *, const DBT *, DBT *, const DBT *, int *), u_int32_t)); +int __db_addrem_read __P((ENV *, DB **, void *, void *, __db_addrem_args **)); +int __db_addrem_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, db_pgno_t, u_int32_t, u_int32_t, const DBT *, const DBT *, DB_LSN *)); +int __db_big_read __P((ENV *, DB **, void *, void *, __db_big_args **)); +int __db_big_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, db_pgno_t, db_pgno_t, db_pgno_t, const DBT *, DB_LSN *, DB_LSN *, DB_LSN *)); +int __db_ovref_read __P((ENV *, DB **, void *, void *, __db_ovref_args **)); +int __db_ovref_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, int32_t, DB_LSN *)); +int __db_relink_42_read __P((ENV *, DB **, void *, void *, __db_relink_42_args **)); +int __db_debug_read __P((ENV *, void *, __db_debug_args **)); +int __db_debug_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, const DBT *, int32_t, const DBT *, const DBT *, u_int32_t)); +int __db_noop_read __P((ENV *, DB **, void *, void *, __db_noop_args **)); +int __db_noop_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *)); +int __db_pg_alloc_42_read __P((ENV *, DB **, void *, void *, __db_pg_alloc_42_args **)); +int __db_pg_alloc_read __P((ENV *, DB **, void *, void *, __db_pg_alloc_args **)); +int __db_pg_alloc_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, u_int32_t, db_pgno_t, db_pgno_t)); +int __db_pg_free_42_read __P((ENV *, DB **, void *, void *, __db_pg_free_42_args **)); +int __db_pg_free_read __P((ENV *, DB **, void *, void *, __db_pg_free_args **)); +int __db_pg_free_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, const DBT *, db_pgno_t, db_pgno_t)); +int __db_cksum_read __P((ENV *, void *, __db_cksum_args **)); +int __db_cksum_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t)); +int __db_pg_freedata_42_read __P((ENV *, DB **, void *, void *, __db_pg_freedata_42_args **)); +int __db_pg_freedata_read __P((ENV *, DB **, void *, void *, __db_pg_freedata_args **)); +int __db_pg_freedata_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, const DBT *, db_pgno_t, db_pgno_t, const DBT *)); +int __db_pg_init_read __P((ENV *, DB **, void *, void *, __db_pg_init_args **)); +int __db_pg_init_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, const DBT *, const DBT *)); +int __db_pg_sort_44_read __P((ENV *, DB **, void *, void *, __db_pg_sort_44_args **)); +int __db_pg_trunc_read __P((ENV *, DB **, void *, void *, __db_pg_trunc_args **)); +int __db_pg_trunc_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, db_pgno_t, const DBT *)); +int __db_init_recover __P((ENV *, DB_DISTAB *)); +int __db_addrem_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_big_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_ovref_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_relink_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_debug_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_noop_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_alloc_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_alloc_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_free_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_free_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_cksum_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_freedata_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_freedata_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_init_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_sort_44_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_trunc_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_init_print __P((ENV *, DB_DISTAB *)); +int __dbc_close __P((DBC *)); +int __dbc_destroy __P((DBC *)); +int __dbc_cmp __P((DBC *, DBC *, int *)); +int __dbc_count __P((DBC *, db_recno_t *)); +int __dbc_del __P((DBC *, u_int32_t)); +int __dbc_idel __P((DBC *, u_int32_t)); +#ifdef HAVE_COMPRESSION +int __dbc_bulk_del __P((DBC *, DBT *, u_int32_t)); +#endif +int __dbc_dup __P((DBC *, DBC **, u_int32_t)); +int __dbc_idup __P((DBC *, DBC **, u_int32_t)); +int __dbc_newopd __P((DBC *, db_pgno_t, DBC *, DBC **)); +int __dbc_get __P((DBC *, DBT *, DBT *, u_int32_t)); +int __dbc_iget __P((DBC *, DBT *, DBT *, u_int32_t)); +int __dbc_put __P((DBC *, DBT *, DBT *, u_int32_t)); +int __dbc_iput __P((DBC *, DBT *, DBT *, u_int32_t)); +int __db_duperr __P((DB *, u_int32_t)); +int __dbc_cleanup __P((DBC *, DBC *, int)); +int __dbc_secondary_get_pp __P((DBC *, DBT *, DBT *, u_int32_t)); +int __dbc_pget __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); +int __dbc_del_primary __P((DBC *)); +int __db_s_first __P((DB *, DB **)); +int __db_s_next __P((DB **, DB_TXN *)); +int __db_s_done __P((DB *, DB_TXN *)); +int __db_buildpartial __P((DB *, DBT *, DBT *, DBT *)); +u_int32_t __db_partsize __P((u_int32_t, DBT *)); +#ifdef DIAGNOSTIC +void __db_check_skeyset __P((DB *, DBT *)); +#endif +int __cdsgroup_begin __P((DB_ENV *, DB_TXN **)); +int __db_pgin __P((DB_ENV *, db_pgno_t, void *, DBT *)); +int __db_pgout __P((DB_ENV *, db_pgno_t, void *, DBT *)); +int __db_decrypt_pg __P((ENV *, DB *, PAGE *)); +int __db_encrypt_and_checksum_pg __P((ENV *, DB *, PAGE *)); +void __db_metaswap __P((PAGE *)); +int __db_byteswap __P((DB *, db_pgno_t, PAGE *, size_t, int)); +int __db_pageswap __P((DB *, void *, size_t, DBT *, int)); +int __db_dispatch __P((ENV *, DB_DISTAB *, DBT *, DB_LSN *, db_recops, DB_TXNHEAD *)); +int __db_add_recovery __P((DB_ENV *, DB_DISTAB *, int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops), u_int32_t)); +int __db_add_recovery_int __P((ENV *, DB_DISTAB *, int (*)(ENV *, DBT *, DB_LSN *, db_recops, void *), u_int32_t)); +int __db_txnlist_init __P((ENV *, DB_THREAD_INFO *, u_int32_t, u_int32_t, DB_LSN *, DB_TXNHEAD **)); +int __db_txnlist_add __P((ENV *, DB_TXNHEAD *, u_int32_t, u_int32_t, DB_LSN *)); +int __db_txnlist_remove __P((ENV *, DB_TXNHEAD *, u_int32_t)); +void __db_txnlist_ckp __P((ENV *, DB_TXNHEAD *, DB_LSN *)); +void __db_txnlist_end __P((ENV *, DB_TXNHEAD *)); +int __db_txnlist_find __P((ENV *, DB_TXNHEAD *, u_int32_t, u_int32_t *)); +int __db_txnlist_update __P((ENV *, DB_TXNHEAD *, u_int32_t, u_int32_t, DB_LSN *, u_int32_t *, int)); +int __db_txnlist_gen __P((ENV *, DB_TXNHEAD *, int, u_int32_t, u_int32_t)); +int __db_txnlist_lsnadd __P((ENV *, DB_TXNHEAD *, DB_LSN *)); +int __db_txnlist_lsnget __P((ENV *, DB_TXNHEAD *, DB_LSN *, u_int32_t)); +int __db_txnlist_lsninit __P((ENV *, DB_TXNHEAD *, DB_LSN *)); +void __db_txnlist_print __P((DB_TXNHEAD *)); +int __db_ditem_nolog __P((DBC *, PAGE *, u_int32_t, u_int32_t)); +int __db_ditem __P((DBC *, PAGE *, u_int32_t, u_int32_t)); +int __db_pitem_nolog __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *)); +int __db_pitem __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *)); +int __db_associate_pp __P((DB *, DB_TXN *, DB *, int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); +int __db_close_pp __P((DB *, u_int32_t)); +int __db_cursor_pp __P((DB *, DB_TXN *, DBC **, u_int32_t)); +int __db_cursor __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBC **, u_int32_t)); +int __db_del_pp __P((DB *, DB_TXN *, DBT *, u_int32_t)); +int __db_exists __P((DB *, DB_TXN *, DBT *, u_int32_t)); +int __db_fd_pp __P((DB *, int *)); +int __db_get_pp __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); +int __db_get __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, u_int32_t)); +int __db_join_pp __P((DB *, DBC **, DBC **, u_int32_t)); +int __db_key_range_pp __P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t)); +int __db_open_pp __P((DB *, DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int)); +int __db_pget_pp __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t)); +int __db_pget __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t)); +int __db_put_pp __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); +int __db_compact_pp __P((DB *, DB_TXN *, DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *)); +int __db_associate_foreign_pp __P((DB *, DB *, int (*)(DB *, const DBT *, DBT *, const DBT *, int *), u_int32_t)); +int __db_sync_pp __P((DB *, u_int32_t)); +int __dbc_close_pp __P((DBC *)); +int __dbc_cmp_pp __P((DBC *, DBC *, int*, u_int32_t)); +int __dbc_count_pp __P((DBC *, db_recno_t *, u_int32_t)); +int __dbc_del_pp __P((DBC *, u_int32_t)); +int __dbc_dup_pp __P((DBC *, DBC **, u_int32_t)); +int __dbc_get_pp __P((DBC *, DBT *, DBT *, u_int32_t)); +int __dbc_get_arg __P((DBC *, DBT *, DBT *, u_int32_t)); +int __db_secondary_close_pp __P((DB *, u_int32_t)); +int __dbc_pget_pp __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); +int __dbc_put_pp __P((DBC *, DBT *, DBT *, u_int32_t)); +int __db_txn_auto_init __P((ENV *, DB_THREAD_INFO *, DB_TXN **)); +int __db_txn_auto_resolve __P((ENV *, DB_TXN *, int, int)); +int __db_join __P((DB *, DBC **, DBC **, u_int32_t)); +int __db_join_close __P((DBC *)); +int __db_secondary_corrupt __P((DB *)); +int __db_new __P((DBC *, u_int32_t, DB_LOCK *, PAGE **)); +int __db_free __P((DBC *, PAGE *)); +#ifdef HAVE_FTRUNCATE +void __db_freelist_pos __P((db_pgno_t, db_pgno_t *, u_int32_t, u_int32_t *)); +#endif +void __db_freelist_sort __P((db_pglist_t *, u_int32_t)); +#ifdef HAVE_FTRUNCATE +int __db_pg_truncate __P((DBC *, DB_TXN *, db_pglist_t *, DB_COMPACT *, u_int32_t *, db_pgno_t , db_pgno_t *, DB_LSN *, int)); +#endif +#ifdef HAVE_FTRUNCATE +int __db_free_truncate __P((DB *, DB_THREAD_INFO *, DB_TXN *, u_int32_t, DB_COMPACT *, db_pglist_t **, u_int32_t *, db_pgno_t *)); +#endif +int __db_lprint __P((DBC *)); +int __db_lget __P((DBC *, int, db_pgno_t, db_lockmode_t, u_int32_t, DB_LOCK *)); +int __db_lput __P((DBC *, DB_LOCK *)); +int __db_create_internal __P((DB **, ENV *, u_int32_t)); +int __dbh_am_chk __P((DB *, u_int32_t)); +int __db_get_flags __P((DB *, u_int32_t *)); +int __db_set_flags __P((DB *, u_int32_t)); +int __db_get_lorder __P((DB *, int *)); +int __db_set_lorder __P((DB *, int)); +int __db_set_pagesize __P((DB *, u_int32_t)); +int __db_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int, db_pgno_t)); +int __db_get_open_flags __P((DB *, u_int32_t *)); +int __db_new_file __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *)); +int __db_init_subdb __P((DB *, DB *, const char *, DB_THREAD_INFO *, DB_TXN *)); +int __db_chk_meta __P((ENV *, DB *, DBMETA *, u_int32_t)); +int __db_meta_setup __P((ENV *, DB *, const char *, DBMETA *, u_int32_t, u_int32_t)); +int __db_goff __P((DBC *, DBT *, u_int32_t, db_pgno_t, void **, u_int32_t *)); +int __db_poff __P((DBC *, const DBT *, db_pgno_t *)); +int __db_ovref __P((DBC *, db_pgno_t)); +int __db_doff __P((DBC *, db_pgno_t)); +int __db_moff __P((DBC *, const DBT *, db_pgno_t, u_int32_t, int (*)(DB *, const DBT *, const DBT *), int *)); +int __db_coff __P((DBC *, const DBT *, const DBT *, int (*)(DB *, const DBT *, const DBT *), int *)); +int __db_vrfy_overflow __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); +int __db_vrfy_ovfl_structure __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, u_int32_t)); +int __db_safe_goff __P((DB *, VRFY_DBINFO *, db_pgno_t, DBT *, void *, u_int32_t *, u_int32_t)); +void __db_loadme __P((void)); +int __db_dumptree __P((DB *, DB_TXN *, char *, char *)); +const FN * __db_get_flags_fn __P((void)); +int __db_prnpage __P((DB *, DB_TXN *, db_pgno_t)); +int __db_prpage __P((DB *, PAGE *, u_int32_t)); +void __db_prbytes __P((ENV *, DB_MSGBUF *, u_int8_t *, u_int32_t)); +void __db_prflags __P((ENV *, DB_MSGBUF *, u_int32_t, const FN *, const char *, const char *)); +const char * __db_lockmode_to_string __P((db_lockmode_t)); +int __db_dumptree __P((DB *, DB_TXN *, char *, char *)); +const FN * __db_get_flags_fn __P((void)); +int __db_dump_pp __P((DB *, const char *, int (*)(void *, const void *), void *, int, int)); +int __db_dump __P((DB *, const char *, int (*)(void *, const void *), void *, int, int)); +int __db_prdbt __P((DBT *, int, const char *, void *, int (*)(void *, const void *), int)); +int __db_prheader __P((DB *, const char *, int, int, void *, int (*)(void *, const void *), VRFY_DBINFO *, db_pgno_t)); +int __db_prfooter __P((void *, int (*)(void *, const void *))); +int __db_pr_callback __P((void *, const void *)); +const char * __db_dbtype_to_string __P((DBTYPE)); +int __db_addrem_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_big_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_ovref_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_debug_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_noop_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_alloc_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_free_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_freedata_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_cksum_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_init_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_trunc_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_sort_44_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_alloc_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_free_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_pg_freedata_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_relink_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __db_traverse_big __P((DBC *, db_pgno_t, int (*)(DBC *, PAGE *, void *, int *), void *)); +int __db_reclaim_callback __P((DBC *, PAGE *, void *, int *)); +int __db_truncate_callback __P((DBC *, PAGE *, void *, int *)); +int __env_dbremove_pp __P((DB_ENV *, DB_TXN *, const char *, const char *, u_int32_t)); +int __db_remove_pp __P((DB *, const char *, const char *, u_int32_t)); +int __db_remove __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, u_int32_t)); +int __db_remove_int __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, u_int32_t)); +int __db_inmem_remove __P((DB *, DB_TXN *, const char *)); +int __env_dbrename_pp __P((DB_ENV *, DB_TXN *, const char *, const char *, const char *, u_int32_t)); +int __db_rename_pp __P((DB *, const char *, const char *, const char *, u_int32_t)); +int __db_rename_int __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, const char *)); +int __db_ret __P((DBC *, PAGE *, u_int32_t, DBT *, void **, u_int32_t *)); +int __db_retcopy __P((ENV *, DBT *, void *, u_int32_t, void **, u_int32_t *)); +int __env_fileid_reset_pp __P((DB_ENV *, const char *, u_int32_t)); +int __env_fileid_reset __P((ENV *, DB_THREAD_INFO *, const char *, int)); +int __env_lsn_reset_pp __P((DB_ENV *, const char *, u_int32_t)); +int __db_lsn_reset __P((DB_MPOOLFILE *, DB_THREAD_INFO *)); +int __db_compare_both __P((DB *, const DBT *, const DBT *, const DBT *, const DBT *)); +int __db_sort_multiple __P((DB *, DBT *, DBT *, u_int32_t)); +int __db_stat_pp __P((DB *, DB_TXN *, void *, u_int32_t)); +int __db_stat_print_pp __P((DB *, u_int32_t)); +int __db_stat_print __P((DB *, DB_THREAD_INFO *, u_int32_t)); +int __db_truncate_pp __P((DB *, DB_TXN *, u_int32_t *, u_int32_t)); +int __db_truncate __P((DB *, DB_THREAD_INFO *, DB_TXN *, u_int32_t *)); +int __db_upgrade_pp __P((DB *, const char *, u_int32_t)); +int __db_upgrade __P((DB *, const char *, u_int32_t)); +int __db_lastpgno __P((DB *, char *, DB_FH *, db_pgno_t *)); +int __db_31_offdup __P((DB *, char *, DB_FH *, int, db_pgno_t *)); +int __db_verify_pp __P((DB *, const char *, const char *, FILE *, u_int32_t)); +int __db_verify_internal __P((DB *, const char *, const char *, void *, int (*)(void *, const void *), u_int32_t)); +int __db_verify __P((DB *, DB_THREAD_INFO *, const char *, const char *, void *, int (*)(void *, const void *), void *, void *, u_int32_t)); +int __db_vrfy_common __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); +int __db_vrfy_datapage __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); +int __db_vrfy_meta __P((DB *, VRFY_DBINFO *, DBMETA *, db_pgno_t, u_int32_t)); +void __db_vrfy_struct_feedback __P((DB *, VRFY_DBINFO *)); +int __db_salvage_pg __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *, void *, int (*)(void *, const void *), u_int32_t)); +int __db_salvage_leaf __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *, void *, int (*)(void *, const void *), u_int32_t)); +int __db_vrfy_inpitem __P((DB *, PAGE *, db_pgno_t, u_int32_t, int, u_int32_t, u_int32_t *, u_int32_t *)); +int __db_vrfy_duptype __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t)); +int __db_salvage_duptree __P((DB *, VRFY_DBINFO *, db_pgno_t, DBT *, void *, int (*)(void *, const void *), u_int32_t)); +int __db_vrfy_dbinfo_create __P((ENV *, DB_THREAD_INFO *, u_int32_t, VRFY_DBINFO **)); +int __db_vrfy_dbinfo_destroy __P((ENV *, VRFY_DBINFO *)); +int __db_vrfy_getpageinfo __P((VRFY_DBINFO *, db_pgno_t, VRFY_PAGEINFO **)); +int __db_vrfy_putpageinfo __P((ENV *, VRFY_DBINFO *, VRFY_PAGEINFO *)); +int __db_vrfy_pgset __P((ENV *, DB_THREAD_INFO *, u_int32_t, DB **)); +int __db_vrfy_pgset_get __P((DB *, DB_THREAD_INFO *, db_pgno_t, int *)); +int __db_vrfy_pgset_inc __P((DB *, DB_THREAD_INFO *, db_pgno_t)); +int __db_vrfy_pgset_next __P((DBC *, db_pgno_t *)); +int __db_vrfy_childcursor __P((VRFY_DBINFO *, DBC **)); +int __db_vrfy_childput __P((VRFY_DBINFO *, db_pgno_t, VRFY_CHILDINFO *)); +int __db_vrfy_ccset __P((DBC *, db_pgno_t, VRFY_CHILDINFO **)); +int __db_vrfy_ccnext __P((DBC *, VRFY_CHILDINFO **)); +int __db_vrfy_ccclose __P((DBC *)); +int __db_salvage_init __P((VRFY_DBINFO *)); +int __db_salvage_destroy __P((VRFY_DBINFO *)); +int __db_salvage_getnext __P((VRFY_DBINFO *, DBC **, db_pgno_t *, u_int32_t *, int)); +int __db_salvage_isdone __P((VRFY_DBINFO *, db_pgno_t)); +int __db_salvage_markdone __P((VRFY_DBINFO *, db_pgno_t)); +int __db_salvage_markneeded __P((VRFY_DBINFO *, db_pgno_t, u_int32_t)); +int __db_vrfy_prdbt __P((DBT *, int, const char *, void *, int (*)(void *, const void *), int, VRFY_DBINFO *)); +int __partition_init __P((DB *, u_int32_t)); +int __partition_set __P((DB *, u_int32_t, DBT *, u_int32_t (*callback)(DB *, DBT *key))); +int __partition_set_dirs __P((DB *, const char **)); +int __partition_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, DBTYPE, u_int32_t, int, int)); +int __partition_get_callback __P((DB *, u_int32_t *, u_int32_t (**callback)(DB *, DBT *key))); +int __partition_get_keys __P((DB *, u_int32_t *, DBT **)); +int __partition_get_dirs __P((DB *, const char ***)); +int __partc_init __P((DBC *)); +int __partc_get __P((DBC*, DBT *, DBT *, u_int32_t)); +int __partition_close __P((DB *, DB_TXN *, u_int32_t)); +int __partition_sync __P((DB *)); +int __partition_stat __P((DBC *, void *, u_int32_t)); +int __part_truncate __P((DBC *, u_int32_t *)); +int __part_compact __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *)); +int __part_lsn_reset __P((DB *, DB_THREAD_INFO *)); +int __part_fileid_reset __P((ENV *, DB_THREAD_INFO *, const char *, u_int32_t, int)); +int __part_key_range __P((DBC *, DBT *, DB_KEY_RANGE *, u_int32_t)); +int __part_remove __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, u_int32_t)); +int __part_rename __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, const char *)); +int __part_verify __P((DB *, VRFY_DBINFO *, const char *, void *, int (*)(void *, const void *), u_int32_t)); +int __part_testdocopy __P((DB *, const char *)); +int __db_no_partition __P((ENV *)); +int __partition_set __P((DB *, u_int32_t, DBT *, u_int32_t (*callback)(DB *, DBT *key))); +int __partition_get_callback __P((DB *, u_int32_t *, u_int32_t (**callback)(DB *, DBT *key))); +int __partition_get_dirs __P((DB *, const char ***)); +int __partition_get_keys __P((DB *, u_int32_t *, DBT **)); +int __partition_init __P((DB *, u_int32_t)); +int __part_fileid_reset __P((ENV *, DB_THREAD_INFO *, const char *, u_int32_t, int)); +int __partition_set_dirs __P((DB *, const char **)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_db_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/dbreg_auto.h b/src/libs/resiprocate/contrib/db/dbinc_auto/dbreg_auto.h new file mode 100644 index 00000000..a9722d0e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/dbreg_auto.h @@ -0,0 +1,19 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#ifndef __dbreg_AUTO_H +#define __dbreg_AUTO_H +#define DB___dbreg_register 2 +typedef struct ___dbreg_register_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t opcode; + DBT name; + DBT uid; + int32_t fileid; + DBTYPE ftype; + db_pgno_t meta_pgno; + u_int32_t id; +} __dbreg_register_args; + +#endif diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/dbreg_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/dbreg_ext.h new file mode 100644 index 00000000..1480da31 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/dbreg_ext.h @@ -0,0 +1,47 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _dbreg_ext_h_ +#define _dbreg_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __dbreg_setup __P((DB *, const char *, const char *, u_int32_t)); +int __dbreg_teardown __P((DB *)); +int __dbreg_teardown_int __P((ENV *, FNAME *)); +int __dbreg_new_id __P((DB *, DB_TXN *)); +int __dbreg_get_id __P((DB *, DB_TXN *, int32_t *)); +int __dbreg_assign_id __P((DB *, int32_t, int)); +int __dbreg_revoke_id __P((DB *, int, int32_t)); +int __dbreg_revoke_id_int __P((ENV *, FNAME *, int, int, int32_t)); +int __dbreg_close_id __P((DB *, DB_TXN *, u_int32_t)); +int __dbreg_close_id_int __P((ENV *, FNAME *, u_int32_t, int)); +int __dbreg_failchk __P((ENV *)); +int __dbreg_log_close __P((ENV *, FNAME *, DB_TXN *, u_int32_t)); +int __dbreg_log_id __P((DB *, DB_TXN *, int32_t, int)); +int __dbreg_register_read __P((ENV *, void *, __dbreg_register_args **)); +int __dbreg_register_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, const DBT *, const DBT *, int32_t, DBTYPE, db_pgno_t, u_int32_t)); +int __dbreg_init_recover __P((ENV *, DB_DISTAB *)); +int __dbreg_register_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __dbreg_init_print __P((ENV *, DB_DISTAB *)); +int __dbreg_register_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __dbreg_stat_print __P((ENV *, u_int32_t)); +void __dbreg_print_fname __P((ENV *, FNAME *)); +int __dbreg_add_dbentry __P((ENV *, DB_LOG *, DB *, int32_t)); +int __dbreg_rem_dbentry __P((DB_LOG *, int32_t)); +int __dbreg_log_files __P((ENV *, u_int32_t)); +int __dbreg_close_files __P((ENV *, int)); +int __dbreg_close_file __P((ENV *, FNAME *)); +int __dbreg_mark_restored __P((ENV *)); +int __dbreg_invalidate_files __P((ENV *, int)); +int __dbreg_id_to_db __P((ENV *, DB_TXN *, DB **, int32_t, int)); +int __dbreg_id_to_fname __P((DB_LOG *, int32_t, int, FNAME **)); +int __dbreg_fid_to_fname __P((DB_LOG *, u_int8_t *, int, FNAME **)); +int __dbreg_get_name __P((ENV *, u_int8_t *, char **, char **)); +int __dbreg_do_open __P((ENV *, DB_TXN *, DB_LOG *, u_int8_t *, char *, DBTYPE, int32_t, db_pgno_t, void *, u_int32_t, u_int32_t)); +int __dbreg_lazy_id __P((DB *)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_dbreg_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/env_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/env_ext.h new file mode 100644 index 00000000..873e173e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/env_ext.h @@ -0,0 +1,128 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _env_ext_h_ +#define _env_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +void __env_alloc_init __P((REGINFO *, size_t)); +size_t __env_alloc_overhead __P((void)); +size_t __env_alloc_size __P((size_t)); +int __env_alloc __P((REGINFO *, size_t, void *)); +void __env_alloc_free __P((REGINFO *, void *)); +void __env_alloc_print __P((REGINFO *, u_int32_t)); +int __env_read_db_config __P((ENV *)); +int __config_split __P((char *, char *[])); +int __env_failchk_pp __P((DB_ENV *, u_int32_t)); +int __env_failchk_int __P((DB_ENV *)); +int __env_thread_init __P((ENV *, int)); +void __env_thread_destroy __P((ENV *)); +int __env_set_state __P((ENV *, DB_THREAD_INFO **, DB_THREAD_STATE)); +char *__env_thread_id_string __P((DB_ENV *, pid_t, db_threadid_t, char *)); +int __db_file_extend __P((ENV *, DB_FH *, size_t)); +int __db_file_multi_write __P((ENV *, const char *)); +int __db_file_write __P((ENV *, DB_FH *, u_int32_t, u_int32_t, int)); +void __db_env_destroy __P((DB_ENV *)); +int __env_get_alloc __P((DB_ENV *, void *(**)(size_t), void *(**)(void *, size_t), void (**)(void *))); +int __env_set_alloc __P((DB_ENV *, void *(*)(size_t), void *(*)(void *, size_t), void (*)(void *))); +int __env_get_encrypt_flags __P((DB_ENV *, u_int32_t *)); +int __env_set_encrypt __P((DB_ENV *, const char *, u_int32_t)); +void __env_map_flags __P((const FLAG_MAP *, u_int, u_int32_t *, u_int32_t *)); +void __env_fetch_flags __P((const FLAG_MAP *, u_int, u_int32_t *, u_int32_t *)); +int __env_set_flags __P((DB_ENV *, u_int32_t, int)); +int __env_set_data_dir __P((DB_ENV *, const char *)); +int __env_add_data_dir __P((DB_ENV *, const char *)); +int __env_set_create_dir __P((DB_ENV *, const char *)); +int __env_set_intermediate_dir_mode __P((DB_ENV *, const char *)); +void __env_get_errcall __P((DB_ENV *, void (**)(const DB_ENV *, const char *, const char *))); +void __env_set_errcall __P((DB_ENV *, void (*)(const DB_ENV *, const char *, const char *))); +void __env_get_errfile __P((DB_ENV *, FILE **)); +void __env_set_errfile __P((DB_ENV *, FILE *)); +void __env_get_errpfx __P((DB_ENV *, const char **)); +void __env_set_errpfx __P((DB_ENV *, const char *)); +int __env_set_thread_count __P((DB_ENV *, u_int32_t)); +void __env_get_msgcall __P((DB_ENV *, void (**)(const DB_ENV *, const char *))); +void __env_set_msgcall __P((DB_ENV *, void (*)(const DB_ENV *, const char *))); +void __env_get_msgfile __P((DB_ENV *, FILE **)); +void __env_set_msgfile __P((DB_ENV *, FILE *)); +int __env_set_paniccall __P((DB_ENV *, void (*)(DB_ENV *, int))); +int __env_set_shm_key __P((DB_ENV *, long)); +int __env_set_tmp_dir __P((DB_ENV *, const char *)); +int __env_set_verbose __P((DB_ENV *, u_int32_t, int)); +int __db_mi_env __P((ENV *, const char *)); +int __db_mi_open __P((ENV *, const char *, int)); +int __env_not_config __P((ENV *, char *, u_int32_t)); +int __env_set_timeout __P((DB_ENV *, db_timeout_t, u_int32_t)); +int __db_appname __P((ENV *, APPNAME, const char *, const char **, char **)); +int __db_tmp_open __P((ENV *, u_int32_t, DB_FH **)); +int __env_open_pp __P((DB_ENV *, const char *, u_int32_t, int)); +int __env_open __P((DB_ENV *, const char *, u_int32_t, int)); +int __env_remove __P((DB_ENV *, const char *, u_int32_t)); +int __env_config __P((DB_ENV *, const char *, u_int32_t, int)); +int __env_close_pp __P((DB_ENV *, u_int32_t)); +int __env_close __P((DB_ENV *, int)); +int __env_refresh __P((DB_ENV *, u_int32_t, int)); +int __env_get_open_flags __P((DB_ENV *, u_int32_t *)); +int __env_attach_regions __P((DB_ENV *, u_int32_t, u_int32_t, int)); +int __db_apprec __P((ENV *, DB_THREAD_INFO *, DB_LSN *, DB_LSN *, int, u_int32_t)); +int __log_backup __P((ENV *, DB_LOGC *, DB_LSN *, DB_LSN *, u_int32_t)); +int __env_openfiles __P((ENV *, DB_LOGC *, void *, DBT *, DB_LSN *, DB_LSN *, double, int)); +int __env_init_rec __P((ENV *, u_int32_t)); +int __env_attach __P((ENV *, u_int32_t *, int, int)); +int __env_turn_on __P((ENV *)); +int __env_turn_off __P((ENV *, u_int32_t)); +void __env_panic_set __P((ENV *, int)); +int __env_ref_increment __P((ENV *)); +int __env_ref_decrement __P((ENV *)); +int __env_detach __P((ENV *, int)); +int __env_remove_env __P((ENV *)); +int __env_region_attach __P((ENV *, REGINFO *, size_t)); +int __env_region_detach __P((ENV *, REGINFO *, int)); +int __envreg_register __P((ENV *, int *, u_int32_t)); +int __envreg_unregister __P((ENV *, int)); +int __envreg_xunlock __P((ENV *)); +u_int32_t __env_struct_sig __P((void)); +int __env_stat_print_pp __P((DB_ENV *, u_int32_t)); +void __db_print_fh __P((ENV *, const char *, DB_FH *, u_int32_t)); +void __db_print_fileid __P((ENV *, u_int8_t *, const char *)); +void __db_dl __P((ENV *, const char *, u_long)); +void __db_dl_pct __P((ENV *, const char *, u_long, int, const char *)); +void __db_dlbytes __P((ENV *, const char *, u_long, u_long, u_long)); +void __db_print_reginfo __P((ENV *, REGINFO *, const char *, u_int32_t)); +int __db_stat_not_built __P((ENV *)); +#ifndef HAVE_REPLICATION_THREADS +int __repmgr_close __P((ENV *)); +#endif +#ifndef HAVE_REPLICATION_THREADS +int __repmgr_add_remote_site __P((DB_ENV *, const char *, u_int, int *, u_int32_t)); +#endif +#ifndef HAVE_REPLICATION_THREADS +int __repmgr_get_ack_policy __P((DB_ENV *, int *)); +#endif +#ifndef HAVE_REPLICATION_THREADS +int __repmgr_set_ack_policy __P((DB_ENV *, int)); +#endif +#ifndef HAVE_REPLICATION_THREADS +int __repmgr_set_local_site __P((DB_ENV *, const char *, u_int, u_int32_t)); +#endif +#ifndef HAVE_REPLICATION_THREADS +int __repmgr_site_list __P((DB_ENV *, u_int *, DB_REPMGR_SITE **)); +#endif +#ifndef HAVE_REPLICATION_THREADS +int __repmgr_start __P((DB_ENV *, int, u_int32_t)); +#endif +#ifndef HAVE_REPLICATION_THREADS +int __repmgr_stat_pp __P((DB_ENV *, DB_REPMGR_STAT **, u_int32_t)); +#endif +#ifndef HAVE_REPLICATION_THREADS +int __repmgr_stat_print_pp __P((DB_ENV *, u_int32_t)); +#endif +#ifndef HAVE_REPLICATION_THREADS +int __repmgr_handle_event __P((ENV *, u_int32_t, void *)); +#endif + +#if defined(__cplusplus) +} +#endif +#endif /* !_env_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/ext_185_def.in b/src/libs/resiprocate/contrib/db/dbinc_auto/ext_185_def.in new file mode 100644 index 00000000..8da68a8d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/ext_185_def.in @@ -0,0 +1,12 @@ + +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _DB_EXT_185_DEF_IN_ +#define _DB_EXT_185_DEF_IN_ + +#ifdef _DB185_INT_H_ +#define __db185_open __db185_open@DB_VERSION_UNIQUE_NAME@ +#else +#define __db185_open __db185_open@DB_VERSION_UNIQUE_NAME@ +#endif + +#endif /* !_DB_EXT_185_DEF_IN_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/ext_185_prot.in b/src/libs/resiprocate/contrib/db/dbinc_auto/ext_185_prot.in new file mode 100644 index 00000000..dfd8d3d4 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/ext_185_prot.in @@ -0,0 +1,19 @@ + +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _DB_EXT_185_PROT_IN_ +#define _DB_EXT_185_PROT_IN_ + +#if defined(__cplusplus) +extern "C" { +#endif + +#ifdef _DB185_INT_H_ +DB185 *__db185_open __P((const char *, int, int, DBTYPE, const void *)); +#else +DB *__db185_open __P((const char *, int, int, DBTYPE, const void *)); +#endif + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_EXT_185_PROT_IN_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/ext_def.in b/src/libs/resiprocate/contrib/db/dbinc_auto/ext_def.in new file mode 100644 index 00000000..ec56ce3e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/ext_def.in @@ -0,0 +1,60 @@ + +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _DB_EXT_DEF_IN_ +#define _DB_EXT_DEF_IN_ + +#define db_create db_create@DB_VERSION_UNIQUE_NAME@ +#define db_strerror db_strerror@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_close db_env_set_func_close@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_dirfree db_env_set_func_dirfree@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_dirlist db_env_set_func_dirlist@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_exists db_env_set_func_exists@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_free db_env_set_func_free@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_fsync db_env_set_func_fsync@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_ftruncate db_env_set_func_ftruncate@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_ioinfo db_env_set_func_ioinfo@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_malloc db_env_set_func_malloc@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_file_map db_env_set_func_file_map@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_region_map db_env_set_func_region_map@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_pread db_env_set_func_pread@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_pwrite db_env_set_func_pwrite@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_open db_env_set_func_open@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_read db_env_set_func_read@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_realloc db_env_set_func_realloc@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_rename db_env_set_func_rename@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_seek db_env_set_func_seek@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_unlink db_env_set_func_unlink@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_write db_env_set_func_write@DB_VERSION_UNIQUE_NAME@ +#define db_env_set_func_yield db_env_set_func_yield@DB_VERSION_UNIQUE_NAME@ +#define db_env_create db_env_create@DB_VERSION_UNIQUE_NAME@ +#define db_version db_version@DB_VERSION_UNIQUE_NAME@ +#define log_compare log_compare@DB_VERSION_UNIQUE_NAME@ +#define db_sequence_create db_sequence_create@DB_VERSION_UNIQUE_NAME@ +#if DB_DBM_HSEARCH != 0 +#define __db_ndbm_clearerr __db_ndbm_clearerr@DB_VERSION_UNIQUE_NAME@ +#define __db_ndbm_close __db_ndbm_close@DB_VERSION_UNIQUE_NAME@ +#define __db_ndbm_delete __db_ndbm_delete@DB_VERSION_UNIQUE_NAME@ +#define __db_ndbm_dirfno __db_ndbm_dirfno@DB_VERSION_UNIQUE_NAME@ +#define __db_ndbm_error __db_ndbm_error@DB_VERSION_UNIQUE_NAME@ +#define __db_ndbm_fetch __db_ndbm_fetch@DB_VERSION_UNIQUE_NAME@ +#define __db_ndbm_firstkey __db_ndbm_firstkey@DB_VERSION_UNIQUE_NAME@ +#define __db_ndbm_nextkey __db_ndbm_nextkey@DB_VERSION_UNIQUE_NAME@ +#define __db_ndbm_open __db_ndbm_open@DB_VERSION_UNIQUE_NAME@ +#define __db_ndbm_pagfno __db_ndbm_pagfno@DB_VERSION_UNIQUE_NAME@ +#define __db_ndbm_rdonly __db_ndbm_rdonly@DB_VERSION_UNIQUE_NAME@ +#define __db_ndbm_store __db_ndbm_store@DB_VERSION_UNIQUE_NAME@ +#define __db_dbm_close __db_dbm_close@DB_VERSION_UNIQUE_NAME@ +#define __db_dbm_delete __db_dbm_delete@DB_VERSION_UNIQUE_NAME@ +#define __db_dbm_fetch __db_dbm_fetch@DB_VERSION_UNIQUE_NAME@ +#define __db_dbm_firstkey __db_dbm_firstkey@DB_VERSION_UNIQUE_NAME@ +#define __db_dbm_init __db_dbm_init@DB_VERSION_UNIQUE_NAME@ +#define __db_dbm_nextkey __db_dbm_nextkey@DB_VERSION_UNIQUE_NAME@ +#define __db_dbm_store __db_dbm_store@DB_VERSION_UNIQUE_NAME@ +#endif +#if DB_DBM_HSEARCH != 0 +#define __db_hcreate __db_hcreate@DB_VERSION_UNIQUE_NAME@ +#define __db_hsearch __db_hsearch@DB_VERSION_UNIQUE_NAME@ +#define __db_hdestroy __db_hdestroy@DB_VERSION_UNIQUE_NAME@ +#endif + +#endif /* !_DB_EXT_DEF_IN_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/ext_prot.in b/src/libs/resiprocate/contrib/db/dbinc_auto/ext_prot.in new file mode 100644 index 00000000..5d4f9819 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/ext_prot.in @@ -0,0 +1,67 @@ + +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _DB_EXT_PROT_IN_ +#define _DB_EXT_PROT_IN_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int db_create __P((DB **, DB_ENV *, u_int32_t)); +char *db_strerror __P((int)); +int db_env_set_func_close __P((int (*)(int))); +int db_env_set_func_dirfree __P((void (*)(char **, int))); +int db_env_set_func_dirlist __P((int (*)(const char *, char ***, int *))); +int db_env_set_func_exists __P((int (*)(const char *, int *))); +int db_env_set_func_free __P((void (*)(void *))); +int db_env_set_func_fsync __P((int (*)(int))); +int db_env_set_func_ftruncate __P((int (*)(int, off_t))); +int db_env_set_func_ioinfo __P((int (*)(const char *, int, u_int32_t *, u_int32_t *, u_int32_t *))); +int db_env_set_func_malloc __P((void *(*)(size_t))); +int db_env_set_func_file_map __P((int (*)(DB_ENV *, char *, size_t, int, void **), int (*)(DB_ENV *, void *))); +int db_env_set_func_region_map __P((int (*)(DB_ENV *, char *, size_t, int *, void **), int (*)(DB_ENV *, void *))); +int db_env_set_func_pread __P((ssize_t (*)(int, void *, size_t, off_t))); +int db_env_set_func_pwrite __P((ssize_t (*)(int, const void *, size_t, off_t))); +int db_env_set_func_open __P((int (*)(const char *, int, ...))); +int db_env_set_func_read __P((ssize_t (*)(int, void *, size_t))); +int db_env_set_func_realloc __P((void *(*)(void *, size_t))); +int db_env_set_func_rename __P((int (*)(const char *, const char *))); +int db_env_set_func_seek __P((int (*)(int, off_t, int))); +int db_env_set_func_unlink __P((int (*)(const char *))); +int db_env_set_func_write __P((ssize_t (*)(int, const void *, size_t))); +int db_env_set_func_yield __P((int (*)(u_long, u_long))); +int db_env_create __P((DB_ENV **, u_int32_t)); +char *db_version __P((int *, int *, int *)); +int log_compare __P((const DB_LSN *, const DB_LSN *)); +int db_sequence_create __P((DB_SEQUENCE **, DB *, u_int32_t)); +#if DB_DBM_HSEARCH != 0 +int __db_ndbm_clearerr __P((DBM *)); +void __db_ndbm_close __P((DBM *)); +int __db_ndbm_delete __P((DBM *, datum)); +int __db_ndbm_dirfno __P((DBM *)); +int __db_ndbm_error __P((DBM *)); +datum __db_ndbm_fetch __P((DBM *, datum)); +datum __db_ndbm_firstkey __P((DBM *)); +datum __db_ndbm_nextkey __P((DBM *)); +DBM *__db_ndbm_open __P((const char *, int, int)); +int __db_ndbm_pagfno __P((DBM *)); +int __db_ndbm_rdonly __P((DBM *)); +int __db_ndbm_store __P((DBM *, datum, datum, int)); +int __db_dbm_close __P((void)); +int __db_dbm_delete __P((datum)); +datum __db_dbm_fetch __P((datum)); +datum __db_dbm_firstkey __P((void)); +int __db_dbm_init __P((char *)); +datum __db_dbm_nextkey __P((datum)); +int __db_dbm_store __P((datum, datum)); +#endif +#if DB_DBM_HSEARCH != 0 +int __db_hcreate __P((size_t)); +ENTRY *__db_hsearch __P((ENTRY, ACTION)); +void __db_hdestroy __P((void)); +#endif + +#if defined(__cplusplus) +} +#endif +#endif /* !_DB_EXT_PROT_IN_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/fileops_auto.h b/src/libs/resiprocate/contrib/db/dbinc_auto/fileops_auto.h new file mode 100644 index 00000000..5b3f4dd9 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/fileops_auto.h @@ -0,0 +1,102 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#ifndef __fop_AUTO_H +#define __fop_AUTO_H +#define DB___fop_create_42 143 +typedef struct ___fop_create_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DBT name; + u_int32_t appname; + u_int32_t mode; +} __fop_create_42_args; + +#define DB___fop_create 143 +typedef struct ___fop_create_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DBT name; + DBT dirname; + u_int32_t appname; + u_int32_t mode; +} __fop_create_args; + +#define DB___fop_remove 144 +typedef struct ___fop_remove_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DBT name; + DBT fid; + u_int32_t appname; +} __fop_remove_args; + +#define DB___fop_write_42 145 +typedef struct ___fop_write_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DBT name; + u_int32_t appname; + u_int32_t pgsize; + db_pgno_t pageno; + u_int32_t offset; + DBT page; + u_int32_t flag; +} __fop_write_42_args; + +#define DB___fop_write 145 +typedef struct ___fop_write_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DBT name; + DBT dirname; + u_int32_t appname; + u_int32_t pgsize; + db_pgno_t pageno; + u_int32_t offset; + DBT page; + u_int32_t flag; +} __fop_write_args; + +#define DB___fop_rename_42 146 +#define DB___fop_rename_noundo_46 150 +typedef struct ___fop_rename_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DBT oldname; + DBT newname; + DBT fileid; + u_int32_t appname; +} __fop_rename_42_args; + +#define DB___fop_rename 146 +#define DB___fop_rename_noundo 150 +typedef struct ___fop_rename_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DBT oldname; + DBT newname; + DBT dirname; + DBT fileid; + u_int32_t appname; +} __fop_rename_args; + +#define DB___fop_file_remove 141 +typedef struct ___fop_file_remove_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DBT real_fid; + DBT tmp_fid; + DBT name; + u_int32_t appname; + u_int32_t child; +} __fop_file_remove_args; + +#endif diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/fileops_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/fileops_ext.h new file mode 100644 index 00000000..697672f4 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/fileops_ext.h @@ -0,0 +1,59 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _fileops_ext_h_ +#define _fileops_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __fop_create_42_read __P((ENV *, void *, __fop_create_42_args **)); +int __fop_create_read __P((ENV *, void *, __fop_create_args **)); +int __fop_create_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, const DBT *, const DBT *, u_int32_t, u_int32_t)); +int __fop_remove_read __P((ENV *, void *, __fop_remove_args **)); +int __fop_remove_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, const DBT *, const DBT *, u_int32_t)); +int __fop_write_42_read __P((ENV *, void *, __fop_write_42_args **)); +int __fop_write_read __P((ENV *, void *, __fop_write_args **)); +int __fop_write_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, const DBT *, const DBT *, u_int32_t, u_int32_t, db_pgno_t, u_int32_t, const DBT *, u_int32_t)); +int __fop_rename_42_read __P((ENV *, void *, __fop_rename_42_args **)); +int __fop_rename_read __P((ENV *, void *, __fop_rename_args **)); +int __fop_rename_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, const DBT *, const DBT *, const DBT *, const DBT *, u_int32_t)); +int __fop_rename_noundo_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, const DBT *, const DBT *, const DBT *, const DBT *, u_int32_t)); +int __fop_rename_int_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, const DBT *, const DBT *, const DBT *, const DBT *, u_int32_t, u_int32_t)); +int __fop_file_remove_read __P((ENV *, void *, __fop_file_remove_args **)); +int __fop_file_remove_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, const DBT *, const DBT *, const DBT *, u_int32_t, u_int32_t)); +int __fop_init_recover __P((ENV *, DB_DISTAB *)); +int __fop_create_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_create_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_remove_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_write_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_write_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_rename_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_rename_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_file_remove_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_init_print __P((ENV *, DB_DISTAB *)); +int __fop_create __P((ENV *, DB_TXN *, DB_FH **, const char *, const char **, APPNAME, int, u_int32_t)); +int __fop_remove __P((ENV *, DB_TXN *, u_int8_t *, const char *, const char **, APPNAME, u_int32_t)); +int __fop_write __P((ENV *, DB_TXN *, const char *, const char *, APPNAME, DB_FH *, u_int32_t, db_pgno_t, u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t)); +int __fop_rename __P((ENV *, DB_TXN *, const char *, const char *, const char **, u_int8_t *, APPNAME, int, u_int32_t)); +int __fop_create_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_create_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_remove_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_write_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_write_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_rename_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_rename_noundo_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_rename_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_rename_noundo_46_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_file_remove_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __fop_lock_handle __P((ENV *, DB *, DB_LOCKER *, db_lockmode_t, DB_LOCK *, u_int32_t)); +int __fop_file_setup __P((DB *, DB_THREAD_INFO *ip, DB_TXN *, const char *, int, u_int32_t, u_int32_t *)); +int __fop_subdb_setup __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, int, u_int32_t)); +int __fop_remove_setup __P((DB *, DB_TXN *, const char *, u_int32_t)); +int __fop_read_meta __P((ENV *, const char *, u_int8_t *, size_t, DB_FH *, int, size_t *)); +int __fop_dummy __P((DB *, DB_TXN *, const char *, const char *)); +int __fop_dbrename __P((DB *, const char *, const char *)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_fileops_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/hash_auto.h b/src/libs/resiprocate/contrib/db/dbinc_auto/hash_auto.h new file mode 100644 index 00000000..8d9f93d0 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/hash_auto.h @@ -0,0 +1,162 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#ifndef __ham_AUTO_H +#define __ham_AUTO_H +#define DB___ham_insdel 21 +typedef struct ___ham_insdel_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t opcode; + int32_t fileid; + db_pgno_t pgno; + u_int32_t ndx; + DB_LSN pagelsn; + DBT key; + DBT data; +} __ham_insdel_args; + +#define DB___ham_newpage 22 +typedef struct ___ham_newpage_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t opcode; + int32_t fileid; + db_pgno_t prev_pgno; + DB_LSN prevlsn; + db_pgno_t new_pgno; + DB_LSN pagelsn; + db_pgno_t next_pgno; + DB_LSN nextlsn; +} __ham_newpage_args; + +#define DB___ham_splitdata 24 +typedef struct ___ham_splitdata_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + u_int32_t opcode; + db_pgno_t pgno; + DBT pageimage; + DB_LSN pagelsn; +} __ham_splitdata_args; + +#define DB___ham_replace 25 +typedef struct ___ham_replace_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + u_int32_t ndx; + DB_LSN pagelsn; + int32_t off; + DBT olditem; + DBT newitem; + u_int32_t makedup; +} __ham_replace_args; + +#define DB___ham_copypage 28 +typedef struct ___ham_copypage_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + DB_LSN pagelsn; + db_pgno_t next_pgno; + DB_LSN nextlsn; + db_pgno_t nnext_pgno; + DB_LSN nnextlsn; + DBT page; +} __ham_copypage_args; + +#define DB___ham_metagroup_42 29 +typedef struct ___ham_metagroup_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + u_int32_t bucket; + db_pgno_t mmpgno; + DB_LSN mmetalsn; + db_pgno_t mpgno; + DB_LSN metalsn; + db_pgno_t pgno; + DB_LSN pagelsn; + u_int32_t newalloc; +} __ham_metagroup_42_args; + +#define DB___ham_metagroup 29 +typedef struct ___ham_metagroup_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + u_int32_t bucket; + db_pgno_t mmpgno; + DB_LSN mmetalsn; + db_pgno_t mpgno; + DB_LSN metalsn; + db_pgno_t pgno; + DB_LSN pagelsn; + u_int32_t newalloc; + db_pgno_t last_pgno; +} __ham_metagroup_args; + +#define DB___ham_groupalloc_42 32 +typedef struct ___ham_groupalloc_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + DB_LSN meta_lsn; + db_pgno_t start_pgno; + u_int32_t num; + db_pgno_t free; +} __ham_groupalloc_42_args; + +#define DB___ham_groupalloc 32 +typedef struct ___ham_groupalloc_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + DB_LSN meta_lsn; + db_pgno_t start_pgno; + u_int32_t num; + db_pgno_t unused; + db_pgno_t last_pgno; +} __ham_groupalloc_args; + +#define DB___ham_curadj 33 +typedef struct ___ham_curadj_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_pgno_t pgno; + u_int32_t indx; + u_int32_t len; + u_int32_t dup_off; + int add; + int is_dup; + u_int32_t order; +} __ham_curadj_args; + +#define DB___ham_chgpg 34 +typedef struct ___ham_chgpg_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_ham_mode mode; + db_pgno_t old_pgno; + db_pgno_t new_pgno; + u_int32_t old_indx; + u_int32_t new_indx; +} __ham_chgpg_args; + +#endif diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/hash_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/hash_ext.h new file mode 100644 index 00000000..1728e4e8 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/hash_ext.h @@ -0,0 +1,134 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _hash_ext_h_ +#define _hash_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __ham_quick_delete __P((DBC *)); +int __hamc_init __P((DBC *)); +int __hamc_count __P((DBC *, db_recno_t *)); +int __hamc_cmp __P((DBC *, DBC *, int *)); +int __hamc_dup __P((DBC *, DBC *)); +u_int32_t __ham_call_hash __P((DBC *, u_int8_t *, u_int32_t)); +int __ham_overwrite __P((DBC *, DBT *, u_int32_t)); +int __ham_init_dbt __P((ENV *, DBT *, u_int32_t, void **, u_int32_t *)); +int __hamc_update __P((DBC *, u_int32_t, db_ham_curadj, int)); +int __ham_get_clist __P((DB *, db_pgno_t, u_int32_t, DBC ***)); +int __ham_insdel_read __P((ENV *, DB **, void *, void *, __ham_insdel_args **)); +int __ham_insdel_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, db_pgno_t, u_int32_t, DB_LSN *, const DBT *, const DBT *)); +int __ham_newpage_read __P((ENV *, DB **, void *, void *, __ham_newpage_args **)); +int __ham_newpage_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *)); +int __ham_splitdata_read __P((ENV *, DB **, void *, void *, __ham_splitdata_args **)); +int __ham_splitdata_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, db_pgno_t, const DBT *, DB_LSN *)); +int __ham_replace_read __P((ENV *, DB **, void *, void *, __ham_replace_args **)); +int __ham_replace_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, u_int32_t, DB_LSN *, int32_t, const DBT *, const DBT *, u_int32_t)); +int __ham_copypage_read __P((ENV *, DB **, void *, void *, __ham_copypage_args **)); +int __ham_copypage_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, const DBT *)); +int __ham_metagroup_42_read __P((ENV *, DB **, void *, void *, __ham_metagroup_42_args **)); +int __ham_metagroup_read __P((ENV *, DB **, void *, void *, __ham_metagroup_args **)); +int __ham_metagroup_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *, u_int32_t, db_pgno_t)); +int __ham_groupalloc_42_read __P((ENV *, DB **, void *, void *, __ham_groupalloc_42_args **)); +int __ham_groupalloc_read __P((ENV *, DB **, void *, void *, __ham_groupalloc_args **)); +int __ham_groupalloc_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, DB_LSN *, db_pgno_t, u_int32_t, db_pgno_t, db_pgno_t)); +int __ham_curadj_read __P((ENV *, DB **, void *, void *, __ham_curadj_args **)); +int __ham_curadj_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_pgno_t, u_int32_t, u_int32_t, u_int32_t, int, int, u_int32_t)); +int __ham_chgpg_read __P((ENV *, DB **, void *, void *, __ham_chgpg_args **)); +int __ham_chgpg_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_ham_mode, db_pgno_t, db_pgno_t, u_int32_t, u_int32_t)); +int __ham_init_recover __P((ENV *, DB_DISTAB *)); +int __ham_insdel_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_newpage_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_splitdata_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_replace_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_copypage_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_metagroup_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_metagroup_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_groupalloc_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_groupalloc_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_curadj_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_chgpg_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_init_print __P((ENV *, DB_DISTAB *)); +int __ham_pgin __P((DB *, db_pgno_t, void *, DBT *)); +int __ham_pgout __P((DB *, db_pgno_t, void *, DBT *)); +int __ham_mswap __P((ENV *, void *)); +int __ham_add_dup __P((DBC *, DBT *, u_int32_t, db_pgno_t *)); +int __ham_dup_convert __P((DBC *)); +int __ham_make_dup __P((ENV *, const DBT *, DBT *d, void **, u_int32_t *)); +void __ham_dsearch __P((DBC *, DBT *, u_int32_t *, int *, u_int32_t)); +u_int32_t __ham_func2 __P((DB *, const void *, u_int32_t)); +u_int32_t __ham_func3 __P((DB *, const void *, u_int32_t)); +u_int32_t __ham_func4 __P((DB *, const void *, u_int32_t)); +u_int32_t __ham_func5 __P((DB *, const void *, u_int32_t)); +u_int32_t __ham_test __P((DB *, const void *, u_int32_t)); +int __ham_get_meta __P((DBC *)); +int __ham_release_meta __P((DBC *)); +int __ham_dirty_meta __P((DBC *, u_int32_t)); +int __ham_return_meta __P((DBC *, u_int32_t, DBMETA **)); +int __ham_db_create __P((DB *)); +int __ham_db_close __P((DB *)); +int __ham_get_h_ffactor __P((DB *, u_int32_t *)); +int __ham_set_h_compare __P((DB *, int (*)(DB *, const DBT *, const DBT *))); +int __ham_get_h_nelem __P((DB *, u_int32_t *)); +void __ham_copy_config __P((DB *, DB*, u_int32_t)); +int __ham_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char * name, db_pgno_t, u_int32_t)); +int __ham_metachk __P((DB *, const char *, HMETA *)); +int __ham_new_file __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *)); +int __ham_new_subdb __P((DB *, DB *, DB_THREAD_INFO *, DB_TXN *)); +int __ham_item __P((DBC *, db_lockmode_t, db_pgno_t *)); +int __ham_item_reset __P((DBC *)); +int __ham_item_init __P((DBC *)); +int __ham_item_last __P((DBC *, db_lockmode_t, db_pgno_t *)); +int __ham_item_first __P((DBC *, db_lockmode_t, db_pgno_t *)); +int __ham_item_prev __P((DBC *, db_lockmode_t, db_pgno_t *)); +int __ham_item_next __P((DBC *, db_lockmode_t, db_pgno_t *)); +int __ham_insertpair __P((DBC *, PAGE *p, db_indx_t *indxp, const DBT *, const DBT *, int, int)); +int __ham_getindex __P((DBC *, PAGE *, const DBT *, int, int *, db_indx_t *)); +int __ham_verify_sorted_page __P((DBC *, PAGE *)); +int __ham_sort_page __P((DBC *, PAGE **, PAGE *)); +int __ham_del_pair __P((DBC *, int)); +int __ham_replpair __P((DBC *, DBT *, u_int32_t)); +void __ham_onpage_replace __P((DB *, PAGE *, u_int32_t, int32_t, u_int32_t, int, DBT *)); +int __ham_split_page __P((DBC *, u_int32_t, u_int32_t)); +int __ham_add_el __P((DBC *, const DBT *, const DBT *, int)); +int __ham_copypair __P((DBC *, PAGE *, u_int32_t, PAGE *, db_indx_t *)); +int __ham_add_ovflpage __P((DBC *, PAGE *, int, PAGE **)); +int __ham_get_cpage __P((DBC *, db_lockmode_t)); +int __ham_next_cpage __P((DBC *, db_pgno_t)); +int __ham_lock_bucket __P((DBC *, db_lockmode_t)); +void __ham_dpair __P((DB *, PAGE *, u_int32_t)); +int __ham_insdel_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_newpage_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_replace_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_splitdata_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_copypage_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_metagroup_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_groupalloc_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_curadj_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_chgpg_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_metagroup_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_groupalloc_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __ham_reclaim __P((DB *, DB_THREAD_INFO *, DB_TXN *txn)); +int __ham_truncate __P((DBC *, u_int32_t *)); +int __ham_stat __P((DBC *, void *, u_int32_t)); +int __ham_stat_print __P((DBC *, u_int32_t)); +void __ham_print_cursor __P((DBC *)); +int __ham_traverse __P((DBC *, db_lockmode_t, int (*)(DBC *, PAGE *, void *, int *), void *, int)); +int __db_no_hash_am __P((ENV *)); +int __ham_30_hashmeta __P((DB *, char *, u_int8_t *)); +int __ham_30_sizefix __P((DB *, DB_FH *, char *, u_int8_t *)); +int __ham_31_hashmeta __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); +int __ham_31_hash __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); +int __ham_46_hashmeta __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); +int __ham_46_hash __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); +int __ham_vrfy_meta __P((DB *, VRFY_DBINFO *, HMETA *, db_pgno_t, u_int32_t)); +int __ham_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); +int __ham_vrfy_structure __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t)); +int __ham_vrfy_hashing __P((DBC *, u_int32_t, HMETA *, u_int32_t, db_pgno_t, u_int32_t, u_int32_t (*) __P((DB *, const void *, u_int32_t)))); +int __ham_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *, void *, int (*)(void *, const void *), u_int32_t)); +int __ham_meta2pgset __P((DB *, VRFY_DBINFO *, HMETA *, u_int32_t, DB *)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_hash_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/hmac_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/hmac_ext.h new file mode 100644 index 00000000..c1371014 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/hmac_ext.h @@ -0,0 +1,20 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _hmac_ext_h_ +#define _hmac_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +void __db_chksum __P((void *, u_int8_t *, size_t, u_int8_t *, u_int8_t *)); +void __db_derive_mac __P((u_int8_t *, size_t, u_int8_t *)); +int __db_check_chksum __P((ENV *, void *, DB_CIPHER *, u_int8_t *, void *, size_t, int)); +void __db_SHA1Transform __P((u_int32_t *, unsigned char *)); +void __db_SHA1Init __P((SHA1_CTX *)); +void __db_SHA1Update __P((SHA1_CTX *, unsigned char *, size_t)); +void __db_SHA1Final __P((unsigned char *, SHA1_CTX *)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_hmac_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/int_def.in b/src/libs/resiprocate/contrib/db/dbinc_auto/int_def.in new file mode 100644 index 00000000..fd7f205c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/int_def.in @@ -0,0 +1,2064 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _DB_INT_DEF_IN_ +#define _DB_INT_DEF_IN_ + +#define __crdel_metasub_read __crdel_metasub_read@DB_VERSION_UNIQUE_NAME@ +#define __crdel_metasub_log __crdel_metasub_log@DB_VERSION_UNIQUE_NAME@ +#define __crdel_inmem_create_read __crdel_inmem_create_read@DB_VERSION_UNIQUE_NAME@ +#define __crdel_inmem_create_log __crdel_inmem_create_log@DB_VERSION_UNIQUE_NAME@ +#define __crdel_inmem_rename_read __crdel_inmem_rename_read@DB_VERSION_UNIQUE_NAME@ +#define __crdel_inmem_rename_log __crdel_inmem_rename_log@DB_VERSION_UNIQUE_NAME@ +#define __crdel_inmem_remove_read __crdel_inmem_remove_read@DB_VERSION_UNIQUE_NAME@ +#define __crdel_inmem_remove_log __crdel_inmem_remove_log@DB_VERSION_UNIQUE_NAME@ +#define __crdel_init_recover __crdel_init_recover@DB_VERSION_UNIQUE_NAME@ +#define __crdel_metasub_print __crdel_metasub_print@DB_VERSION_UNIQUE_NAME@ +#define __crdel_inmem_create_print __crdel_inmem_create_print@DB_VERSION_UNIQUE_NAME@ +#define __crdel_inmem_rename_print __crdel_inmem_rename_print@DB_VERSION_UNIQUE_NAME@ +#define __crdel_inmem_remove_print __crdel_inmem_remove_print@DB_VERSION_UNIQUE_NAME@ +#define __crdel_init_print __crdel_init_print@DB_VERSION_UNIQUE_NAME@ +#define __crdel_metasub_recover __crdel_metasub_recover@DB_VERSION_UNIQUE_NAME@ +#define __crdel_inmem_create_recover __crdel_inmem_create_recover@DB_VERSION_UNIQUE_NAME@ +#define __crdel_inmem_rename_recover __crdel_inmem_rename_recover@DB_VERSION_UNIQUE_NAME@ +#define __crdel_inmem_remove_recover __crdel_inmem_remove_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_master_open __db_master_open@DB_VERSION_UNIQUE_NAME@ +#define __db_master_update __db_master_update@DB_VERSION_UNIQUE_NAME@ +#define __env_setup __env_setup@DB_VERSION_UNIQUE_NAME@ +#define __env_mpool __env_mpool@DB_VERSION_UNIQUE_NAME@ +#define __db_close __db_close@DB_VERSION_UNIQUE_NAME@ +#define __db_refresh __db_refresh@DB_VERSION_UNIQUE_NAME@ +#define __db_log_page __db_log_page@DB_VERSION_UNIQUE_NAME@ +#define __db_backup_name __db_backup_name@DB_VERSION_UNIQUE_NAME@ +#ifdef CONFIG_TEST +#define __db_testcopy __db_testcopy@DB_VERSION_UNIQUE_NAME@ +#endif +#define __db_testdocopy __db_testdocopy@DB_VERSION_UNIQUE_NAME@ +#define __db_cursor_int __db_cursor_int@DB_VERSION_UNIQUE_NAME@ +#define __db_put __db_put@DB_VERSION_UNIQUE_NAME@ +#define __db_del __db_del@DB_VERSION_UNIQUE_NAME@ +#define __db_sync __db_sync@DB_VERSION_UNIQUE_NAME@ +#define __db_associate __db_associate@DB_VERSION_UNIQUE_NAME@ +#define __db_secondary_close __db_secondary_close@DB_VERSION_UNIQUE_NAME@ +#define __db_associate_foreign __db_associate_foreign@DB_VERSION_UNIQUE_NAME@ +#define __db_addrem_read __db_addrem_read@DB_VERSION_UNIQUE_NAME@ +#define __db_addrem_log __db_addrem_log@DB_VERSION_UNIQUE_NAME@ +#define __db_big_read __db_big_read@DB_VERSION_UNIQUE_NAME@ +#define __db_big_log __db_big_log@DB_VERSION_UNIQUE_NAME@ +#define __db_ovref_read __db_ovref_read@DB_VERSION_UNIQUE_NAME@ +#define __db_ovref_log __db_ovref_log@DB_VERSION_UNIQUE_NAME@ +#define __db_relink_42_read __db_relink_42_read@DB_VERSION_UNIQUE_NAME@ +#define __db_debug_read __db_debug_read@DB_VERSION_UNIQUE_NAME@ +#define __db_debug_log __db_debug_log@DB_VERSION_UNIQUE_NAME@ +#define __db_noop_read __db_noop_read@DB_VERSION_UNIQUE_NAME@ +#define __db_noop_log __db_noop_log@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_alloc_42_read __db_pg_alloc_42_read@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_alloc_read __db_pg_alloc_read@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_alloc_log __db_pg_alloc_log@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_free_42_read __db_pg_free_42_read@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_free_read __db_pg_free_read@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_free_log __db_pg_free_log@DB_VERSION_UNIQUE_NAME@ +#define __db_cksum_read __db_cksum_read@DB_VERSION_UNIQUE_NAME@ +#define __db_cksum_log __db_cksum_log@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_freedata_42_read __db_pg_freedata_42_read@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_freedata_read __db_pg_freedata_read@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_freedata_log __db_pg_freedata_log@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_init_read __db_pg_init_read@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_init_log __db_pg_init_log@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_sort_44_read __db_pg_sort_44_read@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_trunc_read __db_pg_trunc_read@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_trunc_log __db_pg_trunc_log@DB_VERSION_UNIQUE_NAME@ +#define __db_init_recover __db_init_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_addrem_print __db_addrem_print@DB_VERSION_UNIQUE_NAME@ +#define __db_big_print __db_big_print@DB_VERSION_UNIQUE_NAME@ +#define __db_ovref_print __db_ovref_print@DB_VERSION_UNIQUE_NAME@ +#define __db_relink_42_print __db_relink_42_print@DB_VERSION_UNIQUE_NAME@ +#define __db_debug_print __db_debug_print@DB_VERSION_UNIQUE_NAME@ +#define __db_noop_print __db_noop_print@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_alloc_42_print __db_pg_alloc_42_print@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_alloc_print __db_pg_alloc_print@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_free_42_print __db_pg_free_42_print@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_free_print __db_pg_free_print@DB_VERSION_UNIQUE_NAME@ +#define __db_cksum_print __db_cksum_print@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_freedata_42_print __db_pg_freedata_42_print@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_freedata_print __db_pg_freedata_print@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_init_print __db_pg_init_print@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_sort_44_print __db_pg_sort_44_print@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_trunc_print __db_pg_trunc_print@DB_VERSION_UNIQUE_NAME@ +#define __db_init_print __db_init_print@DB_VERSION_UNIQUE_NAME@ +#define __dbc_close __dbc_close@DB_VERSION_UNIQUE_NAME@ +#define __dbc_destroy __dbc_destroy@DB_VERSION_UNIQUE_NAME@ +#define __dbc_cmp __dbc_cmp@DB_VERSION_UNIQUE_NAME@ +#define __dbc_count __dbc_count@DB_VERSION_UNIQUE_NAME@ +#define __dbc_del __dbc_del@DB_VERSION_UNIQUE_NAME@ +#define __dbc_idel __dbc_idel@DB_VERSION_UNIQUE_NAME@ +#ifdef HAVE_COMPRESSION +#define __dbc_bulk_del __dbc_bulk_del@DB_VERSION_UNIQUE_NAME@ +#endif +#define __dbc_dup __dbc_dup@DB_VERSION_UNIQUE_NAME@ +#define __dbc_idup __dbc_idup@DB_VERSION_UNIQUE_NAME@ +#define __dbc_newopd __dbc_newopd@DB_VERSION_UNIQUE_NAME@ +#define __dbc_get __dbc_get@DB_VERSION_UNIQUE_NAME@ +#define __dbc_iget __dbc_iget@DB_VERSION_UNIQUE_NAME@ +#define __dbc_put __dbc_put@DB_VERSION_UNIQUE_NAME@ +#define __dbc_iput __dbc_iput@DB_VERSION_UNIQUE_NAME@ +#define __db_duperr __db_duperr@DB_VERSION_UNIQUE_NAME@ +#define __dbc_cleanup __dbc_cleanup@DB_VERSION_UNIQUE_NAME@ +#define __dbc_secondary_get_pp __dbc_secondary_get_pp@DB_VERSION_UNIQUE_NAME@ +#define __dbc_pget __dbc_pget@DB_VERSION_UNIQUE_NAME@ +#define __dbc_del_primary __dbc_del_primary@DB_VERSION_UNIQUE_NAME@ +#define __db_s_first __db_s_first@DB_VERSION_UNIQUE_NAME@ +#define __db_s_next __db_s_next@DB_VERSION_UNIQUE_NAME@ +#define __db_s_done __db_s_done@DB_VERSION_UNIQUE_NAME@ +#define __db_buildpartial __db_buildpartial@DB_VERSION_UNIQUE_NAME@ +#define __db_partsize __db_partsize@DB_VERSION_UNIQUE_NAME@ +#ifdef DIAGNOSTIC +#define __db_check_skeyset __db_check_skeyset@DB_VERSION_UNIQUE_NAME@ +#endif +#define __cdsgroup_begin __cdsgroup_begin@DB_VERSION_UNIQUE_NAME@ +#define __db_pgin __db_pgin@DB_VERSION_UNIQUE_NAME@ +#define __db_pgout __db_pgout@DB_VERSION_UNIQUE_NAME@ +#define __db_decrypt_pg __db_decrypt_pg@DB_VERSION_UNIQUE_NAME@ +#define __db_encrypt_and_checksum_pg __db_encrypt_and_checksum_pg@DB_VERSION_UNIQUE_NAME@ +#define __db_metaswap __db_metaswap@DB_VERSION_UNIQUE_NAME@ +#define __db_byteswap __db_byteswap@DB_VERSION_UNIQUE_NAME@ +#define __db_pageswap __db_pageswap@DB_VERSION_UNIQUE_NAME@ +#define __db_dispatch __db_dispatch@DB_VERSION_UNIQUE_NAME@ +#define __db_add_recovery __db_add_recovery@DB_VERSION_UNIQUE_NAME@ +#define __db_add_recovery_int __db_add_recovery_int@DB_VERSION_UNIQUE_NAME@ +#define __db_txnlist_init __db_txnlist_init@DB_VERSION_UNIQUE_NAME@ +#define __db_txnlist_add __db_txnlist_add@DB_VERSION_UNIQUE_NAME@ +#define __db_txnlist_remove __db_txnlist_remove@DB_VERSION_UNIQUE_NAME@ +#define __db_txnlist_ckp __db_txnlist_ckp@DB_VERSION_UNIQUE_NAME@ +#define __db_txnlist_end __db_txnlist_end@DB_VERSION_UNIQUE_NAME@ +#define __db_txnlist_find __db_txnlist_find@DB_VERSION_UNIQUE_NAME@ +#define __db_txnlist_update __db_txnlist_update@DB_VERSION_UNIQUE_NAME@ +#define __db_txnlist_gen __db_txnlist_gen@DB_VERSION_UNIQUE_NAME@ +#define __db_txnlist_lsnadd __db_txnlist_lsnadd@DB_VERSION_UNIQUE_NAME@ +#define __db_txnlist_lsnget __db_txnlist_lsnget@DB_VERSION_UNIQUE_NAME@ +#define __db_txnlist_lsninit __db_txnlist_lsninit@DB_VERSION_UNIQUE_NAME@ +#define __db_txnlist_print __db_txnlist_print@DB_VERSION_UNIQUE_NAME@ +#define __db_ditem_nolog __db_ditem_nolog@DB_VERSION_UNIQUE_NAME@ +#define __db_ditem __db_ditem@DB_VERSION_UNIQUE_NAME@ +#define __db_pitem_nolog __db_pitem_nolog@DB_VERSION_UNIQUE_NAME@ +#define __db_pitem __db_pitem@DB_VERSION_UNIQUE_NAME@ +#define __db_associate_pp __db_associate_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_close_pp __db_close_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_cursor_pp __db_cursor_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_cursor __db_cursor@DB_VERSION_UNIQUE_NAME@ +#define __db_del_pp __db_del_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_exists __db_exists@DB_VERSION_UNIQUE_NAME@ +#define __db_fd_pp __db_fd_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_get_pp __db_get_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_get __db_get@DB_VERSION_UNIQUE_NAME@ +#define __db_join_pp __db_join_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_key_range_pp __db_key_range_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_open_pp __db_open_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_pget_pp __db_pget_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_pget __db_pget@DB_VERSION_UNIQUE_NAME@ +#define __db_put_pp __db_put_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_compact_pp __db_compact_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_associate_foreign_pp __db_associate_foreign_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_sync_pp __db_sync_pp@DB_VERSION_UNIQUE_NAME@ +#define __dbc_close_pp __dbc_close_pp@DB_VERSION_UNIQUE_NAME@ +#define __dbc_cmp_pp __dbc_cmp_pp@DB_VERSION_UNIQUE_NAME@ +#define __dbc_count_pp __dbc_count_pp@DB_VERSION_UNIQUE_NAME@ +#define __dbc_del_pp __dbc_del_pp@DB_VERSION_UNIQUE_NAME@ +#define __dbc_dup_pp __dbc_dup_pp@DB_VERSION_UNIQUE_NAME@ +#define __dbc_get_pp __dbc_get_pp@DB_VERSION_UNIQUE_NAME@ +#define __dbc_get_arg __dbc_get_arg@DB_VERSION_UNIQUE_NAME@ +#define __db_secondary_close_pp __db_secondary_close_pp@DB_VERSION_UNIQUE_NAME@ +#define __dbc_pget_pp __dbc_pget_pp@DB_VERSION_UNIQUE_NAME@ +#define __dbc_put_pp __dbc_put_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_txn_auto_init __db_txn_auto_init@DB_VERSION_UNIQUE_NAME@ +#define __db_txn_auto_resolve __db_txn_auto_resolve@DB_VERSION_UNIQUE_NAME@ +#define __db_join __db_join@DB_VERSION_UNIQUE_NAME@ +#define __db_join_close __db_join_close@DB_VERSION_UNIQUE_NAME@ +#define __db_secondary_corrupt __db_secondary_corrupt@DB_VERSION_UNIQUE_NAME@ +#define __db_new __db_new@DB_VERSION_UNIQUE_NAME@ +#define __db_free __db_free@DB_VERSION_UNIQUE_NAME@ +#ifdef HAVE_FTRUNCATE +#define __db_freelist_pos __db_freelist_pos@DB_VERSION_UNIQUE_NAME@ +#endif +#define __db_freelist_sort __db_freelist_sort@DB_VERSION_UNIQUE_NAME@ +#ifdef HAVE_FTRUNCATE +#define __db_pg_truncate __db_pg_truncate@DB_VERSION_UNIQUE_NAME@ +#endif +#ifdef HAVE_FTRUNCATE +#define __db_free_truncate __db_free_truncate@DB_VERSION_UNIQUE_NAME@ +#endif +#define __db_lprint __db_lprint@DB_VERSION_UNIQUE_NAME@ +#define __db_lget __db_lget@DB_VERSION_UNIQUE_NAME@ +#define __db_lput __db_lput@DB_VERSION_UNIQUE_NAME@ +#define __db_create_internal __db_create_internal@DB_VERSION_UNIQUE_NAME@ +#define __dbh_am_chk __dbh_am_chk@DB_VERSION_UNIQUE_NAME@ +#define __db_get_flags __db_get_flags@DB_VERSION_UNIQUE_NAME@ +#define __db_set_flags __db_set_flags@DB_VERSION_UNIQUE_NAME@ +#define __db_get_lorder __db_get_lorder@DB_VERSION_UNIQUE_NAME@ +#define __db_set_lorder __db_set_lorder@DB_VERSION_UNIQUE_NAME@ +#define __db_set_pagesize __db_set_pagesize@DB_VERSION_UNIQUE_NAME@ +#define __db_open __db_open@DB_VERSION_UNIQUE_NAME@ +#define __db_get_open_flags __db_get_open_flags@DB_VERSION_UNIQUE_NAME@ +#define __db_new_file __db_new_file@DB_VERSION_UNIQUE_NAME@ +#define __db_init_subdb __db_init_subdb@DB_VERSION_UNIQUE_NAME@ +#define __db_chk_meta __db_chk_meta@DB_VERSION_UNIQUE_NAME@ +#define __db_meta_setup __db_meta_setup@DB_VERSION_UNIQUE_NAME@ +#define __db_goff __db_goff@DB_VERSION_UNIQUE_NAME@ +#define __db_poff __db_poff@DB_VERSION_UNIQUE_NAME@ +#define __db_ovref __db_ovref@DB_VERSION_UNIQUE_NAME@ +#define __db_doff __db_doff@DB_VERSION_UNIQUE_NAME@ +#define __db_moff __db_moff@DB_VERSION_UNIQUE_NAME@ +#define __db_coff __db_coff@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_overflow __db_vrfy_overflow@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_ovfl_structure __db_vrfy_ovfl_structure@DB_VERSION_UNIQUE_NAME@ +#define __db_safe_goff __db_safe_goff@DB_VERSION_UNIQUE_NAME@ +#define __db_loadme __db_loadme@DB_VERSION_UNIQUE_NAME@ +#define __db_dumptree __db_dumptree@DB_VERSION_UNIQUE_NAME@ +#define __db_get_flags_fn __db_get_flags_fn@DB_VERSION_UNIQUE_NAME@ +#define __db_prnpage __db_prnpage@DB_VERSION_UNIQUE_NAME@ +#define __db_prpage __db_prpage@DB_VERSION_UNIQUE_NAME@ +#define __db_prbytes __db_prbytes@DB_VERSION_UNIQUE_NAME@ +#define __db_prflags __db_prflags@DB_VERSION_UNIQUE_NAME@ +#define __db_lockmode_to_string __db_lockmode_to_string@DB_VERSION_UNIQUE_NAME@ +#define __db_dumptree __db_dumptree@DB_VERSION_UNIQUE_NAME@ +#define __db_get_flags_fn __db_get_flags_fn@DB_VERSION_UNIQUE_NAME@ +#define __db_dump_pp __db_dump_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_dump __db_dump@DB_VERSION_UNIQUE_NAME@ +#define __db_prdbt __db_prdbt@DB_VERSION_UNIQUE_NAME@ +#define __db_prheader __db_prheader@DB_VERSION_UNIQUE_NAME@ +#define __db_prfooter __db_prfooter@DB_VERSION_UNIQUE_NAME@ +#define __db_pr_callback __db_pr_callback@DB_VERSION_UNIQUE_NAME@ +#define __db_dbtype_to_string __db_dbtype_to_string@DB_VERSION_UNIQUE_NAME@ +#define __db_addrem_recover __db_addrem_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_big_recover __db_big_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_ovref_recover __db_ovref_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_debug_recover __db_debug_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_noop_recover __db_noop_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_alloc_recover __db_pg_alloc_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_free_recover __db_pg_free_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_freedata_recover __db_pg_freedata_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_cksum_recover __db_cksum_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_init_recover __db_pg_init_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_trunc_recover __db_pg_trunc_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_sort_44_recover __db_pg_sort_44_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_alloc_42_recover __db_pg_alloc_42_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_free_42_recover __db_pg_free_42_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_pg_freedata_42_recover __db_pg_freedata_42_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_relink_42_recover __db_relink_42_recover@DB_VERSION_UNIQUE_NAME@ +#define __db_traverse_big __db_traverse_big@DB_VERSION_UNIQUE_NAME@ +#define __db_reclaim_callback __db_reclaim_callback@DB_VERSION_UNIQUE_NAME@ +#define __db_truncate_callback __db_truncate_callback@DB_VERSION_UNIQUE_NAME@ +#define __env_dbremove_pp __env_dbremove_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_remove_pp __db_remove_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_remove __db_remove@DB_VERSION_UNIQUE_NAME@ +#define __db_remove_int __db_remove_int@DB_VERSION_UNIQUE_NAME@ +#define __db_inmem_remove __db_inmem_remove@DB_VERSION_UNIQUE_NAME@ +#define __env_dbrename_pp __env_dbrename_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_rename_pp __db_rename_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_rename_int __db_rename_int@DB_VERSION_UNIQUE_NAME@ +#define __db_ret __db_ret@DB_VERSION_UNIQUE_NAME@ +#define __db_retcopy __db_retcopy@DB_VERSION_UNIQUE_NAME@ +#define __env_fileid_reset_pp __env_fileid_reset_pp@DB_VERSION_UNIQUE_NAME@ +#define __env_fileid_reset __env_fileid_reset@DB_VERSION_UNIQUE_NAME@ +#define __env_lsn_reset_pp __env_lsn_reset_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_lsn_reset __db_lsn_reset@DB_VERSION_UNIQUE_NAME@ +#define __db_compare_both __db_compare_both@DB_VERSION_UNIQUE_NAME@ +#define __db_sort_multiple __db_sort_multiple@DB_VERSION_UNIQUE_NAME@ +#define __db_stat_pp __db_stat_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_stat_print_pp __db_stat_print_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_stat_print __db_stat_print@DB_VERSION_UNIQUE_NAME@ +#define __db_truncate_pp __db_truncate_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_truncate __db_truncate@DB_VERSION_UNIQUE_NAME@ +#define __db_upgrade_pp __db_upgrade_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_upgrade __db_upgrade@DB_VERSION_UNIQUE_NAME@ +#define __db_lastpgno __db_lastpgno@DB_VERSION_UNIQUE_NAME@ +#define __db_31_offdup __db_31_offdup@DB_VERSION_UNIQUE_NAME@ +#define __db_verify_pp __db_verify_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_verify_internal __db_verify_internal@DB_VERSION_UNIQUE_NAME@ +#define __db_verify __db_verify@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_common __db_vrfy_common@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_datapage __db_vrfy_datapage@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_meta __db_vrfy_meta@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_struct_feedback __db_vrfy_struct_feedback@DB_VERSION_UNIQUE_NAME@ +#define __db_salvage_pg __db_salvage_pg@DB_VERSION_UNIQUE_NAME@ +#define __db_salvage_leaf __db_salvage_leaf@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_inpitem __db_vrfy_inpitem@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_duptype __db_vrfy_duptype@DB_VERSION_UNIQUE_NAME@ +#define __db_salvage_duptree __db_salvage_duptree@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_dbinfo_create __db_vrfy_dbinfo_create@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_dbinfo_destroy __db_vrfy_dbinfo_destroy@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_getpageinfo __db_vrfy_getpageinfo@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_putpageinfo __db_vrfy_putpageinfo@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_pgset __db_vrfy_pgset@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_pgset_get __db_vrfy_pgset_get@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_pgset_inc __db_vrfy_pgset_inc@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_pgset_next __db_vrfy_pgset_next@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_childcursor __db_vrfy_childcursor@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_childput __db_vrfy_childput@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_ccset __db_vrfy_ccset@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_ccnext __db_vrfy_ccnext@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_ccclose __db_vrfy_ccclose@DB_VERSION_UNIQUE_NAME@ +#define __db_salvage_init __db_salvage_init@DB_VERSION_UNIQUE_NAME@ +#define __db_salvage_destroy __db_salvage_destroy@DB_VERSION_UNIQUE_NAME@ +#define __db_salvage_getnext __db_salvage_getnext@DB_VERSION_UNIQUE_NAME@ +#define __db_salvage_isdone __db_salvage_isdone@DB_VERSION_UNIQUE_NAME@ +#define __db_salvage_markdone __db_salvage_markdone@DB_VERSION_UNIQUE_NAME@ +#define __db_salvage_markneeded __db_salvage_markneeded@DB_VERSION_UNIQUE_NAME@ +#define __db_vrfy_prdbt __db_vrfy_prdbt@DB_VERSION_UNIQUE_NAME@ +#define __partition_init __partition_init@DB_VERSION_UNIQUE_NAME@ +#define __partition_set __partition_set@DB_VERSION_UNIQUE_NAME@ +#define __partition_set_dirs __partition_set_dirs@DB_VERSION_UNIQUE_NAME@ +#define __partition_open __partition_open@DB_VERSION_UNIQUE_NAME@ +#define __partition_get_callback __partition_get_callback@DB_VERSION_UNIQUE_NAME@ +#define __partition_get_keys __partition_get_keys@DB_VERSION_UNIQUE_NAME@ +#define __partition_get_dirs __partition_get_dirs@DB_VERSION_UNIQUE_NAME@ +#define __partc_init __partc_init@DB_VERSION_UNIQUE_NAME@ +#define __partc_get __partc_get@DB_VERSION_UNIQUE_NAME@ +#define __partition_close __partition_close@DB_VERSION_UNIQUE_NAME@ +#define __partition_sync __partition_sync@DB_VERSION_UNIQUE_NAME@ +#define __partition_stat __partition_stat@DB_VERSION_UNIQUE_NAME@ +#define __part_truncate __part_truncate@DB_VERSION_UNIQUE_NAME@ +#define __part_compact __part_compact@DB_VERSION_UNIQUE_NAME@ +#define __part_lsn_reset __part_lsn_reset@DB_VERSION_UNIQUE_NAME@ +#define __part_fileid_reset __part_fileid_reset@DB_VERSION_UNIQUE_NAME@ +#define __part_key_range __part_key_range@DB_VERSION_UNIQUE_NAME@ +#define __part_remove __part_remove@DB_VERSION_UNIQUE_NAME@ +#define __part_rename __part_rename@DB_VERSION_UNIQUE_NAME@ +#define __part_verify __part_verify@DB_VERSION_UNIQUE_NAME@ +#define __part_testdocopy __part_testdocopy@DB_VERSION_UNIQUE_NAME@ +#define __db_no_partition __db_no_partition@DB_VERSION_UNIQUE_NAME@ +#define __partition_set __partition_set@DB_VERSION_UNIQUE_NAME@ +#define __partition_get_callback __partition_get_callback@DB_VERSION_UNIQUE_NAME@ +#define __partition_get_dirs __partition_get_dirs@DB_VERSION_UNIQUE_NAME@ +#define __partition_get_keys __partition_get_keys@DB_VERSION_UNIQUE_NAME@ +#define __partition_init __partition_init@DB_VERSION_UNIQUE_NAME@ +#define __part_fileid_reset __part_fileid_reset@DB_VERSION_UNIQUE_NAME@ +#define __partition_set_dirs __partition_set_dirs@DB_VERSION_UNIQUE_NAME@ +#define __bam_compact __bam_compact@DB_VERSION_UNIQUE_NAME@ +#define __bam_cmp __bam_cmp@DB_VERSION_UNIQUE_NAME@ +#define __bam_defcmp __bam_defcmp@DB_VERSION_UNIQUE_NAME@ +#define __bam_defpfx __bam_defpfx@DB_VERSION_UNIQUE_NAME@ +#define __bam_compress_dupcmp __bam_compress_dupcmp@DB_VERSION_UNIQUE_NAME@ +#define __bam_defcompress __bam_defcompress@DB_VERSION_UNIQUE_NAME@ +#define __bam_defdecompress __bam_defdecompress@DB_VERSION_UNIQUE_NAME@ +#define __bamc_compress_get __bamc_compress_get@DB_VERSION_UNIQUE_NAME@ +#define __bamc_compress_put __bamc_compress_put@DB_VERSION_UNIQUE_NAME@ +#define __bamc_compress_del __bamc_compress_del@DB_VERSION_UNIQUE_NAME@ +#define __bamc_compress_bulk_del __bamc_compress_bulk_del@DB_VERSION_UNIQUE_NAME@ +#define __bamc_compress_count __bamc_compress_count@DB_VERSION_UNIQUE_NAME@ +#define __bamc_compress_cmp __bamc_compress_cmp@DB_VERSION_UNIQUE_NAME@ +#define __bamc_compress_dup __bamc_compress_dup@DB_VERSION_UNIQUE_NAME@ +#define __bam_compress_salvage __bam_compress_salvage@DB_VERSION_UNIQUE_NAME@ +#define __bam_compress_count __bam_compress_count@DB_VERSION_UNIQUE_NAME@ +#define __bam_pgin __bam_pgin@DB_VERSION_UNIQUE_NAME@ +#define __bam_pgout __bam_pgout@DB_VERSION_UNIQUE_NAME@ +#define __bam_mswap __bam_mswap@DB_VERSION_UNIQUE_NAME@ +#define __bam_ca_delete __bam_ca_delete@DB_VERSION_UNIQUE_NAME@ +#define __ram_ca_delete __ram_ca_delete@DB_VERSION_UNIQUE_NAME@ +#define __bam_ca_di __bam_ca_di@DB_VERSION_UNIQUE_NAME@ +#define __bam_ca_dup __bam_ca_dup@DB_VERSION_UNIQUE_NAME@ +#define __bam_ca_undodup __bam_ca_undodup@DB_VERSION_UNIQUE_NAME@ +#define __bam_ca_rsplit __bam_ca_rsplit@DB_VERSION_UNIQUE_NAME@ +#define __bam_ca_split __bam_ca_split@DB_VERSION_UNIQUE_NAME@ +#define __bam_ca_undosplit __bam_ca_undosplit@DB_VERSION_UNIQUE_NAME@ +#define __bamc_init __bamc_init@DB_VERSION_UNIQUE_NAME@ +#define __bamc_refresh __bamc_refresh@DB_VERSION_UNIQUE_NAME@ +#define __bamc_cmp __bamc_cmp@DB_VERSION_UNIQUE_NAME@ +#define __bamc_count __bamc_count@DB_VERSION_UNIQUE_NAME@ +#define __bamc_dup __bamc_dup@DB_VERSION_UNIQUE_NAME@ +#define __bam_bulk_overflow __bam_bulk_overflow@DB_VERSION_UNIQUE_NAME@ +#define __bam_bulk_duplicates __bam_bulk_duplicates@DB_VERSION_UNIQUE_NAME@ +#define __bamc_rget __bamc_rget@DB_VERSION_UNIQUE_NAME@ +#define __bam_opd_exists __bam_opd_exists@DB_VERSION_UNIQUE_NAME@ +#define __bam_ditem __bam_ditem@DB_VERSION_UNIQUE_NAME@ +#define __bam_adjindx __bam_adjindx@DB_VERSION_UNIQUE_NAME@ +#define __bam_dpages __bam_dpages@DB_VERSION_UNIQUE_NAME@ +#define __bam_relink __bam_relink@DB_VERSION_UNIQUE_NAME@ +#define __bam_pupdate __bam_pupdate@DB_VERSION_UNIQUE_NAME@ +#define __bam_db_create __bam_db_create@DB_VERSION_UNIQUE_NAME@ +#define __bam_db_close __bam_db_close@DB_VERSION_UNIQUE_NAME@ +#define __bam_map_flags __bam_map_flags@DB_VERSION_UNIQUE_NAME@ +#define __bam_set_flags __bam_set_flags@DB_VERSION_UNIQUE_NAME@ +#define __bam_set_bt_compare __bam_set_bt_compare@DB_VERSION_UNIQUE_NAME@ +#define __bam_set_bt_compress __bam_set_bt_compress@DB_VERSION_UNIQUE_NAME@ +#define __bam_get_bt_minkey __bam_get_bt_minkey@DB_VERSION_UNIQUE_NAME@ +#define __bam_copy_config __bam_copy_config@DB_VERSION_UNIQUE_NAME@ +#define __ram_map_flags __ram_map_flags@DB_VERSION_UNIQUE_NAME@ +#define __ram_set_flags __ram_set_flags@DB_VERSION_UNIQUE_NAME@ +#define __ram_get_re_len __ram_get_re_len@DB_VERSION_UNIQUE_NAME@ +#define __ram_get_re_pad __ram_get_re_pad@DB_VERSION_UNIQUE_NAME@ +#define __bam_open __bam_open@DB_VERSION_UNIQUE_NAME@ +#define __bam_metachk __bam_metachk@DB_VERSION_UNIQUE_NAME@ +#define __bam_read_root __bam_read_root@DB_VERSION_UNIQUE_NAME@ +#define __bam_new_file __bam_new_file@DB_VERSION_UNIQUE_NAME@ +#define __bam_new_subdb __bam_new_subdb@DB_VERSION_UNIQUE_NAME@ +#define __bam_iitem __bam_iitem@DB_VERSION_UNIQUE_NAME@ +#define __bam_ritem __bam_ritem@DB_VERSION_UNIQUE_NAME@ +#define __bam_irep __bam_irep@DB_VERSION_UNIQUE_NAME@ +#define __bam_split_recover __bam_split_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_split_42_recover __bam_split_42_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_rsplit_recover __bam_rsplit_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_adj_recover __bam_adj_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_cadjust_recover __bam_cadjust_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_cdel_recover __bam_cdel_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_repl_recover __bam_repl_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_root_recover __bam_root_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_curadj_recover __bam_curadj_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_rcuradj_recover __bam_rcuradj_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_relink_recover __bam_relink_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_merge_44_recover __bam_merge_44_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_merge_recover __bam_merge_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_pgno_recover __bam_pgno_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_relink_43_recover __bam_relink_43_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_reclaim __bam_reclaim@DB_VERSION_UNIQUE_NAME@ +#define __bam_truncate __bam_truncate@DB_VERSION_UNIQUE_NAME@ +#define __ram_open __ram_open@DB_VERSION_UNIQUE_NAME@ +#define __ram_append __ram_append@DB_VERSION_UNIQUE_NAME@ +#define __ramc_del __ramc_del@DB_VERSION_UNIQUE_NAME@ +#define __ramc_get __ramc_get@DB_VERSION_UNIQUE_NAME@ +#define __ramc_put __ramc_put@DB_VERSION_UNIQUE_NAME@ +#define __ram_ca __ram_ca@DB_VERSION_UNIQUE_NAME@ +#define __ram_getno __ram_getno@DB_VERSION_UNIQUE_NAME@ +#define __ram_writeback __ram_writeback@DB_VERSION_UNIQUE_NAME@ +#define __bam_rsearch __bam_rsearch@DB_VERSION_UNIQUE_NAME@ +#define __bam_adjust __bam_adjust@DB_VERSION_UNIQUE_NAME@ +#define __bam_nrecs __bam_nrecs@DB_VERSION_UNIQUE_NAME@ +#define __bam_total __bam_total@DB_VERSION_UNIQUE_NAME@ +#define __bam_get_root __bam_get_root@DB_VERSION_UNIQUE_NAME@ +#define __bam_search __bam_search@DB_VERSION_UNIQUE_NAME@ +#define __bam_stkrel __bam_stkrel@DB_VERSION_UNIQUE_NAME@ +#define __bam_stkgrow __bam_stkgrow@DB_VERSION_UNIQUE_NAME@ +#define __bam_split __bam_split@DB_VERSION_UNIQUE_NAME@ +#define __bam_broot __bam_broot@DB_VERSION_UNIQUE_NAME@ +#define __ram_root __ram_root@DB_VERSION_UNIQUE_NAME@ +#define __bam_pinsert __bam_pinsert@DB_VERSION_UNIQUE_NAME@ +#define __bam_copy __bam_copy@DB_VERSION_UNIQUE_NAME@ +#define __bam_stat __bam_stat@DB_VERSION_UNIQUE_NAME@ +#define __bam_stat_print __bam_stat_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_stat_callback __bam_stat_callback@DB_VERSION_UNIQUE_NAME@ +#define __bam_print_cursor __bam_print_cursor@DB_VERSION_UNIQUE_NAME@ +#define __bam_key_range __bam_key_range@DB_VERSION_UNIQUE_NAME@ +#define __bam_traverse __bam_traverse@DB_VERSION_UNIQUE_NAME@ +#define __bam_30_btreemeta __bam_30_btreemeta@DB_VERSION_UNIQUE_NAME@ +#define __bam_31_btreemeta __bam_31_btreemeta@DB_VERSION_UNIQUE_NAME@ +#define __bam_31_lbtree __bam_31_lbtree@DB_VERSION_UNIQUE_NAME@ +#define __bam_vrfy_meta __bam_vrfy_meta@DB_VERSION_UNIQUE_NAME@ +#define __ram_vrfy_leaf __ram_vrfy_leaf@DB_VERSION_UNIQUE_NAME@ +#define __bam_vrfy __bam_vrfy@DB_VERSION_UNIQUE_NAME@ +#define __bam_vrfy_itemorder __bam_vrfy_itemorder@DB_VERSION_UNIQUE_NAME@ +#define __bam_vrfy_structure __bam_vrfy_structure@DB_VERSION_UNIQUE_NAME@ +#define __bam_vrfy_subtree __bam_vrfy_subtree@DB_VERSION_UNIQUE_NAME@ +#define __bam_salvage __bam_salvage@DB_VERSION_UNIQUE_NAME@ +#define __bam_salvage_walkdupint __bam_salvage_walkdupint@DB_VERSION_UNIQUE_NAME@ +#define __bam_meta2pgset __bam_meta2pgset@DB_VERSION_UNIQUE_NAME@ +#define __bam_split_read __bam_split_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_split_log __bam_split_log@DB_VERSION_UNIQUE_NAME@ +#define __bam_split_42_read __bam_split_42_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_rsplit_read __bam_rsplit_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_rsplit_log __bam_rsplit_log@DB_VERSION_UNIQUE_NAME@ +#define __bam_adj_read __bam_adj_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_adj_log __bam_adj_log@DB_VERSION_UNIQUE_NAME@ +#define __bam_cadjust_read __bam_cadjust_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_cadjust_log __bam_cadjust_log@DB_VERSION_UNIQUE_NAME@ +#define __bam_cdel_read __bam_cdel_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_cdel_log __bam_cdel_log@DB_VERSION_UNIQUE_NAME@ +#define __bam_repl_read __bam_repl_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_repl_log __bam_repl_log@DB_VERSION_UNIQUE_NAME@ +#define __bam_root_read __bam_root_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_root_log __bam_root_log@DB_VERSION_UNIQUE_NAME@ +#define __bam_curadj_read __bam_curadj_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_curadj_log __bam_curadj_log@DB_VERSION_UNIQUE_NAME@ +#define __bam_rcuradj_read __bam_rcuradj_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_rcuradj_log __bam_rcuradj_log@DB_VERSION_UNIQUE_NAME@ +#define __bam_relink_43_read __bam_relink_43_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_relink_read __bam_relink_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_relink_log __bam_relink_log@DB_VERSION_UNIQUE_NAME@ +#define __bam_merge_44_read __bam_merge_44_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_merge_read __bam_merge_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_merge_log __bam_merge_log@DB_VERSION_UNIQUE_NAME@ +#define __bam_pgno_read __bam_pgno_read@DB_VERSION_UNIQUE_NAME@ +#define __bam_pgno_log __bam_pgno_log@DB_VERSION_UNIQUE_NAME@ +#define __bam_init_recover __bam_init_recover@DB_VERSION_UNIQUE_NAME@ +#define __bam_split_print __bam_split_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_split_42_print __bam_split_42_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_rsplit_print __bam_rsplit_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_adj_print __bam_adj_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_cadjust_print __bam_cadjust_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_cdel_print __bam_cdel_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_repl_print __bam_repl_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_root_print __bam_root_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_curadj_print __bam_curadj_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_rcuradj_print __bam_rcuradj_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_relink_43_print __bam_relink_43_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_relink_print __bam_relink_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_merge_44_print __bam_merge_44_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_merge_print __bam_merge_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_pgno_print __bam_pgno_print@DB_VERSION_UNIQUE_NAME@ +#define __bam_init_print __bam_init_print@DB_VERSION_UNIQUE_NAME@ +#ifndef HAVE_ATOI +#define atoi atoi@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_ATOL +#define atol atol@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_GETCWD +#define getcwd getcwd@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_GETOPT +#define getopt getopt@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_ISALPHA +#define isalpha isalpha@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_ISDIGIT +#define isdigit isdigit@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_ISPRINT +#define isprint isprint@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_ISSPACE +#define isspace isspace@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_MEMCMP +#define memcmp memcmp@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_MEMCPY +#define memcpy memcpy@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_MEMMOVE +#define memmove memmove@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_PRINTF +#define printf printf@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_PRINTF +#define fprintf fprintf@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_PRINTF +#define vfprintf vfprintf@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_QSORT +#define qsort qsort@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_RAISE +#define raise raise@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_RAND +#define rand rand@DB_VERSION_UNIQUE_NAME@ +#define srand srand@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_SNPRINTF +#define snprintf snprintf@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_VSNPRINTF +#define vsnprintf vsnprintf@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_STRCASECMP +#define strcasecmp strcasecmp@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_STRCASECMP +#define strncasecmp strncasecmp@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_STRCAT +#define strcat strcat@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_STRCHR +#define strchr strchr@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_STRDUP +#define strdup strdup@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_STRERROR +#define strerror strerror@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_STRNCAT +#define strncat strncat@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_STRNCMP +#define strncmp strncmp@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_STRRCHR +#define strrchr strrchr@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_STRSEP +#define strsep strsep@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_STRTOL +#define strtol strtol@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_STRTOUL +#define strtoul strtoul@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_TIME +#define time time@DB_VERSION_UNIQUE_NAME@ +#endif +#define __crypto_region_init __crypto_region_init@DB_VERSION_UNIQUE_NAME@ +#define __db_isbigendian __db_isbigendian@DB_VERSION_UNIQUE_NAME@ +#define __db_byteorder __db_byteorder@DB_VERSION_UNIQUE_NAME@ +#define __db_compress_count_int __db_compress_count_int@DB_VERSION_UNIQUE_NAME@ +#define __db_compress_int __db_compress_int@DB_VERSION_UNIQUE_NAME@ +#define __db_decompress_count_int __db_decompress_count_int@DB_VERSION_UNIQUE_NAME@ +#define __db_decompress_int __db_decompress_int@DB_VERSION_UNIQUE_NAME@ +#define __db_decompress_int32 __db_decompress_int32@DB_VERSION_UNIQUE_NAME@ +#define __db_fchk __db_fchk@DB_VERSION_UNIQUE_NAME@ +#define __db_fcchk __db_fcchk@DB_VERSION_UNIQUE_NAME@ +#define __db_ferr __db_ferr@DB_VERSION_UNIQUE_NAME@ +#define __db_fnl __db_fnl@DB_VERSION_UNIQUE_NAME@ +#define __db_pgerr __db_pgerr@DB_VERSION_UNIQUE_NAME@ +#define __db_pgfmt __db_pgfmt@DB_VERSION_UNIQUE_NAME@ +#ifdef DIAGNOSTIC +#define __db_assert __db_assert@DB_VERSION_UNIQUE_NAME@ +#endif +#define __env_panic_msg __env_panic_msg@DB_VERSION_UNIQUE_NAME@ +#define __env_panic __env_panic@DB_VERSION_UNIQUE_NAME@ +#define __db_unknown_error __db_unknown_error@DB_VERSION_UNIQUE_NAME@ +#define __db_syserr __db_syserr@DB_VERSION_UNIQUE_NAME@ +#define __db_err __db_err@DB_VERSION_UNIQUE_NAME@ +#define __db_errx __db_errx@DB_VERSION_UNIQUE_NAME@ +#define __db_errcall __db_errcall@DB_VERSION_UNIQUE_NAME@ +#define __db_errfile __db_errfile@DB_VERSION_UNIQUE_NAME@ +#define __db_msgadd __db_msgadd@DB_VERSION_UNIQUE_NAME@ +#define __db_msgadd_ap __db_msgadd_ap@DB_VERSION_UNIQUE_NAME@ +#define __db_msg __db_msg@DB_VERSION_UNIQUE_NAME@ +#define __db_unknown_flag __db_unknown_flag@DB_VERSION_UNIQUE_NAME@ +#define __db_unknown_type __db_unknown_type@DB_VERSION_UNIQUE_NAME@ +#define __db_unknown_path __db_unknown_path@DB_VERSION_UNIQUE_NAME@ +#define __db_check_txn __db_check_txn@DB_VERSION_UNIQUE_NAME@ +#define __db_txn_deadlock_err __db_txn_deadlock_err@DB_VERSION_UNIQUE_NAME@ +#define __db_not_txn_env __db_not_txn_env@DB_VERSION_UNIQUE_NAME@ +#define __db_rec_toobig __db_rec_toobig@DB_VERSION_UNIQUE_NAME@ +#define __db_rec_repl __db_rec_repl@DB_VERSION_UNIQUE_NAME@ +#define __dbc_logging __dbc_logging@DB_VERSION_UNIQUE_NAME@ +#define __db_check_lsn __db_check_lsn@DB_VERSION_UNIQUE_NAME@ +#define __db_rdonly __db_rdonly@DB_VERSION_UNIQUE_NAME@ +#define __db_space_err __db_space_err@DB_VERSION_UNIQUE_NAME@ +#define __db_failed __db_failed@DB_VERSION_UNIQUE_NAME@ +#define __db_getlong __db_getlong@DB_VERSION_UNIQUE_NAME@ +#define __db_getulong __db_getulong@DB_VERSION_UNIQUE_NAME@ +#define __db_idspace __db_idspace@DB_VERSION_UNIQUE_NAME@ +#define __db_log2 __db_log2@DB_VERSION_UNIQUE_NAME@ +#define __db_tablesize __db_tablesize@DB_VERSION_UNIQUE_NAME@ +#define __db_hashinit __db_hashinit@DB_VERSION_UNIQUE_NAME@ +#define __dbt_usercopy __dbt_usercopy@DB_VERSION_UNIQUE_NAME@ +#define __dbt_userfree __dbt_userfree@DB_VERSION_UNIQUE_NAME@ +#define __db_mkpath __db_mkpath@DB_VERSION_UNIQUE_NAME@ +#define __db_openflags __db_openflags@DB_VERSION_UNIQUE_NAME@ +#define __db_util_arg __db_util_arg@DB_VERSION_UNIQUE_NAME@ +#define __db_util_cache __db_util_cache@DB_VERSION_UNIQUE_NAME@ +#define __db_util_logset __db_util_logset@DB_VERSION_UNIQUE_NAME@ +#define __db_util_siginit __db_util_siginit@DB_VERSION_UNIQUE_NAME@ +#define __db_util_interrupted __db_util_interrupted@DB_VERSION_UNIQUE_NAME@ +#define __db_util_sigresend __db_util_sigresend@DB_VERSION_UNIQUE_NAME@ +#define __db_zero_fill __db_zero_fill@DB_VERSION_UNIQUE_NAME@ +#define __db_zero_extend __db_zero_extend@DB_VERSION_UNIQUE_NAME@ +#define __aes_setup __aes_setup@DB_VERSION_UNIQUE_NAME@ +#define __aes_adj_size __aes_adj_size@DB_VERSION_UNIQUE_NAME@ +#define __aes_close __aes_close@DB_VERSION_UNIQUE_NAME@ +#define __aes_decrypt __aes_decrypt@DB_VERSION_UNIQUE_NAME@ +#define __aes_encrypt __aes_encrypt@DB_VERSION_UNIQUE_NAME@ +#define __aes_init __aes_init@DB_VERSION_UNIQUE_NAME@ +#define __crypto_env_close __crypto_env_close@DB_VERSION_UNIQUE_NAME@ +#define __crypto_env_refresh __crypto_env_refresh@DB_VERSION_UNIQUE_NAME@ +#define __crypto_algsetup __crypto_algsetup@DB_VERSION_UNIQUE_NAME@ +#define __crypto_decrypt_meta __crypto_decrypt_meta@DB_VERSION_UNIQUE_NAME@ +#define __crypto_set_passwd __crypto_set_passwd@DB_VERSION_UNIQUE_NAME@ +#define __db_generate_iv __db_generate_iv@DB_VERSION_UNIQUE_NAME@ +#define __db_rijndaelKeySetupEnc __db_rijndaelKeySetupEnc@DB_VERSION_UNIQUE_NAME@ +#define __db_rijndaelKeySetupDec __db_rijndaelKeySetupDec@DB_VERSION_UNIQUE_NAME@ +#define __db_rijndaelEncrypt __db_rijndaelEncrypt@DB_VERSION_UNIQUE_NAME@ +#define __db_rijndaelDecrypt __db_rijndaelDecrypt@DB_VERSION_UNIQUE_NAME@ +#define __db_rijndaelEncryptRound __db_rijndaelEncryptRound@DB_VERSION_UNIQUE_NAME@ +#define __db_rijndaelDecryptRound __db_rijndaelDecryptRound@DB_VERSION_UNIQUE_NAME@ +#define __db_makeKey __db_makeKey@DB_VERSION_UNIQUE_NAME@ +#define __db_cipherInit __db_cipherInit@DB_VERSION_UNIQUE_NAME@ +#define __db_blockEncrypt __db_blockEncrypt@DB_VERSION_UNIQUE_NAME@ +#define __db_padEncrypt __db_padEncrypt@DB_VERSION_UNIQUE_NAME@ +#define __db_blockDecrypt __db_blockDecrypt@DB_VERSION_UNIQUE_NAME@ +#define __db_padDecrypt __db_padDecrypt@DB_VERSION_UNIQUE_NAME@ +#define __db_cipherUpdateRounds __db_cipherUpdateRounds@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_setup __dbreg_setup@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_teardown __dbreg_teardown@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_teardown_int __dbreg_teardown_int@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_new_id __dbreg_new_id@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_get_id __dbreg_get_id@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_assign_id __dbreg_assign_id@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_revoke_id __dbreg_revoke_id@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_revoke_id_int __dbreg_revoke_id_int@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_close_id __dbreg_close_id@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_close_id_int __dbreg_close_id_int@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_failchk __dbreg_failchk@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_log_close __dbreg_log_close@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_log_id __dbreg_log_id@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_register_read __dbreg_register_read@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_register_log __dbreg_register_log@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_init_recover __dbreg_init_recover@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_register_print __dbreg_register_print@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_init_print __dbreg_init_print@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_register_recover __dbreg_register_recover@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_stat_print __dbreg_stat_print@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_print_fname __dbreg_print_fname@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_add_dbentry __dbreg_add_dbentry@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_rem_dbentry __dbreg_rem_dbentry@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_log_files __dbreg_log_files@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_close_files __dbreg_close_files@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_close_file __dbreg_close_file@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_mark_restored __dbreg_mark_restored@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_invalidate_files __dbreg_invalidate_files@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_id_to_db __dbreg_id_to_db@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_id_to_fname __dbreg_id_to_fname@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_fid_to_fname __dbreg_fid_to_fname@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_get_name __dbreg_get_name@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_do_open __dbreg_do_open@DB_VERSION_UNIQUE_NAME@ +#define __dbreg_lazy_id __dbreg_lazy_id@DB_VERSION_UNIQUE_NAME@ +#define __env_alloc_init __env_alloc_init@DB_VERSION_UNIQUE_NAME@ +#define __env_alloc_overhead __env_alloc_overhead@DB_VERSION_UNIQUE_NAME@ +#define __env_alloc_size __env_alloc_size@DB_VERSION_UNIQUE_NAME@ +#define __env_alloc __env_alloc@DB_VERSION_UNIQUE_NAME@ +#define __env_alloc_free __env_alloc_free@DB_VERSION_UNIQUE_NAME@ +#define __env_alloc_print __env_alloc_print@DB_VERSION_UNIQUE_NAME@ +#define __env_read_db_config __env_read_db_config@DB_VERSION_UNIQUE_NAME@ +#define __config_split __config_split@DB_VERSION_UNIQUE_NAME@ +#define __env_failchk_pp __env_failchk_pp@DB_VERSION_UNIQUE_NAME@ +#define __env_failchk_int __env_failchk_int@DB_VERSION_UNIQUE_NAME@ +#define __env_thread_init __env_thread_init@DB_VERSION_UNIQUE_NAME@ +#define __env_thread_destroy __env_thread_destroy@DB_VERSION_UNIQUE_NAME@ +#define __env_set_state __env_set_state@DB_VERSION_UNIQUE_NAME@ +#define __env_thread_id_string __env_thread_id_string@DB_VERSION_UNIQUE_NAME@ +#define __db_file_extend __db_file_extend@DB_VERSION_UNIQUE_NAME@ +#define __db_file_multi_write __db_file_multi_write@DB_VERSION_UNIQUE_NAME@ +#define __db_file_write __db_file_write@DB_VERSION_UNIQUE_NAME@ +#define __db_env_destroy __db_env_destroy@DB_VERSION_UNIQUE_NAME@ +#define __env_get_alloc __env_get_alloc@DB_VERSION_UNIQUE_NAME@ +#define __env_set_alloc __env_set_alloc@DB_VERSION_UNIQUE_NAME@ +#define __env_get_encrypt_flags __env_get_encrypt_flags@DB_VERSION_UNIQUE_NAME@ +#define __env_set_encrypt __env_set_encrypt@DB_VERSION_UNIQUE_NAME@ +#define __env_map_flags __env_map_flags@DB_VERSION_UNIQUE_NAME@ +#define __env_fetch_flags __env_fetch_flags@DB_VERSION_UNIQUE_NAME@ +#define __env_set_flags __env_set_flags@DB_VERSION_UNIQUE_NAME@ +#define __env_set_data_dir __env_set_data_dir@DB_VERSION_UNIQUE_NAME@ +#define __env_add_data_dir __env_add_data_dir@DB_VERSION_UNIQUE_NAME@ +#define __env_set_create_dir __env_set_create_dir@DB_VERSION_UNIQUE_NAME@ +#define __env_set_intermediate_dir_mode __env_set_intermediate_dir_mode@DB_VERSION_UNIQUE_NAME@ +#define __env_get_errcall __env_get_errcall@DB_VERSION_UNIQUE_NAME@ +#define __env_set_errcall __env_set_errcall@DB_VERSION_UNIQUE_NAME@ +#define __env_get_errfile __env_get_errfile@DB_VERSION_UNIQUE_NAME@ +#define __env_set_errfile __env_set_errfile@DB_VERSION_UNIQUE_NAME@ +#define __env_get_errpfx __env_get_errpfx@DB_VERSION_UNIQUE_NAME@ +#define __env_set_errpfx __env_set_errpfx@DB_VERSION_UNIQUE_NAME@ +#define __env_set_thread_count __env_set_thread_count@DB_VERSION_UNIQUE_NAME@ +#define __env_get_msgcall __env_get_msgcall@DB_VERSION_UNIQUE_NAME@ +#define __env_set_msgcall __env_set_msgcall@DB_VERSION_UNIQUE_NAME@ +#define __env_get_msgfile __env_get_msgfile@DB_VERSION_UNIQUE_NAME@ +#define __env_set_msgfile __env_set_msgfile@DB_VERSION_UNIQUE_NAME@ +#define __env_set_paniccall __env_set_paniccall@DB_VERSION_UNIQUE_NAME@ +#define __env_set_shm_key __env_set_shm_key@DB_VERSION_UNIQUE_NAME@ +#define __env_set_tmp_dir __env_set_tmp_dir@DB_VERSION_UNIQUE_NAME@ +#define __env_set_verbose __env_set_verbose@DB_VERSION_UNIQUE_NAME@ +#define __db_mi_env __db_mi_env@DB_VERSION_UNIQUE_NAME@ +#define __db_mi_open __db_mi_open@DB_VERSION_UNIQUE_NAME@ +#define __env_not_config __env_not_config@DB_VERSION_UNIQUE_NAME@ +#define __env_set_timeout __env_set_timeout@DB_VERSION_UNIQUE_NAME@ +#define __db_appname __db_appname@DB_VERSION_UNIQUE_NAME@ +#define __db_tmp_open __db_tmp_open@DB_VERSION_UNIQUE_NAME@ +#define __env_open_pp __env_open_pp@DB_VERSION_UNIQUE_NAME@ +#define __env_open __env_open@DB_VERSION_UNIQUE_NAME@ +#define __env_remove __env_remove@DB_VERSION_UNIQUE_NAME@ +#define __env_config __env_config@DB_VERSION_UNIQUE_NAME@ +#define __env_close_pp __env_close_pp@DB_VERSION_UNIQUE_NAME@ +#define __env_close __env_close@DB_VERSION_UNIQUE_NAME@ +#define __env_refresh __env_refresh@DB_VERSION_UNIQUE_NAME@ +#define __env_get_open_flags __env_get_open_flags@DB_VERSION_UNIQUE_NAME@ +#define __env_attach_regions __env_attach_regions@DB_VERSION_UNIQUE_NAME@ +#define __db_apprec __db_apprec@DB_VERSION_UNIQUE_NAME@ +#define __log_backup __log_backup@DB_VERSION_UNIQUE_NAME@ +#define __env_openfiles __env_openfiles@DB_VERSION_UNIQUE_NAME@ +#define __env_init_rec __env_init_rec@DB_VERSION_UNIQUE_NAME@ +#define __env_attach __env_attach@DB_VERSION_UNIQUE_NAME@ +#define __env_turn_on __env_turn_on@DB_VERSION_UNIQUE_NAME@ +#define __env_turn_off __env_turn_off@DB_VERSION_UNIQUE_NAME@ +#define __env_panic_set __env_panic_set@DB_VERSION_UNIQUE_NAME@ +#define __env_ref_increment __env_ref_increment@DB_VERSION_UNIQUE_NAME@ +#define __env_ref_decrement __env_ref_decrement@DB_VERSION_UNIQUE_NAME@ +#define __env_detach __env_detach@DB_VERSION_UNIQUE_NAME@ +#define __env_remove_env __env_remove_env@DB_VERSION_UNIQUE_NAME@ +#define __env_region_attach __env_region_attach@DB_VERSION_UNIQUE_NAME@ +#define __env_region_detach __env_region_detach@DB_VERSION_UNIQUE_NAME@ +#define __envreg_register __envreg_register@DB_VERSION_UNIQUE_NAME@ +#define __envreg_unregister __envreg_unregister@DB_VERSION_UNIQUE_NAME@ +#define __envreg_xunlock __envreg_xunlock@DB_VERSION_UNIQUE_NAME@ +#define __env_struct_sig __env_struct_sig@DB_VERSION_UNIQUE_NAME@ +#define __env_stat_print_pp __env_stat_print_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_print_fh __db_print_fh@DB_VERSION_UNIQUE_NAME@ +#define __db_print_fileid __db_print_fileid@DB_VERSION_UNIQUE_NAME@ +#define __db_dl __db_dl@DB_VERSION_UNIQUE_NAME@ +#define __db_dl_pct __db_dl_pct@DB_VERSION_UNIQUE_NAME@ +#define __db_dlbytes __db_dlbytes@DB_VERSION_UNIQUE_NAME@ +#define __db_print_reginfo __db_print_reginfo@DB_VERSION_UNIQUE_NAME@ +#define __db_stat_not_built __db_stat_not_built@DB_VERSION_UNIQUE_NAME@ +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_close __repmgr_close@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_add_remote_site __repmgr_add_remote_site@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_get_ack_policy __repmgr_get_ack_policy@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_set_ack_policy __repmgr_set_ack_policy@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_set_local_site __repmgr_set_local_site@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_site_list __repmgr_site_list@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_start __repmgr_start@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_stat_pp __repmgr_stat_pp@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_stat_print_pp __repmgr_stat_print_pp@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_handle_event __repmgr_handle_event@DB_VERSION_UNIQUE_NAME@ +#endif +#define __fop_create_42_read __fop_create_42_read@DB_VERSION_UNIQUE_NAME@ +#define __fop_create_read __fop_create_read@DB_VERSION_UNIQUE_NAME@ +#define __fop_create_log __fop_create_log@DB_VERSION_UNIQUE_NAME@ +#define __fop_remove_read __fop_remove_read@DB_VERSION_UNIQUE_NAME@ +#define __fop_remove_log __fop_remove_log@DB_VERSION_UNIQUE_NAME@ +#define __fop_write_42_read __fop_write_42_read@DB_VERSION_UNIQUE_NAME@ +#define __fop_write_read __fop_write_read@DB_VERSION_UNIQUE_NAME@ +#define __fop_write_log __fop_write_log@DB_VERSION_UNIQUE_NAME@ +#define __fop_rename_42_read __fop_rename_42_read@DB_VERSION_UNIQUE_NAME@ +#define __fop_rename_read __fop_rename_read@DB_VERSION_UNIQUE_NAME@ +#define __fop_rename_log __fop_rename_log@DB_VERSION_UNIQUE_NAME@ +#define __fop_rename_noundo_log __fop_rename_noundo_log@DB_VERSION_UNIQUE_NAME@ +#define __fop_rename_int_log __fop_rename_int_log@DB_VERSION_UNIQUE_NAME@ +#define __fop_file_remove_read __fop_file_remove_read@DB_VERSION_UNIQUE_NAME@ +#define __fop_file_remove_log __fop_file_remove_log@DB_VERSION_UNIQUE_NAME@ +#define __fop_init_recover __fop_init_recover@DB_VERSION_UNIQUE_NAME@ +#define __fop_create_42_print __fop_create_42_print@DB_VERSION_UNIQUE_NAME@ +#define __fop_create_print __fop_create_print@DB_VERSION_UNIQUE_NAME@ +#define __fop_remove_print __fop_remove_print@DB_VERSION_UNIQUE_NAME@ +#define __fop_write_42_print __fop_write_42_print@DB_VERSION_UNIQUE_NAME@ +#define __fop_write_print __fop_write_print@DB_VERSION_UNIQUE_NAME@ +#define __fop_rename_42_print __fop_rename_42_print@DB_VERSION_UNIQUE_NAME@ +#define __fop_rename_print __fop_rename_print@DB_VERSION_UNIQUE_NAME@ +#define __fop_file_remove_print __fop_file_remove_print@DB_VERSION_UNIQUE_NAME@ +#define __fop_init_print __fop_init_print@DB_VERSION_UNIQUE_NAME@ +#define __fop_create __fop_create@DB_VERSION_UNIQUE_NAME@ +#define __fop_remove __fop_remove@DB_VERSION_UNIQUE_NAME@ +#define __fop_write __fop_write@DB_VERSION_UNIQUE_NAME@ +#define __fop_rename __fop_rename@DB_VERSION_UNIQUE_NAME@ +#define __fop_create_recover __fop_create_recover@DB_VERSION_UNIQUE_NAME@ +#define __fop_create_42_recover __fop_create_42_recover@DB_VERSION_UNIQUE_NAME@ +#define __fop_remove_recover __fop_remove_recover@DB_VERSION_UNIQUE_NAME@ +#define __fop_write_recover __fop_write_recover@DB_VERSION_UNIQUE_NAME@ +#define __fop_write_42_recover __fop_write_42_recover@DB_VERSION_UNIQUE_NAME@ +#define __fop_rename_recover __fop_rename_recover@DB_VERSION_UNIQUE_NAME@ +#define __fop_rename_noundo_recover __fop_rename_noundo_recover@DB_VERSION_UNIQUE_NAME@ +#define __fop_rename_42_recover __fop_rename_42_recover@DB_VERSION_UNIQUE_NAME@ +#define __fop_rename_noundo_46_recover __fop_rename_noundo_46_recover@DB_VERSION_UNIQUE_NAME@ +#define __fop_file_remove_recover __fop_file_remove_recover@DB_VERSION_UNIQUE_NAME@ +#define __fop_lock_handle __fop_lock_handle@DB_VERSION_UNIQUE_NAME@ +#define __fop_file_setup __fop_file_setup@DB_VERSION_UNIQUE_NAME@ +#define __fop_subdb_setup __fop_subdb_setup@DB_VERSION_UNIQUE_NAME@ +#define __fop_remove_setup __fop_remove_setup@DB_VERSION_UNIQUE_NAME@ +#define __fop_read_meta __fop_read_meta@DB_VERSION_UNIQUE_NAME@ +#define __fop_dummy __fop_dummy@DB_VERSION_UNIQUE_NAME@ +#define __fop_dbrename __fop_dbrename@DB_VERSION_UNIQUE_NAME@ +#define __ham_quick_delete __ham_quick_delete@DB_VERSION_UNIQUE_NAME@ +#define __hamc_init __hamc_init@DB_VERSION_UNIQUE_NAME@ +#define __hamc_count __hamc_count@DB_VERSION_UNIQUE_NAME@ +#define __hamc_cmp __hamc_cmp@DB_VERSION_UNIQUE_NAME@ +#define __hamc_dup __hamc_dup@DB_VERSION_UNIQUE_NAME@ +#define __ham_call_hash __ham_call_hash@DB_VERSION_UNIQUE_NAME@ +#define __ham_overwrite __ham_overwrite@DB_VERSION_UNIQUE_NAME@ +#define __ham_init_dbt __ham_init_dbt@DB_VERSION_UNIQUE_NAME@ +#define __hamc_update __hamc_update@DB_VERSION_UNIQUE_NAME@ +#define __ham_get_clist __ham_get_clist@DB_VERSION_UNIQUE_NAME@ +#define __ham_insdel_read __ham_insdel_read@DB_VERSION_UNIQUE_NAME@ +#define __ham_insdel_log __ham_insdel_log@DB_VERSION_UNIQUE_NAME@ +#define __ham_newpage_read __ham_newpage_read@DB_VERSION_UNIQUE_NAME@ +#define __ham_newpage_log __ham_newpage_log@DB_VERSION_UNIQUE_NAME@ +#define __ham_splitdata_read __ham_splitdata_read@DB_VERSION_UNIQUE_NAME@ +#define __ham_splitdata_log __ham_splitdata_log@DB_VERSION_UNIQUE_NAME@ +#define __ham_replace_read __ham_replace_read@DB_VERSION_UNIQUE_NAME@ +#define __ham_replace_log __ham_replace_log@DB_VERSION_UNIQUE_NAME@ +#define __ham_copypage_read __ham_copypage_read@DB_VERSION_UNIQUE_NAME@ +#define __ham_copypage_log __ham_copypage_log@DB_VERSION_UNIQUE_NAME@ +#define __ham_metagroup_42_read __ham_metagroup_42_read@DB_VERSION_UNIQUE_NAME@ +#define __ham_metagroup_read __ham_metagroup_read@DB_VERSION_UNIQUE_NAME@ +#define __ham_metagroup_log __ham_metagroup_log@DB_VERSION_UNIQUE_NAME@ +#define __ham_groupalloc_42_read __ham_groupalloc_42_read@DB_VERSION_UNIQUE_NAME@ +#define __ham_groupalloc_read __ham_groupalloc_read@DB_VERSION_UNIQUE_NAME@ +#define __ham_groupalloc_log __ham_groupalloc_log@DB_VERSION_UNIQUE_NAME@ +#define __ham_curadj_read __ham_curadj_read@DB_VERSION_UNIQUE_NAME@ +#define __ham_curadj_log __ham_curadj_log@DB_VERSION_UNIQUE_NAME@ +#define __ham_chgpg_read __ham_chgpg_read@DB_VERSION_UNIQUE_NAME@ +#define __ham_chgpg_log __ham_chgpg_log@DB_VERSION_UNIQUE_NAME@ +#define __ham_init_recover __ham_init_recover@DB_VERSION_UNIQUE_NAME@ +#define __ham_insdel_print __ham_insdel_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_newpage_print __ham_newpage_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_splitdata_print __ham_splitdata_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_replace_print __ham_replace_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_copypage_print __ham_copypage_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_metagroup_42_print __ham_metagroup_42_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_metagroup_print __ham_metagroup_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_groupalloc_42_print __ham_groupalloc_42_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_groupalloc_print __ham_groupalloc_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_curadj_print __ham_curadj_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_chgpg_print __ham_chgpg_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_init_print __ham_init_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_pgin __ham_pgin@DB_VERSION_UNIQUE_NAME@ +#define __ham_pgout __ham_pgout@DB_VERSION_UNIQUE_NAME@ +#define __ham_mswap __ham_mswap@DB_VERSION_UNIQUE_NAME@ +#define __ham_add_dup __ham_add_dup@DB_VERSION_UNIQUE_NAME@ +#define __ham_dup_convert __ham_dup_convert@DB_VERSION_UNIQUE_NAME@ +#define __ham_make_dup __ham_make_dup@DB_VERSION_UNIQUE_NAME@ +#define __ham_dsearch __ham_dsearch@DB_VERSION_UNIQUE_NAME@ +#define __ham_func2 __ham_func2@DB_VERSION_UNIQUE_NAME@ +#define __ham_func3 __ham_func3@DB_VERSION_UNIQUE_NAME@ +#define __ham_func4 __ham_func4@DB_VERSION_UNIQUE_NAME@ +#define __ham_func5 __ham_func5@DB_VERSION_UNIQUE_NAME@ +#define __ham_test __ham_test@DB_VERSION_UNIQUE_NAME@ +#define __ham_get_meta __ham_get_meta@DB_VERSION_UNIQUE_NAME@ +#define __ham_release_meta __ham_release_meta@DB_VERSION_UNIQUE_NAME@ +#define __ham_dirty_meta __ham_dirty_meta@DB_VERSION_UNIQUE_NAME@ +#define __ham_return_meta __ham_return_meta@DB_VERSION_UNIQUE_NAME@ +#define __ham_db_create __ham_db_create@DB_VERSION_UNIQUE_NAME@ +#define __ham_db_close __ham_db_close@DB_VERSION_UNIQUE_NAME@ +#define __ham_get_h_ffactor __ham_get_h_ffactor@DB_VERSION_UNIQUE_NAME@ +#define __ham_set_h_compare __ham_set_h_compare@DB_VERSION_UNIQUE_NAME@ +#define __ham_get_h_nelem __ham_get_h_nelem@DB_VERSION_UNIQUE_NAME@ +#define __ham_copy_config __ham_copy_config@DB_VERSION_UNIQUE_NAME@ +#define __ham_open __ham_open@DB_VERSION_UNIQUE_NAME@ +#define __ham_metachk __ham_metachk@DB_VERSION_UNIQUE_NAME@ +#define __ham_new_file __ham_new_file@DB_VERSION_UNIQUE_NAME@ +#define __ham_new_subdb __ham_new_subdb@DB_VERSION_UNIQUE_NAME@ +#define __ham_item __ham_item@DB_VERSION_UNIQUE_NAME@ +#define __ham_item_reset __ham_item_reset@DB_VERSION_UNIQUE_NAME@ +#define __ham_item_init __ham_item_init@DB_VERSION_UNIQUE_NAME@ +#define __ham_item_last __ham_item_last@DB_VERSION_UNIQUE_NAME@ +#define __ham_item_first __ham_item_first@DB_VERSION_UNIQUE_NAME@ +#define __ham_item_prev __ham_item_prev@DB_VERSION_UNIQUE_NAME@ +#define __ham_item_next __ham_item_next@DB_VERSION_UNIQUE_NAME@ +#define __ham_insertpair __ham_insertpair@DB_VERSION_UNIQUE_NAME@ +#define __ham_getindex __ham_getindex@DB_VERSION_UNIQUE_NAME@ +#define __ham_verify_sorted_page __ham_verify_sorted_page@DB_VERSION_UNIQUE_NAME@ +#define __ham_sort_page __ham_sort_page@DB_VERSION_UNIQUE_NAME@ +#define __ham_del_pair __ham_del_pair@DB_VERSION_UNIQUE_NAME@ +#define __ham_replpair __ham_replpair@DB_VERSION_UNIQUE_NAME@ +#define __ham_onpage_replace __ham_onpage_replace@DB_VERSION_UNIQUE_NAME@ +#define __ham_split_page __ham_split_page@DB_VERSION_UNIQUE_NAME@ +#define __ham_add_el __ham_add_el@DB_VERSION_UNIQUE_NAME@ +#define __ham_copypair __ham_copypair@DB_VERSION_UNIQUE_NAME@ +#define __ham_add_ovflpage __ham_add_ovflpage@DB_VERSION_UNIQUE_NAME@ +#define __ham_get_cpage __ham_get_cpage@DB_VERSION_UNIQUE_NAME@ +#define __ham_next_cpage __ham_next_cpage@DB_VERSION_UNIQUE_NAME@ +#define __ham_lock_bucket __ham_lock_bucket@DB_VERSION_UNIQUE_NAME@ +#define __ham_dpair __ham_dpair@DB_VERSION_UNIQUE_NAME@ +#define __ham_insdel_recover __ham_insdel_recover@DB_VERSION_UNIQUE_NAME@ +#define __ham_newpage_recover __ham_newpage_recover@DB_VERSION_UNIQUE_NAME@ +#define __ham_replace_recover __ham_replace_recover@DB_VERSION_UNIQUE_NAME@ +#define __ham_splitdata_recover __ham_splitdata_recover@DB_VERSION_UNIQUE_NAME@ +#define __ham_copypage_recover __ham_copypage_recover@DB_VERSION_UNIQUE_NAME@ +#define __ham_metagroup_recover __ham_metagroup_recover@DB_VERSION_UNIQUE_NAME@ +#define __ham_groupalloc_recover __ham_groupalloc_recover@DB_VERSION_UNIQUE_NAME@ +#define __ham_curadj_recover __ham_curadj_recover@DB_VERSION_UNIQUE_NAME@ +#define __ham_chgpg_recover __ham_chgpg_recover@DB_VERSION_UNIQUE_NAME@ +#define __ham_metagroup_42_recover __ham_metagroup_42_recover@DB_VERSION_UNIQUE_NAME@ +#define __ham_groupalloc_42_recover __ham_groupalloc_42_recover@DB_VERSION_UNIQUE_NAME@ +#define __ham_reclaim __ham_reclaim@DB_VERSION_UNIQUE_NAME@ +#define __ham_truncate __ham_truncate@DB_VERSION_UNIQUE_NAME@ +#define __ham_stat __ham_stat@DB_VERSION_UNIQUE_NAME@ +#define __ham_stat_print __ham_stat_print@DB_VERSION_UNIQUE_NAME@ +#define __ham_print_cursor __ham_print_cursor@DB_VERSION_UNIQUE_NAME@ +#define __ham_traverse __ham_traverse@DB_VERSION_UNIQUE_NAME@ +#define __db_no_hash_am __db_no_hash_am@DB_VERSION_UNIQUE_NAME@ +#define __ham_30_hashmeta __ham_30_hashmeta@DB_VERSION_UNIQUE_NAME@ +#define __ham_30_sizefix __ham_30_sizefix@DB_VERSION_UNIQUE_NAME@ +#define __ham_31_hashmeta __ham_31_hashmeta@DB_VERSION_UNIQUE_NAME@ +#define __ham_31_hash __ham_31_hash@DB_VERSION_UNIQUE_NAME@ +#define __ham_46_hashmeta __ham_46_hashmeta@DB_VERSION_UNIQUE_NAME@ +#define __ham_46_hash __ham_46_hash@DB_VERSION_UNIQUE_NAME@ +#define __ham_vrfy_meta __ham_vrfy_meta@DB_VERSION_UNIQUE_NAME@ +#define __ham_vrfy __ham_vrfy@DB_VERSION_UNIQUE_NAME@ +#define __ham_vrfy_structure __ham_vrfy_structure@DB_VERSION_UNIQUE_NAME@ +#define __ham_vrfy_hashing __ham_vrfy_hashing@DB_VERSION_UNIQUE_NAME@ +#define __ham_salvage __ham_salvage@DB_VERSION_UNIQUE_NAME@ +#define __ham_meta2pgset __ham_meta2pgset@DB_VERSION_UNIQUE_NAME@ +#define __db_chksum __db_chksum@DB_VERSION_UNIQUE_NAME@ +#define __db_derive_mac __db_derive_mac@DB_VERSION_UNIQUE_NAME@ +#define __db_check_chksum __db_check_chksum@DB_VERSION_UNIQUE_NAME@ +#define __db_SHA1Transform __db_SHA1Transform@DB_VERSION_UNIQUE_NAME@ +#define __db_SHA1Init __db_SHA1Init@DB_VERSION_UNIQUE_NAME@ +#define __db_SHA1Update __db_SHA1Update@DB_VERSION_UNIQUE_NAME@ +#define __db_SHA1Final __db_SHA1Final@DB_VERSION_UNIQUE_NAME@ +#define __lock_vec_pp __lock_vec_pp@DB_VERSION_UNIQUE_NAME@ +#define __lock_vec __lock_vec@DB_VERSION_UNIQUE_NAME@ +#define __lock_get_pp __lock_get_pp@DB_VERSION_UNIQUE_NAME@ +#define __lock_get __lock_get@DB_VERSION_UNIQUE_NAME@ +#define __lock_get_internal __lock_get_internal@DB_VERSION_UNIQUE_NAME@ +#define __lock_put_pp __lock_put_pp@DB_VERSION_UNIQUE_NAME@ +#define __lock_put __lock_put@DB_VERSION_UNIQUE_NAME@ +#define __lock_downgrade __lock_downgrade@DB_VERSION_UNIQUE_NAME@ +#define __lock_locker_is_parent __lock_locker_is_parent@DB_VERSION_UNIQUE_NAME@ +#define __lock_promote __lock_promote@DB_VERSION_UNIQUE_NAME@ +#define __lock_detect_pp __lock_detect_pp@DB_VERSION_UNIQUE_NAME@ +#define __lock_detect __lock_detect@DB_VERSION_UNIQUE_NAME@ +#define __lock_failchk __lock_failchk@DB_VERSION_UNIQUE_NAME@ +#define __lock_id_pp __lock_id_pp@DB_VERSION_UNIQUE_NAME@ +#define __lock_id __lock_id@DB_VERSION_UNIQUE_NAME@ +#define __lock_set_thread_id __lock_set_thread_id@DB_VERSION_UNIQUE_NAME@ +#define __lock_id_free_pp __lock_id_free_pp@DB_VERSION_UNIQUE_NAME@ +#define __lock_id_free __lock_id_free@DB_VERSION_UNIQUE_NAME@ +#define __lock_id_set __lock_id_set@DB_VERSION_UNIQUE_NAME@ +#define __lock_getlocker __lock_getlocker@DB_VERSION_UNIQUE_NAME@ +#define __lock_getlocker_int __lock_getlocker_int@DB_VERSION_UNIQUE_NAME@ +#define __lock_addfamilylocker __lock_addfamilylocker@DB_VERSION_UNIQUE_NAME@ +#define __lock_freefamilylocker __lock_freefamilylocker@DB_VERSION_UNIQUE_NAME@ +#define __lock_freelocker __lock_freelocker@DB_VERSION_UNIQUE_NAME@ +#define __lock_fix_list __lock_fix_list@DB_VERSION_UNIQUE_NAME@ +#define __lock_get_list __lock_get_list@DB_VERSION_UNIQUE_NAME@ +#define __lock_list_print __lock_list_print@DB_VERSION_UNIQUE_NAME@ +#define __lock_env_create __lock_env_create@DB_VERSION_UNIQUE_NAME@ +#define __lock_env_destroy __lock_env_destroy@DB_VERSION_UNIQUE_NAME@ +#define __lock_get_lk_conflicts __lock_get_lk_conflicts@DB_VERSION_UNIQUE_NAME@ +#define __lock_set_lk_conflicts __lock_set_lk_conflicts@DB_VERSION_UNIQUE_NAME@ +#define __lock_get_lk_detect __lock_get_lk_detect@DB_VERSION_UNIQUE_NAME@ +#define __lock_set_lk_detect __lock_set_lk_detect@DB_VERSION_UNIQUE_NAME@ +#define __lock_get_lk_max_locks __lock_get_lk_max_locks@DB_VERSION_UNIQUE_NAME@ +#define __lock_set_lk_max_locks __lock_set_lk_max_locks@DB_VERSION_UNIQUE_NAME@ +#define __lock_get_lk_max_lockers __lock_get_lk_max_lockers@DB_VERSION_UNIQUE_NAME@ +#define __lock_set_lk_max_lockers __lock_set_lk_max_lockers@DB_VERSION_UNIQUE_NAME@ +#define __lock_get_lk_max_objects __lock_get_lk_max_objects@DB_VERSION_UNIQUE_NAME@ +#define __lock_set_lk_max_objects __lock_set_lk_max_objects@DB_VERSION_UNIQUE_NAME@ +#define __lock_get_lk_partitions __lock_get_lk_partitions@DB_VERSION_UNIQUE_NAME@ +#define __lock_set_lk_partitions __lock_set_lk_partitions@DB_VERSION_UNIQUE_NAME@ +#define __lock_get_env_timeout __lock_get_env_timeout@DB_VERSION_UNIQUE_NAME@ +#define __lock_set_env_timeout __lock_set_env_timeout@DB_VERSION_UNIQUE_NAME@ +#define __lock_open __lock_open@DB_VERSION_UNIQUE_NAME@ +#define __lock_env_refresh __lock_env_refresh@DB_VERSION_UNIQUE_NAME@ +#define __lock_region_mutex_count __lock_region_mutex_count@DB_VERSION_UNIQUE_NAME@ +#define __lock_stat_pp __lock_stat_pp@DB_VERSION_UNIQUE_NAME@ +#define __lock_stat_print_pp __lock_stat_print_pp@DB_VERSION_UNIQUE_NAME@ +#define __lock_stat_print __lock_stat_print@DB_VERSION_UNIQUE_NAME@ +#define __lock_printlock __lock_printlock@DB_VERSION_UNIQUE_NAME@ +#define __lock_set_timeout __lock_set_timeout@DB_VERSION_UNIQUE_NAME@ +#define __lock_set_timeout_internal __lock_set_timeout_internal@DB_VERSION_UNIQUE_NAME@ +#define __lock_inherit_timeout __lock_inherit_timeout@DB_VERSION_UNIQUE_NAME@ +#define __lock_expires __lock_expires@DB_VERSION_UNIQUE_NAME@ +#define __lock_expired __lock_expired@DB_VERSION_UNIQUE_NAME@ +#define __lock_ohash __lock_ohash@DB_VERSION_UNIQUE_NAME@ +#define __lock_lhash __lock_lhash@DB_VERSION_UNIQUE_NAME@ +#define __lock_nomem __lock_nomem@DB_VERSION_UNIQUE_NAME@ +#define __log_open __log_open@DB_VERSION_UNIQUE_NAME@ +#define __log_find __log_find@DB_VERSION_UNIQUE_NAME@ +#define __log_valid __log_valid@DB_VERSION_UNIQUE_NAME@ +#define __log_env_refresh __log_env_refresh@DB_VERSION_UNIQUE_NAME@ +#define __log_get_cached_ckp_lsn __log_get_cached_ckp_lsn@DB_VERSION_UNIQUE_NAME@ +#define __log_region_mutex_count __log_region_mutex_count@DB_VERSION_UNIQUE_NAME@ +#define __log_vtruncate __log_vtruncate@DB_VERSION_UNIQUE_NAME@ +#define __log_is_outdated __log_is_outdated@DB_VERSION_UNIQUE_NAME@ +#define __log_zero __log_zero@DB_VERSION_UNIQUE_NAME@ +#define __log_inmem_lsnoff __log_inmem_lsnoff@DB_VERSION_UNIQUE_NAME@ +#define __log_inmem_newfile __log_inmem_newfile@DB_VERSION_UNIQUE_NAME@ +#define __log_inmem_chkspace __log_inmem_chkspace@DB_VERSION_UNIQUE_NAME@ +#define __log_inmem_copyout __log_inmem_copyout@DB_VERSION_UNIQUE_NAME@ +#define __log_inmem_copyin __log_inmem_copyin@DB_VERSION_UNIQUE_NAME@ +#define __log_set_version __log_set_version@DB_VERSION_UNIQUE_NAME@ +#define __log_get_oldversion __log_get_oldversion@DB_VERSION_UNIQUE_NAME@ +#define __log_archive_pp __log_archive_pp@DB_VERSION_UNIQUE_NAME@ +#define __log_get_stable_lsn __log_get_stable_lsn@DB_VERSION_UNIQUE_NAME@ +#define __log_autoremove __log_autoremove@DB_VERSION_UNIQUE_NAME@ +#define __log_check_page_lsn __log_check_page_lsn@DB_VERSION_UNIQUE_NAME@ +#define __log_printf_capi __log_printf_capi@DB_VERSION_UNIQUE_NAME@ +#define __log_printf_pp __log_printf_pp@DB_VERSION_UNIQUE_NAME@ +#define __log_printf __log_printf@DB_VERSION_UNIQUE_NAME@ +#define __log_cursor_pp __log_cursor_pp@DB_VERSION_UNIQUE_NAME@ +#define __log_cursor __log_cursor@DB_VERSION_UNIQUE_NAME@ +#define __logc_close __logc_close@DB_VERSION_UNIQUE_NAME@ +#define __logc_version __logc_version@DB_VERSION_UNIQUE_NAME@ +#define __logc_get __logc_get@DB_VERSION_UNIQUE_NAME@ +#define __log_hdrswap __log_hdrswap@DB_VERSION_UNIQUE_NAME@ +#define __log_persistswap __log_persistswap@DB_VERSION_UNIQUE_NAME@ +#define __log_rep_split __log_rep_split@DB_VERSION_UNIQUE_NAME@ +#define __log_env_create __log_env_create@DB_VERSION_UNIQUE_NAME@ +#define __log_env_destroy __log_env_destroy@DB_VERSION_UNIQUE_NAME@ +#define __log_get_lg_bsize __log_get_lg_bsize@DB_VERSION_UNIQUE_NAME@ +#define __log_set_lg_bsize __log_set_lg_bsize@DB_VERSION_UNIQUE_NAME@ +#define __log_get_lg_filemode __log_get_lg_filemode@DB_VERSION_UNIQUE_NAME@ +#define __log_set_lg_filemode __log_set_lg_filemode@DB_VERSION_UNIQUE_NAME@ +#define __log_get_lg_max __log_get_lg_max@DB_VERSION_UNIQUE_NAME@ +#define __log_set_lg_max __log_set_lg_max@DB_VERSION_UNIQUE_NAME@ +#define __log_get_lg_regionmax __log_get_lg_regionmax@DB_VERSION_UNIQUE_NAME@ +#define __log_set_lg_regionmax __log_set_lg_regionmax@DB_VERSION_UNIQUE_NAME@ +#define __log_get_lg_dir __log_get_lg_dir@DB_VERSION_UNIQUE_NAME@ +#define __log_set_lg_dir __log_set_lg_dir@DB_VERSION_UNIQUE_NAME@ +#define __log_get_flags __log_get_flags@DB_VERSION_UNIQUE_NAME@ +#define __log_set_flags __log_set_flags@DB_VERSION_UNIQUE_NAME@ +#define __log_get_config __log_get_config@DB_VERSION_UNIQUE_NAME@ +#define __log_set_config __log_set_config@DB_VERSION_UNIQUE_NAME@ +#define __log_set_config_int __log_set_config_int@DB_VERSION_UNIQUE_NAME@ +#define __log_check_sizes __log_check_sizes@DB_VERSION_UNIQUE_NAME@ +#define __log_put_pp __log_put_pp@DB_VERSION_UNIQUE_NAME@ +#define __log_put __log_put@DB_VERSION_UNIQUE_NAME@ +#define __log_current_lsn __log_current_lsn@DB_VERSION_UNIQUE_NAME@ +#define __log_newfile __log_newfile@DB_VERSION_UNIQUE_NAME@ +#define __log_flush_pp __log_flush_pp@DB_VERSION_UNIQUE_NAME@ +#define __log_flush __log_flush@DB_VERSION_UNIQUE_NAME@ +#define __log_flush_int __log_flush_int@DB_VERSION_UNIQUE_NAME@ +#define __log_file_pp __log_file_pp@DB_VERSION_UNIQUE_NAME@ +#define __log_name __log_name@DB_VERSION_UNIQUE_NAME@ +#define __log_rep_put __log_rep_put@DB_VERSION_UNIQUE_NAME@ +#define __log_stat_pp __log_stat_pp@DB_VERSION_UNIQUE_NAME@ +#define __log_stat_print_pp __log_stat_print_pp@DB_VERSION_UNIQUE_NAME@ +#define __log_stat_print __log_stat_print@DB_VERSION_UNIQUE_NAME@ +#define __memp_alloc __memp_alloc@DB_VERSION_UNIQUE_NAME@ +#define __memp_free __memp_free@DB_VERSION_UNIQUE_NAME@ +#define __memp_bhwrite __memp_bhwrite@DB_VERSION_UNIQUE_NAME@ +#define __memp_pgread __memp_pgread@DB_VERSION_UNIQUE_NAME@ +#define __memp_pg __memp_pg@DB_VERSION_UNIQUE_NAME@ +#define __memp_bhfree __memp_bhfree@DB_VERSION_UNIQUE_NAME@ +#define __memp_fget_pp __memp_fget_pp@DB_VERSION_UNIQUE_NAME@ +#define __memp_fget __memp_fget@DB_VERSION_UNIQUE_NAME@ +#define __memp_fcreate_pp __memp_fcreate_pp@DB_VERSION_UNIQUE_NAME@ +#define __memp_fcreate __memp_fcreate@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_clear_len __memp_set_clear_len@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_fileid __memp_get_fileid@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_fileid __memp_set_fileid@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_flags __memp_get_flags@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_flags __memp_set_flags@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_ftype __memp_get_ftype@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_ftype __memp_set_ftype@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_lsn_offset __memp_set_lsn_offset@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_pgcookie __memp_get_pgcookie@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_pgcookie __memp_set_pgcookie@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_last_pgno __memp_get_last_pgno@DB_VERSION_UNIQUE_NAME@ +#define __memp_fn __memp_fn@DB_VERSION_UNIQUE_NAME@ +#define __memp_fns __memp_fns@DB_VERSION_UNIQUE_NAME@ +#define __memp_fopen_pp __memp_fopen_pp@DB_VERSION_UNIQUE_NAME@ +#define __memp_fopen __memp_fopen@DB_VERSION_UNIQUE_NAME@ +#define __memp_fclose_pp __memp_fclose_pp@DB_VERSION_UNIQUE_NAME@ +#define __memp_fclose __memp_fclose@DB_VERSION_UNIQUE_NAME@ +#define __memp_mf_discard __memp_mf_discard@DB_VERSION_UNIQUE_NAME@ +#define __memp_inmemlist __memp_inmemlist@DB_VERSION_UNIQUE_NAME@ +#define __memp_fput_pp __memp_fput_pp@DB_VERSION_UNIQUE_NAME@ +#define __memp_fput __memp_fput@DB_VERSION_UNIQUE_NAME@ +#define __memp_unpin_buffers __memp_unpin_buffers@DB_VERSION_UNIQUE_NAME@ +#define __memp_dirty __memp_dirty@DB_VERSION_UNIQUE_NAME@ +#define __memp_shared __memp_shared@DB_VERSION_UNIQUE_NAME@ +#define __memp_env_create __memp_env_create@DB_VERSION_UNIQUE_NAME@ +#define __memp_env_destroy __memp_env_destroy@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_cachesize __memp_get_cachesize@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_cachesize __memp_set_cachesize@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_config __memp_set_config@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_config __memp_get_config@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_mp_max_openfd __memp_get_mp_max_openfd@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_mp_max_openfd __memp_set_mp_max_openfd@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_mp_max_write __memp_get_mp_max_write@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_mp_max_write __memp_set_mp_max_write@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_mp_mmapsize __memp_get_mp_mmapsize@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_mp_mmapsize __memp_set_mp_mmapsize@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_mp_pagesize __memp_get_mp_pagesize@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_mp_pagesize __memp_set_mp_pagesize@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_mp_tablesize __memp_get_mp_tablesize@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_mp_tablesize __memp_set_mp_tablesize@DB_VERSION_UNIQUE_NAME@ +#define __memp_nameop __memp_nameop@DB_VERSION_UNIQUE_NAME@ +#define __memp_ftruncate __memp_ftruncate@DB_VERSION_UNIQUE_NAME@ +#define __memp_alloc_freelist __memp_alloc_freelist@DB_VERSION_UNIQUE_NAME@ +#define __memp_free_freelist __memp_free_freelist@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_freelist __memp_get_freelist@DB_VERSION_UNIQUE_NAME@ +#define __memp_extend_freelist __memp_extend_freelist@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_last_pgno __memp_set_last_pgno@DB_VERSION_UNIQUE_NAME@ +#define __memp_bh_settxn __memp_bh_settxn@DB_VERSION_UNIQUE_NAME@ +#define __memp_skip_curadj __memp_skip_curadj@DB_VERSION_UNIQUE_NAME@ +#define __memp_bh_freeze __memp_bh_freeze@DB_VERSION_UNIQUE_NAME@ +#define __memp_bh_thaw __memp_bh_thaw@DB_VERSION_UNIQUE_NAME@ +#define __memp_open __memp_open@DB_VERSION_UNIQUE_NAME@ +#define __memp_init __memp_init@DB_VERSION_UNIQUE_NAME@ +#define __memp_max_regions __memp_max_regions@DB_VERSION_UNIQUE_NAME@ +#define __memp_region_mutex_count __memp_region_mutex_count@DB_VERSION_UNIQUE_NAME@ +#define __memp_env_refresh __memp_env_refresh@DB_VERSION_UNIQUE_NAME@ +#define __memp_register_pp __memp_register_pp@DB_VERSION_UNIQUE_NAME@ +#define __memp_register __memp_register@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_bucket __memp_get_bucket@DB_VERSION_UNIQUE_NAME@ +#define __memp_resize __memp_resize@DB_VERSION_UNIQUE_NAME@ +#define __memp_get_cache_max __memp_get_cache_max@DB_VERSION_UNIQUE_NAME@ +#define __memp_set_cache_max __memp_set_cache_max@DB_VERSION_UNIQUE_NAME@ +#define __memp_stat_pp __memp_stat_pp@DB_VERSION_UNIQUE_NAME@ +#define __memp_stat_print_pp __memp_stat_print_pp@DB_VERSION_UNIQUE_NAME@ +#define __memp_stat_print __memp_stat_print@DB_VERSION_UNIQUE_NAME@ +#define __memp_stat_hash __memp_stat_hash@DB_VERSION_UNIQUE_NAME@ +#define __memp_walk_files __memp_walk_files@DB_VERSION_UNIQUE_NAME@ +#define __memp_sync_pp __memp_sync_pp@DB_VERSION_UNIQUE_NAME@ +#define __memp_sync __memp_sync@DB_VERSION_UNIQUE_NAME@ +#define __memp_fsync_pp __memp_fsync_pp@DB_VERSION_UNIQUE_NAME@ +#define __memp_fsync __memp_fsync@DB_VERSION_UNIQUE_NAME@ +#define __mp_xxx_fh __mp_xxx_fh@DB_VERSION_UNIQUE_NAME@ +#define __memp_sync_int __memp_sync_int@DB_VERSION_UNIQUE_NAME@ +#define __memp_mf_sync __memp_mf_sync@DB_VERSION_UNIQUE_NAME@ +#define __memp_trickle_pp __memp_trickle_pp@DB_VERSION_UNIQUE_NAME@ +#define __mutex_alloc __mutex_alloc@DB_VERSION_UNIQUE_NAME@ +#define __mutex_alloc_int __mutex_alloc_int@DB_VERSION_UNIQUE_NAME@ +#define __mutex_free __mutex_free@DB_VERSION_UNIQUE_NAME@ +#define __mutex_free_int __mutex_free_int@DB_VERSION_UNIQUE_NAME@ +#define __mut_failchk __mut_failchk@DB_VERSION_UNIQUE_NAME@ +#define __db_fcntl_mutex_init __db_fcntl_mutex_init@DB_VERSION_UNIQUE_NAME@ +#define __db_fcntl_mutex_lock __db_fcntl_mutex_lock@DB_VERSION_UNIQUE_NAME@ +#define __db_fcntl_mutex_trylock __db_fcntl_mutex_trylock@DB_VERSION_UNIQUE_NAME@ +#define __db_fcntl_mutex_unlock __db_fcntl_mutex_unlock@DB_VERSION_UNIQUE_NAME@ +#define __db_fcntl_mutex_destroy __db_fcntl_mutex_destroy@DB_VERSION_UNIQUE_NAME@ +#define __mutex_alloc_pp __mutex_alloc_pp@DB_VERSION_UNIQUE_NAME@ +#define __mutex_free_pp __mutex_free_pp@DB_VERSION_UNIQUE_NAME@ +#define __mutex_lock_pp __mutex_lock_pp@DB_VERSION_UNIQUE_NAME@ +#define __mutex_unlock_pp __mutex_unlock_pp@DB_VERSION_UNIQUE_NAME@ +#define __mutex_get_align __mutex_get_align@DB_VERSION_UNIQUE_NAME@ +#define __mutex_set_align __mutex_set_align@DB_VERSION_UNIQUE_NAME@ +#define __mutex_get_increment __mutex_get_increment@DB_VERSION_UNIQUE_NAME@ +#define __mutex_set_increment __mutex_set_increment@DB_VERSION_UNIQUE_NAME@ +#define __mutex_get_max __mutex_get_max@DB_VERSION_UNIQUE_NAME@ +#define __mutex_set_max __mutex_set_max@DB_VERSION_UNIQUE_NAME@ +#define __mutex_get_tas_spins __mutex_get_tas_spins@DB_VERSION_UNIQUE_NAME@ +#define __mutex_set_tas_spins __mutex_set_tas_spins@DB_VERSION_UNIQUE_NAME@ +#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT) +#define __atomic_inc __atomic_inc@DB_VERSION_UNIQUE_NAME@ +#endif +#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT) +#define __atomic_dec __atomic_dec@DB_VERSION_UNIQUE_NAME@ +#endif +#define __db_pthread_mutex_init __db_pthread_mutex_init@DB_VERSION_UNIQUE_NAME@ +#define __db_pthread_mutex_lock __db_pthread_mutex_lock@DB_VERSION_UNIQUE_NAME@ +#if defined(HAVE_SHARED_LATCHES) +#define __db_pthread_mutex_readlock __db_pthread_mutex_readlock@DB_VERSION_UNIQUE_NAME@ +#endif +#define __db_pthread_mutex_unlock __db_pthread_mutex_unlock@DB_VERSION_UNIQUE_NAME@ +#define __db_pthread_mutex_destroy __db_pthread_mutex_destroy@DB_VERSION_UNIQUE_NAME@ +#define __mutex_open __mutex_open@DB_VERSION_UNIQUE_NAME@ +#define __mutex_env_refresh __mutex_env_refresh@DB_VERSION_UNIQUE_NAME@ +#define __mutex_resource_return __mutex_resource_return@DB_VERSION_UNIQUE_NAME@ +#define __mutex_stat_pp __mutex_stat_pp@DB_VERSION_UNIQUE_NAME@ +#define __mutex_stat_print_pp __mutex_stat_print_pp@DB_VERSION_UNIQUE_NAME@ +#define __mutex_stat_print __mutex_stat_print@DB_VERSION_UNIQUE_NAME@ +#define __mutex_print_debug_single __mutex_print_debug_single@DB_VERSION_UNIQUE_NAME@ +#define __mutex_print_debug_stats __mutex_print_debug_stats@DB_VERSION_UNIQUE_NAME@ +#define __mutex_set_wait_info __mutex_set_wait_info@DB_VERSION_UNIQUE_NAME@ +#define __mutex_clear __mutex_clear@DB_VERSION_UNIQUE_NAME@ +#define __db_tas_mutex_init __db_tas_mutex_init@DB_VERSION_UNIQUE_NAME@ +#define __db_tas_mutex_lock __db_tas_mutex_lock@DB_VERSION_UNIQUE_NAME@ +#define __db_tas_mutex_trylock __db_tas_mutex_trylock@DB_VERSION_UNIQUE_NAME@ +#if defined(HAVE_SHARED_LATCHES) +#define __db_tas_mutex_readlock __db_tas_mutex_readlock@DB_VERSION_UNIQUE_NAME@ +#endif +#if defined(HAVE_SHARED_LATCHES) +#define __db_tas_mutex_tryreadlock __db_tas_mutex_tryreadlock@DB_VERSION_UNIQUE_NAME@ +#endif +#define __db_tas_mutex_unlock __db_tas_mutex_unlock@DB_VERSION_UNIQUE_NAME@ +#define __db_tas_mutex_destroy __db_tas_mutex_destroy@DB_VERSION_UNIQUE_NAME@ +#define __db_win32_mutex_init __db_win32_mutex_init@DB_VERSION_UNIQUE_NAME@ +#define __db_win32_mutex_lock __db_win32_mutex_lock@DB_VERSION_UNIQUE_NAME@ +#define __db_win32_mutex_trylock __db_win32_mutex_trylock@DB_VERSION_UNIQUE_NAME@ +#if defined(HAVE_SHARED_LATCHES) +#define __db_win32_mutex_readlock __db_win32_mutex_readlock@DB_VERSION_UNIQUE_NAME@ +#endif +#if defined(HAVE_SHARED_LATCHES) +#define __db_win32_mutex_tryreadlock __db_win32_mutex_tryreadlock@DB_VERSION_UNIQUE_NAME@ +#endif +#define __db_win32_mutex_unlock __db_win32_mutex_unlock@DB_VERSION_UNIQUE_NAME@ +#define __db_win32_mutex_destroy __db_win32_mutex_destroy@DB_VERSION_UNIQUE_NAME@ +#define __os_abort __os_abort@DB_VERSION_UNIQUE_NAME@ +#define __os_abspath __os_abspath@DB_VERSION_UNIQUE_NAME@ +#if defined(HAVE_REPLICATION_THREADS) +#define __os_getaddrinfo __os_getaddrinfo@DB_VERSION_UNIQUE_NAME@ +#endif +#if defined(HAVE_REPLICATION_THREADS) +#define __os_freeaddrinfo __os_freeaddrinfo@DB_VERSION_UNIQUE_NAME@ +#endif +#define __os_umalloc __os_umalloc@DB_VERSION_UNIQUE_NAME@ +#define __os_urealloc __os_urealloc@DB_VERSION_UNIQUE_NAME@ +#define __os_ufree __os_ufree@DB_VERSION_UNIQUE_NAME@ +#define __os_strdup __os_strdup@DB_VERSION_UNIQUE_NAME@ +#define __os_calloc __os_calloc@DB_VERSION_UNIQUE_NAME@ +#define __os_malloc __os_malloc@DB_VERSION_UNIQUE_NAME@ +#define __os_realloc __os_realloc@DB_VERSION_UNIQUE_NAME@ +#define __os_free __os_free@DB_VERSION_UNIQUE_NAME@ +#define __ua_memcpy __ua_memcpy@DB_VERSION_UNIQUE_NAME@ +#define __os_gettime __os_gettime@DB_VERSION_UNIQUE_NAME@ +#define __os_fs_notzero __os_fs_notzero@DB_VERSION_UNIQUE_NAME@ +#define __os_support_direct_io __os_support_direct_io@DB_VERSION_UNIQUE_NAME@ +#define __os_support_db_register __os_support_db_register@DB_VERSION_UNIQUE_NAME@ +#define __os_support_replication __os_support_replication@DB_VERSION_UNIQUE_NAME@ +#define __os_cpu_count __os_cpu_count@DB_VERSION_UNIQUE_NAME@ +#define __os_ctime __os_ctime@DB_VERSION_UNIQUE_NAME@ +#define __os_dirlist __os_dirlist@DB_VERSION_UNIQUE_NAME@ +#define __os_dirfree __os_dirfree@DB_VERSION_UNIQUE_NAME@ +#define __os_get_errno_ret_zero __os_get_errno_ret_zero@DB_VERSION_UNIQUE_NAME@ +#define __os_get_errno __os_get_errno@DB_VERSION_UNIQUE_NAME@ +#define __os_get_neterr __os_get_neterr@DB_VERSION_UNIQUE_NAME@ +#define __os_get_syserr __os_get_syserr@DB_VERSION_UNIQUE_NAME@ +#define __os_set_errno __os_set_errno@DB_VERSION_UNIQUE_NAME@ +#define __os_strerror __os_strerror@DB_VERSION_UNIQUE_NAME@ +#define __os_posix_err __os_posix_err@DB_VERSION_UNIQUE_NAME@ +#define __os_fileid __os_fileid@DB_VERSION_UNIQUE_NAME@ +#define __os_fdlock __os_fdlock@DB_VERSION_UNIQUE_NAME@ +#define __os_fsync __os_fsync@DB_VERSION_UNIQUE_NAME@ +#define __os_getenv __os_getenv@DB_VERSION_UNIQUE_NAME@ +#define __os_openhandle __os_openhandle@DB_VERSION_UNIQUE_NAME@ +#define __os_closehandle __os_closehandle@DB_VERSION_UNIQUE_NAME@ +#define __os_attach __os_attach@DB_VERSION_UNIQUE_NAME@ +#define __os_detach __os_detach@DB_VERSION_UNIQUE_NAME@ +#define __os_mapfile __os_mapfile@DB_VERSION_UNIQUE_NAME@ +#define __os_unmapfile __os_unmapfile@DB_VERSION_UNIQUE_NAME@ +#define __os_mkdir __os_mkdir@DB_VERSION_UNIQUE_NAME@ +#define __os_open __os_open@DB_VERSION_UNIQUE_NAME@ +#define __os_id __os_id@DB_VERSION_UNIQUE_NAME@ +#define __os_rename __os_rename@DB_VERSION_UNIQUE_NAME@ +#define __os_isroot __os_isroot@DB_VERSION_UNIQUE_NAME@ +#define __db_rpath __db_rpath@DB_VERSION_UNIQUE_NAME@ +#define __os_io __os_io@DB_VERSION_UNIQUE_NAME@ +#define __os_read __os_read@DB_VERSION_UNIQUE_NAME@ +#define __os_write __os_write@DB_VERSION_UNIQUE_NAME@ +#define __os_physwrite __os_physwrite@DB_VERSION_UNIQUE_NAME@ +#define __os_seek __os_seek@DB_VERSION_UNIQUE_NAME@ +#define __os_stack __os_stack@DB_VERSION_UNIQUE_NAME@ +#define __os_exists __os_exists@DB_VERSION_UNIQUE_NAME@ +#define __os_ioinfo __os_ioinfo@DB_VERSION_UNIQUE_NAME@ +#define __os_tmpdir __os_tmpdir@DB_VERSION_UNIQUE_NAME@ +#define __os_truncate __os_truncate@DB_VERSION_UNIQUE_NAME@ +#define __os_unique_id __os_unique_id@DB_VERSION_UNIQUE_NAME@ +#define __os_unlink __os_unlink@DB_VERSION_UNIQUE_NAME@ +#define __os_yield __os_yield@DB_VERSION_UNIQUE_NAME@ +#ifndef HAVE_FCLOSE +#define fclose fclose@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_FGETC +#define fgetc fgetc@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_FGETS +#define fgets fgets@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_FOPEN +#define fopen fopen@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_FWRITE +#define fwrite fwrite@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_LOCALTIME +#define localtime localtime@DB_VERSION_UNIQUE_NAME@ +#endif +#ifdef HAVE_QNX +#define __os_qnx_region_open __os_qnx_region_open@DB_VERSION_UNIQUE_NAME@ +#endif +#define __os_is_winnt __os_is_winnt@DB_VERSION_UNIQUE_NAME@ +#define __os_cpu_count __os_cpu_count@DB_VERSION_UNIQUE_NAME@ +#ifdef HAVE_REPLICATION_THREADS +#define __os_get_neterr __os_get_neterr@DB_VERSION_UNIQUE_NAME@ +#endif +#define __qam_position __qam_position@DB_VERSION_UNIQUE_NAME@ +#define __qam_pitem __qam_pitem@DB_VERSION_UNIQUE_NAME@ +#define __qam_append __qam_append@DB_VERSION_UNIQUE_NAME@ +#define __qamc_dup __qamc_dup@DB_VERSION_UNIQUE_NAME@ +#define __qamc_init __qamc_init@DB_VERSION_UNIQUE_NAME@ +#define __qam_truncate __qam_truncate@DB_VERSION_UNIQUE_NAME@ +#define __qam_delete __qam_delete@DB_VERSION_UNIQUE_NAME@ +#define __qam_incfirst_read __qam_incfirst_read@DB_VERSION_UNIQUE_NAME@ +#define __qam_incfirst_log __qam_incfirst_log@DB_VERSION_UNIQUE_NAME@ +#define __qam_mvptr_read __qam_mvptr_read@DB_VERSION_UNIQUE_NAME@ +#define __qam_mvptr_log __qam_mvptr_log@DB_VERSION_UNIQUE_NAME@ +#define __qam_del_read __qam_del_read@DB_VERSION_UNIQUE_NAME@ +#define __qam_del_log __qam_del_log@DB_VERSION_UNIQUE_NAME@ +#define __qam_add_read __qam_add_read@DB_VERSION_UNIQUE_NAME@ +#define __qam_add_log __qam_add_log@DB_VERSION_UNIQUE_NAME@ +#define __qam_delext_read __qam_delext_read@DB_VERSION_UNIQUE_NAME@ +#define __qam_delext_log __qam_delext_log@DB_VERSION_UNIQUE_NAME@ +#define __qam_init_recover __qam_init_recover@DB_VERSION_UNIQUE_NAME@ +#define __qam_incfirst_print __qam_incfirst_print@DB_VERSION_UNIQUE_NAME@ +#define __qam_mvptr_print __qam_mvptr_print@DB_VERSION_UNIQUE_NAME@ +#define __qam_del_print __qam_del_print@DB_VERSION_UNIQUE_NAME@ +#define __qam_add_print __qam_add_print@DB_VERSION_UNIQUE_NAME@ +#define __qam_delext_print __qam_delext_print@DB_VERSION_UNIQUE_NAME@ +#define __qam_init_print __qam_init_print@DB_VERSION_UNIQUE_NAME@ +#define __qam_mswap __qam_mswap@DB_VERSION_UNIQUE_NAME@ +#define __qam_pgin_out __qam_pgin_out@DB_VERSION_UNIQUE_NAME@ +#define __qam_fprobe __qam_fprobe@DB_VERSION_UNIQUE_NAME@ +#define __qam_fclose __qam_fclose@DB_VERSION_UNIQUE_NAME@ +#define __qam_fremove __qam_fremove@DB_VERSION_UNIQUE_NAME@ +#define __qam_sync __qam_sync@DB_VERSION_UNIQUE_NAME@ +#define __qam_gen_filelist __qam_gen_filelist@DB_VERSION_UNIQUE_NAME@ +#define __qam_extent_names __qam_extent_names@DB_VERSION_UNIQUE_NAME@ +#define __qam_exid __qam_exid@DB_VERSION_UNIQUE_NAME@ +#define __qam_nameop __qam_nameop@DB_VERSION_UNIQUE_NAME@ +#define __qam_lsn_reset __qam_lsn_reset@DB_VERSION_UNIQUE_NAME@ +#define __qam_db_create __qam_db_create@DB_VERSION_UNIQUE_NAME@ +#define __qam_db_close __qam_db_close@DB_VERSION_UNIQUE_NAME@ +#define __qam_get_extentsize __qam_get_extentsize@DB_VERSION_UNIQUE_NAME@ +#define __queue_pageinfo __queue_pageinfo@DB_VERSION_UNIQUE_NAME@ +#define __db_prqueue __db_prqueue@DB_VERSION_UNIQUE_NAME@ +#define __qam_remove __qam_remove@DB_VERSION_UNIQUE_NAME@ +#define __qam_rename __qam_rename@DB_VERSION_UNIQUE_NAME@ +#define __qam_map_flags __qam_map_flags@DB_VERSION_UNIQUE_NAME@ +#define __qam_set_flags __qam_set_flags@DB_VERSION_UNIQUE_NAME@ +#define __qam_open __qam_open@DB_VERSION_UNIQUE_NAME@ +#define __qam_set_ext_data __qam_set_ext_data@DB_VERSION_UNIQUE_NAME@ +#define __qam_metachk __qam_metachk@DB_VERSION_UNIQUE_NAME@ +#define __qam_new_file __qam_new_file@DB_VERSION_UNIQUE_NAME@ +#define __qam_incfirst_recover __qam_incfirst_recover@DB_VERSION_UNIQUE_NAME@ +#define __qam_mvptr_recover __qam_mvptr_recover@DB_VERSION_UNIQUE_NAME@ +#define __qam_del_recover __qam_del_recover@DB_VERSION_UNIQUE_NAME@ +#define __qam_delext_recover __qam_delext_recover@DB_VERSION_UNIQUE_NAME@ +#define __qam_add_recover __qam_add_recover@DB_VERSION_UNIQUE_NAME@ +#define __qam_stat __qam_stat@DB_VERSION_UNIQUE_NAME@ +#define __qam_stat_print __qam_stat_print@DB_VERSION_UNIQUE_NAME@ +#define __db_no_queue_am __db_no_queue_am@DB_VERSION_UNIQUE_NAME@ +#define __qam_31_qammeta __qam_31_qammeta@DB_VERSION_UNIQUE_NAME@ +#define __qam_32_qammeta __qam_32_qammeta@DB_VERSION_UNIQUE_NAME@ +#define __qam_vrfy_meta __qam_vrfy_meta@DB_VERSION_UNIQUE_NAME@ +#define __qam_meta2pgset __qam_meta2pgset@DB_VERSION_UNIQUE_NAME@ +#define __qam_vrfy_data __qam_vrfy_data@DB_VERSION_UNIQUE_NAME@ +#define __qam_vrfy_structure __qam_vrfy_structure@DB_VERSION_UNIQUE_NAME@ +#define __qam_vrfy_walkqueue __qam_vrfy_walkqueue@DB_VERSION_UNIQUE_NAME@ +#define __qam_salvage __qam_salvage@DB_VERSION_UNIQUE_NAME@ +#define __rep_bulk_marshal __rep_bulk_marshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_bulk_unmarshal __rep_bulk_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_control_marshal __rep_control_marshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_control_unmarshal __rep_control_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_egen_marshal __rep_egen_marshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_egen_unmarshal __rep_egen_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_fileinfo_marshal __rep_fileinfo_marshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_fileinfo_unmarshal __rep_fileinfo_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_grant_info_marshal __rep_grant_info_marshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_grant_info_unmarshal __rep_grant_info_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_logreq_marshal __rep_logreq_marshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_logreq_unmarshal __rep_logreq_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_newfile_marshal __rep_newfile_marshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_newfile_unmarshal __rep_newfile_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_update_marshal __rep_update_marshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_update_unmarshal __rep_update_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_vote_info_marshal __rep_vote_info_marshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_vote_info_unmarshal __rep_vote_info_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_update_req __rep_update_req@DB_VERSION_UNIQUE_NAME@ +#define __rep_page_req __rep_page_req@DB_VERSION_UNIQUE_NAME@ +#define __rep_update_setup __rep_update_setup@DB_VERSION_UNIQUE_NAME@ +#define __rep_bulk_page __rep_bulk_page@DB_VERSION_UNIQUE_NAME@ +#define __rep_page __rep_page@DB_VERSION_UNIQUE_NAME@ +#define __rep_page_fail __rep_page_fail@DB_VERSION_UNIQUE_NAME@ +#define __rep_init_cleanup __rep_init_cleanup@DB_VERSION_UNIQUE_NAME@ +#define __rep_pggap_req __rep_pggap_req@DB_VERSION_UNIQUE_NAME@ +#define __rep_finfo_alloc __rep_finfo_alloc@DB_VERSION_UNIQUE_NAME@ +#define __rep_remove_init_file __rep_remove_init_file@DB_VERSION_UNIQUE_NAME@ +#define __rep_reset_init __rep_reset_init@DB_VERSION_UNIQUE_NAME@ +#define __rep_elect_pp __rep_elect_pp@DB_VERSION_UNIQUE_NAME@ +#define __rep_elect_int __rep_elect_int@DB_VERSION_UNIQUE_NAME@ +#define __rep_vote1 __rep_vote1@DB_VERSION_UNIQUE_NAME@ +#define __rep_vote2 __rep_vote2@DB_VERSION_UNIQUE_NAME@ +#define __rep_update_grant __rep_update_grant@DB_VERSION_UNIQUE_NAME@ +#define __rep_islease_granted __rep_islease_granted@DB_VERSION_UNIQUE_NAME@ +#define __rep_lease_table_alloc __rep_lease_table_alloc@DB_VERSION_UNIQUE_NAME@ +#define __rep_lease_grant __rep_lease_grant@DB_VERSION_UNIQUE_NAME@ +#define __rep_lease_check __rep_lease_check@DB_VERSION_UNIQUE_NAME@ +#define __rep_lease_refresh __rep_lease_refresh@DB_VERSION_UNIQUE_NAME@ +#define __rep_lease_expire __rep_lease_expire@DB_VERSION_UNIQUE_NAME@ +#define __rep_lease_waittime __rep_lease_waittime@DB_VERSION_UNIQUE_NAME@ +#define __rep_allreq __rep_allreq@DB_VERSION_UNIQUE_NAME@ +#define __rep_log __rep_log@DB_VERSION_UNIQUE_NAME@ +#define __rep_bulk_log __rep_bulk_log@DB_VERSION_UNIQUE_NAME@ +#define __rep_logreq __rep_logreq@DB_VERSION_UNIQUE_NAME@ +#define __rep_loggap_req __rep_loggap_req@DB_VERSION_UNIQUE_NAME@ +#define __rep_logready __rep_logready@DB_VERSION_UNIQUE_NAME@ +#define __rep_env_create __rep_env_create@DB_VERSION_UNIQUE_NAME@ +#define __rep_env_destroy __rep_env_destroy@DB_VERSION_UNIQUE_NAME@ +#define __rep_get_config __rep_get_config@DB_VERSION_UNIQUE_NAME@ +#define __rep_set_config __rep_set_config@DB_VERSION_UNIQUE_NAME@ +#define __rep_start_pp __rep_start_pp@DB_VERSION_UNIQUE_NAME@ +#define __rep_start_int __rep_start_int@DB_VERSION_UNIQUE_NAME@ +#define __rep_client_dbinit __rep_client_dbinit@DB_VERSION_UNIQUE_NAME@ +#define __rep_get_limit __rep_get_limit@DB_VERSION_UNIQUE_NAME@ +#define __rep_set_limit __rep_set_limit@DB_VERSION_UNIQUE_NAME@ +#define __rep_set_nsites __rep_set_nsites@DB_VERSION_UNIQUE_NAME@ +#define __rep_get_nsites __rep_get_nsites@DB_VERSION_UNIQUE_NAME@ +#define __rep_set_priority __rep_set_priority@DB_VERSION_UNIQUE_NAME@ +#define __rep_get_priority __rep_get_priority@DB_VERSION_UNIQUE_NAME@ +#define __rep_set_timeout __rep_set_timeout@DB_VERSION_UNIQUE_NAME@ +#define __rep_get_timeout __rep_get_timeout@DB_VERSION_UNIQUE_NAME@ +#define __rep_get_request __rep_get_request@DB_VERSION_UNIQUE_NAME@ +#define __rep_set_request __rep_set_request@DB_VERSION_UNIQUE_NAME@ +#define __rep_set_transport_pp __rep_set_transport_pp@DB_VERSION_UNIQUE_NAME@ +#define __rep_set_transport_int __rep_set_transport_int@DB_VERSION_UNIQUE_NAME@ +#define __rep_get_clockskew __rep_get_clockskew@DB_VERSION_UNIQUE_NAME@ +#define __rep_set_clockskew __rep_set_clockskew@DB_VERSION_UNIQUE_NAME@ +#define __rep_flush __rep_flush@DB_VERSION_UNIQUE_NAME@ +#define __rep_sync __rep_sync@DB_VERSION_UNIQUE_NAME@ +#define __rep_process_message_pp __rep_process_message_pp@DB_VERSION_UNIQUE_NAME@ +#define __rep_process_message_int __rep_process_message_int@DB_VERSION_UNIQUE_NAME@ +#define __rep_apply __rep_apply@DB_VERSION_UNIQUE_NAME@ +#define __rep_process_txn __rep_process_txn@DB_VERSION_UNIQUE_NAME@ +#define __rep_resend_req __rep_resend_req@DB_VERSION_UNIQUE_NAME@ +#define __rep_check_doreq __rep_check_doreq@DB_VERSION_UNIQUE_NAME@ +#define __rep_open __rep_open@DB_VERSION_UNIQUE_NAME@ +#define __rep_env_refresh __rep_env_refresh@DB_VERSION_UNIQUE_NAME@ +#define __rep_env_close __rep_env_close@DB_VERSION_UNIQUE_NAME@ +#define __rep_preclose __rep_preclose@DB_VERSION_UNIQUE_NAME@ +#define __rep_closefiles __rep_closefiles@DB_VERSION_UNIQUE_NAME@ +#define __rep_write_egen __rep_write_egen@DB_VERSION_UNIQUE_NAME@ +#define __rep_write_gen __rep_write_gen@DB_VERSION_UNIQUE_NAME@ +#define __rep_stat_pp __rep_stat_pp@DB_VERSION_UNIQUE_NAME@ +#define __rep_stat_print_pp __rep_stat_print_pp@DB_VERSION_UNIQUE_NAME@ +#define __rep_stat_print __rep_stat_print@DB_VERSION_UNIQUE_NAME@ +#define __rep_bulk_message __rep_bulk_message@DB_VERSION_UNIQUE_NAME@ +#define __rep_send_bulk __rep_send_bulk@DB_VERSION_UNIQUE_NAME@ +#define __rep_bulk_alloc __rep_bulk_alloc@DB_VERSION_UNIQUE_NAME@ +#define __rep_bulk_free __rep_bulk_free@DB_VERSION_UNIQUE_NAME@ +#define __rep_send_message __rep_send_message@DB_VERSION_UNIQUE_NAME@ +#define __rep_new_master __rep_new_master@DB_VERSION_UNIQUE_NAME@ +#define __rep_noarchive __rep_noarchive@DB_VERSION_UNIQUE_NAME@ +#define __rep_send_vote __rep_send_vote@DB_VERSION_UNIQUE_NAME@ +#define __rep_elect_done __rep_elect_done@DB_VERSION_UNIQUE_NAME@ +#define __env_rep_enter __env_rep_enter@DB_VERSION_UNIQUE_NAME@ +#define __env_db_rep_exit __env_db_rep_exit@DB_VERSION_UNIQUE_NAME@ +#define __db_rep_enter __db_rep_enter@DB_VERSION_UNIQUE_NAME@ +#define __op_rep_enter __op_rep_enter@DB_VERSION_UNIQUE_NAME@ +#define __op_rep_exit __op_rep_exit@DB_VERSION_UNIQUE_NAME@ +#define __rep_lockout_api __rep_lockout_api@DB_VERSION_UNIQUE_NAME@ +#define __rep_lockout_apply __rep_lockout_apply@DB_VERSION_UNIQUE_NAME@ +#define __rep_lockout_msg __rep_lockout_msg@DB_VERSION_UNIQUE_NAME@ +#define __rep_send_throttle __rep_send_throttle@DB_VERSION_UNIQUE_NAME@ +#define __rep_msg_to_old __rep_msg_to_old@DB_VERSION_UNIQUE_NAME@ +#define __rep_msg_from_old __rep_msg_from_old@DB_VERSION_UNIQUE_NAME@ +#define __rep_print __rep_print@DB_VERSION_UNIQUE_NAME@ +#define __rep_print_message __rep_print_message@DB_VERSION_UNIQUE_NAME@ +#define __rep_fire_event __rep_fire_event@DB_VERSION_UNIQUE_NAME@ +#define __rep_verify __rep_verify@DB_VERSION_UNIQUE_NAME@ +#define __rep_verify_fail __rep_verify_fail@DB_VERSION_UNIQUE_NAME@ +#define __rep_verify_req __rep_verify_req@DB_VERSION_UNIQUE_NAME@ +#define __rep_dorecovery __rep_dorecovery@DB_VERSION_UNIQUE_NAME@ +#define __rep_verify_match __rep_verify_match@DB_VERSION_UNIQUE_NAME@ +#define __rep_log_backup __rep_log_backup@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_handshake_marshal __repmgr_handshake_marshal@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_handshake_unmarshal __repmgr_handshake_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_v2handshake_marshal __repmgr_v2handshake_marshal@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_v2handshake_unmarshal __repmgr_v2handshake_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_ack_marshal __repmgr_ack_marshal@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_ack_unmarshal __repmgr_ack_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_version_proposal_marshal __repmgr_version_proposal_marshal@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_version_proposal_unmarshal __repmgr_version_proposal_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_version_confirmation_marshal __repmgr_version_confirmation_marshal@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_version_confirmation_unmarshal __repmgr_version_confirmation_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_init_election __repmgr_init_election@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_become_master __repmgr_become_master@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_start __repmgr_start@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_autostart __repmgr_autostart@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_start_selector __repmgr_start_selector@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_close __repmgr_close@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_set_ack_policy __repmgr_set_ack_policy@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_get_ack_policy __repmgr_get_ack_policy@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_env_create __repmgr_env_create@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_env_destroy __repmgr_env_destroy@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_stop_threads __repmgr_stop_threads@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_set_local_site __repmgr_set_local_site@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_add_remote_site __repmgr_add_remote_site@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_msg_thread __repmgr_msg_thread@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_handle_event __repmgr_handle_event@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_send __repmgr_send@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_sync_siteaddr __repmgr_sync_siteaddr@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_send_broadcast __repmgr_send_broadcast@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_send_one __repmgr_send_one@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_is_permanent __repmgr_is_permanent@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_bust_connection __repmgr_bust_connection@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_disable_connection __repmgr_disable_connection@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_cleanup_connection __repmgr_cleanup_connection@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_find_site __repmgr_find_site@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_pack_netaddr __repmgr_pack_netaddr@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_getaddr __repmgr_getaddr@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_add_site __repmgr_add_site@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_add_site_int __repmgr_add_site_int@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_listen __repmgr_listen@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_net_close __repmgr_net_close@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_net_destroy __repmgr_net_destroy@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_thread_start __repmgr_thread_start@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_thread_join __repmgr_thread_join@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_set_nonblocking __repmgr_set_nonblocking@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_wake_waiting_senders __repmgr_wake_waiting_senders@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_await_ack __repmgr_await_ack@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_compute_wait_deadline __repmgr_compute_wait_deadline@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_await_drain __repmgr_await_drain@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_alloc_cond __repmgr_alloc_cond@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_free_cond __repmgr_free_cond@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_env_create_pf __repmgr_env_create_pf@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_create_mutex_pf __repmgr_create_mutex_pf@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_destroy_mutex_pf __repmgr_destroy_mutex_pf@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_init __repmgr_init@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_deinit __repmgr_deinit@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_lock_mutex __repmgr_lock_mutex@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_unlock_mutex __repmgr_unlock_mutex@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_signal __repmgr_signal@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_wake_main_thread __repmgr_wake_main_thread@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_writev __repmgr_writev@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_readv __repmgr_readv@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_select_loop __repmgr_select_loop@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_queue_destroy __repmgr_queue_destroy@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_queue_get __repmgr_queue_get@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_queue_put __repmgr_queue_put@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_queue_size __repmgr_queue_size@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_select_thread __repmgr_select_thread@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_accept __repmgr_accept@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_compute_timeout __repmgr_compute_timeout@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_check_timeouts __repmgr_check_timeouts@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_first_try_connections __repmgr_first_try_connections@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_connect_site __repmgr_connect_site@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_propose_version __repmgr_propose_version@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_read_from_site __repmgr_read_from_site@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_write_some __repmgr_write_some@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_stat_pp __repmgr_stat_pp@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_stat_print_pp __repmgr_stat_print_pp@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_site_list __repmgr_site_list@DB_VERSION_UNIQUE_NAME@ +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_close __repmgr_close@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_add_remote_site __repmgr_add_remote_site@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_get_ack_policy __repmgr_get_ack_policy@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_set_ack_policy __repmgr_set_ack_policy@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_set_local_site __repmgr_set_local_site@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_site_list __repmgr_site_list@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_start __repmgr_start@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_stat_pp __repmgr_stat_pp@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_stat_print_pp __repmgr_stat_print_pp@DB_VERSION_UNIQUE_NAME@ +#endif +#ifndef HAVE_REPLICATION_THREADS +#define __repmgr_handle_event __repmgr_handle_event@DB_VERSION_UNIQUE_NAME@ +#endif +#define __repmgr_schedule_connection_attempt __repmgr_schedule_connection_attempt@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_reset_for_reading __repmgr_reset_for_reading@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_new_connection __repmgr_new_connection@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_new_site __repmgr_new_site@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_cleanup_netaddr __repmgr_cleanup_netaddr@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_iovec_init __repmgr_iovec_init@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_add_buffer __repmgr_add_buffer@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_add_dbt __repmgr_add_dbt@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_update_consumed __repmgr_update_consumed@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_prepare_my_addr __repmgr_prepare_my_addr@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_get_nsites __repmgr_get_nsites@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_thread_failure __repmgr_thread_failure@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_format_eid_loc __repmgr_format_eid_loc@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_format_site_loc __repmgr_format_site_loc@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_repstart __repmgr_repstart@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_each_connection __repmgr_each_connection@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_open __repmgr_open@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_join __repmgr_join@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_env_refresh __repmgr_env_refresh@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_share_netaddrs __repmgr_share_netaddrs@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_copy_in_added_sites __repmgr_copy_in_added_sites@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_init_new_sites __repmgr_init_new_sites@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_check_host_name __repmgr_check_host_name@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_failchk __repmgr_failchk@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_set_rpc_server __dbcl_env_set_rpc_server@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_close_wrap __dbcl_env_close_wrap@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_open_wrap __dbcl_env_open_wrap@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_open_wrap __dbcl_db_open_wrap@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_refresh __dbcl_refresh@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_retcopy __dbcl_retcopy@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_txn_end __dbcl_txn_end@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_txn_setup __dbcl_txn_setup@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_c_refresh __dbcl_c_refresh@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_c_setup __dbcl_c_setup@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbclose_common __dbcl_dbclose_common@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbenv_illegal __dbcl_dbenv_illegal@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_create __dbcl_env_create@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_cdsgroup_begin __dbcl_env_cdsgroup_begin@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_close __dbcl_env_close@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_dbremove __dbcl_env_dbremove@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_dbrename __dbcl_env_dbrename@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_get_cachesize __dbcl_env_get_cachesize@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_get_encrypt_flags __dbcl_env_get_encrypt_flags@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_get_flags __dbcl_env_get_flags@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_get_home __dbcl_env_get_home@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_get_open_flags __dbcl_env_get_open_flags@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_open __dbcl_env_open@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_remove __dbcl_env_remove@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_set_cachesize __dbcl_env_set_cachesize@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_set_encrypt __dbcl_env_set_encrypt@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_set_flags __dbcl_env_set_flags@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_txn_begin __dbcl_env_txn_begin@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_txn_recover __dbcl_env_txn_recover@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_create __dbcl_db_create@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_associate __dbcl_db_associate@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_close __dbcl_db_close@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_cursor __dbcl_db_cursor@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_del __dbcl_db_del@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get __dbcl_db_get@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_bt_minkey __dbcl_db_get_bt_minkey@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_dbname __dbcl_db_get_dbname@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_encrypt_flags __dbcl_db_get_encrypt_flags@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_flags __dbcl_db_get_flags@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_h_ffactor __dbcl_db_get_h_ffactor@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_h_nelem __dbcl_db_get_h_nelem@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_lorder __dbcl_db_get_lorder@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_open_flags __dbcl_db_get_open_flags@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_pagesize __dbcl_db_get_pagesize@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_priority __dbcl_db_get_priority@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_q_extentsize __dbcl_db_get_q_extentsize@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_re_delim __dbcl_db_get_re_delim@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_re_len __dbcl_db_get_re_len@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_re_pad __dbcl_db_get_re_pad@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_join __dbcl_db_join@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_key_range __dbcl_db_key_range@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_open __dbcl_db_open@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_pget __dbcl_db_pget@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_put __dbcl_db_put@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_remove __dbcl_db_remove@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_rename __dbcl_db_rename@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_set_bt_minkey __dbcl_db_set_bt_minkey@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_set_encrypt __dbcl_db_set_encrypt@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_set_flags __dbcl_db_set_flags@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_set_h_ffactor __dbcl_db_set_h_ffactor@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_set_h_nelem __dbcl_db_set_h_nelem@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_set_lorder __dbcl_db_set_lorder@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_set_pagesize __dbcl_db_set_pagesize@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_set_priority __dbcl_db_set_priority@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_set_q_extentsize __dbcl_db_set_q_extentsize@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_set_re_delim __dbcl_db_set_re_delim@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_set_re_len __dbcl_db_set_re_len@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_set_re_pad __dbcl_db_set_re_pad@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_stat __dbcl_db_stat@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_sync __dbcl_db_sync@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_truncate __dbcl_db_truncate@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_close __dbcl_dbc_close@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_count __dbcl_dbc_count@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_del __dbcl_dbc_del@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_dup __dbcl_dbc_dup@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_get __dbcl_dbc_get@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_get_priority __dbcl_dbc_get_priority@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_pget __dbcl_dbc_pget@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_put __dbcl_dbc_put@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_set_priority __dbcl_dbc_set_priority@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_txn_abort __dbcl_txn_abort@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_txn_commit __dbcl_txn_commit@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_txn_discard __dbcl_txn_discard@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_txn_prepare __dbcl_txn_prepare@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbp_init __dbcl_dbp_init@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_init __dbcl_dbc_init@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbenv_init __dbcl_dbenv_init@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_txn_init __dbcl_txn_init@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_create_ret __dbcl_env_create_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_open_ret __dbcl_env_open_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_remove_ret __dbcl_env_remove_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_txn_abort_ret __dbcl_txn_abort_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_txn_begin_ret __dbcl_env_txn_begin_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_cdsgroup_begin_ret __dbcl_env_cdsgroup_begin_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_txn_commit_ret __dbcl_txn_commit_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_txn_discard_ret __dbcl_txn_discard_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_env_txn_recover_ret __dbcl_env_txn_recover_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_close_ret __dbcl_db_close_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_create_ret __dbcl_db_create_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_get_ret __dbcl_db_get_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_key_range_ret __dbcl_db_key_range_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_open_ret __dbcl_db_open_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_pget_ret __dbcl_db_pget_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_put_ret __dbcl_db_put_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_remove_ret __dbcl_db_remove_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_rename_ret __dbcl_db_rename_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_stat_ret __dbcl_db_stat_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_truncate_ret __dbcl_db_truncate_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_cursor_ret __dbcl_db_cursor_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_db_join_ret __dbcl_db_join_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_close_ret __dbcl_dbc_close_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_count_ret __dbcl_dbc_count_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_dup_ret __dbcl_dbc_dup_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_get_ret __dbcl_dbc_get_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_pget_ret __dbcl_dbc_pget_ret@DB_VERSION_UNIQUE_NAME@ +#define __dbcl_dbc_put_ret __dbcl_dbc_put_ret@DB_VERSION_UNIQUE_NAME@ +#define __env_get_cachesize_proc __env_get_cachesize_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_set_cachesize_proc __env_set_cachesize_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_cdsgroup_begin_proc __env_cdsgroup_begin_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_close_proc __env_close_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_create_proc __env_create_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_dbremove_proc __env_dbremove_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_dbrename_proc __env_dbrename_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_get_encrypt_flags_proc __env_get_encrypt_flags_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_set_encrypt_proc __env_set_encrypt_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_get_flags_proc __env_get_flags_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_set_flags_proc __env_set_flags_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_get_home_proc __env_get_home_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_get_open_flags_proc __env_get_open_flags_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_open_proc __env_open_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_remove_proc __env_remove_proc@DB_VERSION_UNIQUE_NAME@ +#define __txn_abort_proc __txn_abort_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_txn_begin_proc __env_txn_begin_proc@DB_VERSION_UNIQUE_NAME@ +#define __txn_commit_proc __txn_commit_proc@DB_VERSION_UNIQUE_NAME@ +#define __txn_discard_proc __txn_discard_proc@DB_VERSION_UNIQUE_NAME@ +#define __txn_prepare_proc __txn_prepare_proc@DB_VERSION_UNIQUE_NAME@ +#define __env_txn_recover_proc __env_txn_recover_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_associate_proc __db_associate_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_bt_minkey_proc __db_get_bt_minkey_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_set_bt_minkey_proc __db_set_bt_minkey_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_close_proc __db_close_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_create_proc __db_create_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_del_proc __db_del_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_encrypt_flags_proc __db_get_encrypt_flags_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_set_encrypt_proc __db_set_encrypt_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_q_extentsize_proc __db_get_q_extentsize_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_set_q_extentsize_proc __db_set_q_extentsize_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_flags_proc __db_get_flags_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_set_flags_proc __db_set_flags_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_proc __db_get_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_h_ffactor_proc __db_get_h_ffactor_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_set_h_ffactor_proc __db_set_h_ffactor_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_h_nelem_proc __db_get_h_nelem_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_set_h_nelem_proc __db_set_h_nelem_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_key_range_proc __db_key_range_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_lorder_proc __db_get_lorder_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_set_lorder_proc __db_set_lorder_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_dbname_proc __db_get_dbname_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_open_flags_proc __db_get_open_flags_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_open_proc __db_open_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_pagesize_proc __db_get_pagesize_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_set_pagesize_proc __db_set_pagesize_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_pget_proc __db_pget_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_put_proc __db_put_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_priority_proc __db_get_priority_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_set_priority_proc __db_set_priority_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_re_delim_proc __db_get_re_delim_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_set_re_delim_proc __db_set_re_delim_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_re_len_proc __db_get_re_len_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_set_re_len_proc __db_set_re_len_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_get_re_pad_proc __db_get_re_pad_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_set_re_pad_proc __db_set_re_pad_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_remove_proc __db_remove_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_rename_proc __db_rename_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_stat_proc __db_stat_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_sync_proc __db_sync_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_truncate_proc __db_truncate_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_cursor_proc __db_cursor_proc@DB_VERSION_UNIQUE_NAME@ +#define __db_join_proc __db_join_proc@DB_VERSION_UNIQUE_NAME@ +#define __dbc_close_proc __dbc_close_proc@DB_VERSION_UNIQUE_NAME@ +#define __dbc_count_proc __dbc_count_proc@DB_VERSION_UNIQUE_NAME@ +#define __dbc_del_proc __dbc_del_proc@DB_VERSION_UNIQUE_NAME@ +#define __dbc_dup_proc __dbc_dup_proc@DB_VERSION_UNIQUE_NAME@ +#define __dbc_get_proc __dbc_get_proc@DB_VERSION_UNIQUE_NAME@ +#define __dbc_pget_proc __dbc_pget_proc@DB_VERSION_UNIQUE_NAME@ +#define __dbc_put_proc __dbc_put_proc@DB_VERSION_UNIQUE_NAME@ +#define __dbc_get_priority_proc __dbc_get_priority_proc@DB_VERSION_UNIQUE_NAME@ +#define __dbc_set_priority_proc __dbc_set_priority_proc@DB_VERSION_UNIQUE_NAME@ +#define __dbsrv_settimeout __dbsrv_settimeout@DB_VERSION_UNIQUE_NAME@ +#define __dbsrv_timeout __dbsrv_timeout@DB_VERSION_UNIQUE_NAME@ +#define __dbclear_ctp __dbclear_ctp@DB_VERSION_UNIQUE_NAME@ +#define __dbdel_ctp __dbdel_ctp@DB_VERSION_UNIQUE_NAME@ +#define new_ct_ent new_ct_ent@DB_VERSION_UNIQUE_NAME@ +#define get_tableent get_tableent@DB_VERSION_UNIQUE_NAME@ +#define __dbsrv_sharedb __dbsrv_sharedb@DB_VERSION_UNIQUE_NAME@ +#define __dbsrv_shareenv __dbsrv_shareenv@DB_VERSION_UNIQUE_NAME@ +#define __dbsrv_active __dbsrv_active@DB_VERSION_UNIQUE_NAME@ +#define __db_close_int __db_close_int@DB_VERSION_UNIQUE_NAME@ +#define __dbc_close_int __dbc_close_int@DB_VERSION_UNIQUE_NAME@ +#define __env_close_int __env_close_int@DB_VERSION_UNIQUE_NAME@ +#define get_fullhome get_fullhome@DB_VERSION_UNIQUE_NAME@ +#define __seq_stat __seq_stat@DB_VERSION_UNIQUE_NAME@ +#define __seq_stat_print __seq_stat_print@DB_VERSION_UNIQUE_NAME@ +#define __db_get_seq_flags_fn __db_get_seq_flags_fn@DB_VERSION_UNIQUE_NAME@ +#define __db_get_seq_flags_fn __db_get_seq_flags_fn@DB_VERSION_UNIQUE_NAME@ +#define bdb_HCommand bdb_HCommand@DB_VERSION_UNIQUE_NAME@ +#if DB_DBM_HSEARCH != 0 +#define bdb_NdbmOpen bdb_NdbmOpen@DB_VERSION_UNIQUE_NAME@ +#endif +#if DB_DBM_HSEARCH != 0 +#define bdb_DbmCommand bdb_DbmCommand@DB_VERSION_UNIQUE_NAME@ +#endif +#define ndbm_Cmd ndbm_Cmd@DB_VERSION_UNIQUE_NAME@ +#define _DbInfoDelete _DbInfoDelete@DB_VERSION_UNIQUE_NAME@ +#define db_Cmd db_Cmd@DB_VERSION_UNIQUE_NAME@ +#define tcl_CompactStat tcl_CompactStat@DB_VERSION_UNIQUE_NAME@ +#define tcl_rep_send tcl_rep_send@DB_VERSION_UNIQUE_NAME@ +#define dbc_Cmd dbc_Cmd@DB_VERSION_UNIQUE_NAME@ +#define env_Cmd env_Cmd@DB_VERSION_UNIQUE_NAME@ +#define tcl_EnvRemove tcl_EnvRemove@DB_VERSION_UNIQUE_NAME@ +#define tcl_EnvIdReset tcl_EnvIdReset@DB_VERSION_UNIQUE_NAME@ +#define tcl_EnvLsnReset tcl_EnvLsnReset@DB_VERSION_UNIQUE_NAME@ +#define tcl_EnvVerbose tcl_EnvVerbose@DB_VERSION_UNIQUE_NAME@ +#define tcl_EnvAttr tcl_EnvAttr@DB_VERSION_UNIQUE_NAME@ +#define tcl_EventNotify tcl_EventNotify@DB_VERSION_UNIQUE_NAME@ +#define tcl_EnvSetFlags tcl_EnvSetFlags@DB_VERSION_UNIQUE_NAME@ +#define tcl_EnvTest tcl_EnvTest@DB_VERSION_UNIQUE_NAME@ +#define tcl_EnvGetEncryptFlags tcl_EnvGetEncryptFlags@DB_VERSION_UNIQUE_NAME@ +#define tcl_EnvSetErrfile tcl_EnvSetErrfile@DB_VERSION_UNIQUE_NAME@ +#define tcl_EnvSetErrpfx tcl_EnvSetErrpfx@DB_VERSION_UNIQUE_NAME@ +#define _NewInfo _NewInfo@DB_VERSION_UNIQUE_NAME@ +#define _NameToPtr _NameToPtr@DB_VERSION_UNIQUE_NAME@ +#define _PtrToInfo _PtrToInfo@DB_VERSION_UNIQUE_NAME@ +#define _NameToInfo _NameToInfo@DB_VERSION_UNIQUE_NAME@ +#define _SetInfoData _SetInfoData@DB_VERSION_UNIQUE_NAME@ +#define _DeleteInfo _DeleteInfo@DB_VERSION_UNIQUE_NAME@ +#define _SetListElem _SetListElem@DB_VERSION_UNIQUE_NAME@ +#define _SetListElemInt _SetListElemInt@DB_VERSION_UNIQUE_NAME@ +#define _SetListElemWideInt _SetListElemWideInt@DB_VERSION_UNIQUE_NAME@ +#define _SetListRecnoElem _SetListRecnoElem@DB_VERSION_UNIQUE_NAME@ +#define _Set3DBTList _Set3DBTList@DB_VERSION_UNIQUE_NAME@ +#define _SetMultiList _SetMultiList@DB_VERSION_UNIQUE_NAME@ +#define _GetGlobPrefix _GetGlobPrefix@DB_VERSION_UNIQUE_NAME@ +#define _ReturnSetup _ReturnSetup@DB_VERSION_UNIQUE_NAME@ +#define _ErrorSetup _ErrorSetup@DB_VERSION_UNIQUE_NAME@ +#define _ErrorFunc _ErrorFunc@DB_VERSION_UNIQUE_NAME@ +#define _EventFunc _EventFunc@DB_VERSION_UNIQUE_NAME@ +#define _GetLsn _GetLsn@DB_VERSION_UNIQUE_NAME@ +#define _GetUInt32 _GetUInt32@DB_VERSION_UNIQUE_NAME@ +#define _GetFlagsList _GetFlagsList@DB_VERSION_UNIQUE_NAME@ +#define _debug_check _debug_check@DB_VERSION_UNIQUE_NAME@ +#define _CopyObjBytes _CopyObjBytes@DB_VERSION_UNIQUE_NAME@ +#define tcl_LockDetect tcl_LockDetect@DB_VERSION_UNIQUE_NAME@ +#define tcl_LockGet tcl_LockGet@DB_VERSION_UNIQUE_NAME@ +#define tcl_LockStat tcl_LockStat@DB_VERSION_UNIQUE_NAME@ +#define tcl_LockTimeout tcl_LockTimeout@DB_VERSION_UNIQUE_NAME@ +#define tcl_LockVec tcl_LockVec@DB_VERSION_UNIQUE_NAME@ +#define tcl_LogArchive tcl_LogArchive@DB_VERSION_UNIQUE_NAME@ +#define tcl_LogCompare tcl_LogCompare@DB_VERSION_UNIQUE_NAME@ +#define tcl_LogFile tcl_LogFile@DB_VERSION_UNIQUE_NAME@ +#define tcl_LogFlush tcl_LogFlush@DB_VERSION_UNIQUE_NAME@ +#define tcl_LogGet tcl_LogGet@DB_VERSION_UNIQUE_NAME@ +#define tcl_LogPut tcl_LogPut@DB_VERSION_UNIQUE_NAME@ +#define tcl_LogStat tcl_LogStat@DB_VERSION_UNIQUE_NAME@ +#define logc_Cmd logc_Cmd@DB_VERSION_UNIQUE_NAME@ +#define tcl_LogConfig tcl_LogConfig@DB_VERSION_UNIQUE_NAME@ +#define tcl_LogGetConfig tcl_LogGetConfig@DB_VERSION_UNIQUE_NAME@ +#define _MpInfoDelete _MpInfoDelete@DB_VERSION_UNIQUE_NAME@ +#define tcl_MpSync tcl_MpSync@DB_VERSION_UNIQUE_NAME@ +#define tcl_MpTrickle tcl_MpTrickle@DB_VERSION_UNIQUE_NAME@ +#define tcl_Mp tcl_Mp@DB_VERSION_UNIQUE_NAME@ +#define tcl_MpStat tcl_MpStat@DB_VERSION_UNIQUE_NAME@ +#define tcl_Mutex tcl_Mutex@DB_VERSION_UNIQUE_NAME@ +#define tcl_MutFree tcl_MutFree@DB_VERSION_UNIQUE_NAME@ +#define tcl_MutGet tcl_MutGet@DB_VERSION_UNIQUE_NAME@ +#define tcl_MutLock tcl_MutLock@DB_VERSION_UNIQUE_NAME@ +#define tcl_MutSet tcl_MutSet@DB_VERSION_UNIQUE_NAME@ +#define tcl_MutStat tcl_MutStat@DB_VERSION_UNIQUE_NAME@ +#define tcl_MutUnlock tcl_MutUnlock@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepConfig tcl_RepConfig@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepGetTwo tcl_RepGetTwo@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepGetConfig tcl_RepGetConfig@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepGetTimeout tcl_RepGetTimeout@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepElect tcl_RepElect@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepFlush tcl_RepFlush@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepSync tcl_RepSync@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepLease tcl_RepLease@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepInmemFiles tcl_RepInmemFiles@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepLimit tcl_RepLimit@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepRequest tcl_RepRequest@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepNoarchiveTimeout tcl_RepNoarchiveTimeout@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepTransport tcl_RepTransport@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepStart tcl_RepStart@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepProcessMessage tcl_RepProcessMessage@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepStat tcl_RepStat@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepMgr tcl_RepMgr@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepMgrSiteList tcl_RepMgrSiteList@DB_VERSION_UNIQUE_NAME@ +#define tcl_RepMgrStat tcl_RepMgrStat@DB_VERSION_UNIQUE_NAME@ +#define seq_Cmd seq_Cmd@DB_VERSION_UNIQUE_NAME@ +#define _TxnInfoDelete _TxnInfoDelete@DB_VERSION_UNIQUE_NAME@ +#define tcl_TxnCheckpoint tcl_TxnCheckpoint@DB_VERSION_UNIQUE_NAME@ +#define tcl_Txn tcl_Txn@DB_VERSION_UNIQUE_NAME@ +#define tcl_CDSGroup tcl_CDSGroup@DB_VERSION_UNIQUE_NAME@ +#define tcl_TxnStat tcl_TxnStat@DB_VERSION_UNIQUE_NAME@ +#define tcl_TxnTimeout tcl_TxnTimeout@DB_VERSION_UNIQUE_NAME@ +#define tcl_TxnRecover tcl_TxnRecover@DB_VERSION_UNIQUE_NAME@ +#define bdb_RandCommand bdb_RandCommand@DB_VERSION_UNIQUE_NAME@ +#define __txn_begin_pp __txn_begin_pp@DB_VERSION_UNIQUE_NAME@ +#define __txn_begin __txn_begin@DB_VERSION_UNIQUE_NAME@ +#define __txn_recycle_id __txn_recycle_id@DB_VERSION_UNIQUE_NAME@ +#define __txn_compensate_begin __txn_compensate_begin@DB_VERSION_UNIQUE_NAME@ +#define __txn_continue __txn_continue@DB_VERSION_UNIQUE_NAME@ +#define __txn_commit __txn_commit@DB_VERSION_UNIQUE_NAME@ +#define __txn_abort __txn_abort@DB_VERSION_UNIQUE_NAME@ +#define __txn_discard_int __txn_discard_int@DB_VERSION_UNIQUE_NAME@ +#define __txn_prepare __txn_prepare@DB_VERSION_UNIQUE_NAME@ +#define __txn_id __txn_id@DB_VERSION_UNIQUE_NAME@ +#define __txn_get_name __txn_get_name@DB_VERSION_UNIQUE_NAME@ +#define __txn_set_name __txn_set_name@DB_VERSION_UNIQUE_NAME@ +#define __txn_set_timeout __txn_set_timeout@DB_VERSION_UNIQUE_NAME@ +#define __txn_activekids __txn_activekids@DB_VERSION_UNIQUE_NAME@ +#define __txn_force_abort __txn_force_abort@DB_VERSION_UNIQUE_NAME@ +#define __txn_preclose __txn_preclose@DB_VERSION_UNIQUE_NAME@ +#define __txn_reset __txn_reset@DB_VERSION_UNIQUE_NAME@ +#define __txn_regop_42_read __txn_regop_42_read@DB_VERSION_UNIQUE_NAME@ +#define __txn_regop_read __txn_regop_read@DB_VERSION_UNIQUE_NAME@ +#define __txn_regop_log __txn_regop_log@DB_VERSION_UNIQUE_NAME@ +#define __txn_ckp_42_read __txn_ckp_42_read@DB_VERSION_UNIQUE_NAME@ +#define __txn_ckp_read __txn_ckp_read@DB_VERSION_UNIQUE_NAME@ +#define __txn_ckp_log __txn_ckp_log@DB_VERSION_UNIQUE_NAME@ +#define __txn_child_read __txn_child_read@DB_VERSION_UNIQUE_NAME@ +#define __txn_child_log __txn_child_log@DB_VERSION_UNIQUE_NAME@ +#define __txn_xa_regop_42_read __txn_xa_regop_42_read@DB_VERSION_UNIQUE_NAME@ +#define __txn_prepare_read __txn_prepare_read@DB_VERSION_UNIQUE_NAME@ +#define __txn_prepare_log __txn_prepare_log@DB_VERSION_UNIQUE_NAME@ +#define __txn_recycle_read __txn_recycle_read@DB_VERSION_UNIQUE_NAME@ +#define __txn_recycle_log __txn_recycle_log@DB_VERSION_UNIQUE_NAME@ +#define __txn_init_recover __txn_init_recover@DB_VERSION_UNIQUE_NAME@ +#define __txn_regop_42_print __txn_regop_42_print@DB_VERSION_UNIQUE_NAME@ +#define __txn_regop_print __txn_regop_print@DB_VERSION_UNIQUE_NAME@ +#define __txn_ckp_42_print __txn_ckp_42_print@DB_VERSION_UNIQUE_NAME@ +#define __txn_ckp_print __txn_ckp_print@DB_VERSION_UNIQUE_NAME@ +#define __txn_child_print __txn_child_print@DB_VERSION_UNIQUE_NAME@ +#define __txn_xa_regop_42_print __txn_xa_regop_42_print@DB_VERSION_UNIQUE_NAME@ +#define __txn_prepare_print __txn_prepare_print@DB_VERSION_UNIQUE_NAME@ +#define __txn_recycle_print __txn_recycle_print@DB_VERSION_UNIQUE_NAME@ +#define __txn_init_print __txn_init_print@DB_VERSION_UNIQUE_NAME@ +#define __txn_checkpoint_pp __txn_checkpoint_pp@DB_VERSION_UNIQUE_NAME@ +#define __txn_checkpoint __txn_checkpoint@DB_VERSION_UNIQUE_NAME@ +#define __txn_getactive __txn_getactive@DB_VERSION_UNIQUE_NAME@ +#define __txn_getckp __txn_getckp@DB_VERSION_UNIQUE_NAME@ +#define __txn_updateckp __txn_updateckp@DB_VERSION_UNIQUE_NAME@ +#define __txn_failchk __txn_failchk@DB_VERSION_UNIQUE_NAME@ +#define __txn_env_create __txn_env_create@DB_VERSION_UNIQUE_NAME@ +#define __txn_env_destroy __txn_env_destroy@DB_VERSION_UNIQUE_NAME@ +#define __txn_get_tx_max __txn_get_tx_max@DB_VERSION_UNIQUE_NAME@ +#define __txn_set_tx_max __txn_set_tx_max@DB_VERSION_UNIQUE_NAME@ +#define __txn_get_tx_timestamp __txn_get_tx_timestamp@DB_VERSION_UNIQUE_NAME@ +#define __txn_set_tx_timestamp __txn_set_tx_timestamp@DB_VERSION_UNIQUE_NAME@ +#define __txn_regop_recover __txn_regop_recover@DB_VERSION_UNIQUE_NAME@ +#define __txn_prepare_recover __txn_prepare_recover@DB_VERSION_UNIQUE_NAME@ +#define __txn_ckp_recover __txn_ckp_recover@DB_VERSION_UNIQUE_NAME@ +#define __txn_child_recover __txn_child_recover@DB_VERSION_UNIQUE_NAME@ +#define __txn_restore_txn __txn_restore_txn@DB_VERSION_UNIQUE_NAME@ +#define __txn_recycle_recover __txn_recycle_recover@DB_VERSION_UNIQUE_NAME@ +#define __txn_regop_42_recover __txn_regop_42_recover@DB_VERSION_UNIQUE_NAME@ +#define __txn_ckp_42_recover __txn_ckp_42_recover@DB_VERSION_UNIQUE_NAME@ +#define __txn_map_gid __txn_map_gid@DB_VERSION_UNIQUE_NAME@ +#define __txn_recover_pp __txn_recover_pp@DB_VERSION_UNIQUE_NAME@ +#define __txn_recover __txn_recover@DB_VERSION_UNIQUE_NAME@ +#define __txn_openfiles __txn_openfiles@DB_VERSION_UNIQUE_NAME@ +#define __txn_open __txn_open@DB_VERSION_UNIQUE_NAME@ +#define __txn_findlastckp __txn_findlastckp@DB_VERSION_UNIQUE_NAME@ +#define __txn_env_refresh __txn_env_refresh@DB_VERSION_UNIQUE_NAME@ +#define __txn_region_mutex_count __txn_region_mutex_count@DB_VERSION_UNIQUE_NAME@ +#define __txn_id_set __txn_id_set@DB_VERSION_UNIQUE_NAME@ +#define __txn_oldest_reader __txn_oldest_reader@DB_VERSION_UNIQUE_NAME@ +#define __txn_add_buffer __txn_add_buffer@DB_VERSION_UNIQUE_NAME@ +#define __txn_remove_buffer __txn_remove_buffer@DB_VERSION_UNIQUE_NAME@ +#define __txn_stat_pp __txn_stat_pp@DB_VERSION_UNIQUE_NAME@ +#define __txn_stat_print_pp __txn_stat_print_pp@DB_VERSION_UNIQUE_NAME@ +#define __txn_stat_print __txn_stat_print@DB_VERSION_UNIQUE_NAME@ +#define __txn_closeevent __txn_closeevent@DB_VERSION_UNIQUE_NAME@ +#define __txn_remevent __txn_remevent@DB_VERSION_UNIQUE_NAME@ +#define __txn_remrem __txn_remrem@DB_VERSION_UNIQUE_NAME@ +#define __txn_lockevent __txn_lockevent@DB_VERSION_UNIQUE_NAME@ +#define __txn_remlock __txn_remlock@DB_VERSION_UNIQUE_NAME@ +#define __txn_doevents __txn_doevents@DB_VERSION_UNIQUE_NAME@ +#define __txn_record_fname __txn_record_fname@DB_VERSION_UNIQUE_NAME@ +#define __txn_dref_fname __txn_dref_fname@DB_VERSION_UNIQUE_NAME@ +#define __db_global_values __db_global_values@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_guesstimated_max __repmgr_guesstimated_max@DB_VERSION_UNIQUE_NAME@ + +#endif /* !_DB_INT_DEF_IN_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/lock_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/lock_ext.h new file mode 100644 index 00000000..c7993928 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/lock_ext.h @@ -0,0 +1,71 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _lock_ext_h_ +#define _lock_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __lock_vec_pp __P((DB_ENV *, u_int32_t, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **)); +int __lock_vec __P((ENV *, DB_LOCKER *, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **)); +int __lock_get_pp __P((DB_ENV *, u_int32_t, u_int32_t, DBT *, db_lockmode_t, DB_LOCK *)); +int __lock_get __P((ENV *, DB_LOCKER *, u_int32_t, const DBT *, db_lockmode_t, DB_LOCK *)); +int __lock_get_internal __P((DB_LOCKTAB *, DB_LOCKER *, u_int32_t, const DBT *, db_lockmode_t, db_timeout_t, DB_LOCK *)); +int __lock_put_pp __P((DB_ENV *, DB_LOCK *)); +int __lock_put __P((ENV *, DB_LOCK *)); +int __lock_downgrade __P((ENV *, DB_LOCK *, db_lockmode_t, u_int32_t)); +int __lock_locker_is_parent __P((ENV *, DB_LOCKER *, DB_LOCKER *, int *)); +int __lock_promote __P((DB_LOCKTAB *, DB_LOCKOBJ *, int *, u_int32_t)); +int __lock_detect_pp __P((DB_ENV *, u_int32_t, u_int32_t, int *)); +int __lock_detect __P((ENV *, u_int32_t, int *)); +int __lock_failchk __P((ENV *)); +int __lock_id_pp __P((DB_ENV *, u_int32_t *)); +int __lock_id __P((ENV *, u_int32_t *, DB_LOCKER **)); +void __lock_set_thread_id __P((void *, pid_t, db_threadid_t)); +int __lock_id_free_pp __P((DB_ENV *, u_int32_t)); +int __lock_id_free __P((ENV *, DB_LOCKER *)); +int __lock_id_set __P((ENV *, u_int32_t, u_int32_t)); +int __lock_getlocker __P((DB_LOCKTAB *, u_int32_t, int, DB_LOCKER **)); +int __lock_getlocker_int __P((DB_LOCKTAB *, u_int32_t, int, DB_LOCKER **)); +int __lock_addfamilylocker __P((ENV *, u_int32_t, u_int32_t)); +int __lock_freefamilylocker __P((DB_LOCKTAB *, DB_LOCKER *)); +int __lock_freelocker __P((DB_LOCKTAB *, DB_LOCKREGION *, DB_LOCKER *)); +int __lock_fix_list __P((ENV *, DBT *, u_int32_t)); +int __lock_get_list __P((ENV *, DB_LOCKER *, u_int32_t, db_lockmode_t, DBT *)); +void __lock_list_print __P((ENV *, DBT *)); +int __lock_env_create __P((DB_ENV *)); +void __lock_env_destroy __P((DB_ENV *)); +int __lock_get_lk_conflicts __P((DB_ENV *, const u_int8_t **, int *)); +int __lock_set_lk_conflicts __P((DB_ENV *, u_int8_t *, int)); +int __lock_get_lk_detect __P((DB_ENV *, u_int32_t *)); +int __lock_set_lk_detect __P((DB_ENV *, u_int32_t)); +int __lock_get_lk_max_locks __P((DB_ENV *, u_int32_t *)); +int __lock_set_lk_max_locks __P((DB_ENV *, u_int32_t)); +int __lock_get_lk_max_lockers __P((DB_ENV *, u_int32_t *)); +int __lock_set_lk_max_lockers __P((DB_ENV *, u_int32_t)); +int __lock_get_lk_max_objects __P((DB_ENV *, u_int32_t *)); +int __lock_set_lk_max_objects __P((DB_ENV *, u_int32_t)); +int __lock_get_lk_partitions __P((DB_ENV *, u_int32_t *)); +int __lock_set_lk_partitions __P((DB_ENV *, u_int32_t)); +int __lock_get_env_timeout __P((DB_ENV *, db_timeout_t *, u_int32_t)); +int __lock_set_env_timeout __P((DB_ENV *, db_timeout_t, u_int32_t)); +int __lock_open __P((ENV *, int)); +int __lock_env_refresh __P((ENV *)); +u_int32_t __lock_region_mutex_count __P((ENV *)); +int __lock_stat_pp __P((DB_ENV *, DB_LOCK_STAT **, u_int32_t)); +int __lock_stat_print_pp __P((DB_ENV *, u_int32_t)); +int __lock_stat_print __P((ENV *, u_int32_t)); +void __lock_printlock __P((DB_LOCKTAB *, DB_MSGBUF *mbp, struct __db_lock *, int)); +int __lock_set_timeout __P((ENV *, DB_LOCKER *, db_timeout_t, u_int32_t)); +int __lock_set_timeout_internal __P((ENV *, DB_LOCKER *, db_timeout_t, u_int32_t)); +int __lock_inherit_timeout __P((ENV *, DB_LOCKER *, DB_LOCKER *)); +void __lock_expires __P((ENV *, db_timespec *, db_timeout_t)); +int __lock_expired __P((ENV *, db_timespec *, db_timespec *)); +u_int32_t __lock_ohash __P((const DBT *)); +u_int32_t __lock_lhash __P((DB_LOCKOBJ *)); +int __lock_nomem __P((ENV *, const char *)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_lock_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/log_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/log_ext.h new file mode 100644 index 00000000..a161c855 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/log_ext.h @@ -0,0 +1,75 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _log_ext_h_ +#define _log_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __log_open __P((ENV *, int)); +int __log_find __P((DB_LOG *, int, u_int32_t *, logfile_validity *)); +int __log_valid __P((DB_LOG *, u_int32_t, int, DB_FH **, u_int32_t, logfile_validity *, u_int32_t *)); +int __log_env_refresh __P((ENV *)); +int __log_get_cached_ckp_lsn __P((ENV *, DB_LSN *)); +u_int32_t __log_region_mutex_count __P((ENV *)); +int __log_vtruncate __P((ENV *, DB_LSN *, DB_LSN *, DB_LSN *)); +int __log_is_outdated __P((ENV *, u_int32_t, int *)); +int __log_zero __P((ENV *, DB_LSN *)); +int __log_inmem_lsnoff __P((DB_LOG *, DB_LSN *, size_t *)); +int __log_inmem_newfile __P((DB_LOG *, u_int32_t)); +int __log_inmem_chkspace __P((DB_LOG *, size_t)); +void __log_inmem_copyout __P((DB_LOG *, size_t, void *, size_t)); +void __log_inmem_copyin __P((DB_LOG *, size_t, void *, size_t)); +void __log_set_version __P((ENV *, u_int32_t)); +int __log_get_oldversion __P((ENV *, u_int32_t *)); +int __log_archive_pp __P((DB_ENV *, char **[], u_int32_t)); +int __log_get_stable_lsn __P((ENV *, DB_LSN *)); +void __log_autoremove __P((ENV *)); +int __log_check_page_lsn __P((ENV *, DB *, DB_LSN *)); +int __log_printf_capi __P((DB_ENV *, DB_TXN *, const char *, ...)) __attribute__ ((__format__ (__printf__, 3, 4))); +int __log_printf_pp __P((DB_ENV *, DB_TXN *, const char *, va_list)); +int __log_printf __P((ENV *, DB_TXN *, const char *, ...)) __attribute__ ((__format__ (__printf__, 3, 4))); +int __log_cursor_pp __P((DB_ENV *, DB_LOGC **, u_int32_t)); +int __log_cursor __P((ENV *, DB_LOGC **)); +int __logc_close __P((DB_LOGC *)); +int __logc_version __P((DB_LOGC *, u_int32_t *)); +int __logc_get __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t)); +void __log_hdrswap __P((HDR *, int)); +void __log_persistswap __P((LOGP *)); +int __log_rep_split __P((ENV *, DB_THREAD_INFO *, __rep_control_args *, DBT *, DB_LSN *, DB_LSN *)); +int __log_env_create __P((DB_ENV *)); +void __log_env_destroy __P((DB_ENV *)); +int __log_get_lg_bsize __P((DB_ENV *, u_int32_t *)); +int __log_set_lg_bsize __P((DB_ENV *, u_int32_t)); +int __log_get_lg_filemode __P((DB_ENV *, int *)); +int __log_set_lg_filemode __P((DB_ENV *, int)); +int __log_get_lg_max __P((DB_ENV *, u_int32_t *)); +int __log_set_lg_max __P((DB_ENV *, u_int32_t)); +int __log_get_lg_regionmax __P((DB_ENV *, u_int32_t *)); +int __log_set_lg_regionmax __P((DB_ENV *, u_int32_t)); +int __log_get_lg_dir __P((DB_ENV *, const char **)); +int __log_set_lg_dir __P((DB_ENV *, const char *)); +void __log_get_flags __P((DB_ENV *, u_int32_t *)); +void __log_set_flags __P((ENV *, u_int32_t, int)); +int __log_get_config __P((DB_ENV *, u_int32_t, int *)); +int __log_set_config __P((DB_ENV *, u_int32_t, int)); +int __log_set_config_int __P((DB_ENV *, u_int32_t, int, int)); +int __log_check_sizes __P((ENV *, u_int32_t, u_int32_t)); +int __log_put_pp __P((DB_ENV *, DB_LSN *, const DBT *, u_int32_t)); +int __log_put __P((ENV *, DB_LSN *, const DBT *, u_int32_t)); +int __log_current_lsn __P((ENV *, DB_LSN *, u_int32_t *, u_int32_t *)); +int __log_newfile __P((DB_LOG *, DB_LSN *, u_int32_t, u_int32_t)); +int __log_flush_pp __P((DB_ENV *, const DB_LSN *)); +int __log_flush __P((ENV *, const DB_LSN *)); +int __log_flush_int __P((DB_LOG *, const DB_LSN *, int)); +int __log_file_pp __P((DB_ENV *, const DB_LSN *, char *, size_t)); +int __log_name __P((DB_LOG *, u_int32_t, char **, DB_FH **, u_int32_t)); +int __log_rep_put __P((ENV *, DB_LSN *, const DBT *, u_int32_t)); +int __log_stat_pp __P((DB_ENV *, DB_LOG_STAT **, u_int32_t)); +int __log_stat_print_pp __P((DB_ENV *, u_int32_t)); +int __log_stat_print __P((ENV *, u_int32_t)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_log_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/mp_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/mp_ext.h new file mode 100644 index 00000000..be63746d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/mp_ext.h @@ -0,0 +1,98 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _mp_ext_h_ +#define _mp_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __memp_alloc __P((DB_MPOOL *, REGINFO *, MPOOLFILE *, size_t, roff_t *, void *)); +void __memp_free __P((REGINFO *, void *)); +int __memp_bhwrite __P((DB_MPOOL *, DB_MPOOL_HASH *, MPOOLFILE *, BH *, int)); +int __memp_pgread __P((DB_MPOOLFILE *, BH *, int)); +int __memp_pg __P((DB_MPOOLFILE *, db_pgno_t, void *, int)); +int __memp_bhfree __P((DB_MPOOL *, REGINFO *, MPOOLFILE *, DB_MPOOL_HASH *, BH *, u_int32_t)); +int __memp_fget_pp __P((DB_MPOOLFILE *, db_pgno_t *, DB_TXN *, u_int32_t, void *)); +int __memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, DB_THREAD_INFO *, DB_TXN *, u_int32_t, void *)); +int __memp_fcreate_pp __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t)); +int __memp_fcreate __P((ENV *, DB_MPOOLFILE **)); +int __memp_set_clear_len __P((DB_MPOOLFILE *, u_int32_t)); +int __memp_get_fileid __P((DB_MPOOLFILE *, u_int8_t *)); +int __memp_set_fileid __P((DB_MPOOLFILE *, u_int8_t *)); +int __memp_get_flags __P((DB_MPOOLFILE *, u_int32_t *)); +int __memp_set_flags __P((DB_MPOOLFILE *, u_int32_t, int)); +int __memp_get_ftype __P((DB_MPOOLFILE *, int *)); +int __memp_set_ftype __P((DB_MPOOLFILE *, int)); +int __memp_set_lsn_offset __P((DB_MPOOLFILE *, int32_t)); +int __memp_get_pgcookie __P((DB_MPOOLFILE *, DBT *)); +int __memp_set_pgcookie __P((DB_MPOOLFILE *, DBT *)); +int __memp_get_last_pgno __P((DB_MPOOLFILE *, db_pgno_t *)); +char * __memp_fn __P((DB_MPOOLFILE *)); +char * __memp_fns __P((DB_MPOOL *, MPOOLFILE *)); +int __memp_fopen_pp __P((DB_MPOOLFILE *, const char *, u_int32_t, int, size_t)); +int __memp_fopen __P((DB_MPOOLFILE *, MPOOLFILE *, const char *, const char **, u_int32_t, int, size_t)); +int __memp_fclose_pp __P((DB_MPOOLFILE *, u_int32_t)); +int __memp_fclose __P((DB_MPOOLFILE *, u_int32_t)); +int __memp_mf_discard __P((DB_MPOOL *, MPOOLFILE *)); +int __memp_inmemlist __P((ENV *, char ***, int *)); +int __memp_fput_pp __P((DB_MPOOLFILE *, void *, DB_CACHE_PRIORITY, u_int32_t)); +int __memp_fput __P((DB_MPOOLFILE *, DB_THREAD_INFO *, void *, DB_CACHE_PRIORITY)); +int __memp_unpin_buffers __P((ENV *, DB_THREAD_INFO *)); +int __memp_dirty __P((DB_MPOOLFILE *, void *, DB_THREAD_INFO *, DB_TXN *, DB_CACHE_PRIORITY, u_int32_t)); +int __memp_shared __P((DB_MPOOLFILE *, void *)); +int __memp_env_create __P((DB_ENV *)); +void __memp_env_destroy __P((DB_ENV *)); +int __memp_get_cachesize __P((DB_ENV *, u_int32_t *, u_int32_t *, int *)); +int __memp_set_cachesize __P((DB_ENV *, u_int32_t, u_int32_t, int)); +int __memp_set_config __P((DB_ENV *, u_int32_t, int)); +int __memp_get_config __P((DB_ENV *, u_int32_t, int *)); +int __memp_get_mp_max_openfd __P((DB_ENV *, int *)); +int __memp_set_mp_max_openfd __P((DB_ENV *, int)); +int __memp_get_mp_max_write __P((DB_ENV *, int *, db_timeout_t *)); +int __memp_set_mp_max_write __P((DB_ENV *, int, db_timeout_t)); +int __memp_get_mp_mmapsize __P((DB_ENV *, size_t *)); +int __memp_set_mp_mmapsize __P((DB_ENV *, size_t)); +int __memp_get_mp_pagesize __P((DB_ENV *, u_int32_t *)); +int __memp_set_mp_pagesize __P((DB_ENV *, u_int32_t)); +int __memp_get_mp_tablesize __P((DB_ENV *, u_int32_t *)); +int __memp_set_mp_tablesize __P((DB_ENV *, u_int32_t)); +int __memp_nameop __P((ENV *, u_int8_t *, const char *, const char *, const char *, int)); +int __memp_ftruncate __P((DB_MPOOLFILE *, DB_TXN *, DB_THREAD_INFO *, db_pgno_t, u_int32_t)); +int __memp_alloc_freelist __P((DB_MPOOLFILE *, u_int32_t, db_pgno_t **)); +int __memp_free_freelist __P((DB_MPOOLFILE *)); +int __memp_get_freelist __P(( DB_MPOOLFILE *, u_int32_t *, db_pgno_t **)); +int __memp_extend_freelist __P(( DB_MPOOLFILE *, u_int32_t , db_pgno_t **)); +void __memp_set_last_pgno __P((DB_MPOOLFILE *, db_pgno_t)); +int __memp_bh_settxn __P((DB_MPOOL *, MPOOLFILE *mfp, BH *, void *)); +int __memp_skip_curadj __P((DBC *, db_pgno_t)); +int __memp_bh_freeze __P((DB_MPOOL *, REGINFO *, DB_MPOOL_HASH *, BH *, int *)); +int __memp_bh_thaw __P((DB_MPOOL *, REGINFO *, DB_MPOOL_HASH *, BH *, BH *)); +int __memp_open __P((ENV *, int)); +int __memp_init __P((ENV *, DB_MPOOL *, u_int, u_int32_t, u_int)); +u_int32_t __memp_max_regions __P((ENV *)); +u_int32_t __memp_region_mutex_count __P((ENV *)); +int __memp_env_refresh __P((ENV *)); +int __memp_register_pp __P((DB_ENV *, int, int (*)(DB_ENV *, db_pgno_t, void *, DBT *), int (*)(DB_ENV *, db_pgno_t, void *, DBT *))); +int __memp_register __P((ENV *, int, int (*)(DB_ENV *, db_pgno_t, void *, DBT *), int (*)(DB_ENV *, db_pgno_t, void *, DBT *))); +int __memp_get_bucket __P((ENV *, MPOOLFILE *, db_pgno_t, REGINFO **, DB_MPOOL_HASH **, u_int32_t *)); +int __memp_resize __P((DB_MPOOL *, u_int32_t, u_int32_t)); +int __memp_get_cache_max __P((DB_ENV *, u_int32_t *, u_int32_t *)); +int __memp_set_cache_max __P((DB_ENV *, u_int32_t, u_int32_t)); +int __memp_stat_pp __P((DB_ENV *, DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t)); +int __memp_stat_print_pp __P((DB_ENV *, u_int32_t)); +int __memp_stat_print __P((ENV *, u_int32_t)); +void __memp_stat_hash __P((REGINFO *, MPOOL *, u_int32_t *)); +int __memp_walk_files __P((ENV *, MPOOL *, int (*) __P((ENV *, MPOOLFILE *, void *, u_int32_t *, u_int32_t)), void *, u_int32_t *, u_int32_t)); +int __memp_sync_pp __P((DB_ENV *, DB_LSN *)); +int __memp_sync __P((ENV *, u_int32_t, DB_LSN *)); +int __memp_fsync_pp __P((DB_MPOOLFILE *)); +int __memp_fsync __P((DB_MPOOLFILE *)); +int __mp_xxx_fh __P((DB_MPOOLFILE *, DB_FH **)); +int __memp_sync_int __P((ENV *, DB_MPOOLFILE *, u_int32_t, u_int32_t, u_int32_t *, int *)); +int __memp_mf_sync __P((DB_MPOOL *, MPOOLFILE *, int)); +int __memp_trickle_pp __P((DB_ENV *, int, int *)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_mp_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/mutex_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/mutex_ext.h new file mode 100644 index 00000000..49673d63 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/mutex_ext.h @@ -0,0 +1,80 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _mutex_ext_h_ +#define _mutex_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __mutex_alloc __P((ENV *, int, u_int32_t, db_mutex_t *)); +int __mutex_alloc_int __P((ENV *, int, int, u_int32_t, db_mutex_t *)); +int __mutex_free __P((ENV *, db_mutex_t *)); +int __mutex_free_int __P((ENV *, int, db_mutex_t *)); +int __mut_failchk __P((ENV *)); +int __db_fcntl_mutex_init __P((ENV *, db_mutex_t, u_int32_t)); +int __db_fcntl_mutex_lock __P((ENV *, db_mutex_t)); +int __db_fcntl_mutex_trylock __P((ENV *, db_mutex_t)); +int __db_fcntl_mutex_unlock __P((ENV *, db_mutex_t)); +int __db_fcntl_mutex_destroy __P((ENV *, db_mutex_t)); +int __mutex_alloc_pp __P((DB_ENV *, u_int32_t, db_mutex_t *)); +int __mutex_free_pp __P((DB_ENV *, db_mutex_t)); +int __mutex_lock_pp __P((DB_ENV *, db_mutex_t)); +int __mutex_unlock_pp __P((DB_ENV *, db_mutex_t)); +int __mutex_get_align __P((DB_ENV *, u_int32_t *)); +int __mutex_set_align __P((DB_ENV *, u_int32_t)); +int __mutex_get_increment __P((DB_ENV *, u_int32_t *)); +int __mutex_set_increment __P((DB_ENV *, u_int32_t)); +int __mutex_get_max __P((DB_ENV *, u_int32_t *)); +int __mutex_set_max __P((DB_ENV *, u_int32_t)); +int __mutex_get_tas_spins __P((DB_ENV *, u_int32_t *)); +int __mutex_set_tas_spins __P((DB_ENV *, u_int32_t)); +#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT) +atomic_value_t __atomic_inc __P((ENV *, db_atomic_t *)); +#endif +#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT) +atomic_value_t __atomic_dec __P((ENV *, db_atomic_t *)); +#endif +int __db_pthread_mutex_init __P((ENV *, db_mutex_t, u_int32_t)); +int __db_pthread_mutex_lock __P((ENV *, db_mutex_t)); +#if defined(HAVE_SHARED_LATCHES) +int __db_pthread_mutex_readlock __P((ENV *, db_mutex_t)); +#endif +int __db_pthread_mutex_unlock __P((ENV *, db_mutex_t)); +int __db_pthread_mutex_destroy __P((ENV *, db_mutex_t)); +int __mutex_open __P((ENV *, int)); +int __mutex_env_refresh __P((ENV *)); +void __mutex_resource_return __P((ENV *, REGINFO *)); +int __mutex_stat_pp __P((DB_ENV *, DB_MUTEX_STAT **, u_int32_t)); +int __mutex_stat_print_pp __P((DB_ENV *, u_int32_t)); +int __mutex_stat_print __P((ENV *, u_int32_t)); +void __mutex_print_debug_single __P((ENV *, const char *, db_mutex_t, u_int32_t)); +void __mutex_print_debug_stats __P((ENV *, DB_MSGBUF *, db_mutex_t, u_int32_t)); +void __mutex_set_wait_info __P((ENV *, db_mutex_t, uintmax_t *, uintmax_t *)); +void __mutex_clear __P((ENV *, db_mutex_t)); +int __db_tas_mutex_init __P((ENV *, db_mutex_t, u_int32_t)); +int __db_tas_mutex_lock __P((ENV *, db_mutex_t)); +int __db_tas_mutex_trylock __P((ENV *, db_mutex_t)); +#if defined(HAVE_SHARED_LATCHES) +int __db_tas_mutex_readlock __P((ENV *, db_mutex_t)); +#endif +#if defined(HAVE_SHARED_LATCHES) +int __db_tas_mutex_tryreadlock __P((ENV *, db_mutex_t)); +#endif +int __db_tas_mutex_unlock __P((ENV *, db_mutex_t)); +int __db_tas_mutex_destroy __P((ENV *, db_mutex_t)); +int __db_win32_mutex_init __P((ENV *, db_mutex_t, u_int32_t)); +int __db_win32_mutex_lock __P((ENV *, db_mutex_t)); +int __db_win32_mutex_trylock __P((ENV *, db_mutex_t)); +#if defined(HAVE_SHARED_LATCHES) +int __db_win32_mutex_readlock __P((ENV *, db_mutex_t)); +#endif +#if defined(HAVE_SHARED_LATCHES) +int __db_win32_mutex_tryreadlock __P((ENV *, db_mutex_t)); +#endif +int __db_win32_mutex_unlock __P((ENV *, db_mutex_t)); +int __db_win32_mutex_destroy __P((ENV *, db_mutex_t)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_mutex_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/os_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/os_ext.h new file mode 100644 index 00000000..d786d237 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/os_ext.h @@ -0,0 +1,101 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _os_ext_h_ +#define _os_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +void __os_abort __P((ENV *)); +int __os_abspath __P((const char *)); +#if defined(HAVE_REPLICATION_THREADS) +int __os_getaddrinfo __P((ENV *, const char *, u_int, const char *, const ADDRINFO *, ADDRINFO **)); +#endif +#if defined(HAVE_REPLICATION_THREADS) +void __os_freeaddrinfo __P((ENV *, ADDRINFO *)); +#endif +int __os_umalloc __P((ENV *, size_t, void *)); +int __os_urealloc __P((ENV *, size_t, void *)); +void __os_ufree __P((ENV *, void *)); +int __os_strdup __P((ENV *, const char *, void *)); +int __os_calloc __P((ENV *, size_t, size_t, void *)); +int __os_malloc __P((ENV *, size_t, void *)); +int __os_realloc __P((ENV *, size_t, void *)); +void __os_free __P((ENV *, void *)); +void *__ua_memcpy __P((void *, const void *, size_t)); +void __os_gettime __P((ENV *, db_timespec *, int)); +int __os_fs_notzero __P((void)); +int __os_support_direct_io __P((void)); +int __os_support_db_register __P((void)); +int __os_support_replication __P((void)); +u_int32_t __os_cpu_count __P((void)); +char *__os_ctime __P((const time_t *, char *)); +int __os_dirlist __P((ENV *, const char *, int, char ***, int *)); +void __os_dirfree __P((ENV *, char **, int)); +int __os_get_errno_ret_zero __P((void)); +int __os_get_errno __P((void)); +int __os_get_neterr __P((void)); +int __os_get_syserr __P((void)); +void __os_set_errno __P((int)); +char *__os_strerror __P((int, char *, size_t)); +int __os_posix_err __P((int)); +int __os_fileid __P((ENV *, const char *, int, u_int8_t *)); +int __os_fdlock __P((ENV *, DB_FH *, off_t, int, int)); +int __os_fsync __P((ENV *, DB_FH *)); +int __os_getenv __P((ENV *, const char *, char **, size_t)); +int __os_openhandle __P((ENV *, const char *, int, int, DB_FH **)); +int __os_closehandle __P((ENV *, DB_FH *)); +int __os_attach __P((ENV *, REGINFO *, REGION *)); +int __os_detach __P((ENV *, REGINFO *, int)); +int __os_mapfile __P((ENV *, char *, DB_FH *, size_t, int, void **)); +int __os_unmapfile __P((ENV *, void *, size_t)); +int __os_mkdir __P((ENV *, const char *, int)); +int __os_open __P((ENV *, const char *, u_int32_t, u_int32_t, int, DB_FH **)); +void __os_id __P((DB_ENV *, pid_t *, db_threadid_t*)); +int __os_rename __P((ENV *, const char *, const char *, u_int32_t)); +int __os_isroot __P((void)); +char *__db_rpath __P((const char *)); +int __os_io __P((ENV *, int, DB_FH *, db_pgno_t, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, size_t *)); +int __os_read __P((ENV *, DB_FH *, void *, size_t, size_t *)); +int __os_write __P((ENV *, DB_FH *, void *, size_t, size_t *)); +int __os_physwrite __P((ENV *, DB_FH *, void *, size_t, size_t *)); +int __os_seek __P((ENV *, DB_FH *, db_pgno_t, u_int32_t, u_int32_t)); +void __os_stack __P((ENV *)); +int __os_exists __P((ENV *, const char *, int *)); +int __os_ioinfo __P((ENV *, const char *, DB_FH *, u_int32_t *, u_int32_t *, u_int32_t *)); +int __os_tmpdir __P((ENV *, u_int32_t)); +int __os_truncate __P((ENV *, DB_FH *, db_pgno_t, u_int32_t)); +void __os_unique_id __P((ENV *, u_int32_t *)); +int __os_unlink __P((ENV *, const char *, int)); +void __os_yield __P((ENV *, u_long, u_long)); +#ifndef HAVE_FCLOSE +int fclose __P((FILE *)); +#endif +#ifndef HAVE_FGETC +int fgetc __P((FILE *)); +#endif +#ifndef HAVE_FGETS +char *fgets __P((char *, int, FILE *)); +#endif +#ifndef HAVE_FOPEN +FILE *fopen __P((const char *, const char *)); +#endif +#ifndef HAVE_FWRITE +size_t fwrite __P((const void *, size_t, size_t, FILE *)); +#endif +#ifndef HAVE_LOCALTIME +struct tm *localtime __P((const time_t *)); +#endif +#ifdef HAVE_QNX +int __os_qnx_region_open __P((ENV *, const char *, int, int, DB_FH **)); +#endif +int __os_is_winnt __P((void)); +u_int32_t __os_cpu_count __P((void)); +#ifdef HAVE_REPLICATION_THREADS +int __os_get_neterr __P((void)); +#endif + +#if defined(__cplusplus) +} +#endif +#endif /* !_os_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/qam_auto.h b/src/libs/resiprocate/contrib/db/dbinc_auto/qam_auto.h new file mode 100644 index 00000000..3b80956a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/qam_auto.h @@ -0,0 +1,70 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#ifndef __qam_AUTO_H +#define __qam_AUTO_H +#define DB___qam_incfirst 84 +typedef struct ___qam_incfirst_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + db_recno_t recno; + db_pgno_t meta_pgno; +} __qam_incfirst_args; + +#define DB___qam_mvptr 85 +typedef struct ___qam_mvptr_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t opcode; + int32_t fileid; + db_recno_t old_first; + db_recno_t new_first; + db_recno_t old_cur; + db_recno_t new_cur; + DB_LSN metalsn; + db_pgno_t meta_pgno; +} __qam_mvptr_args; + +#define DB___qam_del 79 +typedef struct ___qam_del_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + DB_LSN lsn; + db_pgno_t pgno; + u_int32_t indx; + db_recno_t recno; +} __qam_del_args; + +#define DB___qam_add 80 +typedef struct ___qam_add_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + DB_LSN lsn; + db_pgno_t pgno; + u_int32_t indx; + db_recno_t recno; + DBT data; + u_int32_t vflag; + DBT olddata; +} __qam_add_args; + +#define DB___qam_delext 83 +typedef struct ___qam_delext_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + int32_t fileid; + DB_LSN lsn; + db_pgno_t pgno; + u_int32_t indx; + db_recno_t recno; + DBT data; +} __qam_delext_args; + +#endif diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/qam_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/qam_ext.h new file mode 100644 index 00000000..5a886aa3 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/qam_ext.h @@ -0,0 +1,77 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _qam_ext_h_ +#define _qam_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __qam_position __P((DBC *, db_recno_t *, u_int32_t, int *)); +int __qam_pitem __P((DBC *, QPAGE *, u_int32_t, db_recno_t, DBT *)); +int __qam_append __P((DBC *, DBT *, DBT *)); +int __qamc_dup __P((DBC *, DBC *)); +int __qamc_init __P((DBC *)); +int __qam_truncate __P((DBC *, u_int32_t *)); +int __qam_delete __P((DBC *, DBT *, u_int32_t)); +int __qam_incfirst_read __P((ENV *, DB **, void *, void *, __qam_incfirst_args **)); +int __qam_incfirst_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, db_recno_t, db_pgno_t)); +int __qam_mvptr_read __P((ENV *, DB **, void *, void *, __qam_mvptr_args **)); +int __qam_mvptr_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, db_recno_t, db_recno_t, db_recno_t, db_recno_t, DB_LSN *, db_pgno_t)); +int __qam_del_read __P((ENV *, DB **, void *, void *, __qam_del_args **)); +int __qam_del_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, DB_LSN *, db_pgno_t, u_int32_t, db_recno_t)); +int __qam_add_read __P((ENV *, DB **, void *, void *, __qam_add_args **)); +int __qam_add_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, DB_LSN *, db_pgno_t, u_int32_t, db_recno_t, const DBT *, u_int32_t, const DBT *)); +int __qam_delext_read __P((ENV *, DB **, void *, void *, __qam_delext_args **)); +int __qam_delext_log __P((DB *, DB_TXN *, DB_LSN *, u_int32_t, DB_LSN *, db_pgno_t, u_int32_t, db_recno_t, const DBT *)); +int __qam_init_recover __P((ENV *, DB_DISTAB *)); +int __qam_incfirst_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __qam_mvptr_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __qam_del_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __qam_add_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __qam_delext_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __qam_init_print __P((ENV *, DB_DISTAB *)); +int __qam_mswap __P((ENV *, PAGE *)); +int __qam_pgin_out __P((ENV *, db_pgno_t, void *, DBT *)); +int __qam_fprobe __P((DBC *, db_pgno_t, void *, qam_probe_mode, DB_CACHE_PRIORITY, u_int32_t)); +int __qam_fclose __P((DB *, db_pgno_t)); +int __qam_fremove __P((DB *, db_pgno_t)); +int __qam_sync __P((DB *)); +int __qam_gen_filelist __P((DB *, DB_THREAD_INFO *, QUEUE_FILELIST **)); +int __qam_extent_names __P((ENV *, char *, char ***)); +void __qam_exid __P((DB *, u_int8_t *, u_int32_t)); +int __qam_nameop __P((DB *, DB_TXN *, const char *, qam_name_op)); +int __qam_lsn_reset __P((DB *, DB_THREAD_INFO *)); +int __qam_db_create __P((DB *)); +int __qam_db_close __P((DB *, u_int32_t)); +int __qam_get_extentsize __P((DB *, u_int32_t *)); +int __queue_pageinfo __P((DB *, db_pgno_t *, db_pgno_t *, int *, int, u_int32_t)); +int __db_prqueue __P((DB *, u_int32_t)); +int __qam_remove __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, u_int32_t)); +int __qam_rename __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, const char *)); +void __qam_map_flags __P((DB *, u_int32_t *, u_int32_t *)); +int __qam_set_flags __P((DB *, u_int32_t *flagsp)); +int __qam_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, db_pgno_t, int, u_int32_t)); +int __qam_set_ext_data __P((DB*, const char *)); +int __qam_metachk __P((DB *, const char *, QMETA *)); +int __qam_new_file __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *)); +int __qam_incfirst_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __qam_mvptr_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __qam_del_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __qam_delext_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __qam_add_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __qam_stat __P((DBC *, void *, u_int32_t)); +int __qam_stat_print __P((DBC *, u_int32_t)); +int __db_no_queue_am __P((ENV *)); +int __qam_31_qammeta __P((DB *, char *, u_int8_t *)); +int __qam_32_qammeta __P((DB *, char *, u_int8_t *)); +int __qam_vrfy_meta __P((DB *, VRFY_DBINFO *, QMETA *, db_pgno_t, u_int32_t)); +int __qam_meta2pgset __P((DB *, VRFY_DBINFO *, DB *)); +int __qam_vrfy_data __P((DB *, VRFY_DBINFO *, QPAGE *, db_pgno_t, u_int32_t)); +int __qam_vrfy_structure __P((DB *, VRFY_DBINFO *, u_int32_t)); +int __qam_vrfy_walkqueue __P((DB *, VRFY_DBINFO *, void *, int (*)(void *, const void *), u_int32_t)); +int __qam_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *, void *, int (*)(void *, const void *), u_int32_t)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_qam_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/rep_auto.h b/src/libs/resiprocate/contrib/db/dbinc_auto/rep_auto.h new file mode 100644 index 00000000..a28b0c37 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/rep_auto.h @@ -0,0 +1,81 @@ +/* Do not edit: automatically built by gen_msg.awk. */ + +#ifndef __rep_AUTO_H +#define __rep_AUTO_H + +/* + * Message sizes are simply the sum of field sizes (not + * counting variable size parts, when DBTs are present), + * and may be different from struct sizes due to padding. + */ +#define __REP_BULK_SIZE 16 +typedef struct ___rep_bulk_args { + u_int32_t len; + DB_LSN lsn; + DBT bulkdata; +} __rep_bulk_args; + +#define __REP_CONTROL_SIZE 36 +typedef struct ___rep_control_args { + u_int32_t rep_version; + u_int32_t log_version; + DB_LSN lsn; + u_int32_t rectype; + u_int32_t gen; + u_int32_t msg_sec; + u_int32_t msg_nsec; + u_int32_t flags; +} __rep_control_args; + +#define __REP_EGEN_SIZE 4 +typedef struct ___rep_egen_args { + u_int32_t egen; +} __rep_egen_args; + +#define __REP_FILEINFO_SIZE 36 +typedef struct ___rep_fileinfo_args { + u_int32_t pgsize; + db_pgno_t pgno; + db_pgno_t max_pgno; + u_int32_t filenum; + u_int32_t finfo_flags; + u_int32_t type; + u_int32_t db_flags; + DBT uid; + DBT info; +} __rep_fileinfo_args; + +#define __REP_GRANT_INFO_SIZE 8 +typedef struct ___rep_grant_info_args { + u_int32_t msg_sec; + u_int32_t msg_nsec; +} __rep_grant_info_args; + +#define __REP_LOGREQ_SIZE 8 +typedef struct ___rep_logreq_args { + DB_LSN endlsn; +} __rep_logreq_args; + +#define __REP_NEWFILE_SIZE 4 +typedef struct ___rep_newfile_args { + u_int32_t version; +} __rep_newfile_args; + +#define __REP_UPDATE_SIZE 16 +typedef struct ___rep_update_args { + DB_LSN first_lsn; + u_int32_t first_vers; + u_int32_t num_files; +} __rep_update_args; + +#define __REP_VOTE_INFO_SIZE 20 +typedef struct ___rep_vote_info_args { + u_int32_t egen; + u_int32_t nsites; + u_int32_t nvotes; + u_int32_t priority; + u_int32_t tiebreaker; +} __rep_vote_info_args; + +#define __REP_MAXMSG_SIZE 36 +#endif diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/rep_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/rep_ext.h new file mode 100644 index 00000000..cdb27ddd --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/rep_ext.h @@ -0,0 +1,128 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _rep_ext_h_ +#define _rep_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __rep_bulk_marshal __P((ENV *, __rep_bulk_args *, u_int8_t *, size_t, size_t *)); +int __rep_bulk_unmarshal __P((ENV *, __rep_bulk_args *, u_int8_t *, size_t, u_int8_t **)); +int __rep_control_marshal __P((ENV *, __rep_control_args *, u_int8_t *, size_t, size_t *)); +int __rep_control_unmarshal __P((ENV *, __rep_control_args *, u_int8_t *, size_t, u_int8_t **)); +int __rep_egen_marshal __P((ENV *, __rep_egen_args *, u_int8_t *, size_t, size_t *)); +int __rep_egen_unmarshal __P((ENV *, __rep_egen_args *, u_int8_t *, size_t, u_int8_t **)); +int __rep_fileinfo_marshal __P((ENV *, u_int32_t, __rep_fileinfo_args *, u_int8_t *, size_t, size_t *)); +int __rep_fileinfo_unmarshal __P((ENV *, u_int32_t, __rep_fileinfo_args **, u_int8_t *, size_t, u_int8_t **)); +int __rep_grant_info_marshal __P((ENV *, __rep_grant_info_args *, u_int8_t *, size_t, size_t *)); +int __rep_grant_info_unmarshal __P((ENV *, __rep_grant_info_args *, u_int8_t *, size_t, u_int8_t **)); +int __rep_logreq_marshal __P((ENV *, __rep_logreq_args *, u_int8_t *, size_t, size_t *)); +int __rep_logreq_unmarshal __P((ENV *, __rep_logreq_args *, u_int8_t *, size_t, u_int8_t **)); +int __rep_newfile_marshal __P((ENV *, __rep_newfile_args *, u_int8_t *, size_t, size_t *)); +int __rep_newfile_unmarshal __P((ENV *, __rep_newfile_args *, u_int8_t *, size_t, u_int8_t **)); +int __rep_update_marshal __P((ENV *, u_int32_t, __rep_update_args *, u_int8_t *, size_t, size_t *)); +int __rep_update_unmarshal __P((ENV *, u_int32_t, __rep_update_args **, u_int8_t *, size_t, u_int8_t **)); +int __rep_vote_info_marshal __P((ENV *, __rep_vote_info_args *, u_int8_t *, size_t, size_t *)); +int __rep_vote_info_unmarshal __P((ENV *, __rep_vote_info_args *, u_int8_t *, size_t, u_int8_t **)); +int __rep_update_req __P((ENV *, __rep_control_args *, int)); +int __rep_page_req __P((ENV *, DB_THREAD_INFO *, int, __rep_control_args *, DBT *)); +int __rep_update_setup __P((ENV *, int, __rep_control_args *, DBT *, time_t)); +int __rep_bulk_page __P((ENV *, DB_THREAD_INFO *, int, __rep_control_args *, DBT *)); +int __rep_page __P((ENV *, DB_THREAD_INFO *, int, __rep_control_args *, DBT *)); +int __rep_page_fail __P((ENV *, DB_THREAD_INFO *, int, __rep_control_args *, DBT *)); +int __rep_init_cleanup __P((ENV *, REP *, int)); +int __rep_pggap_req __P((ENV *, REP *, __rep_fileinfo_args *, u_int32_t)); +int __rep_finfo_alloc __P((ENV *, __rep_fileinfo_args *, __rep_fileinfo_args **)); +int __rep_remove_init_file __P((ENV *)); +int __rep_reset_init __P((ENV *)); +int __rep_elect_pp __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t)); +int __rep_elect_int __P((ENV *, u_int32_t, u_int32_t, u_int32_t)); +int __rep_vote1 __P((ENV *, __rep_control_args *, DBT *, int)); +int __rep_vote2 __P((ENV *, __rep_control_args *, DBT *, int)); +int __rep_update_grant __P((ENV *, db_timespec *)); +int __rep_islease_granted __P((ENV *)); +int __rep_lease_table_alloc __P((ENV *, u_int32_t)); +int __rep_lease_grant __P((ENV *, __rep_control_args *, DBT *, int)); +int __rep_lease_check __P((ENV *, int)); +int __rep_lease_refresh __P((ENV *)); +int __rep_lease_expire __P((ENV *)); +db_timeout_t __rep_lease_waittime __P((ENV *)); +int __rep_allreq __P((ENV *, __rep_control_args *, int)); +int __rep_log __P((ENV *, DB_THREAD_INFO *, __rep_control_args *, DBT *, time_t, DB_LSN *)); +int __rep_bulk_log __P((ENV *, DB_THREAD_INFO *, __rep_control_args *, DBT *, time_t, DB_LSN *)); +int __rep_logreq __P((ENV *, __rep_control_args *, DBT *, int)); +int __rep_loggap_req __P((ENV *, REP *, DB_LSN *, u_int32_t)); +int __rep_logready __P((ENV *, REP *, time_t, DB_LSN *)); +int __rep_env_create __P((DB_ENV *)); +void __rep_env_destroy __P((DB_ENV *)); +int __rep_get_config __P((DB_ENV *, u_int32_t, int *)); +int __rep_set_config __P((DB_ENV *, u_int32_t, int)); +int __rep_start_pp __P((DB_ENV *, DBT *, u_int32_t)); +int __rep_start_int __P((ENV *, DBT *, u_int32_t)); +int __rep_client_dbinit __P((ENV *, int, repdb_t)); +int __rep_get_limit __P((DB_ENV *, u_int32_t *, u_int32_t *)); +int __rep_set_limit __P((DB_ENV *, u_int32_t, u_int32_t)); +int __rep_set_nsites __P((DB_ENV *, u_int32_t)); +int __rep_get_nsites __P((DB_ENV *, u_int32_t *)); +int __rep_set_priority __P((DB_ENV *, u_int32_t)); +int __rep_get_priority __P((DB_ENV *, u_int32_t *)); +int __rep_set_timeout __P((DB_ENV *, int, db_timeout_t)); +int __rep_get_timeout __P((DB_ENV *, int, db_timeout_t *)); +int __rep_get_request __P((DB_ENV *, db_timeout_t *, db_timeout_t *)); +int __rep_set_request __P((DB_ENV *, db_timeout_t, db_timeout_t)); +int __rep_set_transport_pp __P((DB_ENV *, int, int (*)(DB_ENV *, const DBT *, const DBT *, const DB_LSN *, int, u_int32_t))); +int __rep_set_transport_int __P((ENV *, int, int (*)(DB_ENV *, const DBT *, const DBT *, const DB_LSN *, int, u_int32_t))); +int __rep_get_clockskew __P((DB_ENV *, u_int32_t *, u_int32_t *)); +int __rep_set_clockskew __P((DB_ENV *, u_int32_t, u_int32_t)); +int __rep_flush __P((DB_ENV *)); +int __rep_sync __P((DB_ENV *, u_int32_t)); +int __rep_process_message_pp __P((DB_ENV *, DBT *, DBT *, int, DB_LSN *)); +int __rep_process_message_int __P((ENV *, DBT *, DBT *, int, DB_LSN *)); +int __rep_apply __P((ENV *, DB_THREAD_INFO *, __rep_control_args *, DBT *, DB_LSN *, int *, DB_LSN *)); +int __rep_process_txn __P((ENV *, DBT *)); +int __rep_resend_req __P((ENV *, int)); +int __rep_check_doreq __P((ENV *, REP *)); +int __rep_open __P((ENV *)); +int __rep_env_refresh __P((ENV *)); +int __rep_env_close __P((ENV *)); +int __rep_preclose __P((ENV *)); +int __rep_closefiles __P((ENV *)); +int __rep_write_egen __P((ENV *, REP *, u_int32_t)); +int __rep_write_gen __P((ENV *, REP *, u_int32_t)); +int __rep_stat_pp __P((DB_ENV *, DB_REP_STAT **, u_int32_t)); +int __rep_stat_print_pp __P((DB_ENV *, u_int32_t)); +int __rep_stat_print __P((ENV *, u_int32_t)); +int __rep_bulk_message __P((ENV *, REP_BULK *, REP_THROTTLE *, DB_LSN *, const DBT *, u_int32_t)); +int __rep_send_bulk __P((ENV *, REP_BULK *, u_int32_t)); +int __rep_bulk_alloc __P((ENV *, REP_BULK *, int, uintptr_t *, u_int32_t *, u_int32_t)); +int __rep_bulk_free __P((ENV *, REP_BULK *, u_int32_t)); +int __rep_send_message __P((ENV *, int, u_int32_t, DB_LSN *, const DBT *, u_int32_t, u_int32_t)); +int __rep_new_master __P((ENV *, __rep_control_args *, int)); +int __rep_noarchive __P((ENV *)); +void __rep_send_vote __P((ENV *, DB_LSN *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, int, u_int32_t, u_int32_t)); +void __rep_elect_done __P((ENV *, REP *, int)); +int __env_rep_enter __P((ENV *, int)); +int __env_db_rep_exit __P((ENV *)); +int __db_rep_enter __P((DB *, int, int, int)); +int __op_rep_enter __P((ENV *)); +int __op_rep_exit __P((ENV *)); +int __rep_lockout_api __P((ENV *, REP *)); +int __rep_lockout_apply __P((ENV *, REP *, u_int32_t)); +int __rep_lockout_msg __P((ENV *, REP *, u_int32_t)); +int __rep_send_throttle __P((ENV *, int, REP_THROTTLE *, u_int32_t, u_int32_t)); +u_int32_t __rep_msg_to_old __P((u_int32_t, u_int32_t)); +u_int32_t __rep_msg_from_old __P((u_int32_t, u_int32_t)); +void __rep_print __P((ENV *, const char *, ...)) __attribute__ ((__format__ (__printf__, 2, 3))); +void __rep_print_message __P((ENV *, int, __rep_control_args *, char *, u_int32_t)); +void __rep_fire_event __P((ENV *, u_int32_t, void *)); +int __rep_verify __P((ENV *, __rep_control_args *, DBT *, int, time_t)); +int __rep_verify_fail __P((ENV *, __rep_control_args *)); +int __rep_verify_req __P((ENV *, __rep_control_args *, int)); +int __rep_dorecovery __P((ENV *, DB_LSN *, DB_LSN *)); +int __rep_verify_match __P((ENV *, DB_LSN *, time_t)); +int __rep_log_backup __P((ENV *, REP *, DB_LOGC *, DB_LSN *)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_rep_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/rpc_client_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/rpc_client_ext.h new file mode 100644 index 00000000..b5804713 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/rpc_client_ext.h @@ -0,0 +1,229 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _rpc_client_ext_h_ +#define _rpc_client_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __dbcl_envrpcserver __P((DB_ENV *, void *, const char *, long, long, u_int32_t)); +int __dbcl_env_close_wrap __P((DB_ENV *, u_int32_t)); +int __dbcl_env_open_wrap __P((DB_ENV *, const char *, u_int32_t, int)); +int __dbcl_db_open_wrap __P((DB *, DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int)); +int __dbcl_refresh __P((DB_ENV *)); +int __dbcl_retcopy __P((DB_ENV *, DBT *, void *, u_int32_t, void **, u_int32_t *)); +void __dbcl_txn_end __P((DB_TXN *)); +void __dbcl_txn_setup __P((DB_ENV *, DB_TXN *, DB_TXN *, u_int32_t)); +void __dbcl_c_refresh __P((DBC *)); +int __dbcl_c_setup __P((u_int, DB *, DBC **)); +int __dbcl_dbclose_common __P((DB *)); +int __dbcl_env_alloc __P((DB_ENV *, void *(*)(size_t), void *(*)(void *, size_t), void (*)(void *))); +int __dbcl_set_app_dispatch __P((DB_ENV *, int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops))); +int __dbcl_env_get_cachesize __P((DB_ENV *, u_int32_t *, u_int32_t *, int *)); +int __dbcl_env_cachesize __P((DB_ENV *, u_int32_t, u_int32_t, int)); +int __dbcl_env_close __P((DB_ENV *, u_int32_t)); +int __dbcl_env_create __P((DB_ENV *, long)); +int __dbcl_get_data_dirs __P((DB_ENV *, const char ***)); +int __dbcl_set_data_dir __P((DB_ENV *, const char *)); +int __dbcl_env_dbremove __P((DB_ENV *, DB_TXN *, const char *, const char *, u_int32_t)); +int __dbcl_env_dbrename __P((DB_ENV *, DB_TXN *, const char *, const char *, const char *, u_int32_t)); +int __dbcl_env_get_encrypt_flags __P((DB_ENV *, u_int32_t *)); +int __dbcl_env_encrypt __P((DB_ENV *, const char *, u_int32_t)); +int __dbcl_env_set_feedback __P((DB_ENV *, void (*)(DB_ENV *, int, int))); +int __dbcl_env_get_flags __P((DB_ENV *, u_int32_t *)); +int __dbcl_env_flags __P((DB_ENV *, u_int32_t, int)); +int __dbcl_get_lg_bsize __P((DB_ENV *, u_int32_t *)); +int __dbcl_set_lg_bsize __P((DB_ENV *, u_int32_t)); +int __dbcl_get_lg_dir __P((DB_ENV *, const char * *)); +int __dbcl_set_lg_dir __P((DB_ENV *, const char *)); +int __dbcl_get_lg_max __P((DB_ENV *, u_int32_t *)); +int __dbcl_set_lg_max __P((DB_ENV *, u_int32_t)); +int __dbcl_get_lg_regionmax __P((DB_ENV *, u_int32_t *)); +int __dbcl_set_lg_regionmax __P((DB_ENV *, u_int32_t)); +int __dbcl_get_lk_conflicts __P((DB_ENV *, const u_int8_t **, int *)); +int __dbcl_set_lk_conflict __P((DB_ENV *, u_int8_t *, int)); +int __dbcl_get_lk_detect __P((DB_ENV *, u_int32_t *)); +int __dbcl_set_lk_detect __P((DB_ENV *, u_int32_t)); +int __dbcl_set_lk_max __P((DB_ENV *, u_int32_t)); +int __dbcl_get_lk_max_locks __P((DB_ENV *, u_int32_t *)); +int __dbcl_set_lk_max_locks __P((DB_ENV *, u_int32_t)); +int __dbcl_get_lk_max_lockers __P((DB_ENV *, u_int32_t *)); +int __dbcl_set_lk_max_lockers __P((DB_ENV *, u_int32_t)); +int __dbcl_get_lk_max_objects __P((DB_ENV *, u_int32_t *)); +int __dbcl_set_lk_max_objects __P((DB_ENV *, u_int32_t)); +int __dbcl_get_mp_max_openfd __P((DB_ENV *, int *)); +int __dbcl_set_mp_max_openfd __P((DB_ENV *, int)); +int __dbcl_get_mp_max_write __P((DB_ENV *, int *, int *)); +int __dbcl_set_mp_max_write __P((DB_ENV *, int, int)); +int __dbcl_get_mp_mmapsize __P((DB_ENV *, size_t *)); +int __dbcl_set_mp_mmapsize __P((DB_ENV *, size_t)); +int __dbcl_env_get_home __P((DB_ENV *, const char * *)); +int __dbcl_env_get_open_flags __P((DB_ENV *, u_int32_t *)); +int __dbcl_env_open __P((DB_ENV *, const char *, u_int32_t, int)); +int __dbcl_env_paniccall __P((DB_ENV *, void (*)(DB_ENV *, int))); +int __dbcl_env_remove __P((DB_ENV *, const char *, u_int32_t)); +int __dbcl_get_shm_key __P((DB_ENV *, long *)); +int __dbcl_set_shm_key __P((DB_ENV *, long)); +int __dbcl_get_tas_spins __P((DB_ENV *, u_int32_t *)); +int __dbcl_set_tas_spins __P((DB_ENV *, u_int32_t)); +int __dbcl_get_timeout __P((DB_ENV *, u_int32_t *, u_int32_t)); +int __dbcl_set_timeout __P((DB_ENV *, u_int32_t, u_int32_t)); +int __dbcl_get_tmp_dir __P((DB_ENV *, const char * *)); +int __dbcl_set_tmp_dir __P((DB_ENV *, const char *)); +int __dbcl_get_tx_max __P((DB_ENV *, u_int32_t *)); +int __dbcl_set_tx_max __P((DB_ENV *, u_int32_t)); +int __dbcl_get_tx_timestamp __P((DB_ENV *, time_t *)); +int __dbcl_set_tx_timestamp __P((DB_ENV *, time_t *)); +int __dbcl_get_verbose __P((DB_ENV *, u_int32_t, int *)); +int __dbcl_set_verbose __P((DB_ENV *, u_int32_t, int)); +int __dbcl_txn_abort __P((DB_TXN *)); +int __dbcl_txn_begin __P((DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t)); +int __dbcl_txn_checkpoint __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t)); +int __dbcl_txn_commit __P((DB_TXN *, u_int32_t)); +int __dbcl_txn_discard __P((DB_TXN *, u_int32_t)); +int __dbcl_txn_prepare __P((DB_TXN *, u_int8_t *)); +int __dbcl_txn_recover __P((DB_ENV *, DB_PREPLIST *, long, long *, u_int32_t)); +int __dbcl_txn_stat __P((DB_ENV *, DB_TXN_STAT **, u_int32_t)); +int __dbcl_txn_timeout __P((DB_TXN *, u_int32_t, u_int32_t)); +int __dbcl_rep_elect __P((DB_ENV *, int, int, int, u_int32_t, int *, u_int32_t)); +int __dbcl_rep_flush __P((DB_ENV *)); +int __dbcl_rep_process_message __P((DB_ENV *, DBT *, DBT *, int *, DB_LSN *)); +int __dbcl_rep_get_limit __P((DB_ENV *, u_int32_t *, u_int32_t *)); +int __dbcl_rep_set_limit __P((DB_ENV *, u_int32_t, u_int32_t)); +int __dbcl_rep_set_request __P((DB_ENV *, u_int32_t, u_int32_t)); +int __dbcl_rep_set_rep_transport __P((DB_ENV *, int, int (*)(DB_ENV *, const DBT *, const DBT *, const DB_LSN *, int, u_int32_t))); +int __dbcl_rep_start __P((DB_ENV *, DBT *, u_int32_t)); +int __dbcl_rep_stat __P((DB_ENV *, DB_REP_STAT **, u_int32_t)); +int __dbcl_db_alloc __P((DB *, void *(*)(size_t), void *(*)(void *, size_t), void (*)(void *))); +int __dbcl_db_associate __P((DB *, DB_TXN *, DB *, int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); +int __dbcl_db_bt_compare __P((DB *, int (*)(DB *, const DBT *, const DBT *))); +int __dbcl_db_bt_maxkey __P((DB *, u_int32_t)); +int __dbcl_db_get_bt_minkey __P((DB *, u_int32_t *)); +int __dbcl_db_bt_minkey __P((DB *, u_int32_t)); +int __dbcl_db_bt_prefix __P((DB *, size_t(*)(DB *, const DBT *, const DBT *))); +int __dbcl_db_set_append_recno __P((DB *, int (*)(DB *, DBT *, db_recno_t))); +int __dbcl_db_get_cachesize __P((DB *, u_int32_t *, u_int32_t *, int *)); +int __dbcl_db_cachesize __P((DB *, u_int32_t, u_int32_t, int)); +int __dbcl_db_close __P((DB *, u_int32_t)); +int __dbcl_db_create __P((DB *, DB_ENV *, u_int32_t)); +int __dbcl_db_del __P((DB *, DB_TXN *, DBT *, u_int32_t)); +int __dbcl_db_dup_compare __P((DB *, int (*)(DB *, const DBT *, const DBT *))); +int __dbcl_db_get_encrypt_flags __P((DB *, u_int32_t *)); +int __dbcl_db_encrypt __P((DB *, const char *, u_int32_t)); +int __dbcl_db_get_extentsize __P((DB *, u_int32_t *)); +int __dbcl_db_extentsize __P((DB *, u_int32_t)); +int __dbcl_db_fd __P((DB *, int *)); +int __dbcl_db_feedback __P((DB *, void (*)(DB *, int, int))); +int __dbcl_db_get_flags __P((DB *, u_int32_t *)); +int __dbcl_db_flags __P((DB *, u_int32_t)); +int __dbcl_db_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); +int __dbcl_db_get_name __P((DB *, const char * *, const char * *)); +int __dbcl_db_get_open_flags __P((DB *, u_int32_t *)); +int __dbcl_db_get_h_ffactor __P((DB *, u_int32_t *)); +int __dbcl_db_h_ffactor __P((DB *, u_int32_t)); +int __dbcl_db_h_hash __P((DB *, u_int32_t(*)(DB *, const void *, u_int32_t))); +int __dbcl_db_get_h_nelem __P((DB *, u_int32_t *)); +int __dbcl_db_h_nelem __P((DB *, u_int32_t)); +int __dbcl_db_key_range __P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t)); +int __dbcl_db_get_lorder __P((DB *, int *)); +int __dbcl_db_lorder __P((DB *, int)); +int __dbcl_db_open __P((DB *, DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int)); +int __dbcl_db_get_pagesize __P((DB *, u_int32_t *)); +int __dbcl_db_pagesize __P((DB *, u_int32_t)); +int __dbcl_db_panic __P((DB *, void (*)(DB_ENV *, int))); +int __dbcl_db_pget __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t)); +int __dbcl_db_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); +int __dbcl_db_get_re_delim __P((DB *, int *)); +int __dbcl_db_re_delim __P((DB *, int)); +int __dbcl_db_get_re_len __P((DB *, u_int32_t *)); +int __dbcl_db_re_len __P((DB *, u_int32_t)); +int __dbcl_db_re_pad __P((DB *, int)); +int __dbcl_db_get_re_pad __P((DB *, int *)); +int __dbcl_db_get_re_source __P((DB *, const char * *)); +int __dbcl_db_re_source __P((DB *, const char *)); +int __dbcl_db_remove __P((DB *, const char *, const char *, u_int32_t)); +int __dbcl_db_rename __P((DB *, const char *, const char *, const char *, u_int32_t)); +int __dbcl_db_stat __P((DB *, DB_TXN *, void *, u_int32_t)); +int __dbcl_db_sync __P((DB *, u_int32_t)); +int __dbcl_db_truncate __P((DB *, DB_TXN *, u_int32_t *, u_int32_t)); +int __dbcl_db_upgrade __P((DB *, const char *, u_int32_t)); +int __dbcl_db_verify __P((DB *, const char *, const char *, FILE *, u_int32_t)); +int __dbcl_db_cursor __P((DB *, DB_TXN *, DBC **, u_int32_t)); +int __dbcl_db_join __P((DB *, DBC **, DBC **, u_int32_t)); +int __dbcl_dbc_close __P((DBC *)); +int __dbcl_dbc_count __P((DBC *, db_recno_t *, u_int32_t)); +int __dbcl_dbc_del __P((DBC *, u_int32_t)); +int __dbcl_dbc_dup __P((DBC *, DBC **, u_int32_t)); +int __dbcl_dbc_get __P((DBC *, DBT *, DBT *, u_int32_t)); +int __dbcl_dbc_pget __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); +int __dbcl_dbc_put __P((DBC *, DBT *, DBT *, u_int32_t)); +int __dbcl_lock_detect __P((DB_ENV *, u_int32_t, u_int32_t, int *)); +int __dbcl_lock_get __P((DB_ENV *, u_int32_t, u_int32_t, const DBT *, db_lockmode_t, DB_LOCK *)); +int __dbcl_lock_id __P((DB_ENV *, u_int32_t *)); +int __dbcl_lock_id_free __P((DB_ENV *, u_int32_t)); +int __dbcl_lock_put __P((DB_ENV *, DB_LOCK *)); +int __dbcl_lock_stat __P((DB_ENV *, DB_LOCK_STAT **, u_int32_t)); +int __dbcl_lock_vec __P((DB_ENV *, u_int32_t, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **)); +int __dbcl_log_archive __P((DB_ENV *, char ***, u_int32_t)); +int __dbcl_log_cursor __P((DB_ENV *, DB_LOGC **, u_int32_t)); +int __dbcl_log_file __P((DB_ENV *, const DB_LSN *, char *, size_t)); +int __dbcl_log_flush __P((DB_ENV *, const DB_LSN *)); +int __dbcl_log_put __P((DB_ENV *, DB_LSN *, const DBT *, u_int32_t)); +int __dbcl_log_stat __P((DB_ENV *, DB_LOG_STAT **, u_int32_t)); +int __dbcl_memp_register __P((DB_ENV *, int, int (*)(DB_ENV *, db_pgno_t, void *, DBT *), int (*)(DB_ENV *, db_pgno_t, void *, DBT *))); +int __dbcl_memp_stat __P((DB_ENV *, DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t)); +int __dbcl_memp_sync __P((DB_ENV *, DB_LSN *)); +int __dbcl_memp_trickle __P((DB_ENV *, int, int *)); +int __dbcl_memp_fget __P((DB_MPOOLFILE *, u_int32_t *, u_int32_t, void *)); +int __dbcl_memp_fopen __P((DB_MPOOLFILE *, const char *, u_int32_t, int, size_t)); +int __dbcl_memp_fput __P((DB_MPOOLFILE *, void *, u_int32_t)); +int __dbcl_memp_fset __P((DB_MPOOLFILE *, void *, u_int32_t)); +int __dbcl_memp_get_clear_len __P((DB_MPOOLFILE *, u_int32_t *)); +int __dbcl_memp_set_clear_len __P((DB_MPOOLFILE *, u_int32_t)); +int __dbcl_memp_get_fileid __P((DB_MPOOLFILE *, u_int8_t *)); +int __dbcl_memp_set_fileid __P((DB_MPOOLFILE *, u_int8_t *)); +int __dbcl_memp_get_flags __P((DB_MPOOLFILE *, u_int32_t *)); +int __dbcl_memp_set_flags __P((DB_MPOOLFILE *, u_int32_t, int)); +int __dbcl_memp_get_ftype __P((DB_MPOOLFILE *, int *)); +int __dbcl_memp_set_ftype __P((DB_MPOOLFILE *, int)); +int __dbcl_memp_get_lsn_offset __P((DB_MPOOLFILE *, int32_t *)); +int __dbcl_memp_set_lsn_offset __P((DB_MPOOLFILE *, int32_t)); +int __dbcl_memp_get_maxsize __P((DB_MPOOLFILE *, u_int32_t *, u_int32_t *)); +int __dbcl_memp_set_maxsize __P((DB_MPOOLFILE *, u_int32_t, u_int32_t)); +int __dbcl_memp_get_pgcookie __P((DB_MPOOLFILE *, DBT *)); +int __dbcl_memp_set_pgcookie __P((DB_MPOOLFILE *, DBT *)); +int __dbcl_memp_get_priority __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY *)); +int __dbcl_memp_set_priority __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY)); +int __dbcl_memp_fsync __P((DB_MPOOLFILE *)); +int __dbcl_env_create_ret __P((DB_ENV *, long, __env_create_reply *)); +int __dbcl_env_open_ret __P((DB_ENV *, const char *, u_int32_t, int, __env_open_reply *)); +int __dbcl_env_remove_ret __P((DB_ENV *, const char *, u_int32_t, __env_remove_reply *)); +int __dbcl_txn_abort_ret __P((DB_TXN *, __txn_abort_reply *)); +int __dbcl_txn_begin_ret __P((DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t, __txn_begin_reply *)); +int __dbcl_txn_commit_ret __P((DB_TXN *, u_int32_t, __txn_commit_reply *)); +int __dbcl_txn_discard_ret __P((DB_TXN *, u_int32_t, __txn_discard_reply *)); +int __dbcl_txn_recover_ret __P((DB_ENV *, DB_PREPLIST *, long, long *, u_int32_t, __txn_recover_reply *)); +int __dbcl_db_close_ret __P((DB *, u_int32_t, __db_close_reply *)); +int __dbcl_db_create_ret __P((DB *, DB_ENV *, u_int32_t, __db_create_reply *)); +int __dbcl_db_get_ret __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t, __db_get_reply *)); +int __dbcl_db_key_range_ret __P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t, __db_key_range_reply *)); +int __dbcl_db_open_ret __P((DB *, DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int, __db_open_reply *)); +int __dbcl_db_pget_ret __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t, __db_pget_reply *)); +int __dbcl_db_put_ret __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t, __db_put_reply *)); +int __dbcl_db_remove_ret __P((DB *, const char *, const char *, u_int32_t, __db_remove_reply *)); +int __dbcl_db_rename_ret __P((DB *, const char *, const char *, const char *, u_int32_t, __db_rename_reply *)); +int __dbcl_db_stat_ret __P((DB *, DB_TXN *, void *, u_int32_t, __db_stat_reply *)); +int __dbcl_db_truncate_ret __P((DB *, DB_TXN *, u_int32_t *, u_int32_t, __db_truncate_reply *)); +int __dbcl_db_cursor_ret __P((DB *, DB_TXN *, DBC **, u_int32_t, __db_cursor_reply *)); +int __dbcl_db_join_ret __P((DB *, DBC **, DBC **, u_int32_t, __db_join_reply *)); +int __dbcl_dbc_close_ret __P((DBC *, __dbc_close_reply *)); +int __dbcl_dbc_count_ret __P((DBC *, db_recno_t *, u_int32_t, __dbc_count_reply *)); +int __dbcl_dbc_dup_ret __P((DBC *, DBC **, u_int32_t, __dbc_dup_reply *)); +int __dbcl_dbc_get_ret __P((DBC *, DBT *, DBT *, u_int32_t, __dbc_get_reply *)); +int __dbcl_dbc_pget_ret __P((DBC *, DBT *, DBT *, DBT *, u_int32_t, __dbc_pget_reply *)); +int __dbcl_dbc_put_ret __P((DBC *, DBT *, DBT *, u_int32_t, __dbc_put_reply *)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_rpc_client_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/rpc_server_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/rpc_server_ext.h new file mode 100644 index 00000000..6d8cbc71 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/rpc_server_ext.h @@ -0,0 +1,94 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _rpc_server_ext_h_ +#define _rpc_server_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +void __env_get_cachesize_proc __P((long, __env_get_cachesize_reply *)); +void __env_cachesize_proc __P((long, u_int32_t, u_int32_t, u_int32_t, __env_cachesize_reply *)); +void __env_close_proc __P((long, u_int32_t, __env_close_reply *)); +void __env_create_proc __P((u_int32_t, __env_create_reply *)); +void __env_dbremove_proc __P((long, long, char *, char *, u_int32_t, __env_dbremove_reply *)); +void __env_dbrename_proc __P((long, long, char *, char *, char *, u_int32_t, __env_dbrename_reply *)); +void __env_get_encrypt_flags_proc __P((long, __env_get_encrypt_flags_reply *)); +void __env_encrypt_proc __P((long, char *, u_int32_t, __env_encrypt_reply *)); +void __env_get_flags_proc __P((long, __env_get_flags_reply *)); +void __env_flags_proc __P((long, u_int32_t, u_int32_t, __env_flags_reply *)); +void __env_get_home_proc __P((long, __env_get_home_reply *)); +void __env_get_open_flags_proc __P((long, __env_get_open_flags_reply *)); +void __env_open_proc __P((long, char *, u_int32_t, u_int32_t, __env_open_reply *)); +void __env_remove_proc __P((long, char *, u_int32_t, __env_remove_reply *)); +void __txn_abort_proc __P((long, __txn_abort_reply *)); +void __txn_begin_proc __P((long, long, u_int32_t, __txn_begin_reply *)); +void __txn_commit_proc __P((long, u_int32_t, __txn_commit_reply *)); +void __txn_discard_proc __P((long, u_int32_t, __txn_discard_reply *)); +void __txn_prepare_proc __P((long, u_int8_t *, __txn_prepare_reply *)); +void __txn_recover_proc __P((long, u_int32_t, u_int32_t, __txn_recover_reply *, int *)); +void __db_bt_maxkey_proc __P((long, u_int32_t, __db_bt_maxkey_reply *)); +void __db_associate_proc __P((long, long, long, u_int32_t, __db_associate_reply *)); +void __db_get_bt_minkey_proc __P((long, __db_get_bt_minkey_reply *)); +void __db_bt_minkey_proc __P((long, u_int32_t, __db_bt_minkey_reply *)); +void __db_close_proc __P((long, u_int32_t, __db_close_reply *)); +void __db_create_proc __P((long, u_int32_t, __db_create_reply *)); +void __db_del_proc __P((long, long, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, __db_del_reply *)); +void __db_get_encrypt_flags_proc __P((long, __db_get_encrypt_flags_reply *)); +void __db_encrypt_proc __P((long, char *, u_int32_t, __db_encrypt_reply *)); +void __db_get_extentsize_proc __P((long, __db_get_extentsize_reply *)); +void __db_extentsize_proc __P((long, u_int32_t, __db_extentsize_reply *)); +void __db_get_flags_proc __P((long, __db_get_flags_reply *)); +void __db_flags_proc __P((long, u_int32_t, __db_flags_reply *)); +void __db_get_proc __P((long, long, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, __db_get_reply *, int *)); +void __db_get_h_ffactor_proc __P((long, __db_get_h_ffactor_reply *)); +void __db_h_ffactor_proc __P((long, u_int32_t, __db_h_ffactor_reply *)); +void __db_get_h_nelem_proc __P((long, __db_get_h_nelem_reply *)); +void __db_h_nelem_proc __P((long, u_int32_t, __db_h_nelem_reply *)); +void __db_key_range_proc __P((long, long, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, __db_key_range_reply *)); +void __db_get_lorder_proc __P((long, __db_get_lorder_reply *)); +void __db_lorder_proc __P((long, u_int32_t, __db_lorder_reply *)); +void __db_get_name_proc __P((long, __db_get_name_reply *)); +void __db_get_open_flags_proc __P((long, __db_get_open_flags_reply *)); +void __db_open_proc __P((long, long, char *, char *, u_int32_t, u_int32_t, u_int32_t, __db_open_reply *)); +void __db_get_pagesize_proc __P((long, __db_get_pagesize_reply *)); +void __db_pagesize_proc __P((long, u_int32_t, __db_pagesize_reply *)); +void __db_pget_proc __P((long, long, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, __db_pget_reply *, int *)); +void __db_put_proc __P((long, long, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, __db_put_reply *, int *)); +void __db_get_re_delim_proc __P((long, __db_get_re_delim_reply *)); +void __db_re_delim_proc __P((long, u_int32_t, __db_re_delim_reply *)); +void __db_get_re_len_proc __P((long, __db_get_re_len_reply *)); +void __db_re_len_proc __P((long, u_int32_t, __db_re_len_reply *)); +void __db_get_re_pad_proc __P((long, __db_get_re_pad_reply *)); +void __db_re_pad_proc __P((long, u_int32_t, __db_re_pad_reply *)); +void __db_remove_proc __P((long, char *, char *, u_int32_t, __db_remove_reply *)); +void __db_rename_proc __P((long, char *, char *, char *, u_int32_t, __db_rename_reply *)); +void __db_stat_proc __P((long, long, u_int32_t, __db_stat_reply *, int *)); +void __db_sync_proc __P((long, u_int32_t, __db_sync_reply *)); +void __db_truncate_proc __P((long, long, u_int32_t, __db_truncate_reply *)); +void __db_cursor_proc __P((long, long, u_int32_t, __db_cursor_reply *)); +void __db_join_proc __P((long, u_int32_t *, u_int32_t, u_int32_t, __db_join_reply *)); +void __dbc_close_proc __P((long, __dbc_close_reply *)); +void __dbc_count_proc __P((long, u_int32_t, __dbc_count_reply *)); +void __dbc_del_proc __P((long, u_int32_t, __dbc_del_reply *)); +void __dbc_dup_proc __P((long, u_int32_t, __dbc_dup_reply *)); +void __dbc_get_proc __P((long, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, __dbc_get_reply *, int *)); +void __dbc_pget_proc __P((long, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, __dbc_pget_reply *, int *)); +void __dbc_put_proc __P((long, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, __dbc_put_reply *, int *)); +void __dbsrv_settimeout __P((ct_entry *, u_int32_t)); +void __dbsrv_timeout __P((int)); +void __dbclear_ctp __P((ct_entry *)); +void __dbdel_ctp __P((ct_entry *)); +ct_entry *new_ct_ent __P((int *)); +ct_entry *get_tableent __P((long)); +ct_entry *__dbsrv_sharedb __P((ct_entry *, const char *, const char *, DBTYPE, u_int32_t)); +ct_entry *__dbsrv_shareenv __P((ct_entry *, home_entry *, u_int32_t)); +void __dbsrv_active __P((ct_entry *)); +int __db_close_int __P((long, u_int32_t)); +int __dbc_close_int __P((ct_entry *)); +int __dbenv_close_int __P((long, u_int32_t, int)); +home_entry *get_fullhome __P((char *)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_rpc_server_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/sequence_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/sequence_ext.h new file mode 100644 index 00000000..a2c114cf --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/sequence_ext.h @@ -0,0 +1,17 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _sequence_ext_h_ +#define _sequence_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __seq_stat __P((DB_SEQUENCE *, DB_SEQUENCE_STAT **, u_int32_t)); +int __seq_stat_print __P((DB_SEQUENCE *, u_int32_t)); +const FN * __db_get_seq_flags_fn __P((void)); +const FN * __db_get_seq_flags_fn __P((void)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_sequence_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/tcl_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/tcl_ext.h new file mode 100644 index 00000000..1ae2e285 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/tcl_ext.h @@ -0,0 +1,115 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _tcl_ext_h_ +#define _tcl_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int bdb_HCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*)); +#if DB_DBM_HSEARCH != 0 +int bdb_NdbmOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBM **)); +#endif +#if DB_DBM_HSEARCH != 0 +int bdb_DbmCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*, int, DBM *)); +#endif +int ndbm_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*)); +void _DbInfoDelete __P((Tcl_Interp *, DBTCL_INFO *)); +int db_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*)); +int tcl_CompactStat __P((Tcl_Interp *, DBTCL_INFO *)); +int tcl_rep_send __P((DB_ENV *, const DBT *, const DBT *, const DB_LSN *, int, u_int32_t)); +int dbc_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*)); +int env_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*)); +int tcl_EnvRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *)); +int tcl_EnvIdReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_EnvLsnReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_EnvVerbose __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *, Tcl_Obj *)); +int tcl_EnvAttr __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_EventNotify __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *, DBTCL_INFO *)); +int tcl_EnvSetFlags __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *, Tcl_Obj *)); +int tcl_EnvTest __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_EnvGetEncryptFlags __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +void tcl_EnvSetErrfile __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *, char *)); +int tcl_EnvSetErrpfx __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *, char *)); +DBTCL_INFO *_NewInfo __P((Tcl_Interp *, void *, char *, enum INFOTYPE)); +void *_NameToPtr __P((CONST char *)); +DBTCL_INFO *_PtrToInfo __P((CONST void *)); +DBTCL_INFO *_NameToInfo __P((CONST char *)); +void _SetInfoData __P((DBTCL_INFO *, void *)); +void _DeleteInfo __P((DBTCL_INFO *)); +int _SetListElem __P((Tcl_Interp *, Tcl_Obj *, void *, u_int32_t, void *, u_int32_t)); +int _SetListElemInt __P((Tcl_Interp *, Tcl_Obj *, void *, long)); +int _SetListElemWideInt __P((Tcl_Interp *, Tcl_Obj *, void *, int64_t)); +int _SetListRecnoElem __P((Tcl_Interp *, Tcl_Obj *, db_recno_t, u_char *, u_int32_t)); +int _Set3DBTList __P((Tcl_Interp *, Tcl_Obj *, DBT *, int, DBT *, int, DBT *)); +int _SetMultiList __P((Tcl_Interp *, Tcl_Obj *, DBT *, DBT*, DBTYPE, u_int32_t)); +int _GetGlobPrefix __P((char *, char **)); +int _ReturnSetup __P((Tcl_Interp *, int, int, char *)); +int _ErrorSetup __P((Tcl_Interp *, int, char *)); +void _ErrorFunc __P((const DB_ENV *, CONST char *, const char *)); +void _EventFunc __P((DB_ENV *, u_int32_t, void *)); +int _GetLsn __P((Tcl_Interp *, Tcl_Obj *, DB_LSN *)); +int _GetUInt32 __P((Tcl_Interp *, Tcl_Obj *, u_int32_t *)); +Tcl_Obj *_GetFlagsList __P((Tcl_Interp *, u_int32_t, const FN *)); +void _debug_check __P((void)); +int _CopyObjBytes __P((Tcl_Interp *, Tcl_Obj *obj, void *, u_int32_t *, int *)); +int tcl_LockDetect __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_LockGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_LockStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_LockTimeout __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_LockVec __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_LogArchive __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_LogCompare __P((Tcl_Interp *, int, Tcl_Obj * CONST*)); +int tcl_LogFile __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_LogFlush __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_LogGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_LogPut __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_LogStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int logc_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*)); +int tcl_LogConfig __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *)); +int tcl_LogGetConfig __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *)); +void _MpInfoDelete __P((Tcl_Interp *, DBTCL_INFO *)); +int tcl_MpSync __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_MpTrickle __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_Mp __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *)); +int tcl_MpStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_Mutex __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_MutFree __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_MutGet __P((Tcl_Interp *, DB_ENV *, int)); +int tcl_MutLock __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_MutSet __P((Tcl_Interp *, Tcl_Obj *, DB_ENV *, int)); +int tcl_MutStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_MutUnlock __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_RepConfig __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *)); +int tcl_RepGetTwo __P((Tcl_Interp *, DB_ENV *, int)); +int tcl_RepGetConfig __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *)); +int tcl_RepGetTimeout __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *)); +int tcl_RepElect __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *)); +int tcl_RepFlush __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *)); +int tcl_RepSync __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *)); +int tcl_RepLease __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *)); +int tcl_RepInmemFiles __P((Tcl_Interp *, DB_ENV *)); +int tcl_RepLimit __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *)); +int tcl_RepRequest __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *)); +int tcl_RepNoarchiveTimeout __P((Tcl_Interp *, DB_ENV *)); +int tcl_RepTransport __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *, DBTCL_INFO *)); +int tcl_RepStart __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *)); +int tcl_RepProcessMessage __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *)); +int tcl_RepStat __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *)); +int tcl_RepMgr __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *)); +int tcl_RepMgrSiteList __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *)); +int tcl_RepMgrStat __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *)); +int seq_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*)); +void _TxnInfoDelete __P((Tcl_Interp *, DBTCL_INFO *)); +int tcl_TxnCheckpoint __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_Txn __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *)); +int tcl_CDSGroup __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *)); +int tcl_TxnStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_TxnTimeout __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); +int tcl_TxnRecover __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *)); +int bdb_RandCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_tcl_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/txn_auto.h b/src/libs/resiprocate/contrib/db/dbinc_auto/txn_auto.h new file mode 100644 index 00000000..3feefbcf --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/txn_auto.h @@ -0,0 +1,92 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#ifndef __txn_AUTO_H +#define __txn_AUTO_H +#define DB___txn_regop_42 10 +typedef struct ___txn_regop_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t opcode; + int32_t timestamp; + DBT locks; +} __txn_regop_42_args; + +#define DB___txn_regop 10 +typedef struct ___txn_regop_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t opcode; + int32_t timestamp; + u_int32_t envid; + DBT locks; +} __txn_regop_args; + +#define DB___txn_ckp_42 11 +typedef struct ___txn_ckp_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DB_LSN ckp_lsn; + DB_LSN last_ckp; + int32_t timestamp; + u_int32_t rep_gen; +} __txn_ckp_42_args; + +#define DB___txn_ckp 11 +typedef struct ___txn_ckp_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + DB_LSN ckp_lsn; + DB_LSN last_ckp; + int32_t timestamp; + u_int32_t envid; + u_int32_t spare; +} __txn_ckp_args; + +#define DB___txn_child 12 +typedef struct ___txn_child_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t child; + DB_LSN c_lsn; +} __txn_child_args; + +#define DB___txn_xa_regop_42 13 +typedef struct ___txn_xa_regop_42_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t opcode; + DBT xid; + int32_t formatID; + u_int32_t gtrid; + u_int32_t bqual; + DB_LSN begin_lsn; + DBT locks; +} __txn_xa_regop_42_args; + +#define DB___txn_prepare 13 +typedef struct ___txn_prepare_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t opcode; + DBT gid; + DB_LSN begin_lsn; + DBT locks; +} __txn_prepare_args; + +#define DB___txn_recycle 14 +typedef struct ___txn_recycle_args { + u_int32_t type; + DB_TXN *txnp; + DB_LSN prev_lsn; + u_int32_t min; + u_int32_t max; +} __txn_recycle_args; + +#endif diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/txn_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/txn_ext.h new file mode 100644 index 00000000..4f9acb72 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/txn_ext.h @@ -0,0 +1,96 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _txn_ext_h_ +#define _txn_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __txn_begin_pp __P((DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t)); +int __txn_begin __P((ENV *, DB_THREAD_INFO *, DB_TXN *, DB_TXN **, u_int32_t)); +int __txn_recycle_id __P((ENV *)); +int __txn_compensate_begin __P((ENV *, DB_TXN **)); +int __txn_continue __P((ENV *, DB_TXN *, TXN_DETAIL *)); +int __txn_commit __P((DB_TXN *, u_int32_t)); +int __txn_abort __P((DB_TXN *)); +int __txn_discard_int __P((DB_TXN *, u_int32_t flags)); +int __txn_prepare __P((DB_TXN *, u_int8_t *)); +u_int32_t __txn_id __P((DB_TXN *)); +int __txn_get_name __P((DB_TXN *, const char **)); +int __txn_set_name __P((DB_TXN *, const char *)); +int __txn_set_timeout __P((DB_TXN *, db_timeout_t, u_int32_t)); +int __txn_activekids __P((ENV *, u_int32_t, DB_TXN *)); +int __txn_force_abort __P((ENV *, u_int8_t *)); +int __txn_preclose __P((ENV *)); +int __txn_reset __P((ENV *)); +int __txn_regop_42_read __P((ENV *, void *, __txn_regop_42_args **)); +int __txn_regop_read __P((ENV *, void *, __txn_regop_args **)); +int __txn_regop_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, int32_t, u_int32_t, const DBT *)); +int __txn_ckp_42_read __P((ENV *, void *, __txn_ckp_42_args **)); +int __txn_ckp_read __P((ENV *, void *, __txn_ckp_args **)); +int __txn_ckp_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, DB_LSN *, DB_LSN *, int32_t, u_int32_t, u_int32_t)); +int __txn_child_read __P((ENV *, void *, __txn_child_args **)); +int __txn_child_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, DB_LSN *)); +int __txn_xa_regop_42_read __P((ENV *, void *, __txn_xa_regop_42_args **)); +int __txn_prepare_read __P((ENV *, void *, __txn_prepare_args **)); +int __txn_prepare_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, const DBT *, DB_LSN *, const DBT *)); +int __txn_recycle_read __P((ENV *, void *, __txn_recycle_args **)); +int __txn_recycle_log __P((ENV *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, u_int32_t)); +int __txn_init_recover __P((ENV *, DB_DISTAB *)); +int __txn_regop_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_regop_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_ckp_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_ckp_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_child_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_xa_regop_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_prepare_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_recycle_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_init_print __P((ENV *, DB_DISTAB *)); +int __txn_checkpoint_pp __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t)); +int __txn_checkpoint __P((ENV *, u_int32_t, u_int32_t, u_int32_t)); +int __txn_getactive __P((ENV *, DB_LSN *)); +int __txn_getckp __P((ENV *, DB_LSN *)); +int __txn_updateckp __P((ENV *, DB_LSN *)); +int __txn_failchk __P((ENV *)); +int __txn_env_create __P((DB_ENV *)); +void __txn_env_destroy __P((DB_ENV *)); +int __txn_get_tx_max __P((DB_ENV *, u_int32_t *)); +int __txn_set_tx_max __P((DB_ENV *, u_int32_t)); +int __txn_get_tx_timestamp __P((DB_ENV *, time_t *)); +int __txn_set_tx_timestamp __P((DB_ENV *, time_t *)); +int __txn_regop_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_prepare_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_ckp_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_child_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_restore_txn __P((ENV *, DB_LSN *, __txn_prepare_args *)); +int __txn_recycle_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_regop_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_ckp_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); +int __txn_map_gid __P((ENV *, u_int8_t *, TXN_DETAIL **, roff_t *)); +int __txn_recover_pp __P((DB_ENV *, DB_PREPLIST *, u_int32_t, u_int32_t *, u_int32_t)); +int __txn_recover __P((ENV *, DB_PREPLIST *, u_int32_t, u_int32_t *, u_int32_t)); +int __txn_openfiles __P((ENV *, DB_THREAD_INFO *, DB_LSN *, int)); +int __txn_open __P((ENV *, int)); +int __txn_findlastckp __P((ENV *, DB_LSN *, DB_LSN *)); +int __txn_env_refresh __P((ENV *)); +u_int32_t __txn_region_mutex_count __P((ENV *)); +int __txn_id_set __P((ENV *, u_int32_t, u_int32_t)); +int __txn_oldest_reader __P((ENV *, DB_LSN *)); +int __txn_add_buffer __P((ENV *, TXN_DETAIL *)); +int __txn_remove_buffer __P((ENV *, TXN_DETAIL *, db_mutex_t)); +int __txn_stat_pp __P((DB_ENV *, DB_TXN_STAT **, u_int32_t)); +int __txn_stat_print_pp __P((DB_ENV *, u_int32_t)); +int __txn_stat_print __P((ENV *, u_int32_t)); +int __txn_closeevent __P((ENV *, DB_TXN *, DB *)); +int __txn_remevent __P((ENV *, DB_TXN *, const char *, u_int8_t *, int)); +void __txn_remrem __P((ENV *, DB_TXN *, const char *)); +int __txn_lockevent __P((ENV *, DB_TXN *, DB *, DB_LOCK *, DB_LOCKER *)); +void __txn_remlock __P((ENV *, DB_TXN *, DB_LOCK *, DB_LOCKER *)); +int __txn_doevents __P((ENV *, DB_TXN *, int, int)); +int __txn_record_fname __P((ENV *, DB_TXN *, FNAME *)); +int __txn_dref_fname __P((ENV *, DB_TXN *)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_txn_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbinc_auto/xa_ext.h b/src/libs/resiprocate/contrib/db/dbinc_auto/xa_ext.h new file mode 100644 index 00000000..3247b5bb --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbinc_auto/xa_ext.h @@ -0,0 +1,21 @@ +/* DO NOT EDIT: automatically built by dist/s_include. */ +#ifndef _xa_ext_h_ +#define _xa_ext_h_ + +#if defined(__cplusplus) +extern "C" { +#endif + +int __xa_get_txn __P((DB_ENV *, DB_TXN **, int)); +int __db_xa_create __P((DB *)); +int __db_rmid_to_env __P((int rmid, DB_ENV **envp)); +int __db_xid_to_txn __P((DB_ENV *, XID *, roff_t *)); +int __db_map_rmid __P((int, DB_ENV *)); +int __db_unmap_rmid __P((int)); +int __db_map_xid __P((DB_ENV *, XID *, size_t)); +void __db_unmap_xid __P((DB_ENV *, XID *, size_t)); + +#if defined(__cplusplus) +} +#endif +#endif /* !_xa_ext_h_ */ diff --git a/src/libs/resiprocate/contrib/db/dbm/dbm.c b/src/libs/resiprocate/contrib/db/dbm/dbm.c new file mode 100644 index 00000000..76a90e03 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbm/dbm.c @@ -0,0 +1,499 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993 + * Margo Seltzer. All rights reserved. + */ +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#define DB_DBM_HSEARCH 1 +#include "db_config.h" + +#include "db_int.h" + +/* + * + * This package provides dbm and ndbm compatible interfaces to DB. + * + * EXTERN: #if DB_DBM_HSEARCH != 0 + * + * EXTERN: int __db_ndbm_clearerr __P((DBM *)); + * EXTERN: void __db_ndbm_close __P((DBM *)); + * EXTERN: int __db_ndbm_delete __P((DBM *, datum)); + * EXTERN: int __db_ndbm_dirfno __P((DBM *)); + * EXTERN: int __db_ndbm_error __P((DBM *)); + * EXTERN: datum __db_ndbm_fetch __P((DBM *, datum)); + * EXTERN: datum __db_ndbm_firstkey __P((DBM *)); + * EXTERN: datum __db_ndbm_nextkey __P((DBM *)); + * EXTERN: DBM *__db_ndbm_open __P((const char *, int, int)); + * EXTERN: int __db_ndbm_pagfno __P((DBM *)); + * EXTERN: int __db_ndbm_rdonly __P((DBM *)); + * EXTERN: int __db_ndbm_store __P((DBM *, datum, datum, int)); + * + * EXTERN: int __db_dbm_close __P((void)); + * EXTERN: int __db_dbm_delete __P((datum)); + * EXTERN: datum __db_dbm_fetch __P((datum)); + * EXTERN: datum __db_dbm_firstkey __P((void)); + * EXTERN: int __db_dbm_init __P((char *)); + * EXTERN: datum __db_dbm_nextkey __P((datum)); + * EXTERN: int __db_dbm_store __P((datum, datum)); + * + * EXTERN: #endif + */ + +/* + * The DBM routines, which call the NDBM routines. + */ +static DBM *__cur_db; + +static void __db_no_open __P((void)); + +int +__db_dbm_init(file) + char *file; +{ + if (__cur_db != NULL) + dbm_close(__cur_db); + if ((__cur_db = dbm_open(file, O_CREAT | O_RDWR, DB_MODE_600)) != NULL) + return (0); + if ((__cur_db = dbm_open(file, O_RDONLY, 0)) != NULL) + return (0); + return (-1); +} + +int +__db_dbm_close() +{ + if (__cur_db != NULL) { + dbm_close(__cur_db); + __cur_db = NULL; + } + return (0); +} + +datum +__db_dbm_fetch(key) + datum key; +{ + datum item; + + if (__cur_db == NULL) { + __db_no_open(); + item.dptr = NULL; + item.dsize = 0; + return (item); + } + return (dbm_fetch(__cur_db, key)); +} + +datum +__db_dbm_firstkey() +{ + datum item; + + if (__cur_db == NULL) { + __db_no_open(); + item.dptr = NULL; + item.dsize = 0; + return (item); + } + return (dbm_firstkey(__cur_db)); +} + +datum +__db_dbm_nextkey(key) + datum key; +{ + datum item; + + COMPQUIET(key.dsize, 0); + + if (__cur_db == NULL) { + __db_no_open(); + item.dptr = NULL; + item.dsize = 0; + return (item); + } + return (dbm_nextkey(__cur_db)); +} + +int +__db_dbm_delete(key) + datum key; +{ + if (__cur_db == NULL) { + __db_no_open(); + return (-1); + } + return (dbm_delete(__cur_db, key)); +} + +int +__db_dbm_store(key, dat) + datum key, dat; +{ + if (__cur_db == NULL) { + __db_no_open(); + return (-1); + } + return (dbm_store(__cur_db, key, dat, DBM_REPLACE)); +} + +static void +__db_no_open() +{ + (void)fprintf(stderr, "dbm: no open database.\n"); +} + +/* + * This package provides dbm and ndbm compatible interfaces to DB. + * + * The NDBM routines, which call the DB routines. + */ +/* + * Returns: + * *DBM on success + * NULL on failure + */ +DBM * +__db_ndbm_open(file, oflags, mode) + const char *file; + int oflags, mode; +{ + DB *dbp; + DBC *dbc; + int ret; + char path[DB_MAXPATHLEN]; + + /* + * !!! + * Don't use sprintf(3)/snprintf(3) -- the former is dangerous, and + * the latter isn't standard, and we're manipulating strings handed + * us by the application. + */ + if (strlen(file) + strlen(DBM_SUFFIX) + 1 > sizeof(path)) { + __os_set_errno(ENAMETOOLONG); + return (NULL); + } + (void)strcpy(path, file); + (void)strcat(path, DBM_SUFFIX); + if ((ret = db_create(&dbp, NULL, 0)) != 0) { + __os_set_errno(ret); + return (NULL); + } + + /* + * !!! + * The historic ndbm library corrected for opening O_WRONLY. + */ + if (oflags & O_WRONLY) { + oflags &= ~O_WRONLY; + oflags |= O_RDWR; + } + + if ((ret = dbp->set_pagesize(dbp, 4096)) != 0 || + (ret = dbp->set_h_ffactor(dbp, 40)) != 0 || + (ret = dbp->set_h_nelem(dbp, 1)) != 0 || + (ret = dbp->open(dbp, NULL, + path, NULL, DB_HASH, __db_openflags(oflags), mode)) != 0) { + __os_set_errno(ret); + return (NULL); + } + + if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0) { + (void)dbp->close(dbp, 0); + __os_set_errno(ret); + return (NULL); + } + + return ((DBM *)dbc); +} + +/* + * Returns: + * Nothing. + */ +void +__db_ndbm_close(dbm) + DBM *dbm; +{ + DBC *dbc; + + dbc = (DBC *)dbm; + + (void)dbc->dbp->close(dbc->dbp, 0); +} + +/* + * Returns: + * DATUM on success + * NULL on failure + */ +datum +__db_ndbm_fetch(dbm, key) + DBM *dbm; + datum key; +{ + DBC *dbc; + DBT _key, _data; + datum data; + int ret; + + dbc = (DBC *)dbm; + + DB_INIT_DBT(_key, key.dptr, key.dsize); + memset(&_data, 0, sizeof(DBT)); + + /* + * Note that we can't simply use the dbc we have to do a get/SET, + * because that cursor is the one used for sequential iteration and + * it has to remain stable in the face of intervening gets and puts. + */ + if ((ret = dbc->dbp->get(dbc->dbp, NULL, &_key, &_data, 0)) == 0) { + data.dptr = _data.data; + data.dsize = (int)_data.size; + } else { + data.dptr = NULL; + data.dsize = 0; + if (ret == DB_NOTFOUND) + __os_set_errno(ENOENT); + else { + __os_set_errno(ret); + F_SET(dbc->dbp, DB_AM_DBM_ERROR); + } + } + return (data); +} + +/* + * Returns: + * DATUM on success + * NULL on failure + */ +datum +__db_ndbm_firstkey(dbm) + DBM *dbm; +{ + DBC *dbc; + DBT _key, _data; + datum key; + int ret; + + dbc = (DBC *)dbm; + + memset(&_key, 0, sizeof(DBT)); + memset(&_data, 0, sizeof(DBT)); + + if ((ret = dbc->get(dbc, &_key, &_data, DB_FIRST)) == 0) { + key.dptr = _key.data; + key.dsize = (int)_key.size; + } else { + key.dptr = NULL; + key.dsize = 0; + if (ret == DB_NOTFOUND) + __os_set_errno(ENOENT); + else { + __os_set_errno(ret); + F_SET(dbc->dbp, DB_AM_DBM_ERROR); + } + } + return (key); +} + +/* + * Returns: + * DATUM on success + * NULL on failure + */ +datum +__db_ndbm_nextkey(dbm) + DBM *dbm; +{ + DBC *dbc; + DBT _key, _data; + datum key; + int ret; + + dbc = (DBC *)dbm; + + memset(&_key, 0, sizeof(DBT)); + memset(&_data, 0, sizeof(DBT)); + + if ((ret = dbc->get(dbc, &_key, &_data, DB_NEXT)) == 0) { + key.dptr = _key.data; + key.dsize = (int)_key.size; + } else { + key.dptr = NULL; + key.dsize = 0; + if (ret == DB_NOTFOUND) + __os_set_errno(ENOENT); + else { + __os_set_errno(ret); + F_SET(dbc->dbp, DB_AM_DBM_ERROR); + } + } + return (key); +} + +/* + * Returns: + * 0 on success + * <0 failure + */ +int +__db_ndbm_delete(dbm, key) + DBM *dbm; + datum key; +{ + DBC *dbc; + DBT _key; + int ret; + + dbc = (DBC *)dbm; + + DB_INIT_DBT(_key, key.dptr, key.dsize); + + if ((ret = dbc->dbp->del(dbc->dbp, NULL, &_key, 0)) == 0) + return (0); + + if (ret == DB_NOTFOUND) + __os_set_errno(ENOENT); + else { + __os_set_errno(ret); + F_SET(dbc->dbp, DB_AM_DBM_ERROR); + } + return (-1); +} + +/* + * Returns: + * 0 on success + * <0 failure + * 1 if DBM_INSERT and entry exists + */ +int +__db_ndbm_store(dbm, key, data, flags) + DBM *dbm; + datum key, data; + int flags; +{ + DBC *dbc; + DBT _key, _data; + int ret; + + dbc = (DBC *)dbm; + + DB_INIT_DBT(_key, key.dptr, key.dsize); + DB_INIT_DBT(_data, data.dptr, data.dsize); + + if ((ret = dbc->dbp->put(dbc->dbp, NULL, + &_key, &_data, flags == DBM_INSERT ? DB_NOOVERWRITE : 0)) == 0) + return (0); + + if (ret == DB_KEYEXIST) + return (1); + + __os_set_errno(ret); + F_SET(dbc->dbp, DB_AM_DBM_ERROR); + return (-1); +} + +int +__db_ndbm_error(dbm) + DBM *dbm; +{ + DBC *dbc; + + dbc = (DBC *)dbm; + + return (F_ISSET(dbc->dbp, DB_AM_DBM_ERROR)); +} + +int +__db_ndbm_clearerr(dbm) + DBM *dbm; +{ + DBC *dbc; + + dbc = (DBC *)dbm; + + F_CLR(dbc->dbp, DB_AM_DBM_ERROR); + return (0); +} + +/* + * Returns: + * 1 if read-only + * 0 if not read-only + */ +int +__db_ndbm_rdonly(dbm) + DBM *dbm; +{ + DBC *dbc; + + dbc = (DBC *)dbm; + + return (F_ISSET(dbc->dbp, DB_AM_RDONLY) ? 1 : 0); +} + +/* + * XXX + * We only have a single file descriptor that we can return, not two. Return + * the same one for both files. Hopefully, the user is using it for locking + * and picked one to use at random. + */ +int +__db_ndbm_dirfno(dbm) + DBM *dbm; +{ + return (dbm_pagfno(dbm)); +} + +int +__db_ndbm_pagfno(dbm) + DBM *dbm; +{ + DBC *dbc; + int fd; + + dbc = (DBC *)dbm; + + (void)dbc->dbp->fd(dbc->dbp, &fd); + return (fd); +} diff --git a/src/libs/resiprocate/contrib/db/dbreg/dbreg.c b/src/libs/resiprocate/contrib/db/dbreg/dbreg.c new file mode 100644 index 00000000..5876ce42 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbreg/dbreg.c @@ -0,0 +1,976 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/log.h" +#include "dbinc/txn.h" +#include "dbinc/db_am.h" + +static int __dbreg_push_id __P((ENV *, int32_t)); +static int __dbreg_pop_id __P((ENV *, int32_t *)); +static int __dbreg_pluck_id __P((ENV *, int32_t)); + +/* + * The dbreg subsystem, as its name implies, registers database handles so + * that we can associate log messages with them without logging a filename + * or a full, unique DB ID. Instead, we assign each dbp an int32_t which is + * easy and cheap to log, and use this subsystem to map back and forth. + * + * Overview of how dbreg ids are managed: + * + * OPEN + * dbreg_setup (Creates FNAME struct.) + * dbreg_new_id (Assigns new ID to dbp and logs it. May be postponed + * until we attempt to log something else using that dbp, if the dbp + * was opened on a replication client.) + * + * CLOSE + * dbreg_close_id (Logs closure of dbp/revocation of ID.) + * dbreg_revoke_id (As name implies, revokes ID.) + * dbreg_teardown (Destroys FNAME.) + * + * RECOVERY + * dbreg_setup + * dbreg_assign_id (Assigns a particular ID we have in the log to a dbp.) + * + * sometimes: dbreg_revoke_id; dbreg_teardown + * other times: normal close path + * + * A note about locking: + * + * FNAME structures are referenced only by their corresponding dbp's + * until they have a valid id. + * + * Once they have a valid id, they must get linked into the log + * region list so they can get logged on checkpoints. + * + * An FNAME that may/does have a valid id must be accessed under + * protection of the mtx_filelist, with the following exception: + * + * We don't want to have to grab the mtx_filelist on every log + * record, and it should be safe not to do so when we're just + * looking at the id, because once allocated, the id should + * not change under a handle until the handle is closed. + * + * If a handle is closed during an attempt by another thread to + * log with it, well, the application doing the close deserves to + * go down in flames and a lot else is about to fail anyway. + * + * When in the course of logging we encounter an invalid id + * and go to allocate it lazily, we *do* need to check again + * after grabbing the mutex, because it's possible to race with + * another thread that has also decided that it needs to allocate + * a id lazily. + * + * See SR #5623 for further discussion of the new dbreg design. + */ + +/* + * __dbreg_setup -- + * Allocate and initialize an FNAME structure. The FNAME structures + * live in the log shared region and map one-to-one with open database handles. + * When the handle needs to be logged, the FNAME should have a valid fid + * allocated. If the handle currently isn't logged, it still has an FNAME + * entry. If we later discover that the handle needs to be logged, we can + * allocate a id for it later. (This happens when the handle is on a + * replication client that later becomes a master.) + * + * PUBLIC: int __dbreg_setup __P((DB *, const char *, const char *, u_int32_t)); + */ +int +__dbreg_setup(dbp, fname, dname, create_txnid) + DB *dbp; + const char *fname, *dname; + u_int32_t create_txnid; +{ + DB_LOG *dblp; + ENV *env; + FNAME *fnp; + REGINFO *infop; + int ret; + size_t len; + void *p; + + env = dbp->env; + dblp = env->lg_handle; + infop = &dblp->reginfo; + + fnp = NULL; + p = NULL; + + /* Allocate an FNAME and, if necessary, a buffer for the name itself. */ + LOG_SYSTEM_LOCK(env); + if ((ret = __env_alloc(infop, sizeof(FNAME), &fnp)) != 0) + goto err; + memset(fnp, 0, sizeof(FNAME)); + if (fname == NULL) + fnp->fname_off = INVALID_ROFF; + else { + len = strlen(fname) + 1; + if ((ret = __env_alloc(infop, len, &p)) != 0) + goto err; + fnp->fname_off = R_OFFSET(infop, p); + memcpy(p, fname, len); + } + if (dname == NULL) + fnp->dname_off = INVALID_ROFF; + else { + len = strlen(dname) + 1; + if ((ret = __env_alloc(infop, len, &p)) != 0) + goto err; + fnp->dname_off = R_OFFSET(infop, p); + memcpy(p, dname, len); + } + LOG_SYSTEM_UNLOCK(env); + + /* + * Fill in all the remaining info that we'll need later to register + * the file, if we use it for logging. + */ + fnp->id = fnp->old_id = DB_LOGFILEID_INVALID; + fnp->s_type = dbp->type; + memcpy(fnp->ufid, dbp->fileid, DB_FILE_ID_LEN); + fnp->meta_pgno = dbp->meta_pgno; + fnp->create_txnid = create_txnid; + dbp->dbenv->thread_id(dbp->dbenv, &fnp->pid, NULL); + + if (F_ISSET(dbp, DB_AM_INMEM)) + F_SET(fnp, DB_FNAME_INMEM); + if (F_ISSET(dbp, DB_AM_RECOVER)) + F_SET(fnp, DB_FNAME_RECOVER); + fnp->txn_ref = 1; + fnp->mutex = dbp->mutex; + + dbp->log_filename = fnp; + + return (0); + +err: LOG_SYSTEM_UNLOCK(env); + if (ret == ENOMEM) + __db_errx(env, + "Logging region out of memory; you may need to increase its size"); + + return (ret); +} + +/* + * __dbreg_teardown -- + * Destroy a DB handle's FNAME struct. This is only called when closing + * the DB. + * + * PUBLIC: int __dbreg_teardown __P((DB *)); + */ +int +__dbreg_teardown(dbp) + DB *dbp; +{ + int ret; + + /* + * We may not have an FNAME if we were never opened. This is not an + * error. + */ + if (dbp->log_filename == NULL) + return (0); + + ret = __dbreg_teardown_int(dbp->env, dbp->log_filename); + + /* We freed the copy of the mutex from the FNAME. */ + dbp->log_filename = NULL; + dbp->mutex = MUTEX_INVALID; + + return (ret); +} + +/* + * __dbreg_teardown_int -- + * Destroy an FNAME struct. + * + * PUBLIC: int __dbreg_teardown_int __P((ENV *, FNAME *)); + */ +int +__dbreg_teardown_int(env, fnp) + ENV *env; + FNAME *fnp; +{ + DB_LOG *dblp; + REGINFO *infop; + int ret; + + if (F_ISSET(fnp, DB_FNAME_NOTLOGGED)) + return (0); + dblp = env->lg_handle; + infop = &dblp->reginfo; + + DB_ASSERT(env, fnp->id == DB_LOGFILEID_INVALID); + ret = __mutex_free(env, &fnp->mutex); + + LOG_SYSTEM_LOCK(env); + if (fnp->fname_off != INVALID_ROFF) + __env_alloc_free(infop, R_ADDR(infop, fnp->fname_off)); + if (fnp->dname_off != INVALID_ROFF) + __env_alloc_free(infop, R_ADDR(infop, fnp->dname_off)); + __env_alloc_free(infop, fnp); + LOG_SYSTEM_UNLOCK(env); + + return (ret); +} + +/* + * __dbreg_new_id -- + * Get an unused dbreg id to this database handle. + * Used as a wrapper to acquire the mutex and + * only set the id on success. + * + * PUBLIC: int __dbreg_new_id __P((DB *, DB_TXN *)); + */ +int +__dbreg_new_id(dbp, txn) + DB *dbp; + DB_TXN *txn; +{ + DB_LOG *dblp; + ENV *env; + FNAME *fnp; + LOG *lp; + int32_t id; + int ret; + + env = dbp->env; + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + fnp = dbp->log_filename; + + /* The mtx_filelist protects the FNAME list and id management. */ + MUTEX_LOCK(env, lp->mtx_filelist); + if (fnp->id != DB_LOGFILEID_INVALID) { + MUTEX_UNLOCK(env, lp->mtx_filelist); + return (0); + } + if ((ret = __dbreg_get_id(dbp, txn, &id)) == 0) + fnp->id = id; + MUTEX_UNLOCK(env, lp->mtx_filelist); + return (ret); +} + +/* + * __dbreg_get_id -- + * Assign an unused dbreg id to this database handle. + * Assume the caller holds the mtx_filelist locked. Assume the + * caller will set the fnp->id field with the id we return. + * + * PUBLIC: int __dbreg_get_id __P((DB *, DB_TXN *, int32_t *)); + */ +int +__dbreg_get_id(dbp, txn, idp) + DB *dbp; + DB_TXN *txn; + int32_t *idp; +{ + DB_LOG *dblp; + ENV *env; + FNAME *fnp; + LOG *lp; + int32_t id; + int ret; + + env = dbp->env; + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + fnp = dbp->log_filename; + + /* + * It's possible that after deciding we needed to call this function, + * someone else allocated an ID before we grabbed the lock. Check + * to make sure there was no race and we have something useful to do. + */ + /* Get an unused ID from the free list. */ + if ((ret = __dbreg_pop_id(env, &id)) != 0) + goto err; + + /* If no ID was found, allocate a new one. */ + if (id == DB_LOGFILEID_INVALID) + id = lp->fid_max++; + + /* If the file is durable (i.e., not, not-durable), mark it as such. */ + if (!F_ISSET(dbp, DB_AM_NOT_DURABLE)) + F_SET(fnp, DB_FNAME_DURABLE); + + /* Hook the FNAME into the list of open files. */ + SH_TAILQ_INSERT_HEAD(&lp->fq, fnp, q, __fname); + + /* + * Log the registry. We should only request a new ID in situations + * where logging is reasonable. + */ + DB_ASSERT(env, !F_ISSET(dbp, DB_AM_RECOVER)); + + if ((ret = __dbreg_log_id(dbp, txn, id, 0)) != 0) + goto err; + + /* + * Once we log the create_txnid, we need to make sure we never + * log it again (as might happen if this is a replication client + * that later upgrades to a master). + */ + fnp->create_txnid = TXN_INVALID; + + DB_ASSERT(env, dbp->type == fnp->s_type); + DB_ASSERT(env, dbp->meta_pgno == fnp->meta_pgno); + + if ((ret = __dbreg_add_dbentry(env, dblp, dbp, id)) != 0) + goto err; + /* + * If we have a successful call, set the ID. Otherwise + * we have to revoke it and remove it from all the lists + * it has been added to, and return an invalid id. + */ +err: + if (ret != 0 && id != DB_LOGFILEID_INVALID) { + (void)__dbreg_revoke_id(dbp, 1, id); + id = DB_LOGFILEID_INVALID; + } + *idp = id; + return (ret); +} + +/* + * __dbreg_assign_id -- + * Assign a particular dbreg id to this database handle. + * + * PUBLIC: int __dbreg_assign_id __P((DB *, int32_t, int)); + */ +int +__dbreg_assign_id(dbp, id, deleted) + DB *dbp; + int32_t id; + int deleted; +{ + DB *close_dbp; + DB_LOG *dblp; + ENV *env; + FNAME *close_fnp, *fnp; + LOG *lp; + int ret; + + env = dbp->env; + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + fnp = dbp->log_filename; + + close_dbp = NULL; + close_fnp = NULL; + + /* The mtx_filelist protects the FNAME list and id management. */ + MUTEX_LOCK(env, lp->mtx_filelist); + + /* We should only call this on DB handles that have no ID. */ + DB_ASSERT(env, fnp->id == DB_LOGFILEID_INVALID); + + /* + * Make sure there isn't already a file open with this ID. There can + * be in recovery, if we're recovering across a point where an ID got + * reused. + */ + if (__dbreg_id_to_fname(dblp, id, 1, &close_fnp) == 0) { + /* + * We want to save off any dbp we have open with this id. We + * can't safely close it now, because we hold the mtx_filelist, + * but we should be able to rely on it being open in this + * process, and we're running recovery, so no other thread + * should muck with it if we just put off closing it until + * we're ready to return. + * + * Once we have the dbp, revoke its id; we're about to + * reuse it. + */ + ret = __dbreg_id_to_db(env, NULL, &close_dbp, id, 0); + if (ret == ENOENT) { + ret = 0; + goto cont; + } else if (ret != 0) + goto err; + + if ((ret = __dbreg_revoke_id(close_dbp, 1, + DB_LOGFILEID_INVALID)) != 0) + goto err; + } + + /* + * Remove this ID from the free list, if it's there, and make sure + * we don't allocate it anew. + */ +cont: if ((ret = __dbreg_pluck_id(env, id)) != 0) + goto err; + if (id >= lp->fid_max) + lp->fid_max = id + 1; + + /* Now go ahead and assign the id to our dbp. */ + fnp->id = id; + /* If the file is durable (i.e., not, not-durable), mark it as such. */ + if (!F_ISSET(dbp, DB_AM_NOT_DURABLE)) + F_SET(fnp, DB_FNAME_DURABLE); + SH_TAILQ_INSERT_HEAD(&lp->fq, fnp, q, __fname); + + /* + * If we get an error adding the dbentry, revoke the id. + * We void the return value since we want to retain and + * return the original error in ret anyway. + */ + if ((ret = __dbreg_add_dbentry(env, dblp, dbp, id)) != 0) + (void)__dbreg_revoke_id(dbp, 1, id); + else + dblp->dbentry[id].deleted = deleted; + +err: MUTEX_UNLOCK(env, lp->mtx_filelist); + + /* There's nothing useful that our caller can do if this close fails. */ + if (close_dbp != NULL) + (void)__db_close(close_dbp, NULL, DB_NOSYNC); + + return (ret); +} + +/* + * __dbreg_revoke_id -- + * Take a log id away from a dbp, in preparation for closing it, + * but without logging the close. + * + * PUBLIC: int __dbreg_revoke_id __P((DB *, int, int32_t)); + */ +int +__dbreg_revoke_id(dbp, have_lock, force_id) + DB *dbp; + int have_lock; + int32_t force_id; +{ + DB_REP *db_rep; + ENV *env; + int push; + + env = dbp->env; + + /* + * If we are not in recovery but the file was opened for a recovery + * operation, then this process aborted a transaction for another + * process and the id may still be in use, so don't reuse this id. + * If our fid generation in replication has changed, this fid + * should not be reused + */ + db_rep = env->rep_handle; + push = (!F_ISSET(dbp, DB_AM_RECOVER) || IS_RECOVERING(env)) && + (!REP_ON(env) || ((REP *)db_rep->region)->gen == dbp->fid_gen); + + return (__dbreg_revoke_id_int(dbp->env, + dbp->log_filename, have_lock, push, force_id)); +} +/* + * __dbreg_revoke_id_int -- + * Revoke a log, in preparation for closing it, but without logging + * the close. + * + * PUBLIC: int __dbreg_revoke_id_int + * PUBLIC: __P((ENV *, FNAME *, int, int, int32_t)); + */ +int +__dbreg_revoke_id_int(env, fnp, have_lock, push, force_id) + ENV *env; + FNAME *fnp; + int have_lock, push; + int32_t force_id; +{ + DB_LOG *dblp; + LOG *lp; + int32_t id; + int ret; + + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + ret = 0; + + /* If we lack an ID, this is a null-op. */ + if (fnp == NULL) + return (0); + + /* + * If we have a force_id, we had an error after allocating + * the id, and putting it on the fq list, but before we + * finished setting up fnp. So, if we have a force_id use it. + */ + if (force_id != DB_LOGFILEID_INVALID) + id = force_id; + else if (fnp->id == DB_LOGFILEID_INVALID) { + if (fnp->old_id == DB_LOGFILEID_INVALID) + return (0); + id = fnp->old_id; + } else + id = fnp->id; + if (!have_lock) + MUTEX_LOCK(env, lp->mtx_filelist); + + fnp->id = DB_LOGFILEID_INVALID; + fnp->old_id = DB_LOGFILEID_INVALID; + + /* Remove the FNAME from the list of open files. */ + SH_TAILQ_REMOVE(&lp->fq, fnp, q, __fname); + + /* + * This FNAME may be for a DBP which is already closed. Its ID may + * still be in use by an aborting transaction. If not, + * remove this id from the dbentry table and push it onto the + * free list. + */ + if (!F_ISSET(fnp, DB_FNAME_CLOSED) && + (ret = __dbreg_rem_dbentry(dblp, id)) == 0 && push) + ret = __dbreg_push_id(env, id); + + if (!have_lock) + MUTEX_UNLOCK(env, lp->mtx_filelist); + return (ret); +} + +/* + * __dbreg_close_id -- + * Take a dbreg id away from a dbp that we're closing, and log + * the unregistry if the refcount goes to 0. + * + * PUBLIC: int __dbreg_close_id __P((DB *, DB_TXN *, u_int32_t)); + */ +int +__dbreg_close_id(dbp, txn, op) + DB *dbp; + DB_TXN *txn; + u_int32_t op; +{ + DB_LOG *dblp; + ENV *env; + FNAME *fnp; + LOG *lp; + int ret, t_ret; + + env = dbp->env; + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + fnp = dbp->log_filename; + + /* If we lack an ID, this is a null-op. */ + if (fnp == NULL) + return (0); + + if (fnp->id == DB_LOGFILEID_INVALID) { + ret = __dbreg_revoke_id(dbp, 0, DB_LOGFILEID_INVALID); + goto done; + } + + /* + * If we are the last reference to this db then we need to log it + * as closed. Otherwise the last transaction will do the logging. + * Remove the DBP from the db entry table since it can nolonger + * be used. If we abort it will have to be reopened. + */ + ret = 0; + DB_ASSERT(env, fnp->txn_ref > 0); + if (fnp->txn_ref > 1) { + MUTEX_LOCK(env, dbp->mutex); + if (fnp->txn_ref > 1) { + if (!F_ISSET(fnp, DB_FNAME_CLOSED) && + (t_ret = __dbreg_rem_dbentry( + env->lg_handle, fnp->id)) != 0 && ret == 0) + ret = t_ret; + + /* + * The DB handle has been closed in the logging system. + * Transactions may still have a ref to this name. + * Mark it so that if recovery reopens the file id + * the transaction will not close the wrong handle. + */ + F_SET(fnp, DB_FNAME_CLOSED); + fnp->txn_ref--; + MUTEX_UNLOCK(env, dbp->mutex); + /* The mutex now lives only in the FNAME. */ + dbp->mutex = MUTEX_INVALID; + dbp->log_filename = NULL; + goto no_log; + } + } + MUTEX_LOCK(env, lp->mtx_filelist); + + if ((ret = __dbreg_log_close(env, fnp, txn, op)) != 0) + goto err; + ret = __dbreg_revoke_id(dbp, 1, DB_LOGFILEID_INVALID); + +err: MUTEX_UNLOCK(env, lp->mtx_filelist); + +done: if ((t_ret = __dbreg_teardown(dbp)) != 0 && ret == 0) + ret = t_ret; +no_log: + return (ret); +} +/* + * __dbreg_close_id_int -- + * Close down a dbreg id and log the unregistry. This is called only + * when a transaction has the last ref to the fname. + * + * PUBLIC: int __dbreg_close_id_int __P((ENV *, FNAME *, u_int32_t, int)); + */ +int +__dbreg_close_id_int(env, fnp, op, locked) + ENV *env; + FNAME *fnp; + u_int32_t op; + int locked; +{ + DB_LOG *dblp; + LOG *lp; + int ret, t_ret; + + DB_ASSERT(env, fnp->txn_ref == 1); + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + + if (fnp->id == DB_LOGFILEID_INVALID) + return (__dbreg_revoke_id_int(env, + fnp, locked, 1, DB_LOGFILEID_INVALID)); + + if (F_ISSET(fnp, DB_FNAME_RECOVER)) + return (__dbreg_close_file(env, fnp)); + /* + * If log_close fails then it will mark the name DB_FNAME_NOTLOGGED + * and the id must persist. + */ + if (!locked) + MUTEX_LOCK(env, lp->mtx_filelist); + if ((ret = __dbreg_log_close(env, fnp, NULL, op)) != 0) + goto err; + + ret = __dbreg_revoke_id_int(env, fnp, 1, 1, DB_LOGFILEID_INVALID); + +err: if (!locked) + MUTEX_UNLOCK(env, lp->mtx_filelist); + + if ((t_ret = __dbreg_teardown_int(env, fnp)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +/* + * __dbreg_failchk -- + * + * Look for entries that belong to dead processes and either close them + * out or, if there are pending transactions, just remove the mutex which + * will get discarded later. + * + * PUBLIC: int __dbreg_failchk __P((ENV *)); + */ +int +__dbreg_failchk(env) + ENV *env; +{ + DB_ENV *dbenv; + DB_LOG *dblp; + FNAME *fnp, *nnp; + LOG *lp; + int ret, t_ret; + char buf[DB_THREADID_STRLEN]; + + if ((dblp = env->lg_handle) == NULL) + return (0); + + lp = dblp->reginfo.primary; + dbenv = env->dbenv; + ret = 0; + + MUTEX_LOCK(env, lp->mtx_filelist); + for (fnp = SH_TAILQ_FIRST(&lp->fq, __fname); fnp != NULL; fnp = nnp) { + nnp = SH_TAILQ_NEXT(fnp, q, __fname); + if (dbenv->is_alive(dbenv, fnp->pid, 0, DB_MUTEX_PROCESS_ONLY)) + continue; + MUTEX_LOCK(env, fnp->mutex); + __db_msg(env, + "Freeing log information for process: %s, (ref %lu)", + dbenv->thread_id_string(dbenv, fnp->pid, 0, buf), + (u_long)fnp->txn_ref); + if (fnp->txn_ref > 1 || F_ISSET(fnp, DB_FNAME_CLOSED)) { + if (!F_ISSET(fnp, DB_FNAME_CLOSED)) { + fnp->txn_ref--; + F_SET(fnp, DB_FNAME_CLOSED); + } + MUTEX_UNLOCK(env, fnp->mutex); + fnp->mutex = MUTEX_INVALID; + fnp->pid = 0; + } else { + F_SET(fnp, DB_FNAME_CLOSED); + if ((t_ret = __dbreg_close_id_int(env, + fnp, DBREG_CLOSE, 1)) && ret == 0) + ret = t_ret; + } + } + + MUTEX_UNLOCK(env, lp->mtx_filelist); + return (ret); +} +/* + * __dbreg_log_close -- + * + * Log a close of a database. Called when closing a file or when a + * replication client is becoming a master. That closes all the + * files it previously had open. + * + * Assumes caller holds the lp->mutex_filelist lock already. + * + * PUBLIC: int __dbreg_log_close __P((ENV *, FNAME *, + * PUBLIC: DB_TXN *, u_int32_t)); + */ +int +__dbreg_log_close(env, fnp, txn, op) + ENV *env; + FNAME *fnp; + DB_TXN *txn; + u_int32_t op; +{ + DBT fid_dbt, r_name, *dbtp; + DB_LOG *dblp; + DB_LSN r_unused; + int ret; + + dblp = env->lg_handle; + ret = 0; + + if (fnp->fname_off == INVALID_ROFF) + dbtp = NULL; + else { + memset(&r_name, 0, sizeof(r_name)); + r_name.data = R_ADDR(&dblp->reginfo, fnp->fname_off); + r_name.size = (u_int32_t)strlen((char *)r_name.data) + 1; + dbtp = &r_name; + } + memset(&fid_dbt, 0, sizeof(fid_dbt)); + fid_dbt.data = fnp->ufid; + fid_dbt.size = DB_FILE_ID_LEN; + if ((ret = __dbreg_register_log(env, txn, &r_unused, + F_ISSET(fnp, DB_FNAME_DURABLE) ? 0 : DB_LOG_NOT_DURABLE, + op, dbtp, &fid_dbt, fnp->id, + fnp->s_type, fnp->meta_pgno, TXN_INVALID)) != 0) { + /* + * We are trying to close, but the log write failed. + * Unfortunately, close needs to plow forward, because + * the application can't do anything with the handle. + * Make the entry in the shared memory region so that + * when we close the environment, we know that this + * happened. Also, make sure we remove this from the + * per-process table, so that we don't try to close it + * later. + */ + F_SET(fnp, DB_FNAME_NOTLOGGED); + (void)__dbreg_rem_dbentry(dblp, fnp->id); + } + return (ret); +} + +/* + * __dbreg_push_id and __dbreg_pop_id -- + * Dbreg ids from closed files are kept on a stack in shared memory + * for recycling. (We want to reuse them as much as possible because each + * process keeps open files in an array by ID.) Push them to the stack and + * pop them from it, managing memory as appropriate. + * + * The stack is protected by the mtx_filelist, and both functions assume it + * is already locked. + */ +static int +__dbreg_push_id(env, id) + ENV *env; + int32_t id; +{ + DB_LOG *dblp; + LOG *lp; + REGINFO *infop; + int32_t *stack, *newstack; + int ret; + + dblp = env->lg_handle; + infop = &dblp->reginfo; + lp = infop->primary; + + if (id == lp->fid_max - 1) { + lp->fid_max--; + return (0); + } + + /* Check if we have room on the stack. */ + if (lp->free_fid_stack == INVALID_ROFF || + lp->free_fids_alloced <= lp->free_fids + 1) { + LOG_SYSTEM_LOCK(env); + if ((ret = __env_alloc(infop, + (lp->free_fids_alloced + 20) * sizeof(u_int32_t), + &newstack)) != 0) { + LOG_SYSTEM_UNLOCK(env); + return (ret); + } + + if (lp->free_fid_stack != INVALID_ROFF) { + stack = R_ADDR(infop, lp->free_fid_stack); + memcpy(newstack, stack, + lp->free_fids_alloced * sizeof(u_int32_t)); + __env_alloc_free(infop, stack); + } + lp->free_fid_stack = R_OFFSET(infop, newstack); + lp->free_fids_alloced += 20; + LOG_SYSTEM_UNLOCK(env); + } + + stack = R_ADDR(infop, lp->free_fid_stack); + stack[lp->free_fids++] = id; + return (0); +} + +static int +__dbreg_pop_id(env, id) + ENV *env; + int32_t *id; +{ + DB_LOG *dblp; + LOG *lp; + int32_t *stack; + + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + + /* Do we have anything to pop? */ + if (lp->free_fid_stack != INVALID_ROFF && lp->free_fids > 0) { + stack = R_ADDR(&dblp->reginfo, lp->free_fid_stack); + *id = stack[--lp->free_fids]; + } else + *id = DB_LOGFILEID_INVALID; + + return (0); +} + +/* + * __dbreg_pluck_id -- + * Remove a particular dbreg id from the stack of free ids. This is + * used when we open a file, as in recovery, with a specific ID that might + * be on the stack. + * + * Returns success whether or not the particular id was found, and like + * push and pop, assumes that the mtx_filelist is locked. + */ +static int +__dbreg_pluck_id(env, id) + ENV *env; + int32_t id; +{ + DB_LOG *dblp; + LOG *lp; + int32_t *stack; + u_int i; + + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + + if (id >= lp->fid_max) + return (0); + + /* Do we have anything to look at? */ + if (lp->free_fid_stack != INVALID_ROFF) { + stack = R_ADDR(&dblp->reginfo, lp->free_fid_stack); + for (i = 0; i < lp->free_fids; i++) + if (id == stack[i]) { + /* + * Found it. Overwrite it with the top + * id (which may harmlessly be itself), + * and shorten the stack by one. + */ + stack[i] = stack[lp->free_fids - 1]; + lp->free_fids--; + return (0); + } + } + + return (0); +} + +/* + * __dbreg_log_id -- + * Used for in-memory named files. They are created in mpool and + * are given id's early in the open process so that we can read and + * create pages in the mpool for the files. However, at the time that + * the mpf is created, the file may not be fully created and/or its + * meta-data may not be fully known, so we can't do a full dbregister. + * This is a routine exported that will log a complete dbregister + * record that will allow for both recovery and replication. + * + * PUBLIC: int __dbreg_log_id __P((DB *, DB_TXN *, int32_t, int)); + */ +int +__dbreg_log_id(dbp, txn, id, needlock) + DB *dbp; + DB_TXN *txn; + int32_t id; + int needlock; +{ + DBT fid_dbt, r_name; + DB_LOG *dblp; + DB_LSN unused; + ENV *env; + FNAME *fnp; + LOG *lp; + u_int32_t op; + int i, ret; + + env = dbp->env; + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + fnp = dbp->log_filename; + + /* + * Verify that the fnp has been initialized, by seeing if it + * has any non-zero bytes in it. + */ + for (i = 0; i < DB_FILE_ID_LEN; i++) + if (fnp->ufid[i] != 0) + break; + if (i == DB_FILE_ID_LEN) + memcpy(fnp->ufid, dbp->fileid, DB_FILE_ID_LEN); + + if (fnp->s_type == DB_UNKNOWN) + fnp->s_type = dbp->type; + + /* + * Log the registry. We should only request a new ID in situations + * where logging is reasonable. + */ + memset(&fid_dbt, 0, sizeof(fid_dbt)); + memset(&r_name, 0, sizeof(r_name)); + + if (needlock) + MUTEX_LOCK(env, lp->mtx_filelist); + + if (fnp->fname_off != INVALID_ROFF) { + r_name.data = R_ADDR(&dblp->reginfo, fnp->fname_off); + r_name.size = (u_int32_t)strlen((char *)r_name.data) + 1; + } + + fid_dbt.data = dbp->fileid; + fid_dbt.size = DB_FILE_ID_LEN; + + op = !F_ISSET(dbp, DB_AM_OPEN_CALLED) ? DBREG_PREOPEN : + (F_ISSET(dbp, DB_AM_INMEM) ? DBREG_REOPEN : DBREG_OPEN); + ret = __dbreg_register_log(env, txn, &unused, + F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0, + op, r_name.size == 0 ? NULL : &r_name, &fid_dbt, id, + fnp->s_type, fnp->meta_pgno, fnp->create_txnid); + + if (needlock) + MUTEX_UNLOCK(env, lp->mtx_filelist); + + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/dbreg/dbreg.src b/src/libs/resiprocate/contrib/db/dbreg/dbreg.src new file mode 100644 index 00000000..02b2542d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbreg/dbreg.src @@ -0,0 +1,38 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +DBPRIVATE +PREFIX __dbreg + +INCLUDE #include "db_int.h" +INCLUDE #include "dbinc/crypto.h" +INCLUDE #include "dbinc/db_page.h" +INCLUDE #include "dbinc/db_dispatch.h" +INCLUDE #include "dbinc/db_am.h" +INCLUDE #include "dbinc/log.h" +INCLUDE #include "dbinc/txn.h" +INCLUDE + +/* + * Used for registering name/id translations at open or close. + * opcode: register or unregister + * name: file name + * fileid: unique file id + * ftype: file type + * ftype: database type + * id: transaction id of the subtransaction that created the fs object + */ +BEGIN register 42 2 +ARG opcode u_int32_t lu +DBT name DBT s +DBT uid DBT s +ARG fileid int32_t ld +ARG ftype DBTYPE lx +ARG meta_pgno db_pgno_t lu +ARG id u_int32_t lx +END diff --git a/src/libs/resiprocate/contrib/db/dbreg/dbreg_auto.c b/src/libs/resiprocate/contrib/db/dbreg/dbreg_auto.c new file mode 100644 index 00000000..bfd90ba9 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbreg/dbreg_auto.c @@ -0,0 +1,282 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#include "db_config.h" +#include "db_int.h" +#include "dbinc/crypto.h" +#include "dbinc/db_page.h" +#include "dbinc/db_dispatch.h" +#include "dbinc/db_am.h" +#include "dbinc/log.h" +#include "dbinc/txn.h" + +/* + * PUBLIC: int __dbreg_register_read __P((ENV *, void *, + * PUBLIC: __dbreg_register_args **)); + */ +int +__dbreg_register_read(env, recbuf, argpp) + ENV *env; + void *recbuf; + __dbreg_register_args **argpp; +{ + __dbreg_register_args *argp; + u_int32_t uinttmp; + u_int8_t *bp; + int ret; + + if ((ret = __os_malloc(env, + sizeof(__dbreg_register_args) + sizeof(DB_TXN), &argp)) != 0) + return (ret); + bp = recbuf; + argp->txnp = (DB_TXN *)&argp[1]; + memset(argp->txnp, 0, sizeof(DB_TXN)); + + LOGCOPY_32(env, &argp->type, bp); + bp += sizeof(argp->type); + + LOGCOPY_32(env, &argp->txnp->txnid, bp); + bp += sizeof(argp->txnp->txnid); + + LOGCOPY_TOLSN(env, &argp->prev_lsn, bp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, &argp->opcode, bp); + bp += sizeof(argp->opcode); + + memset(&argp->name, 0, sizeof(argp->name)); + LOGCOPY_32(env,&argp->name.size, bp); + bp += sizeof(u_int32_t); + argp->name.data = bp; + bp += argp->name.size; + + memset(&argp->uid, 0, sizeof(argp->uid)); + LOGCOPY_32(env,&argp->uid.size, bp); + bp += sizeof(u_int32_t); + argp->uid.data = bp; + bp += argp->uid.size; + + LOGCOPY_32(env, &uinttmp, bp); + argp->fileid = (int32_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->ftype = (DBTYPE)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &uinttmp, bp); + argp->meta_pgno = (db_pgno_t)uinttmp; + bp += sizeof(uinttmp); + + LOGCOPY_32(env, &argp->id, bp); + bp += sizeof(argp->id); + + *argpp = argp; + return (ret); +} + +/* + * PUBLIC: int __dbreg_register_log __P((ENV *, DB_TXN *, DB_LSN *, + * PUBLIC: u_int32_t, u_int32_t, const DBT *, const DBT *, int32_t, DBTYPE, + * PUBLIC: db_pgno_t, u_int32_t)); + */ +int +__dbreg_register_log(env, txnp, ret_lsnp, flags, + opcode, name, uid, fileid, ftype, meta_pgno, + id) + ENV *env; + DB_TXN *txnp; + DB_LSN *ret_lsnp; + u_int32_t flags; + u_int32_t opcode; + const DBT *name; + const DBT *uid; + int32_t fileid; + DBTYPE ftype; + db_pgno_t meta_pgno; + u_int32_t id; +{ + DBT logrec; + DB_LSN *lsnp, null_lsn, *rlsnp; + DB_TXNLOGREC *lr; + u_int32_t zero, uinttmp, rectype, txn_num; + u_int npad; + u_int8_t *bp; + int is_durable, ret; + + COMPQUIET(lr, NULL); + + rlsnp = ret_lsnp; + rectype = DB___dbreg_register; + npad = 0; + ret = 0; + + if (LF_ISSET(DB_LOG_NOT_DURABLE)) { + if (txnp == NULL) + return (0); + is_durable = 0; + } else + is_durable = 1; + + if (txnp == NULL) { + txn_num = 0; + lsnp = &null_lsn; + null_lsn.file = null_lsn.offset = 0; + } else { + if (TAILQ_FIRST(&txnp->kids) != NULL && + (ret = __txn_activekids(env, rectype, txnp)) != 0) + return (ret); + /* + * We need to assign begin_lsn while holding region mutex. + * That assignment is done inside the DbEnv->log_put call, + * so pass in the appropriate memory location to be filled + * in by the log_put code. + */ + DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp); + txn_num = txnp->txnid; + } + + logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + (name == NULL ? 0 : name->size) + + sizeof(u_int32_t) + (uid == NULL ? 0 : uid->size) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t) + + sizeof(u_int32_t); + if (CRYPTO_ON(env)) { + npad = env->crypto_handle->adj_size(logrec.size); + logrec.size += npad; + } + + if (is_durable || txnp == NULL) { + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) + return (ret); + } else { + if ((ret = __os_malloc(env, + logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0) + return (ret); +#ifdef DIAGNOSTIC + if ((ret = + __os_malloc(env, logrec.size, &logrec.data)) != 0) { + __os_free(env, lr); + return (ret); + } +#else + logrec.data = lr->data; +#endif + } + if (npad > 0) + memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad); + + bp = logrec.data; + + LOGCOPY_32(env, bp, &rectype); + bp += sizeof(rectype); + + LOGCOPY_32(env, bp, &txn_num); + bp += sizeof(txn_num); + + LOGCOPY_FROMLSN(env, bp, lsnp); + bp += sizeof(DB_LSN); + + LOGCOPY_32(env, bp, &opcode); + bp += sizeof(opcode); + + if (name == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &name->size); + bp += sizeof(name->size); + memcpy(bp, name->data, name->size); + bp += name->size; + } + + if (uid == NULL) { + zero = 0; + LOGCOPY_32(env, bp, &zero); + bp += sizeof(u_int32_t); + } else { + LOGCOPY_32(env, bp, &uid->size); + bp += sizeof(uid->size); + memcpy(bp, uid->data, uid->size); + bp += uid->size; + } + + uinttmp = (u_int32_t)fileid; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)ftype; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + uinttmp = (u_int32_t)meta_pgno; + LOGCOPY_32(env,bp, &uinttmp); + bp += sizeof(uinttmp); + + LOGCOPY_32(env, bp, &id); + bp += sizeof(id); + + DB_ASSERT(env, + (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size); + + if (is_durable || txnp == NULL) { + if ((ret = __log_put(env, rlsnp,(DBT *)&logrec, + flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) { + *lsnp = *rlsnp; + if (rlsnp != ret_lsnp) + *ret_lsnp = *rlsnp; + } + } else { + ret = 0; +#ifdef DIAGNOSTIC + /* + * Set the debug bit if we are going to log non-durable + * transactions so they will be ignored by recovery. + */ + memcpy(lr->data, logrec.data, logrec.size); + rectype |= DB_debug_FLAG; + LOGCOPY_32(env, logrec.data, &rectype); + + if (!IS_REP_CLIENT(env)) + ret = __log_put(env, + rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY); +#endif + STAILQ_INSERT_HEAD(&txnp->logs, lr, links); + F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY); + LSN_NOT_LOGGED(*ret_lsnp); + } + +#ifdef LOG_DIAGNOSTIC + if (ret != 0) + (void)__dbreg_register_print(env, + (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL); +#endif + +#ifdef DIAGNOSTIC + __os_free(env, logrec.data); +#else + if (is_durable || txnp == NULL) + __os_free(env, logrec.data); +#endif + return (ret); +} + +/* + * PUBLIC: int __dbreg_init_recover __P((ENV *, DB_DISTAB *)); + */ +int +__dbreg_init_recover(env, dtabp) + ENV *env; + DB_DISTAB *dtabp; +{ + int ret; + + if ((ret = __db_add_recovery_int(env, dtabp, + __dbreg_register_recover, DB___dbreg_register)) != 0) + return (ret); + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/dbreg/dbreg_autop.c b/src/libs/resiprocate/contrib/db/dbreg/dbreg_autop.c new file mode 100644 index 00000000..4fc69cec --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbreg/dbreg_autop.c @@ -0,0 +1,78 @@ +/* Do not edit: automatically built by gen_rec.awk. */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/crypto.h" +#include "dbinc/db_page.h" +#include "dbinc/db_dispatch.h" +#include "dbinc/db_am.h" +#include "dbinc/log.h" +#include "dbinc/txn.h" + +/* + * PUBLIC: int __dbreg_register_print __P((ENV *, DBT *, DB_LSN *, + * PUBLIC: db_recops, void *)); + */ +int +__dbreg_register_print(env, dbtp, lsnp, notused2, notused3) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops notused2; + void *notused3; +{ + __dbreg_register_args *argp; + u_int32_t i; + int ch; + int ret; + + notused2 = DB_TXN_PRINT; + notused3 = NULL; + + if ((ret = __dbreg_register_read(env, dbtp->data, &argp)) != 0) + return (ret); + (void)printf( + "[%lu][%lu]__dbreg_register%s: rec: %lu txnp %lx prevlsn [%lu][%lu]\n", + (u_long)lsnp->file, (u_long)lsnp->offset, + (argp->type & DB_debug_FLAG) ? "_debug" : "", + (u_long)argp->type, + (u_long)argp->txnp->txnid, + (u_long)argp->prev_lsn.file, (u_long)argp->prev_lsn.offset); + (void)printf("\topcode: %lu\n", (u_long)argp->opcode); + (void)printf("\tname: "); + for (i = 0; i < argp->name.size; i++) { + ch = ((u_int8_t *)argp->name.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tuid: "); + for (i = 0; i < argp->uid.size; i++) { + ch = ((u_int8_t *)argp->uid.data)[i]; + printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); + } + (void)printf("\n"); + (void)printf("\tfileid: %ld\n", (long)argp->fileid); + (void)printf("\tftype: 0x%lx\n", (u_long)argp->ftype); + (void)printf("\tmeta_pgno: %lu\n", (u_long)argp->meta_pgno); + (void)printf("\tid: 0x%lx\n", (u_long)argp->id); + (void)printf("\n"); + __os_free(env, argp); + return (0); +} + +/* + * PUBLIC: int __dbreg_init_print __P((ENV *, DB_DISTAB *)); + */ +int +__dbreg_init_print(env, dtabp) + ENV *env; + DB_DISTAB *dtabp; +{ + int ret; + + if ((ret = __db_add_recovery_int(env, dtabp, + __dbreg_register_print, DB___dbreg_register)) != 0) + return (ret); + return (0); +} diff --git a/src/libs/resiprocate/contrib/db/dbreg/dbreg_rec.c b/src/libs/resiprocate/contrib/db/dbreg/dbreg_rec.c new file mode 100644 index 00000000..7cb5150d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbreg/dbreg_rec.c @@ -0,0 +1,397 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996-2009 Oracle. All rights reserved. + */ +/* + * Copyright (c) 1995, 1996 + * The President and Fellows of Harvard University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/log.h" +#include "dbinc/txn.h" + +static int __dbreg_open_file __P((ENV *, + DB_TXN *, __dbreg_register_args *, void *)); + +/* + * PUBLIC: int __dbreg_register_recover + * PUBLIC: __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__dbreg_register_recover(env, dbtp, lsnp, op, info) + ENV *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __dbreg_register_args *argp; + DB_ENTRY *dbe; + DB_LOG *dblp; + DB *dbp; + u_int32_t status; + int do_close, do_open, do_rem, ret, t_ret; + + dblp = env->lg_handle; + dbp = NULL; + +#ifdef DEBUG_RECOVER + REC_PRINT(__dbreg_register_print); +#endif + do_open = do_close = 0; + if ((ret = __dbreg_register_read(env, dbtp->data, &argp)) != 0) + goto out; + + switch (argp->opcode) { + case DBREG_REOPEN: + case DBREG_PREOPEN: + case DBREG_OPEN: + /* + * In general, we redo the open on REDO and abort on UNDO. + * However, a reopen is a second instance of an open of + * in-memory files and we don't want to close them yet + * on abort, so just skip that here. + */ + if ((DB_REDO(op) || + op == DB_TXN_OPENFILES || op == DB_TXN_POPENFILES)) + do_open = 1; + else if (argp->opcode != DBREG_REOPEN) + do_close = 1; + break; + case DBREG_CLOSE: + if (DB_UNDO(op)) + do_open = 1; + else + do_close = 1; + break; + case DBREG_RCLOSE: + /* + * DBREG_RCLOSE was generated by recover because a file was + * left open. The POPENFILES pass, which is run to open + * files to abort prepared transactions, may not include the + * open for this file so we open it here. Note that a normal + * CLOSE is not legal before the prepared transaction is + * committed or aborted. + */ + if (DB_UNDO(op) || op == DB_TXN_POPENFILES) + do_open = 1; + else + do_close = 1; + break; + case DBREG_CHKPNT: + if (DB_UNDO(op) || + op == DB_TXN_OPENFILES || op == DB_TXN_POPENFILES) + do_open = 1; + break; + default: + ret = __db_unknown_path(env, "__dbreg_register_recover"); + goto out; + } + + if (do_open) { + /* + * We must open the db even if the meta page is not + * yet written as we may be creating subdatabase. + */ + if (op == DB_TXN_OPENFILES && argp->opcode != DBREG_CHKPNT) + F_SET(dblp, DBLOG_FORCE_OPEN); + + /* + * During an abort or an open pass to recover prepared txns, + * we need to make sure that we use the same locker id on the + * open. We pass the txnid along to ensure this. + */ + ret = __dbreg_open_file(env, + op == DB_TXN_ABORT || op == DB_TXN_POPENFILES ? + argp->txnp : NULL, argp, info); + if (ret == DB_PAGE_NOTFOUND && argp->meta_pgno != PGNO_BASE_MD) + ret = ENOENT; + if (ret == ENOENT || ret == EINVAL) { + /* + * If this is an OPEN while rolling forward, it's + * possible that the file was recreated since last + * time we got here. In that case, we've got deleted + * set and probably shouldn't, so we need to check + * for that case and possibly retry. + */ + if (DB_REDO(op) && argp->txnp != 0 && + dblp->dbentry[argp->fileid].deleted) { + dblp->dbentry[argp->fileid].deleted = 0; + ret = + __dbreg_open_file(env, NULL, argp, info); + if (ret == DB_PAGE_NOTFOUND && + argp->meta_pgno != PGNO_BASE_MD) + ret = ENOENT; + } + /* + * We treat ENOENT as OK since it's possible that + * the file was renamed or deleted. + * All other errors, we return. + */ + if (ret == ENOENT) + ret = 0; + } + F_CLR(dblp, DBLOG_FORCE_OPEN); + } + + if (do_close) { + /* + * If we are undoing an open, or redoing a close, + * then we need to close the file. If we are simply + * revoking then we just need to grab the DBP and revoke + * the log id. + * + * If the file is deleted, then we can just ignore this close. + * Otherwise, we should usually have a valid dbp we should + * close or whose reference count should be decremented. + * However, if we shut down without closing a file, we may, in + * fact, not have the file open, and that's OK. + */ + do_rem = 0; + MUTEX_LOCK(env, dblp->mtx_dbreg); + if (argp->fileid < dblp->dbentry_cnt) { + /* + * Typically, closes should match an open which means + * that if this is a close, there should be a valid + * entry in the dbentry table when we get here, + * however there are exceptions. 1. If this is an + * OPENFILES pass, then we may have started from + * a log file other than the first, and the + * corresponding open appears in an earlier file. + * 2. If we are undoing an open on an abort or + * recovery, it's possible that we failed after + * the log record, but before we actually entered + * a handle here. + * 3. If we aborted an open, then we wrote a non-txnal + * RCLOSE into the log. During the forward pass, the + * file won't be open, and that's OK. + */ + dbe = &dblp->dbentry[argp->fileid]; + if (dbe->dbp == NULL && !dbe->deleted) { + /* No valid entry here. Nothing to do. */ + MUTEX_UNLOCK(env, dblp->mtx_dbreg); + goto done; + } + + /* We have either an open entry or a deleted entry. */ + if ((dbp = dbe->dbp) != NULL) { + /* + * If we're a replication client, it's + * possible to get here with a dbp that + * the user opened, but which we later + * assigned a fileid to. Be sure that + * we only close dbps that we opened in + * the recovery code or that were opened + * inside a currently aborting transaction + * but not by the recovery code. + */ + do_rem = F_ISSET(dbp, DB_AM_RECOVER) ? + op != DB_TXN_ABORT : op == DB_TXN_ABORT; + MUTEX_UNLOCK(env, dblp->mtx_dbreg); + } else if (dbe->deleted) { + MUTEX_UNLOCK(env, dblp->mtx_dbreg); + if ((ret = __dbreg_rem_dbentry( + dblp, argp->fileid)) != 0) + goto out; + } + } else + MUTEX_UNLOCK(env, dblp->mtx_dbreg); + + /* + * During recovery, all files are closed. On an abort, we only + * close the file if we opened it during the abort + * (DB_AM_RECOVER set), otherwise we simply do a __db_refresh. + * For the close case, if remove or rename has closed the file, + * don't request a sync, because a NULL mpf would be a problem. + * + * If we are undoing a create we'd better discard any buffers + * from the memory pool. We identify creates because the + * argp->id field contains the transaction containing the file + * create; if that id is invalid, we are not creating. + * + * On the backward pass, we need to "undo" opens even if the + * transaction in which they appeared committed, because we have + * already undone the corresponding close. In that case, the + * id will be valid, but we do not want to discard buffers. + */ + if (do_rem && dbp != NULL) { + if (argp->id != TXN_INVALID) { + if ((ret = __db_txnlist_find(env, + info, argp->txnp->txnid, &status)) + != DB_NOTFOUND && ret != 0) + goto out; + if (ret == DB_NOTFOUND || status != TXN_COMMIT) + F_SET(dbp, DB_AM_DISCARD); + ret = 0; + } + + if (op == DB_TXN_ABORT) { + if ((t_ret = __db_refresh(dbp, + NULL, DB_NOSYNC, NULL, 0)) != 0 && ret == 0) + ret = t_ret; + } else { + if ((t_ret = __db_close( + dbp, NULL, DB_NOSYNC)) != 0 && ret == 0) + ret = t_ret; + } + } + } +done: if (ret == 0) + *lsnp = argp->prev_lsn; +out: if (argp != NULL) + __os_free(env, argp); + return (ret); +} + +/* + * __dbreg_open_file -- + * Called during log_register recovery. Make sure that we have an + * entry in the dbentry table for this ndx. Returns 0 on success, + * non-zero on error. + */ +static int +__dbreg_open_file(env, txn, argp, info) + ENV *env; + DB_TXN *txn; + __dbreg_register_args *argp; + void *info; +{ + DB *dbp; + DB_ENTRY *dbe; + DB_LOG *dblp; + u_int32_t id, status; + int ret; + + dblp = env->lg_handle; + + /* + * When we're opening, we have to check that the name we are opening + * is what we expect. If it's not, then we close the old file and + * open the new one. + */ + MUTEX_LOCK(env, dblp->mtx_dbreg); + if (argp->fileid != DB_LOGFILEID_INVALID && + argp->fileid < dblp->dbentry_cnt) + dbe = &dblp->dbentry[argp->fileid]; + else + dbe = NULL; + + if (dbe != NULL) { + if (dbe->deleted) { + MUTEX_UNLOCK(env, dblp->mtx_dbreg); + return (ENOENT); + } + + /* + * At the end of OPENFILES, we may have a file open. If this + * is a reopen, then we will always close and reopen. If the + * open was part of a committed transaction, so it doesn't + * get undone. However, if the fileid was previously used, + * we'll see a close that may need to get undone. There are + * three ways we can detect this. 1) the meta-pgno in the + * current file does not match that of the open file, 2) the + * file uid of the current file does not match that of the + * previously opened file, 3) the current file is unnamed, in + * which case it should never be opened during recovery. + * It is also possible that the db open previously failed + * because the file was missing. Check the DB_AM_OPEN_CALLED + * bit and try to open it again. + */ + if ((dbp = dbe->dbp) != NULL) { + if (argp->opcode == DBREG_REOPEN || + !F_ISSET(dbp, DB_AM_OPEN_CALLED) || + dbp->meta_pgno != argp->meta_pgno || + argp->name.size == 0 || + memcmp(dbp->fileid, argp->uid.data, + DB_FILE_ID_LEN) != 0) { + MUTEX_UNLOCK(env, dblp->mtx_dbreg); + (void)__dbreg_revoke_id(dbp, 0, + DB_LOGFILEID_INVALID); + if (F_ISSET(dbp, DB_AM_RECOVER)) + (void)__db_close(dbp, NULL, DB_NOSYNC); + goto reopen; + } + + /* + * We should only get here if we already have the + * dbp from an openfiles pass, in which case, what's + * here had better be the same dbp. + */ + DB_ASSERT(env, dbe->dbp == dbp); + MUTEX_UNLOCK(env, dblp->mtx_dbreg); + + /* + * This is a successful open. We need to record that + * in the txnlist so that we know how to handle the + * subtransaction that created the file system object. + */ + if (argp->id != TXN_INVALID && + (ret = __db_txnlist_update(env, info, + argp->id, TXN_EXPECTED, NULL, &status, 1)) != 0) + return (ret); + return (0); + } + } + + MUTEX_UNLOCK(env, dblp->mtx_dbreg); + +reopen: + /* + * We never re-open temporary files. Temp files are only useful during + * aborts in which case the dbp was entered when the file was + * registered. During recovery, we treat temp files as properly deleted + * files, allowing the open to fail and not reporting any errors when + * recovery fails to get a valid dbp from __dbreg_id_to_db. + */ + if (argp->name.size == 0) { + (void)__dbreg_add_dbentry(env, dblp, NULL, argp->fileid); + return (ENOENT); + } + + /* + * We are about to pass a recovery txn pointer into the main library. + * We need to make sure that any accessed fields are set appropriately. + */ + if (txn != NULL) { + id = txn->txnid; + memset(txn, 0, sizeof(DB_TXN)); + txn->txnid = id; + txn->mgrp = env->tx_handle; + } + + return (__dbreg_do_open(env, + txn, dblp, argp->uid.data, argp->name.data, argp->ftype, + argp->fileid, argp->meta_pgno, info, argp->id, argp->opcode)); +} diff --git a/src/libs/resiprocate/contrib/db/dbreg/dbreg_stat.c b/src/libs/resiprocate/contrib/db/dbreg/dbreg_stat.c new file mode 100644 index 00000000..57e7f9c8 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbreg/dbreg_stat.c @@ -0,0 +1,135 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/log.h" +#include "dbinc/txn.h" + +#ifdef HAVE_STATISTICS +static int __dbreg_print_all __P((ENV *, u_int32_t)); + +/* + * __dbreg_stat_print -- + * Print the dbreg statistics. + * + * PUBLIC: int __dbreg_stat_print __P((ENV *, u_int32_t)); + */ +int +__dbreg_stat_print(env, flags) + ENV *env; + u_int32_t flags; +{ + int ret; + + if (LF_ISSET(DB_STAT_ALL) && + (ret = __dbreg_print_all(env, flags)) != 0) + return (ret); + + return (0); +} + +/* + * __dbreg_print_fname -- + * Display the contents of an FNAME structure. + * + * PUBLIC: void __dbreg_print_fname __P((ENV *, FNAME *)); + */ +void +__dbreg_print_fname(env, fnp) + ENV *env; + FNAME *fnp; +{ + static const FN fn[] = { + { DB_FNAME_DURABLE, "DB_FNAME_DURABLE" }, + { DB_FNAME_NOTLOGGED, "DB_FNAME_NOTLOGGED" }, + { 0, NULL } + }; + + __db_msg(env, "%s", DB_GLOBAL(db_line)); + __db_msg(env, "DB handle FNAME contents:"); + STAT_LONG("log ID", fnp->id); + STAT_ULONG("Meta pgno", fnp->meta_pgno); + __db_print_fileid(env, fnp->ufid, "\tFile ID"); + STAT_ULONG("create txn", fnp->create_txnid); + __db_prflags(env, NULL, fnp->flags, fn, NULL, "\tFlags"); +} + +/* + * __dbreg_print_all -- + * Display the ENV's list of files. + */ +static int +__dbreg_print_all(env, flags) + ENV *env; + u_int32_t flags; +{ + DB *dbp; + DB_LOG *dblp; + FNAME *fnp; + LOG *lp; + int32_t *stack; + int del, first; + u_int32_t i; + + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + + __db_msg(env, "LOG FNAME list:"); + __mutex_print_debug_single( + env, "File name mutex", lp->mtx_filelist, flags); + + STAT_LONG("Fid max", lp->fid_max); + STAT_LONG("Log buffer size", lp->buffer_size); + + MUTEX_LOCK(env, lp->mtx_filelist); + first = 1; + SH_TAILQ_FOREACH(fnp, &lp->fq, q, __fname) { + if (first) { + first = 0; + __db_msg(env, + "ID\tName\t\tType\tPgno\tPid\tTxnid\tFlags\tDBP-info"); + } + dbp = fnp->id >= dblp->dbentry_cnt ? NULL : + dblp->dbentry[fnp->id].dbp; + del = fnp->id >= dblp->dbentry_cnt ? 0 : + dblp->dbentry[fnp->id].deleted; + __db_msg(env, + "%ld\t%-8s%s%-8s%s\t%lu\t%lu\t%lx\t%lx\t%s (%d %lx %lx)", + (long)fnp->id, + fnp->fname_off == INVALID_ROFF ? + "" : (char *)R_ADDR(&dblp->reginfo, fnp->fname_off), + fnp->dname_off == INVALID_ROFF ? "" : ":", + fnp->dname_off == INVALID_ROFF ? + "" : (char *)R_ADDR(&dblp->reginfo, fnp->dname_off), + __db_dbtype_to_string(fnp->s_type), + (u_long)fnp->meta_pgno, (u_long)fnp->pid, + (u_long)fnp->create_txnid, (u_long)fnp->flags, + dbp == NULL ? "No DBP" : "DBP", del, P_TO_ULONG(dbp), + (u_long)(dbp == NULL ? 0 : dbp->flags)); + } + MUTEX_UNLOCK(env, lp->mtx_filelist); + + __db_msg(env, "%s", DB_GLOBAL(db_line)); + __db_msg(env, "LOG region list of free IDs."); + if (lp->free_fid_stack == INVALID_ROFF) + __db_msg(env, "Free id stack is empty."); + else { + STAT_ULONG("Free id array size", lp->free_fids_alloced); + STAT_ULONG("Number of ids on the free stack", lp->free_fids); + stack = R_ADDR(&dblp->reginfo, lp->free_fid_stack); + for (i = 0; i < lp->free_fids; i++) + STAT_LONG("fid", stack[i]); + } + + return (0); +} +#endif diff --git a/src/libs/resiprocate/contrib/db/dbreg/dbreg_util.c b/src/libs/resiprocate/contrib/db/dbreg/dbreg_util.c new file mode 100644 index 00000000..e541dd89 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dbreg/dbreg_util.c @@ -0,0 +1,810 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/fop.h" +#include "dbinc/log.h" +#include "dbinc/mp.h" +#include "dbinc/txn.h" + +static int __dbreg_check_master __P((ENV *, u_int8_t *, char *)); + +/* + * __dbreg_add_dbentry -- + * Adds a DB entry to the dbreg DB entry table. + * + * PUBLIC: int __dbreg_add_dbentry __P((ENV *, DB_LOG *, DB *, int32_t)); + */ +int +__dbreg_add_dbentry(env, dblp, dbp, ndx) + ENV *env; + DB_LOG *dblp; + DB *dbp; + int32_t ndx; +{ + int32_t i; + int ret; + + ret = 0; + + MUTEX_LOCK(env, dblp->mtx_dbreg); + + /* + * Check if we need to grow the table. Note, ndx is 0-based (the + * index into the DB entry table) an dbentry_cnt is 1-based, the + * number of available slots. + */ + if (dblp->dbentry_cnt <= ndx) { + if ((ret = __os_realloc(env, + (size_t)(ndx + DB_GROW_SIZE) * sizeof(DB_ENTRY), + &dblp->dbentry)) != 0) + goto err; + + /* Initialize the new entries. */ + for (i = dblp->dbentry_cnt; i < ndx + DB_GROW_SIZE; i++) { + dblp->dbentry[i].dbp = NULL; + dblp->dbentry[i].deleted = 0; + } + dblp->dbentry_cnt = i; + } + + DB_ASSERT(env, dblp->dbentry[ndx].dbp == NULL); + dblp->dbentry[ndx].deleted = dbp == NULL; + dblp->dbentry[ndx].dbp = dbp; + +err: MUTEX_UNLOCK(env, dblp->mtx_dbreg); + return (ret); +} + +/* + * __dbreg_rem_dbentry + * Remove an entry from the DB entry table. + * + * PUBLIC: int __dbreg_rem_dbentry __P((DB_LOG *, int32_t)); + */ +int +__dbreg_rem_dbentry(dblp, ndx) + DB_LOG *dblp; + int32_t ndx; +{ + MUTEX_LOCK(dblp->env, dblp->mtx_dbreg); + if (dblp->dbentry_cnt > ndx) { + dblp->dbentry[ndx].dbp = NULL; + dblp->dbentry[ndx].deleted = 0; + } + MUTEX_UNLOCK(dblp->env, dblp->mtx_dbreg); + + return (0); +} + +/* + * __dbreg_log_files -- + * Put a DBREG_CHKPNT/CLOSE log record for each open database. + * + * PUBLIC: int __dbreg_log_files __P((ENV *, u_int32_t)); + */ +int +__dbreg_log_files(env, opcode) + ENV *env; + u_int32_t opcode; +{ + DBT *dbtp, fid_dbt, t; + DB_LOG *dblp; + DB_LSN r_unused; + FNAME *fnp; + LOG *lp; + int ret; + + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + + ret = 0; + + MUTEX_LOCK(env, lp->mtx_filelist); + + SH_TAILQ_FOREACH(fnp, &lp->fq, q, __fname) { + /* This id was revoked by a switch in replication master. */ + if (fnp->id == DB_LOGFILEID_INVALID) + continue; + if (fnp->fname_off == INVALID_ROFF) + dbtp = NULL; + else { + memset(&t, 0, sizeof(t)); + t.data = R_ADDR(&dblp->reginfo, fnp->fname_off); + t.size = (u_int32_t)strlen(t.data) + 1; + dbtp = &t; + } + memset(&fid_dbt, 0, sizeof(fid_dbt)); + fid_dbt.data = fnp->ufid; + fid_dbt.size = DB_FILE_ID_LEN; + /* + * Output DBREG_CHKPNT records which will be processed during + * the OPENFILES pass of recovery. At the end of recovery we + * want to output the files that were open so a future recovery + * run will have the correct files open during a backward pass. + * For this we output DBREG_RCLOSE records so the files will be + * closed on the forward pass. + */ + if ((ret = __dbreg_register_log(env, NULL, &r_unused, + F_ISSET(fnp, DB_FNAME_DURABLE) ? 0 : DB_LOG_NOT_DURABLE, + opcode, + dbtp, &fid_dbt, fnp->id, fnp->s_type, fnp->meta_pgno, + TXN_INVALID)) != 0) + break; + } + + MUTEX_UNLOCK(env, lp->mtx_filelist); + + return (ret); +} + +/* + * __dbreg_close_files -- + * Remove the id's of open files and actually close those + * files that were opened by the recovery daemon. We sync the + * file, unless its mpf pointer has been NULLed by a db_remove or + * db_rename. We may not have flushed the log_register record that + * closes the file. + * + * PUBLIC: int __dbreg_close_files __P((ENV *, int)); + */ +int +__dbreg_close_files(env, do_restored) + ENV *env; + int do_restored; +{ + DB *dbp; + DB_LOG *dblp; + int ret, t_ret; + int32_t i; + + /* If we haven't initialized logging, we have nothing to do. */ + if (!LOGGING_ON(env)) + return (0); + + dblp = env->lg_handle; + ret = 0; + + MUTEX_LOCK(env, dblp->mtx_dbreg); + for (i = 0; i < dblp->dbentry_cnt; i++) { + /* + * We only want to close dbps that recovery opened. Any + * dbps that weren't opened by recovery but show up here + * are about to be unconditionally removed from the table. + * Before doing so, we need to revoke their log fileids + * so that we don't end up leaving around FNAME entries + * for dbps that shouldn't have them. + */ + if ((dbp = dblp->dbentry[i].dbp) != NULL) { + /* + * It's unsafe to call DB->close or revoke_id + * while holding the thread lock, because + * we'll call __dbreg_rem_dbentry and grab it again. + * + * Just drop it. Since dbreg ids go monotonically + * upward, concurrent opens should be safe, and the + * user should have no business closing files while + * we're in this loop anyway--we're in the process of + * making all outstanding dbps invalid. + */ + /* + * If we only want to close those FNAMES marked + * as restored, check now. + */ + if (do_restored && + !F_ISSET(dbp->log_filename, DB_FNAME_RESTORED)) + continue; + MUTEX_UNLOCK(env, dblp->mtx_dbreg); + if (F_ISSET(dbp, DB_AM_RECOVER)) + t_ret = __db_close(dbp, + NULL, dbp->mpf == NULL ? DB_NOSYNC : 0); + else + t_ret = __dbreg_revoke_id( + dbp, 0, DB_LOGFILEID_INVALID); + if (ret == 0) + ret = t_ret; + MUTEX_LOCK(env, dblp->mtx_dbreg); + } + + dblp->dbentry[i].deleted = 0; + dblp->dbentry[i].dbp = NULL; + } + MUTEX_UNLOCK(env, dblp->mtx_dbreg); + return (ret); +} + +/* + * __dbreg_close_file -- + * Close a database file opened by recovery. + * PUBLIC: int __dbreg_close_file __P((ENV *, FNAME *)); + */ +int +__dbreg_close_file(env, fnp) + ENV *env; + FNAME *fnp; +{ + DB *dbp; + DB_LOG *dblp; + + dblp = env->lg_handle; + + dbp = dblp->dbentry[fnp->id].dbp; + if (dbp == NULL) + return (0); + DB_ASSERT(env, dbp->log_filename == fnp); + DB_ASSERT(env, F_ISSET(dbp, DB_AM_RECOVER)); + return (__db_close(dbp, NULL, DB_NOSYNC)); +} + +/* + * __dbreg_mark_restored -- + * Mark files when we change replication roles and there are outstanding + * prepared txns that may use these files. These will be invalidated later + * when all outstanding prepared txns are resolved. + * + * PUBLIC: int __dbreg_mark_restored __P((ENV *)); + */ +int +__dbreg_mark_restored(env) + ENV *env; +{ + DB_LOG *dblp; + FNAME *fnp; + LOG *lp; + + /* If we haven't initialized logging, we have nothing to do. */ + if (!LOGGING_ON(env)) + return (0); + + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + + MUTEX_LOCK(env, lp->mtx_filelist); + SH_TAILQ_FOREACH(fnp, &lp->fq, q, __fname) + if (fnp->id != DB_LOGFILEID_INVALID) + F_SET(fnp, DB_FNAME_RESTORED); + + MUTEX_UNLOCK(env, lp->mtx_filelist); + return (0); +} + +/* + * __dbreg_invalidate_files -- + * Invalidate files when we change replication roles. Save the + * id so that another process will be able to clean up the information + * when it notices. + * + * PUBLIC: int __dbreg_invalidate_files __P((ENV *, int)); + */ +int +__dbreg_invalidate_files(env, do_restored) + ENV *env; + int do_restored; +{ + DB_LOG *dblp; + FNAME *fnp; + LOG *lp; + int ret; + + /* If we haven't initialized logging, we have nothing to do. */ + if (!LOGGING_ON(env)) + return (0); + + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + + ret = 0; + MUTEX_LOCK(env, lp->mtx_filelist); + SH_TAILQ_FOREACH(fnp, &lp->fq, q, __fname) { + /* + * Normally, skip any file with DB_FNAME_RESTORED + * set. If do_restored is set, only invalidate + * those files with the flag set and skip all others. + */ + if (F_ISSET(fnp, DB_FNAME_RESTORED) && !do_restored) + continue; + if (!F_ISSET(fnp, DB_FNAME_RESTORED) && do_restored) + continue; + if (fnp->id != DB_LOGFILEID_INVALID) { + if ((ret = __dbreg_log_close(env, + fnp, NULL, DBREG_RCLOSE)) != 0) + goto err; + fnp->old_id = fnp->id; + fnp->id = DB_LOGFILEID_INVALID; + } + } +err: MUTEX_UNLOCK(env, lp->mtx_filelist); + return (ret); +} + +/* + * __dbreg_id_to_db -- + * Return the DB corresponding to the specified dbreg id. + * + * PUBLIC: int __dbreg_id_to_db __P((ENV *, DB_TXN *, DB **, int32_t, int)); + */ +int +__dbreg_id_to_db(env, txn, dbpp, ndx, tryopen) + ENV *env; + DB_TXN *txn; + DB **dbpp; + int32_t ndx; + int tryopen; +{ + DB_LOG *dblp; + FNAME *fname; + int ret; + char *name; + + dblp = env->lg_handle; + ret = 0; + + MUTEX_LOCK(env, dblp->mtx_dbreg); + + /* + * We take a final parameter that indicates whether we should attempt + * to open the file if no mapping is found. During recovery, the + * recovery routines all want to try to open the file (and this is + * called from __dbreg_id_to_db), however, if we have a multi-process + * environment where some processes may not have the files open, + * then we also get called from __dbreg_assign_id and it's OK if + * there is no mapping. + * + * Under failchk, a process different than the one issuing DB + * operations may abort a transaction. In this case, the "recovery" + * routines are run by a process that does not necessarily have the + * file open, so we we must open the file explicitly. + */ + if (ndx >= dblp->dbentry_cnt || + (!dblp->dbentry[ndx].deleted && dblp->dbentry[ndx].dbp == NULL)) { + if (!tryopen || F_ISSET(dblp, DBLOG_RECOVER)) { + ret = ENOENT; + goto err; + } + + /* + * __dbreg_id_to_fname acquires the mtx_filelist mutex, which + * we can't safely acquire while we hold the thread lock. We + * no longer need it anyway--the dbentry table didn't have what + * we needed. + */ + MUTEX_UNLOCK(env, dblp->mtx_dbreg); + + if (__dbreg_id_to_fname(dblp, ndx, 0, &fname) != 0) + /* + * With transactional opens, we may actually have + * closed this file in the transaction in which + * case this will fail too. Then it's up to the + * caller to reopen the file. + */ + return (ENOENT); + + /* + * Note that we're relying on fname not to change, even though + * we released the mutex that protects it (mtx_filelist) inside + * __dbreg_id_to_fname. This should be a safe assumption, the + * other process that has the file open shouldn't be closing it + * while we're trying to abort. + */ + name = fname->fname_off == INVALID_ROFF ? + NULL : R_ADDR(&dblp->reginfo, fname->fname_off); + + /* + * At this point, we are not holding the thread lock, so exit + * directly instead of going through the exit code at the + * bottom. If the __dbreg_do_open succeeded, then we don't need + * to do any of the remaining error checking at the end of this + * routine. + * If TXN_INVALID is passed then no txnlist is needed. + */ + if ((ret = __dbreg_do_open(env, txn, dblp, + fname->ufid, name, fname->s_type, ndx, fname->meta_pgno, + NULL, TXN_INVALID, F_ISSET(fname, DB_FNAME_INMEM) ? + DBREG_REOPEN : DBREG_OPEN)) != 0) + return (ret); + + *dbpp = dblp->dbentry[ndx].dbp; + return (*dbpp == NULL ? DB_DELETED : 0); + } + + /* + * Return DB_DELETED if the file has been deleted (it's not an error). + */ + if (dblp->dbentry[ndx].deleted) { + ret = DB_DELETED; + goto err; + } + + /* It's an error if we don't have a corresponding writeable DB. */ + if ((*dbpp = dblp->dbentry[ndx].dbp) == NULL) + ret = ENOENT; + else + /* + * If we are in recovery, then set that the file has + * been written. It is possible to run recovery, + * find all the pages in their post update state + * in the OS buffer pool, put a checkpoint in the log + * and then crash the system without forcing the pages + * to disk. If this is an in-memory file, we may not have + * an mpf yet. + */ + if ((*dbpp)->mpf != NULL && (*dbpp)->mpf->mfp != NULL) + (*dbpp)->mpf->mfp->file_written = 1; + +err: MUTEX_UNLOCK(env, dblp->mtx_dbreg); + return (ret); +} + +/* + * __dbreg_id_to_fname -- + * Traverse the shared-memory region looking for the entry that + * matches the passed dbreg id. Returns 0 on success; -1 on error. + * + * PUBLIC: int __dbreg_id_to_fname __P((DB_LOG *, int32_t, int, FNAME **)); + */ +int +__dbreg_id_to_fname(dblp, id, have_lock, fnamep) + DB_LOG *dblp; + int32_t id; + int have_lock; + FNAME **fnamep; +{ + ENV *env; + FNAME *fnp; + LOG *lp; + int ret; + + env = dblp->env; + lp = dblp->reginfo.primary; + + ret = -1; + + if (!have_lock) + MUTEX_LOCK(env, lp->mtx_filelist); + SH_TAILQ_FOREACH(fnp, &lp->fq, q, __fname) + if (fnp->id == id) { + *fnamep = fnp; + ret = 0; + break; + } + if (!have_lock) + MUTEX_UNLOCK(env, lp->mtx_filelist); + + return (ret); +} +/* + * __dbreg_fid_to_fname -- + * Traverse the shared-memory region looking for the entry that + * matches the passed file unique id. Returns 0 on success; -1 on error. + * + * PUBLIC: int __dbreg_fid_to_fname __P((DB_LOG *, u_int8_t *, int, FNAME **)); + */ +int +__dbreg_fid_to_fname(dblp, fid, have_lock, fnamep) + DB_LOG *dblp; + u_int8_t *fid; + int have_lock; + FNAME **fnamep; +{ + ENV *env; + FNAME *fnp; + LOG *lp; + int ret; + + env = dblp->env; + lp = dblp->reginfo.primary; + + ret = -1; + + if (!have_lock) + MUTEX_LOCK(env, lp->mtx_filelist); + SH_TAILQ_FOREACH(fnp, &lp->fq, q, __fname) + if (memcmp(fnp->ufid, fid, DB_FILE_ID_LEN) == 0) { + *fnamep = fnp; + ret = 0; + break; + } + if (!have_lock) + MUTEX_UNLOCK(env, lp->mtx_filelist); + + return (ret); +} + +/* + * __dbreg_get_name + * + * Interface to get name of registered files. This is mainly diagnostic + * and the name passed could be transient unless there is something + * ensuring that the file cannot be closed. + * + * PUBLIC: int __dbreg_get_name __P((ENV *, u_int8_t *, char **, char **)); + */ +int +__dbreg_get_name(env, fid, fnamep, dnamep) + ENV *env; + u_int8_t *fid; + char **fnamep, **dnamep; +{ + DB_LOG *dblp; + FNAME *fnp; + + dblp = env->lg_handle; + + if (dblp != NULL && __dbreg_fid_to_fname(dblp, fid, 0, &fnp) == 0) { + *fnamep = fnp->fname_off == INVALID_ROFF ? + NULL : R_ADDR(&dblp->reginfo, fnp->fname_off); + *dnamep = fnp->dname_off == INVALID_ROFF ? + NULL : R_ADDR(&dblp->reginfo, fnp->dname_off); + return (0); + } + + *fnamep = *dnamep = NULL; + return (-1); +} + +/* + * __dbreg_do_open -- + * Open files referenced in the log. This is the part of the open that + * is not protected by the thread mutex. + * PUBLIC: int __dbreg_do_open __P((ENV *, + * PUBLIC: DB_TXN *, DB_LOG *, u_int8_t *, char *, DBTYPE, + * PUBLIC: int32_t, db_pgno_t, void *, u_int32_t, u_int32_t)); + */ +int +__dbreg_do_open(env, + txn, lp, uid, name, ftype, ndx, meta_pgno, info, id, opcode) + ENV *env; + DB_TXN *txn; + DB_LOG *lp; + u_int8_t *uid; + char *name; + DBTYPE ftype; + int32_t ndx; + db_pgno_t meta_pgno; + void *info; + u_int32_t id, opcode; +{ + DB *dbp; + u_int32_t cstat, ret_stat; + int ret, t_ret, try_inmem; + char *dname, *fname; + + cstat = TXN_EXPECTED; + fname = name; + dname = NULL; + try_inmem = 0; + +retry_inmem: + if ((ret = __db_create_internal(&dbp, lp->env, 0)) != 0) + return (ret); + + /* + * We can open files under a number of different scenarios. + * First, we can open a file during a normal txn_abort, if that file + * was opened and closed during the transaction (as is the master + * database of a sub-database). + * Second, we might be aborting a transaction in a process other than + * the one that did it (failchk). + * Third, we might be in recovery. + * In case 3, there is no locking, so there is no issue. + * In cases 1 and 2, we are guaranteed to already hold any locks + * that we need, since we're still in the same transaction, so by + * setting DB_AM_RECOVER, we guarantee that we don't log and that + * we don't try to acquire locks on behalf of a different locker id. + */ + F_SET(dbp, DB_AM_RECOVER); + if (meta_pgno != PGNO_BASE_MD) { + memcpy(dbp->fileid, uid, DB_FILE_ID_LEN); + dbp->meta_pgno = meta_pgno; + } + if (opcode == DBREG_PREOPEN) { + dbp->type = ftype; + if ((ret = __dbreg_setup(dbp, name, NULL, id)) != 0) + goto err; + MAKE_INMEM(dbp); + goto skip_open; + } + + if (opcode == DBREG_REOPEN || try_inmem) { + MAKE_INMEM(dbp); + fname = NULL; + dname = name; + } + + if ((ret = __db_open(dbp, NULL, txn, fname, dname, ftype, + DB_DURABLE_UNKNOWN | DB_ODDFILESIZE, + DB_MODE_600, meta_pgno)) == 0) { +skip_open: + /* + * Verify that we are opening the same file that we were + * referring to when we wrote this log record. + */ + if ((meta_pgno != PGNO_BASE_MD && + __dbreg_check_master(env, uid, name) != 0) || + memcmp(uid, dbp->fileid, DB_FILE_ID_LEN) != 0) + cstat = TXN_UNEXPECTED; + else + cstat = TXN_EXPECTED; + + /* Assign the specific dbreg id to this dbp. */ + if ((ret = __dbreg_assign_id(dbp, ndx, 0)) != 0) + goto err; + + /* + * If we successfully opened this file, then we need to + * convey that information to the txnlist so that we + * know how to handle the subtransaction that created + * the file system object. + */ + if (id != TXN_INVALID) + ret = __db_txnlist_update(env, + info, id, cstat, NULL, &ret_stat, 1); + +err: if (cstat == TXN_UNEXPECTED) + goto not_right; + return (ret); + } else if (ret == ENOENT) { + /* + * If the open failed with ENOENT, retry it as a named in-mem + * database. Some record types do not distinguish between a + * named in-memory database and one on-disk. Therefore, an + * internal init via replication that is trying to open and + * access this as a named in-mem database will not find it + * on-disk, and we need to try to open it in-memory too. + * But don't do this for [P]REOPEN, since we're already + * handling those cases specially, above. + */ + if (try_inmem == 0 && + opcode != DBREG_PREOPEN && opcode != DBREG_REOPEN) { + if ((ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0) + return (ret); + try_inmem = 1; + goto retry_inmem; + } else if (try_inmem != 0) + CLR_INMEM(dbp); + + /* + * If it exists neither on disk nor in memory + * record that the open failed in the txnlist. + */ + if (id != TXN_INVALID && (ret = __db_txnlist_update(env, + info, id, TXN_UNEXPECTED, NULL, &ret_stat, 1)) != 0) + goto not_right; + + /* + * If this is file is missing then we may have crashed + * without writing the corresponding close, record + * the open so recovery will write a close record + * with its checkpoint. + */ + if ((opcode == DBREG_CHKPNT || opcode == DBREG_OPEN) && + dbp->log_filename == NULL && + (ret = __dbreg_setup(dbp, name, NULL, id)) != 0) + return (ret); + ret = __dbreg_assign_id(dbp, ndx, 1); + return (ret); + } +not_right: + if ((t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0) + return (ret == 0 ? t_ret : ret); + + /* Add this file as deleted. */ + if ((t_ret = __dbreg_add_dbentry(env, lp, NULL, ndx)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +static int +__dbreg_check_master(env, uid, name) + ENV *env; + u_int8_t *uid; + char *name; +{ + DB *dbp; + int ret; + + ret = 0; + if ((ret = __db_create_internal(&dbp, env, 0)) != 0) + return (ret); + F_SET(dbp, DB_AM_RECOVER); + ret = __db_open(dbp, NULL, NULL, + name, NULL, DB_BTREE, 0, DB_MODE_600, PGNO_BASE_MD); + + if (ret == 0 && memcmp(uid, dbp->fileid, DB_FILE_ID_LEN) != 0) + ret = EINVAL; + + (void)__db_close(dbp, NULL, 0); + return (ret); +} + +/* + * __dbreg_lazy_id -- + * When a replication client gets upgraded to being a replication master, + * it may have database handles open that have not been assigned an ID, but + * which have become legal to use for logging. + * + * This function lazily allocates a new ID for such a function, in a + * new transaction created for the purpose. We need to do this in a new + * transaction because we definitely wish to commit the dbreg_register, but + * at this point we have no way of knowing whether the log record that incited + * us to call this will be part of a committed transaction. + * + * We first revoke any old id this handle may have had. That can happen + * if a master becomes a client and then becomes a master again and + * there are other processes with valid open handles to this env. + * + * PUBLIC: int __dbreg_lazy_id __P((DB *)); + */ +int +__dbreg_lazy_id(dbp) + DB *dbp; +{ + DB_LOG *dblp; + DB_TXN *txn; + ENV *env; + FNAME *fnp; + LOG *lp; + int32_t id; + int ret; + + env = dbp->env; + + DB_ASSERT(env, IS_REP_MASTER(env)); + + env = dbp->env; + dblp = env->lg_handle; + lp = dblp->reginfo.primary; + fnp = dbp->log_filename; + + /* The mtx_filelist protects the FNAME list and id management. */ + MUTEX_LOCK(env, lp->mtx_filelist); + if (fnp->id != DB_LOGFILEID_INVALID) { + MUTEX_UNLOCK(env, lp->mtx_filelist); + return (0); + } + id = DB_LOGFILEID_INVALID; + /* + * When we became master we moved the fnp->id to old_id in + * every FNAME structure that was open. If our id was changed, + * we need to revoke and give back that id. + */ + if (fnp->old_id != DB_LOGFILEID_INVALID && + (ret = __dbreg_revoke_id(dbp, 1, DB_LOGFILEID_INVALID)) != 0) + goto err; + if ((ret = __txn_begin(env, NULL, NULL, &txn, 0)) != 0) + goto err; + + if ((ret = __dbreg_get_id(dbp, txn, &id)) != 0) { + (void)__txn_abort(txn); + goto err; + } + + if ((ret = __txn_commit(txn, DB_TXN_NOSYNC)) != 0) + goto err; + + /* + * All DB related logging routines check the id value *without* + * holding the mtx_filelist to know whether we need to call + * dbreg_lazy_id to begin with. We must set the ID after a + * *successful* commit so that there is no possibility of a second + * modification call finding a valid ID in the dbp before the + * dbreg_register and commit records are in the log. + * If there was an error, then we call __dbreg_revoke_id to + * remove the entry from the lists. + */ + fnp->id = id; +err: + if (ret != 0 && id != DB_LOGFILEID_INVALID) + (void)__dbreg_revoke_id(dbp, 1, id); + MUTEX_UNLOCK(env, lp->mtx_filelist); + return (ret); +} diff --git a/src/libs/resiprocate/contrib/db/dist/Makefile.in b/src/libs/resiprocate/contrib/db/dist/Makefile.in new file mode 100644 index 00000000..c4b07399 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/Makefile.in @@ -0,0 +1,2228 @@ +# $Id$ + +srcdir= @srcdir@/.. +builddir=. + +################################################## +# Installation directories and permissions. +################################################## +prefix= @prefix@ +exec_prefix=@exec_prefix@ +bindir= @bindir@ +includedir=@includedir@ +libdir= @libdir@ +docdir= $(prefix)/docs + +dmode= 755 +emode= 555 +fmode= 444 + +transform=@program_transform_name@ + +################################################## +# Paths for standard user-level commands. +################################################## +AR= @AR@ +CHMOD= @CHMOD@ +CP= @CP@ +LN= @LN@ +MKDIR= @MKDIR@ +RANLIB= @RANLIB@ +RM= @RM@ +SHELL= @db_cv_path_sh@ +STRIP= @STRIP@ + +################################################## +# General library information. +################################################## +DEF_LIB= @DEFAULT_LIB@ +DEF_LIB_CXX= @DEFAULT_LIB_CXX@ +DEF_LIB_STL= @DEFAULT_LIB_STL@ +INSTALLER= @INSTALLER@ +LIBTOOL= @LIBTOOL@ + +POSTLINK= @POSTLINK@ +SOLINK= @MAKEFILE_SOLINK@ @CFLAGS@ +SOFLAGS= @SOFLAGS@ +LIBMAJOR= @DB_VERSION_MAJOR@ +LIBVERSION= @DB_VERSION_MAJOR@.@DB_VERSION_MINOR@ + +CPPFLAGS= -I$(builddir) -I$(srcdir) @CPPFLAGS@ + +################################################## +# C API. +################################################## +CFLAGS= -c $(CPPFLAGS) @CFLAGS@ +CC= @MAKEFILE_CC@ +CCLINK= @MAKEFILE_CCLINK@ @CFLAGS@ + +LDFLAGS= @LDFLAGS@ +LIBS= @LIBSO_LIBS@ +TEST_LIBS= @TEST_LIBS@ +LIBCSO_LIBS= @LIBCSO_LIBS@ @LIBSO_LIBS@ + +libdb_base= libdb +libdb= $(libdb_base).a +libdb_version= $(libdb_base)-$(LIBVERSION).a +libso= $(libdb_base)-$(LIBVERSION)@SOSUFFIX@ +libso_target= $(libdb_base)-$(LIBVERSION).la +libso_default= $(libdb_base)@SOSUFFIX@ +libso_major= $(libdb_base)-$(LIBMAJOR)@SOSUFFIX@ + +################################################## +# C++ API. +# +# C++ support is optional, and can be built with static or shared libraries. +################################################## +CXXFLAGS= -c $(CPPFLAGS) @CXXFLAGS@ +CXX= @MAKEFILE_CXX@ +CXXLINK= @MAKEFILE_CXXLINK@ @CXXFLAGS@ +XSOLINK= @MAKEFILE_XSOLINK@ @CXXFLAGS@ +LIBXSO_LIBS= @LIBXSO_LIBS@ @LIBSO_LIBS@ + +libcxx_base= libdb_cxx +libcxx= $(libcxx_base).a +libcxx_version= $(libcxx_base)-$(LIBVERSION).a +libxso= $(libcxx_base)-$(LIBVERSION)@SOSUFFIX@ +libxso_target= $(libcxx_base)-$(LIBVERSION).la +libxso_default= $(libcxx_base)@SOSUFFIX@ +libxso_major= $(libcxx_base)-$(LIBMAJOR)@SOSUFFIX@ + +################################################## +# STL API. +# +# STL support is optional, and can be built with static or shared libraries. +################################################## +STLFLAGS= $(CXXFLAGS) -I$(srcdir)/stl +LIBSTLSO_LIBS= @LIBXSO_LIBS@ @LIBSO_LIBS@ + +libstl_base= libdb_stl +libstl= $(libstl_base).a +libstl_version= $(libstl_base)-$(LIBVERSION).a +libstlso= $(libstl_base)-$(LIBVERSION)@SOSUFFIX@ +libstlso_target=$(libstl_base)-$(LIBVERSION).la +libstlso_default=$(libstl_base)@SOSUFFIX@ +libstlso_major= $(libstl_base)-$(LIBMAJOR)@SOSUFFIX@ + +################################################## +# Java API. +# +# Java support is optional and requires shared librarires. +################################################## +CLASSPATH= $(JAVA_CLASSTOP) +LIBJSO_LIBS= @LIBJSO_LIBS@ @LIBSO_LIBS@ +SWIGCFLAGS= @SWIGCFLAGS@ + +JAR= @JAR@ +JAVA= env CLASSPATH="$(CLASSPATH)" @JAVA@ +JAVAC= env CLASSPATH="$(CLASSPATH)" @JAVAC@ +JAVACFLAGS= @JAVACFLAGS@ +JAVA_CLASSTOP= ./classes +JAVA_EXCLASSTOP=./classes.ex +JAVA_SRCDIR= $(srcdir)/java/src +JAVA_EXDIR= $(srcdir)/examples_java/src +JAVA_SLEEPYCAT= $(srcdir)/java/src/com/sleepycat +JAVA_MANIFEST= $(srcdir)/java/jarManifestEntries + +libj_jarfile= db.jar +libj_exjarfile= dbexamples.jar +libjso_base= libdb_java +libjso= $(libjso_base)-$(LIBVERSION)@JMODSUFFIX@ +libjso_static= $(libjso_base)-$(LIBVERSION).a +libjso_target= $(libjso_base)-$(LIBVERSION).la +libjso_default= $(libjso_base)@JMODSUFFIX@ +libjso_major= $(libjso_base)-$(LIBMAJOR)@JMODSUFFIX@ +libjso_g= $(libjso_base)-$(LIBVERSION)_g@JMODSUFFIX@ + +################################################## +# TCL API. +# +# Tcl support is optional and requires shared libraries. +################################################## +TCL_INCLUDE_SPEC= @TCL_INCLUDE_SPEC@ +LIBTSO_LIBS= @LIBTSO_LIBS@ @LIBSO_LIBS@ +libtso_base= libdb_tcl +libtso= $(libtso_base)-$(LIBVERSION)@LIBTSO_MODSUFFIX@ +libtso_static= $(libtso_base)-$(LIBVERSION).a +libtso_target= $(libtso_base)-$(LIBVERSION).la +libtso_default= $(libtso_base)@LIBTSO_MODSUFFIX@ +libtso_major= $(libtso_base)-$(LIBMAJOR)@LIBTSO_MODSUFFIX@ + +################################################## +# db_dump185 UTILITY +# +# The db_dump185 application should be compiled using the system's db.h file +# (which should be a DB 1.85/1.86 include file), and the system's 1.85/1.86 +# object library. To include the right db.h, don't include -I$(builddir) on +# the compile line. You may also need to add a local include directory and +# local libraries, for example. Do that by adding -I options to the DB185INC +# line, and -l options to the DB185LIB line. +################################################## +DB185INC= -c @CFLAGS@ -I$(srcdir) @CPPFLAGS@ +DB185LIB= + +################################################## +# NOTHING BELOW THIS LINE SHOULD EVER NEED TO BE MODIFIED. +################################################## + +################################################## +# Object and utility lists. +################################################## +BTREE_OBJS=\ + bt_compare@o@ bt_compress@o@ bt_conv@o@ bt_curadj@o@ bt_cursor@o@ \ + bt_delete@o@ bt_method@o@ bt_open@o@ bt_put@o@ bt_rec@o@ \ + bt_reclaim@o@ bt_recno@o@ bt_rsearch@o@ bt_search@o@ bt_split@o@ bt_stat@o@ \ + bt_compact@o@ bt_upgrade@o@ btree_auto@o@ +BTREE_VRFY_OBJS=\ + db_ovfl_vrfy@o@ db_vrfy@o@ db_vrfyutil@o@ bt_verify@o@ +HASH_OBJS=\ + hash@o@ hash_auto@o@ hash_conv@o@ hash_dup@o@ hash_meta@o@ \ + hash_method@o@ hash_open@o@ hash_page@o@ hash_rec@o@ \ + hash_reclaim@o@ hash_stat@o@ hash_upgrade@o@ +HASH_VRFY_OBJS=\ + hash_verify@o@ +QUEUE_OBJS=\ + qam@o@ qam_auto@o@ qam_conv@o@ qam_files@o@ qam_method@o@ \ + qam_open@o@ qam_rec@o@ qam_stat@o@ qam_upgrade@o@ +QUEUE_VRFY_OBJS=\ + qam_verify@o@ +LOCK_OBJS=\ + lock@o@ lock_deadlock@o@ lock_failchk@o@ lock_id@o@ lock_list@o@ \ + lock_method@o@ lock_region@o@ lock_stat@o@ lock_timer@o@ lock_util@o@ +MUTEX_OBJS=\ + mut_alloc@o@ mut_failchk@o@ mut_method@o@ mut_region@o@ mut_stat@o@ +REP_OBJS=\ + rep_auto@o@ rep_backup@o@ rep_elect@o@ rep_lease@o@ rep_log@o@ \ + rep_method@o@ rep_record@o@ rep_region@o@ rep_stat@o@ \ + rep_util@o@ rep_verify@o@ +REPMGR_OBJS=\ + os_addrinfo@o@\ + repmgr_auto@o@ repmgr_elect@o@ repmgr_method@o@ repmgr_msg@o@ \ + repmgr_net@o@ repmgr_posix@o@ repmgr_queue@o@ repmgr_sel@o@ \ + repmgr_stat@o@ repmgr_util@o@ +PRINT_OBJS=\ + btree_autop@o@ crdel_autop@o@ db_autop@o@ dbreg_autop@o@ \ + fileops_autop@o@ hash_autop@o@ qam_autop@o@ txn_autop@o@ + +C_OBJS= @ADDITIONAL_OBJS@ @REPLACEMENT_OBJS@ @CRYPTO_OBJS@ @RPC_CLIENT_OBJS@ \ + crdel_auto@o@ crdel_rec@o@ db@o@ db_am@o@ db_auto@o@ \ + db_byteorder@o@ db_cam@o@ db_cds@o@ db_compint@o@ db_conv@o@ db_dispatch@o@ \ + db_dup@o@ db_err@o@ db_getlong@o@ db_idspace@o@ db_iface@o@ \ + db_join@o@ db_log2@o@ db_meta@o@ db_method@o@ db_open@o@ \ + db_overflow@o@ db_pr@o@ db_rec@o@ db_reclaim@o@ db_remove@o@ \ + db_rename@o@ db_ret@o@ db_setid@o@ db_setlsn@o@ db_shash@o@ \ + db_sort_multiple@o@ db_stati@o@ db_truncate@o@ db_upg@o@ \ + db_upg_opd@o@ dbm@o@ dbreg@o@ dbreg_auto@o@ dbreg_rec@o@ dbreg_stat@o@ \ + dbreg_util@o@ dbt@o@ env_alloc@o@ env_config@o@ env_failchk@o@ \ + env_file@o@ env_globals@o@ env_method@o@ env_name@o@ env_open@o@ \ + env_recover@o@ env_region@o@ env_register@o@ env_sig@o@ \ + env_stat@o@ fileops_auto@o@ fop_basic@o@ fop_rec@o@ fop_util@o@ \ + hash_func@o@ hmac@o@ hsearch@o@ log@o@ log_archive@o@ \ + log_compare@o@ log_debug@o@ log_get@o@ log_method@o@ log_put@o@ \ + log_stat@o@ mkpath@o@ mp_alloc@o@ mp_bh@o@ mp_fget@o@ \ + mp_fmethod@o@ mp_fopen@o@ mp_fput@o@ mp_fset@o@ mp_method@o@ \ + mp_mvcc@o@ mp_region@o@ mp_register@o@ mp_resize@o@ mp_stat@o@ \ + mp_sync@o@ mp_trickle@o@ openflags@o@ os_abort@o@ os_abs@o@ \ + os_alloc@o@ os_clock@o@ os_cpu@o@ os_ctime@o@ os_config@o@ \ + os_dir@o@ os_errno@o@ os_fid@o@ os_flock@o@ os_fsync@o@ \ + os_getenv@o@ os_handle@o@ os_map@o@ os_method@o@ os_mkdir@o@ \ + os_open@o@ os_pid@o@ os_rename@o@ os_root@o@ os_rpath@o@ \ + os_rw@o@ os_seek@o@ os_stack@o@ os_stat@o@ os_tmpdir@o@ \ + os_truncate@o@ os_uid@o@ os_unlink@o@ os_yield@o@ partition@o@ \ + seq_stat@o@ sequence@o@ sha1@o@ snprintf@o@ txn@o@ txn_auto@o@ \ + txn_chkpt@o@ txn_failchk@o@ txn_method@o@ txn_rec@o@ txn_recover@o@ \ + txn_region@o@ txn_stat@o@ txn_util@o@ zerofill@o@ + +CXX_OBJS=\ + cxx_db@o@ cxx_dbc@o@ cxx_dbt@o@ cxx_env@o@ cxx_except@o@ cxx_lock@o@ \ + cxx_logc@o@ cxx_mpool@o@ cxx_multi@o@ cxx_seq@o@ cxx_txn@o@ + +CRYPTO_OBJS=\ + aes_method@o@ crypto@o@ mt19937db@o@ rijndael-alg-fst@o@ \ + rijndael-api-fst@o@ + +JAVA_OBJS=\ + db_java_wrap@o@ + +JAVA_DBSRCS=\ + $(JAVA_SLEEPYCAT)/asm/AnnotationVisitor.java \ + $(JAVA_SLEEPYCAT)/asm/AnnotationWriter.java \ + $(JAVA_SLEEPYCAT)/asm/Attribute.java \ + $(JAVA_SLEEPYCAT)/asm/ByteVector.java \ + $(JAVA_SLEEPYCAT)/asm/ClassAdapter.java \ + $(JAVA_SLEEPYCAT)/asm/ClassReader.java \ + $(JAVA_SLEEPYCAT)/asm/ClassVisitor.java \ + $(JAVA_SLEEPYCAT)/asm/ClassWriter.java \ + $(JAVA_SLEEPYCAT)/asm/Edge.java \ + $(JAVA_SLEEPYCAT)/asm/FieldVisitor.java \ + $(JAVA_SLEEPYCAT)/asm/FieldWriter.java \ + $(JAVA_SLEEPYCAT)/asm/Handler.java \ + $(JAVA_SLEEPYCAT)/asm/Item.java \ + $(JAVA_SLEEPYCAT)/asm/Label.java \ + $(JAVA_SLEEPYCAT)/asm/MethodVisitor.java \ + $(JAVA_SLEEPYCAT)/asm/MethodWriter.java \ + $(JAVA_SLEEPYCAT)/asm/Opcodes.java \ + $(JAVA_SLEEPYCAT)/asm/Type.java \ + $(JAVA_SLEEPYCAT)/bind/ByteArrayBinding.java \ + $(JAVA_SLEEPYCAT)/bind/EntityBinding.java \ + $(JAVA_SLEEPYCAT)/bind/EntryBinding.java \ + $(JAVA_SLEEPYCAT)/bind/RecordNumberBinding.java \ + $(JAVA_SLEEPYCAT)/bind/serial/ClassCatalog.java \ + $(JAVA_SLEEPYCAT)/bind/serial/SerialBase.java \ + $(JAVA_SLEEPYCAT)/bind/serial/SerialBinding.java \ + $(JAVA_SLEEPYCAT)/bind/serial/SerialInput.java \ + $(JAVA_SLEEPYCAT)/bind/serial/SerialOutput.java \ + $(JAVA_SLEEPYCAT)/bind/serial/SerialSerialBinding.java \ + $(JAVA_SLEEPYCAT)/bind/serial/SerialSerialKeyCreator.java \ + $(JAVA_SLEEPYCAT)/bind/serial/StoredClassCatalog.java \ + $(JAVA_SLEEPYCAT)/bind/serial/TupleSerialBinding.java \ + $(JAVA_SLEEPYCAT)/bind/serial/TupleSerialKeyCreator.java \ + $(JAVA_SLEEPYCAT)/bind/serial/TupleSerialMarshalledBinding.java \ + $(JAVA_SLEEPYCAT)/bind/serial/TupleSerialMarshalledKeyCreator.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/BigIntegerBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/BooleanBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/ByteBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/CharacterBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/DoubleBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/FloatBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/IntegerBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/LongBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/MarshalledTupleEntry.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/MarshalledTupleKeyEntity.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/ShortBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/SortedDoubleBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/SortedFloatBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/StringBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/TupleBase.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/TupleBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/TupleInput.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/TupleInputBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/TupleMarshalledBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/TupleOutput.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/TupleTupleBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/TupleTupleKeyCreator.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/TupleTupleMarshalledBinding.java \ + $(JAVA_SLEEPYCAT)/bind/tuple/TupleTupleMarshalledKeyCreator.java \ + $(JAVA_SLEEPYCAT)/collections/BaseIterator.java \ + $(JAVA_SLEEPYCAT)/collections/BlockIterator.java \ + $(JAVA_SLEEPYCAT)/collections/CurrentTransaction.java \ + $(JAVA_SLEEPYCAT)/collections/DataCursor.java \ + $(JAVA_SLEEPYCAT)/collections/DataView.java \ + $(JAVA_SLEEPYCAT)/collections/MapEntryParameter.java \ + $(JAVA_SLEEPYCAT)/collections/MyRangeCursor.java \ + $(JAVA_SLEEPYCAT)/collections/PrimaryKeyAssigner.java \ + $(JAVA_SLEEPYCAT)/collections/StoredCollection.java \ + $(JAVA_SLEEPYCAT)/collections/StoredCollections.java \ + $(JAVA_SLEEPYCAT)/collections/StoredContainer.java \ + $(JAVA_SLEEPYCAT)/collections/StoredEntrySet.java \ + $(JAVA_SLEEPYCAT)/collections/StoredIterator.java \ + $(JAVA_SLEEPYCAT)/collections/StoredKeySet.java \ + $(JAVA_SLEEPYCAT)/collections/StoredList.java \ + $(JAVA_SLEEPYCAT)/collections/StoredMap.java \ + $(JAVA_SLEEPYCAT)/collections/StoredMapEntry.java \ + $(JAVA_SLEEPYCAT)/collections/StoredSortedEntrySet.java \ + $(JAVA_SLEEPYCAT)/collections/StoredSortedKeySet.java \ + $(JAVA_SLEEPYCAT)/collections/StoredSortedMap.java \ + $(JAVA_SLEEPYCAT)/collections/StoredSortedValueSet.java \ + $(JAVA_SLEEPYCAT)/collections/StoredValueSet.java \ + $(JAVA_SLEEPYCAT)/collections/TransactionRunner.java \ + $(JAVA_SLEEPYCAT)/collections/TransactionWorker.java \ + $(JAVA_SLEEPYCAT)/collections/TupleSerialFactory.java \ + $(JAVA_SLEEPYCAT)/compat/DbCompat.java \ + $(JAVA_SLEEPYCAT)/db/BtreeCompressor.java \ + $(JAVA_SLEEPYCAT)/db/BtreePrefixCalculator.java \ + $(JAVA_SLEEPYCAT)/db/BtreeStats.java \ + $(JAVA_SLEEPYCAT)/db/CacheFile.java \ + $(JAVA_SLEEPYCAT)/db/CacheFilePriority.java \ + $(JAVA_SLEEPYCAT)/db/CacheFileStats.java \ + $(JAVA_SLEEPYCAT)/db/CacheStats.java \ + $(JAVA_SLEEPYCAT)/db/CheckpointConfig.java \ + $(JAVA_SLEEPYCAT)/db/CompactConfig.java \ + $(JAVA_SLEEPYCAT)/db/CompactStats.java \ + $(JAVA_SLEEPYCAT)/db/Cursor.java \ + $(JAVA_SLEEPYCAT)/db/CursorConfig.java \ + $(JAVA_SLEEPYCAT)/db/Database.java \ + $(JAVA_SLEEPYCAT)/db/DatabaseConfig.java \ + $(JAVA_SLEEPYCAT)/db/DatabaseEntry.java \ + $(JAVA_SLEEPYCAT)/db/DatabaseException.java \ + $(JAVA_SLEEPYCAT)/db/DatabaseStats.java \ + $(JAVA_SLEEPYCAT)/db/DatabaseType.java \ + $(JAVA_SLEEPYCAT)/db/DeadlockException.java \ + $(JAVA_SLEEPYCAT)/db/Environment.java \ + $(JAVA_SLEEPYCAT)/db/EnvironmentConfig.java \ + $(JAVA_SLEEPYCAT)/db/ErrorHandler.java \ + $(JAVA_SLEEPYCAT)/db/EventHandler.java \ + $(JAVA_SLEEPYCAT)/db/EventHandlerAdapter.java \ + $(JAVA_SLEEPYCAT)/db/FeedbackHandler.java \ + $(JAVA_SLEEPYCAT)/db/ForeignKeyDeleteAction.java \ + $(JAVA_SLEEPYCAT)/db/ForeignKeyNullifier.java \ + $(JAVA_SLEEPYCAT)/db/ForeignMultiKeyNullifier.java \ + $(JAVA_SLEEPYCAT)/db/HashStats.java \ + $(JAVA_SLEEPYCAT)/db/Hasher.java \ + $(JAVA_SLEEPYCAT)/db/JoinConfig.java \ + $(JAVA_SLEEPYCAT)/db/JoinCursor.java \ + $(JAVA_SLEEPYCAT)/db/KeyRange.java \ + $(JAVA_SLEEPYCAT)/db/Lock.java \ + $(JAVA_SLEEPYCAT)/db/LockDetectMode.java \ + $(JAVA_SLEEPYCAT)/db/LockMode.java \ + $(JAVA_SLEEPYCAT)/db/LockNotGrantedException.java \ + $(JAVA_SLEEPYCAT)/db/LockOperation.java \ + $(JAVA_SLEEPYCAT)/db/LockRequest.java \ + $(JAVA_SLEEPYCAT)/db/LockRequestMode.java \ + $(JAVA_SLEEPYCAT)/db/LockStats.java \ + $(JAVA_SLEEPYCAT)/db/LogCursor.java \ + $(JAVA_SLEEPYCAT)/db/LogRecordHandler.java \ + $(JAVA_SLEEPYCAT)/db/LogSequenceNumber.java \ + $(JAVA_SLEEPYCAT)/db/LogStats.java \ + $(JAVA_SLEEPYCAT)/db/MemoryException.java \ + $(JAVA_SLEEPYCAT)/db/MessageHandler.java \ + $(JAVA_SLEEPYCAT)/db/MultipleNIODataEntry.java \ + $(JAVA_SLEEPYCAT)/db/MultipleKeyNIODataEntry.java \ + $(JAVA_SLEEPYCAT)/db/MultipleRecnoNIODataEntry.java \ + $(JAVA_SLEEPYCAT)/db/MultipleDataEntry.java \ + $(JAVA_SLEEPYCAT)/db/MultipleEntry.java \ + $(JAVA_SLEEPYCAT)/db/MultipleKeyDataEntry.java \ + $(JAVA_SLEEPYCAT)/db/MultipleRecnoDataEntry.java \ + $(JAVA_SLEEPYCAT)/db/MutexStats.java \ + $(JAVA_SLEEPYCAT)/db/OperationStatus.java \ + $(JAVA_SLEEPYCAT)/db/PanicHandler.java \ + $(JAVA_SLEEPYCAT)/db/PartitionHandler.java \ + $(JAVA_SLEEPYCAT)/db/PreparedTransaction.java \ + $(JAVA_SLEEPYCAT)/db/QueueStats.java \ + $(JAVA_SLEEPYCAT)/db/RecordNumberAppender.java \ + $(JAVA_SLEEPYCAT)/db/RecoveryOperation.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationConfig.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationDuplicateMasterException.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationHandleDeadException.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationHoldElectionException.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationHostAddress.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationJoinFailureException.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationLeaseExpiredException.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationLeaseTimeoutException.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationLockoutException.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationManagerAckPolicy.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationManagerSiteInfo.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationManagerStats.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationManagerStartPolicy.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationSiteUnavailableException.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationStats.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationStatus.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationTimeoutType.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationTransport.java \ + $(JAVA_SLEEPYCAT)/db/RunRecoveryException.java \ + $(JAVA_SLEEPYCAT)/db/SecondaryConfig.java \ + $(JAVA_SLEEPYCAT)/db/SecondaryCursor.java \ + $(JAVA_SLEEPYCAT)/db/SecondaryDatabase.java \ + $(JAVA_SLEEPYCAT)/db/SecondaryKeyCreator.java \ + $(JAVA_SLEEPYCAT)/db/SecondaryMultiKeyCreator.java \ + $(JAVA_SLEEPYCAT)/db/Sequence.java \ + $(JAVA_SLEEPYCAT)/db/SequenceConfig.java \ + $(JAVA_SLEEPYCAT)/db/SequenceStats.java \ + $(JAVA_SLEEPYCAT)/db/StatsConfig.java \ + $(JAVA_SLEEPYCAT)/db/Transaction.java \ + $(JAVA_SLEEPYCAT)/db/TransactionConfig.java \ + $(JAVA_SLEEPYCAT)/db/TransactionStats.java \ + $(JAVA_SLEEPYCAT)/db/VerboseConfig.java \ + $(JAVA_SLEEPYCAT)/db/VerifyConfig.java \ + $(JAVA_SLEEPYCAT)/db/VersionMismatchException.java \ + $(JAVA_SLEEPYCAT)/db/internal/Db.java \ + $(JAVA_SLEEPYCAT)/db/internal/DbConstants.java \ + $(JAVA_SLEEPYCAT)/db/internal/DbEnv.java \ + $(JAVA_SLEEPYCAT)/db/internal/DbLock.java \ + $(JAVA_SLEEPYCAT)/db/internal/DbLogc.java \ + $(JAVA_SLEEPYCAT)/db/internal/DbMpoolFile.java \ + $(JAVA_SLEEPYCAT)/db/internal/DbSequence.java \ + $(JAVA_SLEEPYCAT)/db/internal/DbTxn.java \ + $(JAVA_SLEEPYCAT)/db/internal/DbUtil.java \ + $(JAVA_SLEEPYCAT)/db/internal/Dbc.java \ + $(JAVA_SLEEPYCAT)/db/internal/db_java.java \ + $(JAVA_SLEEPYCAT)/db/internal/db_javaJNI.java \ + $(JAVA_SLEEPYCAT)/persist/BasicCursor.java \ + $(JAVA_SLEEPYCAT)/persist/BasicIndex.java \ + $(JAVA_SLEEPYCAT)/persist/BasicIterator.java \ + $(JAVA_SLEEPYCAT)/persist/DataValueAdapter.java \ + $(JAVA_SLEEPYCAT)/persist/DatabaseNamer.java \ + $(JAVA_SLEEPYCAT)/persist/EntityCursor.java \ + $(JAVA_SLEEPYCAT)/persist/EntityIndex.java \ + $(JAVA_SLEEPYCAT)/persist/EntityJoin.java \ + $(JAVA_SLEEPYCAT)/persist/EntityStore.java \ + $(JAVA_SLEEPYCAT)/persist/EntityValueAdapter.java \ + $(JAVA_SLEEPYCAT)/persist/ForwardCursor.java \ + $(JAVA_SLEEPYCAT)/persist/KeySelector.java \ + $(JAVA_SLEEPYCAT)/persist/KeyValueAdapter.java \ + $(JAVA_SLEEPYCAT)/persist/KeysIndex.java \ + $(JAVA_SLEEPYCAT)/persist/PrimaryIndex.java \ + $(JAVA_SLEEPYCAT)/persist/PrimaryKeyValueAdapter.java \ + $(JAVA_SLEEPYCAT)/persist/SecondaryIndex.java \ + $(JAVA_SLEEPYCAT)/persist/StoreConfig.java \ + $(JAVA_SLEEPYCAT)/persist/StoreExistsException.java \ + $(JAVA_SLEEPYCAT)/persist/StoreNotFoundException.java \ + $(JAVA_SLEEPYCAT)/persist/SubIndex.java \ + $(JAVA_SLEEPYCAT)/persist/SubIndexCursor.java \ + $(JAVA_SLEEPYCAT)/persist/ValueAdapter.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/Conversion.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/Converter.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/DeletedClassException.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/Deleter.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/EntityConverter.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/EvolveConfig.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/EvolveEvent.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/EvolveInternal.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/EvolveListener.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/EvolveStats.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/IncompatibleClassException.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/Mutation.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/Mutations.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/Renamer.java \ + $(JAVA_SLEEPYCAT)/persist/impl/AbstractInput.java \ + $(JAVA_SLEEPYCAT)/persist/impl/Accessor.java \ + $(JAVA_SLEEPYCAT)/persist/impl/Catalog.java \ + $(JAVA_SLEEPYCAT)/persist/impl/CollectionProxy.java \ + $(JAVA_SLEEPYCAT)/persist/impl/ComplexFormat.java \ + $(JAVA_SLEEPYCAT)/persist/impl/ComparatorCatalog.java \ + $(JAVA_SLEEPYCAT)/persist/impl/CompositeKeyFormat.java \ + $(JAVA_SLEEPYCAT)/persist/impl/ConverterReader.java \ + $(JAVA_SLEEPYCAT)/persist/impl/Enhanced.java \ + $(JAVA_SLEEPYCAT)/persist/impl/EnhancedAccessor.java \ + $(JAVA_SLEEPYCAT)/persist/impl/EntityInput.java \ + $(JAVA_SLEEPYCAT)/persist/impl/EntityOutput.java \ + $(JAVA_SLEEPYCAT)/persist/impl/EnumFormat.java \ + $(JAVA_SLEEPYCAT)/persist/impl/Evolver.java \ + $(JAVA_SLEEPYCAT)/persist/impl/FieldInfo.java \ + $(JAVA_SLEEPYCAT)/persist/impl/Format.java \ + $(JAVA_SLEEPYCAT)/persist/impl/KeyLocation.java \ + $(JAVA_SLEEPYCAT)/persist/impl/MapProxy.java \ + $(JAVA_SLEEPYCAT)/persist/impl/NonPersistentFormat.java \ + $(JAVA_SLEEPYCAT)/persist/impl/ObjectArrayFormat.java \ + $(JAVA_SLEEPYCAT)/persist/impl/PersistCatalog.java \ + $(JAVA_SLEEPYCAT)/persist/impl/PersistComparator.java \ + $(JAVA_SLEEPYCAT)/persist/impl/PersistEntityBinding.java \ + $(JAVA_SLEEPYCAT)/persist/impl/PersistKeyAssigner.java \ + $(JAVA_SLEEPYCAT)/persist/impl/PersistKeyBinding.java \ + $(JAVA_SLEEPYCAT)/persist/impl/PersistKeyCreator.java \ + $(JAVA_SLEEPYCAT)/persist/impl/PrimitiveArrayFormat.java \ + $(JAVA_SLEEPYCAT)/persist/impl/ProxiedFormat.java \ + $(JAVA_SLEEPYCAT)/persist/impl/RawAbstractInput.java \ + $(JAVA_SLEEPYCAT)/persist/impl/RawAccessor.java \ + $(JAVA_SLEEPYCAT)/persist/impl/RawArrayInput.java \ + $(JAVA_SLEEPYCAT)/persist/impl/RawComplexInput.java \ + $(JAVA_SLEEPYCAT)/persist/impl/RawSingleInput.java \ + $(JAVA_SLEEPYCAT)/persist/impl/ReadOnlyCatalog.java \ + $(JAVA_SLEEPYCAT)/persist/impl/Reader.java \ + $(JAVA_SLEEPYCAT)/persist/impl/RecordInput.java \ + $(JAVA_SLEEPYCAT)/persist/impl/RecordOutput.java \ + $(JAVA_SLEEPYCAT)/persist/impl/ReflectionAccessor.java \ + $(JAVA_SLEEPYCAT)/persist/impl/SimpleCatalog.java \ + $(JAVA_SLEEPYCAT)/persist/impl/SimpleFormat.java \ + $(JAVA_SLEEPYCAT)/persist/impl/Store.java \ + $(JAVA_SLEEPYCAT)/persist/impl/StoredModel.java \ + $(JAVA_SLEEPYCAT)/persist/impl/VisitedObjects.java \ + $(JAVA_SLEEPYCAT)/persist/impl/WidenerInput.java \ + $(JAVA_SLEEPYCAT)/persist/model/AnnotationModel.java \ + $(JAVA_SLEEPYCAT)/persist/model/BytecodeEnhancer.java \ + $(JAVA_SLEEPYCAT)/persist/model/ClassEnhancer.java \ + $(JAVA_SLEEPYCAT)/persist/model/ClassMetadata.java \ + $(JAVA_SLEEPYCAT)/persist/model/DeleteAction.java \ + $(JAVA_SLEEPYCAT)/persist/model/Entity.java \ + $(JAVA_SLEEPYCAT)/persist/model/EntityMetadata.java \ + $(JAVA_SLEEPYCAT)/persist/model/EntityModel.java \ + $(JAVA_SLEEPYCAT)/persist/model/FieldMetadata.java \ + $(JAVA_SLEEPYCAT)/persist/model/KeyField.java \ + $(JAVA_SLEEPYCAT)/persist/model/ModelInternal.java \ + $(JAVA_SLEEPYCAT)/persist/model/NotPersistent.java \ + $(JAVA_SLEEPYCAT)/persist/model/NotTransient.java \ + $(JAVA_SLEEPYCAT)/persist/model/Persistent.java \ + $(JAVA_SLEEPYCAT)/persist/model/PersistentProxy.java \ + $(JAVA_SLEEPYCAT)/persist/model/PrimaryKey.java \ + $(JAVA_SLEEPYCAT)/persist/model/PrimaryKeyMetadata.java \ + $(JAVA_SLEEPYCAT)/persist/model/Relationship.java \ + $(JAVA_SLEEPYCAT)/persist/model/SecondaryKey.java \ + $(JAVA_SLEEPYCAT)/persist/model/SecondaryKeyMetadata.java \ + $(JAVA_SLEEPYCAT)/persist/raw/RawField.java \ + $(JAVA_SLEEPYCAT)/persist/raw/RawObject.java \ + $(JAVA_SLEEPYCAT)/persist/raw/RawStore.java \ + $(JAVA_SLEEPYCAT)/persist/raw/RawType.java \ + $(JAVA_SLEEPYCAT)/util/ErrorBuffer.java \ + $(JAVA_SLEEPYCAT)/util/ExceptionUnwrapper.java \ + $(JAVA_SLEEPYCAT)/util/ExceptionWrapper.java \ + $(JAVA_SLEEPYCAT)/util/FastInputStream.java \ + $(JAVA_SLEEPYCAT)/util/FastOutputStream.java \ + $(JAVA_SLEEPYCAT)/util/IOExceptionWrapper.java \ + $(JAVA_SLEEPYCAT)/util/PackedInteger.java \ + $(JAVA_SLEEPYCAT)/util/RuntimeExceptionWrapper.java \ + $(JAVA_SLEEPYCAT)/util/UtfOps.java \ + $(JAVA_SLEEPYCAT)/util/keyrange/KeyRange.java \ + $(JAVA_SLEEPYCAT)/util/keyrange/KeyRangeException.java \ + $(JAVA_SLEEPYCAT)/util/keyrange/RangeCursor.java + +JAVA_EXSRCS=\ + $(JAVA_EXDIR)/collections/access/AccessExample.java \ + $(JAVA_EXDIR)/collections/hello/HelloDatabaseWorld.java \ + $(JAVA_EXDIR)/collections/ship/basic/PartData.java \ + $(JAVA_EXDIR)/collections/ship/basic/PartKey.java \ + $(JAVA_EXDIR)/collections/ship/basic/Sample.java \ + $(JAVA_EXDIR)/collections/ship/basic/SampleDatabase.java \ + $(JAVA_EXDIR)/collections/ship/basic/SampleViews.java \ + $(JAVA_EXDIR)/collections/ship/basic/ShipmentData.java \ + $(JAVA_EXDIR)/collections/ship/basic/ShipmentKey.java \ + $(JAVA_EXDIR)/collections/ship/basic/SupplierData.java \ + $(JAVA_EXDIR)/collections/ship/basic/SupplierKey.java \ + $(JAVA_EXDIR)/collections/ship/basic/Weight.java \ + $(JAVA_EXDIR)/collections/ship/entity/Part.java \ + $(JAVA_EXDIR)/collections/ship/entity/PartData.java \ + $(JAVA_EXDIR)/collections/ship/entity/PartKey.java \ + $(JAVA_EXDIR)/collections/ship/entity/Sample.java \ + $(JAVA_EXDIR)/collections/ship/entity/SampleDatabase.java \ + $(JAVA_EXDIR)/collections/ship/entity/SampleViews.java \ + $(JAVA_EXDIR)/collections/ship/entity/Shipment.java \ + $(JAVA_EXDIR)/collections/ship/entity/ShipmentData.java \ + $(JAVA_EXDIR)/collections/ship/entity/ShipmentKey.java \ + $(JAVA_EXDIR)/collections/ship/entity/Supplier.java \ + $(JAVA_EXDIR)/collections/ship/entity/SupplierData.java \ + $(JAVA_EXDIR)/collections/ship/entity/SupplierKey.java \ + $(JAVA_EXDIR)/collections/ship/entity/Weight.java \ + $(JAVA_EXDIR)/collections/ship/factory/Part.java \ + $(JAVA_EXDIR)/collections/ship/factory/PartKey.java \ + $(JAVA_EXDIR)/collections/ship/factory/Sample.java \ + $(JAVA_EXDIR)/collections/ship/factory/SampleDatabase.java \ + $(JAVA_EXDIR)/collections/ship/factory/SampleViews.java \ + $(JAVA_EXDIR)/collections/ship/factory/Shipment.java \ + $(JAVA_EXDIR)/collections/ship/factory/ShipmentKey.java \ + $(JAVA_EXDIR)/collections/ship/factory/Supplier.java \ + $(JAVA_EXDIR)/collections/ship/factory/SupplierKey.java \ + $(JAVA_EXDIR)/collections/ship/factory/Weight.java \ + $(JAVA_EXDIR)/collections/ship/index/PartData.java \ + $(JAVA_EXDIR)/collections/ship/index/PartKey.java \ + $(JAVA_EXDIR)/collections/ship/index/Sample.java \ + $(JAVA_EXDIR)/collections/ship/index/SampleDatabase.java \ + $(JAVA_EXDIR)/collections/ship/index/SampleViews.java \ + $(JAVA_EXDIR)/collections/ship/index/ShipmentData.java \ + $(JAVA_EXDIR)/collections/ship/index/ShipmentKey.java \ + $(JAVA_EXDIR)/collections/ship/index/SupplierData.java \ + $(JAVA_EXDIR)/collections/ship/index/SupplierKey.java \ + $(JAVA_EXDIR)/collections/ship/index/Weight.java \ + $(JAVA_EXDIR)/collections/ship/marshal/MarshalledEnt.java \ + $(JAVA_EXDIR)/collections/ship/marshal/MarshalledKey.java \ + $(JAVA_EXDIR)/collections/ship/marshal/Part.java \ + $(JAVA_EXDIR)/collections/ship/marshal/PartKey.java \ + $(JAVA_EXDIR)/collections/ship/marshal/Sample.java \ + $(JAVA_EXDIR)/collections/ship/marshal/SampleDatabase.java \ + $(JAVA_EXDIR)/collections/ship/marshal/SampleViews.java \ + $(JAVA_EXDIR)/collections/ship/marshal/Shipment.java \ + $(JAVA_EXDIR)/collections/ship/marshal/ShipmentKey.java \ + $(JAVA_EXDIR)/collections/ship/marshal/Supplier.java \ + $(JAVA_EXDIR)/collections/ship/marshal/SupplierKey.java \ + $(JAVA_EXDIR)/collections/ship/marshal/Weight.java \ + $(JAVA_EXDIR)/collections/ship/sentity/Part.java \ + $(JAVA_EXDIR)/collections/ship/sentity/PartKey.java \ + $(JAVA_EXDIR)/collections/ship/sentity/Sample.java \ + $(JAVA_EXDIR)/collections/ship/sentity/SampleDatabase.java \ + $(JAVA_EXDIR)/collections/ship/sentity/SampleViews.java \ + $(JAVA_EXDIR)/collections/ship/sentity/Shipment.java \ + $(JAVA_EXDIR)/collections/ship/sentity/ShipmentKey.java \ + $(JAVA_EXDIR)/collections/ship/sentity/Supplier.java \ + $(JAVA_EXDIR)/collections/ship/sentity/SupplierKey.java \ + $(JAVA_EXDIR)/collections/ship/sentity/Weight.java \ + $(JAVA_EXDIR)/collections/ship/tuple/Part.java \ + $(JAVA_EXDIR)/collections/ship/tuple/PartData.java \ + $(JAVA_EXDIR)/collections/ship/tuple/PartKey.java \ + $(JAVA_EXDIR)/collections/ship/tuple/Sample.java \ + $(JAVA_EXDIR)/collections/ship/tuple/SampleDatabase.java \ + $(JAVA_EXDIR)/collections/ship/tuple/SampleViews.java \ + $(JAVA_EXDIR)/collections/ship/tuple/Shipment.java \ + $(JAVA_EXDIR)/collections/ship/tuple/ShipmentData.java \ + $(JAVA_EXDIR)/collections/ship/tuple/ShipmentKey.java \ + $(JAVA_EXDIR)/collections/ship/tuple/Supplier.java \ + $(JAVA_EXDIR)/collections/ship/tuple/SupplierData.java \ + $(JAVA_EXDIR)/collections/ship/tuple/SupplierKey.java \ + $(JAVA_EXDIR)/collections/ship/tuple/Weight.java \ + $(JAVA_EXDIR)/db/AccessExample.java \ + $(JAVA_EXDIR)/db/BtRecExample.java \ + $(JAVA_EXDIR)/db/BulkAccessExample.java \ + $(JAVA_EXDIR)/db/BulkAccessNIOExample.java \ + $(JAVA_EXDIR)/db/EnvExample.java \ + $(JAVA_EXDIR)/db/GettingStarted/ExampleDatabaseLoad.java \ + $(JAVA_EXDIR)/db/GettingStarted/ExampleDatabaseRead.java \ + $(JAVA_EXDIR)/db/GettingStarted/Inventory.java \ + $(JAVA_EXDIR)/db/GettingStarted/InventoryBinding.java \ + $(JAVA_EXDIR)/db/GettingStarted/ItemNameKeyCreator.java \ + $(JAVA_EXDIR)/db/GettingStarted/MyDbs.java \ + $(JAVA_EXDIR)/db/GettingStarted/Vendor.java \ + $(JAVA_EXDIR)/db/LockExample.java \ + $(JAVA_EXDIR)/db/SequenceExample.java \ + $(JAVA_EXDIR)/db/TpcbExample.java \ + $(JAVA_EXDIR)/db/repquote/RepConfig.java \ + $(JAVA_EXDIR)/db/repquote/RepQuoteEnvironment.java \ + $(JAVA_EXDIR)/db/repquote/RepQuoteExample.java \ + $(JAVA_EXDIR)/db/repquote/RepRemoteHost.java \ + $(JAVA_EXDIR)/db/repquote_gsg/RepConfig.java \ + $(JAVA_EXDIR)/db/repquote_gsg/RepQuoteEnvironment.java \ + $(JAVA_EXDIR)/db/repquote_gsg/RepQuoteExampleGSG.java \ + $(JAVA_EXDIR)/db/repquote_gsg/SimpleConfig.java \ + $(JAVA_EXDIR)/db/repquote_gsg/SimpleTxn.java \ + $(JAVA_EXDIR)/db/txn/DBWriter.java \ + $(JAVA_EXDIR)/db/txn/PayloadData.java \ + $(JAVA_EXDIR)/db/txn/TxnGuide.java \ + $(JAVA_EXDIR)/db/txn/TxnGuideInMemory.java \ + $(JAVA_EXDIR)/persist/CustomKeyOrderExample.java \ + $(JAVA_EXDIR)/persist/DplDump.java \ + $(JAVA_EXDIR)/persist/EventExample.java \ + $(JAVA_EXDIR)/persist/EventExampleDPL.java \ + $(JAVA_EXDIR)/persist/PersonExample.java \ + $(JAVA_EXDIR)/persist/gettingStarted/SimpleDA.java \ + $(JAVA_EXDIR)/persist/gettingStarted/SimpleEntityClass.java \ + $(JAVA_EXDIR)/persist/gettingStarted/SimpleStoreGet.java \ + $(JAVA_EXDIR)/persist/gettingStarted/SimpleStorePut.java \ + $(JAVA_EXDIR)/persist/txn/PayloadDataEntity.java \ + $(JAVA_EXDIR)/persist/txn/StoreWriter.java \ + $(JAVA_EXDIR)/persist/txn/TxnGuideDPL.java + +STL_OBJS=\ + dbstl_container@o@ dbstl_resource_manager@o@ + +TCL_OBJS=\ + tcl_compat@o@ tcl_db@o@ tcl_db_pkg@o@ tcl_dbcursor@o@ tcl_env@o@ \ + tcl_internal@o@ tcl_lock@o@ tcl_log@o@ tcl_mp@o@ tcl_mutex@o@ \ + tcl_rep@o@ tcl_seq@o@ tcl_txn@o@ tcl_util@o@ + +RPC_CLIENT_OBJS=\ + client@o@ db_server_clnt@o@ db_server_xdr@o@ gen_client@o@ \ + gen_client_ret@o@ + +RPC_SRV_OBJS=\ + db_server_proc@o@ db_server_svc@o@ db_server_util@o@ \ + gen_db_server@o@ + +RPC_CXXSRV_OBJS=\ + db_server_cxxproc@o@ db_server_cxxutil@o@ db_server_svc@o@ \ + gen_db_server@o@ + +TEST_MICRO_OBJS=\ + b_curalloc@o@ b_curwalk@o@ b_del@o@ b_get@o@ b_inmem@o@ b_latch@o@ \ + b_load@o@ b_open@o@ b_put@o@ b_recover@o@ b_txn@o@ b_txn_write@o@ \ + b_uname@o@ b_util@o@ b_workload@o@ test_micro@o@ util_arg@o@ + +UTIL_PROGS=\ + @ADDITIONAL_PROGS@ \ + db_archive db_checkpoint db_deadlock db_dump \ + db_hotbackup db_load db_printlog db_recover db_sql db_stat db_upgrade \ + db_verify + +################################################## +# List of files installed into the library directory. +################################################## +LIB_INSTALL_FILE_LIST=\ + $(libdb) \ + $(libso) \ + $(libso_default) \ + $(libso_major) \ + $(libdb_version) \ + $(libso_target) \ + $(libcxx) \ + $(libxso) \ + $(libxso_default) \ + $(libxso_major) \ + $(libcxx_version) \ + $(libxso_target) \ + $(libstl) \ + $(libstlso) \ + $(libstlso_default) \ + $(libstlso_major) \ + $(libstlxx_version) \ + $(libstlso_target) \ + $(libtso) \ + $(libtso_default) \ + $(libtso_major) \ + $(libtso_static) \ + $(libtso_target) \ + $(libjso) \ + $(libjso_default) \ + $(libjso_g) \ + $(libjso_major) \ + $(libjso_static) \ + $(libjso_target) \ + $(libj_exjarfile) \ + $(libj_jarfile) + +################################################## +# Note: "all" must be the first target in the Makefile. +################################################## +all: @BUILD_TARGET@ + +install: all @INSTALL_TARGET@ + +################################################## +# Library and standard utilities build. +################################################## +library_build: @INSTALL_LIBS@ @ADDITIONAL_LANG@ $(UTIL_PROGS) + +# Static C library named libdb.a. +$(libdb): $(DEF_LIB) + +# Real static C library. +$(libdb_version): $(C_OBJS) + $(AR) cr $@ $(C_OBJS) + $(RANLIB) $@ + $(RM) $(libdb) + $(LN) -s $(libdb_version) $(libdb) + +# Shared C library. +$(libso_target): $(C_OBJS) + $(SOLINK) $(SOFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) $(LIBCSO_LIBS) + $(RM) $(libdb) + $(LN) -s .libs/$(libdb_version) $(libdb) + +# Static C++ library named libdb_cxx.a. +$(libcxx): $(DEF_LIB_CXX) + +# Real static C++ library. +$(libcxx_version): $(CXX_OBJS) $(C_OBJS) + $(AR) cr $@ $(CXX_OBJS) $(C_OBJS) + $(RANLIB) $@ + $(RM) $(libcxx) + $(LN) -s $(libcxx_version) $(libcxx) + +# Shared C++ library. +$(libxso_target): $(CXX_OBJS) $(C_OBJS) + $(XSOLINK) $(SOFLAGS) $(LDFLAGS) \ + -o $@ $(CXX_OBJS) $(C_OBJS) $(LIBXSO_LIBS) + $(RM) $(libcxx) + $(LN) -s .libs/$(libcxx_version) $(libcxx) + +# Static STL library named libdb_stl.a. +$(libstl): $(DEF_LIB_STL) + +# Real static STL library. +$(libstl_version): $(STL_OBJS) $(CXX_OBJS) $(C_OBJS) + $(AR) cr $@ $(STL_OBJS) $(CXX_OBJS) $(C_OBJS) + $(RANLIB) $@ + $(RM) $(libstl) + $(LN) -s $(libstl_version) $(libstl) + +# Shared STL library. +$(libstlso_target): $(STL_OBJS) $(CXX_OBJS) $(C_OBJS) + $(XSOLINK) $(SOFLAGS) $(LDFLAGS) -o $@ \ + $(STL_OBJS) $(LIBSTLSO_LIBS) $(CXX_OBJS) $(C_OBJS) $(LIBXSO_LIBS) + $(RM) $(libstl) + $(LN) -s .libs/$(libstl_version) $(libstl) + +# Shared Java library. +$(libjso_target): $(JAVA_OBJS) $(C_OBJS) + $(SOLINK) -shrext @JMODSUFFIX@ $(SOFLAGS) $(LDFLAGS) \ + -o $@ $(JAVA_OBJS) $(C_OBJS) $(LIBJSO_LIBS) + +# Shared Tcl library. +$(libtso_target): $(TCL_OBJS) $(C_OBJS) + $(SOLINK) @LIBTSO_MODULE@ $(SOFLAGS) $(LDFLAGS) \ + -o $@ $(TCL_OBJS) $(C_OBJS) $(LIBTSO_LIBS) + +################################################## +# Creating individual dependencies and actions for building class +# files is possible, but it is very messy and error prone. +################################################## +java: $(libj_jarfile) $(libj_exjarfile) + +$(libj_jarfile): $(JAVA_DBSRCS) + @test -d $(JAVA_CLASSTOP) || \ + ($(MKDIR) -p $(JAVA_CLASSTOP) && \ + $(CHMOD) $(dmode) $(JAVA_CLASSTOP)) + $(JAVAC) -d $(JAVA_CLASSTOP) $(JAVACFLAGS) $(JAVA_DBSRCS) + $(JAVA) -classpath $(JAVA_CLASSTOP) \ + com.sleepycat.persist.model.ClassEnhancer $(JAVA_CLASSTOP) + cd $(JAVA_CLASSTOP) && \ + $(JAR) cfm ../$(libj_jarfile) ../$(JAVA_MANIFEST) ./com/sleepycat + +$(libj_exjarfile): $(libj_jarfile) $(JAVA_EXSRCS) + @test -d $(JAVA_EXCLASSTOP) || \ + ($(MKDIR) -p $(JAVA_EXCLASSTOP) && \ + $(CHMOD) $(dmode) $(JAVA_EXCLASSTOP)) + $(JAVAC) -classpath $(libj_jarfile) -d $(JAVA_EXCLASSTOP) \ + $(JAVACFLAGS) $(JAVA_EXSRCS) + cd $(JAVA_EXCLASSTOP) && $(JAR) cf ../$(libj_exjarfile) . + +################################################## +# Utilities +################################################## +berkeley_db_svc: $(RPC_SRV_OBJS) util_log@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + $(RPC_SRV_OBJS) util_log@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +berkeley_db_cxxsvc: $(RPC_CXXSRV_OBJS) util_log@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) \ + $(RPC_CXXSRV_OBJS) util_log@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +db_archive: db_archive@o@ util_sig@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + db_archive@o@ util_sig@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +db_checkpoint: db_checkpoint@o@ util_log@o@ util_sig@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + db_checkpoint@o@ util_log@o@ util_sig@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +db_deadlock: db_deadlock@o@ util_log@o@ util_sig@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + db_deadlock@o@ util_log@o@ util_sig@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +db_dump: db_dump@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + db_dump@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +db_dump185: db_dump185@o@ @REPLACEMENT_OBJS@ + $(CCLINK) -o $@ $(LDFLAGS) db_dump185@o@ @REPLACEMENT_OBJS@ $(DB185LIB) + $(POSTLINK) $@ + +db_hotbackup: db_hotbackup@o@ util_sig@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + db_hotbackup@o@ util_sig@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +db_load: db_load@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + db_load@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +db_printlog: db_printlog@o@ $(PRINT_OBJS) util_sig@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + db_printlog@o@ $(PRINT_OBJS) util_sig@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +db_recover: db_recover@o@ util_sig@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + db_recover@o@ util_sig@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +DBSQL_OBJS=\ + db_sql@o@ parse@o@ preparser@o@ parsefuncs@o@ tokenize@o@ \ + sqlprintf@o@ buildpt@o@ utils@o@ generate@o@ generate_test@o@ \ + generation_utils@o@ generate_verification@o@ hint_comment@o@ +db_sql: $(DBSQL_OBJS) $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) $(DBSQL_OBJS) \ + $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +db_stat: db_stat@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + db_stat@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +db_upgrade: db_upgrade@o@ util_sig@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + db_upgrade@o@ util_sig@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +db_verify: db_verify@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + db_verify@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +################################################## +# Library and standard utilities install. +################################################## +library_install: install_setup +library_install: install_include install_lib install_utilities install_docs + +uninstall: uninstall_include uninstall_lib uninstall_utilities uninstall_docs + +install_setup: + @test -d $(DESTDIR)$(prefix) || \ + ($(MKDIR) -p $(DESTDIR)$(prefix) && \ + $(CHMOD) $(dmode) $(DESTDIR)$(prefix)) + +INCDOT= db.h db_cxx.h @ADDITIONAL_INCS@ +install_include: + @echo "Installing DB include files: $(DESTDIR)$(includedir) ..." + @test -d $(DESTDIR)$(includedir) || \ + ($(MKDIR) -p $(DESTDIR)$(includedir) && \ + $(CHMOD) $(dmode) $(DESTDIR)$(includedir)) + @cd $(DESTDIR)$(includedir) && $(RM) $(INCDOT) + @for f in $(INCDOT); do \ + for d in . $(srcdir)/stl ; do \ + test -f $$d/$$f && \ + $(CP) -p $$d/$$f $(DESTDIR)$(includedir) ; \ + done ; \ + $(CHMOD) $(fmode) $(DESTDIR)$(includedir)/$$f ; \ + done + +uninstall_include: + @cd $(DESTDIR)$(includedir) && $(RM) $(INCDOT) + +install_lib: + @echo "Installing DB library: $(DESTDIR)$(libdir) ..." + @test -d $(DESTDIR)$(libdir) || \ + ($(MKDIR) -p $(DESTDIR)$(libdir) && \ + $(CHMOD) $(dmode) $(DESTDIR)$(libdir)) + @cd $(DESTDIR)$(libdir) && $(RM) $(LIB_INSTALL_FILE_LIST) + @$(INSTALLER) @INSTALL_LIBS@ $(DESTDIR)$(libdir) + @(cd $(DESTDIR)$(libdir) && \ + test -f $(libso) && $(LN) -s $(libso) $(libso_default); \ + test -f $(libso) && $(LN) -s $(libso) $(libso_major); \ + test -f $(libxso) && $(LN) -s $(libxso) $(libxso_default); \ + test -f $(libxso) && $(LN) -s $(libxso) $(libxso_major); \ + test -f $(libstlso) && $(LN) -s $(libstlso) $(libstlso_default); \ + test -f $(libstlso) && $(LN) -s $(libstlso) $(libstlso_major); \ + test -f $(libtso) && $(LN) -s $(libtso) $(libtso_default); \ + test -f $(libtso) && $(LN) -s $(libtso) $(libtso_major); \ + test -f $(libjso) && $(LN) -s $(libjso) $(libjso_default); \ + test -f $(libjso) && $(LN) -s $(libjso) $(libjso_major); \ + test -f $(libjso) && $(LN) -s $(libjso) $(libjso_g)) || exit 0 + @(test -f $(libj_jarfile) && \ + $(CP) $(libj_jarfile) $(DESTDIR)$(libdir) && \ + $(CHMOD) $(fmode) $(DESTDIR)$(libdir)/$(libj_jarfile)) || exit 0 + +uninstall_lib: + @cd $(DESTDIR)$(libdir) && $(RM) $(LIB_INSTALL_FILE_LIST) + +install_utilities: + @echo "Installing DB utilities: $(DESTDIR)$(bindir) ..." + @test -d $(DESTDIR)$(bindir) || \ + ($(MKDIR) -p $(DESTDIR)$(bindir) && \ + $(CHMOD) $(dmode) $(DESTDIR)$(bindir)) + @for i in $(UTIL_PROGS); do \ + test -f $$i.exe && i=$$i.exe || i=$$i; \ + $(RM) $(DESTDIR)$(bindir)/$$i; \ + $(INSTALLER) $$i $(DESTDIR)$(bindir)/$$i; \ + $(STRIP) $(DESTDIR)$(bindir)/$$i; \ + $(CHMOD) $(emode) $(DESTDIR)$(bindir)/$$i; \ + done + +uninstall_utilities: + @(cd $(DESTDIR)$(bindir); for i in $(UTIL_PROGS); do \ + $(RM) $$i $$i.exe; \ + done) + +DOCLIST=api_reference articles collections csharp gsg gsg_db_rep \ + gsg_txn index.html java license porting programmer_reference + +install_docs: + @echo "Installing documentation: $(DESTDIR)$(docdir) ..." + @test -d $(DESTDIR)$(docdir) || \ + ($(MKDIR) -p $(DESTDIR)$(docdir) && \ + $(CHMOD) $(dmode) $(DESTDIR)$(docdir)) + @cd $(DESTDIR)$(docdir) && $(RM) -r $(DOCLIST) + @cd $(srcdir)/docs && $(CP) -pr $(DOCLIST) $(DESTDIR)$(docdir)/ + +uninstall_docs: + @cd $(DESTDIR)$(docdir) && $(RM) -r $(DOCLIST) + +################################################## +# Remaining standard Makefile targets. +################################################## +CLEAN_LIST=\ + StlTxnGuide TxnGuide TxnGuideInMemory bench_001 berkeley_db_cxxsvc \ + berkeley_db_svc db_dump185 db_perf db_repsite db_reptest dbs ex_access \ + ex_apprec ex_btrec ex_dbclient ex_env ex_lock ex_mpool \ + ex_rep_base ex_rep_gsg_repmgr ex_rep_gsg_simple ex_rep_mgr \ + ex_sequence ex_stream ex_thread ex_tpcb \ + example_database_load example_database_read excxx_access \ + excxx_btrec excxx_env excxx_example_database_load \ + excxx_example_database_read excxx_lock excxx_mpool \ + excxx_repquote excxx_repquote_gsg_repmgr excxx_repquote_gsg_simple \ + excxx_sequence excxx_tpcb exstl_access exstl_repquote \ + exstl_tpcb txn_guide test_dbstl txn_guide_inmemory + +mostly-clean clean: + $(RM) -r $(C_OBJS) + $(RM) -r $(CXX_OBJS) $(JAVA_OBJS) $(STL_OBJS) $(TCL_OBJS) + $(RM) -r $(RPC_CLIENT_OBJS) $(RPC_SRV_OBJS) $(RPC_CXXSRV_OBJS) + $(RM) -r $(UTIL_PROGS) *.exe $(CLEAN_LIST) + $(RM) -r $(JAVA_CLASSTOP) $(JAVA_EXCLASSTOP) + $(RM) -r $(DB_STL_TEST_OBJS) $(TEST_MICRO_OBJS) + $(RM) -r tags *@o@ *.o *.o.lock *.lo core *.core core.* + $(RM) -r ALL.OUT.* PARALLEL_TESTDIR.* + $(RM) -r RUN_LOG RUNQUEUE TESTDIR TESTDIR.A TEST.LIST + $(RM) -r logtrack_seen.db test_micro test_mutex .libs + $(RM) -r $(LIB_INSTALL_FILE_LIST) + +REALCLEAN_LIST=\ + Makefile clib_port.h confdefs.h config.cache config.log config.status \ + configure.lineno db.h db185_int.h db_185.h db_config.h \ + db_cxx.h db_int.h db_int_def.h include.tcl \ + db_server.h db_server_clnt.c db_server_svc.c db_server_xdr.c \ + gen_db_server.c + +distclean maintainer-clean realclean: clean + $(RM) -r $(REALCLEAN_LIST) + $(RM) -r libtool + +check depend dvi info obj TAGS: + @echo "make: $@ target not available" + +dist rpm rpmbuild: + @echo "make: $@ target not available" && exit 1 + +################################################## +# Testers, benchmarks. +################################################## +bench_001@o@: $(srcdir)/examples_c/bench_001.c + $(CC) $(CFLAGS) $? +bench_001: bench_001@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) bench_001@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +dbs@o@: $(srcdir)/test_server/dbs.c + $(CC) $(CFLAGS) $? +dbs_am@o@: $(srcdir)/test_server/dbs_am.c + $(CC) $(CFLAGS) $? +dbs_checkpoint@o@: $(srcdir)/test_server/dbs_checkpoint.c + $(CC) $(CFLAGS) $? +dbs_debug@o@: $(srcdir)/test_server/dbs_debug.c + $(CC) $(CFLAGS) $? +dbs_handles@o@: $(srcdir)/test_server/dbs_handles.c + $(CC) $(CFLAGS) $? +dbs_log@o@: $(srcdir)/test_server/dbs_log.c + $(CC) $(CFLAGS) $? +dbs_qam@o@: $(srcdir)/test_server/dbs_qam.c + $(CC) $(CFLAGS) $? +dbs_spawn@o@: $(srcdir)/test_server/dbs_spawn.c + $(CC) $(CFLAGS) $? +dbs_trickle@o@: $(srcdir)/test_server/dbs_trickle.c + $(CC) $(CFLAGS) $? +dbs_util@o@: $(srcdir)/test_server/dbs_util.c + $(CC) $(CFLAGS) $? +dbs_yield@o@: $(srcdir)/test_server/dbs_yield.c + $(CC) $(CFLAGS) $? +DBS_OBJS=\ + dbs@o@ dbs_am@o@ dbs_checkpoint@o@ dbs_debug@o@ dbs_handles@o@ \ + dbs_log@o@ dbs_qam@o@ dbs_spawn@o@ dbs_trickle@o@ dbs_util@o@ \ + dbs_yield@o@ +dbs: $(DBS_OBJS) $(DEF_LIB) + $(CCLINK) -o $@ \ + $(LDFLAGS) $(DBS_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS) + $(POSTLINK) $@ + +db_perf@o@: $(srcdir)/test_perf/db_perf.c + $(CC) $(CFLAGS) $? +perf_checkpoint@o@: $(srcdir)/test_perf/perf_checkpoint.c + $(CC) $(CFLAGS) $? +perf_config@o@: $(srcdir)/test_perf/perf_config.c + $(CC) $(CFLAGS) $? +perf_dbs@o@: $(srcdir)/test_perf/perf_dbs.c + $(CC) $(CFLAGS) $? +perf_dead@o@: $(srcdir)/test_perf/perf_dead.c + $(CC) $(CFLAGS) $? +perf_debug@o@: $(srcdir)/test_perf/perf_debug.c + $(CC) $(CFLAGS) $? +perf_file@o@: $(srcdir)/test_perf/perf_file.c + $(CC) $(CFLAGS) $? +perf_key@o@: $(srcdir)/test_perf/perf_key.c + $(CC) $(CFLAGS) $? +perf_log@o@: $(srcdir)/test_perf/perf_log.c + $(CC) $(CFLAGS) $? +perf_misc@o@: $(srcdir)/test_perf/perf_misc.c + $(CC) $(CFLAGS) $? +perf_op@o@: $(srcdir)/test_perf/perf_op.c + $(CC) $(CFLAGS) $? +perf_parse@o@: $(srcdir)/test_perf/perf_parse.c + $(CC) $(CFLAGS) $? +perf_rand@o@: $(srcdir)/test_perf/perf_rand.c + $(CC) $(CFLAGS) $? +perf_spawn@o@: $(srcdir)/test_perf/perf_spawn.c + $(CC) $(CFLAGS) $? +perf_stat@o@: $(srcdir)/test_perf/perf_stat.c + $(CC) $(CFLAGS) $? +perf_sync@o@: $(srcdir)/test_perf/perf_sync.c + $(CC) $(CFLAGS) $? +perf_thread@o@: $(srcdir)/test_perf/perf_thread.c + $(CC) $(CFLAGS) $? +perf_trickle@o@: $(srcdir)/test_perf/perf_trickle.c + $(CC) $(CFLAGS) $? +perf_txn@o@: $(srcdir)/test_perf/perf_txn.c + $(CC) $(CFLAGS) $? +perf_util@o@: $(srcdir)/test_perf/perf_util.c + $(CC) $(CFLAGS) $? +perf_vx@o@: $(srcdir)/test_perf/perf_vx.c + $(CC) $(CFLAGS) $? +DBPERF_OBJS=\ + db_perf@o@ perf_checkpoint@o@ perf_config@o@ perf_dbs@o@ \ + perf_dead@o@ perf_debug@o@ perf_file@o@ perf_key@o@ perf_log@o@ \ + perf_misc@o@ perf_op@o@ perf_parse@o@ perf_rand@o@ perf_spawn@o@ \ + perf_stat@o@ perf_sync@o@ perf_thread@o@ perf_trickle@o@ \ + perf_txn@o@ perf_util@o@ perf_vx@o@ util_sig@o@ +db_perf: $(DBPERF_OBJS) $(DEF_LIB) + $(CCLINK) -o $@ \ + $(LDFLAGS) $(DBPERF_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS) + $(POSTLINK) $@ + +db_repsite@o@: $(srcdir)/test_repmgr/db_repsite.cpp + $(CXX) $(CXXFLAGS) $? +DBREPSITE_OBJS=db_repsite@o@ +db_repsite: $(DBREPSITE_OBJS) $(DEF_LIB_CXX) + $(CXXLINK) -o $@ \ + $(LDFLAGS) $(DBREPSITE_OBJS) $(DEF_LIB_CXX) $(TEST_LIBS) $(LIBS) + $(POSTLINK) $@ + +db_reptest@o@: $(srcdir)/test_repmgr/db_reptest.c + $(CC) $(CFLAGS) $? +reptest_am@o@: $(srcdir)/test_repmgr/reptest_am.c + $(CC) $(CFLAGS) $? +reptest_handles@o@: $(srcdir)/test_repmgr/reptest_handles.c + $(CC) $(CFLAGS) $? +reptest_spawn@o@: $(srcdir)/test_repmgr/reptest_spawn.c + $(CC) $(CFLAGS) $? +reptest_util@o@: $(srcdir)/test_repmgr/reptest_util.c + $(CC) $(CFLAGS) $? +DBREPTEST_OBJS=\ + db_reptest@o@ reptest_am@o@ reptest_handles@o@ \ + reptest_spawn@o@ reptest_util@o@ + +db_reptest: $(DBREPTEST_OBJS) $(DEF_LIB) + $(CCLINK) -o $@ \ + $(LDFLAGS) $(DBREPTEST_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS) + $(POSTLINK) $@ + +test_dbstl@o@: $(srcdir)/test_stl/base/test_dbstl.cpp + $(CXX) $(STLFLAGS) $? +test_util@o@: $(srcdir)/test_stl/base/test_util.cpp + $(CXX) $(STLFLAGS) $? +DB_STL_TEST_OBJS=test_dbstl@o@ test_util@o@ + +test_dbstl: $(DB_STL_TEST_OBJS) $(DEF_LIB_CXX) $(DEF_LIB_STL) + $(CXXLINK) -o $@ $(LDFLAGS) $(DB_STL_TEST_OBJS) \ + $(DEF_LIB_CXX) $(DEF_LIB_STL) $(LIBS) $(LIBSTLSO_LIBS) + $(POSTLINK) $@ + +b_curalloc@o@: $(srcdir)/test_micro/source/b_curalloc.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_curwalk@o@: $(srcdir)/test_micro/source/b_curwalk.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_del@o@: $(srcdir)/test_micro/source/b_del.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_get@o@: $(srcdir)/test_micro/source/b_get.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_inmem@o@: $(srcdir)/test_micro/source/b_inmem.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_latch@o@: $(srcdir)/test_micro/source/b_latch.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_load@o@: $(srcdir)/test_micro/source/b_load.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_open@o@: $(srcdir)/test_micro/source/b_open.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_put@o@: $(srcdir)/test_micro/source/b_put.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_recover@o@: $(srcdir)/test_micro/source/b_recover.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_txn@o@: $(srcdir)/test_micro/source/b_txn.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_txn_write@o@: $(srcdir)/test_micro/source/b_txn_write.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_uname@o@: $(srcdir)/test_micro/source/b_uname.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_util@o@: $(srcdir)/test_micro/source/b_util.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +b_workload@o@: $(srcdir)/test_micro/source/b_workload.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +test_micro@o@: $(srcdir)/test_micro/source/test_micro.c + $(CC) $(CFLAGS) -I$(srcdir)/test_micro/source $? +test_micro: $(TEST_MICRO_OBJS) $(DEF_LIB) + $(CCLINK) -o $@ \ + $(LDFLAGS) $(TEST_MICRO_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS) + $(POSTLINK) $@ + +test_mutex@o@: $(srcdir)/mutex/test_mutex.c + $(CC) $(CFLAGS) $? +test_mutex: test_mutex@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) test_mutex@o@ $(DEF_LIB) $(TEST_LIBS) $(LIBS) + $(POSTLINK) $@ + +################################################## +# Example programs for C. +################################################## +ex_access@o@: $(srcdir)/examples_c/ex_access.c + $(CC) $(CFLAGS) $? +ex_access: ex_access@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) ex_access@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +ex_apprec@o@: $(srcdir)/examples_c/ex_apprec/ex_apprec.c + $(CC) $(CFLAGS) $? +ex_apprec_auto@o@: $(srcdir)/examples_c/ex_apprec/ex_apprec_auto.c + $(CC) $(CFLAGS) $? +ex_apprec_autop@o@: $(srcdir)/examples_c/ex_apprec/ex_apprec_autop.c + $(CC) $(CFLAGS) $? +ex_apprec_rec@o@: $(srcdir)/examples_c/ex_apprec/ex_apprec_rec.c + $(CC) $(CFLAGS) $? +EX_APPREC_OBJS=\ + ex_apprec@o@ ex_apprec_auto@o@ ex_apprec_autop@o@ ex_apprec_rec@o@ +ex_apprec: $(EX_APPREC_OBJS) $(DEF_LIB) + $(CCLINK) -o $@ \ + $(LDFLAGS) $(EX_APPREC_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS) + +ex_btrec@o@: $(srcdir)/examples_c/ex_btrec.c + $(CC) $(CFLAGS) $? +ex_btrec: ex_btrec@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) ex_btrec@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +ex_dbclient@o@: $(srcdir)/examples_c/ex_dbclient.c + $(CC) $(CFLAGS) $? +ex_dbclient: ex_dbclient@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) ex_dbclient@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +ex_env@o@: $(srcdir)/examples_c/ex_env.c + $(CC) $(CFLAGS) $? +ex_env: ex_env@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) ex_env@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +ex_lock@o@: $(srcdir)/examples_c/ex_lock.c + $(CC) $(CFLAGS) $? +ex_lock: ex_lock@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) ex_lock@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +ex_mpool@o@: $(srcdir)/examples_c/ex_mpool.c + $(CC) $(CFLAGS) $? +ex_mpool: ex_mpool@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) ex_mpool@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +rep_base@o@: $(srcdir)/examples_c/ex_rep/base/rep_base.c + $(CC) $(CFLAGS) $? +rep_common@o@: $(srcdir)/examples_c/ex_rep/common/rep_common.c + $(CC) $(CFLAGS) $? +rep_msg@o@: $(srcdir)/examples_c/ex_rep/base/rep_msg.c + $(CC) $(CFLAGS) $? +rep_net@o@: $(srcdir)/examples_c/ex_rep/base/rep_net.c + $(CC) $(CFLAGS) $? +EX_REP_BASE_OBJS=\ + rep_base@o@ rep_common@o@ rep_msg@o@ rep_net@o@ +ex_rep_base: $(EX_REP_BASE_OBJS) $(DEF_LIB) + $(CCLINK) -o $@ \ + $(LDFLAGS) $(EX_REP_BASE_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS) + $(POSTLINK) $@ + +simple_txn@o@: $(srcdir)/examples_c/ex_rep_gsg/simple_txn.c + $(CC) $(CFLAGS) $? +ex_rep_gsg_simple: simple_txn@o@ $(DEF_LIB) + $(CCLINK) -o $@ \ + $(LDFLAGS) simple_txn@o@ $(DEF_LIB) $(TEST_LIBS) $(LIBS) + $(POSTLINK) $@ + +rep_mgr_gsg@o@: $(srcdir)/examples_c/ex_rep_gsg/rep_mgr_gsg.c + $(CC) $(CFLAGS) $? +ex_rep_gsg_repmgr: rep_mgr_gsg@o@ $(DEF_LIB) + $(CCLINK) -o $@ \ + $(LDFLAGS) rep_mgr_gsg@o@ $(DEF_LIB) $(TEST_LIBS) $(LIBS) + $(POSTLINK) $@ + +rep_mgr@o@: $(srcdir)/examples_c/ex_rep/mgr/rep_mgr.c + $(CC) $(CFLAGS) $? +EX_REP_MGR_OBJS=\ + rep_common@o@ rep_mgr@o@ +ex_rep_mgr: $(EX_REP_MGR_OBJS) $(DEF_LIB) + $(CCLINK) -o $@ \ + $(LDFLAGS) $(EX_REP_MGR_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS) + $(POSTLINK) $@ + +ex_sequence@o@: $(srcdir)/examples_c/ex_sequence.c + $(CC) $(CFLAGS) $? +ex_sequence: ex_sequence@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) ex_sequence@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +ex_stream@o@: $(srcdir)/examples_c/ex_stream.c + $(CC) $(CFLAGS) $? +ex_stream: ex_stream@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) ex_stream@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +ex_thread@o@: $(srcdir)/examples_c/ex_thread.c + $(CC) $(CFLAGS) $? +ex_thread: ex_thread@o@ $(DEF_LIB) + $(CCLINK) -o $@ \ + $(LDFLAGS) ex_thread@o@ $(DEF_LIB) $(TEST_LIBS) $(LIBS) + $(POSTLINK) $@ + +ex_tpcb@o@: $(srcdir)/examples_c/ex_tpcb.c + $(CC) $(CFLAGS) $? +ex_tpcb: ex_tpcb@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) ex_tpcb@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +gettingstarted_common@o@: \ + $(srcdir)/examples_c/getting_started/gettingstarted_common.c + $(CC) -I$(srcdir)/examples_c/getting_started $(CFLAGS) $? +example_database_load@o@: \ + $(srcdir)/examples_c/getting_started/example_database_load.c + $(CC) $(CFLAGS) $? +example_database_read@o@: \ + $(srcdir)/examples_c/getting_started/example_database_read.c + $(CC) $(CFLAGS) $? +example_database_load: example_database_load@o@ gettingstarted_common@o@ \ + $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + example_database_load@o@ gettingstarted_common@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ +example_database_read: example_database_read@o@ gettingstarted_common@o@ \ + $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) \ + example_database_read@o@ gettingstarted_common@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +txn_guide_inmemory@o@: $(srcdir)/examples_c/txn_guide/txn_guide_inmemory.c + $(CC) $(CFLAGS) $? +txn_guide_inmemory: txn_guide_inmemory@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) txn_guide_inmemory@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +txn_guide@o@: $(srcdir)/examples_c/txn_guide/txn_guide.c + $(CC) $(CFLAGS) $? +txn_guide: txn_guide@o@ $(DEF_LIB) + $(CCLINK) -o $@ $(LDFLAGS) txn_guide@o@ $(DEF_LIB) $(LIBS) + $(POSTLINK) $@ + +################################################## +# Example programs for C++. +################################################## +AccessExample@o@: $(srcdir)/examples_cxx/AccessExample.cpp + $(CXX) $(CXXFLAGS) $? +excxx_access: AccessExample@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) AccessExample@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +BtRecExample@o@: $(srcdir)/examples_cxx/BtRecExample.cpp + $(CXX) $(CXXFLAGS) $? +excxx_btrec: BtRecExample@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) BtRecExample@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +EnvExample@o@: $(srcdir)/examples_cxx/EnvExample.cpp + $(CXX) $(CXXFLAGS) $? +excxx_env: EnvExample@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) EnvExample@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +LockExample@o@: $(srcdir)/examples_cxx/LockExample.cpp + $(CXX) $(CXXFLAGS) $? +excxx_lock: LockExample@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) LockExample@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +MpoolExample@o@: $(srcdir)/examples_cxx/MpoolExample.cpp + $(CXX) $(CXXFLAGS) $? +excxx_mpool: MpoolExample@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) MpoolExample@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +RepQuoteExample@o@: $(srcdir)/examples_cxx/excxx_repquote/RepQuoteExample.cpp + $(CXX) -I$(srcdir)/examples_cxx/excxx_repquote $(CXXFLAGS) $? +RepConfigInfo@o@: $(srcdir)/examples_cxx/excxx_repquote/RepConfigInfo.cpp + $(CXX) -I$(srcdir)/examples_cxx/excxx_repquote $(CXXFLAGS) $? +excxx_repquote: RepQuoteExample@o@ RepConfigInfo@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) \ + RepQuoteExample@o@ RepConfigInfo@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +RepMgrGSG@o@: $(srcdir)/examples_cxx/excxx_repquote_gsg/RepMgrGSG.cpp + $(CXX) -I$(srcdir)/examples_cxx/excxx_repquote_gsg $(CXXFLAGS) $? +excxx_repquote_gsg_repmgr: RepMgrGSG@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) RepMgrGSG@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +SimpleTxn@o@: $(srcdir)/examples_cxx/excxx_repquote_gsg/SimpleTxn.cpp + $(CXX) -I$(srcdir)/examples_cxx/excxx_repquote_gsg $(CXXFLAGS) $? +excxx_repquote_gsg_simple: SimpleTxn@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) SimpleTxn@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +SequenceExample@o@: $(srcdir)/examples_cxx/SequenceExample.cpp + $(CXX) $(CXXFLAGS) $? +excxx_sequence: SequenceExample@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) SequenceExample@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +TpcbExample@o@: $(srcdir)/examples_cxx/TpcbExample.cpp + $(CXX) $(CXXFLAGS) $? +excxx_tpcb: TpcbExample@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) TpcbExample@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +excxx_example_database_load@o@: \ + $(srcdir)/examples_cxx/getting_started/excxx_example_database_load.cpp + $(CXX) -I$(srcdir)/examples_cxx/getting_started $(CXXFLAGS) $? +excxx_example_database_read@o@: \ + $(srcdir)/examples_cxx/getting_started/excxx_example_database_read.cpp + $(CXX) -I$(srcdir)/examples_cxx/getting_started $(CXXFLAGS) $? +MyDb@o@: $(srcdir)/examples_cxx/getting_started/MyDb.cpp + $(CXX) -I$(srcdir)/examples_cxx/getting_started $(CXXFLAGS) $? +excxx_example_database_load: \ + excxx_example_database_load@o@ MyDb@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) \ + excxx_example_database_load@o@ MyDb@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ +excxx_example_database_read: \ + excxx_example_database_read@o@ MyDb@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) \ + excxx_example_database_read@o@ MyDb@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +TxnGuideInMemory@o@: $(srcdir)/examples_cxx/txn_guide/TxnGuideInMemory.cpp + $(CXX) $(CXXFLAGS) $? +TxnGuideInMemory: TxnGuideInMemory@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) TxnGuideInMemory@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +TxnGuide@o@: $(srcdir)/examples_cxx/txn_guide/TxnGuide.cpp + $(CXX) $(CXXFLAGS) $? +TxnGuide: TxnGuide@o@ $(DEF_LIB_CXX) + $(CXXLINK) -o $@ $(LDFLAGS) TxnGuide@o@ $(DEF_LIB_CXX) $(LIBS) + $(POSTLINK) $@ + +################################################## +# Example programs for STL. +################################################## +StlAccessExample@o@: $(srcdir)/examples_stl/StlAccessExample.cpp + $(CXX) $(STLFLAGS) $? +exstl_access: StlAccessExample@o@ $(DEF_LIB_STL) + $(CXXLINK) -o $@ $(LDFLAGS) StlAccessExample@o@ $(DEF_LIB_STL) $(LIBS) + $(POSTLINK) $@ + +StlRepQuoteExample@o@: $(srcdir)/examples_stl/repquote/StlRepQuoteExample.cpp + $(CXX) -I$(srcdir)/examples_stl/repquote $(STLFLAGS) $? +StlRepConfigInfo@o@: $(srcdir)/examples_stl/repquote/StlRepConfigInfo.cpp + $(CXX) -I$(srcdir)/examples_stl/repquote $(STLFLAGS) $? +exstl_repquote: StlRepQuoteExample@o@ StlRepConfigInfo@o@ $(DEF_LIB_STL) + $(CXXLINK) -o $@ $(LDFLAGS) \ + StlRepQuoteExample@o@ StlRepConfigInfo@o@ $(DEF_LIB_STL) $(LIBS) + $(POSTLINK) $@ + +StlTpcbExample@o@: $(srcdir)/examples_stl/StlTpcbExample.cpp + $(CXX) $(STLFLAGS) $? +exstl_tpcb: StlTpcbExample@o@ $(DEF_LIB_STL) + $(CXXLINK) -o $@ $(LDFLAGS) StlTpcbExample@o@ $(DEF_LIB_STL) $(LIBS) + $(POSTLINK) $@ + +StlTransactionGuideExample@o@: $(srcdir)/examples_stl/StlTransactionGuideExample.cpp + $(CXX) $(STLFLAGS) $? +StlTxnGuide: StlTransactionGuideExample@o@ $(DEF_LIB_STL) + $(CXXLINK) -o $@ $(LDFLAGS) StlTransactionGuideExample@o@ $(DEF_LIB_STL) $(LIBS) + $(POSTLINK) $@ + +################################################## +# C API build rules. +################################################## +aes_method@o@: $(srcdir)/crypto/aes_method.c + $(CC) $(CFLAGS) $? +bt_compare@o@: $(srcdir)/btree/bt_compare.c + $(CC) $(CFLAGS) $? +bt_compress@o@: $(srcdir)/btree/bt_compress.c + $(CC) $(CFLAGS) $? +bt_conv@o@: $(srcdir)/btree/bt_conv.c + $(CC) $(CFLAGS) $? +bt_curadj@o@: $(srcdir)/btree/bt_curadj.c + $(CC) $(CFLAGS) $? +bt_cursor@o@: $(srcdir)/btree/bt_cursor.c + $(CC) $(CFLAGS) $? +bt_delete@o@: $(srcdir)/btree/bt_delete.c + $(CC) $(CFLAGS) $? +bt_method@o@: $(srcdir)/btree/bt_method.c + $(CC) $(CFLAGS) $? +bt_open@o@: $(srcdir)/btree/bt_open.c + $(CC) $(CFLAGS) $? +bt_put@o@: $(srcdir)/btree/bt_put.c + $(CC) $(CFLAGS) $? +bt_rec@o@: $(srcdir)/btree/bt_rec.c + $(CC) $(CFLAGS) $? +bt_reclaim@o@: $(srcdir)/btree/bt_reclaim.c + $(CC) $(CFLAGS) $? +bt_recno@o@: $(srcdir)/btree/bt_recno.c + $(CC) $(CFLAGS) $? +bt_rsearch@o@: $(srcdir)/btree/bt_rsearch.c + $(CC) $(CFLAGS) $? +bt_search@o@: $(srcdir)/btree/bt_search.c + $(CC) $(CFLAGS) $? +bt_split@o@: $(srcdir)/btree/bt_split.c + $(CC) $(CFLAGS) $? +bt_stat@o@: $(srcdir)/btree/bt_stat.c + $(CC) $(CFLAGS) $? +bt_compact@o@: $(srcdir)/btree/bt_compact.c + $(CC) $(CFLAGS) $? +bt_upgrade@o@: $(srcdir)/btree/bt_upgrade.c + $(CC) $(CFLAGS) $? +bt_verify@o@: $(srcdir)/btree/bt_verify.c + $(CC) $(CFLAGS) $? +btree_auto@o@: $(srcdir)/btree/btree_auto.c + $(CC) $(CFLAGS) $? +btree_autop@o@: $(srcdir)/btree/btree_autop.c + $(CC) $(CFLAGS) $? +crdel_auto@o@: $(srcdir)/db/crdel_auto.c + $(CC) $(CFLAGS) $? +crdel_autop@o@: $(srcdir)/db/crdel_autop.c + $(CC) $(CFLAGS) $? +crdel_rec@o@: $(srcdir)/db/crdel_rec.c + $(CC) $(CFLAGS) $? +crypto@o@: $(srcdir)/crypto/crypto.c + $(CC) $(CFLAGS) $? +crypto_stub@o@: $(srcdir)/common/crypto_stub.c + $(CC) $(CFLAGS) $? +db185@o@: $(srcdir)/db185/db185.c + $(CC) $(CFLAGS) $? +db@o@: $(srcdir)/db/db.c + $(CC) $(CFLAGS) $? +db_am@o@: $(srcdir)/db/db_am.c + $(CC) $(CFLAGS) $? +db_auto@o@: $(srcdir)/db/db_auto.c + $(CC) $(CFLAGS) $? +db_autop@o@: $(srcdir)/db/db_autop.c + $(CC) $(CFLAGS) $? +db_byteorder@o@: $(srcdir)/common/db_byteorder.c + $(CC) $(CFLAGS) $? +db_cam@o@: $(srcdir)/db/db_cam.c + $(CC) $(CFLAGS) $? +db_cds@o@: $(srcdir)/db/db_cds.c + $(CC) $(CFLAGS) $? +db_compint@o@: $(srcdir)/common/db_compint.c + $(CC) $(CFLAGS) $? +db_conv@o@: $(srcdir)/db/db_conv.c + $(CC) $(CFLAGS) $? +db_dispatch@o@: $(srcdir)/db/db_dispatch.c + $(CC) $(CFLAGS) $? +db_dup@o@: $(srcdir)/db/db_dup.c + $(CC) $(CFLAGS) $? +db_err@o@: $(srcdir)/common/db_err.c + $(CC) $(CFLAGS) $? +db_getlong@o@: $(srcdir)/common/db_getlong.c + $(CC) $(CFLAGS) $? +db_idspace@o@: $(srcdir)/common/db_idspace.c + $(CC) $(CFLAGS) $? +db_iface@o@: $(srcdir)/db/db_iface.c + $(CC) $(CFLAGS) $? +db_join@o@: $(srcdir)/db/db_join.c + $(CC) $(CFLAGS) $? +db_log2@o@: $(srcdir)/common/db_log2.c + $(CC) $(CFLAGS) $? +db_meta@o@: $(srcdir)/db/db_meta.c + $(CC) $(CFLAGS) $? +db_method@o@: $(srcdir)/db/db_method.c + $(CC) $(CFLAGS) $? +db_open@o@: $(srcdir)/db/db_open.c + $(CC) $(CFLAGS) $? +db_overflow@o@: $(srcdir)/db/db_overflow.c + $(CC) $(CFLAGS) $? +db_ovfl_vrfy@o@: $(srcdir)/db/db_ovfl_vrfy.c + $(CC) $(CFLAGS) $? +db_pr@o@: $(srcdir)/db/db_pr.c + $(CC) $(CFLAGS) $? +db_rec@o@: $(srcdir)/db/db_rec.c + $(CC) $(CFLAGS) $? +db_reclaim@o@: $(srcdir)/db/db_reclaim.c + $(CC) $(CFLAGS) $? +db_rename@o@: $(srcdir)/db/db_rename.c + $(CC) $(CFLAGS) $? +db_remove@o@: $(srcdir)/db/db_remove.c + $(CC) $(CFLAGS) $? +db_ret@o@: $(srcdir)/db/db_ret.c + $(CC) $(CFLAGS) $? +db_setid@o@: $(srcdir)/db/db_setid.c + $(CC) $(CFLAGS) $? +db_setlsn@o@: $(srcdir)/db/db_setlsn.c + $(CC) $(CFLAGS) $? +db_shash@o@: $(srcdir)/common/db_shash.c + $(CC) $(CFLAGS) $? +db_sort_multiple@o@: $(srcdir)/db/db_sort_multiple.c + $(CC) $(CFLAGS) $? +db_stati@o@: $(srcdir)/db/db_stati.c + $(CC) $(CFLAGS) $? +db_truncate@o@: $(srcdir)/db/db_truncate.c + $(CC) $(CFLAGS) $? +db_upg@o@: $(srcdir)/db/db_upg.c + $(CC) $(CFLAGS) $? +db_upg_opd@o@: $(srcdir)/db/db_upg_opd.c + $(CC) $(CFLAGS) $? +db_vrfy@o@: $(srcdir)/db/db_vrfy.c + $(CC) $(CFLAGS) $? +db_vrfyutil@o@: $(srcdir)/db/db_vrfyutil.c + $(CC) $(CFLAGS) $? +db_vrfy_stub@o@: $(srcdir)/db/db_vrfy_stub.c + $(CC) $(CFLAGS) $? +dbm@o@: $(srcdir)/dbm/dbm.c + $(CC) $(CFLAGS) $? +dbreg@o@: $(srcdir)/dbreg/dbreg.c + $(CC) $(CFLAGS) $? +dbreg_auto@o@: $(srcdir)/dbreg/dbreg_auto.c + $(CC) $(CFLAGS) $? +dbreg_autop@o@: $(srcdir)/dbreg/dbreg_autop.c + $(CC) $(CFLAGS) $? +dbreg_rec@o@: $(srcdir)/dbreg/dbreg_rec.c + $(CC) $(CFLAGS) $? +dbreg_stat@o@: $(srcdir)/dbreg/dbreg_stat.c + $(CC) $(CFLAGS) $? +dbreg_util@o@: $(srcdir)/dbreg/dbreg_util.c + $(CC) $(CFLAGS) $? +dbt@o@: $(srcdir)/common/dbt.c + $(CC) $(CFLAGS) $? +env_alloc@o@: $(srcdir)/env/env_alloc.c + $(CC) $(CFLAGS) $? +env_config@o@: $(srcdir)/env/env_config.c + $(CC) $(CFLAGS) $? +env_failchk@o@: $(srcdir)/env/env_failchk.c + $(CC) $(CFLAGS) $? +env_file@o@: $(srcdir)/env/env_file.c + $(CC) $(CFLAGS) $? +env_globals@o@: $(srcdir)/env/env_globals.c + $(CC) $(CFLAGS) $? +env_method@o@: $(srcdir)/env/env_method.c + $(CC) $(CFLAGS) $? +env_name@o@: $(srcdir)/env/env_name.c + $(CC) $(CFLAGS) $? +env_open@o@: $(srcdir)/env/env_open.c + $(CC) $(CFLAGS) $? +env_recover@o@: $(srcdir)/env/env_recover.c + $(CC) $(CFLAGS) $? +env_region@o@: $(srcdir)/env/env_region.c + $(CC) $(CFLAGS) $? +env_register@o@: $(srcdir)/env/env_register.c + $(CC) $(CFLAGS) $? +env_sig@o@: $(srcdir)/env/env_sig.c + $(CC) $(CFLAGS) $? +env_stat@o@: $(srcdir)/env/env_stat.c + $(CC) $(CFLAGS) $? +fileops_auto@o@: $(srcdir)/fileops/fileops_auto.c + $(CC) $(CFLAGS) $? +fileops_autop@o@: $(srcdir)/fileops/fileops_autop.c + $(CC) $(CFLAGS) $? +fop_basic@o@: $(srcdir)/fileops/fop_basic.c + $(CC) $(CFLAGS) $? +fop_rec@o@: $(srcdir)/fileops/fop_rec.c + $(CC) $(CFLAGS) $? +fop_util@o@: $(srcdir)/fileops/fop_util.c + $(CC) $(CFLAGS) $? +hash@o@: $(srcdir)/hash/hash.c + $(CC) $(CFLAGS) $? +hash_auto@o@: $(srcdir)/hash/hash_auto.c + $(CC) $(CFLAGS) $? +hash_autop@o@: $(srcdir)/hash/hash_autop.c + $(CC) $(CFLAGS) $? +hash_conv@o@: $(srcdir)/hash/hash_conv.c + $(CC) $(CFLAGS) $? +hash_dup@o@: $(srcdir)/hash/hash_dup.c + $(CC) $(CFLAGS) $? +hash_func@o@: $(srcdir)/hash/hash_func.c + $(CC) $(CFLAGS) $? +hash_meta@o@: $(srcdir)/hash/hash_meta.c + $(CC) $(CFLAGS) $? +hash_method@o@: $(srcdir)/hash/hash_method.c + $(CC) $(CFLAGS) $? +hash_open@o@: $(srcdir)/hash/hash_open.c + $(CC) $(CFLAGS) $? +hash_page@o@: $(srcdir)/hash/hash_page.c + $(CC) $(CFLAGS) $? +hash_rec@o@: $(srcdir)/hash/hash_rec.c + $(CC) $(CFLAGS) $? +hash_reclaim@o@: $(srcdir)/hash/hash_reclaim.c + $(CC) $(CFLAGS) $? +hash_stat@o@: $(srcdir)/hash/hash_stat.c + $(CC) $(CFLAGS) $? +hash_stub@o@: $(srcdir)/hash/hash_stub.c + $(CC) $(CFLAGS) $? +hash_upgrade@o@: $(srcdir)/hash/hash_upgrade.c + $(CC) $(CFLAGS) $? +hash_verify@o@: $(srcdir)/hash/hash_verify.c + $(CC) $(CFLAGS) $? +hmac@o@: $(srcdir)/hmac/hmac.c + $(CC) $(CFLAGS) $? +hsearch@o@: $(srcdir)/hsearch/hsearch.c + $(CC) $(CFLAGS) $? +lock@o@: $(srcdir)/lock/lock.c + $(CC) $(CFLAGS) $? +lock_deadlock@o@:$(srcdir)/lock/lock_deadlock.c + $(CC) $(CFLAGS) $? +lock_failchk@o@:$(srcdir)/lock/lock_failchk.c + $(CC) $(CFLAGS) $? +lock_id@o@:$(srcdir)/lock/lock_id.c + $(CC) $(CFLAGS) $? +lock_list@o@:$(srcdir)/lock/lock_list.c + $(CC) $(CFLAGS) $? +lock_method@o@:$(srcdir)/lock/lock_method.c + $(CC) $(CFLAGS) $? +lock_region@o@:$(srcdir)/lock/lock_region.c + $(CC) $(CFLAGS) $? +lock_stat@o@:$(srcdir)/lock/lock_stat.c + $(CC) $(CFLAGS) $? +lock_stub@o@: $(srcdir)/lock/lock_stub.c + $(CC) $(CFLAGS) $? +lock_timer@o@:$(srcdir)/lock/lock_timer.c + $(CC) $(CFLAGS) $? +lock_util@o@:$(srcdir)/lock/lock_util.c + $(CC) $(CFLAGS) $? +log@o@: $(srcdir)/log/log.c + $(CC) $(CFLAGS) $? +log_archive@o@: $(srcdir)/log/log_archive.c + $(CC) $(CFLAGS) $? +log_compare@o@: $(srcdir)/log/log_compare.c + $(CC) $(CFLAGS) $? +log_debug@o@: $(srcdir)/log/log_debug.c + $(CC) $(CFLAGS) $? +log_get@o@: $(srcdir)/log/log_get.c + $(CC) $(CFLAGS) $? +log_method@o@: $(srcdir)/log/log_method.c + $(CC) $(CFLAGS) $? +log_put@o@: $(srcdir)/log/log_put.c + $(CC) $(CFLAGS) $? +log_stat@o@: $(srcdir)/log/log_stat.c + $(CC) $(CFLAGS) $? +mkpath@o@: $(srcdir)/common/mkpath.c + $(CC) $(CFLAGS) $? +mp_alloc@o@: $(srcdir)/mp/mp_alloc.c + $(CC) $(CFLAGS) $? +mp_bh@o@: $(srcdir)/mp/mp_bh.c + $(CC) $(CFLAGS) $? +mp_fget@o@: $(srcdir)/mp/mp_fget.c + $(CC) $(CFLAGS) $? +mp_fmethod@o@: $(srcdir)/mp/mp_fmethod.c + $(CC) $(CFLAGS) $? +mp_fopen@o@: $(srcdir)/mp/mp_fopen.c + $(CC) $(CFLAGS) $? +mp_fput@o@: $(srcdir)/mp/mp_fput.c + $(CC) $(CFLAGS) $? +mp_fset@o@: $(srcdir)/mp/mp_fset.c + $(CC) $(CFLAGS) $? +mp_method@o@: $(srcdir)/mp/mp_method.c + $(CC) $(CFLAGS) $? +mp_mvcc@o@: $(srcdir)/mp/mp_mvcc.c + $(CC) $(CFLAGS) $? +mp_region@o@: $(srcdir)/mp/mp_region.c + $(CC) $(CFLAGS) $? +mp_register@o@: $(srcdir)/mp/mp_register.c + $(CC) $(CFLAGS) $? +mp_resize@o@: $(srcdir)/mp/mp_resize.c + $(CC) $(CFLAGS) $? +mp_stat@o@: $(srcdir)/mp/mp_stat.c + $(CC) $(CFLAGS) $? +mp_sync@o@: $(srcdir)/mp/mp_sync.c + $(CC) $(CFLAGS) $? +mp_trickle@o@: $(srcdir)/mp/mp_trickle.c + $(CC) $(CFLAGS) $? +mt19937db@o@: $(srcdir)/crypto/mersenne/mt19937db.c + $(CC) $(CFLAGS) $? +mut_alloc@o@: $(srcdir)/mutex/mut_alloc.c + $(CC) $(CFLAGS) $? +mut_failchk@o@: $(srcdir)/mutex/mut_failchk.c + $(CC) $(CFLAGS) $? +mut_fcntl@o@: $(srcdir)/mutex/mut_fcntl.c + $(CC) $(CFLAGS) $? +mut_method@o@: $(srcdir)/mutex/mut_method.c + $(CC) $(CFLAGS) $? +mut_pthread@o@: $(srcdir)/mutex/mut_pthread.c + $(CC) $(CFLAGS) $? +mut_region@o@: $(srcdir)/mutex/mut_region.c + $(CC) $(CFLAGS) $? +mut_stat@o@: $(srcdir)/mutex/mut_stat.c + $(CC) $(CFLAGS) $? +mut_stub@o@: $(srcdir)/mutex/mut_stub.c + $(CC) $(CFLAGS) $? +mut_tas@o@: $(srcdir)/mutex/mut_tas.c + $(CC) $(CFLAGS) $? +mut_win32@o@: $(srcdir)/mutex/mut_win32.c + $(CC) $(CFLAGS) $? +openflags@o@: $(srcdir)/common/openflags.c + $(CC) $(CFLAGS) $? +os_abs@o@: $(srcdir)/@OSDIR@/os_abs.c + $(CC) $(CFLAGS) $? +os_abort@o@: $(srcdir)/os/os_abort.c + $(CC) $(CFLAGS) $? +os_addrinfo@o@: $(srcdir)/os/os_addrinfo.c + $(CC) $(CFLAGS) $? +os_alloc@o@: $(srcdir)/os/os_alloc.c + $(CC) $(CFLAGS) $? +os_clock@o@: $(srcdir)/@OSDIR@/os_clock.c + $(CC) $(CFLAGS) $? +os_config@o@: $(srcdir)/@OSDIR@/os_config.c + $(CC) $(CFLAGS) $? +os_cpu@o@: $(srcdir)/@OSDIR@/os_cpu.c + $(CC) $(CFLAGS) $? +os_ctime@o@: $(srcdir)/os/os_ctime.c + $(CC) $(CFLAGS) $? +os_dir@o@: $(srcdir)/@OSDIR@/os_dir.c + $(CC) $(CFLAGS) $? +os_errno@o@: $(srcdir)/@OSDIR@/os_errno.c + $(CC) $(CFLAGS) $? +os_fid@o@: $(srcdir)/@OSDIR@/os_fid.c + $(CC) $(CFLAGS) $? +os_flock@o@: $(srcdir)/@OSDIR@/os_flock.c + $(CC) $(CFLAGS) $? +os_fsync@o@: $(srcdir)/@OSDIR@/os_fsync.c + $(CC) $(CFLAGS) $? +os_getenv@o@: $(srcdir)/@OSDIR@/os_getenv.c + $(CC) $(CFLAGS) $? +os_handle@o@: $(srcdir)/@OSDIR@/os_handle.c + $(CC) $(CFLAGS) $? +os_map@o@: $(srcdir)/@OSDIR@/os_map.c + $(CC) $(CFLAGS) $? +os_method@o@: $(srcdir)/common/os_method.c + $(CC) $(CFLAGS) $? +os_mkdir@o@: $(srcdir)/@OSDIR@/os_mkdir.c + $(CC) $(CFLAGS) $? +os_open@o@: $(srcdir)/@OSDIR@/os_open.c + $(CC) $(CFLAGS) $? +os_pid@o@: $(srcdir)/os/os_pid.c + $(CC) $(CFLAGS) $? +os_qnx_fsync@o@: $(srcdir)/os_qnx/os_qnx_fsync.c + $(CC) $(CFLAGS) $? +os_qnx_open@o@: $(srcdir)/os_qnx/os_qnx_open.c + $(CC) $(CFLAGS) $? +os_rename@o@: $(srcdir)/@OSDIR@/os_rename.c + $(CC) $(CFLAGS) $? +os_root@o@: $(srcdir)/os/os_root.c + $(CC) $(CFLAGS) $? +os_rpath@o@: $(srcdir)/os/os_rpath.c + $(CC) $(CFLAGS) $? +os_rw@o@: $(srcdir)/@OSDIR@/os_rw.c + $(CC) $(CFLAGS) $? +os_seek@o@: $(srcdir)/@OSDIR@/os_seek.c + $(CC) $(CFLAGS) $? +os_stack@o@: $(srcdir)/os/os_stack.c + $(CC) $(CFLAGS) $? +os_stat@o@: $(srcdir)/@OSDIR@/os_stat.c + $(CC) $(CFLAGS) $? +os_tmpdir@o@: $(srcdir)/os/os_tmpdir.c + $(CC) $(CFLAGS) $? +os_truncate@o@: $(srcdir)/@OSDIR@/os_truncate.c + $(CC) $(CFLAGS) $? +os_uid@o@: $(srcdir)/os/os_uid.c + $(CC) $(CFLAGS) $? +os_unlink@o@: $(srcdir)/@OSDIR@/os_unlink.c + $(CC) $(CFLAGS) $? +os_yield@o@: $(srcdir)/@OSDIR@/os_yield.c + $(CC) $(CFLAGS) $? +partition@o@: $(srcdir)/db/partition.c + $(CC) $(CFLAGS) $? +qam@o@: $(srcdir)/qam/qam.c + $(CC) $(CFLAGS) $? +qam_auto@o@: $(srcdir)/qam/qam_auto.c + $(CC) $(CFLAGS) $? +qam_autop@o@: $(srcdir)/qam/qam_autop.c + $(CC) $(CFLAGS) $? +qam_conv@o@: $(srcdir)/qam/qam_conv.c + $(CC) $(CFLAGS) $? +qam_files@o@: $(srcdir)/qam/qam_files.c + $(CC) $(CFLAGS) $? +qam_method@o@: $(srcdir)/qam/qam_method.c + $(CC) $(CFLAGS) $? +qam_open@o@: $(srcdir)/qam/qam_open.c + $(CC) $(CFLAGS) $? +qam_rec@o@: $(srcdir)/qam/qam_rec.c + $(CC) $(CFLAGS) $? +qam_stat@o@: $(srcdir)/qam/qam_stat.c + $(CC) $(CFLAGS) $? +qam_stub@o@: $(srcdir)/qam/qam_stub.c + $(CC) $(CFLAGS) $? +qam_upgrade@o@: $(srcdir)/qam/qam_upgrade.c + $(CC) $(CFLAGS) $? +qam_verify@o@: $(srcdir)/qam/qam_verify.c + $(CC) $(CFLAGS) $? +rep_auto@o@: $(srcdir)/rep/rep_auto.c + $(CC) $(CFLAGS) $? +rep_backup@o@: $(srcdir)/rep/rep_backup.c + $(CC) $(CFLAGS) $? +rep_elect@o@: $(srcdir)/rep/rep_elect.c + $(CC) $(CFLAGS) $? +rep_lease@o@: $(srcdir)/rep/rep_lease.c + $(CC) $(CFLAGS) $? +rep_log@o@: $(srcdir)/rep/rep_log.c + $(CC) $(CFLAGS) $? +rep_method@o@: $(srcdir)/rep/rep_method.c + $(CC) $(CFLAGS) $? +rep_record@o@: $(srcdir)/rep/rep_record.c + $(CC) $(CFLAGS) $? +rep_region@o@: $(srcdir)/rep/rep_region.c + $(CC) $(CFLAGS) $? +rep_stub@o@: $(srcdir)/rep/rep_stub.c + $(CC) $(CFLAGS) $? +rep_stat@o@: $(srcdir)/rep/rep_stat.c + $(CC) $(CFLAGS) $? +rep_util@o@: $(srcdir)/rep/rep_util.c + $(CC) $(CFLAGS) $? +rep_verify@o@: $(srcdir)/rep/rep_verify.c + $(CC) $(CFLAGS) $? +repmgr_auto@o@: $(srcdir)/repmgr/repmgr_auto.c + $(CC) $(CFLAGS) $? +repmgr_elect@o@: $(srcdir)/repmgr/repmgr_elect.c + $(CC) $(CFLAGS) $? +repmgr_method@o@: $(srcdir)/repmgr/repmgr_method.c + $(CC) $(CFLAGS) $? +repmgr_msg@o@: $(srcdir)/repmgr/repmgr_msg.c + $(CC) $(CFLAGS) $? +repmgr_net@o@: $(srcdir)/repmgr/repmgr_net.c + $(CC) $(CFLAGS) $? +repmgr_posix@o@: $(srcdir)/repmgr/repmgr_posix.c + $(CC) $(CFLAGS) $? +repmgr_queue@o@: $(srcdir)/repmgr/repmgr_queue.c + $(CC) $(CFLAGS) $? +repmgr_sel@o@: $(srcdir)/repmgr/repmgr_sel.c + $(CC) $(CFLAGS) $? +repmgr_stat@o@: $(srcdir)/repmgr/repmgr_stat.c + $(CC) $(CFLAGS) $? +repmgr_stub@o@: $(srcdir)/repmgr/repmgr_stub.c + $(CC) $(CFLAGS) $? +repmgr_util@o@: $(srcdir)/repmgr/repmgr_util.c + $(CC) $(CFLAGS) $? +rijndael-alg-fst@o@: $(srcdir)/crypto/rijndael/rijndael-alg-fst.c + $(CC) $(CFLAGS) $? +rijndael-api-fst@o@: $(srcdir)/crypto/rijndael/rijndael-api-fst.c + $(CC) $(CFLAGS) $? +seq_stat@o@: $(srcdir)/sequence/seq_stat.c + $(CC) $(CFLAGS) $? +sequence@o@: $(srcdir)/sequence/sequence.c + $(CC) $(CFLAGS) $? +sha1@o@: $(srcdir)/hmac/sha1.c + $(CC) $(CFLAGS) $? +stat_stub@o@: $(srcdir)/common/stat_stub.c + $(CC) $(CFLAGS) $? +txn@o@: $(srcdir)/txn/txn.c + $(CC) $(CFLAGS) $? +txn_auto@o@: $(srcdir)/txn/txn_auto.c + $(CC) $(CFLAGS) $? +txn_autop@o@: $(srcdir)/txn/txn_autop.c + $(CC) $(CFLAGS) $? +txn_chkpt@o@: $(srcdir)/txn/txn_chkpt.c + $(CC) $(CFLAGS) $? +txn_failchk@o@: $(srcdir)/txn/txn_failchk.c + $(CC) $(CFLAGS) $? +txn_method@o@: $(srcdir)/txn/txn_method.c + $(CC) $(CFLAGS) $? +txn_rec@o@: $(srcdir)/txn/txn_rec.c + $(CC) $(CFLAGS) $? +txn_recover@o@: $(srcdir)/txn/txn_recover.c + $(CC) $(CFLAGS) $? +txn_region@o@: $(srcdir)/txn/txn_region.c + $(CC) $(CFLAGS) $? +txn_stat@o@: $(srcdir)/txn/txn_stat.c + $(CC) $(CFLAGS) $? +txn_util@o@: $(srcdir)/txn/txn_util.c + $(CC) $(CFLAGS) $? +util_arg@o@: $(srcdir)/common/util_arg.c + $(CC) $(CFLAGS) $? +util_cache@o@: $(srcdir)/common/util_cache.c + $(CC) $(CFLAGS) $? +util_log@o@: $(srcdir)/common/util_log.c + $(CC) $(CFLAGS) $? +util_sig@o@: $(srcdir)/common/util_sig.c + $(CC) $(CFLAGS) $? +uts4_cc@o@: $(srcdir)/mutex/uts4_cc.s + $(AS) $(ASFLAGS) -o $@ $? +zerofill@o@: $(srcdir)/common/zerofill.c + $(CC) $(CFLAGS) $? + +################################################## +# C++ API build rules. +################################################## +cxx_db@o@: $(srcdir)/cxx/cxx_db.cpp + $(CXX) $(CXXFLAGS) $? +cxx_dbc@o@: $(srcdir)/cxx/cxx_dbc.cpp + $(CXX) $(CXXFLAGS) $? +cxx_dbt@o@: $(srcdir)/cxx/cxx_dbt.cpp + $(CXX) $(CXXFLAGS) $? +cxx_env@o@: $(srcdir)/cxx/cxx_env.cpp + $(CXX) $(CXXFLAGS) $? +cxx_except@o@: $(srcdir)/cxx/cxx_except.cpp + $(CXX) $(CXXFLAGS) $? +cxx_lock@o@: $(srcdir)/cxx/cxx_lock.cpp + $(CXX) $(CXXFLAGS) $? +cxx_logc@o@: $(srcdir)/cxx/cxx_logc.cpp + $(CXX) $(CXXFLAGS) $? +cxx_mpool@o@: $(srcdir)/cxx/cxx_mpool.cpp + $(CXX) $(CXXFLAGS) $? +cxx_multi@o@: $(srcdir)/cxx/cxx_multi.cpp + $(CXX) $(CXXFLAGS) $? +cxx_seq@o@: $(srcdir)/cxx/cxx_seq.cpp + $(CXX) $(CXXFLAGS) $? +cxx_txn@o@: $(srcdir)/cxx/cxx_txn.cpp + $(CXX) $(CXXFLAGS) $? + +################################################## +# Java API build rules. +################################################## +db_java_wrap@o@: $(srcdir)/libdb_java/db_java_wrap.c + $(CC) $(CFLAGS) $(SWIGCFLAGS) $? + +################################################## +# STL API build rules. +################################################## +dbstl_container@o@: $(srcdir)/stl/dbstl_container.cpp + $(CXX) $(STLFLAGS) $? +dbstl_resource_manager@o@: $(srcdir)/stl/dbstl_resource_manager.cpp + $(CXX) $(STLFLAGS) $? + +################################################## +# Tcl API build rules. +################################################## +tcl_compat@o@: $(srcdir)/tcl/tcl_compat.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_db@o@: $(srcdir)/tcl/tcl_db.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_db_pkg@o@: $(srcdir)/tcl/tcl_db_pkg.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_dbcursor@o@: $(srcdir)/tcl/tcl_dbcursor.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_env@o@: $(srcdir)/tcl/tcl_env.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_internal@o@: $(srcdir)/tcl/tcl_internal.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_lock@o@: $(srcdir)/tcl/tcl_lock.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_log@o@: $(srcdir)/tcl/tcl_log.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_mp@o@: $(srcdir)/tcl/tcl_mp.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_mutex@o@: $(srcdir)/tcl/tcl_mutex.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_rep@o@: $(srcdir)/tcl/tcl_rep.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_seq@o@: $(srcdir)/tcl/tcl_seq.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_txn@o@: $(srcdir)/tcl/tcl_txn.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? +tcl_util@o@: $(srcdir)/tcl/tcl_util.c + $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? + +################################################## +# RPC build rules. +################################################## +# RPC client files +client@o@: $(srcdir)/rpc_client/client.c + $(CC) $(CFLAGS) $? +db_server_clnt@o@: db_server_clnt.c + $(CC) $(CFLAGS) $? +gen_client@o@: $(srcdir)/rpc_client/gen_client.c + $(CC) $(CFLAGS) $? +gen_client_ret@o@: $(srcdir)/rpc_client/gen_client_ret.c + $(CC) $(CFLAGS) $? + +# RPC server files +db_server_proc@o@: $(srcdir)/rpc_server/c/db_server_proc.c + $(CC) $(CFLAGS) $? +db_server_svc@o@: db_server_svc.c + $(CC) $(CFLAGS) $? +db_server_util@o@: $(srcdir)/rpc_server/c/db_server_util.c + $(CC) $(CFLAGS) $? +db_server_xdr@o@: db_server_xdr.c + $(CC) $(CFLAGS) $? +gen_db_server@o@: gen_db_server.c + $(CC) $(CFLAGS) $? +db_server_cxxproc@o@: $(srcdir)/rpc_server/cxx/db_server_cxxproc.cpp + $(CXX) $(CXXFLAGS) $? +db_server_cxxutil@o@: $(srcdir)/rpc_server/cxx/db_server_cxxutil.cpp + $(CXX) $(CXXFLAGS) $? + +################################################## +# Utility build rules. +################################################## +db_archive@o@: $(srcdir)/db_archive/db_archive.c + $(CC) $(CFLAGS) $? +db_checkpoint@o@: $(srcdir)/db_checkpoint/db_checkpoint.c + $(CC) $(CFLAGS) $? +db_deadlock@o@: $(srcdir)/db_deadlock/db_deadlock.c + $(CC) $(CFLAGS) $? +db_dump@o@: $(srcdir)/db_dump/db_dump.c + $(CC) $(CFLAGS) $? +db_dump185@o@: $(srcdir)/db_dump185/db_dump185.c + $(CC) $(DB185INC) $? +db_hotbackup@o@: $(srcdir)/db_hotbackup/db_hotbackup.c + $(CC) $(CFLAGS) $? +db_load@o@: $(srcdir)/db_load/db_load.c + $(CC) $(CFLAGS) $? +db_printlog@o@: $(srcdir)/db_printlog/db_printlog.c + $(CC) $(CFLAGS) $? +db_recover@o@: $(srcdir)/db_recover/db_recover.c + $(CC) $(CFLAGS) $? +db_stat@o@: $(srcdir)/db_stat/db_stat.c + $(CC) $(CFLAGS) $? +db_upgrade@o@: $(srcdir)/db_upgrade/db_upgrade.c + $(CC) $(CFLAGS) $? +db_verify@o@: $(srcdir)/db_verify/db_verify.c + $(CC) $(CFLAGS) $? + +db_sql@o@: $(srcdir)/db_sql/db_sql.c + $(CC) $(CFLAGS) $? +preparser@o@: $(srcdir)/db_sql/preparser.c + $(CC) $(CFLAGS) $? +parsefuncs@o@: $(srcdir)/db_sql/parsefuncs.c + $(CC) $(CFLAGS) $? +tokenize@o@: $(srcdir)/db_sql/tokenize.c + $(CC) $(CFLAGS) $? +buildpt@o@: $(srcdir)/db_sql/buildpt.c + $(CC) $(CFLAGS) $? +utils@o@: $(srcdir)/db_sql/utils.c + $(CC) $(CFLAGS) $? +generate@o@: $(srcdir)/db_sql/generate.c + $(CC) $(CFLAGS) $? +generate_test@o@: $(srcdir)/db_sql/generate_test.c + $(CC) $(CFLAGS) $? +generate_verification@o@: $(srcdir)/db_sql/generate_verification.c + $(CC) $(CFLAGS) $? +generation_utils@o@: $(srcdir)/db_sql/generation_utils.c + $(CC) $(CFLAGS) $? +hint_comment@o@: $(srcdir)/db_sql/hint_comment.c + $(CC) $(CFLAGS) $? +sqlprintf@o@: $(srcdir)/db_sql/sqlite/sqlprintf.c + $(CC) $(CFLAGS) $? +parse@o@: $(srcdir)/db_sql/sqlite/parse.c + $(CC) $(CFLAGS) $? + +################################################## +# C library replacement files. +################################################## +atoi@o@: $(srcdir)/clib/atoi.c + $(CC) $(CFLAGS) $? +atol@o@: $(srcdir)/clib/atol.c + $(CC) $(CFLAGS) $? +getcwd@o@: $(srcdir)/clib/getcwd.c + $(CC) $(CFLAGS) $? +getopt@o@: $(srcdir)/clib/getopt.c + $(CC) $(CFLAGS) $? +isalpha@o@: $(srcdir)/clib/isalpha.c + $(CC) $(CFLAGS) $? +isdigit@o@: $(srcdir)/clib/isdigit.c + $(CC) $(CFLAGS) $? +isprint@o@: $(srcdir)/clib/isprint.c + $(CC) $(CFLAGS) $? +isspace@o@: $(srcdir)/clib/isspace.c + $(CC) $(CFLAGS) $? +memcmp@o@: $(srcdir)/clib/memcmp.c + $(CC) $(CFLAGS) $? +memcpy@o@: $(srcdir)/clib/memmove.c + $(CC) -DMEMCOPY $(CFLAGS) $? -o $@ +memmove@o@: $(srcdir)/clib/memmove.c + $(CC) -DMEMMOVE $(CFLAGS) $? +printf@o@: $(srcdir)/clib/printf.c + $(CC) $(CFLAGS) $? +qsort@o@: $(srcdir)/clib/qsort.c + $(CC) $(CFLAGS) $? +raise@o@: $(srcdir)/clib/raise.c + $(CC) $(CFLAGS) $? +rand@o@: $(srcdir)/clib/rand.c + $(CC) $(CFLAGS) $? +strcasecmp@o@: $(srcdir)/clib/strcasecmp.c + $(CC) $(CFLAGS) $? +strdup@o@: $(srcdir)/clib/strdup.c + $(CC) $(CFLAGS) $? +snprintf@o@: $(srcdir)/clib/snprintf.c + $(CC) $(CFLAGS) $? +strcat@o@: $(srcdir)/clib/strcat.c + $(CC) $(CFLAGS) $? +strchr@o@: $(srcdir)/clib/strchr.c + $(CC) $(CFLAGS) $? +strerror@o@: $(srcdir)/clib/strerror.c + $(CC) $(CFLAGS) $? +strncat@o@: $(srcdir)/clib/strncat.c + $(CC) $(CFLAGS) $? +strncmp@o@: $(srcdir)/clib/strncmp.c + $(CC) $(CFLAGS) $? +strrchr@o@: $(srcdir)/clib/strrchr.c + $(CC) $(CFLAGS) $? +strsep@o@: $(srcdir)/clib/strsep.c + $(CC) $(CFLAGS) $? +strtol@o@: $(srcdir)/clib/strtol.c + $(CC) $(CFLAGS) $? +strtoul@o@: $(srcdir)/clib/strtoul.c + $(CC) $(CFLAGS) $? +time@o@: $(srcdir)/clib/time.c + $(CC) $(CFLAGS) $? diff --git a/src/libs/resiprocate/contrib/db/dist/RELEASE b/src/libs/resiprocate/contrib/db/dist/RELEASE new file mode 100644 index 00000000..a1baf8e7 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/RELEASE @@ -0,0 +1,11 @@ +# $Id$ + +DB_VERSION_MAJOR=4 +DB_VERSION_MINOR=8 +DB_VERSION_PATCH=30 +DB_VERSION="$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH" + +DB_VERSION_UNIQUE_NAME=`printf "_%d%03d" $DB_VERSION_MAJOR $DB_VERSION_MINOR` + +DB_RELEASE_DATE=`date "+%B %e, %Y"` +DB_VERSION_STRING="Berkeley DB $DB_VERSION: ($DB_RELEASE_DATE)" diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal/config.ac b/src/libs/resiprocate/contrib/db/dist/aclocal/config.ac new file mode 100644 index 00000000..717a0bec --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal/config.ac @@ -0,0 +1,62 @@ +# Features we don't test for, but want the #defines to exist for +# other ports. +AH_TEMPLATE(DB_WIN32, + [We use DB_WIN32 much as one would use _WIN32 -- to specify that + we're using an operating system environment that supports Win32 + calls and semantics. We don't use _WIN32 because Cygwin/GCC also + defines _WIN32, even though Cygwin/GCC closely emulates the Unix + environment.]) + +AH_TEMPLATE(HAVE_VXWORKS, [Define to 1 if building VxWorks.]) + +AH_TEMPLATE(HAVE_FILESYSTEM_NOTZERO, + [Define to 1 if allocated filesystem blocks are not zeroed.]) + +AH_TEMPLATE(HAVE_UNLINK_WITH_OPEN_FAILURE, + [Define to 1 if unlink of file with open file descriptors will fail.]) + +AH_BOTTOM([/* + * Exit success/failure macros. + */ +#ifndef HAVE_EXIT_SUCCESS +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 +#endif + +/* + * Don't step on the namespace. Other libraries may have their own + * implementations of these functions, we don't want to use their + * implementations or force them to use ours based on the load order. + */ +#ifndef HAVE_GETCWD +#define getcwd __db_Cgetcwd +#endif +#ifndef HAVE_MEMCMP +#define memcmp __db_Cmemcmp +#endif +#ifndef HAVE_MEMCPY +#define memcpy __db_Cmemcpy +#endif +#ifndef HAVE_MEMMOVE +#define memmove __db_Cmemmove +#endif +#ifndef HAVE_RAISE +#define raise __db_Craise +#endif +#ifndef HAVE_SNPRINTF +#define snprintf __db_Csnprintf +#endif +#ifndef HAVE_STRCASECMP +#define strcasecmp __db_Cstrcasecmp +#define strncasecmp __db_Cstrncasecmp +#endif +#ifndef HAVE_STRERROR +#define strerror __db_Cstrerror +#endif +#ifndef HAVE_VSNPRINTF +#define vsnprintf __db_Cvsnprintf +#endif + +#ifdef DB_WIN32 +#include "win_db.h" +#endif]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal/cxx.ac b/src/libs/resiprocate/contrib/db/dist/aclocal/cxx.ac new file mode 100644 index 00000000..49103cc6 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal/cxx.ac @@ -0,0 +1,17 @@ +# C++ checks to determine what style of headers to use and +# whether to use "using" clauses. + +AC_DEFUN(AC_CXX_HAVE_STDHEADERS, [ +AC_SUBST(cxx_have_stdheaders) +AC_CACHE_CHECK([whether C++ supports the ISO C++ standard includes], +db_cv_cxx_have_stdheaders, +[AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_COMPILE([#include +],[std::ostream *o; return 0;], + db_cv_cxx_have_stdheaders=yes, db_cv_cxx_have_stdheaders=no) + AC_LANG_RESTORE +]) +if test "$db_cv_cxx_have_stdheaders" = yes; then + cxx_have_stdheaders="#define HAVE_CXX_STDHEADERS 1" +fi]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal/gcc.ac b/src/libs/resiprocate/contrib/db/dist/aclocal/gcc.ac new file mode 100644 index 00000000..0949d982 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal/gcc.ac @@ -0,0 +1,36 @@ +# Version 2.96 of gcc (shipped with RedHat Linux 7.[01] and Mandrake) had +# serious problems. +AC_DEFUN(AC_GCC_CONFIG1, [ +AC_CACHE_CHECK([whether we are using gcc version 2.96], +db_cv_gcc_2_96, [ +db_cv_gcc_2_96=no +if test "$GCC" = "yes"; then + GCC_VERSION=`${MAKEFILE_CC} --version` + case ${GCC_VERSION} in + 2.96*) + db_cv_gcc_2_96=yes;; + esac +fi]) +if test "$db_cv_gcc_2_96" = "yes"; then + CFLAGS=`echo "$CFLAGS" | sed 's/-O2/-O/'` + CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-O2/-O/'` + AC_MSG_WARN([INSTALLED GCC COMPILER HAS SERIOUS BUGS; PLEASE UPGRADE.]) + AC_MSG_WARN([GCC OPTIMIZATION LEVEL SET TO -O.]) +fi]) + +# Versions of g++ up to 2.8.0 required -fhandle-exceptions, but it is +# renamed as -fexceptions and is the default in versions 2.8.0 and after. +AC_DEFUN(AC_GCC_CONFIG2, [ +AC_CACHE_CHECK([whether g++ requires -fhandle-exceptions], +db_cv_gxx_except, [ +db_cv_gxx_except=no; +if test "$GXX" = "yes"; then + GXX_VERSION=`${MAKEFILE_CXX} --version` + case ${GXX_VERSION} in + 1.*|2.[[01234567]].*|*-1.*|*-2.[[01234567]].*) + db_cv_gxx_except=yes;; + esac +fi]) +if test "$db_cv_gxx_except" = "yes"; then + CXXFLAGS="$CXXFLAGS -fhandle-exceptions" +fi]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal/libtool.ac b/src/libs/resiprocate/contrib/db/dist/aclocal/libtool.ac new file mode 100644 index 00000000..71dae456 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal/libtool.ac @@ -0,0 +1,5987 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +## Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004 +## Free Software Foundation, Inc. +## Originally by Gordon Matzigkeit , 1996 +## +## 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 2 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, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that contains a +## configuration script generated by Autoconf, you may include it under +## the same distribution terms that you use for the rest of that program. + +# serial 47 AC_PROG_LIBTOOL + + +# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) +# ----------------------------------------------------------- +# If this macro is not defined by Autoconf, define it here. +m4_ifdef([AC_PROVIDE_IFELSE], + [], + [m4_define([AC_PROVIDE_IFELSE], + [m4_ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + + +# AC_PROG_LIBTOOL +# --------------- +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX + ])]) +dnl And a similar setup for Fortran 77 support + AC_PROVIDE_IFELSE([AC_PROG_F77], + [AC_LIBTOOL_F77], + [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], + defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) +])])# AC_PROG_LIBTOOL + + +# _AC_PROG_LIBTOOL +# ---------------- +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +])# _AC_PROG_LIBTOOL + + +# AC_LIBTOOL_SETUP +# ---------------- +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.50)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +AC_LIBTOOL_SYS_MAX_CMD_LEN +AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +AC_LIBTOOL_OBJDIR + +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +_LT_AC_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] + +# Same as above, but do not quote variable references. +[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +AC_CHECK_TOOL(AR, ar, false) +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +AC_ARG_WITH([pic], + [AC_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +AC_LIBTOOL_LANG_C_CONFIG +_LT_AC_TAGCONFIG +])# AC_LIBTOOL_SETUP + + +# _LT_AC_SYS_COMPILER +# ------------------- +AC_DEFUN([_LT_AC_SYS_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_AC_SYS_COMPILER + + +# _LT_AC_SYS_LIBPATH_AIX +# ---------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], +[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_AC_SYS_LIBPATH_AIX + + +# _LT_AC_SHELL_INIT(ARG) +# ---------------------- +AC_DEFUN([_LT_AC_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_AC_SHELL_INIT + + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[_LT_AC_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string="`eval $cmd`") 2>/dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +])])# _LT_AC_PROG_ECHO_BACKSLASH + + +# _LT_AC_LOCK +# ----------- +AC_DEFUN([_LT_AC_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; + ]) +esac + +need_locks="$enable_libtool_lock" + +])# _LT_AC_LOCK + + +# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], +[AC_REQUIRE([LT_AC_PROG_SED]) +AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s conftest.err; then + $2=yes + fi + fi + $rm conftest* +]) + +if test x"[$]$2" = xyes; then + ifelse([$5], , :, [$5]) +else + ifelse([$6], , :, [$6]) +fi +])# AC_LIBTOOL_COMPILER_OPTION + + +# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ------------------------------------------------------------ +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], +[AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + else + $2=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$4], , :, [$4]) +else + ifelse([$5], , :, [$5]) +fi +])# AC_LIBTOOL_LINKER_OPTION + + +# AC_LIBTOOL_SYS_MAX_CMD_LEN +# -------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], +[# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* ) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for *BSD + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + ;; + + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +])# AC_LIBTOOL_SYS_MAX_CMD_LEN + + +# _LT_AC_CHECK_DLFCN +# -------------------- +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h)dnl +])# _LT_AC_CHECK_DLFCN + + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ------------------------------------------------------------------ +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_unknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + + +# AC_LIBTOOL_DLOPEN_SELF +# ------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + + +# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) +# --------------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler +AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s out/conftest.err; then + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* +]) +])# AC_LIBTOOL_PROG_CC_C_O + + +# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) +# ----------------------------------------- +# Check to see if we can do hard links to lock some files if needed +AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], +[AC_REQUIRE([_LT_AC_LOCK])dnl + +hard_links="nottested" +if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS + + +# AC_LIBTOOL_OBJDIR +# ----------------- +AC_DEFUN([AC_LIBTOOL_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +])# AC_LIBTOOL_OBJDIR + + +# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) +# ---------------------------------------------- +# Check hardcoding attributes. +AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_AC_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ + test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_AC_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_AC_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_AC_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH + + +# AC_LIBTOOL_SYS_LIB_STRIP +# ------------------------ +AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], +[striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) +fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +])# AC_LIBTOOL_SYS_LIB_STRIP + + +# AC_LIBTOOL_SYS_DYNAMIC_LINKER +# ----------------------------- +# PORTME Fill in your ld.so characteristics +AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], +[AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case "$host_cpu" in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`$SED -e 's/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g' /etc/ld.so.conf | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no +])# AC_LIBTOOL_SYS_DYNAMIC_LINKER + + +# _LT_AC_TAGCONFIG +# ---------------- +AC_DEFUN([_LT_AC_TAGCONFIG], +[AC_ARG_WITH([tags], + [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], + [include additional configurations @<:@automatic@:>@])], + [tagnames="$withval"]) + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in + "") ;; + *) AC_MSG_ERROR([invalid tag name: $tagname]) + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + AC_MSG_ERROR([tag name \"$tagname\" already exists]) + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && test "X$CXX" != "Xno"; then + AC_LIBTOOL_LANG_CXX_CONFIG + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + else + tagname="" + fi + ;; + + RC) + AC_LIBTOOL_LANG_RC_CONFIG + ;; + + *) + AC_MSG_ERROR([Unsupported tag name: $tagname]) + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + fi +fi +])# _LT_AC_TAGCONFIG + + +# AC_LIBTOOL_DLOPEN +# ----------------- +# enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], + [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_DLOPEN + + +# AC_LIBTOOL_WIN32_DLL +# -------------------- +# declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_WIN32_DLL + + +# AC_ENABLE_SHARED([DEFAULT]) +# --------------------------- +# implement the --enable-shared flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([shared], + [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]AC_ENABLE_SHARED_DEFAULT) +])# AC_ENABLE_SHARED + + +# AC_DISABLE_SHARED +# ----------------- +#- set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no) +])# AC_DISABLE_SHARED + + +# AC_ENABLE_STATIC([DEFAULT]) +# --------------------------- +# implement the --enable-static flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([static], + [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]AC_ENABLE_STATIC_DEFAULT) +])# AC_ENABLE_STATIC + + +# AC_DISABLE_STATIC +# ----------------- +# set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no) +])# AC_DISABLE_STATIC + + +# AC_ENABLE_FAST_INSTALL([DEFAULT]) +# --------------------------------- +# implement the --enable-fast-install flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([fast-install], + [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) +])# AC_ENABLE_FAST_INSTALL + + +# AC_DISABLE_FAST_INSTALL +# ----------------------- +# set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no) +])# AC_DISABLE_FAST_INSTALL + + +# AC_LIBTOOL_PICMODE([MODE]) +# -------------------------- +# implement the --with-pic flag +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default) +])# AC_LIBTOOL_PICMODE + + +# AC_PROG_EGREP +# ------------- +# This is predefined starting with Autoconf 2.54, so this conditional +# definition can be removed once we require Autoconf 2.54 or later. +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], +[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], + [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) + + +# AC_PATH_TOOL_PREFIX +# ------------------- +# find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +])# AC_PATH_TOOL_PREFIX + + +# AC_PATH_MAGIC +# ------------- +# find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# AC_PATH_MAGIC + + +# AC_PROG_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case "$host_cpu" in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux*) + case $host_cpu in + alpha*|hppa*|i*86|ia64*|m68*|mips*|powerpc*|sparc*|s390*|sh*) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown +])# AC_DEPLIBS_CHECK_METHOD + + +# AC_PROG_NM +# ---------- +# find the pathname to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/${ac_tool_prefix}nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + esac + fi + done + IFS="$lt_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +])# AC_PROG_NM + + +# AC_CHECK_LIBM +# ------------- +# check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +])# AC_CHECK_LIBM + + +# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl convenience library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-convenience to the configure arguments. Note that LIBLTDL +# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If +# DIRECTORY is not provided, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_CONVENIENCE + + +# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl installable library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-install to the configure arguments. Note that LIBLTDL +# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If +# DIRECTORY is not provided and an installed libltdl is not found, it is +# assumed to be `libltdl'. LIBLTDL will be prefixed with '${top_builddir}/' +# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single +# quotes!). If your package is not flat and you're not using automake, +# define top_builddir and top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, lt_dlinit, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_INSTALLABLE + + +# AC_LIBTOOL_CXX +# -------------- +# enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], +[AC_REQUIRE([_LT_AC_LANG_CXX]) +])# AC_LIBTOOL_CXX + + +# _LT_AC_LANG_CXX +# --------------- +AC_DEFUN([_LT_AC_LANG_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([AC_PROG_CXXCPP]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +])# _LT_AC_LANG_CXX + + +# AC_LIBTOOL_F77 +# -------------- +# enable support for Fortran 77 libraries +AC_DEFUN([AC_LIBTOOL_F77], +[AC_REQUIRE([_LT_AC_LANG_F77]) +])# AC_LIBTOOL_F77 + + +# _LT_AC_LANG_F77 +# --------------- +AC_DEFUN([_LT_AC_LANG_F77], +[AC_REQUIRE([AC_PROG_F77]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +])# _LT_AC_LANG_F77 + + +# AC_LIBTOOL_GCJ +# -------------- +# enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ], +[AC_REQUIRE([_LT_AC_LANG_GCJ]) +])# AC_LIBTOOL_GCJ + + +# _LT_AC_LANG_GCJ +# --------------- +AC_DEFUN([_LT_AC_LANG_GCJ], +[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) +])# _LT_AC_LANG_GCJ + + +# AC_LIBTOOL_RC +# -------------- +# enable support for Windows resource files +AC_DEFUN([AC_LIBTOOL_RC], +[AC_REQUIRE([LT_AC_PROG_RC]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) +])# AC_LIBTOOL_RC + + +# AC_LIBTOOL_LANG_C_CONFIG +# ------------------------ +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) +AC_DEFUN([_LT_AC_LANG_C_CONFIG], +[lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + +_LT_AC_SYS_COMPILER + +# +# Check for any special shared library compilation flags. +# +_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)= +if test "$GCC" = no; then + case $host_os in + sco3.2v5*) + _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf' + ;; + esac +fi +if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then + AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries]) + if echo "$old_CC $old_CFLAGS " | grep "[[ ]]$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[ ]]" >/dev/null; then : + else + AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure]) + _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no + fi +fi + + +# +# Check to make sure the static flag actually works. +# +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), + $_LT_AC_TAGVAR(lt_prog_compiler_static, $1), + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF($1) + +# Report which librarie types wil actually be built +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_C_CONFIG + + +# AC_LIBTOOL_LANG_CXX_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) +AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], +[AC_LANG_PUSH(C++) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([AC_PROG_CXXCPP]) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Dependencies to place before and after the object being linked: +_LT_AC_TAGVAR(predep_objects, $1)= +_LT_AC_TAGVAR(postdep_objects, $1)= +_LT_AC_TAGVAR(predeps, $1)= +_LT_AC_TAGVAR(postdeps, $1)= +_LT_AC_TAGVAR(compiler_lib_search_path, $1)= + +# Source file extension for C++ test sources. +ac_ext=cc + +# Object file extension for compiled C++ test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' +else + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + AC_PROG_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +_LT_AC_TAGVAR(ld_shlibs, $1)=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds it's shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case "$cc_basename" in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + freebsd-elf*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + freebsd* | kfreebsd*-gnu) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + ;; + gnu*) + ;; + hpux9*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + *) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC) + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case "$host_cpu" in + ia64*|hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + irix5* | irix6*) + case $cc_basename in + CC) + # SGI C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + linux*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + cxx) + # Compaq C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + m88k*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + mvs*) + case $cc_basename in + cxx) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + openbsd*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; + osf3*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' + ;; + RCC) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~ + $rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + sco*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + lcc) + # Lucid + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + tandem*) + case $cc_basename in + NCC) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; +esac +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_AC_TAGVAR(GCC, $1)="$GXX" +_LT_AC_TAGVAR(LD, $1)="$LD" + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_POSTDEP_PREDEP($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +])# AC_LIBTOOL_LANG_CXX_CONFIG + +# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) +# ------------------------ +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <> "$cfgfile" +ifelse([$1], [], +[#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG], +[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# A language-specific compiler. +CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) + +# Is the compiler the GNU C compiler? +with_gcc=$_LT_AC_TAGVAR(GCC, $1) + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_[]_LT_AC_TAGVAR(LD, $1) + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) + +# Commands used to build and install a shared archive. +archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) +archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) +module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" + +# Set to yes if exported symbols are required. +always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) + +# The commands to list exported symbols. +export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) + +# Symbols that must always be exported. +include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) + +ifelse([$1],[], +[# ### END LIBTOOL CONFIG], +[# ### END LIBTOOL TAG CONFIG: $tagname]) + +__EOF__ + +ifelse([$1],[], [ + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +]) +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi +])# AC_LIBTOOL_CONFIG + + +# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl + +_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI + + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris* | sysv5*) + symcode='[[BDRT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[[]] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + + +# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) +# --------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], +[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) + ifelse([$1],[CXX],[ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case "$cc_basename" in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | kfreebsd*-gnu) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC) + # KAI C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc) + # Intel C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + cxx) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC) + # Rational C++ 2.4.1 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx) + # Digital/Compaq C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + sco*) + case $cc_basename in + CC) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + *) + ;; + esac + ;; + solaris*) + case $cc_basename in + CC) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC) + # Sun C++ 4.x + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc) + # Lucid + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC) + # NonStop-UX NCC 3.20 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + unixware*) + ;; + vxworks*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case "$cc_basename" in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + newsos6) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + linux*) + case $CC in + icc* | ecc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + ccc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + sco3.2v5*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn' + ;; + + solaris*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sunos4*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + uts4*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then + AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), + [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +case "$host_os" in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" + ;; +esac +]) + + +# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) +# ------------------------------------ +# See if the linker supports building shared libraries. +AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], +[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +ifelse([$1],[CXX],[ + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +],[ + runpath_var= + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)= + _LT_AC_TAGVAR(archive_expsym_cmds, $1)= + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown + _LT_AC_TAGVAR(hardcode_automatic, $1)=no + _LT_AC_TAGVAR(module_cmds, $1)= + _LT_AC_TAGVAR(module_expsym_cmds, $1)= + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_AC_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sunos4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_cmds, $1)="$tmp_archive_cmds" + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + if test $supports_anon_versioning = yes; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ +cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ +$echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$tmp_archive_cmds" + fi + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = yes; then + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds it's shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + # see comment about different semantics on the GNU ld section + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + bsdi[[45]]*) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case "$cc_basename" in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10* | hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + *) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + sco3.2v5*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4.2uw2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text' + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv5*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +# +# Do we need to explicitly link libc? +# +case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_AC_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac +])# AC_LIBTOOL_PROG_LD_SHLIBS + + +# _LT_AC_FILE_LTDLL_C +# ------------------- +# Be careful that the start marker always follows a newline. +AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ +])# _LT_AC_FILE_LTDLL_C + + +# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) +# --------------------------------- +AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) + + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + +AC_DEFUN([LT_AC_PROG_RC], +[AC_CHECK_TOOL(RC, windres, no) +]) + +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && break + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_MSG_RESULT([$SED]) +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal/mutex.ac b/src/libs/resiprocate/contrib/db/dist/aclocal/mutex.ac new file mode 100644 index 00000000..959ed4eb --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal/mutex.ac @@ -0,0 +1,635 @@ +# $Id: mutex.ac,v 11.46 2004/07/09 16:23:19 bostic Exp $ + +# POSIX pthreads tests: inter-process safe and intra-process only. +AC_DEFUN(AM_PTHREADS_SHARED, [ +AC_TRY_RUN([ +#include +main() { + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_condattr_t condattr; + pthread_mutexattr_t mutexattr; + exit ( + pthread_condattr_init(&condattr) || + pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) || + pthread_mutexattr_init(&mutexattr) || + pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) || + pthread_cond_init(&cond, &condattr) || + pthread_mutex_init(&mutex, &mutexattr) || + pthread_mutex_lock(&mutex) || + pthread_mutex_unlock(&mutex) || + pthread_mutex_destroy(&mutex) || + pthread_cond_destroy(&cond) || + pthread_condattr_destroy(&condattr) || + pthread_mutexattr_destroy(&mutexattr)); +}], [db_cv_mutex="$1"],, +AC_TRY_LINK([ +#include ],[ + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_condattr_t condattr; + pthread_mutexattr_t mutexattr; + exit ( + pthread_condattr_init(&condattr) || + pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) || + pthread_mutexattr_init(&mutexattr) || + pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) || + pthread_cond_init(&cond, &condattr) || + pthread_mutex_init(&mutex, &mutexattr) || + pthread_mutex_lock(&mutex) || + pthread_mutex_unlock(&mutex) || + pthread_mutex_destroy(&mutex) || + pthread_cond_destroy(&cond) || + pthread_condattr_destroy(&condattr) || + pthread_mutexattr_destroy(&mutexattr)); +], [db_cv_mutex="$1"]))]) +AC_DEFUN(AM_PTHREADS_PRIVATE, [ +AC_TRY_RUN([ +#include +main() { + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_condattr_t condattr; + pthread_mutexattr_t mutexattr; + exit ( + pthread_condattr_init(&condattr) || + pthread_mutexattr_init(&mutexattr) || + pthread_cond_init(&cond, &condattr) || + pthread_mutex_init(&mutex, &mutexattr) || + pthread_mutex_lock(&mutex) || + pthread_mutex_unlock(&mutex) || + pthread_mutex_destroy(&mutex) || + pthread_cond_destroy(&cond) || + pthread_condattr_destroy(&condattr) || + pthread_mutexattr_destroy(&mutexattr)); +}], [db_cv_mutex="$1"],, +AC_TRY_LINK([ +#include ],[ + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_condattr_t condattr; + pthread_mutexattr_t mutexattr; + exit ( + pthread_condattr_init(&condattr) || + pthread_mutexattr_init(&mutexattr) || + pthread_cond_init(&cond, &condattr) || + pthread_mutex_init(&mutex, &mutexattr) || + pthread_mutex_lock(&mutex) || + pthread_mutex_unlock(&mutex) || + pthread_mutex_destroy(&mutex) || + pthread_cond_destroy(&cond) || + pthread_condattr_destroy(&condattr) || + pthread_mutexattr_destroy(&mutexattr)); +], [db_cv_mutex="$1"]))]) + +# Figure out mutexes for this compiler/architecture. +AC_DEFUN(AM_DEFINE_MUTEXES, [ + +# Mutexes we don't test for, but want the #defines to exist for +# other ports. +AH_TEMPLATE(HAVE_MUTEX_VMS, [Define to 1 to use VMS mutexes.]) +AH_TEMPLATE(HAVE_MUTEX_VXWORKS, [Define to 1 to use VxWorks mutexes.]) + +AC_CACHE_CHECK([for mutexes], db_cv_mutex, [ +db_cv_mutex=no + +orig_libs=$LIBS + +# User-specified POSIX or UI mutexes. +# +# There are two different reasons to specify mutexes: First, the application +# is already using one type of mutex and doesn't want to mix-and-match (for +# example, on Solaris, which has POSIX, UI and LWP mutexes). Second, the +# applications POSIX pthreads mutexes don't support inter-process locking, +# but the application wants to use them anyway (for example, some Linux and +# *BSD systems). +# +# Test for LWP threads before testing for UI/POSIX threads, we prefer them +# on Solaris. There's a bug in SunOS 5.7 where applications get pwrite, not +# pwrite64, if they load the C library before the appropriate threads library, +# e.g., tclsh using dlopen to load the DB library. By using LWP threads we +# avoid answering lots of user questions, not to mention the bugs. +# +# Otherwise, test for POSIX threads before UI threads. There are Linux systems +# that support a UI compatibility mode, and applications are more likely to be +# written for POSIX threads than UI threads. +# +# Try and link with a threads library if possible. The problem is the Solaris +# C library has UI/POSIX interface stubs, but they're broken, configuring them +# for inter-process mutexes doesn't return an error, but it doesn't work either. +if test "$db_cv_posixmutexes" = yes; then + db_cv_mutex="posix_only"; +fi +if test "$db_cv_uimutexes" = yes; then + db_cv_mutex="ui_only"; +fi + +# User-specified Win32 mutexes (MinGW build) +if test "$db_cv_mingw" = "yes"; then + db_cv_mutex=win32/gcc +fi + +# LWP threads: _lwp_XXX +if test "$db_cv_mutex" = no; then +AC_TRY_LINK([ +#include ],[ + static lwp_mutex_t mi = SHAREDMUTEX; + static lwp_cond_t ci = SHAREDCV; + lwp_mutex_t mutex = mi; + lwp_cond_t cond = ci; + exit ( + _lwp_mutex_lock(&mutex) || + _lwp_mutex_unlock(&mutex)); +], [db_cv_mutex="Solaris/lwp"]) +fi + +# POSIX.1 pthreads: pthread_XXX +# +# If the user specified we use POSIX pthreads mutexes, and we fail to find the +# full interface, try and configure for just intra-process support. +if test "$db_cv_mutex" = no -o "$db_cv_mutex" = "posix_only"; then + LIBS="$LIBS -lpthread" + AM_PTHREADS_SHARED("POSIX/pthreads/library") + LIBS="$orig_libs" +fi +if test "$db_cv_mutex" = no -o "$db_cv_mutex" = "posix_only"; then + AM_PTHREADS_SHARED("POSIX/pthreads") +fi +if test "$db_cv_mutex" = "posix_only"; then + AM_PTHREADS_PRIVATE("POSIX/pthreads/private") +fi +if test "$db_cv_mutex" = "posix_only"; then + LIBS="$LIBS -lpthread" + AM_PTHREADS_PRIVATE("POSIX/pthreads/library/private") + LIBS="$orig_libs" +fi +if test "$db_cv_mutex" = "posix_only"; then + AC_MSG_ERROR([unable to find POSIX 1003.1 mutex interfaces]) +fi + +# UI threads: thr_XXX +if test "$db_cv_mutex" = no -o "$db_cv_mutex" = "ui_only"; then +LIBS="$LIBS -lthread" +AC_TRY_LINK([ +#include +#include ],[ + mutex_t mutex; + cond_t cond; + int type = USYNC_PROCESS; + exit ( + mutex_init(&mutex, type, NULL) || + cond_init(&cond, type, NULL) || + mutex_lock(&mutex) || + mutex_unlock(&mutex)); +], [db_cv_mutex="UI/threads/library"]) +LIBS="$orig_libs" +fi +if test "$db_cv_mutex" = no -o "$db_cv_mutex" = "ui_only"; then +AC_TRY_LINK([ +#include +#include ],[ + mutex_t mutex; + cond_t cond; + int type = USYNC_PROCESS; + exit ( + mutex_init(&mutex, type, NULL) || + cond_init(&cond, type, NULL) || + mutex_lock(&mutex) || + mutex_unlock(&mutex)); +], [db_cv_mutex="UI/threads"]) +fi +if test "$db_cv_mutex" = "ui_only"; then + AC_MSG_ERROR([unable to find UI mutex interfaces]) +fi + +# msemaphore: HPPA only +# Try HPPA before general msem test, it needs special alignment. +if test "$db_cv_mutex" = no; then +AC_TRY_LINK([ +#include ],[ +#if defined(__hppa) + typedef msemaphore tsl_t; + msemaphore x; + msem_init(&x, 0); + msem_lock(&x, 0); + msem_unlock(&x, 0); + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="HP/msem_init"]) +fi + +# msemaphore: AIX, OSF/1 +if test "$db_cv_mutex" = no; then +AC_TRY_LINK([ +#include +#include ],[ + typedef msemaphore tsl_t; + msemaphore x; + msem_init(&x, 0); + msem_lock(&x, 0); + msem_unlock(&x, 0); + exit(0); +], [db_cv_mutex="UNIX/msem_init"]) +fi + +# ReliantUNIX +if test "$db_cv_mutex" = no; then +LIBS="$LIBS -lmproc" +AC_TRY_LINK([ +#include ],[ + typedef spinlock_t tsl_t; + spinlock_t x; + initspin(&x, 1); + cspinlock(&x); + spinunlock(&x); +], [db_cv_mutex="ReliantUNIX/initspin"]) +LIBS="$orig_libs" +fi + +# SCO: UnixWare has threads in libthread, but OpenServer doesn't. +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if defined(__USLC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="SCO/x86/cc-assembly"]) +fi + +# abilock_t: SGI +if test "$db_cv_mutex" = no; then +AC_TRY_LINK([ +#include ],[ + typedef abilock_t tsl_t; + abilock_t x; + init_lock(&x); + acquire_lock(&x); + release_lock(&x); +], [db_cv_mutex="SGI/init_lock"]) +fi + +# sema_t: Solaris +# The sema_XXX calls do not work on Solaris 5.5. I see no reason to ever +# turn this test on, unless we find some other platform that uses the old +# POSIX.1 interfaces. (I plan to move directly to pthreads on Solaris.) +if test "$db_cv_mutex" = DOESNT_WORK; then +AC_TRY_LINK([ +#include ],[ + typedef sema_t tsl_t; + sema_t x; + sema_init(&x, 1, USYNC_PROCESS, NULL); + sema_wait(&x); + sema_post(&x); +], [db_cv_mutex="UNIX/sema_init"]) +fi + +# _lock_try/_lock_clear: Solaris +# On Solaris systems without Pthread or UI mutex interfaces, DB uses the +# undocumented _lock_try _lock_clear function calls instead of either the +# sema_trywait(3T) or sema_wait(3T) function calls. This is because of +# problems in those interfaces in some releases of the Solaris C library. +if test "$db_cv_mutex" = no; then +AC_TRY_LINK([ +#include ],[ + typedef lock_t tsl_t; + lock_t x; + _lock_try(&x); + _lock_clear(&x); +], [db_cv_mutex="Solaris/_lock_try"]) +fi + +# _check_lock/_clear_lock: AIX +if test "$db_cv_mutex" = no; then +AC_TRY_LINK([ +#include ],[ + int x; + _check_lock(&x,0,1); + _clear_lock(&x,0); +], [db_cv_mutex="AIX/_check_lock"]) +fi + +# _spin_lock_try/_spin_unlock: Apple/Darwin +if test "$db_cv_mutex" = no; then +AC_TRY_LINK(,[ + int x; + _spin_lock_try(&x); + _spin_unlock(&x); +], [db_cv_mutex="Darwin/_spin_lock_try"]) +fi + +# Tru64/cc +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if defined(__alpha) && defined(__DECC) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="Tru64/cc-assembly"]) +fi + +# Alpha/gcc +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if defined(__alpha) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="ALPHA/gcc-assembly"]) +fi + +# ARM/gcc: Linux +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if defined(__arm__) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="ARM/gcc-assembly"]) +fi + +# PaRisc/gcc: HP/UX +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if (defined(__hppa) || defined(__hppa__)) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="HPPA/gcc-assembly"]) +fi + +# PPC/gcc: +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if (defined(__powerpc__) || defined(__ppc__)) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="PPC/gcc-assembly"]) +fi + +# Sparc/gcc: SunOS, Solaris +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if defined(__sparc__) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="Sparc/gcc-assembly"]) +fi + +# 68K/gcc: SunOS +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if (defined(mc68020) || defined(sun3)) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="68K/gcc-assembly"]) +fi + +# x86/gcc: FreeBSD, NetBSD, BSD/OS, Linux +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if (defined(i386) || defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="x86/gcc-assembly"]) +fi + +# S390/cc: IBM OS/390 Unix +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if defined(__MVS__) && defined(__IBMC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="S390/cc-assembly"]) +fi + +# S390/gcc: Linux +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if defined(__s390__) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="S390/gcc-assembly"]) +fi + +# ia86/gcc: Linux +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if defined(__ia64) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="ia64/gcc-assembly"]) +fi + +# uts/cc: UTS +if test "$db_cv_mutex" = no; then +AC_TRY_COMPILE(,[ +#if defined(_UTS) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif +], [db_cv_mutex="UTS/cc-assembly"]) +fi + +# default to UNIX fcntl system call mutexes. +if test "$db_cv_mutex" = no; then + db_cv_mutex="UNIX/fcntl" +fi +]) + +case "$db_cv_mutex" in +68K/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_68K_GCC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_68K_GCC_ASSEMBLY, + [Define to 1 to use the GCC compiler and 68K assembly language mutexes.]);; +AIX/_check_lock) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_AIX_CHECK_LOCK) + AH_TEMPLATE(HAVE_MUTEX_AIX_CHECK_LOCK, + [Define to 1 to use the AIX _check_lock mutexes.]);; +Darwin/_spin_lock_try) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY) + AH_TEMPLATE(HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY, + [Define to 1 to use the Apple/Darwin _spin_lock_try mutexes.]);; +ALPHA/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_ALPHA_GCC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_ALPHA_GCC_ASSEMBLY, + [Define to 1 to use the GCC compiler and Alpha assembly language mutexes.]);; +ARM/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_ARM_GCC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_ARM_GCC_ASSEMBLY, + [Define to 1 to use the GCC compiler and ARM assembly language mutexes.]);; +HP/msem_init) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_HPPA_MSEM_INIT) + AH_TEMPLATE(HAVE_MUTEX_HPPA_MSEM_INIT, + [Define to 1 to use the msem_XXX mutexes on HP-UX.]);; +HPPA/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_HPPA_GCC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_HPPA_GCC_ASSEMBLY, + [Define to 1 to use the GCC compiler and PaRisc assembly language mutexes.]);; +ia64/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_IA64_GCC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_IA64_GCC_ASSEMBLY, + [Define to 1 to use the GCC compiler and IA64 assembly language mutexes.]);; +POSIX/pthreads) ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_PTHREADS) + AH_TEMPLATE(HAVE_MUTEX_PTHREADS, + [Define to 1 to use POSIX 1003.1 pthread_XXX mutexes.]);; +POSIX/pthreads/private) ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_PTHREADS) + AH_TEMPLATE(HAVE_MUTEX_PTHREADS, + [Define to 1 to use POSIX 1003.1 pthread_XXX mutexes.]) + AC_DEFINE(HAVE_MUTEX_THREAD_ONLY) + AH_TEMPLATE(HAVE_MUTEX_THREAD_ONLY, + [Define to 1 to configure mutexes intra-process only.]);; +POSIX/pthreads/library) LIBS="$LIBS -lpthread" + LIBJSO_LIBS="$LIBJSO_LIBS -lpthread" + LIBTSO_LIBS="$LIBTSO_LIBS -lpthread" + ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_PTHREADS) + AH_TEMPLATE(HAVE_MUTEX_PTHREADS, + [Define to 1 to use POSIX 1003.1 pthread_XXX mutexes.]);; +POSIX/pthreads/library/private) + LIBS="$LIBS -lpthread" + LIBJSO_LIBS="$LIBJSO_LIBS -lpthread" + LIBTSO_LIBS="$LIBTSO_LIBS -lpthread" + ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_PTHREADS) + AH_TEMPLATE(HAVE_MUTEX_PTHREADS, + [Define to 1 to use POSIX 1003.1 pthread_XXX mutexes.]) + AC_DEFINE(HAVE_MUTEX_THREAD_ONLY) + AH_TEMPLATE(HAVE_MUTEX_THREAD_ONLY, + [Define to 1 to configure mutexes intra-process only.]);; +PPC/gcc-assembly) + ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_PPC_GCC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_PPC_GCC_ASSEMBLY, + [Define to 1 to use the GCC compiler and PowerPC assembly language mutexes.]);; +ReliantUNIX/initspin) LIBS="$LIBS -lmproc" + ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_RELIANTUNIX_INITSPIN) + AH_TEMPLATE(HAVE_MUTEX_RELIANTUNIX_INITSPIN, + [Define to 1 to use Reliant UNIX initspin mutexes.]);; +S390/cc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_S390_CC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_S390_CC_ASSEMBLY, + [Define to 1 to use the IBM C compiler and S/390 assembly language mutexes.]);; +S390/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_S390_GCC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_S390_GCC_ASSEMBLY, + [Define to 1 to use the GCC compiler and S/390 assembly language mutexes.]);; +SCO/x86/cc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_SCO_X86_CC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_SCO_X86_CC_ASSEMBLY, + [Define to 1 to use the SCO compiler and x86 assembly language mutexes.]);; +SGI/init_lock) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_SGI_INIT_LOCK) + AH_TEMPLATE(HAVE_MUTEX_SGI_INIT_LOCK, + [Define to 1 to use the SGI XXX_lock mutexes.]);; +Solaris/_lock_try) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_SOLARIS_LOCK_TRY) + AH_TEMPLATE(HAVE_MUTEX_SOLARIS_LOCK_TRY, + [Define to 1 to use the Solaris _lock_XXX mutexes.]);; +Solaris/lwp) ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_SOLARIS_LWP) + AH_TEMPLATE(HAVE_MUTEX_SOLARIS_LWP, + [Define to 1 to use the Solaris lwp threads mutexes.]);; +Sparc/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_SPARC_GCC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_SPARC_GCC_ASSEMBLY, + [Define to 1 to use the GCC compiler and Sparc assembly language mutexes.]);; +Tru64/cc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_TRU64_CC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_TRU64_CC_ASSEMBLY, + [Define to 1 to use the CC compiler and Tru64 assembly language mutexes.]);; + +UI/threads) ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_UI_THREADS) + AH_TEMPLATE(HAVE_MUTEX_UI_THREADS, + [Define to 1 to use the UNIX International mutexes.]);; +UI/threads/library) LIBS="$LIBS -lthread" + ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_UI_THREADS) + AH_TEMPLATE(HAVE_MUTEX_UI_THREADS, + [Define to 1 to use the UNIX International mutexes.]);; +UNIX/msem_init) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_MSEM_INIT) + AH_TEMPLATE(HAVE_MUTEX_MSEM_INIT, + [Define to 1 to use the msem_XXX mutexes on systems other than HP-UX.]);; +UNIX/sema_init) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_SEMA_INIT) + AH_TEMPLATE(HAVE_MUTEX_SEMA_INIT, + [Define to 1 to use the obsolete POSIX 1003.1 sema_XXX mutexes.]);; +UTS/cc-assembly) ADDITIONAL_OBJS="uts4.cc${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_UTS_CC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_UTS_CC_ASSEMBLY, + [Define to 1 to use the UTS compiler and assembly language mutexes.]);; +win32) ADDITIONAL_OBJS="mut_win32${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_WIN32) + AH_TEMPLATE(HAVE_MUTEX_WIN32, [Define to 1 to use the MSVC compiler and Windows mutexes.]);; +win32/gcc) ADDITIONAL_OBJS="mut_win32${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_WIN32_GCC) + AH_TEMPLATE(HAVE_MUTEX_WIN32_GCC, [Define to 1 to use the GCC compiler and Windows mutexes.]);; +x86/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_X86_GCC_ASSEMBLY) + AH_TEMPLATE(HAVE_MUTEX_X86_GCC_ASSEMBLY, + [Define to 1 to use the GCC compiler and x86 assembly language mutexes.]);; +UNIX/fcntl) AC_MSG_WARN( + [NO FAST MUTEXES FOUND FOR THIS COMPILER/ARCHITECTURE.]) + ADDITIONAL_OBJS="mut_fcntl${o} $ADDITIONAL_OBJS" + AC_DEFINE(HAVE_MUTEX_FCNTL) + AH_TEMPLATE(HAVE_MUTEX_FCNTL, + [Define to 1 to use the UNIX fcntl system call mutexes.]);; +*) AC_MSG_ERROR([Unknown mutex interface: $db_cv_mutex]);; +esac + +if test "$db_cv_mutex" != "UNIX/fcntl"; then + AC_DEFINE(HAVE_MUTEX_THREADS) + AH_TEMPLATE(HAVE_MUTEX_THREADS, + [Define to 1 if fast mutexes are available.]) +fi + +# There are 3 classes of mutexes: +# +# 1: Mutexes requiring no cleanup, for example, test-and-set mutexes. +# 2: Mutexes that must be destroyed, but which don't hold permanent system +# resources, for example, pthread mutexes on MVS aka OS/390 aka z/OS. +# 3: Mutexes that must be destroyed, even after the process is gone, for +# example, pthread mutexes on QNX and binary semaphores on VxWorks. +# +# DB cannot currently distinguish between #2 and #3 because DB does not know +# if the application is running environment recovery as part of startup and +# does not need to do cleanup, or if the environment is being removed and/or +# recovered in a loop in the application, and so does need to clean up. If +# we get it wrong, we're going to call the mutex destroy routine on a random +# piece of memory, which usually works, but just might drop core. For now, +# we group #2 and #3 into the HAVE_MUTEX_SYSTEM_RESOURCES define, until we +# have a better solution or reason to solve this in a general way -- so far, +# the places we've needed to handle this are few. +AH_TEMPLATE(HAVE_MUTEX_SYSTEM_RESOURCES, + [Define to 1 if mutexes hold system resources.]) + +case "$host_os$db_cv_mutex" in +*qnx*POSIX/pthread*|openedition*POSIX/pthread*) + AC_DEFINE(HAVE_MUTEX_SYSTEM_RESOURCES);; +esac]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal/options.ac b/src/libs/resiprocate/contrib/db/dist/aclocal/options.ac new file mode 100644 index 00000000..b770fc44 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal/options.ac @@ -0,0 +1,292 @@ +# $Id: options.ac,v 11.37 2004/06/10 16:38:18 bostic Exp $ + +# Process user-specified options. +AC_DEFUN(AM_OPTIONS_SET, [ + +# --enable-bigfile was the configuration option that Berkeley DB used before +# autoconf 2.50 was released (which had --enable-largefile integrated in). +AC_ARG_ENABLE(bigfile, + [AC_HELP_STRING([--disable-bigfile], + [Obsolete; use --disable-largefile instead.])], + [AC_MSG_ERROR( + [--enable-bigfile no longer supported, use --enable-largefile])]) + +AC_MSG_CHECKING(if --disable-cryptography option specified) +AC_ARG_ENABLE(cryptography, + AC_HELP_STRING([--disable-cryptography], + [Do not build database cryptography support.]),, enableval="yes") +db_cv_build_cryptography="$enableval" +case "$enableval" in + no) AC_MSG_RESULT(yes);; +yes) AC_MSG_RESULT(no);; +esac + +AC_MSG_CHECKING(if --disable-hash option specified) +AC_ARG_ENABLE(hash, + AC_HELP_STRING([--disable-hash], + [Do not build Hash access method.]),, enableval="yes") +db_cv_build_hash="$enableval" +case "$enableval" in + no) AC_MSG_RESULT(yes);; +yes) AC_MSG_RESULT(no);; +esac + +AC_MSG_CHECKING(if --disable-queue option specified) +AC_ARG_ENABLE(queue, + AC_HELP_STRING([--disable-queue], + [Do not build Queue access method.]),, enableval="yes") +db_cv_build_queue="$enableval" +case "$enableval" in + no) AC_MSG_RESULT(yes);; +yes) AC_MSG_RESULT(no);; +esac + +AC_MSG_CHECKING(if --disable-replication option specified) +AC_ARG_ENABLE(replication, + AC_HELP_STRING([--disable-replication], + [Do not build database replication support.]),, enableval="yes") +db_cv_build_replication="$enableval" +case "$enableval" in + no) AC_MSG_RESULT(yes);; +yes) AC_MSG_RESULT(no);; +esac + +AC_MSG_CHECKING(if --disable-statistics option specified) +AC_ARG_ENABLE(statistics, + AC_HELP_STRING([--disable-statistics], + [Do not build statistics support.]),, enableval="yes") +db_cv_build_statistics="$enableval" +case "$enableval" in + no) AC_MSG_RESULT(yes);; +yes) AC_MSG_RESULT(no);; +esac + +AC_MSG_CHECKING(if --disable-verify option specified) +AC_ARG_ENABLE(verify, + AC_HELP_STRING([--disable-verify], + [Do not build database verification support.]),, enableval="yes") +db_cv_build_verify="$enableval" +case "$enableval" in + no) AC_MSG_RESULT(yes);; +yes) AC_MSG_RESULT(no);; +esac + +AC_MSG_CHECKING(if --enable-compat185 option specified) +AC_ARG_ENABLE(compat185, + [AC_HELP_STRING([--enable-compat185], + [Build DB 1.85 compatibility API.])], + [db_cv_compat185="$enable_compat185"], [db_cv_compat185="no"]) +AC_MSG_RESULT($db_cv_compat185) + +AC_MSG_CHECKING(if --enable-cxx option specified) +AC_ARG_ENABLE(cxx, + [AC_HELP_STRING([--enable-cxx], + [Build C++ API.])], + [db_cv_cxx="$enable_cxx"], [db_cv_cxx="no"]) +AC_MSG_RESULT($db_cv_cxx) + +AC_MSG_CHECKING(if --enable-debug option specified) +AC_ARG_ENABLE(debug, + [AC_HELP_STRING([--enable-debug], + [Build a debugging version.])], + [db_cv_debug="$enable_debug"], [db_cv_debug="no"]) +AC_MSG_RESULT($db_cv_debug) + +AC_MSG_CHECKING(if --enable-debug_rop option specified) +AC_ARG_ENABLE(debug_rop, + [AC_HELP_STRING([--enable-debug_rop], + [Build a version that logs read operations.])], + [db_cv_debug_rop="$enable_debug_rop"], [db_cv_debug_rop="no"]) +AC_MSG_RESULT($db_cv_debug_rop) + +AC_MSG_CHECKING(if --enable-debug_wop option specified) +AC_ARG_ENABLE(debug_wop, + [AC_HELP_STRING([--enable-debug_wop], + [Build a version that logs write operations.])], + [db_cv_debug_wop="$enable_debug_wop"], [db_cv_debug_wop="no"]) +AC_MSG_RESULT($db_cv_debug_wop) + +AC_MSG_CHECKING(if --enable-diagnostic option specified) +AC_ARG_ENABLE(diagnostic, + [AC_HELP_STRING([--enable-diagnostic], + [Build a version with run-time diagnostics.])], + [db_cv_diagnostic="$enable_diagnostic"], [db_cv_diagnostic="no"]) +if test "$db_cv_diagnostic" = "yes"; then + AC_MSG_RESULT($db_cv_diagnostic) +fi +if test "$db_cv_diagnostic" = "no" -a "$db_cv_debug_rop" = "yes"; then + db_cv_diagnostic="yes" + AC_MSG_RESULT([by --enable-debug_rop]) +fi +if test "$db_cv_diagnostic" = "no" -a "$db_cv_debug_wop" = "yes"; then + db_cv_diagnostic="yes" + AC_MSG_RESULT([by --enable-debug_wop]) +fi +if test "$db_cv_diagnostic" = "no"; then + AC_MSG_RESULT($db_cv_diagnostic) +fi + +AC_MSG_CHECKING(if --enable-dump185 option specified) +AC_ARG_ENABLE(dump185, + [AC_HELP_STRING([--enable-dump185], + [Build db_dump185(1) to dump 1.85 databases.])], + [db_cv_dump185="$enable_dump185"], [db_cv_dump185="no"]) +AC_MSG_RESULT($db_cv_dump185) + +AC_MSG_CHECKING(if --enable-java option specified) +AC_ARG_ENABLE(java, + [AC_HELP_STRING([--enable-java], + [Build Java API.])], + [db_cv_java="$enable_java"], [db_cv_java="no"]) +AC_MSG_RESULT($db_cv_java) + +AC_MSG_CHECKING(if --enable-mingw option specified) +AC_ARG_ENABLE(mingw, + [AC_HELP_STRING([--enable-mingw], + [Build Berkeley DB for MinGW.])], + [db_cv_mingw="$enable_mingw"], [db_cv_mingw="no"]) +AC_MSG_RESULT($db_cv_mingw) + +AC_MSG_CHECKING(if --enable-o_direct option specified) +AC_ARG_ENABLE(o_direct, + [AC_HELP_STRING([--enable-o_direct], + [Enable the O_DIRECT flag for direct I/O.])], + [db_cv_o_direct="$enable_o_direct"], [db_cv_o_direct="no"]) +AC_MSG_RESULT($db_cv_o_direct) + +AC_MSG_CHECKING(if --enable-posixmutexes option specified) +AC_ARG_ENABLE(posixmutexes, + [AC_HELP_STRING([--enable-posixmutexes], + [Force use of POSIX standard mutexes.])], + [db_cv_posixmutexes="$enable_posixmutexes"], [db_cv_posixmutexes="no"]) +AC_MSG_RESULT($db_cv_posixmutexes) + +AC_MSG_CHECKING(if --enable-rpc option specified) +AC_ARG_ENABLE(rpc, + [AC_HELP_STRING([--enable-rpc], + [Build RPC client/server.])], + [db_cv_rpc="$enable_rpc"], [db_cv_rpc="no"]) +AC_MSG_RESULT($db_cv_rpc) + +AC_MSG_CHECKING(if --enable-smallbuild option specified) +AC_ARG_ENABLE(smallbuild, + [AC_HELP_STRING([--enable-smallbuild], + [Build small footprint version of the library.])], + [db_cv_smallbuild="$enable_smallbuild"], [db_cv_smallbuild="no"]) +if test "$db_cv_smallbuild" = "yes"; then + db_cv_build_cryptography="no" + db_cv_build_hash="no" + db_cv_build_queue="no" + db_cv_build_replication="no" + db_cv_build_statistics="no" + db_cv_build_verify="no" +fi +AC_MSG_RESULT($db_cv_smallbuild) + +AC_MSG_CHECKING(if --enable-tcl option specified) +AC_ARG_ENABLE(tcl, + [AC_HELP_STRING([--enable-tcl], + [Build Tcl API.])], + [db_cv_tcl="$enable_tcl"], [db_cv_tcl="no"]) +AC_MSG_RESULT($db_cv_tcl) + +AC_MSG_CHECKING(if --enable-test option specified) +AC_ARG_ENABLE(test, + [AC_HELP_STRING([--enable-test], + [Configure to run the test suite.])], + [db_cv_test="$enable_test"], [db_cv_test="no"]) +AC_MSG_RESULT($db_cv_test) + +AC_MSG_CHECKING(if --enable-uimutexes option specified) +AC_ARG_ENABLE(uimutexes, + [AC_HELP_STRING([--enable-uimutexes], + [Force use of Unix International mutexes.])], + [db_cv_uimutexes="$enable_uimutexes"], [db_cv_uimutexes="no"]) +AC_MSG_RESULT($db_cv_uimutexes) + +AC_MSG_CHECKING(if --enable-umrw option specified) +AC_ARG_ENABLE(umrw, + [AC_HELP_STRING([--enable-umrw], + [Mask harmless uninitialized memory read/writes.])], + [db_cv_umrw="$enable_umrw"], [db_cv_umrw="no"]) +AC_MSG_RESULT($db_cv_umrw) + +AC_MSG_CHECKING(if --with-mutex=MUTEX option specified) +AC_ARG_WITH(mutex, + [AC_HELP_STRING([--with-mutex=MUTEX], + [Selection of non-standard mutexes.])], + [with_mutex="$withval"], [with_mutex="no"]) +if test "$with_mutex" = "yes"; then + AC_MSG_ERROR([--with-mutex requires a mutex name argument]) +fi +if test "$with_mutex" != "no"; then + db_cv_mutex="$with_mutex" +fi +AC_MSG_RESULT($with_mutex) + +AH_TEMPLATE(MUTEX_ALIGN, + [Define to a value if using non-standard mutex alignment.]) +AC_MSG_CHECKING(if --with-mutexalign=ALIGNMENT option specified) +AC_ARG_WITH(mutexalign, + [AC_HELP_STRING([--with-mutexalign=ALIGNMENT], + [Selection of non-standard mutex alignment.])], + [with_mutexalign="$withval"], [with_mutexalign="no"]) +if test "$with_mutexalign" = "yes"; then + AC_MSG_ERROR([--with-mutexalign requires a mutex alignment argument]) +fi +if test "$with_mutexalign" != "no"; then + AC_DEFINE_UNQUOTED(MUTEX_ALIGN, $with_mutexalign) +fi +AC_MSG_RESULT($with_mutexalign) + +AC_MSG_CHECKING([if --with-tcl=DIR option specified]) +AC_ARG_WITH(tcl, + [AC_HELP_STRING([--with-tcl=DIR], + [Directory location of tclConfig.sh.])], + [with_tclconfig="$withval"], [with_tclconfig="no"]) +AC_MSG_RESULT($with_tclconfig) +if test "$with_tclconfig" != "no"; then + db_cv_tcl="yes" +fi + +AC_MSG_CHECKING([if --with-uniquename=NAME option specified]) +AC_ARG_WITH(uniquename, + [AC_HELP_STRING([--with-uniquename=NAME], + [Build a uniquely named library.])], + [with_uniquename="$withval"], [with_uniquename="no"]) +if test "$with_uniquename" = "no"; then + db_cv_uniquename="no" + DB_VERSION_UNIQUE_NAME="" + AC_MSG_RESULT($with_uniquename) +else + db_cv_uniquename="yes" + if test "$with_uniquename" = "yes"; then + DB_VERSION_UNIQUE_NAME="__EDIT_DB_VERSION_UNIQUE_NAME__" + else + DB_VERSION_UNIQUE_NAME="$with_uniquename" + fi + AC_MSG_RESULT($DB_VERSION_UNIQUE_NAME) +fi + +# Test requires Tcl +if test "$db_cv_test" = "yes"; then + if test "$db_cv_tcl" = "no"; then + AC_MSG_ERROR([--enable-test requires --enable-tcl]) + fi +fi + +# Uniquename excludes C++, Java, RPC. +if test "$db_cv_uniquename" = "yes"; then + if test "$db_cv_rpc" = "yes"; then + AC_MSG_ERROR( + [--with-uniquename is not compatible with --enable-rpc]) + fi + if test "$db_cv_cxx" = "yes"; then + AC_MSG_ERROR( + [--with-uniquename is not compatible with --enable-cxx]) + fi + if test "$db_cv_java" = "yes"; then + AC_MSG_ERROR( + [--with-uniquename is not compatible with --enable-java]) + fi +fi]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal/programs.ac b/src/libs/resiprocate/contrib/db/dist/aclocal/programs.ac new file mode 100644 index 00000000..db6b4f03 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal/programs.ac @@ -0,0 +1,71 @@ +# $Id: programs.ac,v 11.22 2004/06/10 16:38:18 bostic Exp $ + +# Check for programs used in building/installation. +AC_DEFUN(AM_PROGRAMS_SET, [ + +AC_CHECK_TOOL(db_cv_path_ar, ar, missing_ar) +if test "$db_cv_path_ar" = missing_ar; then + AC_MSG_ERROR([No ar utility found.]) +fi + +AC_CHECK_TOOL(db_cv_path_chmod, chmod, missing_chmod) +if test "$db_cv_path_chmod" = missing_chmod; then + AC_MSG_ERROR([No chmod utility found.]) +fi + +AC_CHECK_TOOL(db_cv_path_cp, cp, missing_cp) +if test "$db_cv_path_cp" = missing_cp; then + AC_MSG_ERROR([No cp utility found.]) +fi + +AC_CHECK_TOOL(db_cv_path_ln, ln, missing_ln) +if test "$db_cv_path_ln" = missing_ln; then + AC_MSG_ERROR([No ln utility found.]) +fi + +AC_CHECK_TOOL(db_cv_path_mkdir, mkdir, missing_mkdir) +if test "$db_cv_path_mkdir" = missing_mkdir; then + AC_MSG_ERROR([No mkdir utility found.]) +fi + +# We need a complete path for ranlib, because it doesn't exist on some +# architectures because the ar utility packages the library itself. +AC_CHECK_TOOL(path_ranlib, ranlib, missing_ranlib) +AC_PATH_PROG(db_cv_path_ranlib, $path_ranlib, missing_ranlib) + +AC_CHECK_TOOL(db_cv_path_rm, rm, missing_rm) +if test "$db_cv_path_rm" = missing_rm; then + AC_MSG_ERROR([No rm utility found.]) +fi + +if test "$db_cv_rpc" = "yes"; then + AC_CHECK_TOOL(db_cv_path_rpcgen, rpcgen, missing_rpcgen) + if test "$db_cv_path_rpcgen" = missing_rpcgen; then + AC_MSG_ERROR([No rpcgen utility found.]) + fi +fi + +# We need a complete path for sh, because some implementations of make +# get upset if SHELL is set to just the command name. +AC_CHECK_TOOL(path_sh, sh, missing_sh) +AC_PATH_PROG(db_cv_path_sh, $path_sh, missing_sh) +if test "$db_cv_path_sh" = missing_sh; then + AC_MSG_ERROR([No sh utility found.]) +fi + +# Don't strip the binaries if --enable-debug was specified. +if test "$db_cv_debug" = yes; then + db_cv_path_strip=debug_build_no_strip +else + AC_CHECK_TOOL(path_strip, strip, missing_strip) + AC_PATH_PROG(db_cv_path_strip, $path_strip, missing_strip) +fi + +if test "$db_cv_test" = "yes"; then + AC_CHECK_TOOL(db_cv_path_kill, kill, missing_kill) + if test "$db_cv_path_kill" = missing_kill; then + AC_MSG_ERROR([No kill utility found.]) + fi +fi + +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal/rpc.ac b/src/libs/resiprocate/contrib/db/dist/aclocal/rpc.ac new file mode 100644 index 00000000..7d7f4dab --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal/rpc.ac @@ -0,0 +1,83 @@ +# $Id: rpc.ac,v 11.9 2004/09/27 21:33:48 mjc Exp $ + +# Try and configure RPC support. +AC_DEFUN(AM_RPC_CONFIGURE, [ + AC_DEFINE(HAVE_RPC) + AH_TEMPLATE(HAVE_RPC, [Define to 1 if building RPC client/server.]) + + # We use the target's rpcgen utility because it may be architecture + # specific, for example, 32- or 64-bit specific. + XDR_FILE=$srcdir/../rpc_server/db_server.x + + # Prefer the -C option to rpcgen which generates ANSI C-conformant + # code. + RPCGEN="rpcgen -C" + AC_MSG_CHECKING(["$RPCGEN" build of db_server.h]) + $RPCGEN -h $XDR_FILE > db_server.h 2>/dev/null + if test $? -ne 0; then + AC_MSG_RESULT([no]) + + # Try rpcgen without the -C option. + RPCGEN="rpcgen" + AC_MSG_CHECKING(["$RPCGEN" build of db_server.h]) + $RPCGEN -h $XDR_FILE > db_server.h 2>/dev/null + if test $? -ne 0; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR( + [Unable to build RPC support: $RPCGEN failed.]) + fi + fi + + # Some rpcgen programs generate a set of client stubs called something + # like __db_env_create_4003 and functions on the server to handle the + # request called something like __db_env_create_4003_svc. Others + # expect client and server stubs to both be called __db_env_create_4003. + # + # We have to generate code in whichever format rpcgen expects, and the + # only reliable way to do that is to check what is in the db_server.h + # file we just created. + if grep "env_create_[[0-9]]*_svc" db_server.h >/dev/null 2>&1 ; then + sed 's/__SVCSUFFIX__/_svc/' \ + < $srcdir/../rpc_server/c/gen_db_server.c > gen_db_server.c + else + sed 's/__SVCSUFFIX__//' \ + < $srcdir/../rpc_server/c/gen_db_server.c > gen_db_server.c + fi + + AC_MSG_RESULT([yes]) + + $RPCGEN -l $XDR_FILE | + sed -e 's/^#include.*db_server.h.*/#include "db_server.h"/' \ + -e '1,/^#include/s/^#include/#include "db_config.h"\ +&/' > db_server_clnt.c + + $RPCGEN -s tcp $XDR_FILE | + sed -e 's/^#include.*db_server.h.*/#include "db_server.h"/' \ + -e 's/^main *()/__dbsrv_main()/' \ + -e 's/^main *(.*argc.*argv.*)/__dbsrv_main(int argc, char *argv[])/' \ + -e '/^db_rpc_serverprog/,/^}/{' \ + -e 's/return;//' \ + -e 's/^}/__dbsrv_timeout(0);}/' \ + -e '}' \ + -e '1,/^#include/s/^#include/#include "db_config.h"\ +&/' > db_server_svc.c + + $RPCGEN -c $XDR_FILE | + sed -e 's/^#include.*db_server.h.*/#include "db_server.h"/' \ + -e '1,/^#include/s/^#include/#include "db_config.h"\ +&/' > db_server_xdr.c + + RPC_SERVER_H=db_server.h + RPC_CLIENT_OBJS="\$(RPC_CLIENT_OBJS)" + ADDITIONAL_PROGS="berkeley_db_svc $ADDITIONAL_PROGS" + + case "$host_os" in + hpux*) + AC_CHECK_FUNC(svc_run,, + AC_CHECK_LIB(nsl, svc_run, + LIBS="-lnsl $LIBS"; LIBTSO_LIBS="-lnsl $LIBTSO_LIBS"; + LIBJSO_LIBS="-lnsl $LIBJSO_LIBS"));; + solaris*) + AC_CHECK_FUNC(svc_run,, AC_CHECK_LIB(nsl, svc_run));; + esac +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal/sequence.ac b/src/libs/resiprocate/contrib/db/dist/aclocal/sequence.ac new file mode 100644 index 00000000..ca320b23 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal/sequence.ac @@ -0,0 +1,76 @@ +# $Id: sequence.ac,v 1.3 2004/10/28 18:14:30 bostic Exp $ + +# Try and configure sequence support. +AC_DEFUN(AM_SEQUENCE_CONFIGURE, [ + AC_MSG_CHECKING([for 64-bit integral type support for sequences]) + db_cv_build_sequence="yes" + + # Have to have found 64-bit types to support sequences. If we don't + # find the native types, we try and create our own. + if test "$ac_cv_type_int64_t" = "no" -a -z "$int64_decl"; then + db_cv_build_sequence="no" + fi + if test "$ac_cv_type_uint64_t" = "no" -a -z "$u_int64_decl"; then + db_cv_build_sequence="no" + fi + + # Have to be able to cast variables to the "unsigned long long" and + # "long long" types, that's our cast for the printf "%ll[du]" format. + if test "$ac_cv_type_long_long" = "no"; then + db_cv_build_sequence="no" + fi + if test "$ac_cv_type_unsigned_long_long" = "no"; then + db_cv_build_sequence="no" + fi + + # Test to see if we can declare variables of the appropriate size + # and format them. If we're cross-compiling, all we get is a link + # test, which won't test for the appropriate printf format strings. + if test "$db_cv_build_sequence" = "yes"; then + AC_TRY_RUN([ + main() { + long long l; + unsigned long long u; + char buf[100]; + + buf[0] = 'a'; + l = 9223372036854775807LL; + (void)snprintf(buf, sizeof(buf), "%lld", l); + if (strcmp(buf, "9223372036854775807")) + return (1); + u = 18446744073709551615ULL; + (void)snprintf(buf, sizeof(buf), "%llu", u); + if (strcmp(buf, "18446744073709551615")) + return (1); + return (0); + }],, [db_cv_build_sequence="no"], + AC_TRY_LINK(,[ + long long l; + unsigned long long u; + char buf[100]; + + buf[0] = 'a'; + l = 9223372036854775807LL; + (void)snprintf(buf, sizeof(buf), "%lld", l); + if (strcmp(buf, "9223372036854775807")) + return (1); + u = 18446744073709551615ULL; + (void)snprintf(buf, sizeof(buf), "%llu", u); + if (strcmp(buf, "18446744073709551615")) + return (1); + return (0); + ],, [db_cv_build_sequence="no"])) + fi + if test "$db_cv_build_sequence" = "yes"; then + AC_DEFINE(HAVE_SEQUENCE) + AH_TEMPLATE(HAVE_SEQUENCE, + [Define to 1 if building sequence support.]) + + AC_SUBST(db_seq_decl) + db_seq_decl="typedef int64_t db_seq_t;"; + else + # It still has to compile, but it won't run. + db_seq_decl="typedef int db_seq_t;"; + fi + AC_MSG_RESULT($db_cv_build_sequence) +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal/sosuffix.ac b/src/libs/resiprocate/contrib/db/dist/aclocal/sosuffix.ac new file mode 100644 index 00000000..8864280f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal/sosuffix.ac @@ -0,0 +1,76 @@ +# $Id: sosuffix.ac,v 1.4 2004/08/14 20:00:45 dda Exp $ +# Determine shared object suffixes. +# +# Our method is to use the libtool variable $library_names_spec, +# set by using AC_PROG_LIBTOOL. This variable is a snippet of shell +# defined in terms of $versuffix, $release, $libname and $module +# We want to eval it and grab the suffix used for shared objects. +# By setting $module to yes/no, we obtain the suffixes +# used to create dlloadable, or java loadable modules. +# On many (*nix) systems, these all evaluate to .so, but there +# are some notable exceptions. +# Before calling this macro, $LIBTOOL_PROG must be set to +# the correct method of invoking libtool (e.g. $SHELL ./libtool) + +# This macro is used internally to discover the suffix for the current +# settings of $module. The result is stored in $_SOSUFFIX. +AC_DEFUN(_SOSUFFIX_INTERNAL, [ + versuffix="" + release="" + libname=libfoo + eval _SOSUFFIX=\"$shrext_cmds\" + if test "$_SOSUFFIX" = "" ; then + _SOSUFFIX=".so" + if test `$LIBTOOL_PROG --config | grep build_libtool_libs | grep no` 2>/dev/null; then + if test "$_SOSUFFIX_MESSAGE" = ""; then + _SOSUFFIX_MESSAGE=yes + AC_MSG_WARN([libtool may not know about this architecture.]) + AC_MSG_WARN([assuming $_SUFFIX suffix for dynamic libraries.]) + fi + fi + fi +]) + +# SOSUFFIX_CONFIG will set the variable SOSUFFIX to be the +# shared library extension used for general linking, not dlopen. +AC_DEFUN(SOSUFFIX_CONFIG, [ + AC_MSG_CHECKING([SOSUFFIX from libtool]) + module=no + _SOSUFFIX_INTERNAL + SOSUFFIX=$_SOSUFFIX + AC_MSG_RESULT($SOSUFFIX) + AC_SUBST(SOSUFFIX) +]) + +# MODSUFFIX_CONFIG will set the variable MODSUFFIX to be the +# shared library extension used for dlopen'ed modules. +# To discover this, we set $module, simulating libtool's -module option. +AC_DEFUN(MODSUFFIX_CONFIG, [ + AC_MSG_CHECKING([MODSUFFIX from libtool]) + module=yes + _SOSUFFIX_INTERNAL + MODSUFFIX=$_SOSUFFIX + AC_MSG_RESULT($MODSUFFIX) + AC_SUBST(MODSUFFIX) +]) + +# JMODSUFFIX_CONFIG will set the variable JMODSUFFIX to be the +# shared library extension used JNI modules opened by Java. +# To discover this, we set $jnimodule, simulating libtool's -shrext option. +########################################################################## +# Robert Boehne: Not much point in this macro any more because apparently +# Darwin is the only OS that wants or needs the .jnilib extension. +########################################################################## +AC_DEFUN(JMODSUFFIX_CONFIG, [ + AC_MSG_CHECKING([JMODSUFFIX from libtool]) + module=yes + _SOSUFFIX_INTERNAL + if test `uname` = "Darwin"; then + JMODSUFFIX=".jnilib" + else + JMODSUFFIX=$_SOSUFFIX + fi + AC_MSG_RESULT($JMODSUFFIX) + AC_SUBST(JMODSUFFIX) +]) + diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal/tcl.ac b/src/libs/resiprocate/contrib/db/dist/aclocal/tcl.ac new file mode 100644 index 00000000..d28d3608 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal/tcl.ac @@ -0,0 +1,141 @@ +# $Id: tcl.ac,v 11.18 2004/03/11 20:11:17 bostic Exp $ + +# The SC_* macros in this file are from the unix/tcl.m4 files in the Tcl +# 8.3.0 distribution, with some minor changes. For this reason, license +# terms for the Berkeley DB distribution dist/aclocal/tcl.m4 file are as +# follows (copied from the license.terms file in the Tcl 8.3 distribution): +# +# This software is copyrighted by the Regents of the University of +# California, Sun Microsystems, Inc., Scriptics Corporation, +# and other parties. The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# +# GOVERNMENT USE: If you are acquiring this software on behalf of the +# U.S. government, the Government shall have only "Restricted Rights" +# in the software and related documentation as defined in the Federal +# Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +# are acquiring the software on behalf of the Department of Defense, the +# software shall be classified as "Commercial Computer Software" and the +# Government shall have only "Restricted Rights" as defined in Clause +# 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the +# authors grant the U.S. Government and others acting in its behalf +# permission to use and distribute the software in accordance with the +# terms specified in this license. + +AC_DEFUN(SC_PATH_TCLCONFIG, [ + AC_CACHE_VAL(ac_cv_c_tclconfig,[ + + # First check to see if --with-tclconfig was specified. + if test "${with_tclconfig}" != no; then + if test -f "${with_tclconfig}/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` + else + AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) + fi + fi + + # check in a few common install locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d /usr/local/lib 2>/dev/null` ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i; pwd)` + break + fi + done + fi + + ]) + + if test x"${ac_cv_c_tclconfig}" = x ; then + TCL_BIN_DIR="# no Tcl configs found" + AC_MSG_ERROR(can't find Tcl configuration definitions) + else + TCL_BIN_DIR=${ac_cv_c_tclconfig} + fi +]) + +AC_DEFUN(SC_LOAD_TCLCONFIG, [ + AC_MSG_CHECKING([for existence of $TCL_BIN_DIR/tclConfig.sh]) + + if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then + AC_MSG_RESULT([loading]) + . $TCL_BIN_DIR/tclConfig.sh + else + AC_MSG_RESULT([file not found]) + fi + + # DB requires at least version 8.4. + if test ${TCL_MAJOR_VERSION} -lt 8 \ + -o ${TCL_MAJOR_VERSION} -eq 8 -a ${TCL_MINOR_VERSION} -lt 4; then + AC_MSG_ERROR([Berkeley DB requires Tcl version 8.4 or better.]) + fi + + # + # The eval is required to do the TCL_DBGX substitution in the + # TCL_LIB_FILE variable + # + eval TCL_LIB_FILE="${TCL_LIB_FILE}" + eval TCL_LIB_FLAG="${TCL_LIB_FLAG}" + eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" + + # + # If the DB Tcl library isn't loaded with the Tcl spec and library + # flags on AIX, the resulting libdb_tcl-X.Y.so.0 will drop core at + # load time. [#4843] Furthermore, with Tcl 8.3, the link flags + # given by the Tcl spec are insufficient for our use. [#5779] + # + case "$host_os" in + aix4.[[2-9]].*) + LIBTSO_LIBS="$LIBTSO_LIBS $TCL_LIB_SPEC $TCL_LIB_FLAG" + LIBTSO_LIBS="$LIBTSO_LIBS -L$TCL_EXEC_PREFIX/lib -ltcl$TCL_VERSION";; + aix*) + LIBTSO_LIBS="$LIBTSO_LIBS $TCL_LIB_SPEC $TCL_LIB_FLAG";; + esac + AC_SUBST(TCL_BIN_DIR) + AC_SUBST(TCL_SRC_DIR) + AC_SUBST(TCL_LIB_FILE) + + AC_SUBST(TCL_TCLSH) + TCL_TCLSH="${TCL_PREFIX}/bin/tclsh${TCL_VERSION}" +]) + +# Optional Tcl API. +AC_DEFUN(AM_TCL_LOAD, [ + if test `$LIBTOOL_PROG --config | grep build_libtool_libs | grep no` 2>/dev/null; then + AC_MSG_ERROR([Tcl requires shared libraries]) + fi + + AC_SUBST(TCFLAGS) + + SC_PATH_TCLCONFIG + SC_LOAD_TCLCONFIG + + if test x"$TCL_PREFIX" != x && test -f "$TCL_PREFIX/include/tcl.h"; then + TCFLAGS="-I$TCL_PREFIX/include" + fi + + INSTALL_LIBS="${INSTALL_LIBS} \$(libtso_target)" +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal/types.ac b/src/libs/resiprocate/contrib/db/dist/aclocal/types.ac new file mode 100644 index 00000000..b5843385 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal/types.ac @@ -0,0 +1,163 @@ +# $Id: types.ac,v 11.18 2004/10/25 18:14:14 bostic Exp $ + +# Check the sizes we know about, and see if any of them match what's needed. +# +# Prefer ints to anything else, because read, write and others historically +# returned an int. +AC_DEFUN(AM_SEARCH_USIZES, [ + case "$3" in + "$ac_cv_sizeof_unsigned_int") + $1="typedef unsigned int $2;";; + "$ac_cv_sizeof_unsigned_char") + $1="typedef unsigned char $2;";; + "$ac_cv_sizeof_unsigned_short") + $1="typedef unsigned short $2;";; + "$ac_cv_sizeof_unsigned_long") + $1="typedef unsigned long $2;";; + "$ac_cv_sizeof_unsigned_long_long") + $1="typedef unsigned long long $2;";; + *) + if test "$4" != "notfatal"; then + AC_MSG_ERROR([No unsigned $3-byte integral type]) + fi;; + esac]) +AC_DEFUN(AM_SEARCH_SSIZES, [ + case "$3" in + "$ac_cv_sizeof_int") + $1="typedef int $2;";; + "$ac_cv_sizeof_char") + $1="typedef char $2;";; + "$ac_cv_sizeof_short") + $1="typedef short $2;";; + "$ac_cv_sizeof_long") + $1="typedef long $2;";; + "$ac_cv_sizeof_long_long") + $1="typedef long long $2;";; + *) + if test "$4" != "notfatal"; then + AC_MSG_ERROR([No signed $3-byte integral type]) + fi;; + esac]) + +# Check for the standard system types. +AC_DEFUN(AM_TYPES, [ + +# db.h includes and , not the other default includes +# autoconf usually includes. For that reason, we specify a set of includes +# for all type checking tests. [#5060] +# +# C99 says types should be in ; include if it exists. +# +# Some systems have types in ; include if it exists. +# +# IBM's OS/390 and z/OS releases have types in not also found +# in ; include if it exists. +db_includes="#include " +AC_SUBST(inttypes_h_decl) +AC_CHECK_HEADER(inttypes.h, [ + db_includes="$db_includes +#include " + inttypes_h_decl="#include "]) +AC_SUBST(stdint_h_decl) +AC_CHECK_HEADER(stdint.h, [ + db_includes="$db_includes +#include " + stdint_h_decl="#include "]) +AC_SUBST(stddef_h_decl) +AC_CHECK_HEADER(stddef.h, [ + db_includes="$db_includes +#include " + stddef_h_decl="#include "]) +db_includes="$db_includes +#include " + +# We require off_t and size_t, and we don't try to substitute our own +# if we can't find them. +AC_CHECK_TYPE(off_t,, AC_MSG_ERROR([No off_t type.]), $db_includes) +AC_CHECK_TYPE(size_t,, AC_MSG_ERROR([No size_t type.]), $db_includes) + +# Check for long long and unsigned long long, we only support sequences +# if those types are available. +AC_CHECK_TYPES([long long, unsigned long long],,, $db_includes) + +# We need to know the sizes of various objects on this system. +AC_CHECK_SIZEOF(char,, $db_includes) +AC_CHECK_SIZEOF(unsigned char,, $db_includes) +AC_CHECK_SIZEOF(short,, $db_includes) +AC_CHECK_SIZEOF(unsigned short,, $db_includes) +AC_CHECK_SIZEOF(int,, $db_includes) +AC_CHECK_SIZEOF(unsigned int,, $db_includes) +AC_CHECK_SIZEOF(long,, $db_includes) +AC_CHECK_SIZEOF(unsigned long,, $db_includes) +AC_CHECK_SIZEOF(long long,, $db_includes) +AC_CHECK_SIZEOF(unsigned long long,, $db_includes) +AC_CHECK_SIZEOF(size_t,, $db_includes) +AC_CHECK_SIZEOF(char *,, $db_includes) + +# We look for u_char, u_short, u_int, u_long -- if we can't find them, +# we create our own. +AC_SUBST(u_char_decl) +AC_CHECK_TYPE(u_char,, + [u_char_decl="typedef unsigned char u_char;"], $db_includes) + +AC_SUBST(u_short_decl) +AC_CHECK_TYPE(u_short,, + [u_short_decl="typedef unsigned short u_short;"], $db_includes) + +AC_SUBST(u_int_decl) +AC_CHECK_TYPE(u_int,, + [u_int_decl="typedef unsigned int u_int;"], $db_includes) + +AC_SUBST(u_long_decl) +AC_CHECK_TYPE(u_long,, + [u_long_decl="typedef unsigned long u_long;"], $db_includes) + +# We look for fixed-size variants of u_char, u_short, u_int, u_long as well. +AC_SUBST(u_int8_decl) +AC_CHECK_TYPE(u_int8_t,, + [AM_SEARCH_USIZES(u_int8_decl, u_int8_t, 1)], $db_includes) + +AC_SUBST(u_int16_decl) +AC_CHECK_TYPE(u_int16_t,, + [AM_SEARCH_USIZES(u_int16_decl, u_int16_t, 2)], $db_includes) + +AC_SUBST(int16_decl) +AC_CHECK_TYPE(int16_t,, + [AM_SEARCH_SSIZES(int16_decl, int16_t, 2)], $db_includes) + +AC_SUBST(u_int32_decl) +AC_CHECK_TYPE(u_int32_t,, + [AM_SEARCH_USIZES(u_int32_decl, u_int32_t, 4)], $db_includes) + +AC_SUBST(int32_decl) +AC_CHECK_TYPE(int32_t,, + [AM_SEARCH_SSIZES(int32_decl, int32_t, 4)], $db_includes) + +AC_SUBST(u_int64_decl) +AC_CHECK_TYPE(u_int64_t,, + [AM_SEARCH_USIZES(u_int64_decl, u_int64_t, 8, notfatal)], $db_includes) + +AC_SUBST(int64_decl) +AC_CHECK_TYPE(int64_t,, + [AM_SEARCH_SSIZES(int64_decl, int64_t, 8, notfatal)], $db_includes) + +# Check for ssize_t -- if none exists, find a signed integral type that's +# the same size as a size_t. +AC_SUBST(ssize_t_decl) +AC_CHECK_TYPE(ssize_t,, + [AM_SEARCH_SSIZES(ssize_t_decl, ssize_t, $ac_cv_sizeof_size_t)], + $db_includes) + +# Check for uintmax_t -- if none exists, first the largest unsigned integral +# type available. +AC_SUBST(uintmax_t_decl) +AC_CHECK_TYPE(uintmax_t,, [AC_CHECK_TYPE(unsigned long long, + [uintmax_t_decl="typedef unsigned long long uintmax_t;"], + [uintmax_t_decl="typedef unsigned long uintmax_t;"], $db_includes)]) + +# Check for uintptr_t -- if none exists, find an integral type which is +# the same size as a pointer. +AC_SUBST(uintptr_t_decl) +AC_CHECK_TYPE(uintptr_t,, + [AM_SEARCH_USIZES(uintptr_t_decl, uintptr_t, $ac_cv_sizeof_char_p)]) +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_check_class.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_check_class.ac new file mode 100644 index 00000000..915198af --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_check_class.ac @@ -0,0 +1,107 @@ +dnl @synopsis AC_CHECK_CLASS +dnl +dnl AC_CHECK_CLASS tests the existence of a given Java class, either in +dnl a jar or in a '.class' file. +dnl +dnl *Warning*: its success or failure can depend on a proper setting of the +dnl CLASSPATH env. variable. +dnl +dnl Note: This is part of the set of autoconf M4 macros for Java programs. +dnl It is VERY IMPORTANT that you download the whole set, some +dnl macros depend on other. Unfortunately, the autoconf archive does not +dnl support the concept of set of macros, so I had to break it for +dnl submission. +dnl The general documentation, as well as the sample configure.in, is +dnl included in the AC_PROG_JAVA macro. +dnl +dnl @author Stephane Bortzmeyer +dnl @version $Id: ac_check_class.ac,v 1.1 2001/08/23 16:58:42 dda Exp $ +dnl +AC_DEFUN([AC_CHECK_CLASS],[ +AC_REQUIRE([AC_PROG_JAVA]) +ac_var_name=`echo $1 | sed 's/\./_/g'` +dnl Normaly I'd use a AC_CACHE_CHECK here but since the variable name is +dnl dynamic I need an extra level of extraction +AC_MSG_CHECKING([for $1 class]) +AC_CACHE_VAL(ac_cv_class_$ac_var_name, [ +if test x$ac_cv_prog_uudecode_base64 = xyes; then +dnl /** +dnl * Test.java: used to test dynamicaly if a class exists. +dnl */ +dnl public class Test +dnl { +dnl +dnl public static void +dnl main( String[] argv ) +dnl { +dnl Class lib; +dnl if (argv.length < 1) +dnl { +dnl System.err.println ("Missing argument"); +dnl System.exit (77); +dnl } +dnl try +dnl { +dnl lib = Class.forName (argv[0]); +dnl } +dnl catch (ClassNotFoundException e) +dnl { +dnl System.exit (1); +dnl } +dnl lib = null; +dnl System.exit (0); +dnl } +dnl +dnl } +cat << \EOF > Test.uue +begin-base64 644 Test.class +yv66vgADAC0AKQcAAgEABFRlc3QHAAQBABBqYXZhL2xhbmcvT2JqZWN0AQAE +bWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARDb2RlAQAPTGluZU51 +bWJlclRhYmxlDAAKAAsBAANlcnIBABVMamF2YS9pby9QcmludFN0cmVhbTsJ +AA0ACQcADgEAEGphdmEvbGFuZy9TeXN0ZW0IABABABBNaXNzaW5nIGFyZ3Vt +ZW50DAASABMBAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWCgAV +ABEHABYBABNqYXZhL2lvL1ByaW50U3RyZWFtDAAYABkBAARleGl0AQAEKEkp +VgoADQAXDAAcAB0BAAdmb3JOYW1lAQAlKExqYXZhL2xhbmcvU3RyaW5nOylM +amF2YS9sYW5nL0NsYXNzOwoAHwAbBwAgAQAPamF2YS9sYW5nL0NsYXNzBwAi +AQAgamF2YS9sYW5nL0NsYXNzTm90Rm91bmRFeGNlcHRpb24BAAY8aW5pdD4B +AAMoKVYMACMAJAoAAwAlAQAKU291cmNlRmlsZQEACVRlc3QuamF2YQAhAAEA +AwAAAAAAAgAJAAUABgABAAcAAABtAAMAAwAAACkqvgSiABCyAAwSD7YAFBBN +uAAaKgMyuAAeTKcACE0EuAAaAUwDuAAasQABABMAGgAdACEAAQAIAAAAKgAK +AAAACgAAAAsABgANAA4ADgATABAAEwASAB4AFgAiABgAJAAZACgAGgABACMA +JAABAAcAAAAhAAEAAQAAAAUqtwAmsQAAAAEACAAAAAoAAgAAAAQABAAEAAEA +JwAAAAIAKA== +==== +EOF + if uudecode$EXEEXT Test.uue; then + : + else + echo "configure: __oline__: uudecode had trouble decoding base 64 file 'Test.uue'" >&AC_FD_CC + echo "configure: failed file was:" >&AC_FD_CC + cat Test.uue >&AC_FD_CC + ac_cv_prog_uudecode_base64=no + fi + rm -f Test.uue + if AC_TRY_COMMAND($JAVA $JAVAFLAGS Test $1) >/dev/null 2>&1; then + eval "ac_cv_class_$ac_var_name=yes" + else + eval "ac_cv_class_$ac_var_name=no" + fi + rm -f Test.class +else + AC_TRY_COMPILE_JAVA([$1], , [eval "ac_cv_class_$ac_var_name=yes"], + [eval "ac_cv_class_$ac_var_name=no"]) +fi +eval "ac_var_val=$`eval echo ac_cv_class_$ac_var_name`" +eval "HAVE_$ac_var_name=$`echo ac_cv_class_$ac_var_val`" +HAVE_LAST_CLASS=$ac_var_val +if test x$ac_var_val = xyes; then + ifelse([$2], , :, [$2]) +else + ifelse([$3], , :, [$3]) +fi +]) +dnl for some reason the above statment didn't fall though here? +dnl do scripts have variable scoping? +eval "ac_var_val=$`eval echo ac_cv_class_$ac_var_name`" +AC_MSG_RESULT($ac_var_val) +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_check_classpath.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_check_classpath.ac new file mode 100644 index 00000000..4a78d0f8 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_check_classpath.ac @@ -0,0 +1,23 @@ +dnl @synopsis AC_CHECK_CLASSPATH +dnl +dnl AC_CHECK_CLASSPATH just displays the CLASSPATH, for the edification +dnl of the user. +dnl +dnl Note: This is part of the set of autoconf M4 macros for Java programs. +dnl It is VERY IMPORTANT that you download the whole set, some +dnl macros depend on other. Unfortunately, the autoconf archive does not +dnl support the concept of set of macros, so I had to break it for +dnl submission. +dnl The general documentation, as well as the sample configure.in, is +dnl included in the AC_PROG_JAVA macro. +dnl +dnl @author Stephane Bortzmeyer +dnl @version $Id: ac_check_classpath.ac,v 1.1 2001/08/23 16:58:42 dda Exp $ +dnl +AC_DEFUN([AC_CHECK_CLASSPATH],[ +if test "x$CLASSPATH" = x; then + echo "You have no CLASSPATH, I hope it is good" +else + echo "You have CLASSPATH $CLASSPATH, hope it is correct" +fi +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_check_junit.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_check_junit.ac new file mode 100644 index 00000000..3b81d1dc --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_check_junit.ac @@ -0,0 +1,54 @@ +dnl @synopsis AC_CHECK_JUNIT +dnl +dnl AC_CHECK_JUNIT tests the availability of the Junit testing +dnl framework, and set some variables for conditional compilation +dnl of the test suite by automake. +dnl +dnl If available, JUNIT is set to a command launching the text +dnl based user interface of Junit, @JAVA_JUNIT@ is set to $JAVA_JUNIT +dnl and @TESTS_JUNIT@ is set to $TESTS_JUNIT, otherwise they are set +dnl to empty values. +dnl +dnl You can use these variables in your Makefile.am file like this : +dnl +dnl # Some of the following classes are built only if junit is available +dnl JAVA_JUNIT = Class1Test.java Class2Test.java AllJunitTests.java +dnl +dnl noinst_JAVA = Example1.java Example2.java @JAVA_JUNIT@ +dnl +dnl EXTRA_JAVA = $(JAVA_JUNIT) +dnl +dnl TESTS_JUNIT = AllJunitTests +dnl +dnl TESTS = StandaloneTest1 StandaloneTest2 @TESTS_JUNIT@ +dnl +dnl EXTRA_TESTS = $(TESTS_JUNIT) +dnl +dnl AllJunitTests : +dnl echo "#! /bin/sh" > $@ +dnl echo "exec @JUNIT@ my.package.name.AllJunitTests" >> $@ +dnl chmod +x $@ +dnl +dnl @author Luc Maisonobe +dnl @version $Id: ac_check_junit.ac,v 1.1 2001/08/23 16:58:43 dda Exp $ +dnl +AC_DEFUN([AC_CHECK_JUNIT],[ +AC_CACHE_VAL(ac_cv_prog_JUNIT,[ +AC_CHECK_CLASS(junit.textui.TestRunner) +if test x"`eval 'echo $ac_cv_class_junit_textui_TestRunner'`" != xno ; then + ac_cv_prog_JUNIT='$(CLASSPATH_ENV) $(JAVA) $(JAVAFLAGS) junit.textui.TestRunner' +fi]) +AC_MSG_CHECKING([for junit]) +if test x"`eval 'echo $ac_cv_prog_JUNIT'`" != x ; then + JUNIT="$ac_cv_prog_JUNIT" + JAVA_JUNIT='$(JAVA_JUNIT)' + TESTS_JUNIT='$(TESTS_JUNIT)' +else + JUNIT= + JAVA_JUNIT= + TESTS_JUNIT= +fi +AC_MSG_RESULT($JAVA_JUNIT) +AC_SUBST(JUNIT) +AC_SUBST(JAVA_JUNIT) +AC_SUBST(TESTS_JUNIT)]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_check_rqrd_class.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_check_rqrd_class.ac new file mode 100644 index 00000000..ab62e33c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_check_rqrd_class.ac @@ -0,0 +1,26 @@ +dnl @synopsis AC_CHECK_RQRD_CLASS +dnl +dnl AC_CHECK_RQRD_CLASS tests the existence of a given Java class, either in +dnl a jar or in a '.class' file and fails if it doesn't exist. +dnl Its success or failure can depend on a proper setting of the +dnl CLASSPATH env. variable. +dnl +dnl Note: This is part of the set of autoconf M4 macros for Java programs. +dnl It is VERY IMPORTANT that you download the whole set, some +dnl macros depend on other. Unfortunately, the autoconf archive does not +dnl support the concept of set of macros, so I had to break it for +dnl submission. +dnl The general documentation, as well as the sample configure.in, is +dnl included in the AC_PROG_JAVA macro. +dnl +dnl @author Stephane Bortzmeyer +dnl @version $Id: ac_check_rqrd_class.ac,v 1.1 2001/08/23 16:58:43 dda Exp $ +dnl + +AC_DEFUN([AC_CHECK_RQRD_CLASS],[ +CLASS=`echo $1|sed 's/\./_/g'` +AC_CHECK_CLASS($1) +if test "$HAVE_LAST_CLASS" = "no"; then + AC_MSG_ERROR([Required class $1 missing, exiting.]) +fi +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_java_options.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_java_options.ac new file mode 100644 index 00000000..567afca7 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_java_options.ac @@ -0,0 +1,32 @@ +dnl @synopsis AC_JAVA_OPTIONS +dnl +dnl AC_JAVA_OPTIONS adds configure command line options used for Java m4 +dnl macros. This Macro is optional. +dnl +dnl Note: This is part of the set of autoconf M4 macros for Java programs. +dnl It is VERY IMPORTANT that you download the whole set, some +dnl macros depend on other. Unfortunately, the autoconf archive does not +dnl support the concept of set of macros, so I had to break it for +dnl submission. +dnl The general documentation, as well as the sample configure.in, is +dnl included in the AC_PROG_JAVA macro. +dnl +dnl @author Devin Weaver +dnl @version $Id: ac_java_options.ac,v 1.1 2001/08/23 16:58:43 dda Exp $ +dnl +AC_DEFUN([AC_JAVA_OPTIONS],[ +AC_ARG_WITH(java-prefix, + [ --with-java-prefix=PFX prefix where Java runtime is installed (optional)]) +AC_ARG_WITH(javac-flags, + [ --with-javac-flags=FLAGS flags to pass to the Java compiler (optional)]) +AC_ARG_WITH(java-flags, + [ --with-java-flags=FLAGS flags to pass to the Java VM (optional)]) +JAVAPREFIX=$with_java_prefix +JAVACFLAGS=$with_javac_flags +JAVAFLAGS=$with_java_flags +AC_SUBST(JAVAPREFIX)dnl +AC_SUBST(JAVACFLAGS)dnl +AC_SUBST(JAVAFLAGS)dnl +AC_SUBST(JAVA)dnl +AC_SUBST(JAVAC)dnl +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_jni_include_dirs.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_jni_include_dirs.ac new file mode 100644 index 00000000..b70d108d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_jni_include_dirs.ac @@ -0,0 +1,114 @@ +dnl @synopsis AC_JNI_INCLUDE_DIR +dnl +dnl AC_JNI_INCLUDE_DIR finds include directories needed +dnl for compiling programs using the JNI interface. +dnl +dnl JNI include directories are usually in the java distribution +dnl This is deduced from the value of JAVAC. When this macro +dnl completes, a list of directories is left in the variable +dnl JNI_INCLUDE_DIRS. +dnl +dnl Example usage follows: +dnl +dnl AC_JNI_INCLUDE_DIR +dnl +dnl for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS +dnl do +dnl CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" +dnl done +dnl +dnl If you want to force a specific compiler: +dnl +dnl - at the configure.in level, set JAVAC=yourcompiler before calling +dnl AC_JNI_INCLUDE_DIR +dnl +dnl - at the configure level, setenv JAVAC +dnl +dnl Note: This macro can work with the autoconf M4 macros for Java programs. +dnl This particular macro is not part of the original set of macros. +dnl +dnl @author Don Anderson +dnl @version $Id: ac_jni_include_dirs.ac,v 1.12 2003/10/05 18:10:06 dda Exp $ +dnl +AC_DEFUN(AC_JNI_INCLUDE_DIR,[ + +JNI_INCLUDE_DIRS="" + +test "x$JAVAC" = x && AC_MSG_ERROR(['$JAVAC' undefined]) +AC_PATH_PROG(_ACJNI_JAVAC, $JAVAC, $JAVAC) +test ! -x "$_ACJNI_JAVAC" && AC_MSG_ERROR([$JAVAC could not be found in path]) +AC_MSG_CHECKING(absolute path of $JAVAC) +case "$_ACJNI_JAVAC" in +/*) AC_MSG_RESULT($_ACJNI_JAVAC);; +*) AC_MSG_ERROR([$_ACJNI_JAVAC is not an absolute path name]);; +esac + +_ACJNI_FOLLOW_SYMLINKS("$_ACJNI_JAVAC") +_JTOPDIR=`echo "$_ACJNI_FOLLOWED" | sed -e 's://*:/:g' -e 's:/[[^/]]*$::'` +case "$host_os" in + darwin*) _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` + _JINC="$_JTOPDIR/Headers";; + *) _JINC="$_JTOPDIR/include";; +esac + +# If we find jni.h in /usr/include, then it's not a java-only tree, so +# don't add /usr/include or subdirectories to the list of includes. +# An extra -I/usr/include can foul things up with newer gcc's. +# +# If we don't find jni.h, just keep going. Hopefully javac knows where +# to find its include files, even if we can't. +if test -r "$_JINC/jni.h"; then + if test "$_JINC" != "/usr/include"; then + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JINC" + fi +else + _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` + if test -r "$_JTOPDIR/include/jni.h"; then + if test "$_JTOPDIR" != "/usr"; then + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include" + fi + fi +fi + +# get the likely subdirectories for system specific java includes +if test "$_JTOPDIR" != "/usr"; then + case "$host_os" in + aix*) _JNI_INC_SUBDIRS="aix";; + bsdi*) _JNI_INC_SUBDIRS="bsdos";; + freebsd*) _JNI_INC_SUBDIRS="freebsd";; + hp*) _JNI_INC_SUBDIRS="hp-ux";; + linux*) _JNI_INC_SUBDIRS="linux genunix";; + osf*) _JNI_INC_SUBDIRS="alpha";; + solaris*) _JNI_INC_SUBDIRS="solaris";; + *) _JNI_INC_SUBDIRS="genunix";; + esac +fi + +# add any subdirectories that are present +for _JINCSUBDIR in $_JNI_INC_SUBDIRS +do + if test -d "$_JTOPDIR/include/$_JINCSUBDIR"; then + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include/$_JINCSUBDIR" + fi +done +]) + +# _ACJNI_FOLLOW_SYMLINKS +# Follows symbolic links on , +# finally setting variable _ACJNI_FOLLOWED +# -------------------- +AC_DEFUN(_ACJNI_FOLLOW_SYMLINKS,[ +# find the include directory relative to the javac executable +_cur="$1" +while ls -ld "$_cur" 2>/dev/null | grep " -> " >/dev/null; do + AC_MSG_CHECKING(symlink for $_cur) + _slink=`ls -ld "$_cur" | sed 's/.* -> //'` + case "$_slink" in + /*) _cur="$_slink";; + # 'X' avoids triggering unwanted echo options. + *) _cur=`echo "X$_cur" | sed -e 's/^X//' -e 's:[[^/]]*$::'`"$_slink";; + esac + AC_MSG_RESULT($_cur) +done +_ACJNI_FOLLOWED="$_cur" +])# _ACJNI diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_jar.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_jar.ac new file mode 100644 index 00000000..9dfa1be6 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_jar.ac @@ -0,0 +1,36 @@ +dnl @synopsis AC_PROG_JAR +dnl +dnl AC_PROG_JAR tests for an existing jar program. It uses the environment +dnl variable JAR then tests in sequence various common jar programs. +dnl +dnl If you want to force a specific compiler: +dnl +dnl - at the configure.in level, set JAR=yourcompiler before calling +dnl AC_PROG_JAR +dnl +dnl - at the configure level, setenv JAR +dnl +dnl You can use the JAR variable in your Makefile.in, with @JAR@. +dnl +dnl Note: This macro depends on the autoconf M4 macros for Java programs. +dnl It is VERY IMPORTANT that you download that whole set, some +dnl macros depend on other. Unfortunately, the autoconf archive does not +dnl support the concept of set of macros, so I had to break it for +dnl submission. +dnl +dnl The general documentation of those macros, as well as the sample +dnl configure.in, is included in the AC_PROG_JAVA macro. +dnl +dnl @author Egon Willighagen +dnl @version $Id: ac_prog_jar.ac,v 1.1 2001/08/23 16:58:43 dda Exp $ +dnl +AC_DEFUN([AC_PROG_JAR],[ +AC_REQUIRE([AC_EXEEXT])dnl +if test "x$JAVAPREFIX" = x; then + test "x$JAR" = x && AC_CHECK_PROGS(JAR, jar$EXEEXT) +else + test "x$JAR" = x && AC_CHECK_PROGS(JAR, jar, $JAVAPREFIX) +fi +test "x$JAR" = x && AC_MSG_ERROR([no acceptable jar program found in \$PATH]) +AC_PROVIDE([$0])dnl +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_java.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_java.ac new file mode 100644 index 00000000..67a879ff --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_java.ac @@ -0,0 +1,79 @@ +dnl @synopsis AC_PROG_JAVA +dnl +dnl Here is a summary of the main macros: +dnl +dnl AC_PROG_JAVAC: finds a Java compiler. +dnl +dnl AC_PROG_JAVA: finds a Java virtual machine. +dnl +dnl AC_CHECK_CLASS: finds if we have the given class (beware of CLASSPATH!). +dnl +dnl AC_CHECK_RQRD_CLASS: finds if we have the given class and stops otherwise. +dnl +dnl AC_TRY_COMPILE_JAVA: attempt to compile user given source. +dnl +dnl AC_TRY_RUN_JAVA: attempt to compile and run user given source. +dnl +dnl AC_JAVA_OPTIONS: adds Java configure options. +dnl +dnl AC_PROG_JAVA tests an existing Java virtual machine. It uses the +dnl environment variable JAVA then tests in sequence various common Java +dnl virtual machines. For political reasons, it starts with the free ones. +dnl You *must* call [AC_PROG_JAVAC] before. +dnl +dnl If you want to force a specific VM: +dnl +dnl - at the configure.in level, set JAVA=yourvm before calling AC_PROG_JAVA +dnl (but after AC_INIT) +dnl +dnl - at the configure level, setenv JAVA +dnl +dnl You can use the JAVA variable in your Makefile.in, with @JAVA@. +dnl +dnl *Warning*: its success or failure can depend on a proper setting of the +dnl CLASSPATH env. variable. +dnl +dnl TODO: allow to exclude virtual machines (rationale: most Java programs +dnl cannot run with some VM like kaffe). +dnl +dnl Note: This is part of the set of autoconf M4 macros for Java programs. +dnl It is VERY IMPORTANT that you download the whole set, some +dnl macros depend on other. Unfortunately, the autoconf archive does not +dnl support the concept of set of macros, so I had to break it for +dnl submission. +dnl +dnl A Web page, with a link to the latest CVS snapshot is at +dnl . +dnl +dnl This is a sample configure.in +dnl Process this file with autoconf to produce a configure script. +dnl +dnl AC_INIT(UnTag.java) +dnl +dnl dnl Checks for programs. +dnl AC_CHECK_CLASSPATH +dnl AC_PROG_JAVAC +dnl AC_PROG_JAVA +dnl +dnl dnl Checks for classes +dnl AC_CHECK_RQRD_CLASS(org.xml.sax.Parser) +dnl AC_CHECK_RQRD_CLASS(com.jclark.xml.sax.Driver) +dnl +dnl AC_OUTPUT(Makefile) +dnl +dnl @author Stephane Bortzmeyer +dnl @version $Id: ac_prog_java.ac,v 1.2 2003/05/10 17:46:09 dda Exp $ +dnl +dnl Note: Modified by dda@sleepycat.com to prefer java over kaffe. [#8059] +dnl +AC_DEFUN([AC_PROG_JAVA],[ +AC_REQUIRE([AC_EXEEXT])dnl +if test x$JAVAPREFIX = x; then + test x$JAVA = x && AC_CHECK_PROGS(JAVA, java$EXEEXT kaffe$EXEEXT) +else + test x$JAVA = x && AC_CHECK_PROGS(JAVA, java$EXEEXT kaffe$EXEEXT, $JAVAPREFIX) +fi +test x$JAVA = x && AC_MSG_ERROR([no acceptable Java virtual machine found in \$PATH]) +AC_PROG_JAVA_WORKS +AC_PROVIDE([$0])dnl +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_java_works.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_java_works.ac new file mode 100644 index 00000000..36acd267 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_java_works.ac @@ -0,0 +1,97 @@ +dnl @synopsis AC_PROG_JAVA_WORKS +dnl +dnl Internal use ONLY. +dnl +dnl Note: This is part of the set of autoconf M4 macros for Java programs. +dnl It is VERY IMPORTANT that you download the whole set, some +dnl macros depend on other. Unfortunately, the autoconf archive does not +dnl support the concept of set of macros, so I had to break it for +dnl submission. +dnl The general documentation, as well as the sample configure.in, is +dnl included in the AC_PROG_JAVA macro. +dnl +dnl @author Stephane Bortzmeyer +dnl @version $Id: ac_prog_java_works.ac,v 1.1 2001/08/23 16:58:44 dda Exp $ +dnl +AC_DEFUN([AC_PROG_JAVA_WORKS], [ +AC_CHECK_PROG(uudecode, uudecode$EXEEXT, yes) +if test x$uudecode = xyes; then +AC_CACHE_CHECK([if uudecode can decode base 64 file], ac_cv_prog_uudecode_base64, [ +dnl /** +dnl * Test.java: used to test if java compiler works. +dnl */ +dnl public class Test +dnl { +dnl +dnl public static void +dnl main( String[] argv ) +dnl { +dnl System.exit (0); +dnl } +dnl +dnl } +cat << \EOF > Test.uue +begin-base64 644 Test.class +yv66vgADAC0AFQcAAgEABFRlc3QHAAQBABBqYXZhL2xhbmcvT2JqZWN0AQAE +bWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARDb2RlAQAPTGluZU51 +bWJlclRhYmxlDAAKAAsBAARleGl0AQAEKEkpVgoADQAJBwAOAQAQamF2YS9s +YW5nL1N5c3RlbQEABjxpbml0PgEAAygpVgwADwAQCgADABEBAApTb3VyY2VG +aWxlAQAJVGVzdC5qYXZhACEAAQADAAAAAAACAAkABQAGAAEABwAAACEAAQAB +AAAABQO4AAyxAAAAAQAIAAAACgACAAAACgAEAAsAAQAPABAAAQAHAAAAIQAB +AAEAAAAFKrcAErEAAAABAAgAAAAKAAIAAAAEAAQABAABABMAAAACABQ= +==== +EOF +if uudecode$EXEEXT Test.uue; then + ac_cv_prog_uudecode_base64=yes +else + echo "configure: __oline__: uudecode had trouble decoding base 64 file 'Test.uue'" >&AC_FD_CC + echo "configure: failed file was:" >&AC_FD_CC + cat Test.uue >&AC_FD_CC + ac_cv_prog_uudecode_base64=no +fi +rm -f Test.uue]) +fi +if test x$ac_cv_prog_uudecode_base64 != xyes; then + rm -f Test.class + AC_MSG_WARN([I have to compile Test.class from scratch]) + if test x$ac_cv_prog_javac_works = xno; then + AC_MSG_ERROR([Cannot compile java source. $JAVAC does not work properly]) + fi + if test x$ac_cv_prog_javac_works = x; then + AC_PROG_JAVAC + fi +fi +AC_CACHE_CHECK(if $JAVA works, ac_cv_prog_java_works, [ +JAVA_TEST=Test.java +CLASS_TEST=Test.class +TEST=Test +changequote(, )dnl +cat << \EOF > $JAVA_TEST +/* [#]line __oline__ "configure" */ +public class Test { +public static void main (String args[]) { + System.exit (0); +} } +EOF +changequote([, ])dnl +if test x$ac_cv_prog_uudecode_base64 != xyes; then + if AC_TRY_COMMAND($JAVAC $JAVACFLAGS $JAVA_TEST) && test -s $CLASS_TEST; then + : + else + echo "configure: failed program was:" >&AC_FD_CC + cat $JAVA_TEST >&AC_FD_CC + AC_MSG_ERROR(The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)) + fi +fi +if AC_TRY_COMMAND($JAVA $JAVAFLAGS $TEST) >/dev/null 2>&1; then + ac_cv_prog_java_works=yes +else + echo "configure: failed program was:" >&AC_FD_CC + cat $JAVA_TEST >&AC_FD_CC + AC_MSG_ERROR(The Java VM $JAVA failed (see config.log, check the CLASSPATH?)) +fi +rm -fr $JAVA_TEST $CLASS_TEST Test.uue +]) +AC_PROVIDE([$0])dnl +] +) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_javac.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_javac.ac new file mode 100644 index 00000000..5ded7d1b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_javac.ac @@ -0,0 +1,43 @@ +dnl @synopsis AC_PROG_JAVAC +dnl +dnl AC_PROG_JAVAC tests an existing Java compiler. It uses the environment +dnl variable JAVAC then tests in sequence various common Java compilers. For +dnl political reasons, it starts with the free ones. +dnl +dnl If you want to force a specific compiler: +dnl +dnl - at the configure.in level, set JAVAC=yourcompiler before calling +dnl AC_PROG_JAVAC +dnl +dnl - at the configure level, setenv JAVAC +dnl +dnl You can use the JAVAC variable in your Makefile.in, with @JAVAC@. +dnl +dnl *Warning*: its success or failure can depend on a proper setting of the +dnl CLASSPATH env. variable. +dnl +dnl TODO: allow to exclude compilers (rationale: most Java programs cannot compile +dnl with some compilers like guavac). +dnl +dnl Note: This is part of the set of autoconf M4 macros for Java programs. +dnl It is VERY IMPORTANT that you download the whole set, some +dnl macros depend on other. Unfortunately, the autoconf archive does not +dnl support the concept of set of macros, so I had to break it for +dnl submission. +dnl The general documentation, as well as the sample configure.in, is +dnl included in the AC_PROG_JAVA macro. +dnl +dnl @author Stephane Bortzmeyer +dnl @version $Id: ac_prog_javac.ac,v 1.3 2001/08/23 17:08:22 dda Exp $ +dnl +AC_DEFUN([AC_PROG_JAVAC],[ +AC_REQUIRE([AC_EXEEXT])dnl +if test "x$JAVAPREFIX" = x; then + test "x$JAVAC" = x && AC_CHECK_PROGS(JAVAC, javac$EXEEXT "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT) +else + test "x$JAVAC" = x && AC_CHECK_PROGS(JAVAC, javac$EXEEXT "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT, $JAVAPREFIX) +fi +test "x$JAVAC" = x && AC_MSG_ERROR([no acceptable Java compiler found in \$PATH]) +AC_PROG_JAVAC_WORKS +AC_PROVIDE([$0])dnl +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_javac_works.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_javac_works.ac new file mode 100644 index 00000000..139a99f9 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_javac_works.ac @@ -0,0 +1,35 @@ +dnl @synopsis AC_PROG_JAVAC_WORKS +dnl +dnl Internal use ONLY. +dnl +dnl Note: This is part of the set of autoconf M4 macros for Java programs. +dnl It is VERY IMPORTANT that you download the whole set, some +dnl macros depend on other. Unfortunately, the autoconf archive does not +dnl support the concept of set of macros, so I had to break it for +dnl submission. +dnl The general documentation, as well as the sample configure.in, is +dnl included in the AC_PROG_JAVA macro. +dnl +dnl @author Stephane Bortzmeyer +dnl @version $Id: ac_prog_javac_works.ac,v 1.1 2001/08/23 16:58:44 dda Exp $ +dnl +AC_DEFUN([AC_PROG_JAVAC_WORKS],[ +AC_CACHE_CHECK([if $JAVAC works], ac_cv_prog_javac_works, [ +JAVA_TEST=Test.java +CLASS_TEST=Test.class +cat << \EOF > $JAVA_TEST +/* [#]line __oline__ "configure" */ +public class Test { +} +EOF +if AC_TRY_COMMAND($JAVAC $JAVACFLAGS $JAVA_TEST) >/dev/null 2>&1; then + ac_cv_prog_javac_works=yes +else + AC_MSG_ERROR([The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)]) + echo "configure: failed program was:" >&AC_FD_CC + cat $JAVA_TEST >&AC_FD_CC +fi +rm -f $JAVA_TEST $CLASS_TEST +]) +AC_PROVIDE([$0])dnl +]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_javadoc.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_javadoc.ac new file mode 100644 index 00000000..5154d3f1 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_javadoc.ac @@ -0,0 +1,37 @@ +dnl @synopsis AC_PROG_JAVADOC +dnl +dnl AC_PROG_JAVADOC tests for an existing javadoc generator. It uses the environment +dnl variable JAVADOC then tests in sequence various common javadoc generator. +dnl +dnl If you want to force a specific compiler: +dnl +dnl - at the configure.in level, set JAVADOC=yourgenerator before calling +dnl AC_PROG_JAVADOC +dnl +dnl - at the configure level, setenv JAVADOC +dnl +dnl You can use the JAVADOC variable in your Makefile.in, with @JAVADOC@. +dnl +dnl Note: This macro depends on the autoconf M4 macros for Java programs. +dnl It is VERY IMPORTANT that you download that whole set, some +dnl macros depend on other. Unfortunately, the autoconf archive does not +dnl support the concept of set of macros, so I had to break it for +dnl submission. +dnl +dnl The general documentation of those macros, as well as the sample +dnl configure.in, is included in the AC_PROG_JAVA macro. +dnl +dnl @author Egon Willighagen +dnl @version $Id: ac_prog_javadoc.ac,v 1.1 2001/08/23 16:58:44 dda Exp $ +dnl +AC_DEFUN([AC_PROG_JAVADOC],[ +AC_REQUIRE([AC_EXEEXT])dnl +if test "x$JAVAPREFIX" = x; then + test "x$JAVADOC" = x && AC_CHECK_PROGS(JAVADOC, javadoc$EXEEXT) +else + test "x$JAVADOC" = x && AC_CHECK_PROGS(JAVADOC, javadoc, $JAVAPREFIX) +fi +test "x$JAVADOC" = x && AC_MSG_ERROR([no acceptable javadoc generator found in \$PATH]) +AC_PROVIDE([$0])dnl +]) + diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_javah.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_javah.ac new file mode 100644 index 00000000..1b16d9e2 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_prog_javah.ac @@ -0,0 +1,26 @@ +dnl @synopsis AC_PROG_JAVAH +dnl +dnl AC_PROG_JAVAH tests the availability of the javah header generator +dnl and looks for the jni.h header file. If available, JAVAH is set to +dnl the full path of javah and CPPFLAGS is updated accordingly. +dnl +dnl @author Luc Maisonobe +dnl @version $Id: ac_prog_javah.ac,v 1.1 2001/08/23 16:58:44 dda Exp $ +dnl +AC_DEFUN([AC_PROG_JAVAH],[ +AC_REQUIRE([AC_CANONICAL_SYSTEM])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_PATH_PROG(JAVAH,javah) +if test x"`eval 'echo $ac_cv_path_JAVAH'`" != x ; then + AC_TRY_CPP([#include ],,[ + ac_save_CPPFLAGS="$CPPFLAGS" +changequote(, )dnl + ac_dir=`echo $ac_cv_path_JAVAH | sed 's,\(.*\)/[^/]*/[^/]*$,\1/include,'` + ac_machdep=`echo $build_os | sed 's,[-0-9].*,,'` +changequote([, ])dnl + CPPFLAGS="$ac_save_CPPFLAGS -I$ac_dir -I$ac_dir/$ac_machdep" + AC_TRY_CPP([#include ], + ac_save_CPPFLAGS="$CPPFLAGS", + AC_MSG_WARN([unable to include ])) + CPPFLAGS="$ac_save_CPPFLAGS"]) +fi]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_try_compile_java.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_try_compile_java.ac new file mode 100644 index 00000000..775569ba --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_try_compile_java.ac @@ -0,0 +1,39 @@ +dnl @synopsis AC_TRY_COMPILE_JAVA +dnl +dnl AC_TRY_COMPILE_JAVA attempt to compile user given source. +dnl +dnl *Warning*: its success or failure can depend on a proper setting of the +dnl CLASSPATH env. variable. +dnl +dnl Note: This is part of the set of autoconf M4 macros for Java programs. +dnl It is VERY IMPORTANT that you download the whole set, some +dnl macros depend on other. Unfortunately, the autoconf archive does not +dnl support the concept of set of macros, so I had to break it for +dnl submission. +dnl The general documentation, as well as the sample configure.in, is +dnl included in the AC_PROG_JAVA macro. +dnl +dnl @author Devin Weaver +dnl @version $Id: ac_try_compile_java.ac,v 1.1 2001/08/23 16:58:44 dda Exp $ +dnl +AC_DEFUN([AC_TRY_COMPILE_JAVA],[ +AC_REQUIRE([AC_PROG_JAVAC])dnl +cat << \EOF > Test.java +/* [#]line __oline__ "configure" */ +ifelse([$1], , , [import $1;]) +public class Test { +[$2] +} +EOF +if AC_TRY_COMMAND($JAVAC $JAVACFLAGS Test.java) && test -s Test.class +then +dnl Don't remove the temporary files here, so they can be examined. + ifelse([$3], , :, [$3]) +else + echo "configure: failed program was:" >&AC_FD_CC + cat Test.java >&AC_FD_CC +ifelse([$4], , , [ rm -fr Test* + $4 +])dnl +fi +rm -fr Test*]) diff --git a/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_try_run_javac.ac b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_try_run_javac.ac new file mode 100644 index 00000000..cf91306a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/aclocal_java/ac_try_run_javac.ac @@ -0,0 +1,40 @@ +dnl @synopsis AC_TRY_RUN_JAVA +dnl +dnl AC_TRY_RUN_JAVA attempt to compile and run user given source. +dnl +dnl *Warning*: its success or failure can depend on a proper setting of the +dnl CLASSPATH env. variable. +dnl +dnl Note: This is part of the set of autoconf M4 macros for Java programs. +dnl It is VERY IMPORTANT that you download the whole set, some +dnl macros depend on other. Unfortunately, the autoconf archive does not +dnl support the concept of set of macros, so I had to break it for +dnl submission. +dnl The general documentation, as well as the sample configure.in, is +dnl included in the AC_PROG_JAVA macro. +dnl +dnl @author Devin Weaver +dnl @version $Id: ac_try_run_javac.ac,v 1.1 2001/08/23 16:58:45 dda Exp $ +dnl +AC_DEFUN([AC_TRY_RUN_JAVA],[ +AC_REQUIRE([AC_PROG_JAVAC])dnl +AC_REQUIRE([AC_PROG_JAVA])dnl +cat << \EOF > Test.java +/* [#]line __oline__ "configure" */ +ifelse([$1], , , [include $1;]) +public class Test { +[$2] +} +EOF +if AC_TRY_COMMAND($JAVAC $JAVACFLAGS Test.java) && test -s Test.class && ($JAVA $JAVAFLAGS Test; exit) 2>/dev/null +then +dnl Don't remove the temporary files here, so they can be examined. + ifelse([$3], , :, [$3]) +else + echo "configure: failed program was:" >&AC_FD_CC + cat Test.java >&AC_FD_CC +ifelse([$4], , , [ rm -fr Test* + $4 +])dnl +fi +rm -fr Test*]) diff --git a/src/libs/resiprocate/contrib/db/dist/buildrel b/src/libs/resiprocate/contrib/db/dist/buildrel new file mode 100644 index 00000000..2537376a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/buildrel @@ -0,0 +1,128 @@ +# $Id: buildrel,v 1.65 2004/11/09 01:26:29 bostic Exp $ +# +# Build the distribution package. +# +# A set of commands intended to be cut and pasted into a csh window. + +# Development tree, release home. +setenv D `pwd` + +# Update the release number. +cd $D/dist +cvs -q update RELEASE +vi RELEASE +setenv VERSION `sh -c '. RELEASE; echo $DB_VERSION'` +echo "Version: $VERSION" + +# Make sure the source tree is up-to-date +cd $D && cvs -q update + +# Build auto-generated files. +cd $D/dist && sh s_all + +# Commit all of the changes. +cd $D && cvs -q commit + +# Copy a development tree into a release tree. +setenv R /var/tmp/db-$VERSION +rm -rf $R && mkdir -p $R +cd $D && cvs -q status | \ + grep "Repository revision" | \ + sed -e 's;.*CVSROOT/db/;;' \ + -e 's;.*CVSROOT/;;' \ + -e 's;,v$;;' | pax -rw $R/ + +# Build the documentation, copy it into place. +cd db_docs && cvs -q update +cd db_docs && sh build $D clean && sh build $D |& sed '/.html$/d' +cd je/docs_src && sh build db ../../db +rm -rf $R/docs && cp -r $D/docs $R/docs + +# Remove source directories we don't distribute. +cd $R && rm -rf docs_src docs/api_java +cd $R && rm -rf test/TODO test/upgrade test_perf test_purify +cd $R && rm -rf test_server test_thread test_vxworks test_xa +cd $R && rm -rf java/src/com/sleepycat/xa + +# Fix symbolic links and permissions. +cd $R/dist && sh s_perm +cd $R/dist && sh s_symlink + +# Build a version and smoke test. +cd $R && rm -rf build_run && mkdir build_run +cd $R/build_run && ~bostic/bin/dbconf && make >& mklog +cd $R/build_run && make ex_access && ./ex_access + +# Check the install +cd $R/build_run && make prefix=`pwd`/BDB install + +# Build a small-footprint version and smoke test. +cd $R && rm -rf build_run && mkdir build_run +cd $R/build_run && ../dist/configure --enable-smallbuild && make >& mklog +cd $R/build_run && make ex_access && ./ex_access + +# Remove the build directory +cd $R && rm -rf build_run + +# ACQUIRE ROOT PRIVILEGES +cd $R && find . -type d | xargs chmod 775 +cd $R && find . -type f | xargs chmod 444 +cd $R && chmod 664 build_win32/*.dsp +cd $R/dist && sh s_perm +chown -R 100 $R +chgrp -R 100 $R +# DISCARD ROOT PRIVILEGES + +# Check for file names differing only in case. +cd $R && find . | sort -f | uniq -ic | sed '/1 /d' + +# Create the crypto tar archive release. +setenv T "$R/../db-$VERSION.tar.gz" +cd $R/.. && tar cf - db-$VERSION | gzip --best > $T +chmod 444 $T + +# Check the path length. +gzcat $T | tar tf - |\ +awk '{ if (length() > 99) print "Path length: " length() " bytes: " $0;}' + +# Create the non-crypto tree. +setenv RNC "$R/../db-$VERSION.NC" +rm -rf $RNC $R/../__TMP && mkdir $R/../__TMP +cd $R/../__TMP && gzcat $T | tar xpf - && mv -i db-$VERSION $RNC +cd $R && rm -rf $R/../__TMP +cd $RNC/dist && sh s_crypto + +# ACQUIRE ROOT PRIVILEGES +cd $RNC && find . -type d | xargs chmod 775 +cd $RNC && find . -type f | xargs chmod 444 +cd $RNC && chmod 664 build_win32/*.dsp +cd $RNC/dist && sh s_perm +chown -R 100 $RNC +chgrp -R 100 $RNC +# DISCARD ROOT PRIVILEGES + +# Create the non-crypto tar archive release. +setenv T "$R/../db-$VERSION.NC.tar.gz" +cd $RNC/.. && tar cf - db-$VERSION.NC | gzip --best > $T +chmod 444 $T + +# Check the path length. +gzcat $T | tar tf - |\ +awk '{ if (length() > 99) print "Path length: " length() " bytes: " $0;}' + +# Remove tags files. They're large and we don't want to store symbolic links +# in the zip archive for portability reasons. +# ACQUIRE ROOT PRIVILEGES +cd $R && rm -f `find . -name 'tags'` +cd $RNC && rm -f `find . -name 'tags'` +# DISCARD ROOT PRIVILEGES + +# Create the crypto zip archive release. +setenv T "$R/../db-$VERSION.zip" +cd $R/.. && zip -r - db-$VERSION > $T +chmod 444 $T + +# Create the non-crypto zip archive release. +setenv T "$R/../db-$VERSION.NC.zip" +cd $RNC/.. && zip -r - db-$VERSION.NC > $T +chmod 444 $T diff --git a/src/libs/resiprocate/contrib/db/dist/config.guess b/src/libs/resiprocate/contrib/db/dist/config.guess new file mode 100644 index 00000000..3eda297e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/config.guess @@ -0,0 +1,1558 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +timestamp='2009-02-03' + +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[456]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd | genuineintel) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/libs/resiprocate/contrib/db/dist/config.hin b/src/libs/resiprocate/contrib/db/dist/config.hin new file mode 100644 index 00000000..6cfd7767 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/config.hin @@ -0,0 +1,599 @@ +/* config.hin. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you want to build a version for running the test suite. */ +#undef CONFIG_TEST + +/* We use DB_WIN32 much as one would use _WIN32 -- to specify that we're using + an operating system environment that supports Win32 calls and semantics. We + don't use _WIN32 because Cygwin/GCC also defines _WIN32, even though + Cygwin/GCC closely emulates the Unix environment. */ +#undef DB_WIN32 + +/* Define to 1 if you want a debugging version. */ +#undef DEBUG + +/* Define to 1 if you want a version that logs read operations. */ +#undef DEBUG_ROP + +/* Define to 1 if you want a version that logs write operations. */ +#undef DEBUG_WOP + +/* Define to 1 if you want a version with run-time diagnostic checking. */ +#undef DIAGNOSTIC + +/* Define to 1 if 64-bit types are available. */ +#undef HAVE_64BIT_TYPES + +/* Define to 1 if you have the `abort' function. */ +#undef HAVE_ABORT + +/* Define to 1 if you have the `atoi' function. */ +#undef HAVE_ATOI + +/* Define to 1 if you have the `atol' function. */ +#undef HAVE_ATOL + +/* Define to 1 to use Solaris library routes for atomic operations. */ +#undef HAVE_ATOMIC_SOLARIS + +/* Define to 1 to use native atomic operations. */ +#undef HAVE_ATOMIC_SUPPORT + +/* Define to 1 to use GCC and x86 or x86_64 assemlby language atomic + operations. */ +#undef HAVE_ATOMIC_X86_GCC_ASSEMBLY + +/* Define to 1 if you have the `backtrace' function. */ +#undef HAVE_BACKTRACE + +/* Define to 1 if you have the `backtrace_symbols' function. */ +#undef HAVE_BACKTRACE_SYMBOLS + +/* Define to 1 if building on BREW. */ +#undef HAVE_BREW + +/* Define to 1 if building on BREW (SDK2). */ +#undef HAVE_BREW_SDK2 + +/* Define to 1 if you have the `clock_gettime' function. */ +#undef HAVE_CLOCK_GETTIME + +/* Define to 1 if clock_gettime supports CLOCK_MONOTONIC. */ +#undef HAVE_CLOCK_MONOTONIC + +/* Define to 1 if building compression support. */ +#undef HAVE_COMPRESSION + +/* Define to 1 if Berkeley DB release includes strong cryptography. */ +#undef HAVE_CRYPTO + +/* Define to 1 if you have the `ctime_r' function. */ +#undef HAVE_CTIME_R + +/* Define to 1 if ctime_r takes a buffer length as a third argument. */ +#undef HAVE_CTIME_R_3ARG + +/* Define to 1 if you have the `directio' function. */ +#undef HAVE_DIRECTIO + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_EXECINFO_H + +/* Define to 1 if platform has EXIT_SUCCESS/EXIT_FAILURE #defines. */ +#undef HAVE_EXIT_SUCCESS + +/* Define to 1 if you have the `fchmod' function. */ +#undef HAVE_FCHMOD + +/* Define to 1 if you have the `fclose' function. */ +#undef HAVE_FCLOSE + +/* Define to 1 if you have the `fcntl' function. */ +#undef HAVE_FCNTL + +/* Define to 1 if fcntl/F_SETFD denies child access to file descriptors. */ +#undef HAVE_FCNTL_F_SETFD + +/* Define to 1 if you have the `fdatasync' function. */ +#undef HAVE_FDATASYNC + +/* Define to 1 if you have the `fgetc' function. */ +#undef HAVE_FGETC + +/* Define to 1 if you have the `fgets' function. */ +#undef HAVE_FGETS + +/* Define to 1 if allocated filesystem blocks are not zeroed. */ +#undef HAVE_FILESYSTEM_NOTZERO + +/* Define to 1 if you have the `fopen' function. */ +#undef HAVE_FOPEN + +/* Define to 1 if you have the `ftruncate' function. */ +#undef HAVE_FTRUNCATE + +/* Define to 1 if you have the `fwrite' function. */ +#undef HAVE_FWRITE + +/* Define to 1 if you have the `getaddrinfo' function. */ +#undef HAVE_GETADDRINFO + +/* Define to 1 if you have the `getcwd' function. */ +#undef HAVE_GETCWD + +/* Define to 1 if you have the `getenv' function. */ +#undef HAVE_GETENV + +/* Define to 1 if you have the `getgid' function. */ +#undef HAVE_GETGID + +/* Define to 1 if you have the `getopt' function. */ +#undef HAVE_GETOPT + +/* Define to 1 if getopt supports the optreset variable. */ +#undef HAVE_GETOPT_OPTRESET + +/* Define to 1 if you have the `getrusage' function. */ +#undef HAVE_GETRUSAGE + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the `getuid' function. */ +#undef HAVE_GETUID + +/* Define to 1 if building Hash access method. */ +#undef HAVE_HASH + +/* Define to 1 if you have the `hstrerror' function. */ +#undef HAVE_HSTRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `isalpha' function. */ +#undef HAVE_ISALPHA + +/* Define to 1 if you have the `isdigit' function. */ +#undef HAVE_ISDIGIT + +/* Define to 1 if you have the `isprint' function. */ +#undef HAVE_ISPRINT + +/* Define to 1 if you have the `isspace' function. */ +#undef HAVE_ISSPACE + +/* Define to 1 if you have the `localtime' function. */ +#undef HAVE_LOCALTIME + +/* Define to 1 if you have the `memcmp' function. */ +#undef HAVE_MEMCMP + +/* Define to 1 if you have the `memcpy' function. */ +#undef HAVE_MEMCPY + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mlock' function. */ +#undef HAVE_MLOCK + +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the `mprotect' function. */ +#undef HAVE_MPROTECT + +/* Define to 1 if you have the `munlock' function. */ +#undef HAVE_MUNLOCK + +/* Define to 1 if you have the `munmap' function. */ +#undef HAVE_MUNMAP + +/* Define to 1 to use the GCC compiler and 68K assembly language mutexes. */ +#undef HAVE_MUTEX_68K_GCC_ASSEMBLY + +/* Define to 1 to use the AIX _check_lock mutexes. */ +#undef HAVE_MUTEX_AIX_CHECK_LOCK + +/* Define to 1 to use the GCC compiler and Alpha assembly language mutexes. */ +#undef HAVE_MUTEX_ALPHA_GCC_ASSEMBLY + +/* Define to 1 to use the GCC compiler and ARM assembly language mutexes. */ +#undef HAVE_MUTEX_ARM_GCC_ASSEMBLY + +/* Define to 1 to use the Apple/Darwin _spin_lock_try mutexes. */ +#undef HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY + +/* Define to 1 to use the UNIX fcntl system call mutexes. */ +#undef HAVE_MUTEX_FCNTL + +/* Define to 1 to use the GCC compiler and PaRisc assembly language mutexes. + */ +#undef HAVE_MUTEX_HPPA_GCC_ASSEMBLY + +/* Define to 1 to use the msem_XXX mutexes on HP-UX. */ +#undef HAVE_MUTEX_HPPA_MSEM_INIT + +/* Define to 1 to use test-and-set mutexes with blocking mutexes. */ +#undef HAVE_MUTEX_HYBRID + +/* Define to 1 to use the GCC compiler and IA64 assembly language mutexes. */ +#undef HAVE_MUTEX_IA64_GCC_ASSEMBLY + +/* Define to 1 to use the GCC compiler and MIPS assembly language mutexes. */ +#undef HAVE_MUTEX_MIPS_GCC_ASSEMBLY + +/* Define to 1 to use the msem_XXX mutexes on systems other than HP-UX. */ +#undef HAVE_MUTEX_MSEM_INIT + +/* Define to 1 to use the GCC compiler and PowerPC assembly language mutexes. + */ +#undef HAVE_MUTEX_PPC_GCC_ASSEMBLY + +/* Define to 1 to use POSIX 1003.1 pthread_XXX mutexes. */ +#undef HAVE_MUTEX_PTHREADS + +/* Define to 1 to use Reliant UNIX initspin mutexes. */ +#undef HAVE_MUTEX_RELIANTUNIX_INITSPIN + +/* Define to 1 to use the IBM C compiler and S/390 assembly language mutexes. + */ +#undef HAVE_MUTEX_S390_CC_ASSEMBLY + +/* Define to 1 to use the GCC compiler and S/390 assembly language mutexes. */ +#undef HAVE_MUTEX_S390_GCC_ASSEMBLY + +/* Define to 1 to use the SCO compiler and x86 assembly language mutexes. */ +#undef HAVE_MUTEX_SCO_X86_CC_ASSEMBLY + +/* Define to 1 to use the obsolete POSIX 1003.1 sema_XXX mutexes. */ +#undef HAVE_MUTEX_SEMA_INIT + +/* Define to 1 to use the SGI XXX_lock mutexes. */ +#undef HAVE_MUTEX_SGI_INIT_LOCK + +/* Define to 1 to use the Solaris _lock_XXX mutexes. */ +#undef HAVE_MUTEX_SOLARIS_LOCK_TRY + +/* Define to 1 to use the Solaris lwp threads mutexes. */ +#undef HAVE_MUTEX_SOLARIS_LWP + +/* Define to 1 to use the GCC compiler and Sparc assembly language mutexes. */ +#undef HAVE_MUTEX_SPARC_GCC_ASSEMBLY + +/* Define to 1 if the Berkeley DB library should support mutexes. */ +#undef HAVE_MUTEX_SUPPORT + +/* Define to 1 if mutexes hold system resources. */ +#undef HAVE_MUTEX_SYSTEM_RESOURCES + +/* Define to 1 to configure mutexes intra-process only. */ +#undef HAVE_MUTEX_THREAD_ONLY + +/* Define to 1 to use the CC compiler and Tru64 assembly language mutexes. */ +#undef HAVE_MUTEX_TRU64_CC_ASSEMBLY + +/* Define to 1 to use the UNIX International mutexes. */ +#undef HAVE_MUTEX_UI_THREADS + +/* Define to 1 to use the UTS compiler and assembly language mutexes. */ +#undef HAVE_MUTEX_UTS_CC_ASSEMBLY + +/* Define to 1 to use VMS mutexes. */ +#undef HAVE_MUTEX_VMS + +/* Define to 1 to use VxWorks mutexes. */ +#undef HAVE_MUTEX_VXWORKS + +/* Define to 1 to use the MSVC compiler and Windows mutexes. */ +#undef HAVE_MUTEX_WIN32 + +/* Define to 1 to use the GCC compiler and Windows mutexes. */ +#undef HAVE_MUTEX_WIN32_GCC + +/* Define to 1 to use the GCC compiler and 64-bit x86 assembly language + mutexes. */ +#undef HAVE_MUTEX_X86_64_GCC_ASSEMBLY + +/* Define to 1 to use the GCC compiler and 32-bit x86 assembly language + mutexes. */ +#undef HAVE_MUTEX_X86_GCC_ASSEMBLY + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the O_DIRECT flag. */ +#undef HAVE_O_DIRECT + +/* Define to 1 if building partitioned database support. */ +#undef HAVE_PARTITION + +/* Define to 1 if you have the `pread' function. */ +#undef HAVE_PREAD + +/* Define to 1 if you have the `printf' function. */ +#undef HAVE_PRINTF + +/* Define to 1 if you have the `pstat_getdynamic' function. */ +#undef HAVE_PSTAT_GETDYNAMIC + +/* Define to 1 if you have the `pthread_self' function. */ +#undef HAVE_PTHREAD_SELF + +/* Define to 1 if you have the `pthread_yield' function. */ +#undef HAVE_PTHREAD_YIELD + +/* Define to 1 if you have the `pwrite' function. */ +#undef HAVE_PWRITE + +/* Define to 1 if building on QNX. */ +#undef HAVE_QNX + +/* Define to 1 if you have the `qsort' function. */ +#undef HAVE_QSORT + +/* Define to 1 if building Queue access method. */ +#undef HAVE_QUEUE + +/* Define to 1 if you have the `raise' function. */ +#undef HAVE_RAISE + +/* Define to 1 if you have the `rand' function. */ +#undef HAVE_RAND + +/* Define to 1 if you have the `random' function. */ +#undef HAVE_RANDOM + +/* Define to 1 if building replication support. */ +#undef HAVE_REPLICATION + +/* Define to 1 if building the Berkeley DB replication framework. */ +#undef HAVE_REPLICATION_THREADS + +/* Define to 1 if building RPC client/server. */ +#undef HAVE_RPC + +/* Define to 1 if building on S60. */ +#undef HAVE_S60 + +/* Define to 1 if you have the `sched_yield' function. */ +#undef HAVE_SCHED_YIELD + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the `setgid' function. */ +#undef HAVE_SETGID + +/* Define to 1 if you have the `setuid' function. */ +#undef HAVE_SETUID + +/* Define to 1 to configure Berkeley DB to use read/write latches. */ +#undef HAVE_SHARED_LATCHES + +/* Define to 1 if shmctl/SHM_LOCK locks down shared memory segments. */ +#undef HAVE_SHMCTL_SHM_LOCK + +/* Define to 1 if you have the `shmget' function. */ +#undef HAVE_SHMGET + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if thread identifier type db_threadid_t is integral. */ +#undef HAVE_SIMPLE_THREAD_TYPE + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the `stat' function. */ +#undef HAVE_STAT + +/* Define to 1 if building statistics support. */ +#undef HAVE_STATISTICS + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strcat' function. */ +#undef HAVE_STRCAT + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the `strftime' function. */ +#undef HAVE_STRFTIME + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strncat' function. */ +#undef HAVE_STRNCAT + +/* Define to 1 if you have the `strncmp' function. */ +#undef HAVE_STRNCMP + +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + +/* Define to 1 if you have the `strsep' function. */ +#undef HAVE_STRSEP + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* Define to 1 if `st_blksize' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_BLKSIZE + +/* Define to 1 if you have the `sysconf' function. */ +#undef HAVE_SYSCONF + +/* Define to 1 if port includes files in the Berkeley DB source code. */ +#undef HAVE_SYSTEM_INCLUDE_FILES + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the `time' function. */ +#undef HAVE_TIME + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if unlink of file with open file descriptors will fail. */ +#undef HAVE_UNLINK_WITH_OPEN_FAILURE + +/* Define to 1 if port includes historic database upgrade support. */ +#undef HAVE_UPGRADE_SUPPORT + +/* Define to 1 if building access method verification support. */ +#undef HAVE_VERIFY + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Define to 1 if building on VxWorks. */ +#undef HAVE_VXWORKS + +/* Define to 1 if you have the `yield' function. */ +#undef HAVE_YIELD + +/* Define to 1 if you have the `_fstati64' function. */ +#undef HAVE__FSTATI64 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of `char', as computed by sizeof. */ +#undef SIZEOF_CHAR + +/* The size of `char *', as computed by sizeof. */ +#undef SIZEOF_CHAR_P + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `long long', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG + +/* The size of `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* The size of `size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + +/* The size of `unsigned char', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_CHAR + +/* The size of `unsigned int', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_INT + +/* The size of `unsigned long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG + +/* The size of `unsigned long long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG_LONG + +/* The size of `unsigned short', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_SHORT + +/* Define to 1 if the `S_IS*' macros in do not work properly. */ +#undef STAT_MACROS_BROKEN + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 to mask harmless uninitialized memory read/writes. */ +#undef UMRW + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* type to use in place of socklen_t if not defined */ +#undef socklen_t diff --git a/src/libs/resiprocate/contrib/db/dist/config.sub b/src/libs/resiprocate/contrib/db/dist/config.sub new file mode 100644 index 00000000..d546a94b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/config.sub @@ -0,0 +1,1685 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +timestamp='2009-02-03' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/libs/resiprocate/contrib/db/dist/configure b/src/libs/resiprocate/contrib/db/dist/configure new file mode 100644 index 00000000..295fec1f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/configure @@ -0,0 +1,24377 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.65 for Berkeley DB 4.8.30. +# +# Report bugs to . +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and Oracle Technology +$0: Network Berkeley DB forum about your system, including +$0: any error possibly output before this message. Then +$0: install a modern shell, or manually run the script +$0: under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$lt_ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +ECHO=${lt_ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<_LT_EOF +$* +_LT_EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test -z "$lt_ECHO"; then + if test "X${echo_test_string+set}" != Xset; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if { echo_test_string=`eval $cmd`; } 2>/dev/null && + { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null + then + break + fi + done + fi + + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : + else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$ECHO" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + ECHO='print -r' + elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + ECHO='printf %s\n' + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + ECHO="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + ECHO=echo + fi + fi + fi + fi + fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +lt_ECHO=$ECHO +if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='Berkeley DB' +PACKAGE_TARNAME='db-4.8.30' +PACKAGE_VERSION='4.8.30' +PACKAGE_STRING='Berkeley DB 4.8.30' +PACKAGE_BUGREPORT='Oracle Technology Network Berkeley DB forum' +PACKAGE_URL='' + +ac_unique_file="../db/db.c" +ac_default_prefix=/usr/local/BerkeleyDB.4.8 +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='LTLIBOBJS +db_seq_decl +UINT64_FMT +INT64_FMT +TCL_TCLSH +TCL_SRC_DIR +TCL_LIB_FILE +TCL_INCLUDE_SPEC +TCL_BIN_DIR +LIBOBJS +db_threadid_t_decl +thread_h_decl +uintptr_t_decl +uintmax_t_decl +ssize_t_decl +time_t_decl +size_t_decl +pid_t_decl +off_t_decl +FILE_t_decl +int64_decl +u_int64_decl +int32_decl +u_int32_decl +int16_decl +u_int16_decl +u_int8_decl +u_long_decl +u_int_decl +u_short_decl +u_char_decl +unistd_h_decl +stddef_h_decl +stdint_h_decl +inttypes_h_decl +TLS_defn +TLS_decl +WSTRING_decl +_ACJNI_JAVAC +uudecode +JAVA +JAVAC +JMODSUFFIX +MODSUFFIX +SOSUFFIX +CPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +lt_ECHO +RANLIB +STRIP +AR +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +cxx_have_stdheaders +CXXCPP +ac_ct_CXX +CCC +OBJEXT +EXEEXT +ac_ct_CC +CC +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +db_cv_path_sh +RPCGEN +RM +MKDIR +LN +KILL +CP +CHMOD +DB_VERSION_UNIQUE_NAME +DB_VERSION_STRING +DB_VERSION_PATCH +DB_VERSION_MINOR +DB_VERSION_MAJOR +platform_footer +platform_header +o +db_int_def +TEST_LIBS +SWIGCFLAGS +SOFLAGS +RPC_SERVER_H +RPC_CLIENT_OBJS +REPLACEMENT_OBJS +POSTLINK +OSDIR +MAKEFILE_XSOLINK +MAKEFILE_SOLINK +MAKEFILE_CXXLINK +MAKEFILE_CXX +MAKEFILE_CCLINK +MAKEFILE_CC +LIBXSO_LIBS +LIBTSO_MODULE +LIBTSO_MODSUFFIX +LIBTSO_LIBS +LIBTOOL +LIBSO_LIBS +LIBJSO_LIBS +LIBCSO_LIBS +LDFLAGS +JAVACFLAGS +JAR +INSTALL_TARGET +INSTALL_LIBS +INSTALLER +DEFAULT_LIB_STL +DEFAULT_LIB_CXX +DEFAULT_LIB +DB_PROTO2 +DB_PROTO1 +DB_CONST +CXXFLAGS +CXX +CRYPTO_OBJS +CPPFLAGS +CONFIGURATION_PATH +CONFIGURATION_ARGS +CFLAGS +BUILD_TARGET +ADDITIONAL_PROGS +ADDITIONAL_OBJS +ADDITIONAL_LANG +ADDITIONAL_INCS +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_bigfile +enable_cryptography +enable_hash +enable_partition +enable_compression +enable_mutexsupport +enable_atomicsupport +enable_queue +enable_replication +enable_statistics +enable_verify +enable_compat185 +enable_cxx +enable_debug +enable_debug_rop +enable_debug_wop +enable_diagnostic +enable_dump185 +enable_java +enable_mingw +enable_o_direct +enable_posixmutexes +enable_pthread_self +enable_pthread_api +enable_rpc +enable_smallbuild +enable_stl +enable_tcl +enable_test +enable_uimutexes +enable_umrw +with_mutex +with_mutexalign +with_tcl +with_uniquename +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +enable_libtool_lock +enable_largefile +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CXXCPP +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information." + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures Berkeley DB 4.8.30 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root + [DATAROOTDIR/doc/db-4.8.30] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of Berkeley DB 4.8.30:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-bigfile Obsolete; use --disable-largefile instead. + --disable-cryptography Do not build database cryptography support. + --disable-hash Do not build Hash access method. + --disable-partition Do not build partitioned database support. + --disable-compression Do not build compression support. + --disable-mutexsupport Do not build any mutex support. + --disable-atomicsupport Do not build any native atomic operation support. + --disable-queue Do not build Queue access method. + --disable-replication Do not build database replication support. + --disable-statistics Do not build statistics support. + --disable-verify Do not build database verification support. + --enable-compat185 Build DB 1.85 compatibility API. + --enable-cxx Build C++ API. + --enable-debug Build a debugging version. + --enable-debug_rop Build a version that logs read operations. + --enable-debug_wop Build a version that logs write operations. + --enable-diagnostic Build a version with run-time diagnostics. + --enable-dump185 Build db_dump185(1) to dump 1.85 databases. + --enable-java Build Java API. + --enable-mingw Build Berkeley DB for MinGW. + --enable-o_direct Enable the O_DIRECT flag for direct I/O. + --enable-posixmutexes Force use of POSIX standard mutexes. + + --enable-smallbuild Build small footprint version of the library. + --enable-stl Build STL API. + --enable-tcl Build Tcl API. + --enable-test Configure to run the test suite. + --enable-uimutexes Force use of Unix International mutexes. + --enable-umrw Mask harmless uninitialized memory read/writes. + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --disable-largefile omit support for large files + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-mutex=MUTEX Select non-default mutex implementation. + --with-mutexalign=ALIGNMENT + Obsolete; use DbEnv::mutex_set_align instead. + --with-tcl=DIR Directory location of tclConfig.sh. + --with-uniquename=NAME Build a uniquely named library. + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CXXCPP C++ preprocessor + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +Berkeley DB configure 4.8.30 +generated by GNU Autoconf 2.65 + +Copyright (C) 2009 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( cat <<\_ASBOX +## ---------------------------------------------------------- ## +## Report this to Oracle Technology Network Berkeley DB forum ## +## ---------------------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_member + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 &5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_type +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by Berkeley DB $as_me 4.8.30, which was +generated by GNU Autoconf 2.65. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + ac_site_file1=$CONFIG_SITE +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_config_headers="$ac_config_headers db_config.h:config.hin" + + + + +# Configure setup. +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + for ac_t in install-sh install.sh shtool; do + if test -f "$ac_dir/$ac_t"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/$ac_t -c" + break 2 + fi + done +done +if test -z "$ac_aux_dir"; then + as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if test "${ac_cv_build+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + + +# Don't build in the top-level or dist directories. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if building in the top-level or dist directories" >&5 +$as_echo_n "checking if building in the top-level or dist directories... " >&6; } +if test -d db_archive -o -f configure.ac ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + as_fn_error "\ +Berkeley DB should not be built in the top-level or \"dist\" directories. \ +Change directory to the build_unix directory and run ../dist/configure \ +from there." "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +# Substitution variables. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# The Windows public header has two extra symbols we need to remove. + + + +# Set the default installation location. + + +# Configure the version information. + +DB_VERSION_MAJOR="4" + +DB_VERSION_MINOR="8" + +DB_VERSION_PATCH="30" + +DB_VERSION_STRING='"Berkeley DB 4.8.30: (April 9, 2010)"' + + +# Process all options before using them. + + +# --enable-bigfile was the configuration option that Berkeley DB used before +# autoconf 2.50 was released (which had --enable-largefile integrated in). +# Check whether --enable-bigfile was given. +if test "${enable_bigfile+set}" = set; then : + enableval=$enable_bigfile; as_fn_error "--enable-bigfile no longer supported, use --enable-largefile" "$LINENO" 5 +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-cryptography option specified" >&5 +$as_echo_n "checking if --disable-cryptography option specified... " >&6; } +# Check whether --enable-cryptography was given. +if test "${enable_cryptography+set}" = set; then : + enableval=$enable_cryptography; +else + enableval="yes" +fi + +db_cv_build_cryptography="$enableval" +case "$enableval" in + no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; };; +yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; };; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-hash option specified" >&5 +$as_echo_n "checking if --disable-hash option specified... " >&6; } +# Check whether --enable-hash was given. +if test "${enable_hash+set}" = set; then : + enableval=$enable_hash; +else + enableval="yes" +fi + +db_cv_build_hash="$enableval" +case "$enableval" in + no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; };; +yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; };; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-partition option specified" >&5 +$as_echo_n "checking if --disable-partition option specified... " >&6; } +# Check whether --enable-partition was given. +if test "${enable_partition+set}" = set; then : + enableval=$enable_partition; +else + enableval="yes" +fi + +db_cv_build_partition="$enableval" +case "$enableval" in + no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; };; +yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; };; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-compression option specified" >&5 +$as_echo_n "checking if --disable-compression option specified... " >&6; } +# Check whether --enable-compression was given. +if test "${enable_compression+set}" = set; then : + enableval=$enable_compression; +else + enableval="yes" +fi + +db_cv_build_compression="$enableval" +case "$enableval" in + no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; };; +yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; };; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-mutexsupport option specified" >&5 +$as_echo_n "checking if --disable-mutexsupport option specified... " >&6; } +# Check whether --enable-mutexsupport was given. +if test "${enable_mutexsupport+set}" = set; then : + enableval=$enable_mutexsupport; +else + enableval="yes" +fi + +db_cv_build_mutexsupport="$enableval" +case "$enableval" in + no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; };; +yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; };; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-atomicsupport option specified" >&5 +$as_echo_n "checking if --disable-atomicsupport option specified... " >&6; } +# Check whether --enable-atomicsupport was given. +if test "${enable_atomicsupport+set}" = set; then : + enableval=$enable_atomicsupport; +else + enableval="yes" +fi + +db_cv_build_atomicsupport="$enableval" +case "$enableval" in + no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; };; +yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; };; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-queue option specified" >&5 +$as_echo_n "checking if --disable-queue option specified... " >&6; } +# Check whether --enable-queue was given. +if test "${enable_queue+set}" = set; then : + enableval=$enable_queue; +else + enableval="yes" +fi + +db_cv_build_queue="$enableval" +case "$enableval" in + no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; };; +yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; };; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-replication option specified" >&5 +$as_echo_n "checking if --disable-replication option specified... " >&6; } +# Check whether --enable-replication was given. +if test "${enable_replication+set}" = set; then : + enableval=$enable_replication; +else + enableval="yes" +fi + +db_cv_build_replication="$enableval" +case "$enableval" in + no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; };; +yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; };; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-statistics option specified" >&5 +$as_echo_n "checking if --disable-statistics option specified... " >&6; } +# Check whether --enable-statistics was given. +if test "${enable_statistics+set}" = set; then : + enableval=$enable_statistics; +else + enableval="yes" +fi + +db_cv_build_statistics="$enableval" +case "$enableval" in + no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; };; +yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; };; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-verify option specified" >&5 +$as_echo_n "checking if --disable-verify option specified... " >&6; } +# Check whether --enable-verify was given. +if test "${enable_verify+set}" = set; then : + enableval=$enable_verify; +else + enableval="yes" +fi + +db_cv_build_verify="$enableval" +case "$enableval" in + no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; };; +yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; };; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-compat185 option specified" >&5 +$as_echo_n "checking if --enable-compat185 option specified... " >&6; } +# Check whether --enable-compat185 was given. +if test "${enable_compat185+set}" = set; then : + enableval=$enable_compat185; db_cv_compat185="$enable_compat185" +else + db_cv_compat185="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_compat185" >&5 +$as_echo "$db_cv_compat185" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-cxx option specified" >&5 +$as_echo_n "checking if --enable-cxx option specified... " >&6; } +# Check whether --enable-cxx was given. +if test "${enable_cxx+set}" = set; then : + enableval=$enable_cxx; db_cv_cxx="$enable_cxx" +else + db_cv_cxx="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_cxx" >&5 +$as_echo "$db_cv_cxx" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-debug option specified" >&5 +$as_echo_n "checking if --enable-debug option specified... " >&6; } +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; db_cv_debug="$enable_debug" +else + db_cv_debug="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_debug" >&5 +$as_echo "$db_cv_debug" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-debug_rop option specified" >&5 +$as_echo_n "checking if --enable-debug_rop option specified... " >&6; } +# Check whether --enable-debug_rop was given. +if test "${enable_debug_rop+set}" = set; then : + enableval=$enable_debug_rop; db_cv_debug_rop="$enable_debug_rop" +else + db_cv_debug_rop="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_debug_rop" >&5 +$as_echo "$db_cv_debug_rop" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-debug_wop option specified" >&5 +$as_echo_n "checking if --enable-debug_wop option specified... " >&6; } +# Check whether --enable-debug_wop was given. +if test "${enable_debug_wop+set}" = set; then : + enableval=$enable_debug_wop; db_cv_debug_wop="$enable_debug_wop" +else + db_cv_debug_wop="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_debug_wop" >&5 +$as_echo "$db_cv_debug_wop" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-diagnostic option specified" >&5 +$as_echo_n "checking if --enable-diagnostic option specified... " >&6; } +# Check whether --enable-diagnostic was given. +if test "${enable_diagnostic+set}" = set; then : + enableval=$enable_diagnostic; db_cv_diagnostic="$enable_diagnostic" +else + db_cv_diagnostic="no" +fi + +if test "$db_cv_diagnostic" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_diagnostic" >&5 +$as_echo "$db_cv_diagnostic" >&6; } +fi +if test "$db_cv_diagnostic" = "no" -a "$db_cv_debug_rop" = "yes"; then + db_cv_diagnostic="yes" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: by --enable-debug_rop" >&5 +$as_echo "by --enable-debug_rop" >&6; } +fi +if test "$db_cv_diagnostic" = "no" -a "$db_cv_debug_wop" = "yes"; then + db_cv_diagnostic="yes" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: by --enable-debug_wop" >&5 +$as_echo "by --enable-debug_wop" >&6; } +fi +if test "$db_cv_diagnostic" = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_diagnostic" >&5 +$as_echo "$db_cv_diagnostic" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-dump185 option specified" >&5 +$as_echo_n "checking if --enable-dump185 option specified... " >&6; } +# Check whether --enable-dump185 was given. +if test "${enable_dump185+set}" = set; then : + enableval=$enable_dump185; db_cv_dump185="$enable_dump185" +else + db_cv_dump185="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_dump185" >&5 +$as_echo "$db_cv_dump185" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-java option specified" >&5 +$as_echo_n "checking if --enable-java option specified... " >&6; } +# Check whether --enable-java was given. +if test "${enable_java+set}" = set; then : + enableval=$enable_java; db_cv_java="$enable_java" +else + db_cv_java="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_java" >&5 +$as_echo "$db_cv_java" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-mingw option specified" >&5 +$as_echo_n "checking if --enable-mingw option specified... " >&6; } +# Check whether --enable-mingw was given. +if test "${enable_mingw+set}" = set; then : + enableval=$enable_mingw; db_cv_mingw="$enable_mingw" +else + db_cv_mingw="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_mingw" >&5 +$as_echo "$db_cv_mingw" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-o_direct option specified" >&5 +$as_echo_n "checking if --enable-o_direct option specified... " >&6; } +# Check whether --enable-o_direct was given. +if test "${enable_o_direct+set}" = set; then : + enableval=$enable_o_direct; db_cv_o_direct="$enable_o_direct" +else + db_cv_o_direct="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_o_direct" >&5 +$as_echo "$db_cv_o_direct" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-posixmutexes option specified" >&5 +$as_echo_n "checking if --enable-posixmutexes option specified... " >&6; } +# Check whether --enable-posixmutexes was given. +if test "${enable_posixmutexes+set}" = set; then : + enableval=$enable_posixmutexes; db_cv_posixmutexes="$enable_posixmutexes" +else + db_cv_posixmutexes="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_posixmutexes" >&5 +$as_echo "$db_cv_posixmutexes" >&6; } + +# Check whether --enable-pthread_self was given. +if test "${enable_pthread_self+set}" = set; then : + enableval=$enable_pthread_self; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-pthread_self is now always enabled" >&5 +$as_echo "$as_me: WARNING: --enable-pthread_self is now always enabled" >&2;} +fi + + +# Check whether --enable-pthread_api was given. +if test "${enable_pthread_api+set}" = set; then : + enableval=$enable_pthread_api; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-pthread_api is now always enabled" >&5 +$as_echo "$as_me: WARNING: --enable-pthread_api is now always enabled" >&2;} +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-rpc option specified" >&5 +$as_echo_n "checking if --enable-rpc option specified... " >&6; } +# Check whether --enable-rpc was given. +if test "${enable_rpc+set}" = set; then : + enableval=$enable_rpc; if test "x$DB_FORCE_RPC" = x ; then + as_fn_error "RPC support has been removed from Berkeley DB. Please check the release notes" "$LINENO" 5; + else + db_cv_rpc="$enable_rpc"; + fi +else + db_cv_rpc="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_rpc" >&5 +$as_echo "$db_cv_rpc" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-smallbuild option specified" >&5 +$as_echo_n "checking if --enable-smallbuild option specified... " >&6; } +# Check whether --enable-smallbuild was given. +if test "${enable_smallbuild+set}" = set; then : + enableval=$enable_smallbuild; db_cv_smallbuild="$enable_smallbuild" +else + db_cv_smallbuild="no" +fi + +if test "$db_cv_smallbuild" = "yes"; then + db_cv_build_cryptography="no" + db_cv_build_hash="no" + db_cv_build_queue="no" + db_cv_build_replication="no" + db_cv_build_statistics="no" + db_cv_build_verify="no" + db_cv_build_partition="no" + db_cv_build_compression="no" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_smallbuild" >&5 +$as_echo "$db_cv_smallbuild" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-stl option specified" >&5 +$as_echo_n "checking if --enable-stl option specified... " >&6; } +# Check whether --enable-stl was given. +if test "${enable_stl+set}" = set; then : + enableval=$enable_stl; db_cv_stl="$enable_stl" +else + db_cv_stl="no" +fi + +if test "$db_cv_stl" = "yes" -a "$db_cv_cxx" = "no"; then + db_cv_cxx="yes" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_stl" >&5 +$as_echo "$db_cv_stl" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-tcl option specified" >&5 +$as_echo_n "checking if --enable-tcl option specified... " >&6; } +# Check whether --enable-tcl was given. +if test "${enable_tcl+set}" = set; then : + enableval=$enable_tcl; db_cv_tcl="$enable_tcl" +else + db_cv_tcl="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_tcl" >&5 +$as_echo "$db_cv_tcl" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-test option specified" >&5 +$as_echo_n "checking if --enable-test option specified... " >&6; } +# Check whether --enable-test was given. +if test "${enable_test+set}" = set; then : + enableval=$enable_test; db_cv_test="$enable_test" +else + db_cv_test="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_test" >&5 +$as_echo "$db_cv_test" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-uimutexes option specified" >&5 +$as_echo_n "checking if --enable-uimutexes option specified... " >&6; } +# Check whether --enable-uimutexes was given. +if test "${enable_uimutexes+set}" = set; then : + enableval=$enable_uimutexes; db_cv_uimutexes="$enable_uimutexes" +else + db_cv_uimutexes="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_uimutexes" >&5 +$as_echo "$db_cv_uimutexes" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-umrw option specified" >&5 +$as_echo_n "checking if --enable-umrw option specified... " >&6; } +# Check whether --enable-umrw was given. +if test "${enable_umrw+set}" = set; then : + enableval=$enable_umrw; db_cv_umrw="$enable_umrw" +else + db_cv_umrw="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_umrw" >&5 +$as_echo "$db_cv_umrw" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-mutex=MUTEX option specified" >&5 +$as_echo_n "checking if --with-mutex=MUTEX option specified... " >&6; } + +# Check whether --with-mutex was given. +if test "${with_mutex+set}" = set; then : + withval=$with_mutex; with_mutex="$withval" +else + with_mutex="no" +fi + +if test "$with_mutex" = "yes"; then + as_fn_error "--with-mutex requires a mutex name argument" "$LINENO" 5 +fi +if test "$with_mutex" != "no"; then + db_cv_mutex="$with_mutex" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_mutex" >&5 +$as_echo "$with_mutex" >&6; } + +# --with-mutexalign=ALIGNMENT was the configuration option that Berkeley DB +# used before the DbEnv::mutex_set_align method was added. + +# Check whether --with-mutexalign was given. +if test "${with_mutexalign+set}" = set; then : + withval=$with_mutexalign; as_fn_error "--with-mutexalign no longer supported, use DbEnv::mutex_set_align" "$LINENO" 5 +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-tcl=DIR option specified" >&5 +$as_echo_n "checking if --with-tcl=DIR option specified... " >&6; } + +# Check whether --with-tcl was given. +if test "${with_tcl+set}" = set; then : + withval=$with_tcl; with_tclconfig="$withval" +else + with_tclconfig="no" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_tclconfig" >&5 +$as_echo "$with_tclconfig" >&6; } +if test "$with_tclconfig" != "no"; then + db_cv_tcl="yes" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-uniquename=NAME option specified" >&5 +$as_echo_n "checking if --with-uniquename=NAME option specified... " >&6; } + +# Check whether --with-uniquename was given. +if test "${with_uniquename+set}" = set; then : + withval=$with_uniquename; with_uniquename="$withval" +else + with_uniquename="no" +fi + +if test "$with_uniquename" = "no"; then + db_cv_uniquename="no" + DB_VERSION_UNIQUE_NAME="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_uniquename" >&5 +$as_echo "$with_uniquename" >&6; } +else + db_cv_uniquename="yes" + if test "$with_uniquename" = "yes"; then + DB_VERSION_UNIQUE_NAME="_4008" + else + DB_VERSION_UNIQUE_NAME="$with_uniquename" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DB_VERSION_UNIQUE_NAME" >&5 +$as_echo "$DB_VERSION_UNIQUE_NAME" >&6; } +fi + +# Test requires Tcl +if test "$db_cv_test" = "yes"; then + if test "$db_cv_tcl" = "no"; then + as_fn_error "--enable-test requires --enable-tcl" "$LINENO" 5 + fi +fi + +# Set some #defines based on configuration options. +if test "$db_cv_diagnostic" = "yes"; then + $as_echo "#define DIAGNOSTIC 1" >>confdefs.h + + +fi +if test "$db_cv_debug_rop" = "yes"; then + $as_echo "#define DEBUG_ROP 1" >>confdefs.h + + +fi +if test "$db_cv_debug_wop" = "yes"; then + $as_echo "#define DEBUG_WOP 1" >>confdefs.h + + +fi +if test "$db_cv_umrw" = "yes"; then + $as_echo "#define UMRW 1" >>confdefs.h + + + +fi +if test "$db_cv_test" = "yes"; then + $as_echo "#define CONFIG_TEST 1" >>confdefs.h + + +fi + + +$as_echo "#define HAVE_UPGRADE_SUPPORT 1" >>confdefs.h + + +# Check for programs used in building and installation. + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}chmod", so it can be a program name with args. +set dummy ${ac_tool_prefix}chmod; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CHMOD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CHMOD"; then + ac_cv_prog_CHMOD="$CHMOD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CHMOD="${ac_tool_prefix}chmod" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CHMOD=$ac_cv_prog_CHMOD +if test -n "$CHMOD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CHMOD" >&5 +$as_echo "$CHMOD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CHMOD"; then + ac_ct_CHMOD=$CHMOD + # Extract the first word of "chmod", so it can be a program name with args. +set dummy chmod; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CHMOD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CHMOD"; then + ac_cv_prog_ac_ct_CHMOD="$ac_ct_CHMOD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CHMOD="chmod" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CHMOD=$ac_cv_prog_ac_ct_CHMOD +if test -n "$ac_ct_CHMOD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CHMOD" >&5 +$as_echo "$ac_ct_CHMOD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CHMOD" = x; then + CHMOD="none" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CHMOD=$ac_ct_CHMOD + fi +else + CHMOD="$ac_cv_prog_CHMOD" +fi + +test "$CHMOD" = "none" && as_fn_error "No chmod utility found." "$LINENO" 5 + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cp", so it can be a program name with args. +set dummy ${ac_tool_prefix}cp; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CP"; then + ac_cv_prog_CP="$CP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CP="${ac_tool_prefix}cp" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CP=$ac_cv_prog_CP +if test -n "$CP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CP" >&5 +$as_echo "$CP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CP"; then + ac_ct_CP=$CP + # Extract the first word of "cp", so it can be a program name with args. +set dummy cp; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CP"; then + ac_cv_prog_ac_ct_CP="$ac_ct_CP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CP="cp" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CP=$ac_cv_prog_ac_ct_CP +if test -n "$ac_ct_CP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CP" >&5 +$as_echo "$ac_ct_CP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CP" = x; then + CP="none" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CP=$ac_ct_CP + fi +else + CP="$ac_cv_prog_CP" +fi + +test "$CP" = "none" && as_fn_error "No cp utility found." "$LINENO" 5 + +# The Tcl test suite requires a kill utility. +if test "$db_cv_test" = "yes"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}kill", so it can be a program name with args. +set dummy ${ac_tool_prefix}kill; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_KILL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$KILL"; then + ac_cv_prog_KILL="$KILL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_KILL="${ac_tool_prefix}kill" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +KILL=$ac_cv_prog_KILL +if test -n "$KILL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KILL" >&5 +$as_echo "$KILL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_KILL"; then + ac_ct_KILL=$KILL + # Extract the first word of "kill", so it can be a program name with args. +set dummy kill; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_KILL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_KILL"; then + ac_cv_prog_ac_ct_KILL="$ac_ct_KILL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_KILL="kill" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_KILL=$ac_cv_prog_ac_ct_KILL +if test -n "$ac_ct_KILL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_KILL" >&5 +$as_echo "$ac_ct_KILL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_KILL" = x; then + KILL="none" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + KILL=$ac_ct_KILL + fi +else + KILL="$ac_cv_prog_KILL" +fi + + test "$KILL" = "none" && as_fn_error "No kill utility found." "$LINENO" 5 +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ln", so it can be a program name with args. +set dummy ${ac_tool_prefix}ln; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_LN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LN"; then + ac_cv_prog_LN="$LN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LN="${ac_tool_prefix}ln" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LN=$ac_cv_prog_LN +if test -n "$LN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LN" >&5 +$as_echo "$LN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LN"; then + ac_ct_LN=$LN + # Extract the first word of "ln", so it can be a program name with args. +set dummy ln; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_LN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LN"; then + ac_cv_prog_ac_ct_LN="$ac_ct_LN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LN="ln" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LN=$ac_cv_prog_ac_ct_LN +if test -n "$ac_ct_LN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LN" >&5 +$as_echo "$ac_ct_LN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LN" = x; then + LN="none" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LN=$ac_ct_LN + fi +else + LN="$ac_cv_prog_LN" +fi + +test "$LN" = "none" && as_fn_error "No ln utility found." "$LINENO" 5 + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mkdir", so it can be a program name with args. +set dummy ${ac_tool_prefix}mkdir; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_MKDIR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MKDIR"; then + ac_cv_prog_MKDIR="$MKDIR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MKDIR="${ac_tool_prefix}mkdir" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MKDIR=$ac_cv_prog_MKDIR +if test -n "$MKDIR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR" >&5 +$as_echo "$MKDIR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MKDIR"; then + ac_ct_MKDIR=$MKDIR + # Extract the first word of "mkdir", so it can be a program name with args. +set dummy mkdir; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_MKDIR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MKDIR"; then + ac_cv_prog_ac_ct_MKDIR="$ac_ct_MKDIR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_MKDIR="mkdir" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MKDIR=$ac_cv_prog_ac_ct_MKDIR +if test -n "$ac_ct_MKDIR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MKDIR" >&5 +$as_echo "$ac_ct_MKDIR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MKDIR" = x; then + MKDIR="none" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MKDIR=$ac_ct_MKDIR + fi +else + MKDIR="$ac_cv_prog_MKDIR" +fi + +test "$MKDIR" = "none" && as_fn_error "No mkdir utility found." "$LINENO" 5 + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}rm", so it can be a program name with args. +set dummy ${ac_tool_prefix}rm; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RM+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RM"; then + ac_cv_prog_RM="$RM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RM="${ac_tool_prefix}rm" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RM=$ac_cv_prog_RM +if test -n "$RM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RM" >&5 +$as_echo "$RM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RM"; then + ac_ct_RM=$RM + # Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RM+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RM"; then + ac_cv_prog_ac_ct_RM="$ac_ct_RM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RM="rm" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RM=$ac_cv_prog_ac_ct_RM +if test -n "$ac_ct_RM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RM" >&5 +$as_echo "$ac_ct_RM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RM" = x; then + RM="none" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RM=$ac_ct_RM + fi +else + RM="$ac_cv_prog_RM" +fi + +test "$RM" = "none" && as_fn_error "No rm utility found." "$LINENO" 5 + +# We always want to force removes, and libtool assumes the same. +RM="$RM -f" + +if test "$db_cv_rpc" = "yes"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}rpcgen", so it can be a program name with args. +set dummy ${ac_tool_prefix}rpcgen; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RPCGEN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RPCGEN"; then + ac_cv_prog_RPCGEN="$RPCGEN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RPCGEN="${ac_tool_prefix}rpcgen" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RPCGEN=$ac_cv_prog_RPCGEN +if test -n "$RPCGEN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RPCGEN" >&5 +$as_echo "$RPCGEN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RPCGEN"; then + ac_ct_RPCGEN=$RPCGEN + # Extract the first word of "rpcgen", so it can be a program name with args. +set dummy rpcgen; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RPCGEN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RPCGEN"; then + ac_cv_prog_ac_ct_RPCGEN="$ac_ct_RPCGEN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RPCGEN="rpcgen" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RPCGEN=$ac_cv_prog_ac_ct_RPCGEN +if test -n "$ac_ct_RPCGEN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RPCGEN" >&5 +$as_echo "$ac_ct_RPCGEN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RPCGEN" = x; then + RPCGEN="none" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RPCGEN=$ac_ct_RPCGEN + fi +else + RPCGEN="$ac_cv_prog_RPCGEN" +fi + + test "$RPCGEN" = "none" && as_fn_error "No rpcgen utility found." "$LINENO" 5 +fi + +# We need a complete path for sh, because some make utility implementations get +# upset if SHELL is set to just the command name. Don't use the SHELL variable +# here because the user likely has the SHELL variable set to something other +# than the Bourne shell, which is what Make wants. +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}sh", so it can be a program name with args. +set dummy ${ac_tool_prefix}sh; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_db_cv_path_sh+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $db_cv_path_sh in + [\\/]* | ?:[\\/]*) + ac_cv_path_db_cv_path_sh="$db_cv_path_sh" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_db_cv_path_sh="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +db_cv_path_sh=$ac_cv_path_db_cv_path_sh +if test -n "$db_cv_path_sh"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_path_sh" >&5 +$as_echo "$db_cv_path_sh" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_db_cv_path_sh"; then + ac_pt_db_cv_path_sh=$db_cv_path_sh + # Extract the first word of "sh", so it can be a program name with args. +set dummy sh; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_ac_pt_db_cv_path_sh+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_db_cv_path_sh in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_db_cv_path_sh="$ac_pt_db_cv_path_sh" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_db_cv_path_sh="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_db_cv_path_sh=$ac_cv_path_ac_pt_db_cv_path_sh +if test -n "$ac_pt_db_cv_path_sh"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_db_cv_path_sh" >&5 +$as_echo "$ac_pt_db_cv_path_sh" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_db_cv_path_sh" = x; then + db_cv_path_sh="none" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + db_cv_path_sh=$ac_pt_db_cv_path_sh + fi +else + db_cv_path_sh="$ac_cv_path_db_cv_path_sh" +fi + +test "$db_cv_path_sh" = "none" && as_fn_error "No sh utility found." "$LINENO" 5 + +# Don't strip the binaries if --enable-debug was specified. +if test "$db_cv_debug" = yes; then + STRIP=":" +fi +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +BUILD_TARGET="library_build" +INSTALL_TARGET="library_install" + +# Respect the environment LIBS settings +LIBSO_LIBS="$LIBS" + +# This is where we handle stuff that autoconf can't handle: compiler, +# preprocessor and load flags, libraries that the standard tests don't +# look for. +# +# There are additional libraries we need for some compiler/architecture +# combinations. +# +# Some architectures require DB to be compiled with special flags and/or +# libraries for threaded applications +# +# The makefile CC may be different than the CC used in config testing, +# because the makefile CC may be set to use $(LIBTOOL). +# +# Don't override anything if it's already set from the environment. +optimize_debug="-O" +case "$host_os" in +aix4.3.*|aix[56]*) + case "$host_os" in + aix4.3.*) + CPPFLAGS="$CPPFLAGS -D_LINUX_SOURCE_COMPAT";; + esac + # IBM's XLC compilers (at least versions 7/8/9) generate incorrect code + # when ordinary optimization is enabled because they make strong + # assumptions about the types held at each memory location, and some + # Berkeley DB code violates those assumptions. [#16141] + optimize_debug="-O2 -qalias=noansi" + CC=${CC-"xlc_r"} + CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" + LDFLAGS="$LDFLAGS -Wl,-brtl";; +bsdi3*) CC=${CC-"shlicc2"} + LIBSO_LIBS="$LIBSO_LIBS -lipc";; +cygwin*) + CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";; +freebsd*) + CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" + LDFLAGS="$LDFLAGS -pthread";; +gnu*|k*bsd*-gnu|linux*) + CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";; +hpux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT";; +irix*) optimize_debug="-O2" + CPPFLAGS="$CPPFLAGS -D_SGI_MP_SOURCE";; +mpeix*) CPPFLAGS="$CPPFLAGS -D_POSIX_SOURCE -D_SOCKET_SOURCE" + LIBSO_LIBS="$LIBSO_LIBS -lsocket -lsvipc";; +osf*) CPPFLAGS="$CPPFLAGS -pthread";; +*qnx*) qnx_build="yes" + $as_echo "#define HAVE_QNX 1" >>confdefs.h + + ;; +solaris*) + CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS ";; +esac + +# If the user wants a debugging environment, change any compiler optimization +# flags to -g. We used to add -g to the -O compiler flags, but compilers are +# good enough at code re-organization that debugging with -O no longer works. +# If you want to compile with a different set of flags, specify CFLAGS in the +# environment before configuring. +if test "$db_cv_debug" = "yes"; then + $as_echo "#define DEBUG 1" >>confdefs.h + + + + optimize_debug="-g" +fi + +# Set CFLAGS/CXXFLAGS. We MUST set the flags before we call autoconf +# compiler configuration macros, because if we don't, they set CFLAGS +# to no optimization and -g, which isn't what we want. +CFLAGS=${CFLAGS-$optimize_debug} +CXXFLAGS=${CXXFLAGS-"$CFLAGS"} + +# The default compiler is cc (NOT gcc), the default CFLAGS is as specified +# above, NOT what is set by AC_PROG_CC, as it won't set optimization flags +# for any compiler other than gcc. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in cc gcc + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cc gcc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "no acceptable C compiler found in \$PATH +See \`config.log' for more details." "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "C compiler cannot create executables +See \`config.log' for more details." "$LINENO" 5; }; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot compute suffix of object files: cannot compile +See \`config.log' for more details." "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# We know what compiler we're going to use, now. Set per-compiler flags. +if test "$GCC" = "yes"; then + # Use -O3 if we're using gcc, unless we're doing a small build, in + # which case we use -Os alone. The code size for -O3 is quite a + # bit larger than -O2: a compromise is "-Os -finline-functions", + # it's smaller and explicitly inlining the functions helps Berkeley + # DB. + CFLAGS="$CFLAGS " + if test "$db_cv_smallbuild" = "yes"; then + CFLAGS=`echo "$CFLAGS" | sed 's/-O /-Os /g'` + else + CFLAGS=`echo "$CFLAGS" | sed 's/-O /-O3 /g'` + fi +else + case "$host_os" in + hpux11.0*) ;; + hpux11*) CPPFLAGS="$CPPFLAGS -mt";; + esac +fi + +# Check for "const" and "inline" keywords. + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if test "${ac_cv_c_const+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if test "${ac_cv_c_inline+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + + +# We use prototypes and the keyword "const" in db.h which doesn't include +# db_config.h, so we have to figure out what to do there. +# +# There is an autoconf AC_C_PROTOTYPES macro, but as all it does is define +# db_config.h variables, it doesn't help us. +# +# We don't have much choice, we look at internal autoconf variables. +if test "$ac_cv_c_const" != "yes"; then + DB_CONST="#define const" +fi + +# Clear __P, some other systems use it too. +DB_PROTO1="#undef __P" +if test "$ac_cv_prog_cc_c89" = "no"; then + DB_PROTO2="#define __P(protos) ()" +else + DB_PROTO2="#define __P(protos) protos" +fi + +# Because of shared library building, the ${CC} used for config tests +# may be different than the ${CC} we want to put in the Makefile. +# The latter is known as ${MAKEFILE_CC} in this script. +MAKEFILE_CC="${CC}" +MAKEFILE_CCLINK="${CC}" +MAKEFILE_CXX="nocxx" +MAKEFILE_CXXLINK="nocxx" + +# See if we need the C++ compiler at all. If so, we'd like to find one that +# interoperates with the C compiler we chose. Since we prefered cc over gcc, +# we'll also prefer the vendor's compiler over g++/gcc. If we're wrong, the +# user can set CC and CXX in their environment before running configure. +# +# AC_PROG_CXX sets CXX, but it uses $CXX and $CCC (in that order) as its +# first choices. +if test "$db_cv_cxx" = "yes"; then + if test "$GCC" != "yes"; then + case "$host_os" in + aix*) if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}xlC_r", so it can be a program name with args. +set dummy ${ac_tool_prefix}xlC_r; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CCC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CCC"; then + ac_cv_prog_CCC="$CCC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CCC="${ac_tool_prefix}xlC_r" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CCC=$ac_cv_prog_CCC +if test -n "$CCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCC" >&5 +$as_echo "$CCC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CCC"; then + ac_ct_CCC=$CCC + # Extract the first word of "xlC_r", so it can be a program name with args. +set dummy xlC_r; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CCC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CCC"; then + ac_cv_prog_ac_ct_CCC="$ac_ct_CCC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CCC="xlC_r" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CCC=$ac_cv_prog_ac_ct_CCC +if test -n "$ac_ct_CCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CCC" >&5 +$as_echo "$ac_ct_CCC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CCC" = x; then + CCC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CCC=$ac_ct_CCC + fi +else + CCC="$ac_cv_prog_CCC" +fi + + LIBXSO_LIBS="-lC_r $LIBXSO_LIBS" + LIBSO_LIBS="-lC_r $LIBSO_LIBS";; + hpux*) if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}aCC", so it can be a program name with args. +set dummy ${ac_tool_prefix}aCC; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CCC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CCC"; then + ac_cv_prog_CCC="$CCC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CCC="${ac_tool_prefix}aCC" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CCC=$ac_cv_prog_CCC +if test -n "$CCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCC" >&5 +$as_echo "$CCC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CCC"; then + ac_ct_CCC=$CCC + # Extract the first word of "aCC", so it can be a program name with args. +set dummy aCC; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CCC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CCC"; then + ac_cv_prog_ac_ct_CCC="$ac_ct_CCC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CCC="aCC" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CCC=$ac_cv_prog_ac_ct_CCC +if test -n "$ac_ct_CCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CCC" >&5 +$as_echo "$ac_ct_CCC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CCC" = x; then + CCC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CCC=$ac_ct_CCC + fi +else + CCC="$ac_cv_prog_CCC" +fi +;; + irix*) if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}CC", so it can be a program name with args. +set dummy ${ac_tool_prefix}CC; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CCC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CCC"; then + ac_cv_prog_CCC="$CCC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CCC="${ac_tool_prefix}CC" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CCC=$ac_cv_prog_CCC +if test -n "$CCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCC" >&5 +$as_echo "$CCC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CCC"; then + ac_ct_CCC=$CCC + # Extract the first word of "CC", so it can be a program name with args. +set dummy CC; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CCC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CCC"; then + ac_cv_prog_ac_ct_CCC="$ac_ct_CCC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CCC="CC" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CCC=$ac_cv_prog_ac_ct_CCC +if test -n "$ac_ct_CCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CCC" >&5 +$as_echo "$ac_ct_CCC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CCC" = x; then + CCC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CCC=$ac_ct_CCC + fi +else + CCC="$ac_cv_prog_CCC" +fi +;; + osf*) if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cxx", so it can be a program name with args. +set dummy ${ac_tool_prefix}cxx; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CCC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CCC"; then + ac_cv_prog_CCC="$CCC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CCC="${ac_tool_prefix}cxx" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CCC=$ac_cv_prog_CCC +if test -n "$CCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCC" >&5 +$as_echo "$CCC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CCC"; then + ac_ct_CCC=$CCC + # Extract the first word of "cxx", so it can be a program name with args. +set dummy cxx; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CCC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CCC"; then + ac_cv_prog_ac_ct_CCC="$ac_ct_CCC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CCC="cxx" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CCC=$ac_cv_prog_ac_ct_CCC +if test -n "$ac_ct_CCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CCC" >&5 +$as_echo "$ac_ct_CCC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CCC" = x; then + CCC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CCC=$ac_ct_CCC + fi +else + CCC="$ac_cv_prog_CCC" +fi + + CXXFLAGS="$CXXFLAGS -D__USE_STD_IOSTREAM" + test -d /usr/include.dtk && + CXXFLAGS="$CXXFLAGS -I/usr/include.dtk";; + solaris*) if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}CC", so it can be a program name with args. +set dummy ${ac_tool_prefix}CC; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CCC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CCC"; then + ac_cv_prog_CCC="$CCC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CCC="${ac_tool_prefix}CC" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CCC=$ac_cv_prog_CCC +if test -n "$CCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCC" >&5 +$as_echo "$CCC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CCC"; then + ac_ct_CCC=$CCC + # Extract the first word of "CC", so it can be a program name with args. +set dummy CC; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CCC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CCC"; then + ac_cv_prog_ac_ct_CCC="$ac_ct_CCC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CCC="CC" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CCC=$ac_cv_prog_ac_ct_CCC +if test -n "$ac_ct_CCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CCC" >&5 +$as_echo "$ac_ct_CCC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CCC" = x; then + CCC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CCC=$ac_ct_CCC + fi +else + CCC="$ac_cv_prog_CCC" +fi +;; + esac + fi + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ###### WORKAROUND: SEE SR #7938 + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if test "${ac_cv_prog_CXXCPP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ############################### + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ supports the ISO C++ standard includes" >&5 +$as_echo_n "checking whether C++ supports the ISO C++ standard includes... " >&6; } + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +std::ostream *o; return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + db_cv_cxx_have_stdheaders=yes +else + db_cv_cxx_have_stdheaders=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_cxx_have_stdheaders" >&5 +$as_echo "$db_cv_cxx_have_stdheaders" >&6; } +if test "$db_cv_cxx_have_stdheaders" = yes; then + cxx_have_stdheaders="#define HAVE_CXX_STDHEADERS 1" +fi + MAKEFILE_CXX="${CXX}" + MAKEFILE_CXXLINK="${CXX}" +fi + +# Do some gcc specific configuration. + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using gcc version 2.96" >&5 +$as_echo_n "checking whether we are using gcc version 2.96... " >&6; } +if test "${db_cv_gcc_2_96+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +db_cv_gcc_2_96=no +if test "$GCC" = "yes"; then + GCC_VERSION=`${MAKEFILE_CC} --version` + case ${GCC_VERSION} in + 2.96*) + db_cv_gcc_2_96=yes;; + esac +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_gcc_2_96" >&5 +$as_echo "$db_cv_gcc_2_96" >&6; } +if test "$db_cv_gcc_2_96" = "yes"; then + CFLAGS=`echo "$CFLAGS" | sed 's/-O2/-O/'` + CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-O2/-O/'` + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: INSTALLED GCC COMPILER HAS SERIOUS BUGS; PLEASE UPGRADE." >&5 +$as_echo "$as_me: WARNING: INSTALLED GCC COMPILER HAS SERIOUS BUGS; PLEASE UPGRADE." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GCC OPTIMIZATION LEVEL SET TO -O." >&5 +$as_echo "$as_me: WARNING: GCC OPTIMIZATION LEVEL SET TO -O." >&2;} +fi + +# We need the -Kthread/-pthread flag when compiling on SCO/Caldera's UnixWare +# and OpenUNIX releases. We can't make the test until we know which compiler +# we're using. +case "$host_os" in +sysv5UnixWare*|sysv5OpenUNIX8*) + if test "$GCC" == "yes"; then + CPPFLAGS="$CPPFLAGS -pthread" + LDFLAGS="$LDFLAGS -pthread" + else + CPPFLAGS="$CPPFLAGS -Kthread" + LDFLAGS="$LDFLAGS -Kthread" + fi;; +esac + +# Export our compiler preferences for the libtool configuration. +export CC CCC +CCC=CXX + +# Libtool configuration. +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.2.6' +macro_revision='1.3012' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if test "${ac_cv_path_SED+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if test "${ac_cv_path_GREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if test "${ac_cv_path_FGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if test "${lt_cv_path_NM+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$ac_tool_prefix"; then + for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_DUMPBIN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in "dumpbin -symbols" "link -dump -symbols" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if test "${lt_cv_nm_interface+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:6908: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:6911: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:6914: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if test "${lt_cv_sys_max_cmd_len+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ + = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if test "${lt_cv_ld_reload_flag+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OBJDUMP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if test "${lt_cv_deplibs_check_method+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + + + + + + + + + + + + + + + + + + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 8119 "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if test "${lt_cv_cc_needs_belf+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_DSYMUTIL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_NMEDIT+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_LIPO+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OTOOL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OTOOL64+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if test "${lt_cv_apple_cc_single_mod+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if test "${lt_cv_ld_exported_symbols_list+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if test "${ac_cv_prog_CXXCPP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +_lt_caught_CXX_error=yes; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if test "${lt_cv_objdir+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + + + + + + + + + + + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:10048: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:10052: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl*) + # IBM XL C 8.0/Fortran 10.1 on PPC + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 +$as_echo "$lt_prog_compiler_pic" >&6; } + + + + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test "${lt_cv_prog_compiler_pic_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:10387: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:10391: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test "${lt_cv_prog_compiler_static_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:10492: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:10496: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:10547: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:10551: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag= + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + whole_archive_flag_spec='' + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=echo + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo(void) {} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + archive_cmds_need_lc=no + else + archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 +$as_echo "$archive_cmds_need_lc" >&6; } + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = x""yes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if test "${ac_cv_lib_dld_shl_load+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = x""yes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if test "${ac_cv_lib_svld_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if test "${ac_cv_lib_dld_dld_link+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = x""yes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if test "${lt_cv_dlopen_self+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 12914 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if test "${lt_cv_dlopen_self_static+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 13010 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + whole_archive_flag_spec_CXX='' + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=echo + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5]* | *pgcpp\ [1-5]*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 will use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + xl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=echo + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC*) + # IBM XL 8.0 on PPC + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_prog_compiler_pic_CXX" >&6; } + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14966: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:14970: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:15065: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:15069: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:15117: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:15121: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + archive_cmds_need_lc_CXX=no + else + archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc_CXX" >&5 +$as_echo "$archive_cmds_need_lc_CXX" >&6; } + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +SOFLAGS="-rpath \$(libdir)" + +# Set SOSUFFIX and friends + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking SOSUFFIX from libtool" >&5 +$as_echo_n "checking SOSUFFIX from libtool... " >&6; } + module=no + + versuffix="" + release="" + libname=libfoo + eval _SOSUFFIX=\"$shrext_cmds\" + if test "$_SOSUFFIX" = "" ; then + _SOSUFFIX=".so" + if test "$enable_shared" != "yes"; then + if test "$_SOSUFFIX_MESSAGE" = ""; then + _SOSUFFIX_MESSAGE=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libtool may not know about this architecture." >&5 +$as_echo "$as_me: WARNING: libtool may not know about this architecture." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: assuming $_SOSUFFIX suffix for dynamic libraries." >&5 +$as_echo "$as_me: WARNING: assuming $_SOSUFFIX suffix for dynamic libraries." >&2;} + fi + fi + fi + + SOSUFFIX=$_SOSUFFIX + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SOSUFFIX" >&5 +$as_echo "$SOSUFFIX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking MODSUFFIX from libtool" >&5 +$as_echo_n "checking MODSUFFIX from libtool... " >&6; } + module=yes + + versuffix="" + release="" + libname=libfoo + eval _SOSUFFIX=\"$shrext_cmds\" + if test "$_SOSUFFIX" = "" ; then + _SOSUFFIX=".so" + if test "$enable_shared" != "yes"; then + if test "$_SOSUFFIX_MESSAGE" = ""; then + _SOSUFFIX_MESSAGE=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libtool may not know about this architecture." >&5 +$as_echo "$as_me: WARNING: libtool may not know about this architecture." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: assuming $_SOSUFFIX suffix for dynamic libraries." >&5 +$as_echo "$as_me: WARNING: assuming $_SOSUFFIX suffix for dynamic libraries." >&2;} + fi + fi + fi + + MODSUFFIX=$_SOSUFFIX + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MODSUFFIX" >&5 +$as_echo "$MODSUFFIX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking JMODSUFFIX from libtool" >&5 +$as_echo_n "checking JMODSUFFIX from libtool... " >&6; } + module=yes + + versuffix="" + release="" + libname=libfoo + eval _SOSUFFIX=\"$shrext_cmds\" + if test "$_SOSUFFIX" = "" ; then + _SOSUFFIX=".so" + if test "$enable_shared" != "yes"; then + if test "$_SOSUFFIX_MESSAGE" = ""; then + _SOSUFFIX_MESSAGE=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libtool may not know about this architecture." >&5 +$as_echo "$as_me: WARNING: libtool may not know about this architecture." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: assuming $_SOSUFFIX suffix for dynamic libraries." >&5 +$as_echo "$as_me: WARNING: assuming $_SOSUFFIX suffix for dynamic libraries." >&2;} + fi + fi + fi + + if test `uname` = "Darwin"; then + JMODSUFFIX=".jnilib" + else + JMODSUFFIX=$_SOSUFFIX + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JMODSUFFIX" >&5 +$as_echo "$JMODSUFFIX" >&6; } + + + +LIBTOOL="./libtool" + +INSTALLER="\$(LIBTOOL) --mode=install cp -p" + +MAKEFILE_CC="\$(LIBTOOL) --mode=compile ${MAKEFILE_CC}" +MAKEFILE_SOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK} -avoid-version" +MAKEFILE_CCLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK}" +MAKEFILE_CXX="\$(LIBTOOL) --mode=compile ${MAKEFILE_CXX}" +MAKEFILE_XSOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK} -avoid-version" +MAKEFILE_CXXLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK}" + + +case "$host_os" in +cygwin* | mingw*) + MAKEFILE_SOLINK="$MAKEFILE_SOLINK -no-undefined" + MAKEFILE_XSOLINK="$MAKEFILE_XSOLINK -no-undefined";; +esac + +case "$host_os" in + darwin*) + LIBTSO_MODULE="" + LIBTSO_MODSUFFIX=".dylib";; + *qnx*) + LIBTSO_MODULE="" + LIBTSO_MODSUFFIX=$MODSUFFIX;; + *) + LIBTSO_MODULE="-module" + LIBTSO_MODSUFFIX=$MODSUFFIX;; +esac + +# C API. +if test "$enable_shared" = "no"; then + DEFAULT_LIB="\$(libdb_version)" + POSTLINK=": " + o=".o" +else + DEFAULT_LIB="\$(libso_target)" + POSTLINK="\$(LIBTOOL) --mode=execute true" + o=".lo" +fi +INSTALL_LIBS="$DEFAULT_LIB" +if test "$enable_static" = "yes"; then + INSTALL_LIBS="$INSTALL_LIBS \$(libdb)" +fi + +# Optional C++ API. +if test "$db_cv_cxx" = "yes"; then + if test "$enable_shared" = "no"; then + DEFAULT_LIB_CXX="\$(libcxx_version)" + fi + if test "$enable_shared" = "yes"; then + DEFAULT_LIB_CXX="\$(libxso_target)" + fi + INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_CXX" + if test "$enable_static" = "yes"; then + INSTALL_LIBS="$INSTALL_LIBS \$(libcxx)" + fi +fi + +# Optional Java API. +if test "$db_cv_java" = "yes"; then + # Java requires shared libraries. + if test "$enable_shared" = "no"; then + as_fn_error "Java requires shared libraries" "$LINENO" 5 + fi + + # A classpath that includes . is needed to check for Java + # Since Cygwin uses Windows' javac, we need Windows path separators + case "$host_os" in + cygwin*) CLASSPATH=".;$CLASSPATH";; + *) CLASSPATH=".:$CLASSPATH";; + esac + export CLASSPATH + + +if test "x$JAVAPREFIX" = x; then + test "x$JAVAC" = x && for ac_prog in javac$EXEEXT "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_JAVAC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$JAVAC"; then + ac_cv_prog_JAVAC="$JAVAC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_JAVAC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +JAVAC=$ac_cv_prog_JAVAC +if test -n "$JAVAC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVAC" >&5 +$as_echo "$JAVAC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$JAVAC" && break +done + +else + test "x$JAVAC" = x && for ac_prog in javac$EXEEXT "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_JAVAC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$JAVAC"; then + ac_cv_prog_JAVAC="$JAVAC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_JAVAC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +JAVAC=$ac_cv_prog_JAVAC +if test -n "$JAVAC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVAC" >&5 +$as_echo "$JAVAC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$JAVAC" && break +done +test -n "$JAVAC" || JAVAC="$JAVAPREFIX" + +fi +test "x$JAVAC" = x && as_fn_error "no acceptable Java compiler found in \$PATH" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $JAVAC works" >&5 +$as_echo_n "checking if $JAVAC works... " >&6; } +if test "${ac_cv_prog_javac_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +JAVA_TEST=Test.java +CLASS_TEST=Test.class +cat << \EOF > $JAVA_TEST +/* #line 16333 "configure" */ +public class Test { +} +EOF +if { ac_try='$JAVAC $JAVACFLAGS $JAVA_TEST' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } >/dev/null 2>&1; then + ac_cv_prog_javac_works=yes +else + as_fn_error "The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)" "$LINENO" 5 + echo "configure: failed program was:" >&5 + cat $JAVA_TEST >&5 +fi +rm -f $JAVA_TEST $CLASS_TEST + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_javac_works" >&5 +$as_echo "$ac_cv_prog_javac_works" >&6; } + + + +if test "x$JAVAPREFIX" = x; then + test "x$JAR" = x && for ac_prog in jar$EXEEXT +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_JAR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$JAR"; then + ac_cv_prog_JAR="$JAR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_JAR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +JAR=$ac_cv_prog_JAR +if test -n "$JAR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAR" >&5 +$as_echo "$JAR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$JAR" && break +done + +else + test "x$JAR" = x && for ac_prog in jar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_JAR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$JAR"; then + ac_cv_prog_JAR="$JAR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_JAR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +JAR=$ac_cv_prog_JAR +if test -n "$JAR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAR" >&5 +$as_echo "$JAR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$JAR" && break +done +test -n "$JAR" || JAR="$JAVAPREFIX" + +fi +test "x$JAR" = x && as_fn_error "no acceptable jar program found in \$PATH" "$LINENO" 5 + + +if test x$JAVAPREFIX = x; then + test x$JAVA = x && for ac_prog in java$EXEEXT kaffe$EXEEXT +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_JAVA+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$JAVA"; then + ac_cv_prog_JAVA="$JAVA" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_JAVA="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +JAVA=$ac_cv_prog_JAVA +if test -n "$JAVA"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVA" >&5 +$as_echo "$JAVA" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$JAVA" && break +done + +else + test x$JAVA = x && for ac_prog in java$EXEEXT kaffe$EXEEXT +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_JAVA+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$JAVA"; then + ac_cv_prog_JAVA="$JAVA" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_JAVA="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +JAVA=$ac_cv_prog_JAVA +if test -n "$JAVA"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVA" >&5 +$as_echo "$JAVA" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$JAVA" && break +done +test -n "$JAVA" || JAVA="$JAVAPREFIX" + +fi +test x$JAVA = x && as_fn_error "no acceptable Java virtual machine found in \$PATH" "$LINENO" 5 + +# Extract the first word of "uudecode$EXEEXT", so it can be a program name with args. +set dummy uudecode$EXEEXT; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_uudecode+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$uudecode"; then + ac_cv_prog_uudecode="$uudecode" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_uudecode="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +uudecode=$ac_cv_prog_uudecode +if test -n "$uudecode"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $uudecode" >&5 +$as_echo "$uudecode" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test x$uudecode = xyes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if uudecode can decode base 64 file" >&5 +$as_echo_n "checking if uudecode can decode base 64 file... " >&6; } +if test "${ac_cv_prog_uudecode_base64+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +cat << \EOF > Test.uue +begin-base64 644 Test.class +yv66vgADAC0AFQcAAgEABFRlc3QHAAQBABBqYXZhL2xhbmcvT2JqZWN0AQAE +bWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARDb2RlAQAPTGluZU51 +bWJlclRhYmxlDAAKAAsBAARleGl0AQAEKEkpVgoADQAJBwAOAQAQamF2YS9s +YW5nL1N5c3RlbQEABjxpbml0PgEAAygpVgwADwAQCgADABEBAApTb3VyY2VG +aWxlAQAJVGVzdC5qYXZhACEAAQADAAAAAAACAAkABQAGAAEABwAAACEAAQAB +AAAABQO4AAyxAAAAAQAIAAAACgACAAAACgAEAAsAAQAPABAAAQAHAAAAIQAB +AAEAAAAFKrcAErEAAAABAAgAAAAKAAIAAAAEAAQABAABABMAAAACABQ= +==== +EOF +if uudecode$EXEEXT Test.uue; then + ac_cv_prog_uudecode_base64=yes +else + echo "configure: 16596: uudecode had trouble decoding base 64 file 'Test.uue'" >&5 + echo "configure: failed file was:" >&5 + cat Test.uue >&5 + ac_cv_prog_uudecode_base64=no +fi +rm -f Test.uue +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_uudecode_base64" >&5 +$as_echo "$ac_cv_prog_uudecode_base64" >&6; } +fi +if test x$ac_cv_prog_uudecode_base64 != xyes; then + rm -f Test.class + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: I have to compile Test.class from scratch" >&5 +$as_echo "$as_me: WARNING: I have to compile Test.class from scratch" >&2;} + if test x$ac_cv_prog_javac_works = xno; then + as_fn_error "Cannot compile java source. $JAVAC does not work properly" "$LINENO" 5 + fi + if test x$ac_cv_prog_javac_works = x; then + +if test "x$JAVAPREFIX" = x; then + test "x$JAVAC" = x && for ac_prog in javac$EXEEXT "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_JAVAC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$JAVAC"; then + ac_cv_prog_JAVAC="$JAVAC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_JAVAC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +JAVAC=$ac_cv_prog_JAVAC +if test -n "$JAVAC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVAC" >&5 +$as_echo "$JAVAC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$JAVAC" && break +done + +else + test "x$JAVAC" = x && for ac_prog in javac$EXEEXT "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_JAVAC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$JAVAC"; then + ac_cv_prog_JAVAC="$JAVAC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_JAVAC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +JAVAC=$ac_cv_prog_JAVAC +if test -n "$JAVAC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVAC" >&5 +$as_echo "$JAVAC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$JAVAC" && break +done +test -n "$JAVAC" || JAVAC="$JAVAPREFIX" + +fi +test "x$JAVAC" = x && as_fn_error "no acceptable Java compiler found in \$PATH" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $JAVAC works" >&5 +$as_echo_n "checking if $JAVAC works... " >&6; } +if test "${ac_cv_prog_javac_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +JAVA_TEST=Test.java +CLASS_TEST=Test.class +cat << \EOF > $JAVA_TEST +/* #line 16714 "configure" */ +public class Test { +} +EOF +if { ac_try='$JAVAC $JAVACFLAGS $JAVA_TEST' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } >/dev/null 2>&1; then + ac_cv_prog_javac_works=yes +else + as_fn_error "The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)" "$LINENO" 5 + echo "configure: failed program was:" >&5 + cat $JAVA_TEST >&5 +fi +rm -f $JAVA_TEST $CLASS_TEST + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_javac_works" >&5 +$as_echo "$ac_cv_prog_javac_works" >&6; } + + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $JAVA works" >&5 +$as_echo_n "checking if $JAVA works... " >&6; } +if test "${ac_cv_prog_java_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +JAVA_TEST=Test.java +CLASS_TEST=Test.class +TEST=Test +cat << \EOF > $JAVA_TEST +/* [#]line 16749 "configure" */ +public class Test { +public static void main (String args[]) { + System.exit (0); +} } +EOF +if test x$ac_cv_prog_uudecode_base64 != xyes; then + if { ac_try='$JAVAC $JAVACFLAGS $JAVA_TEST' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } && test -s $CLASS_TEST; then + : + else + echo "configure: failed program was:" >&5 + cat $JAVA_TEST >&5 + as_fn_error "The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)" "$LINENO" 5 + fi +fi +if { ac_try='$JAVA $JAVAFLAGS $TEST' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } >/dev/null 2>&1; then + ac_cv_prog_java_works=yes +else + echo "configure: failed program was:" >&5 + cat $JAVA_TEST >&5 + as_fn_error "The Java VM $JAVA failed (see config.log, check the CLASSPATH?)" "$LINENO" 5 +fi +rm -fr $JAVA_TEST $CLASS_TEST Test.uue + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_java_works" >&5 +$as_echo "$ac_cv_prog_java_works" >&6; } + + + + + +JNI_INCLUDE_DIRS="" + +test "x$JAVAC" = x && as_fn_error "'$JAVAC' undefined" "$LINENO" 5 +# Extract the first word of "$JAVAC", so it can be a program name with args. +set dummy $JAVAC; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path__ACJNI_JAVAC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $_ACJNI_JAVAC in + [\\/]* | ?:[\\/]*) + ac_cv_path__ACJNI_JAVAC="$_ACJNI_JAVAC" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path__ACJNI_JAVAC="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path__ACJNI_JAVAC" && ac_cv_path__ACJNI_JAVAC="$JAVAC" + ;; +esac +fi +_ACJNI_JAVAC=$ac_cv_path__ACJNI_JAVAC +if test -n "$_ACJNI_JAVAC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_ACJNI_JAVAC" >&5 +$as_echo "$_ACJNI_JAVAC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +test ! -x "$_ACJNI_JAVAC" && as_fn_error "$JAVAC could not be found in path" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute path of $JAVAC" >&5 +$as_echo_n "checking absolute path of $JAVAC... " >&6; } +case "$_ACJNI_JAVAC" in +/*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_ACJNI_JAVAC" >&5 +$as_echo "$_ACJNI_JAVAC" >&6; };; +*) as_fn_error "$_ACJNI_JAVAC is not an absolute path name" "$LINENO" 5;; +esac + + +# find the include directory relative to the javac executable +_cur=""$_ACJNI_JAVAC"" +while ls -ld "$_cur" 2>/dev/null | grep " -> " >/dev/null; do + { $as_echo "$as_me:${as_lineno-$LINENO}: checking symlink for $_cur" >&5 +$as_echo_n "checking symlink for $_cur... " >&6; } + _slink=`ls -ld "$_cur" | sed 's/.* -> //'` + case "$_slink" in + /*) _cur="$_slink";; + # 'X' avoids triggering unwanted echo options. + *) _cur=`echo "X$_cur" | sed -e 's/^X//' -e 's:[^/]*$::'`"$_slink";; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_cur" >&5 +$as_echo "$_cur" >&6; } +done +_ACJNI_FOLLOWED="$_cur" + +_JTOPDIR=`echo "$_ACJNI_FOLLOWED" | sed -e 's://*:/:g' -e 's:/[^/]*$::'` +case "$host_os" in + darwin*) _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[^/]*$::'` + _JINC="$_JTOPDIR/Headers";; + *) _JINC="$_JTOPDIR/include";; +esac + +# If we find jni.h in /usr/include, then it's not a java-only tree, so +# don't add /usr/include or subdirectories to the list of includes. +# An extra -I/usr/include can foul things up with newer gcc's. +# +# If we don't find jni.h, just keep going. Hopefully javac knows where +# to find its include files, even if we can't. +if test -r "$_JINC/jni.h"; then + if test "$_JINC" != "/usr/include"; then + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JINC" + fi +else + _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[^/]*$::'` + if test -r "$_JTOPDIR/include/jni.h"; then + if test "$_JTOPDIR" != "/usr"; then + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include" + fi + fi +fi + +# get the likely subdirectories for system specific java includes +if test "$_JTOPDIR" != "/usr"; then + case "$host_os" in + aix*) _JNI_INC_SUBDIRS="aix";; + bsdi*) _JNI_INC_SUBDIRS="bsdos";; + cygwin*) _JNI_INC_SUBDIRS="win32";; + freebsd*) _JNI_INC_SUBDIRS="freebsd";; + hp*) _JNI_INC_SUBDIRS="hp-ux";; + linux*) _JNI_INC_SUBDIRS="linux genunix";; + osf*) _JNI_INC_SUBDIRS="alpha";; + solaris*) _JNI_INC_SUBDIRS="solaris";; + *) _JNI_INC_SUBDIRS="genunix";; + esac +fi + +# add any subdirectories that are present +for _JINCSUBDIR in $_JNI_INC_SUBDIRS +do + if test -d "$_JTOPDIR/include/$_JINCSUBDIR"; then + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include/$_JINCSUBDIR" + fi +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking java version" >&5 +$as_echo_n "checking java version... " >&6; } + case "$JAVA" in + *kaffe* ) + JAVA_VERSION=`$JAVA -version 2>&1 | + sed -e '/Java Version:/!d' -e 's/.*Java Version: \([^ ]*\)[ ]*/\1/'` ;; + * ) JAVA_VERSION=`$JAVA -version 2>&1 | + sed -e '/ version /!d' -e 's/.*"\(.*\)".*/\1/'` ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVA_VERSION" >&5 +$as_echo "$JAVA_VERSION" >&6; } + case "$JAVA_VERSION" in + 1.[3456789]* | 1.[1-9][0-9]* | [23456789]* ) ;; + * ) + as_fn_error "Java version 1.3 or higher required, got $JAVA_VERSION" "$LINENO" 5 ;; + esac + + # Because of the code that SWIG generates to cast between pointers and + # integers, we need to add the flag "-fno-strict-aliasing" to the gcc + # command line when compiling the JNI code. This is documented in + # [#14953] and at http://www.swig.org/Doc1.3/Java.html + if test "${GCC}" = "yes"; then + SWIGCFLAGS="-fno-strict-aliasing" + fi + + for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS + do + CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" + done + + ADDITIONAL_LANG="$ADDITIONAL_LANG java" + INSTALL_LIBS="$INSTALL_LIBS \$(libjso_target)" +else + JAVAC=nojavac +fi + +# MinGW support. +if test "$db_cv_mingw" = "yes"; then + OSDIR=os_windows + PATH_SEPARATOR="\\\\/:" + + $as_echo "#define DB_WIN32 1" >>confdefs.h + + $as_echo "#define STDC_HEADERS 1" >>confdefs.h + +else + OSDIR=os + PATH_SEPARATOR="/" + $as_echo "#define HAVE_SYSTEM_INCLUDE_FILES 1" >>confdefs.h + +fi + +# Optional STL API. +if test "$db_cv_stl" = "yes"; then + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler supports templates for STL" >&5 +$as_echo_n "checking whether the C++ compiler supports templates for STL... " >&6; } + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include + +using std::string; +using std::vector; +namespace dbstl_configure_test { + +template +class MyClass +{ +public: + explicit MyClass(int i) { imem = i;} + + MyClass(const T1& t1, const T2& t2, int i) + { + mem1 = t1; + mem2 = t2; + imem = i; + } + + template + T2 templ_mem_func(T1 t1, T3 t3) + { + mem2 = t1; + T3 t32 = t3; + T2 t2; + return t2; + } + + double templ_mem_func(T1 t1, double t3) + { + mem1 = t1; + double t32 = t3; + return t3; + } + + template + ReturnType templ_mem_func(T7, T8); + + operator T1() const {return mem1;} +private: + T1 mem1; + T2 mem2; + int imem; +}; + +template +template +ReturnType MyClass::templ_mem_func(T7, T8) +{ + ReturnType rt; + return rt; +} + +template<> +class MyClass +{ +public: + explicit MyClass(int i) { imem = i;} + + MyClass(const double& t1, const float& t2, int i) + { + mem1 = t1; + mem2 = t2; + imem = i; + } + + template + float templ_mem_func(double t1, T3 t3) + { + mem2 = t1; + T3 t32 = t3; + float t2; + return t2; + } + + double templ_mem_func(double t1, double t3) + { + mem1 = t1; + double t32 = t3; + return t3; + } + + template + ReturnType templ_mem_func(T7, T8); + + operator double() const {return mem1;} +private: + double mem1; + float mem2; + int imem; +}; + +template +ReturnType MyClass::templ_mem_func(T7, T8) +{ + ReturnType rt; + return rt; +} + +template +class MyClass2 { +public: + MyClass2(const T1& t1, const T2&t2){} +}; + +// partial specialization: both template parameters have same type +template +class MyClass2 { +public: + MyClass2(const T& t1, const T&t2){} +}; + +// partial specialization: second type is int +template +class MyClass2 { +public: + MyClass2(const T& t1, const int&t2){} +}; + +// partial specialization: both template parameters are pointer types +template +class MyClass2 { +public: + MyClass2(const T1* t1, const T2*t2){} +}; + +template +class MyClass2 { +public: + MyClass2(const T* t1, const T*t2){} +}; + +template +int part_spec_func(T4 t4, T5 t5) +{ + // Zero Initialization should work. + T4 t44 = T4(); + T5 t55 = T5(); + + t44 = t4; + t55 = t5; +} + +template +int part_spec_func(T4 t4, std::vector t55) +{ + T4 t44 = t4; + std::vector abc = t55; +} + +// maximum of two int values +inline int const& max (int const& a, int const& b) +{ + return a +inline T2 const max (T1 const& a, T2 const& b) +{ + return a +inline T const& max (T const& a, T const& b) +{ + return a +inline T const& max (T const& a, T const& b, T const& c) +{ + return max (max(a,b), c); +} + +template +class Base { +public: + void exit2(){} + Base(){} +}; + +template +class Derived : public Base { +public: + // Call Base() explicitly here, otherwise can't access it. + // Kind of like this->. + Derived() : Base(){} + + void foo() { + this->exit2(); + } +}; + +} // dbstl_configure_test + +using namespace dbstl_configure_test; +int +main () +{ + + char cc = 'a'; + int i = 4; + double pi = 3.14; + float gold = 0.618; + + MyClass2 mif(i, gold); // uses MyClass2 + MyClass2 mff(gold, gold); // uses MyClass2 + MyClass2 mfi(gold, i); // uses MyClass2 + MyClass2 mp(&i, &gold); // uses MyClass2 + MyClass2 m(&i, &i); // uses MyClass2 + + MyClass obj1(i); + obj1.templ_mem_func(cc, pi); + obj1.templ_mem_func(cc, gold); + obj1.templ_mem_func(i, pi); + obj1.templ_mem_func(cc, cc); + char ch = (char)obj1; + + string str1("abc"), str2("def"); + MyClass obj2(str1.c_str(), str2, i); + obj2.templ_mem_func("klm", str2); + obj2.templ_mem_func("hij", pi); + + // Use j to help distinguish, otherwise unable to use the one defined + // outside of class body. + int j = obj2.templ_mem_func(cc, cc); + // Call explicitly. + obj2.templ_mem_func(gold, pi); + const char *pch = (const char*)obj2; + + MyClass obj3(pi, gold, i); + obj3.templ_mem_func(pi, i); + obj3.templ_mem_func(pi, str1); + obj3.templ_mem_func(pi, pi); + obj3.templ_mem_func(cc, pi); + obj3.templ_mem_func(cc, cc); + double tmpd = (double)obj3; + + MyClass obj4(i); + obj4.templ_mem_func(pi, i); + obj4.templ_mem_func(pi, str1); + obj4.templ_mem_func(pi, pi); + obj4.templ_mem_func(gold, pi); + tmpd = (double)obj4; + + // Function template partial specialization. + part_spec_func(pi, gold); + part_spec_func(gold, i); + part_spec_func(str1, str2); + std::vector strv; + part_spec_func(str1, strv); + std::vector dblv; + part_spec_func(pi, dblv); + + // Function template overloads and explicit call and deduction. + dbstl_configure_test::max(7, 42, 68); // calls the template for three arguments + dbstl_configure_test::max(7.0, 42.0); // calls max (by argument deduction) + dbstl_configure_test::max('a', 'b'); // calls max (by argument deduction) + dbstl_configure_test::max(7, 42.0); + dbstl_configure_test::max(4,4.2); // instantiate T as double + dbstl_configure_test::max(7, 42); // calls the nontemplate for two ints + dbstl_configure_test::max<>(7, 42); // calls max (by argument deduction) + dbstl_configure_test::max(7, 42); // calls max (no argument deduction) + dbstl_configure_test::max('a', 42.7); // calls the nontemplate for two ints + + Base bobj; + bobj.exit2(); + // Using this-> to access base class members. + Derived dobj; + dobj.foo(); + dobj.exit2(); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + as_fn_error "no" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ supports the wstring class" >&5 +$as_echo_n "checking whether C++ supports the wstring class... " >&6; } + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + using std::wstring; +int +main () +{ +wstring ws; ws.find_first_of(ws); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + WSTRING_decl="#define HAVE_WSTRING 1" ; + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + WSTRING_decl="#undef HAVE_WSTRING" ; + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for thread local storage (TLS) class" >&5 +$as_echo_n "checking for thread local storage (TLS) class... " >&6; } + + + ac_cv_tls=none + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + ax_tls_keywords="__thread __declspec(thread) __declspec(__thread)" + for ax_tls_decl_keyword in $ax_tls_keywords ""; do + for ax_tls_defn_keyword in $ax_tls_keywords ""; do + test -z "$ax_tls_decl_keyword" && + test -z "$ax_tls_defn_keyword" && continue + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +template class TLSClass { + public: static $ax_tls_decl_keyword T *tlsvar; + }; + class TLSClass2 { + public: static $ax_tls_decl_keyword int tlsvar; + }; + template $ax_tls_defn_keyword T* TLSClass::tlsvar = NULL; + $ax_tls_defn_keyword int TLSClass2::tlsvar = 1; + static $ax_tls_decl_keyword int x = 0; +int +main () +{ +TLSClass::tlsvar = NULL; TLSClass2::tlsvar = 1; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_tls=modifier ; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done + test "$ac_cv_tls" = none || break + done + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test "$ac_cv_tls" = "none" ; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + + static pthread_once_t once_control_ = PTHREAD_ONCE_INIT; + static pthread_key_t key; + + static void init_once(void) { + pthread_key_create(&key, NULL); + } + static void *get_tls() { + return (void *)pthread_getspecific(&key); + } + static void set_tls(void *p) { + pthread_setspecific(&key, p); + } +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_tls=pthread +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + case "$ac_cv_tls" in + none) break ;; + pthread) + TLS_decl="#define HAVE_PTHREAD_TLS" + TLS_defn="" ;; + modifier) + TLS_decl="#define TLS_DECL_MODIFIER $ax_tls_decl_keyword" + TLS_defn="#define TLS_DEFN_MODIFIER $ax_tls_defn_keyword" ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tls" >&5 +$as_echo "$ac_cv_tls" >&6; } + + if test "$enable_shared" = "no"; then + DEFAULT_LIB_STL="\$(libstl_version)" + fi + if test "$enable_shared" = "yes"; then + DEFAULT_LIB_STL="\$(libstlso_target)" + fi + ADDITIONAL_INCS="dbstl_common.h dbstl_set.h dbstl_vector.h dbstl_exception.h dbstl_map.h dbstl_utility.h dbstl_dbc.h dbstl_dbt.h dbstl_base_iterator.h dbstl_container.h dbstl_element_ref.h dbstl_inner_utility.h dbstl_resource_manager.h $ADDITIONAL_INCS" + INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_STL" + if test "$enable_static" = "yes"; then + INSTALL_LIBS="$INSTALL_LIBS \$(libstl)" + fi +fi + +# Checks for include files, structures, C types. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat file-mode macros are broken" >&5 +$as_echo_n "checking whether stat file-mode macros are broken... " >&6; } +if test "${ac_cv_header_stat_broken+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +#if defined S_ISBLK && defined S_IFDIR +extern char c1[S_ISBLK (S_IFDIR) ? -1 : 1]; +#endif + +#if defined S_ISBLK && defined S_IFCHR +extern char c2[S_ISBLK (S_IFCHR) ? -1 : 1]; +#endif + +#if defined S_ISLNK && defined S_IFREG +extern char c3[S_ISLNK (S_IFREG) ? -1 : 1]; +#endif + +#if defined S_ISSOCK && defined S_IFREG +extern char c4[S_ISSOCK (S_IFREG) ? -1 : 1]; +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stat_broken=no +else + ac_cv_header_stat_broken=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stat_broken" >&5 +$as_echo "$ac_cv_header_stat_broken" >&6; } +if test $ac_cv_header_stat_broken = yes; then + +$as_echo "#define STAT_MACROS_BROKEN 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if test "${ac_cv_header_time+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 +$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_ac_Header=yes" +else + eval "$as_ac_Header=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$as_ac_Header + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if test "${ac_cv_search_opendir+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then : + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if test "${ac_cv_search_opendir+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then : + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + +for ac_header in execinfo.h sys/select.h sys/socket.h sys/time.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_blksize" = x""yes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 +_ACEOF + + +fi + + + +# db.h includes and , not the other default includes +# autoconf usually includes. For that reason, we specify a set of includes +# for all type checking tests. [#5060] +# +# C99 says types should be in ; include if it exists. +# +# Some systems have types in ; include if it exists. +# +# IBM's OS/390 and z/OS releases have types in not also found +# in ; include if it exists. +db_includes="#include " + +ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" +if test "x$ac_cv_header_inttypes_h" = x""yes; then : + + db_includes="$db_includes +#include " + inttypes_h_decl="#include " +fi + + + +# IRIX has stdint.h that is only available when using c99 (i.e. __c99 +# is defined). Problem with having it in a public header is that a c++ +# compiler cannot #include if db.h #includes stdint.h, so we +# need to check that stdint.h is available for all cases. Also the +# IRIX compiler does not exit with a non-zero exit code when it sees +# #error, so we actually need to use the header for the compiler to fail. + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint.h" >&5 +$as_echo_n "checking for stdint.h... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + int main() { + uint_least8_t x=0; + return x; + } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +if test "$db_cv_cxx" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if stdint.h can be used by C++" >&5 +$as_echo_n "checking if stdint.h can be used by C++... " >&6; } + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + int main() { + uint_least8_t x=0; + return x; + } +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + stdint_h_decl="#include " + db_includes="$db_includes +#include " + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + stdint_h_decl="#ifndef __cplusplus +#include +#endif" + db_includes="$db_includes +#ifndef __cplusplus +#include +#endif" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + stdint_h_decl="#include " + db_includes="$db_includes +#include " +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + +ac_fn_c_check_header_mongrel "$LINENO" "stddef.h" "ac_cv_header_stddef_h" "$ac_includes_default" +if test "x$ac_cv_header_stddef_h" = x""yes; then : + + db_includes="$db_includes +#include " + stddef_h_decl="#include " +fi + + + +ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" +if test "x$ac_cv_header_unistd_h" = x""yes; then : + + db_includes="$db_includes +#include " + unistd_h_decl="#include " +fi + + +db_includes="$db_includes +#include " + +# We need to know the sizes of various objects on this system. +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5 +$as_echo_n "checking size of char... " >&6; } +if test "${ac_cv_sizeof_char+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$db_includes +"; then : + +else + if test "$ac_cv_type_char" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (char) +See \`config.log' for more details." "$LINENO" 5; }; } + else + ac_cv_sizeof_char=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5 +$as_echo "$ac_cv_sizeof_char" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHAR $ac_cv_sizeof_char +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned char" >&5 +$as_echo_n "checking size of unsigned char... " >&6; } +if test "${ac_cv_sizeof_unsigned_char+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned char))" "ac_cv_sizeof_unsigned_char" "$db_includes +"; then : + +else + if test "$ac_cv_type_unsigned_char" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (unsigned char) +See \`config.log' for more details." "$LINENO" 5; }; } + else + ac_cv_sizeof_unsigned_char=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_char" >&5 +$as_echo "$ac_cv_sizeof_unsigned_char" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_CHAR $ac_cv_sizeof_unsigned_char +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 +$as_echo_n "checking size of short... " >&6; } +if test "${ac_cv_sizeof_short+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$db_includes +"; then : + +else + if test "$ac_cv_type_short" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (short) +See \`config.log' for more details." "$LINENO" 5; }; } + else + ac_cv_sizeof_short=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 +$as_echo "$ac_cv_sizeof_short" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned short" >&5 +$as_echo_n "checking size of unsigned short... " >&6; } +if test "${ac_cv_sizeof_unsigned_short+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned short))" "ac_cv_sizeof_unsigned_short" "$db_includes +"; then : + +else + if test "$ac_cv_type_unsigned_short" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (unsigned short) +See \`config.log' for more details." "$LINENO" 5; }; } + else + ac_cv_sizeof_unsigned_short=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_short" >&5 +$as_echo "$ac_cv_sizeof_unsigned_short" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +$as_echo_n "checking size of int... " >&6; } +if test "${ac_cv_sizeof_int+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$db_includes +"; then : + +else + if test "$ac_cv_type_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (int) +See \`config.log' for more details." "$LINENO" 5; }; } + else + ac_cv_sizeof_int=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +$as_echo "$ac_cv_sizeof_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5 +$as_echo_n "checking size of unsigned int... " >&6; } +if test "${ac_cv_sizeof_unsigned_int+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int" "$db_includes +"; then : + +else + if test "$ac_cv_type_unsigned_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (unsigned int) +See \`config.log' for more details." "$LINENO" 5; }; } + else + ac_cv_sizeof_unsigned_int=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_int" >&5 +$as_echo "$ac_cv_sizeof_unsigned_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if test "${ac_cv_sizeof_long+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$db_includes +"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (long) +See \`config.log' for more details." "$LINENO" 5; }; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5 +$as_echo_n "checking size of unsigned long... " >&6; } +if test "${ac_cv_sizeof_unsigned_long+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$db_includes +"; then : + +else + if test "$ac_cv_type_unsigned_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (unsigned long) +See \`config.log' for more details." "$LINENO" 5; }; } + else + ac_cv_sizeof_unsigned_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5 +$as_echo "$ac_cv_sizeof_unsigned_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 +$as_echo_n "checking size of long long... " >&6; } +if test "${ac_cv_sizeof_long_long+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$db_includes +"; then : + +else + if test "$ac_cv_type_long_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (long long) +See \`config.log' for more details." "$LINENO" 5; }; } + else + ac_cv_sizeof_long_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 +$as_echo "$ac_cv_sizeof_long_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5 +$as_echo_n "checking size of unsigned long long... " >&6; } +if test "${ac_cv_sizeof_unsigned_long_long+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long" "$db_includes +"; then : + +else + if test "$ac_cv_type_unsigned_long_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (unsigned long long) +See \`config.log' for more details." "$LINENO" 5; }; } + else + ac_cv_sizeof_unsigned_long_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long" >&5 +$as_echo "$ac_cv_sizeof_unsigned_long_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char *" >&5 +$as_echo_n "checking size of char *... " >&6; } +if test "${ac_cv_sizeof_char_p+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char *))" "ac_cv_sizeof_char_p" "$db_includes +"; then : + +else + if test "$ac_cv_type_char_p" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (char *) +See \`config.log' for more details." "$LINENO" 5; }; } + else + ac_cv_sizeof_char_p=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char_p" >&5 +$as_echo "$ac_cv_sizeof_char_p" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHAR_P $ac_cv_sizeof_char_p +_ACEOF + + + +# We look for u_char, u_short, u_int, u_long -- if we can't find them, +# we create our own. + +ac_fn_c_check_type "$LINENO" "u_char" "ac_cv_type_u_char" "$db_includes +" +if test "x$ac_cv_type_u_char" = x""yes; then : + +else + u_char_decl="typedef unsigned char u_char;" +fi + + + +ac_fn_c_check_type "$LINENO" "u_short" "ac_cv_type_u_short" "$db_includes +" +if test "x$ac_cv_type_u_short" = x""yes; then : + +else + u_short_decl="typedef unsigned short u_short;" +fi + + + +ac_fn_c_check_type "$LINENO" "u_int" "ac_cv_type_u_int" "$db_includes +" +if test "x$ac_cv_type_u_int" = x""yes; then : + +else + u_int_decl="typedef unsigned int u_int;" +fi + + + +ac_fn_c_check_type "$LINENO" "u_long" "ac_cv_type_u_long" "$db_includes +" +if test "x$ac_cv_type_u_long" = x""yes; then : + +else + u_long_decl="typedef unsigned long u_long;" +fi + + +# We look for fixed-size variants of u_char, u_short, u_int, u_long as well. + +ac_fn_c_check_type "$LINENO" "u_int8_t" "ac_cv_type_u_int8_t" "$db_includes +" +if test "x$ac_cv_type_u_int8_t" = x""yes; then : + +else + + case "1" in + "$ac_cv_sizeof_unsigned_int") + u_int8_decl="typedef unsigned int u_int8_t;";; + "$ac_cv_sizeof_unsigned_char") + u_int8_decl="typedef unsigned char u_int8_t;";; + "$ac_cv_sizeof_unsigned_short") + u_int8_decl="typedef unsigned short u_int8_t;";; + "$ac_cv_sizeof_unsigned_long") + u_int8_decl="typedef unsigned long u_int8_t;";; + "$ac_cv_sizeof_unsigned_long_long") + u_int8_decl="typedef unsigned long long u_int8_t;";; + *) + if test "" != "notfatal"; then + as_fn_error "No unsigned 1-byte integral type" "$LINENO" 5 + fi;; + esac +fi + + + +ac_fn_c_check_type "$LINENO" "u_int16_t" "ac_cv_type_u_int16_t" "$db_includes +" +if test "x$ac_cv_type_u_int16_t" = x""yes; then : + +else + + case "2" in + "$ac_cv_sizeof_unsigned_int") + u_int16_decl="typedef unsigned int u_int16_t;";; + "$ac_cv_sizeof_unsigned_char") + u_int16_decl="typedef unsigned char u_int16_t;";; + "$ac_cv_sizeof_unsigned_short") + u_int16_decl="typedef unsigned short u_int16_t;";; + "$ac_cv_sizeof_unsigned_long") + u_int16_decl="typedef unsigned long u_int16_t;";; + "$ac_cv_sizeof_unsigned_long_long") + u_int16_decl="typedef unsigned long long u_int16_t;";; + *) + if test "" != "notfatal"; then + as_fn_error "No unsigned 2-byte integral type" "$LINENO" 5 + fi;; + esac +fi + + + +ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$db_includes +" +if test "x$ac_cv_type_int16_t" = x""yes; then : + +else + + case "2" in + "$ac_cv_sizeof_int") + int16_decl="typedef int int16_t;";; + "$ac_cv_sizeof_char") + int16_decl="typedef char int16_t;";; + "$ac_cv_sizeof_short") + int16_decl="typedef short int16_t;";; + "$ac_cv_sizeof_long") + int16_decl="typedef long int16_t;";; + "$ac_cv_sizeof_long_long") + int16_decl="typedef long long int16_t;";; + *) + if test "" != "notfatal"; then + as_fn_error "No signed 2-byte integral type" "$LINENO" 5 + fi;; + esac +fi + + + +ac_fn_c_check_type "$LINENO" "u_int32_t" "ac_cv_type_u_int32_t" "$db_includes +" +if test "x$ac_cv_type_u_int32_t" = x""yes; then : + +else + + case "4" in + "$ac_cv_sizeof_unsigned_int") + u_int32_decl="typedef unsigned int u_int32_t;";; + "$ac_cv_sizeof_unsigned_char") + u_int32_decl="typedef unsigned char u_int32_t;";; + "$ac_cv_sizeof_unsigned_short") + u_int32_decl="typedef unsigned short u_int32_t;";; + "$ac_cv_sizeof_unsigned_long") + u_int32_decl="typedef unsigned long u_int32_t;";; + "$ac_cv_sizeof_unsigned_long_long") + u_int32_decl="typedef unsigned long long u_int32_t;";; + *) + if test "" != "notfatal"; then + as_fn_error "No unsigned 4-byte integral type" "$LINENO" 5 + fi;; + esac +fi + + + +ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$db_includes +" +if test "x$ac_cv_type_int32_t" = x""yes; then : + +else + + case "4" in + "$ac_cv_sizeof_int") + int32_decl="typedef int int32_t;";; + "$ac_cv_sizeof_char") + int32_decl="typedef char int32_t;";; + "$ac_cv_sizeof_short") + int32_decl="typedef short int32_t;";; + "$ac_cv_sizeof_long") + int32_decl="typedef long int32_t;";; + "$ac_cv_sizeof_long_long") + int32_decl="typedef long long int32_t;";; + *) + if test "" != "notfatal"; then + as_fn_error "No signed 4-byte integral type" "$LINENO" 5 + fi;; + esac +fi + + + +ac_fn_c_check_type "$LINENO" "u_int64_t" "ac_cv_type_u_int64_t" "$db_includes +" +if test "x$ac_cv_type_u_int64_t" = x""yes; then : + +else + + case "8" in + "$ac_cv_sizeof_unsigned_int") + u_int64_decl="typedef unsigned int u_int64_t;";; + "$ac_cv_sizeof_unsigned_char") + u_int64_decl="typedef unsigned char u_int64_t;";; + "$ac_cv_sizeof_unsigned_short") + u_int64_decl="typedef unsigned short u_int64_t;";; + "$ac_cv_sizeof_unsigned_long") + u_int64_decl="typedef unsigned long u_int64_t;";; + "$ac_cv_sizeof_unsigned_long_long") + u_int64_decl="typedef unsigned long long u_int64_t;";; + *) + if test "notfatal" != "notfatal"; then + as_fn_error "No unsigned 8-byte integral type" "$LINENO" 5 + fi;; + esac +fi + + + +ac_fn_c_check_type "$LINENO" "int64_t" "ac_cv_type_int64_t" "$db_includes +" +if test "x$ac_cv_type_int64_t" = x""yes; then : + +else + + case "8" in + "$ac_cv_sizeof_int") + int64_decl="typedef int int64_t;";; + "$ac_cv_sizeof_char") + int64_decl="typedef char int64_t;";; + "$ac_cv_sizeof_short") + int64_decl="typedef short int64_t;";; + "$ac_cv_sizeof_long") + int64_decl="typedef long int64_t;";; + "$ac_cv_sizeof_long_long") + int64_decl="typedef long long int64_t;";; + *) + if test "notfatal" != "notfatal"; then + as_fn_error "No signed 8-byte integral type" "$LINENO" 5 + fi;; + esac +fi + + +# No currently autoconf'd systems lack FILE, off_t pid_t, size_t, time_t. +# +# We require them, we don't try to substitute our own if we can't find them. + +ac_fn_c_check_type "$LINENO" "FILE *" "ac_cv_type_FILE_p" "$db_includes +" +if test "x$ac_cv_type_FILE_p" = x""yes; then : + +else + as_fn_error "No FILE type." "$LINENO" 5 +fi + + +ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$db_includes +" +if test "x$ac_cv_type_off_t" = x""yes; then : + +else + as_fn_error "No off_t type." "$LINENO" 5 +fi + + +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$db_includes +" +if test "x$ac_cv_type_pid_t" = x""yes; then : + +else + as_fn_error "No pid_t type." "$LINENO" 5 +fi + + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$db_includes +" +if test "x$ac_cv_type_size_t" = x""yes; then : + +else + as_fn_error "No size_t type." "$LINENO" 5 +fi + + +ac_fn_c_check_type "$LINENO" "time_t" "ac_cv_type_time_t" "$db_includes +" +if test "x$ac_cv_type_time_t" = x""yes; then : + +else + as_fn_error "No time_t type." "$LINENO" 5 +fi + + +# Check for ssize_t -- if none exists, find a signed integral type that's +# the same size as a size_t. +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 +$as_echo_n "checking size of size_t... " >&6; } +if test "${ac_cv_sizeof_size_t+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$db_includes +"; then : + +else + if test "$ac_cv_type_size_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (size_t) +See \`config.log' for more details." "$LINENO" 5; }; } + else + ac_cv_sizeof_size_t=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 +$as_echo "$ac_cv_sizeof_size_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t +_ACEOF + + + +ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$db_includes +" +if test "x$ac_cv_type_ssize_t" = x""yes; then : + +else + + case "$ac_cv_sizeof_size_t" in + "$ac_cv_sizeof_int") + ssize_t_decl="typedef int ssize_t;";; + "$ac_cv_sizeof_char") + ssize_t_decl="typedef char ssize_t;";; + "$ac_cv_sizeof_short") + ssize_t_decl="typedef short ssize_t;";; + "$ac_cv_sizeof_long") + ssize_t_decl="typedef long ssize_t;";; + "$ac_cv_sizeof_long_long") + ssize_t_decl="typedef long long ssize_t;";; + *) + if test "" != "notfatal"; then + as_fn_error "No signed $ac_cv_sizeof_size_t-byte integral type" "$LINENO" 5 + fi;; + esac +fi + + +# Check for uintmax_t -- if none exists, find the largest unsigned integral +# type available. + +ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default" +if test "x$ac_cv_type_uintmax_t" = x""yes; then : + +else + ac_fn_c_check_type "$LINENO" "unsigned long long" "ac_cv_type_unsigned_long_long" "$db_includes +" +if test "x$ac_cv_type_unsigned_long_long" = x""yes; then : + uintmax_t_decl="typedef unsigned long long uintmax_t;" +else + uintmax_t_decl="typedef unsigned long uintmax_t;" +fi + +fi + + +# Check for uintptr_t -- if none exists, find an integral type which is +# the same size as a pointer. + +ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" +if test "x$ac_cv_type_uintptr_t" = x""yes; then : + +else + + case "$ac_cv_sizeof_char_p" in + "$ac_cv_sizeof_unsigned_int") + uintptr_t_decl="typedef unsigned int uintptr_t;";; + "$ac_cv_sizeof_unsigned_char") + uintptr_t_decl="typedef unsigned char uintptr_t;";; + "$ac_cv_sizeof_unsigned_short") + uintptr_t_decl="typedef unsigned short uintptr_t;";; + "$ac_cv_sizeof_unsigned_long") + uintptr_t_decl="typedef unsigned long uintptr_t;";; + "$ac_cv_sizeof_unsigned_long_long") + uintptr_t_decl="typedef unsigned long long uintptr_t;";; + *) + if test "" != "notfatal"; then + as_fn_error "No unsigned $ac_cv_sizeof_char_p-byte integral type" "$LINENO" 5 + fi;; + esac +fi + + + + ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "$db_includes +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +" +if test "x$ac_cv_type_socklen_t" = x""yes; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t equivalent" >&5 +$as_echo_n "checking for socklen_t equivalent... " >&6; } + if test "${db_cv_socklen_t_equiv+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Systems have either "struct sockaddr *" or + # "void *" as the second argument to getpeername + db_cv_socklen_t_equiv= + for arg2 in "struct sockaddr" void; do + for t in int size_t "unsigned int" "long int" "unsigned long int"; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$db_includes +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + int getpeername (int, $arg2 *, $t *); +int +main () +{ +$t len; + getpeername (0, 0, &len); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_socklen_t_equiv="$t" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$db_cv_socklen_t_equiv" != "" && break + done + test "$db_cv_socklen_t_equiv" != "" && break + done + +fi + + if test "$db_cv_socklen_t_equiv" = ""; then + as_fn_error "Cannot find a type to use in place of socklen_t" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_socklen_t_equiv" >&5 +$as_echo "$db_cv_socklen_t_equiv" >&6; } + +cat >>confdefs.h <<_ACEOF +#define socklen_t $db_cv_socklen_t_equiv +_ACEOF + +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C exit success/failure values" >&5 +$as_echo_n "checking for ANSI C exit success/failure values... " >&6; } +if test "${db_cv_exit_defines+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +return (EXIT_SUCCESS); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_exit_defines=yes +else + db_cv_exit_defines=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_exit_defines" >&5 +$as_echo "$db_cv_exit_defines" >&6; } +if test "$db_cv_exit_defines" = "yes"; then + $as_echo "#define HAVE_EXIT_SUCCESS 1" >>confdefs.h + + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getopt optreset variable" >&5 +$as_echo_n "checking for getopt optreset variable... " >&6; } +if test "${db_cv_optreset+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +extern int optreset; optreset = 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_optreset=yes +else + db_cv_optreset=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_optreset" >&5 +$as_echo "$db_cv_optreset" >&6; } +if test "$db_cv_optreset" = "yes"; then + $as_echo "#define HAVE_GETOPT_OPTRESET 1" >>confdefs.h + + +fi + +# Check for mutexes. +# We do this first because it changes $LIBSO_LIBS. + + +# Mutexes we don't test for, but want the #defines to exist for other ports. + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mutexes" >&5 +$as_echo_n "checking for mutexes... " >&6; } +if test "${db_cv_mutex+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + + +orig_libs=$LIBS + +db_cv_mutex=no + +# Mutexes can be disabled. +if test "$db_cv_build_mutexsupport" = no; then + db_cv_mutex=disabled; +fi + +# User-specified Win32 mutexes (MinGW build) +if test "$db_cv_mingw" = yes; then + db_cv_mutex=win32/gcc +fi + +if test "$db_cv_mutex" = no; then + # User-specified POSIX or UI mutexes. + # + # There are two different reasons to specify mutexes: First, the + # application is already using one type of mutex and doesn't want + # to mix-and-match (for example, on Solaris, which has POSIX, UI + # and LWP mutexes). Second, the application's POSIX pthreads + # mutexes don't support inter-process locking, but the application + # wants to use them anyway (for example, some Linux and *BSD systems). + # + # Test for POSIX threads before testing for UI/LWP threads, they are + # the Sun-recommended choice on Solaris. Also, there are Linux systems + # that support a UI compatibility mode, and applications are more + # likely to be written for POSIX threads than UI threads. + if test "$db_cv_posixmutexes" = yes; then + db_cv_mutex=posix_only; + fi + if test "$db_cv_uimutexes" = yes; then + db_cv_mutex=ui_only; + fi + + # POSIX.1 pthreads: pthread_XXX + # + # If the user specified we use POSIX pthreads mutexes, and we fail to + # find the full interface, try and configure for just intra-process + # support. + if test "$db_cv_mutex" = no -o "$db_cv_mutex" = posix_only; then + LIBS="$LIBS -lpthread" + +if test "$cross_compiling" = yes; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_condattr_t condattr; + pthread_mutexattr_t mutexattr; + exit ( + pthread_condattr_init(&condattr) || + pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) || + pthread_mutexattr_init(&mutexattr) || + pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) || + pthread_cond_init(&cond, &condattr) || + pthread_mutex_init(&mutex, &mutexattr) || + pthread_mutex_lock(&mutex) || + pthread_mutex_unlock(&mutex) || + pthread_mutex_destroy(&mutex) || + pthread_cond_destroy(&cond) || + pthread_condattr_destroy(&condattr) || + pthread_mutexattr_destroy(&mutexattr)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex="POSIX/pthreads/library" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +main() { + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_condattr_t condattr; + pthread_mutexattr_t mutexattr; + exit ( + pthread_condattr_init(&condattr) || + pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) || + pthread_mutexattr_init(&mutexattr) || + pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) || + pthread_cond_init(&cond, &condattr) || + pthread_mutex_init(&mutex, &mutexattr) || + pthread_mutex_lock(&mutex) || + pthread_mutex_unlock(&mutex) || + pthread_mutex_destroy(&mutex) || + pthread_cond_destroy(&cond) || + pthread_condattr_destroy(&condattr) || + pthread_mutexattr_destroy(&mutexattr)); +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + db_cv_mutex="POSIX/pthreads/library" +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + LIBS="$orig_libs" + fi + if test "$db_cv_mutex" = no -o "$db_cv_mutex" = posix_only; then + +if test "$cross_compiling" = yes; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_condattr_t condattr; + pthread_mutexattr_t mutexattr; + exit ( + pthread_condattr_init(&condattr) || + pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) || + pthread_mutexattr_init(&mutexattr) || + pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) || + pthread_cond_init(&cond, &condattr) || + pthread_mutex_init(&mutex, &mutexattr) || + pthread_mutex_lock(&mutex) || + pthread_mutex_unlock(&mutex) || + pthread_mutex_destroy(&mutex) || + pthread_cond_destroy(&cond) || + pthread_condattr_destroy(&condattr) || + pthread_mutexattr_destroy(&mutexattr)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex="POSIX/pthreads" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +main() { + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_condattr_t condattr; + pthread_mutexattr_t mutexattr; + exit ( + pthread_condattr_init(&condattr) || + pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) || + pthread_mutexattr_init(&mutexattr) || + pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) || + pthread_cond_init(&cond, &condattr) || + pthread_mutex_init(&mutex, &mutexattr) || + pthread_mutex_lock(&mutex) || + pthread_mutex_unlock(&mutex) || + pthread_mutex_destroy(&mutex) || + pthread_cond_destroy(&cond) || + pthread_condattr_destroy(&condattr) || + pthread_mutexattr_destroy(&mutexattr)); +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + db_cv_mutex="POSIX/pthreads" +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi + if test "$db_cv_mutex" = posix_only; then + +if test "$cross_compiling" = yes; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_condattr_t condattr; + pthread_mutexattr_t mutexattr; + exit ( + pthread_condattr_init(&condattr) || + pthread_mutexattr_init(&mutexattr) || + pthread_cond_init(&cond, &condattr) || + pthread_mutex_init(&mutex, &mutexattr) || + pthread_mutex_lock(&mutex) || + pthread_mutex_unlock(&mutex) || + pthread_mutex_destroy(&mutex) || + pthread_cond_destroy(&cond) || + pthread_condattr_destroy(&condattr) || + pthread_mutexattr_destroy(&mutexattr)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex="POSIX/pthreads/private" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +main() { + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_condattr_t condattr; + pthread_mutexattr_t mutexattr; + exit ( + pthread_condattr_init(&condattr) || + pthread_mutexattr_init(&mutexattr) || + pthread_cond_init(&cond, &condattr) || + pthread_mutex_init(&mutex, &mutexattr) || + pthread_mutex_lock(&mutex) || + pthread_mutex_unlock(&mutex) || + pthread_mutex_destroy(&mutex) || + pthread_cond_destroy(&cond) || + pthread_condattr_destroy(&condattr) || + pthread_mutexattr_destroy(&mutexattr)); +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + db_cv_mutex="POSIX/pthreads/private" +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi + if test "$db_cv_mutex" = posix_only; then + LIBS="$LIBS -lpthread" + +if test "$cross_compiling" = yes; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_condattr_t condattr; + pthread_mutexattr_t mutexattr; + exit ( + pthread_condattr_init(&condattr) || + pthread_mutexattr_init(&mutexattr) || + pthread_cond_init(&cond, &condattr) || + pthread_mutex_init(&mutex, &mutexattr) || + pthread_mutex_lock(&mutex) || + pthread_mutex_unlock(&mutex) || + pthread_mutex_destroy(&mutex) || + pthread_cond_destroy(&cond) || + pthread_condattr_destroy(&condattr) || + pthread_mutexattr_destroy(&mutexattr)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex="POSIX/pthreads/library/private" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +main() { + pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_condattr_t condattr; + pthread_mutexattr_t mutexattr; + exit ( + pthread_condattr_init(&condattr) || + pthread_mutexattr_init(&mutexattr) || + pthread_cond_init(&cond, &condattr) || + pthread_mutex_init(&mutex, &mutexattr) || + pthread_mutex_lock(&mutex) || + pthread_mutex_unlock(&mutex) || + pthread_mutex_destroy(&mutex) || + pthread_cond_destroy(&cond) || + pthread_condattr_destroy(&condattr) || + pthread_mutexattr_destroy(&mutexattr)); +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + db_cv_mutex="POSIX/pthreads/library/private" +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + LIBS="$orig_libs" + fi + if test "$db_cv_mutex" = posix_only; then + as_fn_error "unable to find POSIX 1003.1 mutex interfaces" "$LINENO" 5 + fi + + # LWP threads: _lwp_XXX + if test "$db_cv_mutex" = no; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include +int +main () +{ + + static lwp_mutex_t mi = SHAREDMUTEX; + static lwp_cond_t ci = SHAREDCV; + lwp_mutex_t mutex = mi; + lwp_cond_t cond = ci; + exit ( + _lwp_mutex_lock(&mutex) || + _lwp_mutex_unlock(&mutex)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex=Solaris/lwp +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + fi + + # UI threads: thr_XXX + if test "$db_cv_mutex" = no -o "$db_cv_mutex" = ui_only; then + LIBS="$LIBS -lthread" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include +int +main () +{ + + mutex_t mutex; + cond_t cond; + int type = USYNC_PROCESS; + exit ( + mutex_init(&mutex, type, NULL) || + cond_init(&cond, type, NULL) || + mutex_lock(&mutex) || + mutex_unlock(&mutex)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex=UI/threads/library +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$orig_libs" + fi + if test "$db_cv_mutex" = no -o "$db_cv_mutex" = ui_only; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include +int +main () +{ + + mutex_t mutex; + cond_t cond; + int type = USYNC_PROCESS; + exit ( + mutex_init(&mutex, type, NULL) || + cond_init(&cond, type, NULL) || + mutex_lock(&mutex) || + mutex_unlock(&mutex)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex=UI/threads +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + fi + if test "$db_cv_mutex" = ui_only; then + as_fn_error "unable to find UI mutex interfaces" "$LINENO" 5 + fi + + # We're done testing for pthreads-style mutexes. Next, check for + # test-and-set mutexes. Check first for hybrid implementations, + # because we check for them even if we've already found a + # pthreads-style mutex and they're the most common architectures + # anyway. + # + # x86/gcc: FreeBSD, NetBSD, BSD/OS, Linux + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + #if (defined(i386) || defined(__i386__)) && defined(__GNUC__) + exit(0); + #else + FAIL TO COMPILE/LINK + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex="$db_cv_mutex/x86/gcc-assembly" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + # x86_64/gcc: FreeBSD, NetBSD, BSD/OS, Linux + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + #if (defined(x86_64) || defined(__x86_64__)) && defined(__GNUC__) + exit(0); + #else + FAIL TO COMPILE/LINK + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex="$db_cv_mutex/x86_64/gcc-assembly" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + # Solaris is one of the systems where we can configure hybrid mutexes. + # However, we require the membar_enter function for that, and only newer + # Solaris releases have it. Check to see if we can configure hybrids. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include +int +main () +{ + + typedef lock_t tsl_t; + lock_t x; + _lock_try(&x); + _lock_clear(&x); + membar_enter(); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex="$db_cv_mutex/Solaris/_lock_try/membar" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + # Sparc/gcc: SunOS, Solaris, ultrasparc assembler support + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + #if defined(__sparc__) && defined(__GNUC__) + asm volatile ("membar #StoreStore|#StoreLoad|#LoadStore"); + exit(0); + #else + FAIL TO COMPILE/LINK + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex="$db_cv_mutex/Sparc/gcc-assembly" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + # We're done testing for any hybrid mutex implementations. If we did + # not find a pthreads-style mutex, but did find a test-and-set mutex, + # we set db_cv_mutex to "no/XXX" -- clean that up. + db_cv_mutex=`echo $db_cv_mutex | sed 's/^no\///'` +fi + +# If we still don't have a mutex implementation yet, continue testing for a +# test-and-set mutex implementation. + +# _lock_try/_lock_clear: Solaris +# On Solaris systems without other mutex interfaces, DB uses the undocumented +# _lock_try _lock_clear function calls instead of either the sema_trywait(3T) +# or sema_wait(3T) function calls. This is because of problems in those +# interfaces in some releases of the Solaris C library. +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int +main () +{ + + typedef lock_t tsl_t; + lock_t x; + _lock_try(&x); + _lock_clear(&x); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex=Solaris/_lock_try +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +# msemaphore: HPPA only +# Try HPPA before general msem test, it needs special alignment. +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + +#if defined(__hppa) + typedef msemaphore tsl_t; + msemaphore x; + msem_init(&x, 0); + msem_lock(&x, 0); + msem_unlock(&x, 0); + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex=HP/msem_init +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +# msemaphore: AIX, OSF/1 +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int +main () +{ + + typedef msemaphore tsl_t; + msemaphore x; + msem_init(&x, 0); + msem_lock(&x, 0); + msem_unlock(&x, 0); + exit(0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex=UNIX/msem_init +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +# ReliantUNIX +if test "$db_cv_mutex" = no; then +LIBS="$LIBS -lmproc" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + + typedef spinlock_t tsl_t; + spinlock_t x; + initspin(&x, 1); + cspinlock(&x); + spinunlock(&x); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex=ReliantUNIX/initspin +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$orig_libs" +fi + +# SCO: UnixWare has threads in libthread, but OpenServer doesn't. +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if defined(__USLC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex=SCO/x86/cc-assembly +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# abilock_t: SGI +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + + typedef abilock_t tsl_t; + abilock_t x; + init_lock(&x); + acquire_lock(&x); + release_lock(&x); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex=SGI/init_lock +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +# sema_t: Solaris +# The sema_XXX calls do not work on Solaris 5.5. I see no reason to ever +# turn this test on, unless we find some other platform that uses the old +# POSIX.1 interfaces. +if test "$db_cv_mutex" = DOESNT_WORK; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + + typedef sema_t tsl_t; + sema_t x; + sema_init(&x, 1, USYNC_PROCESS, NULL); + sema_wait(&x); + sema_post(&x); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex=UNIX/sema_init +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +# _check_lock/_clear_lock: AIX +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + + int x; + _check_lock(&x,0,1); + _clear_lock(&x,0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex=AIX/_check_lock +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +# _spin_lock_try/_spin_unlock: Apple/Darwin +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + int x; + _spin_lock_try(&x); + _spin_unlock(&x); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex=Darwin/_spin_lock_try +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +# Tru64/cc +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if defined(__alpha) && defined(__DECC) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex=Tru64/cc-assembly +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# Alpha/gcc +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if defined(__alpha) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex=ALPHA/gcc-assembly +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# ARM/gcc: Linux +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if defined(__arm__) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex=ARM/gcc-assembly +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# MIPS/gcc: Linux +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if (defined(__mips) || defined(__mips__)) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex=MIPS/gcc-assembly +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# PaRisc/gcc: HP/UX +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if (defined(__hppa) || defined(__hppa__)) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex=HPPA/gcc-assembly +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# PPC/gcc: +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if (defined(__powerpc__) || defined(__ppc__)) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex=PPC/gcc-assembly +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# 68K/gcc: SunOS +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if (defined(mc68020) || defined(sun3)) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex=68K/gcc-assembly +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# S390/cc: IBM OS/390 Unix +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if defined(__MVS__) && defined(__IBMC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex=S390/cc-assembly +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# S390/gcc: Linux +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if defined(__s390__) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex=S390/gcc-assembly +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# ia64/gcc: Linux +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if defined(__ia64) && defined(__GNUC__) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex=ia64/gcc-assembly +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# uts/cc: UTS +if test "$db_cv_mutex" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if defined(_UTS) + exit(0); +#else + FAIL TO COMPILE/LINK +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_mutex=UTS/cc-assembly +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# UNIX fcntl system call mutexes. +# Note that fcntl mutexes are no longer supported in 4.8. This code has been +# left in place in case there is some system that we are not aware of that uses +# fcntl mutexes, in which case additional work will be required for DB 4.8 in +# order to support shared latches. +if test "$db_cv_mutex" = no; then + db_cv_mutex=UNIX/fcntl +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + + struct flock l; + l.l_whence = SEEK_SET; + l.l_start = 10; + l.l_len = 1; + l.l_type = F_WRLCK; + fcntl(0, F_SETLK, &l); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_mutex=UNIX/fcntl +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_mutex" >&5 +$as_echo "$db_cv_mutex" >&6; } + +# Configure a pthreads-style mutex implementation. +hybrid=pthread +case "$db_cv_mutex" in +POSIX/pthreads*) ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_PTHREADS 1" >>confdefs.h + + ;; +POSIX/pthreads/private*)ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_PTHREADS 1" >>confdefs.h + + $as_echo "#define HAVE_MUTEX_THREAD_ONLY 1" >>confdefs.h + + ;; +POSIX/pthreads/library*)ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_PTHREADS 1" >>confdefs.h +;; +POSIX/pthreads/library/private*) + ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_PTHREADS 1" >>confdefs.h + + $as_echo "#define HAVE_MUTEX_THREAD_ONLY 1" >>confdefs.h +;; +Solaris/lwp*) ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_SOLARIS_LWP 1" >>confdefs.h + + ;; +UI/threads*) ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_UI_THREADS 1" >>confdefs.h + + ;; +UI/threads/library*) ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_UI_THREADS 1" >>confdefs.h +;; +*) hybrid=no;; +esac + +# Configure a test-and-set mutex implementation. +case "$db_cv_mutex" in +68K/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_68K_GCC_ASSEMBLY 1" >>confdefs.h + + ;; +AIX/_check_lock) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_AIX_CHECK_LOCK 1" >>confdefs.h + + ;; +Darwin/_spin_lock_try) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY 1" >>confdefs.h + + ;; +ALPHA/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_ALPHA_GCC_ASSEMBLY 1" >>confdefs.h + + ;; +ARM/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_ARM_GCC_ASSEMBLY 1" >>confdefs.h + + ;; +HP/msem_init) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_HPPA_MSEM_INIT 1" >>confdefs.h + + ;; +HPPA/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_HPPA_GCC_ASSEMBLY 1" >>confdefs.h + + ;; +ia64/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_IA64_GCC_ASSEMBLY 1" >>confdefs.h + + ;; +MIPS/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_MIPS_GCC_ASSEMBLY 1" >>confdefs.h + + ;; +PPC/gcc-assembly) + ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_PPC_GCC_ASSEMBLY 1" >>confdefs.h + + ;; +ReliantUNIX/initspin) LIBSO_LIBS="$LIBSO_LIBS -lmproc" + ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_RELIANTUNIX_INITSPIN 1" >>confdefs.h + + ;; +S390/cc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_S390_CC_ASSEMBLY 1" >>confdefs.h + + ;; +S390/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_S390_GCC_ASSEMBLY 1" >>confdefs.h + + ;; +SCO/x86/cc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_SCO_X86_CC_ASSEMBLY 1" >>confdefs.h + + ;; +SGI/init_lock) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_SGI_INIT_LOCK 1" >>confdefs.h + + ;; +Solaris/_lock_try) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_SOLARIS_LOCK_TRY 1" >>confdefs.h + + ;; +*Solaris/_lock_try/membar) + hybrid="$hybrid/tas" + ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_SOLARIS_LOCK_TRY 1" >>confdefs.h + + ;; +*Sparc/gcc-assembly) hybrid="$hybrid/tas" + ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_SPARC_GCC_ASSEMBLY 1" >>confdefs.h + + ;; +Tru64/cc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_TRU64_CC_ASSEMBLY 1" >>confdefs.h + + ;; +UNIX/msem_init) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_MSEM_INIT 1" >>confdefs.h + + ;; +UNIX/sema_init) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_SEMA_INIT 1" >>confdefs.h + + ;; +UTS/cc-assembly) ADDITIONAL_OBJS="uts4.cc${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_UTS_CC_ASSEMBLY 1" >>confdefs.h + + ;; +*x86/gcc-assembly) hybrid="$hybrid/tas" + ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_X86_GCC_ASSEMBLY 1" >>confdefs.h + + ;; +*x86_64/gcc-assembly) hybrid="$hybrid/tas" + ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_X86_64_GCC_ASSEMBLY 1" >>confdefs.h + + ;; +esac + +# Configure the remaining special cases. +case "$db_cv_mutex" in +UNIX/fcntl) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: NO SHARED LATCH IMPLEMENTATION FOUND FOR THIS PLATFORM." >&5 +$as_echo "$as_me: WARNING: NO SHARED LATCH IMPLEMENTATION FOUND FOR THIS PLATFORM." >&2;} + ADDITIONAL_OBJS="mut_fcntl${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_FCNTL 1" >>confdefs.h + + ;; +win32) ADDITIONAL_OBJS="mut_win32${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_WIN32 1" >>confdefs.h + + ;; +win32/gcc) ADDITIONAL_OBJS="mut_win32${o} $ADDITIONAL_OBJS" + $as_echo "#define HAVE_MUTEX_WIN32_GCC 1" >>confdefs.h + + ;; +esac + +# Mutexes may not have been found, or may have been disabled. +case "$db_cv_mutex" in +disabled) + ;; +*) + # Test to see if mutexes have been found by checking the list of + # additional objects for a mutex implementation. + case "$ADDITIONAL_OBJS" in + *mut_pthread*|*mut_tas*|*mut_win32*) + $as_echo "#define HAVE_MUTEX_SUPPORT 1" >>confdefs.h + + + + # Shared latches are required in 4.8, and are implemented using + # mutexes if we don't have a native implementation. + # This macro may be removed in a future release. + + $as_echo "#define HAVE_SHARED_LATCHES 1" >>confdefs.h +;; + *) + as_fn_error "Unable to find a mutex implementation" "$LINENO" 5;; + esac +esac + +# We may have found both a pthreads-style mutex implementation as well as a +# test-and-set, in which case configure for the hybrid. +if test "$hybrid" = pthread/tas; then + $as_echo "#define HAVE_MUTEX_HYBRID 1" >>confdefs.h + + +fi + +# The mutex selection may require specific declarations -- we fill in most of +# them above, but here are the common ones. +# +# The mutex selection may tell us what kind of thread package we're using, +# which we use to figure out the thread type. +# +# If we're configured for the POSIX pthread API, then force the thread ID type +# and include function, regardless of the mutex selection. Ditto for the +# (default) Solaris lwp mutexes, because they don't have a way to return the +# thread ID. +# +# Try and link with a threads library if possible. The problem is the Solaris +# C library has UI/POSIX interface stubs, but they're broken, configuring them +# for inter-process mutexes doesn't return an error, but it doesn't work either. +# For that reason always add -lpthread if we're using pthread calls or mutexes +# and there's a pthread library. +# +# We can't depend on any specific call existing (pthread_create, for example), +# as it may be #defined in an include file -- OSF/1 (Tru64) has this problem. + + + +db_threadid_t_decl=notset + +case "$db_cv_mutex" in +UI/threads*) + thread_h_decl="#include " + db_threadid_t_decl="typedef thread_t db_threadid_t;" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lthread" >&5 +$as_echo_n "checking for main in -lthread... " >&6; } +if test "${ac_cv_lib_thread_main+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_thread_main=yes +else + ac_cv_lib_thread_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_thread_main" >&5 +$as_echo "$ac_cv_lib_thread_main" >&6; } +if test "x$ac_cv_lib_thread_main" = x""yes; then : + LIBSO_LIBS="$LIBSO_LIBS -lthread" +fi +ac_cv_lib_thread=ac_cv_lib_thread_main +;; +*) + ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" +if test "x$ac_cv_header_pthread_h" = x""yes; then : + ac_cv_header_pthread_h=yes +fi + + + if test "$ac_cv_header_pthread_h" = "yes" ; then + thread_h_decl="#include " + db_threadid_t_decl="typedef pthread_t db_threadid_t;" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5 +$as_echo_n "checking for main in -lpthread... " >&6; } +if test "${ac_cv_lib_pthread_main+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pthread_main=yes +else + ac_cv_lib_pthread_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5 +$as_echo "$ac_cv_lib_pthread_main" >&6; } +if test "x$ac_cv_lib_pthread_main" = x""yes; then : + LIBSO_LIBS="$LIBSO_LIBS -lpthread" +fi +ac_cv_lib_pthread=ac_cv_lib_pthread_main +;; +esac + +# We need to know if the thread ID type will fit into an integral type and we +# can compare it for equality and generally treat it like an int, or if it's a +# non-integral type and we have to treat it like a structure or other untyped +# block of bytes. For example, MVS typedef's pthread_t to a structure. + +if test "$db_threadid_t_decl" = notset; then + db_threadid_t_decl="typedef uintmax_t db_threadid_t;" + $as_echo "#define HAVE_SIMPLE_THREAD_TYPE 1" >>confdefs.h + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + $thread_h_decl +int +main () +{ + + $db_threadid_t_decl + db_threadid_t a; + a = 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + $as_echo "#define HAVE_SIMPLE_THREAD_TYPE 1" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +# There are 3 classes of mutexes: +# +# 1: Mutexes requiring no cleanup, for example, test-and-set mutexes. +# 2: Mutexes that must be destroyed, but which don't hold permanent system +# resources, for example, pthread mutexes on MVS aka OS/390 aka z/OS. +# 3: Mutexes that must be destroyed, even after the process is gone, for +# example, pthread mutexes on QNX and binary semaphores on VxWorks. +# +# DB cannot currently distinguish between #2 and #3 because DB does not know +# if the application is running environment recovery as part of startup and +# does not need to do cleanup, or if the environment is being removed and/or +# recovered in a loop in the application, and so does need to clean up. If +# we get it wrong, we're going to call the mutex destroy routine on a random +# piece of memory, which usually works, but just might drop core. For now, +# we group #2 and #3 into the HAVE_MUTEX_SYSTEM_RESOURCES define, until we +# have a better solution or reason to solve this in a general way -- so far, +# the places we've needed to handle this are few. + + +case "$host_os$db_cv_mutex" in +*qnx*POSIX/pthread*|openedition*POSIX/pthread*) + $as_echo "#define HAVE_MUTEX_SYSTEM_RESOURCES 1" >>confdefs.h +;; +esac + +# Check for native (system call or instruction set) support for +# atomic increment, decrement, and compare & exchange. + +# Probe for native atomic operations +# gcc/x86{,_64} inline asm +# solaris atomic_* library calls + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atomic operations" >&5 +$as_echo_n "checking for atomic operations... " >&6; } +if test "${db_cv_atomic+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +db_cv_atomic=no +# atomic operations can be disabled via --disable-atomicsupport +if test "$db_cv_build_atomicsupport" = no; then + db_cv_atomic=disabled +fi + +# The MinGW build uses the Windows API for atomic operations +if test "$db_cv_mingw" = yes; then + db_cv_atomic=mingw +fi + +if test "$db_cv_atomic" = no; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + #if ((defined(i386) || defined(__i386__)) && defined(__GNUC__)) + exit(0); + #elif ((defined(x86_64) || defined(__x86_64__)) && defined(__GNUC__)) + exit(0); + #else + FAIL TO COMPILE/LINK + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + db_cv_atomic="x86/gcc-assembly" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +if test "$db_cv_atomic" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + + volatile unsigned val = 1; + exit (atomic_inc_uint_nv(&val) != 2 || + atomic_dec_uint_nv(&val) != 1 || + atomic_cas_32(&val, 1, 3) != 3); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_atomic="solaris/atomic" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_atomic" >&5 +$as_echo "$db_cv_atomic" >&6; } + +case "$db_cv_atomic" in + x86/gcc-assembly) + $as_echo "#define HAVE_ATOMIC_SUPPORT 1" >>confdefs.h + + $as_echo "#define HAVE_ATOMIC_X86_GCC_ASSEMBLY 1" >>confdefs.h + + ;; + + solaris/atomic) + $as_echo "#define HAVE_ATOMIC_SUPPORT 1" >>confdefs.h + + $as_echo "#define HAVE_ATOMIC_SOLARIS 1" >>confdefs.h + + ;; + mingw) + $as_echo "#define HAVE_ATOMIC_SUPPORT 1" >>confdefs.h + + ;; +esac + + +# Test for various functions/libraries -- do tests that change library values +# first. +# +# Update LIBS, so we're testing against the current list of libraries. +LIBS="$LIBSO_LIBS" + +# The yield function on Solaris is almost certainly pthread_yield (LWP threads +# or POSIX pthreads), or thr_yield (UI threads). There's an outside chance it +# is sched_yield() though, only available in -lrt on Solaris. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sched_yield" >&5 +$as_echo_n "checking for library containing sched_yield... " >&6; } +if test "${ac_cv_search_sched_yield+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sched_yield (); +int +main () +{ +return sched_yield (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_sched_yield=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_sched_yield+set}" = set; then : + break +fi +done +if test "${ac_cv_search_sched_yield+set}" = set; then : + +else + ac_cv_search_sched_yield=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sched_yield" >&5 +$as_echo "$ac_cv_search_sched_yield" >&6; } +ac_res=$ac_cv_search_sched_yield +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +# The Berkeley DB library calls fdatasync, only available in -lrt on Solaris. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fdatasync" >&5 +$as_echo_n "checking for library containing fdatasync... " >&6; } +if test "${ac_cv_search_fdatasync+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char fdatasync (); +int +main () +{ +return fdatasync (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_fdatasync=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_fdatasync+set}" = set; then : + break +fi +done +if test "${ac_cv_search_fdatasync+set}" = set; then : + +else + ac_cv_search_fdatasync=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fdatasync" >&5 +$as_echo "$ac_cv_search_fdatasync" >&6; } +ac_res=$ac_cv_search_fdatasync +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getaddrinfo" >&5 +$as_echo_n "checking for library containing getaddrinfo... " >&6; } +if test "${ac_cv_search_getaddrinfo+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char getaddrinfo (); +int +main () +{ +return getaddrinfo (); + ; + return 0; +} +_ACEOF +for ac_lib in '' nsl socket; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_getaddrinfo=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_getaddrinfo+set}" = set; then : + break +fi +done +if test "${ac_cv_search_getaddrinfo+set}" = set; then : + +else + ac_cv_search_getaddrinfo=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_getaddrinfo" >&5 +$as_echo "$ac_cv_search_getaddrinfo" >&6; } +ac_res=$ac_cv_search_getaddrinfo +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing hstrerror" >&5 +$as_echo_n "checking for library containing hstrerror... " >&6; } +if test "${ac_cv_search_hstrerror+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char hstrerror (); +int +main () +{ +return hstrerror (); + ; + return 0; +} +_ACEOF +for ac_lib in '' resolv; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_hstrerror=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_hstrerror+set}" = set; then : + break +fi +done +if test "${ac_cv_search_hstrerror+set}" = set; then : + +else + ac_cv_search_hstrerror=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_hstrerror" >&5 +$as_echo "$ac_cv_search_hstrerror" >&6; } +ac_res=$ac_cv_search_hstrerror +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +# Those tests updated LIBS, update our internal list. +LIBSO_LIBS="$LIBS" + +# !!! +# We could be more exact about whether these libraries are needed, but don't +# bother -- if they exist, we load them, it's only the test programs anyway. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lm" >&5 +$as_echo_n "checking for main in -lm... " >&6; } +if test "${ac_cv_lib_m_main+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_m_main=yes +else + ac_cv_lib_m_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_main" >&5 +$as_echo "$ac_cv_lib_m_main" >&6; } +if test "x$ac_cv_lib_m_main" = x""yes; then : + TEST_LIBS="$TEST_LIBS -lm" +fi +ac_cv_lib_m=ac_cv_lib_m_main + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lnsl" >&5 +$as_echo_n "checking for main in -lnsl... " >&6; } +if test "${ac_cv_lib_nsl_main+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_main=yes +else + ac_cv_lib_nsl_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_main" >&5 +$as_echo "$ac_cv_lib_nsl_main" >&6; } +if test "x$ac_cv_lib_nsl_main" = x""yes; then : + TEST_LIBS="$TEST_LIBS -lnsl" +fi +ac_cv_lib_nsl=ac_cv_lib_nsl_main + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsocket" >&5 +$as_echo_n "checking for main in -lsocket... " >&6; } +if test "${ac_cv_lib_socket_main+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_main=yes +else + ac_cv_lib_socket_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_main" >&5 +$as_echo "$ac_cv_lib_socket_main" >&6; } +if test "x$ac_cv_lib_socket_main" = x""yes; then : + TEST_LIBS="$TEST_LIBS -lsocket" +fi +ac_cv_lib_socket=ac_cv_lib_socket_main + + +# Checks for system functions for which we have replacements. +# +# The only portable getcwd call is getcwd(char *, size_t), where the +# buffer is non-NULL -- Solaris can't handle a NULL buffer, and they +# deleted getwd(). +for ac_func in \ + abort atoi atol getcwd getenv getopt isalpha isdigit isprint\ + isspace memcmp memcpy memmove printf qsort raise rand strcasecmp\ + strcat strchr strdup strerror strncat strncmp strrchr strsep\ + strtol strtoul +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + case " $LIBOBJS " in + *" $ac_func.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" + ;; +esac + +fi +done + + + +# Check for system functions we optionally use. +for ac_func in \ + _fstati64 backtrace backtrace_symbols directio fchmod fclose\ + fcntl fdatasync fgetc fgets fopen fwrite getgid\ + getrusage getuid hstrerror mprotect pstat_getdynamic\ + pthread_self pthread_yield random sched_yield select setgid setuid\ + sigaction snprintf stat sysconf vsnprintf yield +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + +for ac_func in gettimeofday localtime time strftime +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# AIX 4.3 will link applications with calls to clock_gettime, but the +# calls always fail. +case "$host_os" in +aix4.3.*) + ;; +*) + for ac_func in clock_gettime +do : + ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" +if test "x$ac_cv_func_clock_gettime" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_CLOCK_GETTIME 1 +_ACEOF + +fi +done +;; +esac + +# clock_gettime -- monotonic clocks. +# Check to see if we can get a monotonic clock. We actually try and +# run the program if possible, because we don't trust the #define's +# existence to mean the clock really exists. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime monotonic clock" >&5 +$as_echo_n "checking for clock_gettime monotonic clock... " >&6; } +if test "${db_cv_clock_monotonic+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +if test "$cross_compiling" = yes; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + +struct timespec t; +clock_gettime(CLOCK_MONOTONIC, &t); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_clock_monotonic=yes +else + db_cv_clock_monotonic=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +main() { + struct timespec t; + return (clock_gettime(CLOCK_MONOTONIC, &t) != 0); +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + db_cv_clock_monotonic=yes +else + db_cv_clock_monotonic=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_clock_monotonic" >&5 +$as_echo "$db_cv_clock_monotonic" >&6; } +if test "$db_cv_clock_monotonic" = "yes"; then + $as_echo "#define HAVE_CLOCK_MONOTONIC 1" >>confdefs.h + + +fi + +# ctime_r -- +# +# There are two versions of ctime_r, one of which takes a buffer length as a +# third argument, and one which only takes two arguments. (There is also a +# difference in return values and the type of the 3rd argument, but we handle +# those problems in the code itself.) +for ac_func in ctime_r +do : + ac_fn_c_check_func "$LINENO" "ctime_r" "ac_cv_func_ctime_r" +if test "x$ac_cv_func_ctime_r" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_CTIME_R 1 +_ACEOF + +fi +done + +if test "$ac_cv_func_ctime_r" = "yes"; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for 2 or 3 argument version of ctime_r" >&5 +$as_echo_n "checking for 2 or 3 argument version of ctime_r... " >&6; } +if test "${db_cv_ctime_r_3arg+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +int +main () +{ + + ctime_r(NULL, NULL, 100); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_ctime_r_3arg="3-argument" +else + db_cv_ctime_r_3arg="2-argument" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_ctime_r_3arg" >&5 +$as_echo "$db_cv_ctime_r_3arg" >&6; } +fi +if test "$db_cv_ctime_r_3arg" = "3-argument"; then + $as_echo "#define HAVE_CTIME_R_3ARG 1" >>confdefs.h + + +fi + + +# Ftruncate. +# We've run into a problem with ftruncate on Alpha/Tru64, the issue is that +# after a truncate the last page of the file mmaps as all zeros. So just don't +# use ftruncate. +case "$host_os" in +osf*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ftruncate ignored on $host_os-$host_vendor." >&5 +$as_echo "$as_me: WARNING: ftruncate ignored on $host_os-$host_vendor." >&2;};; +*) + for ac_func in ftruncate +do : + ac_fn_c_check_func "$LINENO" "ftruncate" "ac_cv_func_ftruncate" +if test "x$ac_cv_func_ftruncate" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FTRUNCATE 1 +_ACEOF + +fi +done +;; +esac + +# Pread/pwrite. +# HP-UX has pread/pwrite, but it doesn't work with largefile support. +# NCR's version of System V R 4.3 has pread/pwrite symbols, but no support. +case "$host_os-$host_vendor" in +hpux*|sysv4.3*-ncr) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pread/pwrite interfaces ignored on $host_os-$host_vendor." >&5 +$as_echo "$as_me: WARNING: pread/pwrite interfaces ignored on $host_os-$host_vendor." >&2;};; +*) + for ac_func in pread pwrite +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done +;; +esac + +# Check for getaddrinfo; do the test explicitly instead of using AC_CHECK_FUNCS +# because isn't a standard include file. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo" >&5 +$as_echo_n "checking for getaddrinfo... " >&6; } +if test "${db_cv_getaddrinfo+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int +main () +{ + + getaddrinfo(0, 0, 0, 0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_getaddrinfo=yes +else + db_cv_getaddrinfo=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_getaddrinfo" >&5 +$as_echo "$db_cv_getaddrinfo" >&6; } +if test "$db_cv_getaddrinfo" = "yes"; then + $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h + + +fi + +# Check for the fcntl F_SETFD flag to deny child process access to file +# descriptors. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fcntl/F_SETFD" >&5 +$as_echo_n "checking for fcntl/F_SETFD... " >&6; } +if test "${db_cv_fcntl_f_setfd+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int +main () +{ + + fcntl(1, F_SETFD, 1); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_fcntl_f_setfd=yes +else + db_cv_fcntl_f_setfd=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_fcntl_f_setfd" >&5 +$as_echo "$db_cv_fcntl_f_setfd" >&6; } +if test "$db_cv_fcntl_f_setfd" = "yes"; then + $as_echo "#define HAVE_FCNTL_F_SETFD 1" >>confdefs.h + + +fi + +# A/UX has a broken getopt(3). +case "$host_os" in +aux*) case " $LIBOBJS " in + *" getopt.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS getopt.$ac_objext" + ;; +esac +;; +esac + +# Linux has a broken O_DIRECT flag, but you can't detect it at configure time. +# Linux and SGI require buffer alignment we may not match, otherwise writes +# will fail. Default to not using the O_DIRECT flag. +if test "$db_cv_o_direct" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for open/O_DIRECT" >&5 +$as_echo_n "checking for open/O_DIRECT... " >&6; } +if test "${db_cv_open_o_direct+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include +int +main () +{ + + open("a", O_RDONLY | O_DIRECT, 0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_open_o_direct=yes +else + db_cv_open_o_direct=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_open_o_direct" >&5 +$as_echo "$db_cv_open_o_direct" >&6; } + if test \ + "$db_cv_o_direct" = "yes" -a "$db_cv_open_o_direct" = "yes"; then + $as_echo "#define HAVE_O_DIRECT 1" >>confdefs.h + + + fi +fi + +# Check for largefile support. +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if test "${ac_cv_sys_largefile_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if test "${ac_cv_sys_file_offset_bits+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if test "${ac_cv_sys_large_files+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi +fi + + +# Figure out how to create shared regions. +# +# First, we look for mmap. +# +# BSD/OS has mlock(2), but it doesn't work until the 4.1 release. +# +# Nextstep (version 3.3) apparently supports mmap(2) (the mmap symbol +# is defined in the C library) but does not support munmap(2). Don't +# try to use mmap if we can't find munmap. +# +# Ultrix has mmap(2), but it doesn't work. +mmap_ok=no +case "$host_os" in +bsdi3*|bsdi4.0) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: mlock(2) interface ignored on $host_os-$host_vendor." >&5 +$as_echo "$as_me: WARNING: mlock(2) interface ignored on $host_os-$host_vendor." >&2;} + mmap_ok=yes + for ac_func in mmap munmap +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + mmap_ok=no +fi +done +;; +ultrix*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: mmap(2) interface ignored on $host_os-$host_vendor." >&5 +$as_echo "$as_me: WARNING: mmap(2) interface ignored on $host_os-$host_vendor." >&2;};; +*) + mmap_ok=yes + for ac_func in mlock munlock +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + for ac_func in mmap munmap +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + mmap_ok=no +fi +done +;; +esac + +# Second, we look for shmget. +# +# SunOS has the shmget(2) interfaces, but there appears to be a missing +# #include file, so we ignore them. +shmget_ok=no +case "$host_os" in +sunos*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: shmget(2) interface ignored on $host_os-$host_vendor." >&5 +$as_echo "$as_me: WARNING: shmget(2) interface ignored on $host_os-$host_vendor." >&2;};; +*) + shmget_ok=yes + for ac_func in shmget +do : + ac_fn_c_check_func "$LINENO" "shmget" "ac_cv_func_shmget" +if test "x$ac_cv_func_shmget" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SHMGET 1 +_ACEOF + +else + shmget_ok=no +fi +done + + + # Check for shmctl to lock down shared memory segments. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmctl" >&5 +$as_echo_n "checking for shmctl... " >&6; } +if test "${db_cv_shmctl_shm_lock+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include +int +main () +{ + + shmctl(0, SHM_LOCK, NULL); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + db_cv_shmctl_shm_lock=yes +else + db_cv_shmctl_shm_lock=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_shmctl_shm_lock" >&5 +$as_echo "$db_cv_shmctl_shm_lock" >&6; } + if test "$db_cv_shmctl_shm_lock" = "yes"; then + $as_echo "#define HAVE_SHMCTL_SHM_LOCK 1" >>confdefs.h + + + fi;; +esac + +# We require either mmap/munmap(2) or shmget(2). +if test "$mmap_ok" = "no" -a "$shmget_ok" = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Neither mmap/munmap(2) or shmget(2) library functions." >&5 +$as_echo "$as_me: WARNING: Neither mmap/munmap(2) or shmget(2) library functions." >&2;} +fi + +# Optional RPC client/server. +if test "$db_cv_rpc" = "yes"; then + + $as_echo "#define HAVE_RPC 1" >>confdefs.h + + + + # We use the target's rpcgen utility because it may be architecture + # specific, for example, 32- or 64-bit specific. + XDR_FILE=$srcdir/../rpc_server/db_server.x + + # Prefer the -C option to rpcgen which generates ANSI C-conformant + # code. + RPCGEN="rpcgen -C" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking \"$RPCGEN\" build of db_server.h" >&5 +$as_echo_n "checking \"$RPCGEN\" build of db_server.h... " >&6; } + $RPCGEN -h $XDR_FILE > db_server.h 2>/dev/null + if test $? -ne 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + # Try rpcgen without the -C option. + RPCGEN="rpcgen" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking \"$RPCGEN\" build of db_server.h" >&5 +$as_echo_n "checking \"$RPCGEN\" build of db_server.h... " >&6; } + $RPCGEN -h $XDR_FILE > db_server.h 2>/dev/null + if test $? -ne 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error "Unable to build RPC support: $RPCGEN failed." "$LINENO" 5 + fi + fi + + # Some rpcgen programs generate a set of client stubs called something + # like __db_env_create_4003 and functions on the server to handle the + # request called something like __db_env_create_4003_svc. Others + # expect client and server stubs to both be called __db_env_create_4003. + # + # We have to generate code in whichever format rpcgen expects, and the + # only reliable way to do that is to check what is in the db_server.h + # file we just created. + if grep "env_create_[0-9]*_svc" db_server.h >/dev/null 2>&1 ; then + sed 's/__SVCSUFFIX__/_svc/' \ + < $srcdir/../rpc_server/c/gen_db_server.c > gen_db_server.c + else + sed 's/__SVCSUFFIX__//' \ + < $srcdir/../rpc_server/c/gen_db_server.c > gen_db_server.c + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + $RPCGEN -l $XDR_FILE | + sed -e 's/^#include.*db_server.h.*/#include "db_server.h"/' \ + -e '1,/^#include/s/^#include/#include "db_config.h"\ +&/' > db_server_clnt.c + + $RPCGEN -s tcp $XDR_FILE | + sed -e 's/^#include.*db_server.h.*/#include "db_server.h"/' \ + -e 's/^main *()/__dbsrv_main()/' \ + -e 's/^main *(.*argc.*argv.*)/__dbsrv_main(int argc, char *argv)/' \ + -e '/^db_rpc_serverprog/,/^}/{' \ + -e 's/return;//' \ + -e 's/^}/__dbsrv_timeout(0);}/' \ + -e '}' \ + -e '1,/^#include/s/^#include/#include "db_config.h"\ +&/' > db_server_svc.c + + $RPCGEN -c $XDR_FILE | + sed -e 's/^#include.*db_server.h.*/#include "db_server.h"/' \ + -e '1,/^#include/s/^#include/#include "db_config.h"\ +&/' > db_server_xdr.c + + RPC_SERVER_H=db_server.h + RPC_CLIENT_OBJS="\$(RPC_CLIENT_OBJS)" + ADDITIONAL_PROGS="berkeley_db_svc $ADDITIONAL_PROGS" + + # Solaris and HPUX need the nsl library to build RPC. + ac_fn_c_check_func "$LINENO" "svc_run" "ac_cv_func_svc_run" +if test "x$ac_cv_func_svc_run" = x""yes; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lnsl" >&5 +$as_echo_n "checking for main in -lnsl... " >&6; } +if test "${ac_cv_lib_nsl_main+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_main=yes +else + ac_cv_lib_nsl_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_main" >&5 +$as_echo "$ac_cv_lib_nsl_main" >&6; } +if test "x$ac_cv_lib_nsl_main" = x""yes; then : + LIBSO_LIBS="$LIBSO_LIBS -lnsl" +fi +ac_cv_lib_nsl=ac_cv_lib_nsl_main + +fi + + +fi + +# Optional Tcl support. +if test "$db_cv_tcl" = "yes"; then + + if test "$enable_shared" != "yes"; then + as_fn_error "Tcl requires shared libraries" "$LINENO" 5 + fi + + + if test "${ac_cv_c_tclconfig+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + + + # First check to see if --with-tclconfig was specified. + if test "${with_tclconfig}" != no; then + if test -f "${with_tclconfig}/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` + else + as_fn_error "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5 + fi + fi + + # check in a few common install locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d /usr/local/lib 2>/dev/null` ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i; pwd)` + break + fi + done + fi + + +fi + + + if test x"${ac_cv_c_tclconfig}" = x ; then + TCL_BIN_DIR="# no Tcl configs found" + as_fn_error "can't find Tcl configuration definitions" "$LINENO" 5 + else + TCL_BIN_DIR=${ac_cv_c_tclconfig} + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5 +$as_echo_n "checking for existence of $TCL_BIN_DIR/tclConfig.sh... " >&6; } + + if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5 +$as_echo "loading" >&6; } + . $TCL_BIN_DIR/tclConfig.sh + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: file not found" >&5 +$as_echo "file not found" >&6; } + fi + + # DB requires at least version 8.4. + if test ${TCL_MAJOR_VERSION} -lt 8 \ + -o ${TCL_MAJOR_VERSION} -eq 8 -a ${TCL_MINOR_VERSION} -lt 4; then + as_fn_error "Berkeley DB requires Tcl version 8.4 or better." "$LINENO" 5 + fi + + # The eval is required to do substitution (for example, the TCL_DBGX + # substitution in the TCL_LIB_FILE variable. + eval "TCL_INCLUDE_SPEC=\"${TCL_INCLUDE_SPEC}\"" + eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" + eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" + eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" + + # + # If the DB Tcl library isn't loaded with the Tcl spec and library + # flags on AIX, the resulting libdb_tcl-X.Y.so.0 will drop core at + # load time. [#4843] Furthermore, with Tcl 8.3, the link flags + # given by the Tcl spec are insufficient for our use. [#5779],[#17109] + # + case "$host_os" in + aix*) + LIBTSO_LIBS="$LIBTSO_LIBS $TCL_LIB_SPEC $TCL_LIB_FLAG" + LIBTSO_LIBS="$LIBTSO_LIBS -L$TCL_EXEC_PREFIX/lib -ltcl$TCL_VERSION";; + esac + + + + + + + TCL_TCLSH="${TCL_PREFIX}/bin/tclsh${TCL_VERSION}" + + + INSTALL_LIBS="${INSTALL_LIBS} \$(libtso_target)" + +fi + +# Optional sequence code. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit integral type support for sequences" >&5 +$as_echo_n "checking for 64-bit integral type support for sequences... " >&6; } + + db_cv_build_sequence="yes" + + # Have to have found 64-bit types to support sequences. If we don't + # find the native types, we try and create our own. + if test "$ac_cv_type_int64_t" = "no" -a -z "$int64_decl"; then + db_cv_build_sequence="no" + fi + if test "$ac_cv_type_uint64_t" = "no" -a -z "$u_int64_decl"; then + db_cv_build_sequence="no" + fi + + # Figure out what type is the right size, and set the format. + + + db_cv_seq_type="no" + if test "$db_cv_build_sequence" = "yes" -a\ + "$ac_cv_sizeof_long" -eq "8"; then + db_cv_seq_type="long" + db_cv_seq_fmt='"%ld"' + db_cv_seq_ufmt='"%lu"' + INT64_FMT='#define INT64_FMT "%ld"' + UINT64_FMT='#define UINT64_FMT "%lu"' + else if test "$db_cv_build_sequence" = "yes" -a\ + "$ac_cv_sizeof_long_long" -eq "8"; then + db_cv_seq_type="long long" + db_cv_seq_fmt='"%lld"' + db_cv_seq_ufmt='"%llu"' + INT64_FMT='#define INT64_FMT "%lld"' + UINT64_FMT='#define UINT64_FMT "%llu"' + else + db_cv_build_sequence="no" + fi + fi + + # Test to see if we can declare variables of the appropriate size + # and format them. If we're cross-compiling, all we get is a link + # test, which won't test for the appropriate printf format strings. + if test "$db_cv_build_sequence" = "yes"; then + if test "$cross_compiling" = yes; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + $db_cv_seq_type l; + unsigned $db_cv_seq_type u; + char buf[100]; + + buf[0] = 'a'; + l = 9223372036854775807LL; + (void)snprintf(buf, sizeof(buf), $db_cv_seq_fmt, l); + if (strcmp(buf, "9223372036854775807")) + return (1); + u = 18446744073709551615ULL; + (void)snprintf(buf, sizeof(buf), $db_cv_seq_ufmt, u); + if (strcmp(buf, "18446744073709551615")) + return (1); + return (0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +else + db_cv_build_sequence="no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + main() { + $db_cv_seq_type l; + unsigned $db_cv_seq_type u; + char buf[100]; + + buf[0] = 'a'; + l = 9223372036854775807LL; + (void)snprintf(buf, sizeof(buf), $db_cv_seq_fmt, l); + if (strcmp(buf, "9223372036854775807")) + return (1); + u = 18446744073709551615ULL; + (void)snprintf(buf, sizeof(buf), $db_cv_seq_ufmt, u); + if (strcmp(buf, "18446744073709551615")) + return (1); + return (0); + } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + db_cv_build_sequence="no" +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi + if test "$db_cv_build_sequence" = "yes"; then + + db_seq_decl="typedef int64_t db_seq_t;"; + + $as_echo "#define HAVE_64BIT_TYPES 1" >>confdefs.h + + + else + # It still has to compile, but it won't run. + db_seq_decl="typedef int db_seq_t;"; + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_build_sequence" >&5 +$as_echo "$db_cv_build_sequence" >&6; } + + +# Optional DB 1.85 compatibility API. +if test "$db_cv_compat185" = "yes"; then + ADDITIONAL_INCS="db_185.h $ADDITIONAL_INCS" + + ADDITIONAL_OBJS="db185${o} $ADDITIONAL_OBJS" +fi + +# Optional utilities. +if test "$db_cv_dump185" = "yes"; then + ADDITIONAL_PROGS="db_dump185 $ADDITIONAL_PROGS" +fi + +# You can disable pieces of functionality to save space. +# +# Btree is always configured: it is the standard method, and Hash off-page +# duplicates require it. +ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(BTREE_OBJS)" + +# Compression can be disabled. +if test "$db_cv_build_compression" = "yes"; then + $as_echo "#define HAVE_COMPRESSION 1" >>confdefs.h + + +fi + +# Partitioning can be disabled. +if test "$db_cv_build_partition" = "yes"; then + $as_echo "#define HAVE_PARTITION 1" >>confdefs.h + + +fi + +# Hash can be disabled. +if test "$db_cv_build_hash" = "yes"; then + $as_echo "#define HAVE_HASH 1" >>confdefs.h + + + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HASH_OBJS)" + if test "$db_cv_build_verify" = "yes"; then + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HASH_VRFY_OBJS)" + fi +else + ADDITIONAL_OBJS="$ADDITIONAL_OBJS hash_stub${o}" +fi + +# Queue can be disabled. +if test "$db_cv_build_queue" = "yes"; then + $as_echo "#define HAVE_QUEUE 1" >>confdefs.h + + + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(QUEUE_OBJS)" + if test "$db_cv_build_verify" = "yes"; then + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(QUEUE_VRFY_OBJS)" + fi +else + ADDITIONAL_OBJS="$ADDITIONAL_OBJS qam_stub${o}" +fi + +# Replication can be disabled. +if test "$db_cv_build_replication" = "yes"; then + $as_echo "#define HAVE_REPLICATION 1" >>confdefs.h + + + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(REP_OBJS)" + + # If we're building replication and detected POSIX threads, build the + # replication manager. + + + if test "$ac_cv_header_pthread_h" = yes; then + $as_echo "#define HAVE_REPLICATION_THREADS 1" >>confdefs.h + + + # Solaris requires the socket and nsl libraries to build the + # replication manager. Don't add nsl regardless of the OS, + # it causes RPC to fail on AIX 4.3.3. + case "$host_os" in + solaris*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lnsl" >&5 +$as_echo_n "checking for main in -lnsl... " >&6; } +if test "${ac_cv_lib_nsl_main+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_main=yes +else + ac_cv_lib_nsl_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_main" >&5 +$as_echo "$ac_cv_lib_nsl_main" >&6; } +if test "x$ac_cv_lib_nsl_main" = x""yes; then : + LIBSO_LIBS="$LIBSO_LIBS -lnsl" +fi +ac_cv_lib_nsl=ac_cv_lib_nsl_main + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsocket" >&5 +$as_echo_n "checking for main in -lsocket... " >&6; } +if test "${ac_cv_lib_socket_main+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_main=yes +else + ac_cv_lib_socket_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_main" >&5 +$as_echo "$ac_cv_lib_socket_main" >&6; } +if test "x$ac_cv_lib_socket_main" = x""yes; then : + LIBSO_LIBS="$LIBSO_LIBS -lsocket" +fi +ac_cv_lib_socket=ac_cv_lib_socket_main +;; + esac + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(REPMGR_OBJS)" + else + ADDITIONAL_OBJS="$ADDITIONAL_OBJS repmgr_stub${o}" + fi +else + ADDITIONAL_OBJS="$ADDITIONAL_OBJS rep_stub${o} repmgr_stub${o}" +fi + +# The statistics code can be disabled. +if test "$db_cv_build_statistics" = "yes"; then + $as_echo "#define HAVE_STATISTICS 1" >>confdefs.h + + +fi + +# The verification code can be disabled. +if test "$db_cv_build_verify" = "yes"; then + $as_echo "#define HAVE_VERIFY 1" >>confdefs.h + + + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(BTREE_VRFY_OBJS)" +else + ADDITIONAL_OBJS="$ADDITIONAL_OBJS db_vrfy_stub${o}" +fi + +# The crypto code can be disabled. +if test -d "$srcdir/../crypto" -a "$db_cv_build_cryptography" = "yes"; then + $as_echo "#define HAVE_CRYPTO 1" >>confdefs.h + + + + CRYPTO_OBJS="\$(CRYPTO_OBJS)" +else + CRYPTO_OBJS="crypto_stub${o}" +fi + +# The mutex code can be disabled, and if there aren't any mutexes, then there's +# no reason to include the locking code. +if test "$db_cv_build_mutexsupport" = "yes"; then + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(LOCK_OBJS) \$(MUTEX_OBJS)" +else + ADDITIONAL_OBJS="$ADDITIONAL_OBJS lock_stub${o} mut_stub${o}" +fi + +# If DIAGNOSTIC is defined, include the log print routines in the library +# itself, various diagnostic modes use them. +if test "$db_cv_diagnostic" = "yes"; then + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(PRINT_OBJS)" +fi + +# If building for QNX, we need additional OS files. +if test "$qnx_build" = "yes"; then + ADDITIONAL_OBJS="$ADDITIONAL_OBJS os_qnx_fsync${o} os_qnx_open${o}" +fi + +# We need to add the additional object files into the Makefile with the correct +# suffix. We can't use $LTLIBOBJS itself, because that variable has $U encoded +# in it for automake, and that's not what we want. See SR #7227 for additional +# information. +# +# XXX: I'm not sure this is correct. +REPLACEMENT_OBJS=`echo "$LIBOBJS" | + sed "s,\.[^.]* ,$o ,g;s,\.[^.]*$,$o,"` + +# This is necessary so that .o files in LIBOBJS are also built via +# the ANSI2KNR-filtering rules. +LIBOBJS=`echo "$LIBOBJS" | + sed 's,\.[^.]* ,$U&,g;s,\.[^.]*$,$U&,'` +LTLIBOBJS=`echo "$LIBOBJS" | + sed 's,\.[^.]* ,.lo ,g;s,\.[^.]*$,.lo,'` + + +# Initial output file list. +CREATE_LIST="Makefile + db_cxx.h:$srcdir/../dbinc/db_cxx.in + db_int.h:$srcdir/../dbinc/db_int.in + clib_port.h:$srcdir/../dist/clib_port.in + include.tcl:$srcdir/../test/include.tcl" + +# Create the db.h file from a source file, a list of global function +# prototypes, and, if configured for unique names, a list of #defines +# to do DB_VERSION_UNIQUE_NAME substitution. +if test "$db_cv_uniquename" = "yes"; then + CREATE_LIST="$CREATE_LIST + db.h:$srcdir/../dbinc/db.in:$srcdir/../dbinc_auto/api_flags.in:$srcdir/../dbinc_auto/ext_def.in:$srcdir/../dbinc_auto/ext_prot.in" +else + CREATE_LIST="$CREATE_LIST + db.h:$srcdir/../dbinc/db.in:$srcdir/../dbinc_auto/api_flags.in:$srcdir/../dbinc_auto/ext_prot.in" +fi + +# If configured for unique names, create the db_int_uext.h file (which +# does the DB_VERSION_UNIQUE_NAME substitution), which is included by +# the db_int.h file. +if test "$db_cv_uniquename" = "yes"; then + CREATE_LIST="$CREATE_LIST + db_int_def.h:$srcdir/../dbinc_auto/int_def.in" + db_int_def='#include "db_int_def.h"' +fi + +# Create the db_185.h and db185_int.h files from source files, a list of +# global function prototypes, and, if configured for unique names, a list +# of #defines to do DB_VERSION_UNIQUE_NAME substitution. +if test "$db_cv_compat185" = "yes"; then + if test "$db_cv_uniquename" = "yes"; then + CREATE_LIST="$CREATE_LIST + db_185.h:$srcdir/../dbinc/db_185.in:$srcdir/../dbinc_auto/ext_185_def.in:$srcdir/../dbinc_auto/ext_185_prot.in + db185_int.h:$srcdir/../db185/db185_int.in:$srcdir/../dbinc_auto/ext_185_def.in:$srcdir/../dbinc_auto/ext_185_prot.in" + else + CREATE_LIST="$CREATE_LIST + db_185.h:$srcdir/../dbinc/db_185.in:$srcdir/../dbinc_auto/ext_185_prot.in + db185_int.h:$srcdir/../db185/db185_int.in:$srcdir/../dbinc_auto/ext_185_prot.in" + fi +fi + +if test "$db_cv_stl" = "yes"; then + CREATE_LIST="$CREATE_LIST + dbstl_common.h:$srcdir/../stl/dbstl_common.in" +fi + +ac_config_files="$ac_config_files $CREATE_LIST" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by Berkeley DB $as_me 4.8.30, which was +generated by GNU Autoconf 2.65. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +Berkeley DB config.status 4.8.30 +configured by $0, generated by GNU Autoconf 2.65, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2009 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' +macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' +enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' +pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' +host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' +host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' +host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' +build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' +build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' +build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' +SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' +Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' +GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' +EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' +FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' +LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' +NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' +LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' +ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' +exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' +lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' +reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' +AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' +STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' +RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' +CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' +compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' +GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' +objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' +SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' +ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' +need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' +LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' +OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' +libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' +module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' +fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' +need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' +version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' +runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' +libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' +soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' +finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' +old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' +striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "X$compiler_lib_search_dirs" | $Xsed -e "$delay_single_quote_subst"`' +predep_objects='`$ECHO "X$predep_objects" | $Xsed -e "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "X$postdep_objects" | $Xsed -e "$delay_single_quote_subst"`' +predeps='`$ECHO "X$predeps" | $Xsed -e "$delay_single_quote_subst"`' +postdeps='`$ECHO "X$postdeps" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "X$compiler_lib_search_path" | $Xsed -e "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "X$LD_CXX" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "X$old_archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "X$compiler_CXX" | $Xsed -e "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "X$GCC_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "X$lt_prog_compiler_no_builtin_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "X$lt_prog_compiler_wl_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "X$lt_prog_compiler_pic_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "X$lt_prog_compiler_static_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "X$lt_cv_prog_compiler_c_o_CXX" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "X$archive_cmds_need_lc_CXX" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "X$enable_shared_with_static_runtimes_CXX" | $Xsed -e "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "X$export_dynamic_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "X$whole_archive_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "X$compiler_needs_object_CXX" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "X$old_archive_from_new_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "X$old_archive_from_expsyms_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "X$archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "X$archive_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "X$module_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "X$module_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "X$with_gnu_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "X$allow_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "X$no_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "X$hardcode_libdir_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld_CXX='`$ECHO "X$hardcode_libdir_flag_spec_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "X$hardcode_libdir_separator_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "X$hardcode_direct_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "X$hardcode_direct_absolute_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "X$hardcode_minus_L_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "X$hardcode_shlibpath_var_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "X$hardcode_automatic_CXX" | $Xsed -e "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "X$inherit_rpath_CXX" | $Xsed -e "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "X$link_all_deplibs_CXX" | $Xsed -e "$delay_single_quote_subst"`' +fix_srcfile_path_CXX='`$ECHO "X$fix_srcfile_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "X$always_export_symbols_CXX" | $Xsed -e "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "X$export_symbols_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "X$exclude_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "X$include_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "X$prelink_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "X$file_list_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "X$hardcode_action_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "X$compiler_lib_search_dirs_CXX" | $Xsed -e "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "X$predep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "X$postdep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "X$predeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "X$postdeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "X$compiler_lib_search_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# Quote evaled strings. +for var in SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +AR \ +AR_FLAGS \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +SHELL \ +ECHO \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_wl \ +lt_prog_compiler_pic \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +fix_srcfile_path \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_flag_spec_ld_CXX \ +hardcode_libdir_separator_CXX \ +fix_srcfile_path_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX; do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Fix-up fallback echo if it was mangled by the above quoting rules. +case \$lt_ECHO in +*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` + ;; +esac + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "db_config.h") CONFIG_HEADERS="$CONFIG_HEADERS db_config.h:config.hin" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "$CREATE_LIST") CONFIG_FILES="$CONFIG_FILES $CREATE_LIST" ;; + + *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || as_fn_error "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then + break + elif $ac_last_try; then + as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$tmp/config.h" "$ac_file" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error "could not create -" "$LINENO" 5 + fi + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that does not interpret backslashes. +ECHO=$lt_ECHO + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $* )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[^=]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$@"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1+=\$2" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1=\$$1\$2" +} + +_LT_EOF + ;; + esac + + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit $? +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/src/libs/resiprocate/contrib/db/dist/configure.ac b/src/libs/resiprocate/contrib/db/dist/configure.ac new file mode 100644 index 00000000..4a997797 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/configure.ac @@ -0,0 +1,902 @@ +# $Id$ +# Process this file with autoconf to produce a configure script. + +PACKAGE=db +AC_INIT(Berkeley DB, __EDIT_DB_VERSION__, + [Oracle Technology Network Berkeley DB forum], + db-__EDIT_DB_VERSION__) +AC_CONFIG_SRCDIR([../db/db.c]) +AC_CONFIG_HEADERS([db_config.h:config.hin]) + +AC_CONFIG_MACRO_DIR([aclocal]) + +# Configure setup. +AC_CANONICAL_HOST() +AC_ARG_PROGRAM() + +# Don't build in the top-level or dist directories. +AC_MSG_CHECKING(if building in the top-level or dist directories) +if [ test -d db_archive -o -f configure.ac ] ; then + AC_MSG_RESULT(yes) + AC_MSG_ERROR([\ +Berkeley DB should not be built in the top-level or "dist" directories. \ +Change directory to the build_unix directory and run ../dist/configure \ +from there.]) + +fi +AC_MSG_RESULT(no) + +# Substitution variables. +AC_SUBST(ADDITIONAL_INCS) +AC_SUBST(ADDITIONAL_LANG) +AC_SUBST(ADDITIONAL_OBJS) +AC_SUBST(ADDITIONAL_PROGS) +AC_SUBST(BUILD_TARGET) +AC_SUBST(CFLAGS) +AC_SUBST(CONFIGURATION_ARGS) +AC_SUBST(CONFIGURATION_PATH) +AC_SUBST(CPPFLAGS) +AC_SUBST(CRYPTO_OBJS) +AC_SUBST(CXX) +AC_SUBST(CXXFLAGS) +AC_SUBST(DB_CONST) +AC_SUBST(DB_PROTO1) +AC_SUBST(DB_PROTO2) +AC_SUBST(DEFAULT_LIB) +AC_SUBST(DEFAULT_LIB_CXX) +AC_SUBST(DEFAULT_LIB_STL) +AC_SUBST(INSTALLER) +AC_SUBST(INSTALL_LIBS) +AC_SUBST(INSTALL_TARGET) +AC_SUBST(JAR) +AC_SUBST(JAVACFLAGS) +AC_SUBST(LDFLAGS) +AC_SUBST(LIBCSO_LIBS) +AC_SUBST(LIBJSO_LIBS) +AC_SUBST(LIBS) +AC_SUBST(LIBSO_LIBS) +AC_SUBST(LIBTOOL) +AC_SUBST(LIBTSO_LIBS) +AC_SUBST(LIBTSO_MODSUFFIX) +AC_SUBST(LIBTSO_MODULE) +AC_SUBST(LIBXSO_LIBS) +AC_SUBST(MAKEFILE_CC) +AC_SUBST(MAKEFILE_CCLINK) +AC_SUBST(MAKEFILE_CXX) +AC_SUBST(MAKEFILE_CXXLINK) +AC_SUBST(MAKEFILE_SOLINK) +AC_SUBST(MAKEFILE_XSOLINK) +AC_SUBST(OSDIR) +AC_SUBST(PATH_SEPARATOR) +AC_SUBST(POSTLINK) +AC_SUBST(REPLACEMENT_OBJS) +AC_SUBST(RPC_CLIENT_OBJS) +AC_SUBST(RPC_SERVER_H) +AC_SUBST(SOFLAGS) +AC_SUBST(SWIGCFLAGS) +AC_SUBST(TEST_LIBS) +AC_SUBST(db_int_def) +AC_SUBST(o) + +# The Windows public header has two extra symbols we need to remove. +AC_SUBST(platform_header) +AC_SUBST(platform_footer) + +# Set the default installation location. +AC_PREFIX_DEFAULT(/usr/local/BerkeleyDB.__EDIT_DB_VERSION_MAJOR__.__EDIT_DB_VERSION_MINOR__) + +# Configure the version information. +AC_SUBST(DB_VERSION_MAJOR) +DB_VERSION_MAJOR="__EDIT_DB_VERSION_MAJOR__" +AC_SUBST(DB_VERSION_MINOR) +DB_VERSION_MINOR="__EDIT_DB_VERSION_MINOR__" +AC_SUBST(DB_VERSION_PATCH) +DB_VERSION_PATCH="__EDIT_DB_VERSION_PATCH__" +AC_SUBST(DB_VERSION_STRING) +DB_VERSION_STRING='"__EDIT_DB_VERSION_STRING__"' +AC_SUBST(DB_VERSION_UNIQUE_NAME) + +# Process all options before using them. +AM_OPTIONS_SET + +# Set some #defines based on configuration options. +if test "$db_cv_diagnostic" = "yes"; then + AC_DEFINE(DIAGNOSTIC) + AH_TEMPLATE(DIAGNOSTIC, + [Define to 1 if you want a version with run-time diagnostic checking.]) +fi +if test "$db_cv_debug_rop" = "yes"; then + AC_DEFINE(DEBUG_ROP) + AH_TEMPLATE(DEBUG_ROP, + [Define to 1 if you want a version that logs read operations.]) +fi +if test "$db_cv_debug_wop" = "yes"; then + AC_DEFINE(DEBUG_WOP) + AH_TEMPLATE(DEBUG_WOP, + [Define to 1 if you want a version that logs write operations.]) +fi +if test "$db_cv_umrw" = "yes"; then + AC_DEFINE(UMRW) + AH_TEMPLATE(UMRW, + [Define to 1 to mask harmless uninitialized memory read/writes.]) + +fi +if test "$db_cv_test" = "yes"; then + AC_DEFINE(CONFIG_TEST) + AH_TEMPLATE(CONFIG_TEST, + [Define to 1 if you want to build a version for running the test suite.]) +fi + +AH_TEMPLATE(HAVE_UPGRADE_SUPPORT, + [Define to 1 if port includes historic database upgrade support.]) +AC_DEFINE(HAVE_UPGRADE_SUPPORT) + +# Check for programs used in building and installation. +AM_PROGRAMS_SET +AC_PROG_INSTALL + +BUILD_TARGET="library_build" +INSTALL_TARGET="library_install" + +# Respect the environment LIBS settings +LIBSO_LIBS="$LIBS" + +# This is where we handle stuff that autoconf can't handle: compiler, +# preprocessor and load flags, libraries that the standard tests don't +# look for. +# +# There are additional libraries we need for some compiler/architecture +# combinations. +# +# Some architectures require DB to be compiled with special flags and/or +# libraries for threaded applications +# +# The makefile CC may be different than the CC used in config testing, +# because the makefile CC may be set to use $(LIBTOOL). +# +# Don't override anything if it's already set from the environment. +optimize_debug="-O" +case "$host_os" in +aix4.3.*|aix[[56]]*) + case "$host_os" in + aix4.3.*) + CPPFLAGS="$CPPFLAGS -D_LINUX_SOURCE_COMPAT";; + esac + # IBM's XLC compilers (at least versions 7/8/9) generate incorrect code + # when ordinary optimization is enabled because they make strong + # assumptions about the types held at each memory location, and some + # Berkeley DB code violates those assumptions. [#16141] + optimize_debug="-O2 -qalias=noansi" + CC=${CC-"xlc_r"} + CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" + LDFLAGS="$LDFLAGS -Wl,-brtl";; +bsdi3*) CC=${CC-"shlicc2"} + LIBSO_LIBS="$LIBSO_LIBS -lipc";; +cygwin*) + CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";; +freebsd*) + CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" + LDFLAGS="$LDFLAGS -pthread";; +gnu*|k*bsd*-gnu|linux*) + CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";; +hpux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT";; +irix*) optimize_debug="-O2" + CPPFLAGS="$CPPFLAGS -D_SGI_MP_SOURCE";; +mpeix*) CPPFLAGS="$CPPFLAGS -D_POSIX_SOURCE -D_SOCKET_SOURCE" + LIBSO_LIBS="$LIBSO_LIBS -lsocket -lsvipc";; +osf*) CPPFLAGS="$CPPFLAGS -pthread";; +*qnx*) qnx_build="yes" + AC_DEFINE(HAVE_QNX) + AH_TEMPLATE(HAVE_QNX, [Define to 1 if building on QNX.]);; +solaris*) + CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS ";; +esac + +# If the user wants a debugging environment, change any compiler optimization +# flags to -g. We used to add -g to the -O compiler flags, but compilers are +# good enough at code re-organization that debugging with -O no longer works. +# If you want to compile with a different set of flags, specify CFLAGS in the +# environment before configuring. +if test "$db_cv_debug" = "yes"; then + AC_DEFINE(DEBUG) + AH_TEMPLATE(DEBUG, [Define to 1 if you want a debugging version.]) + + optimize_debug="-g" +fi + +# Set CFLAGS/CXXFLAGS. We MUST set the flags before we call autoconf +# compiler configuration macros, because if we don't, they set CFLAGS +# to no optimization and -g, which isn't what we want. +CFLAGS=${CFLAGS-$optimize_debug} +CXXFLAGS=${CXXFLAGS-"$CFLAGS"} + +# The default compiler is cc (NOT gcc), the default CFLAGS is as specified +# above, NOT what is set by AC_PROG_CC, as it won't set optimization flags +# for any compiler other than gcc. +AC_PROG_CC(cc gcc) + +# We know what compiler we're going to use, now. Set per-compiler flags. +if test "$GCC" = "yes"; then + # Use -O3 if we're using gcc, unless we're doing a small build, in + # which case we use -Os alone. The code size for -O3 is quite a + # bit larger than -O2: a compromise is "-Os -finline-functions", + # it's smaller and explicitly inlining the functions helps Berkeley + # DB. + CFLAGS="$CFLAGS " + if test "$db_cv_smallbuild" = "yes"; then + CFLAGS=`echo "$CFLAGS" | sed 's/-O /-Os /g'` + else + CFLAGS=`echo "$CFLAGS" | sed 's/-O /-O3 /g'` + fi +else + case "$host_os" in + hpux11.0*) ;; + hpux11*) CPPFLAGS="$CPPFLAGS -mt";; + esac +fi + +# Check for "const" and "inline" keywords. +AC_C_CONST +AC_C_INLINE + +# We use prototypes and the keyword "const" in db.h which doesn't include +# db_config.h, so we have to figure out what to do there. +# +# There is an autoconf AC_C_PROTOTYPES macro, but as all it does is define +# db_config.h variables, it doesn't help us. +# +# We don't have much choice, we look at internal autoconf variables. +if test "$ac_cv_c_const" != "yes"; then + DB_CONST="#define const" +fi + +# Clear __P, some other systems use it too. +DB_PROTO1="#undef __P" +if test "$ac_cv_prog_cc_c89" = "no"; then + DB_PROTO2="#define __P(protos) ()" +else + DB_PROTO2="#define __P(protos) protos" +fi + +# Because of shared library building, the ${CC} used for config tests +# may be different than the ${CC} we want to put in the Makefile. +# The latter is known as ${MAKEFILE_CC} in this script. +MAKEFILE_CC="${CC}" +MAKEFILE_CCLINK="${CC}" +MAKEFILE_CXX="nocxx" +MAKEFILE_CXXLINK="nocxx" + +# See if we need the C++ compiler at all. If so, we'd like to find one that +# interoperates with the C compiler we chose. Since we prefered cc over gcc, +# we'll also prefer the vendor's compiler over g++/gcc. If we're wrong, the +# user can set CC and CXX in their environment before running configure. +# +# AC_PROG_CXX sets CXX, but it uses $CXX and $CCC (in that order) as its +# first choices. +if test "$db_cv_cxx" = "yes"; then + if test "$GCC" != "yes"; then + case "$host_os" in + aix*) AC_CHECK_TOOL(CCC, xlC_r) + LIBXSO_LIBS="-lC_r $LIBXSO_LIBS" + LIBSO_LIBS="-lC_r $LIBSO_LIBS";; + hpux*) AC_CHECK_TOOL(CCC, aCC);; + irix*) AC_CHECK_TOOL(CCC, CC);; + osf*) AC_CHECK_TOOL(CCC, cxx) + CXXFLAGS="$CXXFLAGS -D__USE_STD_IOSTREAM" + test -d /usr/include.dtk && + CXXFLAGS="$CXXFLAGS -I/usr/include.dtk";; + solaris*) AC_CHECK_TOOL(CCC, CC);; + esac + fi + AC_PROG_CXX + ###### WORKAROUND: SEE SR #7938 + AC_PROG_CXXCPP + ############################### + AC_CXX_STDHEADERS + MAKEFILE_CXX="${CXX}" + MAKEFILE_CXXLINK="${CXX}" +fi + +# Do some gcc specific configuration. +AC_GCC_CONFIG1 + +# We need the -Kthread/-pthread flag when compiling on SCO/Caldera's UnixWare +# and OpenUNIX releases. We can't make the test until we know which compiler +# we're using. +case "$host_os" in +sysv5UnixWare*|sysv5OpenUNIX8*) + if test "$GCC" == "yes"; then + CPPFLAGS="$CPPFLAGS -pthread" + LDFLAGS="$LDFLAGS -pthread" + else + CPPFLAGS="$CPPFLAGS -Kthread" + LDFLAGS="$LDFLAGS -Kthread" + fi;; +esac + +# Export our compiler preferences for the libtool configuration. +export CC CCC +CCC=CXX + +# Libtool configuration. +AC_PROG_LIBTOOL + +SOFLAGS="-rpath \$(libdir)" + +# Set SOSUFFIX and friends +SOSUFFIX_CONFIG +MODSUFFIX_CONFIG +JMODSUFFIX_CONFIG + +LIBTOOL="./libtool" + +INSTALLER="\$(LIBTOOL) --mode=install cp -p" + +MAKEFILE_CC="\$(LIBTOOL) --mode=compile ${MAKEFILE_CC}" +MAKEFILE_SOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK} -avoid-version" +MAKEFILE_CCLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK}" +MAKEFILE_CXX="\$(LIBTOOL) --mode=compile ${MAKEFILE_CXX}" +MAKEFILE_XSOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK} -avoid-version" +MAKEFILE_CXXLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK}" + + +case "$host_os" in +cygwin* | mingw*) + MAKEFILE_SOLINK="$MAKEFILE_SOLINK -no-undefined" + MAKEFILE_XSOLINK="$MAKEFILE_XSOLINK -no-undefined";; +esac + +case "$host_os" in + darwin*) + LIBTSO_MODULE="" + LIBTSO_MODSUFFIX=".dylib";; + *qnx*) + LIBTSO_MODULE="" + LIBTSO_MODSUFFIX=$MODSUFFIX;; + *) + LIBTSO_MODULE="-module" + LIBTSO_MODSUFFIX=$MODSUFFIX;; +esac + +# C API. +if test "$enable_shared" = "no"; then + DEFAULT_LIB="\$(libdb_version)" + POSTLINK=": " + o=".o" +else + DEFAULT_LIB="\$(libso_target)" + POSTLINK="\$(LIBTOOL) --mode=execute true" + o=".lo" +fi +INSTALL_LIBS="$DEFAULT_LIB" +if test "$enable_static" = "yes"; then + INSTALL_LIBS="$INSTALL_LIBS \$(libdb)" +fi + +# Optional C++ API. +if test "$db_cv_cxx" = "yes"; then + if test "$enable_shared" = "no"; then + DEFAULT_LIB_CXX="\$(libcxx_version)" + fi + if test "$enable_shared" = "yes"; then + DEFAULT_LIB_CXX="\$(libxso_target)" + fi + INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_CXX" + if test "$enable_static" = "yes"; then + INSTALL_LIBS="$INSTALL_LIBS \$(libcxx)" + fi +fi + +# Optional Java API. +if test "$db_cv_java" = "yes"; then + # Java requires shared libraries. + if test "$enable_shared" = "no"; then + AC_MSG_ERROR([Java requires shared libraries]) + fi + + # A classpath that includes . is needed to check for Java + # Since Cygwin uses Windows' javac, we need Windows path separators + case "$host_os" in + cygwin*) CLASSPATH=".;$CLASSPATH";; + *) CLASSPATH=".:$CLASSPATH";; + esac + export CLASSPATH + AC_PROG_JAVAC + AC_PROG_JAR + AC_PROG_JAVA + AC_JNI_INCLUDE_DIR + + AC_MSG_CHECKING(java version) + case "$JAVA" in + *kaffe* ) + JAVA_VERSION=`$JAVA -version 2>&1 | + sed -e '/Java Version:/!d' -e 's/.*Java Version: \([[^ ]]*\)[[ ]]*/\1/'` ;; + * ) JAVA_VERSION=`$JAVA -version 2>&1 | + sed -e '/ version /!d' -e 's/.*"\(.*\)".*/\1/'` ;; + esac + AC_MSG_RESULT($JAVA_VERSION) + case "$JAVA_VERSION" in + 1.[[3456789]]* | 1.[[1-9]][[0-9]]* | [[23456789]]* ) ;; + * ) + AC_MSG_ERROR([Java version 1.3 or higher required, got $JAVA_VERSION]) ;; + esac + + # Because of the code that SWIG generates to cast between pointers and + # integers, we need to add the flag "-fno-strict-aliasing" to the gcc + # command line when compiling the JNI code. This is documented in + # [#14953] and at http://www.swig.org/Doc1.3/Java.html + if test "${GCC}" = "yes"; then + SWIGCFLAGS="-fno-strict-aliasing" + fi + + for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS + do + CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" + done + + ADDITIONAL_LANG="$ADDITIONAL_LANG java" + INSTALL_LIBS="$INSTALL_LIBS \$(libjso_target)" +else + JAVAC=nojavac +fi + +# MinGW support. +if test "$db_cv_mingw" = "yes"; then + OSDIR=os_windows + PATH_SEPARATOR="\\\\/:" + + AC_DEFINE(DB_WIN32) + AC_DEFINE(STDC_HEADERS) +else + OSDIR=os + PATH_SEPARATOR="/" + AC_DEFINE(HAVE_SYSTEM_INCLUDE_FILES) +fi + +# Optional STL API. +if test "$db_cv_stl" = "yes"; then + AC_CXX_SUPPORTS_TEMPLATES + AC_CXX_WSTRING + AX_TLS + if test "$enable_shared" = "no"; then + DEFAULT_LIB_STL="\$(libstl_version)" + fi + if test "$enable_shared" = "yes"; then + DEFAULT_LIB_STL="\$(libstlso_target)" + fi + ADDITIONAL_INCS="dbstl_common.h dbstl_set.h dbstl_vector.h dbstl_exception.h dbstl_map.h dbstl_utility.h dbstl_dbc.h dbstl_dbt.h dbstl_base_iterator.h dbstl_container.h dbstl_element_ref.h dbstl_inner_utility.h dbstl_resource_manager.h $ADDITIONAL_INCS" + INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_STL" + if test "$enable_static" = "yes"; then + INSTALL_LIBS="$INSTALL_LIBS \$(libstl)" + fi +fi + +# Checks for include files, structures, C types. +AC_HEADER_STAT +AC_HEADER_TIME +AC_HEADER_DIRENT +AC_CHECK_HEADERS(execinfo.h sys/select.h sys/socket.h sys/time.h) +AC_CHECK_MEMBERS([struct stat.st_blksize]) +AM_TYPES + +AC_CACHE_CHECK([for ANSI C exit success/failure values], db_cv_exit_defines, [ +AC_TRY_COMPILE([#include ], return (EXIT_SUCCESS);, + [db_cv_exit_defines=yes], [db_cv_exit_defines=no])]) +if test "$db_cv_exit_defines" = "yes"; then + AC_DEFINE(HAVE_EXIT_SUCCESS) + AH_TEMPLATE(HAVE_EXIT_SUCCESS, + [Define to 1 if platform has EXIT_SUCCESS/EXIT_FAILURE #defines.]) +fi + +AC_CACHE_CHECK([for getopt optreset variable], db_cv_optreset, [ +AC_TRY_LINK([#include ], extern int optreset; optreset = 1;, + [db_cv_optreset=yes], [db_cv_optreset=no])]) +if test "$db_cv_optreset" = "yes"; then + AC_DEFINE(HAVE_GETOPT_OPTRESET) + AH_TEMPLATE(HAVE_GETOPT_OPTRESET, + [Define to 1 if getopt supports the optreset variable.]) +fi + +# Check for mutexes. +# We do this first because it changes $LIBSO_LIBS. +AM_DEFINE_MUTEXES + +# Check for native (system call or instruction set) support for +# atomic increment, decrement, and compare & exchange. +AM_DEFINE_ATOMIC + +# Test for various functions/libraries -- do tests that change library values +# first. +# +# Update LIBS, so we're testing against the current list of libraries. +LIBS="$LIBSO_LIBS" + +# The yield function on Solaris is almost certainly pthread_yield (LWP threads +# or POSIX pthreads), or thr_yield (UI threads). There's an outside chance it +# is sched_yield() though, only available in -lrt on Solaris. +AC_SEARCH_LIBS(sched_yield, rt) + +# The Berkeley DB library calls fdatasync, only available in -lrt on Solaris. +AC_SEARCH_LIBS(fdatasync, rt) + +AC_SEARCH_LIBS(getaddrinfo, nsl socket) +AC_SEARCH_LIBS(hstrerror, resolv) + +# Those tests updated LIBS, update our internal list. +LIBSO_LIBS="$LIBS" + +# !!! +# We could be more exact about whether these libraries are needed, but don't +# bother -- if they exist, we load them, it's only the test programs anyway. +AC_HAVE_LIBRARY(m, TEST_LIBS="$TEST_LIBS -lm") +AC_HAVE_LIBRARY(nsl, TEST_LIBS="$TEST_LIBS -lnsl") +AC_HAVE_LIBRARY(socket, TEST_LIBS="$TEST_LIBS -lsocket") + +# Checks for system functions for which we have replacements. +# +# The only portable getcwd call is getcwd(char *, size_t), where the +# buffer is non-NULL -- Solaris can't handle a NULL buffer, and they +# deleted getwd(). +AC_REPLACE_FUNCS(\ + abort atoi atol getcwd getenv getopt isalpha isdigit isprint\ + isspace memcmp memcpy memmove printf qsort raise rand strcasecmp\ + strcat strchr strdup strerror strncat strncmp strrchr strsep\ + strtol strtoul) + +# Check for system functions we optionally use. +AC_CHECK_FUNCS(\ + _fstati64 backtrace backtrace_symbols directio fchmod fclose\ + fcntl fdatasync fgetc fgets fopen fwrite getgid\ + getrusage getuid hstrerror mprotect pstat_getdynamic\ + pthread_self pthread_yield random sched_yield select setgid setuid\ + sigaction snprintf stat sysconf vsnprintf yield) + +AC_TIMERS + +# Ftruncate. +# We've run into a problem with ftruncate on Alpha/Tru64, the issue is that +# after a truncate the last page of the file mmaps as all zeros. So just don't +# use ftruncate. +case "$host_os" in +osf*) + AC_MSG_WARN( + [ftruncate ignored on $host_os-$host_vendor.]);; +*) + AC_CHECK_FUNCS(ftruncate);; +esac + +# Pread/pwrite. +# HP-UX has pread/pwrite, but it doesn't work with largefile support. +# NCR's version of System V R 4.3 has pread/pwrite symbols, but no support. +case "$host_os-$host_vendor" in +hpux*|sysv4.3*-ncr) + AC_MSG_WARN( + [pread/pwrite interfaces ignored on $host_os-$host_vendor.]);; +*) + AC_CHECK_FUNCS(pread pwrite);; +esac + +# Check for getaddrinfo; do the test explicitly instead of using AC_CHECK_FUNCS +# because isn't a standard include file. +AC_CACHE_CHECK([for getaddrinfo], db_cv_getaddrinfo, [ +AC_TRY_LINK([ +#include +#include ], [ + getaddrinfo(0, 0, 0, 0); +], [db_cv_getaddrinfo=yes], [db_cv_getaddrinfo=no])]) +if test "$db_cv_getaddrinfo" = "yes"; then + AC_DEFINE(HAVE_GETADDRINFO) + AH_TEMPLATE(HAVE_GETADDRINFO, + [Define to 1 if you have the `getaddrinfo' function.]) +fi + +# Check for the fcntl F_SETFD flag to deny child process access to file +# descriptors. +AC_CACHE_CHECK([for fcntl/F_SETFD], db_cv_fcntl_f_setfd, [ +AC_TRY_LINK([ +#include +#include ], [ + fcntl(1, F_SETFD, 1); +], [db_cv_fcntl_f_setfd=yes], [db_cv_fcntl_f_setfd=no])]) +if test "$db_cv_fcntl_f_setfd" = "yes"; then + AC_DEFINE(HAVE_FCNTL_F_SETFD) + AH_TEMPLATE(HAVE_FCNTL_F_SETFD, + [Define to 1 if fcntl/F_SETFD denies child access to file descriptors.]) +fi + +# A/UX has a broken getopt(3). +case "$host_os" in +aux*) AC_LIBOBJ([getopt]);; +esac + +# Linux has a broken O_DIRECT flag, but you can't detect it at configure time. +# Linux and SGI require buffer alignment we may not match, otherwise writes +# will fail. Default to not using the O_DIRECT flag. +if test "$db_cv_o_direct" = "yes"; then + AC_CACHE_CHECK([for open/O_DIRECT], db_cv_open_o_direct, [ + AC_TRY_LINK([ + #include + #include ], [ + open("a", O_RDONLY | O_DIRECT, 0); + ], [db_cv_open_o_direct=yes], [db_cv_open_o_direct=no])]) + if test \ + "$db_cv_o_direct" = "yes" -a "$db_cv_open_o_direct" = "yes"; then + AC_DEFINE(HAVE_O_DIRECT) + AH_TEMPLATE(HAVE_O_DIRECT, + [Define to 1 if you have the O_DIRECT flag.]) + fi +fi + +# Check for largefile support. +AC_SYS_LARGEFILE + +# Figure out how to create shared regions. +# +# First, we look for mmap. +# +# BSD/OS has mlock(2), but it doesn't work until the 4.1 release. +# +# Nextstep (version 3.3) apparently supports mmap(2) (the mmap symbol +# is defined in the C library) but does not support munmap(2). Don't +# try to use mmap if we can't find munmap. +# +# Ultrix has mmap(2), but it doesn't work. +mmap_ok=no +case "$host_os" in +bsdi3*|bsdi4.0) + AC_MSG_WARN([mlock(2) interface ignored on $host_os-$host_vendor.]) + mmap_ok=yes + AC_CHECK_FUNCS(mmap munmap, , mmap_ok=no);; +ultrix*) + AC_MSG_WARN([mmap(2) interface ignored on $host_os-$host_vendor.]);; +*) + mmap_ok=yes + AC_CHECK_FUNCS(mlock munlock) + AC_CHECK_FUNCS(mmap munmap, , mmap_ok=no);; +esac + +# Second, we look for shmget. +# +# SunOS has the shmget(2) interfaces, but there appears to be a missing +# #include file, so we ignore them. +shmget_ok=no +case "$host_os" in +sunos*) + AC_MSG_WARN([shmget(2) interface ignored on $host_os-$host_vendor.]);; +*) + shmget_ok=yes + AC_CHECK_FUNCS(shmget, , shmget_ok=no) + + # Check for shmctl to lock down shared memory segments. + AC_CACHE_CHECK([for shmctl], db_cv_shmctl_shm_lock, [ + AC_TRY_LINK([ +#include +#include +#include +#include ], [ + shmctl(0, SHM_LOCK, NULL); + ], [db_cv_shmctl_shm_lock=yes], [db_cv_shmctl_shm_lock=no])]) + if test "$db_cv_shmctl_shm_lock" = "yes"; then + AC_DEFINE(HAVE_SHMCTL_SHM_LOCK) + AH_TEMPLATE(HAVE_SHMCTL_SHM_LOCK, + [Define to 1 if shmctl/SHM_LOCK locks down shared memory segments.]) + fi;; +esac + +# We require either mmap/munmap(2) or shmget(2). +if test "$mmap_ok" = "no" -a "$shmget_ok" = "no"; then + AC_MSG_WARN([Neither mmap/munmap(2) or shmget(2) library functions.]) +fi + +# Optional RPC client/server. +if test "$db_cv_rpc" = "yes"; then + AM_RPC_CONFIGURE +fi + +# Optional Tcl support. +if test "$db_cv_tcl" = "yes"; then + AM_TCL_LOAD +fi + +# Optional sequence code. +AM_SEQUENCE_CONFIGURE + +# Optional DB 1.85 compatibility API. +if test "$db_cv_compat185" = "yes"; then + ADDITIONAL_INCS="db_185.h $ADDITIONAL_INCS" + + ADDITIONAL_OBJS="db185${o} $ADDITIONAL_OBJS" +fi + +# Optional utilities. +if test "$db_cv_dump185" = "yes"; then + ADDITIONAL_PROGS="db_dump185 $ADDITIONAL_PROGS" +fi + +# You can disable pieces of functionality to save space. +# +# Btree is always configured: it is the standard method, and Hash off-page +# duplicates require it. +ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(BTREE_OBJS)" + +# Compression can be disabled. +if test "$db_cv_build_compression" = "yes"; then + AC_DEFINE(HAVE_COMPRESSION) + AH_TEMPLATE(HAVE_COMPRESSION, [Define to 1 if building compression support.]) +fi + +# Partitioning can be disabled. +if test "$db_cv_build_partition" = "yes"; then + AC_DEFINE(HAVE_PARTITION) + AH_TEMPLATE(HAVE_PARTITION, [Define to 1 if building partitioned database support.]) +fi + +# Hash can be disabled. +if test "$db_cv_build_hash" = "yes"; then + AC_DEFINE(HAVE_HASH) + AH_TEMPLATE(HAVE_HASH, [Define to 1 if building Hash access method.]) + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HASH_OBJS)" + if test "$db_cv_build_verify" = "yes"; then + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HASH_VRFY_OBJS)" + fi +else + ADDITIONAL_OBJS="$ADDITIONAL_OBJS hash_stub${o}" +fi + +# Queue can be disabled. +if test "$db_cv_build_queue" = "yes"; then + AC_DEFINE(HAVE_QUEUE) + AH_TEMPLATE(HAVE_QUEUE, [Define to 1 if building Queue access method.]) + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(QUEUE_OBJS)" + if test "$db_cv_build_verify" = "yes"; then + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(QUEUE_VRFY_OBJS)" + fi +else + ADDITIONAL_OBJS="$ADDITIONAL_OBJS qam_stub${o}" +fi + +# Replication can be disabled. +if test "$db_cv_build_replication" = "yes"; then + AC_DEFINE(HAVE_REPLICATION) + AH_TEMPLATE(HAVE_REPLICATION, + [Define to 1 if building replication support.]) + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(REP_OBJS)" + + # If we're building replication and detected POSIX threads, build the + # replication manager. + AH_TEMPLATE(HAVE_REPLICATION_THREADS, + [Define to 1 if building the Berkeley DB replication framework.]) + + if test "$ac_cv_header_pthread_h" = yes; then + AC_DEFINE(HAVE_REPLICATION_THREADS) + + # Solaris requires the socket and nsl libraries to build the + # replication manager. Don't add nsl regardless of the OS, + # it causes RPC to fail on AIX 4.3.3. + case "$host_os" in + solaris*) + AC_HAVE_LIBRARY(nsl, LIBSO_LIBS="$LIBSO_LIBS -lnsl") + AC_HAVE_LIBRARY(socket, + LIBSO_LIBS="$LIBSO_LIBS -lsocket");; + esac + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(REPMGR_OBJS)" + else + ADDITIONAL_OBJS="$ADDITIONAL_OBJS repmgr_stub${o}" + fi +else + ADDITIONAL_OBJS="$ADDITIONAL_OBJS rep_stub${o} repmgr_stub${o}" +fi + +# The statistics code can be disabled. +if test "$db_cv_build_statistics" = "yes"; then + AC_DEFINE(HAVE_STATISTICS) + AH_TEMPLATE(HAVE_STATISTICS, + [Define to 1 if building statistics support.]) +fi + +# The verification code can be disabled. +if test "$db_cv_build_verify" = "yes"; then + AC_DEFINE(HAVE_VERIFY) + AH_TEMPLATE(HAVE_VERIFY, + [Define to 1 if building access method verification support.]) + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(BTREE_VRFY_OBJS)" +else + ADDITIONAL_OBJS="$ADDITIONAL_OBJS db_vrfy_stub${o}" +fi + +# The crypto code can be disabled. +if test -d "$srcdir/../crypto" -a "$db_cv_build_cryptography" = "yes"; then + AC_DEFINE(HAVE_CRYPTO) + AH_TEMPLATE(HAVE_CRYPTO, + [Define to 1 if Berkeley DB release includes strong cryptography.]) + + CRYPTO_OBJS="\$(CRYPTO_OBJS)" +else + CRYPTO_OBJS="crypto_stub${o}" +fi + +# The mutex code can be disabled, and if there aren't any mutexes, then there's +# no reason to include the locking code. +if test "$db_cv_build_mutexsupport" = "yes"; then + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(LOCK_OBJS) \$(MUTEX_OBJS)" +else + ADDITIONAL_OBJS="$ADDITIONAL_OBJS lock_stub${o} mut_stub${o}" +fi + +# If DIAGNOSTIC is defined, include the log print routines in the library +# itself, various diagnostic modes use them. +if test "$db_cv_diagnostic" = "yes"; then + ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(PRINT_OBJS)" +fi + +# If building for QNX, we need additional OS files. +if test "$qnx_build" = "yes"; then + ADDITIONAL_OBJS="$ADDITIONAL_OBJS os_qnx_fsync${o} os_qnx_open${o}" +fi + +# We need to add the additional object files into the Makefile with the correct +# suffix. We can't use $LTLIBOBJS itself, because that variable has $U encoded +# in it for automake, and that's not what we want. See SR #7227 for additional +# information. +# +# XXX: I'm not sure this is correct. +REPLACEMENT_OBJS=`echo "$LIB@&t@OBJS" | + sed "s,\.[[^.]]* ,$o ,g;s,\.[[^.]]*$,$o,"` + +# This is necessary so that .o files in LIBOBJS are also built via +# the ANSI2KNR-filtering rules. +LIB@&t@OBJS=`echo "$LIB@&t@OBJS" | + sed 's,\.[[^.]]* ,$U&,g;s,\.[[^.]]*$,$U&,'` +LTLIBOBJS=`echo "$LIB@&t@OBJS" | + sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'` +AC_SUBST(LTLIBOBJS) + +# Initial output file list. +CREATE_LIST="Makefile + db_cxx.h:$srcdir/../dbinc/db_cxx.in + db_int.h:$srcdir/../dbinc/db_int.in + clib_port.h:$srcdir/../dist/clib_port.in + include.tcl:$srcdir/../test/include.tcl" + +# Create the db.h file from a source file, a list of global function +# prototypes, and, if configured for unique names, a list of #defines +# to do DB_VERSION_UNIQUE_NAME substitution. +if test "$db_cv_uniquename" = "yes"; then + CREATE_LIST="$CREATE_LIST + db.h:$srcdir/../dbinc/db.in:$srcdir/../dbinc_auto/api_flags.in:$srcdir/../dbinc_auto/ext_def.in:$srcdir/../dbinc_auto/ext_prot.in" +else + CREATE_LIST="$CREATE_LIST + db.h:$srcdir/../dbinc/db.in:$srcdir/../dbinc_auto/api_flags.in:$srcdir/../dbinc_auto/ext_prot.in" +fi + +# If configured for unique names, create the db_int_uext.h file (which +# does the DB_VERSION_UNIQUE_NAME substitution), which is included by +# the db_int.h file. +if test "$db_cv_uniquename" = "yes"; then + CREATE_LIST="$CREATE_LIST + db_int_def.h:$srcdir/../dbinc_auto/int_def.in" + db_int_def='#include "db_int_def.h"' +fi + +# Create the db_185.h and db185_int.h files from source files, a list of +# global function prototypes, and, if configured for unique names, a list +# of #defines to do DB_VERSION_UNIQUE_NAME substitution. +if test "$db_cv_compat185" = "yes"; then + if test "$db_cv_uniquename" = "yes"; then + CREATE_LIST="$CREATE_LIST + db_185.h:$srcdir/../dbinc/db_185.in:$srcdir/../dbinc_auto/ext_185_def.in:$srcdir/../dbinc_auto/ext_185_prot.in + db185_int.h:$srcdir/../db185/db185_int.in:$srcdir/../dbinc_auto/ext_185_def.in:$srcdir/../dbinc_auto/ext_185_prot.in" + else + CREATE_LIST="$CREATE_LIST + db_185.h:$srcdir/../dbinc/db_185.in:$srcdir/../dbinc_auto/ext_185_prot.in + db185_int.h:$srcdir/../db185/db185_int.in:$srcdir/../dbinc_auto/ext_185_prot.in" + fi +fi + +if test "$db_cv_stl" = "yes"; then + CREATE_LIST="$CREATE_LIST + dbstl_common.h:$srcdir/../stl/dbstl_common.in" +fi + +AC_CONFIG_FILES($CREATE_LIST) +AC_OUTPUT diff --git a/src/libs/resiprocate/contrib/db/dist/gen_inc.awk b/src/libs/resiprocate/contrib/db/dist/gen_inc.awk new file mode 100644 index 00000000..3d631d17 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/gen_inc.awk @@ -0,0 +1,59 @@ +# This awk script parses C input files looking for lines marked "PUBLIC:" +# and "EXTERN:". (PUBLIC lines are DB internal function prototypes and +# #defines, EXTERN are DB external function prototypes and #defines.) +# +# PUBLIC lines are put into two versions of per-directory include files: +# one file that contains the prototypes, and one file that contains a +# #define for the name to be processed during configuration when creating +# unique names for every global C-language symbol in the DB library. +# +# The EXTERN lines are put into two files: one of which contains prototypes +# which are always appended to the db.h file, and one of which contains a +# #define list for use when creating unique symbol names. +# +# Four arguments: +# e_dfile list of EXTERN #defines +# e_pfile include file that contains EXTERN prototypes +# i_dfile list of internal (PUBLIC) #defines +# i_pfile include file that contains internal (PUBLIC) prototypes +/PUBLIC:/ { + sub("^.*PUBLIC:[ ][ ]*", "") + if ($0 ~ "^#if|^#ifdef|^#ifndef|^#else|^#endif") { + print $0 >> i_pfile + print $0 >> i_dfile + next + } + pline = sprintf("%s %s", pline, $0) + if (pline ~ "\\)\\);") { + sub("^[ ]*", "", pline) + print pline >> i_pfile + if (pline !~ db_version_unique_name) { + gsub("[ ][ ]*__P.*", "", pline) + sub("^.*[ ][*]*", "", pline) + printf("#define %s %s@DB_VERSION_UNIQUE_NAME@\n", + pline, pline) >> i_dfile + } + pline = "" + } +} + +/EXTERN:/ { + sub("^.*EXTERN:[ ][ ]*", "") + if ($0 ~ "^#if|^#ifdef|^#ifndef|^#else|^#endif") { + print $0 >> e_pfile + print $0 >> e_dfile + next + } + eline = sprintf("%s %s", eline, $0) + if (eline ~ "\\)\\);") { + sub("^[ ]*", "", eline) + print eline >> e_pfile + if (eline !~ db_version_unique_name) { + gsub("[ ][ ]*__P.*", "", eline) + sub("^.*[ ][*]*", "", eline) + printf("#define %s %s@DB_VERSION_UNIQUE_NAME@\n", + eline, eline) >> e_dfile + } + eline = "" + } +} diff --git a/src/libs/resiprocate/contrib/db/dist/gen_rec.awk b/src/libs/resiprocate/contrib/db/dist/gen_rec.awk new file mode 100644 index 00000000..604608ae --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/gen_rec.awk @@ -0,0 +1,1146 @@ +#!/bin/sh - +# +# See the file LICENSE for redistribution information. +# +# Copyright (c) 1996-2009 Oracle. All rights reserved. +# +# $Id$ +# + +# This awk script generates all the log, print, and read routines for the DB +# logging. It also generates a template for the recovery functions (these +# functions must still be edited, but are highly stylized and the initial +# template gets you a fair way along the path). +# +# For a given file prefix.src, we generate a file prefix_auto.c, and a file +# prefix_auto.h that contains: +# +# external declarations for the file's functions +# defines for the physical record types +# (logical types are defined in each subsystem manually) +# structures to contain the data unmarshalled from the log. +# +# This awk script requires that four variables be set when it is called: +# +# source_file -- the C source file being created +# header_file -- the C #include file being created +# template_file -- the template file being created +# +# And stdin must be the input file that defines the recovery setup. +# +# Within each file prefix.src, we use a number of public keywords (documented +# in the reference guide) as well as the following ones which are private to +# DB: +# DBPRIVATE Indicates that a file will be built as part of DB, +# rather than compiled independently, and so can use +# DB-private interfaces (such as DB_LOG_NOCOPY). +# DB A DB handle. Logs the dbreg fileid for that handle, +# and makes the *_log interface take a DB * instead of a +# DB_ENV *. +# PGDBT Just like DBT, only we know it stores a page or page +# header, so we can byte-swap it (once we write the +# byte-swapping code, which doesn't exist yet). +# LOCKS Just like DBT, but uses a print function for locks. + +BEGIN { + if (source_file == "" || + header_file == "" || template_file == "") { + print "Usage: gen_rec.awk requires three variables to be set:" + print "\theader_file\t-- the recover #include file being created" + print "\tprint_file\t-- the print source file being created" + print "\tsource_file\t-- the recover source file being created" + print "\ttemplate_file\t-- the template file being created" + exit + } + FS="[\t ][\t ]*" + CFILE=source_file + HFILE=header_file + PFILE=print_file + TFILE=template_file + + # These are the variables we use to create code that calls into + # db routines and/or uses an environment. + dbprivate = 0 + env_type = "DB_ENV" + env_var = "dbenv" + log_call = "dbenv->log_put" + +} +/^[ ]*DBPRIVATE/ { + dbprivate = 1 + env_type = "ENV" + env_var = "env" + log_call = "__log_put" +} +/^[ ]*PREFIX/ { + prefix = $2 + num_funcs = 0; + + # Start .c files. + printf("/* Do not edit: automatically built by gen_rec.awk. */\n\n")\ + > CFILE + printf("#include \"db_config.h\"\n") >> CFILE + if (!dbprivate) { + printf("#include \n") >> CFILE + printf("#include \n") >> CFILE + printf("#include \n") >> CFILE + printf("#include \"db.h\"\n") >> CFILE + printf("#include \"db_int.h\"\n") >> CFILE + printf("#include \"dbinc/db_swap.h\"\n") >> CFILE + } + + printf("/* Do not edit: automatically built by gen_rec.awk. */\n\n")\ + > PFILE + printf("#include \"db_config.h\"\n\n") >> PFILE + if (!dbprivate) { + printf("#include \n") >> PFILE + printf("#include \n") >> PFILE + printf("#include \n") >> PFILE + printf("#include \"db.h\"\n") >> PFILE + } + + if (prefix == "__ham") + printf("#ifdef HAVE_HASH\n") >> PFILE + if (prefix == "__qam") + printf("#ifdef HAVE_QUEUE\n") >> PFILE + + # Start .h file, make the entire file conditional. + printf("/* Do not edit: automatically built by gen_rec.awk. */\n\n")\ + > HFILE + printf("#ifndef\t%s_AUTO_H\n#define\t%s_AUTO_H\n", prefix, prefix)\ + >> HFILE + + # Write recovery template file headers + if (dbprivate) { + # This assumes we're doing DB recovery. + printf("#include \"db_config.h\"\n\n") > TFILE + printf("#include \"db_int.h\"\n") >> TFILE + printf("#include \"dbinc/db_page.h\"\n") >> TFILE + printf("#include \"dbinc/%s.h\"\n", prefix) >> TFILE + printf("#include \"dbinc/log.h\"\n\n") >> TFILE + } else { + printf("#include \"db.h\"\n\n") > TFILE + } +} +/^[ ]*INCLUDE/ { + for (i = 2; i < NF; i++) + printf("%s ", $i) >> CFILE + printf("%s\n", $i) >> CFILE + for (i = 2; i < NF; i++) + printf("%s ", $i) >> PFILE + printf("%s\n", $i) >> PFILE +} +/^[ ]*(BEGIN|BEGIN_COMPAT)/ { + if (in_begin) { + print "Invalid format: missing END statement" + exit + } + in_begin = 1; + is_duplicate = 0; + is_dbt = 0; + has_dbp = 0; + is_uint = 0; + hdrdbt = "NULL"; + ddbt = "NULL"; + # + # BEGIN_COMPAT does not need logging function or rec table entry. + # + need_log_function = ($1 == "BEGIN"); + is_compat = ($1 == "BEGIN_COMPAT"); + nvars = 0; + + thisfunc = $2; + dup_thisfunc = $2; + version = $3; + + rectype = $4; + + make_name(thisfunc, thisfunc, version); +} +/^[ ]*(DB|ARG|DBT|LOCKS|PGDBT|PGDDBT|POINTER|TIME)/ { + vars[nvars] = $2; + types[nvars] = $3; + modes[nvars] = $1; + formats[nvars] = $NF; + for (i = 4; i < NF; i++) + types[nvars] = sprintf("%s %s", types[nvars], $i); + + if ($1 == "DB") { + has_dbp = 1; + } + + if ($1 == "DB" || $1 == "ARG" || $1 == "TIME") { + sizes[nvars] = sprintf("sizeof(u_int32_t)"); + if ($3 != "u_int32_t") + is_uint = 1; + } else if ($1 == "POINTER") + sizes[nvars] = sprintf("sizeof(*%s)", $2); + else { # DBT, PGDBT, PGDDBT + sizes[nvars] =\ + sprintf("sizeof(u_int32_t) + (%s == NULL ? 0 : %s->size)",\ + $2, $2); + is_dbt = 1; + if ($1 == "PGDBT") + hdrdbt = vars[nvars]; + else if ($1 == "PGDDBT") + ddbt = vars[nvars]; + } + nvars++; +} +/^[ ]*DUPLICATE/ { + is_duplicate = 1; + dup_rectype = $4; + old_logfunc = logfunc; + old_funcname = funcname; + make_name($2, funcname, $3); + internal_name = sprintf("%s_%s_int", prefix, thisfunc); + dup_logfunc = logfunc; + dup_funcname = funcname; + dup_thisfunc = $2; + logfunc = old_logfunc; + funcname = old_funcname; +} +/^[ ]*END/ { + if (!in_begin) { + print "Invalid format: missing BEGIN statement" + exit; + } + + # Declare the record type. + printf("#define\tDB_%s\t%d\n", funcname, rectype) >> HFILE + if (is_duplicate) + printf("#define\tDB_%s\t%d\n",\ + dup_funcname, dup_rectype) >> HFILE + + # Structure declaration. + printf("typedef struct _%s_args {\n", funcname) >> HFILE + + # Here are the required fields for every structure + printf("\tu_int32_t type;\n\tDB_TXN *txnp;\n") >> HFILE + printf("\tDB_LSN prev_lsn;\n") >>HFILE + + # Here are the specified fields. + for (i = 0; i < nvars; i++) { + t = types[i]; + if (modes[i] == "POINTER") { + ndx = index(t, "*"); + t = substr(types[i], 1, ndx - 2); + } + printf("\t%s\t%s;\n", t, vars[i]) >> HFILE + } + printf("} %s_args;\n\n", funcname) >> HFILE + + # Output the read, log, and print functions (note that we must + # generate the required read function first, because we use its + # prototype in the print function). + + read_function(); + + if (need_log_function) { + log_function(); + } + print_function(); + + # Recovery template + if (dbprivate) + f = "template/rec_ctemp" + else + f = "template/rec_utemp" + + cmd = sprintf(\ + "sed -e s/PREF/%s/ -e s/FUNC/%s/ -e s/DUP/%s/ < template/rec_%s >> %s", + prefix, thisfunc, dup_thisfunc, + dbprivate ? "ctemp" : "utemp", TFILE) + system(cmd); + + # Done writing stuff, reset and continue. + in_begin = 0; +} + +END { + # End the conditional for the HFILE + printf("#endif\n") >> HFILE + + # Print initialization routine; function prototype + p[1] = sprintf("int %s_init_print %s%s%s", prefix, + "__P((", env_type, " *, DB_DISTAB *));"); + p[2] = ""; + proto_format(p, PFILE); + + # Create the routine to call __db_add_recovery(print_fn, id) + printf("int\n%s_init_print(%s, dtabp)\n",\ + prefix, env_var) >> PFILE + printf("\t%s *%s;\n", env_type, env_var) >> PFILE + printf("\tDB_DISTAB *dtabp;\n{\n") >> PFILE + # If application-specific, the user will need a prototype for + # __db_add_recovery, since they won't have DB's. + if (!dbprivate) { + printf(\ + "\tint __db_add_recovery __P((%s *, DB_DISTAB *,\n",\ + env_type) >> PFILE + printf(\ + "\t int (*)(%s *, DBT *, DB_LSN *, db_recops), u_int32_t));\n",\ + env_type) >> PFILE + } + + printf("\tint ret;\n\n") >> PFILE + for (i = 0; i < num_funcs; i++) { + if (functable[i] == 1) + continue; + printf("\tif ((ret = __db_add_recovery%s(%s, ",\ + dbprivate ? "_int" : "", env_var) >> PFILE + printf("dtabp,\n") >> PFILE + printf("\t %s_print, DB_%s)) != 0)\n",\ + dupfuncs[i], funcs[i]) >> PFILE + printf("\t\treturn (ret);\n") >> PFILE + } + printf("\treturn (0);\n}\n") >> PFILE + if (prefix == "__ham") + printf("#endif /* HAVE_HASH */\n") >> PFILE + if (prefix == "__qam") + printf("#endif /* HAVE_QUEUE */\n") >> PFILE + + # We only want to generate *_init_recover functions if this is a + # DB-private, rather than application-specific, set of recovery + # functions. Application-specific recovery functions should be + # dispatched using the DB_ENV->set_app_dispatch callback rather than + # a DB dispatch table ("dtab"). + if (!dbprivate) + exit + # Everything below here is dbprivate, so it uses ENV instead of DB_ENV + # Recover initialization routine + p[1] = sprintf("int %s_init_recover %s", prefix,\ + "__P((ENV *, DB_DISTAB *));"); + p[2] = ""; + proto_format(p, CFILE); + + # Create the routine to call db_add_recovery(func, id) + printf("int\n%s_init_recover(env, dtabp)\n", prefix) >> CFILE + printf("\tENV *env;\n") >> CFILE + printf("\tDB_DISTAB *dtabp;\n{\n") >> CFILE + printf("\tint ret;\n\n") >> CFILE + for (i = 0; i < num_funcs; i++) { + if (functable[i] == 1) + continue; + printf("\tif ((ret = __db_add_recovery_int(env, ") >> CFILE + printf("dtabp,\n") >> CFILE + printf("\t %s_recover, DB_%s)) != 0)\n",\ + funcs[i], funcs[i]) >> CFILE + printf("\t\treturn (ret);\n") >> CFILE + } + printf("\treturn (0);\n}\n") >> CFILE +} + +function log_function() +{ + log_prototype(logfunc, 0); + if (is_duplicate) { + log_prototype(dup_logfunc, 0); + log_prototype(internal_name, 1); + } + + # Function declaration + log_funcdecl(logfunc, 0); + if (is_duplicate) { + log_callint(funcname); + log_funcdecl(dup_logfunc, 0); + log_callint(dup_funcname); + log_funcdecl(internal_name, 1); + } + + # Function body and local decls + printf("{\n") >> CFILE + printf("\tDBT logrec;\n") >> CFILE + printf("\tDB_LSN *lsnp, null_lsn, *rlsnp;\n") >> CFILE + if (dbprivate) { + printf("\tDB_TXNLOGREC *lr;\n") >> CFILE + if (has_dbp) + printf("\t%s *%s;\n", + env_type, env_var) >> CFILE + } else { + printf("\tENV *env;\n") >> CFILE + } + printf("\tu_int32_t ") >> CFILE + if (is_dbt) + printf("zero, ") >> CFILE + if (is_uint) + printf("uinttmp, ") >> CFILE + printf("rectype, txn_num;\n") >> CFILE + printf("\tu_int npad;\n") >> CFILE + printf("\tu_int8_t *bp;\n") >> CFILE + printf("\tint ") >> CFILE + if (dbprivate) { + printf("is_durable, ") >> CFILE + } + printf("ret;\n\n") >> CFILE + + # Initialization + if (dbprivate) + printf("\tCOMPQUIET(lr, NULL);\n\n") >> CFILE + + if (has_dbp) + printf("\t%s = dbp->%s;\n", env_var, env_var) >> CFILE + if (!dbprivate) + printf("\tenv = dbenv->env;\n") >> CFILE + printf("\trlsnp = ret_lsnp;\n") >> CFILE + if (is_duplicate) + printf("\trectype = type;\n") >> CFILE + else + printf("\trectype = DB_%s;\n", funcname) >> CFILE + printf("\tnpad = 0;\n") >> CFILE + printf("\tret = 0;\n\n") >> CFILE + + if (dbprivate) { + printf("\tif (LF_ISSET(DB_LOG_NOT_DURABLE)") >> CFILE + if (has_dbp) { + printf(" ||\n\t ") >> CFILE + printf("F_ISSET(dbp, DB_AM_NOT_DURABLE)) {\n") >> CFILE + } else { + printf(") {\n") >> CFILE + } + printf("\t\tif (txnp == NULL)\n") >> CFILE + printf("\t\t\treturn (0);\n") >> CFILE + printf("\t\tis_durable = 0;\n") >> CFILE + printf("\t} else\n") >> CFILE + printf("\t\tis_durable = 1;\n\n") >> CFILE + } + printf("\tif (txnp == NULL) {\n") >> CFILE + printf("\t\ttxn_num = 0;\n") >> CFILE + printf("\t\tlsnp = &null_lsn;\n") >> CFILE + printf("\t\tnull_lsn.file = null_lsn.offset = 0;\n") >> CFILE + printf("\t} else {\n") >> CFILE + if (dbprivate && logfunc != "__db_debug") { + printf(\ + "\t\tif (TAILQ_FIRST(&txnp->kids) != NULL &&\n") >> CFILE + printf("\t\t (ret = __txn_activekids(") >> CFILE + printf("env, rectype, txnp)) != 0)\n") >> CFILE + printf("\t\t\treturn (ret);\n") >> CFILE + } + printf("\t\t/*\n\t\t * We need to assign begin_lsn while ") >> CFILE + printf("holding region mutex.\n") >> CFILE + printf("\t\t * That assignment is done inside the ") >> CFILE + printf("DbEnv->log_put call,\n\t\t * ") >> CFILE + printf("so pass in the appropriate memory location to be ") >> CFILE + printf("filled\n\t\t * in by the log_put code.\n\t\t */\n") >> CFILE + printf("\t\tDB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp);\n") >> CFILE + printf("\t\ttxn_num = txnp->txnid;\n") >> CFILE + printf("\t}\n\n") >> CFILE + + # If we're logging a DB handle, make sure we have a log + # file ID for it. + db_handle_id_function(modes, nvars); + + # Malloc + printf("\tlogrec.size = ") >> CFILE + printf("sizeof(rectype) + ") >> CFILE + printf("sizeof(txn_num) + sizeof(DB_LSN)") >> CFILE + for (i = 0; i < nvars; i++) + printf("\n\t + %s", sizes[i]) >> CFILE + printf(";\n") >> CFILE + if (dbprivate) { + printf("\tif (CRYPTO_ON(env)) {\n") >> CFILE + printf(\ + "\t\tnpad = env->crypto_handle->adj_size(logrec.size);\n") >> CFILE + printf("\t\tlogrec.size += npad;\n\t}\n\n") >> CFILE + + printf("\tif (is_durable || txnp == NULL) {\n") >> CFILE + printf("\t\tif ((ret =\n\t\t __os_malloc(env, ") >> CFILE + printf("logrec.size, &logrec.data)) != 0)\n") >> CFILE + printf("\t\t\treturn (ret);\n") >> CFILE + printf("\t} else {\n") >> CFILE + write_malloc("\t\t", + "lr", "logrec.size + sizeof(DB_TXNLOGREC)", CFILE) + printf("#ifdef DIAGNOSTIC\n") >> CFILE + printf("\t\tif ((ret =\n\t\t __os_malloc(env, ") >> CFILE + printf("logrec.size, &logrec.data)) != 0) {\n") >> CFILE + printf("\t\t\t__os_free(env, lr);\n") >> CFILE + printf("\t\t\treturn (ret);\n") >> CFILE + printf("\t\t}\n") >> CFILE + printf("#else\n") >> CFILE + printf("\t\tlogrec.data = lr->data;\n") >> CFILE + printf("#endif\n") >> CFILE + printf("\t}\n") >> CFILE + } else { + write_malloc("\t", "logrec.data", "logrec.size", CFILE) + printf("\tbp = logrec.data;\n\n") >> CFILE + } + printf("\tif (npad > 0)\n") >> CFILE + printf("\t\tmemset((u_int8_t *)logrec.data + logrec.size ") >> CFILE + printf("- npad, 0, npad);\n\n") >> CFILE + printf("\tbp = logrec.data;\n\n") >> CFILE + + # Copy args into buffer + printf("\tLOGCOPY_32(env, bp, &rectype);\n") >> CFILE + printf("\tbp += sizeof(rectype);\n\n") >> CFILE + printf("\tLOGCOPY_32(env, bp, &txn_num);\n") >> CFILE + printf("\tbp += sizeof(txn_num);\n\n") >> CFILE + printf("\tLOGCOPY_FROMLSN(env, bp, lsnp);\n") >> CFILE + printf("\tbp += sizeof(DB_LSN);\n\n") >> CFILE + + for (i = 0; i < nvars; i++) { + if (modes[i] == "ARG" || modes[i] == "TIME") { + if (types[i] == "u_int32_t") { + printf("\tLOGCOPY_32(env, bp, &%s);\n", + vars[i]) >> CFILE + printf("\tbp += sizeof(%s);\n\n", + vars[i]) >> CFILE + } else { + printf("\tuinttmp = (u_int32_t)%s;\n", + vars[i]) >> CFILE + printf("\tLOGCOPY_32(env,") >> CFILE + printf("bp, &uinttmp);\n") >> CFILE + printf("\tbp += sizeof(uinttmp);\n\n") >> CFILE + } + } else if (modes[i] == "DBT" || modes[i] == "LOCKS" ||\ + modes[i] == "PGDBT" || modes[i] == "PGDDBT") { + printf("\tif (%s == NULL) {\n", vars[i]) >> CFILE + printf("\t\tzero = 0;\n") >> CFILE + printf("\t\tLOGCOPY_32(env, bp, &zero);\n") >> CFILE + printf("\t\tbp += sizeof(u_int32_t);\n") >> CFILE + printf("\t} else {\n") >> CFILE + printf("\t\tLOGCOPY_32(env, bp, &%s->size);\n", + vars[i]) >> CFILE + printf("\t\tbp += sizeof(%s->size);\n", vars[i])\ + >> CFILE + printf("\t\tmemcpy(bp, %s->data, %s->size);\n",\ + vars[i], vars[i]) >> CFILE + if (modes[i] == "PGDBT" && !is_compat) { + printf("\t\tif (LOG_SWAPPED(env))\n") >> CFILE + printf(\ + "\t\t\tif ((ret = __db_pageswap(dbp,\n") >> CFILE + printf(\ + "\t\t\t (PAGE *)bp, (size_t)%s->size, (DBT *)%s, 0)) != 0)\n", + vars[i], ddbt) >> CFILE + printf("\t\t\t\treturn (ret);\n") >> CFILE + } else if (modes[i] == "PGDDBT") { + printf("\t\tif (LOG_SWAPPED(env) && ") >> CFILE + printf("F_ISSET(%s, DB_DBT_APPMALLOC))\n", + ddbt) >> CFILE + printf("\t\t\t__os_free(env, %s->data);\n", + ddbt) >> CFILE + } + printf("\t\tbp += %s->size;\n", vars[i]) >> CFILE + printf("\t}\n\n") >> CFILE + } else if (modes[i] == "DB") { + printf(\ + "\tuinttmp = (u_int32_t)dbp->log_filename->id;\n")\ + >> CFILE + printf("\tLOGCOPY_32(env, bp, &uinttmp);\n") >> CFILE + printf("\tbp += sizeof(uinttmp);\n\n") >> CFILE + } else { # POINTER + printf("\tif (%s != NULL)", vars[i]) >> CFILE + if (has_dbp && types[i] == "DB_LSN *") { + printf(" {\n\t\tif (txnp != NULL) {\n")\ + >> CFILE + printf(\ + "\t\t\tLOG *lp = env->lg_handle->reginfo.primary;\n") >> CFILE + printf(\ + "\t\t\tif (LOG_COMPARE(%s, &lp->lsn) >= 0 && (ret =\n", vars[i])\ + >> CFILE + printf(\ + "\t\t\t __log_check_page_lsn(env, dbp, %s)) != 0)\n", vars[i])\ + >> CFILE + printf("\t\t\t\treturn (ret);\n") >> CFILE + printf("\t\t}") >> CFILE + } + printf("\n\t\tLOGCOPY_FROMLSN(env, bp, %s);\n", + vars[i]) >> CFILE + if (has_dbp && types[i] == "DB_LSN *") + printf("\t} else\n") >> CFILE + else + printf("\telse\n") >> CFILE + printf("\t\tmemset(bp, 0, %s);\n", sizes[i]) >> CFILE + printf("\tbp += %s;\n\n", sizes[i]) >> CFILE + } + } + + # Error checking. User code won't have DB_ASSERT available, but + # this is a pretty unlikely assertion anyway, so we just leave it out + # rather than requiring assert.h. + if (dbprivate) { + printf("\tDB_ASSERT(env,\n") >> CFILE + printf("\t (u_int32_t)(bp - (u_int8_t *)") >> CFILE + printf("logrec.data) <= logrec.size);\n\n") >> CFILE + # Save the log record off in the txn's linked list, + # or do log call. + # We didn't call the crypto alignment function when + # we created this log record (because we don't have + # the right header files to find the function), so + # we have to copy the log record to make sure the + # alignment is correct. + printf("\tif (is_durable || txnp == NULL) {\n") >> CFILE + # Output the log record and update the return LSN. + printf("\t\tif ((ret = __log_put(env, rlsnp,") >> CFILE + printf("(DBT *)&logrec,\n") >> CFILE + printf("\t\t flags | DB_LOG_NOCOPY)) == 0") >> CFILE + printf(" && txnp != NULL) {\n") >> CFILE + printf("\t\t\t*lsnp = *rlsnp;\n") >> CFILE + + printf("\t\t\tif (rlsnp != ret_lsnp)\n") >> CFILE + printf("\t\t\t\t *ret_lsnp = *rlsnp;\n") >> CFILE + printf("\t\t}\n\t} else {\n") >> CFILE + printf("\t\tret = 0;\n") >> CFILE + printf("#ifdef DIAGNOSTIC\n") >> CFILE + + # Add the debug bit if we are logging a ND record. + printf("\t\t/*\n") >> CFILE + printf("\t\t * Set the debug bit if we are") >> CFILE + printf(" going to log non-durable\n") >> CFILE + printf("\t\t * transactions so they will be ignored") >> CFILE + printf(" by recovery.\n") >> CFILE + printf("\t\t */\n") >> CFILE + printf("\t\tmemcpy(lr->data, logrec.data, ") >> CFILE + printf("logrec.size);\n") >> CFILE + printf("\t\trectype |= DB_debug_FLAG;\n") >> CFILE + printf("\t\tLOGCOPY_32(") >> CFILE + printf("env, logrec.data, &rectype);\n\n") >> CFILE + # Output the log record. + printf("\t\tif (!IS_REP_CLIENT(env))\n") >> CFILE + printf("\t\t\tret = __log_put(env,\n") >> CFILE + printf("\t\t\t rlsnp, (DBT *)&logrec, ") >> CFILE + printf("flags | DB_LOG_NOCOPY);\n") >> CFILE + printf("#endif\n") >> CFILE + # Add a ND record to the txn list. + printf("\t\tSTAILQ_INSERT_HEAD(&txnp") >> CFILE + printf("->logs, lr, links);\n") >> CFILE + printf("\t\tF_SET((TXN_DETAIL *)") >> CFILE + printf("txnp->td, TXN_DTL_INMEMORY);\n") >> CFILE + # Update the return LSN. + printf("\t\tLSN_NOT_LOGGED(*ret_lsnp);\n") >> CFILE + printf("\t}\n\n") >> CFILE + } else { + printf("\tif ((ret = dbenv->log_put(dbenv, rlsnp,") >> CFILE + printf(" (DBT *)&logrec,\n") >> CFILE + printf("\t flags | DB_LOG_NOCOPY)) == 0") >> CFILE + printf(" && txnp != NULL) {\n") >> CFILE + + # Update the transactions last_lsn. + printf("\t\t*lsnp = *rlsnp;\n") >> CFILE + printf("\t\tif (rlsnp != ret_lsnp)\n") >> CFILE + printf("\t\t\t *ret_lsnp = *rlsnp;\n") >> CFILE + printf("\t}\n") >> CFILE + } + + # If out of disk space log writes may fail. If we are debugging + # that print out which records did not make it to disk. + printf("#ifdef LOG_DIAGNOSTIC\n") >> CFILE + printf("\tif (ret != 0)\n") >> CFILE + printf("\t\t(void)%s_print(%s,\n", funcname, env_var) >> CFILE + printf("\t\t (DBT *)&logrec, ret_lsnp, ") >> CFILE + printf("DB_TXN_PRINT%s);\n#endif\n\n",\ + dbprivate ? ", NULL" : "") >> CFILE + # Free and return + if (dbprivate) { + printf("#ifdef DIAGNOSTIC\n") >> CFILE + write_free("\t", "logrec.data", CFILE) + printf("#else\n") >> CFILE + printf("\tif (is_durable || txnp == NULL)\n") >> CFILE + write_free("\t\t", "logrec.data", CFILE) + printf("#endif\n") >> CFILE + } else { + write_free("\t", "logrec.data", CFILE) + } + + printf("\treturn (ret);\n}\n\n") >> CFILE +} + +function log_prototype(fname, with_type) +{ + # Write the log function; function prototype + pi = 1; + p[pi++] = sprintf("int %s_log", fname); + p[pi++] = " "; + if (has_dbp) { + p[pi++] = "__P((DB *"; + } else { + p[pi++] = sprintf("__P((%s *", env_type); + } + p[pi++] = ", DB_TXN *, DB_LSN *, u_int32_t"; + for (i = 0; i < nvars; i++) { + if (modes[i] == "DB") + continue; + p[pi++] = ", "; + p[pi++] = sprintf("%s%s%s", (modes[i] == "DBT" || + modes[i] == "LOCKS" || modes[i] == "PGDBT" || + modes[i] == "PGDDBT") ? "const " : "", types[i], + (modes[i] == "DBT" || modes[i] == "LOCKS" || + modes[i] == "PGDBT" || modes[i] == "PGDDBT") ? " *" : ""); + } + + # If this is a logging call with type, add the type here. + if (with_type) + p[pi++] = ", u_int32_t"; + + p[pi++] = ""; + p[pi++] = "));"; + p[pi++] = ""; + proto_format(p, CFILE); +} + +# If we're logging a DB handle, make sure we have a log +# file ID for it. +function db_handle_id_function(modes, n) +{ + for (i = 0; i < n; i++) + if (modes[i] == "DB") { + # We actually log the DB handle's fileid; from + # that ID we're able to acquire an open handle + # at recovery time. + printf(\ + "\tDB_ASSERT(env, dbp->log_filename != NULL);\n")\ + >> CFILE + printf("\tif (dbp->log_filename->id == ")\ + >> CFILE + printf("DB_LOGFILEID_INVALID &&\n\t ")\ + >> CFILE + printf("(ret = __dbreg_lazy_id(dbp)) != 0)\n")\ + >> CFILE + printf("\t\treturn (ret);\n\n") >> CFILE + break; + } +} + +function print_function() +{ + # Write the print function; function prototype + p[1] = sprintf("int %s_print", funcname); + p[2] = " "; + if (dbprivate) + p[3] = "__P((ENV *, DBT *, DB_LSN *, db_recops, void *));"; + else + p[3] = "__P((DB_ENV *, DBT *, DB_LSN *, db_recops));"; + p[4] = ""; + proto_format(p, PFILE); + + # Function declaration + printf("int\n%s_print(%s, ", funcname, env_var) >> PFILE + printf("dbtp, lsnp, notused2") >> PFILE + if (dbprivate) + printf(", notused3") >> PFILE + printf(")\n") >> PFILE + printf("\t%s *%s;\n", env_type, env_var) >> PFILE + printf("\tDBT *dbtp;\n") >> PFILE + printf("\tDB_LSN *lsnp;\n") >> PFILE + printf("\tdb_recops notused2;\n") >> PFILE + if (dbprivate) + printf("\tvoid *notused3;\n") >> PFILE + printf("{\n") >> PFILE + + # Locals + printf("\t%s_args *argp;\n", funcname) >> PFILE + if (!dbprivate) + printf("\t%s\n", read_proto) >> PFILE + for (i = 0; i < nvars; i ++) + if (modes[i] == "TIME") { + printf("\tstruct tm *lt;\n") >> PFILE + printf("\ttime_t timeval;\n") >> PFILE + printf("\tchar time_buf[CTIME_BUFLEN];\n") >> PFILE + break; + } + for (i = 0; i < nvars; i ++) + if (modes[i] == "DBT" || + modes[i] == "PGDBT" || modes[i] == "PGDDBT") { + printf("\tu_int32_t i;\n") >> PFILE + printf("\tint ch;\n") >> PFILE + break; + } + printf("\tint ret;\n\n") >> PFILE + + # Get rid of complaints about unused parameters. + printf("\tnotused2 = DB_TXN_PRINT;\n") >> PFILE + if (dbprivate) + printf("\tnotused3 = NULL;\n") >> PFILE + printf("\n") >> PFILE + + # Call read routine to initialize structure + if (has_dbp) { + printf("\tif ((ret =\n") >> PFILE + printf(\ + "\t %s_read(%s, NULL, NULL, dbtp->data, &argp)) != 0)\n", + funcname, env_var) >> PFILE + } else { + printf("\tif ((ret = %s_read(%s, dbtp->data, &argp)) != 0)\n", + funcname, env_var) >> PFILE + } + printf("\t\treturn (ret);\n") >> PFILE + + # Print values in every record + printf("\t(void)printf(\n \"[%%lu][%%lu]%s%%s: ", funcname) >> PFILE + printf("rec: %%lu txnp %%lx prevlsn [%%lu][%%lu]\\n\",\n") >> PFILE + printf("\t (u_long)lsnp->file, (u_long)lsnp->offset,\n") >> PFILE + printf("\t (argp->type & DB_debug_FLAG) ? \"_debug\" : \"\",\n")\ + >> PFILE + printf("\t (u_long)argp->type,\n") >> PFILE + printf("\t (u_long)argp->txnp->txnid,\n") >> PFILE + printf("\t (u_long)argp->prev_lsn.file, ") >> PFILE + printf("(u_long)argp->prev_lsn.offset);\n") >> PFILE + + # Now print fields of argp + for (i = 0; i < nvars; i ++) { + if (modes[i] == "TIME") { + printf("\ttimeval = (time_t)argp->%s;\n", + vars[i]) >> PFILE + printf("\tlt = localtime(&timeval);\n") >> PFILE + printf("\t(void)printf(\n\t \"\\t%s: ", + vars[i]) >> PFILE + } else + printf("\t(void)printf(\"\\t%s: ", vars[i]) >> PFILE + + if (modes[i] == "DBT" || + modes[i] == "PGDBT" || modes[i] == "PGDDBT") { + printf("\");\n") >> PFILE + printf("\tfor (i = 0; i < ") >> PFILE + printf("argp->%s.size; i++) {\n", vars[i]) >> PFILE + printf("\t\tch = ((u_int8_t *)argp->%s.data)[i];\n",\ + vars[i]) >> PFILE + printf("\t\tprintf(isprint(ch) || ch == 0x0a") >> PFILE + printf(" ? \"%%c\" : \"%%#x \", ch);\n") >> PFILE + printf("\t}\n\t(void)printf(\"\\n\");\n") >> PFILE + } else if (types[i] == "DB_LSN *") { + printf("[%%%s][%%%s]\\n\",\n",\ + formats[i], formats[i]) >> PFILE + printf("\t (u_long)argp->%s.file,",\ + vars[i]) >> PFILE + printf(" (u_long)argp->%s.offset);\n",\ + vars[i]) >> PFILE + } else if (modes[i] == "TIME") { + # Time values are displayed in two ways: the standard + # string returned by ctime, and in the input format + # expected by db_recover -t. + printf(\ + "%%%s (%%.24s, 20%%02lu%%02lu%%02lu%%02lu%%02lu.%%02lu)\\n\",\n",\ + formats[i]) >> PFILE + printf("\t (long)argp->%s, ", vars[i]) >> PFILE + printf("__os_ctime(&timeval, time_buf),",\ + vars[i]) >> PFILE + printf("\n\t (u_long)lt->tm_year - 100, ") >> PFILE + printf("(u_long)lt->tm_mon+1,") >> PFILE + printf("\n\t (u_long)lt->tm_mday, ") >> PFILE + printf("(u_long)lt->tm_hour,") >> PFILE + printf("\n\t (u_long)lt->tm_min, ") >> PFILE + printf("(u_long)lt->tm_sec);\n") >> PFILE + } else if (modes[i] == "LOCKS") { + printf("\\n\");\n") >> PFILE + printf("\t__lock_list_print(env, &argp->locks);\n")\ + >> PFILE + } else { + if (formats[i] == "lx") + printf("0x") >> PFILE + printf("%%%s\\n\", ", formats[i]) >> PFILE + if (formats[i] == "lx" || formats[i] == "lu") + printf("(u_long)") >> PFILE + if (formats[i] == "ld") + printf("(long)") >> PFILE + printf("argp->%s);\n", vars[i]) >> PFILE + } + } + printf("\t(void)printf(\"\\n\");\n") >> PFILE + write_free("\t", "argp", PFILE); + printf("\treturn (0);\n") >> PFILE + printf("}\n\n") >> PFILE +} + +function read_function() +{ + # Write the read function; function prototype + if (has_dbp) { + p[1] = sprintf("int %s_read __P((%s *, DB **, void *, void *,", + funcname, env_type); + } else { + p[1] = sprintf("int %s_read __P((%s *, void *,", + funcname, env_type); + } + p[2] = " "; + p[3] = sprintf("%s_args **));", funcname); + p[4] = ""; + read_proto = sprintf("%s %s", p[1], p[3]); + proto_format(p, CFILE); + + # Function declaration + if (has_dbp) { + printf("int\n%s_read(%s, dbpp, td, recbuf, argpp)\n", + funcname, env_var) >> CFILE + } else { + printf("int\n%s_read(%s, recbuf, argpp)\n", + funcname, env_var) >> CFILE + } + + # Now print the parameters + printf("\t%s *%s;\n", env_type, env_var) >> CFILE + if (has_dbp) { + printf("\tDB **dbpp;\n") >> CFILE + printf("\tvoid *td;\n") >> CFILE + } + printf("\tvoid *recbuf;\n") >> CFILE + printf("\t%s_args **argpp;\n", funcname) >> CFILE + + # Function body and local decls + printf("{\n\t%s_args *argp;\n", funcname) >> CFILE + if (is_uint) + printf("\tu_int32_t uinttmp;\n") >> CFILE + printf("\tu_int8_t *bp;\n") >> CFILE + + if (dbprivate) { + # We only use ret in the private malloc case. + printf("\tint ret;\n\n") >> CFILE + } else { + printf("\tENV *env;\n\n") >> CFILE + printf("\tenv = dbenv->env;\n\n") >> CFILE + } + + malloc_size = sprintf("sizeof(%s_args) + sizeof(DB_TXN)", funcname) + write_malloc("\t", "argp", malloc_size, CFILE) + + # Set up the pointers to the DB_TXN *. + printf("\tbp = recbuf;\n") >> CFILE + + printf("\targp->txnp = (DB_TXN *)&argp[1];\n") >> CFILE + printf("\tmemset(argp->txnp, 0, sizeof(DB_TXN));\n\n")\ + >> CFILE + if (has_dbp) + printf("\targp->txnp->td = td;\n") >> CFILE + + # First get the record type, prev_lsn, and txnp fields. + printf("\tLOGCOPY_32(env, &argp->type, bp);\n") >> CFILE + printf("\tbp += sizeof(argp->type);\n\n") >> CFILE + printf("\tLOGCOPY_32(env, &argp->txnp->txnid, bp);\n") >> CFILE + printf("\tbp += sizeof(argp->txnp->txnid);\n\n") >> CFILE + printf("\tLOGCOPY_TOLSN(env, &argp->prev_lsn, bp);\n") >> CFILE + printf("\tbp += sizeof(DB_LSN);\n\n") >> CFILE + + # Now get rest of data. + for (i = 0; i < nvars; i ++) { + if (modes[i] == "DBT" || modes[i] == "LOCKS" || + modes[i] == "PGDBT" || modes[i] == "PGDDBT") { + printf("\tmemset(&argp->%s, 0, sizeof(argp->%s));\n",\ + vars[i], vars[i]) >> CFILE + printf("\tLOGCOPY_32(env,") >> CFILE + printf("&argp->%s.size, bp);\n", vars[i]) >> CFILE + printf("\tbp += sizeof(u_int32_t);\n") >> CFILE + printf("\targp->%s.data = bp;\n", vars[i]) >> CFILE + printf("\tbp += argp->%s.size;\n", vars[i]) >> CFILE + if (modes[i] == "PGDBT" && ddbt == "NULL" && + !is_compat) { + printf("\tif (LOG_SWAPPED(env) && ") >> CFILE + printf("dbpp != NULL && ") >> CFILE + printf("*dbpp != NULL) {\n") >> CFILE + printf("\t\tint t_ret;\n") >> CFILE + printf(\ + "\t\tif ((t_ret = __db_pageswap(*dbpp, (PAGE *)argp->%s.data,\n", + vars[i]) >> CFILE + printf(\ + "\t\t (size_t)argp->%s.size, NULL, 1)) != 0)\n", + vars[i]) >> CFILE + printf("\t\t\treturn (t_ret);\n") >> CFILE + printf("\t}\n") >> CFILE + } else if (modes[i] == "PGDDBT" && !is_compat) { + printf("\tif (LOG_SWAPPED(env) && ") >> CFILE + printf("dbpp != NULL && ") >> CFILE + printf("*dbpp != NULL) {\n") >> CFILE + printf("\t\tint t_ret;\n") >> CFILE + printf(\ + "\t\tif ((t_ret = __db_pageswap(*dbpp,\n") >> CFILE + printf(\ + "\t\t (PAGE *)argp->%s.data, (size_t)argp->%s.size,\n", + hdrdbt, hdrdbt) >> CFILE + printf("\t\t &argp->%s, 1)) != 0)\n", + vars[i]) >> CFILE + printf("\t\t\treturn (t_ret);\n") >> CFILE + printf("\t}\n") >> CFILE + } + } else if (modes[i] == "ARG" || modes[i] == "TIME" || + modes[i] == "DB") { + if (types[i] == "u_int32_t") { + printf("\tLOGCOPY_32(env, &argp->%s, bp);\n", + vars[i]) >> CFILE + printf("\tbp += sizeof(argp->%s);\n", vars[i])\ + >> CFILE + } else { + printf("\tLOGCOPY_32(env, &uinttmp, bp);\n")\ + >> CFILE + printf("\targp->%s = (%s)uinttmp;\n", vars[i],\ + types[i]) >> CFILE + printf("\tbp += sizeof(uinttmp);\n") >> CFILE + } + + if (modes[i] == "DB") { + # We can now get the DB handle. + printf("\tif (dbpp != NULL) {\n") >> CFILE + printf("\t\t*dbpp = NULL;\n") >> CFILE + printf(\ + "\t\tret = __dbreg_id_to_db(\n\t\t ") >> CFILE + printf("env, argp->txnp, dbpp, argp->%s, 1);\n", + vars[i]) >> CFILE + printf("\t}\n") >> CFILE + } + } else if (types[i] == "DB_LSN *") { + printf("\tLOGCOPY_TOLSN(env, &argp->%s, bp);\n", + vars[i]) >> CFILE + printf("\tbp += sizeof(DB_LSN);\n", vars[i]) >> CFILE + } else { # POINTER + printf("\tDB_ASSERT(env, sizeof(argp->%s) == 4);", + vars[i]) >> CFILE + printf("\tLOGCOPY_32(env, &argp->%s, bp);", + vars[i]) >> CFILE + printf("\tbp += sizeof(argp->%s);\n", vars[i]) >> CFILE + } + printf("\n") >> CFILE + } + + printf("\t*argpp = argp;\n") >> CFILE + if (dbprivate) + printf("\treturn (ret);\n}\n\n") >> CFILE + else + printf("\treturn (0);\n}\n\n") >> CFILE +} + +# proto_format -- +# Pretty-print a function prototype. +function proto_format(p, fp) +{ + printf("/*\n") >> fp; + + s = ""; + for (i = 1; i in p; ++i) + s = s p[i]; + + t = " * PUBLIC: " + if (length(s) + length(t) < 80) + printf("%s%s", t, s) >> fp; + else { + split(s, p, "__P"); + len = length(t) + length(p[1]); + printf("%s%s", t, p[1]) >> fp + + n = split(p[2], comma, ","); + comma[1] = "__P" comma[1]; + for (i = 1; i <= n; i++) { + if (len + length(comma[i]) > 70) { + printf("\n * PUBLIC: ") >> fp; + len = 0; + } + printf("%s%s", comma[i], i == n ? "" : ",") >> fp; + len += length(comma[i]) + 2; + } + } + printf("\n */\n") >> fp; + delete p; +} + +function write_malloc(tab, ptr, size, file) +{ + if (dbprivate) { + print(tab "if ((ret = __os_malloc(env,") >> file + print(tab " " size ", &" ptr ")) != 0)") >> file + print(tab "\treturn (ret);") >> file; + } else { + print(tab "if ((" ptr " = malloc(" size ")) == NULL)") >> file + print(tab "\treturn (ENOMEM);") >> file + } +} + +function write_free(tab, ptr, file) +{ + if (dbprivate) { + print(tab "__os_free(env, " ptr ");") >> file + } else { + print(tab "free(" ptr ");") >> file + } +} + +function make_name(unique_name, dup_name, p_version) +{ + logfunc = sprintf("%s_%s", prefix, unique_name); + logname[num_funcs] = logfunc; + if (is_compat) { + funcname = sprintf("%s_%s_%s", prefix, unique_name, p_version); + } else { + funcname = logfunc; + } + + if (is_duplicate) + dupfuncs[num_funcs] = dup_name; + else + dupfuncs[num_funcs] = funcname; + + funcs[num_funcs] = funcname; + functable[num_funcs] = is_compat; + ++num_funcs; +} + +function log_funcdecl(name, withtype) +{ + # Function declaration + if (has_dbp) { + printf("int\n%s_log(dbp, txnp, ret_lsnp, flags",\ + name) >> CFILE + } else { + printf("int\n%s_log(%s, txnp, ret_lsnp, flags",\ + name, env_var) >> CFILE + } + for (i = 0; i < nvars; i++) { + if (modes[i] == "DB") { + # We pass in fileids on the dbp, so if this is one, + # skip it. + continue; + } + printf(",") >> CFILE + if ((i % 6) == 0) + printf("\n ") >> CFILE + else + printf(" ") >> CFILE + printf("%s", vars[i]) >> CFILE + } + + if (withtype) + printf(", type") >> CFILE + + printf(")\n") >> CFILE + + # Now print the parameters + if (has_dbp) { + printf("\tDB *dbp;\n") >> CFILE + } else { + printf("\t%s *%s;\n", env_type, env_var) >> CFILE + } + printf("\tDB_TXN *txnp;\n\tDB_LSN *ret_lsnp;\n") >> CFILE + printf("\tu_int32_t flags;\n") >> CFILE + for (i = 0; i < nvars; i++) { + # We just skip for modes == DB. + if (modes[i] == "DBT" || modes[i] == "LOCKS" || + modes[i] == "PGDBT" || modes[i] == "PGDDBT") + printf("\tconst %s *%s;\n", types[i], vars[i]) >> CFILE + else if (modes[i] != "DB") + printf("\t%s %s;\n", types[i], vars[i]) >> CFILE + } + if (withtype) + printf("\tu_int32_t type;\n") >> CFILE +} + +function log_callint(fname) +{ + if (has_dbp) { + printf("\n{\n\treturn (%s_log(dbp, txnp, ret_lsnp, flags",\ + internal_name) >> CFILE + } else { + printf("\n{\n\treturn (%s_log(%s, txnp, ret_lsnp, flags",\ + internal_name, env_var) >> CFILE + } + + for (i = 0; i < nvars; i++) { + if (modes[i] == "DB") { + # We pass in fileids on the dbp, so if this is one, + # skip it. + continue; + } + printf(",") >> CFILE + if ((i % 6) == 0) + printf("\n ") >> CFILE + else + printf(" ") >> CFILE + printf("%s", vars[i]) >> CFILE + } + + printf(", DB_%s", fname) >> CFILE + printf("));\n}\n") >> CFILE +} diff --git a/src/libs/resiprocate/contrib/db/dist/gen_rpc.awk b/src/libs/resiprocate/contrib/db/dist/gen_rpc.awk new file mode 100644 index 00000000..6c542c9c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/gen_rpc.awk @@ -0,0 +1,1187 @@ +# +# $Id$ +# Awk script for generating client/server RPC code. +# +# This awk script generates most of the RPC routines for DB client/server +# use. It also generates a template for server and client procedures. These +# functions must still be edited, but are highly stylized and the initial +# template gets you a fair way along the path). +# +# This awk script requires that these variables be set when it is called: +# +# major -- Major version number +# minor -- Minor version number +# gidsize -- size of GIDs +# client_file -- the C source file being created for client code +# ctmpl_file -- the C template file being created for client code +# server_file -- the C source file being created for server code +# stmpl_file -- the C template file being created for server code +# xdr_file -- the XDR message file created +# +# And stdin must be the input file that defines the RPC setup. +BEGIN { + if (major == "" || minor == "" || gidsize == "" || + client_file == "" || ctmpl_file == "" || + server_file == "" || stmpl_file == "" || xdr_file == "") { + print "Usage: gen_rpc.awk requires these variables be set:" + print "\tmajor\t-- Major version number" + print "\tminor\t-- Minor version number" + print "\tgidsize\t-- GID size" + print "\tclient_file\t-- the client C source file being created" + print "\tctmpl_file\t-- the client template file being created" + print "\tserver_file\t-- the server C source file being created" + print "\tstmpl_file\t-- the server template file being created" + print "\txdr_file\t-- the XDR message file being created" + error = 1; exit + } + + FS="\t\t*" + CFILE=client_file + printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ + > CFILE + + TFILE = ctmpl_file + printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ + > TFILE + + SFILE = server_file + printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ + > SFILE + + # Server procedure template. + PFILE = stmpl_file + XFILE = xdr_file + printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ + > XFILE + nendlist = 1; + + # Output headers + general_headers() + + # Put out the actual illegal and no-server functions. + illegal_functions(CFILE) +} +END { + if (error == 0) { + printf("program DB_RPC_SERVERPROG {\n") >> XFILE + printf("\tversion DB_RPC_SERVERVERS {\n") >> XFILE + + for (i = 1; i < nendlist; ++i) + printf("\t\t%s;\n", endlist[i]) >> XFILE + + printf("\t} = %d%03d;\n", major, minor) >> XFILE + printf("} = 351457;\n") >> XFILE + + obj_init("DB", "dbp", obj_db, CFILE) + obj_init("DBC", "dbc", obj_dbc, CFILE) + obj_init("DB_ENV", "dbenv", obj_dbenv, CFILE) + obj_init("DB_TXN", "txn", obj_txn, CFILE) + } +} + +/^[ ]*LOCAL/ { + # LOCAL methods are ones where we don't override the handle + # method for RPC, nor is it illegal -- it's just satisfied + # locally. + next; +} +/^[ ]*NOFUNC/ { + ++obj_indx; + + # NOFUNC methods are illegal on the RPC client. + if ($2 ~ "^db_") + obj_illegal(obj_db, "dbp", $2, $3) + else if ($2 ~ "^dbc_") + obj_illegal(obj_dbc, "dbc", $2, $3) + else if ($2 ~ "^env_") + obj_illegal(obj_dbenv, "dbenv", $2, $3) + else if ($2 ~ "^txn_") + obj_illegal(obj_txn, "txn", $2, $3) + else { + print "unexpected handle prefix: " $2 + error = 1; exit + } + next; +} +/^[ ]*BEGIN/ { + ++obj_indx; + + name = $2; + link_only = ret_code = 0 + if ($3 == "LINKONLY") + link_only = 1 + else if ($3 == "RETCODE") + ret_code = 1 + + funcvars = 0; + newvars = 0; + nvars = 0; + rvars = 0; + xdr_free = 0; + + db_handle = 0; + dbc_handle = 0; + dbt_handle = 0; + env_handle = 0; + mp_handle = 0; + txn_handle = 0; +} +/^[ ]*ARG/ { + rpc_type[nvars] = $2; + c_type[nvars] = $3; + pr_type[nvars] = $3; + args[nvars] = $4; + func_arg[nvars] = 0; + if (rpc_type[nvars] == "LIST") { + list_type[nvars] = $5; + } else + list_type[nvars] = 0; + + if (c_type[nvars] == "DBT *") + dbt_handle = 1; + else if (c_type[nvars] == "DB_ENV *") { + ctp_type[nvars] = "CT_ENV"; + env_handle = 1; + env_idx = nvars; + + if (nvars == 0) + obj_func("dbenv", obj_dbenv); + } else if (c_type[nvars] == "DB *") { + ctp_type[nvars] = "CT_DB"; + if (db_handle != 1) { + db_handle = 1; + db_idx = nvars; + } + + if (nvars == 0) + obj_func("dbp", obj_db); + } else if (c_type[nvars] == "DBC *") { + ctp_type[nvars] = "CT_CURSOR"; + dbc_handle = 1; + dbc_idx = nvars; + + if (nvars == 0) + obj_func("dbc", obj_dbc); + } else if (c_type[nvars] == "DB_TXN *") { + ctp_type[nvars] = "CT_TXN"; + txn_handle = 1; + txn_idx = nvars; + + if (nvars == 0) + obj_func("txn", obj_txn); + } + + ++nvars; +} +/^[ ]*FUNCPROT/ { + pr_type[nvars] = $2; +} +/^[ ]*FUNCARG/ { + rpc_type[nvars] = "IGNORE"; + c_type[nvars] = $2; + args[nvars] = sprintf("func%d", funcvars); + func_arg[nvars] = 1; + ++funcvars; + ++nvars; +} +/^[ ]*RET/ { + ret_type[rvars] = $2; + retc_type[rvars] = $3; + retargs[rvars] = $4; + if (ret_type[rvars] == "LIST" || ret_type[rvars] == "DBT") { + xdr_free = 1; + } + if (ret_type[rvars] == "LIST") { + retlist_type[rvars] = $5; + } else + retlist_type[rvars] = 0; + ret_isarg[rvars] = 0; + + ++rvars; +} +/^[ ]*ARET/ { + ret_type[rvars] = $2; + rpc_type[nvars] = "IGNORE"; + retc_type[rvars] = $3; + c_type[nvars] = sprintf("%s *", $3); + pr_type[nvars] = c_type[nvars]; + retargs[rvars] = $4; + args[nvars] = sprintf("%sp", $4); + if (ret_type[rvars] == "LIST" || ret_type[rvars] == "DBT") { + xdr_free = 1; + } + func_arg[nvars] = 0; + if (ret_type[nvars] == "LIST") { + retlist_type[rvars] = $5; + list_type[nvars] = $5; + } else { + retlist_type[rvars] = 0; + list_type[nvars] = 0; + } + ret_isarg[rvars] = 1; + + ++nvars; + ++rvars; +} +/^[ ]*END/ { + # + # ===================================================== + # LINKONLY -- just reference the function, that's all. + # + if (link_only) + next; + + # + # ===================================================== + # XDR messages. + # + printf("\n") >> XFILE + printf("struct __%s_msg {\n", name) >> XFILE + for (i = 0; i < nvars; ++i) { + if (rpc_type[i] == "LIST") { + if (list_type[i] == "GID") { + printf("\topaque %s<>;\n", args[i]) >> XFILE + } else { + printf("\tunsigned int %s<>;\n", args[i]) >> XFILE + } + } + if (rpc_type[i] == "ID") { + printf("\tunsigned int %scl_id;\n", args[i]) >> XFILE + } + if (rpc_type[i] == "STRING") { + printf("\tstring %s<>;\n", args[i]) >> XFILE + } + if (rpc_type[i] == "GID") { + printf("\topaque %s[%d];\n", args[i], gidsize) >> XFILE + } + if (rpc_type[i] == "INT") { + printf("\tunsigned int %s;\n", args[i]) >> XFILE + } + if (rpc_type[i] == "DBT") { + printf("\tunsigned int %sdlen;\n", args[i]) >> XFILE + printf("\tunsigned int %sdoff;\n", args[i]) >> XFILE + printf("\tunsigned int %sulen;\n", args[i]) >> XFILE + printf("\tunsigned int %sflags;\n", args[i]) >> XFILE + printf("\topaque %sdata<>;\n", args[i]) >> XFILE + } + } + printf("};\n") >> XFILE + + printf("\n") >> XFILE + # + # Generate the reply message + # + printf("struct __%s_reply {\n", name) >> XFILE + printf("\t/* num return vars: %d */\n", rvars) >> XFILE + printf("\tint status;\n") >> XFILE + for (i = 0; i < rvars; ++i) { + if (ret_type[i] == "ID") { + printf("\tunsigned int %scl_id;\n", retargs[i]) >> XFILE + } + if (ret_type[i] == "STRING") { + printf("\tstring %s<>;\n", retargs[i]) >> XFILE + } + if (ret_type[i] == "INT") { + printf("\tunsigned int %s;\n", retargs[i]) >> XFILE + } + if (ret_type[i] == "DBL") { + printf("\tdouble %s;\n", retargs[i]) >> XFILE + } + if (ret_type[i] == "DBT") { + printf("\topaque %sdata<>;\n", retargs[i]) >> XFILE + } + if (ret_type[i] == "LIST") { + if (retlist_type[i] == "GID") { + printf("\topaque %s<>;\n", retargs[i]) >> XFILE + } else { + printf("\tunsigned int %s<>;\n", retargs[i]) >> XFILE + } + } + } + printf("};\n") >> XFILE + + endlist[nendlist] = \ + sprintf("__%s_reply __DB_%s(__%s_msg) = %d", \ + name, name, name, nendlist); + nendlist++; + # + # ===================================================== + # Server functions. + # + # First spit out PUBLIC prototypes for server functions. + # + printf("__%s_reply *\n", name) >> SFILE + printf("__db_%s_%d%03d__SVCSUFFIX__(msg, req)\n", \ + name, major, minor) >> SFILE + printf("\t__%s_msg *msg;\n", name) >> SFILE; + printf("\tstruct svc_req *req;\n", name) >> SFILE; + printf("{\n") >> SFILE + printf("\tstatic __%s_reply reply; /* must be static */\n", \ + name) >> SFILE + if (xdr_free) { + printf("\tstatic int __%s_free = 0; /* must be static */\n\n", \ + name) >> SFILE + } + printf("\tCOMPQUIET(req, NULL);\n", name) >> SFILE + if (xdr_free) { + printf("\tif (__%s_free)\n", name) >> SFILE + printf("\t\txdr_free((xdrproc_t)xdr___%s_reply, (void *)&reply);\n", \ + name) >> SFILE + printf("\t__%s_free = 0;\n", name) >> SFILE + printf("\n\t/* Reinitialize allocated fields */\n") >> SFILE + for (i = 0; i < rvars; ++i) { + if (ret_type[i] == "LIST") { + printf("\treply.%s.%s_val = NULL;\n", \ + retargs[i], retargs[i]) >> SFILE + } + if (ret_type[i] == "DBT") { + printf("\treply.%sdata.%sdata_val = NULL;\n", \ + retargs[i], retargs[i]) >> SFILE + } + } + } + + need_out = 0; + # + # Compose server proc to call. Decompose message components as args. + # + printf("\n\t__%s_proc(", name) >> SFILE + sep = ""; + for (i = 0; i < nvars; ++i) { + if (rpc_type[i] == "IGNORE") { + continue; + } + if (rpc_type[i] == "ID") { + printf("%smsg->%scl_id", sep, args[i]) >> SFILE + } + if (rpc_type[i] == "STRING") { + printf("%s(*msg->%s == '\\0') ? NULL : msg->%s", \ + sep, args[i], args[i]) >> SFILE + } + if (rpc_type[i] == "GID") { + printf("%s(u_int8_t *)msg->%s", sep, args[i]) >> SFILE + } + if (rpc_type[i] == "INT") { + printf("%smsg->%s", sep, args[i]) >> SFILE + } + if (rpc_type[i] == "LIST") { + printf("%smsg->%s.%s_val", \ + sep, args[i], args[i]) >> SFILE + printf("%smsg->%s.%s_len", \ + sep, args[i], args[i]) >> SFILE + } + if (rpc_type[i] == "DBT") { + printf("%smsg->%sdlen", sep, args[i]) >> SFILE + sep = ",\n\t "; + printf("%smsg->%sdoff", sep, args[i]) >> SFILE + printf("%smsg->%sulen", sep, args[i]) >> SFILE + printf("%smsg->%sflags", sep, args[i]) >> SFILE + printf("%smsg->%sdata.%sdata_val", \ + sep, args[i], args[i]) >> SFILE + printf("%smsg->%sdata.%sdata_len", \ + sep, args[i], args[i]) >> SFILE + } + sep = ",\n\t "; + } + printf("%s&reply", sep) >> SFILE + if (xdr_free) + printf("%s&__%s_free);\n", sep, name) >> SFILE + else + printf(");\n\n") >> SFILE + if (need_out) { + printf("\nout:\n") >> SFILE + } + printf("\treturn (&reply);\n") >> SFILE + printf("}\n\n") >> SFILE + + # + # ===================================================== + # Generate Procedure Template Server code + # + # Spit out comment, prototype, function name and arg list. + printf("/* BEGIN __%s_proc */\n", name) >> PFILE + delete p; + pi = 1; + p[pi++] = sprintf("void __%s_proc __P((", name); + p[pi++] = ""; + for (i = 0; i < nvars; ++i) { + if (rpc_type[i] == "IGNORE") + continue; + if (rpc_type[i] == "ID") { + p[pi++] = "long"; + p[pi++] = ", "; + } + if (rpc_type[i] == "STRING") { + p[pi++] = "char *"; + p[pi++] = ", "; + } + if (rpc_type[i] == "GID") { + p[pi++] = "u_int8_t *"; + p[pi++] = ", "; + } + if (rpc_type[i] == "INT") { + p[pi++] = "u_int32_t"; + p[pi++] = ", "; + } + if (rpc_type[i] == "INTRET") { + p[pi++] = "u_int32_t *"; + p[pi++] = ", "; + } + if (rpc_type[i] == "LIST" && list_type[i] == "GID") { + p[pi++] = "u_int8_t *"; + p[pi++] = ", "; + p[pi++] = "u_int32_t"; + p[pi++] = ", "; + } + if (rpc_type[i] == "LIST" && list_type[i] == "INT") { + p[pi++] = "u_int32_t *"; + p[pi++] = ", "; + p[pi++] = "u_int32_t"; + p[pi++] = ", "; + } + if (rpc_type[i] == "LIST" && list_type[i] == "ID") { + p[pi++] = "u_int32_t *"; + p[pi++] = ", "; + p[pi++] = "u_int32_t"; + p[pi++] = ", "; + } + if (rpc_type[i] == "DBT") { + p[pi++] = "u_int32_t"; + p[pi++] = ", "; + p[pi++] = "u_int32_t"; + p[pi++] = ", "; + p[pi++] = "u_int32_t"; + p[pi++] = ", "; + p[pi++] = "u_int32_t"; + p[pi++] = ", "; + p[pi++] = "void *"; + p[pi++] = ", "; + p[pi++] = "u_int32_t"; + p[pi++] = ", "; + } + } + p[pi++] = sprintf("__%s_reply *", name); + if (xdr_free) { + p[pi++] = ", "; + p[pi++] = "int *));"; + } else { + p[pi++] = ""; + p[pi++] = "));"; + } + p[pi++] = ""; + + printf("void\n") >> PFILE + printf("__%s_proc(", name) >> PFILE + sep = ""; + argcount = 0; + for (i = 0; i < nvars; ++i) { + argcount++; + split_lines(); + if (argcount == 0) { + sep = ""; + } + if (rpc_type[i] == "IGNORE") + continue; + if (rpc_type[i] == "ID") { + printf("%s%scl_id", sep, args[i]) >> PFILE + } + if (rpc_type[i] == "STRING") { + printf("%s%s", sep, args[i]) >> PFILE + } + if (rpc_type[i] == "GID") { + printf("%s%s", sep, args[i]) >> PFILE + } + if (rpc_type[i] == "INT") { + printf("%s%s", sep, args[i]) >> PFILE + } + if (rpc_type[i] == "INTRET") { + printf("%s%s", sep, args[i]) >> PFILE + } + if (rpc_type[i] == "LIST") { + printf("%s%s", sep, args[i]) >> PFILE + argcount++; + split_lines(); + if (argcount == 0) { + sep = ""; + } else { + sep = ", "; + } + printf("%s%slen", sep, args[i]) >> PFILE + } + if (rpc_type[i] == "DBT") { + printf("%s%sdlen", sep, args[i]) >> PFILE + sep = ", "; + argcount++; + split_lines(); + if (argcount == 0) { + sep = ""; + } else { + sep = ", "; + } + printf("%s%sdoff", sep, args[i]) >> PFILE + argcount++; + split_lines(); + if (argcount == 0) { + sep = ""; + } else { + sep = ", "; + } + printf("%s%sulen", sep, args[i]) >> PFILE + argcount++; + split_lines(); + if (argcount == 0) { + sep = ""; + } else { + sep = ", "; + } + printf("%s%sflags", sep, args[i]) >> PFILE + argcount++; + split_lines(); + if (argcount == 0) { + sep = ""; + } else { + sep = ", "; + } + printf("%s%sdata", sep, args[i]) >> PFILE + argcount++; + split_lines(); + if (argcount == 0) { + sep = ""; + } else { + sep = ", "; + } + printf("%s%ssize", sep, args[i]) >> PFILE + } + sep = ", "; + } + printf("%sreplyp",sep) >> PFILE + if (xdr_free) { + printf("%sfreep)\n",sep) >> PFILE + } else { + printf(")\n") >> PFILE + } + # + # Spit out arg types/names; + # + for (i = 0; i < nvars; ++i) { + if (rpc_type[i] == "ID") { + printf("\tunsigned int %scl_id;\n", args[i]) >> PFILE + } + if (rpc_type[i] == "STRING") { + printf("\tchar *%s;\n", args[i]) >> PFILE + } + if (rpc_type[i] == "GID") { + printf("\tu_int8_t *%s;\n", args[i]) >> PFILE + } + if (rpc_type[i] == "INT") { + printf("\tu_int32_t %s;\n", args[i]) >> PFILE + } + if (rpc_type[i] == "LIST" && list_type[i] == "GID") { + printf("\tu_int8_t * %s;\n", args[i]) >> PFILE + } + if (rpc_type[i] == "LIST" && list_type[i] == "INT") { + printf("\tu_int32_t * %s;\n", args[i]) >> PFILE + printf("\tu_int32_t %ssize;\n", args[i]) >> PFILE + } + if (rpc_type[i] == "LIST" && list_type[i] == "ID") { + printf("\tu_int32_t * %s;\n", args[i]) >> PFILE + } + if (rpc_type[i] == "LIST") { + printf("\tu_int32_t %slen;\n", args[i]) >> PFILE + } + if (rpc_type[i] == "DBT") { + printf("\tu_int32_t %sdlen;\n", args[i]) >> PFILE + printf("\tu_int32_t %sdoff;\n", args[i]) >> PFILE + printf("\tu_int32_t %sulen;\n", args[i]) >> PFILE + printf("\tu_int32_t %sflags;\n", args[i]) >> PFILE + printf("\tvoid *%sdata;\n", args[i]) >> PFILE + printf("\tu_int32_t %ssize;\n", args[i]) >> PFILE + } + } + printf("\t__%s_reply *replyp;\n",name) >> PFILE + if (xdr_free) { + printf("\tint * freep;\n") >> PFILE + } + + printf("/* END __%s_proc */\n", name) >> PFILE + + # + # Function body + # + printf("{\n") >> PFILE + printf("\tint ret;\n") >> PFILE + for (i = 0; i < nvars; ++i) { + if (rpc_type[i] == "ID") { + printf("\t%s %s;\n", c_type[i], args[i]) >> PFILE + printf("\tct_entry *%s_ctp;\n", args[i]) >> PFILE + } + } + printf("\n") >> PFILE + for (i = 0; i < nvars; ++i) { + if (rpc_type[i] == "ID") { + printf("\tACTIVATE_CTP(%s_ctp, %scl_id, %s);\n", \ + args[i], args[i], ctp_type[i]) >> PFILE + printf("\t%s = (%s)%s_ctp->ct_anyp;\n", \ + args[i], c_type[i], args[i]) >> PFILE + } + } + printf("\n\t/*\n\t * XXX Code goes here\n\t */\n\n") >> PFILE + printf("\treplyp->status = ret;\n") >> PFILE + printf("\treturn;\n") >> PFILE + printf("}\n\n") >> PFILE + + # + # ===================================================== + # Generate Client code + # + # Spit out PUBLIC prototypes. + # + delete p; + pi = 1; + p[pi++] = sprintf("int __dbcl_%s __P((", name); + p[pi++] = ""; + for (i = 0; i < nvars; ++i) { + p[pi++] = pr_type[i]; + p[pi++] = ", "; + } + p[pi - 1] = ""; + p[pi] = "));"; + proto_format(p, CFILE); + + # + # Spit out function name/args. + # + printf("int\n") >> CFILE + printf("__dbcl_%s(", name) >> CFILE + sep = ""; + for (i = 0; i < nvars; ++i) { + printf("%s%s", sep, args[i]) >> CFILE + sep = ", "; + } + printf(")\n") >> CFILE + + for (i = 0; i < nvars; ++i) + if (func_arg[i] == 0) + printf("\t%s %s;\n", c_type[i], args[i]) >> CFILE + else + printf("\t%s;\n", c_type[i]) >> CFILE + + printf("{\n") >> CFILE + printf("\tCLIENT *cl;\n") >> CFILE + printf("\t__%s_msg msg;\n", name) >> CFILE + printf("\t__%s_reply *replyp = NULL;\n", name) >> CFILE; + printf("\tint ret;\n") >> CFILE + if (!env_handle) + printf("\tDB_ENV *dbenv;\n") >> CFILE + # + # If we are managing a list, we need a few more vars. + # + for (i = 0; i < nvars; ++i) { + if (rpc_type[i] == "LIST") { + printf("\t%s %sp;\n", c_type[i], args[i]) >> CFILE + printf("\tint %si;\n", args[i]) >> CFILE + if (list_type[i] == "GID") + printf("\tu_int8_t ** %sq;\n", args[i]) >> CFILE + else + printf("\tu_int32_t * %sq;\n", args[i]) >> CFILE + } + } + + printf("\n") >> CFILE + printf("\tret = 0;\n") >> CFILE + if (!env_handle) { + if (db_handle) + printf("\tdbenv = %s->dbenv;\n", args[db_idx]) >> CFILE + else if (dbc_handle) + printf("\tdbenv = %s->dbenv;\n", \ + args[dbc_idx]) >> CFILE + else if (txn_handle) + printf("\tdbenv = %s->mgrp->env->dbenv;\n", \ + args[txn_idx]) >> CFILE + else + printf("\tdbenv = NULL;\n") >> CFILE + printf("\tif (dbenv == NULL || !RPC_ON(dbenv))\n") >> CFILE + printf("\t\treturn (__dbcl_noserver(NULL));\n") >> CFILE + } else { + printf("\tif (%s == NULL || !RPC_ON(%s))\n", \ + args[env_idx], args[env_idx]) >> CFILE + printf("\t\treturn (__dbcl_noserver(%s));\n", \ + args[env_idx]) >> CFILE + } + printf("\n") >> CFILE + + printf("\tcl = (CLIENT *)%s->cl_handle;\n\n", \ + env_handle ? args[env_idx] : "dbenv") >> CFILE + + # + # If there is a function arg, check that it is NULL + # + for (i = 0; i < nvars; ++i) { + if (func_arg[i] != 1) + continue; + printf("\tif (%s != NULL) {\n", args[i]) >> CFILE + if (!env_handle) { + printf("\t\t__db_errx(dbenv->env, ") >> CFILE + } else { + printf(\ + "\t\t__db_errx(%s->env, ", args[env_idx]) >> CFILE + } + printf("\"User functions not supported in RPC\");\n") >> CFILE + printf("\t\treturn (EINVAL);\n\t}\n") >> CFILE + } + + # + # Compose message components + # + for (i = 0; i < nvars; ++i) { + if (rpc_type[i] == "ID") { + # We don't need to check for a NULL DB_ENV *, because + # we already checked for it. I frankly couldn't care + # less, but lint gets all upset at the wasted cycles. + if (c_type[i] != "DB_ENV *") { + printf("\tif (%s == NULL)\n", args[i]) >> CFILE + printf("\t\tmsg.%scl_id = 0;\n\telse\n", \ + args[i]) >> CFILE + indent = "\t\t"; + } else + indent = "\t"; + if (c_type[i] == "DB_TXN *") { + printf("%smsg.%scl_id = %s->txnid;\n", \ + indent, args[i], args[i]) >> CFILE + } else { + printf("%smsg.%scl_id = %s->cl_id;\n", \ + indent, args[i], args[i]) >> CFILE + } + } + if (rpc_type[i] == "GID") { + printf("\tmemcpy(msg.%s, %s, %d);\n", \ + args[i], args[i], gidsize) >> CFILE + } + if (rpc_type[i] == "INT") { + printf("\tmsg.%s = (u_int)%s;\n", + args[i], args[i]) >> CFILE + } + if (rpc_type[i] == "STRING") { + printf("\tif (%s == NULL)\n", args[i]) >> CFILE + printf("\t\tmsg.%s = \"\";\n", args[i]) >> CFILE + printf("\telse\n") >> CFILE + printf("\t\tmsg.%s = (char *)%s;\n", \ + args[i], args[i]) >> CFILE + } + if (rpc_type[i] == "DBT") { + printf("\tmsg.%sdlen = %s->dlen;\n", \ + args[i], args[i]) >> CFILE + printf("\tmsg.%sdoff = %s->doff;\n", \ + args[i], args[i]) >> CFILE + printf("\tmsg.%sulen = %s->ulen;\n", \ + args[i], args[i]) >> CFILE + printf("\tmsg.%sflags = %s->flags;\n", \ + args[i], args[i]) >> CFILE + printf("\tmsg.%sdata.%sdata_val = %s->data;\n", \ + args[i], args[i], args[i]) >> CFILE + printf("\tmsg.%sdata.%sdata_len = %s->size;\n", \ + args[i], args[i], args[i]) >> CFILE + } + if (rpc_type[i] == "LIST") { + printf("\tfor (%si = 0, %sp = %s; *%sp != 0; ", \ + args[i], args[i], args[i], args[i]) >> CFILE + printf(" %si++, %sp++)\n\t\t;\n", args[i], args[i]) \ + >> CFILE + + # + # If we are an array of ints, *_len is how many + # elements. If we are a GID, *_len is total bytes. + # + printf("\tmsg.%s.%s_len = (u_int)%si", + args[i], args[i], args[i]) >> CFILE + if (list_type[i] == "GID") + printf(" * %d;\n", gidsize) >> CFILE + else + printf(";\n") >> CFILE + printf("\tif ((ret = __os_calloc(") >> CFILE + if (!env_handle) + printf("dbenv->env,\n") >> CFILE + else + printf("%s->env,\n", args[env_idx]) >> CFILE + printf("\t msg.%s.%s_len,", \ + args[i], args[i]) >> CFILE + if (list_type[i] == "GID") + printf(" 1,") >> CFILE + else + printf(" sizeof(u_int32_t),") >> CFILE + printf(" &msg.%s.%s_val)) != 0)\n",\ + args[i], args[i], args[i], args[i]) >> CFILE + printf("\t\treturn (ret);\n") >> CFILE + printf("\tfor (%sq = msg.%s.%s_val, %sp = %s; ", \ + args[i], args[i], args[i], \ + args[i], args[i]) >> CFILE + printf("%si--; %sq++, %sp++)\n", \ + args[i], args[i], args[i]) >> CFILE + printf("\t\t*%sq = ", args[i]) >> CFILE + if (list_type[i] == "GID") + printf("*%sp;\n", args[i]) >> CFILE + if (list_type[i] == "ID") + printf("(*%sp)->cl_id;\n", args[i]) >> CFILE + if (list_type[i] == "INT") + printf("*%sp;\n", args[i]) >> CFILE + } + } + + printf("\n") >> CFILE + printf("\treplyp = __db_%s_%d%03d(&msg, cl);\n", name, major, minor) \ + >> CFILE + for (i = 0; i < nvars; ++i) + if (rpc_type[i] == "LIST") + printf("\t__os_free(%s->env, msg.%s.%s_val);\n", + env_handle ? args[env_idx] : "dbenv", + args[i], args[i]) >> CFILE + + printf("\tif (replyp == NULL) {\n") >> CFILE + printf("\t\t__db_errx(%s->env, clnt_sperror(cl, \"Berkeley DB\"));\n", + env_handle ? args[env_idx] : "dbenv") >> CFILE + + printf("\t\tret = DB_NOSERVER;\n") >> CFILE + printf("\t\tgoto out;\n") >> CFILE + printf("\t}\n") >> CFILE + + if (ret_code == 0) { + printf("\tret = replyp->status;\n") >> CFILE + + # + # Set any arguments that are returned + # + for (i = 0; i < rvars; ++i) { + if (ret_isarg[i]) { + printf("\tif (%sp != NULL)\n", + retargs[i]) >> CFILE; + printf("\t\t*%sp = (%s)replyp->%s;\n", + retargs[i], + retc_type[i], retargs[i]) >> CFILE; + } + } + } else { + printf("\tret = __dbcl_%s_ret(", name) >> CFILE + sep = ""; + for (i = 0; i < nvars; ++i) { + printf("%s%s", sep, args[i]) >> CFILE + sep = ", "; + } + printf("%sreplyp);\n", sep) >> CFILE + } + printf("out:\n") >> CFILE + # + # Free reply if there was one. + # + printf("\tif (replyp != NULL)\n") >> CFILE + printf("\t\txdr_free((xdrproc_t)xdr___%s_reply,",name) >> CFILE + printf(" (void *)replyp);\n") >> CFILE + printf("\treturn (ret);\n") >> CFILE + printf("}\n\n") >> CFILE + + # + # Generate Client Template code + # + if (ret_code) { + # + # If we are doing a list, write prototypes + # + delete p; + pi = 1; + p[pi++] = sprintf("int __dbcl_%s_ret __P((", name); + p[pi++] = ""; + for (i = 0; i < nvars; ++i) { + p[pi++] = pr_type[i]; + p[pi++] = ", "; + } + p[pi] = sprintf("__%s_reply *));", name); + proto_format(p, TFILE); + + printf("int\n") >> TFILE + printf("__dbcl_%s_ret(", name) >> TFILE + sep = ""; + for (i = 0; i < nvars; ++i) { + printf("%s%s", sep, args[i]) >> TFILE + sep = ", "; + } + printf("%sreplyp)\n",sep) >> TFILE + + for (i = 0; i < nvars; ++i) + if (func_arg[i] == 0) + printf("\t%s %s;\n", c_type[i], args[i]) \ + >> TFILE + else + printf("\t%s;\n", c_type[i]) >> TFILE + printf("\t__%s_reply *replyp;\n", name) >> TFILE; + printf("{\n") >> TFILE + printf("\tint ret;\n") >> TFILE + # + # Local vars in template + # + for (i = 0; i < rvars; ++i) { + if (ret_type[i] == "ID" || ret_type[i] == "STRING" || + ret_type[i] == "INT" || ret_type[i] == "DBL") { + printf("\t%s %s;\n", \ + retc_type[i], retargs[i]) >> TFILE + } else if (ret_type[i] == "LIST") { + if (retlist_type[i] == "GID") + printf("\tu_int8_t *__db_%s;\n", \ + retargs[i]) >> TFILE + if (retlist_type[i] == "ID" || + retlist_type[i] == "INT") + printf("\tu_int32_t *__db_%s;\n", \ + retargs[i]) >> TFILE + } else { + printf("\t/* %s %s; */\n", \ + ret_type[i], retargs[i]) >> TFILE + } + } + # + # Client return code + # + printf("\n") >> TFILE + printf("\tif (replyp->status != 0)\n") >> TFILE + printf("\t\treturn (replyp->status);\n") >> TFILE + for (i = 0; i < rvars; ++i) { + varname = ""; + if (ret_type[i] == "ID") { + varname = sprintf("%scl_id", retargs[i]); + } + if (ret_type[i] == "STRING") { + varname = retargs[i]; + } + if (ret_type[i] == "INT" || ret_type[i] == "DBL") { + varname = retargs[i]; + } + if (ret_type[i] == "DBT") { + varname = sprintf("%sdata", retargs[i]); + } + if (ret_type[i] == "ID" || ret_type[i] == "STRING" || + ret_type[i] == "INT" || ret_type[i] == "DBL") { + printf("\t%s = replyp->%s;\n", \ + retargs[i], varname) >> TFILE + } else if (ret_type[i] == "LIST") { + printf("\n\t/*\n") >> TFILE + printf("\t * XXX Handle list\n") >> TFILE + printf("\t */\n\n") >> TFILE + } else { + printf("\t/* Handle replyp->%s; */\n", \ + varname) >> TFILE + } + } + printf("\n\t/*\n\t * XXX Code goes here\n\t */\n\n") >> TFILE + printf("\treturn (replyp->status);\n") >> TFILE + printf("}\n\n") >> TFILE + } +} + +function general_headers() +{ + printf("#include \"db_config.h\"\n") >> CFILE + printf("\n") >> CFILE + printf("#include \"db_int.h\"\n") >> CFILE + printf("#ifdef HAVE_SYSTEM_INCLUDE_FILES\n") >> CFILE + printf("#include \n") >> CFILE + printf("#endif\n") >> CFILE + printf("#include \"db_server.h\"\n") >> CFILE + printf("#include \"dbinc/txn.h\"\n") >> CFILE + printf("#include \"dbinc_auto/rpc_client_ext.h\"\n") >> CFILE + printf("\n") >> CFILE + + printf("#include \"db_config.h\"\n") >> TFILE + printf("\n") >> TFILE + printf("#include \"db_int.h\"\n") >> TFILE + printf("#include \"dbinc/txn.h\"\n") >> TFILE + printf("\n") >> TFILE + + printf("#include \"db_config.h\"\n") >> SFILE + printf("\n") >> SFILE + printf("#include \"db_int.h\"\n") >> SFILE + printf("#ifdef HAVE_SYSTEM_INCLUDE_FILES\n") >> SFILE + printf("#include \n") >> SFILE + printf("#endif\n") >> SFILE + printf("#include \"db_server.h\"\n") >> SFILE + printf("#include \"dbinc/db_server_int.h\"\n") >> SFILE + printf("#include \"dbinc_auto/rpc_server_ext.h\"\n") >> SFILE + printf("\n") >> SFILE + + printf("#include \"db_config.h\"\n") >> PFILE + printf("\n") >> PFILE + printf("#include \"db_int.h\"\n") >> PFILE + printf("#ifdef HAVE_SYSTEM_INCLUDE_FILES\n") >> PFILE + printf("#include \n") >> PFILE + printf("#endif\n") >> PFILE + printf("#include \"db_server.h\"\n") >> PFILE + printf("#include \"dbinc/db_server_int.h\"\n") >> PFILE + printf("\n") >> PFILE +} + +# +# illegal_functions -- +# Output general illegal-call functions +function illegal_functions(OUTPUT) +{ + printf("static int __dbcl_dbp_illegal __P((DB *));\n") >> OUTPUT + printf("static int __dbcl_noserver __P((DB_ENV *));\n") >> OUTPUT + printf("static int __dbcl_txn_illegal __P((DB_TXN *));\n") >> OUTPUT + # If we ever need an "illegal" function for a DBC method. + # printf("static int __dbcl_dbc_illegal __P((DBC *));\n") >> OUTPUT + printf("\n") >> OUTPUT + + printf("static int\n") >> OUTPUT + printf("__dbcl_noserver(dbenv)\n") >> OUTPUT + printf("\tDB_ENV *dbenv;\n") >> OUTPUT + printf("{\n\t__db_errx(dbenv == NULL ? NULL : dbenv->env,") >> OUTPUT + printf(\ + "\n\t \"No Berkeley DB RPC server environment\");\n") >> OUTPUT + printf("\treturn (DB_NOSERVER);\n") >> OUTPUT + printf("}\n\n") >> OUTPUT + + printf("/*\n") >> OUTPUT + printf(" * __dbcl_dbenv_illegal --\n") >> OUTPUT + printf(" * DB_ENV method not supported under RPC.\n") >> OUTPUT + printf(" *\n") >> OUTPUT + printf(" * PUBLIC: int __dbcl_dbenv_illegal __P((DB_ENV *));\n")\ + >> OUTPUT + printf(" */\n") >> OUTPUT + printf("int\n") >> OUTPUT + printf("__dbcl_dbenv_illegal(dbenv)\n") >> OUTPUT + printf("\tDB_ENV *dbenv;\n") >> OUTPUT + printf("{\n\t__db_errx(dbenv == NULL ? NULL : dbenv->env,") >> OUTPUT + printf("\n\t \"Interface not supported by ") >> OUTPUT + printf("Berkeley DB RPC client environments\");\n") >> OUTPUT + printf("\treturn (DB_OPNOTSUP);\n") >> OUTPUT + printf("}\n\n") >> OUTPUT + printf("/*\n") >> OUTPUT + printf(" * __dbcl_dbp_illegal --\n") >> OUTPUT + printf(" * DB method not supported under RPC.\n") >> OUTPUT + printf(" */\n") >> OUTPUT + printf("static int\n") >> OUTPUT + printf("__dbcl_dbp_illegal(dbp)\n") >> OUTPUT + printf("\tDB *dbp;\n") >> OUTPUT + printf("{\n\treturn (__dbcl_dbenv_illegal(dbp->dbenv));\n") >> OUTPUT + printf("}\n\n") >> OUTPUT + printf("/*\n") >> OUTPUT + printf(" * __dbcl_txn_illegal --\n") >> OUTPUT + printf(" * DB_TXN method not supported under RPC.\n") >> OUTPUT + printf(" */\n") >> OUTPUT + printf("static int\n__dbcl_txn_illegal(txn)\n") >> OUTPUT + printf("\tDB_TXN *txn;\n") >> OUTPUT + printf("{\n\treturn (__dbcl_dbenv_illegal(txn->mgrp->env->dbenv));\n")\ + >> OUTPUT + printf("}\n\n") >> OUTPUT + # If we ever need an "illegal" function for a DBC method. + # printf("static int\n") >> OUTPUT + # printf("__dbcl_dbc_illegal(dbc)\n") >> OUTPUT + # printf("\tDBC *dbc;\n") >> OUTPUT + # printf("{\n\treturn (__dbcl_dbenv_illegal(dbc->dbenv));\n") \ + # >> OUTPUT + # printf("}\n\n") >> OUTPUT +} + +function obj_func(v, l) +{ + # Ignore db_create and env_create -- there's got to be something + # cleaner, but I don't want to rewrite rpc.src right now. + if (name == "db_create") + return; + if (name == "env_create") + return; + + # Strip off the leading prefix for the method name. + # + # There are two method names for cursors, the old and the new. + # + # There just has to be something cleaner, but yadda, yadda, yadda. + len = length(name); + i = index(name, "_"); + s = substr(name, i + 1, len - i) + + if (v != "dbc" || s == "get_priority" || s == "set_priority") + o = "" + else + o = sprintf(" = %s->c_%s", v, s) + l[obj_indx] = sprintf("\t%s->%s%s = __dbcl_%s;", v, s, o, name) +} + +function obj_illegal(l, handle, method, proto) +{ + # All of the functions return an int, with one exception. Hack + # to make that work. + type = method == "db_get_mpf" ? "DB_MPOOLFILE *" : "int" + + # Strip off the leading prefix for the method name -- there's got to + # be something cleaner, but I don't want to rewrite rpc.src right now. + len = length(method); + i = index(method, "_"); + + l[obj_indx] =\ + sprintf("\t%s->%s =\n\t (%s (*)(",\ + handle, substr(method, i + 1, len - i), type)\ + proto\ + sprintf("))\n\t __dbcl_%s_illegal;", handle); +} + +function obj_init(obj, v, list, OUTPUT) { + printf("/*\n") >> OUTPUT + printf(" * __dbcl_%s_init --\n", v) >> OUTPUT + printf(" *\tInitialize %s handle methods.\n", obj) >> OUTPUT + printf(" *\n") >> OUTPUT + printf(\ + " * PUBLIC: void __dbcl_%s_init __P((%s *));\n", v, obj) >> OUTPUT + printf(" */\n") >> OUTPUT + printf("void\n") >> OUTPUT + printf("__dbcl_%s_init(%s)\n", v, v) >> OUTPUT + printf("\t%s *%s;\n", obj, v) >> OUTPUT + printf("{\n") >> OUTPUT + for (i = 1; i < obj_indx; ++i) { + if (i in list) + print list[i] >> OUTPUT + } + printf("\treturn;\n}\n\n") >> OUTPUT +} + +# +# split_lines -- +# Add line separators to pretty-print the output. +function split_lines() { + if (argcount > 3) { + # Reset the counter, remove any trailing whitespace from + # the separator. + argcount = 0; + sub("[ ]$", "", sep) + + printf("%s\n\t\t", sep) >> PFILE + } +} + +# proto_format -- +# Pretty-print a function prototype. +function proto_format(p, OUTPUT) +{ + printf("/*\n") >> OUTPUT; + + s = ""; + for (i = 1; i in p; ++i) + s = s p[i]; + + t = " * PUBLIC: " + if (length(s) + length(t) < 80) + printf("%s%s", t, s) >> OUTPUT; + else { + split(s, p, "__P"); + len = length(t) + length(p[1]); + printf("%s%s", t, p[1]) >> OUTPUT + + n = split(p[2], comma, ","); + comma[1] = "__P" comma[1]; + for (i = 1; i <= n; i++) { + if (len + length(comma[i]) > 75) { + printf("\n * PUBLIC: ") >> OUTPUT; + len = 0; + } + printf("%s%s", comma[i], i == n ? "" : ",") >> OUTPUT; + len += length(comma[i]); + } + } + printf("\n */\n") >> OUTPUT; +} diff --git a/src/libs/resiprocate/contrib/db/dist/install-sh b/src/libs/resiprocate/contrib/db/dist/install-sh new file mode 100644 index 00000000..a5897de6 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/install-sh @@ -0,0 +1,519 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-12-25.00 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/src/libs/resiprocate/contrib/db/dist/ltmain.sh b/src/libs/resiprocate/contrib/db/dist/ltmain.sh new file mode 100644 index 00000000..b36c4ad3 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/ltmain.sh @@ -0,0 +1,8406 @@ +# Generated from ltmain.m4sh. + +# ltmain.sh (GNU libtool) 2.2.6 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print informational messages (default) +# --version print version information +# -h, --help print short or long help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.2.6 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=2.2.6 +TIMESTAMP="" +package_revision=1.3012 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# NLS nuisances: We save the old values to restore during execute mode. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done + +$lt_unset CDPATH + + + + + +: ${CP="cp -f"} +: ${ECHO="echo"} +: ${EGREP="/usr/bin/grep -E"} +: ${FGREP="/usr/bin/grep -F"} +: ${GREP="/usr/bin/grep"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="/opt/local/bin/gsed"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + +# Generated shell functions inserted here. + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +# In the unlikely event $progname began with a '-', it would play havoc with +# func_echo (imagine progname=-n), so we prepend ./ in that case: +func_dirname_and_basename "$progpath" +progname=$func_basename_result +case $progname in + -*) progname=./$progname ;; +esac + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=: + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname${mode+: }$mode: $*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` + done + my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "X$my_tmpdir" | $Xsed +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "X$1" | $Xsed \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + + + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $SED -n '/^# Usage:/,/# -h/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + $ECHO + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help +# Echo long help message to standard output and exit. +func_help () +{ + $SED -n '/^# Usage:/,/# Report bugs to/ { + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + p + }' < "$progpath" + exit $? +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + func_error "missing argument for $1" + exit_cmd=exit +} + +exit_cmd=: + + + + + +# Check that we have a working $ECHO. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell, and then maybe $ECHO will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# Parse options once, thoroughly. This comes as soon as possible in +# the script to make things like `libtool --version' happen quickly. +{ + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Parse non-mode specific arguments: + while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --config) func_config ;; + + --debug) preserve_args="$preserve_args $opt" + func_echo "enabling shell trace mode" + opt_debug='set -x' + $opt_debug + ;; + + -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break + execute_dlfiles="$execute_dlfiles $1" + shift + ;; + + --dry-run | -n) opt_dry_run=: ;; + --features) func_features ;; + --finish) mode="finish" ;; + + --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break + case $1 in + # Valid mode arguments: + clean) ;; + compile) ;; + execute) ;; + finish) ;; + install) ;; + link) ;; + relink) ;; + uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; + esac + + mode="$1" + shift + ;; + + --preserve-dup-deps) + opt_duplicate_deps=: ;; + + --quiet|--silent) preserve_args="$preserve_args $opt" + opt_silent=: + ;; + + --verbose| -v) preserve_args="$preserve_args $opt" + opt_silent=false + ;; + + --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break + preserve_args="$preserve_args $opt $1" + func_enable_tag "$1" # tagname is set here + shift + ;; + + # Separate optargs to long options: + -dlopen=*|--mode=*|--tag=*) + func_opt_split "$opt" + set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} + shift + ;; + + -\?|-h) func_usage ;; + --help) opt_help=: ;; + --version) func_version ;; + + -*) func_fatal_help "unrecognized option \`$opt'" ;; + + *) nonopt="$opt" + break + ;; + esac + done + + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_duplicate_deps + ;; + esac + + # Having warned about all mis-specified options, bail out if + # anything was wrong. + $exit_cmd $EXIT_FAILURE +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +## ----------- ## +## Main. ## +## ----------- ## + +$opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + test -z "$mode" && func_fatal_error "error: you must specify a MODE." + + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$mode' for more information." +} + + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_ltwrapper_scriptname_result="" + if func_ltwrapper_executable_p "$1"; then + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" + fi +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + case "$@ " in + " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T <?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + removelist="$removelist $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + removelist="$removelist $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + command="$command -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { +test "$mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$mode'" + ;; + esac + + $ECHO + $ECHO "Try \`$progname --help' for more information about other modes." + + exit $? +} + + # Now that we've collected a possible --mode arg, show help if necessary + $opt_help && func_mode_help + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_quote_for_eval "$file" + args="$args $func_quote_for_eval_result" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + $ECHO "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + $ECHO "X----------------------------------------------------------------------" | $Xsed + $ECHO "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + $ECHO + $ECHO "If you ever happen to want to link against installed libraries" + $ECHO "in a given directory, LIBDIR, you must either use libtool, and" + $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'" + $ECHO "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable" + $ECHO " during execution" + fi + if test -n "$runpath_var"; then + $ECHO " - add LIBDIR to the \`$runpath_var' environment variable" + $ECHO " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $ECHO + + $ECHO "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual" + $ECHO "pages." + ;; + *) + $ECHO "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + $ECHO "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS +} + +test "$mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $ECHO "X$nonopt" | $GREP shtool >/dev/null; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + install_prog="$install_prog$func_quote_for_eval_result" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + install_prog="$install_prog $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_verbose "extracting global C symbols from \`$progfile'" + $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + $ECHO >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +" + case $host in + *cygwin* | *mingw* | *cegcc* ) + $ECHO >> "$output_objdir/$my_dlsyms" "\ +/* DATA imports from DLLs on WIN32 con't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs. */" + lt_dlsym_const= ;; + *osf5*) + echo >> "$output_objdir/$my_dlsyms" "\ +/* This system does not cope well with relocations in const data */" + lt_dlsym_const= ;; + *) + lt_dlsym_const=const ;; + esac + + $ECHO >> "$output_objdir/$my_dlsyms" "\ +extern $lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +$lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + $ECHO >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) symtab_cflags="$symtab_cflags $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + + +# func_emit_wrapper_part1 [arg=no] +# +# Emit the first part of a libtool wrapper script on stdout. +# For more information, see the description associated with +# func_emit_wrapper(), below. +func_emit_wrapper_part1 () +{ + func_emit_wrapper_part1_arg1=no + if test -n "$1" ; then + func_emit_wrapper_part1_arg1=$1 + fi + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + ECHO=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$ECHO works! + : + else + # Restart under the correct shell, and then maybe \$ECHO will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $ECHO "\ + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done +" +} +# end: func_emit_wrapper_part1 + +# func_emit_wrapper_part2 [arg=no] +# +# Emit the second part of a libtool wrapper script on stdout. +# For more information, see the description associated with +# func_emit_wrapper(), below. +func_emit_wrapper_part2 () +{ + func_emit_wrapper_part2_arg1=no + if test -n "$1" ; then + func_emit_wrapper_part2_arg1=$1 + fi + + $ECHO "\ + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} +# end: func_emit_wrapper_part2 + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=no + if test -n "$1" ; then + func_emit_wrapper_arg1=$1 + fi + + # split this up so that func_emit_cwrapperexe_src + # can call each part independently. + func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" + func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" +} + + +# func_to_host_path arg +# +# Convert paths to host format when used with build tools. +# Intended for use with "native" mingw (where libtool itself +# is running under the msys shell), or in the following cross- +# build environments: +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# where wine is equipped with the `winepath' executable. +# In the native mingw case, the (msys) shell automatically +# converts paths for any non-msys applications it launches, +# but that facility isn't available from inside the cwrapper. +# Similar accommodations are necessary for $host mingw and +# $build cygwin. Calling this function does no harm for other +# $host/$build combinations not listed above. +# +# ARG is the path (on $build) that should be converted to +# the proper representation for $host. The result is stored +# in $func_to_host_path_result. +func_to_host_path () +{ + func_to_host_path_result="$1" + if test -n "$1" ; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + case $build in + *mingw* ) # actually, msys + # awkward: cmd appends spaces to result + lt_sed_strip_trailing_spaces="s/[ ]*\$//" + func_to_host_path_tmp1=`( cmd //c echo "$1" |\ + $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_path_tmp1=`cygpath -w "$1"` + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # Unfortunately, winepath does not exit with a non-zero + # error code, so we are forced to check the contents of + # stdout. On the other hand, if the command is not + # found, the shell will set an exit code of 127 and print + # *an error message* to stdout. So we must check for both + # error code of zero AND non-empty stdout, which explains + # the odd construction: + func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` + if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + else + # Allow warning below. + func_to_host_path_result="" + fi + ;; + esac + if test -z "$func_to_host_path_result" ; then + func_error "Could not determine host path corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_path_result="$1" + fi + ;; + esac + fi +} +# end: func_to_host_path + +# func_to_host_pathlist arg +# +# Convert pathlists to host format when used with build tools. +# See func_to_host_path(), above. This function supports the +# following $build/$host combinations (but does no harm for +# combinations not listed here): +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# +# Path separators are also converted from $build format to +# $host format. If ARG begins or ends with a path separator +# character, it is preserved (but converted to $host format) +# on output. +# +# ARG is a pathlist (on $build) that should be converted to +# the proper representation on $host. The result is stored +# in $func_to_host_pathlist_result. +func_to_host_pathlist () +{ + func_to_host_pathlist_result="$1" + if test -n "$1" ; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_to_host_pathlist_tmp2="$1" + # Once set for this call, this variable should not be + # reassigned. It is used in tha fallback case. + func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e 's|^:*||' -e 's|:*$||'` + case $build in + *mingw* ) # Actually, msys. + # Awkward: cmd appends spaces to result. + lt_sed_strip_trailing_spaces="s/[ ]*\$//" + func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # unfortunately, winepath doesn't convert pathlists + func_to_host_pathlist_result="" + func_to_host_pathlist_oldIFS=$IFS + IFS=: + for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do + IFS=$func_to_host_pathlist_oldIFS + if test -n "$func_to_host_pathlist_f" ; then + func_to_host_path "$func_to_host_pathlist_f" + if test -n "$func_to_host_path_result" ; then + if test -z "$func_to_host_pathlist_result" ; then + func_to_host_pathlist_result="$func_to_host_path_result" + else + func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" + fi + fi + fi + IFS=: + done + IFS=$func_to_host_pathlist_oldIFS + ;; + esac + if test -z "$func_to_host_pathlist_result" ; then + func_error "Could not determine the host path(s) corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This may break if $1 contains DOS-style drive + # specifications. The fix is not to complicate the expression + # below, but for the user to provide a working wine installation + # with winepath so that path translation in the cross-to-mingw + # case works properly. + lt_replace_pathsep_nix_to_dos="s|:|;|g" + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_replace_pathsep_nix_to_dos"` + fi + # Now, add the leading and trailing path separators back + case "$1" in + :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" + ;; + esac + case "$1" in + *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" + ;; + esac + ;; + esac + fi +} +# end: func_to_host_pathlist + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +# define setmode _setmode +#else +# include +# include +# ifdef __CYGWIN__ +# include +# define HAVE_SETENV +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +#ifdef _MSC_VER +# define S_IXUSR _S_IEXEC +# define stat _stat +# ifndef _INTPTR_T_DEFINED +# define intptr_t int +# endif +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifdef __CYGWIN__ +# define FOPEN_WB "wb" +#endif + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#undef LTWRAPPER_DEBUGPRINTF +#if defined DEBUGWRAPPER +# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args +static void +ltwrapper_debugprintf (const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); +} +#else +# define LTWRAPPER_DEBUGPRINTF(args) +#endif + +const char *program_name = NULL; + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_fatal (const char *message, ...); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_opt_process_env_set (const char *arg); +void lt_opt_process_env_prepend (const char *arg); +void lt_opt_process_env_append (const char *arg); +int lt_split_name_value (const char *arg, char** name, char** value); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); + +static const char *script_text_part1 = +EOF + + func_emit_wrapper_part1 yes | + $SED -e 's/\([\\"]\)/\\\1/g' \ + -e 's/^/ "/' -e 's/$/\\n"/' + echo ";" + cat <"))); + for (i = 0; i < newargc; i++) + { + LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); + } + +EOF + + case $host_os in + mingw*) + cat <<"EOF" + /* execv doesn't actually work on mingw as expected on unix */ + rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); + if (rval == -1) + { + /* failed to start process */ + LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno)); + return 127; + } + return rval; +EOF + ;; + *) + cat <<"EOF" + execv (lt_argv_zero, newargz); + return rval; /* =127, but avoids unused variable warning */ +EOF + ;; + esac + + cat <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void *p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), + string) : NULL; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char) name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable (const char *path) +{ + struct stat st; + + LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", + path ? (*path ? path : "EMPTY!") : "NULL!")); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", + path ? (*path ? path : "EMPTY!") : "NULL!")); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", + wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n", + tmp_pathspec)); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + char *errstr = strerror (errno); + lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal ("Could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} + +void +lt_setenv (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", + (name ? name : ""), + (value ? value : ""))); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +int +lt_split_name_value (const char *arg, char** name, char** value) +{ + const char *p; + int len; + if (!arg || !*arg) + return 1; + + p = strchr (arg, (int)'='); + + if (!p) + return 1; + + *value = xstrdup (++p); + + len = strlen (arg) - strlen (*value); + *name = XMALLOC (char, len); + strncpy (*name, arg, len-1); + (*name)[len - 1] = '\0'; + + return 0; +} + +void +lt_opt_process_env_set (const char *arg) +{ + char *name = NULL; + char *value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); + } + + lt_setenv (name, value); + XFREE (name); + XFREE (value); +} + +void +lt_opt_process_env_prepend (const char *arg) +{ + char *name = NULL; + char *value = NULL; + char *new_value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); + } + + new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + XFREE (name); + XFREE (value); +} + +void +lt_opt_process_env_append (const char *arg) +{ + char *name = NULL; + char *value = NULL; + char *new_value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); + } + + new_value = lt_extend_str (getenv (name), value, 1); + lt_setenv (name, new_value); + XFREE (new_value); + XFREE (name); + XFREE (value); +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + (name ? name : ""), + (value ? value : ""))); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + (name ? name : ""), + (value ? value : ""))); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + + +EOF +} +# end: func_emit_cwrapperexe_src + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) deplibs="$deplibs $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + weak_libs="$weak_libs $arg" + prev= + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname '-L' '' "$arg" + dir=$func_stripname_result + if test -z "$dir"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" + linker_flags="$linker_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -F/path gives path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_duplicate_deps ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + case $lib in + *.la) func_source "$lib" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` + case " $weak_libs " in + *" $deplib_base "*) ;; + *) deplibs="$deplibs $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + dir=$func_stripname_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $ECHO + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because the file extensions .$libext of this argument makes me believe" + $ECHO "*** that it is just a static archive that I should not use here." + else + $ECHO + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) temp_rpath="$temp_rpath$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + notinst_deplibs="$notinst_deplibs $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + $ECHO + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $ECHO + $ECHO "*** And there doesn't seem to be a static archive available" + $ECHO "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $ECHO + $ECHO "*** Warning: This system can not link to static lib archive $lib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $ECHO "*** But as you try to build a module library, libtool will still create " + $ECHO "*** a static module, that should work as long as the dlopening application" + $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $ECHO + $ECHO "*** However, this would only work if libtool was able to extract symbol" + $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" + $ECHO "*** not find such a program. So, this module is probably useless." + $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_dirname "$deplib" "" "." + dir="$func_dirname_result" + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + $ECHO + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + libobjs="$libobjs $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` + # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` + # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $ECHO + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $ECHO + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ + -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` + done + fi + if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | + $GREP . >/dev/null; then + $ECHO + if test "X$deplibs_check_method" = "Xnone"; then + $ECHO "*** Warning: inter-library dependencies are not supported in this platform." + else + $ECHO "*** Warning: inter-library dependencies are not known to be supported." + fi + $ECHO "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $ECHO + $ECHO "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + $ECHO "*** a static module, that should work as long as the dlopening" + $ECHO "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $ECHO + $ECHO "*** However, this would only work if libtool was able to extract symbol" + $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" + $ECHO "*** not find such a program. So, this module is probably useless." + $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $ECHO "*** The inter-library dependencies that have been dropped here will be" + $ECHO "*** automatically added whenever a program is linked with this library" + $ECHO "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $ECHO + $ECHO "*** Since this library must not contain undefined symbols," + $ECHO "*** because either the platform does not support them or" + $ECHO "*** it was explicitly requested with -no-undefined," + $ECHO "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + delfiles="$delfiles $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + func_len " $cmd" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$ECHO "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + $ECHO 'INPUT (' > $output + for obj in $save_libobjs + do + $ECHO "$obj" >> $output + done + $ECHO ')' >> $output + delfiles="$delfiles $output" + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + $ECHO "$obj" >> $output + done + delfiles="$delfiles $output" + output=$firstobj\"$file_list_spec$output\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + delfiles="$delfiles $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *cegcc) + # Disable wrappers for cegcc, we are cross compiling anyway. + wrappers_required=no + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $ECHO for shipping. + if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + oldobjs="$oldobjs $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $ECHO "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlfiles="$newdlfiles $libdir/$name" + ;; + *) newdlfiles="$newdlfiles $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlprefiles="$newdlprefiles $libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$mode" = link || test "$mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) RM="$RM $arg"; rmforce=yes ;; + -*) RM="$RM $arg" ;; + *) files="$files $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + rmfiles="$rmfiles $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$mode" = uninstall || test "$mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/src/libs/resiprocate/contrib/db/dist/pubdef.in b/src/libs/resiprocate/contrib/db/dist/pubdef.in new file mode 100644 index 00000000..da877b1c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/pubdef.in @@ -0,0 +1,480 @@ +# $Id$ +# +# Name +# D == documentation +# I == include file +# J == Java constant +# N == wrapped by the Java native layer +# C == C# constant +DB_AFTER D I J C +DB_AGGRESSIVE D I J C +DB_ALREADY_ABORTED * I * * +DB_AM_CHKSUM * I * * +DB_AM_COMPENSATE * I * * +DB_AM_COMPRESS * I * * +DB_AM_CREATED * I * * +DB_AM_CREATED_MSTR * I * * +DB_AM_DBM_ERROR * I * * +DB_AM_DELIMITER * I * * +DB_AM_DISCARD * I * * +DB_AM_DUP * I * * +DB_AM_DUPSORT * I * * +DB_AM_ENCRYPT * I * * +DB_AM_FIXEDLEN * I * * +DB_AM_INMEM * I * * +DB_AM_INORDER * I * * +DB_AM_IN_RENAME * I * * +DB_AM_NOT_DURABLE * I * * +DB_AM_OPEN_CALLED * I * * +DB_AM_PAD * I * * +DB_AM_PGDEF * I * * +DB_AM_RDONLY * I * * +DB_AM_READ_UNCOMMITTED * I * * +DB_AM_RECNUM * I * * +DB_AM_RECOVER * I * * +DB_AM_RENUMBER * I * * +DB_AM_REVSPLITOFF * I * * +DB_AM_SECONDARY * I * * +DB_AM_SNAPSHOT * I * * +DB_AM_SUBDB * I * * +DB_AM_SWAP * I * * +DB_AM_TXN * I * * +DB_AM_VERIFYING * I * * +DB_APPEND D I J C +DB_ARCH_ABS D I J C +DB_ARCH_DATA D I J C +DB_ARCH_LOG D I J C +DB_ARCH_REMOVE D I J C +DB_ASSOC_IMMUTABLE_KEY * I * * +DB_AUTO_COMMIT D I J C +DB_BEFORE D I J C +DB_BTREE D I J C +DB_BTREEMAGIC * I * * +DB_BTREEOLDVER * I * * +DB_BTREEVERSION * I * * +DB_BUFFER_SMALL D I J C +DB_CDB_ALLDB D I J C +DB_CHKSUM D I J C +DB_CKP_INTERNAL * I * * +DB_CONFIG D * * * +DB_CONSUME D I J C +DB_CONSUME_WAIT D I J C +DB_CREATE D I J C +DB_CURRENT D I J C +DB_CURSOR_BULK D I J C +DB_CURSOR_TRANSIENT * I * * +DB_CXX_NO_EXCEPTIONS D I * * +DB_DBM_HSEARCH * I * * +DB_DBT_APPMALLOC D I N C +DB_DBT_BULK D I J C +DB_DBT_DUPOK * I * * +DB_DBT_ISSET * I * * +DB_DBT_MALLOC D I J C +DB_DBT_MULTIPLE D I N C +DB_DBT_PARTIAL D I J C +DB_DBT_REALLOC D I N C +DB_DBT_STREAMING D I * * +DB_DBT_USERCOPY * I N C +DB_DBT_USERMEM D I J C +DB_DEGREE_2 * I * * +DB_DELETED * I * * +DB_DIRECT D I * * +DB_DIRECT_DB D I J C +DB_DIRTY_READ * I * * +DB_DONOTINDEX D I N C +DB_DSYNC_DB D I J C +DB_DUP D I J C +DB_DUPSORT D I J C +DB_DURABLE_UNKNOWN * I * * +DB_EID_BROADCAST D I J C +DB_EID_INVALID D I J C +DB_ENCRYPT D I J C +DB_ENCRYPT_AES D I J C +DB_ENV_AUTO_COMMIT * I * * +DB_ENV_CDB_ALLDB * I * * +DB_ENV_DIRECT_DB * I * * +DB_ENV_DSYNC_DB * I * * +DB_ENV_FAILCHK * I * * +DB_ENV_MULTIVERSION * I * * +DB_ENV_NOLOCKING * I * * +DB_ENV_NOMMAP * I * * +DB_ENV_NOPANIC * I * * +DB_ENV_OVERWRITE * I * * +DB_ENV_REGION_INIT * I * * +DB_ENV_RPCCLIENT * I * * +DB_ENV_RPCCLIENT_GIVEN * I * * +DB_ENV_TIME_NOTGRANTED * I * * +DB_ENV_TXN_NOSYNC * I * * +DB_ENV_TXN_NOWAIT * I * * +DB_ENV_TXN_SNAPSHOT * I * * +DB_ENV_TXN_WRITE_NOSYNC * I * * +DB_ENV_YIELDCPU * I * * +DB_EVENT_NOT_HANDLED * I * * +DB_EVENT_NO_SUCH_EVENT * I * * +DB_EVENT_PANIC D I N C +DB_EVENT_REG_ALIVE D I * * +DB_EVENT_REG_PANIC D I * * +DB_EVENT_REP_CLIENT D I N C +DB_EVENT_REP_ELECTED D I N C +DB_EVENT_REP_MASTER D I N C +DB_EVENT_REP_NEWMASTER D I N C +DB_EVENT_REP_PERM_FAILED D I N C +DB_EVENT_REP_STARTUPDONE D I N C +DB_EVENT_WRITE_FAILED D I N C +DB_EXCL D I J C +DB_EXTENT * I * * +DB_FAILCHK D I * * +DB_FAST_STAT D I J C +DB_FCNTL_LOCKING * I * * +DB_FILE_ID_LEN * I * * +DB_FIRST D I J C +DB_FLUSH D I J C +DB_FORCE D I J C +DB_FOREIGN_ABORT * I J C +DB_FOREIGN_CASCADE * I J C +DB_FOREIGN_CONFLICT * I * C +DB_FOREIGN_NULLIFY * I J C +DB_FREELIST_ONLY D I J C +DB_FREE_SPACE D I J C +DB_GET_BOTH D I J C +DB_GET_BOTHC * I * * +DB_GET_BOTH_LTE D I * * +DB_GET_BOTH_RANGE D I J C +DB_GET_RECNO D I J C +DB_GID_SIZE * I N C +DB_HANDLE_LOCK * I * * +DB_HASH D I J C +DB_HASHMAGIC * I * * +DB_HASHOLDVER * I * * +DB_HASHVERSION * I * * +DB_HOME D * * * +DB_IGNORE_LEASE D I J C +DB_IMMUTABLE_KEY D I J C +DB_INIT_CDB D I J C +DB_INIT_LOCK D I J C +DB_INIT_LOG D I J C +DB_INIT_MPOOL D I J C +DB_INIT_REP D I J C +DB_INIT_TXN D I J C +DB_INORDER D I J C +DB_JOINENV * I J C +DB_JOIN_ITEM D I J C +DB_JOIN_NOSORT D I J C +DB_KEYEMPTY D I J C +DB_KEYEXIST D I J C +DB_KEYFIRST D I J C +DB_KEYLAST D I J C +DB_LAST D I J C +DB_LOCKDOWN D I J C +DB_LOCKVERSION * I * * +DB_LOCK_DEADLOCK D I J C +DB_LOCK_DEFAULT D I J C +DB_LOCK_DUMP * I * * +DB_LOCK_EXPIRE D I J C +DB_LOCK_GET D I J C +DB_LOCK_GET_TIMEOUT D I J C +DB_LOCK_INHERIT * I * * +DB_LOCK_IREAD D I J C +DB_LOCK_IWR D I J C +DB_LOCK_IWRITE D I J C +DB_LOCK_MAXLOCKS D I J C +DB_LOCK_MAXWRITE D I J C +DB_LOCK_MINLOCKS D I J C +DB_LOCK_MINWRITE D I J C +DB_LOCK_NG * I * * +DB_LOCK_NORUN * I * * +DB_LOCK_NOTGRANTED D I J C +DB_LOCK_NOWAIT D I J C +DB_LOCK_OLDEST D I J C +DB_LOCK_PUT D I J C +DB_LOCK_PUT_ALL D I J C +DB_LOCK_PUT_OBJ D I J C +DB_LOCK_PUT_READ * I * * +DB_LOCK_RANDOM D I J C +DB_LOCK_READ D I J C +DB_LOCK_READ_UNCOMMITTED * I * * +DB_LOCK_RECORD * I * * +DB_LOCK_SET_TIMEOUT * I * * +DB_LOCK_SWITCH * I * * +DB_LOCK_TIMEOUT D I J C +DB_LOCK_TRADE * I * * +DB_LOCK_UPGRADE * I * * +DB_LOCK_UPGRADE_WRITE * I * * +DB_LOCK_WAIT * I * * +DB_LOCK_WRITE D I J C +DB_LOCK_WWRITE * I * * +DB_LOCK_YOUNGEST D I J C +DB_LOGCHKSUM D I * * +DB_LOGFILEID_INVALID * I * * +DB_LOGMAGIC * I * * +DB_LOGOLDVER * I * * +DB_LOGVERSION * I * * +DB_LOGVERSION_LATCHING D I * * +DB_LOG_AUTO_REMOVE D I J C +DB_LOG_BUFFER_FULL D I * C +DB_LOG_CHKPNT * I * * +DB_LOG_COMMIT * I * * +DB_LOG_DIRECT D I J C +DB_LOG_DISK * I * * +DB_LOG_DSYNC D I J C +DB_LOG_IN_MEMORY D I J C +DB_LOG_LOCKED * I * * +DB_LOG_NOCOPY * I * * +DB_LOG_NOT_DURABLE * I * * +DB_LOG_SILENT_ERR * I * * +DB_LOG_WRNOSYNC * I * * +DB_LOG_ZERO D I J C +DB_LSTAT_ABORTED * I * * +DB_LSTAT_EXPIRED * I * * +DB_LSTAT_FREE * I * * +DB_LSTAT_HELD * I * * +DB_LSTAT_PENDING * I * * +DB_LSTAT_WAITING * I * * +DB_MAX_PAGES * I * * +DB_MAX_RECORDS * I * * +DB_MPOOL_CREATE D I * * +DB_MPOOL_DIRTY D I * * +DB_MPOOL_TRY D I * * +DB_MPOOL_DISCARD * I * * +DB_MPOOL_EDIT D I * * +DB_MPOOL_FREE * I * * +DB_MPOOL_LAST D I * * +DB_MPOOL_NEW D I * * +DB_MPOOL_NOFILE D I J C +DB_MPOOL_NOLOCK * I * * +DB_MPOOL_UNLINK D I J C +DB_MULTIPLE D I J C +DB_MULTIPLE_INIT D I * * +DB_MULTIPLE_KEY D I J C +DB_MULTIPLE_KEY_NEXT D I * * +DB_MULTIPLE_KEY_RESERVE_NEXT D I * * +DB_MULTIPLE_KEY_WRITE_NEXT D I * * +DB_MULTIPLE_NEXT D I * * +DB_MULTIPLE_RECNO_NEXT D I * * +DB_MULTIPLE_RECNO_RESERVE_NEXT D I * * +DB_MULTIPLE_RECNO_WRITE_INIT D I * * +DB_MULTIPLE_RECNO_WRITE_NEXT D I * * +DB_MULTIPLE_RESERVE_NEXT D I * * +DB_MULTIPLE_WRITE_INIT D I * * +DB_MULTIPLE_WRITE_NEXT D I * * +DB_MULTIVERSION D I J C +DB_MUTEX_ALLOCATED * I * * +DB_MUTEX_LOCKED * I * * +DB_MUTEX_LOGICAL_LOCK * I * * +DB_MUTEX_PROCESS_ONLY D I * C +DB_MUTEX_SELF_BLOCK D I * C +DB_MUTEX_SHARED D I * * +DB_NEEDSPLIT * I * * +DB_NEXT D I J C +DB_NEXT_DUP D I J C +DB_NEXT_NODUP D I J C +DB_NODUPDATA D I J C +DB_NOLOCKING D I J C +DB_NOMMAP D I J C +DB_NOORDERCHK D I J C +DB_NOOVERWRITE D I J C +DB_NOPANIC D I J C +DB_NOSERVER D I * C +DB_NOSERVER_HOME D I J C +DB_NOSERVER_ID D I J C +DB_NOSYNC D I J C +DB_NOTFOUND D I J C +DB_NO_AUTO_COMMIT * I * * +DB_ODDFILESIZE D I * * +DB_OK_BTREE * I * * +DB_OK_HASH * I * * +DB_OK_QUEUE * I * * +DB_OK_RECNO * I * * +DB_OLD_VERSION D I * C +DB_OPFLAGS_MASK * I * * +DB_ORDERCHKONLY D I J C +DB_OVERWRITE D I J C +DB_OVERWRITE_DUP D I * * +DB_PAGE_LOCK * I * * +DB_PAGE_NOTFOUND D I * C +DB_PANIC_ENVIRONMENT D I J C +DB_POSITION D I J C +DB_PREV D I J C +DB_PREV_DUP D I J C +DB_PREV_NODUP D I J C +DB_PRINTABLE D I J C +DB_PRIORITY_DEFAULT D I J C +DB_PRIORITY_HIGH D I J C +DB_PRIORITY_LOW D I J C +DB_PRIORITY_UNCHANGED D I * * +DB_PRIORITY_VERY_HIGH D I J C +DB_PRIORITY_VERY_LOW D I J C +DB_PRIVATE D I J C +DB_PR_PAGE * I * * +DB_PR_RECOVERYTEST * I * * +DB_QAMMAGIC * I * * +DB_QAMOLDVER * I * * +DB_QAMVERSION * I * * +DB_QUEUE D I J C +DB_RDONLY D I J C +DB_RDWRMASTER * I * * +DB_READ_COMMITTED D I J C +DB_READ_UNCOMMITTED D I J C +DB_RECNO D I J C +DB_RECNUM D I J C +DB_RECORD_LOCK * I * * +DB_RECOVER D I J C +DB_RECOVER_FATAL D I J C +DB_REDO * I * * +DB_REGION_INIT D I J C +DB_REGION_MAGIC * I * * +DB_REGISTER D I J C +DB_RENAMEMAGIC * I * * +DB_RENUMBER D I J C +DB_REPMGR_ACKS_ALL D I J C +DB_REPMGR_ACKS_ALL_PEERS D I J C +DB_REPMGR_ACKS_NONE D I J C +DB_REPMGR_ACKS_ONE D I J C +DB_REPMGR_ACKS_ONE_PEER D I J C +DB_REPMGR_ACKS_QUORUM D I J C +DB_REPMGR_CONF_2SITE_STRICT D I J C +DB_REPMGR_CONNECTED D I J C +DB_REPMGR_DISCONNECTED D I * * +DB_REPMGR_PEER D I J C +DB_REP_ACK_TIMEOUT D I J C +DB_REP_ANYWHERE D I J C +DB_REP_BULKOVF * I * * +DB_REP_CHECKPOINT_DELAY D I J C +DB_REP_CLIENT D I J C +DB_REP_CONF_BULK D I J C +DB_REP_CONF_DELAYCLIENT D I J C +DB_REP_CONF_INMEM D I J C +DB_REP_CONF_LEASE D I J C +DB_REP_CONF_NOAUTOINIT D I J C +DB_REP_CONF_NOWAIT D I J C +DB_REP_CONNECTION_RETRY D I J C +DB_REP_DEFAULT_PRIORITY * I J C +DB_REP_DUPMASTER D I N C +DB_REP_EGENCHG * I * * +DB_REP_ELECTION D I J C +DB_REP_ELECTION_RETRY D I J C +DB_REP_ELECTION_TIMEOUT D I J C +DB_REP_FULL_ELECTION_TIMEOUT D I J C +DB_REP_HANDLE_DEAD D I N C +DB_REP_HEARTBEAT_MONITOR D I J C +DB_REP_HEARTBEAT_SEND D I J C +DB_REP_HOLDELECTION D I N C +DB_REP_IGNORE D I J C +DB_REP_ISPERM D I J C +DB_REP_JOIN_FAILURE D I N C +DB_REP_LEASE_EXPIRED D I N C +DB_REP_LEASE_TIMEOUT D I N C +DB_REP_LOCKOUT D I N C +DB_REP_LOGREADY * I * * +DB_REP_MASTER D I J C +DB_REP_NEWMASTER * I * * +DB_REP_NEWSITE D I J C +DB_REP_NOBUFFER D I J C +DB_REP_NOTPERM D I J C +DB_REP_PAGEDONE * I * * +DB_REP_PAGELOCKED D I * * +DB_REP_PERMANENT D I J C +DB_REP_REREQUEST D I J C +DB_REP_UNAVAIL D I N C +DB_REVSPLITOFF D I J C +DB_RMW D I J C +DB_RPCCLIENT D I J C +DB_RUNRECOVERY D I N C +DB_SALVAGE D I J C +DB_SA_SKIPFIRSTKEY * I * * +DB_SA_UNKNOWNKEY * I * * +DB_SECONDARY_BAD D I * C +DB_SEQUENCE_OLDVER * I * * +DB_SEQUENCE_VERSION * I * * +DB_SEQ_DEC D I J C +DB_SEQ_INC D I J C +DB_SEQ_RANGE_SET * I * * +DB_SEQ_WRAP D I J C +DB_SEQ_WRAPPED * I * * +DB_SET D I J C +DB_SET_LTE D I * * +DB_SET_LOCK_TIMEOUT D I J C +DB_SET_RANGE D I J C +DB_SET_REG_TIMEOUT D I * * +DB_SET_RECNO D I J C +DB_SET_TXN_LSNP * I * * +DB_SET_TXN_NOW * I * * +DB_SET_TXN_TIMEOUT D I J C +DB_SHALLOW_DUP * I * * +DB_SNAPSHOT D I J C +DB_STAT_ALL D I * C +DB_STAT_CLEAR D I J C +DB_STAT_LOCK_CONF D I * C +DB_STAT_LOCK_LOCKERS D I * C +DB_STAT_LOCK_OBJECTS D I * C +DB_STAT_LOCK_PARAMS D I * C +DB_STAT_MEMP_HASH D I * C +DB_STAT_MEMP_NOERROR * I * * +DB_STAT_SUBSYSTEM D I * C +DB_ST_DUPOK * I * * +DB_ST_DUPSET * I * * +DB_ST_DUPSORT * I * * +DB_ST_IS_RECNO * I * * +DB_ST_OVFL_LEAF * I * * +DB_ST_RECNUM * I * * +DB_ST_RELEN * I * * +DB_ST_TOPLEVEL * I * * +DB_SURPRISE_KID * I * * +DB_SWAPBYTES * I * * +DB_SYSTEM_MEM D I J C +DB_THREAD D I J C +DB_THREADID_STRLEN D I * * +DB_TIMEOUT * I * * +DB_TIME_NOTGRANTED D I J C +DB_TRUNCATE D I J C +DB_TXNVERSION * I * * +DB_TXN_ABORT D I J C +DB_TXN_APPLY D I J C +DB_TXN_BACKWARD_ROLL D I J C +DB_TXN_CKP * I * * +DB_TXN_FORWARD_ROLL D I J C +DB_TXN_NOSYNC D I J C +DB_TXN_NOT_DURABLE D I J C +DB_TXN_NOWAIT D I J C +DB_TXN_OPENFILES * I * * +DB_TXN_POPENFILES * I * * +DB_TXN_PRINT D I J C +DB_TXN_SNAPSHOT D I J C +DB_TXN_SYNC D I J C +DB_TXN_WAIT D I J C +DB_TXN_WRITE_NOSYNC D I J C +DB_UNDO * I * * +DB_UNKNOWN D I J C +DB_UNREF * I * * +DB_UPDATE_SECONDARY * I * * +DB_UPGRADE D I J C +DB_USE_ENVIRON D I J C +DB_USE_ENVIRON_ROOT D I J C +DB_VERB_DEADLOCK D I J C +DB_VERB_FILEOPS D I J C +DB_VERB_FILEOPS_ALL D I J C +DB_VERB_RECOVERY D I J C +DB_VERB_REGISTER D I J C +DB_VERB_REPLICATION D I J C +DB_VERB_REPMGR_CONNFAIL D I J C +DB_VERB_REPMGR_MISC D I J C +DB_VERB_REP_ELECT D I J C +DB_VERB_REP_LEASE D I J C +DB_VERB_REP_MISC D I J C +DB_VERB_REP_MSGS D I J C +DB_VERB_REP_SYNC D I J C +DB_VERB_REP_TEST D I J C +DB_VERB_WAITSFOR D I J C +DB_VERIFY D I J C +DB_VERIFY_BAD D I N C +DB_VERIFY_FATAL * I * * +DB_VERIFY_PARTITION D I * * +DB_VERSION_MAJOR * I J C +DB_VERSION_MINOR * I J C +DB_VERSION_MISMATCH D I N C +DB_VERSION_PATCH * I J C +DB_VERSION_STRING * I N C +DB_WRITECURSOR D I J C +DB_WRITELOCK * I * * +DB_WRITEOPEN * I * * +DB_YIELDCPU D I J C diff --git a/src/libs/resiprocate/contrib/db/dist/s_all b/src/libs/resiprocate/contrib/db/dist/s_all new file mode 100644 index 00000000..da6ab70e --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_all @@ -0,0 +1,40 @@ +#!/bin/sh - +# $Id$ + +sh s_perm # permissions. +sh s_readme # distribution README file. + +sh s_config # autoconf. +sh s_apiflags # API flags. +sh s_rpc # RPC files. +sh s_sig # Structure signature. +sh s_recover # logging/recovery files. +sh s_message # replication and repmgr message files. + +############################################################# +# The following order is important, s_include must run after +# the other source files have been created. +############################################################# +sh s_include # standard include files. + +sh s_java # Java support. +sh s_test # Test suite support. +#sh s_tags # Tags files. + +############################################################# +# We only build the Cscope file for releases, it's too big to +# commit into the CVS tree. +############################################################# +#sh s_cscope # Cscope files. + +############################################################# +# Create the build environments last, they use files created +# by previous steps. +############################################################# +sh s_brew # BREW support. +sh s_brew_dsp # BREW support: build environment. +sh s_s60 # S60 support. +sh s_s60_mmp # S60 support: build environment. +sh s_vxworks # VxWorks support. +sh s_windows # Windows support. +sh s_windows_dsp # Windows support: build environment. diff --git a/src/libs/resiprocate/contrib/db/dist/s_config b/src/libs/resiprocate/contrib/db/dist/s_config new file mode 100644 index 00000000..132a7658 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_config @@ -0,0 +1,34 @@ +#!/bin/sh - +# $Id$ +# +# Build the autoconfiguration files. + +trap 'rm -f aclocal.m4 ; exit 0' 0 1 2 3 13 15 + +. ./RELEASE + +echo "autoconf: building aclocal.m4..." +cat aclocal/*.m4 aclocal_java/*.m4 > aclocal.m4 + +echo "autoconf: running autoheader to build config.hin..." +rm -f config.hin +autoheader +chmod 444 config.hin + +echo "autoconf: running autoconf to build configure" +rm -f configure +autoconf + +# Edit version information we couldn't pre-compute. +sed -e "s/__EDIT_DB_VERSION_MAJOR__/$DB_VERSION_MAJOR/g" \ + -e "s/__EDIT_DB_VERSION_MINOR__/$DB_VERSION_MINOR/g" \ + -e "s/__EDIT_DB_VERSION_PATCH__/$DB_VERSION_PATCH/g" \ + -e "s/__EDIT_DB_VERSION_STRING__/$DB_VERSION_STRING/g" \ + -e "s/__EDIT_DB_VERSION_UNIQUE_NAME__/$DB_VERSION_UNIQUE_NAME/g" \ + -e "s/__EDIT_DB_VERSION__/$DB_VERSION/g" configure > configure.version +mv configure.version configure + +rm -rf autom4te.cache +chmod 555 configure + +chmod 555 config.guess config.sub install-sh diff --git a/src/libs/resiprocate/contrib/db/dist/s_crypto b/src/libs/resiprocate/contrib/db/dist/s_crypto new file mode 100644 index 00000000..6b3f8aa3 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_crypto @@ -0,0 +1,75 @@ +#!/bin/sh - +# $Id$ + +# Remove crypto from the DB source tree. + +d=.. + +t=/tmp/__db_a +trap 'rm -f $t ; exit 0' 0 +trap 'rm -f $t ; exit 1' 1 2 3 13 15 + +if ! test -d $d/crypto; then + echo "s_crypto: no crypto sources found in the source tree." + exit 1 +fi + +# Remove the crypto. +rm -rf $d/crypto + +# Update the release splash page. +f=$d/docs/index.html +chmod 664 $f +(echo '/DOES/' && + echo 's/DOES/DOES NOT/' && + echo 'w' && + echo 'q') | ed $f + +# Win/32. +f=win_config.in +chmod 664 $f +(echo '/#define.HAVE_CRYPTO/' && + echo 'c' && + echo '/* #undef HAVE_CRYPTO */' + echo '.' && + echo 'w' && + echo 'q') | ed $f + +f=srcfiles.in +chmod 664 $f +f=srcfiles.in +r=`egrep crypto/crypto.c $f | awk 'BEGIN { FS="\t*" } { print $2 }'` +(echo 'g/^crypto\//d' && + echo '/crypto_stub\.c/' && + echo "s/\$/ $r/" && + echo 'w' && + echo 'q') | ed $f + +# Change out crypto/crypto.c for common/crypto_stub.c, remove all other +# references to crypto files. +f=win_projects/projects.template.xml +chmod 664 $f +(echo '/crypto\/crypto\.c/' && + echo 'c' && + echo ' ' && + echo '.' && + echo 'g/"crypto\//d' && + echo "s/\$/ $r/" && + echo ',' && + echo 'w' && + echo 'q') | ed $f + + sh ./s_windows + sh ./s_windows_dsp + +# VxWorks +f=vx_config.in +chmod 664 $f +(echo '/#define.HAVE_CRYPTO/' && + echo 'c' && + echo '/* #undef HAVE_CRYPTO */' + echo '.' && + echo 'w' && + echo 'q') | ed $f + + sh ./s_vxworks diff --git a/src/libs/resiprocate/contrib/db/dist/s_include b/src/libs/resiprocate/contrib/db/dist/s_include new file mode 100644 index 00000000..ce28c217 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_include @@ -0,0 +1,165 @@ +#!/bin/sh - +# $Id$ +# +# Build the automatically generated function prototype files. + +msgc="/* DO NOT EDIT: automatically built by dist/s_include. */" + +. ./RELEASE + +head() +{ + defonly=0 + while : + do case "$1" in + space) + echo ""; shift;; + defonly) + defonly=1; shift;; + *) + name="$1"; break;; + esac + done + + echo "$msgc" + echo "#ifndef $name" + echo "#define $name" + echo "" + if [ $defonly -eq 0 ]; then + echo "#if defined(__cplusplus)" + echo "extern \"C\" {" + echo "#endif" + echo "" + fi +} + +tail() +{ + defonly=0 + while : + do case "$1" in + defonly) + defonly=1; shift;; + *) + name="$1"; break;; + esac + done + + echo "" + if [ $defonly -eq 0 ]; then + echo "#if defined(__cplusplus)" + echo "}" + echo "#endif" + fi + echo "#endif /* !$name */" +} + +# This script is run on a variety of systems. To avoid spurious changes, fix +# some variables that affect sort order of ls(1). +unset LANG +export LANG +LC_ALL="C" +export LC_ALL + +# We are building several files: +# 1 external #define file +# 1 external prototype file +# 1 internal #define file +# N internal prototype files +e_dfile=/tmp/__db_c.$$ +e_pfile=/tmp/__db_a.$$ +i_dfile=/tmp/__db_d.$$ +i_pfile=/tmp/__db_b.$$ +trap 'rm -f $e_dfile $e_pfile $i_dfile $i_pfile; exit 0' 0 1 2 3 13 15 + +head defonly space _DB_EXT_DEF_IN_ > $e_dfile +head space _DB_EXT_PROT_IN_ > $e_pfile +head defonly _DB_INT_DEF_IN_ > $i_dfile + +# Process the standard directories, creating per-directory prototype +# files and adding to the external prototype and #define files. +for i in db btree clib common crypto dbreg env fileops hash hmac \ + lock log mp mutex os qam rep repmgr rpc_client rpc_server \ + sequence tcl txn; do + head "_${i}_ext_h_" > $i_pfile + + if [ $i = os ] ; then + f=`ls ../$i/*.c \ + ../os_brew/*.c ../os_qnx/*.c ../os_vxworks/*.c ../os_windows/*.c` + elif [ $i = rpc_server ] ; then + f=`ls ../$i/c/*.c` + elif [ $i = crypto ] ; then + f=`ls ../$i/*.c ../$i/*/*.c` + elif [ $i = env ] ; then + f=`ls ../$i/*.c ../repmgr/repmgr_stub.c` + else + f=`ls ../$i/*.c` + fi + awk -f gen_inc.awk \ + -v db_version_unique_name=$DB_VERSION_UNIQUE_NAME \ + -v e_dfile=$e_dfile \ + -v e_pfile=$e_pfile \ + -v i_dfile=$i_dfile \ + -v i_pfile=$i_pfile $f + + tail "_${i}_ext_h_" >> $i_pfile + + f=../dbinc_auto/${i}_ext.h + cmp $i_pfile $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $i_pfile $f && chmod 444 $f) +done + +# Process directories which only add to the external prototype and #define +# files. +for i in dbm hsearch; do + f=`ls ../$i/*.c` + awk -f gen_inc.awk \ + -v db_version_unique_name=$DB_VERSION_UNIQUE_NAME \ + -v e_dfile=$e_dfile \ + -v e_pfile=$e_pfile \ + -v i_dfile="" \ + -v i_pfile="" $f +done + +# There are a few global variables in DB -- add them to the external/internal +# #define files. +(echo "#define __db_global_values __db_global_values@DB_VERSION_UNIQUE_NAME@"; + echo "#define __repmgr_guesstimated_max __repmgr_guesstimated_max@DB_VERSION_UNIQUE_NAME@") >> $i_dfile + +# Wrap up the external #defines/prototypes, and internal #defines. +tail defonly _DB_EXT_DEF_IN_ >> $e_dfile +f=../dbinc_auto/ext_def.in +cmp $e_dfile $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $e_dfile $f && chmod 444 $f) + +tail _DB_EXT_PROT_IN_ >> $e_pfile +f=../dbinc_auto/ext_prot.in +cmp $e_pfile $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $e_pfile $f && chmod 444 $f) + +tail defonly _DB_INT_DEF_IN_ >> $i_dfile +f=../dbinc_auto/int_def.in +cmp $i_dfile $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $i_dfile $f && chmod 444 $f) + +# DB185 compatibility support. +head space defonly _DB_EXT_185_DEF_IN_ > $e_dfile +head space _DB_EXT_185_PROT_IN_ > $e_pfile + +f=`ls ../db185/*.c` +awk -f gen_inc.awk \ + -v db_version_unique_name=$DB_VERSION_UNIQUE_NAME \ + -v e_dfile=$e_dfile \ + -v e_pfile=$e_pfile \ + -v i_dfile="" \ + -v i_pfile="" $f + +tail defonly _DB_EXT_185_DEF_IN_ >> $e_dfile +f=../dbinc_auto/ext_185_def.in +cmp $e_dfile $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $e_dfile $f && chmod 444 $f) + +tail _DB_EXT_185_PROT_IN_ >> $e_pfile +f=../dbinc_auto/ext_185_prot.in +cmp $e_pfile $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $e_pfile $f && chmod 444 $f) diff --git a/src/libs/resiprocate/contrib/db/dist/s_java b/src/libs/resiprocate/contrib/db/dist/s_java new file mode 100644 index 00000000..7931169c --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_java @@ -0,0 +1,8 @@ +#!/bin/sh - +# $Id$ +# +# Build the Java files. + +sh s_java_stat # Create Java stat methods +sh s_java_swig # Create core Java API with SWIG +sh s_java_const # Create Java constants diff --git a/src/libs/resiprocate/contrib/db/dist/s_java_const b/src/libs/resiprocate/contrib/db/dist/s_java_const new file mode 100644 index 00000000..94eac9a2 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_java_const @@ -0,0 +1,41 @@ +#!/bin/sh - +# $Id$ +# +# Build the Java files. + +msgjava="/* DO NOT EDIT: automatically built by dist/s_java_const. */" + +. ./RELEASE + +t=/tmp/__java +trap 'rm -f $t; exit 0' 0 1 2 3 13 15 + +(echo "$msgjava" && + echo && + echo 'package com.sleepycat.db.internal;' && + echo && + echo 'public interface DbConstants' && + echo '{' && + for i in `egrep '^DB_.*J [C|\*]$' pubdef.in | awk '{print $1}'`; do \ + sed -e ':a' -e '/\\$/N;s/\\\n[ ]*/ /;ta' \ + ../dbinc_auto/api_flags.in ../dbinc/db.in | \ + egrep -w "^#define[ ]$i|^[ ][ ]*$i" ; + done | + sed -e "s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/" \ + -e "s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/" \ + -e "s/@DB_VERSION_PATCH@/$DB_VERSION_PATCH/" \ + -e 's/^#define[ ][ ]*//' \ + -e 's/[()=,]/ /g' \ + -e 's/\/\*.*$//' \ + -e 's/^[ ]*//' \ + -e 's/[ ]*$//g' \ + -e 's/[ ][ ]*/ /g' \ + -e 's/ / = /' | \ + awk '{ print " int " $0 ";" }' && + echo '}' && + echo && + echo '// end of DbConstants.java') > $t + +f=../java/src/com/sleepycat/db/internal/DbConstants.java +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) diff --git a/src/libs/resiprocate/contrib/db/dist/s_java_stat b/src/libs/resiprocate/contrib/db/dist/s_java_stat new file mode 100644 index 00000000..58ab79de --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_java_stat @@ -0,0 +1,419 @@ +#!/bin/sh - +# $Id$ +# +# Build the Java files. + +msgjava="/*- + * Automatically built by dist/s_java_stat. + * Only the javadoc comments can be edited. + * + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + */" + +s=/tmp/__java.sed +t=/tmp/__java +t0=/tmp/__java0 +c=/tmp/__javajnic +u1=/tmp/__javautil1 +u2=/tmp/__javautil2 +trap 'rm -f $s $t $t0 $c $u1 $u2; exit 0' 0 1 2 3 13 15 + +# Script to convert DB C structure declarations into Java declarations. +jclass() +{ + cat > $s < $s <> $c + echo " jobject jobj, struct __db_$1 *statp) {" >> $c + sed -n -f $s < ../dbinc/db.in >> $c + echo ' return (0);' >> $c + echo '}' >> $c +} + +jni_fieldid_decls() +{ + cat > $s <> $u1 +} + +jni_fieldids() +{ + cat > $s <> $u2 +} + +# Script to convert DB C structure declarations into a toString method body +jclass_toString() +{ + cat > $s < $t0 + f=../java/src/com/sleepycat/db/$j_class.java + ./s_javadoc_merge $f $t0 > $t + cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + jclass_jni $1 $2 +} + +echo "$msgjava" > $c +> $u1 +> $u2 + +stat_class bt_stat BtreeStats " extends DatabaseStats" + +# Build CompactStats.java - not purely a statistics class, but close enough to +# share this code. +(cat < $t0 +f=../java/src/com/sleepycat/db/CompactStats.java +./s_javadoc_merge $f $t0 > $t +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) +jclass_jni compact __dbj_fill_compact + +stat_class h_stat HashStats " extends DatabaseStats" +stat_class lock_stat LockStats +stat_class log_stat LogStats +stat_class mpool_fstat CacheFileStats +stat_class mpool_stat CacheStats +stat_class mutex_stat MutexStats +stat_class qam_stat QueueStats " extends DatabaseStats" +stat_class rep_stat ReplicationStats "" " +import com.sleepycat.db.internal.DbConstants; +" " + public static final int REP_CLIENT = DbConstants.DB_REP_CLIENT; + + public static final int REP_MASTER = DbConstants.DB_REP_MASTER; + + public static final int REP_NONE = 0;" + +stat_class repmgr_stat ReplicationManagerStats +stat_class seq_stat SequenceStats + +# Build TransactionStats.java - special because of embedded Active class +(echo "$msgjava" + echo + echo 'package com.sleepycat.db;' + echo + echo 'import com.sleepycat.db.internal.DbUtil;' + echo + echo 'public class TransactionStats' + echo '{' + echo " // no public constructor" + echo " /* package */ TransactionStats() {}" + echo + echo " public static class Active {" + echo " // no public constructor" + echo " /* package */ Active() {}" + jclass txn_active " " + jclass_toString txn_active Active " " + echo ' };' + jclass txn_stat + jclass_toString txn_stat TransactionStats + echo '}') > $t0 +f=../java/src/com/sleepycat/db/TransactionStats.java +./s_javadoc_merge $f $t0 > $t +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) +jclass_jni txn_stat __dbj_fill_txn_stat +jclass_jni txn_active __dbj_fill_txn_active + +mv $c $t +f=../libdb_java/java_stat_auto.c +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +f=../libdb_java/java_util.i +sed '/BEGIN-STAT-FIELD-DECLS/q' < $f > $t +cat $u1 >> $t +sed -n '/END-STAT-FIELD-DECLS/,/BEGIN-STAT-FIELDS/p' < $f >> $t +cat $u2 >> $t +sed -n '/END-STAT-FIELDS/,$p' < $f >> $t +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 644 $f) diff --git a/src/libs/resiprocate/contrib/db/dist/s_java_swig b/src/libs/resiprocate/contrib/db/dist/s_java_swig new file mode 100644 index 00000000..686c521a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_java_swig @@ -0,0 +1,73 @@ +#!/bin/sh - +# $Id$ +# +# Run SWIG to generate the Java APIs + +t=/tmp/__db_a +trap 'rm -f $t ; exit 0' 0 +trap 'rm -f $t ; exit 1' 1 2 3 13 15 + +SWIG=swig +SWIG_DIR=../libdb_java +SWIG_FILE=$SWIG_DIR/db.i +PACKAGE="com.sleepycat.db.internal" + +die() { + echo "$@" >&2 + exit 1 +} + +[ -f $SWIG_FILE ] || die "Must be run from the dist directory" + +for api in java ; do + echo "Building $api API" + + swig_args="" + case $api in + java) + swig_args="-nodefaultctor -nodefaultdtor -package $PACKAGE $args" + ;; + esac + + $SWIG -Wall -$api $swig_args -I$SWIG_DIR \ + -o ../libdb_$api/db_${api}_wrap.c $SWIG_FILE || exit $? +done + +# Skip Java sources if run with "-n" +if [ "x$1" = "x-n" ] ; then + rm -f $SWIG_DIR/*.java + exit 0 +fi + +# Fixups for Java +JAVA_SRCTOP=../java/src +JAVA_PKGDIR=com/sleepycat/db/internal +JAVA_SRCDIR=$JAVA_SRCTOP/$JAVA_PKGDIR + +# SWIG 1.3.18 puts the Java files in the same directory as the native code. +cd $SWIG_DIR +[ -f Db.java ] || exit 1 + +for f in *.java ; do + case $f in + SWIGTYPE*) + die "Interface contains unresolved types: $f" + esac + rm -f $JAVA_SRCDIR/$f + perl -p $SWIG_DIR/java-post.pl < $f > $JAVA_SRCDIR/$f || exit $? + rm -f $f +done + +# db_config.h must be the first #include, move it to the top of the file. +( + echo '#include "db_config.h"' + sed '/#include "db_config.h"/d' < db_java_wrap.c +) > $t && cp $t db_java_wrap.c + +# The following might become redundant with newer swig versions. +# builds usually already define _CRT_SECURE_NO_DEPRECATE +( + sed -e '/# define _CRT_SECURE_NO_DEPRECATE/i\ +# undef _CRT_SECURE_NO_DEPRECATE' < db_java_wrap.c +) > $t && cp $t db_java_wrap.c + diff --git a/src/libs/resiprocate/contrib/db/dist/s_je2db b/src/libs/resiprocate/contrib/db/dist/s_je2db new file mode 100644 index 00000000..461e7bd2 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_je2db @@ -0,0 +1,94 @@ +#!/bin/sh - + +# The examples must be hand-edited after they are copied: +# - add EnvironmentConfig.setInitializeCache(true), setInitializeLocking(true) +# - add DatabaseConfig.setType(DatabaseType.BTREE) +# - add null databaseName param to openDatabase() and openSecondaryDatabase() + +COPY_EXAMPLES=0 + +JEDIR=$1 +if [ $# -eq 1 ] ; then + DBDIR=.. +else + DBDIR=$2 +fi + +if [ ! -d "$DBDIR/dbinc" -o ! -f "$JEDIR/build.xml" ] ; then + echo >&2 "Usage $0 /path/to/je [ /path/to/db ]" + exit 1 +fi + +JEDIR=$(cd "$JEDIR" ; /bin/pwd) +DBDIR=$(cd "$DBDIR" ; /bin/pwd) + +JESRC="$JEDIR/src" +JETEST="$JEDIR/test" +JEEXAMPLES="$JEDIR/examples" +DBSRC="$DBDIR/java/src" +DBTEST="$DBDIR/test/scr024/src" +DBEXAMPLES="$DBDIR/examples_java/src" +DIRMATCH="com/sleepycat/\(\(asm\)\|\(bind\)\|\(collections\)\|\(persist\)\|\(util\)\)" +EXAMPLESMATCH="^\./\(\(collections\)\|\(persist\)\)" + +cd "$JESRC" +for d in `find . -type d | grep -v CVS | grep $DIRMATCH` ; do + #echo "$DBSRC/$d" + mkdir -p "$DBSRC/$d" +done +cd "$JETEST" +for d in `find . -type d | grep -v CVS | grep $DIRMATCH` ; do + #echo "$DBTEST/$d" + mkdir -p "$DBTEST/$d" +done +if [ $COPY_EXAMPLES -eq 1 ] ; then + cd "$JEEXAMPLES" + for d in `find . -type d | grep -v CVS | grep $EXAMPLESMATCH` ; do + #echo "$DBEXAMPLES/$d" + mkdir -p "$DBEXAMPLES/$d" + done +fi + +E1='s/com\.sleepycat\.je/com.sleepycat.db/g' +E2='//,//d' +E3='s/LockConflictException/DeadlockException/g' +E4='s/$Id:.*\$/$Id$/' +E5='s/TransactionGettingStarted/gsg_txn\/JAVA/' +EXCLUDESRC="\(\(DeletedClassException\)\|\(IncompatibleClassException\)\|\(StoreExistsException\)\|\(StoreNotFoundException\)\)" +#EXCLUDESRC="\(\(ClassEnhancerTask\)\|\(DeletedClassException\)\|\(IncompatibleClassException\)\|\(StoreExistsException\)\|\(StoreNotFoundException\)\)" +EXCLUDETESTS="\(\(ConvertAndAddTest\)\|\(DevolutionTest\)\|\(TestVersionCompatibility\)\|\(XACollectionTest\)\)" + +cd "$JESRC" +for f in `find . -name '*.java' -o -name "package.html" | grep $DIRMATCH | grep -v $EXCLUDESRC` ; do + #echo $DBSRC/$f + sed -e "$E1" -e "$E2" -e "$E3" -e "$E4" -e "$E5" < $f \ + > $DBSRC/$f.sed.out + diff -q -I "\$\Id:" $DBSRC/$f $DBSRC/$f.sed.out || \ + mv -f $DBSRC/$f.sed.out $DBSRC/$f + rm -f $DBSRC/$f.sed.out +done + +cd "$JETEST" +for f in `find . -name '*.java' -o -name "*.java.original" | grep $DIRMATCH | grep -v $EXCLUDETESTS` \ + ; do + #echo $DBTEST/$f + sed -e "$E1" -e "$E2" -e "$E3" -e "$E4" -e "$E5" < $f \ + > $DBTEST/$f.sed.out + diff -q -I "\$\Id:" $DBTEST/$f $DBTEST/$f.sed.out || \ + mv -f $DBTEST/$f.sed.out $DBTEST/$f + rm -f $DBTEST/$f.sed.out +done + +if [ $COPY_EXAMPLES -eq 1 ] ; then + cd "$JEEXAMPLES" + for f in `find . -name '*.java' | grep $EXAMPLESMATCH` ; do + #echo $DBEXAMPLES/$f + sed -e "$E1" -e "$E2" -e "$E3" -e "$E4" -e "$E5" < $f \ + > $DBEXAMPLES/$f.sed.out + diff -q -I "\$\Id:" $DBEXAMPLES/$f $DBEXAMPLES/$f.sed.out || \ + mv -f $DBEXAMPLES/$f.sed.out $DBEXAMPLES/$f + rm -f $DBEXAMPLES/$f.sed.out + done +fi + +exit 0 diff --git a/src/libs/resiprocate/contrib/db/dist/s_perm b/src/libs/resiprocate/contrib/db/dist/s_perm new file mode 100644 index 00000000..5b72c264 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_perm @@ -0,0 +1,63 @@ +#!/bin/sh - +# $Id$ + +d=.. +echo 'Updating Berkeley DB source tree permissions...' + +run() +{ + #echo " $1 ($2)" + if [ -f "$d/$1" ]; then + chmod "$2" "$d/$1" + else + echo "$d/$1: no such file or directory" + exit 1 + fi +} + +run build_windows/include.tcl 664 +run dist/config.guess 555 +run dist/config.sub 555 +run dist/configure 555 +run dist/install-sh 555 +run dist/s_all 555 +run dist/s_apiflags 555 +run dist/s_brew 555 +run dist/s_brew_dsp 555 +run dist/s_brew_posix 555 +run dist/s_config 555 +run dist/s_crypto 555 +run dist/s_cscope 555 +run dist/s_include 555 +run dist/s_java 555 +run dist/s_java_const 555 +run dist/s_java_stat 555 +run dist/s_java_swig 555 +run dist/s_javadoc_merge 555 +run dist/s_je2db 555 +run dist/s_message 555 +run dist/s_perm 555 +run dist/s_readme 555 +run dist/s_recover 555 +run dist/s_rpc 555 +run dist/s_s60 555 +run dist/s_s60_mmp 555 +run dist/s_s60_posix 555 +run dist/s_sig 555 +run dist/s_symlink 555 +run dist/s_tags 555 +run dist/s_test 555 +run dist/s_vxworks 555 +run dist/s_windows 555 +run dist/s_windows_dsp 555 +run dist/s_winmsi 555 +run dist/vx_buildcd 555 +run mod_db4/configure 555 +run perl/BerkeleyDB/dbinfo 555 +run perl/BerkeleyDB/mkpod 555 + +for i in `cd $d && find build_vxworks \ + -name '*.wsp' -o -name '*.cdf' -o -name '*.wpj'`; do + #echo " $i (775)" + chmod 775 $d/$i +done diff --git a/src/libs/resiprocate/contrib/db/dist/s_readme b/src/libs/resiprocate/contrib/db/dist/s_readme new file mode 100644 index 00000000..6a52efac --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_readme @@ -0,0 +1,25 @@ +#!/bin/sh - +# $Id$ +# +# Build the README. + +echo 'Updating Berkeley DB README file...' + +d=.. + +t=/tmp/__t +trap 'rm -f $t; exit 0' 0 1 2 3 13 15 + +. RELEASE + +cat << END_OF_README>$t +$DB_VERSION_STRING + +This is version $DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH of Berkeley DB from Oracle. To view release and +installation documentation, load the distribution file docs/index.html +into your web browser. +END_OF_README + +f=../README +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) diff --git a/src/libs/resiprocate/contrib/db/dist/s_recover b/src/libs/resiprocate/contrib/db/dist/s_recover new file mode 100644 index 00000000..593be29d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_recover @@ -0,0 +1,71 @@ +#!/bin/sh - +# $Id$ +# +# Build the automatically generated logging/recovery files. + +header=/tmp/__db_a +loglist=/tmp/__db_b +print=/tmp/__db_c +source=/tmp/__db_d +template=/tmp/__db_e +tmp=/tmp/__db_f + +trap 'rm -f /tmp/__db_[abcdef]; exit 1' 1 2 3 13 15 +trap 'rm -f /tmp/__db_[abcdef]; exit 0' 0 + +DIR="db dbreg btree fileops hash qam txn" + +# Check to make sure we haven't duplicated a log record entry, and build +# the list of log record types that the test suite uses. +for i in $DIR; do + for f in ../$i/*.src; do + # Grab the PREFIX; there should only be one per file, and + # so it's okay to just take the first. + grep '^PREFIX' $f | sed q + egrep '^BEGIN[ ]|^IGNORED[ ]|^DEPRECATED[ ]' $f | + awk '{print $1 "\t" $2 "\t" $3 "\t" $4}' + done +done > $loglist +grep -v '^PREFIX' $loglist | + awk '{print $2 "\t" $3 "\t" $4}' | sort -n -k 3 | uniq -d -f 1 > $tmp +[ -s $tmp ] && { + echo "DUPLICATE LOG VALUES:" + cat $tmp + rm -f $tmp + exit 1 +} +f=../test/logtrack.list +cmp $loglist $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $loglist $f && chmod 444 $f) + +# Build DB's recovery routines. +for i in $DIR; do + for f in ../$i/*.src; do + subsystem=`basename $f .src` + awk -f gen_rec.awk \ + -v header_file=$header \ + -v print_file=$print\ + -v source_file=$source \ + -v template_file=$template < $f + + f=../dbinc_auto/${subsystem}_auto.h + cmp $header $f > /dev/null 2>&1 || + (echo "Building $f" && + rm -f $f && cp $header $f && chmod 444 $f) + f=../$i/${subsystem}_auto.c + cmp $source $f > /dev/null 2>&1 || + (echo "Building $f" && + rm -f $f && cp $source $f && chmod 444 $f) + f=../$i/${subsystem}_autop.c + cmp $print $f > /dev/null 2>&1 || + (echo "Building $f" && + rm -f $f && cp $print $f && chmod 444 $f) + f=template/rec_${subsystem} + cmp $template $f > /dev/null 2>&1 || + (echo "Building $f" && + rm -f $f && cp $template $f && chmod 444 $f) + done +done + +# Build the example application's recovery routines. +(cd ../examples_c/ex_apprec && sh auto_rebuild) diff --git a/src/libs/resiprocate/contrib/db/dist/s_rpc b/src/libs/resiprocate/contrib/db/dist/s_rpc new file mode 100644 index 00000000..38692b75 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_rpc @@ -0,0 +1,38 @@ +#!/bin/sh - +# $Id$ +# +# Build the automatically generated RPC files + +echo "Building RPC client/server files..." + +. ./RELEASE + +t=/tmp/__db_a +trap 'rm -f $t ; exit 0' 0 +trap 'rm -f $t ; exit 1' 1 2 3 13 15 + +client_file=../rpc_client/gen_client.c +ctmpl_file=./template/gen_client_ret +server_file=../rpc_server/c/gen_db_server.c +stmpl_file=./template/db_server_proc +xdr_file=../rpc_server/db_server.x + +rm -f $client_file $ctmpl_file $server_file $stmpl_file $xdr_file + +# +# Generate client/server/XDR code +# +gidsize=\ +`awk '/^#define/ { if ($2 == "DB_GID_SIZE") { print $3 }}' ../dbinc/db.in` + +awk -f gen_rpc.awk \ + -v client_file=$client_file \ + -v ctmpl_file=$ctmpl_file \ + -v major=$DB_VERSION_MAJOR \ + -v minor=$DB_VERSION_MINOR \ + -v server_file=$server_file \ + -v stmpl_file=$stmpl_file \ + -v xdr_file=$xdr_file \ + -v gidsize=$gidsize < ../rpc_server/rpc.src + +chmod 444 $client_file $server_file diff --git a/src/libs/resiprocate/contrib/db/dist/s_symlink b/src/libs/resiprocate/contrib/db/dist/s_symlink new file mode 100644 index 00000000..598c699b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_symlink @@ -0,0 +1,61 @@ +#!/bin/sh - +# $Id$ + +echo 'Creating Berkeley DB source tree symbolic links...' + +build() +{ + #echo " $1 -> $2" + (cd ../`dirname $1` && rm -f `basename $1` && ln -s $2 `basename $1`) +} + +build btree/tags ../dist/tags +build build_unix/tags ../dist/tags +build clib/tags ../dist/tags +build common/tags ../dist/tags +build crypto/tags ../dist/tags +build cxx/tags ../dist/tags +build db/tags ../dist/tags +build db185/tags ../dist/tags +build db_archive/tags ../dist/tags +build db_checkpoint/tags ../dist/tags +build db_deadlock/tags ../dist/tags +build db_dump/tags ../dist/tags +build db_dump185/tags ../dist/tags +build db_hotbackup/tags ../dist/tags +build db_load/tags ../dist/tags +build db_printlog/tags ../dist/tags +build db_recover/tags ../dist/tags +build db_stat/tags ../dist/tags +build db_upgrade/tags ../dist/tags +build db_verify/tags ../dist/tags +build dbinc/tags ../dist/tags +build dbinc_auto/tags ../dist/tags +build dbm/tags ../dist/tags +build dbreg/tags ../dist/tags +build env/tags ../dist/tags +build examples_c/tags ../dist/tags +build examples_cxx/tags ../dist/tags +build fileops/tags ../dist/tags +build hash/tags ../dist/tags +build hmac/tags ../dist/tags +build hsearch/tags ../dist/tags +build libdb_java/tags ../dist/tags +build lock/tags ../dist/tags +build log/tags ../dist/tags +build mp/tags ../dist/tags +build mutex/tags ../dist/tags +build os/tags ../dist/tags +build os_brew/tags ../dist/tags +build os_qnx/tags ../dist/tags +build os_s60/tags ../dist/tags +build os_vxworks/tags ../dist/tags +build os_windows/tags ../dist/tags +build qam/tags ../dist/tags +build rep/tags ../dist/tags +build repmgr/tags ../dist/tags +build rpc_client/tags ../dist/tags +build rpc_server/tags ../dist/tags +build sequence/tags ../dist/tags +build tcl/tags ../dist/tags +build txn/tags ../dist/tags diff --git a/src/libs/resiprocate/contrib/db/dist/s_tags b/src/libs/resiprocate/contrib/db/dist/s_tags new file mode 100644 index 00000000..de030b15 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_tags @@ -0,0 +1,66 @@ +#!/bin/sh - +# $Id$ +# +# Build tags files. + +files=`echo ../dbinc/*.h \ + ../dbinc/*.in \ + ../btree/*.[ch] \ + ../clib/*.[ch] \ + ../common/*.[ch] \ + ../crypto/*.[ch] \ + ../crypto/mersenne/*.[ch] \ + ../crypto/rijndael/*.[ch] \ + ../db/*.[ch] \ + ../db185/*.[ch] \ + ../dbm/*.[ch] \ + ../dbreg/*.[ch] \ + ../env/*.[ch] \ + ../fileops/*.[ch] \ + ../hash/*.[ch] \ + ../hmac/*.[ch] \ + ../hsearch/*.[ch] \ + ../lock/*.[ch] \ + ../log/*.[ch] \ + ../mp/*.[ch] \ + ../mutex/*.[ch] \ + ../os/*.[ch] \ + ../os_qnx/*.[ch] \ + ../qam/*.[ch] \ + ../rep/*.[ch] \ + ../repmgr/*.[ch] \ + ../rpc_client/*.[ch] \ + ../rpc_server/c/*.[ch] \ + ../sequence/*.[ch] \ + ../tcl/*.[ch] \ + ../txn/*.[ch] \ + ../cxx/*.cpp \ + ../libdb_java/*.[ch] | sed 's/[^ ]*stub.c//g'` + +f=tags +echo "Building $f" +rm -f $f + +# Figure out what flags this ctags accepts. +flags="" +if ctags -d ../db/db.c 2>/dev/null; then + flags="-d $flags" +fi +if ctags -t ../db/db.c 2>/dev/null; then + flags="-t $flags" +fi +if ctags -w ../db/db.c 2>/dev/null; then + flags="-w $flags" +fi + +ctags $flags $files 2>/dev/null +chmod 444 $f + +for i in test_perf test_repmgr test_server; do + test -d ../$i || continue + + f=../$i/tags + echo "Building $f" + (cd ../$i && ctags $flags *.[ch] 2>/dev/null) + chmod 444 $f +done diff --git a/src/libs/resiprocate/contrib/db/dist/s_test b/src/libs/resiprocate/contrib/db/dist/s_test new file mode 100644 index 00000000..9e4636a7 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_test @@ -0,0 +1,111 @@ +#!/bin/sh - +# $Id$ +# +# Build the Tcl test files. + +msg1="# Automatically built by dist/s_test; may require local editing." +msg2="# Automatically built by dist/s_test; may require local editing." + +t=/tmp/__t +trap 'rm -f $t; exit 0' 0 1 2 3 13 15 + +. RELEASE + +(echo "$msg1" && \ + echo "" && \ + echo "set tclsh_path @TCL_TCLSH@" && \ + echo "set tcllib .libs/libdb_tcl-@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@@LIBTSO_MODSUFFIX@" && \ + echo "" && \ + echo "set rpc_server localhost" && \ + echo "set rpc_path ." && \ + echo "set rpc_testdir \$rpc_path/TESTDIR" && \ + echo "" && \ + echo "set src_root @srcdir@/.." && \ + echo "set test_path @srcdir@/../test" && \ + echo "set je_root @srcdir@/../../je" && \ + echo "" && \ + echo "global testdir" && \ + echo "set testdir ./TESTDIR" && \ + echo "" && \ + echo "global dict" && \ + echo "global util_path" && \ + echo "" && \ + echo "global is_freebsd_test" && \ + echo "global is_hp_test" && \ + echo "global is_linux_test" && \ + echo "global is_qnx_test" && \ + echo "global is_sunos_test" && \ + echo "global is_windows_test" && \ + echo "global is_windows9x_test" && \ + echo "" && \ + echo "global valid_methods" && \ + echo "global checking_valid_methods" && \ + echo "global test_recopts" && \ + echo "" && \ + echo "set KILL \"@KILL@\"") > $t + +f=../test/include.tcl +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +(echo "$msg1" && \ + echo "" && \ + echo "set tclsh_path SET_YOUR_TCLSH_PATH" && \ + echo "set buildpath Win32/Debug" && \ + echo "set tcllib libdb_tcl${DB_VERSION_MAJOR}${DB_VERSION_MINOR}d.dll" && \ + echo "" && \ + echo "set src_root .." && \ + echo "set test_path ../test" && \ + echo "set je_root ../../je" && \ + echo "" && \ + echo "global testdir" && \ + echo "set testdir ./TESTDIR" && \ + echo "" && \ + echo "global dict" && \ + echo "global util_path" && \ + echo "" && \ + echo "global is_freebsd_test" && \ + echo "global is_hp_test" && \ + echo "global is_linux_test" && \ + echo "global is_qnx_test" && \ + echo "global is_sunos_test" && \ + echo "global is_windows_test" && \ + echo "global is_windows9x_test" && \ + echo "" && \ + echo "global valid_methods" && \ + echo "global checking_valid_methods" && \ + echo "global test_recopts" && \ + echo "" && \ + echo "set KILL dbkill.exe") > $t + +f=../build_windows/include.tcl +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +# Build the test directory TESTS file. +(echo $msg2; +cat `egrep -l '^#[ ][ ]*TEST' ../test/*.tcl` | +sed -e '/^#[ ][ ]*TEST/!{' \ + -e 's/.*//' \ + -e '}' | +cat -s | +sed -e '/TEST/{' \ + -e 's/^#[ ][ ]*TEST[ ]*//' \ + -e 's/^ //' \ + -e 'H' \ + -e 'd' \ + -e '}' \ + -e 's/.*//' \ + -e x \ + -e 's/\n/__LINEBREAK__/g' | +sort | +sed -e 's/__LINEBREAK__/\ +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\ +/' \ + -e 's/__LINEBREAK__/\ + /g' | +sed -e 's/^[ ][ ]*$//') > $t + +f=../test/TESTS +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) diff --git a/src/libs/resiprocate/contrib/db/dist/s_vxworks b/src/libs/resiprocate/contrib/db/dist/s_vxworks new file mode 100644 index 00000000..4b95f972 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_vxworks @@ -0,0 +1,528 @@ +#!/bin/sh - +# $Id$ +# +# Build the VxWorks files. + +msgc="/* DO NOT EDIT: automatically built by dist/s_vxworks. */" + +. RELEASE + +s=/tmp/__db_a +t=/tmp/__db_b +u=/tmp/__db_c +vxfilelist=/tmp/__db_d +vxsmallfiles=/tmp/__db_e + +trap 'rm -f $s $t $u $vxfilelist $vxsmallfiles ; exit 0' 0 +trap 'rm -f $s $t $u $vxfilelist $vxsmallfiles ; exit 1' 1 2 3 13 15 + +# Build the VxWorks db.h. +cat < $s +/extern "C" {/{ +n +n +i\\ +\\ +/* Tornado 2 does not provide a standard C pre-processor #define. */\\ +#ifndef __vxworks\\ +#define __vxworks\\ +#endif +} +/@inttypes_h_decl@/d +/@stddef_h_decl@/d +/@stdint_h_decl@/d +/@unistd_h_decl@/d +/@thread_h_decl@/d +s/@u_int8_decl@/typedef unsigned char u_int8_t;/ +/@int16_decl@/d +s/@u_int16_decl@/typedef unsigned short u_int16_t;/ +/@int32_decl@/d +s/@u_int32_decl@/typedef unsigned int u_int32_t;/ +s/@int64_decl@// +s/@u_int64_decl@/typedef unsigned long long u_int64_t;/ +/@u_char_decl@/d +/@u_int_decl@/d +/@u_long_decl@/d +/@u_short_decl@/d +s/@uintmax_t_decl@/typedef unsigned long uintmax_t;/ +s/@uintptr_t_decl@/typedef unsigned long uintptr_t;/ +/@FILE_t_decl@/d +/@off_t_decl@/d +/@pid_t_decl@/d +/@size_t_decl@/d +/@ssize_t_decl@/d +/@time_t_decl@/d +s/@db_seq_decl@/typedef int db_seq_t;/ +s/@db_threadid_t_decl@/typedef uintmax_t db_threadid_t;/ +s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/ +s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/ +s/@DB_VERSION_PATCH@/$DB_VERSION_PATCH/ +s/@DB_VERSION_STRING@/"$DB_VERSION_STRING"/ +s/@DB_VERSION_UNIQUE_NAME@// +s/@DB_CONST@// +s/@DB_PROTO1@/#undef __P/ +s/@DB_PROTO2@/#define __P(protos) protos/ +/@platform_header@/d +/@platform_footer@/d +ENDOFSEDTEXT +(echo "$msgc" && + sed -f $s ../dbinc/db.in && + cat ../dbinc_auto/api_flags.in && + cat ../dbinc_auto/ext_prot.in) > $t +test `egrep '@.*@' $t` && { + egrep '@.*@' $t + echo 'Unexpanded autoconf variables found in VxWorks db.h.' + exit 1 +} +f=../build_vxworks/db.h +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +# Build the VxWorks db_cxx.h. +cat < $s +s/@cxx_have_stdheaders@/#define HAVE_CXX_STDHEADERS 1/ +ENDOFSEDTEXT +(echo "$msgc" && sed -f $s ../dbinc/db_cxx.in) > $t +test `egrep '@.*@' $t` && { + egrep '@.*@' $t + echo 'Unexpanded autoconf variables found in VxWorks db_cxx.h.' + exit 1 +} +f=../build_vxworks/db_cxx.h +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +# Build the VxWorks db_int.h. +cat < $s +s/@PATH_SEPARATOR@/\/\\\\\\\\/ +s/@db_int_def@// +/#ifdef.*HAVE_SYSTEM_INCLUDE_FILES/i\\ +#include "vxWorks.h" +/#endif.*HAVE_SYSTEM_INCLUDE_FILES/a\\ +#include "clib_port.h"\\ +#include "db.h" +ENDOFSEDTEXT +(echo "$msgc" && sed -f $s ../dbinc/db_int.in) > $t +test `egrep '@.*@' $t` && { + egrep '@.*@' $t + echo 'Unexpanded autoconf variables found in VxWorks db_int.h.' + exit 1 +} +f=../build_vxworks/db_int.h +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +# Build the VxWorks db_config.h. +# We don't fail, but we complain if the vx_config.in file isn't up-to-date. +check_config() +{ + egrep '^#undef' config.hin | awk '{print $2}' | sort > $s + (egrep '#undef' $1 | awk '{print $3}' + egrep '^#define' $1 | awk '{print $2}') | sort > $t + cmp $s $t > /dev/null || { + echo "config.hin and $1 differ" + echo "<<< config.hin >>> $1" + diff $s $t + } +} +check_config vx_config.in +f=../build_vxworks/db_config.h +(echo "$msgc" && sed "s/__EDIT_DB_VERSION__/$DB_VERSION/" vx_config.in) > $t +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +# Build the VxWorks db_config_small.h. +f=../build_vxworks/db_config_small.h +(echo "$msgc" && + sed -e "s/__EDIT_DB_VERSION__/$DB_VERSION/" \ + -e "s;^#define.*HAVE_CRYPTO.*1;/* #undef HAVE_CRYPTO */;" \ + -e "s;^#define.*HAVE_HASH.*1;/* #undef HAVE_HASH */;" \ + -e "s;^#define.*HAVE_QUEUE.*1;/* #undef HAVE_QUEUE */;" \ + -e "s;^#define.*HAVE_REPLICATION.*1;/* #undef HAVE_REPLICATION */;" \ + -e "s;^#define.*HAVE_STATISTICS.*1;/* #undef HAVE_STATISTICS */;" \ + -e "s;^#define.*HAVE_VERIFY.*1;/* #undef HAVE_VERIFY */;" \ + vx_config.in) > $t +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +# Build the VxWorks clib_port.h. +cat < $s +s/@INT64_FMT@/#define INT64_FMT "%lld"/ +s/@UINT64_FMT@/#define UINT64_FMT "%llu"/ +ENDOFSEDTEXT +sed -f $s clib_port.in > $t +test `egrep '@.*@' $t` && { + egrep '@.*@' $t + echo 'Unexpanded autoconf variables found in VxWorks clib_port.h.' + exit 1 +} +f=../build_vxworks/clib_port.h +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +# Build a sed script that will change a "standard" DB utility into +# VxWorks-compatible code. +transform() +{ + # Build a sed script that will add argument parsing support and + # rename all of the functions to be private to this file. +cat <\\ +#define ERROR_RETURN ERROR\\ +\\ +int\\ +$1_main(argc, argv) +d +} +/^ while ((ch = getopt/i\\ +\\ __db_getopt_reset = 1; +/^[ ]*extern int optind;/s/;/, __db_getopt_reset;/ +ENDOFSEDTEXT + + # Convert the ex_access sample into dbdemo for VxWorks. + echo 's/progname = "ex_access";/progname = "dbdemo";/' + + # The example programs have to load db_int.h, not db.h -- else + # they won't have the right Berkeley DB prototypes for getopt + # and friends. + echo '/#include.*db.h/c\' + echo '#include \' + echo '#include ' + + # Replace all function names with VxWorks safe names. + # Function names are: + # Tokens starting at the beginning of the line, immediately + # followed by an opening parenthesis. + # Replace: + # Matches preceded by a non-C-token character and immediately + # followed by an opening parenthesis. + # Matches preceded by a non-C-token character and immediately + # followed by " __P". + # Matches starting at the beginning of the line, immediately + # followed by an opening parenthesis. + # + # Skip any line that starts with the name we're using as a prefix, + # it's a case we can't handle very well here, and it's been done by + # hand. + sed \ + -e "/^$1/d" \ + -e 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)(.*$/\1/p' -e d > $u + for k in `cat $u`; do +cat < $s + cat ../$i | sed -f $s > $t;; + test_micro*) + target=test_micro/`basename $i` + cat ../$i | transform `basename $i .c` > $s + cat ../$i | sed -f $s > $t;; + *) + target="$i" + cat ../$i | transform `basename $i .c` > $s + cat ../$i | sed -f $s > $t;; + esac + + f=../build_vxworks/$target + cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) +done + +# Output the build lines for a single utility. +# $1 == application name +util_one() +{ + egrep "app=$1" srcfiles.in | + awk '{print $1}' | + sed 's/ex_access/dbdemo/' > $u + + # Build a list of source files. + for i in `cat $u`; do + if test "$1" = "ex_access" -o "$1" = `basename $i .c`; then + i=`basename $i` + else + i="\$(PRJ_DIR)/../../$i" + fi + o=" FILE_$i" + + echo "${o}_dependDone" + echo "FALSE" + echo "" + echo + echo "${o}_dependencies" + echo "" + echo + echo "${o}_objects" + echo "`basename $i .c`.o" + echo "" + echo + echo "${o}_tool" + echo "C/C++ compiler" + echo "" + echo + done + echo " PROJECT_FILES" + for i in `cat $u`; do + if test "$1" = "ex_access" -o "$1" = `basename $i .c`; then + i="`basename $i`" + else + i="../../$i" + fi + echo "\$(PRJ_DIR)/$i" + done | + sed -e '${' \ + -e 'p' \ + -e 'd' \ + -e '}' \ + -e 's/$/ \\/' + echo "" + echo + echo " userComments" + if test "$1" = "ex_access"; then + echo "dbdemo" + else + echo "$1" + fi + echo "" +} + +# Build VxWorks Tornado 2.0 project files for the utilities. +for i in $PROGRAM_LIST; do + if [ $i = "ex_access" ]; then + target=dbdemo + else + target=$i + fi + + (sed -e "s/__DB_APPLICATION_NAME__/$target/g" < vx_2.0/wpj.in + util_one $i) > $t + f=../build_vxworks/$target/${target}20.wpj + cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + + (sed -e "s/__DB_APPLICATION_NAME__/$target/g" < vx_2.2/wpj.in + util_one $i) > $t + f=../build_vxworks/$target/${target}22.wpj + cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) +done + +# Build the list of "normal build" files VxWorks knows about. +sed -e '/^$/d' -e '/^[ #]/d' srcfiles.in | + egrep -w vx | + sed 's/[ ].*//' > $vxfilelist + +# Build the list of "small build" files VxWorks knows about. +sed -e '/^$/d' -e '/^[ #]/d' srcfiles.in | + egrep -w vxsmall | + sed 's/[ ].*//' > $vxsmallfiles + +# Build VxWorks Tornado 2.0 project files for the library itself. +for v in 0 2 ; do + # + # Build regular project files + # + (cat vx_2.${v}/BerkeleyDB.wpj + for i in `cat $vxfilelist`; do + o=" FILE_\$(PRJ_DIR)/../$i" + echo "${o}_dependDone" + echo "TRUE" + echo "" + echo + echo "${o}_dependencies" + echo "\$(PRJ_DIR)/db_config.h \\" + echo " \$(PRJ_DIR)/db_int.h \\" + echo " \$(PRJ_DIR)/db.h" + echo "" + echo + echo "${o}_objects" + echo "`basename $i .c`.o" + echo "" + echo + echo "${o}_tool" + echo "C/C++ compiler" + echo "" + echo + done + echo " PROJECT_FILES" + sed -e '$!s/$/ \\/' \ + -e 's/^/$(PRJ_DIR)\/..\//' \ + -e '1!s/^/ /' < $vxfilelist + echo "" + echo + echo " userComments" + echo "BerkeleyDB" + echo "") > $t + # + # Build small lib project files + # + (cat vx_2.${v}/BerkeleyDBsmall.wpj + for i in `cat $vxsmallfiles`; do + o=" FILE_\$(PRJ_DIR)/../$i" + echo "${o}_dependDone" + echo "TRUE" + echo "" + echo + echo "${o}_dependencies" + echo "\$(PRJ_DIR)/db_config.h \\" + echo " \$(PRJ_DIR)/db_int.h \\" + echo " \$(PRJ_DIR)/db.h" + echo "" + echo + echo "${o}_objects" + echo "`basename $i .c`.o" + echo "" + echo + echo "${o}_tool" + echo "C/C++ compiler" + echo "" + echo + done + echo " PROJECT_FILES" + sed -e '$!s/$/ \\/' \ + -e 's/^/$(PRJ_DIR)\/..\//' \ + -e '1!s/^/ /' < $vxsmallfiles + echo "" + echo + echo " userComments" + echo "BerkeleyDB" + echo "") > $u + f=../build_vxworks/BerkeleyDB2${v}.wpj + cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + f=../build_vxworks/BerkeleyDB2${v}small.wpj + cmp $u $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $u $f && chmod 444 $f) +done + +# vx6 -- +# Generate a VxWorks 6.X Makefile. +# +# $1: list of files +vx6() +{ + # Build VxWorks 6x Makefile. + cat vx_6/Makefile.1 + echo + sed -e 's/\.c$//p' -e d < $1 > $s + for i in `cat $s`; do + sed "s;__FILENAME__;$i;g" < vx_6/cfile + done + echo + sed -e 's/\.cpp$//p' -e d < $1 > $s + for i in `cat $s`; do + sed "s;__FILENAME__;$i;g" < vx_6/cxxfile + done + echo + sed -e 's/\.c.*//' < $1 > $s + /bin/echo -n "OBJECTS_bdbvxw =" + sep=" \\" + for i in `cat $s`; do + echo "$sep" + /bin/echo -n ' bdbvxw/$(MODE_DIR)/Objects/$(BDB_OBJECT_DIR)/' + /bin/echo -n "$i.o" + done + echo + echo + cat vx_6/Makefile.2 + echo + /bin/echo -n "DEP_FILES :=" + for i in `cat $s`; do + echo "$sep" + /bin/echo -n ' bdbvxw/$(MODE_DIR)/Objects/$(BDB_OBJECT_DIR)/' + /bin/echo -n "$i.d" + done + echo + echo + cat vx_6/Makefile.3 +} + +# Build the list of "normal build" files VxWorks 6x knows about -- it's +# the standard Vx list plus some additions. +sed -e '/^$/d' -e '/^[ #]/d' srcfiles.in | + egrep -w vx6 | + sed 's/[ ].*//' >> $vxfilelist +vx6 $vxfilelist > $t +f=../build_vxworks/Makefile.6x +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +# Build the list of "small build" files VxWorks 6x knows about -- it's +# the standard vxsmall list. +sed -e '/^$/d' -e '/^[ #]/d' srcfiles.in | + egrep -w vxsmall | + sed 's/[ ].*//' >> $vxfilelist +vx6 $vxsmallfiles > $t +f=../build_vxworks/Makefile.6x.small +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) diff --git a/src/libs/resiprocate/contrib/db/dist/s_win32 b/src/libs/resiprocate/contrib/db/dist/s_win32 new file mode 100644 index 00000000..acdb9224 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_win32 @@ -0,0 +1,153 @@ +#!/bin/sh - +# $Id: s_win32,v 1.37 2004/10/15 18:28:21 bostic Exp $ +# +# Build Windows/32 include files. + +msgc="/* DO NOT EDIT: automatically built by dist/s_win32. */" +msgw="; DO NOT EDIT: automatically built by dist/s_win32." + +. RELEASE + +s=/tmp/__db_a$$ +t=/tmp/__db_b$$ +rm -f $s $t + +trap 'rm -f $s $t ; exit 1' 1 2 3 13 15 + +# Build the Win32 automatically generated files. +cat < $s +/@inttypes_h_decl@/d +/@stdint_h_decl@/d +s/@stddef_h_decl@/#include / +s/@u_int8_decl@/typedef unsigned char u_int8_t;/ +s/@int16_decl@/typedef short int16_t;/ +s/@u_int16_decl@/typedef unsigned short u_int16_t;/ +s/@int32_decl@/typedef int int32_t;/ +s/@u_int32_decl@/typedef unsigned int u_int32_t;/ +s/@int64_decl@/typedef __int64 int64_t;/ +s/@u_int64_decl@/typedef unsigned __int64 u_int64_t;/ +s/@db_seq_decl@/typedef int64_t db_seq_t;/ +/@u_char_decl@/{ + i\\ +#ifndef _WINSOCKAPI_ + s/@u_char_decl@/typedef unsigned char u_char;/ +} +s/@u_short_decl@/typedef unsigned short u_short;/ +s/@u_int_decl@/typedef unsigned int u_int;/ +/@u_long_decl@/{ + s/@u_long_decl@/typedef unsigned long u_long;/ + a\\ +#endif +} +/@ssize_t_decl@/{ + i\\ +#ifdef _WIN64\\ +typedef int64_t ssize_t;\\ +#else\\ +typedef int32_t ssize_t;\\ +#endif + d +} +s/@uintmax_t_decl@/typedef u_int64_t uintmax_t;/ +/@uintptr_t_decl@/{ + i\\ +#ifdef _WIN64\\ +typedef u_int64_t uintptr_t;\\ +#else\\ +typedef u_int32_t uintptr_t;\\ +#endif + d +} +s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/ +s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/ +s/@DB_VERSION_PATCH@/$DB_VERSION_PATCH/ +s/@DB_VERSION_STRING@/"$DB_VERSION_STRING"/ +s/@DB_VERSION_UNIQUE_NAME@// +s/@DB_CONST@// +s/@DB_PROTO1@/#undef __P/ +s/@DB_PROTO2@/#define __P(protos) protos/ +ENDOFSEDTEXT +(echo "$msgc" && + sed -f $s ../dbinc/db.in && + cat ../dbinc_auto/ext_prot.in) > $t +`egrep '@.*@' $t` && { + echo 'Unexpanded autoconf variables found in Windows db.h.' + exit 1 +} +f=../build_win32/db.h +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) +f=../build_win64/db.h +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +cat < $s +s/@cxx_have_stdheaders@/#define HAVE_CXX_STDHEADERS 1/ +ENDOFSEDTEXT +(echo "$msgc" && sed -f $s ../dbinc/db_cxx.in) > $t +`egrep '@.*@' $t` && { + echo 'Unexpanded autoconf variables found in Windows db_cxx.h.' + exit 1 +} +f=../build_win32/db_cxx.h +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) +f=../build_win64/db_cxx.h +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +cat < $s +s/@PATH_SEPARATOR@/\\\\\\\\\/:/ +s/@db_int_def@// +ENDOFSEDTEXT +(echo "$msgc" && sed -f $s ../dbinc/db_int.in) > $t +`egrep '@.*@' $t` && { + echo 'Unexpanded autoconf variables found in Windows db_int.h.' + exit 1 +} +f=../build_win32/db_int.h +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) +f=../build_win64/db_int.h +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +f=../build_win32/db_config.h +(echo "$msgc" && sed "s/__EDIT_DB_VERSION__/$DB_VERSION/" win_config.in) > $t +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) +f=../build_win64/db_config.h +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +f=../build_win32/libdb.rc +cat < $s +s/%MAJOR%/$DB_VERSION_MAJOR/ +s/%MINOR%/$DB_VERSION_MINOR/ +s/%PATCH%/$DB_VERSION_PATCH/ +ENDOFSEDTEXT +sed -f $s ../build_win32/libdbrc.src > $t +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +f=../build_win32/libdb.def +(echo $msgw && + echo && + echo EXPORTS; +a=1 +for i in `sed -e '/^$/d' -e '/^#/d' win_exports.in`; do + echo " $i @$a" + a=`expr $a + 1` +done) > $t +cmp $t $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) + +f=../build_win32/win_db.h +i=win_db.in +cmp $i $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $i $f && chmod 444 $f) +f=../build_win64/win_db.h +cmp $i $f > /dev/null 2>&1 || + (echo "Building $f" && rm -f $f && cp $i $f && chmod 444 $f) + +rm -f $s $t diff --git a/src/libs/resiprocate/contrib/db/dist/s_win32_dsp b/src/libs/resiprocate/contrib/db/dist/s_win32_dsp new file mode 100644 index 00000000..10e0ccc4 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/s_win32_dsp @@ -0,0 +1,118 @@ +#!/bin/sh - +# $Id: s_win32_dsp,v 1.12 2004/08/20 15:01:06 mjc Exp $ +# +# Build Windows/32 .dsp files. + +. RELEASE + +SRCFILES=srcfiles.in + +create_dsp() +{ + projname="$1" # name of the .dsp file + match="$2" # the string used to egrep the $sources file + sources="$3" # a modified version of $SRCFILES to facilitate matches + dsptemplate="$4" # overall template file for the .dsp + srctemplate="$5" # template file for the src file fragments + + dspoutput=$BUILDDIR/$projname.dsp + + rm -f $dspoutput.insert + for srcpath in `egrep "$match" $sources | sed -e 's/[ ].*//'` + do + # take the path name and break it up, converting / to \\. + # so many backslashes needed because of shell quoting and + # sed quoting -- we'll end up with two backslashes for every + # forward slash, but we need that when feeding that to the + # later sed command. + set - `echo $srcpath | sed -e 's;\(.*\)/;../\\1 ;' \ + -e "s;$BUILDDIR;.;" \ + -e 's;/;\\\\\\\\;g'` + srcdir="$1" + srcfile="$2" + sed -e "s/@srcdir@/$srcdir/g" \ + -e "s/@srcfile@/$srcfile/g" \ + < $srctemplate >> $dspoutput.insert + done + sed -e "/@SOURCE_FILES@/r$dspoutput.insert" \ + -e "/@SOURCE_FILES@/d" \ + -e "s/@project_name@/$projname/g" \ + -e "s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/g" \ + -e "s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/g" \ + < $dsptemplate > $dspoutput.new + + # Set the file mode to 644 because the VC++ IDE needs a writeable file + # in our development environment. + cmp $dspoutput.new $dspoutput > /dev/null 2>&1 || + (echo "Building $dspoutput" && rm -f $dspoutput && + cp $dspoutput.new $dspoutput && chmod 664 $dspoutput) + rm -f $dspoutput.insert $dspoutput.new +} + +TMPA=/tmp/swin32dsp$$a +trap "rm -f $TMPA; exit 1" 1 2 3 15 + +# create a copy of the srcfiles with comments and empty lines removed. +# add a space at the end of each list of modules so that each module +# can be unambiguously matched e.g. ' dynamic ' +sed -e "s/#.*$//" \ + -e "/^[ ]*$/d" \ + -e "s/[ ][ ]*/ /" \ + -e "s/[ ]*$//" \ + -e "/[ ]/!d" \ + -e "s/$/ /" < $SRCFILES > $TMPA + +# get a list of all modules mentioned +# +MODULES="`sed -e 's/^[^ ]* //' < $TMPA \ + | tr ' ' '\012' | sort | uniq`" + +for BUILDDIR in ../build_win32 ../build_win64 +do + for module in $MODULES + do + case "$module" in + dynamic ) + create_dsp db_dll " $module " $TMPA \ + $BUILDDIR/dynamic_dsp.src $BUILDDIR/srcfile_dsp.src + ;; + small ) + create_dsp db_small " $module " $TMPA \ + $BUILDDIR/small_dsp.src $BUILDDIR/srcfile_dsp.src + ;; + static ) + create_dsp db_static " $module " $TMPA \ + $BUILDDIR/static_dsp.src $BUILDDIR/srcfile_dsp.src + ;; + java ) + create_dsp db_java " $module " $TMPA \ + $BUILDDIR/java_dsp.src $BUILDDIR/srcfile_dsp.src + ;; + tcl ) + create_dsp db_tcl " $module " $TMPA \ + $BUILDDIR/tcl_dsp.src $BUILDDIR/srcfile_dsp.src + ;; + testutil ) + create_dsp db_test " $module " $TMPA \ + $BUILDDIR/db_test.src $BUILDDIR/srcfile_dsp.src + ;; + app=* ) + appname=`echo $module | sed -e 's/^app=//'` + if [ -f $BUILDDIR/$appname.src ] ; then + srcname=$BUILDDIR/$appname.src + else + srcname=$BUILDDIR/app_dsp.src + fi + create_dsp $appname " $module " $TMPA \ + $srcname $BUILDDIR/srcfile_dsp.src + ;; + vx|vxsmall ) + ;; + * ) + echo "s_win32_dsp: module name $module in $SRCFILES is unknown type" + ;; + esac + done +done + +rm -f $TMPA diff --git a/src/libs/resiprocate/contrib/db/dist/srcfiles.in b/src/libs/resiprocate/contrib/db/dist/srcfiles.in new file mode 100644 index 00000000..b39c575b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/srcfiles.in @@ -0,0 +1,498 @@ +# $Id$ +# +# This is an input file for the s_windows_dsp and s_vxworks scripts. It lists +# the source files in the Berkeley DB tree and notes which are used to build +# the Windows and VxWorks libraries. +# +# Please keep this list sorted alphabetically! +# +# Each non-blank, non-comment line is of the form +# filename module [ module ...] +# +# The possible Windows modules, including the name of the project (.dsp) file: +# +# app=NAME Windows: Linked into application NAME.exe (db_NAME.dsp) +# dynamic Windows: File is in the Windows DLL (db_dll.dsp) +# small Windows: File is in the small Windows library (db_small.dsp) +# static Windows: File is in the Windows static library (db_static.dsp) +# java Windows: File is in the Windows Java DLL (db_java.dsp) +# tcl Windows: File is in the Windows tcl DLL (db_tcl.dsp) +# testutil Windows: File is used for Windows testing (db_test.dsp) + +btree/bt_compact.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_compare.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_compress.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_conv.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_curadj.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_cursor.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_delete.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_method.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_open.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_put.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_rec.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_reclaim.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_recno.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_rsearch.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_search.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_split.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_stat.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/bt_upgrade.c ce ce_small dynamic small static vx vxsmall +btree/bt_verify.c ce ce_small dynamic static vx +btree/btree_auto.c brew ce ce_small dynamic small static s60 vx vxsmall +btree/btree_autop.c app=db_printlog vx6 +build_vxworks/db_archive/db_archive.c vx6 +build_vxworks/db_checkpoint/db_checkpoint.c vx6 +build_vxworks/db_deadlock/db_deadlock.c vx6 +build_vxworks/db_dump/db_dump.c vx6 +build_vxworks/db_hotbackup/db_hotbackup.c vx6 +build_vxworks/db_load/db_load.c vx6 +build_vxworks/db_printlog/db_printlog.c vx6 +build_vxworks/db_recover/db_recover.c vx6 +build_vxworks/db_stat/db_stat.c vx6 +build_vxworks/db_upgrade/db_upgrade.c vx6 +build_vxworks/db_verify/db_verify.c vx6 +build_vxworks/dbdemo/dbdemo.c vx6 +build_vxworks/test_micro/b_curalloc.c vx6 +build_vxworks/test_micro/b_curwalk.c vx6 +build_vxworks/test_micro/b_del.c vx6 +build_vxworks/test_micro/b_get.c vx6 +build_vxworks/test_micro/b_inmem.c vx6 +build_vxworks/test_micro/b_latch.c vx6 +build_vxworks/test_micro/b_load.c vx6 +build_vxworks/test_micro/b_open.c vx6 +build_vxworks/test_micro/b_put.c vx6 +build_vxworks/test_micro/b_recover.c vx6 +build_vxworks/test_micro/b_txn.c vx6 +build_vxworks/test_micro/b_txn_write.c vx6 +build_vxworks/test_micro/b_uname.c vx6 +build_vxworks/test_micro/b_util.c vx6 +build_vxworks/test_micro/b_workload.c vx6 +build_vxworks/test_micro/test_micro.c vx6 +build_windows/dbkill.cpp testutil +build_windows/libdb.def dynamic +build_windows/libdb.rc dynamic +build_windows/libdb_tcl.def tcl +clib/atoi.c +clib/atol.c brew +clib/getcwd.c +clib/getopt.c vx vxsmall +clib/isalpha.c brew +clib/isdigit.c brew +clib/isprint.c brew +clib/isspace.c brew +clib/memcmp.c +clib/memmove.c +clib/printf.c brew +clib/qsort.c brew +clib/raise.c +clib/rand.c brew +clib/snprintf.c s60 vx vxsmall +clib/strcasecmp.c brew s60 vx vxsmall +clib/strcat.c +clib/strchr.c +clib/strdup.c ce ce_small vx vxsmall +clib/strerror.c ce ce_small brew +clib/strncat.c brew +clib/strncmp.c +clib/strrchr.c +clib/strsep.c brew ce ce_small dynamic small static s60 vx vxsmall +clib/strtol.c brew +clib/strtoul.c +clib/time.c brew ce ce_small +common/crypto_stub.c brew ce_small small s60 vxsmall ce dynamic static vx +common/db_byteorder.c brew ce ce_small dynamic small static s60 vx vxsmall +common/db_compint.c brew ce ce_small dynamic small static s60 vx vxsmall +common/db_err.c brew ce ce_small dynamic small static s60 vx vxsmall +common/db_getlong.c brew ce ce_small dynamic small static s60 vx vxsmall +common/db_idspace.c brew ce ce_small dynamic small static s60 vx vxsmall +common/db_log2.c brew ce ce_small dynamic small static s60 vx vxsmall +common/db_shash.c brew ce ce_small dynamic small static s60 vx vxsmall +common/dbt.c brew ce ce_small dynamic small static s60 vx vxsmall +common/mkpath.c brew ce ce_small dynamic small static s60 vx vxsmall +common/openflags.c dynamic static +common/os_method.c dynamic small static vx vxsmall +common/util_arg.c app=test_micro vx vxsmall +common/util_cache.c ce ce_small dynamic small static vx vxsmall +common/util_log.c ce ce_small dynamic small static vx vxsmall +common/util_sig.c dynamic small static vx vxsmall +common/zerofill.c brew ce ce_small dynamic small static s60 vx vxsmall +cxx/cxx_db.cpp dynamic small static vx6 +cxx/cxx_dbc.cpp dynamic small static vx6 +cxx/cxx_dbt.cpp dynamic small static vx6 +cxx/cxx_env.cpp dynamic small static vx6 +cxx/cxx_except.cpp dynamic small static vx6 +cxx/cxx_lock.cpp dynamic small static vx6 +cxx/cxx_logc.cpp dynamic small static vx6 +cxx/cxx_mpool.cpp dynamic small static vx6 +cxx/cxx_multi.cpp dynamic small static vx6 +cxx/cxx_seq.cpp dynamic small static vx6 +cxx/cxx_txn.cpp dynamic small static vx6 +db/crdel_auto.c brew ce ce_small dynamic small static s60 vx vxsmall +db/crdel_autop.c app=db_printlog vx6 +db/crdel_rec.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_am.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_auto.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_autop.c app=db_printlog vx6 +db/db_cam.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_cds.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_conv.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_dispatch.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_dup.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_iface.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_join.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_meta.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_method.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_open.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_overflow.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_ovfl_vrfy.c ce dynamic static vx +db/db_pr.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_rec.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_reclaim.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_remove.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_rename.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_ret.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_setid.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_setlsn.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_sort_multiple.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_stati.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_truncate.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_upg.c brew ce ce_small dynamic small static s60 vx vxsmall +db/db_upg_opd.c ce ce_small dynamic small static vx vxsmall +db/db_vrfy.c ce dynamic static vx +db/db_vrfy_stub.c brew ce_small small s60 vxsmall +db/db_vrfyutil.c ce dynamic static vx +db/partition.c ce ce_small dynamic small static vx +db185/db185.c +db_archive/db_archive.c app=db_archive +db_checkpoint/db_checkpoint.c app=db_checkpoint +db_deadlock/db_deadlock.c app=db_deadlock +db_dump/db_dump.c app=db_dump +db_dump185/db_dump185.c +db_hotbackup/db_hotbackup.c app=db_hotbackup +db_load/db_load.c app=db_load +db_printlog/db_printlog.c app=db_printlog +db_recover/db_recover.c app=db_recover +db_server_clnt.c +db_server_svc.c +db_server_xdr.c +db_stat/db_stat.c app=db_stat +db_upgrade/db_upgrade.c app=db_upgrade +db_verify/db_verify.c app=db_verify +dbm/dbm.c dynamic static +dbreg/dbreg.c brew ce ce_small dynamic small static s60 vx vxsmall +dbreg/dbreg_auto.c brew ce ce_small dynamic small static s60 vx vxsmall +dbreg/dbreg_autop.c app=db_printlog vx6 +dbreg/dbreg_rec.c brew ce ce_small dynamic small static s60 vx vxsmall +dbreg/dbreg_stat.c brew ce ce_small dynamic small static s60 vx vxsmall +dbreg/dbreg_util.c brew ce ce_small dynamic small static s60 vx vxsmall +env/env_alloc.c brew ce ce_small dynamic small static s60 vx vxsmall +env/env_config.c brew ce ce_small dynamic small static s60 vx vxsmall +env/env_failchk.c brew ce ce_small dynamic small static s60 vx vxsmall +env/env_file.c brew ce ce_small dynamic small static s60 vx vxsmall +env/env_globals.c ce ce_small dynamic small static s60 vx vxsmall +env/env_method.c brew ce ce_small dynamic small static s60 vx vxsmall +env/env_name.c brew ce ce_small dynamic small static s60 vx vxsmall +env/env_open.c brew ce ce_small dynamic small static s60 vx vxsmall +env/env_recover.c brew ce ce_small dynamic small static s60 vx vxsmall +env/env_region.c brew ce ce_small dynamic small static s60 vx vxsmall +env/env_register.c brew ce ce_small dynamic small static s60 vx vxsmall +env/env_sig.c brew ce ce_small dynamic small static s60 vx vxsmall +env/env_stat.c brew ce ce_small dynamic small static s60 vx vxsmall +examples_c/bench_001.c +examples_c/csv/DbRecord.c app=ex_csvload app=ex_csvquery +examples_c/csv/code.c app=ex_csvcode +examples_c/csv/csv_local.c app=ex_csvload app=ex_csvquery +examples_c/csv/db.c app=ex_csvload app=ex_csvquery +examples_c/csv/load.c app=ex_csvload +examples_c/csv/load_main.c app=ex_csvload +examples_c/csv/query.c app=ex_csvquery +examples_c/csv/query_main.c app=ex_csvquery +examples_c/csv/util.c app=ex_csvload app=ex_csvquery +examples_c/ex_access.c app=ex_access +examples_c/ex_apprec/ex_apprec.c +examples_c/ex_apprec/ex_apprec_auto.c +examples_c/ex_apprec/ex_apprec_autop.c +examples_c/ex_apprec/ex_apprec_rec.c +examples_c/ex_btrec.c app=ex_btrec +examples_c/ex_dbclient.c +examples_c/ex_env.c app=ex_env +examples_c/ex_lock.c app=ex_lock +examples_c/ex_mpool.c app=ex_mpool +examples_c/ex_rep/base/rep_base.c app=ex_rep_base +examples_c/ex_rep/base/rep_msg.c app=ex_rep_base +examples_c/ex_rep/base/rep_net.c app=ex_rep_base +examples_c/ex_rep/common/rep_common.c app=ex_rep_base app=ex_rep_mgr +examples_c/ex_rep/mgr/rep_mgr.c app=ex_rep_mgr +examples_c/ex_sequence.c app=ex_sequence +examples_c/ex_stream.c app=ex_stream +examples_c/ex_thread.c +examples_c/ex_tpcb.c app=ex_tpcb +examples_c/getting_started/example_database_load.c app=example_database_load +examples_c/getting_started/example_database_read.c app=example_database_read +examples_c/getting_started/gettingstarted_common.c app=example_database_load app=example_database_read +examples_c/txn_guide/txn_guide.c app=ex_txnguide +examples_c/txn_guide/txn_guide_inmemory.c app=ex_txnguide_inmem +examples_cxx/AccessExample.cpp app=excxx_access +examples_cxx/BtRecExample.cpp app=excxx_btrec +examples_cxx/EnvExample.cpp app=excxx_env +examples_cxx/LockExample.cpp app=excxx_lock +examples_cxx/MpoolExample.cpp app=excxx_mpool +examples_cxx/SequenceExample.cpp app=excxx_sequence +examples_cxx/TpcbExample.cpp app=excxx_tpcb +examples_cxx/excxx_repquote/RepConfigInfo.cpp app=excxx_repquote +examples_cxx/excxx_repquote/RepQuoteExample.cpp app=excxx_repquote +examples_cxx/getting_started/MyDb.cpp app=excxx_example_database_load app=excxx_example_database_read +examples_cxx/getting_started/excxx_example_database_load.cpp app=excxx_example_database_load +examples_cxx/getting_started/excxx_example_database_read.cpp app=excxx_example_database_read +examples_cxx/txn_guide/TxnGuide.cpp app=excxx_txnguide +examples_cxx/txn_guide/TxnGuideInMemory.cpp app=excxx_txnguide_inmem +examples_cxx/wce_tpcb/TpcbExample.cpp app=wce_tpcb +examples_cxx/wce_tpcb/TpcbUI.cpp app=wce_tpcb +examples_cxx/wce_tpcb/wce_tpcb.rc app=wce_tpcb +fileops/fileops_auto.c brew ce ce_small dynamic small static s60 vx vxsmall +fileops/fileops_autop.c app=db_printlog vx6 +fileops/fop_basic.c brew ce ce_small dynamic small static s60 vx vxsmall +fileops/fop_rec.c brew ce ce_small dynamic small static s60 vx vxsmall +fileops/fop_util.c brew ce ce_small dynamic small static s60 vx vxsmall +gen_db_server.c +hash/hash.c ce dynamic static vx +hash/hash_auto.c ce dynamic static vx +hash/hash_autop.c app=db_printlog vx6 +hash/hash_conv.c ce dynamic static vx +hash/hash_dup.c ce dynamic static vx +hash/hash_func.c brew ce ce_small dynamic small static s60 vx vxsmall +hash/hash_meta.c ce dynamic static vx +hash/hash_method.c ce dynamic static vx +hash/hash_open.c ce dynamic static vx +hash/hash_page.c ce dynamic static vx +hash/hash_rec.c ce dynamic static vx +hash/hash_reclaim.c ce dynamic static vx +hash/hash_stat.c ce dynamic static vx +hash/hash_stub.c brew ce_small small s60 vxsmall +hash/hash_upgrade.c ce dynamic static vx +hash/hash_verify.c ce dynamic static vx +hmac/hmac.c brew ce ce_small dynamic small static s60 vx vxsmall +hmac/sha1.c brew ce ce_small dynamic small static s60 vx vxsmall +hsearch/hsearch.c dynamic static +libdb_java/db_java_wrap.c java +lock/lock.c ce ce_small dynamic small static s60 vx vxsmall +lock/lock_deadlock.c ce ce_small dynamic small static s60 vx vxsmall +lock/lock_failchk.c ce ce_small dynamic small static s60 vx vxsmall +lock/lock_id.c ce ce_small dynamic small static s60 vx vxsmall +lock/lock_list.c ce ce_small dynamic small static s60 vx vxsmall +lock/lock_method.c ce ce_small dynamic small static s60 vx vxsmall +lock/lock_region.c ce ce_small dynamic small static s60 vx vxsmall +lock/lock_stat.c ce ce_small dynamic small static s60 vx vxsmall +lock/lock_stub.c brew +lock/lock_timer.c ce ce_small dynamic small static s60 vx vxsmall +lock/lock_util.c ce ce_small dynamic small static s60 vx vxsmall +log/log.c brew ce ce_small dynamic small static s60 vx vxsmall +log/log_archive.c brew ce ce_small dynamic small static s60 vx vxsmall +log/log_compare.c brew ce ce_small dynamic small static s60 vx vxsmall +log/log_debug.c brew ce ce_small dynamic small static s60 vx vxsmall +log/log_get.c brew ce ce_small dynamic small static s60 vx vxsmall +log/log_method.c brew ce ce_small dynamic small static s60 vx vxsmall +log/log_put.c brew ce ce_small dynamic small static s60 vx vxsmall +log/log_stat.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_alloc.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_bh.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_fget.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_fmethod.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_fopen.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_fput.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_fset.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_method.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_mvcc.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_region.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_register.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_resize.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_stat.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_sync.c brew ce ce_small dynamic small static s60 vx vxsmall +mp/mp_trickle.c brew ce ce_small dynamic small static s60 vx vxsmall +mutex/mut_alloc.c ce ce_small dynamic small static s60 vx vxsmall +mutex/mut_failchk.c ce ce_small dynamic small static s60 vx vxsmall +mutex/mut_fcntl.c +mutex/mut_method.c ce ce_small dynamic small static s60 vx vxsmall +mutex/mut_pthread.c s60 +mutex/mut_region.c ce ce_small dynamic small static s60 vx vxsmall +mutex/mut_stat.c ce ce_small dynamic small static s60 vx vxsmall +mutex/mut_stub.c brew +mutex/mut_tas.c vx vxsmall +mutex/mut_win32.c ce ce_small dynamic small static +mutex/test_mutex.c app=test_mutex +os/os_abort.c ce ce_small dynamic small static s60 vx vxsmall tcl +os/os_abs.c s60 +os/os_addrinfo.c dynamic static +os/os_alloc.c brew ce ce_small dynamic small static s60 vx vxsmall +os/os_clock.c s60 vx vxsmall +os/os_config.c +os/os_cpu.c brew s60 vx vxsmall +os/os_ctime.c dynamic small static s60 vx vxsmall +os/os_dir.c s60 vx vxsmall +os/os_errno.c s60 vx vxsmall +os/os_fid.c brew s60 vx vxsmall +os/os_flock.c brew s60 vx vxsmall +os/os_fsync.c s60 vx vxsmall +os/os_getenv.c brew s60 vx vxsmall +os/os_handle.c s60 vx vxsmall +os/os_map.c brew s60 +os/os_mkdir.c s60 vx vxsmall +os/os_open.c s60 vx vxsmall +os/os_pid.c ce ce_small dynamic small static s60 vx vxsmall +os/os_rename.c s60 vx vxsmall +os/os_root.c brew ce ce_small dynamic small static s60 vx vxsmall +os/os_rpath.c brew ce ce_small dynamic small static s60 +os/os_rw.c s60 vx vxsmall +os/os_seek.c s60 vx vxsmall +os/os_stack.c brew ce ce_small dynamic small static s60 vx vxsmall tcl +os/os_stat.c s60 vx vxsmall +os/os_tmpdir.c brew ce ce_small dynamic small static s60 vx vxsmall +os/os_truncate.c s60 vx vxsmall +os/os_uid.c brew ce ce_small dynamic small static s60 vx vxsmall +os/os_unlink.c s60 vx vxsmall +os/os_yield.c s60 +os_brew/ctime.c brew +os_brew/fclose.c brew +os_brew/fgetc.c brew +os_brew/fgets.c brew +os_brew/fopen.c brew +os_brew/fwrite.c brew +os_brew/getcwd.c brew +os_brew/globals.c brew +os_brew/localtime.c brew +os_brew/os_abort.c brew +os_brew/os_abs.c brew +os_brew/os_clock.c brew +os_brew/os_config.c brew +os_brew/os_dir.c brew +os_brew/os_errno.c brew +os_brew/os_handle.c brew +os_brew/os_mkdir.c brew +os_brew/os_open.c brew +os_brew/os_pid.c brew +os_brew/os_rename.c brew +os_brew/os_rw.c brew +os_brew/os_seek.c brew +os_brew/os_stat.c brew +os_brew/os_truncate.c brew +os_brew/os_unlink.c brew +os_brew/os_yield.c brew +os_qnx/os_qnx_fsync.c +os_qnx/os_qnx_open.c +os_s60/os_config.c s60 +os_vxworks/os_vx_abs.c vx vxsmall +os_vxworks/os_vx_config.c vx vxsmall +os_vxworks/os_vx_map.c vx vxsmall +os_vxworks/os_vx_rpath.c vx vxsmall +os_vxworks/os_vx_yield.c vx vxsmall +os_windows/ce_ctime.c ce ce_small +os_windows/os_abs.c ce ce_small dynamic small static +os_windows/os_clock.c ce ce_small dynamic small static +os_windows/os_config.c ce ce_small dynamic small static +os_windows/os_cpu.c ce ce_small dynamic small static +os_windows/os_dir.c ce ce_small dynamic small static +os_windows/os_errno.c ce ce_small dynamic small static +os_windows/os_fid.c ce ce_small dynamic small static +os_windows/os_flock.c ce ce_small dynamic small static +os_windows/os_fsync.c ce ce_small dynamic small static +os_windows/os_getenv.c ce ce_small dynamic small static +os_windows/os_handle.c ce ce_small dynamic small static +os_windows/os_map.c ce ce_small dynamic small static +os_windows/os_mkdir.c ce ce_small dynamic small static +os_windows/os_open.c ce ce_small dynamic small static +os_windows/os_rename.c ce ce_small dynamic small static +os_windows/os_rw.c ce ce_small dynamic small static +os_windows/os_seek.c ce ce_small dynamic small static +os_windows/os_stat.c ce ce_small dynamic small static +os_windows/os_truncate.c ce ce_small dynamic small static +os_windows/os_unlink.c ce ce_small dynamic small static +os_windows/os_yield.c ce ce_small dynamic small static +qam/qam.c ce dynamic static vx +qam/qam_auto.c ce dynamic static vx +qam/qam_autop.c app=db_printlog vx6 +qam/qam_conv.c ce dynamic static vx +qam/qam_files.c ce dynamic static vx +qam/qam_method.c ce dynamic static vx +qam/qam_open.c ce dynamic static vx +qam/qam_rec.c ce dynamic static vx +qam/qam_stat.c ce dynamic static vx +qam/qam_stub.c brew ce_small small s60 vxsmall +qam/qam_upgrade.c ce dynamic static vx +qam/qam_verify.c ce dynamic static vx +rep/rep_auto.c dynamic static vx +rep/rep_backup.c dynamic static vx +rep/rep_elect.c dynamic static vx +rep/rep_lease.c dynamic static vx +rep/rep_log.c dynamic static vx +rep/rep_method.c dynamic static vx +rep/rep_record.c dynamic static vx +rep/rep_region.c dynamic static vx +rep/rep_stat.c dynamic static vx +rep/rep_stub.c brew ce ce_small small s60 vxsmall +rep/rep_util.c dynamic static vx +rep/rep_verify.c dynamic static vx +repmgr/repmgr_auto.c dynamic static +repmgr/repmgr_elect.c dynamic static +repmgr/repmgr_method.c dynamic static +repmgr/repmgr_msg.c dynamic static +repmgr/repmgr_net.c dynamic static +repmgr/repmgr_posix.c +repmgr/repmgr_queue.c dynamic static +repmgr/repmgr_sel.c dynamic static +repmgr/repmgr_stat.c dynamic static +repmgr/repmgr_stub.c brew ce ce_small small s60 vx vxsmall +repmgr/repmgr_util.c dynamic static +repmgr/repmgr_windows.c dynamic static +rpc_client/client.c +rpc_client/gen_client.c +rpc_client/gen_client_ret.c +rpc_server/c/db_server_proc.c +rpc_server/c/db_server_util.c +rpc_server/cxx/db_server_cxxproc.cpp +rpc_server/cxx/db_server_cxxutil.cpp +sequence/seq_stat.c ce ce_small dynamic small static vx6 +sequence/sequence.c ce ce_small dynamic small static vx6 +tcl/tcl_compat.c tcl +tcl/tcl_db.c tcl +tcl/tcl_db_pkg.c tcl +tcl/tcl_dbcursor.c tcl +tcl/tcl_env.c tcl +tcl/tcl_internal.c tcl +tcl/tcl_lock.c tcl +tcl/tcl_log.c tcl +tcl/tcl_mp.c tcl +tcl/tcl_mutex.c tcl +tcl/tcl_rep.c tcl +tcl/tcl_seq.c tcl +tcl/tcl_txn.c tcl +tcl/tcl_util.c tcl +test_micro/source/b_curalloc.c app=test_micro +test_micro/source/b_curwalk.c app=test_micro +test_micro/source/b_del.c app=test_micro +test_micro/source/b_get.c app=test_micro +test_micro/source/b_inmem.c app=test_micro +test_micro/source/b_latch.c app=test_micro +test_micro/source/b_load.c app=test_micro +test_micro/source/b_open.c app=test_micro +test_micro/source/b_put.c app=test_micro +test_micro/source/b_recover.c app=test_micro +test_micro/source/b_txn.c app=test_micro +test_micro/source/b_txn_write.c app=test_micro +test_micro/source/b_uname.c app=test_micro +test_micro/source/b_util.c app=test_micro +test_micro/source/b_workload.c app=test_micro +test_micro/source/test_micro.c app=test_micro +test_perf/perf_vx.c +test_repmgr/db_repsite.cpp app=db_repsite +txn/txn.c brew ce ce_small dynamic small static s60 vx vxsmall +txn/txn_auto.c brew ce ce_small dynamic small static s60 vx vxsmall +txn/txn_autop.c app=db_printlog vx6 +txn/txn_chkpt.c brew ce ce_small dynamic small static s60 vx vxsmall +txn/txn_failchk.c brew ce ce_small dynamic small static s60 vx vxsmall +txn/txn_method.c brew ce ce_small dynamic small static s60 vx vxsmall +txn/txn_rec.c brew ce ce_small dynamic small static s60 vx vxsmall +txn/txn_recover.c brew ce ce_small dynamic small static s60 vx vxsmall +txn/txn_region.c brew ce ce_small dynamic small static s60 vx vxsmall +txn/txn_stat.c brew ce ce_small dynamic small static s60 vx vxsmall +txn/txn_util.c brew ce ce_small dynamic small static s60 vx vxsmall diff --git a/src/libs/resiprocate/contrib/db/dist/template/db_server_proc b/src/libs/resiprocate/contrib/db/dist/template/db_server_proc new file mode 100644 index 00000000..83be0864 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/template/db_server_proc @@ -0,0 +1,1877 @@ +#include "db_config.h" + +#include "db_int.h" +#ifdef HAVE_SYSTEM_INCLUDE_FILES +#include +#endif +#include "db_server.h" +#include "dbinc/db_server_int.h" + +/* BEGIN __env_create_proc */ +void +__env_create_proc(timeout, replyp) + u_int32_t timeout; + __env_create_reply *replyp; +/* END __env_create_proc */ +{ + int ret; + + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_cdsgroup_begin_proc */ +void +__env_cdsgroup_begin_proc(dbenvcl_id, replyp) + unsigned int dbenvcl_id; + __env_cdsgroup_begin_reply *replyp; +/* END __env_cdsgroup_begin_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_close_proc */ +void +__env_close_proc(dbenvcl_id, flags, replyp) + unsigned int dbenvcl_id; + u_int32_t flags; + __env_close_reply *replyp; +/* END __env_close_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_dbremove_proc */ +void +__env_dbremove_proc(dbenvcl_id, txnpcl_id, name, + subdb, flags, replyp) + unsigned int dbenvcl_id; + unsigned int txnpcl_id; + char *name; + char *subdb; + u_int32_t flags; + __env_dbremove_reply *replyp; +/* END __env_dbremove_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_dbrename_proc */ +void +__env_dbrename_proc(dbenvcl_id, txnpcl_id, name, + subdb, newname, flags, replyp) + unsigned int dbenvcl_id; + unsigned int txnpcl_id; + char *name; + char *subdb; + char *newname; + u_int32_t flags; + __env_dbrename_reply *replyp; +/* END __env_dbrename_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_get_cachesize_proc */ +void +__env_get_cachesize_proc(dbenvcl_id, + replyp) + unsigned int dbenvcl_id; + __env_get_cachesize_reply *replyp; +/* END __env_get_cachesize_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_get_encrypt_flags_proc */ +void +__env_get_encrypt_flags_proc(dbenvcl_id, replyp) + unsigned int dbenvcl_id; + __env_get_encrypt_flags_reply *replyp; +/* END __env_get_encrypt_flags_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_get_flags_proc */ +void +__env_get_flags_proc(dbenvcl_id, replyp) + unsigned int dbenvcl_id; + __env_get_flags_reply *replyp; +/* END __env_get_flags_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_get_home_proc */ +void +__env_get_home_proc(dbenvcl_id, replyp) + unsigned int dbenvcl_id; + __env_get_home_reply *replyp; +/* END __env_get_home_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_get_open_flags_proc */ +void +__env_get_open_flags_proc(dbenvcl_id, replyp) + unsigned int dbenvcl_id; + __env_get_open_flags_reply *replyp; +/* END __env_get_open_flags_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_open_proc */ +void +__env_open_proc(dbenvcl_id, home, flags, + mode, replyp) + unsigned int dbenvcl_id; + char *home; + u_int32_t flags; + u_int32_t mode; + __env_open_reply *replyp; +/* END __env_open_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_remove_proc */ +void +__env_remove_proc(dbenvcl_id, home, flags, replyp) + unsigned int dbenvcl_id; + char *home; + u_int32_t flags; + __env_remove_reply *replyp; +/* END __env_remove_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_set_cachesize_proc */ +void +__env_set_cachesize_proc(dbenvcl_id, gbytes, bytes, + ncache, replyp) + unsigned int dbenvcl_id; + u_int32_t gbytes; + u_int32_t bytes; + u_int32_t ncache; + __env_set_cachesize_reply *replyp; +/* END __env_set_cachesize_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_set_encrypt_proc */ +void +__env_set_encrypt_proc(dbenvcl_id, passwd, flags, replyp) + unsigned int dbenvcl_id; + char *passwd; + u_int32_t flags; + __env_set_encrypt_reply *replyp; +/* END __env_set_encrypt_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_set_flags_proc */ +void +__env_set_flags_proc(dbenvcl_id, flags, onoff, replyp) + unsigned int dbenvcl_id; + u_int32_t flags; + u_int32_t onoff; + __env_set_flags_reply *replyp; +/* END __env_set_flags_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_txn_begin_proc */ +void +__env_txn_begin_proc(dbenvcl_id, parentcl_id, + flags, replyp) + unsigned int dbenvcl_id; + unsigned int parentcl_id; + u_int32_t flags; + __env_txn_begin_reply *replyp; +/* END __env_txn_begin_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + DB_TXN * parent; + ct_entry *parent_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + ACTIVATE_CTP(parent_ctp, parentcl_id, CT_TXN); + parent = (DB_TXN *)parent_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __env_txn_recover_proc */ +void +__env_txn_recover_proc(dbenvcl_id, count, + flags, replyp, freep) + unsigned int dbenvcl_id; + u_int32_t count; + u_int32_t flags; + __env_txn_recover_reply *replyp; + int * freep; +/* END __env_txn_recover_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_create_proc */ +void +__db_create_proc(dbenvcl_id, flags, replyp) + unsigned int dbenvcl_id; + u_int32_t flags; + __db_create_reply *replyp; +/* END __db_create_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_associate_proc */ +void +__db_associate_proc(dbpcl_id, txnpcl_id, sdbpcl_id, + flags, replyp) + unsigned int dbpcl_id; + unsigned int txnpcl_id; + unsigned int sdbpcl_id; + u_int32_t flags; + __db_associate_reply *replyp; +/* END __db_associate_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + DB * sdbp; + ct_entry *sdbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + ACTIVATE_CTP(sdbp_ctp, sdbpcl_id, CT_DB); + sdbp = (DB *)sdbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_close_proc */ +void +__db_close_proc(dbpcl_id, flags, replyp) + unsigned int dbpcl_id; + u_int32_t flags; + __db_close_reply *replyp; +/* END __db_close_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_cursor_proc */ +void +__db_cursor_proc(dbpcl_id, txnpcl_id, + flags, replyp) + unsigned int dbpcl_id; + unsigned int txnpcl_id; + u_int32_t flags; + __db_cursor_reply *replyp; +/* END __db_cursor_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_del_proc */ +void +__db_del_proc(dbpcl_id, txnpcl_id, keydlen, + keydoff, keyulen, keyflags, keydata, + keysize, flags, replyp) + unsigned int dbpcl_id; + unsigned int txnpcl_id; + u_int32_t keydlen; + u_int32_t keydoff; + u_int32_t keyulen; + u_int32_t keyflags; + void *keydata; + u_int32_t keysize; + u_int32_t flags; + __db_del_reply *replyp; +/* END __db_del_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_proc */ +void +__db_get_proc(dbpcl_id, txnpcl_id, keydlen, + keydoff, keyulen, keyflags, keydata, + keysize, datadlen, datadoff, dataulen, + dataflags, datadata, datasize, flags, replyp, freep) + unsigned int dbpcl_id; + unsigned int txnpcl_id; + u_int32_t keydlen; + u_int32_t keydoff; + u_int32_t keyulen; + u_int32_t keyflags; + void *keydata; + u_int32_t keysize; + u_int32_t datadlen; + u_int32_t datadoff; + u_int32_t dataulen; + u_int32_t dataflags; + void *datadata; + u_int32_t datasize; + u_int32_t flags; + __db_get_reply *replyp; + int * freep; +/* END __db_get_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_bt_minkey_proc */ +void +__db_get_bt_minkey_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_bt_minkey_reply *replyp; +/* END __db_get_bt_minkey_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_dbname_proc */ +void +__db_get_dbname_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_dbname_reply *replyp; +/* END __db_get_dbname_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_encrypt_flags_proc */ +void +__db_get_encrypt_flags_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_encrypt_flags_reply *replyp; +/* END __db_get_encrypt_flags_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_flags_proc */ +void +__db_get_flags_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_flags_reply *replyp; +/* END __db_get_flags_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_h_ffactor_proc */ +void +__db_get_h_ffactor_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_h_ffactor_reply *replyp; +/* END __db_get_h_ffactor_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_h_nelem_proc */ +void +__db_get_h_nelem_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_h_nelem_reply *replyp; +/* END __db_get_h_nelem_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_lorder_proc */ +void +__db_get_lorder_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_lorder_reply *replyp; +/* END __db_get_lorder_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_open_flags_proc */ +void +__db_get_open_flags_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_open_flags_reply *replyp; +/* END __db_get_open_flags_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_pagesize_proc */ +void +__db_get_pagesize_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_pagesize_reply *replyp; +/* END __db_get_pagesize_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_priority_proc */ +void +__db_get_priority_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_priority_reply *replyp; +/* END __db_get_priority_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_q_extentsize_proc */ +void +__db_get_q_extentsize_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_q_extentsize_reply *replyp; +/* END __db_get_q_extentsize_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_re_delim_proc */ +void +__db_get_re_delim_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_re_delim_reply *replyp; +/* END __db_get_re_delim_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_re_len_proc */ +void +__db_get_re_len_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_re_len_reply *replyp; +/* END __db_get_re_len_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_re_pad_proc */ +void +__db_get_re_pad_proc(dbpcl_id, replyp) + unsigned int dbpcl_id; + __db_get_re_pad_reply *replyp; +/* END __db_get_re_pad_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_join_proc */ +void +__db_join_proc(dbpcl_id, curs, curslen, + flags, replyp) + unsigned int dbpcl_id; + u_int32_t * curs; + u_int32_t curslen; + u_int32_t flags; + __db_join_reply *replyp; +/* END __db_join_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_key_range_proc */ +void +__db_key_range_proc(dbpcl_id, txnpcl_id, keydlen, + keydoff, keyulen, keyflags, keydata, + keysize, flags, replyp) + unsigned int dbpcl_id; + unsigned int txnpcl_id; + u_int32_t keydlen; + u_int32_t keydoff; + u_int32_t keyulen; + u_int32_t keyflags; + void *keydata; + u_int32_t keysize; + u_int32_t flags; + __db_key_range_reply *replyp; +/* END __db_key_range_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_open_proc */ +void +__db_open_proc(dbpcl_id, txnpcl_id, name, + subdb, type, flags, mode, replyp) + unsigned int dbpcl_id; + unsigned int txnpcl_id; + char *name; + char *subdb; + u_int32_t type; + u_int32_t flags; + u_int32_t mode; + __db_open_reply *replyp; +/* END __db_open_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_pget_proc */ +void +__db_pget_proc(dbpcl_id, txnpcl_id, skeydlen, + skeydoff, skeyulen, skeyflags, skeydata, + skeysize, pkeydlen, pkeydoff, pkeyulen, + pkeyflags, pkeydata, pkeysize, datadlen, + datadoff, dataulen, dataflags, datadata, + datasize, flags, replyp, freep) + unsigned int dbpcl_id; + unsigned int txnpcl_id; + u_int32_t skeydlen; + u_int32_t skeydoff; + u_int32_t skeyulen; + u_int32_t skeyflags; + void *skeydata; + u_int32_t skeysize; + u_int32_t pkeydlen; + u_int32_t pkeydoff; + u_int32_t pkeyulen; + u_int32_t pkeyflags; + void *pkeydata; + u_int32_t pkeysize; + u_int32_t datadlen; + u_int32_t datadoff; + u_int32_t dataulen; + u_int32_t dataflags; + void *datadata; + u_int32_t datasize; + u_int32_t flags; + __db_pget_reply *replyp; + int * freep; +/* END __db_pget_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_put_proc */ +void +__db_put_proc(dbpcl_id, txnpcl_id, keydlen, + keydoff, keyulen, keyflags, keydata, + keysize, datadlen, datadoff, dataulen, + dataflags, datadata, datasize, flags, replyp, freep) + unsigned int dbpcl_id; + unsigned int txnpcl_id; + u_int32_t keydlen; + u_int32_t keydoff; + u_int32_t keyulen; + u_int32_t keyflags; + void *keydata; + u_int32_t keysize; + u_int32_t datadlen; + u_int32_t datadoff; + u_int32_t dataulen; + u_int32_t dataflags; + void *datadata; + u_int32_t datasize; + u_int32_t flags; + __db_put_reply *replyp; + int * freep; +/* END __db_put_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_remove_proc */ +void +__db_remove_proc(dbpcl_id, name, subdb, + flags, replyp) + unsigned int dbpcl_id; + char *name; + char *subdb; + u_int32_t flags; + __db_remove_reply *replyp; +/* END __db_remove_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_rename_proc */ +void +__db_rename_proc(dbpcl_id, name, subdb, + newname, flags, replyp) + unsigned int dbpcl_id; + char *name; + char *subdb; + char *newname; + u_int32_t flags; + __db_rename_reply *replyp; +/* END __db_rename_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_set_bt_minkey_proc */ +void +__db_set_bt_minkey_proc(dbpcl_id, minkey, replyp) + unsigned int dbpcl_id; + u_int32_t minkey; + __db_set_bt_minkey_reply *replyp; +/* END __db_set_bt_minkey_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_set_encrypt_proc */ +void +__db_set_encrypt_proc(dbpcl_id, passwd, flags, replyp) + unsigned int dbpcl_id; + char *passwd; + u_int32_t flags; + __db_set_encrypt_reply *replyp; +/* END __db_set_encrypt_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_set_flags_proc */ +void +__db_set_flags_proc(dbpcl_id, flags, replyp) + unsigned int dbpcl_id; + u_int32_t flags; + __db_set_flags_reply *replyp; +/* END __db_set_flags_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_set_h_ffactor_proc */ +void +__db_set_h_ffactor_proc(dbpcl_id, ffactor, replyp) + unsigned int dbpcl_id; + u_int32_t ffactor; + __db_set_h_ffactor_reply *replyp; +/* END __db_set_h_ffactor_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_set_h_nelem_proc */ +void +__db_set_h_nelem_proc(dbpcl_id, nelem, replyp) + unsigned int dbpcl_id; + u_int32_t nelem; + __db_set_h_nelem_reply *replyp; +/* END __db_set_h_nelem_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_set_lorder_proc */ +void +__db_set_lorder_proc(dbpcl_id, lorder, replyp) + unsigned int dbpcl_id; + u_int32_t lorder; + __db_set_lorder_reply *replyp; +/* END __db_set_lorder_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_set_pagesize_proc */ +void +__db_set_pagesize_proc(dbpcl_id, pagesize, replyp) + unsigned int dbpcl_id; + u_int32_t pagesize; + __db_set_pagesize_reply *replyp; +/* END __db_set_pagesize_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_set_priority_proc */ +void +__db_set_priority_proc(dbpcl_id, priority, replyp) + unsigned int dbpcl_id; + u_int32_t priority; + __db_set_priority_reply *replyp; +/* END __db_set_priority_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_set_q_extentsize_proc */ +void +__db_set_q_extentsize_proc(dbpcl_id, extentsize, replyp) + unsigned int dbpcl_id; + u_int32_t extentsize; + __db_set_q_extentsize_reply *replyp; +/* END __db_set_q_extentsize_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_set_re_delim_proc */ +void +__db_set_re_delim_proc(dbpcl_id, delim, replyp) + unsigned int dbpcl_id; + u_int32_t delim; + __db_set_re_delim_reply *replyp; +/* END __db_set_re_delim_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_set_re_len_proc */ +void +__db_set_re_len_proc(dbpcl_id, len, replyp) + unsigned int dbpcl_id; + u_int32_t len; + __db_set_re_len_reply *replyp; +/* END __db_set_re_len_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_set_re_pad_proc */ +void +__db_set_re_pad_proc(dbpcl_id, pad, replyp) + unsigned int dbpcl_id; + u_int32_t pad; + __db_set_re_pad_reply *replyp; +/* END __db_set_re_pad_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_stat_proc */ +void +__db_stat_proc(dbpcl_id, txnpcl_id, + flags, replyp, freep) + unsigned int dbpcl_id; + unsigned int txnpcl_id; + u_int32_t flags; + __db_stat_reply *replyp; + int * freep; +/* END __db_stat_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_sync_proc */ +void +__db_sync_proc(dbpcl_id, flags, replyp) + unsigned int dbpcl_id; + u_int32_t flags; + __db_sync_reply *replyp; +/* END __db_sync_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __db_truncate_proc */ +void +__db_truncate_proc(dbpcl_id, txnpcl_id, + flags, replyp) + unsigned int dbpcl_id; + unsigned int txnpcl_id; + u_int32_t flags; + __db_truncate_reply *replyp; +/* END __db_truncate_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __dbc_close_proc */ +void +__dbc_close_proc(dbccl_id, replyp) + unsigned int dbccl_id; + __dbc_close_reply *replyp; +/* END __dbc_close_proc */ +{ + int ret; + DBC * dbc; + ct_entry *dbc_ctp; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __dbc_count_proc */ +void +__dbc_count_proc(dbccl_id, flags, replyp) + unsigned int dbccl_id; + u_int32_t flags; + __dbc_count_reply *replyp; +/* END __dbc_count_proc */ +{ + int ret; + DBC * dbc; + ct_entry *dbc_ctp; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __dbc_del_proc */ +void +__dbc_del_proc(dbccl_id, flags, replyp) + unsigned int dbccl_id; + u_int32_t flags; + __dbc_del_reply *replyp; +/* END __dbc_del_proc */ +{ + int ret; + DBC * dbc; + ct_entry *dbc_ctp; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __dbc_dup_proc */ +void +__dbc_dup_proc(dbccl_id, flags, replyp) + unsigned int dbccl_id; + u_int32_t flags; + __dbc_dup_reply *replyp; +/* END __dbc_dup_proc */ +{ + int ret; + DBC * dbc; + ct_entry *dbc_ctp; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __dbc_get_proc */ +void +__dbc_get_proc(dbccl_id, keydlen, keydoff, + keyulen, keyflags, keydata, keysize, + datadlen, datadoff, dataulen, dataflags, + datadata, datasize, flags, replyp, freep) + unsigned int dbccl_id; + u_int32_t keydlen; + u_int32_t keydoff; + u_int32_t keyulen; + u_int32_t keyflags; + void *keydata; + u_int32_t keysize; + u_int32_t datadlen; + u_int32_t datadoff; + u_int32_t dataulen; + u_int32_t dataflags; + void *datadata; + u_int32_t datasize; + u_int32_t flags; + __dbc_get_reply *replyp; + int * freep; +/* END __dbc_get_proc */ +{ + int ret; + DBC * dbc; + ct_entry *dbc_ctp; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __dbc_get_priority_proc */ +void +__dbc_get_priority_proc(dbccl_id, replyp) + unsigned int dbccl_id; + __dbc_get_priority_reply *replyp; +/* END __dbc_get_priority_proc */ +{ + int ret; + DBC * dbc; + ct_entry *dbc_ctp; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __dbc_pget_proc */ +void +__dbc_pget_proc(dbccl_id, skeydlen, skeydoff, + skeyulen, skeyflags, skeydata, skeysize, + pkeydlen, pkeydoff, pkeyulen, pkeyflags, + pkeydata, pkeysize, datadlen, datadoff, + dataulen, dataflags, datadata, datasize, + flags, replyp, freep) + unsigned int dbccl_id; + u_int32_t skeydlen; + u_int32_t skeydoff; + u_int32_t skeyulen; + u_int32_t skeyflags; + void *skeydata; + u_int32_t skeysize; + u_int32_t pkeydlen; + u_int32_t pkeydoff; + u_int32_t pkeyulen; + u_int32_t pkeyflags; + void *pkeydata; + u_int32_t pkeysize; + u_int32_t datadlen; + u_int32_t datadoff; + u_int32_t dataulen; + u_int32_t dataflags; + void *datadata; + u_int32_t datasize; + u_int32_t flags; + __dbc_pget_reply *replyp; + int * freep; +/* END __dbc_pget_proc */ +{ + int ret; + DBC * dbc; + ct_entry *dbc_ctp; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __dbc_put_proc */ +void +__dbc_put_proc(dbccl_id, keydlen, keydoff, + keyulen, keyflags, keydata, keysize, + datadlen, datadoff, dataulen, dataflags, + datadata, datasize, flags, replyp, freep) + unsigned int dbccl_id; + u_int32_t keydlen; + u_int32_t keydoff; + u_int32_t keyulen; + u_int32_t keyflags; + void *keydata; + u_int32_t keysize; + u_int32_t datadlen; + u_int32_t datadoff; + u_int32_t dataulen; + u_int32_t dataflags; + void *datadata; + u_int32_t datasize; + u_int32_t flags; + __dbc_put_reply *replyp; + int * freep; +/* END __dbc_put_proc */ +{ + int ret; + DBC * dbc; + ct_entry *dbc_ctp; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __dbc_set_priority_proc */ +void +__dbc_set_priority_proc(dbccl_id, priority, replyp) + unsigned int dbccl_id; + u_int32_t priority; + __dbc_set_priority_reply *replyp; +/* END __dbc_set_priority_proc */ +{ + int ret; + DBC * dbc; + ct_entry *dbc_ctp; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __txn_abort_proc */ +void +__txn_abort_proc(txnpcl_id, replyp) + unsigned int txnpcl_id; + __txn_abort_reply *replyp; +/* END __txn_abort_proc */ +{ + int ret; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __txn_commit_proc */ +void +__txn_commit_proc(txnpcl_id, flags, replyp) + unsigned int txnpcl_id; + u_int32_t flags; + __txn_commit_reply *replyp; +/* END __txn_commit_proc */ +{ + int ret; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __txn_discard_proc */ +void +__txn_discard_proc(txnpcl_id, flags, replyp) + unsigned int txnpcl_id; + u_int32_t flags; + __txn_discard_reply *replyp; +/* END __txn_discard_proc */ +{ + int ret; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + +/* BEGIN __txn_prepare_proc */ +void +__txn_prepare_proc(txnpcl_id, gid, replyp) + unsigned int txnpcl_id; + u_int8_t *gid; + __txn_prepare_reply *replyp; +/* END __txn_prepare_proc */ +{ + int ret; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + /* + * XXX Code goes here + */ + + replyp->status = ret; + return; +} + diff --git a/src/libs/resiprocate/contrib/db/dist/template/gen_client_ret b/src/libs/resiprocate/contrib/db/dist/template/gen_client_ret new file mode 100644 index 00000000..64325b39 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/template/gen_client_ret @@ -0,0 +1,742 @@ +/* Do not edit: automatically built by gen_rpc.awk. */ +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/txn.h" + +/* + * PUBLIC: int __dbcl_env_create_ret __P((DB_ENV *, long, + * PUBLIC: __env_create_reply *)); + */ +int +__dbcl_env_create_ret(dbenv, timeout, replyp) + DB_ENV * dbenv; + long timeout; + __env_create_reply *replyp; +{ + int ret; + long env; + + if (replyp->status != 0) + return (replyp->status); + env = replyp->envcl_id; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_env_cdsgroup_begin_ret __P((DB_ENV *, DB_TXN **, + * PUBLIC: __env_cdsgroup_begin_reply *)); + */ +int +__dbcl_env_cdsgroup_begin_ret(dbenv, txnpp, replyp) + DB_ENV * dbenv; + DB_TXN ** txnpp; + __env_cdsgroup_begin_reply *replyp; +{ + int ret; + long txnid; + + if (replyp->status != 0) + return (replyp->status); + txnid = replyp->txnidcl_id; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_env_open_ret __P((DB_ENV *, const char *, u_int32_t, int, + * PUBLIC: __env_open_reply *)); + */ +int +__dbcl_env_open_ret(dbenv, home, flags, mode, replyp) + DB_ENV * dbenv; + const char * home; + u_int32_t flags; + int mode; + __env_open_reply *replyp; +{ + int ret; + long env; + + if (replyp->status != 0) + return (replyp->status); + env = replyp->envcl_id; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_env_remove_ret __P((DB_ENV *, const char *, u_int32_t, + * PUBLIC: __env_remove_reply *)); + */ +int +__dbcl_env_remove_ret(dbenv, home, flags, replyp) + DB_ENV * dbenv; + const char * home; + u_int32_t flags; + __env_remove_reply *replyp; +{ + int ret; + + if (replyp->status != 0) + return (replyp->status); + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_env_txn_begin_ret __P((DB_ENV *, DB_TXN *, DB_TXN **, + * PUBLIC: u_int32_t, __env_txn_begin_reply *)); + */ +int +__dbcl_env_txn_begin_ret(dbenv, parent, txnpp, flags, replyp) + DB_ENV * dbenv; + DB_TXN * parent; + DB_TXN ** txnpp; + u_int32_t flags; + __env_txn_begin_reply *replyp; +{ + int ret; + long txnid; + + if (replyp->status != 0) + return (replyp->status); + txnid = replyp->txnidcl_id; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_env_txn_recover_ret __P((DB_ENV *, DB_PREPLIST *, + * PUBLIC: u_int32_t, u_int32_t *, u_int32_t, __env_txn_recover_reply *)); + */ +int +__dbcl_env_txn_recover_ret(dbenv, preplist, count, retp, flags, replyp) + DB_ENV * dbenv; + DB_PREPLIST * preplist; + u_int32_t count; + u_int32_t * retp; + u_int32_t flags; + __env_txn_recover_reply *replyp; +{ + int ret; + u_int32_t *__db_txn; + u_int8_t *__db_gid; + u_int32_t retcount; + + if (replyp->status != 0) + return (replyp->status); + + /* + * XXX Handle list + */ + + + /* + * XXX Handle list + */ + + retcount = replyp->retcount; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_create_ret __P((DB *, DB_ENV *, u_int32_t, + * PUBLIC: __db_create_reply *)); + */ +int +__dbcl_db_create_ret(dbp, dbenv, flags, replyp) + DB * dbp; + DB_ENV * dbenv; + u_int32_t flags; + __db_create_reply *replyp; +{ + int ret; + long db; + + if (replyp->status != 0) + return (replyp->status); + db = replyp->dbcl_id; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_close_ret __P((DB *, u_int32_t, __db_close_reply *)); + */ +int +__dbcl_db_close_ret(dbp, flags, replyp) + DB * dbp; + u_int32_t flags; + __db_close_reply *replyp; +{ + int ret; + + if (replyp->status != 0) + return (replyp->status); + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_cursor_ret __P((DB *, DB_TXN *, DBC **, u_int32_t, + * PUBLIC: __db_cursor_reply *)); + */ +int +__dbcl_db_cursor_ret(dbp, txnp, dbcpp, flags, replyp) + DB * dbp; + DB_TXN * txnp; + DBC ** dbcpp; + u_int32_t flags; + __db_cursor_reply *replyp; +{ + int ret; + long dbcid; + + if (replyp->status != 0) + return (replyp->status); + dbcid = replyp->dbcidcl_id; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_get_ret __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t, + * PUBLIC: __db_get_reply *)); + */ +int +__dbcl_db_get_ret(dbp, txnp, key, data, flags, replyp) + DB * dbp; + DB_TXN * txnp; + DBT * key; + DBT * data; + u_int32_t flags; + __db_get_reply *replyp; +{ + int ret; + /* DBT key; */ + /* DBT data; */ + + if (replyp->status != 0) + return (replyp->status); + /* Handle replyp->keydata; */ + /* Handle replyp->datadata; */ + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_join_ret __P((DB *, DBC **, DBC **, u_int32_t, + * PUBLIC: __db_join_reply *)); + */ +int +__dbcl_db_join_ret(dbp, curs, dbcp, flags, replyp) + DB * dbp; + DBC ** curs; + DBC ** dbcp; + u_int32_t flags; + __db_join_reply *replyp; +{ + int ret; + long dbcid; + + if (replyp->status != 0) + return (replyp->status); + dbcid = replyp->dbcidcl_id; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_key_range_ret __P((DB *, DB_TXN *, DBT *, + * PUBLIC: DB_KEY_RANGE *, u_int32_t, __db_key_range_reply *)); + */ +int +__dbcl_db_key_range_ret(dbp, txnp, key, range, flags, replyp) + DB * dbp; + DB_TXN * txnp; + DBT * key; + DB_KEY_RANGE * range; + u_int32_t flags; + __db_key_range_reply *replyp; +{ + int ret; + double less; + double equal; + double greater; + + if (replyp->status != 0) + return (replyp->status); + less = replyp->less; + equal = replyp->equal; + greater = replyp->greater; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_open_ret __P((DB *, DB_TXN *, const char *, + * PUBLIC: const char *, DBTYPE, u_int32_t, int, __db_open_reply *)); + */ +int +__dbcl_db_open_ret(dbp, txnp, name, subdb, type, flags, mode, replyp) + DB * dbp; + DB_TXN * txnp; + const char * name; + const char * subdb; + DBTYPE type; + u_int32_t flags; + int mode; + __db_open_reply *replyp; +{ + int ret; + long db; + DBTYPE type; + int lorder; + + if (replyp->status != 0) + return (replyp->status); + db = replyp->dbcl_id; + type = replyp->type; + lorder = replyp->lorder; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_pget_ret __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, + * PUBLIC: u_int32_t, __db_pget_reply *)); + */ +int +__dbcl_db_pget_ret(dbp, txnp, skey, pkey, data, flags, replyp) + DB * dbp; + DB_TXN * txnp; + DBT * skey; + DBT * pkey; + DBT * data; + u_int32_t flags; + __db_pget_reply *replyp; +{ + int ret; + /* DBT skey; */ + /* DBT pkey; */ + /* DBT data; */ + + if (replyp->status != 0) + return (replyp->status); + /* Handle replyp->skeydata; */ + /* Handle replyp->pkeydata; */ + /* Handle replyp->datadata; */ + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_put_ret __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t, + * PUBLIC: __db_put_reply *)); + */ +int +__dbcl_db_put_ret(dbp, txnp, key, data, flags, replyp) + DB * dbp; + DB_TXN * txnp; + DBT * key; + DBT * data; + u_int32_t flags; + __db_put_reply *replyp; +{ + int ret; + /* DBT key; */ + + if (replyp->status != 0) + return (replyp->status); + /* Handle replyp->keydata; */ + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_remove_ret __P((DB *, const char *, const char *, + * PUBLIC: u_int32_t, __db_remove_reply *)); + */ +int +__dbcl_db_remove_ret(dbp, name, subdb, flags, replyp) + DB * dbp; + const char * name; + const char * subdb; + u_int32_t flags; + __db_remove_reply *replyp; +{ + int ret; + + if (replyp->status != 0) + return (replyp->status); + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_rename_ret __P((DB *, const char *, const char *, + * PUBLIC: const char *, u_int32_t, __db_rename_reply *)); + */ +int +__dbcl_db_rename_ret(dbp, name, subdb, newname, flags, replyp) + DB * dbp; + const char * name; + const char * subdb; + const char * newname; + u_int32_t flags; + __db_rename_reply *replyp; +{ + int ret; + + if (replyp->status != 0) + return (replyp->status); + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_stat_ret __P((DB *, DB_TXN *, void *, u_int32_t, + * PUBLIC: __db_stat_reply *)); + */ +int +__dbcl_db_stat_ret(dbp, txnp, sp, flags, replyp) + DB * dbp; + DB_TXN * txnp; + void * sp; + u_int32_t flags; + __db_stat_reply *replyp; +{ + int ret; + u_int32_t *__db_stats; + + if (replyp->status != 0) + return (replyp->status); + + /* + * XXX Handle list + */ + + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_db_truncate_ret __P((DB *, DB_TXN *, u_int32_t *, + * PUBLIC: u_int32_t, __db_truncate_reply *)); + */ +int +__dbcl_db_truncate_ret(dbp, txnp, countp, flags, replyp) + DB * dbp; + DB_TXN * txnp; + u_int32_t * countp; + u_int32_t flags; + __db_truncate_reply *replyp; +{ + int ret; + u_int32_t count; + + if (replyp->status != 0) + return (replyp->status); + count = replyp->count; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_dbc_close_ret __P((DBC *, __dbc_close_reply *)); + */ +int +__dbcl_dbc_close_ret(dbc, replyp) + DBC * dbc; + __dbc_close_reply *replyp; +{ + int ret; + + if (replyp->status != 0) + return (replyp->status); + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_dbc_count_ret __P((DBC *, db_recno_t *, u_int32_t, + * PUBLIC: __dbc_count_reply *)); + */ +int +__dbcl_dbc_count_ret(dbc, countp, flags, replyp) + DBC * dbc; + db_recno_t * countp; + u_int32_t flags; + __dbc_count_reply *replyp; +{ + int ret; + db_recno_t dupcount; + + if (replyp->status != 0) + return (replyp->status); + dupcount = replyp->dupcount; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_dbc_dup_ret __P((DBC *, DBC **, u_int32_t, + * PUBLIC: __dbc_dup_reply *)); + */ +int +__dbcl_dbc_dup_ret(dbc, dbcp, flags, replyp) + DBC * dbc; + DBC ** dbcp; + u_int32_t flags; + __dbc_dup_reply *replyp; +{ + int ret; + long dbcid; + + if (replyp->status != 0) + return (replyp->status); + dbcid = replyp->dbcidcl_id; + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_dbc_get_ret __P((DBC *, DBT *, DBT *, u_int32_t, + * PUBLIC: __dbc_get_reply *)); + */ +int +__dbcl_dbc_get_ret(dbc, key, data, flags, replyp) + DBC * dbc; + DBT * key; + DBT * data; + u_int32_t flags; + __dbc_get_reply *replyp; +{ + int ret; + /* DBT key; */ + /* DBT data; */ + + if (replyp->status != 0) + return (replyp->status); + /* Handle replyp->keydata; */ + /* Handle replyp->datadata; */ + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_dbc_pget_ret __P((DBC *, DBT *, DBT *, DBT *, u_int32_t, + * PUBLIC: __dbc_pget_reply *)); + */ +int +__dbcl_dbc_pget_ret(dbc, skey, pkey, data, flags, replyp) + DBC * dbc; + DBT * skey; + DBT * pkey; + DBT * data; + u_int32_t flags; + __dbc_pget_reply *replyp; +{ + int ret; + /* DBT skey; */ + /* DBT pkey; */ + /* DBT data; */ + + if (replyp->status != 0) + return (replyp->status); + /* Handle replyp->skeydata; */ + /* Handle replyp->pkeydata; */ + /* Handle replyp->datadata; */ + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_dbc_put_ret __P((DBC *, DBT *, DBT *, u_int32_t, + * PUBLIC: __dbc_put_reply *)); + */ +int +__dbcl_dbc_put_ret(dbc, key, data, flags, replyp) + DBC * dbc; + DBT * key; + DBT * data; + u_int32_t flags; + __dbc_put_reply *replyp; +{ + int ret; + /* DBT key; */ + + if (replyp->status != 0) + return (replyp->status); + /* Handle replyp->keydata; */ + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_txn_abort_ret __P((DB_TXN *, __txn_abort_reply *)); + */ +int +__dbcl_txn_abort_ret(txnp, replyp) + DB_TXN * txnp; + __txn_abort_reply *replyp; +{ + int ret; + + if (replyp->status != 0) + return (replyp->status); + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_txn_commit_ret __P((DB_TXN *, u_int32_t, + * PUBLIC: __txn_commit_reply *)); + */ +int +__dbcl_txn_commit_ret(txnp, flags, replyp) + DB_TXN * txnp; + u_int32_t flags; + __txn_commit_reply *replyp; +{ + int ret; + + if (replyp->status != 0) + return (replyp->status); + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + +/* + * PUBLIC: int __dbcl_txn_discard_ret __P((DB_TXN *, u_int32_t, + * PUBLIC: __txn_discard_reply *)); + */ +int +__dbcl_txn_discard_ret(txnp, flags, replyp) + DB_TXN * txnp; + u_int32_t flags; + __txn_discard_reply *replyp; +{ + int ret; + + if (replyp->status != 0) + return (replyp->status); + + /* + * XXX Code goes here + */ + + return (replyp->status); +} + diff --git a/src/libs/resiprocate/contrib/db/dist/template/rec_btree b/src/libs/resiprocate/contrib/db/dist/template/rec_btree new file mode 100644 index 00000000..7e557d3b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/template/rec_btree @@ -0,0 +1,982 @@ +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/__bam.h" +#include "dbinc/log.h" + +/* + * __bam_split_recover -- + * Recovery function for split. + * + * PUBLIC: int __bam_split_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_split_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_split_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_split_print); + REC_INTRO(__bam_split_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_split_recover -- + * Recovery function for split. + * + * PUBLIC: int __bam_split_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_split_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_split_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_split_print); + REC_INTRO(__bam_split_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_rsplit_recover -- + * Recovery function for rsplit. + * + * PUBLIC: int __bam_rsplit_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_rsplit_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_rsplit_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_rsplit_print); + REC_INTRO(__bam_rsplit_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_adj_recover -- + * Recovery function for adj. + * + * PUBLIC: int __bam_adj_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_adj_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_adj_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_adj_print); + REC_INTRO(__bam_adj_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_cadjust_recover -- + * Recovery function for cadjust. + * + * PUBLIC: int __bam_cadjust_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_cadjust_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_cadjust_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_cadjust_print); + REC_INTRO(__bam_cadjust_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_cdel_recover -- + * Recovery function for cdel. + * + * PUBLIC: int __bam_cdel_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_cdel_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_cdel_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_cdel_print); + REC_INTRO(__bam_cdel_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_repl_recover -- + * Recovery function for repl. + * + * PUBLIC: int __bam_repl_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_repl_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_repl_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_repl_print); + REC_INTRO(__bam_repl_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_root_recover -- + * Recovery function for root. + * + * PUBLIC: int __bam_root_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_root_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_root_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_root_print); + REC_INTRO(__bam_root_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_curadj_recover -- + * Recovery function for curadj. + * + * PUBLIC: int __bam_curadj_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_curadj_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_curadj_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_curadj_print); + REC_INTRO(__bam_curadj_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_rcuradj_recover -- + * Recovery function for rcuradj. + * + * PUBLIC: int __bam_rcuradj_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_rcuradj_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_rcuradj_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_rcuradj_print); + REC_INTRO(__bam_rcuradj_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_relink_recover -- + * Recovery function for relink. + * + * PUBLIC: int __bam_relink_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_relink_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_relink_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_relink_print); + REC_INTRO(__bam_relink_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_relink_recover -- + * Recovery function for relink. + * + * PUBLIC: int __bam_relink_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_relink_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_relink_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_relink_print); + REC_INTRO(__bam_relink_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_merge_recover -- + * Recovery function for merge. + * + * PUBLIC: int __bam_merge_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_merge_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_merge_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_merge_print); + REC_INTRO(__bam_merge_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_merge_recover -- + * Recovery function for merge. + * + * PUBLIC: int __bam_merge_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_merge_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_merge_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_merge_print); + REC_INTRO(__bam_merge_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __bam_pgno_recover -- + * Recovery function for pgno. + * + * PUBLIC: int __bam_pgno_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__bam_pgno_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __bam_pgno_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__bam_pgno_print); + REC_INTRO(__bam_pgno_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + diff --git a/src/libs/resiprocate/contrib/db/dist/template/rec_crdel b/src/libs/resiprocate/contrib/db/dist/template/rec_crdel new file mode 100644 index 00000000..fabdc3ee --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/template/rec_crdel @@ -0,0 +1,267 @@ +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/__crdel.h" +#include "dbinc/log.h" + +/* + * __crdel_metasub_recover -- + * Recovery function for metasub. + * + * PUBLIC: int __crdel_metasub_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__crdel_metasub_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __crdel_metasub_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__crdel_metasub_print); + REC_INTRO(__crdel_metasub_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __crdel_inmem_create_recover -- + * Recovery function for inmem_create. + * + * PUBLIC: int __crdel_inmem_create_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__crdel_inmem_create_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __crdel_inmem_create_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__crdel_inmem_create_print); + REC_INTRO(__crdel_inmem_create_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __crdel_inmem_rename_recover -- + * Recovery function for inmem_rename. + * + * PUBLIC: int __crdel_inmem_rename_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__crdel_inmem_rename_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __crdel_inmem_rename_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__crdel_inmem_rename_print); + REC_INTRO(__crdel_inmem_rename_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __crdel_inmem_remove_recover -- + * Recovery function for inmem_remove. + * + * PUBLIC: int __crdel_inmem_remove_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__crdel_inmem_remove_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __crdel_inmem_remove_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__crdel_inmem_remove_print); + REC_INTRO(__crdel_inmem_remove_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + diff --git a/src/libs/resiprocate/contrib/db/dist/template/rec_ctemp b/src/libs/resiprocate/contrib/db/dist/template/rec_ctemp new file mode 100644 index 00000000..2d90331b --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/template/rec_ctemp @@ -0,0 +1,65 @@ +/* + * PREF_FUNC_recover -- + * Recovery function for FUNC. + * + * PUBLIC: int PREF_FUNC_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +PREF_FUNC_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + PREF_DUP_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(PREF_DUP_print); + REC_INTRO(PREF_DUP_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + diff --git a/src/libs/resiprocate/contrib/db/dist/template/rec_db b/src/libs/resiprocate/contrib/db/dist/template/rec_db new file mode 100644 index 00000000..d7b184ad --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/template/rec_db @@ -0,0 +1,1047 @@ +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/__db.h" +#include "dbinc/log.h" + +/* + * __db_addrem_recover -- + * Recovery function for addrem. + * + * PUBLIC: int __db_addrem_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_addrem_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_addrem_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_addrem_print); + REC_INTRO(__db_addrem_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_big_recover -- + * Recovery function for big. + * + * PUBLIC: int __db_big_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_big_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_big_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_big_print); + REC_INTRO(__db_big_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_ovref_recover -- + * Recovery function for ovref. + * + * PUBLIC: int __db_ovref_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_ovref_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_ovref_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_ovref_print); + REC_INTRO(__db_ovref_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_relink_recover -- + * Recovery function for relink. + * + * PUBLIC: int __db_relink_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_relink_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_relink_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_relink_print); + REC_INTRO(__db_relink_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_debug_recover -- + * Recovery function for debug. + * + * PUBLIC: int __db_debug_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_debug_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_debug_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_debug_print); + REC_INTRO(__db_debug_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_noop_recover -- + * Recovery function for noop. + * + * PUBLIC: int __db_noop_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_noop_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_noop_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_noop_print); + REC_INTRO(__db_noop_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_pg_alloc_recover -- + * Recovery function for pg_alloc. + * + * PUBLIC: int __db_pg_alloc_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_alloc_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_alloc_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_pg_alloc_print); + REC_INTRO(__db_pg_alloc_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_pg_alloc_recover -- + * Recovery function for pg_alloc. + * + * PUBLIC: int __db_pg_alloc_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_alloc_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_alloc_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_pg_alloc_print); + REC_INTRO(__db_pg_alloc_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_pg_free_recover -- + * Recovery function for pg_free. + * + * PUBLIC: int __db_pg_free_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_free_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_free_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_pg_free_print); + REC_INTRO(__db_pg_free_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_pg_free_recover -- + * Recovery function for pg_free. + * + * PUBLIC: int __db_pg_free_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_free_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_free_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_pg_free_print); + REC_INTRO(__db_pg_free_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_cksum_recover -- + * Recovery function for cksum. + * + * PUBLIC: int __db_cksum_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_cksum_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_cksum_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_cksum_print); + REC_INTRO(__db_cksum_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_pg_freedata_recover -- + * Recovery function for pg_freedata. + * + * PUBLIC: int __db_pg_freedata_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_freedata_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_freedata_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_pg_freedata_print); + REC_INTRO(__db_pg_freedata_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_pg_freedata_recover -- + * Recovery function for pg_freedata. + * + * PUBLIC: int __db_pg_freedata_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_freedata_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_freedata_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_pg_freedata_print); + REC_INTRO(__db_pg_freedata_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_pg_init_recover -- + * Recovery function for pg_init. + * + * PUBLIC: int __db_pg_init_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_init_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_init_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_pg_init_print); + REC_INTRO(__db_pg_init_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_pg_sort_recover -- + * Recovery function for pg_sort. + * + * PUBLIC: int __db_pg_sort_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_sort_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_sort_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_pg_sort_print); + REC_INTRO(__db_pg_sort_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __db_pg_trunc_recover -- + * Recovery function for pg_trunc. + * + * PUBLIC: int __db_pg_trunc_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__db_pg_trunc_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __db_pg_trunc_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__db_pg_trunc_print); + REC_INTRO(__db_pg_trunc_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + diff --git a/src/libs/resiprocate/contrib/db/dist/template/rec_dbreg b/src/libs/resiprocate/contrib/db/dist/template/rec_dbreg new file mode 100644 index 00000000..f5657967 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/template/rec_dbreg @@ -0,0 +1,72 @@ +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/__dbreg.h" +#include "dbinc/log.h" + +/* + * __dbreg_register_recover -- + * Recovery function for register. + * + * PUBLIC: int __dbreg_register_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__dbreg_register_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __dbreg_register_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__dbreg_register_print); + REC_INTRO(__dbreg_register_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + diff --git a/src/libs/resiprocate/contrib/db/dist/template/rec_fileops b/src/libs/resiprocate/contrib/db/dist/template/rec_fileops new file mode 100644 index 00000000..c2c770d8 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/template/rec_fileops @@ -0,0 +1,527 @@ +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/__fop.h" +#include "dbinc/log.h" + +/* + * __fop_create_recover -- + * Recovery function for create. + * + * PUBLIC: int __fop_create_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__fop_create_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __fop_create_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__fop_create_print); + REC_INTRO(__fop_create_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __fop_create_recover -- + * Recovery function for create. + * + * PUBLIC: int __fop_create_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__fop_create_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __fop_create_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__fop_create_print); + REC_INTRO(__fop_create_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __fop_remove_recover -- + * Recovery function for remove. + * + * PUBLIC: int __fop_remove_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__fop_remove_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __fop_remove_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__fop_remove_print); + REC_INTRO(__fop_remove_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __fop_write_recover -- + * Recovery function for write. + * + * PUBLIC: int __fop_write_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__fop_write_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __fop_write_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__fop_write_print); + REC_INTRO(__fop_write_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __fop_write_recover -- + * Recovery function for write. + * + * PUBLIC: int __fop_write_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__fop_write_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __fop_write_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__fop_write_print); + REC_INTRO(__fop_write_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __fop_rename_recover -- + * Recovery function for rename. + * + * PUBLIC: int __fop_rename_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__fop_rename_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __fop_rename_noundo_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__fop_rename_noundo_print); + REC_INTRO(__fop_rename_noundo_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __fop_rename_recover -- + * Recovery function for rename. + * + * PUBLIC: int __fop_rename_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__fop_rename_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __fop_rename_noundo_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__fop_rename_noundo_print); + REC_INTRO(__fop_rename_noundo_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __fop_file_remove_recover -- + * Recovery function for file_remove. + * + * PUBLIC: int __fop_file_remove_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__fop_file_remove_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __fop_file_remove_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__fop_file_remove_print); + REC_INTRO(__fop_file_remove_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + diff --git a/src/libs/resiprocate/contrib/db/dist/template/rec_hash b/src/libs/resiprocate/contrib/db/dist/template/rec_hash new file mode 100644 index 00000000..223c449a --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/template/rec_hash @@ -0,0 +1,722 @@ +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/__ham.h" +#include "dbinc/log.h" + +/* + * __ham_insdel_recover -- + * Recovery function for insdel. + * + * PUBLIC: int __ham_insdel_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__ham_insdel_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __ham_insdel_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__ham_insdel_print); + REC_INTRO(__ham_insdel_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __ham_newpage_recover -- + * Recovery function for newpage. + * + * PUBLIC: int __ham_newpage_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__ham_newpage_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __ham_newpage_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__ham_newpage_print); + REC_INTRO(__ham_newpage_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __ham_splitdata_recover -- + * Recovery function for splitdata. + * + * PUBLIC: int __ham_splitdata_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__ham_splitdata_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __ham_splitdata_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__ham_splitdata_print); + REC_INTRO(__ham_splitdata_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __ham_replace_recover -- + * Recovery function for replace. + * + * PUBLIC: int __ham_replace_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__ham_replace_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __ham_replace_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__ham_replace_print); + REC_INTRO(__ham_replace_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __ham_copypage_recover -- + * Recovery function for copypage. + * + * PUBLIC: int __ham_copypage_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__ham_copypage_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __ham_copypage_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__ham_copypage_print); + REC_INTRO(__ham_copypage_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __ham_metagroup_recover -- + * Recovery function for metagroup. + * + * PUBLIC: int __ham_metagroup_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__ham_metagroup_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __ham_metagroup_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__ham_metagroup_print); + REC_INTRO(__ham_metagroup_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __ham_metagroup_recover -- + * Recovery function for metagroup. + * + * PUBLIC: int __ham_metagroup_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__ham_metagroup_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __ham_metagroup_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__ham_metagroup_print); + REC_INTRO(__ham_metagroup_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __ham_groupalloc_recover -- + * Recovery function for groupalloc. + * + * PUBLIC: int __ham_groupalloc_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__ham_groupalloc_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __ham_groupalloc_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__ham_groupalloc_print); + REC_INTRO(__ham_groupalloc_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __ham_groupalloc_recover -- + * Recovery function for groupalloc. + * + * PUBLIC: int __ham_groupalloc_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__ham_groupalloc_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __ham_groupalloc_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__ham_groupalloc_print); + REC_INTRO(__ham_groupalloc_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __ham_curadj_recover -- + * Recovery function for curadj. + * + * PUBLIC: int __ham_curadj_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__ham_curadj_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __ham_curadj_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__ham_curadj_print); + REC_INTRO(__ham_curadj_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __ham_chgpg_recover -- + * Recovery function for chgpg. + * + * PUBLIC: int __ham_chgpg_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__ham_chgpg_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __ham_chgpg_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__ham_chgpg_print); + REC_INTRO(__ham_chgpg_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + diff --git a/src/libs/resiprocate/contrib/db/dist/template/rec_qam b/src/libs/resiprocate/contrib/db/dist/template/rec_qam new file mode 100644 index 00000000..502b555f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/template/rec_qam @@ -0,0 +1,332 @@ +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/__qam.h" +#include "dbinc/log.h" + +/* + * __qam_incfirst_recover -- + * Recovery function for incfirst. + * + * PUBLIC: int __qam_incfirst_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__qam_incfirst_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __qam_incfirst_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__qam_incfirst_print); + REC_INTRO(__qam_incfirst_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __qam_mvptr_recover -- + * Recovery function for mvptr. + * + * PUBLIC: int __qam_mvptr_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__qam_mvptr_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __qam_mvptr_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__qam_mvptr_print); + REC_INTRO(__qam_mvptr_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __qam_del_recover -- + * Recovery function for del. + * + * PUBLIC: int __qam_del_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__qam_del_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __qam_del_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__qam_del_print); + REC_INTRO(__qam_del_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __qam_add_recover -- + * Recovery function for add. + * + * PUBLIC: int __qam_add_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__qam_add_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __qam_add_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__qam_add_print); + REC_INTRO(__qam_add_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __qam_delext_recover -- + * Recovery function for delext. + * + * PUBLIC: int __qam_delext_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__qam_delext_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __qam_delext_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__qam_delext_print); + REC_INTRO(__qam_delext_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + diff --git a/src/libs/resiprocate/contrib/db/dist/template/rec_rep b/src/libs/resiprocate/contrib/db/dist/template/rec_rep new file mode 100644 index 00000000..8008c9de --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/template/rec_rep @@ -0,0 +1,7 @@ +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/__rep.h" +#include "dbinc/log.h" + diff --git a/src/libs/resiprocate/contrib/db/dist/template/rec_txn b/src/libs/resiprocate/contrib/db/dist/template/rec_txn new file mode 100644 index 00000000..89f05387 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/template/rec_txn @@ -0,0 +1,527 @@ +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/__txn.h" +#include "dbinc/log.h" + +/* + * __txn_regop_recover -- + * Recovery function for regop. + * + * PUBLIC: int __txn_regop_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__txn_regop_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __txn_regop_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__txn_regop_print); + REC_INTRO(__txn_regop_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __txn_regop_recover -- + * Recovery function for regop. + * + * PUBLIC: int __txn_regop_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__txn_regop_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __txn_regop_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__txn_regop_print); + REC_INTRO(__txn_regop_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __txn_ckp_recover -- + * Recovery function for ckp. + * + * PUBLIC: int __txn_ckp_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__txn_ckp_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __txn_ckp_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__txn_ckp_print); + REC_INTRO(__txn_ckp_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __txn_ckp_recover -- + * Recovery function for ckp. + * + * PUBLIC: int __txn_ckp_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__txn_ckp_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __txn_ckp_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__txn_ckp_print); + REC_INTRO(__txn_ckp_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __txn_child_recover -- + * Recovery function for child. + * + * PUBLIC: int __txn_child_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__txn_child_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __txn_child_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__txn_child_print); + REC_INTRO(__txn_child_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __txn_xa_regop_recover -- + * Recovery function for xa_regop. + * + * PUBLIC: int __txn_xa_regop_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__txn_xa_regop_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __txn_xa_regop_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__txn_xa_regop_print); + REC_INTRO(__txn_xa_regop_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __txn_prepare_recover -- + * Recovery function for prepare. + * + * PUBLIC: int __txn_prepare_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__txn_prepare_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __txn_prepare_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__txn_prepare_print); + REC_INTRO(__txn_prepare_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + +/* + * __txn_recycle_recover -- + * Recovery function for recycle. + * + * PUBLIC: int __txn_recycle_recover + * PUBLIC: __P((env *, DBT *, DB_LSN *, db_recops, void *)); + */ +int +__txn_recycle_recover(env, dbtp, lsnp, op, info) + env *env; + DBT *dbtp; + DB_LSN *lsnp; + db_recops op; + void *info; +{ + __txn_recycle_args *argp; + DB *file_dbp; + DBC *dbc; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + PAGE *pagep; + int cmp_n, cmp_p, modified, ret; + + ip = ((DB_TXNHEAD *)info)->thread_info; + + REC_PRINT(__txn_recycle_print); + REC_INTRO(__txn_recycle_read, ip, 0); + + if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) + if (DB_REDO(op)) { + if ((ret = mpf->get(mpf, + &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) + goto out; + } else { + *lsnp = argp->prev_lsn; + ret = 0; + goto out; + } + + modified = 0; + cmp_n = log_compare(lsnp, &LSN(pagep)); + + /* + * Use this when there is something like "pagelsn" in the argp + * structure. Sometimes, you might need to compare meta-data + * lsn's instead. + * + * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); + */ + if (cmp_p == 0 && DB_REDO(op)) { + /* Need to redo update described. */ + modified = 1; + } else if (cmp_n == 0 && !DB_REDO(op)) { + /* Need to undo update described. */ + modified = 1; + } + if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) + goto out; + + *lsnp = argp->prev_lsn; + ret = 0; + +out: REC_CLOSE; +} + diff --git a/src/libs/resiprocate/contrib/db/dist/vx_2.0/BerkeleyDB.wpj b/src/libs/resiprocate/contrib/db/dist/vx_2.0/BerkeleyDB.wpj new file mode 100644 index 00000000..692d1b40 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/vx_2.0/BerkeleyDB.wpj @@ -0,0 +1,251 @@ +Document file - DO NOT EDIT + + BUILD_PENTIUM_debug_BUILDRULE +BerkeleyDB20.out + + + BUILD_PENTIUM_debug_MACRO_AR +ar386 + + + BUILD_PENTIUM_debug_MACRO_ARCHIVE +$(PRJ_DIR)/PENTIUMgnu/BerkeleyDB20_sim.a + + + BUILD_PENTIUM_debug_MACRO_AS +cc386 + + + BUILD_PENTIUM_debug_MACRO_CC +cc386 + + + BUILD_PENTIUM_debug_MACRO_CFLAGS +-g \ + -mpentium \ + -ansi \ + -nostdinc \ + -DRW_MULTI_THREAD \ + -D_REENTRANT \ + -fvolatile \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM \ + -O0 \ + -I$(PRJ_DIR) \ + -I$(PRJ_DIR)/.. \ + -DDIAGNOSTIC \ + -DDEBUG + + + BUILD_PENTIUM_debug_MACRO_CFLAGS_AS +-g \ + -mpentium \ + -ansi \ + -nostdinc \ + -fvolatile \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -P \ + -x \ + assembler-with-cpp \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM + + + BUILD_PENTIUM_debug_MACRO_CPP +cc386 -E -P -xc + + + BUILD_PENTIUM_debug_MACRO_LD +ld386 + + + BUILD_PENTIUM_debug_MACRO_LDFLAGS +-X -N + + + BUILD_PENTIUM_debug_MACRO_LD_PARTIAL_FLAGS +-X -r + + + BUILD_PENTIUM_debug_MACRO_NM +nm386 -g + + + BUILD_PENTIUM_debug_MACRO_OPTION_DEFINE_MACRO +-D + + + BUILD_PENTIUM_debug_MACRO_OPTION_INCLUDE_DIR +-I + + + BUILD_PENTIUM_debug_MACRO_POST_BUILD_RULE + + + + BUILD_PENTIUM_debug_MACRO_PRJ_LIBS + + + + BUILD_PENTIUM_debug_MACRO_SIZE +size386 + + + BUILD_PENTIUM_debug_RO_DEPEND_PATH +{$(WIND_BASE)/target/h/} \ + {$(WIND_BASE)/target/src/} \ + {$(WIND_BASE)/target/config/} + + + BUILD_PENTIUM_debug_TC +::tc_PENTIUMgnu + + + BUILD_PENTIUM_release_BUILDRULE +BerkeleyDB20.out + + + BUILD_PENTIUM_release_MACRO_AR +ar386 + + + BUILD_PENTIUM_release_MACRO_ARCHIVE +$(PRJ_DIR)/PENTIUMgnu/BerkeleyDB20_sim.a + + + BUILD_PENTIUM_release_MACRO_AS +cc386 + + + BUILD_PENTIUM_release_MACRO_CC +cc386 + + + BUILD_PENTIUM_release_MACRO_CFLAGS +-mpentium \ + -ansi \ + -nostdinc \ + -DRW_MULTI_THREAD \ + -D_REENTRANT \ + -fvolatile \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM \ + -O2 \ + -I$(PRJ_DIR) \ + -I$(PRJ_DIR)/.. + + + BUILD_PENTIUM_release_MACRO_CFLAGS_AS +-g \ + -mpentium \ + -ansi \ + -nostdinc \ + -fvolatile \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -P \ + -x \ + assembler-with-cpp \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM + + + BUILD_PENTIUM_release_MACRO_CPP +cc386 -E -P -xc + + + BUILD_PENTIUM_release_MACRO_LD +ld386 + + + BUILD_PENTIUM_release_MACRO_LDDEPS + + + + BUILD_PENTIUM_release_MACRO_LDFLAGS +-X -N + + + BUILD_PENTIUM_release_MACRO_LD_PARTIAL_FLAGS +-X -r + + + BUILD_PENTIUM_release_MACRO_NM +nm386 -g + + + BUILD_PENTIUM_release_MACRO_OPTION_DEFINE_MACRO +-D + + + BUILD_PENTIUM_release_MACRO_OPTION_INCLUDE_DIR +-I + + + BUILD_PENTIUM_release_MACRO_POST_BUILD_RULE + + + + BUILD_PENTIUM_release_MACRO_PRJ_LIBS + + + + BUILD_PENTIUM_release_MACRO_SIZE +size386 + + + BUILD_PENTIUM_release_RO_DEPEND_PATH +{$(WIND_BASE)/target/h/} \ + {$(WIND_BASE)/target/src/} \ + {$(WIND_BASE)/target/config/} + + + BUILD_PENTIUM_release_TC +::tc_PENTIUMgnu + + + BUILD_RULE_BerkeleyDB20.out + + + + BUILD_RULE_BerkeleyDB20_sim.out + + + + BUILD_RULE_archive + + + + BUILD_RULE_objects + + + + BUILD__CURRENT +PENTIUM_debug + + + BUILD__LIST +PENTIUM_release PENTIUM_debug + + + CORE_INFO_TYPE +::prj_vxApp + + + CORE_INFO_VERSION +2.0 + + diff --git a/src/libs/resiprocate/contrib/db/dist/vx_2.0/BerkeleyDBsmall.wpj b/src/libs/resiprocate/contrib/db/dist/vx_2.0/BerkeleyDBsmall.wpj new file mode 100644 index 00000000..3c9fd350 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/vx_2.0/BerkeleyDBsmall.wpj @@ -0,0 +1,251 @@ +Document file - DO NOT EDIT + + BUILD_PENTIUM_debug_BUILDRULE +BerkeleyDB20small.out + + + BUILD_PENTIUM_debug_MACRO_AR +ar386 + + + BUILD_PENTIUM_debug_MACRO_ARCHIVE +$(PRJ_DIR)/PENTIUMgnu/BerkeleyDB20small_sim.a + + + BUILD_PENTIUM_debug_MACRO_AS +cc386 + + + BUILD_PENTIUM_debug_MACRO_CC +cc386 + + + BUILD_PENTIUM_debug_MACRO_CFLAGS +-g \ + -mpentium \ + -ansi \ + -nostdinc \ + -DRW_MULTI_THREAD \ + -D_REENTRANT \ + -fvolatile \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM \ + -O0 \ + -I$(PRJ_DIR) \ + -I$(PRJ_DIR)/.. \ + -DDIAGNOSTIC \ + -DDEBUG + + + BUILD_PENTIUM_debug_MACRO_CFLAGS_AS +-g \ + -mpentium \ + -ansi \ + -nostdinc \ + -fvolatile \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -P \ + -x \ + assembler-with-cpp \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM + + + BUILD_PENTIUM_debug_MACRO_CPP +cc386 -E -P -xc + + + BUILD_PENTIUM_debug_MACRO_LD +ld386 + + + BUILD_PENTIUM_debug_MACRO_LDFLAGS +-X -N + + + BUILD_PENTIUM_debug_MACRO_LD_PARTIAL_FLAGS +-X -r + + + BUILD_PENTIUM_debug_MACRO_NM +nm386 -g + + + BUILD_PENTIUM_debug_MACRO_OPTION_DEFINE_MACRO +-D + + + BUILD_PENTIUM_debug_MACRO_OPTION_INCLUDE_DIR +-I + + + BUILD_PENTIUM_debug_MACRO_POST_BUILD_RULE + + + + BUILD_PENTIUM_debug_MACRO_PRJ_LIBS + + + + BUILD_PENTIUM_debug_MACRO_SIZE +size386 + + + BUILD_PENTIUM_debug_RO_DEPEND_PATH +{$(WIND_BASE)/target/h/} \ + {$(WIND_BASE)/target/src/} \ + {$(WIND_BASE)/target/config/} + + + BUILD_PENTIUM_debug_TC +::tc_PENTIUMgnu + + + BUILD_PENTIUM_release_BUILDRULE +BerkeleyDB20small.out + + + BUILD_PENTIUM_release_MACRO_AR +ar386 + + + BUILD_PENTIUM_release_MACRO_ARCHIVE +$(PRJ_DIR)/PENTIUMgnu/BerkeleyDB20small_sim.a + + + BUILD_PENTIUM_release_MACRO_AS +cc386 + + + BUILD_PENTIUM_release_MACRO_CC +cc386 + + + BUILD_PENTIUM_release_MACRO_CFLAGS +-mpentium \ + -ansi \ + -nostdinc \ + -DRW_MULTI_THREAD \ + -D_REENTRANT \ + -fvolatile \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM \ + -O2 \ + -I$(PRJ_DIR) \ + -I$(PRJ_DIR)/.. + + + BUILD_PENTIUM_release_MACRO_CFLAGS_AS +-g \ + -mpentium \ + -ansi \ + -nostdinc \ + -fvolatile \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -P \ + -x \ + assembler-with-cpp \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM + + + BUILD_PENTIUM_release_MACRO_CPP +cc386 -E -P -xc + + + BUILD_PENTIUM_release_MACRO_LD +ld386 + + + BUILD_PENTIUM_release_MACRO_LDDEPS + + + + BUILD_PENTIUM_release_MACRO_LDFLAGS +-X -N + + + BUILD_PENTIUM_release_MACRO_LD_PARTIAL_FLAGS +-X -r + + + BUILD_PENTIUM_release_MACRO_NM +nm386 -g + + + BUILD_PENTIUM_release_MACRO_OPTION_DEFINE_MACRO +-D + + + BUILD_PENTIUM_release_MACRO_OPTION_INCLUDE_DIR +-I + + + BUILD_PENTIUM_release_MACRO_POST_BUILD_RULE + + + + BUILD_PENTIUM_release_MACRO_PRJ_LIBS + + + + BUILD_PENTIUM_release_MACRO_SIZE +size386 + + + BUILD_PENTIUM_release_RO_DEPEND_PATH +{$(WIND_BASE)/target/h/} \ + {$(WIND_BASE)/target/src/} \ + {$(WIND_BASE)/target/config/} + + + BUILD_PENTIUM_release_TC +::tc_PENTIUMgnu + + + BUILD_RULE_BerkeleyDB20small.out + + + + BUILD_RULE_BerkeleyDB20small_sim.out + + + + BUILD_RULE_archive + + + + BUILD_RULE_objects + + + + BUILD__CURRENT +PENTIUM_debug + + + BUILD__LIST +PENTIUM_release PENTIUM_debug + + + CORE_INFO_TYPE +::prj_vxApp + + + CORE_INFO_VERSION +2.0 + + diff --git a/src/libs/resiprocate/contrib/db/dist/vx_2.0/wpj.in b/src/libs/resiprocate/contrib/db/dist/vx_2.0/wpj.in new file mode 100644 index 00000000..88b27dff --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/vx_2.0/wpj.in @@ -0,0 +1,136 @@ +Document file - DO NOT EDIT + + BUILD_PENTIUMgnu_BUILDRULE +__DB_APPLICATION_NAME__20.out + + + BUILD_PENTIUMgnu_MACRO_AR +ar386 + + + BUILD_PENTIUMgnu_MACRO_ARCHIVE +$(PRJ_DIR)/PENTIUMgnu/__DB_APPLICATION_NAME__20.a + + + BUILD_PENTIUMgnu_MACRO_AS +cc386 + + + BUILD_PENTIUMgnu_MACRO_CC +cc386 + + + BUILD_PENTIUMgnu_MACRO_CFLAGS +-g \ + -mpentium \ + -ansi \ + -nostdinc \ + -DRW_MULTI_THREAD \ + -D_REENTRANT \ + -fvolatile \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -I$(PRJ_DIR)/.. \ + -I$(PRJ_DIR)/../.. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM + + + BUILD_PENTIUMgnu_MACRO_CFLAGS_AS +-g \ + -mpentium \ + -ansi \ + -nostdinc \ + -fvolatile \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -P \ + -x \ + assembler-with-cpp \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM + + + BUILD_PENTIUMgnu_MACRO_CPP +cc386 -E -P -xc + + + BUILD_PENTIUMgnu_MACRO_LD +ld386 + + + BUILD_PENTIUMgnu_MACRO_LDDEPS + + + + BUILD_PENTIUMgnu_MACRO_LDFLAGS +-X -N + + + BUILD_PENTIUMgnu_MACRO_LD_PARTIAL_FLAGS +-X -r + + + BUILD_PENTIUMgnu_MACRO_NM +nm386 -g + + + BUILD_PENTIUMgnu_MACRO_OPTION_DEFINE_MACRO +-D + + + BUILD_PENTIUMgnu_MACRO_OPTION_INCLUDE_DIR +-I + + + BUILD_PENTIUMgnu_MACRO_POST_BUILD_RULE + + + + BUILD_PENTIUMgnu_MACRO_PRJ_LIBS + + + + BUILD_PENTIUMgnu_MACRO_SIZE +size386 + + + BUILD_PENTIUMgnu_RO_DEPEND_PATH +{$(WIND_BASE)/target/h/} \ + {$(WIND_BASE)/target/src/} \ + {$(WIND_BASE)/target/config/} + + + BUILD_PENTIUMgnu_TC +::tc_PENTIUMgnu + + + BUILD_RULE_archive + + + + BUILD_RULE___DB_APPLICATION_NAME__20.out + + + + BUILD_RULE_objects + + + + BUILD__CURRENT +PENTIUMgnu + + + BUILD__LIST +PENTIUMgnu + + + CORE_INFO_TYPE +::prj_vxApp + + + CORE_INFO_VERSION +2.0 + diff --git a/src/libs/resiprocate/contrib/db/dist/vx_2.2/BerkeleyDB.wpj b/src/libs/resiprocate/contrib/db/dist/vx_2.2/BerkeleyDB.wpj new file mode 100644 index 00000000..e27a231f --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/vx_2.2/BerkeleyDB.wpj @@ -0,0 +1,310 @@ +Document file - DO NOT EDIT + + BUILD_PENTIUM_debug_BUILDRULE +BerkeleyDB22.out + + + BUILD_PENTIUM_debug_MACRO_AR +arpentium + + + BUILD_PENTIUM_debug_MACRO_ARCHIVE +$(PRJ_DIR)/PENTIUM_debug/BerkeleyDB22.a + + + BUILD_PENTIUM_debug_MACRO_AS +ccpentium + + + BUILD_PENTIUM_debug_MACRO_CC +ccpentium + + + BUILD_PENTIUM_debug_MACRO_CC_ARCH_SPEC +-mcpu=pentiumpro -march=pentiumpro + + + BUILD_PENTIUM_debug_MACRO_CFLAGS +-g \ + -mcpu=pentiumpro \ + -march=pentiumpro \ + -ansi \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM2 \ + -DTOOL_FAMILY=gnu \ + -DTOOL=gnu \ + -O0 \ + -I$(PRJ_DIR) \ + -I$(PRJ_DIR)/.. \ + -DDIAGNOSTIC \ + -DDEBUG + + + BUILD_PENTIUM_debug_MACRO_CFLAGS_AS +-g \ + -mcpu=pentiumpro \ + -march=pentiumpro \ + -ansi \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -P \ + -xassembler-with-cpp \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM2 \ + -DTOOL_FAMILY=gnu \ + -DTOOL=gnu + + + BUILD_PENTIUM_debug_MACRO_CPP +ccpentium -E -P + + + BUILD_PENTIUM_debug_MACRO_HEX_FLAGS + + + + BUILD_PENTIUM_debug_MACRO_LD +ldpentium + + + BUILD_PENTIUM_debug_MACRO_LDFLAGS +-X -N + + + BUILD_PENTIUM_debug_MACRO_LD_PARTIAL +ccpentium -r -nostdlib -Wl,-X + + + BUILD_PENTIUM_debug_MACRO_LD_PARTIAL_FLAGS +-X -r + + + BUILD_PENTIUM_debug_MACRO_NM +nmpentium -g + + + BUILD_PENTIUM_debug_MACRO_OPTION_DEFINE_MACRO +-D + + + BUILD_PENTIUM_debug_MACRO_OPTION_DEPEND +-M -w + + + BUILD_PENTIUM_debug_MACRO_OPTION_GENERATE_DEPENDENCY_FILE +-MD + + + BUILD_PENTIUM_debug_MACRO_OPTION_INCLUDE_DIR +-I + + + BUILD_PENTIUM_debug_MACRO_OPTION_LANG_C +-xc + + + BUILD_PENTIUM_debug_MACRO_OPTION_UNDEFINE_MACRO +-U + + + BUILD_PENTIUM_debug_MACRO_POST_BUILD_RULE + + + + BUILD_PENTIUM_debug_MACRO_PRJ_LIBS + + + + BUILD_PENTIUM_debug_MACRO_SIZE +sizepentium + + + BUILD_PENTIUM_debug_MACRO_TOOL_FAMILY +gnu + + + BUILD_PENTIUM_debug_RO_DEPEND_PATH +{$(WIND_BASE)/target/h/} \ + {$(WIND_BASE)/target/src/} \ + {$(WIND_BASE)/target/config/} + + + BUILD_PENTIUM_debug_TC +::tc_PENTIUM2gnu + + + BUILD_PENTIUM_release_BUILDRULE +BerkeleyDB22.out + + + BUILD_PENTIUM_release_MACRO_AR +arpentium + + + BUILD_PENTIUM_release_MACRO_ARCHIVE +$(PRJ_DIR)/PENTIUM_release/BerkeleyDB22.a + + + BUILD_PENTIUM_release_MACRO_AS +ccpentium + + + BUILD_PENTIUM_release_MACRO_CC +ccpentium + + + BUILD_PENTIUM_release_MACRO_CC_ARCH_SPEC +-mcpu=pentiumpro -march=pentiumpro + + + BUILD_PENTIUM_release_MACRO_CFLAGS +-g \ + -mcpu=pentiumpro \ + -march=pentiumpro \ + -ansi \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM2 \ + -DTOOL_FAMILY=gnu \ + -DTOOL=gnu \ + -O2 \ + -I$(PRJ_DIR) \ + -I$(PRJ_DIR)/.. + + + BUILD_PENTIUM_release_MACRO_CFLAGS_AS +-g \ + -mcpu=pentiumpro \ + -march=pentiumpro \ + -ansi \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -P \ + -xassembler-with-cpp \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM2 \ + -DTOOL_FAMILY=gnu \ + -DTOOL=gnu + + + BUILD_PENTIUM_release_MACRO_CPP +ccpentium -E -P + + + BUILD_PENTIUM_release_MACRO_HEX_FLAGS + + + + BUILD_PENTIUM_release_MACRO_LD +ldpentium + + + BUILD_PENTIUM_release_MACRO_LDFLAGS +-X -N + + + BUILD_PENTIUM_release_MACRO_LD_PARTIAL +ccpentium -r -nostdlib -Wl,-X + + + BUILD_PENTIUM_release_MACRO_LD_PARTIAL_FLAGS +-X -r + + + BUILD_PENTIUM_release_MACRO_NM +nmpentium -g + + + BUILD_PENTIUM_release_MACRO_OPTION_DEFINE_MACRO +-D + + + BUILD_PENTIUM_release_MACRO_OPTION_DEPEND +-M -w + + + BUILD_PENTIUM_release_MACRO_OPTION_GENERATE_DEPENDENCY_FILE +-MD + + + BUILD_PENTIUM_release_MACRO_OPTION_INCLUDE_DIR +-I + + + BUILD_PENTIUM_release_MACRO_OPTION_LANG_C +-xc + + + BUILD_PENTIUM_release_MACRO_OPTION_UNDEFINE_MACRO +-U + + + BUILD_PENTIUM_release_MACRO_POST_BUILD_RULE + + + + BUILD_PENTIUM_release_MACRO_PRJ_LIBS + + + + BUILD_PENTIUM_release_MACRO_SIZE +sizepentium + + + BUILD_PENTIUM_release_MACRO_TOOL_FAMILY +gnu + + + BUILD_PENTIUM_release_RO_DEPEND_PATH +{$(WIND_BASE)/target/h/} \ + {$(WIND_BASE)/target/src/} \ + {$(WIND_BASE)/target/config/} + + + BUILD_PENTIUM_release_TC +::tc_PENTIUM2gnu + + + BUILD_RULE_BerkeleyDB22.out + + + + BUILD_RULE_BerkeleyDB22.pl + + + + BUILD_RULE_archive + + + + BUILD_RULE_objects + + + + BUILD__CURRENT +PENTIUM_debug + + + BUILD__LIST +PENTIUM_release PENTIUM_debug + + + CORE_INFO_TYPE +::prj_vxApp + + + CORE_INFO_VERSION +2.2 + + diff --git a/src/libs/resiprocate/contrib/db/dist/vx_2.2/BerkeleyDBsmall.wpj b/src/libs/resiprocate/contrib/db/dist/vx_2.2/BerkeleyDBsmall.wpj new file mode 100644 index 00000000..b6fa8498 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/vx_2.2/BerkeleyDBsmall.wpj @@ -0,0 +1,309 @@ +Document file - DO NOT EDIT + + BUILD_PENTIUM_debug_BUILDRULE +BerkeleyDB22small.out + + + BUILD_PENTIUM_debug_MACRO_AR +arpentium + + + BUILD_PENTIUM_debug_MACRO_ARCHIVE +$(PRJ_DIR)/PENTIUM_debug/BerkeleyDB22small.a + + + BUILD_PENTIUM_debug_MACRO_AS +ccpentium + + + BUILD_PENTIUM_debug_MACRO_CC +ccpentium + + + BUILD_PENTIUM_debug_MACRO_CC_ARCH_SPEC +-mcpu=pentiumpro -march=pentiumpro + + + BUILD_PENTIUM_debug_MACRO_CFLAGS +-g \ + -mcpu=pentiumpro \ + -march=pentiumpro \ + -ansi \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM2 \ + -DTOOL_FAMILY=gnu \ + -DTOOL=gnu \ + -O0 \ + -I$(PRJ_DIR) \ + -I$(PRJ_DIR)/.. \ + -DDIAGNOSTIC \ + -DDEBUG + + + BUILD_PENTIUM_debug_MACRO_CFLAGS_AS +-g \ + -mcpu=pentiumpro \ + -march=pentiumpro \ + -ansi \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -P \ + -xassembler-with-cpp \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM2 \ + -DTOOL_FAMILY=gnu \ + -DTOOL=gnu + + + BUILD_PENTIUM_debug_MACRO_CPP +ccpentium -E -P + + + BUILD_PENTIUM_debug_MACRO_HEX_FLAGS + + + + BUILD_PENTIUM_debug_MACRO_LD +ldpentium + + + BUILD_PENTIUM_debug_MACRO_LDFLAGS +-X -N + + + BUILD_PENTIUM_debug_MACRO_LD_PARTIAL +ccpentium -r -nostdlib -Wl,-X + + + BUILD_PENTIUM_debug_MACRO_LD_PARTIAL_FLAGS +-X -r + + + BUILD_PENTIUM_debug_MACRO_NM +nmpentium -g + + + BUILD_PENTIUM_debug_MACRO_OPTION_DEFINE_MACRO +-D + + + BUILD_PENTIUM_debug_MACRO_OPTION_DEPEND +-M -w + + + BUILD_PENTIUM_debug_MACRO_OPTION_GENERATE_DEPENDENCY_FILE +-MD + + + BUILD_PENTIUM_debug_MACRO_OPTION_INCLUDE_DIR +-I + + + BUILD_PENTIUM_debug_MACRO_OPTION_LANG_C +-xc + + + BUILD_PENTIUM_debug_MACRO_OPTION_UNDEFINE_MACRO +-U + + + BUILD_PENTIUM_debug_MACRO_POST_BUILD_RULE + + + + BUILD_PENTIUM_debug_MACRO_PRJ_LIBS + + + + BUILD_PENTIUM_debug_MACRO_SIZE +sizepentium + + + BUILD_PENTIUM_debug_MACRO_TOOL_FAMILY +gnu + + + BUILD_PENTIUM_debug_RO_DEPEND_PATH +{$(WIND_BASE)/target/h/} \ + {$(WIND_BASE)/target/src/} \ + {$(WIND_BASE)/target/config/} + + + BUILD_PENTIUM_debug_TC +::tc_PENTIUM2gnu + + + BUILD_PENTIUM_release_BUILDRULE +BerkeleyDB22small.out + + + BUILD_PENTIUM_release_MACRO_AR +arpentium + + + BUILD_PENTIUM_release_MACRO_ARCHIVE +$(PRJ_DIR)/PENTIUM_release/BerkeleyDB22small.a + + + BUILD_PENTIUM_release_MACRO_AS +ccpentium + + + BUILD_PENTIUM_release_MACRO_CC +ccpentium + + + BUILD_PENTIUM_release_MACRO_CC_ARCH_SPEC +-mcpu=pentiumpro -march=pentiumpro + + + BUILD_PENTIUM_release_MACRO_CFLAGS +-mcpu=pentiumpro \ + -march=pentiumpro \ + -ansi \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM2 \ + -DTOOL_FAMILY=gnu \ + -DTOOL=gnu \ + -O2 \ + -I$(PRJ_DIR) \ + -I$(PRJ_DIR)/.. + + + BUILD_PENTIUM_release_MACRO_CFLAGS_AS +-g \ + -mcpu=pentiumpro \ + -march=pentiumpro \ + -ansi \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -P \ + -xassembler-with-cpp \ + -I. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM2 \ + -DTOOL_FAMILY=gnu \ + -DTOOL=gnu + + + BUILD_PENTIUM_release_MACRO_CPP +ccpentium -E -P + + + BUILD_PENTIUM_release_MACRO_HEX_FLAGS + + + + BUILD_PENTIUM_release_MACRO_LD +ldpentium + + + BUILD_PENTIUM_release_MACRO_LDFLAGS +-X -N + + + BUILD_PENTIUM_release_MACRO_LD_PARTIAL +ccpentium -r -nostdlib -Wl,-X + + + BUILD_PENTIUM_release_MACRO_LD_PARTIAL_FLAGS +-X -r + + + BUILD_PENTIUM_release_MACRO_NM +nmpentium -g + + + BUILD_PENTIUM_release_MACRO_OPTION_DEFINE_MACRO +-D + + + BUILD_PENTIUM_release_MACRO_OPTION_DEPEND +-M -w + + + BUILD_PENTIUM_release_MACRO_OPTION_GENERATE_DEPENDENCY_FILE +-MD + + + BUILD_PENTIUM_release_MACRO_OPTION_INCLUDE_DIR +-I + + + BUILD_PENTIUM_release_MACRO_OPTION_LANG_C +-xc + + + BUILD_PENTIUM_release_MACRO_OPTION_UNDEFINE_MACRO +-U + + + BUILD_PENTIUM_release_MACRO_POST_BUILD_RULE + + + + BUILD_PENTIUM_release_MACRO_PRJ_LIBS + + + + BUILD_PENTIUM_release_MACRO_SIZE +sizepentium + + + BUILD_PENTIUM_release_MACRO_TOOL_FAMILY +gnu + + + BUILD_PENTIUM_release_RO_DEPEND_PATH +{$(WIND_BASE)/target/h/} \ + {$(WIND_BASE)/target/src/} \ + {$(WIND_BASE)/target/config/} + + + BUILD_PENTIUM_release_TC +::tc_PENTIUM2gnu + + + BUILD_RULE_BerkeleyDB22small.out + + + + BUILD_RULE_BerkeleyDB22small.pl + + + + BUILD_RULE_archive + + + + BUILD_RULE_objects + + + + BUILD__CURRENT +PENTIUM_debug + + + BUILD__LIST +PENTIUM_release PENTIUM_debug + + + CORE_INFO_TYPE +::prj_vxApp + + + CORE_INFO_VERSION +2.2 + + diff --git a/src/libs/resiprocate/contrib/db/dist/vx_2.2/wpj.in b/src/libs/resiprocate/contrib/db/dist/vx_2.2/wpj.in new file mode 100644 index 00000000..17816d9d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/vx_2.2/wpj.in @@ -0,0 +1,170 @@ +Document file - DO NOT EDIT + + BUILD_PENTIUM2gnu_BUILDRULE +__DB_APPLICATION_NAME__22.out + + + BUILD_PENTIUM2gnu_MACRO_AR +arpentium + + + BUILD_PENTIUM2gnu_MACRO_ARCHIVE +$(PRJ_DIR)/PENTIUM2gnu/__DB_APPLICATION_NAME__22.a + + + BUILD_PENTIUM2gnu_MACRO_AS +ccpentium + + + BUILD_PENTIUM2gnu_MACRO_CC +ccpentium + + + BUILD_PENTIUM2gnu_MACRO_CC_ARCH_SPEC +-mcpu=pentiumpro -march=pentiumpro + + + BUILD_PENTIUM2gnu_MACRO_CFLAGS +-g \ + -mcpu=pentiumpro \ + -march=pentiumpro \ + -ansi \ + -nostdlib \ + -DRW_MULTI_THREAD \ + -D_REENTRANT \ + -fvolatile \ + -fno-builtin \ + -fno-defer-pop \ + -I$(PRJ_DIR)/.. \ + -I$(PRJ_DIR)/../.. \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM2 \ + -DTOOL_FAMILY=gnu \ + -DTOOL=gnu + + + BUILD_PENTIUM2gnu_MACRO_CFLAGS_AS +-g \ + -mcpu=pentiumpro \ + -march=pentiumpro \ + -ansi \ + -nostdlib \ + -fno-builtin \ + -fno-defer-pop \ + -P \ + -xassembler-with-cpp \ + -I$(WIND_BASE)/target/h \ + -DCPU=PENTIUM2 \ + -DTOOL_FAMILY=gnu \ + -DTOOL=gnu + + + BUILD_PENTIUM2gnu_MACRO_CPP +ccpentium -E -P + + + BUILD_PENTIUM2gnu_MACRO_HEX_FLAGS + + + + BUILD_PENTIUM2gnu_MACRO_LD +ldpentium + + + BUILD_PENTIUM2gnu_MACRO_LDFLAGS +-X -N + + + BUILD_PENTIUM2gnu_MACRO_LD_PARTIAL +ccpentium -r -nostdlib -Wl,-X + + + BUILD_PENTIUM2gnu_MACRO_LD_PARTIAL_FLAGS +-X -r + + + BUILD_PENTIUM2gnu_MACRO_NM +nmpentium -g + + + BUILD_PENTIUM2gnu_MACRO_OPTION_DEFINE_MACRO +-D + + + BUILD_PENTIUM2gnu_MACRO_OPTION_DEPEND +-M -w + + + BUILD_PENTIUM2gnu_MACRO_OPTION_GENERATE_DEPENDENCY_FILE +-MD + + + BUILD_PENTIUM2gnu_MACRO_OPTION_INCLUDE_DIR +-I + + + BUILD_PENTIUM2gnu_MACRO_OPTION_LANG_C +-xc + + + BUILD_PENTIUM2gnu_MACRO_OPTION_UNDEFINE_MACRO +-U + + + BUILD_PENTIUM2gnu_MACRO_POST_BUILD_RULE + + + + BUILD_PENTIUM2gnu_MACRO_PRJ_LIBS + + + + BUILD_PENTIUM2gnu_MACRO_SIZE +sizepentium + + + BUILD_PENTIUM2gnu_MACRO_TOOL_FAMILY +gnu + + + BUILD_PENTIUM2gnu_RO_DEPEND_PATH +{$(WIND_BASE)/target/h/} \ + {$(WIND_BASE)/target/src/} \ + {$(WIND_BASE)/target/config/} + + + BUILD_PENTIUM2gnu_TC +::tc_PENTIUM2gnu + + + BUILD_RULE_archive + + + + BUILD_RULE___DB_APPLICATION_NAME__22.out + + + + BUILD_RULE___DB_APPLICATION_NAME__22.pl + + + + BUILD_RULE_objects + + + + BUILD__CURRENT +PENTIUM2gnu + + + BUILD__LIST +PENTIUM2gnu + + + CORE_INFO_TYPE +::prj_vxApp + + + CORE_INFO_VERSION +2.2 + diff --git a/src/libs/resiprocate/contrib/db/dist/vx_buildcd b/src/libs/resiprocate/contrib/db/dist/vx_buildcd new file mode 100644 index 00000000..29ec564d --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/vx_buildcd @@ -0,0 +1,119 @@ +#!/bin/sh +# $Id$ +# +# Build the Setup SDK CD image on the VxWorks host machine. + +. ./RELEASE + +B=`pwd` +B=$B/.. +D=$B/dist/vx_setup +C=$D/db.CD +Q=/export/home/sue/SetupSDK +S=$Q/resource/mfg/setup +W=sun4-solaris2 + +symdoc=$D/docs/BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH +symdb=$D/windlink/sleepycat/BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH +rm -rf $D/docs $D/windlink +mkdir $D/docs $D/windlink $D/windlink/sleepycat +ln -s $B/docs $symdoc +ln -s $B $symdb + +s=/tmp/__db_a +t=/tmp/__db_b + +# +# Remove the old CD directory if it is there. +if test -d $C; then + echo "$C cannot exist." + echo "As root, execute 'rm -rf $C'" + echo "and then rerun the script" + exit 1 +fi + +# +# Check for absolute pathnames in the project files. +# That is bad, but Tornado insists on putting them in +# whenever you add new files. +# +rm -f $t +f=`find $B/build_vxworks -name \*.wpj -print` +for i in $f; do + grep -l -- "$B" $i >> $t +done +if test -s $t; then + echo "The following files contain absolute pathnames." + echo "They must be fixed before building the CD image:" + cat $t + exit 1 +fi + +# +# NOTE: We reuse the same sed script over several files. +# +cat < $s +s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/g +s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/g +s/@DB_VERSION_PATCH@/$DB_VERSION_PATCH/g +s#@DB_SETUP_DIR@#$D#g +ENDOFSEDTEXT + +f=$D/setup.pool +(sed -f $s $D/vx_setup.in) > $t + (echo "Building $f" && rm -f $f && cp $t $f) + +f=$D/README.TXT +(sed -f $s $D/README.in) > $t + (echo "Building $f" && rm -f $f && cp $t $f) + +f=$D/CONFIG.TCL +(sed -f $s $D/CONFIG.in) > $t + (echo "Building $f" && rm -f $f && cp $t $f) + +f=$D/filelist.demo +(sed -f $s $D/vx_demofile.in) > $t + (echo "Building $f" && rm -f $f && cp $t $f) + +# Copy files into the SetupSDK area. +(cd $D && cp README.TXT $S) +(cd $D && cp LICENSE.TXT $S) +(cd $D && cp CONFIG.TCL $S/RESOURCE/TCL) +(cd $D && cp SETUP.BMP $S/RESOURCE/BITMAPS) + +# +# NOTE: The contents of LIB must be on one, long, single line. +# Even preserving it with a \ doesn't work for htmlBook. +# +f=../docs/LIB +(echo "Building $f" && rm -f $f) +cat <> $f +{BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH} {Berkeley DB} {BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH} {BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH} {BerkeleyDB} {} {} {} +ENDOFLIBTEXT + +# +# Start generating the file list. +f=$D/filelist.all + +# +# Just put everything into the image. But we only want to find regular +# files; we cannot have all the directories listed too. +# +# NOTE: This find is overly aggressive in getting files, particularly +# for the 'windlink/sleepycat' files. We actually end up with 3 sets of the +# documentation, the "real" ones in 'docs/BerkeleyDB*', the set found +# via 'windlink/sleepycat/Berk*/docs' and the one found via our symlink in +# 'windlink/sleepycat/Berk*/dist/vx_setup/docs/Berk*'. +# +# However, we waste a little disk space so that the expression below +# is trivial and we don't have to maintain it as new files/directories +# are added to DB. +# +(cd $D && find docs/BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH/ -follow -name \* -type f -print) > $t +(cd $D && find windlink/sleepycat/BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH/ -follow -name docs -prune -o -type f -print) >> $t +(echo "Building $f" && rm -f $f && cp $t $f) +# +# Finally build the CD image! +# +env PATH=$Q/$W/bin:$PATH QMS_BASE=$Q WIND_HOST_TYPE=$W \ +pool mfg -d $C -v -nokey BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR < $D/setup.pool diff --git a/src/libs/resiprocate/contrib/db/dist/vx_config.in b/src/libs/resiprocate/contrib/db/dist/vx_config.in new file mode 100644 index 00000000..bcadd447 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/vx_config.in @@ -0,0 +1,605 @@ +/* !!! + * The CONFIG_TEST option may be added using the Tornado project build. + * DO NOT modify it here. + */ +/* Define to 1 if you want to build a version for running the test suite. */ +/* #undef CONFIG_TEST */ + +/* We use DB_WIN32 much as one would use _WIN32 -- to specify that we're using + an operating system environment that supports Win32 calls and semantics. We + don't use _WIN32 because Cygwin/GCC also defines _WIN32, even though + Cygwin/GCC closely emulates the Unix environment. */ +/* #undef DB_WIN32 */ + +/* !!! + * The DEBUG option may be added using the Tornado project build. + * DO NOT modify it here. + */ +/* Define to 1 if you want a debugging version. */ +/* #undef DEBUG */ + +/* Define to 1 if you want a version that logs read operations. */ +/* #undef DEBUG_ROP */ + +/* Define to 1 if you want a version that logs write operations. */ +/* #undef DEBUG_WOP */ + +/* !!! + * The DIAGNOSTIC option may be added using the Tornado project build. + * DO NOT modify it here. + */ +/* Define to 1 if you want a version with run-time diagnostic checking. */ +/* #undef DIAGNOSTIC */ + +/* Define to 1 if 64-bit types are available. */ +#define HAVE_64BIT_TYPES 1 + +/* Define to 1 if you have the `abort' function. */ +#define HAVE_ABORT 1 + +/* Define to 1 if you have the `atoi' function. */ +#define HAVE_ATOI 1 + +/* Define to 1 if you have the `atol' function. */ +#define HAVE_ATOL 1 + +/* Define to 1 to use Solaris library routes for atomic operations. */ +/* #undef HAVE_ATOMIC_SOLARIS */ + +/* Define to 1 to use native atomic operations. */ +/* #undef HAVE_ATOMIC_SUPPORT */ + +/* Define to 1 to use GCC and x86 or x86_64 assemlby language atomic + operations. */ +/* #undef HAVE_ATOMIC_X86_GCC_ASSEMBLY */ + +/* Define to 1 if you have the `backtrace' function. */ +/* #undef HAVE_BACKTRACE */ + +/* Define to 1 if you have the `backtrace_symbols' function. */ +/* #undef HAVE_BACKTRACE_SYMBOLS */ + +/* Define to 1 if building BREW. */ +/* #undef HAVE_BREW */ + +/* Define to 1 if building on BREW (SDK2). */ +/* #undef HAVE_BREW_SDK2 */ + +/* Define to 1 if you have the `clock_gettime' function. */ +#define HAVE_CLOCK_GETTIME 1 + +/* Define to 1 if clock_gettime supports CLOCK_MONOTONIC. */ +/* #undef HAVE_CLOCK_MONOTONIC */ + +/* Define to 1 if building compression support. */ +/* #undef HAVE_COMPRESSION */ + +/* Define to 1 if Berkeley DB release includes strong cryptography. */ +/* #undef HAVE_CRYPTO */ + +/* Define to 1 if you have the `ctime_r' function. */ +#define HAVE_CTIME_R 1 + +/* Define to 1 if ctime_r takes a buffer length as a third argument. */ +#define HAVE_CTIME_R_3ARG 1 + +/* Define to 1 if you have the `directio' function. */ +/* #undef HAVE_DIRECTIO */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EXECINFO_H */ + +/* Define to 1 if you have EXIT_SUCCESS/EXIT_FAILURE #defines. */ +#define HAVE_EXIT_SUCCESS 1 + +/* Define to 1 if you have the `fchmod' function. */ +/* #undef HAVE_FCHMOD */ + +/* Define to 1 if you have the `fclose' function. */ +#define HAVE_FCLOSE 1 + +/* Define to 1 if you have the `fcntl' function. */ +/* #undef HAVE_FCNTL */ + +/* Define to 1 if fcntl/F_SETFD denies child access to file descriptors. */ +/* #undef HAVE_FCNTL_F_SETFD */ + +/* Define to 1 if you have the `fdatasync' function. */ +/* #undef HAVE_FDATASYNC */ + +/* Define to 1 if you have the `fgetc' function. */ +#define HAVE_FGETC 1 + +/* Define to 1 if you have the `fgets' function. */ +#define HAVE_FGETS 1 + +/* Define to 1 if allocated filesystem blocks are not zeroed. */ +#define HAVE_FILESYSTEM_NOTZERO 1 + +/* Define to 1 if you have the `fopen' function. */ +#define HAVE_FOPEN 1 + +/* Define to 1 if you have the `ftruncate' function. */ +#define HAVE_FTRUNCATE 1 + +/* Define to 1 if you have the `fwrite' function. */ +#define HAVE_FWRITE 1 + +/* Define to 1 if you have the `getaddrinfo' function. */ +/* #undef HAVE_GETADDRINFO */ + +/* Define to 1 if you have the `getcwd' function. */ +#define HAVE_GETCWD 1 + +/* Define to 1 if you have the `getenv' function. */ +#define HAVE_GETENV 1 + +/* Define to 1 if you have the `getgid' function. */ +#define HAVE_GETGID 1 + +/* Define to 1 if you have the `getopt' function. */ +/* #undef HAVE_GETOPT */ + +/* Define to 1 if getopt supports the optreset variable. */ +/* #undef HAVE_GETOPT_OPTRESET */ + +/* Define to 1 if you have the `getrusage' function. */ +/* #undef HAVE_GETRUSAGE */ + +/* Define to 1 if you have the `gettimeofday' function. */ +/* #undef HAVE_GETTIMEOFDAY */ + +/* Define to 1 if you have the `getuid' function. */ +/* #undef HAVE_GETUID */ + +/* Define to 1 if building Hash access method. */ +#define HAVE_HASH 1 + +/* Define to 1 if you have the `hstrerror' function. */ +/* #undef HAVE_HSTRERROR */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTTYPES_H */ + +/* Define to 1 if you have the `isalpha' function. */ +#define HAVE_ISALPHA 1 + +/* Define to 1 if you have the `isdigit' function. */ +#define HAVE_ISDIGIT 1 + +/* Define to 1 if you have the `isprint' function. */ +#define HAVE_ISPRINT 1 + +/* Define to 1 if you have the `isspace' function. */ +#define HAVE_ISSPACE 1 + +/* Define to 1 if you have the `localtime' function. */ +#define HAVE_LOCALTIME 1 + +/* Define to 1 if you have the `memcmp' function. */ +#define HAVE_MEMCMP 1 + +/* Define to 1 if you have the `memcpy' function. */ +#define HAVE_MEMCPY 1 + +/* Define to 1 if you have the `memmove' function. */ +#define HAVE_MEMMOVE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `mlock' function. */ +/* #undef HAVE_MLOCK */ + +/* Define to 1 if you have the `mmap' function. */ +/* #undef HAVE_MMAP */ + +/* Define to 1 if you have the `mprotect' function. */ +/* #undef HAVE_MPROTECT */ + +/* Define to 1 if you have the `munlock' function. */ +/* #undef HAVE_MUNLOCK */ + +/* Define to 1 if you have the `munmap' function. */ +/* #undef HAVE_MUNMAP */ + +/* Define to 1 to use the GCC compiler and 68K assembly language mutexes. */ +/* #undef HAVE_MUTEX_68K_GCC_ASSEMBLY */ + +/* Define to 1 to use the AIX _check_lock mutexes. */ +/* #undef HAVE_MUTEX_AIX_CHECK_LOCK */ + +/* Define to 1 to use the GCC compiler and Alpha assembly language mutexes. */ +/* #undef HAVE_MUTEX_ALPHA_GCC_ASSEMBLY */ + +/* Define to 1 to use the GCC compiler and ARM assembly language mutexes. */ +/* #undef HAVE_MUTEX_ARM_GCC_ASSEMBLY */ + +/* Define to 1 to use the Apple/Darwin _spin_lock_try mutexes. */ +/* #undef HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY */ + +/* Define to 1 to use the UNIX fcntl system call mutexes. */ +/* #undef HAVE_MUTEX_FCNTL */ + +/* Define to 1 to use the GCC compiler and PaRisc assembly language mutexes. + */ +/* #undef HAVE_MUTEX_HPPA_GCC_ASSEMBLY */ + +/* Define to 1 to use the msem_XXX mutexes on HP-UX. */ +/* #undef HAVE_MUTEX_HPPA_MSEM_INIT */ + +/* Define to 1 to use test-and-set mutexes with blocking mutexes. */ +/* #undef HAVE_MUTEX_HYBRID */ + +/* Define to 1 to use the GCC compiler and IA64 assembly language mutexes. */ +/* #undef HAVE_MUTEX_IA64_GCC_ASSEMBLY */ + +/* Define to 1 to use the GCC compiler and MIPS assembly language mutexes. */ +/* #undef HAVE_MUTEX_MIPS_GCC_ASSEMBLY */ + +/* Define to 1 to use the msem_XXX mutexes on systems other than HP-UX. */ +/* #undef HAVE_MUTEX_MSEM_INIT */ + +/* Define to 1 to use the GCC compiler and PowerPC assembly language mutexes. + */ +/* #undef HAVE_MUTEX_PPC_GCC_ASSEMBLY */ + +/* Define to 1 to use POSIX 1003.1 pthread_XXX mutexes. */ +/* #undef HAVE_MUTEX_PTHREADS */ + +/* Define to 1 to use Reliant UNIX initspin mutexes. */ +/* #undef HAVE_MUTEX_RELIANTUNIX_INITSPIN */ + +/* Define to 1 to use the IBM C compiler and S/390 assembly language mutexes. + */ +/* #undef HAVE_MUTEX_S390_CC_ASSEMBLY */ + +/* Define to 1 to use the GCC compiler and S/390 assembly language mutexes. */ +/* #undef HAVE_MUTEX_S390_GCC_ASSEMBLY */ + +/* Define to 1 to use the SCO compiler and x86 assembly language mutexes. */ +/* #undef HAVE_MUTEX_SCO_X86_CC_ASSEMBLY */ + +/* Define to 1 to use the obsolete POSIX 1003.1 sema_XXX mutexes. */ +/* #undef HAVE_MUTEX_SEMA_INIT */ + +/* Define to 1 to use the SGI XXX_lock mutexes. */ +/* #undef HAVE_MUTEX_SGI_INIT_LOCK */ + +/* Define to 1 to use the Solaris _lock_XXX mutexes. */ +/* #undef HAVE_MUTEX_SOLARIS_LOCK_TRY */ + +/* Define to 1 to use the Solaris lwp threads mutexes. */ +/* #undef HAVE_MUTEX_SOLARIS_LWP */ + +/* Define to 1 to use the GCC compiler and Sparc assembly language mutexes. */ +/* #undef HAVE_MUTEX_SPARC_GCC_ASSEMBLY */ + +/* Define to 1 if the Berkeley DB library should support mutexes. */ +#define HAVE_MUTEX_SUPPORT 1 + +/* Define to 1 if mutexes hold system resources. */ +#define HAVE_MUTEX_SYSTEM_RESOURCES 1 + +/* Define to 1 to configure mutexes intra-process only. */ +/* #undef HAVE_MUTEX_THREAD_ONLY */ + +/* Define to 1 to use the CC compiler and Tru64 assembly language mutexes. */ +/* #undef HAVE_MUTEX_TRU64_CC_ASSEMBLY */ + +/* Define to 1 to use the UNIX International mutexes. */ +/* #undef HAVE_MUTEX_UI_THREADS */ + +/* Define to 1 to use the UTS compiler and assembly language mutexes. */ +/* #undef HAVE_MUTEX_UTS_CC_ASSEMBLY */ + +/* Define to 1 to use VMS mutexes. */ +/* #undef HAVE_MUTEX_VMS */ + +/* Define to 1 to use VxWorks mutexes. */ +#define HAVE_MUTEX_VXWORKS 1 + +/* Define to 1 to use the MSVC compiler and Windows mutexes. */ +/* #undef HAVE_MUTEX_WIN32 */ + +/* Define to 1 to use the GCC compiler and Windows mutexes. */ +/* #undef HAVE_MUTEX_WIN32_GCC */ + +/* Define to 1 to use the GCC compiler and 64-bit x86 assembly language + mutexes. */ +/* #undef HAVE_MUTEX_X86_64_GCC_ASSEMBLY */ + +/* Define to 1 to use the GCC compiler and 32-bit x86 assembly language + mutexes. */ +/* #undef HAVE_MUTEX_X86_GCC_ASSEMBLY */ + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the O_DIRECT flag. */ +/* #undef HAVE_O_DIRECT */ + +/* Define to 1 if building partitioned database support. */ +/* #undef HAVE_PARTITION */ + +/* Define to 1 if you have the `pread' function. */ +/* #undef HAVE_PREAD */ + +/* Define to 1 if you have the `printf' function. */ +#define HAVE_PRINTF 1 + +/* Define to 1 if you have the `pstat_getdynamic' function. */ +/* #undef HAVE_PSTAT_GETDYNAMIC */ + +/* Define to 1 if you have the `pthread_self' function. */ +/* #undef HAVE_PTHREAD_SELF */ + +/* Define to 1 if you have the `pthread_yield' function. */ +/* #undef HAVE_PTHREAD_YIELD */ + +/* Define to 1 if you have the `pwrite' function. */ +/* #undef HAVE_PWRITE */ + +/* Define to 1 if building on QNX. */ +/* #undef HAVE_QNX */ + +/* Define to 1 if you have the `qsort' function. */ +#define HAVE_QSORT 1 + +/* Define to 1 if building Queue access method. */ +#define HAVE_QUEUE 1 + +/* Define to 1 if you have the `raise' function. */ +#define HAVE_RAISE 1 + +/* Define to 1 if you have the `rand' function. */ +#define HAVE_RAND 1 + +/* Define to 1 if you have the `random' function. */ +/* #undef HAVE_RANDOM */ + +/* Define to 1 if building replication support. */ +#define HAVE_REPLICATION 1 + +/* Define to 1 if building the Berkeley DB replication framework. */ +/* #undef HAVE_REPLICATION_THREADS */ + +/* Define to 1 if building RPC client/server. */ +/* #undef HAVE_RPC */ + +/* Define to 1 if building on S60. */ +/* #undef HAVE_S60 */ + +/* Define to 1 if you have the `sched_yield' function. */ +#define HAVE_SCHED_YIELD 1 + +/* Define to 1 if you have the `select' function. */ +#define HAVE_SELECT 1 + +/* Define to 1 if you have the `setgid' function. */ +#define HAVE_SETGID 1 + +/* Define to 1 if you have the `setuid' function. */ +#define HAVE_SETUID 1 + +/* Define to 1 to configure Berkeley DB to use shared, read/write latches. */ +#define HAVE_SHARED_LATCHES 1 + +/* Define to 1 if shmctl/SHM_LOCK locks down shared memory segments. */ +/* #undef HAVE_SHMCTL_SHM_LOCK */ + +/* Define to 1 if you have the `shmget' function. */ +/* #undef HAVE_SHMGET */ + +/* Define to 1 if you have the `sigaction' function. */ +/* #undef HAVE_SIGACTION */ + +/* Define to 1 if thread identifier type db_threadid_t is integral. */ +#define HAVE_SIMPLE_THREAD_TYPE 1 + +/* Define to 1 if you have the `snprintf' function. */ +/* #undef HAVE_SNPRINTF */ + +/* Define to 1 if you have the `stat' function. */ +#define HAVE_STAT 1 + +/* Define to 1 if building statistics support. */ +#define HAVE_STATISTICS 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDINT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strcasecmp' function. */ +/* #undef HAVE_STRCASECMP */ + +/* Define to 1 if you have the `strcat' function. */ +#define HAVE_STRCAT 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the `strdup' function. */ +/* #undef HAVE_STRDUP */ + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the `strftime' function. */ +#define HAVE_STRFTIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strncat' function. */ +#define HAVE_STRNCAT 1 + +/* Define to 1 if you have the `strncmp' function. */ +#define HAVE_STRNCMP 1 + +/* Define to 1 if you have the `strrchr' function. */ +#define HAVE_STRRCHR 1 + +/* Define to 1 if you have the `strsep' function. */ +/* #undef HAVE_STRSEP */ + +/* Define to 1 if you have the `strtol' function. */ +#define HAVE_STRTOL 1 + +/* Define to 1 if you have the `strtoul' function. */ +#define HAVE_STRTOUL 1 + +/* Define to 1 if `st_blksize' is member of `struct stat'. */ +#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 + +/* Define to 1 if you have the `sysconf' function. */ +/* #undef HAVE_SYSCONF */ + +/* Define to 1 if port includes files in the Berkeley DB source code. */ +#define HAVE_SYSTEM_INCLUDE_FILES 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SELECT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SOCKET_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_STAT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TIME_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TYPES_H */ + +/* Define to 1 if you have the `time' function. */ +#define HAVE_TIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if unlink of file with open file descriptors will fail. */ +#define HAVE_UNLINK_WITH_OPEN_FAILURE 1 + +/* Define to 1 if port includes historic database upgrade support. */ +#define HAVE_UPGRADE_SUPPORT 1 + +/* Define to 1 if building access method verification support. */ +#define HAVE_VERIFY 1 + +/* Define to 1 if you have the `vsnprintf' function. */ +/* #undef HAVE_VSNPRINTF */ + +/* Define to 1 if building VxWorks. */ +#define HAVE_VXWORKS 1 + +/* Define to 1 if you have the `yield' function. */ +/* #undef HAVE_YIELD */ + +/* Define to 1 if you have the `_fstati64' function. */ +/* #undef HAVE__FSTATI64 */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. */ +/* #undef LT_OBJDIR */ + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "Oracle Technology Network Berkeley DB forum" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "Berkeley DB" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "Berkeley DB __EDIT_DB_VERSION__" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "db-__EDIT_DB_VERSION__" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "__EDIT_DB_VERSION__" + +/* The size of a `char', as computed by sizeof. */ +/* #undef SIZEOF_CHAR */ + +/* The size of a `char *', as computed by sizeof. */ +/* #undef SIZEOF_CHAR_P */ + +/* The size of a `int', as computed by sizeof. */ +/* #undef SIZEOF_INT */ + +/* The size of a `long', as computed by sizeof. */ +/* #undef SIZEOF_LONG */ + +/* The size of a `long long', as computed by sizeof. */ +/* #undef SIZEOF_LONG_LONG */ + +/* The size of a `short', as computed by sizeof. */ +/* #undef SIZEOF_SHORT */ + +/* The size of a `size_t', as computed by sizeof. */ +/* #undef SIZEOF_SIZE_T */ + +/* The size of a `unsigned char', as computed by sizeof. */ +/* #undef SIZEOF_UNSIGNED_CHAR */ + +/* The size of a `unsigned int', as computed by sizeof. */ +/* #undef SIZEOF_UNSIGNED_INT */ + +/* The size of a `unsigned long', as computed by sizeof. */ +/* #undef SIZEOF_UNSIGNED_LONG */ + +/* The size of a `unsigned long long', as computed by sizeof. */ +/* #undef SIZEOF_UNSIGNED_LONG_LONG */ + +/* The size of a `unsigned short', as computed by sizeof. */ +/* #undef SIZEOF_UNSIGNED_SHORT */ + +/* Define to 1 if the `S_IS*' macros in do not work properly. */ +/* #undef STAT_MACROS_BROKEN */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +/* #undef TIME_WITH_SYS_TIME */ + +/* Define to 1 to mask harmless uninitialized memory read/writes. */ +/* #undef UMRW */ + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#define inline +#endif + +/* type to use in place of socklen_t if not defined */ +/* #undef socklen_t */ diff --git a/src/libs/resiprocate/contrib/db/dist/vx_setup/CONFIG.in b/src/libs/resiprocate/contrib/db/dist/vx_setup/CONFIG.in new file mode 100644 index 00000000..1fccd1d2 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/vx_setup/CONFIG.in @@ -0,0 +1,10 @@ +# +# Install configuration file. +# +# Note: This file may be modified during the pool manufacturing process to +# add additional configuration statements. This file is sourced by +# INSTW32.TCL. +# + +cdromDescSet "Berkeley DB @DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@" + diff --git a/src/libs/resiprocate/contrib/db/dist/vx_setup/LICENSE.TXT b/src/libs/resiprocate/contrib/db/dist/vx_setup/LICENSE.TXT new file mode 100644 index 00000000..6fce1362 --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/vx_setup/LICENSE.TXT @@ -0,0 +1,2 @@ +Copyright (c) 1996-2009 Oracle. All rights reserved. +See the file LICENSE for redistribution information. diff --git a/src/libs/resiprocate/contrib/db/dist/vx_setup/MESSAGES.TCL b/src/libs/resiprocate/contrib/db/dist/vx_setup/MESSAGES.TCL new file mode 100644 index 00000000..718a67fb --- /dev/null +++ b/src/libs/resiprocate/contrib/db/dist/vx_setup/MESSAGES.TCL @@ -0,0 +1,651 @@ +# MESSAGES.TCL - All setup strings. + +# modification history +# -------------------- +# 03q,20apr99,bjl added release notes message for backward compatibility +# page. +# 03p,12apr99,wmd Add word about simulator in message about the drivers +# object product. +# 03o,03mar99,tcy Adjust setup directory size based on platform (fix for +# SPR 25228) +# 03n,24feb99,tcy modified DLL update messages +# 03m,22feb99,tcy modified to align messages +# 03l,17feb99,tcy modified message in the finish page for program group +# installation +# 03k,11feb99,tcy added messages for backward compatibility page +# 03j,25jan99,tcy added messages from INSTW32.TCL +# 03i,25jan99,wmd Reword the message for 5010_DRIVERS_INFO. +# 03h,09dec98,bjl added messages about manufacturers updating patches. +# 03g,01dec98,wmd Fix typos. +# 03f,23nov98,tcy warn user to disable virus protection on Welcome screen +# 03e,19nov98,wmd fixed minor nits in wording. +# 03d,19nov98,bjl added web site locations for patchinfo. +# 03c,18nov98,bjl added formatted patch messages for patchinfo file. +# 03b,12nov98,tcy added message for not saving installation key +# 03a,10nov98,tcy added warning message for space in destination directory +# removed message for checking temporary disk space +# 02z,27oct98,bjl added recommended patch messages, modified required msg. +# 02y,26oct98,tcy added message for checking temporary disk space +# 02x,22oct98,wmd fix messages for clarity. +# 02w,21oct98,wmd fix message for drv/obj. +# 02v,20oct98,tcy added message for updating system and changed dcom message +# 02u,20oct98,bjl added tornado registry name entry message. +# 02t,19oct98,bjl added tornado registry description message. +# 02s,16oct98,wmd add new message for driver product warning. +# 02r,16oct98,wmd fixed README.TXT description. +# 02q,12oct98,tcy removed extraneous "the" from messages +# 02p,06oct98,tcy added CD description to Welcome page +# 02o,29sep98,bjl added required patches message 5000_PATCHES_TEXT. +# 02n,29sep98,wmd add text for readme page +# 02m,29sep98,tcy refined DLL registration page text +# 02l,29sep98,tcy changed message for DCOM +# 02k,26sep98,tcy added messages for DLL and DCOM pages +# 02j,24sep98,tcy removed "following" from 1080_WARN_4 message. +# 02i,17sep98,tcy added comment on size of SETUP files to 1140_COMP_SELECT. +# 02h,17sep98,wmd reword message 1080_WARN_4. +# 02g,14sep98,tcy changed 1210_FINISH and 1550_USAGE messages +# 02f,08sep98,tcy warn user library update may take several minutes +# 02e,01sep98,wmd reword message for installing over tree. +# added new messages for license agreement pages. +# 02d,20aug98,wmd added message for license agreeement. +# 02c,18aug98,tcy added message for zip-file dialog box +# 02d,04aug98,wmd added newer/older duplicate file warnings. +# 02c,24jul98,tcy added system check messages +# 02b,16jul98,wmd add new messages for T-2. +# 02a,22jul98,tcy moved license messages to LICW32.TCL; +# removed portMapper messages +# 01n,09feb98,pdn updated string 1080_WARN_4 +# 01m,08apr97,pdn added new string for remote icon installing +# fixed spr#8334 +# 01l,08mar97,tcy fixed language in string id 3340 +# 01k,07mar97,tcy added string id 3340 +# 01j,10feb97,pdn added more license messages. +# 01i,09feb97,pdn implemented variable argument list for strTableGet(), +# clean up. +# 01h,17jan97,jmo fixed language in strings +# 01g,12dec96,tcy merged in TEXT-only strings +# 01f,12dec96,pdn added 1080_WARN_4 string warning that CD-ROM +# revision is older than expected. +# 01e,27nov96,sj added string for warning against installing in +# the root of windows drive. +# 01d,18nov96,tcy added strings for text-based installation script +# 01c,14nov96,pdn substituted function for some global variables +# 01b,14nov96,sj added strings from Windows installation script +# 01a,11nov96,pdn written + +proc strTableGet {strId args} { + global strTable + global setupVals + global current_file + + if [regexp {^format.*$} $strTable($strId) junk] { + return [eval $strTable($strId)] + } { + return $strTable($strId) + } +} + +set strTable(1000_WELCOME_CD) \ + "format %s \"[cdNameGet description]\"" + +set strTable(1000_WELCOME1) \ + "format %s \"Welcome to the SETUP program. This program will\ + install \[cdromDescGet\] on your computer.\"" + +set strTable(1010_WELCOME2) \ + "It is strongly recommended that you exit all programs and disable virus\ + protection before running this SETUP program." + +set strTable(1020_WELCOME3) \ + "At any time, you can quit the SETUP program by clicking the \ + button. You also can go back to previous dialog boxes by clicking the\ + button. To accept the current settings for a dialog box and go on\ + with the installation process, click the button." + +set strTable(3020_WELCOME3) \ + "format %s \"At any prompt, you can cancel installation \[cdromDescGet\]\ + by typing \'exit\'. You can also go to the previous question\ + by typing \'-\'. To accept current settings and go on with\ + the installation process, press .\"" + +set strTable(1030_WELCOME4) \ + "WARNING: This program is protected by copyright law and international\ + treaties." + +set strTable(1040_WELCOME5) \ + "Unauthorized reproduction or distribution of this program, or any portion\ + of it, may result in severe civil and criminal penalties, and will be\ + prosecuted to the maximum extent possible under law." + +set strTable(1050_ROOT_WARN) \ + "format %s \"Installing \[cdromDescGet\] as \[setupId effective user\] is not\ + recommended. We suggest that you logoff and logon as a normal\ + user before running this program.\ + \n\nClick Next to continue with SETUP anyway.\"" + +set strTable(3050_ROOT_WARN) \ + "format %s \"Installing \[cdromDescGet\] as \[setupId effective user\]\ + is not recommended. We suggest that you logoff and \ + logon as a normal user before running this program.\ + \n\nPress to continue with SETUP anyway.\"" + +set strTable(1051_ROOT_WARN) \ + "format %s \"Installing \[cdromDescGet\] without System Administrator\ + privileges is not recommended. Under your present privileges,\ + SETUP will not offer certain installation options, such as \ + the installation of some services, etc. Also, the software\ + will be installed as a personal copy and will not be visible\ + to other users on this machine.\ + \n\nTo install \[cdromDescGet\] with access to all its\ + installation features and options, we suggest that you exit\ + the installation now and rerun it later with System\ + Administrator\'s privileges.\n\nClick to continue with\ + SETUP anyway.\"" + +set strTable(1060_REGISTRATION) \ + "Below, type your name, the name of your company." + +set strTable(1070_WARN_1) \ + "The installation key you entered is invalid. Please enter a valid\ + installation key." + +set strTable(1071_WARN_1) \ + "Please enter the requested information." + +set strTable(1080_WARN_2) \ + "You entered a key that was not created for this CD-ROM. Please verify\ + that you are using the appropriate key. If this problem persists, contact\ + Wind River Systems Sales department for help." + +set strTable(1080_WARN_3) \ + "The installation key you entered is meant for other vendor's CD-ROM.\ + Please contact the vendor who issued the CD-ROM for a proper key." + +set strTable(1085_WARN_4) \ + "This CD-ROM does not require an installation key. Click the \"Next\"\ + button to continue the installation." + +set strTable(1090_WARN_3) \ + "format %s \"Can\'t initiate SETUP: \[lindex \$args 0\]. Please correct\ + the problem then run SETUP again.\"" + +set strTable(1095_WARN_NO_TCPIP) \ + "SETUP has detected that your system does not have TCP-IP installed.\ + To correct the problem, please contact your administrator and then\ + run SETUP again.\nAborting setup." + +set strTable(1097_WARN_NO_LONGFILENAME_SUP) \ + "SETUP has detected that your system does not have long filename\ + support. To correct the problem, please contact your administrator\ + and then run SETUP again.\nAborting setup." + +set strTable(1105_FULL_INSTALL) \ + "Installs the Tornado products, tools, compilers, and other optional\ + components that you may have purchased." + +set strTable(1107_PROGRAM_GROUP) \ +"Installs only the Tornado program group and tools icons for access to\ + Tornado tools installed on a remote server." + +set strTable(1100_DEST_DIR) \ + "format %s \"Please type the name of the directory where you want SETUP to\ + install \[cdromDescGet\].\ + \n\nClick the button to choose the directory\ + interactively.\"" + +set strTable(1100_REMOTE_DIR) \ + "format %s \"Please type the name of the directory where Tornado has\ + already been installed.\ + \n\nClick the button to choose the directory\ + interactively.\"" + +set strTable(3100_DEST_DIR) \ + "format %s \"Please type the name of the directory where you want SETUP\ + to install \[cdromDescGet\].\"" + +set strTable(1110_DEST_DIR_WARN) \ + "The installation directory you entered does not exist.\ + \nDo you want to create it now?" + +set strTable(3110_DEST_DIR_WARN) \ + "The installation directory you entered does not exist." + +set strTable(3115_DEST_DIR_QUESTION) \ + "Do you want to create it now? \[y\]" + +set strTable(1111_DEST_DIR_WARN) \ + "format %s \"Installing \[cdromDescGet\] in the root directory is not\ + recommended.\nClick to select another directory.\"" + +set strTable(1120_DEST_DIR_WARN2) \ + "format %s \"Creating \[destDirGet\] failed: file exists.\"" + +set strTable(1121_DEST_DIR_WARN2) \ + "format %s \"Installing in \[destDirGet\] is not recommended.\ + \nDo you want to change the installation directory?\"" + +set strTable(1122_DEST_DIR_WARN2) \ + "format %s \"Unable to create \[destDirGet\].\"" + +set strTable(1130_DEST_DIR_WARN3) \ + "You do not have permission to write files into the installation directory\ + you entered.\ + \n\nPlease choose a writable directory." + +set strTable(1135_DEST_DIR_WARN4) \ + "format %s \"The installation directory you entered contains white\ + space(s). Please select another directory.\"" + +set strTable(1137_DUP_PRODUCT_WARN) \ + "format %s \"Reinstalling products may potentially destroy any\ + modifications you may have made to previously installed files.\ + Do you wish to continue with the installation or go back to the\ + '\[strTableGet 1450_TITLE_OPTION\]' page to reconsider your choices?\"" + +set strTable(3155_COMP_SELECT_QUESTION) \ + "Do you want to go back and specify a directory on a bigger partition?\ + \[y\]" + +set strTable(1140_COMP_SELECT) \ + "format %s \"In the option list below, please check all items you wish\ + to install. SETUP files will be copied to your selected directory and\ + take up \[setupSizeGet\] MB of disk space.\n\"" + +set strTable(3140_COMP_SELECT) \ + "In the option list below, select the item(s) you want to install." + +set strTable(3145_COMP_SELECT_CHANGE) \ + "Press to accept the setting. To change the setting, enter a\ + list of item numbers separated by spaces." + +set strTable(3145_COMP_SELECT_CHANGE_INVALID) \ + "The item number(s) you entered is not valid." + +set strTable(1150_COMP_SELECT_WARN) \ + "There is not enough disk space to install the selected component(s).\ + \n\nDo you want to go back and specify a directory on a bigger disk or\ + partition?" + +set strTable(3150_COMP_SELECT_WARN) \ + "There is not enough space to install the selected component(s)." + +set strTable(1151_COMP_SELECT_WARN) \ + "At least one component must be selected to continue installation." + +set strTable(1160_PERMISSION) \ + "SETUP is about to install the component(s) you have requested.\ + \n\nThe selected button(s) below indicate the file permissions which\ + will be set during the installation process.\ + \n\nPlease adjust these to suit your site requirements." + +set strTable(3160_PERMISSION) \ + "SETUP is about to install the component(s) you have requested." + +set strTable(3162_PERMISSION) \ + "The list below indicates the file permissions which will be set during\ + the installation process. Please adjust these to suit your site\ + requirements." + +set strTable(3165_PERMISSION_QUESTION) \ + "Press to accept the setting. To change the setting, enter a\ + list of item numbers separated by spaces." + +set strTable(1161_FOLDER_SELECT) \ + "SETUP will add program icons to the Program Folder listed below. You may\ + type a new folder name, or select one from the existing Folders list." + +set strTable(1162_FOLDER_SELECT) \ + "Please enter a valid folder name." + +set strTable(1170_FILE_COPY) \ + "format %s \"SETUP is copying the selected component(s) to the directory\ + \[destDirGet\].\"" + +set strTable(1171_FILE_COPY) \ + "format %s \"SETUP cannot read \[setupFileNameGet 0\] from the CD-ROM.\ + Please ensure that the CD-ROM is properly mounted.\"" + +set strTable(1180_LIB_UPDATE) \ + "SETUP is updating the VxWorks libraries. We recommend that you let\ + SETUP finish this step, or the libraries will be in an inconsistent\ + state. Please be patient as the process may take several minutes. \ + If you want to quit the SETUP program, click and run\ + the SETUP program again at a later time." + +set strTable(3180_LIB_UPDATE) \ + "SETUP is updating the VxWorks libraries." + +set strTable(1190_REGISTRY_HOST) \ + "The Tornado Registry is a daemon that keeps track of all available\ + targets by name. Only one registry is required on your network, \ + and it can run on any networked host.\ + \n\nPlease enter the name of the host where the Tornado Registry will\ + be running." + +set strTable(1191_REGISTRY_DESC) \ + "The Tornado Registry is a daemon that keeps track of all available\ + targets by name. Only one registry is required on your network, \ + and it can run on any networked host." + +set strTable(1192_REGISTRY_NAME) \ + "Please enter the name of the host where the Tornado Registry will\ + be running." + +set strTable(1200_FINISH_WARN) \ + "format %s \"However, there were \[errorCountGet\] error(s) which occured\ + during the process. Please review the log file\ + \[destDirDispGet\]/setup.log for more information.\"" + +set strTable(1210_FINISH) \ + "format %s \"SETUP has completed installing the selected product(s).\"" + +set strTable(1212_FINISH) \ + "SETUP has completed installing the program folders and icons." + +set strTable(1213_FINISH) \ + "Terminating SETUP program." + +set strTable(1360_QUIT_CALLBACK) \ + "format %s \"SETUP is not complete. If you quit the SETUP program now,\ + \[cdromDescGet\] will not be installed.\n\nYou may run\ + the SETUP program at a later time to complete the\ + installation.\ + \n\nTo continue installing the program, click . \ + To quit the SETUP program, click .\"" + +set strTable(3360_QUIT_CALLBACK) \ + "format %s \"SETUP is not complete. If you quit the SETUP program now,\ + \[cdromDescGet\] will not be installed.\n\nYou may run the\ + SETUP program at a later time to complete the installation.\ + \n\nTo continue installing the program, Press . \ + To quit the SETUP program, type \'exit\'.\"" + +set strTable(1370_FILE_ACCESS_ERROR) \ + "format %s \"SETUP cannot create/update file \[lindex \$args 0\]:\ + \[lindex \$args 1\]\"" + +set strTable(1380_DEFLATE_ERROR) \ + "format %s \"SETUP isn\'t able to deflate \[setupFileNameGet 0\]\ + \n\nPlease select one of the following options\ + to continue with the SETUP process.\"" + +set strTable(1390_MEMORY_LOW) \ + "The system is running out of memory. To continue, close applications\ + or increase the system swap space." + +set strTable(1400_DISK_FULL) \ + "No disk space left. To continue, free up some disk space." + +set strTable(1550_USAGE) \ + "Usage: SETUP /I\[con\]\]\t\n\ + /I : Add standard Tornado icons \n\ + from a remote installation" + +set strTable(1410_TITLE_WELCOME) "Welcome" +set strTable(1420_TITLE_WARNING) "Warning" +set strTable(1430_TITLE_REGISTRATION) "User Registration" +set strTable(1440_TITLE_DESTDIR) "Select Directory" +set strTable(1450_TITLE_OPTION) "Select Products" +set strTable(1460_TITLE_PERMISSION) "Permission" +set strTable(1470_TITLE_FILECOPY) "Copying Files" +set strTable(1480_TITLE_LIBUPDATE) "Update Libraries" +set strTable(1490_TITLE_REGISTRY_HOST) "Tornado Registry" +set strTable(1495_TITLE_BACKWARD_COMPATIBILITY) "Backward Compatibility" +set strTable(1500_TITLE_FINISH) "Finish" +set strTable(1560_TITLE_FOLDER) "Select Folder" +set strTable(1563_TITLE_DLL_REG) "Software Registration" +set strTable(1567_TITLE_DCOM) "DCOM Installation" + +set strTable(1570_OPTION_SELECT) \ + "Choose one of the options listed below, then click the\ + button to continue the installation." + +set strTable(1576_OPTION_MANUAL) \ + "Install Tornado Registry manually" + +set strTable(1577_OPTION_STARTUP) \ + "Install Tornado Registry locally in the Startup Group" + +set strTable(1578_OPTION_SERVICE) \ + "Install Tornado Registry locally as a Service" + +set strTable(1579_OPTION_REMOTE) \ + "Configure to use a remote Tornado Registry" + +set strTable(1580_OPTION_DESC) \ + "If you plan on running Tornado in a non-networked environment, we\ + recommend that you install the registry in your Startup Group or as an\ + NT Service. For more information, consult your Tornado User\'s Guide." + +set strTable(1581_OPTION_DESC) \ + "If you plan on running Tornado in a non-networked environment, we\ + recommend that you install the registry in your Startup Group. For more\ + information, consult your Tornado User\'s Guide." + +set strTable(3000_RETURN_QUESTION) \ + "Press to continue" + +set strTable(3055_EXIT_QUESTION) \ + "Type \'exit\' to quit the program or press to continue" + +set strTable(3370_BACK_CALLBACK) \ + "Cannot go back further." + +set strTable(1080_WARN_4) \ + "The installation key you entered attempted to unlock one or more \ + products that may have been removed from our product line. \ + Please compare the unlocked product list on the\ + \"[strTableGet 1450_TITLE_OPTION]\" screen with your purchased order\ + list, and contact us if you discover any differences." + +set strTable(4000_BASE_INSTALL_WARN) \ + "format %s \"Warning! Re-installing Tornado over an existing \ + tree will overwrite any installed patches. \ + If you proceed with the installation, please \ + re-install patches if any.\"" + +set strTable(4000_BASE_INSTALL_WARN_1) \ + "Select to overwrite existing Tornado installation,\ + or choose []]\n"); + printf(" -C show PCRE compile-time options and exit\n"); + printf(" -d debug: show compiled code; implies -i\n" + " -i show information about compiled pattern\n" + " -m output memory used information\n" + " -o set size of offsets vector to \n"); +#if !defined NOPOSIX + printf(" -p use POSIX interface\n"); +#endif + printf(" -s output store (memory) used information\n" + " -t time compilation and execution\n"); + return 1; + } + op++; + argc--; + } + +/* Get the store for the offsets vector, and remember what it was */ + +size_offsets_max = size_offsets; +offsets = (int *)malloc(size_offsets_max * sizeof(int)); +if (offsets == NULL) + { + printf("** Failed to get %d bytes of memory for offsets vector\n", + size_offsets_max * sizeof(int)); + return 1; + } + +/* Sort out the input and output files */ + +if (argc > 1) + { + infile = fopen(argv[op], "rb"); + if (infile == NULL) + { + printf("** Failed to open %s\n", argv[op]); + return 1; + } + } + +if (argc > 2) + { + outfile = fopen(argv[op+1], "wb"); + if (outfile == NULL) + { + printf("** Failed to open %s\n", argv[op+1]); + return 1; + } + } + +/* Set alternative malloc function */ + +pcre_malloc = new_malloc; +pcre_free = new_free; +pcre_stack_malloc = stack_malloc; +pcre_stack_free = stack_free; + +/* Heading line, then prompt for first regex if stdin */ + +fprintf(outfile, "PCRE version %s\n\n", pcre_version()); + +/* Main loop */ + +while (!done) + { + pcre *re = NULL; + pcre_extra *extra = NULL; + +#if !defined NOPOSIX /* There are still compilers that require no indent */ + regex_t preg; + int do_posix = 0; +#endif + + const char *error; + unsigned char *p, *pp, *ppp; + unsigned char *to_file = NULL; + const unsigned char *tables = NULL; + unsigned long int true_size, true_study_size = 0; + size_t size, regex_gotten_store; + int do_study = 0; + int do_debug = debug; + int do_G = 0; + int do_g = 0; + int do_showinfo = showinfo; + int do_showrest = 0; + int do_flip = 0; + int erroroffset, len, delimiter; + + use_utf8 = 0; + + if (infile == stdin) printf(" re> "); + if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) break; + if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); + fflush(outfile); + + p = buffer; + while (isspace(*p)) p++; + if (*p == 0) continue; + + /* See if the pattern is to be loaded pre-compiled from a file. */ + + if (*p == '<' && strchr((char *)(p+1), '<') == NULL) + { + unsigned long int magic; + uschar sbuf[8]; + FILE *f; + + p++; + pp = p + (int)strlen((char *)p); + while (isspace(pp[-1])) pp--; + *pp = 0; + + f = fopen((char *)p, "rb"); + if (f == NULL) + { + fprintf(outfile, "Failed to open %s: %s\n", p, strerror(errno)); + continue; + } + + if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ; + + true_size = + (sbuf[0] << 24) | (sbuf[1] << 16) | (sbuf[2] << 8) | sbuf[3]; + true_study_size = + (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7]; + + re = (real_pcre *)new_malloc(true_size); + regex_gotten_store = gotten_store; + + if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ; + + magic = ((real_pcre *)re)->magic_number; + if (magic != MAGIC_NUMBER) + { + if (byteflip(magic, sizeof(magic)) == MAGIC_NUMBER) + { + do_flip = 1; + } + else + { + fprintf(outfile, "Data in %s is not a compiled PCRE regex\n", p); + fclose(f); + continue; + } + } + + fprintf(outfile, "Compiled regex%s loaded from %s\n", + do_flip? " (byte-inverted)" : "", p); + + /* Need to know if UTF-8 for printing data strings */ + + new_info(re, NULL, PCRE_INFO_OPTIONS, &options); + use_utf8 = (options & PCRE_UTF8) != 0; + + /* Now see if there is any following study data */ + + if (true_study_size != 0) + { + pcre_study_data *psd; + + extra = (pcre_extra *)new_malloc(sizeof(pcre_extra) + true_study_size); + extra->flags = PCRE_EXTRA_STUDY_DATA; + + psd = (pcre_study_data *)(((char *)extra) + sizeof(pcre_extra)); + extra->study_data = psd; + + if (fread(psd, 1, true_study_size, f) != true_study_size) + { + FAIL_READ: + fprintf(outfile, "Failed to read data from %s\n", p); + if (extra != NULL) new_free(extra); + if (re != NULL) new_free(re); + fclose(f); + continue; + } + fprintf(outfile, "Study data loaded from %s\n", p); + do_study = 1; /* To get the data output if requested */ + } + else fprintf(outfile, "No study data\n"); + + fclose(f); + goto SHOW_INFO; + } + + /* In-line pattern (the usual case). Get the delimiter and seek the end of + the pattern; if is isn't complete, read more. */ + + delimiter = *p++; + + if (isalnum(delimiter) || delimiter == '\\') + { + fprintf(outfile, "** Delimiter must not be alphameric or \\\n"); + goto SKIP_DATA; + } + + pp = p; + + for(;;) + { + while (*pp != 0) + { + if (*pp == '\\' && pp[1] != 0) pp++; + else if (*pp == delimiter) break; + pp++; + } + if (*pp != 0) break; + + len = BUFFER_SIZE - (pp - buffer); + if (len < 256) + { + fprintf(outfile, "** Expression too long - missing delimiter?\n"); + goto SKIP_DATA; + } + + if (infile == stdin) printf(" > "); + if (fgets((char *)pp, len, infile) == NULL) + { + fprintf(outfile, "** Unexpected EOF\n"); + done = 1; + goto CONTINUE; + } + if (infile != stdin) fprintf(outfile, "%s", (char *)pp); + } + + /* If the first character after the delimiter is backslash, make + the pattern end with backslash. This is purely to provide a way + of testing for the error message when a pattern ends with backslash. */ + + if (pp[1] == '\\') *pp++ = '\\'; + + /* Terminate the pattern at the delimiter, and save a copy of the pattern + for callouts. */ + + *pp++ = 0; + strcpy((char *)pbuffer, (char *)p); + + /* Look for options after final delimiter */ + + options = 0; + study_options = 0; + log_store = showstore; /* default from command line */ + + while (*pp != 0) + { + switch (*pp++) + { + case 'g': do_g = 1; break; + case 'i': options |= PCRE_CASELESS; break; + case 'm': options |= PCRE_MULTILINE; break; + case 's': options |= PCRE_DOTALL; break; + case 'x': options |= PCRE_EXTENDED; break; + + case '+': do_showrest = 1; break; + case 'A': options |= PCRE_ANCHORED; break; + case 'C': options |= PCRE_AUTO_CALLOUT; break; + case 'D': do_debug = do_showinfo = 1; break; + case 'E': options |= PCRE_DOLLAR_ENDONLY; break; + case 'F': do_flip = 1; break; + case 'G': do_G = 1; break; + case 'I': do_showinfo = 1; break; + case 'M': log_store = 1; break; + case 'N': options |= PCRE_NO_AUTO_CAPTURE; break; + +#if !defined NOPOSIX + case 'P': do_posix = 1; break; +#endif + + case 'S': do_study = 1; break; + case 'U': options |= PCRE_UNGREEDY; break; + case 'X': options |= PCRE_EXTRA; break; + case '8': options |= PCRE_UTF8; use_utf8 = 1; break; + case '?': options |= PCRE_NO_UTF8_CHECK; break; + + case 'L': + ppp = pp; + while (*ppp != '\n' && *ppp != ' ') ppp++; + *ppp = 0; + if (setlocale(LC_CTYPE, (const char *)pp) == NULL) + { + fprintf(outfile, "** Failed to set locale \"%s\"\n", pp); + goto SKIP_DATA; + } + tables = pcre_maketables(); + pp = ppp; + break; + + case '>': + to_file = pp; + while (*pp != 0) pp++; + while (isspace(pp[-1])) pp--; + *pp = 0; + break; + + case '\n': case ' ': break; + + default: + fprintf(outfile, "** Unknown option '%c'\n", pp[-1]); + goto SKIP_DATA; + } + } + + /* Handle compiling via the POSIX interface, which doesn't support the + timing, showing, or debugging options, nor the ability to pass over + local character tables. */ + +#if !defined NOPOSIX + if (posix || do_posix) + { + int rc; + int cflags = 0; + + if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE; + if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE; + rc = regcomp(&preg, (char *)p, cflags); + + /* Compilation failed; go back for another re, skipping to blank line + if non-interactive. */ + + if (rc != 0) + { + (void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE); + fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer); + goto SKIP_DATA; + } + } + + /* Handle compiling via the native interface */ + + else +#endif /* !defined NOPOSIX */ + + { + if (timeit) + { + register int i; + clock_t time_taken; + clock_t start_time = clock(); + for (i = 0; i < LOOPREPEAT; i++) + { + re = pcre_compile((char *)p, options, &error, &erroroffset, tables); + if (re != NULL) free(re); + } + time_taken = clock() - start_time; + fprintf(outfile, "Compile time %.3f milliseconds\n", + (((double)time_taken * 1000.0) / (double)LOOPREPEAT) / + (double)CLOCKS_PER_SEC); + } + + re = pcre_compile((char *)p, options, &error, &erroroffset, tables); + + /* Compilation failed; go back for another re, skipping to blank line + if non-interactive. */ + + if (re == NULL) + { + fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset); + SKIP_DATA: + if (infile != stdin) + { + for (;;) + { + if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) + { + done = 1; + goto CONTINUE; + } + len = (int)strlen((char *)buffer); + while (len > 0 && isspace(buffer[len-1])) len--; + if (len == 0) break; + } + fprintf(outfile, "\n"); + } + goto CONTINUE; + } + + /* Compilation succeeded; print data if required. There are now two + info-returning functions. The old one has a limited interface and + returns only limited data. Check that it agrees with the newer one. */ + + if (log_store) + fprintf(outfile, "Memory allocation (code space): %d\n", + (int)(gotten_store - + sizeof(real_pcre) - + ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size)); + + /* Extract the size for possible writing before possibly flipping it, + and remember the store that was got. */ + + true_size = ((real_pcre *)re)->size; + regex_gotten_store = gotten_store; + + /* If /S was present, study the regexp to generate additional info to + help with the matching. */ + + if (do_study) + { + if (timeit) + { + register int i; + clock_t time_taken; + clock_t start_time = clock(); + for (i = 0; i < LOOPREPEAT; i++) + extra = pcre_study(re, study_options, &error); + time_taken = clock() - start_time; + if (extra != NULL) free(extra); + fprintf(outfile, " Study time %.3f milliseconds\n", + (((double)time_taken * 1000.0) / (double)LOOPREPEAT) / + (double)CLOCKS_PER_SEC); + } + extra = pcre_study(re, study_options, &error); + if (error != NULL) + fprintf(outfile, "Failed to study: %s\n", error); + else if (extra != NULL) + true_study_size = ((pcre_study_data *)(extra->study_data))->size; + } + + /* If the 'F' option was present, we flip the bytes of all the integer + fields in the regex data block and the study block. This is to make it + possible to test PCRE's handling of byte-flipped patterns, e.g. those + compiled on a different architecture. */ + + if (do_flip) + { + real_pcre *rre = (real_pcre *)re; + rre->magic_number = byteflip(rre->magic_number, sizeof(rre->magic_number)); + rre->size = byteflip(rre->size, sizeof(rre->size)); + rre->options = byteflip(rre->options, sizeof(rre->options)); + rre->top_bracket = byteflip(rre->top_bracket, sizeof(rre->top_bracket)); + rre->top_backref = byteflip(rre->top_backref, sizeof(rre->top_backref)); + rre->first_byte = byteflip(rre->first_byte, sizeof(rre->first_byte)); + rre->req_byte = byteflip(rre->req_byte, sizeof(rre->req_byte)); + rre->name_table_offset = byteflip(rre->name_table_offset, + sizeof(rre->name_table_offset)); + rre->name_entry_size = byteflip(rre->name_entry_size, + sizeof(rre->name_entry_size)); + rre->name_count = byteflip(rre->name_count, sizeof(rre->name_count)); + + if (extra != NULL) + { + pcre_study_data *rsd = (pcre_study_data *)(extra->study_data); + rsd->size = byteflip(rsd->size, sizeof(rsd->size)); + rsd->options = byteflip(rsd->options, sizeof(rsd->options)); + } + } + + /* Extract information from the compiled data if required */ + + SHOW_INFO: + + if (do_showinfo) + { + unsigned long int get_options, all_options; + int old_first_char, old_options, old_count; + int count, backrefmax, first_char, need_char; + int nameentrysize, namecount; + const uschar *nametable; + + if (do_debug) + { + fprintf(outfile, "------------------------------------------------------------------\n"); + print_internals(re, outfile); + } + + new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options); + new_info(re, NULL, PCRE_INFO_SIZE, &size); + new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count); + new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax); + new_info(re, NULL, PCRE_INFO_FIRSTBYTE, &first_char); + new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char); + new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); + new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount); + new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable); + + old_count = pcre_info(re, &old_options, &old_first_char); + if (count < 0) fprintf(outfile, + "Error %d from pcre_info()\n", count); + else + { + if (old_count != count) fprintf(outfile, + "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count, + old_count); + + if (old_first_char != first_char) fprintf(outfile, + "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n", + first_char, old_first_char); + + if (old_options != (int)get_options) fprintf(outfile, + "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n", + get_options, old_options); + } + + if (size != regex_gotten_store) fprintf(outfile, + "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n", + size, regex_gotten_store); + + fprintf(outfile, "Capturing subpattern count = %d\n", count); + if (backrefmax > 0) + fprintf(outfile, "Max back reference = %d\n", backrefmax); + + if (namecount > 0) + { + fprintf(outfile, "Named capturing subpatterns:\n"); + while (namecount-- > 0) + { + fprintf(outfile, " %s %*s%3d\n", nametable + 2, + nameentrysize - 3 - (int)strlen((char *)nametable + 2), "", + GET2(nametable, 0)); + nametable += nameentrysize; + } + } + + /* The NOPARTIAL bit is a private bit in the options, so we have + to fish it out via out back door */ + + all_options = ((real_pcre *)re)->options; + if (do_flip) + { + all_options = byteflip(all_options, sizeof(all_options)); + } + + if ((all_options & PCRE_NOPARTIAL) != 0) + fprintf(outfile, "Partial matching not supported\n"); + + if (get_options == 0) fprintf(outfile, "No options\n"); + else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s\n", + ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "", + ((get_options & PCRE_CASELESS) != 0)? " caseless" : "", + ((get_options & PCRE_EXTENDED) != 0)? " extended" : "", + ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "", + ((get_options & PCRE_DOTALL) != 0)? " dotall" : "", + ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "", + ((get_options & PCRE_EXTRA) != 0)? " extra" : "", + ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "", + ((get_options & PCRE_UTF8) != 0)? " utf8" : "", + ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : ""); + + if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0) + fprintf(outfile, "Case state changes\n"); + + if (first_char == -1) + { + fprintf(outfile, "First char at start or follows \\n\n"); + } + else if (first_char < 0) + { + fprintf(outfile, "No first char\n"); + } + else + { + int ch = first_char & 255; + const char *caseless = ((first_char & REQ_CASELESS) == 0)? + "" : " (caseless)"; + if (isprint(ch)) + fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless); + else + fprintf(outfile, "First char = %d%s\n", ch, caseless); + } + + if (need_char < 0) + { + fprintf(outfile, "No need char\n"); + } + else + { + int ch = need_char & 255; + const char *caseless = ((need_char & REQ_CASELESS) == 0)? + "" : " (caseless)"; + if (isprint(ch)) + fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless); + else + fprintf(outfile, "Need char = %d%s\n", ch, caseless); + } + + /* Don't output study size; at present it is in any case a fixed + value, but it varies, depending on the computer architecture, and + so messes up the test suite. (And with the /F option, it might be + flipped.) */ + + if (do_study) + { + if (extra == NULL) + fprintf(outfile, "Study returned NULL\n"); + else + { + uschar *start_bits = NULL; + new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits); + + if (start_bits == NULL) + fprintf(outfile, "No starting byte set\n"); + else + { + int i; + int c = 24; + fprintf(outfile, "Starting byte set: "); + for (i = 0; i < 256; i++) + { + if ((start_bits[i/8] & (1<<(i&7))) != 0) + { + if (c > 75) + { + fprintf(outfile, "\n "); + c = 2; + } + if (isprint(i) && i != ' ') + { + fprintf(outfile, "%c ", i); + c += 2; + } + else + { + fprintf(outfile, "\\x%02x ", i); + c += 5; + } + } + } + fprintf(outfile, "\n"); + } + } + } + } + + /* If the '>' option was present, we write out the regex to a file, and + that is all. The first 8 bytes of the file are the regex length and then + the study length, in big-endian order. */ + + if (to_file != NULL) + { + FILE *f = fopen((char *)to_file, "wb"); + if (f == NULL) + { + fprintf(outfile, "Unable to open %s: %s\n", to_file, strerror(errno)); + } + else + { + uschar sbuf[8]; + sbuf[0] = (true_size >> 24) & 255; + sbuf[1] = (true_size >> 16) & 255; + sbuf[2] = (true_size >> 8) & 255; + sbuf[3] = (true_size) & 255; + + sbuf[4] = (true_study_size >> 24) & 255; + sbuf[5] = (true_study_size >> 16) & 255; + sbuf[6] = (true_study_size >> 8) & 255; + sbuf[7] = (true_study_size) & 255; + + if (fwrite(sbuf, 1, 8, f) < 8 || + fwrite(re, 1, true_size, f) < true_size) + { + fprintf(outfile, "Write error on %s: %s\n", to_file, strerror(errno)); + } + else + { + fprintf(outfile, "Compiled regex written to %s\n", to_file); + if (extra != NULL) + { + if (fwrite(extra->study_data, 1, true_study_size, f) < + true_study_size) + { + fprintf(outfile, "Write error on %s: %s\n", to_file, + strerror(errno)); + } + else fprintf(outfile, "Study data written to %s\n", to_file); + } + } + fclose(f); + } + continue; /* With next regex */ + } + } /* End of non-POSIX compile */ + + /* Read data lines and test them */ + + for (;;) + { + unsigned char *q; + unsigned char *bptr = dbuffer; + int *use_offsets = offsets; + int use_size_offsets = size_offsets; + int callout_data = 0; + int callout_data_set = 0; + int count, c; + int copystrings = 0; + int find_match_limit = 0; + int getstrings = 0; + int getlist = 0; + int gmatched = 0; + int start_offset = 0; + int g_notempty = 0; + + options = 0; + + pcre_callout = callout; + first_callout = 1; + callout_extra = 0; + callout_count = 0; + callout_fail_count = 999999; + callout_fail_id = -1; + show_malloc = 0; + + if (infile == stdin) printf("data> "); + if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) + { + done = 1; + goto CONTINUE; + } + if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); + + len = (int)strlen((char *)buffer); + while (len > 0 && isspace(buffer[len-1])) len--; + buffer[len] = 0; + if (len == 0) break; + + p = buffer; + while (isspace(*p)) p++; + + q = dbuffer; + while ((c = *p++) != 0) + { + int i = 0; + int n = 0; + + if (c == '\\') switch ((c = *p++)) + { + case 'a': c = 7; break; + case 'b': c = '\b'; break; + case 'e': c = 27; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + c -= '0'; + while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9') + c = c * 8 + *p++ - '0'; + break; + + case 'x': + + /* Handle \x{..} specially - new Perl thing for utf8 */ + + if (*p == '{') + { + unsigned char *pt = p; + c = 0; + while (isxdigit(*(++pt))) + c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W'); + if (*pt == '}') + { + unsigned char buff8[8]; + int ii, utn; + utn = ord2utf8(c, buff8); + for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii]; + c = buff8[ii]; /* Last byte */ + p = pt + 1; + break; + } + /* Not correct form; fall through */ + } + + /* Ordinary \x */ + + c = 0; + while (i++ < 2 && isxdigit(*p)) + { + c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W'); + p++; + } + break; + + case 0: /* \ followed by EOF allows for an empty line */ + p--; + continue; + + case '>': + while(isdigit(*p)) start_offset = start_offset * 10 + *p++ - '0'; + continue; + + case 'A': /* Option setting */ + options |= PCRE_ANCHORED; + continue; + + case 'B': + options |= PCRE_NOTBOL; + continue; + + case 'C': + if (isdigit(*p)) /* Set copy string */ + { + while(isdigit(*p)) n = n * 10 + *p++ - '0'; + copystrings |= 1 << n; + } + else if (isalnum(*p)) + { + uschar name[256]; + uschar *npp = name; + while (isalnum(*p)) *npp++ = *p++; + *npp = 0; + n = pcre_get_stringnumber(re, (char *)name); + if (n < 0) + fprintf(outfile, "no parentheses with name \"%s\"\n", name); + else copystrings |= 1 << n; + } + else if (*p == '+') + { + callout_extra = 1; + p++; + } + else if (*p == '-') + { + pcre_callout = NULL; + p++; + } + else if (*p == '!') + { + callout_fail_id = 0; + p++; + while(isdigit(*p)) + callout_fail_id = callout_fail_id * 10 + *p++ - '0'; + callout_fail_count = 0; + if (*p == '!') + { + p++; + while(isdigit(*p)) + callout_fail_count = callout_fail_count * 10 + *p++ - '0'; + } + } + else if (*p == '*') + { + int sign = 1; + callout_data = 0; + if (*(++p) == '-') { sign = -1; p++; } + while(isdigit(*p)) + callout_data = callout_data * 10 + *p++ - '0'; + callout_data *= sign; + callout_data_set = 1; + } + continue; + + case 'G': + if (isdigit(*p)) + { + while(isdigit(*p)) n = n * 10 + *p++ - '0'; + getstrings |= 1 << n; + } + else if (isalnum(*p)) + { + uschar name[256]; + uschar *npp = name; + while (isalnum(*p)) *npp++ = *p++; + *npp = 0; + n = pcre_get_stringnumber(re, (char *)name); + if (n < 0) + fprintf(outfile, "no parentheses with name \"%s\"\n", name); + else getstrings |= 1 << n; + } + continue; + + case 'L': + getlist = 1; + continue; + + case 'M': + find_match_limit = 1; + continue; + + case 'N': + options |= PCRE_NOTEMPTY; + continue; + + case 'O': + while(isdigit(*p)) n = n * 10 + *p++ - '0'; + if (n > size_offsets_max) + { + size_offsets_max = n; + free(offsets); + use_offsets = offsets = (int *)malloc(size_offsets_max * sizeof(int)); + if (offsets == NULL) + { + printf("** Failed to get %d bytes of memory for offsets vector\n", + size_offsets_max * sizeof(int)); + return 1; + } + } + use_size_offsets = n; + if (n == 0) use_offsets = NULL; /* Ensures it can't write to it */ + continue; + + case 'P': + options |= PCRE_PARTIAL; + continue; + + case 'S': + show_malloc = 1; + continue; + + case 'Z': + options |= PCRE_NOTEOL; + continue; + + case '?': + options |= PCRE_NO_UTF8_CHECK; + continue; + } + *q++ = c; + } + *q = 0; + len = q - dbuffer; + + /* Handle matching via the POSIX interface, which does not + support timing or playing with the match limit or callout data. */ + +#if !defined NOPOSIX + if (posix || do_posix) + { + int rc; + int eflags = 0; + regmatch_t *pmatch = NULL; + if (use_size_offsets > 0) + pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets); + if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; + if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; + + rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags); + + if (rc != 0) + { + (void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE); + fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer); + } + else + { + size_t i; + for (i = 0; i < (size_t)use_size_offsets; i++) + { + if (pmatch[i].rm_so >= 0) + { + fprintf(outfile, "%2d: ", (int)i); + (void)pchars(dbuffer + pmatch[i].rm_so, + pmatch[i].rm_eo - pmatch[i].rm_so, outfile); + fprintf(outfile, "\n"); + if (i == 0 && do_showrest) + { + fprintf(outfile, " 0+ "); + (void)pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo, + outfile); + fprintf(outfile, "\n"); + } + } + } + } + free(pmatch); + } + + /* Handle matching via the native interface - repeats for /g and /G */ + + else +#endif /* !defined NOPOSIX */ + + for (;; gmatched++) /* Loop for /g or /G */ + { + if (timeit) + { + register int i; + clock_t time_taken; + clock_t start_time = clock(); + for (i = 0; i < LOOPREPEAT; i++) + count = pcre_exec(re, extra, (char *)bptr, len, + start_offset, options | g_notempty, use_offsets, use_size_offsets); + time_taken = clock() - start_time; + fprintf(outfile, "Execute time %.3f milliseconds\n", + (((double)time_taken * 1000.0) / (double)LOOPREPEAT) / + (double)CLOCKS_PER_SEC); + } + + /* If find_match_limit is set, we want to do repeated matches with + varying limits in order to find the minimum value. */ + + if (find_match_limit) + { + int min = 0; + int mid = 64; + int max = -1; + + if (extra == NULL) + { + extra = (pcre_extra *)malloc(sizeof(pcre_extra)); + extra->flags = 0; + } + extra->flags |= PCRE_EXTRA_MATCH_LIMIT; + + for (;;) + { + extra->match_limit = mid; + count = pcre_exec(re, extra, (char *)bptr, len, start_offset, + options | g_notempty, use_offsets, use_size_offsets); + if (count == PCRE_ERROR_MATCHLIMIT) + { + /* fprintf(outfile, "Testing match limit = %d\n", mid); */ + min = mid; + mid = (mid == max - 1)? max : (max > 0)? (min + max)/2 : mid*2; + } + else if (count >= 0 || count == PCRE_ERROR_NOMATCH || + count == PCRE_ERROR_PARTIAL) + { + if (mid == min + 1) + { + fprintf(outfile, "Minimum match limit = %d\n", mid); + break; + } + /* fprintf(outfile, "Testing match limit = %d\n", mid); */ + max = mid; + mid = (min + mid)/2; + } + else break; /* Some other error */ + } + + extra->flags &= ~PCRE_EXTRA_MATCH_LIMIT; + } + + /* If callout_data is set, use the interface with additional data */ + + else if (callout_data_set) + { + if (extra == NULL) + { + extra = (pcre_extra *)malloc(sizeof(pcre_extra)); + extra->flags = 0; + } + extra->flags |= PCRE_EXTRA_CALLOUT_DATA; + extra->callout_data = &callout_data; + count = pcre_exec(re, extra, (char *)bptr, len, start_offset, + options | g_notempty, use_offsets, use_size_offsets); + extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA; + } + + /* The normal case is just to do the match once, with the default + value of match_limit. */ + + else + { + count = pcre_exec(re, extra, (char *)bptr, len, + start_offset, options | g_notempty, use_offsets, use_size_offsets); + } + + if (count == 0) + { + fprintf(outfile, "Matched, but too many substrings\n"); + count = use_size_offsets/3; + } + + /* Matched */ + + if (count >= 0) + { + int i; + for (i = 0; i < count * 2; i += 2) + { + if (use_offsets[i] < 0) + fprintf(outfile, "%2d: \n", i/2); + else + { + fprintf(outfile, "%2d: ", i/2); + (void)pchars(bptr + use_offsets[i], + use_offsets[i+1] - use_offsets[i], outfile); + fprintf(outfile, "\n"); + if (i == 0) + { + if (do_showrest) + { + fprintf(outfile, " 0+ "); + (void)pchars(bptr + use_offsets[i+1], len - use_offsets[i+1], + outfile); + fprintf(outfile, "\n"); + } + } + } + } + + for (i = 0; i < 32; i++) + { + if ((copystrings & (1 << i)) != 0) + { + char copybuffer[16]; + int rc = pcre_copy_substring((char *)bptr, use_offsets, count, + i, copybuffer, sizeof(copybuffer)); + if (rc < 0) + fprintf(outfile, "copy substring %d failed %d\n", i, rc); + else + fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc); + } + } + + for (i = 0; i < 32; i++) + { + if ((getstrings & (1 << i)) != 0) + { + const char *substring; + int rc = pcre_get_substring((char *)bptr, use_offsets, count, + i, &substring); + if (rc < 0) + fprintf(outfile, "get substring %d failed %d\n", i, rc); + else + { + fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc); + /* free((void *)substring); */ + pcre_free_substring(substring); + } + } + } + + if (getlist) + { + const char **stringlist; + int rc = pcre_get_substring_list((char *)bptr, use_offsets, count, + &stringlist); + if (rc < 0) + fprintf(outfile, "get substring list failed %d\n", rc); + else + { + for (i = 0; i < count; i++) + fprintf(outfile, "%2dL %s\n", i, stringlist[i]); + if (stringlist[i] != NULL) + fprintf(outfile, "string list not terminated by NULL\n"); + /* free((void *)stringlist); */ + pcre_free_substring_list(stringlist); + } + } + } + + /* There was a partial match */ + + else if (count == PCRE_ERROR_PARTIAL) + { + fprintf(outfile, "Partial match\n"); + break; /* Out of the /g loop */ + } + + /* Failed to match. If this is a /g or /G loop and we previously set + g_notempty after a null match, this is not necessarily the end. + We want to advance the start offset, and continue. In the case of UTF-8 + matching, the advance must be one character, not one byte. Fudge the + offset values to achieve this. We won't be at the end of the string - + that was checked before setting g_notempty. */ + + else + { + if (g_notempty != 0) + { + int onechar = 1; + use_offsets[0] = start_offset; + if (use_utf8) + { + while (start_offset + onechar < len) + { + int tb = bptr[start_offset+onechar]; + if (tb <= 127) break; + tb &= 0xc0; + if (tb != 0 && tb != 0xc0) onechar++; + } + } + use_offsets[1] = start_offset + onechar; + } + else + { + if (count == PCRE_ERROR_NOMATCH) + { + if (gmatched == 0) fprintf(outfile, "No match\n"); + } + else fprintf(outfile, "Error %d\n", count); + break; /* Out of the /g loop */ + } + } + + /* If not /g or /G we are done */ + + if (!do_g && !do_G) break; + + /* If we have matched an empty string, first check to see if we are at + the end of the subject. If so, the /g loop is over. Otherwise, mimic + what Perl's /g options does. This turns out to be rather cunning. First + we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the + same point. If this fails (picked up above) we advance to the next + character. */ + + g_notempty = 0; + if (use_offsets[0] == use_offsets[1]) + { + if (use_offsets[0] == len) break; + g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED; + } + + /* For /g, update the start offset, leaving the rest alone */ + + if (do_g) start_offset = use_offsets[1]; + + /* For /G, update the pointer and length */ + + else + { + bptr += use_offsets[1]; + len -= use_offsets[1]; + } + } /* End of loop for /g and /G */ + } /* End of loop for data lines */ + + CONTINUE: + +#if !defined NOPOSIX + if (posix || do_posix) regfree(&preg); +#endif + + if (re != NULL) free(re); + if (extra != NULL) free(extra); + if (tables != NULL) + { + free((void *)tables); + setlocale(LC_CTYPE, "C"); + } + } + +if (infile == stdin) fprintf(outfile, "\n"); +return 0; +} + +/* End */ diff --git a/src/libs/resiprocate/contrib/pcre/printint.c b/src/libs/resiprocate/contrib/pcre/printint.c new file mode 100644 index 00000000..8e5da426 --- /dev/null +++ b/src/libs/resiprocate/contrib/pcre/printint.c @@ -0,0 +1,461 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +This is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. See +the file Tech.Notes for some information on the internals. + +Written by: Philip Hazel + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module contains a debugging function for printing out the internal form +of a compiled regular expression. It is kept in a separate file so that it can +be #included both in the pcretest program, and in the library itself when +compiled with the debugging switch. */ + + +static const char *OP_names[] = { OP_NAME_LIST }; + + +/************************************************* +* Print single- or multi-byte character * +*************************************************/ + +/* These tables are actually copies of ones in pcre.c. If we compile the +library with debugging, they are included twice, but that isn't really a +problem - compiling with debugging is pretty rare and these are very small. */ + +static const int utf8_t3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; + +static const uschar utf8_t4[] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; + +static int +print_char(FILE *f, uschar *ptr, BOOL utf8) +{ +int c = *ptr; + +if (!utf8 || (c & 0xc0) != 0xc0) + { + if (isprint(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); + return 0; + } +else + { + int i; + int a = utf8_t4[c & 0x3f]; /* Number of additional bytes */ + int s = 6*a; + c = (c & utf8_t3[a]) << s; + for (i = 1; i <= a; i++) + { + /* This is a check for malformed UTF-8; it should only occur if the sanity + check has been turned off. Rather than swallow random bytes, just stop if + we hit a bad one. Print it with \X instead of \x as an indication. */ + + if ((ptr[i] & 0xc0) != 0x80) + { + fprintf(f, "\\X{%x}", c); + return i - 1; + } + + /* The byte is OK */ + + s -= 6; + c |= (ptr[i] & 0x3f) << s; + } + if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c); + return a; + } +} + + + + +/************************************************* +* Find Unicode property name * +*************************************************/ + +static const char * +get_ucpname(int property) +{ +int i; +for (i = sizeof(utt)/sizeof(ucp_type_table); i >= 0; i--) + { + if (property == utt[i].value) break; + } +return (i >= 0)? utt[i].name : "??"; +} + + + +/************************************************* +* Print compiled regex * +*************************************************/ + +/* Make this function work for a regex with integers either byte order. +However, we assume that what we are passed is a compiled regex. */ + +static void +print_internals(pcre *external_re, FILE *f) +{ +real_pcre *re = (real_pcre *)external_re; +uschar *codestart, *code; +BOOL utf8; + +unsigned int options = re->options; +int offset = re->name_table_offset; +int count = re->name_count; +int size = re->name_entry_size; + +if (re->magic_number != MAGIC_NUMBER) + { + offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff); + count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff); + size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff); + options = ((options << 24) & 0xff000000) | + ((options << 8) & 0x00ff0000) | + ((options >> 8) & 0x0000ff00) | + ((options >> 24) & 0x000000ff); + } + +code = codestart = (uschar *)re + offset + count * size; +utf8 = (options & PCRE_UTF8) != 0; + +for(;;) + { + uschar *ccode; + int c; + int extra = 0; + + fprintf(f, "%3d ", code - codestart); + + if (*code >= OP_BRA) + { + if (*code - OP_BRA > EXTRACT_BASIC_MAX) + fprintf(f, "%3d Bra extra\n", GET(code, 1)); + else + fprintf(f, "%3d Bra %d\n", GET(code, 1), *code - OP_BRA); + code += OP_lengths[OP_BRA]; + continue; + } + + switch(*code) + { + case OP_END: + fprintf(f, " %s\n", OP_names[*code]); + fprintf(f, "------------------------------------------------------------------\n"); + return; + + case OP_OPT: + fprintf(f, " %.2x %s", code[1], OP_names[*code]); + break; + + case OP_CHAR: + { + fprintf(f, " "); + do + { + code++; + code += 1 + print_char(f, code, utf8); + } + while (*code == OP_CHAR); + fprintf(f, "\n"); + continue; + } + break; + + case OP_CHARNC: + { + fprintf(f, " NC "); + do + { + code++; + code += 1 + print_char(f, code, utf8); + } + while (*code == OP_CHARNC); + fprintf(f, "\n"); + continue; + } + break; + + case OP_KETRMAX: + case OP_KETRMIN: + case OP_ALT: + case OP_KET: + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_COND: + case OP_REVERSE: + fprintf(f, "%3d %s", GET(code, 1), OP_names[*code]); + break; + + case OP_BRANUMBER: + printf("%3d %s", GET2(code, 1), OP_names[*code]); + break; + + case OP_CREF: + if (GET2(code, 1) == CREF_RECURSE) + fprintf(f, " Cond recurse"); + else + fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]); + break; + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + fprintf(f, " "); + if (*code >= OP_TYPESTAR) + { + fprintf(f, "%s", OP_names[code[1]]); + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) + { + fprintf(f, " %s ", get_ucpname(code[2])); + extra = 1; + } + } + else extra = print_char(f, code+1, utf8); + fprintf(f, "%s", OP_names[*code]); + break; + + case OP_EXACT: + case OP_UPTO: + case OP_MINUPTO: + fprintf(f, " "); + extra = print_char(f, code+3, utf8); + fprintf(f, "{"); + if (*code != OP_EXACT) fprintf(f, ","); + fprintf(f, "%d}", GET2(code,1)); + if (*code == OP_MINUPTO) fprintf(f, "?"); + break; + + case OP_TYPEEXACT: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + fprintf(f, " %s", OP_names[code[3]]); + if (code[3] == OP_PROP || code[3] == OP_NOTPROP) + { + fprintf(f, " %s ", get_ucpname(code[4])); + extra = 1; + } + fprintf(f, "{"); + if (*code != OP_TYPEEXACT) fprintf(f, "0,"); + fprintf(f, "%d}", GET2(code,1)); + if (*code == OP_TYPEMINUPTO) fprintf(f, "?"); + break; + + case OP_NOT: + if (isprint(c = code[1])) fprintf(f, " [^%c]", c); + else fprintf(f, " [^\\x%02x]", c); + break; + + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + if (isprint(c = code[1])) fprintf(f, " [^%c]", c); + else fprintf(f, " [^\\x%02x]", c); + fprintf(f, "%s", OP_names[*code]); + break; + + case OP_NOTEXACT: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + if (isprint(c = code[3])) fprintf(f, " [^%c]{", c); + else fprintf(f, " [^\\x%02x]{", c); + if (*code != OP_NOTEXACT) fprintf(f, ","); + fprintf(f, "%d}", GET2(code,1)); + if (*code == OP_NOTMINUPTO) fprintf(f, "?"); + break; + + case OP_RECURSE: + fprintf(f, "%3d %s", GET(code, 1), OP_names[*code]); + break; + + case OP_REF: + fprintf(f, " \\%d", GET2(code,1)); + ccode = code + OP_lengths[*code]; + goto CLASS_REF_REPEAT; + + case OP_CALLOUT: + fprintf(f, " %s %d %d %d", OP_names[*code], code[1], GET(code,2), + GET(code, 2 + LINK_SIZE)); + break; + + case OP_PROP: + case OP_NOTPROP: + fprintf(f, " %s %s", OP_names[*code], get_ucpname(code[1])); + break; + + /* OP_XCLASS can only occur in UTF-8 mode. However, there's no harm in + having this code always here, and it makes it less messy without all those + #ifdefs. */ + + case OP_CLASS: + case OP_NCLASS: + case OP_XCLASS: + { + int i, min, max; + BOOL printmap; + + fprintf(f, " ["); + + if (*code == OP_XCLASS) + { + extra = GET(code, 1); + ccode = code + LINK_SIZE + 1; + printmap = (*ccode & XCL_MAP) != 0; + if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^"); + } + else + { + printmap = TRUE; + ccode = code + 1; + } + + /* Print a bit map */ + + if (printmap) + { + for (i = 0; i < 256; i++) + { + if ((ccode[i/8] & (1 << (i&7))) != 0) + { + int j; + for (j = i+1; j < 256; j++) + if ((ccode[j/8] & (1 << (j&7))) == 0) break; + if (i == '-' || i == ']') fprintf(f, "\\"); + if (isprint(i)) fprintf(f, "%c", i); else fprintf(f, "\\x%02x", i); + if (--j > i) + { + if (j != i + 1) fprintf(f, "-"); + if (j == '-' || j == ']') fprintf(f, "\\"); + if (isprint(j)) fprintf(f, "%c", j); else fprintf(f, "\\x%02x", j); + } + i = j; + } + } + ccode += 32; + } + + /* For an XCLASS there is always some additional data */ + + if (*code == OP_XCLASS) + { + int ch; + while ((ch = *ccode++) != XCL_END) + { + if (ch == XCL_PROP) + { + fprintf(f, "\\p{%s}", get_ucpname(*ccode++)); + } + else if (ch == XCL_NOTPROP) + { + fprintf(f, "\\P{%s}", get_ucpname(*ccode++)); + } + else + { + ccode += 1 + print_char(f, ccode, TRUE); + if (ch == XCL_RANGE) + { + fprintf(f, "-"); + ccode += 1 + print_char(f, ccode, TRUE); + } + } + } + } + + /* Indicate a non-UTF8 class which was created by negation */ + + fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : ""); + + /* Handle repeats after a class or a back reference */ + + CLASS_REF_REPEAT: + switch(*ccode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + fprintf(f, "%s", OP_names[*ccode]); + extra += OP_lengths[*ccode]; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + min = GET2(ccode,1); + max = GET2(ccode,3); + if (max == 0) fprintf(f, "{%d,}", min); + else fprintf(f, "{%d,%d}", min, max); + if (*ccode == OP_CRMINRANGE) fprintf(f, "?"); + extra += OP_lengths[*ccode]; + break; + } + } + break; + + /* Anything else is just an item with no data*/ + + default: + fprintf(f, " %s", OP_names[*code]); + break; + } + + code += OP_lengths[*code] + extra; + fprintf(f, "\n"); + } +} + +/* End of printint.c */ diff --git a/src/libs/resiprocate/contrib/pcre/study.c b/src/libs/resiprocate/contrib/pcre/study.c new file mode 100644 index 00000000..d99b8a99 --- /dev/null +++ b/src/libs/resiprocate/contrib/pcre/study.c @@ -0,0 +1,484 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +This is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. See +the file Tech.Notes for some information on the internals. + +Written by: Philip Hazel + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* Include the internals header, which itself includes Standard C headers plus +the external pcre header. */ + +#include "internal.h" + + + +/************************************************* +* Set a bit and maybe its alternate case * +*************************************************/ + +/* Given a character, set its bit in the table, and also the bit for the other +version of a letter if we are caseless. + +Arguments: + start_bits points to the bit map + c is the character + caseless the caseless flag + cd the block with char table pointers + +Returns: nothing +*/ + +static void +set_bit(uschar *start_bits, unsigned int c, BOOL caseless, compile_data *cd) +{ +start_bits[c/8] |= (1 << (c&7)); +if (caseless && (cd->ctypes[c] & ctype_letter) != 0) + start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7)); +} + + + +/************************************************* +* Create bitmap of starting chars * +*************************************************/ + +/* This function scans a compiled unanchored expression and attempts to build a +bitmap of the set of initial characters. If it can't, it returns FALSE. As time +goes by, we may be able to get more clever at doing this. + +Arguments: + code points to an expression + start_bits points to a 32-byte table, initialized to 0 + caseless the current state of the caseless flag + utf8 TRUE if in UTF-8 mode + cd the block with char table pointers + +Returns: TRUE if table built, FALSE otherwise +*/ + +static BOOL +set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless, + BOOL utf8, compile_data *cd) +{ +register int c; + +/* This next statement and the later reference to dummy are here in order to +trick the optimizer of the IBM C compiler for OS/2 into generating correct +code. Apparently IBM isn't going to fix the problem, and we would rather not +disable optimization (in this module it actually makes a big difference, and +the pcre module can use all the optimization it can get). */ + +volatile int dummy; + +do + { + const uschar *tcode = code + 1 + LINK_SIZE; + BOOL try_next = TRUE; + + while (try_next) + { + /* If a branch starts with a bracket or a positive lookahead assertion, + recurse to set bits from within them. That's all for this branch. */ + + if ((int)*tcode >= OP_BRA || *tcode == OP_ASSERT) + { + if (!set_start_bits(tcode, start_bits, caseless, utf8, cd)) + return FALSE; + try_next = FALSE; + } + + else switch(*tcode) + { + default: + return FALSE; + + /* Skip over callout */ + + case OP_CALLOUT: + tcode += 2 + 2*LINK_SIZE; + break; + + /* Skip over extended extraction bracket number */ + + case OP_BRANUMBER: + tcode += 3; + break; + + /* Skip over lookbehind and negative lookahead assertions */ + + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + do tcode += GET(tcode, 1); while (*tcode == OP_ALT); + tcode += 1+LINK_SIZE; + break; + + /* Skip over an option setting, changing the caseless flag */ + + case OP_OPT: + caseless = (tcode[1] & PCRE_CASELESS) != 0; + tcode += 2; + break; + + /* BRAZERO does the bracket, but carries on. */ + + case OP_BRAZERO: + case OP_BRAMINZERO: + if (!set_start_bits(++tcode, start_bits, caseless, utf8, cd)) + return FALSE; + dummy = 1; + do tcode += GET(tcode,1); while (*tcode == OP_ALT); + tcode += 1+LINK_SIZE; + break; + + /* Single-char * or ? sets the bit and tries the next item */ + + case OP_STAR: + case OP_MINSTAR: + case OP_QUERY: + case OP_MINQUERY: + set_bit(start_bits, tcode[1], caseless, cd); + tcode += 2; +#ifdef SUPPORT_UTF8 + if (utf8) while ((*tcode & 0xc0) == 0x80) tcode++; +#endif + break; + + /* Single-char upto sets the bit and tries the next */ + + case OP_UPTO: + case OP_MINUPTO: + set_bit(start_bits, tcode[3], caseless, cd); + tcode += 4; +#ifdef SUPPORT_UTF8 + if (utf8) while ((*tcode & 0xc0) == 0x80) tcode++; +#endif + break; + + /* At least one single char sets the bit and stops */ + + case OP_EXACT: /* Fall through */ + tcode += 2; + + case OP_CHAR: + case OP_CHARNC: + case OP_PLUS: + case OP_MINPLUS: + set_bit(start_bits, tcode[1], caseless, cd); + try_next = FALSE; + break; + + /* Single character type sets the bits and stops */ + + case OP_NOT_DIGIT: + for (c = 0; c < 32; c++) + start_bits[c] |= ~cd->cbits[c+cbit_digit]; + try_next = FALSE; + break; + + case OP_DIGIT: + for (c = 0; c < 32; c++) + start_bits[c] |= cd->cbits[c+cbit_digit]; + try_next = FALSE; + break; + + case OP_NOT_WHITESPACE: + for (c = 0; c < 32; c++) + start_bits[c] |= ~cd->cbits[c+cbit_space]; + try_next = FALSE; + break; + + case OP_WHITESPACE: + for (c = 0; c < 32; c++) + start_bits[c] |= cd->cbits[c+cbit_space]; + try_next = FALSE; + break; + + case OP_NOT_WORDCHAR: + for (c = 0; c < 32; c++) + start_bits[c] |= ~cd->cbits[c+cbit_word]; + try_next = FALSE; + break; + + case OP_WORDCHAR: + for (c = 0; c < 32; c++) + start_bits[c] |= cd->cbits[c+cbit_word]; + try_next = FALSE; + break; + + /* One or more character type fudges the pointer and restarts, knowing + it will hit a single character type and stop there. */ + + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + tcode++; + break; + + case OP_TYPEEXACT: + tcode += 3; + break; + + /* Zero or more repeats of character types set the bits and then + try again. */ + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + tcode += 2; /* Fall through */ + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + switch(tcode[1]) + { + case OP_ANY: + return FALSE; + + case OP_NOT_DIGIT: + for (c = 0; c < 32; c++) + start_bits[c] |= ~cd->cbits[c+cbit_digit]; + break; + + case OP_DIGIT: + for (c = 0; c < 32; c++) + start_bits[c] |= cd->cbits[c+cbit_digit]; + break; + + case OP_NOT_WHITESPACE: + for (c = 0; c < 32; c++) + start_bits[c] |= ~cd->cbits[c+cbit_space]; + break; + + case OP_WHITESPACE: + for (c = 0; c < 32; c++) + start_bits[c] |= cd->cbits[c+cbit_space]; + break; + + case OP_NOT_WORDCHAR: + for (c = 0; c < 32; c++) + start_bits[c] |= ~cd->cbits[c+cbit_word]; + break; + + case OP_WORDCHAR: + for (c = 0; c < 32; c++) + start_bits[c] |= cd->cbits[c+cbit_word]; + break; + } + + tcode += 2; + break; + + /* Character class where all the information is in a bit map: set the + bits and either carry on or not, according to the repeat count. If it was + a negative class, and we are operating with UTF-8 characters, any byte + with a value >= 0xc4 is a potentially valid starter because it starts a + character with a value > 255. */ + + case OP_NCLASS: + if (utf8) + { + start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */ + memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */ + } + /* Fall through */ + + case OP_CLASS: + { + tcode++; + + /* In UTF-8 mode, the bits in a bit map correspond to character + values, not to byte values. However, the bit map we are constructing is + for byte values. So we have to do a conversion for characters whose + value is > 127. In fact, there are only two possible starting bytes for + characters in the range 128 - 255. */ + + if (utf8) + { + for (c = 0; c < 16; c++) start_bits[c] |= tcode[c]; + for (c = 128; c < 256; c++) + { + if ((tcode[c/8] && (1 << (c&7))) != 0) + { + int d = (c >> 6) | 0xc0; /* Set bit for this starter */ + start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */ + c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */ + } + } + } + + /* In non-UTF-8 mode, the two bit maps are completely compatible. */ + + else + { + for (c = 0; c < 32; c++) start_bits[c] |= tcode[c]; + } + + /* Advance past the bit map, and act on what follows */ + + tcode += 32; + switch (*tcode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + tcode++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5; + else try_next = FALSE; + break; + + default: + try_next = FALSE; + break; + } + } + break; /* End of bitmap class handling */ + + } /* End of switch */ + } /* End of try_next loop */ + + code += GET(code, 1); /* Advance to next branch */ + } +while (*code == OP_ALT); +return TRUE; +} + + + +/************************************************* +* Study a compiled expression * +*************************************************/ + +/* This function is handed a compiled expression that it must study to produce +information that will speed up the matching. It returns a pcre_extra block +which then gets handed back to pcre_exec(). + +Arguments: + re points to the compiled expression + options contains option bits + errorptr points to where to place error messages; + set NULL unless error + +Returns: pointer to a pcre_extra block, with study_data filled in and the + appropriate flag set; + NULL on error or if no optimization possible +*/ + +EXPORT pcre_extra * +pcre_study(const pcre *external_re, int options, const char **errorptr) +{ +uschar start_bits[32]; +pcre_extra *extra; +pcre_study_data *study; +const uschar *tables; +const real_pcre *re = (const real_pcre *)external_re; +uschar *code = (uschar *)re + re->name_table_offset + + (re->name_count * re->name_entry_size); +compile_data compile_block; + +*errorptr = NULL; + +if (re == NULL || re->magic_number != MAGIC_NUMBER) + { + *errorptr = "argument is not a compiled regular expression"; + return NULL; + } + +if ((options & ~PUBLIC_STUDY_OPTIONS) != 0) + { + *errorptr = "unknown or incorrect option bit(s) set"; + return NULL; + } + +/* For an anchored pattern, or an unanchored pattern that has a first char, or +a multiline pattern that matches only at "line starts", no further processing +at present. */ + +if ((re->options & (PCRE_ANCHORED|PCRE_FIRSTSET|PCRE_STARTLINE)) != 0) + return NULL; + +/* Set the character tables in the block that is passed around */ + +tables = re->tables; +if (tables == NULL) + (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, &tables); + +compile_block.lcc = tables + lcc_offset; +compile_block.fcc = tables + fcc_offset; +compile_block.cbits = tables + cbits_offset; +compile_block.ctypes = tables + ctypes_offset; + +/* See if we can find a fixed set of initial characters for the pattern. */ + +memset(start_bits, 0, 32 * sizeof(uschar)); +if (!set_start_bits(code, start_bits, (re->options & PCRE_CASELESS) != 0, + (re->options & PCRE_UTF8) != 0, &compile_block)) return NULL; + +/* Get a pcre_extra block and a pcre_study_data block. The study data is put in +the latter, which is pointed to by the former, which may also get additional +data set later by the calling program. At the moment, the size of +pcre_study_data is fixed. We nevertheless save it in a field for returning via +the pcre_fullinfo() function so that if it becomes variable in the future, we +don't have to change that code. */ + +extra = (pcre_extra *)(pcre_malloc) + (sizeof(pcre_extra) + sizeof(pcre_study_data)); + +if (extra == NULL) + { + *errorptr = "failed to get memory"; + return NULL; + } + +study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra)); +extra->flags = PCRE_EXTRA_STUDY_DATA; +extra->study_data = study; + +study->size = sizeof(pcre_study_data); +study->options = PCRE_STUDY_MAPPED; +memcpy(study->start_bits, start_bits, sizeof(start_bits)); + +return extra; +} + +/* End of study.c */ diff --git a/src/libs/resiprocate/contrib/pcre/ucp.c b/src/libs/resiprocate/contrib/pcre/ucp.c new file mode 100644 index 00000000..3d69653b --- /dev/null +++ b/src/libs/resiprocate/contrib/pcre/ucp.c @@ -0,0 +1,151 @@ +/************************************************* +* libucp - Unicode Property Table handler * +*************************************************/ + +/* This function provides a fast way of obtaining the basic Unicode properties +of a character, using a compact binary tree that occupies less than 100K bytes. + + Copyright (c) 2004 University of Cambridge + +------------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +------------------------------------------------------------------------------- +*/ + + +#include "ucp.h" /* Exported interface */ +#include "ucpinternal.h" /* Internal table details */ +#include "ucptable.c" /* The table itself */ + + + +/************************************************* +* Search table and return data * +*************************************************/ + +/* Two values are returned: the category is ucp_C, ucp_L, etc. The detailed +character type is ucp_Lu, ucp_Nd, etc. + +Arguments: + c the character value + type_ptr the detailed character type is returned here + case_ptr for letters, the opposite case is returned here, if there + is one, else zero + +Returns: the character type category or -1 if not found +*/ + +static int +ucp_findchar(const int c, int *type_ptr, int *case_ptr) +{ +cnode *node = ucp_table; +register int cc = c; +int case_offset; + +for (;;) + { + register int d = node->f1 | ((node->f0 & f0_chhmask) << 16); + if (cc == d) break; + if (cc < d) + { + if ((node->f0 & f0_leftexists) == 0) return -1; + node ++; + } + else + { + register int roffset = (node->f2 & f2_rightmask) >> f2_rightshift; + if (roffset == 0) return -1; + node += 1 << (roffset - 1); + } + } + +switch ((*type_ptr = ((node->f0 & f0_typemask) >> f0_typeshift))) + { + case ucp_Cc: + case ucp_Cf: + case ucp_Cn: + case ucp_Co: + case ucp_Cs: + return ucp_C; + break; + + case ucp_Ll: + case ucp_Lu: + case_offset = node->f2 & f2_casemask; + if ((case_offset & 0x0100) != 0) case_offset |= 0xfffff000; + *case_ptr = (case_offset == 0)? 0 : cc + case_offset; + return ucp_L; + + case ucp_Lm: + case ucp_Lo: + case ucp_Lt: + *case_ptr = 0; + return ucp_L; + break; + + case ucp_Mc: + case ucp_Me: + case ucp_Mn: + return ucp_M; + break; + + case ucp_Nd: + case ucp_Nl: + case ucp_No: + return ucp_N; + break; + + case ucp_Pc: + case ucp_Pd: + case ucp_Pe: + case ucp_Pf: + case ucp_Pi: + case ucp_Ps: + case ucp_Po: + return ucp_P; + break; + + case ucp_Sc: + case ucp_Sk: + case ucp_Sm: + case ucp_So: + return ucp_S; + break; + + case ucp_Zl: + case ucp_Zp: + case ucp_Zs: + return ucp_Z; + break; + + default: /* "Should never happen" */ + return -1; + break; + } +} + +/* End of ucp.c */ diff --git a/src/libs/resiprocate/contrib/pcre/ucp.h b/src/libs/resiprocate/contrib/pcre/ucp.h new file mode 100644 index 00000000..c013978e --- /dev/null +++ b/src/libs/resiprocate/contrib/pcre/ucp.h @@ -0,0 +1,58 @@ +/************************************************* +* libucp - Unicode Property Table handler * +*************************************************/ + +/* These are the character categories that are returned by ucp_findchar */ + +enum { + ucp_C, /* Other */ + ucp_L, /* Letter */ + ucp_M, /* Mark */ + ucp_N, /* Number */ + ucp_P, /* Punctuation */ + ucp_S, /* Symbol */ + ucp_Z /* Separator */ +}; + +/* These are the detailed character types that are returned by ucp_findchar */ + +enum { + ucp_Cc, /* Control */ + ucp_Cf, /* Format */ + ucp_Cn, /* Unassigned */ + ucp_Co, /* Private use */ + ucp_Cs, /* Surrogate */ + ucp_Ll, /* Lower case letter */ + ucp_Lm, /* Modifier letter */ + ucp_Lo, /* Other letter */ + ucp_Lt, /* Title case letter */ + ucp_Lu, /* Upper case letter */ + ucp_Mc, /* Spacing mark */ + ucp_Me, /* Enclosing mark */ + ucp_Mn, /* Non-spacing mark */ + ucp_Nd, /* Decimal number */ + ucp_Nl, /* Letter number */ + ucp_No, /* Other number */ + ucp_Pc, /* Connector punctuation */ + ucp_Pd, /* Dash punctuation */ + ucp_Pe, /* Close punctuation */ + ucp_Pf, /* Final punctuation */ + ucp_Pi, /* Initial punctuation */ + ucp_Po, /* Other punctuation */ + ucp_Ps, /* Open punctuation */ + ucp_Sc, /* Currency symbol */ + ucp_Sk, /* Modifier symbol */ + ucp_Sm, /* Mathematical symbol */ + ucp_So, /* Other symbol */ + ucp_Zl, /* Line separator */ + ucp_Zp, /* Paragraph separator */ + ucp_Zs /* Space separator */ +}; + +/* For use in PCRE we make this function static so that there is no conflict if +PCRE is linked with an application that makes use of an external version - +assuming an external version is ever released... */ + +static int ucp_findchar(const int, int *, int *); + +/* End of ucp.h */ diff --git a/src/libs/resiprocate/contrib/pcre/ucpinternal.h b/src/libs/resiprocate/contrib/pcre/ucpinternal.h new file mode 100644 index 00000000..faefb030 --- /dev/null +++ b/src/libs/resiprocate/contrib/pcre/ucpinternal.h @@ -0,0 +1,91 @@ +/************************************************* +* libucp - Unicode Property Table handler * +*************************************************/ + +/* Internal header file defining the layout of compact nodes in the tree. */ + +typedef struct cnode { + unsigned short int f0; + unsigned short int f1; + unsigned short int f2; +} cnode; + +/* Things for the f0 field */ + +#define f0_leftexists 0x8000 /* Left child exists */ +#define f0_typemask 0x3f00 /* Type bits */ +#define f0_typeshift 8 /* Type shift */ +#define f0_chhmask 0x00ff /* Character high bits */ + +/* Things for the f2 field */ + +#define f2_rightmask 0xf000 /* Mask for right offset bits */ +#define f2_rightshift 12 /* Shift for right offset */ +#define f2_casemask 0x0fff /* Mask for case offset */ + +/* The tree consists of a vector of structures of type cnode, with the root +node as the first element. The three short ints (16-bits) are used as follows: + +(f0) (1) The 0x8000 bit of f0 is set if a left child exists. The child's node + is the next node in the vector. + (2) The 0x4000 bits of f0 is spare. + (3) The 0x3f00 bits of f0 contain the character type; this is a number + defined by the enumeration in ucp.h (e.g. ucp_Lu). + (4) The bottom 8 bits of f0 contain the most significant byte of the + character's 24-bit codepoint. + +(f1) (1) The f1 field contains the two least significant bytes of the + codepoint. + +(f2) (1) The 0xf000 bits of f2 contain zero if there is no right child of this + node. Otherwise, they contain one plus the exponent of the power of + two of the offset to the right node (e.g. a value of 3 means 8). The + units of the offset are node items. + + (2) The 0x0fff bits of f2 contain the signed offset from this character to + its alternate cased value. They are zero if there is no such + character. + + +----------------------------------------------------------------------------- +||.|.| type (6) | ms char (8) || ls char (16) ||....| case offset (12) || +----------------------------------------------------------------------------- + | | | + | |-> spare | + | exponent of right + |-> left child exists child offset + + +The upper/lower casing information is set only for characters that come in +pairs. There are (at present) four non-one-to-one mappings in the Unicode data. +These are ignored. They are: + + 1FBE Greek Prosgegrammeni (lower, with upper -> capital iota) + 2126 Ohm + 212A Kelvin + 212B Angstrom + +Certainly for the last three, having an alternate case would seem to be a +mistake. I don't know any Greek, so cannot comment on the first one. + + +When searching the tree, proceed as follows: + +(1) Start at the first node. + +(2) Extract the character value from f1 and the bottom 8 bits of f0; + +(3) Compare with the character being sought. If equal, we are done. + +(4) If the test character is smaller, inspect the f0_leftexists flag. If it is + not set, the character is not in the tree. If it is set, move to the next + node, and go to (2). + +(5) If the test character is bigger, extract the f2_rightmask bits from f2, and + shift them right by f2_rightshift. If the result is zero, the character is + not in the tree. Otherwise, calculate the number of nodes to skip by + shifting the value 1 left by this number minus one. Go to (2). +*/ + + +/* End of internal.h */ diff --git a/src/libs/resiprocate/contrib/pcre/ucptable.c b/src/libs/resiprocate/contrib/pcre/ucptable.c new file mode 100644 index 00000000..7fb3a123 --- /dev/null +++ b/src/libs/resiprocate/contrib/pcre/ucptable.c @@ -0,0 +1,15105 @@ +/* This source module is automatically generated from the Unicode +property table. See internal.h for a description of the layout. */ + +static cnode ucp_table[] = { + { 0x9a00, 0x2f1f, 0xe000 }, + { 0x8700, 0x1558, 0xd000 }, + { 0x8700, 0x0a99, 0xc000 }, + { 0x8500, 0x0435, 0xbfe0 }, + { 0x8500, 0x01ff, 0xafff }, + { 0x8500, 0x00ff, 0x9079 }, + { 0x8000, 0x007f, 0x8000 }, + { 0x9500, 0x003f, 0x7000 }, + { 0x8000, 0x001f, 0x6000 }, + { 0x8000, 0x000f, 0x5000 }, + { 0x8000, 0x0007, 0x4000 }, + { 0x8000, 0x0003, 0x3000 }, + { 0x8000, 0x0001, 0x2000 }, + { 0x0000, 0x0000, 0x0000 }, + { 0x0000, 0x0002, 0x0000 }, + { 0x8000, 0x0005, 0x2000 }, + { 0x0000, 0x0004, 0x0000 }, + { 0x0000, 0x0006, 0x0000 }, + { 0x8000, 0x000b, 0x3000 }, + { 0x8000, 0x0009, 0x2000 }, + { 0x0000, 0x0008, 0x0000 }, + { 0x0000, 0x000a, 0x0000 }, + { 0x8000, 0x000d, 0x2000 }, + { 0x0000, 0x000c, 0x0000 }, + { 0x0000, 0x000e, 0x0000 }, + { 0x8000, 0x0017, 0x4000 }, + { 0x8000, 0x0013, 0x3000 }, + { 0x8000, 0x0011, 0x2000 }, + { 0x0000, 0x0010, 0x0000 }, + { 0x0000, 0x0012, 0x0000 }, + { 0x8000, 0x0015, 0x2000 }, + { 0x0000, 0x0014, 0x0000 }, + { 0x0000, 0x0016, 0x0000 }, + { 0x8000, 0x001b, 0x3000 }, + { 0x8000, 0x0019, 0x2000 }, + { 0x0000, 0x0018, 0x0000 }, + { 0x0000, 0x001a, 0x0000 }, + { 0x8000, 0x001d, 0x2000 }, + { 0x0000, 0x001c, 0x0000 }, + { 0x0000, 0x001e, 0x0000 }, + { 0x9500, 0x002f, 0x5000 }, + { 0x9500, 0x0027, 0x4000 }, + { 0x9500, 0x0023, 0x3000 }, + { 0x9500, 0x0021, 0x2000 }, + { 0x1d00, 0x0020, 0x0000 }, + { 0x1500, 0x0022, 0x0000 }, + { 0x9500, 0x0025, 0x2000 }, + { 0x1700, 0x0024, 0x0000 }, + { 0x1500, 0x0026, 0x0000 }, + { 0x9900, 0x002b, 0x3000 }, + { 0x9200, 0x0029, 0x2000 }, + { 0x1600, 0x0028, 0x0000 }, + { 0x1500, 0x002a, 0x0000 }, + { 0x9100, 0x002d, 0x2000 }, + { 0x1500, 0x002c, 0x0000 }, + { 0x1500, 0x002e, 0x0000 }, + { 0x8d00, 0x0037, 0x4000 }, + { 0x8d00, 0x0033, 0x3000 }, + { 0x8d00, 0x0031, 0x2000 }, + { 0x0d00, 0x0030, 0x0000 }, + { 0x0d00, 0x0032, 0x0000 }, + { 0x8d00, 0x0035, 0x2000 }, + { 0x0d00, 0x0034, 0x0000 }, + { 0x0d00, 0x0036, 0x0000 }, + { 0x9500, 0x003b, 0x3000 }, + { 0x8d00, 0x0039, 0x2000 }, + { 0x0d00, 0x0038, 0x0000 }, + { 0x1500, 0x003a, 0x0000 }, + { 0x9900, 0x003d, 0x2000 }, + { 0x1900, 0x003c, 0x0000 }, + { 0x1900, 0x003e, 0x0000 }, + { 0x9000, 0x005f, 0x6000 }, + { 0x8900, 0x004f, 0x5020 }, + { 0x8900, 0x0047, 0x4020 }, + { 0x8900, 0x0043, 0x3020 }, + { 0x8900, 0x0041, 0x2020 }, + { 0x1500, 0x0040, 0x0000 }, + { 0x0900, 0x0042, 0x0020 }, + { 0x8900, 0x0045, 0x2020 }, + { 0x0900, 0x0044, 0x0020 }, + { 0x0900, 0x0046, 0x0020 }, + { 0x8900, 0x004b, 0x3020 }, + { 0x8900, 0x0049, 0x2020 }, + { 0x0900, 0x0048, 0x0020 }, + { 0x0900, 0x004a, 0x0020 }, + { 0x8900, 0x004d, 0x2020 }, + { 0x0900, 0x004c, 0x0020 }, + { 0x0900, 0x004e, 0x0020 }, + { 0x8900, 0x0057, 0x4020 }, + { 0x8900, 0x0053, 0x3020 }, + { 0x8900, 0x0051, 0x2020 }, + { 0x0900, 0x0050, 0x0020 }, + { 0x0900, 0x0052, 0x0020 }, + { 0x8900, 0x0055, 0x2020 }, + { 0x0900, 0x0054, 0x0020 }, + { 0x0900, 0x0056, 0x0020 }, + { 0x9600, 0x005b, 0x3000 }, + { 0x8900, 0x0059, 0x2020 }, + { 0x0900, 0x0058, 0x0020 }, + { 0x0900, 0x005a, 0x0020 }, + { 0x9200, 0x005d, 0x2000 }, + { 0x1500, 0x005c, 0x0000 }, + { 0x1800, 0x005e, 0x0000 }, + { 0x8500, 0x006f, 0x5fe0 }, + { 0x8500, 0x0067, 0x4fe0 }, + { 0x8500, 0x0063, 0x3fe0 }, + { 0x8500, 0x0061, 0x2fe0 }, + { 0x1800, 0x0060, 0x0000 }, + { 0x0500, 0x0062, 0x0fe0 }, + { 0x8500, 0x0065, 0x2fe0 }, + { 0x0500, 0x0064, 0x0fe0 }, + { 0x0500, 0x0066, 0x0fe0 }, + { 0x8500, 0x006b, 0x3fe0 }, + { 0x8500, 0x0069, 0x2fe0 }, + { 0x0500, 0x0068, 0x0fe0 }, + { 0x0500, 0x006a, 0x0fe0 }, + { 0x8500, 0x006d, 0x2fe0 }, + { 0x0500, 0x006c, 0x0fe0 }, + { 0x0500, 0x006e, 0x0fe0 }, + { 0x8500, 0x0077, 0x4fe0 }, + { 0x8500, 0x0073, 0x3fe0 }, + { 0x8500, 0x0071, 0x2fe0 }, + { 0x0500, 0x0070, 0x0fe0 }, + { 0x0500, 0x0072, 0x0fe0 }, + { 0x8500, 0x0075, 0x2fe0 }, + { 0x0500, 0x0074, 0x0fe0 }, + { 0x0500, 0x0076, 0x0fe0 }, + { 0x9600, 0x007b, 0x3000 }, + { 0x8500, 0x0079, 0x2fe0 }, + { 0x0500, 0x0078, 0x0fe0 }, + { 0x0500, 0x007a, 0x0fe0 }, + { 0x9200, 0x007d, 0x2000 }, + { 0x1900, 0x007c, 0x0000 }, + { 0x1900, 0x007e, 0x0000 }, + { 0x9500, 0x00bf, 0x7000 }, + { 0x8000, 0x009f, 0x6000 }, + { 0x8000, 0x008f, 0x5000 }, + { 0x8000, 0x0087, 0x4000 }, + { 0x8000, 0x0083, 0x3000 }, + { 0x8000, 0x0081, 0x2000 }, + { 0x0000, 0x0080, 0x0000 }, + { 0x0000, 0x0082, 0x0000 }, + { 0x8000, 0x0085, 0x2000 }, + { 0x0000, 0x0084, 0x0000 }, + { 0x0000, 0x0086, 0x0000 }, + { 0x8000, 0x008b, 0x3000 }, + { 0x8000, 0x0089, 0x2000 }, + { 0x0000, 0x0088, 0x0000 }, + { 0x0000, 0x008a, 0x0000 }, + { 0x8000, 0x008d, 0x2000 }, + { 0x0000, 0x008c, 0x0000 }, + { 0x0000, 0x008e, 0x0000 }, + { 0x8000, 0x0097, 0x4000 }, + { 0x8000, 0x0093, 0x3000 }, + { 0x8000, 0x0091, 0x2000 }, + { 0x0000, 0x0090, 0x0000 }, + { 0x0000, 0x0092, 0x0000 }, + { 0x8000, 0x0095, 0x2000 }, + { 0x0000, 0x0094, 0x0000 }, + { 0x0000, 0x0096, 0x0000 }, + { 0x8000, 0x009b, 0x3000 }, + { 0x8000, 0x0099, 0x2000 }, + { 0x0000, 0x0098, 0x0000 }, + { 0x0000, 0x009a, 0x0000 }, + { 0x8000, 0x009d, 0x2000 }, + { 0x0000, 0x009c, 0x0000 }, + { 0x0000, 0x009e, 0x0000 }, + { 0x9800, 0x00af, 0x5000 }, + { 0x9a00, 0x00a7, 0x4000 }, + { 0x9700, 0x00a3, 0x3000 }, + { 0x9500, 0x00a1, 0x2000 }, + { 0x1d00, 0x00a0, 0x0000 }, + { 0x1700, 0x00a2, 0x0000 }, + { 0x9700, 0x00a5, 0x2000 }, + { 0x1700, 0x00a4, 0x0000 }, + { 0x1a00, 0x00a6, 0x0000 }, + { 0x9400, 0x00ab, 0x3000 }, + { 0x9a00, 0x00a9, 0x2000 }, + { 0x1800, 0x00a8, 0x0000 }, + { 0x0500, 0x00aa, 0x0000 }, + { 0x8100, 0x00ad, 0x2000 }, + { 0x1900, 0x00ac, 0x0000 }, + { 0x1a00, 0x00ae, 0x0000 }, + { 0x9500, 0x00b7, 0x4000 }, + { 0x8f00, 0x00b3, 0x3000 }, + { 0x9900, 0x00b1, 0x2000 }, + { 0x1a00, 0x00b0, 0x0000 }, + { 0x0f00, 0x00b2, 0x0000 }, + { 0x8500, 0x00b5, 0x22e7 }, + { 0x1800, 0x00b4, 0x0000 }, + { 0x1a00, 0x00b6, 0x0000 }, + { 0x9300, 0x00bb, 0x3000 }, + { 0x8f00, 0x00b9, 0x2000 }, + { 0x1800, 0x00b8, 0x0000 }, + { 0x0500, 0x00ba, 0x0000 }, + { 0x8f00, 0x00bd, 0x2000 }, + { 0x0f00, 0x00bc, 0x0000 }, + { 0x0f00, 0x00be, 0x0000 }, + { 0x8500, 0x00df, 0x6000 }, + { 0x8900, 0x00cf, 0x5020 }, + { 0x8900, 0x00c7, 0x4020 }, + { 0x8900, 0x00c3, 0x3020 }, + { 0x8900, 0x00c1, 0x2020 }, + { 0x0900, 0x00c0, 0x0020 }, + { 0x0900, 0x00c2, 0x0020 }, + { 0x8900, 0x00c5, 0x2020 }, + { 0x0900, 0x00c4, 0x0020 }, + { 0x0900, 0x00c6, 0x0020 }, + { 0x8900, 0x00cb, 0x3020 }, + { 0x8900, 0x00c9, 0x2020 }, + { 0x0900, 0x00c8, 0x0020 }, + { 0x0900, 0x00ca, 0x0020 }, + { 0x8900, 0x00cd, 0x2020 }, + { 0x0900, 0x00cc, 0x0020 }, + { 0x0900, 0x00ce, 0x0020 }, + { 0x9900, 0x00d7, 0x4000 }, + { 0x8900, 0x00d3, 0x3020 }, + { 0x8900, 0x00d1, 0x2020 }, + { 0x0900, 0x00d0, 0x0020 }, + { 0x0900, 0x00d2, 0x0020 }, + { 0x8900, 0x00d5, 0x2020 }, + { 0x0900, 0x00d4, 0x0020 }, + { 0x0900, 0x00d6, 0x0020 }, + { 0x8900, 0x00db, 0x3020 }, + { 0x8900, 0x00d9, 0x2020 }, + { 0x0900, 0x00d8, 0x0020 }, + { 0x0900, 0x00da, 0x0020 }, + { 0x8900, 0x00dd, 0x2020 }, + { 0x0900, 0x00dc, 0x0020 }, + { 0x0900, 0x00de, 0x0020 }, + { 0x8500, 0x00ef, 0x5fe0 }, + { 0x8500, 0x00e7, 0x4fe0 }, + { 0x8500, 0x00e3, 0x3fe0 }, + { 0x8500, 0x00e1, 0x2fe0 }, + { 0x0500, 0x00e0, 0x0fe0 }, + { 0x0500, 0x00e2, 0x0fe0 }, + { 0x8500, 0x00e5, 0x2fe0 }, + { 0x0500, 0x00e4, 0x0fe0 }, + { 0x0500, 0x00e6, 0x0fe0 }, + { 0x8500, 0x00eb, 0x3fe0 }, + { 0x8500, 0x00e9, 0x2fe0 }, + { 0x0500, 0x00e8, 0x0fe0 }, + { 0x0500, 0x00ea, 0x0fe0 }, + { 0x8500, 0x00ed, 0x2fe0 }, + { 0x0500, 0x00ec, 0x0fe0 }, + { 0x0500, 0x00ee, 0x0fe0 }, + { 0x9900, 0x00f7, 0x4000 }, + { 0x8500, 0x00f3, 0x3fe0 }, + { 0x8500, 0x00f1, 0x2fe0 }, + { 0x0500, 0x00f0, 0x0fe0 }, + { 0x0500, 0x00f2, 0x0fe0 }, + { 0x8500, 0x00f5, 0x2fe0 }, + { 0x0500, 0x00f4, 0x0fe0 }, + { 0x0500, 0x00f6, 0x0fe0 }, + { 0x8500, 0x00fb, 0x3fe0 }, + { 0x8500, 0x00f9, 0x2fe0 }, + { 0x0500, 0x00f8, 0x0fe0 }, + { 0x0500, 0x00fa, 0x0fe0 }, + { 0x8500, 0x00fd, 0x2fe0 }, + { 0x0500, 0x00fc, 0x0fe0 }, + { 0x0500, 0x00fe, 0x0fe0 }, + { 0x8500, 0x017f, 0x8ed4 }, + { 0x8900, 0x013f, 0x7001 }, + { 0x8500, 0x011f, 0x6fff }, + { 0x8500, 0x010f, 0x5fff }, + { 0x8500, 0x0107, 0x4fff }, + { 0x8500, 0x0103, 0x3fff }, + { 0x8500, 0x0101, 0x2fff }, + { 0x0900, 0x0100, 0x0001 }, + { 0x0900, 0x0102, 0x0001 }, + { 0x8500, 0x0105, 0x2fff }, + { 0x0900, 0x0104, 0x0001 }, + { 0x0900, 0x0106, 0x0001 }, + { 0x8500, 0x010b, 0x3fff }, + { 0x8500, 0x0109, 0x2fff }, + { 0x0900, 0x0108, 0x0001 }, + { 0x0900, 0x010a, 0x0001 }, + { 0x8500, 0x010d, 0x2fff }, + { 0x0900, 0x010c, 0x0001 }, + { 0x0900, 0x010e, 0x0001 }, + { 0x8500, 0x0117, 0x4fff }, + { 0x8500, 0x0113, 0x3fff }, + { 0x8500, 0x0111, 0x2fff }, + { 0x0900, 0x0110, 0x0001 }, + { 0x0900, 0x0112, 0x0001 }, + { 0x8500, 0x0115, 0x2fff }, + { 0x0900, 0x0114, 0x0001 }, + { 0x0900, 0x0116, 0x0001 }, + { 0x8500, 0x011b, 0x3fff }, + { 0x8500, 0x0119, 0x2fff }, + { 0x0900, 0x0118, 0x0001 }, + { 0x0900, 0x011a, 0x0001 }, + { 0x8500, 0x011d, 0x2fff }, + { 0x0900, 0x011c, 0x0001 }, + { 0x0900, 0x011e, 0x0001 }, + { 0x8500, 0x012f, 0x5fff }, + { 0x8500, 0x0127, 0x4fff }, + { 0x8500, 0x0123, 0x3fff }, + { 0x8500, 0x0121, 0x2fff }, + { 0x0900, 0x0120, 0x0001 }, + { 0x0900, 0x0122, 0x0001 }, + { 0x8500, 0x0125, 0x2fff }, + { 0x0900, 0x0124, 0x0001 }, + { 0x0900, 0x0126, 0x0001 }, + { 0x8500, 0x012b, 0x3fff }, + { 0x8500, 0x0129, 0x2fff }, + { 0x0900, 0x0128, 0x0001 }, + { 0x0900, 0x012a, 0x0001 }, + { 0x8500, 0x012d, 0x2fff }, + { 0x0900, 0x012c, 0x0001 }, + { 0x0900, 0x012e, 0x0001 }, + { 0x8500, 0x0137, 0x4fff }, + { 0x8500, 0x0133, 0x3fff }, + { 0x8500, 0x0131, 0x2f18 }, + { 0x0900, 0x0130, 0x0f39 }, + { 0x0900, 0x0132, 0x0001 }, + { 0x8500, 0x0135, 0x2fff }, + { 0x0900, 0x0134, 0x0001 }, + { 0x0900, 0x0136, 0x0001 }, + { 0x8900, 0x013b, 0x3001 }, + { 0x8900, 0x0139, 0x2001 }, + { 0x0500, 0x0138, 0x0000 }, + { 0x0500, 0x013a, 0x0fff }, + { 0x8900, 0x013d, 0x2001 }, + { 0x0500, 0x013c, 0x0fff }, + { 0x0500, 0x013e, 0x0fff }, + { 0x8500, 0x015f, 0x6fff }, + { 0x8500, 0x014f, 0x5fff }, + { 0x8900, 0x0147, 0x4001 }, + { 0x8900, 0x0143, 0x3001 }, + { 0x8900, 0x0141, 0x2001 }, + { 0x0500, 0x0140, 0x0fff }, + { 0x0500, 0x0142, 0x0fff }, + { 0x8900, 0x0145, 0x2001 }, + { 0x0500, 0x0144, 0x0fff }, + { 0x0500, 0x0146, 0x0fff }, + { 0x8500, 0x014b, 0x3fff }, + { 0x8500, 0x0149, 0x2000 }, + { 0x0500, 0x0148, 0x0fff }, + { 0x0900, 0x014a, 0x0001 }, + { 0x8500, 0x014d, 0x2fff }, + { 0x0900, 0x014c, 0x0001 }, + { 0x0900, 0x014e, 0x0001 }, + { 0x8500, 0x0157, 0x4fff }, + { 0x8500, 0x0153, 0x3fff }, + { 0x8500, 0x0151, 0x2fff }, + { 0x0900, 0x0150, 0x0001 }, + { 0x0900, 0x0152, 0x0001 }, + { 0x8500, 0x0155, 0x2fff }, + { 0x0900, 0x0154, 0x0001 }, + { 0x0900, 0x0156, 0x0001 }, + { 0x8500, 0x015b, 0x3fff }, + { 0x8500, 0x0159, 0x2fff }, + { 0x0900, 0x0158, 0x0001 }, + { 0x0900, 0x015a, 0x0001 }, + { 0x8500, 0x015d, 0x2fff }, + { 0x0900, 0x015c, 0x0001 }, + { 0x0900, 0x015e, 0x0001 }, + { 0x8500, 0x016f, 0x5fff }, + { 0x8500, 0x0167, 0x4fff }, + { 0x8500, 0x0163, 0x3fff }, + { 0x8500, 0x0161, 0x2fff }, + { 0x0900, 0x0160, 0x0001 }, + { 0x0900, 0x0162, 0x0001 }, + { 0x8500, 0x0165, 0x2fff }, + { 0x0900, 0x0164, 0x0001 }, + { 0x0900, 0x0166, 0x0001 }, + { 0x8500, 0x016b, 0x3fff }, + { 0x8500, 0x0169, 0x2fff }, + { 0x0900, 0x0168, 0x0001 }, + { 0x0900, 0x016a, 0x0001 }, + { 0x8500, 0x016d, 0x2fff }, + { 0x0900, 0x016c, 0x0001 }, + { 0x0900, 0x016e, 0x0001 }, + { 0x8500, 0x0177, 0x4fff }, + { 0x8500, 0x0173, 0x3fff }, + { 0x8500, 0x0171, 0x2fff }, + { 0x0900, 0x0170, 0x0001 }, + { 0x0900, 0x0172, 0x0001 }, + { 0x8500, 0x0175, 0x2fff }, + { 0x0900, 0x0174, 0x0001 }, + { 0x0900, 0x0176, 0x0001 }, + { 0x8900, 0x017b, 0x3001 }, + { 0x8900, 0x0179, 0x2001 }, + { 0x0900, 0x0178, 0x0f87 }, + { 0x0500, 0x017a, 0x0fff }, + { 0x8900, 0x017d, 0x2001 }, + { 0x0500, 0x017c, 0x0fff }, + { 0x0500, 0x017e, 0x0fff }, + { 0x8500, 0x01bf, 0x7038 }, + { 0x8900, 0x019f, 0x60d6 }, + { 0x8900, 0x018f, 0x50ca }, + { 0x8900, 0x0187, 0x4001 }, + { 0x8500, 0x0183, 0x3fff }, + { 0x8900, 0x0181, 0x20d2 }, + { 0x0500, 0x0180, 0x0000 }, + { 0x0900, 0x0182, 0x0001 }, + { 0x8500, 0x0185, 0x2fff }, + { 0x0900, 0x0184, 0x0001 }, + { 0x0900, 0x0186, 0x00ce }, + { 0x8900, 0x018b, 0x3001 }, + { 0x8900, 0x0189, 0x20cd }, + { 0x0500, 0x0188, 0x0fff }, + { 0x0900, 0x018a, 0x00cd }, + { 0x8500, 0x018d, 0x2000 }, + { 0x0500, 0x018c, 0x0fff }, + { 0x0900, 0x018e, 0x004f }, + { 0x8900, 0x0197, 0x40d1 }, + { 0x8900, 0x0193, 0x30cd }, + { 0x8900, 0x0191, 0x2001 }, + { 0x0900, 0x0190, 0x00cb }, + { 0x0500, 0x0192, 0x0fff }, + { 0x8500, 0x0195, 0x2061 }, + { 0x0900, 0x0194, 0x00cf }, + { 0x0900, 0x0196, 0x00d3 }, + { 0x8500, 0x019b, 0x3000 }, + { 0x8500, 0x0199, 0x2fff }, + { 0x0900, 0x0198, 0x0001 }, + { 0x0500, 0x019a, 0x0000 }, + { 0x8900, 0x019d, 0x20d5 }, + { 0x0900, 0x019c, 0x00d3 }, + { 0x0500, 0x019e, 0x0082 }, + { 0x8900, 0x01af, 0x5001 }, + { 0x8900, 0x01a7, 0x4001 }, + { 0x8500, 0x01a3, 0x3fff }, + { 0x8500, 0x01a1, 0x2fff }, + { 0x0900, 0x01a0, 0x0001 }, + { 0x0900, 0x01a2, 0x0001 }, + { 0x8500, 0x01a5, 0x2fff }, + { 0x0900, 0x01a4, 0x0001 }, + { 0x0900, 0x01a6, 0x00da }, + { 0x8500, 0x01ab, 0x3000 }, + { 0x8900, 0x01a9, 0x20da }, + { 0x0500, 0x01a8, 0x0fff }, + { 0x0500, 0x01aa, 0x0000 }, + { 0x8500, 0x01ad, 0x2fff }, + { 0x0900, 0x01ac, 0x0001 }, + { 0x0900, 0x01ae, 0x00da }, + { 0x8900, 0x01b7, 0x40db }, + { 0x8900, 0x01b3, 0x3001 }, + { 0x8900, 0x01b1, 0x20d9 }, + { 0x0500, 0x01b0, 0x0fff }, + { 0x0900, 0x01b2, 0x00d9 }, + { 0x8900, 0x01b5, 0x2001 }, + { 0x0500, 0x01b4, 0x0fff }, + { 0x0500, 0x01b6, 0x0fff }, + { 0x8700, 0x01bb, 0x3000 }, + { 0x8500, 0x01b9, 0x2fff }, + { 0x0900, 0x01b8, 0x0001 }, + { 0x0500, 0x01ba, 0x0000 }, + { 0x8500, 0x01bd, 0x2fff }, + { 0x0900, 0x01bc, 0x0001 }, + { 0x0500, 0x01be, 0x0000 }, + { 0x8500, 0x01df, 0x6fff }, + { 0x8900, 0x01cf, 0x5001 }, + { 0x8900, 0x01c7, 0x4002 }, + { 0x8700, 0x01c3, 0x3000 }, + { 0x8700, 0x01c1, 0x2000 }, + { 0x0700, 0x01c0, 0x0000 }, + { 0x0700, 0x01c2, 0x0000 }, + { 0x8800, 0x01c5, 0x2000 }, + { 0x0900, 0x01c4, 0x0002 }, + { 0x0500, 0x01c6, 0x0ffe }, + { 0x8800, 0x01cb, 0x3000 }, + { 0x8500, 0x01c9, 0x2ffe }, + { 0x0800, 0x01c8, 0x0000 }, + { 0x0900, 0x01ca, 0x0002 }, + { 0x8900, 0x01cd, 0x2001 }, + { 0x0500, 0x01cc, 0x0ffe }, + { 0x0500, 0x01ce, 0x0fff }, + { 0x8900, 0x01d7, 0x4001 }, + { 0x8900, 0x01d3, 0x3001 }, + { 0x8900, 0x01d1, 0x2001 }, + { 0x0500, 0x01d0, 0x0fff }, + { 0x0500, 0x01d2, 0x0fff }, + { 0x8900, 0x01d5, 0x2001 }, + { 0x0500, 0x01d4, 0x0fff }, + { 0x0500, 0x01d6, 0x0fff }, + { 0x8900, 0x01db, 0x3001 }, + { 0x8900, 0x01d9, 0x2001 }, + { 0x0500, 0x01d8, 0x0fff }, + { 0x0500, 0x01da, 0x0fff }, + { 0x8500, 0x01dd, 0x2fb1 }, + { 0x0500, 0x01dc, 0x0fff }, + { 0x0900, 0x01de, 0x0001 }, + { 0x8500, 0x01ef, 0x5fff }, + { 0x8500, 0x01e7, 0x4fff }, + { 0x8500, 0x01e3, 0x3fff }, + { 0x8500, 0x01e1, 0x2fff }, + { 0x0900, 0x01e0, 0x0001 }, + { 0x0900, 0x01e2, 0x0001 }, + { 0x8500, 0x01e5, 0x2fff }, + { 0x0900, 0x01e4, 0x0001 }, + { 0x0900, 0x01e6, 0x0001 }, + { 0x8500, 0x01eb, 0x3fff }, + { 0x8500, 0x01e9, 0x2fff }, + { 0x0900, 0x01e8, 0x0001 }, + { 0x0900, 0x01ea, 0x0001 }, + { 0x8500, 0x01ed, 0x2fff }, + { 0x0900, 0x01ec, 0x0001 }, + { 0x0900, 0x01ee, 0x0001 }, + { 0x8900, 0x01f7, 0x4fc8 }, + { 0x8500, 0x01f3, 0x3ffe }, + { 0x8900, 0x01f1, 0x2002 }, + { 0x0500, 0x01f0, 0x0000 }, + { 0x0800, 0x01f2, 0x0000 }, + { 0x8500, 0x01f5, 0x2fff }, + { 0x0900, 0x01f4, 0x0001 }, + { 0x0900, 0x01f6, 0x0f9f }, + { 0x8500, 0x01fb, 0x3fff }, + { 0x8500, 0x01f9, 0x2fff }, + { 0x0900, 0x01f8, 0x0001 }, + { 0x0900, 0x01fa, 0x0001 }, + { 0x8500, 0x01fd, 0x2fff }, + { 0x0900, 0x01fc, 0x0001 }, + { 0x0900, 0x01fe, 0x0001 }, + { 0x8c00, 0x0318, 0x9000 }, + { 0x8500, 0x0298, 0x8000 }, + { 0x8500, 0x0258, 0x7000 }, + { 0x8500, 0x021f, 0x6fff }, + { 0x8500, 0x020f, 0x5fff }, + { 0x8500, 0x0207, 0x4fff }, + { 0x8500, 0x0203, 0x3fff }, + { 0x8500, 0x0201, 0x2fff }, + { 0x0900, 0x0200, 0x0001 }, + { 0x0900, 0x0202, 0x0001 }, + { 0x8500, 0x0205, 0x2fff }, + { 0x0900, 0x0204, 0x0001 }, + { 0x0900, 0x0206, 0x0001 }, + { 0x8500, 0x020b, 0x3fff }, + { 0x8500, 0x0209, 0x2fff }, + { 0x0900, 0x0208, 0x0001 }, + { 0x0900, 0x020a, 0x0001 }, + { 0x8500, 0x020d, 0x2fff }, + { 0x0900, 0x020c, 0x0001 }, + { 0x0900, 0x020e, 0x0001 }, + { 0x8500, 0x0217, 0x4fff }, + { 0x8500, 0x0213, 0x3fff }, + { 0x8500, 0x0211, 0x2fff }, + { 0x0900, 0x0210, 0x0001 }, + { 0x0900, 0x0212, 0x0001 }, + { 0x8500, 0x0215, 0x2fff }, + { 0x0900, 0x0214, 0x0001 }, + { 0x0900, 0x0216, 0x0001 }, + { 0x8500, 0x021b, 0x3fff }, + { 0x8500, 0x0219, 0x2fff }, + { 0x0900, 0x0218, 0x0001 }, + { 0x0900, 0x021a, 0x0001 }, + { 0x8500, 0x021d, 0x2fff }, + { 0x0900, 0x021c, 0x0001 }, + { 0x0900, 0x021e, 0x0001 }, + { 0x8500, 0x022f, 0x5fff }, + { 0x8500, 0x0227, 0x4fff }, + { 0x8500, 0x0223, 0x3fff }, + { 0x8500, 0x0221, 0x2000 }, + { 0x0900, 0x0220, 0x0f7e }, + { 0x0900, 0x0222, 0x0001 }, + { 0x8500, 0x0225, 0x2fff }, + { 0x0900, 0x0224, 0x0001 }, + { 0x0900, 0x0226, 0x0001 }, + { 0x8500, 0x022b, 0x3fff }, + { 0x8500, 0x0229, 0x2fff }, + { 0x0900, 0x0228, 0x0001 }, + { 0x0900, 0x022a, 0x0001 }, + { 0x8500, 0x022d, 0x2fff }, + { 0x0900, 0x022c, 0x0001 }, + { 0x0900, 0x022e, 0x0001 }, + { 0x8500, 0x0250, 0x4000 }, + { 0x8500, 0x0233, 0x3fff }, + { 0x8500, 0x0231, 0x2fff }, + { 0x0900, 0x0230, 0x0001 }, + { 0x0900, 0x0232, 0x0001 }, + { 0x8500, 0x0235, 0x2000 }, + { 0x0500, 0x0234, 0x0000 }, + { 0x0500, 0x0236, 0x0000 }, + { 0x8500, 0x0254, 0x3f32 }, + { 0x8500, 0x0252, 0x2000 }, + { 0x0500, 0x0251, 0x0000 }, + { 0x0500, 0x0253, 0x0f2e }, + { 0x8500, 0x0256, 0x2f33 }, + { 0x0500, 0x0255, 0x0000 }, + { 0x0500, 0x0257, 0x0f33 }, + { 0x8500, 0x0278, 0x6000 }, + { 0x8500, 0x0268, 0x5f2f }, + { 0x8500, 0x0260, 0x4f33 }, + { 0x8500, 0x025c, 0x3000 }, + { 0x8500, 0x025a, 0x2000 }, + { 0x0500, 0x0259, 0x0f36 }, + { 0x0500, 0x025b, 0x0f35 }, + { 0x8500, 0x025e, 0x2000 }, + { 0x0500, 0x025d, 0x0000 }, + { 0x0500, 0x025f, 0x0000 }, + { 0x8500, 0x0264, 0x3000 }, + { 0x8500, 0x0262, 0x2000 }, + { 0x0500, 0x0261, 0x0000 }, + { 0x0500, 0x0263, 0x0f31 }, + { 0x8500, 0x0266, 0x2000 }, + { 0x0500, 0x0265, 0x0000 }, + { 0x0500, 0x0267, 0x0000 }, + { 0x8500, 0x0270, 0x4000 }, + { 0x8500, 0x026c, 0x3000 }, + { 0x8500, 0x026a, 0x2000 }, + { 0x0500, 0x0269, 0x0f2d }, + { 0x0500, 0x026b, 0x0000 }, + { 0x8500, 0x026e, 0x2000 }, + { 0x0500, 0x026d, 0x0000 }, + { 0x0500, 0x026f, 0x0f2d }, + { 0x8500, 0x0274, 0x3000 }, + { 0x8500, 0x0272, 0x2f2b }, + { 0x0500, 0x0271, 0x0000 }, + { 0x0500, 0x0273, 0x0000 }, + { 0x8500, 0x0276, 0x2000 }, + { 0x0500, 0x0275, 0x0f2a }, + { 0x0500, 0x0277, 0x0000 }, + { 0x8500, 0x0288, 0x5f26 }, + { 0x8500, 0x0280, 0x4f26 }, + { 0x8500, 0x027c, 0x3000 }, + { 0x8500, 0x027a, 0x2000 }, + { 0x0500, 0x0279, 0x0000 }, + { 0x0500, 0x027b, 0x0000 }, + { 0x8500, 0x027e, 0x2000 }, + { 0x0500, 0x027d, 0x0000 }, + { 0x0500, 0x027f, 0x0000 }, + { 0x8500, 0x0284, 0x3000 }, + { 0x8500, 0x0282, 0x2000 }, + { 0x0500, 0x0281, 0x0000 }, + { 0x0500, 0x0283, 0x0f26 }, + { 0x8500, 0x0286, 0x2000 }, + { 0x0500, 0x0285, 0x0000 }, + { 0x0500, 0x0287, 0x0000 }, + { 0x8500, 0x0290, 0x4000 }, + { 0x8500, 0x028c, 0x3000 }, + { 0x8500, 0x028a, 0x2f27 }, + { 0x0500, 0x0289, 0x0000 }, + { 0x0500, 0x028b, 0x0f27 }, + { 0x8500, 0x028e, 0x2000 }, + { 0x0500, 0x028d, 0x0000 }, + { 0x0500, 0x028f, 0x0000 }, + { 0x8500, 0x0294, 0x3000 }, + { 0x8500, 0x0292, 0x2f25 }, + { 0x0500, 0x0291, 0x0000 }, + { 0x0500, 0x0293, 0x0000 }, + { 0x8500, 0x0296, 0x2000 }, + { 0x0500, 0x0295, 0x0000 }, + { 0x0500, 0x0297, 0x0000 }, + { 0x9800, 0x02d8, 0x7000 }, + { 0x8600, 0x02b8, 0x6000 }, + { 0x8500, 0x02a8, 0x5000 }, + { 0x8500, 0x02a0, 0x4000 }, + { 0x8500, 0x029c, 0x3000 }, + { 0x8500, 0x029a, 0x2000 }, + { 0x0500, 0x0299, 0x0000 }, + { 0x0500, 0x029b, 0x0000 }, + { 0x8500, 0x029e, 0x2000 }, + { 0x0500, 0x029d, 0x0000 }, + { 0x0500, 0x029f, 0x0000 }, + { 0x8500, 0x02a4, 0x3000 }, + { 0x8500, 0x02a2, 0x2000 }, + { 0x0500, 0x02a1, 0x0000 }, + { 0x0500, 0x02a3, 0x0000 }, + { 0x8500, 0x02a6, 0x2000 }, + { 0x0500, 0x02a5, 0x0000 }, + { 0x0500, 0x02a7, 0x0000 }, + { 0x8600, 0x02b0, 0x4000 }, + { 0x8500, 0x02ac, 0x3000 }, + { 0x8500, 0x02aa, 0x2000 }, + { 0x0500, 0x02a9, 0x0000 }, + { 0x0500, 0x02ab, 0x0000 }, + { 0x8500, 0x02ae, 0x2000 }, + { 0x0500, 0x02ad, 0x0000 }, + { 0x0500, 0x02af, 0x0000 }, + { 0x8600, 0x02b4, 0x3000 }, + { 0x8600, 0x02b2, 0x2000 }, + { 0x0600, 0x02b1, 0x0000 }, + { 0x0600, 0x02b3, 0x0000 }, + { 0x8600, 0x02b6, 0x2000 }, + { 0x0600, 0x02b5, 0x0000 }, + { 0x0600, 0x02b7, 0x0000 }, + { 0x8600, 0x02c8, 0x5000 }, + { 0x8600, 0x02c0, 0x4000 }, + { 0x8600, 0x02bc, 0x3000 }, + { 0x8600, 0x02ba, 0x2000 }, + { 0x0600, 0x02b9, 0x0000 }, + { 0x0600, 0x02bb, 0x0000 }, + { 0x8600, 0x02be, 0x2000 }, + { 0x0600, 0x02bd, 0x0000 }, + { 0x0600, 0x02bf, 0x0000 }, + { 0x9800, 0x02c4, 0x3000 }, + { 0x9800, 0x02c2, 0x2000 }, + { 0x0600, 0x02c1, 0x0000 }, + { 0x1800, 0x02c3, 0x0000 }, + { 0x8600, 0x02c6, 0x2000 }, + { 0x1800, 0x02c5, 0x0000 }, + { 0x0600, 0x02c7, 0x0000 }, + { 0x8600, 0x02d0, 0x4000 }, + { 0x8600, 0x02cc, 0x3000 }, + { 0x8600, 0x02ca, 0x2000 }, + { 0x0600, 0x02c9, 0x0000 }, + { 0x0600, 0x02cb, 0x0000 }, + { 0x8600, 0x02ce, 0x2000 }, + { 0x0600, 0x02cd, 0x0000 }, + { 0x0600, 0x02cf, 0x0000 }, + { 0x9800, 0x02d4, 0x3000 }, + { 0x9800, 0x02d2, 0x2000 }, + { 0x0600, 0x02d1, 0x0000 }, + { 0x1800, 0x02d3, 0x0000 }, + { 0x9800, 0x02d6, 0x2000 }, + { 0x1800, 0x02d5, 0x0000 }, + { 0x1800, 0x02d7, 0x0000 }, + { 0x9800, 0x02f8, 0x6000 }, + { 0x9800, 0x02e8, 0x5000 }, + { 0x8600, 0x02e0, 0x4000 }, + { 0x9800, 0x02dc, 0x3000 }, + { 0x9800, 0x02da, 0x2000 }, + { 0x1800, 0x02d9, 0x0000 }, + { 0x1800, 0x02db, 0x0000 }, + { 0x9800, 0x02de, 0x2000 }, + { 0x1800, 0x02dd, 0x0000 }, + { 0x1800, 0x02df, 0x0000 }, + { 0x8600, 0x02e4, 0x3000 }, + { 0x8600, 0x02e2, 0x2000 }, + { 0x0600, 0x02e1, 0x0000 }, + { 0x0600, 0x02e3, 0x0000 }, + { 0x9800, 0x02e6, 0x2000 }, + { 0x1800, 0x02e5, 0x0000 }, + { 0x1800, 0x02e7, 0x0000 }, + { 0x9800, 0x02f0, 0x4000 }, + { 0x9800, 0x02ec, 0x3000 }, + { 0x9800, 0x02ea, 0x2000 }, + { 0x1800, 0x02e9, 0x0000 }, + { 0x1800, 0x02eb, 0x0000 }, + { 0x8600, 0x02ee, 0x2000 }, + { 0x1800, 0x02ed, 0x0000 }, + { 0x1800, 0x02ef, 0x0000 }, + { 0x9800, 0x02f4, 0x3000 }, + { 0x9800, 0x02f2, 0x2000 }, + { 0x1800, 0x02f1, 0x0000 }, + { 0x1800, 0x02f3, 0x0000 }, + { 0x9800, 0x02f6, 0x2000 }, + { 0x1800, 0x02f5, 0x0000 }, + { 0x1800, 0x02f7, 0x0000 }, + { 0x8c00, 0x0308, 0x5000 }, + { 0x8c00, 0x0300, 0x4000 }, + { 0x9800, 0x02fc, 0x3000 }, + { 0x9800, 0x02fa, 0x2000 }, + { 0x1800, 0x02f9, 0x0000 }, + { 0x1800, 0x02fb, 0x0000 }, + { 0x9800, 0x02fe, 0x2000 }, + { 0x1800, 0x02fd, 0x0000 }, + { 0x1800, 0x02ff, 0x0000 }, + { 0x8c00, 0x0304, 0x3000 }, + { 0x8c00, 0x0302, 0x2000 }, + { 0x0c00, 0x0301, 0x0000 }, + { 0x0c00, 0x0303, 0x0000 }, + { 0x8c00, 0x0306, 0x2000 }, + { 0x0c00, 0x0305, 0x0000 }, + { 0x0c00, 0x0307, 0x0000 }, + { 0x8c00, 0x0310, 0x4000 }, + { 0x8c00, 0x030c, 0x3000 }, + { 0x8c00, 0x030a, 0x2000 }, + { 0x0c00, 0x0309, 0x0000 }, + { 0x0c00, 0x030b, 0x0000 }, + { 0x8c00, 0x030e, 0x2000 }, + { 0x0c00, 0x030d, 0x0000 }, + { 0x0c00, 0x030f, 0x0000 }, + { 0x8c00, 0x0314, 0x3000 }, + { 0x8c00, 0x0312, 0x2000 }, + { 0x0c00, 0x0311, 0x0000 }, + { 0x0c00, 0x0313, 0x0000 }, + { 0x8c00, 0x0316, 0x2000 }, + { 0x0c00, 0x0315, 0x0000 }, + { 0x0c00, 0x0317, 0x0000 }, + { 0x8500, 0x03b0, 0x8000 }, + { 0x8c00, 0x035d, 0x7000 }, + { 0x8c00, 0x0338, 0x6000 }, + { 0x8c00, 0x0328, 0x5000 }, + { 0x8c00, 0x0320, 0x4000 }, + { 0x8c00, 0x031c, 0x3000 }, + { 0x8c00, 0x031a, 0x2000 }, + { 0x0c00, 0x0319, 0x0000 }, + { 0x0c00, 0x031b, 0x0000 }, + { 0x8c00, 0x031e, 0x2000 }, + { 0x0c00, 0x031d, 0x0000 }, + { 0x0c00, 0x031f, 0x0000 }, + { 0x8c00, 0x0324, 0x3000 }, + { 0x8c00, 0x0322, 0x2000 }, + { 0x0c00, 0x0321, 0x0000 }, + { 0x0c00, 0x0323, 0x0000 }, + { 0x8c00, 0x0326, 0x2000 }, + { 0x0c00, 0x0325, 0x0000 }, + { 0x0c00, 0x0327, 0x0000 }, + { 0x8c00, 0x0330, 0x4000 }, + { 0x8c00, 0x032c, 0x3000 }, + { 0x8c00, 0x032a, 0x2000 }, + { 0x0c00, 0x0329, 0x0000 }, + { 0x0c00, 0x032b, 0x0000 }, + { 0x8c00, 0x032e, 0x2000 }, + { 0x0c00, 0x032d, 0x0000 }, + { 0x0c00, 0x032f, 0x0000 }, + { 0x8c00, 0x0334, 0x3000 }, + { 0x8c00, 0x0332, 0x2000 }, + { 0x0c00, 0x0331, 0x0000 }, + { 0x0c00, 0x0333, 0x0000 }, + { 0x8c00, 0x0336, 0x2000 }, + { 0x0c00, 0x0335, 0x0000 }, + { 0x0c00, 0x0337, 0x0000 }, + { 0x8c00, 0x0348, 0x5000 }, + { 0x8c00, 0x0340, 0x4000 }, + { 0x8c00, 0x033c, 0x3000 }, + { 0x8c00, 0x033a, 0x2000 }, + { 0x0c00, 0x0339, 0x0000 }, + { 0x0c00, 0x033b, 0x0000 }, + { 0x8c00, 0x033e, 0x2000 }, + { 0x0c00, 0x033d, 0x0000 }, + { 0x0c00, 0x033f, 0x0000 }, + { 0x8c00, 0x0344, 0x3000 }, + { 0x8c00, 0x0342, 0x2000 }, + { 0x0c00, 0x0341, 0x0000 }, + { 0x0c00, 0x0343, 0x0000 }, + { 0x8c00, 0x0346, 0x2000 }, + { 0x0c00, 0x0345, 0x0000 }, + { 0x0c00, 0x0347, 0x0000 }, + { 0x8c00, 0x0350, 0x4000 }, + { 0x8c00, 0x034c, 0x3000 }, + { 0x8c00, 0x034a, 0x2000 }, + { 0x0c00, 0x0349, 0x0000 }, + { 0x0c00, 0x034b, 0x0000 }, + { 0x8c00, 0x034e, 0x2000 }, + { 0x0c00, 0x034d, 0x0000 }, + { 0x0c00, 0x034f, 0x0000 }, + { 0x8c00, 0x0354, 0x3000 }, + { 0x8c00, 0x0352, 0x2000 }, + { 0x0c00, 0x0351, 0x0000 }, + { 0x0c00, 0x0353, 0x0000 }, + { 0x8c00, 0x0356, 0x2000 }, + { 0x0c00, 0x0355, 0x0000 }, + { 0x0c00, 0x0357, 0x0000 }, + { 0x8900, 0x038f, 0x603f }, + { 0x8c00, 0x036d, 0x5000 }, + { 0x8c00, 0x0365, 0x4000 }, + { 0x8c00, 0x0361, 0x3000 }, + { 0x8c00, 0x035f, 0x2000 }, + { 0x0c00, 0x035e, 0x0000 }, + { 0x0c00, 0x0360, 0x0000 }, + { 0x8c00, 0x0363, 0x2000 }, + { 0x0c00, 0x0362, 0x0000 }, + { 0x0c00, 0x0364, 0x0000 }, + { 0x8c00, 0x0369, 0x3000 }, + { 0x8c00, 0x0367, 0x2000 }, + { 0x0c00, 0x0366, 0x0000 }, + { 0x0c00, 0x0368, 0x0000 }, + { 0x8c00, 0x036b, 0x2000 }, + { 0x0c00, 0x036a, 0x0000 }, + { 0x0c00, 0x036c, 0x0000 }, + { 0x9800, 0x0385, 0x4000 }, + { 0x9800, 0x0375, 0x3000 }, + { 0x8c00, 0x036f, 0x2000 }, + { 0x0c00, 0x036e, 0x0000 }, + { 0x1800, 0x0374, 0x0000 }, + { 0x9500, 0x037e, 0x2000 }, + { 0x0600, 0x037a, 0x0000 }, + { 0x1800, 0x0384, 0x0000 }, + { 0x8900, 0x0389, 0x3025 }, + { 0x9500, 0x0387, 0x2000 }, + { 0x0900, 0x0386, 0x0026 }, + { 0x0900, 0x0388, 0x0025 }, + { 0x8900, 0x038c, 0x2040 }, + { 0x0900, 0x038a, 0x0025 }, + { 0x0900, 0x038e, 0x003f }, + { 0x8900, 0x039f, 0x5020 }, + { 0x8900, 0x0397, 0x4020 }, + { 0x8900, 0x0393, 0x3020 }, + { 0x8900, 0x0391, 0x2020 }, + { 0x0500, 0x0390, 0x0000 }, + { 0x0900, 0x0392, 0x0020 }, + { 0x8900, 0x0395, 0x2020 }, + { 0x0900, 0x0394, 0x0020 }, + { 0x0900, 0x0396, 0x0020 }, + { 0x8900, 0x039b, 0x3020 }, + { 0x8900, 0x0399, 0x2020 }, + { 0x0900, 0x0398, 0x0020 }, + { 0x0900, 0x039a, 0x0020 }, + { 0x8900, 0x039d, 0x2020 }, + { 0x0900, 0x039c, 0x0020 }, + { 0x0900, 0x039e, 0x0020 }, + { 0x8900, 0x03a8, 0x4020 }, + { 0x8900, 0x03a4, 0x3020 }, + { 0x8900, 0x03a1, 0x2020 }, + { 0x0900, 0x03a0, 0x0020 }, + { 0x0900, 0x03a3, 0x0020 }, + { 0x8900, 0x03a6, 0x2020 }, + { 0x0900, 0x03a5, 0x0020 }, + { 0x0900, 0x03a7, 0x0020 }, + { 0x8500, 0x03ac, 0x3fda }, + { 0x8900, 0x03aa, 0x2020 }, + { 0x0900, 0x03a9, 0x0020 }, + { 0x0900, 0x03ab, 0x0020 }, + { 0x8500, 0x03ae, 0x2fdb }, + { 0x0500, 0x03ad, 0x0fdb }, + { 0x0500, 0x03af, 0x0fdb }, + { 0x8500, 0x03f1, 0x7fb0 }, + { 0x8500, 0x03d1, 0x6fc7 }, + { 0x8500, 0x03c0, 0x5fe0 }, + { 0x8500, 0x03b8, 0x4fe0 }, + { 0x8500, 0x03b4, 0x3fe0 }, + { 0x8500, 0x03b2, 0x2fe0 }, + { 0x0500, 0x03b1, 0x0fe0 }, + { 0x0500, 0x03b3, 0x0fe0 }, + { 0x8500, 0x03b6, 0x2fe0 }, + { 0x0500, 0x03b5, 0x0fe0 }, + { 0x0500, 0x03b7, 0x0fe0 }, + { 0x8500, 0x03bc, 0x3fe0 }, + { 0x8500, 0x03ba, 0x2fe0 }, + { 0x0500, 0x03b9, 0x0fe0 }, + { 0x0500, 0x03bb, 0x0fe0 }, + { 0x8500, 0x03be, 0x2fe0 }, + { 0x0500, 0x03bd, 0x0fe0 }, + { 0x0500, 0x03bf, 0x0fe0 }, + { 0x8500, 0x03c8, 0x4fe0 }, + { 0x8500, 0x03c4, 0x3fe0 }, + { 0x8500, 0x03c2, 0x2fe1 }, + { 0x0500, 0x03c1, 0x0fe0 }, + { 0x0500, 0x03c3, 0x0fe0 }, + { 0x8500, 0x03c6, 0x2fe0 }, + { 0x0500, 0x03c5, 0x0fe0 }, + { 0x0500, 0x03c7, 0x0fe0 }, + { 0x8500, 0x03cc, 0x3fc0 }, + { 0x8500, 0x03ca, 0x2fe0 }, + { 0x0500, 0x03c9, 0x0fe0 }, + { 0x0500, 0x03cb, 0x0fe0 }, + { 0x8500, 0x03ce, 0x2fc1 }, + { 0x0500, 0x03cd, 0x0fc1 }, + { 0x0500, 0x03d0, 0x0fc2 }, + { 0x8500, 0x03e1, 0x5fff }, + { 0x8500, 0x03d9, 0x4fff }, + { 0x8500, 0x03d5, 0x3fd1 }, + { 0x8900, 0x03d3, 0x2000 }, + { 0x0900, 0x03d2, 0x0000 }, + { 0x0900, 0x03d4, 0x0000 }, + { 0x8500, 0x03d7, 0x2000 }, + { 0x0500, 0x03d6, 0x0fca }, + { 0x0900, 0x03d8, 0x0001 }, + { 0x8500, 0x03dd, 0x3fff }, + { 0x8500, 0x03db, 0x2fff }, + { 0x0900, 0x03da, 0x0001 }, + { 0x0900, 0x03dc, 0x0001 }, + { 0x8500, 0x03df, 0x2fff }, + { 0x0900, 0x03de, 0x0001 }, + { 0x0900, 0x03e0, 0x0001 }, + { 0x8500, 0x03e9, 0x4fff }, + { 0x8500, 0x03e5, 0x3fff }, + { 0x8500, 0x03e3, 0x2fff }, + { 0x0900, 0x03e2, 0x0001 }, + { 0x0900, 0x03e4, 0x0001 }, + { 0x8500, 0x03e7, 0x2fff }, + { 0x0900, 0x03e6, 0x0001 }, + { 0x0900, 0x03e8, 0x0001 }, + { 0x8500, 0x03ed, 0x3fff }, + { 0x8500, 0x03eb, 0x2fff }, + { 0x0900, 0x03ea, 0x0001 }, + { 0x0900, 0x03ec, 0x0001 }, + { 0x8500, 0x03ef, 0x2fff }, + { 0x0900, 0x03ee, 0x0001 }, + { 0x0500, 0x03f0, 0x0faa }, + { 0x8900, 0x0415, 0x6020 }, + { 0x8900, 0x0405, 0x5050 }, + { 0x8900, 0x03f9, 0x4ff9 }, + { 0x8500, 0x03f5, 0x3fa0 }, + { 0x8500, 0x03f3, 0x2000 }, + { 0x0500, 0x03f2, 0x0007 }, + { 0x0900, 0x03f4, 0x0fc4 }, + { 0x8900, 0x03f7, 0x2001 }, + { 0x1900, 0x03f6, 0x0000 }, + { 0x0500, 0x03f8, 0x0fff }, + { 0x8900, 0x0401, 0x3050 }, + { 0x8500, 0x03fb, 0x2fff }, + { 0x0900, 0x03fa, 0x0001 }, + { 0x0900, 0x0400, 0x0050 }, + { 0x8900, 0x0403, 0x2050 }, + { 0x0900, 0x0402, 0x0050 }, + { 0x0900, 0x0404, 0x0050 }, + { 0x8900, 0x040d, 0x4050 }, + { 0x8900, 0x0409, 0x3050 }, + { 0x8900, 0x0407, 0x2050 }, + { 0x0900, 0x0406, 0x0050 }, + { 0x0900, 0x0408, 0x0050 }, + { 0x8900, 0x040b, 0x2050 }, + { 0x0900, 0x040a, 0x0050 }, + { 0x0900, 0x040c, 0x0050 }, + { 0x8900, 0x0411, 0x3020 }, + { 0x8900, 0x040f, 0x2050 }, + { 0x0900, 0x040e, 0x0050 }, + { 0x0900, 0x0410, 0x0020 }, + { 0x8900, 0x0413, 0x2020 }, + { 0x0900, 0x0412, 0x0020 }, + { 0x0900, 0x0414, 0x0020 }, + { 0x8900, 0x0425, 0x5020 }, + { 0x8900, 0x041d, 0x4020 }, + { 0x8900, 0x0419, 0x3020 }, + { 0x8900, 0x0417, 0x2020 }, + { 0x0900, 0x0416, 0x0020 }, + { 0x0900, 0x0418, 0x0020 }, + { 0x8900, 0x041b, 0x2020 }, + { 0x0900, 0x041a, 0x0020 }, + { 0x0900, 0x041c, 0x0020 }, + { 0x8900, 0x0421, 0x3020 }, + { 0x8900, 0x041f, 0x2020 }, + { 0x0900, 0x041e, 0x0020 }, + { 0x0900, 0x0420, 0x0020 }, + { 0x8900, 0x0423, 0x2020 }, + { 0x0900, 0x0422, 0x0020 }, + { 0x0900, 0x0424, 0x0020 }, + { 0x8900, 0x042d, 0x4020 }, + { 0x8900, 0x0429, 0x3020 }, + { 0x8900, 0x0427, 0x2020 }, + { 0x0900, 0x0426, 0x0020 }, + { 0x0900, 0x0428, 0x0020 }, + { 0x8900, 0x042b, 0x2020 }, + { 0x0900, 0x042a, 0x0020 }, + { 0x0900, 0x042c, 0x0020 }, + { 0x8500, 0x0431, 0x3fe0 }, + { 0x8900, 0x042f, 0x2020 }, + { 0x0900, 0x042e, 0x0020 }, + { 0x0500, 0x0430, 0x0fe0 }, + { 0x8500, 0x0433, 0x2fe0 }, + { 0x0500, 0x0432, 0x0fe0 }, + { 0x0500, 0x0434, 0x0fe0 }, + { 0x8700, 0x06a4, 0xa000 }, + { 0x8500, 0x0563, 0x9fd0 }, + { 0x8900, 0x04b6, 0x8001 }, + { 0x8500, 0x0475, 0x7fff }, + { 0x8500, 0x0455, 0x6fb0 }, + { 0x8500, 0x0445, 0x5fe0 }, + { 0x8500, 0x043d, 0x4fe0 }, + { 0x8500, 0x0439, 0x3fe0 }, + { 0x8500, 0x0437, 0x2fe0 }, + { 0x0500, 0x0436, 0x0fe0 }, + { 0x0500, 0x0438, 0x0fe0 }, + { 0x8500, 0x043b, 0x2fe0 }, + { 0x0500, 0x043a, 0x0fe0 }, + { 0x0500, 0x043c, 0x0fe0 }, + { 0x8500, 0x0441, 0x3fe0 }, + { 0x8500, 0x043f, 0x2fe0 }, + { 0x0500, 0x043e, 0x0fe0 }, + { 0x0500, 0x0440, 0x0fe0 }, + { 0x8500, 0x0443, 0x2fe0 }, + { 0x0500, 0x0442, 0x0fe0 }, + { 0x0500, 0x0444, 0x0fe0 }, + { 0x8500, 0x044d, 0x4fe0 }, + { 0x8500, 0x0449, 0x3fe0 }, + { 0x8500, 0x0447, 0x2fe0 }, + { 0x0500, 0x0446, 0x0fe0 }, + { 0x0500, 0x0448, 0x0fe0 }, + { 0x8500, 0x044b, 0x2fe0 }, + { 0x0500, 0x044a, 0x0fe0 }, + { 0x0500, 0x044c, 0x0fe0 }, + { 0x8500, 0x0451, 0x3fb0 }, + { 0x8500, 0x044f, 0x2fe0 }, + { 0x0500, 0x044e, 0x0fe0 }, + { 0x0500, 0x0450, 0x0fb0 }, + { 0x8500, 0x0453, 0x2fb0 }, + { 0x0500, 0x0452, 0x0fb0 }, + { 0x0500, 0x0454, 0x0fb0 }, + { 0x8500, 0x0465, 0x5fff }, + { 0x8500, 0x045d, 0x4fb0 }, + { 0x8500, 0x0459, 0x3fb0 }, + { 0x8500, 0x0457, 0x2fb0 }, + { 0x0500, 0x0456, 0x0fb0 }, + { 0x0500, 0x0458, 0x0fb0 }, + { 0x8500, 0x045b, 0x2fb0 }, + { 0x0500, 0x045a, 0x0fb0 }, + { 0x0500, 0x045c, 0x0fb0 }, + { 0x8500, 0x0461, 0x3fff }, + { 0x8500, 0x045f, 0x2fb0 }, + { 0x0500, 0x045e, 0x0fb0 }, + { 0x0900, 0x0460, 0x0001 }, + { 0x8500, 0x0463, 0x2fff }, + { 0x0900, 0x0462, 0x0001 }, + { 0x0900, 0x0464, 0x0001 }, + { 0x8500, 0x046d, 0x4fff }, + { 0x8500, 0x0469, 0x3fff }, + { 0x8500, 0x0467, 0x2fff }, + { 0x0900, 0x0466, 0x0001 }, + { 0x0900, 0x0468, 0x0001 }, + { 0x8500, 0x046b, 0x2fff }, + { 0x0900, 0x046a, 0x0001 }, + { 0x0900, 0x046c, 0x0001 }, + { 0x8500, 0x0471, 0x3fff }, + { 0x8500, 0x046f, 0x2fff }, + { 0x0900, 0x046e, 0x0001 }, + { 0x0900, 0x0470, 0x0001 }, + { 0x8500, 0x0473, 0x2fff }, + { 0x0900, 0x0472, 0x0001 }, + { 0x0900, 0x0474, 0x0001 }, + { 0x8900, 0x0496, 0x6001 }, + { 0x8c00, 0x0485, 0x5000 }, + { 0x8500, 0x047d, 0x4fff }, + { 0x8500, 0x0479, 0x3fff }, + { 0x8500, 0x0477, 0x2fff }, + { 0x0900, 0x0476, 0x0001 }, + { 0x0900, 0x0478, 0x0001 }, + { 0x8500, 0x047b, 0x2fff }, + { 0x0900, 0x047a, 0x0001 }, + { 0x0900, 0x047c, 0x0001 }, + { 0x8500, 0x0481, 0x3fff }, + { 0x8500, 0x047f, 0x2fff }, + { 0x0900, 0x047e, 0x0001 }, + { 0x0900, 0x0480, 0x0001 }, + { 0x8c00, 0x0483, 0x2000 }, + { 0x1a00, 0x0482, 0x0000 }, + { 0x0c00, 0x0484, 0x0000 }, + { 0x8900, 0x048e, 0x4001 }, + { 0x8900, 0x048a, 0x3001 }, + { 0x8b00, 0x0488, 0x2000 }, + { 0x0c00, 0x0486, 0x0000 }, + { 0x0b00, 0x0489, 0x0000 }, + { 0x8900, 0x048c, 0x2001 }, + { 0x0500, 0x048b, 0x0fff }, + { 0x0500, 0x048d, 0x0fff }, + { 0x8900, 0x0492, 0x3001 }, + { 0x8900, 0x0490, 0x2001 }, + { 0x0500, 0x048f, 0x0fff }, + { 0x0500, 0x0491, 0x0fff }, + { 0x8900, 0x0494, 0x2001 }, + { 0x0500, 0x0493, 0x0fff }, + { 0x0500, 0x0495, 0x0fff }, + { 0x8900, 0x04a6, 0x5001 }, + { 0x8900, 0x049e, 0x4001 }, + { 0x8900, 0x049a, 0x3001 }, + { 0x8900, 0x0498, 0x2001 }, + { 0x0500, 0x0497, 0x0fff }, + { 0x0500, 0x0499, 0x0fff }, + { 0x8900, 0x049c, 0x2001 }, + { 0x0500, 0x049b, 0x0fff }, + { 0x0500, 0x049d, 0x0fff }, + { 0x8900, 0x04a2, 0x3001 }, + { 0x8900, 0x04a0, 0x2001 }, + { 0x0500, 0x049f, 0x0fff }, + { 0x0500, 0x04a1, 0x0fff }, + { 0x8900, 0x04a4, 0x2001 }, + { 0x0500, 0x04a3, 0x0fff }, + { 0x0500, 0x04a5, 0x0fff }, + { 0x8900, 0x04ae, 0x4001 }, + { 0x8900, 0x04aa, 0x3001 }, + { 0x8900, 0x04a8, 0x2001 }, + { 0x0500, 0x04a7, 0x0fff }, + { 0x0500, 0x04a9, 0x0fff }, + { 0x8900, 0x04ac, 0x2001 }, + { 0x0500, 0x04ab, 0x0fff }, + { 0x0500, 0x04ad, 0x0fff }, + { 0x8900, 0x04b2, 0x3001 }, + { 0x8900, 0x04b0, 0x2001 }, + { 0x0500, 0x04af, 0x0fff }, + { 0x0500, 0x04b1, 0x0fff }, + { 0x8900, 0x04b4, 0x2001 }, + { 0x0500, 0x04b3, 0x0fff }, + { 0x0500, 0x04b5, 0x0fff }, + { 0x8500, 0x04f9, 0x7fff }, + { 0x8500, 0x04d7, 0x6fff }, + { 0x8500, 0x04c6, 0x5fff }, + { 0x8900, 0x04be, 0x4001 }, + { 0x8900, 0x04ba, 0x3001 }, + { 0x8900, 0x04b8, 0x2001 }, + { 0x0500, 0x04b7, 0x0fff }, + { 0x0500, 0x04b9, 0x0fff }, + { 0x8900, 0x04bc, 0x2001 }, + { 0x0500, 0x04bb, 0x0fff }, + { 0x0500, 0x04bd, 0x0fff }, + { 0x8500, 0x04c2, 0x3fff }, + { 0x8900, 0x04c0, 0x2000 }, + { 0x0500, 0x04bf, 0x0fff }, + { 0x0900, 0x04c1, 0x0001 }, + { 0x8500, 0x04c4, 0x2fff }, + { 0x0900, 0x04c3, 0x0001 }, + { 0x0900, 0x04c5, 0x0001 }, + { 0x8500, 0x04ce, 0x4fff }, + { 0x8500, 0x04ca, 0x3fff }, + { 0x8500, 0x04c8, 0x2fff }, + { 0x0900, 0x04c7, 0x0001 }, + { 0x0900, 0x04c9, 0x0001 }, + { 0x8500, 0x04cc, 0x2fff }, + { 0x0900, 0x04cb, 0x0001 }, + { 0x0900, 0x04cd, 0x0001 }, + { 0x8500, 0x04d3, 0x3fff }, + { 0x8500, 0x04d1, 0x2fff }, + { 0x0900, 0x04d0, 0x0001 }, + { 0x0900, 0x04d2, 0x0001 }, + { 0x8500, 0x04d5, 0x2fff }, + { 0x0900, 0x04d4, 0x0001 }, + { 0x0900, 0x04d6, 0x0001 }, + { 0x8500, 0x04e7, 0x5fff }, + { 0x8500, 0x04df, 0x4fff }, + { 0x8500, 0x04db, 0x3fff }, + { 0x8500, 0x04d9, 0x2fff }, + { 0x0900, 0x04d8, 0x0001 }, + { 0x0900, 0x04da, 0x0001 }, + { 0x8500, 0x04dd, 0x2fff }, + { 0x0900, 0x04dc, 0x0001 }, + { 0x0900, 0x04de, 0x0001 }, + { 0x8500, 0x04e3, 0x3fff }, + { 0x8500, 0x04e1, 0x2fff }, + { 0x0900, 0x04e0, 0x0001 }, + { 0x0900, 0x04e2, 0x0001 }, + { 0x8500, 0x04e5, 0x2fff }, + { 0x0900, 0x04e4, 0x0001 }, + { 0x0900, 0x04e6, 0x0001 }, + { 0x8500, 0x04ef, 0x4fff }, + { 0x8500, 0x04eb, 0x3fff }, + { 0x8500, 0x04e9, 0x2fff }, + { 0x0900, 0x04e8, 0x0001 }, + { 0x0900, 0x04ea, 0x0001 }, + { 0x8500, 0x04ed, 0x2fff }, + { 0x0900, 0x04ec, 0x0001 }, + { 0x0900, 0x04ee, 0x0001 }, + { 0x8500, 0x04f3, 0x3fff }, + { 0x8500, 0x04f1, 0x2fff }, + { 0x0900, 0x04f0, 0x0001 }, + { 0x0900, 0x04f2, 0x0001 }, + { 0x8500, 0x04f5, 0x2fff }, + { 0x0900, 0x04f4, 0x0001 }, + { 0x0900, 0x04f8, 0x0001 }, + { 0x8900, 0x0540, 0x6030 }, + { 0x8500, 0x050f, 0x5fff }, + { 0x8500, 0x0507, 0x4fff }, + { 0x8500, 0x0503, 0x3fff }, + { 0x8500, 0x0501, 0x2fff }, + { 0x0900, 0x0500, 0x0001 }, + { 0x0900, 0x0502, 0x0001 }, + { 0x8500, 0x0505, 0x2fff }, + { 0x0900, 0x0504, 0x0001 }, + { 0x0900, 0x0506, 0x0001 }, + { 0x8500, 0x050b, 0x3fff }, + { 0x8500, 0x0509, 0x2fff }, + { 0x0900, 0x0508, 0x0001 }, + { 0x0900, 0x050a, 0x0001 }, + { 0x8500, 0x050d, 0x2fff }, + { 0x0900, 0x050c, 0x0001 }, + { 0x0900, 0x050e, 0x0001 }, + { 0x8900, 0x0538, 0x4030 }, + { 0x8900, 0x0534, 0x3030 }, + { 0x8900, 0x0532, 0x2030 }, + { 0x0900, 0x0531, 0x0030 }, + { 0x0900, 0x0533, 0x0030 }, + { 0x8900, 0x0536, 0x2030 }, + { 0x0900, 0x0535, 0x0030 }, + { 0x0900, 0x0537, 0x0030 }, + { 0x8900, 0x053c, 0x3030 }, + { 0x8900, 0x053a, 0x2030 }, + { 0x0900, 0x0539, 0x0030 }, + { 0x0900, 0x053b, 0x0030 }, + { 0x8900, 0x053e, 0x2030 }, + { 0x0900, 0x053d, 0x0030 }, + { 0x0900, 0x053f, 0x0030 }, + { 0x8900, 0x0550, 0x5030 }, + { 0x8900, 0x0548, 0x4030 }, + { 0x8900, 0x0544, 0x3030 }, + { 0x8900, 0x0542, 0x2030 }, + { 0x0900, 0x0541, 0x0030 }, + { 0x0900, 0x0543, 0x0030 }, + { 0x8900, 0x0546, 0x2030 }, + { 0x0900, 0x0545, 0x0030 }, + { 0x0900, 0x0547, 0x0030 }, + { 0x8900, 0x054c, 0x3030 }, + { 0x8900, 0x054a, 0x2030 }, + { 0x0900, 0x0549, 0x0030 }, + { 0x0900, 0x054b, 0x0030 }, + { 0x8900, 0x054e, 0x2030 }, + { 0x0900, 0x054d, 0x0030 }, + { 0x0900, 0x054f, 0x0030 }, + { 0x9500, 0x055a, 0x4000 }, + { 0x8900, 0x0554, 0x3030 }, + { 0x8900, 0x0552, 0x2030 }, + { 0x0900, 0x0551, 0x0030 }, + { 0x0900, 0x0553, 0x0030 }, + { 0x8900, 0x0556, 0x2030 }, + { 0x0900, 0x0555, 0x0030 }, + { 0x0600, 0x0559, 0x0000 }, + { 0x9500, 0x055e, 0x3000 }, + { 0x9500, 0x055c, 0x2000 }, + { 0x1500, 0x055b, 0x0000 }, + { 0x1500, 0x055d, 0x0000 }, + { 0x8500, 0x0561, 0x2fd0 }, + { 0x1500, 0x055f, 0x0000 }, + { 0x0500, 0x0562, 0x0fd0 }, + { 0x9a00, 0x060f, 0x8000 }, + { 0x8c00, 0x05ab, 0x7000 }, + { 0x8500, 0x0583, 0x6fd0 }, + { 0x8500, 0x0573, 0x5fd0 }, + { 0x8500, 0x056b, 0x4fd0 }, + { 0x8500, 0x0567, 0x3fd0 }, + { 0x8500, 0x0565, 0x2fd0 }, + { 0x0500, 0x0564, 0x0fd0 }, + { 0x0500, 0x0566, 0x0fd0 }, + { 0x8500, 0x0569, 0x2fd0 }, + { 0x0500, 0x0568, 0x0fd0 }, + { 0x0500, 0x056a, 0x0fd0 }, + { 0x8500, 0x056f, 0x3fd0 }, + { 0x8500, 0x056d, 0x2fd0 }, + { 0x0500, 0x056c, 0x0fd0 }, + { 0x0500, 0x056e, 0x0fd0 }, + { 0x8500, 0x0571, 0x2fd0 }, + { 0x0500, 0x0570, 0x0fd0 }, + { 0x0500, 0x0572, 0x0fd0 }, + { 0x8500, 0x057b, 0x4fd0 }, + { 0x8500, 0x0577, 0x3fd0 }, + { 0x8500, 0x0575, 0x2fd0 }, + { 0x0500, 0x0574, 0x0fd0 }, + { 0x0500, 0x0576, 0x0fd0 }, + { 0x8500, 0x0579, 0x2fd0 }, + { 0x0500, 0x0578, 0x0fd0 }, + { 0x0500, 0x057a, 0x0fd0 }, + { 0x8500, 0x057f, 0x3fd0 }, + { 0x8500, 0x057d, 0x2fd0 }, + { 0x0500, 0x057c, 0x0fd0 }, + { 0x0500, 0x057e, 0x0fd0 }, + { 0x8500, 0x0581, 0x2fd0 }, + { 0x0500, 0x0580, 0x0fd0 }, + { 0x0500, 0x0582, 0x0fd0 }, + { 0x8c00, 0x059a, 0x5000 }, + { 0x8c00, 0x0592, 0x4000 }, + { 0x8500, 0x0587, 0x3000 }, + { 0x8500, 0x0585, 0x2fd0 }, + { 0x0500, 0x0584, 0x0fd0 }, + { 0x0500, 0x0586, 0x0fd0 }, + { 0x9100, 0x058a, 0x2000 }, + { 0x1500, 0x0589, 0x0000 }, + { 0x0c00, 0x0591, 0x0000 }, + { 0x8c00, 0x0596, 0x3000 }, + { 0x8c00, 0x0594, 0x2000 }, + { 0x0c00, 0x0593, 0x0000 }, + { 0x0c00, 0x0595, 0x0000 }, + { 0x8c00, 0x0598, 0x2000 }, + { 0x0c00, 0x0597, 0x0000 }, + { 0x0c00, 0x0599, 0x0000 }, + { 0x8c00, 0x05a3, 0x4000 }, + { 0x8c00, 0x059e, 0x3000 }, + { 0x8c00, 0x059c, 0x2000 }, + { 0x0c00, 0x059b, 0x0000 }, + { 0x0c00, 0x059d, 0x0000 }, + { 0x8c00, 0x05a0, 0x2000 }, + { 0x0c00, 0x059f, 0x0000 }, + { 0x0c00, 0x05a1, 0x0000 }, + { 0x8c00, 0x05a7, 0x3000 }, + { 0x8c00, 0x05a5, 0x2000 }, + { 0x0c00, 0x05a4, 0x0000 }, + { 0x0c00, 0x05a6, 0x0000 }, + { 0x8c00, 0x05a9, 0x2000 }, + { 0x0c00, 0x05a8, 0x0000 }, + { 0x0c00, 0x05aa, 0x0000 }, + { 0x8700, 0x05d7, 0x6000 }, + { 0x8c00, 0x05bc, 0x5000 }, + { 0x8c00, 0x05b3, 0x4000 }, + { 0x8c00, 0x05af, 0x3000 }, + { 0x8c00, 0x05ad, 0x2000 }, + { 0x0c00, 0x05ac, 0x0000 }, + { 0x0c00, 0x05ae, 0x0000 }, + { 0x8c00, 0x05b1, 0x2000 }, + { 0x0c00, 0x05b0, 0x0000 }, + { 0x0c00, 0x05b2, 0x0000 }, + { 0x8c00, 0x05b7, 0x3000 }, + { 0x8c00, 0x05b5, 0x2000 }, + { 0x0c00, 0x05b4, 0x0000 }, + { 0x0c00, 0x05b6, 0x0000 }, + { 0x8c00, 0x05b9, 0x2000 }, + { 0x0c00, 0x05b8, 0x0000 }, + { 0x0c00, 0x05bb, 0x0000 }, + { 0x8c00, 0x05c4, 0x4000 }, + { 0x9500, 0x05c0, 0x3000 }, + { 0x9500, 0x05be, 0x2000 }, + { 0x0c00, 0x05bd, 0x0000 }, + { 0x0c00, 0x05bf, 0x0000 }, + { 0x8c00, 0x05c2, 0x2000 }, + { 0x0c00, 0x05c1, 0x0000 }, + { 0x1500, 0x05c3, 0x0000 }, + { 0x8700, 0x05d3, 0x3000 }, + { 0x8700, 0x05d1, 0x2000 }, + { 0x0700, 0x05d0, 0x0000 }, + { 0x0700, 0x05d2, 0x0000 }, + { 0x8700, 0x05d5, 0x2000 }, + { 0x0700, 0x05d4, 0x0000 }, + { 0x0700, 0x05d6, 0x0000 }, + { 0x8700, 0x05e7, 0x5000 }, + { 0x8700, 0x05df, 0x4000 }, + { 0x8700, 0x05db, 0x3000 }, + { 0x8700, 0x05d9, 0x2000 }, + { 0x0700, 0x05d8, 0x0000 }, + { 0x0700, 0x05da, 0x0000 }, + { 0x8700, 0x05dd, 0x2000 }, + { 0x0700, 0x05dc, 0x0000 }, + { 0x0700, 0x05de, 0x0000 }, + { 0x8700, 0x05e3, 0x3000 }, + { 0x8700, 0x05e1, 0x2000 }, + { 0x0700, 0x05e0, 0x0000 }, + { 0x0700, 0x05e2, 0x0000 }, + { 0x8700, 0x05e5, 0x2000 }, + { 0x0700, 0x05e4, 0x0000 }, + { 0x0700, 0x05e6, 0x0000 }, + { 0x9500, 0x05f4, 0x4000 }, + { 0x8700, 0x05f0, 0x3000 }, + { 0x8700, 0x05e9, 0x2000 }, + { 0x0700, 0x05e8, 0x0000 }, + { 0x0700, 0x05ea, 0x0000 }, + { 0x8700, 0x05f2, 0x2000 }, + { 0x0700, 0x05f1, 0x0000 }, + { 0x1500, 0x05f3, 0x0000 }, + { 0x8100, 0x0603, 0x3000 }, + { 0x8100, 0x0601, 0x2000 }, + { 0x0100, 0x0600, 0x0000 }, + { 0x0100, 0x0602, 0x0000 }, + { 0x9500, 0x060d, 0x2000 }, + { 0x1500, 0x060c, 0x0000 }, + { 0x1a00, 0x060e, 0x0000 }, + { 0x8d00, 0x0664, 0x7000 }, + { 0x8700, 0x0638, 0x6000 }, + { 0x8700, 0x0628, 0x5000 }, + { 0x9500, 0x061f, 0x4000 }, + { 0x8c00, 0x0613, 0x3000 }, + { 0x8c00, 0x0611, 0x2000 }, + { 0x0c00, 0x0610, 0x0000 }, + { 0x0c00, 0x0612, 0x0000 }, + { 0x8c00, 0x0615, 0x2000 }, + { 0x0c00, 0x0614, 0x0000 }, + { 0x1500, 0x061b, 0x0000 }, + { 0x8700, 0x0624, 0x3000 }, + { 0x8700, 0x0622, 0x2000 }, + { 0x0700, 0x0621, 0x0000 }, + { 0x0700, 0x0623, 0x0000 }, + { 0x8700, 0x0626, 0x2000 }, + { 0x0700, 0x0625, 0x0000 }, + { 0x0700, 0x0627, 0x0000 }, + { 0x8700, 0x0630, 0x4000 }, + { 0x8700, 0x062c, 0x3000 }, + { 0x8700, 0x062a, 0x2000 }, + { 0x0700, 0x0629, 0x0000 }, + { 0x0700, 0x062b, 0x0000 }, + { 0x8700, 0x062e, 0x2000 }, + { 0x0700, 0x062d, 0x0000 }, + { 0x0700, 0x062f, 0x0000 }, + { 0x8700, 0x0634, 0x3000 }, + { 0x8700, 0x0632, 0x2000 }, + { 0x0700, 0x0631, 0x0000 }, + { 0x0700, 0x0633, 0x0000 }, + { 0x8700, 0x0636, 0x2000 }, + { 0x0700, 0x0635, 0x0000 }, + { 0x0700, 0x0637, 0x0000 }, + { 0x8c00, 0x064d, 0x5000 }, + { 0x8700, 0x0645, 0x4000 }, + { 0x8700, 0x0641, 0x3000 }, + { 0x8700, 0x063a, 0x2000 }, + { 0x0700, 0x0639, 0x0000 }, + { 0x0600, 0x0640, 0x0000 }, + { 0x8700, 0x0643, 0x2000 }, + { 0x0700, 0x0642, 0x0000 }, + { 0x0700, 0x0644, 0x0000 }, + { 0x8700, 0x0649, 0x3000 }, + { 0x8700, 0x0647, 0x2000 }, + { 0x0700, 0x0646, 0x0000 }, + { 0x0700, 0x0648, 0x0000 }, + { 0x8c00, 0x064b, 0x2000 }, + { 0x0700, 0x064a, 0x0000 }, + { 0x0c00, 0x064c, 0x0000 }, + { 0x8c00, 0x0655, 0x4000 }, + { 0x8c00, 0x0651, 0x3000 }, + { 0x8c00, 0x064f, 0x2000 }, + { 0x0c00, 0x064e, 0x0000 }, + { 0x0c00, 0x0650, 0x0000 }, + { 0x8c00, 0x0653, 0x2000 }, + { 0x0c00, 0x0652, 0x0000 }, + { 0x0c00, 0x0654, 0x0000 }, + { 0x8d00, 0x0660, 0x3000 }, + { 0x8c00, 0x0657, 0x2000 }, + { 0x0c00, 0x0656, 0x0000 }, + { 0x0c00, 0x0658, 0x0000 }, + { 0x8d00, 0x0662, 0x2000 }, + { 0x0d00, 0x0661, 0x0000 }, + { 0x0d00, 0x0663, 0x0000 }, + { 0x8700, 0x0684, 0x6000 }, + { 0x8700, 0x0674, 0x5000 }, + { 0x9500, 0x066c, 0x4000 }, + { 0x8d00, 0x0668, 0x3000 }, + { 0x8d00, 0x0666, 0x2000 }, + { 0x0d00, 0x0665, 0x0000 }, + { 0x0d00, 0x0667, 0x0000 }, + { 0x9500, 0x066a, 0x2000 }, + { 0x0d00, 0x0669, 0x0000 }, + { 0x1500, 0x066b, 0x0000 }, + { 0x8c00, 0x0670, 0x3000 }, + { 0x8700, 0x066e, 0x2000 }, + { 0x1500, 0x066d, 0x0000 }, + { 0x0700, 0x066f, 0x0000 }, + { 0x8700, 0x0672, 0x2000 }, + { 0x0700, 0x0671, 0x0000 }, + { 0x0700, 0x0673, 0x0000 }, + { 0x8700, 0x067c, 0x4000 }, + { 0x8700, 0x0678, 0x3000 }, + { 0x8700, 0x0676, 0x2000 }, + { 0x0700, 0x0675, 0x0000 }, + { 0x0700, 0x0677, 0x0000 }, + { 0x8700, 0x067a, 0x2000 }, + { 0x0700, 0x0679, 0x0000 }, + { 0x0700, 0x067b, 0x0000 }, + { 0x8700, 0x0680, 0x3000 }, + { 0x8700, 0x067e, 0x2000 }, + { 0x0700, 0x067d, 0x0000 }, + { 0x0700, 0x067f, 0x0000 }, + { 0x8700, 0x0682, 0x2000 }, + { 0x0700, 0x0681, 0x0000 }, + { 0x0700, 0x0683, 0x0000 }, + { 0x8700, 0x0694, 0x5000 }, + { 0x8700, 0x068c, 0x4000 }, + { 0x8700, 0x0688, 0x3000 }, + { 0x8700, 0x0686, 0x2000 }, + { 0x0700, 0x0685, 0x0000 }, + { 0x0700, 0x0687, 0x0000 }, + { 0x8700, 0x068a, 0x2000 }, + { 0x0700, 0x0689, 0x0000 }, + { 0x0700, 0x068b, 0x0000 }, + { 0x8700, 0x0690, 0x3000 }, + { 0x8700, 0x068e, 0x2000 }, + { 0x0700, 0x068d, 0x0000 }, + { 0x0700, 0x068f, 0x0000 }, + { 0x8700, 0x0692, 0x2000 }, + { 0x0700, 0x0691, 0x0000 }, + { 0x0700, 0x0693, 0x0000 }, + { 0x8700, 0x069c, 0x4000 }, + { 0x8700, 0x0698, 0x3000 }, + { 0x8700, 0x0696, 0x2000 }, + { 0x0700, 0x0695, 0x0000 }, + { 0x0700, 0x0697, 0x0000 }, + { 0x8700, 0x069a, 0x2000 }, + { 0x0700, 0x0699, 0x0000 }, + { 0x0700, 0x069b, 0x0000 }, + { 0x8700, 0x06a0, 0x3000 }, + { 0x8700, 0x069e, 0x2000 }, + { 0x0700, 0x069d, 0x0000 }, + { 0x0700, 0x069f, 0x0000 }, + { 0x8700, 0x06a2, 0x2000 }, + { 0x0700, 0x06a1, 0x0000 }, + { 0x0700, 0x06a3, 0x0000 }, + { 0x8700, 0x0926, 0x9000 }, + { 0x8700, 0x0725, 0x8000 }, + { 0x8c00, 0x06e4, 0x7000 }, + { 0x8700, 0x06c4, 0x6000 }, + { 0x8700, 0x06b4, 0x5000 }, + { 0x8700, 0x06ac, 0x4000 }, + { 0x8700, 0x06a8, 0x3000 }, + { 0x8700, 0x06a6, 0x2000 }, + { 0x0700, 0x06a5, 0x0000 }, + { 0x0700, 0x06a7, 0x0000 }, + { 0x8700, 0x06aa, 0x2000 }, + { 0x0700, 0x06a9, 0x0000 }, + { 0x0700, 0x06ab, 0x0000 }, + { 0x8700, 0x06b0, 0x3000 }, + { 0x8700, 0x06ae, 0x2000 }, + { 0x0700, 0x06ad, 0x0000 }, + { 0x0700, 0x06af, 0x0000 }, + { 0x8700, 0x06b2, 0x2000 }, + { 0x0700, 0x06b1, 0x0000 }, + { 0x0700, 0x06b3, 0x0000 }, + { 0x8700, 0x06bc, 0x4000 }, + { 0x8700, 0x06b8, 0x3000 }, + { 0x8700, 0x06b6, 0x2000 }, + { 0x0700, 0x06b5, 0x0000 }, + { 0x0700, 0x06b7, 0x0000 }, + { 0x8700, 0x06ba, 0x2000 }, + { 0x0700, 0x06b9, 0x0000 }, + { 0x0700, 0x06bb, 0x0000 }, + { 0x8700, 0x06c0, 0x3000 }, + { 0x8700, 0x06be, 0x2000 }, + { 0x0700, 0x06bd, 0x0000 }, + { 0x0700, 0x06bf, 0x0000 }, + { 0x8700, 0x06c2, 0x2000 }, + { 0x0700, 0x06c1, 0x0000 }, + { 0x0700, 0x06c3, 0x0000 }, + { 0x9500, 0x06d4, 0x5000 }, + { 0x8700, 0x06cc, 0x4000 }, + { 0x8700, 0x06c8, 0x3000 }, + { 0x8700, 0x06c6, 0x2000 }, + { 0x0700, 0x06c5, 0x0000 }, + { 0x0700, 0x06c7, 0x0000 }, + { 0x8700, 0x06ca, 0x2000 }, + { 0x0700, 0x06c9, 0x0000 }, + { 0x0700, 0x06cb, 0x0000 }, + { 0x8700, 0x06d0, 0x3000 }, + { 0x8700, 0x06ce, 0x2000 }, + { 0x0700, 0x06cd, 0x0000 }, + { 0x0700, 0x06cf, 0x0000 }, + { 0x8700, 0x06d2, 0x2000 }, + { 0x0700, 0x06d1, 0x0000 }, + { 0x0700, 0x06d3, 0x0000 }, + { 0x8c00, 0x06dc, 0x4000 }, + { 0x8c00, 0x06d8, 0x3000 }, + { 0x8c00, 0x06d6, 0x2000 }, + { 0x0700, 0x06d5, 0x0000 }, + { 0x0c00, 0x06d7, 0x0000 }, + { 0x8c00, 0x06da, 0x2000 }, + { 0x0c00, 0x06d9, 0x0000 }, + { 0x0c00, 0x06db, 0x0000 }, + { 0x8c00, 0x06e0, 0x3000 }, + { 0x8b00, 0x06de, 0x2000 }, + { 0x0100, 0x06dd, 0x0000 }, + { 0x0c00, 0x06df, 0x0000 }, + { 0x8c00, 0x06e2, 0x2000 }, + { 0x0c00, 0x06e1, 0x0000 }, + { 0x0c00, 0x06e3, 0x0000 }, + { 0x9500, 0x0704, 0x6000 }, + { 0x8d00, 0x06f4, 0x5000 }, + { 0x8c00, 0x06ec, 0x4000 }, + { 0x8c00, 0x06e8, 0x3000 }, + { 0x8600, 0x06e6, 0x2000 }, + { 0x0600, 0x06e5, 0x0000 }, + { 0x0c00, 0x06e7, 0x0000 }, + { 0x8c00, 0x06ea, 0x2000 }, + { 0x1a00, 0x06e9, 0x0000 }, + { 0x0c00, 0x06eb, 0x0000 }, + { 0x8d00, 0x06f0, 0x3000 }, + { 0x8700, 0x06ee, 0x2000 }, + { 0x0c00, 0x06ed, 0x0000 }, + { 0x0700, 0x06ef, 0x0000 }, + { 0x8d00, 0x06f2, 0x2000 }, + { 0x0d00, 0x06f1, 0x0000 }, + { 0x0d00, 0x06f3, 0x0000 }, + { 0x8700, 0x06fc, 0x4000 }, + { 0x8d00, 0x06f8, 0x3000 }, + { 0x8d00, 0x06f6, 0x2000 }, + { 0x0d00, 0x06f5, 0x0000 }, + { 0x0d00, 0x06f7, 0x0000 }, + { 0x8700, 0x06fa, 0x2000 }, + { 0x0d00, 0x06f9, 0x0000 }, + { 0x0700, 0x06fb, 0x0000 }, + { 0x9500, 0x0700, 0x3000 }, + { 0x9a00, 0x06fe, 0x2000 }, + { 0x1a00, 0x06fd, 0x0000 }, + { 0x0700, 0x06ff, 0x0000 }, + { 0x9500, 0x0702, 0x2000 }, + { 0x1500, 0x0701, 0x0000 }, + { 0x1500, 0x0703, 0x0000 }, + { 0x8700, 0x0715, 0x5000 }, + { 0x9500, 0x070c, 0x4000 }, + { 0x9500, 0x0708, 0x3000 }, + { 0x9500, 0x0706, 0x2000 }, + { 0x1500, 0x0705, 0x0000 }, + { 0x1500, 0x0707, 0x0000 }, + { 0x9500, 0x070a, 0x2000 }, + { 0x1500, 0x0709, 0x0000 }, + { 0x1500, 0x070b, 0x0000 }, + { 0x8c00, 0x0711, 0x3000 }, + { 0x8100, 0x070f, 0x2000 }, + { 0x1500, 0x070d, 0x0000 }, + { 0x0700, 0x0710, 0x0000 }, + { 0x8700, 0x0713, 0x2000 }, + { 0x0700, 0x0712, 0x0000 }, + { 0x0700, 0x0714, 0x0000 }, + { 0x8700, 0x071d, 0x4000 }, + { 0x8700, 0x0719, 0x3000 }, + { 0x8700, 0x0717, 0x2000 }, + { 0x0700, 0x0716, 0x0000 }, + { 0x0700, 0x0718, 0x0000 }, + { 0x8700, 0x071b, 0x2000 }, + { 0x0700, 0x071a, 0x0000 }, + { 0x0700, 0x071c, 0x0000 }, + { 0x8700, 0x0721, 0x3000 }, + { 0x8700, 0x071f, 0x2000 }, + { 0x0700, 0x071e, 0x0000 }, + { 0x0700, 0x0720, 0x0000 }, + { 0x8700, 0x0723, 0x2000 }, + { 0x0700, 0x0722, 0x0000 }, + { 0x0700, 0x0724, 0x0000 }, + { 0x8700, 0x0797, 0x7000 }, + { 0x8c00, 0x0745, 0x6000 }, + { 0x8c00, 0x0735, 0x5000 }, + { 0x8700, 0x072d, 0x4000 }, + { 0x8700, 0x0729, 0x3000 }, + { 0x8700, 0x0727, 0x2000 }, + { 0x0700, 0x0726, 0x0000 }, + { 0x0700, 0x0728, 0x0000 }, + { 0x8700, 0x072b, 0x2000 }, + { 0x0700, 0x072a, 0x0000 }, + { 0x0700, 0x072c, 0x0000 }, + { 0x8c00, 0x0731, 0x3000 }, + { 0x8700, 0x072f, 0x2000 }, + { 0x0700, 0x072e, 0x0000 }, + { 0x0c00, 0x0730, 0x0000 }, + { 0x8c00, 0x0733, 0x2000 }, + { 0x0c00, 0x0732, 0x0000 }, + { 0x0c00, 0x0734, 0x0000 }, + { 0x8c00, 0x073d, 0x4000 }, + { 0x8c00, 0x0739, 0x3000 }, + { 0x8c00, 0x0737, 0x2000 }, + { 0x0c00, 0x0736, 0x0000 }, + { 0x0c00, 0x0738, 0x0000 }, + { 0x8c00, 0x073b, 0x2000 }, + { 0x0c00, 0x073a, 0x0000 }, + { 0x0c00, 0x073c, 0x0000 }, + { 0x8c00, 0x0741, 0x3000 }, + { 0x8c00, 0x073f, 0x2000 }, + { 0x0c00, 0x073e, 0x0000 }, + { 0x0c00, 0x0740, 0x0000 }, + { 0x8c00, 0x0743, 0x2000 }, + { 0x0c00, 0x0742, 0x0000 }, + { 0x0c00, 0x0744, 0x0000 }, + { 0x8700, 0x0787, 0x5000 }, + { 0x8700, 0x074f, 0x4000 }, + { 0x8c00, 0x0749, 0x3000 }, + { 0x8c00, 0x0747, 0x2000 }, + { 0x0c00, 0x0746, 0x0000 }, + { 0x0c00, 0x0748, 0x0000 }, + { 0x8700, 0x074d, 0x2000 }, + { 0x0c00, 0x074a, 0x0000 }, + { 0x0700, 0x074e, 0x0000 }, + { 0x8700, 0x0783, 0x3000 }, + { 0x8700, 0x0781, 0x2000 }, + { 0x0700, 0x0780, 0x0000 }, + { 0x0700, 0x0782, 0x0000 }, + { 0x8700, 0x0785, 0x2000 }, + { 0x0700, 0x0784, 0x0000 }, + { 0x0700, 0x0786, 0x0000 }, + { 0x8700, 0x078f, 0x4000 }, + { 0x8700, 0x078b, 0x3000 }, + { 0x8700, 0x0789, 0x2000 }, + { 0x0700, 0x0788, 0x0000 }, + { 0x0700, 0x078a, 0x0000 }, + { 0x8700, 0x078d, 0x2000 }, + { 0x0700, 0x078c, 0x0000 }, + { 0x0700, 0x078e, 0x0000 }, + { 0x8700, 0x0793, 0x3000 }, + { 0x8700, 0x0791, 0x2000 }, + { 0x0700, 0x0790, 0x0000 }, + { 0x0700, 0x0792, 0x0000 }, + { 0x8700, 0x0795, 0x2000 }, + { 0x0700, 0x0794, 0x0000 }, + { 0x0700, 0x0796, 0x0000 }, + { 0x8700, 0x0906, 0x6000 }, + { 0x8c00, 0x07a7, 0x5000 }, + { 0x8700, 0x079f, 0x4000 }, + { 0x8700, 0x079b, 0x3000 }, + { 0x8700, 0x0799, 0x2000 }, + { 0x0700, 0x0798, 0x0000 }, + { 0x0700, 0x079a, 0x0000 }, + { 0x8700, 0x079d, 0x2000 }, + { 0x0700, 0x079c, 0x0000 }, + { 0x0700, 0x079e, 0x0000 }, + { 0x8700, 0x07a3, 0x3000 }, + { 0x8700, 0x07a1, 0x2000 }, + { 0x0700, 0x07a0, 0x0000 }, + { 0x0700, 0x07a2, 0x0000 }, + { 0x8700, 0x07a5, 0x2000 }, + { 0x0700, 0x07a4, 0x0000 }, + { 0x0c00, 0x07a6, 0x0000 }, + { 0x8c00, 0x07af, 0x4000 }, + { 0x8c00, 0x07ab, 0x3000 }, + { 0x8c00, 0x07a9, 0x2000 }, + { 0x0c00, 0x07a8, 0x0000 }, + { 0x0c00, 0x07aa, 0x0000 }, + { 0x8c00, 0x07ad, 0x2000 }, + { 0x0c00, 0x07ac, 0x0000 }, + { 0x0c00, 0x07ae, 0x0000 }, + { 0x8c00, 0x0902, 0x3000 }, + { 0x8700, 0x07b1, 0x2000 }, + { 0x0c00, 0x07b0, 0x0000 }, + { 0x0c00, 0x0901, 0x0000 }, + { 0x8700, 0x0904, 0x2000 }, + { 0x0a00, 0x0903, 0x0000 }, + { 0x0700, 0x0905, 0x0000 }, + { 0x8700, 0x0916, 0x5000 }, + { 0x8700, 0x090e, 0x4000 }, + { 0x8700, 0x090a, 0x3000 }, + { 0x8700, 0x0908, 0x2000 }, + { 0x0700, 0x0907, 0x0000 }, + { 0x0700, 0x0909, 0x0000 }, + { 0x8700, 0x090c, 0x2000 }, + { 0x0700, 0x090b, 0x0000 }, + { 0x0700, 0x090d, 0x0000 }, + { 0x8700, 0x0912, 0x3000 }, + { 0x8700, 0x0910, 0x2000 }, + { 0x0700, 0x090f, 0x0000 }, + { 0x0700, 0x0911, 0x0000 }, + { 0x8700, 0x0914, 0x2000 }, + { 0x0700, 0x0913, 0x0000 }, + { 0x0700, 0x0915, 0x0000 }, + { 0x8700, 0x091e, 0x4000 }, + { 0x8700, 0x091a, 0x3000 }, + { 0x8700, 0x0918, 0x2000 }, + { 0x0700, 0x0917, 0x0000 }, + { 0x0700, 0x0919, 0x0000 }, + { 0x8700, 0x091c, 0x2000 }, + { 0x0700, 0x091b, 0x0000 }, + { 0x0700, 0x091d, 0x0000 }, + { 0x8700, 0x0922, 0x3000 }, + { 0x8700, 0x0920, 0x2000 }, + { 0x0700, 0x091f, 0x0000 }, + { 0x0700, 0x0921, 0x0000 }, + { 0x8700, 0x0924, 0x2000 }, + { 0x0700, 0x0923, 0x0000 }, + { 0x0700, 0x0925, 0x0000 }, + { 0x8c00, 0x09cd, 0x8000 }, + { 0x8d00, 0x096d, 0x7000 }, + { 0x8c00, 0x0948, 0x6000 }, + { 0x8700, 0x0936, 0x5000 }, + { 0x8700, 0x092e, 0x4000 }, + { 0x8700, 0x092a, 0x3000 }, + { 0x8700, 0x0928, 0x2000 }, + { 0x0700, 0x0927, 0x0000 }, + { 0x0700, 0x0929, 0x0000 }, + { 0x8700, 0x092c, 0x2000 }, + { 0x0700, 0x092b, 0x0000 }, + { 0x0700, 0x092d, 0x0000 }, + { 0x8700, 0x0932, 0x3000 }, + { 0x8700, 0x0930, 0x2000 }, + { 0x0700, 0x092f, 0x0000 }, + { 0x0700, 0x0931, 0x0000 }, + { 0x8700, 0x0934, 0x2000 }, + { 0x0700, 0x0933, 0x0000 }, + { 0x0700, 0x0935, 0x0000 }, + { 0x8a00, 0x0940, 0x4000 }, + { 0x8c00, 0x093c, 0x3000 }, + { 0x8700, 0x0938, 0x2000 }, + { 0x0700, 0x0937, 0x0000 }, + { 0x0700, 0x0939, 0x0000 }, + { 0x8a00, 0x093e, 0x2000 }, + { 0x0700, 0x093d, 0x0000 }, + { 0x0a00, 0x093f, 0x0000 }, + { 0x8c00, 0x0944, 0x3000 }, + { 0x8c00, 0x0942, 0x2000 }, + { 0x0c00, 0x0941, 0x0000 }, + { 0x0c00, 0x0943, 0x0000 }, + { 0x8c00, 0x0946, 0x2000 }, + { 0x0c00, 0x0945, 0x0000 }, + { 0x0c00, 0x0947, 0x0000 }, + { 0x8700, 0x095d, 0x5000 }, + { 0x8c00, 0x0952, 0x4000 }, + { 0x8a00, 0x094c, 0x3000 }, + { 0x8a00, 0x094a, 0x2000 }, + { 0x0a00, 0x0949, 0x0000 }, + { 0x0a00, 0x094b, 0x0000 }, + { 0x8700, 0x0950, 0x2000 }, + { 0x0c00, 0x094d, 0x0000 }, + { 0x0c00, 0x0951, 0x0000 }, + { 0x8700, 0x0959, 0x3000 }, + { 0x8c00, 0x0954, 0x2000 }, + { 0x0c00, 0x0953, 0x0000 }, + { 0x0700, 0x0958, 0x0000 }, + { 0x8700, 0x095b, 0x2000 }, + { 0x0700, 0x095a, 0x0000 }, + { 0x0700, 0x095c, 0x0000 }, + { 0x9500, 0x0965, 0x4000 }, + { 0x8700, 0x0961, 0x3000 }, + { 0x8700, 0x095f, 0x2000 }, + { 0x0700, 0x095e, 0x0000 }, + { 0x0700, 0x0960, 0x0000 }, + { 0x8c00, 0x0963, 0x2000 }, + { 0x0c00, 0x0962, 0x0000 }, + { 0x1500, 0x0964, 0x0000 }, + { 0x8d00, 0x0969, 0x3000 }, + { 0x8d00, 0x0967, 0x2000 }, + { 0x0d00, 0x0966, 0x0000 }, + { 0x0d00, 0x0968, 0x0000 }, + { 0x8d00, 0x096b, 0x2000 }, + { 0x0d00, 0x096a, 0x0000 }, + { 0x0d00, 0x096c, 0x0000 }, + { 0x8700, 0x09a2, 0x6000 }, + { 0x8700, 0x0990, 0x5000 }, + { 0x8700, 0x0986, 0x4000 }, + { 0x8c00, 0x0981, 0x3000 }, + { 0x8d00, 0x096f, 0x2000 }, + { 0x0d00, 0x096e, 0x0000 }, + { 0x1500, 0x0970, 0x0000 }, + { 0x8a00, 0x0983, 0x2000 }, + { 0x0a00, 0x0982, 0x0000 }, + { 0x0700, 0x0985, 0x0000 }, + { 0x8700, 0x098a, 0x3000 }, + { 0x8700, 0x0988, 0x2000 }, + { 0x0700, 0x0987, 0x0000 }, + { 0x0700, 0x0989, 0x0000 }, + { 0x8700, 0x098c, 0x2000 }, + { 0x0700, 0x098b, 0x0000 }, + { 0x0700, 0x098f, 0x0000 }, + { 0x8700, 0x099a, 0x4000 }, + { 0x8700, 0x0996, 0x3000 }, + { 0x8700, 0x0994, 0x2000 }, + { 0x0700, 0x0993, 0x0000 }, + { 0x0700, 0x0995, 0x0000 }, + { 0x8700, 0x0998, 0x2000 }, + { 0x0700, 0x0997, 0x0000 }, + { 0x0700, 0x0999, 0x0000 }, + { 0x8700, 0x099e, 0x3000 }, + { 0x8700, 0x099c, 0x2000 }, + { 0x0700, 0x099b, 0x0000 }, + { 0x0700, 0x099d, 0x0000 }, + { 0x8700, 0x09a0, 0x2000 }, + { 0x0700, 0x099f, 0x0000 }, + { 0x0700, 0x09a1, 0x0000 }, + { 0x8700, 0x09b7, 0x5000 }, + { 0x8700, 0x09ab, 0x4000 }, + { 0x8700, 0x09a6, 0x3000 }, + { 0x8700, 0x09a4, 0x2000 }, + { 0x0700, 0x09a3, 0x0000 }, + { 0x0700, 0x09a5, 0x0000 }, + { 0x8700, 0x09a8, 0x2000 }, + { 0x0700, 0x09a7, 0x0000 }, + { 0x0700, 0x09aa, 0x0000 }, + { 0x8700, 0x09af, 0x3000 }, + { 0x8700, 0x09ad, 0x2000 }, + { 0x0700, 0x09ac, 0x0000 }, + { 0x0700, 0x09ae, 0x0000 }, + { 0x8700, 0x09b2, 0x2000 }, + { 0x0700, 0x09b0, 0x0000 }, + { 0x0700, 0x09b6, 0x0000 }, + { 0x8c00, 0x09c1, 0x4000 }, + { 0x8700, 0x09bd, 0x3000 }, + { 0x8700, 0x09b9, 0x2000 }, + { 0x0700, 0x09b8, 0x0000 }, + { 0x0c00, 0x09bc, 0x0000 }, + { 0x8a00, 0x09bf, 0x2000 }, + { 0x0a00, 0x09be, 0x0000 }, + { 0x0a00, 0x09c0, 0x0000 }, + { 0x8a00, 0x09c7, 0x3000 }, + { 0x8c00, 0x09c3, 0x2000 }, + { 0x0c00, 0x09c2, 0x0000 }, + { 0x0c00, 0x09c4, 0x0000 }, + { 0x8a00, 0x09cb, 0x2000 }, + { 0x0a00, 0x09c8, 0x0000 }, + { 0x0a00, 0x09cc, 0x0000 }, + { 0x8700, 0x0a2b, 0x7000 }, + { 0x8a00, 0x0a03, 0x6000 }, + { 0x8d00, 0x09ed, 0x5000 }, + { 0x8c00, 0x09e3, 0x4000 }, + { 0x8700, 0x09df, 0x3000 }, + { 0x8700, 0x09dc, 0x2000 }, + { 0x0a00, 0x09d7, 0x0000 }, + { 0x0700, 0x09dd, 0x0000 }, + { 0x8700, 0x09e1, 0x2000 }, + { 0x0700, 0x09e0, 0x0000 }, + { 0x0c00, 0x09e2, 0x0000 }, + { 0x8d00, 0x09e9, 0x3000 }, + { 0x8d00, 0x09e7, 0x2000 }, + { 0x0d00, 0x09e6, 0x0000 }, + { 0x0d00, 0x09e8, 0x0000 }, + { 0x8d00, 0x09eb, 0x2000 }, + { 0x0d00, 0x09ea, 0x0000 }, + { 0x0d00, 0x09ec, 0x0000 }, + { 0x8f00, 0x09f5, 0x4000 }, + { 0x8700, 0x09f1, 0x3000 }, + { 0x8d00, 0x09ef, 0x2000 }, + { 0x0d00, 0x09ee, 0x0000 }, + { 0x0700, 0x09f0, 0x0000 }, + { 0x9700, 0x09f3, 0x2000 }, + { 0x1700, 0x09f2, 0x0000 }, + { 0x0f00, 0x09f4, 0x0000 }, + { 0x8f00, 0x09f9, 0x3000 }, + { 0x8f00, 0x09f7, 0x2000 }, + { 0x0f00, 0x09f6, 0x0000 }, + { 0x0f00, 0x09f8, 0x0000 }, + { 0x8c00, 0x0a01, 0x2000 }, + { 0x1a00, 0x09fa, 0x0000 }, + { 0x0c00, 0x0a02, 0x0000 }, + { 0x8700, 0x0a1a, 0x5000 }, + { 0x8700, 0x0a10, 0x4000 }, + { 0x8700, 0x0a08, 0x3000 }, + { 0x8700, 0x0a06, 0x2000 }, + { 0x0700, 0x0a05, 0x0000 }, + { 0x0700, 0x0a07, 0x0000 }, + { 0x8700, 0x0a0a, 0x2000 }, + { 0x0700, 0x0a09, 0x0000 }, + { 0x0700, 0x0a0f, 0x0000 }, + { 0x8700, 0x0a16, 0x3000 }, + { 0x8700, 0x0a14, 0x2000 }, + { 0x0700, 0x0a13, 0x0000 }, + { 0x0700, 0x0a15, 0x0000 }, + { 0x8700, 0x0a18, 0x2000 }, + { 0x0700, 0x0a17, 0x0000 }, + { 0x0700, 0x0a19, 0x0000 }, + { 0x8700, 0x0a22, 0x4000 }, + { 0x8700, 0x0a1e, 0x3000 }, + { 0x8700, 0x0a1c, 0x2000 }, + { 0x0700, 0x0a1b, 0x0000 }, + { 0x0700, 0x0a1d, 0x0000 }, + { 0x8700, 0x0a20, 0x2000 }, + { 0x0700, 0x0a1f, 0x0000 }, + { 0x0700, 0x0a21, 0x0000 }, + { 0x8700, 0x0a26, 0x3000 }, + { 0x8700, 0x0a24, 0x2000 }, + { 0x0700, 0x0a23, 0x0000 }, + { 0x0700, 0x0a25, 0x0000 }, + { 0x8700, 0x0a28, 0x2000 }, + { 0x0700, 0x0a27, 0x0000 }, + { 0x0700, 0x0a2a, 0x0000 }, + { 0x8d00, 0x0a6a, 0x6000 }, + { 0x8c00, 0x0a41, 0x5000 }, + { 0x8700, 0x0a35, 0x4000 }, + { 0x8700, 0x0a2f, 0x3000 }, + { 0x8700, 0x0a2d, 0x2000 }, + { 0x0700, 0x0a2c, 0x0000 }, + { 0x0700, 0x0a2e, 0x0000 }, + { 0x8700, 0x0a32, 0x2000 }, + { 0x0700, 0x0a30, 0x0000 }, + { 0x0700, 0x0a33, 0x0000 }, + { 0x8c00, 0x0a3c, 0x3000 }, + { 0x8700, 0x0a38, 0x2000 }, + { 0x0700, 0x0a36, 0x0000 }, + { 0x0700, 0x0a39, 0x0000 }, + { 0x8a00, 0x0a3f, 0x2000 }, + { 0x0a00, 0x0a3e, 0x0000 }, + { 0x0a00, 0x0a40, 0x0000 }, + { 0x8700, 0x0a5a, 0x4000 }, + { 0x8c00, 0x0a4b, 0x3000 }, + { 0x8c00, 0x0a47, 0x2000 }, + { 0x0c00, 0x0a42, 0x0000 }, + { 0x0c00, 0x0a48, 0x0000 }, + { 0x8c00, 0x0a4d, 0x2000 }, + { 0x0c00, 0x0a4c, 0x0000 }, + { 0x0700, 0x0a59, 0x0000 }, + { 0x8d00, 0x0a66, 0x3000 }, + { 0x8700, 0x0a5c, 0x2000 }, + { 0x0700, 0x0a5b, 0x0000 }, + { 0x0700, 0x0a5e, 0x0000 }, + { 0x8d00, 0x0a68, 0x2000 }, + { 0x0d00, 0x0a67, 0x0000 }, + { 0x0d00, 0x0a69, 0x0000 }, + { 0x8700, 0x0a87, 0x5000 }, + { 0x8700, 0x0a72, 0x4000 }, + { 0x8d00, 0x0a6e, 0x3000 }, + { 0x8d00, 0x0a6c, 0x2000 }, + { 0x0d00, 0x0a6b, 0x0000 }, + { 0x0d00, 0x0a6d, 0x0000 }, + { 0x8c00, 0x0a70, 0x2000 }, + { 0x0d00, 0x0a6f, 0x0000 }, + { 0x0c00, 0x0a71, 0x0000 }, + { 0x8c00, 0x0a82, 0x3000 }, + { 0x8700, 0x0a74, 0x2000 }, + { 0x0700, 0x0a73, 0x0000 }, + { 0x0c00, 0x0a81, 0x0000 }, + { 0x8700, 0x0a85, 0x2000 }, + { 0x0a00, 0x0a83, 0x0000 }, + { 0x0700, 0x0a86, 0x0000 }, + { 0x8700, 0x0a90, 0x4000 }, + { 0x8700, 0x0a8b, 0x3000 }, + { 0x8700, 0x0a89, 0x2000 }, + { 0x0700, 0x0a88, 0x0000 }, + { 0x0700, 0x0a8a, 0x0000 }, + { 0x8700, 0x0a8d, 0x2000 }, + { 0x0700, 0x0a8c, 0x0000 }, + { 0x0700, 0x0a8f, 0x0000 }, + { 0x8700, 0x0a95, 0x3000 }, + { 0x8700, 0x0a93, 0x2000 }, + { 0x0700, 0x0a91, 0x0000 }, + { 0x0700, 0x0a94, 0x0000 }, + { 0x8700, 0x0a97, 0x2000 }, + { 0x0700, 0x0a96, 0x0000 }, + { 0x0700, 0x0a98, 0x0000 }, + { 0x8700, 0x10ef, 0xb000 }, + { 0x8700, 0x0dc6, 0xa000 }, + { 0x8700, 0x0c31, 0x9000 }, + { 0x8700, 0x0b5f, 0x8000 }, + { 0x8a00, 0x0b03, 0x7000 }, + { 0x8a00, 0x0abe, 0x6000 }, + { 0x8700, 0x0aaa, 0x5000 }, + { 0x8700, 0x0aa1, 0x4000 }, + { 0x8700, 0x0a9d, 0x3000 }, + { 0x8700, 0x0a9b, 0x2000 }, + { 0x0700, 0x0a9a, 0x0000 }, + { 0x0700, 0x0a9c, 0x0000 }, + { 0x8700, 0x0a9f, 0x2000 }, + { 0x0700, 0x0a9e, 0x0000 }, + { 0x0700, 0x0aa0, 0x0000 }, + { 0x8700, 0x0aa5, 0x3000 }, + { 0x8700, 0x0aa3, 0x2000 }, + { 0x0700, 0x0aa2, 0x0000 }, + { 0x0700, 0x0aa4, 0x0000 }, + { 0x8700, 0x0aa7, 0x2000 }, + { 0x0700, 0x0aa6, 0x0000 }, + { 0x0700, 0x0aa8, 0x0000 }, + { 0x8700, 0x0ab3, 0x4000 }, + { 0x8700, 0x0aae, 0x3000 }, + { 0x8700, 0x0aac, 0x2000 }, + { 0x0700, 0x0aab, 0x0000 }, + { 0x0700, 0x0aad, 0x0000 }, + { 0x8700, 0x0ab0, 0x2000 }, + { 0x0700, 0x0aaf, 0x0000 }, + { 0x0700, 0x0ab2, 0x0000 }, + { 0x8700, 0x0ab8, 0x3000 }, + { 0x8700, 0x0ab6, 0x2000 }, + { 0x0700, 0x0ab5, 0x0000 }, + { 0x0700, 0x0ab7, 0x0000 }, + { 0x8c00, 0x0abc, 0x2000 }, + { 0x0700, 0x0ab9, 0x0000 }, + { 0x0700, 0x0abd, 0x0000 }, + { 0x8700, 0x0ae1, 0x5000 }, + { 0x8c00, 0x0ac7, 0x4000 }, + { 0x8c00, 0x0ac2, 0x3000 }, + { 0x8a00, 0x0ac0, 0x2000 }, + { 0x0a00, 0x0abf, 0x0000 }, + { 0x0c00, 0x0ac1, 0x0000 }, + { 0x8c00, 0x0ac4, 0x2000 }, + { 0x0c00, 0x0ac3, 0x0000 }, + { 0x0c00, 0x0ac5, 0x0000 }, + { 0x8a00, 0x0acc, 0x3000 }, + { 0x8a00, 0x0ac9, 0x2000 }, + { 0x0c00, 0x0ac8, 0x0000 }, + { 0x0a00, 0x0acb, 0x0000 }, + { 0x8700, 0x0ad0, 0x2000 }, + { 0x0c00, 0x0acd, 0x0000 }, + { 0x0700, 0x0ae0, 0x0000 }, + { 0x8d00, 0x0aeb, 0x4000 }, + { 0x8d00, 0x0ae7, 0x3000 }, + { 0x8c00, 0x0ae3, 0x2000 }, + { 0x0c00, 0x0ae2, 0x0000 }, + { 0x0d00, 0x0ae6, 0x0000 }, + { 0x8d00, 0x0ae9, 0x2000 }, + { 0x0d00, 0x0ae8, 0x0000 }, + { 0x0d00, 0x0aea, 0x0000 }, + { 0x8d00, 0x0aef, 0x3000 }, + { 0x8d00, 0x0aed, 0x2000 }, + { 0x0d00, 0x0aec, 0x0000 }, + { 0x0d00, 0x0aee, 0x0000 }, + { 0x8c00, 0x0b01, 0x2000 }, + { 0x1700, 0x0af1, 0x0000 }, + { 0x0a00, 0x0b02, 0x0000 }, + { 0x8700, 0x0b28, 0x6000 }, + { 0x8700, 0x0b18, 0x5000 }, + { 0x8700, 0x0b0c, 0x4000 }, + { 0x8700, 0x0b08, 0x3000 }, + { 0x8700, 0x0b06, 0x2000 }, + { 0x0700, 0x0b05, 0x0000 }, + { 0x0700, 0x0b07, 0x0000 }, + { 0x8700, 0x0b0a, 0x2000 }, + { 0x0700, 0x0b09, 0x0000 }, + { 0x0700, 0x0b0b, 0x0000 }, + { 0x8700, 0x0b14, 0x3000 }, + { 0x8700, 0x0b10, 0x2000 }, + { 0x0700, 0x0b0f, 0x0000 }, + { 0x0700, 0x0b13, 0x0000 }, + { 0x8700, 0x0b16, 0x2000 }, + { 0x0700, 0x0b15, 0x0000 }, + { 0x0700, 0x0b17, 0x0000 }, + { 0x8700, 0x0b20, 0x4000 }, + { 0x8700, 0x0b1c, 0x3000 }, + { 0x8700, 0x0b1a, 0x2000 }, + { 0x0700, 0x0b19, 0x0000 }, + { 0x0700, 0x0b1b, 0x0000 }, + { 0x8700, 0x0b1e, 0x2000 }, + { 0x0700, 0x0b1d, 0x0000 }, + { 0x0700, 0x0b1f, 0x0000 }, + { 0x8700, 0x0b24, 0x3000 }, + { 0x8700, 0x0b22, 0x2000 }, + { 0x0700, 0x0b21, 0x0000 }, + { 0x0700, 0x0b23, 0x0000 }, + { 0x8700, 0x0b26, 0x2000 }, + { 0x0700, 0x0b25, 0x0000 }, + { 0x0700, 0x0b27, 0x0000 }, + { 0x8700, 0x0b3d, 0x5000 }, + { 0x8700, 0x0b32, 0x4000 }, + { 0x8700, 0x0b2d, 0x3000 }, + { 0x8700, 0x0b2b, 0x2000 }, + { 0x0700, 0x0b2a, 0x0000 }, + { 0x0700, 0x0b2c, 0x0000 }, + { 0x8700, 0x0b2f, 0x2000 }, + { 0x0700, 0x0b2e, 0x0000 }, + { 0x0700, 0x0b30, 0x0000 }, + { 0x8700, 0x0b37, 0x3000 }, + { 0x8700, 0x0b35, 0x2000 }, + { 0x0700, 0x0b33, 0x0000 }, + { 0x0700, 0x0b36, 0x0000 }, + { 0x8700, 0x0b39, 0x2000 }, + { 0x0700, 0x0b38, 0x0000 }, + { 0x0c00, 0x0b3c, 0x0000 }, + { 0x8a00, 0x0b48, 0x4000 }, + { 0x8c00, 0x0b41, 0x3000 }, + { 0x8c00, 0x0b3f, 0x2000 }, + { 0x0a00, 0x0b3e, 0x0000 }, + { 0x0a00, 0x0b40, 0x0000 }, + { 0x8c00, 0x0b43, 0x2000 }, + { 0x0c00, 0x0b42, 0x0000 }, + { 0x0a00, 0x0b47, 0x0000 }, + { 0x8c00, 0x0b56, 0x3000 }, + { 0x8a00, 0x0b4c, 0x2000 }, + { 0x0a00, 0x0b4b, 0x0000 }, + { 0x0c00, 0x0b4d, 0x0000 }, + { 0x8700, 0x0b5c, 0x2000 }, + { 0x0a00, 0x0b57, 0x0000 }, + { 0x0700, 0x0b5d, 0x0000 }, + { 0x8d00, 0x0be7, 0x7000 }, + { 0x8700, 0x0b9c, 0x6000 }, + { 0x8700, 0x0b83, 0x5000 }, + { 0x8d00, 0x0b6b, 0x4000 }, + { 0x8d00, 0x0b67, 0x3000 }, + { 0x8700, 0x0b61, 0x2000 }, + { 0x0700, 0x0b60, 0x0000 }, + { 0x0d00, 0x0b66, 0x0000 }, + { 0x8d00, 0x0b69, 0x2000 }, + { 0x0d00, 0x0b68, 0x0000 }, + { 0x0d00, 0x0b6a, 0x0000 }, + { 0x8d00, 0x0b6f, 0x3000 }, + { 0x8d00, 0x0b6d, 0x2000 }, + { 0x0d00, 0x0b6c, 0x0000 }, + { 0x0d00, 0x0b6e, 0x0000 }, + { 0x8700, 0x0b71, 0x2000 }, + { 0x1a00, 0x0b70, 0x0000 }, + { 0x0c00, 0x0b82, 0x0000 }, + { 0x8700, 0x0b8f, 0x4000 }, + { 0x8700, 0x0b88, 0x3000 }, + { 0x8700, 0x0b86, 0x2000 }, + { 0x0700, 0x0b85, 0x0000 }, + { 0x0700, 0x0b87, 0x0000 }, + { 0x8700, 0x0b8a, 0x2000 }, + { 0x0700, 0x0b89, 0x0000 }, + { 0x0700, 0x0b8e, 0x0000 }, + { 0x8700, 0x0b94, 0x3000 }, + { 0x8700, 0x0b92, 0x2000 }, + { 0x0700, 0x0b90, 0x0000 }, + { 0x0700, 0x0b93, 0x0000 }, + { 0x8700, 0x0b99, 0x2000 }, + { 0x0700, 0x0b95, 0x0000 }, + { 0x0700, 0x0b9a, 0x0000 }, + { 0x8700, 0x0bb7, 0x5000 }, + { 0x8700, 0x0bae, 0x4000 }, + { 0x8700, 0x0ba4, 0x3000 }, + { 0x8700, 0x0b9f, 0x2000 }, + { 0x0700, 0x0b9e, 0x0000 }, + { 0x0700, 0x0ba3, 0x0000 }, + { 0x8700, 0x0ba9, 0x2000 }, + { 0x0700, 0x0ba8, 0x0000 }, + { 0x0700, 0x0baa, 0x0000 }, + { 0x8700, 0x0bb2, 0x3000 }, + { 0x8700, 0x0bb0, 0x2000 }, + { 0x0700, 0x0baf, 0x0000 }, + { 0x0700, 0x0bb1, 0x0000 }, + { 0x8700, 0x0bb4, 0x2000 }, + { 0x0700, 0x0bb3, 0x0000 }, + { 0x0700, 0x0bb5, 0x0000 }, + { 0x8a00, 0x0bc6, 0x4000 }, + { 0x8a00, 0x0bbf, 0x3000 }, + { 0x8700, 0x0bb9, 0x2000 }, + { 0x0700, 0x0bb8, 0x0000 }, + { 0x0a00, 0x0bbe, 0x0000 }, + { 0x8a00, 0x0bc1, 0x2000 }, + { 0x0c00, 0x0bc0, 0x0000 }, + { 0x0a00, 0x0bc2, 0x0000 }, + { 0x8a00, 0x0bcb, 0x3000 }, + { 0x8a00, 0x0bc8, 0x2000 }, + { 0x0a00, 0x0bc7, 0x0000 }, + { 0x0a00, 0x0bca, 0x0000 }, + { 0x8c00, 0x0bcd, 0x2000 }, + { 0x0a00, 0x0bcc, 0x0000 }, + { 0x0a00, 0x0bd7, 0x0000 }, + { 0x8700, 0x0c0f, 0x6000 }, + { 0x9a00, 0x0bf7, 0x5000 }, + { 0x8d00, 0x0bef, 0x4000 }, + { 0x8d00, 0x0beb, 0x3000 }, + { 0x8d00, 0x0be9, 0x2000 }, + { 0x0d00, 0x0be8, 0x0000 }, + { 0x0d00, 0x0bea, 0x0000 }, + { 0x8d00, 0x0bed, 0x2000 }, + { 0x0d00, 0x0bec, 0x0000 }, + { 0x0d00, 0x0bee, 0x0000 }, + { 0x9a00, 0x0bf3, 0x3000 }, + { 0x8f00, 0x0bf1, 0x2000 }, + { 0x0f00, 0x0bf0, 0x0000 }, + { 0x0f00, 0x0bf2, 0x0000 }, + { 0x9a00, 0x0bf5, 0x2000 }, + { 0x1a00, 0x0bf4, 0x0000 }, + { 0x1a00, 0x0bf6, 0x0000 }, + { 0x8700, 0x0c06, 0x4000 }, + { 0x8a00, 0x0c01, 0x3000 }, + { 0x9700, 0x0bf9, 0x2000 }, + { 0x1a00, 0x0bf8, 0x0000 }, + { 0x1a00, 0x0bfa, 0x0000 }, + { 0x8a00, 0x0c03, 0x2000 }, + { 0x0a00, 0x0c02, 0x0000 }, + { 0x0700, 0x0c05, 0x0000 }, + { 0x8700, 0x0c0a, 0x3000 }, + { 0x8700, 0x0c08, 0x2000 }, + { 0x0700, 0x0c07, 0x0000 }, + { 0x0700, 0x0c09, 0x0000 }, + { 0x8700, 0x0c0c, 0x2000 }, + { 0x0700, 0x0c0b, 0x0000 }, + { 0x0700, 0x0c0e, 0x0000 }, + { 0x8700, 0x0c20, 0x5000 }, + { 0x8700, 0x0c18, 0x4000 }, + { 0x8700, 0x0c14, 0x3000 }, + { 0x8700, 0x0c12, 0x2000 }, + { 0x0700, 0x0c10, 0x0000 }, + { 0x0700, 0x0c13, 0x0000 }, + { 0x8700, 0x0c16, 0x2000 }, + { 0x0700, 0x0c15, 0x0000 }, + { 0x0700, 0x0c17, 0x0000 }, + { 0x8700, 0x0c1c, 0x3000 }, + { 0x8700, 0x0c1a, 0x2000 }, + { 0x0700, 0x0c19, 0x0000 }, + { 0x0700, 0x0c1b, 0x0000 }, + { 0x8700, 0x0c1e, 0x2000 }, + { 0x0700, 0x0c1d, 0x0000 }, + { 0x0700, 0x0c1f, 0x0000 }, + { 0x8700, 0x0c28, 0x4000 }, + { 0x8700, 0x0c24, 0x3000 }, + { 0x8700, 0x0c22, 0x2000 }, + { 0x0700, 0x0c21, 0x0000 }, + { 0x0700, 0x0c23, 0x0000 }, + { 0x8700, 0x0c26, 0x2000 }, + { 0x0700, 0x0c25, 0x0000 }, + { 0x0700, 0x0c27, 0x0000 }, + { 0x8700, 0x0c2d, 0x3000 }, + { 0x8700, 0x0c2b, 0x2000 }, + { 0x0700, 0x0c2a, 0x0000 }, + { 0x0700, 0x0c2c, 0x0000 }, + { 0x8700, 0x0c2f, 0x2000 }, + { 0x0700, 0x0c2e, 0x0000 }, + { 0x0700, 0x0c30, 0x0000 }, + { 0x8700, 0x0d0e, 0x8000 }, + { 0x8700, 0x0ca1, 0x7000 }, + { 0x8d00, 0x0c6c, 0x6000 }, + { 0x8c00, 0x0c47, 0x5000 }, + { 0x8c00, 0x0c3e, 0x4000 }, + { 0x8700, 0x0c36, 0x3000 }, + { 0x8700, 0x0c33, 0x2000 }, + { 0x0700, 0x0c32, 0x0000 }, + { 0x0700, 0x0c35, 0x0000 }, + { 0x8700, 0x0c38, 0x2000 }, + { 0x0700, 0x0c37, 0x0000 }, + { 0x0700, 0x0c39, 0x0000 }, + { 0x8a00, 0x0c42, 0x3000 }, + { 0x8c00, 0x0c40, 0x2000 }, + { 0x0c00, 0x0c3f, 0x0000 }, + { 0x0a00, 0x0c41, 0x0000 }, + { 0x8a00, 0x0c44, 0x2000 }, + { 0x0a00, 0x0c43, 0x0000 }, + { 0x0c00, 0x0c46, 0x0000 }, + { 0x8700, 0x0c60, 0x4000 }, + { 0x8c00, 0x0c4c, 0x3000 }, + { 0x8c00, 0x0c4a, 0x2000 }, + { 0x0c00, 0x0c48, 0x0000 }, + { 0x0c00, 0x0c4b, 0x0000 }, + { 0x8c00, 0x0c55, 0x2000 }, + { 0x0c00, 0x0c4d, 0x0000 }, + { 0x0c00, 0x0c56, 0x0000 }, + { 0x8d00, 0x0c68, 0x3000 }, + { 0x8d00, 0x0c66, 0x2000 }, + { 0x0700, 0x0c61, 0x0000 }, + { 0x0d00, 0x0c67, 0x0000 }, + { 0x8d00, 0x0c6a, 0x2000 }, + { 0x0d00, 0x0c69, 0x0000 }, + { 0x0d00, 0x0c6b, 0x0000 }, + { 0x8700, 0x0c90, 0x5000 }, + { 0x8700, 0x0c87, 0x4000 }, + { 0x8a00, 0x0c82, 0x3000 }, + { 0x8d00, 0x0c6e, 0x2000 }, + { 0x0d00, 0x0c6d, 0x0000 }, + { 0x0d00, 0x0c6f, 0x0000 }, + { 0x8700, 0x0c85, 0x2000 }, + { 0x0a00, 0x0c83, 0x0000 }, + { 0x0700, 0x0c86, 0x0000 }, + { 0x8700, 0x0c8b, 0x3000 }, + { 0x8700, 0x0c89, 0x2000 }, + { 0x0700, 0x0c88, 0x0000 }, + { 0x0700, 0x0c8a, 0x0000 }, + { 0x8700, 0x0c8e, 0x2000 }, + { 0x0700, 0x0c8c, 0x0000 }, + { 0x0700, 0x0c8f, 0x0000 }, + { 0x8700, 0x0c99, 0x4000 }, + { 0x8700, 0x0c95, 0x3000 }, + { 0x8700, 0x0c93, 0x2000 }, + { 0x0700, 0x0c92, 0x0000 }, + { 0x0700, 0x0c94, 0x0000 }, + { 0x8700, 0x0c97, 0x2000 }, + { 0x0700, 0x0c96, 0x0000 }, + { 0x0700, 0x0c98, 0x0000 }, + { 0x8700, 0x0c9d, 0x3000 }, + { 0x8700, 0x0c9b, 0x2000 }, + { 0x0700, 0x0c9a, 0x0000 }, + { 0x0700, 0x0c9c, 0x0000 }, + { 0x8700, 0x0c9f, 0x2000 }, + { 0x0700, 0x0c9e, 0x0000 }, + { 0x0700, 0x0ca0, 0x0000 }, + { 0x8c00, 0x0cc6, 0x6000 }, + { 0x8700, 0x0cb2, 0x5000 }, + { 0x8700, 0x0caa, 0x4000 }, + { 0x8700, 0x0ca5, 0x3000 }, + { 0x8700, 0x0ca3, 0x2000 }, + { 0x0700, 0x0ca2, 0x0000 }, + { 0x0700, 0x0ca4, 0x0000 }, + { 0x8700, 0x0ca7, 0x2000 }, + { 0x0700, 0x0ca6, 0x0000 }, + { 0x0700, 0x0ca8, 0x0000 }, + { 0x8700, 0x0cae, 0x3000 }, + { 0x8700, 0x0cac, 0x2000 }, + { 0x0700, 0x0cab, 0x0000 }, + { 0x0700, 0x0cad, 0x0000 }, + { 0x8700, 0x0cb0, 0x2000 }, + { 0x0700, 0x0caf, 0x0000 }, + { 0x0700, 0x0cb1, 0x0000 }, + { 0x8700, 0x0cbd, 0x4000 }, + { 0x8700, 0x0cb7, 0x3000 }, + { 0x8700, 0x0cb5, 0x2000 }, + { 0x0700, 0x0cb3, 0x0000 }, + { 0x0700, 0x0cb6, 0x0000 }, + { 0x8700, 0x0cb9, 0x2000 }, + { 0x0700, 0x0cb8, 0x0000 }, + { 0x0c00, 0x0cbc, 0x0000 }, + { 0x8a00, 0x0cc1, 0x3000 }, + { 0x8c00, 0x0cbf, 0x2000 }, + { 0x0a00, 0x0cbe, 0x0000 }, + { 0x0a00, 0x0cc0, 0x0000 }, + { 0x8a00, 0x0cc3, 0x2000 }, + { 0x0a00, 0x0cc2, 0x0000 }, + { 0x0a00, 0x0cc4, 0x0000 }, + { 0x8d00, 0x0cea, 0x5000 }, + { 0x8a00, 0x0cd6, 0x4000 }, + { 0x8a00, 0x0ccb, 0x3000 }, + { 0x8a00, 0x0cc8, 0x2000 }, + { 0x0a00, 0x0cc7, 0x0000 }, + { 0x0a00, 0x0cca, 0x0000 }, + { 0x8c00, 0x0ccd, 0x2000 }, + { 0x0c00, 0x0ccc, 0x0000 }, + { 0x0a00, 0x0cd5, 0x0000 }, + { 0x8d00, 0x0ce6, 0x3000 }, + { 0x8700, 0x0ce0, 0x2000 }, + { 0x0700, 0x0cde, 0x0000 }, + { 0x0700, 0x0ce1, 0x0000 }, + { 0x8d00, 0x0ce8, 0x2000 }, + { 0x0d00, 0x0ce7, 0x0000 }, + { 0x0d00, 0x0ce9, 0x0000 }, + { 0x8700, 0x0d05, 0x4000 }, + { 0x8d00, 0x0cee, 0x3000 }, + { 0x8d00, 0x0cec, 0x2000 }, + { 0x0d00, 0x0ceb, 0x0000 }, + { 0x0d00, 0x0ced, 0x0000 }, + { 0x8a00, 0x0d02, 0x2000 }, + { 0x0d00, 0x0cef, 0x0000 }, + { 0x0a00, 0x0d03, 0x0000 }, + { 0x8700, 0x0d09, 0x3000 }, + { 0x8700, 0x0d07, 0x2000 }, + { 0x0700, 0x0d06, 0x0000 }, + { 0x0700, 0x0d08, 0x0000 }, + { 0x8700, 0x0d0b, 0x2000 }, + { 0x0700, 0x0d0a, 0x0000 }, + { 0x0700, 0x0d0c, 0x0000 }, + { 0x8d00, 0x0d6c, 0x7000 }, + { 0x8700, 0x0d30, 0x6000 }, + { 0x8700, 0x0d1f, 0x5000 }, + { 0x8700, 0x0d17, 0x4000 }, + { 0x8700, 0x0d13, 0x3000 }, + { 0x8700, 0x0d10, 0x2000 }, + { 0x0700, 0x0d0f, 0x0000 }, + { 0x0700, 0x0d12, 0x0000 }, + { 0x8700, 0x0d15, 0x2000 }, + { 0x0700, 0x0d14, 0x0000 }, + { 0x0700, 0x0d16, 0x0000 }, + { 0x8700, 0x0d1b, 0x3000 }, + { 0x8700, 0x0d19, 0x2000 }, + { 0x0700, 0x0d18, 0x0000 }, + { 0x0700, 0x0d1a, 0x0000 }, + { 0x8700, 0x0d1d, 0x2000 }, + { 0x0700, 0x0d1c, 0x0000 }, + { 0x0700, 0x0d1e, 0x0000 }, + { 0x8700, 0x0d27, 0x4000 }, + { 0x8700, 0x0d23, 0x3000 }, + { 0x8700, 0x0d21, 0x2000 }, + { 0x0700, 0x0d20, 0x0000 }, + { 0x0700, 0x0d22, 0x0000 }, + { 0x8700, 0x0d25, 0x2000 }, + { 0x0700, 0x0d24, 0x0000 }, + { 0x0700, 0x0d26, 0x0000 }, + { 0x8700, 0x0d2c, 0x3000 }, + { 0x8700, 0x0d2a, 0x2000 }, + { 0x0700, 0x0d28, 0x0000 }, + { 0x0700, 0x0d2b, 0x0000 }, + { 0x8700, 0x0d2e, 0x2000 }, + { 0x0700, 0x0d2d, 0x0000 }, + { 0x0700, 0x0d2f, 0x0000 }, + { 0x8a00, 0x0d46, 0x5000 }, + { 0x8700, 0x0d38, 0x4000 }, + { 0x8700, 0x0d34, 0x3000 }, + { 0x8700, 0x0d32, 0x2000 }, + { 0x0700, 0x0d31, 0x0000 }, + { 0x0700, 0x0d33, 0x0000 }, + { 0x8700, 0x0d36, 0x2000 }, + { 0x0700, 0x0d35, 0x0000 }, + { 0x0700, 0x0d37, 0x0000 }, + { 0x8a00, 0x0d40, 0x3000 }, + { 0x8a00, 0x0d3e, 0x2000 }, + { 0x0700, 0x0d39, 0x0000 }, + { 0x0a00, 0x0d3f, 0x0000 }, + { 0x8c00, 0x0d42, 0x2000 }, + { 0x0c00, 0x0d41, 0x0000 }, + { 0x0c00, 0x0d43, 0x0000 }, + { 0x8700, 0x0d60, 0x4000 }, + { 0x8a00, 0x0d4b, 0x3000 }, + { 0x8a00, 0x0d48, 0x2000 }, + { 0x0a00, 0x0d47, 0x0000 }, + { 0x0a00, 0x0d4a, 0x0000 }, + { 0x8c00, 0x0d4d, 0x2000 }, + { 0x0a00, 0x0d4c, 0x0000 }, + { 0x0a00, 0x0d57, 0x0000 }, + { 0x8d00, 0x0d68, 0x3000 }, + { 0x8d00, 0x0d66, 0x2000 }, + { 0x0700, 0x0d61, 0x0000 }, + { 0x0d00, 0x0d67, 0x0000 }, + { 0x8d00, 0x0d6a, 0x2000 }, + { 0x0d00, 0x0d69, 0x0000 }, + { 0x0d00, 0x0d6b, 0x0000 }, + { 0x8700, 0x0da2, 0x6000 }, + { 0x8700, 0x0d8f, 0x5000 }, + { 0x8700, 0x0d87, 0x4000 }, + { 0x8a00, 0x0d82, 0x3000 }, + { 0x8d00, 0x0d6e, 0x2000 }, + { 0x0d00, 0x0d6d, 0x0000 }, + { 0x0d00, 0x0d6f, 0x0000 }, + { 0x8700, 0x0d85, 0x2000 }, + { 0x0a00, 0x0d83, 0x0000 }, + { 0x0700, 0x0d86, 0x0000 }, + { 0x8700, 0x0d8b, 0x3000 }, + { 0x8700, 0x0d89, 0x2000 }, + { 0x0700, 0x0d88, 0x0000 }, + { 0x0700, 0x0d8a, 0x0000 }, + { 0x8700, 0x0d8d, 0x2000 }, + { 0x0700, 0x0d8c, 0x0000 }, + { 0x0700, 0x0d8e, 0x0000 }, + { 0x8700, 0x0d9a, 0x4000 }, + { 0x8700, 0x0d93, 0x3000 }, + { 0x8700, 0x0d91, 0x2000 }, + { 0x0700, 0x0d90, 0x0000 }, + { 0x0700, 0x0d92, 0x0000 }, + { 0x8700, 0x0d95, 0x2000 }, + { 0x0700, 0x0d94, 0x0000 }, + { 0x0700, 0x0d96, 0x0000 }, + { 0x8700, 0x0d9e, 0x3000 }, + { 0x8700, 0x0d9c, 0x2000 }, + { 0x0700, 0x0d9b, 0x0000 }, + { 0x0700, 0x0d9d, 0x0000 }, + { 0x8700, 0x0da0, 0x2000 }, + { 0x0700, 0x0d9f, 0x0000 }, + { 0x0700, 0x0da1, 0x0000 }, + { 0x8700, 0x0db3, 0x5000 }, + { 0x8700, 0x0daa, 0x4000 }, + { 0x8700, 0x0da6, 0x3000 }, + { 0x8700, 0x0da4, 0x2000 }, + { 0x0700, 0x0da3, 0x0000 }, + { 0x0700, 0x0da5, 0x0000 }, + { 0x8700, 0x0da8, 0x2000 }, + { 0x0700, 0x0da7, 0x0000 }, + { 0x0700, 0x0da9, 0x0000 }, + { 0x8700, 0x0dae, 0x3000 }, + { 0x8700, 0x0dac, 0x2000 }, + { 0x0700, 0x0dab, 0x0000 }, + { 0x0700, 0x0dad, 0x0000 }, + { 0x8700, 0x0db0, 0x2000 }, + { 0x0700, 0x0daf, 0x0000 }, + { 0x0700, 0x0db1, 0x0000 }, + { 0x8700, 0x0dbb, 0x4000 }, + { 0x8700, 0x0db7, 0x3000 }, + { 0x8700, 0x0db5, 0x2000 }, + { 0x0700, 0x0db4, 0x0000 }, + { 0x0700, 0x0db6, 0x0000 }, + { 0x8700, 0x0db9, 0x2000 }, + { 0x0700, 0x0db8, 0x0000 }, + { 0x0700, 0x0dba, 0x0000 }, + { 0x8700, 0x0dc2, 0x3000 }, + { 0x8700, 0x0dc0, 0x2000 }, + { 0x0700, 0x0dbd, 0x0000 }, + { 0x0700, 0x0dc1, 0x0000 }, + { 0x8700, 0x0dc4, 0x2000 }, + { 0x0700, 0x0dc3, 0x0000 }, + { 0x0700, 0x0dc5, 0x0000 }, + { 0x8700, 0x0f55, 0x9000 }, + { 0x8700, 0x0ea5, 0x8000 }, + { 0x8700, 0x0e2d, 0x7000 }, + { 0x8700, 0x0e0d, 0x6000 }, + { 0x8a00, 0x0ddf, 0x5000 }, + { 0x8c00, 0x0dd6, 0x4000 }, + { 0x8a00, 0x0dd1, 0x3000 }, + { 0x8a00, 0x0dcf, 0x2000 }, + { 0x0c00, 0x0dca, 0x0000 }, + { 0x0a00, 0x0dd0, 0x0000 }, + { 0x8c00, 0x0dd3, 0x2000 }, + { 0x0c00, 0x0dd2, 0x0000 }, + { 0x0c00, 0x0dd4, 0x0000 }, + { 0x8a00, 0x0ddb, 0x3000 }, + { 0x8a00, 0x0dd9, 0x2000 }, + { 0x0a00, 0x0dd8, 0x0000 }, + { 0x0a00, 0x0dda, 0x0000 }, + { 0x8a00, 0x0ddd, 0x2000 }, + { 0x0a00, 0x0ddc, 0x0000 }, + { 0x0a00, 0x0dde, 0x0000 }, + { 0x8700, 0x0e05, 0x4000 }, + { 0x8700, 0x0e01, 0x3000 }, + { 0x8a00, 0x0df3, 0x2000 }, + { 0x0a00, 0x0df2, 0x0000 }, + { 0x1500, 0x0df4, 0x0000 }, + { 0x8700, 0x0e03, 0x2000 }, + { 0x0700, 0x0e02, 0x0000 }, + { 0x0700, 0x0e04, 0x0000 }, + { 0x8700, 0x0e09, 0x3000 }, + { 0x8700, 0x0e07, 0x2000 }, + { 0x0700, 0x0e06, 0x0000 }, + { 0x0700, 0x0e08, 0x0000 }, + { 0x8700, 0x0e0b, 0x2000 }, + { 0x0700, 0x0e0a, 0x0000 }, + { 0x0700, 0x0e0c, 0x0000 }, + { 0x8700, 0x0e1d, 0x5000 }, + { 0x8700, 0x0e15, 0x4000 }, + { 0x8700, 0x0e11, 0x3000 }, + { 0x8700, 0x0e0f, 0x2000 }, + { 0x0700, 0x0e0e, 0x0000 }, + { 0x0700, 0x0e10, 0x0000 }, + { 0x8700, 0x0e13, 0x2000 }, + { 0x0700, 0x0e12, 0x0000 }, + { 0x0700, 0x0e14, 0x0000 }, + { 0x8700, 0x0e19, 0x3000 }, + { 0x8700, 0x0e17, 0x2000 }, + { 0x0700, 0x0e16, 0x0000 }, + { 0x0700, 0x0e18, 0x0000 }, + { 0x8700, 0x0e1b, 0x2000 }, + { 0x0700, 0x0e1a, 0x0000 }, + { 0x0700, 0x0e1c, 0x0000 }, + { 0x8700, 0x0e25, 0x4000 }, + { 0x8700, 0x0e21, 0x3000 }, + { 0x8700, 0x0e1f, 0x2000 }, + { 0x0700, 0x0e1e, 0x0000 }, + { 0x0700, 0x0e20, 0x0000 }, + { 0x8700, 0x0e23, 0x2000 }, + { 0x0700, 0x0e22, 0x0000 }, + { 0x0700, 0x0e24, 0x0000 }, + { 0x8700, 0x0e29, 0x3000 }, + { 0x8700, 0x0e27, 0x2000 }, + { 0x0700, 0x0e26, 0x0000 }, + { 0x0700, 0x0e28, 0x0000 }, + { 0x8700, 0x0e2b, 0x2000 }, + { 0x0700, 0x0e2a, 0x0000 }, + { 0x0700, 0x0e2c, 0x0000 }, + { 0x8d00, 0x0e51, 0x6000 }, + { 0x8700, 0x0e41, 0x5000 }, + { 0x8c00, 0x0e35, 0x4000 }, + { 0x8c00, 0x0e31, 0x3000 }, + { 0x8700, 0x0e2f, 0x2000 }, + { 0x0700, 0x0e2e, 0x0000 }, + { 0x0700, 0x0e30, 0x0000 }, + { 0x8700, 0x0e33, 0x2000 }, + { 0x0700, 0x0e32, 0x0000 }, + { 0x0c00, 0x0e34, 0x0000 }, + { 0x8c00, 0x0e39, 0x3000 }, + { 0x8c00, 0x0e37, 0x2000 }, + { 0x0c00, 0x0e36, 0x0000 }, + { 0x0c00, 0x0e38, 0x0000 }, + { 0x9700, 0x0e3f, 0x2000 }, + { 0x0c00, 0x0e3a, 0x0000 }, + { 0x0700, 0x0e40, 0x0000 }, + { 0x8c00, 0x0e49, 0x4000 }, + { 0x8700, 0x0e45, 0x3000 }, + { 0x8700, 0x0e43, 0x2000 }, + { 0x0700, 0x0e42, 0x0000 }, + { 0x0700, 0x0e44, 0x0000 }, + { 0x8c00, 0x0e47, 0x2000 }, + { 0x0600, 0x0e46, 0x0000 }, + { 0x0c00, 0x0e48, 0x0000 }, + { 0x8c00, 0x0e4d, 0x3000 }, + { 0x8c00, 0x0e4b, 0x2000 }, + { 0x0c00, 0x0e4a, 0x0000 }, + { 0x0c00, 0x0e4c, 0x0000 }, + { 0x9500, 0x0e4f, 0x2000 }, + { 0x0c00, 0x0e4e, 0x0000 }, + { 0x0d00, 0x0e50, 0x0000 }, + { 0x8700, 0x0e8a, 0x5000 }, + { 0x8d00, 0x0e59, 0x4000 }, + { 0x8d00, 0x0e55, 0x3000 }, + { 0x8d00, 0x0e53, 0x2000 }, + { 0x0d00, 0x0e52, 0x0000 }, + { 0x0d00, 0x0e54, 0x0000 }, + { 0x8d00, 0x0e57, 0x2000 }, + { 0x0d00, 0x0e56, 0x0000 }, + { 0x0d00, 0x0e58, 0x0000 }, + { 0x8700, 0x0e82, 0x3000 }, + { 0x9500, 0x0e5b, 0x2000 }, + { 0x1500, 0x0e5a, 0x0000 }, + { 0x0700, 0x0e81, 0x0000 }, + { 0x8700, 0x0e87, 0x2000 }, + { 0x0700, 0x0e84, 0x0000 }, + { 0x0700, 0x0e88, 0x0000 }, + { 0x8700, 0x0e9b, 0x4000 }, + { 0x8700, 0x0e96, 0x3000 }, + { 0x8700, 0x0e94, 0x2000 }, + { 0x0700, 0x0e8d, 0x0000 }, + { 0x0700, 0x0e95, 0x0000 }, + { 0x8700, 0x0e99, 0x2000 }, + { 0x0700, 0x0e97, 0x0000 }, + { 0x0700, 0x0e9a, 0x0000 }, + { 0x8700, 0x0e9f, 0x3000 }, + { 0x8700, 0x0e9d, 0x2000 }, + { 0x0700, 0x0e9c, 0x0000 }, + { 0x0700, 0x0e9e, 0x0000 }, + { 0x8700, 0x0ea2, 0x2000 }, + { 0x0700, 0x0ea1, 0x0000 }, + { 0x0700, 0x0ea3, 0x0000 }, + { 0x9a00, 0x0f14, 0x7000 }, + { 0x8d00, 0x0ed0, 0x6000 }, + { 0x8c00, 0x0eb9, 0x5000 }, + { 0x8c00, 0x0eb1, 0x4000 }, + { 0x8700, 0x0ead, 0x3000 }, + { 0x8700, 0x0eaa, 0x2000 }, + { 0x0700, 0x0ea7, 0x0000 }, + { 0x0700, 0x0eab, 0x0000 }, + { 0x8700, 0x0eaf, 0x2000 }, + { 0x0700, 0x0eae, 0x0000 }, + { 0x0700, 0x0eb0, 0x0000 }, + { 0x8c00, 0x0eb5, 0x3000 }, + { 0x8700, 0x0eb3, 0x2000 }, + { 0x0700, 0x0eb2, 0x0000 }, + { 0x0c00, 0x0eb4, 0x0000 }, + { 0x8c00, 0x0eb7, 0x2000 }, + { 0x0c00, 0x0eb6, 0x0000 }, + { 0x0c00, 0x0eb8, 0x0000 }, + { 0x8700, 0x0ec4, 0x4000 }, + { 0x8700, 0x0ec0, 0x3000 }, + { 0x8c00, 0x0ebc, 0x2000 }, + { 0x0c00, 0x0ebb, 0x0000 }, + { 0x0700, 0x0ebd, 0x0000 }, + { 0x8700, 0x0ec2, 0x2000 }, + { 0x0700, 0x0ec1, 0x0000 }, + { 0x0700, 0x0ec3, 0x0000 }, + { 0x8c00, 0x0eca, 0x3000 }, + { 0x8c00, 0x0ec8, 0x2000 }, + { 0x0600, 0x0ec6, 0x0000 }, + { 0x0c00, 0x0ec9, 0x0000 }, + { 0x8c00, 0x0ecc, 0x2000 }, + { 0x0c00, 0x0ecb, 0x0000 }, + { 0x0c00, 0x0ecd, 0x0000 }, + { 0x9500, 0x0f04, 0x5000 }, + { 0x8d00, 0x0ed8, 0x4000 }, + { 0x8d00, 0x0ed4, 0x3000 }, + { 0x8d00, 0x0ed2, 0x2000 }, + { 0x0d00, 0x0ed1, 0x0000 }, + { 0x0d00, 0x0ed3, 0x0000 }, + { 0x8d00, 0x0ed6, 0x2000 }, + { 0x0d00, 0x0ed5, 0x0000 }, + { 0x0d00, 0x0ed7, 0x0000 }, + { 0x8700, 0x0f00, 0x3000 }, + { 0x8700, 0x0edc, 0x2000 }, + { 0x0d00, 0x0ed9, 0x0000 }, + { 0x0700, 0x0edd, 0x0000 }, + { 0x9a00, 0x0f02, 0x2000 }, + { 0x1a00, 0x0f01, 0x0000 }, + { 0x1a00, 0x0f03, 0x0000 }, + { 0x9500, 0x0f0c, 0x4000 }, + { 0x9500, 0x0f08, 0x3000 }, + { 0x9500, 0x0f06, 0x2000 }, + { 0x1500, 0x0f05, 0x0000 }, + { 0x1500, 0x0f07, 0x0000 }, + { 0x9500, 0x0f0a, 0x2000 }, + { 0x1500, 0x0f09, 0x0000 }, + { 0x1500, 0x0f0b, 0x0000 }, + { 0x9500, 0x0f10, 0x3000 }, + { 0x9500, 0x0f0e, 0x2000 }, + { 0x1500, 0x0f0d, 0x0000 }, + { 0x1500, 0x0f0f, 0x0000 }, + { 0x9500, 0x0f12, 0x2000 }, + { 0x1500, 0x0f11, 0x0000 }, + { 0x1a00, 0x0f13, 0x0000 }, + { 0x9a00, 0x0f34, 0x6000 }, + { 0x8d00, 0x0f24, 0x5000 }, + { 0x9a00, 0x0f1c, 0x4000 }, + { 0x8c00, 0x0f18, 0x3000 }, + { 0x9a00, 0x0f16, 0x2000 }, + { 0x1a00, 0x0f15, 0x0000 }, + { 0x1a00, 0x0f17, 0x0000 }, + { 0x9a00, 0x0f1a, 0x2000 }, + { 0x0c00, 0x0f19, 0x0000 }, + { 0x1a00, 0x0f1b, 0x0000 }, + { 0x8d00, 0x0f20, 0x3000 }, + { 0x9a00, 0x0f1e, 0x2000 }, + { 0x1a00, 0x0f1d, 0x0000 }, + { 0x1a00, 0x0f1f, 0x0000 }, + { 0x8d00, 0x0f22, 0x2000 }, + { 0x0d00, 0x0f21, 0x0000 }, + { 0x0d00, 0x0f23, 0x0000 }, + { 0x8f00, 0x0f2c, 0x4000 }, + { 0x8d00, 0x0f28, 0x3000 }, + { 0x8d00, 0x0f26, 0x2000 }, + { 0x0d00, 0x0f25, 0x0000 }, + { 0x0d00, 0x0f27, 0x0000 }, + { 0x8f00, 0x0f2a, 0x2000 }, + { 0x0d00, 0x0f29, 0x0000 }, + { 0x0f00, 0x0f2b, 0x0000 }, + { 0x8f00, 0x0f30, 0x3000 }, + { 0x8f00, 0x0f2e, 0x2000 }, + { 0x0f00, 0x0f2d, 0x0000 }, + { 0x0f00, 0x0f2f, 0x0000 }, + { 0x8f00, 0x0f32, 0x2000 }, + { 0x0f00, 0x0f31, 0x0000 }, + { 0x0f00, 0x0f33, 0x0000 }, + { 0x8700, 0x0f44, 0x5000 }, + { 0x9600, 0x0f3c, 0x4000 }, + { 0x9a00, 0x0f38, 0x3000 }, + { 0x9a00, 0x0f36, 0x2000 }, + { 0x0c00, 0x0f35, 0x0000 }, + { 0x0c00, 0x0f37, 0x0000 }, + { 0x9600, 0x0f3a, 0x2000 }, + { 0x0c00, 0x0f39, 0x0000 }, + { 0x1200, 0x0f3b, 0x0000 }, + { 0x8700, 0x0f40, 0x3000 }, + { 0x8a00, 0x0f3e, 0x2000 }, + { 0x1200, 0x0f3d, 0x0000 }, + { 0x0a00, 0x0f3f, 0x0000 }, + { 0x8700, 0x0f42, 0x2000 }, + { 0x0700, 0x0f41, 0x0000 }, + { 0x0700, 0x0f43, 0x0000 }, + { 0x8700, 0x0f4d, 0x4000 }, + { 0x8700, 0x0f49, 0x3000 }, + { 0x8700, 0x0f46, 0x2000 }, + { 0x0700, 0x0f45, 0x0000 }, + { 0x0700, 0x0f47, 0x0000 }, + { 0x8700, 0x0f4b, 0x2000 }, + { 0x0700, 0x0f4a, 0x0000 }, + { 0x0700, 0x0f4c, 0x0000 }, + { 0x8700, 0x0f51, 0x3000 }, + { 0x8700, 0x0f4f, 0x2000 }, + { 0x0700, 0x0f4e, 0x0000 }, + { 0x0700, 0x0f50, 0x0000 }, + { 0x8700, 0x0f53, 0x2000 }, + { 0x0700, 0x0f52, 0x0000 }, + { 0x0700, 0x0f54, 0x0000 }, + { 0x8700, 0x1013, 0x8000 }, + { 0x8c00, 0x0fa0, 0x7000 }, + { 0x8c00, 0x0f7b, 0x6000 }, + { 0x8700, 0x0f65, 0x5000 }, + { 0x8700, 0x0f5d, 0x4000 }, + { 0x8700, 0x0f59, 0x3000 }, + { 0x8700, 0x0f57, 0x2000 }, + { 0x0700, 0x0f56, 0x0000 }, + { 0x0700, 0x0f58, 0x0000 }, + { 0x8700, 0x0f5b, 0x2000 }, + { 0x0700, 0x0f5a, 0x0000 }, + { 0x0700, 0x0f5c, 0x0000 }, + { 0x8700, 0x0f61, 0x3000 }, + { 0x8700, 0x0f5f, 0x2000 }, + { 0x0700, 0x0f5e, 0x0000 }, + { 0x0700, 0x0f60, 0x0000 }, + { 0x8700, 0x0f63, 0x2000 }, + { 0x0700, 0x0f62, 0x0000 }, + { 0x0700, 0x0f64, 0x0000 }, + { 0x8c00, 0x0f73, 0x4000 }, + { 0x8700, 0x0f69, 0x3000 }, + { 0x8700, 0x0f67, 0x2000 }, + { 0x0700, 0x0f66, 0x0000 }, + { 0x0700, 0x0f68, 0x0000 }, + { 0x8c00, 0x0f71, 0x2000 }, + { 0x0700, 0x0f6a, 0x0000 }, + { 0x0c00, 0x0f72, 0x0000 }, + { 0x8c00, 0x0f77, 0x3000 }, + { 0x8c00, 0x0f75, 0x2000 }, + { 0x0c00, 0x0f74, 0x0000 }, + { 0x0c00, 0x0f76, 0x0000 }, + { 0x8c00, 0x0f79, 0x2000 }, + { 0x0c00, 0x0f78, 0x0000 }, + { 0x0c00, 0x0f7a, 0x0000 }, + { 0x8700, 0x0f8b, 0x5000 }, + { 0x8c00, 0x0f83, 0x4000 }, + { 0x8a00, 0x0f7f, 0x3000 }, + { 0x8c00, 0x0f7d, 0x2000 }, + { 0x0c00, 0x0f7c, 0x0000 }, + { 0x0c00, 0x0f7e, 0x0000 }, + { 0x8c00, 0x0f81, 0x2000 }, + { 0x0c00, 0x0f80, 0x0000 }, + { 0x0c00, 0x0f82, 0x0000 }, + { 0x8c00, 0x0f87, 0x3000 }, + { 0x9500, 0x0f85, 0x2000 }, + { 0x0c00, 0x0f84, 0x0000 }, + { 0x0c00, 0x0f86, 0x0000 }, + { 0x8700, 0x0f89, 0x2000 }, + { 0x0700, 0x0f88, 0x0000 }, + { 0x0700, 0x0f8a, 0x0000 }, + { 0x8c00, 0x0f97, 0x4000 }, + { 0x8c00, 0x0f93, 0x3000 }, + { 0x8c00, 0x0f91, 0x2000 }, + { 0x0c00, 0x0f90, 0x0000 }, + { 0x0c00, 0x0f92, 0x0000 }, + { 0x8c00, 0x0f95, 0x2000 }, + { 0x0c00, 0x0f94, 0x0000 }, + { 0x0c00, 0x0f96, 0x0000 }, + { 0x8c00, 0x0f9c, 0x3000 }, + { 0x8c00, 0x0f9a, 0x2000 }, + { 0x0c00, 0x0f99, 0x0000 }, + { 0x0c00, 0x0f9b, 0x0000 }, + { 0x8c00, 0x0f9e, 0x2000 }, + { 0x0c00, 0x0f9d, 0x0000 }, + { 0x0c00, 0x0f9f, 0x0000 }, + { 0x9a00, 0x0fc1, 0x6000 }, + { 0x8c00, 0x0fb0, 0x5000 }, + { 0x8c00, 0x0fa8, 0x4000 }, + { 0x8c00, 0x0fa4, 0x3000 }, + { 0x8c00, 0x0fa2, 0x2000 }, + { 0x0c00, 0x0fa1, 0x0000 }, + { 0x0c00, 0x0fa3, 0x0000 }, + { 0x8c00, 0x0fa6, 0x2000 }, + { 0x0c00, 0x0fa5, 0x0000 }, + { 0x0c00, 0x0fa7, 0x0000 }, + { 0x8c00, 0x0fac, 0x3000 }, + { 0x8c00, 0x0faa, 0x2000 }, + { 0x0c00, 0x0fa9, 0x0000 }, + { 0x0c00, 0x0fab, 0x0000 }, + { 0x8c00, 0x0fae, 0x2000 }, + { 0x0c00, 0x0fad, 0x0000 }, + { 0x0c00, 0x0faf, 0x0000 }, + { 0x8c00, 0x0fb8, 0x4000 }, + { 0x8c00, 0x0fb4, 0x3000 }, + { 0x8c00, 0x0fb2, 0x2000 }, + { 0x0c00, 0x0fb1, 0x0000 }, + { 0x0c00, 0x0fb3, 0x0000 }, + { 0x8c00, 0x0fb6, 0x2000 }, + { 0x0c00, 0x0fb5, 0x0000 }, + { 0x0c00, 0x0fb7, 0x0000 }, + { 0x8c00, 0x0fbc, 0x3000 }, + { 0x8c00, 0x0fba, 0x2000 }, + { 0x0c00, 0x0fb9, 0x0000 }, + { 0x0c00, 0x0fbb, 0x0000 }, + { 0x9a00, 0x0fbf, 0x2000 }, + { 0x1a00, 0x0fbe, 0x0000 }, + { 0x1a00, 0x0fc0, 0x0000 }, + { 0x8700, 0x1003, 0x5000 }, + { 0x9a00, 0x0fc9, 0x4000 }, + { 0x9a00, 0x0fc5, 0x3000 }, + { 0x9a00, 0x0fc3, 0x2000 }, + { 0x1a00, 0x0fc2, 0x0000 }, + { 0x1a00, 0x0fc4, 0x0000 }, + { 0x9a00, 0x0fc7, 0x2000 }, + { 0x0c00, 0x0fc6, 0x0000 }, + { 0x1a00, 0x0fc8, 0x0000 }, + { 0x9a00, 0x0fcf, 0x3000 }, + { 0x9a00, 0x0fcb, 0x2000 }, + { 0x1a00, 0x0fca, 0x0000 }, + { 0x1a00, 0x0fcc, 0x0000 }, + { 0x8700, 0x1001, 0x2000 }, + { 0x0700, 0x1000, 0x0000 }, + { 0x0700, 0x1002, 0x0000 }, + { 0x8700, 0x100b, 0x4000 }, + { 0x8700, 0x1007, 0x3000 }, + { 0x8700, 0x1005, 0x2000 }, + { 0x0700, 0x1004, 0x0000 }, + { 0x0700, 0x1006, 0x0000 }, + { 0x8700, 0x1009, 0x2000 }, + { 0x0700, 0x1008, 0x0000 }, + { 0x0700, 0x100a, 0x0000 }, + { 0x8700, 0x100f, 0x3000 }, + { 0x8700, 0x100d, 0x2000 }, + { 0x0700, 0x100c, 0x0000 }, + { 0x0700, 0x100e, 0x0000 }, + { 0x8700, 0x1011, 0x2000 }, + { 0x0700, 0x1010, 0x0000 }, + { 0x0700, 0x1012, 0x0000 }, + { 0x8900, 0x10a5, 0x7000 }, + { 0x8c00, 0x1039, 0x6000 }, + { 0x8700, 0x1024, 0x5000 }, + { 0x8700, 0x101b, 0x4000 }, + { 0x8700, 0x1017, 0x3000 }, + { 0x8700, 0x1015, 0x2000 }, + { 0x0700, 0x1014, 0x0000 }, + { 0x0700, 0x1016, 0x0000 }, + { 0x8700, 0x1019, 0x2000 }, + { 0x0700, 0x1018, 0x0000 }, + { 0x0700, 0x101a, 0x0000 }, + { 0x8700, 0x101f, 0x3000 }, + { 0x8700, 0x101d, 0x2000 }, + { 0x0700, 0x101c, 0x0000 }, + { 0x0700, 0x101e, 0x0000 }, + { 0x8700, 0x1021, 0x2000 }, + { 0x0700, 0x1020, 0x0000 }, + { 0x0700, 0x1023, 0x0000 }, + { 0x8c00, 0x102e, 0x4000 }, + { 0x8700, 0x1029, 0x3000 }, + { 0x8700, 0x1026, 0x2000 }, + { 0x0700, 0x1025, 0x0000 }, + { 0x0700, 0x1027, 0x0000 }, + { 0x8a00, 0x102c, 0x2000 }, + { 0x0700, 0x102a, 0x0000 }, + { 0x0c00, 0x102d, 0x0000 }, + { 0x8c00, 0x1032, 0x3000 }, + { 0x8c00, 0x1030, 0x2000 }, + { 0x0c00, 0x102f, 0x0000 }, + { 0x0a00, 0x1031, 0x0000 }, + { 0x8c00, 0x1037, 0x2000 }, + { 0x0c00, 0x1036, 0x0000 }, + { 0x0a00, 0x1038, 0x0000 }, + { 0x9500, 0x104f, 0x5000 }, + { 0x8d00, 0x1047, 0x4000 }, + { 0x8d00, 0x1043, 0x3000 }, + { 0x8d00, 0x1041, 0x2000 }, + { 0x0d00, 0x1040, 0x0000 }, + { 0x0d00, 0x1042, 0x0000 }, + { 0x8d00, 0x1045, 0x2000 }, + { 0x0d00, 0x1044, 0x0000 }, + { 0x0d00, 0x1046, 0x0000 }, + { 0x9500, 0x104b, 0x3000 }, + { 0x8d00, 0x1049, 0x2000 }, + { 0x0d00, 0x1048, 0x0000 }, + { 0x1500, 0x104a, 0x0000 }, + { 0x9500, 0x104d, 0x2000 }, + { 0x1500, 0x104c, 0x0000 }, + { 0x1500, 0x104e, 0x0000 }, + { 0x8a00, 0x1057, 0x4000 }, + { 0x8700, 0x1053, 0x3000 }, + { 0x8700, 0x1051, 0x2000 }, + { 0x0700, 0x1050, 0x0000 }, + { 0x0700, 0x1052, 0x0000 }, + { 0x8700, 0x1055, 0x2000 }, + { 0x0700, 0x1054, 0x0000 }, + { 0x0a00, 0x1056, 0x0000 }, + { 0x8900, 0x10a1, 0x3000 }, + { 0x8c00, 0x1059, 0x2000 }, + { 0x0c00, 0x1058, 0x0000 }, + { 0x0900, 0x10a0, 0x0000 }, + { 0x8900, 0x10a3, 0x2000 }, + { 0x0900, 0x10a2, 0x0000 }, + { 0x0900, 0x10a4, 0x0000 }, + { 0x8900, 0x10c5, 0x6000 }, + { 0x8900, 0x10b5, 0x5000 }, + { 0x8900, 0x10ad, 0x4000 }, + { 0x8900, 0x10a9, 0x3000 }, + { 0x8900, 0x10a7, 0x2000 }, + { 0x0900, 0x10a6, 0x0000 }, + { 0x0900, 0x10a8, 0x0000 }, + { 0x8900, 0x10ab, 0x2000 }, + { 0x0900, 0x10aa, 0x0000 }, + { 0x0900, 0x10ac, 0x0000 }, + { 0x8900, 0x10b1, 0x3000 }, + { 0x8900, 0x10af, 0x2000 }, + { 0x0900, 0x10ae, 0x0000 }, + { 0x0900, 0x10b0, 0x0000 }, + { 0x8900, 0x10b3, 0x2000 }, + { 0x0900, 0x10b2, 0x0000 }, + { 0x0900, 0x10b4, 0x0000 }, + { 0x8900, 0x10bd, 0x4000 }, + { 0x8900, 0x10b9, 0x3000 }, + { 0x8900, 0x10b7, 0x2000 }, + { 0x0900, 0x10b6, 0x0000 }, + { 0x0900, 0x10b8, 0x0000 }, + { 0x8900, 0x10bb, 0x2000 }, + { 0x0900, 0x10ba, 0x0000 }, + { 0x0900, 0x10bc, 0x0000 }, + { 0x8900, 0x10c1, 0x3000 }, + { 0x8900, 0x10bf, 0x2000 }, + { 0x0900, 0x10be, 0x0000 }, + { 0x0900, 0x10c0, 0x0000 }, + { 0x8900, 0x10c3, 0x2000 }, + { 0x0900, 0x10c2, 0x0000 }, + { 0x0900, 0x10c4, 0x0000 }, + { 0x8700, 0x10df, 0x5000 }, + { 0x8700, 0x10d7, 0x4000 }, + { 0x8700, 0x10d3, 0x3000 }, + { 0x8700, 0x10d1, 0x2000 }, + { 0x0700, 0x10d0, 0x0000 }, + { 0x0700, 0x10d2, 0x0000 }, + { 0x8700, 0x10d5, 0x2000 }, + { 0x0700, 0x10d4, 0x0000 }, + { 0x0700, 0x10d6, 0x0000 }, + { 0x8700, 0x10db, 0x3000 }, + { 0x8700, 0x10d9, 0x2000 }, + { 0x0700, 0x10d8, 0x0000 }, + { 0x0700, 0x10da, 0x0000 }, + { 0x8700, 0x10dd, 0x2000 }, + { 0x0700, 0x10dc, 0x0000 }, + { 0x0700, 0x10de, 0x0000 }, + { 0x8700, 0x10e7, 0x4000 }, + { 0x8700, 0x10e3, 0x3000 }, + { 0x8700, 0x10e1, 0x2000 }, + { 0x0700, 0x10e0, 0x0000 }, + { 0x0700, 0x10e2, 0x0000 }, + { 0x8700, 0x10e5, 0x2000 }, + { 0x0700, 0x10e4, 0x0000 }, + { 0x0700, 0x10e6, 0x0000 }, + { 0x8700, 0x10eb, 0x3000 }, + { 0x8700, 0x10e9, 0x2000 }, + { 0x0700, 0x10e8, 0x0000 }, + { 0x0700, 0x10ea, 0x0000 }, + { 0x8700, 0x10ed, 0x2000 }, + { 0x0700, 0x10ec, 0x0000 }, + { 0x0700, 0x10ee, 0x0000 }, + { 0x8700, 0x1322, 0xa000 }, + { 0x8700, 0x1205, 0x9000 }, + { 0x8700, 0x117a, 0x8000 }, + { 0x8700, 0x1135, 0x7000 }, + { 0x8700, 0x1115, 0x6000 }, + { 0x8700, 0x1105, 0x5000 }, + { 0x8700, 0x10f7, 0x4000 }, + { 0x8700, 0x10f3, 0x3000 }, + { 0x8700, 0x10f1, 0x2000 }, + { 0x0700, 0x10f0, 0x0000 }, + { 0x0700, 0x10f2, 0x0000 }, + { 0x8700, 0x10f5, 0x2000 }, + { 0x0700, 0x10f4, 0x0000 }, + { 0x0700, 0x10f6, 0x0000 }, + { 0x8700, 0x1101, 0x3000 }, + { 0x9500, 0x10fb, 0x2000 }, + { 0x0700, 0x10f8, 0x0000 }, + { 0x0700, 0x1100, 0x0000 }, + { 0x8700, 0x1103, 0x2000 }, + { 0x0700, 0x1102, 0x0000 }, + { 0x0700, 0x1104, 0x0000 }, + { 0x8700, 0x110d, 0x4000 }, + { 0x8700, 0x1109, 0x3000 }, + { 0x8700, 0x1107, 0x2000 }, + { 0x0700, 0x1106, 0x0000 }, + { 0x0700, 0x1108, 0x0000 }, + { 0x8700, 0x110b, 0x2000 }, + { 0x0700, 0x110a, 0x0000 }, + { 0x0700, 0x110c, 0x0000 }, + { 0x8700, 0x1111, 0x3000 }, + { 0x8700, 0x110f, 0x2000 }, + { 0x0700, 0x110e, 0x0000 }, + { 0x0700, 0x1110, 0x0000 }, + { 0x8700, 0x1113, 0x2000 }, + { 0x0700, 0x1112, 0x0000 }, + { 0x0700, 0x1114, 0x0000 }, + { 0x8700, 0x1125, 0x5000 }, + { 0x8700, 0x111d, 0x4000 }, + { 0x8700, 0x1119, 0x3000 }, + { 0x8700, 0x1117, 0x2000 }, + { 0x0700, 0x1116, 0x0000 }, + { 0x0700, 0x1118, 0x0000 }, + { 0x8700, 0x111b, 0x2000 }, + { 0x0700, 0x111a, 0x0000 }, + { 0x0700, 0x111c, 0x0000 }, + { 0x8700, 0x1121, 0x3000 }, + { 0x8700, 0x111f, 0x2000 }, + { 0x0700, 0x111e, 0x0000 }, + { 0x0700, 0x1120, 0x0000 }, + { 0x8700, 0x1123, 0x2000 }, + { 0x0700, 0x1122, 0x0000 }, + { 0x0700, 0x1124, 0x0000 }, + { 0x8700, 0x112d, 0x4000 }, + { 0x8700, 0x1129, 0x3000 }, + { 0x8700, 0x1127, 0x2000 }, + { 0x0700, 0x1126, 0x0000 }, + { 0x0700, 0x1128, 0x0000 }, + { 0x8700, 0x112b, 0x2000 }, + { 0x0700, 0x112a, 0x0000 }, + { 0x0700, 0x112c, 0x0000 }, + { 0x8700, 0x1131, 0x3000 }, + { 0x8700, 0x112f, 0x2000 }, + { 0x0700, 0x112e, 0x0000 }, + { 0x0700, 0x1130, 0x0000 }, + { 0x8700, 0x1133, 0x2000 }, + { 0x0700, 0x1132, 0x0000 }, + { 0x0700, 0x1134, 0x0000 }, + { 0x8700, 0x1155, 0x6000 }, + { 0x8700, 0x1145, 0x5000 }, + { 0x8700, 0x113d, 0x4000 }, + { 0x8700, 0x1139, 0x3000 }, + { 0x8700, 0x1137, 0x2000 }, + { 0x0700, 0x1136, 0x0000 }, + { 0x0700, 0x1138, 0x0000 }, + { 0x8700, 0x113b, 0x2000 }, + { 0x0700, 0x113a, 0x0000 }, + { 0x0700, 0x113c, 0x0000 }, + { 0x8700, 0x1141, 0x3000 }, + { 0x8700, 0x113f, 0x2000 }, + { 0x0700, 0x113e, 0x0000 }, + { 0x0700, 0x1140, 0x0000 }, + { 0x8700, 0x1143, 0x2000 }, + { 0x0700, 0x1142, 0x0000 }, + { 0x0700, 0x1144, 0x0000 }, + { 0x8700, 0x114d, 0x4000 }, + { 0x8700, 0x1149, 0x3000 }, + { 0x8700, 0x1147, 0x2000 }, + { 0x0700, 0x1146, 0x0000 }, + { 0x0700, 0x1148, 0x0000 }, + { 0x8700, 0x114b, 0x2000 }, + { 0x0700, 0x114a, 0x0000 }, + { 0x0700, 0x114c, 0x0000 }, + { 0x8700, 0x1151, 0x3000 }, + { 0x8700, 0x114f, 0x2000 }, + { 0x0700, 0x114e, 0x0000 }, + { 0x0700, 0x1150, 0x0000 }, + { 0x8700, 0x1153, 0x2000 }, + { 0x0700, 0x1152, 0x0000 }, + { 0x0700, 0x1154, 0x0000 }, + { 0x8700, 0x116a, 0x5000 }, + { 0x8700, 0x1162, 0x4000 }, + { 0x8700, 0x1159, 0x3000 }, + { 0x8700, 0x1157, 0x2000 }, + { 0x0700, 0x1156, 0x0000 }, + { 0x0700, 0x1158, 0x0000 }, + { 0x8700, 0x1160, 0x2000 }, + { 0x0700, 0x115f, 0x0000 }, + { 0x0700, 0x1161, 0x0000 }, + { 0x8700, 0x1166, 0x3000 }, + { 0x8700, 0x1164, 0x2000 }, + { 0x0700, 0x1163, 0x0000 }, + { 0x0700, 0x1165, 0x0000 }, + { 0x8700, 0x1168, 0x2000 }, + { 0x0700, 0x1167, 0x0000 }, + { 0x0700, 0x1169, 0x0000 }, + { 0x8700, 0x1172, 0x4000 }, + { 0x8700, 0x116e, 0x3000 }, + { 0x8700, 0x116c, 0x2000 }, + { 0x0700, 0x116b, 0x0000 }, + { 0x0700, 0x116d, 0x0000 }, + { 0x8700, 0x1170, 0x2000 }, + { 0x0700, 0x116f, 0x0000 }, + { 0x0700, 0x1171, 0x0000 }, + { 0x8700, 0x1176, 0x3000 }, + { 0x8700, 0x1174, 0x2000 }, + { 0x0700, 0x1173, 0x0000 }, + { 0x0700, 0x1175, 0x0000 }, + { 0x8700, 0x1178, 0x2000 }, + { 0x0700, 0x1177, 0x0000 }, + { 0x0700, 0x1179, 0x0000 }, + { 0x8700, 0x11bf, 0x7000 }, + { 0x8700, 0x119a, 0x6000 }, + { 0x8700, 0x118a, 0x5000 }, + { 0x8700, 0x1182, 0x4000 }, + { 0x8700, 0x117e, 0x3000 }, + { 0x8700, 0x117c, 0x2000 }, + { 0x0700, 0x117b, 0x0000 }, + { 0x0700, 0x117d, 0x0000 }, + { 0x8700, 0x1180, 0x2000 }, + { 0x0700, 0x117f, 0x0000 }, + { 0x0700, 0x1181, 0x0000 }, + { 0x8700, 0x1186, 0x3000 }, + { 0x8700, 0x1184, 0x2000 }, + { 0x0700, 0x1183, 0x0000 }, + { 0x0700, 0x1185, 0x0000 }, + { 0x8700, 0x1188, 0x2000 }, + { 0x0700, 0x1187, 0x0000 }, + { 0x0700, 0x1189, 0x0000 }, + { 0x8700, 0x1192, 0x4000 }, + { 0x8700, 0x118e, 0x3000 }, + { 0x8700, 0x118c, 0x2000 }, + { 0x0700, 0x118b, 0x0000 }, + { 0x0700, 0x118d, 0x0000 }, + { 0x8700, 0x1190, 0x2000 }, + { 0x0700, 0x118f, 0x0000 }, + { 0x0700, 0x1191, 0x0000 }, + { 0x8700, 0x1196, 0x3000 }, + { 0x8700, 0x1194, 0x2000 }, + { 0x0700, 0x1193, 0x0000 }, + { 0x0700, 0x1195, 0x0000 }, + { 0x8700, 0x1198, 0x2000 }, + { 0x0700, 0x1197, 0x0000 }, + { 0x0700, 0x1199, 0x0000 }, + { 0x8700, 0x11af, 0x5000 }, + { 0x8700, 0x11a2, 0x4000 }, + { 0x8700, 0x119e, 0x3000 }, + { 0x8700, 0x119c, 0x2000 }, + { 0x0700, 0x119b, 0x0000 }, + { 0x0700, 0x119d, 0x0000 }, + { 0x8700, 0x11a0, 0x2000 }, + { 0x0700, 0x119f, 0x0000 }, + { 0x0700, 0x11a1, 0x0000 }, + { 0x8700, 0x11ab, 0x3000 }, + { 0x8700, 0x11a9, 0x2000 }, + { 0x0700, 0x11a8, 0x0000 }, + { 0x0700, 0x11aa, 0x0000 }, + { 0x8700, 0x11ad, 0x2000 }, + { 0x0700, 0x11ac, 0x0000 }, + { 0x0700, 0x11ae, 0x0000 }, + { 0x8700, 0x11b7, 0x4000 }, + { 0x8700, 0x11b3, 0x3000 }, + { 0x8700, 0x11b1, 0x2000 }, + { 0x0700, 0x11b0, 0x0000 }, + { 0x0700, 0x11b2, 0x0000 }, + { 0x8700, 0x11b5, 0x2000 }, + { 0x0700, 0x11b4, 0x0000 }, + { 0x0700, 0x11b6, 0x0000 }, + { 0x8700, 0x11bb, 0x3000 }, + { 0x8700, 0x11b9, 0x2000 }, + { 0x0700, 0x11b8, 0x0000 }, + { 0x0700, 0x11ba, 0x0000 }, + { 0x8700, 0x11bd, 0x2000 }, + { 0x0700, 0x11bc, 0x0000 }, + { 0x0700, 0x11be, 0x0000 }, + { 0x8700, 0x11df, 0x6000 }, + { 0x8700, 0x11cf, 0x5000 }, + { 0x8700, 0x11c7, 0x4000 }, + { 0x8700, 0x11c3, 0x3000 }, + { 0x8700, 0x11c1, 0x2000 }, + { 0x0700, 0x11c0, 0x0000 }, + { 0x0700, 0x11c2, 0x0000 }, + { 0x8700, 0x11c5, 0x2000 }, + { 0x0700, 0x11c4, 0x0000 }, + { 0x0700, 0x11c6, 0x0000 }, + { 0x8700, 0x11cb, 0x3000 }, + { 0x8700, 0x11c9, 0x2000 }, + { 0x0700, 0x11c8, 0x0000 }, + { 0x0700, 0x11ca, 0x0000 }, + { 0x8700, 0x11cd, 0x2000 }, + { 0x0700, 0x11cc, 0x0000 }, + { 0x0700, 0x11ce, 0x0000 }, + { 0x8700, 0x11d7, 0x4000 }, + { 0x8700, 0x11d3, 0x3000 }, + { 0x8700, 0x11d1, 0x2000 }, + { 0x0700, 0x11d0, 0x0000 }, + { 0x0700, 0x11d2, 0x0000 }, + { 0x8700, 0x11d5, 0x2000 }, + { 0x0700, 0x11d4, 0x0000 }, + { 0x0700, 0x11d6, 0x0000 }, + { 0x8700, 0x11db, 0x3000 }, + { 0x8700, 0x11d9, 0x2000 }, + { 0x0700, 0x11d8, 0x0000 }, + { 0x0700, 0x11da, 0x0000 }, + { 0x8700, 0x11dd, 0x2000 }, + { 0x0700, 0x11dc, 0x0000 }, + { 0x0700, 0x11de, 0x0000 }, + { 0x8700, 0x11ef, 0x5000 }, + { 0x8700, 0x11e7, 0x4000 }, + { 0x8700, 0x11e3, 0x3000 }, + { 0x8700, 0x11e1, 0x2000 }, + { 0x0700, 0x11e0, 0x0000 }, + { 0x0700, 0x11e2, 0x0000 }, + { 0x8700, 0x11e5, 0x2000 }, + { 0x0700, 0x11e4, 0x0000 }, + { 0x0700, 0x11e6, 0x0000 }, + { 0x8700, 0x11eb, 0x3000 }, + { 0x8700, 0x11e9, 0x2000 }, + { 0x0700, 0x11e8, 0x0000 }, + { 0x0700, 0x11ea, 0x0000 }, + { 0x8700, 0x11ed, 0x2000 }, + { 0x0700, 0x11ec, 0x0000 }, + { 0x0700, 0x11ee, 0x0000 }, + { 0x8700, 0x11f7, 0x4000 }, + { 0x8700, 0x11f3, 0x3000 }, + { 0x8700, 0x11f1, 0x2000 }, + { 0x0700, 0x11f0, 0x0000 }, + { 0x0700, 0x11f2, 0x0000 }, + { 0x8700, 0x11f5, 0x2000 }, + { 0x0700, 0x11f4, 0x0000 }, + { 0x0700, 0x11f6, 0x0000 }, + { 0x8700, 0x1201, 0x3000 }, + { 0x8700, 0x11f9, 0x2000 }, + { 0x0700, 0x11f8, 0x0000 }, + { 0x0700, 0x1200, 0x0000 }, + { 0x8700, 0x1203, 0x2000 }, + { 0x0700, 0x1202, 0x0000 }, + { 0x0700, 0x1204, 0x0000 }, + { 0x8700, 0x1292, 0x8000 }, + { 0x8700, 0x1246, 0x7000 }, + { 0x8700, 0x1226, 0x6000 }, + { 0x8700, 0x1216, 0x5000 }, + { 0x8700, 0x120e, 0x4000 }, + { 0x8700, 0x120a, 0x3000 }, + { 0x8700, 0x1208, 0x2000 }, + { 0x0700, 0x1206, 0x0000 }, + { 0x0700, 0x1209, 0x0000 }, + { 0x8700, 0x120c, 0x2000 }, + { 0x0700, 0x120b, 0x0000 }, + { 0x0700, 0x120d, 0x0000 }, + { 0x8700, 0x1212, 0x3000 }, + { 0x8700, 0x1210, 0x2000 }, + { 0x0700, 0x120f, 0x0000 }, + { 0x0700, 0x1211, 0x0000 }, + { 0x8700, 0x1214, 0x2000 }, + { 0x0700, 0x1213, 0x0000 }, + { 0x0700, 0x1215, 0x0000 }, + { 0x8700, 0x121e, 0x4000 }, + { 0x8700, 0x121a, 0x3000 }, + { 0x8700, 0x1218, 0x2000 }, + { 0x0700, 0x1217, 0x0000 }, + { 0x0700, 0x1219, 0x0000 }, + { 0x8700, 0x121c, 0x2000 }, + { 0x0700, 0x121b, 0x0000 }, + { 0x0700, 0x121d, 0x0000 }, + { 0x8700, 0x1222, 0x3000 }, + { 0x8700, 0x1220, 0x2000 }, + { 0x0700, 0x121f, 0x0000 }, + { 0x0700, 0x1221, 0x0000 }, + { 0x8700, 0x1224, 0x2000 }, + { 0x0700, 0x1223, 0x0000 }, + { 0x0700, 0x1225, 0x0000 }, + { 0x8700, 0x1236, 0x5000 }, + { 0x8700, 0x122e, 0x4000 }, + { 0x8700, 0x122a, 0x3000 }, + { 0x8700, 0x1228, 0x2000 }, + { 0x0700, 0x1227, 0x0000 }, + { 0x0700, 0x1229, 0x0000 }, + { 0x8700, 0x122c, 0x2000 }, + { 0x0700, 0x122b, 0x0000 }, + { 0x0700, 0x122d, 0x0000 }, + { 0x8700, 0x1232, 0x3000 }, + { 0x8700, 0x1230, 0x2000 }, + { 0x0700, 0x122f, 0x0000 }, + { 0x0700, 0x1231, 0x0000 }, + { 0x8700, 0x1234, 0x2000 }, + { 0x0700, 0x1233, 0x0000 }, + { 0x0700, 0x1235, 0x0000 }, + { 0x8700, 0x123e, 0x4000 }, + { 0x8700, 0x123a, 0x3000 }, + { 0x8700, 0x1238, 0x2000 }, + { 0x0700, 0x1237, 0x0000 }, + { 0x0700, 0x1239, 0x0000 }, + { 0x8700, 0x123c, 0x2000 }, + { 0x0700, 0x123b, 0x0000 }, + { 0x0700, 0x123d, 0x0000 }, + { 0x8700, 0x1242, 0x3000 }, + { 0x8700, 0x1240, 0x2000 }, + { 0x0700, 0x123f, 0x0000 }, + { 0x0700, 0x1241, 0x0000 }, + { 0x8700, 0x1244, 0x2000 }, + { 0x0700, 0x1243, 0x0000 }, + { 0x0700, 0x1245, 0x0000 }, + { 0x8700, 0x126e, 0x6000 }, + { 0x8700, 0x125c, 0x5000 }, + { 0x8700, 0x1252, 0x4000 }, + { 0x8700, 0x124c, 0x3000 }, + { 0x8700, 0x124a, 0x2000 }, + { 0x0700, 0x1248, 0x0000 }, + { 0x0700, 0x124b, 0x0000 }, + { 0x8700, 0x1250, 0x2000 }, + { 0x0700, 0x124d, 0x0000 }, + { 0x0700, 0x1251, 0x0000 }, + { 0x8700, 0x1256, 0x3000 }, + { 0x8700, 0x1254, 0x2000 }, + { 0x0700, 0x1253, 0x0000 }, + { 0x0700, 0x1255, 0x0000 }, + { 0x8700, 0x125a, 0x2000 }, + { 0x0700, 0x1258, 0x0000 }, + { 0x0700, 0x125b, 0x0000 }, + { 0x8700, 0x1266, 0x4000 }, + { 0x8700, 0x1262, 0x3000 }, + { 0x8700, 0x1260, 0x2000 }, + { 0x0700, 0x125d, 0x0000 }, + { 0x0700, 0x1261, 0x0000 }, + { 0x8700, 0x1264, 0x2000 }, + { 0x0700, 0x1263, 0x0000 }, + { 0x0700, 0x1265, 0x0000 }, + { 0x8700, 0x126a, 0x3000 }, + { 0x8700, 0x1268, 0x2000 }, + { 0x0700, 0x1267, 0x0000 }, + { 0x0700, 0x1269, 0x0000 }, + { 0x8700, 0x126c, 0x2000 }, + { 0x0700, 0x126b, 0x0000 }, + { 0x0700, 0x126d, 0x0000 }, + { 0x8700, 0x127e, 0x5000 }, + { 0x8700, 0x1276, 0x4000 }, + { 0x8700, 0x1272, 0x3000 }, + { 0x8700, 0x1270, 0x2000 }, + { 0x0700, 0x126f, 0x0000 }, + { 0x0700, 0x1271, 0x0000 }, + { 0x8700, 0x1274, 0x2000 }, + { 0x0700, 0x1273, 0x0000 }, + { 0x0700, 0x1275, 0x0000 }, + { 0x8700, 0x127a, 0x3000 }, + { 0x8700, 0x1278, 0x2000 }, + { 0x0700, 0x1277, 0x0000 }, + { 0x0700, 0x1279, 0x0000 }, + { 0x8700, 0x127c, 0x2000 }, + { 0x0700, 0x127b, 0x0000 }, + { 0x0700, 0x127d, 0x0000 }, + { 0x8700, 0x1286, 0x4000 }, + { 0x8700, 0x1282, 0x3000 }, + { 0x8700, 0x1280, 0x2000 }, + { 0x0700, 0x127f, 0x0000 }, + { 0x0700, 0x1281, 0x0000 }, + { 0x8700, 0x1284, 0x2000 }, + { 0x0700, 0x1283, 0x0000 }, + { 0x0700, 0x1285, 0x0000 }, + { 0x8700, 0x128c, 0x3000 }, + { 0x8700, 0x128a, 0x2000 }, + { 0x0700, 0x1288, 0x0000 }, + { 0x0700, 0x128b, 0x0000 }, + { 0x8700, 0x1290, 0x2000 }, + { 0x0700, 0x128d, 0x0000 }, + { 0x0700, 0x1291, 0x0000 }, + { 0x8700, 0x12dc, 0x7000 }, + { 0x8700, 0x12b4, 0x6000 }, + { 0x8700, 0x12a2, 0x5000 }, + { 0x8700, 0x129a, 0x4000 }, + { 0x8700, 0x1296, 0x3000 }, + { 0x8700, 0x1294, 0x2000 }, + { 0x0700, 0x1293, 0x0000 }, + { 0x0700, 0x1295, 0x0000 }, + { 0x8700, 0x1298, 0x2000 }, + { 0x0700, 0x1297, 0x0000 }, + { 0x0700, 0x1299, 0x0000 }, + { 0x8700, 0x129e, 0x3000 }, + { 0x8700, 0x129c, 0x2000 }, + { 0x0700, 0x129b, 0x0000 }, + { 0x0700, 0x129d, 0x0000 }, + { 0x8700, 0x12a0, 0x2000 }, + { 0x0700, 0x129f, 0x0000 }, + { 0x0700, 0x12a1, 0x0000 }, + { 0x8700, 0x12aa, 0x4000 }, + { 0x8700, 0x12a6, 0x3000 }, + { 0x8700, 0x12a4, 0x2000 }, + { 0x0700, 0x12a3, 0x0000 }, + { 0x0700, 0x12a5, 0x0000 }, + { 0x8700, 0x12a8, 0x2000 }, + { 0x0700, 0x12a7, 0x0000 }, + { 0x0700, 0x12a9, 0x0000 }, + { 0x8700, 0x12ae, 0x3000 }, + { 0x8700, 0x12ac, 0x2000 }, + { 0x0700, 0x12ab, 0x0000 }, + { 0x0700, 0x12ad, 0x0000 }, + { 0x8700, 0x12b2, 0x2000 }, + { 0x0700, 0x12b0, 0x0000 }, + { 0x0700, 0x12b3, 0x0000 }, + { 0x8700, 0x12ca, 0x5000 }, + { 0x8700, 0x12be, 0x4000 }, + { 0x8700, 0x12ba, 0x3000 }, + { 0x8700, 0x12b8, 0x2000 }, + { 0x0700, 0x12b5, 0x0000 }, + { 0x0700, 0x12b9, 0x0000 }, + { 0x8700, 0x12bc, 0x2000 }, + { 0x0700, 0x12bb, 0x0000 }, + { 0x0700, 0x12bd, 0x0000 }, + { 0x8700, 0x12c4, 0x3000 }, + { 0x8700, 0x12c2, 0x2000 }, + { 0x0700, 0x12c0, 0x0000 }, + { 0x0700, 0x12c3, 0x0000 }, + { 0x8700, 0x12c8, 0x2000 }, + { 0x0700, 0x12c5, 0x0000 }, + { 0x0700, 0x12c9, 0x0000 }, + { 0x8700, 0x12d3, 0x4000 }, + { 0x8700, 0x12ce, 0x3000 }, + { 0x8700, 0x12cc, 0x2000 }, + { 0x0700, 0x12cb, 0x0000 }, + { 0x0700, 0x12cd, 0x0000 }, + { 0x8700, 0x12d1, 0x2000 }, + { 0x0700, 0x12d0, 0x0000 }, + { 0x0700, 0x12d2, 0x0000 }, + { 0x8700, 0x12d8, 0x3000 }, + { 0x8700, 0x12d5, 0x2000 }, + { 0x0700, 0x12d4, 0x0000 }, + { 0x0700, 0x12d6, 0x0000 }, + { 0x8700, 0x12da, 0x2000 }, + { 0x0700, 0x12d9, 0x0000 }, + { 0x0700, 0x12db, 0x0000 }, + { 0x8700, 0x12fd, 0x6000 }, + { 0x8700, 0x12ec, 0x5000 }, + { 0x8700, 0x12e4, 0x4000 }, + { 0x8700, 0x12e0, 0x3000 }, + { 0x8700, 0x12de, 0x2000 }, + { 0x0700, 0x12dd, 0x0000 }, + { 0x0700, 0x12df, 0x0000 }, + { 0x8700, 0x12e2, 0x2000 }, + { 0x0700, 0x12e1, 0x0000 }, + { 0x0700, 0x12e3, 0x0000 }, + { 0x8700, 0x12e8, 0x3000 }, + { 0x8700, 0x12e6, 0x2000 }, + { 0x0700, 0x12e5, 0x0000 }, + { 0x0700, 0x12e7, 0x0000 }, + { 0x8700, 0x12ea, 0x2000 }, + { 0x0700, 0x12e9, 0x0000 }, + { 0x0700, 0x12eb, 0x0000 }, + { 0x8700, 0x12f5, 0x4000 }, + { 0x8700, 0x12f1, 0x3000 }, + { 0x8700, 0x12ee, 0x2000 }, + { 0x0700, 0x12ed, 0x0000 }, + { 0x0700, 0x12f0, 0x0000 }, + { 0x8700, 0x12f3, 0x2000 }, + { 0x0700, 0x12f2, 0x0000 }, + { 0x0700, 0x12f4, 0x0000 }, + { 0x8700, 0x12f9, 0x3000 }, + { 0x8700, 0x12f7, 0x2000 }, + { 0x0700, 0x12f6, 0x0000 }, + { 0x0700, 0x12f8, 0x0000 }, + { 0x8700, 0x12fb, 0x2000 }, + { 0x0700, 0x12fa, 0x0000 }, + { 0x0700, 0x12fc, 0x0000 }, + { 0x8700, 0x130d, 0x5000 }, + { 0x8700, 0x1305, 0x4000 }, + { 0x8700, 0x1301, 0x3000 }, + { 0x8700, 0x12ff, 0x2000 }, + { 0x0700, 0x12fe, 0x0000 }, + { 0x0700, 0x1300, 0x0000 }, + { 0x8700, 0x1303, 0x2000 }, + { 0x0700, 0x1302, 0x0000 }, + { 0x0700, 0x1304, 0x0000 }, + { 0x8700, 0x1309, 0x3000 }, + { 0x8700, 0x1307, 0x2000 }, + { 0x0700, 0x1306, 0x0000 }, + { 0x0700, 0x1308, 0x0000 }, + { 0x8700, 0x130b, 0x2000 }, + { 0x0700, 0x130a, 0x0000 }, + { 0x0700, 0x130c, 0x0000 }, + { 0x8700, 0x1319, 0x4000 }, + { 0x8700, 0x1313, 0x3000 }, + { 0x8700, 0x1310, 0x2000 }, + { 0x0700, 0x130e, 0x0000 }, + { 0x0700, 0x1312, 0x0000 }, + { 0x8700, 0x1315, 0x2000 }, + { 0x0700, 0x1314, 0x0000 }, + { 0x0700, 0x1318, 0x0000 }, + { 0x8700, 0x131d, 0x3000 }, + { 0x8700, 0x131b, 0x2000 }, + { 0x0700, 0x131a, 0x0000 }, + { 0x0700, 0x131c, 0x0000 }, + { 0x8700, 0x1320, 0x2000 }, + { 0x0700, 0x131e, 0x0000 }, + { 0x0700, 0x1321, 0x0000 }, + { 0x8700, 0x1458, 0x9000 }, + { 0x8700, 0x13cc, 0x8000 }, + { 0x8d00, 0x1369, 0x7000 }, + { 0x8700, 0x1342, 0x6000 }, + { 0x8700, 0x1332, 0x5000 }, + { 0x8700, 0x132a, 0x4000 }, + { 0x8700, 0x1326, 0x3000 }, + { 0x8700, 0x1324, 0x2000 }, + { 0x0700, 0x1323, 0x0000 }, + { 0x0700, 0x1325, 0x0000 }, + { 0x8700, 0x1328, 0x2000 }, + { 0x0700, 0x1327, 0x0000 }, + { 0x0700, 0x1329, 0x0000 }, + { 0x8700, 0x132e, 0x3000 }, + { 0x8700, 0x132c, 0x2000 }, + { 0x0700, 0x132b, 0x0000 }, + { 0x0700, 0x132d, 0x0000 }, + { 0x8700, 0x1330, 0x2000 }, + { 0x0700, 0x132f, 0x0000 }, + { 0x0700, 0x1331, 0x0000 }, + { 0x8700, 0x133a, 0x4000 }, + { 0x8700, 0x1336, 0x3000 }, + { 0x8700, 0x1334, 0x2000 }, + { 0x0700, 0x1333, 0x0000 }, + { 0x0700, 0x1335, 0x0000 }, + { 0x8700, 0x1338, 0x2000 }, + { 0x0700, 0x1337, 0x0000 }, + { 0x0700, 0x1339, 0x0000 }, + { 0x8700, 0x133e, 0x3000 }, + { 0x8700, 0x133c, 0x2000 }, + { 0x0700, 0x133b, 0x0000 }, + { 0x0700, 0x133d, 0x0000 }, + { 0x8700, 0x1340, 0x2000 }, + { 0x0700, 0x133f, 0x0000 }, + { 0x0700, 0x1341, 0x0000 }, + { 0x8700, 0x1353, 0x5000 }, + { 0x8700, 0x134b, 0x4000 }, + { 0x8700, 0x1346, 0x3000 }, + { 0x8700, 0x1344, 0x2000 }, + { 0x0700, 0x1343, 0x0000 }, + { 0x0700, 0x1345, 0x0000 }, + { 0x8700, 0x1349, 0x2000 }, + { 0x0700, 0x1348, 0x0000 }, + { 0x0700, 0x134a, 0x0000 }, + { 0x8700, 0x134f, 0x3000 }, + { 0x8700, 0x134d, 0x2000 }, + { 0x0700, 0x134c, 0x0000 }, + { 0x0700, 0x134e, 0x0000 }, + { 0x8700, 0x1351, 0x2000 }, + { 0x0700, 0x1350, 0x0000 }, + { 0x0700, 0x1352, 0x0000 }, + { 0x9500, 0x1361, 0x4000 }, + { 0x8700, 0x1357, 0x3000 }, + { 0x8700, 0x1355, 0x2000 }, + { 0x0700, 0x1354, 0x0000 }, + { 0x0700, 0x1356, 0x0000 }, + { 0x8700, 0x1359, 0x2000 }, + { 0x0700, 0x1358, 0x0000 }, + { 0x0700, 0x135a, 0x0000 }, + { 0x9500, 0x1365, 0x3000 }, + { 0x9500, 0x1363, 0x2000 }, + { 0x1500, 0x1362, 0x0000 }, + { 0x1500, 0x1364, 0x0000 }, + { 0x9500, 0x1367, 0x2000 }, + { 0x1500, 0x1366, 0x0000 }, + { 0x1500, 0x1368, 0x0000 }, + { 0x8700, 0x13ac, 0x6000 }, + { 0x8f00, 0x1379, 0x5000 }, + { 0x8d00, 0x1371, 0x4000 }, + { 0x8d00, 0x136d, 0x3000 }, + { 0x8d00, 0x136b, 0x2000 }, + { 0x0d00, 0x136a, 0x0000 }, + { 0x0d00, 0x136c, 0x0000 }, + { 0x8d00, 0x136f, 0x2000 }, + { 0x0d00, 0x136e, 0x0000 }, + { 0x0d00, 0x1370, 0x0000 }, + { 0x8f00, 0x1375, 0x3000 }, + { 0x8f00, 0x1373, 0x2000 }, + { 0x0f00, 0x1372, 0x0000 }, + { 0x0f00, 0x1374, 0x0000 }, + { 0x8f00, 0x1377, 0x2000 }, + { 0x0f00, 0x1376, 0x0000 }, + { 0x0f00, 0x1378, 0x0000 }, + { 0x8700, 0x13a4, 0x4000 }, + { 0x8700, 0x13a0, 0x3000 }, + { 0x8f00, 0x137b, 0x2000 }, + { 0x0f00, 0x137a, 0x0000 }, + { 0x0f00, 0x137c, 0x0000 }, + { 0x8700, 0x13a2, 0x2000 }, + { 0x0700, 0x13a1, 0x0000 }, + { 0x0700, 0x13a3, 0x0000 }, + { 0x8700, 0x13a8, 0x3000 }, + { 0x8700, 0x13a6, 0x2000 }, + { 0x0700, 0x13a5, 0x0000 }, + { 0x0700, 0x13a7, 0x0000 }, + { 0x8700, 0x13aa, 0x2000 }, + { 0x0700, 0x13a9, 0x0000 }, + { 0x0700, 0x13ab, 0x0000 }, + { 0x8700, 0x13bc, 0x5000 }, + { 0x8700, 0x13b4, 0x4000 }, + { 0x8700, 0x13b0, 0x3000 }, + { 0x8700, 0x13ae, 0x2000 }, + { 0x0700, 0x13ad, 0x0000 }, + { 0x0700, 0x13af, 0x0000 }, + { 0x8700, 0x13b2, 0x2000 }, + { 0x0700, 0x13b1, 0x0000 }, + { 0x0700, 0x13b3, 0x0000 }, + { 0x8700, 0x13b8, 0x3000 }, + { 0x8700, 0x13b6, 0x2000 }, + { 0x0700, 0x13b5, 0x0000 }, + { 0x0700, 0x13b7, 0x0000 }, + { 0x8700, 0x13ba, 0x2000 }, + { 0x0700, 0x13b9, 0x0000 }, + { 0x0700, 0x13bb, 0x0000 }, + { 0x8700, 0x13c4, 0x4000 }, + { 0x8700, 0x13c0, 0x3000 }, + { 0x8700, 0x13be, 0x2000 }, + { 0x0700, 0x13bd, 0x0000 }, + { 0x0700, 0x13bf, 0x0000 }, + { 0x8700, 0x13c2, 0x2000 }, + { 0x0700, 0x13c1, 0x0000 }, + { 0x0700, 0x13c3, 0x0000 }, + { 0x8700, 0x13c8, 0x3000 }, + { 0x8700, 0x13c6, 0x2000 }, + { 0x0700, 0x13c5, 0x0000 }, + { 0x0700, 0x13c7, 0x0000 }, + { 0x8700, 0x13ca, 0x2000 }, + { 0x0700, 0x13c9, 0x0000 }, + { 0x0700, 0x13cb, 0x0000 }, + { 0x8700, 0x1418, 0x7000 }, + { 0x8700, 0x13ec, 0x6000 }, + { 0x8700, 0x13dc, 0x5000 }, + { 0x8700, 0x13d4, 0x4000 }, + { 0x8700, 0x13d0, 0x3000 }, + { 0x8700, 0x13ce, 0x2000 }, + { 0x0700, 0x13cd, 0x0000 }, + { 0x0700, 0x13cf, 0x0000 }, + { 0x8700, 0x13d2, 0x2000 }, + { 0x0700, 0x13d1, 0x0000 }, + { 0x0700, 0x13d3, 0x0000 }, + { 0x8700, 0x13d8, 0x3000 }, + { 0x8700, 0x13d6, 0x2000 }, + { 0x0700, 0x13d5, 0x0000 }, + { 0x0700, 0x13d7, 0x0000 }, + { 0x8700, 0x13da, 0x2000 }, + { 0x0700, 0x13d9, 0x0000 }, + { 0x0700, 0x13db, 0x0000 }, + { 0x8700, 0x13e4, 0x4000 }, + { 0x8700, 0x13e0, 0x3000 }, + { 0x8700, 0x13de, 0x2000 }, + { 0x0700, 0x13dd, 0x0000 }, + { 0x0700, 0x13df, 0x0000 }, + { 0x8700, 0x13e2, 0x2000 }, + { 0x0700, 0x13e1, 0x0000 }, + { 0x0700, 0x13e3, 0x0000 }, + { 0x8700, 0x13e8, 0x3000 }, + { 0x8700, 0x13e6, 0x2000 }, + { 0x0700, 0x13e5, 0x0000 }, + { 0x0700, 0x13e7, 0x0000 }, + { 0x8700, 0x13ea, 0x2000 }, + { 0x0700, 0x13e9, 0x0000 }, + { 0x0700, 0x13eb, 0x0000 }, + { 0x8700, 0x1408, 0x5000 }, + { 0x8700, 0x13f4, 0x4000 }, + { 0x8700, 0x13f0, 0x3000 }, + { 0x8700, 0x13ee, 0x2000 }, + { 0x0700, 0x13ed, 0x0000 }, + { 0x0700, 0x13ef, 0x0000 }, + { 0x8700, 0x13f2, 0x2000 }, + { 0x0700, 0x13f1, 0x0000 }, + { 0x0700, 0x13f3, 0x0000 }, + { 0x8700, 0x1404, 0x3000 }, + { 0x8700, 0x1402, 0x2000 }, + { 0x0700, 0x1401, 0x0000 }, + { 0x0700, 0x1403, 0x0000 }, + { 0x8700, 0x1406, 0x2000 }, + { 0x0700, 0x1405, 0x0000 }, + { 0x0700, 0x1407, 0x0000 }, + { 0x8700, 0x1410, 0x4000 }, + { 0x8700, 0x140c, 0x3000 }, + { 0x8700, 0x140a, 0x2000 }, + { 0x0700, 0x1409, 0x0000 }, + { 0x0700, 0x140b, 0x0000 }, + { 0x8700, 0x140e, 0x2000 }, + { 0x0700, 0x140d, 0x0000 }, + { 0x0700, 0x140f, 0x0000 }, + { 0x8700, 0x1414, 0x3000 }, + { 0x8700, 0x1412, 0x2000 }, + { 0x0700, 0x1411, 0x0000 }, + { 0x0700, 0x1413, 0x0000 }, + { 0x8700, 0x1416, 0x2000 }, + { 0x0700, 0x1415, 0x0000 }, + { 0x0700, 0x1417, 0x0000 }, + { 0x8700, 0x1438, 0x6000 }, + { 0x8700, 0x1428, 0x5000 }, + { 0x8700, 0x1420, 0x4000 }, + { 0x8700, 0x141c, 0x3000 }, + { 0x8700, 0x141a, 0x2000 }, + { 0x0700, 0x1419, 0x0000 }, + { 0x0700, 0x141b, 0x0000 }, + { 0x8700, 0x141e, 0x2000 }, + { 0x0700, 0x141d, 0x0000 }, + { 0x0700, 0x141f, 0x0000 }, + { 0x8700, 0x1424, 0x3000 }, + { 0x8700, 0x1422, 0x2000 }, + { 0x0700, 0x1421, 0x0000 }, + { 0x0700, 0x1423, 0x0000 }, + { 0x8700, 0x1426, 0x2000 }, + { 0x0700, 0x1425, 0x0000 }, + { 0x0700, 0x1427, 0x0000 }, + { 0x8700, 0x1430, 0x4000 }, + { 0x8700, 0x142c, 0x3000 }, + { 0x8700, 0x142a, 0x2000 }, + { 0x0700, 0x1429, 0x0000 }, + { 0x0700, 0x142b, 0x0000 }, + { 0x8700, 0x142e, 0x2000 }, + { 0x0700, 0x142d, 0x0000 }, + { 0x0700, 0x142f, 0x0000 }, + { 0x8700, 0x1434, 0x3000 }, + { 0x8700, 0x1432, 0x2000 }, + { 0x0700, 0x1431, 0x0000 }, + { 0x0700, 0x1433, 0x0000 }, + { 0x8700, 0x1436, 0x2000 }, + { 0x0700, 0x1435, 0x0000 }, + { 0x0700, 0x1437, 0x0000 }, + { 0x8700, 0x1448, 0x5000 }, + { 0x8700, 0x1440, 0x4000 }, + { 0x8700, 0x143c, 0x3000 }, + { 0x8700, 0x143a, 0x2000 }, + { 0x0700, 0x1439, 0x0000 }, + { 0x0700, 0x143b, 0x0000 }, + { 0x8700, 0x143e, 0x2000 }, + { 0x0700, 0x143d, 0x0000 }, + { 0x0700, 0x143f, 0x0000 }, + { 0x8700, 0x1444, 0x3000 }, + { 0x8700, 0x1442, 0x2000 }, + { 0x0700, 0x1441, 0x0000 }, + { 0x0700, 0x1443, 0x0000 }, + { 0x8700, 0x1446, 0x2000 }, + { 0x0700, 0x1445, 0x0000 }, + { 0x0700, 0x1447, 0x0000 }, + { 0x8700, 0x1450, 0x4000 }, + { 0x8700, 0x144c, 0x3000 }, + { 0x8700, 0x144a, 0x2000 }, + { 0x0700, 0x1449, 0x0000 }, + { 0x0700, 0x144b, 0x0000 }, + { 0x8700, 0x144e, 0x2000 }, + { 0x0700, 0x144d, 0x0000 }, + { 0x0700, 0x144f, 0x0000 }, + { 0x8700, 0x1454, 0x3000 }, + { 0x8700, 0x1452, 0x2000 }, + { 0x0700, 0x1451, 0x0000 }, + { 0x0700, 0x1453, 0x0000 }, + { 0x8700, 0x1456, 0x2000 }, + { 0x0700, 0x1455, 0x0000 }, + { 0x0700, 0x1457, 0x0000 }, + { 0x8700, 0x14d8, 0x8000 }, + { 0x8700, 0x1498, 0x7000 }, + { 0x8700, 0x1478, 0x6000 }, + { 0x8700, 0x1468, 0x5000 }, + { 0x8700, 0x1460, 0x4000 }, + { 0x8700, 0x145c, 0x3000 }, + { 0x8700, 0x145a, 0x2000 }, + { 0x0700, 0x1459, 0x0000 }, + { 0x0700, 0x145b, 0x0000 }, + { 0x8700, 0x145e, 0x2000 }, + { 0x0700, 0x145d, 0x0000 }, + { 0x0700, 0x145f, 0x0000 }, + { 0x8700, 0x1464, 0x3000 }, + { 0x8700, 0x1462, 0x2000 }, + { 0x0700, 0x1461, 0x0000 }, + { 0x0700, 0x1463, 0x0000 }, + { 0x8700, 0x1466, 0x2000 }, + { 0x0700, 0x1465, 0x0000 }, + { 0x0700, 0x1467, 0x0000 }, + { 0x8700, 0x1470, 0x4000 }, + { 0x8700, 0x146c, 0x3000 }, + { 0x8700, 0x146a, 0x2000 }, + { 0x0700, 0x1469, 0x0000 }, + { 0x0700, 0x146b, 0x0000 }, + { 0x8700, 0x146e, 0x2000 }, + { 0x0700, 0x146d, 0x0000 }, + { 0x0700, 0x146f, 0x0000 }, + { 0x8700, 0x1474, 0x3000 }, + { 0x8700, 0x1472, 0x2000 }, + { 0x0700, 0x1471, 0x0000 }, + { 0x0700, 0x1473, 0x0000 }, + { 0x8700, 0x1476, 0x2000 }, + { 0x0700, 0x1475, 0x0000 }, + { 0x0700, 0x1477, 0x0000 }, + { 0x8700, 0x1488, 0x5000 }, + { 0x8700, 0x1480, 0x4000 }, + { 0x8700, 0x147c, 0x3000 }, + { 0x8700, 0x147a, 0x2000 }, + { 0x0700, 0x1479, 0x0000 }, + { 0x0700, 0x147b, 0x0000 }, + { 0x8700, 0x147e, 0x2000 }, + { 0x0700, 0x147d, 0x0000 }, + { 0x0700, 0x147f, 0x0000 }, + { 0x8700, 0x1484, 0x3000 }, + { 0x8700, 0x1482, 0x2000 }, + { 0x0700, 0x1481, 0x0000 }, + { 0x0700, 0x1483, 0x0000 }, + { 0x8700, 0x1486, 0x2000 }, + { 0x0700, 0x1485, 0x0000 }, + { 0x0700, 0x1487, 0x0000 }, + { 0x8700, 0x1490, 0x4000 }, + { 0x8700, 0x148c, 0x3000 }, + { 0x8700, 0x148a, 0x2000 }, + { 0x0700, 0x1489, 0x0000 }, + { 0x0700, 0x148b, 0x0000 }, + { 0x8700, 0x148e, 0x2000 }, + { 0x0700, 0x148d, 0x0000 }, + { 0x0700, 0x148f, 0x0000 }, + { 0x8700, 0x1494, 0x3000 }, + { 0x8700, 0x1492, 0x2000 }, + { 0x0700, 0x1491, 0x0000 }, + { 0x0700, 0x1493, 0x0000 }, + { 0x8700, 0x1496, 0x2000 }, + { 0x0700, 0x1495, 0x0000 }, + { 0x0700, 0x1497, 0x0000 }, + { 0x8700, 0x14b8, 0x6000 }, + { 0x8700, 0x14a8, 0x5000 }, + { 0x8700, 0x14a0, 0x4000 }, + { 0x8700, 0x149c, 0x3000 }, + { 0x8700, 0x149a, 0x2000 }, + { 0x0700, 0x1499, 0x0000 }, + { 0x0700, 0x149b, 0x0000 }, + { 0x8700, 0x149e, 0x2000 }, + { 0x0700, 0x149d, 0x0000 }, + { 0x0700, 0x149f, 0x0000 }, + { 0x8700, 0x14a4, 0x3000 }, + { 0x8700, 0x14a2, 0x2000 }, + { 0x0700, 0x14a1, 0x0000 }, + { 0x0700, 0x14a3, 0x0000 }, + { 0x8700, 0x14a6, 0x2000 }, + { 0x0700, 0x14a5, 0x0000 }, + { 0x0700, 0x14a7, 0x0000 }, + { 0x8700, 0x14b0, 0x4000 }, + { 0x8700, 0x14ac, 0x3000 }, + { 0x8700, 0x14aa, 0x2000 }, + { 0x0700, 0x14a9, 0x0000 }, + { 0x0700, 0x14ab, 0x0000 }, + { 0x8700, 0x14ae, 0x2000 }, + { 0x0700, 0x14ad, 0x0000 }, + { 0x0700, 0x14af, 0x0000 }, + { 0x8700, 0x14b4, 0x3000 }, + { 0x8700, 0x14b2, 0x2000 }, + { 0x0700, 0x14b1, 0x0000 }, + { 0x0700, 0x14b3, 0x0000 }, + { 0x8700, 0x14b6, 0x2000 }, + { 0x0700, 0x14b5, 0x0000 }, + { 0x0700, 0x14b7, 0x0000 }, + { 0x8700, 0x14c8, 0x5000 }, + { 0x8700, 0x14c0, 0x4000 }, + { 0x8700, 0x14bc, 0x3000 }, + { 0x8700, 0x14ba, 0x2000 }, + { 0x0700, 0x14b9, 0x0000 }, + { 0x0700, 0x14bb, 0x0000 }, + { 0x8700, 0x14be, 0x2000 }, + { 0x0700, 0x14bd, 0x0000 }, + { 0x0700, 0x14bf, 0x0000 }, + { 0x8700, 0x14c4, 0x3000 }, + { 0x8700, 0x14c2, 0x2000 }, + { 0x0700, 0x14c1, 0x0000 }, + { 0x0700, 0x14c3, 0x0000 }, + { 0x8700, 0x14c6, 0x2000 }, + { 0x0700, 0x14c5, 0x0000 }, + { 0x0700, 0x14c7, 0x0000 }, + { 0x8700, 0x14d0, 0x4000 }, + { 0x8700, 0x14cc, 0x3000 }, + { 0x8700, 0x14ca, 0x2000 }, + { 0x0700, 0x14c9, 0x0000 }, + { 0x0700, 0x14cb, 0x0000 }, + { 0x8700, 0x14ce, 0x2000 }, + { 0x0700, 0x14cd, 0x0000 }, + { 0x0700, 0x14cf, 0x0000 }, + { 0x8700, 0x14d4, 0x3000 }, + { 0x8700, 0x14d2, 0x2000 }, + { 0x0700, 0x14d1, 0x0000 }, + { 0x0700, 0x14d3, 0x0000 }, + { 0x8700, 0x14d6, 0x2000 }, + { 0x0700, 0x14d5, 0x0000 }, + { 0x0700, 0x14d7, 0x0000 }, + { 0x8700, 0x1518, 0x7000 }, + { 0x8700, 0x14f8, 0x6000 }, + { 0x8700, 0x14e8, 0x5000 }, + { 0x8700, 0x14e0, 0x4000 }, + { 0x8700, 0x14dc, 0x3000 }, + { 0x8700, 0x14da, 0x2000 }, + { 0x0700, 0x14d9, 0x0000 }, + { 0x0700, 0x14db, 0x0000 }, + { 0x8700, 0x14de, 0x2000 }, + { 0x0700, 0x14dd, 0x0000 }, + { 0x0700, 0x14df, 0x0000 }, + { 0x8700, 0x14e4, 0x3000 }, + { 0x8700, 0x14e2, 0x2000 }, + { 0x0700, 0x14e1, 0x0000 }, + { 0x0700, 0x14e3, 0x0000 }, + { 0x8700, 0x14e6, 0x2000 }, + { 0x0700, 0x14e5, 0x0000 }, + { 0x0700, 0x14e7, 0x0000 }, + { 0x8700, 0x14f0, 0x4000 }, + { 0x8700, 0x14ec, 0x3000 }, + { 0x8700, 0x14ea, 0x2000 }, + { 0x0700, 0x14e9, 0x0000 }, + { 0x0700, 0x14eb, 0x0000 }, + { 0x8700, 0x14ee, 0x2000 }, + { 0x0700, 0x14ed, 0x0000 }, + { 0x0700, 0x14ef, 0x0000 }, + { 0x8700, 0x14f4, 0x3000 }, + { 0x8700, 0x14f2, 0x2000 }, + { 0x0700, 0x14f1, 0x0000 }, + { 0x0700, 0x14f3, 0x0000 }, + { 0x8700, 0x14f6, 0x2000 }, + { 0x0700, 0x14f5, 0x0000 }, + { 0x0700, 0x14f7, 0x0000 }, + { 0x8700, 0x1508, 0x5000 }, + { 0x8700, 0x1500, 0x4000 }, + { 0x8700, 0x14fc, 0x3000 }, + { 0x8700, 0x14fa, 0x2000 }, + { 0x0700, 0x14f9, 0x0000 }, + { 0x0700, 0x14fb, 0x0000 }, + { 0x8700, 0x14fe, 0x2000 }, + { 0x0700, 0x14fd, 0x0000 }, + { 0x0700, 0x14ff, 0x0000 }, + { 0x8700, 0x1504, 0x3000 }, + { 0x8700, 0x1502, 0x2000 }, + { 0x0700, 0x1501, 0x0000 }, + { 0x0700, 0x1503, 0x0000 }, + { 0x8700, 0x1506, 0x2000 }, + { 0x0700, 0x1505, 0x0000 }, + { 0x0700, 0x1507, 0x0000 }, + { 0x8700, 0x1510, 0x4000 }, + { 0x8700, 0x150c, 0x3000 }, + { 0x8700, 0x150a, 0x2000 }, + { 0x0700, 0x1509, 0x0000 }, + { 0x0700, 0x150b, 0x0000 }, + { 0x8700, 0x150e, 0x2000 }, + { 0x0700, 0x150d, 0x0000 }, + { 0x0700, 0x150f, 0x0000 }, + { 0x8700, 0x1514, 0x3000 }, + { 0x8700, 0x1512, 0x2000 }, + { 0x0700, 0x1511, 0x0000 }, + { 0x0700, 0x1513, 0x0000 }, + { 0x8700, 0x1516, 0x2000 }, + { 0x0700, 0x1515, 0x0000 }, + { 0x0700, 0x1517, 0x0000 }, + { 0x8700, 0x1538, 0x6000 }, + { 0x8700, 0x1528, 0x5000 }, + { 0x8700, 0x1520, 0x4000 }, + { 0x8700, 0x151c, 0x3000 }, + { 0x8700, 0x151a, 0x2000 }, + { 0x0700, 0x1519, 0x0000 }, + { 0x0700, 0x151b, 0x0000 }, + { 0x8700, 0x151e, 0x2000 }, + { 0x0700, 0x151d, 0x0000 }, + { 0x0700, 0x151f, 0x0000 }, + { 0x8700, 0x1524, 0x3000 }, + { 0x8700, 0x1522, 0x2000 }, + { 0x0700, 0x1521, 0x0000 }, + { 0x0700, 0x1523, 0x0000 }, + { 0x8700, 0x1526, 0x2000 }, + { 0x0700, 0x1525, 0x0000 }, + { 0x0700, 0x1527, 0x0000 }, + { 0x8700, 0x1530, 0x4000 }, + { 0x8700, 0x152c, 0x3000 }, + { 0x8700, 0x152a, 0x2000 }, + { 0x0700, 0x1529, 0x0000 }, + { 0x0700, 0x152b, 0x0000 }, + { 0x8700, 0x152e, 0x2000 }, + { 0x0700, 0x152d, 0x0000 }, + { 0x0700, 0x152f, 0x0000 }, + { 0x8700, 0x1534, 0x3000 }, + { 0x8700, 0x1532, 0x2000 }, + { 0x0700, 0x1531, 0x0000 }, + { 0x0700, 0x1533, 0x0000 }, + { 0x8700, 0x1536, 0x2000 }, + { 0x0700, 0x1535, 0x0000 }, + { 0x0700, 0x1537, 0x0000 }, + { 0x8700, 0x1548, 0x5000 }, + { 0x8700, 0x1540, 0x4000 }, + { 0x8700, 0x153c, 0x3000 }, + { 0x8700, 0x153a, 0x2000 }, + { 0x0700, 0x1539, 0x0000 }, + { 0x0700, 0x153b, 0x0000 }, + { 0x8700, 0x153e, 0x2000 }, + { 0x0700, 0x153d, 0x0000 }, + { 0x0700, 0x153f, 0x0000 }, + { 0x8700, 0x1544, 0x3000 }, + { 0x8700, 0x1542, 0x2000 }, + { 0x0700, 0x1541, 0x0000 }, + { 0x0700, 0x1543, 0x0000 }, + { 0x8700, 0x1546, 0x2000 }, + { 0x0700, 0x1545, 0x0000 }, + { 0x0700, 0x1547, 0x0000 }, + { 0x8700, 0x1550, 0x4000 }, + { 0x8700, 0x154c, 0x3000 }, + { 0x8700, 0x154a, 0x2000 }, + { 0x0700, 0x1549, 0x0000 }, + { 0x0700, 0x154b, 0x0000 }, + { 0x8700, 0x154e, 0x2000 }, + { 0x0700, 0x154d, 0x0000 }, + { 0x0700, 0x154f, 0x0000 }, + { 0x8700, 0x1554, 0x3000 }, + { 0x8700, 0x1552, 0x2000 }, + { 0x0700, 0x1551, 0x0000 }, + { 0x0700, 0x1553, 0x0000 }, + { 0x8700, 0x1556, 0x2000 }, + { 0x0700, 0x1555, 0x0000 }, + { 0x0700, 0x1557, 0x0000 }, + { 0x9900, 0x22ae, 0xc000 }, + { 0x8900, 0x1e24, 0xb001 }, + { 0x8700, 0x17a2, 0xa000 }, + { 0x8700, 0x1658, 0x9000 }, + { 0x8700, 0x15d8, 0x8000 }, + { 0x8700, 0x1598, 0x7000 }, + { 0x8700, 0x1578, 0x6000 }, + { 0x8700, 0x1568, 0x5000 }, + { 0x8700, 0x1560, 0x4000 }, + { 0x8700, 0x155c, 0x3000 }, + { 0x8700, 0x155a, 0x2000 }, + { 0x0700, 0x1559, 0x0000 }, + { 0x0700, 0x155b, 0x0000 }, + { 0x8700, 0x155e, 0x2000 }, + { 0x0700, 0x155d, 0x0000 }, + { 0x0700, 0x155f, 0x0000 }, + { 0x8700, 0x1564, 0x3000 }, + { 0x8700, 0x1562, 0x2000 }, + { 0x0700, 0x1561, 0x0000 }, + { 0x0700, 0x1563, 0x0000 }, + { 0x8700, 0x1566, 0x2000 }, + { 0x0700, 0x1565, 0x0000 }, + { 0x0700, 0x1567, 0x0000 }, + { 0x8700, 0x1570, 0x4000 }, + { 0x8700, 0x156c, 0x3000 }, + { 0x8700, 0x156a, 0x2000 }, + { 0x0700, 0x1569, 0x0000 }, + { 0x0700, 0x156b, 0x0000 }, + { 0x8700, 0x156e, 0x2000 }, + { 0x0700, 0x156d, 0x0000 }, + { 0x0700, 0x156f, 0x0000 }, + { 0x8700, 0x1574, 0x3000 }, + { 0x8700, 0x1572, 0x2000 }, + { 0x0700, 0x1571, 0x0000 }, + { 0x0700, 0x1573, 0x0000 }, + { 0x8700, 0x1576, 0x2000 }, + { 0x0700, 0x1575, 0x0000 }, + { 0x0700, 0x1577, 0x0000 }, + { 0x8700, 0x1588, 0x5000 }, + { 0x8700, 0x1580, 0x4000 }, + { 0x8700, 0x157c, 0x3000 }, + { 0x8700, 0x157a, 0x2000 }, + { 0x0700, 0x1579, 0x0000 }, + { 0x0700, 0x157b, 0x0000 }, + { 0x8700, 0x157e, 0x2000 }, + { 0x0700, 0x157d, 0x0000 }, + { 0x0700, 0x157f, 0x0000 }, + { 0x8700, 0x1584, 0x3000 }, + { 0x8700, 0x1582, 0x2000 }, + { 0x0700, 0x1581, 0x0000 }, + { 0x0700, 0x1583, 0x0000 }, + { 0x8700, 0x1586, 0x2000 }, + { 0x0700, 0x1585, 0x0000 }, + { 0x0700, 0x1587, 0x0000 }, + { 0x8700, 0x1590, 0x4000 }, + { 0x8700, 0x158c, 0x3000 }, + { 0x8700, 0x158a, 0x2000 }, + { 0x0700, 0x1589, 0x0000 }, + { 0x0700, 0x158b, 0x0000 }, + { 0x8700, 0x158e, 0x2000 }, + { 0x0700, 0x158d, 0x0000 }, + { 0x0700, 0x158f, 0x0000 }, + { 0x8700, 0x1594, 0x3000 }, + { 0x8700, 0x1592, 0x2000 }, + { 0x0700, 0x1591, 0x0000 }, + { 0x0700, 0x1593, 0x0000 }, + { 0x8700, 0x1596, 0x2000 }, + { 0x0700, 0x1595, 0x0000 }, + { 0x0700, 0x1597, 0x0000 }, + { 0x8700, 0x15b8, 0x6000 }, + { 0x8700, 0x15a8, 0x5000 }, + { 0x8700, 0x15a0, 0x4000 }, + { 0x8700, 0x159c, 0x3000 }, + { 0x8700, 0x159a, 0x2000 }, + { 0x0700, 0x1599, 0x0000 }, + { 0x0700, 0x159b, 0x0000 }, + { 0x8700, 0x159e, 0x2000 }, + { 0x0700, 0x159d, 0x0000 }, + { 0x0700, 0x159f, 0x0000 }, + { 0x8700, 0x15a4, 0x3000 }, + { 0x8700, 0x15a2, 0x2000 }, + { 0x0700, 0x15a1, 0x0000 }, + { 0x0700, 0x15a3, 0x0000 }, + { 0x8700, 0x15a6, 0x2000 }, + { 0x0700, 0x15a5, 0x0000 }, + { 0x0700, 0x15a7, 0x0000 }, + { 0x8700, 0x15b0, 0x4000 }, + { 0x8700, 0x15ac, 0x3000 }, + { 0x8700, 0x15aa, 0x2000 }, + { 0x0700, 0x15a9, 0x0000 }, + { 0x0700, 0x15ab, 0x0000 }, + { 0x8700, 0x15ae, 0x2000 }, + { 0x0700, 0x15ad, 0x0000 }, + { 0x0700, 0x15af, 0x0000 }, + { 0x8700, 0x15b4, 0x3000 }, + { 0x8700, 0x15b2, 0x2000 }, + { 0x0700, 0x15b1, 0x0000 }, + { 0x0700, 0x15b3, 0x0000 }, + { 0x8700, 0x15b6, 0x2000 }, + { 0x0700, 0x15b5, 0x0000 }, + { 0x0700, 0x15b7, 0x0000 }, + { 0x8700, 0x15c8, 0x5000 }, + { 0x8700, 0x15c0, 0x4000 }, + { 0x8700, 0x15bc, 0x3000 }, + { 0x8700, 0x15ba, 0x2000 }, + { 0x0700, 0x15b9, 0x0000 }, + { 0x0700, 0x15bb, 0x0000 }, + { 0x8700, 0x15be, 0x2000 }, + { 0x0700, 0x15bd, 0x0000 }, + { 0x0700, 0x15bf, 0x0000 }, + { 0x8700, 0x15c4, 0x3000 }, + { 0x8700, 0x15c2, 0x2000 }, + { 0x0700, 0x15c1, 0x0000 }, + { 0x0700, 0x15c3, 0x0000 }, + { 0x8700, 0x15c6, 0x2000 }, + { 0x0700, 0x15c5, 0x0000 }, + { 0x0700, 0x15c7, 0x0000 }, + { 0x8700, 0x15d0, 0x4000 }, + { 0x8700, 0x15cc, 0x3000 }, + { 0x8700, 0x15ca, 0x2000 }, + { 0x0700, 0x15c9, 0x0000 }, + { 0x0700, 0x15cb, 0x0000 }, + { 0x8700, 0x15ce, 0x2000 }, + { 0x0700, 0x15cd, 0x0000 }, + { 0x0700, 0x15cf, 0x0000 }, + { 0x8700, 0x15d4, 0x3000 }, + { 0x8700, 0x15d2, 0x2000 }, + { 0x0700, 0x15d1, 0x0000 }, + { 0x0700, 0x15d3, 0x0000 }, + { 0x8700, 0x15d6, 0x2000 }, + { 0x0700, 0x15d5, 0x0000 }, + { 0x0700, 0x15d7, 0x0000 }, + { 0x8700, 0x1618, 0x7000 }, + { 0x8700, 0x15f8, 0x6000 }, + { 0x8700, 0x15e8, 0x5000 }, + { 0x8700, 0x15e0, 0x4000 }, + { 0x8700, 0x15dc, 0x3000 }, + { 0x8700, 0x15da, 0x2000 }, + { 0x0700, 0x15d9, 0x0000 }, + { 0x0700, 0x15db, 0x0000 }, + { 0x8700, 0x15de, 0x2000 }, + { 0x0700, 0x15dd, 0x0000 }, + { 0x0700, 0x15df, 0x0000 }, + { 0x8700, 0x15e4, 0x3000 }, + { 0x8700, 0x15e2, 0x2000 }, + { 0x0700, 0x15e1, 0x0000 }, + { 0x0700, 0x15e3, 0x0000 }, + { 0x8700, 0x15e6, 0x2000 }, + { 0x0700, 0x15e5, 0x0000 }, + { 0x0700, 0x15e7, 0x0000 }, + { 0x8700, 0x15f0, 0x4000 }, + { 0x8700, 0x15ec, 0x3000 }, + { 0x8700, 0x15ea, 0x2000 }, + { 0x0700, 0x15e9, 0x0000 }, + { 0x0700, 0x15eb, 0x0000 }, + { 0x8700, 0x15ee, 0x2000 }, + { 0x0700, 0x15ed, 0x0000 }, + { 0x0700, 0x15ef, 0x0000 }, + { 0x8700, 0x15f4, 0x3000 }, + { 0x8700, 0x15f2, 0x2000 }, + { 0x0700, 0x15f1, 0x0000 }, + { 0x0700, 0x15f3, 0x0000 }, + { 0x8700, 0x15f6, 0x2000 }, + { 0x0700, 0x15f5, 0x0000 }, + { 0x0700, 0x15f7, 0x0000 }, + { 0x8700, 0x1608, 0x5000 }, + { 0x8700, 0x1600, 0x4000 }, + { 0x8700, 0x15fc, 0x3000 }, + { 0x8700, 0x15fa, 0x2000 }, + { 0x0700, 0x15f9, 0x0000 }, + { 0x0700, 0x15fb, 0x0000 }, + { 0x8700, 0x15fe, 0x2000 }, + { 0x0700, 0x15fd, 0x0000 }, + { 0x0700, 0x15ff, 0x0000 }, + { 0x8700, 0x1604, 0x3000 }, + { 0x8700, 0x1602, 0x2000 }, + { 0x0700, 0x1601, 0x0000 }, + { 0x0700, 0x1603, 0x0000 }, + { 0x8700, 0x1606, 0x2000 }, + { 0x0700, 0x1605, 0x0000 }, + { 0x0700, 0x1607, 0x0000 }, + { 0x8700, 0x1610, 0x4000 }, + { 0x8700, 0x160c, 0x3000 }, + { 0x8700, 0x160a, 0x2000 }, + { 0x0700, 0x1609, 0x0000 }, + { 0x0700, 0x160b, 0x0000 }, + { 0x8700, 0x160e, 0x2000 }, + { 0x0700, 0x160d, 0x0000 }, + { 0x0700, 0x160f, 0x0000 }, + { 0x8700, 0x1614, 0x3000 }, + { 0x8700, 0x1612, 0x2000 }, + { 0x0700, 0x1611, 0x0000 }, + { 0x0700, 0x1613, 0x0000 }, + { 0x8700, 0x1616, 0x2000 }, + { 0x0700, 0x1615, 0x0000 }, + { 0x0700, 0x1617, 0x0000 }, + { 0x8700, 0x1638, 0x6000 }, + { 0x8700, 0x1628, 0x5000 }, + { 0x8700, 0x1620, 0x4000 }, + { 0x8700, 0x161c, 0x3000 }, + { 0x8700, 0x161a, 0x2000 }, + { 0x0700, 0x1619, 0x0000 }, + { 0x0700, 0x161b, 0x0000 }, + { 0x8700, 0x161e, 0x2000 }, + { 0x0700, 0x161d, 0x0000 }, + { 0x0700, 0x161f, 0x0000 }, + { 0x8700, 0x1624, 0x3000 }, + { 0x8700, 0x1622, 0x2000 }, + { 0x0700, 0x1621, 0x0000 }, + { 0x0700, 0x1623, 0x0000 }, + { 0x8700, 0x1626, 0x2000 }, + { 0x0700, 0x1625, 0x0000 }, + { 0x0700, 0x1627, 0x0000 }, + { 0x8700, 0x1630, 0x4000 }, + { 0x8700, 0x162c, 0x3000 }, + { 0x8700, 0x162a, 0x2000 }, + { 0x0700, 0x1629, 0x0000 }, + { 0x0700, 0x162b, 0x0000 }, + { 0x8700, 0x162e, 0x2000 }, + { 0x0700, 0x162d, 0x0000 }, + { 0x0700, 0x162f, 0x0000 }, + { 0x8700, 0x1634, 0x3000 }, + { 0x8700, 0x1632, 0x2000 }, + { 0x0700, 0x1631, 0x0000 }, + { 0x0700, 0x1633, 0x0000 }, + { 0x8700, 0x1636, 0x2000 }, + { 0x0700, 0x1635, 0x0000 }, + { 0x0700, 0x1637, 0x0000 }, + { 0x8700, 0x1648, 0x5000 }, + { 0x8700, 0x1640, 0x4000 }, + { 0x8700, 0x163c, 0x3000 }, + { 0x8700, 0x163a, 0x2000 }, + { 0x0700, 0x1639, 0x0000 }, + { 0x0700, 0x163b, 0x0000 }, + { 0x8700, 0x163e, 0x2000 }, + { 0x0700, 0x163d, 0x0000 }, + { 0x0700, 0x163f, 0x0000 }, + { 0x8700, 0x1644, 0x3000 }, + { 0x8700, 0x1642, 0x2000 }, + { 0x0700, 0x1641, 0x0000 }, + { 0x0700, 0x1643, 0x0000 }, + { 0x8700, 0x1646, 0x2000 }, + { 0x0700, 0x1645, 0x0000 }, + { 0x0700, 0x1647, 0x0000 }, + { 0x8700, 0x1650, 0x4000 }, + { 0x8700, 0x164c, 0x3000 }, + { 0x8700, 0x164a, 0x2000 }, + { 0x0700, 0x1649, 0x0000 }, + { 0x0700, 0x164b, 0x0000 }, + { 0x8700, 0x164e, 0x2000 }, + { 0x0700, 0x164d, 0x0000 }, + { 0x0700, 0x164f, 0x0000 }, + { 0x8700, 0x1654, 0x3000 }, + { 0x8700, 0x1652, 0x2000 }, + { 0x0700, 0x1651, 0x0000 }, + { 0x0700, 0x1653, 0x0000 }, + { 0x8700, 0x1656, 0x2000 }, + { 0x0700, 0x1655, 0x0000 }, + { 0x0700, 0x1657, 0x0000 }, + { 0x8700, 0x16e4, 0x8000 }, + { 0x8700, 0x16a4, 0x7000 }, + { 0x8700, 0x1681, 0x6000 }, + { 0x8700, 0x1668, 0x5000 }, + { 0x8700, 0x1660, 0x4000 }, + { 0x8700, 0x165c, 0x3000 }, + { 0x8700, 0x165a, 0x2000 }, + { 0x0700, 0x1659, 0x0000 }, + { 0x0700, 0x165b, 0x0000 }, + { 0x8700, 0x165e, 0x2000 }, + { 0x0700, 0x165d, 0x0000 }, + { 0x0700, 0x165f, 0x0000 }, + { 0x8700, 0x1664, 0x3000 }, + { 0x8700, 0x1662, 0x2000 }, + { 0x0700, 0x1661, 0x0000 }, + { 0x0700, 0x1663, 0x0000 }, + { 0x8700, 0x1666, 0x2000 }, + { 0x0700, 0x1665, 0x0000 }, + { 0x0700, 0x1667, 0x0000 }, + { 0x8700, 0x1670, 0x4000 }, + { 0x8700, 0x166c, 0x3000 }, + { 0x8700, 0x166a, 0x2000 }, + { 0x0700, 0x1669, 0x0000 }, + { 0x0700, 0x166b, 0x0000 }, + { 0x9500, 0x166e, 0x2000 }, + { 0x1500, 0x166d, 0x0000 }, + { 0x0700, 0x166f, 0x0000 }, + { 0x8700, 0x1674, 0x3000 }, + { 0x8700, 0x1672, 0x2000 }, + { 0x0700, 0x1671, 0x0000 }, + { 0x0700, 0x1673, 0x0000 }, + { 0x8700, 0x1676, 0x2000 }, + { 0x0700, 0x1675, 0x0000 }, + { 0x1d00, 0x1680, 0x0000 }, + { 0x8700, 0x1691, 0x5000 }, + { 0x8700, 0x1689, 0x4000 }, + { 0x8700, 0x1685, 0x3000 }, + { 0x8700, 0x1683, 0x2000 }, + { 0x0700, 0x1682, 0x0000 }, + { 0x0700, 0x1684, 0x0000 }, + { 0x8700, 0x1687, 0x2000 }, + { 0x0700, 0x1686, 0x0000 }, + { 0x0700, 0x1688, 0x0000 }, + { 0x8700, 0x168d, 0x3000 }, + { 0x8700, 0x168b, 0x2000 }, + { 0x0700, 0x168a, 0x0000 }, + { 0x0700, 0x168c, 0x0000 }, + { 0x8700, 0x168f, 0x2000 }, + { 0x0700, 0x168e, 0x0000 }, + { 0x0700, 0x1690, 0x0000 }, + { 0x8700, 0x1699, 0x4000 }, + { 0x8700, 0x1695, 0x3000 }, + { 0x8700, 0x1693, 0x2000 }, + { 0x0700, 0x1692, 0x0000 }, + { 0x0700, 0x1694, 0x0000 }, + { 0x8700, 0x1697, 0x2000 }, + { 0x0700, 0x1696, 0x0000 }, + { 0x0700, 0x1698, 0x0000 }, + { 0x8700, 0x16a0, 0x3000 }, + { 0x9600, 0x169b, 0x2000 }, + { 0x0700, 0x169a, 0x0000 }, + { 0x1200, 0x169c, 0x0000 }, + { 0x8700, 0x16a2, 0x2000 }, + { 0x0700, 0x16a1, 0x0000 }, + { 0x0700, 0x16a3, 0x0000 }, + { 0x8700, 0x16c4, 0x6000 }, + { 0x8700, 0x16b4, 0x5000 }, + { 0x8700, 0x16ac, 0x4000 }, + { 0x8700, 0x16a8, 0x3000 }, + { 0x8700, 0x16a6, 0x2000 }, + { 0x0700, 0x16a5, 0x0000 }, + { 0x0700, 0x16a7, 0x0000 }, + { 0x8700, 0x16aa, 0x2000 }, + { 0x0700, 0x16a9, 0x0000 }, + { 0x0700, 0x16ab, 0x0000 }, + { 0x8700, 0x16b0, 0x3000 }, + { 0x8700, 0x16ae, 0x2000 }, + { 0x0700, 0x16ad, 0x0000 }, + { 0x0700, 0x16af, 0x0000 }, + { 0x8700, 0x16b2, 0x2000 }, + { 0x0700, 0x16b1, 0x0000 }, + { 0x0700, 0x16b3, 0x0000 }, + { 0x8700, 0x16bc, 0x4000 }, + { 0x8700, 0x16b8, 0x3000 }, + { 0x8700, 0x16b6, 0x2000 }, + { 0x0700, 0x16b5, 0x0000 }, + { 0x0700, 0x16b7, 0x0000 }, + { 0x8700, 0x16ba, 0x2000 }, + { 0x0700, 0x16b9, 0x0000 }, + { 0x0700, 0x16bb, 0x0000 }, + { 0x8700, 0x16c0, 0x3000 }, + { 0x8700, 0x16be, 0x2000 }, + { 0x0700, 0x16bd, 0x0000 }, + { 0x0700, 0x16bf, 0x0000 }, + { 0x8700, 0x16c2, 0x2000 }, + { 0x0700, 0x16c1, 0x0000 }, + { 0x0700, 0x16c3, 0x0000 }, + { 0x8700, 0x16d4, 0x5000 }, + { 0x8700, 0x16cc, 0x4000 }, + { 0x8700, 0x16c8, 0x3000 }, + { 0x8700, 0x16c6, 0x2000 }, + { 0x0700, 0x16c5, 0x0000 }, + { 0x0700, 0x16c7, 0x0000 }, + { 0x8700, 0x16ca, 0x2000 }, + { 0x0700, 0x16c9, 0x0000 }, + { 0x0700, 0x16cb, 0x0000 }, + { 0x8700, 0x16d0, 0x3000 }, + { 0x8700, 0x16ce, 0x2000 }, + { 0x0700, 0x16cd, 0x0000 }, + { 0x0700, 0x16cf, 0x0000 }, + { 0x8700, 0x16d2, 0x2000 }, + { 0x0700, 0x16d1, 0x0000 }, + { 0x0700, 0x16d3, 0x0000 }, + { 0x8700, 0x16dc, 0x4000 }, + { 0x8700, 0x16d8, 0x3000 }, + { 0x8700, 0x16d6, 0x2000 }, + { 0x0700, 0x16d5, 0x0000 }, + { 0x0700, 0x16d7, 0x0000 }, + { 0x8700, 0x16da, 0x2000 }, + { 0x0700, 0x16d9, 0x0000 }, + { 0x0700, 0x16db, 0x0000 }, + { 0x8700, 0x16e0, 0x3000 }, + { 0x8700, 0x16de, 0x2000 }, + { 0x0700, 0x16dd, 0x0000 }, + { 0x0700, 0x16df, 0x0000 }, + { 0x8700, 0x16e2, 0x2000 }, + { 0x0700, 0x16e1, 0x0000 }, + { 0x0700, 0x16e3, 0x0000 }, + { 0x8700, 0x1748, 0x7000 }, + { 0x8c00, 0x1714, 0x6000 }, + { 0x8700, 0x1703, 0x5000 }, + { 0x9500, 0x16ec, 0x4000 }, + { 0x8700, 0x16e8, 0x3000 }, + { 0x8700, 0x16e6, 0x2000 }, + { 0x0700, 0x16e5, 0x0000 }, + { 0x0700, 0x16e7, 0x0000 }, + { 0x8700, 0x16ea, 0x2000 }, + { 0x0700, 0x16e9, 0x0000 }, + { 0x1500, 0x16eb, 0x0000 }, + { 0x8e00, 0x16f0, 0x3000 }, + { 0x8e00, 0x16ee, 0x2000 }, + { 0x1500, 0x16ed, 0x0000 }, + { 0x0e00, 0x16ef, 0x0000 }, + { 0x8700, 0x1701, 0x2000 }, + { 0x0700, 0x1700, 0x0000 }, + { 0x0700, 0x1702, 0x0000 }, + { 0x8700, 0x170b, 0x4000 }, + { 0x8700, 0x1707, 0x3000 }, + { 0x8700, 0x1705, 0x2000 }, + { 0x0700, 0x1704, 0x0000 }, + { 0x0700, 0x1706, 0x0000 }, + { 0x8700, 0x1709, 0x2000 }, + { 0x0700, 0x1708, 0x0000 }, + { 0x0700, 0x170a, 0x0000 }, + { 0x8700, 0x1710, 0x3000 }, + { 0x8700, 0x170e, 0x2000 }, + { 0x0700, 0x170c, 0x0000 }, + { 0x0700, 0x170f, 0x0000 }, + { 0x8c00, 0x1712, 0x2000 }, + { 0x0700, 0x1711, 0x0000 }, + { 0x0c00, 0x1713, 0x0000 }, + { 0x8700, 0x172f, 0x5000 }, + { 0x8700, 0x1727, 0x4000 }, + { 0x8700, 0x1723, 0x3000 }, + { 0x8700, 0x1721, 0x2000 }, + { 0x0700, 0x1720, 0x0000 }, + { 0x0700, 0x1722, 0x0000 }, + { 0x8700, 0x1725, 0x2000 }, + { 0x0700, 0x1724, 0x0000 }, + { 0x0700, 0x1726, 0x0000 }, + { 0x8700, 0x172b, 0x3000 }, + { 0x8700, 0x1729, 0x2000 }, + { 0x0700, 0x1728, 0x0000 }, + { 0x0700, 0x172a, 0x0000 }, + { 0x8700, 0x172d, 0x2000 }, + { 0x0700, 0x172c, 0x0000 }, + { 0x0700, 0x172e, 0x0000 }, + { 0x8700, 0x1740, 0x4000 }, + { 0x8c00, 0x1733, 0x3000 }, + { 0x8700, 0x1731, 0x2000 }, + { 0x0700, 0x1730, 0x0000 }, + { 0x0c00, 0x1732, 0x0000 }, + { 0x9500, 0x1735, 0x2000 }, + { 0x0c00, 0x1734, 0x0000 }, + { 0x1500, 0x1736, 0x0000 }, + { 0x8700, 0x1744, 0x3000 }, + { 0x8700, 0x1742, 0x2000 }, + { 0x0700, 0x1741, 0x0000 }, + { 0x0700, 0x1743, 0x0000 }, + { 0x8700, 0x1746, 0x2000 }, + { 0x0700, 0x1745, 0x0000 }, + { 0x0700, 0x1747, 0x0000 }, + { 0x8700, 0x1782, 0x6000 }, + { 0x8700, 0x1764, 0x5000 }, + { 0x8700, 0x1750, 0x4000 }, + { 0x8700, 0x174c, 0x3000 }, + { 0x8700, 0x174a, 0x2000 }, + { 0x0700, 0x1749, 0x0000 }, + { 0x0700, 0x174b, 0x0000 }, + { 0x8700, 0x174e, 0x2000 }, + { 0x0700, 0x174d, 0x0000 }, + { 0x0700, 0x174f, 0x0000 }, + { 0x8700, 0x1760, 0x3000 }, + { 0x8c00, 0x1752, 0x2000 }, + { 0x0700, 0x1751, 0x0000 }, + { 0x0c00, 0x1753, 0x0000 }, + { 0x8700, 0x1762, 0x2000 }, + { 0x0700, 0x1761, 0x0000 }, + { 0x0700, 0x1763, 0x0000 }, + { 0x8700, 0x176c, 0x4000 }, + { 0x8700, 0x1768, 0x3000 }, + { 0x8700, 0x1766, 0x2000 }, + { 0x0700, 0x1765, 0x0000 }, + { 0x0700, 0x1767, 0x0000 }, + { 0x8700, 0x176a, 0x2000 }, + { 0x0700, 0x1769, 0x0000 }, + { 0x0700, 0x176b, 0x0000 }, + { 0x8c00, 0x1772, 0x3000 }, + { 0x8700, 0x176f, 0x2000 }, + { 0x0700, 0x176e, 0x0000 }, + { 0x0700, 0x1770, 0x0000 }, + { 0x8700, 0x1780, 0x2000 }, + { 0x0c00, 0x1773, 0x0000 }, + { 0x0700, 0x1781, 0x0000 }, + { 0x8700, 0x1792, 0x5000 }, + { 0x8700, 0x178a, 0x4000 }, + { 0x8700, 0x1786, 0x3000 }, + { 0x8700, 0x1784, 0x2000 }, + { 0x0700, 0x1783, 0x0000 }, + { 0x0700, 0x1785, 0x0000 }, + { 0x8700, 0x1788, 0x2000 }, + { 0x0700, 0x1787, 0x0000 }, + { 0x0700, 0x1789, 0x0000 }, + { 0x8700, 0x178e, 0x3000 }, + { 0x8700, 0x178c, 0x2000 }, + { 0x0700, 0x178b, 0x0000 }, + { 0x0700, 0x178d, 0x0000 }, + { 0x8700, 0x1790, 0x2000 }, + { 0x0700, 0x178f, 0x0000 }, + { 0x0700, 0x1791, 0x0000 }, + { 0x8700, 0x179a, 0x4000 }, + { 0x8700, 0x1796, 0x3000 }, + { 0x8700, 0x1794, 0x2000 }, + { 0x0700, 0x1793, 0x0000 }, + { 0x0700, 0x1795, 0x0000 }, + { 0x8700, 0x1798, 0x2000 }, + { 0x0700, 0x1797, 0x0000 }, + { 0x0700, 0x1799, 0x0000 }, + { 0x8700, 0x179e, 0x3000 }, + { 0x8700, 0x179c, 0x2000 }, + { 0x0700, 0x179b, 0x0000 }, + { 0x0700, 0x179d, 0x0000 }, + { 0x8700, 0x17a0, 0x2000 }, + { 0x0700, 0x179f, 0x0000 }, + { 0x0700, 0x17a1, 0x0000 }, + { 0x8700, 0x1915, 0x9000 }, + { 0x8700, 0x1837, 0x8000 }, + { 0x8d00, 0x17e4, 0x7000 }, + { 0x8a00, 0x17c2, 0x6000 }, + { 0x8700, 0x17b2, 0x5000 }, + { 0x8700, 0x17aa, 0x4000 }, + { 0x8700, 0x17a6, 0x3000 }, + { 0x8700, 0x17a4, 0x2000 }, + { 0x0700, 0x17a3, 0x0000 }, + { 0x0700, 0x17a5, 0x0000 }, + { 0x8700, 0x17a8, 0x2000 }, + { 0x0700, 0x17a7, 0x0000 }, + { 0x0700, 0x17a9, 0x0000 }, + { 0x8700, 0x17ae, 0x3000 }, + { 0x8700, 0x17ac, 0x2000 }, + { 0x0700, 0x17ab, 0x0000 }, + { 0x0700, 0x17ad, 0x0000 }, + { 0x8700, 0x17b0, 0x2000 }, + { 0x0700, 0x17af, 0x0000 }, + { 0x0700, 0x17b1, 0x0000 }, + { 0x8c00, 0x17ba, 0x4000 }, + { 0x8a00, 0x17b6, 0x3000 }, + { 0x8100, 0x17b4, 0x2000 }, + { 0x0700, 0x17b3, 0x0000 }, + { 0x0100, 0x17b5, 0x0000 }, + { 0x8c00, 0x17b8, 0x2000 }, + { 0x0c00, 0x17b7, 0x0000 }, + { 0x0c00, 0x17b9, 0x0000 }, + { 0x8a00, 0x17be, 0x3000 }, + { 0x8c00, 0x17bc, 0x2000 }, + { 0x0c00, 0x17bb, 0x0000 }, + { 0x0c00, 0x17bd, 0x0000 }, + { 0x8a00, 0x17c0, 0x2000 }, + { 0x0a00, 0x17bf, 0x0000 }, + { 0x0a00, 0x17c1, 0x0000 }, + { 0x8c00, 0x17d2, 0x5000 }, + { 0x8c00, 0x17ca, 0x4000 }, + { 0x8c00, 0x17c6, 0x3000 }, + { 0x8a00, 0x17c4, 0x2000 }, + { 0x0a00, 0x17c3, 0x0000 }, + { 0x0a00, 0x17c5, 0x0000 }, + { 0x8a00, 0x17c8, 0x2000 }, + { 0x0a00, 0x17c7, 0x0000 }, + { 0x0c00, 0x17c9, 0x0000 }, + { 0x8c00, 0x17ce, 0x3000 }, + { 0x8c00, 0x17cc, 0x2000 }, + { 0x0c00, 0x17cb, 0x0000 }, + { 0x0c00, 0x17cd, 0x0000 }, + { 0x8c00, 0x17d0, 0x2000 }, + { 0x0c00, 0x17cf, 0x0000 }, + { 0x0c00, 0x17d1, 0x0000 }, + { 0x9500, 0x17da, 0x4000 }, + { 0x9500, 0x17d6, 0x3000 }, + { 0x9500, 0x17d4, 0x2000 }, + { 0x0c00, 0x17d3, 0x0000 }, + { 0x1500, 0x17d5, 0x0000 }, + { 0x9500, 0x17d8, 0x2000 }, + { 0x0600, 0x17d7, 0x0000 }, + { 0x1500, 0x17d9, 0x0000 }, + { 0x8d00, 0x17e0, 0x3000 }, + { 0x8700, 0x17dc, 0x2000 }, + { 0x1700, 0x17db, 0x0000 }, + { 0x0c00, 0x17dd, 0x0000 }, + { 0x8d00, 0x17e2, 0x2000 }, + { 0x0d00, 0x17e1, 0x0000 }, + { 0x0d00, 0x17e3, 0x0000 }, + { 0x8d00, 0x1811, 0x6000 }, + { 0x9500, 0x1800, 0x5000 }, + { 0x8f00, 0x17f2, 0x4000 }, + { 0x8d00, 0x17e8, 0x3000 }, + { 0x8d00, 0x17e6, 0x2000 }, + { 0x0d00, 0x17e5, 0x0000 }, + { 0x0d00, 0x17e7, 0x0000 }, + { 0x8f00, 0x17f0, 0x2000 }, + { 0x0d00, 0x17e9, 0x0000 }, + { 0x0f00, 0x17f1, 0x0000 }, + { 0x8f00, 0x17f6, 0x3000 }, + { 0x8f00, 0x17f4, 0x2000 }, + { 0x0f00, 0x17f3, 0x0000 }, + { 0x0f00, 0x17f5, 0x0000 }, + { 0x8f00, 0x17f8, 0x2000 }, + { 0x0f00, 0x17f7, 0x0000 }, + { 0x0f00, 0x17f9, 0x0000 }, + { 0x9500, 0x1808, 0x4000 }, + { 0x9500, 0x1804, 0x3000 }, + { 0x9500, 0x1802, 0x2000 }, + { 0x1500, 0x1801, 0x0000 }, + { 0x1500, 0x1803, 0x0000 }, + { 0x9100, 0x1806, 0x2000 }, + { 0x1500, 0x1805, 0x0000 }, + { 0x1500, 0x1807, 0x0000 }, + { 0x8c00, 0x180c, 0x3000 }, + { 0x9500, 0x180a, 0x2000 }, + { 0x1500, 0x1809, 0x0000 }, + { 0x0c00, 0x180b, 0x0000 }, + { 0x9d00, 0x180e, 0x2000 }, + { 0x0c00, 0x180d, 0x0000 }, + { 0x0d00, 0x1810, 0x0000 }, + { 0x8700, 0x1827, 0x5000 }, + { 0x8d00, 0x1819, 0x4000 }, + { 0x8d00, 0x1815, 0x3000 }, + { 0x8d00, 0x1813, 0x2000 }, + { 0x0d00, 0x1812, 0x0000 }, + { 0x0d00, 0x1814, 0x0000 }, + { 0x8d00, 0x1817, 0x2000 }, + { 0x0d00, 0x1816, 0x0000 }, + { 0x0d00, 0x1818, 0x0000 }, + { 0x8700, 0x1823, 0x3000 }, + { 0x8700, 0x1821, 0x2000 }, + { 0x0700, 0x1820, 0x0000 }, + { 0x0700, 0x1822, 0x0000 }, + { 0x8700, 0x1825, 0x2000 }, + { 0x0700, 0x1824, 0x0000 }, + { 0x0700, 0x1826, 0x0000 }, + { 0x8700, 0x182f, 0x4000 }, + { 0x8700, 0x182b, 0x3000 }, + { 0x8700, 0x1829, 0x2000 }, + { 0x0700, 0x1828, 0x0000 }, + { 0x0700, 0x182a, 0x0000 }, + { 0x8700, 0x182d, 0x2000 }, + { 0x0700, 0x182c, 0x0000 }, + { 0x0700, 0x182e, 0x0000 }, + { 0x8700, 0x1833, 0x3000 }, + { 0x8700, 0x1831, 0x2000 }, + { 0x0700, 0x1830, 0x0000 }, + { 0x0700, 0x1832, 0x0000 }, + { 0x8700, 0x1835, 0x2000 }, + { 0x0700, 0x1834, 0x0000 }, + { 0x0700, 0x1836, 0x0000 }, + { 0x8700, 0x1877, 0x7000 }, + { 0x8700, 0x1857, 0x6000 }, + { 0x8700, 0x1847, 0x5000 }, + { 0x8700, 0x183f, 0x4000 }, + { 0x8700, 0x183b, 0x3000 }, + { 0x8700, 0x1839, 0x2000 }, + { 0x0700, 0x1838, 0x0000 }, + { 0x0700, 0x183a, 0x0000 }, + { 0x8700, 0x183d, 0x2000 }, + { 0x0700, 0x183c, 0x0000 }, + { 0x0700, 0x183e, 0x0000 }, + { 0x8600, 0x1843, 0x3000 }, + { 0x8700, 0x1841, 0x2000 }, + { 0x0700, 0x1840, 0x0000 }, + { 0x0700, 0x1842, 0x0000 }, + { 0x8700, 0x1845, 0x2000 }, + { 0x0700, 0x1844, 0x0000 }, + { 0x0700, 0x1846, 0x0000 }, + { 0x8700, 0x184f, 0x4000 }, + { 0x8700, 0x184b, 0x3000 }, + { 0x8700, 0x1849, 0x2000 }, + { 0x0700, 0x1848, 0x0000 }, + { 0x0700, 0x184a, 0x0000 }, + { 0x8700, 0x184d, 0x2000 }, + { 0x0700, 0x184c, 0x0000 }, + { 0x0700, 0x184e, 0x0000 }, + { 0x8700, 0x1853, 0x3000 }, + { 0x8700, 0x1851, 0x2000 }, + { 0x0700, 0x1850, 0x0000 }, + { 0x0700, 0x1852, 0x0000 }, + { 0x8700, 0x1855, 0x2000 }, + { 0x0700, 0x1854, 0x0000 }, + { 0x0700, 0x1856, 0x0000 }, + { 0x8700, 0x1867, 0x5000 }, + { 0x8700, 0x185f, 0x4000 }, + { 0x8700, 0x185b, 0x3000 }, + { 0x8700, 0x1859, 0x2000 }, + { 0x0700, 0x1858, 0x0000 }, + { 0x0700, 0x185a, 0x0000 }, + { 0x8700, 0x185d, 0x2000 }, + { 0x0700, 0x185c, 0x0000 }, + { 0x0700, 0x185e, 0x0000 }, + { 0x8700, 0x1863, 0x3000 }, + { 0x8700, 0x1861, 0x2000 }, + { 0x0700, 0x1860, 0x0000 }, + { 0x0700, 0x1862, 0x0000 }, + { 0x8700, 0x1865, 0x2000 }, + { 0x0700, 0x1864, 0x0000 }, + { 0x0700, 0x1866, 0x0000 }, + { 0x8700, 0x186f, 0x4000 }, + { 0x8700, 0x186b, 0x3000 }, + { 0x8700, 0x1869, 0x2000 }, + { 0x0700, 0x1868, 0x0000 }, + { 0x0700, 0x186a, 0x0000 }, + { 0x8700, 0x186d, 0x2000 }, + { 0x0700, 0x186c, 0x0000 }, + { 0x0700, 0x186e, 0x0000 }, + { 0x8700, 0x1873, 0x3000 }, + { 0x8700, 0x1871, 0x2000 }, + { 0x0700, 0x1870, 0x0000 }, + { 0x0700, 0x1872, 0x0000 }, + { 0x8700, 0x1875, 0x2000 }, + { 0x0700, 0x1874, 0x0000 }, + { 0x0700, 0x1876, 0x0000 }, + { 0x8700, 0x189f, 0x6000 }, + { 0x8700, 0x188f, 0x5000 }, + { 0x8700, 0x1887, 0x4000 }, + { 0x8700, 0x1883, 0x3000 }, + { 0x8700, 0x1881, 0x2000 }, + { 0x0700, 0x1880, 0x0000 }, + { 0x0700, 0x1882, 0x0000 }, + { 0x8700, 0x1885, 0x2000 }, + { 0x0700, 0x1884, 0x0000 }, + { 0x0700, 0x1886, 0x0000 }, + { 0x8700, 0x188b, 0x3000 }, + { 0x8700, 0x1889, 0x2000 }, + { 0x0700, 0x1888, 0x0000 }, + { 0x0700, 0x188a, 0x0000 }, + { 0x8700, 0x188d, 0x2000 }, + { 0x0700, 0x188c, 0x0000 }, + { 0x0700, 0x188e, 0x0000 }, + { 0x8700, 0x1897, 0x4000 }, + { 0x8700, 0x1893, 0x3000 }, + { 0x8700, 0x1891, 0x2000 }, + { 0x0700, 0x1890, 0x0000 }, + { 0x0700, 0x1892, 0x0000 }, + { 0x8700, 0x1895, 0x2000 }, + { 0x0700, 0x1894, 0x0000 }, + { 0x0700, 0x1896, 0x0000 }, + { 0x8700, 0x189b, 0x3000 }, + { 0x8700, 0x1899, 0x2000 }, + { 0x0700, 0x1898, 0x0000 }, + { 0x0700, 0x189a, 0x0000 }, + { 0x8700, 0x189d, 0x2000 }, + { 0x0700, 0x189c, 0x0000 }, + { 0x0700, 0x189e, 0x0000 }, + { 0x8700, 0x1905, 0x5000 }, + { 0x8700, 0x18a7, 0x4000 }, + { 0x8700, 0x18a3, 0x3000 }, + { 0x8700, 0x18a1, 0x2000 }, + { 0x0700, 0x18a0, 0x0000 }, + { 0x0700, 0x18a2, 0x0000 }, + { 0x8700, 0x18a5, 0x2000 }, + { 0x0700, 0x18a4, 0x0000 }, + { 0x0700, 0x18a6, 0x0000 }, + { 0x8700, 0x1901, 0x3000 }, + { 0x8c00, 0x18a9, 0x2000 }, + { 0x0700, 0x18a8, 0x0000 }, + { 0x0700, 0x1900, 0x0000 }, + { 0x8700, 0x1903, 0x2000 }, + { 0x0700, 0x1902, 0x0000 }, + { 0x0700, 0x1904, 0x0000 }, + { 0x8700, 0x190d, 0x4000 }, + { 0x8700, 0x1909, 0x3000 }, + { 0x8700, 0x1907, 0x2000 }, + { 0x0700, 0x1906, 0x0000 }, + { 0x0700, 0x1908, 0x0000 }, + { 0x8700, 0x190b, 0x2000 }, + { 0x0700, 0x190a, 0x0000 }, + { 0x0700, 0x190c, 0x0000 }, + { 0x8700, 0x1911, 0x3000 }, + { 0x8700, 0x190f, 0x2000 }, + { 0x0700, 0x190e, 0x0000 }, + { 0x0700, 0x1910, 0x0000 }, + { 0x8700, 0x1913, 0x2000 }, + { 0x0700, 0x1912, 0x0000 }, + { 0x0700, 0x1914, 0x0000 }, + { 0x8500, 0x1d10, 0x8000 }, + { 0x8700, 0x1963, 0x7000 }, + { 0x9a00, 0x1940, 0x6000 }, + { 0x8c00, 0x1928, 0x5000 }, + { 0x8c00, 0x1920, 0x4000 }, + { 0x8700, 0x1919, 0x3000 }, + { 0x8700, 0x1917, 0x2000 }, + { 0x0700, 0x1916, 0x0000 }, + { 0x0700, 0x1918, 0x0000 }, + { 0x8700, 0x191b, 0x2000 }, + { 0x0700, 0x191a, 0x0000 }, + { 0x0700, 0x191c, 0x0000 }, + { 0x8a00, 0x1924, 0x3000 }, + { 0x8c00, 0x1922, 0x2000 }, + { 0x0c00, 0x1921, 0x0000 }, + { 0x0a00, 0x1923, 0x0000 }, + { 0x8a00, 0x1926, 0x2000 }, + { 0x0a00, 0x1925, 0x0000 }, + { 0x0c00, 0x1927, 0x0000 }, + { 0x8a00, 0x1934, 0x4000 }, + { 0x8a00, 0x1930, 0x3000 }, + { 0x8a00, 0x192a, 0x2000 }, + { 0x0a00, 0x1929, 0x0000 }, + { 0x0a00, 0x192b, 0x0000 }, + { 0x8c00, 0x1932, 0x2000 }, + { 0x0a00, 0x1931, 0x0000 }, + { 0x0a00, 0x1933, 0x0000 }, + { 0x8a00, 0x1938, 0x3000 }, + { 0x8a00, 0x1936, 0x2000 }, + { 0x0a00, 0x1935, 0x0000 }, + { 0x0a00, 0x1937, 0x0000 }, + { 0x8c00, 0x193a, 0x2000 }, + { 0x0c00, 0x1939, 0x0000 }, + { 0x0c00, 0x193b, 0x0000 }, + { 0x8700, 0x1953, 0x5000 }, + { 0x8d00, 0x194b, 0x4000 }, + { 0x8d00, 0x1947, 0x3000 }, + { 0x9500, 0x1945, 0x2000 }, + { 0x1500, 0x1944, 0x0000 }, + { 0x0d00, 0x1946, 0x0000 }, + { 0x8d00, 0x1949, 0x2000 }, + { 0x0d00, 0x1948, 0x0000 }, + { 0x0d00, 0x194a, 0x0000 }, + { 0x8d00, 0x194f, 0x3000 }, + { 0x8d00, 0x194d, 0x2000 }, + { 0x0d00, 0x194c, 0x0000 }, + { 0x0d00, 0x194e, 0x0000 }, + { 0x8700, 0x1951, 0x2000 }, + { 0x0700, 0x1950, 0x0000 }, + { 0x0700, 0x1952, 0x0000 }, + { 0x8700, 0x195b, 0x4000 }, + { 0x8700, 0x1957, 0x3000 }, + { 0x8700, 0x1955, 0x2000 }, + { 0x0700, 0x1954, 0x0000 }, + { 0x0700, 0x1956, 0x0000 }, + { 0x8700, 0x1959, 0x2000 }, + { 0x0700, 0x1958, 0x0000 }, + { 0x0700, 0x195a, 0x0000 }, + { 0x8700, 0x195f, 0x3000 }, + { 0x8700, 0x195d, 0x2000 }, + { 0x0700, 0x195c, 0x0000 }, + { 0x0700, 0x195e, 0x0000 }, + { 0x8700, 0x1961, 0x2000 }, + { 0x0700, 0x1960, 0x0000 }, + { 0x0700, 0x1962, 0x0000 }, + { 0x9a00, 0x19f0, 0x6000 }, + { 0x9a00, 0x19e0, 0x5000 }, + { 0x8700, 0x196b, 0x4000 }, + { 0x8700, 0x1967, 0x3000 }, + { 0x8700, 0x1965, 0x2000 }, + { 0x0700, 0x1964, 0x0000 }, + { 0x0700, 0x1966, 0x0000 }, + { 0x8700, 0x1969, 0x2000 }, + { 0x0700, 0x1968, 0x0000 }, + { 0x0700, 0x196a, 0x0000 }, + { 0x8700, 0x1971, 0x3000 }, + { 0x8700, 0x196d, 0x2000 }, + { 0x0700, 0x196c, 0x0000 }, + { 0x0700, 0x1970, 0x0000 }, + { 0x8700, 0x1973, 0x2000 }, + { 0x0700, 0x1972, 0x0000 }, + { 0x0700, 0x1974, 0x0000 }, + { 0x9a00, 0x19e8, 0x4000 }, + { 0x9a00, 0x19e4, 0x3000 }, + { 0x9a00, 0x19e2, 0x2000 }, + { 0x1a00, 0x19e1, 0x0000 }, + { 0x1a00, 0x19e3, 0x0000 }, + { 0x9a00, 0x19e6, 0x2000 }, + { 0x1a00, 0x19e5, 0x0000 }, + { 0x1a00, 0x19e7, 0x0000 }, + { 0x9a00, 0x19ec, 0x3000 }, + { 0x9a00, 0x19ea, 0x2000 }, + { 0x1a00, 0x19e9, 0x0000 }, + { 0x1a00, 0x19eb, 0x0000 }, + { 0x9a00, 0x19ee, 0x2000 }, + { 0x1a00, 0x19ed, 0x0000 }, + { 0x1a00, 0x19ef, 0x0000 }, + { 0x8500, 0x1d00, 0x5000 }, + { 0x9a00, 0x19f8, 0x4000 }, + { 0x9a00, 0x19f4, 0x3000 }, + { 0x9a00, 0x19f2, 0x2000 }, + { 0x1a00, 0x19f1, 0x0000 }, + { 0x1a00, 0x19f3, 0x0000 }, + { 0x9a00, 0x19f6, 0x2000 }, + { 0x1a00, 0x19f5, 0x0000 }, + { 0x1a00, 0x19f7, 0x0000 }, + { 0x9a00, 0x19fc, 0x3000 }, + { 0x9a00, 0x19fa, 0x2000 }, + { 0x1a00, 0x19f9, 0x0000 }, + { 0x1a00, 0x19fb, 0x0000 }, + { 0x9a00, 0x19fe, 0x2000 }, + { 0x1a00, 0x19fd, 0x0000 }, + { 0x1a00, 0x19ff, 0x0000 }, + { 0x8500, 0x1d08, 0x4000 }, + { 0x8500, 0x1d04, 0x3000 }, + { 0x8500, 0x1d02, 0x2000 }, + { 0x0500, 0x1d01, 0x0000 }, + { 0x0500, 0x1d03, 0x0000 }, + { 0x8500, 0x1d06, 0x2000 }, + { 0x0500, 0x1d05, 0x0000 }, + { 0x0500, 0x1d07, 0x0000 }, + { 0x8500, 0x1d0c, 0x3000 }, + { 0x8500, 0x1d0a, 0x2000 }, + { 0x0500, 0x1d09, 0x0000 }, + { 0x0500, 0x1d0b, 0x0000 }, + { 0x8500, 0x1d0e, 0x2000 }, + { 0x0500, 0x1d0d, 0x0000 }, + { 0x0500, 0x1d0f, 0x0000 }, + { 0x8600, 0x1d50, 0x7000 }, + { 0x8600, 0x1d30, 0x6000 }, + { 0x8500, 0x1d20, 0x5000 }, + { 0x8500, 0x1d18, 0x4000 }, + { 0x8500, 0x1d14, 0x3000 }, + { 0x8500, 0x1d12, 0x2000 }, + { 0x0500, 0x1d11, 0x0000 }, + { 0x0500, 0x1d13, 0x0000 }, + { 0x8500, 0x1d16, 0x2000 }, + { 0x0500, 0x1d15, 0x0000 }, + { 0x0500, 0x1d17, 0x0000 }, + { 0x8500, 0x1d1c, 0x3000 }, + { 0x8500, 0x1d1a, 0x2000 }, + { 0x0500, 0x1d19, 0x0000 }, + { 0x0500, 0x1d1b, 0x0000 }, + { 0x8500, 0x1d1e, 0x2000 }, + { 0x0500, 0x1d1d, 0x0000 }, + { 0x0500, 0x1d1f, 0x0000 }, + { 0x8500, 0x1d28, 0x4000 }, + { 0x8500, 0x1d24, 0x3000 }, + { 0x8500, 0x1d22, 0x2000 }, + { 0x0500, 0x1d21, 0x0000 }, + { 0x0500, 0x1d23, 0x0000 }, + { 0x8500, 0x1d26, 0x2000 }, + { 0x0500, 0x1d25, 0x0000 }, + { 0x0500, 0x1d27, 0x0000 }, + { 0x8600, 0x1d2c, 0x3000 }, + { 0x8500, 0x1d2a, 0x2000 }, + { 0x0500, 0x1d29, 0x0000 }, + { 0x0500, 0x1d2b, 0x0000 }, + { 0x8600, 0x1d2e, 0x2000 }, + { 0x0600, 0x1d2d, 0x0000 }, + { 0x0600, 0x1d2f, 0x0000 }, + { 0x8600, 0x1d40, 0x5000 }, + { 0x8600, 0x1d38, 0x4000 }, + { 0x8600, 0x1d34, 0x3000 }, + { 0x8600, 0x1d32, 0x2000 }, + { 0x0600, 0x1d31, 0x0000 }, + { 0x0600, 0x1d33, 0x0000 }, + { 0x8600, 0x1d36, 0x2000 }, + { 0x0600, 0x1d35, 0x0000 }, + { 0x0600, 0x1d37, 0x0000 }, + { 0x8600, 0x1d3c, 0x3000 }, + { 0x8600, 0x1d3a, 0x2000 }, + { 0x0600, 0x1d39, 0x0000 }, + { 0x0600, 0x1d3b, 0x0000 }, + { 0x8600, 0x1d3e, 0x2000 }, + { 0x0600, 0x1d3d, 0x0000 }, + { 0x0600, 0x1d3f, 0x0000 }, + { 0x8600, 0x1d48, 0x4000 }, + { 0x8600, 0x1d44, 0x3000 }, + { 0x8600, 0x1d42, 0x2000 }, + { 0x0600, 0x1d41, 0x0000 }, + { 0x0600, 0x1d43, 0x0000 }, + { 0x8600, 0x1d46, 0x2000 }, + { 0x0600, 0x1d45, 0x0000 }, + { 0x0600, 0x1d47, 0x0000 }, + { 0x8600, 0x1d4c, 0x3000 }, + { 0x8600, 0x1d4a, 0x2000 }, + { 0x0600, 0x1d49, 0x0000 }, + { 0x0600, 0x1d4b, 0x0000 }, + { 0x8600, 0x1d4e, 0x2000 }, + { 0x0600, 0x1d4d, 0x0000 }, + { 0x0600, 0x1d4f, 0x0000 }, + { 0x8900, 0x1e04, 0x6001 }, + { 0x8600, 0x1d60, 0x5000 }, + { 0x8600, 0x1d58, 0x4000 }, + { 0x8600, 0x1d54, 0x3000 }, + { 0x8600, 0x1d52, 0x2000 }, + { 0x0600, 0x1d51, 0x0000 }, + { 0x0600, 0x1d53, 0x0000 }, + { 0x8600, 0x1d56, 0x2000 }, + { 0x0600, 0x1d55, 0x0000 }, + { 0x0600, 0x1d57, 0x0000 }, + { 0x8600, 0x1d5c, 0x3000 }, + { 0x8600, 0x1d5a, 0x2000 }, + { 0x0600, 0x1d59, 0x0000 }, + { 0x0600, 0x1d5b, 0x0000 }, + { 0x8600, 0x1d5e, 0x2000 }, + { 0x0600, 0x1d5d, 0x0000 }, + { 0x0600, 0x1d5f, 0x0000 }, + { 0x8500, 0x1d68, 0x4000 }, + { 0x8500, 0x1d64, 0x3000 }, + { 0x8500, 0x1d62, 0x2000 }, + { 0x0600, 0x1d61, 0x0000 }, + { 0x0500, 0x1d63, 0x0000 }, + { 0x8500, 0x1d66, 0x2000 }, + { 0x0500, 0x1d65, 0x0000 }, + { 0x0500, 0x1d67, 0x0000 }, + { 0x8900, 0x1e00, 0x3001 }, + { 0x8500, 0x1d6a, 0x2000 }, + { 0x0500, 0x1d69, 0x0000 }, + { 0x0500, 0x1d6b, 0x0000 }, + { 0x8900, 0x1e02, 0x2001 }, + { 0x0500, 0x1e01, 0x0fff }, + { 0x0500, 0x1e03, 0x0fff }, + { 0x8900, 0x1e14, 0x5001 }, + { 0x8900, 0x1e0c, 0x4001 }, + { 0x8900, 0x1e08, 0x3001 }, + { 0x8900, 0x1e06, 0x2001 }, + { 0x0500, 0x1e05, 0x0fff }, + { 0x0500, 0x1e07, 0x0fff }, + { 0x8900, 0x1e0a, 0x2001 }, + { 0x0500, 0x1e09, 0x0fff }, + { 0x0500, 0x1e0b, 0x0fff }, + { 0x8900, 0x1e10, 0x3001 }, + { 0x8900, 0x1e0e, 0x2001 }, + { 0x0500, 0x1e0d, 0x0fff }, + { 0x0500, 0x1e0f, 0x0fff }, + { 0x8900, 0x1e12, 0x2001 }, + { 0x0500, 0x1e11, 0x0fff }, + { 0x0500, 0x1e13, 0x0fff }, + { 0x8900, 0x1e1c, 0x4001 }, + { 0x8900, 0x1e18, 0x3001 }, + { 0x8900, 0x1e16, 0x2001 }, + { 0x0500, 0x1e15, 0x0fff }, + { 0x0500, 0x1e17, 0x0fff }, + { 0x8900, 0x1e1a, 0x2001 }, + { 0x0500, 0x1e19, 0x0fff }, + { 0x0500, 0x1e1b, 0x0fff }, + { 0x8900, 0x1e20, 0x3001 }, + { 0x8900, 0x1e1e, 0x2001 }, + { 0x0500, 0x1e1d, 0x0fff }, + { 0x0500, 0x1e1f, 0x0fff }, + { 0x8900, 0x1e22, 0x2001 }, + { 0x0500, 0x1e21, 0x0fff }, + { 0x0500, 0x1e23, 0x0fff }, + { 0x9600, 0x2045, 0xa000 }, + { 0x8500, 0x1f32, 0x9008 }, + { 0x8900, 0x1ea8, 0x8001 }, + { 0x8900, 0x1e64, 0x7001 }, + { 0x8900, 0x1e44, 0x6001 }, + { 0x8900, 0x1e34, 0x5001 }, + { 0x8900, 0x1e2c, 0x4001 }, + { 0x8900, 0x1e28, 0x3001 }, + { 0x8900, 0x1e26, 0x2001 }, + { 0x0500, 0x1e25, 0x0fff }, + { 0x0500, 0x1e27, 0x0fff }, + { 0x8900, 0x1e2a, 0x2001 }, + { 0x0500, 0x1e29, 0x0fff }, + { 0x0500, 0x1e2b, 0x0fff }, + { 0x8900, 0x1e30, 0x3001 }, + { 0x8900, 0x1e2e, 0x2001 }, + { 0x0500, 0x1e2d, 0x0fff }, + { 0x0500, 0x1e2f, 0x0fff }, + { 0x8900, 0x1e32, 0x2001 }, + { 0x0500, 0x1e31, 0x0fff }, + { 0x0500, 0x1e33, 0x0fff }, + { 0x8900, 0x1e3c, 0x4001 }, + { 0x8900, 0x1e38, 0x3001 }, + { 0x8900, 0x1e36, 0x2001 }, + { 0x0500, 0x1e35, 0x0fff }, + { 0x0500, 0x1e37, 0x0fff }, + { 0x8900, 0x1e3a, 0x2001 }, + { 0x0500, 0x1e39, 0x0fff }, + { 0x0500, 0x1e3b, 0x0fff }, + { 0x8900, 0x1e40, 0x3001 }, + { 0x8900, 0x1e3e, 0x2001 }, + { 0x0500, 0x1e3d, 0x0fff }, + { 0x0500, 0x1e3f, 0x0fff }, + { 0x8900, 0x1e42, 0x2001 }, + { 0x0500, 0x1e41, 0x0fff }, + { 0x0500, 0x1e43, 0x0fff }, + { 0x8900, 0x1e54, 0x5001 }, + { 0x8900, 0x1e4c, 0x4001 }, + { 0x8900, 0x1e48, 0x3001 }, + { 0x8900, 0x1e46, 0x2001 }, + { 0x0500, 0x1e45, 0x0fff }, + { 0x0500, 0x1e47, 0x0fff }, + { 0x8900, 0x1e4a, 0x2001 }, + { 0x0500, 0x1e49, 0x0fff }, + { 0x0500, 0x1e4b, 0x0fff }, + { 0x8900, 0x1e50, 0x3001 }, + { 0x8900, 0x1e4e, 0x2001 }, + { 0x0500, 0x1e4d, 0x0fff }, + { 0x0500, 0x1e4f, 0x0fff }, + { 0x8900, 0x1e52, 0x2001 }, + { 0x0500, 0x1e51, 0x0fff }, + { 0x0500, 0x1e53, 0x0fff }, + { 0x8900, 0x1e5c, 0x4001 }, + { 0x8900, 0x1e58, 0x3001 }, + { 0x8900, 0x1e56, 0x2001 }, + { 0x0500, 0x1e55, 0x0fff }, + { 0x0500, 0x1e57, 0x0fff }, + { 0x8900, 0x1e5a, 0x2001 }, + { 0x0500, 0x1e59, 0x0fff }, + { 0x0500, 0x1e5b, 0x0fff }, + { 0x8900, 0x1e60, 0x3001 }, + { 0x8900, 0x1e5e, 0x2001 }, + { 0x0500, 0x1e5d, 0x0fff }, + { 0x0500, 0x1e5f, 0x0fff }, + { 0x8900, 0x1e62, 0x2001 }, + { 0x0500, 0x1e61, 0x0fff }, + { 0x0500, 0x1e63, 0x0fff }, + { 0x8900, 0x1e84, 0x6001 }, + { 0x8900, 0x1e74, 0x5001 }, + { 0x8900, 0x1e6c, 0x4001 }, + { 0x8900, 0x1e68, 0x3001 }, + { 0x8900, 0x1e66, 0x2001 }, + { 0x0500, 0x1e65, 0x0fff }, + { 0x0500, 0x1e67, 0x0fff }, + { 0x8900, 0x1e6a, 0x2001 }, + { 0x0500, 0x1e69, 0x0fff }, + { 0x0500, 0x1e6b, 0x0fff }, + { 0x8900, 0x1e70, 0x3001 }, + { 0x8900, 0x1e6e, 0x2001 }, + { 0x0500, 0x1e6d, 0x0fff }, + { 0x0500, 0x1e6f, 0x0fff }, + { 0x8900, 0x1e72, 0x2001 }, + { 0x0500, 0x1e71, 0x0fff }, + { 0x0500, 0x1e73, 0x0fff }, + { 0x8900, 0x1e7c, 0x4001 }, + { 0x8900, 0x1e78, 0x3001 }, + { 0x8900, 0x1e76, 0x2001 }, + { 0x0500, 0x1e75, 0x0fff }, + { 0x0500, 0x1e77, 0x0fff }, + { 0x8900, 0x1e7a, 0x2001 }, + { 0x0500, 0x1e79, 0x0fff }, + { 0x0500, 0x1e7b, 0x0fff }, + { 0x8900, 0x1e80, 0x3001 }, + { 0x8900, 0x1e7e, 0x2001 }, + { 0x0500, 0x1e7d, 0x0fff }, + { 0x0500, 0x1e7f, 0x0fff }, + { 0x8900, 0x1e82, 0x2001 }, + { 0x0500, 0x1e81, 0x0fff }, + { 0x0500, 0x1e83, 0x0fff }, + { 0x8900, 0x1e94, 0x5001 }, + { 0x8900, 0x1e8c, 0x4001 }, + { 0x8900, 0x1e88, 0x3001 }, + { 0x8900, 0x1e86, 0x2001 }, + { 0x0500, 0x1e85, 0x0fff }, + { 0x0500, 0x1e87, 0x0fff }, + { 0x8900, 0x1e8a, 0x2001 }, + { 0x0500, 0x1e89, 0x0fff }, + { 0x0500, 0x1e8b, 0x0fff }, + { 0x8900, 0x1e90, 0x3001 }, + { 0x8900, 0x1e8e, 0x2001 }, + { 0x0500, 0x1e8d, 0x0fff }, + { 0x0500, 0x1e8f, 0x0fff }, + { 0x8900, 0x1e92, 0x2001 }, + { 0x0500, 0x1e91, 0x0fff }, + { 0x0500, 0x1e93, 0x0fff }, + { 0x8900, 0x1ea0, 0x4001 }, + { 0x8500, 0x1e98, 0x3000 }, + { 0x8500, 0x1e96, 0x2000 }, + { 0x0500, 0x1e95, 0x0fff }, + { 0x0500, 0x1e97, 0x0000 }, + { 0x8500, 0x1e9a, 0x2000 }, + { 0x0500, 0x1e99, 0x0000 }, + { 0x0500, 0x1e9b, 0x0fc5 }, + { 0x8900, 0x1ea4, 0x3001 }, + { 0x8900, 0x1ea2, 0x2001 }, + { 0x0500, 0x1ea1, 0x0fff }, + { 0x0500, 0x1ea3, 0x0fff }, + { 0x8900, 0x1ea6, 0x2001 }, + { 0x0500, 0x1ea5, 0x0fff }, + { 0x0500, 0x1ea7, 0x0fff }, + { 0x8900, 0x1ee8, 0x7001 }, + { 0x8900, 0x1ec8, 0x6001 }, + { 0x8900, 0x1eb8, 0x5001 }, + { 0x8900, 0x1eb0, 0x4001 }, + { 0x8900, 0x1eac, 0x3001 }, + { 0x8900, 0x1eaa, 0x2001 }, + { 0x0500, 0x1ea9, 0x0fff }, + { 0x0500, 0x1eab, 0x0fff }, + { 0x8900, 0x1eae, 0x2001 }, + { 0x0500, 0x1ead, 0x0fff }, + { 0x0500, 0x1eaf, 0x0fff }, + { 0x8900, 0x1eb4, 0x3001 }, + { 0x8900, 0x1eb2, 0x2001 }, + { 0x0500, 0x1eb1, 0x0fff }, + { 0x0500, 0x1eb3, 0x0fff }, + { 0x8900, 0x1eb6, 0x2001 }, + { 0x0500, 0x1eb5, 0x0fff }, + { 0x0500, 0x1eb7, 0x0fff }, + { 0x8900, 0x1ec0, 0x4001 }, + { 0x8900, 0x1ebc, 0x3001 }, + { 0x8900, 0x1eba, 0x2001 }, + { 0x0500, 0x1eb9, 0x0fff }, + { 0x0500, 0x1ebb, 0x0fff }, + { 0x8900, 0x1ebe, 0x2001 }, + { 0x0500, 0x1ebd, 0x0fff }, + { 0x0500, 0x1ebf, 0x0fff }, + { 0x8900, 0x1ec4, 0x3001 }, + { 0x8900, 0x1ec2, 0x2001 }, + { 0x0500, 0x1ec1, 0x0fff }, + { 0x0500, 0x1ec3, 0x0fff }, + { 0x8900, 0x1ec6, 0x2001 }, + { 0x0500, 0x1ec5, 0x0fff }, + { 0x0500, 0x1ec7, 0x0fff }, + { 0x8900, 0x1ed8, 0x5001 }, + { 0x8900, 0x1ed0, 0x4001 }, + { 0x8900, 0x1ecc, 0x3001 }, + { 0x8900, 0x1eca, 0x2001 }, + { 0x0500, 0x1ec9, 0x0fff }, + { 0x0500, 0x1ecb, 0x0fff }, + { 0x8900, 0x1ece, 0x2001 }, + { 0x0500, 0x1ecd, 0x0fff }, + { 0x0500, 0x1ecf, 0x0fff }, + { 0x8900, 0x1ed4, 0x3001 }, + { 0x8900, 0x1ed2, 0x2001 }, + { 0x0500, 0x1ed1, 0x0fff }, + { 0x0500, 0x1ed3, 0x0fff }, + { 0x8900, 0x1ed6, 0x2001 }, + { 0x0500, 0x1ed5, 0x0fff }, + { 0x0500, 0x1ed7, 0x0fff }, + { 0x8900, 0x1ee0, 0x4001 }, + { 0x8900, 0x1edc, 0x3001 }, + { 0x8900, 0x1eda, 0x2001 }, + { 0x0500, 0x1ed9, 0x0fff }, + { 0x0500, 0x1edb, 0x0fff }, + { 0x8900, 0x1ede, 0x2001 }, + { 0x0500, 0x1edd, 0x0fff }, + { 0x0500, 0x1edf, 0x0fff }, + { 0x8900, 0x1ee4, 0x3001 }, + { 0x8900, 0x1ee2, 0x2001 }, + { 0x0500, 0x1ee1, 0x0fff }, + { 0x0500, 0x1ee3, 0x0fff }, + { 0x8900, 0x1ee6, 0x2001 }, + { 0x0500, 0x1ee5, 0x0fff }, + { 0x0500, 0x1ee7, 0x0fff }, + { 0x8900, 0x1f0e, 0x6ff8 }, + { 0x8900, 0x1ef8, 0x5001 }, + { 0x8900, 0x1ef0, 0x4001 }, + { 0x8900, 0x1eec, 0x3001 }, + { 0x8900, 0x1eea, 0x2001 }, + { 0x0500, 0x1ee9, 0x0fff }, + { 0x0500, 0x1eeb, 0x0fff }, + { 0x8900, 0x1eee, 0x2001 }, + { 0x0500, 0x1eed, 0x0fff }, + { 0x0500, 0x1eef, 0x0fff }, + { 0x8900, 0x1ef4, 0x3001 }, + { 0x8900, 0x1ef2, 0x2001 }, + { 0x0500, 0x1ef1, 0x0fff }, + { 0x0500, 0x1ef3, 0x0fff }, + { 0x8900, 0x1ef6, 0x2001 }, + { 0x0500, 0x1ef5, 0x0fff }, + { 0x0500, 0x1ef7, 0x0fff }, + { 0x8500, 0x1f06, 0x4008 }, + { 0x8500, 0x1f02, 0x3008 }, + { 0x8500, 0x1f00, 0x2008 }, + { 0x0500, 0x1ef9, 0x0fff }, + { 0x0500, 0x1f01, 0x0008 }, + { 0x8500, 0x1f04, 0x2008 }, + { 0x0500, 0x1f03, 0x0008 }, + { 0x0500, 0x1f05, 0x0008 }, + { 0x8900, 0x1f0a, 0x3ff8 }, + { 0x8900, 0x1f08, 0x2ff8 }, + { 0x0500, 0x1f07, 0x0008 }, + { 0x0900, 0x1f09, 0x0ff8 }, + { 0x8900, 0x1f0c, 0x2ff8 }, + { 0x0900, 0x1f0b, 0x0ff8 }, + { 0x0900, 0x1f0d, 0x0ff8 }, + { 0x8500, 0x1f22, 0x5008 }, + { 0x8900, 0x1f18, 0x4ff8 }, + { 0x8500, 0x1f12, 0x3008 }, + { 0x8500, 0x1f10, 0x2008 }, + { 0x0900, 0x1f0f, 0x0ff8 }, + { 0x0500, 0x1f11, 0x0008 }, + { 0x8500, 0x1f14, 0x2008 }, + { 0x0500, 0x1f13, 0x0008 }, + { 0x0500, 0x1f15, 0x0008 }, + { 0x8900, 0x1f1c, 0x3ff8 }, + { 0x8900, 0x1f1a, 0x2ff8 }, + { 0x0900, 0x1f19, 0x0ff8 }, + { 0x0900, 0x1f1b, 0x0ff8 }, + { 0x8500, 0x1f20, 0x2008 }, + { 0x0900, 0x1f1d, 0x0ff8 }, + { 0x0500, 0x1f21, 0x0008 }, + { 0x8900, 0x1f2a, 0x4ff8 }, + { 0x8500, 0x1f26, 0x3008 }, + { 0x8500, 0x1f24, 0x2008 }, + { 0x0500, 0x1f23, 0x0008 }, + { 0x0500, 0x1f25, 0x0008 }, + { 0x8900, 0x1f28, 0x2ff8 }, + { 0x0500, 0x1f27, 0x0008 }, + { 0x0900, 0x1f29, 0x0ff8 }, + { 0x8900, 0x1f2e, 0x3ff8 }, + { 0x8900, 0x1f2c, 0x2ff8 }, + { 0x0900, 0x1f2b, 0x0ff8 }, + { 0x0900, 0x1f2d, 0x0ff8 }, + { 0x8500, 0x1f30, 0x2008 }, + { 0x0900, 0x1f2f, 0x0ff8 }, + { 0x0500, 0x1f31, 0x0008 }, + { 0x9800, 0x1fbd, 0x8000 }, + { 0x8500, 0x1f7a, 0x7070 }, + { 0x8500, 0x1f56, 0x6000 }, + { 0x8500, 0x1f42, 0x5008 }, + { 0x8900, 0x1f3a, 0x4ff8 }, + { 0x8500, 0x1f36, 0x3008 }, + { 0x8500, 0x1f34, 0x2008 }, + { 0x0500, 0x1f33, 0x0008 }, + { 0x0500, 0x1f35, 0x0008 }, + { 0x8900, 0x1f38, 0x2ff8 }, + { 0x0500, 0x1f37, 0x0008 }, + { 0x0900, 0x1f39, 0x0ff8 }, + { 0x8900, 0x1f3e, 0x3ff8 }, + { 0x8900, 0x1f3c, 0x2ff8 }, + { 0x0900, 0x1f3b, 0x0ff8 }, + { 0x0900, 0x1f3d, 0x0ff8 }, + { 0x8500, 0x1f40, 0x2008 }, + { 0x0900, 0x1f3f, 0x0ff8 }, + { 0x0500, 0x1f41, 0x0008 }, + { 0x8900, 0x1f4c, 0x4ff8 }, + { 0x8900, 0x1f48, 0x3ff8 }, + { 0x8500, 0x1f44, 0x2008 }, + { 0x0500, 0x1f43, 0x0008 }, + { 0x0500, 0x1f45, 0x0008 }, + { 0x8900, 0x1f4a, 0x2ff8 }, + { 0x0900, 0x1f49, 0x0ff8 }, + { 0x0900, 0x1f4b, 0x0ff8 }, + { 0x8500, 0x1f52, 0x3000 }, + { 0x8500, 0x1f50, 0x2000 }, + { 0x0900, 0x1f4d, 0x0ff8 }, + { 0x0500, 0x1f51, 0x0008 }, + { 0x8500, 0x1f54, 0x2000 }, + { 0x0500, 0x1f53, 0x0008 }, + { 0x0500, 0x1f55, 0x0008 }, + { 0x8900, 0x1f6a, 0x5ff8 }, + { 0x8500, 0x1f62, 0x4008 }, + { 0x8900, 0x1f5d, 0x3ff8 }, + { 0x8900, 0x1f59, 0x2ff8 }, + { 0x0500, 0x1f57, 0x0008 }, + { 0x0900, 0x1f5b, 0x0ff8 }, + { 0x8500, 0x1f60, 0x2008 }, + { 0x0900, 0x1f5f, 0x0ff8 }, + { 0x0500, 0x1f61, 0x0008 }, + { 0x8500, 0x1f66, 0x3008 }, + { 0x8500, 0x1f64, 0x2008 }, + { 0x0500, 0x1f63, 0x0008 }, + { 0x0500, 0x1f65, 0x0008 }, + { 0x8900, 0x1f68, 0x2ff8 }, + { 0x0500, 0x1f67, 0x0008 }, + { 0x0900, 0x1f69, 0x0ff8 }, + { 0x8500, 0x1f72, 0x4056 }, + { 0x8900, 0x1f6e, 0x3ff8 }, + { 0x8900, 0x1f6c, 0x2ff8 }, + { 0x0900, 0x1f6b, 0x0ff8 }, + { 0x0900, 0x1f6d, 0x0ff8 }, + { 0x8500, 0x1f70, 0x204a }, + { 0x0900, 0x1f6f, 0x0ff8 }, + { 0x0500, 0x1f71, 0x004a }, + { 0x8500, 0x1f76, 0x3064 }, + { 0x8500, 0x1f74, 0x2056 }, + { 0x0500, 0x1f73, 0x0056 }, + { 0x0500, 0x1f75, 0x0056 }, + { 0x8500, 0x1f78, 0x2080 }, + { 0x0500, 0x1f77, 0x0064 }, + { 0x0500, 0x1f79, 0x0080 }, + { 0x8800, 0x1f9c, 0x6000 }, + { 0x8800, 0x1f8c, 0x5000 }, + { 0x8500, 0x1f84, 0x4008 }, + { 0x8500, 0x1f80, 0x3008 }, + { 0x8500, 0x1f7c, 0x207e }, + { 0x0500, 0x1f7b, 0x0070 }, + { 0x0500, 0x1f7d, 0x007e }, + { 0x8500, 0x1f82, 0x2008 }, + { 0x0500, 0x1f81, 0x0008 }, + { 0x0500, 0x1f83, 0x0008 }, + { 0x8800, 0x1f88, 0x3000 }, + { 0x8500, 0x1f86, 0x2008 }, + { 0x0500, 0x1f85, 0x0008 }, + { 0x0500, 0x1f87, 0x0008 }, + { 0x8800, 0x1f8a, 0x2000 }, + { 0x0800, 0x1f89, 0x0000 }, + { 0x0800, 0x1f8b, 0x0000 }, + { 0x8500, 0x1f94, 0x4008 }, + { 0x8500, 0x1f90, 0x3008 }, + { 0x8800, 0x1f8e, 0x2000 }, + { 0x0800, 0x1f8d, 0x0000 }, + { 0x0800, 0x1f8f, 0x0000 }, + { 0x8500, 0x1f92, 0x2008 }, + { 0x0500, 0x1f91, 0x0008 }, + { 0x0500, 0x1f93, 0x0008 }, + { 0x8800, 0x1f98, 0x3000 }, + { 0x8500, 0x1f96, 0x2008 }, + { 0x0500, 0x1f95, 0x0008 }, + { 0x0500, 0x1f97, 0x0008 }, + { 0x8800, 0x1f9a, 0x2000 }, + { 0x0800, 0x1f99, 0x0000 }, + { 0x0800, 0x1f9b, 0x0000 }, + { 0x8800, 0x1fac, 0x5000 }, + { 0x8500, 0x1fa4, 0x4008 }, + { 0x8500, 0x1fa0, 0x3008 }, + { 0x8800, 0x1f9e, 0x2000 }, + { 0x0800, 0x1f9d, 0x0000 }, + { 0x0800, 0x1f9f, 0x0000 }, + { 0x8500, 0x1fa2, 0x2008 }, + { 0x0500, 0x1fa1, 0x0008 }, + { 0x0500, 0x1fa3, 0x0008 }, + { 0x8800, 0x1fa8, 0x3000 }, + { 0x8500, 0x1fa6, 0x2008 }, + { 0x0500, 0x1fa5, 0x0008 }, + { 0x0500, 0x1fa7, 0x0008 }, + { 0x8800, 0x1faa, 0x2000 }, + { 0x0800, 0x1fa9, 0x0000 }, + { 0x0800, 0x1fab, 0x0000 }, + { 0x8500, 0x1fb4, 0x4000 }, + { 0x8500, 0x1fb0, 0x3008 }, + { 0x8800, 0x1fae, 0x2000 }, + { 0x0800, 0x1fad, 0x0000 }, + { 0x0800, 0x1faf, 0x0000 }, + { 0x8500, 0x1fb2, 0x2000 }, + { 0x0500, 0x1fb1, 0x0008 }, + { 0x0500, 0x1fb3, 0x0009 }, + { 0x8900, 0x1fb9, 0x3ff8 }, + { 0x8500, 0x1fb7, 0x2000 }, + { 0x0500, 0x1fb6, 0x0000 }, + { 0x0900, 0x1fb8, 0x0ff8 }, + { 0x8900, 0x1fbb, 0x2fb6 }, + { 0x0900, 0x1fba, 0x0fb6 }, + { 0x0800, 0x1fbc, 0x0000 }, + { 0x9d00, 0x2005, 0x7000 }, + { 0x8500, 0x1fe1, 0x6008 }, + { 0x9800, 0x1fce, 0x5000 }, + { 0x8500, 0x1fc6, 0x4000 }, + { 0x9800, 0x1fc1, 0x3000 }, + { 0x9800, 0x1fbf, 0x2000 }, + { 0x0500, 0x1fbe, 0x0000 }, + { 0x1800, 0x1fc0, 0x0000 }, + { 0x8500, 0x1fc3, 0x2009 }, + { 0x0500, 0x1fc2, 0x0000 }, + { 0x0500, 0x1fc4, 0x0000 }, + { 0x8900, 0x1fca, 0x3faa }, + { 0x8900, 0x1fc8, 0x2faa }, + { 0x0500, 0x1fc7, 0x0000 }, + { 0x0900, 0x1fc9, 0x0faa }, + { 0x8800, 0x1fcc, 0x2000 }, + { 0x0900, 0x1fcb, 0x0faa }, + { 0x1800, 0x1fcd, 0x0000 }, + { 0x8900, 0x1fd8, 0x4ff8 }, + { 0x8500, 0x1fd2, 0x3000 }, + { 0x8500, 0x1fd0, 0x2008 }, + { 0x1800, 0x1fcf, 0x0000 }, + { 0x0500, 0x1fd1, 0x0008 }, + { 0x8500, 0x1fd6, 0x2000 }, + { 0x0500, 0x1fd3, 0x0000 }, + { 0x0500, 0x1fd7, 0x0000 }, + { 0x9800, 0x1fdd, 0x3000 }, + { 0x8900, 0x1fda, 0x2f9c }, + { 0x0900, 0x1fd9, 0x0ff8 }, + { 0x0900, 0x1fdb, 0x0f9c }, + { 0x9800, 0x1fdf, 0x2000 }, + { 0x1800, 0x1fde, 0x0000 }, + { 0x0500, 0x1fe0, 0x0008 }, + { 0x8500, 0x1ff3, 0x5009 }, + { 0x8900, 0x1fe9, 0x4ff8 }, + { 0x8500, 0x1fe5, 0x3007 }, + { 0x8500, 0x1fe3, 0x2000 }, + { 0x0500, 0x1fe2, 0x0000 }, + { 0x0500, 0x1fe4, 0x0000 }, + { 0x8500, 0x1fe7, 0x2000 }, + { 0x0500, 0x1fe6, 0x0000 }, + { 0x0900, 0x1fe8, 0x0ff8 }, + { 0x9800, 0x1fed, 0x3000 }, + { 0x8900, 0x1feb, 0x2f90 }, + { 0x0900, 0x1fea, 0x0f90 }, + { 0x0900, 0x1fec, 0x0ff9 }, + { 0x9800, 0x1fef, 0x2000 }, + { 0x1800, 0x1fee, 0x0000 }, + { 0x0500, 0x1ff2, 0x0000 }, + { 0x8800, 0x1ffc, 0x4000 }, + { 0x8900, 0x1ff8, 0x3f80 }, + { 0x8500, 0x1ff6, 0x2000 }, + { 0x0500, 0x1ff4, 0x0000 }, + { 0x0500, 0x1ff7, 0x0000 }, + { 0x8900, 0x1ffa, 0x2f82 }, + { 0x0900, 0x1ff9, 0x0f80 }, + { 0x0900, 0x1ffb, 0x0f82 }, + { 0x9d00, 0x2001, 0x3000 }, + { 0x9800, 0x1ffe, 0x2000 }, + { 0x1800, 0x1ffd, 0x0000 }, + { 0x1d00, 0x2000, 0x0000 }, + { 0x9d00, 0x2003, 0x2000 }, + { 0x1d00, 0x2002, 0x0000 }, + { 0x1d00, 0x2004, 0x0000 }, + { 0x9500, 0x2025, 0x6000 }, + { 0x9100, 0x2015, 0x5000 }, + { 0x8100, 0x200d, 0x4000 }, + { 0x9d00, 0x2009, 0x3000 }, + { 0x9d00, 0x2007, 0x2000 }, + { 0x1d00, 0x2006, 0x0000 }, + { 0x1d00, 0x2008, 0x0000 }, + { 0x9d00, 0x200b, 0x2000 }, + { 0x1d00, 0x200a, 0x0000 }, + { 0x0100, 0x200c, 0x0000 }, + { 0x9100, 0x2011, 0x3000 }, + { 0x8100, 0x200f, 0x2000 }, + { 0x0100, 0x200e, 0x0000 }, + { 0x1100, 0x2010, 0x0000 }, + { 0x9100, 0x2013, 0x2000 }, + { 0x1100, 0x2012, 0x0000 }, + { 0x1100, 0x2014, 0x0000 }, + { 0x9300, 0x201d, 0x4000 }, + { 0x9300, 0x2019, 0x3000 }, + { 0x9500, 0x2017, 0x2000 }, + { 0x1500, 0x2016, 0x0000 }, + { 0x1400, 0x2018, 0x0000 }, + { 0x9400, 0x201b, 0x2000 }, + { 0x1600, 0x201a, 0x0000 }, + { 0x1400, 0x201c, 0x0000 }, + { 0x9500, 0x2021, 0x3000 }, + { 0x9400, 0x201f, 0x2000 }, + { 0x1600, 0x201e, 0x0000 }, + { 0x1500, 0x2020, 0x0000 }, + { 0x9500, 0x2023, 0x2000 }, + { 0x1500, 0x2022, 0x0000 }, + { 0x1500, 0x2024, 0x0000 }, + { 0x9500, 0x2035, 0x5000 }, + { 0x8100, 0x202d, 0x4000 }, + { 0x9c00, 0x2029, 0x3000 }, + { 0x9500, 0x2027, 0x2000 }, + { 0x1500, 0x2026, 0x0000 }, + { 0x1b00, 0x2028, 0x0000 }, + { 0x8100, 0x202b, 0x2000 }, + { 0x0100, 0x202a, 0x0000 }, + { 0x0100, 0x202c, 0x0000 }, + { 0x9500, 0x2031, 0x3000 }, + { 0x9d00, 0x202f, 0x2000 }, + { 0x0100, 0x202e, 0x0000 }, + { 0x1500, 0x2030, 0x0000 }, + { 0x9500, 0x2033, 0x2000 }, + { 0x1500, 0x2032, 0x0000 }, + { 0x1500, 0x2034, 0x0000 }, + { 0x9500, 0x203d, 0x4000 }, + { 0x9400, 0x2039, 0x3000 }, + { 0x9500, 0x2037, 0x2000 }, + { 0x1500, 0x2036, 0x0000 }, + { 0x1500, 0x2038, 0x0000 }, + { 0x9500, 0x203b, 0x2000 }, + { 0x1300, 0x203a, 0x0000 }, + { 0x1500, 0x203c, 0x0000 }, + { 0x9500, 0x2041, 0x3000 }, + { 0x9000, 0x203f, 0x2000 }, + { 0x1500, 0x203e, 0x0000 }, + { 0x1000, 0x2040, 0x0000 }, + { 0x9500, 0x2043, 0x2000 }, + { 0x1500, 0x2042, 0x0000 }, + { 0x1900, 0x2044, 0x0000 }, + { 0x9900, 0x21ae, 0x9000 }, + { 0x8900, 0x211a, 0x8000 }, + { 0x9700, 0x20a7, 0x7000 }, + { 0x8f00, 0x2076, 0x6000 }, + { 0x9500, 0x2057, 0x5000 }, + { 0x9500, 0x204d, 0x4000 }, + { 0x9500, 0x2049, 0x3000 }, + { 0x9500, 0x2047, 0x2000 }, + { 0x1200, 0x2046, 0x0000 }, + { 0x1500, 0x2048, 0x0000 }, + { 0x9500, 0x204b, 0x2000 }, + { 0x1500, 0x204a, 0x0000 }, + { 0x1500, 0x204c, 0x0000 }, + { 0x9500, 0x2051, 0x3000 }, + { 0x9500, 0x204f, 0x2000 }, + { 0x1500, 0x204e, 0x0000 }, + { 0x1500, 0x2050, 0x0000 }, + { 0x9500, 0x2053, 0x2000 }, + { 0x1900, 0x2052, 0x0000 }, + { 0x1000, 0x2054, 0x0000 }, + { 0x8100, 0x206c, 0x4000 }, + { 0x8100, 0x2062, 0x3000 }, + { 0x8100, 0x2060, 0x2000 }, + { 0x1d00, 0x205f, 0x0000 }, + { 0x0100, 0x2061, 0x0000 }, + { 0x8100, 0x206a, 0x2000 }, + { 0x0100, 0x2063, 0x0000 }, + { 0x0100, 0x206b, 0x0000 }, + { 0x8f00, 0x2070, 0x3000 }, + { 0x8100, 0x206e, 0x2000 }, + { 0x0100, 0x206d, 0x0000 }, + { 0x0100, 0x206f, 0x0000 }, + { 0x8f00, 0x2074, 0x2000 }, + { 0x0500, 0x2071, 0x0000 }, + { 0x0f00, 0x2075, 0x0000 }, + { 0x8f00, 0x2086, 0x5000 }, + { 0x9200, 0x207e, 0x4000 }, + { 0x9900, 0x207a, 0x3000 }, + { 0x8f00, 0x2078, 0x2000 }, + { 0x0f00, 0x2077, 0x0000 }, + { 0x0f00, 0x2079, 0x0000 }, + { 0x9900, 0x207c, 0x2000 }, + { 0x1900, 0x207b, 0x0000 }, + { 0x1600, 0x207d, 0x0000 }, + { 0x8f00, 0x2082, 0x3000 }, + { 0x8f00, 0x2080, 0x2000 }, + { 0x0500, 0x207f, 0x0000 }, + { 0x0f00, 0x2081, 0x0000 }, + { 0x8f00, 0x2084, 0x2000 }, + { 0x0f00, 0x2083, 0x0000 }, + { 0x0f00, 0x2085, 0x0000 }, + { 0x9200, 0x208e, 0x4000 }, + { 0x9900, 0x208a, 0x3000 }, + { 0x8f00, 0x2088, 0x2000 }, + { 0x0f00, 0x2087, 0x0000 }, + { 0x0f00, 0x2089, 0x0000 }, + { 0x9900, 0x208c, 0x2000 }, + { 0x1900, 0x208b, 0x0000 }, + { 0x1600, 0x208d, 0x0000 }, + { 0x9700, 0x20a3, 0x3000 }, + { 0x9700, 0x20a1, 0x2000 }, + { 0x1700, 0x20a0, 0x0000 }, + { 0x1700, 0x20a2, 0x0000 }, + { 0x9700, 0x20a5, 0x2000 }, + { 0x1700, 0x20a4, 0x0000 }, + { 0x1700, 0x20a6, 0x0000 }, + { 0x8c00, 0x20e5, 0x6000 }, + { 0x8c00, 0x20d5, 0x5000 }, + { 0x9700, 0x20af, 0x4000 }, + { 0x9700, 0x20ab, 0x3000 }, + { 0x9700, 0x20a9, 0x2000 }, + { 0x1700, 0x20a8, 0x0000 }, + { 0x1700, 0x20aa, 0x0000 }, + { 0x9700, 0x20ad, 0x2000 }, + { 0x1700, 0x20ac, 0x0000 }, + { 0x1700, 0x20ae, 0x0000 }, + { 0x8c00, 0x20d1, 0x3000 }, + { 0x9700, 0x20b1, 0x2000 }, + { 0x1700, 0x20b0, 0x0000 }, + { 0x0c00, 0x20d0, 0x0000 }, + { 0x8c00, 0x20d3, 0x2000 }, + { 0x0c00, 0x20d2, 0x0000 }, + { 0x0c00, 0x20d4, 0x0000 }, + { 0x8b00, 0x20dd, 0x4000 }, + { 0x8c00, 0x20d9, 0x3000 }, + { 0x8c00, 0x20d7, 0x2000 }, + { 0x0c00, 0x20d6, 0x0000 }, + { 0x0c00, 0x20d8, 0x0000 }, + { 0x8c00, 0x20db, 0x2000 }, + { 0x0c00, 0x20da, 0x0000 }, + { 0x0c00, 0x20dc, 0x0000 }, + { 0x8c00, 0x20e1, 0x3000 }, + { 0x8b00, 0x20df, 0x2000 }, + { 0x0b00, 0x20de, 0x0000 }, + { 0x0b00, 0x20e0, 0x0000 }, + { 0x8b00, 0x20e3, 0x2000 }, + { 0x0b00, 0x20e2, 0x0000 }, + { 0x0b00, 0x20e4, 0x0000 }, + { 0x8500, 0x210a, 0x5000 }, + { 0x8900, 0x2102, 0x4000 }, + { 0x8c00, 0x20e9, 0x3000 }, + { 0x8c00, 0x20e7, 0x2000 }, + { 0x0c00, 0x20e6, 0x0000 }, + { 0x0c00, 0x20e8, 0x0000 }, + { 0x9a00, 0x2100, 0x2000 }, + { 0x0c00, 0x20ea, 0x0000 }, + { 0x1a00, 0x2101, 0x0000 }, + { 0x9a00, 0x2106, 0x3000 }, + { 0x9a00, 0x2104, 0x2000 }, + { 0x1a00, 0x2103, 0x0000 }, + { 0x1a00, 0x2105, 0x0000 }, + { 0x9a00, 0x2108, 0x2000 }, + { 0x0900, 0x2107, 0x0000 }, + { 0x1a00, 0x2109, 0x0000 }, + { 0x8900, 0x2112, 0x4000 }, + { 0x8500, 0x210e, 0x3000 }, + { 0x8900, 0x210c, 0x2000 }, + { 0x0900, 0x210b, 0x0000 }, + { 0x0900, 0x210d, 0x0000 }, + { 0x8900, 0x2110, 0x2000 }, + { 0x0500, 0x210f, 0x0000 }, + { 0x0900, 0x2111, 0x0000 }, + { 0x9a00, 0x2116, 0x3000 }, + { 0x9a00, 0x2114, 0x2000 }, + { 0x0500, 0x2113, 0x0000 }, + { 0x0900, 0x2115, 0x0000 }, + { 0x9a00, 0x2118, 0x2000 }, + { 0x1a00, 0x2117, 0x0000 }, + { 0x0900, 0x2119, 0x0000 }, + { 0x8e00, 0x2162, 0x7000 }, + { 0x9a00, 0x213a, 0x6000 }, + { 0x8900, 0x212a, 0x5000 }, + { 0x9a00, 0x2122, 0x4000 }, + { 0x9a00, 0x211e, 0x3000 }, + { 0x8900, 0x211c, 0x2000 }, + { 0x0900, 0x211b, 0x0000 }, + { 0x0900, 0x211d, 0x0000 }, + { 0x9a00, 0x2120, 0x2000 }, + { 0x1a00, 0x211f, 0x0000 }, + { 0x1a00, 0x2121, 0x0000 }, + { 0x8900, 0x2126, 0x3000 }, + { 0x8900, 0x2124, 0x2000 }, + { 0x1a00, 0x2123, 0x0000 }, + { 0x1a00, 0x2125, 0x0000 }, + { 0x8900, 0x2128, 0x2000 }, + { 0x1a00, 0x2127, 0x0000 }, + { 0x1a00, 0x2129, 0x0000 }, + { 0x9a00, 0x2132, 0x4000 }, + { 0x9a00, 0x212e, 0x3000 }, + { 0x8900, 0x212c, 0x2000 }, + { 0x0900, 0x212b, 0x0000 }, + { 0x0900, 0x212d, 0x0000 }, + { 0x8900, 0x2130, 0x2000 }, + { 0x0500, 0x212f, 0x0000 }, + { 0x0900, 0x2131, 0x0000 }, + { 0x8700, 0x2136, 0x3000 }, + { 0x8500, 0x2134, 0x2000 }, + { 0x0900, 0x2133, 0x0000 }, + { 0x0700, 0x2135, 0x0000 }, + { 0x8700, 0x2138, 0x2000 }, + { 0x0700, 0x2137, 0x0000 }, + { 0x0500, 0x2139, 0x0000 }, + { 0x9900, 0x214b, 0x5000 }, + { 0x9900, 0x2143, 0x4000 }, + { 0x8900, 0x213f, 0x3000 }, + { 0x8500, 0x213d, 0x2000 }, + { 0x1a00, 0x213b, 0x0000 }, + { 0x0900, 0x213e, 0x0000 }, + { 0x9900, 0x2141, 0x2000 }, + { 0x1900, 0x2140, 0x0000 }, + { 0x1900, 0x2142, 0x0000 }, + { 0x8500, 0x2147, 0x3000 }, + { 0x8900, 0x2145, 0x2000 }, + { 0x1900, 0x2144, 0x0000 }, + { 0x0500, 0x2146, 0x0000 }, + { 0x8500, 0x2149, 0x2000 }, + { 0x0500, 0x2148, 0x0000 }, + { 0x1a00, 0x214a, 0x0000 }, + { 0x8f00, 0x215a, 0x4000 }, + { 0x8f00, 0x2156, 0x3000 }, + { 0x8f00, 0x2154, 0x2000 }, + { 0x0f00, 0x2153, 0x0000 }, + { 0x0f00, 0x2155, 0x0000 }, + { 0x8f00, 0x2158, 0x2000 }, + { 0x0f00, 0x2157, 0x0000 }, + { 0x0f00, 0x2159, 0x0000 }, + { 0x8f00, 0x215e, 0x3000 }, + { 0x8f00, 0x215c, 0x2000 }, + { 0x0f00, 0x215b, 0x0000 }, + { 0x0f00, 0x215d, 0x0000 }, + { 0x8e00, 0x2160, 0x2000 }, + { 0x0f00, 0x215f, 0x0000 }, + { 0x0e00, 0x2161, 0x0000 }, + { 0x8e00, 0x2182, 0x6000 }, + { 0x8e00, 0x2172, 0x5000 }, + { 0x8e00, 0x216a, 0x4000 }, + { 0x8e00, 0x2166, 0x3000 }, + { 0x8e00, 0x2164, 0x2000 }, + { 0x0e00, 0x2163, 0x0000 }, + { 0x0e00, 0x2165, 0x0000 }, + { 0x8e00, 0x2168, 0x2000 }, + { 0x0e00, 0x2167, 0x0000 }, + { 0x0e00, 0x2169, 0x0000 }, + { 0x8e00, 0x216e, 0x3000 }, + { 0x8e00, 0x216c, 0x2000 }, + { 0x0e00, 0x216b, 0x0000 }, + { 0x0e00, 0x216d, 0x0000 }, + { 0x8e00, 0x2170, 0x2000 }, + { 0x0e00, 0x216f, 0x0000 }, + { 0x0e00, 0x2171, 0x0000 }, + { 0x8e00, 0x217a, 0x4000 }, + { 0x8e00, 0x2176, 0x3000 }, + { 0x8e00, 0x2174, 0x2000 }, + { 0x0e00, 0x2173, 0x0000 }, + { 0x0e00, 0x2175, 0x0000 }, + { 0x8e00, 0x2178, 0x2000 }, + { 0x0e00, 0x2177, 0x0000 }, + { 0x0e00, 0x2179, 0x0000 }, + { 0x8e00, 0x217e, 0x3000 }, + { 0x8e00, 0x217c, 0x2000 }, + { 0x0e00, 0x217b, 0x0000 }, + { 0x0e00, 0x217d, 0x0000 }, + { 0x8e00, 0x2180, 0x2000 }, + { 0x0e00, 0x217f, 0x0000 }, + { 0x0e00, 0x2181, 0x0000 }, + { 0x9a00, 0x219e, 0x5000 }, + { 0x9a00, 0x2196, 0x4000 }, + { 0x9900, 0x2192, 0x3000 }, + { 0x9900, 0x2190, 0x2000 }, + { 0x0e00, 0x2183, 0x0000 }, + { 0x1900, 0x2191, 0x0000 }, + { 0x9900, 0x2194, 0x2000 }, + { 0x1900, 0x2193, 0x0000 }, + { 0x1a00, 0x2195, 0x0000 }, + { 0x9900, 0x219a, 0x3000 }, + { 0x9a00, 0x2198, 0x2000 }, + { 0x1a00, 0x2197, 0x0000 }, + { 0x1a00, 0x2199, 0x0000 }, + { 0x9a00, 0x219c, 0x2000 }, + { 0x1900, 0x219b, 0x0000 }, + { 0x1a00, 0x219d, 0x0000 }, + { 0x9900, 0x21a6, 0x4000 }, + { 0x9a00, 0x21a2, 0x3000 }, + { 0x9900, 0x21a0, 0x2000 }, + { 0x1a00, 0x219f, 0x0000 }, + { 0x1a00, 0x21a1, 0x0000 }, + { 0x9a00, 0x21a4, 0x2000 }, + { 0x1900, 0x21a3, 0x0000 }, + { 0x1a00, 0x21a5, 0x0000 }, + { 0x9a00, 0x21aa, 0x3000 }, + { 0x9a00, 0x21a8, 0x2000 }, + { 0x1a00, 0x21a7, 0x0000 }, + { 0x1a00, 0x21a9, 0x0000 }, + { 0x9a00, 0x21ac, 0x2000 }, + { 0x1a00, 0x21ab, 0x0000 }, + { 0x1a00, 0x21ad, 0x0000 }, + { 0x9900, 0x222e, 0x8000 }, + { 0x9a00, 0x21ee, 0x7000 }, + { 0x9900, 0x21ce, 0x6000 }, + { 0x9a00, 0x21be, 0x5000 }, + { 0x9a00, 0x21b6, 0x4000 }, + { 0x9a00, 0x21b2, 0x3000 }, + { 0x9a00, 0x21b0, 0x2000 }, + { 0x1a00, 0x21af, 0x0000 }, + { 0x1a00, 0x21b1, 0x0000 }, + { 0x9a00, 0x21b4, 0x2000 }, + { 0x1a00, 0x21b3, 0x0000 }, + { 0x1a00, 0x21b5, 0x0000 }, + { 0x9a00, 0x21ba, 0x3000 }, + { 0x9a00, 0x21b8, 0x2000 }, + { 0x1a00, 0x21b7, 0x0000 }, + { 0x1a00, 0x21b9, 0x0000 }, + { 0x9a00, 0x21bc, 0x2000 }, + { 0x1a00, 0x21bb, 0x0000 }, + { 0x1a00, 0x21bd, 0x0000 }, + { 0x9a00, 0x21c6, 0x4000 }, + { 0x9a00, 0x21c2, 0x3000 }, + { 0x9a00, 0x21c0, 0x2000 }, + { 0x1a00, 0x21bf, 0x0000 }, + { 0x1a00, 0x21c1, 0x0000 }, + { 0x9a00, 0x21c4, 0x2000 }, + { 0x1a00, 0x21c3, 0x0000 }, + { 0x1a00, 0x21c5, 0x0000 }, + { 0x9a00, 0x21ca, 0x3000 }, + { 0x9a00, 0x21c8, 0x2000 }, + { 0x1a00, 0x21c7, 0x0000 }, + { 0x1a00, 0x21c9, 0x0000 }, + { 0x9a00, 0x21cc, 0x2000 }, + { 0x1a00, 0x21cb, 0x0000 }, + { 0x1a00, 0x21cd, 0x0000 }, + { 0x9a00, 0x21de, 0x5000 }, + { 0x9a00, 0x21d6, 0x4000 }, + { 0x9900, 0x21d2, 0x3000 }, + { 0x9a00, 0x21d0, 0x2000 }, + { 0x1900, 0x21cf, 0x0000 }, + { 0x1a00, 0x21d1, 0x0000 }, + { 0x9900, 0x21d4, 0x2000 }, + { 0x1a00, 0x21d3, 0x0000 }, + { 0x1a00, 0x21d5, 0x0000 }, + { 0x9a00, 0x21da, 0x3000 }, + { 0x9a00, 0x21d8, 0x2000 }, + { 0x1a00, 0x21d7, 0x0000 }, + { 0x1a00, 0x21d9, 0x0000 }, + { 0x9a00, 0x21dc, 0x2000 }, + { 0x1a00, 0x21db, 0x0000 }, + { 0x1a00, 0x21dd, 0x0000 }, + { 0x9a00, 0x21e6, 0x4000 }, + { 0x9a00, 0x21e2, 0x3000 }, + { 0x9a00, 0x21e0, 0x2000 }, + { 0x1a00, 0x21df, 0x0000 }, + { 0x1a00, 0x21e1, 0x0000 }, + { 0x9a00, 0x21e4, 0x2000 }, + { 0x1a00, 0x21e3, 0x0000 }, + { 0x1a00, 0x21e5, 0x0000 }, + { 0x9a00, 0x21ea, 0x3000 }, + { 0x9a00, 0x21e8, 0x2000 }, + { 0x1a00, 0x21e7, 0x0000 }, + { 0x1a00, 0x21e9, 0x0000 }, + { 0x9a00, 0x21ec, 0x2000 }, + { 0x1a00, 0x21eb, 0x0000 }, + { 0x1a00, 0x21ed, 0x0000 }, + { 0x9900, 0x220e, 0x6000 }, + { 0x9900, 0x21fe, 0x5000 }, + { 0x9900, 0x21f6, 0x4000 }, + { 0x9a00, 0x21f2, 0x3000 }, + { 0x9a00, 0x21f0, 0x2000 }, + { 0x1a00, 0x21ef, 0x0000 }, + { 0x1a00, 0x21f1, 0x0000 }, + { 0x9900, 0x21f4, 0x2000 }, + { 0x1a00, 0x21f3, 0x0000 }, + { 0x1900, 0x21f5, 0x0000 }, + { 0x9900, 0x21fa, 0x3000 }, + { 0x9900, 0x21f8, 0x2000 }, + { 0x1900, 0x21f7, 0x0000 }, + { 0x1900, 0x21f9, 0x0000 }, + { 0x9900, 0x21fc, 0x2000 }, + { 0x1900, 0x21fb, 0x0000 }, + { 0x1900, 0x21fd, 0x0000 }, + { 0x9900, 0x2206, 0x4000 }, + { 0x9900, 0x2202, 0x3000 }, + { 0x9900, 0x2200, 0x2000 }, + { 0x1900, 0x21ff, 0x0000 }, + { 0x1900, 0x2201, 0x0000 }, + { 0x9900, 0x2204, 0x2000 }, + { 0x1900, 0x2203, 0x0000 }, + { 0x1900, 0x2205, 0x0000 }, + { 0x9900, 0x220a, 0x3000 }, + { 0x9900, 0x2208, 0x2000 }, + { 0x1900, 0x2207, 0x0000 }, + { 0x1900, 0x2209, 0x0000 }, + { 0x9900, 0x220c, 0x2000 }, + { 0x1900, 0x220b, 0x0000 }, + { 0x1900, 0x220d, 0x0000 }, + { 0x9900, 0x221e, 0x5000 }, + { 0x9900, 0x2216, 0x4000 }, + { 0x9900, 0x2212, 0x3000 }, + { 0x9900, 0x2210, 0x2000 }, + { 0x1900, 0x220f, 0x0000 }, + { 0x1900, 0x2211, 0x0000 }, + { 0x9900, 0x2214, 0x2000 }, + { 0x1900, 0x2213, 0x0000 }, + { 0x1900, 0x2215, 0x0000 }, + { 0x9900, 0x221a, 0x3000 }, + { 0x9900, 0x2218, 0x2000 }, + { 0x1900, 0x2217, 0x0000 }, + { 0x1900, 0x2219, 0x0000 }, + { 0x9900, 0x221c, 0x2000 }, + { 0x1900, 0x221b, 0x0000 }, + { 0x1900, 0x221d, 0x0000 }, + { 0x9900, 0x2226, 0x4000 }, + { 0x9900, 0x2222, 0x3000 }, + { 0x9900, 0x2220, 0x2000 }, + { 0x1900, 0x221f, 0x0000 }, + { 0x1900, 0x2221, 0x0000 }, + { 0x9900, 0x2224, 0x2000 }, + { 0x1900, 0x2223, 0x0000 }, + { 0x1900, 0x2225, 0x0000 }, + { 0x9900, 0x222a, 0x3000 }, + { 0x9900, 0x2228, 0x2000 }, + { 0x1900, 0x2227, 0x0000 }, + { 0x1900, 0x2229, 0x0000 }, + { 0x9900, 0x222c, 0x2000 }, + { 0x1900, 0x222b, 0x0000 }, + { 0x1900, 0x222d, 0x0000 }, + { 0x9900, 0x226e, 0x7000 }, + { 0x9900, 0x224e, 0x6000 }, + { 0x9900, 0x223e, 0x5000 }, + { 0x9900, 0x2236, 0x4000 }, + { 0x9900, 0x2232, 0x3000 }, + { 0x9900, 0x2230, 0x2000 }, + { 0x1900, 0x222f, 0x0000 }, + { 0x1900, 0x2231, 0x0000 }, + { 0x9900, 0x2234, 0x2000 }, + { 0x1900, 0x2233, 0x0000 }, + { 0x1900, 0x2235, 0x0000 }, + { 0x9900, 0x223a, 0x3000 }, + { 0x9900, 0x2238, 0x2000 }, + { 0x1900, 0x2237, 0x0000 }, + { 0x1900, 0x2239, 0x0000 }, + { 0x9900, 0x223c, 0x2000 }, + { 0x1900, 0x223b, 0x0000 }, + { 0x1900, 0x223d, 0x0000 }, + { 0x9900, 0x2246, 0x4000 }, + { 0x9900, 0x2242, 0x3000 }, + { 0x9900, 0x2240, 0x2000 }, + { 0x1900, 0x223f, 0x0000 }, + { 0x1900, 0x2241, 0x0000 }, + { 0x9900, 0x2244, 0x2000 }, + { 0x1900, 0x2243, 0x0000 }, + { 0x1900, 0x2245, 0x0000 }, + { 0x9900, 0x224a, 0x3000 }, + { 0x9900, 0x2248, 0x2000 }, + { 0x1900, 0x2247, 0x0000 }, + { 0x1900, 0x2249, 0x0000 }, + { 0x9900, 0x224c, 0x2000 }, + { 0x1900, 0x224b, 0x0000 }, + { 0x1900, 0x224d, 0x0000 }, + { 0x9900, 0x225e, 0x5000 }, + { 0x9900, 0x2256, 0x4000 }, + { 0x9900, 0x2252, 0x3000 }, + { 0x9900, 0x2250, 0x2000 }, + { 0x1900, 0x224f, 0x0000 }, + { 0x1900, 0x2251, 0x0000 }, + { 0x9900, 0x2254, 0x2000 }, + { 0x1900, 0x2253, 0x0000 }, + { 0x1900, 0x2255, 0x0000 }, + { 0x9900, 0x225a, 0x3000 }, + { 0x9900, 0x2258, 0x2000 }, + { 0x1900, 0x2257, 0x0000 }, + { 0x1900, 0x2259, 0x0000 }, + { 0x9900, 0x225c, 0x2000 }, + { 0x1900, 0x225b, 0x0000 }, + { 0x1900, 0x225d, 0x0000 }, + { 0x9900, 0x2266, 0x4000 }, + { 0x9900, 0x2262, 0x3000 }, + { 0x9900, 0x2260, 0x2000 }, + { 0x1900, 0x225f, 0x0000 }, + { 0x1900, 0x2261, 0x0000 }, + { 0x9900, 0x2264, 0x2000 }, + { 0x1900, 0x2263, 0x0000 }, + { 0x1900, 0x2265, 0x0000 }, + { 0x9900, 0x226a, 0x3000 }, + { 0x9900, 0x2268, 0x2000 }, + { 0x1900, 0x2267, 0x0000 }, + { 0x1900, 0x2269, 0x0000 }, + { 0x9900, 0x226c, 0x2000 }, + { 0x1900, 0x226b, 0x0000 }, + { 0x1900, 0x226d, 0x0000 }, + { 0x9900, 0x228e, 0x6000 }, + { 0x9900, 0x227e, 0x5000 }, + { 0x9900, 0x2276, 0x4000 }, + { 0x9900, 0x2272, 0x3000 }, + { 0x9900, 0x2270, 0x2000 }, + { 0x1900, 0x226f, 0x0000 }, + { 0x1900, 0x2271, 0x0000 }, + { 0x9900, 0x2274, 0x2000 }, + { 0x1900, 0x2273, 0x0000 }, + { 0x1900, 0x2275, 0x0000 }, + { 0x9900, 0x227a, 0x3000 }, + { 0x9900, 0x2278, 0x2000 }, + { 0x1900, 0x2277, 0x0000 }, + { 0x1900, 0x2279, 0x0000 }, + { 0x9900, 0x227c, 0x2000 }, + { 0x1900, 0x227b, 0x0000 }, + { 0x1900, 0x227d, 0x0000 }, + { 0x9900, 0x2286, 0x4000 }, + { 0x9900, 0x2282, 0x3000 }, + { 0x9900, 0x2280, 0x2000 }, + { 0x1900, 0x227f, 0x0000 }, + { 0x1900, 0x2281, 0x0000 }, + { 0x9900, 0x2284, 0x2000 }, + { 0x1900, 0x2283, 0x0000 }, + { 0x1900, 0x2285, 0x0000 }, + { 0x9900, 0x228a, 0x3000 }, + { 0x9900, 0x2288, 0x2000 }, + { 0x1900, 0x2287, 0x0000 }, + { 0x1900, 0x2289, 0x0000 }, + { 0x9900, 0x228c, 0x2000 }, + { 0x1900, 0x228b, 0x0000 }, + { 0x1900, 0x228d, 0x0000 }, + { 0x9900, 0x229e, 0x5000 }, + { 0x9900, 0x2296, 0x4000 }, + { 0x9900, 0x2292, 0x3000 }, + { 0x9900, 0x2290, 0x2000 }, + { 0x1900, 0x228f, 0x0000 }, + { 0x1900, 0x2291, 0x0000 }, + { 0x9900, 0x2294, 0x2000 }, + { 0x1900, 0x2293, 0x0000 }, + { 0x1900, 0x2295, 0x0000 }, + { 0x9900, 0x229a, 0x3000 }, + { 0x9900, 0x2298, 0x2000 }, + { 0x1900, 0x2297, 0x0000 }, + { 0x1900, 0x2299, 0x0000 }, + { 0x9900, 0x229c, 0x2000 }, + { 0x1900, 0x229b, 0x0000 }, + { 0x1900, 0x229d, 0x0000 }, + { 0x9900, 0x22a6, 0x4000 }, + { 0x9900, 0x22a2, 0x3000 }, + { 0x9900, 0x22a0, 0x2000 }, + { 0x1900, 0x229f, 0x0000 }, + { 0x1900, 0x22a1, 0x0000 }, + { 0x9900, 0x22a4, 0x2000 }, + { 0x1900, 0x22a3, 0x0000 }, + { 0x1900, 0x22a5, 0x0000 }, + { 0x9900, 0x22aa, 0x3000 }, + { 0x9900, 0x22a8, 0x2000 }, + { 0x1900, 0x22a7, 0x0000 }, + { 0x1900, 0x22a9, 0x0000 }, + { 0x9900, 0x22ac, 0x2000 }, + { 0x1900, 0x22ab, 0x0000 }, + { 0x1900, 0x22ad, 0x0000 }, + { 0x8f00, 0x2787, 0xb000 }, + { 0x9a00, 0x250b, 0xa000 }, + { 0x9900, 0x23ae, 0x9000 }, + { 0x9a00, 0x232e, 0x8000 }, + { 0x9900, 0x22ee, 0x7000 }, + { 0x9900, 0x22ce, 0x6000 }, + { 0x9900, 0x22be, 0x5000 }, + { 0x9900, 0x22b6, 0x4000 }, + { 0x9900, 0x22b2, 0x3000 }, + { 0x9900, 0x22b0, 0x2000 }, + { 0x1900, 0x22af, 0x0000 }, + { 0x1900, 0x22b1, 0x0000 }, + { 0x9900, 0x22b4, 0x2000 }, + { 0x1900, 0x22b3, 0x0000 }, + { 0x1900, 0x22b5, 0x0000 }, + { 0x9900, 0x22ba, 0x3000 }, + { 0x9900, 0x22b8, 0x2000 }, + { 0x1900, 0x22b7, 0x0000 }, + { 0x1900, 0x22b9, 0x0000 }, + { 0x9900, 0x22bc, 0x2000 }, + { 0x1900, 0x22bb, 0x0000 }, + { 0x1900, 0x22bd, 0x0000 }, + { 0x9900, 0x22c6, 0x4000 }, + { 0x9900, 0x22c2, 0x3000 }, + { 0x9900, 0x22c0, 0x2000 }, + { 0x1900, 0x22bf, 0x0000 }, + { 0x1900, 0x22c1, 0x0000 }, + { 0x9900, 0x22c4, 0x2000 }, + { 0x1900, 0x22c3, 0x0000 }, + { 0x1900, 0x22c5, 0x0000 }, + { 0x9900, 0x22ca, 0x3000 }, + { 0x9900, 0x22c8, 0x2000 }, + { 0x1900, 0x22c7, 0x0000 }, + { 0x1900, 0x22c9, 0x0000 }, + { 0x9900, 0x22cc, 0x2000 }, + { 0x1900, 0x22cb, 0x0000 }, + { 0x1900, 0x22cd, 0x0000 }, + { 0x9900, 0x22de, 0x5000 }, + { 0x9900, 0x22d6, 0x4000 }, + { 0x9900, 0x22d2, 0x3000 }, + { 0x9900, 0x22d0, 0x2000 }, + { 0x1900, 0x22cf, 0x0000 }, + { 0x1900, 0x22d1, 0x0000 }, + { 0x9900, 0x22d4, 0x2000 }, + { 0x1900, 0x22d3, 0x0000 }, + { 0x1900, 0x22d5, 0x0000 }, + { 0x9900, 0x22da, 0x3000 }, + { 0x9900, 0x22d8, 0x2000 }, + { 0x1900, 0x22d7, 0x0000 }, + { 0x1900, 0x22d9, 0x0000 }, + { 0x9900, 0x22dc, 0x2000 }, + { 0x1900, 0x22db, 0x0000 }, + { 0x1900, 0x22dd, 0x0000 }, + { 0x9900, 0x22e6, 0x4000 }, + { 0x9900, 0x22e2, 0x3000 }, + { 0x9900, 0x22e0, 0x2000 }, + { 0x1900, 0x22df, 0x0000 }, + { 0x1900, 0x22e1, 0x0000 }, + { 0x9900, 0x22e4, 0x2000 }, + { 0x1900, 0x22e3, 0x0000 }, + { 0x1900, 0x22e5, 0x0000 }, + { 0x9900, 0x22ea, 0x3000 }, + { 0x9900, 0x22e8, 0x2000 }, + { 0x1900, 0x22e7, 0x0000 }, + { 0x1900, 0x22e9, 0x0000 }, + { 0x9900, 0x22ec, 0x2000 }, + { 0x1900, 0x22eb, 0x0000 }, + { 0x1900, 0x22ed, 0x0000 }, + { 0x9a00, 0x230e, 0x6000 }, + { 0x9900, 0x22fe, 0x5000 }, + { 0x9900, 0x22f6, 0x4000 }, + { 0x9900, 0x22f2, 0x3000 }, + { 0x9900, 0x22f0, 0x2000 }, + { 0x1900, 0x22ef, 0x0000 }, + { 0x1900, 0x22f1, 0x0000 }, + { 0x9900, 0x22f4, 0x2000 }, + { 0x1900, 0x22f3, 0x0000 }, + { 0x1900, 0x22f5, 0x0000 }, + { 0x9900, 0x22fa, 0x3000 }, + { 0x9900, 0x22f8, 0x2000 }, + { 0x1900, 0x22f7, 0x0000 }, + { 0x1900, 0x22f9, 0x0000 }, + { 0x9900, 0x22fc, 0x2000 }, + { 0x1900, 0x22fb, 0x0000 }, + { 0x1900, 0x22fd, 0x0000 }, + { 0x9a00, 0x2306, 0x4000 }, + { 0x9a00, 0x2302, 0x3000 }, + { 0x9a00, 0x2300, 0x2000 }, + { 0x1900, 0x22ff, 0x0000 }, + { 0x1a00, 0x2301, 0x0000 }, + { 0x9a00, 0x2304, 0x2000 }, + { 0x1a00, 0x2303, 0x0000 }, + { 0x1a00, 0x2305, 0x0000 }, + { 0x9900, 0x230a, 0x3000 }, + { 0x9900, 0x2308, 0x2000 }, + { 0x1a00, 0x2307, 0x0000 }, + { 0x1900, 0x2309, 0x0000 }, + { 0x9a00, 0x230c, 0x2000 }, + { 0x1900, 0x230b, 0x0000 }, + { 0x1a00, 0x230d, 0x0000 }, + { 0x9a00, 0x231e, 0x5000 }, + { 0x9a00, 0x2316, 0x4000 }, + { 0x9a00, 0x2312, 0x3000 }, + { 0x9a00, 0x2310, 0x2000 }, + { 0x1a00, 0x230f, 0x0000 }, + { 0x1a00, 0x2311, 0x0000 }, + { 0x9a00, 0x2314, 0x2000 }, + { 0x1a00, 0x2313, 0x0000 }, + { 0x1a00, 0x2315, 0x0000 }, + { 0x9a00, 0x231a, 0x3000 }, + { 0x9a00, 0x2318, 0x2000 }, + { 0x1a00, 0x2317, 0x0000 }, + { 0x1a00, 0x2319, 0x0000 }, + { 0x9a00, 0x231c, 0x2000 }, + { 0x1a00, 0x231b, 0x0000 }, + { 0x1a00, 0x231d, 0x0000 }, + { 0x9a00, 0x2326, 0x4000 }, + { 0x9a00, 0x2322, 0x3000 }, + { 0x9900, 0x2320, 0x2000 }, + { 0x1a00, 0x231f, 0x0000 }, + { 0x1900, 0x2321, 0x0000 }, + { 0x9a00, 0x2324, 0x2000 }, + { 0x1a00, 0x2323, 0x0000 }, + { 0x1a00, 0x2325, 0x0000 }, + { 0x9200, 0x232a, 0x3000 }, + { 0x9a00, 0x2328, 0x2000 }, + { 0x1a00, 0x2327, 0x0000 }, + { 0x1600, 0x2329, 0x0000 }, + { 0x9a00, 0x232c, 0x2000 }, + { 0x1a00, 0x232b, 0x0000 }, + { 0x1a00, 0x232d, 0x0000 }, + { 0x9a00, 0x236e, 0x7000 }, + { 0x9a00, 0x234e, 0x6000 }, + { 0x9a00, 0x233e, 0x5000 }, + { 0x9a00, 0x2336, 0x4000 }, + { 0x9a00, 0x2332, 0x3000 }, + { 0x9a00, 0x2330, 0x2000 }, + { 0x1a00, 0x232f, 0x0000 }, + { 0x1a00, 0x2331, 0x0000 }, + { 0x9a00, 0x2334, 0x2000 }, + { 0x1a00, 0x2333, 0x0000 }, + { 0x1a00, 0x2335, 0x0000 }, + { 0x9a00, 0x233a, 0x3000 }, + { 0x9a00, 0x2338, 0x2000 }, + { 0x1a00, 0x2337, 0x0000 }, + { 0x1a00, 0x2339, 0x0000 }, + { 0x9a00, 0x233c, 0x2000 }, + { 0x1a00, 0x233b, 0x0000 }, + { 0x1a00, 0x233d, 0x0000 }, + { 0x9a00, 0x2346, 0x4000 }, + { 0x9a00, 0x2342, 0x3000 }, + { 0x9a00, 0x2340, 0x2000 }, + { 0x1a00, 0x233f, 0x0000 }, + { 0x1a00, 0x2341, 0x0000 }, + { 0x9a00, 0x2344, 0x2000 }, + { 0x1a00, 0x2343, 0x0000 }, + { 0x1a00, 0x2345, 0x0000 }, + { 0x9a00, 0x234a, 0x3000 }, + { 0x9a00, 0x2348, 0x2000 }, + { 0x1a00, 0x2347, 0x0000 }, + { 0x1a00, 0x2349, 0x0000 }, + { 0x9a00, 0x234c, 0x2000 }, + { 0x1a00, 0x234b, 0x0000 }, + { 0x1a00, 0x234d, 0x0000 }, + { 0x9a00, 0x235e, 0x5000 }, + { 0x9a00, 0x2356, 0x4000 }, + { 0x9a00, 0x2352, 0x3000 }, + { 0x9a00, 0x2350, 0x2000 }, + { 0x1a00, 0x234f, 0x0000 }, + { 0x1a00, 0x2351, 0x0000 }, + { 0x9a00, 0x2354, 0x2000 }, + { 0x1a00, 0x2353, 0x0000 }, + { 0x1a00, 0x2355, 0x0000 }, + { 0x9a00, 0x235a, 0x3000 }, + { 0x9a00, 0x2358, 0x2000 }, + { 0x1a00, 0x2357, 0x0000 }, + { 0x1a00, 0x2359, 0x0000 }, + { 0x9a00, 0x235c, 0x2000 }, + { 0x1a00, 0x235b, 0x0000 }, + { 0x1a00, 0x235d, 0x0000 }, + { 0x9a00, 0x2366, 0x4000 }, + { 0x9a00, 0x2362, 0x3000 }, + { 0x9a00, 0x2360, 0x2000 }, + { 0x1a00, 0x235f, 0x0000 }, + { 0x1a00, 0x2361, 0x0000 }, + { 0x9a00, 0x2364, 0x2000 }, + { 0x1a00, 0x2363, 0x0000 }, + { 0x1a00, 0x2365, 0x0000 }, + { 0x9a00, 0x236a, 0x3000 }, + { 0x9a00, 0x2368, 0x2000 }, + { 0x1a00, 0x2367, 0x0000 }, + { 0x1a00, 0x2369, 0x0000 }, + { 0x9a00, 0x236c, 0x2000 }, + { 0x1a00, 0x236b, 0x0000 }, + { 0x1a00, 0x236d, 0x0000 }, + { 0x9a00, 0x238e, 0x6000 }, + { 0x9a00, 0x237e, 0x5000 }, + { 0x9a00, 0x2376, 0x4000 }, + { 0x9a00, 0x2372, 0x3000 }, + { 0x9a00, 0x2370, 0x2000 }, + { 0x1a00, 0x236f, 0x0000 }, + { 0x1a00, 0x2371, 0x0000 }, + { 0x9a00, 0x2374, 0x2000 }, + { 0x1a00, 0x2373, 0x0000 }, + { 0x1a00, 0x2375, 0x0000 }, + { 0x9a00, 0x237a, 0x3000 }, + { 0x9a00, 0x2378, 0x2000 }, + { 0x1a00, 0x2377, 0x0000 }, + { 0x1a00, 0x2379, 0x0000 }, + { 0x9900, 0x237c, 0x2000 }, + { 0x1a00, 0x237b, 0x0000 }, + { 0x1a00, 0x237d, 0x0000 }, + { 0x9a00, 0x2386, 0x4000 }, + { 0x9a00, 0x2382, 0x3000 }, + { 0x9a00, 0x2380, 0x2000 }, + { 0x1a00, 0x237f, 0x0000 }, + { 0x1a00, 0x2381, 0x0000 }, + { 0x9a00, 0x2384, 0x2000 }, + { 0x1a00, 0x2383, 0x0000 }, + { 0x1a00, 0x2385, 0x0000 }, + { 0x9a00, 0x238a, 0x3000 }, + { 0x9a00, 0x2388, 0x2000 }, + { 0x1a00, 0x2387, 0x0000 }, + { 0x1a00, 0x2389, 0x0000 }, + { 0x9a00, 0x238c, 0x2000 }, + { 0x1a00, 0x238b, 0x0000 }, + { 0x1a00, 0x238d, 0x0000 }, + { 0x9900, 0x239e, 0x5000 }, + { 0x9a00, 0x2396, 0x4000 }, + { 0x9a00, 0x2392, 0x3000 }, + { 0x9a00, 0x2390, 0x2000 }, + { 0x1a00, 0x238f, 0x0000 }, + { 0x1a00, 0x2391, 0x0000 }, + { 0x9a00, 0x2394, 0x2000 }, + { 0x1a00, 0x2393, 0x0000 }, + { 0x1a00, 0x2395, 0x0000 }, + { 0x9a00, 0x239a, 0x3000 }, + { 0x9a00, 0x2398, 0x2000 }, + { 0x1a00, 0x2397, 0x0000 }, + { 0x1a00, 0x2399, 0x0000 }, + { 0x9900, 0x239c, 0x2000 }, + { 0x1900, 0x239b, 0x0000 }, + { 0x1900, 0x239d, 0x0000 }, + { 0x9900, 0x23a6, 0x4000 }, + { 0x9900, 0x23a2, 0x3000 }, + { 0x9900, 0x23a0, 0x2000 }, + { 0x1900, 0x239f, 0x0000 }, + { 0x1900, 0x23a1, 0x0000 }, + { 0x9900, 0x23a4, 0x2000 }, + { 0x1900, 0x23a3, 0x0000 }, + { 0x1900, 0x23a5, 0x0000 }, + { 0x9900, 0x23aa, 0x3000 }, + { 0x9900, 0x23a8, 0x2000 }, + { 0x1900, 0x23a7, 0x0000 }, + { 0x1900, 0x23a9, 0x0000 }, + { 0x9900, 0x23ac, 0x2000 }, + { 0x1900, 0x23ab, 0x0000 }, + { 0x1900, 0x23ad, 0x0000 }, + { 0x8f00, 0x248b, 0x8000 }, + { 0x9a00, 0x241d, 0x7000 }, + { 0x9a00, 0x23ce, 0x6000 }, + { 0x9a00, 0x23be, 0x5000 }, + { 0x9500, 0x23b6, 0x4000 }, + { 0x9900, 0x23b2, 0x3000 }, + { 0x9900, 0x23b0, 0x2000 }, + { 0x1900, 0x23af, 0x0000 }, + { 0x1900, 0x23b1, 0x0000 }, + { 0x9600, 0x23b4, 0x2000 }, + { 0x1900, 0x23b3, 0x0000 }, + { 0x1200, 0x23b5, 0x0000 }, + { 0x9a00, 0x23ba, 0x3000 }, + { 0x9a00, 0x23b8, 0x2000 }, + { 0x1a00, 0x23b7, 0x0000 }, + { 0x1a00, 0x23b9, 0x0000 }, + { 0x9a00, 0x23bc, 0x2000 }, + { 0x1a00, 0x23bb, 0x0000 }, + { 0x1a00, 0x23bd, 0x0000 }, + { 0x9a00, 0x23c6, 0x4000 }, + { 0x9a00, 0x23c2, 0x3000 }, + { 0x9a00, 0x23c0, 0x2000 }, + { 0x1a00, 0x23bf, 0x0000 }, + { 0x1a00, 0x23c1, 0x0000 }, + { 0x9a00, 0x23c4, 0x2000 }, + { 0x1a00, 0x23c3, 0x0000 }, + { 0x1a00, 0x23c5, 0x0000 }, + { 0x9a00, 0x23ca, 0x3000 }, + { 0x9a00, 0x23c8, 0x2000 }, + { 0x1a00, 0x23c7, 0x0000 }, + { 0x1a00, 0x23c9, 0x0000 }, + { 0x9a00, 0x23cc, 0x2000 }, + { 0x1a00, 0x23cb, 0x0000 }, + { 0x1a00, 0x23cd, 0x0000 }, + { 0x9a00, 0x240d, 0x5000 }, + { 0x9a00, 0x2405, 0x4000 }, + { 0x9a00, 0x2401, 0x3000 }, + { 0x9a00, 0x23d0, 0x2000 }, + { 0x1a00, 0x23cf, 0x0000 }, + { 0x1a00, 0x2400, 0x0000 }, + { 0x9a00, 0x2403, 0x2000 }, + { 0x1a00, 0x2402, 0x0000 }, + { 0x1a00, 0x2404, 0x0000 }, + { 0x9a00, 0x2409, 0x3000 }, + { 0x9a00, 0x2407, 0x2000 }, + { 0x1a00, 0x2406, 0x0000 }, + { 0x1a00, 0x2408, 0x0000 }, + { 0x9a00, 0x240b, 0x2000 }, + { 0x1a00, 0x240a, 0x0000 }, + { 0x1a00, 0x240c, 0x0000 }, + { 0x9a00, 0x2415, 0x4000 }, + { 0x9a00, 0x2411, 0x3000 }, + { 0x9a00, 0x240f, 0x2000 }, + { 0x1a00, 0x240e, 0x0000 }, + { 0x1a00, 0x2410, 0x0000 }, + { 0x9a00, 0x2413, 0x2000 }, + { 0x1a00, 0x2412, 0x0000 }, + { 0x1a00, 0x2414, 0x0000 }, + { 0x9a00, 0x2419, 0x3000 }, + { 0x9a00, 0x2417, 0x2000 }, + { 0x1a00, 0x2416, 0x0000 }, + { 0x1a00, 0x2418, 0x0000 }, + { 0x9a00, 0x241b, 0x2000 }, + { 0x1a00, 0x241a, 0x0000 }, + { 0x1a00, 0x241c, 0x0000 }, + { 0x8f00, 0x246b, 0x6000 }, + { 0x9a00, 0x2446, 0x5000 }, + { 0x9a00, 0x2425, 0x4000 }, + { 0x9a00, 0x2421, 0x3000 }, + { 0x9a00, 0x241f, 0x2000 }, + { 0x1a00, 0x241e, 0x0000 }, + { 0x1a00, 0x2420, 0x0000 }, + { 0x9a00, 0x2423, 0x2000 }, + { 0x1a00, 0x2422, 0x0000 }, + { 0x1a00, 0x2424, 0x0000 }, + { 0x9a00, 0x2442, 0x3000 }, + { 0x9a00, 0x2440, 0x2000 }, + { 0x1a00, 0x2426, 0x0000 }, + { 0x1a00, 0x2441, 0x0000 }, + { 0x9a00, 0x2444, 0x2000 }, + { 0x1a00, 0x2443, 0x0000 }, + { 0x1a00, 0x2445, 0x0000 }, + { 0x8f00, 0x2463, 0x4000 }, + { 0x9a00, 0x244a, 0x3000 }, + { 0x9a00, 0x2448, 0x2000 }, + { 0x1a00, 0x2447, 0x0000 }, + { 0x1a00, 0x2449, 0x0000 }, + { 0x8f00, 0x2461, 0x2000 }, + { 0x0f00, 0x2460, 0x0000 }, + { 0x0f00, 0x2462, 0x0000 }, + { 0x8f00, 0x2467, 0x3000 }, + { 0x8f00, 0x2465, 0x2000 }, + { 0x0f00, 0x2464, 0x0000 }, + { 0x0f00, 0x2466, 0x0000 }, + { 0x8f00, 0x2469, 0x2000 }, + { 0x0f00, 0x2468, 0x0000 }, + { 0x0f00, 0x246a, 0x0000 }, + { 0x8f00, 0x247b, 0x5000 }, + { 0x8f00, 0x2473, 0x4000 }, + { 0x8f00, 0x246f, 0x3000 }, + { 0x8f00, 0x246d, 0x2000 }, + { 0x0f00, 0x246c, 0x0000 }, + { 0x0f00, 0x246e, 0x0000 }, + { 0x8f00, 0x2471, 0x2000 }, + { 0x0f00, 0x2470, 0x0000 }, + { 0x0f00, 0x2472, 0x0000 }, + { 0x8f00, 0x2477, 0x3000 }, + { 0x8f00, 0x2475, 0x2000 }, + { 0x0f00, 0x2474, 0x0000 }, + { 0x0f00, 0x2476, 0x0000 }, + { 0x8f00, 0x2479, 0x2000 }, + { 0x0f00, 0x2478, 0x0000 }, + { 0x0f00, 0x247a, 0x0000 }, + { 0x8f00, 0x2483, 0x4000 }, + { 0x8f00, 0x247f, 0x3000 }, + { 0x8f00, 0x247d, 0x2000 }, + { 0x0f00, 0x247c, 0x0000 }, + { 0x0f00, 0x247e, 0x0000 }, + { 0x8f00, 0x2481, 0x2000 }, + { 0x0f00, 0x2480, 0x0000 }, + { 0x0f00, 0x2482, 0x0000 }, + { 0x8f00, 0x2487, 0x3000 }, + { 0x8f00, 0x2485, 0x2000 }, + { 0x0f00, 0x2484, 0x0000 }, + { 0x0f00, 0x2486, 0x0000 }, + { 0x8f00, 0x2489, 0x2000 }, + { 0x0f00, 0x2488, 0x0000 }, + { 0x0f00, 0x248a, 0x0000 }, + { 0x9a00, 0x24cb, 0x7000 }, + { 0x9a00, 0x24ab, 0x6000 }, + { 0x8f00, 0x249b, 0x5000 }, + { 0x8f00, 0x2493, 0x4000 }, + { 0x8f00, 0x248f, 0x3000 }, + { 0x8f00, 0x248d, 0x2000 }, + { 0x0f00, 0x248c, 0x0000 }, + { 0x0f00, 0x248e, 0x0000 }, + { 0x8f00, 0x2491, 0x2000 }, + { 0x0f00, 0x2490, 0x0000 }, + { 0x0f00, 0x2492, 0x0000 }, + { 0x8f00, 0x2497, 0x3000 }, + { 0x8f00, 0x2495, 0x2000 }, + { 0x0f00, 0x2494, 0x0000 }, + { 0x0f00, 0x2496, 0x0000 }, + { 0x8f00, 0x2499, 0x2000 }, + { 0x0f00, 0x2498, 0x0000 }, + { 0x0f00, 0x249a, 0x0000 }, + { 0x9a00, 0x24a3, 0x4000 }, + { 0x9a00, 0x249f, 0x3000 }, + { 0x9a00, 0x249d, 0x2000 }, + { 0x1a00, 0x249c, 0x0000 }, + { 0x1a00, 0x249e, 0x0000 }, + { 0x9a00, 0x24a1, 0x2000 }, + { 0x1a00, 0x24a0, 0x0000 }, + { 0x1a00, 0x24a2, 0x0000 }, + { 0x9a00, 0x24a7, 0x3000 }, + { 0x9a00, 0x24a5, 0x2000 }, + { 0x1a00, 0x24a4, 0x0000 }, + { 0x1a00, 0x24a6, 0x0000 }, + { 0x9a00, 0x24a9, 0x2000 }, + { 0x1a00, 0x24a8, 0x0000 }, + { 0x1a00, 0x24aa, 0x0000 }, + { 0x9a00, 0x24bb, 0x5000 }, + { 0x9a00, 0x24b3, 0x4000 }, + { 0x9a00, 0x24af, 0x3000 }, + { 0x9a00, 0x24ad, 0x2000 }, + { 0x1a00, 0x24ac, 0x0000 }, + { 0x1a00, 0x24ae, 0x0000 }, + { 0x9a00, 0x24b1, 0x2000 }, + { 0x1a00, 0x24b0, 0x0000 }, + { 0x1a00, 0x24b2, 0x0000 }, + { 0x9a00, 0x24b7, 0x3000 }, + { 0x9a00, 0x24b5, 0x2000 }, + { 0x1a00, 0x24b4, 0x0000 }, + { 0x1a00, 0x24b6, 0x0000 }, + { 0x9a00, 0x24b9, 0x2000 }, + { 0x1a00, 0x24b8, 0x0000 }, + { 0x1a00, 0x24ba, 0x0000 }, + { 0x9a00, 0x24c3, 0x4000 }, + { 0x9a00, 0x24bf, 0x3000 }, + { 0x9a00, 0x24bd, 0x2000 }, + { 0x1a00, 0x24bc, 0x0000 }, + { 0x1a00, 0x24be, 0x0000 }, + { 0x9a00, 0x24c1, 0x2000 }, + { 0x1a00, 0x24c0, 0x0000 }, + { 0x1a00, 0x24c2, 0x0000 }, + { 0x9a00, 0x24c7, 0x3000 }, + { 0x9a00, 0x24c5, 0x2000 }, + { 0x1a00, 0x24c4, 0x0000 }, + { 0x1a00, 0x24c6, 0x0000 }, + { 0x9a00, 0x24c9, 0x2000 }, + { 0x1a00, 0x24c8, 0x0000 }, + { 0x1a00, 0x24ca, 0x0000 }, + { 0x8f00, 0x24eb, 0x6000 }, + { 0x9a00, 0x24db, 0x5000 }, + { 0x9a00, 0x24d3, 0x4000 }, + { 0x9a00, 0x24cf, 0x3000 }, + { 0x9a00, 0x24cd, 0x2000 }, + { 0x1a00, 0x24cc, 0x0000 }, + { 0x1a00, 0x24ce, 0x0000 }, + { 0x9a00, 0x24d1, 0x2000 }, + { 0x1a00, 0x24d0, 0x0000 }, + { 0x1a00, 0x24d2, 0x0000 }, + { 0x9a00, 0x24d7, 0x3000 }, + { 0x9a00, 0x24d5, 0x2000 }, + { 0x1a00, 0x24d4, 0x0000 }, + { 0x1a00, 0x24d6, 0x0000 }, + { 0x9a00, 0x24d9, 0x2000 }, + { 0x1a00, 0x24d8, 0x0000 }, + { 0x1a00, 0x24da, 0x0000 }, + { 0x9a00, 0x24e3, 0x4000 }, + { 0x9a00, 0x24df, 0x3000 }, + { 0x9a00, 0x24dd, 0x2000 }, + { 0x1a00, 0x24dc, 0x0000 }, + { 0x1a00, 0x24de, 0x0000 }, + { 0x9a00, 0x24e1, 0x2000 }, + { 0x1a00, 0x24e0, 0x0000 }, + { 0x1a00, 0x24e2, 0x0000 }, + { 0x9a00, 0x24e7, 0x3000 }, + { 0x9a00, 0x24e5, 0x2000 }, + { 0x1a00, 0x24e4, 0x0000 }, + { 0x1a00, 0x24e6, 0x0000 }, + { 0x9a00, 0x24e9, 0x2000 }, + { 0x1a00, 0x24e8, 0x0000 }, + { 0x0f00, 0x24ea, 0x0000 }, + { 0x8f00, 0x24fb, 0x5000 }, + { 0x8f00, 0x24f3, 0x4000 }, + { 0x8f00, 0x24ef, 0x3000 }, + { 0x8f00, 0x24ed, 0x2000 }, + { 0x0f00, 0x24ec, 0x0000 }, + { 0x0f00, 0x24ee, 0x0000 }, + { 0x8f00, 0x24f1, 0x2000 }, + { 0x0f00, 0x24f0, 0x0000 }, + { 0x0f00, 0x24f2, 0x0000 }, + { 0x8f00, 0x24f7, 0x3000 }, + { 0x8f00, 0x24f5, 0x2000 }, + { 0x0f00, 0x24f4, 0x0000 }, + { 0x0f00, 0x24f6, 0x0000 }, + { 0x8f00, 0x24f9, 0x2000 }, + { 0x0f00, 0x24f8, 0x0000 }, + { 0x0f00, 0x24fa, 0x0000 }, + { 0x9a00, 0x2503, 0x4000 }, + { 0x8f00, 0x24ff, 0x3000 }, + { 0x8f00, 0x24fd, 0x2000 }, + { 0x0f00, 0x24fc, 0x0000 }, + { 0x0f00, 0x24fe, 0x0000 }, + { 0x9a00, 0x2501, 0x2000 }, + { 0x1a00, 0x2500, 0x0000 }, + { 0x1a00, 0x2502, 0x0000 }, + { 0x9a00, 0x2507, 0x3000 }, + { 0x9a00, 0x2505, 0x2000 }, + { 0x1a00, 0x2504, 0x0000 }, + { 0x1a00, 0x2506, 0x0000 }, + { 0x9a00, 0x2509, 0x2000 }, + { 0x1a00, 0x2508, 0x0000 }, + { 0x1a00, 0x250a, 0x0000 }, + { 0x9a00, 0x260b, 0x9000 }, + { 0x9a00, 0x258b, 0x8000 }, + { 0x9a00, 0x254b, 0x7000 }, + { 0x9a00, 0x252b, 0x6000 }, + { 0x9a00, 0x251b, 0x5000 }, + { 0x9a00, 0x2513, 0x4000 }, + { 0x9a00, 0x250f, 0x3000 }, + { 0x9a00, 0x250d, 0x2000 }, + { 0x1a00, 0x250c, 0x0000 }, + { 0x1a00, 0x250e, 0x0000 }, + { 0x9a00, 0x2511, 0x2000 }, + { 0x1a00, 0x2510, 0x0000 }, + { 0x1a00, 0x2512, 0x0000 }, + { 0x9a00, 0x2517, 0x3000 }, + { 0x9a00, 0x2515, 0x2000 }, + { 0x1a00, 0x2514, 0x0000 }, + { 0x1a00, 0x2516, 0x0000 }, + { 0x9a00, 0x2519, 0x2000 }, + { 0x1a00, 0x2518, 0x0000 }, + { 0x1a00, 0x251a, 0x0000 }, + { 0x9a00, 0x2523, 0x4000 }, + { 0x9a00, 0x251f, 0x3000 }, + { 0x9a00, 0x251d, 0x2000 }, + { 0x1a00, 0x251c, 0x0000 }, + { 0x1a00, 0x251e, 0x0000 }, + { 0x9a00, 0x2521, 0x2000 }, + { 0x1a00, 0x2520, 0x0000 }, + { 0x1a00, 0x2522, 0x0000 }, + { 0x9a00, 0x2527, 0x3000 }, + { 0x9a00, 0x2525, 0x2000 }, + { 0x1a00, 0x2524, 0x0000 }, + { 0x1a00, 0x2526, 0x0000 }, + { 0x9a00, 0x2529, 0x2000 }, + { 0x1a00, 0x2528, 0x0000 }, + { 0x1a00, 0x252a, 0x0000 }, + { 0x9a00, 0x253b, 0x5000 }, + { 0x9a00, 0x2533, 0x4000 }, + { 0x9a00, 0x252f, 0x3000 }, + { 0x9a00, 0x252d, 0x2000 }, + { 0x1a00, 0x252c, 0x0000 }, + { 0x1a00, 0x252e, 0x0000 }, + { 0x9a00, 0x2531, 0x2000 }, + { 0x1a00, 0x2530, 0x0000 }, + { 0x1a00, 0x2532, 0x0000 }, + { 0x9a00, 0x2537, 0x3000 }, + { 0x9a00, 0x2535, 0x2000 }, + { 0x1a00, 0x2534, 0x0000 }, + { 0x1a00, 0x2536, 0x0000 }, + { 0x9a00, 0x2539, 0x2000 }, + { 0x1a00, 0x2538, 0x0000 }, + { 0x1a00, 0x253a, 0x0000 }, + { 0x9a00, 0x2543, 0x4000 }, + { 0x9a00, 0x253f, 0x3000 }, + { 0x9a00, 0x253d, 0x2000 }, + { 0x1a00, 0x253c, 0x0000 }, + { 0x1a00, 0x253e, 0x0000 }, + { 0x9a00, 0x2541, 0x2000 }, + { 0x1a00, 0x2540, 0x0000 }, + { 0x1a00, 0x2542, 0x0000 }, + { 0x9a00, 0x2547, 0x3000 }, + { 0x9a00, 0x2545, 0x2000 }, + { 0x1a00, 0x2544, 0x0000 }, + { 0x1a00, 0x2546, 0x0000 }, + { 0x9a00, 0x2549, 0x2000 }, + { 0x1a00, 0x2548, 0x0000 }, + { 0x1a00, 0x254a, 0x0000 }, + { 0x9a00, 0x256b, 0x6000 }, + { 0x9a00, 0x255b, 0x5000 }, + { 0x9a00, 0x2553, 0x4000 }, + { 0x9a00, 0x254f, 0x3000 }, + { 0x9a00, 0x254d, 0x2000 }, + { 0x1a00, 0x254c, 0x0000 }, + { 0x1a00, 0x254e, 0x0000 }, + { 0x9a00, 0x2551, 0x2000 }, + { 0x1a00, 0x2550, 0x0000 }, + { 0x1a00, 0x2552, 0x0000 }, + { 0x9a00, 0x2557, 0x3000 }, + { 0x9a00, 0x2555, 0x2000 }, + { 0x1a00, 0x2554, 0x0000 }, + { 0x1a00, 0x2556, 0x0000 }, + { 0x9a00, 0x2559, 0x2000 }, + { 0x1a00, 0x2558, 0x0000 }, + { 0x1a00, 0x255a, 0x0000 }, + { 0x9a00, 0x2563, 0x4000 }, + { 0x9a00, 0x255f, 0x3000 }, + { 0x9a00, 0x255d, 0x2000 }, + { 0x1a00, 0x255c, 0x0000 }, + { 0x1a00, 0x255e, 0x0000 }, + { 0x9a00, 0x2561, 0x2000 }, + { 0x1a00, 0x2560, 0x0000 }, + { 0x1a00, 0x2562, 0x0000 }, + { 0x9a00, 0x2567, 0x3000 }, + { 0x9a00, 0x2565, 0x2000 }, + { 0x1a00, 0x2564, 0x0000 }, + { 0x1a00, 0x2566, 0x0000 }, + { 0x9a00, 0x2569, 0x2000 }, + { 0x1a00, 0x2568, 0x0000 }, + { 0x1a00, 0x256a, 0x0000 }, + { 0x9a00, 0x257b, 0x5000 }, + { 0x9a00, 0x2573, 0x4000 }, + { 0x9a00, 0x256f, 0x3000 }, + { 0x9a00, 0x256d, 0x2000 }, + { 0x1a00, 0x256c, 0x0000 }, + { 0x1a00, 0x256e, 0x0000 }, + { 0x9a00, 0x2571, 0x2000 }, + { 0x1a00, 0x2570, 0x0000 }, + { 0x1a00, 0x2572, 0x0000 }, + { 0x9a00, 0x2577, 0x3000 }, + { 0x9a00, 0x2575, 0x2000 }, + { 0x1a00, 0x2574, 0x0000 }, + { 0x1a00, 0x2576, 0x0000 }, + { 0x9a00, 0x2579, 0x2000 }, + { 0x1a00, 0x2578, 0x0000 }, + { 0x1a00, 0x257a, 0x0000 }, + { 0x9a00, 0x2583, 0x4000 }, + { 0x9a00, 0x257f, 0x3000 }, + { 0x9a00, 0x257d, 0x2000 }, + { 0x1a00, 0x257c, 0x0000 }, + { 0x1a00, 0x257e, 0x0000 }, + { 0x9a00, 0x2581, 0x2000 }, + { 0x1a00, 0x2580, 0x0000 }, + { 0x1a00, 0x2582, 0x0000 }, + { 0x9a00, 0x2587, 0x3000 }, + { 0x9a00, 0x2585, 0x2000 }, + { 0x1a00, 0x2584, 0x0000 }, + { 0x1a00, 0x2586, 0x0000 }, + { 0x9a00, 0x2589, 0x2000 }, + { 0x1a00, 0x2588, 0x0000 }, + { 0x1a00, 0x258a, 0x0000 }, + { 0x9a00, 0x25cb, 0x7000 }, + { 0x9a00, 0x25ab, 0x6000 }, + { 0x9a00, 0x259b, 0x5000 }, + { 0x9a00, 0x2593, 0x4000 }, + { 0x9a00, 0x258f, 0x3000 }, + { 0x9a00, 0x258d, 0x2000 }, + { 0x1a00, 0x258c, 0x0000 }, + { 0x1a00, 0x258e, 0x0000 }, + { 0x9a00, 0x2591, 0x2000 }, + { 0x1a00, 0x2590, 0x0000 }, + { 0x1a00, 0x2592, 0x0000 }, + { 0x9a00, 0x2597, 0x3000 }, + { 0x9a00, 0x2595, 0x2000 }, + { 0x1a00, 0x2594, 0x0000 }, + { 0x1a00, 0x2596, 0x0000 }, + { 0x9a00, 0x2599, 0x2000 }, + { 0x1a00, 0x2598, 0x0000 }, + { 0x1a00, 0x259a, 0x0000 }, + { 0x9a00, 0x25a3, 0x4000 }, + { 0x9a00, 0x259f, 0x3000 }, + { 0x9a00, 0x259d, 0x2000 }, + { 0x1a00, 0x259c, 0x0000 }, + { 0x1a00, 0x259e, 0x0000 }, + { 0x9a00, 0x25a1, 0x2000 }, + { 0x1a00, 0x25a0, 0x0000 }, + { 0x1a00, 0x25a2, 0x0000 }, + { 0x9a00, 0x25a7, 0x3000 }, + { 0x9a00, 0x25a5, 0x2000 }, + { 0x1a00, 0x25a4, 0x0000 }, + { 0x1a00, 0x25a6, 0x0000 }, + { 0x9a00, 0x25a9, 0x2000 }, + { 0x1a00, 0x25a8, 0x0000 }, + { 0x1a00, 0x25aa, 0x0000 }, + { 0x9a00, 0x25bb, 0x5000 }, + { 0x9a00, 0x25b3, 0x4000 }, + { 0x9a00, 0x25af, 0x3000 }, + { 0x9a00, 0x25ad, 0x2000 }, + { 0x1a00, 0x25ac, 0x0000 }, + { 0x1a00, 0x25ae, 0x0000 }, + { 0x9a00, 0x25b1, 0x2000 }, + { 0x1a00, 0x25b0, 0x0000 }, + { 0x1a00, 0x25b2, 0x0000 }, + { 0x9900, 0x25b7, 0x3000 }, + { 0x9a00, 0x25b5, 0x2000 }, + { 0x1a00, 0x25b4, 0x0000 }, + { 0x1a00, 0x25b6, 0x0000 }, + { 0x9a00, 0x25b9, 0x2000 }, + { 0x1a00, 0x25b8, 0x0000 }, + { 0x1a00, 0x25ba, 0x0000 }, + { 0x9a00, 0x25c3, 0x4000 }, + { 0x9a00, 0x25bf, 0x3000 }, + { 0x9a00, 0x25bd, 0x2000 }, + { 0x1a00, 0x25bc, 0x0000 }, + { 0x1a00, 0x25be, 0x0000 }, + { 0x9900, 0x25c1, 0x2000 }, + { 0x1a00, 0x25c0, 0x0000 }, + { 0x1a00, 0x25c2, 0x0000 }, + { 0x9a00, 0x25c7, 0x3000 }, + { 0x9a00, 0x25c5, 0x2000 }, + { 0x1a00, 0x25c4, 0x0000 }, + { 0x1a00, 0x25c6, 0x0000 }, + { 0x9a00, 0x25c9, 0x2000 }, + { 0x1a00, 0x25c8, 0x0000 }, + { 0x1a00, 0x25ca, 0x0000 }, + { 0x9a00, 0x25eb, 0x6000 }, + { 0x9a00, 0x25db, 0x5000 }, + { 0x9a00, 0x25d3, 0x4000 }, + { 0x9a00, 0x25cf, 0x3000 }, + { 0x9a00, 0x25cd, 0x2000 }, + { 0x1a00, 0x25cc, 0x0000 }, + { 0x1a00, 0x25ce, 0x0000 }, + { 0x9a00, 0x25d1, 0x2000 }, + { 0x1a00, 0x25d0, 0x0000 }, + { 0x1a00, 0x25d2, 0x0000 }, + { 0x9a00, 0x25d7, 0x3000 }, + { 0x9a00, 0x25d5, 0x2000 }, + { 0x1a00, 0x25d4, 0x0000 }, + { 0x1a00, 0x25d6, 0x0000 }, + { 0x9a00, 0x25d9, 0x2000 }, + { 0x1a00, 0x25d8, 0x0000 }, + { 0x1a00, 0x25da, 0x0000 }, + { 0x9a00, 0x25e3, 0x4000 }, + { 0x9a00, 0x25df, 0x3000 }, + { 0x9a00, 0x25dd, 0x2000 }, + { 0x1a00, 0x25dc, 0x0000 }, + { 0x1a00, 0x25de, 0x0000 }, + { 0x9a00, 0x25e1, 0x2000 }, + { 0x1a00, 0x25e0, 0x0000 }, + { 0x1a00, 0x25e2, 0x0000 }, + { 0x9a00, 0x25e7, 0x3000 }, + { 0x9a00, 0x25e5, 0x2000 }, + { 0x1a00, 0x25e4, 0x0000 }, + { 0x1a00, 0x25e6, 0x0000 }, + { 0x9a00, 0x25e9, 0x2000 }, + { 0x1a00, 0x25e8, 0x0000 }, + { 0x1a00, 0x25ea, 0x0000 }, + { 0x9900, 0x25fb, 0x5000 }, + { 0x9a00, 0x25f3, 0x4000 }, + { 0x9a00, 0x25ef, 0x3000 }, + { 0x9a00, 0x25ed, 0x2000 }, + { 0x1a00, 0x25ec, 0x0000 }, + { 0x1a00, 0x25ee, 0x0000 }, + { 0x9a00, 0x25f1, 0x2000 }, + { 0x1a00, 0x25f0, 0x0000 }, + { 0x1a00, 0x25f2, 0x0000 }, + { 0x9a00, 0x25f7, 0x3000 }, + { 0x9a00, 0x25f5, 0x2000 }, + { 0x1a00, 0x25f4, 0x0000 }, + { 0x1a00, 0x25f6, 0x0000 }, + { 0x9900, 0x25f9, 0x2000 }, + { 0x1900, 0x25f8, 0x0000 }, + { 0x1900, 0x25fa, 0x0000 }, + { 0x9a00, 0x2603, 0x4000 }, + { 0x9900, 0x25ff, 0x3000 }, + { 0x9900, 0x25fd, 0x2000 }, + { 0x1900, 0x25fc, 0x0000 }, + { 0x1900, 0x25fe, 0x0000 }, + { 0x9a00, 0x2601, 0x2000 }, + { 0x1a00, 0x2600, 0x0000 }, + { 0x1a00, 0x2602, 0x0000 }, + { 0x9a00, 0x2607, 0x3000 }, + { 0x9a00, 0x2605, 0x2000 }, + { 0x1a00, 0x2604, 0x0000 }, + { 0x1a00, 0x2606, 0x0000 }, + { 0x9a00, 0x2609, 0x2000 }, + { 0x1a00, 0x2608, 0x0000 }, + { 0x1a00, 0x260a, 0x0000 }, + { 0x9a00, 0x268e, 0x8000 }, + { 0x9a00, 0x264c, 0x7000 }, + { 0x9a00, 0x262c, 0x6000 }, + { 0x9a00, 0x261c, 0x5000 }, + { 0x9a00, 0x2613, 0x4000 }, + { 0x9a00, 0x260f, 0x3000 }, + { 0x9a00, 0x260d, 0x2000 }, + { 0x1a00, 0x260c, 0x0000 }, + { 0x1a00, 0x260e, 0x0000 }, + { 0x9a00, 0x2611, 0x2000 }, + { 0x1a00, 0x2610, 0x0000 }, + { 0x1a00, 0x2612, 0x0000 }, + { 0x9a00, 0x2617, 0x3000 }, + { 0x9a00, 0x2615, 0x2000 }, + { 0x1a00, 0x2614, 0x0000 }, + { 0x1a00, 0x2616, 0x0000 }, + { 0x9a00, 0x261a, 0x2000 }, + { 0x1a00, 0x2619, 0x0000 }, + { 0x1a00, 0x261b, 0x0000 }, + { 0x9a00, 0x2624, 0x4000 }, + { 0x9a00, 0x2620, 0x3000 }, + { 0x9a00, 0x261e, 0x2000 }, + { 0x1a00, 0x261d, 0x0000 }, + { 0x1a00, 0x261f, 0x0000 }, + { 0x9a00, 0x2622, 0x2000 }, + { 0x1a00, 0x2621, 0x0000 }, + { 0x1a00, 0x2623, 0x0000 }, + { 0x9a00, 0x2628, 0x3000 }, + { 0x9a00, 0x2626, 0x2000 }, + { 0x1a00, 0x2625, 0x0000 }, + { 0x1a00, 0x2627, 0x0000 }, + { 0x9a00, 0x262a, 0x2000 }, + { 0x1a00, 0x2629, 0x0000 }, + { 0x1a00, 0x262b, 0x0000 }, + { 0x9a00, 0x263c, 0x5000 }, + { 0x9a00, 0x2634, 0x4000 }, + { 0x9a00, 0x2630, 0x3000 }, + { 0x9a00, 0x262e, 0x2000 }, + { 0x1a00, 0x262d, 0x0000 }, + { 0x1a00, 0x262f, 0x0000 }, + { 0x9a00, 0x2632, 0x2000 }, + { 0x1a00, 0x2631, 0x0000 }, + { 0x1a00, 0x2633, 0x0000 }, + { 0x9a00, 0x2638, 0x3000 }, + { 0x9a00, 0x2636, 0x2000 }, + { 0x1a00, 0x2635, 0x0000 }, + { 0x1a00, 0x2637, 0x0000 }, + { 0x9a00, 0x263a, 0x2000 }, + { 0x1a00, 0x2639, 0x0000 }, + { 0x1a00, 0x263b, 0x0000 }, + { 0x9a00, 0x2644, 0x4000 }, + { 0x9a00, 0x2640, 0x3000 }, + { 0x9a00, 0x263e, 0x2000 }, + { 0x1a00, 0x263d, 0x0000 }, + { 0x1a00, 0x263f, 0x0000 }, + { 0x9a00, 0x2642, 0x2000 }, + { 0x1a00, 0x2641, 0x0000 }, + { 0x1a00, 0x2643, 0x0000 }, + { 0x9a00, 0x2648, 0x3000 }, + { 0x9a00, 0x2646, 0x2000 }, + { 0x1a00, 0x2645, 0x0000 }, + { 0x1a00, 0x2647, 0x0000 }, + { 0x9a00, 0x264a, 0x2000 }, + { 0x1a00, 0x2649, 0x0000 }, + { 0x1a00, 0x264b, 0x0000 }, + { 0x9a00, 0x266c, 0x6000 }, + { 0x9a00, 0x265c, 0x5000 }, + { 0x9a00, 0x2654, 0x4000 }, + { 0x9a00, 0x2650, 0x3000 }, + { 0x9a00, 0x264e, 0x2000 }, + { 0x1a00, 0x264d, 0x0000 }, + { 0x1a00, 0x264f, 0x0000 }, + { 0x9a00, 0x2652, 0x2000 }, + { 0x1a00, 0x2651, 0x0000 }, + { 0x1a00, 0x2653, 0x0000 }, + { 0x9a00, 0x2658, 0x3000 }, + { 0x9a00, 0x2656, 0x2000 }, + { 0x1a00, 0x2655, 0x0000 }, + { 0x1a00, 0x2657, 0x0000 }, + { 0x9a00, 0x265a, 0x2000 }, + { 0x1a00, 0x2659, 0x0000 }, + { 0x1a00, 0x265b, 0x0000 }, + { 0x9a00, 0x2664, 0x4000 }, + { 0x9a00, 0x2660, 0x3000 }, + { 0x9a00, 0x265e, 0x2000 }, + { 0x1a00, 0x265d, 0x0000 }, + { 0x1a00, 0x265f, 0x0000 }, + { 0x9a00, 0x2662, 0x2000 }, + { 0x1a00, 0x2661, 0x0000 }, + { 0x1a00, 0x2663, 0x0000 }, + { 0x9a00, 0x2668, 0x3000 }, + { 0x9a00, 0x2666, 0x2000 }, + { 0x1a00, 0x2665, 0x0000 }, + { 0x1a00, 0x2667, 0x0000 }, + { 0x9a00, 0x266a, 0x2000 }, + { 0x1a00, 0x2669, 0x0000 }, + { 0x1a00, 0x266b, 0x0000 }, + { 0x9a00, 0x267c, 0x5000 }, + { 0x9a00, 0x2674, 0x4000 }, + { 0x9a00, 0x2670, 0x3000 }, + { 0x9a00, 0x266e, 0x2000 }, + { 0x1a00, 0x266d, 0x0000 }, + { 0x1900, 0x266f, 0x0000 }, + { 0x9a00, 0x2672, 0x2000 }, + { 0x1a00, 0x2671, 0x0000 }, + { 0x1a00, 0x2673, 0x0000 }, + { 0x9a00, 0x2678, 0x3000 }, + { 0x9a00, 0x2676, 0x2000 }, + { 0x1a00, 0x2675, 0x0000 }, + { 0x1a00, 0x2677, 0x0000 }, + { 0x9a00, 0x267a, 0x2000 }, + { 0x1a00, 0x2679, 0x0000 }, + { 0x1a00, 0x267b, 0x0000 }, + { 0x9a00, 0x2686, 0x4000 }, + { 0x9a00, 0x2682, 0x3000 }, + { 0x9a00, 0x2680, 0x2000 }, + { 0x1a00, 0x267d, 0x0000 }, + { 0x1a00, 0x2681, 0x0000 }, + { 0x9a00, 0x2684, 0x2000 }, + { 0x1a00, 0x2683, 0x0000 }, + { 0x1a00, 0x2685, 0x0000 }, + { 0x9a00, 0x268a, 0x3000 }, + { 0x9a00, 0x2688, 0x2000 }, + { 0x1a00, 0x2687, 0x0000 }, + { 0x1a00, 0x2689, 0x0000 }, + { 0x9a00, 0x268c, 0x2000 }, + { 0x1a00, 0x268b, 0x0000 }, + { 0x1a00, 0x268d, 0x0000 }, + { 0x9a00, 0x273f, 0x7000 }, + { 0x9a00, 0x271e, 0x6000 }, + { 0x9a00, 0x270e, 0x5000 }, + { 0x9a00, 0x2703, 0x4000 }, + { 0x9a00, 0x26a0, 0x3000 }, + { 0x9a00, 0x2690, 0x2000 }, + { 0x1a00, 0x268f, 0x0000 }, + { 0x1a00, 0x2691, 0x0000 }, + { 0x9a00, 0x2701, 0x2000 }, + { 0x1a00, 0x26a1, 0x0000 }, + { 0x1a00, 0x2702, 0x0000 }, + { 0x9a00, 0x2708, 0x3000 }, + { 0x9a00, 0x2706, 0x2000 }, + { 0x1a00, 0x2704, 0x0000 }, + { 0x1a00, 0x2707, 0x0000 }, + { 0x9a00, 0x270c, 0x2000 }, + { 0x1a00, 0x2709, 0x0000 }, + { 0x1a00, 0x270d, 0x0000 }, + { 0x9a00, 0x2716, 0x4000 }, + { 0x9a00, 0x2712, 0x3000 }, + { 0x9a00, 0x2710, 0x2000 }, + { 0x1a00, 0x270f, 0x0000 }, + { 0x1a00, 0x2711, 0x0000 }, + { 0x9a00, 0x2714, 0x2000 }, + { 0x1a00, 0x2713, 0x0000 }, + { 0x1a00, 0x2715, 0x0000 }, + { 0x9a00, 0x271a, 0x3000 }, + { 0x9a00, 0x2718, 0x2000 }, + { 0x1a00, 0x2717, 0x0000 }, + { 0x1a00, 0x2719, 0x0000 }, + { 0x9a00, 0x271c, 0x2000 }, + { 0x1a00, 0x271b, 0x0000 }, + { 0x1a00, 0x271d, 0x0000 }, + { 0x9a00, 0x272f, 0x5000 }, + { 0x9a00, 0x2726, 0x4000 }, + { 0x9a00, 0x2722, 0x3000 }, + { 0x9a00, 0x2720, 0x2000 }, + { 0x1a00, 0x271f, 0x0000 }, + { 0x1a00, 0x2721, 0x0000 }, + { 0x9a00, 0x2724, 0x2000 }, + { 0x1a00, 0x2723, 0x0000 }, + { 0x1a00, 0x2725, 0x0000 }, + { 0x9a00, 0x272b, 0x3000 }, + { 0x9a00, 0x2729, 0x2000 }, + { 0x1a00, 0x2727, 0x0000 }, + { 0x1a00, 0x272a, 0x0000 }, + { 0x9a00, 0x272d, 0x2000 }, + { 0x1a00, 0x272c, 0x0000 }, + { 0x1a00, 0x272e, 0x0000 }, + { 0x9a00, 0x2737, 0x4000 }, + { 0x9a00, 0x2733, 0x3000 }, + { 0x9a00, 0x2731, 0x2000 }, + { 0x1a00, 0x2730, 0x0000 }, + { 0x1a00, 0x2732, 0x0000 }, + { 0x9a00, 0x2735, 0x2000 }, + { 0x1a00, 0x2734, 0x0000 }, + { 0x1a00, 0x2736, 0x0000 }, + { 0x9a00, 0x273b, 0x3000 }, + { 0x9a00, 0x2739, 0x2000 }, + { 0x1a00, 0x2738, 0x0000 }, + { 0x1a00, 0x273a, 0x0000 }, + { 0x9a00, 0x273d, 0x2000 }, + { 0x1a00, 0x273c, 0x0000 }, + { 0x1a00, 0x273e, 0x0000 }, + { 0x9a00, 0x2767, 0x6000 }, + { 0x9a00, 0x2751, 0x5000 }, + { 0x9a00, 0x2747, 0x4000 }, + { 0x9a00, 0x2743, 0x3000 }, + { 0x9a00, 0x2741, 0x2000 }, + { 0x1a00, 0x2740, 0x0000 }, + { 0x1a00, 0x2742, 0x0000 }, + { 0x9a00, 0x2745, 0x2000 }, + { 0x1a00, 0x2744, 0x0000 }, + { 0x1a00, 0x2746, 0x0000 }, + { 0x9a00, 0x274b, 0x3000 }, + { 0x9a00, 0x2749, 0x2000 }, + { 0x1a00, 0x2748, 0x0000 }, + { 0x1a00, 0x274a, 0x0000 }, + { 0x9a00, 0x274f, 0x2000 }, + { 0x1a00, 0x274d, 0x0000 }, + { 0x1a00, 0x2750, 0x0000 }, + { 0x9a00, 0x275d, 0x4000 }, + { 0x9a00, 0x2759, 0x3000 }, + { 0x9a00, 0x2756, 0x2000 }, + { 0x1a00, 0x2752, 0x0000 }, + { 0x1a00, 0x2758, 0x0000 }, + { 0x9a00, 0x275b, 0x2000 }, + { 0x1a00, 0x275a, 0x0000 }, + { 0x1a00, 0x275c, 0x0000 }, + { 0x9a00, 0x2763, 0x3000 }, + { 0x9a00, 0x2761, 0x2000 }, + { 0x1a00, 0x275e, 0x0000 }, + { 0x1a00, 0x2762, 0x0000 }, + { 0x9a00, 0x2765, 0x2000 }, + { 0x1a00, 0x2764, 0x0000 }, + { 0x1a00, 0x2766, 0x0000 }, + { 0x8f00, 0x2777, 0x5000 }, + { 0x9200, 0x276f, 0x4000 }, + { 0x9200, 0x276b, 0x3000 }, + { 0x9200, 0x2769, 0x2000 }, + { 0x1600, 0x2768, 0x0000 }, + { 0x1600, 0x276a, 0x0000 }, + { 0x9200, 0x276d, 0x2000 }, + { 0x1600, 0x276c, 0x0000 }, + { 0x1600, 0x276e, 0x0000 }, + { 0x9200, 0x2773, 0x3000 }, + { 0x9200, 0x2771, 0x2000 }, + { 0x1600, 0x2770, 0x0000 }, + { 0x1600, 0x2772, 0x0000 }, + { 0x9200, 0x2775, 0x2000 }, + { 0x1600, 0x2774, 0x0000 }, + { 0x0f00, 0x2776, 0x0000 }, + { 0x8f00, 0x277f, 0x4000 }, + { 0x8f00, 0x277b, 0x3000 }, + { 0x8f00, 0x2779, 0x2000 }, + { 0x0f00, 0x2778, 0x0000 }, + { 0x0f00, 0x277a, 0x0000 }, + { 0x8f00, 0x277d, 0x2000 }, + { 0x0f00, 0x277c, 0x0000 }, + { 0x0f00, 0x277e, 0x0000 }, + { 0x8f00, 0x2783, 0x3000 }, + { 0x8f00, 0x2781, 0x2000 }, + { 0x0f00, 0x2780, 0x0000 }, + { 0x0f00, 0x2782, 0x0000 }, + { 0x8f00, 0x2785, 0x2000 }, + { 0x0f00, 0x2784, 0x0000 }, + { 0x0f00, 0x2786, 0x0000 }, + { 0x9900, 0x29a0, 0xa000 }, + { 0x9a00, 0x28a0, 0x9000 }, + { 0x9a00, 0x2820, 0x8000 }, + { 0x9900, 0x27dc, 0x7000 }, + { 0x9a00, 0x27aa, 0x6000 }, + { 0x9a00, 0x279a, 0x5000 }, + { 0x8f00, 0x278f, 0x4000 }, + { 0x8f00, 0x278b, 0x3000 }, + { 0x8f00, 0x2789, 0x2000 }, + { 0x0f00, 0x2788, 0x0000 }, + { 0x0f00, 0x278a, 0x0000 }, + { 0x8f00, 0x278d, 0x2000 }, + { 0x0f00, 0x278c, 0x0000 }, + { 0x0f00, 0x278e, 0x0000 }, + { 0x8f00, 0x2793, 0x3000 }, + { 0x8f00, 0x2791, 0x2000 }, + { 0x0f00, 0x2790, 0x0000 }, + { 0x0f00, 0x2792, 0x0000 }, + { 0x9a00, 0x2798, 0x2000 }, + { 0x1a00, 0x2794, 0x0000 }, + { 0x1a00, 0x2799, 0x0000 }, + { 0x9a00, 0x27a2, 0x4000 }, + { 0x9a00, 0x279e, 0x3000 }, + { 0x9a00, 0x279c, 0x2000 }, + { 0x1a00, 0x279b, 0x0000 }, + { 0x1a00, 0x279d, 0x0000 }, + { 0x9a00, 0x27a0, 0x2000 }, + { 0x1a00, 0x279f, 0x0000 }, + { 0x1a00, 0x27a1, 0x0000 }, + { 0x9a00, 0x27a6, 0x3000 }, + { 0x9a00, 0x27a4, 0x2000 }, + { 0x1a00, 0x27a3, 0x0000 }, + { 0x1a00, 0x27a5, 0x0000 }, + { 0x9a00, 0x27a8, 0x2000 }, + { 0x1a00, 0x27a7, 0x0000 }, + { 0x1a00, 0x27a9, 0x0000 }, + { 0x9a00, 0x27bb, 0x5000 }, + { 0x9a00, 0x27b3, 0x4000 }, + { 0x9a00, 0x27ae, 0x3000 }, + { 0x9a00, 0x27ac, 0x2000 }, + { 0x1a00, 0x27ab, 0x0000 }, + { 0x1a00, 0x27ad, 0x0000 }, + { 0x9a00, 0x27b1, 0x2000 }, + { 0x1a00, 0x27af, 0x0000 }, + { 0x1a00, 0x27b2, 0x0000 }, + { 0x9a00, 0x27b7, 0x3000 }, + { 0x9a00, 0x27b5, 0x2000 }, + { 0x1a00, 0x27b4, 0x0000 }, + { 0x1a00, 0x27b6, 0x0000 }, + { 0x9a00, 0x27b9, 0x2000 }, + { 0x1a00, 0x27b8, 0x0000 }, + { 0x1a00, 0x27ba, 0x0000 }, + { 0x9900, 0x27d4, 0x4000 }, + { 0x9900, 0x27d0, 0x3000 }, + { 0x9a00, 0x27bd, 0x2000 }, + { 0x1a00, 0x27bc, 0x0000 }, + { 0x1a00, 0x27be, 0x0000 }, + { 0x9900, 0x27d2, 0x2000 }, + { 0x1900, 0x27d1, 0x0000 }, + { 0x1900, 0x27d3, 0x0000 }, + { 0x9900, 0x27d8, 0x3000 }, + { 0x9900, 0x27d6, 0x2000 }, + { 0x1900, 0x27d5, 0x0000 }, + { 0x1900, 0x27d7, 0x0000 }, + { 0x9900, 0x27da, 0x2000 }, + { 0x1900, 0x27d9, 0x0000 }, + { 0x1900, 0x27db, 0x0000 }, + { 0x9a00, 0x2800, 0x6000 }, + { 0x9900, 0x27f0, 0x5000 }, + { 0x9900, 0x27e4, 0x4000 }, + { 0x9900, 0x27e0, 0x3000 }, + { 0x9900, 0x27de, 0x2000 }, + { 0x1900, 0x27dd, 0x0000 }, + { 0x1900, 0x27df, 0x0000 }, + { 0x9900, 0x27e2, 0x2000 }, + { 0x1900, 0x27e1, 0x0000 }, + { 0x1900, 0x27e3, 0x0000 }, + { 0x9600, 0x27e8, 0x3000 }, + { 0x9600, 0x27e6, 0x2000 }, + { 0x1900, 0x27e5, 0x0000 }, + { 0x1200, 0x27e7, 0x0000 }, + { 0x9600, 0x27ea, 0x2000 }, + { 0x1200, 0x27e9, 0x0000 }, + { 0x1200, 0x27eb, 0x0000 }, + { 0x9900, 0x27f8, 0x4000 }, + { 0x9900, 0x27f4, 0x3000 }, + { 0x9900, 0x27f2, 0x2000 }, + { 0x1900, 0x27f1, 0x0000 }, + { 0x1900, 0x27f3, 0x0000 }, + { 0x9900, 0x27f6, 0x2000 }, + { 0x1900, 0x27f5, 0x0000 }, + { 0x1900, 0x27f7, 0x0000 }, + { 0x9900, 0x27fc, 0x3000 }, + { 0x9900, 0x27fa, 0x2000 }, + { 0x1900, 0x27f9, 0x0000 }, + { 0x1900, 0x27fb, 0x0000 }, + { 0x9900, 0x27fe, 0x2000 }, + { 0x1900, 0x27fd, 0x0000 }, + { 0x1900, 0x27ff, 0x0000 }, + { 0x9a00, 0x2810, 0x5000 }, + { 0x9a00, 0x2808, 0x4000 }, + { 0x9a00, 0x2804, 0x3000 }, + { 0x9a00, 0x2802, 0x2000 }, + { 0x1a00, 0x2801, 0x0000 }, + { 0x1a00, 0x2803, 0x0000 }, + { 0x9a00, 0x2806, 0x2000 }, + { 0x1a00, 0x2805, 0x0000 }, + { 0x1a00, 0x2807, 0x0000 }, + { 0x9a00, 0x280c, 0x3000 }, + { 0x9a00, 0x280a, 0x2000 }, + { 0x1a00, 0x2809, 0x0000 }, + { 0x1a00, 0x280b, 0x0000 }, + { 0x9a00, 0x280e, 0x2000 }, + { 0x1a00, 0x280d, 0x0000 }, + { 0x1a00, 0x280f, 0x0000 }, + { 0x9a00, 0x2818, 0x4000 }, + { 0x9a00, 0x2814, 0x3000 }, + { 0x9a00, 0x2812, 0x2000 }, + { 0x1a00, 0x2811, 0x0000 }, + { 0x1a00, 0x2813, 0x0000 }, + { 0x9a00, 0x2816, 0x2000 }, + { 0x1a00, 0x2815, 0x0000 }, + { 0x1a00, 0x2817, 0x0000 }, + { 0x9a00, 0x281c, 0x3000 }, + { 0x9a00, 0x281a, 0x2000 }, + { 0x1a00, 0x2819, 0x0000 }, + { 0x1a00, 0x281b, 0x0000 }, + { 0x9a00, 0x281e, 0x2000 }, + { 0x1a00, 0x281d, 0x0000 }, + { 0x1a00, 0x281f, 0x0000 }, + { 0x9a00, 0x2860, 0x7000 }, + { 0x9a00, 0x2840, 0x6000 }, + { 0x9a00, 0x2830, 0x5000 }, + { 0x9a00, 0x2828, 0x4000 }, + { 0x9a00, 0x2824, 0x3000 }, + { 0x9a00, 0x2822, 0x2000 }, + { 0x1a00, 0x2821, 0x0000 }, + { 0x1a00, 0x2823, 0x0000 }, + { 0x9a00, 0x2826, 0x2000 }, + { 0x1a00, 0x2825, 0x0000 }, + { 0x1a00, 0x2827, 0x0000 }, + { 0x9a00, 0x282c, 0x3000 }, + { 0x9a00, 0x282a, 0x2000 }, + { 0x1a00, 0x2829, 0x0000 }, + { 0x1a00, 0x282b, 0x0000 }, + { 0x9a00, 0x282e, 0x2000 }, + { 0x1a00, 0x282d, 0x0000 }, + { 0x1a00, 0x282f, 0x0000 }, + { 0x9a00, 0x2838, 0x4000 }, + { 0x9a00, 0x2834, 0x3000 }, + { 0x9a00, 0x2832, 0x2000 }, + { 0x1a00, 0x2831, 0x0000 }, + { 0x1a00, 0x2833, 0x0000 }, + { 0x9a00, 0x2836, 0x2000 }, + { 0x1a00, 0x2835, 0x0000 }, + { 0x1a00, 0x2837, 0x0000 }, + { 0x9a00, 0x283c, 0x3000 }, + { 0x9a00, 0x283a, 0x2000 }, + { 0x1a00, 0x2839, 0x0000 }, + { 0x1a00, 0x283b, 0x0000 }, + { 0x9a00, 0x283e, 0x2000 }, + { 0x1a00, 0x283d, 0x0000 }, + { 0x1a00, 0x283f, 0x0000 }, + { 0x9a00, 0x2850, 0x5000 }, + { 0x9a00, 0x2848, 0x4000 }, + { 0x9a00, 0x2844, 0x3000 }, + { 0x9a00, 0x2842, 0x2000 }, + { 0x1a00, 0x2841, 0x0000 }, + { 0x1a00, 0x2843, 0x0000 }, + { 0x9a00, 0x2846, 0x2000 }, + { 0x1a00, 0x2845, 0x0000 }, + { 0x1a00, 0x2847, 0x0000 }, + { 0x9a00, 0x284c, 0x3000 }, + { 0x9a00, 0x284a, 0x2000 }, + { 0x1a00, 0x2849, 0x0000 }, + { 0x1a00, 0x284b, 0x0000 }, + { 0x9a00, 0x284e, 0x2000 }, + { 0x1a00, 0x284d, 0x0000 }, + { 0x1a00, 0x284f, 0x0000 }, + { 0x9a00, 0x2858, 0x4000 }, + { 0x9a00, 0x2854, 0x3000 }, + { 0x9a00, 0x2852, 0x2000 }, + { 0x1a00, 0x2851, 0x0000 }, + { 0x1a00, 0x2853, 0x0000 }, + { 0x9a00, 0x2856, 0x2000 }, + { 0x1a00, 0x2855, 0x0000 }, + { 0x1a00, 0x2857, 0x0000 }, + { 0x9a00, 0x285c, 0x3000 }, + { 0x9a00, 0x285a, 0x2000 }, + { 0x1a00, 0x2859, 0x0000 }, + { 0x1a00, 0x285b, 0x0000 }, + { 0x9a00, 0x285e, 0x2000 }, + { 0x1a00, 0x285d, 0x0000 }, + { 0x1a00, 0x285f, 0x0000 }, + { 0x9a00, 0x2880, 0x6000 }, + { 0x9a00, 0x2870, 0x5000 }, + { 0x9a00, 0x2868, 0x4000 }, + { 0x9a00, 0x2864, 0x3000 }, + { 0x9a00, 0x2862, 0x2000 }, + { 0x1a00, 0x2861, 0x0000 }, + { 0x1a00, 0x2863, 0x0000 }, + { 0x9a00, 0x2866, 0x2000 }, + { 0x1a00, 0x2865, 0x0000 }, + { 0x1a00, 0x2867, 0x0000 }, + { 0x9a00, 0x286c, 0x3000 }, + { 0x9a00, 0x286a, 0x2000 }, + { 0x1a00, 0x2869, 0x0000 }, + { 0x1a00, 0x286b, 0x0000 }, + { 0x9a00, 0x286e, 0x2000 }, + { 0x1a00, 0x286d, 0x0000 }, + { 0x1a00, 0x286f, 0x0000 }, + { 0x9a00, 0x2878, 0x4000 }, + { 0x9a00, 0x2874, 0x3000 }, + { 0x9a00, 0x2872, 0x2000 }, + { 0x1a00, 0x2871, 0x0000 }, + { 0x1a00, 0x2873, 0x0000 }, + { 0x9a00, 0x2876, 0x2000 }, + { 0x1a00, 0x2875, 0x0000 }, + { 0x1a00, 0x2877, 0x0000 }, + { 0x9a00, 0x287c, 0x3000 }, + { 0x9a00, 0x287a, 0x2000 }, + { 0x1a00, 0x2879, 0x0000 }, + { 0x1a00, 0x287b, 0x0000 }, + { 0x9a00, 0x287e, 0x2000 }, + { 0x1a00, 0x287d, 0x0000 }, + { 0x1a00, 0x287f, 0x0000 }, + { 0x9a00, 0x2890, 0x5000 }, + { 0x9a00, 0x2888, 0x4000 }, + { 0x9a00, 0x2884, 0x3000 }, + { 0x9a00, 0x2882, 0x2000 }, + { 0x1a00, 0x2881, 0x0000 }, + { 0x1a00, 0x2883, 0x0000 }, + { 0x9a00, 0x2886, 0x2000 }, + { 0x1a00, 0x2885, 0x0000 }, + { 0x1a00, 0x2887, 0x0000 }, + { 0x9a00, 0x288c, 0x3000 }, + { 0x9a00, 0x288a, 0x2000 }, + { 0x1a00, 0x2889, 0x0000 }, + { 0x1a00, 0x288b, 0x0000 }, + { 0x9a00, 0x288e, 0x2000 }, + { 0x1a00, 0x288d, 0x0000 }, + { 0x1a00, 0x288f, 0x0000 }, + { 0x9a00, 0x2898, 0x4000 }, + { 0x9a00, 0x2894, 0x3000 }, + { 0x9a00, 0x2892, 0x2000 }, + { 0x1a00, 0x2891, 0x0000 }, + { 0x1a00, 0x2893, 0x0000 }, + { 0x9a00, 0x2896, 0x2000 }, + { 0x1a00, 0x2895, 0x0000 }, + { 0x1a00, 0x2897, 0x0000 }, + { 0x9a00, 0x289c, 0x3000 }, + { 0x9a00, 0x289a, 0x2000 }, + { 0x1a00, 0x2899, 0x0000 }, + { 0x1a00, 0x289b, 0x0000 }, + { 0x9a00, 0x289e, 0x2000 }, + { 0x1a00, 0x289d, 0x0000 }, + { 0x1a00, 0x289f, 0x0000 }, + { 0x9900, 0x2920, 0x8000 }, + { 0x9a00, 0x28e0, 0x7000 }, + { 0x9a00, 0x28c0, 0x6000 }, + { 0x9a00, 0x28b0, 0x5000 }, + { 0x9a00, 0x28a8, 0x4000 }, + { 0x9a00, 0x28a4, 0x3000 }, + { 0x9a00, 0x28a2, 0x2000 }, + { 0x1a00, 0x28a1, 0x0000 }, + { 0x1a00, 0x28a3, 0x0000 }, + { 0x9a00, 0x28a6, 0x2000 }, + { 0x1a00, 0x28a5, 0x0000 }, + { 0x1a00, 0x28a7, 0x0000 }, + { 0x9a00, 0x28ac, 0x3000 }, + { 0x9a00, 0x28aa, 0x2000 }, + { 0x1a00, 0x28a9, 0x0000 }, + { 0x1a00, 0x28ab, 0x0000 }, + { 0x9a00, 0x28ae, 0x2000 }, + { 0x1a00, 0x28ad, 0x0000 }, + { 0x1a00, 0x28af, 0x0000 }, + { 0x9a00, 0x28b8, 0x4000 }, + { 0x9a00, 0x28b4, 0x3000 }, + { 0x9a00, 0x28b2, 0x2000 }, + { 0x1a00, 0x28b1, 0x0000 }, + { 0x1a00, 0x28b3, 0x0000 }, + { 0x9a00, 0x28b6, 0x2000 }, + { 0x1a00, 0x28b5, 0x0000 }, + { 0x1a00, 0x28b7, 0x0000 }, + { 0x9a00, 0x28bc, 0x3000 }, + { 0x9a00, 0x28ba, 0x2000 }, + { 0x1a00, 0x28b9, 0x0000 }, + { 0x1a00, 0x28bb, 0x0000 }, + { 0x9a00, 0x28be, 0x2000 }, + { 0x1a00, 0x28bd, 0x0000 }, + { 0x1a00, 0x28bf, 0x0000 }, + { 0x9a00, 0x28d0, 0x5000 }, + { 0x9a00, 0x28c8, 0x4000 }, + { 0x9a00, 0x28c4, 0x3000 }, + { 0x9a00, 0x28c2, 0x2000 }, + { 0x1a00, 0x28c1, 0x0000 }, + { 0x1a00, 0x28c3, 0x0000 }, + { 0x9a00, 0x28c6, 0x2000 }, + { 0x1a00, 0x28c5, 0x0000 }, + { 0x1a00, 0x28c7, 0x0000 }, + { 0x9a00, 0x28cc, 0x3000 }, + { 0x9a00, 0x28ca, 0x2000 }, + { 0x1a00, 0x28c9, 0x0000 }, + { 0x1a00, 0x28cb, 0x0000 }, + { 0x9a00, 0x28ce, 0x2000 }, + { 0x1a00, 0x28cd, 0x0000 }, + { 0x1a00, 0x28cf, 0x0000 }, + { 0x9a00, 0x28d8, 0x4000 }, + { 0x9a00, 0x28d4, 0x3000 }, + { 0x9a00, 0x28d2, 0x2000 }, + { 0x1a00, 0x28d1, 0x0000 }, + { 0x1a00, 0x28d3, 0x0000 }, + { 0x9a00, 0x28d6, 0x2000 }, + { 0x1a00, 0x28d5, 0x0000 }, + { 0x1a00, 0x28d7, 0x0000 }, + { 0x9a00, 0x28dc, 0x3000 }, + { 0x9a00, 0x28da, 0x2000 }, + { 0x1a00, 0x28d9, 0x0000 }, + { 0x1a00, 0x28db, 0x0000 }, + { 0x9a00, 0x28de, 0x2000 }, + { 0x1a00, 0x28dd, 0x0000 }, + { 0x1a00, 0x28df, 0x0000 }, + { 0x9900, 0x2900, 0x6000 }, + { 0x9a00, 0x28f0, 0x5000 }, + { 0x9a00, 0x28e8, 0x4000 }, + { 0x9a00, 0x28e4, 0x3000 }, + { 0x9a00, 0x28e2, 0x2000 }, + { 0x1a00, 0x28e1, 0x0000 }, + { 0x1a00, 0x28e3, 0x0000 }, + { 0x9a00, 0x28e6, 0x2000 }, + { 0x1a00, 0x28e5, 0x0000 }, + { 0x1a00, 0x28e7, 0x0000 }, + { 0x9a00, 0x28ec, 0x3000 }, + { 0x9a00, 0x28ea, 0x2000 }, + { 0x1a00, 0x28e9, 0x0000 }, + { 0x1a00, 0x28eb, 0x0000 }, + { 0x9a00, 0x28ee, 0x2000 }, + { 0x1a00, 0x28ed, 0x0000 }, + { 0x1a00, 0x28ef, 0x0000 }, + { 0x9a00, 0x28f8, 0x4000 }, + { 0x9a00, 0x28f4, 0x3000 }, + { 0x9a00, 0x28f2, 0x2000 }, + { 0x1a00, 0x28f1, 0x0000 }, + { 0x1a00, 0x28f3, 0x0000 }, + { 0x9a00, 0x28f6, 0x2000 }, + { 0x1a00, 0x28f5, 0x0000 }, + { 0x1a00, 0x28f7, 0x0000 }, + { 0x9a00, 0x28fc, 0x3000 }, + { 0x9a00, 0x28fa, 0x2000 }, + { 0x1a00, 0x28f9, 0x0000 }, + { 0x1a00, 0x28fb, 0x0000 }, + { 0x9a00, 0x28fe, 0x2000 }, + { 0x1a00, 0x28fd, 0x0000 }, + { 0x1a00, 0x28ff, 0x0000 }, + { 0x9900, 0x2910, 0x5000 }, + { 0x9900, 0x2908, 0x4000 }, + { 0x9900, 0x2904, 0x3000 }, + { 0x9900, 0x2902, 0x2000 }, + { 0x1900, 0x2901, 0x0000 }, + { 0x1900, 0x2903, 0x0000 }, + { 0x9900, 0x2906, 0x2000 }, + { 0x1900, 0x2905, 0x0000 }, + { 0x1900, 0x2907, 0x0000 }, + { 0x9900, 0x290c, 0x3000 }, + { 0x9900, 0x290a, 0x2000 }, + { 0x1900, 0x2909, 0x0000 }, + { 0x1900, 0x290b, 0x0000 }, + { 0x9900, 0x290e, 0x2000 }, + { 0x1900, 0x290d, 0x0000 }, + { 0x1900, 0x290f, 0x0000 }, + { 0x9900, 0x2918, 0x4000 }, + { 0x9900, 0x2914, 0x3000 }, + { 0x9900, 0x2912, 0x2000 }, + { 0x1900, 0x2911, 0x0000 }, + { 0x1900, 0x2913, 0x0000 }, + { 0x9900, 0x2916, 0x2000 }, + { 0x1900, 0x2915, 0x0000 }, + { 0x1900, 0x2917, 0x0000 }, + { 0x9900, 0x291c, 0x3000 }, + { 0x9900, 0x291a, 0x2000 }, + { 0x1900, 0x2919, 0x0000 }, + { 0x1900, 0x291b, 0x0000 }, + { 0x9900, 0x291e, 0x2000 }, + { 0x1900, 0x291d, 0x0000 }, + { 0x1900, 0x291f, 0x0000 }, + { 0x9900, 0x2960, 0x7000 }, + { 0x9900, 0x2940, 0x6000 }, + { 0x9900, 0x2930, 0x5000 }, + { 0x9900, 0x2928, 0x4000 }, + { 0x9900, 0x2924, 0x3000 }, + { 0x9900, 0x2922, 0x2000 }, + { 0x1900, 0x2921, 0x0000 }, + { 0x1900, 0x2923, 0x0000 }, + { 0x9900, 0x2926, 0x2000 }, + { 0x1900, 0x2925, 0x0000 }, + { 0x1900, 0x2927, 0x0000 }, + { 0x9900, 0x292c, 0x3000 }, + { 0x9900, 0x292a, 0x2000 }, + { 0x1900, 0x2929, 0x0000 }, + { 0x1900, 0x292b, 0x0000 }, + { 0x9900, 0x292e, 0x2000 }, + { 0x1900, 0x292d, 0x0000 }, + { 0x1900, 0x292f, 0x0000 }, + { 0x9900, 0x2938, 0x4000 }, + { 0x9900, 0x2934, 0x3000 }, + { 0x9900, 0x2932, 0x2000 }, + { 0x1900, 0x2931, 0x0000 }, + { 0x1900, 0x2933, 0x0000 }, + { 0x9900, 0x2936, 0x2000 }, + { 0x1900, 0x2935, 0x0000 }, + { 0x1900, 0x2937, 0x0000 }, + { 0x9900, 0x293c, 0x3000 }, + { 0x9900, 0x293a, 0x2000 }, + { 0x1900, 0x2939, 0x0000 }, + { 0x1900, 0x293b, 0x0000 }, + { 0x9900, 0x293e, 0x2000 }, + { 0x1900, 0x293d, 0x0000 }, + { 0x1900, 0x293f, 0x0000 }, + { 0x9900, 0x2950, 0x5000 }, + { 0x9900, 0x2948, 0x4000 }, + { 0x9900, 0x2944, 0x3000 }, + { 0x9900, 0x2942, 0x2000 }, + { 0x1900, 0x2941, 0x0000 }, + { 0x1900, 0x2943, 0x0000 }, + { 0x9900, 0x2946, 0x2000 }, + { 0x1900, 0x2945, 0x0000 }, + { 0x1900, 0x2947, 0x0000 }, + { 0x9900, 0x294c, 0x3000 }, + { 0x9900, 0x294a, 0x2000 }, + { 0x1900, 0x2949, 0x0000 }, + { 0x1900, 0x294b, 0x0000 }, + { 0x9900, 0x294e, 0x2000 }, + { 0x1900, 0x294d, 0x0000 }, + { 0x1900, 0x294f, 0x0000 }, + { 0x9900, 0x2958, 0x4000 }, + { 0x9900, 0x2954, 0x3000 }, + { 0x9900, 0x2952, 0x2000 }, + { 0x1900, 0x2951, 0x0000 }, + { 0x1900, 0x2953, 0x0000 }, + { 0x9900, 0x2956, 0x2000 }, + { 0x1900, 0x2955, 0x0000 }, + { 0x1900, 0x2957, 0x0000 }, + { 0x9900, 0x295c, 0x3000 }, + { 0x9900, 0x295a, 0x2000 }, + { 0x1900, 0x2959, 0x0000 }, + { 0x1900, 0x295b, 0x0000 }, + { 0x9900, 0x295e, 0x2000 }, + { 0x1900, 0x295d, 0x0000 }, + { 0x1900, 0x295f, 0x0000 }, + { 0x9900, 0x2980, 0x6000 }, + { 0x9900, 0x2970, 0x5000 }, + { 0x9900, 0x2968, 0x4000 }, + { 0x9900, 0x2964, 0x3000 }, + { 0x9900, 0x2962, 0x2000 }, + { 0x1900, 0x2961, 0x0000 }, + { 0x1900, 0x2963, 0x0000 }, + { 0x9900, 0x2966, 0x2000 }, + { 0x1900, 0x2965, 0x0000 }, + { 0x1900, 0x2967, 0x0000 }, + { 0x9900, 0x296c, 0x3000 }, + { 0x9900, 0x296a, 0x2000 }, + { 0x1900, 0x2969, 0x0000 }, + { 0x1900, 0x296b, 0x0000 }, + { 0x9900, 0x296e, 0x2000 }, + { 0x1900, 0x296d, 0x0000 }, + { 0x1900, 0x296f, 0x0000 }, + { 0x9900, 0x2978, 0x4000 }, + { 0x9900, 0x2974, 0x3000 }, + { 0x9900, 0x2972, 0x2000 }, + { 0x1900, 0x2971, 0x0000 }, + { 0x1900, 0x2973, 0x0000 }, + { 0x9900, 0x2976, 0x2000 }, + { 0x1900, 0x2975, 0x0000 }, + { 0x1900, 0x2977, 0x0000 }, + { 0x9900, 0x297c, 0x3000 }, + { 0x9900, 0x297a, 0x2000 }, + { 0x1900, 0x2979, 0x0000 }, + { 0x1900, 0x297b, 0x0000 }, + { 0x9900, 0x297e, 0x2000 }, + { 0x1900, 0x297d, 0x0000 }, + { 0x1900, 0x297f, 0x0000 }, + { 0x9200, 0x2990, 0x5000 }, + { 0x9200, 0x2988, 0x4000 }, + { 0x9200, 0x2984, 0x3000 }, + { 0x9900, 0x2982, 0x2000 }, + { 0x1900, 0x2981, 0x0000 }, + { 0x1600, 0x2983, 0x0000 }, + { 0x9200, 0x2986, 0x2000 }, + { 0x1600, 0x2985, 0x0000 }, + { 0x1600, 0x2987, 0x0000 }, + { 0x9200, 0x298c, 0x3000 }, + { 0x9200, 0x298a, 0x2000 }, + { 0x1600, 0x2989, 0x0000 }, + { 0x1600, 0x298b, 0x0000 }, + { 0x9200, 0x298e, 0x2000 }, + { 0x1600, 0x298d, 0x0000 }, + { 0x1600, 0x298f, 0x0000 }, + { 0x9200, 0x2998, 0x4000 }, + { 0x9200, 0x2994, 0x3000 }, + { 0x9200, 0x2992, 0x2000 }, + { 0x1600, 0x2991, 0x0000 }, + { 0x1600, 0x2993, 0x0000 }, + { 0x9200, 0x2996, 0x2000 }, + { 0x1600, 0x2995, 0x0000 }, + { 0x1600, 0x2997, 0x0000 }, + { 0x9900, 0x299c, 0x3000 }, + { 0x9900, 0x299a, 0x2000 }, + { 0x1900, 0x2999, 0x0000 }, + { 0x1900, 0x299b, 0x0000 }, + { 0x9900, 0x299e, 0x2000 }, + { 0x1900, 0x299d, 0x0000 }, + { 0x1900, 0x299f, 0x0000 }, + { 0x9900, 0x2aa0, 0x9000 }, + { 0x9900, 0x2a20, 0x8000 }, + { 0x9900, 0x29e0, 0x7000 }, + { 0x9900, 0x29c0, 0x6000 }, + { 0x9900, 0x29b0, 0x5000 }, + { 0x9900, 0x29a8, 0x4000 }, + { 0x9900, 0x29a4, 0x3000 }, + { 0x9900, 0x29a2, 0x2000 }, + { 0x1900, 0x29a1, 0x0000 }, + { 0x1900, 0x29a3, 0x0000 }, + { 0x9900, 0x29a6, 0x2000 }, + { 0x1900, 0x29a5, 0x0000 }, + { 0x1900, 0x29a7, 0x0000 }, + { 0x9900, 0x29ac, 0x3000 }, + { 0x9900, 0x29aa, 0x2000 }, + { 0x1900, 0x29a9, 0x0000 }, + { 0x1900, 0x29ab, 0x0000 }, + { 0x9900, 0x29ae, 0x2000 }, + { 0x1900, 0x29ad, 0x0000 }, + { 0x1900, 0x29af, 0x0000 }, + { 0x9900, 0x29b8, 0x4000 }, + { 0x9900, 0x29b4, 0x3000 }, + { 0x9900, 0x29b2, 0x2000 }, + { 0x1900, 0x29b1, 0x0000 }, + { 0x1900, 0x29b3, 0x0000 }, + { 0x9900, 0x29b6, 0x2000 }, + { 0x1900, 0x29b5, 0x0000 }, + { 0x1900, 0x29b7, 0x0000 }, + { 0x9900, 0x29bc, 0x3000 }, + { 0x9900, 0x29ba, 0x2000 }, + { 0x1900, 0x29b9, 0x0000 }, + { 0x1900, 0x29bb, 0x0000 }, + { 0x9900, 0x29be, 0x2000 }, + { 0x1900, 0x29bd, 0x0000 }, + { 0x1900, 0x29bf, 0x0000 }, + { 0x9900, 0x29d0, 0x5000 }, + { 0x9900, 0x29c8, 0x4000 }, + { 0x9900, 0x29c4, 0x3000 }, + { 0x9900, 0x29c2, 0x2000 }, + { 0x1900, 0x29c1, 0x0000 }, + { 0x1900, 0x29c3, 0x0000 }, + { 0x9900, 0x29c6, 0x2000 }, + { 0x1900, 0x29c5, 0x0000 }, + { 0x1900, 0x29c7, 0x0000 }, + { 0x9900, 0x29cc, 0x3000 }, + { 0x9900, 0x29ca, 0x2000 }, + { 0x1900, 0x29c9, 0x0000 }, + { 0x1900, 0x29cb, 0x0000 }, + { 0x9900, 0x29ce, 0x2000 }, + { 0x1900, 0x29cd, 0x0000 }, + { 0x1900, 0x29cf, 0x0000 }, + { 0x9600, 0x29d8, 0x4000 }, + { 0x9900, 0x29d4, 0x3000 }, + { 0x9900, 0x29d2, 0x2000 }, + { 0x1900, 0x29d1, 0x0000 }, + { 0x1900, 0x29d3, 0x0000 }, + { 0x9900, 0x29d6, 0x2000 }, + { 0x1900, 0x29d5, 0x0000 }, + { 0x1900, 0x29d7, 0x0000 }, + { 0x9900, 0x29dc, 0x3000 }, + { 0x9600, 0x29da, 0x2000 }, + { 0x1200, 0x29d9, 0x0000 }, + { 0x1200, 0x29db, 0x0000 }, + { 0x9900, 0x29de, 0x2000 }, + { 0x1900, 0x29dd, 0x0000 }, + { 0x1900, 0x29df, 0x0000 }, + { 0x9900, 0x2a00, 0x6000 }, + { 0x9900, 0x29f0, 0x5000 }, + { 0x9900, 0x29e8, 0x4000 }, + { 0x9900, 0x29e4, 0x3000 }, + { 0x9900, 0x29e2, 0x2000 }, + { 0x1900, 0x29e1, 0x0000 }, + { 0x1900, 0x29e3, 0x0000 }, + { 0x9900, 0x29e6, 0x2000 }, + { 0x1900, 0x29e5, 0x0000 }, + { 0x1900, 0x29e7, 0x0000 }, + { 0x9900, 0x29ec, 0x3000 }, + { 0x9900, 0x29ea, 0x2000 }, + { 0x1900, 0x29e9, 0x0000 }, + { 0x1900, 0x29eb, 0x0000 }, + { 0x9900, 0x29ee, 0x2000 }, + { 0x1900, 0x29ed, 0x0000 }, + { 0x1900, 0x29ef, 0x0000 }, + { 0x9900, 0x29f8, 0x4000 }, + { 0x9900, 0x29f4, 0x3000 }, + { 0x9900, 0x29f2, 0x2000 }, + { 0x1900, 0x29f1, 0x0000 }, + { 0x1900, 0x29f3, 0x0000 }, + { 0x9900, 0x29f6, 0x2000 }, + { 0x1900, 0x29f5, 0x0000 }, + { 0x1900, 0x29f7, 0x0000 }, + { 0x9600, 0x29fc, 0x3000 }, + { 0x9900, 0x29fa, 0x2000 }, + { 0x1900, 0x29f9, 0x0000 }, + { 0x1900, 0x29fb, 0x0000 }, + { 0x9900, 0x29fe, 0x2000 }, + { 0x1200, 0x29fd, 0x0000 }, + { 0x1900, 0x29ff, 0x0000 }, + { 0x9900, 0x2a10, 0x5000 }, + { 0x9900, 0x2a08, 0x4000 }, + { 0x9900, 0x2a04, 0x3000 }, + { 0x9900, 0x2a02, 0x2000 }, + { 0x1900, 0x2a01, 0x0000 }, + { 0x1900, 0x2a03, 0x0000 }, + { 0x9900, 0x2a06, 0x2000 }, + { 0x1900, 0x2a05, 0x0000 }, + { 0x1900, 0x2a07, 0x0000 }, + { 0x9900, 0x2a0c, 0x3000 }, + { 0x9900, 0x2a0a, 0x2000 }, + { 0x1900, 0x2a09, 0x0000 }, + { 0x1900, 0x2a0b, 0x0000 }, + { 0x9900, 0x2a0e, 0x2000 }, + { 0x1900, 0x2a0d, 0x0000 }, + { 0x1900, 0x2a0f, 0x0000 }, + { 0x9900, 0x2a18, 0x4000 }, + { 0x9900, 0x2a14, 0x3000 }, + { 0x9900, 0x2a12, 0x2000 }, + { 0x1900, 0x2a11, 0x0000 }, + { 0x1900, 0x2a13, 0x0000 }, + { 0x9900, 0x2a16, 0x2000 }, + { 0x1900, 0x2a15, 0x0000 }, + { 0x1900, 0x2a17, 0x0000 }, + { 0x9900, 0x2a1c, 0x3000 }, + { 0x9900, 0x2a1a, 0x2000 }, + { 0x1900, 0x2a19, 0x0000 }, + { 0x1900, 0x2a1b, 0x0000 }, + { 0x9900, 0x2a1e, 0x2000 }, + { 0x1900, 0x2a1d, 0x0000 }, + { 0x1900, 0x2a1f, 0x0000 }, + { 0x9900, 0x2a60, 0x7000 }, + { 0x9900, 0x2a40, 0x6000 }, + { 0x9900, 0x2a30, 0x5000 }, + { 0x9900, 0x2a28, 0x4000 }, + { 0x9900, 0x2a24, 0x3000 }, + { 0x9900, 0x2a22, 0x2000 }, + { 0x1900, 0x2a21, 0x0000 }, + { 0x1900, 0x2a23, 0x0000 }, + { 0x9900, 0x2a26, 0x2000 }, + { 0x1900, 0x2a25, 0x0000 }, + { 0x1900, 0x2a27, 0x0000 }, + { 0x9900, 0x2a2c, 0x3000 }, + { 0x9900, 0x2a2a, 0x2000 }, + { 0x1900, 0x2a29, 0x0000 }, + { 0x1900, 0x2a2b, 0x0000 }, + { 0x9900, 0x2a2e, 0x2000 }, + { 0x1900, 0x2a2d, 0x0000 }, + { 0x1900, 0x2a2f, 0x0000 }, + { 0x9900, 0x2a38, 0x4000 }, + { 0x9900, 0x2a34, 0x3000 }, + { 0x9900, 0x2a32, 0x2000 }, + { 0x1900, 0x2a31, 0x0000 }, + { 0x1900, 0x2a33, 0x0000 }, + { 0x9900, 0x2a36, 0x2000 }, + { 0x1900, 0x2a35, 0x0000 }, + { 0x1900, 0x2a37, 0x0000 }, + { 0x9900, 0x2a3c, 0x3000 }, + { 0x9900, 0x2a3a, 0x2000 }, + { 0x1900, 0x2a39, 0x0000 }, + { 0x1900, 0x2a3b, 0x0000 }, + { 0x9900, 0x2a3e, 0x2000 }, + { 0x1900, 0x2a3d, 0x0000 }, + { 0x1900, 0x2a3f, 0x0000 }, + { 0x9900, 0x2a50, 0x5000 }, + { 0x9900, 0x2a48, 0x4000 }, + { 0x9900, 0x2a44, 0x3000 }, + { 0x9900, 0x2a42, 0x2000 }, + { 0x1900, 0x2a41, 0x0000 }, + { 0x1900, 0x2a43, 0x0000 }, + { 0x9900, 0x2a46, 0x2000 }, + { 0x1900, 0x2a45, 0x0000 }, + { 0x1900, 0x2a47, 0x0000 }, + { 0x9900, 0x2a4c, 0x3000 }, + { 0x9900, 0x2a4a, 0x2000 }, + { 0x1900, 0x2a49, 0x0000 }, + { 0x1900, 0x2a4b, 0x0000 }, + { 0x9900, 0x2a4e, 0x2000 }, + { 0x1900, 0x2a4d, 0x0000 }, + { 0x1900, 0x2a4f, 0x0000 }, + { 0x9900, 0x2a58, 0x4000 }, + { 0x9900, 0x2a54, 0x3000 }, + { 0x9900, 0x2a52, 0x2000 }, + { 0x1900, 0x2a51, 0x0000 }, + { 0x1900, 0x2a53, 0x0000 }, + { 0x9900, 0x2a56, 0x2000 }, + { 0x1900, 0x2a55, 0x0000 }, + { 0x1900, 0x2a57, 0x0000 }, + { 0x9900, 0x2a5c, 0x3000 }, + { 0x9900, 0x2a5a, 0x2000 }, + { 0x1900, 0x2a59, 0x0000 }, + { 0x1900, 0x2a5b, 0x0000 }, + { 0x9900, 0x2a5e, 0x2000 }, + { 0x1900, 0x2a5d, 0x0000 }, + { 0x1900, 0x2a5f, 0x0000 }, + { 0x9900, 0x2a80, 0x6000 }, + { 0x9900, 0x2a70, 0x5000 }, + { 0x9900, 0x2a68, 0x4000 }, + { 0x9900, 0x2a64, 0x3000 }, + { 0x9900, 0x2a62, 0x2000 }, + { 0x1900, 0x2a61, 0x0000 }, + { 0x1900, 0x2a63, 0x0000 }, + { 0x9900, 0x2a66, 0x2000 }, + { 0x1900, 0x2a65, 0x0000 }, + { 0x1900, 0x2a67, 0x0000 }, + { 0x9900, 0x2a6c, 0x3000 }, + { 0x9900, 0x2a6a, 0x2000 }, + { 0x1900, 0x2a69, 0x0000 }, + { 0x1900, 0x2a6b, 0x0000 }, + { 0x9900, 0x2a6e, 0x2000 }, + { 0x1900, 0x2a6d, 0x0000 }, + { 0x1900, 0x2a6f, 0x0000 }, + { 0x9900, 0x2a78, 0x4000 }, + { 0x9900, 0x2a74, 0x3000 }, + { 0x9900, 0x2a72, 0x2000 }, + { 0x1900, 0x2a71, 0x0000 }, + { 0x1900, 0x2a73, 0x0000 }, + { 0x9900, 0x2a76, 0x2000 }, + { 0x1900, 0x2a75, 0x0000 }, + { 0x1900, 0x2a77, 0x0000 }, + { 0x9900, 0x2a7c, 0x3000 }, + { 0x9900, 0x2a7a, 0x2000 }, + { 0x1900, 0x2a79, 0x0000 }, + { 0x1900, 0x2a7b, 0x0000 }, + { 0x9900, 0x2a7e, 0x2000 }, + { 0x1900, 0x2a7d, 0x0000 }, + { 0x1900, 0x2a7f, 0x0000 }, + { 0x9900, 0x2a90, 0x5000 }, + { 0x9900, 0x2a88, 0x4000 }, + { 0x9900, 0x2a84, 0x3000 }, + { 0x9900, 0x2a82, 0x2000 }, + { 0x1900, 0x2a81, 0x0000 }, + { 0x1900, 0x2a83, 0x0000 }, + { 0x9900, 0x2a86, 0x2000 }, + { 0x1900, 0x2a85, 0x0000 }, + { 0x1900, 0x2a87, 0x0000 }, + { 0x9900, 0x2a8c, 0x3000 }, + { 0x9900, 0x2a8a, 0x2000 }, + { 0x1900, 0x2a89, 0x0000 }, + { 0x1900, 0x2a8b, 0x0000 }, + { 0x9900, 0x2a8e, 0x2000 }, + { 0x1900, 0x2a8d, 0x0000 }, + { 0x1900, 0x2a8f, 0x0000 }, + { 0x9900, 0x2a98, 0x4000 }, + { 0x9900, 0x2a94, 0x3000 }, + { 0x9900, 0x2a92, 0x2000 }, + { 0x1900, 0x2a91, 0x0000 }, + { 0x1900, 0x2a93, 0x0000 }, + { 0x9900, 0x2a96, 0x2000 }, + { 0x1900, 0x2a95, 0x0000 }, + { 0x1900, 0x2a97, 0x0000 }, + { 0x9900, 0x2a9c, 0x3000 }, + { 0x9900, 0x2a9a, 0x2000 }, + { 0x1900, 0x2a99, 0x0000 }, + { 0x1900, 0x2a9b, 0x0000 }, + { 0x9900, 0x2a9e, 0x2000 }, + { 0x1900, 0x2a9d, 0x0000 }, + { 0x1900, 0x2a9f, 0x0000 }, + { 0x9a00, 0x2e92, 0x8000 }, + { 0x9900, 0x2ae0, 0x7000 }, + { 0x9900, 0x2ac0, 0x6000 }, + { 0x9900, 0x2ab0, 0x5000 }, + { 0x9900, 0x2aa8, 0x4000 }, + { 0x9900, 0x2aa4, 0x3000 }, + { 0x9900, 0x2aa2, 0x2000 }, + { 0x1900, 0x2aa1, 0x0000 }, + { 0x1900, 0x2aa3, 0x0000 }, + { 0x9900, 0x2aa6, 0x2000 }, + { 0x1900, 0x2aa5, 0x0000 }, + { 0x1900, 0x2aa7, 0x0000 }, + { 0x9900, 0x2aac, 0x3000 }, + { 0x9900, 0x2aaa, 0x2000 }, + { 0x1900, 0x2aa9, 0x0000 }, + { 0x1900, 0x2aab, 0x0000 }, + { 0x9900, 0x2aae, 0x2000 }, + { 0x1900, 0x2aad, 0x0000 }, + { 0x1900, 0x2aaf, 0x0000 }, + { 0x9900, 0x2ab8, 0x4000 }, + { 0x9900, 0x2ab4, 0x3000 }, + { 0x9900, 0x2ab2, 0x2000 }, + { 0x1900, 0x2ab1, 0x0000 }, + { 0x1900, 0x2ab3, 0x0000 }, + { 0x9900, 0x2ab6, 0x2000 }, + { 0x1900, 0x2ab5, 0x0000 }, + { 0x1900, 0x2ab7, 0x0000 }, + { 0x9900, 0x2abc, 0x3000 }, + { 0x9900, 0x2aba, 0x2000 }, + { 0x1900, 0x2ab9, 0x0000 }, + { 0x1900, 0x2abb, 0x0000 }, + { 0x9900, 0x2abe, 0x2000 }, + { 0x1900, 0x2abd, 0x0000 }, + { 0x1900, 0x2abf, 0x0000 }, + { 0x9900, 0x2ad0, 0x5000 }, + { 0x9900, 0x2ac8, 0x4000 }, + { 0x9900, 0x2ac4, 0x3000 }, + { 0x9900, 0x2ac2, 0x2000 }, + { 0x1900, 0x2ac1, 0x0000 }, + { 0x1900, 0x2ac3, 0x0000 }, + { 0x9900, 0x2ac6, 0x2000 }, + { 0x1900, 0x2ac5, 0x0000 }, + { 0x1900, 0x2ac7, 0x0000 }, + { 0x9900, 0x2acc, 0x3000 }, + { 0x9900, 0x2aca, 0x2000 }, + { 0x1900, 0x2ac9, 0x0000 }, + { 0x1900, 0x2acb, 0x0000 }, + { 0x9900, 0x2ace, 0x2000 }, + { 0x1900, 0x2acd, 0x0000 }, + { 0x1900, 0x2acf, 0x0000 }, + { 0x9900, 0x2ad8, 0x4000 }, + { 0x9900, 0x2ad4, 0x3000 }, + { 0x9900, 0x2ad2, 0x2000 }, + { 0x1900, 0x2ad1, 0x0000 }, + { 0x1900, 0x2ad3, 0x0000 }, + { 0x9900, 0x2ad6, 0x2000 }, + { 0x1900, 0x2ad5, 0x0000 }, + { 0x1900, 0x2ad7, 0x0000 }, + { 0x9900, 0x2adc, 0x3000 }, + { 0x9900, 0x2ada, 0x2000 }, + { 0x1900, 0x2ad9, 0x0000 }, + { 0x1900, 0x2adb, 0x0000 }, + { 0x9900, 0x2ade, 0x2000 }, + { 0x1900, 0x2add, 0x0000 }, + { 0x1900, 0x2adf, 0x0000 }, + { 0x9a00, 0x2b00, 0x6000 }, + { 0x9900, 0x2af0, 0x5000 }, + { 0x9900, 0x2ae8, 0x4000 }, + { 0x9900, 0x2ae4, 0x3000 }, + { 0x9900, 0x2ae2, 0x2000 }, + { 0x1900, 0x2ae1, 0x0000 }, + { 0x1900, 0x2ae3, 0x0000 }, + { 0x9900, 0x2ae6, 0x2000 }, + { 0x1900, 0x2ae5, 0x0000 }, + { 0x1900, 0x2ae7, 0x0000 }, + { 0x9900, 0x2aec, 0x3000 }, + { 0x9900, 0x2aea, 0x2000 }, + { 0x1900, 0x2ae9, 0x0000 }, + { 0x1900, 0x2aeb, 0x0000 }, + { 0x9900, 0x2aee, 0x2000 }, + { 0x1900, 0x2aed, 0x0000 }, + { 0x1900, 0x2aef, 0x0000 }, + { 0x9900, 0x2af8, 0x4000 }, + { 0x9900, 0x2af4, 0x3000 }, + { 0x9900, 0x2af2, 0x2000 }, + { 0x1900, 0x2af1, 0x0000 }, + { 0x1900, 0x2af3, 0x0000 }, + { 0x9900, 0x2af6, 0x2000 }, + { 0x1900, 0x2af5, 0x0000 }, + { 0x1900, 0x2af7, 0x0000 }, + { 0x9900, 0x2afc, 0x3000 }, + { 0x9900, 0x2afa, 0x2000 }, + { 0x1900, 0x2af9, 0x0000 }, + { 0x1900, 0x2afb, 0x0000 }, + { 0x9900, 0x2afe, 0x2000 }, + { 0x1900, 0x2afd, 0x0000 }, + { 0x1900, 0x2aff, 0x0000 }, + { 0x9a00, 0x2e82, 0x5000 }, + { 0x9a00, 0x2b08, 0x4000 }, + { 0x9a00, 0x2b04, 0x3000 }, + { 0x9a00, 0x2b02, 0x2000 }, + { 0x1a00, 0x2b01, 0x0000 }, + { 0x1a00, 0x2b03, 0x0000 }, + { 0x9a00, 0x2b06, 0x2000 }, + { 0x1a00, 0x2b05, 0x0000 }, + { 0x1a00, 0x2b07, 0x0000 }, + { 0x9a00, 0x2b0c, 0x3000 }, + { 0x9a00, 0x2b0a, 0x2000 }, + { 0x1a00, 0x2b09, 0x0000 }, + { 0x1a00, 0x2b0b, 0x0000 }, + { 0x9a00, 0x2e80, 0x2000 }, + { 0x1a00, 0x2b0d, 0x0000 }, + { 0x1a00, 0x2e81, 0x0000 }, + { 0x9a00, 0x2e8a, 0x4000 }, + { 0x9a00, 0x2e86, 0x3000 }, + { 0x9a00, 0x2e84, 0x2000 }, + { 0x1a00, 0x2e83, 0x0000 }, + { 0x1a00, 0x2e85, 0x0000 }, + { 0x9a00, 0x2e88, 0x2000 }, + { 0x1a00, 0x2e87, 0x0000 }, + { 0x1a00, 0x2e89, 0x0000 }, + { 0x9a00, 0x2e8e, 0x3000 }, + { 0x9a00, 0x2e8c, 0x2000 }, + { 0x1a00, 0x2e8b, 0x0000 }, + { 0x1a00, 0x2e8d, 0x0000 }, + { 0x9a00, 0x2e90, 0x2000 }, + { 0x1a00, 0x2e8f, 0x0000 }, + { 0x1a00, 0x2e91, 0x0000 }, + { 0x9a00, 0x2ed3, 0x7000 }, + { 0x9a00, 0x2eb3, 0x6000 }, + { 0x9a00, 0x2ea3, 0x5000 }, + { 0x9a00, 0x2e9b, 0x4000 }, + { 0x9a00, 0x2e96, 0x3000 }, + { 0x9a00, 0x2e94, 0x2000 }, + { 0x1a00, 0x2e93, 0x0000 }, + { 0x1a00, 0x2e95, 0x0000 }, + { 0x9a00, 0x2e98, 0x2000 }, + { 0x1a00, 0x2e97, 0x0000 }, + { 0x1a00, 0x2e99, 0x0000 }, + { 0x9a00, 0x2e9f, 0x3000 }, + { 0x9a00, 0x2e9d, 0x2000 }, + { 0x1a00, 0x2e9c, 0x0000 }, + { 0x1a00, 0x2e9e, 0x0000 }, + { 0x9a00, 0x2ea1, 0x2000 }, + { 0x1a00, 0x2ea0, 0x0000 }, + { 0x1a00, 0x2ea2, 0x0000 }, + { 0x9a00, 0x2eab, 0x4000 }, + { 0x9a00, 0x2ea7, 0x3000 }, + { 0x9a00, 0x2ea5, 0x2000 }, + { 0x1a00, 0x2ea4, 0x0000 }, + { 0x1a00, 0x2ea6, 0x0000 }, + { 0x9a00, 0x2ea9, 0x2000 }, + { 0x1a00, 0x2ea8, 0x0000 }, + { 0x1a00, 0x2eaa, 0x0000 }, + { 0x9a00, 0x2eaf, 0x3000 }, + { 0x9a00, 0x2ead, 0x2000 }, + { 0x1a00, 0x2eac, 0x0000 }, + { 0x1a00, 0x2eae, 0x0000 }, + { 0x9a00, 0x2eb1, 0x2000 }, + { 0x1a00, 0x2eb0, 0x0000 }, + { 0x1a00, 0x2eb2, 0x0000 }, + { 0x9a00, 0x2ec3, 0x5000 }, + { 0x9a00, 0x2ebb, 0x4000 }, + { 0x9a00, 0x2eb7, 0x3000 }, + { 0x9a00, 0x2eb5, 0x2000 }, + { 0x1a00, 0x2eb4, 0x0000 }, + { 0x1a00, 0x2eb6, 0x0000 }, + { 0x9a00, 0x2eb9, 0x2000 }, + { 0x1a00, 0x2eb8, 0x0000 }, + { 0x1a00, 0x2eba, 0x0000 }, + { 0x9a00, 0x2ebf, 0x3000 }, + { 0x9a00, 0x2ebd, 0x2000 }, + { 0x1a00, 0x2ebc, 0x0000 }, + { 0x1a00, 0x2ebe, 0x0000 }, + { 0x9a00, 0x2ec1, 0x2000 }, + { 0x1a00, 0x2ec0, 0x0000 }, + { 0x1a00, 0x2ec2, 0x0000 }, + { 0x9a00, 0x2ecb, 0x4000 }, + { 0x9a00, 0x2ec7, 0x3000 }, + { 0x9a00, 0x2ec5, 0x2000 }, + { 0x1a00, 0x2ec4, 0x0000 }, + { 0x1a00, 0x2ec6, 0x0000 }, + { 0x9a00, 0x2ec9, 0x2000 }, + { 0x1a00, 0x2ec8, 0x0000 }, + { 0x1a00, 0x2eca, 0x0000 }, + { 0x9a00, 0x2ecf, 0x3000 }, + { 0x9a00, 0x2ecd, 0x2000 }, + { 0x1a00, 0x2ecc, 0x0000 }, + { 0x1a00, 0x2ece, 0x0000 }, + { 0x9a00, 0x2ed1, 0x2000 }, + { 0x1a00, 0x2ed0, 0x0000 }, + { 0x1a00, 0x2ed2, 0x0000 }, + { 0x9a00, 0x2ef3, 0x6000 }, + { 0x9a00, 0x2ee3, 0x5000 }, + { 0x9a00, 0x2edb, 0x4000 }, + { 0x9a00, 0x2ed7, 0x3000 }, + { 0x9a00, 0x2ed5, 0x2000 }, + { 0x1a00, 0x2ed4, 0x0000 }, + { 0x1a00, 0x2ed6, 0x0000 }, + { 0x9a00, 0x2ed9, 0x2000 }, + { 0x1a00, 0x2ed8, 0x0000 }, + { 0x1a00, 0x2eda, 0x0000 }, + { 0x9a00, 0x2edf, 0x3000 }, + { 0x9a00, 0x2edd, 0x2000 }, + { 0x1a00, 0x2edc, 0x0000 }, + { 0x1a00, 0x2ede, 0x0000 }, + { 0x9a00, 0x2ee1, 0x2000 }, + { 0x1a00, 0x2ee0, 0x0000 }, + { 0x1a00, 0x2ee2, 0x0000 }, + { 0x9a00, 0x2eeb, 0x4000 }, + { 0x9a00, 0x2ee7, 0x3000 }, + { 0x9a00, 0x2ee5, 0x2000 }, + { 0x1a00, 0x2ee4, 0x0000 }, + { 0x1a00, 0x2ee6, 0x0000 }, + { 0x9a00, 0x2ee9, 0x2000 }, + { 0x1a00, 0x2ee8, 0x0000 }, + { 0x1a00, 0x2eea, 0x0000 }, + { 0x9a00, 0x2eef, 0x3000 }, + { 0x9a00, 0x2eed, 0x2000 }, + { 0x1a00, 0x2eec, 0x0000 }, + { 0x1a00, 0x2eee, 0x0000 }, + { 0x9a00, 0x2ef1, 0x2000 }, + { 0x1a00, 0x2ef0, 0x0000 }, + { 0x1a00, 0x2ef2, 0x0000 }, + { 0x9a00, 0x2f0f, 0x5000 }, + { 0x9a00, 0x2f07, 0x4000 }, + { 0x9a00, 0x2f03, 0x3000 }, + { 0x9a00, 0x2f01, 0x2000 }, + { 0x1a00, 0x2f00, 0x0000 }, + { 0x1a00, 0x2f02, 0x0000 }, + { 0x9a00, 0x2f05, 0x2000 }, + { 0x1a00, 0x2f04, 0x0000 }, + { 0x1a00, 0x2f06, 0x0000 }, + { 0x9a00, 0x2f0b, 0x3000 }, + { 0x9a00, 0x2f09, 0x2000 }, + { 0x1a00, 0x2f08, 0x0000 }, + { 0x1a00, 0x2f0a, 0x0000 }, + { 0x9a00, 0x2f0d, 0x2000 }, + { 0x1a00, 0x2f0c, 0x0000 }, + { 0x1a00, 0x2f0e, 0x0000 }, + { 0x9a00, 0x2f17, 0x4000 }, + { 0x9a00, 0x2f13, 0x3000 }, + { 0x9a00, 0x2f11, 0x2000 }, + { 0x1a00, 0x2f10, 0x0000 }, + { 0x1a00, 0x2f12, 0x0000 }, + { 0x9a00, 0x2f15, 0x2000 }, + { 0x1a00, 0x2f14, 0x0000 }, + { 0x1a00, 0x2f16, 0x0000 }, + { 0x9a00, 0x2f1b, 0x3000 }, + { 0x9a00, 0x2f19, 0x2000 }, + { 0x1a00, 0x2f18, 0x0000 }, + { 0x1a00, 0x2f1a, 0x0000 }, + { 0x9a00, 0x2f1d, 0x2000 }, + { 0x1a00, 0x2f1c, 0x0000 }, + { 0x1a00, 0x2f1e, 0x0000 }, + { 0x8701, 0x00f0, 0xd000 }, + { 0x8700, 0xa34d, 0xc000 }, + { 0x9a00, 0x3391, 0xb000 }, + { 0x8700, 0x3149, 0xa000 }, + { 0x9500, 0x303d, 0x9000 }, + { 0x9a00, 0x2f9f, 0x8000 }, + { 0x9a00, 0x2f5f, 0x7000 }, + { 0x9a00, 0x2f3f, 0x6000 }, + { 0x9a00, 0x2f2f, 0x5000 }, + { 0x9a00, 0x2f27, 0x4000 }, + { 0x9a00, 0x2f23, 0x3000 }, + { 0x9a00, 0x2f21, 0x2000 }, + { 0x1a00, 0x2f20, 0x0000 }, + { 0x1a00, 0x2f22, 0x0000 }, + { 0x9a00, 0x2f25, 0x2000 }, + { 0x1a00, 0x2f24, 0x0000 }, + { 0x1a00, 0x2f26, 0x0000 }, + { 0x9a00, 0x2f2b, 0x3000 }, + { 0x9a00, 0x2f29, 0x2000 }, + { 0x1a00, 0x2f28, 0x0000 }, + { 0x1a00, 0x2f2a, 0x0000 }, + { 0x9a00, 0x2f2d, 0x2000 }, + { 0x1a00, 0x2f2c, 0x0000 }, + { 0x1a00, 0x2f2e, 0x0000 }, + { 0x9a00, 0x2f37, 0x4000 }, + { 0x9a00, 0x2f33, 0x3000 }, + { 0x9a00, 0x2f31, 0x2000 }, + { 0x1a00, 0x2f30, 0x0000 }, + { 0x1a00, 0x2f32, 0x0000 }, + { 0x9a00, 0x2f35, 0x2000 }, + { 0x1a00, 0x2f34, 0x0000 }, + { 0x1a00, 0x2f36, 0x0000 }, + { 0x9a00, 0x2f3b, 0x3000 }, + { 0x9a00, 0x2f39, 0x2000 }, + { 0x1a00, 0x2f38, 0x0000 }, + { 0x1a00, 0x2f3a, 0x0000 }, + { 0x9a00, 0x2f3d, 0x2000 }, + { 0x1a00, 0x2f3c, 0x0000 }, + { 0x1a00, 0x2f3e, 0x0000 }, + { 0x9a00, 0x2f4f, 0x5000 }, + { 0x9a00, 0x2f47, 0x4000 }, + { 0x9a00, 0x2f43, 0x3000 }, + { 0x9a00, 0x2f41, 0x2000 }, + { 0x1a00, 0x2f40, 0x0000 }, + { 0x1a00, 0x2f42, 0x0000 }, + { 0x9a00, 0x2f45, 0x2000 }, + { 0x1a00, 0x2f44, 0x0000 }, + { 0x1a00, 0x2f46, 0x0000 }, + { 0x9a00, 0x2f4b, 0x3000 }, + { 0x9a00, 0x2f49, 0x2000 }, + { 0x1a00, 0x2f48, 0x0000 }, + { 0x1a00, 0x2f4a, 0x0000 }, + { 0x9a00, 0x2f4d, 0x2000 }, + { 0x1a00, 0x2f4c, 0x0000 }, + { 0x1a00, 0x2f4e, 0x0000 }, + { 0x9a00, 0x2f57, 0x4000 }, + { 0x9a00, 0x2f53, 0x3000 }, + { 0x9a00, 0x2f51, 0x2000 }, + { 0x1a00, 0x2f50, 0x0000 }, + { 0x1a00, 0x2f52, 0x0000 }, + { 0x9a00, 0x2f55, 0x2000 }, + { 0x1a00, 0x2f54, 0x0000 }, + { 0x1a00, 0x2f56, 0x0000 }, + { 0x9a00, 0x2f5b, 0x3000 }, + { 0x9a00, 0x2f59, 0x2000 }, + { 0x1a00, 0x2f58, 0x0000 }, + { 0x1a00, 0x2f5a, 0x0000 }, + { 0x9a00, 0x2f5d, 0x2000 }, + { 0x1a00, 0x2f5c, 0x0000 }, + { 0x1a00, 0x2f5e, 0x0000 }, + { 0x9a00, 0x2f7f, 0x6000 }, + { 0x9a00, 0x2f6f, 0x5000 }, + { 0x9a00, 0x2f67, 0x4000 }, + { 0x9a00, 0x2f63, 0x3000 }, + { 0x9a00, 0x2f61, 0x2000 }, + { 0x1a00, 0x2f60, 0x0000 }, + { 0x1a00, 0x2f62, 0x0000 }, + { 0x9a00, 0x2f65, 0x2000 }, + { 0x1a00, 0x2f64, 0x0000 }, + { 0x1a00, 0x2f66, 0x0000 }, + { 0x9a00, 0x2f6b, 0x3000 }, + { 0x9a00, 0x2f69, 0x2000 }, + { 0x1a00, 0x2f68, 0x0000 }, + { 0x1a00, 0x2f6a, 0x0000 }, + { 0x9a00, 0x2f6d, 0x2000 }, + { 0x1a00, 0x2f6c, 0x0000 }, + { 0x1a00, 0x2f6e, 0x0000 }, + { 0x9a00, 0x2f77, 0x4000 }, + { 0x9a00, 0x2f73, 0x3000 }, + { 0x9a00, 0x2f71, 0x2000 }, + { 0x1a00, 0x2f70, 0x0000 }, + { 0x1a00, 0x2f72, 0x0000 }, + { 0x9a00, 0x2f75, 0x2000 }, + { 0x1a00, 0x2f74, 0x0000 }, + { 0x1a00, 0x2f76, 0x0000 }, + { 0x9a00, 0x2f7b, 0x3000 }, + { 0x9a00, 0x2f79, 0x2000 }, + { 0x1a00, 0x2f78, 0x0000 }, + { 0x1a00, 0x2f7a, 0x0000 }, + { 0x9a00, 0x2f7d, 0x2000 }, + { 0x1a00, 0x2f7c, 0x0000 }, + { 0x1a00, 0x2f7e, 0x0000 }, + { 0x9a00, 0x2f8f, 0x5000 }, + { 0x9a00, 0x2f87, 0x4000 }, + { 0x9a00, 0x2f83, 0x3000 }, + { 0x9a00, 0x2f81, 0x2000 }, + { 0x1a00, 0x2f80, 0x0000 }, + { 0x1a00, 0x2f82, 0x0000 }, + { 0x9a00, 0x2f85, 0x2000 }, + { 0x1a00, 0x2f84, 0x0000 }, + { 0x1a00, 0x2f86, 0x0000 }, + { 0x9a00, 0x2f8b, 0x3000 }, + { 0x9a00, 0x2f89, 0x2000 }, + { 0x1a00, 0x2f88, 0x0000 }, + { 0x1a00, 0x2f8a, 0x0000 }, + { 0x9a00, 0x2f8d, 0x2000 }, + { 0x1a00, 0x2f8c, 0x0000 }, + { 0x1a00, 0x2f8e, 0x0000 }, + { 0x9a00, 0x2f97, 0x4000 }, + { 0x9a00, 0x2f93, 0x3000 }, + { 0x9a00, 0x2f91, 0x2000 }, + { 0x1a00, 0x2f90, 0x0000 }, + { 0x1a00, 0x2f92, 0x0000 }, + { 0x9a00, 0x2f95, 0x2000 }, + { 0x1a00, 0x2f94, 0x0000 }, + { 0x1a00, 0x2f96, 0x0000 }, + { 0x9a00, 0x2f9b, 0x3000 }, + { 0x9a00, 0x2f99, 0x2000 }, + { 0x1a00, 0x2f98, 0x0000 }, + { 0x1a00, 0x2f9a, 0x0000 }, + { 0x9a00, 0x2f9d, 0x2000 }, + { 0x1a00, 0x2f9c, 0x0000 }, + { 0x1a00, 0x2f9e, 0x0000 }, + { 0x9a00, 0x2ff9, 0x7000 }, + { 0x9a00, 0x2fbf, 0x6000 }, + { 0x9a00, 0x2faf, 0x5000 }, + { 0x9a00, 0x2fa7, 0x4000 }, + { 0x9a00, 0x2fa3, 0x3000 }, + { 0x9a00, 0x2fa1, 0x2000 }, + { 0x1a00, 0x2fa0, 0x0000 }, + { 0x1a00, 0x2fa2, 0x0000 }, + { 0x9a00, 0x2fa5, 0x2000 }, + { 0x1a00, 0x2fa4, 0x0000 }, + { 0x1a00, 0x2fa6, 0x0000 }, + { 0x9a00, 0x2fab, 0x3000 }, + { 0x9a00, 0x2fa9, 0x2000 }, + { 0x1a00, 0x2fa8, 0x0000 }, + { 0x1a00, 0x2faa, 0x0000 }, + { 0x9a00, 0x2fad, 0x2000 }, + { 0x1a00, 0x2fac, 0x0000 }, + { 0x1a00, 0x2fae, 0x0000 }, + { 0x9a00, 0x2fb7, 0x4000 }, + { 0x9a00, 0x2fb3, 0x3000 }, + { 0x9a00, 0x2fb1, 0x2000 }, + { 0x1a00, 0x2fb0, 0x0000 }, + { 0x1a00, 0x2fb2, 0x0000 }, + { 0x9a00, 0x2fb5, 0x2000 }, + { 0x1a00, 0x2fb4, 0x0000 }, + { 0x1a00, 0x2fb6, 0x0000 }, + { 0x9a00, 0x2fbb, 0x3000 }, + { 0x9a00, 0x2fb9, 0x2000 }, + { 0x1a00, 0x2fb8, 0x0000 }, + { 0x1a00, 0x2fba, 0x0000 }, + { 0x9a00, 0x2fbd, 0x2000 }, + { 0x1a00, 0x2fbc, 0x0000 }, + { 0x1a00, 0x2fbe, 0x0000 }, + { 0x9a00, 0x2fcf, 0x5000 }, + { 0x9a00, 0x2fc7, 0x4000 }, + { 0x9a00, 0x2fc3, 0x3000 }, + { 0x9a00, 0x2fc1, 0x2000 }, + { 0x1a00, 0x2fc0, 0x0000 }, + { 0x1a00, 0x2fc2, 0x0000 }, + { 0x9a00, 0x2fc5, 0x2000 }, + { 0x1a00, 0x2fc4, 0x0000 }, + { 0x1a00, 0x2fc6, 0x0000 }, + { 0x9a00, 0x2fcb, 0x3000 }, + { 0x9a00, 0x2fc9, 0x2000 }, + { 0x1a00, 0x2fc8, 0x0000 }, + { 0x1a00, 0x2fca, 0x0000 }, + { 0x9a00, 0x2fcd, 0x2000 }, + { 0x1a00, 0x2fcc, 0x0000 }, + { 0x1a00, 0x2fce, 0x0000 }, + { 0x9a00, 0x2ff1, 0x4000 }, + { 0x9a00, 0x2fd3, 0x3000 }, + { 0x9a00, 0x2fd1, 0x2000 }, + { 0x1a00, 0x2fd0, 0x0000 }, + { 0x1a00, 0x2fd2, 0x0000 }, + { 0x9a00, 0x2fd5, 0x2000 }, + { 0x1a00, 0x2fd4, 0x0000 }, + { 0x1a00, 0x2ff0, 0x0000 }, + { 0x9a00, 0x2ff5, 0x3000 }, + { 0x9a00, 0x2ff3, 0x2000 }, + { 0x1a00, 0x2ff2, 0x0000 }, + { 0x1a00, 0x2ff4, 0x0000 }, + { 0x9a00, 0x2ff7, 0x2000 }, + { 0x1a00, 0x2ff6, 0x0000 }, + { 0x1a00, 0x2ff8, 0x0000 }, + { 0x9600, 0x301d, 0x6000 }, + { 0x9200, 0x300d, 0x5000 }, + { 0x8600, 0x3005, 0x4000 }, + { 0x9500, 0x3001, 0x3000 }, + { 0x9a00, 0x2ffb, 0x2000 }, + { 0x1a00, 0x2ffa, 0x0000 }, + { 0x1d00, 0x3000, 0x0000 }, + { 0x9500, 0x3003, 0x2000 }, + { 0x1500, 0x3002, 0x0000 }, + { 0x1a00, 0x3004, 0x0000 }, + { 0x9200, 0x3009, 0x3000 }, + { 0x8e00, 0x3007, 0x2000 }, + { 0x0700, 0x3006, 0x0000 }, + { 0x1600, 0x3008, 0x0000 }, + { 0x9200, 0x300b, 0x2000 }, + { 0x1600, 0x300a, 0x0000 }, + { 0x1600, 0x300c, 0x0000 }, + { 0x9200, 0x3015, 0x4000 }, + { 0x9200, 0x3011, 0x3000 }, + { 0x9200, 0x300f, 0x2000 }, + { 0x1600, 0x300e, 0x0000 }, + { 0x1600, 0x3010, 0x0000 }, + { 0x9a00, 0x3013, 0x2000 }, + { 0x1a00, 0x3012, 0x0000 }, + { 0x1600, 0x3014, 0x0000 }, + { 0x9200, 0x3019, 0x3000 }, + { 0x9200, 0x3017, 0x2000 }, + { 0x1600, 0x3016, 0x0000 }, + { 0x1600, 0x3018, 0x0000 }, + { 0x9200, 0x301b, 0x2000 }, + { 0x1600, 0x301a, 0x0000 }, + { 0x1100, 0x301c, 0x0000 }, + { 0x8c00, 0x302d, 0x5000 }, + { 0x8e00, 0x3025, 0x4000 }, + { 0x8e00, 0x3021, 0x3000 }, + { 0x9200, 0x301f, 0x2000 }, + { 0x1200, 0x301e, 0x0000 }, + { 0x1a00, 0x3020, 0x0000 }, + { 0x8e00, 0x3023, 0x2000 }, + { 0x0e00, 0x3022, 0x0000 }, + { 0x0e00, 0x3024, 0x0000 }, + { 0x8e00, 0x3029, 0x3000 }, + { 0x8e00, 0x3027, 0x2000 }, + { 0x0e00, 0x3026, 0x0000 }, + { 0x0e00, 0x3028, 0x0000 }, + { 0x8c00, 0x302b, 0x2000 }, + { 0x0c00, 0x302a, 0x0000 }, + { 0x0c00, 0x302c, 0x0000 }, + { 0x8600, 0x3035, 0x4000 }, + { 0x8600, 0x3031, 0x3000 }, + { 0x8c00, 0x302f, 0x2000 }, + { 0x0c00, 0x302e, 0x0000 }, + { 0x1100, 0x3030, 0x0000 }, + { 0x8600, 0x3033, 0x2000 }, + { 0x0600, 0x3032, 0x0000 }, + { 0x0600, 0x3034, 0x0000 }, + { 0x8e00, 0x3039, 0x3000 }, + { 0x9a00, 0x3037, 0x2000 }, + { 0x1a00, 0x3036, 0x0000 }, + { 0x0e00, 0x3038, 0x0000 }, + { 0x8600, 0x303b, 0x2000 }, + { 0x0e00, 0x303a, 0x0000 }, + { 0x0700, 0x303c, 0x0000 }, + { 0x8700, 0x30c0, 0x8000 }, + { 0x8700, 0x307e, 0x7000 }, + { 0x8700, 0x305e, 0x6000 }, + { 0x8700, 0x304e, 0x5000 }, + { 0x8700, 0x3046, 0x4000 }, + { 0x8700, 0x3042, 0x3000 }, + { 0x9a00, 0x303f, 0x2000 }, + { 0x1a00, 0x303e, 0x0000 }, + { 0x0700, 0x3041, 0x0000 }, + { 0x8700, 0x3044, 0x2000 }, + { 0x0700, 0x3043, 0x0000 }, + { 0x0700, 0x3045, 0x0000 }, + { 0x8700, 0x304a, 0x3000 }, + { 0x8700, 0x3048, 0x2000 }, + { 0x0700, 0x3047, 0x0000 }, + { 0x0700, 0x3049, 0x0000 }, + { 0x8700, 0x304c, 0x2000 }, + { 0x0700, 0x304b, 0x0000 }, + { 0x0700, 0x304d, 0x0000 }, + { 0x8700, 0x3056, 0x4000 }, + { 0x8700, 0x3052, 0x3000 }, + { 0x8700, 0x3050, 0x2000 }, + { 0x0700, 0x304f, 0x0000 }, + { 0x0700, 0x3051, 0x0000 }, + { 0x8700, 0x3054, 0x2000 }, + { 0x0700, 0x3053, 0x0000 }, + { 0x0700, 0x3055, 0x0000 }, + { 0x8700, 0x305a, 0x3000 }, + { 0x8700, 0x3058, 0x2000 }, + { 0x0700, 0x3057, 0x0000 }, + { 0x0700, 0x3059, 0x0000 }, + { 0x8700, 0x305c, 0x2000 }, + { 0x0700, 0x305b, 0x0000 }, + { 0x0700, 0x305d, 0x0000 }, + { 0x8700, 0x306e, 0x5000 }, + { 0x8700, 0x3066, 0x4000 }, + { 0x8700, 0x3062, 0x3000 }, + { 0x8700, 0x3060, 0x2000 }, + { 0x0700, 0x305f, 0x0000 }, + { 0x0700, 0x3061, 0x0000 }, + { 0x8700, 0x3064, 0x2000 }, + { 0x0700, 0x3063, 0x0000 }, + { 0x0700, 0x3065, 0x0000 }, + { 0x8700, 0x306a, 0x3000 }, + { 0x8700, 0x3068, 0x2000 }, + { 0x0700, 0x3067, 0x0000 }, + { 0x0700, 0x3069, 0x0000 }, + { 0x8700, 0x306c, 0x2000 }, + { 0x0700, 0x306b, 0x0000 }, + { 0x0700, 0x306d, 0x0000 }, + { 0x8700, 0x3076, 0x4000 }, + { 0x8700, 0x3072, 0x3000 }, + { 0x8700, 0x3070, 0x2000 }, + { 0x0700, 0x306f, 0x0000 }, + { 0x0700, 0x3071, 0x0000 }, + { 0x8700, 0x3074, 0x2000 }, + { 0x0700, 0x3073, 0x0000 }, + { 0x0700, 0x3075, 0x0000 }, + { 0x8700, 0x307a, 0x3000 }, + { 0x8700, 0x3078, 0x2000 }, + { 0x0700, 0x3077, 0x0000 }, + { 0x0700, 0x3079, 0x0000 }, + { 0x8700, 0x307c, 0x2000 }, + { 0x0700, 0x307b, 0x0000 }, + { 0x0700, 0x307d, 0x0000 }, + { 0x9100, 0x30a0, 0x6000 }, + { 0x8700, 0x308e, 0x5000 }, + { 0x8700, 0x3086, 0x4000 }, + { 0x8700, 0x3082, 0x3000 }, + { 0x8700, 0x3080, 0x2000 }, + { 0x0700, 0x307f, 0x0000 }, + { 0x0700, 0x3081, 0x0000 }, + { 0x8700, 0x3084, 0x2000 }, + { 0x0700, 0x3083, 0x0000 }, + { 0x0700, 0x3085, 0x0000 }, + { 0x8700, 0x308a, 0x3000 }, + { 0x8700, 0x3088, 0x2000 }, + { 0x0700, 0x3087, 0x0000 }, + { 0x0700, 0x3089, 0x0000 }, + { 0x8700, 0x308c, 0x2000 }, + { 0x0700, 0x308b, 0x0000 }, + { 0x0700, 0x308d, 0x0000 }, + { 0x8700, 0x3096, 0x4000 }, + { 0x8700, 0x3092, 0x3000 }, + { 0x8700, 0x3090, 0x2000 }, + { 0x0700, 0x308f, 0x0000 }, + { 0x0700, 0x3091, 0x0000 }, + { 0x8700, 0x3094, 0x2000 }, + { 0x0700, 0x3093, 0x0000 }, + { 0x0700, 0x3095, 0x0000 }, + { 0x9800, 0x309c, 0x3000 }, + { 0x8c00, 0x309a, 0x2000 }, + { 0x0c00, 0x3099, 0x0000 }, + { 0x1800, 0x309b, 0x0000 }, + { 0x8600, 0x309e, 0x2000 }, + { 0x0600, 0x309d, 0x0000 }, + { 0x0700, 0x309f, 0x0000 }, + { 0x8700, 0x30b0, 0x5000 }, + { 0x8700, 0x30a8, 0x4000 }, + { 0x8700, 0x30a4, 0x3000 }, + { 0x8700, 0x30a2, 0x2000 }, + { 0x0700, 0x30a1, 0x0000 }, + { 0x0700, 0x30a3, 0x0000 }, + { 0x8700, 0x30a6, 0x2000 }, + { 0x0700, 0x30a5, 0x0000 }, + { 0x0700, 0x30a7, 0x0000 }, + { 0x8700, 0x30ac, 0x3000 }, + { 0x8700, 0x30aa, 0x2000 }, + { 0x0700, 0x30a9, 0x0000 }, + { 0x0700, 0x30ab, 0x0000 }, + { 0x8700, 0x30ae, 0x2000 }, + { 0x0700, 0x30ad, 0x0000 }, + { 0x0700, 0x30af, 0x0000 }, + { 0x8700, 0x30b8, 0x4000 }, + { 0x8700, 0x30b4, 0x3000 }, + { 0x8700, 0x30b2, 0x2000 }, + { 0x0700, 0x30b1, 0x0000 }, + { 0x0700, 0x30b3, 0x0000 }, + { 0x8700, 0x30b6, 0x2000 }, + { 0x0700, 0x30b5, 0x0000 }, + { 0x0700, 0x30b7, 0x0000 }, + { 0x8700, 0x30bc, 0x3000 }, + { 0x8700, 0x30ba, 0x2000 }, + { 0x0700, 0x30b9, 0x0000 }, + { 0x0700, 0x30bb, 0x0000 }, + { 0x8700, 0x30be, 0x2000 }, + { 0x0700, 0x30bd, 0x0000 }, + { 0x0700, 0x30bf, 0x0000 }, + { 0x8700, 0x3105, 0x7000 }, + { 0x8700, 0x30e0, 0x6000 }, + { 0x8700, 0x30d0, 0x5000 }, + { 0x8700, 0x30c8, 0x4000 }, + { 0x8700, 0x30c4, 0x3000 }, + { 0x8700, 0x30c2, 0x2000 }, + { 0x0700, 0x30c1, 0x0000 }, + { 0x0700, 0x30c3, 0x0000 }, + { 0x8700, 0x30c6, 0x2000 }, + { 0x0700, 0x30c5, 0x0000 }, + { 0x0700, 0x30c7, 0x0000 }, + { 0x8700, 0x30cc, 0x3000 }, + { 0x8700, 0x30ca, 0x2000 }, + { 0x0700, 0x30c9, 0x0000 }, + { 0x0700, 0x30cb, 0x0000 }, + { 0x8700, 0x30ce, 0x2000 }, + { 0x0700, 0x30cd, 0x0000 }, + { 0x0700, 0x30cf, 0x0000 }, + { 0x8700, 0x30d8, 0x4000 }, + { 0x8700, 0x30d4, 0x3000 }, + { 0x8700, 0x30d2, 0x2000 }, + { 0x0700, 0x30d1, 0x0000 }, + { 0x0700, 0x30d3, 0x0000 }, + { 0x8700, 0x30d6, 0x2000 }, + { 0x0700, 0x30d5, 0x0000 }, + { 0x0700, 0x30d7, 0x0000 }, + { 0x8700, 0x30dc, 0x3000 }, + { 0x8700, 0x30da, 0x2000 }, + { 0x0700, 0x30d9, 0x0000 }, + { 0x0700, 0x30db, 0x0000 }, + { 0x8700, 0x30de, 0x2000 }, + { 0x0700, 0x30dd, 0x0000 }, + { 0x0700, 0x30df, 0x0000 }, + { 0x8700, 0x30f0, 0x5000 }, + { 0x8700, 0x30e8, 0x4000 }, + { 0x8700, 0x30e4, 0x3000 }, + { 0x8700, 0x30e2, 0x2000 }, + { 0x0700, 0x30e1, 0x0000 }, + { 0x0700, 0x30e3, 0x0000 }, + { 0x8700, 0x30e6, 0x2000 }, + { 0x0700, 0x30e5, 0x0000 }, + { 0x0700, 0x30e7, 0x0000 }, + { 0x8700, 0x30ec, 0x3000 }, + { 0x8700, 0x30ea, 0x2000 }, + { 0x0700, 0x30e9, 0x0000 }, + { 0x0700, 0x30eb, 0x0000 }, + { 0x8700, 0x30ee, 0x2000 }, + { 0x0700, 0x30ed, 0x0000 }, + { 0x0700, 0x30ef, 0x0000 }, + { 0x8700, 0x30f8, 0x4000 }, + { 0x8700, 0x30f4, 0x3000 }, + { 0x8700, 0x30f2, 0x2000 }, + { 0x0700, 0x30f1, 0x0000 }, + { 0x0700, 0x30f3, 0x0000 }, + { 0x8700, 0x30f6, 0x2000 }, + { 0x0700, 0x30f5, 0x0000 }, + { 0x0700, 0x30f7, 0x0000 }, + { 0x8600, 0x30fc, 0x3000 }, + { 0x8700, 0x30fa, 0x2000 }, + { 0x0700, 0x30f9, 0x0000 }, + { 0x1000, 0x30fb, 0x0000 }, + { 0x8600, 0x30fe, 0x2000 }, + { 0x0600, 0x30fd, 0x0000 }, + { 0x0700, 0x30ff, 0x0000 }, + { 0x8700, 0x3125, 0x6000 }, + { 0x8700, 0x3115, 0x5000 }, + { 0x8700, 0x310d, 0x4000 }, + { 0x8700, 0x3109, 0x3000 }, + { 0x8700, 0x3107, 0x2000 }, + { 0x0700, 0x3106, 0x0000 }, + { 0x0700, 0x3108, 0x0000 }, + { 0x8700, 0x310b, 0x2000 }, + { 0x0700, 0x310a, 0x0000 }, + { 0x0700, 0x310c, 0x0000 }, + { 0x8700, 0x3111, 0x3000 }, + { 0x8700, 0x310f, 0x2000 }, + { 0x0700, 0x310e, 0x0000 }, + { 0x0700, 0x3110, 0x0000 }, + { 0x8700, 0x3113, 0x2000 }, + { 0x0700, 0x3112, 0x0000 }, + { 0x0700, 0x3114, 0x0000 }, + { 0x8700, 0x311d, 0x4000 }, + { 0x8700, 0x3119, 0x3000 }, + { 0x8700, 0x3117, 0x2000 }, + { 0x0700, 0x3116, 0x0000 }, + { 0x0700, 0x3118, 0x0000 }, + { 0x8700, 0x311b, 0x2000 }, + { 0x0700, 0x311a, 0x0000 }, + { 0x0700, 0x311c, 0x0000 }, + { 0x8700, 0x3121, 0x3000 }, + { 0x8700, 0x311f, 0x2000 }, + { 0x0700, 0x311e, 0x0000 }, + { 0x0700, 0x3120, 0x0000 }, + { 0x8700, 0x3123, 0x2000 }, + { 0x0700, 0x3122, 0x0000 }, + { 0x0700, 0x3124, 0x0000 }, + { 0x8700, 0x3139, 0x5000 }, + { 0x8700, 0x3131, 0x4000 }, + { 0x8700, 0x3129, 0x3000 }, + { 0x8700, 0x3127, 0x2000 }, + { 0x0700, 0x3126, 0x0000 }, + { 0x0700, 0x3128, 0x0000 }, + { 0x8700, 0x312b, 0x2000 }, + { 0x0700, 0x312a, 0x0000 }, + { 0x0700, 0x312c, 0x0000 }, + { 0x8700, 0x3135, 0x3000 }, + { 0x8700, 0x3133, 0x2000 }, + { 0x0700, 0x3132, 0x0000 }, + { 0x0700, 0x3134, 0x0000 }, + { 0x8700, 0x3137, 0x2000 }, + { 0x0700, 0x3136, 0x0000 }, + { 0x0700, 0x3138, 0x0000 }, + { 0x8700, 0x3141, 0x4000 }, + { 0x8700, 0x313d, 0x3000 }, + { 0x8700, 0x313b, 0x2000 }, + { 0x0700, 0x313a, 0x0000 }, + { 0x0700, 0x313c, 0x0000 }, + { 0x8700, 0x313f, 0x2000 }, + { 0x0700, 0x313e, 0x0000 }, + { 0x0700, 0x3140, 0x0000 }, + { 0x8700, 0x3145, 0x3000 }, + { 0x8700, 0x3143, 0x2000 }, + { 0x0700, 0x3142, 0x0000 }, + { 0x0700, 0x3144, 0x0000 }, + { 0x8700, 0x3147, 0x2000 }, + { 0x0700, 0x3146, 0x0000 }, + { 0x0700, 0x3148, 0x0000 }, + { 0x9a00, 0x3290, 0x9000 }, + { 0x9a00, 0x3202, 0x8000 }, + { 0x8700, 0x3189, 0x7000 }, + { 0x8700, 0x3169, 0x6000 }, + { 0x8700, 0x3159, 0x5000 }, + { 0x8700, 0x3151, 0x4000 }, + { 0x8700, 0x314d, 0x3000 }, + { 0x8700, 0x314b, 0x2000 }, + { 0x0700, 0x314a, 0x0000 }, + { 0x0700, 0x314c, 0x0000 }, + { 0x8700, 0x314f, 0x2000 }, + { 0x0700, 0x314e, 0x0000 }, + { 0x0700, 0x3150, 0x0000 }, + { 0x8700, 0x3155, 0x3000 }, + { 0x8700, 0x3153, 0x2000 }, + { 0x0700, 0x3152, 0x0000 }, + { 0x0700, 0x3154, 0x0000 }, + { 0x8700, 0x3157, 0x2000 }, + { 0x0700, 0x3156, 0x0000 }, + { 0x0700, 0x3158, 0x0000 }, + { 0x8700, 0x3161, 0x4000 }, + { 0x8700, 0x315d, 0x3000 }, + { 0x8700, 0x315b, 0x2000 }, + { 0x0700, 0x315a, 0x0000 }, + { 0x0700, 0x315c, 0x0000 }, + { 0x8700, 0x315f, 0x2000 }, + { 0x0700, 0x315e, 0x0000 }, + { 0x0700, 0x3160, 0x0000 }, + { 0x8700, 0x3165, 0x3000 }, + { 0x8700, 0x3163, 0x2000 }, + { 0x0700, 0x3162, 0x0000 }, + { 0x0700, 0x3164, 0x0000 }, + { 0x8700, 0x3167, 0x2000 }, + { 0x0700, 0x3166, 0x0000 }, + { 0x0700, 0x3168, 0x0000 }, + { 0x8700, 0x3179, 0x5000 }, + { 0x8700, 0x3171, 0x4000 }, + { 0x8700, 0x316d, 0x3000 }, + { 0x8700, 0x316b, 0x2000 }, + { 0x0700, 0x316a, 0x0000 }, + { 0x0700, 0x316c, 0x0000 }, + { 0x8700, 0x316f, 0x2000 }, + { 0x0700, 0x316e, 0x0000 }, + { 0x0700, 0x3170, 0x0000 }, + { 0x8700, 0x3175, 0x3000 }, + { 0x8700, 0x3173, 0x2000 }, + { 0x0700, 0x3172, 0x0000 }, + { 0x0700, 0x3174, 0x0000 }, + { 0x8700, 0x3177, 0x2000 }, + { 0x0700, 0x3176, 0x0000 }, + { 0x0700, 0x3178, 0x0000 }, + { 0x8700, 0x3181, 0x4000 }, + { 0x8700, 0x317d, 0x3000 }, + { 0x8700, 0x317b, 0x2000 }, + { 0x0700, 0x317a, 0x0000 }, + { 0x0700, 0x317c, 0x0000 }, + { 0x8700, 0x317f, 0x2000 }, + { 0x0700, 0x317e, 0x0000 }, + { 0x0700, 0x3180, 0x0000 }, + { 0x8700, 0x3185, 0x3000 }, + { 0x8700, 0x3183, 0x2000 }, + { 0x0700, 0x3182, 0x0000 }, + { 0x0700, 0x3184, 0x0000 }, + { 0x8700, 0x3187, 0x2000 }, + { 0x0700, 0x3186, 0x0000 }, + { 0x0700, 0x3188, 0x0000 }, + { 0x8700, 0x31aa, 0x6000 }, + { 0x9a00, 0x319a, 0x5000 }, + { 0x8f00, 0x3192, 0x4000 }, + { 0x8700, 0x318d, 0x3000 }, + { 0x8700, 0x318b, 0x2000 }, + { 0x0700, 0x318a, 0x0000 }, + { 0x0700, 0x318c, 0x0000 }, + { 0x9a00, 0x3190, 0x2000 }, + { 0x0700, 0x318e, 0x0000 }, + { 0x1a00, 0x3191, 0x0000 }, + { 0x9a00, 0x3196, 0x3000 }, + { 0x8f00, 0x3194, 0x2000 }, + { 0x0f00, 0x3193, 0x0000 }, + { 0x0f00, 0x3195, 0x0000 }, + { 0x9a00, 0x3198, 0x2000 }, + { 0x1a00, 0x3197, 0x0000 }, + { 0x1a00, 0x3199, 0x0000 }, + { 0x8700, 0x31a2, 0x4000 }, + { 0x9a00, 0x319e, 0x3000 }, + { 0x9a00, 0x319c, 0x2000 }, + { 0x1a00, 0x319b, 0x0000 }, + { 0x1a00, 0x319d, 0x0000 }, + { 0x8700, 0x31a0, 0x2000 }, + { 0x1a00, 0x319f, 0x0000 }, + { 0x0700, 0x31a1, 0x0000 }, + { 0x8700, 0x31a6, 0x3000 }, + { 0x8700, 0x31a4, 0x2000 }, + { 0x0700, 0x31a3, 0x0000 }, + { 0x0700, 0x31a5, 0x0000 }, + { 0x8700, 0x31a8, 0x2000 }, + { 0x0700, 0x31a7, 0x0000 }, + { 0x0700, 0x31a9, 0x0000 }, + { 0x8700, 0x31f2, 0x5000 }, + { 0x8700, 0x31b2, 0x4000 }, + { 0x8700, 0x31ae, 0x3000 }, + { 0x8700, 0x31ac, 0x2000 }, + { 0x0700, 0x31ab, 0x0000 }, + { 0x0700, 0x31ad, 0x0000 }, + { 0x8700, 0x31b0, 0x2000 }, + { 0x0700, 0x31af, 0x0000 }, + { 0x0700, 0x31b1, 0x0000 }, + { 0x8700, 0x31b6, 0x3000 }, + { 0x8700, 0x31b4, 0x2000 }, + { 0x0700, 0x31b3, 0x0000 }, + { 0x0700, 0x31b5, 0x0000 }, + { 0x8700, 0x31f0, 0x2000 }, + { 0x0700, 0x31b7, 0x0000 }, + { 0x0700, 0x31f1, 0x0000 }, + { 0x8700, 0x31fa, 0x4000 }, + { 0x8700, 0x31f6, 0x3000 }, + { 0x8700, 0x31f4, 0x2000 }, + { 0x0700, 0x31f3, 0x0000 }, + { 0x0700, 0x31f5, 0x0000 }, + { 0x8700, 0x31f8, 0x2000 }, + { 0x0700, 0x31f7, 0x0000 }, + { 0x0700, 0x31f9, 0x0000 }, + { 0x8700, 0x31fe, 0x3000 }, + { 0x8700, 0x31fc, 0x2000 }, + { 0x0700, 0x31fb, 0x0000 }, + { 0x0700, 0x31fd, 0x0000 }, + { 0x9a00, 0x3200, 0x2000 }, + { 0x0700, 0x31ff, 0x0000 }, + { 0x1a00, 0x3201, 0x0000 }, + { 0x9a00, 0x3243, 0x7000 }, + { 0x8f00, 0x3223, 0x6000 }, + { 0x9a00, 0x3212, 0x5000 }, + { 0x9a00, 0x320a, 0x4000 }, + { 0x9a00, 0x3206, 0x3000 }, + { 0x9a00, 0x3204, 0x2000 }, + { 0x1a00, 0x3203, 0x0000 }, + { 0x1a00, 0x3205, 0x0000 }, + { 0x9a00, 0x3208, 0x2000 }, + { 0x1a00, 0x3207, 0x0000 }, + { 0x1a00, 0x3209, 0x0000 }, + { 0x9a00, 0x320e, 0x3000 }, + { 0x9a00, 0x320c, 0x2000 }, + { 0x1a00, 0x320b, 0x0000 }, + { 0x1a00, 0x320d, 0x0000 }, + { 0x9a00, 0x3210, 0x2000 }, + { 0x1a00, 0x320f, 0x0000 }, + { 0x1a00, 0x3211, 0x0000 }, + { 0x9a00, 0x321a, 0x4000 }, + { 0x9a00, 0x3216, 0x3000 }, + { 0x9a00, 0x3214, 0x2000 }, + { 0x1a00, 0x3213, 0x0000 }, + { 0x1a00, 0x3215, 0x0000 }, + { 0x9a00, 0x3218, 0x2000 }, + { 0x1a00, 0x3217, 0x0000 }, + { 0x1a00, 0x3219, 0x0000 }, + { 0x9a00, 0x321e, 0x3000 }, + { 0x9a00, 0x321c, 0x2000 }, + { 0x1a00, 0x321b, 0x0000 }, + { 0x1a00, 0x321d, 0x0000 }, + { 0x8f00, 0x3221, 0x2000 }, + { 0x0f00, 0x3220, 0x0000 }, + { 0x0f00, 0x3222, 0x0000 }, + { 0x9a00, 0x3233, 0x5000 }, + { 0x9a00, 0x322b, 0x4000 }, + { 0x8f00, 0x3227, 0x3000 }, + { 0x8f00, 0x3225, 0x2000 }, + { 0x0f00, 0x3224, 0x0000 }, + { 0x0f00, 0x3226, 0x0000 }, + { 0x8f00, 0x3229, 0x2000 }, + { 0x0f00, 0x3228, 0x0000 }, + { 0x1a00, 0x322a, 0x0000 }, + { 0x9a00, 0x322f, 0x3000 }, + { 0x9a00, 0x322d, 0x2000 }, + { 0x1a00, 0x322c, 0x0000 }, + { 0x1a00, 0x322e, 0x0000 }, + { 0x9a00, 0x3231, 0x2000 }, + { 0x1a00, 0x3230, 0x0000 }, + { 0x1a00, 0x3232, 0x0000 }, + { 0x9a00, 0x323b, 0x4000 }, + { 0x9a00, 0x3237, 0x3000 }, + { 0x9a00, 0x3235, 0x2000 }, + { 0x1a00, 0x3234, 0x0000 }, + { 0x1a00, 0x3236, 0x0000 }, + { 0x9a00, 0x3239, 0x2000 }, + { 0x1a00, 0x3238, 0x0000 }, + { 0x1a00, 0x323a, 0x0000 }, + { 0x9a00, 0x323f, 0x3000 }, + { 0x9a00, 0x323d, 0x2000 }, + { 0x1a00, 0x323c, 0x0000 }, + { 0x1a00, 0x323e, 0x0000 }, + { 0x9a00, 0x3241, 0x2000 }, + { 0x1a00, 0x3240, 0x0000 }, + { 0x1a00, 0x3242, 0x0000 }, + { 0x9a00, 0x326f, 0x6000 }, + { 0x8f00, 0x325f, 0x5000 }, + { 0x8f00, 0x3257, 0x4000 }, + { 0x8f00, 0x3253, 0x3000 }, + { 0x8f00, 0x3251, 0x2000 }, + { 0x1a00, 0x3250, 0x0000 }, + { 0x0f00, 0x3252, 0x0000 }, + { 0x8f00, 0x3255, 0x2000 }, + { 0x0f00, 0x3254, 0x0000 }, + { 0x0f00, 0x3256, 0x0000 }, + { 0x8f00, 0x325b, 0x3000 }, + { 0x8f00, 0x3259, 0x2000 }, + { 0x0f00, 0x3258, 0x0000 }, + { 0x0f00, 0x325a, 0x0000 }, + { 0x8f00, 0x325d, 0x2000 }, + { 0x0f00, 0x325c, 0x0000 }, + { 0x0f00, 0x325e, 0x0000 }, + { 0x9a00, 0x3267, 0x4000 }, + { 0x9a00, 0x3263, 0x3000 }, + { 0x9a00, 0x3261, 0x2000 }, + { 0x1a00, 0x3260, 0x0000 }, + { 0x1a00, 0x3262, 0x0000 }, + { 0x9a00, 0x3265, 0x2000 }, + { 0x1a00, 0x3264, 0x0000 }, + { 0x1a00, 0x3266, 0x0000 }, + { 0x9a00, 0x326b, 0x3000 }, + { 0x9a00, 0x3269, 0x2000 }, + { 0x1a00, 0x3268, 0x0000 }, + { 0x1a00, 0x326a, 0x0000 }, + { 0x9a00, 0x326d, 0x2000 }, + { 0x1a00, 0x326c, 0x0000 }, + { 0x1a00, 0x326e, 0x0000 }, + { 0x8f00, 0x3280, 0x5000 }, + { 0x9a00, 0x3277, 0x4000 }, + { 0x9a00, 0x3273, 0x3000 }, + { 0x9a00, 0x3271, 0x2000 }, + { 0x1a00, 0x3270, 0x0000 }, + { 0x1a00, 0x3272, 0x0000 }, + { 0x9a00, 0x3275, 0x2000 }, + { 0x1a00, 0x3274, 0x0000 }, + { 0x1a00, 0x3276, 0x0000 }, + { 0x9a00, 0x327b, 0x3000 }, + { 0x9a00, 0x3279, 0x2000 }, + { 0x1a00, 0x3278, 0x0000 }, + { 0x1a00, 0x327a, 0x0000 }, + { 0x9a00, 0x327d, 0x2000 }, + { 0x1a00, 0x327c, 0x0000 }, + { 0x1a00, 0x327f, 0x0000 }, + { 0x8f00, 0x3288, 0x4000 }, + { 0x8f00, 0x3284, 0x3000 }, + { 0x8f00, 0x3282, 0x2000 }, + { 0x0f00, 0x3281, 0x0000 }, + { 0x0f00, 0x3283, 0x0000 }, + { 0x8f00, 0x3286, 0x2000 }, + { 0x0f00, 0x3285, 0x0000 }, + { 0x0f00, 0x3287, 0x0000 }, + { 0x9a00, 0x328c, 0x3000 }, + { 0x9a00, 0x328a, 0x2000 }, + { 0x0f00, 0x3289, 0x0000 }, + { 0x1a00, 0x328b, 0x0000 }, + { 0x9a00, 0x328e, 0x2000 }, + { 0x1a00, 0x328d, 0x0000 }, + { 0x1a00, 0x328f, 0x0000 }, + { 0x9a00, 0x3311, 0x8000 }, + { 0x9a00, 0x32d0, 0x7000 }, + { 0x9a00, 0x32b0, 0x6000 }, + { 0x9a00, 0x32a0, 0x5000 }, + { 0x9a00, 0x3298, 0x4000 }, + { 0x9a00, 0x3294, 0x3000 }, + { 0x9a00, 0x3292, 0x2000 }, + { 0x1a00, 0x3291, 0x0000 }, + { 0x1a00, 0x3293, 0x0000 }, + { 0x9a00, 0x3296, 0x2000 }, + { 0x1a00, 0x3295, 0x0000 }, + { 0x1a00, 0x3297, 0x0000 }, + { 0x9a00, 0x329c, 0x3000 }, + { 0x9a00, 0x329a, 0x2000 }, + { 0x1a00, 0x3299, 0x0000 }, + { 0x1a00, 0x329b, 0x0000 }, + { 0x9a00, 0x329e, 0x2000 }, + { 0x1a00, 0x329d, 0x0000 }, + { 0x1a00, 0x329f, 0x0000 }, + { 0x9a00, 0x32a8, 0x4000 }, + { 0x9a00, 0x32a4, 0x3000 }, + { 0x9a00, 0x32a2, 0x2000 }, + { 0x1a00, 0x32a1, 0x0000 }, + { 0x1a00, 0x32a3, 0x0000 }, + { 0x9a00, 0x32a6, 0x2000 }, + { 0x1a00, 0x32a5, 0x0000 }, + { 0x1a00, 0x32a7, 0x0000 }, + { 0x9a00, 0x32ac, 0x3000 }, + { 0x9a00, 0x32aa, 0x2000 }, + { 0x1a00, 0x32a9, 0x0000 }, + { 0x1a00, 0x32ab, 0x0000 }, + { 0x9a00, 0x32ae, 0x2000 }, + { 0x1a00, 0x32ad, 0x0000 }, + { 0x1a00, 0x32af, 0x0000 }, + { 0x9a00, 0x32c0, 0x5000 }, + { 0x8f00, 0x32b8, 0x4000 }, + { 0x8f00, 0x32b4, 0x3000 }, + { 0x8f00, 0x32b2, 0x2000 }, + { 0x0f00, 0x32b1, 0x0000 }, + { 0x0f00, 0x32b3, 0x0000 }, + { 0x8f00, 0x32b6, 0x2000 }, + { 0x0f00, 0x32b5, 0x0000 }, + { 0x0f00, 0x32b7, 0x0000 }, + { 0x8f00, 0x32bc, 0x3000 }, + { 0x8f00, 0x32ba, 0x2000 }, + { 0x0f00, 0x32b9, 0x0000 }, + { 0x0f00, 0x32bb, 0x0000 }, + { 0x8f00, 0x32be, 0x2000 }, + { 0x0f00, 0x32bd, 0x0000 }, + { 0x0f00, 0x32bf, 0x0000 }, + { 0x9a00, 0x32c8, 0x4000 }, + { 0x9a00, 0x32c4, 0x3000 }, + { 0x9a00, 0x32c2, 0x2000 }, + { 0x1a00, 0x32c1, 0x0000 }, + { 0x1a00, 0x32c3, 0x0000 }, + { 0x9a00, 0x32c6, 0x2000 }, + { 0x1a00, 0x32c5, 0x0000 }, + { 0x1a00, 0x32c7, 0x0000 }, + { 0x9a00, 0x32cc, 0x3000 }, + { 0x9a00, 0x32ca, 0x2000 }, + { 0x1a00, 0x32c9, 0x0000 }, + { 0x1a00, 0x32cb, 0x0000 }, + { 0x9a00, 0x32ce, 0x2000 }, + { 0x1a00, 0x32cd, 0x0000 }, + { 0x1a00, 0x32cf, 0x0000 }, + { 0x9a00, 0x32f0, 0x6000 }, + { 0x9a00, 0x32e0, 0x5000 }, + { 0x9a00, 0x32d8, 0x4000 }, + { 0x9a00, 0x32d4, 0x3000 }, + { 0x9a00, 0x32d2, 0x2000 }, + { 0x1a00, 0x32d1, 0x0000 }, + { 0x1a00, 0x32d3, 0x0000 }, + { 0x9a00, 0x32d6, 0x2000 }, + { 0x1a00, 0x32d5, 0x0000 }, + { 0x1a00, 0x32d7, 0x0000 }, + { 0x9a00, 0x32dc, 0x3000 }, + { 0x9a00, 0x32da, 0x2000 }, + { 0x1a00, 0x32d9, 0x0000 }, + { 0x1a00, 0x32db, 0x0000 }, + { 0x9a00, 0x32de, 0x2000 }, + { 0x1a00, 0x32dd, 0x0000 }, + { 0x1a00, 0x32df, 0x0000 }, + { 0x9a00, 0x32e8, 0x4000 }, + { 0x9a00, 0x32e4, 0x3000 }, + { 0x9a00, 0x32e2, 0x2000 }, + { 0x1a00, 0x32e1, 0x0000 }, + { 0x1a00, 0x32e3, 0x0000 }, + { 0x9a00, 0x32e6, 0x2000 }, + { 0x1a00, 0x32e5, 0x0000 }, + { 0x1a00, 0x32e7, 0x0000 }, + { 0x9a00, 0x32ec, 0x3000 }, + { 0x9a00, 0x32ea, 0x2000 }, + { 0x1a00, 0x32e9, 0x0000 }, + { 0x1a00, 0x32eb, 0x0000 }, + { 0x9a00, 0x32ee, 0x2000 }, + { 0x1a00, 0x32ed, 0x0000 }, + { 0x1a00, 0x32ef, 0x0000 }, + { 0x9a00, 0x3301, 0x5000 }, + { 0x9a00, 0x32f8, 0x4000 }, + { 0x9a00, 0x32f4, 0x3000 }, + { 0x9a00, 0x32f2, 0x2000 }, + { 0x1a00, 0x32f1, 0x0000 }, + { 0x1a00, 0x32f3, 0x0000 }, + { 0x9a00, 0x32f6, 0x2000 }, + { 0x1a00, 0x32f5, 0x0000 }, + { 0x1a00, 0x32f7, 0x0000 }, + { 0x9a00, 0x32fc, 0x3000 }, + { 0x9a00, 0x32fa, 0x2000 }, + { 0x1a00, 0x32f9, 0x0000 }, + { 0x1a00, 0x32fb, 0x0000 }, + { 0x9a00, 0x32fe, 0x2000 }, + { 0x1a00, 0x32fd, 0x0000 }, + { 0x1a00, 0x3300, 0x0000 }, + { 0x9a00, 0x3309, 0x4000 }, + { 0x9a00, 0x3305, 0x3000 }, + { 0x9a00, 0x3303, 0x2000 }, + { 0x1a00, 0x3302, 0x0000 }, + { 0x1a00, 0x3304, 0x0000 }, + { 0x9a00, 0x3307, 0x2000 }, + { 0x1a00, 0x3306, 0x0000 }, + { 0x1a00, 0x3308, 0x0000 }, + { 0x9a00, 0x330d, 0x3000 }, + { 0x9a00, 0x330b, 0x2000 }, + { 0x1a00, 0x330a, 0x0000 }, + { 0x1a00, 0x330c, 0x0000 }, + { 0x9a00, 0x330f, 0x2000 }, + { 0x1a00, 0x330e, 0x0000 }, + { 0x1a00, 0x3310, 0x0000 }, + { 0x9a00, 0x3351, 0x7000 }, + { 0x9a00, 0x3331, 0x6000 }, + { 0x9a00, 0x3321, 0x5000 }, + { 0x9a00, 0x3319, 0x4000 }, + { 0x9a00, 0x3315, 0x3000 }, + { 0x9a00, 0x3313, 0x2000 }, + { 0x1a00, 0x3312, 0x0000 }, + { 0x1a00, 0x3314, 0x0000 }, + { 0x9a00, 0x3317, 0x2000 }, + { 0x1a00, 0x3316, 0x0000 }, + { 0x1a00, 0x3318, 0x0000 }, + { 0x9a00, 0x331d, 0x3000 }, + { 0x9a00, 0x331b, 0x2000 }, + { 0x1a00, 0x331a, 0x0000 }, + { 0x1a00, 0x331c, 0x0000 }, + { 0x9a00, 0x331f, 0x2000 }, + { 0x1a00, 0x331e, 0x0000 }, + { 0x1a00, 0x3320, 0x0000 }, + { 0x9a00, 0x3329, 0x4000 }, + { 0x9a00, 0x3325, 0x3000 }, + { 0x9a00, 0x3323, 0x2000 }, + { 0x1a00, 0x3322, 0x0000 }, + { 0x1a00, 0x3324, 0x0000 }, + { 0x9a00, 0x3327, 0x2000 }, + { 0x1a00, 0x3326, 0x0000 }, + { 0x1a00, 0x3328, 0x0000 }, + { 0x9a00, 0x332d, 0x3000 }, + { 0x9a00, 0x332b, 0x2000 }, + { 0x1a00, 0x332a, 0x0000 }, + { 0x1a00, 0x332c, 0x0000 }, + { 0x9a00, 0x332f, 0x2000 }, + { 0x1a00, 0x332e, 0x0000 }, + { 0x1a00, 0x3330, 0x0000 }, + { 0x9a00, 0x3341, 0x5000 }, + { 0x9a00, 0x3339, 0x4000 }, + { 0x9a00, 0x3335, 0x3000 }, + { 0x9a00, 0x3333, 0x2000 }, + { 0x1a00, 0x3332, 0x0000 }, + { 0x1a00, 0x3334, 0x0000 }, + { 0x9a00, 0x3337, 0x2000 }, + { 0x1a00, 0x3336, 0x0000 }, + { 0x1a00, 0x3338, 0x0000 }, + { 0x9a00, 0x333d, 0x3000 }, + { 0x9a00, 0x333b, 0x2000 }, + { 0x1a00, 0x333a, 0x0000 }, + { 0x1a00, 0x333c, 0x0000 }, + { 0x9a00, 0x333f, 0x2000 }, + { 0x1a00, 0x333e, 0x0000 }, + { 0x1a00, 0x3340, 0x0000 }, + { 0x9a00, 0x3349, 0x4000 }, + { 0x9a00, 0x3345, 0x3000 }, + { 0x9a00, 0x3343, 0x2000 }, + { 0x1a00, 0x3342, 0x0000 }, + { 0x1a00, 0x3344, 0x0000 }, + { 0x9a00, 0x3347, 0x2000 }, + { 0x1a00, 0x3346, 0x0000 }, + { 0x1a00, 0x3348, 0x0000 }, + { 0x9a00, 0x334d, 0x3000 }, + { 0x9a00, 0x334b, 0x2000 }, + { 0x1a00, 0x334a, 0x0000 }, + { 0x1a00, 0x334c, 0x0000 }, + { 0x9a00, 0x334f, 0x2000 }, + { 0x1a00, 0x334e, 0x0000 }, + { 0x1a00, 0x3350, 0x0000 }, + { 0x9a00, 0x3371, 0x6000 }, + { 0x9a00, 0x3361, 0x5000 }, + { 0x9a00, 0x3359, 0x4000 }, + { 0x9a00, 0x3355, 0x3000 }, + { 0x9a00, 0x3353, 0x2000 }, + { 0x1a00, 0x3352, 0x0000 }, + { 0x1a00, 0x3354, 0x0000 }, + { 0x9a00, 0x3357, 0x2000 }, + { 0x1a00, 0x3356, 0x0000 }, + { 0x1a00, 0x3358, 0x0000 }, + { 0x9a00, 0x335d, 0x3000 }, + { 0x9a00, 0x335b, 0x2000 }, + { 0x1a00, 0x335a, 0x0000 }, + { 0x1a00, 0x335c, 0x0000 }, + { 0x9a00, 0x335f, 0x2000 }, + { 0x1a00, 0x335e, 0x0000 }, + { 0x1a00, 0x3360, 0x0000 }, + { 0x9a00, 0x3369, 0x4000 }, + { 0x9a00, 0x3365, 0x3000 }, + { 0x9a00, 0x3363, 0x2000 }, + { 0x1a00, 0x3362, 0x0000 }, + { 0x1a00, 0x3364, 0x0000 }, + { 0x9a00, 0x3367, 0x2000 }, + { 0x1a00, 0x3366, 0x0000 }, + { 0x1a00, 0x3368, 0x0000 }, + { 0x9a00, 0x336d, 0x3000 }, + { 0x9a00, 0x336b, 0x2000 }, + { 0x1a00, 0x336a, 0x0000 }, + { 0x1a00, 0x336c, 0x0000 }, + { 0x9a00, 0x336f, 0x2000 }, + { 0x1a00, 0x336e, 0x0000 }, + { 0x1a00, 0x3370, 0x0000 }, + { 0x9a00, 0x3381, 0x5000 }, + { 0x9a00, 0x3379, 0x4000 }, + { 0x9a00, 0x3375, 0x3000 }, + { 0x9a00, 0x3373, 0x2000 }, + { 0x1a00, 0x3372, 0x0000 }, + { 0x1a00, 0x3374, 0x0000 }, + { 0x9a00, 0x3377, 0x2000 }, + { 0x1a00, 0x3376, 0x0000 }, + { 0x1a00, 0x3378, 0x0000 }, + { 0x9a00, 0x337d, 0x3000 }, + { 0x9a00, 0x337b, 0x2000 }, + { 0x1a00, 0x337a, 0x0000 }, + { 0x1a00, 0x337c, 0x0000 }, + { 0x9a00, 0x337f, 0x2000 }, + { 0x1a00, 0x337e, 0x0000 }, + { 0x1a00, 0x3380, 0x0000 }, + { 0x9a00, 0x3389, 0x4000 }, + { 0x9a00, 0x3385, 0x3000 }, + { 0x9a00, 0x3383, 0x2000 }, + { 0x1a00, 0x3382, 0x0000 }, + { 0x1a00, 0x3384, 0x0000 }, + { 0x9a00, 0x3387, 0x2000 }, + { 0x1a00, 0x3386, 0x0000 }, + { 0x1a00, 0x3388, 0x0000 }, + { 0x9a00, 0x338d, 0x3000 }, + { 0x9a00, 0x338b, 0x2000 }, + { 0x1a00, 0x338a, 0x0000 }, + { 0x1a00, 0x338c, 0x0000 }, + { 0x9a00, 0x338f, 0x2000 }, + { 0x1a00, 0x338e, 0x0000 }, + { 0x1a00, 0x3390, 0x0000 }, + { 0x8700, 0xa14d, 0xa000 }, + { 0x8700, 0xa04d, 0x9000 }, + { 0x9a00, 0x4dcf, 0x8000 }, + { 0x9a00, 0x33d1, 0x7000 }, + { 0x9a00, 0x33b1, 0x6000 }, + { 0x9a00, 0x33a1, 0x5000 }, + { 0x9a00, 0x3399, 0x4000 }, + { 0x9a00, 0x3395, 0x3000 }, + { 0x9a00, 0x3393, 0x2000 }, + { 0x1a00, 0x3392, 0x0000 }, + { 0x1a00, 0x3394, 0x0000 }, + { 0x9a00, 0x3397, 0x2000 }, + { 0x1a00, 0x3396, 0x0000 }, + { 0x1a00, 0x3398, 0x0000 }, + { 0x9a00, 0x339d, 0x3000 }, + { 0x9a00, 0x339b, 0x2000 }, + { 0x1a00, 0x339a, 0x0000 }, + { 0x1a00, 0x339c, 0x0000 }, + { 0x9a00, 0x339f, 0x2000 }, + { 0x1a00, 0x339e, 0x0000 }, + { 0x1a00, 0x33a0, 0x0000 }, + { 0x9a00, 0x33a9, 0x4000 }, + { 0x9a00, 0x33a5, 0x3000 }, + { 0x9a00, 0x33a3, 0x2000 }, + { 0x1a00, 0x33a2, 0x0000 }, + { 0x1a00, 0x33a4, 0x0000 }, + { 0x9a00, 0x33a7, 0x2000 }, + { 0x1a00, 0x33a6, 0x0000 }, + { 0x1a00, 0x33a8, 0x0000 }, + { 0x9a00, 0x33ad, 0x3000 }, + { 0x9a00, 0x33ab, 0x2000 }, + { 0x1a00, 0x33aa, 0x0000 }, + { 0x1a00, 0x33ac, 0x0000 }, + { 0x9a00, 0x33af, 0x2000 }, + { 0x1a00, 0x33ae, 0x0000 }, + { 0x1a00, 0x33b0, 0x0000 }, + { 0x9a00, 0x33c1, 0x5000 }, + { 0x9a00, 0x33b9, 0x4000 }, + { 0x9a00, 0x33b5, 0x3000 }, + { 0x9a00, 0x33b3, 0x2000 }, + { 0x1a00, 0x33b2, 0x0000 }, + { 0x1a00, 0x33b4, 0x0000 }, + { 0x9a00, 0x33b7, 0x2000 }, + { 0x1a00, 0x33b6, 0x0000 }, + { 0x1a00, 0x33b8, 0x0000 }, + { 0x9a00, 0x33bd, 0x3000 }, + { 0x9a00, 0x33bb, 0x2000 }, + { 0x1a00, 0x33ba, 0x0000 }, + { 0x1a00, 0x33bc, 0x0000 }, + { 0x9a00, 0x33bf, 0x2000 }, + { 0x1a00, 0x33be, 0x0000 }, + { 0x1a00, 0x33c0, 0x0000 }, + { 0x9a00, 0x33c9, 0x4000 }, + { 0x9a00, 0x33c5, 0x3000 }, + { 0x9a00, 0x33c3, 0x2000 }, + { 0x1a00, 0x33c2, 0x0000 }, + { 0x1a00, 0x33c4, 0x0000 }, + { 0x9a00, 0x33c7, 0x2000 }, + { 0x1a00, 0x33c6, 0x0000 }, + { 0x1a00, 0x33c8, 0x0000 }, + { 0x9a00, 0x33cd, 0x3000 }, + { 0x9a00, 0x33cb, 0x2000 }, + { 0x1a00, 0x33ca, 0x0000 }, + { 0x1a00, 0x33cc, 0x0000 }, + { 0x9a00, 0x33cf, 0x2000 }, + { 0x1a00, 0x33ce, 0x0000 }, + { 0x1a00, 0x33d0, 0x0000 }, + { 0x9a00, 0x33f1, 0x6000 }, + { 0x9a00, 0x33e1, 0x5000 }, + { 0x9a00, 0x33d9, 0x4000 }, + { 0x9a00, 0x33d5, 0x3000 }, + { 0x9a00, 0x33d3, 0x2000 }, + { 0x1a00, 0x33d2, 0x0000 }, + { 0x1a00, 0x33d4, 0x0000 }, + { 0x9a00, 0x33d7, 0x2000 }, + { 0x1a00, 0x33d6, 0x0000 }, + { 0x1a00, 0x33d8, 0x0000 }, + { 0x9a00, 0x33dd, 0x3000 }, + { 0x9a00, 0x33db, 0x2000 }, + { 0x1a00, 0x33da, 0x0000 }, + { 0x1a00, 0x33dc, 0x0000 }, + { 0x9a00, 0x33df, 0x2000 }, + { 0x1a00, 0x33de, 0x0000 }, + { 0x1a00, 0x33e0, 0x0000 }, + { 0x9a00, 0x33e9, 0x4000 }, + { 0x9a00, 0x33e5, 0x3000 }, + { 0x9a00, 0x33e3, 0x2000 }, + { 0x1a00, 0x33e2, 0x0000 }, + { 0x1a00, 0x33e4, 0x0000 }, + { 0x9a00, 0x33e7, 0x2000 }, + { 0x1a00, 0x33e6, 0x0000 }, + { 0x1a00, 0x33e8, 0x0000 }, + { 0x9a00, 0x33ed, 0x3000 }, + { 0x9a00, 0x33eb, 0x2000 }, + { 0x1a00, 0x33ea, 0x0000 }, + { 0x1a00, 0x33ec, 0x0000 }, + { 0x9a00, 0x33ef, 0x2000 }, + { 0x1a00, 0x33ee, 0x0000 }, + { 0x1a00, 0x33f0, 0x0000 }, + { 0x8700, 0x4db5, 0x5000 }, + { 0x9a00, 0x33f9, 0x4000 }, + { 0x9a00, 0x33f5, 0x3000 }, + { 0x9a00, 0x33f3, 0x2000 }, + { 0x1a00, 0x33f2, 0x0000 }, + { 0x1a00, 0x33f4, 0x0000 }, + { 0x9a00, 0x33f7, 0x2000 }, + { 0x1a00, 0x33f6, 0x0000 }, + { 0x1a00, 0x33f8, 0x0000 }, + { 0x9a00, 0x33fd, 0x3000 }, + { 0x9a00, 0x33fb, 0x2000 }, + { 0x1a00, 0x33fa, 0x0000 }, + { 0x1a00, 0x33fc, 0x0000 }, + { 0x9a00, 0x33ff, 0x2000 }, + { 0x1a00, 0x33fe, 0x0000 }, + { 0x0700, 0x3400, 0x0000 }, + { 0x9a00, 0x4dc7, 0x4000 }, + { 0x9a00, 0x4dc3, 0x3000 }, + { 0x9a00, 0x4dc1, 0x2000 }, + { 0x1a00, 0x4dc0, 0x0000 }, + { 0x1a00, 0x4dc2, 0x0000 }, + { 0x9a00, 0x4dc5, 0x2000 }, + { 0x1a00, 0x4dc4, 0x0000 }, + { 0x1a00, 0x4dc6, 0x0000 }, + { 0x9a00, 0x4dcb, 0x3000 }, + { 0x9a00, 0x4dc9, 0x2000 }, + { 0x1a00, 0x4dc8, 0x0000 }, + { 0x1a00, 0x4dca, 0x0000 }, + { 0x9a00, 0x4dcd, 0x2000 }, + { 0x1a00, 0x4dcc, 0x0000 }, + { 0x1a00, 0x4dce, 0x0000 }, + { 0x8700, 0xa00d, 0x7000 }, + { 0x9a00, 0x4def, 0x6000 }, + { 0x9a00, 0x4ddf, 0x5000 }, + { 0x9a00, 0x4dd7, 0x4000 }, + { 0x9a00, 0x4dd3, 0x3000 }, + { 0x9a00, 0x4dd1, 0x2000 }, + { 0x1a00, 0x4dd0, 0x0000 }, + { 0x1a00, 0x4dd2, 0x0000 }, + { 0x9a00, 0x4dd5, 0x2000 }, + { 0x1a00, 0x4dd4, 0x0000 }, + { 0x1a00, 0x4dd6, 0x0000 }, + { 0x9a00, 0x4ddb, 0x3000 }, + { 0x9a00, 0x4dd9, 0x2000 }, + { 0x1a00, 0x4dd8, 0x0000 }, + { 0x1a00, 0x4dda, 0x0000 }, + { 0x9a00, 0x4ddd, 0x2000 }, + { 0x1a00, 0x4ddc, 0x0000 }, + { 0x1a00, 0x4dde, 0x0000 }, + { 0x9a00, 0x4de7, 0x4000 }, + { 0x9a00, 0x4de3, 0x3000 }, + { 0x9a00, 0x4de1, 0x2000 }, + { 0x1a00, 0x4de0, 0x0000 }, + { 0x1a00, 0x4de2, 0x0000 }, + { 0x9a00, 0x4de5, 0x2000 }, + { 0x1a00, 0x4de4, 0x0000 }, + { 0x1a00, 0x4de6, 0x0000 }, + { 0x9a00, 0x4deb, 0x3000 }, + { 0x9a00, 0x4de9, 0x2000 }, + { 0x1a00, 0x4de8, 0x0000 }, + { 0x1a00, 0x4dea, 0x0000 }, + { 0x9a00, 0x4ded, 0x2000 }, + { 0x1a00, 0x4dec, 0x0000 }, + { 0x1a00, 0x4dee, 0x0000 }, + { 0x9a00, 0x4dff, 0x5000 }, + { 0x9a00, 0x4df7, 0x4000 }, + { 0x9a00, 0x4df3, 0x3000 }, + { 0x9a00, 0x4df1, 0x2000 }, + { 0x1a00, 0x4df0, 0x0000 }, + { 0x1a00, 0x4df2, 0x0000 }, + { 0x9a00, 0x4df5, 0x2000 }, + { 0x1a00, 0x4df4, 0x0000 }, + { 0x1a00, 0x4df6, 0x0000 }, + { 0x9a00, 0x4dfb, 0x3000 }, + { 0x9a00, 0x4df9, 0x2000 }, + { 0x1a00, 0x4df8, 0x0000 }, + { 0x1a00, 0x4dfa, 0x0000 }, + { 0x9a00, 0x4dfd, 0x2000 }, + { 0x1a00, 0x4dfc, 0x0000 }, + { 0x1a00, 0x4dfe, 0x0000 }, + { 0x8700, 0xa005, 0x4000 }, + { 0x8700, 0xa001, 0x3000 }, + { 0x8700, 0x9fa5, 0x2000 }, + { 0x0700, 0x4e00, 0x0000 }, + { 0x0700, 0xa000, 0x0000 }, + { 0x8700, 0xa003, 0x2000 }, + { 0x0700, 0xa002, 0x0000 }, + { 0x0700, 0xa004, 0x0000 }, + { 0x8700, 0xa009, 0x3000 }, + { 0x8700, 0xa007, 0x2000 }, + { 0x0700, 0xa006, 0x0000 }, + { 0x0700, 0xa008, 0x0000 }, + { 0x8700, 0xa00b, 0x2000 }, + { 0x0700, 0xa00a, 0x0000 }, + { 0x0700, 0xa00c, 0x0000 }, + { 0x8700, 0xa02d, 0x6000 }, + { 0x8700, 0xa01d, 0x5000 }, + { 0x8700, 0xa015, 0x4000 }, + { 0x8700, 0xa011, 0x3000 }, + { 0x8700, 0xa00f, 0x2000 }, + { 0x0700, 0xa00e, 0x0000 }, + { 0x0700, 0xa010, 0x0000 }, + { 0x8700, 0xa013, 0x2000 }, + { 0x0700, 0xa012, 0x0000 }, + { 0x0700, 0xa014, 0x0000 }, + { 0x8700, 0xa019, 0x3000 }, + { 0x8700, 0xa017, 0x2000 }, + { 0x0700, 0xa016, 0x0000 }, + { 0x0700, 0xa018, 0x0000 }, + { 0x8700, 0xa01b, 0x2000 }, + { 0x0700, 0xa01a, 0x0000 }, + { 0x0700, 0xa01c, 0x0000 }, + { 0x8700, 0xa025, 0x4000 }, + { 0x8700, 0xa021, 0x3000 }, + { 0x8700, 0xa01f, 0x2000 }, + { 0x0700, 0xa01e, 0x0000 }, + { 0x0700, 0xa020, 0x0000 }, + { 0x8700, 0xa023, 0x2000 }, + { 0x0700, 0xa022, 0x0000 }, + { 0x0700, 0xa024, 0x0000 }, + { 0x8700, 0xa029, 0x3000 }, + { 0x8700, 0xa027, 0x2000 }, + { 0x0700, 0xa026, 0x0000 }, + { 0x0700, 0xa028, 0x0000 }, + { 0x8700, 0xa02b, 0x2000 }, + { 0x0700, 0xa02a, 0x0000 }, + { 0x0700, 0xa02c, 0x0000 }, + { 0x8700, 0xa03d, 0x5000 }, + { 0x8700, 0xa035, 0x4000 }, + { 0x8700, 0xa031, 0x3000 }, + { 0x8700, 0xa02f, 0x2000 }, + { 0x0700, 0xa02e, 0x0000 }, + { 0x0700, 0xa030, 0x0000 }, + { 0x8700, 0xa033, 0x2000 }, + { 0x0700, 0xa032, 0x0000 }, + { 0x0700, 0xa034, 0x0000 }, + { 0x8700, 0xa039, 0x3000 }, + { 0x8700, 0xa037, 0x2000 }, + { 0x0700, 0xa036, 0x0000 }, + { 0x0700, 0xa038, 0x0000 }, + { 0x8700, 0xa03b, 0x2000 }, + { 0x0700, 0xa03a, 0x0000 }, + { 0x0700, 0xa03c, 0x0000 }, + { 0x8700, 0xa045, 0x4000 }, + { 0x8700, 0xa041, 0x3000 }, + { 0x8700, 0xa03f, 0x2000 }, + { 0x0700, 0xa03e, 0x0000 }, + { 0x0700, 0xa040, 0x0000 }, + { 0x8700, 0xa043, 0x2000 }, + { 0x0700, 0xa042, 0x0000 }, + { 0x0700, 0xa044, 0x0000 }, + { 0x8700, 0xa049, 0x3000 }, + { 0x8700, 0xa047, 0x2000 }, + { 0x0700, 0xa046, 0x0000 }, + { 0x0700, 0xa048, 0x0000 }, + { 0x8700, 0xa04b, 0x2000 }, + { 0x0700, 0xa04a, 0x0000 }, + { 0x0700, 0xa04c, 0x0000 }, + { 0x8700, 0xa0cd, 0x8000 }, + { 0x8700, 0xa08d, 0x7000 }, + { 0x8700, 0xa06d, 0x6000 }, + { 0x8700, 0xa05d, 0x5000 }, + { 0x8700, 0xa055, 0x4000 }, + { 0x8700, 0xa051, 0x3000 }, + { 0x8700, 0xa04f, 0x2000 }, + { 0x0700, 0xa04e, 0x0000 }, + { 0x0700, 0xa050, 0x0000 }, + { 0x8700, 0xa053, 0x2000 }, + { 0x0700, 0xa052, 0x0000 }, + { 0x0700, 0xa054, 0x0000 }, + { 0x8700, 0xa059, 0x3000 }, + { 0x8700, 0xa057, 0x2000 }, + { 0x0700, 0xa056, 0x0000 }, + { 0x0700, 0xa058, 0x0000 }, + { 0x8700, 0xa05b, 0x2000 }, + { 0x0700, 0xa05a, 0x0000 }, + { 0x0700, 0xa05c, 0x0000 }, + { 0x8700, 0xa065, 0x4000 }, + { 0x8700, 0xa061, 0x3000 }, + { 0x8700, 0xa05f, 0x2000 }, + { 0x0700, 0xa05e, 0x0000 }, + { 0x0700, 0xa060, 0x0000 }, + { 0x8700, 0xa063, 0x2000 }, + { 0x0700, 0xa062, 0x0000 }, + { 0x0700, 0xa064, 0x0000 }, + { 0x8700, 0xa069, 0x3000 }, + { 0x8700, 0xa067, 0x2000 }, + { 0x0700, 0xa066, 0x0000 }, + { 0x0700, 0xa068, 0x0000 }, + { 0x8700, 0xa06b, 0x2000 }, + { 0x0700, 0xa06a, 0x0000 }, + { 0x0700, 0xa06c, 0x0000 }, + { 0x8700, 0xa07d, 0x5000 }, + { 0x8700, 0xa075, 0x4000 }, + { 0x8700, 0xa071, 0x3000 }, + { 0x8700, 0xa06f, 0x2000 }, + { 0x0700, 0xa06e, 0x0000 }, + { 0x0700, 0xa070, 0x0000 }, + { 0x8700, 0xa073, 0x2000 }, + { 0x0700, 0xa072, 0x0000 }, + { 0x0700, 0xa074, 0x0000 }, + { 0x8700, 0xa079, 0x3000 }, + { 0x8700, 0xa077, 0x2000 }, + { 0x0700, 0xa076, 0x0000 }, + { 0x0700, 0xa078, 0x0000 }, + { 0x8700, 0xa07b, 0x2000 }, + { 0x0700, 0xa07a, 0x0000 }, + { 0x0700, 0xa07c, 0x0000 }, + { 0x8700, 0xa085, 0x4000 }, + { 0x8700, 0xa081, 0x3000 }, + { 0x8700, 0xa07f, 0x2000 }, + { 0x0700, 0xa07e, 0x0000 }, + { 0x0700, 0xa080, 0x0000 }, + { 0x8700, 0xa083, 0x2000 }, + { 0x0700, 0xa082, 0x0000 }, + { 0x0700, 0xa084, 0x0000 }, + { 0x8700, 0xa089, 0x3000 }, + { 0x8700, 0xa087, 0x2000 }, + { 0x0700, 0xa086, 0x0000 }, + { 0x0700, 0xa088, 0x0000 }, + { 0x8700, 0xa08b, 0x2000 }, + { 0x0700, 0xa08a, 0x0000 }, + { 0x0700, 0xa08c, 0x0000 }, + { 0x8700, 0xa0ad, 0x6000 }, + { 0x8700, 0xa09d, 0x5000 }, + { 0x8700, 0xa095, 0x4000 }, + { 0x8700, 0xa091, 0x3000 }, + { 0x8700, 0xa08f, 0x2000 }, + { 0x0700, 0xa08e, 0x0000 }, + { 0x0700, 0xa090, 0x0000 }, + { 0x8700, 0xa093, 0x2000 }, + { 0x0700, 0xa092, 0x0000 }, + { 0x0700, 0xa094, 0x0000 }, + { 0x8700, 0xa099, 0x3000 }, + { 0x8700, 0xa097, 0x2000 }, + { 0x0700, 0xa096, 0x0000 }, + { 0x0700, 0xa098, 0x0000 }, + { 0x8700, 0xa09b, 0x2000 }, + { 0x0700, 0xa09a, 0x0000 }, + { 0x0700, 0xa09c, 0x0000 }, + { 0x8700, 0xa0a5, 0x4000 }, + { 0x8700, 0xa0a1, 0x3000 }, + { 0x8700, 0xa09f, 0x2000 }, + { 0x0700, 0xa09e, 0x0000 }, + { 0x0700, 0xa0a0, 0x0000 }, + { 0x8700, 0xa0a3, 0x2000 }, + { 0x0700, 0xa0a2, 0x0000 }, + { 0x0700, 0xa0a4, 0x0000 }, + { 0x8700, 0xa0a9, 0x3000 }, + { 0x8700, 0xa0a7, 0x2000 }, + { 0x0700, 0xa0a6, 0x0000 }, + { 0x0700, 0xa0a8, 0x0000 }, + { 0x8700, 0xa0ab, 0x2000 }, + { 0x0700, 0xa0aa, 0x0000 }, + { 0x0700, 0xa0ac, 0x0000 }, + { 0x8700, 0xa0bd, 0x5000 }, + { 0x8700, 0xa0b5, 0x4000 }, + { 0x8700, 0xa0b1, 0x3000 }, + { 0x8700, 0xa0af, 0x2000 }, + { 0x0700, 0xa0ae, 0x0000 }, + { 0x0700, 0xa0b0, 0x0000 }, + { 0x8700, 0xa0b3, 0x2000 }, + { 0x0700, 0xa0b2, 0x0000 }, + { 0x0700, 0xa0b4, 0x0000 }, + { 0x8700, 0xa0b9, 0x3000 }, + { 0x8700, 0xa0b7, 0x2000 }, + { 0x0700, 0xa0b6, 0x0000 }, + { 0x0700, 0xa0b8, 0x0000 }, + { 0x8700, 0xa0bb, 0x2000 }, + { 0x0700, 0xa0ba, 0x0000 }, + { 0x0700, 0xa0bc, 0x0000 }, + { 0x8700, 0xa0c5, 0x4000 }, + { 0x8700, 0xa0c1, 0x3000 }, + { 0x8700, 0xa0bf, 0x2000 }, + { 0x0700, 0xa0be, 0x0000 }, + { 0x0700, 0xa0c0, 0x0000 }, + { 0x8700, 0xa0c3, 0x2000 }, + { 0x0700, 0xa0c2, 0x0000 }, + { 0x0700, 0xa0c4, 0x0000 }, + { 0x8700, 0xa0c9, 0x3000 }, + { 0x8700, 0xa0c7, 0x2000 }, + { 0x0700, 0xa0c6, 0x0000 }, + { 0x0700, 0xa0c8, 0x0000 }, + { 0x8700, 0xa0cb, 0x2000 }, + { 0x0700, 0xa0ca, 0x0000 }, + { 0x0700, 0xa0cc, 0x0000 }, + { 0x8700, 0xa10d, 0x7000 }, + { 0x8700, 0xa0ed, 0x6000 }, + { 0x8700, 0xa0dd, 0x5000 }, + { 0x8700, 0xa0d5, 0x4000 }, + { 0x8700, 0xa0d1, 0x3000 }, + { 0x8700, 0xa0cf, 0x2000 }, + { 0x0700, 0xa0ce, 0x0000 }, + { 0x0700, 0xa0d0, 0x0000 }, + { 0x8700, 0xa0d3, 0x2000 }, + { 0x0700, 0xa0d2, 0x0000 }, + { 0x0700, 0xa0d4, 0x0000 }, + { 0x8700, 0xa0d9, 0x3000 }, + { 0x8700, 0xa0d7, 0x2000 }, + { 0x0700, 0xa0d6, 0x0000 }, + { 0x0700, 0xa0d8, 0x0000 }, + { 0x8700, 0xa0db, 0x2000 }, + { 0x0700, 0xa0da, 0x0000 }, + { 0x0700, 0xa0dc, 0x0000 }, + { 0x8700, 0xa0e5, 0x4000 }, + { 0x8700, 0xa0e1, 0x3000 }, + { 0x8700, 0xa0df, 0x2000 }, + { 0x0700, 0xa0de, 0x0000 }, + { 0x0700, 0xa0e0, 0x0000 }, + { 0x8700, 0xa0e3, 0x2000 }, + { 0x0700, 0xa0e2, 0x0000 }, + { 0x0700, 0xa0e4, 0x0000 }, + { 0x8700, 0xa0e9, 0x3000 }, + { 0x8700, 0xa0e7, 0x2000 }, + { 0x0700, 0xa0e6, 0x0000 }, + { 0x0700, 0xa0e8, 0x0000 }, + { 0x8700, 0xa0eb, 0x2000 }, + { 0x0700, 0xa0ea, 0x0000 }, + { 0x0700, 0xa0ec, 0x0000 }, + { 0x8700, 0xa0fd, 0x5000 }, + { 0x8700, 0xa0f5, 0x4000 }, + { 0x8700, 0xa0f1, 0x3000 }, + { 0x8700, 0xa0ef, 0x2000 }, + { 0x0700, 0xa0ee, 0x0000 }, + { 0x0700, 0xa0f0, 0x0000 }, + { 0x8700, 0xa0f3, 0x2000 }, + { 0x0700, 0xa0f2, 0x0000 }, + { 0x0700, 0xa0f4, 0x0000 }, + { 0x8700, 0xa0f9, 0x3000 }, + { 0x8700, 0xa0f7, 0x2000 }, + { 0x0700, 0xa0f6, 0x0000 }, + { 0x0700, 0xa0f8, 0x0000 }, + { 0x8700, 0xa0fb, 0x2000 }, + { 0x0700, 0xa0fa, 0x0000 }, + { 0x0700, 0xa0fc, 0x0000 }, + { 0x8700, 0xa105, 0x4000 }, + { 0x8700, 0xa101, 0x3000 }, + { 0x8700, 0xa0ff, 0x2000 }, + { 0x0700, 0xa0fe, 0x0000 }, + { 0x0700, 0xa100, 0x0000 }, + { 0x8700, 0xa103, 0x2000 }, + { 0x0700, 0xa102, 0x0000 }, + { 0x0700, 0xa104, 0x0000 }, + { 0x8700, 0xa109, 0x3000 }, + { 0x8700, 0xa107, 0x2000 }, + { 0x0700, 0xa106, 0x0000 }, + { 0x0700, 0xa108, 0x0000 }, + { 0x8700, 0xa10b, 0x2000 }, + { 0x0700, 0xa10a, 0x0000 }, + { 0x0700, 0xa10c, 0x0000 }, + { 0x8700, 0xa12d, 0x6000 }, + { 0x8700, 0xa11d, 0x5000 }, + { 0x8700, 0xa115, 0x4000 }, + { 0x8700, 0xa111, 0x3000 }, + { 0x8700, 0xa10f, 0x2000 }, + { 0x0700, 0xa10e, 0x0000 }, + { 0x0700, 0xa110, 0x0000 }, + { 0x8700, 0xa113, 0x2000 }, + { 0x0700, 0xa112, 0x0000 }, + { 0x0700, 0xa114, 0x0000 }, + { 0x8700, 0xa119, 0x3000 }, + { 0x8700, 0xa117, 0x2000 }, + { 0x0700, 0xa116, 0x0000 }, + { 0x0700, 0xa118, 0x0000 }, + { 0x8700, 0xa11b, 0x2000 }, + { 0x0700, 0xa11a, 0x0000 }, + { 0x0700, 0xa11c, 0x0000 }, + { 0x8700, 0xa125, 0x4000 }, + { 0x8700, 0xa121, 0x3000 }, + { 0x8700, 0xa11f, 0x2000 }, + { 0x0700, 0xa11e, 0x0000 }, + { 0x0700, 0xa120, 0x0000 }, + { 0x8700, 0xa123, 0x2000 }, + { 0x0700, 0xa122, 0x0000 }, + { 0x0700, 0xa124, 0x0000 }, + { 0x8700, 0xa129, 0x3000 }, + { 0x8700, 0xa127, 0x2000 }, + { 0x0700, 0xa126, 0x0000 }, + { 0x0700, 0xa128, 0x0000 }, + { 0x8700, 0xa12b, 0x2000 }, + { 0x0700, 0xa12a, 0x0000 }, + { 0x0700, 0xa12c, 0x0000 }, + { 0x8700, 0xa13d, 0x5000 }, + { 0x8700, 0xa135, 0x4000 }, + { 0x8700, 0xa131, 0x3000 }, + { 0x8700, 0xa12f, 0x2000 }, + { 0x0700, 0xa12e, 0x0000 }, + { 0x0700, 0xa130, 0x0000 }, + { 0x8700, 0xa133, 0x2000 }, + { 0x0700, 0xa132, 0x0000 }, + { 0x0700, 0xa134, 0x0000 }, + { 0x8700, 0xa139, 0x3000 }, + { 0x8700, 0xa137, 0x2000 }, + { 0x0700, 0xa136, 0x0000 }, + { 0x0700, 0xa138, 0x0000 }, + { 0x8700, 0xa13b, 0x2000 }, + { 0x0700, 0xa13a, 0x0000 }, + { 0x0700, 0xa13c, 0x0000 }, + { 0x8700, 0xa145, 0x4000 }, + { 0x8700, 0xa141, 0x3000 }, + { 0x8700, 0xa13f, 0x2000 }, + { 0x0700, 0xa13e, 0x0000 }, + { 0x0700, 0xa140, 0x0000 }, + { 0x8700, 0xa143, 0x2000 }, + { 0x0700, 0xa142, 0x0000 }, + { 0x0700, 0xa144, 0x0000 }, + { 0x8700, 0xa149, 0x3000 }, + { 0x8700, 0xa147, 0x2000 }, + { 0x0700, 0xa146, 0x0000 }, + { 0x0700, 0xa148, 0x0000 }, + { 0x8700, 0xa14b, 0x2000 }, + { 0x0700, 0xa14a, 0x0000 }, + { 0x0700, 0xa14c, 0x0000 }, + { 0x8700, 0xa24d, 0x9000 }, + { 0x8700, 0xa1cd, 0x8000 }, + { 0x8700, 0xa18d, 0x7000 }, + { 0x8700, 0xa16d, 0x6000 }, + { 0x8700, 0xa15d, 0x5000 }, + { 0x8700, 0xa155, 0x4000 }, + { 0x8700, 0xa151, 0x3000 }, + { 0x8700, 0xa14f, 0x2000 }, + { 0x0700, 0xa14e, 0x0000 }, + { 0x0700, 0xa150, 0x0000 }, + { 0x8700, 0xa153, 0x2000 }, + { 0x0700, 0xa152, 0x0000 }, + { 0x0700, 0xa154, 0x0000 }, + { 0x8700, 0xa159, 0x3000 }, + { 0x8700, 0xa157, 0x2000 }, + { 0x0700, 0xa156, 0x0000 }, + { 0x0700, 0xa158, 0x0000 }, + { 0x8700, 0xa15b, 0x2000 }, + { 0x0700, 0xa15a, 0x0000 }, + { 0x0700, 0xa15c, 0x0000 }, + { 0x8700, 0xa165, 0x4000 }, + { 0x8700, 0xa161, 0x3000 }, + { 0x8700, 0xa15f, 0x2000 }, + { 0x0700, 0xa15e, 0x0000 }, + { 0x0700, 0xa160, 0x0000 }, + { 0x8700, 0xa163, 0x2000 }, + { 0x0700, 0xa162, 0x0000 }, + { 0x0700, 0xa164, 0x0000 }, + { 0x8700, 0xa169, 0x3000 }, + { 0x8700, 0xa167, 0x2000 }, + { 0x0700, 0xa166, 0x0000 }, + { 0x0700, 0xa168, 0x0000 }, + { 0x8700, 0xa16b, 0x2000 }, + { 0x0700, 0xa16a, 0x0000 }, + { 0x0700, 0xa16c, 0x0000 }, + { 0x8700, 0xa17d, 0x5000 }, + { 0x8700, 0xa175, 0x4000 }, + { 0x8700, 0xa171, 0x3000 }, + { 0x8700, 0xa16f, 0x2000 }, + { 0x0700, 0xa16e, 0x0000 }, + { 0x0700, 0xa170, 0x0000 }, + { 0x8700, 0xa173, 0x2000 }, + { 0x0700, 0xa172, 0x0000 }, + { 0x0700, 0xa174, 0x0000 }, + { 0x8700, 0xa179, 0x3000 }, + { 0x8700, 0xa177, 0x2000 }, + { 0x0700, 0xa176, 0x0000 }, + { 0x0700, 0xa178, 0x0000 }, + { 0x8700, 0xa17b, 0x2000 }, + { 0x0700, 0xa17a, 0x0000 }, + { 0x0700, 0xa17c, 0x0000 }, + { 0x8700, 0xa185, 0x4000 }, + { 0x8700, 0xa181, 0x3000 }, + { 0x8700, 0xa17f, 0x2000 }, + { 0x0700, 0xa17e, 0x0000 }, + { 0x0700, 0xa180, 0x0000 }, + { 0x8700, 0xa183, 0x2000 }, + { 0x0700, 0xa182, 0x0000 }, + { 0x0700, 0xa184, 0x0000 }, + { 0x8700, 0xa189, 0x3000 }, + { 0x8700, 0xa187, 0x2000 }, + { 0x0700, 0xa186, 0x0000 }, + { 0x0700, 0xa188, 0x0000 }, + { 0x8700, 0xa18b, 0x2000 }, + { 0x0700, 0xa18a, 0x0000 }, + { 0x0700, 0xa18c, 0x0000 }, + { 0x8700, 0xa1ad, 0x6000 }, + { 0x8700, 0xa19d, 0x5000 }, + { 0x8700, 0xa195, 0x4000 }, + { 0x8700, 0xa191, 0x3000 }, + { 0x8700, 0xa18f, 0x2000 }, + { 0x0700, 0xa18e, 0x0000 }, + { 0x0700, 0xa190, 0x0000 }, + { 0x8700, 0xa193, 0x2000 }, + { 0x0700, 0xa192, 0x0000 }, + { 0x0700, 0xa194, 0x0000 }, + { 0x8700, 0xa199, 0x3000 }, + { 0x8700, 0xa197, 0x2000 }, + { 0x0700, 0xa196, 0x0000 }, + { 0x0700, 0xa198, 0x0000 }, + { 0x8700, 0xa19b, 0x2000 }, + { 0x0700, 0xa19a, 0x0000 }, + { 0x0700, 0xa19c, 0x0000 }, + { 0x8700, 0xa1a5, 0x4000 }, + { 0x8700, 0xa1a1, 0x3000 }, + { 0x8700, 0xa19f, 0x2000 }, + { 0x0700, 0xa19e, 0x0000 }, + { 0x0700, 0xa1a0, 0x0000 }, + { 0x8700, 0xa1a3, 0x2000 }, + { 0x0700, 0xa1a2, 0x0000 }, + { 0x0700, 0xa1a4, 0x0000 }, + { 0x8700, 0xa1a9, 0x3000 }, + { 0x8700, 0xa1a7, 0x2000 }, + { 0x0700, 0xa1a6, 0x0000 }, + { 0x0700, 0xa1a8, 0x0000 }, + { 0x8700, 0xa1ab, 0x2000 }, + { 0x0700, 0xa1aa, 0x0000 }, + { 0x0700, 0xa1ac, 0x0000 }, + { 0x8700, 0xa1bd, 0x5000 }, + { 0x8700, 0xa1b5, 0x4000 }, + { 0x8700, 0xa1b1, 0x3000 }, + { 0x8700, 0xa1af, 0x2000 }, + { 0x0700, 0xa1ae, 0x0000 }, + { 0x0700, 0xa1b0, 0x0000 }, + { 0x8700, 0xa1b3, 0x2000 }, + { 0x0700, 0xa1b2, 0x0000 }, + { 0x0700, 0xa1b4, 0x0000 }, + { 0x8700, 0xa1b9, 0x3000 }, + { 0x8700, 0xa1b7, 0x2000 }, + { 0x0700, 0xa1b6, 0x0000 }, + { 0x0700, 0xa1b8, 0x0000 }, + { 0x8700, 0xa1bb, 0x2000 }, + { 0x0700, 0xa1ba, 0x0000 }, + { 0x0700, 0xa1bc, 0x0000 }, + { 0x8700, 0xa1c5, 0x4000 }, + { 0x8700, 0xa1c1, 0x3000 }, + { 0x8700, 0xa1bf, 0x2000 }, + { 0x0700, 0xa1be, 0x0000 }, + { 0x0700, 0xa1c0, 0x0000 }, + { 0x8700, 0xa1c3, 0x2000 }, + { 0x0700, 0xa1c2, 0x0000 }, + { 0x0700, 0xa1c4, 0x0000 }, + { 0x8700, 0xa1c9, 0x3000 }, + { 0x8700, 0xa1c7, 0x2000 }, + { 0x0700, 0xa1c6, 0x0000 }, + { 0x0700, 0xa1c8, 0x0000 }, + { 0x8700, 0xa1cb, 0x2000 }, + { 0x0700, 0xa1ca, 0x0000 }, + { 0x0700, 0xa1cc, 0x0000 }, + { 0x8700, 0xa20d, 0x7000 }, + { 0x8700, 0xa1ed, 0x6000 }, + { 0x8700, 0xa1dd, 0x5000 }, + { 0x8700, 0xa1d5, 0x4000 }, + { 0x8700, 0xa1d1, 0x3000 }, + { 0x8700, 0xa1cf, 0x2000 }, + { 0x0700, 0xa1ce, 0x0000 }, + { 0x0700, 0xa1d0, 0x0000 }, + { 0x8700, 0xa1d3, 0x2000 }, + { 0x0700, 0xa1d2, 0x0000 }, + { 0x0700, 0xa1d4, 0x0000 }, + { 0x8700, 0xa1d9, 0x3000 }, + { 0x8700, 0xa1d7, 0x2000 }, + { 0x0700, 0xa1d6, 0x0000 }, + { 0x0700, 0xa1d8, 0x0000 }, + { 0x8700, 0xa1db, 0x2000 }, + { 0x0700, 0xa1da, 0x0000 }, + { 0x0700, 0xa1dc, 0x0000 }, + { 0x8700, 0xa1e5, 0x4000 }, + { 0x8700, 0xa1e1, 0x3000 }, + { 0x8700, 0xa1df, 0x2000 }, + { 0x0700, 0xa1de, 0x0000 }, + { 0x0700, 0xa1e0, 0x0000 }, + { 0x8700, 0xa1e3, 0x2000 }, + { 0x0700, 0xa1e2, 0x0000 }, + { 0x0700, 0xa1e4, 0x0000 }, + { 0x8700, 0xa1e9, 0x3000 }, + { 0x8700, 0xa1e7, 0x2000 }, + { 0x0700, 0xa1e6, 0x0000 }, + { 0x0700, 0xa1e8, 0x0000 }, + { 0x8700, 0xa1eb, 0x2000 }, + { 0x0700, 0xa1ea, 0x0000 }, + { 0x0700, 0xa1ec, 0x0000 }, + { 0x8700, 0xa1fd, 0x5000 }, + { 0x8700, 0xa1f5, 0x4000 }, + { 0x8700, 0xa1f1, 0x3000 }, + { 0x8700, 0xa1ef, 0x2000 }, + { 0x0700, 0xa1ee, 0x0000 }, + { 0x0700, 0xa1f0, 0x0000 }, + { 0x8700, 0xa1f3, 0x2000 }, + { 0x0700, 0xa1f2, 0x0000 }, + { 0x0700, 0xa1f4, 0x0000 }, + { 0x8700, 0xa1f9, 0x3000 }, + { 0x8700, 0xa1f7, 0x2000 }, + { 0x0700, 0xa1f6, 0x0000 }, + { 0x0700, 0xa1f8, 0x0000 }, + { 0x8700, 0xa1fb, 0x2000 }, + { 0x0700, 0xa1fa, 0x0000 }, + { 0x0700, 0xa1fc, 0x0000 }, + { 0x8700, 0xa205, 0x4000 }, + { 0x8700, 0xa201, 0x3000 }, + { 0x8700, 0xa1ff, 0x2000 }, + { 0x0700, 0xa1fe, 0x0000 }, + { 0x0700, 0xa200, 0x0000 }, + { 0x8700, 0xa203, 0x2000 }, + { 0x0700, 0xa202, 0x0000 }, + { 0x0700, 0xa204, 0x0000 }, + { 0x8700, 0xa209, 0x3000 }, + { 0x8700, 0xa207, 0x2000 }, + { 0x0700, 0xa206, 0x0000 }, + { 0x0700, 0xa208, 0x0000 }, + { 0x8700, 0xa20b, 0x2000 }, + { 0x0700, 0xa20a, 0x0000 }, + { 0x0700, 0xa20c, 0x0000 }, + { 0x8700, 0xa22d, 0x6000 }, + { 0x8700, 0xa21d, 0x5000 }, + { 0x8700, 0xa215, 0x4000 }, + { 0x8700, 0xa211, 0x3000 }, + { 0x8700, 0xa20f, 0x2000 }, + { 0x0700, 0xa20e, 0x0000 }, + { 0x0700, 0xa210, 0x0000 }, + { 0x8700, 0xa213, 0x2000 }, + { 0x0700, 0xa212, 0x0000 }, + { 0x0700, 0xa214, 0x0000 }, + { 0x8700, 0xa219, 0x3000 }, + { 0x8700, 0xa217, 0x2000 }, + { 0x0700, 0xa216, 0x0000 }, + { 0x0700, 0xa218, 0x0000 }, + { 0x8700, 0xa21b, 0x2000 }, + { 0x0700, 0xa21a, 0x0000 }, + { 0x0700, 0xa21c, 0x0000 }, + { 0x8700, 0xa225, 0x4000 }, + { 0x8700, 0xa221, 0x3000 }, + { 0x8700, 0xa21f, 0x2000 }, + { 0x0700, 0xa21e, 0x0000 }, + { 0x0700, 0xa220, 0x0000 }, + { 0x8700, 0xa223, 0x2000 }, + { 0x0700, 0xa222, 0x0000 }, + { 0x0700, 0xa224, 0x0000 }, + { 0x8700, 0xa229, 0x3000 }, + { 0x8700, 0xa227, 0x2000 }, + { 0x0700, 0xa226, 0x0000 }, + { 0x0700, 0xa228, 0x0000 }, + { 0x8700, 0xa22b, 0x2000 }, + { 0x0700, 0xa22a, 0x0000 }, + { 0x0700, 0xa22c, 0x0000 }, + { 0x8700, 0xa23d, 0x5000 }, + { 0x8700, 0xa235, 0x4000 }, + { 0x8700, 0xa231, 0x3000 }, + { 0x8700, 0xa22f, 0x2000 }, + { 0x0700, 0xa22e, 0x0000 }, + { 0x0700, 0xa230, 0x0000 }, + { 0x8700, 0xa233, 0x2000 }, + { 0x0700, 0xa232, 0x0000 }, + { 0x0700, 0xa234, 0x0000 }, + { 0x8700, 0xa239, 0x3000 }, + { 0x8700, 0xa237, 0x2000 }, + { 0x0700, 0xa236, 0x0000 }, + { 0x0700, 0xa238, 0x0000 }, + { 0x8700, 0xa23b, 0x2000 }, + { 0x0700, 0xa23a, 0x0000 }, + { 0x0700, 0xa23c, 0x0000 }, + { 0x8700, 0xa245, 0x4000 }, + { 0x8700, 0xa241, 0x3000 }, + { 0x8700, 0xa23f, 0x2000 }, + { 0x0700, 0xa23e, 0x0000 }, + { 0x0700, 0xa240, 0x0000 }, + { 0x8700, 0xa243, 0x2000 }, + { 0x0700, 0xa242, 0x0000 }, + { 0x0700, 0xa244, 0x0000 }, + { 0x8700, 0xa249, 0x3000 }, + { 0x8700, 0xa247, 0x2000 }, + { 0x0700, 0xa246, 0x0000 }, + { 0x0700, 0xa248, 0x0000 }, + { 0x8700, 0xa24b, 0x2000 }, + { 0x0700, 0xa24a, 0x0000 }, + { 0x0700, 0xa24c, 0x0000 }, + { 0x8700, 0xa2cd, 0x8000 }, + { 0x8700, 0xa28d, 0x7000 }, + { 0x8700, 0xa26d, 0x6000 }, + { 0x8700, 0xa25d, 0x5000 }, + { 0x8700, 0xa255, 0x4000 }, + { 0x8700, 0xa251, 0x3000 }, + { 0x8700, 0xa24f, 0x2000 }, + { 0x0700, 0xa24e, 0x0000 }, + { 0x0700, 0xa250, 0x0000 }, + { 0x8700, 0xa253, 0x2000 }, + { 0x0700, 0xa252, 0x0000 }, + { 0x0700, 0xa254, 0x0000 }, + { 0x8700, 0xa259, 0x3000 }, + { 0x8700, 0xa257, 0x2000 }, + { 0x0700, 0xa256, 0x0000 }, + { 0x0700, 0xa258, 0x0000 }, + { 0x8700, 0xa25b, 0x2000 }, + { 0x0700, 0xa25a, 0x0000 }, + { 0x0700, 0xa25c, 0x0000 }, + { 0x8700, 0xa265, 0x4000 }, + { 0x8700, 0xa261, 0x3000 }, + { 0x8700, 0xa25f, 0x2000 }, + { 0x0700, 0xa25e, 0x0000 }, + { 0x0700, 0xa260, 0x0000 }, + { 0x8700, 0xa263, 0x2000 }, + { 0x0700, 0xa262, 0x0000 }, + { 0x0700, 0xa264, 0x0000 }, + { 0x8700, 0xa269, 0x3000 }, + { 0x8700, 0xa267, 0x2000 }, + { 0x0700, 0xa266, 0x0000 }, + { 0x0700, 0xa268, 0x0000 }, + { 0x8700, 0xa26b, 0x2000 }, + { 0x0700, 0xa26a, 0x0000 }, + { 0x0700, 0xa26c, 0x0000 }, + { 0x8700, 0xa27d, 0x5000 }, + { 0x8700, 0xa275, 0x4000 }, + { 0x8700, 0xa271, 0x3000 }, + { 0x8700, 0xa26f, 0x2000 }, + { 0x0700, 0xa26e, 0x0000 }, + { 0x0700, 0xa270, 0x0000 }, + { 0x8700, 0xa273, 0x2000 }, + { 0x0700, 0xa272, 0x0000 }, + { 0x0700, 0xa274, 0x0000 }, + { 0x8700, 0xa279, 0x3000 }, + { 0x8700, 0xa277, 0x2000 }, + { 0x0700, 0xa276, 0x0000 }, + { 0x0700, 0xa278, 0x0000 }, + { 0x8700, 0xa27b, 0x2000 }, + { 0x0700, 0xa27a, 0x0000 }, + { 0x0700, 0xa27c, 0x0000 }, + { 0x8700, 0xa285, 0x4000 }, + { 0x8700, 0xa281, 0x3000 }, + { 0x8700, 0xa27f, 0x2000 }, + { 0x0700, 0xa27e, 0x0000 }, + { 0x0700, 0xa280, 0x0000 }, + { 0x8700, 0xa283, 0x2000 }, + { 0x0700, 0xa282, 0x0000 }, + { 0x0700, 0xa284, 0x0000 }, + { 0x8700, 0xa289, 0x3000 }, + { 0x8700, 0xa287, 0x2000 }, + { 0x0700, 0xa286, 0x0000 }, + { 0x0700, 0xa288, 0x0000 }, + { 0x8700, 0xa28b, 0x2000 }, + { 0x0700, 0xa28a, 0x0000 }, + { 0x0700, 0xa28c, 0x0000 }, + { 0x8700, 0xa2ad, 0x6000 }, + { 0x8700, 0xa29d, 0x5000 }, + { 0x8700, 0xa295, 0x4000 }, + { 0x8700, 0xa291, 0x3000 }, + { 0x8700, 0xa28f, 0x2000 }, + { 0x0700, 0xa28e, 0x0000 }, + { 0x0700, 0xa290, 0x0000 }, + { 0x8700, 0xa293, 0x2000 }, + { 0x0700, 0xa292, 0x0000 }, + { 0x0700, 0xa294, 0x0000 }, + { 0x8700, 0xa299, 0x3000 }, + { 0x8700, 0xa297, 0x2000 }, + { 0x0700, 0xa296, 0x0000 }, + { 0x0700, 0xa298, 0x0000 }, + { 0x8700, 0xa29b, 0x2000 }, + { 0x0700, 0xa29a, 0x0000 }, + { 0x0700, 0xa29c, 0x0000 }, + { 0x8700, 0xa2a5, 0x4000 }, + { 0x8700, 0xa2a1, 0x3000 }, + { 0x8700, 0xa29f, 0x2000 }, + { 0x0700, 0xa29e, 0x0000 }, + { 0x0700, 0xa2a0, 0x0000 }, + { 0x8700, 0xa2a3, 0x2000 }, + { 0x0700, 0xa2a2, 0x0000 }, + { 0x0700, 0xa2a4, 0x0000 }, + { 0x8700, 0xa2a9, 0x3000 }, + { 0x8700, 0xa2a7, 0x2000 }, + { 0x0700, 0xa2a6, 0x0000 }, + { 0x0700, 0xa2a8, 0x0000 }, + { 0x8700, 0xa2ab, 0x2000 }, + { 0x0700, 0xa2aa, 0x0000 }, + { 0x0700, 0xa2ac, 0x0000 }, + { 0x8700, 0xa2bd, 0x5000 }, + { 0x8700, 0xa2b5, 0x4000 }, + { 0x8700, 0xa2b1, 0x3000 }, + { 0x8700, 0xa2af, 0x2000 }, + { 0x0700, 0xa2ae, 0x0000 }, + { 0x0700, 0xa2b0, 0x0000 }, + { 0x8700, 0xa2b3, 0x2000 }, + { 0x0700, 0xa2b2, 0x0000 }, + { 0x0700, 0xa2b4, 0x0000 }, + { 0x8700, 0xa2b9, 0x3000 }, + { 0x8700, 0xa2b7, 0x2000 }, + { 0x0700, 0xa2b6, 0x0000 }, + { 0x0700, 0xa2b8, 0x0000 }, + { 0x8700, 0xa2bb, 0x2000 }, + { 0x0700, 0xa2ba, 0x0000 }, + { 0x0700, 0xa2bc, 0x0000 }, + { 0x8700, 0xa2c5, 0x4000 }, + { 0x8700, 0xa2c1, 0x3000 }, + { 0x8700, 0xa2bf, 0x2000 }, + { 0x0700, 0xa2be, 0x0000 }, + { 0x0700, 0xa2c0, 0x0000 }, + { 0x8700, 0xa2c3, 0x2000 }, + { 0x0700, 0xa2c2, 0x0000 }, + { 0x0700, 0xa2c4, 0x0000 }, + { 0x8700, 0xa2c9, 0x3000 }, + { 0x8700, 0xa2c7, 0x2000 }, + { 0x0700, 0xa2c6, 0x0000 }, + { 0x0700, 0xa2c8, 0x0000 }, + { 0x8700, 0xa2cb, 0x2000 }, + { 0x0700, 0xa2ca, 0x0000 }, + { 0x0700, 0xa2cc, 0x0000 }, + { 0x8700, 0xa30d, 0x7000 }, + { 0x8700, 0xa2ed, 0x6000 }, + { 0x8700, 0xa2dd, 0x5000 }, + { 0x8700, 0xa2d5, 0x4000 }, + { 0x8700, 0xa2d1, 0x3000 }, + { 0x8700, 0xa2cf, 0x2000 }, + { 0x0700, 0xa2ce, 0x0000 }, + { 0x0700, 0xa2d0, 0x0000 }, + { 0x8700, 0xa2d3, 0x2000 }, + { 0x0700, 0xa2d2, 0x0000 }, + { 0x0700, 0xa2d4, 0x0000 }, + { 0x8700, 0xa2d9, 0x3000 }, + { 0x8700, 0xa2d7, 0x2000 }, + { 0x0700, 0xa2d6, 0x0000 }, + { 0x0700, 0xa2d8, 0x0000 }, + { 0x8700, 0xa2db, 0x2000 }, + { 0x0700, 0xa2da, 0x0000 }, + { 0x0700, 0xa2dc, 0x0000 }, + { 0x8700, 0xa2e5, 0x4000 }, + { 0x8700, 0xa2e1, 0x3000 }, + { 0x8700, 0xa2df, 0x2000 }, + { 0x0700, 0xa2de, 0x0000 }, + { 0x0700, 0xa2e0, 0x0000 }, + { 0x8700, 0xa2e3, 0x2000 }, + { 0x0700, 0xa2e2, 0x0000 }, + { 0x0700, 0xa2e4, 0x0000 }, + { 0x8700, 0xa2e9, 0x3000 }, + { 0x8700, 0xa2e7, 0x2000 }, + { 0x0700, 0xa2e6, 0x0000 }, + { 0x0700, 0xa2e8, 0x0000 }, + { 0x8700, 0xa2eb, 0x2000 }, + { 0x0700, 0xa2ea, 0x0000 }, + { 0x0700, 0xa2ec, 0x0000 }, + { 0x8700, 0xa2fd, 0x5000 }, + { 0x8700, 0xa2f5, 0x4000 }, + { 0x8700, 0xa2f1, 0x3000 }, + { 0x8700, 0xa2ef, 0x2000 }, + { 0x0700, 0xa2ee, 0x0000 }, + { 0x0700, 0xa2f0, 0x0000 }, + { 0x8700, 0xa2f3, 0x2000 }, + { 0x0700, 0xa2f2, 0x0000 }, + { 0x0700, 0xa2f4, 0x0000 }, + { 0x8700, 0xa2f9, 0x3000 }, + { 0x8700, 0xa2f7, 0x2000 }, + { 0x0700, 0xa2f6, 0x0000 }, + { 0x0700, 0xa2f8, 0x0000 }, + { 0x8700, 0xa2fb, 0x2000 }, + { 0x0700, 0xa2fa, 0x0000 }, + { 0x0700, 0xa2fc, 0x0000 }, + { 0x8700, 0xa305, 0x4000 }, + { 0x8700, 0xa301, 0x3000 }, + { 0x8700, 0xa2ff, 0x2000 }, + { 0x0700, 0xa2fe, 0x0000 }, + { 0x0700, 0xa300, 0x0000 }, + { 0x8700, 0xa303, 0x2000 }, + { 0x0700, 0xa302, 0x0000 }, + { 0x0700, 0xa304, 0x0000 }, + { 0x8700, 0xa309, 0x3000 }, + { 0x8700, 0xa307, 0x2000 }, + { 0x0700, 0xa306, 0x0000 }, + { 0x0700, 0xa308, 0x0000 }, + { 0x8700, 0xa30b, 0x2000 }, + { 0x0700, 0xa30a, 0x0000 }, + { 0x0700, 0xa30c, 0x0000 }, + { 0x8700, 0xa32d, 0x6000 }, + { 0x8700, 0xa31d, 0x5000 }, + { 0x8700, 0xa315, 0x4000 }, + { 0x8700, 0xa311, 0x3000 }, + { 0x8700, 0xa30f, 0x2000 }, + { 0x0700, 0xa30e, 0x0000 }, + { 0x0700, 0xa310, 0x0000 }, + { 0x8700, 0xa313, 0x2000 }, + { 0x0700, 0xa312, 0x0000 }, + { 0x0700, 0xa314, 0x0000 }, + { 0x8700, 0xa319, 0x3000 }, + { 0x8700, 0xa317, 0x2000 }, + { 0x0700, 0xa316, 0x0000 }, + { 0x0700, 0xa318, 0x0000 }, + { 0x8700, 0xa31b, 0x2000 }, + { 0x0700, 0xa31a, 0x0000 }, + { 0x0700, 0xa31c, 0x0000 }, + { 0x8700, 0xa325, 0x4000 }, + { 0x8700, 0xa321, 0x3000 }, + { 0x8700, 0xa31f, 0x2000 }, + { 0x0700, 0xa31e, 0x0000 }, + { 0x0700, 0xa320, 0x0000 }, + { 0x8700, 0xa323, 0x2000 }, + { 0x0700, 0xa322, 0x0000 }, + { 0x0700, 0xa324, 0x0000 }, + { 0x8700, 0xa329, 0x3000 }, + { 0x8700, 0xa327, 0x2000 }, + { 0x0700, 0xa326, 0x0000 }, + { 0x0700, 0xa328, 0x0000 }, + { 0x8700, 0xa32b, 0x2000 }, + { 0x0700, 0xa32a, 0x0000 }, + { 0x0700, 0xa32c, 0x0000 }, + { 0x8700, 0xa33d, 0x5000 }, + { 0x8700, 0xa335, 0x4000 }, + { 0x8700, 0xa331, 0x3000 }, + { 0x8700, 0xa32f, 0x2000 }, + { 0x0700, 0xa32e, 0x0000 }, + { 0x0700, 0xa330, 0x0000 }, + { 0x8700, 0xa333, 0x2000 }, + { 0x0700, 0xa332, 0x0000 }, + { 0x0700, 0xa334, 0x0000 }, + { 0x8700, 0xa339, 0x3000 }, + { 0x8700, 0xa337, 0x2000 }, + { 0x0700, 0xa336, 0x0000 }, + { 0x0700, 0xa338, 0x0000 }, + { 0x8700, 0xa33b, 0x2000 }, + { 0x0700, 0xa33a, 0x0000 }, + { 0x0700, 0xa33c, 0x0000 }, + { 0x8700, 0xa345, 0x4000 }, + { 0x8700, 0xa341, 0x3000 }, + { 0x8700, 0xa33f, 0x2000 }, + { 0x0700, 0xa33e, 0x0000 }, + { 0x0700, 0xa340, 0x0000 }, + { 0x8700, 0xa343, 0x2000 }, + { 0x0700, 0xa342, 0x0000 }, + { 0x0700, 0xa344, 0x0000 }, + { 0x8700, 0xa349, 0x3000 }, + { 0x8700, 0xa347, 0x2000 }, + { 0x0700, 0xa346, 0x0000 }, + { 0x0700, 0xa348, 0x0000 }, + { 0x8700, 0xa34b, 0x2000 }, + { 0x0700, 0xa34a, 0x0000 }, + { 0x0700, 0xa34c, 0x0000 }, + { 0x8700, 0xfc4d, 0xb000 }, + { 0x8700, 0xf97f, 0xa000 }, + { 0x8700, 0xa44d, 0x9000 }, + { 0x8700, 0xa3cd, 0x8000 }, + { 0x8700, 0xa38d, 0x7000 }, + { 0x8700, 0xa36d, 0x6000 }, + { 0x8700, 0xa35d, 0x5000 }, + { 0x8700, 0xa355, 0x4000 }, + { 0x8700, 0xa351, 0x3000 }, + { 0x8700, 0xa34f, 0x2000 }, + { 0x0700, 0xa34e, 0x0000 }, + { 0x0700, 0xa350, 0x0000 }, + { 0x8700, 0xa353, 0x2000 }, + { 0x0700, 0xa352, 0x0000 }, + { 0x0700, 0xa354, 0x0000 }, + { 0x8700, 0xa359, 0x3000 }, + { 0x8700, 0xa357, 0x2000 }, + { 0x0700, 0xa356, 0x0000 }, + { 0x0700, 0xa358, 0x0000 }, + { 0x8700, 0xa35b, 0x2000 }, + { 0x0700, 0xa35a, 0x0000 }, + { 0x0700, 0xa35c, 0x0000 }, + { 0x8700, 0xa365, 0x4000 }, + { 0x8700, 0xa361, 0x3000 }, + { 0x8700, 0xa35f, 0x2000 }, + { 0x0700, 0xa35e, 0x0000 }, + { 0x0700, 0xa360, 0x0000 }, + { 0x8700, 0xa363, 0x2000 }, + { 0x0700, 0xa362, 0x0000 }, + { 0x0700, 0xa364, 0x0000 }, + { 0x8700, 0xa369, 0x3000 }, + { 0x8700, 0xa367, 0x2000 }, + { 0x0700, 0xa366, 0x0000 }, + { 0x0700, 0xa368, 0x0000 }, + { 0x8700, 0xa36b, 0x2000 }, + { 0x0700, 0xa36a, 0x0000 }, + { 0x0700, 0xa36c, 0x0000 }, + { 0x8700, 0xa37d, 0x5000 }, + { 0x8700, 0xa375, 0x4000 }, + { 0x8700, 0xa371, 0x3000 }, + { 0x8700, 0xa36f, 0x2000 }, + { 0x0700, 0xa36e, 0x0000 }, + { 0x0700, 0xa370, 0x0000 }, + { 0x8700, 0xa373, 0x2000 }, + { 0x0700, 0xa372, 0x0000 }, + { 0x0700, 0xa374, 0x0000 }, + { 0x8700, 0xa379, 0x3000 }, + { 0x8700, 0xa377, 0x2000 }, + { 0x0700, 0xa376, 0x0000 }, + { 0x0700, 0xa378, 0x0000 }, + { 0x8700, 0xa37b, 0x2000 }, + { 0x0700, 0xa37a, 0x0000 }, + { 0x0700, 0xa37c, 0x0000 }, + { 0x8700, 0xa385, 0x4000 }, + { 0x8700, 0xa381, 0x3000 }, + { 0x8700, 0xa37f, 0x2000 }, + { 0x0700, 0xa37e, 0x0000 }, + { 0x0700, 0xa380, 0x0000 }, + { 0x8700, 0xa383, 0x2000 }, + { 0x0700, 0xa382, 0x0000 }, + { 0x0700, 0xa384, 0x0000 }, + { 0x8700, 0xa389, 0x3000 }, + { 0x8700, 0xa387, 0x2000 }, + { 0x0700, 0xa386, 0x0000 }, + { 0x0700, 0xa388, 0x0000 }, + { 0x8700, 0xa38b, 0x2000 }, + { 0x0700, 0xa38a, 0x0000 }, + { 0x0700, 0xa38c, 0x0000 }, + { 0x8700, 0xa3ad, 0x6000 }, + { 0x8700, 0xa39d, 0x5000 }, + { 0x8700, 0xa395, 0x4000 }, + { 0x8700, 0xa391, 0x3000 }, + { 0x8700, 0xa38f, 0x2000 }, + { 0x0700, 0xa38e, 0x0000 }, + { 0x0700, 0xa390, 0x0000 }, + { 0x8700, 0xa393, 0x2000 }, + { 0x0700, 0xa392, 0x0000 }, + { 0x0700, 0xa394, 0x0000 }, + { 0x8700, 0xa399, 0x3000 }, + { 0x8700, 0xa397, 0x2000 }, + { 0x0700, 0xa396, 0x0000 }, + { 0x0700, 0xa398, 0x0000 }, + { 0x8700, 0xa39b, 0x2000 }, + { 0x0700, 0xa39a, 0x0000 }, + { 0x0700, 0xa39c, 0x0000 }, + { 0x8700, 0xa3a5, 0x4000 }, + { 0x8700, 0xa3a1, 0x3000 }, + { 0x8700, 0xa39f, 0x2000 }, + { 0x0700, 0xa39e, 0x0000 }, + { 0x0700, 0xa3a0, 0x0000 }, + { 0x8700, 0xa3a3, 0x2000 }, + { 0x0700, 0xa3a2, 0x0000 }, + { 0x0700, 0xa3a4, 0x0000 }, + { 0x8700, 0xa3a9, 0x3000 }, + { 0x8700, 0xa3a7, 0x2000 }, + { 0x0700, 0xa3a6, 0x0000 }, + { 0x0700, 0xa3a8, 0x0000 }, + { 0x8700, 0xa3ab, 0x2000 }, + { 0x0700, 0xa3aa, 0x0000 }, + { 0x0700, 0xa3ac, 0x0000 }, + { 0x8700, 0xa3bd, 0x5000 }, + { 0x8700, 0xa3b5, 0x4000 }, + { 0x8700, 0xa3b1, 0x3000 }, + { 0x8700, 0xa3af, 0x2000 }, + { 0x0700, 0xa3ae, 0x0000 }, + { 0x0700, 0xa3b0, 0x0000 }, + { 0x8700, 0xa3b3, 0x2000 }, + { 0x0700, 0xa3b2, 0x0000 }, + { 0x0700, 0xa3b4, 0x0000 }, + { 0x8700, 0xa3b9, 0x3000 }, + { 0x8700, 0xa3b7, 0x2000 }, + { 0x0700, 0xa3b6, 0x0000 }, + { 0x0700, 0xa3b8, 0x0000 }, + { 0x8700, 0xa3bb, 0x2000 }, + { 0x0700, 0xa3ba, 0x0000 }, + { 0x0700, 0xa3bc, 0x0000 }, + { 0x8700, 0xa3c5, 0x4000 }, + { 0x8700, 0xa3c1, 0x3000 }, + { 0x8700, 0xa3bf, 0x2000 }, + { 0x0700, 0xa3be, 0x0000 }, + { 0x0700, 0xa3c0, 0x0000 }, + { 0x8700, 0xa3c3, 0x2000 }, + { 0x0700, 0xa3c2, 0x0000 }, + { 0x0700, 0xa3c4, 0x0000 }, + { 0x8700, 0xa3c9, 0x3000 }, + { 0x8700, 0xa3c7, 0x2000 }, + { 0x0700, 0xa3c6, 0x0000 }, + { 0x0700, 0xa3c8, 0x0000 }, + { 0x8700, 0xa3cb, 0x2000 }, + { 0x0700, 0xa3ca, 0x0000 }, + { 0x0700, 0xa3cc, 0x0000 }, + { 0x8700, 0xa40d, 0x7000 }, + { 0x8700, 0xa3ed, 0x6000 }, + { 0x8700, 0xa3dd, 0x5000 }, + { 0x8700, 0xa3d5, 0x4000 }, + { 0x8700, 0xa3d1, 0x3000 }, + { 0x8700, 0xa3cf, 0x2000 }, + { 0x0700, 0xa3ce, 0x0000 }, + { 0x0700, 0xa3d0, 0x0000 }, + { 0x8700, 0xa3d3, 0x2000 }, + { 0x0700, 0xa3d2, 0x0000 }, + { 0x0700, 0xa3d4, 0x0000 }, + { 0x8700, 0xa3d9, 0x3000 }, + { 0x8700, 0xa3d7, 0x2000 }, + { 0x0700, 0xa3d6, 0x0000 }, + { 0x0700, 0xa3d8, 0x0000 }, + { 0x8700, 0xa3db, 0x2000 }, + { 0x0700, 0xa3da, 0x0000 }, + { 0x0700, 0xa3dc, 0x0000 }, + { 0x8700, 0xa3e5, 0x4000 }, + { 0x8700, 0xa3e1, 0x3000 }, + { 0x8700, 0xa3df, 0x2000 }, + { 0x0700, 0xa3de, 0x0000 }, + { 0x0700, 0xa3e0, 0x0000 }, + { 0x8700, 0xa3e3, 0x2000 }, + { 0x0700, 0xa3e2, 0x0000 }, + { 0x0700, 0xa3e4, 0x0000 }, + { 0x8700, 0xa3e9, 0x3000 }, + { 0x8700, 0xa3e7, 0x2000 }, + { 0x0700, 0xa3e6, 0x0000 }, + { 0x0700, 0xa3e8, 0x0000 }, + { 0x8700, 0xa3eb, 0x2000 }, + { 0x0700, 0xa3ea, 0x0000 }, + { 0x0700, 0xa3ec, 0x0000 }, + { 0x8700, 0xa3fd, 0x5000 }, + { 0x8700, 0xa3f5, 0x4000 }, + { 0x8700, 0xa3f1, 0x3000 }, + { 0x8700, 0xa3ef, 0x2000 }, + { 0x0700, 0xa3ee, 0x0000 }, + { 0x0700, 0xa3f0, 0x0000 }, + { 0x8700, 0xa3f3, 0x2000 }, + { 0x0700, 0xa3f2, 0x0000 }, + { 0x0700, 0xa3f4, 0x0000 }, + { 0x8700, 0xa3f9, 0x3000 }, + { 0x8700, 0xa3f7, 0x2000 }, + { 0x0700, 0xa3f6, 0x0000 }, + { 0x0700, 0xa3f8, 0x0000 }, + { 0x8700, 0xa3fb, 0x2000 }, + { 0x0700, 0xa3fa, 0x0000 }, + { 0x0700, 0xa3fc, 0x0000 }, + { 0x8700, 0xa405, 0x4000 }, + { 0x8700, 0xa401, 0x3000 }, + { 0x8700, 0xa3ff, 0x2000 }, + { 0x0700, 0xa3fe, 0x0000 }, + { 0x0700, 0xa400, 0x0000 }, + { 0x8700, 0xa403, 0x2000 }, + { 0x0700, 0xa402, 0x0000 }, + { 0x0700, 0xa404, 0x0000 }, + { 0x8700, 0xa409, 0x3000 }, + { 0x8700, 0xa407, 0x2000 }, + { 0x0700, 0xa406, 0x0000 }, + { 0x0700, 0xa408, 0x0000 }, + { 0x8700, 0xa40b, 0x2000 }, + { 0x0700, 0xa40a, 0x0000 }, + { 0x0700, 0xa40c, 0x0000 }, + { 0x8700, 0xa42d, 0x6000 }, + { 0x8700, 0xa41d, 0x5000 }, + { 0x8700, 0xa415, 0x4000 }, + { 0x8700, 0xa411, 0x3000 }, + { 0x8700, 0xa40f, 0x2000 }, + { 0x0700, 0xa40e, 0x0000 }, + { 0x0700, 0xa410, 0x0000 }, + { 0x8700, 0xa413, 0x2000 }, + { 0x0700, 0xa412, 0x0000 }, + { 0x0700, 0xa414, 0x0000 }, + { 0x8700, 0xa419, 0x3000 }, + { 0x8700, 0xa417, 0x2000 }, + { 0x0700, 0xa416, 0x0000 }, + { 0x0700, 0xa418, 0x0000 }, + { 0x8700, 0xa41b, 0x2000 }, + { 0x0700, 0xa41a, 0x0000 }, + { 0x0700, 0xa41c, 0x0000 }, + { 0x8700, 0xa425, 0x4000 }, + { 0x8700, 0xa421, 0x3000 }, + { 0x8700, 0xa41f, 0x2000 }, + { 0x0700, 0xa41e, 0x0000 }, + { 0x0700, 0xa420, 0x0000 }, + { 0x8700, 0xa423, 0x2000 }, + { 0x0700, 0xa422, 0x0000 }, + { 0x0700, 0xa424, 0x0000 }, + { 0x8700, 0xa429, 0x3000 }, + { 0x8700, 0xa427, 0x2000 }, + { 0x0700, 0xa426, 0x0000 }, + { 0x0700, 0xa428, 0x0000 }, + { 0x8700, 0xa42b, 0x2000 }, + { 0x0700, 0xa42a, 0x0000 }, + { 0x0700, 0xa42c, 0x0000 }, + { 0x8700, 0xa43d, 0x5000 }, + { 0x8700, 0xa435, 0x4000 }, + { 0x8700, 0xa431, 0x3000 }, + { 0x8700, 0xa42f, 0x2000 }, + { 0x0700, 0xa42e, 0x0000 }, + { 0x0700, 0xa430, 0x0000 }, + { 0x8700, 0xa433, 0x2000 }, + { 0x0700, 0xa432, 0x0000 }, + { 0x0700, 0xa434, 0x0000 }, + { 0x8700, 0xa439, 0x3000 }, + { 0x8700, 0xa437, 0x2000 }, + { 0x0700, 0xa436, 0x0000 }, + { 0x0700, 0xa438, 0x0000 }, + { 0x8700, 0xa43b, 0x2000 }, + { 0x0700, 0xa43a, 0x0000 }, + { 0x0700, 0xa43c, 0x0000 }, + { 0x8700, 0xa445, 0x4000 }, + { 0x8700, 0xa441, 0x3000 }, + { 0x8700, 0xa43f, 0x2000 }, + { 0x0700, 0xa43e, 0x0000 }, + { 0x0700, 0xa440, 0x0000 }, + { 0x8700, 0xa443, 0x2000 }, + { 0x0700, 0xa442, 0x0000 }, + { 0x0700, 0xa444, 0x0000 }, + { 0x8700, 0xa449, 0x3000 }, + { 0x8700, 0xa447, 0x2000 }, + { 0x0700, 0xa446, 0x0000 }, + { 0x0700, 0xa448, 0x0000 }, + { 0x8700, 0xa44b, 0x2000 }, + { 0x0700, 0xa44a, 0x0000 }, + { 0x0700, 0xa44c, 0x0000 }, + { 0x8300, 0xf8ff, 0x8000 }, + { 0x9a00, 0xa490, 0x7000 }, + { 0x8700, 0xa46d, 0x6000 }, + { 0x8700, 0xa45d, 0x5000 }, + { 0x8700, 0xa455, 0x4000 }, + { 0x8700, 0xa451, 0x3000 }, + { 0x8700, 0xa44f, 0x2000 }, + { 0x0700, 0xa44e, 0x0000 }, + { 0x0700, 0xa450, 0x0000 }, + { 0x8700, 0xa453, 0x2000 }, + { 0x0700, 0xa452, 0x0000 }, + { 0x0700, 0xa454, 0x0000 }, + { 0x8700, 0xa459, 0x3000 }, + { 0x8700, 0xa457, 0x2000 }, + { 0x0700, 0xa456, 0x0000 }, + { 0x0700, 0xa458, 0x0000 }, + { 0x8700, 0xa45b, 0x2000 }, + { 0x0700, 0xa45a, 0x0000 }, + { 0x0700, 0xa45c, 0x0000 }, + { 0x8700, 0xa465, 0x4000 }, + { 0x8700, 0xa461, 0x3000 }, + { 0x8700, 0xa45f, 0x2000 }, + { 0x0700, 0xa45e, 0x0000 }, + { 0x0700, 0xa460, 0x0000 }, + { 0x8700, 0xa463, 0x2000 }, + { 0x0700, 0xa462, 0x0000 }, + { 0x0700, 0xa464, 0x0000 }, + { 0x8700, 0xa469, 0x3000 }, + { 0x8700, 0xa467, 0x2000 }, + { 0x0700, 0xa466, 0x0000 }, + { 0x0700, 0xa468, 0x0000 }, + { 0x8700, 0xa46b, 0x2000 }, + { 0x0700, 0xa46a, 0x0000 }, + { 0x0700, 0xa46c, 0x0000 }, + { 0x8700, 0xa47d, 0x5000 }, + { 0x8700, 0xa475, 0x4000 }, + { 0x8700, 0xa471, 0x3000 }, + { 0x8700, 0xa46f, 0x2000 }, + { 0x0700, 0xa46e, 0x0000 }, + { 0x0700, 0xa470, 0x0000 }, + { 0x8700, 0xa473, 0x2000 }, + { 0x0700, 0xa472, 0x0000 }, + { 0x0700, 0xa474, 0x0000 }, + { 0x8700, 0xa479, 0x3000 }, + { 0x8700, 0xa477, 0x2000 }, + { 0x0700, 0xa476, 0x0000 }, + { 0x0700, 0xa478, 0x0000 }, + { 0x8700, 0xa47b, 0x2000 }, + { 0x0700, 0xa47a, 0x0000 }, + { 0x0700, 0xa47c, 0x0000 }, + { 0x8700, 0xa485, 0x4000 }, + { 0x8700, 0xa481, 0x3000 }, + { 0x8700, 0xa47f, 0x2000 }, + { 0x0700, 0xa47e, 0x0000 }, + { 0x0700, 0xa480, 0x0000 }, + { 0x8700, 0xa483, 0x2000 }, + { 0x0700, 0xa482, 0x0000 }, + { 0x0700, 0xa484, 0x0000 }, + { 0x8700, 0xa489, 0x3000 }, + { 0x8700, 0xa487, 0x2000 }, + { 0x0700, 0xa486, 0x0000 }, + { 0x0700, 0xa488, 0x0000 }, + { 0x8700, 0xa48b, 0x2000 }, + { 0x0700, 0xa48a, 0x0000 }, + { 0x0700, 0xa48c, 0x0000 }, + { 0x9a00, 0xa4b0, 0x6000 }, + { 0x9a00, 0xa4a0, 0x5000 }, + { 0x9a00, 0xa498, 0x4000 }, + { 0x9a00, 0xa494, 0x3000 }, + { 0x9a00, 0xa492, 0x2000 }, + { 0x1a00, 0xa491, 0x0000 }, + { 0x1a00, 0xa493, 0x0000 }, + { 0x9a00, 0xa496, 0x2000 }, + { 0x1a00, 0xa495, 0x0000 }, + { 0x1a00, 0xa497, 0x0000 }, + { 0x9a00, 0xa49c, 0x3000 }, + { 0x9a00, 0xa49a, 0x2000 }, + { 0x1a00, 0xa499, 0x0000 }, + { 0x1a00, 0xa49b, 0x0000 }, + { 0x9a00, 0xa49e, 0x2000 }, + { 0x1a00, 0xa49d, 0x0000 }, + { 0x1a00, 0xa49f, 0x0000 }, + { 0x9a00, 0xa4a8, 0x4000 }, + { 0x9a00, 0xa4a4, 0x3000 }, + { 0x9a00, 0xa4a2, 0x2000 }, + { 0x1a00, 0xa4a1, 0x0000 }, + { 0x1a00, 0xa4a3, 0x0000 }, + { 0x9a00, 0xa4a6, 0x2000 }, + { 0x1a00, 0xa4a5, 0x0000 }, + { 0x1a00, 0xa4a7, 0x0000 }, + { 0x9a00, 0xa4ac, 0x3000 }, + { 0x9a00, 0xa4aa, 0x2000 }, + { 0x1a00, 0xa4a9, 0x0000 }, + { 0x1a00, 0xa4ab, 0x0000 }, + { 0x9a00, 0xa4ae, 0x2000 }, + { 0x1a00, 0xa4ad, 0x0000 }, + { 0x1a00, 0xa4af, 0x0000 }, + { 0x9a00, 0xa4c0, 0x5000 }, + { 0x9a00, 0xa4b8, 0x4000 }, + { 0x9a00, 0xa4b4, 0x3000 }, + { 0x9a00, 0xa4b2, 0x2000 }, + { 0x1a00, 0xa4b1, 0x0000 }, + { 0x1a00, 0xa4b3, 0x0000 }, + { 0x9a00, 0xa4b6, 0x2000 }, + { 0x1a00, 0xa4b5, 0x0000 }, + { 0x1a00, 0xa4b7, 0x0000 }, + { 0x9a00, 0xa4bc, 0x3000 }, + { 0x9a00, 0xa4ba, 0x2000 }, + { 0x1a00, 0xa4b9, 0x0000 }, + { 0x1a00, 0xa4bb, 0x0000 }, + { 0x9a00, 0xa4be, 0x2000 }, + { 0x1a00, 0xa4bd, 0x0000 }, + { 0x1a00, 0xa4bf, 0x0000 }, + { 0x8700, 0xd7a3, 0x4000 }, + { 0x9a00, 0xa4c4, 0x3000 }, + { 0x9a00, 0xa4c2, 0x2000 }, + { 0x1a00, 0xa4c1, 0x0000 }, + { 0x1a00, 0xa4c3, 0x0000 }, + { 0x9a00, 0xa4c6, 0x2000 }, + { 0x1a00, 0xa4c5, 0x0000 }, + { 0x0700, 0xac00, 0x0000 }, + { 0x8400, 0xdbff, 0x3000 }, + { 0x8400, 0xdb7f, 0x2000 }, + { 0x0400, 0xd800, 0x0000 }, + { 0x0400, 0xdb80, 0x0000 }, + { 0x8400, 0xdfff, 0x2000 }, + { 0x0400, 0xdc00, 0x0000 }, + { 0x0300, 0xe000, 0x0000 }, + { 0x8700, 0xf93f, 0x7000 }, + { 0x8700, 0xf91f, 0x6000 }, + { 0x8700, 0xf90f, 0x5000 }, + { 0x8700, 0xf907, 0x4000 }, + { 0x8700, 0xf903, 0x3000 }, + { 0x8700, 0xf901, 0x2000 }, + { 0x0700, 0xf900, 0x0000 }, + { 0x0700, 0xf902, 0x0000 }, + { 0x8700, 0xf905, 0x2000 }, + { 0x0700, 0xf904, 0x0000 }, + { 0x0700, 0xf906, 0x0000 }, + { 0x8700, 0xf90b, 0x3000 }, + { 0x8700, 0xf909, 0x2000 }, + { 0x0700, 0xf908, 0x0000 }, + { 0x0700, 0xf90a, 0x0000 }, + { 0x8700, 0xf90d, 0x2000 }, + { 0x0700, 0xf90c, 0x0000 }, + { 0x0700, 0xf90e, 0x0000 }, + { 0x8700, 0xf917, 0x4000 }, + { 0x8700, 0xf913, 0x3000 }, + { 0x8700, 0xf911, 0x2000 }, + { 0x0700, 0xf910, 0x0000 }, + { 0x0700, 0xf912, 0x0000 }, + { 0x8700, 0xf915, 0x2000 }, + { 0x0700, 0xf914, 0x0000 }, + { 0x0700, 0xf916, 0x0000 }, + { 0x8700, 0xf91b, 0x3000 }, + { 0x8700, 0xf919, 0x2000 }, + { 0x0700, 0xf918, 0x0000 }, + { 0x0700, 0xf91a, 0x0000 }, + { 0x8700, 0xf91d, 0x2000 }, + { 0x0700, 0xf91c, 0x0000 }, + { 0x0700, 0xf91e, 0x0000 }, + { 0x8700, 0xf92f, 0x5000 }, + { 0x8700, 0xf927, 0x4000 }, + { 0x8700, 0xf923, 0x3000 }, + { 0x8700, 0xf921, 0x2000 }, + { 0x0700, 0xf920, 0x0000 }, + { 0x0700, 0xf922, 0x0000 }, + { 0x8700, 0xf925, 0x2000 }, + { 0x0700, 0xf924, 0x0000 }, + { 0x0700, 0xf926, 0x0000 }, + { 0x8700, 0xf92b, 0x3000 }, + { 0x8700, 0xf929, 0x2000 }, + { 0x0700, 0xf928, 0x0000 }, + { 0x0700, 0xf92a, 0x0000 }, + { 0x8700, 0xf92d, 0x2000 }, + { 0x0700, 0xf92c, 0x0000 }, + { 0x0700, 0xf92e, 0x0000 }, + { 0x8700, 0xf937, 0x4000 }, + { 0x8700, 0xf933, 0x3000 }, + { 0x8700, 0xf931, 0x2000 }, + { 0x0700, 0xf930, 0x0000 }, + { 0x0700, 0xf932, 0x0000 }, + { 0x8700, 0xf935, 0x2000 }, + { 0x0700, 0xf934, 0x0000 }, + { 0x0700, 0xf936, 0x0000 }, + { 0x8700, 0xf93b, 0x3000 }, + { 0x8700, 0xf939, 0x2000 }, + { 0x0700, 0xf938, 0x0000 }, + { 0x0700, 0xf93a, 0x0000 }, + { 0x8700, 0xf93d, 0x2000 }, + { 0x0700, 0xf93c, 0x0000 }, + { 0x0700, 0xf93e, 0x0000 }, + { 0x8700, 0xf95f, 0x6000 }, + { 0x8700, 0xf94f, 0x5000 }, + { 0x8700, 0xf947, 0x4000 }, + { 0x8700, 0xf943, 0x3000 }, + { 0x8700, 0xf941, 0x2000 }, + { 0x0700, 0xf940, 0x0000 }, + { 0x0700, 0xf942, 0x0000 }, + { 0x8700, 0xf945, 0x2000 }, + { 0x0700, 0xf944, 0x0000 }, + { 0x0700, 0xf946, 0x0000 }, + { 0x8700, 0xf94b, 0x3000 }, + { 0x8700, 0xf949, 0x2000 }, + { 0x0700, 0xf948, 0x0000 }, + { 0x0700, 0xf94a, 0x0000 }, + { 0x8700, 0xf94d, 0x2000 }, + { 0x0700, 0xf94c, 0x0000 }, + { 0x0700, 0xf94e, 0x0000 }, + { 0x8700, 0xf957, 0x4000 }, + { 0x8700, 0xf953, 0x3000 }, + { 0x8700, 0xf951, 0x2000 }, + { 0x0700, 0xf950, 0x0000 }, + { 0x0700, 0xf952, 0x0000 }, + { 0x8700, 0xf955, 0x2000 }, + { 0x0700, 0xf954, 0x0000 }, + { 0x0700, 0xf956, 0x0000 }, + { 0x8700, 0xf95b, 0x3000 }, + { 0x8700, 0xf959, 0x2000 }, + { 0x0700, 0xf958, 0x0000 }, + { 0x0700, 0xf95a, 0x0000 }, + { 0x8700, 0xf95d, 0x2000 }, + { 0x0700, 0xf95c, 0x0000 }, + { 0x0700, 0xf95e, 0x0000 }, + { 0x8700, 0xf96f, 0x5000 }, + { 0x8700, 0xf967, 0x4000 }, + { 0x8700, 0xf963, 0x3000 }, + { 0x8700, 0xf961, 0x2000 }, + { 0x0700, 0xf960, 0x0000 }, + { 0x0700, 0xf962, 0x0000 }, + { 0x8700, 0xf965, 0x2000 }, + { 0x0700, 0xf964, 0x0000 }, + { 0x0700, 0xf966, 0x0000 }, + { 0x8700, 0xf96b, 0x3000 }, + { 0x8700, 0xf969, 0x2000 }, + { 0x0700, 0xf968, 0x0000 }, + { 0x0700, 0xf96a, 0x0000 }, + { 0x8700, 0xf96d, 0x2000 }, + { 0x0700, 0xf96c, 0x0000 }, + { 0x0700, 0xf96e, 0x0000 }, + { 0x8700, 0xf977, 0x4000 }, + { 0x8700, 0xf973, 0x3000 }, + { 0x8700, 0xf971, 0x2000 }, + { 0x0700, 0xf970, 0x0000 }, + { 0x0700, 0xf972, 0x0000 }, + { 0x8700, 0xf975, 0x2000 }, + { 0x0700, 0xf974, 0x0000 }, + { 0x0700, 0xf976, 0x0000 }, + { 0x8700, 0xf97b, 0x3000 }, + { 0x8700, 0xf979, 0x2000 }, + { 0x0700, 0xf978, 0x0000 }, + { 0x0700, 0xf97a, 0x0000 }, + { 0x8700, 0xf97d, 0x2000 }, + { 0x0700, 0xf97c, 0x0000 }, + { 0x0700, 0xf97e, 0x0000 }, + { 0x8700, 0xfb27, 0x9000 }, + { 0x8700, 0xf9ff, 0x8000 }, + { 0x8700, 0xf9bf, 0x7000 }, + { 0x8700, 0xf99f, 0x6000 }, + { 0x8700, 0xf98f, 0x5000 }, + { 0x8700, 0xf987, 0x4000 }, + { 0x8700, 0xf983, 0x3000 }, + { 0x8700, 0xf981, 0x2000 }, + { 0x0700, 0xf980, 0x0000 }, + { 0x0700, 0xf982, 0x0000 }, + { 0x8700, 0xf985, 0x2000 }, + { 0x0700, 0xf984, 0x0000 }, + { 0x0700, 0xf986, 0x0000 }, + { 0x8700, 0xf98b, 0x3000 }, + { 0x8700, 0xf989, 0x2000 }, + { 0x0700, 0xf988, 0x0000 }, + { 0x0700, 0xf98a, 0x0000 }, + { 0x8700, 0xf98d, 0x2000 }, + { 0x0700, 0xf98c, 0x0000 }, + { 0x0700, 0xf98e, 0x0000 }, + { 0x8700, 0xf997, 0x4000 }, + { 0x8700, 0xf993, 0x3000 }, + { 0x8700, 0xf991, 0x2000 }, + { 0x0700, 0xf990, 0x0000 }, + { 0x0700, 0xf992, 0x0000 }, + { 0x8700, 0xf995, 0x2000 }, + { 0x0700, 0xf994, 0x0000 }, + { 0x0700, 0xf996, 0x0000 }, + { 0x8700, 0xf99b, 0x3000 }, + { 0x8700, 0xf999, 0x2000 }, + { 0x0700, 0xf998, 0x0000 }, + { 0x0700, 0xf99a, 0x0000 }, + { 0x8700, 0xf99d, 0x2000 }, + { 0x0700, 0xf99c, 0x0000 }, + { 0x0700, 0xf99e, 0x0000 }, + { 0x8700, 0xf9af, 0x5000 }, + { 0x8700, 0xf9a7, 0x4000 }, + { 0x8700, 0xf9a3, 0x3000 }, + { 0x8700, 0xf9a1, 0x2000 }, + { 0x0700, 0xf9a0, 0x0000 }, + { 0x0700, 0xf9a2, 0x0000 }, + { 0x8700, 0xf9a5, 0x2000 }, + { 0x0700, 0xf9a4, 0x0000 }, + { 0x0700, 0xf9a6, 0x0000 }, + { 0x8700, 0xf9ab, 0x3000 }, + { 0x8700, 0xf9a9, 0x2000 }, + { 0x0700, 0xf9a8, 0x0000 }, + { 0x0700, 0xf9aa, 0x0000 }, + { 0x8700, 0xf9ad, 0x2000 }, + { 0x0700, 0xf9ac, 0x0000 }, + { 0x0700, 0xf9ae, 0x0000 }, + { 0x8700, 0xf9b7, 0x4000 }, + { 0x8700, 0xf9b3, 0x3000 }, + { 0x8700, 0xf9b1, 0x2000 }, + { 0x0700, 0xf9b0, 0x0000 }, + { 0x0700, 0xf9b2, 0x0000 }, + { 0x8700, 0xf9b5, 0x2000 }, + { 0x0700, 0xf9b4, 0x0000 }, + { 0x0700, 0xf9b6, 0x0000 }, + { 0x8700, 0xf9bb, 0x3000 }, + { 0x8700, 0xf9b9, 0x2000 }, + { 0x0700, 0xf9b8, 0x0000 }, + { 0x0700, 0xf9ba, 0x0000 }, + { 0x8700, 0xf9bd, 0x2000 }, + { 0x0700, 0xf9bc, 0x0000 }, + { 0x0700, 0xf9be, 0x0000 }, + { 0x8700, 0xf9df, 0x6000 }, + { 0x8700, 0xf9cf, 0x5000 }, + { 0x8700, 0xf9c7, 0x4000 }, + { 0x8700, 0xf9c3, 0x3000 }, + { 0x8700, 0xf9c1, 0x2000 }, + { 0x0700, 0xf9c0, 0x0000 }, + { 0x0700, 0xf9c2, 0x0000 }, + { 0x8700, 0xf9c5, 0x2000 }, + { 0x0700, 0xf9c4, 0x0000 }, + { 0x0700, 0xf9c6, 0x0000 }, + { 0x8700, 0xf9cb, 0x3000 }, + { 0x8700, 0xf9c9, 0x2000 }, + { 0x0700, 0xf9c8, 0x0000 }, + { 0x0700, 0xf9ca, 0x0000 }, + { 0x8700, 0xf9cd, 0x2000 }, + { 0x0700, 0xf9cc, 0x0000 }, + { 0x0700, 0xf9ce, 0x0000 }, + { 0x8700, 0xf9d7, 0x4000 }, + { 0x8700, 0xf9d3, 0x3000 }, + { 0x8700, 0xf9d1, 0x2000 }, + { 0x0700, 0xf9d0, 0x0000 }, + { 0x0700, 0xf9d2, 0x0000 }, + { 0x8700, 0xf9d5, 0x2000 }, + { 0x0700, 0xf9d4, 0x0000 }, + { 0x0700, 0xf9d6, 0x0000 }, + { 0x8700, 0xf9db, 0x3000 }, + { 0x8700, 0xf9d9, 0x2000 }, + { 0x0700, 0xf9d8, 0x0000 }, + { 0x0700, 0xf9da, 0x0000 }, + { 0x8700, 0xf9dd, 0x2000 }, + { 0x0700, 0xf9dc, 0x0000 }, + { 0x0700, 0xf9de, 0x0000 }, + { 0x8700, 0xf9ef, 0x5000 }, + { 0x8700, 0xf9e7, 0x4000 }, + { 0x8700, 0xf9e3, 0x3000 }, + { 0x8700, 0xf9e1, 0x2000 }, + { 0x0700, 0xf9e0, 0x0000 }, + { 0x0700, 0xf9e2, 0x0000 }, + { 0x8700, 0xf9e5, 0x2000 }, + { 0x0700, 0xf9e4, 0x0000 }, + { 0x0700, 0xf9e6, 0x0000 }, + { 0x8700, 0xf9eb, 0x3000 }, + { 0x8700, 0xf9e9, 0x2000 }, + { 0x0700, 0xf9e8, 0x0000 }, + { 0x0700, 0xf9ea, 0x0000 }, + { 0x8700, 0xf9ed, 0x2000 }, + { 0x0700, 0xf9ec, 0x0000 }, + { 0x0700, 0xf9ee, 0x0000 }, + { 0x8700, 0xf9f7, 0x4000 }, + { 0x8700, 0xf9f3, 0x3000 }, + { 0x8700, 0xf9f1, 0x2000 }, + { 0x0700, 0xf9f0, 0x0000 }, + { 0x0700, 0xf9f2, 0x0000 }, + { 0x8700, 0xf9f5, 0x2000 }, + { 0x0700, 0xf9f4, 0x0000 }, + { 0x0700, 0xf9f6, 0x0000 }, + { 0x8700, 0xf9fb, 0x3000 }, + { 0x8700, 0xf9f9, 0x2000 }, + { 0x0700, 0xf9f8, 0x0000 }, + { 0x0700, 0xf9fa, 0x0000 }, + { 0x8700, 0xf9fd, 0x2000 }, + { 0x0700, 0xf9fc, 0x0000 }, + { 0x0700, 0xf9fe, 0x0000 }, + { 0x8700, 0xfa41, 0x7000 }, + { 0x8700, 0xfa1f, 0x6000 }, + { 0x8700, 0xfa0f, 0x5000 }, + { 0x8700, 0xfa07, 0x4000 }, + { 0x8700, 0xfa03, 0x3000 }, + { 0x8700, 0xfa01, 0x2000 }, + { 0x0700, 0xfa00, 0x0000 }, + { 0x0700, 0xfa02, 0x0000 }, + { 0x8700, 0xfa05, 0x2000 }, + { 0x0700, 0xfa04, 0x0000 }, + { 0x0700, 0xfa06, 0x0000 }, + { 0x8700, 0xfa0b, 0x3000 }, + { 0x8700, 0xfa09, 0x2000 }, + { 0x0700, 0xfa08, 0x0000 }, + { 0x0700, 0xfa0a, 0x0000 }, + { 0x8700, 0xfa0d, 0x2000 }, + { 0x0700, 0xfa0c, 0x0000 }, + { 0x0700, 0xfa0e, 0x0000 }, + { 0x8700, 0xfa17, 0x4000 }, + { 0x8700, 0xfa13, 0x3000 }, + { 0x8700, 0xfa11, 0x2000 }, + { 0x0700, 0xfa10, 0x0000 }, + { 0x0700, 0xfa12, 0x0000 }, + { 0x8700, 0xfa15, 0x2000 }, + { 0x0700, 0xfa14, 0x0000 }, + { 0x0700, 0xfa16, 0x0000 }, + { 0x8700, 0xfa1b, 0x3000 }, + { 0x8700, 0xfa19, 0x2000 }, + { 0x0700, 0xfa18, 0x0000 }, + { 0x0700, 0xfa1a, 0x0000 }, + { 0x8700, 0xfa1d, 0x2000 }, + { 0x0700, 0xfa1c, 0x0000 }, + { 0x0700, 0xfa1e, 0x0000 }, + { 0x8700, 0xfa31, 0x5000 }, + { 0x8700, 0xfa27, 0x4000 }, + { 0x8700, 0xfa23, 0x3000 }, + { 0x8700, 0xfa21, 0x2000 }, + { 0x0700, 0xfa20, 0x0000 }, + { 0x0700, 0xfa22, 0x0000 }, + { 0x8700, 0xfa25, 0x2000 }, + { 0x0700, 0xfa24, 0x0000 }, + { 0x0700, 0xfa26, 0x0000 }, + { 0x8700, 0xfa2b, 0x3000 }, + { 0x8700, 0xfa29, 0x2000 }, + { 0x0700, 0xfa28, 0x0000 }, + { 0x0700, 0xfa2a, 0x0000 }, + { 0x8700, 0xfa2d, 0x2000 }, + { 0x0700, 0xfa2c, 0x0000 }, + { 0x0700, 0xfa30, 0x0000 }, + { 0x8700, 0xfa39, 0x4000 }, + { 0x8700, 0xfa35, 0x3000 }, + { 0x8700, 0xfa33, 0x2000 }, + { 0x0700, 0xfa32, 0x0000 }, + { 0x0700, 0xfa34, 0x0000 }, + { 0x8700, 0xfa37, 0x2000 }, + { 0x0700, 0xfa36, 0x0000 }, + { 0x0700, 0xfa38, 0x0000 }, + { 0x8700, 0xfa3d, 0x3000 }, + { 0x8700, 0xfa3b, 0x2000 }, + { 0x0700, 0xfa3a, 0x0000 }, + { 0x0700, 0xfa3c, 0x0000 }, + { 0x8700, 0xfa3f, 0x2000 }, + { 0x0700, 0xfa3e, 0x0000 }, + { 0x0700, 0xfa40, 0x0000 }, + { 0x8700, 0xfa61, 0x6000 }, + { 0x8700, 0xfa51, 0x5000 }, + { 0x8700, 0xfa49, 0x4000 }, + { 0x8700, 0xfa45, 0x3000 }, + { 0x8700, 0xfa43, 0x2000 }, + { 0x0700, 0xfa42, 0x0000 }, + { 0x0700, 0xfa44, 0x0000 }, + { 0x8700, 0xfa47, 0x2000 }, + { 0x0700, 0xfa46, 0x0000 }, + { 0x0700, 0xfa48, 0x0000 }, + { 0x8700, 0xfa4d, 0x3000 }, + { 0x8700, 0xfa4b, 0x2000 }, + { 0x0700, 0xfa4a, 0x0000 }, + { 0x0700, 0xfa4c, 0x0000 }, + { 0x8700, 0xfa4f, 0x2000 }, + { 0x0700, 0xfa4e, 0x0000 }, + { 0x0700, 0xfa50, 0x0000 }, + { 0x8700, 0xfa59, 0x4000 }, + { 0x8700, 0xfa55, 0x3000 }, + { 0x8700, 0xfa53, 0x2000 }, + { 0x0700, 0xfa52, 0x0000 }, + { 0x0700, 0xfa54, 0x0000 }, + { 0x8700, 0xfa57, 0x2000 }, + { 0x0700, 0xfa56, 0x0000 }, + { 0x0700, 0xfa58, 0x0000 }, + { 0x8700, 0xfa5d, 0x3000 }, + { 0x8700, 0xfa5b, 0x2000 }, + { 0x0700, 0xfa5a, 0x0000 }, + { 0x0700, 0xfa5c, 0x0000 }, + { 0x8700, 0xfa5f, 0x2000 }, + { 0x0700, 0xfa5e, 0x0000 }, + { 0x0700, 0xfa60, 0x0000 }, + { 0x8500, 0xfb06, 0x5000 }, + { 0x8700, 0xfa69, 0x4000 }, + { 0x8700, 0xfa65, 0x3000 }, + { 0x8700, 0xfa63, 0x2000 }, + { 0x0700, 0xfa62, 0x0000 }, + { 0x0700, 0xfa64, 0x0000 }, + { 0x8700, 0xfa67, 0x2000 }, + { 0x0700, 0xfa66, 0x0000 }, + { 0x0700, 0xfa68, 0x0000 }, + { 0x8500, 0xfb02, 0x3000 }, + { 0x8500, 0xfb00, 0x2000 }, + { 0x0700, 0xfa6a, 0x0000 }, + { 0x0500, 0xfb01, 0x0000 }, + { 0x8500, 0xfb04, 0x2000 }, + { 0x0500, 0xfb03, 0x0000 }, + { 0x0500, 0xfb05, 0x0000 }, + { 0x8700, 0xfb1f, 0x4000 }, + { 0x8500, 0xfb16, 0x3000 }, + { 0x8500, 0xfb14, 0x2000 }, + { 0x0500, 0xfb13, 0x0000 }, + { 0x0500, 0xfb15, 0x0000 }, + { 0x8700, 0xfb1d, 0x2000 }, + { 0x0500, 0xfb17, 0x0000 }, + { 0x0c00, 0xfb1e, 0x0000 }, + { 0x8700, 0xfb23, 0x3000 }, + { 0x8700, 0xfb21, 0x2000 }, + { 0x0700, 0xfb20, 0x0000 }, + { 0x0700, 0xfb22, 0x0000 }, + { 0x8700, 0xfb25, 0x2000 }, + { 0x0700, 0xfb24, 0x0000 }, + { 0x0700, 0xfb26, 0x0000 }, + { 0x8700, 0xfbac, 0x8000 }, + { 0x8700, 0xfb6c, 0x7000 }, + { 0x8700, 0xfb4c, 0x6000 }, + { 0x8700, 0xfb38, 0x5000 }, + { 0x8700, 0xfb2f, 0x4000 }, + { 0x8700, 0xfb2b, 0x3000 }, + { 0x9900, 0xfb29, 0x2000 }, + { 0x0700, 0xfb28, 0x0000 }, + { 0x0700, 0xfb2a, 0x0000 }, + { 0x8700, 0xfb2d, 0x2000 }, + { 0x0700, 0xfb2c, 0x0000 }, + { 0x0700, 0xfb2e, 0x0000 }, + { 0x8700, 0xfb33, 0x3000 }, + { 0x8700, 0xfb31, 0x2000 }, + { 0x0700, 0xfb30, 0x0000 }, + { 0x0700, 0xfb32, 0x0000 }, + { 0x8700, 0xfb35, 0x2000 }, + { 0x0700, 0xfb34, 0x0000 }, + { 0x0700, 0xfb36, 0x0000 }, + { 0x8700, 0xfb43, 0x4000 }, + { 0x8700, 0xfb3c, 0x3000 }, + { 0x8700, 0xfb3a, 0x2000 }, + { 0x0700, 0xfb39, 0x0000 }, + { 0x0700, 0xfb3b, 0x0000 }, + { 0x8700, 0xfb40, 0x2000 }, + { 0x0700, 0xfb3e, 0x0000 }, + { 0x0700, 0xfb41, 0x0000 }, + { 0x8700, 0xfb48, 0x3000 }, + { 0x8700, 0xfb46, 0x2000 }, + { 0x0700, 0xfb44, 0x0000 }, + { 0x0700, 0xfb47, 0x0000 }, + { 0x8700, 0xfb4a, 0x2000 }, + { 0x0700, 0xfb49, 0x0000 }, + { 0x0700, 0xfb4b, 0x0000 }, + { 0x8700, 0xfb5c, 0x5000 }, + { 0x8700, 0xfb54, 0x4000 }, + { 0x8700, 0xfb50, 0x3000 }, + { 0x8700, 0xfb4e, 0x2000 }, + { 0x0700, 0xfb4d, 0x0000 }, + { 0x0700, 0xfb4f, 0x0000 }, + { 0x8700, 0xfb52, 0x2000 }, + { 0x0700, 0xfb51, 0x0000 }, + { 0x0700, 0xfb53, 0x0000 }, + { 0x8700, 0xfb58, 0x3000 }, + { 0x8700, 0xfb56, 0x2000 }, + { 0x0700, 0xfb55, 0x0000 }, + { 0x0700, 0xfb57, 0x0000 }, + { 0x8700, 0xfb5a, 0x2000 }, + { 0x0700, 0xfb59, 0x0000 }, + { 0x0700, 0xfb5b, 0x0000 }, + { 0x8700, 0xfb64, 0x4000 }, + { 0x8700, 0xfb60, 0x3000 }, + { 0x8700, 0xfb5e, 0x2000 }, + { 0x0700, 0xfb5d, 0x0000 }, + { 0x0700, 0xfb5f, 0x0000 }, + { 0x8700, 0xfb62, 0x2000 }, + { 0x0700, 0xfb61, 0x0000 }, + { 0x0700, 0xfb63, 0x0000 }, + { 0x8700, 0xfb68, 0x3000 }, + { 0x8700, 0xfb66, 0x2000 }, + { 0x0700, 0xfb65, 0x0000 }, + { 0x0700, 0xfb67, 0x0000 }, + { 0x8700, 0xfb6a, 0x2000 }, + { 0x0700, 0xfb69, 0x0000 }, + { 0x0700, 0xfb6b, 0x0000 }, + { 0x8700, 0xfb8c, 0x6000 }, + { 0x8700, 0xfb7c, 0x5000 }, + { 0x8700, 0xfb74, 0x4000 }, + { 0x8700, 0xfb70, 0x3000 }, + { 0x8700, 0xfb6e, 0x2000 }, + { 0x0700, 0xfb6d, 0x0000 }, + { 0x0700, 0xfb6f, 0x0000 }, + { 0x8700, 0xfb72, 0x2000 }, + { 0x0700, 0xfb71, 0x0000 }, + { 0x0700, 0xfb73, 0x0000 }, + { 0x8700, 0xfb78, 0x3000 }, + { 0x8700, 0xfb76, 0x2000 }, + { 0x0700, 0xfb75, 0x0000 }, + { 0x0700, 0xfb77, 0x0000 }, + { 0x8700, 0xfb7a, 0x2000 }, + { 0x0700, 0xfb79, 0x0000 }, + { 0x0700, 0xfb7b, 0x0000 }, + { 0x8700, 0xfb84, 0x4000 }, + { 0x8700, 0xfb80, 0x3000 }, + { 0x8700, 0xfb7e, 0x2000 }, + { 0x0700, 0xfb7d, 0x0000 }, + { 0x0700, 0xfb7f, 0x0000 }, + { 0x8700, 0xfb82, 0x2000 }, + { 0x0700, 0xfb81, 0x0000 }, + { 0x0700, 0xfb83, 0x0000 }, + { 0x8700, 0xfb88, 0x3000 }, + { 0x8700, 0xfb86, 0x2000 }, + { 0x0700, 0xfb85, 0x0000 }, + { 0x0700, 0xfb87, 0x0000 }, + { 0x8700, 0xfb8a, 0x2000 }, + { 0x0700, 0xfb89, 0x0000 }, + { 0x0700, 0xfb8b, 0x0000 }, + { 0x8700, 0xfb9c, 0x5000 }, + { 0x8700, 0xfb94, 0x4000 }, + { 0x8700, 0xfb90, 0x3000 }, + { 0x8700, 0xfb8e, 0x2000 }, + { 0x0700, 0xfb8d, 0x0000 }, + { 0x0700, 0xfb8f, 0x0000 }, + { 0x8700, 0xfb92, 0x2000 }, + { 0x0700, 0xfb91, 0x0000 }, + { 0x0700, 0xfb93, 0x0000 }, + { 0x8700, 0xfb98, 0x3000 }, + { 0x8700, 0xfb96, 0x2000 }, + { 0x0700, 0xfb95, 0x0000 }, + { 0x0700, 0xfb97, 0x0000 }, + { 0x8700, 0xfb9a, 0x2000 }, + { 0x0700, 0xfb99, 0x0000 }, + { 0x0700, 0xfb9b, 0x0000 }, + { 0x8700, 0xfba4, 0x4000 }, + { 0x8700, 0xfba0, 0x3000 }, + { 0x8700, 0xfb9e, 0x2000 }, + { 0x0700, 0xfb9d, 0x0000 }, + { 0x0700, 0xfb9f, 0x0000 }, + { 0x8700, 0xfba2, 0x2000 }, + { 0x0700, 0xfba1, 0x0000 }, + { 0x0700, 0xfba3, 0x0000 }, + { 0x8700, 0xfba8, 0x3000 }, + { 0x8700, 0xfba6, 0x2000 }, + { 0x0700, 0xfba5, 0x0000 }, + { 0x0700, 0xfba7, 0x0000 }, + { 0x8700, 0xfbaa, 0x2000 }, + { 0x0700, 0xfba9, 0x0000 }, + { 0x0700, 0xfbab, 0x0000 }, + { 0x8700, 0xfc0d, 0x7000 }, + { 0x8700, 0xfbed, 0x6000 }, + { 0x8700, 0xfbdd, 0x5000 }, + { 0x8700, 0xfbd5, 0x4000 }, + { 0x8700, 0xfbb0, 0x3000 }, + { 0x8700, 0xfbae, 0x2000 }, + { 0x0700, 0xfbad, 0x0000 }, + { 0x0700, 0xfbaf, 0x0000 }, + { 0x8700, 0xfbd3, 0x2000 }, + { 0x0700, 0xfbb1, 0x0000 }, + { 0x0700, 0xfbd4, 0x0000 }, + { 0x8700, 0xfbd9, 0x3000 }, + { 0x8700, 0xfbd7, 0x2000 }, + { 0x0700, 0xfbd6, 0x0000 }, + { 0x0700, 0xfbd8, 0x0000 }, + { 0x8700, 0xfbdb, 0x2000 }, + { 0x0700, 0xfbda, 0x0000 }, + { 0x0700, 0xfbdc, 0x0000 }, + { 0x8700, 0xfbe5, 0x4000 }, + { 0x8700, 0xfbe1, 0x3000 }, + { 0x8700, 0xfbdf, 0x2000 }, + { 0x0700, 0xfbde, 0x0000 }, + { 0x0700, 0xfbe0, 0x0000 }, + { 0x8700, 0xfbe3, 0x2000 }, + { 0x0700, 0xfbe2, 0x0000 }, + { 0x0700, 0xfbe4, 0x0000 }, + { 0x8700, 0xfbe9, 0x3000 }, + { 0x8700, 0xfbe7, 0x2000 }, + { 0x0700, 0xfbe6, 0x0000 }, + { 0x0700, 0xfbe8, 0x0000 }, + { 0x8700, 0xfbeb, 0x2000 }, + { 0x0700, 0xfbea, 0x0000 }, + { 0x0700, 0xfbec, 0x0000 }, + { 0x8700, 0xfbfd, 0x5000 }, + { 0x8700, 0xfbf5, 0x4000 }, + { 0x8700, 0xfbf1, 0x3000 }, + { 0x8700, 0xfbef, 0x2000 }, + { 0x0700, 0xfbee, 0x0000 }, + { 0x0700, 0xfbf0, 0x0000 }, + { 0x8700, 0xfbf3, 0x2000 }, + { 0x0700, 0xfbf2, 0x0000 }, + { 0x0700, 0xfbf4, 0x0000 }, + { 0x8700, 0xfbf9, 0x3000 }, + { 0x8700, 0xfbf7, 0x2000 }, + { 0x0700, 0xfbf6, 0x0000 }, + { 0x0700, 0xfbf8, 0x0000 }, + { 0x8700, 0xfbfb, 0x2000 }, + { 0x0700, 0xfbfa, 0x0000 }, + { 0x0700, 0xfbfc, 0x0000 }, + { 0x8700, 0xfc05, 0x4000 }, + { 0x8700, 0xfc01, 0x3000 }, + { 0x8700, 0xfbff, 0x2000 }, + { 0x0700, 0xfbfe, 0x0000 }, + { 0x0700, 0xfc00, 0x0000 }, + { 0x8700, 0xfc03, 0x2000 }, + { 0x0700, 0xfc02, 0x0000 }, + { 0x0700, 0xfc04, 0x0000 }, + { 0x8700, 0xfc09, 0x3000 }, + { 0x8700, 0xfc07, 0x2000 }, + { 0x0700, 0xfc06, 0x0000 }, + { 0x0700, 0xfc08, 0x0000 }, + { 0x8700, 0xfc0b, 0x2000 }, + { 0x0700, 0xfc0a, 0x0000 }, + { 0x0700, 0xfc0c, 0x0000 }, + { 0x8700, 0xfc2d, 0x6000 }, + { 0x8700, 0xfc1d, 0x5000 }, + { 0x8700, 0xfc15, 0x4000 }, + { 0x8700, 0xfc11, 0x3000 }, + { 0x8700, 0xfc0f, 0x2000 }, + { 0x0700, 0xfc0e, 0x0000 }, + { 0x0700, 0xfc10, 0x0000 }, + { 0x8700, 0xfc13, 0x2000 }, + { 0x0700, 0xfc12, 0x0000 }, + { 0x0700, 0xfc14, 0x0000 }, + { 0x8700, 0xfc19, 0x3000 }, + { 0x8700, 0xfc17, 0x2000 }, + { 0x0700, 0xfc16, 0x0000 }, + { 0x0700, 0xfc18, 0x0000 }, + { 0x8700, 0xfc1b, 0x2000 }, + { 0x0700, 0xfc1a, 0x0000 }, + { 0x0700, 0xfc1c, 0x0000 }, + { 0x8700, 0xfc25, 0x4000 }, + { 0x8700, 0xfc21, 0x3000 }, + { 0x8700, 0xfc1f, 0x2000 }, + { 0x0700, 0xfc1e, 0x0000 }, + { 0x0700, 0xfc20, 0x0000 }, + { 0x8700, 0xfc23, 0x2000 }, + { 0x0700, 0xfc22, 0x0000 }, + { 0x0700, 0xfc24, 0x0000 }, + { 0x8700, 0xfc29, 0x3000 }, + { 0x8700, 0xfc27, 0x2000 }, + { 0x0700, 0xfc26, 0x0000 }, + { 0x0700, 0xfc28, 0x0000 }, + { 0x8700, 0xfc2b, 0x2000 }, + { 0x0700, 0xfc2a, 0x0000 }, + { 0x0700, 0xfc2c, 0x0000 }, + { 0x8700, 0xfc3d, 0x5000 }, + { 0x8700, 0xfc35, 0x4000 }, + { 0x8700, 0xfc31, 0x3000 }, + { 0x8700, 0xfc2f, 0x2000 }, + { 0x0700, 0xfc2e, 0x0000 }, + { 0x0700, 0xfc30, 0x0000 }, + { 0x8700, 0xfc33, 0x2000 }, + { 0x0700, 0xfc32, 0x0000 }, + { 0x0700, 0xfc34, 0x0000 }, + { 0x8700, 0xfc39, 0x3000 }, + { 0x8700, 0xfc37, 0x2000 }, + { 0x0700, 0xfc36, 0x0000 }, + { 0x0700, 0xfc38, 0x0000 }, + { 0x8700, 0xfc3b, 0x2000 }, + { 0x0700, 0xfc3a, 0x0000 }, + { 0x0700, 0xfc3c, 0x0000 }, + { 0x8700, 0xfc45, 0x4000 }, + { 0x8700, 0xfc41, 0x3000 }, + { 0x8700, 0xfc3f, 0x2000 }, + { 0x0700, 0xfc3e, 0x0000 }, + { 0x0700, 0xfc40, 0x0000 }, + { 0x8700, 0xfc43, 0x2000 }, + { 0x0700, 0xfc42, 0x0000 }, + { 0x0700, 0xfc44, 0x0000 }, + { 0x8700, 0xfc49, 0x3000 }, + { 0x8700, 0xfc47, 0x2000 }, + { 0x0700, 0xfc46, 0x0000 }, + { 0x0700, 0xfc48, 0x0000 }, + { 0x8700, 0xfc4b, 0x2000 }, + { 0x0700, 0xfc4a, 0x0000 }, + { 0x0700, 0xfc4c, 0x0000 }, + { 0x8700, 0xfeac, 0xa000 }, + { 0x8700, 0xfd5d, 0x9000 }, + { 0x8700, 0xfccd, 0x8000 }, + { 0x8700, 0xfc8d, 0x7000 }, + { 0x8700, 0xfc6d, 0x6000 }, + { 0x8700, 0xfc5d, 0x5000 }, + { 0x8700, 0xfc55, 0x4000 }, + { 0x8700, 0xfc51, 0x3000 }, + { 0x8700, 0xfc4f, 0x2000 }, + { 0x0700, 0xfc4e, 0x0000 }, + { 0x0700, 0xfc50, 0x0000 }, + { 0x8700, 0xfc53, 0x2000 }, + { 0x0700, 0xfc52, 0x0000 }, + { 0x0700, 0xfc54, 0x0000 }, + { 0x8700, 0xfc59, 0x3000 }, + { 0x8700, 0xfc57, 0x2000 }, + { 0x0700, 0xfc56, 0x0000 }, + { 0x0700, 0xfc58, 0x0000 }, + { 0x8700, 0xfc5b, 0x2000 }, + { 0x0700, 0xfc5a, 0x0000 }, + { 0x0700, 0xfc5c, 0x0000 }, + { 0x8700, 0xfc65, 0x4000 }, + { 0x8700, 0xfc61, 0x3000 }, + { 0x8700, 0xfc5f, 0x2000 }, + { 0x0700, 0xfc5e, 0x0000 }, + { 0x0700, 0xfc60, 0x0000 }, + { 0x8700, 0xfc63, 0x2000 }, + { 0x0700, 0xfc62, 0x0000 }, + { 0x0700, 0xfc64, 0x0000 }, + { 0x8700, 0xfc69, 0x3000 }, + { 0x8700, 0xfc67, 0x2000 }, + { 0x0700, 0xfc66, 0x0000 }, + { 0x0700, 0xfc68, 0x0000 }, + { 0x8700, 0xfc6b, 0x2000 }, + { 0x0700, 0xfc6a, 0x0000 }, + { 0x0700, 0xfc6c, 0x0000 }, + { 0x8700, 0xfc7d, 0x5000 }, + { 0x8700, 0xfc75, 0x4000 }, + { 0x8700, 0xfc71, 0x3000 }, + { 0x8700, 0xfc6f, 0x2000 }, + { 0x0700, 0xfc6e, 0x0000 }, + { 0x0700, 0xfc70, 0x0000 }, + { 0x8700, 0xfc73, 0x2000 }, + { 0x0700, 0xfc72, 0x0000 }, + { 0x0700, 0xfc74, 0x0000 }, + { 0x8700, 0xfc79, 0x3000 }, + { 0x8700, 0xfc77, 0x2000 }, + { 0x0700, 0xfc76, 0x0000 }, + { 0x0700, 0xfc78, 0x0000 }, + { 0x8700, 0xfc7b, 0x2000 }, + { 0x0700, 0xfc7a, 0x0000 }, + { 0x0700, 0xfc7c, 0x0000 }, + { 0x8700, 0xfc85, 0x4000 }, + { 0x8700, 0xfc81, 0x3000 }, + { 0x8700, 0xfc7f, 0x2000 }, + { 0x0700, 0xfc7e, 0x0000 }, + { 0x0700, 0xfc80, 0x0000 }, + { 0x8700, 0xfc83, 0x2000 }, + { 0x0700, 0xfc82, 0x0000 }, + { 0x0700, 0xfc84, 0x0000 }, + { 0x8700, 0xfc89, 0x3000 }, + { 0x8700, 0xfc87, 0x2000 }, + { 0x0700, 0xfc86, 0x0000 }, + { 0x0700, 0xfc88, 0x0000 }, + { 0x8700, 0xfc8b, 0x2000 }, + { 0x0700, 0xfc8a, 0x0000 }, + { 0x0700, 0xfc8c, 0x0000 }, + { 0x8700, 0xfcad, 0x6000 }, + { 0x8700, 0xfc9d, 0x5000 }, + { 0x8700, 0xfc95, 0x4000 }, + { 0x8700, 0xfc91, 0x3000 }, + { 0x8700, 0xfc8f, 0x2000 }, + { 0x0700, 0xfc8e, 0x0000 }, + { 0x0700, 0xfc90, 0x0000 }, + { 0x8700, 0xfc93, 0x2000 }, + { 0x0700, 0xfc92, 0x0000 }, + { 0x0700, 0xfc94, 0x0000 }, + { 0x8700, 0xfc99, 0x3000 }, + { 0x8700, 0xfc97, 0x2000 }, + { 0x0700, 0xfc96, 0x0000 }, + { 0x0700, 0xfc98, 0x0000 }, + { 0x8700, 0xfc9b, 0x2000 }, + { 0x0700, 0xfc9a, 0x0000 }, + { 0x0700, 0xfc9c, 0x0000 }, + { 0x8700, 0xfca5, 0x4000 }, + { 0x8700, 0xfca1, 0x3000 }, + { 0x8700, 0xfc9f, 0x2000 }, + { 0x0700, 0xfc9e, 0x0000 }, + { 0x0700, 0xfca0, 0x0000 }, + { 0x8700, 0xfca3, 0x2000 }, + { 0x0700, 0xfca2, 0x0000 }, + { 0x0700, 0xfca4, 0x0000 }, + { 0x8700, 0xfca9, 0x3000 }, + { 0x8700, 0xfca7, 0x2000 }, + { 0x0700, 0xfca6, 0x0000 }, + { 0x0700, 0xfca8, 0x0000 }, + { 0x8700, 0xfcab, 0x2000 }, + { 0x0700, 0xfcaa, 0x0000 }, + { 0x0700, 0xfcac, 0x0000 }, + { 0x8700, 0xfcbd, 0x5000 }, + { 0x8700, 0xfcb5, 0x4000 }, + { 0x8700, 0xfcb1, 0x3000 }, + { 0x8700, 0xfcaf, 0x2000 }, + { 0x0700, 0xfcae, 0x0000 }, + { 0x0700, 0xfcb0, 0x0000 }, + { 0x8700, 0xfcb3, 0x2000 }, + { 0x0700, 0xfcb2, 0x0000 }, + { 0x0700, 0xfcb4, 0x0000 }, + { 0x8700, 0xfcb9, 0x3000 }, + { 0x8700, 0xfcb7, 0x2000 }, + { 0x0700, 0xfcb6, 0x0000 }, + { 0x0700, 0xfcb8, 0x0000 }, + { 0x8700, 0xfcbb, 0x2000 }, + { 0x0700, 0xfcba, 0x0000 }, + { 0x0700, 0xfcbc, 0x0000 }, + { 0x8700, 0xfcc5, 0x4000 }, + { 0x8700, 0xfcc1, 0x3000 }, + { 0x8700, 0xfcbf, 0x2000 }, + { 0x0700, 0xfcbe, 0x0000 }, + { 0x0700, 0xfcc0, 0x0000 }, + { 0x8700, 0xfcc3, 0x2000 }, + { 0x0700, 0xfcc2, 0x0000 }, + { 0x0700, 0xfcc4, 0x0000 }, + { 0x8700, 0xfcc9, 0x3000 }, + { 0x8700, 0xfcc7, 0x2000 }, + { 0x0700, 0xfcc6, 0x0000 }, + { 0x0700, 0xfcc8, 0x0000 }, + { 0x8700, 0xfccb, 0x2000 }, + { 0x0700, 0xfcca, 0x0000 }, + { 0x0700, 0xfccc, 0x0000 }, + { 0x8700, 0xfd0d, 0x7000 }, + { 0x8700, 0xfced, 0x6000 }, + { 0x8700, 0xfcdd, 0x5000 }, + { 0x8700, 0xfcd5, 0x4000 }, + { 0x8700, 0xfcd1, 0x3000 }, + { 0x8700, 0xfccf, 0x2000 }, + { 0x0700, 0xfcce, 0x0000 }, + { 0x0700, 0xfcd0, 0x0000 }, + { 0x8700, 0xfcd3, 0x2000 }, + { 0x0700, 0xfcd2, 0x0000 }, + { 0x0700, 0xfcd4, 0x0000 }, + { 0x8700, 0xfcd9, 0x3000 }, + { 0x8700, 0xfcd7, 0x2000 }, + { 0x0700, 0xfcd6, 0x0000 }, + { 0x0700, 0xfcd8, 0x0000 }, + { 0x8700, 0xfcdb, 0x2000 }, + { 0x0700, 0xfcda, 0x0000 }, + { 0x0700, 0xfcdc, 0x0000 }, + { 0x8700, 0xfce5, 0x4000 }, + { 0x8700, 0xfce1, 0x3000 }, + { 0x8700, 0xfcdf, 0x2000 }, + { 0x0700, 0xfcde, 0x0000 }, + { 0x0700, 0xfce0, 0x0000 }, + { 0x8700, 0xfce3, 0x2000 }, + { 0x0700, 0xfce2, 0x0000 }, + { 0x0700, 0xfce4, 0x0000 }, + { 0x8700, 0xfce9, 0x3000 }, + { 0x8700, 0xfce7, 0x2000 }, + { 0x0700, 0xfce6, 0x0000 }, + { 0x0700, 0xfce8, 0x0000 }, + { 0x8700, 0xfceb, 0x2000 }, + { 0x0700, 0xfcea, 0x0000 }, + { 0x0700, 0xfcec, 0x0000 }, + { 0x8700, 0xfcfd, 0x5000 }, + { 0x8700, 0xfcf5, 0x4000 }, + { 0x8700, 0xfcf1, 0x3000 }, + { 0x8700, 0xfcef, 0x2000 }, + { 0x0700, 0xfcee, 0x0000 }, + { 0x0700, 0xfcf0, 0x0000 }, + { 0x8700, 0xfcf3, 0x2000 }, + { 0x0700, 0xfcf2, 0x0000 }, + { 0x0700, 0xfcf4, 0x0000 }, + { 0x8700, 0xfcf9, 0x3000 }, + { 0x8700, 0xfcf7, 0x2000 }, + { 0x0700, 0xfcf6, 0x0000 }, + { 0x0700, 0xfcf8, 0x0000 }, + { 0x8700, 0xfcfb, 0x2000 }, + { 0x0700, 0xfcfa, 0x0000 }, + { 0x0700, 0xfcfc, 0x0000 }, + { 0x8700, 0xfd05, 0x4000 }, + { 0x8700, 0xfd01, 0x3000 }, + { 0x8700, 0xfcff, 0x2000 }, + { 0x0700, 0xfcfe, 0x0000 }, + { 0x0700, 0xfd00, 0x0000 }, + { 0x8700, 0xfd03, 0x2000 }, + { 0x0700, 0xfd02, 0x0000 }, + { 0x0700, 0xfd04, 0x0000 }, + { 0x8700, 0xfd09, 0x3000 }, + { 0x8700, 0xfd07, 0x2000 }, + { 0x0700, 0xfd06, 0x0000 }, + { 0x0700, 0xfd08, 0x0000 }, + { 0x8700, 0xfd0b, 0x2000 }, + { 0x0700, 0xfd0a, 0x0000 }, + { 0x0700, 0xfd0c, 0x0000 }, + { 0x8700, 0xfd2d, 0x6000 }, + { 0x8700, 0xfd1d, 0x5000 }, + { 0x8700, 0xfd15, 0x4000 }, + { 0x8700, 0xfd11, 0x3000 }, + { 0x8700, 0xfd0f, 0x2000 }, + { 0x0700, 0xfd0e, 0x0000 }, + { 0x0700, 0xfd10, 0x0000 }, + { 0x8700, 0xfd13, 0x2000 }, + { 0x0700, 0xfd12, 0x0000 }, + { 0x0700, 0xfd14, 0x0000 }, + { 0x8700, 0xfd19, 0x3000 }, + { 0x8700, 0xfd17, 0x2000 }, + { 0x0700, 0xfd16, 0x0000 }, + { 0x0700, 0xfd18, 0x0000 }, + { 0x8700, 0xfd1b, 0x2000 }, + { 0x0700, 0xfd1a, 0x0000 }, + { 0x0700, 0xfd1c, 0x0000 }, + { 0x8700, 0xfd25, 0x4000 }, + { 0x8700, 0xfd21, 0x3000 }, + { 0x8700, 0xfd1f, 0x2000 }, + { 0x0700, 0xfd1e, 0x0000 }, + { 0x0700, 0xfd20, 0x0000 }, + { 0x8700, 0xfd23, 0x2000 }, + { 0x0700, 0xfd22, 0x0000 }, + { 0x0700, 0xfd24, 0x0000 }, + { 0x8700, 0xfd29, 0x3000 }, + { 0x8700, 0xfd27, 0x2000 }, + { 0x0700, 0xfd26, 0x0000 }, + { 0x0700, 0xfd28, 0x0000 }, + { 0x8700, 0xfd2b, 0x2000 }, + { 0x0700, 0xfd2a, 0x0000 }, + { 0x0700, 0xfd2c, 0x0000 }, + { 0x8700, 0xfd3d, 0x5000 }, + { 0x8700, 0xfd35, 0x4000 }, + { 0x8700, 0xfd31, 0x3000 }, + { 0x8700, 0xfd2f, 0x2000 }, + { 0x0700, 0xfd2e, 0x0000 }, + { 0x0700, 0xfd30, 0x0000 }, + { 0x8700, 0xfd33, 0x2000 }, + { 0x0700, 0xfd32, 0x0000 }, + { 0x0700, 0xfd34, 0x0000 }, + { 0x8700, 0xfd39, 0x3000 }, + { 0x8700, 0xfd37, 0x2000 }, + { 0x0700, 0xfd36, 0x0000 }, + { 0x0700, 0xfd38, 0x0000 }, + { 0x8700, 0xfd3b, 0x2000 }, + { 0x0700, 0xfd3a, 0x0000 }, + { 0x0700, 0xfd3c, 0x0000 }, + { 0x8700, 0xfd55, 0x4000 }, + { 0x8700, 0xfd51, 0x3000 }, + { 0x9200, 0xfd3f, 0x2000 }, + { 0x1600, 0xfd3e, 0x0000 }, + { 0x0700, 0xfd50, 0x0000 }, + { 0x8700, 0xfd53, 0x2000 }, + { 0x0700, 0xfd52, 0x0000 }, + { 0x0700, 0xfd54, 0x0000 }, + { 0x8700, 0xfd59, 0x3000 }, + { 0x8700, 0xfd57, 0x2000 }, + { 0x0700, 0xfd56, 0x0000 }, + { 0x0700, 0xfd58, 0x0000 }, + { 0x8700, 0xfd5b, 0x2000 }, + { 0x0700, 0xfd5a, 0x0000 }, + { 0x0700, 0xfd5c, 0x0000 }, + { 0x8c00, 0xfe09, 0x8000 }, + { 0x8700, 0xfd9f, 0x7000 }, + { 0x8700, 0xfd7d, 0x6000 }, + { 0x8700, 0xfd6d, 0x5000 }, + { 0x8700, 0xfd65, 0x4000 }, + { 0x8700, 0xfd61, 0x3000 }, + { 0x8700, 0xfd5f, 0x2000 }, + { 0x0700, 0xfd5e, 0x0000 }, + { 0x0700, 0xfd60, 0x0000 }, + { 0x8700, 0xfd63, 0x2000 }, + { 0x0700, 0xfd62, 0x0000 }, + { 0x0700, 0xfd64, 0x0000 }, + { 0x8700, 0xfd69, 0x3000 }, + { 0x8700, 0xfd67, 0x2000 }, + { 0x0700, 0xfd66, 0x0000 }, + { 0x0700, 0xfd68, 0x0000 }, + { 0x8700, 0xfd6b, 0x2000 }, + { 0x0700, 0xfd6a, 0x0000 }, + { 0x0700, 0xfd6c, 0x0000 }, + { 0x8700, 0xfd75, 0x4000 }, + { 0x8700, 0xfd71, 0x3000 }, + { 0x8700, 0xfd6f, 0x2000 }, + { 0x0700, 0xfd6e, 0x0000 }, + { 0x0700, 0xfd70, 0x0000 }, + { 0x8700, 0xfd73, 0x2000 }, + { 0x0700, 0xfd72, 0x0000 }, + { 0x0700, 0xfd74, 0x0000 }, + { 0x8700, 0xfd79, 0x3000 }, + { 0x8700, 0xfd77, 0x2000 }, + { 0x0700, 0xfd76, 0x0000 }, + { 0x0700, 0xfd78, 0x0000 }, + { 0x8700, 0xfd7b, 0x2000 }, + { 0x0700, 0xfd7a, 0x0000 }, + { 0x0700, 0xfd7c, 0x0000 }, + { 0x8700, 0xfd8d, 0x5000 }, + { 0x8700, 0xfd85, 0x4000 }, + { 0x8700, 0xfd81, 0x3000 }, + { 0x8700, 0xfd7f, 0x2000 }, + { 0x0700, 0xfd7e, 0x0000 }, + { 0x0700, 0xfd80, 0x0000 }, + { 0x8700, 0xfd83, 0x2000 }, + { 0x0700, 0xfd82, 0x0000 }, + { 0x0700, 0xfd84, 0x0000 }, + { 0x8700, 0xfd89, 0x3000 }, + { 0x8700, 0xfd87, 0x2000 }, + { 0x0700, 0xfd86, 0x0000 }, + { 0x0700, 0xfd88, 0x0000 }, + { 0x8700, 0xfd8b, 0x2000 }, + { 0x0700, 0xfd8a, 0x0000 }, + { 0x0700, 0xfd8c, 0x0000 }, + { 0x8700, 0xfd97, 0x4000 }, + { 0x8700, 0xfd93, 0x3000 }, + { 0x8700, 0xfd8f, 0x2000 }, + { 0x0700, 0xfd8e, 0x0000 }, + { 0x0700, 0xfd92, 0x0000 }, + { 0x8700, 0xfd95, 0x2000 }, + { 0x0700, 0xfd94, 0x0000 }, + { 0x0700, 0xfd96, 0x0000 }, + { 0x8700, 0xfd9b, 0x3000 }, + { 0x8700, 0xfd99, 0x2000 }, + { 0x0700, 0xfd98, 0x0000 }, + { 0x0700, 0xfd9a, 0x0000 }, + { 0x8700, 0xfd9d, 0x2000 }, + { 0x0700, 0xfd9c, 0x0000 }, + { 0x0700, 0xfd9e, 0x0000 }, + { 0x8700, 0xfdbf, 0x6000 }, + { 0x8700, 0xfdaf, 0x5000 }, + { 0x8700, 0xfda7, 0x4000 }, + { 0x8700, 0xfda3, 0x3000 }, + { 0x8700, 0xfda1, 0x2000 }, + { 0x0700, 0xfda0, 0x0000 }, + { 0x0700, 0xfda2, 0x0000 }, + { 0x8700, 0xfda5, 0x2000 }, + { 0x0700, 0xfda4, 0x0000 }, + { 0x0700, 0xfda6, 0x0000 }, + { 0x8700, 0xfdab, 0x3000 }, + { 0x8700, 0xfda9, 0x2000 }, + { 0x0700, 0xfda8, 0x0000 }, + { 0x0700, 0xfdaa, 0x0000 }, + { 0x8700, 0xfdad, 0x2000 }, + { 0x0700, 0xfdac, 0x0000 }, + { 0x0700, 0xfdae, 0x0000 }, + { 0x8700, 0xfdb7, 0x4000 }, + { 0x8700, 0xfdb3, 0x3000 }, + { 0x8700, 0xfdb1, 0x2000 }, + { 0x0700, 0xfdb0, 0x0000 }, + { 0x0700, 0xfdb2, 0x0000 }, + { 0x8700, 0xfdb5, 0x2000 }, + { 0x0700, 0xfdb4, 0x0000 }, + { 0x0700, 0xfdb6, 0x0000 }, + { 0x8700, 0xfdbb, 0x3000 }, + { 0x8700, 0xfdb9, 0x2000 }, + { 0x0700, 0xfdb8, 0x0000 }, + { 0x0700, 0xfdba, 0x0000 }, + { 0x8700, 0xfdbd, 0x2000 }, + { 0x0700, 0xfdbc, 0x0000 }, + { 0x0700, 0xfdbe, 0x0000 }, + { 0x8700, 0xfdf7, 0x5000 }, + { 0x8700, 0xfdc7, 0x4000 }, + { 0x8700, 0xfdc3, 0x3000 }, + { 0x8700, 0xfdc1, 0x2000 }, + { 0x0700, 0xfdc0, 0x0000 }, + { 0x0700, 0xfdc2, 0x0000 }, + { 0x8700, 0xfdc5, 0x2000 }, + { 0x0700, 0xfdc4, 0x0000 }, + { 0x0700, 0xfdc6, 0x0000 }, + { 0x8700, 0xfdf3, 0x3000 }, + { 0x8700, 0xfdf1, 0x2000 }, + { 0x0700, 0xfdf0, 0x0000 }, + { 0x0700, 0xfdf2, 0x0000 }, + { 0x8700, 0xfdf5, 0x2000 }, + { 0x0700, 0xfdf4, 0x0000 }, + { 0x0700, 0xfdf6, 0x0000 }, + { 0x8c00, 0xfe01, 0x4000 }, + { 0x8700, 0xfdfb, 0x3000 }, + { 0x8700, 0xfdf9, 0x2000 }, + { 0x0700, 0xfdf8, 0x0000 }, + { 0x0700, 0xfdfa, 0x0000 }, + { 0x9a00, 0xfdfd, 0x2000 }, + { 0x1700, 0xfdfc, 0x0000 }, + { 0x0c00, 0xfe00, 0x0000 }, + { 0x8c00, 0xfe05, 0x3000 }, + { 0x8c00, 0xfe03, 0x2000 }, + { 0x0c00, 0xfe02, 0x0000 }, + { 0x0c00, 0xfe04, 0x0000 }, + { 0x8c00, 0xfe07, 0x2000 }, + { 0x0c00, 0xfe06, 0x0000 }, + { 0x0c00, 0xfe08, 0x0000 }, + { 0x9900, 0xfe66, 0x7000 }, + { 0x9500, 0xfe45, 0x6000 }, + { 0x9600, 0xfe35, 0x5000 }, + { 0x8c00, 0xfe21, 0x4000 }, + { 0x8c00, 0xfe0d, 0x3000 }, + { 0x8c00, 0xfe0b, 0x2000 }, + { 0x0c00, 0xfe0a, 0x0000 }, + { 0x0c00, 0xfe0c, 0x0000 }, + { 0x8c00, 0xfe0f, 0x2000 }, + { 0x0c00, 0xfe0e, 0x0000 }, + { 0x0c00, 0xfe20, 0x0000 }, + { 0x9100, 0xfe31, 0x3000 }, + { 0x8c00, 0xfe23, 0x2000 }, + { 0x0c00, 0xfe22, 0x0000 }, + { 0x1500, 0xfe30, 0x0000 }, + { 0x9000, 0xfe33, 0x2000 }, + { 0x1100, 0xfe32, 0x0000 }, + { 0x1000, 0xfe34, 0x0000 }, + { 0x9600, 0xfe3d, 0x4000 }, + { 0x9600, 0xfe39, 0x3000 }, + { 0x9600, 0xfe37, 0x2000 }, + { 0x1200, 0xfe36, 0x0000 }, + { 0x1200, 0xfe38, 0x0000 }, + { 0x9600, 0xfe3b, 0x2000 }, + { 0x1200, 0xfe3a, 0x0000 }, + { 0x1200, 0xfe3c, 0x0000 }, + { 0x9600, 0xfe41, 0x3000 }, + { 0x9600, 0xfe3f, 0x2000 }, + { 0x1200, 0xfe3e, 0x0000 }, + { 0x1200, 0xfe40, 0x0000 }, + { 0x9600, 0xfe43, 0x2000 }, + { 0x1200, 0xfe42, 0x0000 }, + { 0x1200, 0xfe44, 0x0000 }, + { 0x9500, 0xfe56, 0x5000 }, + { 0x9000, 0xfe4d, 0x4000 }, + { 0x9500, 0xfe49, 0x3000 }, + { 0x9600, 0xfe47, 0x2000 }, + { 0x1500, 0xfe46, 0x0000 }, + { 0x1200, 0xfe48, 0x0000 }, + { 0x9500, 0xfe4b, 0x2000 }, + { 0x1500, 0xfe4a, 0x0000 }, + { 0x1500, 0xfe4c, 0x0000 }, + { 0x9500, 0xfe51, 0x3000 }, + { 0x9000, 0xfe4f, 0x2000 }, + { 0x1000, 0xfe4e, 0x0000 }, + { 0x1500, 0xfe50, 0x0000 }, + { 0x9500, 0xfe54, 0x2000 }, + { 0x1500, 0xfe52, 0x0000 }, + { 0x1500, 0xfe55, 0x0000 }, + { 0x9200, 0xfe5e, 0x4000 }, + { 0x9200, 0xfe5a, 0x3000 }, + { 0x9100, 0xfe58, 0x2000 }, + { 0x1500, 0xfe57, 0x0000 }, + { 0x1600, 0xfe59, 0x0000 }, + { 0x9200, 0xfe5c, 0x2000 }, + { 0x1600, 0xfe5b, 0x0000 }, + { 0x1600, 0xfe5d, 0x0000 }, + { 0x9900, 0xfe62, 0x3000 }, + { 0x9500, 0xfe60, 0x2000 }, + { 0x1500, 0xfe5f, 0x0000 }, + { 0x1500, 0xfe61, 0x0000 }, + { 0x9900, 0xfe64, 0x2000 }, + { 0x1100, 0xfe63, 0x0000 }, + { 0x1900, 0xfe65, 0x0000 }, + { 0x8700, 0xfe8c, 0x6000 }, + { 0x8700, 0xfe7c, 0x5000 }, + { 0x8700, 0xfe73, 0x4000 }, + { 0x9500, 0xfe6b, 0x3000 }, + { 0x9700, 0xfe69, 0x2000 }, + { 0x1500, 0xfe68, 0x0000 }, + { 0x1500, 0xfe6a, 0x0000 }, + { 0x8700, 0xfe71, 0x2000 }, + { 0x0700, 0xfe70, 0x0000 }, + { 0x0700, 0xfe72, 0x0000 }, + { 0x8700, 0xfe78, 0x3000 }, + { 0x8700, 0xfe76, 0x2000 }, + { 0x0700, 0xfe74, 0x0000 }, + { 0x0700, 0xfe77, 0x0000 }, + { 0x8700, 0xfe7a, 0x2000 }, + { 0x0700, 0xfe79, 0x0000 }, + { 0x0700, 0xfe7b, 0x0000 }, + { 0x8700, 0xfe84, 0x4000 }, + { 0x8700, 0xfe80, 0x3000 }, + { 0x8700, 0xfe7e, 0x2000 }, + { 0x0700, 0xfe7d, 0x0000 }, + { 0x0700, 0xfe7f, 0x0000 }, + { 0x8700, 0xfe82, 0x2000 }, + { 0x0700, 0xfe81, 0x0000 }, + { 0x0700, 0xfe83, 0x0000 }, + { 0x8700, 0xfe88, 0x3000 }, + { 0x8700, 0xfe86, 0x2000 }, + { 0x0700, 0xfe85, 0x0000 }, + { 0x0700, 0xfe87, 0x0000 }, + { 0x8700, 0xfe8a, 0x2000 }, + { 0x0700, 0xfe89, 0x0000 }, + { 0x0700, 0xfe8b, 0x0000 }, + { 0x8700, 0xfe9c, 0x5000 }, + { 0x8700, 0xfe94, 0x4000 }, + { 0x8700, 0xfe90, 0x3000 }, + { 0x8700, 0xfe8e, 0x2000 }, + { 0x0700, 0xfe8d, 0x0000 }, + { 0x0700, 0xfe8f, 0x0000 }, + { 0x8700, 0xfe92, 0x2000 }, + { 0x0700, 0xfe91, 0x0000 }, + { 0x0700, 0xfe93, 0x0000 }, + { 0x8700, 0xfe98, 0x3000 }, + { 0x8700, 0xfe96, 0x2000 }, + { 0x0700, 0xfe95, 0x0000 }, + { 0x0700, 0xfe97, 0x0000 }, + { 0x8700, 0xfe9a, 0x2000 }, + { 0x0700, 0xfe99, 0x0000 }, + { 0x0700, 0xfe9b, 0x0000 }, + { 0x8700, 0xfea4, 0x4000 }, + { 0x8700, 0xfea0, 0x3000 }, + { 0x8700, 0xfe9e, 0x2000 }, + { 0x0700, 0xfe9d, 0x0000 }, + { 0x0700, 0xfe9f, 0x0000 }, + { 0x8700, 0xfea2, 0x2000 }, + { 0x0700, 0xfea1, 0x0000 }, + { 0x0700, 0xfea3, 0x0000 }, + { 0x8700, 0xfea8, 0x3000 }, + { 0x8700, 0xfea6, 0x2000 }, + { 0x0700, 0xfea5, 0x0000 }, + { 0x0700, 0xfea7, 0x0000 }, + { 0x8700, 0xfeaa, 0x2000 }, + { 0x0700, 0xfea9, 0x0000 }, + { 0x0700, 0xfeab, 0x0000 }, + { 0x8700, 0xffaf, 0x9000 }, + { 0x8900, 0xff2f, 0x8020 }, + { 0x8700, 0xfeec, 0x7000 }, + { 0x8700, 0xfecc, 0x6000 }, + { 0x8700, 0xfebc, 0x5000 }, + { 0x8700, 0xfeb4, 0x4000 }, + { 0x8700, 0xfeb0, 0x3000 }, + { 0x8700, 0xfeae, 0x2000 }, + { 0x0700, 0xfead, 0x0000 }, + { 0x0700, 0xfeaf, 0x0000 }, + { 0x8700, 0xfeb2, 0x2000 }, + { 0x0700, 0xfeb1, 0x0000 }, + { 0x0700, 0xfeb3, 0x0000 }, + { 0x8700, 0xfeb8, 0x3000 }, + { 0x8700, 0xfeb6, 0x2000 }, + { 0x0700, 0xfeb5, 0x0000 }, + { 0x0700, 0xfeb7, 0x0000 }, + { 0x8700, 0xfeba, 0x2000 }, + { 0x0700, 0xfeb9, 0x0000 }, + { 0x0700, 0xfebb, 0x0000 }, + { 0x8700, 0xfec4, 0x4000 }, + { 0x8700, 0xfec0, 0x3000 }, + { 0x8700, 0xfebe, 0x2000 }, + { 0x0700, 0xfebd, 0x0000 }, + { 0x0700, 0xfebf, 0x0000 }, + { 0x8700, 0xfec2, 0x2000 }, + { 0x0700, 0xfec1, 0x0000 }, + { 0x0700, 0xfec3, 0x0000 }, + { 0x8700, 0xfec8, 0x3000 }, + { 0x8700, 0xfec6, 0x2000 }, + { 0x0700, 0xfec5, 0x0000 }, + { 0x0700, 0xfec7, 0x0000 }, + { 0x8700, 0xfeca, 0x2000 }, + { 0x0700, 0xfec9, 0x0000 }, + { 0x0700, 0xfecb, 0x0000 }, + { 0x8700, 0xfedc, 0x5000 }, + { 0x8700, 0xfed4, 0x4000 }, + { 0x8700, 0xfed0, 0x3000 }, + { 0x8700, 0xfece, 0x2000 }, + { 0x0700, 0xfecd, 0x0000 }, + { 0x0700, 0xfecf, 0x0000 }, + { 0x8700, 0xfed2, 0x2000 }, + { 0x0700, 0xfed1, 0x0000 }, + { 0x0700, 0xfed3, 0x0000 }, + { 0x8700, 0xfed8, 0x3000 }, + { 0x8700, 0xfed6, 0x2000 }, + { 0x0700, 0xfed5, 0x0000 }, + { 0x0700, 0xfed7, 0x0000 }, + { 0x8700, 0xfeda, 0x2000 }, + { 0x0700, 0xfed9, 0x0000 }, + { 0x0700, 0xfedb, 0x0000 }, + { 0x8700, 0xfee4, 0x4000 }, + { 0x8700, 0xfee0, 0x3000 }, + { 0x8700, 0xfede, 0x2000 }, + { 0x0700, 0xfedd, 0x0000 }, + { 0x0700, 0xfedf, 0x0000 }, + { 0x8700, 0xfee2, 0x2000 }, + { 0x0700, 0xfee1, 0x0000 }, + { 0x0700, 0xfee3, 0x0000 }, + { 0x8700, 0xfee8, 0x3000 }, + { 0x8700, 0xfee6, 0x2000 }, + { 0x0700, 0xfee5, 0x0000 }, + { 0x0700, 0xfee7, 0x0000 }, + { 0x8700, 0xfeea, 0x2000 }, + { 0x0700, 0xfee9, 0x0000 }, + { 0x0700, 0xfeeb, 0x0000 }, + { 0x9500, 0xff0f, 0x6000 }, + { 0x8700, 0xfefc, 0x5000 }, + { 0x8700, 0xfef4, 0x4000 }, + { 0x8700, 0xfef0, 0x3000 }, + { 0x8700, 0xfeee, 0x2000 }, + { 0x0700, 0xfeed, 0x0000 }, + { 0x0700, 0xfeef, 0x0000 }, + { 0x8700, 0xfef2, 0x2000 }, + { 0x0700, 0xfef1, 0x0000 }, + { 0x0700, 0xfef3, 0x0000 }, + { 0x8700, 0xfef8, 0x3000 }, + { 0x8700, 0xfef6, 0x2000 }, + { 0x0700, 0xfef5, 0x0000 }, + { 0x0700, 0xfef7, 0x0000 }, + { 0x8700, 0xfefa, 0x2000 }, + { 0x0700, 0xfef9, 0x0000 }, + { 0x0700, 0xfefb, 0x0000 }, + { 0x9500, 0xff07, 0x4000 }, + { 0x9500, 0xff03, 0x3000 }, + { 0x9500, 0xff01, 0x2000 }, + { 0x0100, 0xfeff, 0x0000 }, + { 0x1500, 0xff02, 0x0000 }, + { 0x9500, 0xff05, 0x2000 }, + { 0x1700, 0xff04, 0x0000 }, + { 0x1500, 0xff06, 0x0000 }, + { 0x9900, 0xff0b, 0x3000 }, + { 0x9200, 0xff09, 0x2000 }, + { 0x1600, 0xff08, 0x0000 }, + { 0x1500, 0xff0a, 0x0000 }, + { 0x9100, 0xff0d, 0x2000 }, + { 0x1500, 0xff0c, 0x0000 }, + { 0x1500, 0xff0e, 0x0000 }, + { 0x9500, 0xff1f, 0x5000 }, + { 0x8d00, 0xff17, 0x4000 }, + { 0x8d00, 0xff13, 0x3000 }, + { 0x8d00, 0xff11, 0x2000 }, + { 0x0d00, 0xff10, 0x0000 }, + { 0x0d00, 0xff12, 0x0000 }, + { 0x8d00, 0xff15, 0x2000 }, + { 0x0d00, 0xff14, 0x0000 }, + { 0x0d00, 0xff16, 0x0000 }, + { 0x9500, 0xff1b, 0x3000 }, + { 0x8d00, 0xff19, 0x2000 }, + { 0x0d00, 0xff18, 0x0000 }, + { 0x1500, 0xff1a, 0x0000 }, + { 0x9900, 0xff1d, 0x2000 }, + { 0x1900, 0xff1c, 0x0000 }, + { 0x1900, 0xff1e, 0x0000 }, + { 0x8900, 0xff27, 0x4020 }, + { 0x8900, 0xff23, 0x3020 }, + { 0x8900, 0xff21, 0x2020 }, + { 0x1500, 0xff20, 0x0000 }, + { 0x0900, 0xff22, 0x0020 }, + { 0x8900, 0xff25, 0x2020 }, + { 0x0900, 0xff24, 0x0020 }, + { 0x0900, 0xff26, 0x0020 }, + { 0x8900, 0xff2b, 0x3020 }, + { 0x8900, 0xff29, 0x2020 }, + { 0x0900, 0xff28, 0x0020 }, + { 0x0900, 0xff2a, 0x0020 }, + { 0x8900, 0xff2d, 0x2020 }, + { 0x0900, 0xff2c, 0x0020 }, + { 0x0900, 0xff2e, 0x0020 }, + { 0x8700, 0xff6f, 0x7000 }, + { 0x8500, 0xff4f, 0x6fe0 }, + { 0x9000, 0xff3f, 0x5000 }, + { 0x8900, 0xff37, 0x4020 }, + { 0x8900, 0xff33, 0x3020 }, + { 0x8900, 0xff31, 0x2020 }, + { 0x0900, 0xff30, 0x0020 }, + { 0x0900, 0xff32, 0x0020 }, + { 0x8900, 0xff35, 0x2020 }, + { 0x0900, 0xff34, 0x0020 }, + { 0x0900, 0xff36, 0x0020 }, + { 0x9600, 0xff3b, 0x3000 }, + { 0x8900, 0xff39, 0x2020 }, + { 0x0900, 0xff38, 0x0020 }, + { 0x0900, 0xff3a, 0x0020 }, + { 0x9200, 0xff3d, 0x2000 }, + { 0x1500, 0xff3c, 0x0000 }, + { 0x1800, 0xff3e, 0x0000 }, + { 0x8500, 0xff47, 0x4fe0 }, + { 0x8500, 0xff43, 0x3fe0 }, + { 0x8500, 0xff41, 0x2fe0 }, + { 0x1800, 0xff40, 0x0000 }, + { 0x0500, 0xff42, 0x0fe0 }, + { 0x8500, 0xff45, 0x2fe0 }, + { 0x0500, 0xff44, 0x0fe0 }, + { 0x0500, 0xff46, 0x0fe0 }, + { 0x8500, 0xff4b, 0x3fe0 }, + { 0x8500, 0xff49, 0x2fe0 }, + { 0x0500, 0xff48, 0x0fe0 }, + { 0x0500, 0xff4a, 0x0fe0 }, + { 0x8500, 0xff4d, 0x2fe0 }, + { 0x0500, 0xff4c, 0x0fe0 }, + { 0x0500, 0xff4e, 0x0fe0 }, + { 0x9600, 0xff5f, 0x5000 }, + { 0x8500, 0xff57, 0x4fe0 }, + { 0x8500, 0xff53, 0x3fe0 }, + { 0x8500, 0xff51, 0x2fe0 }, + { 0x0500, 0xff50, 0x0fe0 }, + { 0x0500, 0xff52, 0x0fe0 }, + { 0x8500, 0xff55, 0x2fe0 }, + { 0x0500, 0xff54, 0x0fe0 }, + { 0x0500, 0xff56, 0x0fe0 }, + { 0x9600, 0xff5b, 0x3000 }, + { 0x8500, 0xff59, 0x2fe0 }, + { 0x0500, 0xff58, 0x0fe0 }, + { 0x0500, 0xff5a, 0x0fe0 }, + { 0x9200, 0xff5d, 0x2000 }, + { 0x1900, 0xff5c, 0x0000 }, + { 0x1900, 0xff5e, 0x0000 }, + { 0x8700, 0xff67, 0x4000 }, + { 0x9200, 0xff63, 0x3000 }, + { 0x9500, 0xff61, 0x2000 }, + { 0x1200, 0xff60, 0x0000 }, + { 0x1600, 0xff62, 0x0000 }, + { 0x9000, 0xff65, 0x2000 }, + { 0x1500, 0xff64, 0x0000 }, + { 0x0700, 0xff66, 0x0000 }, + { 0x8700, 0xff6b, 0x3000 }, + { 0x8700, 0xff69, 0x2000 }, + { 0x0700, 0xff68, 0x0000 }, + { 0x0700, 0xff6a, 0x0000 }, + { 0x8700, 0xff6d, 0x2000 }, + { 0x0700, 0xff6c, 0x0000 }, + { 0x0700, 0xff6e, 0x0000 }, + { 0x8700, 0xff8f, 0x6000 }, + { 0x8700, 0xff7f, 0x5000 }, + { 0x8700, 0xff77, 0x4000 }, + { 0x8700, 0xff73, 0x3000 }, + { 0x8700, 0xff71, 0x2000 }, + { 0x0600, 0xff70, 0x0000 }, + { 0x0700, 0xff72, 0x0000 }, + { 0x8700, 0xff75, 0x2000 }, + { 0x0700, 0xff74, 0x0000 }, + { 0x0700, 0xff76, 0x0000 }, + { 0x8700, 0xff7b, 0x3000 }, + { 0x8700, 0xff79, 0x2000 }, + { 0x0700, 0xff78, 0x0000 }, + { 0x0700, 0xff7a, 0x0000 }, + { 0x8700, 0xff7d, 0x2000 }, + { 0x0700, 0xff7c, 0x0000 }, + { 0x0700, 0xff7e, 0x0000 }, + { 0x8700, 0xff87, 0x4000 }, + { 0x8700, 0xff83, 0x3000 }, + { 0x8700, 0xff81, 0x2000 }, + { 0x0700, 0xff80, 0x0000 }, + { 0x0700, 0xff82, 0x0000 }, + { 0x8700, 0xff85, 0x2000 }, + { 0x0700, 0xff84, 0x0000 }, + { 0x0700, 0xff86, 0x0000 }, + { 0x8700, 0xff8b, 0x3000 }, + { 0x8700, 0xff89, 0x2000 }, + { 0x0700, 0xff88, 0x0000 }, + { 0x0700, 0xff8a, 0x0000 }, + { 0x8700, 0xff8d, 0x2000 }, + { 0x0700, 0xff8c, 0x0000 }, + { 0x0700, 0xff8e, 0x0000 }, + { 0x8600, 0xff9f, 0x5000 }, + { 0x8700, 0xff97, 0x4000 }, + { 0x8700, 0xff93, 0x3000 }, + { 0x8700, 0xff91, 0x2000 }, + { 0x0700, 0xff90, 0x0000 }, + { 0x0700, 0xff92, 0x0000 }, + { 0x8700, 0xff95, 0x2000 }, + { 0x0700, 0xff94, 0x0000 }, + { 0x0700, 0xff96, 0x0000 }, + { 0x8700, 0xff9b, 0x3000 }, + { 0x8700, 0xff99, 0x2000 }, + { 0x0700, 0xff98, 0x0000 }, + { 0x0700, 0xff9a, 0x0000 }, + { 0x8700, 0xff9d, 0x2000 }, + { 0x0700, 0xff9c, 0x0000 }, + { 0x0600, 0xff9e, 0x0000 }, + { 0x8700, 0xffa7, 0x4000 }, + { 0x8700, 0xffa3, 0x3000 }, + { 0x8700, 0xffa1, 0x2000 }, + { 0x0700, 0xffa0, 0x0000 }, + { 0x0700, 0xffa2, 0x0000 }, + { 0x8700, 0xffa5, 0x2000 }, + { 0x0700, 0xffa4, 0x0000 }, + { 0x0700, 0xffa6, 0x0000 }, + { 0x8700, 0xffab, 0x3000 }, + { 0x8700, 0xffa9, 0x2000 }, + { 0x0700, 0xffa8, 0x0000 }, + { 0x0700, 0xffaa, 0x0000 }, + { 0x8700, 0xffad, 0x2000 }, + { 0x0700, 0xffac, 0x0000 }, + { 0x0700, 0xffae, 0x0000 }, + { 0x8701, 0x004c, 0x8000 }, + { 0x8701, 0x0008, 0x7000 }, + { 0x8700, 0xffd6, 0x6000 }, + { 0x8700, 0xffc2, 0x5000 }, + { 0x8700, 0xffb7, 0x4000 }, + { 0x8700, 0xffb3, 0x3000 }, + { 0x8700, 0xffb1, 0x2000 }, + { 0x0700, 0xffb0, 0x0000 }, + { 0x0700, 0xffb2, 0x0000 }, + { 0x8700, 0xffb5, 0x2000 }, + { 0x0700, 0xffb4, 0x0000 }, + { 0x0700, 0xffb6, 0x0000 }, + { 0x8700, 0xffbb, 0x3000 }, + { 0x8700, 0xffb9, 0x2000 }, + { 0x0700, 0xffb8, 0x0000 }, + { 0x0700, 0xffba, 0x0000 }, + { 0x8700, 0xffbd, 0x2000 }, + { 0x0700, 0xffbc, 0x0000 }, + { 0x0700, 0xffbe, 0x0000 }, + { 0x8700, 0xffcc, 0x4000 }, + { 0x8700, 0xffc6, 0x3000 }, + { 0x8700, 0xffc4, 0x2000 }, + { 0x0700, 0xffc3, 0x0000 }, + { 0x0700, 0xffc5, 0x0000 }, + { 0x8700, 0xffca, 0x2000 }, + { 0x0700, 0xffc7, 0x0000 }, + { 0x0700, 0xffcb, 0x0000 }, + { 0x8700, 0xffd2, 0x3000 }, + { 0x8700, 0xffce, 0x2000 }, + { 0x0700, 0xffcd, 0x0000 }, + { 0x0700, 0xffcf, 0x0000 }, + { 0x8700, 0xffd4, 0x2000 }, + { 0x0700, 0xffd3, 0x0000 }, + { 0x0700, 0xffd5, 0x0000 }, + { 0x9900, 0xffec, 0x5000 }, + { 0x9800, 0xffe3, 0x4000 }, + { 0x8700, 0xffdc, 0x3000 }, + { 0x8700, 0xffda, 0x2000 }, + { 0x0700, 0xffd7, 0x0000 }, + { 0x0700, 0xffdb, 0x0000 }, + { 0x9700, 0xffe1, 0x2000 }, + { 0x1700, 0xffe0, 0x0000 }, + { 0x1900, 0xffe2, 0x0000 }, + { 0x9a00, 0xffe8, 0x3000 }, + { 0x9700, 0xffe5, 0x2000 }, + { 0x1a00, 0xffe4, 0x0000 }, + { 0x1700, 0xffe6, 0x0000 }, + { 0x9900, 0xffea, 0x2000 }, + { 0x1900, 0xffe9, 0x0000 }, + { 0x1900, 0xffeb, 0x0000 }, + { 0x8701, 0x0000, 0x4000 }, + { 0x8100, 0xfffa, 0x3000 }, + { 0x9a00, 0xffee, 0x2000 }, + { 0x1a00, 0xffed, 0x0000 }, + { 0x0100, 0xfff9, 0x0000 }, + { 0x9a00, 0xfffc, 0x2000 }, + { 0x0100, 0xfffb, 0x0000 }, + { 0x1a00, 0xfffd, 0x0000 }, + { 0x8701, 0x0004, 0x3000 }, + { 0x8701, 0x0002, 0x2000 }, + { 0x0701, 0x0001, 0x0000 }, + { 0x0701, 0x0003, 0x0000 }, + { 0x8701, 0x0006, 0x2000 }, + { 0x0701, 0x0005, 0x0000 }, + { 0x0701, 0x0007, 0x0000 }, + { 0x8701, 0x002a, 0x6000 }, + { 0x8701, 0x0019, 0x5000 }, + { 0x8701, 0x0011, 0x4000 }, + { 0x8701, 0x000d, 0x3000 }, + { 0x8701, 0x000a, 0x2000 }, + { 0x0701, 0x0009, 0x0000 }, + { 0x0701, 0x000b, 0x0000 }, + { 0x8701, 0x000f, 0x2000 }, + { 0x0701, 0x000e, 0x0000 }, + { 0x0701, 0x0010, 0x0000 }, + { 0x8701, 0x0015, 0x3000 }, + { 0x8701, 0x0013, 0x2000 }, + { 0x0701, 0x0012, 0x0000 }, + { 0x0701, 0x0014, 0x0000 }, + { 0x8701, 0x0017, 0x2000 }, + { 0x0701, 0x0016, 0x0000 }, + { 0x0701, 0x0018, 0x0000 }, + { 0x8701, 0x0021, 0x4000 }, + { 0x8701, 0x001d, 0x3000 }, + { 0x8701, 0x001b, 0x2000 }, + { 0x0701, 0x001a, 0x0000 }, + { 0x0701, 0x001c, 0x0000 }, + { 0x8701, 0x001f, 0x2000 }, + { 0x0701, 0x001e, 0x0000 }, + { 0x0701, 0x0020, 0x0000 }, + { 0x8701, 0x0025, 0x3000 }, + { 0x8701, 0x0023, 0x2000 }, + { 0x0701, 0x0022, 0x0000 }, + { 0x0701, 0x0024, 0x0000 }, + { 0x8701, 0x0028, 0x2000 }, + { 0x0701, 0x0026, 0x0000 }, + { 0x0701, 0x0029, 0x0000 }, + { 0x8701, 0x003a, 0x5000 }, + { 0x8701, 0x0032, 0x4000 }, + { 0x8701, 0x002e, 0x3000 }, + { 0x8701, 0x002c, 0x2000 }, + { 0x0701, 0x002b, 0x0000 }, + { 0x0701, 0x002d, 0x0000 }, + { 0x8701, 0x0030, 0x2000 }, + { 0x0701, 0x002f, 0x0000 }, + { 0x0701, 0x0031, 0x0000 }, + { 0x8701, 0x0036, 0x3000 }, + { 0x8701, 0x0034, 0x2000 }, + { 0x0701, 0x0033, 0x0000 }, + { 0x0701, 0x0035, 0x0000 }, + { 0x8701, 0x0038, 0x2000 }, + { 0x0701, 0x0037, 0x0000 }, + { 0x0701, 0x0039, 0x0000 }, + { 0x8701, 0x0044, 0x4000 }, + { 0x8701, 0x0040, 0x3000 }, + { 0x8701, 0x003d, 0x2000 }, + { 0x0701, 0x003c, 0x0000 }, + { 0x0701, 0x003f, 0x0000 }, + { 0x8701, 0x0042, 0x2000 }, + { 0x0701, 0x0041, 0x0000 }, + { 0x0701, 0x0043, 0x0000 }, + { 0x8701, 0x0048, 0x3000 }, + { 0x8701, 0x0046, 0x2000 }, + { 0x0701, 0x0045, 0x0000 }, + { 0x0701, 0x0047, 0x0000 }, + { 0x8701, 0x004a, 0x2000 }, + { 0x0701, 0x0049, 0x0000 }, + { 0x0701, 0x004b, 0x0000 }, + { 0x8701, 0x00b0, 0x7000 }, + { 0x8701, 0x0090, 0x6000 }, + { 0x8701, 0x0080, 0x5000 }, + { 0x8701, 0x0056, 0x4000 }, + { 0x8701, 0x0052, 0x3000 }, + { 0x8701, 0x0050, 0x2000 }, + { 0x0701, 0x004d, 0x0000 }, + { 0x0701, 0x0051, 0x0000 }, + { 0x8701, 0x0054, 0x2000 }, + { 0x0701, 0x0053, 0x0000 }, + { 0x0701, 0x0055, 0x0000 }, + { 0x8701, 0x005a, 0x3000 }, + { 0x8701, 0x0058, 0x2000 }, + { 0x0701, 0x0057, 0x0000 }, + { 0x0701, 0x0059, 0x0000 }, + { 0x8701, 0x005c, 0x2000 }, + { 0x0701, 0x005b, 0x0000 }, + { 0x0701, 0x005d, 0x0000 }, + { 0x8701, 0x0088, 0x4000 }, + { 0x8701, 0x0084, 0x3000 }, + { 0x8701, 0x0082, 0x2000 }, + { 0x0701, 0x0081, 0x0000 }, + { 0x0701, 0x0083, 0x0000 }, + { 0x8701, 0x0086, 0x2000 }, + { 0x0701, 0x0085, 0x0000 }, + { 0x0701, 0x0087, 0x0000 }, + { 0x8701, 0x008c, 0x3000 }, + { 0x8701, 0x008a, 0x2000 }, + { 0x0701, 0x0089, 0x0000 }, + { 0x0701, 0x008b, 0x0000 }, + { 0x8701, 0x008e, 0x2000 }, + { 0x0701, 0x008d, 0x0000 }, + { 0x0701, 0x008f, 0x0000 }, + { 0x8701, 0x00a0, 0x5000 }, + { 0x8701, 0x0098, 0x4000 }, + { 0x8701, 0x0094, 0x3000 }, + { 0x8701, 0x0092, 0x2000 }, + { 0x0701, 0x0091, 0x0000 }, + { 0x0701, 0x0093, 0x0000 }, + { 0x8701, 0x0096, 0x2000 }, + { 0x0701, 0x0095, 0x0000 }, + { 0x0701, 0x0097, 0x0000 }, + { 0x8701, 0x009c, 0x3000 }, + { 0x8701, 0x009a, 0x2000 }, + { 0x0701, 0x0099, 0x0000 }, + { 0x0701, 0x009b, 0x0000 }, + { 0x8701, 0x009e, 0x2000 }, + { 0x0701, 0x009d, 0x0000 }, + { 0x0701, 0x009f, 0x0000 }, + { 0x8701, 0x00a8, 0x4000 }, + { 0x8701, 0x00a4, 0x3000 }, + { 0x8701, 0x00a2, 0x2000 }, + { 0x0701, 0x00a1, 0x0000 }, + { 0x0701, 0x00a3, 0x0000 }, + { 0x8701, 0x00a6, 0x2000 }, + { 0x0701, 0x00a5, 0x0000 }, + { 0x0701, 0x00a7, 0x0000 }, + { 0x8701, 0x00ac, 0x3000 }, + { 0x8701, 0x00aa, 0x2000 }, + { 0x0701, 0x00a9, 0x0000 }, + { 0x0701, 0x00ab, 0x0000 }, + { 0x8701, 0x00ae, 0x2000 }, + { 0x0701, 0x00ad, 0x0000 }, + { 0x0701, 0x00af, 0x0000 }, + { 0x8701, 0x00d0, 0x6000 }, + { 0x8701, 0x00c0, 0x5000 }, + { 0x8701, 0x00b8, 0x4000 }, + { 0x8701, 0x00b4, 0x3000 }, + { 0x8701, 0x00b2, 0x2000 }, + { 0x0701, 0x00b1, 0x0000 }, + { 0x0701, 0x00b3, 0x0000 }, + { 0x8701, 0x00b6, 0x2000 }, + { 0x0701, 0x00b5, 0x0000 }, + { 0x0701, 0x00b7, 0x0000 }, + { 0x8701, 0x00bc, 0x3000 }, + { 0x8701, 0x00ba, 0x2000 }, + { 0x0701, 0x00b9, 0x0000 }, + { 0x0701, 0x00bb, 0x0000 }, + { 0x8701, 0x00be, 0x2000 }, + { 0x0701, 0x00bd, 0x0000 }, + { 0x0701, 0x00bf, 0x0000 }, + { 0x8701, 0x00c8, 0x4000 }, + { 0x8701, 0x00c4, 0x3000 }, + { 0x8701, 0x00c2, 0x2000 }, + { 0x0701, 0x00c1, 0x0000 }, + { 0x0701, 0x00c3, 0x0000 }, + { 0x8701, 0x00c6, 0x2000 }, + { 0x0701, 0x00c5, 0x0000 }, + { 0x0701, 0x00c7, 0x0000 }, + { 0x8701, 0x00cc, 0x3000 }, + { 0x8701, 0x00ca, 0x2000 }, + { 0x0701, 0x00c9, 0x0000 }, + { 0x0701, 0x00cb, 0x0000 }, + { 0x8701, 0x00ce, 0x2000 }, + { 0x0701, 0x00cd, 0x0000 }, + { 0x0701, 0x00cf, 0x0000 }, + { 0x8701, 0x00e0, 0x5000 }, + { 0x8701, 0x00d8, 0x4000 }, + { 0x8701, 0x00d4, 0x3000 }, + { 0x8701, 0x00d2, 0x2000 }, + { 0x0701, 0x00d1, 0x0000 }, + { 0x0701, 0x00d3, 0x0000 }, + { 0x8701, 0x00d6, 0x2000 }, + { 0x0701, 0x00d5, 0x0000 }, + { 0x0701, 0x00d7, 0x0000 }, + { 0x8701, 0x00dc, 0x3000 }, + { 0x8701, 0x00da, 0x2000 }, + { 0x0701, 0x00d9, 0x0000 }, + { 0x0701, 0x00db, 0x0000 }, + { 0x8701, 0x00de, 0x2000 }, + { 0x0701, 0x00dd, 0x0000 }, + { 0x0701, 0x00df, 0x0000 }, + { 0x8701, 0x00e8, 0x4000 }, + { 0x8701, 0x00e4, 0x3000 }, + { 0x8701, 0x00e2, 0x2000 }, + { 0x0701, 0x00e1, 0x0000 }, + { 0x0701, 0x00e3, 0x0000 }, + { 0x8701, 0x00e6, 0x2000 }, + { 0x0701, 0x00e5, 0x0000 }, + { 0x0701, 0x00e7, 0x0000 }, + { 0x8701, 0x00ec, 0x3000 }, + { 0x8701, 0x00ea, 0x2000 }, + { 0x0701, 0x00e9, 0x0000 }, + { 0x0701, 0x00eb, 0x0000 }, + { 0x8701, 0x00ee, 0x2000 }, + { 0x0701, 0x00ed, 0x0000 }, + { 0x0701, 0x00ef, 0x0000 }, + { 0x8501, 0xd459, 0xb000 }, + { 0x9a01, 0xd080, 0xa000 }, + { 0x8701, 0x045f, 0x9000 }, + { 0x8701, 0x0349, 0x8000 }, + { 0x9a01, 0x013c, 0x7000 }, + { 0x8f01, 0x0119, 0x6000 }, + { 0x8f01, 0x0109, 0x5000 }, + { 0x8701, 0x00f8, 0x4000 }, + { 0x8701, 0x00f4, 0x3000 }, + { 0x8701, 0x00f2, 0x2000 }, + { 0x0701, 0x00f1, 0x0000 }, + { 0x0701, 0x00f3, 0x0000 }, + { 0x8701, 0x00f6, 0x2000 }, + { 0x0701, 0x00f5, 0x0000 }, + { 0x0701, 0x00f7, 0x0000 }, + { 0x9501, 0x0101, 0x3000 }, + { 0x8701, 0x00fa, 0x2000 }, + { 0x0701, 0x00f9, 0x0000 }, + { 0x1501, 0x0100, 0x0000 }, + { 0x8f01, 0x0107, 0x2000 }, + { 0x1a01, 0x0102, 0x0000 }, + { 0x0f01, 0x0108, 0x0000 }, + { 0x8f01, 0x0111, 0x4000 }, + { 0x8f01, 0x010d, 0x3000 }, + { 0x8f01, 0x010b, 0x2000 }, + { 0x0f01, 0x010a, 0x0000 }, + { 0x0f01, 0x010c, 0x0000 }, + { 0x8f01, 0x010f, 0x2000 }, + { 0x0f01, 0x010e, 0x0000 }, + { 0x0f01, 0x0110, 0x0000 }, + { 0x8f01, 0x0115, 0x3000 }, + { 0x8f01, 0x0113, 0x2000 }, + { 0x0f01, 0x0112, 0x0000 }, + { 0x0f01, 0x0114, 0x0000 }, + { 0x8f01, 0x0117, 0x2000 }, + { 0x0f01, 0x0116, 0x0000 }, + { 0x0f01, 0x0118, 0x0000 }, + { 0x8f01, 0x0129, 0x5000 }, + { 0x8f01, 0x0121, 0x4000 }, + { 0x8f01, 0x011d, 0x3000 }, + { 0x8f01, 0x011b, 0x2000 }, + { 0x0f01, 0x011a, 0x0000 }, + { 0x0f01, 0x011c, 0x0000 }, + { 0x8f01, 0x011f, 0x2000 }, + { 0x0f01, 0x011e, 0x0000 }, + { 0x0f01, 0x0120, 0x0000 }, + { 0x8f01, 0x0125, 0x3000 }, + { 0x8f01, 0x0123, 0x2000 }, + { 0x0f01, 0x0122, 0x0000 }, + { 0x0f01, 0x0124, 0x0000 }, + { 0x8f01, 0x0127, 0x2000 }, + { 0x0f01, 0x0126, 0x0000 }, + { 0x0f01, 0x0128, 0x0000 }, + { 0x8f01, 0x0131, 0x4000 }, + { 0x8f01, 0x012d, 0x3000 }, + { 0x8f01, 0x012b, 0x2000 }, + { 0x0f01, 0x012a, 0x0000 }, + { 0x0f01, 0x012c, 0x0000 }, + { 0x8f01, 0x012f, 0x2000 }, + { 0x0f01, 0x012e, 0x0000 }, + { 0x0f01, 0x0130, 0x0000 }, + { 0x9a01, 0x0138, 0x3000 }, + { 0x8f01, 0x0133, 0x2000 }, + { 0x0f01, 0x0132, 0x0000 }, + { 0x1a01, 0x0137, 0x0000 }, + { 0x9a01, 0x013a, 0x2000 }, + { 0x1a01, 0x0139, 0x0000 }, + { 0x1a01, 0x013b, 0x0000 }, + { 0x8701, 0x031c, 0x6000 }, + { 0x8701, 0x030c, 0x5000 }, + { 0x8701, 0x0304, 0x4000 }, + { 0x8701, 0x0300, 0x3000 }, + { 0x9a01, 0x013e, 0x2000 }, + { 0x1a01, 0x013d, 0x0000 }, + { 0x1a01, 0x013f, 0x0000 }, + { 0x8701, 0x0302, 0x2000 }, + { 0x0701, 0x0301, 0x0000 }, + { 0x0701, 0x0303, 0x0000 }, + { 0x8701, 0x0308, 0x3000 }, + { 0x8701, 0x0306, 0x2000 }, + { 0x0701, 0x0305, 0x0000 }, + { 0x0701, 0x0307, 0x0000 }, + { 0x8701, 0x030a, 0x2000 }, + { 0x0701, 0x0309, 0x0000 }, + { 0x0701, 0x030b, 0x0000 }, + { 0x8701, 0x0314, 0x4000 }, + { 0x8701, 0x0310, 0x3000 }, + { 0x8701, 0x030e, 0x2000 }, + { 0x0701, 0x030d, 0x0000 }, + { 0x0701, 0x030f, 0x0000 }, + { 0x8701, 0x0312, 0x2000 }, + { 0x0701, 0x0311, 0x0000 }, + { 0x0701, 0x0313, 0x0000 }, + { 0x8701, 0x0318, 0x3000 }, + { 0x8701, 0x0316, 0x2000 }, + { 0x0701, 0x0315, 0x0000 }, + { 0x0701, 0x0317, 0x0000 }, + { 0x8701, 0x031a, 0x2000 }, + { 0x0701, 0x0319, 0x0000 }, + { 0x0701, 0x031b, 0x0000 }, + { 0x8701, 0x0339, 0x5000 }, + { 0x8701, 0x0331, 0x4000 }, + { 0x8f01, 0x0321, 0x3000 }, + { 0x8701, 0x031e, 0x2000 }, + { 0x0701, 0x031d, 0x0000 }, + { 0x0f01, 0x0320, 0x0000 }, + { 0x8f01, 0x0323, 0x2000 }, + { 0x0f01, 0x0322, 0x0000 }, + { 0x0701, 0x0330, 0x0000 }, + { 0x8701, 0x0335, 0x3000 }, + { 0x8701, 0x0333, 0x2000 }, + { 0x0701, 0x0332, 0x0000 }, + { 0x0701, 0x0334, 0x0000 }, + { 0x8701, 0x0337, 0x2000 }, + { 0x0701, 0x0336, 0x0000 }, + { 0x0701, 0x0338, 0x0000 }, + { 0x8701, 0x0341, 0x4000 }, + { 0x8701, 0x033d, 0x3000 }, + { 0x8701, 0x033b, 0x2000 }, + { 0x0701, 0x033a, 0x0000 }, + { 0x0701, 0x033c, 0x0000 }, + { 0x8701, 0x033f, 0x2000 }, + { 0x0701, 0x033e, 0x0000 }, + { 0x0701, 0x0340, 0x0000 }, + { 0x8701, 0x0345, 0x3000 }, + { 0x8701, 0x0343, 0x2000 }, + { 0x0701, 0x0342, 0x0000 }, + { 0x0701, 0x0344, 0x0000 }, + { 0x8701, 0x0347, 0x2000 }, + { 0x0701, 0x0346, 0x0000 }, + { 0x0701, 0x0348, 0x0000 }, + { 0x8901, 0x041f, 0x7028 }, + { 0x9501, 0x039f, 0x6000 }, + { 0x8701, 0x038e, 0x5000 }, + { 0x8701, 0x0386, 0x4000 }, + { 0x8701, 0x0382, 0x3000 }, + { 0x8701, 0x0380, 0x2000 }, + { 0x0e01, 0x034a, 0x0000 }, + { 0x0701, 0x0381, 0x0000 }, + { 0x8701, 0x0384, 0x2000 }, + { 0x0701, 0x0383, 0x0000 }, + { 0x0701, 0x0385, 0x0000 }, + { 0x8701, 0x038a, 0x3000 }, + { 0x8701, 0x0388, 0x2000 }, + { 0x0701, 0x0387, 0x0000 }, + { 0x0701, 0x0389, 0x0000 }, + { 0x8701, 0x038c, 0x2000 }, + { 0x0701, 0x038b, 0x0000 }, + { 0x0701, 0x038d, 0x0000 }, + { 0x8701, 0x0396, 0x4000 }, + { 0x8701, 0x0392, 0x3000 }, + { 0x8701, 0x0390, 0x2000 }, + { 0x0701, 0x038f, 0x0000 }, + { 0x0701, 0x0391, 0x0000 }, + { 0x8701, 0x0394, 0x2000 }, + { 0x0701, 0x0393, 0x0000 }, + { 0x0701, 0x0395, 0x0000 }, + { 0x8701, 0x039a, 0x3000 }, + { 0x8701, 0x0398, 0x2000 }, + { 0x0701, 0x0397, 0x0000 }, + { 0x0701, 0x0399, 0x0000 }, + { 0x8701, 0x039c, 0x2000 }, + { 0x0701, 0x039b, 0x0000 }, + { 0x0701, 0x039d, 0x0000 }, + { 0x8901, 0x040f, 0x5028 }, + { 0x8901, 0x0407, 0x4028 }, + { 0x8901, 0x0403, 0x3028 }, + { 0x8901, 0x0401, 0x2028 }, + { 0x0901, 0x0400, 0x0028 }, + { 0x0901, 0x0402, 0x0028 }, + { 0x8901, 0x0405, 0x2028 }, + { 0x0901, 0x0404, 0x0028 }, + { 0x0901, 0x0406, 0x0028 }, + { 0x8901, 0x040b, 0x3028 }, + { 0x8901, 0x0409, 0x2028 }, + { 0x0901, 0x0408, 0x0028 }, + { 0x0901, 0x040a, 0x0028 }, + { 0x8901, 0x040d, 0x2028 }, + { 0x0901, 0x040c, 0x0028 }, + { 0x0901, 0x040e, 0x0028 }, + { 0x8901, 0x0417, 0x4028 }, + { 0x8901, 0x0413, 0x3028 }, + { 0x8901, 0x0411, 0x2028 }, + { 0x0901, 0x0410, 0x0028 }, + { 0x0901, 0x0412, 0x0028 }, + { 0x8901, 0x0415, 0x2028 }, + { 0x0901, 0x0414, 0x0028 }, + { 0x0901, 0x0416, 0x0028 }, + { 0x8901, 0x041b, 0x3028 }, + { 0x8901, 0x0419, 0x2028 }, + { 0x0901, 0x0418, 0x0028 }, + { 0x0901, 0x041a, 0x0028 }, + { 0x8901, 0x041d, 0x2028 }, + { 0x0901, 0x041c, 0x0028 }, + { 0x0901, 0x041e, 0x0028 }, + { 0x8501, 0x043f, 0x6fd8 }, + { 0x8501, 0x042f, 0x5fd8 }, + { 0x8901, 0x0427, 0x4028 }, + { 0x8901, 0x0423, 0x3028 }, + { 0x8901, 0x0421, 0x2028 }, + { 0x0901, 0x0420, 0x0028 }, + { 0x0901, 0x0422, 0x0028 }, + { 0x8901, 0x0425, 0x2028 }, + { 0x0901, 0x0424, 0x0028 }, + { 0x0901, 0x0426, 0x0028 }, + { 0x8501, 0x042b, 0x3fd8 }, + { 0x8501, 0x0429, 0x2fd8 }, + { 0x0501, 0x0428, 0x0fd8 }, + { 0x0501, 0x042a, 0x0fd8 }, + { 0x8501, 0x042d, 0x2fd8 }, + { 0x0501, 0x042c, 0x0fd8 }, + { 0x0501, 0x042e, 0x0fd8 }, + { 0x8501, 0x0437, 0x4fd8 }, + { 0x8501, 0x0433, 0x3fd8 }, + { 0x8501, 0x0431, 0x2fd8 }, + { 0x0501, 0x0430, 0x0fd8 }, + { 0x0501, 0x0432, 0x0fd8 }, + { 0x8501, 0x0435, 0x2fd8 }, + { 0x0501, 0x0434, 0x0fd8 }, + { 0x0501, 0x0436, 0x0fd8 }, + { 0x8501, 0x043b, 0x3fd8 }, + { 0x8501, 0x0439, 0x2fd8 }, + { 0x0501, 0x0438, 0x0fd8 }, + { 0x0501, 0x043a, 0x0fd8 }, + { 0x8501, 0x043d, 0x2fd8 }, + { 0x0501, 0x043c, 0x0fd8 }, + { 0x0501, 0x043e, 0x0fd8 }, + { 0x8501, 0x044f, 0x5fd8 }, + { 0x8501, 0x0447, 0x4fd8 }, + { 0x8501, 0x0443, 0x3fd8 }, + { 0x8501, 0x0441, 0x2fd8 }, + { 0x0501, 0x0440, 0x0fd8 }, + { 0x0501, 0x0442, 0x0fd8 }, + { 0x8501, 0x0445, 0x2fd8 }, + { 0x0501, 0x0444, 0x0fd8 }, + { 0x0501, 0x0446, 0x0fd8 }, + { 0x8501, 0x044b, 0x3fd8 }, + { 0x8501, 0x0449, 0x2fd8 }, + { 0x0501, 0x0448, 0x0fd8 }, + { 0x0501, 0x044a, 0x0fd8 }, + { 0x8501, 0x044d, 0x2fd8 }, + { 0x0501, 0x044c, 0x0fd8 }, + { 0x0501, 0x044e, 0x0fd8 }, + { 0x8701, 0x0457, 0x4000 }, + { 0x8701, 0x0453, 0x3000 }, + { 0x8701, 0x0451, 0x2000 }, + { 0x0701, 0x0450, 0x0000 }, + { 0x0701, 0x0452, 0x0000 }, + { 0x8701, 0x0455, 0x2000 }, + { 0x0701, 0x0454, 0x0000 }, + { 0x0701, 0x0456, 0x0000 }, + { 0x8701, 0x045b, 0x3000 }, + { 0x8701, 0x0459, 0x2000 }, + { 0x0701, 0x0458, 0x0000 }, + { 0x0701, 0x045a, 0x0000 }, + { 0x8701, 0x045d, 0x2000 }, + { 0x0701, 0x045c, 0x0000 }, + { 0x0701, 0x045e, 0x0000 }, + { 0x9a01, 0xd000, 0x8000 }, + { 0x8d01, 0x04a1, 0x7000 }, + { 0x8701, 0x047f, 0x6000 }, + { 0x8701, 0x046f, 0x5000 }, + { 0x8701, 0x0467, 0x4000 }, + { 0x8701, 0x0463, 0x3000 }, + { 0x8701, 0x0461, 0x2000 }, + { 0x0701, 0x0460, 0x0000 }, + { 0x0701, 0x0462, 0x0000 }, + { 0x8701, 0x0465, 0x2000 }, + { 0x0701, 0x0464, 0x0000 }, + { 0x0701, 0x0466, 0x0000 }, + { 0x8701, 0x046b, 0x3000 }, + { 0x8701, 0x0469, 0x2000 }, + { 0x0701, 0x0468, 0x0000 }, + { 0x0701, 0x046a, 0x0000 }, + { 0x8701, 0x046d, 0x2000 }, + { 0x0701, 0x046c, 0x0000 }, + { 0x0701, 0x046e, 0x0000 }, + { 0x8701, 0x0477, 0x4000 }, + { 0x8701, 0x0473, 0x3000 }, + { 0x8701, 0x0471, 0x2000 }, + { 0x0701, 0x0470, 0x0000 }, + { 0x0701, 0x0472, 0x0000 }, + { 0x8701, 0x0475, 0x2000 }, + { 0x0701, 0x0474, 0x0000 }, + { 0x0701, 0x0476, 0x0000 }, + { 0x8701, 0x047b, 0x3000 }, + { 0x8701, 0x0479, 0x2000 }, + { 0x0701, 0x0478, 0x0000 }, + { 0x0701, 0x047a, 0x0000 }, + { 0x8701, 0x047d, 0x2000 }, + { 0x0701, 0x047c, 0x0000 }, + { 0x0701, 0x047e, 0x0000 }, + { 0x8701, 0x048f, 0x5000 }, + { 0x8701, 0x0487, 0x4000 }, + { 0x8701, 0x0483, 0x3000 }, + { 0x8701, 0x0481, 0x2000 }, + { 0x0701, 0x0480, 0x0000 }, + { 0x0701, 0x0482, 0x0000 }, + { 0x8701, 0x0485, 0x2000 }, + { 0x0701, 0x0484, 0x0000 }, + { 0x0701, 0x0486, 0x0000 }, + { 0x8701, 0x048b, 0x3000 }, + { 0x8701, 0x0489, 0x2000 }, + { 0x0701, 0x0488, 0x0000 }, + { 0x0701, 0x048a, 0x0000 }, + { 0x8701, 0x048d, 0x2000 }, + { 0x0701, 0x048c, 0x0000 }, + { 0x0701, 0x048e, 0x0000 }, + { 0x8701, 0x0497, 0x4000 }, + { 0x8701, 0x0493, 0x3000 }, + { 0x8701, 0x0491, 0x2000 }, + { 0x0701, 0x0490, 0x0000 }, + { 0x0701, 0x0492, 0x0000 }, + { 0x8701, 0x0495, 0x2000 }, + { 0x0701, 0x0494, 0x0000 }, + { 0x0701, 0x0496, 0x0000 }, + { 0x8701, 0x049b, 0x3000 }, + { 0x8701, 0x0499, 0x2000 }, + { 0x0701, 0x0498, 0x0000 }, + { 0x0701, 0x049a, 0x0000 }, + { 0x8701, 0x049d, 0x2000 }, + { 0x0701, 0x049c, 0x0000 }, + { 0x0d01, 0x04a0, 0x0000 }, + { 0x8701, 0x081a, 0x6000 }, + { 0x8701, 0x080a, 0x5000 }, + { 0x8d01, 0x04a9, 0x4000 }, + { 0x8d01, 0x04a5, 0x3000 }, + { 0x8d01, 0x04a3, 0x2000 }, + { 0x0d01, 0x04a2, 0x0000 }, + { 0x0d01, 0x04a4, 0x0000 }, + { 0x8d01, 0x04a7, 0x2000 }, + { 0x0d01, 0x04a6, 0x0000 }, + { 0x0d01, 0x04a8, 0x0000 }, + { 0x8701, 0x0803, 0x3000 }, + { 0x8701, 0x0801, 0x2000 }, + { 0x0701, 0x0800, 0x0000 }, + { 0x0701, 0x0802, 0x0000 }, + { 0x8701, 0x0805, 0x2000 }, + { 0x0701, 0x0804, 0x0000 }, + { 0x0701, 0x0808, 0x0000 }, + { 0x8701, 0x0812, 0x4000 }, + { 0x8701, 0x080e, 0x3000 }, + { 0x8701, 0x080c, 0x2000 }, + { 0x0701, 0x080b, 0x0000 }, + { 0x0701, 0x080d, 0x0000 }, + { 0x8701, 0x0810, 0x2000 }, + { 0x0701, 0x080f, 0x0000 }, + { 0x0701, 0x0811, 0x0000 }, + { 0x8701, 0x0816, 0x3000 }, + { 0x8701, 0x0814, 0x2000 }, + { 0x0701, 0x0813, 0x0000 }, + { 0x0701, 0x0815, 0x0000 }, + { 0x8701, 0x0818, 0x2000 }, + { 0x0701, 0x0817, 0x0000 }, + { 0x0701, 0x0819, 0x0000 }, + { 0x8701, 0x082a, 0x5000 }, + { 0x8701, 0x0822, 0x4000 }, + { 0x8701, 0x081e, 0x3000 }, + { 0x8701, 0x081c, 0x2000 }, + { 0x0701, 0x081b, 0x0000 }, + { 0x0701, 0x081d, 0x0000 }, + { 0x8701, 0x0820, 0x2000 }, + { 0x0701, 0x081f, 0x0000 }, + { 0x0701, 0x0821, 0x0000 }, + { 0x8701, 0x0826, 0x3000 }, + { 0x8701, 0x0824, 0x2000 }, + { 0x0701, 0x0823, 0x0000 }, + { 0x0701, 0x0825, 0x0000 }, + { 0x8701, 0x0828, 0x2000 }, + { 0x0701, 0x0827, 0x0000 }, + { 0x0701, 0x0829, 0x0000 }, + { 0x8701, 0x0832, 0x4000 }, + { 0x8701, 0x082e, 0x3000 }, + { 0x8701, 0x082c, 0x2000 }, + { 0x0701, 0x082b, 0x0000 }, + { 0x0701, 0x082d, 0x0000 }, + { 0x8701, 0x0830, 0x2000 }, + { 0x0701, 0x082f, 0x0000 }, + { 0x0701, 0x0831, 0x0000 }, + { 0x8701, 0x0837, 0x3000 }, + { 0x8701, 0x0834, 0x2000 }, + { 0x0701, 0x0833, 0x0000 }, + { 0x0701, 0x0835, 0x0000 }, + { 0x8701, 0x083c, 0x2000 }, + { 0x0701, 0x0838, 0x0000 }, + { 0x0701, 0x083f, 0x0000 }, + { 0x9a01, 0xd040, 0x7000 }, + { 0x9a01, 0xd020, 0x6000 }, + { 0x9a01, 0xd010, 0x5000 }, + { 0x9a01, 0xd008, 0x4000 }, + { 0x9a01, 0xd004, 0x3000 }, + { 0x9a01, 0xd002, 0x2000 }, + { 0x1a01, 0xd001, 0x0000 }, + { 0x1a01, 0xd003, 0x0000 }, + { 0x9a01, 0xd006, 0x2000 }, + { 0x1a01, 0xd005, 0x0000 }, + { 0x1a01, 0xd007, 0x0000 }, + { 0x9a01, 0xd00c, 0x3000 }, + { 0x9a01, 0xd00a, 0x2000 }, + { 0x1a01, 0xd009, 0x0000 }, + { 0x1a01, 0xd00b, 0x0000 }, + { 0x9a01, 0xd00e, 0x2000 }, + { 0x1a01, 0xd00d, 0x0000 }, + { 0x1a01, 0xd00f, 0x0000 }, + { 0x9a01, 0xd018, 0x4000 }, + { 0x9a01, 0xd014, 0x3000 }, + { 0x9a01, 0xd012, 0x2000 }, + { 0x1a01, 0xd011, 0x0000 }, + { 0x1a01, 0xd013, 0x0000 }, + { 0x9a01, 0xd016, 0x2000 }, + { 0x1a01, 0xd015, 0x0000 }, + { 0x1a01, 0xd017, 0x0000 }, + { 0x9a01, 0xd01c, 0x3000 }, + { 0x9a01, 0xd01a, 0x2000 }, + { 0x1a01, 0xd019, 0x0000 }, + { 0x1a01, 0xd01b, 0x0000 }, + { 0x9a01, 0xd01e, 0x2000 }, + { 0x1a01, 0xd01d, 0x0000 }, + { 0x1a01, 0xd01f, 0x0000 }, + { 0x9a01, 0xd030, 0x5000 }, + { 0x9a01, 0xd028, 0x4000 }, + { 0x9a01, 0xd024, 0x3000 }, + { 0x9a01, 0xd022, 0x2000 }, + { 0x1a01, 0xd021, 0x0000 }, + { 0x1a01, 0xd023, 0x0000 }, + { 0x9a01, 0xd026, 0x2000 }, + { 0x1a01, 0xd025, 0x0000 }, + { 0x1a01, 0xd027, 0x0000 }, + { 0x9a01, 0xd02c, 0x3000 }, + { 0x9a01, 0xd02a, 0x2000 }, + { 0x1a01, 0xd029, 0x0000 }, + { 0x1a01, 0xd02b, 0x0000 }, + { 0x9a01, 0xd02e, 0x2000 }, + { 0x1a01, 0xd02d, 0x0000 }, + { 0x1a01, 0xd02f, 0x0000 }, + { 0x9a01, 0xd038, 0x4000 }, + { 0x9a01, 0xd034, 0x3000 }, + { 0x9a01, 0xd032, 0x2000 }, + { 0x1a01, 0xd031, 0x0000 }, + { 0x1a01, 0xd033, 0x0000 }, + { 0x9a01, 0xd036, 0x2000 }, + { 0x1a01, 0xd035, 0x0000 }, + { 0x1a01, 0xd037, 0x0000 }, + { 0x9a01, 0xd03c, 0x3000 }, + { 0x9a01, 0xd03a, 0x2000 }, + { 0x1a01, 0xd039, 0x0000 }, + { 0x1a01, 0xd03b, 0x0000 }, + { 0x9a01, 0xd03e, 0x2000 }, + { 0x1a01, 0xd03d, 0x0000 }, + { 0x1a01, 0xd03f, 0x0000 }, + { 0x9a01, 0xd060, 0x6000 }, + { 0x9a01, 0xd050, 0x5000 }, + { 0x9a01, 0xd048, 0x4000 }, + { 0x9a01, 0xd044, 0x3000 }, + { 0x9a01, 0xd042, 0x2000 }, + { 0x1a01, 0xd041, 0x0000 }, + { 0x1a01, 0xd043, 0x0000 }, + { 0x9a01, 0xd046, 0x2000 }, + { 0x1a01, 0xd045, 0x0000 }, + { 0x1a01, 0xd047, 0x0000 }, + { 0x9a01, 0xd04c, 0x3000 }, + { 0x9a01, 0xd04a, 0x2000 }, + { 0x1a01, 0xd049, 0x0000 }, + { 0x1a01, 0xd04b, 0x0000 }, + { 0x9a01, 0xd04e, 0x2000 }, + { 0x1a01, 0xd04d, 0x0000 }, + { 0x1a01, 0xd04f, 0x0000 }, + { 0x9a01, 0xd058, 0x4000 }, + { 0x9a01, 0xd054, 0x3000 }, + { 0x9a01, 0xd052, 0x2000 }, + { 0x1a01, 0xd051, 0x0000 }, + { 0x1a01, 0xd053, 0x0000 }, + { 0x9a01, 0xd056, 0x2000 }, + { 0x1a01, 0xd055, 0x0000 }, + { 0x1a01, 0xd057, 0x0000 }, + { 0x9a01, 0xd05c, 0x3000 }, + { 0x9a01, 0xd05a, 0x2000 }, + { 0x1a01, 0xd059, 0x0000 }, + { 0x1a01, 0xd05b, 0x0000 }, + { 0x9a01, 0xd05e, 0x2000 }, + { 0x1a01, 0xd05d, 0x0000 }, + { 0x1a01, 0xd05f, 0x0000 }, + { 0x9a01, 0xd070, 0x5000 }, + { 0x9a01, 0xd068, 0x4000 }, + { 0x9a01, 0xd064, 0x3000 }, + { 0x9a01, 0xd062, 0x2000 }, + { 0x1a01, 0xd061, 0x0000 }, + { 0x1a01, 0xd063, 0x0000 }, + { 0x9a01, 0xd066, 0x2000 }, + { 0x1a01, 0xd065, 0x0000 }, + { 0x1a01, 0xd067, 0x0000 }, + { 0x9a01, 0xd06c, 0x3000 }, + { 0x9a01, 0xd06a, 0x2000 }, + { 0x1a01, 0xd069, 0x0000 }, + { 0x1a01, 0xd06b, 0x0000 }, + { 0x9a01, 0xd06e, 0x2000 }, + { 0x1a01, 0xd06d, 0x0000 }, + { 0x1a01, 0xd06f, 0x0000 }, + { 0x9a01, 0xd078, 0x4000 }, + { 0x9a01, 0xd074, 0x3000 }, + { 0x9a01, 0xd072, 0x2000 }, + { 0x1a01, 0xd071, 0x0000 }, + { 0x1a01, 0xd073, 0x0000 }, + { 0x9a01, 0xd076, 0x2000 }, + { 0x1a01, 0xd075, 0x0000 }, + { 0x1a01, 0xd077, 0x0000 }, + { 0x9a01, 0xd07c, 0x3000 }, + { 0x9a01, 0xd07a, 0x2000 }, + { 0x1a01, 0xd079, 0x0000 }, + { 0x1a01, 0xd07b, 0x0000 }, + { 0x9a01, 0xd07e, 0x2000 }, + { 0x1a01, 0xd07d, 0x0000 }, + { 0x1a01, 0xd07f, 0x0000 }, + { 0x9a01, 0xd18d, 0x9000 }, + { 0x9a01, 0xd10a, 0x8000 }, + { 0x9a01, 0xd0c0, 0x7000 }, + { 0x9a01, 0xd0a0, 0x6000 }, + { 0x9a01, 0xd090, 0x5000 }, + { 0x9a01, 0xd088, 0x4000 }, + { 0x9a01, 0xd084, 0x3000 }, + { 0x9a01, 0xd082, 0x2000 }, + { 0x1a01, 0xd081, 0x0000 }, + { 0x1a01, 0xd083, 0x0000 }, + { 0x9a01, 0xd086, 0x2000 }, + { 0x1a01, 0xd085, 0x0000 }, + { 0x1a01, 0xd087, 0x0000 }, + { 0x9a01, 0xd08c, 0x3000 }, + { 0x9a01, 0xd08a, 0x2000 }, + { 0x1a01, 0xd089, 0x0000 }, + { 0x1a01, 0xd08b, 0x0000 }, + { 0x9a01, 0xd08e, 0x2000 }, + { 0x1a01, 0xd08d, 0x0000 }, + { 0x1a01, 0xd08f, 0x0000 }, + { 0x9a01, 0xd098, 0x4000 }, + { 0x9a01, 0xd094, 0x3000 }, + { 0x9a01, 0xd092, 0x2000 }, + { 0x1a01, 0xd091, 0x0000 }, + { 0x1a01, 0xd093, 0x0000 }, + { 0x9a01, 0xd096, 0x2000 }, + { 0x1a01, 0xd095, 0x0000 }, + { 0x1a01, 0xd097, 0x0000 }, + { 0x9a01, 0xd09c, 0x3000 }, + { 0x9a01, 0xd09a, 0x2000 }, + { 0x1a01, 0xd099, 0x0000 }, + { 0x1a01, 0xd09b, 0x0000 }, + { 0x9a01, 0xd09e, 0x2000 }, + { 0x1a01, 0xd09d, 0x0000 }, + { 0x1a01, 0xd09f, 0x0000 }, + { 0x9a01, 0xd0b0, 0x5000 }, + { 0x9a01, 0xd0a8, 0x4000 }, + { 0x9a01, 0xd0a4, 0x3000 }, + { 0x9a01, 0xd0a2, 0x2000 }, + { 0x1a01, 0xd0a1, 0x0000 }, + { 0x1a01, 0xd0a3, 0x0000 }, + { 0x9a01, 0xd0a6, 0x2000 }, + { 0x1a01, 0xd0a5, 0x0000 }, + { 0x1a01, 0xd0a7, 0x0000 }, + { 0x9a01, 0xd0ac, 0x3000 }, + { 0x9a01, 0xd0aa, 0x2000 }, + { 0x1a01, 0xd0a9, 0x0000 }, + { 0x1a01, 0xd0ab, 0x0000 }, + { 0x9a01, 0xd0ae, 0x2000 }, + { 0x1a01, 0xd0ad, 0x0000 }, + { 0x1a01, 0xd0af, 0x0000 }, + { 0x9a01, 0xd0b8, 0x4000 }, + { 0x9a01, 0xd0b4, 0x3000 }, + { 0x9a01, 0xd0b2, 0x2000 }, + { 0x1a01, 0xd0b1, 0x0000 }, + { 0x1a01, 0xd0b3, 0x0000 }, + { 0x9a01, 0xd0b6, 0x2000 }, + { 0x1a01, 0xd0b5, 0x0000 }, + { 0x1a01, 0xd0b7, 0x0000 }, + { 0x9a01, 0xd0bc, 0x3000 }, + { 0x9a01, 0xd0ba, 0x2000 }, + { 0x1a01, 0xd0b9, 0x0000 }, + { 0x1a01, 0xd0bb, 0x0000 }, + { 0x9a01, 0xd0be, 0x2000 }, + { 0x1a01, 0xd0bd, 0x0000 }, + { 0x1a01, 0xd0bf, 0x0000 }, + { 0x9a01, 0xd0e0, 0x6000 }, + { 0x9a01, 0xd0d0, 0x5000 }, + { 0x9a01, 0xd0c8, 0x4000 }, + { 0x9a01, 0xd0c4, 0x3000 }, + { 0x9a01, 0xd0c2, 0x2000 }, + { 0x1a01, 0xd0c1, 0x0000 }, + { 0x1a01, 0xd0c3, 0x0000 }, + { 0x9a01, 0xd0c6, 0x2000 }, + { 0x1a01, 0xd0c5, 0x0000 }, + { 0x1a01, 0xd0c7, 0x0000 }, + { 0x9a01, 0xd0cc, 0x3000 }, + { 0x9a01, 0xd0ca, 0x2000 }, + { 0x1a01, 0xd0c9, 0x0000 }, + { 0x1a01, 0xd0cb, 0x0000 }, + { 0x9a01, 0xd0ce, 0x2000 }, + { 0x1a01, 0xd0cd, 0x0000 }, + { 0x1a01, 0xd0cf, 0x0000 }, + { 0x9a01, 0xd0d8, 0x4000 }, + { 0x9a01, 0xd0d4, 0x3000 }, + { 0x9a01, 0xd0d2, 0x2000 }, + { 0x1a01, 0xd0d1, 0x0000 }, + { 0x1a01, 0xd0d3, 0x0000 }, + { 0x9a01, 0xd0d6, 0x2000 }, + { 0x1a01, 0xd0d5, 0x0000 }, + { 0x1a01, 0xd0d7, 0x0000 }, + { 0x9a01, 0xd0dc, 0x3000 }, + { 0x9a01, 0xd0da, 0x2000 }, + { 0x1a01, 0xd0d9, 0x0000 }, + { 0x1a01, 0xd0db, 0x0000 }, + { 0x9a01, 0xd0de, 0x2000 }, + { 0x1a01, 0xd0dd, 0x0000 }, + { 0x1a01, 0xd0df, 0x0000 }, + { 0x9a01, 0xd0f0, 0x5000 }, + { 0x9a01, 0xd0e8, 0x4000 }, + { 0x9a01, 0xd0e4, 0x3000 }, + { 0x9a01, 0xd0e2, 0x2000 }, + { 0x1a01, 0xd0e1, 0x0000 }, + { 0x1a01, 0xd0e3, 0x0000 }, + { 0x9a01, 0xd0e6, 0x2000 }, + { 0x1a01, 0xd0e5, 0x0000 }, + { 0x1a01, 0xd0e7, 0x0000 }, + { 0x9a01, 0xd0ec, 0x3000 }, + { 0x9a01, 0xd0ea, 0x2000 }, + { 0x1a01, 0xd0e9, 0x0000 }, + { 0x1a01, 0xd0eb, 0x0000 }, + { 0x9a01, 0xd0ee, 0x2000 }, + { 0x1a01, 0xd0ed, 0x0000 }, + { 0x1a01, 0xd0ef, 0x0000 }, + { 0x9a01, 0xd102, 0x4000 }, + { 0x9a01, 0xd0f4, 0x3000 }, + { 0x9a01, 0xd0f2, 0x2000 }, + { 0x1a01, 0xd0f1, 0x0000 }, + { 0x1a01, 0xd0f3, 0x0000 }, + { 0x9a01, 0xd100, 0x2000 }, + { 0x1a01, 0xd0f5, 0x0000 }, + { 0x1a01, 0xd101, 0x0000 }, + { 0x9a01, 0xd106, 0x3000 }, + { 0x9a01, 0xd104, 0x2000 }, + { 0x1a01, 0xd103, 0x0000 }, + { 0x1a01, 0xd105, 0x0000 }, + { 0x9a01, 0xd108, 0x2000 }, + { 0x1a01, 0xd107, 0x0000 }, + { 0x1a01, 0xd109, 0x0000 }, + { 0x9a01, 0xd14d, 0x7000 }, + { 0x9a01, 0xd12d, 0x6000 }, + { 0x9a01, 0xd11a, 0x5000 }, + { 0x9a01, 0xd112, 0x4000 }, + { 0x9a01, 0xd10e, 0x3000 }, + { 0x9a01, 0xd10c, 0x2000 }, + { 0x1a01, 0xd10b, 0x0000 }, + { 0x1a01, 0xd10d, 0x0000 }, + { 0x9a01, 0xd110, 0x2000 }, + { 0x1a01, 0xd10f, 0x0000 }, + { 0x1a01, 0xd111, 0x0000 }, + { 0x9a01, 0xd116, 0x3000 }, + { 0x9a01, 0xd114, 0x2000 }, + { 0x1a01, 0xd113, 0x0000 }, + { 0x1a01, 0xd115, 0x0000 }, + { 0x9a01, 0xd118, 0x2000 }, + { 0x1a01, 0xd117, 0x0000 }, + { 0x1a01, 0xd119, 0x0000 }, + { 0x9a01, 0xd122, 0x4000 }, + { 0x9a01, 0xd11e, 0x3000 }, + { 0x9a01, 0xd11c, 0x2000 }, + { 0x1a01, 0xd11b, 0x0000 }, + { 0x1a01, 0xd11d, 0x0000 }, + { 0x9a01, 0xd120, 0x2000 }, + { 0x1a01, 0xd11f, 0x0000 }, + { 0x1a01, 0xd121, 0x0000 }, + { 0x9a01, 0xd126, 0x3000 }, + { 0x9a01, 0xd124, 0x2000 }, + { 0x1a01, 0xd123, 0x0000 }, + { 0x1a01, 0xd125, 0x0000 }, + { 0x9a01, 0xd12b, 0x2000 }, + { 0x1a01, 0xd12a, 0x0000 }, + { 0x1a01, 0xd12c, 0x0000 }, + { 0x9a01, 0xd13d, 0x5000 }, + { 0x9a01, 0xd135, 0x4000 }, + { 0x9a01, 0xd131, 0x3000 }, + { 0x9a01, 0xd12f, 0x2000 }, + { 0x1a01, 0xd12e, 0x0000 }, + { 0x1a01, 0xd130, 0x0000 }, + { 0x9a01, 0xd133, 0x2000 }, + { 0x1a01, 0xd132, 0x0000 }, + { 0x1a01, 0xd134, 0x0000 }, + { 0x9a01, 0xd139, 0x3000 }, + { 0x9a01, 0xd137, 0x2000 }, + { 0x1a01, 0xd136, 0x0000 }, + { 0x1a01, 0xd138, 0x0000 }, + { 0x9a01, 0xd13b, 0x2000 }, + { 0x1a01, 0xd13a, 0x0000 }, + { 0x1a01, 0xd13c, 0x0000 }, + { 0x9a01, 0xd145, 0x4000 }, + { 0x9a01, 0xd141, 0x3000 }, + { 0x9a01, 0xd13f, 0x2000 }, + { 0x1a01, 0xd13e, 0x0000 }, + { 0x1a01, 0xd140, 0x0000 }, + { 0x9a01, 0xd143, 0x2000 }, + { 0x1a01, 0xd142, 0x0000 }, + { 0x1a01, 0xd144, 0x0000 }, + { 0x9a01, 0xd149, 0x3000 }, + { 0x9a01, 0xd147, 0x2000 }, + { 0x1a01, 0xd146, 0x0000 }, + { 0x1a01, 0xd148, 0x0000 }, + { 0x9a01, 0xd14b, 0x2000 }, + { 0x1a01, 0xd14a, 0x0000 }, + { 0x1a01, 0xd14c, 0x0000 }, + { 0x8a01, 0xd16d, 0x6000 }, + { 0x9a01, 0xd15d, 0x5000 }, + { 0x9a01, 0xd155, 0x4000 }, + { 0x9a01, 0xd151, 0x3000 }, + { 0x9a01, 0xd14f, 0x2000 }, + { 0x1a01, 0xd14e, 0x0000 }, + { 0x1a01, 0xd150, 0x0000 }, + { 0x9a01, 0xd153, 0x2000 }, + { 0x1a01, 0xd152, 0x0000 }, + { 0x1a01, 0xd154, 0x0000 }, + { 0x9a01, 0xd159, 0x3000 }, + { 0x9a01, 0xd157, 0x2000 }, + { 0x1a01, 0xd156, 0x0000 }, + { 0x1a01, 0xd158, 0x0000 }, + { 0x9a01, 0xd15b, 0x2000 }, + { 0x1a01, 0xd15a, 0x0000 }, + { 0x1a01, 0xd15c, 0x0000 }, + { 0x8a01, 0xd165, 0x4000 }, + { 0x9a01, 0xd161, 0x3000 }, + { 0x9a01, 0xd15f, 0x2000 }, + { 0x1a01, 0xd15e, 0x0000 }, + { 0x1a01, 0xd160, 0x0000 }, + { 0x9a01, 0xd163, 0x2000 }, + { 0x1a01, 0xd162, 0x0000 }, + { 0x1a01, 0xd164, 0x0000 }, + { 0x8c01, 0xd169, 0x3000 }, + { 0x8c01, 0xd167, 0x2000 }, + { 0x0a01, 0xd166, 0x0000 }, + { 0x0c01, 0xd168, 0x0000 }, + { 0x9a01, 0xd16b, 0x2000 }, + { 0x1a01, 0xd16a, 0x0000 }, + { 0x1a01, 0xd16c, 0x0000 }, + { 0x8c01, 0xd17d, 0x5000 }, + { 0x8101, 0xd175, 0x4000 }, + { 0x8a01, 0xd171, 0x3000 }, + { 0x8a01, 0xd16f, 0x2000 }, + { 0x0a01, 0xd16e, 0x0000 }, + { 0x0a01, 0xd170, 0x0000 }, + { 0x8101, 0xd173, 0x2000 }, + { 0x0a01, 0xd172, 0x0000 }, + { 0x0101, 0xd174, 0x0000 }, + { 0x8101, 0xd179, 0x3000 }, + { 0x8101, 0xd177, 0x2000 }, + { 0x0101, 0xd176, 0x0000 }, + { 0x0101, 0xd178, 0x0000 }, + { 0x8c01, 0xd17b, 0x2000 }, + { 0x0101, 0xd17a, 0x0000 }, + { 0x0c01, 0xd17c, 0x0000 }, + { 0x8c01, 0xd185, 0x4000 }, + { 0x8c01, 0xd181, 0x3000 }, + { 0x8c01, 0xd17f, 0x2000 }, + { 0x0c01, 0xd17e, 0x0000 }, + { 0x0c01, 0xd180, 0x0000 }, + { 0x9a01, 0xd183, 0x2000 }, + { 0x0c01, 0xd182, 0x0000 }, + { 0x1a01, 0xd184, 0x0000 }, + { 0x8c01, 0xd189, 0x3000 }, + { 0x8c01, 0xd187, 0x2000 }, + { 0x0c01, 0xd186, 0x0000 }, + { 0x0c01, 0xd188, 0x0000 }, + { 0x8c01, 0xd18b, 0x2000 }, + { 0x0c01, 0xd18a, 0x0000 }, + { 0x1a01, 0xd18c, 0x0000 }, + { 0x9a01, 0xd32f, 0x8000 }, + { 0x9a01, 0xd1cd, 0x7000 }, + { 0x8c01, 0xd1ad, 0x6000 }, + { 0x9a01, 0xd19d, 0x5000 }, + { 0x9a01, 0xd195, 0x4000 }, + { 0x9a01, 0xd191, 0x3000 }, + { 0x9a01, 0xd18f, 0x2000 }, + { 0x1a01, 0xd18e, 0x0000 }, + { 0x1a01, 0xd190, 0x0000 }, + { 0x9a01, 0xd193, 0x2000 }, + { 0x1a01, 0xd192, 0x0000 }, + { 0x1a01, 0xd194, 0x0000 }, + { 0x9a01, 0xd199, 0x3000 }, + { 0x9a01, 0xd197, 0x2000 }, + { 0x1a01, 0xd196, 0x0000 }, + { 0x1a01, 0xd198, 0x0000 }, + { 0x9a01, 0xd19b, 0x2000 }, + { 0x1a01, 0xd19a, 0x0000 }, + { 0x1a01, 0xd19c, 0x0000 }, + { 0x9a01, 0xd1a5, 0x4000 }, + { 0x9a01, 0xd1a1, 0x3000 }, + { 0x9a01, 0xd19f, 0x2000 }, + { 0x1a01, 0xd19e, 0x0000 }, + { 0x1a01, 0xd1a0, 0x0000 }, + { 0x9a01, 0xd1a3, 0x2000 }, + { 0x1a01, 0xd1a2, 0x0000 }, + { 0x1a01, 0xd1a4, 0x0000 }, + { 0x9a01, 0xd1a9, 0x3000 }, + { 0x9a01, 0xd1a7, 0x2000 }, + { 0x1a01, 0xd1a6, 0x0000 }, + { 0x1a01, 0xd1a8, 0x0000 }, + { 0x8c01, 0xd1ab, 0x2000 }, + { 0x0c01, 0xd1aa, 0x0000 }, + { 0x0c01, 0xd1ac, 0x0000 }, + { 0x9a01, 0xd1bd, 0x5000 }, + { 0x9a01, 0xd1b5, 0x4000 }, + { 0x9a01, 0xd1b1, 0x3000 }, + { 0x9a01, 0xd1af, 0x2000 }, + { 0x1a01, 0xd1ae, 0x0000 }, + { 0x1a01, 0xd1b0, 0x0000 }, + { 0x9a01, 0xd1b3, 0x2000 }, + { 0x1a01, 0xd1b2, 0x0000 }, + { 0x1a01, 0xd1b4, 0x0000 }, + { 0x9a01, 0xd1b9, 0x3000 }, + { 0x9a01, 0xd1b7, 0x2000 }, + { 0x1a01, 0xd1b6, 0x0000 }, + { 0x1a01, 0xd1b8, 0x0000 }, + { 0x9a01, 0xd1bb, 0x2000 }, + { 0x1a01, 0xd1ba, 0x0000 }, + { 0x1a01, 0xd1bc, 0x0000 }, + { 0x9a01, 0xd1c5, 0x4000 }, + { 0x9a01, 0xd1c1, 0x3000 }, + { 0x9a01, 0xd1bf, 0x2000 }, + { 0x1a01, 0xd1be, 0x0000 }, + { 0x1a01, 0xd1c0, 0x0000 }, + { 0x9a01, 0xd1c3, 0x2000 }, + { 0x1a01, 0xd1c2, 0x0000 }, + { 0x1a01, 0xd1c4, 0x0000 }, + { 0x9a01, 0xd1c9, 0x3000 }, + { 0x9a01, 0xd1c7, 0x2000 }, + { 0x1a01, 0xd1c6, 0x0000 }, + { 0x1a01, 0xd1c8, 0x0000 }, + { 0x9a01, 0xd1cb, 0x2000 }, + { 0x1a01, 0xd1ca, 0x0000 }, + { 0x1a01, 0xd1cc, 0x0000 }, + { 0x9a01, 0xd30f, 0x6000 }, + { 0x9a01, 0xd1dd, 0x5000 }, + { 0x9a01, 0xd1d5, 0x4000 }, + { 0x9a01, 0xd1d1, 0x3000 }, + { 0x9a01, 0xd1cf, 0x2000 }, + { 0x1a01, 0xd1ce, 0x0000 }, + { 0x1a01, 0xd1d0, 0x0000 }, + { 0x9a01, 0xd1d3, 0x2000 }, + { 0x1a01, 0xd1d2, 0x0000 }, + { 0x1a01, 0xd1d4, 0x0000 }, + { 0x9a01, 0xd1d9, 0x3000 }, + { 0x9a01, 0xd1d7, 0x2000 }, + { 0x1a01, 0xd1d6, 0x0000 }, + { 0x1a01, 0xd1d8, 0x0000 }, + { 0x9a01, 0xd1db, 0x2000 }, + { 0x1a01, 0xd1da, 0x0000 }, + { 0x1a01, 0xd1dc, 0x0000 }, + { 0x9a01, 0xd307, 0x4000 }, + { 0x9a01, 0xd303, 0x3000 }, + { 0x9a01, 0xd301, 0x2000 }, + { 0x1a01, 0xd300, 0x0000 }, + { 0x1a01, 0xd302, 0x0000 }, + { 0x9a01, 0xd305, 0x2000 }, + { 0x1a01, 0xd304, 0x0000 }, + { 0x1a01, 0xd306, 0x0000 }, + { 0x9a01, 0xd30b, 0x3000 }, + { 0x9a01, 0xd309, 0x2000 }, + { 0x1a01, 0xd308, 0x0000 }, + { 0x1a01, 0xd30a, 0x0000 }, + { 0x9a01, 0xd30d, 0x2000 }, + { 0x1a01, 0xd30c, 0x0000 }, + { 0x1a01, 0xd30e, 0x0000 }, + { 0x9a01, 0xd31f, 0x5000 }, + { 0x9a01, 0xd317, 0x4000 }, + { 0x9a01, 0xd313, 0x3000 }, + { 0x9a01, 0xd311, 0x2000 }, + { 0x1a01, 0xd310, 0x0000 }, + { 0x1a01, 0xd312, 0x0000 }, + { 0x9a01, 0xd315, 0x2000 }, + { 0x1a01, 0xd314, 0x0000 }, + { 0x1a01, 0xd316, 0x0000 }, + { 0x9a01, 0xd31b, 0x3000 }, + { 0x9a01, 0xd319, 0x2000 }, + { 0x1a01, 0xd318, 0x0000 }, + { 0x1a01, 0xd31a, 0x0000 }, + { 0x9a01, 0xd31d, 0x2000 }, + { 0x1a01, 0xd31c, 0x0000 }, + { 0x1a01, 0xd31e, 0x0000 }, + { 0x9a01, 0xd327, 0x4000 }, + { 0x9a01, 0xd323, 0x3000 }, + { 0x9a01, 0xd321, 0x2000 }, + { 0x1a01, 0xd320, 0x0000 }, + { 0x1a01, 0xd322, 0x0000 }, + { 0x9a01, 0xd325, 0x2000 }, + { 0x1a01, 0xd324, 0x0000 }, + { 0x1a01, 0xd326, 0x0000 }, + { 0x9a01, 0xd32b, 0x3000 }, + { 0x9a01, 0xd329, 0x2000 }, + { 0x1a01, 0xd328, 0x0000 }, + { 0x1a01, 0xd32a, 0x0000 }, + { 0x9a01, 0xd32d, 0x2000 }, + { 0x1a01, 0xd32c, 0x0000 }, + { 0x1a01, 0xd32e, 0x0000 }, + { 0x8901, 0xd418, 0x7000 }, + { 0x9a01, 0xd34f, 0x6000 }, + { 0x9a01, 0xd33f, 0x5000 }, + { 0x9a01, 0xd337, 0x4000 }, + { 0x9a01, 0xd333, 0x3000 }, + { 0x9a01, 0xd331, 0x2000 }, + { 0x1a01, 0xd330, 0x0000 }, + { 0x1a01, 0xd332, 0x0000 }, + { 0x9a01, 0xd335, 0x2000 }, + { 0x1a01, 0xd334, 0x0000 }, + { 0x1a01, 0xd336, 0x0000 }, + { 0x9a01, 0xd33b, 0x3000 }, + { 0x9a01, 0xd339, 0x2000 }, + { 0x1a01, 0xd338, 0x0000 }, + { 0x1a01, 0xd33a, 0x0000 }, + { 0x9a01, 0xd33d, 0x2000 }, + { 0x1a01, 0xd33c, 0x0000 }, + { 0x1a01, 0xd33e, 0x0000 }, + { 0x9a01, 0xd347, 0x4000 }, + { 0x9a01, 0xd343, 0x3000 }, + { 0x9a01, 0xd341, 0x2000 }, + { 0x1a01, 0xd340, 0x0000 }, + { 0x1a01, 0xd342, 0x0000 }, + { 0x9a01, 0xd345, 0x2000 }, + { 0x1a01, 0xd344, 0x0000 }, + { 0x1a01, 0xd346, 0x0000 }, + { 0x9a01, 0xd34b, 0x3000 }, + { 0x9a01, 0xd349, 0x2000 }, + { 0x1a01, 0xd348, 0x0000 }, + { 0x1a01, 0xd34a, 0x0000 }, + { 0x9a01, 0xd34d, 0x2000 }, + { 0x1a01, 0xd34c, 0x0000 }, + { 0x1a01, 0xd34e, 0x0000 }, + { 0x8901, 0xd408, 0x5000 }, + { 0x8901, 0xd400, 0x4000 }, + { 0x9a01, 0xd353, 0x3000 }, + { 0x9a01, 0xd351, 0x2000 }, + { 0x1a01, 0xd350, 0x0000 }, + { 0x1a01, 0xd352, 0x0000 }, + { 0x9a01, 0xd355, 0x2000 }, + { 0x1a01, 0xd354, 0x0000 }, + { 0x1a01, 0xd356, 0x0000 }, + { 0x8901, 0xd404, 0x3000 }, + { 0x8901, 0xd402, 0x2000 }, + { 0x0901, 0xd401, 0x0000 }, + { 0x0901, 0xd403, 0x0000 }, + { 0x8901, 0xd406, 0x2000 }, + { 0x0901, 0xd405, 0x0000 }, + { 0x0901, 0xd407, 0x0000 }, + { 0x8901, 0xd410, 0x4000 }, + { 0x8901, 0xd40c, 0x3000 }, + { 0x8901, 0xd40a, 0x2000 }, + { 0x0901, 0xd409, 0x0000 }, + { 0x0901, 0xd40b, 0x0000 }, + { 0x8901, 0xd40e, 0x2000 }, + { 0x0901, 0xd40d, 0x0000 }, + { 0x0901, 0xd40f, 0x0000 }, + { 0x8901, 0xd414, 0x3000 }, + { 0x8901, 0xd412, 0x2000 }, + { 0x0901, 0xd411, 0x0000 }, + { 0x0901, 0xd413, 0x0000 }, + { 0x8901, 0xd416, 0x2000 }, + { 0x0901, 0xd415, 0x0000 }, + { 0x0901, 0xd417, 0x0000 }, + { 0x8901, 0xd438, 0x6000 }, + { 0x8501, 0xd428, 0x5000 }, + { 0x8501, 0xd420, 0x4000 }, + { 0x8501, 0xd41c, 0x3000 }, + { 0x8501, 0xd41a, 0x2000 }, + { 0x0901, 0xd419, 0x0000 }, + { 0x0501, 0xd41b, 0x0000 }, + { 0x8501, 0xd41e, 0x2000 }, + { 0x0501, 0xd41d, 0x0000 }, + { 0x0501, 0xd41f, 0x0000 }, + { 0x8501, 0xd424, 0x3000 }, + { 0x8501, 0xd422, 0x2000 }, + { 0x0501, 0xd421, 0x0000 }, + { 0x0501, 0xd423, 0x0000 }, + { 0x8501, 0xd426, 0x2000 }, + { 0x0501, 0xd425, 0x0000 }, + { 0x0501, 0xd427, 0x0000 }, + { 0x8501, 0xd430, 0x4000 }, + { 0x8501, 0xd42c, 0x3000 }, + { 0x8501, 0xd42a, 0x2000 }, + { 0x0501, 0xd429, 0x0000 }, + { 0x0501, 0xd42b, 0x0000 }, + { 0x8501, 0xd42e, 0x2000 }, + { 0x0501, 0xd42d, 0x0000 }, + { 0x0501, 0xd42f, 0x0000 }, + { 0x8901, 0xd434, 0x3000 }, + { 0x8501, 0xd432, 0x2000 }, + { 0x0501, 0xd431, 0x0000 }, + { 0x0501, 0xd433, 0x0000 }, + { 0x8901, 0xd436, 0x2000 }, + { 0x0901, 0xd435, 0x0000 }, + { 0x0901, 0xd437, 0x0000 }, + { 0x8901, 0xd448, 0x5000 }, + { 0x8901, 0xd440, 0x4000 }, + { 0x8901, 0xd43c, 0x3000 }, + { 0x8901, 0xd43a, 0x2000 }, + { 0x0901, 0xd439, 0x0000 }, + { 0x0901, 0xd43b, 0x0000 }, + { 0x8901, 0xd43e, 0x2000 }, + { 0x0901, 0xd43d, 0x0000 }, + { 0x0901, 0xd43f, 0x0000 }, + { 0x8901, 0xd444, 0x3000 }, + { 0x8901, 0xd442, 0x2000 }, + { 0x0901, 0xd441, 0x0000 }, + { 0x0901, 0xd443, 0x0000 }, + { 0x8901, 0xd446, 0x2000 }, + { 0x0901, 0xd445, 0x0000 }, + { 0x0901, 0xd447, 0x0000 }, + { 0x8501, 0xd450, 0x4000 }, + { 0x8901, 0xd44c, 0x3000 }, + { 0x8901, 0xd44a, 0x2000 }, + { 0x0901, 0xd449, 0x0000 }, + { 0x0901, 0xd44b, 0x0000 }, + { 0x8501, 0xd44e, 0x2000 }, + { 0x0901, 0xd44d, 0x0000 }, + { 0x0501, 0xd44f, 0x0000 }, + { 0x8501, 0xd454, 0x3000 }, + { 0x8501, 0xd452, 0x2000 }, + { 0x0501, 0xd451, 0x0000 }, + { 0x0501, 0xd453, 0x0000 }, + { 0x8501, 0xd457, 0x2000 }, + { 0x0501, 0xd456, 0x0000 }, + { 0x0501, 0xd458, 0x0000 }, + { 0x8702, 0xf876, 0xb000 }, + { 0x8901, 0xd670, 0xa000 }, + { 0x8901, 0xd570, 0x9000 }, + { 0x8901, 0xd4e4, 0x8000 }, + { 0x8501, 0xd499, 0x7000 }, + { 0x8901, 0xd479, 0x6000 }, + { 0x8901, 0xd469, 0x5000 }, + { 0x8501, 0xd461, 0x4000 }, + { 0x8501, 0xd45d, 0x3000 }, + { 0x8501, 0xd45b, 0x2000 }, + { 0x0501, 0xd45a, 0x0000 }, + { 0x0501, 0xd45c, 0x0000 }, + { 0x8501, 0xd45f, 0x2000 }, + { 0x0501, 0xd45e, 0x0000 }, + { 0x0501, 0xd460, 0x0000 }, + { 0x8501, 0xd465, 0x3000 }, + { 0x8501, 0xd463, 0x2000 }, + { 0x0501, 0xd462, 0x0000 }, + { 0x0501, 0xd464, 0x0000 }, + { 0x8501, 0xd467, 0x2000 }, + { 0x0501, 0xd466, 0x0000 }, + { 0x0901, 0xd468, 0x0000 }, + { 0x8901, 0xd471, 0x4000 }, + { 0x8901, 0xd46d, 0x3000 }, + { 0x8901, 0xd46b, 0x2000 }, + { 0x0901, 0xd46a, 0x0000 }, + { 0x0901, 0xd46c, 0x0000 }, + { 0x8901, 0xd46f, 0x2000 }, + { 0x0901, 0xd46e, 0x0000 }, + { 0x0901, 0xd470, 0x0000 }, + { 0x8901, 0xd475, 0x3000 }, + { 0x8901, 0xd473, 0x2000 }, + { 0x0901, 0xd472, 0x0000 }, + { 0x0901, 0xd474, 0x0000 }, + { 0x8901, 0xd477, 0x2000 }, + { 0x0901, 0xd476, 0x0000 }, + { 0x0901, 0xd478, 0x0000 }, + { 0x8501, 0xd489, 0x5000 }, + { 0x8901, 0xd481, 0x4000 }, + { 0x8901, 0xd47d, 0x3000 }, + { 0x8901, 0xd47b, 0x2000 }, + { 0x0901, 0xd47a, 0x0000 }, + { 0x0901, 0xd47c, 0x0000 }, + { 0x8901, 0xd47f, 0x2000 }, + { 0x0901, 0xd47e, 0x0000 }, + { 0x0901, 0xd480, 0x0000 }, + { 0x8501, 0xd485, 0x3000 }, + { 0x8501, 0xd483, 0x2000 }, + { 0x0501, 0xd482, 0x0000 }, + { 0x0501, 0xd484, 0x0000 }, + { 0x8501, 0xd487, 0x2000 }, + { 0x0501, 0xd486, 0x0000 }, + { 0x0501, 0xd488, 0x0000 }, + { 0x8501, 0xd491, 0x4000 }, + { 0x8501, 0xd48d, 0x3000 }, + { 0x8501, 0xd48b, 0x2000 }, + { 0x0501, 0xd48a, 0x0000 }, + { 0x0501, 0xd48c, 0x0000 }, + { 0x8501, 0xd48f, 0x2000 }, + { 0x0501, 0xd48e, 0x0000 }, + { 0x0501, 0xd490, 0x0000 }, + { 0x8501, 0xd495, 0x3000 }, + { 0x8501, 0xd493, 0x2000 }, + { 0x0501, 0xd492, 0x0000 }, + { 0x0501, 0xd494, 0x0000 }, + { 0x8501, 0xd497, 0x2000 }, + { 0x0501, 0xd496, 0x0000 }, + { 0x0501, 0xd498, 0x0000 }, + { 0x8501, 0xd4c3, 0x6000 }, + { 0x8901, 0xd4b1, 0x5000 }, + { 0x8901, 0xd4a6, 0x4000 }, + { 0x8901, 0xd49e, 0x3000 }, + { 0x8501, 0xd49b, 0x2000 }, + { 0x0501, 0xd49a, 0x0000 }, + { 0x0901, 0xd49c, 0x0000 }, + { 0x8901, 0xd4a2, 0x2000 }, + { 0x0901, 0xd49f, 0x0000 }, + { 0x0901, 0xd4a5, 0x0000 }, + { 0x8901, 0xd4ac, 0x3000 }, + { 0x8901, 0xd4aa, 0x2000 }, + { 0x0901, 0xd4a9, 0x0000 }, + { 0x0901, 0xd4ab, 0x0000 }, + { 0x8901, 0xd4af, 0x2000 }, + { 0x0901, 0xd4ae, 0x0000 }, + { 0x0901, 0xd4b0, 0x0000 }, + { 0x8501, 0xd4b9, 0x4000 }, + { 0x8901, 0xd4b5, 0x3000 }, + { 0x8901, 0xd4b3, 0x2000 }, + { 0x0901, 0xd4b2, 0x0000 }, + { 0x0901, 0xd4b4, 0x0000 }, + { 0x8501, 0xd4b7, 0x2000 }, + { 0x0501, 0xd4b6, 0x0000 }, + { 0x0501, 0xd4b8, 0x0000 }, + { 0x8501, 0xd4bf, 0x3000 }, + { 0x8501, 0xd4bd, 0x2000 }, + { 0x0501, 0xd4bb, 0x0000 }, + { 0x0501, 0xd4be, 0x0000 }, + { 0x8501, 0xd4c1, 0x2000 }, + { 0x0501, 0xd4c0, 0x0000 }, + { 0x0501, 0xd4c2, 0x0000 }, + { 0x8901, 0xd4d4, 0x5000 }, + { 0x8501, 0xd4cc, 0x4000 }, + { 0x8501, 0xd4c8, 0x3000 }, + { 0x8501, 0xd4c6, 0x2000 }, + { 0x0501, 0xd4c5, 0x0000 }, + { 0x0501, 0xd4c7, 0x0000 }, + { 0x8501, 0xd4ca, 0x2000 }, + { 0x0501, 0xd4c9, 0x0000 }, + { 0x0501, 0xd4cb, 0x0000 }, + { 0x8901, 0xd4d0, 0x3000 }, + { 0x8501, 0xd4ce, 0x2000 }, + { 0x0501, 0xd4cd, 0x0000 }, + { 0x0501, 0xd4cf, 0x0000 }, + { 0x8901, 0xd4d2, 0x2000 }, + { 0x0901, 0xd4d1, 0x0000 }, + { 0x0901, 0xd4d3, 0x0000 }, + { 0x8901, 0xd4dc, 0x4000 }, + { 0x8901, 0xd4d8, 0x3000 }, + { 0x8901, 0xd4d6, 0x2000 }, + { 0x0901, 0xd4d5, 0x0000 }, + { 0x0901, 0xd4d7, 0x0000 }, + { 0x8901, 0xd4da, 0x2000 }, + { 0x0901, 0xd4d9, 0x0000 }, + { 0x0901, 0xd4db, 0x0000 }, + { 0x8901, 0xd4e0, 0x3000 }, + { 0x8901, 0xd4de, 0x2000 }, + { 0x0901, 0xd4dd, 0x0000 }, + { 0x0901, 0xd4df, 0x0000 }, + { 0x8901, 0xd4e2, 0x2000 }, + { 0x0901, 0xd4e1, 0x0000 }, + { 0x0901, 0xd4e3, 0x0000 }, + { 0x8501, 0xd529, 0x7000 }, + { 0x8901, 0xd504, 0x6000 }, + { 0x8501, 0xd4f4, 0x5000 }, + { 0x8501, 0xd4ec, 0x4000 }, + { 0x8901, 0xd4e8, 0x3000 }, + { 0x8901, 0xd4e6, 0x2000 }, + { 0x0901, 0xd4e5, 0x0000 }, + { 0x0901, 0xd4e7, 0x0000 }, + { 0x8501, 0xd4ea, 0x2000 }, + { 0x0901, 0xd4e9, 0x0000 }, + { 0x0501, 0xd4eb, 0x0000 }, + { 0x8501, 0xd4f0, 0x3000 }, + { 0x8501, 0xd4ee, 0x2000 }, + { 0x0501, 0xd4ed, 0x0000 }, + { 0x0501, 0xd4ef, 0x0000 }, + { 0x8501, 0xd4f2, 0x2000 }, + { 0x0501, 0xd4f1, 0x0000 }, + { 0x0501, 0xd4f3, 0x0000 }, + { 0x8501, 0xd4fc, 0x4000 }, + { 0x8501, 0xd4f8, 0x3000 }, + { 0x8501, 0xd4f6, 0x2000 }, + { 0x0501, 0xd4f5, 0x0000 }, + { 0x0501, 0xd4f7, 0x0000 }, + { 0x8501, 0xd4fa, 0x2000 }, + { 0x0501, 0xd4f9, 0x0000 }, + { 0x0501, 0xd4fb, 0x0000 }, + { 0x8501, 0xd500, 0x3000 }, + { 0x8501, 0xd4fe, 0x2000 }, + { 0x0501, 0xd4fd, 0x0000 }, + { 0x0501, 0xd4ff, 0x0000 }, + { 0x8501, 0xd502, 0x2000 }, + { 0x0501, 0xd501, 0x0000 }, + { 0x0501, 0xd503, 0x0000 }, + { 0x8901, 0xd518, 0x5000 }, + { 0x8901, 0xd50f, 0x4000 }, + { 0x8901, 0xd509, 0x3000 }, + { 0x8901, 0xd507, 0x2000 }, + { 0x0901, 0xd505, 0x0000 }, + { 0x0901, 0xd508, 0x0000 }, + { 0x8901, 0xd50d, 0x2000 }, + { 0x0901, 0xd50a, 0x0000 }, + { 0x0901, 0xd50e, 0x0000 }, + { 0x8901, 0xd513, 0x3000 }, + { 0x8901, 0xd511, 0x2000 }, + { 0x0901, 0xd510, 0x0000 }, + { 0x0901, 0xd512, 0x0000 }, + { 0x8901, 0xd516, 0x2000 }, + { 0x0901, 0xd514, 0x0000 }, + { 0x0901, 0xd517, 0x0000 }, + { 0x8501, 0xd521, 0x4000 }, + { 0x8901, 0xd51c, 0x3000 }, + { 0x8901, 0xd51a, 0x2000 }, + { 0x0901, 0xd519, 0x0000 }, + { 0x0901, 0xd51b, 0x0000 }, + { 0x8501, 0xd51f, 0x2000 }, + { 0x0501, 0xd51e, 0x0000 }, + { 0x0501, 0xd520, 0x0000 }, + { 0x8501, 0xd525, 0x3000 }, + { 0x8501, 0xd523, 0x2000 }, + { 0x0501, 0xd522, 0x0000 }, + { 0x0501, 0xd524, 0x0000 }, + { 0x8501, 0xd527, 0x2000 }, + { 0x0501, 0xd526, 0x0000 }, + { 0x0501, 0xd528, 0x0000 }, + { 0x8901, 0xd54f, 0x6000 }, + { 0x8901, 0xd539, 0x5000 }, + { 0x8501, 0xd531, 0x4000 }, + { 0x8501, 0xd52d, 0x3000 }, + { 0x8501, 0xd52b, 0x2000 }, + { 0x0501, 0xd52a, 0x0000 }, + { 0x0501, 0xd52c, 0x0000 }, + { 0x8501, 0xd52f, 0x2000 }, + { 0x0501, 0xd52e, 0x0000 }, + { 0x0501, 0xd530, 0x0000 }, + { 0x8501, 0xd535, 0x3000 }, + { 0x8501, 0xd533, 0x2000 }, + { 0x0501, 0xd532, 0x0000 }, + { 0x0501, 0xd534, 0x0000 }, + { 0x8501, 0xd537, 0x2000 }, + { 0x0501, 0xd536, 0x0000 }, + { 0x0901, 0xd538, 0x0000 }, + { 0x8901, 0xd543, 0x4000 }, + { 0x8901, 0xd53e, 0x3000 }, + { 0x8901, 0xd53c, 0x2000 }, + { 0x0901, 0xd53b, 0x0000 }, + { 0x0901, 0xd53d, 0x0000 }, + { 0x8901, 0xd541, 0x2000 }, + { 0x0901, 0xd540, 0x0000 }, + { 0x0901, 0xd542, 0x0000 }, + { 0x8901, 0xd54b, 0x3000 }, + { 0x8901, 0xd546, 0x2000 }, + { 0x0901, 0xd544, 0x0000 }, + { 0x0901, 0xd54a, 0x0000 }, + { 0x8901, 0xd54d, 0x2000 }, + { 0x0901, 0xd54c, 0x0000 }, + { 0x0901, 0xd54e, 0x0000 }, + { 0x8501, 0xd560, 0x5000 }, + { 0x8501, 0xd558, 0x4000 }, + { 0x8501, 0xd554, 0x3000 }, + { 0x8501, 0xd552, 0x2000 }, + { 0x0901, 0xd550, 0x0000 }, + { 0x0501, 0xd553, 0x0000 }, + { 0x8501, 0xd556, 0x2000 }, + { 0x0501, 0xd555, 0x0000 }, + { 0x0501, 0xd557, 0x0000 }, + { 0x8501, 0xd55c, 0x3000 }, + { 0x8501, 0xd55a, 0x2000 }, + { 0x0501, 0xd559, 0x0000 }, + { 0x0501, 0xd55b, 0x0000 }, + { 0x8501, 0xd55e, 0x2000 }, + { 0x0501, 0xd55d, 0x0000 }, + { 0x0501, 0xd55f, 0x0000 }, + { 0x8501, 0xd568, 0x4000 }, + { 0x8501, 0xd564, 0x3000 }, + { 0x8501, 0xd562, 0x2000 }, + { 0x0501, 0xd561, 0x0000 }, + { 0x0501, 0xd563, 0x0000 }, + { 0x8501, 0xd566, 0x2000 }, + { 0x0501, 0xd565, 0x0000 }, + { 0x0501, 0xd567, 0x0000 }, + { 0x8901, 0xd56c, 0x3000 }, + { 0x8501, 0xd56a, 0x2000 }, + { 0x0501, 0xd569, 0x0000 }, + { 0x0501, 0xd56b, 0x0000 }, + { 0x8901, 0xd56e, 0x2000 }, + { 0x0901, 0xd56d, 0x0000 }, + { 0x0901, 0xd56f, 0x0000 }, + { 0x8501, 0xd5f0, 0x8000 }, + { 0x8901, 0xd5b0, 0x7000 }, + { 0x8501, 0xd590, 0x6000 }, + { 0x8901, 0xd580, 0x5000 }, + { 0x8901, 0xd578, 0x4000 }, + { 0x8901, 0xd574, 0x3000 }, + { 0x8901, 0xd572, 0x2000 }, + { 0x0901, 0xd571, 0x0000 }, + { 0x0901, 0xd573, 0x0000 }, + { 0x8901, 0xd576, 0x2000 }, + { 0x0901, 0xd575, 0x0000 }, + { 0x0901, 0xd577, 0x0000 }, + { 0x8901, 0xd57c, 0x3000 }, + { 0x8901, 0xd57a, 0x2000 }, + { 0x0901, 0xd579, 0x0000 }, + { 0x0901, 0xd57b, 0x0000 }, + { 0x8901, 0xd57e, 0x2000 }, + { 0x0901, 0xd57d, 0x0000 }, + { 0x0901, 0xd57f, 0x0000 }, + { 0x8501, 0xd588, 0x4000 }, + { 0x8901, 0xd584, 0x3000 }, + { 0x8901, 0xd582, 0x2000 }, + { 0x0901, 0xd581, 0x0000 }, + { 0x0901, 0xd583, 0x0000 }, + { 0x8501, 0xd586, 0x2000 }, + { 0x0901, 0xd585, 0x0000 }, + { 0x0501, 0xd587, 0x0000 }, + { 0x8501, 0xd58c, 0x3000 }, + { 0x8501, 0xd58a, 0x2000 }, + { 0x0501, 0xd589, 0x0000 }, + { 0x0501, 0xd58b, 0x0000 }, + { 0x8501, 0xd58e, 0x2000 }, + { 0x0501, 0xd58d, 0x0000 }, + { 0x0501, 0xd58f, 0x0000 }, + { 0x8901, 0xd5a0, 0x5000 }, + { 0x8501, 0xd598, 0x4000 }, + { 0x8501, 0xd594, 0x3000 }, + { 0x8501, 0xd592, 0x2000 }, + { 0x0501, 0xd591, 0x0000 }, + { 0x0501, 0xd593, 0x0000 }, + { 0x8501, 0xd596, 0x2000 }, + { 0x0501, 0xd595, 0x0000 }, + { 0x0501, 0xd597, 0x0000 }, + { 0x8501, 0xd59c, 0x3000 }, + { 0x8501, 0xd59a, 0x2000 }, + { 0x0501, 0xd599, 0x0000 }, + { 0x0501, 0xd59b, 0x0000 }, + { 0x8501, 0xd59e, 0x2000 }, + { 0x0501, 0xd59d, 0x0000 }, + { 0x0501, 0xd59f, 0x0000 }, + { 0x8901, 0xd5a8, 0x4000 }, + { 0x8901, 0xd5a4, 0x3000 }, + { 0x8901, 0xd5a2, 0x2000 }, + { 0x0901, 0xd5a1, 0x0000 }, + { 0x0901, 0xd5a3, 0x0000 }, + { 0x8901, 0xd5a6, 0x2000 }, + { 0x0901, 0xd5a5, 0x0000 }, + { 0x0901, 0xd5a7, 0x0000 }, + { 0x8901, 0xd5ac, 0x3000 }, + { 0x8901, 0xd5aa, 0x2000 }, + { 0x0901, 0xd5a9, 0x0000 }, + { 0x0901, 0xd5ab, 0x0000 }, + { 0x8901, 0xd5ae, 0x2000 }, + { 0x0901, 0xd5ad, 0x0000 }, + { 0x0901, 0xd5af, 0x0000 }, + { 0x8501, 0xd5d0, 0x6000 }, + { 0x8501, 0xd5c0, 0x5000 }, + { 0x8901, 0xd5b8, 0x4000 }, + { 0x8901, 0xd5b4, 0x3000 }, + { 0x8901, 0xd5b2, 0x2000 }, + { 0x0901, 0xd5b1, 0x0000 }, + { 0x0901, 0xd5b3, 0x0000 }, + { 0x8901, 0xd5b6, 0x2000 }, + { 0x0901, 0xd5b5, 0x0000 }, + { 0x0901, 0xd5b7, 0x0000 }, + { 0x8501, 0xd5bc, 0x3000 }, + { 0x8501, 0xd5ba, 0x2000 }, + { 0x0901, 0xd5b9, 0x0000 }, + { 0x0501, 0xd5bb, 0x0000 }, + { 0x8501, 0xd5be, 0x2000 }, + { 0x0501, 0xd5bd, 0x0000 }, + { 0x0501, 0xd5bf, 0x0000 }, + { 0x8501, 0xd5c8, 0x4000 }, + { 0x8501, 0xd5c4, 0x3000 }, + { 0x8501, 0xd5c2, 0x2000 }, + { 0x0501, 0xd5c1, 0x0000 }, + { 0x0501, 0xd5c3, 0x0000 }, + { 0x8501, 0xd5c6, 0x2000 }, + { 0x0501, 0xd5c5, 0x0000 }, + { 0x0501, 0xd5c7, 0x0000 }, + { 0x8501, 0xd5cc, 0x3000 }, + { 0x8501, 0xd5ca, 0x2000 }, + { 0x0501, 0xd5c9, 0x0000 }, + { 0x0501, 0xd5cb, 0x0000 }, + { 0x8501, 0xd5ce, 0x2000 }, + { 0x0501, 0xd5cd, 0x0000 }, + { 0x0501, 0xd5cf, 0x0000 }, + { 0x8901, 0xd5e0, 0x5000 }, + { 0x8901, 0xd5d8, 0x4000 }, + { 0x8901, 0xd5d4, 0x3000 }, + { 0x8501, 0xd5d2, 0x2000 }, + { 0x0501, 0xd5d1, 0x0000 }, + { 0x0501, 0xd5d3, 0x0000 }, + { 0x8901, 0xd5d6, 0x2000 }, + { 0x0901, 0xd5d5, 0x0000 }, + { 0x0901, 0xd5d7, 0x0000 }, + { 0x8901, 0xd5dc, 0x3000 }, + { 0x8901, 0xd5da, 0x2000 }, + { 0x0901, 0xd5d9, 0x0000 }, + { 0x0901, 0xd5db, 0x0000 }, + { 0x8901, 0xd5de, 0x2000 }, + { 0x0901, 0xd5dd, 0x0000 }, + { 0x0901, 0xd5df, 0x0000 }, + { 0x8901, 0xd5e8, 0x4000 }, + { 0x8901, 0xd5e4, 0x3000 }, + { 0x8901, 0xd5e2, 0x2000 }, + { 0x0901, 0xd5e1, 0x0000 }, + { 0x0901, 0xd5e3, 0x0000 }, + { 0x8901, 0xd5e6, 0x2000 }, + { 0x0901, 0xd5e5, 0x0000 }, + { 0x0901, 0xd5e7, 0x0000 }, + { 0x8901, 0xd5ec, 0x3000 }, + { 0x8901, 0xd5ea, 0x2000 }, + { 0x0901, 0xd5e9, 0x0000 }, + { 0x0901, 0xd5eb, 0x0000 }, + { 0x8501, 0xd5ee, 0x2000 }, + { 0x0901, 0xd5ed, 0x0000 }, + { 0x0501, 0xd5ef, 0x0000 }, + { 0x8501, 0xd630, 0x7000 }, + { 0x8901, 0xd610, 0x6000 }, + { 0x8501, 0xd600, 0x5000 }, + { 0x8501, 0xd5f8, 0x4000 }, + { 0x8501, 0xd5f4, 0x3000 }, + { 0x8501, 0xd5f2, 0x2000 }, + { 0x0501, 0xd5f1, 0x0000 }, + { 0x0501, 0xd5f3, 0x0000 }, + { 0x8501, 0xd5f6, 0x2000 }, + { 0x0501, 0xd5f5, 0x0000 }, + { 0x0501, 0xd5f7, 0x0000 }, + { 0x8501, 0xd5fc, 0x3000 }, + { 0x8501, 0xd5fa, 0x2000 }, + { 0x0501, 0xd5f9, 0x0000 }, + { 0x0501, 0xd5fb, 0x0000 }, + { 0x8501, 0xd5fe, 0x2000 }, + { 0x0501, 0xd5fd, 0x0000 }, + { 0x0501, 0xd5ff, 0x0000 }, + { 0x8901, 0xd608, 0x4000 }, + { 0x8501, 0xd604, 0x3000 }, + { 0x8501, 0xd602, 0x2000 }, + { 0x0501, 0xd601, 0x0000 }, + { 0x0501, 0xd603, 0x0000 }, + { 0x8501, 0xd606, 0x2000 }, + { 0x0501, 0xd605, 0x0000 }, + { 0x0501, 0xd607, 0x0000 }, + { 0x8901, 0xd60c, 0x3000 }, + { 0x8901, 0xd60a, 0x2000 }, + { 0x0901, 0xd609, 0x0000 }, + { 0x0901, 0xd60b, 0x0000 }, + { 0x8901, 0xd60e, 0x2000 }, + { 0x0901, 0xd60d, 0x0000 }, + { 0x0901, 0xd60f, 0x0000 }, + { 0x8901, 0xd620, 0x5000 }, + { 0x8901, 0xd618, 0x4000 }, + { 0x8901, 0xd614, 0x3000 }, + { 0x8901, 0xd612, 0x2000 }, + { 0x0901, 0xd611, 0x0000 }, + { 0x0901, 0xd613, 0x0000 }, + { 0x8901, 0xd616, 0x2000 }, + { 0x0901, 0xd615, 0x0000 }, + { 0x0901, 0xd617, 0x0000 }, + { 0x8901, 0xd61c, 0x3000 }, + { 0x8901, 0xd61a, 0x2000 }, + { 0x0901, 0xd619, 0x0000 }, + { 0x0901, 0xd61b, 0x0000 }, + { 0x8901, 0xd61e, 0x2000 }, + { 0x0901, 0xd61d, 0x0000 }, + { 0x0901, 0xd61f, 0x0000 }, + { 0x8501, 0xd628, 0x4000 }, + { 0x8501, 0xd624, 0x3000 }, + { 0x8501, 0xd622, 0x2000 }, + { 0x0901, 0xd621, 0x0000 }, + { 0x0501, 0xd623, 0x0000 }, + { 0x8501, 0xd626, 0x2000 }, + { 0x0501, 0xd625, 0x0000 }, + { 0x0501, 0xd627, 0x0000 }, + { 0x8501, 0xd62c, 0x3000 }, + { 0x8501, 0xd62a, 0x2000 }, + { 0x0501, 0xd629, 0x0000 }, + { 0x0501, 0xd62b, 0x0000 }, + { 0x8501, 0xd62e, 0x2000 }, + { 0x0501, 0xd62d, 0x0000 }, + { 0x0501, 0xd62f, 0x0000 }, + { 0x8901, 0xd650, 0x6000 }, + { 0x8901, 0xd640, 0x5000 }, + { 0x8501, 0xd638, 0x4000 }, + { 0x8501, 0xd634, 0x3000 }, + { 0x8501, 0xd632, 0x2000 }, + { 0x0501, 0xd631, 0x0000 }, + { 0x0501, 0xd633, 0x0000 }, + { 0x8501, 0xd636, 0x2000 }, + { 0x0501, 0xd635, 0x0000 }, + { 0x0501, 0xd637, 0x0000 }, + { 0x8901, 0xd63c, 0x3000 }, + { 0x8501, 0xd63a, 0x2000 }, + { 0x0501, 0xd639, 0x0000 }, + { 0x0501, 0xd63b, 0x0000 }, + { 0x8901, 0xd63e, 0x2000 }, + { 0x0901, 0xd63d, 0x0000 }, + { 0x0901, 0xd63f, 0x0000 }, + { 0x8901, 0xd648, 0x4000 }, + { 0x8901, 0xd644, 0x3000 }, + { 0x8901, 0xd642, 0x2000 }, + { 0x0901, 0xd641, 0x0000 }, + { 0x0901, 0xd643, 0x0000 }, + { 0x8901, 0xd646, 0x2000 }, + { 0x0901, 0xd645, 0x0000 }, + { 0x0901, 0xd647, 0x0000 }, + { 0x8901, 0xd64c, 0x3000 }, + { 0x8901, 0xd64a, 0x2000 }, + { 0x0901, 0xd649, 0x0000 }, + { 0x0901, 0xd64b, 0x0000 }, + { 0x8901, 0xd64e, 0x2000 }, + { 0x0901, 0xd64d, 0x0000 }, + { 0x0901, 0xd64f, 0x0000 }, + { 0x8501, 0xd660, 0x5000 }, + { 0x8501, 0xd658, 0x4000 }, + { 0x8901, 0xd654, 0x3000 }, + { 0x8901, 0xd652, 0x2000 }, + { 0x0901, 0xd651, 0x0000 }, + { 0x0901, 0xd653, 0x0000 }, + { 0x8501, 0xd656, 0x2000 }, + { 0x0901, 0xd655, 0x0000 }, + { 0x0501, 0xd657, 0x0000 }, + { 0x8501, 0xd65c, 0x3000 }, + { 0x8501, 0xd65a, 0x2000 }, + { 0x0501, 0xd659, 0x0000 }, + { 0x0501, 0xd65b, 0x0000 }, + { 0x8501, 0xd65e, 0x2000 }, + { 0x0501, 0xd65d, 0x0000 }, + { 0x0501, 0xd65f, 0x0000 }, + { 0x8501, 0xd668, 0x4000 }, + { 0x8501, 0xd664, 0x3000 }, + { 0x8501, 0xd662, 0x2000 }, + { 0x0501, 0xd661, 0x0000 }, + { 0x0501, 0xd663, 0x0000 }, + { 0x8501, 0xd666, 0x2000 }, + { 0x0501, 0xd665, 0x0000 }, + { 0x0501, 0xd667, 0x0000 }, + { 0x8501, 0xd66c, 0x3000 }, + { 0x8501, 0xd66a, 0x2000 }, + { 0x0501, 0xd669, 0x0000 }, + { 0x0501, 0xd66b, 0x0000 }, + { 0x8501, 0xd66e, 0x2000 }, + { 0x0501, 0xd66d, 0x0000 }, + { 0x0501, 0xd66f, 0x0000 }, + { 0x8501, 0xd774, 0x9000 }, + { 0x8901, 0xd6f4, 0x8000 }, + { 0x8901, 0xd6b4, 0x7000 }, + { 0x8501, 0xd690, 0x6000 }, + { 0x8901, 0xd680, 0x5000 }, + { 0x8901, 0xd678, 0x4000 }, + { 0x8901, 0xd674, 0x3000 }, + { 0x8901, 0xd672, 0x2000 }, + { 0x0901, 0xd671, 0x0000 }, + { 0x0901, 0xd673, 0x0000 }, + { 0x8901, 0xd676, 0x2000 }, + { 0x0901, 0xd675, 0x0000 }, + { 0x0901, 0xd677, 0x0000 }, + { 0x8901, 0xd67c, 0x3000 }, + { 0x8901, 0xd67a, 0x2000 }, + { 0x0901, 0xd679, 0x0000 }, + { 0x0901, 0xd67b, 0x0000 }, + { 0x8901, 0xd67e, 0x2000 }, + { 0x0901, 0xd67d, 0x0000 }, + { 0x0901, 0xd67f, 0x0000 }, + { 0x8901, 0xd688, 0x4000 }, + { 0x8901, 0xd684, 0x3000 }, + { 0x8901, 0xd682, 0x2000 }, + { 0x0901, 0xd681, 0x0000 }, + { 0x0901, 0xd683, 0x0000 }, + { 0x8901, 0xd686, 0x2000 }, + { 0x0901, 0xd685, 0x0000 }, + { 0x0901, 0xd687, 0x0000 }, + { 0x8501, 0xd68c, 0x3000 }, + { 0x8501, 0xd68a, 0x2000 }, + { 0x0901, 0xd689, 0x0000 }, + { 0x0501, 0xd68b, 0x0000 }, + { 0x8501, 0xd68e, 0x2000 }, + { 0x0501, 0xd68d, 0x0000 }, + { 0x0501, 0xd68f, 0x0000 }, + { 0x8501, 0xd6a0, 0x5000 }, + { 0x8501, 0xd698, 0x4000 }, + { 0x8501, 0xd694, 0x3000 }, + { 0x8501, 0xd692, 0x2000 }, + { 0x0501, 0xd691, 0x0000 }, + { 0x0501, 0xd693, 0x0000 }, + { 0x8501, 0xd696, 0x2000 }, + { 0x0501, 0xd695, 0x0000 }, + { 0x0501, 0xd697, 0x0000 }, + { 0x8501, 0xd69c, 0x3000 }, + { 0x8501, 0xd69a, 0x2000 }, + { 0x0501, 0xd699, 0x0000 }, + { 0x0501, 0xd69b, 0x0000 }, + { 0x8501, 0xd69e, 0x2000 }, + { 0x0501, 0xd69d, 0x0000 }, + { 0x0501, 0xd69f, 0x0000 }, + { 0x8901, 0xd6ac, 0x4000 }, + { 0x8901, 0xd6a8, 0x3000 }, + { 0x8501, 0xd6a2, 0x2000 }, + { 0x0501, 0xd6a1, 0x0000 }, + { 0x0501, 0xd6a3, 0x0000 }, + { 0x8901, 0xd6aa, 0x2000 }, + { 0x0901, 0xd6a9, 0x0000 }, + { 0x0901, 0xd6ab, 0x0000 }, + { 0x8901, 0xd6b0, 0x3000 }, + { 0x8901, 0xd6ae, 0x2000 }, + { 0x0901, 0xd6ad, 0x0000 }, + { 0x0901, 0xd6af, 0x0000 }, + { 0x8901, 0xd6b2, 0x2000 }, + { 0x0901, 0xd6b1, 0x0000 }, + { 0x0901, 0xd6b3, 0x0000 }, + { 0x8501, 0xd6d4, 0x6000 }, + { 0x8501, 0xd6c4, 0x5000 }, + { 0x8901, 0xd6bc, 0x4000 }, + { 0x8901, 0xd6b8, 0x3000 }, + { 0x8901, 0xd6b6, 0x2000 }, + { 0x0901, 0xd6b5, 0x0000 }, + { 0x0901, 0xd6b7, 0x0000 }, + { 0x8901, 0xd6ba, 0x2000 }, + { 0x0901, 0xd6b9, 0x0000 }, + { 0x0901, 0xd6bb, 0x0000 }, + { 0x8901, 0xd6c0, 0x3000 }, + { 0x8901, 0xd6be, 0x2000 }, + { 0x0901, 0xd6bd, 0x0000 }, + { 0x0901, 0xd6bf, 0x0000 }, + { 0x8501, 0xd6c2, 0x2000 }, + { 0x1901, 0xd6c1, 0x0000 }, + { 0x0501, 0xd6c3, 0x0000 }, + { 0x8501, 0xd6cc, 0x4000 }, + { 0x8501, 0xd6c8, 0x3000 }, + { 0x8501, 0xd6c6, 0x2000 }, + { 0x0501, 0xd6c5, 0x0000 }, + { 0x0501, 0xd6c7, 0x0000 }, + { 0x8501, 0xd6ca, 0x2000 }, + { 0x0501, 0xd6c9, 0x0000 }, + { 0x0501, 0xd6cb, 0x0000 }, + { 0x8501, 0xd6d0, 0x3000 }, + { 0x8501, 0xd6ce, 0x2000 }, + { 0x0501, 0xd6cd, 0x0000 }, + { 0x0501, 0xd6cf, 0x0000 }, + { 0x8501, 0xd6d2, 0x2000 }, + { 0x0501, 0xd6d1, 0x0000 }, + { 0x0501, 0xd6d3, 0x0000 }, + { 0x8901, 0xd6e4, 0x5000 }, + { 0x8501, 0xd6dc, 0x4000 }, + { 0x8501, 0xd6d8, 0x3000 }, + { 0x8501, 0xd6d6, 0x2000 }, + { 0x0501, 0xd6d5, 0x0000 }, + { 0x0501, 0xd6d7, 0x0000 }, + { 0x8501, 0xd6da, 0x2000 }, + { 0x0501, 0xd6d9, 0x0000 }, + { 0x1901, 0xd6db, 0x0000 }, + { 0x8501, 0xd6e0, 0x3000 }, + { 0x8501, 0xd6de, 0x2000 }, + { 0x0501, 0xd6dd, 0x0000 }, + { 0x0501, 0xd6df, 0x0000 }, + { 0x8901, 0xd6e2, 0x2000 }, + { 0x0501, 0xd6e1, 0x0000 }, + { 0x0901, 0xd6e3, 0x0000 }, + { 0x8901, 0xd6ec, 0x4000 }, + { 0x8901, 0xd6e8, 0x3000 }, + { 0x8901, 0xd6e6, 0x2000 }, + { 0x0901, 0xd6e5, 0x0000 }, + { 0x0901, 0xd6e7, 0x0000 }, + { 0x8901, 0xd6ea, 0x2000 }, + { 0x0901, 0xd6e9, 0x0000 }, + { 0x0901, 0xd6eb, 0x0000 }, + { 0x8901, 0xd6f0, 0x3000 }, + { 0x8901, 0xd6ee, 0x2000 }, + { 0x0901, 0xd6ed, 0x0000 }, + { 0x0901, 0xd6ef, 0x0000 }, + { 0x8901, 0xd6f2, 0x2000 }, + { 0x0901, 0xd6f1, 0x0000 }, + { 0x0901, 0xd6f3, 0x0000 }, + { 0x8901, 0xd734, 0x7000 }, + { 0x8501, 0xd714, 0x6000 }, + { 0x8501, 0xd704, 0x5000 }, + { 0x8501, 0xd6fc, 0x4000 }, + { 0x8901, 0xd6f8, 0x3000 }, + { 0x8901, 0xd6f6, 0x2000 }, + { 0x0901, 0xd6f5, 0x0000 }, + { 0x0901, 0xd6f7, 0x0000 }, + { 0x8901, 0xd6fa, 0x2000 }, + { 0x0901, 0xd6f9, 0x0000 }, + { 0x1901, 0xd6fb, 0x0000 }, + { 0x8501, 0xd700, 0x3000 }, + { 0x8501, 0xd6fe, 0x2000 }, + { 0x0501, 0xd6fd, 0x0000 }, + { 0x0501, 0xd6ff, 0x0000 }, + { 0x8501, 0xd702, 0x2000 }, + { 0x0501, 0xd701, 0x0000 }, + { 0x0501, 0xd703, 0x0000 }, + { 0x8501, 0xd70c, 0x4000 }, + { 0x8501, 0xd708, 0x3000 }, + { 0x8501, 0xd706, 0x2000 }, + { 0x0501, 0xd705, 0x0000 }, + { 0x0501, 0xd707, 0x0000 }, + { 0x8501, 0xd70a, 0x2000 }, + { 0x0501, 0xd709, 0x0000 }, + { 0x0501, 0xd70b, 0x0000 }, + { 0x8501, 0xd710, 0x3000 }, + { 0x8501, 0xd70e, 0x2000 }, + { 0x0501, 0xd70d, 0x0000 }, + { 0x0501, 0xd70f, 0x0000 }, + { 0x8501, 0xd712, 0x2000 }, + { 0x0501, 0xd711, 0x0000 }, + { 0x0501, 0xd713, 0x0000 }, + { 0x8901, 0xd724, 0x5000 }, + { 0x8901, 0xd71c, 0x4000 }, + { 0x8501, 0xd718, 0x3000 }, + { 0x8501, 0xd716, 0x2000 }, + { 0x1901, 0xd715, 0x0000 }, + { 0x0501, 0xd717, 0x0000 }, + { 0x8501, 0xd71a, 0x2000 }, + { 0x0501, 0xd719, 0x0000 }, + { 0x0501, 0xd71b, 0x0000 }, + { 0x8901, 0xd720, 0x3000 }, + { 0x8901, 0xd71e, 0x2000 }, + { 0x0901, 0xd71d, 0x0000 }, + { 0x0901, 0xd71f, 0x0000 }, + { 0x8901, 0xd722, 0x2000 }, + { 0x0901, 0xd721, 0x0000 }, + { 0x0901, 0xd723, 0x0000 }, + { 0x8901, 0xd72c, 0x4000 }, + { 0x8901, 0xd728, 0x3000 }, + { 0x8901, 0xd726, 0x2000 }, + { 0x0901, 0xd725, 0x0000 }, + { 0x0901, 0xd727, 0x0000 }, + { 0x8901, 0xd72a, 0x2000 }, + { 0x0901, 0xd729, 0x0000 }, + { 0x0901, 0xd72b, 0x0000 }, + { 0x8901, 0xd730, 0x3000 }, + { 0x8901, 0xd72e, 0x2000 }, + { 0x0901, 0xd72d, 0x0000 }, + { 0x0901, 0xd72f, 0x0000 }, + { 0x8901, 0xd732, 0x2000 }, + { 0x0901, 0xd731, 0x0000 }, + { 0x0901, 0xd733, 0x0000 }, + { 0x8501, 0xd754, 0x6000 }, + { 0x8501, 0xd744, 0x5000 }, + { 0x8501, 0xd73c, 0x4000 }, + { 0x8501, 0xd738, 0x3000 }, + { 0x8501, 0xd736, 0x2000 }, + { 0x1901, 0xd735, 0x0000 }, + { 0x0501, 0xd737, 0x0000 }, + { 0x8501, 0xd73a, 0x2000 }, + { 0x0501, 0xd739, 0x0000 }, + { 0x0501, 0xd73b, 0x0000 }, + { 0x8501, 0xd740, 0x3000 }, + { 0x8501, 0xd73e, 0x2000 }, + { 0x0501, 0xd73d, 0x0000 }, + { 0x0501, 0xd73f, 0x0000 }, + { 0x8501, 0xd742, 0x2000 }, + { 0x0501, 0xd741, 0x0000 }, + { 0x0501, 0xd743, 0x0000 }, + { 0x8501, 0xd74c, 0x4000 }, + { 0x8501, 0xd748, 0x3000 }, + { 0x8501, 0xd746, 0x2000 }, + { 0x0501, 0xd745, 0x0000 }, + { 0x0501, 0xd747, 0x0000 }, + { 0x8501, 0xd74a, 0x2000 }, + { 0x0501, 0xd749, 0x0000 }, + { 0x0501, 0xd74b, 0x0000 }, + { 0x8501, 0xd750, 0x3000 }, + { 0x8501, 0xd74e, 0x2000 }, + { 0x0501, 0xd74d, 0x0000 }, + { 0x1901, 0xd74f, 0x0000 }, + { 0x8501, 0xd752, 0x2000 }, + { 0x0501, 0xd751, 0x0000 }, + { 0x0501, 0xd753, 0x0000 }, + { 0x8901, 0xd764, 0x5000 }, + { 0x8901, 0xd75c, 0x4000 }, + { 0x8901, 0xd758, 0x3000 }, + { 0x8901, 0xd756, 0x2000 }, + { 0x0501, 0xd755, 0x0000 }, + { 0x0901, 0xd757, 0x0000 }, + { 0x8901, 0xd75a, 0x2000 }, + { 0x0901, 0xd759, 0x0000 }, + { 0x0901, 0xd75b, 0x0000 }, + { 0x8901, 0xd760, 0x3000 }, + { 0x8901, 0xd75e, 0x2000 }, + { 0x0901, 0xd75d, 0x0000 }, + { 0x0901, 0xd75f, 0x0000 }, + { 0x8901, 0xd762, 0x2000 }, + { 0x0901, 0xd761, 0x0000 }, + { 0x0901, 0xd763, 0x0000 }, + { 0x8901, 0xd76c, 0x4000 }, + { 0x8901, 0xd768, 0x3000 }, + { 0x8901, 0xd766, 0x2000 }, + { 0x0901, 0xd765, 0x0000 }, + { 0x0901, 0xd767, 0x0000 }, + { 0x8901, 0xd76a, 0x2000 }, + { 0x0901, 0xd769, 0x0000 }, + { 0x0901, 0xd76b, 0x0000 }, + { 0x8501, 0xd770, 0x3000 }, + { 0x8901, 0xd76e, 0x2000 }, + { 0x0901, 0xd76d, 0x0000 }, + { 0x1901, 0xd76f, 0x0000 }, + { 0x8501, 0xd772, 0x2000 }, + { 0x0501, 0xd771, 0x0000 }, + { 0x0501, 0xd773, 0x0000 }, + { 0x8d01, 0xd7f8, 0x8000 }, + { 0x8501, 0xd7b4, 0x7000 }, + { 0x8901, 0xd794, 0x6000 }, + { 0x8501, 0xd784, 0x5000 }, + { 0x8501, 0xd77c, 0x4000 }, + { 0x8501, 0xd778, 0x3000 }, + { 0x8501, 0xd776, 0x2000 }, + { 0x0501, 0xd775, 0x0000 }, + { 0x0501, 0xd777, 0x0000 }, + { 0x8501, 0xd77a, 0x2000 }, + { 0x0501, 0xd779, 0x0000 }, + { 0x0501, 0xd77b, 0x0000 }, + { 0x8501, 0xd780, 0x3000 }, + { 0x8501, 0xd77e, 0x2000 }, + { 0x0501, 0xd77d, 0x0000 }, + { 0x0501, 0xd77f, 0x0000 }, + { 0x8501, 0xd782, 0x2000 }, + { 0x0501, 0xd781, 0x0000 }, + { 0x0501, 0xd783, 0x0000 }, + { 0x8501, 0xd78c, 0x4000 }, + { 0x8501, 0xd788, 0x3000 }, + { 0x8501, 0xd786, 0x2000 }, + { 0x0501, 0xd785, 0x0000 }, + { 0x0501, 0xd787, 0x0000 }, + { 0x8501, 0xd78a, 0x2000 }, + { 0x1901, 0xd789, 0x0000 }, + { 0x0501, 0xd78b, 0x0000 }, + { 0x8901, 0xd790, 0x3000 }, + { 0x8501, 0xd78e, 0x2000 }, + { 0x0501, 0xd78d, 0x0000 }, + { 0x0501, 0xd78f, 0x0000 }, + { 0x8901, 0xd792, 0x2000 }, + { 0x0901, 0xd791, 0x0000 }, + { 0x0901, 0xd793, 0x0000 }, + { 0x8901, 0xd7a4, 0x5000 }, + { 0x8901, 0xd79c, 0x4000 }, + { 0x8901, 0xd798, 0x3000 }, + { 0x8901, 0xd796, 0x2000 }, + { 0x0901, 0xd795, 0x0000 }, + { 0x0901, 0xd797, 0x0000 }, + { 0x8901, 0xd79a, 0x2000 }, + { 0x0901, 0xd799, 0x0000 }, + { 0x0901, 0xd79b, 0x0000 }, + { 0x8901, 0xd7a0, 0x3000 }, + { 0x8901, 0xd79e, 0x2000 }, + { 0x0901, 0xd79d, 0x0000 }, + { 0x0901, 0xd79f, 0x0000 }, + { 0x8901, 0xd7a2, 0x2000 }, + { 0x0901, 0xd7a1, 0x0000 }, + { 0x0901, 0xd7a3, 0x0000 }, + { 0x8501, 0xd7ac, 0x4000 }, + { 0x8901, 0xd7a8, 0x3000 }, + { 0x8901, 0xd7a6, 0x2000 }, + { 0x0901, 0xd7a5, 0x0000 }, + { 0x0901, 0xd7a7, 0x0000 }, + { 0x8501, 0xd7aa, 0x2000 }, + { 0x1901, 0xd7a9, 0x0000 }, + { 0x0501, 0xd7ab, 0x0000 }, + { 0x8501, 0xd7b0, 0x3000 }, + { 0x8501, 0xd7ae, 0x2000 }, + { 0x0501, 0xd7ad, 0x0000 }, + { 0x0501, 0xd7af, 0x0000 }, + { 0x8501, 0xd7b2, 0x2000 }, + { 0x0501, 0xd7b1, 0x0000 }, + { 0x0501, 0xd7b3, 0x0000 }, + { 0x8d01, 0xd7d8, 0x6000 }, + { 0x8501, 0xd7c4, 0x5000 }, + { 0x8501, 0xd7bc, 0x4000 }, + { 0x8501, 0xd7b8, 0x3000 }, + { 0x8501, 0xd7b6, 0x2000 }, + { 0x0501, 0xd7b5, 0x0000 }, + { 0x0501, 0xd7b7, 0x0000 }, + { 0x8501, 0xd7ba, 0x2000 }, + { 0x0501, 0xd7b9, 0x0000 }, + { 0x0501, 0xd7bb, 0x0000 }, + { 0x8501, 0xd7c0, 0x3000 }, + { 0x8501, 0xd7be, 0x2000 }, + { 0x0501, 0xd7bd, 0x0000 }, + { 0x0501, 0xd7bf, 0x0000 }, + { 0x8501, 0xd7c2, 0x2000 }, + { 0x0501, 0xd7c1, 0x0000 }, + { 0x1901, 0xd7c3, 0x0000 }, + { 0x8d01, 0xd7d0, 0x4000 }, + { 0x8501, 0xd7c8, 0x3000 }, + { 0x8501, 0xd7c6, 0x2000 }, + { 0x0501, 0xd7c5, 0x0000 }, + { 0x0501, 0xd7c7, 0x0000 }, + { 0x8d01, 0xd7ce, 0x2000 }, + { 0x0501, 0xd7c9, 0x0000 }, + { 0x0d01, 0xd7cf, 0x0000 }, + { 0x8d01, 0xd7d4, 0x3000 }, + { 0x8d01, 0xd7d2, 0x2000 }, + { 0x0d01, 0xd7d1, 0x0000 }, + { 0x0d01, 0xd7d3, 0x0000 }, + { 0x8d01, 0xd7d6, 0x2000 }, + { 0x0d01, 0xd7d5, 0x0000 }, + { 0x0d01, 0xd7d7, 0x0000 }, + { 0x8d01, 0xd7e8, 0x5000 }, + { 0x8d01, 0xd7e0, 0x4000 }, + { 0x8d01, 0xd7dc, 0x3000 }, + { 0x8d01, 0xd7da, 0x2000 }, + { 0x0d01, 0xd7d9, 0x0000 }, + { 0x0d01, 0xd7db, 0x0000 }, + { 0x8d01, 0xd7de, 0x2000 }, + { 0x0d01, 0xd7dd, 0x0000 }, + { 0x0d01, 0xd7df, 0x0000 }, + { 0x8d01, 0xd7e4, 0x3000 }, + { 0x8d01, 0xd7e2, 0x2000 }, + { 0x0d01, 0xd7e1, 0x0000 }, + { 0x0d01, 0xd7e3, 0x0000 }, + { 0x8d01, 0xd7e6, 0x2000 }, + { 0x0d01, 0xd7e5, 0x0000 }, + { 0x0d01, 0xd7e7, 0x0000 }, + { 0x8d01, 0xd7f0, 0x4000 }, + { 0x8d01, 0xd7ec, 0x3000 }, + { 0x8d01, 0xd7ea, 0x2000 }, + { 0x0d01, 0xd7e9, 0x0000 }, + { 0x0d01, 0xd7eb, 0x0000 }, + { 0x8d01, 0xd7ee, 0x2000 }, + { 0x0d01, 0xd7ed, 0x0000 }, + { 0x0d01, 0xd7ef, 0x0000 }, + { 0x8d01, 0xd7f4, 0x3000 }, + { 0x8d01, 0xd7f2, 0x2000 }, + { 0x0d01, 0xd7f1, 0x0000 }, + { 0x0d01, 0xd7f3, 0x0000 }, + { 0x8d01, 0xd7f6, 0x2000 }, + { 0x0d01, 0xd7f5, 0x0000 }, + { 0x0d01, 0xd7f7, 0x0000 }, + { 0x8702, 0xf836, 0x7000 }, + { 0x8702, 0xf816, 0x6000 }, + { 0x8702, 0xf806, 0x5000 }, + { 0x8702, 0x0000, 0x4000 }, + { 0x8d01, 0xd7fc, 0x3000 }, + { 0x8d01, 0xd7fa, 0x2000 }, + { 0x0d01, 0xd7f9, 0x0000 }, + { 0x0d01, 0xd7fb, 0x0000 }, + { 0x8d01, 0xd7fe, 0x2000 }, + { 0x0d01, 0xd7fd, 0x0000 }, + { 0x0d01, 0xd7ff, 0x0000 }, + { 0x8702, 0xf802, 0x3000 }, + { 0x8702, 0xf800, 0x2000 }, + { 0x0702, 0xa6d6, 0x0000 }, + { 0x0702, 0xf801, 0x0000 }, + { 0x8702, 0xf804, 0x2000 }, + { 0x0702, 0xf803, 0x0000 }, + { 0x0702, 0xf805, 0x0000 }, + { 0x8702, 0xf80e, 0x4000 }, + { 0x8702, 0xf80a, 0x3000 }, + { 0x8702, 0xf808, 0x2000 }, + { 0x0702, 0xf807, 0x0000 }, + { 0x0702, 0xf809, 0x0000 }, + { 0x8702, 0xf80c, 0x2000 }, + { 0x0702, 0xf80b, 0x0000 }, + { 0x0702, 0xf80d, 0x0000 }, + { 0x8702, 0xf812, 0x3000 }, + { 0x8702, 0xf810, 0x2000 }, + { 0x0702, 0xf80f, 0x0000 }, + { 0x0702, 0xf811, 0x0000 }, + { 0x8702, 0xf814, 0x2000 }, + { 0x0702, 0xf813, 0x0000 }, + { 0x0702, 0xf815, 0x0000 }, + { 0x8702, 0xf826, 0x5000 }, + { 0x8702, 0xf81e, 0x4000 }, + { 0x8702, 0xf81a, 0x3000 }, + { 0x8702, 0xf818, 0x2000 }, + { 0x0702, 0xf817, 0x0000 }, + { 0x0702, 0xf819, 0x0000 }, + { 0x8702, 0xf81c, 0x2000 }, + { 0x0702, 0xf81b, 0x0000 }, + { 0x0702, 0xf81d, 0x0000 }, + { 0x8702, 0xf822, 0x3000 }, + { 0x8702, 0xf820, 0x2000 }, + { 0x0702, 0xf81f, 0x0000 }, + { 0x0702, 0xf821, 0x0000 }, + { 0x8702, 0xf824, 0x2000 }, + { 0x0702, 0xf823, 0x0000 }, + { 0x0702, 0xf825, 0x0000 }, + { 0x8702, 0xf82e, 0x4000 }, + { 0x8702, 0xf82a, 0x3000 }, + { 0x8702, 0xf828, 0x2000 }, + { 0x0702, 0xf827, 0x0000 }, + { 0x0702, 0xf829, 0x0000 }, + { 0x8702, 0xf82c, 0x2000 }, + { 0x0702, 0xf82b, 0x0000 }, + { 0x0702, 0xf82d, 0x0000 }, + { 0x8702, 0xf832, 0x3000 }, + { 0x8702, 0xf830, 0x2000 }, + { 0x0702, 0xf82f, 0x0000 }, + { 0x0702, 0xf831, 0x0000 }, + { 0x8702, 0xf834, 0x2000 }, + { 0x0702, 0xf833, 0x0000 }, + { 0x0702, 0xf835, 0x0000 }, + { 0x8702, 0xf856, 0x6000 }, + { 0x8702, 0xf846, 0x5000 }, + { 0x8702, 0xf83e, 0x4000 }, + { 0x8702, 0xf83a, 0x3000 }, + { 0x8702, 0xf838, 0x2000 }, + { 0x0702, 0xf837, 0x0000 }, + { 0x0702, 0xf839, 0x0000 }, + { 0x8702, 0xf83c, 0x2000 }, + { 0x0702, 0xf83b, 0x0000 }, + { 0x0702, 0xf83d, 0x0000 }, + { 0x8702, 0xf842, 0x3000 }, + { 0x8702, 0xf840, 0x2000 }, + { 0x0702, 0xf83f, 0x0000 }, + { 0x0702, 0xf841, 0x0000 }, + { 0x8702, 0xf844, 0x2000 }, + { 0x0702, 0xf843, 0x0000 }, + { 0x0702, 0xf845, 0x0000 }, + { 0x8702, 0xf84e, 0x4000 }, + { 0x8702, 0xf84a, 0x3000 }, + { 0x8702, 0xf848, 0x2000 }, + { 0x0702, 0xf847, 0x0000 }, + { 0x0702, 0xf849, 0x0000 }, + { 0x8702, 0xf84c, 0x2000 }, + { 0x0702, 0xf84b, 0x0000 }, + { 0x0702, 0xf84d, 0x0000 }, + { 0x8702, 0xf852, 0x3000 }, + { 0x8702, 0xf850, 0x2000 }, + { 0x0702, 0xf84f, 0x0000 }, + { 0x0702, 0xf851, 0x0000 }, + { 0x8702, 0xf854, 0x2000 }, + { 0x0702, 0xf853, 0x0000 }, + { 0x0702, 0xf855, 0x0000 }, + { 0x8702, 0xf866, 0x5000 }, + { 0x8702, 0xf85e, 0x4000 }, + { 0x8702, 0xf85a, 0x3000 }, + { 0x8702, 0xf858, 0x2000 }, + { 0x0702, 0xf857, 0x0000 }, + { 0x0702, 0xf859, 0x0000 }, + { 0x8702, 0xf85c, 0x2000 }, + { 0x0702, 0xf85b, 0x0000 }, + { 0x0702, 0xf85d, 0x0000 }, + { 0x8702, 0xf862, 0x3000 }, + { 0x8702, 0xf860, 0x2000 }, + { 0x0702, 0xf85f, 0x0000 }, + { 0x0702, 0xf861, 0x0000 }, + { 0x8702, 0xf864, 0x2000 }, + { 0x0702, 0xf863, 0x0000 }, + { 0x0702, 0xf865, 0x0000 }, + { 0x8702, 0xf86e, 0x4000 }, + { 0x8702, 0xf86a, 0x3000 }, + { 0x8702, 0xf868, 0x2000 }, + { 0x0702, 0xf867, 0x0000 }, + { 0x0702, 0xf869, 0x0000 }, + { 0x8702, 0xf86c, 0x2000 }, + { 0x0702, 0xf86b, 0x0000 }, + { 0x0702, 0xf86d, 0x0000 }, + { 0x8702, 0xf872, 0x3000 }, + { 0x8702, 0xf870, 0x2000 }, + { 0x0702, 0xf86f, 0x0000 }, + { 0x0702, 0xf871, 0x0000 }, + { 0x8702, 0xf874, 0x2000 }, + { 0x0702, 0xf873, 0x0000 }, + { 0x0702, 0xf875, 0x0000 }, + { 0x8702, 0xf976, 0x9000 }, + { 0x8702, 0xf8f6, 0x8000 }, + { 0x8702, 0xf8b6, 0x7000 }, + { 0x8702, 0xf896, 0x6000 }, + { 0x8702, 0xf886, 0x5000 }, + { 0x8702, 0xf87e, 0x4000 }, + { 0x8702, 0xf87a, 0x3000 }, + { 0x8702, 0xf878, 0x2000 }, + { 0x0702, 0xf877, 0x0000 }, + { 0x0702, 0xf879, 0x0000 }, + { 0x8702, 0xf87c, 0x2000 }, + { 0x0702, 0xf87b, 0x0000 }, + { 0x0702, 0xf87d, 0x0000 }, + { 0x8702, 0xf882, 0x3000 }, + { 0x8702, 0xf880, 0x2000 }, + { 0x0702, 0xf87f, 0x0000 }, + { 0x0702, 0xf881, 0x0000 }, + { 0x8702, 0xf884, 0x2000 }, + { 0x0702, 0xf883, 0x0000 }, + { 0x0702, 0xf885, 0x0000 }, + { 0x8702, 0xf88e, 0x4000 }, + { 0x8702, 0xf88a, 0x3000 }, + { 0x8702, 0xf888, 0x2000 }, + { 0x0702, 0xf887, 0x0000 }, + { 0x0702, 0xf889, 0x0000 }, + { 0x8702, 0xf88c, 0x2000 }, + { 0x0702, 0xf88b, 0x0000 }, + { 0x0702, 0xf88d, 0x0000 }, + { 0x8702, 0xf892, 0x3000 }, + { 0x8702, 0xf890, 0x2000 }, + { 0x0702, 0xf88f, 0x0000 }, + { 0x0702, 0xf891, 0x0000 }, + { 0x8702, 0xf894, 0x2000 }, + { 0x0702, 0xf893, 0x0000 }, + { 0x0702, 0xf895, 0x0000 }, + { 0x8702, 0xf8a6, 0x5000 }, + { 0x8702, 0xf89e, 0x4000 }, + { 0x8702, 0xf89a, 0x3000 }, + { 0x8702, 0xf898, 0x2000 }, + { 0x0702, 0xf897, 0x0000 }, + { 0x0702, 0xf899, 0x0000 }, + { 0x8702, 0xf89c, 0x2000 }, + { 0x0702, 0xf89b, 0x0000 }, + { 0x0702, 0xf89d, 0x0000 }, + { 0x8702, 0xf8a2, 0x3000 }, + { 0x8702, 0xf8a0, 0x2000 }, + { 0x0702, 0xf89f, 0x0000 }, + { 0x0702, 0xf8a1, 0x0000 }, + { 0x8702, 0xf8a4, 0x2000 }, + { 0x0702, 0xf8a3, 0x0000 }, + { 0x0702, 0xf8a5, 0x0000 }, + { 0x8702, 0xf8ae, 0x4000 }, + { 0x8702, 0xf8aa, 0x3000 }, + { 0x8702, 0xf8a8, 0x2000 }, + { 0x0702, 0xf8a7, 0x0000 }, + { 0x0702, 0xf8a9, 0x0000 }, + { 0x8702, 0xf8ac, 0x2000 }, + { 0x0702, 0xf8ab, 0x0000 }, + { 0x0702, 0xf8ad, 0x0000 }, + { 0x8702, 0xf8b2, 0x3000 }, + { 0x8702, 0xf8b0, 0x2000 }, + { 0x0702, 0xf8af, 0x0000 }, + { 0x0702, 0xf8b1, 0x0000 }, + { 0x8702, 0xf8b4, 0x2000 }, + { 0x0702, 0xf8b3, 0x0000 }, + { 0x0702, 0xf8b5, 0x0000 }, + { 0x8702, 0xf8d6, 0x6000 }, + { 0x8702, 0xf8c6, 0x5000 }, + { 0x8702, 0xf8be, 0x4000 }, + { 0x8702, 0xf8ba, 0x3000 }, + { 0x8702, 0xf8b8, 0x2000 }, + { 0x0702, 0xf8b7, 0x0000 }, + { 0x0702, 0xf8b9, 0x0000 }, + { 0x8702, 0xf8bc, 0x2000 }, + { 0x0702, 0xf8bb, 0x0000 }, + { 0x0702, 0xf8bd, 0x0000 }, + { 0x8702, 0xf8c2, 0x3000 }, + { 0x8702, 0xf8c0, 0x2000 }, + { 0x0702, 0xf8bf, 0x0000 }, + { 0x0702, 0xf8c1, 0x0000 }, + { 0x8702, 0xf8c4, 0x2000 }, + { 0x0702, 0xf8c3, 0x0000 }, + { 0x0702, 0xf8c5, 0x0000 }, + { 0x8702, 0xf8ce, 0x4000 }, + { 0x8702, 0xf8ca, 0x3000 }, + { 0x8702, 0xf8c8, 0x2000 }, + { 0x0702, 0xf8c7, 0x0000 }, + { 0x0702, 0xf8c9, 0x0000 }, + { 0x8702, 0xf8cc, 0x2000 }, + { 0x0702, 0xf8cb, 0x0000 }, + { 0x0702, 0xf8cd, 0x0000 }, + { 0x8702, 0xf8d2, 0x3000 }, + { 0x8702, 0xf8d0, 0x2000 }, + { 0x0702, 0xf8cf, 0x0000 }, + { 0x0702, 0xf8d1, 0x0000 }, + { 0x8702, 0xf8d4, 0x2000 }, + { 0x0702, 0xf8d3, 0x0000 }, + { 0x0702, 0xf8d5, 0x0000 }, + { 0x8702, 0xf8e6, 0x5000 }, + { 0x8702, 0xf8de, 0x4000 }, + { 0x8702, 0xf8da, 0x3000 }, + { 0x8702, 0xf8d8, 0x2000 }, + { 0x0702, 0xf8d7, 0x0000 }, + { 0x0702, 0xf8d9, 0x0000 }, + { 0x8702, 0xf8dc, 0x2000 }, + { 0x0702, 0xf8db, 0x0000 }, + { 0x0702, 0xf8dd, 0x0000 }, + { 0x8702, 0xf8e2, 0x3000 }, + { 0x8702, 0xf8e0, 0x2000 }, + { 0x0702, 0xf8df, 0x0000 }, + { 0x0702, 0xf8e1, 0x0000 }, + { 0x8702, 0xf8e4, 0x2000 }, + { 0x0702, 0xf8e3, 0x0000 }, + { 0x0702, 0xf8e5, 0x0000 }, + { 0x8702, 0xf8ee, 0x4000 }, + { 0x8702, 0xf8ea, 0x3000 }, + { 0x8702, 0xf8e8, 0x2000 }, + { 0x0702, 0xf8e7, 0x0000 }, + { 0x0702, 0xf8e9, 0x0000 }, + { 0x8702, 0xf8ec, 0x2000 }, + { 0x0702, 0xf8eb, 0x0000 }, + { 0x0702, 0xf8ed, 0x0000 }, + { 0x8702, 0xf8f2, 0x3000 }, + { 0x8702, 0xf8f0, 0x2000 }, + { 0x0702, 0xf8ef, 0x0000 }, + { 0x0702, 0xf8f1, 0x0000 }, + { 0x8702, 0xf8f4, 0x2000 }, + { 0x0702, 0xf8f3, 0x0000 }, + { 0x0702, 0xf8f5, 0x0000 }, + { 0x8702, 0xf936, 0x7000 }, + { 0x8702, 0xf916, 0x6000 }, + { 0x8702, 0xf906, 0x5000 }, + { 0x8702, 0xf8fe, 0x4000 }, + { 0x8702, 0xf8fa, 0x3000 }, + { 0x8702, 0xf8f8, 0x2000 }, + { 0x0702, 0xf8f7, 0x0000 }, + { 0x0702, 0xf8f9, 0x0000 }, + { 0x8702, 0xf8fc, 0x2000 }, + { 0x0702, 0xf8fb, 0x0000 }, + { 0x0702, 0xf8fd, 0x0000 }, + { 0x8702, 0xf902, 0x3000 }, + { 0x8702, 0xf900, 0x2000 }, + { 0x0702, 0xf8ff, 0x0000 }, + { 0x0702, 0xf901, 0x0000 }, + { 0x8702, 0xf904, 0x2000 }, + { 0x0702, 0xf903, 0x0000 }, + { 0x0702, 0xf905, 0x0000 }, + { 0x8702, 0xf90e, 0x4000 }, + { 0x8702, 0xf90a, 0x3000 }, + { 0x8702, 0xf908, 0x2000 }, + { 0x0702, 0xf907, 0x0000 }, + { 0x0702, 0xf909, 0x0000 }, + { 0x8702, 0xf90c, 0x2000 }, + { 0x0702, 0xf90b, 0x0000 }, + { 0x0702, 0xf90d, 0x0000 }, + { 0x8702, 0xf912, 0x3000 }, + { 0x8702, 0xf910, 0x2000 }, + { 0x0702, 0xf90f, 0x0000 }, + { 0x0702, 0xf911, 0x0000 }, + { 0x8702, 0xf914, 0x2000 }, + { 0x0702, 0xf913, 0x0000 }, + { 0x0702, 0xf915, 0x0000 }, + { 0x8702, 0xf926, 0x5000 }, + { 0x8702, 0xf91e, 0x4000 }, + { 0x8702, 0xf91a, 0x3000 }, + { 0x8702, 0xf918, 0x2000 }, + { 0x0702, 0xf917, 0x0000 }, + { 0x0702, 0xf919, 0x0000 }, + { 0x8702, 0xf91c, 0x2000 }, + { 0x0702, 0xf91b, 0x0000 }, + { 0x0702, 0xf91d, 0x0000 }, + { 0x8702, 0xf922, 0x3000 }, + { 0x8702, 0xf920, 0x2000 }, + { 0x0702, 0xf91f, 0x0000 }, + { 0x0702, 0xf921, 0x0000 }, + { 0x8702, 0xf924, 0x2000 }, + { 0x0702, 0xf923, 0x0000 }, + { 0x0702, 0xf925, 0x0000 }, + { 0x8702, 0xf92e, 0x4000 }, + { 0x8702, 0xf92a, 0x3000 }, + { 0x8702, 0xf928, 0x2000 }, + { 0x0702, 0xf927, 0x0000 }, + { 0x0702, 0xf929, 0x0000 }, + { 0x8702, 0xf92c, 0x2000 }, + { 0x0702, 0xf92b, 0x0000 }, + { 0x0702, 0xf92d, 0x0000 }, + { 0x8702, 0xf932, 0x3000 }, + { 0x8702, 0xf930, 0x2000 }, + { 0x0702, 0xf92f, 0x0000 }, + { 0x0702, 0xf931, 0x0000 }, + { 0x8702, 0xf934, 0x2000 }, + { 0x0702, 0xf933, 0x0000 }, + { 0x0702, 0xf935, 0x0000 }, + { 0x8702, 0xf956, 0x6000 }, + { 0x8702, 0xf946, 0x5000 }, + { 0x8702, 0xf93e, 0x4000 }, + { 0x8702, 0xf93a, 0x3000 }, + { 0x8702, 0xf938, 0x2000 }, + { 0x0702, 0xf937, 0x0000 }, + { 0x0702, 0xf939, 0x0000 }, + { 0x8702, 0xf93c, 0x2000 }, + { 0x0702, 0xf93b, 0x0000 }, + { 0x0702, 0xf93d, 0x0000 }, + { 0x8702, 0xf942, 0x3000 }, + { 0x8702, 0xf940, 0x2000 }, + { 0x0702, 0xf93f, 0x0000 }, + { 0x0702, 0xf941, 0x0000 }, + { 0x8702, 0xf944, 0x2000 }, + { 0x0702, 0xf943, 0x0000 }, + { 0x0702, 0xf945, 0x0000 }, + { 0x8702, 0xf94e, 0x4000 }, + { 0x8702, 0xf94a, 0x3000 }, + { 0x8702, 0xf948, 0x2000 }, + { 0x0702, 0xf947, 0x0000 }, + { 0x0702, 0xf949, 0x0000 }, + { 0x8702, 0xf94c, 0x2000 }, + { 0x0702, 0xf94b, 0x0000 }, + { 0x0702, 0xf94d, 0x0000 }, + { 0x8702, 0xf952, 0x3000 }, + { 0x8702, 0xf950, 0x2000 }, + { 0x0702, 0xf94f, 0x0000 }, + { 0x0702, 0xf951, 0x0000 }, + { 0x8702, 0xf954, 0x2000 }, + { 0x0702, 0xf953, 0x0000 }, + { 0x0702, 0xf955, 0x0000 }, + { 0x8702, 0xf966, 0x5000 }, + { 0x8702, 0xf95e, 0x4000 }, + { 0x8702, 0xf95a, 0x3000 }, + { 0x8702, 0xf958, 0x2000 }, + { 0x0702, 0xf957, 0x0000 }, + { 0x0702, 0xf959, 0x0000 }, + { 0x8702, 0xf95c, 0x2000 }, + { 0x0702, 0xf95b, 0x0000 }, + { 0x0702, 0xf95d, 0x0000 }, + { 0x8702, 0xf962, 0x3000 }, + { 0x8702, 0xf960, 0x2000 }, + { 0x0702, 0xf95f, 0x0000 }, + { 0x0702, 0xf961, 0x0000 }, + { 0x8702, 0xf964, 0x2000 }, + { 0x0702, 0xf963, 0x0000 }, + { 0x0702, 0xf965, 0x0000 }, + { 0x8702, 0xf96e, 0x4000 }, + { 0x8702, 0xf96a, 0x3000 }, + { 0x8702, 0xf968, 0x2000 }, + { 0x0702, 0xf967, 0x0000 }, + { 0x0702, 0xf969, 0x0000 }, + { 0x8702, 0xf96c, 0x2000 }, + { 0x0702, 0xf96b, 0x0000 }, + { 0x0702, 0xf96d, 0x0000 }, + { 0x8702, 0xf972, 0x3000 }, + { 0x8702, 0xf970, 0x2000 }, + { 0x0702, 0xf96f, 0x0000 }, + { 0x0702, 0xf971, 0x0000 }, + { 0x8702, 0xf974, 0x2000 }, + { 0x0702, 0xf973, 0x0000 }, + { 0x0702, 0xf975, 0x0000 }, + { 0x810e, 0x0077, 0x9000 }, + { 0x8702, 0xf9f6, 0x8000 }, + { 0x8702, 0xf9b6, 0x7000 }, + { 0x8702, 0xf996, 0x6000 }, + { 0x8702, 0xf986, 0x5000 }, + { 0x8702, 0xf97e, 0x4000 }, + { 0x8702, 0xf97a, 0x3000 }, + { 0x8702, 0xf978, 0x2000 }, + { 0x0702, 0xf977, 0x0000 }, + { 0x0702, 0xf979, 0x0000 }, + { 0x8702, 0xf97c, 0x2000 }, + { 0x0702, 0xf97b, 0x0000 }, + { 0x0702, 0xf97d, 0x0000 }, + { 0x8702, 0xf982, 0x3000 }, + { 0x8702, 0xf980, 0x2000 }, + { 0x0702, 0xf97f, 0x0000 }, + { 0x0702, 0xf981, 0x0000 }, + { 0x8702, 0xf984, 0x2000 }, + { 0x0702, 0xf983, 0x0000 }, + { 0x0702, 0xf985, 0x0000 }, + { 0x8702, 0xf98e, 0x4000 }, + { 0x8702, 0xf98a, 0x3000 }, + { 0x8702, 0xf988, 0x2000 }, + { 0x0702, 0xf987, 0x0000 }, + { 0x0702, 0xf989, 0x0000 }, + { 0x8702, 0xf98c, 0x2000 }, + { 0x0702, 0xf98b, 0x0000 }, + { 0x0702, 0xf98d, 0x0000 }, + { 0x8702, 0xf992, 0x3000 }, + { 0x8702, 0xf990, 0x2000 }, + { 0x0702, 0xf98f, 0x0000 }, + { 0x0702, 0xf991, 0x0000 }, + { 0x8702, 0xf994, 0x2000 }, + { 0x0702, 0xf993, 0x0000 }, + { 0x0702, 0xf995, 0x0000 }, + { 0x8702, 0xf9a6, 0x5000 }, + { 0x8702, 0xf99e, 0x4000 }, + { 0x8702, 0xf99a, 0x3000 }, + { 0x8702, 0xf998, 0x2000 }, + { 0x0702, 0xf997, 0x0000 }, + { 0x0702, 0xf999, 0x0000 }, + { 0x8702, 0xf99c, 0x2000 }, + { 0x0702, 0xf99b, 0x0000 }, + { 0x0702, 0xf99d, 0x0000 }, + { 0x8702, 0xf9a2, 0x3000 }, + { 0x8702, 0xf9a0, 0x2000 }, + { 0x0702, 0xf99f, 0x0000 }, + { 0x0702, 0xf9a1, 0x0000 }, + { 0x8702, 0xf9a4, 0x2000 }, + { 0x0702, 0xf9a3, 0x0000 }, + { 0x0702, 0xf9a5, 0x0000 }, + { 0x8702, 0xf9ae, 0x4000 }, + { 0x8702, 0xf9aa, 0x3000 }, + { 0x8702, 0xf9a8, 0x2000 }, + { 0x0702, 0xf9a7, 0x0000 }, + { 0x0702, 0xf9a9, 0x0000 }, + { 0x8702, 0xf9ac, 0x2000 }, + { 0x0702, 0xf9ab, 0x0000 }, + { 0x0702, 0xf9ad, 0x0000 }, + { 0x8702, 0xf9b2, 0x3000 }, + { 0x8702, 0xf9b0, 0x2000 }, + { 0x0702, 0xf9af, 0x0000 }, + { 0x0702, 0xf9b1, 0x0000 }, + { 0x8702, 0xf9b4, 0x2000 }, + { 0x0702, 0xf9b3, 0x0000 }, + { 0x0702, 0xf9b5, 0x0000 }, + { 0x8702, 0xf9d6, 0x6000 }, + { 0x8702, 0xf9c6, 0x5000 }, + { 0x8702, 0xf9be, 0x4000 }, + { 0x8702, 0xf9ba, 0x3000 }, + { 0x8702, 0xf9b8, 0x2000 }, + { 0x0702, 0xf9b7, 0x0000 }, + { 0x0702, 0xf9b9, 0x0000 }, + { 0x8702, 0xf9bc, 0x2000 }, + { 0x0702, 0xf9bb, 0x0000 }, + { 0x0702, 0xf9bd, 0x0000 }, + { 0x8702, 0xf9c2, 0x3000 }, + { 0x8702, 0xf9c0, 0x2000 }, + { 0x0702, 0xf9bf, 0x0000 }, + { 0x0702, 0xf9c1, 0x0000 }, + { 0x8702, 0xf9c4, 0x2000 }, + { 0x0702, 0xf9c3, 0x0000 }, + { 0x0702, 0xf9c5, 0x0000 }, + { 0x8702, 0xf9ce, 0x4000 }, + { 0x8702, 0xf9ca, 0x3000 }, + { 0x8702, 0xf9c8, 0x2000 }, + { 0x0702, 0xf9c7, 0x0000 }, + { 0x0702, 0xf9c9, 0x0000 }, + { 0x8702, 0xf9cc, 0x2000 }, + { 0x0702, 0xf9cb, 0x0000 }, + { 0x0702, 0xf9cd, 0x0000 }, + { 0x8702, 0xf9d2, 0x3000 }, + { 0x8702, 0xf9d0, 0x2000 }, + { 0x0702, 0xf9cf, 0x0000 }, + { 0x0702, 0xf9d1, 0x0000 }, + { 0x8702, 0xf9d4, 0x2000 }, + { 0x0702, 0xf9d3, 0x0000 }, + { 0x0702, 0xf9d5, 0x0000 }, + { 0x8702, 0xf9e6, 0x5000 }, + { 0x8702, 0xf9de, 0x4000 }, + { 0x8702, 0xf9da, 0x3000 }, + { 0x8702, 0xf9d8, 0x2000 }, + { 0x0702, 0xf9d7, 0x0000 }, + { 0x0702, 0xf9d9, 0x0000 }, + { 0x8702, 0xf9dc, 0x2000 }, + { 0x0702, 0xf9db, 0x0000 }, + { 0x0702, 0xf9dd, 0x0000 }, + { 0x8702, 0xf9e2, 0x3000 }, + { 0x8702, 0xf9e0, 0x2000 }, + { 0x0702, 0xf9df, 0x0000 }, + { 0x0702, 0xf9e1, 0x0000 }, + { 0x8702, 0xf9e4, 0x2000 }, + { 0x0702, 0xf9e3, 0x0000 }, + { 0x0702, 0xf9e5, 0x0000 }, + { 0x8702, 0xf9ee, 0x4000 }, + { 0x8702, 0xf9ea, 0x3000 }, + { 0x8702, 0xf9e8, 0x2000 }, + { 0x0702, 0xf9e7, 0x0000 }, + { 0x0702, 0xf9e9, 0x0000 }, + { 0x8702, 0xf9ec, 0x2000 }, + { 0x0702, 0xf9eb, 0x0000 }, + { 0x0702, 0xf9ed, 0x0000 }, + { 0x8702, 0xf9f2, 0x3000 }, + { 0x8702, 0xf9f0, 0x2000 }, + { 0x0702, 0xf9ef, 0x0000 }, + { 0x0702, 0xf9f1, 0x0000 }, + { 0x8702, 0xf9f4, 0x2000 }, + { 0x0702, 0xf9f3, 0x0000 }, + { 0x0702, 0xf9f5, 0x0000 }, + { 0x810e, 0x0037, 0x7000 }, + { 0x8702, 0xfa16, 0x6000 }, + { 0x8702, 0xfa06, 0x5000 }, + { 0x8702, 0xf9fe, 0x4000 }, + { 0x8702, 0xf9fa, 0x3000 }, + { 0x8702, 0xf9f8, 0x2000 }, + { 0x0702, 0xf9f7, 0x0000 }, + { 0x0702, 0xf9f9, 0x0000 }, + { 0x8702, 0xf9fc, 0x2000 }, + { 0x0702, 0xf9fb, 0x0000 }, + { 0x0702, 0xf9fd, 0x0000 }, + { 0x8702, 0xfa02, 0x3000 }, + { 0x8702, 0xfa00, 0x2000 }, + { 0x0702, 0xf9ff, 0x0000 }, + { 0x0702, 0xfa01, 0x0000 }, + { 0x8702, 0xfa04, 0x2000 }, + { 0x0702, 0xfa03, 0x0000 }, + { 0x0702, 0xfa05, 0x0000 }, + { 0x8702, 0xfa0e, 0x4000 }, + { 0x8702, 0xfa0a, 0x3000 }, + { 0x8702, 0xfa08, 0x2000 }, + { 0x0702, 0xfa07, 0x0000 }, + { 0x0702, 0xfa09, 0x0000 }, + { 0x8702, 0xfa0c, 0x2000 }, + { 0x0702, 0xfa0b, 0x0000 }, + { 0x0702, 0xfa0d, 0x0000 }, + { 0x8702, 0xfa12, 0x3000 }, + { 0x8702, 0xfa10, 0x2000 }, + { 0x0702, 0xfa0f, 0x0000 }, + { 0x0702, 0xfa11, 0x0000 }, + { 0x8702, 0xfa14, 0x2000 }, + { 0x0702, 0xfa13, 0x0000 }, + { 0x0702, 0xfa15, 0x0000 }, + { 0x810e, 0x0027, 0x5000 }, + { 0x810e, 0x0001, 0x4000 }, + { 0x8702, 0xfa1a, 0x3000 }, + { 0x8702, 0xfa18, 0x2000 }, + { 0x0702, 0xfa17, 0x0000 }, + { 0x0702, 0xfa19, 0x0000 }, + { 0x8702, 0xfa1c, 0x2000 }, + { 0x0702, 0xfa1b, 0x0000 }, + { 0x0702, 0xfa1d, 0x0000 }, + { 0x810e, 0x0023, 0x3000 }, + { 0x810e, 0x0021, 0x2000 }, + { 0x010e, 0x0020, 0x0000 }, + { 0x010e, 0x0022, 0x0000 }, + { 0x810e, 0x0025, 0x2000 }, + { 0x010e, 0x0024, 0x0000 }, + { 0x010e, 0x0026, 0x0000 }, + { 0x810e, 0x002f, 0x4000 }, + { 0x810e, 0x002b, 0x3000 }, + { 0x810e, 0x0029, 0x2000 }, + { 0x010e, 0x0028, 0x0000 }, + { 0x010e, 0x002a, 0x0000 }, + { 0x810e, 0x002d, 0x2000 }, + { 0x010e, 0x002c, 0x0000 }, + { 0x010e, 0x002e, 0x0000 }, + { 0x810e, 0x0033, 0x3000 }, + { 0x810e, 0x0031, 0x2000 }, + { 0x010e, 0x0030, 0x0000 }, + { 0x010e, 0x0032, 0x0000 }, + { 0x810e, 0x0035, 0x2000 }, + { 0x010e, 0x0034, 0x0000 }, + { 0x010e, 0x0036, 0x0000 }, + { 0x810e, 0x0057, 0x6000 }, + { 0x810e, 0x0047, 0x5000 }, + { 0x810e, 0x003f, 0x4000 }, + { 0x810e, 0x003b, 0x3000 }, + { 0x810e, 0x0039, 0x2000 }, + { 0x010e, 0x0038, 0x0000 }, + { 0x010e, 0x003a, 0x0000 }, + { 0x810e, 0x003d, 0x2000 }, + { 0x010e, 0x003c, 0x0000 }, + { 0x010e, 0x003e, 0x0000 }, + { 0x810e, 0x0043, 0x3000 }, + { 0x810e, 0x0041, 0x2000 }, + { 0x010e, 0x0040, 0x0000 }, + { 0x010e, 0x0042, 0x0000 }, + { 0x810e, 0x0045, 0x2000 }, + { 0x010e, 0x0044, 0x0000 }, + { 0x010e, 0x0046, 0x0000 }, + { 0x810e, 0x004f, 0x4000 }, + { 0x810e, 0x004b, 0x3000 }, + { 0x810e, 0x0049, 0x2000 }, + { 0x010e, 0x0048, 0x0000 }, + { 0x010e, 0x004a, 0x0000 }, + { 0x810e, 0x004d, 0x2000 }, + { 0x010e, 0x004c, 0x0000 }, + { 0x010e, 0x004e, 0x0000 }, + { 0x810e, 0x0053, 0x3000 }, + { 0x810e, 0x0051, 0x2000 }, + { 0x010e, 0x0050, 0x0000 }, + { 0x010e, 0x0052, 0x0000 }, + { 0x810e, 0x0055, 0x2000 }, + { 0x010e, 0x0054, 0x0000 }, + { 0x010e, 0x0056, 0x0000 }, + { 0x810e, 0x0067, 0x5000 }, + { 0x810e, 0x005f, 0x4000 }, + { 0x810e, 0x005b, 0x3000 }, + { 0x810e, 0x0059, 0x2000 }, + { 0x010e, 0x0058, 0x0000 }, + { 0x010e, 0x005a, 0x0000 }, + { 0x810e, 0x005d, 0x2000 }, + { 0x010e, 0x005c, 0x0000 }, + { 0x010e, 0x005e, 0x0000 }, + { 0x810e, 0x0063, 0x3000 }, + { 0x810e, 0x0061, 0x2000 }, + { 0x010e, 0x0060, 0x0000 }, + { 0x010e, 0x0062, 0x0000 }, + { 0x810e, 0x0065, 0x2000 }, + { 0x010e, 0x0064, 0x0000 }, + { 0x010e, 0x0066, 0x0000 }, + { 0x810e, 0x006f, 0x4000 }, + { 0x810e, 0x006b, 0x3000 }, + { 0x810e, 0x0069, 0x2000 }, + { 0x010e, 0x0068, 0x0000 }, + { 0x010e, 0x006a, 0x0000 }, + { 0x810e, 0x006d, 0x2000 }, + { 0x010e, 0x006c, 0x0000 }, + { 0x010e, 0x006e, 0x0000 }, + { 0x810e, 0x0073, 0x3000 }, + { 0x810e, 0x0071, 0x2000 }, + { 0x010e, 0x0070, 0x0000 }, + { 0x010e, 0x0072, 0x0000 }, + { 0x810e, 0x0075, 0x2000 }, + { 0x010e, 0x0074, 0x0000 }, + { 0x010e, 0x0076, 0x0000 }, + { 0x8c0e, 0x0177, 0x8000 }, + { 0x8c0e, 0x0137, 0x7000 }, + { 0x8c0e, 0x0117, 0x6000 }, + { 0x8c0e, 0x0107, 0x5000 }, + { 0x810e, 0x007f, 0x4000 }, + { 0x810e, 0x007b, 0x3000 }, + { 0x810e, 0x0079, 0x2000 }, + { 0x010e, 0x0078, 0x0000 }, + { 0x010e, 0x007a, 0x0000 }, + { 0x810e, 0x007d, 0x2000 }, + { 0x010e, 0x007c, 0x0000 }, + { 0x010e, 0x007e, 0x0000 }, + { 0x8c0e, 0x0103, 0x3000 }, + { 0x8c0e, 0x0101, 0x2000 }, + { 0x0c0e, 0x0100, 0x0000 }, + { 0x0c0e, 0x0102, 0x0000 }, + { 0x8c0e, 0x0105, 0x2000 }, + { 0x0c0e, 0x0104, 0x0000 }, + { 0x0c0e, 0x0106, 0x0000 }, + { 0x8c0e, 0x010f, 0x4000 }, + { 0x8c0e, 0x010b, 0x3000 }, + { 0x8c0e, 0x0109, 0x2000 }, + { 0x0c0e, 0x0108, 0x0000 }, + { 0x0c0e, 0x010a, 0x0000 }, + { 0x8c0e, 0x010d, 0x2000 }, + { 0x0c0e, 0x010c, 0x0000 }, + { 0x0c0e, 0x010e, 0x0000 }, + { 0x8c0e, 0x0113, 0x3000 }, + { 0x8c0e, 0x0111, 0x2000 }, + { 0x0c0e, 0x0110, 0x0000 }, + { 0x0c0e, 0x0112, 0x0000 }, + { 0x8c0e, 0x0115, 0x2000 }, + { 0x0c0e, 0x0114, 0x0000 }, + { 0x0c0e, 0x0116, 0x0000 }, + { 0x8c0e, 0x0127, 0x5000 }, + { 0x8c0e, 0x011f, 0x4000 }, + { 0x8c0e, 0x011b, 0x3000 }, + { 0x8c0e, 0x0119, 0x2000 }, + { 0x0c0e, 0x0118, 0x0000 }, + { 0x0c0e, 0x011a, 0x0000 }, + { 0x8c0e, 0x011d, 0x2000 }, + { 0x0c0e, 0x011c, 0x0000 }, + { 0x0c0e, 0x011e, 0x0000 }, + { 0x8c0e, 0x0123, 0x3000 }, + { 0x8c0e, 0x0121, 0x2000 }, + { 0x0c0e, 0x0120, 0x0000 }, + { 0x0c0e, 0x0122, 0x0000 }, + { 0x8c0e, 0x0125, 0x2000 }, + { 0x0c0e, 0x0124, 0x0000 }, + { 0x0c0e, 0x0126, 0x0000 }, + { 0x8c0e, 0x012f, 0x4000 }, + { 0x8c0e, 0x012b, 0x3000 }, + { 0x8c0e, 0x0129, 0x2000 }, + { 0x0c0e, 0x0128, 0x0000 }, + { 0x0c0e, 0x012a, 0x0000 }, + { 0x8c0e, 0x012d, 0x2000 }, + { 0x0c0e, 0x012c, 0x0000 }, + { 0x0c0e, 0x012e, 0x0000 }, + { 0x8c0e, 0x0133, 0x3000 }, + { 0x8c0e, 0x0131, 0x2000 }, + { 0x0c0e, 0x0130, 0x0000 }, + { 0x0c0e, 0x0132, 0x0000 }, + { 0x8c0e, 0x0135, 0x2000 }, + { 0x0c0e, 0x0134, 0x0000 }, + { 0x0c0e, 0x0136, 0x0000 }, + { 0x8c0e, 0x0157, 0x6000 }, + { 0x8c0e, 0x0147, 0x5000 }, + { 0x8c0e, 0x013f, 0x4000 }, + { 0x8c0e, 0x013b, 0x3000 }, + { 0x8c0e, 0x0139, 0x2000 }, + { 0x0c0e, 0x0138, 0x0000 }, + { 0x0c0e, 0x013a, 0x0000 }, + { 0x8c0e, 0x013d, 0x2000 }, + { 0x0c0e, 0x013c, 0x0000 }, + { 0x0c0e, 0x013e, 0x0000 }, + { 0x8c0e, 0x0143, 0x3000 }, + { 0x8c0e, 0x0141, 0x2000 }, + { 0x0c0e, 0x0140, 0x0000 }, + { 0x0c0e, 0x0142, 0x0000 }, + { 0x8c0e, 0x0145, 0x2000 }, + { 0x0c0e, 0x0144, 0x0000 }, + { 0x0c0e, 0x0146, 0x0000 }, + { 0x8c0e, 0x014f, 0x4000 }, + { 0x8c0e, 0x014b, 0x3000 }, + { 0x8c0e, 0x0149, 0x2000 }, + { 0x0c0e, 0x0148, 0x0000 }, + { 0x0c0e, 0x014a, 0x0000 }, + { 0x8c0e, 0x014d, 0x2000 }, + { 0x0c0e, 0x014c, 0x0000 }, + { 0x0c0e, 0x014e, 0x0000 }, + { 0x8c0e, 0x0153, 0x3000 }, + { 0x8c0e, 0x0151, 0x2000 }, + { 0x0c0e, 0x0150, 0x0000 }, + { 0x0c0e, 0x0152, 0x0000 }, + { 0x8c0e, 0x0155, 0x2000 }, + { 0x0c0e, 0x0154, 0x0000 }, + { 0x0c0e, 0x0156, 0x0000 }, + { 0x8c0e, 0x0167, 0x5000 }, + { 0x8c0e, 0x015f, 0x4000 }, + { 0x8c0e, 0x015b, 0x3000 }, + { 0x8c0e, 0x0159, 0x2000 }, + { 0x0c0e, 0x0158, 0x0000 }, + { 0x0c0e, 0x015a, 0x0000 }, + { 0x8c0e, 0x015d, 0x2000 }, + { 0x0c0e, 0x015c, 0x0000 }, + { 0x0c0e, 0x015e, 0x0000 }, + { 0x8c0e, 0x0163, 0x3000 }, + { 0x8c0e, 0x0161, 0x2000 }, + { 0x0c0e, 0x0160, 0x0000 }, + { 0x0c0e, 0x0162, 0x0000 }, + { 0x8c0e, 0x0165, 0x2000 }, + { 0x0c0e, 0x0164, 0x0000 }, + { 0x0c0e, 0x0166, 0x0000 }, + { 0x8c0e, 0x016f, 0x4000 }, + { 0x8c0e, 0x016b, 0x3000 }, + { 0x8c0e, 0x0169, 0x2000 }, + { 0x0c0e, 0x0168, 0x0000 }, + { 0x0c0e, 0x016a, 0x0000 }, + { 0x8c0e, 0x016d, 0x2000 }, + { 0x0c0e, 0x016c, 0x0000 }, + { 0x0c0e, 0x016e, 0x0000 }, + { 0x8c0e, 0x0173, 0x3000 }, + { 0x8c0e, 0x0171, 0x2000 }, + { 0x0c0e, 0x0170, 0x0000 }, + { 0x0c0e, 0x0172, 0x0000 }, + { 0x8c0e, 0x0175, 0x2000 }, + { 0x0c0e, 0x0174, 0x0000 }, + { 0x0c0e, 0x0176, 0x0000 }, + { 0x8c0e, 0x01b7, 0x7000 }, + { 0x8c0e, 0x0197, 0x6000 }, + { 0x8c0e, 0x0187, 0x5000 }, + { 0x8c0e, 0x017f, 0x4000 }, + { 0x8c0e, 0x017b, 0x3000 }, + { 0x8c0e, 0x0179, 0x2000 }, + { 0x0c0e, 0x0178, 0x0000 }, + { 0x0c0e, 0x017a, 0x0000 }, + { 0x8c0e, 0x017d, 0x2000 }, + { 0x0c0e, 0x017c, 0x0000 }, + { 0x0c0e, 0x017e, 0x0000 }, + { 0x8c0e, 0x0183, 0x3000 }, + { 0x8c0e, 0x0181, 0x2000 }, + { 0x0c0e, 0x0180, 0x0000 }, + { 0x0c0e, 0x0182, 0x0000 }, + { 0x8c0e, 0x0185, 0x2000 }, + { 0x0c0e, 0x0184, 0x0000 }, + { 0x0c0e, 0x0186, 0x0000 }, + { 0x8c0e, 0x018f, 0x4000 }, + { 0x8c0e, 0x018b, 0x3000 }, + { 0x8c0e, 0x0189, 0x2000 }, + { 0x0c0e, 0x0188, 0x0000 }, + { 0x0c0e, 0x018a, 0x0000 }, + { 0x8c0e, 0x018d, 0x2000 }, + { 0x0c0e, 0x018c, 0x0000 }, + { 0x0c0e, 0x018e, 0x0000 }, + { 0x8c0e, 0x0193, 0x3000 }, + { 0x8c0e, 0x0191, 0x2000 }, + { 0x0c0e, 0x0190, 0x0000 }, + { 0x0c0e, 0x0192, 0x0000 }, + { 0x8c0e, 0x0195, 0x2000 }, + { 0x0c0e, 0x0194, 0x0000 }, + { 0x0c0e, 0x0196, 0x0000 }, + { 0x8c0e, 0x01a7, 0x5000 }, + { 0x8c0e, 0x019f, 0x4000 }, + { 0x8c0e, 0x019b, 0x3000 }, + { 0x8c0e, 0x0199, 0x2000 }, + { 0x0c0e, 0x0198, 0x0000 }, + { 0x0c0e, 0x019a, 0x0000 }, + { 0x8c0e, 0x019d, 0x2000 }, + { 0x0c0e, 0x019c, 0x0000 }, + { 0x0c0e, 0x019e, 0x0000 }, + { 0x8c0e, 0x01a3, 0x3000 }, + { 0x8c0e, 0x01a1, 0x2000 }, + { 0x0c0e, 0x01a0, 0x0000 }, + { 0x0c0e, 0x01a2, 0x0000 }, + { 0x8c0e, 0x01a5, 0x2000 }, + { 0x0c0e, 0x01a4, 0x0000 }, + { 0x0c0e, 0x01a6, 0x0000 }, + { 0x8c0e, 0x01af, 0x4000 }, + { 0x8c0e, 0x01ab, 0x3000 }, + { 0x8c0e, 0x01a9, 0x2000 }, + { 0x0c0e, 0x01a8, 0x0000 }, + { 0x0c0e, 0x01aa, 0x0000 }, + { 0x8c0e, 0x01ad, 0x2000 }, + { 0x0c0e, 0x01ac, 0x0000 }, + { 0x0c0e, 0x01ae, 0x0000 }, + { 0x8c0e, 0x01b3, 0x3000 }, + { 0x8c0e, 0x01b1, 0x2000 }, + { 0x0c0e, 0x01b0, 0x0000 }, + { 0x0c0e, 0x01b2, 0x0000 }, + { 0x8c0e, 0x01b5, 0x2000 }, + { 0x0c0e, 0x01b4, 0x0000 }, + { 0x0c0e, 0x01b6, 0x0000 }, + { 0x8c0e, 0x01d7, 0x6000 }, + { 0x8c0e, 0x01c7, 0x5000 }, + { 0x8c0e, 0x01bf, 0x4000 }, + { 0x8c0e, 0x01bb, 0x3000 }, + { 0x8c0e, 0x01b9, 0x2000 }, + { 0x0c0e, 0x01b8, 0x0000 }, + { 0x0c0e, 0x01ba, 0x0000 }, + { 0x8c0e, 0x01bd, 0x2000 }, + { 0x0c0e, 0x01bc, 0x0000 }, + { 0x0c0e, 0x01be, 0x0000 }, + { 0x8c0e, 0x01c3, 0x3000 }, + { 0x8c0e, 0x01c1, 0x2000 }, + { 0x0c0e, 0x01c0, 0x0000 }, + { 0x0c0e, 0x01c2, 0x0000 }, + { 0x8c0e, 0x01c5, 0x2000 }, + { 0x0c0e, 0x01c4, 0x0000 }, + { 0x0c0e, 0x01c6, 0x0000 }, + { 0x8c0e, 0x01cf, 0x4000 }, + { 0x8c0e, 0x01cb, 0x3000 }, + { 0x8c0e, 0x01c9, 0x2000 }, + { 0x0c0e, 0x01c8, 0x0000 }, + { 0x0c0e, 0x01ca, 0x0000 }, + { 0x8c0e, 0x01cd, 0x2000 }, + { 0x0c0e, 0x01cc, 0x0000 }, + { 0x0c0e, 0x01ce, 0x0000 }, + { 0x8c0e, 0x01d3, 0x3000 }, + { 0x8c0e, 0x01d1, 0x2000 }, + { 0x0c0e, 0x01d0, 0x0000 }, + { 0x0c0e, 0x01d2, 0x0000 }, + { 0x8c0e, 0x01d5, 0x2000 }, + { 0x0c0e, 0x01d4, 0x0000 }, + { 0x0c0e, 0x01d6, 0x0000 }, + { 0x8c0e, 0x01e7, 0x5000 }, + { 0x8c0e, 0x01df, 0x4000 }, + { 0x8c0e, 0x01db, 0x3000 }, + { 0x8c0e, 0x01d9, 0x2000 }, + { 0x0c0e, 0x01d8, 0x0000 }, + { 0x0c0e, 0x01da, 0x0000 }, + { 0x8c0e, 0x01dd, 0x2000 }, + { 0x0c0e, 0x01dc, 0x0000 }, + { 0x0c0e, 0x01de, 0x0000 }, + { 0x8c0e, 0x01e3, 0x3000 }, + { 0x8c0e, 0x01e1, 0x2000 }, + { 0x0c0e, 0x01e0, 0x0000 }, + { 0x0c0e, 0x01e2, 0x0000 }, + { 0x8c0e, 0x01e5, 0x2000 }, + { 0x0c0e, 0x01e4, 0x0000 }, + { 0x0c0e, 0x01e6, 0x0000 }, + { 0x8c0e, 0x01ef, 0x4000 }, + { 0x8c0e, 0x01eb, 0x3000 }, + { 0x8c0e, 0x01e9, 0x2000 }, + { 0x0c0e, 0x01e8, 0x0000 }, + { 0x0c0e, 0x01ea, 0x0000 }, + { 0x8c0e, 0x01ed, 0x2000 }, + { 0x0c0e, 0x01ec, 0x0000 }, + { 0x0c0e, 0x01ee, 0x0000 }, + { 0x830f, 0xfffd, 0x2000 }, + { 0x030f, 0x0000, 0x0000 }, + { 0x0310, 0x0000, 0x1000 }, + { 0x0310, 0xfffd, 0x0000 }, +}; diff --git a/src/libs/resiprocate/contrib/pcre/ucptypetable.c b/src/libs/resiprocate/contrib/pcre/ucptypetable.c new file mode 100644 index 00000000..129529b5 --- /dev/null +++ b/src/libs/resiprocate/contrib/pcre/ucptypetable.c @@ -0,0 +1,93 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +This is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. See +the file Tech.Notes for some information on the internals. + +Written by: Philip Hazel + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* This module contains a table for translating Unicode property names into +code values for the ucp_findchar function. It is in a separate module so that +it can be included both in the main pcre library, and into pcretest (for +printing out internals). */ + +typedef struct { + const char *name; + int value; +} ucp_type_table; + +static ucp_type_table utt[] = { + { "C", 128 + ucp_C }, + { "Cc", ucp_Cc }, + { "Cf", ucp_Cf }, + { "Cn", ucp_Cn }, + { "Co", ucp_Co }, + { "Cs", ucp_Cs }, + { "L", 128 + ucp_L }, + { "Ll", ucp_Ll }, + { "Lm", ucp_Lm }, + { "Lo", ucp_Lo }, + { "Lt", ucp_Lt }, + { "Lu", ucp_Lu }, + { "M", 128 + ucp_M }, + { "Mc", ucp_Mc }, + { "Me", ucp_Me }, + { "Mn", ucp_Mn }, + { "N", 128 + ucp_N }, + { "Nd", ucp_Nd }, + { "Nl", ucp_Nl }, + { "No", ucp_No }, + { "P", 128 + ucp_P }, + { "Pc", ucp_Pc }, + { "Pd", ucp_Pd }, + { "Pe", ucp_Pe }, + { "Pf", ucp_Pf }, + { "Pi", ucp_Pi }, + { "Po", ucp_Po }, + { "Ps", ucp_Ps }, + { "S", 128 + ucp_S }, + { "Sc", ucp_Sc }, + { "Sk", ucp_Sk }, + { "Sm", ucp_Sm }, + { "So", ucp_So }, + { "Z", 128 + ucp_Z }, + { "Zl", ucp_Zl }, + { "Zp", ucp_Zp }, + { "Zs", ucp_Zs } +}; + +/* End of ucptypetable.c */ diff --git a/src/libs/resiprocate/contrib/popt/win32/include/popt.h b/src/libs/resiprocate/contrib/popt/win32/include/popt.h new file mode 100644 index 00000000..f203371d --- /dev/null +++ b/src/libs/resiprocate/contrib/popt/win32/include/popt.h @@ -0,0 +1,547 @@ +/** \file popt/popt.h + * \ingroup popt + */ + +/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#ifndef H_POPT +#define H_POPT + +#include /* for FILE * */ +#include + +#define POPT_OPTION_DEPTH 10 + +/** \ingroup popt + * \name Arg type identifiers + */ +/*@{*/ +#define POPT_ARG_NONE 0 /*!< no arg */ +#define POPT_ARG_STRING 1 /*!< arg will be saved as string */ +#define POPT_ARG_INT 2 /*!< arg will be converted to int */ +#define POPT_ARG_LONG 3 /*!< arg will be converted to long */ +#define POPT_ARG_INCLUDE_TABLE 4 /*!< arg points to table */ +#define POPT_ARG_CALLBACK 5 /*!< table-wide callback... must be + set first in table; arg points + to callback, descrip points to + callback data to pass */ +#define POPT_ARG_INTL_DOMAIN 6 /*!< set the translation domain + for this table and any + included tables; arg points + to the domain string */ +#define POPT_ARG_VAL 7 /*!< arg should take value val */ +#define POPT_ARG_FLOAT 8 /*!< arg will be converted to float */ +#define POPT_ARG_DOUBLE 9 /*!< arg will be converted to double */ + +#define POPT_ARG_MASK 0x0000FFFF +/*@}*/ + +/** \ingroup popt + * \name Arg modifiers + */ +/*@{*/ +#define POPT_ARGFLAG_ONEDASH 0x80000000 /*!< allow -longoption */ +#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /*!< don't show in help/usage */ +#define POPT_ARGFLAG_STRIP 0x20000000 /*!< strip this arg from argv(only applies to long args) */ +#define POPT_ARGFLAG_OPTIONAL 0x10000000 /*!< arg may be missing */ + +#define POPT_ARGFLAG_OR 0x08000000 /*!< arg will be or'ed */ +#define POPT_ARGFLAG_NOR 0x09000000 /*!< arg will be nor'ed */ +#define POPT_ARGFLAG_AND 0x04000000 /*!< arg will be and'ed */ +#define POPT_ARGFLAG_NAND 0x05000000 /*!< arg will be nand'ed */ +#define POPT_ARGFLAG_XOR 0x02000000 /*!< arg will be xor'ed */ +#define POPT_ARGFLAG_NOT 0x01000000 /*!< arg will be negated */ +#define POPT_ARGFLAG_LOGICALOPS \ + (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR) + +#define POPT_BIT_SET (POPT_ARG_VAL|POPT_ARGFLAG_OR) + /*!< set arg bit(s) */ +#define POPT_BIT_CLR (POPT_ARG_VAL|POPT_ARGFLAG_NAND) + /*!< clear arg bit(s) */ + +#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000 /*!< show default value in --help */ + +/*@}*/ + +/** \ingroup popt + * \name Callback modifiers + */ +/*@{*/ +#define POPT_CBFLAG_PRE 0x80000000 /*!< call the callback before parse */ +#define POPT_CBFLAG_POST 0x40000000 /*!< call the callback after parse */ +#define POPT_CBFLAG_INC_DATA 0x20000000 /*!< use data from the include line, + not the subtable */ +#define POPT_CBFLAG_SKIPOPTION 0x10000000 /*!< don't callback with option */ +#define POPT_CBFLAG_CONTINUE 0x08000000 /*!< continue callbacks with option */ +/*@}*/ + +/** \ingroup popt + * \name Error return values + */ +/*@{*/ +#define POPT_ERROR_NOARG -10 /*!< missing argument */ +#define POPT_ERROR_BADOPT -11 /*!< unknown option */ +#define POPT_ERROR_OPTSTOODEEP -13 /*!< aliases nested too deeply */ +#define POPT_ERROR_BADQUOTE -15 /*!< error in paramter quoting */ +#define POPT_ERROR_ERRNO -16 /*!< errno set, use strerror(errno) */ +#define POPT_ERROR_BADNUMBER -17 /*!< invalid numeric value */ +#define POPT_ERROR_OVERFLOW -18 /*!< number too large or too small */ +#define POPT_ERROR_BADOPERATION -19 /*!< mutually exclusive logical operations requested */ +#define POPT_ERROR_NULLARG -20 /*!< opt->arg should not be NULL */ +#define POPT_ERROR_MALLOC -21 /*!< memory allocation failed */ +/*@}*/ + +/** \ingroup popt + * \name poptBadOption() flags + */ +/*@{*/ +#define POPT_BADOPTION_NOALIAS (1 << 0) /*!< don't go into an alias */ +/*@}*/ + +/** \ingroup popt + * \name poptGetContext() flags + */ +/*@{*/ +#define POPT_CONTEXT_NO_EXEC (1 << 0) /*!< ignore exec expansions */ +#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /*!< pay attention to argv[0] */ +#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /*!< options can't follow args */ +#define POPT_CONTEXT_ARG_OPTS (1 << 4) /*!< return args as options with value 0 */ +/*@}*/ + +/** \ingroup popt + */ +struct poptOption { +/*@observer@*/ /*@null@*/ + const char * longName; /*!< may be NULL */ + char shortName; /*!< may be '\0' */ + int argInfo; +/*@shared@*/ /*@null@*/ + void * arg; /*!< depends on argInfo */ + int val; /*!< 0 means don't return, just update flag */ +/*@observer@*/ /*@null@*/ + const char * descrip; /*!< description for autohelp -- may be NULL */ +/*@observer@*/ /*@null@*/ + const char * argDescrip; /*!< argument description for autohelp */ +}; + +/** \ingroup popt + * A popt alias argument for poptAddAlias(). + */ +struct poptAlias { +/*@owned@*/ /*@null@*/ + const char * longName; /*!< may be NULL */ + char shortName; /*!< may be '\0' */ + int argc; +/*@owned@*/ + const char ** argv; /*!< must be free()able */ +}; + +/** \ingroup popt + * A popt alias or exec argument for poptAddItem(). + */ +/*@-exporttype@*/ +typedef struct poptItem_s { + struct poptOption option; /*!< alias/exec name(s) and description. */ + int argc; /*!< (alias) no. of args. */ +/*@owned@*/ + const char ** argv; /*!< (alias) args, must be free()able. */ +} * poptItem; +/*@=exporttype@*/ + +/** \ingroup popt + * \name Auto-generated help/usage + */ +/*@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Empty table marker to enable displaying popt alias/exec options. + */ +/*@-exportvar@*/ +/*@unchecked@*/ /*@observer@*/ +POPT_DLL_IMPEXP struct poptOption poptAliasOptions[]; +/*@=exportvar@*/ +#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \ + 0, "Options implemented via popt alias/exec:", NULL }, + +/** + * Auto help table options. + */ +/*@-exportvar@*/ +/*@unchecked@*/ /*@observer@*/ +POPT_DLL_IMPEXP struct poptOption poptHelpOptions[]; +/*@=exportvar@*/ +#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \ + 0, "Help options:", NULL }, + +#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL } +/*@}*/ + +/** \ingroup popt + */ +/*@-exporttype@*/ +typedef /*@abstract@*/ struct poptContext_s * poptContext; +/*@=exporttype@*/ + +/** \ingroup popt + */ +#ifndef __cplusplus +/*@-exporttype -typeuse@*/ +typedef struct poptOption * poptOption; +/*@=exporttype =typeuse@*/ +#endif + +/*@-exportconst@*/ +enum poptCallbackReason { + POPT_CALLBACK_REASON_PRE = 0, + POPT_CALLBACK_REASON_POST = 1, + POPT_CALLBACK_REASON_OPTION = 2 +}; +/*@=exportconst@*/ + +/*@-type@*/ + +/** \ingroup popt + * Table callback prototype. + * @param con context + * @param reason reason for callback + * @param opt option that triggered callback + * @param arg @todo Document. + * @param data @todo Document. + */ +typedef void (*poptCallbackType) (poptContext con, + enum poptCallbackReason reason, + /*@null@*/ const struct poptOption * opt, + /*@null@*/ const char * arg, + /*@null@*/ const void * data) + /*@*/; + +/** \ingroup popt + * Initialize popt context. + * @param name context name (usually argv[0] program name) + * @param argc no. of arguments + * @param argv argument array + * @param options address of popt option table + * @param flags or'd POPT_CONTEXT_* bits + * @return initialized popt context + */ +/*@only@*/ /*@null@*/ poptContext poptGetContext( + /*@dependent@*/ /*@keep@*/ const char * name, + int argc, /*@dependent@*/ /*@keep@*/ const char ** argv, + /*@dependent@*/ /*@keep@*/ const struct poptOption * options, + int flags) + /*@*/; + +/** \ingroup popt + * Reinitialize popt context. + * @param con context + */ +/*@unused@*/ +void poptResetContext(/*@null@*/poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Return value of next option found. + * @param con context + * @return next option val, -1 on last item, POPT_ERROR_* on error + */ +int poptGetNextOpt(/*@null@*/poptContext con) + /*@globals fileSystem, internalState @*/ + /*@modifies con, fileSystem, internalState @*/; + +/** \ingroup popt + * Return next option argument (if any). + * @param con context + * @return option argument, NULL if no argument is available + */ +/*@observer@*/ /*@null@*/ const char * poptGetOptArg(/*@null@*/poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Return next argument. + * @param con context + * @return next argument, NULL if no argument is available + */ +/*@observer@*/ /*@null@*/ const char * poptGetArg(/*@null@*/poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Peek at current argument. + * @param con context + * @return current argument, NULL if no argument is available + */ +/*@observer@*/ /*@null@*/ const char * poptPeekArg(/*@null@*/poptContext con) + /*@*/; + +/** \ingroup popt + * Return remaining arguments. + * @param con context + * @return argument array, NULL terminated + */ +/*@observer@*/ /*@null@*/ const char ** poptGetArgs(/*@null@*/poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Return the option which caused the most recent error. + * @param con context + * @param flags + * @return offending option + */ +/*@observer@*/ const char * poptBadOption(/*@null@*/poptContext con, int flags) + /*@*/; + +/** \ingroup popt + * Destroy context. + * @param con context + * @return NULL always + */ +/*@null@*/ poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Add arguments to context. + * @param con context + * @param argv argument array, NULL terminated + * @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure + */ +int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv) + /*@modifies con @*/; + +/** \ingroup popt + * Add alias to context. + * @todo Pass alias by reference, not value. + * @deprecated Use poptAddItem instead. + * @param con context + * @param alias alias to add + * @param flags (unused) + * @return 0 on success + */ +/*@unused@*/ +int poptAddAlias(poptContext con, struct poptAlias alias, int flags) + /*@modifies con @*/; + +/** \ingroup popt + * Add alias/exec item to context. + * @param con context + * @param newItem alias/exec item to add + * @param flags 0 for alias, 1 for exec + * @return 0 on success + */ +int poptAddItem(poptContext con, poptItem newItem, int flags) + /*@modifies con @*/; + +/** \ingroup popt + * Read configuration file. + * @param con context + * @param fn file name to read + * @return 0 on success, POPT_ERROR_ERRNO on failure + */ +int poptReadConfigFile(poptContext con, const char * fn) + /*@globals fileSystem, internalState @*/ + /*@modifies con->execs, con->numExecs, + fileSystem, internalState @*/; + +/** \ingroup popt + * Read default configuration from /etc/popt and $HOME/.popt. + * @param con context + * @param useEnv (unused) + * @return 0 on success, POPT_ERROR_ERRNO on failure + */ +int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) + /*@globals fileSystem, internalState @*/ + /*@modifies con->execs, con->numExecs, + fileSystem, internalState @*/; + +/** \ingroup popt + * Duplicate an argument array. + * @note: The argument array is malloc'd as a single area, so only argv must + * be free'd. + * + * @param argc no. of arguments + * @param argv argument array + * @retval argcPtr address of returned no. of arguments + * @retval argvPtr address of returned argument array + * @return 0 on success, POPT_ERROR_NOARG on failure + */ +int poptDupArgv(int argc, /*@null@*/ const char **argv, + /*@null@*/ /*@out@*/ int * argcPtr, + /*@null@*/ /*@out@*/ const char *** argvPtr) + /*@modifies *argcPtr, *argvPtr @*/; + +/** \ingroup popt + * Parse a string into an argument array. + * The parse allows ', ", and \ quoting, but ' is treated the same as " and + * both may include \ quotes. + * @note: The argument array is malloc'd as a single area, so only argv must + * be free'd. + * + * @param s string to parse + * @retval argcPtr address of returned no. of arguments + * @retval argvPtr address of returned argument array + */ +int poptParseArgvString(const char * s, + /*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr) + /*@modifies *argcPtr, *argvPtr @*/; + +/** \ingroup popt + * Parses an input configuration file and returns an string that is a + * command line. For use with popt. You must free the return value when done. + * + * Given the file: +\verbatim +# this line is ignored + # this one too +aaa + bbb + ccc +bla=bla + +this_is = fdsafdas + bad_line= + reall bad line + reall bad line = again +5555= 55555 + test = with lots of spaces +\endverbatim +* +* The result is: +\verbatim +--aaa --bbb --ccc --bla="bla" --this_is="fdsafdas" --5555="55555" --test="with lots of spaces" +\endverbatim +* +* Passing this to poptParseArgvString() yields an argv of: +\verbatim +'--aaa' +'--bbb' +'--ccc' +'--bla=bla' +'--this_is=fdsafdas' +'--5555=55555' +'--test=with lots of spaces' +\endverbatim + * + * @bug NULL is returned if file line is too long. + * @bug Silently ignores invalid lines. + * + * @param fp file handle to read + * @param *argstrp return string of options (malloc'd) + * @param flags unused + * @return 0 on success + * @see poptParseArgvString + */ +/*@-fcnuse@*/ +int poptConfigFileToString(FILE *fp, /*@out@*/ char ** argstrp, int flags) + /*@globals fileSystem @*/ + /*@modifies *fp, *argstrp, fileSystem @*/; +/*@=fcnuse@*/ + +/** \ingroup popt + * Return formatted error string for popt failure. + * @param error popt error + * @return error string + */ +/*@observer@*/ const char *const poptStrerror(const int error) + /*@*/; + +/** \ingroup popt + * Limit search for executables. + * @param con context + * @param path single path to search for executables + * @param allowAbsolute absolute paths only? + */ +void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) + /*@modifies con @*/; + +/** \ingroup popt + * Print detailed description of options. + * @param con context + * @param fp ouput file handle + * @param flags (unused) + */ +void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags) + /*@globals fileSystem @*/ + /*@modifies *fp, fileSystem @*/; + +/** \ingroup popt + * Print terse description of options. + * @param con context + * @param fp ouput file handle + * @param flags (unused) + */ +void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags) + /*@globals fileSystem @*/ + /*@modifies *fp, fileSystem @*/; + +/** \ingroup popt + * Provide text to replace default "[OPTION...]" in help/usage output. + * @param con context + * @param text replacement text + */ +/*@-fcnuse@*/ +void poptSetOtherOptionHelp(poptContext con, const char * text) + /*@modifies con @*/; +/*@=fcnuse@*/ + +/** \ingroup popt + * Return argv[0] from context. + * @param con context + * @return argv[0] + */ +/*@-fcnuse@*/ +/*@observer@*/ const char * poptGetInvocationName(poptContext con) + /*@*/; +/*@=fcnuse@*/ + +/** \ingroup popt + * Shuffle argv pointers to remove stripped args, returns new argc. + * @param con context + * @param argc no. of args + * @param argv arg vector + * @return new argc + */ +/*@-fcnuse@*/ +int poptStrippedArgv(poptContext con, int argc, char ** argv) + /*@modifies *argv @*/; +/*@=fcnuse@*/ + +/** + * Save a long, performing logical operation with value. + * @warning Alignment check may be too strict on certain platorms. + * @param arg integer pointer, aligned on int boundary. + * @param argInfo logical operation (see POPT_ARGFLAG_*) + * @param aLong value to use + * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION + */ +/*@-incondefs@*/ +/*@unused@*/ +int poptSaveLong(/*@null@*/ long * arg, int argInfo, long aLong) + /*@modifies *arg @*/ + /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; +/*@=incondefs@*/ + +/** + * Save an integer, performing logical operation with value. + * @warning Alignment check may be too strict on certain platorms. + * @param arg integer pointer, aligned on int boundary. + * @param argInfo logical operation (see POPT_ARGFLAG_*) + * @param aLong value to use + * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION + */ +/*@-incondefs@*/ +/*@unused@*/ +int poptSaveInt(/*@null@*/ int * arg, int argInfo, long aLong) + /*@modifies *arg @*/ + /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; +/*@=incondefs@*/ + +/*@=type@*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/resiprocate/contrib/popt/win32/include/poptdll.h b/src/libs/resiprocate/contrib/popt/win32/include/poptdll.h new file mode 100644 index 00000000..8b0bdf25 --- /dev/null +++ b/src/libs/resiprocate/contrib/popt/win32/include/poptdll.h @@ -0,0 +1,26 @@ +#ifndef _POPT_DLL_IMPEXP_H_ +#define _POPT_DLL_IMPEXP_H_ 1 + +#ifndef __GNUC__ +# define __DLL_IMPORT__ __declspec(dllimport) +# define __DLL_EXPORT__ __declspec(dllexport) +#else +# define __DLL_IMPORT__ __attribute__((dllimport)) extern +# define __DLL_EXPORT__ __attribute__((dllexport)) extern +#endif + +#if defined(__WIN32__) || defined(_WIN32) +# ifdef BUILD_POPT_DLL +# define POPT_DLL_IMPEXP __DLL_EXPORT__ +# elif defined(POPT_STATIC) +# define POPT_DLL_IMPEXP extern +# elif defined (USE_POPT_DLL) +# define POPT_DLL_IMPEXP __DLL_IMPORT__ +# else /* assume USE_POPT_DLL */ +# define POPT_DLL_IMPEXP __DLL_IMPORT__ +# endif +#else /* __WIN32__ */ +# define POPT_DLL_IMPEXP +#endif + +#endif /* _POPTDLLIMPEXP_H_ */ diff --git a/src/libs/resiprocate/contrib/popt/win32/lib/libpopt-bcc.lib b/src/libs/resiprocate/contrib/popt/win32/lib/libpopt-bcc.lib new file mode 100644 index 00000000..869e67ee Binary files /dev/null and b/src/libs/resiprocate/contrib/popt/win32/lib/libpopt-bcc.lib differ diff --git a/src/libs/resiprocate/contrib/popt/win32/lib/libpopt.a b/src/libs/resiprocate/contrib/popt/win32/lib/libpopt.a new file mode 100644 index 00000000..511eb4d4 Binary files /dev/null and b/src/libs/resiprocate/contrib/popt/win32/lib/libpopt.a differ diff --git a/src/libs/resiprocate/contrib/popt/win32/lib/libpopt.dll.a b/src/libs/resiprocate/contrib/popt/win32/lib/libpopt.dll.a new file mode 100644 index 00000000..ef21779b Binary files /dev/null and b/src/libs/resiprocate/contrib/popt/win32/lib/libpopt.dll.a differ diff --git a/src/libs/resiprocate/contrib/popt/win32/lib/libpopt.la b/src/libs/resiprocate/contrib/popt/win32/lib/libpopt.la new file mode 100644 index 00000000..26bfd47d --- /dev/null +++ b/src/libs/resiprocate/contrib/popt/win32/lib/libpopt.la @@ -0,0 +1,32 @@ +# libpopt.la - a libtool library file +# Generated by ltmain.sh - GNU libtool 1.4.3 (1.922.2.111 2002/10/23 02:54:36) +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='' + +# Names of this library. +library_names='' + +# The name of the static archive. +old_library='libpopt.dll.a' + +# Libraries that this one depends upon. +dependency_libs='' + +# Version information for libpopt. +current=0 +age=0 +revision=0 + +# Is this an already installed library? +installed=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='c:/progra~1/Popt/lib' diff --git a/src/libs/resiprocate/contrib/popt/win32/lib/libpopt.lib b/src/libs/resiprocate/contrib/popt/win32/lib/libpopt.lib new file mode 100644 index 00000000..afc63dc9 Binary files /dev/null and b/src/libs/resiprocate/contrib/popt/win32/lib/libpopt.lib differ diff --git a/src/libs/resiprocate/contrib/popt/win32/lib/popt1.def b/src/libs/resiprocate/contrib/popt/win32/lib/popt1.def new file mode 100644 index 00000000..d81a75be --- /dev/null +++ b/src/libs/resiprocate/contrib/popt/win32/lib/popt1.def @@ -0,0 +1,31 @@ +; h:\mingw\bin\dlltool.exe --add-indirect --export-all-symbols --output-def popt1.def DLLTMPDIR.libpopt.a/findme.o DLLTMPDIR.libpopt.a/popt.o DLLTMPDIR.libpopt.a/poptconfig.o DLLTMPDIR.libpopt.a/popthelp.o DLLTMPDIR.libpopt.a/poptparse.o popt1-rc.o +EXPORTS + findProgramPath @ 1 ; + poptAddAlias @ 2 ; + poptAddItem @ 3 ; + poptAliasOptions @ 4 DATA ; + poptBadOption @ 5 ; + poptConfigFileToString @ 6 ; + poptDupArgv @ 7 ; + poptFreeContext @ 8 ; + poptGetArg @ 9 ; + poptGetArgs @ 10 ; + poptGetContext @ 11 ; + poptGetInvocationName @ 12 ; + poptGetNextOpt @ 13 ; + poptGetOptArg @ 14 ; + poptHelpOptions @ 15 DATA ; + poptParseArgvString @ 16 ; + poptPeekArg @ 17 ; + poptPrintHelp @ 18 ; + poptPrintUsage @ 19 ; + poptReadConfigFile @ 20 ; + poptReadDefaultConfig @ 21 ; + poptResetContext @ 22 ; + poptSaveInt @ 23 ; + poptSaveLong @ 24 ; + poptSetExecPath @ 25 ; + poptSetOtherOptionHelp @ 26 ; + poptStrerror @ 27 ; + poptStrippedArgv @ 28 ; + poptStuffArgs @ 29 ; diff --git a/src/libs/resiprocate/contrib/popt/win32/libiconv-2.dll b/src/libs/resiprocate/contrib/popt/win32/libiconv-2.dll new file mode 100644 index 00000000..a2bb33f4 Binary files /dev/null and b/src/libs/resiprocate/contrib/popt/win32/libiconv-2.dll differ diff --git a/src/libs/resiprocate/contrib/popt/win32/libintl-2.dll b/src/libs/resiprocate/contrib/popt/win32/libintl-2.dll new file mode 100644 index 00000000..51786590 Binary files /dev/null and b/src/libs/resiprocate/contrib/popt/win32/libintl-2.dll differ diff --git a/src/libs/resiprocate/contrib/popt/win32/manifest/popt-1.8-1-lib.mft b/src/libs/resiprocate/contrib/popt/win32/manifest/popt-1.8-1-lib.mft new file mode 100644 index 00000000..8ad617d0 --- /dev/null +++ b/src/libs/resiprocate/contrib/popt/win32/manifest/popt-1.8-1-lib.mft @@ -0,0 +1,10 @@ +include/popt.h +include/poptdll.h +lib/libpopt-bcc.lib +lib/libpopt.a +lib/libpopt.dll.a +lib/libpopt.la +lib/libpopt.lib +lib/popt1.def +manifest/popt-1.8-1-lib.mft +manifest/popt-1.8-1-lib.ver diff --git a/src/libs/resiprocate/contrib/popt/win32/manifest/popt-1.8-1-lib.ver b/src/libs/resiprocate/contrib/popt/win32/manifest/popt-1.8-1-lib.ver new file mode 100644 index 00000000..d868e783 --- /dev/null +++ b/src/libs/resiprocate/contrib/popt/win32/manifest/popt-1.8-1-lib.ver @@ -0,0 +1,2 @@ +Popt 1.8: Developer files +Popt: parse command line options diff --git a/src/libs/resiprocate/contrib/popt/win32/popt1.dll b/src/libs/resiprocate/contrib/popt/win32/popt1.dll new file mode 100644 index 00000000..b4bd9a89 Binary files /dev/null and b/src/libs/resiprocate/contrib/popt/win32/popt1.dll differ diff --git a/src/libs/resiprocate/contrib/srtp/.cvsignore b/src/libs/resiprocate/contrib/srtp/.cvsignore new file mode 100644 index 00000000..8e7e1f44 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/.cvsignore @@ -0,0 +1,7 @@ +Debug +Makefile +Root +autom4te.cache +config.log +config.status +fixcvs.sh diff --git a/src/libs/resiprocate/contrib/srtp/CHANGES b/src/libs/resiprocate/contrib/srtp/CHANGES new file mode 100644 index 00000000..949c3893 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/CHANGES @@ -0,0 +1,223 @@ +Changelog + +1.3.20 + + Lots of changes. Thanks to Jeff Chan for catching a memory leak and + helping track down the endian issues with the SSRCs. + +1.3.8 + + This is an interim release. Several little-endian bugs were identified + and fixed; this means that we can use intel/linux for development again. + + Cleaned up sha1 and hmac code significantly, got rid of some excess + functions and properly documented the fuctions in the .h files. + + Eliminated some vestigial files. + + There is a SIGBUS error in the AES encrypt function on sparc + (observed on both solaris and openbsd) with gcc 2.95. Was unable to + find bad pointer anywhere, so I'm wondering if it isn't a compiler + problem (there's a known problem whose profile it fits). It doesn't + appear on any other platform, even in the cipher_driver stress + tests. + + Planned changes + + Change interface to nonces (xtd_seq_num_t) so that it uses + network byte ordering, and is consistent with other arguments. + + +1.3.6 + + Changed /dev/random (in configure.in and crypto/rng/rand_source.c) to + /dev/urandom; the latter is non-blocking on all known platforms (which + corrects some programs that seem to hang) and is actually present on + Open BSD (unlike /dev/random, which only works in the presence of + hardware supported random number generation). + + Added machine/types.h case in include/integers.h. + +1.3.5 + + Removing srtp_t::template and stream_clone(). + + Adding a new policy structure, which will reflect a complete SRTP + policy (including SRTCP). + + This version is *incomplete* and will undergo more changes. It is + provided only as a basis for discussion. + +1.3.4 + + Removed tmmh.c and tmmh.h, which implemented version one of TMMH. + + Changed srtp_get_trailer_length() to act on streams rather than + sessions, and documented the macro SRTP_MAX_TRAILER_LEN, which should + usually be used rather than that function. + + Removed 'salt' from cipher input. + + Changed rdbx to use err.h error codes. + + Changed malloc() and free() to xalloc() and xfree; these functions + are defined in crypto/kernel/alloc.c and declared in + include/alloc.h. + + Added 'output' functions to cipher, in addition to 'encrypt' + functions. It is no longer necessary to zeroize a buffer before + encrypting in order to get keystream. + + Changed octet_string_hex_string() so that "times two" isn't needed + in its input. + + Added crypto_kernel_init() prior to command-line parsing, so that + kernel can be passed command-line arguments, such as "-d + debug_module". This was done to for the applications + test/srtp-driver, test/kernel-driver, and test/ust-driver. + + Improved srtp_init_aes_128_prf - wrote key derivation function + (srtp_kdf_t). + + Add the tag_len as an argument to the auth_compute() function, but + not the corresponding macro. This change allows the tag length for + a given auth func to be set to different values at initialization + time. Previously, the structure auth_t contained the + output_length, but that value was inaccessible from hmac_compute() + and other functions. + + Re-named files from a-b.c to a_b.c. in order to help portability. + + Re-named rijndael to aes (or aes_128 as appropriate). + + +1.2.1 + + Changes so that 1.2.0 compiles on cygwin-win2k. + + Added better error reporting system. If syslog is present on the + OS, then it is used. + + +1.2.0 Many improvements and additions, and a fex fixes + + Fixed endian issues in RTP header construction in the function + rtp_sendto() in srtp/rtp.c. + + Implemented RIJNDAEL decryption operation, adding the functions + rijndael_decrypt() and rijndael_expand_decryption_key(). Also + re-named rijndael_expand_key() to rijndael_expand_encryption_key() + for consistency. + + Implemented random number source using /dev/random, in the files + crypto/rng/rand_source.c and include/rand_source.h. + + Added index check to SEAL cipher (only values less than 2^32 are + allowed) + + Added test case for null_auth authentication function. + + Added a timing test which tests the effect of CPU cache thrash on + cipher throughput. The test is done by the function + cipher_test_throughput_array(); the function + cipher_array_alloc_init() creates an array of ciphers for use in + this test. This test can be accessed by using the -a flag to + the application cipher-driver in the test subdirectory. + + Added argument processing to ust-driver.c, and added that app to + the 'runtest' target in Makefile.in. + + A minor auth_t API change: last argument of auth_init() eliminated. + + +1.0.6 A small but important fix + + Fixed srtp_init_aes_128_prf() by adding octet_string_set_to_zero() + after buffer allocation. + + Eliminated references to no-longer-existing variables in debugging + code in srtp/srtp.c. This fixes the compilation failure that + occured when using PRINT_DEBUG in that file. + + Corrected spelling of Richard Priestley's name in credits. Sorry + Richard! + + +1.0.5 Many little fixes + + Fixed octet_string_set_to_zero(), which was writing one + more zero octet than it should. This bug caused srtp_protect() + and srtp_unprotect() to overwrite the byte that followed the + srtp packet. + + Changed sizeof(uint32_t) to srtp_get_trailer_length() in + srtp-driver.c. This is just defensive coding. + + Added NULL check to malloc in srtp_alloc(). + + +1.0.4 Many minor fixes and two big ones (thanks for the bug reports!) + + Removed 'ssrc' from the srtp_init_aes_128_prf() function argument + list. This is so that applications which do not a priori know the + ssrc which they will be receiving can still use libsrtp. Now the + SSRC value is gleaned from the rtp header and exored into the + counter mode offset in the srtp_protect() and srtp_unprotect() + functions, if that cipher is used. This change cascaed through + many other functions, including srtp_init_from_hex(), + srtp_sender_init() and srtp_receiver_init() in rtp.c, and also + changing the CLI to test/rtpw. In the future, another function + call will be added to the library that enables multiple ssrc/key + pairs to be installed into the same srtp session, so that libsrtp + works with multiple srtp senders. For now, this functionality is + lacking. + + Removed the GDOI interface to the rtpw demo program. This will be + added again at a later date, after the SRTP and GDOI distributions + stabilize. For now, I've left in the GDOI #defines and autoconf + definitions so that they'll be in place when needed. + + Updated tmmhv2_compute() so that it didn't assume any particular + alginment of the output tag. + + Changed bit field variables in srtp.h to unsigned char from + unsigned int in order to avoid a potential endianness issue. + + Fixed rdbx_estimate_index() to handle all input cases. This solves + the now notorious "abaft" bug in the rtpw demo app on linux/intel, + in which spurious replay protection failures happen after that word + is received. + + Added ntohs(hdr->seq) to srtp_protect and srtp_unprotect, removed + from rijndael_icm_set_segment(). + + Added error checking and handling to srtp_sender_init() and + srtp_receiver_init(). + + Changed srtp_alloc() so that it does what you'd expect: allocate an + srtp_ctx_t structure. This hides the library internals. + + +1.0.1 Many minor fixes + + Added cipher_driver_buffer_test(...) to test/cipher-driver.c. This + function checks that the byte-buffering functions used by a cipher + are correct. + + Fixed SunOS/Solaris build problems: added HAVE_SYS_INT_TYPES_H and + changed index_t to xtd_seq_num_t (see include/rdbx.h). + + Fixed SEAL3.0 output byte buffering, added byte-buffering test to + cipher/cipher-driver.c. + + Fixed roc-driver so that the non-sequential insertion test + automatically recovers from bad estimates. This was required to + prevent spurious failures. + + Made rdbx_estimate_index(...) function smarter, so that initial RTP + sequence numbers greater than 32,768 don't cause it to estimate the + rollover counter of 0xffffffff. + + +1.0.0 Initial release + diff --git a/src/libs/resiprocate/contrib/srtp/LICENSE b/src/libs/resiprocate/contrib/srtp/LICENSE new file mode 100644 index 00000000..dd43240c --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/LICENSE @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ diff --git a/src/libs/resiprocate/contrib/srtp/Makefile.in b/src/libs/resiprocate/contrib/srtp/Makefile.in new file mode 100644 index 00000000..97f5cb82 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/Makefile.in @@ -0,0 +1,232 @@ +# Makefile for secure rtp +# +# David A. McGrew +# Cisco Systems, Inc. + +# targets: +# +# runtest runs test applications +# test builds test applications +# libcrypt.a static library implementing crypto engine +# libsrtp.a static library implementing srtp +# clean removes objects, libs, and executables +# distribution cleans and builds a .tgz +# tags builds etags file from all .c and .h files + +.PHONY: all test build_table_apps + +all: test + +runtest: build_table_apps test + @echo "running libsrtp test applications..." + crypto/test/cipher_driver$(EXE) -v >/dev/null + crypto/test/kernel_driver$(EXE) -v >/dev/null + test/rdbx_driver$(EXE) -v >/dev/null + test/srtp_driver$(EXE) -v >/dev/null + test/roc_driver$(EXE) -v >/dev/null + test/replay_driver$(EXE) -v >/dev/null + test/dtls_srtp_driver$(EXE) >/dev/null + cd test; ./rtpw_test.sh >/dev/null + @echo "libsrtp test applications passed." + $(MAKE) -C crypto runtest + +# makefile variables + +CC = @CC@ +INCDIR = -Icrypto/include -I$(srcdir)/include -I$(srcdir)/crypto/include +DEFS = @DEFS@ +CPPFLAGS= @CPPFLAGS@ +CFLAGS = @CFLAGS@ +LIBS = @LIBS@ +LDFLAGS = @LDFLAGS@ -L. +COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS) +SRTPLIB = -lsrtp + +RANLIB = @RANLIB@ +INSTALL = @INSTALL@ + +# EXE defines the suffix on executables - it's .exe for Windows, and +# null on linux, bsd, and OS X and other OSes. +EXE = @EXE@ +# gdoi is the group domain of interpretation for isakmp, a group key +# management system which can provide keys for srtp +gdoi = @GDOI_OBJS@ +# Random source. +RNG_OBJS = @RNG_OBJS@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +includedir = @includedir@ +libdir = @libdir@ + + +# implicit rules for object files and test apps + +%.o: %.c + $(COMPILE) -c $< -o $@ + +%$(EXE): %.c + $(COMPILE) $(LDFLAGS) $< -o $@ $(SRTPLIB) $(LIBS) + + +# libcrypt.a (the crypto engine) +ciphers = crypto/cipher/cipher.o crypto/cipher/null_cipher.o \ + crypto/cipher/aes.o crypto/cipher/aes_icm.o \ + crypto/cipher/aes_cbc.o + +hashes = crypto/hash/null_auth.o crypto/hash/sha1.o \ + crypto/hash/hmac.o crypto/hash/auth.o # crypto/hash/tmmhv2.o + +replay = crypto/replay/rdb.o crypto/replay/rdbx.o \ + crypto/replay/ut_sim.o + +math = crypto/math/datatypes.o crypto/math/stat.o + +ust = crypto/ust/ust.o + +rng = crypto/rng/$(RNG_OBJS) crypto/rng/prng.o crypto/rng/ctr_prng.o + +err = crypto/kernel/err.o + +kernel = crypto/kernel/crypto_kernel.o crypto/kernel/alloc.o \ + crypto/kernel/key.o $(rng) $(err) # $(ust) + +cryptobj = $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(replay) + +# libsrtp.a (implements srtp processing) + +srtpobj = srtp/srtp.o + +libsrtp.a: $(srtpobj) $(cryptobj) $(gdoi) + ar cr libsrtp.a $^ + $(RANLIB) libsrtp.a + +# libcryptomath.a contains general-purpose routines that are used to +# generate tables and verify cryptoalgorithm implementations - this +# library is not meant to be included in production code + +cryptomath = crypto/math/math.o crypto/math/gf2_8.o + +libcryptomath.a: $(cryptomath) + ar cr libcryptomath.a $(cryptomath) + $(RANLIB) libcryptomath.a + + +# test applications + +crypto_testapp = crypto/test/aes_calc$(EXE) crypto/test/cipher_driver$(EXE) \ + crypto/test/datatypes_driver$(EXE) crypto/test/kernel_driver$(EXE) \ + crypto/test/rand_gen$(EXE) crypto/test/sha1_driver$(EXE) \ + crypto/test/stat_driver$(EXE) + +testapp = $(crypto_testapp) test/srtp_driver$(EXE) test/replay_driver$(EXE) \ + test/roc_driver$(EXE) test/rdbx_driver$(EXE) test/rtpw$(EXE) \ + test/dtls_srtp_driver$(EXE) + +$(testapp): libsrtp.a + +test/rtpw$(EXE): test/rtpw.c test/rtp.c test/getopt_s.c + $(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB) + +test/srtp_driver$(EXE): test/srtp_driver.c test/getopt_s.c + $(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB) + +test/rdbx_driver$(EXE): test/rdbx_driver.c test/getopt_s.c + $(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB) + +test/dtls_srtp_driver$(EXE): test/dtls_srtp_driver.c test/getopt_s.c + $(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB) + +test: $(testapp) + @echo "Build done. Please run '$(MAKE) runtest' to run self tests." + +memtest: test/srtp_driver + @test/srtp_driver -v -d "alloc" > tmp + @grep freed tmp | wc -l > freed + @grep allocated tmp | wc -l > allocated + @echo "checking for memory leaks (only works with --enable-stdout)" + cmp -s allocated freed + @echo "passed (same number of alloc() and dealloc() calls found)" + @rm freed allocated tmp + +# tables_apps are used to generate the tables used in the crypto +# implementations; these need only be generated during porting, not +# for building libsrtp or the test applications + +table_apps = tables/aes_tables + +build_table_apps: $(table_apps) + +# in the tables/ subdirectory, we use libcryptomath instead of libsrtp + +tables/%: tables/%.c libcryptomath.a + $(COMPILE) $(LDFLAGS) $< -o $@ $(LIBS) libcryptomath.a + +# the target 'plot' runs the timing test (test/srtp_driver -t) then +# uses gnuplot to produce plots of the results - see the script file +# 'timing' + +plot: test/srtp_driver + test/srtp_driver -t > timing.dat + + +# bookkeeping: tags, clean, and distribution + +tags: + etags */*.[ch] */*/*.[ch] + + +# documentation - the target libsrtpdoc builds a PDF file documenting +# libsrtp + +libsrtpdoc: + $(MAKE) -C doc + +.PHONY: clean superclean install + +install: + @if [ -d $(DESTDIR)$(includedir)/srtp ]; then \ + echo "you should run 'make uninstall' first"; exit 1; \ + fi + $(INSTALL) -d $(DESTDIR)$(includedir)/srtp + $(INSTALL) -d $(DESTDIR)$(libdir) + cp include/*.h $(DESTDIR)$(includedir)/srtp + cp crypto/include/*.h $(DESTDIR)$(includedir)/srtp + if [ -f libsrtp.a ]; then cp libsrtp.a $(DESTDIR)$(libdir)/; fi + +uninstall: + rm -rf $(DESTDIR)$(includedir)/srtp + rm -rf $(DESTDIR)$(libdir)/libsrtp.a + +clean: + rm -rf $(cryptobj) $(srtpobj) $(cryptomath) TAGS \ + libcryptomath.a libsrtp.a core *.core test/core + for a in * */* */*/*; do \ + if [ -f "$$a~" ] ; then rm -f $$a~; fi; \ + done; + for a in $(testapp) $(table_apps); do rm -rf $$a$(EXE); done + rm -rf *.pict *.jpg *.dat + rm -rf freed allocated tmp + $(MAKE) -C doc clean + $(MAKE) -C crypto clean + + +superclean: clean + rm -rf crypto/include/config.h config.log config.cache config.status \ + Makefile .gdb_history test/.gdb_history .DS_Store + rm -rf autom4te.cache + +distname = srtp-$(shell cat VERSION) + +distribution: runtest superclean + if ! [ -f VERSION ]; then exit 1; fi + if [ -f ../$(distname).tgz ]; then \ + mv ../$(distname).tgz ../$(distname).tgz.bak; \ + fi + cd ..; tar cvzf $(distname).tgz srtp + +# EOF diff --git a/src/libs/resiprocate/contrib/srtp/README b/src/libs/resiprocate/contrib/srtp/README new file mode 100644 index 00000000..02dc1f8e --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/README @@ -0,0 +1,172 @@ +Secure RTP (SRTP) and UST Reference Implementations +David A. McGrew +Cisco Systems, Inc. +mcgrew@cisco.com + + +This package provides an implementation of the Secure Real-time +Transport Protocol (SRTP), the Universal Security Transform (UST), and +a supporting cryptographic kernel. These mechanisms are documented in +the Internet Drafts in the doc/ subdirectory. The SRTP API is +documented in include/srtp.h, and the library is in libsrtp.a (after +compilation). + + +Installation: + +./configure [ options ] # GNU autoconf script +make # or gmake if needed; use GNU make + +The configure script accepts the following options: + + --help provides a usage summary + --disable-debug compile without the runtime debugging system + --enable-syslog use syslog for error reporting + --disable-stdout use stdout for error reporting + --enable-console use /dev/console for error reporting + --gdoi use GDOI key management (disabled at present) + +By default, debbuging is enabled and stdout is used for debugging. +You can use the above configure options to have the debugging output +sent to syslog or the system console. Alternatively, you can define +ERR_REPORTING_FILE in include/conf.h to be any other file that can be +opened by libSRTP, and debug messages will be sent to it. + +This package has been tested on Mac OS X (powerpc-apple-darwin1.4), +Cygwin (i686-pc-cygwin), and Sparc (sparc-sun-solaris2.6). Previous +versions have been tested on Linux and OpenBSD on both x86 and sparc +platforms. + +A quick tour of this package: + +Makefile targets: all, clean, ... +README this file +CHANGES change log +VERSION version number of this package +LICENSE legal details (it's a BSD-like license) +crypto/ciphers/ ciphers (null, aes_icm, ...) +crypto/math/ crypto math routines +crypto/hash/ crypto hashing (hmac, tmmhv2, ...) +crypto/replay/ replay protection +doc/ documentation: rfcs, apis, and suchlike +include/ include files for all code in distribution +srtp/ secure real-time transport protocol implementation +tables/ apps for generating tables (useful in porting) +test/ test drivers + + +Applications + + Several test drivers and a simple and portable srtp application + are included in the test/ subdirectory. + + test driver function tested + ------------------------------------------------------------- + kernel_driver crypto kernel (ciphers, auth funcs, rng) + srtp_driver srtp in-memory tests (does not use the network) + rdbx_driver rdbx (extended replay database) + roc_driver extended sequence number functions + replay_driver replay database (n.b. not used in libsrtp) + cipher_driver ciphers + auth_driver hash functions + + The app rtpw is a simple rtp application which reads words from + /usr/dict/words and then sends them out one at a time using [s]rtp. + Manual srtp keying uses the -k option; automated key management + using gdoi will be added later. + +usage: rtpw [-d ]* [-k [-a][-e]] [-s | -r] dest_ip dest_port +or rtpw -l + + Either the -s (sender) or -r (receiver) option must be chosen. + + The values dest_ip, dest_port are the ip address and udp port to + which the dictionary will be sent, respectively. + + options: + + -s (s)rtp sender - causes app to send words + + -r (s)rtp receive - causes app to receve words + + -k use srtp master key , where the + key is a hexadecimal value (without the + leading "0x") + + -e encrypt/decrypt (for data confidentiality) + (requires use of -k option as well) + + -a message authentication + (requires use of -k option as well) + + -l list debug modules + + -d turn on debugging for module + + +In order to get random 30-byte values for use as key/salt pairs , you +can use the following bash function to format the output of +/dev/random (where that device is available). + +function randhex() { + cat /dev/random | od --read-bytes=32 --width=32 -x | awk '{ print $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 }' +} + + +An example of an SRTP session using two rtpw programs follows: + +set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451 + +[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999 +Security services: confidentiality message authentication +set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451 +setting SSRC to 2078917053 +sending word: A +sending word: a +sending word: aa +sending word: aal +... + +[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999 +security services: confidentiality message authentication +set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451 +19 octets received from SSRC 2078917053 word: A +19 octets received from SSRC 2078917053 word: a +20 octets received from SSRC 2078917053 word: aa +21 octets received from SSRC 2078917053 word: aal +... + +Implementation Notes + + * The srtp_protect() function assumes that the buffer holding the + rtp packet has enough storage allocated that the authentication + tag can be written to the end of that packet. If this assumption + is not valid, memory corruption will ensue. + + * Automated tests for the crypto functions are provided through + the cipher_type_self_test() and auth_type_self_test() functions. + These functions should be used to test each port of this code + to a new platform. + + * Replay protection is contained in the crypto engine, and + tests for it are provided. + + * This implementation provides calls to initialize, protect, and + unprotect RTP packets, and makes as few as possible assumptions + about how these functions will be called. For example, the + caller is not expected to provide packets in order (though if + they're called more than 65k out of sequence, synchronization + will be lost). + + * The sequence number in the rtp packet is used as the low 16 bits + of the sender's local packet index. Note that RTP will start its + sequence number in a random place, and the SRTP layer just jumps + forward to that number at its first invocation. An earlier + version of this library used initial sequence numbers that are + less than 32,768; this trick is no longer required as the + rdbx_estimate_index(...) function has been made smarter. + + * The replay window is 128 bits in length, and is hard-coded to this + value for now. + + diff --git a/src/libs/resiprocate/contrib/srtp/TODO b/src/libs/resiprocate/contrib/srtp/TODO new file mode 100644 index 00000000..18846e8a --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/TODO @@ -0,0 +1,66 @@ +TODO List + +1.4.1 + + - document which fields are in NBO/HBO, and check for consistency. + + - move HAVE_U_LONG_LONG inside of datatypes.c, or some other + separate file + + - re-write configure.in to make cross-compilation easier + + - eliminate GENERIC_AESICM by generalizing the code a bit + +Older comments + + - add tests for key_limit_t datatype + + - move octet_get_weight() from datatypes.c to math.c (any other + funcs?) + +Changes and additions planned + + Make cipher and auth dealloc() functions zeroize the key-storage + areas before calling free(). + + Eliminate key_len from auth_init() + + Doucument internal APIs (cipher, auth, srtp_protect, ...) + + +SRTP options not (yet) included in this libaray: + + - the aes-f8-mode cipher + - the Master Key Index + - re-keying using the key derivation function (only the initial + use of the PRF has been implemented, as it's sufficient + for most uses) + + +(OLD) PLANNED CHANGES + + strip out test/lfsr.c + + Write new documentation!!! + + Fix the x86 assembly code in aes.c. + + Eliminate /* DAM */ - there's one in srtp.c + + Change debugging so that it can print more than one line. Or perhaps + just change it so that a single check of the debug-enabled flag is + needed. + + Improve interface between cipher and rdbx - perhaps generalize rdbx + into 'nonce' datatype. + + Make rijndael_icm accept variable sized keys. + + Add rdbx functions that allow different-sized explicit sequence + numbers to be used. + + Write uniform byte-buffering code for PRFs, preferably as macros. + + Consider eliminating low-level alloc functions in favor of len() + functions, so that there need not be multiple allocations within a + particular alloc() function. diff --git a/src/libs/resiprocate/contrib/srtp/VERSION b/src/libs/resiprocate/contrib/srtp/VERSION new file mode 100644 index 00000000..428b770e --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/VERSION @@ -0,0 +1 @@ +1.4.3 diff --git a/src/libs/resiprocate/contrib/srtp/config.guess b/src/libs/resiprocate/contrib/srtp/config.guess new file mode 100644 index 00000000..7d0185e0 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/config.guess @@ -0,0 +1,1447 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + +timestamp='2004-09-07' + +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amd64:OpenBSD:*:*) + echo x86_64-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + cats:OpenBSD:*:*) + echo arm-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + luna88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips64-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit 0 ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit 0 ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit 0 ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + *86) UNAME_PROCESSOR=i686 ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms && exit 0 ;; + I*) echo ia64-dec-vms && exit 0 ;; + V*) echo vax-dec-vms && exit 0 ;; + esac +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/libs/resiprocate/contrib/srtp/config.h_win32vc7 b/src/libs/resiprocate/contrib/srtp/config.h_win32vc7 new file mode 100644 index 00000000..b6ae0a79 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/config.h_win32vc7 @@ -0,0 +1,170 @@ +/* Hacked config.h for Windows XP 32-bit & VC7 */ + +/* Define if building for a CISC machine (e.g. Intel). */ +#define CPU_CISC 1 + +/* Define if building for a RISC machine (assume slow byte access). */ +#undef CPU_RISC + +/* Path to random device */ +#undef DEV_URANDOM + +/* Define to compile in dynamic debugging system. */ +#undef ENABLE_DEBUGGING + +/* Report errors to this file. */ +#undef ERR_REPORTING_FILE + +/* Define to use logging to stdout. */ +#undef ERR_REPORTING_STDOUT + +/* Define this to use ISMAcryp code. */ +#undef GENERIC_AESICM + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_BYTESWAP_H + +/* Define to 1 if you have the `inet_aton' function. */ +#define HAVE_INET_ATON 1 + +/* Define to 1 if the system has the type `int16_t'. */ +#undef HAVE_INT16_T + +/* Define to 1 if the system has the type `int32_t'. */ +#undef HAVE_INT32_T + +/* Define to 1 if the system has the type `int8_t'. */ +#undef HAVE_INT8_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_MACHINE_TYPES_H + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_INT_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UIO_H + +/* Define to 1 if the system has the type `uint16_t'. */ +#undef HAVE_UINT16_T + +/* Define to 1 if the system has the type `uint32_t'. */ +#undef HAVE_UINT32_T + +/* Define to 1 if the system has the type `uint64_t'. */ +#undef HAVE_UINT64_T + +/* Define to 1 if the system has the type `uint8_t'. */ +#undef HAVE_UINT8_T + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `usleep' function. */ +#define HAVE_USLEEP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_WINDOWS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_WINSOCK2_H 1 + +/* Define to use X86 inlined assembly code */ +#undef HAVE_X86 + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of a `unsigned long', as computed by sizeof. */ +#define SIZEOF_UNSIGNED_LONG 4 + +/* The size of a `unsigned long long', as computed by sizeof. */ +#define SIZEOF_UNSIGNED_LONG_LONG 8 + +/* Define to use GDOI. */ +#undef SRTP_GDOI + +/* Define to compile for kernel contexts. */ +#undef SRTP_KERNEL + +/* Define to compile for Linux kernel context. */ +#undef SRTP_KERNEL_LINUX + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Write errors to this file */ +#undef USE_ERR_REPORTING_FILE + +/* Define to use syslog logging. */ +#undef USE_SYSLOG + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define to empty if `const' does not conform to ANSI C. */ +//#undef const +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +//#ifndef __cplusplus +//#undef inline +//#endif +#define inline __inline + +/* Define to `unsigned' if does not define. */ +//#undef size_t diff --git a/src/libs/resiprocate/contrib/srtp/config.hw b/src/libs/resiprocate/contrib/srtp/config.hw new file mode 100644 index 00000000..b895318e --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/config.hw @@ -0,0 +1,192 @@ +/* crypto/include/config.h. Generated by configure. */ +/* config_in.h. Generated from configure.in by autoheader. */ + +/* Define if building for a CISC machine (e.g. Intel). */ +#define CPU_CISC 1 + +/* Define if building for a RISC machine (assume slow byte access). */ +/* #undef CPU_RISC */ + +/* Path to random device */ +/* #define DEV_URANDOM "/dev/urandom" */ + +/* Define to compile in dynamic debugging system. */ +#define ENABLE_DEBUGGING 1 + +/* Report errors to this file. */ +/* #undef ERR_REPORTING_FILE */ + +/* Define to use logging to stdout. */ +#define ERR_REPORTING_STDOUT 1 + +/* Define this to use ISMAcryp code. */ +/* #undef GENERIC_AESICM */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ARPA_INET_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BYTESWAP_H */ + +/* Define to 1 if you have the `inet_aton' function. */ +/* #undef HAVE_INET_ATON */ + +/* Define to 1 if the system has the type `int16_t'. */ +#define HAVE_INT16_T 1 + +/* Define to 1 if the system has the type `int32_t'. */ +#define HAVE_INT32_T 1 + +/* Define to 1 if the system has the type `int8_t'. */ +#define HAVE_INT8_T 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTTYPES_H */ + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MACHINE_TYPES_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NETINET_IN_H */ + +/* Define to 1 if you have the `socket' function. */ +/* #undef HAVE_SOCKET */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDINT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYSLOG_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_INT_TYPES_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SOCKET_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_UIO_H */ + +/* Define to 1 if the system has the type `uint16_t'. */ +#define HAVE_UINT16_T 1 + +/* Define to 1 if the system has the type `uint32_t'. */ +#define HAVE_UINT32_T 1 + +/* Define to 1 if the system has the type `uint64_t'. */ +#define HAVE_UINT64_T 1 + +/* Define to 1 if the system has the type `uint8_t'. */ +#define HAVE_UINT8_T 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UNISTD_H */ + +/* Define to 1 if you have the `usleep' function. */ +/* #undef HAVE_USLEEP */ + +/* Define to 1 if you have the header file. */ +#define HAVE_WINDOWS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_WINSOCK2_H 1 + +/* Define to use X86 inlined assembly code */ +/* #undef HAVE_X86 */ + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* The size of a `unsigned long', as computed by sizeof. */ +#define SIZEOF_UNSIGNED_LONG 4 + +/* The size of a `unsigned long long', as computed by sizeof. */ +#define SIZEOF_UNSIGNED_LONG_LONG 8 + +/* Define to use GDOI. */ +/* #undef SRTP_GDOI */ + +/* Define to compile for kernel contexts. */ +/* #undef SRTP_KERNEL */ + +/* Define to compile for Linux kernel context. */ +/* #undef SRTP_KERNEL_LINUX */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Write errors to this file */ +/* #undef USE_ERR_REPORTING_FILE */ + +/* Define to use syslog logging. */ +/* #undef USE_SYSLOG */ + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define 'inline' to nothing, since the MSVC compiler doesn't support it. */ +#define inline + +/* Define to `unsigned' if does not define. */ +/* #undef size_t */ + +#if (_MSC_VER >= 1400) // VC8+ +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE +#endif +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE +#endif +#endif // VC8+ + +#ifndef uint32_t +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +typedef signed __int8 int8_t; +typedef signed __int16 int16_t; +typedef signed __int32 int32_t; +typedef signed __int64 int64_t; +#endif + +#ifdef _MSC_VER +#pragma warning(disable:4311) +#endif diff --git a/src/libs/resiprocate/contrib/srtp/config.sub b/src/libs/resiprocate/contrib/srtp/config.sub new file mode 100644 index 00000000..edb6b663 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/config.sub @@ -0,0 +1,1555 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + +timestamp='2004-08-29' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | msp430-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/libs/resiprocate/contrib/srtp/config_in.h b/src/libs/resiprocate/contrib/srtp/config_in.h new file mode 100644 index 00000000..5951861e --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/config_in.h @@ -0,0 +1,170 @@ +/* config_in.h. Generated from configure.in by autoheader. */ + +/* Define if building for a CISC machine (e.g. Intel). */ +#undef CPU_CISC + +/* Define if building for a RISC machine (assume slow byte access). */ +#undef CPU_RISC + +/* Path to random device */ +#undef DEV_URANDOM + +/* Define to compile in dynamic debugging system. */ +#undef ENABLE_DEBUGGING + +/* Report errors to this file. */ +#undef ERR_REPORTING_FILE + +/* Define to use logging to stdout. */ +#undef ERR_REPORTING_STDOUT + +/* Define this to use ISMAcryp code. */ +#undef GENERIC_AESICM + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_BYTESWAP_H + +/* Define to 1 if you have the `inet_aton' function. */ +#undef HAVE_INET_ATON + +/* Define to 1 if the system has the type `int16_t'. */ +#undef HAVE_INT16_T + +/* Define to 1 if the system has the type `int32_t'. */ +#undef HAVE_INT32_T + +/* Define to 1 if the system has the type `int8_t'. */ +#undef HAVE_INT8_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_MACHINE_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_INT_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UIO_H + +/* Define to 1 if the system has the type `uint16_t'. */ +#undef HAVE_UINT16_T + +/* Define to 1 if the system has the type `uint32_t'. */ +#undef HAVE_UINT32_T + +/* Define to 1 if the system has the type `uint64_t'. */ +#undef HAVE_UINT64_T + +/* Define to 1 if the system has the type `uint8_t'. */ +#undef HAVE_UINT8_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `usleep' function. */ +#undef HAVE_USLEEP + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINDOWS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINSOCK2_H + +/* Define to use X86 inlined assembly code */ +#undef HAVE_X86 + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of a `unsigned long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG + +/* The size of a `unsigned long long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG_LONG + +/* Define to use GDOI. */ +#undef SRTP_GDOI + +/* Define to compile for kernel contexts. */ +#undef SRTP_KERNEL + +/* Define to compile for Linux kernel context. */ +#undef SRTP_KERNEL_LINUX + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Write errors to this file */ +#undef USE_ERR_REPORTING_FILE + +/* Define to use syslog logging. */ +#undef USE_SYSLOG + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `unsigned' if does not define. */ +#undef size_t diff --git a/src/libs/resiprocate/contrib/srtp/configure b/src/libs/resiprocate/contrib/srtp/configure new file mode 100644 index 00000000..b959b113 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/configure @@ -0,0 +1,8603 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59. +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="srtp" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS RANLIB ac_ct_RANLIB CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RNG_OBJS CPP EGREP build build_cpu build_vendor build_os host host_cpu host_vendor host_os EXE GDOI_OBJS LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-kernel-linux build library to run in Linux kernel context + --disable-debug do not compile in dynamic debugging system + --enable-generic-aesicm compile in changes for ISMAcryp + --enable-syslog use syslog for error reporting + --disable-stdout don't use stdout for error reporting + --enable-console use /dev/console for error reporting + --enable-gdoi enable GDOI key management + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + +if test -z "$CFLAGS"; then + CFLAGS="-Wall -O4 -fexpensive-optimizations -funroll-loops" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + + +# Check whether --enable-kernel-linux or --disable-kernel-linux was given. +if test "${enable_kernel_linux+set}" = set; then + enableval="$enable_kernel_linux" + +else + enable_kernel_linux=no +fi; +echo "$as_me:$LINENO: checking whether to build for Linux kernel context" >&5 +echo $ECHO_N "checking whether to build for Linux kernel context... $ECHO_C" >&6 +if test "$enable_kernel_linux" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define SRTP_KERNEL 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define SRTP_KERNEL_LINUX 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: $enable_kernel_linux" >&5 +echo "${ECHO_T}$enable_kernel_linux" >&6 + +if test "$cross_compiling" != yes; then + echo "$as_me:$LINENO: checking for /dev/urandom" >&5 +echo $ECHO_N "checking for /dev/urandom... $ECHO_C" >&6 +if test "${ac_cv_file__dev_urandom+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + test "$cross_compiling" = yes && + { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 +echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} + { (exit 1); exit 1; }; } +if test -r "/dev/urandom"; then + ac_cv_file__dev_urandom=yes +else + ac_cv_file__dev_urandom=no +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_file__dev_urandom" >&5 +echo "${ECHO_T}$ac_cv_file__dev_urandom" >&6 +if test $ac_cv_file__dev_urandom = yes; then + DEV_URANDOM=/dev/urandom +else + echo "$as_me:$LINENO: checking for /dev/random" >&5 +echo $ECHO_N "checking for /dev/random... $ECHO_C" >&6 +if test "${ac_cv_file__dev_random+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + test "$cross_compiling" = yes && + { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 +echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} + { (exit 1); exit 1; }; } +if test -r "/dev/random"; then + ac_cv_file__dev_random=yes +else + ac_cv_file__dev_random=no +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_file__dev_random" >&5 +echo "${ECHO_T}$ac_cv_file__dev_random" >&6 +if test $ac_cv_file__dev_random = yes; then + DEV_URANDOM=/dev/random +fi + +fi + +fi + +echo "$as_me:$LINENO: checking which random device to use" >&5 +echo $ECHO_N "checking which random device to use... $ECHO_C" >&6 +if test "$enable_kernel_linux" = "yes"; then + RNG_OBJS=rand_linux_kernel.o + echo "$as_me:$LINENO: result: Linux kernel builtin" >&5 +echo "${ECHO_T}Linux kernel builtin" >&6 +else + RNG_OBJS=rand_source.o + if test -n "$DEV_URANDOM"; then + +cat >>confdefs.h <<_ACEOF +#define DEV_URANDOM "$DEV_URANDOM" +_ACEOF + + echo "$as_me:$LINENO: result: $DEV_URANDOM" >&5 +echo "${ECHO_T}$DEV_URANDOM" >&6 + else + echo "$as_me:$LINENO: result: standard rand() function..." >&5 +echo "${ECHO_T}standard rand() function..." >&6 + fi +fi + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in stdlib.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in byteswap.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in stdint.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/uio.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in inttypes.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/types.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in machine/types.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/int_types.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + +for ac_header in sys/socket.h netinet/in.h arpa/inet.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in windows.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +for ac_header in winsock2.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +fi + +done + + + +for ac_header in syslog.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +echo "$as_me:$LINENO: checking for int8_t" >&5 +echo $ECHO_N "checking for int8_t... $ECHO_C" >&6 +if test "${ac_cv_type_int8_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((int8_t *) 0) + return 0; +if (sizeof (int8_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_int8_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_int8_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_int8_t" >&5 +echo "${ECHO_T}$ac_cv_type_int8_t" >&6 +if test $ac_cv_type_int8_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT8_T 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for uint8_t" >&5 +echo $ECHO_N "checking for uint8_t... $ECHO_C" >&6 +if test "${ac_cv_type_uint8_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((uint8_t *) 0) + return 0; +if (sizeof (uint8_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uint8_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_uint8_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uint8_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint8_t" >&6 +if test $ac_cv_type_uint8_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT8_T 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for int16_t" >&5 +echo $ECHO_N "checking for int16_t... $ECHO_C" >&6 +if test "${ac_cv_type_int16_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((int16_t *) 0) + return 0; +if (sizeof (int16_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_int16_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_int16_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_int16_t" >&5 +echo "${ECHO_T}$ac_cv_type_int16_t" >&6 +if test $ac_cv_type_int16_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT16_T 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for uint16_t" >&5 +echo $ECHO_N "checking for uint16_t... $ECHO_C" >&6 +if test "${ac_cv_type_uint16_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((uint16_t *) 0) + return 0; +if (sizeof (uint16_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uint16_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_uint16_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uint16_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint16_t" >&6 +if test $ac_cv_type_uint16_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT16_T 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for int32_t" >&5 +echo $ECHO_N "checking for int32_t... $ECHO_C" >&6 +if test "${ac_cv_type_int32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((int32_t *) 0) + return 0; +if (sizeof (int32_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_int32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_int32_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_int32_t" >&5 +echo "${ECHO_T}$ac_cv_type_int32_t" >&6 +if test $ac_cv_type_int32_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT32_T 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for uint32_t" >&5 +echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6 +if test "${ac_cv_type_uint32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((uint32_t *) 0) + return 0; +if (sizeof (uint32_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uint32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_uint32_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint32_t" >&6 +if test $ac_cv_type_uint32_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT32_T 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for uint64_t" >&5 +echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6 +if test "${ac_cv_type_uint64_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((uint64_t *) 0) + return 0; +if (sizeof (uint64_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uint64_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_uint64_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint64_t" >&6 +if test $ac_cv_type_uint64_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT64_T 1 +_ACEOF + + +fi + +echo "$as_me:$LINENO: checking for unsigned long" >&5 +echo $ECHO_N "checking for unsigned long... $ECHO_C" >&6 +if test "${ac_cv_type_unsigned_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((unsigned long *) 0) + return 0; +if (sizeof (unsigned long)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_unsigned_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_unsigned_long=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long" >&5 +echo "${ECHO_T}$ac_cv_type_unsigned_long" >&6 + +echo "$as_me:$LINENO: checking size of unsigned long" >&5 +echo $ECHO_N "checking size of unsigned long... $ECHO_C" >&6 +if test "${ac_cv_sizeof_unsigned_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_unsigned_long" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo= ac_hi= +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_unsigned_long=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (unsigned long), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +long longval () { return (long) (sizeof (unsigned long)); } +unsigned long ulongval () { return (long) (sizeof (unsigned long)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (unsigned long))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (unsigned long)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (unsigned long)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_unsigned_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (unsigned long), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_unsigned_long=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_unsigned_long" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long +_ACEOF + + +echo "$as_me:$LINENO: checking for unsigned long long" >&5 +echo $ECHO_N "checking for unsigned long long... $ECHO_C" >&6 +if test "${ac_cv_type_unsigned_long_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((unsigned long long *) 0) + return 0; +if (sizeof (unsigned long long)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_unsigned_long_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_unsigned_long_long=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long_long" >&5 +echo "${ECHO_T}$ac_cv_type_unsigned_long_long" >&6 + +echo "$as_me:$LINENO: checking size of unsigned long long" >&5 +echo $ECHO_N "checking size of unsigned long long... $ECHO_C" >&6 +if test "${ac_cv_sizeof_unsigned_long_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_unsigned_long_long" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo= ac_hi= +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_unsigned_long_long=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long long), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (unsigned long long), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +long longval () { return (long) (sizeof (unsigned long long)); } +unsigned long ulongval () { return (long) (sizeof (unsigned long long)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (unsigned long long))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (unsigned long long)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (unsigned long long)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_unsigned_long_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long long), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (unsigned long long), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_unsigned_long_long=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_long_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_unsigned_long_long" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long +_ACEOF + + + +echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_const=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6 +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_inline=$ac_kw; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6 + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6 +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((size_t *) 0) + return 0; +if (sizeof (size_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_size_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6 +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned +_ACEOF + +fi + + + + + +for ac_func in socket inet_aton usleep +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +if test "x$ac_cv_func_socket" = "xno"; then + +echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 +echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_socket+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_socket=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_socket_socket=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6 +if test $ac_cv_lib_socket_socket = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + + echo "$as_me:$LINENO: checking for socket in -lwsock32" >&5 +echo $ECHO_N "checking for socket in -lwsock32... $ECHO_C" >&6 + SAVELIBS="$LIBS" + LIBS="$LIBS -lwsock32" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include + +int +main () +{ + +socket(0, 0, 0); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_socket=yes + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +LIBS="$SAVELIBS" + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_bigendian=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +# It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then + ac_cv_c_bigendian=yes +fi +if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int +main () +{ + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long l; + char c[sizeof (long)]; + } u; + u.l = 1; + exit (u.c[sizeof (long) - 1] == 1); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6 +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + + +case $host_cpu in + i*86 ) + +cat >>confdefs.h <<\_ACEOF +#define CPU_CISC 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_X86 1 +_ACEOF +;; + * ) + # CPU_RISC is only supported for big endian machines. + if test "$ac_cv_c_bigendian" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define CPU_RISC 1 +_ACEOF + + else + cat >>confdefs.h <<\_ACEOF +#define CPU_CISC 1 +_ACEOF + + fi + ;; +esac + +case $host_os in + *cygwin*|*mingw* ) + EXE=.exe;; + * ) EXE="";; +esac + + # define executable suffix; this is needed for `make clean' + +echo "$as_me:$LINENO: checking whether to compile in debugging" >&5 +echo $ECHO_N "checking whether to compile in debugging... $ECHO_C" >&6 +# Check whether --enable-debug or --disable-debug was given. +if test "${enable_debug+set}" = set; then + enableval="$enable_debug" + +else + enable_debug=yes +fi; +if test "$enable_debug" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define ENABLE_DEBUGGING 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: $enable_debug" >&5 +echo "${ECHO_T}$enable_debug" >&6 + +echo "$as_me:$LINENO: checking whether to use ISMAcryp code" >&5 +echo $ECHO_N "checking whether to use ISMAcryp code... $ECHO_C" >&6 +# Check whether --enable-generic-aesicm or --disable-generic-aesicm was given. +if test "${enable_generic_aesicm+set}" = set; then + enableval="$enable_generic_aesicm" + +else + enable_generic_aesicm=no +fi; +if test "$enable_generic_aesicm" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define GENERIC_AESICM 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: $enable_generic_aesicm" >&5 +echo "${ECHO_T}$enable_generic_aesicm" >&6 + +echo "$as_me:$LINENO: checking whether to use syslog for error reporting" >&5 +echo $ECHO_N "checking whether to use syslog for error reporting... $ECHO_C" >&6 +# Check whether --enable-syslog or --disable-syslog was given. +if test "${enable_syslog+set}" = set; then + enableval="$enable_syslog" + +else + enable_syslog=no +fi; +if test "$enable_syslog" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define USE_SYSLOG 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: $enable_syslog" >&5 +echo "${ECHO_T}$enable_syslog" >&6 + +echo "$as_me:$LINENO: checking whether to use stdout for error reporting" >&5 +echo $ECHO_N "checking whether to use stdout for error reporting... $ECHO_C" >&6 +# Check whether --enable-stdout or --disable-stdout was given. +if test "${enable_stdout+set}" = set; then + enableval="$enable_stdout" + +else + enable_stdout=yes +fi; +if test "$enable_stdout" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define ERR_REPORTING_STDOUT 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: $enable_stdout" >&5 +echo "${ECHO_T}$enable_stdout" >&6 + +echo "$as_me:$LINENO: checking whether to use /dev/console for error reporting" >&5 +echo $ECHO_N "checking whether to use /dev/console for error reporting... $ECHO_C" >&6 +# Check whether --enable-console or --disable-console was given. +if test "${enable_console+set}" = set; then + enableval="$enable_console" + +else + enable_console=no +fi; +if test "$enable_console" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define USE_ERR_REPORTING_FILE 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define ERR_REPORTING_FILE "/dev/console" +_ACEOF + +fi +echo "$as_me:$LINENO: result: $enable_console" >&5 +echo "${ECHO_T}$enable_console" >&6 + +echo "$as_me:$LINENO: checking whether to use GDOI key management" >&5 +echo $ECHO_N "checking whether to use GDOI key management... $ECHO_C" >&6 +# Check whether --enable-gdoi or --disable-gdoi was given. +if test "${enable_gdoi+set}" = set; then + enableval="$enable_gdoi" + +else + enable_gdoi=no +fi; +if test "$enable_gdoi" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define SRTP_GDOI 1 +_ACEOF + + GDOI_OBJS=gdoi/srtp+gdoi.o + +fi +echo "$as_me:$LINENO: result: $enable_gdoi" >&5 +echo "${ECHO_T}$enable_gdoi" >&6 + + ac_config_headers="$ac_config_headers crypto/include/config.h:config_in.h" + + + ac_config_files="$ac_config_files Makefile crypto/Makefile doc/Makefile" +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "crypto/Makefile" ) CONFIG_FILES="$CONFIG_FILES crypto/Makefile" ;; + "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "crypto/include/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS crypto/include/config.h:config_in.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@RNG_OBJS@,$RNG_OBJS,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@EXE@,$EXE,;t t +s,@GDOI_OBJS@,$GDOI_OBJS,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + + +# This is needed when building outside the source dir. +{ if $as_mkdir_p; then + mkdir -p crypto/ae_xfm + else + as_dir=crypto/ae_xfm + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/ae_xfm" >&5 +echo "$as_me: error: cannot create directory crypto/ae_xfm" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/cipher + else + as_dir=crypto/cipher + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/cipher" >&5 +echo "$as_me: error: cannot create directory crypto/cipher" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/hash + else + as_dir=crypto/hash + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/hash" >&5 +echo "$as_me: error: cannot create directory crypto/hash" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/kernel + else + as_dir=crypto/kernel + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/kernel" >&5 +echo "$as_me: error: cannot create directory crypto/kernel" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/math + else + as_dir=crypto/math + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/math" >&5 +echo "$as_me: error: cannot create directory crypto/math" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/replay + else + as_dir=crypto/replay + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/replay" >&5 +echo "$as_me: error: cannot create directory crypto/replay" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/rng + else + as_dir=crypto/rng + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/rng" >&5 +echo "$as_me: error: cannot create directory crypto/rng" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/test + else + as_dir=crypto/test + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/test" >&5 +echo "$as_me: error: cannot create directory crypto/test" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p doc + else + as_dir=doc + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory doc" >&5 +echo "$as_me: error: cannot create directory doc" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p srtp + else + as_dir=srtp + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory srtp" >&5 +echo "$as_me: error: cannot create directory srtp" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p tables + else + as_dir=tables + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory tables" >&5 +echo "$as_me: error: cannot create directory tables" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p test + else + as_dir=test + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory test" >&5 +echo "$as_me: error: cannot create directory test" >&2;} + { (exit 1); exit 1; }; }; } + diff --git a/src/libs/resiprocate/contrib/srtp/configure.in b/src/libs/resiprocate/contrib/srtp/configure.in new file mode 100644 index 00000000..49aaf8e0 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/configure.in @@ -0,0 +1,206 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(srtp) + +dnl Must come before AC_PROG_CC +if test -z "$CFLAGS"; then + dnl Default value for CFLAGS if not specified. + CFLAGS="-Wall -O4 -fexpensive-optimizations -funroll-loops" +fi + +dnl Checks for programs. +AC_PROG_RANLIB +AC_PROG_CC +AC_PROG_INSTALL + + +AC_ARG_ENABLE(kernel-linux, + [AS_HELP_STRING([--enable-kernel-linux], + [build library to run in Linux kernel context])], + [], enable_kernel_linux=no) +AC_MSG_CHECKING(whether to build for Linux kernel context) +if test "$enable_kernel_linux" = "yes"; then + AC_DEFINE(SRTP_KERNEL, 1, + [Define to compile for kernel contexts.]) + AC_DEFINE(SRTP_KERNEL_LINUX, 1, + [Define to compile for Linux kernel context.]) +fi +AC_MSG_RESULT($enable_kernel_linux) + +if test "$cross_compiling" != yes; then + dnl Check for /dev/urandom + AC_CHECK_FILE(/dev/urandom, DEV_URANDOM=/dev/urandom, + [AC_CHECK_FILE(/dev/random, DEV_URANDOM=/dev/random)]) +fi + +AC_MSG_CHECKING(which random device to use) +if test "$enable_kernel_linux" = "yes"; then + RNG_OBJS=rand_linux_kernel.o + AC_MSG_RESULT([Linux kernel builtin]) +else + RNG_OBJS=rand_source.o + if test -n "$DEV_URANDOM"; then + AC_DEFINE_UNQUOTED(DEV_URANDOM, "$DEV_URANDOM",[Path to random device]) + AC_MSG_RESULT([$DEV_URANDOM]) + else + AC_MSG_RESULT([standard rand() function...]) + fi +fi +AC_SUBST(RNG_OBJS) + + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(stdlib.h) +AC_CHECK_HEADERS(unistd.h) +AC_CHECK_HEADERS(byteswap.h) +AC_CHECK_HEADERS(stdint.h) +AC_CHECK_HEADERS(sys/uio.h) +AC_CHECK_HEADERS(inttypes.h) +AC_CHECK_HEADERS(sys/types.h) +AC_CHECK_HEADERS(machine/types.h) +AC_CHECK_HEADERS(sys/int_types.h) + +dnl socket() and friends +AC_CHECK_HEADERS(sys/socket.h netinet/in.h arpa/inet.h) +AC_CHECK_HEADERS(windows.h, [AC_CHECK_HEADERS(winsock2.h)]) + +AC_CHECK_HEADERS(syslog.h) + +AC_CHECK_TYPES([int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,uint64_t]) +AC_CHECK_SIZEOF(unsigned long) +AC_CHECK_SIZEOF(unsigned long long) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIZE_T + +dnl Checks for library functions. +AC_CHECK_FUNCS(socket inet_aton usleep) + +dnl Find socket function if not found yet. +if test "x$ac_cv_func_socket" = "xno"; then + AC_CHECK_LIB(socket, socket) + AC_MSG_CHECKING([for socket in -lwsock32]) + SAVELIBS="$LIBS" + LIBS="$LIBS -lwsock32" + AC_TRY_LINK([ +#include +],[ +socket(0, 0, 0); +], + ac_cv_func_socket=yes + AC_MSG_RESULT(yes), + LIBS="$SAVELIBS" + AC_MSG_RESULT(no)) +fi + +dnl Check the byte order +AC_C_BIGENDIAN + +AC_CANONICAL_HOST + +dnl check host_cpu type, set defines appropriately +case $host_cpu in + i*86 ) + AC_DEFINE(CPU_CISC, 1, + [Define if building for a CISC machine (e.g. Intel).]) + AC_DEFINE(HAVE_X86, 1, + [Define to use X86 inlined assembly code]);; + * ) + # CPU_RISC is only supported for big endian machines. + if test "$ac_cv_c_bigendian" = "yes"; then + AC_DEFINE(CPU_RISC, 1, + [Define if building for a RISC machine (assume slow byte access).]) + else + AC_DEFINE(CPU_CISC, 1) + fi + ;; +esac + +dnl Check if we're on a Windows platform. +case $host_os in + *cygwin*|*mingw* ) + EXE=.exe;; + * ) EXE="";; +esac + +AC_SUBST(EXE) # define executable suffix; this is needed for `make clean' + +AC_MSG_CHECKING(whether to compile in debugging) +AC_ARG_ENABLE(debug, + [AS_HELP_STRING([--disable-debug], + [do not compile in dynamic debugging system])], + [], enable_debug=yes) +if test "$enable_debug" = "yes"; then + AC_DEFINE(ENABLE_DEBUGGING, 1, + [Define to compile in dynamic debugging system.]) +fi +AC_MSG_RESULT($enable_debug) + +AC_MSG_CHECKING(whether to use ISMAcryp code) +AC_ARG_ENABLE(generic-aesicm, + [AS_HELP_STRING([--enable-generic-aesicm], + [compile in changes for ISMAcryp])], + [], enable_generic_aesicm=no) +if test "$enable_generic_aesicm" = "yes"; then + AC_DEFINE(GENERIC_AESICM, 1, [Define this to use ISMAcryp code.]) +fi +AC_MSG_RESULT($enable_generic_aesicm) + +AC_MSG_CHECKING(whether to use syslog for error reporting) +AC_ARG_ENABLE(syslog, + [AS_HELP_STRING([--enable-syslog], [use syslog for error reporting])], + [], enable_syslog=no) +if test "$enable_syslog" = "yes"; then + AC_DEFINE(USE_SYSLOG, 1, [Define to use syslog logging.]) +fi +AC_MSG_RESULT($enable_syslog) + +AC_MSG_CHECKING(whether to use stdout for error reporting) +AC_ARG_ENABLE(stdout, + [AS_HELP_STRING([--disable-stdout], [don't use stdout for error reporting])], + [], enable_stdout=yes) +if test "$enable_stdout" = "yes"; then + AC_DEFINE(ERR_REPORTING_STDOUT, 1, [Define to use logging to stdout.]) +fi +AC_MSG_RESULT($enable_stdout) + +AC_MSG_CHECKING(whether to use /dev/console for error reporting) +AC_ARG_ENABLE(console, + [AS_HELP_STRING([--enable-console], [use /dev/console for error reporting])], + [], enable_console=no) +if test "$enable_console" = "yes"; then + AC_DEFINE(USE_ERR_REPORTING_FILE, 1, [Write errors to this file]) + AC_DEFINE(ERR_REPORTING_FILE, "/dev/console", [Report errors to this file.]) +fi +AC_MSG_RESULT($enable_console) + +AC_MSG_CHECKING(whether to use GDOI key management) +AC_ARG_ENABLE(gdoi, + [AS_HELP_STRING([--enable-gdoi], [enable GDOI key management])], + [], enable_gdoi=no) +if test "$enable_gdoi" = "yes"; then + AC_DEFINE(SRTP_GDOI, 1, [Define to use GDOI.]) + GDOI_OBJS=gdoi/srtp+gdoi.o + AC_SUBST(GDOI_OBJS) +fi +AC_MSG_RESULT($enable_gdoi) + +AC_CONFIG_HEADER(crypto/include/config.h:config_in.h) + +AC_OUTPUT(Makefile crypto/Makefile doc/Makefile) + +# This is needed when building outside the source dir. +AS_MKDIR_P(crypto/ae_xfm) +AS_MKDIR_P(crypto/cipher) +AS_MKDIR_P(crypto/hash) +AS_MKDIR_P(crypto/kernel) +AS_MKDIR_P(crypto/math) +AS_MKDIR_P(crypto/replay) +AS_MKDIR_P(crypto/rng) +AS_MKDIR_P(crypto/test) +AS_MKDIR_P(doc) +AS_MKDIR_P(srtp) +AS_MKDIR_P(tables) +AS_MKDIR_P(test) diff --git a/src/libs/resiprocate/contrib/srtp/crypto/.cvsignore b/src/libs/resiprocate/contrib/srtp/crypto/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/src/libs/resiprocate/contrib/srtp/crypto/Makefile.in b/src/libs/resiprocate/contrib/srtp/crypto/Makefile.in new file mode 100644 index 00000000..5aab20f4 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/Makefile.in @@ -0,0 +1,130 @@ +# Makefile for libcryptomodule.a +# +# David A. McGrew +# Cisco Systems, Inc. + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ +VPATH = @srcdir@ + +CC = @CC@ +INCDIR = -Iinclude -I$(srcdir)/include +DEFS = @DEFS@ +CPPFLAGS= @CPPFLAGS@ +CFLAGS = @CFLAGS@ +LIBS = @LIBS@ +LDFLAGS = @LDFLAGS@ -L. +COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS) +CRYPTOLIB = -lcryptomodule + +RANLIB = @RANLIB@ + +# EXE defines the suffix on executables - it's .exe for cygwin, and +# null on linux, bsd, and OS X and other OSes. we define this so that +# `make clean` will work on the cygwin platform +EXE = @EXE@ +# Random source. +RNG_OBJS = @RNG_OBJS@ + +ifdef ARCH + DEFS += -D$(ARCH)=1 +endif + +ifdef sysname + DEFS += -D$(sysname)=1 +endif + +.PHONY: dummy all runtest clean superclean + +dummy : all runtest + +# test applications + +testapp = test/cipher_driver$(EXE) test/datatypes_driver$(EXE) \ + test/stat_driver$(EXE) test/sha1_driver$(EXE) \ + test/kernel_driver$(EXE) test/aes_calc$(EXE) test/rand_gen$(EXE) \ + test/env$(EXE) + +# data values used to test the aes_calc application + +k=000102030405060708090a0b0c0d0e0f +p=00112233445566778899aabbccddeeff +c=69c4e0d86a7b0430d8cdb78070b4c55a + +runtest: libcryptomodule.a $(testapp) + test/env$(EXE) # print out information on the build environment + @echo "running libcryptomodule test applications..." + test `test/aes_calc $k $p` = $c + test/cipher_driver$(EXE) -v >/dev/null + test/datatypes_driver$(EXE) -v >/dev/null + test/stat_driver$(EXE) >/dev/null + test/sha1_driver$(EXE) -v >/dev/null + test/kernel_driver$(EXE) -v >/dev/null + test/rand_gen$(EXE) -n 256 >/dev/null + @echo "libcryptomodule test applications passed." + +# libcryptomodule.a (the crypto engine) + +ciphers = cipher/cipher.o cipher/null_cipher.o \ + cipher/aes.o cipher/aes_icm.o \ + cipher/aes_cbc.o + +hashes = hash/null_auth.o hash/sha1.o \ + hash/hmac.o hash/auth.o + +math = math/datatypes.o math/stat.o + +rng = rng/$(RNG_OBJS) rng/rand_source.o rng/prng.o rng/ctr_prng.o + +err = kernel/err.o + +kernel = kernel/crypto_kernel.o kernel/alloc.o \ + kernel/key.o $(rng) $(err) + +xfm = ae_xfm/xfm.o + +cryptobj = $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(xfm) + +# the rule for making object files and test apps + +%.o: %.c + $(COMPILE) -c $< -o $@ + +%$(EXE): %.c libcryptomodule.a + $(COMPILE) $(LDFLAGS) $< -o $@ $(CRYPTOLIB) $(LIBS) + +ifndef AR + AR=ar +endif + +# and the crypto module library itself + +libcryptomodule.a: $(cryptobj) + $(AR) cr libcryptomodule.a $(cryptobj) + $(RANLIB) libcryptomodule.a + +all: libcryptomodule.a $(testapp) + +# housekeeping functions + +clean: + rm -f libcryptomodule.a + rm -f $(testapp) *.o */*.o + for a in * .* */*; do if [ -f "$$a~" ] ; then rm $$a~; fi; done; + rm -f `find . -name "*.[ch]~*~"` + rm -rf latex + +superclean: clean + rm -f *core TAGS ktrace.out Makefile + + +# the target 'package' builds a compressed tar archive of the source code + +distname = crypto-$(shell cat VERSION) + +package: superclean + cd ..; tar cvzf $(distname).tgz crypto/ + + +# EOF diff --git a/src/libs/resiprocate/contrib/srtp/crypto/VERSION b/src/libs/resiprocate/contrib/srtp/crypto/VERSION new file mode 100644 index 00000000..3eefcb9d --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/VERSION @@ -0,0 +1 @@ +1.0.0 diff --git a/src/libs/resiprocate/contrib/srtp/crypto/ae_xfm/xfm.c b/src/libs/resiprocate/contrib/srtp/crypto/ae_xfm/xfm.c new file mode 100644 index 00000000..f149d461 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/ae_xfm/xfm.c @@ -0,0 +1,570 @@ +/* + * xfm.c + * + * Crypto transform implementation + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +#include "cryptoalg.h" +#include "aes_cbc.h" +#include "hmac.h" +#include "crypto_kernel.h" /* for crypto_get_random() */ + +#define KEY_LEN 16 +#define ENC_KEY_LEN 16 +#define MAC_KEY_LEN 16 +#define IV_LEN 16 +#define TAG_LEN 12 +#define MAX_EXPAND 27 + +err_status_t +aes_128_cbc_hmac_sha1_96_func(void *key, + void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len, + void *auth_tag) { + aes_cbc_ctx_t aes_ctx; + hmac_ctx_t hmac_ctx; + unsigned char enc_key[ENC_KEY_LEN]; + unsigned char mac_key[MAC_KEY_LEN]; + err_status_t status; + + /* check if we're doing authentication only */ + if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { + + /* perform authentication only */ + + } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { + + /* + * bad parameter - we expect either all three pointers to be NULL, + * or none of those pointers to be NULL + */ + return err_status_fail; + + } else { + + /* derive encryption and authentication keys from the input key */ + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); + if (status) return status; + + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); + if (status) return status; + + + /* perform encryption and authentication */ + + /* set aes key */ + status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt); + if (status) return status; + + /* set iv */ + status = crypto_get_random(iv, IV_LEN); + if (status) return status; + status = aes_cbc_set_iv(&aes_ctx, iv); + + /* encrypt the opaque data */ + status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len); + if (status) return status; + + /* authenticate clear and opaque data */ + status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); + if (status) return status; + + status = hmac_start(&hmac_ctx); + if (status) return status; + + status = hmac_update(&hmac_ctx, clear, clear_len); + if (status) return status; + + status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag); + if (status) return status; + + } + + return err_status_ok; +} + +err_status_t +aes_128_cbc_hmac_sha1_96_inv(void *key, + void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len, + void *auth_tag) { + aes_cbc_ctx_t aes_ctx; + hmac_ctx_t hmac_ctx; + unsigned char enc_key[ENC_KEY_LEN]; + unsigned char mac_key[MAC_KEY_LEN]; + unsigned char tmp_tag[TAG_LEN]; + unsigned char *tag = auth_tag; + err_status_t status; + int i; + + /* check if we're doing authentication only */ + if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { + + /* perform authentication only */ + + } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { + + /* + * bad parameter - we expect either all three pointers to be NULL, + * or none of those pointers to be NULL + */ + return err_status_fail; + + } else { + + /* derive encryption and authentication keys from the input key */ + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); + if (status) return status; + + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); + if (status) return status; + + /* perform encryption and authentication */ + + /* set aes key */ + status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt); + if (status) return status; + + /* set iv */ + status = rand_source_get_octet_string(iv, IV_LEN); + if (status) return status; + status = aes_cbc_set_iv(&aes_ctx, iv); + + /* encrypt the opaque data */ + status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len); + if (status) return status; + + /* authenticate clear and opaque data */ + status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); + if (status) return status; + + status = hmac_start(&hmac_ctx); + if (status) return status; + + status = hmac_update(&hmac_ctx, clear, clear_len); + if (status) return status; + + status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag); + if (status) return status; + + /* compare the computed tag with the one provided as input */ + for (i=0; i < TAG_LEN; i++) + if (tmp_tag[i] != tag[i]) + return err_status_auth_fail; + + } + + return err_status_ok; +} + + +#define ENC 1 + +#define DEBUG 0 + +err_status_t +aes_128_cbc_hmac_sha1_96_enc(void *key, + const void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len) { + aes_cbc_ctx_t aes_ctx; + hmac_ctx_t hmac_ctx; + unsigned char enc_key[ENC_KEY_LEN]; + unsigned char mac_key[MAC_KEY_LEN]; + unsigned char *auth_tag; + err_status_t status; + + /* check if we're doing authentication only */ + if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { + + /* perform authentication only */ + + } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { + + /* + * bad parameter - we expect either all three pointers to be NULL, + * or none of those pointers to be NULL + */ + return err_status_fail; + + } else { + +#if DEBUG + printf("ENC using key %s\n", octet_string_hex_string(key, KEY_LEN)); +#endif + + /* derive encryption and authentication keys from the input key */ + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); + if (status) return status; + + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); + if (status) return status; + + + /* perform encryption and authentication */ + + /* set aes key */ + status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt); + if (status) return status; + + /* set iv */ + status = rand_source_get_octet_string(iv, IV_LEN); + if (status) return status; + status = aes_cbc_set_iv(&aes_ctx, iv); + if (status) return status; + +#if DEBUG + printf("plaintext len: %d\n", *opaque_len); + printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); + printf("plaintext: %s\n", octet_string_hex_string(opaque, *opaque_len)); +#endif + +#if ENC + /* encrypt the opaque data */ + status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len); + if (status) return status; +#endif + +#if DEBUG + printf("ciphertext len: %d\n", *opaque_len); + printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len)); +#endif + + /* + * authenticate clear and opaque data, then write the + * authentication tag to the location immediately following the + * ciphertext + */ + status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); + if (status) return status; + + status = hmac_start(&hmac_ctx); + if (status) return status; + + status = hmac_update(&hmac_ctx, clear, clear_len); + if (status) return status; +#if DEBUG + printf("hmac input: %s\n", + octet_string_hex_string(clear, clear_len)); +#endif + auth_tag = (unsigned char *)opaque; + auth_tag += *opaque_len; + status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag); + if (status) return status; +#if DEBUG + printf("hmac input: %s\n", + octet_string_hex_string(opaque, *opaque_len)); +#endif + /* bump up the opaque_len to reflect the authentication tag */ + *opaque_len += TAG_LEN; + +#if DEBUG + printf("prot data len: %d\n", *opaque_len); + printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len)); +#endif + } + + return err_status_ok; +} + +err_status_t +aes_128_cbc_hmac_sha1_96_dec(void *key, + const void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len) { + aes_cbc_ctx_t aes_ctx; + hmac_ctx_t hmac_ctx; + unsigned char enc_key[ENC_KEY_LEN]; + unsigned char mac_key[MAC_KEY_LEN]; + unsigned char tmp_tag[TAG_LEN]; + unsigned char *auth_tag; + unsigned ciphertext_len; + err_status_t status; + int i; + + /* check if we're doing authentication only */ + if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { + + /* perform authentication only */ + + } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { + + /* + * bad parameter - we expect either all three pointers to be NULL, + * or none of those pointers to be NULL + */ + return err_status_fail; + + } else { +#if DEBUG + printf("DEC using key %s\n", octet_string_hex_string(key, KEY_LEN)); +#endif + + /* derive encryption and authentication keys from the input key */ + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); + if (status) return status; + + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); + if (status) return status; + +#if DEBUG + printf("prot data len: %d\n", *opaque_len); + printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len)); +#endif + + /* + * set the protected data length to that of the ciphertext, by + * subtracting out the length of the authentication tag + */ + ciphertext_len = *opaque_len - TAG_LEN; + +#if DEBUG + printf("ciphertext len: %d\n", ciphertext_len); +#endif + /* verify the authentication tag */ + + /* + * compute the authentication tag for the clear and opaque data, + * and write it to a temporary location + */ + status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); + if (status) return status; + + status = hmac_start(&hmac_ctx); + if (status) return status; + + status = hmac_update(&hmac_ctx, clear, clear_len); + if (status) return status; + +#if DEBUG + printf("hmac input: %s\n", + octet_string_hex_string(clear, clear_len)); +#endif + + status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag); + if (status) return status; + +#if DEBUG + printf("hmac input: %s\n", + octet_string_hex_string(opaque, ciphertext_len)); +#endif + + /* + * compare the computed tag with the one provided as input (which + * immediately follows the ciphertext) + */ + auth_tag = (unsigned char *)opaque; + auth_tag += ciphertext_len; +#if DEBUG + printf("auth_tag: %s\n", octet_string_hex_string(auth_tag, TAG_LEN)); + printf("tmp_tag: %s\n", octet_string_hex_string(tmp_tag, TAG_LEN)); +#endif + for (i=0; i < TAG_LEN; i++) { + if (tmp_tag[i] != auth_tag[i]) + return err_status_auth_fail; + } + + /* bump down the opaque_len to reflect the authentication tag */ + *opaque_len -= TAG_LEN; + + /* decrypt the confidential data */ + status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt); + if (status) return status; + status = aes_cbc_set_iv(&aes_ctx, iv); + if (status) return status; + +#if DEBUG + printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len)); + printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); +#endif + +#if ENC + status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len); + if (status) return status; +#endif + +#if DEBUG + printf("plaintext len: %d\n", ciphertext_len); + printf("plaintext: %s\n", + octet_string_hex_string(opaque, ciphertext_len)); +#endif + + /* indicate the length of the plaintext */ + *opaque_len = ciphertext_len; + } + + return err_status_ok; +} + +cryptoalg_ctx_t cryptoalg_ctx = { + aes_128_cbc_hmac_sha1_96_enc, + aes_128_cbc_hmac_sha1_96_dec, + KEY_LEN, + IV_LEN, + TAG_LEN, + MAX_EXPAND, +}; + +cryptoalg_t cryptoalg = &cryptoalg_ctx; + +#define NULL_TAG_LEN 12 + +err_status_t +null_enc(void *key, + const void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len) { + int i; + unsigned char *auth_tag; + unsigned char *init_vec = iv; + + /* check if we're doing authentication only */ + if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { + + /* perform authentication only */ + + } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { + + /* + * bad parameter - we expect either all three pointers to be NULL, + * or none of those pointers to be NULL + */ + return err_status_fail; + + } else { + +#if DEBUG + printf("NULL ENC using key %s\n", octet_string_hex_string(key, KEY_LEN)); + printf("NULL_TAG_LEN: %d\n", NULL_TAG_LEN); + printf("plaintext len: %d\n", *opaque_len); +#endif + for (i=0; i < IV_LEN; i++) + init_vec[i] = i + (i * 16); +#if DEBUG + printf("iv: %s\n", + octet_string_hex_string(iv, IV_LEN)); + printf("plaintext: %s\n", + octet_string_hex_string(opaque, *opaque_len)); +#endif + auth_tag = opaque; + auth_tag += *opaque_len; + for (i=0; i < NULL_TAG_LEN; i++) + auth_tag[i] = i + (i * 16); + *opaque_len += NULL_TAG_LEN; +#if DEBUG + printf("protected data len: %d\n", *opaque_len); + printf("protected data: %s\n", + octet_string_hex_string(opaque, *opaque_len)); +#endif + + } + + return err_status_ok; +} + +err_status_t +null_dec(void *key, + const void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len) { + unsigned char *auth_tag; + + /* check if we're doing authentication only */ + if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { + + /* perform authentication only */ + + } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { + + /* + * bad parameter - we expect either all three pointers to be NULL, + * or none of those pointers to be NULL + */ + return err_status_fail; + + } else { + +#if DEBUG + printf("NULL DEC using key %s\n", octet_string_hex_string(key, KEY_LEN)); + + printf("protected data len: %d\n", *opaque_len); + printf("protected data: %s\n", + octet_string_hex_string(opaque, *opaque_len)); +#endif + auth_tag = opaque; + auth_tag += (*opaque_len - NULL_TAG_LEN); +#if DEBUG + printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); +#endif + *opaque_len -= NULL_TAG_LEN; +#if DEBUG + printf("plaintext len: %d\n", *opaque_len); + printf("plaintext: %s\n", + octet_string_hex_string(opaque, *opaque_len)); +#endif + } + + return err_status_ok; +} + +cryptoalg_ctx_t null_cryptoalg_ctx = { + null_enc, + null_dec, + KEY_LEN, + IV_LEN, + NULL_TAG_LEN, + MAX_EXPAND, +}; + +cryptoalg_t null_cryptoalg = &null_cryptoalg_ctx; + +int +cryptoalg_get_id(cryptoalg_t c) { + if (c == cryptoalg) + return 1; + return 0; +} + +cryptoalg_t +cryptoalg_find_by_id(int id) { + switch(id) { + case 1: + return cryptoalg; + default: + break; + } + return 0; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/cipher/aes.c b/src/libs/resiprocate/contrib/srtp/crypto/cipher/aes.c new file mode 100644 index 00000000..f1286c36 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/cipher/aes.c @@ -0,0 +1,1951 @@ +/* + * aes.c + * + * An implemnetation of the AES block cipher. + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "aes.h" +#include "err.h" + +/* + * we use the tables T0, T1, T2, T3, and T4 to compute AES, and + * the tables U0, U1, U2, and U4 to compute its inverse + * + * different tables are used on little-endian (Intel, VMS) and + * big-endian processors (everything else) + * + * these tables are computed using the program tables/aes_tables; use + * this program to generate different tables for porting or + * optimization on a different platform + */ + +#ifndef WORDS_BIGENDIAN + +static uint32_t T0[256] = { + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, + 0xdf2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, + 0x50303060, 0x3010102, 0xa96767ce, 0x7d2b2b56, + 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, + 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, + 0x15fafaef, 0xeb5959b2, 0xc947478e, 0xbf0f0fb, + 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, + 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, + 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, + 0x5a36366c, 0x413f3f7e, 0x2f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x8f1f1f9, + 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, + 0xc040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, + 0x28181830, 0xa1969637, 0xf05050a, 0xb59a9a2f, + 0x907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, + 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, + 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, + 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, + 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, + 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x0, 0x2cededc1, + 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, + 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, + 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, + 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, + 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, + 0xcf45458a, 0x10f9f9e9, 0x6020204, 0x817f7ffe, + 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, + 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, + 0xad92923f, 0xbc9d9d21, 0x48383870, 0x4f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, + 0x30101020, 0x1affffe5, 0xef3f3fd, 0x6dd2d2bf, + 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, + 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, + 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, + 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, + 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, + 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, + 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, + 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, + 0xdb494992, 0xa06060c, 0x6c242448, 0xe45c5cb8, + 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, + 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, + 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, + 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, + 0xb46c6cd8, 0xfa5656ac, 0x7f4f4f3, 0x25eaeacf, + 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, + 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, + 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, + 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, + 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, + 0xd8484890, 0x5030306, 0x1f6f6f7, 0x120e0e1c, + 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, + 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, + 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, + 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, + 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, + 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, + 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, + 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, + 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c, +}; + +static uint32_t T1[256] = { + 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, + 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, + 0x30306050, 0x1010203, 0x6767cea9, 0x2b2b567d, + 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, + 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, + 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, + 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, + 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, + 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, + 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, + 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, + 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, + 0x404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, + 0x18183028, 0x969637a1, 0x5050a0f, 0x9a9a2fb5, + 0x7070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, + 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, + 0x909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, + 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, + 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, + 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, + 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, + 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, + 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, + 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, + 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, + 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, + 0x45458acf, 0xf9f9e910, 0x2020406, 0x7f7ffe81, + 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, + 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, + 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, + 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, + 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, + 0xcdcd814c, 0xc0c1814, 0x13132635, 0xececc32f, + 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, + 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, + 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, + 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, + 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, + 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, + 0xdedea779, 0x5e5ebce2, 0xb0b161d, 0xdbdbad76, + 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0xa0a141e, + 0x494992db, 0x6060c0a, 0x2424486c, 0x5c5cb8e4, + 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, + 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, + 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, + 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, + 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, + 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x8081018, + 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, + 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, + 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, + 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, + 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, + 0x484890d8, 0x3030605, 0xf6f6f701, 0xe0e1c12, + 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, + 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, + 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, + 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, + 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, + 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, + 0x8c8c038f, 0xa1a159f8, 0x89890980, 0xd0d1a17, + 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, + 0x414182c3, 0x999929b0, 0x2d2d5a77, 0xf0f1e11, + 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a, +}; + +static uint32_t T2[256] = { + 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, + 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, + 0x30605030, 0x1020301, 0x67cea967, 0x2b567d2b, + 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, + 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, + 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, + 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, + 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, + 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, + 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, + 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, + 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, + 0x4080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, + 0x18302818, 0x9637a196, 0x50a0f05, 0x9a2fb59a, + 0x70e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, + 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, + 0x9121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, + 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, + 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, + 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, + 0x53a6f553, 0xd1b968d1, 0x0, 0xedc12ced, + 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, + 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, + 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, + 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, + 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, + 0x458acf45, 0xf9e910f9, 0x2040602, 0x7ffe817f, + 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, + 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, + 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, + 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, + 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, + 0xcd814ccd, 0xc18140c, 0x13263513, 0xecc32fec, + 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, + 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, + 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, + 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, + 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, + 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, + 0xdea779de, 0x5ebce25e, 0xb161d0b, 0xdbad76db, + 0xe0db3be0, 0x32645632, 0x3a744e3a, 0xa141e0a, + 0x4992db49, 0x60c0a06, 0x24486c24, 0x5cb8e45c, + 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, + 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, + 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, + 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, + 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, + 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x8101808, + 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, + 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, + 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, + 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, + 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, + 0x4890d848, 0x3060503, 0xf6f701f6, 0xe1c120e, + 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, + 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, + 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, + 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, + 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, + 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, + 0x8c038f8c, 0xa159f8a1, 0x89098089, 0xd1a170d, + 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, + 0x4182c341, 0x9929b099, 0x2d5a772d, 0xf1e110f, + 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16, +}; + +static uint32_t T3[256] = { + 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, + 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, + 0x60503030, 0x2030101, 0xcea96767, 0x567d2b2b, + 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, + 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, + 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, + 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, + 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, + 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, + 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, + 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, + 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, + 0x80c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, + 0x30281818, 0x37a19696, 0xa0f0505, 0x2fb59a9a, + 0xe090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, + 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, + 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, + 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, + 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, + 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, + 0xa6f55353, 0xb968d1d1, 0x0, 0xc12ceded, + 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, + 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, + 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, + 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, + 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, + 0x8acf4545, 0xe910f9f9, 0x4060202, 0xfe817f7f, + 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, + 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x58a8f8f, + 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, + 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, + 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, + 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, + 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, + 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, + 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, + 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, + 0x44662222, 0x547e2a2a, 0x3bab9090, 0xb838888, + 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, + 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, + 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, + 0x92db4949, 0xc0a0606, 0x486c2424, 0xb8e45c5c, + 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, + 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, + 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, + 0x18c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, + 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, + 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, + 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, + 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, + 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, + 0x96dd4b4b, 0x61dcbdbd, 0xd868b8b, 0xf858a8a, + 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, + 0x90d84848, 0x6050303, 0xf701f6f6, 0x1c120e0e, + 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, + 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, + 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, + 0xd2bb6969, 0xa970d9d9, 0x7898e8e, 0x33a79494, + 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, + 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, + 0x38f8c8c, 0x59f8a1a1, 0x9808989, 0x1a170d0d, + 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, + 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, + 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616, +}; + +static uint32_t U0[256] = { + 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, + 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, + 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, + 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, + 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, + 0x2752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, + 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, + 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, + 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, + 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, + 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, + 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, + 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, + 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, + 0x728ebb2, 0x3c2b52f, 0x9a7bc586, 0xa50837d3, + 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, + 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, + 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, + 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, + 0x39ec830b, 0xaaef6040, 0x69f715e, 0x51106ebd, + 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, + 0xb58d5491, 0x55dc471, 0x6fd40604, 0xff155060, + 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, + 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, + 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x0, + 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, + 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, + 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, + 0xb1670a0c, 0xfe75793, 0xd296eeb4, 0x9e919b1b, + 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, + 0xaba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, + 0xb0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, + 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, + 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, + 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, + 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, + 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, + 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, + 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, + 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, + 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, + 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, + 0xe49d3a2c, 0xd927850, 0x9bcc5f6a, 0x62467e54, + 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, + 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, + 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, + 0x97826cd, 0xf418596e, 0x1b79aec, 0xa89a4f83, + 0x656e95e6, 0x7ee6ffaa, 0x8cfbc21, 0xe6e815ef, + 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, + 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, + 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, + 0x4a9804f1, 0xf7daec41, 0xe50cd7f, 0x2ff69117, + 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, + 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, + 0x4ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, + 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, + 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, + 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, + 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, + 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, + 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, + 0x72c31d16, 0xc25e2bc, 0x8b493c28, 0x41950dff, + 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, + 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0, +}; + +static uint32_t U1[256] = { + 0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, + 0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x3e34b93, + 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, + 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, + 0x5ab1de49, 0x1bba2567, 0xeea4598, 0xc0fe5de1, + 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, + 0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, + 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, + 0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, + 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, + 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, + 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, + 0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, + 0xd373ab23, 0x24b72e2, 0x8f1fe357, 0xab55662a, + 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x837d3a5, + 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, + 0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, + 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a, + 0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, + 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, + 0x8a213ef9, 0x6dd963d, 0x53eddae, 0xbde64d46, + 0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, + 0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, + 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db, + 0xa7ca147, 0xf427ce9, 0x1e84f8c9, 0x0, + 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, + 0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, + 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, + 0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, + 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, + 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, + 0xd090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, + 0x19f15785, 0x775af4c, 0xdd99eebb, 0x607fa3fd, + 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, + 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, + 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, + 0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, + 0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0, + 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, + 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, + 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0xbd49836, + 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, + 0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, + 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, + 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, + 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, + 0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, + 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, + 0x9be7bad9, 0x366f4ace, 0x99fead4, 0x7cb029d6, + 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, + 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, + 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, + 0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x496e4df, + 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, + 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, + 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, + 0x61d79a8c, 0xca1377a, 0x14f8598e, 0x3c13eb89, + 0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, + 0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, + 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, + 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, + 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, + 0x1a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, + 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042, +}; + +static uint32_t U2[256] = { + 0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, + 0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303, + 0x302055fa, 0x76adf66d, 0xcc889176, 0x2f5254c, + 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, + 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, + 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, + 0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, + 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, + 0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, + 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, + 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, + 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x8f9942b, + 0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, + 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, + 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, + 0x2830f287, 0xbf23b2a5, 0x302ba6a, 0x16ed5c82, + 0xcf8a2b1c, 0x79a792b4, 0x7f3f0f2, 0x694ea1e2, + 0xda65cdf4, 0x506d5be, 0x34d11f62, 0xa6c48afe, + 0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, + 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, + 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, + 0x5491b58d, 0xc471055d, 0x6046fd4, 0x5060ff15, + 0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, + 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee, + 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x0, + 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, + 0xefdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, + 0xf0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, + 0xa0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, + 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, + 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, + 0x90e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, + 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, + 0x1f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, + 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, + 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, + 0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, + 0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3, + 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, + 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, + 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, + 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf, + 0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, + 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, + 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, + 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, + 0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, + 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, + 0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, + 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, + 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, + 0x4f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, + 0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, + 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, + 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0xbfb2e41, + 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, + 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, + 0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, + 0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, + 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, + 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, + 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0xdff4195, + 0xa8397101, 0xc08deb3, 0xb4d89ce4, 0x566490c1, + 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257, +}; + +static uint32_t U3[256] = { + 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, + 0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3, + 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, + 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, + 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, + 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, + 0x3e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, + 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, + 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, + 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, + 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, + 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, + 0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, + 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, + 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, + 0x30f28728, 0x23b2a5bf, 0x2ba6a03, 0xed5c8216, + 0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, + 0x65cdf4da, 0x6d5be05, 0xd11f6234, 0xc48afea6, + 0x349d532e, 0xa2a055f3, 0x532e18a, 0xa475ebf6, + 0xb39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, + 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, + 0x91b58d54, 0x71055dc4, 0x46fd406, 0x60ff1550, + 0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, + 0xb0bd42e8, 0x7888b89, 0xe7385b19, 0x79dbeec8, + 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x0, + 0x9838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, + 0xfdfbff0e, 0xf563885, 0x3d1ed5ae, 0x3627392d, + 0xa64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, + 0xcb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, + 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, + 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, + 0xe0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, + 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, + 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, + 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, + 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, + 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, + 0x1d4b2f9e, 0xdcf330b2, 0xdec5286, 0x77d0e3c1, + 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, + 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, + 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, + 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad, + 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, + 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, + 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, + 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, + 0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, + 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, + 0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, + 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, + 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, + 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, + 0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, + 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165, + 0x9d04ea5e, 0x15d358c, 0xfa737487, 0xfb2e410b, + 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, + 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, + 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, + 0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, + 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, + 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, + 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, + 0x397101a8, 0x8deb30c, 0xd89ce4b4, 0x6490c156, + 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8, +}; + +#else /* assume big endian */ + +static uint32_t T0[256] = { + 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, + 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, + 0x60303050, 0x2010103, 0xce6767a9, 0x562b2b7d, + 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, + 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, + 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, + 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, + 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, + 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, + 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, + 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, + 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, + 0x804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, + 0x30181828, 0x379696a1, 0xa05050f, 0x2f9a9ab5, + 0xe070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, + 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, + 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, + 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, + 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, + 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, + 0xa65353f5, 0xb9d1d168, 0x0, 0xc1eded2c, + 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, + 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, + 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, + 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, + 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, + 0x8a4545cf, 0xe9f9f910, 0x4020206, 0xfe7f7f81, + 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, + 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x58f8f8a, + 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, + 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, + 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, + 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, + 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, + 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, + 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, + 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, + 0x44222266, 0x542a2a7e, 0x3b9090ab, 0xb888883, + 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, + 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, + 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, + 0x924949db, 0xc06060a, 0x4824246c, 0xb85c5ce4, + 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, + 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, + 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, + 0x18d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, + 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, + 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, + 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, + 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, + 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, + 0x964b4bdd, 0x61bdbddc, 0xd8b8b86, 0xf8a8a85, + 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, + 0x904848d8, 0x6030305, 0xf7f6f601, 0x1c0e0e12, + 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, + 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, + 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, + 0xd26969bb, 0xa9d9d970, 0x78e8e89, 0x339494a7, + 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, + 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, + 0x38c8c8f, 0x59a1a1f8, 0x9898980, 0x1a0d0d17, + 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, + 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, + 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a, +}; + +static uint32_t T1[256] = { + 0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, + 0xdfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5, + 0x50603030, 0x3020101, 0xa9ce6767, 0x7d562b2b, + 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, + 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, + 0x15effafa, 0xebb25959, 0xc98e4747, 0xbfbf0f0, + 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, + 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0, + 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, + 0x5a6c3636, 0x417e3f3f, 0x2f5f7f7, 0x4f83cccc, + 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x8f9f1f1, + 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, + 0xc080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, + 0x28301818, 0xa1379696, 0xf0a0505, 0xb52f9a9a, + 0x90e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, + 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, + 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, + 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, + 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, + 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484, + 0xf5a65353, 0x68b9d1d1, 0x0, 0x2cc1eded, + 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, + 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, + 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, + 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, + 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585, + 0xcf8a4545, 0x10e9f9f9, 0x6040202, 0x81fe7f7f, + 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, + 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, + 0xad3f9292, 0xbc219d9d, 0x48703838, 0x4f1f5f5, + 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, + 0x30201010, 0x1ae5ffff, 0xefdf3f3, 0x6dbfd2d2, + 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, + 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, + 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, + 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, + 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, + 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888, + 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, + 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, + 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, + 0xdb924949, 0xa0c0606, 0x6c482424, 0xe4b85c5c, + 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, + 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979, + 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, + 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, + 0xb4d86c6c, 0xfaac5656, 0x7f3f4f4, 0x25cfeaea, + 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, + 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, + 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6, + 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, + 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, + 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, + 0xd8904848, 0x5060303, 0x1f7f6f6, 0x121c0e0e, + 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, + 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e, + 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, + 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, + 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, + 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, + 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, + 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868, + 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, + 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616, +}; + +static uint32_t T2[256] = { + 0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, + 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5, + 0x30506030, 0x1030201, 0x67a9ce67, 0x2b7d562b, + 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, + 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, + 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, + 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, + 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0, + 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, + 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, + 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, + 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, + 0x40c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, + 0x18283018, 0x96a13796, 0x50f0a05, 0x9ab52f9a, + 0x7090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, + 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, + 0x91b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, + 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, + 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, + 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384, + 0x53f5a653, 0xd168b9d1, 0x0, 0xed2cc1ed, + 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, + 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, + 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, + 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, + 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185, + 0x45cf8a45, 0xf910e9f9, 0x2060402, 0x7f81fe7f, + 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, + 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, + 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, + 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, + 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2, + 0xcd4c81cd, 0xc14180c, 0x13352613, 0xec2fc3ec, + 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, + 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, + 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, + 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, + 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88, + 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, + 0xde79a7de, 0x5ee2bc5e, 0xb1d160b, 0xdb76addb, + 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0xa1e140a, + 0x49db9249, 0x60a0c06, 0x246c4824, 0x5ce4b85c, + 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, + 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279, + 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, + 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, + 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, + 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x8181008, + 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, + 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6, + 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, + 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, + 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, + 0x48d89048, 0x3050603, 0xf601f7f6, 0xe121c0e, + 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, + 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e, + 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, + 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, + 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, + 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, + 0x8c8f038c, 0xa1f859a1, 0x89800989, 0xd171a0d, + 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068, + 0x41c38241, 0x99b02999, 0x2d775a2d, 0xf111e0f, + 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16, +}; + +static uint32_t T3[256] = { + 0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, + 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491, + 0x30305060, 0x1010302, 0x6767a9ce, 0x2b2b7d56, + 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, + 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, + 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, + 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, + 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b, + 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, + 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, + 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, + 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, + 0x4040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, + 0x18182830, 0x9696a137, 0x5050f0a, 0x9a9ab52f, + 0x707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, + 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, + 0x9091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, + 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, + 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, + 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713, + 0x5353f5a6, 0xd1d168b9, 0x0, 0xeded2cc1, + 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, + 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, + 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, + 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, + 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411, + 0x4545cf8a, 0xf9f910e9, 0x2020604, 0x7f7f81fe, + 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, + 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, + 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, + 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, + 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf, + 0xcdcd4c81, 0xc0c1418, 0x13133526, 0xecec2fc3, + 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, + 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, + 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, + 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, + 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b, + 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, + 0xdede79a7, 0x5e5ee2bc, 0xb0b1d16, 0xdbdb76ad, + 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0xa0a1e14, + 0x4949db92, 0x6060a0c, 0x24246c48, 0x5c5ce4b8, + 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, + 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2, + 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, + 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, + 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, + 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x8081810, + 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, + 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197, + 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, + 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, + 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, + 0x4848d890, 0x3030506, 0xf6f601f7, 0xe0e121c, + 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, + 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927, + 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, + 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, + 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, + 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, + 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0xd0d171a, + 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0, + 0x4141c382, 0x9999b029, 0x2d2d775a, 0xf0f111e, + 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c, +}; + +static uint32_t U0[256] = { + 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, + 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, + 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, + 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, + 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, + 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, + 0x38f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, + 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, + 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, + 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, + 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, + 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, + 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, + 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, + 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, + 0x302887f2, 0x23bfa5b2, 0x2036aba, 0xed16825c, + 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, + 0x65daf4cd, 0x605bed5, 0xd134621f, 0xc4a6fe8a, + 0x342e539d, 0xa2f355a0, 0x58ae132, 0xa4f6eb75, + 0xb83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, + 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, + 0x91548db5, 0x71c45d05, 0x406d46f, 0x605015ff, + 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, + 0xb0e842bd, 0x7898b88, 0xe7195b38, 0x79c8eedb, + 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x0, + 0x9808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, + 0xfd0efffb, 0xf853856, 0x3daed51e, 0x362d3927, + 0xa0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, + 0xc0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, + 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, + 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, + 0xe090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, + 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, + 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, + 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, + 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, + 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, + 0x1d9e2f4b, 0xdcb230f3, 0xd8652ec, 0x77c1e3d0, + 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, + 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, + 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, + 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, + 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, + 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, + 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, + 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, + 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, + 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, + 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, + 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, + 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, + 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, + 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, + 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, + 0x9d5eea04, 0x18c355d, 0xfa877473, 0xfb0b412e, + 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, + 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, + 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, + 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, + 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, + 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, + 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, + 0x39a80171, 0x80cb3de, 0xd8b4e49c, 0x6456c190, + 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742 +}; + +static uint32_t U1[256] = { + 0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, + 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303, + 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, + 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, + 0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, + 0x2c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9, + 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, + 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8, + 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, + 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, + 0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, + 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b, + 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, + 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab, + 0x7b2eb28, 0x32fb5c2, 0x9a86c57b, 0xa5d33708, + 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, + 0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, + 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe, + 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, + 0x390b83ec, 0xaa4060ef, 0x65e719f, 0x51bd6e10, + 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, + 0xb591548d, 0x571c45d, 0x6f0406d4, 0xff605015, + 0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, + 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee, + 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x0, + 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72, + 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, + 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, + 0xb10c0a67, 0xf9357e7, 0xd2b4ee96, 0x9e1b9b91, + 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a, + 0xae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, + 0xb0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9, + 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, + 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, + 0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, + 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611, + 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, + 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3, + 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, + 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, + 0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, + 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf, + 0xe42c3a9d, 0xd507892, 0x9b6a5fcc, 0x62547e46, + 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af, + 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, + 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, + 0x9cd2678, 0xf46e5918, 0x1ec9ab7, 0xa8834f9a, + 0x65e6956e, 0x7eaaffe6, 0x821bccf, 0xe6ef15e8, + 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, + 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266, + 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, + 0x4af10498, 0xf741ecda, 0xe7fcd50, 0x2f1791f6, + 0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, + 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551, + 0x49d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, + 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647, + 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, + 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, + 0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, + 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db, + 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, + 0x72161dc3, 0xcbce225, 0x8b283c49, 0x41ff0d95, + 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, + 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857 +}; + +static uint32_t U2[256] = { + 0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, + 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x3934be3, + 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, + 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, + 0x5a49deb1, 0x1b6725ba, 0xe9845ea, 0xc0e15dfe, + 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3, + 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, + 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9, + 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, + 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, + 0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, + 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908, + 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, + 0xd323ab73, 0x2e2724b, 0x8f57e31f, 0xab2a6655, + 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x8a5d337, + 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, + 0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, + 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6, + 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, + 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e, + 0x8af93e21, 0x63d96dd, 0x5aedd3e, 0xbd464de6, + 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, + 0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, + 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8, + 0xa47a17c, 0xfe97c42, 0x1ec9f884, 0x0, + 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a, + 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, + 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, + 0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, + 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12, + 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, + 0xd0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e, + 0x198557f1, 0x74caf75, 0xddbbee99, 0x60fda37f, + 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, + 0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, + 0xdccad731, 0x85104263, 0x22401397, 0x112084c6, + 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, + 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1, + 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, + 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, + 0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0xb3698d4, + 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad, + 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, + 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3, + 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, + 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, + 0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, + 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15, + 0x9bd9bae7, 0x36ce4a6f, 0x9d4ea9f, 0x7cd629b0, + 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2, + 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, + 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, + 0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x4dfe496, + 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665, + 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, + 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6, + 0x618c9ad7, 0xc7a37a1, 0x148e59f8, 0x3c89eb13, + 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, + 0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, + 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844, + 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, + 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d, + 0x17139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, + 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8 +}; + +static uint32_t U3[256] = { + 0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, + 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b, + 0x30fa5520, 0x766df6ad, 0xcc769188, 0x24c25f5, + 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, + 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, + 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, + 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, + 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e, + 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, + 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, + 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, + 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x82b94f9, + 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, + 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66, + 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, + 0x2887f230, 0xbfa5b223, 0x36aba02, 0x16825ced, + 0xcf1c2b8a, 0x79b492a7, 0x7f2f0f3, 0x69e2a14e, + 0xdaf4cd65, 0x5bed506, 0x34621fd1, 0xa6fe8ac4, + 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, + 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd, + 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, + 0x548db591, 0xc45d0571, 0x6d46f04, 0x5015ff60, + 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, + 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, + 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x0, + 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c, + 0xefffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, + 0xfd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, + 0xa67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, + 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, + 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, + 0x90d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814, + 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, + 0x1269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, + 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, + 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, + 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, + 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077, + 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, + 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, + 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, + 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, + 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, + 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582, + 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, + 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, + 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, + 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, + 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, + 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035, + 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, + 0x4984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, + 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, + 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, + 0x5eea049d, 0x8c355d01, 0x877473fa, 0xb412efb, + 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d, + 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, + 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, + 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, + 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, + 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, + 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0xd9541ff, + 0xa8017139, 0xcb3de08, 0xb4e49cd8, 0x56c19064, + 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0 +}; + +#endif + +/* + * the following tables (aes_sbox, aes_inv_sbox, T4, U4) are + * endian-neutral + */ + +static uint8_t +aes_sbox[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +}; + +#ifndef CPU_RISC +static uint8_t +aes_inv_sbox[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, + 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, + 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, + 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, + 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, + 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, + 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, + 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, + 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, + 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, + 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +}; +#endif /* ! CPU_RISC */ + +#ifdef CPU_RISC +static uint32_t +T4[256] = { + 0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b, + 0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5, + 0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b, + 0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676, + 0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d, + 0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0, + 0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf, + 0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0, + 0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626, + 0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc, + 0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1, + 0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515, + 0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3, + 0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a, + 0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2, + 0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575, + 0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a, + 0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0, + 0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3, + 0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484, + 0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed, + 0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b, + 0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939, + 0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf, + 0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb, + 0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585, + 0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f, + 0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8, + 0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f, + 0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5, + 0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121, + 0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2, + 0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec, + 0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717, + 0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d, + 0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373, + 0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc, + 0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888, + 0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414, + 0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb, + 0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a, + 0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c, + 0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262, + 0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979, + 0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d, + 0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9, + 0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea, + 0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808, + 0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e, + 0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6, + 0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f, + 0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a, + 0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666, + 0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e, + 0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9, + 0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e, + 0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111, + 0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494, + 0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9, + 0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf, + 0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d, + 0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868, + 0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f, + 0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616 +}; + +static uint32_t U4[256] = { + 0x52525252, 0x9090909, 0x6a6a6a6a, 0xd5d5d5d5, + 0x30303030, 0x36363636, 0xa5a5a5a5, 0x38383838, + 0xbfbfbfbf, 0x40404040, 0xa3a3a3a3, 0x9e9e9e9e, + 0x81818181, 0xf3f3f3f3, 0xd7d7d7d7, 0xfbfbfbfb, + 0x7c7c7c7c, 0xe3e3e3e3, 0x39393939, 0x82828282, + 0x9b9b9b9b, 0x2f2f2f2f, 0xffffffff, 0x87878787, + 0x34343434, 0x8e8e8e8e, 0x43434343, 0x44444444, + 0xc4c4c4c4, 0xdededede, 0xe9e9e9e9, 0xcbcbcbcb, + 0x54545454, 0x7b7b7b7b, 0x94949494, 0x32323232, + 0xa6a6a6a6, 0xc2c2c2c2, 0x23232323, 0x3d3d3d3d, + 0xeeeeeeee, 0x4c4c4c4c, 0x95959595, 0xb0b0b0b, + 0x42424242, 0xfafafafa, 0xc3c3c3c3, 0x4e4e4e4e, + 0x8080808, 0x2e2e2e2e, 0xa1a1a1a1, 0x66666666, + 0x28282828, 0xd9d9d9d9, 0x24242424, 0xb2b2b2b2, + 0x76767676, 0x5b5b5b5b, 0xa2a2a2a2, 0x49494949, + 0x6d6d6d6d, 0x8b8b8b8b, 0xd1d1d1d1, 0x25252525, + 0x72727272, 0xf8f8f8f8, 0xf6f6f6f6, 0x64646464, + 0x86868686, 0x68686868, 0x98989898, 0x16161616, + 0xd4d4d4d4, 0xa4a4a4a4, 0x5c5c5c5c, 0xcccccccc, + 0x5d5d5d5d, 0x65656565, 0xb6b6b6b6, 0x92929292, + 0x6c6c6c6c, 0x70707070, 0x48484848, 0x50505050, + 0xfdfdfdfd, 0xedededed, 0xb9b9b9b9, 0xdadadada, + 0x5e5e5e5e, 0x15151515, 0x46464646, 0x57575757, + 0xa7a7a7a7, 0x8d8d8d8d, 0x9d9d9d9d, 0x84848484, + 0x90909090, 0xd8d8d8d8, 0xabababab, 0x0, + 0x8c8c8c8c, 0xbcbcbcbc, 0xd3d3d3d3, 0xa0a0a0a, + 0xf7f7f7f7, 0xe4e4e4e4, 0x58585858, 0x5050505, + 0xb8b8b8b8, 0xb3b3b3b3, 0x45454545, 0x6060606, + 0xd0d0d0d0, 0x2c2c2c2c, 0x1e1e1e1e, 0x8f8f8f8f, + 0xcacacaca, 0x3f3f3f3f, 0xf0f0f0f, 0x2020202, + 0xc1c1c1c1, 0xafafafaf, 0xbdbdbdbd, 0x3030303, + 0x1010101, 0x13131313, 0x8a8a8a8a, 0x6b6b6b6b, + 0x3a3a3a3a, 0x91919191, 0x11111111, 0x41414141, + 0x4f4f4f4f, 0x67676767, 0xdcdcdcdc, 0xeaeaeaea, + 0x97979797, 0xf2f2f2f2, 0xcfcfcfcf, 0xcececece, + 0xf0f0f0f0, 0xb4b4b4b4, 0xe6e6e6e6, 0x73737373, + 0x96969696, 0xacacacac, 0x74747474, 0x22222222, + 0xe7e7e7e7, 0xadadadad, 0x35353535, 0x85858585, + 0xe2e2e2e2, 0xf9f9f9f9, 0x37373737, 0xe8e8e8e8, + 0x1c1c1c1c, 0x75757575, 0xdfdfdfdf, 0x6e6e6e6e, + 0x47474747, 0xf1f1f1f1, 0x1a1a1a1a, 0x71717171, + 0x1d1d1d1d, 0x29292929, 0xc5c5c5c5, 0x89898989, + 0x6f6f6f6f, 0xb7b7b7b7, 0x62626262, 0xe0e0e0e, + 0xaaaaaaaa, 0x18181818, 0xbebebebe, 0x1b1b1b1b, + 0xfcfcfcfc, 0x56565656, 0x3e3e3e3e, 0x4b4b4b4b, + 0xc6c6c6c6, 0xd2d2d2d2, 0x79797979, 0x20202020, + 0x9a9a9a9a, 0xdbdbdbdb, 0xc0c0c0c0, 0xfefefefe, + 0x78787878, 0xcdcdcdcd, 0x5a5a5a5a, 0xf4f4f4f4, + 0x1f1f1f1f, 0xdddddddd, 0xa8a8a8a8, 0x33333333, + 0x88888888, 0x7070707, 0xc7c7c7c7, 0x31313131, + 0xb1b1b1b1, 0x12121212, 0x10101010, 0x59595959, + 0x27272727, 0x80808080, 0xecececec, 0x5f5f5f5f, + 0x60606060, 0x51515151, 0x7f7f7f7f, 0xa9a9a9a9, + 0x19191919, 0xb5b5b5b5, 0x4a4a4a4a, 0xd0d0d0d, + 0x2d2d2d2d, 0xe5e5e5e5, 0x7a7a7a7a, 0x9f9f9f9f, + 0x93939393, 0xc9c9c9c9, 0x9c9c9c9c, 0xefefefef, + 0xa0a0a0a0, 0xe0e0e0e0, 0x3b3b3b3b, 0x4d4d4d4d, + 0xaeaeaeae, 0x2a2a2a2a, 0xf5f5f5f5, 0xb0b0b0b0, + 0xc8c8c8c8, 0xebebebeb, 0xbbbbbbbb, 0x3c3c3c3c, + 0x83838383, 0x53535353, 0x99999999, 0x61616161, + 0x17171717, 0x2b2b2b2b, 0x4040404, 0x7e7e7e7e, + 0xbabababa, 0x77777777, 0xd6d6d6d6, 0x26262626, + 0xe1e1e1e1, 0x69696969, 0x14141414, 0x63636363, + 0x55555555, 0x21212121, 0xc0c0c0c, 0x7d7d7d7d +}; +#endif /* CPU_RISC */ + + +/* aes internals */ + +extern debug_module_t mod_aes_icm; + +void +aes_expand_encryption_key(const v128_t *key, + aes_expanded_key_t expanded_key) { + int i; + gf2_8 rc; + + /* initialize round constant */ + rc = 1; + + expanded_key[0].v32[0] = key->v32[0]; + expanded_key[0].v32[1] = key->v32[1]; + expanded_key[0].v32[2] = key->v32[2]; + expanded_key[0].v32[3] = key->v32[3]; + +#if 0 + debug_print(mod_aes_icm, + "expanded key[0]: %s", v128_hex_string(&expanded_key[0])); +#endif + + /* loop over round keys */ + for (i=1; i < 11; i++) { + + /* munge first word of round key */ + expanded_key[i].v8[0] = aes_sbox[expanded_key[i-1].v8[13]] ^ rc; + expanded_key[i].v8[1] = aes_sbox[expanded_key[i-1].v8[14]]; + expanded_key[i].v8[2] = aes_sbox[expanded_key[i-1].v8[15]]; + expanded_key[i].v8[3] = aes_sbox[expanded_key[i-1].v8[12]]; + + expanded_key[i].v32[0] ^= expanded_key[i-1].v32[0]; + + /* set remaining 32 bit words to the exor of the one previous with + * the one four words previous */ + + expanded_key[i].v32[1] = + expanded_key[i].v32[0] ^ expanded_key[i-1].v32[1]; + + expanded_key[i].v32[2] = + expanded_key[i].v32[1] ^ expanded_key[i-1].v32[2]; + + expanded_key[i].v32[3] = + expanded_key[i].v32[2] ^ expanded_key[i-1].v32[3]; + +#if 0 + debug_print2(mod_aes_icm, + "expanded key[%d]: %s", i,v128_hex_string(&expanded_key[i])); +#endif + + /* modify round constant */ + rc = gf2_8_shift(rc); + + } +} + +void +aes_expand_decryption_key(const v128_t *key, + aes_expanded_key_t expanded_key) { + int i; + + aes_expand_encryption_key(key, expanded_key); + + /* invert the order of the round keys */ + for (i=0; i < 5; i++) { + v128_t tmp; + v128_copy(&tmp, &expanded_key[10-i]); + v128_copy(&expanded_key[10-i], &expanded_key[i]); + v128_copy(&expanded_key[i], &tmp); + } + + /* + * apply the inverse mixColumn transform to the round keys (except + * for the first and the last) + * + * mixColumn is implemented by using the tables U0, U1, U2, U3, + * followed by the T4 table (which cancels out the use of the sbox + * in the U-tables) + */ + for (i=1; i < 10; i++) { +#ifdef CPU_RISC + uint32_t tmp; + + tmp = expanded_key[i].v32[0]; + expanded_key[i].v32[0] = + U0[T4[(tmp >> 24) ] & 0xff] ^ + U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ + U2[T4[(tmp >> 8) & 0xff] & 0xff] ^ + U3[T4[(tmp) & 0xff] & 0xff]; + + tmp = expanded_key[i].v32[1]; + expanded_key[i].v32[1] = + U0[T4[(tmp >> 24) ] & 0xff] ^ + U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ + U2[T4[(tmp >> 8) & 0xff] & 0xff] ^ + U3[T4[(tmp) & 0xff] & 0xff]; + + tmp = expanded_key[i].v32[2]; + expanded_key[i].v32[2] = + U0[T4[(tmp >> 24) ] & 0xff] ^ + U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ + U2[T4[(tmp >> 8) & 0xff] & 0xff] ^ + U3[T4[(tmp) & 0xff] & 0xff]; + + tmp = expanded_key[i].v32[3]; + expanded_key[i].v32[3] = + U0[T4[(tmp >> 24) ] & 0xff] ^ + U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ + U2[T4[(tmp >> 8) & 0xff] & 0xff] ^ + U3[T4[(tmp) & 0xff] & 0xff]; +#else /* assume CPU_CISC */ + + uint32_t c0, c1, c2, c3; + + c0 = U0[aes_sbox[expanded_key[i].v8[0]]] + ^ U1[aes_sbox[expanded_key[i].v8[1]]] + ^ U2[aes_sbox[expanded_key[i].v8[2]]] + ^ U3[aes_sbox[expanded_key[i].v8[3]]]; + + c1 = U0[aes_sbox[expanded_key[i].v8[4]]] + ^ U1[aes_sbox[expanded_key[i].v8[5]]] + ^ U2[aes_sbox[expanded_key[i].v8[6]]] + ^ U3[aes_sbox[expanded_key[i].v8[7]]]; + + c2 = U0[aes_sbox[expanded_key[i].v8[8]]] + ^ U1[aes_sbox[expanded_key[i].v8[9]]] + ^ U2[aes_sbox[expanded_key[i].v8[10]]] + ^ U3[aes_sbox[expanded_key[i].v8[11]]]; + + c3 = U0[aes_sbox[expanded_key[i].v8[12]]] + ^ U1[aes_sbox[expanded_key[i].v8[13]]] + ^ U2[aes_sbox[expanded_key[i].v8[14]]] + ^ U3[aes_sbox[expanded_key[i].v8[15]]]; + + expanded_key[i].v32[0] = c0; + expanded_key[i].v32[1] = c1; + expanded_key[i].v32[2] = c2; + expanded_key[i].v32[3] = c3; + +#endif + } +} + +#ifdef CPU_CISC + + +static inline void +aes_round(v128_t *state, const v128_t *round_key) { + uint32_t column0, column1, column2, column3; + + /* compute the columns of the output square in terms of the octets + of state, using the tables T0, T1, T2, T3 */ + + column0 = T0[state->v8[0]] ^ T1[state->v8[5]] + ^ T2[state->v8[10]] ^ T3[state->v8[15]]; + + column1 = T0[state->v8[4]] ^ T1[state->v8[9]] + ^ T2[state->v8[14]] ^ T3[state->v8[3]]; + + column2 = T0[state->v8[8]] ^ T1[state->v8[13]] + ^ T2[state->v8[2]] ^ T3[state->v8[7]]; + + column3 = T0[state->v8[12]] ^ T1[state->v8[1]] + ^ T2[state->v8[6]] ^ T3[state->v8[11]]; + + state->v32[0] = column0 ^ round_key->v32[0]; + state->v32[1] = column1 ^ round_key->v32[1]; + state->v32[2] = column2 ^ round_key->v32[2]; + state->v32[3] = column3 ^ round_key->v32[3]; + +} + + +static inline void +aes_inv_round(v128_t *state, const v128_t *round_key) { + uint32_t column0, column1, column2, column3; + + /* compute the columns of the output square in terms of the octets + of state, using the tables U0, U1, U2, U3 */ + + column0 = U0[state->v8[0]] ^ U1[state->v8[13]] + ^ U2[state->v8[10]] ^ U3[state->v8[7]]; + + column1 = U0[state->v8[4]] ^ U1[state->v8[1]] + ^ U2[state->v8[14]] ^ U3[state->v8[11]]; + + column2 = U0[state->v8[8]] ^ U1[state->v8[5]] + ^ U2[state->v8[2]] ^ U3[state->v8[15]]; + + column3 = U0[state->v8[12]] ^ U1[state->v8[9]] + ^ U2[state->v8[6]] ^ U3[state->v8[3]]; + + state->v32[0] = column0 ^ round_key->v32[0]; + state->v32[1] = column1 ^ round_key->v32[1]; + state->v32[2] = column2 ^ round_key->v32[2]; + state->v32[3] = column3 ^ round_key->v32[3]; + +} + +static inline void +aes_final_round(v128_t *state, const v128_t *round_key) { + uint8_t tmp; + + /* byte substitutions and row shifts */ + /* first row - no shift */ + state->v8[0] = aes_sbox[state->v8[0]]; + state->v8[4] = aes_sbox[state->v8[4]]; + state->v8[8] = aes_sbox[state->v8[8]]; + state->v8[12] = aes_sbox[state->v8[12]]; + + /* second row - shift one left */ + tmp = aes_sbox[state->v8[1]]; + state->v8[1] = aes_sbox[state->v8[5]]; + state->v8[5] = aes_sbox[state->v8[9]]; + state->v8[9] = aes_sbox[state->v8[13]]; + state->v8[13] = tmp; + + /* third row - shift two left */ + tmp = aes_sbox[state->v8[10]]; + state->v8[10] = aes_sbox[state->v8[2]]; + state->v8[2] = tmp; + tmp = aes_sbox[state->v8[14]]; + state->v8[14] = aes_sbox[state->v8[6]]; + state->v8[6] = tmp; + + /* fourth row - shift three left */ + tmp = aes_sbox[state->v8[15]]; + state->v8[15] = aes_sbox[state->v8[11]]; + state->v8[11] = aes_sbox[state->v8[7]]; + state->v8[7] = aes_sbox[state->v8[3]]; + state->v8[3] = tmp; + + v128_xor_eq(state, round_key); +} + +static inline void +aes_inv_final_round(v128_t *state, const v128_t *round_key) { + uint8_t tmp; + + /* byte substitutions and row shifts */ + /* first row - no shift */ + state->v8[0] = aes_inv_sbox[state->v8[0]]; + state->v8[4] = aes_inv_sbox[state->v8[4]]; + state->v8[8] = aes_inv_sbox[state->v8[8]]; + state->v8[12] = aes_inv_sbox[state->v8[12]]; + + /* second row - shift one right */ + tmp = aes_inv_sbox[state->v8[13]]; + state->v8[13] = aes_inv_sbox[state->v8[9]]; + state->v8[9] = aes_inv_sbox[state->v8[5]]; + state->v8[5] = aes_inv_sbox[state->v8[1]]; + state->v8[1] = tmp; + + /* third row - shift two right */ + tmp = aes_inv_sbox[state->v8[2]]; + state->v8[2] = aes_inv_sbox[state->v8[10]]; + state->v8[10] = tmp; + tmp = aes_inv_sbox[state->v8[6]]; + state->v8[6] = aes_inv_sbox[state->v8[14]]; + state->v8[14] = tmp; + + /* fourth row - shift three right */ + tmp = aes_inv_sbox[state->v8[3]]; + state->v8[3] = aes_inv_sbox[state->v8[7]]; + state->v8[7] = aes_inv_sbox[state->v8[11]]; + state->v8[11] = aes_inv_sbox[state->v8[15]]; + state->v8[15] = tmp; + + v128_xor_eq(state, round_key); +} + + +#elif CPU_RISC + +static inline void +aes_round(v128_t *state, const v128_t *round_key) { + uint32_t column0, column1, column2, column3; + + /* compute the columns of the output square in terms of the octets + of state, using the tables T0, T1, T2, T3 */ +#ifdef WORDS_BIGENDIAN + column0 = T0[state->v32[0] >> 24] ^ T1[(state->v32[1] >> 16) & 0xff] + ^ T2[(state->v32[2] >> 8) & 0xff] ^ T3[state->v32[3] & 0xff]; + + column1 = T0[state->v32[1] >> 24] ^ T1[(state->v32[2] >> 16) & 0xff] + ^ T2[(state->v32[3] >> 8) & 0xff] ^ T3[state->v32[0] & 0xff]; + + column2 = T0[state->v32[2] >> 24] ^ T1[(state->v32[3] >> 16) & 0xff] + ^ T2[(state->v32[0] >> 8) & 0xff] ^ T3[state->v32[1] & 0xff]; + + column3 = T0[state->v32[3] >> 24] ^ T1[(state->v32[0] >> 16) & 0xff] + ^ T2[(state->v32[1] >> 8) & 0xff] ^ T3[state->v32[2] & 0xff]; +#else + column0 = T0[state->v32[0] & 0xff] ^ T1[(state->v32[1] >> 8) & 0xff] + ^ T2[(state->v32[2] >> 16) & 0xff] ^ T3[state->v32[3] >> 24]; + + column1 = T0[state->v32[1] & 0xff] ^ T1[(state->v32[2] >> 8) & 0xff] + ^ T2[(state->v32[3] >> 16) & 0xff] ^ T3[state->v32[0] >> 24]; + + column2 = T0[state->v32[2] & 0xff] ^ T1[(state->v32[3] >> 8) & 0xff] + ^ T2[(state->v32[0] >> 16) & 0xff] ^ T3[state->v32[1] >> 24]; + + column3 = T0[state->v32[3] & 0xff] ^ T1[(state->v32[0] >> 8) & 0xff] + ^ T2[(state->v32[1] >> 16) & 0xff] ^ T3[state->v32[2] >> 24]; +#endif /* WORDS_BIGENDIAN */ + + state->v32[0] = column0 ^ round_key->v32[0]; + state->v32[1] = column1 ^ round_key->v32[1]; + state->v32[2] = column2 ^ round_key->v32[2]; + state->v32[3] = column3 ^ round_key->v32[3]; + +} + +static inline void +aes_inv_round(v128_t *state, const v128_t *round_key) { + uint32_t column0, column1, column2, column3; + + /* compute the columns of the output square in terms of the octets + of state, using the tables U0, U1, U2, U3 */ + +#ifdef WORDS_BIGENDIAN + /* FIX! WRong indexes */ + column0 = U0[state->v32[0] >> 24] ^ U1[(state->v32[3] >> 16) & 0xff] + ^ U2[(state->v32[2] >> 8) & 0xff] ^ U3[state->v32[1] & 0xff]; + + column1 = U0[state->v32[1] >> 24] ^ U1[(state->v32[0] >> 16) & 0xff] + ^ U2[(state->v32[3] >> 8) & 0xff] ^ U3[state->v32[2] & 0xff]; + + column2 = U0[state->v32[2] >> 24] ^ U1[(state->v32[1] >> 16) & 0xff] + ^ U2[(state->v32[0] >> 8) & 0xff] ^ U3[state->v32[3] & 0xff]; + + column3 = U0[state->v32[3] >> 24] ^ U1[(state->v32[2] >> 16) & 0xff] + ^ U2[(state->v32[1] >> 8) & 0xff] ^ U3[state->v32[0] & 0xff]; +#else + column0 = U0[state->v32[0] & 0xff] ^ U1[(state->v32[1] >> 8) & 0xff] + ^ U2[(state->v32[2] >> 16) & 0xff] ^ U3[state->v32[3] >> 24]; + + column1 = U0[state->v32[1] & 0xff] ^ U1[(state->v32[2] >> 8) & 0xff] + ^ U2[(state->v32[3] >> 16) & 0xff] ^ U3[state->v32[0] >> 24]; + + column2 = U0[state->v32[2] & 0xff] ^ U1[(state->v32[3] >> 8) & 0xff] + ^ U2[(state->v32[0] >> 16) & 0xff] ^ U3[state->v32[1] >> 24]; + + column3 = U0[state->v32[3] & 0xff] ^ U1[(state->v32[0] >> 8) & 0xff] + ^ U2[(state->v32[1] >> 16) & 0xff] ^ U3[state->v32[2] >> 24]; +#endif /* WORDS_BIGENDIAN */ + + state->v32[0] = column0 ^ round_key->v32[0]; + state->v32[1] = column1 ^ round_key->v32[1]; + state->v32[2] = column2 ^ round_key->v32[2]; + state->v32[3] = column3 ^ round_key->v32[3]; + +} + +static inline void +aes_final_round(v128_t *state, const v128_t *round_key) { + uint32_t tmp0, tmp1, tmp2, tmp3; + + tmp0 = (T4[(state->v32[0] >> 24)] & 0xff000000) + ^ (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) + ^ (T4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00) + ^ (T4[(state->v32[3] ) & 0xff] & 0x000000ff) + ^ round_key->v32[0]; + + tmp1 = (T4[(state->v32[1] >> 24)] & 0xff000000) + ^ (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) + ^ (T4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00) + ^ (T4[(state->v32[0] ) & 0xff] & 0x000000ff) + ^ round_key->v32[1]; + + tmp2 = (T4[(state->v32[2] >> 24)] & 0xff000000) + ^ (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) + ^ (T4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00) + ^ (T4[(state->v32[1] ) & 0xff] & 0x000000ff) + ^ round_key->v32[2]; + + tmp3 = (T4[(state->v32[3] >> 24)] & 0xff000000) + ^ (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) + ^ (T4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00) + ^ (T4[(state->v32[2] ) & 0xff] & 0x000000ff) + ^ round_key->v32[3]; + + state->v32[0] = tmp0; + state->v32[1] = tmp1; + state->v32[2] = tmp2; + state->v32[3] = tmp3; + +} + +static inline void +aes_inv_final_round(v128_t *state, const v128_t *round_key) { + uint32_t tmp0, tmp1, tmp2, tmp3; + + tmp0 = (U4[(state->v32[0] >> 24)] & 0xff000000) + ^ (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) + ^ (U4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00) + ^ (U4[(state->v32[1] ) & 0xff] & 0x000000ff) + ^ round_key->v32[0]; + + tmp1 = (U4[(state->v32[1] >> 24)] & 0xff000000) + ^ (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) + ^ (U4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00) + ^ (U4[(state->v32[2] ) & 0xff] & 0x000000ff) + ^ round_key->v32[1]; + + tmp2 = (U4[(state->v32[2] >> 24)] & 0xff000000) + ^ (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) + ^ (U4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00) + ^ (U4[(state->v32[3] ) & 0xff] & 0x000000ff) + ^ round_key->v32[2]; + + tmp3 = (U4[(state->v32[3] >> 24)] & 0xff000000) + ^ (U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) + ^ (U4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00) + ^ (U4[(state->v32[0] ) & 0xff] & 0x000000ff) + ^ round_key->v32[3]; + + state->v32[0] = tmp0; + state->v32[1] = tmp1; + state->v32[2] = tmp2; + state->v32[3] = tmp3; + +} + +#elif CPU_16 /* assume 16-bit word size on processor */ + +static inline void +aes_round(v128_t *state, const v128_t *round_key) { + uint32_t column0, column1, column2, column3; + uint16_t c + /* compute the columns of the output square in terms of the octets + of state, using the tables T0, T1, T2, T3 */ + + column0 = T0[state->v8[0]] ^ T1[state->v8[5]] + ^ T2[state->v8[10]] ^ T3[state->v8[15]]; + + column1 = T0[state->v8[4]] ^ T1[state->v8[9]] + ^ T2[state->v8[14]] ^ T3[state->v8[3]]; + + column2 = T0[state->v8[8]] ^ T1[state->v8[13]] + ^ T2[state->v8[2]] ^ T3[state->v8[7]]; + + column3 = T0[state->v8[12]] ^ T1[state->v8[1]] + ^ T2[state->v8[6]] ^ T3[state->v8[11]]; + + state->v32[0] = column0 ^ round_key->v32[0]; + state->v32[1] = column1 ^ round_key->v32[1]; + state->v32[2] = column2 ^ round_key->v32[2]; + state->v32[3] = column3 ^ round_key->v32[3]; + +} + + +static inline void +aes_inv_round(v128_t *state, const v128_t *round_key) { + uint32_t column0, column1, column2, column3; + + /* compute the columns of the output square in terms of the octets + of state, using the tables U0, U1, U2, U3 */ + + column0 = U0[state->v8[0]] ^ U1[state->v8[5]] + ^ U2[state->v8[10]] ^ U3[state->v8[15]]; + + column1 = U0[state->v8[4]] ^ U1[state->v8[9]] + ^ U2[state->v8[14]] ^ U3[state->v8[3]]; + + column2 = U0[state->v8[8]] ^ U1[state->v8[13]] + ^ U2[state->v8[2]] ^ U3[state->v8[7]]; + + column3 = U0[state->v8[12]] ^ U1[state->v8[1]] + ^ U2[state->v8[6]] ^ U3[state->v8[11]]; + + state->v32[0] = column0 ^ round_key->v32[0]; + state->v32[1] = column1 ^ round_key->v32[1]; + state->v32[2] = column2 ^ round_key->v32[2]; + state->v32[3] = column3 ^ round_key->v32[3]; + +} + +static inline void +aes_final_round(v128_t *state, const v128_t *round_key) { + uint8_t tmp; + + /* byte substitutions and row shifts */ + /* first row - no shift */ + state->v8[0] = aes_sbox[state->v8[0]]; + state->v8[4] = aes_sbox[state->v8[4]]; + state->v8[8] = aes_sbox[state->v8[8]]; + state->v8[12] = aes_sbox[state->v8[12]]; + + /* second row - shift one left */ + tmp = aes_sbox[state->v8[1]]; + state->v8[1] = aes_sbox[state->v8[5]]; + state->v8[5] = aes_sbox[state->v8[9]]; + state->v8[9] = aes_sbox[state->v8[13]]; + state->v8[13] = tmp; + + /* third row - shift two left */ + tmp = aes_sbox[state->v8[10]]; + state->v8[10] = aes_sbox[state->v8[2]]; + state->v8[2] = tmp; + tmp = aes_sbox[state->v8[14]]; + state->v8[14] = aes_sbox[state->v8[6]]; + state->v8[6] = tmp; + + /* fourth row - shift three left */ + tmp = aes_sbox[state->v8[15]]; + state->v8[15] = aes_sbox[state->v8[11]]; + state->v8[11] = aes_sbox[state->v8[7]]; + state->v8[7] = aes_sbox[state->v8[3]]; + state->v8[3] = tmp; + + v128_xor_eq(state, round_key); +} + +static inline void +aes_inv_final_round(v128_t *state, const v128_t *round_key) { + uint8_t tmp; + + /* byte substitutions and row shifts */ + /* first row - no shift */ + state->v8[0] = aes_inv_sbox[state->v8[0]]; + state->v8[4] = aes_inv_sbox[state->v8[4]]; + state->v8[8] = aes_inv_sbox[state->v8[8]]; + state->v8[12] = aes_inv_sbox[state->v8[12]]; + + /* second row - shift one left */ + tmp = aes_inv_sbox[state->v8[1]]; + state->v8[1] = aes_inv_sbox[state->v8[5]]; + state->v8[5] = aes_inv_sbox[state->v8[9]]; + state->v8[9] = aes_inv_sbox[state->v8[13]]; + state->v8[13] = tmp; + + /* third row - shift two left */ + tmp = aes_inv_sbox[state->v8[10]]; + state->v8[10] = aes_inv_sbox[state->v8[2]]; + state->v8[2] = tmp; + tmp = aes_inv_sbox[state->v8[14]]; + state->v8[14] = aes_inv_sbox[state->v8[6]]; + state->v8[6] = tmp; + + /* fourth row - shift three left */ + tmp = aes_inv_sbox[state->v8[15]]; + state->v8[15] = aes_inv_sbox[state->v8[11]]; + state->v8[11] = aes_inv_sbox[state->v8[7]]; + state->v8[7] = aes_inv_sbox[state->v8[3]]; + state->v8[3] = tmp; + + v128_xor_eq(state, round_key); +} + +#endif /* CPU type */ + + +void +aes_encrypt(v128_t *plaintext, const aes_expanded_key_t exp_key) { + + /* add in the subkey */ + v128_xor_eq(plaintext, exp_key + 0); + + /* now do nine rounds */ + aes_round(plaintext, exp_key + 1); + aes_round(plaintext, exp_key + 2); + aes_round(plaintext, exp_key + 3); + aes_round(plaintext, exp_key + 4); + aes_round(plaintext, exp_key + 5); + aes_round(plaintext, exp_key + 6); + aes_round(plaintext, exp_key + 7); + aes_round(plaintext, exp_key + 8); + aes_round(plaintext, exp_key + 9); + /* the last round is different */ + + aes_final_round(plaintext, exp_key + 10); +} + +void +aes_decrypt(v128_t *plaintext, const aes_expanded_key_t exp_key) { + + /* add in the subkey */ + v128_xor_eq(plaintext, exp_key + 0); + + /* now do nine rounds */ + aes_inv_round(plaintext, exp_key + 1); + aes_inv_round(plaintext, exp_key + 2); + aes_inv_round(plaintext, exp_key + 3); + aes_inv_round(plaintext, exp_key + 4); + aes_inv_round(plaintext, exp_key + 5); + aes_inv_round(plaintext, exp_key + 6); + aes_inv_round(plaintext, exp_key + 7); + aes_inv_round(plaintext, exp_key + 8); + aes_inv_round(plaintext, exp_key + 9); + /* the last round is different */ + aes_inv_final_round(plaintext, exp_key + 10); +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/cipher/aes_cbc.c b/src/libs/resiprocate/contrib/srtp/crypto/cipher/aes_cbc.c new file mode 100644 index 00000000..8fc6a327 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/cipher/aes_cbc.c @@ -0,0 +1,444 @@ +/* + * aes_cbc.c + * + * AES Cipher Block Chaining Mode + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "aes_cbc.h" +#include "alloc.h" + +debug_module_t mod_aes_cbc = { + 0, /* debugging is off by default */ + "aes cbc" /* printable module name */ +}; + + + +err_status_t +aes_cbc_alloc(cipher_t **c, int key_len) { + extern cipher_type_t aes_cbc; + uint8_t *pointer; + int tmp; + + debug_print(mod_aes_cbc, + "allocating cipher with key length %d", key_len); + + if (key_len != 16) + return err_status_bad_param; + + /* allocate memory a cipher of type aes_icm */ + tmp = (sizeof(aes_cbc_ctx_t) + sizeof(cipher_t)); + pointer = (uint8_t*)crypto_alloc(tmp); + if (pointer == NULL) + return err_status_alloc_fail; + + /* set pointers */ + *c = (cipher_t *)pointer; + (*c)->type = &aes_cbc; + (*c)->state = pointer + sizeof(cipher_t); + + /* increment ref_count */ + aes_cbc.ref_count++; + + /* set key size */ + (*c)->key_len = key_len; + + return err_status_ok; +} + +err_status_t +aes_cbc_dealloc(cipher_t *c) { + extern cipher_type_t aes_cbc; + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t *)c, + sizeof(aes_cbc_ctx_t) + sizeof(cipher_t)); + + /* free memory */ + crypto_free(c); + + /* decrement ref_count */ + aes_cbc.ref_count--; + + return err_status_ok; +} + +err_status_t +aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, + cipher_direction_t dir) { + v128_t tmp_key; + + /* set tmp_key (for alignment) */ + v128_copy_octet_string(&tmp_key, key); + + debug_print(mod_aes_cbc, + "key: %s", v128_hex_string(&tmp_key)); + + /* expand key for the appropriate direction */ + switch (dir) { + case (direction_encrypt): + aes_expand_encryption_key(&tmp_key, c->expanded_key); + break; + case (direction_decrypt): + aes_expand_decryption_key(&tmp_key, c->expanded_key); + break; + default: + return err_status_bad_param; + } + + + return err_status_ok; +} + + +err_status_t +aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv) { + int i; +/* v128_t *input = iv; */ + uint8_t *input = (uint8_t*) iv; + + /* set state and 'previous' block to iv */ + for (i=0; i < 16; i++) + c->previous.v8[i] = c->state.v8[i] = input[i]; + + debug_print(mod_aes_cbc, "setting iv: %s", v128_hex_string(&c->state)); + + return err_status_ok; +} + +err_status_t +aes_cbc_encrypt(aes_cbc_ctx_t *c, + unsigned char *data, + unsigned int *bytes_in_data) { + int i; + unsigned char *input = data; /* pointer to data being read */ + unsigned char *output = data; /* pointer to data being written */ + int bytes_to_encr = *bytes_in_data; + + /* + * verify that we're 16-octet aligned + */ + if (*bytes_in_data & 0xf) + return err_status_bad_param; + + /* + * note that we assume that the initialization vector has already + * been set, e.g. by calling aes_cbc_set_iv() + */ + debug_print(mod_aes_cbc, "iv: %s", + v128_hex_string(&c->state)); + + /* + * loop over plaintext blocks, exoring state into plaintext then + * encrypting and writing to output + */ + while (bytes_to_encr > 0) { + + /* exor plaintext into state */ + for (i=0; i < 16; i++) + c->state.v8[i] ^= *input++; + + debug_print(mod_aes_cbc, "inblock: %s", + v128_hex_string(&c->state)); + + aes_encrypt(&c->state, c->expanded_key); + + debug_print(mod_aes_cbc, "outblock: %s", + v128_hex_string(&c->state)); + + /* copy ciphertext to output */ + for (i=0; i < 16; i++) + *output++ = c->state.v8[i]; + + bytes_to_encr -= 16; + } + + return err_status_ok; +} + +err_status_t +aes_cbc_decrypt(aes_cbc_ctx_t *c, + unsigned char *data, + unsigned int *bytes_in_data) { + int i; + v128_t state, previous; + unsigned char *input = data; /* pointer to data being read */ + unsigned char *output = data; /* pointer to data being written */ + int bytes_to_encr = *bytes_in_data; + uint8_t tmp; + + /* + * verify that we're 16-octet aligned + */ + if (*bytes_in_data & 0x0f) + return err_status_bad_param; + + /* set 'previous' block to iv*/ + for (i=0; i < 16; i++) { + previous.v8[i] = c->previous.v8[i]; + } + + debug_print(mod_aes_cbc, "iv: %s", + v128_hex_string(&previous)); + + /* + * loop over ciphertext blocks, decrypting then exoring with state + * then writing plaintext to output + */ + while (bytes_to_encr > 0) { + + /* set state to ciphertext input block */ + for (i=0; i < 16; i++) { + state.v8[i] = *input++; + } + + debug_print(mod_aes_cbc, "inblock: %s", + v128_hex_string(&state)); + + /* decrypt state */ + aes_decrypt(&state, c->expanded_key); + + debug_print(mod_aes_cbc, "outblock: %s", + v128_hex_string(&state)); + + /* + * exor previous ciphertext block out of plaintext, and write new + * plaintext block to output, while copying old ciphertext block + * to the 'previous' block + */ + for (i=0; i < 16; i++) { + tmp = *output; + *output++ = state.v8[i] ^ previous.v8[i]; + previous.v8[i] = tmp; + } + + bytes_to_encr -= 16; + } + + return err_status_ok; +} + + +err_status_t +aes_cbc_nist_encrypt(aes_cbc_ctx_t *c, + unsigned char *data, + unsigned int *bytes_in_data) { + int i; + unsigned char *pad_start; + int num_pad_bytes; + err_status_t status; + + /* + * determine the number of padding bytes that we need to add - + * this value is always between 1 and 16, inclusive. + */ + num_pad_bytes = 16 - (*bytes_in_data & 0xf); + pad_start = data; + pad_start += *bytes_in_data; + *pad_start++ = 0xa0; + for (i=0; i < num_pad_bytes; i++) + *pad_start++ = 0x00; + + /* + * increment the data size + */ + *bytes_in_data += num_pad_bytes; + + /* + * now cbc encrypt the padded data + */ + status = aes_cbc_encrypt(c, data, bytes_in_data); + if (status) + return status; + + return err_status_ok; +} + + +err_status_t +aes_cbc_nist_decrypt(aes_cbc_ctx_t *c, + unsigned char *data, + unsigned int *bytes_in_data) { + unsigned char *pad_end; + int num_pad_bytes; + err_status_t status; + + /* + * cbc decrypt the padded data + */ + status = aes_cbc_decrypt(c, data, bytes_in_data); + if (status) + return status; + + /* + * determine the number of padding bytes in the decrypted plaintext + * - this value is always between 1 and 16, inclusive. + */ + num_pad_bytes = 1; + pad_end = data + (*bytes_in_data - 1); + while (*pad_end != 0xa0) { /* note: should check padding correctness */ + pad_end--; + num_pad_bytes++; + } + + /* decrement data size */ + *bytes_in_data -= num_pad_bytes; + + return err_status_ok; +} + + +char +aes_cbc_description[] = "aes cipher block chaining (cbc) mode"; + +/* + * Test case 0 is derived from FIPS 197 Appendix A; it uses an + * all-zero IV, so that the first block encryption matches the test + * case in that appendix. This property provides a check of the base + * AES encryption and decryption algorithms; if CBC fails on some + * particular platform, then you should print out AES intermediate + * data and compare with the detailed info provided in that appendix. + * + */ + + +uint8_t aes_cbc_test_case_0_key[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f +}; + +uint8_t aes_cbc_test_case_0_plaintext[64] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff +}; + +uint8_t aes_cbc_test_case_0_ciphertext[80] = { + 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a, + 0x03, 0x35, 0xed, 0x27, 0x67, 0xf2, 0x6d, 0xf1, + 0x64, 0x83, 0x2e, 0x23, 0x44, 0x38, 0x70, 0x8b + +}; + +uint8_t aes_cbc_test_case_0_iv[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + +cipher_test_case_t aes_cbc_test_case_0 = { + 16, /* octets in key */ + aes_cbc_test_case_0_key, /* key */ + aes_cbc_test_case_0_iv, /* initialization vector */ + 16, /* octets in plaintext */ + aes_cbc_test_case_0_plaintext, /* plaintext */ + 32, /* octets in ciphertext */ + aes_cbc_test_case_0_ciphertext, /* ciphertext */ + NULL /* pointer to next testcase */ +}; + + +/* + * this test case is taken directly from Appendix F.2 of NIST Special + * Publication SP 800-38A + */ + +uint8_t aes_cbc_test_case_1_key[16] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +uint8_t aes_cbc_test_case_1_plaintext[64] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 +}; + +uint8_t aes_cbc_test_case_1_ciphertext[80] = { + 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, + 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, + 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, + 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, + 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, + 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, + 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, + 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7, + 0x39, 0x34, 0x07, 0x03, 0x36, 0xd0, 0x77, 0x99, + 0xe0, 0xc4, 0x2f, 0xdd, 0xa8, 0xdf, 0x4c, 0xa3 +}; + +uint8_t aes_cbc_test_case_1_iv[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f +}; + +cipher_test_case_t aes_cbc_test_case_1 = { + 16, /* octets in key */ + aes_cbc_test_case_1_key, /* key */ + aes_cbc_test_case_1_iv, /* initialization vector */ + 64, /* octets in plaintext */ + aes_cbc_test_case_1_plaintext, /* plaintext */ + 80, /* octets in ciphertext */ + aes_cbc_test_case_1_ciphertext, /* ciphertext */ + &aes_cbc_test_case_0 /* pointer to next testcase */ +}; + +cipher_type_t aes_cbc = { + (cipher_alloc_func_t) aes_cbc_alloc, + (cipher_dealloc_func_t) aes_cbc_dealloc, + (cipher_init_func_t) aes_cbc_context_init, + (cipher_encrypt_func_t) aes_cbc_nist_encrypt, + (cipher_decrypt_func_t) aes_cbc_nist_decrypt, + (cipher_set_iv_func_t) aes_cbc_set_iv, + (char *) aes_cbc_description, + (int) 0, /* instance count */ + (cipher_test_case_t *) &aes_cbc_test_case_0, + (debug_module_t *) &mod_aes_cbc +}; + + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/cipher/aes_icm.c b/src/libs/resiprocate/contrib/srtp/crypto/cipher/aes_icm.c new file mode 100644 index 00000000..b466ca9a --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/cipher/aes_icm.c @@ -0,0 +1,511 @@ +/* + * aes_icm.c + * + * AES Integer Counter Mode + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#define ALIGN_32 0 + +#include "aes_icm.h" +#include "alloc.h" + + +debug_module_t mod_aes_icm = { + 0, /* debugging is off by default */ + "aes icm" /* printable module name */ +}; + +/* + * integer counter mode works as follows: + * + * 16 bits + * <-----> + * +------+------+------+------+------+------+------+------+ + * | nonce | pakcet index | ctr |---+ + * +------+------+------+------+------+------+------+------+ | + * | + * +------+------+------+------+------+------+------+------+ v + * | salt |000000|->(+) + * +------+------+------+------+------+------+------+------+ | + * | + * +---------+ + * | encrypt | + * +---------+ + * | + * +------+------+------+------+------+------+------+------+ | + * | keystream block |<--+ + * +------+------+------+------+------+------+------+------+ + * + * All fields are big-endian + * + * ctr is the block counter, which increments from zero for + * each packet (16 bits wide) + * + * packet index is distinct for each packet (48 bits wide) + * + * nonce can be distinct across many uses of the same key, or + * can be a fixed value per key, or can be per-packet randomness + * (64 bits) + * + */ + +err_status_t +aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) { + extern cipher_type_t aes_icm; + uint8_t *pointer; + int tmp; + + debug_print(mod_aes_icm, + "allocating cipher with key length %d", key_len); + + /* + * Ismacryp, for example, uses 16 byte key + 8 byte + * salt so this function is called with key_len = 24. + * The check for key_len = 30 does not apply. Our usage + * of aes functions with key_len = values other than 30 + * has not broken anything. Don't know what would be the + * effect of skipping this check for srtp in general. + */ + if (!forIsmacryp && key_len != 30) + return err_status_bad_param; + + /* allocate memory a cipher of type aes_icm */ + tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t)); + pointer = (uint8_t*)crypto_alloc(tmp); + if (pointer == NULL) + return err_status_alloc_fail; + + /* set pointers */ + *c = (cipher_t *)pointer; + (*c)->type = &aes_icm; + (*c)->state = pointer + sizeof(cipher_t); + + /* increment ref_count */ + aes_icm.ref_count++; + + /* set key size */ + (*c)->key_len = key_len; + + return err_status_ok; +} + +err_status_t aes_icm_alloc(cipher_t **c, int key_len, int forIsmacryp) { + return aes_icm_alloc_ismacryp(c, key_len, 0); +} + +err_status_t +aes_icm_dealloc(cipher_t *c) { + extern cipher_type_t aes_icm; + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t *)c, + sizeof(aes_icm_ctx_t) + sizeof(cipher_t)); + + /* free memory */ + crypto_free(c); + + /* decrement ref_count */ + aes_icm.ref_count--; + + return err_status_ok; +} + + +/* + * aes_icm_context_init(...) initializes the aes_icm_context + * using the value in key[]. + * + * the key is the secret key + * + * the salt is unpredictable (but not necessarily secret) data which + * randomizes the starting point in the keystream + */ + +err_status_t +aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key) { + v128_t tmp_key; + + /* set counter and initial values to 'offset' value */ + /* FIX!!! this assumes the salt is at key + 16, and thus that the */ + /* FIX!!! cipher key length is 16! Also note this copies past the + end of the 'key' array by 2 bytes! */ + v128_copy_octet_string(&c->counter, key + 16); + v128_copy_octet_string(&c->offset, key + 16); + + /* force last two octets of the offset to zero (for srtp compatibility) */ + c->offset.v8[14] = c->offset.v8[15] = 0; + c->counter.v8[14] = c->counter.v8[15] = 0; + + /* set tmp_key (for alignment) */ + v128_copy_octet_string(&tmp_key, key); + + debug_print(mod_aes_icm, + "key: %s", v128_hex_string(&tmp_key)); + debug_print(mod_aes_icm, + "offset: %s", v128_hex_string(&c->offset)); + + /* expand key */ + aes_expand_encryption_key(&tmp_key, c->expanded_key); + + /* indicate that the keystream_buffer is empty */ + c->bytes_in_buffer = 0; + + return err_status_ok; +} + +/* + * aes_icm_set_octet(c, i) sets the counter of the context which it is + * passed so that the next octet of keystream that will be generated + * is the ith octet + */ + +err_status_t +aes_icm_set_octet(aes_icm_ctx_t *c, + uint64_t octet_num) { + +#ifdef NO_64BIT_MATH + int tail_num = low32(octet_num) & 0x0f; + /* 64-bit right-shift 4 */ + uint64_t block_num = make64(high32(octet_num) >> 4, + ((high32(octet_num) & 0x0f)<<(32-4)) | + (low32(octet_num) >> 4)); +#else + int tail_num = octet_num % 16; + uint64_t block_num = octet_num / 16; +#endif + + + /* set counter value */ + /* FIX - There's no way this is correct */ + c->counter.v64[0] = c->offset.v64[0]; +#ifdef NO_64BIT_MATH + c->counter.v64[0] = make64(high32(c->offset.v64[0]) ^ high32(block_num), + low32(c->offset.v64[0]) ^ low32(block_num)); +#else + c->counter.v64[0] = c->offset.v64[0] ^ block_num; +#endif + + debug_print(mod_aes_icm, + "set_octet: %s", v128_hex_string(&c->counter)); + + /* fill keystream buffer, if needed */ + if (tail_num) { + v128_copy(&c->keystream_buffer, &c->counter); + aes_encrypt(&c->keystream_buffer, c->expanded_key); + c->bytes_in_buffer = sizeof(v128_t); + + debug_print(mod_aes_icm, "counter: %s", + v128_hex_string(&c->counter)); + debug_print(mod_aes_icm, "ciphertext: %s", + v128_hex_string(&c->keystream_buffer)); + + /* indicate number of bytes in keystream_buffer */ + c->bytes_in_buffer = sizeof(v128_t) - tail_num; + + } else { + + /* indicate that keystream_buffer is empty */ + c->bytes_in_buffer = 0; + } + + return err_status_ok; +} + +/* + * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with + * the offset + */ + +err_status_t +aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) { + v128_t *nonce = (v128_t *) iv; + + debug_print(mod_aes_icm, + "setting iv: %s", v128_hex_string(nonce)); + + v128_xor(&c->counter, &c->offset, nonce); + + debug_print(mod_aes_icm, + "set_counter: %s", v128_hex_string(&c->counter)); + + /* indicate that the keystream_buffer is empty */ + c->bytes_in_buffer = 0; + + return err_status_ok; +} + + + +/* + * aes_icm_advance(...) refills the keystream_buffer and + * advances the block index of the sicm_context forward by one + * + * this is an internal, hopefully inlined function + */ + +inline void +aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) { + /* fill buffer with new keystream */ + v128_copy(&c->keystream_buffer, &c->counter); + aes_encrypt(&c->keystream_buffer, c->expanded_key); + c->bytes_in_buffer = sizeof(v128_t); + + debug_print(mod_aes_icm, "counter: %s", + v128_hex_string(&c->counter)); + debug_print(mod_aes_icm, "ciphertext: %s", + v128_hex_string(&c->keystream_buffer)); + + /* clock counter forward */ + + if (forIsmacryp) { + uint32_t temp; + //alex's clock counter forward + temp = ntohl(c->counter.v32[3]); + c->counter.v32[3] = htonl(++temp); + } else { + if (!++(c->counter.v8[15])) + ++(c->counter.v8[14]); + } +} + +inline void aes_icm_advance(aes_icm_ctx_t *c) { + aes_icm_advance_ismacryp(c, 0); +} + + +/*e + * icm_encrypt deals with the following cases: + * + * bytes_to_encr < bytes_in_buffer + * - add keystream into data + * + * bytes_to_encr > bytes_in_buffer + * - add keystream into data until keystream_buffer is depleted + * - loop over blocks, filling keystream_buffer and then + * adding keystream into data + * - fill buffer then add in remaining (< 16) bytes of keystream + */ + +err_status_t +aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c, + unsigned char *buf, unsigned int *enc_len, + int forIsmacryp) { + unsigned int bytes_to_encr = *enc_len; + unsigned int i; + uint32_t *b; + + /* check that there's enough segment left but not for ismacryp*/ + if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff) + return err_status_terminus; + + debug_print(mod_aes_icm, "block index: %d", + htons(c->counter.v16[7])); + if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) { + + /* deal with odd case of small bytes_to_encr */ + for (i = (sizeof(v128_t) - c->bytes_in_buffer); + i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++) + { + *buf++ ^= c->keystream_buffer.v8[i]; + } + + c->bytes_in_buffer -= bytes_to_encr; + + /* return now to avoid the main loop */ + return err_status_ok; + + } else { + + /* encrypt bytes until the remaining data is 16-byte aligned */ + for (i=(sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++) + *buf++ ^= c->keystream_buffer.v8[i]; + + bytes_to_encr -= c->bytes_in_buffer; + c->bytes_in_buffer = 0; + + } + + /* now loop over entire 16-byte blocks of keystream */ + for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) { + + /* fill buffer with new keystream */ + aes_icm_advance_ismacryp(c, forIsmacryp); + + /* + * add keystream into the data buffer (this would be a lot faster + * if we could assume 32-bit alignment!) + */ + +#if ALIGN_32 + b = (uint32_t *)buf; + *b++ ^= c->keystream_buffer.v32[0]; + *b++ ^= c->keystream_buffer.v32[1]; + *b++ ^= c->keystream_buffer.v32[2]; + *b++ ^= c->keystream_buffer.v32[3]; + buf = (uint8_t *)b; +#else + if ((((unsigned long) buf) & 0x03) != 0) { + *buf++ ^= c->keystream_buffer.v8[0]; + *buf++ ^= c->keystream_buffer.v8[1]; + *buf++ ^= c->keystream_buffer.v8[2]; + *buf++ ^= c->keystream_buffer.v8[3]; + *buf++ ^= c->keystream_buffer.v8[4]; + *buf++ ^= c->keystream_buffer.v8[5]; + *buf++ ^= c->keystream_buffer.v8[6]; + *buf++ ^= c->keystream_buffer.v8[7]; + *buf++ ^= c->keystream_buffer.v8[8]; + *buf++ ^= c->keystream_buffer.v8[9]; + *buf++ ^= c->keystream_buffer.v8[10]; + *buf++ ^= c->keystream_buffer.v8[11]; + *buf++ ^= c->keystream_buffer.v8[12]; + *buf++ ^= c->keystream_buffer.v8[13]; + *buf++ ^= c->keystream_buffer.v8[14]; + *buf++ ^= c->keystream_buffer.v8[15]; + } else { + b = (uint32_t *)buf; + *b++ ^= c->keystream_buffer.v32[0]; + *b++ ^= c->keystream_buffer.v32[1]; + *b++ ^= c->keystream_buffer.v32[2]; + *b++ ^= c->keystream_buffer.v32[3]; + buf = (uint8_t *)b; + } +#endif /* #if ALIGN_32 */ + + } + + /* if there is a tail end of the data, process it */ + if ((bytes_to_encr & 0xf) != 0) { + + /* fill buffer with new keystream */ + aes_icm_advance_ismacryp(c, forIsmacryp); + + for (i=0; i < (bytes_to_encr & 0xf); i++) + *buf++ ^= c->keystream_buffer.v8[i]; + + /* reset the keystream buffer size to right value */ + c->bytes_in_buffer = sizeof(v128_t) - i; + } else { + + /* no tail, so just reset the keystream buffer size to zero */ + c->bytes_in_buffer = 0; + + } + + return err_status_ok; +} + +err_status_t +aes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) { + return aes_icm_encrypt_ismacryp(c, buf, enc_len, 0); +} + +err_status_t +aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) { + unsigned int len = num_octets_to_output; + + /* zeroize the buffer */ + octet_string_set_to_zero(buffer, num_octets_to_output); + + /* exor keystream into buffer */ + return aes_icm_encrypt(c, buffer, &len); +} + + +char +aes_icm_description[] = "aes integer counter mode"; + +uint8_t aes_icm_test_case_0_key[30] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd +}; + +uint8_t aes_icm_test_case_0_nonce[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8_t aes_icm_test_case_0_plaintext[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t aes_icm_test_case_0_ciphertext[32] = { + 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80, + 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4, + 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7, + 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab +}; + +cipher_test_case_t aes_icm_test_case_0 = { + 30, /* octets in key */ + aes_icm_test_case_0_key, /* key */ + aes_icm_test_case_0_nonce, /* packet index */ + 32, /* octets in plaintext */ + aes_icm_test_case_0_plaintext, /* plaintext */ + 32, /* octets in ciphertext */ + aes_icm_test_case_0_ciphertext, /* ciphertext */ + NULL /* pointer to next testcase */ +}; + + +/* + * note: the encrypt function is identical to the decrypt function + */ + +cipher_type_t aes_icm = { + (cipher_alloc_func_t) aes_icm_alloc, + (cipher_dealloc_func_t) aes_icm_dealloc, + (cipher_init_func_t) aes_icm_context_init, + (cipher_encrypt_func_t) aes_icm_encrypt, + (cipher_decrypt_func_t) aes_icm_encrypt, + (cipher_set_iv_func_t) aes_icm_set_iv, + (char *) aes_icm_description, + (int) 0, /* instance count */ + (cipher_test_case_t *) &aes_icm_test_case_0, + (debug_module_t *) &mod_aes_icm +}; + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/cipher/cipher.c b/src/libs/resiprocate/contrib/srtp/crypto/cipher/cipher.c new file mode 100644 index 00000000..573c5e23 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/cipher/cipher.c @@ -0,0 +1,407 @@ +/* + * cipher.c + * + * cipher meta-functions + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "cipher.h" +#include "rand_source.h" /* used in invertibiltiy tests */ +#include "alloc.h" /* for crypto_alloc(), crypto_free() */ + +debug_module_t mod_cipher = { + 0, /* debugging is off by default */ + "cipher" /* printable module name */ +}; + +err_status_t +cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output) { + + /* zeroize the buffer */ + octet_string_set_to_zero(buffer, num_octets_to_output); + + /* exor keystream into buffer */ + return cipher_encrypt(c, buffer, (unsigned int *) &num_octets_to_output); +} + +/* some bookkeeping functions */ + +int +cipher_get_key_length(const cipher_t *c) { + return c->key_len; +} + +/* + * cipher_type_self_test(ct) tests a cipher of type ct against test cases + * provided in an array of values of key, salt, xtd_seq_num_t, + * plaintext, and ciphertext that is known to be good + */ + +#define SELF_TEST_BUF_OCTETS 128 +#define NUM_RAND_TESTS 128 +#define MAX_KEY_LEN 64 + +err_status_t +cipher_type_self_test(const cipher_type_t *ct) { + const cipher_test_case_t *test_case = ct->test_data; + cipher_t *c; + err_status_t status; + uint8_t buffer[SELF_TEST_BUF_OCTETS]; + uint8_t buffer2[SELF_TEST_BUF_OCTETS]; + unsigned int len; + int i, j, case_num = 0; + + debug_print(mod_cipher, "running self-test for cipher %s", + ct->description); + + /* + * check to make sure that we have at least one test case, and + * return an error if we don't - we need to be paranoid here + */ + if (test_case == NULL) + return err_status_cant_check; + + /* + * loop over all test cases, perform known-answer tests of both the + * encryption and decryption functions + */ + while (test_case != NULL) { + + /* allocate cipher */ + status = cipher_type_alloc(ct, &c, test_case->key_length_octets); + if (status) + return status; + + /* + * test the encrypt function + */ + debug_print(mod_cipher, "testing encryption", NULL); + + /* initialize cipher */ + status = cipher_init(c, test_case->key, direction_encrypt); + if (status) { + cipher_dealloc(c); + return status; + } + + /* copy plaintext into test buffer */ + if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) { + cipher_dealloc(c); + return err_status_bad_param; + } + for (i=0; i < test_case->plaintext_length_octets; i++) + buffer[i] = test_case->plaintext[i]; + + debug_print(mod_cipher, "plaintext: %s", + octet_string_hex_string(buffer, + test_case->plaintext_length_octets)); + + /* set the initialization vector */ + status = cipher_set_iv(c, test_case->idx); + if (status) { + cipher_dealloc(c); + return status; + } + + /* encrypt */ + len = test_case->plaintext_length_octets; + status = cipher_encrypt(c, buffer, &len); + if (status) { + cipher_dealloc(c); + return status; + } + + debug_print(mod_cipher, "ciphertext: %s", + octet_string_hex_string(buffer, + test_case->ciphertext_length_octets)); + + /* compare the resulting ciphertext with that in the test case */ + if (len != test_case->ciphertext_length_octets) + return err_status_algo_fail; + status = err_status_ok; + for (i=0; i < test_case->ciphertext_length_octets; i++) + if (buffer[i] != test_case->ciphertext[i]) { + status = err_status_algo_fail; + debug_print(mod_cipher, "test case %d failed", case_num); + debug_print(mod_cipher, "(failure at byte %d)", i); + break; + } + if (status) { + + debug_print(mod_cipher, "c computed: %s", + octet_string_hex_string(buffer, + 2*test_case->plaintext_length_octets)); + debug_print(mod_cipher, "c expected: %s", + octet_string_hex_string(test_case->ciphertext, + 2*test_case->plaintext_length_octets)); + + cipher_dealloc(c); + return err_status_algo_fail; + } + + /* + * test the decrypt function + */ + debug_print(mod_cipher, "testing decryption", NULL); + + /* re-initialize cipher for decryption */ + status = cipher_init(c, test_case->key, direction_decrypt); + if (status) { + cipher_dealloc(c); + return status; + } + + /* copy ciphertext into test buffer */ + if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) { + cipher_dealloc(c); + return err_status_bad_param; + } + for (i=0; i < test_case->ciphertext_length_octets; i++) + buffer[i] = test_case->ciphertext[i]; + + debug_print(mod_cipher, "ciphertext: %s", + octet_string_hex_string(buffer, + test_case->plaintext_length_octets)); + + /* set the initialization vector */ + status = cipher_set_iv(c, test_case->idx); + if (status) { + cipher_dealloc(c); + return status; + } + + /* decrypt */ + len = test_case->ciphertext_length_octets; + status = cipher_decrypt(c, buffer, &len); + if (status) { + cipher_dealloc(c); + return status; + } + + debug_print(mod_cipher, "plaintext: %s", + octet_string_hex_string(buffer, + test_case->plaintext_length_octets)); + + /* compare the resulting plaintext with that in the test case */ + if (len != test_case->plaintext_length_octets) + return err_status_algo_fail; + status = err_status_ok; + for (i=0; i < test_case->plaintext_length_octets; i++) + if (buffer[i] != test_case->plaintext[i]) { + status = err_status_algo_fail; + debug_print(mod_cipher, "test case %d failed", case_num); + debug_print(mod_cipher, "(failure at byte %d)", i); + } + if (status) { + + debug_print(mod_cipher, "p computed: %s", + octet_string_hex_string(buffer, + 2*test_case->plaintext_length_octets)); + debug_print(mod_cipher, "p expected: %s", + octet_string_hex_string(test_case->plaintext, + 2*test_case->plaintext_length_octets)); + + cipher_dealloc(c); + return err_status_algo_fail; + } + + /* deallocate the cipher */ + status = cipher_dealloc(c); + if (status) + return status; + + /* + * the cipher passed the test case, so move on to the next test + * case in the list; if NULL, we'l proceed to the next test + */ + test_case = test_case->next_test_case; + ++case_num; + } + + /* now run some random invertibility tests */ + + /* allocate cipher, using paramaters from the first test case */ + test_case = ct->test_data; + status = cipher_type_alloc(ct, &c, test_case->key_length_octets); + if (status) + return status; + + rand_source_init(); + + for (j=0; j < NUM_RAND_TESTS; j++) { + unsigned length; + int plaintext_len; + uint8_t key[MAX_KEY_LEN]; + uint8_t iv[MAX_KEY_LEN]; + + /* choose a length at random (leaving room for IV and padding) */ + length = rand() % (SELF_TEST_BUF_OCTETS - 64); + debug_print(mod_cipher, "random plaintext length %d\n", length); + status = rand_source_get_octet_string(buffer, length); + if (status) return status; + + debug_print(mod_cipher, "plaintext: %s", + octet_string_hex_string(buffer, length)); + + /* copy plaintext into second buffer */ + for (i=0; (unsigned int)i < length; i++) + buffer2[i] = buffer[i]; + + /* choose a key at random */ + if (test_case->key_length_octets > MAX_KEY_LEN) + return err_status_cant_check; + status = rand_source_get_octet_string(key, test_case->key_length_octets); + if (status) return status; + + /* chose a random initialization vector */ + status = rand_source_get_octet_string(iv, MAX_KEY_LEN); + if (status) return status; + + /* initialize cipher */ + status = cipher_init(c, key, direction_encrypt); + if (status) { + cipher_dealloc(c); + return status; + } + + /* set initialization vector */ + status = cipher_set_iv(c, test_case->idx); + if (status) { + cipher_dealloc(c); + return status; + } + + /* encrypt buffer with cipher */ + plaintext_len = length; + status = cipher_encrypt(c, buffer, &length); + if (status) { + cipher_dealloc(c); + return status; + } + debug_print(mod_cipher, "ciphertext: %s", + octet_string_hex_string(buffer, length)); + + /* + * re-initialize cipher for decryption, re-set the iv, then + * decrypt the ciphertext + */ + status = cipher_init(c, key, direction_decrypt); + if (status) { + cipher_dealloc(c); + return status; + } + status = cipher_set_iv(c, test_case->idx); + if (status) { + cipher_dealloc(c); + return status; + } + status = cipher_decrypt(c, buffer, &length); + if (status) { + cipher_dealloc(c); + return status; + } + + debug_print(mod_cipher, "plaintext[2]: %s", + octet_string_hex_string(buffer, length)); + + /* compare the resulting plaintext with the original one */ + if (length != plaintext_len) + return err_status_algo_fail; + status = err_status_ok; + for (i=0; i < plaintext_len; i++) + if (buffer[i] != buffer2[i]) { + status = err_status_algo_fail; + debug_print(mod_cipher, "random test case %d failed", case_num); + debug_print(mod_cipher, "(failure at byte %d)", i); + } + if (status) { + cipher_dealloc(c); + return err_status_algo_fail; + } + + } + + return err_status_ok; +} + + +/* + * cipher_bits_per_second(c, l, t) computes (an estimate of) the + * number of bits that a cipher implementation can encrypt in a second + * + * c is a cipher (which MUST be allocated and initialized already), l + * is the length in octets of the test data to be encrypted, and t is + * the number of trials + * + * if an error is encountered, the value 0 is returned + */ + +uint64_t +cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials) { + int i; + v128_t nonce; + clock_t timer; + unsigned char *enc_buf; + unsigned int len = octets_in_buffer; + + enc_buf = (unsigned char*) crypto_alloc(octets_in_buffer); + if (enc_buf == NULL) + return 0; /* indicate bad parameters by returning null */ + + /* time repeated trials */ + v128_set_to_zero(&nonce); + timer = clock(); + for(i=0; i < num_trials; i++, nonce.v32[3] = i) { + cipher_set_iv(c, &nonce); + cipher_encrypt(c, enc_buf, &len); + } + timer = clock() - timer; + + crypto_free(enc_buf); + + if (timer == 0) { + /* Too fast! */ + return 0; + } + + return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/cipher/null_cipher.c b/src/libs/resiprocate/contrib/srtp/crypto/cipher/null_cipher.c new file mode 100644 index 00000000..721f50cf --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/cipher/null_cipher.c @@ -0,0 +1,152 @@ +/* + * null_cipher.c + * + * A null cipher implementation. This cipher leaves the plaintext + * unchanged. + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "datatypes.h" +#include "null_cipher.h" +#include "alloc.h" + +/* the null_cipher uses the cipher debug module */ + +extern debug_module_t mod_cipher; + +err_status_t +null_cipher_alloc(cipher_t **c, int key_len) { + extern cipher_type_t null_cipher; + uint8_t *pointer; + + debug_print(mod_cipher, + "allocating cipher with key length %d", key_len); + + /* allocate memory a cipher of type null_cipher */ + pointer = (uint8_t*)crypto_alloc(sizeof(null_cipher_ctx_t) + sizeof(cipher_t)); + if (pointer == NULL) + return err_status_alloc_fail; + + /* set pointers */ + *c = (cipher_t *)pointer; + (*c)->type = &null_cipher; + (*c)->state = pointer + sizeof(cipher_t); + + /* set key size */ + (*c)->key_len = key_len; + + /* increment ref_count */ + null_cipher.ref_count++; + + return err_status_ok; + +} + +err_status_t +null_cipher_dealloc(cipher_t *c) { + extern cipher_type_t null_cipher; + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t *)c, + sizeof(null_cipher_ctx_t) + sizeof(cipher_t)); + + /* free memory of type null_cipher */ + crypto_free(c); + + /* decrement reference count */ + null_cipher.ref_count--; + + return err_status_ok; + +} + +err_status_t +null_cipher_init(null_cipher_ctx_t *ctx, const uint8_t *key) { + + debug_print(mod_cipher, "initializing null cipher", NULL); + + return err_status_ok; +} + +err_status_t +null_cipher_set_iv(null_cipher_ctx_t *c, void *iv) { + return err_status_ok; +} + +err_status_t +null_cipher_encrypt(null_cipher_ctx_t *c, + unsigned char *buf, unsigned int *bytes_to_encr) { + return err_status_ok; +} + +char +null_cipher_description[] = "null cipher"; + +cipher_test_case_t +null_cipher_test_0 = { + 0, /* octets in key */ + NULL, /* key */ + 0, /* packet index */ + 0, /* octets in plaintext */ + NULL, /* plaintext */ + 0, /* octets in plaintext */ + NULL, /* ciphertext */ + NULL /* pointer to next testcase */ +}; + + +/* + * note: the decrypt function is idential to the encrypt function + */ + +cipher_type_t null_cipher = { + (cipher_alloc_func_t) null_cipher_alloc, + (cipher_dealloc_func_t) null_cipher_dealloc, + (cipher_init_func_t) null_cipher_init, + (cipher_encrypt_func_t) null_cipher_encrypt, + (cipher_decrypt_func_t) null_cipher_encrypt, + (cipher_set_iv_func_t) null_cipher_set_iv, + (char *) null_cipher_description, + (int) 0, + (cipher_test_case_t *) &null_cipher_test_0, + (debug_module_t *) NULL +}; + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/hash/auth.c b/src/libs/resiprocate/contrib/srtp/crypto/hash/auth.c new file mode 100644 index 00000000..8eb722d0 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/hash/auth.c @@ -0,0 +1,173 @@ +/* + * auth.c + * + * some bookkeeping functions for authentication functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "auth.h" + +/* the debug module for authentiation */ + +debug_module_t mod_auth = { + 0, /* debugging is off by default */ + "auth func" /* printable name for module */ +}; + + +int +auth_get_key_length(const auth_t *a) { + return a->key_len; +} + +int +auth_get_tag_length(const auth_t *a) { + return a->out_len; +} + +int +auth_get_prefix_length(const auth_t *a) { + return a->prefix_len; +} + +int +auth_type_get_ref_count(const auth_type_t *at) { + return at->ref_count; +} + +/* + * auth_type_self_test() tests an auth function of type ct against + * test cases provided in an array of values of key, data, and tag + * that is known to be good + */ + +/* should be big enough for most occasions */ +#define SELF_TEST_TAG_BUF_OCTETS 32 + +err_status_t +auth_type_self_test(const auth_type_t *at) { + auth_test_case_t *test_case = at->test_data; + auth_t *a; + err_status_t status; + uint8_t tag[SELF_TEST_TAG_BUF_OCTETS]; + int i, case_num = 0; + + debug_print(mod_auth, "running self-test for auth function %s", + at->description); + + /* + * check to make sure that we have at least one test case, and + * return an error if we don't - we need to be paranoid here + */ + if (test_case == NULL) + return err_status_cant_check; + + /* loop over all test cases */ + while (test_case != NULL) { + + /* check test case parameters */ + if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS) + return err_status_bad_param; + + /* allocate auth */ + status = auth_type_alloc(at, &a, test_case->key_length_octets, + test_case->tag_length_octets); + if (status) + return status; + + /* initialize auth */ + status = auth_init(a, test_case->key); + if (status) { + auth_dealloc(a); + return status; + } + + /* zeroize tag then compute */ + octet_string_set_to_zero(tag, test_case->tag_length_octets); + status = auth_compute(a, test_case->data, + test_case->data_length_octets, tag); + if (status) { + auth_dealloc(a); + return status; + } + + debug_print(mod_auth, "key: %s", + octet_string_hex_string(test_case->key, + test_case->key_length_octets)); + debug_print(mod_auth, "data: %s", + octet_string_hex_string(test_case->data, + test_case->data_length_octets)); + debug_print(mod_auth, "tag computed: %s", + octet_string_hex_string(tag, test_case->tag_length_octets)); + debug_print(mod_auth, "tag expected: %s", + octet_string_hex_string(test_case->tag, + test_case->tag_length_octets)); + + /* check the result */ + status = err_status_ok; + for (i=0; i < test_case->tag_length_octets; i++) + if (tag[i] != test_case->tag[i]) { + status = err_status_algo_fail; + debug_print(mod_auth, "test case %d failed", case_num); + debug_print(mod_auth, " (mismatch at octet %d)", i); + } + if (status) { + auth_dealloc(a); + return err_status_algo_fail; + } + + /* deallocate the auth function */ + status = auth_dealloc(a); + if (status) + return status; + + /* + * the auth function passed the test case, so move on to the next test + * case in the list; if NULL, we'll quit and return an OK + */ + test_case = test_case->next_test_case; + ++case_num; + } + + return err_status_ok; +} + + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/hash/hmac.c b/src/libs/resiprocate/contrib/srtp/crypto/hash/hmac.c new file mode 100644 index 00000000..4336cf0a --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/hash/hmac.c @@ -0,0 +1,267 @@ +/* + * hmac.c + * + * implementation of hmac auth_type_t + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "hmac.h" +#include "alloc.h" + +/* the debug module for authentiation */ + +debug_module_t mod_hmac = { + 0, /* debugging is off by default */ + "hmac sha-1" /* printable name for module */ +}; + + +err_status_t +hmac_alloc(auth_t **a, int key_len, int out_len) { + extern auth_type_t hmac; + uint8_t *pointer; + + debug_print(mod_hmac, "allocating auth func with key length %d", key_len); + debug_print(mod_hmac, " tag length %d", out_len); + + /* + * check key length - note that we don't support keys larger + * than 20 bytes yet + */ + if (key_len > 20) + return err_status_bad_param; + + /* check output length - should be less than 20 bytes */ + if (out_len > 20) + return err_status_bad_param; + + /* allocate memory for auth and hmac_ctx_t structures */ + pointer = (uint8_t*)crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t)); + if (pointer == NULL) + return err_status_alloc_fail; + + /* set pointers */ + *a = (auth_t *)pointer; + (*a)->type = &hmac; + (*a)->state = pointer + sizeof(auth_t); + (*a)->out_len = out_len; + (*a)->key_len = key_len; + (*a)->prefix_len = 0; + + /* increment global count of all hmac uses */ + hmac.ref_count++; + + return err_status_ok; +} + +err_status_t +hmac_dealloc(auth_t *a) { + extern auth_type_t hmac; + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t *)a, + sizeof(hmac_ctx_t) + sizeof(auth_t)); + + /* free memory */ + crypto_free(a); + + /* decrement global count of all hmac uses */ + hmac.ref_count--; + + return err_status_ok; +} + +err_status_t +hmac_init(hmac_ctx_t *state, const uint8_t *key, int key_len) { + int i; + uint8_t ipad[64]; + + /* + * check key length - note that we don't support keys larger + * than 20 bytes yet + */ + if (key_len > 20) + return err_status_bad_param; + + /* + * set values of ipad and opad by exoring the key into the + * appropriate constant values + */ + for (i=0; i < key_len; i++) { + ipad[i] = key[i] ^ 0x36; + state->opad[i] = key[i] ^ 0x5c; + } + /* set the rest of ipad, opad to constant values */ + for ( ; i < 64; i++) { + ipad[i] = 0x36; + ((uint8_t *)state->opad)[i] = 0x5c; + } + + debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, 64)); + + /* initialize sha1 context */ + sha1_init(&state->init_ctx); + + /* hash ipad ^ key */ + sha1_update(&state->init_ctx, ipad, 64); + memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t)); + + return err_status_ok; +} + +err_status_t +hmac_start(hmac_ctx_t *state) { + + memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t)); + + return err_status_ok; +} + +err_status_t +hmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets) { + + debug_print(mod_hmac, "input: %s", + octet_string_hex_string(message, msg_octets)); + + /* hash message into sha1 context */ + sha1_update(&state->ctx, message, msg_octets); + + return err_status_ok; +} + +err_status_t +hmac_compute(hmac_ctx_t *state, const void *message, + int msg_octets, int tag_len, uint8_t *result) { + uint32_t hash_value[5]; + uint32_t H[5]; + int i; + + /* check tag length, return error if we can't provide the value expected */ + if (tag_len > 20) + return err_status_bad_param; + + /* hash message, copy output into H */ + hmac_update(state, (const uint8_t*)message, msg_octets); + sha1_final(&state->ctx, H); + + /* + * note that we don't need to debug_print() the input, since the + * function hmac_update() already did that for us + */ + debug_print(mod_hmac, "intermediate state: %s", + octet_string_hex_string((uint8_t *)H, 20)); + + /* re-initialize hash context */ + sha1_init(&state->ctx); + + /* hash opad ^ key */ + sha1_update(&state->ctx, (uint8_t *)state->opad, 64); + + /* hash the result of the inner hash */ + sha1_update(&state->ctx, (uint8_t *)H, 20); + + /* the result is returned in the array hash_value[] */ + sha1_final(&state->ctx, hash_value); + + /* copy hash_value to *result */ + for (i=0; i < tag_len; i++) + result[i] = ((uint8_t *)hash_value)[i]; + + debug_print(mod_hmac, "output: %s", + octet_string_hex_string((uint8_t *)hash_value, tag_len)); + + return err_status_ok; +} + + +/* begin test case 0 */ + +uint8_t +hmac_test_case_0_key[20] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b +}; + +uint8_t +hmac_test_case_0_data[8] = { + 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */ +}; + +uint8_t +hmac_test_case_0_tag[20] = { + 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, + 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, + 0xf1, 0x46, 0xbe, 0x00 +}; + +auth_test_case_t +hmac_test_case_0 = { + 20, /* octets in key */ + hmac_test_case_0_key, /* key */ + 8, /* octets in data */ + hmac_test_case_0_data, /* data */ + 20, /* octets in tag */ + hmac_test_case_0_tag, /* tag */ + NULL /* pointer to next testcase */ +}; + +/* end test case 0 */ + +char hmac_description[] = "hmac sha-1 authentication function"; + +/* + * auth_type_t hmac is the hmac metaobject + */ + +auth_type_t +hmac = { + (auth_alloc_func) hmac_alloc, + (auth_dealloc_func) hmac_dealloc, + (auth_init_func) hmac_init, + (auth_compute_func) hmac_compute, + (auth_update_func) hmac_update, + (auth_start_func) hmac_start, + (char *) hmac_description, + (int) 0, /* instance count */ + (auth_test_case_t *) &hmac_test_case_0, + (debug_module_t *) &mod_hmac +}; + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/hash/null_auth.c b/src/libs/resiprocate/contrib/srtp/crypto/hash/null_auth.c new file mode 100644 index 00000000..301348b6 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/hash/null_auth.c @@ -0,0 +1,160 @@ +/* + * null_auth.c + * + * implements the do-nothing auth algorithm + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "null_auth.h" +#include "alloc.h" + +/* null_auth uses the auth debug module */ + +extern debug_module_t mod_auth; + +err_status_t +null_auth_alloc(auth_t **a, int key_len, int out_len) { + extern auth_type_t null_auth; + uint8_t *pointer; + + debug_print(mod_auth, "allocating auth func with key length %d", key_len); + debug_print(mod_auth, " tag length %d", out_len); + + /* allocate memory for auth and null_auth_ctx_t structures */ + pointer = (uint8_t*)crypto_alloc(sizeof(null_auth_ctx_t) + sizeof(auth_t)); + if (pointer == NULL) + return err_status_alloc_fail; + + /* set pointers */ + *a = (auth_t *)pointer; + (*a)->type = &null_auth; + (*a)->state = pointer + sizeof (auth_t); + (*a)->out_len = out_len; + (*a)->prefix_len = out_len; + (*a)->key_len = key_len; + + /* increment global count of all null_auth uses */ + null_auth.ref_count++; + + return err_status_ok; +} + +err_status_t +null_auth_dealloc(auth_t *a) { + extern auth_type_t null_auth; + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t *)a, + sizeof(null_auth_ctx_t) + sizeof(auth_t)); + + /* free memory */ + crypto_free(a); + + /* decrement global count of all null_auth uses */ + null_auth.ref_count--; + + return err_status_ok; +} + +err_status_t +null_auth_init(null_auth_ctx_t *state, const uint8_t *key, int key_len) { + + /* accept any length of key, and do nothing */ + + return err_status_ok; +} + +err_status_t +null_auth_compute(null_auth_ctx_t *state, uint8_t *message, + int msg_octets, int tag_len, uint8_t *result) { + + return err_status_ok; +} + +err_status_t +null_auth_update(null_auth_ctx_t *state, uint8_t *message, + int msg_octets) { + + return err_status_ok; +} + +err_status_t +null_auth_start(null_auth_ctx_t *state) { + return err_status_ok; +} + +/* + * auth_type_t - defines description, test case, and null_auth + * metaobject + */ + +/* begin test case 0 */ + +auth_test_case_t +null_auth_test_case_0 = { + 0, /* octets in key */ + NULL, /* key */ + 0, /* octets in data */ + NULL, /* data */ + 0, /* octets in tag */ + NULL, /* tag */ + NULL /* pointer to next testcase */ +}; + +/* end test case 0 */ + +char null_auth_description[] = "null authentication function"; + +auth_type_t +null_auth = { + (auth_alloc_func) null_auth_alloc, + (auth_dealloc_func) null_auth_dealloc, + (auth_init_func) null_auth_init, + (auth_compute_func) null_auth_compute, + (auth_update_func) null_auth_update, + (auth_start_func) null_auth_start, + (char *) null_auth_description, + (int) 0, /* instance count */ + (auth_test_case_t *) &null_auth_test_case_0 +}; + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/hash/sha1.c b/src/libs/resiprocate/contrib/srtp/crypto/hash/sha1.c new file mode 100644 index 00000000..566672de --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/hash/sha1.c @@ -0,0 +1,404 @@ +/* + * sha1.c + * + * an implementation of the Secure Hash Algorithm v.1 (SHA-1), + * specified in FIPS 180-1 + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "sha1.h" + +debug_module_t mod_sha1 = { + 0, /* debugging is off by default */ + "sha-1" /* printable module name */ +}; + +/* SN == Rotate left N bits */ +#define S1(X) ((X << 1) | (X >> 31)) +#define S5(X) ((X << 5) | (X >> 27)) +#define S30(X) ((X << 30) | (X >> 2)) + +#define f0(B,C,D) ((B & C) | (~B & D)) +#define f1(B,C,D) (B ^ C ^ D) +#define f2(B,C,D) ((B & C) | (B & D) | (C & D)) +#define f3(B,C,D) (B ^ C ^ D) + +/* + * nota bene: the variable K0 appears in the curses library, so we + * give longer names to these variables to avoid spurious warnings + * on systems that uses curses + */ + +uint32_t SHA_K0 = 0x5A827999; /* Kt for 0 <= t <= 19 */ +uint32_t SHA_K1 = 0x6ED9EBA1; /* Kt for 20 <= t <= 39 */ +uint32_t SHA_K2 = 0x8F1BBCDC; /* Kt for 40 <= t <= 59 */ +uint32_t SHA_K3 = 0xCA62C1D6; /* Kt for 60 <= t <= 79 */ + +void +sha1(const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5]) { + sha1_ctx_t ctx; + + sha1_init(&ctx); + sha1_update(&ctx, msg, octets_in_msg); + sha1_final(&ctx, hash_value); + +} + +/* + * sha1_core(M, H) computes the core compression function, where M is + * the next part of the message (in network byte order) and H is the + * intermediate state { H0, H1, ...} (in host byte order) + * + * this function does not do any of the padding required in the + * complete SHA1 function + * + * this function is used in the SEAL 3.0 key setup routines + * (crypto/cipher/seal.c) + */ + +void +sha1_core(const uint32_t M[16], uint32_t hash_value[5]) { + uint32_t H0; + uint32_t H1; + uint32_t H2; + uint32_t H3; + uint32_t H4; + uint32_t W[80]; + uint32_t A, B, C, D, E, TEMP; + int t; + + /* copy hash_value into H0, H1, H2, H3, H4 */ + H0 = hash_value[0]; + H1 = hash_value[1]; + H2 = hash_value[2]; + H3 = hash_value[3]; + H4 = hash_value[4]; + + /* copy/xor message into array */ + + W[0] = be32_to_cpu(M[0]); + W[1] = be32_to_cpu(M[1]); + W[2] = be32_to_cpu(M[2]); + W[3] = be32_to_cpu(M[3]); + W[4] = be32_to_cpu(M[4]); + W[5] = be32_to_cpu(M[5]); + W[6] = be32_to_cpu(M[6]); + W[7] = be32_to_cpu(M[7]); + W[8] = be32_to_cpu(M[8]); + W[9] = be32_to_cpu(M[9]); + W[10] = be32_to_cpu(M[10]); + W[11] = be32_to_cpu(M[11]); + W[12] = be32_to_cpu(M[12]); + W[13] = be32_to_cpu(M[13]); + W[14] = be32_to_cpu(M[14]); + W[15] = be32_to_cpu(M[15]); + TEMP = W[13] ^ W[8] ^ W[2] ^ W[0]; W[16] = S1(TEMP); + TEMP = W[14] ^ W[9] ^ W[3] ^ W[1]; W[17] = S1(TEMP); + TEMP = W[15] ^ W[10] ^ W[4] ^ W[2]; W[18] = S1(TEMP); + TEMP = W[16] ^ W[11] ^ W[5] ^ W[3]; W[19] = S1(TEMP); + TEMP = W[17] ^ W[12] ^ W[6] ^ W[4]; W[20] = S1(TEMP); + TEMP = W[18] ^ W[13] ^ W[7] ^ W[5]; W[21] = S1(TEMP); + TEMP = W[19] ^ W[14] ^ W[8] ^ W[6]; W[22] = S1(TEMP); + TEMP = W[20] ^ W[15] ^ W[9] ^ W[7]; W[23] = S1(TEMP); + TEMP = W[21] ^ W[16] ^ W[10] ^ W[8]; W[24] = S1(TEMP); + TEMP = W[22] ^ W[17] ^ W[11] ^ W[9]; W[25] = S1(TEMP); + TEMP = W[23] ^ W[18] ^ W[12] ^ W[10]; W[26] = S1(TEMP); + TEMP = W[24] ^ W[19] ^ W[13] ^ W[11]; W[27] = S1(TEMP); + TEMP = W[25] ^ W[20] ^ W[14] ^ W[12]; W[28] = S1(TEMP); + TEMP = W[26] ^ W[21] ^ W[15] ^ W[13]; W[29] = S1(TEMP); + TEMP = W[27] ^ W[22] ^ W[16] ^ W[14]; W[30] = S1(TEMP); + TEMP = W[28] ^ W[23] ^ W[17] ^ W[15]; W[31] = S1(TEMP); + + /* process the remainder of the array */ + for (t=32; t < 80; t++) { + TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]; + W[t] = S1(TEMP); + } + + A = H0; B = H1; C = H2; D = H3; E = H4; + + for (t=0; t < 20; t++) { + TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 40; t++) { + TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 60; t++) { + TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 80; t++) { + TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + + hash_value[0] = H0 + A; + hash_value[1] = H1 + B; + hash_value[2] = H2 + C; + hash_value[3] = H3 + D; + hash_value[4] = H4 + E; + + return; +} + +void +sha1_init(sha1_ctx_t *ctx) { + + /* initialize state vector */ + ctx->H[0] = 0x67452301; + ctx->H[1] = 0xefcdab89; + ctx->H[2] = 0x98badcfe; + ctx->H[3] = 0x10325476; + ctx->H[4] = 0xc3d2e1f0; + + /* indicate that message buffer is empty */ + ctx->octets_in_buffer = 0; + + /* reset message bit-count to zero */ + ctx->num_bits_in_msg = 0; + +} + +void +sha1_update(sha1_ctx_t *ctx, const uint8_t *msg, int octets_in_msg) { + int i; + uint8_t *buf = (uint8_t *)ctx->M; + + /* update message bit-count */ + ctx->num_bits_in_msg += octets_in_msg * 8; + + /* loop over 16-word blocks of M */ + while (octets_in_msg > 0) { + + if (octets_in_msg + ctx->octets_in_buffer >= 64) { + + /* + * copy words of M into msg buffer until that buffer is full, + * converting them into host byte order as needed + */ + octets_in_msg -= (64 - ctx->octets_in_buffer); + for (i=ctx->octets_in_buffer; i < 64; i++) + buf[i] = *msg++; + ctx->octets_in_buffer = 0; + + /* process a whole block */ + + debug_print(mod_sha1, "(update) running sha1_core()", NULL); + + sha1_core(ctx->M, ctx->H); + + } else { + + debug_print(mod_sha1, "(update) not running sha1_core()", NULL); + + for (i=ctx->octets_in_buffer; + i < (ctx->octets_in_buffer + octets_in_msg); i++) + buf[i] = *msg++; + ctx->octets_in_buffer += octets_in_msg; + octets_in_msg = 0; + } + + } + +} + +/* + * sha1_final(ctx, output) computes the result for ctx and copies it + * into the twenty octets located at *output + */ + +void +sha1_final(sha1_ctx_t *ctx, uint32_t *output) { + uint32_t A, B, C, D, E, TEMP; + uint32_t W[80]; + int i, t; + + /* + * process the remaining octets_in_buffer, padding and terminating as + * necessary + */ + { + int tail = ctx->octets_in_buffer % 4; + + /* copy/xor message into array */ + for (i=0; i < (ctx->octets_in_buffer+3)/4; i++) + W[i] = be32_to_cpu(ctx->M[i]); + + /* set the high bit of the octet immediately following the message */ + switch (tail) { + case (3): + W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xffffff00) | 0x80; + W[i] = 0x0; + break; + case (2): + W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xffff0000) | 0x8000; + W[i] = 0x0; + break; + case (1): + W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xff000000) | 0x800000; + W[i] = 0x0; + break; + case (0): + W[i] = 0x80000000; + break; + } + + /* zeroize remaining words */ + for (i++ ; i < 15; i++) + W[i] = 0x0; + + /* + * if there is room at the end of the word array, then set the + * last word to the bit-length of the message; otherwise, set that + * word to zero and then we need to do one more run of the + * compression algo. + */ + if (ctx->octets_in_buffer < 56) + W[15] = ctx->num_bits_in_msg; + else if (ctx->octets_in_buffer < 60) + W[15] = 0x0; + + /* process the word array */ for (t=16; t < 80; t++) { + TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]; + W[t] = S1(TEMP); + } + + A = ctx->H[0]; + B = ctx->H[1]; + C = ctx->H[2]; + D = ctx->H[3]; + E = ctx->H[4]; + + for (t=0; t < 20; t++) { + TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 40; t++) { + TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 60; t++) { + TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 80; t++) { + TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + + ctx->H[0] += A; + ctx->H[1] += B; + ctx->H[2] += C; + ctx->H[3] += D; + ctx->H[4] += E; + + } + + debug_print(mod_sha1, "(final) running sha1_core()", NULL); + + if (ctx->octets_in_buffer >= 56) { + + debug_print(mod_sha1, "(final) running sha1_core() again", NULL); + + /* we need to do one final run of the compression algo */ + + /* + * set initial part of word array to zeros, and set the + * final part to the number of bits in the message + */ + for (i=0; i < 15; i++) + W[i] = 0x0; + W[15] = ctx->num_bits_in_msg; + + /* process the word array */ + for (t=16; t < 80; t++) { + TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]; + W[t] = S1(TEMP); + } + + A = ctx->H[0]; + B = ctx->H[1]; + C = ctx->H[2]; + D = ctx->H[3]; + E = ctx->H[4]; + + for (t=0; t < 20; t++) { + TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 40; t++) { + TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 60; t++) { + TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 80; t++) { + TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + + ctx->H[0] += A; + ctx->H[1] += B; + ctx->H[2] += C; + ctx->H[3] += D; + ctx->H[4] += E; + } + + /* copy result into output buffer */ + output[0] = be32_to_cpu(ctx->H[0]); + output[1] = be32_to_cpu(ctx->H[1]); + output[2] = be32_to_cpu(ctx->H[2]); + output[3] = be32_to_cpu(ctx->H[3]); + output[4] = be32_to_cpu(ctx->H[4]); + + /* indicate that message buffer in context is empty */ + ctx->octets_in_buffer = 0; + + return; +} + + + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/.cvsignore b/src/libs/resiprocate/contrib/srtp/crypto/include/.cvsignore new file mode 100644 index 00000000..0e56cf2f --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/.cvsignore @@ -0,0 +1 @@ +config.h diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/aes.h b/src/libs/resiprocate/contrib/srtp/crypto/include/aes.h new file mode 100644 index 00000000..d9652809 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/aes.h @@ -0,0 +1,84 @@ +/* + * aes.h + * + * header file for the AES block cipher + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _AES_H +#define _AES_H + +#include "config.h" + +#include "datatypes.h" +#include "gf2_8.h" + +/* aes internals */ + +typedef v128_t aes_expanded_key_t[11]; + +void +aes_expand_encryption_key(const v128_t *key, + aes_expanded_key_t expanded_key); + +void +aes_expand_decryption_key(const v128_t *key, + aes_expanded_key_t expanded_key); + +void +aes_encrypt(v128_t *plaintext, const aes_expanded_key_t exp_key); + +void +aes_decrypt(v128_t *plaintext, const aes_expanded_key_t exp_key); + +#if 0 +/* + * internal functions + */ + +void +aes_init_sbox(void); + +void +aes_compute_tables(void); +#endif + +#endif /* _AES_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/aes_cbc.h b/src/libs/resiprocate/contrib/srtp/crypto/include/aes_cbc.h new file mode 100644 index 00000000..9fb6682b --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/aes_cbc.h @@ -0,0 +1,50 @@ +/* + * aes_cbc.h + * + * Header for AES Cipher Blobk Chaining Mode. + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ + +#ifndef AES_CBC_H +#define AES_CBC_H + +#include "aes.h" +#include "cipher.h" + +typedef struct { + v128_t state; /* cipher chaining state */ + v128_t previous; /* previous ciphertext block */ + aes_expanded_key_t expanded_key; /* the cipher key */ +} aes_cbc_ctx_t; + +err_status_t +aes_cbc_set_key(aes_cbc_ctx_t *c, + const unsigned char *key); + +err_status_t +aes_cbc_encrypt(aes_cbc_ctx_t *c, + unsigned char *buf, + unsigned int *bytes_in_data); + +err_status_t +aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, + cipher_direction_t dir); + +err_status_t +aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv); + +err_status_t +aes_cbc_nist_encrypt(aes_cbc_ctx_t *c, + unsigned char *data, + unsigned int *bytes_in_data); + +err_status_t +aes_cbc_nist_decrypt(aes_cbc_ctx_t *c, + unsigned char *data, + unsigned int *bytes_in_data); + +#endif /* AES_CBC_H */ + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/aes_icm.h b/src/libs/resiprocate/contrib/srtp/crypto/include/aes_icm.h new file mode 100644 index 00000000..17a1ddba --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/aes_icm.h @@ -0,0 +1,56 @@ +/* + * aes_icm.h + * + * Header for AES Integer Counter Mode. + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ + +#ifndef AES_ICM_H +#define AES_ICM_H + +#include "aes.h" +#include "cipher.h" + +typedef struct { + v128_t counter; /* holds the counter value */ + v128_t offset; /* initial offset value */ + v128_t keystream_buffer; /* buffers bytes of keystream */ + aes_expanded_key_t expanded_key; /* the cipher key */ + int bytes_in_buffer; /* number of unused bytes in buffer */ +} aes_icm_ctx_t; + + +err_status_t +aes_icm_context_init(aes_icm_ctx_t *c, + const unsigned char *key); + +err_status_t +aes_icm_set_iv(aes_icm_ctx_t *c, void *iv); + +err_status_t +aes_icm_encrypt(aes_icm_ctx_t *c, + unsigned char *buf, unsigned int *bytes_to_encr); + +err_status_t +aes_icm_output(aes_icm_ctx_t *c, + unsigned char *buf, int bytes_to_output); + +err_status_t +aes_icm_dealloc(cipher_t *c); + +err_status_t +aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c, + unsigned char *buf, + unsigned int *enc_len, + int forIsmacryp); + +err_status_t +aes_icm_alloc_ismacryp(cipher_t **c, + int key_len, + int forIsmacryp); + +#endif /* AES_ICM_H */ + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/alloc.h b/src/libs/resiprocate/contrib/srtp/crypto/include/alloc.h new file mode 100644 index 00000000..5980eed6 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/alloc.h @@ -0,0 +1,57 @@ +/* + * alloc.h + * + * interface to memory allocation and deallocation, with optional debugging + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef CRYPTO_ALLOC_H +#define CRYPTO_ALLOC_H + +#include "datatypes.h" + +void * +crypto_alloc(size_t size); + +void +crypto_free(void *ptr); + +#endif /* CRYPTO_ALLOC_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/auth.h b/src/libs/resiprocate/contrib/srtp/crypto/include/auth.h new file mode 100644 index 00000000..295b5f6f --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/auth.h @@ -0,0 +1,159 @@ +/* + * auth.h + * + * common interface to authentication functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef AUTH_H +#define AUTH_H + +#include "datatypes.h" +#include "err.h" /* error codes */ + +typedef struct auth_type_t *auth_type_pointer; +typedef struct auth_t *auth_pointer_t; + +typedef err_status_t (*auth_alloc_func) + (auth_pointer_t *ap, int key_len, int out_len); + +typedef err_status_t (*auth_init_func) + (void *state, const uint8_t *key, int key_len); + +typedef err_status_t (*auth_dealloc_func)(auth_pointer_t ap); + +typedef err_status_t (*auth_compute_func) + (void *state, uint8_t *buffer, int octets_to_auth, + int tag_len, uint8_t *tag); + +typedef err_status_t (*auth_update_func) + (void *state, uint8_t *buffer, int octets_to_auth); + +typedef err_status_t (*auth_start_func)(void *state); + +/* some syntactic sugar on these function types */ + +#define auth_type_alloc(at, a, klen, outlen) \ + ((at)->alloc((a), (klen), (outlen))) + +#define auth_init(a, key) \ + (((a)->type)->init((a)->state, (key), ((a)->key_len))) + +#define auth_compute(a, buf, len, res) \ + (((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res))) + +#define auth_update(a, buf, len) \ + (((a)->type)->update((a)->state, (buf), (len))) + +#define auth_start(a)(((a)->type)->start((a)->state)) + +#define auth_dealloc(c) (((c)->type)->dealloc(c)) + +/* functions to get information about a particular auth_t */ + +int +auth_get_key_length(const struct auth_t *a); + +int +auth_get_tag_length(const struct auth_t *a); + +int +auth_get_prefix_length(const struct auth_t *a); + +/* + * auth_test_case_t is a (list of) key/message/tag values that are + * known to be correct for a particular cipher. this data can be used + * to test an implementation in an on-the-fly self test of the + * correcness of the implementation. (see the auth_type_self_test() + * function below) + */ + +typedef struct auth_test_case_t { + int key_length_octets; /* octets in key */ + uint8_t *key; /* key */ + int data_length_octets; /* octets in data */ + uint8_t *data; /* data */ + int tag_length_octets; /* octets in tag */ + uint8_t *tag; /* tag */ + struct auth_test_case_t *next_test_case; /* pointer to next testcase */ +} auth_test_case_t; + +/* auth_type_t */ + +typedef struct auth_type_t { + auth_alloc_func alloc; + auth_dealloc_func dealloc; + auth_init_func init; + auth_compute_func compute; + auth_update_func update; + auth_start_func start; + char *description; + int ref_count; + auth_test_case_t *test_data; + debug_module_t *debug; +} auth_type_t; + +typedef struct auth_t { + auth_type_t *type; + void *state; + int out_len; /* length of output tag in octets */ + int key_len; /* length of key in octets */ + int prefix_len; /* length of keystream prefix */ +} auth_t; + +/* + * auth_type_self_test() tests an auth_type against test cases + * provided in an array of values of key/message/tag that is known to + * be good + */ + +err_status_t +auth_type_self_test(const auth_type_t *at); + +/* + * auth_type_get_ref_count(at) returns the reference count (the number + * of instantiations) of the auth_type_t at + */ + +int +auth_type_get_ref_count(const auth_type_t *at); + +#endif /* AUTH_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/cipher.h b/src/libs/resiprocate/contrib/srtp/crypto/include/cipher.h new file mode 100644 index 00000000..96ee9dc3 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/cipher.h @@ -0,0 +1,218 @@ +/* + * cipher.h + * + * common interface to ciphers + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef CIPHER_H +#define CIPHER_H + +#include "datatypes.h" +#include "rdbx.h" /* for xtd_seq_num_t */ +#include "err.h" /* for error codes */ + + +/** + * @brief cipher_direction_t defines a particular cipher operation. + * + * A cipher_direction_t is an enum that describes a particular cipher + * operation, i.e. encryption or decryption. For some ciphers, this + * distinction does not matter, but for others, it is essential. + */ + +typedef enum { + direction_encrypt, /**< encryption (convert plaintext to ciphertext) */ + direction_decrypt, /**< decryption (convert ciphertext to plaintext) */ + direction_any /**< encryption or decryption */ +} cipher_direction_t; + +/* + * the cipher_pointer and cipher_type_pointer definitions are needed + * as cipher_t and cipher_type_t are not yet defined + */ + +typedef struct cipher_type_t *cipher_type_pointer_t; +typedef struct cipher_t *cipher_pointer_t; + +/* + * a cipher_alloc_func_t allocates (but does not initialize) a cipher_t + */ + +typedef err_status_t (*cipher_alloc_func_t) + (cipher_pointer_t *cp, int key_len); + +/* + * a cipher_init_func_t [re-]initializes a cipher_t with a given key + * and direction (i.e., encrypt or decrypt) + */ + +typedef err_status_t (*cipher_init_func_t) + (void *state, const uint8_t *key, cipher_direction_t dir); + +/* a cipher_dealloc_func_t de-allocates a cipher_t */ + +typedef err_status_t (*cipher_dealloc_func_t)(cipher_pointer_t cp); + +/* a cipher_set_segment_func_t sets the segment index of a cipher_t */ + +typedef err_status_t (*cipher_set_segment_func_t) + (void *state, xtd_seq_num_t idx); + +/* a cipher_encrypt_func_t encrypts data in-place */ + +typedef err_status_t (*cipher_encrypt_func_t) + (void *state, uint8_t *buffer, unsigned int *octets_to_encrypt); + +/* a cipher_decrypt_func_t decrypts data in-place */ + +typedef err_status_t (*cipher_decrypt_func_t) + (void *state, uint8_t *buffer, unsigned int *octets_to_decrypt); + +/* + * a cipher_set_nonce_seq_func_t function sets both the nonce + * and the extended sequence number + */ + +typedef err_status_t (*cipher_set_iv_func_t) + (cipher_pointer_t cp, void *iv); + +/* + * cipher_test_case_t is a (list of) key, salt, xtd_seq_num_t, + * plaintext, and ciphertext values that are known to be correct for a + * particular cipher. this data can be used to test an implementation + * in an on-the-fly self test of the correcness of the implementation. + * (see the cipher_type_self_test() function below) + */ + +typedef struct cipher_test_case_t { + int key_length_octets; /* octets in key */ + uint8_t *key; /* key */ + uint8_t *idx; /* packet index */ + int plaintext_length_octets; /* octets in plaintext */ + uint8_t *plaintext; /* plaintext */ + int ciphertext_length_octets; /* octets in plaintext */ + uint8_t *ciphertext; /* ciphertext */ + struct cipher_test_case_t *next_test_case; /* pointer to next testcase */ +} cipher_test_case_t; + +/* cipher_type_t defines the 'metadata' for a particular cipher type */ + +typedef struct cipher_type_t { + cipher_alloc_func_t alloc; + cipher_dealloc_func_t dealloc; + cipher_init_func_t init; + cipher_encrypt_func_t encrypt; + cipher_encrypt_func_t decrypt; + cipher_set_iv_func_t set_iv; + char *description; + int ref_count; + cipher_test_case_t *test_data; + debug_module_t *debug; +} cipher_type_t; + +/* + * cipher_t defines an instantiation of a particular cipher, with fixed + * key length, key and salt values + */ + +typedef struct cipher_t { + cipher_type_t *type; + void *state; + int key_len; +#ifdef FORCE_64BIT_ALIGN + int pad; +#endif +} cipher_t; + +/* some syntactic sugar on these function types */ + +#define cipher_type_alloc(ct, c, klen) ((ct)->alloc((c), (klen))) + +#define cipher_dealloc(c) (((c)->type)->dealloc(c)) + +#define cipher_init(c, k, dir) (((c)->type)->init(((c)->state), (k), (dir))) + +#define cipher_encrypt(c, buf, len) \ + (((c)->type)->encrypt(((c)->state), (buf), (len))) + +#define cipher_decrypt(c, buf, len) \ + (((c)->type)->decrypt(((c)->state), (buf), (len))) + +#define cipher_set_iv(c, n) \ + ((c) ? (((c)->type)->set_iv(((cipher_pointer_t)(c)->state), (n))) : \ + err_status_no_such_op) + +err_status_t +cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output); + + +/* some bookkeeping functions */ + +int +cipher_get_key_length(const cipher_t *c); + + +/* + * cipher_type_self_test() tests a cipher against test cases provided in + * an array of values of key/xtd_seq_num_t/plaintext/ciphertext + * that is known to be good + */ + +err_status_t +cipher_type_self_test(const cipher_type_t *ct); + + +/* + * cipher_bits_per_second(c, l, t) computes (and estimate of) the + * number of bits that a cipher implementation can encrypt in a second + * + * c is a cipher (which MUST be allocated and initialized already), l + * is the length in octets of the test data to be encrypted, and t is + * the number of trials + * + * if an error is encountered, then the value 0 is returned + */ + +uint64_t +cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials); + +#endif /* CIPHER_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/crypto.h b/src/libs/resiprocate/contrib/srtp/crypto/include/crypto.h new file mode 100644 index 00000000..0e9667da --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/crypto.h @@ -0,0 +1,43 @@ +/* + * crypto.h + * + * API for libcrypto + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +#ifndef CRYPTO_H +#define CRYPTO_H + +/** + * @brief A cipher_type_id_t is an identifier for a particular cipher + * type. + * + * A cipher_type_id_t is an integer that represents a particular + * cipher type, e.g. the Advanced Encryption Standard (AES). A + * NULL_CIPHER is avaliable; this cipher leaves the data unchanged, + * and can be selected to indicate that no encryption is to take + * place. + * + * @ingroup Ciphers + */ +typedef uint32_t cipher_type_id_t; + +/** + * @brief An auth_type_id_t is an identifier for a particular authentication + * function. + * + * An auth_type_id_t is an integer that represents a particular + * authentication function type, e.g. HMAC-SHA1. A NULL_AUTH is + * avaliable; this authentication function performs no computation, + * and can be selected to indicate that no authentication is to take + * place. + * + * @ingroup Authentication + */ +typedef uint32_t auth_type_id_t; + +#endif /* CRYPTO_H */ + + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/crypto_kernel.h b/src/libs/resiprocate/contrib/srtp/crypto/include/crypto_kernel.h new file mode 100644 index 00000000..b8cd9be1 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/crypto_kernel.h @@ -0,0 +1,258 @@ +/* + * crypto_kernel.h + * + * header for the cryptographic kernel + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef CRYPTO_KERNEL +#define CRYPTO_KERNEL + +#include "rand_source.h" +#include "prng.h" +#include "cipher.h" +#include "auth.h" +#include "cryptoalg.h" +#include "stat.h" +#include "err.h" +#include "crypto_types.h" +#include "key.h" +#include "crypto.h" + +/* + * crypto_kernel_state_t defines the possible states: + * + * insecure - not yet initialized + * secure - initialized and passed self-tests + */ + +typedef enum { + crypto_kernel_state_insecure, + crypto_kernel_state_secure +} crypto_kernel_state_t; + +/* + * linked list of cipher types + */ + +typedef struct kernel_cipher_type { + cipher_type_id_t id; + cipher_type_t *cipher_type; + struct kernel_cipher_type *next; +} kernel_cipher_type_t; + +/* + * linked list of auth types + */ + +typedef struct kernel_auth_type { + auth_type_id_t id; + auth_type_t *auth_type; + struct kernel_auth_type *next; +} kernel_auth_type_t; + +/* + * linked list of debug modules + */ + +typedef struct kernel_debug_module { + debug_module_t *mod; + struct kernel_debug_module *next; +} kernel_debug_module_t; + + +/* + * crypto_kernel_t is the data structure for the crypto kernel + * + * note that there is *exactly one* instance of this data type, + * a global variable defined in crypto_kernel.c + */ + +typedef struct { + crypto_kernel_state_t state; /* current state of kernel */ + kernel_cipher_type_t *cipher_type_list; /* list of all cipher types */ + kernel_auth_type_t *auth_type_list; /* list of all auth func types */ + kernel_debug_module_t *debug_module_list; /* list of all debug modules */ +} crypto_kernel_t; + + +/* + * crypto_kernel_t external api + */ + + +/* + * The function crypto_kernel_init() initialized the crypto kernel and + * runs the self-test operations on the random number generators and + * crypto algorithms. Possible return values are: + * + * err_status_ok initialization successful + * init failure + * + * If any value other than err_status_ok is returned, the + * crypto_kernel MUST NOT be used. + */ + +err_status_t +crypto_kernel_init(void); + + +/* + * The function crypto_kernel_shutdown() de-initializes the + * crypto_kernel, zeroizes keys and other cryptographic material, and + * deallocates any dynamically allocated memory. Possible return + * values are: + * + * err_status_ok shutdown successful + * shutdown failure + * + */ + +err_status_t +crypto_kernel_shutdown(void); + +/* + * The function crypto_kernel_stats() checks the the crypto_kernel, + * running tests on the ciphers, auth funcs, and rng, and prints out a + * status report. Possible return values are: + * + * err_status_ok all tests were passed + * a test failed + * + */ + +err_status_t +crypto_kernel_status(void); + + +/* + * crypto_kernel_list_debug_modules() outputs a list of debugging modules + * + */ + +err_status_t +crypto_kernel_list_debug_modules(void); + +/* + * crypto_kernel_load_cipher_type() + * + */ + +err_status_t +crypto_kernel_load_cipher_type(cipher_type_t *ct, cipher_type_id_t id); + +err_status_t +crypto_kernel_load_auth_type(auth_type_t *ct, auth_type_id_t id); + +err_status_t +crypto_kernel_load_debug_module(debug_module_t *new_dm); + +/* + * crypto_kernel_alloc_cipher(id, cp, key_len); + * + * allocates a cipher of type id at location *cp, with key length + * key_len octets. Return values are: + * + * err_status_ok no problems + * err_status_alloc_fail an allocation failure occured + * err_status_fail couldn't find cipher with identifier 'id' + */ + +err_status_t +crypto_kernel_alloc_cipher(cipher_type_id_t id, + cipher_pointer_t *cp, + int key_len); + +/* + * crypto_kernel_alloc_auth(id, ap, key_len, tag_len); + * + * allocates an auth function of type id at location *ap, with key + * length key_len octets and output tag length of tag_len. Return + * values are: + * + * err_status_ok no problems + * err_status_alloc_fail an allocation failure occured + * err_status_fail couldn't find auth with identifier 'id' + */ + +err_status_t +crypto_kernel_alloc_auth(auth_type_id_t id, + auth_pointer_t *ap, + int key_len, + int tag_len); + + +/* + * crypto_kernel_set_debug_module(mod_name, v) + * + * sets dynamic debugging to the value v (0 for off, 1 for on) for the + * debug module with the name mod_name + * + * returns err_status_ok on success, err_status_fail otherwise + */ + +err_status_t +crypto_kernel_set_debug_module(char *mod_name, int v); + +/** + * @brief writes a random octet string. + * + * The function call crypto_get_random(dest, len) writes len octets of + * random data to the location to which dest points, and returns an + * error code. This error code @b must be checked, and if a failure is + * reported, the data in the buffer @b must @b not be used. + * + * @warning If the return code is not checked, then non-random + * data may be in the buffer. This function will fail + * unless it is called after crypto_kernel_init(). + * + * @return + * - err_status_ok if no problems occured. + * - [other] a problem occured, and no assumptions should + * be made about the contents of the destination + * buffer. + * + * @ingroup SRTP + */ +err_status_t +crypto_get_random(unsigned char *buffer, unsigned int length); + +#endif /* CRYPTO_KERNEL */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/crypto_math.h b/src/libs/resiprocate/contrib/srtp/crypto/include/crypto_math.h new file mode 100644 index 00000000..c3e7b76b --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/crypto_math.h @@ -0,0 +1,273 @@ +/* + * math.h + * + * crypto math operations and data types + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef MATH_H +#define MATH_H + +#include "datatypes.h" + +unsigned char +v32_weight(v32_t a); + +unsigned char +v32_distance(v32_t x, v32_t y); + +unsigned int +v32_dot_product(v32_t a, v32_t b); + +char * +v16_bit_string(v16_t x); + +char * +v32_bit_string(v32_t x); + +char * +v64_bit_string(const v64_t *x); + +char * +octet_hex_string(uint8_t x); + +char * +v16_hex_string(v16_t x); + +char * +v32_hex_string(v32_t x); + +char * +v64_hex_string(const v64_t *x); + +int +hex_char_to_nibble(uint8_t c); + +int +is_hex_string(char *s); + +v16_t +hex_string_to_v16(char *s); + +v32_t +hex_string_to_v32(char *s); + +v64_t +hex_string_to_v64(char *s); + +/* the matrix A[] is stored in column format, i.e., A[i] is + the ith column of the matrix */ + +uint8_t +A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b); + +void +v16_copy_octet_string(v16_t *x, const uint8_t s[2]); + +void +v32_copy_octet_string(v32_t *x, const uint8_t s[4]); + +void +v64_copy_octet_string(v64_t *x, const uint8_t s[8]); + +void +v128_add(v128_t *z, v128_t *x, v128_t *y); + +int +octet_string_is_eq(uint8_t *a, uint8_t *b, int len); + +void +octet_string_set_to_zero(uint8_t *s, int len); + + + +/* + * the matrix A[] is stored in column format, i.e., A[i] is the ith + * column of the matrix +*/ +uint8_t +A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b); + + +#if 0 +#if WORDS_BIGENDIAN + +#define _v128_add(z, x, y) { \ + uint64_t tmp; \ + \ + tmp = x->v32[3] + y->v32[3]; \ + z->v32[3] = (uint32_t) tmp; \ + \ + tmp = x->v32[2] + y->v32[2] + (tmp >> 32); \ + z->v32[2] = (uint32_t) tmp; \ + \ + tmp = x->v32[1] + y->v32[1] + (tmp >> 32); \ + z->v32[1] = (uint32_t) tmp; \ + \ + tmp = x->v32[0] + y->v32[0] + (tmp >> 32); \ + z->v32[0] = (uint32_t) tmp; \ +} + +#else /* assume little endian architecture */ + +#define _v128_add(z, x, y) { \ + uint64_t tmp; \ + \ + tmp = htonl(x->v32[3]) + htonl(y->v32[3]); \ + z->v32[3] = ntohl((uint32_t) tmp); \ + \ + tmp = htonl(x->v32[2]) + htonl(y->v32[2]) \ + + htonl(tmp >> 32); \ + z->v32[2] = ntohl((uint32_t) tmp); \ + \ + tmp = htonl(x->v32[1]) + htonl(y->v32[1]) \ + + htonl(tmp >> 32); \ + z->v32[1] = ntohl((uint32_t) tmp); \ + \ + tmp = htonl(x->v32[0]) + htonl(y->v32[0]) \ + + htonl(tmp >> 32); \ + z->v32[0] = ntohl((uint32_t) tmp); \ +} + +#endif /* WORDS_BIGENDIAN */ +#endif + +#ifdef DATATYPES_USE_MACROS /* little functions are really macros */ + +#define v128_set_to_zero(z) _v128_set_to_zero(z) +#define v128_copy(z, x) _v128_copy(z, x) +#define v128_xor(z, x, y) _v128_xor(z, x, y) +#define v128_and(z, x, y) _v128_and(z, x, y) +#define v128_or(z, x, y) _v128_or(z, x, y) +#define v128_complement(x) _v128_complement(x) +#define v128_is_eq(x, y) _v128_is_eq(x, y) +#define v128_xor_eq(x, y) _v128_xor_eq(x, y) +#define v128_get_bit(x, i) _v128_get_bit(x, i) +#define v128_set_bit(x, i) _v128_set_bit(x, i) +#define v128_clear_bit(x, i) _v128_clear_bit(x, i) +#define v128_set_bit_to(x, i, y) _v128_set_bit_to(x, i, y) + +#else + +void +v128_set_to_zero(v128_t *x); + +int +v128_is_eq(const v128_t *x, const v128_t *y); + +void +v128_copy(v128_t *x, const v128_t *y); + +void +v128_xor(v128_t *z, v128_t *x, v128_t *y); + +void +v128_and(v128_t *z, v128_t *x, v128_t *y); + +void +v128_or(v128_t *z, v128_t *x, v128_t *y); + +void +v128_complement(v128_t *x); + +int +v128_get_bit(const v128_t *x, int i); + +void +v128_set_bit(v128_t *x, int i) ; + +void +v128_clear_bit(v128_t *x, int i); + +void +v128_set_bit_to(v128_t *x, int i, int y); + +#endif /* DATATYPES_USE_MACROS */ + +/* + * octet_string_is_eq(a,b, len) returns 1 if the length len strings a + * and b are not equal, returns 0 otherwise + */ + +int +octet_string_is_eq(uint8_t *a, uint8_t *b, int len); + +void +octet_string_set_to_zero(uint8_t *s, int len); + + +/* + * functions manipulating bit_vector_t + * + * A bitvector_t consists of an array of words and an integer + * representing the number of significant bits stored in the array. + * The bits are packed as follows: the least significant bit is that + * of word[0], while the most significant bit is the nth most + * significant bit of word[m], where length = bits_per_word * m + n. + * + */ + +#define bits_per_word 32 +#define bytes_per_word 4 + +typedef struct { + uint32_t length; + uint32_t *word; +} bitvector_t; + +int +bitvector_alloc(bitvector_t *v, unsigned long length); + +void +bitvector_set_bit(bitvector_t *v, int bit_index); + +int +bitvector_get_bit(const bitvector_t *v, int bit_index); + +int +bitvector_print_hex(const bitvector_t *v, FILE *stream); + +int +bitvector_set_from_hex(bitvector_t *v, char *string); + +#endif /* MATH_H */ + + + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/crypto_types.h b/src/libs/resiprocate/contrib/srtp/crypto/include/crypto_types.h new file mode 100644 index 00000000..0ce50f4b --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/crypto_types.h @@ -0,0 +1,206 @@ +/* + * crypto_types.h + * + * constants for cipher types and auth func types + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef CRYPTO_TYPES_H +#define CRYPTO_TYPES_H + +/** + * @defgroup Algos Cryptographic Algorithms + * + * + * This library provides several different cryptographic algorithms, + * each of which can be selected by using the cipher_type_id_t and + * auth_type_id_t. These algorithms are documented below. + * + * Authentication functions that use the Universal Security Transform + * (UST) must be used in conjunction with a cipher other than the null + * cipher. These functions require a per-message pseudorandom input + * that is generated by the cipher. + * + * The identifiers STRONGHOLD_AUTH and STRONGHOLD_CIPHER identify the + * strongest available authentication function and cipher, + * respectively. They are resolved at compile time to the strongest + * available algorithm. The stronghold algorithms can serve as did + * the keep of a medieval fortification; they provide the strongest + * defense (or the last refuge). + * + * @{ + */ + +/** + * @defgroup Ciphers Cipher Types + * + * @brief Each cipher type is identified by an unsigned integer. The + * cipher types available in this edition of libSRTP are given + * by the #defines below. + * + * A cipher_type_id_t is an identifier for a cipher_type; only values + * given by the #defines above (or those present in the file + * crypto_types.h) should be used. + * + * The identifier STRONGHOLD_CIPHER indicates the strongest available + * cipher, allowing an application to choose the strongest available + * algorithm without any advance knowledge about the avaliable + * algorithms. + * + * @{ + */ + +/** + * @brief The null cipher performs no encryption. + * + * The NULL_CIPHER leaves its inputs unaltered, during both the + * encryption and decryption operations. This cipher can be chosen + * to indicate that no encryption is to be performed. + */ +#define NULL_CIPHER 0 + +/** + * @brief AES-128 Integer Counter Mode (AES ICM) + * + * AES-128 ICM is the variant of counter mode that is used by Secure RTP. + * This cipher uses a 16-octet key and a 30-octet offset (or salt) value. + */ +#define AES_128_ICM 1 + +/** + * @brief SEAL 3.0 + * + * SEAL is the Software-Optimized Encryption Algorithm of Coppersmith + * and Rogaway. Nota bene: this cipher is IBM proprietary. + */ +#define SEAL 2 + +/** + * @brief AES-128 Integer Counter Mode (AES ICM) + * + * AES-128 ICM is the variant of counter mode that is used by Secure RTP. + * This cipher uses a 16-octet key and a 30-octet offset (or salt) value. + */ +#define AES_128_CBC 3 + +/** + * @brief Strongest available cipher. + * + * This identifier resolves to the strongest cipher type available. + */ +#define STRONGHOLD_CIPHER AES_128_ICM + +/** + * @} + */ + + + +/** + * @defgroup Authentication Authentication Function Types + * + * @brief Each authentication function type is identified by an + * unsigned integer. The authentication function types available in + * this edition of libSRTP are given by the #defines below. + * + * An auth_type_id_t is an identifier for an authentication function type; + * only values given by the #defines above (or those present in the + * file crypto_types.h) should be used. + * + * The identifier STRONGHOLD_AUTH indicates the strongest available + * authentication function, allowing an application to choose the + * strongest available algorithm without any advance knowledge about + * the avaliable algorithms. The stronghold algorithms can serve as + * did the keep of a medieval fortification; they provide the + * strongest defense (or the last refuge). + * + * @{ + */ + +/** + * @brief The null authentication function performs no authentication. + * + * The NULL_AUTH function does nothing, and can be selected to indicate + * that authentication should not be performed. + */ +#define NULL_AUTH 0 + +/** + * @brief UST with TMMH Version 2 + * + * UST_TMMHv2 implements the Truncated Multi-Modular Hash using + * UST. This function must be used in conjunction with a cipher other + * than the null cipher. + * with a cipher. + */ +#define UST_TMMHv2 1 + +/** + * @brief (UST) AES-128 XORMAC + * + * UST_AES_128_XMAC implements AES-128 XORMAC, using UST. Nota bene: + * the XORMAC algorithm is IBM proprietary. + */ +#define UST_AES_128_XMAC 2 + +/** + * @brief HMAC-SHA1 + * + * HMAC_SHA1 implements the Hash-based MAC using the NIST Secure + * Hash Algorithm version 1 (SHA1). + */ +#define HMAC_SHA1 3 + +/** + * @brief Strongest available authentication function. + * + * This identifier resolves to the strongest available authentication + * function. + */ +#define STRONGHOLD_AUTH HMAC_SHA1 + +/** + * @} + */ +/** + * @} + */ + +#endif /* CRYPTO_TYPES_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/cryptoalg.h b/src/libs/resiprocate/contrib/srtp/crypto/include/cryptoalg.h new file mode 100644 index 00000000..d9f0441e --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/cryptoalg.h @@ -0,0 +1,133 @@ +/* + * cryptoalg.h + * + * API for authenticated encryption crypto algorithms + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef CRYPTOALG_H +#define CRYPTOALG_H + +#include "err.h" + +/** + * @defgroup Crypto Cryptography + * + * Zed uses a simple interface to a cryptographic transform. + * + * @{ + */ + +/** + * @brief applies a crypto algorithm + * + * The function pointer cryptoalg_func_t points to a function that + * implements a crypto transform, and provides a uniform API for + * accessing crypto mechanisms. + * + * @param key location of secret key + * + * @param clear data to be authenticated but not encrypted + * + * @param clear_len length of data to be authenticated but not encrypted + * + * @param iv location to write the Initialization Vector (IV) + * + * @param protect location of the data to be encrypted and + * authenticated (before the function call), and the ciphertext + * and authentication tag (after the call) + * + * @param protected_len location of the length of the data to be + * encrypted and authenticated (before the function call), and the + * length of the ciphertext (after the call) + * + */ + +typedef err_status_t (*cryptoalg_func_t) + (void *key, + const void *clear, + unsigned clear_len, + void *iv, + void *protect, + unsigned *protected_len); + +typedef +err_status_t (*cryptoalg_inv_t) + (void *key, /* location of secret key */ + const void *clear, /* data to be authenticated only */ + unsigned clear_len, /* length of data to be authenticated only */ + void *iv, /* location of iv */ + void *opaque, /* data to be decrypted and authenticated */ + unsigned *opaque_len /* location of the length of data to be + * decrypted and authd (before and after) + */ + ); + +typedef struct cryptoalg_ctx_t { + cryptoalg_func_t enc; + cryptoalg_inv_t dec; + unsigned key_len; + unsigned iv_len; + unsigned auth_tag_len; + unsigned max_expansion; +} cryptoalg_ctx_t; + +typedef cryptoalg_ctx_t *cryptoalg_t; + +#define cryptoalg_get_key_len(cryptoalg) ((cryptoalg)->key_len) + +#define cryptoalg_get_iv_len(cryptoalg) ((cryptoalg)->iv_len) + +#define cryptoalg_get_auth_tag_len(cryptoalg) ((cryptoalg)->auth_tag_len) + +int +cryptoalg_get_id(cryptoalg_t c); + +cryptoalg_t +cryptoalg_find_by_id(int id); + + +/** + * @} + */ + +#endif /* CRYPTOALG_H */ + + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/datatypes.h b/src/libs/resiprocate/contrib/srtp/crypto/include/datatypes.h new file mode 100644 index 00000000..4f86b556 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/datatypes.h @@ -0,0 +1,427 @@ +/* + * datatypes.h + * + * data types for bit vectors and finite fields + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef _DATATYPES_H +#define _DATATYPES_H + +#include "integers.h" /* definitions of uint32_t, et cetera */ +#include "alloc.h" + +#include + +#ifndef SRTP_KERNEL +# include +# include +# include +# ifdef HAVE_NETINET_IN_H +# include +# elif defined HAVE_WINSOCK2_H +# include +# endif +#endif + + +/* if DATATYPES_USE_MACROS is defined, then little functions are macros */ +#define DATATYPES_USE_MACROS + +typedef union { + uint8_t v8[2]; + uint16_t value; +} v16_t; + +typedef union { + uint8_t v8[4]; + uint16_t v16[2]; + uint32_t value; +} v32_t; + +typedef union { + uint8_t v8[8]; + uint16_t v16[4]; + uint32_t v32[2]; + uint64_t value; +} v64_t; + +typedef union { + uint8_t v8[16]; + uint16_t v16[8]; + uint32_t v32[4]; + uint64_t v64[2]; +} v128_t; + + + +/* some useful and simple math functions */ + +#define pow_2(X) ( (unsigned int)1 << (X) ) /* 2^X */ + +#define pow_minus_one(X) ( (X) ? -1 : 1 ) /* (-1)^X */ + + +/* + * octet_get_weight(x) returns the hamming weight (number of bits equal to + * one) in the octet x + */ + +int +octet_get_weight(uint8_t octet); + +char * +octet_bit_string(uint8_t x); + +#define MAX_PRINT_STRING_LEN 1024 + +char * +octet_string_hex_string(const void *str, int length); + +char * +v128_bit_string(v128_t *x); + +char * +v128_hex_string(v128_t *x); + +uint8_t +nibble_to_hex_char(uint8_t nibble); + +char * +char_to_hex_string(char *x, int num_char); + +uint8_t +hex_string_to_octet(char *s); + +/* + * hex_string_to_octet_string(raw, hex, len) converts the hexadecimal + * string at *hex (of length len octets) to the equivalent raw data + * and writes it to *raw. + * + * if a character in the hex string that is not a hexadeciaml digit + * (0123456789abcdefABCDEF) is encountered, the function stops writing + * data to *raw + * + * the number of hex digits copied (which is two times the number of + * octets in *raw) is returned + */ + +int +hex_string_to_octet_string(char *raw, char *hex, int len); + +v128_t +hex_string_to_v128(char *s); + +void +v128_copy_octet_string(v128_t *x, const uint8_t s[16]); + +void +v128_left_shift(v128_t *x, int index); + +void +v128_right_shift(v128_t *x, int index); + +/* + * the following macros define the data manipulation functions + * + * If DATATYPES_USE_MACROS is defined, then these macros are used + * directly (and function call overhead is avoided). Otherwise, + * the macros are used through the functions defined in datatypes.c + * (and the compiler provides better warnings). + */ + +#define _v128_set_to_zero(x) \ +( \ + (x)->v32[0] = 0, \ + (x)->v32[1] = 0, \ + (x)->v32[2] = 0, \ + (x)->v32[3] = 0 \ +) + +#define _v128_copy(x, y) \ +( \ + (x)->v32[0] = (y)->v32[0], \ + (x)->v32[1] = (y)->v32[1], \ + (x)->v32[2] = (y)->v32[2], \ + (x)->v32[3] = (y)->v32[3] \ +) + +#define _v128_xor(z, x, y) \ +( \ + (z)->v32[0] = (x)->v32[0] ^ (y)->v32[0], \ + (z)->v32[1] = (x)->v32[1] ^ (y)->v32[1], \ + (z)->v32[2] = (x)->v32[2] ^ (y)->v32[2], \ + (z)->v32[3] = (x)->v32[3] ^ (y)->v32[3] \ +) + +#define _v128_and(z, x, y) \ +( \ + (z)->v32[0] = (x)->v32[0] & (y)->v32[0], \ + (z)->v32[1] = (x)->v32[1] & (y)->v32[1], \ + (z)->v32[2] = (x)->v32[2] & (y)->v32[2], \ + (z)->v32[3] = (x)->v32[3] & (y)->v32[3] \ +) + +#define _v128_or(z, x, y) \ +( \ + (z)->v32[0] = (x)->v32[0] | (y)->v32[0], \ + (z)->v32[1] = (x)->v32[1] | (y)->v32[1], \ + (z)->v32[2] = (x)->v32[2] | (y)->v32[2], \ + (z)->v32[3] = (x)->v32[3] | (y)->v32[3] \ +) + +#define _v128_complement(x) \ +( \ + (x)->v32[0] = ~(x)->v32[0], \ + (x)->v32[1] = ~(x)->v32[1], \ + (x)->v32[2] = ~(x)->v32[2], \ + (x)->v32[3] = ~(x)->v32[3] \ +) + +/* ok for NO_64BIT_MATH if it can compare uint64_t's (even as structures) */ +#define _v128_is_eq(x, y) \ + (((x)->v64[0] == (y)->v64[0]) && ((x)->v64[1] == (y)->v64[1])) + + +#ifdef NO_64BIT_MATH +#define _v128_xor_eq(z, x) \ +( \ + (z)->v32[0] ^= (x)->v32[0], \ + (z)->v32[1] ^= (x)->v32[1], \ + (z)->v32[2] ^= (x)->v32[2], \ + (z)->v32[3] ^= (x)->v32[3] \ +) +#else +#define _v128_xor_eq(z, x) \ +( \ + (z)->v64[0] ^= (x)->v64[0], \ + (z)->v64[1] ^= (x)->v64[1] \ +) +#endif + +/* NOTE! This assumes an odd ordering! */ +/* This will not be compatible directly with math on some processors */ +/* bit 0 is first 32-bit word, low order bit. in little-endian, that's + the first byte of the first 32-bit word. In big-endian, that's + the 3rd byte of the first 32-bit word */ +/* The get/set bit code is used by the replay code ONLY, and it doesn't + really care which bit is which. AES does care which bit is which, but + doesn't use the 128-bit get/set or 128-bit shifts */ + +#define _v128_get_bit(x, bit) \ +( \ + ((((x)->v32[(bit) >> 5]) >> ((bit) & 31)) & 1) \ +) + +#define _v128_set_bit(x, bit) \ +( \ + (((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit) & 31))) \ +) + +#define _v128_clear_bit(x, bit) \ +( \ + (((x)->v32[(bit) >> 5]) &= ~((uint32_t)1 << ((bit) & 31))) \ +) + +#define _v128_set_bit_to(x, bit, value) \ +( \ + (value) ? _v128_set_bit(x, bit) : \ + _v128_clear_bit(x, bit) \ +) + + +#if 0 +/* nothing uses this */ +#ifdef WORDS_BIGENDIAN + +#define _v128_add(z, x, y) { \ + uint64_t tmp; \ + \ + tmp = x->v32[3] + y->v32[3]; \ + z->v32[3] = (uint32_t) tmp; \ + \ + tmp = x->v32[2] + y->v32[2] + (tmp >> 32); \ + z->v32[2] = (uint32_t) tmp; \ + \ + tmp = x->v32[1] + y->v32[1] + (tmp >> 32); \ + z->v32[1] = (uint32_t) tmp; \ + \ + tmp = x->v32[0] + y->v32[0] + (tmp >> 32); \ + z->v32[0] = (uint32_t) tmp; \ +} + +#else /* assume little endian architecture */ + +#define _v128_add(z, x, y) { \ + uint64_t tmp; \ + \ + tmp = htonl(x->v32[3]) + htonl(y->v32[3]); \ + z->v32[3] = ntohl((uint32_t) tmp); \ + \ + tmp = htonl(x->v32[2]) + htonl(y->v32[2]) \ + + htonl(tmp >> 32); \ + z->v32[2] = ntohl((uint32_t) tmp); \ + \ + tmp = htonl(x->v32[1]) + htonl(y->v32[1]) \ + + htonl(tmp >> 32); \ + z->v32[1] = ntohl((uint32_t) tmp); \ + \ + tmp = htonl(x->v32[0]) + htonl(y->v32[0]) \ + + htonl(tmp >> 32); \ + z->v32[0] = ntohl((uint32_t) tmp); \ +} +#endif /* WORDS_BIGENDIAN */ +#endif /* 0 */ + + +#ifdef DATATYPES_USE_MACROS /* little functions are really macros */ + +#define v128_set_to_zero(z) _v128_set_to_zero(z) +#define v128_copy(z, x) _v128_copy(z, x) +#define v128_xor(z, x, y) _v128_xor(z, x, y) +#define v128_and(z, x, y) _v128_and(z, x, y) +#define v128_or(z, x, y) _v128_or(z, x, y) +#define v128_complement(x) _v128_complement(x) +#define v128_is_eq(x, y) _v128_is_eq(x, y) +#define v128_xor_eq(x, y) _v128_xor_eq(x, y) +#define v128_get_bit(x, i) _v128_get_bit(x, i) +#define v128_set_bit(x, i) _v128_set_bit(x, i) +#define v128_clear_bit(x, i) _v128_clear_bit(x, i) +#define v128_set_bit_to(x, i, y) _v128_set_bit_to(x, i, y) + +#else + +void +v128_set_to_zero(v128_t *x); + +int +v128_is_eq(const v128_t *x, const v128_t *y); + +void +v128_copy(v128_t *x, const v128_t *y); + +void +v128_xor(v128_t *z, v128_t *x, v128_t *y); + +void +v128_and(v128_t *z, v128_t *x, v128_t *y); + +void +v128_or(v128_t *z, v128_t *x, v128_t *y); + +void +v128_complement(v128_t *x); + +int +v128_get_bit(const v128_t *x, int i); + +void +v128_set_bit(v128_t *x, int i) ; + +void +v128_clear_bit(v128_t *x, int i); + +void +v128_set_bit_to(v128_t *x, int i, int y); + +#endif /* DATATYPES_USE_MACROS */ + +/* + * octet_string_is_eq(a,b, len) returns 1 if the length len strings a + * and b are not equal, returns 0 otherwise + */ + +int +octet_string_is_eq(uint8_t *a, uint8_t *b, int len); + +void +octet_string_set_to_zero(uint8_t *s, int len); + + +#ifndef SRTP_KERNEL_LINUX + +/* + * Convert big endian integers to CPU byte order. + */ +#ifdef WORDS_BIGENDIAN +/* Nothing to do. */ +# define be32_to_cpu(x) (x) +# define be64_to_cpu(x) (x) +#elif defined(HAVE_BYTESWAP_H) +/* We have (hopefully) optimized versions in byteswap.h */ +# include +# define be32_to_cpu(x) bswap_32((x)) +# define be64_to_cpu(x) bswap_64((x)) +#else + +#if defined(__GNUC__) && defined(HAVE_X86) +/* Fall back. */ +static inline uint32_t be32_to_cpu(uint32_t v) { + /* optimized for x86. */ + asm("bswap %0" : "=r" (v) : "0" (v)); + return v; +} +# else /* HAVE_X86 */ +# ifdef HAVE_NETINET_IN_H +# include +# elif defined HAVE_WINSOCK2_H +# include +# endif +# define be32_to_cpu(x) ntohl((x)) +# endif /* HAVE_X86 */ + +static inline uint64_t be64_to_cpu(uint64_t v) { +# ifdef NO_64BIT_MATH + /* use the make64 functions to do 64-bit math */ + v = make64(htonl(low32(v)),htonl(high32(v))); +# else + /* use the native 64-bit math */ + v= (uint64_t)((be32_to_cpu((uint32_t)(v >> 32))) | (((uint64_t)be32_to_cpu((uint32_t)v)) << 32)); +# endif + return v; +} + +#endif /* ! SRTP_KERNEL_LINUX */ + +#endif /* WORDS_BIGENDIAN */ + +#endif /* _DATATYPES_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/err.h b/src/libs/resiprocate/contrib/srtp/crypto/include/err.h new file mode 100644 index 00000000..1a6e1701 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/err.h @@ -0,0 +1,174 @@ +/* + * err.h + * + * error status codes + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef ERR_H +#define ERR_H + +#include "datatypes.h" + +/** + * @defgroup Error Error Codes + * + * Error status codes are represented by the enumeration err_status_t. + * + * @{ + */ + + +/* + * @brief err_status_t defines error codes. + * + * The enumeration err_status_t defines error codes. Note that the + * value of err_status_ok is equal to zero, which can simplify error + * checking somewhat. + * + */ +typedef enum { + err_status_ok = 0, /**< nothing to report */ + err_status_fail = 1, /**< unspecified failure */ + err_status_bad_param = 2, /**< unsupported parameter */ + err_status_alloc_fail = 3, /**< couldn't allocate memory */ + err_status_dealloc_fail = 4, /**< couldn't deallocate properly */ + err_status_init_fail = 5, /**< couldn't initialize */ + err_status_terminus = 6, /**< can't process as much data as requested */ + err_status_auth_fail = 7, /**< authentication failure */ + err_status_cipher_fail = 8, /**< cipher failure */ + err_status_replay_fail = 9, /**< replay check failed (bad index) */ + err_status_replay_old = 10, /**< replay check failed (index too old) */ + err_status_algo_fail = 11, /**< algorithm failed test routine */ + err_status_no_such_op = 12, /**< unsupported operation */ + err_status_no_ctx = 13, /**< no appropriate context found */ + err_status_cant_check = 14, /**< unable to perform desired validation */ + err_status_key_expired = 15, /**< can't use key any more */ + err_status_socket_err = 16, /**< error in use of socket */ + err_status_signal_err = 17, /**< error in use POSIX signals */ + err_status_nonce_bad = 18, /**< nonce check failed */ + err_status_read_fail = 19, /**< couldn't read data */ + err_status_write_fail = 20, /**< couldn't write data */ + err_status_parse_err = 21, /**< error pasring data */ + err_status_encode_err = 22, /**< error encoding data */ + err_status_semaphore_err = 23,/**< error while using semaphores */ + err_status_pfkey_err = 24 /**< error while using pfkey */ +} err_status_t; + +/** + * @} + */ + +typedef enum { + err_level_emergency = 0, + err_level_alert, + err_level_critical, + err_level_error, + err_level_warning, + err_level_notice, + err_level_info, + err_level_debug, + err_level_none +} err_reporting_level_t; + +/* + * err_reporting_init prepares the error system. If + * ERR_REPORTING_SYSLOG is defined, it will open syslog. + * + * The ident argument is a string that will be prepended to + * all syslog messages. It is conventionally argv[0]. + */ + +err_status_t +err_reporting_init(char *ident); + +#ifdef SRTP_KERNEL_LINUX +extern err_reporting_level_t err_level; +#else + +/* + * keydaemon_report_error reports a 'printf' formatted error + * string, followed by a an arg list. The priority argument + * is equivalent to that defined for syslog. + * + * Errors will be reported to ERR_REPORTING_FILE, if defined, and to + * syslog, if ERR_REPORTING_SYSLOG is defined. + * + */ + +void +err_report(int priority, char *format, ...); +#endif /* ! SRTP_KERNEL_LINUX */ + + +/* + * debug_module_t defines a debug module + */ + +typedef struct { + int on; /* 1 if debugging is on, 0 if it is off */ + char *name; /* printable name for debug module */ +} debug_module_t; + +#ifdef ENABLE_DEBUGGING + +#define debug_on(mod) (mod).on = 1 + +#define debug_off(mod) (mod).on = 0 + +/* use err_report() to report debug message */ +#define debug_print(mod, format, arg) \ + if (mod.on) err_report(err_level_debug, ("%s: " format "\n"), mod.name, arg) +#define debug_print2(mod, format, arg1,arg2) \ + if (mod.on) err_report(err_level_debug, ("%s: " format "\n"), mod.name, arg1,arg2) + +#else + +/* define macros to do nothing */ +#define debug_print(mod, format, arg) + +#define debug_on(mod) + +#define debug_off(mod) + +#endif + +#endif /* ERR_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/gf2_8.h b/src/libs/resiprocate/contrib/srtp/crypto/include/gf2_8.h new file mode 100644 index 00000000..098d37c9 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/gf2_8.h @@ -0,0 +1,79 @@ +/* + * gf2_8.h + * + * GF(256) implementation + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef GF2_8_H +#define GF2_8_H + +#include "datatypes.h" /* for uint8_t definition */ + +typedef uint8_t gf2_8; + +#define gf2_8_field_polynomial 0x1B + +/* + * gf2_8_shift(x) returns + */ + +/* + * gf2_8_shift(z) returns the result of the GF(2^8) 'multiply by x' + * operation, using the field representation from AES; that is, the + * next gf2_8 value in the cyclic representation of that field. The + * value z should be an uint8_t. + */ + +#define gf2_8_shift(z) (((z) & 128) ? \ + (((z) << 1) ^ gf2_8_field_polynomial) : ((z) << 1)) + +gf2_8 +gf2_8_compute_inverse(gf2_8 x); + +void +test_gf2_8(void); + +gf2_8 +gf2_8_multiply(gf2_8 x, gf2_8 y); + +#endif /* GF2_8_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/hmac.h b/src/libs/resiprocate/contrib/srtp/crypto/include/hmac.h new file mode 100644 index 00000000..262c0e2d --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/hmac.h @@ -0,0 +1,78 @@ +/* + * hmac.h + * + * interface to hmac auth_type_t + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef HMAC_H +#define HMAC_H + +#include "auth.h" +#include "sha1.h" + +typedef struct { + uint8_t opad[64]; + sha1_ctx_t ctx; + sha1_ctx_t init_ctx; +} hmac_ctx_t; + +err_status_t +hmac_alloc(auth_t **a, int key_len, int out_len); + +err_status_t +hmac_dealloc(auth_t *a); + +err_status_t +hmac_init(hmac_ctx_t *state, const uint8_t *key, int key_len); + +err_status_t +hmac_start(hmac_ctx_t *state); + +err_status_t +hmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets); + +err_status_t +hmac_compute(hmac_ctx_t *state, const void *message, + int msg_octets, int tag_len, uint8_t *result); + + +#endif /* HMAC_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/integers.h b/src/libs/resiprocate/contrib/srtp/crypto/include/integers.h new file mode 100644 index 00000000..7010efdd --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/integers.h @@ -0,0 +1,147 @@ +/* + * integers.h + * + * defines integer types (or refers to their definitions) + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef INTEGERS_H +#define INTEGERS_H + +#include "config.h" /* configuration file, using autoconf */ + +#ifdef SRTP_KERNEL + +#include "kernel_compat.h" + +#else /* SRTP_KERNEL */ + +/* use standard integer definitions, if they're available */ +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_INT_TYPES_H +# include /* this exists on Sun OS */ +#endif +#ifdef HAVE_MACHINE_TYPES_H +# include +#endif + +/* Can we do 64 bit integers? */ +#ifndef HAVE_UINT64_T +# if SIZEOF_UNSIGNED_LONG == 8 +typedef unsigned long uint64_t; +# elif SIZEOF_UNSIGNED_LONG_LONG == 8 +typedef unsigned long long uint64_t; +# else +# define NO_64BIT_MATH 1 +# endif +#endif + +/* Reasonable defaults for 32 bit machines - you may need to + * edit these definitions for your own machine. */ +#ifndef HAVE_UINT8_T +typedef unsigned char uint8_t; +#endif +#ifndef HAVE_UINT16_T +typedef unsigned short int uint16_t; +#endif +#ifndef HAVE_UINT32_T +typedef unsigned int uint32_t; +#endif + + +#ifdef NO_64BIT_MATH +typedef double uint64_t; +/* assert that sizeof(double) == 8 */ +extern uint64_t make64(uint32_t high, uint32_t low); +extern uint32_t high32(uint64_t value); +extern uint32_t low32(uint64_t value); +#endif + +#endif /* SRTP_KERNEL */ + +/* These macros are to load and store 32-bit values from un-aligned + addresses. This is required for processors that do not allow unaligned + loads. */ +#ifdef ALIGNMENT_32BIT_REQUIRED +/* Note that if it's in a variable, you can memcpy it */ +#ifdef WORDS_BIGENDIAN +#define PUT_32(addr,value) \ + { \ + ((unsigned char *) (addr))[0] = (value >> 24); \ + ((unsigned char *) (addr))[1] = (value >> 16) & 0xff; \ + ((unsigned char *) (addr))[2] = (value >> 8) & 0xff; \ + ((unsigned char *) (addr))[3] = (value) & 0xff; \ + } +#define GET_32(addr) ((((unsigned char *) (addr))[0] << 24) | \ + (((unsigned char *) (addr))[1] << 16) | \ + (((unsigned char *) (addr))[2] << 8) | \ + (((unsigned char *) (addr))[3])) +#else +#define PUT_32(addr,value) \ + { \ + ((unsigned char *) (addr))[3] = (value >> 24); \ + ((unsigned char *) (addr))[2] = (value >> 16) & 0xff; \ + ((unsigned char *) (addr))[1] = (value >> 8) & 0xff; \ + ((unsigned char *) (addr))[0] = (value) & 0xff; \ + } +#define GET_32(addr) ((((unsigned char *) (addr))[3] << 24) | \ + (((unsigned char *) (addr))[2] << 16) | \ + (((unsigned char *) (addr))[1] << 8) | \ + (((unsigned char *) (addr))[0])) +#endif // WORDS_BIGENDIAN +#else +#define PUT_32(addr,value) *(((uint32_t *) (addr)) = (value) +#define GET_32(addr) (*(((uint32_t *) (addr))) +#endif + +#endif /* INTEGERS_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/kernel_compat.h b/src/libs/resiprocate/contrib/srtp/crypto/include/kernel_compat.h new file mode 100644 index 00000000..59d1898e --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/kernel_compat.h @@ -0,0 +1,84 @@ +/* + * kernel_compat.h + * + * Compatibility stuff for building in kernel context where standard + * C headers and library are not available. + * + * Marcus Sundberg + * Ingate Systems AB + */ +/* + * + * Copyright(c) 2005 Ingate Systems AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the author(s) nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef KERNEL_COMPAT_H +#define KERNEL_COMPAT_H + +#ifdef SRTP_KERNEL_LINUX + +#include +#include +#include +#include +#include + + +#define err_report(priority, ...) \ + do {\ + if (priority <= err_level) {\ + printk(__VA_ARGS__);\ + }\ + }while(0) + +#define clock() (jiffies) +#define time(x) (jiffies) + +/* rand() implementation. */ +#define RAND_MAX 32767 + +static inline int rand(void) +{ + uint32_t temp; + get_random_bytes(&temp, sizeof(temp)); + return temp % (RAND_MAX+1); +} + +/* stdio/stdlib implementation. */ +#define printf(...) printk(__VA_ARGS__) +#define exit(n) panic("%s:%d: exit(%d)\n", __FILE__, __LINE__, (n)) + +#endif /* SRTP_KERNEL_LINUX */ + +#endif /* KERNEL_COMPAT_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/key.h b/src/libs/resiprocate/contrib/srtp/crypto/include/key.h new file mode 100644 index 00000000..e7e07448 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/key.h @@ -0,0 +1,82 @@ +/* + * key.h + * + * key usage limits enforcement + * + * David A. Mcgrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef KEY_H +#define KEY_H + +#include "rdbx.h" /* for xtd_seq_num_t */ +#include "err.h" + +typedef struct key_limit_ctx_t *key_limit_t; + +typedef enum { + key_event_normal, + key_event_soft_limit, + key_event_hard_limit +} key_event_t; + +err_status_t +key_limit_set(key_limit_t key, const xtd_seq_num_t s); + +err_status_t +key_limit_clone(key_limit_t original, key_limit_t *new_key); + +err_status_t +key_limit_check(const key_limit_t key); + +key_event_t +key_limit_update(key_limit_t key); + +typedef enum { + key_state_normal, + key_state_past_soft_limit, + key_state_expired +} key_state_t; + +typedef struct key_limit_ctx_t { + xtd_seq_num_t num_left; + key_state_t state; +} key_limit_ctx_t; + +#endif /* KEY_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/null_auth.h b/src/libs/resiprocate/contrib/srtp/crypto/include/null_auth.h new file mode 100644 index 00000000..44f9a4a2 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/null_auth.h @@ -0,0 +1,68 @@ +/* + * null-auth.h + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef NULL_AUTH_H +#define NULL_AUTH_H + +#include "auth.h" + +typedef struct { + char foo; +} null_auth_ctx_t; + +err_status_t +null_auth_alloc(auth_t **a, int key_len, int out_len); + +err_status_t +null_auth_dealloc(auth_t *a); + +err_status_t +null_auth_init(null_auth_ctx_t *state, const uint8_t *key, int key_len); + +err_status_t +null_auth_compute (null_auth_ctx_t *state, uint8_t *message, + int msg_octets, int tag_len, uint8_t *result); + + +#endif /* NULL_AUTH_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/null_cipher.h b/src/libs/resiprocate/contrib/srtp/crypto/include/null_cipher.h new file mode 100644 index 00000000..7d6bbdd6 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/null_cipher.h @@ -0,0 +1,80 @@ +/* + * null-cipher.h + * + * header file for the null cipher + * + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef NULL_CIPHER_H +#define NULL_CIPHER_H + +#include "datatypes.h" +#include "cipher.h" + +typedef struct { + char foo ;/* empty, for now */ +} null_cipher_ctx_t; + + +/* + * none of these functions do anything (though future versions may keep + * track of bytes encrypted, number of instances, and/or other info). + */ + +err_status_t +null_cipher_init(null_cipher_ctx_t *c, const uint8_t *key); + +err_status_t +null_cipher_set_segment(null_cipher_ctx_t *c, + unsigned long index); + +err_status_t +null_cipher_encrypt(null_cipher_ctx_t *c, + unsigned char *buf, unsigned int *bytes_to_encr); + + +err_status_t +null_cipher_encrypt_aligned(null_cipher_ctx_t *c, + unsigned char *buf, int bytes_to_encr); + +#endif /* NULL_CIPHER_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/prng.h b/src/libs/resiprocate/contrib/srtp/crypto/include/prng.h new file mode 100644 index 00000000..fb96b5eb --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/prng.h @@ -0,0 +1,54 @@ +/* + * prng.h + * + * pseudorandom source + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +#ifndef PRNG_H +#define PRNG_H + +#include "rand_source.h" /* for rand_source_func_t definition */ +#include "aes.h" /* for aes */ +#include "aes_icm.h" /* for aes ctr */ + +#define MAX_PRNG_OUT_LEN 0xffffffffU + +/* + * x917_prng is an ANSI X9.17-like AES-based PRNG + */ + +typedef struct { + v128_t state; /* state data */ + aes_expanded_key_t key; /* secret key */ + uint32_t octet_count; /* number of octets output since last init */ + rand_source_func_t rand; /* random source for re-initialization */ +} x917_prng_t; + +err_status_t +x917_prng_init(rand_source_func_t random_source); + +err_status_t +x917_prng_get_octet_string(uint8_t *dest, uint32_t len); + + +/* + * ctr_prng is an AES-CTR based PRNG + */ + +typedef struct { + uint32_t octet_count; /* number of octets output since last init */ + aes_icm_ctx_t state; /* state data */ + rand_source_func_t rand; /* random source for re-initialization */ +} ctr_prng_t; + +err_status_t +ctr_prng_init(rand_source_func_t random_source); + +err_status_t +ctr_prng_get_octet_string(void *dest, uint32_t len); + + +#endif diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/rand_source.h b/src/libs/resiprocate/contrib/srtp/crypto/include/rand_source.h new file mode 100644 index 00000000..b4c21103 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/rand_source.h @@ -0,0 +1,91 @@ +/* + * rand_source.h + * + * implements a random source based on /dev/random + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef RAND_SOURCE +#define RAND_SOURCE + +#include "err.h" +#include "datatypes.h" + +err_status_t +rand_source_init(void); + +/* + * rand_source_get_octet_string() writes a random octet string. + * + * The function call rand_source_get_octet_string(dest, len) writes + * len octets of random data to the location to which dest points, + * and returns an error code. This error code should be checked, + * and if a failure is reported, the data in the buffer MUST NOT + * be used. + * + * warning: If the return code is not checked, then non-random + * data may inadvertently be used. + * + * returns: + * - err_status_ok if no problems occured. + * - [other] a problem occured, and no assumptions should + * be made about the contents of the destination + * buffer. + */ + +err_status_t +rand_source_get_octet_string(void *dest, uint32_t length); + +err_status_t +rand_source_deinit(void); + +/* + * function prototype for a random source function + * + * A rand_source_func_t writes num_octets at the location indicated by + * dest and returns err_status_ok. Any other return value indicates + * failure. + */ + +typedef err_status_t (*rand_source_func_t) + (void *dest, uint32_t num_octets); + +#endif /* RAND_SOURCE */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/rdb.h b/src/libs/resiprocate/contrib/srtp/crypto/include/rdb.h new file mode 100644 index 00000000..5a26c5e3 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/rdb.h @@ -0,0 +1,94 @@ +/* + * replay-database.h + * + * interface for a replay database for packet security + * + * David A. McGrew + * Cisco Systems, Inc. + */ + + +#ifndef REPLAY_DB_H +#define REPLAY_DB_H + +#include "integers.h" /* for uint32_t */ +#include "datatypes.h" /* for v128_t */ +#include "err.h" /* for err_status_t */ + +/* + * if the ith least significant bit is one, then the packet index + * window_end-i is in the database + */ + +typedef struct { + uint32_t window_start; /* packet index of the first bit in bitmask */ + v128_t bitmask; +} rdb_t; + +#define rdb_bits_in_bitmask (8*sizeof(v128_t)) + +/* + * rdb init + * + * initalizes rdb + * + * returns err_status_ok on success, err_status_t_fail otherwise + */ + +err_status_t +rdb_init(rdb_t *rdb); + + +/* + * rdb_check + * + * checks to see if index appears in rdb + * + * returns err_status_fail if the index already appears in rdb, + * returns err_status_ok otherwise + */ + +err_status_t +rdb_check(const rdb_t *rdb, uint32_t index); + +/* + * rdb_add_index + * + * adds index to rdb_t (and does *not* check if index appears in db) + * + * returns err_status_ok on success, err_status_fail otherwise + * + */ + +err_status_t +rdb_add_index(rdb_t *rdb, uint32_t index); + +/* + * the functions rdb_increment() and rdb_get_value() are for use by + * senders, not receivers - DO NOT use these functions on the same + * rdb_t upon which rdb_add_index is used! + */ + + +/* + * rdb_increment(db) increments the sequence number in db, if it is + * not too high + * + * return values: + * + * err_status_ok no problem + * err_status_key_expired sequence number too high + * + */ +err_status_t +rdb_increment(rdb_t *rdb); + +/* + * rdb_get_value(db) returns the current sequence number of db + */ + +uint32_t +rdb_get_value(const rdb_t *rdb); + + +#endif /* REPLAY_DB_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/rdbx.h b/src/libs/resiprocate/contrib/srtp/crypto/include/rdbx.h new file mode 100644 index 00000000..ce9ecf6f --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/rdbx.h @@ -0,0 +1,146 @@ +/* + * rdbx.h + * + * replay database with extended packet indices, using a rollover counter + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ + +#ifndef RDBX_H +#define RDBX_H + +#include "datatypes.h" +#include "err.h" + +/* #define ROC_TEST */ + +#ifndef ROC_TEST + +typedef uint16_t sequence_number_t; /* 16 bit sequence number */ +typedef uint32_t rollover_counter_t; /* 32 bit rollover counter */ + +#else /* use small seq_num and roc datatypes for testing purposes */ + +typedef unsigned char sequence_number_t; /* 8 bit sequence number */ +typedef uint16_t rollover_counter_t; /* 16 bit rollover counter */ + +#endif + +#define seq_num_median (1 << (8*sizeof(sequence_number_t) - 1)) +#define seq_num_max (1 << (8*sizeof(sequence_number_t))) + +/* + * An xtd_seq_num_t is a 64-bit unsigned integer used as an 'extended' + * sequence number. + */ + +typedef uint64_t xtd_seq_num_t; + + +/* + * An rdbx_t is a replay database with extended range; it uses an + * xtd_seq_num_t and a bitmask of recently received indices. + */ + +typedef struct { + xtd_seq_num_t index; + v128_t bitmask; +} rdbx_t; + + +/* + * rdbx_init(rdbx_ptr) + * + * initializes the rdbx pointed to by its argument, setting the + * rollover counter and sequence number to zero + */ + +err_status_t +rdbx_init(rdbx_t *rdbx); + + +/* + * rdbx_estimate_index(rdbx, guess, s) + * + * given an rdbx and a sequence number s (from a newly arrived packet), + * sets the contents of *guess to contain the best guess of the packet + * index to which s corresponds, and returns the difference between + * *guess and the locally stored synch info + */ + +int +rdbx_estimate_index(const rdbx_t *rdbx, + xtd_seq_num_t *guess, + sequence_number_t s); + +/* + * rdbx_check(rdbx, delta); + * + * rdbx_check(&r, delta) checks to see if the xtd_seq_num_t + * which is at rdbx->window_start + delta is in the rdb + * + */ + +err_status_t +rdbx_check(const rdbx_t *rdbx, int difference); + +/* + * replay_add_index(rdbx, delta) + * + * adds the xtd_seq_num_t at rdbx->window_start + delta to replay_db + * (and does *not* check if that xtd_seq_num_t appears in db) + * + * this function should be called *only* after replay_check has + * indicated that the index does not appear in the rdbx, and a mutex + * should protect the rdbx between these calls if necessary. + */ + +err_status_t +rdbx_add_index(rdbx_t *rdbx, int delta); + +/* + * xtd_seq_num_t functions - these are *internal* functions of rdbx, and + * shouldn't be used to manipulate rdbx internal values. use the rdbx + * api instead! + */ + + +/* index_init(&pi) initializes a packet index pi (sets it to zero) */ + +void +index_init(xtd_seq_num_t *pi); + +/* index_advance(&pi, s) advances a xtd_seq_num_t forward by s */ + +void +index_advance(xtd_seq_num_t *pi, sequence_number_t s); + + +/* + * index_guess(local, guess, s) + * + * given a xtd_seq_num_t local (which represents the highest + * known-to-be-good index) and a sequence number s (from a newly + * arrived packet), sets the contents of *guess to contain the best + * guess of the packet index to which s corresponds, and returns the + * difference between *guess and *local + */ + +int +index_guess(const xtd_seq_num_t *local, + xtd_seq_num_t *guess, + sequence_number_t s); + + +#endif /* RDBX_H */ + + + + + + + + + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/sha1.h b/src/libs/resiprocate/contrib/srtp/crypto/include/sha1.h new file mode 100644 index 00000000..e3af4d4b --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/sha1.h @@ -0,0 +1,108 @@ +/* + * sha1.h + * + * interface to the Secure Hash Algorithm v.1 (SHA-1), specified in + * FIPS 180-1 + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef SHA1_H +#define SHA1_H + +#include "err.h" +#include "datatypes.h" + +typedef struct { + uint32_t H[5]; /* state vector */ + uint32_t M[16]; /* message buffer */ + int octets_in_buffer; /* octets of message in buffer */ + uint32_t num_bits_in_msg; /* total number of bits in message */ +} sha1_ctx_t; + +/* + * sha1(&ctx, msg, len, output) hashes the len octets starting at msg + * into the SHA1 context, then writes the result to the 20 octets at + * output + * + */ + +void +sha1(const uint8_t *message, int octets_in_msg, uint32_t output[5]); + +/* + * sha1_init(&ctx) initializes the SHA1 context ctx + * + * sha1_update(&ctx, msg, len) hashes the len octets starting at msg + * into the SHA1 context + * + * sha1_final(&ctx, output) performs the final processing of the SHA1 + * context and writes the result to the 20 octets at output + * + */ + +void +sha1_init(sha1_ctx_t *ctx); + +void +sha1_update(sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg); + +void +sha1_final(sha1_ctx_t *ctx, uint32_t output[5]); + +/* + * The sha1_core function is INTERNAL to SHA-1, but it is declared + * here because it is also used by the cipher SEAL 3.0 in its key + * setup algorithm. + */ + +/* + * sha1_core(M, H) computes the core sha1 compression function, where M is + * the next part of the message and H is the intermediate state {H0, + * H1, ...} + * + * this function does not do any of the padding required in the + * complete sha1 function + */ + +void +sha1_core(const uint32_t M[16], uint32_t hash_value[5]); + +#endif /* SHA1_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/stat.h b/src/libs/resiprocate/contrib/srtp/crypto/include/stat.h new file mode 100644 index 00000000..e28b1314 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/stat.h @@ -0,0 +1,69 @@ +/* + * stats.h + * + * interface to statistical test functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright(c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef STAT_H +#define STAT_H + +#include "datatypes.h" /* for uint8_t */ +#include "err.h" /* for err_status_t */ +#include "rand_source.h" /* for rand_source_func_t definition */ + +err_status_t +stat_test_monobit(uint8_t *data); + +err_status_t +stat_test_poker(uint8_t *data); + +err_status_t +stat_test_runs(uint8_t *data); + +err_status_t +stat_test_rand_source(rand_source_func_t rs); + +err_status_t +stat_test_rand_source_with_repetition(rand_source_func_t source, unsigned num_trials); + +#endif /* STAT_H */ diff --git a/src/libs/resiprocate/contrib/srtp/crypto/include/xfm.h b/src/libs/resiprocate/contrib/srtp/crypto/include/xfm.h new file mode 100644 index 00000000..5837149b --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/include/xfm.h @@ -0,0 +1,139 @@ +/* + * xfm.h + * + * interface for abstract crypto transform + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +#ifndef XFM_H +#define XFM_H + +#include "crypto_kernel.h" +#include "err.h" + +/** + * @defgroup Crypto Cryptography + * + * A simple interface to an abstract cryptographic transform that + * provides both confidentiality and message authentication. + * + * @{ + */ + +/** + * @brief applies a crypto transform + * + * The function pointer xfm_func_t points to a function that + * implements a crypto transform, and provides a uniform API for + * accessing crypto mechanisms. + * + * @param key location of secret key + * + * @param clear data to be authenticated only + * + * @param clear_len length of data to be authenticated only + * + * @param iv location to write the Initialization Vector (IV) + * + * @param protect location of the data to be encrypted and + * authenticated (before the function call), and the ciphertext + * and authentication tag (after the call) + * + * @param protected_len location of the length of the data to be + * encrypted and authenticated (before the function call), and the + * length of the ciphertext (after the call) + * + * @param auth_tag location to write auth tag + */ + +typedef err_status_t (*xfm_func_t) + (void *key, + void *clear, + unsigned clear_len, + void *iv, + void *protect, + unsigned *protected_len, + void *auth_tag + ); + +typedef +err_status_t (*xfm_inv_t) + (void *key, /* location of secret key */ + void *clear, /* data to be authenticated only */ + unsigned clear_len, /* length of data to be authenticated only */ + void *iv, /* location of iv */ + void *opaque, /* data to be decrypted and authenticated */ + unsigned *opaque_len, /* location of the length of data to be + * decrypted and authd (before and after) + */ + void *auth_tag /* location of auth tag */ + ); + +typedef struct xfm_ctx_t { + xfm_func_t func; + xfm_inv_t inv; + unsigned key_len; + unsigned iv_len; + unsigned auth_tag_len; +} xfm_ctx_t; + +typedef xfm_ctx_t *xfm_t; + +#define xfm_get_key_len(xfm) ((xfm)->key_len) + +#define xfm_get_iv_len(xfm) ((xfm)->iv_len) + +#define xfm_get_auth_tag_len(xfm) ((xfm)->auth_tag_len) + + +/* cryptoalgo - 5/28 */ + +typedef err_status_t (*cryptoalg_func_t) + (void *key, + void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len + ); + +typedef +err_status_t (*cryptoalg_inv_t) + (void *key, /* location of secret key */ + void *clear, /* data to be authenticated only */ + unsigned clear_len, /* length of data to be authenticated only */ + void *iv, /* location of iv */ + void *opaque, /* data to be decrypted and authenticated */ + unsigned *opaque_len /* location of the length of data to be + * decrypted and authd (before and after) + */ + ); + +typedef struct cryptoalg_ctx_t { + cryptoalg_func_t enc; + cryptoalg_inv_t dec; + unsigned key_len; + unsigned iv_len; + unsigned auth_tag_len; + unsigned max_expansion; +} cryptoalg_ctx_t; + +typedef cryptoalg_ctx_t *cryptoalg_t; + +#define cryptoalg_get_key_len(cryptoalg) ((cryptoalg)->key_len) + +#define cryptoalg_get_iv_len(cryptoalg) ((cryptoalg)->iv_len) + +#define cryptoalg_get_auth_tag_len(cryptoalg) ((cryptoalg)->auth_tag_len) + + + +/** + * @} + */ + +#endif /* XFM_H */ + + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/kernel/alloc.c b/src/libs/resiprocate/contrib/srtp/crypto/kernel/alloc.c new file mode 100644 index 00000000..5dd09474 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/kernel/alloc.c @@ -0,0 +1,119 @@ +/* + * alloc.c + * + * memory allocation and deallocation + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "alloc.h" +#include "crypto_kernel.h" + +/* the debug module for memory allocation */ + +debug_module_t mod_alloc = { + 0, /* debugging is off by default */ + "alloc" /* printable name for module */ +}; + +/* + * Nota bene: the debugging statements for crypto_alloc() and + * crypto_free() have identical prefixes, which include the addresses + * of the memory locations on which they are operating. This fact can + * be used to locate memory leaks, by turning on memory debugging, + * grepping for 'alloc', then matching alloc and free calls by + * address. + */ + +#ifdef SRTP_KERNEL_LINUX + +#include + +void * +crypto_alloc(size_t size) { + void *ptr; + + ptr = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + + if (ptr) { + debug_print(mod_alloc, "(location: %p) allocated", ptr); + } else + debug_print(mod_alloc, "allocation failed (asked for %d bytes)\n", size); + + return ptr; +} + +void +crypto_free(void *ptr) { + + debug_print(mod_alloc, "(location: %p) freed", ptr); + + kfree(ptr); +} + + +#elif defined(HAVE_STDLIB_H) + +void * +crypto_alloc(size_t size) { + void *ptr; + + ptr = malloc(size); + + if (ptr) { + debug_print(mod_alloc, "(location: %p) allocated", ptr); + } else + debug_print(mod_alloc, "allocation failed (asked for %d bytes)\n", size); + + return ptr; +} + +void +crypto_free(void *ptr) { + + debug_print(mod_alloc, "(location: %p) freed", ptr); + + free(ptr); +} + +#else /* we need to define our own memory allocation routines */ + +#error no memory allocation defined yet + +#endif diff --git a/src/libs/resiprocate/contrib/srtp/crypto/kernel/crypto_kernel.c b/src/libs/resiprocate/contrib/srtp/crypto/kernel/crypto_kernel.c new file mode 100644 index 00000000..230dda62 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/kernel/crypto_kernel.c @@ -0,0 +1,523 @@ +/* + * crypto_kernel.c + * + * header for the cryptographic kernel + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "alloc.h" + +#include "crypto_kernel.h" + +/* the debug module for the crypto_kernel */ + +debug_module_t mod_crypto_kernel = { + 0, /* debugging is off by default */ + "crypto kernel" /* printable name for module */ +}; + +/* + * other debug modules that can be included in the kernel + */ + +extern debug_module_t mod_auth; +extern debug_module_t mod_cipher; +extern debug_module_t mod_stat; +extern debug_module_t mod_alloc; + +/* + * cipher types that can be included in the kernel + */ + +extern cipher_type_t null_cipher; +extern cipher_type_t aes_icm; +extern cipher_type_t aes_cbc; + + +/* + * auth func types that can be included in the kernel + */ + +extern auth_type_t null_auth; +extern auth_type_t hmac; + +/* crypto_kernel is a global variable, the only one of its datatype */ + +crypto_kernel_t +crypto_kernel = { + crypto_kernel_state_insecure, /* start off in insecure state */ + NULL, /* no cipher types yet */ + NULL, /* no auth types yet */ + NULL /* no debug modules yet */ +}; + +#define MAX_RNG_TRIALS 25 + +err_status_t +crypto_kernel_init() { + err_status_t status; + + /* check the security state */ + if (crypto_kernel.state == crypto_kernel_state_secure) { + + /* + * we're already in the secure state, but we've been asked to + * re-initialize, so we just re-run the self-tests and then return + */ + return crypto_kernel_status(); + } + + /* initialize error reporting system */ + status = err_reporting_init("crypto"); + if (status) + return status; + + /* load debug modules */ + status = crypto_kernel_load_debug_module(&mod_crypto_kernel); + if (status) + return status; + status = crypto_kernel_load_debug_module(&mod_auth); + if (status) + return status; + status = crypto_kernel_load_debug_module(&mod_cipher); + if (status) + return status; + status = crypto_kernel_load_debug_module(&mod_stat); + if (status) + return status; + status = crypto_kernel_load_debug_module(&mod_alloc); + if (status) + return status; + + /* initialize random number generator */ + status = rand_source_init(); + if (status) + return status; + + /* run FIPS-140 statistical tests on rand_source */ + status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS); + if (status) + return status; + + /* initialize pseudorandom number generator */ + status = ctr_prng_init(rand_source_get_octet_string); + if (status) + return status; + + /* run FIPS-140 statistical tests on ctr_prng */ + status = stat_test_rand_source_with_repetition(ctr_prng_get_octet_string, MAX_RNG_TRIALS); + if (status) + return status; + + /* load cipher types */ + status = crypto_kernel_load_cipher_type(&null_cipher, NULL_CIPHER); + if (status) + return status; + status = crypto_kernel_load_cipher_type(&aes_icm, AES_128_ICM); + if (status) + return status; + status = crypto_kernel_load_cipher_type(&aes_cbc, AES_128_CBC); + if (status) + return status; + + /* load auth func types */ + status = crypto_kernel_load_auth_type(&null_auth, NULL_AUTH); + if (status) + return status; + status = crypto_kernel_load_auth_type(&hmac, HMAC_SHA1); + if (status) + return status; + + /* change state to secure */ + crypto_kernel.state = crypto_kernel_state_secure; + + return err_status_ok; +} + +err_status_t +crypto_kernel_status() { + err_status_t status; + kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list; + kernel_auth_type_t *atype = crypto_kernel.auth_type_list; + kernel_debug_module_t *dm = crypto_kernel.debug_module_list; + + /* run FIPS-140 statistical tests on rand_source */ + printf("testing rand_source..."); + status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS); + if (status) { + printf("failed\n"); + crypto_kernel.state = crypto_kernel_state_insecure; + return status; + } + printf("passed\n"); + + /* for each cipher type, describe and test */ + while(ctype != NULL) { + printf("cipher: %s\n", ctype->cipher_type->description); + printf(" instance count: %d\n", ctype->cipher_type->ref_count); + printf(" self-test: "); + status = cipher_type_self_test(ctype->cipher_type); + if (status) { + printf("failed with error code %d\n", status); + exit(status); + } + printf("passed\n"); + ctype = ctype->next; + } + + /* for each auth type, describe and test */ + while(atype != NULL) { + printf("auth func: %s\n", atype->auth_type->description); + printf(" instance count: %d\n", atype->auth_type->ref_count); + printf(" self-test: "); + status = auth_type_self_test(atype->auth_type); + if (status) { + printf("failed with error code %d\n", status); + exit(status); + } + printf("passed\n"); + atype = atype->next; + } + + /* describe each debug module */ + printf("debug modules loaded:\n"); + while (dm != NULL) { + printf(" %s ", dm->mod->name); + if (dm->mod->on) + printf("(on)\n"); + else + printf("(off)\n"); + dm = dm->next; + } + + return err_status_ok; +} + +err_status_t +crypto_kernel_list_debug_modules() { + kernel_debug_module_t *dm = crypto_kernel.debug_module_list; + + /* describe each debug module */ + printf("debug modules loaded:\n"); + while (dm != NULL) { + printf(" %s ", dm->mod->name); + if (dm->mod->on) + printf("(on)\n"); + else + printf("(off)\n"); + dm = dm->next; + } + + return err_status_ok; +} + +err_status_t +crypto_kernel_shutdown() { + err_status_t status; + + /* + * free dynamic memory used in crypto_kernel at present + */ + + /* walk down cipher type list, freeing memory */ + while (crypto_kernel.cipher_type_list != NULL) { + kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list; + crypto_kernel.cipher_type_list = ctype->next; + debug_print(mod_crypto_kernel, + "freeing memory for cipher %s", + ctype->cipher_type->description); + crypto_free(ctype); + } + + /* walk down authetication module list, freeing memory */ + while (crypto_kernel.auth_type_list != NULL) { + kernel_auth_type_t *atype = crypto_kernel.auth_type_list; + crypto_kernel.auth_type_list = atype->next; + debug_print(mod_crypto_kernel, + "freeing memory for authentication %s", + atype->auth_type->description); + crypto_free(atype); + } + + /* walk down debug module list, freeing memory */ + while (crypto_kernel.debug_module_list != NULL) { + kernel_debug_module_t *kdm = crypto_kernel.debug_module_list; + crypto_kernel.debug_module_list = kdm->next; + debug_print(mod_crypto_kernel, + "freeing memory for debug module %s", + kdm->mod->name); + crypto_free(kdm); + } + + /* de-initialize random number generator */ status = rand_source_deinit(); + if (status) + return status; + + /* return to insecure state */ + crypto_kernel.state = crypto_kernel_state_insecure; + + return err_status_ok; +} + +err_status_t +crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) { + kernel_cipher_type_t *ctype, *new_ctype; + err_status_t status; + + /* defensive coding */ + if (new_ct == NULL) + return err_status_bad_param; + + /* check cipher type by running self-test */ + status = cipher_type_self_test(new_ct); + if (status) { + return status; + } + + /* walk down list, checking if this type is in the list already */ + ctype = crypto_kernel.cipher_type_list; + while (ctype != NULL) { + if ((new_ct == ctype->cipher_type) || (id == ctype->id)) + return err_status_bad_param; + ctype = ctype->next; + } + + /* put new_ct at the head of the list */ + /* allocate memory */ + new_ctype = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_t)); + if (new_ctype == NULL) + return err_status_alloc_fail; + + /* set fields */ + new_ctype->cipher_type = new_ct; + new_ctype->id = id; + new_ctype->next = crypto_kernel.cipher_type_list; + + /* set head of list to new cipher type */ + crypto_kernel.cipher_type_list = new_ctype; + + /* load debug module, if there is one present */ + if (new_ct->debug != NULL) + crypto_kernel_load_debug_module(new_ct->debug); + /* we could check for errors here */ + + return err_status_ok; +} + +err_status_t +crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) { + kernel_auth_type_t *atype, *new_atype; + err_status_t status; + + /* defensive coding */ + if (new_at == NULL) + return err_status_bad_param; + + /* check auth type by running self-test */ + status = auth_type_self_test(new_at); + if (status) { + return status; + } + + /* walk down list, checking if this type is in the list already */ + atype = crypto_kernel.auth_type_list; + while (atype != NULL) { + if ((new_at == atype->auth_type) || (id == atype->id)) + return err_status_bad_param; + atype = atype->next; + } + + /* put new_at at the head of the list */ + /* allocate memory */ + new_atype = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t)); + if (new_atype == NULL) + return err_status_alloc_fail; + + /* set fields */ + new_atype->auth_type = new_at; + new_atype->id = id; + new_atype->next = crypto_kernel.auth_type_list; + + /* set head of list to new auth type */ + crypto_kernel.auth_type_list = new_atype; + + /* load debug module, if there is one present */ + if (new_at->debug != NULL) + crypto_kernel_load_debug_module(new_at->debug); + /* we could check for errors here */ + + return err_status_ok; + +} + + +cipher_type_t * +crypto_kernel_get_cipher_type(cipher_type_id_t id) { + kernel_cipher_type_t *ctype; + + /* walk down list, looking for id */ + ctype = crypto_kernel.cipher_type_list; + while (ctype != NULL) { + if (id == ctype->id) + return ctype->cipher_type; + ctype = ctype->next; + } + + /* haven't found the right one, indicate failure by returning NULL */ + return NULL; +} + + +err_status_t +crypto_kernel_alloc_cipher(cipher_type_id_t id, + cipher_pointer_t *cp, + int key_len) { + cipher_type_t *ct; + + /* + * if the crypto_kernel is not yet initialized, we refuse to allocate + * any ciphers - this is a bit extra-paranoid + */ + if (crypto_kernel.state != crypto_kernel_state_secure) + return err_status_init_fail; + + ct = crypto_kernel_get_cipher_type(id); + if (!ct) + return err_status_fail; + + return ((ct)->alloc(cp, key_len)); +} + + + +auth_type_t * +crypto_kernel_get_auth_type(auth_type_id_t id) { + kernel_auth_type_t *atype; + + /* walk down list, looking for id */ + atype = crypto_kernel.auth_type_list; + while (atype != NULL) { + if (id == atype->id) + return atype->auth_type; + atype = atype->next; + } + + /* haven't found the right one, indicate failure by returning NULL */ + return NULL; +} + +err_status_t +crypto_kernel_alloc_auth(auth_type_id_t id, + auth_pointer_t *ap, + int key_len, + int tag_len) { + auth_type_t *at; + + /* + * if the crypto_kernel is not yet initialized, we refuse to allocate + * any auth functions - this is a bit extra-paranoid + */ + if (crypto_kernel.state != crypto_kernel_state_secure) + return err_status_init_fail; + + at = crypto_kernel_get_auth_type(id); + if (!at) + return err_status_fail; + + return ((at)->alloc(ap, key_len, tag_len)); +} + +err_status_t +crypto_kernel_load_debug_module(debug_module_t *new_dm) { + kernel_debug_module_t *kdm, *new; + + /* defensive coding */ + if (new_dm == NULL) + return err_status_bad_param; + + /* walk down list, checking if this type is in the list already */ + kdm = crypto_kernel.debug_module_list; + while (kdm != NULL) { + if (strncmp(new_dm->name, kdm->mod->name, 64) == 0) + return err_status_bad_param; + kdm = kdm->next; + } + + /* put new_dm at the head of the list */ + /* allocate memory */ + new = (kernel_debug_module_t *)crypto_alloc(sizeof(kernel_debug_module_t)); + if (new == NULL) + return err_status_alloc_fail; + + /* set fields */ + new->mod = new_dm; + new->next = crypto_kernel.debug_module_list; + + /* set head of list to new cipher type */ + crypto_kernel.debug_module_list = new; + + return err_status_ok; +} + +err_status_t +crypto_kernel_set_debug_module(char *name, int on) { + kernel_debug_module_t *kdm; + + /* walk down list, checking if this type is in the list already */ + kdm = crypto_kernel.debug_module_list; + while (kdm != NULL) { + if (strncmp(name, kdm->mod->name, 64) == 0) { + kdm->mod->on = on; + return err_status_ok; + } + kdm = kdm->next; + } + + return err_status_fail; +} + +err_status_t +crypto_get_random(unsigned char *buffer, unsigned int length) { + if (crypto_kernel.state == crypto_kernel_state_secure) + return ctr_prng_get_octet_string(buffer, length); + else + return err_status_fail; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/kernel/err.c b/src/libs/resiprocate/contrib/srtp/crypto/kernel/err.c new file mode 100644 index 00000000..4a3a8589 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/kernel/err.c @@ -0,0 +1,148 @@ +/* + * err.c + * + * error status reporting functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "err.h" + +#ifdef ERR_REPORTING_SYSLOG +# ifdef HAVE_SYSLOG_H +# include +# endif +#endif + + +/* err_level reflects the level of errors that are reported */ + +err_reporting_level_t err_level = err_level_none; + +#ifdef SRTP_KERNEL_LINUX +err_status_t +err_reporting_init(char *ident) { + + return err_status_ok; +} + +#else /* SRTP_KERNEL_LINUX */ + +/* err_file is the FILE to which errors are reported */ + +static FILE *err_file = NULL; + +err_status_t +err_reporting_init(char *ident) { +#ifdef ERR_REPORTING_SYSLOG + openlog(ident, LOG_PID, LOG_AUTHPRIV); +#endif + + /* + * Believe it or not, openlog doesn't return an error on failure. + * But then, neither does the syslog() call... + */ + +#ifdef ERR_REPORTING_STDOUT + err_file = stdout; +#elif defined(USE_ERR_REPORTING_FILE) + /* open file for error reporting */ + err_file = fopen(ERR_REPORTING_FILE, "w"); + if (err_file == NULL) + return err_status_init_fail; +#endif + + return err_status_ok; +} + +void +err_report(int priority, char *format, ...) { + va_list args; + + if (priority <= err_level) { + + va_start(args, format); + if (err_file != NULL) { + vfprintf(err_file, format, args); + /* fprintf(err_file, "\n"); */ + } +#ifdef ERR_REPORTING_SYSLOG + if (1) { /* FIXME: Make this a runtime option. */ + int syslogpri; + + switch (priority) { + case err_level_emergency: + syslogpri = LOG_EMERG; + break; + case err_level_alert: + syslogpri = LOG_ALERT; + break; + case err_level_critical: + syslogpri = LOG_CRIT; + break; + case err_level_error: + syslogpri = LOG_ERR; + break; + case err_level_warning: + syslogpri = LOG_WARNING; + break; + case err_level_notice: + syslogpri = LOG_NOTICE; + break; + case err_level_info: + syslogpri = LOG_INFO; + break; + case err_level_debug: + case err_level_none: + default: + syslogpri = LOG_DEBUG; + break; + } + + vsyslog(syslogpri, format, args); +#endif + va_end(args); + } +} +#endif /* SRTP_KERNEL_LINUX */ + +void +err_reporting_set_level(err_reporting_level_t lvl) { + err_level = lvl; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/kernel/key.c b/src/libs/resiprocate/contrib/srtp/crypto/kernel/key.c new file mode 100644 index 00000000..9f63b22c --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/kernel/key.c @@ -0,0 +1,115 @@ +/* + * key.c + * + * key usage limits enforcement + * + * David A. Mcgrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "key.h" + +#define soft_limit 0x10000 + +err_status_t +key_limit_set(key_limit_t key, const xtd_seq_num_t s) { +#ifdef NO_64BIT_MATH + if (high32(s) == 0 && low32(s) < soft_limit) + return err_status_bad_param; +#else + if (s < soft_limit) + return err_status_bad_param; +#endif + key->num_left = s; + key->state = key_state_normal; + return err_status_ok; +} + +err_status_t +key_limit_clone(key_limit_t original, key_limit_t *new_key) { + if (original == NULL) + return err_status_bad_param; + *new_key = original; + return err_status_ok; +} + +err_status_t +key_limit_check(const key_limit_t key) { + if (key->state == key_state_expired) + return err_status_key_expired; + return err_status_ok; +} + +key_event_t +key_limit_update(key_limit_t key) { +#ifdef NO_64BIT_MATH + if (low32(key->num_left) == 0) + { + // carry + key->num_left = make64(high32(key->num_left)-1,low32(key->num_left) - 1); + } + else + { + // no carry + key->num_left = make64(high32(key->num_left),low32(key->num_left) - 1); + } + if (high32(key->num_left) != 0 || low32(key->num_left) >= soft_limit) { + return key_event_normal; /* we're above the soft limit */ + } +#else + key->num_left--; + if (key->num_left >= soft_limit) { + return key_event_normal; /* we're above the soft limit */ + } +#endif + if (key->state == key_state_normal) { + /* we just passed the soft limit, so change the state */ + key->state = key_state_past_soft_limit; + } +#ifdef NO_64BIT_MATH + if (low32(key->num_left) == 0 && high32(key->num_left == 0)) +#else + if (key->num_left < 1) +#endif + { /* we just hit the hard limit */ + key->state = key_state_expired; + return key_event_hard_limit; + } + return key_event_soft_limit; +} + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/math/datatypes.c b/src/libs/resiprocate/contrib/srtp/crypto/math/datatypes.c new file mode 100644 index 00000000..61bf34fe --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/math/datatypes.c @@ -0,0 +1,600 @@ +/* + * datatypes.c + * + * data types for finite fields and functions for input, output, and + * manipulation + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "datatypes.h" + +int +octet_weight[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, + 5, 6, 6, 7, 6, 7, 7, 8 +}; + +int +octet_get_weight(uint8_t octet) { + extern int octet_weight[256]; + + return octet_weight[octet]; +} + +/* + * bit_string is a buffer that is used to hold output strings, e.g. + * for printing. + */ + +/* the value MAX_PRINT_STRING_LEN is defined in datatypes.h */ + +char bit_string[MAX_PRINT_STRING_LEN]; + +uint8_t +nibble_to_hex_char(uint8_t nibble) { + char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + return buf[nibble & 0xF]; +} + +char * +octet_string_hex_string(const void *s, int length) { + const uint8_t *str = (const uint8_t *)s; + int i; + + /* double length, since one octet takes two hex characters */ + length *= 2; + + /* truncate string if it would be too long */ + if (length > MAX_PRINT_STRING_LEN) + length = MAX_PRINT_STRING_LEN-1; + + for (i=0; i < length; i+=2) { + bit_string[i] = nibble_to_hex_char(*str >> 4); + bit_string[i+1] = nibble_to_hex_char(*str++ & 0xF); + } + bit_string[i] = 0; /* null terminate string */ + return bit_string; +} + +inline int +hex_char_to_nibble(uint8_t c) { + switch(c) { + case ('0'): return 0x0; + case ('1'): return 0x1; + case ('2'): return 0x2; + case ('3'): return 0x3; + case ('4'): return 0x4; + case ('5'): return 0x5; + case ('6'): return 0x6; + case ('7'): return 0x7; + case ('8'): return 0x8; + case ('9'): return 0x9; + case ('a'): return 0xa; + case ('A'): return 0xa; + case ('b'): return 0xb; + case ('B'): return 0xb; + case ('c'): return 0xc; + case ('C'): return 0xc; + case ('d'): return 0xd; + case ('D'): return 0xd; + case ('e'): return 0xe; + case ('E'): return 0xe; + case ('f'): return 0xf; + case ('F'): return 0xf; + default: return -1; /* this flags an error */ + } + /* NOTREACHED */ + return -1; /* this keeps compilers from complaining */ +} + +int +is_hex_string(char *s) { + while(*s != 0) + if (hex_char_to_nibble(*s++) == -1) + return 0; + return 1; +} + +/* + * hex_string_to_octet_string converts a hexadecimal string + * of length 2 * len to a raw octet string of length len + */ + +int +hex_string_to_octet_string(char *raw, char *hex, int len) { + uint8_t x; + int tmp; + int hex_len; + + hex_len = 0; + while (hex_len < len) { + tmp = hex_char_to_nibble(hex[0]); + if (tmp == -1) + return hex_len; + x = (tmp << 4); + hex_len++; + tmp = hex_char_to_nibble(hex[1]); + if (tmp == -1) + return hex_len; + x |= (tmp & 0xff); + hex_len++; + *raw++ = x; + hex += 2; + } + return hex_len; +} + +char * +v128_hex_string(v128_t *x) { + int i, j; + + for (i=j=0; i < 16; i++) { + bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4); + bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF); + } + + bit_string[j] = 0; /* null terminate string */ + return bit_string; +} + +char * +v128_bit_string(v128_t *x) { + int j, index; + uint32_t mask; + + for (j=index=0; j < 4; j++) { + for (mask=0x80000000; mask > 0; mask >>= 1) { + if (x->v32[j] & mask) + bit_string[index] = '1'; + else + bit_string[index] = '0'; + ++index; + } + } + bit_string[128] = 0; /* null terminate string */ + + return bit_string; +} + +void +v128_copy_octet_string(v128_t *x, const uint8_t s[16]) { +#ifdef ALIGNMENT_32BIT_REQUIRED + if ((((uint32_t) &s[0]) & 0x3) != 0) +#endif + { + x->v8[0] = s[0]; + x->v8[1] = s[1]; + x->v8[2] = s[2]; + x->v8[3] = s[3]; + x->v8[4] = s[4]; + x->v8[5] = s[5]; + x->v8[6] = s[6]; + x->v8[7] = s[7]; + x->v8[8] = s[8]; + x->v8[9] = s[9]; + x->v8[10] = s[10]; + x->v8[11] = s[11]; + x->v8[12] = s[12]; + x->v8[13] = s[13]; + x->v8[14] = s[14]; + x->v8[15] = s[15]; + } +#ifdef ALIGNMENT_32BIT_REQUIRED + else + { + v128_t *v = (v128_t *) &s[0]; + + v128_copy(x,v); + } +#endif +} + +#ifndef DATATYPES_USE_MACROS /* little functions are not macros */ + +void +v128_set_to_zero(v128_t *x) { + _v128_set_to_zero(x); +} + +void +v128_copy(v128_t *x, const v128_t *y) { + _v128_copy(x, y); +} + +void +v128_xor(v128_t *z, v128_t *x, v128_t *y) { + _v128_xor(z, x, y); +} + +void +v128_and(v128_t *z, v128_t *x, v128_t *y) { + _v128_and(z, x, y); +} + +void +v128_or(v128_t *z, v128_t *x, v128_t *y) { + _v128_or(z, x, y); +} + +void +v128_complement(v128_t *x) { + _v128_complement(x); +} + +int +v128_is_eq(const v128_t *x, const v128_t *y) { + return _v128_is_eq(x, y); +} + +int +v128_xor_eq(v128_t *x, const v128_t *y) { + return _v128_xor_eq(x, y); +} + +int +v128_get_bit(const v128_t *x, int i) { + return _v128_get_bit(x, i); +} + +void +v128_set_bit(v128_t *x, int i) { + _v128_set_bit(x, i); +} + +void +v128_clear_bit(v128_t *x, int i){ + _v128_clear_bit(x, i); +} + +void +v128_set_bit_to(v128_t *x, int i, int y){ + _v128_set_bit_to(x, i, y); +} + + +#endif /* DATATYPES_USE_MACROS */ + +void +v128_right_shift(v128_t *x, int index) { + const int base_index = index >> 5; + const int bit_index = index & 31; + int i, from; + uint32_t b; + + if (index > 127) { + v128_set_to_zero(x); + return; + } + + if (bit_index == 0) { + + /* copy each word from left size to right side */ + x->v32[4-1] = x->v32[4-1-base_index]; + for (i=4-1; i > base_index; i--) + x->v32[i-1] = x->v32[i-1-base_index]; + + } else { + + /* set each word to the "or" of the two bit-shifted words */ + for (i = 4; i > base_index; i--) { + from = i-1 - base_index; + b = x->v32[from] << bit_index; + if (from > 0) + b |= x->v32[from-1] >> (32-bit_index); + x->v32[i-1] = b; + } + + } + + /* now wrap up the final portion */ + for (i=0; i < base_index; i++) + x->v32[i] = 0; + +} + +void +v128_left_shift(v128_t *x, int index) { + int i; + const int base_index = index >> 5; + const int bit_index = index & 31; + + if (index > 127) { + v128_set_to_zero(x); + return; + } + + if (bit_index == 0) { + for (i=0; i < 4 - base_index; i++) + x->v32[i] = x->v32[i+base_index]; + } else { + for (i=0; i < 4 - base_index - 1; i++) + x->v32[i] = (x->v32[i+base_index] >> bit_index) ^ + (x->v32[i+base_index+1] << (32 - bit_index)); + x->v32[4 - base_index-1] = x->v32[4-1] >> bit_index; + } + + /* now wrap up the final portion */ + for (i = 4 - base_index; i < 4; i++) + x->v32[i] = 0; + +} + + +int +octet_string_is_eq(uint8_t *a, uint8_t *b, int len) { + uint8_t *end = b + len; + while (b < end) + if (*a++ != *b++) + return 1; + return 0; +} + +void +octet_string_set_to_zero(uint8_t *s, int len) { + uint8_t *end = s + len; + + do { + *s = 0; + } while (++s < end); + +} + + +/* + * From RFC 1521: The Base64 Alphabet + * + * Value Encoding Value Encoding Value Encoding Value Encoding + * 0 A 17 R 34 i 51 z + * 1 B 18 S 35 j 52 0 + * 2 C 19 T 36 k 53 1 + * 3 D 20 U 37 l 54 2 + * 4 E 21 V 38 m 55 3 + * 5 F 22 W 39 n 56 4 + * 6 G 23 X 40 o 57 5 + * 7 H 24 Y 41 p 58 6 + * 8 I 25 Z 42 q 59 7 + * 9 J 26 a 43 r 60 8 + * 10 K 27 b 44 s 61 9 + * 11 L 28 c 45 t 62 + + * 12 M 29 d 46 u 63 / + * 13 N 30 e 47 v + * 14 O 31 f 48 w (pad) = + * 15 P 32 g 49 x + * 16 Q 33 h 50 y + */ + +int +base64_char_to_sextet(uint8_t c) { + switch(c) { + case 'A': + return 0; + case 'B': + return 1; + case 'C': + return 2; + case 'D': + return 3; + case 'E': + return 4; + case 'F': + return 5; + case 'G': + return 6; + case 'H': + return 7; + case 'I': + return 8; + case 'J': + return 9; + case 'K': + return 10; + case 'L': + return 11; + case 'M': + return 12; + case 'N': + return 13; + case 'O': + return 14; + case 'P': + return 15; + case 'Q': + return 16; + case 'R': + return 17; + case 'S': + return 18; + case 'T': + return 19; + case 'U': + return 20; + case 'V': + return 21; + case 'W': + return 22; + case 'X': + return 23; + case 'Y': + return 24; + case 'Z': + return 25; + case 'a': + return 26; + case 'b': + return 27; + case 'c': + return 28; + case 'd': + return 29; + case 'e': + return 30; + case 'f': + return 31; + case 'g': + return 32; + case 'h': + return 33; + case 'i': + return 34; + case 'j': + return 35; + case 'k': + return 36; + case 'l': + return 37; + case 'm': + return 38; + case 'n': + return 39; + case 'o': + return 40; + case 'p': + return 41; + case 'q': + return 42; + case 'r': + return 43; + case 's': + return 44; + case 't': + return 45; + case 'u': + return 46; + case 'v': + return 47; + case 'w': + return 48; + case 'x': + return 49; + case 'y': + return 50; + case 'z': + return 51; + case '0': + return 52; + case '1': + return 53; + case '2': + return 54; + case '3': + return 55; + case '4': + return 56; + case '5': + return 57; + case '6': + return 58; + case '7': + return 59; + case '8': + return 60; + case '9': + return 61; + case '+': + return 62; + case '/': + return 63; + case '=': + return 64; + default: + break; + } + return -1; +} + +/* + * base64_string_to_octet_string converts a hexadecimal string + * of length 2 * len to a raw octet string of length len + */ + +int +base64_string_to_octet_string(char *raw, char *base64, int len) { + uint8_t x; + int tmp; + int base64_len; + + base64_len = 0; + while (base64_len < len) { + tmp = base64_char_to_sextet(base64[0]); + if (tmp == -1) + return base64_len; + x = (tmp << 6); + base64_len++; + tmp = base64_char_to_sextet(base64[1]); + if (tmp == -1) + return base64_len; + x |= (tmp & 0xffff); + base64_len++; + *raw++ = x; + base64 += 2; + } + return base64_len; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/math/gf2_8.c b/src/libs/resiprocate/contrib/srtp/crypto/math/gf2_8.c new file mode 100644 index 00000000..8a112ba7 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/math/gf2_8.c @@ -0,0 +1,83 @@ +/* + * gf2_8.c + * + * GF(256) finite field implementation, with the representation used + * in the AES cipher. + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "datatypes.h" +#include "gf2_8.h" + +/* gf2_8_shift() moved to gf2_8.h as an inline function */ + +inline gf2_8 +gf2_8_multiply(gf2_8 x, gf2_8 y) { + gf2_8 z = 0; + + if (y & 1) z ^= x; x = gf2_8_shift(x); + if (y & 2) z ^= x; x = gf2_8_shift(x); + if (y & 4) z ^= x; x = gf2_8_shift(x); + if (y & 8) z ^= x; x = gf2_8_shift(x); + if (y & 16) z ^= x; x = gf2_8_shift(x); + if (y & 32) z ^= x; x = gf2_8_shift(x); + if (y & 64) z ^= x; x = gf2_8_shift(x); + if (y & 128) z ^= x; + + return z; +} + + +/* this should use the euclidean algorithm */ + +gf2_8 +gf2_8_compute_inverse(gf2_8 x) { + unsigned int i; + + if (x == 0) return 0; /* zero is a special case */ + for (i=0; i < 256; i++) + if (gf2_8_multiply((gf2_8) i, x) == 1) + return (gf2_8) i; + + return 0; +} + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/math/math.c b/src/libs/resiprocate/contrib/srtp/crypto/math/math.c new file mode 100644 index 00000000..3e619979 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/math/math.c @@ -0,0 +1,962 @@ +/* + * math.c + * + * crypto math operations and data types + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "crypto_math.h" +#include /* malloc() used in bitvector_alloc */ + +int +octet_weight[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, + 5, 6, 6, 7, 6, 7, 7, 8 +}; + +int +low_bit[256] = { + -1, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 7, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0 +}; + + +int +high_bit[256] = { + -1, 0, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7 +}; + +int +octet_get_weight(uint8_t octet) { + extern int octet_weight[256]; + + return octet_weight[octet]; +} + +unsigned char +v32_weight(v32_t a) { + unsigned int wt = 0; + + wt += octet_weight[a.v8[0]]; /* note: endian-ness makes no difference */ + wt += octet_weight[a.v8[1]]; + wt += octet_weight[a.v8[2]]; + wt += octet_weight[a.v8[3]]; + + return wt; +} + +inline unsigned char +v32_distance(v32_t x, v32_t y) { + x.value ^= y.value; + return v32_weight(x); +} + +unsigned int +v32_dot_product(v32_t a, v32_t b) { + a.value &= b.value; + return v32_weight(a) & 1; +} + +/* + * _bit_string returns a NULL-terminated character string suitable for + * printing + */ + +#define MAX_STRING_LENGTH 1024 + +char bit_string[MAX_STRING_LENGTH]; + +char * +octet_bit_string(uint8_t x) { + int mask, index; + + for (mask = 1, index = 0; mask < 256; mask <<= 1) + if ((x & mask) == 0) + bit_string[index++] = '0'; + else + bit_string[index++] = '1'; + + bit_string[index++] = 0; /* NULL terminate string */ + + return bit_string; +} + +char * +v16_bit_string(v16_t x) { + int i, mask, index; + + for (i = index = 0; i < 2; i++) { + for (mask = 1; mask < 256; mask <<= 1) + if ((x.v8[i] & mask) == 0) + bit_string[index++] = '0'; + else + bit_string[index++] = '1'; + } + bit_string[index++] = 0; /* NULL terminate string */ + return bit_string; +} + +char * +v32_bit_string(v32_t x) { + int i, mask, index; + + for (i = index = 0; i < 4; i++) { + for (mask = 128; mask > 0; mask >>= 1) + if ((x.v8[i] & mask) == 0) + bit_string[index++] = '0'; + else + bit_string[index++] = '1'; + } + bit_string[index++] = 0; /* NULL terminate string */ + return bit_string; +} + +char * +v64_bit_string(const v64_t *x) { + int i, mask, index; + + for (i = index = 0; i < 8; i++) { + for (mask = 1; mask < 256; mask <<= 1) + if ((x->v8[i] & mask) == 0) + bit_string[index++] = '0'; + else + bit_string[index++] = '1'; + } + bit_string[index++] = 0; /* NULL terminate string */ + return bit_string; +} + +char * +v128_bit_string(v128_t *x) { + int j, index; + uint32_t mask; + + for (j=index=0; j < 4; j++) { + for (mask=0x80000000; mask > 0; mask >>= 1) { + if (x->v32[j] & mask) + bit_string[index] = '1'; + else + bit_string[index] = '0'; + ++index; + } + } + bit_string[128] = 0; /* null terminate string */ + + return bit_string; +} + +uint8_t +nibble_to_hex_char(uint8_t nibble) { + char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + return buf[nibble & 0xF]; +} + +char * +octet_hex_string(uint8_t x) { + + bit_string[0] = nibble_to_hex_char(x >> 4); + bit_string[1] = nibble_to_hex_char(x & 0xF); + + bit_string[2] = 0; /* null terminate string */ + return bit_string; +} + +char * +octet_string_hex_string(const void *str, int length) { + const uint8_t *s = str; + int i; + + /* double length, since one octet takes two hex characters */ + length *= 2; + + /* truncate string if it would be too long */ + if (length > MAX_STRING_LENGTH) + length = MAX_STRING_LENGTH-1; + + for (i=0; i < length; i+=2) { + bit_string[i] = nibble_to_hex_char(*s >> 4); + bit_string[i+1] = nibble_to_hex_char(*s++ & 0xF); + } + bit_string[i] = 0; /* null terminate string */ + return bit_string; +} + +char * +v16_hex_string(v16_t x) { + int i, j; + + for (i=j=0; i < 2; i++) { + bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4); + bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF); + } + + bit_string[j] = 0; /* null terminate string */ + return bit_string; +} + +char * +v32_hex_string(v32_t x) { + int i, j; + + for (i=j=0; i < 4; i++) { + bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4); + bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF); + } + + bit_string[j] = 0; /* null terminate string */ + return bit_string; +} + +char * +v64_hex_string(const v64_t *x) { + int i, j; + + for (i=j=0; i < 8; i++) { + bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4); + bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF); + } + + bit_string[j] = 0; /* null terminate string */ + return bit_string; +} + +char * +v128_hex_string(v128_t *x) { + int i, j; + + for (i=j=0; i < 16; i++) { + bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4); + bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF); + } + + bit_string[j] = 0; /* null terminate string */ + return bit_string; +} + +char * +char_to_hex_string(char *x, int num_char) { + int i, j; + + if (num_char >= 16) + num_char = 16; + for (i=j=0; i < num_char; i++) { + bit_string[j++] = nibble_to_hex_char(x[i] >> 4); + bit_string[j++] = nibble_to_hex_char(x[i] & 0xF); + } + + bit_string[j] = 0; /* null terminate string */ + return bit_string; +} + +int +hex_char_to_nibble(uint8_t c) { + switch(c) { + case ('0'): return 0x0; + case ('1'): return 0x1; + case ('2'): return 0x2; + case ('3'): return 0x3; + case ('4'): return 0x4; + case ('5'): return 0x5; + case ('6'): return 0x6; + case ('7'): return 0x7; + case ('8'): return 0x8; + case ('9'): return 0x9; + case ('a'): return 0xa; + case ('A'): return 0xa; + case ('b'): return 0xb; + case ('B'): return 0xb; + case ('c'): return 0xc; + case ('C'): return 0xc; + case ('d'): return 0xd; + case ('D'): return 0xd; + case ('e'): return 0xe; + case ('E'): return 0xe; + case ('f'): return 0xf; + case ('F'): return 0xf; + default: return -1; /* this flags an error */ + } + /* NOTREACHED */ + return -1; /* this keeps compilers from complaining */ +} + +int +is_hex_string(char *s) { + while(*s != 0) + if (hex_char_to_nibble(*s++) == -1) + return 0; + return 1; +} + +uint8_t +hex_string_to_octet(char *s) { + uint8_t x; + + x = (hex_char_to_nibble(s[0]) << 4) + | hex_char_to_nibble(s[1] & 0xFF); + + return x; +} + +/* + * hex_string_to_octet_string converts a hexadecimal string + * of length 2 * len to a raw octet string of length len + */ + +int +hex_string_to_octet_string(char *raw, char *hex, int len) { + uint8_t x; + int tmp; + int hex_len; + + hex_len = 0; + while (hex_len < len) { + tmp = hex_char_to_nibble(hex[0]); + if (tmp == -1) + return hex_len; + x = (tmp << 4); + hex_len++; + tmp = hex_char_to_nibble(hex[1]); + if (tmp == -1) + return hex_len; + x |= (tmp & 0xff); + hex_len++; + *raw++ = x; + hex += 2; + } + return hex_len; +} + +v16_t +hex_string_to_v16(char *s) { + v16_t x; + int i, j; + + for (i=j=0; i < 4; i += 2, j++) { + x.v8[j] = (hex_char_to_nibble(s[i]) << 4) + | hex_char_to_nibble(s[i+1] & 0xFF); + } + return x; +} + +v32_t +hex_string_to_v32(char *s) { + v32_t x; + int i, j; + + for (i=j=0; i < 8; i += 2, j++) { + x.v8[j] = (hex_char_to_nibble(s[i]) << 4) + | hex_char_to_nibble(s[i+1] & 0xFF); + } + return x; +} + +v64_t +hex_string_to_v64(char *s) { + v64_t x; + int i, j; + + for (i=j=0; i < 16; i += 2, j++) { + x.v8[j] = (hex_char_to_nibble(s[i]) << 4) + | hex_char_to_nibble(s[i+1] & 0xFF); + } + return x; +} + +v128_t +hex_string_to_v128(char *s) { + v128_t x; + int i, j; + + for (i=j=0; i < 32; i += 2, j++) { + x.v8[j] = (hex_char_to_nibble(s[i]) << 4) + | hex_char_to_nibble(s[i+1] & 0xFF); + } + return x; +} + + + +/* + * the matrix A[] is stored in column format, i.e., A[i] is the ith + * column of the matrix + */ + +uint8_t +A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b) { + int index = 0; + unsigned mask; + + for (mask=1; mask < 256; mask *= 2) { + if (x & mask) + b^= A[index]; + ++index; + } + + return b; +} + +inline void +v16_copy_octet_string(v16_t *x, const uint8_t s[2]) { + x->v8[0] = s[0]; + x->v8[1] = s[1]; +} + +inline void +v32_copy_octet_string(v32_t *x, const uint8_t s[4]) { + x->v8[0] = s[0]; + x->v8[1] = s[1]; + x->v8[2] = s[2]; + x->v8[3] = s[3]; +} + +inline void +v64_copy_octet_string(v64_t *x, const uint8_t s[8]) { + x->v8[0] = s[0]; + x->v8[1] = s[1]; + x->v8[2] = s[2]; + x->v8[3] = s[3]; + x->v8[4] = s[4]; + x->v8[5] = s[5]; + x->v8[6] = s[6]; + x->v8[7] = s[7]; +} + +void +v128_copy_octet_string(v128_t *x, const uint8_t s[16]) { + x->v8[0] = s[0]; + x->v8[1] = s[1]; + x->v8[2] = s[2]; + x->v8[3] = s[3]; + x->v8[4] = s[4]; + x->v8[5] = s[5]; + x->v8[6] = s[6]; + x->v8[7] = s[7]; + x->v8[8] = s[8]; + x->v8[9] = s[9]; + x->v8[10] = s[10]; + x->v8[11] = s[11]; + x->v8[12] = s[12]; + x->v8[13] = s[13]; + x->v8[14] = s[14]; + x->v8[15] = s[15]; + +} + +#ifndef DATATYPES_USE_MACROS /* little functions are not macros */ + +void +v128_set_to_zero(v128_t *x) { + _v128_set_to_zero(x); +} + +void +v128_copy(v128_t *x, const v128_t *y) { + _v128_copy(x, y); +} + +void +v128_xor(v128_t *z, v128_t *x, v128_t *y) { + _v128_xor(z, x, y); +} + +void +v128_and(v128_t *z, v128_t *x, v128_t *y) { + _v128_and(z, x, y); +} + +void +v128_or(v128_t *z, v128_t *x, v128_t *y) { + _v128_or(z, x, y); +} + +void +v128_complement(v128_t *x) { + _v128_complement(x); +} + +int +v128_is_eq(const v128_t *x, const v128_t *y) { + return _v128_is_eq(x, y); +} + +int +v128_get_bit(const v128_t *x, int i) { + return _v128_get_bit(x, i); +} + +void +v128_set_bit(v128_t *x, int i) { + _v128_set_bit(x, i); +} + +void +v128_clear_bit(v128_t *x, int i){ + _v128_clear_bit(x, i); +} + +void +v128_set_bit_to(v128_t *x, int i, int y){ + _v128_set_bit_to(x, i, y); +} + + +#endif /* DATATYPES_USE_MACROS */ + + +inline void +v128_left_shift2(v128_t *x, int num_bits) { + int i; + int word_shift = num_bits >> 5; + int bit_shift = num_bits & 31; + + for (i=0; i < (4-word_shift); i++) { + x->v32[i] = x->v32[i+word_shift] << bit_shift; + } + + for ( ; i < word_shift; i++) { + x->v32[i] = 0; + } + +} + +void +v128_right_shift(v128_t *x, int index) { + const int base_index = index >> 5; + const int bit_index = index & 31; + int i, from; + uint32_t b; + + if (index > 127) { + v128_set_to_zero(x); + return; + } + + if (bit_index == 0) { + + /* copy each word from left size to right side */ + x->v32[4-1] = x->v32[4-1-base_index]; + for (i=4-1; i > base_index; i--) + x->v32[i-1] = x->v32[i-1-base_index]; + + } else { + + /* set each word to the "or" of the two bit-shifted words */ + for (i = 4; i > base_index; i--) { + from = i-1 - base_index; + b = x->v32[from] << bit_index; + if (from > 0) + b |= x->v32[from-1] >> (32-bit_index); + x->v32[i-1] = b; + } + + } + + /* now wrap up the final portion */ + for (i=0; i < base_index; i++) + x->v32[i] = 0; + +} + +void +v128_left_shift(v128_t *x, int index) { + int i; + const int base_index = index >> 5; + const int bit_index = index & 31; + + if (index > 127) { + v128_set_to_zero(x); + return; + } + + if (bit_index == 0) { + for (i=0; i < 4 - base_index; i++) + x->v32[i] = x->v32[i+base_index]; + } else { + for (i=0; i < 4 - base_index - 1; i++) + x->v32[i] = (x->v32[i+base_index] << bit_index) ^ + (x->v32[i+base_index+1] >> (32 - bit_index)); + x->v32[4 - base_index-1] = x->v32[4-1] << bit_index; + } + + /* now wrap up the final portion */ + for (i = 4 - base_index; i < 4; i++) + x->v32[i] = 0; + +} + + +#if 0 +void +v128_add(v128_t *z, v128_t *x, v128_t *y) { + /* integer addition modulo 2^128 */ + +#ifdef WORDS_BIGENDIAN + uint64_t tmp; + + tmp = x->v32[3] + y->v32[3]; + z->v32[3] = (uint32_t) tmp; + + tmp = x->v32[2] + y->v32[2] + (tmp >> 32); + z->v32[2] = (uint32_t) tmp; + + tmp = x->v32[1] + y->v32[1] + (tmp >> 32); + z->v32[1] = (uint32_t) tmp; + + tmp = x->v32[0] + y->v32[0] + (tmp >> 32); + z->v32[0] = (uint32_t) tmp; + +#else /* assume little endian architecture */ + uint64_t tmp; + + tmp = htonl(x->v32[3]) + htonl(y->v32[3]); + z->v32[3] = ntohl((uint32_t) tmp); + + tmp = htonl(x->v32[2]) + htonl(y->v32[2]) + htonl(tmp >> 32); + z->v32[2] = ntohl((uint32_t) tmp); + + tmp = htonl(x->v32[1]) + htonl(y->v32[1]) + htonl(tmp >> 32); + z->v32[1] = ntohl((uint32_t) tmp); + + tmp = htonl(x->v32[0]) + htonl(y->v32[0]) + htonl(tmp >> 32); + z->v32[0] = ntohl((uint32_t) tmp); + +#endif /* WORDS_BIGENDIAN */ + +} +#endif + +int +octet_string_is_eq(uint8_t *a, uint8_t *b, int len) { + uint8_t *end = b + len; + while (b < end) + if (*a++ != *b++) + return 1; + return 0; +} + +void +octet_string_set_to_zero(uint8_t *s, int len) { + uint8_t *end = s + len; + + do { + *s = 0; + } while (++s < end); + +} + +/* functions manipulating bit_vector_t */ + +#define BITVECTOR_MAX_WORDS 5 + +int +bitvector_alloc(bitvector_t *v, unsigned long length) { + unsigned long l = (length + bytes_per_word - 1) / bytes_per_word; + int i; + + /* allocate memory, then set parameters */ + if (l > BITVECTOR_MAX_WORDS) + return -1; + else + l = BITVECTOR_MAX_WORDS; + v->word = malloc(l); + if (v->word == NULL) + return -1; + v->length = length; + + /* initialize bitvector to zero */ + for (i=0; i < (length >> 5); i++) { + v->word = 0; + } + + return 0; +} + +void +bitvector_set_bit(bitvector_t *v, int bit_index) { + + v->word[(bit_index >> 5)] |= (1 << (bit_index & 31)); + +} + +int +bitvector_get_bit(const bitvector_t *v, int bit_index) { + + return ((v->word[(bit_index >> 5)]) >> (bit_index & 31)) & 1; + +} + +#include + +int +bitvector_print_hex(const bitvector_t *v, FILE *stream) { + int i; + int m = v->length >> 5; + int n = v->length & 31; + char string[9]; + uint32_t tmp; + + /* if length isn't a multiple of four, we can't hex_print */ + if (n & 3) + return -1; + + /* if the length is zero, do nothing */ + if (v->length == 0) + return 0; + + /* + * loop over words from most significant to least significant - + */ + + for (i=m; i > 0; i++) { + char *str = string + 7; + tmp = v->word[i]; + + /* null terminate string */ + string[8] = 0; + + /* loop over nibbles */ + *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4; + *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4; + *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4; + *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4; + *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4; + *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4; + *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4; + *str-- = nibble_to_hex_char(tmp & 0xf); + + /* now print stream */ + fprintf(stream, string); + } + + return 0; + +} + + +int +hex_string_length(char *s) { + int count = 0; + + /* ignore leading zeros */ + while ((*s != 0) && *s == '0') + s++; + + /* count remaining characters */ + while (*s != 0) { + if (hex_char_to_nibble(*s++) == -1) + return -1; + count++; + } + + return count; +} + +int +bitvector_set_from_hex(bitvector_t *v, char *string) { + int num_hex_chars, m, n, i, j; + uint32_t tmp; + + num_hex_chars = hex_string_length(string); + if (num_hex_chars == -1) + return -1; + + /* set length */ + v->length = num_hex_chars * 4; + /* + * at this point, we should subtract away a bit if the high + * bit of the first character is zero, but we ignore that + * for now and assume that we're four-bit aligned - DAM + */ + + + m = num_hex_chars / 8; /* number of words */ + n = num_hex_chars % 8; /* number of nibbles in last word */ + + /* if the length is greater than the bitvector, return an error */ + if (m > BITVECTOR_MAX_WORDS) + return -1; + + /* + * loop over words from most significant - first word is a special + * case + */ + + if (n) { + tmp = 0; + for (i=0; i < n; i++) { + tmp = hex_char_to_nibble(*string++); + tmp <<= 4; + } + v->word[m] = tmp; + } + + /* now loop over the rest of the words */ + for (i=m-1; i >= 0; i--) { + tmp = 0; + for (j=0; j < 8; j++) { + tmp = hex_char_to_nibble(*string++); + tmp <<= 4; + } + v->word[i] = tmp; + } + + return 0; +} + + +/* functions below not yet tested! */ + +int +v32_low_bit(v32_t *w) { + int value; + + value = low_bit[w->v8[0]]; + if (value != -1) + return value; + value = low_bit[w->v8[1]]; + if (value != -1) + return value + 8; + value = low_bit[w->v8[2]]; + if (value != -1) + return value + 16; + value = low_bit[w->v8[3]]; + if (value == -1) + return -1; + return value + 24; +} + +/* high_bit not done yet */ + + + + + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/math/stat.c b/src/libs/resiprocate/contrib/srtp/crypto/math/stat.c new file mode 100644 index 00000000..5e46c209 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/math/stat.c @@ -0,0 +1,367 @@ +/* + * stats.c + * + * statistical tests for randomness (FIPS 140-2, Section 4.9) + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +#include "stat.h" + +debug_module_t mod_stat = { + 0, /* debugging is off by default */ + (char *)"stat test" /* printable module name */ +}; + +/* + * each test assumes that 20,000 bits (2500 octets) of data is + * provided as input + */ + +#define STAT_TEST_DATA_LEN 2500 + +err_status_t +stat_test_monobit(uint8_t *data) { + uint8_t *data_end = data + STAT_TEST_DATA_LEN; + uint16_t ones_count; + + ones_count = 0; + while (data < data_end) { + ones_count += octet_get_weight(*data); + data++; + } + + debug_print(mod_stat, "bit count: %d", ones_count); + + if ((ones_count < 9725) || (ones_count > 10275)) + return err_status_algo_fail; + + return err_status_ok; +} + +err_status_t +stat_test_poker(uint8_t *data) { + int i; + uint8_t *data_end = data + STAT_TEST_DATA_LEN; + double poker; + uint16_t f[16] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }; + + while (data < data_end) { + f[*data & 0x0f]++; /* increment freq. count for low nibble */ + f[(*data) >> 4]++; /* increment freq. count for high nibble */ + data++; + } + + poker = 0.0; + for (i=0; i < 16; i++) + poker += (double) f[i] * f[i]; + + poker *= (16.0 / 5000.0); + poker -= 5000.0; + + debug_print(mod_stat, "poker test: %f\n", poker); + + if ((poker < 2.16) || (poker > 46.17)) + return err_status_algo_fail; + + return err_status_ok; +} + + +/* + * runs[i] holds the number of runs of size (i-1) + */ + +err_status_t +stat_test_runs(uint8_t *data) { + uint8_t *data_end = data + STAT_TEST_DATA_LEN; + uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 }; + uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 }; + uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 }; + uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 }; + int state = 0; + uint16_t mask; + int i; + + /* + * the state variable holds the number of bits in the + * current run (or gap, if negative) + */ + + while (data < data_end) { + + /* loop over the bits of this byte */ + for (mask = 1; mask < 256; mask <<= 1) { + if (*data & mask) { + + /* next bit is a one */ + if (state > 0) { + + /* prefix is a run, so increment the run-count */ + state++; + + /* check for long runs */ + if (state > 25) { + debug_print(mod_stat, ">25 runs: %d", state); + return err_status_algo_fail; + } + + } else if (state < 0) { + + /* prefix is a gap */ + if (state < -25) { + debug_print(mod_stat, ">25 gaps: %d", state); + return err_status_algo_fail; /* long-runs test failed */ + } + if (state < -6) { + state = -6; /* group together gaps > 5 */ + } + gaps[-1-state]++; /* increment gap count */ + state = 1; /* set state at one set bit */ + } else { + + /* state is zero; this happens only at initialization */ + state = 1; + } + } else { + + /* next bit is a zero */ + if (state > 0) { + + /* prefix is a run */ + if (state > 25) { + debug_print(mod_stat, ">25 runs (2): %d", state); + return err_status_algo_fail; /* long-runs test failed */ + } + if (state > 6) { + state = 6; /* group together runs > 5 */ + } + runs[state-1]++; /* increment run count */ + state = -1; /* set state at one zero bit */ + } else if (state < 0) { + + /* prefix is a gap, so increment gap-count (decrement state) */ + state--; + + /* check for long gaps */ + if (state < -25) { + debug_print(mod_stat, ">25 gaps (2): %d", state); + return err_status_algo_fail; + } + + } else { + + /* state is zero; this happens only at initialization */ + state = -1; + } + } + } + + /* move along to next octet */ + data++; + } + + if (mod_stat.on) { + debug_print(mod_stat, "runs test", NULL); + for (i=0; i < 6; i++) + debug_print(mod_stat, " runs[]: %d", runs[i]); + for (i=0; i < 6; i++) + debug_print(mod_stat, " gaps[]: %d", gaps[i]); + } + + /* check run and gap counts against the fixed limits */ + for (i=0; i < 6; i++) + if ( (runs[i] < lo_value[i] ) || (runs[i] > hi_value[i]) + || (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i])) + return err_status_algo_fail; + + + return err_status_ok; +} + + +/* + * the function stat_test_rand_source applys the FIPS-140-2 statistical + * tests to the random source defined by rs + * + */ + +#define RAND_SRC_BUF_OCTETS 50 /* this value MUST divide 2500! */ + +err_status_t +stat_test_rand_source(rand_source_func_t get_rand_bytes) { + int i; + double poker; + uint8_t *data, *data_end; + uint16_t f[16] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }; + uint8_t buffer[RAND_SRC_BUF_OCTETS]; + err_status_t status; + int ones_count = 0; + uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 }; + uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 }; + uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 }; + uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 }; + int state = 0; + uint16_t mask; + + /* counters for monobit, poker, and runs tests are initialized above */ + + /* main loop: fill buffer, update counters for stat tests */ + for (i=0; i < 2500; i+=RAND_SRC_BUF_OCTETS) { + + /* fill data buffer */ + status = get_rand_bytes(buffer, RAND_SRC_BUF_OCTETS); + if (status) { + debug_print(mod_stat, "couldn't get rand bytes: %d",status); + return status; + } + +#if 0 + debug_print(mod_stat, "%s", + octet_string_hex_string(buffer, RAND_SRC_BUF_OCTETS)); +#endif + + data = buffer; + data_end = data + RAND_SRC_BUF_OCTETS; + while (data < data_end) { + + /* update monobit test counter */ + ones_count += octet_get_weight(*data); + + /* update poker test counters */ + f[*data & 0x0f]++; /* increment freq. count for low nibble */ + f[(*data) >> 4]++; /* increment freq. count for high nibble */ + + /* update runs test counters */ + /* loop over the bits of this byte */ + for (mask = 1; mask < 256; mask <<= 1) { + if (*data & mask) { + + /* next bit is a one */ + if (state > 0) { + + /* prefix is a run, so increment the run-count */ + state++; + + /* check for long runs */ + if (state > 25) { + debug_print(mod_stat, ">25 runs (3): %d", state); + return err_status_algo_fail; + } + + } else if (state < 0) { + + /* prefix is a gap */ + if (state < -25) { + debug_print(mod_stat, ">25 gaps (3): %d", state); + return err_status_algo_fail; /* long-runs test failed */ + } + if (state < -6) { + state = -6; /* group together gaps > 5 */ + } + gaps[-1-state]++; /* increment gap count */ + state = 1; /* set state at one set bit */ + } else { + + /* state is zero; this happens only at initialization */ + state = 1; + } + } else { + + /* next bit is a zero */ + if (state > 0) { + + /* prefix is a run */ + if (state > 25) { + debug_print(mod_stat, ">25 runs (4): %d", state); + return err_status_algo_fail; /* long-runs test failed */ + } + if (state > 6) { + state = 6; /* group together runs > 5 */ + } + runs[state-1]++; /* increment run count */ + state = -1; /* set state at one zero bit */ + } else if (state < 0) { + + /* prefix is a gap, so increment gap-count (decrement state) */ + state--; + + /* check for long gaps */ + if (state < -25) { + debug_print(mod_stat, ">25 gaps (4): %d", state); + return err_status_algo_fail; + } + + } else { + + /* state is zero; this happens only at initialization */ + state = -1; + } + } + } + + /* advance data pointer */ + data++; + } + } + + /* check to see if test data is within bounds */ + + /* check monobit test data */ + + debug_print(mod_stat, "stat: bit count: %d", ones_count); + + if ((ones_count < 9725) || (ones_count > 10275)) { + debug_print(mod_stat, "stat: failed monobit test %d", ones_count); + return err_status_algo_fail; + } + + /* check poker test data */ + poker = 0.0; + for (i=0; i < 16; i++) + poker += (double) f[i] * f[i]; + + poker *= (16.0 / 5000.0); + poker -= 5000.0; + + debug_print(mod_stat, "stat: poker test: %f", poker); + + if ((poker < 2.16) || (poker > 46.17)) { + debug_print(mod_stat, "stat: failed poker test", NULL); + return err_status_algo_fail; + } + + /* check run and gap counts against the fixed limits */ + for (i=0; i < 6; i++) + if ((runs[i] < lo_value[i] ) || (runs[i] > hi_value[i]) + || (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i])) { + debug_print(mod_stat, "stat: failed run/gap test", NULL); + return err_status_algo_fail; + } + + debug_print(mod_stat, "passed random stat test", NULL); + return err_status_ok; +} + +err_status_t +stat_test_rand_source_with_repetition(rand_source_func_t source, unsigned num_trials) { + unsigned int i; + err_status_t err = err_status_algo_fail; + + for (i=0; i < num_trials; i++) { + err = stat_test_rand_source(source); + if (err == err_status_ok) { + return err_status_ok; + } + debug_print(mod_stat, "failed stat test (try number %d)\n", i); + } + + return err; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/replay/rdb.c b/src/libs/resiprocate/contrib/srtp/crypto/replay/rdb.c new file mode 100644 index 00000000..9f2ea878 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/replay/rdb.c @@ -0,0 +1,137 @@ +/* + * rdb.c + * + * Implements a replay database for packet security + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "rdb.h" + + +/* + * this implementation of a replay database works as follows: + * + * window_start is the index of the first packet in the window + * bitmask a bit-buffer, containing the most recently entered + * index as the leftmost bit + * + */ + +/* rdb_init initalizes rdb */ + +err_status_t +rdb_init(rdb_t *rdb) { + v128_set_to_zero(&rdb->bitmask); + rdb->window_start = 0; + return err_status_ok; +} + +/* + * rdb_check checks to see if index appears in rdb + */ + +err_status_t +rdb_check(const rdb_t *rdb, uint32_t index) { + + /* if the index appears after (or at very end of) the window, its good */ + if (index >= rdb->window_start + rdb_bits_in_bitmask) + return err_status_ok; + + /* if the index appears before the window, its bad */ + if (index < rdb->window_start) + return err_status_replay_old; + + /* otherwise, the index appears within the window, so check the bitmask */ + if (v128_get_bit(&rdb->bitmask, (index - rdb->window_start)) == 1) + return err_status_replay_fail; + + /* otherwise, the index is okay */ + return err_status_ok; +} + +/* + * rdb_add_index adds index to rdb_t (and does *not* check if + * index appears in db) + * + * this function should be called only after rdb_check has + * indicated that the index does not appear in the rdb, e.g., a mutex + * should protect the rdb between these calls + */ + +err_status_t +rdb_add_index(rdb_t *rdb, uint32_t index) { + int delta; + + /* here we *assume* that index > rdb->window_start */ + + delta = (index - rdb->window_start); + if (delta < rdb_bits_in_bitmask) { + + /* if the index is within the window, set the appropriate bit */ + v128_set_bit(&rdb->bitmask, delta); + + } else { + + delta -= rdb_bits_in_bitmask - 1; + + /* shift the window forward by delta bits*/ + v128_left_shift(&rdb->bitmask, delta); + v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask-delta); + rdb->window_start += delta; + + } + + return err_status_ok; +} + +err_status_t +rdb_increment(rdb_t *rdb) { + + if (rdb->window_start++ > 0x7fffffff) + return err_status_key_expired; + return err_status_ok; +} + +uint32_t +rdb_get_value(const rdb_t *rdb) { + return rdb->window_start; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/replay/rdbx.c b/src/libs/resiprocate/contrib/srtp/crypto/replay/rdbx.c new file mode 100644 index 00000000..12e4e8f8 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/replay/rdbx.c @@ -0,0 +1,289 @@ +/* + * rdbx.c + * + * a replay database with extended range, using a rollover counter + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "rdbx.h" + +#define rdbx_high_bit_in_bitmask 127 + +/* + * from draft-ietf-avt-srtp-00.txt: + * + * A receiver reconstructs the index i of a packet with sequence + * number s using the estimate + * + * i = 65,536 * t + s, + * + * where t is chosen from the set { r-1, r, r+1 } such that i is + * closest to the value 65,536 * r + s_l. If the value r+1 is used, + * then the rollover counter r in the cryptographic context is + * incremented by one (if the packet containing s is authentic). + */ + + + +/* + * rdbx implementation notes + * + * A xtd_seq_num_t is essentially a sequence number for which some of + * the data on the wire are implicit. It logically consists of a + * rollover counter and a sequence number; the sequence number is the + * explicit part, and the rollover counter is the implicit part. + * + * Upon receiving a sequence_number (e.g. in a newly received SRTP + * packet), the complete xtd_seq_num_t can be estimated by using a + * local xtd_seq_num_t as a basis. This is done using the function + * index_guess(&local, &guess, seq_from_packet). This function + * returns the difference of the guess and the local value. The local + * xtd_seq_num_t can be moved forward to the guess using the function + * index_advance(&guess, delta), where delta is the difference. + * + * + * A rdbx_t consists of a xtd_seq_num_t and a bitmask. The index is highest + * sequence number that has been received, and the bitmask indicates + * which of the recent indicies have been received as well. The + * highest bit in the bitmask corresponds to the index in the bitmask. + */ + + +void +index_init(xtd_seq_num_t *pi) { +#ifdef NO_64BIT_MATH + *pi = make64(0,0); +#else + *pi = 0; +#endif +} + +void +index_advance(xtd_seq_num_t *pi, sequence_number_t s) { +#ifdef NO_64BIT_MATH + /* a > ~b means a+b will generate a carry */ + /* s is uint16 here */ + *pi = make64(high32(*pi) + (s > ~low32(*pi) ? 1 : 0),low32(*pi) + s); +#else + *pi += s; +#endif +} + + +/* + * index_guess(local, guess, s) + * + * given a xtd_seq_num_t local (which represents the last + * known-to-be-good received xtd_seq_num_t) and a sequence number s + * (from a newly arrived packet), sets the contents of *guess to + * contain the best guess of the packet index to which s corresponds, + * and returns the difference between *guess and *local + * + * nota bene - the output is a signed integer, DON'T cast it to a + * unsigned integer! + */ + +int +index_guess(const xtd_seq_num_t *local, + xtd_seq_num_t *guess, + sequence_number_t s) { +#ifdef NO_64BIT_MATH + uint32_t local_roc = ((high32(*local) << 16) | + (low32(*local) >> 16)); + uint16_t local_seq = (uint16_t) (low32(*local)); +#else + uint32_t local_roc = (uint32_t)(*local >> 16); + uint16_t local_seq = (uint16_t) *local; +#endif +#ifdef NO_64BIT_MATH + uint32_t guess_roc = ((high32(*guess) << 16) | + (low32(*guess) >> 16)); + uint16_t guess_seq = (uint16_t) (low32(*guess)); +#else + uint32_t guess_roc = (uint32_t)(*guess >> 16); + uint16_t guess_seq = (uint16_t) *guess; +#endif + int difference; + + if (local_seq < seq_num_median) { + if (s - local_seq > seq_num_median) { + guess_roc = local_roc - 1; + difference = seq_num_max - s + local_seq; + } else { + guess_roc = local_roc; + difference = s - local_seq; + } + } else { + if (local_seq - seq_num_median > s) { + guess_roc = local_roc+1; + difference = seq_num_max - local_seq + s; + } else { + difference = s - local_seq; + guess_roc = local_roc; + } + } + guess_seq = s; + + /* Note: guess_roc is 32 bits, so this generates a 48-bit result! */ +#ifdef NO_64BIT_MATH + *guess = make64(guess_roc >> 16, + (guess_roc << 16) | guess_seq); +#else + *guess = (((uint64_t) guess_roc) << 16) | guess_seq; +#endif + + return difference; +} + +/* + * rdbx + * + */ + + +/* + * rdbx_init(&r) initalizes the rdbx_t pointed to by r + */ + +err_status_t +rdbx_init(rdbx_t *rdbx) { + v128_set_to_zero(&rdbx->bitmask); + index_init(&rdbx->index); + + return err_status_ok; +} + + +/* + * rdbx_check(&r, delta) checks to see if the xtd_seq_num_t + * which is at rdbx->index + delta is in the rdb + */ + +err_status_t +rdbx_check(const rdbx_t *rdbx, int delta) { + + if (delta > 0) { /* if delta is positive, it's good */ + return err_status_ok; + } else if (rdbx_high_bit_in_bitmask + delta < 0) { + /* if delta is lower than the bitmask, it's bad */ + return err_status_replay_old; + } else if (v128_get_bit(&rdbx->bitmask, + rdbx_high_bit_in_bitmask + delta) == 1) { + /* delta is within the window, so check the bitmask */ + return err_status_replay_fail; + } + /* otherwise, the index is okay */ + + return err_status_ok; +} + +/* + * rdbx_add_index adds the xtd_seq_num_t at rdbx->window_start + d to + * replay_db (and does *not* check if that xtd_seq_num_t appears in db) + * + * this function should be called only after replay_check has + * indicated that the index does not appear in the rdbx, e.g., a mutex + * should protect the rdbx between these calls if need be + */ + +err_status_t +rdbx_add_index(rdbx_t *rdbx, int delta) { + + if (delta > 0) { + /* shift forward by delta */ + index_advance(&rdbx->index, delta); + v128_left_shift(&rdbx->bitmask, delta); + v128_set_bit(&rdbx->bitmask, 127); + } else { + /* delta is in window, so flip bit in bitmask */ + v128_set_bit(&rdbx->bitmask, -delta); + } + + /* note that we need not consider the case that delta == 0 */ + + return err_status_ok; +} + + + +/* + * rdbx_estimate_index(rdbx, guess, s) + * + * given an rdbx and a sequence number s (from a newly arrived packet), + * sets the contents of *guess to contain the best guess of the packet + * index to which s corresponds, and returns the difference between + * *guess and the locally stored synch info + */ + +int +rdbx_estimate_index(const rdbx_t *rdbx, + xtd_seq_num_t *guess, + sequence_number_t s) { + + /* + * if the sequence number and rollover counter in the rdbx are + * non-zero, then use the index_guess(...) function, otherwise, just + * set the rollover counter to zero (since the index_guess(...) + * function might incorrectly guess that the rollover counter is + * 0xffffffff) + */ + +#ifdef NO_64BIT_MATH + /* seq_num_median = 0x8000 */ + if (high32(rdbx->index) > 0 || + low32(rdbx->index) > seq_num_median) +#else + if (rdbx->index > seq_num_median) +#endif + return index_guess(&rdbx->index, guess, s); + +#ifdef NO_64BIT_MATH + *guess = make64(0,(uint32_t) s); +#else + *guess = s; +#endif + +#ifdef NO_64BIT_MATH + return s - (uint16_t) low32(rdbx->index); +#else + return s - (uint16_t) rdbx->index; +#endif +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/replay/ut_sim.c b/src/libs/resiprocate/contrib/srtp/crypto/replay/ut_sim.c new file mode 100644 index 00000000..43c411e4 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/replay/ut_sim.c @@ -0,0 +1,105 @@ +/* + * ut_sim.c + * + * an unreliable transport simulator + * (for testing replay databases and suchlike) + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "ut_sim.h" + + +int +ut_compar(const void *a, const void *b) { + return rand() > (RAND_MAX/2) ? -1 : 1; +} + +void +ut_init(ut_connection *utc) { + int i; + utc->index = 0; + + for (i=0; i < UT_BUF; i++) + utc->buffer[i] = i; + + qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar); + + utc->index = UT_BUF - 1; +} + +uint32_t +ut_next_index(ut_connection *utc) { + uint32_t tmp; + + tmp = utc->buffer[0]; + utc->index++; + utc->buffer[0] = utc->index; + + qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar); + + return tmp; +} + + + +#ifdef UT_TEST + +#include + +int +main() { + uint32_t i, irecvd, idiff; + ut_connection utc; + + ut_init(&utc); + + for (i=0; i < 1000; i++) { + irecvd = ut_next_index(&utc); + idiff = i - irecvd; + printf("%lu\t%lu\t%d\n", i, irecvd, idiff); + } + + return 0; +} + + +#endif diff --git a/src/libs/resiprocate/contrib/srtp/crypto/rng/ctr_prng.c b/src/libs/resiprocate/contrib/srtp/crypto/rng/ctr_prng.c new file mode 100644 index 00000000..ab76df36 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/rng/ctr_prng.c @@ -0,0 +1,108 @@ +/* + * ctr_prng.c + * + * counter mode based pseudorandom source + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "prng.h" + +/* single, global prng structure */ + +ctr_prng_t ctr_prng; + +err_status_t +ctr_prng_init(rand_source_func_t random_source) { + uint8_t tmp_key[32]; + err_status_t status; + + /* initialize output count to zero */ + ctr_prng.octet_count = 0; + + /* set random source */ + ctr_prng.rand = random_source; + + /* initialize secret key from random source */ + status = random_source(tmp_key, 32); + if (status) + return status; + + /* initialize aes ctr context with random key */ + status = aes_icm_context_init(&ctr_prng.state, tmp_key); + if (status) + return status; + + return err_status_ok; +} + +err_status_t +ctr_prng_get_octet_string(void *dest, uint32_t len) { + err_status_t status; + + /* + * if we need to re-initialize the prng, do so now + * + * avoid 32-bit overflows by subtracting instead of adding + */ + if (ctr_prng.octet_count > MAX_PRNG_OUT_LEN - len) { + status = ctr_prng_init(ctr_prng.rand); + if (status) + return status; + } + ctr_prng.octet_count += len; + + /* + * write prng output + */ + status = aes_icm_output(&ctr_prng.state, (uint8_t*)dest, len); + if (status) + return status; + + return err_status_ok; +} + +err_status_t +ctr_prng_deinit(void) { + + /* nothing */ + + return err_status_ok; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/rng/prng.c b/src/libs/resiprocate/contrib/srtp/crypto/rng/prng.c new file mode 100644 index 00000000..69350a48 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/rng/prng.c @@ -0,0 +1,180 @@ +/* + * prng.c + * + * pseudorandom source + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "prng.h" + +/* single, global prng structure */ + +x917_prng_t x917_prng; + +err_status_t +x917_prng_init(rand_source_func_t random_source) { + v128_t tmp_key; + err_status_t status; + + /* initialize output count to zero */ + x917_prng.octet_count = 0; + + /* set random source */ + x917_prng.rand = random_source; + + /* initialize secret key from random source */ + status = random_source((uint8_t *)&tmp_key, 16); + if (status) + return status; + + /* expand aes key */ + aes_expand_encryption_key(&tmp_key, x917_prng.key); + + /* initialize prng state from random source */ + status = x917_prng.rand((uint8_t *)&x917_prng.state, 16); + if (status) + return status; + + return err_status_ok; +} + +err_status_t +x917_prng_get_octet_string(uint8_t *dest, uint32_t len) { + uint32_t t; + v128_t buffer; + uint32_t i, tail_len; + err_status_t status; + + /* + * if we need to re-initialize the prng, do so now + * + * avoid overflows by subtracting instead of adding + */ + if (x917_prng.octet_count > MAX_PRNG_OUT_LEN - len) { + status = x917_prng_init(x917_prng.rand); + if (status) + return status; + } + x917_prng.octet_count += len; + + /* find out the time */ + t = (uint32_t)time(NULL); + + /* loop until we have output enough data */ + for (i=0; i < len/16; i++) { + + /* exor time into state */ + x917_prng.state.v32[0] ^= t; + + /* copy state into buffer */ + v128_copy(&buffer, &x917_prng.state); + + /* apply aes to buffer */ + aes_encrypt(&buffer, x917_prng.key); + + /* write data to output */ + *dest++ = buffer.v8[0]; + *dest++ = buffer.v8[1]; + *dest++ = buffer.v8[2]; + *dest++ = buffer.v8[3]; + *dest++ = buffer.v8[4]; + *dest++ = buffer.v8[5]; + *dest++ = buffer.v8[6]; + *dest++ = buffer.v8[7]; + *dest++ = buffer.v8[8]; + *dest++ = buffer.v8[9]; + *dest++ = buffer.v8[10]; + *dest++ = buffer.v8[11]; + *dest++ = buffer.v8[12]; + *dest++ = buffer.v8[13]; + *dest++ = buffer.v8[14]; + *dest++ = buffer.v8[15]; + + /* exor time into buffer */ + buffer.v32[0] ^= t; + + /* encrypt buffer */ + aes_encrypt(&buffer, x917_prng.key); + + /* copy buffer into state */ + v128_copy(&x917_prng.state, &buffer); + + } + + /* if we need to output any more octets, we'll do so now */ + tail_len = len % 16; + if (tail_len) { + + /* exor time into state */ + x917_prng.state.v32[0] ^= t; + + /* copy value into buffer */ + v128_copy(&buffer, &x917_prng.state); + + /* apply aes to buffer */ + aes_encrypt(&buffer, x917_prng.key); + + /* write data to output */ + for (i=0; i < tail_len; i++) { + *dest++ = buffer.v8[i]; + } + + /* now update the state one more time */ + + /* exor time into buffer */ + buffer.v32[0] ^= t; + + /* encrypt buffer */ + aes_encrypt(&buffer, x917_prng.key); + + /* copy buffer into state */ + v128_copy(&x917_prng.state, &buffer); + + } + + return err_status_ok; +} + +err_status_t +x917_prng_deinit(void) { + + return err_status_ok; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/rng/rand_linux_kernel.c b/src/libs/resiprocate/contrib/srtp/crypto/rng/rand_linux_kernel.c new file mode 100644 index 00000000..c51978e5 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/rng/rand_linux_kernel.c @@ -0,0 +1,65 @@ +/* + * rand_linux_kernel.c + * + * implements a random source using Linux kernel functions + * + * Marcus Sundberg + * Ingate Systems AB + */ +/* + * + * Copyright(c) 2005 Ingate Systems AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the author(s) nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "config.h" +#include "rand_source.h" + + +err_status_t +rand_source_init(void) { + return err_status_ok; +} + +err_status_t +rand_source_get_octet_string(void *dest, uint32_t len) { + + get_random_bytes(dest, len); + + return err_status_ok; +} + +err_status_t +rand_source_deinit(void) { + return err_status_ok; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/rng/rand_source.c b/src/libs/resiprocate/contrib/srtp/crypto/rng/rand_source.c new file mode 100644 index 00000000..1b60ad7d --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/rng/rand_source.c @@ -0,0 +1,153 @@ +/* + * rand_source.c + * + * implements a random source based on /dev/random + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "config.h" + +#ifdef DEV_URANDOM +# include /* for open() */ +# include /* for close() */ +#elif (_MSC_VER >= 1400) +#define _CRT_RAND_S +# include +# include +#else +# include +#endif + +#include "rand_source.h" + + +/* + * global dev_rand_fdes is file descriptor for /dev/random + * + * This variable is also used to indicate that the random source has + * been initialized. When this variable is set to the value of the + * #define RAND_SOURCE_NOT_READY, it indicates that the random source + * is not ready to be used. The value of the #define + * RAND_SOURCE_READY is for use whenever that variable is used as an + * indicator of the state of the random source, but not as a file + * descriptor. + */ + +#define RAND_SOURCE_NOT_READY (-1) +#define RAND_SOURCE_READY (17) + +static int dev_random_fdes = RAND_SOURCE_NOT_READY; + + +err_status_t +rand_source_init(void) { + if (dev_random_fdes >= 0) { + /* already open */ + return err_status_ok; + } +#ifdef DEV_URANDOM + /* open random source for reading */ + dev_random_fdes = open(DEV_URANDOM, O_RDONLY); + if (dev_random_fdes < 0) + return err_status_init_fail; +#elif (_MSC_VER >= 1400) + dev_random_fdes = RAND_SOURCE_READY; +#else + /* no random source available; let the user know */ + fprintf(stderr, "WARNING: no real random source present!\n"); + dev_random_fdes = RAND_SOURCE_READY; +#endif + return err_status_ok; +} + +err_status_t +rand_source_get_octet_string(void *dest, uint32_t len) { + + /* + * read len octets from /dev/random to dest, and + * check return value to make sure enough octets were + * written + */ +#ifdef DEV_URANDOM + if (read(dev_random_fdes, dest, len) != len) + return err_status_fail; +#elif (_MSC_VER >= 1400) + uint8_t *dst = dest; + while (len) + { + unsigned int val = 0; + errno_t err = rand_s(&val); + if (err != 0) + { + return err_status_fail; + } + + *dst++ = val; + len--; + } +#else + /* Generic C-library (rand()) version */ + /* This is a random source of last resort */ + uint8_t *dst = (uint8_t *)dest; + while (len) + { + int val = rand(); + /* rand() returns 0-32767 (ugh) */ + /* Is this a good enough way to get random bytes? + It is if it passes FIPS-140... */ + *dst++ = val & 0xff; + len--; + } +#endif + return err_status_ok; +} + +err_status_t +rand_source_deinit(void) { + if (dev_random_fdes < 0) + return err_status_dealloc_fail; /* well, we haven't really failed, * + * but there is something wrong */ +#ifdef DEV_URANDOM + close(dev_random_fdes); +#endif + dev_random_fdes = RAND_SOURCE_NOT_READY; + + return err_status_ok; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/test/.cvsignore b/src/libs/resiprocate/contrib/srtp/crypto/test/.cvsignore new file mode 100644 index 00000000..888bf597 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/test/.cvsignore @@ -0,0 +1,8 @@ +aes_calc +cipher_driver +datatypes_driver +env +kernel_driver +rand_gen +sha1_driver +stat_driver diff --git a/src/libs/resiprocate/contrib/srtp/crypto/test/aes_calc.c b/src/libs/resiprocate/contrib/srtp/crypto/test/aes_calc.c new file mode 100644 index 00000000..2fac07ae --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/test/aes_calc.c @@ -0,0 +1,111 @@ +/* + * aes_calc.c + * + * A simple AES calculator for generating AES encryption values + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + + Example usage (with first NIST FIPS 197 test case): + +[sh]$ test/aes_calc 000102030405060708090a0b0c0d0e0f 00112233445566778899aabbccddeeff -v + plaintext: 00112233445566778899aabbccddeeff + key: 000102030405060708090a0b0c0d0e0f + ciphertext: 69c4e0d86a7b0430d8cdb78070b4c55a + + */ + +#include "aes.h" +#include +#include + +void +usage(char *prog_name) { + printf("usage: %s [-v]\n", prog_name); + exit(255); +} + +#define AES_KEY_LEN 16 + +int +main (int argc, char *argv[]) { + v128_t data, key; + aes_expanded_key_t exp_key; + int len; + int verbose; + + if (argc == 3) { + /* we're not in verbose mode */ + verbose = 0; + } else if (argc == 4) { + if (strncmp(argv[3], "-v", 2) == 0) { + /* we're in verbose mode */ + verbose = 1; + } else { + /* unrecognized flag, complain and exit */ + usage(argv[0]); + } + } else { + /* we've been fed the wrong number of arguments - compain and exit */ + usage(argv[0]); + } + + /* read in key, checking length */ + if (strlen(argv[1]) > AES_KEY_LEN*2) { + fprintf(stderr, + "error: too many digits in key " + "(should be %d hexadecimal digits, found %u)\n", + AES_KEY_LEN*2, (unsigned)strlen(argv[1])); + exit(1); + } + len = hex_string_to_octet_string((char *)&key, argv[1], AES_KEY_LEN*2); + /* check that hex string is the right length */ + if (len < AES_KEY_LEN*2) { + fprintf(stderr, + "error: too few digits in key " + "(should be %d hexadecimal digits, found %d)\n", + AES_KEY_LEN*2, len); + exit(1); + } + + /* read in plaintext, checking length */ + if (strlen(argv[2]) > 16*2) { + fprintf(stderr, + "error: too many digits in plaintext " + "(should be %d hexadecimal digits, found %u)\n", + 16*2, (unsigned)strlen(argv[2])); + exit(1); + } + len = hex_string_to_octet_string((char *)(&data), argv[2], 16*2); + /* check that hex string is the right length */ + if (len < 16*2) { + fprintf(stderr, + "error: too few digits in plaintext " + "(should be %d hexadecimal digits, found %d)\n", + 16*2, len); + exit(1); + } + + if (verbose) { + /* print out plaintext */ + printf("plaintext:\t%s\n", octet_string_hex_string((uint8_t *)&data, 16)); + } + + /* encrypt plaintext */ + aes_expand_encryption_key(&key, exp_key); + + aes_encrypt(&data, exp_key); + + /* write ciphertext to output */ + if (verbose) { + printf("key:\t\t%s\n", v128_hex_string(&key)); + printf("ciphertext:\t"); + } + printf("%s\n", v128_hex_string(&data)); + + return 0; +} + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/test/auth_driver.c b/src/libs/resiprocate/contrib/srtp/crypto/test/auth_driver.c new file mode 100644 index 00000000..cd8a75dd --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/test/auth_driver.c @@ -0,0 +1,200 @@ +/* + * auth_driver.c + * + * a driver for auth functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include <stdio.h> /* for printf() */ +#include <stdlib.h> /* for xalloc() */ +#include <unistd.h> /* for getopt() */ + +#include "auth.h" +#include "null_auth.h" + +#define PRINT_DEBUG_DATA 0 + +extern auth_type_t tmmhv2; + +const uint16_t msg0[9] = { + 0x6015, 0xf141, 0x5ba1, 0x29a0, 0xf604, 0xd1c, 0x2d9, 0xaa8a, 0x7931 +}; + +/* key1 is for TAG_WORDS = 2 */ + +const uint16_t key1[47] = { + 0xe627, 0x6a01, 0x5ea7, 0xf27a, 0xc536, 0x2192, 0x11be, 0xea35, + 0xdb9d, 0x63d6, 0xfa8a, 0xfc45, 0xe08b, 0xd216, 0xced2, 0x7853, + 0x1a82, 0x22f5, 0x90fb, 0x1c29, 0x708e, 0xd06f, 0x82c3, 0xbee6, + 0x4f21, 0x6f33, 0x65c0, 0xd211, 0xc25e, 0x9138, 0x4fa3, 0x7c1f, + 0x61ac, 0x3489, 0x2976, 0x8c19, 0x8252, 0xddbf, 0xcad3, 0xc28f, + 0x68d6, 0x58dd, 0x504f, 0x2bbf, 0x0278, 0x70b7, 0xcfca +}; + +double +auth_bits_per_second(auth_t *h, int msg_len); + + +void +usage(char *prog_name) { + printf("usage: %s [ -t | -v ]\n", prog_name); + exit(255); +} + +#define MAX_MSG_LEN 2048 + +int +main (int argc, char *argv[]) { + auth_t *a = NULL; + err_status_t status; + int i; + int c; + unsigned do_timing_test = 0; + unsigned do_validation = 0; + + /* process input arguments */ + while (1) { + c = getopt(argc, argv, "tv"); + if (c == -1) + break; + switch (c) { + case 't': + do_timing_test = 1; + break; + case 'v': + do_validation = 1; + break; + default: + usage(argv[0]); + } + } + + printf("auth driver\nDavid A. McGrew\nCisco Systems, Inc.\n"); + + if (!do_validation && !do_timing_test) + usage(argv[0]); + + if (do_validation) { + printf("running self-test for %s...", tmmhv2.description); + status = tmmhv2_add_big_test(); + if (status) { + printf("tmmhv2_add_big_test failed with error code %d\n", status); + exit(status); + } + status = auth_type_self_test(&tmmhv2); + if (status) { + printf("failed with error code %d\n", status); + exit(status); + } + printf("passed\n"); + } + + if (do_timing_test) { + + /* tmmhv2 timing test */ + status = auth_type_alloc(&tmmhv2, &a, 94, 4); + if (status) { + fprintf(stderr, "can't allocate tmmhv2\n"); + exit(status); + } + status = auth_init(a, (uint8_t *)key1); + if (status) { + printf("error initializaing auth function\n"); + exit(status); + } + + printf("timing %s (tag length %d)\n", + tmmhv2.description, auth_get_tag_length(a)); + for (i=8; i <= MAX_MSG_LEN; i *= 2) + printf("msg len: %d\tgigabits per second: %f\n", + i, auth_bits_per_second(a, i) / 1E9); + + status = auth_dealloc(a); + if (status) { + printf("error deallocating auth function\n"); + exit(status); + } + + } + + return 0; +} + +#define NUM_TRIALS 100000 + +#include <time.h> + +double +auth_bits_per_second(auth_t *a, int msg_len_octets) { + int i; + clock_t timer; + uint8_t *result; + int msg_len = (msg_len_octets + 1)/2; + uint16_t *msg_string; + + /* create random message */ + msg_string = (uint16_t *) crypto_alloc(msg_len_octets); + if (msg_string == NULL) + return 0.0; /* indicate failure */ + for (i=0; i < msg_len; i++) + msg_string[i] = (uint16_t) random(); + + /* allocate temporary storage for authentication tag */ + result = crypto_alloc(auth_get_tag_length(a)); + if (result == NULL) { + free(msg_string); + return 0.0; /* indicate failure */ + } + + timer = clock(); + for (i=0; i < NUM_TRIALS; i++) { + auth_compute(a, (uint8_t *)msg_string, msg_len_octets, (uint8_t *)result); + } + timer = clock() - timer; + + free(msg_string); + free(result); + + return (double) NUM_TRIALS * 8 * msg_len_octets * CLOCKS_PER_SEC / timer; +} + + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/test/cipher_driver.c b/src/libs/resiprocate/contrib/srtp/crypto/test/cipher_driver.c new file mode 100644 index 00000000..25ca90af --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/test/cipher_driver.c @@ -0,0 +1,491 @@ +/* + * cipher_driver.c + * + * A driver for the generic cipher type + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> /* for printf() */ +#include <stdlib.h> /* for rand() */ +#include <string.h> /* for memset() */ +#include <unistd.h> /* for getopt() */ +#include "cipher.h" +#include "aes_icm.h" +#include "null_cipher.h" + +#define PRINT_DEBUG 0 + +void +cipher_driver_test_throughput(cipher_t *c); + +err_status_t +cipher_driver_self_test(cipher_type_t *ct); + + +/* + * cipher_driver_test_buffering(ct) tests the cipher's output + * buffering for correctness by checking the consistency of succesive + * calls + */ + +err_status_t +cipher_driver_test_buffering(cipher_t *c); + + +/* + * functions for testing cipher cache thrash + */ +err_status_t +cipher_driver_test_array_throughput(cipher_type_t *ct, + int klen, int num_cipher); + +void +cipher_array_test_throughput(cipher_t *ca[], int num_cipher); + +uint64_t +cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, + unsigned octets_in_buffer, int num_trials); + +err_status_t +cipher_array_delete(cipher_t *cipher_array[], int num_cipher); + +err_status_t +cipher_array_alloc_init(cipher_t ***cipher_array, int num_ciphers, + cipher_type_t *ctype, int klen); + +void +usage(char *prog_name) { + printf("usage: %s [ -t | -v | -a ]\n", prog_name); + exit(255); +} + +void +check_status(err_status_t s) { + if (s) { + printf("error (code %d)\n", s); + exit(s); + } + return; +} + +/* + * null_cipher, aes_icm, and aes_cbc are the cipher meta-objects + * defined in the files in crypto/cipher subdirectory. these are + * declared external so that we can use these cipher types here + */ + +extern cipher_type_t null_cipher; +extern cipher_type_t aes_icm; +extern cipher_type_t aes_cbc; + +int +main(int argc, char *argv[]) { + cipher_t *c = NULL; + err_status_t status; + unsigned char test_key[20] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 + }; + int q; + unsigned do_timing_test = 0; + unsigned do_validation = 0; + unsigned do_array_timing_test = 0; + + /* process input arguments */ + while (1) { + q = getopt(argc, argv, "tva"); + if (q == -1) + break; + switch (q) { + case 't': + do_timing_test = 1; + break; + case 'v': + do_validation = 1; + break; + case 'a': + do_array_timing_test = 1; + break; + default: + usage(argv[0]); + } + } + + printf("cipher test driver\n" + "David A. McGrew\n" + "Cisco Systems, Inc.\n"); + + if (!do_validation && !do_timing_test && !do_array_timing_test) + usage(argv[0]); + + /* arry timing (cache thrash) test */ + if (do_array_timing_test) { + int max_num_cipher = 1 << 16; /* number of ciphers in cipher_array */ + int num_cipher; + + for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) + cipher_driver_test_array_throughput(&null_cipher, 0, num_cipher); + + for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) + cipher_driver_test_array_throughput(&aes_icm, 30, num_cipher); + + for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) + cipher_driver_test_array_throughput(&aes_cbc, 16, num_cipher); + + } + + if (do_validation) { + cipher_driver_self_test(&null_cipher); + cipher_driver_self_test(&aes_icm); + cipher_driver_self_test(&aes_cbc); + } + + /* do timing and/or buffer_test on null_cipher */ + status = cipher_type_alloc(&null_cipher, &c, 0); + check_status(status); + + status = cipher_init(c, NULL, direction_encrypt); + check_status(status); + + if (do_timing_test) + cipher_driver_test_throughput(c); + if (do_validation) { + status = cipher_driver_test_buffering(c); + check_status(status); + } + status = cipher_dealloc(c); + check_status(status); + + + /* run the throughput test on the aes_icm cipher */ + status = cipher_type_alloc(&aes_icm, &c, 30); + if (status) { + fprintf(stderr, "error: can't allocate cipher\n"); + exit(status); + } + + status = cipher_init(c, test_key, direction_encrypt); + check_status(status); + + if (do_timing_test) + cipher_driver_test_throughput(c); + + if (do_validation) { + status = cipher_driver_test_buffering(c); + check_status(status); + } + + status = cipher_dealloc(c); + check_status(status); + + return 0; +} + +void +cipher_driver_test_throughput(cipher_t *c) { + int i; + int min_enc_len = 32; + int max_enc_len = 2048; /* should be a power of two */ + int num_trials = 100000; + + printf("timing %s throughput:\n", c->type->description); + fflush(stdout); + for (i=min_enc_len; i <= max_enc_len; i = i * 2) + printf("msg len: %d\tgigabits per second: %f\n", + i, cipher_bits_per_second(c, i, num_trials) / 1e9); + +} + +err_status_t +cipher_driver_self_test(cipher_type_t *ct) { + err_status_t status; + + printf("running cipher self-test for %s...", ct->description); + status = cipher_type_self_test(ct); + if (status) { + printf("failed with error code %d\n", status); + exit(status); + } + printf("passed\n"); + + return err_status_ok; +} + +/* + * cipher_driver_test_buffering(ct) tests the cipher's output + * buffering for correctness by checking the consistency of succesive + * calls + */ + +err_status_t +cipher_driver_test_buffering(cipher_t *c) { + int i, j, num_trials = 1000; + unsigned len, buflen = 1024; + uint8_t buffer0[buflen], buffer1[buflen], *current, *end; + uint8_t idx[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34 + }; + err_status_t status; + + printf("testing output buffering for cipher %s...", + c->type->description); + + for (i=0; i < num_trials; i++) { + + /* set buffers to zero */ + for (j=0; j < buflen; j++) + buffer0[j] = buffer1[j] = 0; + + /* initialize cipher */ + status = cipher_set_iv(c, idx); + if (status) + return status; + + /* generate 'reference' value by encrypting all at once */ + status = cipher_encrypt(c, buffer0, &buflen); + if (status) + return status; + + /* re-initialize cipher */ + status = cipher_set_iv(c, idx); + if (status) + return status; + + /* now loop over short lengths until buffer1 is encrypted */ + current = buffer1; + end = buffer1 + buflen; + while (current < end) { + + /* choose a short length */ + len = rand() & 0x01f; + + /* make sure that len doesn't cause us to overreach the buffer */ + if (current + len > end) + len = end - current; + + status = cipher_encrypt(c, current, &len); + if (status) + return status; + + /* advance pointer into buffer1 to reflect encryption */ + current += len; + + /* if buffer1 is all encrypted, break out of loop */ + if (current == end) + break; + } + + /* compare buffers */ + for (j=0; j < buflen; j++) + if (buffer0[j] != buffer1[j]) { +#if PRINT_DEBUG + printf("test case %d failed at byte %d\n", i, j); + printf("computed: %s\n", octet_string_hex_string(buffer1, buflen)); + printf("expected: %s\n", octet_string_hex_string(buffer0, buflen)); +#endif + return err_status_algo_fail; + } + } + + printf("passed\n"); + + return err_status_ok; +} + + +/* + * The function cipher_test_throughput_array() tests the effect of CPU + * cache thrash on cipher throughput. + * + * cipher_array_alloc_init(ctype, array, num_ciphers) creates an array + * of cipher_t of type ctype + */ + +err_status_t +cipher_array_alloc_init(cipher_t ***ca, int num_ciphers, + cipher_type_t *ctype, int klen) { + int i, j; + err_status_t status; + uint8_t *key; + cipher_t **cipher_array; + + /* allocate array of pointers to ciphers */ + cipher_array = (cipher_t **) malloc(sizeof(cipher_t *) * num_ciphers); + if (cipher_array == NULL) + return err_status_alloc_fail; + + /* set ca to location of cipher_array */ + *ca = cipher_array; + + /* allocate key */ + key = crypto_alloc(klen); + if (key == NULL) { + free(cipher_array); + return err_status_alloc_fail; + } + + /* allocate and initialize an array of ciphers */ + for (i=0; i < num_ciphers; i++) { + + /* allocate cipher */ + status = cipher_type_alloc(ctype, cipher_array, klen); + if (status) + return status; + + /* generate random key and initialize cipher */ + for (j=0; j < klen; j++) + key[j] = (uint8_t) rand(); + status = cipher_init(*cipher_array, key, direction_encrypt); + if (status) + return status; + +/* printf("%dth cipher is at %p\n", i, *cipher_array); */ +/* printf("%dth cipher description: %s\n", i, */ +/* (*cipher_array)->type->description); */ + + /* advance cipher array pointer */ + cipher_array++; + } + + return err_status_ok; +} + +err_status_t +cipher_array_delete(cipher_t *cipher_array[], int num_cipher) { + int i; + + for (i=0; i < num_cipher; i++) { + cipher_dealloc(cipher_array[i]); + } + + free(cipher_array); + + return err_status_ok; +} + + +/* + * cipher_array_bits_per_second(c, l, t) computes (an estimate of) the + * number of bits that a cipher implementation can encrypt in a second + * when distinct keys are used to encrypt distinct messages + * + * c is a cipher (which MUST be allocated an initialized already), l + * is the length in octets of the test data to be encrypted, and t is + * the number of trials + * + * if an error is encountered, the value 0 is returned + */ + +uint64_t +cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, + unsigned octets_in_buffer, int num_trials) { + int i; + v128_t nonce; + clock_t timer; + unsigned char *enc_buf; + int cipher_index = 0; + + + enc_buf = crypto_alloc(octets_in_buffer); + if (enc_buf == NULL) + return 0; /* indicate bad parameters by returning null */ + + /* time repeated trials */ + v128_set_to_zero(&nonce); + timer = clock(); + for(i=0; i < num_trials; i++, nonce.v32[3] = i) { + + /* choose a cipher at random from the array*/ + cipher_index = (*((uint32_t *)enc_buf)) % num_cipher; + + /* encrypt buffer with cipher */ + cipher_set_iv(cipher_array[cipher_index], &nonce); + cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_in_buffer); + } + timer = clock() - timer; + + free(enc_buf); + + if (timer == 0) { + /* Too fast! */ + return 0; + } + + return CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer; +} + +void +cipher_array_test_throughput(cipher_t *ca[], int num_cipher) { + int i; + int min_enc_len = 16; + int max_enc_len = 2048; /* should be a power of two */ + int num_trials = 10000; + + printf("timing %s throughput with array size %d:\n", + (ca[0])->type->description, num_cipher); + fflush(stdout); + for (i=min_enc_len; i <= max_enc_len; i = i * 4) + printf("msg len: %d\tgigabits per second: %f\n", i, + cipher_array_bits_per_second(ca, num_cipher, i, num_trials) / 1e9); + +} + +err_status_t +cipher_driver_test_array_throughput(cipher_type_t *ct, + int klen, int num_cipher) { + cipher_t **ca = NULL; + err_status_t status; + + status = cipher_array_alloc_init(&ca, num_cipher, ct, klen); + if (status) { + printf("error: cipher_array_alloc_init() failed with error code %d\n", + status); + return status; + } + + cipher_array_test_throughput(ca, num_cipher); + + cipher_array_delete(ca, num_cipher); + + return err_status_ok; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/test/datatypes_driver.c b/src/libs/resiprocate/contrib/srtp/crypto/test/datatypes_driver.c new file mode 100644 index 00000000..f1866524 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/test/datatypes_driver.c @@ -0,0 +1,237 @@ +/* + * datatypes_driver.c + * + * a test driver for crypto/math datatypes + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include <stdio.h> /* for printf() */ +#include <string.h> /* for strlen() */ +#include "datatypes.h" + +void +byte_order(void); + +void +test_hex_string_funcs(void); + +void +print_string(char *s); + +void +test_bswap(void); + +int +main (void) { + + /* + * this program includes various and sundry tests for fundamental + * datatypes. it's a grab-bag of throwaway code, retained only in + * case of future problems + */ + + int i, j; + v128_t x; + char *r = + "The Moving Finger writes; and, having writ,\n" + "Moves on: nor all thy Piety nor Wit\n" + "Shall lure it back to cancel half a Line,\n" + "Nor all thy Tears wash out a Word of it."; + char *s = "incomplet"; + + print_string(r); + print_string(s); + + byte_order(); + test_hex_string_funcs(); + + for (j=0; j < 128; j++) { + v128_set_to_zero(&x); + /* x.v32[0] = (1 << j); */ + v128_set_bit(&x, j); + printf("%s\n", v128_bit_string(&x)); + v128_clear_bit(&x, j); + printf("%s\n", v128_bit_string(&x)); + + } + + printf("----------------------------------------------\n"); + v128_set_to_zero(&x); + for (i=0; i < 128; i++) { + v128_set_bit(&x, i); + } + printf("%s\n", v128_bit_string(&x)); + + printf("----------------------------------------------\n"); + v128_set_to_zero(&x); + v128_set_bit(&x, 0); + for (i=0; i < 128; i++) { + printf("%s\n", v128_bit_string(&x)); + v128_right_shift(&x, 1); + } + printf("----------------------------------------------\n"); + v128_set_to_zero(&x); + v128_set_bit(&x, 127); + for (i=0; i < 128; i++) { + printf("%s\n", v128_bit_string(&x)); + v128_left_shift(&x, 1); + } + printf("----------------------------------------------\n"); + for (i=0; i < 128; i++) { + v128_set_to_zero(&x); + v128_set_bit(&x, 127); + v128_left_shift(&x, i); + printf("%s\n", v128_bit_string(&x)); + } + printf("----------------------------------------------\n"); + v128_set_to_zero(&x); + for (i=0; i < 128; i+=2) { + v128_set_bit(&x, i); + } + printf("bit_string: { %s }\n", v128_bit_string(&x)); + printf("get_bit: { "); + for (i=0; i < 128; i++) { + if (v128_get_bit(&x, i) == 1) + printf("1"); + else + printf("0"); + } + printf(" } \n"); + + test_bswap(); + + return 0; +} + + +/* byte_order() prints out byte ordering of datatypes */ + +void +byte_order(void) { + int i; + v128_t e; +#if 0 + v16_t b; + v32_t c; + v64_t d; + + for (i=0; i < sizeof(b); i++) + b.octet[i] = i; + for (i=0; i < sizeof(c); i++) + c.octet[i] = i; + for (i=0; i < sizeof(d); i++) + d.octet[i] = i; + + printf("v128_t:\t%s\n", v128_hex_string(&e)); + printf("v64_t:\t%s\n", v64_hex_string(&d)); + printf("v32_t:\t%s\n", v32_hex_string(c)); + printf("v16_t:\t%s\n", v16_hex_string(b)); + + c.value = 0x01020304; + printf("v32_t:\t%s\n", v32_hex_string(c)); + b.value = 0x0102; + printf("v16_t:\t%s\n", v16_hex_string(b)); + + printf("uint16_t ordering:\n"); + + c.value = 0x00010002; + printf("v32_t:\t%x%x\n", c.v16[0], c.v16[1]); +#endif + + printf("byte ordering of crypto/math datatypes:\n"); + for (i=0; i < sizeof(e); i++) + e.v8[i] = i; + printf("v128_t: %s\n", v128_hex_string(&e)); + +} + +void +test_hex_string_funcs(void) { + char hex1[] = "abadcafe"; + char hex2[] = "0123456789abcdefqqqqq"; + char raw[10]; + int len; + + len = hex_string_to_octet_string(raw, hex1, strlen(hex1)); + printf("computed length: %d\tstring: %s\n", len, + octet_string_hex_string(raw, len/2)); + printf("expected length: %u\tstring: %s\n", (unsigned)strlen(hex1), hex1); + + len = hex_string_to_octet_string(raw, hex2, strlen(hex2)); + printf("computed length: %d\tstring: %s\n", len, + octet_string_hex_string(raw, len/2)); + printf("expected length: %d\tstring: %s\n", 16, "0123456789abcdef"); + +} + +void +print_string(char *s) { + int i; + printf("%s\n", s); + printf("strlen(s) = %u\n", (unsigned)strlen(s)); + printf("{ "); + for (i=0; i < strlen(s); i++) { + printf("0x%x, ", s[i]); + if (((i+1) % 8) == 0) + printf("\n "); + } + printf("}\n"); +} + +void +test_bswap(void) { + uint32_t x = 0x11223344; + uint64_t y = 0x1122334455667788LL; + + printf("before: %0x\nafter: %0x\n", x, be32_to_cpu(x)); + printf("before: %0llx\nafter: %0llx\n", (unsigned long long)y, + (unsigned long long)be64_to_cpu(y)); + + y = 1234; + + printf("1234: %0llx\n", (unsigned long long)y); + printf("as octet string: %s\n", + octet_string_hex_string((uint8_t *) &y, 8)); + y = be64_to_cpu(y); + printf("bswapped octet string: %s\n", + octet_string_hex_string((uint8_t *) &y, 8)); +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/test/env.c b/src/libs/resiprocate/contrib/srtp/crypto/test/env.c new file mode 100644 index 00000000..37a6e273 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/test/env.c @@ -0,0 +1,99 @@ +/* + * env.c + * + * prints out a brief report on the build environment + * + * David McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> +#include <string.h> /* for srtcmp() */ +#include "config.h" + +int +main(void) { + int err_count = 0; + char *str; + +#ifdef WORDS_BIGENDIAN + printf("CPU set to big-endian\t\t\t(WORDS_BIGENDIAN == 1)\n"); +#else + printf("CPU set to little-endian\t\t(WORDS_BIGENDIAN == 0)\n"); +#endif + +#ifdef CPU_RISC + printf("CPU set to RISC\t\t\t\t(CPU_RISC == 1)\n"); +#elif defined(CPU_CISC) + printf("CPU set to CISC\t\t\t\t(CPU_CISC == 1)\n"); +#else + printf("CPU set to an unknown type, probably due to a configuration error\n"); + err_count++; +#endif + +#ifdef CPU_ALTIVEC + printf("CPU set to ALTIVEC\t\t\t\t(CPU_ALTIVEC == 0)\n"); +#endif + +#ifndef NO_64BIT_MATH + printf("using native 64-bit type\t\t(NO_64_BIT_MATH == 0)\n"); +#else + printf("using built-in 64-bit math\t\t(NO_64_BIT_MATH == 1)\n"); +#endif + +#ifdef ERR_REPORTING_STDOUT + printf("using stdout for error reporting\t(ERR_REPORTING_STDOUT == 1)\n"); +#endif + +#ifdef DEV_URANDOM + str = DEV_URANDOM; +#else + str = ""; +#endif + printf("using %s as a random source\t(DEV_URANDOM == %s)\n", + str, str); + if (strcmp("", str) == 0) { + err_count++; + } + + if (err_count) + printf("warning: configuration is probably in error " + "(found %d problems)\n", err_count); + + return err_count; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/test/kernel_driver.c b/src/libs/resiprocate/contrib/srtp/crypto/test/kernel_driver.c new file mode 100644 index 00000000..8ef8a5f4 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/test/kernel_driver.c @@ -0,0 +1,126 @@ +/* + * kernel_driver.c + * + * a test driver for the crypto_kernel + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include <stdio.h> /* for printf() */ +#include <unistd.h> /* for getopt() */ +#include "crypto_kernel.h" + +void +usage(char *prog_name) { + printf("usage: %s [ -v ][ -d debug_module ]*\n", prog_name); + exit(255); +} + +int +main (int argc, char *argv[]) { + extern char *optarg; + int q; + int do_validation = 0; + err_status_t status; + + if (argc == 1) + usage(argv[0]); + + /* initialize kernel - we need to do this before anything else */ + status = crypto_kernel_init(); + if (status) { + printf("error: crypto_kernel init failed\n"); + exit(1); + } + printf("crypto_kernel successfully initalized\n"); + + /* process input arguments */ + while (1) { + q = getopt(argc, argv, "vd:"); + if (q == -1) + break; + switch (q) { + case 'v': + do_validation = 1; + break; + case 'd': + status = crypto_kernel_set_debug_module(optarg, 1); + if (status) { + printf("error: set debug module (%s) failed\n", optarg); + exit(1); + } + break; + default: + usage(argv[0]); + } + } + + if (do_validation) { + printf("checking crypto_kernel status...\n"); + status = crypto_kernel_status(); + if (status) { + printf("failed\n"); + exit(1); + } + printf("crypto_kernel passed self-tests\n"); + } + + status = crypto_kernel_shutdown(); + if (status) { + printf("error: crypto_kernel shutdown failed\n"); + exit(1); + } + printf("crypto_kernel successfully shut down\n"); + + return 0; +} + +/* + * crypto_kernel_cipher_test() is a test of the cipher interface + * of the crypto_kernel + */ + +err_status_t +crypto_kernel_cipher_test(void) { + + /* not implemented yet! */ + + return err_status_ok; +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/test/rand_gen.c b/src/libs/resiprocate/contrib/srtp/crypto/test/rand_gen.c new file mode 100644 index 00000000..ccea097f --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/test/rand_gen.c @@ -0,0 +1,140 @@ +/* + * rand_gen.c + * + * a random source (random number generator) + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include <stdio.h> /* for printf() */ +#include <unistd.h> /* for getopt() */ +#include "crypto_kernel.h" + +/* + * MAX_PRINT_STRING_LEN is defined in datatypes.h, and is the length + * of the largest hexadecimal string that can be generated by the + * function octet_string_hex_string(). + */ + +#define BUF_LEN (MAX_PRINT_STRING_LEN/2) + +void +usage(char *prog_name) { + printf("usage: %s -n <num_bytes> [-l][ -d debug_module ]*\n" + " -n <num> output <num> random bytes, where <num>" + " is between zero and %d\n" + " -l list the avaliable debug modules\n" + " -d <mod> turn on debugging module <mod>\n", + prog_name, BUF_LEN); + exit(255); +} + +int +main (int argc, char *argv[]) { + extern char *optarg; + int q; + int num_octets = 0; + unsigned do_list_mods = 0; + err_status_t status; + + if (argc == 1) + usage(argv[0]); + + /* initialize kernel - we need to do this before anything else */ + status = crypto_kernel_init(); + if (status) { + printf("error: crypto_kernel init failed\n"); + exit(1); + } + + /* process input arguments */ + while (1) { + q = getopt(argc, argv, "ld:n:"); + if (q == -1) + break; + switch (q) { + case 'd': + status = crypto_kernel_set_debug_module(optarg, 1); + if (status) { + printf("error: set debug module (%s) failed\n", optarg); + exit(1); + } + break; + case 'l': + do_list_mods = 1; + break; + case 'n': + num_octets = atoi(optarg); + if (num_octets < 0 || num_octets > BUF_LEN) + usage(argv[0]); + break; + default: + usage(argv[0]); + } + } + + if (do_list_mods) { + status = crypto_kernel_list_debug_modules(); + if (status) { + printf("error: list of debug modules failed\n"); + exit(1); + } + } + + if (num_octets > 0) { + uint8_t buffer[BUF_LEN]; + + status = crypto_get_random(buffer, num_octets); + if (status) { + printf("error: failure in random source\n"); + } else { + printf("%s\n", octet_string_hex_string(buffer, num_octets)); + } + } + + status = crypto_kernel_shutdown(); + if (status) { + printf("error: crypto_kernel shutdown failed\n"); + exit(1); + } + + return 0; +} + diff --git a/src/libs/resiprocate/contrib/srtp/crypto/test/sha1_driver.c b/src/libs/resiprocate/contrib/srtp/crypto/test/sha1_driver.c new file mode 100644 index 00000000..f7cb6ca2 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/test/sha1_driver.c @@ -0,0 +1,533 @@ +/* + * sha1_driver.c + * + * a test driver for SHA-1 + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> +#include "sha1.h" + +#define SHA_PASS 0 +#define SHA_FAIL 1 + +#define MAX_HASH_DATA_LEN 1024 +#define MAX_HASH_OUT_LEN 20 + +typedef struct hash_test_case_t { + unsigned data_len; /* number of octets in data */ + unsigned hash_len; /* number of octets output by hash */ + uint8_t data[MAX_HASH_DATA_LEN]; /* message data */ + uint8_t hash[MAX_HASH_OUT_LEN]; /* expected hash output */ + struct hash_test_case_t *next_test_case; +} hash_test_case_t; + +hash_test_case_t *sha1_test_case_list; + +err_status_t +hash_test_case_add(hash_test_case_t **list_ptr, + char *hex_data, + unsigned data_len, + char *hex_hash, + unsigned hash_len) { + hash_test_case_t *list_head = *list_ptr; + hash_test_case_t *test_case; + unsigned tmp_len; + + test_case = malloc(sizeof(hash_test_case_t)); + if (test_case == NULL) + return err_status_alloc_fail; + + tmp_len = hex_string_to_octet_string((char *)test_case->data, hex_data, data_len*2); + if (tmp_len != data_len*2) + return err_status_parse_err; + + tmp_len = hex_string_to_octet_string((char *)test_case->hash, hex_hash, hash_len*2); + if (tmp_len != hash_len*2) + return err_status_parse_err; + + test_case->data_len = data_len; + test_case->hash_len = hash_len; + + /* add the new test case to the head of the list */ + test_case->next_test_case = list_head; + *list_ptr = test_case; + + return err_status_ok; +} + +err_status_t +sha1_test_case_validate(const hash_test_case_t *test_case) { + sha1_ctx_t ctx; + uint32_t hash_value[5]; + + if (test_case == NULL) + return err_status_bad_param; + + if (test_case->hash_len != 20) + return err_status_bad_param; + if (test_case->data_len > MAX_HASH_DATA_LEN) + return err_status_bad_param; + + sha1_init(&ctx); + sha1_update(&ctx, test_case->data, test_case->data_len); + sha1_final(&ctx, hash_value); + if (0 == memcmp(test_case->hash, hash_value, 20)) { +#if VERBOSE + printf("PASSED: reference value: %s\n", + octet_string_hex_string((uint8_t *)test_case->hash, 20)); + printf("PASSED: computed value: %s\n", + octet_string_hex_string((uint8_t *)hash_value, 20)); +#endif + return err_status_ok; + } + + printf("reference value: %s\n", + octet_string_hex_string((uint8_t *)test_case->hash, 20)); + printf("computed value: %s\n", + octet_string_hex_string((uint8_t *)hash_value, 20)); + + return err_status_algo_fail; + +} + +struct hex_sha1_test_case_t { + unsigned bit_len; + char hex_data[MAX_HASH_DATA_LEN*2]; + char hex_hash[40]; +}; + +err_status_t +sha1_add_test_cases() { + int i; + err_status_t err; + + /* + * these test cases are taken from the "SHA-1 Sample Vectors" + * provided by NIST at http://csrc.nist.gov/cryptval/shs.html + */ + + struct hex_sha1_test_case_t tc[] = { + { + 0, + "", + "da39a3ee5e6b4b0d3255bfef95601890afd80709" + }, + { + 8, + "a8", + "99f2aa95e36f95c2acb0eaf23998f030638f3f15" + }, + { + 16, + "3000", + "f944dcd635f9801f7ac90a407fbc479964dec024" + }, + { + 24, + "42749e", + "a444319e9b6cc1e8464c511ec0969c37d6bb2619" + }, + { + 32, + "9fc3fe08", + "16a0ff84fcc156fd5d3ca3a744f20a232d172253" + }, + { + 40, + "b5c1c6f1af", + "fec9deebfcdedaf66dda525e1be43597a73a1f93" + }, + { + 48, + "e47571e5022e", + "8ce051181f0ed5e9d0c498f6bc4caf448d20deb5" + }, + { + 56, + "3e1b28839fb758", + "67da53837d89e03bf652ef09c369a3415937cfd3" + }, + { + 64, + "a81350cbb224cb90", + "305e4ff9888ad855a78573cddf4c5640cce7e946" + }, + { + 72, "c243d167923dec3ce1", + "5902b77b3265f023f9bbc396ba1a93fa3509bde7" + }, + { + 80, + "50ac18c59d6a37a29bf4", + "fcade5f5d156bf6f9af97bdfa9c19bccfb4ff6ab" + }, + { + 88, + "98e2b611ad3b1cccf634f6", + "1d20fbe00533c10e3cbd6b27088a5de0c632c4b5" + }, + { + 96, + "73fe9afb68e1e8712e5d4eec", + "7e1b7e0f7a8f3455a9c03e9580fd63ae205a2d93" + }, + { + 104, + "9e701ed7d412a9226a2a130e66", + "706f0677146307b20bb0e8d6311e329966884d13" + }, + { + 112, + "6d3ee90413b0a7cbf69e5e6144ca", + "a7241a703aaf0d53fe142f86bf2e849251fa8dff" + }, + { + 120, + "fae24d56514efcb530fd4802f5e71f", + "400f53546916d33ad01a5e6df66822dfbdc4e9e6" + }, + { + 128, + "c5a22dd6eda3fe2bdc4ddb3ce6b35fd1", + "fac8ab93c1ae6c16f0311872b984f729dc928ccd" + }, + { + 136, + "d98cded2adabf08fda356445c781802d95", + "fba6d750c18da58f6e2aab10112b9a5ef3301b3b" + }, + { + 144, + "bcc6d7087a84f00103ccb32e5f5487a751a2", + "29d27c2d44c205c8107f0351b05753ac708226b6" + }, + { + 152, + "36ecacb1055434190dbbc556c48bafcb0feb0d", + "b971bfc1ebd6f359e8d74cb7ecfe7f898d0ba845" + }, + { + 160, + "5ff9edb69e8f6bbd498eb4537580b7fba7ad31d0", + "96d08c430094b9fcc164ad2fb6f72d0a24268f68" + }, + { + 168, "c95b441d8270822a46a798fae5defcf7b26abace36", + "a287ea752a593d5209e287881a09c49fa3f0beb1" + }, + { + 176, + "83104c1d8a55b28f906f1b72cb53f68cbb097b44f860", + "a06c713779cbd88519ed4a585ac0cb8a5e9d612b" + }, + { + 184, + "755175528d55c39c56493d697b790f099a5ce741f7754b", + "bff7d52c13a3688132a1d407b1ab40f5b5ace298" + }, + { + 192, + "088fc38128bbdb9fd7d65228b3184b3faac6c8715f07272f", + "c7566b91d7b6f56bdfcaa9781a7b6841aacb17e9" + }, + { + 200, + "a4a586eb9245a6c87e3adf1009ac8a49f46c07e14185016895", + "ffa30c0b5c550ea4b1e34f8a60ec9295a1e06ac1" + }, + { + 208, + "8e7c555270c006092c2a3189e2a526b873e2e269f0fb28245256", + "29e66ed23e914351e872aa761df6e4f1a07f4b81" + }, + { + 216, + "a5f3bfa6bb0ba3b59f6b9cbdef8a558ec565e8aa3121f405e7f2f0", + "b28cf5e5b806a01491d41f69bd9248765c5dc292" + }, + { + 224, + "589054f0d2bd3c2c85b466bfd8ce18e6ec3e0b87d944cd093ba36469", + "60224fb72c46069652cd78bcd08029ef64da62f3" + }, + { + 232, + "a0abb12083b5bbc78128601bf1cbdbc0fdf4b862b24d899953d8da0ff3", + "b72c4a86f72608f24c05f3b9088ef92fba431df7" + }, + { + 240, + "82143f4cea6fadbf998e128a8811dc75301cf1db4f079501ea568da68eeb", + "73779ad5d6b71b9b8328ef7220ff12eb167076ac" + }, + { + 248, + "9f1231dd6df1ff7bc0b0d4f989d048672683ce35d956d2f57913046267e6f3", + "a09671d4452d7cf50015c914a1e31973d20cc1a0" + }, + { + 256, + "041c512b5eed791f80d3282f3a28df263bb1df95e1239a7650e5670fc2187919", + "e88cdcd233d99184a6fd260b8fca1b7f7687aee0" + }, + { + 264, + "17e81f6ae8c2e5579d69dafa6e070e7111461552d314b691e7a3e7a4feb3fae418", + "010def22850deb1168d525e8c84c28116cb8a269" + }, + { + 272, + "d15976b23a1d712ad28fad04d805f572026b54dd64961fda94d5355a0cc98620cf77", + "aeaa40ba1717ed5439b1e6ea901b294ba500f9ad" + }, + { + 280, + "09fce4d434f6bd32a44e04b848ff50ec9f642a8a85b37a264dc73f130f22838443328f", + "c6433791238795e34f080a5f1f1723f065463ca0" + }, + { + 288, "f17af27d776ec82a257d8d46d2b46b639462c56984cc1be9c1222eadb8b26594a25c709d", + "e21e22b89c1bb944a32932e6b2a2f20d491982c3" + }, + { + 296, + "b13ce635d6f8758143ffb114f2f601cb20b6276951416a2f94fbf4ad081779d79f4f195b22", + "575323a9661f5d28387964d2ba6ab92c17d05a8a" + }, + { + 304, + "5498793f60916ff1c918dde572cdea76da8629ba4ead6d065de3dfb48de94d234cc1c5002910", + "feb44494af72f245bfe68e86c4d7986d57c11db7" + }, + { + 312, + "498a1e0b39fa49582ae688cd715c86fbaf8a81b8b11b4d1594c49c902d197c8ba8a621fd6e3be5", + "cff2290b3648ba2831b98dde436a72f9ebf51eee" + }, + { + 320, + "3a36ae71521f9af628b3e34dcb0d4513f84c78ee49f10416a98857150b8b15cb5c83afb4b570376e", + "9b4efe9d27b965905b0c3dab67b8d7c9ebacd56c" + }, + { + 328, + "dcc76b40ae0ea3ba253e92ac50fcde791662c5b6c948538cffc2d95e9de99cac34dfca38910db2678f", + "afedb0ff156205bcd831cbdbda43db8b0588c113" + }, + { + 336, + "5b5ec6ec4fd3ad9c4906f65c747fd4233c11a1736b6b228b92e90cddabb0c7c2fcf9716d3fad261dff33", + "8deb1e858f88293a5e5e4d521a34b2a4efa70fc4" + }, + { + 344, + "df48a37b29b1d6de4e94717d60cdb4293fcf170bba388bddf7a9035a15d433f20fd697c3e4c8b8c5f590ab", + "95cbdac0f74afa69cebd0e5c7defbc6faf0cbeaf" + }, + { + 352, + "1f179b3b82250a65e1b0aee949e218e2f45c7a8dbfd6ba08de05c55acfc226b48c68d7f7057e5675cd96fcfc", + "f0307bcb92842e5ae0cd4f4f14f3df7f877fbef2" + }, + { + 360, + "ee3d72da3a44d971578972a8e6780ce64941267e0f7d0179b214fa97855e1790e888e09fbe3a70412176cb3b54", + "7b13bb0dbf14964bd63b133ac85e22100542ef55" + }, + { + 368, + "d4d4c7843d312b30f610b3682254c8be96d5f6684503f8fbfbcd15774fc1b084d3741afb8d24aaa8ab9c104f7258", + "c314d2b6cf439be678d2a74e890d96cfac1c02ed" + }, + { + 376, + "32c094944f5936a190a0877fb9178a7bf60ceae36fd530671c5b38c5dbd5e6a6c0d615c2ac8ad04b213cc589541cf6", + "4d0be361e410b47a9d67d8ce0bb6a8e01c53c078" + }, + { + 384, + "e5d3180c14bf27a5409fa12b104a8fd7e9639609bfde6ee82bbf9648be2546d29688a65e2e3f3da47a45ac14343c9c02", + "e5353431ffae097f675cbf498869f6fbb6e1c9f2" + }, + { + 392, + "e7b6e4b69f724327e41e1188a37f4fe38b1dba19cbf5a7311d6e32f1038e97ab506ee05aebebc1eed09fc0e357109818b9", + "b8720a7068a085c018ab18961de2765aa6cd9ac4" + }, + { + 400, + "bc880cb83b8ac68ef2fedc2da95e7677ce2aa18b0e2d8b322701f67af7d5e7a0d96e9e33326ccb7747cfff0852b961bfd475", + "b0732181568543ba85f2b6da602b4b065d9931aa" + }, + { + 408, + "235ea9c2ba7af25400f2e98a47a291b0bccdaad63faa2475721fda5510cc7dad814bce8dabb611790a6abe56030b798b75c944", + "9c22674cf3222c3ba921672694aafee4ce67b96b" + }, + { + 416, + "07e3e29fed63104b8410f323b975fd9fba53f636af8c4e68a53fb202ca35dd9ee07cb169ec5186292e44c27e5696a967f5e67709", + "d128335f4cecca9066cdae08958ce656ff0b4cfc" + }, + { + 424, + "65d2a1dd60a517eb27bfbf530cf6a5458f9d5f4730058bd9814379547f34241822bf67e6335a6d8b5ed06abf8841884c636a25733f", + "0b67c57ac578de88a2ae055caeaec8bb9b0085a0" + }, + { + 432, + "dcc86b3bd461615bab739d8daafac231c0f462e819ad29f9f14058f3ab5b75941d4241ea2f17ebb8a458831b37a9b16dead4a76a9b0e", + "c766f912a89d4ccda88e0cce6a713ef5f178b596" + }, + { + 440, + "4627d54f0568dc126b62a8c35fb46a9ac5024400f2995e51635636e1afc4373dbb848eb32df23914230560b82477e9c3572647a7f2bb92", + "9aa3925a9dcb177b15ccff9b78e70cf344858779" + }, + { + 448, + "ba531affd4381168ef24d8b275a84d9254c7f5cc55fded53aa8024b2c5c5c8aa7146fe1d1b83d62b70467e9a2e2cb67b3361830adbab28d7", + "4811fa30042fc076acf37c8e2274d025307e5943" + }, + { + 456, + "8764dcbcf89dcf4282eb644e3d568bdccb4b13508bfa7bfe0ffc05efd1390be22109969262992d377691eb4f77f3d59ea8466a74abf57b2ef4", + "6743018450c9730761ee2b130df9b91c1e118150" + }, + { + 464, + "497d9df9ddb554f3d17870b1a31986c1be277bc44feff713544217a9f579623d18b5ffae306c25a45521d2759a72c0459b58957255ab592f3be4", + "71ad4a19d37d92a5e6ef3694ddbeb5aa61ada645" + }, + { + 472, + "72c3c2e065aefa8d9f7a65229e818176eef05da83f835107ba90ec2e95472e73e538f783b416c04654ba8909f26a12db6e5c4e376b7615e4a25819", + "a7d9dc68dacefb7d6116186048cb355cc548e11d" + }, + { + 480, + "7cc9894454d0055ab5069a33984e2f712bef7e3124960d33559f5f3b81906bb66fe64da13c153ca7f5cabc89667314c32c01036d12ecaf5f9a78de98", + "142e429f0522ba5abf5131fa81df82d355b96909" + }, + { + 488, + "74e8404d5a453c5f4d306f2cfa338ca65501c840ddab3fb82117933483afd6913c56aaf8a0a0a6b2a342fc3d9dc7599f4a850dfa15d06c61966d74ea59", + "ef72db70dcbcab991e9637976c6faf00d22caae9" + }, + { + 496, + "46fe5ed326c8fe376fcc92dc9e2714e2240d3253b105adfbb256ff7a19bc40975c604ad7c0071c4fd78a7cb64786e1bece548fa4833c04065fe593f6fb10", + "f220a7457f4588d639dc21407c942e9843f8e26b" + }, + { + 504, + "836dfa2524d621cf07c3d2908835de859e549d35030433c796b81272fd8bc0348e8ddbc7705a5ad1fdf2155b6bc48884ac0cd376925f069a37849c089c8645", + "ddd2117b6e309c233ede85f962a0c2fc215e5c69" + }, + { + 512, + "7e3a4c325cb9c52b88387f93d01ae86d42098f5efa7f9457388b5e74b6d28b2438d42d8b64703324d4aa25ab6aad153ae30cd2b2af4d5e5c00a8a2d0220c6116", + "a3054427cdb13f164a610b348702724c808a0dcc" + } + }; + + + for (i=0; i < 65; i++) { + err = hash_test_case_add(&sha1_test_case_list, + tc[i].hex_data, + tc[i].bit_len/8, + tc[i].hex_hash, 20); + if (err) { + printf("error adding hash test case (code %d)\n", err); + return err; + } + } + + return err_status_ok; +} + + +err_status_t +sha1_validate(void) { + hash_test_case_t *test_case; + err_status_t err; + + err = sha1_add_test_cases(); + if (err) { + printf("error adding SHA1 test cases (error code %d)\n", err); + return err; + } + + if (sha1_test_case_list == NULL) + return err_status_cant_check; + + test_case = sha1_test_case_list; + while (test_case != NULL) { + err = sha1_test_case_validate(test_case); + if (err) { + printf("error validating hash test case (error code %d)\n", err); + return err; + } + test_case = test_case->next_test_case; + } + + return err_status_ok; +} + + + +int +main (void) { + err_status_t err; + + printf("sha1 test driver\n"); + + err = sha1_validate(); + if (err) { + printf("SHA1 did not pass validation testing\n"); + return 1; + } + printf("SHA1 passed validation tests\n"); + + return 0; + +} diff --git a/src/libs/resiprocate/contrib/srtp/crypto/test/stat_driver.c b/src/libs/resiprocate/contrib/srtp/crypto/test/stat_driver.c new file mode 100644 index 00000000..09cc44a6 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/crypto/test/stat_driver.c @@ -0,0 +1,101 @@ +/* + * stat-driver.c + * + * test driver for the stat_test functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ + + +#include <stdio.h> /* for printf() */ + +#include "err.h" +#include "stat.h" + +#include "cipher.h" + +typedef struct { + void *state; +} random_source_t; + +err_status_t +random_source_alloc(void); + +void +err_check(err_status_t s) { + if (s) { + printf("error (code %d)\n", s); + exit(1); + } +} + +int +main (int argc, char *argv[]) { + uint8_t buffer[2500]; + unsigned int buf_len = 2500; + int i, j; + extern cipher_type_t aes_icm; + cipher_t *c; + uint8_t key[30] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 + }; + v128_t nonce; + int num_trials = 500; + int num_fail; + + printf("statistical tests driver\n"); + + for (i=0; i < 2500; i++) + buffer[i] = 0; + + /* run tests */ + printf("running stat_tests on all-null buffer, expecting failure\n"); + printf("monobit %d\n", stat_test_monobit(buffer)); + printf("poker %d\n", stat_test_poker(buffer)); + printf("runs %d\n", stat_test_runs(buffer)); + + for (i=0; i < 2500; i++) + buffer[i] = rand(); + printf("running stat_tests on rand(), expecting success\n"); + printf("monobit %d\n", stat_test_monobit(buffer)); + printf("poker %d\n", stat_test_poker(buffer)); + printf("runs %d\n", stat_test_runs(buffer)); + + printf("running stat_tests on AES-128-ICM, expecting success\n"); + /* set buffer to cipher output */ + for (i=0; i < 2500; i++) + buffer[i] = 0; + err_check(cipher_type_alloc(&aes_icm, &c, 30)); + err_check(cipher_init(c, key, direction_encrypt)); + err_check(cipher_set_iv(c, &nonce)); + err_check(cipher_encrypt(c, buffer, &buf_len)); + /* run tests on cipher outout */ + printf("monobit %d\n", stat_test_monobit(buffer)); + printf("poker %d\n", stat_test_poker(buffer)); + printf("runs %d\n", stat_test_runs(buffer)); + + printf("runs test (please be patient): "); + fflush(stdout); + num_fail = 0; + v128_set_to_zero(&nonce); + for(j=0; j < num_trials; j++) { + for (i=0; i < 2500; i++) + buffer[i] = 0; + nonce.v32[3] = i; + err_check(cipher_set_iv(c, &nonce)); + err_check(cipher_encrypt(c, buffer, &buf_len)); + if (stat_test_runs(buffer)) { + num_fail++; + } + } + + printf("%d failures in %d tests\n", num_fail, num_trials); + printf("(nota bene: a small fraction of stat_test failures does not \n" + "indicate that the random source is invalid)\n"); + + return 0; +} diff --git a/src/libs/resiprocate/contrib/srtp/doc/.cvsignore b/src/libs/resiprocate/contrib/srtp/doc/.cvsignore new file mode 100644 index 00000000..55a080ae --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/doc/.cvsignore @@ -0,0 +1,3 @@ +Makefile +header.tex +latex diff --git a/src/libs/resiprocate/contrib/srtp/doc/Doxyfile b/src/libs/resiprocate/contrib/srtp/doc/Doxyfile new file mode 100644 index 00000000..c6e6a6d2 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/doc/Doxyfile @@ -0,0 +1,1042 @@ +# Doxyfile 1.3-rc3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = libSRTP + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.3.22 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = NO + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show +# all inherited members of a class in the documentation of that class +# as if those members were ordinary class members. Constructors, +# destructors and assignment operators of the base classes will not be +# shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are adviced to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 3 + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consist of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = intro.txt ../include/srtp.h ../crypto/include/crypto_types.h ../crypto/include/err.h ../crypto/include/crypto.h crypto_kernel.txt + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = NO + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output dir. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non empty doxygen will try to run +# the html help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the Html help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = letter + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = header.tex + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_XML = NO + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superceded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yield more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermedate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = /usr/local/bin/ + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/src/libs/resiprocate/contrib/srtp/doc/Makefile.in b/src/libs/resiprocate/contrib/srtp/doc/Makefile.in new file mode 100644 index 00000000..30633bd9 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/doc/Makefile.in @@ -0,0 +1,47 @@ +# Makefile for libSRTP documentation +# +# David A. McGrew +# Cisco Systems, Inc. +# +# This makefile does not use the autoconf system; we don't really need +# it. We just run doxygen then latex. If you don't have either of +# these, then there is no way that you can make your own +# documentation. Of course, you can just go online at pick up the +# documentation from http://srtp.sourceforge.net. + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ +VPATH = @srcdir@ + +# Determine the version of the library + +version = $(shell cat $(top_srcdir)/VERSION) + + +.PHONY: libsrtpdoc cryptodoc clean +libsrtpdoc: + @if test ! -e Doxyfile; then \ + echo "*** Sorry, can't build doc outside source dir"; exit 1; \ + fi + sed 's/LIBSRTPVERSION/$(version)/' header.template > header.tex + doxygen + sed 's/\subsection/\section/' latex/index.tex > latex/index.tmp + mv latex/index.tmp latex/index.tex + cd latex; make + cp latex/refman.pdf libsrtp.pdf + + +cryptodoc: clean + doxygen crypto.dox + cd latex; make + cp latex/refman.pdf crypto.pdf + +clean: + rm -rf latex/ header.tex + for a in * ; do \ + if [ -f "$$a~" ] ; then rm -f $$a~; fi; \ + done; + +superclean: + -rm -f Makefile diff --git a/src/libs/resiprocate/contrib/srtp/doc/crypto_kernel.txt b/src/libs/resiprocate/contrib/srtp/doc/crypto_kernel.txt new file mode 100644 index 00000000..b0d033ff --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/doc/crypto_kernel.txt @@ -0,0 +1,76 @@ +/** + +@defgroup CryptoKernel Cryptographic Kernel + +All of the cryptographic functions are contained in a kernel. + +*/ + +/** + +@defgroup CipherImplementations Ciphers +@ingroup CryptoKernel + +@brief A generic cipher type enables cipher agility, that is, the +ability to write code that runs with multiple cipher types. +Ciphers can be used through the crypto kernel, or can be accessed +directly, if need be. + +@{ + +*/ + +/** + * @brief Allocates a cipher of a particular type. + * @warning May be implemented as a macro. + */ +err_status_t +cipher_type_alloc(cipher_type_t *ctype, cipher_t **cipher, + unsigned key_len); + +/** + * @brief Initialized a cipher to use a particular key. May + * be invoked more than once on the same cipher. + * @warning May be implemented as a macro. + */ + +err_status_t +cipher_init(cipher_t *cipher, const uint8_t *key); + +/** + * @brief Sets the initialization vector of a given cipher. + * @warning May be implemented as a macro. + */ + +err_status_t +cipher_set_iv(cipher_t *cipher, void *iv); + +/** + * @brief Encrypts a buffer with a given cipher. + * @warning May be implemented as a macro. + */ + +err_status_t +cipher_encrypt(cipher_t *cipher, void *buf, unsigned int *len); + +/** + * @brief Sets a buffer to the keystream generated by the cipher. + * @warning May be implemented as a macro. + */ +err_status_t +cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output); + +/** + * @brief Deallocates a cipher. + * @warning May be implemented as a macro. + */ +err_status_t +cipher_dealloc(cipher_t *cipher); + + + +/** + * @} + */ + + */ \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/srtp/doc/draft-irtf-cfrg-icm-00.txt b/src/libs/resiprocate/contrib/srtp/doc/draft-irtf-cfrg-icm-00.txt new file mode 100644 index 00000000..ddfce338 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/doc/draft-irtf-cfrg-icm-00.txt @@ -0,0 +1 @@ + Crypto Forum Research Group David A. McGrew Internet Draft Cisco Systems, Inc. Expires April, 2003 October, 2002 Integer Counter Mode <draft-irtf-cfrg-icm-00.txt> Status of this Memo This document is an Internet Draft and is in full conformance with all provisions of Section 10 of RFC-2026. Internet Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and working groups. Note that other groups may also distribute working documents as Internet Drafts. Internet Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet Drafts as reference material or to cite them other than as "work in progress." The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html. 1. Abstract This document specifies Integer Counter Mode (ICM), a mode of operation of a block cipher which defines an indexed keystream generator (which generates a keystream segment given an index). This mode is efficient, parallelizable, and has been proven secure given realistic assumptions about the block cipher. Test vectors are provided for AES. Counter Mode admits many variations. The variant specified in this document is secure and flexible, yet it enables a single implementation of a keystream generator to suffice in different application domains. McGrew [Page 1] Internet Draft Integer Counter Mode October, 2002 2. Notational Conventions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC-2119 [B97]. 3. Introduction Counter Mode is a way to define a pseudorandom keystream generator using a block cipher [CTR]. The keystream can be used for additive encryption, key derivation, or any other application requiring pseudorandom data. In ICM, the keystream is logically broken into segments. Each segment is identified with a segment index, and the segments have equal lengths. This segmentation makes ICM especially appropriate for securing packet-based protocols. 4. ICM In this section, ICM keystream generation and encryption are defined. 4.1. ICM Parameters The following parameters are used in ICM. These parameters MUST remain fixed for any given use of a key. Parameter Meaning ----------------------------------------------------------------- BLOCK_LENGTH the number of octets in the cipher block KEY_LENGTH the number of octets in the cipher key OFFSET_LENGTH the number of octets in the offset SEGMENT_INDEX_LENGTH the number of octets in the segment index BLOCK_INDEX_LENGTH the number of octets in the block index 4.2. Keystream Segments Conceptually, ICM is a keystream generator that takes a secret key and a segment index as an input and then outputs a keystream segment. The segmentation lends itself to packet encryption, as each keystream segment can be used to encrypt a distinct packet. A counter is a value containing BLOCK_LENGTH octets which is McGrew [Page 2] Internet Draft Integer Counter Mode October, 2002 incremented using an increment function based on integer addition, to produce a sequence of distinct values which are used as inputs to the block cipher. (In the context of this specification, an integer is an octet string, the most significant of which is the first.) The output blocks of the cipher are concatenated to form the keystream segment. The first octet of the segment is the first octet of the first output block, and so on. A schematic of this process is shown in Figure 1. Figure 1. The generation of a keystream segment given a segment index and a block cipher key K. Here C[i] and S[i] denote the ith counter and keystream block, respectively. segment index | v C[0] -----> C[1] -----> C[2] -----> ... | | | v v v +---+ +---+ +---+ K->| E | K->| E | K->| E | ... +---+ +---+ +---+ | | | v v v S[0] S[1] S[2] ... The ith counter C[i] of the keystream segment with segment index s is defined as C[i] = (i + s * (256^BLOCK_INDEX_LENGTH)) (+) r where r denotes the shifted Offset, which is defined as the Offset times 256^(BLOCK_LENGTH - OFFSET_LENGTH). (This multiplication left-shifts the Offset so that it is aligned with the leftmost edge of the block.) Here ^ denotes exponentiation and (+) denotes the bitwise exclusive-or operation. The number of blocks in any segment MUST NOT exceed 256^BLOCK_INDEX_LENGTH. The number of segments MUST NOT exceed 256^SEGMENT_INDEX_LENGTH. These restrictions ensure the uniqueness of each block cipher input. They also imply that each segment contains no more than (256^BLOCK_INDEX_LENGTH)*BLOCK_LENGTH octets. The sum of SEGMENT_INDEX_LENGTH and BLOCK_INDEX_LENGTH MUST NOT exceed BLOCK_LENGTH / 2. This requirement protects the ICM keystream generator from potentially failing to be pseudorandom (see McGrew [Page 3] Internet Draft Integer Counter Mode October, 2002 the rationale). Figure 2. An illustration of the structure of a counter with BLOCK_LENGTH = 8, SEGMENT_INDEX_LENGTH = 2, and BLOCK_INDEX_LENGTH = 2. The field marked `null' is not part of either the block or segment indices. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | null | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | segment index | block index | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4.3. ICM Encryption Unless otherwise specified, ICM encryption consists of bitwise exclusive-oring the keystream into the plaintext to produce the ciphertext. 4.4 ICM KEY An ICM key consists of the block cipher key and an Offset. The Offset is an integer with OFFSET_LENGTH octets, which is used to `randomize' the logical starting point of keystream. The Offset is crucial to providing security; see the rationale. The value of OFFSET_LENGTH SHOULD be at least half that of BLOCK_LENGTH. For the purposes of transporting an ICM key, e.g. in a signaling protocol, that key SHOULD be considered a sequence of octets in which the block cipher key precedes the Offset. 5. Implementation Considerations Implementation of the `add one modulo 2^m' operation is simple. For example, with BLOCK_LENGTH = 8 (m=64), it can be implemented in C as if (!++x) ++y; where x and y are 32-bit unsigned integers in network byte order. The implementation of general purpose addition modulo 2^m is slightly more complicated. The fact that the Offset is left-aligned enables an implementation McGrew [Page 4] Internet Draft Integer Counter Mode October, 2002 to avoid propagating carry values outside of the block index and/or the segment index. Choosing an OFFSET_LENGTH value equal to half that of BLOCK_LENGTH avoids all of these carries, since the Offset is then shifted so that it occupies the most significant octets of the block, while the block and segment indices occupy the least significant ones. 6. Parameters and Test Vectors for AES This section provides ICM parameters and test vectors for AES with a 128 bit block size and 128 bit key (that is, with a BLOCK_LENGTH and KEY_LENGTH of 16). All integers are expressed in hexadecimal. Each consecutive pair of hex digits corresponds to an octet, so that the integer 000102030405060708090A0B0C0D0E0F corresponds to the octet sequence { 00, 01, 02, 02 ... }. BLOCK_LENGTH 16 KEY_LENGTH 16 OFFSET_LENGTH 14 SEGMENT_INDEX_LENGTH 6 BLOCK_INDEX_LENGTH 2 Block Cipher Key: 2b7e151628aed2a6abf7158809cf4f3c Offset: f0f1f2f3f4f5f6f7f8f9fafbfcfd Segment Index: 000000000000 Keystream: e03ead0935c95e80e166b16dd92b4eb4 d23513162b02d0f72a43a2fe4a5f97ab ... The counter values that correspond to the keystream blocks are outlined below. Counter Keystream f0f1f2f3f4f5f6f7f8f9fafbfcfd0000 e03ead0935c95e80e166b16dd92b4eb4 f0f1f2f3f4f5f6f7f8f9fafbfcfd0001 d23513162b02d0f72a43a2fe4a5f97ab f0f1f2f3f4f5f6f7f8f9fafbfcfd0002 41e95b3bb0a2e8dd477901e4fca894c0 ... ... 7. Security Considerations Each block cipher input is distinct for any segment and any block index. To see this fact, subtract any two counter values with distinct segment or block indices; the result is non-zero. McGrew [Page 5] Internet Draft Integer Counter Mode October, 2002 The limitation on the number of segments which can be generated ensures that the probability with which an adversary can distinguish the keystream generator from random is negligible. For a theoretical justification of this fact, see Bellare et. al. [BR98]. Their analysis shows that if the block cipher cannot be distinguished from a random permutation, then the keystream generated by ICM cannot be distinguished from keystream generated by a truly random process, as long as the length of keystream which is generated is kept below some threshold. The threshold defined in Section 4.2 is sufficient for most uses of ICM for encryption. This specification refrains from dictating a lower threshold in order to refrain from dictating a particular policy, and to avoid a complicated digression. The use of the Offset, a key-dependent value which randomizes the starting position of the keystream, is essential for security. The omission of this mechanism leaves the door open for practical attacks, such as the key collision attack and Hellman's time-memory tradeoff attack; see McGrew and Fluhrer [MF00] for a description of these attacks which is applicable to ICM. Several counter mode proposals do not include an offset, and are thus vulnerable to these attacks. 8. Rationale This speficiation includes input from implementation experience with several counter mode variants. The goals of ICM are to provide: o a secure keystream generator and cipher, and o a definition flexible enough that a single implementation can be used for a variety of applications (e.g., Secure RTP [SRTP], IPsec ESP [KA96]). The Offset slightly increases the key management overhead, but this minor disadvantage is well outweighed by other savings. The Offset is no larger than a CBC mode IV, and ICM enables the use of an explicit IV (as is commonly used with CBC [MD98]) to be avoided. 9. History This draft is based on draft-mcgrew-saag-icm-00.txt, which was submitted to SAAG on November, 2001 and which expired in May, 2002. The current definition of ICM has changed from the earlier one; the counter formation is different and the specifications are McGrew [Page 6] Internet Draft Integer Counter Mode October, 2002 unfortunately not interoperable. This change was motivated by a considerable amount of feedback on the desirability of admitting optimizations of the sort described in Section 5, in which the carry operations of counter addition need not be propagated across a large register. The current definition of ICM is interoperable with that defined in Secure RTP [SRTP]. 10. Acknowledgements Thanks are due to Helger Lipmaa, Jerome Etienne, Scott Fluhrer and Mats Naslund for their helpful discussion and comments. 11. Contact Information Questions and comments on this draft SHOULD be sent to: David A. McGrew Cisco Systems, Inc. mcgrew@cisco.com and copied to the Crypto Forum Research Group at: cfrg@ietf.org. 12. References [BR98] M. Bellare, A. Desai, E. Lokipii and P. Rogaway, A Concrete Security Treatment of Symmetric Encryption: Analysis of DES Modes of Operation, Proceedings of the 38th Symposium on Foundations of Computer Science, IEEE, 1997. [B97] S. Bradner, Key words for use in RFCs to Indicate Requirement Levels, RFC 2119, March 1997. [AES] The Advanced Encryption Standard, United States National Institute for Standards and Technology (NIST), http://www.nist.gov/aes/. [CTR] M. Dworkin, NIST Special Publication 800-38A, "Recommendation for Block Cipher Modes of Operation: Methods and Techniques", 2001. Online at McGrew [Page 7] Internet Draft Integer Counter Mode October, 2002 http://csrc.nist.gov/publications/nistpubs/800-38a/sp800- 38a.pdf. [MD98] Madson, C., and Doraswamy, N., "The ESP DES-CBC Cipher Algorithm With Explicit IV", RFC 2405, November 1998. [MF00] D. McGrew and S. Fluhrer, Attacks on Additive Encryption and Implications on Internet Security, Selected Areas in Cryptography 2000. [SRTP] The Secure Real-time Transport Protocol, Baugher et. al., Internet Draft, draft-ietf-avt-srtp-05.txt. McGrew [Page 8] \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/srtp/doc/header.template b/src/libs/resiprocate/contrib/srtp/doc/header.template new file mode 100644 index 00000000..2c0b96d4 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/doc/header.template @@ -0,0 +1,115 @@ +% header.tex +% +% header file for the libSRTP documentation - based on the header +% file generated by doxygen, with the initial chapters of the +% original libSRTP documentation tacked on +% +\documentclass[letterpaper]{book} +\usepackage{makeidx} +\usepackage{fancyhdr} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{times} +\usepackage{graphicx} +\ifx\pdfoutput\undefined +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue + ]{hyperref} +\else +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue + ]{hyperref} +\fi +\usepackage{doxygen} +\makeindex +\setcounter{tocdepth}{1} +\renewcommand{\footrulewidth}{0.4pt} + +% these lengths are from DAM +\textwidth = 6.5 in +%\textheight = 9 in +\oddsidemargin = 0.0 in +\evensidemargin = 0.0 in +\topmargin = 0.0 in +\headheight = 0.0 in +%\headsep = 0.0 in +\parskip = 0.2in +\parindent = 0.0in + +% these header and footer definitions from DAM +\lhead{libSRTP} +\chead{} +\rhead{\rightmark} +%\rhead{\slshape } +\lfoot{} +\cfoot{ \thepage } +\rfoot{} +%\fancyhead[LE,RO]{\rightmark } +%\fancyhead[LO,RE]{\slshape } + +% let's use the palatino font +\fontfamily{ppl} +\selectfont + + +\begin{document} +\begin{titlepage} +\vspace*{4cm} +%\begin{center} +{\Huge +libSRTP LIBSRTPVERSION Overview and Reference Manual\\ + \hrulefill +}\\ +\vspace*{0cm} +\begin{flushright} +{\Large David A. McGrew \\ \texttt{mcgrew@cisco.com} }\\ +\vspace*{0.5cm} +\end{flushright} +%\end{center} + +%\includegraphics[scale=.8]{phone} + +\end{titlepage} + + +\clearemptydoublepage +\vspace*{3cm} +{\LARGE Preface} +\vspace{1cm} + +The original implementation and documentation of libSRTP was written +by David McGrew of Cisco Systems, Inc. in order to promote the use, +understanding, and interoperability of Secure RTP. Michael Jerris +contributed support for building under MSVC. Andris Pavenis +contributed many important fixes. Brian West contributed changes to +enable dynamic linking. Yves Shumann reported documentation bugs. +Randell Jesup contributed a working SRTCP implementation and other +fixes. Alex Vanzella and Will Clark contributed changes so that the +AES ICM implementation can be used for ISMA media encryption. Steve +Underwood contributed x86\_64 portability changes. We also give +thanks to Fredrik Thulin, Brian Weis, Mark Baugher, Jeff Chan, Bill +Simon, Douglas Smith, Bill May, Richard Preistley, Joe Tardo and +others for contributions, comments, and corrections. + +This reference material in this documenation was generated using the +\texttt{doxygen} utility for automatic documentation of source code. + +\copyright 2001-2005 by David A. McGrew, Cisco Systems, Inc. +\thispagestyle{empty} + +\clearemptydoublepage +\pagenumbering{roman} +\tableofcontents +%\clearemptydoublepage + +\clearemptydoublepage +\pagenumbering{arabic} + + diff --git a/src/libs/resiprocate/contrib/srtp/doc/intro.txt b/src/libs/resiprocate/contrib/srtp/doc/intro.txt new file mode 100644 index 00000000..f3155992 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/doc/intro.txt @@ -0,0 +1,395 @@ +/** + +@mainpage Introduction to libSRTP + +This document describes libSRTP, the Open Source Secure RTP library +from Cisco Systems, Inc. RTP is the Real-time Transport Protocol, an +IETF standard for the transport of real-time data such as telephony, +audio, and video, defined by RFC1889. Secure RTP (SRTP) is an RTP +profile for providing confidentiality to RTP data and authentication +to the RTP header and payload. SRTP is an IETF Proposed Standard, and +is defined in RFC 3711, and was developed in the IETF Audio/Video +Transport (AVT) Working Group. This library supports all of the +mandatory features of SRTP, but not all of the optional features. See +the @ref Features section for more detailed information. + +This document is organized as follows. The first chapter provides +background material on SRTP and overview of libSRTP. The following +chapters provide a detailed reference to the libSRTP API and related +functions. The reference material is created automatically (using the +doxygen utility) from comments embedded in some of the C header +files. The documentation is organized into modules in order to improve +its clarity. These modules do not directly correspond to files. An +underlying cryptographic kernel provides much of the basic +functionality of libSRTP, but is mostly undocumented because it does +its work behind the scenes. + +@section LICENSE License and Disclaimer + +libSRTP is distributed under the following license, which is included +in the source code distribution. It is reproduced in the manual in +case you got the library from another source. + +@latexonly +\begin{quote} +Copyright (c) 2001-2005 Cisco Systems, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +\begin{itemize} +\item Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +\item Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. +\item Neither the name of the Cisco Systems, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. +\end{itemize} +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. +\end{quote} +@endlatexonly + +@section Features Supported Features + +This library supports all of the mandatory-to-implement features of +SRTP (as defined by the most recent Internet Draft). Some of these +features can be selected (or de-selected) at run time by setting an +appropriate policy; this is done using the structure srtp_policy_t. +Some other behaviors of the protocol can be adapted by defining an +approriate event handler for the exceptional events; see the @ref +SRTPevents section. + +Some options that are not included in the specification are supported. +Most notably, the TMMH authentication function is included, though it +was removed from the SRTP Internet Draft during the summer of 2002. + + +@latexonly +Some options that are described in the SRTP specification are not +supported. This includes +\begin{itemize} +\item the Master Key Index (MKI), +\item key derivation rates other than zero, +\item the cipher F8, +\item anti-replay lists with sizes other than 128, +\item the use of the packet index to select between master keys. +\end{itemize} +@endlatexonly + +The user should be aware that it is possible to misuse this libary, +and that the result may be that the security level it provides is +inadequate. If you are implementing a feature using this library, you +will want to read the Security Considerations section of the Internet +Draft. In addition, it is important that you read and understand the +terms outlined in the @ref LICENSE section. + + +@section Installing Installing and Building libSRTP + +@latexonly + +To install libSRTP, download the latest release of the distribution +from \texttt{srtp.sourceforge.net}. The format of the names of the +distributions are \texttt{srtp-A.B.C.tgz}, where \texttt{A} is the +version number, \texttt{B} is the major release number, \texttt{C} is +the minor release number, and \texttt{tgz} is the file +extension\footnote{The extension \texttt{.tgz} is identical to +\texttt{tar.gz}, and indicates a compressed tar file.} You probably +want to get the most recent release. Unpack the distribution and +extract the source files; the directory into which the soruce files +will go is named \texttt{srtp}. + +libSRTP uses the GNU \texttt{autoconf} and \texttt{make} +utilities\footnote{BSD make will not work; if both versions of make +are on your platform, you can invoke GNU make as \texttt{gmake}.}. In +the \texttt{srtp} directory, run the configure script and then make: +\begin{verbatim} + ./configure [ options ] + make +\end{verbatim} +The configure script accepts the following options: +\begin{quote} +\begin{description} +\item[--help] provides a usage summary. +\item[--disable-debug] compiles libSRTP without the runtime + dynamic debugging system. +\item[--enable-generic-aesicm] compile in changes for ismacryp +\item[--enable-syslog] use syslog for error reporting. +\item[--disable-stdout] diables stdout for error reporting. +\item[--enable-console] use \texttt{/dev/console} for error reporting +\item[--gdoi] use GDOI key management (disabled at present). +\end{description} +\end{quote} + +By default, dynamic debbuging is enabled and stdout is used for +debugging. You can use the configure options to have the debugging +output sent to syslog or the system console. Alternatively, you can +define ERR\_REPORTING\_FILE in \texttt{include/conf.h} to be any other +file that can be opened by libSRTP, and debug messages will be sent to +it. + +This package has been tested on the following platforms: Mac OS X +(powerpc-apple-darwin1.4), Cygwin (i686-pc-cygwin), Solaris +(sparc-sun-solaris2.6), RedHat Linux 7.1 and 9 (i686-pc-linux), and +OpenBSD (sparc-unknown-openbsd2.7). + + +@endlatexonly + +@section Applications Applications + +@latexonly + +Several test drivers and a simple and portable srtp application are +included in the \texttt{test/} subdirectory. + +\begin{center} +\begin{tabular}{ll} +\hline +Test driver & Function tested \\ +\hline +kernel\_driver & crypto kernel (ciphers, auth funcs, rng) \\ +srtp\_driver & srtp in-memory tests (does not use the network) \\ +rdbx\_driver & rdbx (extended replay database) \\ +roc\_driver & extended sequence number functions \\ +replay\_driver & replay database \\ +cipher\_driver & ciphers \\ +auth\_driver & hash functions \\ +\hline +\end{tabular} +\end{center} + +The app rtpw is a simple rtp application which reads words from +/usr/dict/words and then sends them out one at a time using [s]rtp. +Manual srtp keying uses the -k option; automated key management +using gdoi will be added later. + +The usage for rtpw is + +\texttt{rtpw [[-d $<$debug$>$]* [-k $<$key$>$ [-a][-e]] [-s | -r] dest\_ip +dest\_port][-l]} + +Either the -s (sender) or -r (receiver) option must be chosen. The +values dest\_ip, dest\_port are the IP address and UDP port to which +the dictionary will be sent, respectively. The options are: +\begin{center} +\begin{tabular}{ll} + -s & (S)RTP sender - causes app to send words \\ + -r & (S)RTP receive - causes app to receve words \\ + -k $<$key$>$ & use SRTP master key $<$key$>$, where the + key is a hexadecimal value (without the + leading "0x") \\ + -e & encrypt/decrypt (for data confidentiality) + (requires use of -k option as well)\\ + -a & message authentication + (requires use of -k option as well) \\ + -l & list the avaliable debug modules \\ + -d $<$debug$>$ & turn on debugging for module $<$debug$>$ \\ +\end{tabular} +\end{center} + +In order to get a random 30-byte value for use as a key/salt pair, you +can use the \texttt{rand\_gen} utility in the \texttt{test/} +subdirectory. + +An example of an SRTP session using two rtpw programs follows: + +\begin{verbatim} +[sh1] set k=`test/rand_gen -n 30` +[sh1] echo $k +c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451 +[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999 +Security services: confidentiality message authentication +set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451 +setting SSRC to 2078917053 +sending word: A +sending word: a +sending word: aa +sending word: aal +sending word: aalii +sending word: aam +sending word: Aani +sending word: aardvark +... + +[sh2] set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451 +[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999 +security services: confidentiality message authentication +set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451 +19 octets received from SSRC 2078917053 word: A +19 octets received from SSRC 2078917053 word: a +20 octets received from SSRC 2078917053 word: aa +21 octets received from SSRC 2078917053 word: aal +... +\end{verbatim} + + +@endlatexonly + + +@section Review Secure RTP Background + +In this section we review SRTP and introduce some terms that are used +in libSRTP. An RTP session is defined by a pair of destination +transport addresses, that is, a network address plus a pair of UDP +ports for RTP and RTCP. RTCP, the RTP control protocol, is used to +coordinate between the participants in an RTP session, e.g. to provide +feedback from receivers to senders. An @e SRTP @e session is +similarly defined; it is just an RTP session for which the SRTP +profile is being used. An SRTP session consists of the traffic sent +to the SRTP or SRTCP destination transport addresses. Each +participant in a session is identified by a synchronization source +(SSRC) identifier. Some participants may not send any SRTP traffic; +they are called receivers, even though they send out SRTCP traffic, +such as receiver reports. + +RTP allows multiple sources to send RTP and RTCP traffic during the +same session. The synchronization source identifier (SSRC) is used to +distinguish these sources. In libSRTP, we call the SRTP and SRTCP +traffic from a particular source a @e stream. Each stream has its own +SSRC, sequence number, rollover counter, and other data. A particular +choice of options, cryptographic mechanisms, and keys is called a @e +policy. Each stream within a session can have a distinct policy +applied to it. A session policy is a collection of stream policies. + +A single policy can be used for all of the streams in a given session, +though the case in which a single @e key is shared across multiple +streams requires care. When key sharing is used, the SSRC values that +identify the streams @b must be distinct. This requirement can be +enforced by using the convention that each SRTP and SRTCP key is used +for encryption by only a single sender. In other words, the key is +shared only across streams that originate from a particular device (of +course, other SRTP participants will need to use the key for +decryption). libSRTP supports this enforcement by detecting the case +in which a key is used for both inbound and outbound data. + + +@section Overview libSRTP Overview + +libSRTP provides functions for protecting RTP and RTCP. RTP packets +can be encrypted and authenticated (using the srtp_protect() +function), turning them into SRTP packets. Similarly, SRTP packets +can be decrypted and have their authentication verified (using the +srtp_unprotect() function), turning them into RTP packets. Similar +functions apply security to RTCP packets. + +The typedef srtp_stream_t points to a structure holding all of the +state associated with an SRTP stream, including the keys and +parameters for cipher and message authentication functions and the +anti-replay data. A particular srtp_stream_t holds the information +needed to protect a particular RTP and RTCP stream. This datatype +is intentionally opaque in order to better seperate the libSRTP +API from its implementation. + +Within an SRTP session, there can be multiple streams, each +originating from a particular sender. Each source uses a distinct +stream context to protect the RTP and RTCP stream that it is +originating. The typedef srtp_t points to a structure holding all of +the state associated with an SRTP session. There can be multiple +stream contexts associated with a single srtp_t. A stream context +cannot exist indepent from an srtp_t, though of course an srtp_t can +be created that contains only a single stream context. A device +participating in an SRTP session must have a stream context for each +source in that session, so that it can process the data that it +receives from each sender. + + +In libSRTP, a session is created using the function srtp_create(). +The policy to be implemented in the session is passed into this +function as an srtp_policy_t structure. A single one of these +structures describes the policy of a single stream. These structures +can also be linked together to form an entire session policy. A linked +list of srtp_policy_t structures is equivalent to a session policy. +In such a policy, we refer to a single srtp_policy_t as an @e element. + +An srtp_policy_t strucutre contains two crypto_policy_t structures +that describe the cryptograhic policies for RTP and RTCP, as well as +the SRTP master key and the SSRC value. The SSRC describes what to +protect (e.g. which stream), and the crypto_policy_t structures +describe how to protect it. The key is contained in a policy element +because it simplifies the interface to the library. In many cases, it +is desirable to use the same cryptographic policies across all of the +streams in a session, but to use a distinct key for each stream. A +crypto_policy_t structure can be initialized by using either the +crypto_policy_set_rtp_default() or crypto_policy_set_rtcp_default() +functions, which set a crypto policy structure to the default policies +for RTP and RTCP protection, respectively. + +@section Example Example Code + +This section provides a simple example of how to use libSRTP. The +example code lacks error checking, but is functional. Here we assume +that the value ssrc is already set to describe the SSRC of the stream +that we are sending, and that the functions get_rtp_packet() and +send_srtp_packet() are available to us. The former puts an RTP packet +into the buffer and returns the number of octets written to that +buffer. The latter sends the RTP packet in the buffer, given the +length as its second argument. + +@verbatim + srtp_t session; + srtp_policy_t policy; + uint8_t key[30]; + + // initialize libSRTP + srtp_init(); + + // set policy to describe a policy for an SRTP stream + crypto_policy_set_rtp_default(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + policy.ssrc = ssrc; + policy.key = key; + policy.next = NULL; + + // set key to random value + crypto_get_random(key, 30); + + // allocate and initialize the SRTP session + srtp_create(&session, policy); + + // main loop: get rtp packets, send srtp packets + while (1) { + char rtp_buffer[2048]; + unsigned len; + + len = get_rtp_packet(rtp_buffer); + srtp_protect(session, rtp_buffer, &len); + send_srtp_packet(rtp_buffer, len); + } +@endverbatim + +@section ISMAcryp ISMA Encryption Support + +The Internet Streaming Media Alliance (ISMA) specifies a way +to pre-encrypt a media file prior to streaming. This method +is an alternative to SRTP encryption, which is potentially +useful when a particular media file will be streamed +multiple times. The specification is available online +at http://www.isma.tv/specreq.nsf/SpecRequest. + +libSRTP provides the encryption and decryption functions needed for ISMAcryp +in the library @t libaesicm.a, which is included in the default +Makefile target. This library is used by the MPEG4IP project; see +http://mpeg4ip.sourceforge.net/. + +Note that ISMAcryp does not provide authentication for +RTP nor RTCP, nor confidentiality for RTCP. +ISMAcryp RECOMMENDS the use of SRTP message authentication for ISMAcryp +streams while using ISMAcryp encryption to protect the media itself. + + + */ diff --git a/src/libs/resiprocate/contrib/srtp/doc/libsrtp.pdf b/src/libs/resiprocate/contrib/srtp/doc/libsrtp.pdf new file mode 100644 index 00000000..8b9f7fe2 Binary files /dev/null and b/src/libs/resiprocate/contrib/srtp/doc/libsrtp.pdf differ diff --git a/src/libs/resiprocate/contrib/srtp/doc/references.txt b/src/libs/resiprocate/contrib/srtp/doc/references.txt new file mode 100644 index 00000000..2ec9d437 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/doc/references.txt @@ -0,0 +1,21 @@ +SRTP and ICM References +September, 2005 + +This document provides references for the various cryptographic +functions used in libSRTP and libaesicm. + +Secure RTP is defined in RFC 3711, which is included in this +distribution for convenience. The counter mode definition is in +Section 4.1.1 of the SRTP draft. + +SHA-1 is defined in FIPS-180-1, available online at the NIST website. + +HMAC is defined in RFC2104, and HMAC-SHA1 test vectors are available +in RFC2202, which are available online at http://www.ietf.org/rfc/ + +ICM is defined by draft-irtf-cfrg-icm-00.txt, and its application in +ISMAcryp (the Internet Streaming Media Alliance 1.0 Encryption and +Authentication) is defined in that specification. It is available +from http://www.isma.tv/. + + diff --git a/src/libs/resiprocate/contrib/srtp/doc/rfc3711.txt b/src/libs/resiprocate/contrib/srtp/doc/rfc3711.txt new file mode 100644 index 00000000..ecc0648a --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/doc/rfc3711.txt @@ -0,0 +1,3139 @@ + + + + + + +Network Working Group M. Baugher +Request for Comments: 3711 D. McGrew +Category: Standards Track Cisco Systems, Inc. + M. Naslund + E. Carrara + K. Norrman + Ericsson Research + March 2004 + + + The Secure Real-time Transport Protocol (SRTP) + +Status of this Memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2004). All Rights Reserved. + +Abstract + + This document describes the Secure Real-time Transport Protocol + (SRTP), a profile of the Real-time Transport Protocol (RTP), which + can provide confidentiality, message authentication, and replay + protection to the RTP traffic and to the control traffic for RTP, the + Real-time Transport Control Protocol (RTCP). + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 3 + 2. Goals and Features . . . . . . . . . . . . . . . . . . . . . . 4 + 2.1. Features . . . . . . . . . . . . . . . . . . . . . . . . 5 + 3. SRTP Framework . . . . . . . . . . . . . . . . . . . . . . . . 5 + 3.1. Secure RTP . . . . . . . . . . . . . . . . . . . . . . . 6 + 3.2. SRTP Cryptographic Contexts. . . . . . . . . . . . . . . 7 + 3.2.1. Transform-independent parameters . . . . . . . . 8 + 3.2.2. Transform-dependent parameters . . . . . . . . . 10 + 3.2.3. Mapping SRTP Packets to Cryptographic Contexts . 10 + 3.3. SRTP Packet Processing . . . . . . . . . . . . . . . . . 11 + 3.3.1. Packet Index Determination, and ROC, s_l Update. 13 + 3.3.2. Replay Protection. . . . . . . . . . . . . . . . 15 + 3.4. Secure RTCP . . . . . . . . . . . . . . . . . . . . . . . 15 + + + +Baugher, et al. Standards Track [Page 1] + +RFC 3711 SRTP March 2004 + + + 4. Pre-Defined Cryptographic Transforms . . . . . . . . . . . . . 19 + 4.1. Encryption . . . . . . . . . . . . . . . . . . . . . . . 19 + 4.1.1. AES in Counter Mode. . . . . . . . . . . . . . . 21 + 4.1.2. AES in f8-mode . . . . . . . . . . . . . . . . . 22 + 4.1.3. NULL Cipher. . . . . . . . . . . . . . . . . . . 25 + 4.2. Message Authentication and Integrity . . . . . . . . . . 25 + 4.2.1. HMAC-SHA1. . . . . . . . . . . . . . . . . . . . 25 + 4.3. Key Derivation . . . . . . . . . . . . . . . . . . . . . 26 + 4.3.1. Key Derivation Algorithm . . . . . . . . . . . . 26 + 4.3.2. SRTCP Key Derivation . . . . . . . . . . . . . . 28 + 4.3.3. AES-CM PRF . . . . . . . . . . . . . . . . . . . 28 + 5. Default and mandatory-to-implement Transforms. . . . . . . . . 28 + 5.1. Encryption: AES-CM and NULL. . . . . . . . . . . . . . . 29 + 5.2. Message Authentication/Integrity: HMAC-SHA1. . . . . . . 29 + 5.3. Key Derivation: AES-CM PRF . . . . . . . . . . . . . . . 29 + 6. Adding SRTP Transforms . . . . . . . . . . . . . . . . . . . . 29 + 7. Rationale. . . . . . . . . . . . . . . . . . . . . . . . . . . 30 + 7.1. Key derivation . . . . . . . . . . . . . . . . . . . . . 30 + 7.2. Salting key. . . . . . . . . . . . . . . . . . . . . . . 30 + 7.3. Message Integrity from Universal Hashing . . . . . . . . 31 + 7.4. Data Origin Authentication Considerations. . . . . . . . 31 + 7.5. Short and Zero-length Message Authentication . . . . . . 32 + 8. Key Management Considerations. . . . . . . . . . . . . . . . . 33 + 8.1. Re-keying . . . . . . . . . . . . . . . . . . . . . . . 34 + 8.1.1. Use of the <From, To> for re-keying. . . . . . . 34 + 8.2. Key Management parameters. . . . . . . . . . . . . . . . 35 + 9. Security Considerations. . . . . . . . . . . . . . . . . . . . 37 + 9.1. SSRC collision and two-time pad. . . . . . . . . . . . . 37 + 9.2. Key Usage. . . . . . . . . . . . . . . . . . . . . . . . 38 + 9.3. Confidentiality of the RTP Payload . . . . . . . . . . . 39 + 9.4. Confidentiality of the RTP Header. . . . . . . . . . . . 40 + 9.5. Integrity of the RTP payload and header. . . . . . . . . 40 + 9.5.1. Risks of Weak or Null Message Authentication. . . 42 + 9.5.2. Implicit Header Authentication . . . . . . . . . 43 + 10. Interaction with Forward Error Correction mechanisms. . . . . 43 + 11. Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . 43 + 11.1. Unicast. . . . . . . . . . . . . . . . . . . . . . . . . 43 + 11.2. Multicast (one sender) . . . . . . . . . . . . . . . . . 44 + 11.3. Re-keying and access control . . . . . . . . . . . . . . 45 + 11.4. Summary of basic scenarios . . . . . . . . . . . . . . . 46 + 12. IANA Considerations. . . . . . . . . . . . . . . . . . . . . . 46 + 13. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 47 + 14. References . . . . . . . . . . . . . . . . . . . . . . . . . . 47 + 14.1. Normative References . . . . . . . . . . . . . . . . . . 47 + 14.2. Informative References . . . . . . . . . . . . . . . . . 48 + Appendix A: Pseudocode for Index Determination . . . . . . . . . . 51 + Appendix B: Test Vectors . . . . . . . . . . . . . . . . . . . . . 51 + B.1. AES-f8 Test Vectors. . . . . . . . . . . . . . . . . . . 51 + + + +Baugher, et al. Standards Track [Page 2] + +RFC 3711 SRTP March 2004 + + + B.2. AES-CM Test Vectors. . . . . . . . . . . . . . . . . . . 52 + B.3. Key Derivation Test Vectors. . . . . . . . . . . . . . . 53 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 55 + Full Copyright Statement . . . . . . . . . . . . . . . . . . . . . 56 + +1. Introduction + + This document describes the Secure Real-time Transport Protocol + (SRTP), a profile of the Real-time Transport Protocol (RTP), which + can provide confidentiality, message authentication, and replay + protection to the RTP traffic and to the control traffic for RTP, + RTCP (the Real-time Transport Control Protocol) [RFC3350]. + + SRTP provides a framework for encryption and message authentication + of RTP and RTCP streams (Section 3). SRTP defines a set of default + cryptographic transforms (Sections 4 and 5), and it allows new + transforms to be introduced in the future (Section 6). With + appropriate key management (Sections 7 and 8), SRTP is secure + (Sections 9) for unicast and multicast RTP applications (Section 11). + + SRTP can achieve high throughput and low packet expansion. SRTP + proves to be a suitable protection for heterogeneous environments + (mix of wired and wireless networks). To get such features, default + transforms are described, based on an additive stream cipher for + encryption, a keyed-hash based function for message authentication, + and an "implicit" index for sequencing/synchronization based on the + RTP sequence number for SRTP and an index number for Secure RTCP + (SRTCP). + +1.1. Notational Conventions + + The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in [RFC2119]. The + terminology conforms to [RFC2828] with the following exception. For + simplicity we use the term "random" throughout the document to denote + randomly or pseudo-randomly generated values. Large amounts of + random bits may be difficult to obtain, and for the security of SRTP, + pseudo-randomness is sufficient [RFC1750]. + + By convention, the adopted representation is the network byte order, + i.e., the left most bit (octet) is the most significant one. By XOR + we mean bitwise addition modulo 2 of binary strings, and || denotes + concatenation. In other words, if C = A || B, then the most + significant bits of C are the bits of A, and the least significant + bits of C equal the bits of B. Hexadecimal numbers are prefixed by + 0x. + + + + +Baugher, et al. Standards Track [Page 3] + +RFC 3711 SRTP March 2004 + + + The word "encryption" includes also use of the NULL algorithm (which + in practice does leave the data in the clear). + + With slight abuse of notation, we use the terms "message + authentication" and "authentication tag" as is common practice, even + though in some circumstances, e.g., group communication, the service + provided is actually only integrity protection and not data origin + authentication. + +2. Goals and Features + + The security goals for SRTP are to ensure: + + * the confidentiality of the RTP and RTCP payloads, and + + * the integrity of the entire RTP and RTCP packets, together with + protection against replayed packets. + + These security services are optional and independent from each other, + except that SRTCP integrity protection is mandatory (malicious or + erroneous alteration of RTCP messages could otherwise disrupt the + processing of the RTP stream). + + Other, functional, goals for the protocol are: + + * a framework that permits upgrading with new cryptographic + transforms, + + * low bandwidth cost, i.e., a framework preserving RTP header + compression efficiency, + + and, asserted by the pre-defined transforms: + + * a low computational cost, + + * a small footprint (i.e., small code size and data memory for + keying information and replay lists), + + * limited packet expansion to support the bandwidth economy goal, + + * independence from the underlying transport, network, and physical + layers used by RTP, in particular high tolerance to packet loss + and re-ordering. + + These properties ensure that SRTP is a suitable protection scheme for + RTP/RTCP in both wired and wireless scenarios. + + + + + +Baugher, et al. Standards Track [Page 4] + +RFC 3711 SRTP March 2004 + + +2.1. Features + + Besides the above mentioned direct goals, SRTP provides for some + additional features. They have been introduced to lighten the burden + on key management and to further increase security. They include: + + * A single "master key" can provide keying material for + confidentiality and integrity protection, both for the SRTP stream + and the corresponding SRTCP stream. This is achieved with a key + derivation function (see Section 4.3), providing "session keys" + for the respective security primitive, securely derived from the + master key. + + * In addition, the key derivation can be configured to periodically + refresh the session keys, which limits the amount of ciphertext + produced by a fixed key, available for an adversary to + cryptanalyze. + + * "Salting keys" are used to protect against pre-computation and + time-memory tradeoff attacks [MF00] [BS00]. + + Detailed rationale for these features can be found in Section 7. + +3. SRTP Framework + + RTP is the Real-time Transport Protocol [RFC3550]. We define SRTP as + a profile of RTP. This profile is an extension to the RTP + Audio/Video Profile [RFC3551]. Except where explicitly noted, all + aspects of that profile apply, with the addition of the SRTP security + features. Conceptually, we consider SRTP to be a "bump in the stack" + implementation which resides between the RTP application and the + transport layer. SRTP intercepts RTP packets and then forwards an + equivalent SRTP packet on the sending side, and intercepts SRTP + packets and passes an equivalent RTP packet up the stack on the + receiving side. + + Secure RTCP (SRTCP) provides the same security services to RTCP as + SRTP does to RTP. SRTCP message authentication is MANDATORY and + thereby protects the RTCP fields to keep track of membership, provide + feedback to RTP senders, or maintain packet sequence counters. SRTCP + is described in Section 3.4. + + + + + + + + + + +Baugher, et al. Standards Track [Page 5] + +RFC 3711 SRTP March 2004 + + +3.1. Secure RTP + + The format of an SRTP packet is illustrated in Figure 1. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+ + |V=2|P|X| CC |M| PT | sequence number | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | timestamp | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | synchronization source (SSRC) identifier | | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | + | contributing source (CSRC) identifiers | | + | .... | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | RTP extension (OPTIONAL) | | + +>+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | | payload ... | | + | | +-------------------------------+ | + | | | RTP padding | RTP pad count | | + +>+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+ + | ~ SRTP MKI (OPTIONAL) ~ | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | : authentication tag (RECOMMENDED) : | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | | + +- Encrypted Portion* Authenticated Portion ---+ + + Figure 1. The format of an SRTP packet. *Encrypted Portion is the + same size as the plaintext for the Section 4 pre-defined transforms. + + The "Encrypted Portion" of an SRTP packet consists of the encryption + of the RTP payload (including RTP padding when present) of the + equivalent RTP packet. The Encrypted Portion MAY be the exact size + of the plaintext or MAY be larger. Figure 1 shows the RTP payload + including any possible padding for RTP [RFC3550]. + + None of the pre-defined encryption transforms uses any padding; for + these, the RTP and SRTP payload sizes match exactly. New transforms + added to SRTP (following Section 6) may require padding, and may + hence produce larger payloads. RTP provides its own padding format + (as seen in Fig. 1), which due to the padding indicator in the RTP + header has merits in terms of compactness relative to paddings using + prefix-free codes. This RTP padding SHALL be the default method for + transforms requiring padding. Transforms MAY specify other padding + methods, and MUST then specify the amount, format, and processing of + their padding. It is important to note that encryption transforms + + + +Baugher, et al. Standards Track [Page 6] + +RFC 3711 SRTP March 2004 + + + that use padding are vulnerable to subtle attacks, especially when + message authentication is not used [V02]. Each specification for a + new encryption transform needs to carefully consider and describe the + security implications of the padding that it uses. Message + authentication codes define their own padding, so this default does + not apply to authentication transforms. + + The OPTIONAL MKI and the RECOMMENDED authentication tag are the only + fields defined by SRTP that are not in RTP. Only 8-bit alignment is + assumed. + + MKI (Master Key Identifier): configurable length, OPTIONAL. The + MKI is defined, signaled, and used by key management. The + MKI identifies the master key from which the session + key(s) were derived that authenticate and/or encrypt the + particular packet. Note that the MKI SHALL NOT identify + the SRTP cryptographic context, which is identified + according to Section 3.2.3. The MKI MAY be used by key + management for the purposes of re-keying, identifying a + particular master key within the cryptographic context + (Section 3.2.1). + + Authentication tag: configurable length, RECOMMENDED. The + authentication tag is used to carry message authentication + data. The Authenticated Portion of an SRTP packet + consists of the RTP header followed by the Encrypted + Portion of the SRTP packet. Thus, if both encryption and + authentication are applied, encryption SHALL be applied + before authentication on the sender side and conversely on + the receiver side. The authentication tag provides + authentication of the RTP header and payload, and it + indirectly provides replay protection by authenticating + the sequence number. Note that the MKI is not integrity + protected as this does not provide any extra protection. + +3.2. SRTP Cryptographic Contexts + + Each SRTP stream requires the sender and receiver to maintain + cryptographic state information. This information is called the + "cryptographic context". + + SRTP uses two types of keys: session keys and master keys. By a + "session key", we mean a key which is used directly in a + cryptographic transform (e.g., encryption or message authentication), + and by a "master key", we mean a random bit string (given by the key + management protocol) from which session keys are derived in a + + + + + +Baugher, et al. Standards Track [Page 7] + +RFC 3711 SRTP March 2004 + + + cryptographically secure way. The master key(s) and other parameters + in the cryptographic context are provided by key management + mechanisms external to SRTP, see Section 8. + +3.2.1. Transform-independent parameters + + Transform-independent parameters are present in the cryptographic + context independently of the particular encryption or authentication + transforms that are used. The transform-independent parameters of + the cryptographic context for SRTP consist of: + + * a 32-bit unsigned rollover counter (ROC), which records how many + times the 16-bit RTP sequence number has been reset to zero after + passing through 65,535. Unlike the sequence number (SEQ), which + SRTP extracts from the RTP packet header, the ROC is maintained by + SRTP as described in Section 3.3.1. + + We define the index of the SRTP packet corresponding to a given + ROC and RTP sequence number to be the 48-bit quantity + + i = 2^16 * ROC + SEQ. + + * for the receiver only, a 16-bit sequence number s_l, which can be + thought of as the highest received RTP sequence number (see + Section 3.3.1 for its handling), which SHOULD be authenticated + since message authentication is RECOMMENDED, + + * an identifier for the encryption algorithm, i.e., the cipher and + its mode of operation, + + * an identifier for the message authentication algorithm, + + * a replay list, maintained by the receiver only (when + authentication and replay protection are provided), containing + indices of recently received and authenticated SRTP packets, + + * an MKI indicator (0/1) as to whether an MKI is present in SRTP and + SRTCP packets, + + * if the MKI indicator is set to one, the length (in octets) of the + MKI field, and (for the sender) the actual value of the currently + active MKI (the value of the MKI indicator and length MUST be kept + fixed for the lifetime of the context), + + * the master key(s), which MUST be random and kept secret, + + + + + + +Baugher, et al. Standards Track [Page 8] + +RFC 3711 SRTP March 2004 + + + * for each master key, there is a counter of the number of SRTP + packets that have been processed (sent) with that master key + (essential for security, see Sections 3.3.1 and 9), + + * non-negative integers n_e, and n_a, determining the length of the + session keys for encryption, and message authentication. + + In addition, for each master key, an SRTP stream MAY use the + following associated values: + + * a master salt, to be used in the key derivation of session keys. + This value, when used, MUST be random, but MAY be public. Use of + master salt is strongly RECOMMENDED, see Section 9.2. A "NULL" + salt is treated as 00...0. + + * an integer in the set {1,2,4,...,2^24}, the "key_derivation_rate", + where an unspecified value is treated as zero. The constraint to + be a power of 2 simplifies the session-key derivation + implementation, see Section 4.3. + + * an MKI value, + + * <From, To> values, specifying the lifetime for a master key, + expressed in terms of the two 48-bit index values inside whose + range (including the range end-points) the master key is valid. + For the use of <From, To>, see Section 8.1.1. <From, To> is an + alternative to the MKI and assumes that a master key is in one- + to-one correspondence with the SRTP session key on which the + <From, To> range is defined. + + SRTCP SHALL by default share the crypto context with SRTP, except: + + * no rollover counter and s_l-value need to be maintained as the + RTCP index is explicitly carried in each SRTCP packet, + + * a separate replay list is maintained (when replay protection is + provided), + + * SRTCP maintains a separate counter for its master key (even if the + master key is the same as that for SRTP, see below), as a means to + maintain a count of the number of SRTCP packets that have been + processed with that key. + + Note in particular that the master key(s) MAY be shared between SRTP + and the corresponding SRTCP, if the pre-defined transforms (including + the key derivation) are used but the session key(s) MUST NOT be so + shared. + + + + +Baugher, et al. Standards Track [Page 9] + +RFC 3711 SRTP March 2004 + + + In addition, there can be cases (see Sections 8 and 9.1) where + several SRTP streams within a given RTP session, identified by their + synchronization source (SSRCs, which is part of the RTP header), + share most of the crypto context parameters (including possibly + master and session keys). In such cases, just as in the normal + SRTP/SRTCP parameter sharing above, separate replay lists and packet + counters for each stream (SSRC) MUST still be maintained. Also, + separate SRTP indices MUST then be maintained. + + A summary of parameters, pre-defined transforms, and default values + for the above parameters (and other SRTP parameters) can be found in + Sections 5 and 8.2. + +3.2.2. Transform-dependent parameters + + All encryption, authentication/integrity, and key derivation + parameters are defined in the transforms section (Section 4). + Typical examples of such parameters are block size of ciphers, + session keys, data for the Initialization Vector (IV) formation, etc. + Future SRTP transform specifications MUST include a section to list + the additional cryptographic context's parameters for that transform, + if any. + +3.2.3. Mapping SRTP Packets to Cryptographic Contexts + + Recall that an RTP session for each participant is defined [RFC3550] + by a pair of destination transport addresses (one network address + plus a port pair for RTP and RTCP), and that a multimedia session is + defined as a collection of RTP sessions. For example, a particular + multimedia session could include an audio RTP session, a video RTP + session, and a text RTP session. + + A cryptographic context SHALL be uniquely identified by the triplet + context identifier: + + context id = <SSRC, destination network address, destination + transport port number> + + where the destination network address and the destination transport + port are the ones in the SRTP packet. It is assumed that, when + presented with this information, the key management returns a context + with the information as described in Section 3.2. + + As noted above, SRTP and SRTCP by default share the bulk of the + parameters in the cryptographic context. Thus, retrieving the crypto + context parameters for an SRTCP stream in practice may imply a + binding to the correspondent SRTP crypto context. It is up to the + implementation to assure such binding, since the RTCP port may not be + + + +Baugher, et al. Standards Track [Page 10] + +RFC 3711 SRTP March 2004 + + + directly deducible from the RTP port only. Alternatively, the key + management may choose to provide separate SRTP- and SRTCP- contexts, + duplicating the common parameters (such as master key(s)). The + latter approach then also enables SRTP and SRTCP to use, e.g., + distinct transforms, if so desired. Similar considerations arise + when multiple SRTP streams, forming part of one single RTP session, + share keys and other parameters. + + If no valid context can be found for a packet corresponding to a + certain context identifier, that packet MUST be discarded. + +3.3. SRTP Packet Processing + + The following applies to SRTP. SRTCP is described in Section 3.4. + + Assuming initialization of the cryptographic context(s) has taken + place via key management, the sender SHALL do the following to + construct an SRTP packet: + + 1. Determine which cryptographic context to use as described in + Section 3.2.3. + + 2. Determine the index of the SRTP packet using the rollover counter, + the highest sequence number in the cryptographic context, and the + sequence number in the RTP packet, as described in Section 3.3.1. + + 3. Determine the master key and master salt. This is done using the + index determined in the previous step or the current MKI in the + cryptographic context, according to Section 8.1. + + 4. Determine the session keys and session salt (if they are used by + the transform) as described in Section 4.3, using master key, + master salt, key_derivation_rate, and session key-lengths in the + cryptographic context with the index, determined in Steps 2 and 3. + + 5. Encrypt the RTP payload to produce the Encrypted Portion of the + packet (see Section 4.1, for the defined ciphers). This step uses + the encryption algorithm indicated in the cryptographic context, + the session encryption key and the session salt (if used) found in + Step 4 together with the index found in Step 2. + + 6. If the MKI indicator is set to one, append the MKI to the packet. + + 7. For message authentication, compute the authentication tag for the + Authenticated Portion of the packet, as described in Section 4.2. + This step uses the current rollover counter, the authentication + + + + + +Baugher, et al. Standards Track [Page 11] + +RFC 3711 SRTP March 2004 + + + algorithm indicated in the cryptographic context, and the session + authentication key found in Step 4. Append the authentication tag + to the packet. + + 8. If necessary, update the ROC as in Section 3.3.1, using the packet + index determined in Step 2. + + To authenticate and decrypt an SRTP packet, the receiver SHALL do the + following: + + 1. Determine which cryptographic context to use as described in + Section 3.2.3. + + 2. Run the algorithm in Section 3.3.1 to get the index of the SRTP + packet. The algorithm uses the rollover counter and highest + sequence number in the cryptographic context with the sequence + number in the SRTP packet, as described in Section 3.3.1. + + 3. Determine the master key and master salt. If the MKI indicator in + the context is set to one, use the MKI in the SRTP packet, + otherwise use the index from the previous step, according to + Section 8.1. + + 4. Determine the session keys, and session salt (if used by the + transform) as described in Section 4.3, using master key, master + salt, key_derivation_rate and session key-lengths in the + cryptographic context with the index, determined in Steps 2 and 3. + + 5. For message authentication and replay protection, first check if + the packet has been replayed (Section 3.3.2), using the Replay + List and the index as determined in Step 2. If the packet is + judged to be replayed, then the packet MUST be discarded, and the + event SHOULD be logged. + + Next, perform verification of the authentication tag, using the + rollover counter from Step 2, the authentication algorithm + indicated in the cryptographic context, and the session + authentication key from Step 4. If the result is "AUTHENTICATION + FAILURE" (see Section 4.2), the packet MUST be discarded from + further processing and the event SHOULD be logged. + + 6. Decrypt the Encrypted Portion of the packet (see Section 4.1, for + the defined ciphers), using the decryption algorithm indicated in + the cryptographic context, the session encryption key and salt (if + used) found in Step 4 with the index from Step 2. + + + + + + +Baugher, et al. Standards Track [Page 12] + +RFC 3711 SRTP March 2004 + + + 7. Update the rollover counter and highest sequence number, s_l, in + the cryptographic context as in Section 3.3.1, using the packet + index estimated in Step 2. If replay protection is provided, also + update the Replay List as described in Section 3.3.2. + + 8. When present, remove the MKI and authentication tag fields from + the packet. + +3.3.1. Packet Index Determination, and ROC, s_l Update + + SRTP implementations use an "implicit" packet index for sequencing, + i.e., not all of the index is explicitly carried in the SRTP packet. + For the pre-defined transforms, the index i is used in replay + protection (Section 3.3.2), encryption (Section 4.1), message + authentication (Section 4.2), and for the key derivation (Section + 4.3). + + When the session starts, the sender side MUST set the rollover + counter, ROC, to zero. Each time the RTP sequence number, SEQ, wraps + modulo 2^16, the sender side MUST increment ROC by one, modulo 2^32 + (see security aspects below). The sender's packet index is then + defined as + + i = 2^16 * ROC + SEQ. + + Receiver-side implementations use the RTP sequence number to + determine the correct index of a packet, which is the location of the + packet in the sequence of all SRTP packets. A robust approach for + the proper use of a rollover counter requires its handling and use to + be well defined. In particular, out-of-order RTP packets with + sequence numbers close to 2^16 or zero must be properly handled. + + The index estimate is based on the receiver's locally maintained ROC + and s_l values. At the setup of the session, the ROC MUST be set to + zero. Receivers joining an on-going session MUST be given the + current ROC value using out-of-band signaling such as key-management + signaling. Furthermore, the receiver SHALL initialize s_l to the RTP + sequence number (SEQ) of the first observed SRTP packet (unless the + initial value is provided by out of band signaling such as key + management). + + On consecutive SRTP packets, the receiver SHOULD estimate the index + as + i = 2^16 * v + SEQ, + + where v is chosen from the set { ROC-1, ROC, ROC+1 } (modulo 2^32) + such that i is closest (in modulo 2^48 sense) to the value 2^16 * ROC + + s_l (see Appendix A for pseudocode). + + + +Baugher, et al. Standards Track [Page 13] + +RFC 3711 SRTP March 2004 + + + After the packet has been processed and authenticated (when enabled + for SRTP packets for the session), the receiver MUST use v to + conditionally update its s_l and ROC variables as follows. If + v=(ROC-1) mod 2^32, then there is no update to s_l or ROC. If v=ROC, + then s_l is set to SEQ if and only if SEQ is larger than the current + s_l; there is no change to ROC. If v=(ROC+1) mod 2^32, then s_l is + set to SEQ and ROC is set to v. + + After a re-keying occurs (changing to a new master key), the rollover + counter always maintains its sequence of values, i.e., it MUST NOT be + reset to zero. + + As the rollover counter is 32 bits long and the sequence number is 16 + bits long, the maximum number of packets belonging to a given SRTP + stream that can be secured with the same key is 2^48 using the pre- + defined transforms. After that number of SRTP packets have been sent + with a given (master or session) key, the sender MUST NOT send any + more packets with that key. (There exists a similar limit for SRTCP, + which in practice may be more restrictive, see Section 9.2.) This + limitation enforces a security benefit by providing an upper bound on + the amount of traffic that can pass before cryptographic keys are + changed. Re-keying (see Section 8.1) MUST be triggered, before this + amount of traffic, and MAY be triggered earlier, e.g., for increased + security and access control to media. Recurring key derivation by + means of a non-zero key_derivation_rate (see Section 4.3), also gives + stronger security but does not change the above absolute maximum + value. + + On the receiver side, there is a caveat to updating s_l and ROC: if + message authentication is not present, neither the initialization of + s_l, nor the ROC update can be made completely robust. The + receiver's "implicit index" approach works for the pre-defined + transforms as long as the reorder and loss of the packets are not too + great and bit-errors do not occur in unfortunate ways. In + particular, 2^15 packets would need to be lost, or a packet would + need to be 2^15 packets out of sequence before synchronization is + lost. Such drastic loss or reorder is likely to disrupt the RTP + application itself. + + The algorithm for the index estimate and ROC update is a matter of + implementation, and should take into consideration the environment + (e.g., packet loss rate) and the cases when synchronization is likely + to be lost, e.g., when the initial sequence number (randomly chosen + by RTP) is not known in advance (not sent in the key management + protocol) but may be near to wrap modulo 2^16. + + + + + + +Baugher, et al. Standards Track [Page 14] + +RFC 3711 SRTP March 2004 + + + A more elaborate and more robust scheme than the one given above is + the handling of RTP's own "rollover counter", see Appendix A.1 of + [RFC3550]. + +3.3.2. Replay Protection + + Secure replay protection is only possible when integrity protection + is present. It is RECOMMENDED to use replay protection, both for RTP + and RTCP, as integrity protection alone cannot assure security + against replay attacks. + + A packet is "replayed" when it is stored by an adversary, and then + re-injected into the network. When message authentication is + provided, SRTP protects against such attacks through a Replay List. + Each SRTP receiver maintains a Replay List, which conceptually + contains the indices of all of the packets which have been received + and authenticated. In practice, the list can use a "sliding window" + approach, so that a fixed amount of storage suffices for replay + protection. Packet indices which lag behind the packet index in the + context by more than SRTP-WINDOW-SIZE can be assumed to have been + received, where SRTP-WINDOW-SIZE is a receiver-side, implementation- + dependent parameter and MUST be at least 64, but which MAY be set to + a higher value. + + The receiver checks the index of an incoming packet against the + replay list and the window. Only packets with index ahead of the + window, or, inside the window but not already received, SHALL be + accepted. + + After the packet has been authenticated (if necessary the window is + first moved ahead), the replay list SHALL be updated with the new + index. + + The Replay List can be efficiently implemented by using a bitmap to + represent which packets have been received, as described in the + Security Architecture for IP [RFC2401]. + +3.4. Secure RTCP + + Secure RTCP follows the definition of Secure RTP. SRTCP adds three + mandatory new fields (the SRTCP index, an "encrypt-flag", and the + authentication tag) and one optional field (the MKI) to the RTCP + packet definition. The three mandatory fields MUST be appended to an + RTCP packet in order to form an equivalent SRTCP packet. The added + fields follow any other profile-specific extensions. + + + + + + +Baugher, et al. Standards Track [Page 15] + +RFC 3711 SRTP March 2004 + + + According to Section 6.1 of [RFC3550], there is a REQUIRED packet + format for compound packets. SRTCP MUST be given packets according + to that requirement in the sense that the first part MUST be a sender + report or a receiver report. However, the RTCP encryption prefix (a + random 32-bit quantity) specified in that Section MUST NOT be used + since, as is stated there, it is only applicable to the encryption + method specified in [RFC3550] and is not needed by the cryptographic + mechanisms used in SRTP. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+ + |V=2|P| RC | PT=SR or RR | length | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | SSRC of sender | | + +>+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | + | ~ sender info ~ | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | ~ report block 1 ~ | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | ~ report block 2 ~ | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | ~ ... ~ | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | |V=2|P| SC | PT=SDES=202 | length | | + | +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | + | | SSRC/CSRC_1 | | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | ~ SDES items ~ | + | +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | + | ~ ... ~ | + +>+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | + | |E| SRTCP index | | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+ + | ~ SRTCP MKI (OPTIONAL) ~ | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | : authentication tag : | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | | + +-- Encrypted Portion Authenticated Portion -----+ + + + Figure 2. An example of the format of a Secure RTCP packet, + consisting of an underlying RTCP compound packet with a Sender Report + and SDES packet. + + + + + + +Baugher, et al. Standards Track [Page 16] + +RFC 3711 SRTP March 2004 + + + The Encrypted Portion of an SRTCP packet consists of the encryption + (Section 4.1) of the RTCP payload of the equivalent compound RTCP + packet, from the first RTCP packet, i.e., from the ninth (9) octet to + the end of the compound packet. The Authenticated Portion of an + SRTCP packet consists of the entire equivalent (eventually compound) + RTCP packet, the E flag, and the SRTCP index (after any encryption + has been applied to the payload). + + The added fields are: + + E-flag: 1 bit, REQUIRED + The E-flag indicates if the current SRTCP packet is + encrypted or unencrypted. Section 9.1 of [RFC3550] allows + the split of a compound RTCP packet into two lower-layer + packets, one to be encrypted and one to be sent in the + clear. The E bit set to "1" indicates encrypted packet, and + "0" indicates non-encrypted packet. + + SRTCP index: 31 bits, REQUIRED + The SRTCP index is a 31-bit counter for the SRTCP packet. + The index is explicitly included in each packet, in contrast + to the "implicit" index approach used for SRTP. The SRTCP + index MUST be set to zero before the first SRTCP packet is + sent, and MUST be incremented by one, modulo 2^31, after + each SRTCP packet is sent. In particular, after a re-key, + the SRTCP index MUST NOT be reset to zero again. + + Authentication Tag: configurable length, REQUIRED + The authentication tag is used to carry message + authentication data. + + MKI: configurable length, OPTIONAL + The MKI is the Master Key Indicator, and functions according + to the MKI definition in Section 3. + + SRTCP uses the cryptographic context parameters and packet processing + of SRTP by default, with the following changes: + + * The receiver does not need to "estimate" the index, as it is + explicitly signaled in the packet. + + * Pre-defined SRTCP encryption is as specified in Section 4.1, but + using the definition of the SRTCP Encrypted Portion given in this + section, and using the SRTCP index as the index i. The encryption + transform and related parameters SHALL by default be the same + selected for the protection of the associated SRTP stream(s), + while the NULL algorithm SHALL be applied to the RTCP packets not + to be encrypted. SRTCP may have a different encryption transform + + + +Baugher, et al. Standards Track [Page 17] + +RFC 3711 SRTP March 2004 + + + than the one used by the corresponding SRTP. The expected use for + this feature is when the former has NULL-encryption and the latter + has a non NULL-encryption. + + The E-flag is assigned a value by the sender depending on whether the + packet was encrypted or not. + + * SRTCP decryption is performed as in Section 4, but only if the E + flag is equal to 1. If so, the Encrypted Portion is decrypted, + using the SRTCP index as the index i. In case the E-flag is 0, + the payload is simply left unmodified. + + * SRTCP replay protection is as defined in Section 3.3.2, but using + the SRTCP index as the index i and a separate Replay List that is + specific to SRTCP. + + * The pre-defined SRTCP authentication tag is specified as in + Section 4.2, but with the Authenticated Portion of the SRTCP + packet given in this section (which includes the index). The + authentication transform and related parameters (e.g., key size) + SHALL by default be the same as selected for the protection of the + associated SRTP stream(s). + + * In the last step of the processing, only the sender needs to + update the value of the SRTCP index by incrementing it modulo 2^31 + and for security reasons the sender MUST also check the number of + SRTCP packets processed, see Section 9.2. + + Message authentication for RTCP is REQUIRED, as it is the control + protocol (e.g., it has a BYE packet) for RTP. + + Precautions must be taken so that the packet expansion in SRTCP (due + to the added fields) does not cause SRTCP messages to use more than + their share of RTCP bandwidth. To avoid this, the following two + measures MUST be taken: + + 1. When initializing the RTCP variable "avg_rtcp_size" defined in + chapter 6.3 of [RFC3550], it MUST include the size of the fields + that will be added by SRTCP (index, E-bit, authentication tag, and + when present, the MKI). + + 2. When updating the "avg_rtcp_size" using the variable "packet_size" + (section 6.3.3 of [RFC3550]), the value of "packet_size" MUST + include the size of the additional fields added by SRTCP. + + + + + + + +Baugher, et al. Standards Track [Page 18] + +RFC 3711 SRTP March 2004 + + + With these measures in place the SRTCP messages will not use more + than the allotted bandwidth. The effect of the size of the added + fields on the SRTCP traffic will be that messages will be sent with + longer packet intervals. The increase in the intervals will be + directly proportional to size of the added fields. For the pre- + defined transforms, the size of the added fields will be at least 14 + octets, and upper bounded depending on MKI and the authentication tag + sizes. + +4. Pre-Defined Cryptographic Transforms + + While there are numerous encryption and message authentication + algorithms that can be used in SRTP, below we define default + algorithms in order to avoid the complexity of specifying the + encodings for the signaling of algorithm and parameter identifiers. + The defined algorithms have been chosen as they fulfill the goals + listed in Section 2. Recommendations on how to extend SRTP with new + transforms are given in Section 6. + +4.1. Encryption + + The following parameters are common to both pre-defined, non-NULL, + encryption transforms specified in this section. + + * BLOCK_CIPHER-MODE indicates the block cipher used and its mode of + operation + * n_b is the bit-size of the block for the block cipher + * k_e is the session encryption key + * n_e is the bit-length of k_e + * k_s is the session salting key + * n_s is the bit-length of k_s + * SRTP_PREFIX_LENGTH is the octet length of the keystream prefix, a + non-negative integer, specified by the message authentication code + in use. + + The distinct session keys and salts for SRTP/SRTCP are by default + derived as specified in Section 4.3. + + The encryption transforms defined in SRTP map the SRTP packet index + and secret key into a pseudo-random keystream segment. Each + keystream segment encrypts a single RTP packet. The process of + encrypting a packet consists of generating the keystream segment + corresponding to the packet, and then bitwise exclusive-oring that + keystream segment onto the payload of the RTP packet to produce the + Encrypted Portion of the SRTP packet. In case the payload size is + not an integer multiple of n_b bits, the excess (least significant) + bits of the keystream are simply discarded. Decryption is done the + same way, but swapping the roles of the plaintext and ciphertext. + + + +Baugher, et al. Standards Track [Page 19] + +RFC 3711 SRTP March 2004 + + + +----+ +------------------+---------------------------------+ + | KG |-->| Keystream Prefix | Keystream Suffix |---+ + +----+ +------------------+---------------------------------+ | + | + +---------------------------------+ v + | Payload of RTP Packet |->(*) + +---------------------------------+ | + | + +---------------------------------+ | + | Encrypted Portion of SRTP Packet|<--+ + +---------------------------------+ + + Figure 3: Default SRTP Encryption Processing. Here KG denotes the + keystream generator, and (*) denotes bitwise exclusive-or. + + The definition of how the keystream is generated, given the index, + depends on the cipher and its mode of operation. Below, two such + keystream generators are defined. The NULL cipher is also defined, + to be used when encryption of RTP is not required. + + The SRTP definition of the keystream is illustrated in Figure 3. The + initial octets of each keystream segment MAY be reserved for use in a + message authentication code, in which case the keystream used for + encryption starts immediately after the last reserved octet. The + initial reserved octets are called the "keystream prefix" (not to be + confused with the "encryption prefix" of [RFC3550, Section 6.1]), and + the remaining octets are called the "keystream suffix". The + keystream prefix MUST NOT be used for encryption. The process is + illustrated in Figure 3. + + The number of octets in the keystream prefix is denoted as + SRTP_PREFIX_LENGTH. The keystream prefix is indicated by a positive, + non-zero value of SRTP_PREFIX_LENGTH. This means that, even if + confidentiality is not to be provided, the keystream generator output + may still need to be computed for packet authentication, in which + case the default keystream generator (mode) SHALL be used. + + The default cipher is the Advanced Encryption Standard (AES) [AES], + and we define two modes of running AES, (1) Segmented Integer Counter + Mode AES and (2) AES in f8-mode. In the remainder of this section, + let E(k,x) be AES applied to key k and input block x. + + + + + + + + + + +Baugher, et al. Standards Track [Page 20] + +RFC 3711 SRTP March 2004 + + +4.1.1. AES in Counter Mode + + Conceptually, counter mode [AES-CTR] consists of encrypting + successive integers. The actual definition is somewhat more + complicated, in order to randomize the starting point of the integer + sequence. Each packet is encrypted with a distinct keystream + segment, which SHALL be computed as follows. + + A keystream segment SHALL be the concatenation of the 128-bit output + blocks of the AES cipher in the encrypt direction, using key k = k_e, + in which the block indices are in increasing order. Symbolically, + each keystream segment looks like + + E(k, IV) || E(k, IV + 1 mod 2^128) || E(k, IV + 2 mod 2^128) ... + + where the 128-bit integer value IV SHALL be defined by the SSRC, the + SRTP packet index i, and the SRTP session salting key k_s, as below. + + IV = (k_s * 2^16) XOR (SSRC * 2^64) XOR (i * 2^16) + + Each of the three terms in the XOR-sum above is padded with as many + leading zeros as needed to make the operation well-defined, + considered as a 128-bit value. + + The inclusion of the SSRC allows the use of the same key to protect + distinct SRTP streams within the same RTP session, see the security + caveats in Section 9.1. + + In the case of SRTCP, the SSRC of the first header of the compound + packet MUST be used, i SHALL be the 31-bit SRTCP index and k_e, k_s + SHALL be replaced by the SRTCP encryption session key and salt. + + Note that the initial value, IV, is fixed for each packet and is + formed by "reserving" 16 zeros in the least significant bits for the + purpose of the counter. The number of blocks of keystream generated + for any fixed value of IV MUST NOT exceed 2^16 to avoid keystream + re-use, see below. The AES has a block size of 128 bits, so 2^16 + output blocks are sufficient to generate the 2^23 bits of keystream + needed to encrypt the largest possible RTP packet (except for IPv6 + "jumbograms" [RFC2675], which are not likely to be used for RTP-based + multimedia traffic). This restriction on the maximum bit-size of the + packet that can be encrypted ensures the security of the encryption + method by limiting the effectiveness of probabilistic attacks [BDJR]. + + For a particular Counter Mode key, each IV value used as an input + MUST be distinct, in order to avoid the security exposure of a two- + time pad situation (Section 9.1). To satisfy this constraint, an + implementation MUST ensure that the combination of the SRTP packet + + + +Baugher, et al. Standards Track [Page 21] + +RFC 3711 SRTP March 2004 + + + index of ROC || SEQ, and the SSRC used in the construction of the IV + are distinct for any particular key. The failure to ensure this + uniqueness could be catastrophic for Secure RTP. This is in contrast + to the situation for RTP itself, which may be able to tolerate such + failures. It is RECOMMENDED that, if a dedicated security module is + present, the RTP sequence numbers and SSRC either be generated or + checked by that module (i.e., sequence-number and SSRC processing in + an SRTP system needs to be protected as well as the key). + +4.1.2. AES in f8-mode + + To encrypt UMTS (Universal Mobile Telecommunications System, as 3G + networks) data, a solution (see [f8-a] [f8-b]) known as the f8- + algorithm has been developed. On a high level, the proposed scheme + is a variant of Output Feedback Mode (OFB) [HAC], with a more + elaborate initialization and feedback function. As in normal OFB, + the core consists of a block cipher. We also define here the use of + AES as a block cipher to be used in what we shall call "f8-mode of + operation" RTP encryption. The AES f8-mode SHALL use the same + default sizes for session key and salt as AES counter mode. + + Figure 4 shows the structure of block cipher, E, running in f8-mode. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Baugher, et al. Standards Track [Page 22] + +RFC 3711 SRTP March 2004 + + + IV + | + v + +------+ + | | + +--->| E | + | +------+ + | | + m -> (*) +-----------+-------------+-- ... ------+ + | IV' | | | | + | | j=1 -> (*) j=2 -> (*) ... j=L-1 ->(*) + | | | | | + | | +-> (*) +-> (*) ... +-> (*) + | | | | | | | | + | v | v | v | v + | +------+ | +------+ | +------+ | +------+ + k_e ---+--->| E | | | E | | | E | | | E | + | | | | | | | | | | | + +------+ | +------+ | +------+ | +------+ + | | | | | | | + +------+ +--------+ +-- ... ----+ | + | | | | + v v v v + S(0) S(1) S(2) . . . S(L-1) + + Figure 4. f8-mode of operation (asterisk, (*), denotes bitwise XOR). + The figure represents the KG in Figure 3, when AES-f8 is used. + +4.1.2.1. f8 Keystream Generation + + The Initialization Vector (IV) SHALL be determined as described in + Section 4.1.2.2 (and in Section 4.1.2.3 for SRTCP). + + Let IV', S(j), and m denote n_b-bit blocks. The keystream, + S(0) ||... || S(L-1), for an N-bit message SHALL be defined by + setting IV' = E(k_e XOR m, IV), and S(-1) = 00..0. For + j = 0,1,..,L-1 where L = N/n_b (rounded up to nearest integer if it + is not already an integer) compute + + S(j) = E(k_e, IV' XOR j XOR S(j-1)) + + Notice that the IV is not used directly. Instead it is fed through E + under another key to produce an internal, "masked" value (denoted + IV') to prevent an attacker from gaining known input/output pairs. + + + + + + + +Baugher, et al. Standards Track [Page 23] + +RFC 3711 SRTP March 2004 + + + The role of the internal counter, j, is to prevent short keystream + cycles. The value of the key mask m SHALL be + + m = k_s || 0x555..5, + + i.e., the session salting key, appended by the binary pattern 0101.. + to fill out the entire desired key size, n_e. + + The sender SHOULD NOT generate more than 2^32 blocks, which is + sufficient to generate 2^39 bits of keystream. Unlike counter mode, + there is no absolute threshold above (below) which f8 is guaranteed + to be insecure (secure). The above bound has been chosen to limit, + with sufficient security margin, the probability of degenerative + behavior in the f8 keystream generation. + +4.1.2.2. f8 SRTP IV Formation + + The purpose of the following IV formation is to provide a feature + which we call implicit header authentication (IHA), see Section 9.5. + + The SRTP IV for 128-bit block AES-f8 SHALL be formed in the following + way: + + IV = 0x00 || M || PT || SEQ || TS || SSRC || ROC + + M, PT, SEQ, TS, SSRC SHALL be taken from the RTP header; ROC is from + the cryptographic context. + + The presence of the SSRC as part of the IV allows AES-f8 to be used + when a master key is shared between multiple streams within the same + RTP session, see Section 9.1. + +4.1.2.3. f8 SRTCP IV Formation + + The SRTCP IV for 128-bit block AES-f8 SHALL be formed in the + following way: + + IV= 0..0 || E || SRTCP index || V || P || RC || PT || length || SSRC + + where V, P, RC, PT, length, SSRC SHALL be taken from the first header + in the RTCP compound packet. E and SRTCP index are the 1-bit and + 31-bit fields added to the packet. + + + + + + + + + +Baugher, et al. Standards Track [Page 24] + +RFC 3711 SRTP March 2004 + + +4.1.3. NULL Cipher + + The NULL cipher is used when no confidentiality for RTP/RTCP is + requested. The keystream can be thought of as "000..0", i.e., the + encryption SHALL simply copy the plaintext input into the ciphertext + output. + +4.2. Message Authentication and Integrity + + Throughout this section, M will denote data to be integrity + protected. In the case of SRTP, M SHALL consist of the Authenticated + Portion of the packet (as specified in Figure 1) concatenated with + the ROC, M = Authenticated Portion || ROC; in the case of SRTCP, M + SHALL consist of the Authenticated Portion (as specified in Figure 2) + only. + + Common parameters: + + * AUTH_ALG is the authentication algorithm + * k_a is the session message authentication key + * n_a is the bit-length of the authentication key + * n_tag is the bit-length of the output authentication tag + * SRTP_PREFIX_LENGTH is the octet length of the keystream prefix as + defined above, a parameter of AUTH_ALG + + The distinct session authentication keys for SRTP/SRTCP are by + default derived as specified in Section 4.3. + + The values of n_a, n_tag, and SRTP_PREFIX_LENGTH MUST be fixed for + any particular fixed value of the key. + + We describe the process of computing authentication tags as follows. + The sender computes the tag of M and appends it to the packet. The + SRTP receiver verifies a message/authentication tag pair by computing + a new authentication tag over M using the selected algorithm and key, + and then compares it to the tag associated with the received message. + If the two tags are equal, then the message/tag pair is valid; + otherwise, it is invalid and the error audit message "AUTHENTICATION + FAILURE" MUST be returned. + +4.2.1. HMAC-SHA1 + + The pre-defined authentication transform for SRTP is HMAC-SHA1 + [RFC2104]. With HMAC-SHA1, the SRTP_PREFIX_LENGTH (Figure 3) SHALL + be 0. For SRTP (respectively SRTCP), the HMAC SHALL be applied to + the session authentication key and M as specified above, i.e., + HMAC(k_a, M). The HMAC output SHALL then be truncated to the n_tag + left-most bits. + + + +Baugher, et al. Standards Track [Page 25] + +RFC 3711 SRTP March 2004 + + +4.3. Key Derivation + +4.3.1. Key Derivation Algorithm + + Regardless of the encryption or message authentication transform that + is employed (it may be an SRTP pre-defined transform or newly + introduced according to Section 6), interoperable SRTP + implementations MUST use the SRTP key derivation to generate session + keys. Once the key derivation rate is properly signaled at the start + of the session, there is no need for extra communication between the + parties that use SRTP key derivation. + + packet index ---+ + | + v + +-----------+ master +--------+ session encr_key + | ext | key | |----------> + | key mgmt |-------->| key | session auth_key + | (optional | | deriv |----------> + | rekey) |-------->| | session salt_key + | | master | |----------> + +-----------+ salt +--------+ + + Figure 5: SRTP key derivation. + + At least one initial key derivation SHALL be performed by SRTP, i.e., + the first key derivation is REQUIRED. Further applications of the + key derivation MAY be performed, according to the + "key_derivation_rate" value in the cryptographic context. The key + derivation function SHALL initially be invoked before the first + packet and then, when r > 0, a key derivation is performed whenever + index mod r equals zero. This can be thought of as "refreshing" the + session keys. The value of "key_derivation_rate" MUST be kept fixed + for the lifetime of the associated master key. + + Interoperable SRTP implementations MAY also derive session salting + keys for encryption transforms, as is done in both of the pre- + defined transforms. + + Let m and n be positive integers. A pseudo-random function family is + a set of keyed functions {PRF_n(k,x)} such that for the (secret) + random key k, given m-bit x, PRF_n(k,x) is an n-bit string, + computationally indistinguishable from random n-bit strings, see + [HAC]. For the purpose of key derivation in SRTP, a secure PRF with + m = 128 (or more) MUST be used, and a default PRF transform is + defined in Section 4.3.3. + + + + + +Baugher, et al. Standards Track [Page 26] + +RFC 3711 SRTP March 2004 + + + Let "a DIV t" denote integer division of a by t, rounded down, and + with the convention that "a DIV 0 = 0" for all a. We also make the + convention of treating "a DIV t" as a bit string of the same length + as a, and thus "a DIV t" will in general have leading zeros. + + Key derivation SHALL be defined as follows in terms of <label>, an + 8-bit constant (see below), master_salt and key_derivation_rate, as + determined in the cryptographic context, and index, the packet index + (i.e., the 48-bit ROC || SEQ for SRTP): + + * Let r = index DIV key_derivation_rate (with DIV as defined above). + + * Let key_id = <label> || r. + + * Let x = key_id XOR master_salt, where key_id and master_salt are + aligned so that their least significant bits agree (right- + alignment). + + <label> MUST be unique for each type of key to be derived. We + currently define <label> 0x00 to 0x05 (see below), and future + extensions MAY specify new values in the range 0x06 to 0xff for other + purposes. The n-bit SRTP key (or salt) for this packet SHALL then be + derived from the master key, k_master as follows: + + PRF_n(k_master, x). + + (The PRF may internally specify additional formatting and padding of + x, see e.g., Section 4.3.3 for the default PRF.) + + The session keys and salt SHALL now be derived using: + + - k_e (SRTP encryption): <label> = 0x00, n = n_e. + + - k_a (SRTP message authentication): <label> = 0x01, n = n_a. + + - k_s (SRTP salting key): <label> = 0x02, n = n_s. + + where n_e, n_s, and n_a are from the cryptographic context. + + The master key and master salt MUST be random, but the master salt + MAY be public. + + Note that for a key_derivation_rate of 0, the application of the key + derivation SHALL take place exactly once. + + The definition of DIV above is purely for notational convenience. + For a non-zero t among the set of allowed key derivation rates, "a + DIV t" can be implemented as a right-shift by the base-2 logarithm of + + + +Baugher, et al. Standards Track [Page 27] + +RFC 3711 SRTP March 2004 + + + t. The derivation operation is further facilitated if the rates are + chosen to be powers of 256, but that granularity was considered too + coarse to be a requirement of this specification. + + The upper limit on the number of packets that can be secured using + the same master key (see Section 9.2) is independent of the key + derivation. + +4.3.2. SRTCP Key Derivation + + SRTCP SHALL by default use the same master key (and master salt) as + SRTP. To do this securely, the following changes SHALL be done to + the definitions in Section 4.3.1 when applying session key derivation + for SRTCP. + + Replace the SRTP index by the 32-bit quantity: 0 || SRTCP index + (i.e., excluding the E-bit, replacing it with a fixed 0-bit), and use + <label> = 0x03 for the SRTCP encryption key, <label> = 0x04 for the + SRTCP authentication key, and, <label> = 0x05 for the SRTCP salting + key. + +4.3.3. AES-CM PRF + + The currently defined PRF, keyed by 128, 192, or 256 bit master key, + has input block size m = 128 and can produce n-bit outputs for n up + to 2^23. PRF_n(k_master,x) SHALL be AES in Counter Mode as described + in Section 4.1.1, applied to key k_master, and IV equal to (x*2^16), + and with the output keystream truncated to the n first (left-most) + bits. (Requiring n/128, rounded up, applications of AES.) + +5. Default and mandatory-to-implement Transforms + + The default transforms also are mandatory-to-implement transforms in + SRTP. Of course, "mandatory-to-implement" does not imply + "mandatory-to-use". Table 1 summarizes the pre-defined transforms. + The default values below are valid for the pre-defined transforms. + + mandatory-to-impl. optional default + + encryption AES-CM, NULL AES-f8 AES-CM + message integrity HMAC-SHA1 - HMAC-SHA1 + key derivation (PRF) AES-CM - AES-CM + + Table 1: Mandatory-to-implement, optional and default transforms in + SRTP and SRTCP. + + + + + + +Baugher, et al. Standards Track [Page 28] + +RFC 3711 SRTP March 2004 + + +5.1. Encryption: AES-CM and NULL + + AES running in Segmented Integer Counter Mode, as defined in Section + 4.1.1, SHALL be the default encryption algorithm. The default key + lengths SHALL be 128-bit for the session encryption key (n_e). The + default session salt key-length (n_s) SHALL be 112 bits. + + The NULL cipher SHALL also be mandatory-to-implement. + +5.2. Message Authentication/Integrity: HMAC-SHA1 + + HMAC-SHA1, as defined in Section 4.2.1, SHALL be the default message + authentication code. The default session authentication key-length + (n_a) SHALL be 160 bits, the default authentication tag length + (n_tag) SHALL be 80 bits, and the SRTP_PREFIX_LENGTH SHALL be zero + for HMAC-SHA1. In addition, for SRTCP, the pre-defined HMAC-SHA1 + MUST NOT be applied with a value of n_tag, nor n_a, that are smaller + than these defaults. For SRTP, smaller values are NOT RECOMMENDED, + but MAY be used after careful consideration of the issues in Section + 7.5 and 9.5. + +5.3. Key Derivation: AES-CM PRF + + The AES Counter Mode based key derivation and PRF defined in Sections + 4.3.1 to 4.3.3, using a 128-bit master key, SHALL be the default + method for generating session keys. The default master salt length + SHALL be 112 bits and the default key-derivation rate SHALL be zero. + +6. Adding SRTP Transforms + + Section 4 provides examples of the level of detail needed for + defining transforms. Whenever a new transform is to be added to + SRTP, a companion standard track RFC MUST be written to exactly + define how the new transform can be used with SRTP (and SRTCP). Such + a companion RFC SHOULD avoid overlap with the SRTP protocol document. + Note however, that it MAY be necessary to extend the SRTP or SRTCP + cryptographic context definition with new parameters (including fixed + or default values), add steps to the packet processing, or even add + fields to the SRTP/SRTCP packets. The companion RFC SHALL explain + any known issues regarding interactions between the transform and + other aspects of SRTP. + + Each new transform document SHOULD specify its key attributes, e.g., + size of keys (minimum, maximum, recommended), format of keys, + recommended/required processing of input keying material, + requirements/recommendations on key lifetime, re-keying and key + derivation, whether sharing of keys between SRTP and SRTCP is allowed + or not, etc. + + + +Baugher, et al. Standards Track [Page 29] + +RFC 3711 SRTP March 2004 + + + An added message integrity transform SHOULD define a minimum + acceptable key/tag size for SRTCP, equivalent in strength to the + minimum values as defined in Section 5.2. + +7. Rationale + + This section explains the rationale behind several important features + of SRTP. + +7.1. Key derivation + + Key derivation reduces the burden on the key establishment. As many + as six different keys are needed per crypto context (SRTP and SRTCP + encryption keys and salts, SRTP and SRTCP authentication keys), but + these are derived from a single master key in a cryptographically + secure way. Thus, the key management protocol needs to exchange only + one master key (plus master salt when required), and then SRTP itself + derives all the necessary session keys (via the first, mandatory + application of the key derivation function). + + Multiple applications of the key derivation function are optional, + but will give security benefits when enabled. They prevent an + attacker from obtaining large amounts of ciphertext produced by a + single fixed session key. If the attacker was able to collect a + large amount of ciphertext for a certain session key, he might be + helped in mounting certain attacks. + + Multiple applications of the key derivation function provide + backwards and forward security in the sense that a compromised + session key does not compromise other session keys derived from the + same master key. This means that the attacker who is able to recover + a certain session key, is anyway not able to have access to messages + secured under previous and later session keys (derived from the same + master key). (Note that, of course, a leaked master key reveals all + the session keys derived from it.) + + Considerations arise with high-rate key refresh, especially in large + multicast settings, see Section 11. + +7.2. Salting key + + The master salt guarantees security against off-line key-collision + attacks on the key derivation that might otherwise reduce the + effective key size [MF00]. + + + + + + + +Baugher, et al. Standards Track [Page 30] + +RFC 3711 SRTP March 2004 + + + The derived session salting key used in the encryption, has been + introduced to protect against some attacks on additive stream + ciphers, see Section 9.2. The explicit inclusion method of the salt + in the IV has been selected for ease of hardware implementation. + +7.3. Message Integrity from Universal Hashing + + The particular definition of the keystream given in Section 4.1 (the + keystream prefix) is to give provision for particular universal hash + functions, suitable for message authentication in the Wegman-Carter + paradigm [WC81]. Such functions are provably secure, simple, quick, + and especially appropriate for Digital Signal Processors and other + processors with a fast multiply operation. + + No authentication transforms are currently provided in SRTP other + than HMAC-SHA1. Future transforms, like the above mentioned + universal hash functions, MAY be added following the guidelines in + Section 6. + +7.4. Data Origin Authentication Considerations + + Note that in pair-wise communications, integrity and data origin + authentication are provided together. However, in group scenarios + where the keys are shared between members, the MAC tag only proves + that a member of the group sent the packet, but does not prevent + against a member impersonating another. Data origin authentication + (DOA) for multicast and group RTP sessions is a hard problem that + needs a solution; while some promising proposals are being + investigated [PCST1] [PCST2], more work is needed to rigorously + specify these technologies. Thus SRTP data origin authentication in + groups is for further study. + + DOA can be done otherwise using signatures. However, this has high + impact in terms of bandwidth and processing time, therefore we do not + offer this form of authentication in the pre-defined packet-integrity + transform. + + The presence of mixers and translators does not allow data origin + authentication in case the RTP payload and/or the RTP header are + manipulated. Note that these types of middle entities also disrupt + end-to-end confidentiality (as the IV formation depends e.g., on the + RTP header preservation). A certain trust model may choose to trust + the mixers/translators to decrypt/re-encrypt the media (this would + imply breaking the end-to-end security, with related security + implications). + + + + + + +Baugher, et al. Standards Track [Page 31] + +RFC 3711 SRTP March 2004 + + +7.5. Short and Zero-length Message Authentication + + As shown in Figure 1, the authentication tag is RECOMMENDED in SRTP. + A full 80-bit authentication-tag SHOULD be used, but a shorter tag or + even a zero-length tag (i.e., no message authentication) MAY be used + under certain conditions to support either of the following two + application environments. + + 1. Strong authentication can be impractical in environments where + bandwidth preservation is imperative. An important special + case is wireless communication systems, in which bandwidth is a + scarce and expensive resource. Studies have shown that for + certain applications and link technologies, additional bytes + may result in a significant decrease in spectrum efficiency + [SWO]. Considerable effort has been made to design IP header + compression techniques to improve spectrum efficiency + [RFC3095]. A typical voice application produces 20 byte + samples, and the RTP, UDP and IP headers need to be jointly + compressed to one or two bytes on average in order to obtain + acceptable wireless bandwidth economy [RFC3095]. In this case, + strong authentication would impose nearly fifty percent + overhead. + + 2. Authentication is impractical for applications that use data + links with fixed-width fields that cannot accommodate the + expansion due to the authentication tag. This is the case for + some important existing wireless channels. For example, zero- + byte header compression is used to adapt EVRC/SMV voice with + the legacy IS-95 bearer channel in CDMA2000 VoIP services. It + was found that not a single additional octet could be added to + the data, which motivated the creation of a zero-byte profile + for ROHC [RFC3242]. + + A short tag is secure for a restricted set of applications. Consider + a voice telephony application, for example, such as a G.729 audio + codec with a 20-millisecond packetization interval, protected by a + 32-bit message authentication tag. The likelihood of any given + packet being successfully forged is only one in 2^32. Thus an + adversary can control no more than 20 milliseconds of audio output + during a 994-day period, on average. In contrast, the effect of a + single forged packet can be much larger if the application is + stateful. A codec that uses relative or predictive compression + across packets will propagate the maliciously generated state, + affecting a longer duration of output. + + + + + + + +Baugher, et al. Standards Track [Page 32] + +RFC 3711 SRTP March 2004 + + + Certainly not all SRTP or telephony applications meet the criteria + for short or zero-length authentication tags. Section 9.5.1 + discusses the risks of weak or no message authentication, and section + 9.5 describes the circumstances when it is acceptable and when it is + unacceptable. + +8. Key Management Considerations + + There are emerging key management standards [MIKEY] [KEYMGT] [SDMS] + for establishing an SRTP cryptographic context (e.g., an SRTP master + key). Both proprietary and open-standard key management methods are + likely to be used for telephony applications [MIKEY] [KINK] and + multicast applications [GDOI]. This section provides guidance for + key management systems that service SRTP session. + + For initialization, an interoperable SRTP implementation SHOULD be + given the SSRC and MAY be given the initial RTP sequence number for + the RTP stream by key management (thus, key management has a + dependency on RTP operational parameters). Sending the RTP sequence + number in the key management may be useful e.g., when the initial + sequence number is close to wrapping (to avoid synchronization + problems), and to communicate the current sequence number to a + joining endpoint (to properly initialize its replay list). + + If the pre-defined transforms are used, SRTP allows sharing of the + same master key between SRTP/SRTCP streams belonging to the same RTP + session. + + First, sharing between SRTP streams belonging to the same RTP session + is secure if the design of the synchronization mechanism, i.e., the + IV, avoids keystream re-use (the two-time pad, Section 9.1). This is + taken care of by the fact that RTP provides for unique SSRCs for + streams belonging to the same RTP session. See Section 9.1 for + further discussion. + + Second, sharing between SRTP and the corresponding SRTCP is secure. + The fact that an SRTP stream and its associated SRTCP stream both + carry the same SSRC does not constitute a problem for the two-time + pad due to the key derivation. Thus, SRTP and SRTCP corresponding to + one RTP session MAY share master keys (as they do by default). + + Note that message authentication also has a dependency on SSRC + uniqueness that is unrelated to the problem of keystream reuse: SRTP + streams authenticated under the same key MUST have a distinct SSRC in + order to identify the sender of the message. This requirement is + needed because the SSRC is the cryptographically authenticated field + + + + + +Baugher, et al. Standards Track [Page 33] + +RFC 3711 SRTP March 2004 + + + used to distinguish between different SRTP streams. Were two streams + to use identical SSRC values, then an adversary could substitute + messages from one stream into the other without detection. + + SRTP/SRTCP MUST NOT share master keys under any other circumstances + than the ones given above, i.e., between SRTP and its corresponding + SRTCP, and, between streams belonging to the same RTP session. + +8.1. Re-keying + + The recommended way for a particular key management system to provide + re-key within SRTP is by associating a master key in a crypto context + with an MKI. + + This provides for easy master key retrieval (see Scenarios in Section + 11), but has the disadvantage of adding extra bits to each packet. + As noted in Section 7.5, some wireless links do not cater for added + bits, therefore SRTP also defines a more economic way of triggering + re-keying, via use of <From, To>, which works in some specific, + simple scenarios (see Section 8.1.1). + + SRTP senders SHALL count the amount of SRTP and SRTCP traffic being + used for a master key and invoke key management to re-key if needed + (Section 9.2). These interactions are defined by the key management + interface to SRTP and are not defined by this protocol specification. + +8.1.1. Use of the <From, To> for re-keying + + In addition to the use of the MKI, SRTP defines another optional + mechanism for master key retrieval, the <From, To>. The <From, To> + specifies the range of SRTP indices (a pair of sequence number and + ROC) within which a certain master key is valid, and is (when used) + part of the crypto context. By looking at the 48-bit SRTP index of + the current SRTP packet, the corresponding master key can be found by + determining which From-To interval it belongs to. For SRTCP, the + most recently observed/used SRTP index (which can be obtained from + the cryptographic context) is used for this purpose, even though + SRTCP has its own (31-bit) index (see caveat below). + + This method, compared to the MKI, has the advantage of identifying + the master key and defining its lifetime without adding extra bits to + each packet. This could be useful, as already noted, for some + wireless links that do not cater for added bits. However, its use + SHOULD be limited to specific, very simple scenarios. We recommend + to limit its use when the RTP session is a simple unidirectional or + bi-directional stream. This is because in case of multiple streams, + it is difficult to trigger the re-key based on the <From, To> of a + single RTP stream. For example, if several streams share a master + + + +Baugher, et al. Standards Track [Page 34] + +RFC 3711 SRTP March 2004 + + + key, there is no simple one-to-one correspondence between the index + sequence space of a certain stream, and the index sequence space on + which the <From, To> values are based. Consequently, when a master + key is shared between streams, one of these streams MUST be + designated by key management as the one whose index space defines the + re-keying points. Also, the re-key triggering on SRTCP is based on + the correspondent SRTP stream, i.e., when the SRTP stream changes the + master key, so does the correspondent SRTCP. This becomes obviously + more and more complex with multiple streams. + + The default values for the <From, To> are "from the first observed + packet" and "until further notice". However, the maximum limit of + SRTP/SRTCP packets that are sent under each given master/session key + (Section 9.2) MUST NOT be exceeded. + + In case the <From, To> is used as key retrieval, then the MKI is not + inserted in the packet (and its indicator in the crypto context is + zero). However, using the MKI does not exclude using <From, To> key + lifetime simultaneously. This can for instance be useful to signal + at the sender side at which point in time an MKI is to be made + active. + +8.2. Key Management parameters + + The table below lists all SRTP parameters that key management can + supply. For reference, it also provides a summary of the default and + mandatory-to-support values for an SRTP implementation as described + in Section 5. + + + + + + + + + + + + + + + + + + + + + + + +Baugher, et al. Standards Track [Page 35] + +RFC 3711 SRTP March 2004 + + + Parameter Mandatory-to-support Default + --------- -------------------- ------- + + SRTP and SRTCP encr transf. AES_CM, NULL AES_CM + (Other possible values: AES_f8) + + SRTP and SRTCP auth transf. HMAC-SHA1 HMAC-SHA1 + + SRTP and SRTCP auth params: + n_tag (tag length) 80 80 + SRTP prefix_length 0 0 + + Key derivation PRF AES_CM AES_CM + + Key material params + (for each master key): + master key length 128 128 + n_e (encr session key length) 128 128 + n_a (auth session key length) 160 160 + master salt key + length of the master salt 112 112 + n_s (session salt key length) 112 112 + key derivation rate 0 0 + + key lifetime + SRTP-packets-max-lifetime 2^48 2^48 + SRTCP-packets-max-lifetime 2^31 2^31 + from-to-lifetime <From, To> + MKI indicator 0 0 + length of the MKI 0 0 + value of the MKI + + Crypto context index params: + SSRC value + ROC + SEQ + SRTCP Index + Transport address + Port number + + Relation to other RTP profiles: + sender's order between FEC and SRTP FEC-SRTP FEC-SRTP + (see Section 10) + + + + + + + + +Baugher, et al. Standards Track [Page 36] + +RFC 3711 SRTP March 2004 + + +9. Security Considerations + +9.1. SSRC collision and two-time pad + + Any fixed keystream output, generated from the same key and index + MUST only be used to encrypt once. Re-using such keystream (jokingly + called a "two-time pad" system by cryptographers), can seriously + compromise security. The NSA's VENONA project [C99] provides a + historical example of such a compromise. It is REQUIRED that + automatic key management be used for establishing and maintaining + SRTP and SRTCP keying material; this requirement is to avoid + keystream reuse, which is more likely to occur with manual key + management. Furthermore, in SRTP, a "two-time pad" is avoided by + requiring the key, or some other parameter of cryptographic + significance, to be unique per RTP/RTCP stream and packet. The pre- + defined SRTP transforms accomplish packet-uniqueness by including the + packet index and stream-uniqueness by inclusion of the SSRC. + + The pre-defined transforms (AES-CM and AES-f8) allow master keys to + be shared across streams belonging to the same RTP session by the + inclusion of the SSRC in the IV. A master key MUST NOT be shared + among different RTP sessions. + + Thus, the SSRC MUST be unique between all the RTP streams within the + same RTP session that share the same master key. RTP itself provides + an algorithm for detecting SSRC collisions within the same RTP + session. Thus, temporary collisions could lead to temporary two-time + pad, in the unfortunate event that SSRCs collide at a point in time + when the streams also have identical sequence numbers (occurring with + probability roughly 2^(-48)). Therefore, the key management SHOULD + take care of avoiding such SSRC collisions by including the SSRCs to + be used in the session as negotiation parameters, proactively + assuring their uniqueness. This is a strong requirements in + scenarios where for example, there are multiple senders that can + start to transmit simultaneously, before SSRC collision are detected + at the RTP level. + + Note also that even with distinct SSRCs, extensive use of the same + key might improve chances of probabilistic collision and time- + memory-tradeoff attacks succeeding. + + As described, master keys MAY be shared between streams belonging to + the same RTP session, but it is RECOMMENDED that each SSRC have its + own master key. When master keys are shared among SSRC participants + and SSRCs are managed by a key management module as recommended + above, the RECOMMENDED policy for an SSRC collision error is for the + participant to leave the SRTP session as it is a sign of malfunction. + + + + +Baugher, et al. Standards Track [Page 37] + +RFC 3711 SRTP March 2004 + + +9.2. Key Usage + + The effective key size is determined (upper bounded) by the size of + the master key and, for encryption, the size of the salting key. Any + additive stream cipher is vulnerable to attacks that use statistical + knowledge about the plaintext source to enable key collision and + time-memory tradeoff attacks [MF00] [H80] [BS00]. These attacks take + advantage of commonalities among plaintexts, and provide a way for a + cryptanalyst to amortize the computational effort of decryption over + many keys, or over many bytes of output, thus reducing the effective + key size of the cipher. A detailed analysis of these attacks and + their applicability to the encryption of Internet traffic is provided + in [MF00]. In summary, the effective key size of SRTP when used in a + security system in which m distinct keys are used, is equal to the + key size of the cipher less the logarithm (base two) of m. + Protection against such attacks can be provided simply by increasing + the size of the keys used, which here can be accomplished by the use + of the salting key. Note that the salting key MUST be random but MAY + be public. A salt size of (the suggested) size 112 bits protects + against attacks in scenarios where at most 2^112 keys are in use. + This is sufficient for all practical purposes. + + Implementations SHOULD use keys that are as large as possible. + Please note that in many cases increasing the key size of a cipher + does not affect the throughput of that cipher. + + The use of the SRTP and SRTCP indices in the pre-defined transforms + fixes the maximum number of packets that can be secured with the same + key. This limit is fixed to 2^48 SRTP packets for an SRTP stream, + and 2^31 SRTCP packets, when SRTP and SRTCP are considered + independently. Due to for example re-keying, reaching this limit may + or may not coincide with wrapping of the indices, and thus the sender + MUST keep packet counts. However, when the session keys for related + SRTP and SRTCP streams are derived from the same master key (the + default behavior, Section 4.3), the upper bound that has to be + considered is in practice the minimum of the two quantities. That + is, when 2^48 SRTP packets or 2^31 SRTCP packets have been secured + with the same key (whichever occurs before), the key management MUST + be called to provide new master key(s) (previously stored and used + keys MUST NOT be used again), or the session MUST be terminated. If + a sender of RTCP discovers that the sender of SRTP (or SRTCP) has not + updated the master or session key prior to sending 2^48 SRTP (or 2^31 + SRTCP) packets belonging to the same SRTP (SRTCP) stream, it is up to + the security policy of the RTCP sender how to behave, e.g., whether + an RTCP BYE-packet should be sent and/or if the event should be + logged. + + + + + +Baugher, et al. Standards Track [Page 38] + +RFC 3711 SRTP March 2004 + + + Note: in most typical applications (assuming at least one RTCP packet + for every 128,000 RTP packets), it will be the SRTCP index that first + reaches the upper limit, although the time until this occurs is very + long: even at 200 SRTCP packets/sec, the 2^31 index space of SRTCP is + enough to secure approximately 4 months of communication. + + Note that if the master key is to be shared between SRTP streams + within the same RTP session (Section 9.1), although the above bounds + are on a per stream (i.e., per SSRC) basis, the sender MUST base re- + key decision on the stream whose sequence number space is the first + to be exhausted. + + Key derivation limits the amount of plaintext that is encrypted with + a fixed session key, and made available to an attacker for analysis, + but key derivation does not extend the master key's lifetime. To see + this, simply consider our requirements to avoid two-time pad: two + distinct packets MUST either be processed with distinct IVs, or with + distinct session keys, and both the distinctness of IV and of the + session keys are (for the pre-defined transforms) dependent on the + distinctness of the packet indices. + + Note that with the key derivation, the effective key size is at most + that of the master key, even if the derived session key is + considerably longer. With the pre-defined authentication transform, + the session authentication key is 160 bits, but the master key by + default is only 128 bits. This design choice was made to comply with + certain recommendations in [RFC2104] so that an existing HMAC + implementation can be plugged into SRTP without problems. Since the + default tag size is 80 bits, it is, for the applications in mind, + also considered acceptable from security point of view. Users having + concerns about this are RECOMMENDED to instead use a 192 bit master + key in the key derivation. It was, however, chosen not to mandate + 192-bit keys since existing AES implementations to be used in the + key-derivation may not always support key-lengths other than 128 + bits. Since AES is not defined (or properly analyzed) for use with + 160 bit keys it is NOT RECOMMENDED that ad-hoc key-padding schemes + are used to pad shorter keys to 192 or 256 bits. + +9.3. Confidentiality of the RTP Payload + + SRTP's pre-defined ciphers are "seekable" stream ciphers, i.e., + ciphers able to efficiently seek to arbitrary locations in their + keystream (so that the encryption or decryption of one packet does + not depend on preceding packets). By using seekable stream ciphers, + SRTP avoids the denial of service attacks that are possible on stream + ciphers that lack this property. It is important to be aware that, + as with any stream cipher, the exact length of the payload is + revealed by the encryption. This means that it may be possible to + + + +Baugher, et al. Standards Track [Page 39] + +RFC 3711 SRTP March 2004 + + + deduce certain "formatting bits" of the payload, as the length of the + codec output might vary due to certain parameter settings etc. This, + in turn, implies that the corresponding bit of the keystream can be + deduced. However, if the stream cipher is secure (counter mode and + f8 are provably secure under certain assumptions [BDJR] [KSYH] [IK]), + knowledge of a few bits of the keystream will not aid an attacker in + predicting subsequent keystream bits. Thus, the payload length (and + information deducible from this) will leak, but nothing else. + + As some RTP packet could contain highly predictable data, e.g., SID, + it is important to use a cipher designed to resist known plaintext + attacks (which is the current practice). + +9.4. Confidentiality of the RTP Header + + In SRTP, RTP headers are sent in the clear to allow for header + compression. This means that data such as payload type, + synchronization source identifier, and timestamp are available to an + eavesdropper. Moreover, since RTP allows for future extensions of + headers, we cannot foresee what kind of possibly sensitive + information might also be "leaked". + + SRTP is a low-cost method, which allows header compression to reduce + bandwidth. It is up to the endpoints' policies to decide about the + security protocol to employ. If one really needs to protect headers, + and is allowed to do so by the surrounding environment, then one + should also look at alternatives, e.g., IPsec [RFC2401]. + +9.5. Integrity of the RTP payload and header + + SRTP messages are subject to attacks on their integrity and source + identification, and these risks are discussed in Section 9.5.1. To + protect against these attacks, each SRTP stream SHOULD be protected + by HMAC-SHA1 [RFC2104] with an 80-bit output tag and a 160-bit key, + or a message authentication code with equivalent strength. Secure + RTP SHOULD NOT be used without message authentication, except under + the circumstances described in this section. It is important to note + that encryption algorithms, including AES Counter Mode and f8, do not + provide message authentication. SRTCP MUST NOT be used with weak (or + NULL) authentication. + + SRTP MAY be used with weak authentication (e.g., a 32-bit + authentication tag), or with no authentication (the NULL + authentication algorithm). These options allow SRTP to be used to + provide confidentiality in situations where + + * weak or null authentication is an acceptable security risk, and + * it is impractical to provide strong message authentication. + + + +Baugher, et al. Standards Track [Page 40] + +RFC 3711 SRTP March 2004 + + + These conditions are described below and in Section 7.5. Note that + both conditions MUST hold in order for weak or null authentication to + be used. The risks associated with exercising the weak or null + authentication options need to be considered by a security audit + prior to their use for a particular application or environment given + the risks, which are discussed in Section 9.5.1. + + Weak authentication is acceptable when the RTP application is such + that the effect of a small fraction of successful forgeries is + negligible. If the application is stateless, then the effect of a + single forged RTP packet is limited to the decoding of that + particular packet. Under this condition, the size of the + authentication tag MUST ensure that only a negligible fraction of the + packets passed to the RTP application by the SRTP receiver can be + forgeries. This fraction is negligible when an adversary, if given + control of the forged packets, is not able to make a significant + impact on the output of the RTP application (see the example of + Section 7.5). + + Weak or null authentication MAY be acceptable when it is unlikely + that an adversary can modify ciphertext so that it decrypts to an + intelligible value. One important case is when it is difficult for + an adversary to acquire the RTP plaintext data, since for many + codecs, an adversary that does not know the input signal cannot + manipulate the output signal in a controlled way. In many cases it + may be difficult for the adversary to determine the actual value of + the plaintext. For example, a hidden snooping device might be + required in order to know a live audio or video signal. The + adversary's signal must have a quality equivalent to or greater than + that of the signal under attack, since otherwise the adversary would + not have enough information to encode that signal with the codec used + by the victim. Plaintext prediction may also be especially difficult + for an interactive application such as a telephone call. + + Weak or null authentication MUST NOT be used when the RTP application + makes data forwarding or access control decisions based on the RTP + data. In such a case, an attacker may be able to subvert + confidentiality by causing the receiver to forward data to an + attacker. See Section 3 of [B96] for a real-life example of such + attacks. + + Null authentication MUST NOT be used when a replay attack, in which + an adversary stores packets then replays them later in the session, + could have a non-negligible impact on the receiver. An example of a + successful replay attack is the storing of the output of a + surveillance camera for a period of time, later followed by the + + + + + +Baugher, et al. Standards Track [Page 41] + +RFC 3711 SRTP March 2004 + + + injection of that output to the monitoring station to avoid + surveillance. Encryption does not protect against this attack, and + non-null authentication is REQUIRED in order to defeat it. + + If existential message forgery is an issue, i.e., when the accuracy + of the received data is of non-negligible importance, null + authentication MUST NOT be used. + +9.5.1. Risks of Weak or Null Message Authentication + + During a security audit considering the use of weak or null + authentication, it is important to keep in mind the following attacks + which are possible when no message authentication algorithm is used. + + An attacker who cannot predict the plaintext is still always able to + modify the message sent between the sender and the receiver so that + it decrypts to a random plaintext value, or to send a stream of bogus + packets to the receiver that will decrypt to random plaintext values. + This attack is essentially a denial of service attack, though in the + absence of message authentication, the RTP application will have + inputs that are bit-wise correlated with the true value. Some + multimedia codecs and common operating systems will crash when such + data are accepted as valid video data. This denial of service attack + may be a much larger threat than that due to an attacker dropping, + delaying, or re-ordering packets. + + An attacker who cannot predict the plaintext can still replay a + previous message with certainty that the receiver will accept it. + Applications with stateless codecs might be robust against this type + of attack, but for other, more complex applications these attacks may + be far more grave. + + An attacker who can predict the plaintext can modify the ciphertext + so that it will decrypt to any value of her choosing. With an + additive stream cipher, an attacker will always be able to change + individual bits. + + An attacker may be able to subvert confidentiality due to the lack of + authentication when a data forwarding or access control decision is + made on decrypted but unauthenticated plaintext. This is because the + receiver may be fooled into forwarding data to an attacker, leading + to an indirect breach of confidentiality (see Section 3 of [B96]). + This is because data-forwarding decisions are made on the decrypted + plaintext; information in the plaintext will determine to what subnet + (or process) the plaintext is forwarded in ESP [RFC2401] tunnel mode + (respectively, transport mode). When Secure RTP is used without + + + + + +Baugher, et al. Standards Track [Page 42] + +RFC 3711 SRTP March 2004 + + + message authentication, it should be verified that the application + does not make data forwarding or access control decisions based on + the decrypted plaintext. + + Some cipher modes of operation that require padding, e.g., standard + cipher block chaining (CBC) are very sensitive to attacks on + confidentiality if certain padding types are used in the absence of + integrity. The attack [V02] shows that this is indeed the case for + the standard RTP padding as discussed in reference to Figure 1, when + used together with CBC mode. Later transform additions to SRTP MUST + therefore carefully consider the risk of using this padding without + proper integrity protection. + +9.5.2. Implicit Header Authentication + + The IV formation of the f8-mode gives implicit authentication (IHA) + of the RTP header, even when message authentication is not used. + When IHA is used, an attacker that modifies the value of the RTP + header will cause the decryption process at the receiver to produce + random plaintext values. While this protection is not equivalent to + message authentication, it may be useful for some applications. + +10. Interaction with Forward Error Correction mechanisms + + The default processing when using Forward Error Correction (e.g., RFC + 2733) processing with SRTP SHALL be to perform FEC processing prior + to SRTP processing on the sender side and to perform SRTP processing + prior to FEC processing on the receiver side. Any change to this + ordering (reversing it, or, placing FEC between SRTP encryption and + SRTP authentication) SHALL be signaled out of band. + +11. Scenarios + + SRTP can be used as security protocol for the RTP/RTCP traffic in + many different scenarios. SRTP has a number of configuration + options, in particular regarding key usage, and can have impact on + the total performance of the application according to the way it is + used. Hence, the use of SRTP is dependent on the kind of scenario + and application it is used with. In the following, we briefly + illustrate some use cases for SRTP, and give some guidelines for + recommended setting of its options. + +11.1. Unicast + + A typical example would be a voice call or video-on-demand + application. + + + + + +Baugher, et al. Standards Track [Page 43] + +RFC 3711 SRTP March 2004 + + + Consider one bi-directional RTP stream, as one RTP session. It is + possible for the two parties to share the same master key in the two + directions according to the principles of Section 9.1. The first + round of the key derivation splits the master key into any or all of + the following session keys (according to the provided security + functions): + + SRTP_encr_key, SRTP_auth_key, SRTCP_encr_key, and SRTCP_auth key. + + (For simplicity, we omit discussion of the salts, which are also + derived.) In this scenario, it will in most cases suffice to have a + single master key with the default lifetime. This guarantees + sufficiently long lifetime of the keys and a minimum set of keys in + place for most practical purposes. Also, in this case RTCP + protection can be applied smoothly. Under these assumptions, use of + the MKI can be omitted. As the key-derivation in combination with + large difference in the packet rate in the respective directions may + require simultaneous storage of several session keys, if storage is + an issue, we recommended to use low-rate key derivation. + + The same considerations can be extended to the unicast scenario with + multiple RTP sessions, where each session would have a distinct + master key. + +11.2. Multicast (one sender) + + Just as with (unprotected) RTP, a scalability issue arises in big + groups due to the possibly very large amount of SRTCP Receiver + Reports that the sender might need to process. In SRTP, the sender + may have to keep state (the cryptographic context) for each receiver, + or more precisely, for the SRTCP used to protect Receiver Reports. + The overhead increases proportionally to the size of the group. In + particular, re-keying requires special concern, see below. + + Consider first a small group of receivers. There are a few possible + setups with the distribution of master keys among the receivers. + Given a single RTP session, one possibility is that the receivers + share the same master key as per Section 9.1 to secure all their + respective RTCP traffic. This shared master key could then be the + same one used by the sender to protect its outbound SRTP traffic. + Alternatively, it could be a master key shared only among the + receivers and used solely for their SRTCP traffic. Both alternatives + require the receivers to trust each other. + + Considering SRTCP and key storage, it is recommended to use low-rate + (or zero) key_derivation (except the mandatory initial one), so that + the sender does not need to store too many session keys (each SRTCP + stream might otherwise have a different session key at a given point + + + +Baugher, et al. Standards Track [Page 44] + +RFC 3711 SRTP March 2004 + + + in time, as the SRTCP sources send at different times). Thus, in + case key derivation is wanted for SRTP, the cryptographic context for + SRTP can be kept separate from the SRTCP crypto context, so that it + is possible to have a key_derivation_rate of 0 for SRTCP and a non- + zero value for SRTP. + + Use of the MKI for re-keying is RECOMMENDED for most applications + (see Section 8.1). + + If there are more than one SRTP/SRTCP stream (within the same RTP + session) that share the master key, the upper limit of 2^48 SRTP + packets / 2^31 SRTCP packets means that, before one of the streams + reaches its maximum number of packets, re-keying MUST be triggered on + ALL streams sharing the master key. (From strict security point of + view, only the stream reaching the maximum would need to be re-keyed, + but then the streams would no longer be sharing master key, which is + the intention.) A local policy at the sender side should force + rekeying in a way that the maximum packet limit is not reached on any + of the streams. Use of the MKI for re-keying is RECOMMENDED. + + In large multicast with one sender, the same considerations as for + the small group multicast hold. The biggest issue in this scenario + is the additional load placed at the sender side, due to the state + (cryptographic contexts) that has to be maintained for each receiver, + sending back RTCP Receiver Reports. At minimum, a replay window + might need to be maintained for each RTCP source. + +11.3. Re-keying and access control + + Re-keying may occur due to access control (e.g., when a member is + removed during a multicast RTP session), or for pure cryptographic + reasons (e.g., the key is at the end of its lifetime). When using + SRTP default transforms, the master key MUST be replaced before any + of the index spaces are exhausted for any of the streams protected by + one and the same master key. + + How key management re-keys SRTP implementations is out of scope, but + it is clear that there are straightforward ways to manage keys for a + multicast group. In one-sender multicast, for example, it is + typically the responsibility of the sender to determine when a new + key is needed. The sender is the one entity that can keep track of + when the maximum number of packets has been sent, as receivers may + join and leave the session at any time, there may be packet loss and + delay etc. In scenarios other than one-sender multicast, other + methods can be used. Here, one must take into consideration that key + exchange can be a costly operation, taking several seconds for a + single exchange. Hence, some time before the master key is + exhausted/expires, out-of-band key management is initiated, resulting + + + +Baugher, et al. Standards Track [Page 45] + +RFC 3711 SRTP March 2004 + + + in a new master key that is shared with the receiver(s). In any + event, to maintain synchronization when switching to the new key, + group policy might choose between using the MKI and the <From, To>, + as described in Section 8.1. + + For access control purposes, the <From, To> periods are set at the + desired granularity, dependent on the packet rate. High rate re- + keying can be problematic for SRTCP in some large-group scenarios. + As mentioned, there are potential problems in using the SRTP index, + rather than the SRTCP index, for determining the master key. In + particular, for short periods during switching of master keys, it may + be the case that SRTCP packets are not under the current master key + of the correspondent SRTP. Therefore, using the MKI for re-keying in + such scenarios will produce better results. + +11.4. Summary of basic scenarios + + The description of these scenarios highlights some recommendations on + the use of SRTP, mainly related to re-keying and large scale + multicast: + + - Do not use fast re-keying with the <From, To> feature. It may, in + particular, give problems in retrieving the correct SRTCP key, if + an SRTCP packet arrives close to the re-keying time. The MKI + SHOULD be used in this case. + + - If multiple SRTP streams in the same RTP session share the same + master key, also moderate rate re-keying MAY have the same + problems, and the MKI SHOULD be used. + + - Though offering increased security, a non-zero key_derivation_rate + is NOT RECOMMENDED when trying to minimize the number of keys in + use with multiple streams. + +12. IANA Considerations + + The RTP specification establishes a registry of profile names for use + by higher-level control protocols, such as the Session Description + Protocol (SDP), to refer to transport methods. This profile + registers the name "RTP/SAVP". + + SRTP uses cryptographic transforms which a key management protocol + signals. It is the task of each particular key management protocol + to register the cryptographic transforms or suites of transforms with + IANA. The key management protocol conveys these protocol numbers, + not SRTP, and each key management protocol chooses the numbering + scheme and syntax that it requires. + + + + +Baugher, et al. Standards Track [Page 46] + +RFC 3711 SRTP March 2004 + + + Specification of a key management protocol for SRTP is out of scope + here. Section 8.2, however, provides guidance on the parameters that + need to be defined for the default and mandatory transforms. + +13. Acknowledgements + + David Oran (Cisco) and Rolf Blom (Ericsson) are co-authors of this + document but their valuable contributions are acknowledged here to + keep the length of the author list down. + + The authors would in addition like to thank Magnus Westerlund, Brian + Weis, Ghyslain Pelletier, Morgan Lindqvist, Robert Fairlie- + Cuninghame, Adrian Perrig, the AVT WG and in particular the chairmen + Colin Perkins and Stephen Casner, the Transport and Security Area + Directors, and Eric Rescorla for their reviews and support. + +14. References + +14.1. Normative References + + [AES] NIST, "Advanced Encryption Standard (AES)", FIPS PUB 197, + http://www.nist.gov/aes/ + + [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed- + Hashing for Message Authentication", RFC 2104, February + 1997. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC2401] Kent, S. and R. Atkinson, "Security Architecture for + Internet Protocol", RFC 2401, November 1998. + + [RFC2828] Shirey, R., "Internet Security Glossary", FYI 36, RFC 2828, + May 2000. + + [RFC3550] Schulzrinne, H., Casner, S., Frederick, R. and V. Jacobson, + "RTP: A Transport Protocol for Real-time Applications", RFC + 3550, July 2003. + + [RFC3551] Schulzrinne, H. and S. Casner, "RTP Profile for Audio and + Video Conferences with Minimal Control", RFC 3551, July + 2003. + + + + + + + + +Baugher, et al. Standards Track [Page 47] + +RFC 3711 SRTP March 2004 + + +14.2. Informative References + + [AES-CTR] Lipmaa, H., Rogaway, P. and D. Wagner, "CTR-Mode + Encryption", NIST, http://csrc.nist.gov/encryption/modes/ + workshop1/papers/lipmaa-ctr.pdf + + [B96] Bellovin, S., "Problem Areas for the IP Security + Protocols," in Proceedings of the Sixth Usenix Unix + Security Symposium, pp. 1-16, San Jose, CA, July 1996 + (http://www.research.att.com/~smb/papers/index.html). + + [BDJR] Bellare, M., Desai, A., Jokipii, E. and P. Rogaway, "A + Concrete Treatment of Symmetric Encryption: Analysis of DES + Modes of Operation", Proceedings 38th IEEE FOCS, pp. 394- + 403, 1997. + + [BS00] Biryukov, A. and A. Shamir, "Cryptanalytic Time/Memory/Data + Tradeoffs for Stream Ciphers", Proceedings, ASIACRYPT 2000, + LNCS 1976, pp. 1-13, Springer Verlag. + + [C99] Crowell, W. P., "Introduction to the VENONA Project", + http://www.nsa.gov:8080/docs/venona/index.html. + + [CTR] Dworkin, M., NIST Special Publication 800-38A, + "Recommendation for Block Cipher Modes of Operation: + Methods and Techniques", 2001. + http://csrc.nist.gov/publications/nistpubs/800-38a/sp800- + 38a.pdf. + + [f8-a] 3GPP TS 35.201 V4.1.0 (2001-12) Technical Specification 3rd + Generation Partnership Project; Technical Specification + Group Services and System Aspects; 3G Security; + Specification of the 3GPP Confidentiality and Integrity + Algorithms; Document 1: f8 and f9 Specification (Release + 4). + + [f8-b] 3GPP TR 33.908 V4.0.0 (2001-09) Technical Report 3rd + Generation Partnership Project; Technical Specification + Group Services and System Aspects; 3G Security; General + Report on the Design, Specification and Evaluation of 3GPP + Standard Confidentiality and Integrity Algorithms (Release + 4). + + [GDOI] Baugher, M., Weis, B., Hardjono, T. and H. Harney, "The + Group Domain of Interpretation, RFC 3547, July 2003. + + + + + + +Baugher, et al. Standards Track [Page 48] + +RFC 3711 SRTP March 2004 + + + [HAC] Menezes, A., Van Oorschot, P. and S. Vanstone, "Handbook + of Applied Cryptography", CRC Press, 1997, ISBN 0-8493- + 8523-7. + + [H80] Hellman, M. E., "A cryptanalytic time-memory trade-off", + IEEE Transactions on Information Theory, July 1980, pp. + 401-406. + + [IK] T. Iwata and T. Kohno: "New Security Proofs for the 3GPP + Confidentiality and Integrity Algorithms", Proceedings of + FSE 2004. + + [KINK] Thomas, M. and J. Vilhuber, "Kerberized Internet + Negotiation of Keys (KINK)", Work in Progress. + + [KEYMGT] Arrko, J., et al., "Key Management Extensions for Session + Description Protocol (SDP) and Real Time Streaming Protocol + (RTSP)", Work in Progress. + + [KSYH] Kang, J-S., Shin, S-U., Hong, D. and O. Yi, "Provable + Security of KASUMI and 3GPP Encryption Mode f8", + Proceedings Asiacrypt 2001, Springer Verlag LNCS 2248, pp. + 255-271, 2001. + + [MIKEY] Arrko, J., et. al., "MIKEY: Multimedia Internet KEYing", + Work in Progress. + + [MF00] McGrew, D. and S. Fluhrer, "Attacks on Encryption of + Redundant Plaintext and Implications on Internet Security", + the Proceedings of the Seventh Annual Workshop on Selected + Areas in Cryptography (SAC 2000), Springer-Verlag. + + [PCST1] Perrig, A., Canetti, R., Tygar, D. and D. Song, "Efficient + and Secure Source Authentication for Multicast", in Proc. + of Network and Distributed System Security Symposium NDSS + 2001, pp. 35-46, 2001. + + [PCST2] Perrig, A., Canetti, R., Tygar, D. and D. Song, "Efficient + Authentication and Signing of Multicast Streams over Lossy + Channels", in Proc. of IEEE Security and Privacy Symposium + S&P2000, pp. 56-73, 2000. + + [RFC1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness + Recommendations for Security", RFC 1750, December 1994. + + [RFC2675] Borman, D., Deering, S. and R. Hinden, "IPv6 Jumbograms", + RFC 2675, August 1999. + + + + +Baugher, et al. Standards Track [Page 49] + +RFC 3711 SRTP March 2004 + + + [RFC3095] Bormann, C., Burmeister, C., Degermark, M., Fukuhsima, H., + Hannu, H., Jonsson, L-E., Hakenberg, R., Koren, T., Le, K., + Liu, Z., Martensson, A., Miyazaki, A., Svanbro, K., Wiebke, + T., Yoshimura, T. and H. Zheng, "RObust Header Compression: + Framework and Four Profiles: RTP, UDP, ESP, and + uncompressed (ROHC)", RFC 3095, July 2001. + + [RFC3242] Jonsson, L-E. and G. Pelletier, "RObust Header Compression + (ROHC): A Link-Layer Assisted Profile for IP/UDP/RTP ", RFC + 3242, April 2002. + + [SDMS] Andreasen, F., Baugher, M. and D. Wing, "Session + Description Protocol Security Descriptions for Media + Streams", Work in Progress. + + [SWO] Svanbro, K., Wiorek, J. and B. Olin, "Voice-over-IP-over- + wireless", Proc. PIMRC 2000, London, Sept. 2000. + + [V02] Vaudenay, S., "Security Flaws Induced by CBC Padding - + Application to SSL, IPsec, WTLS...", Advances in + Cryptology, EUROCRYPT'02, LNCS 2332, pp. 534-545. + + [WC81] Wegman, M. N., and J.L. Carter, "New Hash Functions and + Their Use in Authentication and Set Equality", JCSS 22, + 265-279, 1981. + + + + + + + + + + + + + + + + + + + + + + + + + + +Baugher, et al. Standards Track [Page 50] + +RFC 3711 SRTP March 2004 + + +Appendix A: Pseudocode for Index Determination + + The following is an example of pseudo-code for the algorithm to + determine the index i of an SRTP packet with sequence number SEQ. In + the following, signed arithmetic is assumed. + + if (s_l < 32,768) + if (SEQ - s_l > 32,768) + set v to (ROC-1) mod 2^32 + else + set v to ROC + endif + else + if (s_l - 32,768 > SEQ) + set v to (ROC+1) mod 2^32 + else + set v to ROC + endif + endif + return SEQ + v*65,536 + +Appendix B: Test Vectors + + All values are in hexadecimal. + +B.1. AES-f8 Test Vectors + + SRTP PREFIX LENGTH : 0 + + RTP packet header : 806e5cba50681de55c621599 + + RTP packet payload : 70736575646f72616e646f6d6e657373 + 20697320746865206e65787420626573 + 74207468696e67 + + ROC : d462564a + key : 234829008467be186c3de14aae72d62c + salt key : 32f2870d + key-mask (m) : 32f2870d555555555555555555555555 + key XOR key-mask : 11baae0dd132eb4d3968b41ffb278379 + + IV : 006e5cba50681de55c621599d462564a + IV' : 595b699bbd3bc0df26062093c1ad8f73 + + + + + + + + +Baugher, et al. Standards Track [Page 51] + +RFC 3711 SRTP March 2004 + + + j = 0 + IV' xor j : 595b699bbd3bc0df26062093c1ad8f73 + S(-1) : 00000000000000000000000000000000 + IV' xor S(-1) xor j : 595b699bbd3bc0df26062093c1ad8f73 + S(0) : 71ef82d70a172660240709c7fbb19d8e + plaintext : 70736575646f72616e646f6d6e657373 + ciphertext : 019ce7a26e7854014a6366aa95d4eefd + + j = 1 + IV' xor j : 595b699bbd3bc0df26062093c1ad8f72 + S(0) : 71ef82d70a172660240709c7fbb19d8e + IV' xor S(0) xor j : 28b4eb4cb72ce6bf020129543a1c12fc + S(1) : 3abd640a60919fd43bd289a09649b5fc + plaintext : 20697320746865206e65787420626573 + ciphertext : 1ad4172a14f9faf455b7f1d4b62bd08f + + j = 2 + IV' xor j : 595b699bbd3bc0df26062093c1ad8f71 + S(1) : 3abd640a60919fd43bd289a09649b5fc + IV' xor S(1) xor j : 63e60d91ddaa5f0b1dd4a93357e43a8d + S(2) : 220c7a8715266565b09ecc8a2a62b11b + plaintext : 74207468696e67 + ciphertext : 562c0eef7c4802 + +B.2. AES-CM Test Vectors + + Keystream segment length: 1044512 octets (65282 AES blocks) + Session Key: 2B7E151628AED2A6ABF7158809CF4F3C + Rollover Counter: 00000000 + Sequence Number: 0000 + SSRC: 00000000 + Session Salt: F0F1F2F3F4F5F6F7F8F9FAFBFCFD0000 (already shifted) + Offset: F0F1F2F3F4F5F6F7F8F9FAFBFCFD0000 + + Counter Keystream + + F0F1F2F3F4F5F6F7F8F9FAFBFCFD0000 E03EAD0935C95E80E166B16DD92B4EB4 + F0F1F2F3F4F5F6F7F8F9FAFBFCFD0001 D23513162B02D0F72A43A2FE4A5F97AB + F0F1F2F3F4F5F6F7F8F9FAFBFCFD0002 41E95B3BB0A2E8DD477901E4FCA894C0 + ... ... + F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF EC8CDF7398607CB0F2D21675EA9EA1E4 + F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF00 362B7C3C6773516318A077D7FC5073AE + F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF01 6A2CC3787889374FBEB4C81B17BA6C44 + + Nota Bene: this test case is contrived so that the latter part of the + keystream segment coincides with the test case in Section F.5.1 of + [CTR]. + + + + +Baugher, et al. Standards Track [Page 52] + +RFC 3711 SRTP March 2004 + + +B.3. Key Derivation Test Vectors + + This section provides test data for the default key derivation + function, which uses AES-128 in Counter Mode. In the following, we + walk through the initial key derivation for the AES-128 Counter Mode + cipher, which requires a 16 octet session encryption key and a 14 + octet session salt, and an authentication function which requires a + 94-octet session authentication key. These values are called the + cipher key, the cipher salt, and the auth key in the following. + Since this is the initial key derivation and the key derivation rate + is equal to zero, the value of (index DIV key_derivation_rate) is + zero (actually, a six-octet string of zeros). In the following, we + shorten key_derivation_rate to kdr. + + The inputs to the key derivation function are the 16 octet master key + and the 14 octet master salt: + + master key: E1F97A0D3E018BE0D64FA32C06DE4139 + master salt: 0EC675AD498AFEEBB6960B3AABE6 + + We first show how the cipher key is generated. The input block for + AES-CM is generated by exclusive-oring the master salt with the + concatenation of the encryption key label 0x00 with (index DIV kdr), + then padding on the right with two null octets (which implements the + multiply-by-2^16 operation, see Section 4.3.3). The resulting value + is then AES-CM- encrypted using the master key to get the cipher key. + + index DIV kdr: 000000000000 + label: 00 + master salt: 0EC675AD498AFEEBB6960B3AABE6 + ----------------------------------------------- + xor: 0EC675AD498AFEEBB6960B3AABE6 (x, PRF input) + + x*2^16: 0EC675AD498AFEEBB6960B3AABE60000 (AES-CM input) + + cipher key: C61E7A93744F39EE10734AFE3FF7A087 (AES-CM output) + + + + + + + + + + + + + + + +Baugher, et al. Standards Track [Page 53] + +RFC 3711 SRTP March 2004 + + + Next, we show how the cipher salt is generated. The input block for + AES-CM is generated by exclusive-oring the master salt with the + concatenation of the encryption salt label. That value is padded and + encrypted as above. + + index DIV kdr: 000000000000 + label: 02 + master salt: 0EC675AD498AFEEBB6960B3AABE6 + + ---------------------------------------------- + xor: 0EC675AD498AFEE9B6960B3AABE6 (x, PRF input) + + x*2^16: 0EC675AD498AFEE9B6960B3AABE60000 (AES-CM input) + + 30CBBC08863D8C85D49DB34A9AE17AC6 (AES-CM ouptut) + + cipher salt: 30CBBC08863D8C85D49DB34A9AE1 + + We now show how the auth key is generated. The input block for AES- + CM is generated as above, but using the authentication key label. + + index DIV kdr: 000000000000 + label: 01 + master salt: 0EC675AD498AFEEBB6960B3AABE6 + ----------------------------------------------- + xor: 0EC675AD498AFEEAB6960B3AABE6 (x, PRF input) + + x*2^16: 0EC675AD498AFEEAB6960B3AABE60000 (AES-CM input) + + Below, the auth key is shown on the left, while the corresponding AES + input blocks are shown on the right. + + auth key AES input blocks + CEBE321F6FF7716B6FD4AB49AF256A15 0EC675AD498AFEEAB6960B3AABE60000 + 6D38BAA48F0A0ACF3C34E2359E6CDBCE 0EC675AD498AFEEAB6960B3AABE60001 + E049646C43D9327AD175578EF7227098 0EC675AD498AFEEAB6960B3AABE60002 + 6371C10C9A369AC2F94A8C5FBCDDDC25 0EC675AD498AFEEAB6960B3AABE60003 + 6D6E919A48B610EF17C2041E47403576 0EC675AD498AFEEAB6960B3AABE60004 + 6B68642C59BBFC2F34DB60DBDFB2 0EC675AD498AFEEAB6960B3AABE60005 + + + + + + + + + + + + +Baugher, et al. Standards Track [Page 54] + +RFC 3711 SRTP March 2004 + + +Authors' Addresses + + Questions and comments should be directed to the authors and + avt@ietf.org: + + Mark Baugher + Cisco Systems, Inc. + 5510 SW Orchid Street + Portland, OR 97219 USA + + Phone: +1 408-853-4418 + EMail: mbaugher@cisco.com + + + Elisabetta Carrara + Ericsson Research + SE-16480 Stockholm + Sweden + + Phone: +46 8 50877040 + EMail: elisabetta.carrara@ericsson.com + + + David A. McGrew + Cisco Systems, Inc. + San Jose, CA 95134-1706 + USA + + Phone: +1 301-349-5815 + EMail: mcgrew@cisco.com + + + Mats Naslund + Ericsson Research + SE-16480 Stockholm + Sweden + + Phone: +46 8 58533739 + EMail: mats.naslund@ericsson.com + + + Karl Norrman + Ericsson Research + SE-16480 Stockholm + Sweden + + Phone: +46 8 4044502 + EMail: karl.norrman@ericsson.com + + + +Baugher, et al. Standards Track [Page 55] + +RFC 3711 SRTP March 2004 + + +Full Copyright Statement + + Copyright (C) The Internet Society (2004). This document is subject + to the rights, licenses and restrictions contained in BCP 78 and + except as set forth therein, the authors retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE + INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at ietf- + ipr@ietf.org. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + + + +Baugher, et al. Standards Track [Page 56] + diff --git a/src/libs/resiprocate/contrib/srtp/include/getopt_s.h b/src/libs/resiprocate/contrib/srtp/include/getopt_s.h new file mode 100644 index 00000000..2a6ece34 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/include/getopt_s.h @@ -0,0 +1,60 @@ +/* + * getopt.h + * + * interface to a minimal implementation of the getopt() function, + * written so that test applications that use that function can run on + * non-POSIX platforms + * + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GETOPT_S_H +#define GETOPT_S_H + +/* + * getopt_s(), optarg_s, and optind_s are small, locally defined + * versions of the POSIX standard getopt() interface. + */ + +int +getopt_s(int argc, char * const argv[], const char *optstring); + +extern char *optarg_s; /* defined in getopt.c */ + +extern int optind_s; /* defined in getopt.c */ + +#endif /* GETOPT_S_H */ diff --git a/src/libs/resiprocate/contrib/srtp/include/rtp.h b/src/libs/resiprocate/contrib/srtp/include/rtp.h new file mode 100644 index 00000000..94279f56 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/include/rtp.h @@ -0,0 +1,127 @@ +/* + * rtp.h + * + * rtp interface for srtp reference implementation + * + * David A. McGrew + * Cisco Systems, Inc. + * + * data types: + * + * rtp_msg_t an rtp message (the data that goes on the wire) + * rtp_sender_t sender side socket and rtp info + * rtp_receiver_t receiver side socket and rtp info + * + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef RTP_H +#define RTP_H + +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#elif defined HAVE_WINSOCK2_H +# include <winsock2.h> +#endif + +#include "srtp.h" + +typedef struct rtp_sender_ctx_t *rtp_sender_t; + +typedef struct rtp_receiver_ctx_t *rtp_receiver_t; + +unsigned int +rtp_sendto(rtp_sender_t sender, const void* msg, int len); + +unsigned int +rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len); + +int +rtp_receiver_init(rtp_receiver_t rcvr, int socket, + struct sockaddr_in addr, unsigned int ssrc); + +int +rtp_sender_init(rtp_sender_t sender, int socket, + struct sockaddr_in addr, unsigned int ssrc); + +/* + * srtp_sender_init(...) initializes an rtp_sender_t + */ + +int +srtp_sender_init(rtp_sender_t rtp_ctx, /* structure to be init'ed */ + struct sockaddr_in name, /* socket name */ + sec_serv_t security_services, /* sec. servs. to be used */ + unsigned char *input_key /* master key/salt in hex */ + ); + +int +srtp_receiver_init(rtp_receiver_t rtp_ctx, /* structure to be init'ed */ + struct sockaddr_in name, /* socket name */ + sec_serv_t security_services, /* sec. servs. to be used */ + unsigned char *input_key /* master key/salt in hex */ + ); + + +int +rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy); + +int +rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy); + + +rtp_sender_t +rtp_sender_alloc(); + +rtp_receiver_t +rtp_receiver_alloc(); + + +/* + * RTP_HEADER_LEN indicates the size of an RTP header + */ +#define RTP_HEADER_LEN 12 + +/* + * RTP_MAX_BUF_LEN defines the largest RTP packet in the rtp.c implementation + */ +#define RTP_MAX_BUF_LEN 16384 + + +#endif /* RTP_H */ diff --git a/src/libs/resiprocate/contrib/srtp/include/rtp_priv.h b/src/libs/resiprocate/contrib/srtp/include/rtp_priv.h new file mode 100644 index 00000000..14213866 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/include/rtp_priv.h @@ -0,0 +1,74 @@ +/* + * rtp_priv.h + * + * private, internal header file for RTP + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef RTP_PRIV_H +#define RTP_PRIV_H + +#include "srtp_priv.h" +#include "rtp.h" + +typedef srtp_hdr_t rtp_hdr_t; + +typedef struct { + srtp_hdr_t header; + char body[RTP_MAX_BUF_LEN]; +} rtp_msg_t; + +typedef struct rtp_sender_ctx_t { + rtp_msg_t message; + int socket; + srtp_ctx_t *srtp_ctx; + struct sockaddr_in addr; /* reciever's address */ +} rtp_sender_ctx_t; + +typedef struct rtp_receiver_ctx_t { + rtp_msg_t message; + int socket; + srtp_ctx_t *srtp_ctx; + struct sockaddr_in addr; /* receiver's address */ +} rtp_receiver_ctx_t; + + +#endif /* RTP_PRIV_H */ diff --git a/src/libs/resiprocate/contrib/srtp/include/srtp.h b/src/libs/resiprocate/contrib/srtp/include/srtp.h new file mode 100644 index 00000000..bb9387f3 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/include/srtp.h @@ -0,0 +1,919 @@ +/* + * srtp.h + * + * interface to libsrtp + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef SRTP_H +#define SRTP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER +#pragma pack(4) +#endif + +#include "crypto_kernel.h" + +/** + * @defgroup SRTP Secure RTP + * + * @brief libSRTP provides functions for protecting RTP and RTCP. See + * Section @ref Overview for an introduction to the use of the library. + * + * @{ + */ + +/* + * SRTP_MASTER_KEY_LEN is the nominal master key length supported by libSRTP + */ + +#define SRTP_MASTER_KEY_LEN 30 + +/* + * SRTP_MAX_KEY_LEN is the maximum key length supported by libSRTP + */ +#define SRTP_MAX_KEY_LEN 64 + +/* + * SRTP_MAX_TAG_LEN is the maximum tag length supported by libSRTP + */ + +#define SRTP_MAX_TAG_LEN 12 + +/** + * SRTP_MAX_TRAILER_LEN is the maximum length of the SRTP trailer + * (authentication tag and MKI) supported by libSRTP. This value is + * the maximum number of octets that will be added to an RTP packet by + * srtp_protect(). + * + * @brief the maximum number of octets added by srtp_protect(). + */ +#define SRTP_MAX_TRAILER_LEN SRTP_MAX_TAG_LEN + +/* + * nota bene: since libSRTP doesn't support the use of the MKI, the + * SRTP_MAX_TRAILER_LEN value is just the maximum tag length + */ + +/** + * @brief sec_serv_t describes a set of security services. + * + * A sec_serv_t enumeration is used to describe the particular + * security services that will be applied by a particular crypto + * policy (or other mechanism). + */ + +typedef enum { + sec_serv_none = 0, /**< no services */ + sec_serv_conf = 1, /**< confidentiality */ + sec_serv_auth = 2, /**< authentication */ + sec_serv_conf_and_auth = 3 /**< confidentiality and authentication */ +} sec_serv_t; + +/** + * @brief crypto_policy_t describes a particular crypto policy that + * can be applied to an SRTP stream. + * + * A crypto_policy_t describes a particular cryptographic policy that + * can be applied to an SRTP or SRTCP stream. An SRTP session policy + * consists of a list of these policies, one for each SRTP stream + * in the session. + */ + +typedef struct crypto_policy_t { + cipher_type_id_t cipher_type; /**< An integer representing + * the type of cipher. */ + int cipher_key_len; /**< The length of the cipher key + * in octets. */ + auth_type_id_t auth_type; /**< An integer representing the + * authentication function. */ + int auth_key_len; /**< The length of the authentication + * function key in octets. */ + int auth_tag_len; /**< The length of the authentication + * tag in octets. */ + sec_serv_t sec_serv; /**< The flag indicating the security + * services to be applied. */ +} crypto_policy_t; + + +/** + * @brief ssrc_type_t describes the type of an SSRC. + * + * An ssrc_type_t enumeration is used to indicate a type of SSRC. See + * @ref srtp_policy_t for more informataion. + */ + +typedef enum { + ssrc_undefined = 0, /**< Indicates an undefined SSRC type. */ + ssrc_specific = 1, /**< Indicates a specific SSRC value */ + ssrc_any_inbound = 2, /**< Indicates any inbound SSRC value + (i.e. a value that is used in the + function srtp_unprotect()) */ + ssrc_any_outbound = 3 /**< Indicates any outbound SSRC value + (i.e. a value that is used in the + function srtp_protect()) */ +} ssrc_type_t; + +/** + * @brief An ssrc_t represents a particular SSRC value, or a `wildcard' SSRC. + * + * An ssrc_t represents a particular SSRC value (if its type is + * ssrc_specific), or a wildcard SSRC value that will match all + * outbound SSRCs (if its type is ssrc_any_outbound) or all inbound + * SSRCs (if its type is ssrc_any_inbound). + * + */ + +typedef struct { + ssrc_type_t type; /**< The type of this particular SSRC */ + unsigned int value; /**< The value of this SSRC, if it is not a wildcard */ +} ssrc_t; + + +/** + * @brief represents the policy for an SRTP session. + * + * A single srtp_policy_t struct represents the policy for a single + * SRTP stream, and a linked list of these elements represents the + * policy for an entire SRTP session. Each element contains the SRTP + * and SRTCP crypto policies for that stream, a pointer to the SRTP + * master key for that stream, the SSRC describing that stream, or a + * flag indicating a `wildcard' SSRC value, and a `next' field that + * holds a pointer to the next element in the list of policy elements, + * or NULL if it is the last element. + * + * The wildcard value SSRC_ANY_INBOUND matches any SSRC from an + * inbound stream that for which there is no explicit SSRC entry in + * another policy element. Similarly, the value SSRC_ANY_OUTBOUND + * will matches any SSRC from an outbound stream that does not appear + * in another policy element. Note that wildcard SSRCs &b cannot be + * used to match both inbound and outbound traffic. This restriction + * is intentional, and it allows libSRTP to ensure that no security + * lapses result from accidental re-use of SSRC values during key + * sharing. + * + * + * @warning The final element of the list @b must have its `next' pointer + * set to NULL. + */ + +typedef struct srtp_policy_t { + ssrc_t ssrc; /**< The SSRC value of stream, or the + * flags SSRC_ANY_INBOUND or + * SSRC_ANY_OUTBOUND if key sharing + * is used for this policy element. + */ + crypto_policy_t rtp; /**< SRTP crypto policy. */ + crypto_policy_t rtcp; /**< SRTCP crypto policy. */ + unsigned char *key; /**< Pointer to the SRTP master key for + * this stream. */ + struct srtp_policy_t *next; /**< Pointer to next stream policy. */ +} srtp_policy_t; + + + + +/** + * @brief An srtp_t points to an SRTP session structure. + * + * The typedef srtp_t is a pointer to a structure that represents + * an SRTP session. This datatype is intentially opaque in + * order to separate the interface from the implementation. + * + * An SRTP session consists of all of the traffic sent to the RTP and + * RTCP destination transport addresses, using the RTP/SAVP (Secure + * Audio/Video Profile). A session can be viewed as a set of SRTP + * streams, each of which originates with a different participant. + */ + +typedef struct srtp_ctx_t *srtp_t; + + +/** + * @brief An srtp_stream_t points to an SRTP stream structure. + * + * The typedef srtp_stream_t is a pointer to a structure that + * represents an SRTP stream. This datatype is intentionally + * opaque in order to separate the interface from the implementation. + * + * An SRTP stream consists of all of the traffic sent to an SRTP + * session by a single participant. A session can be viewed as + * a set of streams. + * + */ +typedef struct srtp_stream_ctx_t *srtp_stream_t; + + + +/** + * @brief srtp_init() initializes the srtp library. + * + * @warning This function @b must be called before any other srtp + * functions. + */ + +err_status_t +srtp_init(void); + +/** + * @brief srtp_protect() is the Secure RTP sender-side packet processing + * function. + * + * The function call srtp_protect(ctx, rtp_hdr, len_ptr) applies SRTP + * protection to the RTP packet rtp_hdr (which has length *len_ptr) using + * the SRTP context ctx. If err_status_ok is returned, then rtp_hdr + * points to the resulting SRTP packet and *len_ptr is the number of + * octets in that packet; otherwise, no assumptions should be made + * about the value of either data elements. + * + * The sequence numbers of the RTP packets presented to this function + * need not be consecutive, but they @b must be out of order by less + * than 2^15 = 32,768 packets. + * + * @warning This function assumes that it can write the authentication + * tag into the location in memory immediately following the RTP + * packet, and assumes that the RTP packet is aligned on a 32-bit + * boundary. + * + * @param ctx is the SRTP context to use in processing the packet. + * + * @param rtp_hdr is a pointer to the RTP packet (before the call); after + * the function returns, it points to the srtp packet. + * + * @param len_ptr is a pointer to the length in octets of the complete + * RTP packet (header and body) before the function call, and of the + * complete SRTP packet after the call, if err_status_ok was returned. + * Otherwise, the value of the data to which it points is undefined. + * + * @return + * - err_status_ok no problems + * - err_status_replay_fail rtp sequence number was non-increasing + * - @e other failure in cryptographic mechanisms + */ + +err_status_t +srtp_protect(srtp_t ctx, void *rtp_hdr, int *len_ptr); + +/** + * @brief srtp_unprotect() is the Secure RTP receiver-side packet + * processing function. + * + * The function call srtp_unprotect(ctx, srtp_hdr, len_ptr) verifies + * the Secure RTP protection of the SRTP packet pointed to by srtp_hdr + * (which has length *len_ptr), using the SRTP context ctx. If + * err_status_ok is returned, then srtp_hdr points to the resulting + * RTP packet and *len_ptr is the number of octets in that packet; + * otherwise, no assumptions should be made about the value of either + * data elements. + * + * The sequence numbers of the RTP packets presented to this function + * need not be consecutive, but they @b must be out of order by less + * than 2^15 = 32,768 packets. + * + * @warning This function assumes that the SRTP packet is aligned on a + * 32-bit boundary. + * + * @param ctx is a pointer to the srtp_t which applies to the + * particular packet. + * + * @param srtp_hdr is a pointer to the header of the SRTP packet + * (before the call). after the function returns, it points to the + * rtp packet if err_status_ok was returned; otherwise, the value of + * the data to which it points is undefined. + * + * @param len_ptr is a pointer to the length in octets of the complete + * srtp packet (header and body) before the function call, and of the + * complete rtp packet after the call, if err_status_ok was returned. + * Otherwise, the value of the data to which it points is undefined. + * + * @return + * - err_status_ok if the RTP packet is valid. + * - err_status_auth_fail if the SRTP packet failed the message + * authentication check. + * - err_status_replay_fail if the SRTP packet is a replay (e.g. packet has + * already been processed and accepted). + * - [other] if there has been an error in the cryptographic mechanisms. + * + */ + +err_status_t +srtp_unprotect(srtp_t ctx, void *srtp_hdr, int *len_ptr); + + +/** + * @brief srtp_create() allocates and initializes an SRTP session. + + * The function call srtp_create(session, policy, key) allocates and + * initializes an SRTP session context, applying the given policy and + * key. + * + * @param session is the SRTP session to which the policy is to be added. + * + * @param policy is the srtp_policy_t struct that describes the policy + * for the session. The struct may be a single element, or it may be + * the head of a list, in which case each element of the list is + * processed. It may also be NULL, in which case streams should be added + * later using srtp_add_stream(). The final element of the list @b must + * have its `next' field set to NULL. + * + * @return + * - err_status_ok if creation succeded. + * - err_status_alloc_fail if allocation failed. + * - err_status_init_fail if initialization failed. + */ + +err_status_t +srtp_create(srtp_t *session, const srtp_policy_t *policy); + + +/** + * @brief srtp_add_stream() allocates and initializes an SRTP stream + * within a given SRTP session. + * + * The function call srtp_add_stream(session, policy) allocates and + * initializes a new SRTP stream within a given, previously created + * session, applying the policy given as the other argument to that + * stream. + * + * @return values: + * - err_status_ok if stream creation succeded. + * - err_status_alloc_fail if stream allocation failed + * - err_status_init_fail if stream initialization failed. + */ + +err_status_t +srtp_add_stream(srtp_t session, + const srtp_policy_t *policy); + + +/** + * @brief srtp_remove_stream() deallocates an SRTP stream. + * + * The function call srtp_remove_stream(session, ssrc) removes + * the SRTP stream with the SSRC value ssrc from the SRTP session + * context given by the argument session. + * + * @param session is the SRTP session from which the stream + * will be removed. + * + * @param ssrc is the SSRC value of the stream to be removed. + * + * @warning Wildcard SSRC values cannot be removed from a + * session. + * + * @return + * - err_status_ok if the stream deallocation succeded. + * - [other] otherwise. + * + */ + +err_status_t +srtp_remove_stream(srtp_t session, unsigned int ssrc); + +/** + * @brief crypto_policy_set_rtp_default() sets a crypto policy + * structure to the SRTP default policy for RTP protection. + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_rtp_default(&p) sets the + * crypto_policy_t at location p to the SRTP default policy for RTP + * protection, as defined in the specification. This function is a + * convenience that helps to avoid dealing directly with the policy + * data structure. You are encouraged to initialize policy elements + * with this function call. Doing so may allow your code to be + * forward compatible with later versions of libSRTP that include more + * elements in the crypto_policy_t datatype. + * + * @return void. + * + */ + +void +crypto_policy_set_rtp_default(crypto_policy_t *p); + +/** + * @brief crypto_policy_set_rtcp_default() sets a crypto policy + * structure to the SRTP default policy for RTCP protection. + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_rtcp_default(&p) sets the + * crypto_policy_t at location p to the SRTP default policy for RTCP + * protection, as defined in the specification. This function is a + * convenience that helps to avoid dealing directly with the policy + * data structure. You are encouraged to initialize policy elements + * with this function call. Doing so may allow your code to be + * forward compatible with later versions of libSRTP that include more + * elements in the crypto_policy_t datatype. + * + * @return void. + * + */ + +void +crypto_policy_set_rtcp_default(crypto_policy_t *p); + +/** + * @brief crypto_policy_set_aes_cm_128_hmac_sha1_80() sets a crypto + * policy structure to the SRTP default policy for RTP protection. + * + * @param p is a pointer to the policy structure to be set + * + * The function crypto_policy_set_aes_cm_128_hmac_sha1_80() is a + * synonym for crypto_policy_set_rtp_default(). It conforms to the + * naming convention used in + * http://www.ietf.org/internet-drafts/draft-ietf-mmusic-sdescriptions-12.txt + * + * @return void. + * + */ + +#define crypto_policy_set_aes_cm_128_hmac_sha1_80(p) crypto_policy_set_rtp_default(p) + + +/** + * @brief crypto_policy_set_aes_cm_128_hmac_sha1_32() sets a crypto + * policy structure to a short-authentication tag policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_aes_cm_128_hmac_sha1_32(&p) + * sets the crypto_policy_t at location p to use policy + * AES_CM_128_HMAC_SHA1_32 as defined in + * draft-ietf-mmusic-sdescriptions-12.txt. This policy uses AES-128 + * Counter Mode encryption and HMAC-SHA1 authentication, with an + * authentication tag that is only 32 bits long. This length is + * considered adequate only for protecting audio and video media that + * use a stateless playback function. See Section 7.5 of RFC 3711 + * (http://www.ietf.org/rfc/rfc3711.txt). + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the crypto_policy_t datatype. + * + * @warning This crypto policy is intended for use in SRTP, but not in + * SRTCP. It is recommended that a policy that uses longer + * authentication tags be used for SRTCP. See Section 7.5 of RFC 3711 + * (http://www.ietf.org/rfc/rfc3711.txt). + * + * @return void. + * + */ + +void +crypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p); + + + +/** + * @brief crypto_policy_set_aes_cm_128_null_auth() sets a crypto + * policy structure to an encryption-only policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_aes_cm_128_null_auth(&p) sets + * the crypto_policy_t at location p to use the SRTP default cipher + * (AES-128 Counter Mode), but to use no authentication method. This + * policy is NOT RECOMMENDED unless it is unavoidable; see Section 7.5 + * of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt). + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the crypto_policy_t datatype. + * + * @warning This policy is NOT RECOMMENDED for SRTP unless it is + * unavoidable, and it is NOT RECOMMENDED at all for SRTCP; see + * Section 7.5 of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt). + * + * @return void. + * + */ + +void +crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p); + + +/** + * @brief crypto_policy_set_null_cipher_hmac_sha1_80() sets a crypto + * policy structure to an authentication-only policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_null_cipher_hmac_sha1_80(&p) + * sets the crypto_policy_t at location p to use HMAC-SHA1 with an 80 + * bit authentication tag to provide message authentication, but to + * use no encryption. This policy is NOT RECOMMENDED for SRTP unless + * there is a requirement to forego encryption. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the crypto_policy_t datatype. + * + * @warning This policy is NOT RECOMMENDED for SRTP unless there is a + * requirement to forego encryption. + * + * @return void. + * + */ + +void +crypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p); + +/** + * @brief srtp_dealloc() deallocates storage for an SRTP session + * context. + * + * The function call srtp_dealloc(s) deallocates storage for the + * SRTP session context s. This function should be called no more + * than one time for each of the contexts allocated by the function + * srtp_create(). + * + * @param s is the srtp_t for the session to be deallocated. + * + * @return + * - err_status_ok if there no problems. + * - err_status_dealloc_fail a memory deallocation failure occured. + */ + +err_status_t +srtp_dealloc(srtp_t s); + + +/* + * @brief identifies a particular SRTP profile + * + * An srtp_profile_t enumeration is used to identify a particular SRTP + * profile (that is, a set of algorithms and parameters). These + * profiles are defined in the DTLS-SRTP draft. + */ + +typedef enum { + srtp_profile_reserved = 0, + srtp_profile_aes128_cm_sha1_80 = 1, + srtp_profile_aes128_cm_sha1_32 = 2, + srtp_profile_aes256_cm_sha1_80 = 3, + srtp_profile_aes256_cm_sha1_32 = 4, + srtp_profile_null_sha1_80 = 5, + srtp_profile_null_sha1_32 = 6, +} srtp_profile_t; + + +/** + * @brief crypto_policy_set_from_profile_for_rtp() sets a crypto policy + * structure to the appropriate value for RTP based on an srtp_profile_t + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_rtp_default(&policy, profile) + * sets the crypto_policy_t at location policy to the policy for RTP + * protection, as defined by the srtp_profile_t profile. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the crypto_policy_t datatype. + * + * @return values + * - err_status_ok no problems were encountered + * - err_status_bad_param the profile is not supported + * + */ +err_status_t +crypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy, + srtp_profile_t profile); + + + + +/** + * @brief crypto_policy_set_from_profile_for_rtcp() sets a crypto policy + * structure to the appropriate value for RTCP based on an srtp_profile_t + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_rtcp_default(&policy, profile) + * sets the crypto_policy_t at location policy to the policy for RTCP + * protection, as defined by the srtp_profile_t profile. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the crypto_policy_t datatype. + * + * @return values + * - err_status_ok no problems were encountered + * - err_status_bad_param the profile is not supported + * + */ +err_status_t +crypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy, + srtp_profile_t profile); + +/** + * @brief returns the master key length for a given SRTP profile + */ +unsigned int +srtp_profile_get_master_key_length(srtp_profile_t profile); + + +/** + * @brief returns the master salt length for a given SRTP profile + */ +unsigned int +srtp_profile_get_master_salt_length(srtp_profile_t profile); + +/** + * @brief appends the salt to the key + * + * The function call append_salt_to_key(k, klen, s, slen) + * copies the string s to the location at klen bytes following + * the location k. + * + * @warning There must be at least bytes_in_salt + bytes_in_key bytes + * available at the location pointed to by key. + * + */ + +void +append_salt_to_key(unsigned char *key, unsigned int bytes_in_key, + unsigned char *salt, unsigned int bytes_in_salt); + + + +/** + * @} + */ + + + +/** + * @defgroup SRTCP Secure RTCP + * @ingroup SRTP + * + * @brief Secure RTCP functions are used to protect RTCP traffic. + * + * RTCP is the control protocol for RTP. libSRTP protects RTCP + * traffic in much the same way as it does RTP traffic. The function + * srtp_protect_rtcp() applies cryptographic protections to outbound + * RTCP packets, and srtp_unprotect_rtcp() verifies the protections on + * inbound RTCP packets. + * + * A note on the naming convention: srtp_protect_rtcp() has an srtp_t + * as its first argument, and thus has `srtp_' as its prefix. The + * trailing `_rtcp' indicates the protocol on which it acts. + * + * @{ + */ + +/** + * @brief srtp_protect_rtcp() is the Secure RTCP sender-side packet + * processing function. + * + * The function call srtp_protect_rtcp(ctx, rtp_hdr, len_ptr) applies + * SRTCP protection to the RTCP packet rtcp_hdr (which has length + * *len_ptr) using the SRTP session context ctx. If err_status_ok is + * returned, then rtp_hdr points to the resulting SRTCP packet and + * *len_ptr is the number of octets in that packet; otherwise, no + * assumptions should be made about the value of either data elements. + * + * @warning This function assumes that it can write the authentication + * tag into the location in memory immediately following the RTCP + * packet, and assumes that the RTCP packet is aligned on a 32-bit + * boundary. + * + * @param ctx is the SRTP context to use in processing the packet. + * + * @param rtcp_hdr is a pointer to the RTCP packet (before the call); after + * the function returns, it points to the srtp packet. + * + * @param pkt_octet_len is a pointer to the length in octets of the + * complete RTCP packet (header and body) before the function call, + * and of the complete SRTCP packet after the call, if err_status_ok + * was returned. Otherwise, the value of the data to which it points + * is undefined. + * + * @return + * - err_status_ok if there were no problems. + * - [other] if there was a failure in + * the cryptographic mechanisms. + */ + + +err_status_t +srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len); + +/** + * @brief srtp_unprotect_rtcp() is the Secure RTCP receiver-side packet + * processing function. + * + * The function call srtp_unprotect_rtcp(ctx, srtp_hdr, len_ptr) + * verifies the Secure RTCP protection of the SRTCP packet pointed to + * by srtcp_hdr (which has length *len_ptr), using the SRTP session + * context ctx. If err_status_ok is returned, then srtcp_hdr points + * to the resulting RTCP packet and *len_ptr is the number of octets + * in that packet; otherwise, no assumptions should be made about the + * value of either data elements. + * + * @warning This function assumes that the SRTCP packet is aligned on a + * 32-bit boundary. + * + * @param ctx is a pointer to the srtp_t which applies to the + * particular packet. + * + * @param srtcp_hdr is a pointer to the header of the SRTCP packet + * (before the call). After the function returns, it points to the + * rtp packet if err_status_ok was returned; otherwise, the value of + * the data to which it points is undefined. + * + * @param pkt_octet_len is a pointer to the length in octets of the + * complete SRTCP packet (header and body) before the function call, + * and of the complete rtp packet after the call, if err_status_ok was + * returned. Otherwise, the value of the data to which it points is + * undefined. + * + * @return + * - err_status_ok if the RTCP packet is valid. + * - err_status_auth_fail if the SRTCP packet failed the message + * authentication check. + * - err_status_replay_fail if the SRTCP packet is a replay (e.g. has + * already been processed and accepted). + * - [other] if there has been an error in the cryptographic mechanisms. + * + */ + +err_status_t +srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len); + +/** + * @} + */ + +/** + * @defgroup SRTPevents SRTP events and callbacks + * @ingroup SRTP + * + * @brief libSRTP can use a user-provided callback function to + * handle events. + * + * + * libSRTP allows a user to provide a callback function to handle + * events that need to be dealt with outside of the data plane (see + * the enum srtp_event_t for a description of these events). Dealing + * with these events is not a strict necessity; they are not + * security-critical, but the application may suffer if they are not + * handled. The function srtp_set_event_handler() is used to provide + * the callback function. + * + * A default event handler that merely reports on the events as they + * happen is included. It is also possible to set the event handler + * function to NULL, in which case all events will just be silently + * ignored. + * + * @{ + */ + +/** + * @brief srtp_event_t defines events that need to be handled + * + * The enum srtp_event_t defines events that need to be handled + * outside the `data plane', such as SSRC collisions and + * key expirations. + * + * When a key expires or the maximum number of packets has been + * reached, an SRTP stream will enter an `expired' state in which no + * more packets can be protected or unprotected. When this happens, + * it is likely that you will want to either deallocate the stream + * (using srtp_stream_dealloc()), and possibly allocate a new one. + * + * When an SRTP stream expires, the other streams in the same session + * are unaffected, unless key sharing is used by that stream. In the + * latter case, all of the streams in the session will expire. + */ + +typedef enum { + event_ssrc_collision, /**< + * An SSRC collision occured. + */ + event_key_soft_limit, /**< An SRTP stream reached the soft key + * usage limit and will expire soon. + */ + event_key_hard_limit, /**< An SRTP stream reached the hard + * key usage limit and has expired. + */ + event_packet_index_limit /**< An SRTP stream reached the hard + * packet limit (2^48 packets). + */ +} srtp_event_t; + +/** + * @brief srtp_event_data_t is the structure passed as a callback to + * the event handler function + * + * The struct srtp_event_data_t holds the data passed to the event + * handler function. + */ + +typedef struct srtp_event_data_t { + srtp_t session; /**< The session in which the event happend. */ + srtp_stream_t stream; /**< The stream in which the event happend. */ + srtp_event_t event; /**< An enum indicating the type of event. */ +} srtp_event_data_t; + +/** + * @brief srtp_event_handler_func_t is the function prototype for + * the event handler. + * + * The typedef srtp_event_handler_func_t is the prototype for the + * event handler function. It has as its only argument an + * srtp_event_data_t which describes the event that needs to be handled. + * There can only be a single, global handler for all events in + * libSRTP. + */ + +typedef void (srtp_event_handler_func_t)(srtp_event_data_t *data); + +/** + * @brief sets the event handler to the function supplied by the caller. + * + * The function call srtp_install_event_handler(func) sets the event + * handler function to the value func. The value NULL is acceptable + * as an argument; in this case, events will be ignored rather than + * handled. + * + * @param func is a pointer to a fuction that takes an srtp_event_data_t + * pointer as an argument and returns void. This function + * will be used by libSRTP to handle events. + */ + +err_status_t +srtp_install_event_handler(srtp_event_handler_func_t func); + +/** + * @} + */ +/* in host order, so outside the #if */ +#define SRTCP_E_BIT 0x80000000 +/* for byte-access */ +#define SRTCP_E_BYTE_BIT 0x80 +#define SRTCP_INDEX_MASK 0x7fffffff + +#ifdef _MSC_VER +#pragma pack() +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SRTP_H */ diff --git a/src/libs/resiprocate/contrib/srtp/include/srtp_priv.h b/src/libs/resiprocate/contrib/srtp/include/srtp_priv.h new file mode 100644 index 00000000..de273ab3 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/include/srtp_priv.h @@ -0,0 +1,245 @@ +/* + * srtp_priv.h + * + * private internal data structures and functions for libSRTP + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef SRTP_PRIV_H +#define SRTP_PRIV_H + +#include "srtp.h" +#include "rdbx.h" +#include "rdb.h" +#include "integers.h" + +/* + * an srtp_hdr_t represents the srtp header + * + * in this implementation, an srtp_hdr_t is assumed to be 32-bit aligned + * + * (note that this definition follows that of RFC 1889 Appendix A, but + * is not identical) + */ + +#ifndef WORDS_BIGENDIAN + +/* + * srtp_hdr_t represents an RTP or SRTP header. The bit-fields in + * this structure should be declared "unsigned int" instead of + * "unsigned char", but doing so causes the MS compiler to not + * fully pack the bit fields. + */ + +typedef struct { + unsigned char cc:4; /* CSRC count */ + unsigned char x:1; /* header extension flag */ + unsigned char p:1; /* padding flag */ + unsigned char version:2; /* protocol version */ + unsigned char pt:7; /* payload type */ + unsigned char m:1; /* marker bit */ + uint16_t seq; /* sequence number */ + uint32_t ts; /* timestamp */ + uint32_t ssrc; /* synchronization source */ +} srtp_hdr_t; + +#else /* BIG_ENDIAN */ + +typedef struct { + unsigned char version:2; /* protocol version */ + unsigned char p:1; /* padding flag */ + unsigned char x:1; /* header extension flag */ + unsigned char cc:4; /* CSRC count */ + unsigned char m:1; /* marker bit */ + unsigned pt:7; /* payload type */ + uint16_t seq; /* sequence number */ + uint32_t ts; /* timestamp */ + uint32_t ssrc; /* synchronization source */ +} srtp_hdr_t; + +#endif + +typedef struct { + uint16_t profile_specific; /* profile-specific info */ + uint16_t length; /* number of 32-bit words in extension */ +} srtp_hdr_xtnd_t; + + +/* + * srtcp_hdr_t represents a secure rtcp header + * + * in this implementation, an srtcp header is assumed to be 32-bit + * alinged + */ + +#ifndef WORDS_BIGENDIAN + +typedef struct { + unsigned char rc:5; /* reception report count */ + unsigned char p:1; /* padding flag */ + unsigned char version:2; /* protocol version */ + unsigned char pt:8; /* payload type */ + uint16_t len; /* length */ + uint32_t ssrc; /* synchronization source */ +} srtcp_hdr_t; + +typedef struct { + unsigned int index:31; /* srtcp packet index in network order! */ + unsigned int e:1; /* encrypted? 1=yes */ + /* optional mikey/etc go here */ + /* and then the variable-length auth tag */ +} srtcp_trailer_t; + + +#else /* BIG_ENDIAN */ + +typedef struct { + unsigned char version:2; /* protocol version */ + unsigned char p:1; /* padding flag */ + unsigned char rc:5; /* reception report count */ + unsigned char pt:8; /* payload type */ + uint16_t len; /* length */ + uint32_t ssrc; /* synchronization source */ +} srtcp_hdr_t; + +typedef struct { + unsigned int version:2; /* protocol version */ + unsigned int p:1; /* padding flag */ + unsigned int count:5; /* varies by packet type */ + unsigned int pt:8; /* payload type */ + uint16_t length; /* len of uint32s of packet less header */ +} rtcp_common_t; + +typedef struct { + unsigned int e:1; /* encrypted? 1=yes */ + unsigned int index:31; /* srtcp packet index */ + /* optional mikey/etc go here */ + /* and then the variable-length auth tag */ +} srtcp_trailer_t; + +#endif + + +/* + * the following declarations are libSRTP internal functions + */ + +/* + * srtp_get_stream(ssrc) returns a pointer to the stream corresponding + * to ssrc, or NULL if no stream exists for that ssrc + */ + +srtp_stream_t +srtp_get_stream(srtp_t srtp, uint32_t ssrc); + + +/* + * srtp_stream_init_keys(s, k) (re)initializes the srtp_stream_t s by + * deriving all of the needed keys using the KDF and the key k. + */ + + +err_status_t +srtp_stream_init_keys(srtp_stream_t srtp, const void *key); + +/* + * libsrtp internal datatypes + */ + +typedef enum direction_t { + dir_unknown = 0, + dir_srtp_sender = 1, + dir_srtp_receiver = 2 +} direction_t; + +/* + * an srtp_stream_t has its own SSRC, encryption key, authentication + * key, sequence number, and replay database + * + * note that the keys might not actually be unique, in which case the + * cipher_t and auth_t pointers will point to the same structures + */ + +typedef struct srtp_stream_ctx_t { + uint32_t ssrc; + cipher_t *rtp_cipher; + auth_t *rtp_auth; + rdbx_t rtp_rdbx; + sec_serv_t rtp_services; + cipher_t *rtcp_cipher; + auth_t *rtcp_auth; + rdb_t rtcp_rdb; + sec_serv_t rtcp_services; + key_limit_ctx_t *limit; + direction_t direction; + struct srtp_stream_ctx_t *next; /* linked list of streams */ +} srtp_stream_ctx_t; + + +/* + * an srtp_ctx_t holds a stream list and a service description + */ + +typedef struct srtp_ctx_t { + srtp_stream_ctx_t *stream_list; /* linked list of streams */ + srtp_stream_ctx_t *stream_template; /* act as template for other streams */ +} srtp_ctx_t; + + + +/* + * srtp_handle_event(srtp, srtm, evnt) calls the event handling + * function, if there is one. + * + * This macro is not included in the documentation as it is + * an internal-only function. + */ + +#define srtp_handle_event(srtp, strm, evnt) \ + if(srtp_event_handler) { \ + srtp_event_data_t data; \ + data.session = srtp; \ + data.stream = strm; \ + data.event = evnt; \ + srtp_event_handler(&data); \ +} + + +#endif /* SRTP_PRIV_H */ diff --git a/src/libs/resiprocate/contrib/srtp/include/ut_sim.h b/src/libs/resiprocate/contrib/srtp/include/ut_sim.h new file mode 100644 index 00000000..c25feeb6 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/include/ut_sim.h @@ -0,0 +1,80 @@ +/* + * ut-sim.h + * + * an unreliable transport simulator + * (for testing replay databases and suchlike) + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + + +#ifndef UT_SIM_H +#define UT_SIM_H + +#include "integers.h" /* for uint32_t */ + +#define UT_BUF 160 /* maximum amount of packet reorder */ + +typedef struct { + uint32_t index; + uint32_t buffer[UT_BUF]; +} ut_connection; + +/* + * ut_init(&u) initializes the ut_connection + * + * this function should always be the first one called on a new + * ut_connection + */ + +void +ut_init(ut_connection *utc); + +/* + * ut_next_index(&u) returns the next index from the simulated + * unreliable connection + */ + +uint32_t +ut_next_index(ut_connection *utc); + + +#endif /* UT_SIM_H */ diff --git a/src/libs/resiprocate/contrib/srtp/install-sh b/src/libs/resiprocate/contrib/srtp/install-sh new file mode 100644 index 00000000..e9de2384 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/src/libs/resiprocate/contrib/srtp/srtp.def b/src/libs/resiprocate/contrib/srtp/srtp.def new file mode 100644 index 00000000..c1198c5e --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/srtp.def @@ -0,0 +1,92 @@ +EXPORTS +srtp_init +srtp_protect +srtp_unprotect +srtp_create +srtp_add_stream +srtp_remove_stream +crypto_policy_set_rtp_default +crypto_policy_set_rtcp_default +crypto_policy_set_aes_cm_128_hmac_sha1_32 +crypto_policy_set_aes_cm_128_null_auth +crypto_policy_set_null_cipher_hmac_sha1_80 +srtp_dealloc +srtp_get_stream +srtp_protect_rtcp +srtp_unprotect_rtcp +srtp_install_event_handler +crypto_kernel_init +crypto_kernel_shutdown +crypto_kernel_status +crypto_kernel_list_debug_modules +crypto_kernel_load_cipher_type +crypto_kernel_load_auth_type +crypto_kernel_load_debug_module +crypto_kernel_alloc_cipher +crypto_kernel_alloc_auth +crypto_kernel_set_debug_module +crypto_get_random +rand_source_init +rand_source_get_octet_string +rand_source_deinit +x917_prng_init +x917_prng_get_octet_string +ctr_prng_init +ctr_prng_get_octet_string +cipher_output +cipher_get_key_length +cipher_type_self_test +cipher_bits_per_second +auth_get_key_length +auth_get_tag_length +auth_get_prefix_length +auth_type_self_test +auth_type_get_ref_count +stat_test_monobit +stat_test_poker +stat_test_runs +stat_test_rand_source +stat_test_rand_source_with_repetition +err_reporting_init +err_report +key_limit_set +key_limit_clone +key_limit_check +key_limit_update +rdbx_init +rdbx_estimate_index +rdbx_check +rdbx_add_index +index_init +index_advance +index_guess +octet_get_weight +octet_string_hex_string +v128_bit_string +v128_hex_string +nibble_to_hex_char +hex_string_to_octet_string +v128_copy_octet_string +v128_left_shift +v128_right_shift +octet_string_is_eq +octet_string_set_to_zero +rdb_init +rdb_check +rdb_add_index +rdb_increment +rdb_get_value +aes_expand_encryption_key +aes_expand_decryption_key +aes_encrypt +aes_decrypt +aes_icm_context_init +aes_icm_set_iv +aes_icm_encrypt +aes_icm_output +aes_icm_dealloc +aes_icm_encrypt_ismacryp +aes_icm_alloc_ismacryp +crypto_alloc +crypto_free +\ No newline at end of file \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/srtp/srtp.vcproj b/src/libs/resiprocate/contrib/srtp/srtp.vcproj new file mode 100644 index 00000000..fca45b02 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/srtp.vcproj @@ -0,0 +1,588 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="libSRTP" + ProjectGUID="{EEF031CB-FED8-451E-A471-91EC8D4F6750}" + RootNamespace="libSRTP" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + Description="Creating config.h from config.hw" + CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="crypto/include;include" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + StructMemberAlignment="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + Description="Creating config.h from config.hw" + CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="crypto/include;include" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + RuntimeLibrary="2" + StructMemberAlignment="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug Dll|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + Description="Creating config.h from config.hw" + CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="crypto/include;include" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + StructMemberAlignment="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib" + ModuleDefinitionFile="srtp.def" + OptimizeReferences="1" + EnableCOMDATFolding="1" + OptimizeForWindows98="1" + LinkTimeCodeGeneration="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release Dll|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + Description="Creating config.h from config.hw" + CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="crypto/include;include" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + RuntimeLibrary="2" + StructMemberAlignment="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib" + ModuleDefinitionFile="srtp.def" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\srtp\srtp.c" + > + </File> + <Filter + Name="Kernel" + > + <File + RelativePath=".\crypto\kernel\alloc.c" + > + </File> + <File + RelativePath=".\crypto\kernel\crypto_kernel.c" + > + </File> + <File + RelativePath=".\crypto\rng\ctr_prng.c" + > + </File> + <File + RelativePath=".\crypto\kernel\err.c" + > + </File> + <File + RelativePath=".\crypto\kernel\key.c" + > + </File> + <File + RelativePath=".\crypto\rng\prng.c" + > + </File> + <File + RelativePath=".\crypto\rng\rand_source.c" + > + </File> + </Filter> + <Filter + Name="Ciphers" + > + <File + RelativePath=".\crypto\cipher\aes.c" + > + <FileConfiguration + Name="Debug Dll|Win32" + > + <Tool + Name="VCCLCompilerTool" + InlineFunctionExpansion="0" + EnableIntrinsicFunctions="false" + EnableFunctionLevelLinking="false" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\crypto\cipher\aes_cbc.c" + > + </File> + <File + RelativePath=".\crypto\cipher\aes_icm.c" + > + </File> + <File + RelativePath=".\crypto\cipher\cipher.c" + > + </File> + <File + RelativePath=".\crypto\cipher\null_cipher.c" + > + </File> + </Filter> + <Filter + Name="Hashes" + > + <File + RelativePath=".\crypto\hash\auth.c" + > + </File> + <File + RelativePath=".\crypto\hash\hmac.c" + > + </File> + <File + RelativePath=".\crypto\hash\null_auth.c" + > + </File> + <File + RelativePath=".\crypto\hash\sha1.c" + > + </File> + </Filter> + <Filter + Name="Replay" + > + <File + RelativePath=".\crypto\replay\rdb.c" + > + </File> + <File + RelativePath=".\crypto\replay\rdbx.c" + > + </File> + <File + RelativePath=".\crypto\replay\ut_sim.c" + > + </File> + </Filter> + <Filter + Name="Math" + > + <File + RelativePath=".\crypto\math\datatypes.c" + > + </File> + <File + RelativePath=".\crypto\math\stat.c" + > + </File> + </Filter> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\crypto\include\aes.h" + > + </File> + <File + RelativePath=".\crypto\include\aes_cbc.h" + > + </File> + <File + RelativePath=".\crypto\include\aes_icm.h" + > + </File> + <File + RelativePath=".\crypto\include\alloc.h" + > + </File> + <File + RelativePath=".\crypto\include\auth.h" + > + </File> + <File + RelativePath=".\crypto\include\cipher.h" + > + </File> + <File + RelativePath=".\crypto\include\config.h" + > + </File> + <File + RelativePath=".\crypto\include\crypto.h" + > + </File> + <File + RelativePath=".\crypto\include\crypto_kernel.h" + > + </File> + <File + RelativePath=".\crypto\include\crypto_math.h" + > + </File> + <File + RelativePath=".\crypto\include\crypto_types.h" + > + </File> + <File + RelativePath=".\crypto\include\cryptoalg.h" + > + </File> + <File + RelativePath=".\crypto\include\datatypes.h" + > + </File> + <File + RelativePath=".\crypto\include\err.h" + > + </File> + <File + RelativePath=".\crypto\include\gf2_8.h" + > + </File> + <File + RelativePath=".\crypto\include\hmac.h" + > + </File> + <File + RelativePath=".\crypto\include\integers.h" + > + </File> + <File + RelativePath=".\crypto\include\kernel_compat.h" + > + </File> + <File + RelativePath=".\crypto\include\key.h" + > + </File> + <File + RelativePath=".\crypto\include\null_auth.h" + > + </File> + <File + RelativePath=".\crypto\include\null_cipher.h" + > + </File> + <File + RelativePath=".\crypto\include\prng.h" + > + </File> + <File + RelativePath=".\crypto\include\rand_source.h" + > + </File> + <File + RelativePath=".\crypto\include\rdb.h" + > + </File> + <File + RelativePath=".\crypto\include\rdbx.h" + > + </File> + <File + RelativePath=".\include\rtp.h" + > + </File> + <File + RelativePath=".\crypto\include\sha1.h" + > + </File> + <File + RelativePath=".\include\srtp.h" + > + </File> + <File + RelativePath=".\crypto\include\stat.h" + > + </File> + <File + RelativePath=".\include\ut_sim.h" + > + </File> + <File + RelativePath=".\crypto\include\xfm.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <File + RelativePath=".\srtp.def" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/contrib/srtp/srtp/srtp.c b/src/libs/resiprocate/contrib/srtp/srtp/srtp.c new file mode 100644 index 00000000..2cf8d570 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/srtp/srtp.c @@ -0,0 +1,1904 @@ +/* + * srtp.c + * + * the secure real-time transport protocol + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "srtp_priv.h" +#include "aes_icm.h" /* aes_icm is used in the KDF */ +#include "alloc.h" /* for crypto_alloc() */ + +#ifndef SRTP_KERNEL +# include <limits.h> +# ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +# elif defined(HAVE_WINSOCK2_H) +# include <winsock2.h> +# endif +#endif /* ! SRTP_KERNEL */ + + +extern cipher_type_t aes_icm; +extern auth_type_t tmmhv2; + +/* the debug module for srtp */ + +debug_module_t mod_srtp = { + 0, /* debugging is off by default */ + "srtp" /* printable name for module */ +}; + +#define octets_in_rtp_header 12 +#define uint32s_in_rtp_header 3 +#define octets_in_rtcp_header 8 +#define uint32s_in_rtcp_header 2 + + +err_status_t +srtp_stream_alloc(srtp_stream_ctx_t **str_ptr, + const srtp_policy_t *p) { + srtp_stream_ctx_t *str; + err_status_t stat; + + /* + * This function allocates the stream context, rtp and rtcp ciphers + * and auth functions, and key limit structure. If there is a + * failure during allocation, we free all previously allocated + * memory and return a failure code. The code could probably + * be improved, but it works and should be clear. + */ + + /* allocate srtp stream and set str_ptr */ + str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t)); + if (str == NULL) + return err_status_alloc_fail; + *str_ptr = str; + + /* allocate cipher */ + stat = crypto_kernel_alloc_cipher(p->rtp.cipher_type, + &str->rtp_cipher, + p->rtp.cipher_key_len); + if (stat) { + crypto_free(str); + return stat; + } + + /* allocate auth function */ + stat = crypto_kernel_alloc_auth(p->rtp.auth_type, + &str->rtp_auth, + p->rtp.auth_key_len, + p->rtp.auth_tag_len); + if (stat) { + cipher_dealloc(str->rtp_cipher); + crypto_free(str); + return stat; + } + + /* allocate key limit structure */ + str->limit = (key_limit_ctx_t*) crypto_alloc(sizeof(key_limit_ctx_t)); + if (str->limit == NULL) { + auth_dealloc(str->rtp_auth); + cipher_dealloc(str->rtp_cipher); + crypto_free(str); + return err_status_alloc_fail; + } + + /* + * ...and now the RTCP-specific initialization - first, allocate + * the cipher + */ + stat = crypto_kernel_alloc_cipher(p->rtcp.cipher_type, + &str->rtcp_cipher, + p->rtcp.cipher_key_len); + if (stat) { + auth_dealloc(str->rtp_auth); + cipher_dealloc(str->rtp_cipher); + crypto_free(str->limit); + crypto_free(str); + return stat; + } + + /* allocate auth function */ + stat = crypto_kernel_alloc_auth(p->rtcp.auth_type, + &str->rtcp_auth, + p->rtcp.auth_key_len, + p->rtcp.auth_tag_len); + if (stat) { + cipher_dealloc(str->rtcp_cipher); + auth_dealloc(str->rtp_auth); + cipher_dealloc(str->rtp_cipher); + crypto_free(str->limit); + crypto_free(str); + return stat; + } + + return err_status_ok; +} + +err_status_t +srtp_stream_dealloc(srtp_t session, srtp_stream_ctx_t *stream) { + err_status_t status; + + /* + * we use a conservative deallocation strategy - if any deallocation + * fails, then we report that fact without trying to deallocate + * anything else + */ + + /* deallocate cipher, if it is not the same as that in template */ + if (session->stream_template + && stream->rtp_cipher == session->stream_template->rtp_cipher) { + /* do nothing */ + } else { + status = cipher_dealloc(stream->rtp_cipher); + if (status) + return status; + } + + /* deallocate auth function, if it is not the same as that in template */ + if (session->stream_template + && stream->rtp_auth == session->stream_template->rtp_auth) { + /* do nothing */ + } else { + status = auth_dealloc(stream->rtp_auth); + if (status) + return status; + } + + /* deallocate key usage limit, if it is not the same as that in template */ + if (session->stream_template + && stream->limit == session->stream_template->limit) { + /* do nothing */ + } else { + crypto_free(stream->limit); + } + + /* + * deallocate rtcp cipher, if it is not the same as that in + * template + */ + if (session->stream_template + && stream->rtcp_cipher == session->stream_template->rtcp_cipher) { + /* do nothing */ + } else { + status = cipher_dealloc(stream->rtcp_cipher); + if (status) + return status; + } + + /* + * deallocate rtcp auth function, if it is not the same as that in + * template + */ + if (session->stream_template + && stream->rtcp_auth == session->stream_template->rtcp_auth) { + /* do nothing */ + } else { + status = auth_dealloc(stream->rtcp_auth); + if (status) + return status; + } + + /* deallocate srtp stream context */ + crypto_free(stream); + + return err_status_ok; +} + + +/* + * srtp_stream_clone(stream_template, new) allocates a new stream and + * initializes it using the cipher and auth of the stream_template + * + * the only unique data in a cloned stream is the replay database and + * the SSRC + */ + +err_status_t +srtp_stream_clone(const srtp_stream_ctx_t *stream_template, + uint32_t ssrc, + srtp_stream_ctx_t **str_ptr) { + err_status_t status; + srtp_stream_ctx_t *str; + + debug_print(mod_srtp, "cloning stream (SSRC: 0x%08x)", ssrc); + + /* allocate srtp stream and set str_ptr */ + str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t)); + if (str == NULL) + return err_status_alloc_fail; + *str_ptr = str; + + /* set cipher and auth pointers to those of the template */ + str->rtp_cipher = stream_template->rtp_cipher; + str->rtp_auth = stream_template->rtp_auth; + str->rtcp_cipher = stream_template->rtcp_cipher; + str->rtcp_auth = stream_template->rtcp_auth; + + /* set key limit to point to that of the template */ + status = key_limit_clone(stream_template->limit, &str->limit); + if (status) + return status; + + /* initialize replay databases */ + rdbx_init(&str->rtp_rdbx); + rdb_init(&str->rtcp_rdb); + + /* set ssrc to that provided */ + str->ssrc = ssrc; + + /* set direction and security services */ + str->direction = stream_template->direction; + str->rtp_services = stream_template->rtp_services; + str->rtcp_services = stream_template->rtcp_services; + + /* defensive coding */ + str->next = NULL; + + return err_status_ok; +} + + +/* + * key derivation functions, internal to libSRTP + * + * srtp_kdf_t is a key derivation context + * + * srtp_kdf_init(&kdf, k) initializes kdf with the key k + * + * srtp_kdf_generate(&kdf, l, kl, keylen) derives the key + * corresponding to label l and puts it into kl; the length + * of the key in octets is provided as keylen. this function + * should be called once for each subkey that is derived. + * + * srtp_kdf_clear(&kdf) zeroizes the kdf state + */ + +typedef enum { + label_rtp_encryption = 0x00, + label_rtp_msg_auth = 0x01, + label_rtp_salt = 0x02, + label_rtcp_encryption = 0x03, + label_rtcp_msg_auth = 0x04, + label_rtcp_salt = 0x05 +} srtp_prf_label; + + +/* + * srtp_kdf_t represents a key derivation function. The SRTP + * default KDF is the only one implemented at present. + */ + +typedef struct { + aes_icm_ctx_t c; /* cipher used for key derivation */ +} srtp_kdf_t; + +err_status_t +srtp_kdf_init(srtp_kdf_t *kdf, const uint8_t key[30]) { + + aes_icm_context_init(&kdf->c, key); + + return err_status_ok; +} + +err_status_t +srtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label, + uint8_t *key, int length) { + + v128_t nonce; + + /* set eigth octet of nonce to <label>, set the rest of it to zero */ + v128_set_to_zero(&nonce); + nonce.v8[7] = label; + + aes_icm_set_iv(&kdf->c, &nonce); + + /* generate keystream output */ + aes_icm_output(&kdf->c, key, length); + + return err_status_ok; +} + +err_status_t +srtp_kdf_clear(srtp_kdf_t *kdf) { + + /* zeroize aes context */ + octet_string_set_to_zero((uint8_t *)kdf, sizeof(srtp_kdf_t)); + + return err_status_ok; +} + +/* + * end of key derivation functions + */ + +#define MAX_SRTP_KEY_LEN 256 + + +err_status_t +srtp_stream_init_keys(srtp_stream_ctx_t *srtp, const void *key) { + err_status_t stat; + srtp_kdf_t kdf; + uint8_t tmp_key[MAX_SRTP_KEY_LEN]; + + /* initialize KDF state */ + srtp_kdf_init(&kdf, (const uint8_t *)key); + + /* generate encryption key */ + srtp_kdf_generate(&kdf, label_rtp_encryption, + tmp_key, cipher_get_key_length(srtp->rtp_cipher)); + /* + * if the cipher in the srtp context is aes_icm, then we need + * to generate the salt value + */ + if (srtp->rtp_cipher->type == &aes_icm) { + /* FIX!!! this is really the cipher key length; rest is salt */ + int base_key_len = 16; + int salt_len = cipher_get_key_length(srtp->rtp_cipher) - base_key_len; + + debug_print(mod_srtp, "found aes_icm, generating salt", NULL); + + /* generate encryption salt, put after encryption key */ + srtp_kdf_generate(&kdf, label_rtp_salt, + tmp_key + base_key_len, salt_len); + } + debug_print(mod_srtp, "cipher key: %s", + octet_string_hex_string(tmp_key, + cipher_get_key_length(srtp->rtp_cipher))); + + /* initialize cipher */ + stat = cipher_init(srtp->rtp_cipher, tmp_key, direction_any); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + + /* generate authentication key */ + srtp_kdf_generate(&kdf, label_rtp_msg_auth, + tmp_key, auth_get_key_length(srtp->rtp_auth)); + debug_print(mod_srtp, "auth key: %s", + octet_string_hex_string(tmp_key, + auth_get_key_length(srtp->rtp_auth))); + + /* initialize auth function */ + stat = auth_init(srtp->rtp_auth, tmp_key); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + + /* + * ...now initialize SRTCP keys + */ + + /* generate encryption key */ + srtp_kdf_generate(&kdf, label_rtcp_encryption, + tmp_key, cipher_get_key_length(srtp->rtcp_cipher)); + /* + * if the cipher in the srtp context is aes_icm, then we need + * to generate the salt value + */ + if (srtp->rtcp_cipher->type == &aes_icm) { + /* FIX!!! this is really the cipher key length; rest is salt */ + int base_key_len = 16; + int salt_len = cipher_get_key_length(srtp->rtcp_cipher) - base_key_len; + + debug_print(mod_srtp, "found aes_icm, generating rtcp salt", NULL); + + /* generate encryption salt, put after encryption key */ + srtp_kdf_generate(&kdf, label_rtcp_salt, + tmp_key + base_key_len, salt_len); + } + debug_print(mod_srtp, "rtcp cipher key: %s", + octet_string_hex_string(tmp_key, + cipher_get_key_length(srtp->rtcp_cipher))); + + /* initialize cipher */ + stat = cipher_init(srtp->rtcp_cipher, tmp_key, direction_any); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + + /* generate authentication key */ + srtp_kdf_generate(&kdf, label_rtcp_msg_auth, + tmp_key, auth_get_key_length(srtp->rtcp_auth)); + debug_print(mod_srtp, "rtcp auth key: %s", + octet_string_hex_string(tmp_key, + auth_get_key_length(srtp->rtcp_auth))); + + /* initialize auth function */ + stat = auth_init(srtp->rtcp_auth, tmp_key); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + + /* clear memory then return */ + srtp_kdf_clear(&kdf); + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + + return err_status_ok; +} + +err_status_t +srtp_stream_init(srtp_stream_ctx_t *srtp, + const srtp_policy_t *p) { + err_status_t err; + + debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)", + p->ssrc.value); + + /* initialize replay database */ + rdbx_init(&srtp->rtp_rdbx); + + /* initialize key limit to maximum value */ +#ifdef NO_64BIT_MATH +{ + uint64_t temp; + temp = make64(UINT_MAX,UINT_MAX); + key_limit_set(srtp->limit, temp); +} +#else + key_limit_set(srtp->limit, 0xffffffffffffLL); +#endif + + /* set the SSRC value */ + srtp->ssrc = htonl(p->ssrc.value); + + /* set the security service flags */ + srtp->rtp_services = p->rtp.sec_serv; + srtp->rtcp_services = p->rtcp.sec_serv; + + /* + * set direction to unknown - this flag gets checked in srtp_protect(), + * srtp_unprotect(), srtp_protect_rtcp(), and srtp_unprotect_rtcp(), and + * gets set appropriately if it is set to unknown. + */ + srtp->direction = dir_unknown; + + /* initialize SRTCP replay database */ + rdb_init(&srtp->rtcp_rdb); + + /* DAM - no RTCP key limit at present */ + + /* initialize keys */ + err = srtp_stream_init_keys(srtp, p->key); + if (err) return err; + + return err_status_ok; + } + + + /* + * srtp_event_reporter is an event handler function that merely + * reports the events that are reported by the callbacks + */ + + void + srtp_event_reporter(srtp_event_data_t *data) { + + err_report(err_level_warning, "srtp: in stream 0x%x: ", + data->stream->ssrc); + + switch(data->event) { + case event_ssrc_collision: + err_report(err_level_warning, "\tSSRC collision\n"); + break; + case event_key_soft_limit: + err_report(err_level_warning, "\tkey usage soft limit reached\n"); + break; + case event_key_hard_limit: + err_report(err_level_warning, "\tkey usage hard limit reached\n"); + break; + case event_packet_index_limit: + err_report(err_level_warning, "\tpacket index limit reached\n"); + break; + default: + err_report(err_level_warning, "\tunknown event reported to handler\n"); + } + } + + /* + * srtp_event_handler is a global variable holding a pointer to the + * event handler function; this function is called for any unexpected + * event that needs to be handled out of the SRTP data path. see + * srtp_event_t in srtp.h for more info + * + * it is okay to set srtp_event_handler to NULL, but we set + * it to the srtp_event_reporter. + */ + + static srtp_event_handler_func_t *srtp_event_handler = srtp_event_reporter; + + err_status_t + srtp_install_event_handler(srtp_event_handler_func_t func) { + + /* + * note that we accept NULL arguments intentionally - calling this + * function with a NULL arguments removes an event handler that's + * been previously installed + */ + + /* set global event handling function */ + srtp_event_handler = func; + return err_status_ok; + } + + err_status_t + srtp_protect(srtp_ctx_t *ctx, void *rtp_hdr, int *pkt_octet_len) { + srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr; + uint32_t *enc_start; /* pointer to start of encrypted portion */ + uint32_t *auth_start; /* pointer to start of auth. portion */ + unsigned enc_octet_len = 0; /* number of octets in encrypted portion */ + xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */ + int delta; /* delta of local pkt idx and that in hdr */ + uint8_t *auth_tag = NULL; /* location of auth_tag within packet */ + err_status_t status; + int tag_len; + srtp_stream_ctx_t *stream; + int prefix_len; + + debug_print(mod_srtp, "function srtp_protect", NULL); + + /* we assume the hdr is 32-bit aligned to start */ + + /* check the packet length - it must at least contain a full header */ + if (*pkt_octet_len < octets_in_rtp_header) + return err_status_bad_param; + + /* + * look up ssrc in srtp_stream list, and process the packet with + * the appropriate stream. if we haven't seen this stream before, + * there's a template key for this srtp_session, and the cipher + * supports key-sharing, then we assume that a new stream using + * that key has just started up + */ + stream = srtp_get_stream(ctx, hdr->ssrc); + if (stream == NULL) { + if (ctx->stream_template != NULL) { + srtp_stream_ctx_t *new_stream; + + /* allocate and initialize a new stream */ + status = srtp_stream_clone(ctx->stream_template, + hdr->ssrc, &new_stream); + if (status) + return status; + + /* add new stream to the head of the stream_list */ + new_stream->next = ctx->stream_list; + ctx->stream_list = new_stream; + + /* set direction to outbound */ + new_stream->direction = dir_srtp_sender; + + /* set stream (the pointer used in this function) */ + stream = new_stream; + } else { + /* no template stream, so we return an error */ + return err_status_no_ctx; + } + } + + /* + * verify that stream is for sending traffic - this check will + * detect SSRC collisions, since a stream that appears in both + * srtp_protect() and srtp_unprotect() will fail this test in one of + * those functions. + */ + if (stream->direction != dir_srtp_sender) { + if (stream->direction == dir_unknown) { + stream->direction = dir_srtp_sender; + } else { + srtp_handle_event(ctx, stream, event_ssrc_collision); + } + } + + /* + * update the key usage limit, and check it to make sure that we + * didn't just hit either the soft limit or the hard limit, and call + * the event handler if we hit either. + */ + switch(key_limit_update(stream->limit)) { + case key_event_normal: + break; + case key_event_soft_limit: + srtp_handle_event(ctx, stream, event_key_soft_limit); + break; + case key_event_hard_limit: + srtp_handle_event(ctx, stream, event_key_hard_limit); + return err_status_key_expired; + default: + break; + } + + /* get tag length from stream */ + tag_len = auth_get_tag_length(stream->rtp_auth); + + /* + * find starting point for encryption and length of data to be + * encrypted - the encrypted portion starts after the rtp header + * extension, if present; otherwise, it starts after the last csrc, + * if any are present + * + * if we're not providing confidentiality, set enc_start to NULL + */ + if (stream->rtp_services & sec_serv_conf) { + enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; + if (hdr->x == 1) { + srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start; + enc_start += (ntohs(xtn_hdr->length) + 1); + } + enc_octet_len = (unsigned int)(*pkt_octet_len + - ((enc_start - (uint32_t *)hdr) << 2)); + } else { + enc_start = NULL; + } + + /* + * if we're providing authentication, set the auth_start and auth_tag + * pointers to the proper locations; otherwise, set auth_start to NULL + * to indicate that no authentication is needed + */ + if (stream->rtp_services & sec_serv_auth) { + auth_start = (uint32_t *)hdr; + auth_tag = (uint8_t *)hdr + *pkt_octet_len; + } else { + auth_start = NULL; + auth_tag = NULL; + } + + /* + * estimate the packet index using the start of the replay window + * and the sequence number from the header + */ + delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq)); + status = rdbx_check(&stream->rtp_rdbx, delta); + if (status) + return status; /* we've been asked to reuse an index */ + rdbx_add_index(&stream->rtp_rdbx, delta); + +#ifdef NO_64BIT_MATH + debug_print2(mod_srtp, "estimated packet index: %08x%08x", + high32(est),low32(est)); +#else + debug_print(mod_srtp, "estimated packet index: %016llx", est); +#endif + + /* + * if we're using rindael counter mode, set nonce and seq + */ + if (stream->rtp_cipher->type == &aes_icm) { + v128_t iv; + + iv.v32[0] = 0; + iv.v32[1] = hdr->ssrc; +#ifdef NO_64BIT_MATH + iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16), + low32(est) << 16)); +#else + iv.v64[1] = be64_to_cpu(est << 16); +#endif + status = cipher_set_iv(stream->rtp_cipher, &iv); + + } else { + v128_t iv; + + /* otherwise, set the index to est */ +#ifdef NO_64BIT_MATH + iv.v32[0] = 0; + iv.v32[1] = 0; +#else + iv.v64[0] = 0; +#endif + iv.v64[1] = be64_to_cpu(est); + status = cipher_set_iv(stream->rtp_cipher, &iv); + } + if (status) + return err_status_cipher_fail; + + /* shift est, put into network byte order */ +#ifdef NO_64BIT_MATH + est = be64_to_cpu(make64((high32(est) << 16) | + (low32(est) >> 16), + low32(est) << 16)); +#else + est = be64_to_cpu(est << 16); +#endif + + /* + * if we're authenticating using a universal hash, put the keystream + * prefix into the authentication tag + */ + if (auth_start) { + + prefix_len = auth_get_prefix_length(stream->rtp_auth); + if (prefix_len) { + status = cipher_output(stream->rtp_cipher, auth_tag, prefix_len); + if (status) + return err_status_cipher_fail; + debug_print(mod_srtp, "keystream prefix: %s", + octet_string_hex_string(auth_tag, prefix_len)); + } + } + + /* if we're encrypting, exor keystream into the message */ + if (enc_start) { + status = cipher_encrypt(stream->rtp_cipher, + (uint8_t *)enc_start, &enc_octet_len); + if (status) + return err_status_cipher_fail; + } + + /* + * if we're authenticating, run authentication function and put result + * into the auth_tag + */ + if (auth_start) { + + /* initialize auth func context */ + status = auth_start(stream->rtp_auth); + if (status) return status; + + /* run auth func over packet */ + status = auth_update(stream->rtp_auth, + (uint8_t *)auth_start, *pkt_octet_len); + if (status) return status; + + /* run auth func over ROC, put result into auth_tag */ + debug_print(mod_srtp, "estimated packet index: %016llx", est); + status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, auth_tag); + debug_print(mod_srtp, "srtp auth tag: %s", + octet_string_hex_string(auth_tag, tag_len)); + if (status) + return err_status_auth_fail; + + } + + if (auth_tag) { + + /* increase the packet length by the length of the auth tag */ + *pkt_octet_len += tag_len; + } + + return err_status_ok; +} + + +err_status_t +srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) { + srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr; + uint32_t *enc_start; /* pointer to start of encrypted portion */ + uint32_t *auth_start; /* pointer to start of auth. portion */ + unsigned enc_octet_len = 0;/* number of octets in encrypted portion */ + uint8_t *auth_tag = NULL; /* location of auth_tag within packet */ + xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */ + int delta; /* delta of local pkt idx and that in hdr */ + v128_t iv; + err_status_t status; + srtp_stream_ctx_t *stream; + uint8_t tmp_tag[SRTP_MAX_TAG_LEN]; + int tag_len, prefix_len; + + debug_print(mod_srtp, "function srtp_unprotect", NULL); + + /* we assume the hdr is 32-bit aligned to start */ + + /* check the packet length - it must at least contain a full header */ + if (*pkt_octet_len < octets_in_rtp_header) + return err_status_bad_param; + + /* + * look up ssrc in srtp_stream list, and process the packet with + * the appropriate stream. if we haven't seen this stream before, + * there's only one key for this srtp_session, and the cipher + * supports key-sharing, then we assume that a new stream using + * that key has just started up + */ + stream = srtp_get_stream(ctx, hdr->ssrc); + if (stream == NULL) { + if (ctx->stream_template != NULL) { + stream = ctx->stream_template; + debug_print(mod_srtp, "using provisional stream (SSRC: 0x%08x)", + hdr->ssrc); + + /* + * set estimated packet index to sequence number from header, + * and set delta equal to the same value + */ +#ifdef NO_64BIT_MATH + est = (xtd_seq_num_t) make64(0,ntohs(hdr->seq)); + delta = low32(est); +#else + est = (xtd_seq_num_t) ntohs(hdr->seq); + delta = (int)est; +#endif + } else { + + /* + * no stream corresponding to SSRC found, and we don't do + * key-sharing, so return an error + */ + return err_status_no_ctx; + } + } else { + + /* estimate packet index from seq. num. in header */ + delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq)); + + /* check replay database */ + status = rdbx_check(&stream->rtp_rdbx, delta); + if (status) + return status; + } + +#ifdef NO_64BIT_MATH + debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),low32(est)); +#else + debug_print(mod_srtp, "estimated u_packet index: %016llx", est); +#endif + + /* get tag length from stream */ + tag_len = auth_get_tag_length(stream->rtp_auth); + + /* + * set the cipher's IV properly, depending on whatever cipher we + * happen to be using + */ + if (stream->rtp_cipher->type == &aes_icm) { + + /* aes counter mode */ + iv.v32[0] = 0; + iv.v32[1] = hdr->ssrc; /* still in network order */ +#ifdef NO_64BIT_MATH + iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16), + low32(est) << 16)); +#else + iv.v64[1] = be64_to_cpu(est << 16); +#endif + status = aes_icm_set_iv((aes_icm_ctx_t*)stream->rtp_cipher->state, &iv); + } else { + + /* no particular format - set the iv to the pakcet index */ +#ifdef NO_64BIT_MATH + iv.v32[0] = 0; + iv.v32[1] = 0; +#else + iv.v64[0] = 0; +#endif + iv.v64[1] = be64_to_cpu(est); + status = cipher_set_iv(stream->rtp_cipher, &iv); + } + if (status) + return err_status_cipher_fail; + + /* shift est, put into network byte order */ +#ifdef NO_64BIT_MATH + est = be64_to_cpu(make64((high32(est) << 16) | + (low32(est) >> 16), + low32(est) << 16)); +#else + est = be64_to_cpu(est << 16); +#endif + + /* + * find starting point for decryption and length of data to be + * decrypted - the encrypted portion starts after the rtp header + * extension, if present; otherwise, it starts after the last csrc, + * if any are present + * + * if we're not providing confidentiality, set enc_start to NULL + */ + if (stream->rtp_services & sec_serv_conf) { + enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; + if (hdr->x == 1) { + srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start; + enc_start += (ntohs(xtn_hdr->length) + 1); + } + enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len + - ((enc_start - (uint32_t *)hdr) << 2)); + } else { + enc_start = NULL; + } + + /* + * if we're providing authentication, set the auth_start and auth_tag + * pointers to the proper locations; otherwise, set auth_start to NULL + * to indicate that no authentication is needed + */ + if (stream->rtp_services & sec_serv_auth) { + auth_start = (uint32_t *)hdr; + auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len; + } else { + auth_start = NULL; + auth_tag = NULL; + } + + /* + * if we expect message authentication, run the authentication + * function and compare the result with the value of the auth_tag + */ + if (auth_start) { + + /* + * if we're using a universal hash, then we need to compute the + * keystream prefix for encrypting the universal hash output + * + * if the keystream prefix length is zero, then we know that + * the authenticator isn't using a universal hash function + */ + if (stream->rtp_auth->prefix_len != 0) { + + prefix_len = auth_get_prefix_length(stream->rtp_auth); + status = cipher_output(stream->rtp_cipher, tmp_tag, prefix_len); + debug_print(mod_srtp, "keystream prefix: %s", + octet_string_hex_string(tmp_tag, prefix_len)); + if (status) + return err_status_cipher_fail; + } + + /* initialize auth func context */ + status = auth_start(stream->rtp_auth); + if (status) return status; + + /* now compute auth function over packet */ + status = auth_update(stream->rtp_auth, (uint8_t *)auth_start, + *pkt_octet_len - tag_len); + + /* run auth func over ROC, then write tmp tag */ + status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag); + + debug_print(mod_srtp, "computed auth tag: %s", + octet_string_hex_string(tmp_tag, tag_len)); + debug_print(mod_srtp, "packet auth tag: %s", + octet_string_hex_string(auth_tag, tag_len)); + if (status) + return err_status_auth_fail; + + if (octet_string_is_eq(tmp_tag, auth_tag, tag_len)) + return err_status_auth_fail; + } + + /* + * update the key usage limit, and check it to make sure that we + * didn't just hit either the soft limit or the hard limit, and call + * the event handler if we hit either. + */ + switch(key_limit_update(stream->limit)) { + case key_event_normal: + break; + case key_event_soft_limit: + srtp_handle_event(ctx, stream, event_key_soft_limit); + break; + case key_event_hard_limit: + srtp_handle_event(ctx, stream, event_key_hard_limit); + return err_status_key_expired; + default: + break; + } + + /* if we're encrypting, add keystream into ciphertext */ + if (enc_start) { + status = cipher_encrypt(stream->rtp_cipher, + (uint8_t *)enc_start, &enc_octet_len); + if (status) + return err_status_cipher_fail; + } + + /* + * verify that stream is for received traffic - this check will + * detect SSRC collisions, since a stream that appears in both + * srtp_protect() and srtp_unprotect() will fail this test in one of + * those functions. + * + * we do this check *after* the authentication check, so that the + * latter check will catch any attempts to fool us into thinking + * that we've got a collision + */ + if (stream->direction != dir_srtp_receiver) { + if (stream->direction == dir_unknown) { + stream->direction = dir_srtp_receiver; + } else { + srtp_handle_event(ctx, stream, event_ssrc_collision); + } + } + + /* + * if the stream is a 'provisional' one, in which the template context + * is used, then we need to allocate a new stream at this point, since + * the authentication passed + */ + if (stream == ctx->stream_template) { + srtp_stream_ctx_t *new_stream; + + /* + * allocate and initialize a new stream + * + * note that we indicate failure if we can't allocate the new + * stream, and some implementations will want to not return + * failure here + */ + status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); + if (status) + return status; + + /* add new stream to the head of the stream_list */ + new_stream->next = ctx->stream_list; + ctx->stream_list = new_stream; + + /* set stream (the pointer used in this function) */ + stream = new_stream; + } + + /* + * the message authentication function passed, so add the packet + * index into the replay database + */ + rdbx_add_index(&stream->rtp_rdbx, delta); + + /* decrease the packet length by the length of the auth tag */ + *pkt_octet_len -= tag_len; + + return err_status_ok; +} + +err_status_t +srtp_init() { + err_status_t status; + + /* initialize crypto kernel */ + status = crypto_kernel_init(); + if (status) + return status; + + /* load srtp debug module into the kernel */ + status = crypto_kernel_load_debug_module(&mod_srtp); + if (status) + return status; + + return err_status_ok; +} + +/* + * The following code is under consideration for removal. See + * SRTP_MAX_TRAILER_LEN + */ +#if 0 + +/* + * srtp_get_trailer_length(&a) returns the number of octets that will + * be added to an RTP packet by the SRTP processing. This value + * is constant for a given srtp_stream_t (i.e. between initializations). + */ + +int +srtp_get_trailer_length(const srtp_stream_t s) { + return auth_get_tag_length(s->rtp_auth); +} + +#endif + +/* + * srtp_get_stream(ssrc) returns a pointer to the stream corresponding + * to ssrc, or NULL if no stream exists for that ssrc + * + * this is an internal function + */ + +srtp_stream_ctx_t * +srtp_get_stream(srtp_t srtp, uint32_t ssrc) { + srtp_stream_ctx_t *stream; + + /* walk down list until ssrc is found */ + stream = srtp->stream_list; + while (stream != NULL) { + if (stream->ssrc == ssrc) + return stream; + stream = stream->next; + } + + /* we haven't found our ssrc, so return a null */ + return NULL; +} + +err_status_t +srtp_dealloc(srtp_t session) { + srtp_stream_ctx_t *stream; + err_status_t status; + + /* + * we take a conservative deallocation strategy - if we encounter an + * error deallocating a stream, then we stop trying to deallocate + * memory and just return an error + */ + + /* walk list of streams, deallocating as we go */ + stream = session->stream_list; + while (stream != NULL) { + srtp_stream_t next = stream->next; + status = srtp_stream_dealloc(session, stream); + if (status) + return status; + stream = next; + } + + /* deallocate stream template, if there is one */ + if (session->stream_template != NULL) { + status = auth_dealloc(session->stream_template->rtcp_auth); + if (status) + return status; + status = cipher_dealloc(session->stream_template->rtcp_cipher); + if (status) + return status; + crypto_free(session->stream_template->limit); + status = cipher_dealloc(session->stream_template->rtp_cipher); + if (status) + return status; + status = auth_dealloc(session->stream_template->rtp_auth); + if (status) + return status; + crypto_free(session->stream_template); + } + + /* deallocate session context */ + crypto_free(session); + + return err_status_ok; +} + + +err_status_t +srtp_add_stream(srtp_t session, + const srtp_policy_t *policy) { + err_status_t status; + srtp_stream_t tmp; + + /* sanity check arguments */ + if ((session == NULL) || (policy == NULL) || (policy->key == NULL)) + return err_status_bad_param; + + /* allocate stream */ + status = srtp_stream_alloc(&tmp, policy); + if (status) { + return status; + } + + /* initialize stream */ + status = srtp_stream_init(tmp, policy); + if (status) { + crypto_free(tmp); + return status; + } + + /* + * set the head of the stream list or the template to point to the + * stream that we've just alloced and init'ed, depending on whether + * or not it has a wildcard SSRC value or not + * + * if the template stream has already been set, then the policy is + * inconsistent, so we return a bad_param error code + */ + switch (policy->ssrc.type) { + case (ssrc_any_outbound): + if (session->stream_template) { + return err_status_bad_param; + } + session->stream_template = tmp; + session->stream_template->direction = dir_srtp_sender; + break; + case (ssrc_any_inbound): + if (session->stream_template) { + return err_status_bad_param; + } + session->stream_template = tmp; + session->stream_template->direction = dir_srtp_receiver; + break; + case (ssrc_specific): + tmp->next = session->stream_list; + session->stream_list = tmp; + break; + case (ssrc_undefined): + default: + crypto_free(tmp); + return err_status_bad_param; + } + + return err_status_ok; +} + + +err_status_t +srtp_create(srtp_t *session, /* handle for session */ + const srtp_policy_t *policy) { /* SRTP policy (list) */ + err_status_t stat; + srtp_ctx_t *ctx; + + /* sanity check arguments */ + if (session == NULL) + return err_status_bad_param; + + /* allocate srtp context and set ctx_ptr */ + ctx = (srtp_ctx_t *) crypto_alloc(sizeof(srtp_ctx_t)); + if (ctx == NULL) + return err_status_alloc_fail; + *session = ctx; + + /* + * loop over elements in the policy list, allocating and + * initializing a stream for each element + */ + ctx->stream_template = NULL; + ctx->stream_list = NULL; + while (policy != NULL) { + + stat = srtp_add_stream(ctx, policy); + if (stat) { + /* clean up everything */ + srtp_dealloc(*session); + return stat; + } + + /* set policy to next item in list */ + policy = policy->next; + } + + return err_status_ok; +} + + +err_status_t +srtp_remove_stream(srtp_t session, uint32_t ssrc) { + srtp_stream_ctx_t *stream, *last_stream; + err_status_t status; + + /* sanity check arguments */ + if (session == NULL) + return err_status_bad_param; + + /* find stream in list; complain if not found */ + last_stream = stream = session->stream_list; + while ((stream != NULL) && (ssrc != stream->ssrc)) { + last_stream = stream; + stream = stream->next; + } + if (stream == NULL) + return err_status_no_ctx; + + /* remove stream from the list */ + last_stream->next = stream->next; + + /* deallocate the stream */ + status = srtp_stream_dealloc(session, stream); + if (status) + return status; + + return err_status_ok; +} + + +/* + * the default policy - provides a convenient way for callers to use + * the default security policy + * + * this policy is that defined in the current SRTP internet draft. + * + */ + +/* + * NOTE: cipher_key_len is really key len (128 bits) plus salt len + * (112 bits) + */ +/* There are hard-coded 16's for base_key_len in the key generation code */ + +void +crypto_policy_set_rtp_default(crypto_policy_t *p) { + + p->cipher_type = AES_128_ICM; + p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */ + p->auth_type = HMAC_SHA1; + p->auth_key_len = 20; /* default 160 bits per RFC 3711 */ + p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */ + p->sec_serv = sec_serv_conf_and_auth; + +} + +void +crypto_policy_set_rtcp_default(crypto_policy_t *p) { + + p->cipher_type = AES_128_ICM; + p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */ + p->auth_type = HMAC_SHA1; + p->auth_key_len = 20; /* default 160 bits per RFC 3711 */ + p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */ + p->sec_serv = sec_serv_conf_and_auth; + +} + +void +crypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p) { + + /* + * corresponds to draft-ietf-mmusic-sdescriptions-12.txt + * + * note that this crypto policy is intended for SRTP, but not SRTCP + */ + + p->cipher_type = AES_128_ICM; + p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */ + p->auth_type = HMAC_SHA1; + p->auth_key_len = 20; /* 160 bit key */ + p->auth_tag_len = 4; /* 32 bit tag */ + p->sec_serv = sec_serv_conf_and_auth; + +} + + +void +crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p) { + + /* + * corresponds to draft-ietf-mmusic-sdescriptions-12.txt + * + * note that this crypto policy is intended for SRTP, but not SRTCP + */ + + p->cipher_type = AES_128_ICM; + p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */ + p->auth_type = NULL_AUTH; + p->auth_key_len = 0; + p->auth_tag_len = 0; + p->sec_serv = sec_serv_conf; + +} + + +void +crypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p) { + + /* + * corresponds to draft-ietf-mmusic-sdescriptions-12.txt + */ + + p->cipher_type = NULL_CIPHER; + p->cipher_key_len = 0; + p->auth_type = HMAC_SHA1; + p->auth_key_len = 20; + p->auth_tag_len = 10; + p->sec_serv = sec_serv_auth; + +} + + +/* + * secure rtcp functions + */ + +err_status_t +srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) { + srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr; + uint32_t *enc_start; /* pointer to start of encrypted portion */ + uint32_t *auth_start; /* pointer to start of auth. portion */ + uint32_t *trailer; /* pointer to start of trailer */ + unsigned enc_octet_len = 0;/* number of octets in encrypted portion */ + uint8_t *auth_tag = NULL; /* location of auth_tag within packet */ + err_status_t status; + int tag_len; + srtp_stream_ctx_t *stream; + int prefix_len; + uint32_t seq_num; + + /* we assume the hdr is 32-bit aligned to start */ + /* + * look up ssrc in srtp_stream list, and process the packet with + * the appropriate stream. if we haven't seen this stream before, + * there's only one key for this srtp_session, and the cipher + * supports key-sharing, then we assume that a new stream using + * that key has just started up + */ + stream = srtp_get_stream(ctx, hdr->ssrc); + if (stream == NULL) { + if (ctx->stream_template != NULL) { + srtp_stream_ctx_t *new_stream; + + /* allocate and initialize a new stream */ + status = srtp_stream_clone(ctx->stream_template, + hdr->ssrc, &new_stream); + if (status) + return status; + + /* add new stream to the head of the stream_list */ + new_stream->next = ctx->stream_list; + ctx->stream_list = new_stream; + + /* set stream (the pointer used in this function) */ + stream = new_stream; + } else { + /* no template stream, so we return an error */ + return err_status_no_ctx; + } + } + + /* + * verify that stream is for sending traffic - this check will + * detect SSRC collisions, since a stream that appears in both + * srtp_protect() and srtp_unprotect() will fail this test in one of + * those functions. + */ + if (stream->direction != dir_srtp_sender) { + if (stream->direction == dir_unknown) { + stream->direction = dir_srtp_sender; + } else { + srtp_handle_event(ctx, stream, event_ssrc_collision); + } + } + + /* get tag length from stream context */ + tag_len = auth_get_tag_length(stream->rtcp_auth); + + /* + * set encryption start and encryption length - if we're not + * providing confidentiality, set enc_start to NULL + */ + enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header; + enc_octet_len = *pkt_octet_len - octets_in_rtcp_header; + + /* all of the packet, except the header, gets encrypted */ + /* NOTE: hdr->length is not usable - it refers to only the first + RTCP report in the compound packet! */ + /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always + multiples of 32-bits (RFC 3550 6.1) */ + trailer = (uint32_t *) ((char *)enc_start + enc_octet_len); + + if (stream->rtcp_services & sec_serv_conf) { + *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */ + } else { + enc_start = NULL; + enc_octet_len = 0; + /* 0 is network-order independant */ + *trailer = 0x00000000; /* set encrypt bit */ + } + + /* + * set the auth_start and auth_tag pointers to the proper locations + * (note that srtpc *always* provides authentication, unlike srtp) + */ + /* Note: This would need to change for optional mikey data */ + auth_start = (uint32_t *)hdr; + auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t); + + /* + * check sequence number for overruns, and copy it into the packet + * if its value isn't too big + */ + status = rdb_increment(&stream->rtcp_rdb); + if (status) + return status; + seq_num = rdb_get_value(&stream->rtcp_rdb); + *trailer |= htonl(seq_num); + debug_print(mod_srtp, "srtcp index: %x", seq_num); + + /* + * if we're using rindael counter mode, set nonce and seq + */ + if (stream->rtcp_cipher->type == &aes_icm) { + v128_t iv; + + iv.v32[0] = 0; + iv.v32[1] = hdr->ssrc; /* still in network order! */ + iv.v32[2] = htonl(seq_num >> 16); + iv.v32[3] = htonl(seq_num << 16); + status = aes_icm_set_iv((aes_icm_ctx_t*)stream->rtcp_cipher->state, &iv); + + } else { + v128_t iv; + + /* otherwise, just set the index to seq_num */ + iv.v32[0] = 0; + iv.v32[1] = 0; + iv.v32[2] = 0; + iv.v32[3] = htonl(seq_num); + status = cipher_set_iv(stream->rtcp_cipher, &iv); + } + if (status) + return err_status_cipher_fail; + + /* + * if we're authenticating using a universal hash, put the keystream + * prefix into the authentication tag + */ + + /* if auth_start is non-null, then put keystream into tag */ + if (auth_start) { + + /* put keystream prefix into auth_tag */ + prefix_len = auth_get_prefix_length(stream->rtcp_auth); + status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len); + + debug_print(mod_srtp, "keystream prefix: %s", + octet_string_hex_string(auth_tag, prefix_len)); + + if (status) + return err_status_cipher_fail; + } + + /* if we're encrypting, exor keystream into the message */ + if (enc_start) { + status = cipher_encrypt(stream->rtcp_cipher, + (uint8_t *)enc_start, &enc_octet_len); + if (status) + return err_status_cipher_fail; + } + + /* initialize auth func context */ + auth_start(stream->rtcp_auth); + + /* + * run auth func over packet (including trailer), and write the + * result at auth_tag + */ + status = auth_compute(stream->rtcp_auth, + (uint8_t *)auth_start, + (*pkt_octet_len) + sizeof(srtcp_trailer_t), + auth_tag); + debug_print(mod_srtp, "srtcp auth tag: %s", + octet_string_hex_string(auth_tag, tag_len)); + if (status) + return err_status_auth_fail; + + /* increase the packet length by the length of the auth tag and seq_num*/ + *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t)); + + return err_status_ok; +} + + +err_status_t +srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) { + srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr; + uint32_t *enc_start; /* pointer to start of encrypted portion */ + uint32_t *auth_start; /* pointer to start of auth. portion */ + uint32_t *trailer; /* pointer to start of trailer */ + unsigned enc_octet_len = 0;/* number of octets in encrypted portion */ + uint8_t *auth_tag = NULL; /* location of auth_tag within packet */ + uint8_t tmp_tag[SRTP_MAX_TAG_LEN]; + err_status_t status; + int tag_len; + srtp_stream_ctx_t *stream; + int prefix_len; + uint32_t seq_num; + + /* we assume the hdr is 32-bit aligned to start */ + /* + * look up ssrc in srtp_stream list, and process the packet with + * the appropriate stream. if we haven't seen this stream before, + * there's only one key for this srtp_session, and the cipher + * supports key-sharing, then we assume that a new stream using + * that key has just started up + */ + stream = srtp_get_stream(ctx, hdr->ssrc); + if (stream == NULL) { + if (ctx->stream_template != NULL) { + stream = ctx->stream_template; + debug_print(mod_srtp, "srtcp using provisional stream (SSRC: 0x%08x)", + hdr->ssrc); + } else { + /* no template stream, so we return an error */ + return err_status_no_ctx; + } + } + + /* get tag length from stream context */ + tag_len = auth_get_tag_length(stream->rtcp_auth); + + /* + * set encryption start, encryption length, and trailer + */ + enc_octet_len = *pkt_octet_len - + (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t)); + /* index & E (encryption) bit follow normal data. hdr->len + is the number of words (32-bit) in the normal packet minus 1 */ + /* This should point trailer to the word past the end of the + normal data. */ + /* This would need to be modified for optional mikey data */ + /* + * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always + * multiples of 32-bits (RFC 3550 6.1) + */ + trailer = (uint32_t *) ((char *) hdr + + *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t))); + if (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT) { + enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header; + } else { + enc_octet_len = 0; + enc_start = NULL; /* this indicates that there's no encryption */ + } + + /* + * set the auth_start and auth_tag pointers to the proper locations + * (note that srtcp *always* uses authentication, unlike srtp) + */ + auth_start = (uint32_t *)hdr; + auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len; + + /* + * check the sequence number for replays + */ + /* this is easier than dealing with bitfield access */ + seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK; + debug_print(mod_srtp, "srtcp index: %x", seq_num); + status = rdb_check(&stream->rtcp_rdb, seq_num); + if (status) + return status; + + /* + * if we're using aes counter mode, set nonce and seq + */ + if (stream->rtcp_cipher->type == &aes_icm) { + v128_t iv; + + iv.v32[0] = 0; + iv.v32[1] = hdr->ssrc; /* still in network order! */ + iv.v32[2] = htonl(seq_num >> 16); + iv.v32[3] = htonl(seq_num << 16); + status = aes_icm_set_iv((aes_icm_ctx_t*)stream->rtcp_cipher->state, &iv); + + } else { + v128_t iv; + + /* otherwise, just set the index to seq_num */ + iv.v32[0] = 0; + iv.v32[1] = 0; + iv.v32[2] = 0; + iv.v32[3] = htonl(seq_num); + status = cipher_set_iv(stream->rtcp_cipher, &iv); + + } + if (status) + return err_status_cipher_fail; + + /* initialize auth func context */ + auth_start(stream->rtcp_auth); + + /* run auth func over packet, put result into tmp_tag */ + status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start, + *pkt_octet_len - tag_len, + tmp_tag); + debug_print(mod_srtp, "srtcp computed tag: %s", + octet_string_hex_string(tmp_tag, tag_len)); + if (status) + return err_status_auth_fail; + + /* compare the tag just computed with the one in the packet */ + debug_print(mod_srtp, "srtcp tag from packet: %s", + octet_string_hex_string(auth_tag, tag_len)); + if (octet_string_is_eq(tmp_tag, auth_tag, tag_len)) + return err_status_auth_fail; + + /* + * if we're authenticating using a universal hash, put the keystream + * prefix into the authentication tag + */ + prefix_len = auth_get_prefix_length(stream->rtcp_auth); + if (prefix_len) { + status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len); + debug_print(mod_srtp, "keystream prefix: %s", + octet_string_hex_string(auth_tag, prefix_len)); + if (status) + return err_status_cipher_fail; + } + + /* if we're decrypting, exor keystream into the message */ + if (enc_start) { + status = cipher_encrypt(stream->rtcp_cipher, + (uint8_t *)enc_start, &enc_octet_len); + if (status) + return err_status_cipher_fail; + } + + /* decrease the packet length by the length of the auth tag and seq_num*/ + *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t)); + + /* + * verify that stream is for received traffic - this check will + * detect SSRC collisions, since a stream that appears in both + * srtp_protect() and srtp_unprotect() will fail this test in one of + * those functions. + * + * we do this check *after* the authentication check, so that the + * latter check will catch any attempts to fool us into thinking + * that we've got a collision + */ + if (stream->direction != dir_srtp_receiver) { + if (stream->direction == dir_unknown) { + stream->direction = dir_srtp_receiver; + } else { + srtp_handle_event(ctx, stream, event_ssrc_collision); + } + } + + /* + * if the stream is a 'provisional' one, in which the template context + * is used, then we need to allocate a new stream at this point, since + * the authentication passed + */ + if (stream == ctx->stream_template) { + srtp_stream_ctx_t *new_stream; + + /* + * allocate and initialize a new stream + * + * note that we indicate failure if we can't allocate the new + * stream, and some implementations will want to not return + * failure here + */ + status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); + if (status) + return status; + + /* add new stream to the head of the stream_list */ + new_stream->next = ctx->stream_list; + ctx->stream_list = new_stream; + + /* set stream (the pointer used in this function) */ + stream = new_stream; + } + + /* we've passed the authentication check, so add seq_num to the rdb */ + rdb_add_index(&stream->rtcp_rdb, seq_num); + + + return err_status_ok; +} + + + +/* + * dtls keying for srtp + */ + +err_status_t +crypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy, + srtp_profile_t profile) { + + /* set SRTP policy from the SRTP profile in the key set */ + switch(profile) { + case srtp_profile_aes128_cm_sha1_80: + crypto_policy_set_aes_cm_128_hmac_sha1_80(policy); + break; + case srtp_profile_aes128_cm_sha1_32: + crypto_policy_set_aes_cm_128_hmac_sha1_32(policy); + break; + case srtp_profile_null_sha1_80: + crypto_policy_set_null_cipher_hmac_sha1_80(policy); + break; + /* the following profiles are not (yet) supported */ + case srtp_profile_null_sha1_32: + case srtp_profile_aes256_cm_sha1_80: + case srtp_profile_aes256_cm_sha1_32: + default: + return err_status_bad_param; + } + + return err_status_ok; +} + +err_status_t +crypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy, + srtp_profile_t profile) { + + /* set SRTP policy from the SRTP profile in the key set */ + switch(profile) { + case srtp_profile_aes128_cm_sha1_80: + crypto_policy_set_aes_cm_128_hmac_sha1_80(policy); + break; + case srtp_profile_aes128_cm_sha1_32: + crypto_policy_set_aes_cm_128_hmac_sha1_32(policy); + break; + case srtp_profile_null_sha1_80: + crypto_policy_set_null_cipher_hmac_sha1_80(policy); + break; + /* the following profiles are not (yet) supported */ + case srtp_profile_null_sha1_32: + case srtp_profile_aes256_cm_sha1_80: + case srtp_profile_aes256_cm_sha1_32: + default: + return err_status_bad_param; + } + + return err_status_ok; +} + +void +append_salt_to_key(uint8_t *key, unsigned int bytes_in_key, + uint8_t *salt, unsigned int bytes_in_salt) { + + memcpy(key + bytes_in_key, salt, bytes_in_salt); + +} + +unsigned int +srtp_profile_get_master_key_length(srtp_profile_t profile) { + + switch(profile) { + case srtp_profile_aes128_cm_sha1_80: + return 16; + break; + case srtp_profile_aes128_cm_sha1_32: + return 16; + break; + case srtp_profile_null_sha1_80: + return 16; + break; + /* the following profiles are not (yet) supported */ + case srtp_profile_null_sha1_32: + case srtp_profile_aes256_cm_sha1_80: + case srtp_profile_aes256_cm_sha1_32: + default: + return 0; /* indicate error by returning a zero */ + } +} + +unsigned int +srtp_profile_get_master_salt_length(srtp_profile_t profile) { + + switch(profile) { + case srtp_profile_aes128_cm_sha1_80: + return 14; + break; + case srtp_profile_aes128_cm_sha1_32: + return 14; + break; + case srtp_profile_null_sha1_80: + return 14; + break; + /* the following profiles are not (yet) supported */ + case srtp_profile_null_sha1_32: + case srtp_profile_aes256_cm_sha1_80: + case srtp_profile_aes256_cm_sha1_32: + default: + return 0; /* indicate error by returning a zero */ + } +} diff --git a/src/libs/resiprocate/contrib/srtp/srtp10.vcxproj b/src/libs/resiprocate/contrib/srtp/srtp10.vcxproj new file mode 100644 index 00000000..4cf1f470 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/srtp10.vcxproj @@ -0,0 +1,269 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug Dll|Win32"> + <Configuration>Debug Dll</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release Dll|Win32"> + <Configuration>Release Dll</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>libSRTP</ProjectName> + <ProjectGuid>{EEF031CB-FED8-451E-A471-91EC8D4F6750}</ProjectGuid> + <RootNamespace>libSRTP</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Dll|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Dll|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Dll|Win32'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Dll|Win32'">$(Configuration)\</IntDir> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release Dll|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release Dll|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release Dll|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <PreBuildEvent> + <Message>Creating config.h from config.hw</Message> + <Command>copy /Y "$(ProjectDir)config.hw" "$(ProjectDir)crypto\include\config.h" &gt; NUL</Command> + </PreBuildEvent> + <CustomBuildStep> + <Message> + </Message> + <Command> + </Command> + <Outputs>%(Outputs)</Outputs> + </CustomBuildStep> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>crypto/include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <StructMemberAlignment>Default</StructMemberAlignment> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <PreBuildEvent> + <Message>Creating config.h from config.hw</Message> + <Command>copy /Y "$(ProjectDir)config.hw" "$(ProjectDir)crypto\include\config.h" &gt; NUL</Command> + </PreBuildEvent> + <CustomBuildStep> + <Message> + </Message> + <Command> + </Command> + <Outputs>%(Outputs)</Outputs> + </CustomBuildStep> + <ClCompile> + <AdditionalIncludeDirectories>crypto/include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <StructMemberAlignment>Default</StructMemberAlignment> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'"> + <PreBuildEvent> + <Message>Creating config.h from config.hw</Message> + <Command>copy /Y "$(ProjectDir)config.hw" "$(ProjectDir)crypto\include\config.h" &gt; NUL</Command> + </PreBuildEvent> + <CustomBuildStep> + <Message> + </Message> + <Command> + </Command> + <Outputs>%(Outputs)</Outputs> + </CustomBuildStep> + <ClCompile> + <Optimization>Disabled</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <AdditionalIncludeDirectories>crypto/include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <StructMemberAlignment>Default</StructMemberAlignment> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile>srtp.def</ModuleDefinitionFile> + <OptimizeReferences>false</OptimizeReferences> + <EnableCOMDATFolding>false</EnableCOMDATFolding> + <LinkTimeCodeGeneration> + </LinkTimeCodeGeneration> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Dll|Win32'"> + <PreBuildEvent> + <Message>Creating config.h from config.hw</Message> + <Command>copy /Y "$(ProjectDir)config.hw" "$(ProjectDir)crypto\include\config.h" &gt; NUL</Command> + </PreBuildEvent> + <CustomBuildStep> + <Message> + </Message> + <Command> + </Command> + <Outputs>%(Outputs)</Outputs> + </CustomBuildStep> + <ClCompile> + <AdditionalIncludeDirectories>crypto/include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <StructMemberAlignment>Default</StructMemberAlignment> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile>srtp.def</ModuleDefinitionFile> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="srtp\srtp.c" /> + <ClCompile Include="crypto\kernel\alloc.c" /> + <ClCompile Include="crypto\kernel\crypto_kernel.c" /> + <ClCompile Include="crypto\rng\ctr_prng.c" /> + <ClCompile Include="crypto\kernel\err.c" /> + <ClCompile Include="crypto\kernel\key.c" /> + <ClCompile Include="crypto\rng\prng.c" /> + <ClCompile Include="crypto\rng\rand_source.c" /> + <ClCompile Include="crypto\cipher\aes.c"> + <InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">Default</InlineFunctionExpansion> + <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">false</IntrinsicFunctions> + <FunctionLevelLinking Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">false</FunctionLevelLinking> + </ClCompile> + <ClCompile Include="crypto\cipher\aes_cbc.c" /> + <ClCompile Include="crypto\cipher\aes_icm.c" /> + <ClCompile Include="crypto\cipher\cipher.c" /> + <ClCompile Include="crypto\cipher\null_cipher.c" /> + <ClCompile Include="crypto\hash\auth.c" /> + <ClCompile Include="crypto\hash\hmac.c" /> + <ClCompile Include="crypto\hash\null_auth.c" /> + <ClCompile Include="crypto\hash\sha1.c" /> + <ClCompile Include="crypto\replay\rdb.c" /> + <ClCompile Include="crypto\replay\rdbx.c" /> + <ClCompile Include="crypto\replay\ut_sim.c" /> + <ClCompile Include="crypto\math\datatypes.c" /> + <ClCompile Include="crypto\math\stat.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="crypto\include\aes.h" /> + <ClInclude Include="crypto\include\aes_cbc.h" /> + <ClInclude Include="crypto\include\aes_icm.h" /> + <ClInclude Include="crypto\include\alloc.h" /> + <ClInclude Include="crypto\include\auth.h" /> + <ClInclude Include="crypto\include\cipher.h" /> + <ClInclude Include="crypto\include\config.h" /> + <ClInclude Include="crypto\include\crypto.h" /> + <ClInclude Include="crypto\include\crypto_kernel.h" /> + <ClInclude Include="crypto\include\crypto_math.h" /> + <ClInclude Include="crypto\include\crypto_types.h" /> + <ClInclude Include="crypto\include\cryptoalg.h" /> + <ClInclude Include="crypto\include\datatypes.h" /> + <ClInclude Include="crypto\include\err.h" /> + <ClInclude Include="crypto\include\gf2_8.h" /> + <ClInclude Include="crypto\include\hmac.h" /> + <ClInclude Include="crypto\include\integers.h" /> + <ClInclude Include="crypto\include\kernel_compat.h" /> + <ClInclude Include="crypto\include\key.h" /> + <ClInclude Include="crypto\include\null_auth.h" /> + <ClInclude Include="crypto\include\null_cipher.h" /> + <ClInclude Include="crypto\include\prng.h" /> + <ClInclude Include="crypto\include\rand_source.h" /> + <ClInclude Include="crypto\include\rdb.h" /> + <ClInclude Include="crypto\include\rdbx.h" /> + <ClInclude Include="include\rtp.h" /> + <ClInclude Include="crypto\include\sha1.h" /> + <ClInclude Include="include\srtp.h" /> + <ClInclude Include="crypto\include\stat.h" /> + <ClInclude Include="include\ut_sim.h" /> + <ClInclude Include="crypto\include\xfm.h" /> + </ItemGroup> + <ItemGroup> + <None Include="srtp.def" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/srtp/srtp10.vcxproj.filters b/src/libs/resiprocate/contrib/srtp/srtp10.vcxproj.filters new file mode 100644 index 00000000..46850450 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/srtp10.vcxproj.filters @@ -0,0 +1,200 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Source Files\Kernel"> + <UniqueIdentifier>{37e0a933-f94c-480e-bf0f-2c2cd5281dc1}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Ciphers"> + <UniqueIdentifier>{9ca8e582-3846-4f76-98e5-eb13c4cd59ee}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Hashes"> + <UniqueIdentifier>{1df6957d-cf62-4436-a44b-c1b040a59d72}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Replay"> + <UniqueIdentifier>{10f95d8d-733c-473b-9b93-68bde892b3ed}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Math"> + <UniqueIdentifier>{5887afcc-75a9-443c-9648-ba9a0aa000a5}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="srtp\srtp.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="crypto\kernel\alloc.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\kernel\crypto_kernel.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\rng\ctr_prng.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\kernel\err.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\kernel\key.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\rng\prng.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\rng\rand_source.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\cipher\aes.c"> + <Filter>Source Files\Ciphers</Filter> + </ClCompile> + <ClCompile Include="crypto\cipher\aes_cbc.c"> + <Filter>Source Files\Ciphers</Filter> + </ClCompile> + <ClCompile Include="crypto\cipher\aes_icm.c"> + <Filter>Source Files\Ciphers</Filter> + </ClCompile> + <ClCompile Include="crypto\cipher\cipher.c"> + <Filter>Source Files\Ciphers</Filter> + </ClCompile> + <ClCompile Include="crypto\cipher\null_cipher.c"> + <Filter>Source Files\Ciphers</Filter> + </ClCompile> + <ClCompile Include="crypto\hash\auth.c"> + <Filter>Source Files\Hashes</Filter> + </ClCompile> + <ClCompile Include="crypto\hash\hmac.c"> + <Filter>Source Files\Hashes</Filter> + </ClCompile> + <ClCompile Include="crypto\hash\null_auth.c"> + <Filter>Source Files\Hashes</Filter> + </ClCompile> + <ClCompile Include="crypto\hash\sha1.c"> + <Filter>Source Files\Hashes</Filter> + </ClCompile> + <ClCompile Include="crypto\replay\rdb.c"> + <Filter>Source Files\Replay</Filter> + </ClCompile> + <ClCompile Include="crypto\replay\rdbx.c"> + <Filter>Source Files\Replay</Filter> + </ClCompile> + <ClCompile Include="crypto\replay\ut_sim.c"> + <Filter>Source Files\Replay</Filter> + </ClCompile> + <ClCompile Include="crypto\math\datatypes.c"> + <Filter>Source Files\Math</Filter> + </ClCompile> + <ClCompile Include="crypto\math\stat.c"> + <Filter>Source Files\Math</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="crypto\include\aes.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\aes_cbc.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\aes_icm.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\alloc.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\auth.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\cipher.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\config.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\crypto.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\crypto_kernel.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\crypto_math.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\crypto_types.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\cryptoalg.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\datatypes.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\err.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\gf2_8.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\hmac.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\integers.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\kernel_compat.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\key.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\null_auth.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\null_cipher.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\prng.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\rand_source.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\rdb.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\rdbx.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="include\rtp.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\sha1.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="include\srtp.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\stat.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="include\ut_sim.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\xfm.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="srtp.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/srtp/srtp7.sln b/src/libs/resiprocate/contrib/srtp/srtp7.sln new file mode 100644 index 00000000..a963bf39 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/srtp7.sln @@ -0,0 +1,23 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libSRTP", "srtp7.vcproj", "{7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Debug.ActiveCfg = Debug|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Debug.Build.0 = Debug|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Release.ActiveCfg = Release|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/contrib/srtp/srtp7.vcproj b/src/libs/resiprocate/contrib/srtp/srtp7.vcproj new file mode 100644 index 00000000..fd9de3e3 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/srtp7.vcproj @@ -0,0 +1,294 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="libSRTP" + ProjectGUID="{7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + InlineFunctionExpansion="0" + AdditionalIncludeDirectories="..\srtp\crypto\include;..\openssl\inc32;..\srtp\include" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;DEBUG" + ExceptionHandling="FALSE" + BasicRuntimeChecks="0" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4" + CompileAs="1"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool" + Description="Creating windows build configuration" + CommandLine="copy config.h_win32vc7 crypto\include\config.h"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\srtp\crypto\include;..\openssl\inc32;..\srtp\include" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + BasicRuntimeChecks="0" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + ObjectFile="$(IntDir)/" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool" + Description="Creating windows build configuration" + CommandLine="copy config.h_win32vc7 crypto\include\config.h"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath=".\srtp\srtp.c"> + </File> + <File + RelativePath=".\test\srtp_driver.c"> + </File> + <Filter + Name="Kernel"> + <File + RelativePath=".\crypto\kernel\alloc.c"> + </File> + <File + RelativePath=".\crypto\kernel\crypto_kernel.c"> + </File> + <File + RelativePath=".\crypto\rng\ctr_prng.c"> + </File> + <File + RelativePath=".\crypto\kernel\err.c"> + </File> + <File + RelativePath=".\crypto\kernel\key.c"> + </File> + <File + RelativePath=".\crypto\rng\prng.c"> + </File> + <File + RelativePath=".\crypto\rng\rand_source.c"> + </File> + </Filter> + <Filter + Name="Ciphers"> + <File + RelativePath=".\crypto\cipher\aes.c"> + </File> + <File + RelativePath=".\crypto\cipher\aes_cbc.c"> + </File> + <File + RelativePath=".\crypto\cipher\aes_icm.c"> + </File> + <File + RelativePath=".\crypto\cipher\cipher.c"> + </File> + <File + RelativePath=".\crypto\cipher\null_cipher.c"> + </File> + </Filter> + <Filter + Name="Hashes"> + <File + RelativePath=".\crypto\hash\auth.c"> + </File> + <File + RelativePath=".\crypto\hash\hmac.c"> + </File> + <File + RelativePath=".\crypto\hash\null_auth.c"> + </File> + <File + RelativePath=".\crypto\hash\sha1.c"> + </File> + </Filter> + <Filter + Name="Replay"> + <File + RelativePath=".\crypto\replay\rdb.c"> + </File> + <File + RelativePath=".\crypto\replay\rdbx.c"> + </File> + <File + RelativePath=".\crypto\replay\ut_sim.c"> + </File> + </Filter> + <Filter + Name="Math"> + <File + RelativePath=".\crypto\math\datatypes.c"> + </File> + <File + RelativePath=".\crypto\math\stat.c"> + </File> + </Filter> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath=".\crypto\include\aes.h"> + </File> + <File + RelativePath=".\crypto\include\aes_cbc.h"> + </File> + <File + RelativePath=".\crypto\include\aes_icm.h"> + </File> + <File + RelativePath=".\crypto\include\alloc.h"> + </File> + <File + RelativePath=".\crypto\include\auth.h"> + </File> + <File + RelativePath=".\crypto\include\cipher.h"> + </File> + <File + RelativePath=".\crypto\include\config.h"> + </File> + <File + RelativePath=".\crypto\include\crypto.h"> + </File> + <File + RelativePath=".\crypto\include\crypto_kernel.h"> + </File> + <File + RelativePath=".\crypto\include\crypto_math.h"> + </File> + <File + RelativePath=".\crypto\include\crypto_types.h"> + </File> + <File + RelativePath=".\crypto\include\cryptoalg.h"> + </File> + <File + RelativePath=".\crypto\include\datatypes.h"> + </File> + <File + RelativePath=".\crypto\include\err.h"> + </File> + <File + RelativePath=".\crypto\include\gf2_8.h"> + </File> + <File + RelativePath=".\crypto\include\hmac.h"> + </File> + <File + RelativePath=".\crypto\include\integers.h"> + </File> + <File + RelativePath=".\crypto\include\kernel_compat.h"> + </File> + <File + RelativePath=".\crypto\include\key.h"> + </File> + <File + RelativePath=".\crypto\include\null_auth.h"> + </File> + <File + RelativePath=".\crypto\include\null_cipher.h"> + </File> + <File + RelativePath=".\crypto\include\prng.h"> + </File> + <File + RelativePath=".\crypto\include\rand_source.h"> + </File> + <File + RelativePath=".\crypto\include\rdb.h"> + </File> + <File + RelativePath=".\crypto\include\rdbx.h"> + </File> + <File + RelativePath=".\include\rtp.h"> + </File> + <File + RelativePath=".\crypto\include\sha1.h"> + </File> + <File + RelativePath=".\include\srtp.h"> + </File> + <File + RelativePath=".\crypto\include\stat.h"> + </File> + <File + RelativePath=".\include\ut_sim.h"> + </File> + <File + RelativePath=".\crypto\include\xfm.h"> + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/contrib/srtp/srtp9.vcproj b/src/libs/resiprocate/contrib/srtp/srtp9.vcproj new file mode 100644 index 00000000..e581688f --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/srtp9.vcproj @@ -0,0 +1,587 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="libSRTP" + ProjectGUID="{EEF031CB-FED8-451E-A471-91EC8D4F6750}" + RootNamespace="libSRTP" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + Description="Creating config.h from config.hw" + CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="crypto/include;include" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + StructMemberAlignment="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + Description="Creating config.h from config.hw" + CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="crypto/include;include" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + RuntimeLibrary="2" + StructMemberAlignment="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug Dll|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + Description="Creating config.h from config.hw" + CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="crypto/include;include" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + StructMemberAlignment="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib" + ModuleDefinitionFile="srtp.def" + OptimizeReferences="1" + EnableCOMDATFolding="1" + OptimizeForWindows98="1" + LinkTimeCodeGeneration="0" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release Dll|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + Description="Creating config.h from config.hw" + CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="crypto/include;include" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + RuntimeLibrary="2" + StructMemberAlignment="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib" + ModuleDefinitionFile="srtp.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\srtp\srtp.c" + > + </File> + <Filter + Name="Kernel" + > + <File + RelativePath=".\crypto\kernel\alloc.c" + > + </File> + <File + RelativePath=".\crypto\kernel\crypto_kernel.c" + > + </File> + <File + RelativePath=".\crypto\rng\ctr_prng.c" + > + </File> + <File + RelativePath=".\crypto\kernel\err.c" + > + </File> + <File + RelativePath=".\crypto\kernel\key.c" + > + </File> + <File + RelativePath=".\crypto\rng\prng.c" + > + </File> + <File + RelativePath=".\crypto\rng\rand_source.c" + > + </File> + </Filter> + <Filter + Name="Ciphers" + > + <File + RelativePath=".\crypto\cipher\aes.c" + > + <FileConfiguration + Name="Debug Dll|Win32" + > + <Tool + Name="VCCLCompilerTool" + InlineFunctionExpansion="0" + EnableIntrinsicFunctions="false" + EnableFunctionLevelLinking="false" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\crypto\cipher\aes_cbc.c" + > + </File> + <File + RelativePath=".\crypto\cipher\aes_icm.c" + > + </File> + <File + RelativePath=".\crypto\cipher\cipher.c" + > + </File> + <File + RelativePath=".\crypto\cipher\null_cipher.c" + > + </File> + </Filter> + <Filter + Name="Hashes" + > + <File + RelativePath=".\crypto\hash\auth.c" + > + </File> + <File + RelativePath=".\crypto\hash\hmac.c" + > + </File> + <File + RelativePath=".\crypto\hash\null_auth.c" + > + </File> + <File + RelativePath=".\crypto\hash\sha1.c" + > + </File> + </Filter> + <Filter + Name="Replay" + > + <File + RelativePath=".\crypto\replay\rdb.c" + > + </File> + <File + RelativePath=".\crypto\replay\rdbx.c" + > + </File> + <File + RelativePath=".\crypto\replay\ut_sim.c" + > + </File> + </Filter> + <Filter + Name="Math" + > + <File + RelativePath=".\crypto\math\datatypes.c" + > + </File> + <File + RelativePath=".\crypto\math\stat.c" + > + </File> + </Filter> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\crypto\include\aes.h" + > + </File> + <File + RelativePath=".\crypto\include\aes_cbc.h" + > + </File> + <File + RelativePath=".\crypto\include\aes_icm.h" + > + </File> + <File + RelativePath=".\crypto\include\alloc.h" + > + </File> + <File + RelativePath=".\crypto\include\auth.h" + > + </File> + <File + RelativePath=".\crypto\include\cipher.h" + > + </File> + <File + RelativePath=".\crypto\include\config.h" + > + </File> + <File + RelativePath=".\crypto\include\crypto.h" + > + </File> + <File + RelativePath=".\crypto\include\crypto_kernel.h" + > + </File> + <File + RelativePath=".\crypto\include\crypto_math.h" + > + </File> + <File + RelativePath=".\crypto\include\crypto_types.h" + > + </File> + <File + RelativePath=".\crypto\include\cryptoalg.h" + > + </File> + <File + RelativePath=".\crypto\include\datatypes.h" + > + </File> + <File + RelativePath=".\crypto\include\err.h" + > + </File> + <File + RelativePath=".\crypto\include\gf2_8.h" + > + </File> + <File + RelativePath=".\crypto\include\hmac.h" + > + </File> + <File + RelativePath=".\crypto\include\integers.h" + > + </File> + <File + RelativePath=".\crypto\include\kernel_compat.h" + > + </File> + <File + RelativePath=".\crypto\include\key.h" + > + </File> + <File + RelativePath=".\crypto\include\null_auth.h" + > + </File> + <File + RelativePath=".\crypto\include\null_cipher.h" + > + </File> + <File + RelativePath=".\crypto\include\prng.h" + > + </File> + <File + RelativePath=".\crypto\include\rand_source.h" + > + </File> + <File + RelativePath=".\crypto\include\rdb.h" + > + </File> + <File + RelativePath=".\crypto\include\rdbx.h" + > + </File> + <File + RelativePath=".\include\rtp.h" + > + </File> + <File + RelativePath=".\crypto\include\sha1.h" + > + </File> + <File + RelativePath=".\include\srtp.h" + > + </File> + <File + RelativePath=".\crypto\include\stat.h" + > + </File> + <File + RelativePath=".\include\ut_sim.h" + > + </File> + <File + RelativePath=".\crypto\include\xfm.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <File + RelativePath=".\srtp.def" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/contrib/srtp/tables/.cvsignore b/src/libs/resiprocate/contrib/srtp/tables/.cvsignore new file mode 100644 index 00000000..45492b4a --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/tables/.cvsignore @@ -0,0 +1 @@ +aes_tables diff --git a/src/libs/resiprocate/contrib/srtp/tables/aes_tables.c b/src/libs/resiprocate/contrib/srtp/tables/aes_tables.c new file mode 100644 index 00000000..b2bc1d78 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/tables/aes_tables.c @@ -0,0 +1,346 @@ +/* + * aes_tables.c + * + * generate tables for the AES cipher + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> +#include "gf2_8.h" +#include "crypto_math.h" + + +unsigned char aes_sbox[256]; + +unsigned char aes_inv_sbox[256]; + +uint32_t T0[256], T1[256], T2[256], T3[256], T4[256]; + + +#define AES_INVERSE_TEST 0 /* set to 1 to test forward/backwards aes */ + +/* functions for precomputing AES values */ + +/* + * A[] is the 8 x 8 binary matrix (represented as an array of columns, + * where each column is an octet) which defines the affine + * transformation used in the AES substitution table (Section + * 4.2.1 of the spec). + */ + +uint8_t A[8] = { 31, 62, 124, 248, 241, 227, 199, 143 }; + +/* + * b is the 8 bit vector (represented as an octet) used in the affine + * transform described above. + */ + +uint8_t b = 99; + + +void +aes_init_sbox(void) { + unsigned int i; + uint8_t x; + + for (i=0; i < 256; i++) { + x = gf2_8_compute_inverse((gf2_8)i); + x = A_times_x_plus_b(A, x, b); + aes_sbox[i] = x; + aes_inv_sbox[x] = i; + } +} + +void +aes_compute_tables(void) { + int i; + uint32_t x1, x2, x3; + v32_t tmp; + + /* initialize substitution table */ + aes_init_sbox(); + + /* combine sbox with linear operations to form 8-bit to 32-bit tables */ + for (i=0; i < 256; i++) { + x1 = aes_sbox[i]; + x2 = gf2_8_shift(x1); + x3 = x2 ^ x1; + + tmp.v8[0] = x2; + tmp.v8[1] = x1; + tmp.v8[2] = x1; + tmp.v8[3] = x3; + T0[i] = tmp.value; + + tmp.v8[0] = x3; + tmp.v8[1] = x2; + tmp.v8[2] = x1; + tmp.v8[3] = x1; + T1[i] = tmp.value; + + tmp.v8[0] = x1; + tmp.v8[1] = x3; + tmp.v8[2] = x2; + tmp.v8[3] = x1; + T2[i] = tmp.value; + + tmp.v8[0] = x1; + tmp.v8[1] = x1; + tmp.v8[2] = x3; + tmp.v8[3] = x2; + T3[i] = tmp.value; + + } +} + + +/* + * the tables U0, U1, U2, U3 implement the aes operations invSubBytes, + * invMixColumns, and invShiftRows + */ + +uint32_t U0[256], U1[256], U2[256], U3[256], U4[256]; + +extern uint8_t aes_inv_sbox[256]; + +void +aes_compute_inv_tables(void) { + int i; + uint8_t x, xe, x9, xd, xb; + v32_t tmp; + + /* combine sbox with linear operations to form 8-bit to 32-bit tables */ + for (i=0; i < 256; i++) { + x = aes_inv_sbox[i]; + + xe = gf2_8_multiply(0x0e, x); + x9 = gf2_8_multiply(0x09, x); + xd = gf2_8_multiply(0x0d, x); + xb = gf2_8_multiply(0x0b, x); + + tmp.v8[0] = xe; + tmp.v8[1] = x9; + tmp.v8[2] = xd; + tmp.v8[3] = xb; + U0[i] = tmp.value; + + tmp.v8[0] = xb; + tmp.v8[1] = xe; + tmp.v8[2] = x9; + tmp.v8[3] = xd; + U1[i] = tmp.value; + + tmp.v8[0] = xd; + tmp.v8[1] = xb; + tmp.v8[2] = xe; + tmp.v8[3] = x9; + U2[i] = tmp.value; + + tmp.v8[0] = x9; + tmp.v8[1] = xd; + tmp.v8[2] = xb; + tmp.v8[3] = xe; + U3[i] = tmp.value; + + tmp.v8[0] = tmp.v8[1] = tmp.v8[2] = tmp.v8[3] = x; + U4[i] = tmp.value; + } +} + + +/* + * aes_test_inverse() returns err_status_ok if aes + * encryption and decryption are true inverses of each other, and + * returns err_status_algo_fail otherwise + */ + +#include "err.h" + +err_status_t +aes_test_inverse(void); + +#define TABLES_32BIT 1 + +int +main(void) { + int i; + + aes_init_sbox(); + aes_compute_inv_tables(); + +#if TABLES_32BIT + printf("uint32_t U0 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%0x, ", U0[i]); + } + printf("\n}\n"); + + printf("uint32_t U1 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%x, ", U1[i]); + } + printf("\n}\n"); + + printf("uint32_t U2 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%x, ", U2[i]); + } + printf("\n}\n"); + + printf("uint32_t U3 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%x, ", U3[i]); + } + printf("\n}\n"); + + printf("uint32_t U4 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%x, ", U4[i]); + } + printf("\n}\n"); + +#else + + printf("uint32_t U0 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%lx, ", U0[i]); + } + printf("\n}\n"); + + printf("uint32_t U1 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%lx, ", U1[i]); + } + printf("\n}\n"); + + printf("uint32_t U2 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%lx, ", U2[i]); + } + printf("\n}\n"); + + printf("uint32_t U3 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%lx, ", U3[i]); + } + printf("\n}\n"); + + printf("uint32_t U4 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%lx, ", U4[i]); + } + printf("\n}\n"); + + +#endif /* TABLES_32BIT */ + + +#if AES_INVERSE_TEST + /* + * test that aes_encrypt and aes_decrypt are actually + * inverses of each other + */ + + printf("aes inverse test: "); + if (aes_test_inverse() == err_status_ok) + printf("passed\n"); + else { + printf("failed\n"); + exit(1); + } +#endif + + return 0; +} + +#if AES_INVERSE_TEST + +err_status_t +aes_test_inverse(void) { + v128_t x, y; + aes_expanded_key_t expanded_key, decrypt_key; + uint8_t plaintext[16] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff + }; + uint8_t key[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + }; + v128_t k; + v128_set_to_zero(&x); + + v128_copy_octet_string(&k, key); + v128_copy_octet_string(&x, plaintext); + aes_expand_encryption_key(k, expanded_key); + aes_expand_decryption_key(k, decrypt_key); + aes_encrypt(&x, expanded_key); + aes_decrypt(&x, decrypt_key); + + /* compare to expected value then report */ + v128_copy_octet_string(&y, plaintext); + + if (v128_is_eq(&x, &y)) + return err_status_ok; + return err_status_algo_fail; + +} + +#endif diff --git a/src/libs/resiprocate/contrib/srtp/test/.cvsignore b/src/libs/resiprocate/contrib/srtp/test/.cvsignore new file mode 100644 index 00000000..2b9f0e78 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/test/.cvsignore @@ -0,0 +1,12 @@ +aes_calc +cipher_driver +datatypes_driver +kernel_driver +rand_gen +rdbx_driver +replay_driver +roc_driver +rtpw +sha1_driver +srtp_driver +stat_driver diff --git a/src/libs/resiprocate/contrib/srtp/test/dtls_srtp_driver.c b/src/libs/resiprocate/contrib/srtp/test/dtls_srtp_driver.c new file mode 100644 index 00000000..a8eddc08 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/test/dtls_srtp_driver.c @@ -0,0 +1,245 @@ +/* + * dtls_srtp_driver.c + * + * test driver for DTLS-SRTP functions + * + * David McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> /* for printf() */ +#include "getopt_s.h" /* for local getopt() */ +#include "srtp_priv.h" + +err_status_t +test_dtls_srtp(); + +srtp_hdr_t * +srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc); + +void +usage(char *prog_name) { + printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n" + " -d <mod> turn on debugging module <mod>\n" + " -l list debugging modules\n", prog_name); + exit(1); +} + +int +main(int argc, char *argv[]) { + unsigned do_list_mods = 0; + char q; + err_status_t err; + + printf("dtls_srtp_driver\n"); + + /* initialize srtp library */ + err = srtp_init(); + if (err) { + printf("error: srtp init failed with error code %d\n", err); + exit(1); + } + + /* process input arguments */ + while (1) { + q = getopt_s(argc, argv, "ld:"); + if (q == -1) + break; + switch (q) { + case 'l': + do_list_mods = 1; + break; + case 'd': + err = crypto_kernel_set_debug_module(optarg_s, 1); + if (err) { + printf("error: set debug module (%s) failed\n", optarg_s); + exit(1); + } + break; + default: + usage(argv[0]); + } + } + + if (do_list_mods) { + err = crypto_kernel_list_debug_modules(); + if (err) { + printf("error: list of debug modules failed\n"); + exit(1); + } + } + + printf("testing dtls_srtp..."); + err = test_dtls_srtp(); + if (err) { + printf("\nerror (code %d)\n", err); + exit(1); + } + printf("passed\n"); + + return 0; +} + + +err_status_t +test_dtls_srtp() { + srtp_hdr_t *test_packet; + int test_packet_len = 80; + srtp_t s; + srtp_policy_t policy; + uint8_t key[SRTP_MAX_KEY_LEN]; + uint8_t salt[SRTP_MAX_KEY_LEN]; + unsigned int key_len, salt_len; + srtp_profile_t profile; + err_status_t err; + + /* create a 'null' SRTP session */ + err = srtp_create(&s, NULL); + if (err) + return err; + + /* + * verify that packet-processing functions behave properly - we + * expect that these functions will return err_status_no_ctx + */ + test_packet = srtp_create_test_packet(80, 0xa5a5a5a5); + if (test_packet == NULL) + return err_status_alloc_fail; + err = srtp_protect(s, test_packet, &test_packet_len); + if (err != err_status_no_ctx) { + printf("wrong return value from srtp_protect() (got code %d)\n", + err); + return err_status_fail; + } + err = srtp_unprotect(s, test_packet, &test_packet_len); + if (err != err_status_no_ctx) { + printf("wrong return value from srtp_unprotect() (got code %d)\n", + err); + return err_status_fail; + } + err = srtp_protect_rtcp(s, test_packet, &test_packet_len); + if (err != err_status_no_ctx) { + printf("wrong return value from srtp_protect_rtcp() (got code %d)\n", + err); + return err_status_fail; + } + err = srtp_unprotect_rtcp(s, test_packet, &test_packet_len); + if (err != err_status_no_ctx) { + printf("wrong return value from srtp_unprotect_rtcp() (got code %d)\n", + err); + return err_status_fail; + } + + + /* + * set keys to known values for testing + */ + profile = srtp_profile_aes128_cm_sha1_80; + key_len = srtp_profile_get_master_key_length(profile); + salt_len = srtp_profile_get_master_salt_length(profile); + memset(key, 0xff, key_len); + memset(salt, 0xee, salt_len); + append_salt_to_key(key, key_len, salt, salt_len); + policy.key = key; + + /* initialize SRTP policy from profile */ + err = crypto_policy_set_from_profile_for_rtp(&policy.rtp, profile); + if (err) return err; + err = crypto_policy_set_from_profile_for_rtcp(&policy.rtcp, profile); + if (err) return err; + policy.ssrc.type = ssrc_any_inbound; + policy.next = NULL; + + err = srtp_add_stream(s, &policy); + if (err) + return err; + + return err_status_ok; +} + + + +/* + * srtp_create_test_packet(len, ssrc) returns a pointer to a + * (malloced) example RTP packet whose data field has the length given + * by pkt_octet_len and the SSRC value ssrc. The total length of the + * packet is twelve octets longer, since the header is at the + * beginning. There is room at the end of the packet for a trailer, + * and the four octets following the packet are filled with 0xff + * values to enable testing for overwrites. + * + * note that the location of the test packet can (and should) be + * deallocated with the free() call once it is no longer needed. + */ + +srtp_hdr_t * +srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) { + int i; + uint8_t *buffer; + srtp_hdr_t *hdr; + int bytes_in_hdr = 12; + + /* allocate memory for test packet */ + hdr = malloc(pkt_octet_len + bytes_in_hdr + + SRTP_MAX_TRAILER_LEN + 4); + if (!hdr) + return NULL; + + hdr->version = 2; /* RTP version two */ + hdr->p = 0; /* no padding needed */ + hdr->x = 0; /* no header extension */ + hdr->cc = 0; /* no CSRCs */ + hdr->m = 0; /* marker bit */ + hdr->pt = 0xf; /* payload type */ + hdr->seq = htons(0x1234); /* sequence number */ + hdr->ts = htonl(0xdecafbad); /* timestamp */ + hdr->ssrc = htonl(ssrc); /* synch. source */ + + buffer = (uint8_t *)hdr; + buffer += bytes_in_hdr; + + /* set RTP data to 0xab */ + for (i=0; i < pkt_octet_len; i++) + *buffer++ = 0xab; + + /* set post-data value to 0xffff to enable overrun checking */ + for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++) + *buffer++ = 0xff; + + return hdr; +} diff --git a/src/libs/resiprocate/contrib/srtp/test/getopt_s.c b/src/libs/resiprocate/contrib/srtp/test/getopt_s.c new file mode 100644 index 00000000..243ad6e3 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/test/getopt_s.c @@ -0,0 +1,112 @@ +/* + * getopt.c + * + * a minimal implementation of the getopt() function, written so that + * test applications that use that function can run on non-POSIX + * platforms + * + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdlib.h> /* for NULL */ + +int optind_s = 0; + +char *optarg_s; + +#define GETOPT_FOUND_WITHOUT_ARGUMENT 2 +#define GETOPT_FOUND_WITH_ARGUMENT 1 +#define GETOPT_NOT_FOUND 0 + +static int +getopt_check_character(char c, const char *string) { + unsigned int max_string_len = 128; + + while (*string != 0) { + if (max_string_len == 0) { + return '?'; + } + if (*string++ == c) { + if (*string == ':') { + return GETOPT_FOUND_WITH_ARGUMENT; + } else { + return GETOPT_FOUND_WITHOUT_ARGUMENT; + } + } + } + return GETOPT_NOT_FOUND; +} + +int +getopt_s(int argc, + char * const argv[], + const char *optstring) { + + + while (optind_s + 1 < argc) { + char *string; + + /* move 'string' on to next argument */ + optind_s++; + string = argv[optind_s]; + + if (string == NULL) + return '?'; /* NULL argument string */ + + if (string[0] != '-') + return -1; /* found an unexpected character */ + + switch(getopt_check_character(string[1], optstring)) { + case GETOPT_FOUND_WITH_ARGUMENT: + if (optind_s + 1 < argc) { + optind_s++; + optarg_s = argv[optind_s]; + return string[1]; + } else { + return '?'; /* argument missing */ + } + case GETOPT_FOUND_WITHOUT_ARGUMENT: + return string[1]; + case GETOPT_NOT_FOUND: + default: + return '?'; /* didn't find expected character */ + break; + } + } + + return -1; +} diff --git a/src/libs/resiprocate/contrib/srtp/test/lfsr.c b/src/libs/resiprocate/contrib/srtp/test/lfsr.c new file mode 100644 index 00000000..28ea02eb --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/test/lfsr.c @@ -0,0 +1,310 @@ +/* + * lfsr.c + * + */ + + +#include <stdio.h> +#include "datatypes.h" + +uint32_t +parity(uint32_t x) { + + x ^= (x >> 16); + x ^= (x >> 8); + x ^= (x >> 4); + x ^= (x >> 2); + x ^= (x >> 1); + + return x & 1; +} + + +/* typedef struct { */ +/* uint32_t register[8]; */ +/* } lfsr_t; */ + +void +compute_period(uint32_t feedback_polynomial) { + int i; + v32_t lfsr; + v32_t mask; + + mask.value = feedback_polynomial; + lfsr.value = 1; + + printf("polynomial: %s\t", v32_bit_string(mask)); + + for (i=0; i < 256; i++) { +/* printf("%s\n", v32_bit_string(lfsr)); */ + if (parity(mask.value & lfsr.value)) + lfsr.value = ((lfsr.value << 1) | 1) & 0xff; + else + lfsr.value = (lfsr.value << 1) & 0xff; + + /* now halt if we're back at the initial state */ + if (lfsr.value == 1) { + printf("period: %d\n", i); + break; + } + } +} + +uint32_t poly0 = 223; + + +uint32_t polynomials[39] = { +31, +47, +55, +59, +61, +79, +87, +91, +103, +107, +109, +115, +117, +121, +143, +151, +157, +167, +171, +173, +179, +181, +185, +199, +203, +205, +211, +213, +227, +229, +233, +241, +127, +191, +223, +239, +247, +251, +253 +}; + +char binary_string[32]; + +char * +u32_bit_string(uint32_t x, unsigned int length) { + unsigned int mask; + int index; + + mask = 1 << length; + index = 0; + for (; mask > 0; mask >>= 1) + if ((x & mask) == 0) + binary_string[index++] = '0'; + else + binary_string[index++] = '1'; + + binary_string[index++] = 0; /* NULL terminate string */ + return binary_string; +} + +extern int octet_weight[256]; + +unsigned int +weight(uint32_t poly) { + int wt = 0; + + /* note: endian-ness makes no difference */ + wt += octet_weight[poly & 0xff]; + wt += octet_weight[(poly >> 8) & 0xff]; + wt += octet_weight[(poly >> 16) & 0xff]; + wt += octet_weight[(poly >> 24)]; + + return wt; +} + +#define MAX_PERIOD 65535 + +#define debug_print 0 + +int +period(uint32_t poly) { + int i; + uint32_t x; + + + /* set lfsr to 1 */ + x = 1; +#if debug_print + printf("%d:\t%s\n", 0, u32_bit_string(x,8)); +#endif + for (i=1; i < MAX_PERIOD; i++) { + if (x & 1) + x = (x >> 1) ^ poly; + else + x = (x >> 1); + +#if debug_print + /* print for a sanity check */ + printf("%d:\t%s\n", i, u32_bit_string(x,8)); +#endif + + /* check for return to original value */ + if (x == 1) + return i; + } + return i; +} + +/* + * weight distribution computes the weight distribution of the + * code generated by the polynomial poly + */ + +#define MAX_LEN 8 +#define MAX_WEIGHT (1 << MAX_LEN) + +int A[MAX_WEIGHT+1]; + +void +weight_distribution2(uint32_t poly, int *A) { + int i; + uint32_t x; + + /* zeroize array */ + for (i=0; i < MAX_WEIGHT+1; i++) + A[i] = 0; + + /* loop over all input sequences */ + + + /* set lfsr to 1 */ + x = 1; +#if debug_print + printf("%d:\t%s\n", 0, u32_bit_string(x,8)); +#endif + for (i=1; i < MAX_PERIOD; i++) { + if (x & 1) + x = (x >> 1) ^ poly; + else + x = (x >> 1); + +#if debug_print + /* print for a sanity check */ + printf("%d:\t%s\n", i, u32_bit_string(x,8)); +#endif + + /* increment weight */ + wt += (x & 1); + + /* check for return to original value */ + if (x == 1) + break; + } + + /* set zero */ + A[0] = 0; +} + + +void +weight_distribution(uint32_t poly, int *A) { + int i; + uint32_t x; + + /* zeroize array */ + for (i=0; i < MAX_WEIGHT+1; i++) + A[i] = 0; + + /* set lfsr to 1 */ + x = 1; +#if debug_print + printf("%d:\t%s\n", 0, u32_bit_string(x,8)); +#endif + for (i=1; i < MAX_PERIOD; i++) { + if (x & 1) + x = (x >> 1) ^ poly; + else + x = (x >> 1); + +#if debug_print + /* print for a sanity check */ + printf("%d:\t%s\n", i, u32_bit_string(x,8)); +#endif + + /* compute weight, increment proper element */ + A[weight(x)]++; + + /* check for return to original value */ + if (x == 1) + break; + } + + /* set zero */ + A[0] = 0; +} + + + + +int +main () { + + int i,j; + v32_t x; + v32_t p; + + /* originally 0xaf */ + p.value = 0x9; + + printf("polynomial: %s\tperiod: %d\n", + u32_bit_string(p.value,8), period(p.value)); + + /* compute weight distribution */ + weight_distribution(p.value, A); + + /* print weight distribution */ + for (i=0; i <= 8; i++) { + printf("A[%d]: %d\n", i, A[i]); + } + +#if 0 + for (i=0; i < 39; i++) { + printf("polynomial: %s\tperiod: %d\n", + u32_bit_string(polynomials[i],8), period(polynomials[i])); + + /* compute weight distribution */ + weight_distribution(p.value, A); + + /* print weight distribution */ + for (j=0; j <= 8; j++) { + printf("A[%d]: %d\n", j, A[j]); + } + } +#endif + + { + int bits = 8; + uint32_t y; + for (y=0; y < (1 << bits); y++) { + printf("polynomial: %s\tweight: %d\tperiod: %d\n", + u32_bit_string(y,bits), weight(y), period(y)); + + /* compute weight distribution */ + weight_distribution(y, A); + + /* print weight distribution */ + for (j=0; j <= 8; j++) { + printf("A[%d]: %d\n", j, A[j]); + } + } + } + + return 0; +} diff --git a/src/libs/resiprocate/contrib/srtp/test/rdbx_driver.c b/src/libs/resiprocate/contrib/srtp/test/rdbx_driver.c new file mode 100644 index 00000000..7db67a2b --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/test/rdbx_driver.c @@ -0,0 +1,306 @@ +/* + * rdbx_driver.c + * + * driver for the rdbx implementation (replay database with extended range) + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> /* for printf() */ +#include "getopt_s.h" /* for local getopt() */ + +#include "rdbx.h" + +#ifdef ROC_TEST +#error "rdbx_t won't work with ROC_TEST - bitmask same size as seq_median" +#endif + +#include "ut_sim.h" + +err_status_t +test_replay_dbx(int num_trials); + +double +rdbx_check_adds_per_second(int num_trials); + +void +usage(char *prog_name) { + printf("usage: %s [ -t | -v ]\n", prog_name); + exit(255); +} + +int +main (int argc, char *argv[]) { + double rate; + err_status_t status; + char q; + unsigned do_timing_test = 0; + unsigned do_validation = 0; + + /* process input arguments */ + while (1) { + q = getopt_s(argc, argv, "tv"); + if (q == -1) + break; + switch (q) { + case 't': + do_timing_test = 1; + break; + case 'v': + do_validation = 1; + break; + default: + usage(argv[0]); + } + } + + printf("rdbx (replay database w/ extended range) test driver\n" + "David A. McGrew\n" + "Cisco Systems, Inc.\n"); + + if (!do_validation && !do_timing_test) + usage(argv[0]); + + if (do_validation) { + printf("testing rdbx_t...\n"); + + status = test_replay_dbx(1 << 12); + if (status) { + printf("failed\n"); + exit(1); + } + printf("passed\n"); + } + + if (do_timing_test) { + rate = rdbx_check_adds_per_second(1 << 18); + printf("rdbx_check/replay_adds per second: %e\n", rate); + } + + return 0; +} + +void +print_rdbx(rdbx_t *rdbx) { + printf("rdbx: {%llu, %s}\n", + (unsigned long long)(rdbx->index), v128_bit_string(&rdbx->bitmask)); +} + + +/* + * rdbx_check_add(rdbx, idx) checks a known-to-be-good idx against + * rdbx, then adds it. if a failure is detected (i.e., the check + * indicates that the value is already in rdbx) then + * err_status_algo_fail is returned. + * + */ + +err_status_t +rdbx_check_add(rdbx_t *rdbx, uint32_t idx) { + int delta; + xtd_seq_num_t est; + + delta = index_guess(&rdbx->index, &est, idx); + + if (rdbx_check(rdbx, delta) != err_status_ok) { + printf("replay_check failed at index %u\n", idx); + return err_status_algo_fail; + } + + /* + * in practice, we'd authenticate the packet containing idx, using + * the estimated value est, at this point + */ + + if (rdbx_add_index(rdbx, delta) != err_status_ok) { + printf("rdbx_add_index failed at index %u\n", idx); + return err_status_algo_fail; + } + + return err_status_ok; +} + +/* + * rdbx_check_expect_failure(rdbx_t *rdbx, uint32_t idx) + * + * checks that a sequence number idx is in the replay database + * and thus will be rejected + */ + +err_status_t +rdbx_check_expect_failure(rdbx_t *rdbx, uint32_t idx) { + int delta; + xtd_seq_num_t est; + err_status_t status; + + delta = index_guess(&rdbx->index, &est, idx); + + status = rdbx_check(rdbx, delta); + if (status == err_status_ok) { + printf("delta: %d ", delta); + printf("replay_check failed at index %u (false positive)\n", idx); + return err_status_algo_fail; + } + + return err_status_ok; +} + +err_status_t +rdbx_check_unordered(rdbx_t *rdbx, uint32_t idx) { + err_status_t rstat; + + rstat = rdbx_check(rdbx, idx); + if ((rstat != err_status_ok) && (rstat != err_status_replay_old)) { + printf("replay_check_unordered failed at index %u\n", idx); + return err_status_algo_fail; + } + return err_status_ok; +} + +#define MAX_IDX 160 + +err_status_t +test_replay_dbx(int num_trials) { + rdbx_t rdbx; + uint32_t idx, ircvd; + ut_connection utc; + err_status_t status; + int num_fp_trials; + + status = rdbx_init(&rdbx); + if (status) { + printf("replay_init failed with error code %d\n", status); + exit(1); + } + + /* + * test sequential insertion + */ + printf("\ttesting sequential insertion..."); + for (idx=0; idx < num_trials; idx++) { + status = rdbx_check_add(&rdbx, idx); + if (status) + return status; + } + printf("passed\n"); + + /* + * test for false positives by checking all of the index + * values which we've just added + * + * note that we limit the number of trials here, since allowing the + * rollover counter to roll over would defeat this test + */ + num_fp_trials = num_trials % 0x10000; + if (num_fp_trials == 0) { + printf("warning: no false positive tests performed\n"); + } + printf("\ttesting for false positives..."); + for (idx=0; idx < num_fp_trials; idx++) { + status = rdbx_check_expect_failure(&rdbx, idx); + if (status) + return status; + } + printf("passed\n"); + + /* re-initialize */ + if (rdbx_init(&rdbx) != err_status_ok) { + printf("replay_init failed\n"); + return err_status_init_fail; + } + + /* + * test non-sequential insertion + * + * this test covers only fase negatives, since the values returned + * by ut_next_index(...) are distinct + */ + ut_init(&utc); + + printf("\ttesting non-sequential insertion..."); + for (idx=0; idx < num_trials; idx++) { + ircvd = ut_next_index(&utc); + status = rdbx_check_unordered(&rdbx, ircvd); + if (status) + return status; + } + printf("passed\n"); + + return err_status_ok; +} + + + +#include <time.h> /* for clock() */ +#include <stdlib.h> /* for random() */ + +double +rdbx_check_adds_per_second(int num_trials) { + uint32_t i; + int delta; + rdbx_t rdbx; + xtd_seq_num_t est; + clock_t timer; + int failures; /* count number of failures */ + + if (rdbx_init(&rdbx) != err_status_ok) { + printf("replay_init failed\n"); + exit(1); + } + + failures = 0; + timer = clock(); + for(i=0; i < num_trials; i++) { + + delta = index_guess(&rdbx.index, &est, i); + + if (rdbx_check(&rdbx, delta) != err_status_ok) + ++failures; + else + if (rdbx_add_index(&rdbx, delta) != err_status_ok) + ++failures; + } + timer = clock() - timer; + + printf("number of failures: %d \n", failures); + + return (double) CLOCKS_PER_SEC * num_trials / timer; +} + diff --git a/src/libs/resiprocate/contrib/srtp/test/replay_driver.c b/src/libs/resiprocate/contrib/srtp/test/replay_driver.c new file mode 100644 index 00000000..369a77a4 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/test/replay_driver.c @@ -0,0 +1,209 @@ +/* + * replay_driver.c + * + * A driver for the replay_database implementation + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> + +#include "rdb.h" +#include "ut_sim.h" + +/* + * num_trials defines the number of trials that are used in the + * validation functions below + */ + +unsigned num_trials = 1 << 16; + +err_status_t +test_rdb_db(void); + +double +rdb_check_adds_per_second(void); + +int +main (void) { + err_status_t err; + + printf("testing anti-replay database (rdb_t)...\n"); + err = test_rdb_db(); + if (err) { + printf("failed\n"); + exit(1); + } + printf("done\n"); + + printf("rdb_check/rdb_adds per second: %e\n", + rdb_check_adds_per_second()); + + return 0; +} + + +void +print_rdb(rdb_t *rdb) { + printf("rdb: {%u, %s}\n", rdb->window_start, v128_bit_string(&rdb->bitmask)); +} + +err_status_t +rdb_check_add(rdb_t *rdb, uint32_t idx) { + + if (rdb_check(rdb, idx) != err_status_ok) { + printf("rdb_check failed at index %u\n", idx); + return err_status_fail; + } + if (rdb_add_index(rdb, idx) != err_status_ok) { + printf("rdb_add_index failed at index %u\n", idx); + return err_status_fail; + } + + return err_status_ok; +} + +err_status_t +rdb_check_expect_failure(rdb_t *rdb, uint32_t idx) { + err_status_t err; + + err = rdb_check(rdb, idx); + if ((err != err_status_replay_old) && (err != err_status_replay_fail)) { + printf("rdb_check failed at index %u (false positive)\n", idx); + return err_status_fail; + } + + return err_status_ok; +} + +err_status_t +rdb_check_unordered(rdb_t *rdb, uint32_t idx) { + err_status_t rstat; + + /* printf("index: %u\n", idx); */ + rstat = rdb_check(rdb, idx); + if ((rstat != err_status_ok) && (rstat != err_status_replay_old)) { + printf("rdb_check_unordered failed at index %u\n", idx); + return rstat; + } + return err_status_ok; +} + +err_status_t +test_rdb_db() { + rdb_t rdb; + uint32_t idx, ircvd; + ut_connection utc; + err_status_t err; + + if (rdb_init(&rdb) != err_status_ok) { + printf("rdb_init failed\n"); + return err_status_init_fail; + } + + /* test sequential insertion */ + for (idx=0; idx < num_trials; idx++) { + err = rdb_check_add(&rdb, idx); + if (err) + return err; + } + + /* test for false positives */ + for (idx=0; idx < num_trials; idx++) { + err = rdb_check_expect_failure(&rdb, idx); + if (err) + return err; + } + + /* re-initialize */ + if (rdb_init(&rdb) != err_status_ok) { + printf("rdb_init failed\n"); + return err_status_fail; + } + + /* test non-sequential insertion */ + ut_init(&utc); + + for (idx=0; idx < num_trials; idx++) { + ircvd = ut_next_index(&utc); + err = rdb_check_unordered(&rdb, ircvd); + if (err) + return err; + } + + return err_status_ok; +} + +#include <time.h> /* for clock() */ +#include <stdlib.h> /* for random() */ + +#define REPLAY_NUM_TRIALS 10000000 + +double +rdb_check_adds_per_second(void) { + uint32_t i; + rdb_t rdb; + clock_t timer; + int failures; /* count number of failures */ + + if (rdb_init(&rdb) != err_status_ok) { + printf("rdb_init failed\n"); + exit(1); + } + + timer = clock(); + for(i=0; i < REPLAY_NUM_TRIALS; i+=3) { + if (rdb_check(&rdb, i+2) != err_status_ok) + ++failures; + if (rdb_add_index(&rdb, i+2) != err_status_ok) + ++failures; + if (rdb_check(&rdb, i+1) != err_status_ok) + ++failures; + if (rdb_add_index(&rdb, i+1) != err_status_ok) + ++failures; + if (rdb_check(&rdb, i) != err_status_ok) + ++failures; + if (rdb_add_index(&rdb, i) != err_status_ok) + ++failures; + } + timer = clock() - timer; + + return (double) CLOCKS_PER_SEC * REPLAY_NUM_TRIALS / timer; +} diff --git a/src/libs/resiprocate/contrib/srtp/test/roc_driver.c b/src/libs/resiprocate/contrib/srtp/test/roc_driver.c new file mode 100644 index 00000000..396c9a79 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/test/roc_driver.c @@ -0,0 +1,165 @@ +/* + * roc_driver.c + * + * test driver for rollover counter replay implementation + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include <stdio.h> + +/* + * defining ROC_TEST causes small datatypes to be used in + * xtd_seq_num_t - this allows the functions to be exhaustively tested. + */ +#if ROC_NEEDS_TO_BE_TESTED +#define ROC_TEST +#endif + +#include "rdbx.h" +#include "ut_sim.h" + +err_status_t +roc_test(int num_trials); + +int +main (void) { + err_status_t status; + + printf("rollover counter test driver\n" + "David A. McGrew\n" + "Cisco Systems, Inc.\n"); + + printf("testing index functions..."); + status = roc_test(1 << 18); + if (status) { + printf("failed\n"); + exit(status); + } + printf("passed\n"); + return 0; +} + + +#define ROC_VERBOSE 0 + +err_status_t +roc_test(int num_trials) { + xtd_seq_num_t local, est, ref; + ut_connection utc; + int i, num_bad_est = 0; + int delta; + uint32_t ircvd; + double failure_rate; + + index_init(&local); + index_init(&ref); + index_init(&est); + + printf("\n\ttesting sequential insertion..."); + for (i=0; i < 2048; i++) { + delta = index_guess(&local, &est, (uint16_t) ref); +#if ROC_VERBOSE + printf("%lld, %lld, %d\n", ref, est, i); +#endif + if (ref != est) { +#if ROC_VERBOSE + printf(" *bad estimate*\n"); +#endif + ++num_bad_est; + } + index_advance(&ref, 1); + } + failure_rate = (double) num_bad_est / num_trials; + if (failure_rate > 0.01) { + printf("error: failure rate too high (%d bad estimates in %d trials)\n", + num_bad_est, num_trials); + return err_status_algo_fail; + } + printf("done\n"); + + + printf("\ttesting non-sequential insertion..."); + index_init(&local); + index_init(&ref); + index_init(&est); + ut_init(&utc); + + for (i=0; i < num_trials; i++) { + + /* get next seq num from unreliable transport simulator */ + ircvd = ut_next_index(&utc); + + /* set ref to value of ircvd */ + ref = ircvd; + + /* estimate index based on low bits of ircvd */ + delta = index_guess(&local, &est, (uint16_t) ref); +#if ROC_VERBOSE + printf("ref: %lld, local: %lld, est: %lld, ircvd: %d, delta: %d\n", + ref, local, est, ircvd, delta); +#endif + + /* now update local xtd_seq_num_t as necessary */ + if (delta > 0) + index_advance(&local, delta); + + if (ref != est) { +#if ROC_VERBOSE + printf(" *bad estimate*\n"); +#endif + /* record failure event */ + ++num_bad_est; + + /* reset local value to correct value */ + local = ref; + } + } + failure_rate = (double) num_bad_est / num_trials; + if (failure_rate > 0.01) { + printf("error: failure rate too high (%d bad estimates in %d trials)\n", + num_bad_est, num_trials); + return err_status_algo_fail; + } + printf("done\n"); + + return err_status_ok; +} diff --git a/src/libs/resiprocate/contrib/srtp/test/rtp.c b/src/libs/resiprocate/contrib/srtp/test/rtp.c new file mode 100644 index 00000000..69968f3f --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/test/rtp.c @@ -0,0 +1,167 @@ +/* + * rtp.c + * + * library functions for the real-time transport protocol + * + * David A. McGrew + * Cisco Systems, Inc. + */ + + +#include "rtp_priv.h" + +#include <stdio.h> +#include <string.h> + +#include <sys/types.h> +#ifdef HAVE_SYS_SOCKET_H +# include <sys/socket.h> +#endif + +#define PRINT_DEBUG 0 /* set to 1 to print out debugging data */ +#define VERBOSE_DEBUG 0 /* set to 1 to print out more data */ + +unsigned int +rtp_sendto(rtp_sender_t sender, const void* msg, int len) { + int octets_sent; + err_status_t stat; + int pkt_len = len + RTP_HEADER_LEN; + + /* marshal data */ + strncpy(sender->message.body, msg, len); + + /* update header */ + sender->message.header.seq = ntohs(sender->message.header.seq) + 1; + sender->message.header.seq = htons(sender->message.header.seq); + sender->message.header.ts = ntohl(sender->message.header.ts) + 1; + sender->message.header.ts = htonl(sender->message.header.ts); + + /* apply srtp */ + stat = srtp_protect(sender->srtp_ctx, &sender->message.header, &pkt_len); + if (stat) { +#if PRINT_DEBUG + fprintf(stderr, "error: srtp protection failed with code %d\n", stat); +#endif + return -1; + } +#if VERBOSE_DEBUG + srtp_print_packet(&sender->message.header, pkt_len); +#endif + octets_sent = sendto(sender->socket, (void*)&sender->message, + pkt_len, 0, (struct sockaddr *)&sender->addr, + sizeof (struct sockaddr_in)); + + if (octets_sent != pkt_len) { +#if PRINT_DEBUG + fprintf(stderr, "error: couldn't send message %s", (char *)msg); + perror(""); +#endif + } + + return octets_sent; +} + +unsigned int +rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len) { + int octets_recvd; + err_status_t stat; + + octets_recvd = recvfrom(receiver->socket, (void *)&receiver->message, + *len, 0, (struct sockaddr *) NULL, 0); + + /* verify rtp header */ + if (receiver->message.header.version != 2) { + *len = 0; + return -1; + } + +#if PRINT_DEBUG + fprintf(stderr, "%d octets received from SSRC %u\n", + octets_recvd, receiver->message.header.ssrc); +#endif +#if VERBOSE_DEBUG + srtp_print_packet(&receiver->message.header, octets_recvd); +#endif + + /* apply srtp */ + stat = srtp_unprotect(receiver->srtp_ctx, + &receiver->message.header, &octets_recvd); + if (stat) { + fprintf(stderr, + "error: srtp unprotection failed with code %d%s\n", stat, + stat == err_status_replay_fail ? " (replay check failed)" : + stat == err_status_auth_fail ? " (auth check failed)" : ""); + return -1; + } + strncpy(msg, receiver->message.body, octets_recvd); + + return octets_recvd; +} + +int +rtp_sender_init(rtp_sender_t sender, + int socket, + struct sockaddr_in addr, + unsigned int ssrc) { + + /* set header values */ + sender->message.header.ssrc = htonl(ssrc); + sender->message.header.ts = 0; + sender->message.header.seq = (uint16_t) rand(); + sender->message.header.m = 0; + sender->message.header.pt = 0x1; + sender->message.header.version = 2; + sender->message.header.p = 0; + sender->message.header.x = 0; + sender->message.header.cc = 0; + + /* set other stuff */ + sender->socket = socket; + sender->addr = addr; + + return 0; +} + +int +rtp_receiver_init(rtp_receiver_t rcvr, + int socket, + struct sockaddr_in addr, + unsigned int ssrc) { + + /* set header values */ + rcvr->message.header.ssrc = htonl(ssrc); + rcvr->message.header.ts = 0; + rcvr->message.header.seq = 0; + rcvr->message.header.m = 0; + rcvr->message.header.pt = 0x1; + rcvr->message.header.version = 2; + rcvr->message.header.p = 0; + rcvr->message.header.x = 0; + rcvr->message.header.cc = 0; + + /* set other stuff */ + rcvr->socket = socket; + rcvr->addr = addr; + + return 0; +} + +int +rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy) { + return srtp_create(&sender->srtp_ctx, policy); +} + +int +rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy) { + return srtp_create(&sender->srtp_ctx, policy); +} + +rtp_sender_t +rtp_sender_alloc() { + return (rtp_sender_t)malloc(sizeof(rtp_sender_ctx_t)); +} + +rtp_receiver_t +rtp_receiver_alloc() { + return (rtp_receiver_t)malloc(sizeof(rtp_receiver_ctx_t)); +} diff --git a/src/libs/resiprocate/contrib/srtp/test/rtpw.c b/src/libs/resiprocate/contrib/srtp/test/rtpw.c new file mode 100644 index 00000000..e477a779 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/test/rtpw.c @@ -0,0 +1,519 @@ +/* + * rtpw.c + * + * rtp word sender/receiver + * + * David A. McGrew + * Cisco Systems, Inc. + * + * This app is a simple RTP application intended only for testing + * libsrtp. It reads one word at a time from /usr/dict/words (or + * whatever file is specified as DICT_FILE), and sends one word out + * each USEC_RATE microseconds. Secure RTP protections can be + * applied. See the usage() function for more details. + * + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "datatypes.h" +#include "getopt_s.h" /* for local getopt() */ + +#include <stdio.h> /* for printf, fprintf */ +#include <stdlib.h> /* for atoi() */ +#include <errno.h> +#include <unistd.h> /* for close() */ + +#include <string.h> /* for strncpy() */ +#include <time.h> /* for usleep() */ +#ifdef HAVE_SYS_SOCKET_H +# include <sys/socket.h> +#endif +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#elif defined HAVE_WINSOCK2_H +# include <winsock2.h> +# include <ws2tcpip.h> +# define RTPW_USE_WINSOCK2 1 +#endif +#ifdef HAVE_ARPA_INET_H +# include <arpa/inet.h> +#endif + +#include "srtp.h" +#include "rtp.h" + +#ifdef RTPW_USE_WINSOCK2 +# define DICT_FILE "words.txt" +#else +# define DICT_FILE "/usr/share/dict/words" +#endif +#define USEC_RATE (5e5) +#define MAX_WORD_LEN 128 +#define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a)) +#define MAX_KEY_LEN 64 +#define MASTER_KEY_LEN 30 + + +#ifndef HAVE_USLEEP +# ifdef HAVE_WINDOWS_H +# define usleep(us) Sleep((us)/1000) +# else +# define usleep(us) sleep((us)/1000000) +# endif +#endif + + +/* + * the function usage() prints an error message describing how this + * program should be called, then calls exit() + */ + +void +usage(char *prog_name); + +/* + * leave_group(...) de-registers from a multicast group + */ + +void +leave_group(int sock, struct ip_mreq mreq, char *name); + + +/* + * program_type distinguishes the [s]rtp sender and receiver cases + */ + +typedef enum { sender, receiver, unknown } program_type; + +int +main (int argc, char *argv[]) { + char *dictfile = DICT_FILE; + FILE *dict; + char word[MAX_WORD_LEN]; + int sock, ret; + struct in_addr rcvr_addr; + struct sockaddr_in name; + struct ip_mreq mreq; +#if BEW + struct sockaddr_in local; +#endif + program_type prog_type = unknown; + sec_serv_t sec_servs = sec_serv_none; + unsigned char ttl = 5; + int c; + char *input_key = NULL; + char *address = NULL; + char key[MAX_KEY_LEN]; + unsigned short port = 0; + rtp_sender_t snd; + srtp_policy_t policy; + err_status_t status; + int len; + int do_list_mods = 0; + uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */ +#ifdef RTPW_USE_WINSOCK2 + WORD wVersionRequested = MAKEWORD(2, 0); + WSADATA wsaData; + + ret = WSAStartup(wVersionRequested, &wsaData); + if (ret != 0) { + fprintf(stderr, "error: WSAStartup() failed: %d\n", ret); + exit(1); + } +#endif + + /* initialize srtp library */ + status = srtp_init(); + if (status) { + printf("error: srtp initialization failed with error code %d\n", status); + exit(1); + } + + /* check args */ + while (1) { + c = getopt_s(argc, argv, "k:rsaeld:"); + if (c == -1) { + break; + } + switch (c) { + case 'k': + input_key = optarg_s; + break; + case 'e': + sec_servs |= sec_serv_conf; + break; + case 'a': + sec_servs |= sec_serv_auth; + break; + case 'r': + prog_type = receiver; + break; + case 's': + prog_type = sender; + break; + case 'd': + status = crypto_kernel_set_debug_module(optarg_s, 1); + if (status) { + printf("error: set debug module (%s) failed\n", optarg_s); + exit(1); + } + break; + case 'l': + do_list_mods = 1; + break; + default: + usage(argv[0]); + } + } + + if (prog_type == unknown) { + if (do_list_mods) { + status = crypto_kernel_list_debug_modules(); + if (status) { + printf("error: list of debug modules failed\n"); + exit(1); + } + return 0; + } else { + printf("error: neither sender [-s] nor receiver [-r] specified\n"); + usage(argv[0]); + } + } + + if ((sec_servs && !input_key) || (!sec_servs && input_key)) { + /* + * a key must be provided if and only if security services have + * been requested + */ + usage(argv[0]); + } + + if (argc != optind_s + 2) { + /* wrong number of arguments */ + usage(argv[0]); + } + + /* get address from arg */ + address = argv[optind_s++]; + + /* get port from arg */ + port = atoi(argv[optind_s++]); + + /* set address */ +#ifdef HAVE_INET_ATON + if (0 == inet_aton(address, &rcvr_addr)) { + fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0], address); + exit(1); + } + if (rcvr_addr.s_addr == INADDR_NONE) { + fprintf(stderr, "%s: address error", argv[0]); + exit(1); + } +#else + rcvr_addr.s_addr = inet_addr(address); + if (0xffffffff == rcvr_addr.s_addr) { + fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0], address); + exit(1); + } +#endif + + /* open socket */ + sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) { + int err; +#ifdef RTPW_USE_WINSOCK2 + err = WSAGetLastError(); +#else + err = errno; +#endif + fprintf(stderr, "%s: couldn't open socket: %d\n", argv[0], err); + exit(1); + } + + name.sin_addr = rcvr_addr; + name.sin_family = PF_INET; + name.sin_port = htons(port); + + if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) { + if (prog_type == sender) { + ret = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, + sizeof(ttl)); + if (ret < 0) { + fprintf(stderr, "%s: Failed to set TTL for multicast group", argv[0]); + perror(""); + exit(1); + } + } + + mreq.imr_multiaddr.s_addr = rcvr_addr.s_addr; + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&mreq, + sizeof(mreq)); + if (ret < 0) { + fprintf(stderr, "%s: Failed to join multicast group", argv[0]); + perror(""); + exit(1); + } + } + + /* report security services selected on the command line */ + printf("security services: "); + if (sec_servs & sec_serv_conf) + printf("confidentiality "); + if (sec_servs & sec_serv_auth) + printf("message authentication"); + if (sec_servs == sec_serv_none) + printf("none"); + printf("\n"); + + /* set up the srtp policy and master key */ + if (sec_servs) { + /* + * create policy structure, using the default mechanisms but + * with only the security services requested on the command line, + * using the right SSRC value + */ + switch (sec_servs) { + case sec_serv_conf_and_auth: + crypto_policy_set_rtp_default(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + break; + case sec_serv_conf: + crypto_policy_set_aes_cm_128_null_auth(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + break; + case sec_serv_auth: + crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + break; + default: + printf("error: unknown security service requested\n"); + return -1; + } + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = ssrc; + policy.key = (uint8_t *) key; + policy.next = NULL; + policy.rtp.sec_serv = sec_servs; + policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */ + + /* + * read key from hexadecimal on command line into an octet string + */ + len = hex_string_to_octet_string(key, input_key, MASTER_KEY_LEN*2); + + /* check that hex string is the right length */ + if (len < MASTER_KEY_LEN*2) { + fprintf(stderr, + "error: too few digits in key/salt " + "(should be %d hexadecimal digits, found %d)\n", + MASTER_KEY_LEN*2, len); + exit(1); + } + if (strlen(input_key) > MASTER_KEY_LEN*2) { + fprintf(stderr, + "error: too many digits in key/salt " + "(should be %d hexadecimal digits, found %u)\n", + MASTER_KEY_LEN*2, (unsigned)strlen(input_key)); + exit(1); + } + + printf("set master key/salt to %s/", octet_string_hex_string(key, 16)); + printf("%s\n", octet_string_hex_string(key+16, 14)); + + } else { + /* + * we're not providing security services, so set the policy to the + * null policy + * + * Note that this policy does not conform to the SRTP + * specification, since RTCP authentication is required. However, + * the effect of this policy is to turn off SRTP, so that this + * application is now a vanilla-flavored RTP application. + */ + policy.key = (uint8_t *)key; + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = ssrc; + policy.rtp.cipher_type = NULL_CIPHER; + policy.rtp.cipher_key_len = 0; + policy.rtp.auth_type = NULL_AUTH; + policy.rtp.auth_key_len = 0; + policy.rtp.auth_tag_len = 0; + policy.rtp.sec_serv = sec_serv_none; + policy.rtcp.cipher_type = NULL_CIPHER; + policy.rtcp.cipher_key_len = 0; + policy.rtcp.auth_type = NULL_AUTH; + policy.rtcp.auth_key_len = 0; + policy.rtcp.auth_tag_len = 0; + policy.rtcp.sec_serv = sec_serv_none; + policy.next = NULL; + } + + if (prog_type == sender) { + +#if BEW + /* bind to local socket (to match crypto policy, if need be) */ + memset(&local, 0, sizeof(struct sockaddr_in)); + local.sin_addr.s_addr = htonl(INADDR_ANY); + local.sin_port = htons(port); + ret = bind(sock, (struct sockaddr *) &local, sizeof(struct sockaddr_in)); + if (ret < 0) { + fprintf(stderr, "%s: bind failed\n", argv[0]); + perror(""); + exit(1); + } +#endif /* BEW */ + + /* initialize sender's rtp and srtp contexts */ + snd = rtp_sender_alloc(); + if (snd == NULL) { + fprintf(stderr, "error: malloc() failed\n"); + exit(1); + } + rtp_sender_init(snd, sock, name, ssrc); + status = rtp_sender_init_srtp(snd, &policy); + if (status) { + fprintf(stderr, + "error: srtp_create() failed with code %d\n", + status); + exit(1); + } + + /* open dictionary */ + dict = fopen (dictfile, "r"); + if (dict == NULL) { + fprintf(stderr, "%s: couldn't open file %s\n", argv[0], dictfile); + if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) { + leave_group(sock, mreq, argv[0]); + } + exit(1); + } + + /* read words from dictionary, then send them off */ + while (fgets(word, MAX_WORD_LEN, dict) != NULL) { + len = strlen(word) + 1; /* plus one for null */ + + if (len > MAX_WORD_LEN) + printf("error: word %s too large to send\n", word); + else { + rtp_sendto(snd, word, len); + printf("sending word: %s", word); + } + usleep(USEC_RATE); + } + + } else { /* prog_type == receiver */ + rtp_receiver_t rcvr; + + if (bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0) { + close(sock); + fprintf(stderr, "%s: socket bind error\n", argv[0]); + perror(NULL); + if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) { + leave_group(sock, mreq, argv[0]); + } + exit(1); + } + + rcvr = rtp_receiver_alloc(); + if (rcvr == NULL) { + fprintf(stderr, "error: malloc() failed\n"); + exit(1); + } + rtp_receiver_init(rcvr, sock, name, ssrc); + status = rtp_receiver_init_srtp(rcvr, &policy); + if (status) { + fprintf(stderr, + "error: srtp_create() failed with code %d\n", + status); + exit(1); + } + + /* get next word and loop */ + while (1) { + len = MAX_WORD_LEN; + if (rtp_recvfrom(rcvr, word, &len) > -1) + printf("\tword: %s", word); + } + + } + + if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) { + leave_group(sock, mreq, argv[0]); + } + +#ifdef RTPW_USE_WINSOCK2 + WSACleanup(); +#endif + + return 0; +} + + +void +usage(char *string) { + + printf("usage: %s [-d <debug>]* [-k <key> [-a][-e]] " + "[-s | -r] dest_ip dest_port\n" + "or %s -l\n" + "where -a use message authentication\n" + " -e use encryption\n" + " -k <key> sets the srtp master key\n" + " -s act as rtp sender\n" + " -r act as rtp receiver\n" + " -l list debug modules\n" + " -d <debug> turn on debugging for module <debug>\n", + string, string); + exit(1); + +} + + +void +leave_group(int sock, struct ip_mreq mreq, char *name) { + int ret; + + ret = setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void*)&mreq, + sizeof(mreq)); + if (ret < 0) { + fprintf(stderr, "%s: Failed to leave multicast group", name); + perror(""); + } +} + diff --git a/src/libs/resiprocate/contrib/srtp/test/rtpw_test.sh b/src/libs/resiprocate/contrib/srtp/test/rtpw_test.sh new file mode 100644 index 00000000..f82e9370 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/test/rtpw_test.sh @@ -0,0 +1,77 @@ +#!/bin/sh +# +# usage: rtpw_test <rtpw_commands> +# +# tests the rtpw sender and receiver functions + +RTPW=rtpw +DEST_PORT=9999 +DURATION=3 + +key=2b2edc5034f61a72345ca5986d7bfd0189aa6dc2ecab32fd9af74df6dfc6 + +ARGS="-k $key -ae" + +# First, we run "killall" to get rid of all existing rtpw processes. +# This step also enables this script to clean up after itself; if this +# script is interrupted after the rtpw processes are started but before +# they are killed, those processes will linger. Re-running the script +# will get rid of them. + +killall rtpw 2&>/dev/null + +if test -x $RTPW; then + +echo $0 ": starting rtpw receiver process... " + +$RTPW $* $ARGS -r 0.0.0.0 $DEST_PORT & + +receiver_pid=$! + +echo $0 ": receiver PID = $receiver_pid" + +sleep 1 + +# verify that the background job is running +ps | grep -q $receiver_pid +retval=$? +echo $retval +if [ $retval != 0 ]; then + echo $0 ": error" + exit 254 +fi + +echo $0 ": starting rtpw sender process..." + +$RTPW $* $ARGS -s 127.0.0.1 $DEST_PORT & + +sender_pid=$! + +echo $0 ": sender PID = $sender_pid" + +# verify that the background job is running +ps | grep -q $sender_pid +retval=$? +echo $retval +if [ $retval != 0 ]; then + echo $0 ": error" + exit 255 +fi + +sleep $DURATION + +kill $receiver_pid +kill $sender_pid + +echo $0 ": done (test passed)" + +else + +echo "error: can't find executable" $RTPW +exit 1 + +fi + +# EOF + + diff --git a/src/libs/resiprocate/contrib/srtp/test/srtp_driver.c b/src/libs/resiprocate/contrib/srtp/test/srtp_driver.c new file mode 100644 index 00000000..12d1c8c2 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/test/srtp_driver.c @@ -0,0 +1,1491 @@ +/* + * srtp_driver.c + * + * a test driver for libSRTP + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include <string.h> /* for memcpy() */ +#include <time.h> /* for clock() */ +#include <stdlib.h> /* for malloc(), free() */ +#include <stdio.h> /* for print(), fflush() */ +#include "getopt_s.h" /* for local getopt() */ + +#include "srtp_priv.h" + +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#elif defined HAVE_WINSOCK2_H +# include <winsock2.h> +#endif + +#define PRINT_REFERENCE_PACKET 1 + +err_status_t +srtp_validate(void); + +err_status_t +srtp_create_big_policy(srtp_policy_t **list); + +err_status_t +srtp_test_remove_stream(void); + +double +srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy); + +double +srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy); + +void +srtp_do_timing(const srtp_policy_t *policy); + +void +srtp_do_rejection_timing(const srtp_policy_t *policy); + +err_status_t +srtp_test(const srtp_policy_t *policy); + +err_status_t +srtcp_test(const srtp_policy_t *policy); + +err_status_t +srtp_session_print_policy(srtp_t srtp); + +err_status_t +srtp_print_policy(const srtp_policy_t *policy); + +char * +srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len); + +double +mips_estimate(int num_trials, int *ignore); + +extern uint8_t test_key[30]; + +void +usage(char *prog_name) { + printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n" + " -t run timing test\n" + " -r run rejection timing test\n" + " -c run codec timing test\n" + " -v run validation tests\n" + " -d <mod> turn on debugging module <mod>\n" + " -l list debugging modules\n", prog_name); + exit(1); +} + +/* + * The policy_array is a null-terminated array of policy structs. it + * is declared at the end of this file + */ + +extern const srtp_policy_t *policy_array[]; + + +/* the wildcard_policy is declared below; it has a wildcard ssrc */ + +extern const srtp_policy_t wildcard_policy; + +/* + * mod_driver debug module - debugging module for this test driver + * + * we use the crypto_kernel debugging system in this driver, which + * makes the interface uniform and increases portability + */ + +debug_module_t mod_driver = { + 0, /* debugging is off by default */ + "driver" /* printable name for module */ +}; + +int +main (int argc, char *argv[]) { + char q; + unsigned do_timing_test = 0; + unsigned do_rejection_test = 0; + unsigned do_codec_timing = 0; + unsigned do_validation = 0; + unsigned do_list_mods = 0; + err_status_t status; + + /* + * verify that the compiler has interpreted the header data + * structure srtp_hdr_t correctly + */ + if (sizeof(srtp_hdr_t) != 12) { + printf("error: srtp_hdr_t has incorrect size" + "(size is %ld bytes, expected 12)\n", + sizeof(srtp_hdr_t)); + exit(1); + } + + /* initialize srtp library */ + status = srtp_init(); + if (status) { + printf("error: srtp init failed with error code %d\n", status); + exit(1); + } + + /* load srtp_driver debug module */ + status = crypto_kernel_load_debug_module(&mod_driver); + if (status) { + printf("error: load of srtp_driver debug module failed " + "with error code %d\n", status); + exit(1); + } + + /* process input arguments */ + while (1) { + q = getopt_s(argc, argv, "trcvld:"); + if (q == -1) + break; + switch (q) { + case 't': + do_timing_test = 1; + break; + case 'r': + do_rejection_test = 1; + break; + case 'c': + do_codec_timing = 1; + break; + case 'v': + do_validation = 1; + break; + case 'l': + do_list_mods = 1; + break; + case 'd': + status = crypto_kernel_set_debug_module(optarg_s, 1); + if (status) { + printf("error: set debug module (%s) failed\n", optarg_s); + exit(1); + } + break; + default: + usage(argv[0]); + } + } + + if (!do_validation && !do_timing_test && !do_codec_timing + && !do_list_mods && !do_rejection_test) + usage(argv[0]); + + if (do_list_mods) { + status = crypto_kernel_list_debug_modules(); + if (status) { + printf("error: list of debug modules failed\n"); + exit(1); + } + } + + if (do_validation) { + const srtp_policy_t **policy = policy_array; + srtp_policy_t *big_policy; + + /* loop over policy array, testing srtp and srtcp for each policy */ + while (*policy != NULL) { + printf("testing srtp_protect and srtp_unprotect\n"); + if (srtp_test(*policy) == err_status_ok) + printf("passed\n\n"); + else { + printf("failed\n"); + exit(1); + } + printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n"); + if (srtcp_test(*policy) == err_status_ok) + printf("passed\n\n"); + else { + printf("failed\n"); + exit(1); + } + policy++; + } + + /* create a big policy list and run tests on it */ + status = srtp_create_big_policy(&big_policy); + if (status) { + printf("unexpected failure with error code %d\n", status); + exit(1); + } + printf("testing srtp_protect and srtp_unprotect with big policy\n"); + if (srtp_test(big_policy) == err_status_ok) + printf("passed\n\n"); + else { + printf("failed\n"); + exit(1); + } + + /* run test on wildcard policy */ + printf("testing srtp_protect and srtp_unprotect on " + "wildcard ssrc policy\n"); + if (srtp_test(&wildcard_policy) == err_status_ok) + printf("passed\n\n"); + else { + printf("failed\n"); + exit(1); + } + + /* + * run validation test against the reference packets - note + * that this test only covers the default policy + */ + printf("testing srtp_protect and srtp_unprotect against " + "reference packets\n"); + if (srtp_validate() == err_status_ok) + printf("passed\n\n"); + else { + printf("failed\n"); + exit(1); + } + + /* + * test the function srtp_remove_stream() + */ + printf("testing srtp_remove_stream()..."); + if (srtp_test_remove_stream() == err_status_ok) + printf("passed\n"); + else { + printf("failed\n"); + exit(1); + } + } + + if (do_timing_test) { + const srtp_policy_t **policy = policy_array; + + /* loop over policies, run timing test for each */ + while (*policy != NULL) { + srtp_print_policy(*policy); + srtp_do_timing(*policy); + policy++; + } + } + + if (do_rejection_test) { + const srtp_policy_t **policy = policy_array; + + /* loop over policies, run rejection timing test for each */ + while (*policy != NULL) { + srtp_print_policy(*policy); + srtp_do_rejection_timing(*policy); + policy++; + } + } + + if (do_codec_timing) { + srtp_policy_t policy; + int ignore; + double mips = mips_estimate(1000000000, &ignore); + + crypto_policy_set_rtp_default(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = 0xdecafbad; + policy.key = test_key; + policy.next = NULL; + + printf("mips estimate: %e\n", mips); + + printf("testing srtp processing time for voice codecs:\n"); + printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n"); + printf("G.711\t\t%d\t\t\t%e\n", 80, + (double) mips * (80 * 8) / + srtp_bits_per_second(80, &policy) / .01 ); + printf("G.711\t\t%d\t\t\t%e\n", 160, + (double) mips * (160 * 8) / + srtp_bits_per_second(160, &policy) / .02); + printf("G.726-32\t%d\t\t\t%e\n", 40, + (double) mips * (40 * 8) / + srtp_bits_per_second(40, &policy) / .01 ); + printf("G.726-32\t%d\t\t\t%e\n", 80, + (double) mips * (80 * 8) / + srtp_bits_per_second(80, &policy) / .02); + printf("G.729\t\t%d\t\t\t%e\n", 10, + (double) mips * (10 * 8) / + srtp_bits_per_second(10, &policy) / .01 ); + printf("G.729\t\t%d\t\t\t%e\n", 20, + (double) mips * (20 * 8) / + srtp_bits_per_second(20, &policy) / .02 ); + printf("Wideband\t%d\t\t\t%e\n", 320, + (double) mips * (320 * 8) / + srtp_bits_per_second(320, &policy) / .01 ); + printf("Wideband\t%d\t\t\t%e\n", 640, + (double) mips * (640 * 8) / + srtp_bits_per_second(640, &policy) / .02 ); + } + + return 0; +} + + + +/* + * srtp_create_test_packet(len, ssrc) returns a pointer to a + * (malloced) example RTP packet whose data field has the length given + * by pkt_octet_len and the SSRC value ssrc. The total length of the + * packet is twelve octets longer, since the header is at the + * beginning. There is room at the end of the packet for a trailer, + * and the four octets following the packet are filled with 0xff + * values to enable testing for overwrites. + * + * note that the location of the test packet can (and should) be + * deallocated with the free() call once it is no longer needed. + */ + +srtp_hdr_t * +srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) { + int i; + uint8_t *buffer; + srtp_hdr_t *hdr; + int bytes_in_hdr = 12; + + /* allocate memory for test packet */ + hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr + + SRTP_MAX_TRAILER_LEN + 4); + if (!hdr) + return NULL; + + hdr->version = 2; /* RTP version two */ + hdr->p = 0; /* no padding needed */ + hdr->x = 0; /* no header extension */ + hdr->cc = 0; /* no CSRCs */ + hdr->m = 0; /* marker bit */ + hdr->pt = 0xf; /* payload type */ + hdr->seq = htons(0x1234); /* sequence number */ + hdr->ts = htonl(0xdecafbad); /* timestamp */ + hdr->ssrc = htonl(ssrc); /* synch. source */ + + buffer = (uint8_t *)hdr; + buffer += bytes_in_hdr; + + /* set RTP data to 0xab */ + for (i=0; i < pkt_octet_len; i++) + *buffer++ = 0xab; + + /* set post-data value to 0xffff to enable overrun checking */ + for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++) + *buffer++ = 0xff; + + return hdr; +} + +void +srtp_do_timing(const srtp_policy_t *policy) { + int len; + + /* + * note: the output of this function is formatted so that it + * can be used in gnuplot. '#' indicates a comment, and "\r\n" + * terminates a record + */ + + printf("# testing srtp throughput:\r\n"); + printf("# mesg length (octets)\tthroughput (megabits per second)\r\n"); + + for (len=16; len <= 2048; len *= 2) + printf("%d\t\t\t%f\r\n", len, + srtp_bits_per_second(len, policy) / 1.0E6); + + /* these extra linefeeds let gnuplot know that a dataset is done */ + printf("\r\n\r\n"); + +} + +void +srtp_do_rejection_timing(const srtp_policy_t *policy) { + int len; + + /* + * note: the output of this function is formatted so that it + * can be used in gnuplot. '#' indicates a comment, and "\r\n" + * terminates a record + */ + + printf("# testing srtp rejection throughput:\r\n"); + printf("# mesg length (octets)\trejections per second\r\n"); + + for (len=8; len <= 2048; len *= 2) + printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy)); + + /* these extra linefeeds let gnuplot know that a dataset is done */ + printf("\r\n\r\n"); + +} + + +#define MAX_MSG_LEN 1024 + +double +srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) { + srtp_t srtp; + srtp_hdr_t *mesg; + int i; + clock_t timer; + int num_trials = 100000; + int len; + uint32_t ssrc; + err_status_t status; + + /* + * allocate and initialize an srtp session + */ + status = srtp_create(&srtp, policy); + if (status) { + printf("error: srtp_create() failed with error code %d\n", status); + exit(1); + } + + /* + * if the ssrc is unspecified, use a predetermined one + */ + if (policy->ssrc.type != ssrc_specific) { + ssrc = 0xdeadbeef; + } else { + ssrc = policy->ssrc.value; + } + + /* + * create a test packet + */ + mesg = srtp_create_test_packet(msg_len_octets, ssrc); + if (mesg == NULL) + return 0.0; /* indicate failure by returning zero */ + + timer = clock(); + for (i=0; i < num_trials; i++) { + err_status_t status; + len = msg_len_octets + 12; /* add in rtp header length */ + + /* srtp protect message */ + status = srtp_protect(srtp, mesg, &len); + if (status) { + printf("error: srtp_protect() failed with error code %d\n", status); + exit(1); + } + + /* increment message number */ + mesg->seq = htons(ntohs(mesg->seq) + 1); + + } + timer = clock() - timer; + + free(mesg); + + return (double) (msg_len_octets) * 8 * + num_trials * CLOCKS_PER_SEC / timer; +} + +double +srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) { + srtp_ctx_t *srtp; + srtp_hdr_t *mesg; + int i; + int len; + clock_t timer; + int num_trials = 1000000; + uint32_t ssrc = policy->ssrc.value; + err_status_t status; + + /* + * allocate and initialize an srtp session + */ + status = srtp_create(&srtp, policy); + if (status) { + printf("error: srtp_create() failed with error code %d\n", status); + exit(1); + } + + mesg = srtp_create_test_packet(msg_len_octets, ssrc); + if (mesg == NULL) + return 0.0; /* indicate failure by returning zero */ + + len = msg_len_octets; + srtp_protect(srtp, (srtp_hdr_t *)mesg, &len); + + timer = clock(); + for (i=0; i < num_trials; i++) { + len = msg_len_octets; + srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len); + } + timer = clock() - timer; + + free(mesg); + + return (double) num_trials * CLOCKS_PER_SEC / timer; +} + + +void +err_check(err_status_t s) { + if (s == err_status_ok) + return; + else + fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s); + exit (1); +} + +err_status_t +srtp_test(const srtp_policy_t *policy) { + int i; + srtp_t srtp_sender; + srtp_t srtp_rcvr; + err_status_t status = err_status_ok; + srtp_hdr_t *hdr, *hdr2; + uint8_t hdr_enc[64]; + uint8_t *pkt_end; + int msg_len_octets, msg_len_enc; + int len; + int tag_length = policy->rtp.auth_tag_len; + uint32_t ssrc; + srtp_policy_t *rcvr_policy; + + err_check(srtp_create(&srtp_sender, policy)); + + /* print out policy */ + err_check(srtp_session_print_policy(srtp_sender)); + + /* + * initialize data buffer, using the ssrc in the policy unless that + * value is a wildcard, in which case we'll just use an arbitrary + * one + */ + if (policy->ssrc.type != ssrc_specific) + ssrc = 0xdecafbad; + else + ssrc = policy->ssrc.value; + msg_len_octets = 28; + hdr = srtp_create_test_packet(msg_len_octets, ssrc); + + if (hdr == NULL) + return err_status_alloc_fail; + hdr2 = srtp_create_test_packet(msg_len_octets, ssrc); + if (hdr2 == NULL) { + free(hdr); + return err_status_alloc_fail; + } + + /* set message length */ + len = msg_len_octets; + + debug_print(mod_driver, "before protection:\n%s", + srtp_packet_to_string(hdr, len)); + +#if PRINT_REFERENCE_PACKET + debug_print(mod_driver, "reference packet before protection:\n%s", + octet_string_hex_string((uint8_t *)hdr, len)); +#endif + err_check(srtp_protect(srtp_sender, hdr, &len)); + + debug_print(mod_driver, "after protection:\n%s", + srtp_packet_to_string(hdr, len)); +#if PRINT_REFERENCE_PACKET + debug_print(mod_driver, "after protection:\n%s", + octet_string_hex_string((uint8_t *)hdr, len)); +#endif + + /* save protected message and length */ + memcpy(hdr_enc, hdr, len); + msg_len_enc = len; + + /* + * check for overrun of the srtp_protect() function + * + * The packet is followed by a value of 0xfffff; if the value of the + * data following the packet is different, then we know that the + * protect function is overwriting the end of the packet. + */ + pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t) + + msg_len_octets + tag_length; + for (i = 0; i < 4; i++) + if (pkt_end[i] != 0xff) { + fprintf(stdout, "overwrite in srtp_protect() function " + "(expected %x, found %x in trailing octet %d)\n", + 0xff, ((uint8_t *)hdr)[i], i); + free(hdr); + free(hdr2); + return err_status_algo_fail; + } + + /* + * if the policy includes confidentiality, check that ciphertext is + * different than plaintext + * + * Note that this check will give false negatives, with some small + * probability, especially if the packets are short. For that + * reason, we skip this check if the plaintext is less than four + * octets long. + */ + if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) { + printf("testing that ciphertext is distinct from plaintext..."); + status = err_status_algo_fail; + for (i=12; i < msg_len_octets+12; i++) + if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { + status = err_status_ok; + } + if (status) { + printf("failed\n"); + free(hdr); + free(hdr2); + return status; + } + printf("passed\n"); + } + + /* + * if the policy uses a 'wildcard' ssrc, then we need to make a copy + * of the policy that changes the direction to inbound + * + * we always copy the policy into the rcvr_policy, since otherwise + * the compiler would fret about the constness of the policy + */ + rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t)); + if (rcvr_policy == NULL) + return err_status_alloc_fail; + memcpy(rcvr_policy, policy, sizeof(srtp_policy_t)); + if (policy->ssrc.type == ssrc_any_outbound) { + rcvr_policy->ssrc.type = ssrc_any_inbound; + } + + err_check(srtp_create(&srtp_rcvr, rcvr_policy)); + + err_check(srtp_unprotect(srtp_rcvr, hdr, &len)); + + debug_print(mod_driver, "after unprotection:\n%s", + srtp_packet_to_string(hdr, len)); + + /* verify that the unprotected packet matches the origial one */ + for (i=0; i < msg_len_octets; i++) + if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { + fprintf(stdout, "mismatch at octet %d\n", i); + status = err_status_algo_fail; + } + if (status) { + free(hdr); + free(hdr2); + return status; + } + + /* + * if the policy includes authentication, then test for false positives + */ + if (policy->rtp.sec_serv & sec_serv_auth) { + char *data = ((char *)hdr) + 12; + + printf("testing for false positives in replay check..."); + + /* set message length */ + len = msg_len_enc; + + /* unprotect a second time - should fail with a replay error */ + status = srtp_unprotect(srtp_rcvr, hdr_enc, &len); + if (status != err_status_replay_fail) { + printf("failed with error code %d\n", status); + free(hdr); + free(hdr2); + return status; + } else { + printf("passed\n"); + } + + printf("testing for false positives in auth check..."); + + /* increment sequence number in header */ + hdr->seq++; + + /* set message length */ + len = msg_len_octets; + + /* apply protection */ + err_check(srtp_protect(srtp_sender, hdr, &len)); + + /* flip bits in packet */ + data[0] ^= 0xff; + + /* unprotect, and check for authentication failure */ + status = srtp_unprotect(srtp_rcvr, hdr, &len); + if (status != err_status_auth_fail) { + printf("failed\n"); + free(hdr); + free(hdr2); + return status; + } else { + printf("passed\n"); + } + + } + + err_check(srtp_dealloc(srtp_sender)); + err_check(srtp_dealloc(srtp_rcvr)); + + free(hdr); + free(hdr2); + return err_status_ok; +} + + +err_status_t +srtcp_test(const srtp_policy_t *policy) { + int i; + srtp_t srtcp_sender; + srtp_t srtcp_rcvr; + err_status_t status = err_status_ok; + srtp_hdr_t *hdr, *hdr2; + uint8_t hdr_enc[64]; + uint8_t *pkt_end; + int msg_len_octets, msg_len_enc; + int len; + int tag_length = policy->rtp.auth_tag_len; + uint32_t ssrc; + srtp_policy_t *rcvr_policy; + + err_check(srtp_create(&srtcp_sender, policy)); + + /* print out policy */ + err_check(srtp_session_print_policy(srtcp_sender)); + + /* + * initialize data buffer, using the ssrc in the policy unless that + * value is a wildcard, in which case we'll just use an arbitrary + * one + */ + if (policy->ssrc.type != ssrc_specific) + ssrc = 0xdecafbad; + else + ssrc = policy->ssrc.value; + msg_len_octets = 28; + hdr = srtp_create_test_packet(msg_len_octets, ssrc); + + if (hdr == NULL) + return err_status_alloc_fail; + hdr2 = srtp_create_test_packet(msg_len_octets, ssrc); + if (hdr2 == NULL) { + free(hdr); + return err_status_alloc_fail; + } + + /* set message length */ + len = msg_len_octets; + + debug_print(mod_driver, "before protection:\n%s", + srtp_packet_to_string(hdr, len)); + +#if PRINT_REFERENCE_PACKET + debug_print(mod_driver, "reference packet before protection:\n%s", + octet_string_hex_string((uint8_t *)hdr, len)); +#endif + err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len)); + + debug_print(mod_driver, "after protection:\n%s", + srtp_packet_to_string(hdr, len)); +#if PRINT_REFERENCE_PACKET + debug_print(mod_driver, "after protection:\n%s", + octet_string_hex_string((uint8_t *)hdr, len)); +#endif + + /* save protected message and length */ + memcpy(hdr_enc, hdr, len); + msg_len_enc = len; + + /* + * check for overrun of the srtp_protect() function + * + * The packet is followed by a value of 0xfffff; if the value of the + * data following the packet is different, then we know that the + * protect function is overwriting the end of the packet. + */ + pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t) + + msg_len_octets + tag_length; + for (i = 0; i < 4; i++) + if (pkt_end[i] != 0xff) { + fprintf(stdout, "overwrite in srtp_protect_rtcp() function " + "(expected %x, found %x in trailing octet %d)\n", + 0xff, ((uint8_t *)hdr)[i], i); + free(hdr); + free(hdr2); + return err_status_algo_fail; + } + + /* + * if the policy includes confidentiality, check that ciphertext is + * different than plaintext + * + * Note that this check will give false negatives, with some small + * probability, especially if the packets are short. For that + * reason, we skip this check if the plaintext is less than four + * octets long. + */ + if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) { + printf("testing that ciphertext is distinct from plaintext..."); + status = err_status_algo_fail; + for (i=12; i < msg_len_octets+12; i++) + if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { + status = err_status_ok; + } + if (status) { + printf("failed\n"); + free(hdr); + free(hdr2); + return status; + } + printf("passed\n"); + } + + /* + * if the policy uses a 'wildcard' ssrc, then we need to make a copy + * of the policy that changes the direction to inbound + * + * we always copy the policy into the rcvr_policy, since otherwise + * the compiler would fret about the constness of the policy + */ + rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t)); + if (rcvr_policy == NULL) + return err_status_alloc_fail; + memcpy(rcvr_policy, policy, sizeof(srtp_policy_t)); + if (policy->ssrc.type == ssrc_any_outbound) { + rcvr_policy->ssrc.type = ssrc_any_inbound; + } + + err_check(srtp_create(&srtcp_rcvr, rcvr_policy)); + + err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len)); + + debug_print(mod_driver, "after unprotection:\n%s", + srtp_packet_to_string(hdr, len)); + + /* verify that the unprotected packet matches the origial one */ + for (i=0; i < msg_len_octets; i++) + if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { + fprintf(stdout, "mismatch at octet %d\n", i); + status = err_status_algo_fail; + } + if (status) { + free(hdr); + free(hdr2); + return status; + } + + /* + * if the policy includes authentication, then test for false positives + */ + if (policy->rtp.sec_serv & sec_serv_auth) { + char *data = ((char *)hdr) + 12; + + printf("testing for false positives in replay check..."); + + /* set message length */ + len = msg_len_enc; + + /* unprotect a second time - should fail with a replay error */ + status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len); + if (status != err_status_replay_fail) { + printf("failed with error code %d\n", status); + free(hdr); + free(hdr2); + return status; + } else { + printf("passed\n"); + } + + printf("testing for false positives in auth check..."); + + /* increment sequence number in header */ + hdr->seq++; + + /* set message length */ + len = msg_len_octets; + + /* apply protection */ + err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len)); + + /* flip bits in packet */ + data[0] ^= 0xff; + + /* unprotect, and check for authentication failure */ + status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len); + if (status != err_status_auth_fail) { + printf("failed\n"); + free(hdr); + free(hdr2); + return status; + } else { + printf("passed\n"); + } + + } + + err_check(srtp_dealloc(srtcp_sender)); + err_check(srtp_dealloc(srtcp_rcvr)); + + free(hdr); + free(hdr2); + return err_status_ok; +} + + +err_status_t +srtp_session_print_policy(srtp_t srtp) { + char *serv_descr[4] = { + "none", + "confidentiality", + "authentication", + "confidentiality and authentication" + }; + char *direction[3] = { + "unknown", + "outbound", + "inbound" + }; + srtp_stream_t stream; + + /* sanity checking */ + if (srtp == NULL) + return err_status_fail; + + /* if there's a template stream, print it out */ + if (srtp->stream_template != NULL) { + stream = srtp->stream_template; + printf("# SSRC: any %s\r\n" + "# rtp cipher: %s\r\n" + "# rtp auth: %s\r\n" + "# rtp services: %s\r\n" + "# rtcp cipher: %s\r\n" + "# rtcp auth: %s\r\n" + "# rtcp services: %s\r\n", + direction[stream->direction], + stream->rtp_cipher->type->description, + stream->rtp_auth->type->description, + serv_descr[stream->rtp_services], + stream->rtcp_cipher->type->description, + stream->rtcp_auth->type->description, + serv_descr[stream->rtcp_services]); + } + + /* loop over streams in session, printing the policy of each */ + stream = srtp->stream_list; + while (stream != NULL) { + if (stream->rtp_services > sec_serv_conf_and_auth) + return err_status_bad_param; + + printf("# SSRC: 0x%08x\r\n" + "# rtp cipher: %s\r\n" + "# rtp auth: %s\r\n" + "# rtp services: %s\r\n" + "# rtcp cipher: %s\r\n" + "# rtcp auth: %s\r\n" + "# rtcp services: %s\r\n", + stream->ssrc, + stream->rtp_cipher->type->description, + stream->rtp_auth->type->description, + serv_descr[stream->rtp_services], + stream->rtcp_cipher->type->description, + stream->rtcp_auth->type->description, + serv_descr[stream->rtcp_services]); + + /* advance to next stream in the list */ + stream = stream->next; + } + return err_status_ok; +} + +err_status_t +srtp_print_policy(const srtp_policy_t *policy) { + err_status_t status; + srtp_t session; + + status = srtp_create(&session, policy); + if (status) + return status; + status = srtp_session_print_policy(session); + if (status) + return status; + status = srtp_dealloc(session); + if (status) + return status; + return err_status_ok; +} + +/* + * srtp_print_packet(...) is for debugging only + * it prints an RTP packet to the stdout + * + * note that this function is *not* threadsafe + */ + +#include <stdio.h> + +#define MTU 2048 + +char packet_string[MTU]; + +char * +srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) { + int octets_in_rtp_header = 12; + uint8_t *data = ((uint8_t *)hdr)+octets_in_rtp_header; + int hex_len = pkt_octet_len-octets_in_rtp_header; + + /* sanity checking */ + if ((hdr == NULL) || (pkt_octet_len > MTU)) + return NULL; + + /* write packet into string */ + sprintf(packet_string, + "(s)rtp packet: {\n" + " version:\t%d\n" + " p:\t\t%d\n" + " x:\t\t%d\n" + " cc:\t\t%d\n" + " m:\t\t%d\n" + " pt:\t\t%x\n" + " seq:\t\t%x\n" + " ts:\t\t%x\n" + " ssrc:\t%x\n" + " data:\t%s\n" + "} (%d octets in total)\n", + hdr->version, + hdr->p, + hdr->x, + hdr->cc, + hdr->m, + hdr->pt, + hdr->seq, + hdr->ts, + hdr->ssrc, + octet_string_hex_string(data, hex_len), + pkt_octet_len); + + return packet_string; +} + +/* + * mips_estimate() is a simple function to estimate the number of + * instructions per second that the host can perform. note that this + * function can be grossly wrong; you may want to have a manual sanity + * check of its output! + * + * the 'ignore' pointer is there to convince the compiler to not just + * optimize away the function + */ + +double +mips_estimate(int num_trials, int *ignore) { + clock_t t; + int i, sum; + + sum = 0; + t = clock(); + for (i=0; i<num_trials; i++) + sum += i; + t = clock() - t; + +/* printf("%d\n", sum); */ + *ignore = sum; + + return (double) num_trials * CLOCKS_PER_SEC / t; +} + + +/* + * srtp_validate() verifies the correctness of libsrtp by comparing + * some computed packets against some pre-computed reference values. + * These packets were made with the default SRTP policy. + */ + + +err_status_t +srtp_validate() { + unsigned char test_key[30] = { + 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0, + 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39, + 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb, + 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6 + }; + uint8_t srtp_plaintext_ref[28] = { + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab + }; + uint8_t srtp_plaintext[38] = { + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + uint8_t srtp_ciphertext[38] = { + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c, + 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15, + 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc, + 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb + }; + srtp_t srtp_snd, srtp_recv; + err_status_t status; + int len; + srtp_policy_t policy; + + /* + * create a session with a single stream using the default srtp + * policy and with the SSRC value 0xcafebabe + */ + crypto_policy_set_rtp_default(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = 0xcafebabe; + policy.key = test_key; + policy.next = NULL; + + status = srtp_create(&srtp_snd, &policy); + if (status) + return status; + + /* + * protect plaintext, then compare with ciphertext + */ + len = 28; + status = srtp_protect(srtp_snd, srtp_plaintext, &len); + if (status || (len != 38)) + return err_status_fail; + + debug_print(mod_driver, "ciphertext:\n %s", + octet_string_hex_string(srtp_plaintext, len)); + debug_print(mod_driver, "ciphertext reference:\n %s", + octet_string_hex_string(srtp_ciphertext, len)); + + if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) + return err_status_fail; + + /* + * create a receiver session context comparable to the one created + * above - we need to do this so that the replay checking doesn't + * complain + */ + status = srtp_create(&srtp_recv, &policy); + if (status) + return status; + + /* + * unprotect ciphertext, then compare with plaintext + */ + status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len); + if (status || (len != 28)) + return status; + + if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) + return err_status_fail; + + return err_status_ok; +} + + +err_status_t +srtp_create_big_policy(srtp_policy_t **list) { + extern const srtp_policy_t *policy_array[]; + srtp_policy_t *p, *tmp; + int i = 0; + uint32_t ssrc = 0; + + /* sanity checking */ + if ((list == NULL) || (policy_array[0] == NULL)) + return err_status_bad_param; + + /* + * loop over policy list, mallocing a new list and copying values + * into it (and incrementing the SSRC value as we go along) + */ + tmp = NULL; + while (policy_array[i] != NULL) { + p = (srtp_policy_t*) malloc(sizeof(srtp_policy_t)); + if (p == NULL) + return err_status_bad_param; + memcpy(p, policy_array[i], sizeof(srtp_policy_t)); + p->ssrc.type = ssrc_specific; + p->ssrc.value = ssrc++; + p->next = tmp; + tmp = p; + i++; + } + *list = p; + + return err_status_ok; +} + +err_status_t +srtp_test_remove_stream() { + err_status_t status; + srtp_policy_t *policy_list; + srtp_t session; + srtp_stream_t stream; + /* + * srtp_get_stream() is a libSRTP internal function that we declare + * here so that we can use it to verify the correct operation of the + * library + */ + extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc); + + + status = srtp_create_big_policy(&policy_list); + if (status) + return status; + + status = srtp_create(&session, policy_list); + if (status) + return status; + + /* + * check for false positives by trying to remove a stream that's not + * in the session + */ + status = srtp_remove_stream(session, htonl(0xaaaaaaaa)); + if (status != err_status_no_ctx) + return err_status_fail; + + /* + * check for false negatives by removing stream 0x1, then + * searching for streams 0x0 and 0x2 + */ + status = srtp_remove_stream(session, htonl(0x1)); + if (status != err_status_ok) + return err_status_fail; + stream = srtp_get_stream(session, htonl(0x0)); + if (stream == NULL) + return err_status_fail; + stream = srtp_get_stream(session, htonl(0x2)); + if (stream == NULL) + return err_status_fail; + + return err_status_ok; +} + +/* + * srtp policy definitions - these definitions are used above + */ + +unsigned char test_key[30] = { + 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0, + 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39, + 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb, + 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6 +}; + + +const srtp_policy_t default_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { /* SRTP policy */ + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 16, /* auth key length in octets */ + 10, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + { /* SRTCP policy */ + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 16, /* auth key length in octets */ + 10, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + test_key, + NULL +}; + +const srtp_policy_t aes_tmmh_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + UST_TMMHv2, /* authentication func type */ + 94, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + { + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + UST_TMMHv2, /* authentication func type */ + 94, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + test_key, + NULL +}; + +const srtp_policy_t tmmh_only_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + UST_TMMHv2, /* authentication func type */ + 94, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_auth /* security services flag */ + }, + { + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + UST_TMMHv2, /* authentication func type */ + 94, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_auth /* security services flag */ + }, + test_key, + NULL +}; + +const srtp_policy_t aes_only_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + NULL_AUTH, /* authentication func type */ + 0, /* auth key length in octets */ + 0, /* auth tag length in octets */ + sec_serv_conf /* security services flag */ + }, + { + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + NULL_AUTH, /* authentication func type */ + 0, /* auth key length in octets */ + 0, /* auth tag length in octets */ + sec_serv_conf /* security services flag */ + }, + test_key, + NULL +}; + +const srtp_policy_t hmac_only_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { + NULL_CIPHER, /* cipher type */ + 0, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 20, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_auth /* security services flag */ + }, + { + NULL_CIPHER, /* cipher type */ + 0, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 20, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_auth /* security services flag */ + }, + test_key, + NULL +}; + +const srtp_policy_t null_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { + NULL_CIPHER, /* cipher type */ + 0, /* cipher key length in octets */ + NULL_AUTH, /* authentication func type */ + 0, /* auth key length in octets */ + 0, /* auth tag length in octets */ + sec_serv_none /* security services flag */ + }, + { + NULL_CIPHER, /* cipher type */ + 0, /* cipher key length in octets */ + NULL_AUTH, /* authentication func type */ + 0, /* auth key length in octets */ + 0, /* auth tag length in octets */ + sec_serv_none /* security services flag */ + }, + test_key, + NULL +}; + + +/* + * an array of pointers to the policies listed above + * + * This array is used to test various aspects of libSRTP for + * different cryptographic policies. The order of the elements + * matters - the timing test generates output that can be used + * in a plot (see the gnuplot script file 'timing'). If you + * add to this list, you should do it at the end. + */ + +#define USE_TMMH 0 + +const srtp_policy_t * +policy_array[] = { + &hmac_only_policy, +#if USE_TMMH + &tmmh_only_policy, +#endif + &aes_only_policy, +#if USE_TMMH + &aes_tmmh_policy, +#endif + &default_policy, + &null_policy, + NULL +}; + +const srtp_policy_t wildcard_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { /* SRTP policy */ + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 16, /* auth key length in octets */ + 10, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + { /* SRTCP policy */ + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 16, /* auth key length in octets */ + 10, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + test_key, + NULL +}; diff --git a/src/libs/resiprocate/contrib/srtp/timing b/src/libs/resiprocate/contrib/srtp/timing new file mode 100644 index 00000000..66b00c45 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/timing @@ -0,0 +1 @@ +# timing.plt # # gnuplot script file for plotting the output generated by srtp_driver -t # # David A. McGrew # Cisco Systems, Inc. # set xrange [0:2500] set term pict "Times-Roman" 9 # # plot authentication-only data # set title "Authentication Only" set ylabel "Megabits per second" set xlabel "Octets in packet" set yrange [0:2000] set output "plot-auth.pict" plot "timing.dat" index 0 title "HMAC SHA1" with lines, "timing.dat" index 1 title "TMMH/AES" with lines, "timing.dat" index 2 title "TMMH/SEAL" with lines # # plot encryption-only data # set title "Encryption Only" set ylabel "Megabits per second" set xlabel "Octets in packet" set output "plot-enc.pict" set yrange [0:1200] plot "timing.dat" index 3 title "SEAL" with lines, "timing.dat" index 4 title "AES ICM" with lines # # plot encryption and authentication data # set title "Encryption and Authentication" set ylabel "Megabits per second" set xlabel "Octets in packet" set yrange [0:1000] set output "plot-enc-auth.pict" plot "timing.dat" index 5 title "TMMH/SEAL" with lines, "timing.dat" index 6 title "TMMH/AES" with lines, "timing.dat" index 7 title "HMAC/AES" with lines \ No newline at end of file diff --git a/src/libs/resiprocate/contrib/srtp/undos.sh b/src/libs/resiprocate/contrib/srtp/undos.sh new file mode 100644 index 00000000..db120649 --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/undos.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# +# usage: undos <file> +# +# strips CRs from a file - useful when moving DOS-created files +# onto UN*X machines + +cat $1 | tr -d "\r" > $1.tmp +mv $1.tmp $1 + diff --git a/src/libs/resiprocate/contrib/srtp/update.sh b/src/libs/resiprocate/contrib/srtp/update.sh new file mode 100644 index 00000000..595b647f --- /dev/null +++ b/src/libs/resiprocate/contrib/srtp/update.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# +# update.sh +# +# update copyright dates in files + +a=`find . -name "*.[ch]"` +for x in $a; do + sed 's/(c) 2001-2005/(c) 2001-2006/' $x > $x.tmp; + mv $x.tmp $x; +done + + + + diff --git a/src/libs/resiprocate/p2p/AbstractValue.hxx b/src/libs/resiprocate/p2p/AbstractValue.hxx new file mode 100644 index 00000000..f71dd358 --- /dev/null +++ b/src/libs/resiprocate/p2p/AbstractValue.hxx @@ -0,0 +1,56 @@ +#ifndef P2P_AbstractValue_hxx +#define P2P_AbstractValue_hxx + +#include "Signable.hxx" + +namespace p2p +{ + +class AbstractValue :public Signable +{ + public: + int getKind() const; + UInt64 getGeneration() const; + + void setKind(int kind) const; + void getGeneration(UInt64 generation) const; +}; + +} // p2p + +#endif // P2P_AbstractValue_hxx + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/ArrayValue.hxx b/src/libs/resiprocate/p2p/ArrayValue.hxx new file mode 100644 index 00000000..f97e5725 --- /dev/null +++ b/src/libs/resiprocate/p2p/ArrayValue.hxx @@ -0,0 +1,67 @@ +#ifndef P2P_ArrayValue_hxx +#define P2P_ArrayValue_hxx + +#include "rutil/Data.hxx" +#include "AbstractValue.hxx" +#include "SingleValue.hxx" +#include "DataSpecifier.hxx" + +#include <map> + +namespace p2p +{ + +class ArrayValue : public AbstractValue +{ + public: + static const UInt32 Last = SpecifyArray::Last; + typedef std::map<int, SingleValue> ArrayMap; + void sign(); + bool isValid() const; + + ArrayMap& arrayMap() { return mArrayMap; } + const ArrayMap& arrayMap() const { return mArrayMap; } + protected: + std::vector<resip::Data> collectSignableData() const = 0; + private: + ArrayMap mArrayMap; +}; + +} // p2p + +#endif // P2P_ArrayValue_hxx + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + diff --git a/src/libs/resiprocate/p2p/BatchMessages.cxx b/src/libs/resiprocate/p2p/BatchMessages.cxx new file mode 100644 index 00000000..074e3ffc --- /dev/null +++ b/src/libs/resiprocate/p2p/BatchMessages.cxx @@ -0,0 +1,122 @@ +#include "BatchMessages.hxx" + +#include "p2p/P2PSubsystem.hxx" +#include "p2p/EventWrapper.hxx" +#include "p2p/Dispatcher.hxx" +#include "p2p/Connect.hxx" +#include "p2p/FetchAns.hxx" +#include "p2p/Find.hxx" +#include "p2p/Leave.hxx" +#include "p2p/Join.hxx" +#include "p2p/StoreAns.hxx" +#include "p2p/Update.hxx" +#include "p2p/Message.hxx" + +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P + +using namespace p2p; + +BatchMessages::BatchMessages(Dispatcher& dispatcher, + std::vector<std::auto_ptr<Message> >& messages, + Postable<Event>& postable) + : mPostable(&postable), + mResponseCount(messages.size()), + mSucceeded(true) +{ + for (std::vector<std::auto_ptr<Message> >::iterator i = messages.begin(); + i != messages.end(); i++) + { + dispatcher.send(*i, *this); + } +} + +BatchMessages::~BatchMessages() +{} + +void +BatchMessages::countDown(Message& message) +{ + if (message.getType() == Message::FailureResponseType) + { + mSucceeded = false; + } + mResponseCount--; + if (mResponseCount == 0) + { + mPostable->post(std::auto_ptr<Event>(this)); + } +} + +void +BatchMessages::completed() +{ + if (mSucceeded) + { + onSuccess(); + } + else + { + onFailure(); + } +} + +void BatchMessages::consume(PingAns& m) +{ + countDown(m); +} + +void BatchMessages::consume(ConnectAns& m) +{ + countDown(m); +} + +void BatchMessages::consume(TunnelAns& m) +{ + countDown(m); +} + +void BatchMessages::consume(StoreAns& m) +{ + countDown(m); +} + +void BatchMessages::consume(FetchAns& m) +{ + countDown(m); +} + +void BatchMessages::consume(RemoveAns& m) +{ + countDown(m); +} + +void BatchMessages::consume(FindAns& m) +{ + countDown(m); +} + +void BatchMessages::consume(JoinAns& m) +{ + countDown(m); +} + +void BatchMessages::consume(LeaveAns& m) +{ + countDown(m); +} + +void BatchMessages::consume(UpdateAns& m) +{ + countDown(m); +} + +void BatchMessages::consume(RouteQueryAns& m) +{ + countDown(m); +} + +void BatchMessages::consume(ErrorResponse& m) +{ + countDown(m); +} + diff --git a/src/libs/resiprocate/p2p/BatchMessages.hxx b/src/libs/resiprocate/p2p/BatchMessages.hxx new file mode 100644 index 00000000..1568ca28 --- /dev/null +++ b/src/libs/resiprocate/p2p/BatchMessages.hxx @@ -0,0 +1,109 @@ +#ifndef P2P_BatchMessages_hxx +#define P2P_BatchMessages_hxx + +#include <memory> +#include <vector> + +#include "EventConsumerBase.hxx" +#include "Event.hxx" + +namespace p2p +{ + +class Dispatcher; +class Message; + +class BatchMessages : public EventConsumerBase, public Event +{ + BatchMessages(Dispatcher& dispatcher, + std::vector<std::auto_ptr<Message> >& messages, + Postable<Event>& postable); + virtual ~BatchMessages() = 0; + + virtual void onFailure() = 0; + virtual void onSuccess() = 0; + // called by creator on consumption + void completed(); + + virtual void consume(PingAns& m); + virtual void consume(ConnectAns& m); + virtual void consume(TunnelAns& m); + virtual void consume(StoreAns& m); + virtual void consume(FetchAns& m); + virtual void consume(RemoveAns& m); + virtual void consume(FindAns& m); + virtual void consume(JoinAns& m); + virtual void consume(LeaveAns& m); + virtual void consume(UpdateAns& m); + virtual void consume(RouteQueryAns& m); + virtual void consume(ErrorResponse& m); + + // other consumer methods + virtual void consume(CertDoneEvent& certdone) { assert(0); } + virtual void consume(ConnectionOpened& m) { assert(0); } + virtual void consume(ConnectionClosed& m) { assert(0); } + virtual void consume(MessageArrived& m) { assert(0); } + virtual void consume(ApplicationMessageArrived& m) { assert(0); } + virtual void consume(LocalCandidatesCollected& m) { assert(0); } + virtual void consume(PingReq& m) { assert(0); } + virtual void consume(ConnectReq& m) { assert(0); } + virtual void consume(TunnelReq& m) { assert(0); } + virtual void consume(StoreReq& m) { assert(0); } + virtual void consume(FetchReq& m) { assert(0); } + virtual void consume(RemoveReq& m) { assert(0); } + virtual void consume(JoinReq& m) { assert(0); } + virtual void consume(LeaveReq& m) { assert(0); } + virtual void consume(UpdateReq& m) { assert(0); } + virtual void consume(RouteQueryReq& m) { assert(0); } + virtual void consume(const BatchMessages& cm) { assert(0); } + + virtual resip::Data brief() const + { + return "BatchMessages"; + } + + private: + void countDown(Message& m); + Postable<Event>* mPostable; + int mResponseCount; + bool mSucceeded; +}; + +} + +#endif + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/Candidate.hxx b/src/libs/resiprocate/p2p/Candidate.hxx new file mode 100644 index 00000000..b08e98e4 --- /dev/null +++ b/src/libs/resiprocate/p2p/Candidate.hxx @@ -0,0 +1,136 @@ +#ifndef __P2P_CANDIDATE_HXX +#define __P2P_CANDIDATE_HXX 1 + +#include "rutil/GenericIPAddress.hxx" +#include "rutil/TransportType.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Logger.hxx" + +#include "p2p/P2PSubsystem.hxx" +namespace p2p +{ + +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P + +//candidate:1 1 UDP 2130706431 10.0.1.1 8998 typ host + +class Candidate +{ + public: + + Candidate(resip::TransportType type, resip::GenericIPAddress& address) + : mTransportType(type), mAddress(address) + { + resip::Data tmp; + { + resip::DataStream ds(tmp); + + ds << "candidate:1 1 " + << resip::getTransportNameFromType(type) << " " + << rand() << " " + << resip::DnsUtil::inet_ntop(address.v4Address.sin_addr) << " " + << ntohs(address.v4Address.sin_port) << " typ host"; + } + mValue = tmp; + } + + Candidate(const resip::Data &iceline) + { + resip::Data transport; + resip::Data ip("127.0.0.1"); // WRONG WRONG WRONG + resip::Data port; + const char *anchor; + + DebugLog(<< "Constructing Candidate from iceline " << iceline); + resip::ParseBuffer pb(iceline); + + // At beginning + pb.skipToChar(' '); // At end of foundation + pb.skipWhitespace(); // Skip the whitespace after foundation + + // Beginning of component ID + pb.skipToChar(' '); // End of component ID + + anchor = pb.skipWhitespace(); // Beginning of transport + pb.skipToChar(' '); // End of transport + pb.data(transport, anchor); + DebugLog(<< "transport is " << transport); + + pb.skipWhitespace(); // Beginning of priority + pb.skipToChar(' '); // End of priority + + anchor = pb.skipWhitespace(); // Beginning of IP + pb.skipToChar(' '); // End of IP + // pb.data(ip, anchor); WRONG WRONG WRONG + DebugLog(<< "IP is " << ip); + + anchor=pb.skipWhitespace(); // Beginning of port + pb.skipToChar(' '); // End of port + pb.data(port, anchor); + DebugLog(<< "port is " << port); + + mTransportType = resip::getTransportTypeFromName(transport.c_str()); + + mAddress.v4Address.sin_family = AF_INET; + mAddress.v4Address.sin_port = htons(port.convertInt()); + memset(mAddress.v4Address.sin_zero, 0, + sizeof(mAddress.v4Address.sin_zero)) ; + + resip::DnsUtil::inet_pton(ip, mAddress.v4Address.sin_addr); + + mValue = iceline; + } + + const resip::Data &getIceString() const { return mValue; } + + const resip::TransportType &getTransportType() const + { return mTransportType; } + + const resip::GenericIPAddress &getAddress() const + { return mAddress; } + + private: + resip::Data mValue; + resip::TransportType mTransportType; + resip::GenericIPAddress mAddress; + // TODO add ice specific members +}; + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/CertDoneEvent.hxx b/src/libs/resiprocate/p2p/CertDoneEvent.hxx new file mode 100644 index 00000000..9f754489 --- /dev/null +++ b/src/libs/resiprocate/p2p/CertDoneEvent.hxx @@ -0,0 +1,38 @@ +#ifndef P2P_CertDone_hxx +#define P2P_CertDone_hxx + +#include "rutil/Data.hxx" +#include "Event.hxx" + +namespace p2p +{ + +class CertDone : public Event +{ + public: + enum Resolution + { + Succeeded = 0, + NoNetWork, + SingerUnknown, + }; + + CertDone(const resip::Data& id, + Resolution resolution) + : mId(id) + {} + + virtual resip::Data brief() const + { + return "CertDone"; + } + + + private: + const resip::Data mId; + Resolution mResolution; +}; + +} // p2p + +#endif // P2P_CertDone_hxx diff --git a/src/libs/resiprocate/p2p/ChordTopology.cxx b/src/libs/resiprocate/p2p/ChordTopology.cxx new file mode 100644 index 00000000..5db3a27f --- /dev/null +++ b/src/libs/resiprocate/p2p/ChordTopology.cxx @@ -0,0 +1,647 @@ + +#include "rutil/Data.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/ssl/SHA1Stream.hxx" + +#include "p2p/Candidate.hxx" +#include "p2p/ChordTopology.hxx" +#include "p2p/ChordUpdate.hxx" +#include "p2p/Connect.hxx" +#include "p2p/Dispatcher.hxx" +#include "p2p/FlowId.hxx" +#include "p2p/Message.hxx" +#include "p2p/P2PSubsystem.hxx" +#include "p2p/Profile.hxx" +#include "p2p/Update.hxx" + +using namespace p2p; + +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P + +ChordTopology::ChordTopology(Profile& config, + Dispatcher& dispatcher, + Transporter& transporter) : + TopologyAPI(config, dispatcher, transporter), mJoined(false) +{ +} + + +ChordTopology::~ChordTopology() +{ +} + + +void +ChordTopology::joinOverlay() +{ + // tell the transport layer to form a connection to bootstrap node (special + // bootstrap connect ). This needs to give up the address of the BP node + mTransporter.connect(mProfile.bootstrapNodes().front()); + DebugLog(<< "attempting to connect to bootstrap node"); +} + + +// Messages that the forwarding layer sends to this object +void +ChordTopology::newConnectionFormed( const NodeId& node, bool inbound ) +{ + DebugLog(<< "newConnectionFormed to: " << node << " (" << (inbound ? "inbound" : "outbound") << ")"); + + if(!inbound) + { + // If this is the first connection we have - then it must be the connection to + // the bootstrap node + if(mFingerTable.size() == 0 && mNextTable.size() == 0 && !mProfile.isBootstrap()) + { + // collect candidates for our NodeId + attach(mProfile.nodeId()); + + // Build finger table + buildFingerTable(); + } + + // If we are not joined yet and this connection is to our Admitting Peer (next peer) + // the send a join + if(mNextTable.size() == 1 && node == mNextTable[0]) + { + DebugLog(<< "sending join to node: " << node); + DestinationId destination(node); + std::auto_ptr<Message> joinReq(new JoinReq(destination, mProfile.nodeId())); + mDispatcher.send(joinReq, *this); + } + + // go and add this to the finger table + assert(mFingerTable.find(node) == mFingerTable.end()); + mFingerTable.insert(node); + } +} + + +void +ChordTopology::connectionLost( const NodeId& node ) +{ + DebugLog(<< "connectionLost to: " << node); + + // if node is in the finger table, remove it + mFingerTable.erase(node); + + // if node is in the mPrevTable, remove it + std::vector<NodeId>::iterator it = mPrevTable.begin(); + for(; it != mPrevTable.end(); it++) + { + if(*it == node) + { + mPrevTable.erase(it); + } + } + + // if this is in the mNextTable, remove it + it = mNextTable.begin(); + for(; it != mNextTable.end(); it++) + { + if(*it == node) + { + mPrevTable.erase(it); + } + } + + // TODO - go get another finger table entry? +} + + +void +ChordTopology::consume(ConnectReq& msg) +{ + DebugLog(<< "received CONNECT req."); + + // Build Connect Response and store to be sent out after candidate collection completes + // Real data will be filled out later + mPendingResponses[msg.getTransactionId()] = msg.makeConnectResponse(resip::Data::Empty /* frag */, + resip::Data::Empty /* password */, + RELOAD_APPLICATION_ID, + resip::Data::Empty /* role */, + msg.getCandidates() /* candidates */); + + // Collect candidates for response + startCandidateCollection(msg.getTransactionId(), msg.getResponseNodeId() /* TODO - we really want to retrieve sending NodeId */); + + // Socket connect - once ice is integrated this likely needs to move to after the candidates are collected + resip::GenericIPAddress stunTurnServer; + mTransporter.connect(msg.getResponseNodeId(), msg.getCandidates(), stunTurnServer /* stunTurnServer */); +} + + +// deal with topoogy change messages +void +ChordTopology::consume(JoinReq& msg) +{ + DebugLog(<< "received JOIN req from: " << msg.getNodeId()); + + // check we are reponsible for the data from this node + if(!isResponsible(msg.getNodeId())) + { + // send error response - not responsible + std::auto_ptr<Message> errorAns(msg.makeErrorResponse(Message::Error::NotFound, "Not responsible for this Join")); + mDispatcher.send(errorAns, *this); + return; + } + + // TODO - send the data using multiple store messages over to the new node + // use a StoreSet to monitor + + // TODO - update the replicated data storage + + // wait for all data to be stored + + // send them an update to put the joining node in the ring + std::vector<NodeId> nodes; + nodes.push_back(msg.getNodeId()); + if(addNewNeighbors(nodes, false /* adjustNextOnly */)) + { + sendUpdates(); + } + + std::auto_ptr<Message> joinAns(msg.makeJoinResponse(resip::Data::Empty /* Overlay specific */)); + mDispatcher.send(joinAns, *this); +} + + +void +ChordTopology::consume(UpdateReq& msg) +{ + DebugLog(<< "received JOIN req from: ?"); + + // if our, prev empty, then this update will have the prev and need to + // connect to them and set the prev + ChordUpdate cordUpdate( msg.getRequestMessageBody() ); + + if(addNewNeighbors(cordUpdate.getPredecessors(), false /* adjustNextOnly */) || + addNewNeighbors(cordUpdate.getSuccessors(), false /* adjustNextOnly */)) + { + sendUpdates(); + } + + std::auto_ptr<Message> udpateAns(msg.makeUpdateResponse(resip::Data::Empty /* Overlay specific */)); + mDispatcher.send(udpateAns, *this); +} + + +void +ChordTopology::consume(LeaveReq& msg) +{ + DebugLog(<< "received LEAVE req from: ?"); + + // if this is in the prev/next table, remove it and send updates + assert(0); + + std::auto_ptr<Message> leaveAns(msg.makeLeaveResponse()); + mDispatcher.send(leaveAns, *this); +} + + +void +ChordTopology::consume(ConnectAns& msg) +{ + DebugLog(<< "received CONNECT ans from: " << msg.getResponseNodeId()); + +} + + +void +ChordTopology::consume(JoinAns& msg) +{ + DebugLog(<< "received JOIN ans from: " << msg.getResponseNodeId()); + + // TODO check response code? + mJoined = true; +} + + +void +ChordTopology::consume(UpdateAns& msg) +{ + DebugLog(<< "received UPDATE ans from: " << msg.getResponseNodeId()); + + // TODO check response - and log? +} + + +void +ChordTopology::consume(LeaveAns& msg) +{ + DebugLog(<< "received LEAVE ans from: " << msg.getResponseNodeId()); + + // TODO check response - and log? +} + + +// Deal with routing queries +const NodeId& +ChordTopology::findNextHop( const NodeId& node ) +{ + assert( !isResponsible(node) ); + + if(mFingerTable.size() == 0) + { + // return the next pointer and increment around slowly + assert( mNextTable.size() > 0 ); + DebugLog(<< "findNextHop returning (from next table): " << mNextTable[0]); + + // TODO - deal with case wehre there is no next + + return mNextTable[0]; + } + + std::set<NodeId>::iterator it = mFingerTable.begin(); + for(;it != mFingerTable.end(); it++) + { + std::set<NodeId>::iterator nextIt = it; + nextIt++; + if(nextIt == mFingerTable.end()) break; + if((*it <= node) && (node < *nextIt)) + { + DebugLog(<< "findNextHop returning (from finger table): " << *it); + return *it; + } + } + DebugLog(<< "findNextHop returning: " << *it); + return *it; +} + + +const NodeId& +ChordTopology::findNextHop( const ResourceId& resource ) +{ + NodeId node( resource.value() ); + return findNextHop( node ); +} + + +const NodeId& +ChordTopology::findNextHop( const DestinationId& did ) +{ + if(did.isNodeId()) + { + return findNextHop(did.asNodeId()); + } + else if(did.isResourceId()) + { + return findNextHop(did.asResourceId()); + } + else + { + assert(false); + static NodeId none; + return none; + } +} + + +// Deal with replication for storage +std::vector<NodeId> +ChordTopology::getReplicationSet( const ResourceId& resource ) +{ + std::vector<NodeId> replicateSet; + const unsigned int numReplications=2; + + for ( unsigned int i=0; i<numReplications; i++) + { + if (mNextTable.size() > i ) + { + replicateSet[i] = mNextTable[i]; + } + } + + return replicateSet; +} + + +// Functions to find out if this peer is responsible for something +bool +ChordTopology::isResponsible( const NodeId& node ) const +{ + // for now we are going to assume that if the prev table is empty, then we have a + // a new ring being formed and we are responsible for this request. We need to consider + // the case where we are a node trying to join a stable ring, and the "join" process + // has not completed yet - but we receive a message for another node. + if (mPrevTable.size() == 0) + { + if ( mProfile.isBootstrap() ) + { + return true; // only thing in the ring so responsible for everything + } + else + { + return false; // have not joined ring yet so responsible for nothing + } + } + + if ( (mPrevTable[0] < node) && (node <= mProfile.nodeId()) ) + { + return true; + } + return false; +} + + +bool +ChordTopology::isResponsible( const ResourceId& resource ) const +{ + NodeId node( resource.value() ); + return isResponsible( node ); +} + +bool +ChordTopology::isResponsible( const DestinationId& did ) const +{ + if(did.isNodeId()) + { + return isResponsible(did.asNodeId()); + } + else if(did.isResourceId()) + { + return isResponsible(did.asResourceId()); + } + else + { + assert(false); + return false; + } +} + + +// Functions to find out if this peer is responsible for something +bool +ChordTopology::isConnected( const NodeId& node ) const +{ + // Check if node is in finger table + if(mFingerTable.find(node) != mFingerTable.end()) + { + return true; + } + + return false; +} + + +// Function to hash resource names into resourceID +ResourceId +ChordTopology::resourceId( const resip::Data& resourceName ) +{ + // call sha1, truncate to 128 bits, and return + resip::SHA1Stream strm; + strm << resourceName; + resip::ParseBuffer pb(strm.getBin()); + const char* anchor = pb.position(); + pb.skipN(128); + resip::Data result; + pb.data(result, anchor); + + return ResourceId(result); +} + + +void +ChordTopology::post(std::auto_ptr<Event> event) +{ + //will run in same thread as the dispatcher + DebugLog(<< "ChordTopology received: " << event->brief()); + event->dispatch(*this); +} + +bool +ChordTopology::addNewNeighbors(const std::vector<NodeId>& nodes, bool adjustNextOnly) +{ + // This function takes a list of nodes and merges them into next and prev + // tables. If anything changes, it sends updates + + assert( nodes.size() > 0 ); + bool changed=false; + + for (unsigned int n=0; n<nodes.size(); n++ ) + { + bool setNext = false; + bool setPrev = false; + if (mNextTable.size() == 0) + { + setNext = true; + } + else if ( (mProfile.nodeId() < nodes[n]) && (nodes[n] < mNextTable[0]) ) + { + setNext = true; + } + + if(!adjustNextOnly) + { + if (mPrevTable.size() == 0) + { + setPrev = true; + } + else if ( (mPrevTable[0] < nodes[n]) && (nodes[n] < mProfile.nodeId()) ) + { + setPrev = true; + } + } + + if(setNext) + { + DebugLog(<< "new next neighbour added: " << nodes[n]); + mNextTable[0] = nodes[n]; + } + + if(setPrev) + { + DebugLog(<< "new prev neighbour added: " << nodes[n]); + mPrevTable[0] = nodes[n]; + } + + if(setNext || setPrev) + { + changed=true; + // kick start connection to newly added node if not admitting peer addition + DebugLog(<< "collecting candidates for new neighbour: " << nodes[n]); + if(!adjustNextOnly) attach(nodes[n]); + } + } + + return changed; +} + +// May not actually be needed +bool +ChordTopology::addNewFingers(const std::vector<NodeId>& nodes) +{ + assert( nodes.size() > 0 ); + bool changed=false; + + // iterate through finger table and check if we are actually adding new nodes + std::vector<NodeId>::const_iterator it = nodes.begin(); + for(;it != nodes.end(); it++) + { + std::set<NodeId>::iterator it2 = mFingerTable.find(*it); + if(it2 == mFingerTable.end()) + { + changed = true; + mFingerTable.insert(*it); + } + } + return changed; +} + + +// TODO - need timers that periodically call this +void +ChordTopology::buildFingerTable() +{ + assert(mProfile.numInitialFingers() <= 127); + for(unsigned int i = 0; i < mProfile.numInitialFingers(); i++) + { + NodeId fingerNodeId = mProfile.nodeId().add2Pow(127-i); + DebugLog(<< "collecting candidates for fingertable: " << fingerNodeId); + attach(fingerNodeId); + } +} + + +void +ChordTopology::sendUpdates() +{ + // Create our update message + ChordUpdate ourUpdate; + ourUpdate.setUpdateType(ChordUpdate::Neighbors); + + // set our predecessors and successors + ourUpdate.setPredecessors(mPrevTable); + ourUpdate.setSuccessors(mNextTable); + + // TODO - put our nodeid somewhere in the message? + + // if this changes the neighbor tables and if it does send updates to all + // peers in prev/next table + std::vector<NodeId>::iterator it = mPrevTable.begin(); + for(; it != mPrevTable.end(); it++) + { + DebugLog(<< "sending update to prev neighbour: " << *it); + DestinationId destination(*it); + std::auto_ptr<Message> updateReq(new UpdateReq(destination, ourUpdate.encode())); + mDispatcher.send(updateReq, *this); + } + + it = mNextTable.begin(); + for(; it != mNextTable.end(); it++) + { + DebugLog(<< "sending update to next neighbour: " << *it); + DestinationId destination(*it); + std::auto_ptr<Message> updateReq(new UpdateReq(destination, ourUpdate.encode())); + mDispatcher.send(updateReq, *this); + } +} + + + +// Connection management subsystem... This will eventually need to be +// moved somewhere else, but for now... + +void +ChordTopology::attach(const NodeId &attachTo) +{ + DebugLog(<< "Attaching to node " << attachTo); + + startCandidateCollection(0,attachTo); +} + +void +ChordTopology::startCandidateCollection(const UInt64 tid, const NodeId &attachTo) +{ + DebugLog(<< "Starting candidate collection"); + + mTransporter.collectCandidates(tid, attachTo); +} + + +void +ChordTopology::candidatesCollected(UInt64 tid, + const NodeId& node, unsigned short appId, std::vector<Candidate>& candidates) +{ + + if(tid==0) + { + DebugLog(<< "candidateCollection completed, sending CONNECT req to: " << node); + + // We're initiating + + // This needs to be a resourceId to ensure correct routing + // hack-o-rama + ResourceId rid(node.encodeToNetwork()); + DestinationId destination(rid); + + std::auto_ptr<Message> connectReq(new ConnectReq(destination, resip::Data::Empty /* icefrag */, resip::Data::Empty /* password */, appId, resip::Data::Empty /* ice tcp role */, candidates)); + mDispatcher.send(connectReq, *this); + } + else + { + DebugLog(<< "candidateCollection completed, sending CONNECT response to: " << node); + // We're responding + + // Find pending response + PendingResponseMap::iterator it = mPendingResponses.find(tid); + if(it != mPendingResponses.end()) + { + if(it->second->getType() == Message::ConnectAnsType) + { + // Fill in the remaining Connect Response data + ConnectAns* connectAns = (ConnectAns*)it->second; + connectAns->setCandidates(candidates); + mDispatcher.send(std::auto_ptr<Message>(it->second), *this); + // Send Connect Ans + mPendingResponses.erase(it); + } + else + { + // Response not of expected type + assert(false); + } + } + else + { + // Response not found + assert(false); + } + } +} + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/ChordTopology.hxx b/src/libs/resiprocate/p2p/ChordTopology.hxx new file mode 100644 index 00000000..d0edc473 --- /dev/null +++ b/src/libs/resiprocate/p2p/ChordTopology.hxx @@ -0,0 +1,135 @@ +#ifndef __P2P_CHORDTOPOLOGY_HXX +#define __P2P_CHORDTOPOLOGY_HXX 1 + +#include <set> +#include "rutil/Data.hxx" +#include "rutil/Fifo.hxx" + +#include "p2p/NodeId.hxx" +#include "p2p/ResourceId.hxx" +#include "p2p/Profile.hxx" +#include "p2p/Message.hxx" +#include "p2p/TopologyAPI.hxx" + +namespace p2p +{ + +class Dispatcher; + +/// This is an abstract base class from which to derive the actually topology plugins +class ChordTopology : public TopologyAPI +{ + public: + ChordTopology(Profile& config, + Dispatcher& dispatcher, + Transporter& transporter); + virtual ~ChordTopology(); + + virtual void joinOverlay(); + + // need a fifo to receive timer events + + // Messages that the forwarding layer sends to this object + virtual void newConnectionFormed( const NodeId& node, bool inbound ); + virtual void connectionLost( const NodeId& node ); + + // deal with topology change messages + virtual void consume(ConnectReq& msg); + virtual void consume(JoinReq& msg); + virtual void consume(UpdateReq& msg); + virtual void consume(LeaveReq& msg); + + // deal with responses + virtual void consume(ConnectAns& msg); + virtual void consume(JoinAns& msg); + virtual void consume(UpdateAns& msg); + virtual void consume(LeaveAns& msg); + + // called when store set completes, cases update to get sent + // virtual void consume(EventWrapper<StoreSetFoo>& event); + + // Deal with routing querries + virtual const NodeId& findNextHop( const DestinationId& did); + virtual const NodeId& findNextHop( const NodeId& node ); + virtual const NodeId& findNextHop( const ResourceId& resource ); + + // Deal with replication for storage + virtual std::vector<NodeId> getReplicationSet( const ResourceId& resource ); + /// Returns list of nodes to replicate on + + // Functions to find out if this peer is responsible for something + virtual bool isResponsible( const DestinationId& did ) const; + virtual bool isResponsible( const NodeId& node ) const; + virtual bool isResponsible( const ResourceId& resource ) const; + + // Function to determine if we are connected to a node + virtual bool isConnected( const NodeId& node ) const; + + // Function to hash resource names into resourceID + virtual ResourceId resourceId( const resip::Data& resourceName ); + + // not public api + virtual void post(std::auto_ptr<Event> message); + + private: + + std::set<NodeId> mFingerTable; + std::vector<NodeId> mPrevTable; + std::vector<NodeId> mNextTable; + bool mJoined; + + typedef std::map<UInt64, Message* > PendingResponseMap; + PendingResponseMap mPendingResponses; + + bool addNewNeighbors( const std::vector<NodeId>& nodes, bool adjustNextOnly ); // return true if + // anything changed + bool addNewFingers( const std::vector<NodeId>& nodes ); // return true if changed + void buildFingerTable(); + void sendUpdates(); + + // Attach subsystem + void attach(const NodeId &attachTo); + void startCandidateCollection(const UInt64 tid, const NodeId &id); + virtual void candidatesCollected( UInt64 tid, + const NodeId& node, + unsigned short appId, + std::vector<Candidate>& candidates); +}; + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/ChordUpdate.cxx b/src/libs/resiprocate/p2p/ChordUpdate.cxx new file mode 100644 index 00000000..23328e09 --- /dev/null +++ b/src/libs/resiprocate/p2p/ChordUpdate.cxx @@ -0,0 +1,142 @@ +#include "p2p/ChordUpdate.hxx" +#include <assert.h> + +using namespace p2p; +using namespace s2c; + +ChordUpdate::ChordUpdate() : + mUpdateType(NotSpecified) +{ + +} + +ChordUpdate::ChordUpdate(const resip::Data &chordUpdateBody) : + mUpdateBody(chordUpdateBody), + mUpdateType(NotSpecified) +{ + parse(); +} + +bool +ChordUpdate::operator == (const ChordUpdate &chord) const +{ + return + (mUpdateType == chord.mUpdateType) && + (mPredecessors == chord.mPredecessors) && + (mSuccessors == chord.mSuccessors) && + (mFingers == chord.mFingers); +} + +void +ChordUpdate::setUpdateType(UpdateType updateType) +{ + mUpdateType = updateType; +} + +void +ChordUpdate::clear() +{ + mPredecessors.clear(); + mSuccessors.clear(); + mFingers.clear(); +} + +const std::vector<NodeId> & +ChordUpdate::getFingers() +{ + assert(mUpdateType == Full); + return mFingers; +} + +const std::vector<NodeId> & +ChordUpdate::getSuccessors() +{ + assert(mUpdateType == Neighbors || mUpdateType == Full); + return mSuccessors; +} + +const std::vector<NodeId> & +ChordUpdate::getPredecessors() +{ + assert(mUpdateType == Neighbors || mUpdateType == Full); + return mPredecessors; +} + +void +ChordUpdate::setFingers(const std::vector<NodeId> &fingers) +{ + mFingers = fingers; +} + +void +ChordUpdate::setSuccessors(const std::vector<NodeId> &successors) +{ + mSuccessors = successors; +} + +void +ChordUpdate::setPredecessors(const std::vector<NodeId> &predecessors) +{ + mPredecessors = predecessors; +} + +resip::Data +ChordUpdate::encode() +{ + resip::Data encodedData; + + { + resip::DataStream encodedStream(encodedData); + + mType = static_cast<ChordUpdateType>(mUpdateType); + s2c::ChordUpdateStruct::encode(encodedStream); + } + + return encodedData; +} + +void +ChordUpdate::parse() +{ + resip::DataStream encodedStream(mUpdateBody); + decode(encodedStream); + + mUpdateType = static_cast<UpdateType>(mType); +} + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + + + diff --git a/src/libs/resiprocate/p2p/ChordUpdate.hxx b/src/libs/resiprocate/p2p/ChordUpdate.hxx new file mode 100644 index 00000000..40b5a77e --- /dev/null +++ b/src/libs/resiprocate/p2p/ChordUpdate.hxx @@ -0,0 +1,95 @@ +#ifndef P2P_CHORDUPDATE_HXX +#define P2P_CHORDUPDATE_HXX + +#include "rutil/Data.hxx" +#include "p2p/NodeId.hxx" +#include "p2p/MessageStructsGen.hxx" + +namespace p2p +{ + +class ChordUpdate : private s2c::ChordUpdateStruct +{ +public: + enum UpdateType + { + Reserved = 0, + PeerReady = 1, + Neighbors = 2, + Full = 3, + NotSpecified = 0xff + }; + + ChordUpdate(); + + // parses immediately + ChordUpdate(const resip::Data &chordUpdateBody); + + UpdateType getUpdateType() const { return mUpdateType; } + void setUpdateType(UpdateType updateType); + + // empties NodeId vectors + void clear(); + + // these will assert if mUpdateType is incorrect, assumes it's already ben parsed (handled in ctor) + const std::vector<NodeId> &getFingers(); + const std::vector<NodeId> &getSuccessors(); + const std::vector<NodeId> &getPredecessors(); + + void setFingers(const std::vector<NodeId> &fingers); + void setSuccessors(const std::vector<NodeId> &successors); + void setPredecessors(const std::vector<NodeId> &predecessors); + + resip::Data encode(); // encodes into a blob + + bool operator == (const ChordUpdate &chord) const; +protected: + resip::Data mUpdateBody; + UpdateType mUpdateType; + + std::vector<NodeId> mPredecessors; + std::vector<NodeId> mSuccessors; + std::vector<NodeId> mFingers; +private: + void parse(); + +}; + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + diff --git a/src/libs/resiprocate/p2p/Connect.cxx b/src/libs/resiprocate/p2p/Connect.cxx new file mode 100644 index 00000000..d36b24c8 --- /dev/null +++ b/src/libs/resiprocate/p2p/Connect.cxx @@ -0,0 +1,37 @@ +#include "p2p/Connect.hxx" +#include "p2p/MessageHelper.hxx" + +using namespace p2p; +using namespace s2c; + +ConnectReq::ConnectReq() +{ +} + +ConnectReq::ConnectReq(const DestinationId &dest, + const resip::Data &frag, + const resip::Data &password, + UInt16 application, + const resip::Data &role, + const std::vector<Candidate> &candidates) : + ConnectBase(frag, password, application, role, candidates) +{ + pushDestinationId(dest); +} + +ConnectAns::ConnectAns() +{ + ; +} + +ConnectAns::ConnectAns(Message *req, + const resip::Data &frag, + const resip::Data &password, + UInt16 application, + const resip::Data &role, + const std::vector<Candidate> &candidates) : + ConnectBase(frag, password, application, role, candidates) +{ + assert(req); + copyForwardingData(*req); +} diff --git a/src/libs/resiprocate/p2p/Connect.hxx b/src/libs/resiprocate/p2p/Connect.hxx new file mode 100644 index 00000000..789df93b --- /dev/null +++ b/src/libs/resiprocate/p2p/Connect.hxx @@ -0,0 +1,51 @@ +#ifndef P2P_CONNECT_HXX +#define P2P_CONNECT_HXX + +#include "p2p/Message.hxx" +#include "p2p/ConnectBase.hxx" +#include "p2p/EventWrapper.hxx" +namespace p2p +{ + +class ConnectReq : public ConnectBase +{ +public: + ConnectReq(const DestinationId &dest, const resip::Data &frag, const resip::Data &password, UInt16 application, const resip::Data &role, const std::vector<Candidate> &candidates); + virtual MessageType getType() const { return ConnectReqType; } + virtual resip::Data brief() const { return "ConnectReq Message"; } + + std::auto_ptr<Event> event() + { + return wrap(this); + } + +protected: + friend class Message; + + ConnectReq(); +}; + +class ConnectAns : public ConnectBase +{ +public: + + virtual MessageType getType() const { return ConnectAnsType; } + virtual resip::Data brief() const { return "ConnectAns Message"; } + + std::auto_ptr<Event> event() + { + return wrap(this); + } + +protected: + friend class Message; + + // should use Message::makeResponse + ConnectAns(Message *req, const resip::Data &frag, const resip::Data &password, UInt16 application, const resip::Data &role, const std::vector<Candidate> &candidates); + ConnectAns(); +}; + + +} + +#endif diff --git a/src/libs/resiprocate/p2p/ConnectBase.cxx b/src/libs/resiprocate/p2p/ConnectBase.cxx new file mode 100644 index 00000000..054dac04 --- /dev/null +++ b/src/libs/resiprocate/p2p/ConnectBase.cxx @@ -0,0 +1,81 @@ +#include "p2p/ConnectBase.hxx" +#include "p2p/Message.hxx" + +using namespace p2p; +using namespace s2c; + + +ConnectBase::ConnectBase() +{ + +} + +void +ConnectBase::decodePayload(resip::DataStream &dataStream) +{ + decode(dataStream); + + print(std::cout, 2); +} + +void +ConnectBase::getEncodedPayload(resip::DataStream &dataStream) +{ + encode(dataStream); +} + +ConnectBase::ConnectBase(const resip::Data &frag, const resip::Data &password, UInt16 application, const resip::Data &role, const std::vector<Candidate> &candidates) +{ + mUfrag = frag; + mPassword = password; + mApplication = application; + mRole = role; + setCandidates(candidates); +} + +const resip::Data& +ConnectBase::getUfrag() +{ + return mUfrag; +} + +const resip::Data& +ConnectBase::getPassword() +{ + return mPassword; +} + +UInt16 +ConnectBase::getApplication() +{ + return mApplication; +} + +const resip::Data& +ConnectBase::getRole() +{ + return mRole; +} + +std::vector<Candidate> +ConnectBase::getCandidates() +{ + std::vector<Candidate> retCandidates; + std::vector<IceCandidateStruct*>::iterator it = mCandidates.begin(); + for(;it != mCandidates.end(); it++) + { + retCandidates.push_back(Candidate((*it)->mCandidate)); + } + return retCandidates; +} + +void +ConnectBase::setCandidates(const std::vector<Candidate> &candidates) +{ + for (std::vector<Candidate>::const_iterator iter = candidates.begin(); iter != candidates.end(); iter++) + { + IceCandidateStruct *iceStruct = new IceCandidateStruct; + iceStruct->mCandidate = iter->getIceString(); + mCandidates.push_back(iceStruct); + } +} diff --git a/src/libs/resiprocate/p2p/ConnectBase.hxx b/src/libs/resiprocate/p2p/ConnectBase.hxx new file mode 100644 index 00000000..fc8a4c8f --- /dev/null +++ b/src/libs/resiprocate/p2p/ConnectBase.hxx @@ -0,0 +1,34 @@ +#ifndef P2P_CONNECTBASE_HXX +#define P2P_CONNECTBASE_HXX + +#include "p2p/Message.hxx" +#include "p2p/MessageHelper.hxx" +#include "p2p/Candidate.hxx" + +namespace p2p +{ + +class ConnectBase : public Message, protected s2c::ConnectReqAnsStruct +{ +public: + friend class Message; + + ConnectBase(const resip::Data &frag, const resip::Data &password, UInt16 application, const resip::Data &role, const std::vector<Candidate> &candidates); + virtual void getEncodedPayload(resip::DataStream &dataStream); + + const resip::Data& getUfrag(); + const resip::Data& getPassword(); + UInt16 getApplication(); + const resip::Data& getRole(); + std::vector<Candidate> getCandidates(); + + void setCandidates(const std::vector<Candidate> &candidates); + +protected: + virtual void decodePayload(resip::DataStream &dataStream); + ConnectBase(); +}; + +} + +#endif diff --git a/src/libs/resiprocate/p2p/DataSpecifier.hxx b/src/libs/resiprocate/p2p/DataSpecifier.hxx new file mode 100644 index 00000000..9974104f --- /dev/null +++ b/src/libs/resiprocate/p2p/DataSpecifier.hxx @@ -0,0 +1,58 @@ +#ifndef P2P_DataSpecifier_hxx +#define P2P_DataSpecifier_hxx + +#include <list> +#include <vector> + +namespace p2p +{ + +class DataSpecifier +{ + public: + KindId kind; + Generation generation; + //encoding? +}; + +class SpecifySingle :public DataSpecifier +{ + public: +}; + +//default to entire array +class SpecifyArray :public DataSpecifier +{ + public: + const static UInt32 Last = INT_MAX; + + class Range + { + public: + UInt32 first; + UInt32 last; + }; + + std::vector<Range>& ranges(); + const std::vector<Range>& ranges() const; + + private: + std::vector<Range>& mRange; +}; + +//empty is entire dictionary, th default +class SpecifyDictionary +{ + public: + std::vector<resip::Data>& keys(); +}; + +// class DeleteReq +// { +// public: +// typedef std::list<DataSpecifier> Specifiers; +// }; + +} // p2p + +#endif P2P_DataSpecifier_hxx diff --git a/src/libs/resiprocate/p2p/DestinationId.cxx b/src/libs/resiprocate/p2p/DestinationId.cxx new file mode 100644 index 00000000..d89d33f7 --- /dev/null +++ b/src/libs/resiprocate/p2p/DestinationId.cxx @@ -0,0 +1,135 @@ +#include <algorithm> +#include <assert.h> + +#include "rutil/Data.hxx" +#include "p2p/DestinationId.hxx" + +using namespace p2p; + +DestinationId::DestinationId(s2c::DestinationStruct s) : s2c::DestinationStruct(s) +{ +} + +DestinationId::DestinationId(const NodeId& nid) +{ + mPeer.mNodeId = new s2c::NodeIdStruct; + *(mPeer.mNodeId) = nid.getNodeIdStruct(); + mResource.mResourceId = 0; + mType = s2c::peer; +} + +DestinationId::DestinationId(const ResourceId& rid) +{ + mPeer.mNodeId = 0; + mResource.mResourceId = new s2c::ResourceIdStruct; + mResource.mResourceId->mId = rid.value(); + mType = s2c::resource; +} + +bool +DestinationId::isNodeId() const +{ + return (mType == s2c::peer); +} + +NodeId +DestinationId::asNodeId() const +{ + assert(isNodeId()); + assert(mPeer.mNodeId); + return NodeId(*mPeer.mNodeId); +} + +bool +DestinationId::isCompressedId()const +{ + return (mType == s2c::compressed); +} + +CompressedId +DestinationId::asCompressedId() const +{ + assert(isCompressedId()); + return CompressedId(mCompressed.mCompressedId); +} + +bool +DestinationId::isResourceId()const +{ + return (mType == s2c::resource); +} + +ResourceId +DestinationId::asResourceId() const +{ + assert(isResourceId()); + assert(mResource.mResourceId); + return ResourceId(mResource.mResourceId->mId); +} + +bool +DestinationId::operator==(const NodeId& nid) const +{ + return (isNodeId() && nid == asNodeId()); +} + +bool +DestinationId::operator==(const DestinationId& nid) const +{ + if (nid.isNodeId() && this->isNodeId()) + { + return nid.asNodeId() == this->asNodeId(); + } + else if (nid.isResourceId() && this->isResourceId()) + { + return nid.asResourceId() == this->asResourceId(); + } + else if (nid.isCompressedId() && this->isCompressedId()) + { + return nid.asCompressedId() == this->asCompressedId(); + } + return false; +} + +s2c::DestinationStruct* +DestinationId::copyDestinationStruct() const +{ + return new s2c::DestinationStruct(*this); +} + + + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/DestinationId.hxx b/src/libs/resiprocate/p2p/DestinationId.hxx new file mode 100644 index 00000000..aa3ee84d --- /dev/null +++ b/src/libs/resiprocate/p2p/DestinationId.hxx @@ -0,0 +1,36 @@ +#ifndef __P2P_DESTINATION_ID_HXX +#define __P2P_DESTINATION_ID_HXX + +#include "p2p/MessageStructsGen.hxx" +#include "p2p/NodeId.hxx" +#include "p2p/ResourceId.hxx" + +namespace p2p +{ + +// Either a CompressedId, NodeId or ResourceId +class DestinationId : private s2c::DestinationStruct +{ + public: + DestinationId(s2c::DestinationStruct); + DestinationId(const NodeId& nid); + DestinationId(const ResourceId& rid); + + bool isNodeId() const; + NodeId asNodeId() const; + + bool isCompressedId() const; + CompressedId asCompressedId() const; + + bool isResourceId() const; + ResourceId asResourceId() const; + + bool operator==(const NodeId& nid) const; + bool operator==(const DestinationId& nid) const; + + s2c::DestinationStruct* copyDestinationStruct() const; +}; + +} + +#endif diff --git a/src/libs/resiprocate/p2p/DictionaryValue.hxx b/src/libs/resiprocate/p2p/DictionaryValue.hxx new file mode 100644 index 00000000..b6abd9f8 --- /dev/null +++ b/src/libs/resiprocate/p2p/DictionaryValue.hxx @@ -0,0 +1,90 @@ +#ifndef P2P_DictionayValue_hxx +#define P2P_DictionaryValue_hxx + +#include "rutil/Data.hxx" +#include <map> + +namespace p2p +{ + +class DictionaryValue : public AbstractValue +{ + public: + DictionaryValue() + : mMap() + {} + + virtual std::vector<resip::Data> collectSignableData() const + { + assert(0); + } + + private: + class Entry : public Signable { + Entry(const resip::Data& key, const resip::Data& value) + : mKey(key), + mValue(value) + {} + + virtual std::vector<resip::Data> collectSignableData() const + { + std::vector<resip::Data> result; + result.push_back(resip::Data(resip::Data::Borrow, mKey)); + result.push_back(resip::Data(resip::Data::Borrow, mValue)); + return result; + } + + bool exists() + { + return mValue == SingleValue::NoValue; + } + + private: + const resip::Data mKey; + const resip::Data mValue; + }; + + std::map<resip::Data, Entry> mMap; + + public: + std::map<resip::Data, Entry>& value(); +}; + +} // p2p + +#endif // P2P_DictionaryValue_hxx + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/Dispatcher.cxx b/src/libs/resiprocate/p2p/Dispatcher.cxx new file mode 100644 index 00000000..3c3b037c --- /dev/null +++ b/src/libs/resiprocate/p2p/Dispatcher.cxx @@ -0,0 +1,84 @@ +#include "p2p/Dispatcher.hxx" + +#include "p2p/P2PSubsystem.hxx" +#include "p2p/EventWrapper.hxx" +#include "p2p/ForwardingLayer.hxx" +#include "rutil/Logger.hxx" +#include "p2p/Message.hxx" + +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P + +using namespace p2p; + +Dispatcher::Dispatcher() + : mForwardingLayer(0) +{} + +void +Dispatcher::init(ForwardingLayer& forwardingLayer) +{ + mForwardingLayer = &forwardingLayer; +} + +void +Dispatcher::registerPostable(Message::MessageType type, + Postable<Event>& postable) +{ + Registry::iterator it = mRegistry.find(type); + if (it == mRegistry.end()) + { + mRegistry[type] = &postable; + } + else + { + assert(0); + } +} + +void +Dispatcher::send(std::auto_ptr<Message> message, Postable<Event>& postable) +{ + //.dcm. more with timers + + mTidMap[message->getTransactionId()] = Entry(postable); + mForwardingLayer->forward(message); +} + +static const resip::Data NO_HANDLER("Message not understood"); + +void +Dispatcher::post(std::auto_ptr<Message> message) +{ + DebugLog(<<"Dispatcher received " << message->brief()); + + Registry::iterator it = mRegistry.find(message->getType()); + if (it == mRegistry.end()) + { + if (message->isRequest()) + { + mForwardingLayer->forward(std::auto_ptr<Message>( + message->makeErrorResponse(Message::Error::Forbidden, + NO_HANDLER))); + } + else + { + TidMap::iterator id = mTidMap.find(message->getTransactionId()); + if (id != mTidMap.end()) + { + Entry& entry = id->second; + entry.mPostable->post(message.release()->event()); + mTidMap.erase(id); + } + else + { + DebugLog(<< "Unexpected response, dropping " + << message->brief()); + } + } + } + else + { + it->second->post(message.release()->event()); + } +} + diff --git a/src/libs/resiprocate/p2p/Dispatcher.hxx b/src/libs/resiprocate/p2p/Dispatcher.hxx new file mode 100644 index 00000000..30f83151 --- /dev/null +++ b/src/libs/resiprocate/p2p/Dispatcher.hxx @@ -0,0 +1,84 @@ +#ifndef P2P_Dispatcher_hxx +#define P2P_Dispatcher_hxx + +#include "p2p/Postable.hxx" +#include "p2p/Message.hxx" +#include <map> + +namespace p2p +{ + +class Event; +class Message; +class ForwardingLayer; + +class Dispatcher : public Postable<Message> +{ + public: + Dispatcher(); + + void init(ForwardingLayer& forwardingLayer); + void registerPostable(Message::MessageType type, Postable<Event>& postable); + void send(std::auto_ptr<Message> message, Postable<Event>& responseSink); + + // not public API + virtual void post(std::auto_ptr<Message> message); + + private: + class Entry + { + public: + Entry() + : mPostable(0) + {} + Entry(Postable<Event>& postable, bool forBaseMessage = false) + : mPostable(&postable) + {} + Postable<Event>* mPostable; + }; + + typedef std::map<Message::MessageType, Postable<Event>*> Registry; + typedef std::map<TransactionId, Entry> TidMap; + Registry mRegistry; + TidMap mTidMap; + ForwardingLayer* mForwardingLayer; +}; + +} // p2p + +#endif // P2P_Dispatcher_hxx + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/Event.hxx b/src/libs/resiprocate/p2p/Event.hxx new file mode 100644 index 00000000..dd689ad5 --- /dev/null +++ b/src/libs/resiprocate/p2p/Event.hxx @@ -0,0 +1,25 @@ +#ifndef P2P_Event_hxx +#define P2P_Event_hxx + +#include "rutil/Data.hxx" + +#include "p2p.hxx" + +namespace p2p +{ + +class EventConsumer; + +class Event +{ + public: + virtual ~Event(){}; + virtual void dispatch(EventConsumer& consumer) = 0; + + virtual resip::Data brief() const =0; + +}; + +} + +#endif // P2P_Event_hxx diff --git a/src/libs/resiprocate/p2p/EventConsumer.hxx b/src/libs/resiprocate/p2p/EventConsumer.hxx new file mode 100644 index 00000000..c7eed280 --- /dev/null +++ b/src/libs/resiprocate/p2p/EventConsumer.hxx @@ -0,0 +1,88 @@ +#ifndef P2P_EventConsumer_hxx +#define P2P_EventConsumer_hxx + +#include <cassert> + +#include "p2p/EventConsumerBase.hxx" + +namespace p2p +{ + +class EventConsumer : public EventConsumerBase +{ + public: + virtual ~EventConsumer(){}; + + virtual void consume(CertDoneEvent& certdone) { assert(0); } + virtual void consume(ConnectionOpened& m) { assert(0); } + virtual void consume(ConnectionClosed& m) { assert(0); } + virtual void consume(MessageArrived& m) { assert(0); } + virtual void consume(ApplicationMessageArrived& m) { assert(0); } + virtual void consume(LocalCandidatesCollected& m) { assert(0); } + + virtual void consume(PingReq& m) { assert(0); } + virtual void consume(PingAns& m) { assert(0); } + virtual void consume(ConnectReq& m) { assert(0); } + virtual void consume(ConnectAns& m) { assert(0); } + virtual void consume(TunnelReq& m) { assert(0); } + virtual void consume(TunnelAns& m) { assert(0); } + virtual void consume(StoreReq& m) { assert(0); } + virtual void consume(StoreAns& m) { assert(0); } + virtual void consume(FetchReq& m) { assert(0); } + virtual void consume(FetchAns& m) { assert(0); } + virtual void consume(RemoveReq& m) { assert(0); } + virtual void consume(RemoveAns& m) { assert(0); } + virtual void consume(FindAns& m) { assert(0); } + virtual void consume(JoinReq& m) { assert(0); } + virtual void consume(JoinAns& m) { assert(0); } + virtual void consume(LeaveReq& m) { assert(0); } + virtual void consume(LeaveAns& m) { assert(0); } + virtual void consume(UpdateReq& m) { assert(0); } + virtual void consume(UpdateAns& m) { assert(0); } + virtual void consume(RouteQueryReq& m) { assert(0); } + virtual void consume(RouteQueryAns& m) { assert(0); } + virtual void consume(ErrorResponse& m) { assert(0); } + + virtual void consume(const BatchMessages& cm) { assert(0); } + + virtual resip::Data brief() const { return "EventConsumer"; } + +}; + +} + +#endif // P2P_EventConsumer_hxx + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/EventConsumerBase.hxx b/src/libs/resiprocate/p2p/EventConsumerBase.hxx new file mode 100644 index 00000000..e23ceadd --- /dev/null +++ b/src/libs/resiprocate/p2p/EventConsumerBase.hxx @@ -0,0 +1,124 @@ +#ifndef P2P_EventConsumerBase_hxx +#define P2P_EventConsumerBase_hxx + +#include <cassert> + +#include "p2p/Postable.hxx" + +namespace p2p +{ + +class BatchMessages; +class CertDoneEvent; +class ConnectionOpened; +class ConnectionClosed; +class Event; +class MessageArrived; +class ApplicationMessageArrived; +class LocalCandidatesCollected; + +class PingReq; +class PingAns; +class ConnectReq; +class ConnectAns; +class TunnelReq; +class TunnelAns; +class StoreReq; +class StoreAns; +class FetchReq; +class FetchAns; +class RemoveReq; +class RemoveAns; +class FindReq; +class FindAns; +class JoinReq; +class JoinAns; +class LeaveReq; +class LeaveAns; +class UpdateReq; +class UpdateAns; +class RouteQueryReq; +class RouteQueryAns; +class ErrorResponse; + +template<class T> class EventWrapper; + +/** + * Base class for consuming double dispatced events. + * Events can be sent to the consumer as a Postable. + */ +class EventConsumerBase : public Postable<Event> +{ + public: + virtual ~EventConsumerBase(){}; + + virtual void consume(CertDoneEvent& certdone) = 0; + virtual void consume(ConnectionOpened& m) = 0; + virtual void consume(ConnectionClosed& m) = 0; + virtual void consume(MessageArrived& m) = 0; + virtual void consume(ApplicationMessageArrived& m) = 0; + virtual void consume(LocalCandidatesCollected& m) = 0; + + virtual void consume(PingReq& m) = 0; + virtual void consume(PingAns& m) = 0; + virtual void consume(ConnectReq& m) = 0; + virtual void consume(ConnectAns& m) = 0; + virtual void consume(TunnelReq& m) = 0; + virtual void consume(TunnelAns& m) = 0; + virtual void consume(StoreReq& m) = 0; + virtual void consume(StoreAns& m) = 0; + virtual void consume(FetchReq& m) = 0; + virtual void consume(FetchAns& m) = 0; + virtual void consume(RemoveReq& m) = 0; + virtual void consume(RemoveAns& m) = 0; + virtual void consume(FindAns& m) = 0; + virtual void consume(JoinReq& m) = 0; + virtual void consume(JoinAns& m) = 0; + virtual void consume(LeaveReq& m) = 0; + virtual void consume(LeaveAns& m) = 0; + virtual void consume(UpdateReq& m) = 0; + virtual void consume(UpdateAns& m) = 0; + virtual void consume(RouteQueryReq& m) = 0; + virtual void consume(RouteQueryAns& m) = 0; + virtual void consume(ErrorResponse& m) = 0; + + virtual void consume(const BatchMessages& cm) = 0; +}; + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/EventWrapper.hxx b/src/libs/resiprocate/p2p/EventWrapper.hxx new file mode 100644 index 00000000..041d184b --- /dev/null +++ b/src/libs/resiprocate/p2p/EventWrapper.hxx @@ -0,0 +1,43 @@ +#ifndef P2P_EventWrapper_hxx +#define P2P_EventWrapper_hxx + +#include "p2p/p2p.hxx" +#include "p2p/Event.hxx" +#include "p2p/EventConsumer.hxx" + +#include <memory> + +namespace p2p +{ + +template <class T> +class EventWrapper : public Event +{ + public: + EventWrapper(T* t) : mWrapped(t) + {} + + virtual void dispatch(EventConsumer& consumer) + { + consumer.consume(*mWrapped); + } + + virtual resip::Data brief() const + { + return "Event Wrapper"; + } + + + private: + std::auto_ptr<T> mWrapped; +}; + +template <class T> +static std::auto_ptr<Event> wrap(T* t) +{ + return std::auto_ptr<Event>(new EventWrapper<T>(t)); +} + +} + +#endif // P2P_Event_hxx diff --git a/src/libs/resiprocate/p2p/FetchAns.hxx b/src/libs/resiprocate/p2p/FetchAns.hxx new file mode 100644 index 00000000..723ec223 --- /dev/null +++ b/src/libs/resiprocate/p2p/FetchAns.hxx @@ -0,0 +1,66 @@ +#ifndef P2P_FetchAns_hxx +#define P2P_FetchAns_hxx + +#include "Message.hxx" +#include "AbstractValue.hxx" +#include "rutil/SharedPtr.hxx" + +namespace p2p +{ + +class FetchAns : public Message +{ + public: + typedef std::list<resip::SharedPtr<AbstractValue> > AbstractValues; + virtual MessageType getMessageType() const { return Message::FetchAnsType; } + + AbstractValues& values(); + const AbstractValues& values() const; + + std::auto_ptr<Event> event() + { + return wrap(this); + } + + private: + AbstractValues mValues; +}; + +} // p2p + +#endif // P2P_FetchAns_hxx + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + diff --git a/src/libs/resiprocate/p2p/FetchKind.hxx b/src/libs/resiprocate/p2p/FetchKind.hxx new file mode 100644 index 00000000..f50cefb8 --- /dev/null +++ b/src/libs/resiprocate/p2p/FetchKind.hxx @@ -0,0 +1,82 @@ +#ifndef P2P_FetchKind_hxx +#define P2P_FetchKind_hxx + +#include "p2p.hxx" + +namespace p2p +{ + +class DataSpecifier +{ + public: + KindId kind; + //encoding? +}; + +class SpecifySingle : public FetchKind +{ + public: +}; + +//defualt to entire array +class SpecifyArray : public FetchKind +{ + public: + class RangeEntry + { + public: + size_t index; + bool isEnd(); + }; + class Range + { + public: + RangeEntry first; + RangeEntry last; + }; + + void addRange(const RangeEntry& r); + + vector<Range>& ranges(); + const vector<Range>& ranges() const; +}; + +//empty is entire dictionary, th default +class SpecifyDictionary +{ + public: + std::vector<Data>& keys(); +}; + +class FetchReq +{ + public: + //resoure + typedef std::list<DataSpecifier> Specifiers; +}; + +class DeleteReq +{ + public: + typedef std::list<DataSpecifier> Specifiers; +}; + +} // p2p + +#endif // P2P_FetchKind_hxx + +//this is boring, no special foo required...stay close to defn. +//are these potential replicas or committed replicas? Seems that timing would be +//an issue. +/* +struct { + KindId kind; + uint64 generation_counter; + NodeId replicas<0..2^16-1>; +} StoreKindResponse; + + +struct { + StoreKindResponse kind_responses<0..2^16-1>; +} StoreAns; +*/ diff --git a/src/libs/resiprocate/p2p/FetchReq.hxx b/src/libs/resiprocate/p2p/FetchReq.hxx new file mode 100644 index 00000000..bbd8aefb --- /dev/null +++ b/src/libs/resiprocate/p2p/FetchReq.hxx @@ -0,0 +1,68 @@ +#ifndef P2P_FetchReq_hxx +#define P2P_FetchReq_hxx + +#include "DataSpecifier.hxx" + +#include "rutil/SharedPtr.hxx" +#include "Message.hxx" + +namespace p2p +{ + +class FetchReq : public ResourceMessage +{ + public: + typedef std::list<resip::SharedPtr<DataSpecifier> > DataSpecifiers; + + virtual MessageType getMessageType() const { return Message::FetchReqType; } + + DataSpecifiers& specifiers(); + const DataSpecifiers& specifiers() const; + + std::auto_ptr<Event> event() + { + return wrap(this); + } + + private: + DataSpecifiers mSpecifier; +}; + +} // p2p + +#endif // P2P_FetchReq_hxx + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + diff --git a/src/libs/resiprocate/p2p/Find.cxx b/src/libs/resiprocate/p2p/Find.cxx new file mode 100644 index 00000000..8ba9f8a3 --- /dev/null +++ b/src/libs/resiprocate/p2p/Find.cxx @@ -0,0 +1,3 @@ +#include "p2p/Find.hxx" + +using namespace p2p; diff --git a/src/libs/resiprocate/p2p/Find.hxx b/src/libs/resiprocate/p2p/Find.hxx new file mode 100644 index 00000000..4799aba6 --- /dev/null +++ b/src/libs/resiprocate/p2p/Find.hxx @@ -0,0 +1,24 @@ +#ifndef P2P_Find_hxx +#define P2P_Find_hxx + +#include "p2p/Message.hxx" + +namespace p2p +{ + +class FindAns : public Message +{ + public: + virtual MessageType getMessageType() const { return FindAnsType; } +}; + + +class FindReq : public Message +{ + public: + virtual MessageType getMessageType() const { return FindReqType; } +}; + +} + +#endif diff --git a/src/libs/resiprocate/p2p/FlowId.cxx b/src/libs/resiprocate/p2p/FlowId.cxx new file mode 100644 index 00000000..1f773d9a --- /dev/null +++ b/src/libs/resiprocate/p2p/FlowId.cxx @@ -0,0 +1,15 @@ +#include "p2p/Event.hxx" +#include "p2p/FlowId.hxx" +#include <iostream> + +namespace p2p +{ + +std::ostream& +operator<<( std::ostream& strm, const FlowId& flow ) +{ + strm << "Flow: " << flow.getApplication() << " " << flow.getSocket(); + return strm; +} + +} diff --git a/src/libs/resiprocate/p2p/FlowId.hxx b/src/libs/resiprocate/p2p/FlowId.hxx new file mode 100644 index 00000000..0a9810b6 --- /dev/null +++ b/src/libs/resiprocate/p2p/FlowId.hxx @@ -0,0 +1,82 @@ +#ifndef __P2P_FLOW_ID_HXX +#define __P2P_FLOW_ID_HXX 1 + +#include "rutil/Socket.hxx" +#include "rutil/Fifo.hxx" +#include "p2p/NodeId.hxx" + +#include <iosfwd> + +namespace p2p +{ + +class Event; + +class FlowId +{ + public: + FlowId(NodeId nodeId, + unsigned short application, + resip::Socket &socket, + resip::Fifo<Event>& fifo) + : mNodeId(nodeId), mApplication(application), + mFifo(fifo), + mDescriptor(socket) + {;} + + resip::Socket getSocket() const { return mDescriptor; } + + unsigned short getApplication() const {return mApplication;} + + const NodeId &getNodeId() const {return mNodeId;} + + resip::Fifo<Event> &getFifo() {return mFifo;} + + private: + NodeId mNodeId; + unsigned short mApplication; + resip::Fifo<Event> &mFifo; + + // This is descriptor for now; it changes to something else + // when we add ICE + resip::Socket mDescriptor; +}; +std::ostream& operator<<( std::ostream& strm, const FlowId& node ); + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/ForwardingLayer.cxx b/src/libs/resiprocate/p2p/ForwardingLayer.cxx new file mode 100644 index 00000000..39200d23 --- /dev/null +++ b/src/libs/resiprocate/p2p/ForwardingLayer.cxx @@ -0,0 +1,213 @@ +#include "p2p/ForwardingLayer.hxx" +#include "p2p/Dispatcher.hxx" +#include "p2p/P2PSubsystem.hxx" + +namespace p2p +{ + +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P + +void +ForwardingLayer::process(int ms) +{ + Event *event = mRxFifo.getNext(ms); + if (event) + { + DebugLog(<< "ForwardingLayer received:" << event->brief()); + + event->dispatch(*this); + } +} + + +void +ForwardingLayer::forward( std::auto_ptr<Message> m ) +{ + // get the destination node from m + DebugLog(<< "ForwardingLayer: message arrived"); + + redo: + DestinationId did = m->nextDestination(); + + if (did.isCompressedId()) + { + assert(0); + } + else if (did.isNodeId()) + { + DebugLog(<< "ForwardingLayer: this is a node-id"); + + if (did == mProfile.nodeId()) // this is me + { + DebugLog(<< "ForwardingLayer: addressed to me"); + + m->popNextDestinationId(); + if (!m->isDestinationListEmpty()) + { + DebugLog(<< "ForwardingLayer: more entries on destination list. Reentering forwarding loop"); + goto redo; + } + else + { + DebugLog(<< "ForwardingLayer: no more entries on destination list. Posting."); + mDispatcher.post(m); + } + } + else // not me + { + DebugLog(<< "ForwardingLayer: not addressed to me"); + + if (mTopology.isConnected(did.asNodeId())) + { + DebugLog(<< "ForwardingLayer: forwarding to directly connected node"); + + mTransporter.send(did.asNodeId(), m); + } + else if(mTopology.isResponsible(did.asNodeId())) + { + // We own this section of space so we'd know about this node if + // it existed + DebugLog(<< "ForwardingLayer: dropping packet"); + } + else + { + // We're not responsible, try to route to someone who is + DebugLog(<< "ForwardingLayer: routing to next hop"); + + mTransporter.send(mTopology.findNextHop(did), m); + } + } + } + else // resourceID + { + assert (did.isResourceId()); + + DebugLog(<< "ForwardingLayer: destination is resource-id"); + + if(mTopology.isResponsible(did.asResourceId())) + { + m->popNextDestinationId(); + if (m->isDestinationListEmpty()) + { + DebugLog(<< "ForwardingLayer: delivering"); + + mDispatcher.post(m); + } + else + { + DebugLog(<< "ForwardingLayer: discarding illegal destination list (resource-id at nonterminal position)"); + + // drop on the floor + } + } + else + { + // Not responsible so try to route + DebugLog(<< "ForwardingLayer: routing to next hop"); + + mTransporter.send(mTopology.findNextHop(did.asResourceId()), m); + } + } +} + + +void +ForwardingLayer::consume(ConnectionOpened& m) +{ + DebugLog(<< "ForwardingLayer: new connection formed"); + + if(m.getApplication() == RELOAD_APPLICATION_ID) + { + mTopology.newConnectionFormed(m.getNodeId(), m.isInbound()); + } + else + { + // TODO - notify application that new connection is formed + } +} + +void +ForwardingLayer::consume(ConnectionClosed& m) +{ + DebugLog(<< "ForwardingLayer: connection closed"); + + if(m.getApplicationId() == RELOAD_APPLICATION_ID) + { + mTopology.connectionLost(m.getNodeId()); + } + else + { + // TODO - notify application that connection is closed + } +} + +void +ForwardingLayer::consume(MessageArrived& m) +{ + DebugLog(<< "ForwardingLayer: message arrived"); + + forward(m.getMessage()); +} + +void +ForwardingLayer::consume(ApplicationMessageArrived& m) +{ + // do nothing for now +} + +void +ForwardingLayer::consume(LocalCandidatesCollected& m) +{ + // pass to the TopologyAPI + if(m.getAppId() == RELOAD_APPLICATION_ID) + { + mTopology.candidatesCollected(m.getTransactionId(), + m.getNodeId(), m.getAppId(), m.getCandidates()); + } + else + { + // TODO - notify application that candidates are collected + } +} + +void +ForwardingLayer::post(std::auto_ptr<Event> event) +{ + event->dispatch(*this); +} + +} + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/ForwardingLayer.hxx b/src/libs/resiprocate/p2p/ForwardingLayer.hxx new file mode 100644 index 00000000..4f8ca670 --- /dev/null +++ b/src/libs/resiprocate/p2p/ForwardingLayer.hxx @@ -0,0 +1,101 @@ +#ifndef __P2P_FORWARDINGLAYER_HXX +#define __P2P_FORWARDINGLAYER_HXX 1 + +#include "rutil/Data.hxx" +#include "rutil/Fifo.hxx" + +#include "p2p/NodeId.hxx" +#include "p2p/ResourceId.hxx" +#include "p2p/Message.hxx" +#include "p2p/Transporter.hxx" +#include "p2p/TransporterMessage.hxx" +#include "p2p/TopologyAPI.hxx" +#include "p2p/Message.hxx" + +namespace p2p +{ +class Dispatcher; +class TransporterMessage; + +class ForwardingLayer: public EventConsumer +{ + public: + ForwardingLayer(const Profile& profile, + Dispatcher& dispatcher, + Transporter& transporter, + TopologyAPI& topology) + : mProfile(profile), + mDispatcher(dispatcher), + mTransporter(transporter), + mTopology(topology) + { + mTransporter.setRxFifo(&mRxFifo); + } + + void process(int ms); + + // all the consumes methods are for messages coming up from transports to this + virtual void consume(ConnectionOpened& m); + virtual void consume(ConnectionClosed& m); + virtual void consume(MessageArrived& m); + virtual void consume(ApplicationMessageArrived& m); + virtual void consume(LocalCandidatesCollected& m); + + // from messages from above or below that need to be forwarded + void forward( std::auto_ptr<Message> m ); + + //not public api + virtual void post(std::auto_ptr<Event> event); + + virtual resip::Data brief() const + { + return "ForwardingLayer"; + } + + + private: + const Profile& mProfile; + Dispatcher& mDispatcher; + Transporter& mTransporter; + TopologyAPI& mTopology; + + resip::Fifo<Event> mRxFifo; +}; + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/Join.cxx b/src/libs/resiprocate/p2p/Join.cxx new file mode 100644 index 00000000..d5353172 --- /dev/null +++ b/src/libs/resiprocate/p2p/Join.cxx @@ -0,0 +1,95 @@ +#include "p2p/Join.hxx" + +using namespace p2p; + +JoinAns::JoinAns() +{ + +} + +JoinAns::JoinAns(p2p::JoinReq *request, const resip::Data &overlaySpecific) +{ + mOverlaySpecificData = overlaySpecific; + + copyForwardingData(*request); +} + +void +JoinAns::getEncodedPayload(resip::DataStream &strm) +{ + encode(strm); +} + +void +JoinAns::decodePayload(resip::DataStream &strm) +{ + decode(strm); +} + +JoinReq::JoinReq() +{ + +} + +JoinReq::JoinReq(const DestinationId &dest, const NodeId &node, const resip::Data &overlaySpecific) : + mNodeId(node) +{ + mJoiningPeerId = new s2c::NodeIdStruct; + *mJoiningPeerId = node.getNodeIdStruct(); + + mOverlaySpecificData = overlaySpecific; +} + +NodeId +JoinReq::getNodeId() const +{ + return NodeId(*mJoiningPeerId); +} + + +void +JoinReq::getEncodedPayload(resip::DataStream &strm) +{ + encode(strm); +} + +void +JoinReq::decodePayload(resip::DataStream &strm) +{ + decode(strm); +} + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + diff --git a/src/libs/resiprocate/p2p/Join.hxx b/src/libs/resiprocate/p2p/Join.hxx new file mode 100644 index 00000000..79ed55d9 --- /dev/null +++ b/src/libs/resiprocate/p2p/Join.hxx @@ -0,0 +1,90 @@ +#if !defined(P2P_JOIN_HXX) +#define P2P_JOIN_HXX + +#include "p2p/Message.hxx" +#include "p2p/EventWrapper.hxx" + +namespace p2p +{ + +class JoinReq; + +class JoinAns : public Message, private s2c::JoinAnsStruct +{ +public: + friend class Message; + + JoinAns(p2p::JoinReq *request, const resip::Data &overlaySpecific = resip::Data::Empty); + virtual MessageType getType() const { return Message::JoinAnsType; } + + virtual void getEncodedPayload(resip::DataStream &data); + virtual resip::Data brief() const { return "JoinAns Message"; } + + std::auto_ptr<Event> event() {return wrap(this);} + +protected: + virtual void decodePayload(resip::DataStream &dataStream); + JoinAns(); +}; + +class JoinReq : public Message, private s2c::JoinReqStruct +{ +public: + JoinReq(const DestinationId &dest, const NodeId &nodeId, const resip::Data &overlaySpecific=resip::Data::Empty); + + virtual MessageType getType() const { return Message::JoinReqType; } + NodeId getNodeId() const; + + virtual void getEncodedPayload(resip::DataStream &data); + virtual resip::Data brief() const { return "JoinReq Message"; } + + std::auto_ptr<Event> event() {return wrap(this);} + +protected: + virtual void decodePayload(resip::DataStream &dataStream); + JoinReq(); + + NodeId mNodeId; + resip::Data mOverlaySpecific; + + friend class Message; +}; + + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/Leave.cxx b/src/libs/resiprocate/p2p/Leave.cxx new file mode 100644 index 00000000..4ae49b05 --- /dev/null +++ b/src/libs/resiprocate/p2p/Leave.cxx @@ -0,0 +1,48 @@ +#include "p2p/Leave.hxx" + +using namespace p2p; + +LeaveAns::LeaveAns() +{ +} + +LeaveAns::LeaveAns(LeaveReq *request) +{ + copyForwardingData(*request); +} + +void +LeaveAns::getEncodedPayload(resip::DataStream &data) +{ + assert(0); +} + +void +LeaveAns::decodePayload(resip::DataStream &dataStream) +{ + +} + +LeaveReq::LeaveReq() +{ +} + +void +LeaveReq::getEncodedPayload(resip::DataStream &data) +{ + assert(0); +} + +LeaveReq::LeaveReq(const DestinationId &dest, NodeId node) : + mNode(node) +{ + +} + +void +LeaveReq::decodePayload(resip::DataStream &dataStream) +{ + +} + + diff --git a/src/libs/resiprocate/p2p/Leave.hxx b/src/libs/resiprocate/p2p/Leave.hxx new file mode 100644 index 00000000..57b1d28a --- /dev/null +++ b/src/libs/resiprocate/p2p/Leave.hxx @@ -0,0 +1,54 @@ +#ifndef P2P_Leave_hxx +#define P2P_Leave_hxx + +#include "p2p/Message.hxx" +#include "p2p/EventWrapper.hxx" + +namespace p2p +{ + +class LeaveReq; + +class LeaveAns: public Message, private s2c::LeaveReqStruct +{ +public: + friend class Message; + + LeaveAns(p2p::LeaveReq *request); + + virtual MessageType getType() const { return Message::LeaveAnsType; } + virtual void getEncodedPayload(resip::DataStream &data); + virtual resip::Data brief() const { return "LeaveAns Message"; } + + std::auto_ptr<Event> event() {return wrap(this);} + + +protected: + virtual void decodePayload(resip::DataStream &dataStream); + LeaveAns(); +}; + + +class LeaveReq : public Message +{ +public: + friend class Message; + + LeaveReq(const DestinationId &dest, NodeId node); + + virtual MessageType getType() const { return Message::LeaveReqType; } + virtual void getEncodedPayload(resip::DataStream &data); + virtual resip::Data brief() const { return "LeaveReq Message"; } + + std::auto_ptr<Event> event() {return wrap(this);} + +protected: + virtual void decodePayload(resip::DataStream &dataStream); + LeaveReq(); + + NodeId mNode; +}; + +} + +#endif diff --git a/src/libs/resiprocate/p2p/Makefile b/src/libs/resiprocate/p2p/Makefile new file mode 100644 index 00000000..dabd699c --- /dev/null +++ b/src/libs/resiprocate/p2p/Makefile @@ -0,0 +1,79 @@ +# $Id: Makefile,v 1.9 2004/05/10 01:12:46 jason Exp $ + +BUILD = ../build +include $(BUILD)/Makefile.pre + +CXXFLAGS += -I.. -I./s2c + +PACKAGES += RUTIL OPENSSL PTHREAD S2C + +CODE_SUBDIRS := + +TARGET_LIBRARY := libp2p + +TESTPROGRAMS := ParsingTest.cxx + +SRC += \ + ChordTopology.cxx \ + ChordUpdate.cxx \ + Connect.cxx \ + ConnectBase.cxx \ + DestinationId.cxx \ + Dispatcher.cxx \ + Find.cxx \ + FlowId.cxx \ + ForwardingLayer.cxx \ + Join.cxx \ + Leave.cxx \ + Message.cxx \ + MessageHelper.cxx \ + MessageStructsGen.cxx \ + NodeId.cxx \ + P2PStack.cxx \ + P2PSubsystem.cxx \ + ResourceId.cxx \ + SelectTransporter.cxx \ + Signable.cxx \ + SignatureContext.cxx \ + TestMake.cxx \ + TopologyAPI.cxx \ + Transporter.cxx \ + TransporterMessage.cxx \ + Update.cxx \ + BatchMessages.cxx \ + +include $(BUILD)/Makefile.post + +#====================================================================== +# Copyright (c) 2008, Various contributors to the Resiprocate project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# - The names of the project's contributors may not be used to +# endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +#====================================================================== diff --git a/src/libs/resiprocate/p2p/Message.cxx b/src/libs/resiprocate/p2p/Message.cxx new file mode 100644 index 00000000..dee06dab --- /dev/null +++ b/src/libs/resiprocate/p2p/Message.cxx @@ -0,0 +1,501 @@ +#include "p2p/Message.hxx" +#include "p2p/Join.hxx" +#include "p2p/Update.hxx" +#include "p2p/Connect.hxx" +#include "p2p/Leave.hxx" +#include "p2p/Event.hxx" +#include "p2p/DestinationId.hxx" + +#include "rutil/ssl/SHA1Stream.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Log.hxx" + +#include <openssl/rand.h> +#include <assert.h> + +using namespace p2p; +using namespace s2c; +using namespace resip; + +const UInt8 Message::MessageVersion = 0x1; +const UInt8 Message::MessageTtl = 0x20; +const UInt32 Message::MessageReloToken=0xd2454c4f; + +#include "p2p/P2PSubsystem.hxx" +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P + + +Message::Message(ResourceId rid) : + mResourceId(rid) +{ + // not really sure what this ctor does it + initForwardingData(); +} + +Message::Message() +{ + initForwardingData(); +} + +Message::Message(const DestinationId &dest) +{ + // this is the constructor for requests + initForwardingData(); + + // add to the destination list here +} + +void +Message::dump() const +{ + DebugLog(<< "type: " << mPDU.mHeader->mMessageCode << ", txid: " << mPDU.mHeader->mTransactionId); +} + +NodeId +Message::getResponseNodeId() const +{ + // todo grab from via + NodeId n; + return n; +} + +bool +Message::compareDestinationLists(const std::vector<DestinationStruct *> &l1, const std::vector<DestinationStruct *> &l2) const +{ + std::vector<DestinationStruct*>::const_iterator iter1 = l1.begin(); + std::vector<DestinationStruct*>::const_iterator iter2 = l2.begin(); + + bool isOk = true; + while (iter1 != l1.end() && iter2 != l2.end() && isOk) + { + DestinationId id1(**iter1); + DestinationId id2(**iter2); + + isOk = isOk && (id1 == id2); + + ++iter1; + ++iter2; + } + + return isOk; +} + +bool +Message::operator==(const Message& msg) const +{ + DebugLog(<< "txid1: " << mPDU.mHeader->mTransactionId << ", txid2: " << msg.mPDU.mHeader->mTransactionId); + + bool headerPayloadOk = + (mPDU.mHeader->mReloToken == msg.mPDU.mHeader->mReloToken) && + (mPDU.mHeader->mOverlay == msg.mPDU.mHeader->mOverlay) && + (mPDU.mHeader->mTtl == msg.mPDU.mHeader->mTtl) && + (mPDU.mHeader->mReserved == msg.mPDU.mHeader->mReserved) && + (mPDU.mHeader->mFragment == msg.mPDU.mHeader->mFragment) && +// (mPDU.mHeader->mLength == msg.mPDU.mHeader->mLength); && + (mPDU.mHeader->mTransactionId == msg.mPDU.mHeader->mTransactionId) && + (mPDU.mHeader->mFlags == msg.mPDU.mHeader->mFlags) && + (mPDU.mHeader->mRouteLogLenDummy == msg.mPDU.mHeader->mRouteLogLenDummy) && + (getType() == msg.getType()) && + (mPDU.mHeader->mViaList.size() == msg.mPDU.mHeader->mViaList.size()) && + (mPDU.mHeader->mDestinationList.size() == msg.mPDU.mHeader->mDestinationList.size()) && + (mPDU.mPayload == msg.mPDU.mPayload); + + DebugLog(<< "operator state " << headerPayloadOk); + + // check Vias + if (headerPayloadOk) + { + headerPayloadOk = (headerPayloadOk && compareDestinationLists(mPDU.mHeader->mDestinationList, msg.mPDU.mHeader->mDestinationList)); + } + + DebugLog(<< "operator state 2 " << headerPayloadOk); + + if (headerPayloadOk) + { + headerPayloadOk = (headerPayloadOk && compareDestinationLists(mPDU.mHeader->mViaList, msg.mPDU.mHeader->mViaList)); + } + + DebugLog(<< "operator state 3 " << headerPayloadOk); + + // check sig + return headerPayloadOk; +} + + +void +Message::initForwardingData() +{ + mPDU.mHeader = new ForwardingHeaderStruct(); + mPDU.mHeader->mVersion = MessageVersion; // set by the draft + + // Random transaction ID + RAND_bytes((unsigned char *)&mPDU.mHeader->mTransactionId,4); + + mPDU.mHeader->mTtl = Message::MessageTtl; + + // remove me + setOverlayName("test"); +} + +Message::~Message() +{ + +} + +void +Message::setOverlayName(const resip::Data &overlayName) +{ + mOverlayName = overlayName; + + // create the overlay field from the overlay name + resip::SHA1Stream stream; + stream << mOverlayName; + mPDU.mHeader->mOverlay = stream.getUInt32(); +} + +Message * +Message::makeErrorResponse(Message::Error::Code code, const resip::Data& reason) const +{ + assert(0); + return 0; +} + +resip::Data +Message::getRequestMessageBody() const +{ + assert(isRequest()); + + return mRequestMessageBody; +} + +bool +Message::isRequest() const +{ + unsigned int reqValue = static_cast<unsigned int>(getType()); + return ((reqValue % 2) == 1); +} + +Message * +Message::parse(const resip::Data &message) +{ + Message *newMessage = 0; + + resip::Data copyData = message; + resip::DataStream stream(copyData); + + ForwardingHeaderStruct header; + header.decode(stream); + + // figure out what type of message this is + Message::MessageType messageType = static_cast<Message::MessageType>(header.mMessageCode); + DebugLog(<< "Transaction ID =" << std::hex << header.mTransactionId << "TTL=" << + std::hex << (int)header.mTtl); + + // parse the forwarding header + + switch(messageType) + { + case UpdateReqType: + DebugLog(<< "UpdateReqType message received"); + newMessage = new UpdateReq(); + break; + case UpdateAnsType: + DebugLog(<< "UpdateAnsType message received"); + newMessage = new UpdateAns(); + break; + case JoinReqType: + DebugLog(<< "JoinReqType message received"); + newMessage = new JoinReq(); + break; + case JoinAnsType: + DebugLog(<< "JoinAns message received"); + newMessage = new JoinAns(); + break; + case LeaveReqType: + DebugLog(<< "LeaveReq message received"); + newMessage = new LeaveReq(); + break; + case LeaveAnsType: + DebugLog(<< "LeaveAns message received"); + newMessage = new LeaveAns(); + break; + case ConnectReqType: + DebugLog(<< "ConnectReq message received"); + newMessage = new ConnectReq(); + break; + case ConnectAnsType: + DebugLog(<< "ConnectAns message received"); + newMessage = new ConnectAns(); + break; + default: + DebugLog(<< "Unhandled message"); + assert(0); // unknown value + } + + // let's decode the payload + MessagePayloadStruct payloadStruct; + payloadStruct.decode(stream); + newMessage->mRequestMessageBody = payloadStruct.mPayload; + *newMessage->mPDU.mHeader = header; + + DebugLog(<< "Message Body Payload Size Is " << newMessage->mRequestMessageBody.size()); + resip::DataStream payloadStream( newMessage->mRequestMessageBody ); + + // get the signature + SignatureStruct signature; + signature.decode(stream); + + // todo: verify the signature here + newMessage->decodePayload(payloadStream); + + return newMessage; +} + +void +Message::copyForwardingData(const Message &header) +{ + assert(header.isRequest()); + mPDU.mHeader->mOverlay = header.mPDU.mHeader->mOverlay; + mPDU.mHeader->mTransactionId = header.mPDU.mHeader->mTransactionId; + + assert(mPDU.mHeader->mDestinationList.empty()); + std::vector<DestinationStruct*>::reverse_iterator i; + for (i=header.mPDU.mHeader->mViaList.rbegin(); i!=header.mPDU.mHeader->mViaList.rend(); ++i) + { + DestinationStruct* ds = new DestinationStruct(**i); + mPDU.mHeader->mDestinationList.push_back(ds); + } +} + +void +Message::decrementTTL() +{ + assert(mPDU.mHeader->mTtl); + mPDU.mHeader->mTtl--; +} + +UInt8 +Message::getTTL() const +{ + return mPDU.mHeader->mTtl; +} + +void +Message::setTTL(UInt8 ttl) +{ + mPDU.mHeader->mTtl = ttl; +} + +UInt32 +Message::getOverlay() const +{ + return mPDU.mHeader->mOverlay; +} + +UInt64 +Message::getTransactionId() const +{ + return mPDU.mHeader->mTransactionId; +} + +UInt16 +Message::getFlags() const +{ + return mPDU.mHeader->mFlags; +} + +ConnectAns * +Message::makeConnectResponse(const resip::Data &frag, const resip::Data &password, UInt16 application, const resip::Data &role, const std::vector<Candidate> &candidates) +{ + assert(getType() == ConnectReqType); + + ConnectReq *req = static_cast<ConnectReq *>(this); + ConnectAns *response = new ConnectAns(req, frag, password, application, role, candidates); + + return response; +} + + +JoinAns * +Message::makeJoinResponse(const resip::Data &overlaySpecific) +{ + assert(getType() == JoinReqType); + + JoinReq *req = static_cast<JoinReq *>(this); + JoinAns *response = new JoinAns(req, overlaySpecific); + + return response; +} + +LeaveAns * +Message::makeLeaveResponse() +{ + assert(getType() == LeaveReqType); + + LeaveReq *req = static_cast<LeaveReq *>(this); + return new LeaveAns(req); +} + +UpdateAns * +Message::makeUpdateResponse(const resip::Data &overlaySpecific) +{ + assert(getType() == UpdateReqType); + + UpdateReq *req = static_cast<UpdateReq *>(this); + UpdateAns *response = new UpdateAns(req,overlaySpecific); + + return response; +} + +resip::Data +Message::encodePayload() +{ + + assert(mOverlayName.size()); // user needs to call setOverlayName + + // create the overlay field from the overlay name + resip::SHA1Stream stream; + stream << mOverlayName; + mPDU.mHeader->mReloToken=Message::MessageReloToken; + mPDU.mHeader->mMessageCode = static_cast<UInt16>(getType()); + mPDU.mHeader->mOverlay = stream.getUInt32(); + + // TODO: Set flag to something goofy + mPDU.mHeader->mFlags = 0xfeeb; + + resip::Data encodedData; + resip::DataStream encodedStream(encodedData); + + int fff=encodedStream.tellp(); + std::cerr << fff; + + // encode forwarding header + mPDU.mHeader->encode(encodedStream); + + encodedStream.flush(); + size_t startOfPayload = encodedData.size(); + + // encode specific message payload + MessagePayloadStruct msgPayload; + { + resip::DataStream payloadStream(msgPayload.mPayload); + getEncodedPayload(payloadStream); + } + + msgPayload.encode(encodedStream); + + encodedStream.flush(); + size_t endOfPayload = encodedData.size(); + + DebugLog(<< "Encoded Payload Size Is: " << (endOfPayload - startOfPayload)); + + + // compute signature block + std::vector<resip::Data> sigChunks; + sigChunks.push_back(resip::Data(resip::Data::Borrow, encodedData.data() + 4, 4)); // overlay + sigChunks.push_back(resip::Data(resip::Data::Borrow, encodedData.data() + 16, 8)); // transaction id + sigChunks.push_back(resip::Data(resip::Data::Borrow, encodedData.data() + startOfPayload, endOfPayload - startOfPayload)); // transaction id + + s2c::SignatureStruct *sigBlock = sign(sigChunks); + mPDU.mSig = sigBlock; + + mPDU.mSig->encode(encodedStream); + encodedStream.flush(); + + size_t finalLength = encodedData.size(); + + // add the length to the header + assert(mPDU.mHeader->mVersion); + UInt32 *lengthWord = reinterpret_cast<UInt32 *>(const_cast<char *>(encodedData.data()) + 13); + + (*lengthWord) = (*lengthWord | (htonl(finalLength & 0x0fff) >> 8)); + + // we should optimize this eventually to avoid this copy + return encodedData; +} + +std::vector<resip::Data> +Message::collectSignableData() const +{ + assert(0); + std::vector<resip::Data> list; + return list; +} + +bool +Message::isDestinationListEmpty() const +{ + return mPDU.mHeader->mDestinationList.empty(); +} + +DestinationId +Message::nextDestination() const +{ + assert(!isDestinationListEmpty()); + return DestinationId(*mPDU.mHeader->mDestinationList.front()); +} + +void +Message::popNextDestinationId() +{ + assert(!isDestinationListEmpty()); + mPDU.mHeader->mDestinationList.erase(mPDU.mHeader->mDestinationList.begin()); +} + +std::auto_ptr<Event> +Message::event() +{ + assert(0); + return std::auto_ptr<Event>(0); +} + +void +Message::pushVia(const DestinationId& did) +{ + assert(!did.isResourceId()); + mPDU.mHeader->mViaList.push_back(did.copyDestinationStruct()); +} + +void +Message::pushDestinationId(const DestinationId& did) +{ + mPDU.mHeader->mDestinationList.push_back(did.copyDestinationStruct()); +} + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + + + diff --git a/src/libs/resiprocate/p2p/Message.hxx b/src/libs/resiprocate/p2p/Message.hxx new file mode 100644 index 00000000..074c3907 --- /dev/null +++ b/src/libs/resiprocate/p2p/Message.hxx @@ -0,0 +1,279 @@ +#ifndef __P2P_Message_hxx +#define __P2P_Message_hxx + +#include <cassert> +#include <memory> +#include "rutil/Data.hxx" + +#include "p2p/Event.hxx" +#include "p2p/Signable.hxx" +#include "p2p/ResourceId.hxx" +#include "p2p/NodeId.hxx" +#include "p2p/DestinationId.hxx" +#include "p2p/MessageStructsGen.hxx" +#include "p2p/Candidate.hxx" + +namespace p2p +{ + +class MessageContents; +class ErrorResponse; +class Event; + + +class JoinAns; +class UpdateAns; +class LeaveAns; +class ConnectAns; + +class Message : public Signable +{ + public: + // Used to make a request. Will populate the rid into the destination list. + Message(ResourceId rid); + + virtual ~Message() = 0; + + enum MessageType + { + PingReqType = 1, + PingAnsType = 2, + ConnectReqType = 3, // + ConnectAnsType = 4, // + TunnelReqType = 5, + TunnelAnsType = 6, + StoreReqType = 7, // + StoreAnsType = 8, // + FetchReqType = 9, // + FetchAnsType = 10, // + RemoveReqType = 11, + RemoveAnsType = 12, + FindReqType = 13, + FindAnsType = 14, + JoinReqType = 15, // + JoinAnsType = 16, // + LeaveReqType = 17, + LeaveAnsType = 18, + UpdateReqType = 19, // + UpdateAnsType = 20, // + RouteQueryReqType = 21, + RouteQueryAnsType = 22, + FailureRequestType = 0xFFFE, + FailureResponseType = 0xFFFF + }; + + static const UInt8 MessageVersion; + static const UInt8 MessageTtl; + static const UInt32 MessageReloToken; + + + void setOverlayName(const resip::Data &overlayName); + + struct Error + { + enum Code + { + MovedTemporarily = 302, + Unauthorized = 401, + Forbidden = 403, + NotFound = 404, + RequestTimeout = 408, + PreconditionFailed = 412, + IncompatibleWithOverlay = 498 + }; + }; + + bool isRequest() const; // convenience function + + virtual MessageType getType() const = 0; + + // copies via list to dest. list in reverse order + virtual Message *makeErrorResponse(Error::Code code, + const resip::Data& reason) const; + + JoinAns* makeJoinResponse(const resip::Data &overlaySpecific = resip::Data::Empty); + UpdateAns* makeUpdateResponse(const resip::Data &overlaySpecific); + LeaveAns* makeLeaveResponse(); + ConnectAns* makeConnectResponse(const resip::Data &frag, const resip::Data &password, UInt16 application, const resip::Data &role, const std::vector<Candidate> &candidates); + + resip::Data getRequestMessageBody() const; + + // encoding/parsing methods + resip::Data encodePayload(); + static Message *parse(const resip::Data &message); + + // TTL + UInt8 getTTL() const; + void decrementTTL(); + void setTTL(UInt8 ttl); + + UInt32 getOverlay() const; + UInt64 getTransactionId() const; + UInt16 getFlags() const; + void pushVia(const DestinationId& node); + void pushDestinationId(const DestinationId& did); + + NodeId getResponseNodeId() const; // pull this from the via list + + // placeholder for doing via list compression + + bool isDestinationListEmpty() const; + DestinationId nextDestination() const; + void popNextDestinationId(); + + virtual std::auto_ptr<Event> event() = 0; + + virtual resip::Data brief() const =0; + + + void dump() const; + + bool operator==(const Message& msg) const; + +protected: + ResourceId mResourceId; + resip::Data mOverlayName; + resip::Data mEncodedData; + resip::Data mRequestMessageBody; + + s2c::ForwardingLayerMessageStruct mPDU; + + // these have to be defined in the subclasses to encode and decode their message bodies + virtual void getEncodedPayload(resip::DataStream &dataStream) = 0; + virtual void decodePayload(resip::DataStream &dataStream) = 0; + + virtual std::vector<resip::Data> collectSignableData() const; + + Message(); + Message(const DestinationId &dest); + void copyForwardingData(const Message &header); + + private: + void initForwardingData(); + bool compareDestinationLists(const std::vector<s2c::DestinationStruct *> &l1, const std::vector<s2c::DestinationStruct *> &l2) const; + +}; + +class MessageContents +{ + public: +}; + +class ErrorResponse : public Message +{ + public: + virtual MessageType getType() const { return FailureResponseType; } + + Error::Code getErrorCode() const; + const resip::Data& getReasonPhrase() const; + + protected: + virtual std::vector<resip::Data> collectSignableData() const; +}; + +class RouteQueryAns : public Message +{ + public: + virtual MessageType getType() const { return RouteQueryAnsType; } +}; + +class RouteQueryReq : public Message +{ + public: + virtual MessageType getType() const { return RouteQueryReqType; } +}; + +class RemoveAns : public Message +{ + public: + virtual MessageType getType() const { return RemoveAnsType; } +}; + + +class RemoveReq : public Message +{ + public: + virtual MessageType getType() const { return RemoveReqType; } +}; + + +class TunnelAns : public Message +{ + public: + virtual MessageType getType() const { return TunnelAnsType; } +}; + + +class TunnelReq : public Message +{ + public: + virtual MessageType getType() const { return TunnelReqType; } +}; + +class PingAns : public Message +{ + public: + virtual MessageType getType() const { return PingAnsType; } +}; + + +class PingReq : public Message +{ + public: + virtual MessageType getType() const { return PingReqType; } +}; + +class ResourceMessage : public Message +{ + public: + resip::Data& getResourceId(); + const resip::Data& getResourceId() const; + void setResourceId(const resip::Data& resourceId); + + resip::Data& getResourceName(); + const resip::Data& getResourceName() const; + void setResourceName(const resip::Data& resorceName); + + private: + resip::Data mResourceId; + resip::Data mResourceName; +}; + +} + +#endif + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/MessageHelper.cxx b/src/libs/resiprocate/p2p/MessageHelper.cxx new file mode 100644 index 00000000..67007a66 --- /dev/null +++ b/src/libs/resiprocate/p2p/MessageHelper.cxx @@ -0,0 +1,22 @@ +#include "p2p/MessageHelper.hxx" +#include <vector> + +using namespace p2p; + +std::vector<unsigned char> +MessageHelper::convert(const resip::Data &data) +{ + std::vector<unsigned char> byteData; + byteData.resize(data.size()); + std::copy(data.begin(), data.end(), &byteData[0]); + return byteData; +} + +void +MessageHelper::convert(const resip::Data &data, std::vector<unsigned char> &output) +{ + output.clear(); + output.resize(data.size()); + std::copy(data.begin(), data.end(), &output[0]); +} + diff --git a/src/libs/resiprocate/p2p/MessageHelper.hxx b/src/libs/resiprocate/p2p/MessageHelper.hxx new file mode 100644 index 00000000..94188304 --- /dev/null +++ b/src/libs/resiprocate/p2p/MessageHelper.hxx @@ -0,0 +1,20 @@ +#ifndef P2P_MESSAGEHELPER_HXX +#define P2P_MESSAGEHELPER_HXX + +#include <vector> + +#include "rutil/Data.hxx" + +namespace p2p +{ + +class MessageHelper +{ +public: + static std::vector<unsigned char> convert(const resip::Data &data); + static void convert(const resip::Data &data, std::vector<unsigned char> &output); +}; + +} + +#endif diff --git a/src/libs/resiprocate/p2p/MessageStructs.s2c b/src/libs/resiprocate/p2p/MessageStructs.s2c new file mode 100644 index 00000000..26feec9d --- /dev/null +++ b/src/libs/resiprocate/p2p/MessageStructs.s2c @@ -0,0 +1,406 @@ + enum { bool_false (0), bool_true(1), (255)} Boolean; + + struct { + uint64 high; + uint64 low; + } NodeId; + + struct { + opaque id<0..2^8-1>; + } ResourceId; + + + enum {reserved_addr(0), ipv4_address (1), ipv6_address (2), (255)} + AddressType; + + struct { + uint32 addr; + uint16 port; + } IPv4AddrPort; + + struct { + opaque addr[16]; + uint16 port; + } IPv6AddrPort; + + + struct { + AddressType type; + uint8 length; + + select (type) { + case ipv4_address: + IPv4AddrPort v4addr_port; + + case ipv6_address: + IPv6AddrPort v6addr_port; + + /* This structure can be extended */ + } ; + } IpAddressAndPort; + + + enum {reserved_destination(0), peer(1), resource(2), compressed(3), (255) } + DestinationType; + + + struct { + DestinationType type; + uint8 length.auto_len; + + select (type) { + case peer: + NodeId node_id; + + case resource: + ResourceId resource_id; + + case compressed: + opaque compressed_id<0..2^8-1>; + + /* This structure may be extended with new types */ + + } ; + } Destination; + + enum {reserved1(0), signer_identity_peer (1), + signer_identity_name (2), signer_identity_certificate (3), + (255)} SignerIdentityType; + + struct { + SignerIdentityType identity_type; + opaque signer_identity<0..2^16-1>; + } SignerIdentity; + + struct { + uint8 sig; + uint8 hash; + } SignatureAndHashAlgorithm; + + struct { + SignatureAndHashAlgorithm algorithm; + SignerIdentity identity; + opaque signature_value<0..2^16-1>; + } Signature; + + + struct { + uint32 relo_token; + uint32 overlay; + uint8 ttl; + uint8 reserved; + uint16 fragment; + uint8 version; + uint24 length; + uint64 transaction_id; + uint16 flags; + + Destination via_list<0..2^16-1>; + Destination destination_list<0..2^16-1>; + uint16 route_log_len_dummy; + uint16 message_code; + } ForwardingHeader; + + struct { + ForwardingHeader header; + opaque payload<0..2^24-1>; + Signature sig; + } ForwardingLayerMessage; + + struct { + opaque payload<0..2^24-1>; + } MessagePayload; + + public struct { + uint16 error_code; + opaque reason_phrase<0..2^8-1>; /* String*/ + opaque error_info<0..2^16-1>; + } ErrorResponse; + + + struct { + NodeId joining_peer_id; + opaque overlay_specific_data<0..2^16-1>; + } JoinReq; + + struct { + opaque overlay_specific_data<0..2^16-1>; + } JoinAns; + + public struct { + NodeId leaving_peer_id; + opaque overlay_specific_data<0..2^16-1>; + } LeaveReq; + + struct { + Boolean send_update; + Destination destination; + opaque overlay_specific_data<0..2^16-1>; + } RouteQueryReq; + + + + enum {data (128), ack (129), (255)} FramedMessageType; + + struct { + FramedMessageType type; + + select (type) { + case data: + uint24 sequence; + opaque message<0..2^24-1>; + + case ack: + uint24 ack_sequence; + uint32 received; + }; + } FramedMessage; + + + struct { + opaque candidate<0..2^16-1>; + } IceCandidate; + + struct { + opaque ufrag<0..2^8-1>; + opaque password<0..2^8-1>; + uint16 application; + opaque role<0..2^8-1>; + IceCandidate candidates<0..2^16-1>; + } ConnectReqAns; + + + enum { responsible_set(1), num_resources(2), (255)} + PingInformationType; + + struct { + /* TODO: FIX */ + /* PingInformationType requested_info<0..2^8-1>; */ + uint8 requested_info<0..2^8-1>; + } PingReq; + + + struct { + PingInformationType type; + + select (type) { + case responsible_set: + uint32 responsible_ppb; + + case num_resources: + uint32 num_resources; + + /* This type may be extended */ + + }; + } PingInformation; + + struct { + uint64 response_id; + PingInformation ping_info<0..2^16-1>; + } PingAns; + + + + struct { + uint16 application; + opaque dialog_id<0..2^8-1>; + opaque application_pdu<0..2^24-1>; + } TunnelReq; + + + + enum { reserved_data_model(0), single_value(1), array(2), + dictionary(3), (255)} DataModel; + + struct { + Boolean exists; + opaque value<0..2^32-1>; + } DataValue; + + struct { + uint32 index; + DataValue value; + } ArrayEntry; + + + /* TODO FIXME typedef opaque DictionaryKey<0..2^16-1>; */ + struct { + opaque key<0..2^16-1>; + } DictionaryKey; + + struct { + DictionaryKey key; + DataValue value; + } DictionaryEntry; + + + struct { + DataModel model; /* TODO: Compensation for compiler?? */ + + select (model) { + case single_value: + DataValue single_value_entry; + + case array: + ArrayEntry array_entry; + + case dictionary: + DictionaryEntry dictionary_entry; + + + /* This structure may be extended */ + } ; + } StoredDataValue; + + struct { + uint32 length.auto_len; + uint64 storage_time; + uint32 lifetime; + StoredDataValue value; + Signature signature; + } StoredData; + + + struct { + KindId kind; + DataModel data_model; + uint64 generation_counter; + StoredData values<0..2^32-1>; + } StoreKindData; + + struct { + ResourceId resource; + uint8 replica_number; + StoreKindData kind_data<0..2^32-1>; + } StoreReq; + + struct { + KindId kind; + uint64 generation_counter; + NodeId replicas<0..2^16-1>; + } StoreKindResponse; + + + struct { + StoreKindResponse kind_responses<0..2^16-1>; + } StoreAns; + + struct { + uint32 first; + uint32 last; + } ArrayRange; + + struct { + KindId kind; + DataModel model; + uint64 generation; + uint16 length.auto_len; + + select (model) { + case single_value: ; /* Empty */ + + case array: + ArrayRange indices<0..2^16-1>; + + case dictionary: + DictionaryKey keys<0..2^16-1>; + + /* This structure may be extended */ + + } ; + } StoredDataSpecifier; + + struct { + ResourceId resource; + StoredDataSpecifier specifiers<0..2^16-1>; + } FetchReq; + + struct { + KindId kind; + uint64 generation; + StoredData values<0..2^32-1>; + } FetchKindResponse; + + struct { + FetchKindResponse kind_responses<0..2^32-1>; + } FetchAns; + + struct { + ResourceId resource; + StoredDataSpecifier specifiers<0..2^16-1>; + } RemoveReq; + + + struct { + StoreKindResponse kind_responses<0..2^16-1>; + } RemoveAns; + + struct { + ResourceId resource; + KindId kinds<0..2^8-1>; + } FindReq; + + struct { + KindId kind; + ResourceId closest; + } FindKindData; + + struct { + FindKindData results<0..2^16-1>; + } FindAns; + + struct { + uint8 iteration; + IpAddressAndPort server_address; + } TurnServer; + + + enum {sip_registration_uri (1), sip_registration_route (2), + (255)} SipRegistrationType; + + + struct { + SipRegistrationType type; + uint16 length.auto_len; + + select (type) { + case sip_registration_uri: + opaque uri<0..2^16-1>; + + case sip_registration_route: + opaque contact_prefs<0..2^16-1>; + Destination destination_list<0..2^16-1>; + + /* This type can be extended */ + + } ; + + } SipRegistration; + + enum { reserved_chord (0), peer_ready(1), neighbors(2), full(3), (255) } + ChordUpdateType; + + + struct { + ChordUpdateType type; + + select(type){ + case peer_ready: /* Empty */ + ; + + case neighbors: + NodeId predecessors<0..2^16-1>; + NodeId successors<0..2^16-1>; + + case full: + NodeId predecessors<0..2^16-1>; + NodeId successors<0..2^16-1>; + NodeId fingers<0..2^16-1>; + }; + } ChordUpdate; + + + struct { + NodeId next_id; + } ChordRouteQueryAns; diff --git a/src/libs/resiprocate/p2p/MessageStructsGen.cxx b/src/libs/resiprocate/p2p/MessageStructsGen.cxx new file mode 100644 index 00000000..9b87efbf --- /dev/null +++ b/src/libs/resiprocate/p2p/MessageStructsGen.cxx @@ -0,0 +1,4228 @@ +#include <iostream> +#include <iomanip> +#include "rutil/Logger.hxx" +#include "rutil/ParseException.hxx" +#include "rutil/Data.hxx" +#include "rutil/DataStream.hxx" +#include "P2PSubsystem.hxx" +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P +#include "MessageStructsGen.hxx" +#include <assert.h> + +namespace s2c { + + +/* EKR: Most unprincipled hack of the day */ +#define TELLP(a) (static_cast<resip::DataStream &>(a)).tellp() +#define SEEKP(a,b) (static_cast<resip::DataStream &>(a)).seekp(b) + + +// Classes for NodeIdStruct */ + +NodeIdStruct :: NodeIdStruct () +{ + mName = "NodeIdStruct"; + StackLog(<< "Constructing NodeIdStruct"); + mHigh=0; + + mLow=0; + +}; + +NodeIdStruct :: NodeIdStruct (const NodeIdStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "NodeIdStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void NodeIdStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "NodeId:\n"; + indent+=2; + do_indent(out, indent); + (out) << "high:" << std::hex << (unsigned long long)mHigh << "\n"; + do_indent(out, indent); + (out) << "low:" << std::hex << (unsigned long long)mLow << "\n"; +}; + +void NodeIdStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding NodeIdStruct"); + decode_uintX(in, 64, mHigh); + StackLog( << "mHigh =" << std::hex << (unsigned long long) mHigh ); + + decode_uintX(in, 64, mLow); + StackLog( << "mLow =" << std::hex << (unsigned long long) mLow ); + +}; + +void NodeIdStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding NodeIdStruct"); + StackLog( << "mHigh =" << std::hex << (unsigned long long) mHigh ); + encode_uintX(out, 64, mHigh); + + StackLog( << "mLow =" << std::hex << (unsigned long long) mLow ); + encode_uintX(out, 64, mLow); + +}; + + + +// Classes for ResourceIdStruct */ + +ResourceIdStruct :: ResourceIdStruct () +{ + mName = "ResourceIdStruct"; + StackLog(<< "Constructing ResourceIdStruct"); + +}; + +ResourceIdStruct :: ResourceIdStruct (const ResourceIdStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "ResourceIdStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void ResourceIdStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "ResourceId:\n"; + indent+=2; + out << mId.hex(); +}; + +void ResourceIdStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding ResourceIdStruct"); + { + UInt32 len; + int c; + decode_uintX(in, 8, len); + resip::DataStream strm(mId); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "id",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void ResourceIdStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding ResourceIdStruct"); + encode_uintX(out, 8, mId.size()); + out << mId; + +}; + + + +// Classes for IPv4AddrPortStruct */ + +IPv4AddrPortStruct :: IPv4AddrPortStruct () +{ + mName = "IPv4AddrPortStruct"; + StackLog(<< "Constructing IPv4AddrPortStruct"); + mAddr=0; + + mPort=0; + +}; + +IPv4AddrPortStruct :: IPv4AddrPortStruct (const IPv4AddrPortStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "IPv4AddrPortStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void IPv4AddrPortStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "IPv4AddrPort:\n"; + indent+=2; + do_indent(out, indent); + (out) << "addr:" << std::hex << (unsigned long long)mAddr << "\n"; + do_indent(out, indent); + (out) << "port:" << std::hex << (unsigned long long)mPort << "\n"; +}; + +void IPv4AddrPortStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding IPv4AddrPortStruct"); + decode_uintX(in, 32, mAddr); + StackLog( << "mAddr =" << std::hex << (unsigned long long) mAddr ); + + decode_uintX(in, 16, mPort); + StackLog( << "mPort =" << std::hex << (unsigned long long) mPort ); + +}; + +void IPv4AddrPortStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding IPv4AddrPortStruct"); + StackLog( << "mAddr =" << std::hex << (unsigned long long) mAddr ); + encode_uintX(out, 32, mAddr); + + StackLog( << "mPort =" << std::hex << (unsigned long long) mPort ); + encode_uintX(out, 16, mPort); + +}; + + + +// Classes for IPv6AddrPortStruct */ + +IPv6AddrPortStruct :: IPv6AddrPortStruct () +{ + mName = "IPv6AddrPortStruct"; + StackLog(<< "Constructing IPv6AddrPortStruct"); + for(unsigned int i=0;i<16;i++){ + mAddr[i]=0; +} + + mPort=0; + +}; + +IPv6AddrPortStruct :: IPv6AddrPortStruct (const IPv6AddrPortStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "IPv6AddrPortStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void IPv6AddrPortStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "IPv6AddrPort:\n"; + indent+=2; + for(unsigned int i=0;i<16;i++) { + do_indent(out, indent); + (out) << "opaque:" << std::hex << (unsigned long long) mAddr[i] << "\n"; + } + do_indent(out, indent); + (out) << "port:" << std::hex << (unsigned long long)mPort << "\n"; +}; + +void IPv6AddrPortStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding IPv6AddrPortStruct"); + for(unsigned int i=0;i<16;i++){ + decode_uintX(in, 8, mAddr[i]); + StackLog( << "mAddr[i] =" << std::hex << (unsigned long long) mAddr[i] ); + } + + decode_uintX(in, 16, mPort); + StackLog( << "mPort =" << std::hex << (unsigned long long) mPort ); + +}; + +void IPv6AddrPortStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding IPv6AddrPortStruct"); + for(unsigned int i=0;i<16;i++){ + StackLog( << "mAddr[i] =" << std::hex << (unsigned long long) mAddr[i] ); + encode_uintX(out, 8, mAddr[i]); + } + + StackLog( << "mPort =" << std::hex << (unsigned long long) mPort ); + encode_uintX(out, 16, mPort); + +}; + + + +// Classes for IpAddressAndPortStruct */ + +IpAddressAndPortStruct :: IpAddressAndPortStruct () +{ + mName = "IpAddressAndPortStruct"; + StackLog(<< "Constructing IpAddressAndPortStruct"); + mType=(AddressType)0; + + mLength=0; + + mIpv4Address.mV4addrPort=0; + mIpv6Address.mV6addrPort=0; + +}; + +IpAddressAndPortStruct :: IpAddressAndPortStruct (const IpAddressAndPortStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "IpAddressAndPortStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void IpAddressAndPortStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "IpAddressAndPort:\n"; + indent+=2; + do_indent(out, indent); + (out) << "type:" << std::hex << (unsigned long long) mType << "\n"; + do_indent(out, indent); + (out) << "length:" << std::hex << (unsigned long long)mLength << "\n"; +}; + +void IpAddressAndPortStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding IpAddressAndPortStruct"); + { + u_int32 v; + decode_uintX(in, 8, v); + mType=(AddressType)v; + } + + decode_uintX(in, 8, mLength); + StackLog( << "mLength =" << std::hex << (unsigned long long) mLength ); + + switch(mType){ + case 1: + mIpv4Address.mV4addrPort = new IPv4AddrPortStruct(); + mIpv4Address.mV4addrPort->decode(in); + break; + + case 2: + mIpv6Address.mV6addrPort = new IPv6AddrPortStruct(); + mIpv6Address.mV6addrPort->decode(in); + break; + + default: /* User error */ + assert(1==0); + } + + +}; + +void IpAddressAndPortStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding IpAddressAndPortStruct"); + encode_uintX(out, 8, (u_int64)(mType)); + + StackLog( << "mLength =" << std::hex << (unsigned long long) mLength ); + encode_uintX(out, 8, mLength); + + switch(mType) { + case 1: + mIpv4Address.mV4addrPort->encode(out); + break; + + case 2: + mIpv6Address.mV6addrPort->encode(out); + break; + + default: /* User error */ + assert(1==0); + } + + +}; + + + +// Classes for DestinationStruct */ + +DestinationStruct :: DestinationStruct () +{ + mName = "DestinationStruct"; + StackLog(<< "Constructing DestinationStruct"); + mType=(DestinationType)0; + + + mPeer.mNodeId=0; + mResource.mResourceId=0; + +}; + +DestinationStruct :: DestinationStruct (const DestinationStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "DestinationStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void DestinationStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "Destination:\n"; + indent+=2; + do_indent(out, indent); + (out) << "type:" << std::hex << (unsigned long long) mType << "\n"; +}; + +void DestinationStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding DestinationStruct"); + { + u_int32 v; + decode_uintX(in, 8, v); + mType=(DestinationType)v; + } + + { + resip::Data d; + read_varray1(in, 1, d); + resip::DataStream in_auto(d); + + switch(mType){ + case 1: + mPeer.mNodeId = new NodeIdStruct(); + mPeer.mNodeId->decode(in_auto); + break; + + case 2: + mResource.mResourceId = new ResourceIdStruct(); + mResource.mResourceId->decode(in_auto); + break; + + case 3: + { + UInt32 len; + int c; + decode_uintX(in_auto, 8, len); + resip::DataStream strm(mCompressed.mCompressedId); + while(len--){ + c=in_auto.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "compressed_id",__FILE__,__LINE__); + strm.put(c); + }; + } + break; + + default: /* User error */ + assert(1==0); + } + + + if(in_auto.peek()!=EOF) + throw resip::ParseException("Inner encoded value too long", + "Destination",__FILE__,__LINE__); + } +}; + +void DestinationStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding DestinationStruct"); + encode_uintX(out, 8, (u_int64)(mType)); + + long pos1=TELLP(out); + for(int i=0;i<1;i++) out.put(0); + + switch(mType) { + case 1: + mPeer.mNodeId->encode(out); + break; + + case 2: + mResource.mResourceId->encode(out); + break; + + case 3: + encode_uintX(out, 8, mCompressed.mCompressedId.size()); + out << mCompressed.mCompressedId; + break; + + default: /* User error */ + assert(1==0); + } + + + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 8, (pos2 - pos1) - 1); + SEEKP(out,pos2); +}; + + + +// Classes for SignerIdentityStruct */ + +SignerIdentityStruct :: SignerIdentityStruct () +{ + mName = "SignerIdentityStruct"; + StackLog(<< "Constructing SignerIdentityStruct"); + mIdentityType=(SignerIdentityType)0; + + +}; + +SignerIdentityStruct :: SignerIdentityStruct (const SignerIdentityStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "SignerIdentityStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void SignerIdentityStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "SignerIdentity:\n"; + indent+=2; + do_indent(out, indent); + (out) << "identity_type:" << std::hex << (unsigned long long) mIdentityType << "\n"; + out << mSignerIdentity.hex(); +}; + +void SignerIdentityStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding SignerIdentityStruct"); + { + u_int32 v; + decode_uintX(in, 8, v); + mIdentityType=(SignerIdentityType)v; + } + + { + UInt32 len; + int c; + decode_uintX(in, 16, len); + resip::DataStream strm(mSignerIdentity); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "signer_identity",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void SignerIdentityStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding SignerIdentityStruct"); + encode_uintX(out, 8, (u_int64)(mIdentityType)); + + encode_uintX(out, 16, mSignerIdentity.size()); + out << mSignerIdentity; + +}; + + + +// Classes for SignatureAndHashAlgorithmStruct */ + +SignatureAndHashAlgorithmStruct :: SignatureAndHashAlgorithmStruct () +{ + mName = "SignatureAndHashAlgorithmStruct"; + StackLog(<< "Constructing SignatureAndHashAlgorithmStruct"); + mSig=0; + + mHash=0; + +}; + +SignatureAndHashAlgorithmStruct :: SignatureAndHashAlgorithmStruct (const SignatureAndHashAlgorithmStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "SignatureAndHashAlgorithmStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void SignatureAndHashAlgorithmStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "SignatureAndHashAlgorithm:\n"; + indent+=2; + do_indent(out, indent); + (out) << "sig:" << std::hex << (unsigned long long)mSig << "\n"; + do_indent(out, indent); + (out) << "hash:" << std::hex << (unsigned long long)mHash << "\n"; +}; + +void SignatureAndHashAlgorithmStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding SignatureAndHashAlgorithmStruct"); + decode_uintX(in, 8, mSig); + StackLog( << "mSig =" << std::hex << (unsigned long long) mSig ); + + decode_uintX(in, 8, mHash); + StackLog( << "mHash =" << std::hex << (unsigned long long) mHash ); + +}; + +void SignatureAndHashAlgorithmStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding SignatureAndHashAlgorithmStruct"); + StackLog( << "mSig =" << std::hex << (unsigned long long) mSig ); + encode_uintX(out, 8, mSig); + + StackLog( << "mHash =" << std::hex << (unsigned long long) mHash ); + encode_uintX(out, 8, mHash); + +}; + + + +// Classes for SignatureStruct */ + +SignatureStruct :: SignatureStruct () +{ + mName = "SignatureStruct"; + StackLog(<< "Constructing SignatureStruct"); + mAlgorithm=0; + + mIdentity=0; + + +}; + +SignatureStruct :: SignatureStruct (const SignatureStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "SignatureStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void SignatureStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "Signature:\n"; + indent+=2; + mAlgorithm->print(out, indent); + mIdentity->print(out, indent); + out << mSignatureValue.hex(); +}; + +void SignatureStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding SignatureStruct"); + mAlgorithm = new SignatureAndHashAlgorithmStruct(); + mAlgorithm->decode(in); + + mIdentity = new SignerIdentityStruct(); + mIdentity->decode(in); + + { + UInt32 len; + int c; + decode_uintX(in, 16, len); + resip::DataStream strm(mSignatureValue); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "signature_value",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void SignatureStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding SignatureStruct"); + mAlgorithm->encode(out); + + mIdentity->encode(out); + + encode_uintX(out, 16, mSignatureValue.size()); + out << mSignatureValue; + +}; + + + +// Classes for ForwardingHeaderStruct */ + +ForwardingHeaderStruct :: ForwardingHeaderStruct () +{ + mName = "ForwardingHeaderStruct"; + StackLog(<< "Constructing ForwardingHeaderStruct"); + mReloToken=0; + + mOverlay=0; + + mTtl=0; + + mReserved=0; + + mFragment=0; + + mVersion=0; + + mLength=0; + + mTransactionId=0; + + mFlags=0; + + + + mRouteLogLenDummy=0; + + mMessageCode=0; + +}; + +ForwardingHeaderStruct :: ForwardingHeaderStruct (const ForwardingHeaderStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "ForwardingHeaderStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void ForwardingHeaderStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "ForwardingHeader:\n"; + indent+=2; + do_indent(out, indent); + (out) << "relo_token:" << std::hex << (unsigned long long)mReloToken << "\n"; + do_indent(out, indent); + (out) << "overlay:" << std::hex << (unsigned long long)mOverlay << "\n"; + do_indent(out, indent); + (out) << "ttl:" << std::hex << (unsigned long long)mTtl << "\n"; + do_indent(out, indent); + (out) << "reserved:" << std::hex << (unsigned long long)mReserved << "\n"; + do_indent(out, indent); + (out) << "fragment:" << std::hex << (unsigned long long)mFragment << "\n"; + do_indent(out, indent); + (out) << "version:" << std::hex << (unsigned long long)mVersion << "\n"; + do_indent(out, indent); + (out) << "length:" << std::hex << (unsigned long long)mLength << "\n"; + do_indent(out, indent); + (out) << "transaction_id:" << std::hex << (unsigned long long)mTransactionId << "\n"; + do_indent(out, indent); + (out) << "flags:" << std::hex << (unsigned long long)mFlags << "\n"; + for(unsigned int i=0;i<mViaList.size();i++){ + mViaList[i]->print(out, indent); + } + for(unsigned int i=0;i<mDestinationList.size();i++){ + mDestinationList[i]->print(out, indent); + } + do_indent(out, indent); + (out) << "route_log_len_dummy:" << std::hex << (unsigned long long)mRouteLogLenDummy << "\n"; + do_indent(out, indent); + (out) << "message_code:" << std::hex << (unsigned long long)mMessageCode << "\n"; +}; + +void ForwardingHeaderStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding ForwardingHeaderStruct"); + decode_uintX(in, 32, mReloToken); + StackLog( << "mReloToken =" << std::hex << (unsigned long long) mReloToken ); + + decode_uintX(in, 32, mOverlay); + StackLog( << "mOverlay =" << std::hex << (unsigned long long) mOverlay ); + + decode_uintX(in, 8, mTtl); + StackLog( << "mTtl =" << std::hex << (unsigned long long) mTtl ); + + decode_uintX(in, 8, mReserved); + StackLog( << "mReserved =" << std::hex << (unsigned long long) mReserved ); + + decode_uintX(in, 16, mFragment); + StackLog( << "mFragment =" << std::hex << (unsigned long long) mFragment ); + + decode_uintX(in, 8, mVersion); + StackLog( << "mVersion =" << std::hex << (unsigned long long) mVersion ); + + decode_uintX(in, 24, mLength); + StackLog( << "mLength =" << std::hex << (unsigned long long) mLength ); + + decode_uintX(in, 64, mTransactionId); + StackLog( << "mTransactionId =" << std::hex << (unsigned long long) mTransactionId ); + + decode_uintX(in, 16, mFlags); + StackLog( << "mFlags =" << std::hex << (unsigned long long) mFlags ); + + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mViaList.push_back(0); + mViaList[i] = new DestinationStruct(); + mViaList[i]->decode(in2); + i++; + } +; } + + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mDestinationList.push_back(0); + mDestinationList[i] = new DestinationStruct(); + mDestinationList[i]->decode(in2); + i++; + } +; } + + decode_uintX(in, 16, mRouteLogLenDummy); + StackLog( << "mRouteLogLenDummy =" << std::hex << (unsigned long long) mRouteLogLenDummy ); + + decode_uintX(in, 16, mMessageCode); + StackLog( << "mMessageCode =" << std::hex << (unsigned long long) mMessageCode ); + +}; + +void ForwardingHeaderStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding ForwardingHeaderStruct"); + StackLog( << "mReloToken =" << std::hex << (unsigned long long) mReloToken ); + encode_uintX(out, 32, mReloToken); + + StackLog( << "mOverlay =" << std::hex << (unsigned long long) mOverlay ); + encode_uintX(out, 32, mOverlay); + + StackLog( << "mTtl =" << std::hex << (unsigned long long) mTtl ); + encode_uintX(out, 8, mTtl); + + StackLog( << "mReserved =" << std::hex << (unsigned long long) mReserved ); + encode_uintX(out, 8, mReserved); + + StackLog( << "mFragment =" << std::hex << (unsigned long long) mFragment ); + encode_uintX(out, 16, mFragment); + + StackLog( << "mVersion =" << std::hex << (unsigned long long) mVersion ); + encode_uintX(out, 8, mVersion); + + StackLog( << "mLength =" << std::hex << (unsigned long long) mLength ); + encode_uintX(out, 24, mLength); + + StackLog( << "mTransactionId =" << std::hex << (unsigned long long) mTransactionId ); + encode_uintX(out, 64, mTransactionId); + + StackLog( << "mFlags =" << std::hex << (unsigned long long) mFlags ); + encode_uintX(out, 16, mFlags); + + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mViaList.size();i++) + { + mViaList[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mDestinationList.size();i++) + { + mDestinationList[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + + StackLog( << "mRouteLogLenDummy =" << std::hex << (unsigned long long) mRouteLogLenDummy ); + encode_uintX(out, 16, mRouteLogLenDummy); + + StackLog( << "mMessageCode =" << std::hex << (unsigned long long) mMessageCode ); + encode_uintX(out, 16, mMessageCode); + +}; + + + +// Classes for ForwardingLayerMessageStruct */ + +ForwardingLayerMessageStruct :: ForwardingLayerMessageStruct () +{ + mName = "ForwardingLayerMessageStruct"; + StackLog(<< "Constructing ForwardingLayerMessageStruct"); + mHeader=0; + + + mSig=0; + +}; + +ForwardingLayerMessageStruct :: ForwardingLayerMessageStruct (const ForwardingLayerMessageStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "ForwardingLayerMessageStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void ForwardingLayerMessageStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "ForwardingLayerMessage:\n"; + indent+=2; + mHeader->print(out, indent); + out << mPayload.hex(); + mSig->print(out, indent); +}; + +void ForwardingLayerMessageStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding ForwardingLayerMessageStruct"); + mHeader = new ForwardingHeaderStruct(); + mHeader->decode(in); + + { + UInt32 len; + int c; + decode_uintX(in, 24, len); + resip::DataStream strm(mPayload); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "payload",__FILE__,__LINE__); + strm.put(c); + }; + } + + mSig = new SignatureStruct(); + mSig->decode(in); + +}; + +void ForwardingLayerMessageStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding ForwardingLayerMessageStruct"); + mHeader->encode(out); + + encode_uintX(out, 24, mPayload.size()); + out << mPayload; + + mSig->encode(out); + +}; + + + +// Classes for MessagePayloadStruct */ + +MessagePayloadStruct :: MessagePayloadStruct () +{ + mName = "MessagePayloadStruct"; + StackLog(<< "Constructing MessagePayloadStruct"); + +}; + +MessagePayloadStruct :: MessagePayloadStruct (const MessagePayloadStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "MessagePayloadStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void MessagePayloadStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "MessagePayload:\n"; + indent+=2; + out << mPayload.hex(); +}; + +void MessagePayloadStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding MessagePayloadStruct"); + { + UInt32 len; + int c; + decode_uintX(in, 24, len); + resip::DataStream strm(mPayload); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "payload",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void MessagePayloadStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding MessagePayloadStruct"); + encode_uintX(out, 24, mPayload.size()); + out << mPayload; + +}; + + + +// Classes for ErrorResponseStruct */ + +ErrorResponseStruct :: ErrorResponseStruct () +{ + mName = "ErrorResponseStruct"; + StackLog(<< "Constructing ErrorResponseStruct"); + mErrorCode=0; + + + +}; + +ErrorResponseStruct :: ErrorResponseStruct (const ErrorResponseStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "ErrorResponseStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void ErrorResponseStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "ErrorResponse:\n"; + indent+=2; + do_indent(out, indent); + (out) << "error_code:" << std::hex << (unsigned long long)mErrorCode << "\n"; + out << mReasonPhrase.hex(); + out << mErrorInfo.hex(); +}; + +void ErrorResponseStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding ErrorResponseStruct"); + decode_uintX(in, 16, mErrorCode); + StackLog( << "mErrorCode =" << std::hex << (unsigned long long) mErrorCode ); + + { + UInt32 len; + int c; + decode_uintX(in, 8, len); + resip::DataStream strm(mReasonPhrase); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "reason_phrase",__FILE__,__LINE__); + strm.put(c); + }; + } + + { + UInt32 len; + int c; + decode_uintX(in, 16, len); + resip::DataStream strm(mErrorInfo); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "error_info",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void ErrorResponseStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding ErrorResponseStruct"); + StackLog( << "mErrorCode =" << std::hex << (unsigned long long) mErrorCode ); + encode_uintX(out, 16, mErrorCode); + + encode_uintX(out, 8, mReasonPhrase.size()); + out << mReasonPhrase; + + encode_uintX(out, 16, mErrorInfo.size()); + out << mErrorInfo; + +}; + + + +// Classes for JoinReqStruct */ + +JoinReqStruct :: JoinReqStruct () +{ + mName = "JoinReqStruct"; + StackLog(<< "Constructing JoinReqStruct"); + mJoiningPeerId=0; + + +}; + +JoinReqStruct :: JoinReqStruct (const JoinReqStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "JoinReqStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void JoinReqStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "JoinReq:\n"; + indent+=2; + mJoiningPeerId->print(out, indent); + out << mOverlaySpecificData.hex(); +}; + +void JoinReqStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding JoinReqStruct"); + mJoiningPeerId = new NodeIdStruct(); + mJoiningPeerId->decode(in); + + { + UInt32 len; + int c; + decode_uintX(in, 16, len); + resip::DataStream strm(mOverlaySpecificData); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "overlay_specific_data",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void JoinReqStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding JoinReqStruct"); + mJoiningPeerId->encode(out); + + encode_uintX(out, 16, mOverlaySpecificData.size()); + out << mOverlaySpecificData; + +}; + + + +// Classes for JoinAnsStruct */ + +JoinAnsStruct :: JoinAnsStruct () +{ + mName = "JoinAnsStruct"; + StackLog(<< "Constructing JoinAnsStruct"); + +}; + +JoinAnsStruct :: JoinAnsStruct (const JoinAnsStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "JoinAnsStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void JoinAnsStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "JoinAns:\n"; + indent+=2; + out << mOverlaySpecificData.hex(); +}; + +void JoinAnsStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding JoinAnsStruct"); + { + UInt32 len; + int c; + decode_uintX(in, 16, len); + resip::DataStream strm(mOverlaySpecificData); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "overlay_specific_data",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void JoinAnsStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding JoinAnsStruct"); + encode_uintX(out, 16, mOverlaySpecificData.size()); + out << mOverlaySpecificData; + +}; + + + +// Classes for LeaveReqStruct */ + +LeaveReqStruct :: LeaveReqStruct () +{ + mName = "LeaveReqStruct"; + StackLog(<< "Constructing LeaveReqStruct"); + mLeavingPeerId=0; + + +}; + +LeaveReqStruct :: LeaveReqStruct (const LeaveReqStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "LeaveReqStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void LeaveReqStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "LeaveReq:\n"; + indent+=2; + mLeavingPeerId->print(out, indent); + out << mOverlaySpecificData.hex(); +}; + +void LeaveReqStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding LeaveReqStruct"); + mLeavingPeerId = new NodeIdStruct(); + mLeavingPeerId->decode(in); + + { + UInt32 len; + int c; + decode_uintX(in, 16, len); + resip::DataStream strm(mOverlaySpecificData); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "overlay_specific_data",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void LeaveReqStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding LeaveReqStruct"); + mLeavingPeerId->encode(out); + + encode_uintX(out, 16, mOverlaySpecificData.size()); + out << mOverlaySpecificData; + +}; + + + +// Classes for RouteQueryReqStruct */ + +RouteQueryReqStruct :: RouteQueryReqStruct () +{ + mName = "RouteQueryReqStruct"; + StackLog(<< "Constructing RouteQueryReqStruct"); + mSendUpdate=(Boolean)0; + + mDestination=0; + + +}; + +RouteQueryReqStruct :: RouteQueryReqStruct (const RouteQueryReqStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "RouteQueryReqStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void RouteQueryReqStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "RouteQueryReq:\n"; + indent+=2; + do_indent(out, indent); + (out) << "send_update:" << std::hex << (unsigned long long) mSendUpdate << "\n"; + mDestination->print(out, indent); + out << mOverlaySpecificData.hex(); +}; + +void RouteQueryReqStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding RouteQueryReqStruct"); + { + u_int32 v; + decode_uintX(in, 8, v); + mSendUpdate=(Boolean)v; + } + + mDestination = new DestinationStruct(); + mDestination->decode(in); + + { + UInt32 len; + int c; + decode_uintX(in, 16, len); + resip::DataStream strm(mOverlaySpecificData); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "overlay_specific_data",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void RouteQueryReqStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding RouteQueryReqStruct"); + encode_uintX(out, 8, (u_int64)(mSendUpdate)); + + mDestination->encode(out); + + encode_uintX(out, 16, mOverlaySpecificData.size()); + out << mOverlaySpecificData; + +}; + + + +// Classes for FramedMessageStruct */ + +FramedMessageStruct :: FramedMessageStruct () +{ + mName = "FramedMessageStruct"; + StackLog(<< "Constructing FramedMessageStruct"); + mType=(FramedMessageType)0; + + mData.mSequence=0; + mAck.mAckSequence=0; + mAck.mReceived=0; + +}; + +FramedMessageStruct :: FramedMessageStruct (const FramedMessageStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "FramedMessageStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void FramedMessageStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "FramedMessage:\n"; + indent+=2; + do_indent(out, indent); + (out) << "type:" << std::hex << (unsigned long long) mType << "\n"; +}; + +void FramedMessageStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding FramedMessageStruct"); + { + u_int32 v; + decode_uintX(in, 8, v); + mType=(FramedMessageType)v; + } + + switch(mType){ + case 128: + decode_uintX(in, 24, mData.mSequence); + StackLog( << "mData.mSequence =" << std::hex << (unsigned long long) mData.mSequence ); + { + UInt32 len; + int c; + decode_uintX(in, 24, len); + resip::DataStream strm(mData.mMessage); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "message",__FILE__,__LINE__); + strm.put(c); + }; + } + break; + + case 129: + decode_uintX(in, 24, mAck.mAckSequence); + StackLog( << "mAck.mAckSequence =" << std::hex << (unsigned long long) mAck.mAckSequence ); + decode_uintX(in, 32, mAck.mReceived); + StackLog( << "mAck.mReceived =" << std::hex << (unsigned long long) mAck.mReceived ); + break; + + default: /* User error */ + assert(1==0); + } + + +}; + +void FramedMessageStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding FramedMessageStruct"); + encode_uintX(out, 8, (u_int64)(mType)); + + switch(mType) { + case 128: + StackLog( << "mData.mSequence =" << std::hex << (unsigned long long) mData.mSequence ); + encode_uintX(out, 24, mData.mSequence); + encode_uintX(out, 24, mData.mMessage.size()); + out << mData.mMessage; + break; + + case 129: + StackLog( << "mAck.mAckSequence =" << std::hex << (unsigned long long) mAck.mAckSequence ); + encode_uintX(out, 24, mAck.mAckSequence); + StackLog( << "mAck.mReceived =" << std::hex << (unsigned long long) mAck.mReceived ); + encode_uintX(out, 32, mAck.mReceived); + break; + + default: /* User error */ + assert(1==0); + } + + +}; + + + +// Classes for IceCandidateStruct */ + +IceCandidateStruct :: IceCandidateStruct () +{ + mName = "IceCandidateStruct"; + StackLog(<< "Constructing IceCandidateStruct"); + +}; + +IceCandidateStruct :: IceCandidateStruct (const IceCandidateStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "IceCandidateStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void IceCandidateStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "IceCandidate:\n"; + indent+=2; + out << mCandidate.hex(); +}; + +void IceCandidateStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding IceCandidateStruct"); + { + UInt32 len; + int c; + decode_uintX(in, 16, len); + resip::DataStream strm(mCandidate); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "candidate",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void IceCandidateStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding IceCandidateStruct"); + encode_uintX(out, 16, mCandidate.size()); + out << mCandidate; + +}; + + + +// Classes for ConnectReqAnsStruct */ + +ConnectReqAnsStruct :: ConnectReqAnsStruct () +{ + mName = "ConnectReqAnsStruct"; + StackLog(<< "Constructing ConnectReqAnsStruct"); + + + mApplication=0; + + + +}; + +ConnectReqAnsStruct :: ConnectReqAnsStruct (const ConnectReqAnsStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "ConnectReqAnsStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void ConnectReqAnsStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "ConnectReqAns:\n"; + indent+=2; + out << mUfrag.hex(); + out << mPassword.hex(); + do_indent(out, indent); + (out) << "application:" << std::hex << (unsigned long long)mApplication << "\n"; + out << mRole.hex(); + for(unsigned int i=0;i<mCandidates.size();i++){ + mCandidates[i]->print(out, indent); + } +}; + +void ConnectReqAnsStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding ConnectReqAnsStruct"); + { + UInt32 len; + int c; + decode_uintX(in, 8, len); + resip::DataStream strm(mUfrag); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "ufrag",__FILE__,__LINE__); + strm.put(c); + }; + } + + { + UInt32 len; + int c; + decode_uintX(in, 8, len); + resip::DataStream strm(mPassword); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "password",__FILE__,__LINE__); + strm.put(c); + }; + } + + decode_uintX(in, 16, mApplication); + StackLog( << "mApplication =" << std::hex << (unsigned long long) mApplication ); + + { + UInt32 len; + int c; + decode_uintX(in, 8, len); + resip::DataStream strm(mRole); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "role",__FILE__,__LINE__); + strm.put(c); + }; + } + + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mCandidates.push_back(0); + mCandidates[i] = new IceCandidateStruct(); + mCandidates[i]->decode(in2); + i++; + } +; } + +}; + +void ConnectReqAnsStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding ConnectReqAnsStruct"); + encode_uintX(out, 8, mUfrag.size()); + out << mUfrag; + + encode_uintX(out, 8, mPassword.size()); + out << mPassword; + + StackLog( << "mApplication =" << std::hex << (unsigned long long) mApplication ); + encode_uintX(out, 16, mApplication); + + encode_uintX(out, 8, mRole.size()); + out << mRole; + + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mCandidates.size();i++) + { + mCandidates[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + +}; + + + +// Classes for PingReqStruct */ + +PingReqStruct :: PingReqStruct () +{ + mName = "PingReqStruct"; + StackLog(<< "Constructing PingReqStruct"); + +}; + +PingReqStruct :: PingReqStruct (const PingReqStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "PingReqStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void PingReqStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "PingReq:\n"; + indent+=2; + for(unsigned int i=0;i<mRequestedInfo.size();i++){ + do_indent(out, indent); + (out) << "uint8:" << std::hex << (unsigned long long) mRequestedInfo[i] << "\n"; + } +}; + +void PingReqStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding PingReqStruct"); + { + resip::Data d; + read_varray1(in, 1, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mRequestedInfo.push_back(0); + decode_uintX(in2, 8, mRequestedInfo[i]); + StackLog( << "mRequestedInfo[i] =" << std::hex << (unsigned long long) mRequestedInfo[i] ); + i++; + } +; } + +}; + +void PingReqStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding PingReqStruct"); + { + long pos1=TELLP(out); + for(int i=0;i<1;i++) out.put(0); + for(unsigned int i=0;i<mRequestedInfo.size();i++) + { + StackLog( << "mRequestedInfo[i] =" << std::hex << (unsigned long long) mRequestedInfo[i] ); + encode_uintX(out, 8, mRequestedInfo[i]); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 8, (pos2 - pos1) - 1); + SEEKP(out,pos2); + } + +}; + + + +// Classes for PingInformationStruct */ + +PingInformationStruct :: PingInformationStruct () +{ + mName = "PingInformationStruct"; + StackLog(<< "Constructing PingInformationStruct"); + mType=(PingInformationType)0; + + mResponsibleSet.mResponsiblePpb=0; + mNumResources.mNumResources=0; + +}; + +PingInformationStruct :: PingInformationStruct (const PingInformationStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "PingInformationStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void PingInformationStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "PingInformation:\n"; + indent+=2; + do_indent(out, indent); + (out) << "type:" << std::hex << (unsigned long long) mType << "\n"; +}; + +void PingInformationStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding PingInformationStruct"); + { + u_int32 v; + decode_uintX(in, 8, v); + mType=(PingInformationType)v; + } + + switch(mType){ + case 1: + decode_uintX(in, 32, mResponsibleSet.mResponsiblePpb); + StackLog( << "mResponsibleSet.mResponsiblePpb =" << std::hex << (unsigned long long) mResponsibleSet.mResponsiblePpb ); + break; + + case 2: + decode_uintX(in, 32, mNumResources.mNumResources); + StackLog( << "mNumResources.mNumResources =" << std::hex << (unsigned long long) mNumResources.mNumResources ); + break; + + default: /* User error */ + assert(1==0); + } + + +}; + +void PingInformationStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding PingInformationStruct"); + encode_uintX(out, 8, (u_int64)(mType)); + + switch(mType) { + case 1: + StackLog( << "mResponsibleSet.mResponsiblePpb =" << std::hex << (unsigned long long) mResponsibleSet.mResponsiblePpb ); + encode_uintX(out, 32, mResponsibleSet.mResponsiblePpb); + break; + + case 2: + StackLog( << "mNumResources.mNumResources =" << std::hex << (unsigned long long) mNumResources.mNumResources ); + encode_uintX(out, 32, mNumResources.mNumResources); + break; + + default: /* User error */ + assert(1==0); + } + + +}; + + + +// Classes for PingAnsStruct */ + +PingAnsStruct :: PingAnsStruct () +{ + mName = "PingAnsStruct"; + StackLog(<< "Constructing PingAnsStruct"); + mResponseId=0; + + +}; + +PingAnsStruct :: PingAnsStruct (const PingAnsStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "PingAnsStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void PingAnsStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "PingAns:\n"; + indent+=2; + do_indent(out, indent); + (out) << "response_id:" << std::hex << (unsigned long long)mResponseId << "\n"; + for(unsigned int i=0;i<mPingInfo.size();i++){ + mPingInfo[i]->print(out, indent); + } +}; + +void PingAnsStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding PingAnsStruct"); + decode_uintX(in, 64, mResponseId); + StackLog( << "mResponseId =" << std::hex << (unsigned long long) mResponseId ); + + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mPingInfo.push_back(0); + mPingInfo[i] = new PingInformationStruct(); + mPingInfo[i]->decode(in2); + i++; + } +; } + +}; + +void PingAnsStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding PingAnsStruct"); + StackLog( << "mResponseId =" << std::hex << (unsigned long long) mResponseId ); + encode_uintX(out, 64, mResponseId); + + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mPingInfo.size();i++) + { + mPingInfo[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + +}; + + + +// Classes for TunnelReqStruct */ + +TunnelReqStruct :: TunnelReqStruct () +{ + mName = "TunnelReqStruct"; + StackLog(<< "Constructing TunnelReqStruct"); + mApplication=0; + + + +}; + +TunnelReqStruct :: TunnelReqStruct (const TunnelReqStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "TunnelReqStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void TunnelReqStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "TunnelReq:\n"; + indent+=2; + do_indent(out, indent); + (out) << "application:" << std::hex << (unsigned long long)mApplication << "\n"; + out << mDialogId.hex(); + out << mApplicationPdu.hex(); +}; + +void TunnelReqStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding TunnelReqStruct"); + decode_uintX(in, 16, mApplication); + StackLog( << "mApplication =" << std::hex << (unsigned long long) mApplication ); + + { + UInt32 len; + int c; + decode_uintX(in, 8, len); + resip::DataStream strm(mDialogId); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "dialog_id",__FILE__,__LINE__); + strm.put(c); + }; + } + + { + UInt32 len; + int c; + decode_uintX(in, 24, len); + resip::DataStream strm(mApplicationPdu); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "application_pdu",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void TunnelReqStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding TunnelReqStruct"); + StackLog( << "mApplication =" << std::hex << (unsigned long long) mApplication ); + encode_uintX(out, 16, mApplication); + + encode_uintX(out, 8, mDialogId.size()); + out << mDialogId; + + encode_uintX(out, 24, mApplicationPdu.size()); + out << mApplicationPdu; + +}; + + + +// Classes for DataValueStruct */ + +DataValueStruct :: DataValueStruct () +{ + mName = "DataValueStruct"; + StackLog(<< "Constructing DataValueStruct"); + mExists=(Boolean)0; + + +}; + +DataValueStruct :: DataValueStruct (const DataValueStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "DataValueStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void DataValueStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "DataValue:\n"; + indent+=2; + do_indent(out, indent); + (out) << "exists:" << std::hex << (unsigned long long) mExists << "\n"; + out << mValue.hex(); +}; + +void DataValueStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding DataValueStruct"); + { + u_int32 v; + decode_uintX(in, 8, v); + mExists=(Boolean)v; + } + + { + UInt32 len; + int c; + decode_uintX(in, 32, len); + resip::DataStream strm(mValue); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "value",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void DataValueStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding DataValueStruct"); + encode_uintX(out, 8, (u_int64)(mExists)); + + encode_uintX(out, 32, mValue.size()); + out << mValue; + +}; + + + +// Classes for ArrayEntryStruct */ + +ArrayEntryStruct :: ArrayEntryStruct () +{ + mName = "ArrayEntryStruct"; + StackLog(<< "Constructing ArrayEntryStruct"); + mIndex=0; + + mValue=0; + +}; + +ArrayEntryStruct :: ArrayEntryStruct (const ArrayEntryStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "ArrayEntryStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void ArrayEntryStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "ArrayEntry:\n"; + indent+=2; + do_indent(out, indent); + (out) << "index:" << std::hex << (unsigned long long)mIndex << "\n"; + mValue->print(out, indent); +}; + +void ArrayEntryStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding ArrayEntryStruct"); + decode_uintX(in, 32, mIndex); + StackLog( << "mIndex =" << std::hex << (unsigned long long) mIndex ); + + mValue = new DataValueStruct(); + mValue->decode(in); + +}; + +void ArrayEntryStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding ArrayEntryStruct"); + StackLog( << "mIndex =" << std::hex << (unsigned long long) mIndex ); + encode_uintX(out, 32, mIndex); + + mValue->encode(out); + +}; + + + +// Classes for DictionaryKeyStruct */ + +DictionaryKeyStruct :: DictionaryKeyStruct () +{ + mName = "DictionaryKeyStruct"; + StackLog(<< "Constructing DictionaryKeyStruct"); + +}; + +DictionaryKeyStruct :: DictionaryKeyStruct (const DictionaryKeyStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "DictionaryKeyStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void DictionaryKeyStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "DictionaryKey:\n"; + indent+=2; + out << mKey.hex(); +}; + +void DictionaryKeyStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding DictionaryKeyStruct"); + { + UInt32 len; + int c; + decode_uintX(in, 16, len); + resip::DataStream strm(mKey); + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "key",__FILE__,__LINE__); + strm.put(c); + }; + } + +}; + +void DictionaryKeyStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding DictionaryKeyStruct"); + encode_uintX(out, 16, mKey.size()); + out << mKey; + +}; + + + +// Classes for DictionaryEntryStruct */ + +DictionaryEntryStruct :: DictionaryEntryStruct () +{ + mName = "DictionaryEntryStruct"; + StackLog(<< "Constructing DictionaryEntryStruct"); + mKey=0; + + mValue=0; + +}; + +DictionaryEntryStruct :: DictionaryEntryStruct (const DictionaryEntryStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "DictionaryEntryStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void DictionaryEntryStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "DictionaryEntry:\n"; + indent+=2; + mKey->print(out, indent); + mValue->print(out, indent); +}; + +void DictionaryEntryStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding DictionaryEntryStruct"); + mKey = new DictionaryKeyStruct(); + mKey->decode(in); + + mValue = new DataValueStruct(); + mValue->decode(in); + +}; + +void DictionaryEntryStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding DictionaryEntryStruct"); + mKey->encode(out); + + mValue->encode(out); + +}; + + + +// Classes for StoredDataValueStruct */ + +StoredDataValueStruct :: StoredDataValueStruct () +{ + mName = "StoredDataValueStruct"; + StackLog(<< "Constructing StoredDataValueStruct"); + mModel=(DataModel)0; + + mSingleValue.mSingleValueEntry=0; + mArray.mArrayEntry=0; + mDictionary.mDictionaryEntry=0; + +}; + +StoredDataValueStruct :: StoredDataValueStruct (const StoredDataValueStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "StoredDataValueStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void StoredDataValueStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "StoredDataValue:\n"; + indent+=2; + do_indent(out, indent); + (out) << "model:" << std::hex << (unsigned long long) mModel << "\n"; +}; + +void StoredDataValueStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding StoredDataValueStruct"); + { + u_int32 v; + decode_uintX(in, 8, v); + mModel=(DataModel)v; + } + + switch(mModel){ + case 1: + mSingleValue.mSingleValueEntry = new DataValueStruct(); + mSingleValue.mSingleValueEntry->decode(in); + break; + + case 2: + mArray.mArrayEntry = new ArrayEntryStruct(); + mArray.mArrayEntry->decode(in); + break; + + case 3: + mDictionary.mDictionaryEntry = new DictionaryEntryStruct(); + mDictionary.mDictionaryEntry->decode(in); + break; + + default: /* User error */ + assert(1==0); + } + + +}; + +void StoredDataValueStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding StoredDataValueStruct"); + encode_uintX(out, 8, (u_int64)(mModel)); + + switch(mModel) { + case 1: + mSingleValue.mSingleValueEntry->encode(out); + break; + + case 2: + mArray.mArrayEntry->encode(out); + break; + + case 3: + mDictionary.mDictionaryEntry->encode(out); + break; + + default: /* User error */ + assert(1==0); + } + + +}; + + + +// Classes for StoredDataStruct */ + +StoredDataStruct :: StoredDataStruct () +{ + mName = "StoredDataStruct"; + StackLog(<< "Constructing StoredDataStruct"); + + mStorageTime=0; + + mLifetime=0; + + mValue=0; + + mSignature=0; + +}; + +StoredDataStruct :: StoredDataStruct (const StoredDataStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "StoredDataStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void StoredDataStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "StoredData:\n"; + indent+=2; + do_indent(out, indent); + (out) << "storage_time:" << std::hex << (unsigned long long)mStorageTime << "\n"; + do_indent(out, indent); + (out) << "lifetime:" << std::hex << (unsigned long long)mLifetime << "\n"; + mValue->print(out, indent); + mSignature->print(out, indent); +}; + +void StoredDataStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding StoredDataStruct"); + { + resip::Data d; + read_varray1(in, 4, d); + resip::DataStream in_auto(d); + + decode_uintX(in_auto, 64, mStorageTime); + StackLog( << "mStorageTime =" << std::hex << (unsigned long long) mStorageTime ); + + decode_uintX(in_auto, 32, mLifetime); + StackLog( << "mLifetime =" << std::hex << (unsigned long long) mLifetime ); + + mValue = new StoredDataValueStruct(); + mValue->decode(in_auto); + + mSignature = new SignatureStruct(); + mSignature->decode(in_auto); + + if(in_auto.peek()!=EOF) + throw resip::ParseException("Inner encoded value too long", + "StoredData",__FILE__,__LINE__); + } +}; + +void StoredDataStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding StoredDataStruct"); + long pos1=TELLP(out); + for(int i=0;i<4;i++) out.put(0); + + StackLog( << "mStorageTime =" << std::hex << (unsigned long long) mStorageTime ); + encode_uintX(out, 64, mStorageTime); + + StackLog( << "mLifetime =" << std::hex << (unsigned long long) mLifetime ); + encode_uintX(out, 32, mLifetime); + + mValue->encode(out); + + mSignature->encode(out); + + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 32, (pos2 - pos1) - 4); + SEEKP(out,pos2); +}; + + + +// Classes for StoreKindDataStruct */ + +StoreKindDataStruct :: StoreKindDataStruct () +{ + mName = "StoreKindDataStruct"; + StackLog(<< "Constructing StoreKindDataStruct"); + mKind=0; + + mDataModel=(DataModel)0; + + mGenerationCounter=0; + + +}; + +StoreKindDataStruct :: StoreKindDataStruct (const StoreKindDataStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "StoreKindDataStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void StoreKindDataStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "StoreKindData:\n"; + indent+=2; + do_indent(out, indent); + (out) << "kind:" << std::hex << (unsigned long long)mKind << "\n"; + do_indent(out, indent); + (out) << "data_model:" << std::hex << (unsigned long long) mDataModel << "\n"; + do_indent(out, indent); + (out) << "generation_counter:" << std::hex << (unsigned long long)mGenerationCounter << "\n"; + for(unsigned int i=0;i<mValues.size();i++){ + mValues[i]->print(out, indent); + } +}; + +void StoreKindDataStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding StoreKindDataStruct"); + decode_uintX(in, 32, mKind); + StackLog( << "mKind =" << std::hex << (unsigned long long) mKind ); + + { + u_int32 v; + decode_uintX(in, 8, v); + mDataModel=(DataModel)v; + } + + decode_uintX(in, 64, mGenerationCounter); + StackLog( << "mGenerationCounter =" << std::hex << (unsigned long long) mGenerationCounter ); + + { + resip::Data d; + read_varray1(in, 4, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mValues.push_back(0); + mValues[i] = new StoredDataStruct(); + mValues[i]->decode(in2); + i++; + } +; } + +}; + +void StoreKindDataStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding StoreKindDataStruct"); + StackLog( << "mKind =" << std::hex << (unsigned long long) mKind ); + encode_uintX(out, 32, mKind); + + encode_uintX(out, 8, (u_int64)(mDataModel)); + + StackLog( << "mGenerationCounter =" << std::hex << (unsigned long long) mGenerationCounter ); + encode_uintX(out, 64, mGenerationCounter); + + { + long pos1=TELLP(out); + for(int i=0;i<4;i++) out.put(0); + for(unsigned int i=0;i<mValues.size();i++) + { + mValues[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 32, (pos2 - pos1) - 4); + SEEKP(out,pos2); + } + +}; + + + +// Classes for StoreReqStruct */ + +StoreReqStruct :: StoreReqStruct () +{ + mName = "StoreReqStruct"; + StackLog(<< "Constructing StoreReqStruct"); + mResource=0; + + mReplicaNumber=0; + + +}; + +StoreReqStruct :: StoreReqStruct (const StoreReqStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "StoreReqStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void StoreReqStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "StoreReq:\n"; + indent+=2; + mResource->print(out, indent); + do_indent(out, indent); + (out) << "replica_number:" << std::hex << (unsigned long long)mReplicaNumber << "\n"; + for(unsigned int i=0;i<mKindData.size();i++){ + mKindData[i]->print(out, indent); + } +}; + +void StoreReqStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding StoreReqStruct"); + mResource = new ResourceIdStruct(); + mResource->decode(in); + + decode_uintX(in, 8, mReplicaNumber); + StackLog( << "mReplicaNumber =" << std::hex << (unsigned long long) mReplicaNumber ); + + { + resip::Data d; + read_varray1(in, 4, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mKindData.push_back(0); + mKindData[i] = new StoreKindDataStruct(); + mKindData[i]->decode(in2); + i++; + } +; } + +}; + +void StoreReqStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding StoreReqStruct"); + mResource->encode(out); + + StackLog( << "mReplicaNumber =" << std::hex << (unsigned long long) mReplicaNumber ); + encode_uintX(out, 8, mReplicaNumber); + + { + long pos1=TELLP(out); + for(int i=0;i<4;i++) out.put(0); + for(unsigned int i=0;i<mKindData.size();i++) + { + mKindData[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 32, (pos2 - pos1) - 4); + SEEKP(out,pos2); + } + +}; + + + +// Classes for StoreKindResponseStruct */ + +StoreKindResponseStruct :: StoreKindResponseStruct () +{ + mName = "StoreKindResponseStruct"; + StackLog(<< "Constructing StoreKindResponseStruct"); + mKind=0; + + mGenerationCounter=0; + + +}; + +StoreKindResponseStruct :: StoreKindResponseStruct (const StoreKindResponseStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "StoreKindResponseStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void StoreKindResponseStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "StoreKindResponse:\n"; + indent+=2; + do_indent(out, indent); + (out) << "kind:" << std::hex << (unsigned long long)mKind << "\n"; + do_indent(out, indent); + (out) << "generation_counter:" << std::hex << (unsigned long long)mGenerationCounter << "\n"; + for(unsigned int i=0;i<mReplicas.size();i++){ + mReplicas[i]->print(out, indent); + } +}; + +void StoreKindResponseStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding StoreKindResponseStruct"); + decode_uintX(in, 32, mKind); + StackLog( << "mKind =" << std::hex << (unsigned long long) mKind ); + + decode_uintX(in, 64, mGenerationCounter); + StackLog( << "mGenerationCounter =" << std::hex << (unsigned long long) mGenerationCounter ); + + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mReplicas.push_back(0); + mReplicas[i] = new NodeIdStruct(); + mReplicas[i]->decode(in2); + i++; + } +; } + +}; + +void StoreKindResponseStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding StoreKindResponseStruct"); + StackLog( << "mKind =" << std::hex << (unsigned long long) mKind ); + encode_uintX(out, 32, mKind); + + StackLog( << "mGenerationCounter =" << std::hex << (unsigned long long) mGenerationCounter ); + encode_uintX(out, 64, mGenerationCounter); + + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mReplicas.size();i++) + { + mReplicas[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + +}; + + + +// Classes for StoreAnsStruct */ + +StoreAnsStruct :: StoreAnsStruct () +{ + mName = "StoreAnsStruct"; + StackLog(<< "Constructing StoreAnsStruct"); + +}; + +StoreAnsStruct :: StoreAnsStruct (const StoreAnsStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "StoreAnsStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void StoreAnsStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "StoreAns:\n"; + indent+=2; + for(unsigned int i=0;i<mKindResponses.size();i++){ + mKindResponses[i]->print(out, indent); + } +}; + +void StoreAnsStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding StoreAnsStruct"); + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mKindResponses.push_back(0); + mKindResponses[i] = new StoreKindResponseStruct(); + mKindResponses[i]->decode(in2); + i++; + } +; } + +}; + +void StoreAnsStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding StoreAnsStruct"); + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mKindResponses.size();i++) + { + mKindResponses[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + +}; + + + +// Classes for ArrayRangeStruct */ + +ArrayRangeStruct :: ArrayRangeStruct () +{ + mName = "ArrayRangeStruct"; + StackLog(<< "Constructing ArrayRangeStruct"); + mFirst=0; + + mLast=0; + +}; + +ArrayRangeStruct :: ArrayRangeStruct (const ArrayRangeStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "ArrayRangeStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void ArrayRangeStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "ArrayRange:\n"; + indent+=2; + do_indent(out, indent); + (out) << "first:" << std::hex << (unsigned long long)mFirst << "\n"; + do_indent(out, indent); + (out) << "last:" << std::hex << (unsigned long long)mLast << "\n"; +}; + +void ArrayRangeStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding ArrayRangeStruct"); + decode_uintX(in, 32, mFirst); + StackLog( << "mFirst =" << std::hex << (unsigned long long) mFirst ); + + decode_uintX(in, 32, mLast); + StackLog( << "mLast =" << std::hex << (unsigned long long) mLast ); + +}; + +void ArrayRangeStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding ArrayRangeStruct"); + StackLog( << "mFirst =" << std::hex << (unsigned long long) mFirst ); + encode_uintX(out, 32, mFirst); + + StackLog( << "mLast =" << std::hex << (unsigned long long) mLast ); + encode_uintX(out, 32, mLast); + +}; + + + +// Classes for StoredDataSpecifierStruct */ + +StoredDataSpecifierStruct :: StoredDataSpecifierStruct () +{ + mName = "StoredDataSpecifierStruct"; + StackLog(<< "Constructing StoredDataSpecifierStruct"); + mKind=0; + + mModel=(DataModel)0; + + mGeneration=0; + + + +}; + +StoredDataSpecifierStruct :: StoredDataSpecifierStruct (const StoredDataSpecifierStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "StoredDataSpecifierStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void StoredDataSpecifierStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "StoredDataSpecifier:\n"; + indent+=2; + do_indent(out, indent); + (out) << "kind:" << std::hex << (unsigned long long)mKind << "\n"; + do_indent(out, indent); + (out) << "model:" << std::hex << (unsigned long long) mModel << "\n"; + do_indent(out, indent); + (out) << "generation:" << std::hex << (unsigned long long)mGeneration << "\n"; +}; + +void StoredDataSpecifierStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding StoredDataSpecifierStruct"); + decode_uintX(in, 32, mKind); + StackLog( << "mKind =" << std::hex << (unsigned long long) mKind ); + + { + u_int32 v; + decode_uintX(in, 8, v); + mModel=(DataModel)v; + } + + decode_uintX(in, 64, mGeneration); + StackLog( << "mGeneration =" << std::hex << (unsigned long long) mGeneration ); + + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in_auto(d); + + switch(mModel){ + case 1: + break; + + case 2: + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mArray.mIndices.push_back(0); + mArray.mIndices[i] = new ArrayRangeStruct(); + mArray.mIndices[i]->decode(in2); + i++; + } +; } + break; + + case 3: + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mDictionary.mKeys.push_back(0); + mDictionary.mKeys[i] = new DictionaryKeyStruct(); + mDictionary.mKeys[i]->decode(in2); + i++; + } +; } + break; + + default: /* User error */ + assert(1==0); + } + + + if(in_auto.peek()!=EOF) + throw resip::ParseException("Inner encoded value too long", + "StoredDataSpecifier",__FILE__,__LINE__); + } +}; + +void StoredDataSpecifierStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding StoredDataSpecifierStruct"); + StackLog( << "mKind =" << std::hex << (unsigned long long) mKind ); + encode_uintX(out, 32, mKind); + + encode_uintX(out, 8, (u_int64)(mModel)); + + StackLog( << "mGeneration =" << std::hex << (unsigned long long) mGeneration ); + encode_uintX(out, 64, mGeneration); + + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + + switch(mModel) { + case 1: + break; + + case 2: + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mArray.mIndices.size();i++) + { + mArray.mIndices[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + break; + + case 3: + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mDictionary.mKeys.size();i++) + { + mDictionary.mKeys[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + break; + + default: /* User error */ + assert(1==0); + } + + + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); +}; + + + +// Classes for FetchReqStruct */ + +FetchReqStruct :: FetchReqStruct () +{ + mName = "FetchReqStruct"; + StackLog(<< "Constructing FetchReqStruct"); + mResource=0; + + +}; + +FetchReqStruct :: FetchReqStruct (const FetchReqStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "FetchReqStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void FetchReqStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "FetchReq:\n"; + indent+=2; + mResource->print(out, indent); + for(unsigned int i=0;i<mSpecifiers.size();i++){ + mSpecifiers[i]->print(out, indent); + } +}; + +void FetchReqStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding FetchReqStruct"); + mResource = new ResourceIdStruct(); + mResource->decode(in); + + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mSpecifiers.push_back(0); + mSpecifiers[i] = new StoredDataSpecifierStruct(); + mSpecifiers[i]->decode(in2); + i++; + } +; } + +}; + +void FetchReqStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding FetchReqStruct"); + mResource->encode(out); + + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mSpecifiers.size();i++) + { + mSpecifiers[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + +}; + + + +// Classes for FetchKindResponseStruct */ + +FetchKindResponseStruct :: FetchKindResponseStruct () +{ + mName = "FetchKindResponseStruct"; + StackLog(<< "Constructing FetchKindResponseStruct"); + mKind=0; + + mGeneration=0; + + +}; + +FetchKindResponseStruct :: FetchKindResponseStruct (const FetchKindResponseStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "FetchKindResponseStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void FetchKindResponseStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "FetchKindResponse:\n"; + indent+=2; + do_indent(out, indent); + (out) << "kind:" << std::hex << (unsigned long long)mKind << "\n"; + do_indent(out, indent); + (out) << "generation:" << std::hex << (unsigned long long)mGeneration << "\n"; + for(unsigned int i=0;i<mValues.size();i++){ + mValues[i]->print(out, indent); + } +}; + +void FetchKindResponseStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding FetchKindResponseStruct"); + decode_uintX(in, 32, mKind); + StackLog( << "mKind =" << std::hex << (unsigned long long) mKind ); + + decode_uintX(in, 64, mGeneration); + StackLog( << "mGeneration =" << std::hex << (unsigned long long) mGeneration ); + + { + resip::Data d; + read_varray1(in, 4, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mValues.push_back(0); + mValues[i] = new StoredDataStruct(); + mValues[i]->decode(in2); + i++; + } +; } + +}; + +void FetchKindResponseStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding FetchKindResponseStruct"); + StackLog( << "mKind =" << std::hex << (unsigned long long) mKind ); + encode_uintX(out, 32, mKind); + + StackLog( << "mGeneration =" << std::hex << (unsigned long long) mGeneration ); + encode_uintX(out, 64, mGeneration); + + { + long pos1=TELLP(out); + for(int i=0;i<4;i++) out.put(0); + for(unsigned int i=0;i<mValues.size();i++) + { + mValues[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 32, (pos2 - pos1) - 4); + SEEKP(out,pos2); + } + +}; + + + +// Classes for FetchAnsStruct */ + +FetchAnsStruct :: FetchAnsStruct () +{ + mName = "FetchAnsStruct"; + StackLog(<< "Constructing FetchAnsStruct"); + +}; + +FetchAnsStruct :: FetchAnsStruct (const FetchAnsStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "FetchAnsStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void FetchAnsStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "FetchAns:\n"; + indent+=2; + for(unsigned int i=0;i<mKindResponses.size();i++){ + mKindResponses[i]->print(out, indent); + } +}; + +void FetchAnsStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding FetchAnsStruct"); + { + resip::Data d; + read_varray1(in, 4, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mKindResponses.push_back(0); + mKindResponses[i] = new FetchKindResponseStruct(); + mKindResponses[i]->decode(in2); + i++; + } +; } + +}; + +void FetchAnsStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding FetchAnsStruct"); + { + long pos1=TELLP(out); + for(int i=0;i<4;i++) out.put(0); + for(unsigned int i=0;i<mKindResponses.size();i++) + { + mKindResponses[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 32, (pos2 - pos1) - 4); + SEEKP(out,pos2); + } + +}; + + + +// Classes for RemoveReqStruct */ + +RemoveReqStruct :: RemoveReqStruct () +{ + mName = "RemoveReqStruct"; + StackLog(<< "Constructing RemoveReqStruct"); + mResource=0; + + +}; + +RemoveReqStruct :: RemoveReqStruct (const RemoveReqStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "RemoveReqStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void RemoveReqStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "RemoveReq:\n"; + indent+=2; + mResource->print(out, indent); + for(unsigned int i=0;i<mSpecifiers.size();i++){ + mSpecifiers[i]->print(out, indent); + } +}; + +void RemoveReqStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding RemoveReqStruct"); + mResource = new ResourceIdStruct(); + mResource->decode(in); + + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mSpecifiers.push_back(0); + mSpecifiers[i] = new StoredDataSpecifierStruct(); + mSpecifiers[i]->decode(in2); + i++; + } +; } + +}; + +void RemoveReqStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding RemoveReqStruct"); + mResource->encode(out); + + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mSpecifiers.size();i++) + { + mSpecifiers[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + +}; + + + +// Classes for RemoveAnsStruct */ + +RemoveAnsStruct :: RemoveAnsStruct () +{ + mName = "RemoveAnsStruct"; + StackLog(<< "Constructing RemoveAnsStruct"); + +}; + +RemoveAnsStruct :: RemoveAnsStruct (const RemoveAnsStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "RemoveAnsStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void RemoveAnsStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "RemoveAns:\n"; + indent+=2; + for(unsigned int i=0;i<mKindResponses.size();i++){ + mKindResponses[i]->print(out, indent); + } +}; + +void RemoveAnsStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding RemoveAnsStruct"); + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mKindResponses.push_back(0); + mKindResponses[i] = new StoreKindResponseStruct(); + mKindResponses[i]->decode(in2); + i++; + } +; } + +}; + +void RemoveAnsStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding RemoveAnsStruct"); + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mKindResponses.size();i++) + { + mKindResponses[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + +}; + + + +// Classes for FindReqStruct */ + +FindReqStruct :: FindReqStruct () +{ + mName = "FindReqStruct"; + StackLog(<< "Constructing FindReqStruct"); + mResource=0; + + +}; + +FindReqStruct :: FindReqStruct (const FindReqStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "FindReqStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void FindReqStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "FindReq:\n"; + indent+=2; + mResource->print(out, indent); + for(unsigned int i=0;i<mKinds.size();i++){ + do_indent(out, indent); + (out) << "KindId:" << std::hex << (unsigned long long) mKinds[i] << "\n"; + } +}; + +void FindReqStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding FindReqStruct"); + mResource = new ResourceIdStruct(); + mResource->decode(in); + + { + resip::Data d; + read_varray1(in, 1, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mKinds.push_back(0); + decode_uintX(in2, 32, mKinds[i]); + StackLog( << "mKinds[i] =" << std::hex << (unsigned long long) mKinds[i] ); + i++; + } +; } + +}; + +void FindReqStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding FindReqStruct"); + mResource->encode(out); + + { + long pos1=TELLP(out); + for(int i=0;i<1;i++) out.put(0); + for(unsigned int i=0;i<mKinds.size();i++) + { + StackLog( << "mKinds[i] =" << std::hex << (unsigned long long) mKinds[i] ); + encode_uintX(out, 32, mKinds[i]); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 8, (pos2 - pos1) - 1); + SEEKP(out,pos2); + } + +}; + + + +// Classes for FindKindDataStruct */ + +FindKindDataStruct :: FindKindDataStruct () +{ + mName = "FindKindDataStruct"; + StackLog(<< "Constructing FindKindDataStruct"); + mKind=0; + + mClosest=0; + +}; + +FindKindDataStruct :: FindKindDataStruct (const FindKindDataStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "FindKindDataStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void FindKindDataStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "FindKindData:\n"; + indent+=2; + do_indent(out, indent); + (out) << "kind:" << std::hex << (unsigned long long)mKind << "\n"; + mClosest->print(out, indent); +}; + +void FindKindDataStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding FindKindDataStruct"); + decode_uintX(in, 32, mKind); + StackLog( << "mKind =" << std::hex << (unsigned long long) mKind ); + + mClosest = new ResourceIdStruct(); + mClosest->decode(in); + +}; + +void FindKindDataStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding FindKindDataStruct"); + StackLog( << "mKind =" << std::hex << (unsigned long long) mKind ); + encode_uintX(out, 32, mKind); + + mClosest->encode(out); + +}; + + + +// Classes for FindAnsStruct */ + +FindAnsStruct :: FindAnsStruct () +{ + mName = "FindAnsStruct"; + StackLog(<< "Constructing FindAnsStruct"); + +}; + +FindAnsStruct :: FindAnsStruct (const FindAnsStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "FindAnsStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void FindAnsStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "FindAns:\n"; + indent+=2; + for(unsigned int i=0;i<mResults.size();i++){ + mResults[i]->print(out, indent); + } +}; + +void FindAnsStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding FindAnsStruct"); + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mResults.push_back(0); + mResults[i] = new FindKindDataStruct(); + mResults[i]->decode(in2); + i++; + } +; } + +}; + +void FindAnsStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding FindAnsStruct"); + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mResults.size();i++) + { + mResults[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + +}; + + + +// Classes for TurnServerStruct */ + +TurnServerStruct :: TurnServerStruct () +{ + mName = "TurnServerStruct"; + StackLog(<< "Constructing TurnServerStruct"); + mIteration=0; + + mServerAddress=0; + +}; + +TurnServerStruct :: TurnServerStruct (const TurnServerStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "TurnServerStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void TurnServerStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "TurnServer:\n"; + indent+=2; + do_indent(out, indent); + (out) << "iteration:" << std::hex << (unsigned long long)mIteration << "\n"; + mServerAddress->print(out, indent); +}; + +void TurnServerStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding TurnServerStruct"); + decode_uintX(in, 8, mIteration); + StackLog( << "mIteration =" << std::hex << (unsigned long long) mIteration ); + + mServerAddress = new IpAddressAndPortStruct(); + mServerAddress->decode(in); + +}; + +void TurnServerStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding TurnServerStruct"); + StackLog( << "mIteration =" << std::hex << (unsigned long long) mIteration ); + encode_uintX(out, 8, mIteration); + + mServerAddress->encode(out); + +}; + + + +// Classes for SipRegistrationStruct */ + +SipRegistrationStruct :: SipRegistrationStruct () +{ + mName = "SipRegistrationStruct"; + StackLog(<< "Constructing SipRegistrationStruct"); + mType=(SipRegistrationType)0; + + + +}; + +SipRegistrationStruct :: SipRegistrationStruct (const SipRegistrationStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "SipRegistrationStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void SipRegistrationStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "SipRegistration:\n"; + indent+=2; + do_indent(out, indent); + (out) << "type:" << std::hex << (unsigned long long) mType << "\n"; +}; + +void SipRegistrationStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding SipRegistrationStruct"); + { + u_int32 v; + decode_uintX(in, 8, v); + mType=(SipRegistrationType)v; + } + + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in_auto(d); + + switch(mType){ + case 1: + { + UInt32 len; + int c; + decode_uintX(in_auto, 16, len); + resip::DataStream strm(mSipRegistrationUri.mUri); + while(len--){ + c=in_auto.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "uri",__FILE__,__LINE__); + strm.put(c); + }; + } + break; + + case 2: + { + UInt32 len; + int c; + decode_uintX(in_auto, 16, len); + resip::DataStream strm(mSipRegistrationRoute.mContactPrefs); + while(len--){ + c=in_auto.get(); + if(c==EOF) + throw resip::ParseException("Premature end of data", + "contact_prefs",__FILE__,__LINE__); + strm.put(c); + }; + } + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mSipRegistrationRoute.mDestinationList.push_back(0); + mSipRegistrationRoute.mDestinationList[i] = new DestinationStruct(); + mSipRegistrationRoute.mDestinationList[i]->decode(in2); + i++; + } +; } + break; + + default: /* User error */ + assert(1==0); + } + + + if(in_auto.peek()!=EOF) + throw resip::ParseException("Inner encoded value too long", + "SipRegistration",__FILE__,__LINE__); + } +}; + +void SipRegistrationStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding SipRegistrationStruct"); + encode_uintX(out, 8, (u_int64)(mType)); + + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + + switch(mType) { + case 1: + encode_uintX(out, 16, mSipRegistrationUri.mUri.size()); + out << mSipRegistrationUri.mUri; + break; + + case 2: + encode_uintX(out, 16, mSipRegistrationRoute.mContactPrefs.size()); + out << mSipRegistrationRoute.mContactPrefs; + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mSipRegistrationRoute.mDestinationList.size();i++) + { + mSipRegistrationRoute.mDestinationList[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + break; + + default: /* User error */ + assert(1==0); + } + + + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); +}; + + + +// Classes for ChordUpdateStruct */ + +ChordUpdateStruct :: ChordUpdateStruct () +{ + mName = "ChordUpdateStruct"; + StackLog(<< "Constructing ChordUpdateStruct"); + mType=(ChordUpdateType)0; + + +}; + +ChordUpdateStruct :: ChordUpdateStruct (const ChordUpdateStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "ChordUpdateStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void ChordUpdateStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "ChordUpdate:\n"; + indent+=2; + do_indent(out, indent); + (out) << "type:" << std::hex << (unsigned long long) mType << "\n"; +}; + +void ChordUpdateStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding ChordUpdateStruct"); + { + u_int32 v; + decode_uintX(in, 8, v); + mType=(ChordUpdateType)v; + } + + switch(mType){ + case 1: + break; + + case 2: + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mNeighbors.mPredecessors.push_back(0); + mNeighbors.mPredecessors[i] = new NodeIdStruct(); + mNeighbors.mPredecessors[i]->decode(in2); + i++; + } +; } + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mNeighbors.mSuccessors.push_back(0); + mNeighbors.mSuccessors[i] = new NodeIdStruct(); + mNeighbors.mSuccessors[i]->decode(in2); + i++; + } +; } + break; + + case 3: + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mFull.mPredecessors.push_back(0); + mFull.mPredecessors[i] = new NodeIdStruct(); + mFull.mPredecessors[i]->decode(in2); + i++; + } +; } + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mFull.mSuccessors.push_back(0); + mFull.mSuccessors[i] = new NodeIdStruct(); + mFull.mSuccessors[i]->decode(in2); + i++; + } +; } + { + resip::Data d; + read_varray1(in, 2, d); + resip::DataStream in2(d); + int i=0; + while(in2.peek()!=EOF){ + mFull.mFingers.push_back(0); + mFull.mFingers[i] = new NodeIdStruct(); + mFull.mFingers[i]->decode(in2); + i++; + } +; } + break; + + default: /* User error */ + assert(1==0); + } + + +}; + +void ChordUpdateStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding ChordUpdateStruct"); + encode_uintX(out, 8, (u_int64)(mType)); + + switch(mType) { + case 1: + break; + + case 2: + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mNeighbors.mPredecessors.size();i++) + { + mNeighbors.mPredecessors[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mNeighbors.mSuccessors.size();i++) + { + mNeighbors.mSuccessors[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + break; + + case 3: + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mFull.mPredecessors.size();i++) + { + mFull.mPredecessors[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mFull.mSuccessors.size();i++) + { + mFull.mSuccessors[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + { + long pos1=TELLP(out); + for(int i=0;i<2;i++) out.put(0); + for(unsigned int i=0;i<mFull.mFingers.size();i++) + { + mFull.mFingers[i]->encode(out); + } + long pos2=TELLP(out); + SEEKP(out,pos1); + encode_uintX(out, 16, (pos2 - pos1) - 2); + SEEKP(out,pos2); + } + break; + + default: /* User error */ + assert(1==0); + } + + +}; + + + +// Classes for ChordRouteQueryAnsStruct */ + +ChordRouteQueryAnsStruct :: ChordRouteQueryAnsStruct () +{ + mName = "ChordRouteQueryAnsStruct"; + StackLog(<< "Constructing ChordRouteQueryAnsStruct"); + mNextId=0; + +}; + +ChordRouteQueryAnsStruct :: ChordRouteQueryAnsStruct (const ChordRouteQueryAnsStruct &from) +{ + // World's lamest copy constructor + if(this==&from) return; + mName = "ChordRouteQueryAnsStruct"; + resip::Data dat; + { + resip::DataStream strm(dat); + from.encode(strm); + } + { + resip::DataStream strm(dat); + decode(strm); + } +} + +void ChordRouteQueryAnsStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "ChordRouteQueryAns:\n"; + indent+=2; + mNextId->print(out, indent); +}; + +void ChordRouteQueryAnsStruct :: decode(std::istream& in) +{ + StackLog(<< "Decoding ChordRouteQueryAnsStruct"); + mNextId = new NodeIdStruct(); + mNextId->decode(in); + +}; + +void ChordRouteQueryAnsStruct :: encode(std::ostream& out) const +{ + StackLog(<< "Encoding ChordRouteQueryAnsStruct"); + mNextId->encode(out); + +}; + +} diff --git a/src/libs/resiprocate/p2p/MessageStructsGen.hxx b/src/libs/resiprocate/p2p/MessageStructsGen.hxx new file mode 100644 index 00000000..b562bff9 --- /dev/null +++ b/src/libs/resiprocate/p2p/MessageStructsGen.hxx @@ -0,0 +1,714 @@ +#ifndef _MessageStructs_h_ +#define _MessageStructs_h_ + +#include "p2p/s2c/s2c/s2c_native.hxx" + +namespace s2c { + +typedef enum { + bool_false = 0, + bool_true = 1 +} Boolean; + +class NodeIdStruct : public PDU { +public: + NodeIdStruct(); + NodeIdStruct(const NodeIdStruct&); + UInt64 mHigh; + UInt64 mLow; + + + PDUMemberFunctions +}; + + +class ResourceIdStruct : public PDU { +public: + ResourceIdStruct(); + ResourceIdStruct(const ResourceIdStruct&); + resip::Data mId; + + + PDUMemberFunctions +}; + + +typedef enum { + reserved_addr = 0, + ipv4_address = 1, + ipv6_address = 2 +} AddressType; + +class IPv4AddrPortStruct : public PDU { +public: + IPv4AddrPortStruct(); + IPv4AddrPortStruct(const IPv4AddrPortStruct&); + UInt32 mAddr; + UInt16 mPort; + + + PDUMemberFunctions +}; + + +class IPv6AddrPortStruct : public PDU { +public: + IPv6AddrPortStruct(); + IPv6AddrPortStruct(const IPv6AddrPortStruct&); + unsigned char mAddr[16]; + UInt16 mPort; + + + PDUMemberFunctions +}; + + +class IpAddressAndPortStruct : public PDU { +public: + IpAddressAndPortStruct(); + IpAddressAndPortStruct(const IpAddressAndPortStruct&); + AddressType mType; + UInt8 mLength; + struct mIpv4Address_ { + IPv4AddrPortStruct* mV4addrPort; + } mIpv4Address; + struct mIpv6Address_ { + IPv6AddrPortStruct* mV6addrPort; + } mIpv6Address; + + + PDUMemberFunctions +}; + + +typedef enum { + reserved_destination = 0, + peer = 1, + resource = 2, + compressed = 3 +} DestinationType; + +class DestinationStruct : public PDU { +public: + DestinationStruct(); + DestinationStruct(const DestinationStruct&); + DestinationType mType; + struct mPeer_ { + NodeIdStruct* mNodeId; + } mPeer; + struct mResource_ { + ResourceIdStruct* mResourceId; + } mResource; + struct mCompressed_ { + resip::Data mCompressedId; + } mCompressed; + + + PDUMemberFunctions +}; + + +typedef enum { + reserved1 = 0, + signer_identity_peer = 1, + signer_identity_name = 2, + signer_identity_certificate = 3 +} SignerIdentityType; + +class SignerIdentityStruct : public PDU { +public: + SignerIdentityStruct(); + SignerIdentityStruct(const SignerIdentityStruct&); + SignerIdentityType mIdentityType; + resip::Data mSignerIdentity; + + + PDUMemberFunctions +}; + + +class SignatureAndHashAlgorithmStruct : public PDU { +public: + SignatureAndHashAlgorithmStruct(); + SignatureAndHashAlgorithmStruct(const SignatureAndHashAlgorithmStruct&); + UInt8 mSig; + UInt8 mHash; + + + PDUMemberFunctions +}; + + +class SignatureStruct : public PDU { +public: + SignatureStruct(); + SignatureStruct(const SignatureStruct&); + SignatureAndHashAlgorithmStruct* mAlgorithm; + SignerIdentityStruct* mIdentity; + resip::Data mSignatureValue; + + + PDUMemberFunctions +}; + + +class ForwardingHeaderStruct : public PDU { +public: + ForwardingHeaderStruct(); + ForwardingHeaderStruct(const ForwardingHeaderStruct&); + UInt32 mReloToken; + UInt32 mOverlay; + UInt8 mTtl; + UInt8 mReserved; + UInt16 mFragment; + UInt8 mVersion; + UInt32 mLength; + UInt64 mTransactionId; + UInt16 mFlags; + std::vector<DestinationStruct*> mViaList; + std::vector<DestinationStruct*> mDestinationList; + UInt16 mRouteLogLenDummy; + UInt16 mMessageCode; + + + PDUMemberFunctions +}; + + +class ForwardingLayerMessageStruct : public PDU { +public: + ForwardingLayerMessageStruct(); + ForwardingLayerMessageStruct(const ForwardingLayerMessageStruct&); + ForwardingHeaderStruct* mHeader; + resip::Data mPayload; + SignatureStruct* mSig; + + + PDUMemberFunctions +}; + + +class MessagePayloadStruct : public PDU { +public: + MessagePayloadStruct(); + MessagePayloadStruct(const MessagePayloadStruct&); + resip::Data mPayload; + + + PDUMemberFunctions +}; + + +class ErrorResponseStruct : public PDU { +public: + ErrorResponseStruct(); + ErrorResponseStruct(const ErrorResponseStruct&); + UInt16 mErrorCode; + resip::Data mReasonPhrase; + resip::Data mErrorInfo; + + + PDUMemberFunctions +}; + + +class JoinReqStruct : public PDU { +public: + JoinReqStruct(); + JoinReqStruct(const JoinReqStruct&); + NodeIdStruct* mJoiningPeerId; + resip::Data mOverlaySpecificData; + + + PDUMemberFunctions +}; + + +class JoinAnsStruct : public PDU { +public: + JoinAnsStruct(); + JoinAnsStruct(const JoinAnsStruct&); + resip::Data mOverlaySpecificData; + + + PDUMemberFunctions +}; + + +class LeaveReqStruct : public PDU { +public: + LeaveReqStruct(); + LeaveReqStruct(const LeaveReqStruct&); + NodeIdStruct* mLeavingPeerId; + resip::Data mOverlaySpecificData; + + + PDUMemberFunctions +}; + + +class RouteQueryReqStruct : public PDU { +public: + RouteQueryReqStruct(); + RouteQueryReqStruct(const RouteQueryReqStruct&); + Boolean mSendUpdate; + DestinationStruct* mDestination; + resip::Data mOverlaySpecificData; + + + PDUMemberFunctions +}; + + +typedef enum { + data = 128, + ack = 129 +} FramedMessageType; + +class FramedMessageStruct : public PDU { +public: + FramedMessageStruct(); + FramedMessageStruct(const FramedMessageStruct&); + FramedMessageType mType; + struct mData_ { + UInt32 mSequence; + resip::Data mMessage; + } mData; + struct mAck_ { + UInt32 mAckSequence; + UInt32 mReceived; + } mAck; + + + PDUMemberFunctions +}; + + +class IceCandidateStruct : public PDU { +public: + IceCandidateStruct(); + IceCandidateStruct(const IceCandidateStruct&); + resip::Data mCandidate; + + + PDUMemberFunctions +}; + + +class ConnectReqAnsStruct : public PDU { +public: + ConnectReqAnsStruct(); + ConnectReqAnsStruct(const ConnectReqAnsStruct&); + resip::Data mUfrag; + resip::Data mPassword; + UInt16 mApplication; + resip::Data mRole; + std::vector<IceCandidateStruct*> mCandidates; + + + PDUMemberFunctions +}; + + +typedef enum { + responsible_set = 1, + num_resources = 2 +} PingInformationType; + +class PingReqStruct : public PDU { +public: + PingReqStruct(); + PingReqStruct(const PingReqStruct&); + std::vector<UInt8> mRequestedInfo; + + + PDUMemberFunctions +}; + + +class PingInformationStruct : public PDU { +public: + PingInformationStruct(); + PingInformationStruct(const PingInformationStruct&); + PingInformationType mType; + struct mResponsibleSet_ { + UInt32 mResponsiblePpb; + } mResponsibleSet; + struct mNumResources_ { + UInt32 mNumResources; + } mNumResources; + + + PDUMemberFunctions +}; + + +class PingAnsStruct : public PDU { +public: + PingAnsStruct(); + PingAnsStruct(const PingAnsStruct&); + UInt64 mResponseId; + std::vector<PingInformationStruct*> mPingInfo; + + + PDUMemberFunctions +}; + + +class TunnelReqStruct : public PDU { +public: + TunnelReqStruct(); + TunnelReqStruct(const TunnelReqStruct&); + UInt16 mApplication; + resip::Data mDialogId; + resip::Data mApplicationPdu; + + + PDUMemberFunctions +}; + + +typedef enum { + reserved_data_model = 0, + single_value = 1, + array = 2, + dictionary = 3 +} DataModel; + +class DataValueStruct : public PDU { +public: + DataValueStruct(); + DataValueStruct(const DataValueStruct&); + Boolean mExists; + resip::Data mValue; + + + PDUMemberFunctions +}; + + +class ArrayEntryStruct : public PDU { +public: + ArrayEntryStruct(); + ArrayEntryStruct(const ArrayEntryStruct&); + UInt32 mIndex; + DataValueStruct* mValue; + + + PDUMemberFunctions +}; + + +class DictionaryKeyStruct : public PDU { +public: + DictionaryKeyStruct(); + DictionaryKeyStruct(const DictionaryKeyStruct&); + resip::Data mKey; + + + PDUMemberFunctions +}; + + +class DictionaryEntryStruct : public PDU { +public: + DictionaryEntryStruct(); + DictionaryEntryStruct(const DictionaryEntryStruct&); + DictionaryKeyStruct* mKey; + DataValueStruct* mValue; + + + PDUMemberFunctions +}; + + +class StoredDataValueStruct : public PDU { +public: + StoredDataValueStruct(); + StoredDataValueStruct(const StoredDataValueStruct&); + DataModel mModel; + struct mSingleValue_ { + DataValueStruct* mSingleValueEntry; + } mSingleValue; + struct mArray_ { + ArrayEntryStruct* mArrayEntry; + } mArray; + struct mDictionary_ { + DictionaryEntryStruct* mDictionaryEntry; + } mDictionary; + + + PDUMemberFunctions +}; + + +class StoredDataStruct : public PDU { +public: + StoredDataStruct(); + StoredDataStruct(const StoredDataStruct&); + UInt64 mStorageTime; + UInt32 mLifetime; + StoredDataValueStruct* mValue; + SignatureStruct* mSignature; + + + PDUMemberFunctions +}; + + +class StoreKindDataStruct : public PDU { +public: + StoreKindDataStruct(); + StoreKindDataStruct(const StoreKindDataStruct&); + UInt32 mKind; + DataModel mDataModel; + UInt64 mGenerationCounter; + std::vector<StoredDataStruct*> mValues; + + + PDUMemberFunctions +}; + + +class StoreReqStruct : public PDU { +public: + StoreReqStruct(); + StoreReqStruct(const StoreReqStruct&); + ResourceIdStruct* mResource; + UInt8 mReplicaNumber; + std::vector<StoreKindDataStruct*> mKindData; + + + PDUMemberFunctions +}; + + +class StoreKindResponseStruct : public PDU { +public: + StoreKindResponseStruct(); + StoreKindResponseStruct(const StoreKindResponseStruct&); + UInt32 mKind; + UInt64 mGenerationCounter; + std::vector<NodeIdStruct*> mReplicas; + + + PDUMemberFunctions +}; + + +class StoreAnsStruct : public PDU { +public: + StoreAnsStruct(); + StoreAnsStruct(const StoreAnsStruct&); + std::vector<StoreKindResponseStruct*> mKindResponses; + + + PDUMemberFunctions +}; + + +class ArrayRangeStruct : public PDU { +public: + ArrayRangeStruct(); + ArrayRangeStruct(const ArrayRangeStruct&); + UInt32 mFirst; + UInt32 mLast; + + + PDUMemberFunctions +}; + + +class StoredDataSpecifierStruct : public PDU { +public: + StoredDataSpecifierStruct(); + StoredDataSpecifierStruct(const StoredDataSpecifierStruct&); + UInt32 mKind; + DataModel mModel; + UInt64 mGeneration; + struct mSingleValue_ { + } mSingleValue; + struct mArray_ { + std::vector<ArrayRangeStruct*> mIndices; + } mArray; + struct mDictionary_ { + std::vector<DictionaryKeyStruct*> mKeys; + } mDictionary; + + + PDUMemberFunctions +}; + + +class FetchReqStruct : public PDU { +public: + FetchReqStruct(); + FetchReqStruct(const FetchReqStruct&); + ResourceIdStruct* mResource; + std::vector<StoredDataSpecifierStruct*> mSpecifiers; + + + PDUMemberFunctions +}; + + +class FetchKindResponseStruct : public PDU { +public: + FetchKindResponseStruct(); + FetchKindResponseStruct(const FetchKindResponseStruct&); + UInt32 mKind; + UInt64 mGeneration; + std::vector<StoredDataStruct*> mValues; + + + PDUMemberFunctions +}; + + +class FetchAnsStruct : public PDU { +public: + FetchAnsStruct(); + FetchAnsStruct(const FetchAnsStruct&); + std::vector<FetchKindResponseStruct*> mKindResponses; + + + PDUMemberFunctions +}; + + +class RemoveReqStruct : public PDU { +public: + RemoveReqStruct(); + RemoveReqStruct(const RemoveReqStruct&); + ResourceIdStruct* mResource; + std::vector<StoredDataSpecifierStruct*> mSpecifiers; + + + PDUMemberFunctions +}; + + +class RemoveAnsStruct : public PDU { +public: + RemoveAnsStruct(); + RemoveAnsStruct(const RemoveAnsStruct&); + std::vector<StoreKindResponseStruct*> mKindResponses; + + + PDUMemberFunctions +}; + + +class FindReqStruct : public PDU { +public: + FindReqStruct(); + FindReqStruct(const FindReqStruct&); + ResourceIdStruct* mResource; + std::vector<UInt32> mKinds; + + + PDUMemberFunctions +}; + + +class FindKindDataStruct : public PDU { +public: + FindKindDataStruct(); + FindKindDataStruct(const FindKindDataStruct&); + UInt32 mKind; + ResourceIdStruct* mClosest; + + + PDUMemberFunctions +}; + + +class FindAnsStruct : public PDU { +public: + FindAnsStruct(); + FindAnsStruct(const FindAnsStruct&); + std::vector<FindKindDataStruct*> mResults; + + + PDUMemberFunctions +}; + + +class TurnServerStruct : public PDU { +public: + TurnServerStruct(); + TurnServerStruct(const TurnServerStruct&); + UInt8 mIteration; + IpAddressAndPortStruct* mServerAddress; + + + PDUMemberFunctions +}; + + +typedef enum { + sip_registration_uri = 1, + sip_registration_route = 2 +} SipRegistrationType; + +class SipRegistrationStruct : public PDU { +public: + SipRegistrationStruct(); + SipRegistrationStruct(const SipRegistrationStruct&); + SipRegistrationType mType; + struct mSipRegistrationUri_ { + resip::Data mUri; + } mSipRegistrationUri; + struct mSipRegistrationRoute_ { + resip::Data mContactPrefs; + std::vector<DestinationStruct*> mDestinationList; + } mSipRegistrationRoute; + + + PDUMemberFunctions +}; + + +typedef enum { + reserved_chord = 0, + peer_ready = 1, + neighbors = 2, + full = 3 +} ChordUpdateType; + +class ChordUpdateStruct : public PDU { +public: + ChordUpdateStruct(); + ChordUpdateStruct(const ChordUpdateStruct&); + ChordUpdateType mType; + struct mPeerReady_ { + } mPeerReady; + struct mNeighbors_ { + std::vector<NodeIdStruct*> mPredecessors; + std::vector<NodeIdStruct*> mSuccessors; + } mNeighbors; + struct mFull_ { + std::vector<NodeIdStruct*> mPredecessors; + std::vector<NodeIdStruct*> mSuccessors; + std::vector<NodeIdStruct*> mFingers; + } mFull; + + + PDUMemberFunctions +}; + + +class ChordRouteQueryAnsStruct : public PDU { +public: + ChordRouteQueryAnsStruct(); + ChordRouteQueryAnsStruct(const ChordRouteQueryAnsStruct&); + NodeIdStruct* mNextId; + + + PDUMemberFunctions +}; + + +} + +#endif diff --git a/src/libs/resiprocate/p2p/NodeId.cxx b/src/libs/resiprocate/p2p/NodeId.cxx new file mode 100644 index 00000000..e7f62d3c --- /dev/null +++ b/src/libs/resiprocate/p2p/NodeId.cxx @@ -0,0 +1,159 @@ +#include <algorithm> +#include <assert.h> + +#include "rutil/Data.hxx" +#include "rutil/DataStream.hxx" +#include "p2p/NodeId.hxx" +#include "p2p/ResourceId.hxx" + +using namespace p2p; + +NodeId::NodeId() +{ + assert( sizeof(mNodeId.mHigh) == 8 ); +} + +NodeId::NodeId(const s2c::NodeIdStruct& nid) : mNodeId(nid) +{ +} + +NodeId::NodeId(const ResourceId& rid) +{ + assert(rid.value().size() == 16); + resip::Data buffer(rid.value()); + resip::iDataStream strm(buffer); + mNodeId.decode(strm); +} + +NodeId& NodeId::operator=(const NodeId& rhs) +{ + mNodeId = rhs.mNodeId; + return *this; +} + +bool +NodeId::operator<(const NodeId &r) const +{ + return ( (mNodeId.mHigh < r.mNodeId.mHigh) || + (mNodeId.mHigh == r.mNodeId.mHigh && mNodeId.mLow < r.mNodeId.mLow)); +} + +bool +NodeId::operator<=(const NodeId& rhs) const +{ + return *this == rhs || *this < rhs; +} + +bool +NodeId::operator==(const NodeId& rhs) const +{ + return !(*this < rhs) && !(rhs < *this); +} + +NodeId +NodeId::add2Pow( int power ) const +{ + assert( power < 128 ); + assert( power >= 0 ); + NodeId ret; + + ret = *this; + + if ( power >= 64 ) + { + // working on high word + power -= 64; + if (power>0) + { + long long inc = 1; + inc <<= (power-1); + ret.mNodeId.mHigh += inc; + } + } + else + { + // working on low word + if (power>0) + { + long long inc = 1; + inc <<= (power-1); + ret.mNodeId.mLow += inc; + } + } + + return ret; +} + +const s2c::NodeIdStruct& +NodeId::getNodeIdStruct() const +{ + return mNodeId; +} + + +const resip::Data +NodeId::encodeToNetwork() const +{ + resip::Data d; + resip::DataStream strm(d); + + mNodeId.encode(strm); + strm.flush(); + + return d; +} + +std::ostream& +p2p::operator<<( std::ostream& strm, const NodeId& node ) +{ + strm << "H:" << node.mNodeId.mHigh << " L:" << node.mNodeId.mLow; + return strm; +} + + +CompressedId::CompressedId(const resip::Data& cid) +{ + assert(0); +} + +bool +CompressedId::operator==(const CompressedId& rhs) const +{ + return false; +} + + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/NodeId.hxx b/src/libs/resiprocate/p2p/NodeId.hxx new file mode 100644 index 00000000..498e9404 --- /dev/null +++ b/src/libs/resiprocate/p2p/NodeId.hxx @@ -0,0 +1,86 @@ +#ifndef __P2P_NODE_ID_HXX +#define __P2P_NODE_ID_HXX + +#include <iosfwd> +#include "p2p/MessageStructsGen.hxx" + +namespace p2p +{ + +class ResourceId; + +class NodeId +{ + public: + NodeId(); + NodeId(const s2c::NodeIdStruct& nid); + NodeId(const ResourceId& rid); + NodeId& operator=(const NodeId& data); + + bool operator<(const NodeId& rhs) const; + bool operator<=(const NodeId& rhs) const; + bool operator==(const NodeId& rhs) const; + + // returns a node ID that is the value of this node plus 2^power passed + // in. In chord terms, add2Pow( 127 ) is half way around the ring + NodeId add2Pow( int power ) const; + + const s2c::NodeIdStruct& getNodeIdStruct() const; + const resip::Data encodeToNetwork() const; + + friend std::ostream& operator<<( std::ostream& strm, const NodeId& node ); + + private: + // NOTE: this should be 128 bits + s2c::NodeIdStruct mNodeId; + +}; + +class CompressedId +{ + public: + CompressedId(const resip::Data& cid); + bool operator==(const CompressedId& rhs) const; +}; + +std::ostream& operator<<( std::ostream& strm, const p2p::NodeId& node ); + +} + + + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/P2PStack.cxx b/src/libs/resiprocate/p2p/P2PStack.cxx new file mode 100644 index 00000000..2002dce5 --- /dev/null +++ b/src/libs/resiprocate/p2p/P2PStack.cxx @@ -0,0 +1,68 @@ + +#include "p2p/P2PStack.hxx" +#include <rutil/DnsUtil.hxx> + +using namespace p2p; + +P2PStack::P2PStack(const Profile& profile) : + mProfile(profile), + mDispatcher(), + mTransporter(mProfile), + mChord(mProfile, mDispatcher, mTransporter), + mForwarder(mProfile, mDispatcher, mTransporter, mChord) +{ + mDispatcher.init(mForwarder); +} + +void +P2PStack::run() +{ + while (1) + { + assert(0); + //process(1000); + } + +} + +void +P2PStack::process(int waitTimeMS) +{ + mTransporter.process(waitTimeMS); + mForwarder.process(waitTimeMS); +} + + +void +P2PStack::join() +{ + mChord.joinOverlay(); +} + + +void +P2PStack::listenOn(int port) +{ + resip::TransportType transport = resip::TCP; + + struct in_addr addr; + if(resip::DnsUtil::inet_pton("0.0.0.0", addr)==0) + { + assert(0); + } + + sockaddr_in addr_in; + addr_in.sin_family = AF_INET; + addr_in.sin_addr = addr; + addr_in.sin_port = htons(port); + + resip::GenericIPAddress address(addr_in); + mTransporter.addListener(transport,address); +} + + +ResourceId +P2PStack::getIdFromResourceName( const resip::Data& resourceName ) +{ + return mChord.resourceId(resourceName); +} diff --git a/src/libs/resiprocate/p2p/P2PStack.hxx b/src/libs/resiprocate/p2p/P2PStack.hxx new file mode 100644 index 00000000..27750863 --- /dev/null +++ b/src/libs/resiprocate/p2p/P2PStack.hxx @@ -0,0 +1,40 @@ +#if !defined(P2PStack_hxx) +#define P2PStack_hxx + +#include "p2p/Profile.hxx" +#include "p2p/Dispatcher.hxx" +#include "p2p/ChordTopology.hxx" +#include "p2p/SelectTransporter.hxx" +#include "p2p/ForwardingLayer.hxx" + +namespace p2p +{ + +class P2PStack +{ + public: + P2PStack(const Profile& profile); + + void run(); // this never returns + void process(int waitTimeMS); // run a time slice and return + + void listenOn(int port); + void join(); + + ResourceId getIdFromResourceName( const resip::Data& resourceName ); + + + private: + Profile mProfile; + + Dispatcher mDispatcher; + SelectTransporter mTransporter; + ChordTopology mChord; // TODO - this needs to be changed to a Topology + // object + ForwardingLayer mForwarder; +}; + + +} + +#endif diff --git a/src/libs/resiprocate/p2p/P2PSubsystem.cxx b/src/libs/resiprocate/p2p/P2PSubsystem.cxx new file mode 100644 index 00000000..45cf2187 --- /dev/null +++ b/src/libs/resiprocate/p2p/P2PSubsystem.cxx @@ -0,0 +1,37 @@ +#include "P2PSubsystem.hxx" + +P2PSubsystem P2PSubsystem::P2P("P2P"); + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/P2PSubsystem.hxx b/src/libs/resiprocate/p2p/P2PSubsystem.hxx new file mode 100644 index 00000000..a88f33e0 --- /dev/null +++ b/src/libs/resiprocate/p2p/P2PSubsystem.hxx @@ -0,0 +1,54 @@ +#ifndef P2P_SUBSYSTEM_HXX +#define P2P_SUBSYSTEM_HXX + +#include <iostream> +#include "rutil/Subsystem.hxx" +#include "rutil/Logger.hxx" + +class P2PSubsystem : public resip::Subsystem +{ + public: + static P2PSubsystem P2P; + + private: + explicit P2PSubsystem(const char* rhs) : resip::Subsystem(rhs) {}; + explicit P2PSubsystem(const resip::Data& rhs); + P2PSubsystem& operator=(const resip::Data& rhs); +}; + +#endif + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/ParsingTest.cxx b/src/libs/resiprocate/p2p/ParsingTest.cxx new file mode 100644 index 00000000..77d485a1 --- /dev/null +++ b/src/libs/resiprocate/p2p/ParsingTest.cxx @@ -0,0 +1,230 @@ +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Data.hxx" +#include "p2p/ChordUpdate.hxx" +#include "p2p/Join.hxx" +#include "p2p/Connect.hxx" +#include "p2p/Update.hxx" +#include "p2p/MessageStructsGen.hxx" +#include "p2p/Candidate.hxx" + +#include "rutil/DataStream.hxx" +#include "rutil/Random.hxx" + +#include "p2p/P2PSubsystem.hxx" +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P + +#include <iostream> + +using namespace s2c; +using namespace resip; // approved by Adam +using namespace p2p; + +void +TestConnect() +{ + NodeId node; + DestinationId dest(node); + resip::Data noData; + + //const DestinationId &dest, const resip::Data &frag, const resip::Data &password, UInt16 application, const resip::Data &role, const std::vector<Candidate> &candidates + + resip::Data password = "password"; + UInt16 application = 100; + resip::Data role = "test"; + + std::vector<Candidate> candidates; + + ConnectReq *connect = new ConnectReq(dest, noData, password, application, role, candidates); + assert(connect); + assert(connect->getType() == Message::ConnectReqType); + + resip::Data encodedData = connect->encodePayload(); + assert(encodedData.size()); + + Message *message = Message::parse(encodedData); + assert(message->getType() == Message::ConnectReqType); + assert(*message == *connect); + + ConnectReq *connectReq = static_cast<ConnectReq *>(message); + assert(connectReq->getPassword() == password); + assert(connectReq->getRole() == role); + assert(connectReq->getApplication() == application); + + Candidate c("candidate:1 1 UDP 2130706431 10.0.1.1 8998 typ host"); + assert(connectReq->getCandidates().empty()); + + candidates.push_back(c); + ConnectReq *connect2 = new ConnectReq(dest, noData, password, application, role, candidates); + assert(connect2); + + resip::Data encodedData2 = connect2->encodePayload(); + Message *message2 = Message::parse(encodedData2); + assert(message2); + + ConnectReq *connectReq3 = static_cast<ConnectReq *>(message2); + assert(connectReq3); + assert(!connectReq3->getCandidates().empty()); + + std::vector<Candidate> newCandidates = connectReq3->getCandidates(); + assert(newCandidates[0].getIceString() == c.getIceString()); +} + +void +TestUpdate() +{ + NodeId node; + DestinationId dest(node); + + // Test Update Request + resip::Data noData; + UpdateReq *update = new UpdateReq(dest, noData); + assert(update->getType() == Message::UpdateReqType); + + // check for non zero encoded payload + resip::Data encodedMessage = update->encodePayload(); + assert(encodedMessage.size()); + + Message *compareMessage = Message::parse(encodedMessage); + assert(compareMessage->getType() == Message::UpdateReqType); + + // check that messages are equal + assert(*compareMessage == *update); + resip::Data secondMessage = compareMessage->encodePayload(); + + // check that two similar messages encode the same + assert(secondMessage == encodedMessage); + + // Test message type on a response + UpdateAns *updateAns = update->makeUpdateResponse(noData); + assert(updateAns->getType() == Message::UpdateAnsType); + + // Check transaction ID + assert(updateAns->getTransactionId() == update->getTransactionId()); +} + +void +TestChordUpdate() +{ + DebugLog(<< "Testing ChordUpdate"); + + NodeId node; + DestinationId dest(node); + + ChordUpdate update; + update.setUpdateType(ChordUpdate::PeerReady); + resip::Data chordData = update.encode(); + assert(chordData.size()); + + UpdateReq *updateReq = new UpdateReq(dest, chordData); + resip::Data encodedMessage = updateReq->encodePayload(); + + Message *compareMessage = Message::parse(encodedMessage); + assert(*compareMessage == *updateReq); + + resip::Data reqBlob = compareMessage->getRequestMessageBody(); + assert(reqBlob.size()); + + ChordUpdate update2(reqBlob); + assert(update2 == update); + + UpdateAns *updateAns = updateReq->makeUpdateResponse(update.encode()); + assert(updateAns); + + assert(updateAns->getTransactionId() == updateReq->getTransactionId()); + + assert(updateAns->getType() == Message::UpdateAnsType); +} + +void +TestJoin() +{ + DebugLog(<< "Testing Join"); + + NodeId node; + DestinationId dest(node); + + JoinReq *joinReq = new JoinReq(dest, node); + assert(joinReq->getType() == Message::JoinReqType); + resip::Data encodedData = joinReq->encodePayload(); + + Message *msg = Message::parse(encodedData); + assert(msg); + assert(msg->getType() == Message::JoinReqType); + + JoinReq *joinReqMsg = static_cast<JoinReq *>(msg); + assert(joinReqMsg->getNodeId() == node); + + ResourceId rid(Random::getRandom(16)); + NodeId nid(rid); + + JoinReq *newReq = new JoinReq(dest, nid); + assert(newReq->getNodeId() == nid); + Message *testMessage = Message::parse(newReq->encodePayload()); + assert(testMessage->getType() == Message::JoinReqType); + + JoinReq *joinReq2 = static_cast<JoinReq *>(testMessage); + assert(joinReq2->getNodeId() == nid); + + JoinAns *ans = joinReq2->makeJoinResponse(); + assert(ans->getType() == Message::JoinAnsType); + assert(!ans->isRequest()); + + resip::Data encodedAnswer = ans->encodePayload(); + Message *testMsg = Message::parse(encodedAnswer); + assert(testMsg); + assert(testMsg->getType() == Message::JoinAnsType); +} + +void +TestMessages() +{ + TestJoin(); + TestUpdate(); + TestChordUpdate(); + TestConnect(); +} + +int main() +{ + resip::Log::initialize(resip::Data("cerr"), + resip::Data("DEBUG"),resip::Data("ParsingTest")); + +#if 0 + + std::cout << "ctor" << std::endl; + ForwardingLayerMessageStruct hdr; + std::cout << "done" << std::endl; + + NodeId node; + DestinationId dest(node); + + resip::Data d; + std::vector<Candidate> v; + Message *m2 = new ConnectReq(dest, d, d, 0, d, v); + + p2p::NodeId n; + p2p::Message *m = new p2p::JoinReq(dest, n,d); + m->setOverlayName("duane"); + resip::Data encodedMessage = m->encodePayload(); + + DebugLog(<< "attempting to parse"); + + Message *newMessage = Message::parse(encodedMessage); + + std::cout << encodedMessage.hex() << std::endl; + + ForwardingLayerMessageStruct hdr2; + resip::DataStream is(encodedMessage); + hdr2.decode(is); + +#endif + + TestMessages(); + +// Data d; +// DataStream ds(d); +// hdr.encode(ds); +// Data foo = Data::from(hdr); + return 0; +} diff --git a/src/libs/resiprocate/p2p/Postable.hxx b/src/libs/resiprocate/p2p/Postable.hxx new file mode 100644 index 00000000..12b2bf4f --- /dev/null +++ b/src/libs/resiprocate/p2p/Postable.hxx @@ -0,0 +1,54 @@ +#ifndef P2P_Postable_hxx +#define P2P_Postable_hxx + +#include <memory> + +namespace p2p +{ + +template<class T> +class Postable +{ + public: + virtual ~Postable(){} + virtual void post(std::auto_ptr<T> posted)=0; +}; + +} + +#endif + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/Profile.hxx b/src/libs/resiprocate/p2p/Profile.hxx new file mode 100644 index 00000000..f5212bf9 --- /dev/null +++ b/src/libs/resiprocate/p2p/Profile.hxx @@ -0,0 +1,99 @@ +#ifndef __P2P_PROFILE_HXX +#define __P2P_PROFILE_HXX 1 + +#include <openssl/evp.h> +#include <openssl/x509.h> + +#ifndef WIN32 +#include <arpa/inet.h> // For htonl +#endif + +#include "rutil/Data.hxx" +#include "rutil/GenericIPAddress.hxx" + +#include "p2p/NodeId.hxx" +#include "p2p/UserName.hxx" + +namespace p2p +{ + +enum {RELOAD_APPLICATION_ID = 8675}; + +class Profile +{ +public: + Profile() : mNodeId(), mNumInitialFingers(8) {} + virtual ~Profile() {;} + + virtual const X509 *getCertificate() { return 0; } + virtual const EVP_PKEY *getPrivateKey() { return 0; } + + virtual resip::Data& signatureDigest() { return mSignatureDigest; } + virtual const resip::Data& signatureDigest() const { return mSignatureDigest; } + + virtual resip::Data& overlayName() { return mOverlayName; } + virtual const resip::Data& overlayName() const { return mOverlayName; } + + virtual bool& isBootstrap() { return mBootstrap; } + virtual const bool isBootstrap() const { return mBootstrap; } + + virtual NodeId& nodeId() { return mNodeId; } + virtual const NodeId nodeId() const { return mNodeId; } + + virtual UserName& userName() { return mUserName; } + virtual const UserName& userName() const { return mUserName; } + + virtual unsigned int& numInitialFingers() { return mNumInitialFingers; } + virtual const unsigned int numInitialFingers() const { return mNumInitialFingers; } + + virtual std::vector<resip::GenericIPAddress>& bootstrapNodes() { return mBootstrapNodes; } + virtual const std::vector<resip::GenericIPAddress>& bootstrapNodes() const { return mBootstrapNodes; } + + private: + resip::Data mOverlayName; + resip::Data mSignatureDigest; + NodeId mNodeId; + UserName mUserName; + unsigned int mNumInitialFingers; + std::vector<resip::GenericIPAddress> mBootstrapNodes; + bool mBootstrap; +}; + +} + + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/ResourceId.cxx b/src/libs/resiprocate/p2p/ResourceId.cxx new file mode 100644 index 00000000..7e8e28a5 --- /dev/null +++ b/src/libs/resiprocate/p2p/ResourceId.cxx @@ -0,0 +1,36 @@ +#include "p2p/ResourceId.hxx" + +using namespace p2p; + +ResourceId::ResourceId() +{ + +} + +ResourceId::ResourceId(const resip::Data& rid) : + mResourceId(rid) +{ +} + +ResourceId::ResourceId(const ResourceId& rhs) : + mResourceId(rhs.mResourceId) +{ +} + +resip::Data& +ResourceId::operator=(const ResourceId& rhs) +{ + return mResourceId = rhs.mResourceId; +} + +bool +ResourceId::operator==(const ResourceId& rhs) const +{ + return mResourceId == rhs.mResourceId; +} + +const resip::Data& +ResourceId::value() const +{ + return mResourceId; +} diff --git a/src/libs/resiprocate/p2p/ResourceId.hxx b/src/libs/resiprocate/p2p/ResourceId.hxx new file mode 100644 index 00000000..827581df --- /dev/null +++ b/src/libs/resiprocate/p2p/ResourceId.hxx @@ -0,0 +1,61 @@ +#ifndef __P2P_RESOURCE_ID_HXX +#define __P2P_RESOURCE_ID_HXX 1 + +#include "rutil/Data.hxx" + +namespace p2p +{ + +class ResourceId +{ + public: + ResourceId(); + ResourceId(const resip::Data& rid); + ResourceId(const ResourceId& rhs); + + const resip::Data& value() const; + resip::Data& operator= ( const ResourceId& rhs ); + bool operator==(const ResourceId& rhs) const; + + private: + + resip::Data mResourceId; +}; + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/SelectTransporter.cxx b/src/libs/resiprocate/p2p/SelectTransporter.cxx new file mode 100644 index 00000000..3e326ea4 --- /dev/null +++ b/src/libs/resiprocate/p2p/SelectTransporter.cxx @@ -0,0 +1,686 @@ +#include "rutil/GenericIPAddress.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Logger.hxx" + +#include "p2p/SelectTransporter.hxx" +#include "p2p/Profile.hxx" +#include "p2p/TransporterMessage.hxx" +#include "p2p/FlowId.hxx" +#include "p2p/Message.hxx" +#include "p2p/Candidate.hxx" +#include "p2p/p2p.hxx" +#include "p2p/P2PSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P + +namespace p2p +{ + +SelectTransporter::SelectTransporter ( Profile &configuration ) + : Transporter(configuration), mHasBootstrapSocket(false) +{ + resip::Data localIp = resip::DnsUtil::getLocalIpAddress(); + resip::DnsUtil::inet_pton(localIp, mLocalAddress); + mNextPort = 30000; +} + +SelectTransporter::~SelectTransporter() +{ + // Tear down any of the open sockets we have hanging around. + std::map<NodeId, FlowId>::iterator i; + for (i = mNodeFlowMap.begin(); i != mNodeFlowMap.end(); i++) + { + resip::closeSocket((i->second).getSocket()); + } + + // And kill the listeners + ListenerMap::iterator j; + for (j = mListenerMap.begin(); j != mListenerMap.end(); j++) + { + resip::closeSocket(j->second.first); + } + +} + +//---------------------------------------------------------------------- +// Impls follow + +/** + @note This method is to be called by bootstrap nodes only -- all other + modes need to use ICE-allocated addresses. +*/ +void +SelectTransporter::addListenerImpl(resip::TransportType transport, + resip::GenericIPAddress &address) +{ + int status; + assert(!mHasBootstrapSocket); + assert(transport == resip::TCP); + + DebugLog(<< "Adding bootstrap listener"); + + struct sockaddr_in addr = address.v4Address; + + mBootstrapSocket = ::socket(AF_INET, SOCK_STREAM, 0); + if (!mBootstrapSocket) {ErrLog(<< "::socket() failed, errno " << resip::getErrno());} + + int on = 1; +#if !defined(WIN32) + ::setsockopt ( mBootstrapSocket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); +#else + ::setsockopt ( mBootstrapSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)); +#endif + + status = ::bind(mBootstrapSocket, reinterpret_cast<sockaddr *>(&addr), + sizeof(struct sockaddr_in)); + if (status) { ErrLog( << "Cannot ::bind, errno " << resip::getErrno()); } + + status = ::listen(mBootstrapSocket, 120); + if (status) { ErrLog( << "Cannot ::listen, errno " << resip::getErrno()); } + + mHasBootstrapSocket = true; +} + +void +SelectTransporter::sendImpl(NodeId nodeId, std::auto_ptr<p2p::Message> msg) +{ + DebugLog( << "sending " << msg->brief() << " to " << nodeId); + if (msg->getTTL() <= 1) + { + InfoLog(<< "TTL Exhausted -- dropping message."); + return; + } + + msg->decrementTTL(); + + std::map<NodeId, FlowId>::iterator i; + i = mNodeFlowMap.find(nodeId); + + if (i == mNodeFlowMap.end()) + { + // XXX FIX ME -- should send error to application + ErrLog( << "Cannot send -- node not in flow map"); + return; + } + + //********************************************************************** + // XXX For datagram transports, we would need to fragment here. + //********************************************************************** + + resip::Data data; + data = msg->encodePayload(); + + size_t bytesSent = ::send((i->second).getSocket(), data.data(), data.size(), 0); + // XXX should check send response, and inform app of error if fail + + if (bytesSent != data.size()) + { + ErrLog( << "Cannot send -- ::send returned " << bytesSent << " errno " << resip::getErrno()); + assert(0); + } + else + { + DebugLog(<< "sent " << msg->brief() << " over " << i->second << "bytes=" << bytesSent ); + } +} + +void +SelectTransporter::sendImpl(FlowId flowId, std::auto_ptr<resip::Data> data) +{ + DebugLog( << "sending raw data to: " << flowId); + + size_t bytesSent = ::send(flowId.getSocket(), data->data(), data->size(), 0); + // XXX should check send response, and inform app of error if fail + + if (bytesSent != data->size()) + { + ErrLog(<< "Cannot send -- ::send returned " << bytesSent << " errno " << resip::getErrno()); + assert(0); + } +} + +void +SelectTransporter::collectCandidatesImpl(UInt64 tid, NodeId nodeId, unsigned short appId) +{ + // For right now, we just return one candidate: a single TCP + // listener. And we return it right away. + DebugLog(<< "Collection candidates for application " << appId); + + ListenerMap::iterator i; + resip::GenericIPAddress addrPort; + int status; + + i = mListenerMap.find(std::make_pair(nodeId, appId)); + + // If we don't already have a listener, we need to create + // a new one and throw it in the listener map + if (i == mListenerMap.end()) + { + DebugLog(<< "Adding new listener for application " << appId << " on port " << mNextPort); + struct sockaddr_in addr; + resip::Socket s; + int yes=1; + + int retry=5; + + while(retry--) + { +#ifdef HAVE_sockaddr_in_len + addr.sin_len = sizeof(struct sockaddr_in); +#endif + addr.sin_family = AF_INET; + addr.sin_port = htons(mNextPort++); + memset(&addr.sin_addr, 0, sizeof(addr.sin_addr)); + memset(addr.sin_zero, 0, sizeof(addr.sin_zero)); + + + s = ::socket(AF_INET, SOCK_STREAM, 0); + +#if !defined(WIN32) + ::setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); +#else + ::setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(yes)); +#endif + + if (!s) {ErrLog(<< "::socket() failed, errno " << resip::getErrno());} + + DebugLog(<< "Binding to port " << ntohs(addr.sin_port)); + + status = ::bind(s, reinterpret_cast<sockaddr *>(&addr), + sizeof(struct sockaddr_in)); + if (status) { + ErrLog( << "Cannot ::bind, errno " << resip::getErrno()); + continue; + } + } + assert(status==0); + + status = ::listen(s, 5); + if (status) { ErrLog( << "Cannot ::listen, errno " << resip::getErrno()); } + + addrPort.v4Address = addr; + + mListenerMap.insert(ListenerMap::value_type( + std::make_pair(nodeId, appId), + std::make_pair(s,addrPort))); + + i = mListenerMap.find(std::make_pair(nodeId, appId)); + assert(i != mListenerMap.end()); + } + else + { + DebugLog(<< "Found existing listener for application " << appId); + addrPort = i->second.second; + } + + std::vector<Candidate> candidates; + Candidate c(resip::TCP, addrPort); // XXX -- SHOULD BE TLS + candidates.push_back(c); + + LocalCandidatesCollected *lcc = new LocalCandidatesCollected(tid, nodeId, appId, candidates); + mRxFifo->add(lcc); +} + +void +SelectTransporter::connectImpl(resip::GenericIPAddress &bootstrapServer) +{ + unsigned short application = RELOAD_APPLICATION_ID; + resip::Socket s; + + DebugLog(<<"Trying to connect to bootstrap server"); + + s = ::socket(AF_INET, SOCK_STREAM, 0); + if (!s) + { + ErrLog(<< "::socket() failed"); + assert(0); + } + + int status = ::connect(s, &(bootstrapServer.address), sizeof(sockaddr_in)); + if (status) { ErrLog( << "Cannot ::connect, errno " << resip::getErrno()); assert(0); return; } + + DebugLog(<<"Connect succeeded"); + + // Get the remote node ID from the incoming socket + unsigned char buffer[16]; + + size_t bytesRead = readSocket(s, (char*)buffer, sizeof(buffer)); + DebugLog(<< "Read#1" << bytesRead); + + if (bytesRead != sizeof(buffer)) + { + ErrLog( << "Cannot ::read -- returned " << bytesRead << " errno " << resip::getErrno()); + assert(0); + } + s2c::NodeIdStruct nid; + nid.mHigh = *((UInt64*)(buffer)); + nid.mLow = *((UInt64*)(buffer+sizeof(UInt64))); + + NodeId nodeId(nid); + FlowId flowId(nodeId, application, s, *mRxFifo); + + mNodeFlowMap.insert(std::map<NodeId, FlowId>::value_type(nodeId, flowId)); + + // ********** XXX REMOVE THIS WHEN WE GO TO TLS/DTLS XXX ********** + // Blow our node ID out on the wire (because there is no cert) + + resip::Data ourNid=mConfiguration.nodeId().encodeToNetwork(); + size_t bytesSent = ::send(s,ourNid.data(), ourNid.size(), 0); + if (bytesSent != ourNid.size()) + { + ErrLog( << "Cannot ::send -- returned " << bytesSent << " errno " << resip::getErrno()); + } + + + DebugLog(<< "Connected to server: " << flowId << " sending ConnectionOpened to forwarding layer"); + ConnectionOpened *co = new ConnectionOpened(flowId, + application, + resip::TCP, + false /* inbound? */, + 0 /* no cert for you */); + mRxFifo->add(co); + //assert(0); +} + +void +SelectTransporter::connectImpl(NodeId nodeId, + std::vector<Candidate> remoteCandidates, + resip::GenericIPAddress &stunTurnServer) +{ + DebugLog(<< "connectImpl invoked"); + + connectImpl(nodeId, remoteCandidates, RELOAD_APPLICATION_ID, + *mRxFifo, stunTurnServer); +} + +void +SelectTransporter::connectImpl(NodeId nodeId, + std::vector<Candidate> remoteCandidates, + unsigned short application, + resip::Fifo<Event>& dataFifo, + resip::GenericIPAddress &stunTurnServer) +{ + // XXX Right now, we just grab the first candidate out of the array + // and connect to it. Whee! + + DebugLog(<< "connectImpl invoked"); + + resip::Socket s; + Candidate candidate = remoteCandidates.front(); + + // Right now, we're only implementing stream stuff. + // Later on, we'll have to have different processing + // based on the transports -- but this will likely be + // hidden from us by the ICE library + assert (candidate.getTransportType() == resip::TCP + || candidate.getTransportType() == resip::TLS); + + s = ::socket(AF_INET, SOCK_STREAM, 0); + if (!s) {ErrLog(<< "::socket() failed, errno " << resip::getErrno());} + + int status = ::connect(s, &(candidate.getAddress().address), sizeof(sockaddr_in)); + if (status) { ErrLog( << "Cannot ::connect, errno " << resip::getErrno()); } + + + // ********** XXX REMOVE THIS WHEN WE GO TO TLS/DTLS XXX ********** + // Blow our node ID out on the wire (because there is no cert) + const resip::Data nid = mConfiguration.nodeId().encodeToNetwork(); + size_t bytesSent = ::send(s, nid.data(), nid.size(), 0); + if (bytesSent != nid.size()) + { + ErrLog( << "Cannot ::send -- returned " << bytesSent << " errno " << resip::getErrno()); + } + // ********** XXX REMOVE THIS WHEN WE GO TO TLS/DTLS XXX ********** + + // Get the remote node ID from the incoming socket + char buffer[16]; + size_t bytesRead = readSocket(s, buffer, sizeof(buffer)); + DebugLog(<< "Read#2 " << bytesRead); + if (bytesRead != sizeof(buffer)) + { + ErrLog( << "Cannot ::read -- returned " << bytesRead << " errno " << resip::getErrno()); + assert(0); + } + + // Parse the node id + s2c::NodeIdStruct nids; + resip::Data data(resip::Data::Borrow, buffer, sizeof(buffer)); + resip::DataStream strm(data); + nids.decode(strm); + NodeId nodeId2(nids); + + FlowId flowId(nodeId2, application, s, *mRxFifo); + + DebugLog(<< "SelectTransporter: connection to node " << nodeId2); + + mNodeFlowMap.insert(std::map<NodeId, FlowId>::value_type(nodeId, flowId)); + + + + ConnectionOpened *co = new ConnectionOpened(flowId, + application, + candidate.getTransportType(), + false /* inbound? */, + 0 /* no cert for you */); + flowId.getFifo().add(co); +} + +//---------------------------------------------------------------------- + + +// XXX FIXME -- Currently, we spin between waiting for the +// descriptor and waiting for the command queue. This should be +// fixed later to have a unified wait. +bool +SelectTransporter::process(int ms) +{ + resip::FdSet fdSet; + TransporterCommand *cmd; + + // First, we do the socket descriptors... + + std::map<NodeId, FlowId>::iterator i; + for (i = mNodeFlowMap.begin(); i != mNodeFlowMap.end(); i++) + { + fdSet.setRead((i->second).getSocket()); + } + + ListenerMap::iterator j; + for (j = mListenerMap.begin(); j != mListenerMap.end(); j++) + { + fdSet.setRead(j->second.first); + } + + if (mHasBootstrapSocket) + { + fdSet.setRead(mBootstrapSocket); + } + + // TODO -- add bootstrap listener socket + fdSet.selectMilliSeconds(ms); + + + if (mHasBootstrapSocket && fdSet.readyToRead(mBootstrapSocket)) + { + // New incoming BOOTSTRAP connection. Yaay!!! + unsigned short application = RELOAD_APPLICATION_ID; + + resip::Socket s; + struct sockaddr addr; + socklen_t addrlen = sizeof(sockaddr); + + if((s = accept(mBootstrapSocket, &addr, &addrlen))==(-1)){ + ErrLog( << "Could not accept, errno " << resip::getErrno()); + assert(false); + } + DebugLog(<<"Accepted a connection"); + + // ********** XXX REMOVE THIS WHEN WE GO TO TLS/DTLS XXX ********** + // Blow our node ID out on the wire (because there is no cert) + const resip::Data nid = mConfiguration.nodeId().encodeToNetwork(); + size_t bytesSent = ::send(s, nid.data(), nid.size(), 0); + if (bytesSent != nid.size()) + { + ErrLog( << "Cannot ::send -- returned " << bytesSent << " errno " << resip::getErrno()); + } + // ********** XXX REMOVE THIS WHEN WE GO TO TLS/DTLS XXX ********** + + // Get the remote node ID from the incoming socket + char buffer[16]; + size_t bytesRead = readSocket(s, buffer, sizeof(buffer)); + DebugLog(<< "Read#2 " << bytesRead); + if (bytesRead != sizeof(buffer)) + { + ErrLog( << "Cannot ::read -- returned " << bytesRead << " errno " << resip::getErrno()); + assert(0); + } + + // Parse the node id + s2c::NodeIdStruct nids; + resip::Data data(resip::Data::Borrow, buffer, sizeof(buffer)); + resip::DataStream strm(data); + nids.decode(strm); + NodeId nodeId(nids); + + FlowId flowId(nodeId, application, s, *mRxFifo); + + + mNodeFlowMap.insert( + std::map<NodeId, FlowId>::value_type(nodeId, flowId)); + + ConnectionOpened *co = new ConnectionOpened(flowId, + application, + resip::TCP, + true /* inbound? */, + 0 /* no cert for you */); + mRxFifo->add(co); + } + + // Check for new incoming connections + for (j = mListenerMap.begin(); j != mListenerMap.end(); j++) + { + DebugLog(<< "XXXXYYY"); + + + if (fdSet.readyToRead(j->second.first)) + { + // New incoming connection. Yaay! + NodeId nodeId = j->first.first; + unsigned short application = j->first.second; + + resip::Socket s; + struct sockaddr addr; + socklen_t addrlen = sizeof(sockaddr); + + s = accept(j->second.first, &addr, &addrlen); + + // ********** XXX REMOVE THIS WHEN WE GO TO TLS/DTLS XXX ********** + // Blow our node ID out on the wire (because there is no cert) + const resip::Data nid = mConfiguration.nodeId().encodeToNetwork(); + size_t bytesSent = ::send(s,nid.data(), nid.size(), 0); + + if (bytesSent != nid.size()) + { + ErrLog( << "Cannot ::send -- returned " << bytesSent << " errno " << resip::getErrno()); + } + // ********** XXX REMOVE THIS WHEN WE GO TO TLS/DTLS XXX ********** + + unsigned char buffer[16]; + size_t bytesRead = readSocket(s, (char*)buffer, sizeof(buffer)); + DebugLog(<< "Read#3" << bytesRead); + if (bytesRead != sizeof(buffer)) + { + ErrLog( << "Cannot ::read -- returned " << bytesRead << " errno " << resip::getErrno()); + assert(0); + } + + s2c::NodeIdStruct nids; + + nids.mHigh = *((UInt64*)(buffer)); + nids.mLow = *((UInt64*)(buffer+sizeof(UInt64))); + + NodeId nodeId2(nids); + FlowId flowId(nodeId2, application, s, *mRxFifo); + + mNodeFlowMap.insert( + std::map<NodeId, FlowId>::value_type(nodeId2, flowId)); + + DebugLog(<< "SelectTransporter: connection to node " << nodeId); + + // Ideally, we'd check that the nodeId we just read + // actually matches the nodeId we were expecting. + + ConnectionOpened *co = new ConnectionOpened(flowId, + application, + resip::TCP, + true /* inbound? */, + 0 /* no cert for you + * */); + + DebugLog(<< "Notifying about connection opened"); + + mRxFifo->add(co); + + // Open Issue -- should we close and remove the listener here? + // Adam and ekr say "probably"; fluffy says "hell no". + resip::closeSocket(j->second.first); + // TODO: remove this from the map somehow? + //ListenerMap::iterator jold=j++; + //mListenerMap.erase(jold); + } + } + + + // Check for new incoming data + for (i = mNodeFlowMap.begin(); i != mNodeFlowMap.end(); i++) + { + FlowId &flowId = i->second; + if (fdSet.readyToRead(flowId.getSocket())) + { + // There's data waiting to be read + if (flowId.getApplication() == RELOAD_APPLICATION_ID) + { + //************************************************** + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // XXX XXX THIS IS NAIVE AND WRONG -- WE ASSUME ALL + // THE BYTES FOR THIS MESSAGE ARE ALREADY IN THE + // LOCAL TCP BUFFER. THIS MUST BE FIXED. + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //************************************************** + char *buffer = new char[16384]; + UInt32 *int_buffer = reinterpret_cast<UInt32*>(buffer); + // Suck in the header + char *ptr; + size_t bytesRead; + size_t left=30; + ptr=buffer; + + while(left){ + bytesRead = readSocket(flowId.getSocket(), ptr, left); + if(bytesRead == -1) + { + ErrLog( << "Cannot ::read -- returned " << bytesRead << " errno " << resip::getErrno()); + assert(false); + } + left-=bytesRead; + ptr+=bytesRead; + DebugLog(<< "Read from socket: " << bytesRead << " left=" << left); + assert(bytesRead!=0); // Closed... + } + + if (int_buffer[0] == htonl(0x80000000 | 0x52454C4F)) + { + size_t length = ntohl(int_buffer[3]) & 0xFFFFFF; + bytesRead = readSocket(flowId.getSocket(), buffer+30, length-30); + + if (bytesRead != (length - 30)) + { + ErrLog( << "Cannot ::read -- returned " << bytesRead << " errno " << resip::getErrno()); + } + + resip::Data data(resip::Data::Take, buffer, length); + std::auto_ptr<p2p::Message> msg(Message::parse(data)); + msg->pushVia(i->first); + + MessageArrived *ma = new MessageArrived(flowId.getNodeId(), msg); + + mRxFifo->add(ma); + } + else + { + ErrLog(<< "Not a correct reload message"); + assert(0); + delete(buffer); + // Yikes! This isn't a reload message! + } + + } + else + { + // Application data is sent as-is. + char *buffer = new char[4096]; + size_t bytesRead; + bytesRead = readSocket(flowId.getSocket(), buffer, 4096); + if (bytesRead > 0) + { + resip::Data data(resip::Data::Take, buffer, bytesRead); + + ApplicationMessageArrived *ama = new + ApplicationMessageArrived(flowId, data); + + flowId.getFifo().add(ama); + } + else + { + delete [] buffer; + } + } + } + } + + // ...then, we do the command FIFO + if ((cmd = mCmdFifo.getNext(ms)) != 0) + { + (*cmd)(); + delete cmd; + return true; + } + return false; +} + +size_t +SelectTransporter::readSocket(resip::Socket s, char* buffer, unsigned int size) +{ +#if defined(WIN32) + return ::recv(s, buffer, size, 0); +#else + return ::read(s, buffer, size); +#endif +} + +int +SelectTransporter::writeSocket(resip::Socket s, char* buffer, unsigned int size) +{ +#if defined(WIN32) + return ::send(s, buffer, size, 0); +#else + return ::write(s, buffer, size); +#endif +} + +} + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/SelectTransporter.hxx b/src/libs/resiprocate/p2p/SelectTransporter.hxx new file mode 100644 index 00000000..8801c208 --- /dev/null +++ b/src/libs/resiprocate/p2p/SelectTransporter.hxx @@ -0,0 +1,122 @@ +#ifndef __P2P_SELECT_TRANSPORTER_HXX +#define __P2P_SELECT_TRANSPORTER_HXX 1 + +#include <vector> +#include <map> + +#include "rutil/Data.hxx" +#include "rutil/Fifo.hxx" +#include "rutil/TransportType.hxx" +#include "rutil/GenericIPAddress.hxx" +#include "rutil/Socket.hxx" + +#include "p2p/NodeId.hxx" +#include "p2p/Transporter.hxx" + +namespace p2p +{ + +class Event; +class Candidate; +class Message; +class Profile; +class FlowId; +class TransporterCommand; + +class SelectTransporter : public Transporter +{ + public: + friend class AddListenerCommand; + friend class SendP2pCommand; + friend class SendApplicationCommand; + friend class CollectCandidatesCommand; + friend class ConnectP2pCommand; + friend class ConnectApplicationCommand; + + SelectTransporter( Profile &configuration ); + + ~SelectTransporter(); + + // ms is the value passed to select. + bool process(int ms=0); + + protected: + void addListenerImpl(resip::TransportType transport, + resip::GenericIPAddress &address); + + void sendImpl(NodeId nodeId, std::auto_ptr<p2p::Message> msg); + void sendImpl(FlowId flowId, std::auto_ptr<resip::Data> data); + + void collectCandidatesImpl(UInt64 tid, NodeId nodeId, unsigned short appId); + + virtual void connectImpl(resip::GenericIPAddress &); + + void connectImpl(NodeId nodeId, + std::vector<Candidate> remoteCandidates, + resip::GenericIPAddress &stunTurnServer); + + void connectImpl(NodeId nodeId, + std::vector<Candidate> remoteCandidates, + unsigned short application, + resip::Fifo<Event>&, + resip::GenericIPAddress &stunTurnServer); + + private: + std::map<NodeId, FlowId> mNodeFlowMap; + + typedef std::map<std::pair<NodeId,unsigned short>, + std::pair<resip::Socket, resip::GenericIPAddress> > + ListenerMap; + + ListenerMap mListenerMap; + + // This will also change -- or really, go away -- when we add ice + in_addr mLocalAddress; + unsigned short mNextPort; + + bool mHasBootstrapSocket; + resip::GenericIPAddress mBootstrapAddress; + resip::Socket mBootstrapSocket; + + // OS independant implementations + size_t readSocket(resip::Socket s, char* buffer, unsigned int size); + int writeSocket(resip::Socket s, char* buffer, unsigned int size); +}; + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/Signable.cxx b/src/libs/resiprocate/p2p/Signable.cxx new file mode 100644 index 00000000..6bc63f57 --- /dev/null +++ b/src/libs/resiprocate/p2p/Signable.cxx @@ -0,0 +1,16 @@ +#include "p2p/Signable.hxx" + +using namespace p2p; +using namespace s2c; + +s2c::SignatureStruct * +Signable::sign(const std::vector<resip::Data> &signableData) +{ + SignatureStruct *sig = new SignatureStruct; + sig->mAlgorithm = new SignatureAndHashAlgorithmStruct(); + sig->mIdentity = new SignerIdentityStruct(); + sig->mIdentity->mIdentityType = signer_identity_peer; + + return sig; +} + diff --git a/src/libs/resiprocate/p2p/Signable.hxx b/src/libs/resiprocate/p2p/Signable.hxx new file mode 100644 index 00000000..3b5d841e --- /dev/null +++ b/src/libs/resiprocate/p2p/Signable.hxx @@ -0,0 +1,76 @@ +#ifndef P2P_Signable_hxx +#define P2P_Signable_hxx + +#include "rutil/Data.hxx" +#include "p2p.hxx" + +#include "p2p/MessageStructsGen.hxx" + +#include <vector> + +namespace p2p +{ + +class Signable +{ + public: + virtual ~Signable() {} + void sign(); + bool isValid() const; + + const resip::Data& getSignature() const + { + return mSignature; + } + + s2c::SignatureStruct *sign(const std::vector<resip::Data> &signableData); + + protected: + virtual std::vector<resip::Data> collectSignableData() const = 0; + + void setSignature(resip::Data& signature) + { + mSignature = signature; + } + + private: + resip::Data mSignature; +}; + +} +#endif + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/SignatureContext.cxx b/src/libs/resiprocate/p2p/SignatureContext.cxx new file mode 100644 index 00000000..3ffea78c --- /dev/null +++ b/src/libs/resiprocate/p2p/SignatureContext.cxx @@ -0,0 +1,82 @@ +#include "SignatureContext.hxx" + +#include <openssl/evp.h> + +#if 0 +namespace p2p { +SignatureContext::SignatureContext(Profile &profile) + : mProfile(profile) +{ + ; +} + +Data SignatureContext::computeSignature(const vector<Data> toBeSigned) +{ + EVP_MD_CTX md; + + const EVP_MD *digest_ptr=EVP_get_digestbyname(mProfile.signatureDigest().c_str()); + + assert(digest_ptr!=0); + + if(!EVP_SignInit(md,digest_ptr)) + assert(0); // This should not fail + + for(unsigned int i=0;i<toBeSigned.size();i++) + { + EVP_DigestUpdate(&md,toBeSigned[i].data(),toBeSigned[i].size()); + } + + + unsigned char *sig_buf sig_buf=new unsigned char[EVP_PKEY_size(size)]; + unsigned int sig_len; + + if(!EVP_SignFinal(&md,sig_buf,&sig_len,mProfile.getPrivateKey())) + { + delete sig_buf[]; + } + + return Data(sig_buf); +} + + + + + + +} +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + diff --git a/src/libs/resiprocate/p2p/SignatureContext.hxx b/src/libs/resiprocate/p2p/SignatureContext.hxx new file mode 100644 index 00000000..b7d96886 --- /dev/null +++ b/src/libs/resiprocate/p2p/SignatureContext.hxx @@ -0,0 +1,122 @@ +#ifndef __P2P_SIGNATURE_CONTEXT_HXX +#define __P2P_SIGNATURE_CONTEXT_HXX 1 + +#include <map> +#include "rutil/Data.hxx" + +#include "NodeId.hxx" +#include "Postable.hxx" +#include "ResourceId.hxx" +#include "UserName.hxx" +#include "Profile.hxx" + +using resip::Data; +using std::vector; + +namespace p2p +{ + +class SignatureContext +{ + public: + SignatureContext(Profile &config); + + // The types of hash function we support + enum { + sha1 = 1, + sha256 = 2 + } HashAlgorithm; + + + // Compute signatures, one function for each signature type + // Returns an encoded "Signature" object + Data computeSignatureWithPeerIdentity(const vector<const Data> toBeSigned); + Data computeSignatureWithUserName(const vector<const Data> toBeSigned); + Data computeSignatureWithCertificate(const vector<const Data> toBeSigned); + + + // Fetch all the certificates corresponding to this set of + // signatures, works in terms of encoded "Signature" objects + void fetchCertificates(const vector<Data> signatures, Postable<bool> done); + + // Validate a signature, comparing to the expected NodeId node + bool validateSignature(const vector<Data> toBeSigned, + const Data &signature, NodeId node); + + // Validate a signature, comparing to the expected UserName name + bool validateSignature(const vector<Data> toBeSigned, + const Data &signature, UserName user); + + + private: + void digestData(const vector<Data> toBeSigned, unsigned char digest[32], + unsigned int *digest_len); + Data computeSignature(const vector<Data> toBeSigned); + + Profile &mProfile; + + class CachedCertificate + { + public: + CachedCertificate(X509 *x, bool isValid, UInt64 expires) + { + mCertificate=x; + mValid=isValid; + mExpiryTime=expires; + } + + ~CachedCertificate() + { + X509_free(mCertificate); + } + + + X509 *mCertificate; // The certificate + bool mValid; // Is this entry valid + UInt64 mExpiryTime; // How long is this entry + // trustable for + }; + + std::map<Data,CachedCertificate> mCertificateCache; + + +}; +} + + +#endif + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/SingleValue.hxx b/src/libs/resiprocate/p2p/SingleValue.hxx new file mode 100644 index 00000000..65662f5a --- /dev/null +++ b/src/libs/resiprocate/p2p/SingleValue.hxx @@ -0,0 +1,86 @@ +#ifndef P2P_SingleValue_hxx +#define P2P_SingleValue_hxx + +#include "AbstractValue.hxx" + +namespace p2p +{ + +class SingleValue : public AbstractValue +{ + public: + static const resip::Data NoValue; + + SingleValue(const resip::Data& value) + : mValue(value), + mExists(true) + {} + + const resip::Data& get() const + { + if (mExists) + { + return mValue; + } else { + return NoValue; + } + } + + void set(const resip::Data& value) + { + mValue = value; + } + + void clear() + { + mExists = false; + } + + bool isSet() const + { + return mExists; + } + + private: + resip::Data mValue; + bool mExists; +}; + +} // p2p + +#endif // P2P_SingleValue_hxx + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + diff --git a/src/libs/resiprocate/p2p/StoreAns.hxx b/src/libs/resiprocate/p2p/StoreAns.hxx new file mode 100644 index 00000000..5729b34e --- /dev/null +++ b/src/libs/resiprocate/p2p/StoreAns.hxx @@ -0,0 +1,81 @@ +#ifndef P2P_StoreAns_hxx +#define P2P_StoreAns_hxx + +#include <vector> + +#include "p2p/Message.hxx" +#include "p2p/EventWrapper.hxx" + +namespace p2p +{ + +class StoreAns : public ResourceMessage +{ + public: + typedef std::vector<NodeId> NodeIds; + + virtual MessageType getMessageType() const { return Message::StoreAnsType; } + + KindId getKindId() const + { + return mKindId; + } + + Generation getGeneration() const + { + return mGeneration; + } + + // call Event->dispatch(consumer) when you want to dispatch this + std::auto_ptr<Event> event() + { + return wrap(this); + } + + NodeIds& nodeIds(); + const NodeIds& nodeIds() const; + + private: + KindId mKindId; + Generation mGeneration; + NodeIds mNodeIds; +}; + +} // p2p + +#endif // P2P_StoreAns_hxx + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + diff --git a/src/libs/resiprocate/p2p/StoreReq.hxx b/src/libs/resiprocate/p2p/StoreReq.hxx new file mode 100644 index 00000000..f055ec79 --- /dev/null +++ b/src/libs/resiprocate/p2p/StoreReq.hxx @@ -0,0 +1,73 @@ +#ifndef P2P_StoreReq_hxx +#define P2P_StoreReq_hxx + +#include "Message.hxx" +#include "AbstractValue.hxx" +#include "rutil/SharedPtr.hxx" + +namespace p2p +{ + +class StoreReq : public ResourceMessage +{ + public: + typedef std::list<resip::SharedPtr<AbstractValue> > AbstractValues; + virtual MessageType getMessageType() const { return Message::StoreReqType; } + + AbstractValues& values(); + const AbstractValues& values() const; + + ReplicaNumber getReplicaNumber() const; + void setReplicaNumber(ReplicaNumber number) + { + mReplicaNamber = number; + } + + std::auto_ptr<Event> event() + { + return wrap(this); + } + + private: + AbstractValues mValues; + ReplicaNumber mReplicaNamber; +}; + +} // p2p + +#endif // P2P_StoreReq_hxx + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + diff --git a/src/libs/resiprocate/p2p/StoreSet.hxx b/src/libs/resiprocate/p2p/StoreSet.hxx new file mode 100644 index 00000000..2e75f194 --- /dev/null +++ b/src/libs/resiprocate/p2p/StoreSet.hxx @@ -0,0 +1,70 @@ +#ifndef P2P_StoreSet_hxx +#define P2P_StoreSet_hxx + +#include "p2p/EventConsumer.hxx" + +namespace p2p +{ + +class TopologyApi; +class Dispatcher; + +class StoreSet : public EventConsumer, + public Postable<Event> +{ + public: + StoreSet(Dispatcher& dispatcher, + TopologyApi& topology, + std::vector<auto_ptr<StoreReq> > stores); + + virtual void consume(EventWrapper<StoreAns>& event); + virtual void post(std::auto_ptr<Event> event) + { + event->dispatch(this); + } + + virtual resip::Data brief() const; + + private: + + int mStoreRequestsOutstanding; +}; + +} // p2p + +#endif // P2P_StoreSet_hxx + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/TestMake.cxx b/src/libs/resiprocate/p2p/TestMake.cxx new file mode 100644 index 00000000..12fcd56a --- /dev/null +++ b/src/libs/resiprocate/p2p/TestMake.cxx @@ -0,0 +1,27 @@ +#include "AbstractValue.hxx" +#include "ArrayValue.hxx" +#include "Candidate.hxx" +#include "CertDoneEvent.hxx" +#include "Profile.hxx" +#include "DataSpecifier.hxx" +#include "DictionaryValue.hxx" +#include "Event.hxx" +#include "EventConsumer.hxx" +#include "FlowId.hxx" +#include "Message.hxx" +#include "NodeId.hxx" +#include "P2PSubsystem.hxx" +#include "Postable.hxx" +#include "ResourceId.hxx" +#include "Signable.hxx" +#include "SignatureContext.hxx" +#include "SingleValue.hxx" +#include "TopologyAPI.hxx" +#include "Transporter.hxx" +#include "TransporterMessage.hxx" +#include "UserName.hxx" +#include "FetchReq.hxx" +#include "FetchAns.hxx" +#include "StoreReq.hxx" +#include "StoreAns.hxx" + diff --git a/src/libs/resiprocate/p2p/TopologyAPI.cxx b/src/libs/resiprocate/p2p/TopologyAPI.cxx new file mode 100644 index 00000000..a3fb5fe2 --- /dev/null +++ b/src/libs/resiprocate/p2p/TopologyAPI.cxx @@ -0,0 +1,55 @@ +#include "p2p/TopologyAPI.hxx" +#include "p2p/Dispatcher.hxx" + +namespace p2p +{ + +TopologyAPI::TopologyAPI(Profile& config, Dispatcher& dispatcher, Transporter& transporter) : + mProfile(config), mDispatcher(dispatcher), mTransporter(transporter) +{ + // register with dispatcher for reload request events + mDispatcher.registerPostable(Message::JoinReqType, *this); + mDispatcher.registerPostable(Message::ConnectReqType, *this); // What about app connect? + mDispatcher.registerPostable(Message::UpdateReqType, *this); + mDispatcher.registerPostable(Message::LeaveReqType, *this); +} + +TopologyAPI::~TopologyAPI() +{ +} + +} + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/TopologyAPI.hxx b/src/libs/resiprocate/p2p/TopologyAPI.hxx new file mode 100644 index 00000000..b8de35b9 --- /dev/null +++ b/src/libs/resiprocate/p2p/TopologyAPI.hxx @@ -0,0 +1,122 @@ +#ifndef __P2P_TOPOLOGYAPI_HXX +#define __P2P_TOPOLOGYAPI_HXX 1 + +#include "rutil/Data.hxx" +#include "rutil/Fifo.hxx" + +#include "p2p/NodeId.hxx" +#include "p2p/ResourceId.hxx" +#include "p2p/Profile.hxx" +#include "p2p/Message.hxx" +#include "p2p/EventConsumer.hxx" +#include "p2p/Join.hxx" +#include "p2p/Update.hxx" +#include "p2p/Leave.hxx" +#include "p2p/Message.hxx" +//#include "p2p/Dispatcher.hxx" +#include "p2p/Transporter.hxx" + +namespace p2p +{ + +class Dispatcher; +class TransactionLayer; + +/// This is an abstract base class from which to derive the actual topology plugins +class TopologyAPI : public EventConsumer +{ + public: + virtual ~TopologyAPI() = 0; + TopologyAPI(Profile& config, Dispatcher& dispatcher, Transporter& transporter); + + // called to join the overlay + virtual void joinOverlay()=0; + + // need a fifo to receive timer events + + // Messages that the forwarding layer sends to this object + virtual void newConnectionFormed( const NodeId& node, bool inbound )=0; + virtual void connectionLost( const NodeId& node )=0; + virtual void candidatesCollected( UInt64 tid, const NodeId& node, unsigned short appId, std::vector<Candidate>& candidates )=0; + + // deal with topology change messages + virtual void consume(ConnectReq& event)=0; + virtual void consume(JoinReq& event)=0; + virtual void consume(UpdateReq& event)=0; + virtual void consume(LeaveReq& event)=0; + + // deal with responses + virtual void consume(ConnectAns& msg)=0; + virtual void consume(JoinAns& msg)=0; + virtual void consume(UpdateAns& msg)=0; + virtual void consume(LeaveAns& msg)=0; + + // Deal with routing querries + virtual const NodeId& findNextHop( const DestinationId& did) = 0; + virtual const NodeId& findNextHop( const NodeId& node )=0; + virtual const NodeId& findNextHop( const ResourceId& resource )=0; + + // Deal with replication for storage + virtual std::vector<NodeId> getReplicationSet( const ResourceId& resource )=0; + /// Returns list of nodes to replicate on + + // Functions to find out if this peer is responsible for something + virtual bool isResponsible( const DestinationId& did) const=0; + virtual bool isResponsible( const NodeId& node ) const=0; + virtual bool isResponsible( const ResourceId& resource ) const=0; + + // Function to determine if we are connected to a node + virtual bool isConnected( const NodeId& node ) const=0; + + // Function to hash resource names into resourceID + virtual ResourceId resourceId( const resip::Data& resourceName )=0; + + virtual resip::Data brief() const + { + return "TopologyAPI"; + } + + + protected: + Profile& mProfile; + Dispatcher& mDispatcher; + Transporter& mTransporter; +}; + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/TransApi.hxx b/src/libs/resiprocate/p2p/TransApi.hxx new file mode 100644 index 00000000..70d56ffd --- /dev/null +++ b/src/libs/resiprocate/p2p/TransApi.hxx @@ -0,0 +1,177 @@ +// Much of the reload protocol should be hidden from app level users of the +// transaction layer. Methods are opqaue to the tranport layer, but a certain +// amount of interaction will be required. +// 1. A mechanism to correleate requests and responses +// 2. Enough information to populate a Via list +// It is unclear how much more information should be required by the transaction +// layer API. + + +//this approach exposes a limited message concept which will contrcut transation +//ids...similar to how resip populates a tid when a via header is +//created. Subclasses(store_q, fetch_q, etc) will infer a destination list whenever possible. +//Dignature operations are hidden; signature check methods are expsoed where +//apropriate. + +class MessageFactory() // some sort sort of factory sigleton for pasing data from the + // wire and forming a new message of the correc type + // (like FetchReq for example) +{ + public: + static ReloadMeassage* parseData( Data msg ); +} + +// Show me what the elements of a DestinationList look like given they are a +// variant record + +class Message +{ + public: + DestinationList destinationList(); + ViaList viaList(); //is this useful or just diagnostic? (CJ - have to use it ) + TransactionId transactionId(); //populated at const. time(for requests) + MessageContents contents(); + virtual Data encode(); +}; + + + +//note that signature is not exposed +class MessageContents +{ + public: + virtual u_int16 messageCode() const=0; //should we req. subclassing? + virtual Data payload(); + private: +}; + +// needs classes simular to this for all the message types +class FetchReq : public Message // Should we derive off Message or + // MEssageContents ???? +{ + public: +} +class FetchAns : public Message +{ + public: +} + +//base class for MessageContents which can hint at routing? +//shared ptr. for poly. list? Ownership should be clear. +class StoreReq : public MessageContents +{ + public: + typedef std::list<StoreKindData*> StoreList(); + ResourceID resource(); + StoreList storeList(); +}; + +//variants here? +class StoreKindData +{ + KindId kindId(); + Generation generation(); +}; + + +//data model classes + +/* Basic operation--2 phase + +Contrsuct StoreQ. +call reloadTrans->makeRequest(StoreQ); +custom modification if necessary, store tid +call reloadTrans->send(req) + +ownership? + +Sepcifying a per-operation/per-kind sink will avoid unecessary demux cod ein the +app. + +*/ + +//from rutil... +class FifoHandler +{ + public: + void post(Message m); +}; + +void dhtSipRegister() +{ + //setup stuff...dht + ReloadTransaction reloadTrans; + StoreQ s = reloadTrans->makeStoreQ(unhashedId, kind); + //install payload into s + //per-request handler model + reloadTrans->send(s, handler); +} + +//1 per data model? +class StoreQHandler +{ + void onFailure(..); + void onSuccess(StoreQResponse); +}; + + +// Each peer in th dht is providing a service to store data; there are light +// validation rules, but it seems that the data can be treated as opaque. The +// main issue is that the kind-id must be supported. I'm not sure if generation +// calcuations should involve the app at all. + +//one of these is installed for each kind/dm supported. There will be a subclass +//for each DM. We can use static_cast for the calls or do templates w/ no +//subclassing. Signature checking is done by the sig. service and hidden from +//the app. +class ValidateCRUD +{ +}; + +class ValidateDictionary : public ValidateCRUD +{ + typedef vector<pair<Data, DictEntry>> Dictionary; + + bool isValid(const Resourse& r, const Dictionary& d, Generation gen); +}; + +// storage services are also installed onse per kind/DM +class CRUDService +{ +}; + + +class DictionaryService +{ + Generation update(const Resourse& r, const Dictionary& d); + //not sure about generation here.... + Generation delete(const Resourse& r); +}; + +class ServiceMap +{ + public: + void registerKind(); + map<KindId, Validate>; + + +}; + +class ConnectRequest +{ + //peer id + //protocol +}; + + +//under the hood mechanisms that need to be fleshed out +// signature validation/signing service + +/* How do we wire this into resip? + +- Fetch-Q for location mapped into 3263 style dns lookup + - transactionState will convey that this is dht to the transportSelector + - TS will try various alternatives +*/ + + diff --git a/src/libs/resiprocate/p2p/TransactionController.cxx b/src/libs/resiprocate/p2p/TransactionController.cxx new file mode 100644 index 00000000..96ec0c56 --- /dev/null +++ b/src/libs/resiprocate/p2p/TransactionController.cxx @@ -0,0 +1,58 @@ +#include "rutil/Logger.hxx" + +#include "p2p/P2PSubsystem.hxx" +#include "p2p/TransactionController.hxx" +#include "p2p/TransactionState.hxx" + +using namespace p2p; + +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P + +TransactionController::TransactionController() +{ +} + +TransactionController::~TransactionController() +{ +} + +void +TransactionController::send(TransactionMessage* msg) +{ + mStateMacFifo.add(msg); +} + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/TransactionController.hxx b/src/libs/resiprocate/p2p/TransactionController.hxx new file mode 100644 index 00000000..cb3e2c60 --- /dev/null +++ b/src/libs/resiprocate/p2p/TransactionController.hxx @@ -0,0 +1,92 @@ +#if !defined(P2P_TRANSACTION_CONTROLLER_HXX) +#define P2P_TRANSACTION_CONTROLLER_HXX + +#include <map> +#include "rutil/Fifo.hxx" + +namespace p2p +{ + +class TransactionState; + +class TransactionMessage +{ +public: +private: +}; + +class TimerMessage : public TransactionMessage +{ +public: +private: +}; + +class TransactionController +{ + public: + TransactionController(); + ~TransactionController(); + + private: + TransactionController(const TransactionController& rhs); + TransactionController& operator=(const TransactionController& rhs); + + /// Get a message into the transaction controller + void send(TransactionMessage* msg); + void process(); + + resip::Fifo<TransactionMessage> mStateMacFifo; + + // stores all of the transactions that are currently active in this stack + typedef std::map<UInt64, TransactionState*> TransactionMap; + TransactionMap mClientTransactionMap; // used to send retransmission + TransactionMap mServerTransactionMap; // used to absorb retransmissions + + // timers associated with the transactions. When a timer fires, it is + // placed in the mStateMacFifo + //TimerQueue mTimers; + + friend class TransactionState; +}; + + +} + + +#endif + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + diff --git a/src/libs/resiprocate/p2p/TransactionState.cxx b/src/libs/resiprocate/p2p/TransactionState.cxx new file mode 100644 index 00000000..c6b0dd48 --- /dev/null +++ b/src/libs/resiprocate/p2p/TransactionState.cxx @@ -0,0 +1,148 @@ +#include <assert.h> +#include <iostream> +#include "rutil/Logger.hxx" + +#include "p2p/TransactionState.hxx" +#include "p2p/TransactionController.hxx" +#include "p2p/Message.hxx" +#include "p2p/P2PSubsystem.hxx" + +using namespace p2p; + +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P + +TransactionState::TransactionState(TransactionController& controller, Machine m, + State s, UInt64 tid) : + mController(controller), + mMachine(m), + mState(s), + mMsgToRetransmit(0), + mTid(tid) +{ + add(tid); + StackLog (<< "Creating new TransactionState: " << *this); +} + + +TransactionState::~TransactionState() +{ + //StackLog (<< "Deleting TransactionState " << mId << " : " << this); + erase(mTid); + + delete mMsgToRetransmit; + mMsgToRetransmit = 0; +} + + +void +TransactionState::add(UInt64 tid) +{ + if (isClient()) + { + mController.mClientTransactionMap[tid] = this; + } + else + { + mController.mServerTransactionMap[tid] = this; + } +} + +void +TransactionState::erase(UInt64 tid) +{ + if (isClient()) + { + mController.mClientTransactionMap.erase(tid); + } + else + { + mController.mServerTransactionMap.erase(tid); + } +} + + +bool +TransactionState::isClient() const +{ + switch(mMachine) + { + case ClientRequest: + return true; + case ServerRequest: + return false; + default: + assert(0); + } + return false; +} + +std::ostream& +p2p::operator<<(std::ostream& strm, const p2p::TransactionState& state) +{ + strm << "tid=" << state.mTid << " [ "; + switch (state.mMachine) + { + case TransactionState::ClientRequest: + strm << "ClientRequest"; + break; + case TransactionState::ServerRequest: + strm << "ServerRequest"; + break; + default: + strm << "Unknown(" << state.mMachine << ")"; + } + + strm << "/"; + switch (state.mState) + { + case TransactionState::Initial: + strm << "Initial"; + break; + case TransactionState::Trying: + strm << "Trying"; + break; + case TransactionState::Completed: + strm << "Completed"; + break; + default: + strm << "Unknown(" << state.mState << ")"; + } + + strm << "]"; + return strm; +} + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/TransactionState.hxx b/src/libs/resiprocate/p2p/TransactionState.hxx new file mode 100644 index 00000000..b2ff381c --- /dev/null +++ b/src/libs/resiprocate/p2p/TransactionState.hxx @@ -0,0 +1,96 @@ +#if !defined(P2P_TRANSACTIONSTATE_HXX) +#define P2P_TRANSACTIONSTATE_HXX + +#include "rutil/Data.hxx" + +namespace p2p +{ + +class Message; +class TransactionController; + +class TransactionState +{ + public: + ~TransactionState(); + + private: + typedef enum + { + ClientRequest, + ServerRequest + } Machine; + + typedef enum + { + Initial, + Trying, + Completed + } State; + + TransactionState(TransactionController& controller, + Machine m, + State s, + UInt64 tid); + + void processClientRequest(Message* msg); + void processServerRequest(Message* msg); + + bool isClient() const; + void add(UInt64 tid); + void erase(UInt64 tid); + + private: + + TransactionController& mController; + + Machine mMachine; + State mState; + + Message* mMsgToRetransmit; + + UInt64 mTid; + + friend std::ostream& operator<<(std::ostream& strm, const TransactionState& state); + friend class TransactionController; +}; + + +} + +#endif + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/Transporter.cxx b/src/libs/resiprocate/p2p/Transporter.cxx new file mode 100644 index 00000000..98ccaff9 --- /dev/null +++ b/src/libs/resiprocate/p2p/Transporter.cxx @@ -0,0 +1,241 @@ +#include "rutil/GenericIPAddress.hxx" +#include "rutil/DnsUtil.hxx" + +#include "p2p/Transporter.hxx" +#include "p2p/Profile.hxx" +#include "p2p/TransporterMessage.hxx" +#include "p2p/FlowId.hxx" +#include "p2p/Message.hxx" +#include "p2p/Candidate.hxx" + +namespace p2p +{ + +//---------------------------------------------------------------------- +// Command Objects from here to the next line -- Transporter methods +// come after that. + +class AddListenerCommand : public TransporterCommand +{ + public: + AddListenerCommand(Transporter *transporter, + resip::TransportType transport, + resip::GenericIPAddress &address) + : TransporterCommand(transporter), + mTransport(transport), + mAddress(address) {;} + + void operator()() { mTransporter->addListenerImpl(mTransport, mAddress); } + + private: + resip::TransportType mTransport; + resip::GenericIPAddress mAddress; +}; + +class SendP2pCommand : public TransporterCommand +{ + public: + SendP2pCommand(Transporter *transporter, + NodeId nodeId, + std::auto_ptr<p2p::Message> message) + : TransporterCommand(transporter), + mNodeId(nodeId), + mMessage(message) {;} + + void operator()() { mTransporter->sendImpl(mNodeId, mMessage); } + + private: + NodeId mNodeId; + std::auto_ptr<p2p::Message> mMessage; +}; + +class SendApplicationCommand : public TransporterCommand +{ + public: + SendApplicationCommand(Transporter *transporter, + FlowId flowId, + std::auto_ptr<resip::Data> message) + : TransporterCommand(transporter), + mFlowId(flowId), + mMessage(message) {;} + + void operator()() { mTransporter->sendImpl(mFlowId, mMessage); } + + private: + FlowId mFlowId; + std::auto_ptr<resip::Data> mMessage; +}; + +class CollectCandidatesCommand : public TransporterCommand +{ + public: + CollectCandidatesCommand(Transporter *transporter, + UInt64 tid, + NodeId &nodeId, + unsigned short appId) + : TransporterCommand(transporter), mTransactionId(tid), + mNodeId(nodeId), mAppId(appId) {;} + + void operator()() { mTransporter->collectCandidatesImpl(mTransactionId, mNodeId, mAppId); } + + private: + UInt64 mTransactionId; + NodeId mNodeId; + unsigned short mAppId; +}; + +class ConnectBootstrapCommand : public TransporterCommand +{ + public: + ConnectBootstrapCommand(Transporter *transporter, + resip::GenericIPAddress &addr) + : TransporterCommand(transporter), mAddress (addr) {;} + + void operator()() { mTransporter->connectImpl(mAddress); } + + private: + resip::GenericIPAddress mAddress; +}; + +class ConnectP2pCommand : public TransporterCommand +{ + public: + ConnectP2pCommand(Transporter *transporter, + NodeId nodeId, + std::vector<Candidate> remoteCandidates, + resip::GenericIPAddress &stunTurnServer) + : TransporterCommand(transporter), + mNodeId(nodeId), + mRemoteCandidates(remoteCandidates), + mStunTurnServer (stunTurnServer) {;} + + void operator()() { mTransporter->connectImpl(mNodeId, mRemoteCandidates, mStunTurnServer); } + + private: + NodeId mNodeId; + std::vector<Candidate> mRemoteCandidates; + resip::GenericIPAddress mStunTurnServer; +}; + +class ConnectApplicationCommand : public TransporterCommand +{ + public: + ConnectApplicationCommand(Transporter *transporter, + NodeId nodeId, + std::vector<Candidate> remoteCandidates, + unsigned short application, + resip::Fifo<Event> &fifo, + resip::GenericIPAddress &stunTurnServer) + + : TransporterCommand(transporter), + mNodeId(nodeId), + mRemoteCandidates(remoteCandidates), + mApplication(application), + mFifo(fifo), + mStunTurnServer (stunTurnServer) {;} + + void operator()() { mTransporter->connectImpl(mNodeId, mRemoteCandidates, mApplication, mFifo, mStunTurnServer); } + + private: + NodeId mNodeId; + std::vector<Candidate> mRemoteCandidates; + unsigned short mApplication; + resip::Fifo<Event> &mFifo; + resip::GenericIPAddress mStunTurnServer; +}; + +//---------------------------------------------------------------------- + +Transporter::Transporter (Profile &configuration) + : mRxFifo(0), mConfiguration(configuration) +{ +} + +Transporter::~Transporter() +{ +} + +void +Transporter::addListener(resip::TransportType transport, + resip::GenericIPAddress &address) +{ + mCmdFifo.add(new AddListenerCommand(this, transport, address)); +} + +void +Transporter::send(NodeId nodeId, std::auto_ptr<p2p::Message> msg) +{ + mCmdFifo.add(new SendP2pCommand(this, nodeId, msg)); +} + +void +Transporter::send(FlowId flowId, std::auto_ptr<resip::Data> msg) +{ + mCmdFifo.add(new SendApplicationCommand(this, flowId, msg)); +} + +void +Transporter::collectCandidates(const UInt64 tid, NodeId nodeId, unsigned short appId) +{ + mCmdFifo.add(new CollectCandidatesCommand(this, tid, nodeId, appId)); +} + +void +Transporter::connect(resip::GenericIPAddress &addr) +{ + mCmdFifo.add(new ConnectBootstrapCommand(this, addr)); +} + +void +Transporter::connect(NodeId nodeId, + std::vector<Candidate> remoteCandidates, + resip::GenericIPAddress &stunTurnServer) +{ + mCmdFifo.add(new ConnectP2pCommand(this, nodeId, remoteCandidates, stunTurnServer)); +} + +void +Transporter::connect(NodeId nodeId, + std::vector<Candidate> remoteCandidates, + unsigned short application, + resip::Fifo<Event> &fifo, + resip::GenericIPAddress &stunTurnServer) +{ + mCmdFifo.add(new ConnectApplicationCommand(this, nodeId, remoteCandidates, application, fifo, stunTurnServer)); +} + +} + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/Transporter.hxx b/src/libs/resiprocate/p2p/Transporter.hxx new file mode 100644 index 00000000..4d815823 --- /dev/null +++ b/src/libs/resiprocate/p2p/Transporter.hxx @@ -0,0 +1,148 @@ +#ifndef __P2P_TRANSPORTER_HXX +#define __P2P_TRANSPORTER_HXX 1 + +#include <memory> +#include <vector> +#include <map> + +#include "rutil/Data.hxx" +#include "rutil/Fifo.hxx" +#include "rutil/TransportType.hxx" +#include "rutil/GenericIPAddress.hxx" +#include "rutil/Socket.hxx" + +#include "p2p/Profile.hxx" +#include "p2p/NodeId.hxx" + +namespace p2p +{ + +class Candidate; +class Event; +class FlowId; +class Message; +class Profile; +class TransporterCommand; +class Event; + +class Transporter +{ + public: + friend class AddListenerCommand; + friend class SendP2pCommand; + friend class SendApplicationCommand; + friend class CollectCandidatesCommand; + friend class ConnectBootstrapCommand; + friend class ConnectP2pCommand; + friend class ConnectApplicationCommand; + + Transporter(Profile &configuration); + + virtual ~Transporter(); + + void setRxFifo(resip::Fifo<Event> *fifo) {mRxFifo = fifo;} + + virtual bool process(int ms=0) = 0; + + void addListener(resip::TransportType transport, + resip::GenericIPAddress &address); + + void send(NodeId nodeId, std::auto_ptr<p2p::Message> msg); + void send(FlowId flowId, std::auto_ptr<resip::Data> data); + + void collectCandidates(UInt64 tid, NodeId nodeId, + unsigned short appId = RELOAD_APPLICATION_ID); + + void connect(resip::GenericIPAddress &); + + void connect(NodeId nodeId, + std::vector<Candidate> remoteCandidates, + resip::GenericIPAddress &stunTurnServer); + + void connect(NodeId nodeId, + std::vector<Candidate> remoteCandidates, + unsigned short application, + resip::Fifo<Event>&, + resip::GenericIPAddress &stunTurnServer); + + protected: + virtual void addListenerImpl(resip::TransportType transport, + resip::GenericIPAddress &address) = 0; + + virtual void sendImpl(NodeId nodeId, std::auto_ptr<p2p::Message> msg) = 0; + virtual void sendImpl(FlowId flowId, std::auto_ptr<resip::Data> data) = 0; + + virtual void collectCandidatesImpl(UInt64 tid, NodeId, unsigned short appId) = 0; + + virtual void connectImpl(resip::GenericIPAddress &) = 0; + + virtual void connectImpl(NodeId nodeId, + std::vector<Candidate> remoteCandidates, + resip::GenericIPAddress &stunTurnServer) = 0; + + virtual void connectImpl(NodeId nodeId, + std::vector<Candidate> remoteCandidates, + unsigned short application, + resip::Fifo<Event>&, + resip::GenericIPAddress &stunTurnServer) = 0; + + resip::Fifo<TransporterCommand> mCmdFifo; + resip::Fifo<Event>* mRxFifo; + + Profile &mConfiguration; + + private: +}; + +/// This class is used internally by Transporter. Don't get any crazy ideas. +class TransporterCommand +{ + public: + TransporterCommand(Transporter *transporter) : mTransporter(transporter) {;} + + virtual ~TransporterCommand() {;} + + virtual void operator()() = 0; + + protected: + Transporter *mTransporter; +}; + + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/TransporterMessage.cxx b/src/libs/resiprocate/p2p/TransporterMessage.cxx new file mode 100644 index 00000000..02c6b25d --- /dev/null +++ b/src/libs/resiprocate/p2p/TransporterMessage.cxx @@ -0,0 +1,158 @@ +#include "p2p/TransporterMessage.hxx" +#include "p2p/EventConsumer.hxx" + +using namespace p2p; +ConnectionOpened::ConnectionOpened(FlowId flowId, + unsigned short application, + resip::TransportType transportType, + bool inbound, + X509 *cert) : + mFlowId(flowId), + mApplication(application), + mTransportType(transportType), + mInbound(inbound), + mCert(cert) +{ +} + +ConnectionOpened::~ConnectionOpened() +{ +} + +void +ConnectionOpened::dispatch(EventConsumer& consumer) +{ + consumer.consume(*this); +} + +FlowId +ConnectionOpened::getFlowId() const +{ + return mFlowId; +} + +unsigned short +ConnectionOpened::getApplication() const +{ + return mApplication; +} + +NodeId +ConnectionOpened::getNodeId() const +{ + return mFlowId.getNodeId(); +} + +resip::TransportType +ConnectionOpened::getTransportType() const +{ + return mTransportType; +} + +bool +ConnectionOpened::isInbound() const +{ + return mInbound; +} + +X509* +ConnectionOpened::getCertificate() const +{ + return mCert; +} + +ConnectionClosed::ConnectionClosed(FlowId flowId, unsigned short appId) : + mFlowId(flowId), + mApplication(appId) +{ +} + +NodeId +ConnectionClosed::getNodeId() const +{ + return mFlowId.getNodeId(); +} + +unsigned short +ConnectionClosed::getApplicationId() const +{ + return mApplication; +} + +void +ConnectionClosed::dispatch(EventConsumer& consumer) +{ + consumer.consume(*this); +} + +ConnectionClosed::~ConnectionClosed() +{ +} + + +void +MessageArrived::dispatch(EventConsumer& consumer) +{ + consumer.consume(*this); +} + +MessageArrived::~MessageArrived() +{ +} + + +void +ApplicationMessageArrived::dispatch(EventConsumer& consumer) +{ + consumer.consume(*this); +} + +ApplicationMessageArrived::~ApplicationMessageArrived() +{ +} + + +void +LocalCandidatesCollected::dispatch(EventConsumer& consumer) +{ + consumer.consume(*this); +} + +LocalCandidatesCollected::~LocalCandidatesCollected() +{ +} + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/TransporterMessage.hxx b/src/libs/resiprocate/p2p/TransporterMessage.hxx new file mode 100644 index 00000000..27e33aee --- /dev/null +++ b/src/libs/resiprocate/p2p/TransporterMessage.hxx @@ -0,0 +1,200 @@ +#ifndef __P2P_TRANSPORTER_MESSAGE_HXX +#define __P2P_TRANSPORTER_MESSAGE_HXX 1 + +#include "openssl/ssl.h" + +#include "rutil/Data.hxx" +#include "rutil/Fifo.hxx" +#include "rutil/TransportType.hxx" + +#include "p2p/Event.hxx" +#include "p2p/NodeId.hxx" +#include "p2p/FlowId.hxx" +#include "p2p/Candidate.hxx" +#include "p2p/Message.hxx" + +namespace p2p +{ + +class ConnectionOpened; +class ConnectionClosed; +class ApplicationMessageArrived; +class MessageArrived; +class LocalCandidatesCollected; + +class Message; +class FlowId; +class Candidate; + +class ConnectionOpened : public Event +{ + public: + ConnectionOpened(FlowId flowId, + unsigned short application, + resip::TransportType transportType, + bool inbound, + X509 *cert); + ~ConnectionOpened(); + + virtual void dispatch(EventConsumer& consumer); + + FlowId getFlowId() const; + unsigned short getApplication() const; + NodeId getNodeId() const; + resip::TransportType getTransportType() const; + bool isInbound() const; + X509 *getCertificate() const; + + virtual resip::Data brief() const + { + return "ConnectionOpened"; + } + + + private: + FlowId mFlowId; + unsigned short mApplication; + resip::TransportType mTransportType; + bool mInbound; + X509* mCert; +}; + +class ConnectionClosed : public Event +{ + public: + ConnectionClosed(FlowId flowId, + unsigned short application); + ~ConnectionClosed(); + + NodeId getNodeId() const; + unsigned short getApplicationId() const; + virtual void dispatch(EventConsumer& consumer); + + + virtual resip::Data brief() const + { + return "ConnectionClosed"; + } + + protected: + FlowId mFlowId; + unsigned short mApplication; + +}; + +class MessageArrived : public Event +{ + public: + MessageArrived (NodeId nodeId, std::auto_ptr<p2p::Message> message) + : mNodeId(nodeId), mMessage(message) {} + ~MessageArrived(); + + virtual void dispatch(EventConsumer& consumer); + + NodeId getNodeId() const {return mNodeId;} + std::auto_ptr<p2p::Message> getMessage() { assert(mMessage.get()); + return mMessage; } + + virtual resip::Data brief() const + { + return "MessageArrived"; + } + + + protected: + + NodeId mNodeId; + std::auto_ptr<p2p::Message> mMessage; +}; + +class ApplicationMessageArrived : public Event +{ + public: + ApplicationMessageArrived(FlowId flowId, resip::Data &data) + : mFlowId(flowId), mData(data) {} + ~ApplicationMessageArrived(); + + virtual void dispatch(EventConsumer& consumer); + + FlowId getFlowId() const { return mFlowId; } + const resip::Data &getData() const { return mData; } + + virtual resip::Data brief() const + { + return "ApplicationMessageArrived"; + } + + + protected: + + private: + FlowId mFlowId; + resip::Data mData; +}; + +class LocalCandidatesCollected : public Event +{ + public: + LocalCandidatesCollected(UInt64 tid, NodeId& nodeId, unsigned short appId, std::vector<Candidate> &c) : + mTransactionId(tid), mNodeId(nodeId), mAppId(appId), mCandidates(c) {} + ~LocalCandidatesCollected(); + + virtual void dispatch(EventConsumer& consumer); + + const UInt64 getTransactionId() const { return mTransactionId; } + const NodeId& getNodeId() const { return mNodeId; } + unsigned short getAppId() const { return mAppId; } + std::vector<Candidate>& getCandidates() { return mCandidates; } + + virtual resip::Data brief() const + { + return "LocalCandidatesCollected"; + } + + + protected: + + private: + UInt64 mTransactionId; + NodeId mNodeId; + unsigned short mAppId; + std::vector<Candidate> mCandidates; +}; + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/Update.cxx b/src/libs/resiprocate/p2p/Update.cxx new file mode 100644 index 00000000..c3b55284 --- /dev/null +++ b/src/libs/resiprocate/p2p/Update.cxx @@ -0,0 +1,85 @@ +#include "p2p/Update.hxx" + +using namespace p2p; + +UpdateAns::UpdateAns() +{ +} + +UpdateAns::UpdateAns(UpdateReq *request, const resip::Data &overlaySpecificData) : + mOverlaySpecificData(overlaySpecificData) +{ + copyForwardingData(*request); +} + +void +UpdateAns::getEncodedPayload(resip::DataStream &data) +{ + data << mOverlaySpecificData; +} + +void +UpdateAns::decodePayload(resip::DataStream &dataStream) +{ + // this function intentionally left blank +} + +UpdateReq::UpdateReq() +{ + +} + +UpdateReq::UpdateReq(const DestinationId &dest, const resip::Data &overlaySpecificData) : + mOverlaySpecificData(overlaySpecificData) +{ + +} + +void +UpdateReq::getEncodedPayload(resip::DataStream &data) +{ + std::cout << "POOO: " << mOverlaySpecificData.size() << std::endl; + data << mOverlaySpecificData; +} + + +void +UpdateReq::decodePayload(resip::DataStream &dataStream) +{ + // this is intentionally left blank +} + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ + diff --git a/src/libs/resiprocate/p2p/Update.hxx b/src/libs/resiprocate/p2p/Update.hxx new file mode 100644 index 00000000..7382c009 --- /dev/null +++ b/src/libs/resiprocate/p2p/Update.hxx @@ -0,0 +1,95 @@ +#ifndef P2P_UPDATE_HXX +#define P2P_UPDATE_HXX + +#include "p2p/Message.hxx" +#include "p2p/EventWrapper.hxx" + +namespace p2p +{ + +class UpdateReq; + +class UpdateAns : public Message +{ +public: + virtual MessageType getType() const { return Message::UpdateAnsType; } + virtual void getEncodedPayload(resip::DataStream &data); + virtual resip::Data brief() const { return "UpdateAns Message"; } + + + std::auto_ptr<Event> event() + { + return wrap(this); + } +protected: + resip::Data mOverlaySpecificData; + + friend class Message; + + virtual void decodePayload(resip::DataStream &dataStream); + + UpdateAns(); + UpdateAns(UpdateReq *request, const resip::Data &overlaySpecificData); +}; + + +class UpdateReq : public Message +{ +public: + UpdateReq(const DestinationId &dest, const resip::Data &overlaySpecificBlob); + virtual MessageType getType() const { return Message::UpdateReqType; } + + virtual void getEncodedPayload(resip::DataStream &data); + virtual resip::Data brief() const { return "UpdateReq Message"; } + + std::auto_ptr<Event> event() + { + return wrap(this); + } + +protected: + friend class Message; + + resip::Data mOverlaySpecificData; + + virtual void decodePayload(resip::DataStream &dataStream); + UpdateReq(); +}; + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/UserName.hxx b/src/libs/resiprocate/p2p/UserName.hxx new file mode 100644 index 00000000..14df217a --- /dev/null +++ b/src/libs/resiprocate/p2p/UserName.hxx @@ -0,0 +1,57 @@ +#ifndef __P2P_USERNAME_HXX +#define __P2P_USERNAME_HXX 1 + +#include "rutil/Data.hxx" + +namespace p2p +{ + +// This is pretty much wrong, but it serves as a good placeholder at +// the moment. +class UserName +{ + public: + resip::Data& value() { return mValue; } // looks like fluffy@example.com not fluffy + bool operator= ( const UserName& foo ); + private: + resip::Data mValue; +}; + + +} + +#endif + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/config b/src/libs/resiprocate/p2p/config new file mode 100644 index 00000000..563c0f02 --- /dev/null +++ b/src/libs/resiprocate/p2p/config @@ -0,0 +1,106 @@ +### This file configures various client-side behaviors. +### +### The commented-out examples below are intended to demonstrate +### how to use this file. + +### Section for authentication and authorization customizations. +[auth] +### Set store-passwords to 'no' to avoid storing passwords in the +### auth/ area of your config directory. It defaults to 'yes'. +### Note that this option only prevents saving of *new* passwords; +### it doesn't invalidate existing passwords. (To do that, remove +### the cache files by hand as described in the Subversion book.) +# store-passwords = no +### Set store-auth-creds to 'no' to avoid storing any subversion +### credentials in the auth/ area of your config directory. +### It defaults to 'yes'. Note that this option only prevents +### saving of *new* credentials; it doesn't invalidate existing +### caches. (To do that, remove the cache files by hand.) +# store-auth-creds = no + +### Section for configuring external helper applications. +[helpers] +### Set editor to the command used to invoke your text editor. +### This will override the environment variables that Subversion +### examines by default to find this information ($EDITOR, +### et al). +# editor-cmd = editor (vi, emacs, notepad, etc.) +### Set diff-cmd to the absolute path of your 'diff' program. +### This will override the compile-time default, which is to use +### Subversion's internal diff implementation. +# diff-cmd = diff_program (diff, gdiff, etc.) +### Set diff3-cmd to the absolute path of your 'diff3' program. +### This will override the compile-time default, which is to use +### Subversion's internal diff3 implementation. +# diff3-cmd = diff3_program (diff3, gdiff3, etc.) +### Set diff3-has-program-arg to 'true' or 'yes' if your 'diff3' +### program accepts the '--diff-program' option. +# diff3-has-program-arg = [true | false] + +### Section for configuring tunnel agents. +[tunnels] +### Configure svn protocol tunnel schemes here. By default, only +### the 'ssh' scheme is defined. You can define other schemes to +### be used with 'svn+scheme://hostname/path' URLs. A scheme +### definition is simply a command, optionally prefixed by an +### environment variable name which can override the command if it +### is defined. The command (or environment variable) may contain +### arguments, using standard shell quoting for arguments with +### spaces. The command will be invoked as: +### <command> <hostname> svnserve -t +### (If the URL includes a username, then the hostname will be +### passed to the tunnel agent as <user>@<hostname>.) If the +### built-in ssh scheme were not predefined, it could be defined +### as: +# ssh = $SVN_SSH ssh +### If you wanted to define a new 'rsh' scheme, to be used with +### 'svn+rsh:' URLs, you could do so as follows: +# rsh = rsh +### Or, if you wanted to specify a full path and arguments: +# rsh = /path/to/rsh -l myusername +### On Windows, if you are specifying a full path to a command, +### use a forward slash (/) or a paired backslash (\\) as the +### path separator. A single backslash will be treated as an +### escape for the following character. + +### Section for configuring miscelleneous Subversion options. +[miscellany] +### Set global-ignores to a set of whitespace-delimited globs +### which Subversion will ignore in its 'status' output, and +### while importing or adding files and directories. +# global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store +### Set log-encoding to the default encoding for log messages +# log-encoding = latin1 +### Set use-commit-times to make checkout/update/switch/revert +### put last-committed timestamps on every file touched. +# use-commit-times = yes +### Set no-unlock to prevent 'svn commit' from automatically +### releasing locks on files. +# no-unlock = yes +### Set enable-auto-props to 'yes' to enable automatic properties +### for 'svn add' and 'svn import', it defaults to 'no'. +### Automatic properties are defined in the section 'auto-props'. +# enable-auto-props = yes + +### Section for configuring automatic properties. +[auto-props] +### The format of the entries is: +### file-name-pattern = propname[=value][;propname[=value]...] +### The file-name-pattern can contain wildcards (such as '*' and +### '?'). All entries which match will be applied to the file. +### Note that auto-props functionality must be enabled, which +### is typically done by setting the 'enable-auto-props' option. +*.c = svn:eol-style=native +*.cpp = svn:eol-style=native +*.hxx = svn:eol-style=native +*.cxx = svn:eol-style=native +*.h = svn:eol-style=native +*.hpp = svn:eol-style=native +*.dsp = svn:eol-style=CRLF +*.dsw = svn:eol-style=CRLF +*.sh = svn:eol-style=native;svn:executable +*.txt = svn:eol-style=native +*.png = svn:mime-type=image/png +*.jpg = svn:mime-type=image/jpeg +# Makefile = svn:eol-style=native + diff --git a/src/libs/resiprocate/p2p/p2p.hxx b/src/libs/resiprocate/p2p/p2p.hxx new file mode 100644 index 00000000..c2737f7d --- /dev/null +++ b/src/libs/resiprocate/p2p/p2p.hxx @@ -0,0 +1,17 @@ +#ifndef p2p_hxx +#define p2p_hxx + +#include "rutil/compat.hxx" + +namespace p2p +{ + +// Reload types +typedef ::UInt32 KindId; +typedef ::UInt32 Generation; +typedef ::UInt8 ReplicaNumber; +typedef ::UInt64 TransactionId; + +} // p2p + +#endif // p2p_hxx diff --git a/src/libs/resiprocate/p2p/p2p_8_0.sln b/src/libs/resiprocate/p2p/p2p_8_0.sln new file mode 100644 index 00000000..6dc72809 --- /dev/null +++ b/src/libs/resiprocate/p2p/p2p_8_0.sln @@ -0,0 +1,42 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "p2p", "p2p_8_0.vcproj", "{D941A353-F065-4833-B454-F013209DF37B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\contrib\ares\ares_8_0.vcproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\rutil\rutil_8_0.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testConsole", "test\testConsole_8_0.vcproj", "{E70B1CEE-B744-4306-A4F5-4F8A353EC01C}" + ProjectSection(ProjectDependencies) = postProject + {D941A353-F065-4833-B454-F013209DF37B} = {D941A353-F065-4833-B454-F013209DF37B} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D941A353-F065-4833-B454-F013209DF37B}.Debug|Win32.ActiveCfg = Debug|Win32 + {D941A353-F065-4833-B454-F013209DF37B}.Debug|Win32.Build.0 = Debug|Win32 + {D941A353-F065-4833-B454-F013209DF37B}.Release|Win32.ActiveCfg = Release|Win32 + {D941A353-F065-4833-B454-F013209DF37B}.Release|Win32.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.Build.0 = SSL-Release|Win32 + {E70B1CEE-B744-4306-A4F5-4F8A353EC01C}.Debug|Win32.ActiveCfg = Debug|Win32 + {E70B1CEE-B744-4306-A4F5-4F8A353EC01C}.Debug|Win32.Build.0 = Debug|Win32 + {E70B1CEE-B744-4306-A4F5-4F8A353EC01C}.Release|Win32.ActiveCfg = Release|Win32 + {E70B1CEE-B744-4306-A4F5-4F8A353EC01C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/p2p/p2p_8_0.vcproj b/src/libs/resiprocate/p2p/p2p_8_0.vcproj new file mode 100644 index 00000000..4df8a158 --- /dev/null +++ b/src/libs/resiprocate/p2p/p2p_8_0.vcproj @@ -0,0 +1,467 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="p2p" + ProjectGUID="{D941A353-F065-4833-B454-F013209DF37B}" + RootNamespace="p2p" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\;&quot;$(ProjectDir)/../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_SSL" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\;&quot;$(ProjectDir)/../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_SSL" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\ChordTopology.cxx" + > + </File> + <File + RelativePath=".\ChordUpdate.cxx" + > + </File> + <File + RelativePath=".\Connect.cxx" + > + </File> + <File + RelativePath=".\ConnectBase.cxx" + > + </File> + <File + RelativePath=".\DestinationId.cxx" + > + </File> + <File + RelativePath=".\Dispatcher.cxx" + > + </File> + <File + RelativePath=".\Find.cxx" + > + </File> + <File + RelativePath=".\FlowId.cxx" + > + </File> + <File + RelativePath=".\ForwardingLayer.cxx" + > + </File> + <File + RelativePath=".\Join.cxx" + > + </File> + <File + RelativePath=".\Leave.cxx" + > + </File> + <File + RelativePath=".\Message.cxx" + > + </File> + <File + RelativePath=".\MessageStructsGen.cxx" + > + </File> + <File + RelativePath=".\NodeId.cxx" + > + </File> + <File + RelativePath=".\P2PStack.cxx" + > + </File> + <File + RelativePath=".\P2PSubsystem.cxx" + > + </File> + <File + RelativePath=".\ResourceId.cxx" + > + </File> + <File + RelativePath=".\s2c\s2c\s2c_native.cxx" + > + </File> + <File + RelativePath=".\SelectTransporter.cxx" + > + </File> + <File + RelativePath=".\Signable.cxx" + > + </File> + <File + RelativePath=".\SignatureContext.cxx" + > + </File> + <File + RelativePath=".\TopologyAPI.cxx" + > + </File> + <File + RelativePath=".\TransactionController.cxx" + > + </File> + <File + RelativePath=".\TransactionState.cxx" + > + </File> + <File + RelativePath=".\Transporter.cxx" + > + </File> + <File + RelativePath=".\TransporterMessage.cxx" + > + </File> + <File + RelativePath=".\Update.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\AbstractValue.hxx" + > + </File> + <File + RelativePath=".\ArrayValue.hxx" + > + </File> + <File + RelativePath=".\Candidate.hxx" + > + </File> + <File + RelativePath=".\CertDoneEvent.hxx" + > + </File> + <File + RelativePath=".\ChordTopology.hxx" + > + </File> + <File + RelativePath=".\ChordUpdate.hxx" + > + </File> + <File + RelativePath=".\Connect.hxx" + > + </File> + <File + RelativePath=".\ConnectBase.hxx" + > + </File> + <File + RelativePath=".\DataSpecifier.hxx" + > + </File> + <File + RelativePath=".\DestinationId.hxx" + > + </File> + <File + RelativePath=".\DictionaryValue.hxx" + > + </File> + <File + RelativePath=".\Dispatcher.hxx" + > + </File> + <File + RelativePath=".\Event.hxx" + > + </File> + <File + RelativePath=".\EventConsumer.hxx" + > + </File> + <File + RelativePath=".\EventWrapper.hxx" + > + </File> + <File + RelativePath=".\FetchAns.hxx" + > + </File> + <File + RelativePath=".\FetchKind.hxx" + > + </File> + <File + RelativePath=".\FetchReq.hxx" + > + </File> + <File + RelativePath=".\Find.hxx" + > + </File> + <File + RelativePath=".\FlowId.hxx" + > + </File> + <File + RelativePath=".\ForwardingLayer.hxx" + > + </File> + <File + RelativePath=".\Join.hxx" + > + </File> + <File + RelativePath=".\Leave.hxx" + > + </File> + <File + RelativePath=".\Message.hxx" + > + </File> + <File + RelativePath=".\MessageStructsGen.hxx" + > + </File> + <File + RelativePath=".\NodeId.hxx" + > + </File> + <File + RelativePath=".\p2p.hxx" + > + </File> + <File + RelativePath=".\P2PStack.hxx" + > + </File> + <File + RelativePath=".\P2PSubsystem.hxx" + > + </File> + <File + RelativePath=".\Postable.hxx" + > + </File> + <File + RelativePath=".\Profile.hxx" + > + </File> + <File + RelativePath=".\ResourceId.hxx" + > + </File> + <File + RelativePath=".\s2c\s2c\s2c_native.hxx" + > + </File> + <File + RelativePath=".\SelectTransporter.hxx" + > + </File> + <File + RelativePath=".\Signable.hxx" + > + </File> + <File + RelativePath=".\SignatureContext.hxx" + > + </File> + <File + RelativePath=".\SingleValue.hxx" + > + </File> + <File + RelativePath=".\StoreAns.hxx" + > + </File> + <File + RelativePath=".\StoreReq.hxx" + > + </File> + <File + RelativePath=".\StoreSet.hxx" + > + </File> + <File + RelativePath=".\TopologyAPI.hxx" + > + </File> + <File + RelativePath=".\TransactionController.hxx" + > + </File> + <File + RelativePath=".\TransactionState.hxx" + > + </File> + <File + RelativePath=".\TransApi.hxx" + > + </File> + <File + RelativePath=".\Transporter.hxx" + > + </File> + <File + RelativePath=".\TransporterMessage.hxx" + > + </File> + <File + RelativePath=".\Update.hxx" + > + </File> + <File + RelativePath=".\UserName.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/p2p/s2c/Makefile b/src/libs/resiprocate/p2p/s2c/Makefile new file mode 100644 index 00000000..ffaf65b4 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/Makefile @@ -0,0 +1,40 @@ +# nrappkit is Network Resonance's application development kit. +# See http://nrappkit.sourceforge.net + +NRAPPKIT_SRC = /users/ekr/src/nrappkit/src/ +NRAPPKIT_MAKE=$(NRAPPKIT_SRC)make/freebsd + +#NRAPPKIT_SRC = /Users/ekr/src/nrappkit/src/ +#NRAPPKIT_MAKE=$(NRAPPKIT_SRC)make/darwin + + +RESIPROCATE_SRCDIR=/users/ekr/src/resiprocate/main/ +RESIPROCATE_PLATFORM=FreeBSD.i386 +RESIPROCATE_DEBUG=debug. + +YFLAGS = -dv +CFLAGS = -g -DYYDEBUG=0 -I$(NRAPPKIT_MAKE) -I$(NRAPPKIT_SRC)util/libekr +CFLAGS += -DHAVE_STRDUP +LDFLAGS = -L$(NRAPPKIT_MAKE) -lnrappkit + + +SRC = gram.y scan.l +OBJ = gram.o scan.o gen.o + +s2c: main.o $(OBJ) + cc $(CFLAGS) -g -o $@ main.o $(OBJ) $(LDFLAGS) + +test: test_driver.o test.o s2c_native.o + cc $(CFLAGS) -g -o $@ test_driver.o test.o s2c_native.o $(LDFLAGS) + +$(OBJ): y.tab.h + +y.tab.h: gram.c gram.y + +scan.c : y.tab.h +scan.o : y.tab.h + +clean : + rm -f y.tab.h y.output *.o clic gram.c + + diff --git a/src/libs/resiprocate/p2p/s2c/make/freebsd/Makefile b/src/libs/resiprocate/p2p/s2c/make/freebsd/Makefile new file mode 100644 index 00000000..a72f3113 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/make/freebsd/Makefile @@ -0,0 +1,22 @@ +PLATFORM=freebsd +CC=gcc -g +CXX=g++ -g +BINARY_PATH=$(PWD)/ + +RESIPROCATE_SRCDIR=/users/ekr/src/resip/main/ +RESIPROCATE_PLATFORM=FreeBSD.i386 +RESIPROCATE_DEBUG=debug. + +#all: programs +include ../generic/pre.mk + +CFLAGS += -DSANITY_CHECKS -Wno-unused -DNDEBUG -DFREEBSD +CFLAGS += -fPIC +CFLAGS += -DHAVE_STRLCPY # cleanup for libpcap +CFLAGS += -DHAVE_SIN_LEN +CFLAGS += -DDEBUG + +GLOBAL_LDFLAGS += -Wl,--export-dynamic + +include ../generic/targets.mk + diff --git a/src/libs/resiprocate/p2p/s2c/make/generic/compile_wrap b/src/libs/resiprocate/p2p/s2c/make/generic/compile_wrap new file mode 100644 index 00000000..6ab3d1b5 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/make/generic/compile_wrap @@ -0,0 +1,19 @@ +$COMMAND1 = shift @ARGV; +$FILE = shift @ARGV; +$FILEOUT = shift @ARGV; + +print ("Running $COMMAND1 $FILE\n"); + +system("$COMMAND1 $FILE") && die("Error"); + +# Now run the compile +while($arg = shift @ARGV){ + $arg = $FILEOUT if $arg eq $FILE; + push(@ARGS,$arg); +} + +print(join(" ",@ARGS)); + +exec(@ARGS); + + diff --git a/src/libs/resiprocate/p2p/s2c/make/generic/dirs.mk b/src/libs/resiprocate/p2p/s2c/make/generic/dirs.mk new file mode 100644 index 00000000..2ce8ed41 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/make/generic/dirs.mk @@ -0,0 +1,35 @@ +# +# Copyright (C) 2006, Network Resonance, Inc. +# All Rights Reserved +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Network Resonance, Inc. nor the name of any +# contributors to this software may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +S2C_S2C_SRCDIR=$(S2C_SRC)s2c/ + + +#include the platform port definitions +include $(S2C_S2C_SRCDIR)targets.mk diff --git a/src/libs/resiprocate/p2p/s2c/make/generic/pre.mk b/src/libs/resiprocate/p2p/s2c/make/generic/pre.mk new file mode 100644 index 00000000..676d7f54 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/make/generic/pre.mk @@ -0,0 +1,53 @@ +# +# Copyright (C) 2006, Network Resonance, Inc. +# All Rights Reserved +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Network Resonance, Inc. nor the name of any +# contributors to this software may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + + +NRAPPKIT_SRC = /users/ekr/src/nrappkit/src/ +NRAPPKIT_MAKE=$(NRAPPKIT_SRC)make/$(PLATFORM) + +S2C_SRC=../../ + +include $(PWD)/../generic/rules.mk +include $(PWD)/../generic/dirs.mk +include $(PWD)/../generic/test-dirs.mk +-include $(PWD)/*.d + +GLOBAL_BUILD += $(GLOBAL_LIBNAME) + +GLOBAL_CFLAGS += -I. +GLOBAL_CFLAGS += -DHAVE_STRDUP -D__UNUSED__="__attribute__((unused))" -I$(NRAPPKIT_MAKE) -I$(NRAPPKIT_SRC)util/libekr/ -Werror +GLOBAL_CFLAGS += -Wno-unused + +GLOBAL_LDFLAGS = -L$(NRAPPKIT_MAKE) -lnrappkit + +MODDYAR=$(DYAR) + + diff --git a/src/libs/resiprocate/p2p/s2c/make/generic/rules.mk b/src/libs/resiprocate/p2p/s2c/make/generic/rules.mk new file mode 100644 index 00000000..343b267d --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/make/generic/rules.mk @@ -0,0 +1,47 @@ +# +# Copyright (C) 2006, Network Resonance, Inc. +# All Rights Reserved +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Network Resonance, Inc. nor the name of any +# contributors to this software may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# +# defaults +# +OBJSUFFIX=o +ARSUFFIX=a +RANLIB=ranlib +CP=cp + +COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) -c -o +LINK.c = $(CC) $(LDFLAGS) -o +COMPILE.cxx = $(CXX) $(CFLAGS) $(CPPFLAGS) -c -o +LINK.cxx = $(CXX) $(LDFLAGS) -o + +COMPILE.clic = ../../tools/clic/clic $< -- $(COMPILE.c) +COMPILE.y = perl ../generic/compile_wrap "yacc -dv -o $(<:.y=.c)" $< $(<:.y=.c) $(COMPILE.c) +COMPILE.l = perl ../generic/compile_wrap "lex -o$(<:.l=.c)" $< $(<:.l=.c) $(COMPILE.c) +COMPILE.s2c = perl ../generic/compile_wrap "./s2c " $< `basename $(<:.s2c=Gen.cxx)` $(COMPILE.c) \ No newline at end of file diff --git a/src/libs/resiprocate/p2p/s2c/make/generic/targets.mk b/src/libs/resiprocate/p2p/s2c/make/generic/targets.mk new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/resiprocate/p2p/s2c/make/generic/test-dirs.mk b/src/libs/resiprocate/p2p/s2c/make/generic/test-dirs.mk new file mode 100644 index 00000000..d9b93b2d --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/make/generic/test-dirs.mk @@ -0,0 +1,3 @@ +S2C_S2C_TEST_SRCDIR=$(S2C_S2C_SRCDIR)test/ + +include $(S2C_S2C_TEST_SRCDIR)targets.mk \ No newline at end of file diff --git a/src/libs/resiprocate/p2p/s2c/s2c/Makefile b/src/libs/resiprocate/p2p/s2c/s2c/Makefile new file mode 100644 index 00000000..6e13e763 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/Makefile @@ -0,0 +1,52 @@ +# $Id: Makefile,v 1.9 2004/05/10 01:12:46 jason Exp $ + +BUILD = ../../../build +include $(BUILD)/Makefile.pre + +CXXFLAGS += -I.. + +PACKAGES += RUTIL OPENSSL PTHREAD POPT + +CODE_SUBDIRS := + +TARGET_LIBRARY := libs2c + +TESTPROGRAMS := + +SRC += s2c_native.cxx + +include $(BUILD)/Makefile.post + +#====================================================================== +# Copyright (c) 2008, Various contributors to the Resiprocate project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# - The names of the project's contributors may not be used to +# endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +#====================================================================== diff --git a/src/libs/resiprocate/p2p/s2c/s2c/gen.c b/src/libs/resiprocate/p2p/s2c/s2c/gen.c new file mode 100644 index 00000000..e6cb1738 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/gen.c @@ -0,0 +1,1015 @@ +/** + gen.c + + Copyright (C) 2008, RTFM, Inc. + All Rights Reserved. + + ekr@rtfm.com Fri May 2 22:12:12 2008 + */ + +//static char *RCSSTRING __UNUSED__="$Id$"; + +#include <string.h> +#include <stdlib.h> +#include "parser.h" + + +static int s2c_gen_pdu_h_select(p_decl *decl, FILE *out, int do_inline); +static int s2c_gen_encode_c_select(p_decl *decl, FILE *out, int do_inline); +static int s2c_gen_decode_c_select(p_decl *decl, FILE *out,char *instream,int do_inline); +static int s2c_gen_print_c_select(p_decl *decl, FILE *out,int do_inline); +static int s2c_gen_construct_c_member(p_decl *member, FILE *out,int indent, char *prefix); + +static char *camelback(char *name) + { + char *buf; + int j; + int i=0; + int leading=1; + + buf=RCALLOC(strlen(name)+10); + + for(j=0;j<strlen(name);j++){ + if(leading){ + buf[i++]=toupper(name[j]); + leading=0; + } + else{ + if(name[j]=='_'){ + leading=1; + } + else + buf[i++]=name[j]; + } + } + + return buf; + } + +char *name2namespace(char *name) + { + char *tmp=r_strdup(name); + char *p; + + p=tmp; + while(*p){ + if(!isalnum(*p)) + *p='_'; + p++; + } + + return(tmp); + } + +static char *type2class(char *name) + { + char *buf; + + buf=RCALLOC(strlen(name)+10); + + sprintf(buf,"%sStruct",camelback(name)); + + return buf; + } + + +static char *s2c_decl2type(p_decl *decl) + { + char *buf=RMALLOC(100); + + if(decl->type==TYPE_PRIMITIVE){ + return(decl->u.primitive_.type); + } + if(decl->type==TYPE_OBJECT){ + return(decl->u.object_.classname); + } + else if(decl->type==TYPE_ENUM){ + return(camelback(decl->name)); + } + else{ + snprintf(buf,100,"%s%c",type2class(decl->name),'*'); + return(buf); + } + } + +static char *name2var(char *name) + { + char *buf; + + buf=RCALLOC(strlen(name)+10); + + sprintf(buf,"m%s",camelback(name)); + + return buf; + } + + +static char *name2enum(char *name) + { + char *buf; + + buf=RCALLOC(strlen(name)+10); + + sprintf(buf,"t%s",camelback(name)); + + return buf; + } + +static int max2bytes(UINT4 max) + { + int b=0; + + while(max){ + b++; + max >>=8; + } + + return b; + } + +static int is_opaque(p_decl *decl) + { + if(!strcmp(decl->name,"opaque")) + return 1; + return 0; + } + +/* Generate H files */ +int s2c_gen_hdr_h(char *name, FILE *out) + { + + fprintf(out,"#ifndef _%s_h_\n#define _%s_h_\n\n",name,name); + fprintf(out,"#include \"p2p/s2c/s2c/s2c_native.hxx\"\n\nnamespace s2c {\n\n", + name2namespace(name)); + + return(0); + } + +static int s2c_gen_member_fxns_h(char *classname, char *name, FILE *out) + { + fprintf(out,"\n\n"); + fprintf(out," PDUMemberFunctions\n"); + + return(0); + } + +static int s2c_print_a_b_indent(char *a, char *b, FILE *out) + { + int indent=30; + + fprintf(out, " %s",a); + if(strlen(a) < 30) { + indent-=strlen(a); + } + else{ + indent=2; + } + + while(indent--){ + fprintf(out," "); + } + + fprintf(out, "%s;\n",b); + + return(0); + } + +static int s2c_gen_pdu_h_member(p_decl *member, FILE *out) + { + char buf[100]; + + switch(member->type){ + case TYPE_REF: + s2c_print_a_b_indent(s2c_decl2type(member->u.ref_.ref), + name2var(member->name),out); + break; + case TYPE_VARRAY: + if(!is_opaque(member->u.varray_.ref)){ + snprintf(buf,sizeof(buf),"std::vector<%s>", + s2c_decl2type(member->u.varray_.ref)); + s2c_print_a_b_indent(buf,name2var(member->name),out); + } + else{ + s2c_print_a_b_indent("resip::Data",name2var(member->name),out); + } + break; + case TYPE_ARRAY: + { + int ct; + + if(member->u.array_.ref->type != TYPE_PRIMITIVE) + nr_verr_exit("Don't know how to handle non-primitive arrays"); + + if((member->u.array_.length * 8) % (member->u.array_.ref->u.primitive_.bits)) + nr_verr_exit("Non-even array length for %s",member->name); + + ct=(member->u.array_.length*8) / (member->u.array_.ref->u.primitive_.bits); + + snprintf(buf,sizeof(buf), "%s[%d]", name2var(member->name),ct); + s2c_print_a_b_indent(s2c_decl2type(member->u.array_.ref), buf, out); + + break; + } + case TYPE_SELECT: + { + s2c_gen_pdu_h_select(member, out, 1); + } + break; + default: + nr_verr_exit("Don't know how to render element %s",member->name); + } + return(0); + } + + +static int s2c_gen_pdu_h_select(p_decl *decl, FILE *out, int do_inline) + { + p_decl *arm; + + if(!do_inline){ + /* First emit the class for the select itself */ + fprintf(out,"class %s : public PDU {\npublic:\n", type2class(decl->name)); + fprintf(out," %s();\n",type2class(decl->name)); + } + + /* Now emit each select arm */ + for(arm=STAILQ_FIRST(&decl->u.select_.arms);arm;arm=STAILQ_NEXT(arm,entry)){ + p_decl *member; + char armname[100]; + + snprintf(armname,100,"m%s",camelback(arm->name)); + + fprintf(out," struct %s_ {\n", armname); + + for(member=STAILQ_FIRST(&arm->u.select_arm_.members);member;member=STAILQ_NEXT(member,entry)){ + fprintf(out," "); + s2c_gen_pdu_h_member(member, out); + } + + fprintf(out," } %s;\n",armname); + } + + if(!do_inline){ + s2c_gen_member_fxns_h(type2class(decl->name),decl->name,out); + + fprintf(out,"};\n\n"); + } + + return(0); + } + + + +static int s2c_gen_pdu_h_struct(p_decl *decl, FILE *out) + { + p_decl *entry; + + fprintf(out,"class %s : public PDU {\npublic:\n", type2class(decl->name)); + fprintf(out," %s();\n",type2class(decl->name)); + fprintf(out," %s(const %s&);\n",type2class(decl->name),type2class(decl->name)); + + entry=STAILQ_FIRST(&decl->u.struct_.members); + while(entry){ + if(!entry->auto_len) + s2c_gen_pdu_h_member(entry, out); + + entry=STAILQ_NEXT(entry,entry); + } + + s2c_gen_member_fxns_h(type2class(decl->name),decl->name, out); + + fprintf(out,"};\n\n\n"); + + return(0); + } + +static int s2c_gen_pdu_h_enum(p_decl *decl, FILE *out) + { + p_decl *entry; + + fprintf(out,"typedef enum {\n"); + + entry=STAILQ_FIRST(&decl->u.enum_.members); + while(entry){ + fprintf(out," %s = %d",entry->name,entry->u.enum_value_.value); + entry=STAILQ_NEXT(entry,entry); + if(entry){ + fprintf(out,",\n"); + } + else{ + fprintf(out,"\n"); + } + } + + fprintf(out,"} %s;\n\n", camelback(decl->name)); + + return(0); + } + +int s2c_gen_pdu_h(p_decl *decl, FILE *out) + { + if(decl->type == TYPE_STRUCT){ + return(s2c_gen_pdu_h_struct(decl, out)); + } + else if(decl->type==TYPE_SELECT){ + return(s2c_gen_pdu_h_select(decl, out,0)); + } + else if(decl->type==TYPE_ENUM){ + return(s2c_gen_pdu_h_enum(decl,out)); + } + else + nr_verr_exit("Internal error: can't generate .h for PDU %s",decl->name); + + return(0); + } + + +int s2c_gen_ftr_h(FILE *out) + { + fprintf(out,"}\n\n#endif\n"); + + return(0); + } + + + +/* Generate C files */ +int s2c_gen_hdr_c(char *name,FILE *out) + { + fprintf(out,"#include <iostream>\n"); + fprintf(out,"#include <iomanip>\n"); + fprintf(out,"#include \"rutil/Logger.hxx\"\n"); + fprintf(out,"#include \"rutil/ParseException.hxx\"\n"); + fprintf(out,"#include \"rutil/Data.hxx\"\n"); + fprintf(out,"#include \"rutil/DataStream.hxx\"\n"); + fprintf(out,"#include \"P2PSubsystem.hxx\"\n"); + fprintf(out,"#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P\n"); + fprintf(out,"#include \"%sGen.hxx\"\n",name); + fprintf(out,"#include <assert.h>\n"); + fprintf(out,"\n"); + fprintf(out,"namespace s2c {\n"); + fprintf(out,"\n");fprintf(out,"\n"); + + fprintf(out,"/* EKR: Most unprincipled hack of the day */\n"); + fprintf(out,"#define TELLP(a) (static_cast<resip::DataStream &>(a)).tellp()\n"); + fprintf(out,"#define SEEKP(a,b) (static_cast<resip::DataStream &>(a)).seekp(b)\n"); + + return(0); + } + + +static int s2c_gen_encode_c_simple_type(p_decl *decl, char *prefix, char *reference, FILE *out) + { + /* We can get a primitive as a ref or directly here because of arrays versus + simple declarations*/ + if(decl->u.ref_.ref->type==TYPE_PRIMITIVE){ + fprintf(out," StackLog( << \"%s%s =\" << std::hex << (unsigned long long) %s%s );\n",prefix,reference, + prefix,reference); + fprintf(out," encode_uintX(out, %d, %s%s);\n", + decl->u.ref_.ref->u.primitive_.bits,prefix,reference); + } + else if(decl->u.ref_.ref->type==TYPE_ENUM){ + fprintf(out," encode_uintX(out, %d, (u_int64)(%s%s));\n", + 8*max2bytes(decl->u.ref_.ref->u.enum_.max),prefix,reference); + } + else if(decl->type==TYPE_PRIMITIVE){ + fprintf(out," StackLog( << \"%s%s =\" << std::hex << (unsigned long long) %s%s );\n",prefix,reference, + prefix,reference); + fprintf(out," encode_uintX(out, %d, %s%s);\n", + decl->u.primitive_.bits,prefix,reference); + } + else if(decl->type==TYPE_OBJECT){ + fprintf(out," out << %s%s;\n",prefix,reference); + } + else{ + fprintf(out," %s%s->encode(out);\n",prefix,reference); + } + return(0); + } + + +static int s2c_gen_encode_c_member(p_decl *member, FILE *out,int indent, char *prefix) + { + int i; + + for(i=0;i<indent;i++) fputc(' ',out); + + switch(member->type){ + case TYPE_REF: + s2c_gen_encode_c_simple_type(member,prefix,name2var(member->name),out); + break; + case TYPE_VARRAY: + { + char reference[100]; + int lengthbytes=max2bytes(member->u.varray_.length); + + if(!is_opaque(member->u.varray_.ref)){ + fprintf(out," {\n"); + fprintf(out," long pos1=TELLP(out);\n"); + fprintf(out," for(int i=0;i<%d;i++) out.put(0);\n",lengthbytes); + + fprintf(out," for(unsigned int i=0;i<%s%s.size();i++)\n",prefix,name2var(member->name)); + fprintf(out," {\n"); + snprintf(reference,sizeof(reference),"%s%s[i]",prefix,name2var(member->name)); + + for(i=0;i<indent+3;i++) fputc(' ',out); + s2c_gen_encode_c_simple_type(member->u.varray_.ref,"",reference,out); + fprintf(out," }\n"); + fprintf(out," long pos2=TELLP(out);\n"); + fprintf(out," SEEKP(out,pos1);\n"); + fprintf(out," encode_uintX(out, %d, (pos2 - pos1) - %d);\n", + lengthbytes*8, lengthbytes); + fprintf(out," SEEKP(out,pos2);\n"); + fprintf(out," }\n"); + break; + } + else { + // Special case Data for Duane + fprintf(out," encode_uintX(out, %d, %s%s.size());\n", + 8*lengthbytes, prefix, name2var(member->name)); + fprintf(out," out << %s%s;\n",prefix,name2var(member->name)); + } + } + break; + case TYPE_ARRAY: + { + char reference[100]; + int ct=(member->u.array_.length*8) / (member->u.array_.ref->u.primitive_.bits); + + fprintf(out," for(unsigned int i=0;i<%d;i++){\n",ct); + snprintf(reference,sizeof(reference),"%s%s[i]",prefix,name2var(member->name)); + + for(i=0;i<indent+3;i++) fputc(' ',out); + s2c_gen_encode_c_simple_type(member->u.array_.ref,"",reference,out); + + fprintf(out," }\n"); + break; + } + case TYPE_SELECT: + { + s2c_gen_encode_c_select(member, out, 1); + } + break; + default: + nr_verr_exit("Don't know how to render element %s",member->name); + } + return(0); + } + + +static int s2c_gen_encode_c_struct(p_decl *decl, FILE *out) + { + p_decl *entry; + int do_auto=0; + + fprintf(out,"void %s :: encode(std::ostream& out) const \n{\n",type2class(decl->name)); + + fprintf(out," StackLog(<< \"Encoding %s\");\n",type2class(decl->name)); + entry=STAILQ_FIRST(&decl->u.struct_.members); + + while(entry){ + if(entry->auto_len){ + if(do_auto) + nr_verr_exit("Auto len feature can only be used once per struct"); + + do_auto=entry->u.ref_.ref->u.primitive_.bits; + + fprintf(out," long pos1=TELLP(out);\n"); + fprintf(out," for(int i=0;i<%d;i++) out.put(0);\n",do_auto/8); + } + else{ + s2c_gen_encode_c_member(entry, out, 0,""); + } + + fprintf(out,"\n"); + entry=STAILQ_NEXT(entry,entry); + } + + if(do_auto){ + fprintf(out," long pos2=TELLP(out);\n"); + fprintf(out," SEEKP(out,pos1);\n"); + fprintf(out," encode_uintX(out, %d, (pos2 - pos1) - %d);\n", + do_auto, do_auto/8); + fprintf(out," SEEKP(out,pos2);\n"); + } + + fprintf(out,"};\n\n"); + + return(0); + } + +static int s2c_gen_encode_c_select(p_decl *decl, FILE *out, int do_inline) + { + p_decl *arm,*entry; + char prefix[100]; + + if(!do_inline){ + fprintf(out,"void %s :: encode(std::ostream& out) const\n{\n",type2class(decl->name)); + + fprintf(out," StackLog(<< \"Encoding %s\");\n",type2class(decl->name)); + } + + fprintf(out," switch(%s) {\n",name2var(decl->u.select_.switch_on)); + arm=STAILQ_FIRST(&decl->u.select_.arms); + while(arm){ + fprintf(out," case %d:\n",arm->u.select_arm_.value); + entry=STAILQ_FIRST(&arm->u.select_arm_.members); + while(entry){ + snprintf(prefix,100,"m%s.",camelback(arm->name)); + s2c_gen_encode_c_member(entry, out, 9, prefix); + entry=STAILQ_NEXT(entry,entry); + } + fprintf(out," break;\n\n"); + arm=STAILQ_NEXT(arm,entry); + } + fprintf(out," default: /* User error */ \n"); + fprintf(out," assert(1==0);\n"); + fprintf(out," }\n\n"); + + if(!do_inline){ + fprintf(out,"};\n"); + } + return(0); + } + + +static int s2c_gen_print_c_simple_type(p_decl *decl, char *reference, FILE *out) + { + /* We can get a primitive as a ref or directly here because of arrays versus + simple declarations*/ + + if(decl->u.ref_.ref->type==TYPE_PRIMITIVE){ + fprintf(out," do_indent(out, indent);\n"); + fprintf(out," (out) << \"%s:\" << std::hex << (unsigned long long)%s << \"\\n\"; \n", decl->name, reference); + } + else if(decl->u.ref_.ref->type==TYPE_ENUM){ + fprintf(out," do_indent(out, indent);\n"); + fprintf(out," (out) << \"%s:\" << std::hex << (unsigned long long) %s << \"\\n\"; \n", decl->name, reference); + } + + else if(decl->type==TYPE_PRIMITIVE){ + fprintf(out," do_indent(out, indent);\n"); + fprintf(out," (out) << \"%s:\" << std::hex << (unsigned long long) %s << \"\\n\"; \n", decl->name, reference); + } + else if(decl->type==TYPE_OBJECT){ + ; /* TODO */ + } + else + fprintf(out," %s->print(out, indent);\n",reference); + + return(0); + } + + +static int s2c_gen_print_c_member(p_decl *member, FILE *out) + { + int i; + char reference[100]; + + switch(member->type){ + case TYPE_REF: + s2c_gen_print_c_simple_type(member,name2var(member->name),out); + break; + case TYPE_VARRAY: + if(!is_opaque(member->u.varray_.ref)){ + fprintf(out," for(unsigned int i=0;i<%s.size();i++){\n",name2var(member->name)); + snprintf(reference,sizeof(reference),"%s[i]",name2var(member->name)); + + for(i=0;i<3;i++) fputc(' ',out); + s2c_gen_print_c_simple_type(member->u.varray_.ref,reference,out); + fprintf(out," }\n"); + } + else { + /* Special case Data for duane */ + fprintf(out, " out << %s.hex();\n",name2var(member->name)); + } + + break; + case TYPE_ARRAY: + { + char reference[100]; + int ct=(member->u.array_.length*8) / (member->u.array_.ref->u.primitive_.bits); + + fprintf(out," for(unsigned int i=0;i<%d;i++) {\n",ct); + snprintf(reference,sizeof(reference),"%s[i]",name2var(member->name)); + for(i=0;i<3;i++) fputc(' ',out); + s2c_gen_print_c_simple_type(member->u.array_.ref,reference,out); + fprintf(out," }\n"); + + break; + } + case TYPE_SELECT: + { + s2c_gen_print_c_select(member,out,1); + } + break; + default: + nr_verr_exit("Don't know how to render element %s",member->name); + } + return(0); + } + + + +static int s2c_gen_print_c_struct(p_decl *decl, FILE *out) + { + p_decl *entry; + + fprintf(out,"void %s :: print(std::ostream& out, int indent) const \n{\n",type2class(decl->name)); + fprintf(out," do_indent(out,indent);\n"); + fprintf(out," (out) << \"%s:\\n\";\n",decl->name); + fprintf(out," indent+=2;\n"); + + entry=STAILQ_FIRST(&decl->u.struct_.members); + + while(entry){ + if(!entry->auto_len) + s2c_gen_print_c_member(entry, out); + + entry=STAILQ_NEXT(entry,entry); + } + + fprintf(out,"};\n\n"); + + return(0); + } + +static int s2c_gen_decode_c_simple_type(p_decl *decl, char *prefix, char *reference, char *instream, FILE *out) + { + /* We can get a primitive as a ref or directly here because of arrays versus + simple declarations*/ + if(decl->u.ref_.ref->type==TYPE_PRIMITIVE){ + fprintf(out," decode_uintX(%s, %d, %s%s);\n", + instream,decl->u.ref_.ref->u.primitive_.bits,prefix,reference); + fprintf(out," StackLog( << \"%s%s =\" << std::hex << (unsigned long long) %s%s );\n",prefix,reference, + prefix,reference); + } + else if(decl->u.ref_.ref->type==TYPE_ENUM){ + fprintf(out," {\n"); + fprintf(out," u_int32 v;\n"); + fprintf(out," decode_uintX(%s, %d, v);\n",instream, + 8*max2bytes(decl->u.ref_.ref->u.enum_.max)); + fprintf(out," %s%s=(%s)v;\n",prefix,reference,decl->u.ref_.ref->name); + fprintf(out," }\n"); + + } + else if(decl->type==TYPE_PRIMITIVE){ + fprintf(out," decode_uintX(%s, %d, %s%s);\n", + instream,decl->u.primitive_.bits,prefix,reference); + fprintf(out," StackLog( << \"%s%s =\" << std::hex << (unsigned long long) %s%s );\n",prefix,reference, + prefix,reference); + } + else if(decl->type==TYPE_OBJECT){ + fprintf(out," %s%s << %s;\n",prefix,reference,instream); + } + else{ + if(decl->type==TYPE_REF){ + fprintf(out," %s%s = new %s();\n",prefix,reference,type2class(decl->u.ref_.ref->name)); + } + else{ + fprintf(out," %s%s = new %s();\n",prefix,reference,type2class(decl->name)); + } + + fprintf(out," %s%s->decode(%s);\n",prefix,reference,instream); + } + return(0); + } + +static int s2c_gen_decode_c_member(p_decl *member, FILE *out,char *instream,int indent, char *prefix) + { + int i; + + for(i=0;i<indent;i++) fputc(' ',out); + + switch(member->type){ + case TYPE_REF: + s2c_gen_decode_c_simple_type(member,prefix,name2var(member->name),instream,out); + break; + case TYPE_VARRAY: + if(!is_opaque(member->u.varray_.ref)){ + char reference[100]; + + fprintf(out," {\n"); + fprintf(out," resip::Data d;\n"); + fprintf(out," read_varray1(in, %d, d);\n",max2bytes(member->u.varray_.length)); + fprintf(out," resip::DataStream in2(d);\n"); + fprintf(out," int i=0;\n"); + fprintf(out," while(in2.peek()!=EOF){\n"); + fprintf(out," %s%s.push_back(0);\n",prefix,name2var(member->name)); + snprintf(reference,sizeof(reference),"%s[i]",name2var(member->name)); + for(i=0;i<indent+3;i++) fputc(' ',out); + s2c_gen_decode_c_simple_type(member->u.varray_.ref,prefix,reference,"in2",out); + fprintf(out," i++;\n"); + fprintf(out," }\n;"); + fprintf(out," }\n"); + } + else{ + /* Special case Data for Duane */ + fprintf(out," {\n"); + fprintf(out," UInt32 len;\n"); + fprintf(out," int c;\n"); + fprintf(out," decode_uintX(%s, %d, len);\n", + instream, max2bytes(member->u.varray_.length)*8); + fprintf(out," resip::DataStream strm(%s%s);\n",prefix,name2var(member->name)); + fprintf(out," while(len--){\n"); + fprintf(out," c=%s.get();\n",instream); + fprintf(out," if(c==EOF)\n"); + fprintf(out," throw resip::ParseException(\"Premature end of data\",\n"); + fprintf(out," \"%s\",__FILE__,__LINE__);\n",member->name); + fprintf(out," strm.put(c);\n",name2var(member->name)); + fprintf(out," };\n"); + fprintf(out," }\n"); + } + break; + case TYPE_ARRAY: + { + char reference[100]; + int ct=(member->u.array_.length*8) / (member->u.array_.ref->u.primitive_.bits); + + fprintf(out," for(unsigned int i=0;i<%d;i++){\n",ct); + snprintf(reference,sizeof(reference),"%s[i]",name2var(member->name)); + + for(i=0;i<indent+3;i++) fputc(' ',out); + s2c_gen_decode_c_simple_type(member->u.array_.ref,prefix,reference,instream,out); + fprintf(out," }\n"); + break; + } + case TYPE_SELECT: + { + s2c_gen_decode_c_select(member, out, instream, 1); + } + break; + default: + nr_verr_exit("Don't know how to render element %s%s",prefix,member->name); + } + return(0); + } + +static int s2c_gen_decode_c_struct(p_decl *decl, FILE *out) + { + p_decl *entry; + int do_auto=0; + + fprintf(out,"void %s :: decode(std::istream& in)\n{\n",type2class(decl->name)); + + fprintf(out," StackLog(<< \"Decoding %s\");\n",type2class(decl->name)); + entry=STAILQ_FIRST(&decl->u.struct_.members); + + while(entry){ + if(entry->auto_len){ + if(do_auto) + nr_verr_exit("Auto len feature can only be used once per struct"); + + do_auto=entry->u.ref_.ref->u.primitive_.bits; + fprintf(out," {\n"); + fprintf(out," resip::Data d;\n"); + fprintf(out," read_varray1(in, %d, d);\n",do_auto/8); + fprintf(out," resip::DataStream in_auto(d);\n"); + } + else{ + s2c_gen_decode_c_member(entry, out, do_auto?"in_auto":"in",0, ""); + } + + fprintf(out,"\n"); + entry=STAILQ_NEXT(entry,entry); + + } + if(do_auto) { + fprintf(out," if(in_auto.peek()!=EOF)\n"); + fprintf(out," throw resip::ParseException(\"Inner encoded value too long\",\n"); + fprintf(out," \"%s\",__FILE__,__LINE__);\n",decl->name); + fprintf(out," }\n"); + } + fprintf(out,"};\n\n"); + + return(0); + } + + + +static int s2c_gen_construct_c_select(p_decl *decl, FILE *out, int do_inline) + { + p_decl *arm,*entry; + char prefix[100]; + + if(!do_inline){ + fprintf(out,"%s :: %s ()\n{\n",type2class(decl->name), + type2class(decl->name)); + + fprintf(out," StackLog(<< \"Constructing %s\");\n",type2class(decl->name)); + fprintf(out," mName = \"%s\";\n", type2class(decl->name)); + + } + + arm=STAILQ_FIRST(&decl->u.select_.arms); + while(arm){ + entry=STAILQ_FIRST(&arm->u.select_arm_.members); + while(entry){ + snprintf(prefix,100,"m%s.",camelback(arm->name)); + s2c_gen_construct_c_member(entry, out, 9, prefix); + entry=STAILQ_NEXT(entry,entry); + } + arm=STAILQ_NEXT(arm,entry); + } + if(!do_inline){ + fprintf(out,"};\n"); + } + return(0); + } + + + +static int s2c_gen_construct_c_simple_type(p_decl *decl, char *prefix, char *reference, FILE *out) + { + if((decl->type == TYPE_REF) && (decl->u.ref_.ref->type==TYPE_ENUM)) + fprintf(out," %s%s=(%s)0;\n",prefix,reference,decl->u.ref_.ref->name); + else + fprintf(out," %s%s=0;\n",prefix,reference); + + + + + return(0); + } + +static int s2c_gen_construct_c_member(p_decl *member, FILE *out,int indent, char *prefix) + { + int i; + + switch(member->type){ + case TYPE_REF: + s2c_gen_construct_c_simple_type(member,prefix,name2var(member->name),out); + break; + case TYPE_VARRAY: + { + ; + } + break; + case TYPE_ARRAY: + { + char reference[100]; + int ct=(member->u.array_.length*8) / (member->u.array_.ref->u.primitive_.bits); + + fprintf(out," for(unsigned int i=0;i<%d;i++){\n",ct); + snprintf(reference,sizeof(reference),"%s%s[i]",prefix,name2var(member->name)); + + for(i=0;i<indent+3;i++) fputc(' ',out); + s2c_gen_construct_c_simple_type(member->u.array_.ref,"",reference,out); + fprintf(out,"}\n"); + } + break; + case TYPE_SELECT: + { + s2c_gen_construct_c_select(member, out, 1); + } + break; + default: + nr_verr_exit("Don't know how to render element %s",member->name); + } + } + +static int s2c_gen_construct_c_struct(p_decl *decl, FILE *out) + { + p_decl *entry; + + fprintf(out,"%s :: %s ()\n{\n",type2class(decl->name),type2class(decl->name)); + + fprintf(out," mName = \"%s\";\n", type2class(decl->name)); + fprintf(out," StackLog(<< \"Constructing %s\");\n",type2class(decl->name)); + entry=STAILQ_FIRST(&decl->u.struct_.members); + while(entry){ + if(!entry->auto_len){ + s2c_gen_construct_c_member(entry, out, 0, ""); + } + + fprintf(out,"\n"); + entry=STAILQ_NEXT(entry,entry); + } + + fprintf(out,"};\n\n"); + + return(0); + } + +static int s2c_gen_copy_construct_c_all(p_decl *decl, FILE *out) + { + fprintf(out,"%s :: %s (const %s &from)\n{\n",type2class(decl->name),type2class(decl->name), + type2class(decl->name)); + + fprintf(out," // World's lamest copy constructor\n"); + fprintf(out," if(this==&from) return;\n"); + fprintf(out," mName = \"%s\";\n", type2class(decl->name)); + fprintf(out," resip::Data dat;\n"); + fprintf(out," {\n"); + fprintf(out," resip::DataStream strm(dat);\n"); + fprintf(out," from.encode(strm);\n"); + fprintf(out," }\n"); + fprintf(out," {\n"); + fprintf(out," resip::DataStream strm(dat);\n"); + fprintf(out," decode(strm);\n"); + fprintf(out," }\n"); + fprintf(out,"}\n\n"); + } + +static int s2c_gen_pdu_c_struct(p_decl *decl, FILE *out) + { + fprintf(out,"\n\n// Classes for %s */\n\n",type2class(decl->name)); + + s2c_gen_construct_c_struct(decl, out); + s2c_gen_copy_construct_c_all(decl, out); + s2c_gen_print_c_struct(decl, out); + s2c_gen_decode_c_struct(decl, out); + s2c_gen_encode_c_struct(decl, out); + + return(0); + } + + +static int s2c_gen_print_c_select(p_decl *decl, FILE *out, int do_inline) + { + if(!do_inline){ + fprintf(out,"void %s :: print(std::ostream& out, int indent) const \n{\n",type2class(decl->name)); + } + + if(!do_inline){ + fprintf(out,"}\n"); + } + } + +static int s2c_gen_decode_c_select(p_decl *decl, FILE *out,char *instream, int do_inline) + { + p_decl *arm; + p_decl *entry; + char prefix[100]; + + if(!do_inline){ + fprintf(out,"void %s :: decode(std::istream& in)\n{\n",type2class(decl->name)); + + fprintf(out," StackLog(<< \"Decoding %s\");\n",type2class(decl->name)); + } + + fprintf(out," switch(%s){\n",name2var(decl->u.select_.switch_on)); + + arm=STAILQ_FIRST(&decl->u.select_.arms); + while(arm){ + fprintf(out," case %d:\n",arm->u.select_arm_.value); + entry=STAILQ_FIRST(&arm->u.select_arm_.members); + while(entry){ + snprintf(prefix,100,"m%s.",camelback(arm->name)); + s2c_gen_decode_c_member(entry, out, instream, 9, prefix); + entry=STAILQ_NEXT(entry,entry); + } + fprintf(out," break;\n\n"); + arm=STAILQ_NEXT(arm,entry); + } + fprintf(out," default: /* User error */ \n"); + fprintf(out," assert(1==0);\n"); + fprintf(out," }\n\n"); + + if(!do_inline){ + fprintf(out,"};\n"); + } + + return(0); + } + +static int s2c_gen_pdu_c_select(p_decl *decl, FILE *out) + { + fprintf(out,"\n\n// Classes for %s */\n\n",type2class(decl->name)); + + s2c_gen_construct_c_select(decl, out, 0); + s2c_gen_copy_construct_c_all(decl, out); + s2c_gen_print_c_select(decl, out,0 ); + s2c_gen_decode_c_select(decl, out, "in" ,0); + s2c_gen_encode_c_select(decl, out, 0); + + return(0); + } + +int s2c_gen_pdu_c(p_decl *decl, FILE *out) + { + if(decl->type == TYPE_STRUCT){ + return(s2c_gen_pdu_c_struct(decl, out)); + } + else if(decl->type==TYPE_SELECT){ + return(s2c_gen_pdu_c_select(decl, out)); + } + else if(decl->type==TYPE_ENUM){ + // Do nothing + } + else + nr_verr_exit("Internal error: can't generate .c for PDU %s",decl->name); + + + return(0); + } + + +int s2c_gen_ftr_c(FILE *out) + { + fprintf(out,"}\n"); + + return(0); + } + + diff --git a/src/libs/resiprocate/p2p/s2c/s2c/gen.h b/src/libs/resiprocate/p2p/s2c/s2c/gen.h new file mode 100644 index 00000000..7b340aac --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/gen.h @@ -0,0 +1,23 @@ +/** + gen.h + + Copyright (C) 2008, RTFM, Inc. + All Rights Reserved. + + ekr@rtfm.com Fri May 2 22:47:16 2008 + */ + + +#ifndef _gen_h +#define _gen_h + +int s2c_gen_hdr_h(char *name, FILE *out); +int s2c_gen_ftr_h(FILE *out); +int s2c_gen_hdr_c(char *name,FILE *out); +int s2c_gen_ftr_c(FILE *out); +int s2c_gen_pdu_h(p_decl *decl, FILE *out); + + +#endif + + diff --git a/src/libs/resiprocate/p2p/s2c/s2c/gram.y b/src/libs/resiprocate/p2p/s2c/s2c/gram.y new file mode 100644 index 00000000..e1a80300 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/gram.y @@ -0,0 +1,531 @@ +/** + ssl.y + + Copyright (C) 1998, RTFM, Inc. + All Rights Reserved. + + ekr@rtfm.com Fri Dec 25 20:33:47 1998 + */ + +/* %error-verbose */ + +%{ + +#include <stdlib.h> +#include <string.h> +#include "parser.h" +#include "r_log.h" +#include <stdio.h> + + +extern FILE *dotc; +extern FILE *doth; + +#define CURRENT_DECL current_decl[current_decl_depth] + +p_decl *current_decl[50]={0}; +int current_decl_depth=0; + +void push_decl(p_decl *decl) + { + r_log(LOG_GENERIC,LOG_DEBUG,"Pushing decl"); + current_decl[++current_decl_depth]=decl; + } + +void pop_decl() + { + r_log(LOG_GENERIC,LOG_DEBUG,"Popping decl %s, depth=%d",CURRENT_DECL->name, + current_decl_depth); + current_decl_depth--; + } + +p_decl *make_fwd_ref (char *type) + { + p_decl *decl; + + decl=RCALLOC(sizeof(p_decl)); + + decl->type=TYPE_FWDREF; + decl->u.fwd_ref_.type=r_strdup(type); + + return(decl); + } + +%} +%union { + unsigned int val; + char str[8192]; + p_decl *decl; +} + + +/*These tokens have attributes*/ +%token <str> NAME_ +%token <val> NUM_ + +/*Tokens*/ +%token <val> DOT_DOT_ +%token <val> PUBLIC_ +%token <val> STRUCT_ +%token <val> SELECT_ +%token <str> OPAQUE_ +%token <val> ENUM_ +%token <val> DIGITALLY_SIGNED_ +%token <val> COMMENT_START_ +%token <str> CODE_ +%token <val> COMMENT_END_ +%token <val> CASE_ +%token <val> CONSTANT_ +%token <val> PRIMITIVE_ +%token <val> TYPEDEF_ +%token <val> OBJECT_ + +/*Types for nonterminals*/ +%type <val> module +%type <val> typelist +%type <val> definition + /*%type <val> selecttype */ + /* %type <val> constant_type */ + /* %type <val> selecterateds*/ + /* %type <val> selectmax*/ + /* %type <val> constval*/ +%type <decl> declaration +%type <decl> select_arm +%type <decl> select +%type <str> p_type +%type <val> varray_size + +/*%type <val> selecterated*/ +%% +module: typelist + +typelist: definition {} +| +definition typelist {} +; + +definition: + | primitive + | struct_type + | enum + | select + | typedef + | object + { + + } +; + + +struct_start: STRUCT_ +{ + p_decl *decl=0; + + r_log(LOG_GENERIC,LOG_DEBUG,"struct start\n"); + + decl=RCALLOC(sizeof(p_decl)); + + decl->type=TYPE_STRUCT; + STAILQ_INIT(&decl->u.struct_.members); + push_decl(decl); + STAILQ_INSERT_TAIL(&public_decls,decl,entry); // All decls public here +}; + | PUBLIC_ STRUCT_ +{ + p_decl *decl=0; + + r_log(LOG_GENERIC,LOG_DEBUG,"struct start\n"); + + decl=RCALLOC(sizeof(p_decl)); + + decl->type=TYPE_STRUCT; + STAILQ_INIT(&decl->u.struct_.members); + push_decl(decl); + + STAILQ_INSERT_TAIL(&public_decls,decl,entry); +}; + + +struct_type : struct_start '{' struct_decls '}' NAME_ ';' + { + int r; + + CURRENT_DECL->name=r_strdup($5); + + r_log(LOG_GENERIC,LOG_DEBUG,"Finished with struct %s\n",$5); + + if(r=r_assoc_insert(types,CURRENT_DECL->name,strlen(CURRENT_DECL->name), + CURRENT_DECL,0,0,R_ASSOC_NEW)){ + r_log(LOG_GENERIC,LOG_DEBUG,"Couldn't insert struct %s. Exists?\n",$5); + exit(1); + } + pop_decl(); + } + +struct_decls : {}; + | struct_decls declaration + { + p_decl *decl=$2; + + r_log(LOG_GENERIC,LOG_DEBUG,"Adding type %s to %s\n", decl->name, CURRENT_DECL->name); + + STAILQ_INSERT_TAIL(&CURRENT_DECL->u.struct_.members,decl,entry); + }; + + +declaration : NAME_ NAME_ ';' + { + p_decl *decl=0; + void *v; + int r; + char *magic; + + if(r=r_assoc_fetch(types,$1, strlen($1), &v)){ + r_log(LOG_GENERIC,LOG_DEBUG,"Unknown type %s\n",$1); + + nr_verr_exit("Unknown type %s",$1); + + //v=make_fwd_ref($1); + + } + + decl=RCALLOC(sizeof(p_decl)); + + + decl->name=r_strdup($2); + decl->type = TYPE_REF; + decl->u.ref_.ref = v; + + if(magic=strchr(decl->name,'.')){ + magic++; + if(!strcmp(magic,"auto_len")){ + if(decl->u.ref_.ref->type != TYPE_PRIMITIVE) + nr_verr_exit("Auto len feature only usable with integers"); + decl->auto_len=1; + } + else{ + nr_verr_exit("Illegal magic operation %s",magic); + } + } + + $$=decl; + }; + | NAME_ NAME_ '<' varray_size '>' ';' + { + int r; + p_decl *decl; + void *v; + + + if(r=r_assoc_fetch(types,$1, strlen($1), &v)){ + r_log(LOG_GENERIC,LOG_DEBUG,"Unknown type %s\n",$1); + + nr_verr_exit("Unknown type %s",$1); + // v=make_fwd_ref($1); + } + + + decl=RCALLOC(sizeof(p_decl)); + decl->name=r_strdup($2); + decl->type = TYPE_VARRAY; + decl->u.varray_.ref = v; + decl->u.varray_.length = $4; + + $$=decl; + }; + | NAME_ NAME_ '[' NUM_ ']' ';' + { + int r; + p_decl *decl; + void *v; + + + if(r=r_assoc_fetch(types,$1, strlen($1), &v)){ + r_log(LOG_GENERIC,LOG_DEBUG,"Unknown type %s\n",$1); + + nr_verr_exit("Unknown type %s",$1); + // v=make_fwd_ref($1); + } + + + decl=RCALLOC(sizeof(p_decl)); + decl->name=r_strdup($2); + decl->type = TYPE_ARRAY; + decl->u.varray_.ref = v; + decl->u.varray_.length = $4; + + $$=decl; + }; + | select + { + $$ = $1; + } + + +varray_size: + NUM_ DOT_DOT_ NUM_ '^' NUM_ '-' NUM_ + { + unsigned long long l; + int i; + + if($5 <= 0) + nr_verr_exit("Bogus exponent %d in size expression",$5); + l=$3; + + for(i = 1; i<$5;i++){ + l *= $3; + } + + l -= $5; + + if(l > 0xffffffffu) + nr_verr_exit("Overflow value in size expression"); + + $$=(unsigned int)l; + } + | NUM_ + { + $$=$1; + } + +p_type : NAME_ + { + strcpy($$,$1); + } + | p_type NAME_ + { + sprintf($$,"%s %s",$1, $2); + } + +primitive : PRIMITIVE_ NAME_ p_type NUM_ ';' + { + p_decl *decl=0; + int r; + decl=RCALLOC(sizeof(p_decl)); + + decl->name=r_strdup($2); + decl->u.primitive_.bits=$4; + decl->u.primitive_.type=r_strdup($3); + + decl->type=TYPE_PRIMITIVE; + + if(r=r_assoc_insert(types,decl->name,strlen(decl->name), + decl,0,0,R_ASSOC_NEW)){ + r_log(LOG_GENERIC,LOG_DEBUG,"Couldn't insert primitive %s. Exists?\n",decl->name); + exit(1); + } + } + +object: OBJECT_ NAME_ NAME_ ';' + { + p_decl *decl=0; + int r; + decl=RCALLOC(sizeof(p_decl)); + + decl->name=r_strdup($3); + decl->u.object_.classname=r_strdup($2); + + decl->type=TYPE_OBJECT; + + if(r=r_assoc_insert(types,decl->name,strlen(decl->name), + decl,0,0,R_ASSOC_NEW)){ + r_log(LOG_GENERIC,LOG_DEBUG,"Couldn't insert object %s. Exists?\n",decl->name); + exit(1); + } + } + +enum_start: ENUM_ + { + p_decl *decl=0; + + r_log(LOG_GENERIC,LOG_DEBUG,"enums start\n"); + + decl=RCALLOC(sizeof(p_decl)); + + decl->type=TYPE_ENUM; + STAILQ_INIT(&decl->u.enum_.members); + push_decl(decl); + STAILQ_INSERT_TAIL(&public_decls,decl,entry); // All decls public here + } + +enum: enum_start '{' enumerateds '}' NAME_ ';' +{ + int r; + + CURRENT_DECL->name=r_strdup($5); + + r_log(LOG_GENERIC,LOG_DEBUG,"Finished with enum %s\n",$5); + + if(r=r_assoc_insert(types,CURRENT_DECL->name,strlen(CURRENT_DECL->name), + CURRENT_DECL,0,0,R_ASSOC_NEW)){ + r_log(LOG_GENERIC,LOG_DEBUG,"Couldn't insert enum %s. Exists?\n",$5); + exit(1); + } + + pop_decl(); +} + +enumerateds: enumerated {}; + | enumerated ',' enumerateds {}; + +enumerated: NAME_ '(' NUM_ ')' + { + p_decl *decl=0; + int r; + decl=RCALLOC(sizeof(p_decl)); + + decl->name=r_strdup($1); + decl->u.enum_value_.value=$3; + decl->type=TYPE_ENUM_VALUE; + + if(r=r_assoc_insert(types,decl->name,strlen(decl->name), + decl,0,0,R_ASSOC_NEW)){ + r_log(LOG_GENERIC,LOG_DEBUG,"Couldn't insert enum value %s. Exists?\n",$1); + exit(1); + } + + STAILQ_INSERT_TAIL(&CURRENT_DECL->u.enum_.members,decl,entry); + } +| '(' NUM_ ')' + + { + CURRENT_DECL->u.enum_.max=$2; + } + +select: select_start '{' select_arms '}' ';' +{ + int r; + +// CURRENT_DECL->name=r_strdup($5); + CURRENT_DECL->name=r_strdup("auto-generated"); + +/* + r_log(LOG_GENERIC,LOG_DEBUG,"Finished with select %s\n",$5); + + if(r=r_assoc_insert(types,CURRENT_DECL->name,strlen(CURRENT_DECL->name), + CURRENT_DECL,0,0,R_ASSOC_NEW)){ + r_log(LOG_GENERIC,LOG_DEBUG,"Couldn't insert struct %s. Exists?\n",$5); + exit(1); + } +*/ + $$ = CURRENT_DECL; + + pop_decl(); +}; + + +select_start: SELECT_ '(' NAME_ ')' +{ + p_decl *decl=0; + + r_log(LOG_GENERIC,LOG_DEBUG,"select start\n"); + + decl=RCALLOC(sizeof(p_decl)); + + decl->type=TYPE_SELECT; + STAILQ_INIT(&decl->u.select_.arms); + decl->u.select_.switch_on=r_strdup($3); + + push_decl(decl); + if(!CURRENT_DECL) + STAILQ_INSERT_TAIL(&public_decls,decl,entry); +}; + +/* | PUBLIC_ SELECT_ +{ + p_decl *decl=0; + + r_log(LOG_GENERIC,LOG_DEBUG,"select start\n"); + + decl=RCALLOC(sizeof(p_decl)); + + decl->type=TYPE_SELECT; + decl->u.select_.switch_on=r_strdup($ 4); + STAILQ_INIT(&decl->u.select_.arms); + push_decl(decl); + if(!CURRENT_DECL) + STAILQ_INSERT_TAIL(&public_decls,decl,entry); +}; +*/ + + + +select_arms : {}; + | select_arms select_arm + { + p_decl *decl=$2; + + r_log(LOG_GENERIC,LOG_DEBUG,"Adding arm %s to %s\n", decl->name, CURRENT_DECL->name); + + STAILQ_INSERT_TAIL(&CURRENT_DECL->u.select_.arms,decl,entry); + }; + +select_arm_start: CASE_ NAME_ ':' + { + void *v; + p_decl *decl=0; + p_decl *value; + int r; + + decl=RCALLOC(sizeof(p_decl)); + + + if(r=r_assoc_fetch(types,$2, strlen($2), &v)){ + nr_verr_exit("Unknown value %s\n",$2); + exit(1); + } + value=v; + if(value->type != TYPE_ENUM_VALUE) + nr_verr_exit("%s is not a constant/enum",value->name); + + decl->type=TYPE_SELECT_ARM; + decl->name=r_strdup($2); + decl->u.select_arm_.value=value->u.enum_value_.value; + + STAILQ_INIT(&decl->u.select_arm_.members); + + push_decl(decl); + } + + +select_arm: select_arm_start select_arm_decls + { + void *v; + p_decl *decl=0; + p_decl *value; + int r; + + + $$=CURRENT_DECL; + + pop_decl(); + } + +select_arm_decls: {}; + | select_arm_decls declaration + { + p_decl *decl=$2; + +// r_log(LOG_GENERIC,LOG_DEBUG,"Adding type %s to %s",decl->name,CURRENT_DECL->name); + + STAILQ_INSERT_TAIL(&CURRENT_DECL->u.select_arm_.members,decl,entry); + } + | ';' + { + } + + +typedef: TYPEDEF_ declaration + { + int r; + + if(r=r_assoc_insert(types,$2->name,strlen($2->name), + $2,0,0,R_ASSOC_NEW)){ + r_log(LOG_GENERIC,LOG_DEBUG,"Couldn't insert struct %s. Exists?\n",$2->name); + exit(1); + } + }; + + + + diff --git a/src/libs/resiprocate/p2p/s2c/s2c/parser.h b/src/libs/resiprocate/p2p/s2c/s2c/parser.h new file mode 100644 index 00000000..4827984f --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/parser.h @@ -0,0 +1,89 @@ +/** + parser.h + + Copyright (C) 2007, Network Resonance, Inc. + All Rights Reserved. + + ekr@networkresonance.com Tue Nov 13 16:18:32 2007 + */ + + +#ifndef _parser_h +#define _parser_h + +#include "r_common.h" +#include "r_assoc.h" + +#include <sys/queue.h> + +typedef STAILQ_HEAD(p_decl_head_,p_decl_) p_decl_head; + +typedef struct p_decl_ { + char *name; + int type; + int auto_len; + +#define TYPE_PRIMITIVE 1 +#define TYPE_VARRAY 2 +#define TYPE_STRUCT 3 +#define TYPE_REF 4 +#define TYPE_SELECT 6 +#define TYPE_SELECT_ARM 7 +#define TYPE_FWDREF 8 +#define TYPE_ARRAY 9 +#define TYPE_ENUM 10 +#define TYPE_ENUM_VALUE 11 +#define TYPE_OBJECT 12 + + union { + struct { + char *type; + int bits; + } primitive_; + struct { + UINT4 length; + struct p_decl_ *ref; + } varray_; + struct { + p_decl_head members; + } struct_; + struct { + struct p_decl_ *ref; + } ref_; + struct { + char *switch_on; + p_decl_head arms; + } select_; + struct { + int value; + p_decl_head members; + } select_arm_; + struct { + char *type; + } fwd_ref_; + struct { + UINT4 length; + struct p_decl_ *ref; + } array_; + struct { + int max; + p_decl_head members; + } enum_; + struct { + int value; + } enum_value_; + struct { + char *classname; + } object_; + } u; + + STAILQ_ENTRY(p_decl_) entry; +} p_decl; + +extern r_assoc *types; + + +extern p_decl_head public_decls; + +#endif + diff --git a/src/libs/resiprocate/p2p/s2c/s2c/s2c.c b/src/libs/resiprocate/p2p/s2c/s2c/s2c.c new file mode 100644 index 00000000..f1cbc9e9 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/s2c.c @@ -0,0 +1,185 @@ +/** + main.c + + + Copyright (C) 1999-2000 RTFM, Inc. + All Rights Reserved + + This package is a SSLv3/TLS protocol analyzer written by Eric Rescorla + <ekr@rtfm.com> and licensed by RTFM, Inc. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + + This product includes software developed by Eric Rescorla for + RTFM, Inc. + + 4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may be + used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE. + + $Id: main.c,v 1.2 2000/10/17 16:10:01 ekr Exp $ + + + ekr@rtfm.com Mon Jan 18 16:28:43 1999 + */ + + +static char *RCSSTRING="$Id: main.c,v 1.2 2000/10/17 16:10:01 ekr Exp $"; + +extern int yydebug; + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include "parser.h" +#include "gen.h" +#include "r_log.h" + +extern int yydebug; + +FILE *doth,*dotc; + +r_assoc *types; +p_decl_head public_decls; + +int parser_preload() + { + int r; + + r_assoc_create(&types,r_assoc_crc32_hash_compute,10); + STAILQ_INIT(&public_decls); + } + + +int main(argc,argv) + int argc; + char **argv; + { + char namec[100],nameh[100]; + FILE *in; + FILE *dotc; + FILE *doth; + char base_name[100]={0}; + int c; + extern char *optarg; + extern int optind; + + p_decl *decl; + + parser_preload(); + + while((c=getopt(argc,argv,"b:"))!=-1){ + switch(c){ + case 'b': + strcpy(base_name,optarg); + break; + default: + nr_verr_exit("Bogus argument"); + } + } + + argc-=optind; + argv+=optind; + + /* Read the prologue */ + if(!(in=freopen("./decls.s2c","r",stdin))){ + nr_verr_exit("Couldn't read decls"); + } + yyparse(); + fclose(in); + yyset_lineno(1); + + if(argc==1){ + char *ptr,*sl=0; + if(!(in=freopen(argv[0],"r",stdin))) + nr_verr_exit("Couldn't open input file %s\n",argv[0]); + + if(strlen(base_name)==0){ + ptr=argv[0]+strlen(argv[0])-1; + while(ptr >= argv[0]){ + if(*ptr=='/'){ + sl=ptr; + break; + } + ptr--; + } + if(sl){ + sl++; + strncpy(base_name,sl,sizeof(base_name)); + } + else{ + strncpy(base_name,argv[0],sizeof(base_name)); + } + + if(strcmp(base_name + strlen(base_name)-4,".s2c")) + nr_verr_exit("Wrong file type %s",base_name); + base_name[strlen(base_name)-4]=0; + } + } + else{ + nr_verr_exit("usage: s2c [-b base_name] <input-file>"); + } + snprintf(nameh,sizeof(nameh),"%sGen.hxx",base_name); + if(!(doth=fopen(nameh,"w"))) + nr_verr_exit("Couldn't open %s",nameh); + + snprintf(namec,sizeof(namec),"%sGen.cxx",base_name); + if(!(dotc=fopen(namec,"w"))) + nr_verr_exit("Couldn't open %s",namec); + + yyparse(); + + decl=STAILQ_FIRST(&public_decls); + + s2c_gen_hdr_h(base_name,doth); + s2c_gen_hdr_c(base_name,dotc); + + while(decl){ + s2c_gen_pdu_h(decl, doth); + + s2c_gen_pdu_c(decl, dotc); + + decl=STAILQ_NEXT(decl,entry); + } + + s2c_gen_ftr_h(doth); + s2c_gen_ftr_c(dotc); + + exit(0); + } + + +extern int yylineno; + +int yywrap() +{ +;} + +int yyerror(s) + char *s; + { + printf("Parse error %s at line %d\n",s,yylineno); + exit(1); + } diff --git a/src/libs/resiprocate/p2p/s2c/s2c/s2c_native.cxx b/src/libs/resiprocate/p2p/s2c/s2c/s2c_native.cxx new file mode 100644 index 00000000..d223f6f7 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/s2c_native.cxx @@ -0,0 +1,200 @@ +/** + s2c_native.cxx + + Copyright (C) 2008, RTFM, Inc. + All Rights Reserved. + + ekr@rtfm.com Fri May 2 17:04:55 2008 +*/ + + + +#include <assert.h> +#include "rutil/Data.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/ParseException.hxx" +#include "s2c_native.hxx" + +void s2c::encode_uintX(std::ostream& out, const unsigned int bits, const u_int64 value) + { + int size; + + assert((bits%8)==0); + assert(bits<=64); + + size=bits/8; + + switch(size){ + case 8: + out.put(((value>>56)&0xff)); + case 7: + out.put(((value>>48)&0xff)); + case 6: + out.put(((value>>40)&0xff)); + case 5: + out.put(((value>>32)&0xff)); + case 4: + out.put(((value>>24)&0xff)); + case 3: + out.put(((value>>16)&0xff)); + case 2: + out.put(((value>>8)&0xff)); + case 1: + out.put(value&0xff); + break; + default: + assert(1==0); + } + } + + +void s2c::decode_uintX(std::istream& in, const unsigned int bits, u_char &value) + { + int size; + int c; + + assert(bits<=8); + + size=bits/8; + + value=0; + + while(size--){ + value <<=8; + c=in.get(); + + if(c==EOF) + throw resip::ParseException("Unexpected end of encoding","",__FILE__,__LINE__); + value |= c; + } + } + + +/*void s2c::decode_uintX(std::istream& in, const unsigned int bits, u_int8 &value) + { + int size; + int c; + + assert(bits==8); + + size=bits/8; + + value=0; + + while(size--){ + value <<=8; + c=in->get(); + value |= c; + } + } +*/ +void s2c::decode_uintX(std::istream& in, const unsigned int bits, u_int16 &value) + { + int size; + int c; + + assert(bits<=16); + + size=bits/8; + + value=0; + + while(size--){ + value <<=8; + c=in.get(); + if(c==EOF) + throw resip::ParseException("Unexpected end of encoding","",__FILE__,__LINE__); + + + value |= c; + } + } + +void s2c::decode_uintX(std::istream& in, const unsigned int bits, u_int32 &value) + { + int size; + int c; + + assert(bits<=32); + + size=bits/8; + + value=0; + + while(size--){ + value <<=8; + + c=in.get(); + if(c==EOF) + throw resip::ParseException("Unexpected end of encoding","",__FILE__,__LINE__); + + value |= c; + } + } + +void s2c::decode_uintX(std::istream& in, const unsigned int bits, u_int64 &value) + { + int size; + int c; + + assert(bits<=64); + + size=bits/8; + + value=0; + + while(size--){ + value <<=8; + c=in.get(); + if(c==EOF) + throw resip::ParseException("Unexpected end of encoding","",__FILE__,__LINE__); + value |= c; + } + } + +void s2c::do_indent(std::ostream& out, int indent) + { + while(indent--) out << ' '; + } + +// This is really clumsy, but I don't understand rutil +// TODO: !ekr! cleanup +void s2c::read_varray1(std::istream& in, unsigned int lenlen, resip::Data &buf) + { + u_int64 len=0; + int c; + + // First read the length + assert(lenlen<=8); + while(lenlen--){ + len<<=8; + c=in.get(); + if(c==EOF) + throw resip::ParseException("Unexpected end of encoding","",__FILE__,__LINE__); + len|=c; + } + + resip::DataStream out(buf); + + while(len--){ + c=in.get(); + if(c==EOF) + throw resip::ParseException("Unexpected end of encoding","",__FILE__,__LINE__); + + out.put(c); + } + + out.flush(); + } + +s2c::PDU::~PDU() +{ +} + +std::ostream& +operator<<(std::ostream& strm, const s2c::PDU& pdu) +{ + pdu.print(strm); + return strm; +} + diff --git a/src/libs/resiprocate/p2p/s2c/s2c/s2c_native.hxx b/src/libs/resiprocate/p2p/s2c/s2c/s2c_native.hxx new file mode 100644 index 00000000..f0f4491c --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/s2c_native.hxx @@ -0,0 +1,73 @@ +/** + s2c_native.hxx + + Copyright (C) 2008, RTFM, Inc. + All Rights Reserved. + + ekr@rtfm.com Fri May 2 16:58:21 2008 +*/ + + +#ifndef _s2c_native_h +#define _s2c_native_h + +#include <iostream> +#include <vector> +#include <string> + +/* Typedefs for integral types */ +typedef unsigned char u_char; +typedef unsigned char u_int8; +typedef unsigned short u_int16; +typedef unsigned int u_int32; +typedef unsigned long long u_int64; + +typedef signed char int8; +typedef signed short int16; +typedef signed int int32; +typedef signed long long int64; + +namespace s2c { + +class PDU { + public: + virtual ~PDU()=0; + + std::string mName; + + virtual void print(std::ostream& out) const + { + print(out, 0); + } + + virtual void print(std::ostream& out, int indent) const + { + out << mName << "(empty)" << "\n"; + } + + virtual void encode(std::ostream& out) const=0; + virtual void decode(std::istream& in)=0; +}; + +#define PDUMemberFunctions \ +virtual void print(std::ostream& out, int indent) const; \ +virtual void encode(std::ostream& out) const; \ +virtual void decode(std::istream& in); + + +/* Functions for primitive integral types */ +void encode_uintX(std::ostream& out, const unsigned int bits, const u_int64 value); +void decode_uintX(std::istream& in, const unsigned int bits, u_char &value); +//void decode_uintX(std::istream& in, const unsigned int bits, u_int8 &value); +void decode_uintX(std::istream& in, const unsigned int bits, u_int16 &value); +void decode_uintX(std::istream& in, const unsigned int bits, u_int32 &value); +void decode_uintX(std::istream& in, const unsigned int bits, u_int64 &value); + +void do_indent(std::ostream& out, int indent); +void read_varray1(std::istream& in, unsigned int lenlen, resip::Data &buf); + +} /* Close of namespace */ + +std::ostream& operator<<(std::ostream& strm, const s2c::PDU& pdu); + +#endif diff --git a/src/libs/resiprocate/p2p/s2c/s2c/scan.l b/src/libs/resiprocate/p2p/s2c/s2c/scan.l new file mode 100644 index 00000000..186dc58c --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/scan.l @@ -0,0 +1,73 @@ +%option yylineno + +%{ +#include "parser.h" +#include "gram.h" + +#if 0 +#define RETURN(x) printf("TOK:%s\n",#x); return(x) +#else +#define RETURN return +#endif + +long strtol(); +%} + +IDCHAR [a-zA-Z0-9_\-\.] +NUMCHAR [0-9] +S [ \t\n\r\f]+ +NAME [a-zA-Z]{IDCHAR}* +NUM {NUMCHAR}+ +HEXNUM "0x"[0-9A-Za-z]+ +COMMENT "/*"("*"?[^/]+)*("*/") +CODE "{@"[^@]+"@}" +%% + +".." {RETURN(DOT_DOT_);} +"enum" {RETURN(ENUM_);} +"struct" {RETURN(STRUCT_);} +"select" {RETURN(SELECT_);} +"constant" {RETURN(CONSTANT_);} +"digitally-signed" {/* Do nothing*/} +"public-key-encrypted" {/* Do nothing*/} +"case" {RETURN(CASE_);} +"public" {RETURN(PUBLIC_);} +"primitive" {RETURN(PRIMITIVE_);} +"typedef" {RETURN(TYPEDEF_);} +"object" {RETURN(OBJECT_);} + +{COMMENT} { /*Do nothing*/} +{CODE} { strcpy(yylval.str,yytext); RETURN(CODE_);} + +{S} {/*do nothing*/} +{NAME} {mkname();RETURN(NAME_);} +{NUM} {yylval.val=atoi(yytext); RETURN(NUM_);} +{HEXNUM} {yylval.val=strtol(yytext,0,16); RETURN(NUM_);} +"{" { RETURN('{'); } +"}" { RETURN('}'); } +"(" { RETURN('('); } +")" { RETURN(')'); } +"[" { RETURN('['); } +"]" { RETURN(']'); } +"<" { RETURN('<'); } +">" { RETURN('>'); } +";" { RETURN(';'); } +":" { RETURN(':'); } +"," { RETURN(','); } +"." { RETURN('.'); } +"^" { RETURN('^'); } +"-" { RETURN('-'); } +"=" { RETURN('='); } +. { fprintf(stderr,"Invalid input token: %s at %d!!!\n",yytext,yylineno); + exit(1); + } + +%% +int mkname() +{ +#if 0 +printf("%s\n",yytext); +#endif +strcpy(yylval.str,yytext); +} + diff --git a/src/libs/resiprocate/p2p/s2c/s2c/targets.mk b/src/libs/resiprocate/p2p/s2c/s2c/targets.mk new file mode 100644 index 00000000..ba32028a --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/targets.mk @@ -0,0 +1,157 @@ +# +# targets.mk +# +# $Source$ +# $Revision$ +# $Date$ +# +# Copyright (C) 2008, Network Resonance, Inc. +# All Rights Reserved. +# + +# S2C_S2C_ARCHIVE: +# source files to compile to object and to place in a library archive +# +# S2C_S2C_ARCHIVE_NAME: +# the library name to use to archive the object files +# +# S2C_S2C_ARCHIVE_TYPE: +# either 'static', 'dynamic', or 'jni' (the default is 'static') +# +# S2C_S2C_AUTOGENERATED: +# whether this targets.mk is autogenerated (either 'true' or 'false') +# +# S2C_S2C_COMPILE: +# source files to compile to object +# +# S2C_S2C_COPY: +# files to copy to the build directory +# +# S2C_S2C_GLOBAL_CFLAGS: +# preprocessor and compile-time flags specific to compiling +# everything +# +# S2C_S2C_GLOBAL_LDFLAGS: +# link-time flags specific to linking everything +# +# S2C_S2C_LINK: +# source files compile and link +# +# S2C_S2C_LOCAL_CFLAGS: +# preprocessor and compile-time flags specific to compiling only +# the files in this module directory +# +# S2C_S2C_LOCAL_LDFLAGS: +# link-time flags specific to linking only the files in +# this module directory +# +# S2C_S2C_PREFIX: +# defines the module name, which also serves as the +# prefix for all the variable names defined in this file +# +# S2C_S2C_SUBDIRS: +# subdirectories containing additional targets.mk files +# +S2C_S2C_ARCHIVE = gen.c gram.y scan.l +S2C_S2C_ARCHIVE_NAME = s2c +S2C_S2C_ARCHIVE_TYPE = +S2C_S2C_AUTOGENERATED = true +S2C_S2C_COMPILE = s2c_native.cxx +S2C_S2C_COPY = s2c_native.hxx +S2C_S2C_GLOBAL_CFLAGS = +S2C_S2C_GLOBAL_LDFLAGS = +S2C_S2C_LINK = s2c.c +S2C_S2C_LOCAL_CFLAGS = -I$(RESIPROCATE_SRCDIR) -I$(RESIPROCATE_SRCDIR)rutil +S2C_S2C_LOCAL_LDFLAGS = -L. -ls2c -L$(RESIPROCATE_SRCDIR)rutil/obj.$(RESIPROCATE_DEBUG)$(RESIPROCATE_PLATFORM) -lrutil +S2C_S2C_PREFIX = S2C_S2C +S2C_S2C_SUBDIRS = + + + +# +# AUTOMATICALLY-GENERATED SECTION +# + + + +# +# LOCAL ENVIRONMENT +# +S2C_S2C_BUILD = gen.$(OBJSUFFIX) gen.d gram.$(OBJSUFFIX) \ + gram.d libs2c.$(ARSUFFIX) s2c \ + s2c.$(OBJSUFFIX) s2c.d \ + s2c_native.$(OBJSUFFIX) s2c_native.d \ + s2c_native.hxx scan.$(OBJSUFFIX) scan.d + + + +# +# GLOBAL ENVIRONMENT +# +GLOBAL_BUILD += $(S2C_S2C_BUILD) +GLOBAL_CFLAGS += $(S2C_S2C_GLOBAL_CFLAGS) -I$(S2C_S2C_SRCDIR) +GLOBAL_LDFLAGS += $(S2C_S2C_GLOBAL_LDFLAGS) + + + +# +# GENERIC DEPENDENCIES +# +all: $(S2C_S2C_BUILD) +depend: gen.d +depend: gram.d +depend: s2c.d +depend: s2c_native.d +depend: scan.d + + + +# +# BUILD DEPENDENCIES +# + +gen.$(OBJSUFFIX): $(S2C_S2C_SRCDIR)gen.c gen.d + $(COMPILE.c) $@ $< $(S2C_S2C_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +gen.d: $(S2C_S2C_SRCDIR)gen.c + $(COMPILE.c) $@ $< -MM -MG $(S2C_S2C_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +gram.$(OBJSUFFIX): $(S2C_S2C_SRCDIR)gram.y gram.d + $(COMPILE.y) $@ $< $(S2C_S2C_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +gram.d: $(S2C_S2C_SRCDIR)gram.y + $(COMPILE.y) $@ $< -MM -MG $(S2C_S2C_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +s2c.$(OBJSUFFIX): $(S2C_S2C_SRCDIR)s2c.c s2c.d + $(COMPILE.c) $@ $< $(S2C_S2C_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +s2c.d: $(S2C_S2C_SRCDIR)s2c.c + $(COMPILE.c) $@ $< -MM -MG $(S2C_S2C_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +s2c_native.$(OBJSUFFIX): $(S2C_S2C_SRCDIR)s2c_native.cxx s2c_native.d + $(COMPILE.cxx) $@ $< $(S2C_S2C_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +s2c_native.d: $(S2C_S2C_SRCDIR)s2c_native.cxx + $(COMPILE.cxx) $@ $< -MM -MG $(S2C_S2C_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +scan.$(OBJSUFFIX): $(S2C_S2C_SRCDIR)scan.l scan.d + $(COMPILE.l) $@ $< $(S2C_S2C_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +scan.d: $(S2C_S2C_SRCDIR)scan.l + $(COMPILE.l) $@ $< -MM -MG $(S2C_S2C_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +s2c_native.hxx: $(S2C_S2C_SRCDIR)s2c_native.hxx + $(CP) $(CPFLAGS) $(S2C_S2C_SRCDIR)$@ $@ + +libs2c.$(ARSUFFIX): gen.$(OBJSUFFIX) + +libs2c.$(ARSUFFIX): gram.$(OBJSUFFIX) + +libs2c.$(ARSUFFIX): scan.$(OBJSUFFIX) + +libs2c.$(ARSUFFIX): + $(AR) $(ARFLAGS) $@ $? + $(RANLIB) $@ + +s2c: s2c.$(OBJSUFFIX) $(GLOBAL_LIBNAME) + $(LINK.c) $@ s2c.$(OBJSUFFIX) $(S2C_S2C_LOCAL_LDFLAGS) $(GLOBAL_LDFLAGS) diff --git a/src/libs/resiprocate/p2p/s2c/s2c/test/Forwarding.s2c b/src/libs/resiprocate/p2p/s2c/s2c/test/Forwarding.s2c new file mode 100644 index 00000000..3648fbb9 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/test/Forwarding.s2c @@ -0,0 +1,13 @@ +struct { + uint8 relo_token; + uint32 overlay; + uint8 ttl; + uint8 reserved; + uint16 fragment; + uint8 version; + uint24 length; + uint64 transaction_id; + uint16 flags; + uint16 via_list_length; + uint16 destination_list_length; +} ForwardingHdr; \ No newline at end of file diff --git a/src/libs/resiprocate/p2p/s2c/s2c/test/enum.s2c b/src/libs/resiprocate/p2p/s2c/s2c/test/enum.s2c new file mode 100644 index 00000000..ad290072 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/test/enum.s2c @@ -0,0 +1,7 @@ +enum { abel (0), baker(1), (255) } Dual; + +struct { + Dual frob; +} BooleanContainer; + + diff --git a/src/libs/resiprocate/p2p/s2c/s2c/test/select.s2c b/src/libs/resiprocate/p2p/s2c/s2c/test/select.s2c new file mode 100644 index 00000000..0aabd9ea --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/test/select.s2c @@ -0,0 +1,14 @@ +enum { zero (0), one(1), (255) } Binary; + +struct { + Binary switchtype; + + select (switchtype) { + case zero: + uint8 zero_arm; + case one: + uint16 one_arm1; + opaque one_arm2[10]; + opaque one_arm3<0..2^16-1>; + }; +} named; \ No newline at end of file diff --git a/src/libs/resiprocate/p2p/s2c/s2c/test/struct.s2c b/src/libs/resiprocate/p2p/s2c/s2c/test/struct.s2c new file mode 100644 index 00000000..a87588bb --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/test/struct.s2c @@ -0,0 +1,5 @@ +public struct { + uint8 simple_int; + opaque fixed[10]; + opaque variable<0..2^16-1>; +} struct_test; \ No newline at end of file diff --git a/src/libs/resiprocate/p2p/s2c/s2c/test/targets.mk b/src/libs/resiprocate/p2p/s2c/s2c/test/targets.mk new file mode 100644 index 00000000..ab785cb8 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/test/targets.mk @@ -0,0 +1,160 @@ +# +# targets.mk +# +# $Source$ +# $Revision$ +# $Date$ +# +# Copyright (C) 2008, Network Resonance, Inc. +# All Rights Reserved. +# + +# S2C_S2C_TEST_ARCHIVE: +# source files to compile to object and to place in a library archive +# +# S2C_S2C_TEST_ARCHIVE_NAME: +# the library name to use to archive the object files +# +# S2C_S2C_TEST_ARCHIVE_TYPE: +# either 'static', 'dynamic', or 'jni' (the default is 'static') +# +# S2C_S2C_TEST_AUTOGENERATED: +# whether this targets.mk is autogenerated (either 'true' or 'false') +# +# S2C_S2C_TEST_COMPILE: +# source files to compile to object +# +# S2C_S2C_TEST_COPY: +# files to copy to the build directory +# +# S2C_S2C_TEST_GLOBAL_CFLAGS: +# preprocessor and compile-time flags specific to compiling +# everything +# +# S2C_S2C_TEST_GLOBAL_LDFLAGS: +# link-time flags specific to linking everything +# +# S2C_S2C_TEST_LINK: +# source files compile and link +# +# S2C_S2C_TEST_LOCAL_CFLAGS: +# preprocessor and compile-time flags specific to compiling only +# the files in this module directory +# +# S2C_S2C_TEST_LOCAL_LDFLAGS: +# link-time flags specific to linking only the files in +# this module directory +# +# S2C_S2C_TEST_PREFIX: +# defines the module name, which also serves as the +# prefix for all the variable names defined in this file +# +# S2C_S2C_TEST_SUBDIRS: +# subdirectories containing additional targets.mk files +# +S2C_S2C_TEST_ARCHIVE = auto.s2c enum.s2c select.s2c struct.s2c +S2C_S2C_TEST_ARCHIVE_NAME = s2ctest +S2C_S2C_TEST_ARCHIVE_TYPE = +S2C_S2C_TEST_AUTOGENERATED = true +S2C_S2C_TEST_COMPILE = +S2C_S2C_TEST_COPY = +S2C_S2C_TEST_GLOBAL_CFLAGS = +S2C_S2C_TEST_GLOBAL_LDFLAGS = +S2C_S2C_TEST_LINK = test_s2c.cxx +S2C_S2C_TEST_LOCAL_CFLAGS = -I$(RESIPROCATE_SRCDIR) \ + -I$(RESIPROCATE_SRCDIR)/p2p/ +S2C_S2C_TEST_LOCAL_LDFLAGS = -L$(RESIPROCATE_SRCDIR)p2p/obj.$(RESIPROCATE_DEBUG)$(RESIPROCATE_PLATFORM) \ + -L$(RESIPROCATE_SRCDIR)rutil/obj.$(RESIPROCATE_DEBUG)$(RESIPROCATE_PLATFORM) \ + -L. -lp2p -lrutil -ls2ctest s2c_native.o +S2C_S2C_TEST_PREFIX = S2C_S2C_TEST +S2C_S2C_TEST_SUBDIRS = + + + +# +# AUTOMATICALLY-GENERATED SECTION +# + + + +# +# LOCAL ENVIRONMENT +# +S2C_S2C_TEST_BUILD = auto.$(OBJSUFFIX) auto.d enum.$(OBJSUFFIX) \ + enum.d libs2ctest.$(ARSUFFIX) \ + select.$(OBJSUFFIX) select.d \ + struct.$(OBJSUFFIX) struct.d test_s2c \ + test_s2c.$(OBJSUFFIX) test_s2c.d + + + +# +# GLOBAL ENVIRONMENT +# +GLOBAL_BUILD += $(S2C_S2C_TEST_BUILD) +GLOBAL_CFLAGS += $(S2C_S2C_TEST_GLOBAL_CFLAGS) \ + -I$(S2C_S2C_TEST_SRCDIR) +GLOBAL_LDFLAGS += $(S2C_S2C_TEST_GLOBAL_LDFLAGS) + + + +# +# GENERIC DEPENDENCIES +# +all: $(S2C_S2C_TEST_BUILD) +depend: auto.d +depend: enum.d +depend: select.d +depend: struct.d +depend: test_s2c.d + + + +# +# BUILD DEPENDENCIES +# + +auto.$(OBJSUFFIX): $(S2C_S2C_TEST_SRCDIR)auto.s2c auto.d + $(COMPILE.s2c) $@ $< $(S2C_S2C_TEST_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +auto.d: $(S2C_S2C_TEST_SRCDIR)auto.s2c + $(COMPILE.s2c) $@ $< -MM -MG $(S2C_S2C_TEST_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +enum.$(OBJSUFFIX): $(S2C_S2C_TEST_SRCDIR)enum.s2c enum.d + $(COMPILE.s2c) $@ $< $(S2C_S2C_TEST_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +enum.d: $(S2C_S2C_TEST_SRCDIR)enum.s2c + $(COMPILE.s2c) $@ $< -MM -MG $(S2C_S2C_TEST_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +select.$(OBJSUFFIX): $(S2C_S2C_TEST_SRCDIR)select.s2c select.d + $(COMPILE.s2c) $@ $< $(S2C_S2C_TEST_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +select.d: $(S2C_S2C_TEST_SRCDIR)select.s2c + $(COMPILE.s2c) $@ $< -MM -MG $(S2C_S2C_TEST_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +struct.$(OBJSUFFIX): $(S2C_S2C_TEST_SRCDIR)struct.s2c struct.d + $(COMPILE.s2c) $@ $< $(S2C_S2C_TEST_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +struct.d: $(S2C_S2C_TEST_SRCDIR)struct.s2c + $(COMPILE.s2c) $@ $< -MM -MG $(S2C_S2C_TEST_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +test_s2c.$(OBJSUFFIX): $(S2C_S2C_TEST_SRCDIR)test_s2c.cxx test_s2c.d + $(COMPILE.cxx) $@ $< $(S2C_S2C_TEST_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +test_s2c.d: $(S2C_S2C_TEST_SRCDIR)test_s2c.cxx + $(COMPILE.cxx) $@ $< -MM -MG $(S2C_S2C_TEST_LOCAL_CFLAGS) $(GLOBAL_CFLAGS) + +libs2ctest.$(ARSUFFIX): auto.$(OBJSUFFIX) + +libs2ctest.$(ARSUFFIX): enum.$(OBJSUFFIX) + +libs2ctest.$(ARSUFFIX): select.$(OBJSUFFIX) + +libs2ctest.$(ARSUFFIX): struct.$(OBJSUFFIX) + +libs2ctest.$(ARSUFFIX): + $(AR) $(ARFLAGS) $@ $? + $(RANLIB) $@ + +test_s2c: test_s2c.$(OBJSUFFIX) $(GLOBAL_LIBNAME) + $(LINK.cxx) $@ test_s2c.$(OBJSUFFIX) $(S2C_S2C_TEST_LOCAL_LDFLAGS) $(GLOBAL_LDFLAGS) diff --git a/src/libs/resiprocate/p2p/s2c/s2c/test/test.in b/src/libs/resiprocate/p2p/s2c/s2c/test/test.in new file mode 100644 index 00000000..aac86a1e --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/test/test.in @@ -0,0 +1,37 @@ +primitive uint8 unsigned char 8; +primitive uint16 short 16; +primitive uint32 unsigned int 32; +primitive opaque unsigned char 8; + +struct { + opaque Id<255>; +} peer_id; + + +enum { abc(5), bcd(10) } exx; + +select { + case abc: + uint8 jjj; + case bcd: + uint16 www; + uint32 mmm; +} select_example; + + +struct { + uint16 zzz; +} baz_type; + +public struct { + uint8 bar; + baz_type mumble; + peer_id id; + uint16 zulu; + uint8 www[5]; + uint16 wwx[6]; + + uint8 variable<16384>; +/* select_example sss;*/ +} foo; + diff --git a/src/libs/resiprocate/p2p/s2c/s2c/test/test.s2c b/src/libs/resiprocate/p2p/s2c/s2c/test/test.s2c new file mode 100644 index 00000000..9221ab0f --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/test/test.s2c @@ -0,0 +1,38 @@ +primitive uint8 unsigned char 8; +primitive uint16 unsigned short 16; +primitive uint32 unsigned int 32; +primitive opaque unsigned char 8; + +struct { + opaque Id[16]; +} peer_id; + + +enum { abc(5), bcd(10) } exx; + +select ( blahblah) +{ + case abc: + uint8 jjj; + case bcd: + uint16 www; + uint32 mmm; +} select_example; + + +struct { + uint16 zzz; +} baz_type; + +public struct { + uint8 bar; + uint8 variable<16384>; + baz_type mumble; + peer_id id; + uint16 zulu; + uint8 www[5]; + uint16 wwx[6]; + +/* select_example sss;*/ +} foo; + diff --git a/src/libs/resiprocate/p2p/s2c/s2c/test/test_s2c.cxx b/src/libs/resiprocate/p2p/s2c/s2c/test/test_s2c.cxx new file mode 100644 index 00000000..070cec09 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/test/test_s2c.cxx @@ -0,0 +1,96 @@ +/** + test_s2c.cxx + + Copyright (C) 2008, RTFM, Inc. + All Rights Reserved. + + ekr@rtfm.com Sun May 4 16:13:37 2008 +*/ + + + +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Subsystem.hxx" +#include "rutil/Data.hxx" +#include "rutil/DataStream.hxx" +#include "selectGen.hxx" +#include "autoGen.hxx" +#include "structGen.hxx" +#include <iostream> +#include <fstream> +#include <vector> + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST + + +int main(int argc, char **argv) + { + std::ofstream fout; + std::ifstream fin; + + resip::Log::initialize(resip::Data("cerr"), + resip::Data("DEBUG"),resip::Data("test_s2c")); + InfoLog(<<"XXXX"); + + + // ***** Test select ***** + // Cook up an ns and write it + s2c::NamedStruct ns1; + + // Set up both variants + ns1.mZero.mZeroArm=9; + ns1.mOne.mOneArm1=99; + memset(ns1.mOne.mOneArm2,0xff,10); + unsigned char blahblah=0x11; + + // Now choose one +// ns1.mSwitchtype=s2c::zero; + ns1.mSwitchtype=s2c::one; + + fout.open("test.out"); + ns1.encode(fout); + fout.close(); + + + // Now read it back in again + fin.open("test.out"); + s2c::NamedStruct ns2; + ns2.decode(fin); + + std::cout << "Type is" << std::hex << (int)ns2.mSwitchtype << "\n"; +// std::cout << std::hex << (int)ns2.mZero.mZeroArm << "\n"; + + + // Now a copy constructor + s2c::NamedStruct ns3(ns2); + + // ***** Test auto ****** + s2c::AutoExampleStruct a1; + a1.mType=s2c::abel; + a1.mAbel.mAbel1=55; + fout.open("test2.out"); + a1.encode(fout); + fout.close(); + + std::ifstream fin2; + fin2.open("test2.out"); + s2c::AutoExampleStruct a2; + a2.decode(fin2); + + + // ****** Test Struct ***** + s2c::StructTestStruct st; + st.mSimpleInt=7; + st.mVariable="Bogus"; + fout.open("test3.out"); + st.encode(fout); + fout.close(); + + s2c::StructTestStruct st2; + std::ifstream fin3; + fin3.open("test3.out"); + st2.decode(fin3); + } + + diff --git a/src/libs/resiprocate/p2p/s2c/s2c/test/typedef.s2c b/src/libs/resiprocate/p2p/s2c/s2c/test/typedef.s2c new file mode 100644 index 00000000..9332f8b4 --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/s2c/test/typedef.s2c @@ -0,0 +1,5 @@ +typedef opaque NodeId[16]; + +struct { + NodeId id; +} NodeIdTest; \ No newline at end of file diff --git a/src/libs/resiprocate/p2p/s2c/store.in b/src/libs/resiprocate/p2p/s2c/store.in new file mode 100644 index 00000000..ee24a0ce --- /dev/null +++ b/src/libs/resiprocate/p2p/s2c/store.in @@ -0,0 +1,62 @@ +primitive opaque u_char 8; +primitive uint8 u_int8 8; +primitive uint16 u_int16 16; +primitive uint32 u_int32 32; +primitive uint64 u_int64 64; +primitive int32 int32 32; + +struct { + opaque id<255>; +} resource_id; + +enum { single_value(1), array(2), dictionary(3) } kind_id ; + +select { + case single_value: + opaque value<65000>; + case array: + int32 index; + opaque value<65000>; + case dictionary: + opaque key<65000>; + opaque value<65000>; +} data_value; + +enum {signer_identity_peer (1), signer_identity_name (2), + signer_identity_certificate (3)} signer_identity_type; + +select { + case signer_identity_peer: + opaque peer_id[16]; + case signer_identity_name: + opaque signer_name<255>; + case signer_identity_certificate: + opaque certificate<65000>; +} signer_identity; + +public struct { + uint8 algorithm; + opaque signature_value<65000>; + signer_identity identity; +} signature; + +struct { + uint32 length; + uint64 storage_time; + uint32 lifetime; + data_value data; + signature sig; +} stored_data; + +public struct { + uint32 kind; + uint8 data_model; + uint64 generation; + stored_data values<65000>; +} store_kind_data; + +public struct { + resource_id resource; + store_kind_data store_data<4000000000>; +} store_q; + diff --git a/src/libs/resiprocate/p2p/test/Makefile b/src/libs/resiprocate/p2p/test/Makefile new file mode 100644 index 00000000..fbdc297f --- /dev/null +++ b/src/libs/resiprocate/p2p/test/Makefile @@ -0,0 +1,49 @@ +BUILD := ../../build +include $(BUILD)/Makefile.pre + +CXXFLAGS += -I../../ -g + +PACKAGES += RUTIL OPENSSL PTHREAD S2C P2P +LIBNAMES += readline popt + +TESTPROGRAMS = testCon.cxx + + + +include $(BUILD)/Makefile.post + + +#====================================================================== +# Copyright (c) 2008, Various contributors to the Resiprocate project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# - The names of the project's contributors may not be used to +# endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +#====================================================================== + diff --git a/src/libs/resiprocate/p2p/test/ReadMe.txt b/src/libs/resiprocate/p2p/test/ReadMe.txt new file mode 100644 index 00000000..e5e3bd75 --- /dev/null +++ b/src/libs/resiprocate/p2p/test/ReadMe.txt @@ -0,0 +1,10 @@ + +You can run the text program for the bootstrap node with + +testConsole -p 9000 -B + +and for the non bootstrap node start with + +testConsole -bs 127.0.0.1:9000 + + diff --git a/src/libs/resiprocate/p2p/test/testCon.cxx b/src/libs/resiprocate/p2p/test/testCon.cxx new file mode 100644 index 00000000..b3893f39 --- /dev/null +++ b/src/libs/resiprocate/p2p/test/testCon.cxx @@ -0,0 +1,413 @@ +#include <signal.h> +#ifdef WIN32 +#include <conio.h> +#else +#include <stdio.h> +#include <sys/select.h> +#include <termios.h> + +#include <histedit.h> +#include <readline/readline.h> + +#include <popt.h> + +#include <sys/ioctl.h> + +// I'm thinking this can all just be readline/libedit compliant. + +extern "C" char **completion_matches(const char*, char* func(const char*, int)); +extern "C" void rl_set_help(int func(int, int)); +extern "C" void rl_insertstr(char*); +extern "C" int add_history(const char*); + +#endif + + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/Random.hxx> +#include <rutil/ParseBuffer.hxx> +#include <rutil/BaseException.hxx> + +#include "p2p/P2PSubsystem.hxx" +#include "p2p/TransporterMessage.hxx" +#include "p2p/Profile.hxx" +#include "p2p/SelectTransporter.hxx" +#include "p2p/P2PStack.hxx" + +using namespace p2p; +using namespace resip; +using namespace std; + + +int +bind_help_key() +{ + // rl_bind_key('?', helpme); + return 0; +} + +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P + +void sleepSeconds(unsigned int seconds) +{ +#ifdef WIN32 + Sleep(seconds*1000); +#else + sleep(seconds); +#endif +} + +static bool finished = false; + +void processCommandLine(Data& commandline) +{ + Data command; +#define MAX_ARGS 5 + Data arg[MAX_ARGS]; + ParseBuffer pb(commandline); + pb.skipWhitespace(); + if(pb.eof()) return; + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace); + pb.data(command, start); + + // Get arguments (up to MAX_ARGS) + int currentArg = 0; + while(!pb.eof() && currentArg < MAX_ARGS) + { + pb.skipWhitespace(); + if(!pb.eof()) + { + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace); + pb.data(arg[currentArg++], start); + } + } + + // Process commands + if(isEqualNoCase(command, "quit") || isEqualNoCase(command, "q") || isEqualNoCase(command, "exit")) + { + finished=true; + return; + } + if(isEqualNoCase(command, "store") || isEqualNoCase(command, "st")) + { + // TODO - resource name and value + return; + } + if(isEqualNoCase(command, "fetch") || isEqualNoCase(command, "ft")) + { + // TODO - resource name + return; + } + + InfoLog( << "Possible commands are: " << endl + << " <store|st> <...>" << endl + << " <fetch|ft> <...>" << endl + << " <'exit'|'quit'|'q'>"); +} + +#define KBD_BUFFER_SIZE 256 +void processKeyboard(char input) +{ + static char buffer[KBD_BUFFER_SIZE]; + static int bufferpos = 0; + + if(input == 13 || input == 10) // enter + { + Data db(buffer,bufferpos); +#ifdef WIN32 + cout << endl; +#endif + processCommandLine(db); + bufferpos = 0; + } + else if(input == 8 || input == 127) // backspace + { + if(bufferpos > 0) + { +#ifdef WIN32 + cout << input << ' ' << input; +#else + // note: This is bit of a hack and may not be portable to all linux terminal types + cout << "\b\b\b \b\b\b"; + fflush(stdout); +#endif + bufferpos--; + } + } + else + { + if(bufferpos == KBD_BUFFER_SIZE) + { + cout << endl; + bufferpos = 0; + } + else + { +#ifdef WIN32 + cout << input; +#endif + buffer[bufferpos++] = (char)input; + } + } +} + +class TtyInterface +{ +public: + TtyInterface(const char * name); + virtual ~TtyInterface() {}; + void go(); + static int helpme(int,int){/*unimplemented*/return 0;}; + static void sigCatch(int) { cerr << "Exiting..."; if (mFinished) exit(-1); mFinished=true;} +// static void sigCatchAlrm(int) { } + +private: + static bool mFinished; +}; + +bool TtyInterface::mFinished = false; + +TtyInterface::TtyInterface(const char * ) +{ +// rl_readline_name = name; +} + +void +TtyInterface::go() +{ + // setup signals + // +#define TS(sig,disposition) { #sig, sig, disposition} + struct + { + char *name; + int signum; + sig_t f; + } sigs[] = { + TS(SIGTSTP,sigCatch), + TS(SIGINT,sigCatch), +#if !defined(WIN32) + TS(SIGPIPE,SIG_IGN), +#endif + TS(SIGQUIT,sigCatch), + TS(SIGTERM,sigCatch) +}; +#undef TS + + for (unsigned int i = 0 ; i < sizeof(sigs)/sizeof(*sigs); i++) + { + if( signal( sigs[i].signum, sigs[i].f ) == SIG_ERR ) + { + cerr << sigs[i].name << ": error setting singal disposition, errno=" << errno << endl; + // This isn't fatal .. let it ride. + } + } +} + +struct options_s +{ + unsigned short listenPort; + Data remoteHost; + unsigned int remotePort; + char * connect; + int bootstrapMode; + char * logLevel; +} options; + + +int +main (int argc, const char** argv) +{ + TtyInterface tty(*argv); + + // Defaults + Data address = DnsUtil::getLocalIpAddress(); + + + + // Command line args + // --help + // short long type varname + // -p --port unsigned short listenPort + // -b -- + // Loop through command line arguments and process them + +// struct poptOption { +// const char * longName; /* may be NULL */ +// char shortName; /* may be '\0' */ +// int argInfo; +// void * arg; /* depends on argInfo */ +// int val; /* 0 means don't return, just update flag */ +// char * descrip; /* description for autohelp -- may be NULL */ +// char * argDescrip; /* argument description for autohelp */ +// }; + + struct poptOption opt[] = { + {"bootstrap" , 'B', POPT_ARG_NONE, &options.bootstrapMode, 'B', "enable bootstrap mode", 0 }, + {"port", 'p', POPT_ARG_INT, &options.listenPort, 'p', "listen port", 0}, + {"log-level",'l',POPT_ARG_STRING, &options.logLevel, 'l', "Log Level <NONE|CRIT|ERR|WARNING|INFO|DEBUG|STACK>" ,"LOG_LEVEL"}, + {"connect", 'C', POPT_ARG_STRING, &options.connect, 'C', "Host to connect with.", "hostname[:port]"} , + POPT_AUTOHELP + {0,0,0,0,0,0} + }; + + options.bootstrapMode = 0; + + poptContext optCon ( poptGetContext(0, argc, argv, opt, 0) ) ; + + poptSetOtherOptionHelp(optCon,"[OPTIONS]* <port>"); + + if (argc < 1) { + poptPrintUsage(optCon,stderr,0); + exit(1); + } + //-- + int c; + while ((c = poptGetNextOpt(optCon)) >= 0) + { + switch(c) + { + case 'C': + // look for the ':' from the END. + const char * colon = strrchr(options.connect,':'); + if (colon) + { + unsigned long port = strtoul(++colon,0,0); + options.remotePort = port & 0xffff; + options.remoteHost = Data(options.connect,colon-options.connect-1); + } + else + { + options.remoteHost=Data(options.connect); + } + break; + } + } + if (c < -1) { + /* an error occurred during option processing */ + fprintf(stderr, "%s: '%s' %s\n", *argv, + poptBadOption(optCon, POPT_BADOPTION_NOALIAS), + poptStrerror(c)); + return 1; + } + +// ---xxx--- + cerr << "listenPort " << options.listenPort << endl; + cerr << "bootstrapMode " << options.bootstrapMode << endl; + cerr << "remoteHost " << options.remoteHost << endl; + cerr << "remotePort " << options.remotePort << endl; + cerr << "logLevel " << options.logLevel << endl; + + + Log::initialize("Cout", Data(options.logLevel), "testConsole"); + + initNetwork(); + + InfoLog( << "testConsole settings:"); + InfoLog( << " Listen Port = " << options.listenPort); + InfoLog( << " connect = " << options.remoteHost << ":" << options.remotePort ); + InfoLog( << " Log Level = " << options.logLevel); + InfoLog( << " bootstrap = " << options.bootstrapMode); + InfoLog( << "type help or '?' for list of accepted commands." << endl); + + ////////////////////////////////////////////////////////////////////////////// + // Setup Config Object + ////////////////////////////////////////////////////////////////////////////// + Profile profile; + profile.overlayName() = "p2poverlay.com"; + + ResourceId rid(Random::getRandom(16)); + profile.nodeId() = NodeId(rid); + cerr << "Using NodeId: " << profile.nodeId() << endl; + + profile.userName().value() = "test"; + + if(options.remotePort != 0) + { + struct in_addr addr; + if(resip::DnsUtil::inet_pton(options.remoteHost, addr)==0) + { + cerr << "Invalid remote host address:" << options.remoteHost << endl; + exit(-1); + } + sockaddr_in addr_in; + addr_in.sin_family = AF_INET; + addr_in.sin_addr = addr; + addr_in.sin_port = htons(options.remotePort); + profile.bootstrapNodes().push_back(resip::GenericIPAddress(addr_in)); + } + + profile.numInitialFingers() = 0; // FIXME - debugging only + + ////////////////////////////////////////////////////////////////////////////// + // Setup P2PStack + ////////////////////////////////////////////////////////////////////////////// + P2PStack p2pStack(profile); + + p2pStack.listenOn(options.listenPort); + if(options.remotePort != 0) + { + p2pStack.join(); + } + + int input; + while(true) + { + p2pStack.process(10); + + while(3) /*do readline stuff */ + { +#ifdef WIN32 + input = _getch(); + processKeyboard(input); +#else + input = fgetc(stdin); + fflush(stdin); + //cout << "input: " << input << endl; + processKeyboard(input); +#endif + } + } + + InfoLog(<< "testConsole is shutdown."); + sleepSeconds(2); +} + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/test/testConsole.cxx b/src/libs/resiprocate/p2p/test/testConsole.cxx new file mode 100644 index 00000000..d93cfe16 --- /dev/null +++ b/src/libs/resiprocate/p2p/test/testConsole.cxx @@ -0,0 +1,386 @@ +#include <signal.h> +#ifdef WIN32 +#include <conio.h> +#else +/** + Linux (POSIX) implementation of _kbhit(). + Morgan McGuire, morgan@cs.brown.edu + */ +#include <stdio.h> +#include <sys/select.h> +#include <termios.h> +//#include <stropts.h> +#include <sys/ioctl.h> + +int _kbhit() { + static const int STDIN = 0; + static bool initialized = false; + + if (! initialized) { + // Use termios to turn off line buffering + termios term; + tcgetattr(STDIN, &term); + term.c_lflag &= ~ICANON; + tcsetattr(STDIN, TCSANOW, &term); + setbuf(stdin, NULL); + initialized = true; + } + + int bytesWaiting; + ioctl(STDIN, FIONREAD, &bytesWaiting); + return bytesWaiting; +} +#endif + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/Random.hxx> +#include <rutil/ParseBuffer.hxx> +#include <rutil/BaseException.hxx> + +#include "p2p/P2PSubsystem.hxx" +#include "p2p/TransporterMessage.hxx" +#include "p2p/Profile.hxx" +#include "p2p/SelectTransporter.hxx" +#include "p2p/P2PStack.hxx" + +using namespace p2p; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM P2PSubsystem::P2P + +void sleepSeconds(unsigned int seconds) +{ +#ifdef WIN32 + Sleep(seconds*1000); +#else + sleep(seconds); +#endif +} + +static bool finished = false; + +static void +signalHandler(int signo) +{ + std::cerr << "Shutting down" << endl; + + if ( finished ) + { + exit(1); + } + + finished = true; +} + +void processCommandLine(Data& commandline) +{ + Data command; +#define MAX_ARGS 5 + Data arg[MAX_ARGS]; + ParseBuffer pb(commandline); + pb.skipWhitespace(); + if(pb.eof()) return; + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace); + pb.data(command, start); + + // Get arguments (up to MAX_ARGS) + int currentArg = 0; + while(!pb.eof() && currentArg < MAX_ARGS) + { + pb.skipWhitespace(); + if(!pb.eof()) + { + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace); + pb.data(arg[currentArg++], start); + } + } + + // Process commands + if(isEqualNoCase(command, "quit") || isEqualNoCase(command, "q") || isEqualNoCase(command, "exit")) + { + finished=true; + return; + } + if(isEqualNoCase(command, "store") || isEqualNoCase(command, "st")) + { + // TODO - resource name and value + return; + } + if(isEqualNoCase(command, "fetch") || isEqualNoCase(command, "ft")) + { + // TODO - resource name + return; + } + + InfoLog( << "Possible commands are: " << endl + << " <store|st> <...>" << endl + << " <fetch|ft> <...>" << endl + << " <'exit'|'quit'|'q'>"); +} + +#define KBD_BUFFER_SIZE 256 +void processKeyboard(char input) +{ + static char buffer[KBD_BUFFER_SIZE]; + static int bufferpos = 0; + + if(input == 13 || input == 10) // enter + { + Data db(buffer,bufferpos); +#ifdef WIN32 + cout << endl; +#endif + processCommandLine(db); + bufferpos = 0; + } + else if(input == 8 || input == 127) // backspace + { + if(bufferpos > 0) + { +#ifdef WIN32 + cout << input << ' ' << input; +#else + // note: This is bit of a hack and may not be portable to all linux terminal types + cout << "\b\b\b \b\b\b"; + fflush(stdout); +#endif + bufferpos--; + } + } + else + { + if(bufferpos == KBD_BUFFER_SIZE) + { + cout << endl; + bufferpos = 0; + } + else + { +#ifdef WIN32 + cout << input; +#endif + buffer[bufferpos++] = (char)input; + } + } +} + +int +main (int argc, char** argv) +{ + +#ifndef _WIN32 + if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR) + { + cerr << "Couldn't install signal handler for SIGPIPE" << endl; + exit(-1); + } +#endif + + if ( signal( SIGINT, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGINT" << endl; + exit( -1 ); + } + + if ( signal( SIGTERM, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGTERM" << endl; + exit( -1 ); + } + + // Defaults + Data address = DnsUtil::getLocalIpAddress(); + Data bootstrapAddress; + unsigned short bootstrapPort=0; + unsigned short listenPort=9000; + + //Data logLevel("INFO"); + Data logLevel("DEBUG"); + + ////////////////////////////////////////////////////////////////////////////// + // Setup Config Object + ////////////////////////////////////////////////////////////////////////////// + Profile profile; + profile.overlayName() = "p2poverlay.com"; + profile.isBootstrap() = false; + + // Loop through command line arguments and process them + for(int i = 1; i < argc; i++) + { + Data commandName(argv[i]); + + // Process all commandNames that don't take values + if(isEqualNoCase(commandName, "-?") || + isEqualNoCase(commandName, "--?") || + isEqualNoCase(commandName, "--help") || + isEqualNoCase(commandName, "/?")) + { + cout << "Command line options are:" << endl; + cout << " -p <listenPort>" << endl; + cout << " -bs <booststrap node hostname/address>:<port>" << endl; + cout << " -l <NONE|CRIT|ERR|WARNING|INFO|DEBUG|STACK> - logging level" << endl; + cout << endl; + cout << "Sample Command line:" << endl; + cout << "testConsole -bs 192.168.1.100:9000" << endl; + return 0; + } + else if (isEqualNoCase(commandName,"--bootstrap") || isEqualNoCase(commandName,"-B")) + { + profile.isBootstrap() = true; + } + else + { + // Process commands that have values + Data commandValue(i+1 < argc ? argv[i+1] : Data::Empty); + if(commandValue.empty() || commandValue.at(0) == '-') + { + cerr << "Invalid command line parameters!" << endl; + exit(-1); + } + i++; // increment argument + + if(isEqualNoCase(commandName, "-p")) + { + listenPort = commandValue.convertInt(); + } + else if(isEqualNoCase(commandName, "-bs")) + { + // Read server and port + Data serverAndPort = commandValue; + ParseBuffer pb(serverAndPort); + pb.skipWhitespace(); + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace, ":"); // white space or ":" + Data hostname; + pb.data(hostname, start); + bootstrapAddress = hostname; + if(!pb.eof()) + { + pb.skipChar(':'); + start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace); // white space + Data port; + pb.data(port, start); + bootstrapPort = (unsigned short)port.convertUnsignedLong(); + } + } + else if(isEqualNoCase(commandName, "-l")) + { + logLevel = commandValue; + } + else + { + cerr << "Invalid command line parameters!" << endl; + exit(-1); + } + } + } + + Log::initialize("Cout", logLevel, "testConsole"); + + initNetwork(); + + InfoLog( << "testConsole settings:"); + InfoLog( << " Listen Port = " << listenPort); + InfoLog( << " Bootstrap server = " << bootstrapAddress << ":" << bootstrapPort); + InfoLog( << " Log Level = " << logLevel); + + InfoLog( << "type help or '?' for list of accepted commands." << endl); + + + ResourceId rid(Random::getRandom(16)); + profile.nodeId() = NodeId(rid); + cerr << "Using NodeId: " << profile.nodeId() << endl; + + profile.userName().value() = "test"; + + if(bootstrapPort != 0) + { + struct in_addr addr; + if(resip::DnsUtil::inet_pton(bootstrapAddress, addr)==0) + { + cerr << "Invalid bootstrap address:" << bootstrapAddress << endl; + exit(-1); + } + sockaddr_in addr_in; + addr_in.sin_family = AF_INET; + addr_in.sin_addr = addr; + addr_in.sin_port = htons(bootstrapPort); + profile.bootstrapNodes().push_back(resip::GenericIPAddress(addr_in)); + } + profile.numInitialFingers() = 0; // FIXME - debugging only + + ////////////////////////////////////////////////////////////////////////////// + // Setup P2PStack + ////////////////////////////////////////////////////////////////////////////// + P2PStack p2pStack(profile); + + p2pStack.listenOn(listenPort); + if(bootstrapPort != 0) + { + p2pStack.join(); + } + + int input; + while(true) + { + p2pStack.process(10); + + while(_kbhit() != 0) + { +#ifdef WIN32 + input = _getch(); + processKeyboard(input); +#else + input = fgetc(stdin); + fflush(stdin); + //cout << "input: " << input << endl; + processKeyboard(input); +#endif + } + if(finished) break; + } + + InfoLog(<< "testConsole is shutdown."); + sleepSeconds(2); +} + + +/* ====================================================================== + * Copyright (c) 2008, Various contributors to the Resiprocate project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * - The names of the project's contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + *====================================================================== */ diff --git a/src/libs/resiprocate/p2p/test/testConsole_8_0.vcproj b/src/libs/resiprocate/p2p/test/testConsole_8_0.vcproj new file mode 100644 index 00000000..3c4cbaa7 --- /dev/null +++ b/src/libs/resiprocate/p2p/test/testConsole_8_0.vcproj @@ -0,0 +1,201 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="testConsole" + ProjectGUID="{E70B1CEE-B744-4306-A4F5-4F8A353EC01C}" + RootNamespace="testConsole" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\;&quot;$(ProjectDir)/../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_SSL" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot;" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\..\;&quot;$(ProjectDir)/../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_SSL" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot;" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\testConsole.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/p2p/tmp/ForwardingGen.cxx b/src/libs/resiprocate/p2p/tmp/ForwardingGen.cxx new file mode 100644 index 00000000..6736a71a --- /dev/null +++ b/src/libs/resiprocate/p2p/tmp/ForwardingGen.cxx @@ -0,0 +1,108 @@ +#include <iostream> +#include <iomanip> +#include "rutil/Logger.hxx" +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST +#include "ForwardingGen.hxx" + +namespace s2c { + + + + +// Classes for ForwardingHdrStruct */ + +void ForwardingHdrStruct :: print(std::ostream& out, int indent) const +{ + do_indent(out,indent); + (out) << "ForwardingHdr:\n"; + indent+=2; + do_indent(out, indent); + (out) << "relo_token:" << std::hex << (unsigned long long)mReloToken << "\n"; + do_indent(out, indent); + (out) << "overlay:" << std::hex << (unsigned long long)mOverlay << "\n"; + do_indent(out, indent); + (out) << "ttl:" << std::hex << (unsigned long long)mTtl << "\n"; + do_indent(out, indent); + (out) << "reserved:" << std::hex << (unsigned long long)mReserved << "\n"; + do_indent(out, indent); + (out) << "fragment:" << std::hex << (unsigned long long)mFragment << "\n"; + do_indent(out, indent); + (out) << "version:" << std::hex << (unsigned long long)mVersion << "\n"; + do_indent(out, indent); + (out) << "length:" << std::hex << (unsigned long long)mLength << "\n"; + do_indent(out, indent); + (out) << "transaction_id:" << std::hex << (unsigned long long)mTransactionId << "\n"; + do_indent(out, indent); + (out) << "flags:" << std::hex << (unsigned long long)mFlags << "\n"; + do_indent(out, indent); + (out) << "via_list_length:" << std::hex << (unsigned long long)mViaListLength << "\n"; + do_indent(out, indent); + (out) << "destination_list_length:" << std::hex << (unsigned long long)mDestinationListLength << "\n"; +}; + +void ForwardingHdrStruct :: decode(std::istream& in) +{ + DebugLog(<< "Decoding ForwardingHdrStruct"); + decode_uintX(in, 8, mReloToken); + DebugLog( << "mReloToken"); + + decode_uintX(in, 32, mOverlay); + DebugLog( << "mOverlay"); + + decode_uintX(in, 8, mTtl); + DebugLog( << "mTtl"); + + decode_uintX(in, 8, mReserved); + DebugLog( << "mReserved"); + + decode_uintX(in, 16, mFragment); + DebugLog( << "mFragment"); + + decode_uintX(in, 8, mVersion); + DebugLog( << "mVersion"); + + decode_uintX(in, 24, mLength); + DebugLog( << "mLength"); + + decode_uintX(in, 64, mTransactionId); + DebugLog( << "mTransactionId"); + + decode_uintX(in, 16, mFlags); + DebugLog( << "mFlags"); + + decode_uintX(in, 16, mViaListLength); + DebugLog( << "mViaListLength"); + + decode_uintX(in, 16, mDestinationListLength); + DebugLog( << "mDestinationListLength"); + +}; + +void ForwardingHdrStruct :: encode(std::ostream& out) +{ + DebugLog(<< "Encoding ForwardingHdrStruct"); + encode_uintX(out, 8, mReloToken); + + encode_uintX(out, 32, mOverlay); + + encode_uintX(out, 8, mTtl); + + encode_uintX(out, 8, mReserved); + + encode_uintX(out, 16, mFragment); + + encode_uintX(out, 8, mVersion); + + encode_uintX(out, 24, mLength); + + encode_uintX(out, 64, mTransactionId); + + encode_uintX(out, 16, mFlags); + + encode_uintX(out, 16, mViaListLength); + + encode_uintX(out, 16, mDestinationListLength); + +}; + +} diff --git a/src/libs/resiprocate/p2p/tmp/ForwardingGen.hxx b/src/libs/resiprocate/p2p/tmp/ForwardingGen.hxx new file mode 100644 index 00000000..f49a2bda --- /dev/null +++ b/src/libs/resiprocate/p2p/tmp/ForwardingGen.hxx @@ -0,0 +1,25 @@ +#include "s2c/s2c_native.hxx" + +namespace s2c { + +class ForwardingHdrStruct : public PDU { +public: + UInt8 mReloToken; + UInt32 mOverlay; + UInt8 mTtl; + UInt8 mReserved; + UInt16 mFragment; + UInt8 mVersion; + UInt32 mLength; + UInt64 mTransactionId; + UInt16 mFlags; + UInt16 mViaListLength; + UInt16 mDestinationListLength; + + + ForwardingHdrStruct() {mName = "ForwardingHdr";} + PDUMemberFunctions +}; + + +} diff --git a/src/libs/resiprocate/p2p/tmp/fwding.cxx b/src/libs/resiprocate/p2p/tmp/fwding.cxx new file mode 100644 index 00000000..8383d0e2 --- /dev/null +++ b/src/libs/resiprocate/p2p/tmp/fwding.cxx @@ -0,0 +1,109 @@ +#include <iostream> +#include <iomanip> +#include "rutil/Logger.hxx" +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST +#include "fwding.hxx" + +namespace s2c { +namespace fwding { + + + +// Classes for ForwardingHdrStruct */ + +void ForwardingHdrStruct :: print(std::ostream *out, int indent) +{ + do_indent(out,indent); + (*out) << "ForwardingHdr:\n"; + indent+=2; + do_indent(out, indent); + (*out) << "relo_token:" << std::hex << (unsigned long long)mReloToken << "\n"; + do_indent(out, indent); + (*out) << "overlay:" << std::hex << (unsigned long long)mOverlay << "\n"; + do_indent(out, indent); + (*out) << "ttl:" << std::hex << (unsigned long long)mTtl << "\n"; + do_indent(out, indent); + (*out) << "reserved:" << std::hex << (unsigned long long)mReserved << "\n"; + do_indent(out, indent); + (*out) << "fragment:" << std::hex << (unsigned long long)mFragment << "\n"; + do_indent(out, indent); + (*out) << "version:" << std::hex << (unsigned long long)mVersion << "\n"; + do_indent(out, indent); + (*out) << "length:" << std::hex << (unsigned long long)mLength << "\n"; + do_indent(out, indent); + (*out) << "transaction_id:" << std::hex << (unsigned long long)mTransactionId << "\n"; + do_indent(out, indent); + (*out) << "flags:" << std::hex << (unsigned long long)mFlags << "\n"; + do_indent(out, indent); + (*out) << "via_list_length:" << std::hex << (unsigned long long)mViaListLength << "\n"; + do_indent(out, indent); + (*out) << "destination_list_length:" << std::hex << (unsigned long long)mDestinationListLength << "\n"; +}; + +void ForwardingHdrStruct :: decode(std::istream *in) +{ + DebugLog(<< "Decoding ForwardingHdrStruct"); + decode_uintX(in, 8, mReloToken); + DebugLog( << "mReloToken"); + + decode_uintX(in, 32, mOverlay); + DebugLog( << "mOverlay"); + + decode_uintX(in, 8, mTtl); + DebugLog( << "mTtl"); + + decode_uintX(in, 8, mReserved); + DebugLog( << "mReserved"); + + decode_uintX(in, 16, mFragment); + DebugLog( << "mFragment"); + + decode_uintX(in, 8, mVersion); + DebugLog( << "mVersion"); + + decode_uintX(in, 24, mLength); + DebugLog( << "mLength"); + + decode_uintX(in, 64, mTransactionId); + DebugLog( << "mTransactionId"); + + decode_uintX(in, 16, mFlags); + DebugLog( << "mFlags"); + + decode_uintX(in, 16, mViaListLength); + DebugLog( << "mViaListLength"); + + decode_uintX(in, 16, mDestinationListLength); + DebugLog( << "mDestinationListLength"); + +}; + +void ForwardingHdrStruct :: encode(std::ostream *out) +{ + DebugLog(<< "Encoding ForwardingHdrStruct"); + encode_uintX(out, 8, mReloToken); + + encode_uintX(out, 32, mOverlay); + + encode_uintX(out, 8, mTtl); + + encode_uintX(out, 8, mReserved); + + encode_uintX(out, 16, mFragment); + + encode_uintX(out, 8, mVersion); + + encode_uintX(out, 24, mLength); + + encode_uintX(out, 64, mTransactionId); + + encode_uintX(out, 16, mFlags); + + encode_uintX(out, 16, mViaListLength); + + encode_uintX(out, 16, mDestinationListLength); + +}; + +} +} diff --git a/src/libs/resiprocate/p2p/tmp/fwding.hxx b/src/libs/resiprocate/p2p/tmp/fwding.hxx new file mode 100644 index 00000000..f413a62c --- /dev/null +++ b/src/libs/resiprocate/p2p/tmp/fwding.hxx @@ -0,0 +1,27 @@ +#include "s2c_native.hxx" + +namespace s2c { +namespace fwding { + +class ForwardingHdrStruct : public PDU { +public: + UInt8 mReloToken; + UInt32 mOverlay; + UInt8 mTtl; + UInt8 mReserved; + UInt16 mFragment; + UInt8 mVersion; + UInt32 mLength; + UInt64 mTransactionId; + UInt16 mFlags; + UInt16 mViaListLength; + UInt16 mDestinationListLength; + + + ForwardingHdrStruct() {mName = "ForwardingHdr";} + PDUMemberFunctions +}; + + +} +} diff --git a/src/libs/resiprocate/presSvr/.cvsignore b/src/libs/resiprocate/presSvr/.cvsignore new file mode 100644 index 00000000..c96c16b5 --- /dev/null +++ b/src/libs/resiprocate/presSvr/.cvsignore @@ -0,0 +1,2 @@ +bin.debug.Darwin.Power_Macintosh +obj.debug.Darwin.Power_Macintosh diff --git a/src/libs/resiprocate/presSvr/DialogSetMgr.cpp b/src/libs/resiprocate/presSvr/DialogSetMgr.cpp new file mode 100644 index 00000000..f09de4b6 --- /dev/null +++ b/src/libs/resiprocate/presSvr/DialogSetMgr.cpp @@ -0,0 +1,108 @@ +#include "DialogSetMgr.h" + +#include "rutil/MD5Stream.hxx" + +DialogSetMgr::~DialogSetMgr() { + DialogSetMap_iter iter = mDialogSetMap.begin(); + while (iter!=mDialogSetMap.end()) + { + delete iter->second.second; + mDialogSetMap.erase(iter); // !dlb! does this increment iter? + } +} + +DialogState* +DialogSetMgr::matchDialogState(SipMessage* msg) +{ + assert(0); // Clean this function out + Data key = getDialogSetKey(msg); + DialogSetMap_iter iter = mDialogSetMap.find(key); + if (iter!=mDialogSetMap.end()) + { + return iter->second.second; + } + else + { + return NULL; + } +} + +DialogState* +DialogSetMgr::attachDialogState(SipMessage* msg) +{ + Data key = getDialogSetKey(msg); + DialogState* dialogState; + DialogSetMap_iter iter = mDialogSetMap.find(key); + if (iter==mDialogSetMap.end()) + { + dialogState = new DialogState(key,msg); + pair<int, DialogState*> mapSecond = make_pair(1,dialogState); + mDialogSetMap.insert(make_pair(key,mapSecond)); + cout << "Creating DialogSet " << key << endl; + } + else + { + dialogState = iter->second.second; + iter->second.first++; + cout << "Reference for DialogSet " << key << " is now " << iter->second.first << endl; + } + return dialogState; +} + +void +DialogSetMgr::detachDialogState(SubDialog* subDialog) +{ + DialogSetMap_iter iter = mDialogSetMap.find(subDialog->dialogState()->key()); + if (iter!=mDialogSetMap.end()) + { + iter->second.first -=1; + cout << "Reference for DialogSet " << subDialog->dialogState()->key() << " is now " << iter->second.first << endl; + if (iter->second.first == 0) + { + cout << "Destroying DialogSet " << subDialog->dialogState()->key() << endl; + delete iter->second.second; + mDialogSetMap.erase(iter); + } + } +} + +// The following Key function builds handles to +// identify a Dialog Set (messages that share +// a common callID, remote and local tag) + +Data +DialogSetMgr::getDialogSetKey(SipMessage * msg) +{ + bool putToOnLeft; + + if (msg->isExternal()) + putToOnLeft = true; + else + putToOnLeft = false; + + if (msg->isResponse()) + putToOnLeft = !putToOnLeft; + + Data leftTag(""); + Data rightTag(""); + if (putToOnLeft) + { + if (msg->header(h_To).exists(p_tag)) + leftTag = msg->header(h_To).param(p_tag); + if (msg->header(h_From).exists(p_tag)) + rightTag = msg->header(h_From).param(p_tag); + } + else + { + if (msg->header(h_From).exists(p_tag)) + leftTag = msg->header(h_From).param(p_tag); + if (msg->header(h_To).exists(p_tag)) + rightTag = msg->header(h_To).param(p_tag); + } + + MD5Stream strm; + strm << msg->header(h_CallId).value(); + strm << ":" << leftTag << rightTag; // !dlb! another punctuation between left and right? + return strm.getHex(); +} + diff --git a/src/libs/resiprocate/presSvr/DialogSetMgr.h b/src/libs/resiprocate/presSvr/DialogSetMgr.h new file mode 100644 index 00000000..610e92b9 --- /dev/null +++ b/src/libs/resiprocate/presSvr/DialogSetMgr.h @@ -0,0 +1,31 @@ +#ifndef DIALOGSETMGR +#define DIALOGSETMGR + +#include "DialogState.h" +#include "SubDialog.h" + +class SubDialogMgr; + +#include <map> + +using namespace std; + +//Map dialog set ID to a DialogState object +typedef map<Data,pair<int,DialogState *> > DialogSetMap_t; +typedef DialogSetMap_t::iterator DialogSetMap_iter; + +class DialogSetMgr +{ + public: + DialogSetMgr(SubDialogMgr& dialogMgr) + :mDialogMgr(dialogMgr){} + ~DialogSetMgr(); + DialogState* matchDialogState(SipMessage* msg); + DialogState* attachDialogState(SipMessage* msg); + void detachDialogState(SubDialog* subDialog); + Data getDialogSetKey(SipMessage* msg); + private: + DialogSetMap_t mDialogSetMap; + SubDialogMgr& mDialogMgr; +}; +#endif diff --git a/src/libs/resiprocate/presSvr/DialogState.cpp b/src/libs/resiprocate/presSvr/DialogState.cpp new file mode 100644 index 00000000..38896257 --- /dev/null +++ b/src/libs/resiprocate/presSvr/DialogState.cpp @@ -0,0 +1,25 @@ +#include "DialogState.h" + +DialogState::DialogState(Data key,SipMessage* msg) + :mKey(key) +{ + //Assume for now that msg is a request we recieved + //Remember that this is a bad assumption and more + //work needs to happen here + + //invariants + mLocalTFHeader = msg->header(h_To); + mRemoteTFHeader = msg->header(h_From); + mCallId = msg->header(h_CallId).value(); + if (msg->exists(h_RecordRoutes)) + { + mRouteSet = msg->header(h_RecordRoutes); + } + mMe = NameAddr(msg->header(h_RequestLine).uri()); + + //variants + mLocalCSeq = 0; + mRemoteCSeq = msg->header(h_CSeq).sequence(); + mRemoteTarget = msg->header(h_Contacts).front(); + +} diff --git a/src/libs/resiprocate/presSvr/DialogState.h b/src/libs/resiprocate/presSvr/DialogState.h new file mode 100644 index 00000000..796bbeea --- /dev/null +++ b/src/libs/resiprocate/presSvr/DialogState.h @@ -0,0 +1,37 @@ +#ifndef DIALOGSTATE +#define DIALOGSTATE + + +#include "rutil/Data.hxx" +#include "resip/stack/SipMessage.hxx" + +using namespace resip; + +class DialogState { + public: + DialogState(Data key,SipMessage* msg); + const Data& key() { return mKey; } + const H_To::Type& localTFHeader() {return mLocalTFHeader;} + const H_To::Type& remoteTFHeader() {return mRemoteTFHeader;} + unsigned long & localCSeq() {return mLocalCSeq;} + unsigned long & remoteCSeq() {return mRemoteCSeq;} + const Data & callId() {return mCallId;} + NameAddr & remoteTarget() {return mRemoteTarget;} + const NameAddrs & routeSet() {return mRouteSet;} + const NameAddr & me() {return mMe;} + private: + + //invariants + Data mKey; + H_To::Type mLocalTFHeader; + H_To::Type mRemoteTFHeader; + Data mCallId; + NameAddrs mRouteSet; + NameAddr mMe; + + //variants + unsigned long mLocalCSeq; + unsigned long mRemoteCSeq; + NameAddr mRemoteTarget; +}; +#endif diff --git a/src/libs/resiprocate/presSvr/Makefile b/src/libs/resiprocate/presSvr/Makefile new file mode 100644 index 00000000..3c6b04ca --- /dev/null +++ b/src/libs/resiprocate/presSvr/Makefile @@ -0,0 +1,70 @@ +# This should be the path to the build directory of resip (in the sip subdirectory) +BUILD = ../build + +# Includes macros +include $(BUILD)/Makefile.pre + +# All of these packages are prerequisites for resiprocate +PACKAGES += RESIP RUTIL OPENSSL ARES PTHREAD + +# Add an entry to TESTPROGRAMS for each target that has a main in it +# On linux this will generate an executable in bin.debug.Linux.i686/main +TESTPROGRAMS += presSvr.cpp + +# Add each of the C++ or C files that other than the main +# Each main target (from TESTPROGRAMS) will be linked with all of the files in SRC +SRC = PresConfig.cpp TuPresSvr.cpp ResourceMgr.cpp SubDialogMgr.cpp SubDialog.cpp Resource.cpp DialogSetMgr.cpp DialogState.cpp + +# Includes macros +include $(BUILD)/Makefile.post + + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# <http://www.vovida.org/>. +# +############################################################################## diff --git a/src/libs/resiprocate/presSvr/PresConfig.cpp b/src/libs/resiprocate/presSvr/PresConfig.cpp new file mode 100644 index 00000000..053ac358 --- /dev/null +++ b/src/libs/resiprocate/presSvr/PresConfig.cpp @@ -0,0 +1,35 @@ +#include "resip/stack/SipStack.hxx" +#include "PresConfig.h" +#include "ResourceMgr.h" + +using namespace resip; +PresConfig* PresConfig::theInstance = 0; + +PresConfig & +PresConfig::instance() +{ + if (!theInstance) + { + theInstance = new PresConfig(); + } + return (*theInstance); +} + +void +PresConfig::initializeStack(SipStack& stack, int argc, char **argv) +{ + int fromPort = (argc>2?atoi(argv[2]):5060); + stack.addTransport(UDP, fromPort); + stack.addTransport(TCP, fromPort); +// stack.addTransport(Transport::UDP, fromPort,Data("207.219.179.228")); +// stack.addTransport(Transport::TCP, fromPort,Data("207.219.179.228")); +} + +void +PresConfig::initializeResources(int argc, char **argv) +{ + ResourceMgr::instance() + .addResource(Data("RjS@127.0.0.1")); +// ResourceMgr::instance() +// .addResource(Data("pekka@ds.sipit.net")); +} diff --git a/src/libs/resiprocate/presSvr/PresConfig.h b/src/libs/resiprocate/presSvr/PresConfig.h new file mode 100644 index 00000000..4d45ec04 --- /dev/null +++ b/src/libs/resiprocate/presSvr/PresConfig.h @@ -0,0 +1,14 @@ +#ifndef PRESCONFIG +#define PRESCONFIG + +class PresConfig { + public: + static PresConfig & instance(); + void initializeStack(resip::SipStack& stack, int argc, char ** argv); + void initializeResources(int argc, char ** argv); + private: + PresConfig(){} + ~PresConfig(){} + static PresConfig *theInstance; +}; +#endif diff --git a/src/libs/resiprocate/presSvr/Resource.cpp b/src/libs/resiprocate/presSvr/Resource.cpp new file mode 100644 index 00000000..aa5a25cf --- /dev/null +++ b/src/libs/resiprocate/presSvr/Resource.cpp @@ -0,0 +1,50 @@ +#include "Resource.h" + +#include "resip/stack/PlainContents.hxx" + +using namespace resip; + +Resource::Resource() +{ + mPresenceDocument = new PlainContents("No known Presence document"); +} + +Resource::~Resource() +{ + delete mPresenceDocument; +} + +void +Resource::setPresenceDocument(Contents* document) +{ + delete mPresenceDocument; + mPresenceDocument = document->clone(); + notifyPDocObservers(); +} + +void +Resource::attachToPresenceDoc(SubDialog* observer) +{ + mPdocObservers.insert(observer); +} + +void +Resource::detachFromPresenceDoc(SubDialog* observer) +{ + PDocObserverSet_t::iterator iter = mPdocObservers.find(observer); + if (iter!=mPdocObservers.end()) + { + mPdocObservers.erase(iter); + } +} + +void +Resource::notifyPDocObservers() +{ + PDocObserverSet_t::iterator iter = mPdocObservers.begin(); + while (iter!=mPdocObservers.end()) + { + (*iter)->presenceDocumentChanged(presenceDocument()); + ++iter; + } +} diff --git a/src/libs/resiprocate/presSvr/Resource.h b/src/libs/resiprocate/presSvr/Resource.h new file mode 100644 index 00000000..7c8da118 --- /dev/null +++ b/src/libs/resiprocate/presSvr/Resource.h @@ -0,0 +1,27 @@ +#ifndef RESOURCE +#define RESOURCE + +#include <set> +#include "resip/stack/Contents.hxx" +#include "SubDialog.h" + +typedef std::set<SubDialog *> PDocObserverSet_t; + +using namespace resip; + +class Resource { + public: + Resource(); + ~Resource(); + const Contents * presenceDocument() {return mPresenceDocument;} + void setPresenceDocument(Contents* document); + void attachToPresenceDoc(SubDialog* observer); + void detachFromPresenceDoc(SubDialog* observer); + + private: + void notifyPDocObservers(); + Contents * mPresenceDocument; + PDocObserverSet_t mPdocObservers; +}; + +#endif diff --git a/src/libs/resiprocate/presSvr/ResourceMgr.cpp b/src/libs/resiprocate/presSvr/ResourceMgr.cpp new file mode 100644 index 00000000..3190b940 --- /dev/null +++ b/src/libs/resiprocate/presSvr/ResourceMgr.cpp @@ -0,0 +1,90 @@ +#include "rutil/Data.hxx" +#include "ResourceMgr.h" + +#include <iostream> + +using std::cout; +using std::endl; + +ResourceMgr* ResourceMgr::mInstance = 0; + +ResourceMgr& +ResourceMgr::instance() +{ + if (!mInstance) { mInstance = new ResourceMgr(); } + return (*mInstance); +} + +bool +ResourceMgr::exists(const Data& aor) +{ + return (mResources.find(aor)!=mResources.end()); +} + +bool +ResourceMgr::addResource(const Data& aor) +{ + if (exists(aor)) return 0; + pair<Data,Resource*> mapentry = make_pair(aor, new Resource); + pair<ResourceMap_iter,bool> inserted = mResources.insert(mapentry); + if (!inserted.second) + { + delete mapentry.second; + return 0; + } + else + { + return 1; + } +} + +bool +ResourceMgr::setPresenceDocument(const Data& aor, Contents* contents) +{ + // ?dlb? assert(contents); + ResourceMap_iter resIter = mResources.find(aor); + if (resIter!=mResources.end()) + { + (resIter->second)->setPresenceDocument(contents); + return 1; + } + else + { + return 0; + } +} + +const Contents* +ResourceMgr::presenceDocument(const Data& aor) +{ + ResourceMap_iter resIter = mResources.find(aor); + if (resIter!=mResources.end()) + { + return (resIter->second)->presenceDocument(); + } + else + { + return NULL; + } +} + +void +ResourceMgr::attachToPresenceDoc(const Data& aor, SubDialog* observer) +{ + ResourceMap_iter resIter = mResources.find(aor); + if (resIter!=mResources.end()) + { + (resIter->second)->attachToPresenceDoc(observer); + } +} + +void +ResourceMgr::detachFromPresenceDoc(const Data& aor, SubDialog* observer) +{ + ResourceMap_iter resIter = mResources.find(aor); + if (resIter!=mResources.end()) + { + (resIter->second)->detachFromPresenceDoc(observer); + } +} + diff --git a/src/libs/resiprocate/presSvr/ResourceMgr.h b/src/libs/resiprocate/presSvr/ResourceMgr.h new file mode 100644 index 00000000..6ff53810 --- /dev/null +++ b/src/libs/resiprocate/presSvr/ResourceMgr.h @@ -0,0 +1,28 @@ +#ifndef RESOURCEMGR +#define RESOURCEMGR +#include <map> + +#include "Resource.h" + +using namespace resip; +using namespace std; + +typedef map<Data,Resource*> ResourceMap; +typedef ResourceMap::iterator ResourceMap_iter; + +class ResourceMgr { + public: + static ResourceMgr& instance(); + bool exists(const Data& aor); + bool addResource(const Data& aor); + bool setPresenceDocument(const Data& aor, Contents* contents); + const Contents* presenceDocument(const Data& aor); + void attachToPresenceDoc(const Data& aor, SubDialog* observer); + void detachFromPresenceDoc(const Data& aor, SubDialog* observer); + private: + ResourceMgr(){} + ~ResourceMgr(){} + ResourceMap mResources; + static ResourceMgr* mInstance; +}; +#endif diff --git a/src/libs/resiprocate/presSvr/SubDialog.cpp b/src/libs/resiprocate/presSvr/SubDialog.cpp new file mode 100644 index 00000000..53ed0ccb --- /dev/null +++ b/src/libs/resiprocate/presSvr/SubDialog.cpp @@ -0,0 +1,167 @@ +#include "SubDialog.h" +#include "ResourceMgr.h" +#include "rutil/MD5Stream.hxx" +#include "resip/stack/Helper.hxx" + +SubDialog::SubDialog(Data key, SipStack* stack, DialogState *dlgState) + : mKey(key) +{ + assert (dlgState); + mStack = stack; + mSubState = NULL; + mDlgState = dlgState; +} + +SubDialog::~SubDialog() +{ + ResourceMgr::instance().detachFromPresenceDoc(mSubState->resource(),this); + if (mSubState) delete mSubState; +} + +SubDialogCondition +SubDialog::processSubscribe(SipMessage* msg) +{ + + if (!mSubState) + { + mSubState = new SubscriptionState; + + mSubState->resource() = msg->header(h_RequestLine).uri().getAorNoPort(); + if (!msg->exists(h_Expires)) + { + mSubState->expires() = time(NULL)+3600; + } + else + { + // ?dlb? maximum/minimum expire? + mSubState->expires() = (time(NULL)+msg->header(h_Expires).value()); + } + + + mSubState->event() = msg->header(h_Event).value(); + mSubState->eventId() = msg->header(h_Event).param(p_id); + // need subState.watcher + // subState.Accepts + + // check authorization + // reject if no + // setup observation of resource + ResourceMgr::instance().attachToPresenceDoc(mSubState->resource(),this); + } else { + assert(mSubState); + assert(mDlgState); + // verify remote CSeq is sane + // ?dlb? expires not present? + mSubState->expires() = (time(NULL)+msg->header(h_Expires).value()); + + } + + auto_ptr<SipMessage> resp(Helper::makeResponse(*msg,202,"")); + resp->header(h_Expires).value() = mSubState->expires()-time(NULL); + mStack->send(*resp); + + sendNotify(ResourceMgr::instance().presenceDocument(mSubState->resource())); + return ACTIVE; + +} + +void +SubDialog::sendNotify() +{ + sendNotify(ResourceMgr::instance().presenceDocument(mSubState->resource())); +} + +void +SubDialog::sendNotify(const Contents* document) +{ + + assert (document); + + bool expired = (mSubState->expires()<=time(NULL)); + + + SipMessage *notify = new SipMessage;; + { + RequestLine rLine(NOTIFY); + rLine.uri() = mDlgState->remoteTarget().uri(); + notify->header(h_RequestLine) = rLine; + notify->header(h_To) = mDlgState->remoteTFHeader(); + notify->header(h_From) = mDlgState->localTFHeader(); + notify->header(h_CallId).value() = mDlgState->callId(); + notify->header(h_CSeq).method() = NOTIFY; + notify->header(h_CSeq).sequence() = (++(mDlgState->localCSeq())); + notify->header(h_Event).value() = mSubState->event(); + if (!mSubState->eventId().empty()) + { + notify->header(h_Event).param(p_id) = mSubState->eventId(); + } + notify->header(h_Contacts).push_front(mDlgState->me()); + notify->header(h_MaxForwards).value() = 70; + { + Token substateHFV; + if (expired) + { + substateHFV.value() = Data("terminated"); + substateHFV.param(p_reason) = Data("timeout"); + } + else + { + substateHFV.value() = Data("active");// pending? + substateHFV.param(p_expires) = mSubState->expires()-time(NULL); + } + notify->header(h_SubscriptionState) = substateHFV; + } + + /*hackage*/ +// Token req; +// req.value() = Data("YouDontSupportThis"); +// notify->header(h_Requires).push_front(req); + /*end hackage*/ + notify->setContents(document); + + // Now build a via with the right dialog identifier in the client + // field of the branch parameter + { + Via firstVia; + firstVia.param(p_branch).clientData()= key(); + notify->header(h_Vias).push_front(firstVia); + } + + } + //send message + mStack->send(*notify); + delete notify; + //add transaction key to dlgState->pendingNotifies (may be waste) +} + +SubDialogCondition +SubDialog::processNotifyResponse(SipMessage *msg) +{ + //verify transactionkey (may be waste) + // if 1xx, ignore + // if 2xx return current condition + // if 481 just return condition TERMINATED + // + // think about other non2xx's - for now + // become TERMINATED, send a new NOTIFY and + // return condition TERMINATED + // + // Major hackage for simplet 1 + if (msg->header(h_StatusLine).responseCode() == 481) + { + return TERMINATED; + } + return ACTIVE; +} + +time_t +SubDialog::expires() { + assert(mSubState); + return mSubState->expires(); +} + +void +SubDialog::presenceDocumentChanged(const Contents* document) +{ + sendNotify(document); +} diff --git a/src/libs/resiprocate/presSvr/SubDialog.h b/src/libs/resiprocate/presSvr/SubDialog.h new file mode 100644 index 00000000..b13b85a9 --- /dev/null +++ b/src/libs/resiprocate/presSvr/SubDialog.h @@ -0,0 +1,38 @@ +#ifndef SUBDIALOG +#define SUBDIALOG + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/SipStack.hxx" +#include "rutil/Data.hxx" + +#include "SubscriptionState.h" +#include "DialogState.h" + +using namespace resip; + +enum SubDialogCondition { PENDING, ACTIVE, TERMINATED }; + +class SubDialog { + + public: + + SubDialog(Data key, SipStack* stack,DialogState* dlgState); + ~SubDialog(); + SubDialogCondition processSubscribe(SipMessage* msg); + SubDialogCondition processNotifyResponse(SipMessage *msg); + const Data& key(){ return mKey; } + DialogState* dialogState() {return mDlgState;} + time_t expires(); + void presenceDocumentChanged(const Contents* document); + void sendNotify(); + + private: + void sendNotify(const Contents* document); + Data mKey; + SipStack* mStack; + SubscriptionState* mSubState; + DialogState* mDlgState; + +}; + +#endif diff --git a/src/libs/resiprocate/presSvr/SubDialogMgr.cpp b/src/libs/resiprocate/presSvr/SubDialogMgr.cpp new file mode 100644 index 00000000..99d36215 --- /dev/null +++ b/src/libs/resiprocate/presSvr/SubDialogMgr.cpp @@ -0,0 +1,162 @@ +#include "resip/stack/Helper.hxx" +#include "rutil/MD5Stream.hxx" +#include "SubDialogMgr.h" + +using namespace resip; + +void +SubDialogMgr::dispatchSubscribe(SipMessage* msg) +{ + SubDialog *dialog = matchDialog(msg); + if (!dialog) + { + auto_ptr<SipMessage> resp(Helper::makeResponse(*msg,481,"")); + mStack->send(*resp); + // !dlb! return here? + } + SubDialogCondition cond= dialog->processSubscribe(msg); + if (cond==TERMINATED) + { + destroyDialog(dialog); + } + else + { + mExpirationMap.insert( make_pair(dialog->expires(),dialog->key()) ); + } +} + +void +SubDialogMgr::dispatchNewSubscribe(SipMessage* msg) +{ + SubDialog *dialog = createDialog(msg); + SubDialogCondition cond = dialog->processSubscribe(msg); + if (cond==TERMINATED) + { + destroyDialog(dialog); + } + else + { + mExpirationMap.insert( make_pair(dialog->expires(),dialog->key()) ); + } +} + + +void +SubDialogMgr::dispatchNotifyResponse(SipMessage* msg) +{ + SubDialog *dialog = matchDialog(msg); + if (dialog) + { + SubDialogCondition cond = dialog->processNotifyResponse(msg); + if (cond==TERMINATED) + { + destroyDialog(dialog); + } + } +} + +SubDialog * +SubDialogMgr::matchDialog(SipMessage* msg) +{ + Data dialogKey = getDialogKey(msg); + DialogMap_t::iterator iter=mDialogMap.find(dialogKey) ; + return (iter==mDialogMap.end()? NULL: (*iter).second); +} + +bool +SubDialogMgr::dialogExists(SipMessage* msg) +{ + return (matchDialog(msg)!=NULL); +} + +SubDialog * +SubDialogMgr::createDialog(SipMessage* msg) +{ + if (!msg->header(h_To).exists(p_tag)) + { + msg->header(h_To).param(p_tag) = Helper::computeTag(Helper::tagSize); + } + Data dialogKey = getDialogKey(msg); + assert(mDialogMap.find(dialogKey)==mDialogMap.end()); + + DialogState* dlgState = mDialogSetMgr.attachDialogState(msg); + SubDialog *dlg = new SubDialog(dialogKey,mStack,dlgState); + pair<DialogMap_t::iterator,bool> result = + mDialogMap.insert(make_pair(dialogKey,dlg)); + assert(result.second); + return(dlg); +} + +void +SubDialogMgr::destroyDialog(SubDialog* dlg) +{ + DialogMap_t::iterator iter= + mDialogMap.find(dlg->key()); + assert ( iter!=mDialogMap.end() ); + mDialogSetMgr.detachDialogState(dlg); + mDialogMap.erase(iter); + delete (dlg); +} + +Data +SubDialogMgr::getDialogKey(SipMessage * msg) +{ + //closer, but this is still broken + // one has the dialogsetkey in it, the other doesn't. + // + if (msg->isRequest()) + { + MD5Stream dlgKeyStr; + dlgKeyStr << mDialogSetMgr.getDialogSetKey(msg); + dlgKeyStr << ":"; + MD5Stream eventHashStr; + assert(msg->exists(h_Event)); + // ?dlb? empty event Ok? + eventHashStr << msg->header(h_Event); + if (msg->header(h_Event).exists(p_id)) + eventHashStr << ":" << msg->header(h_Event).param(p_id); + dlgKeyStr << eventHashStr.getHex(); + return dlgKeyStr.getHex(); + } + else + { + assert(msg->exists(h_Vias)); + return msg->header(h_Vias).front().param(p_branch).clientData(); + } +} + +// A (time,Data) pair gets put into mExpirationMap whenever +// a subscribe establishing a new expiration is processed. +// When a subscription is deleted, this map is not cleaned, +// so when processing it, we have to make sure the subscription +// that Data keys is still there. +// On a refresh subscription, old (time,Data) pairs belonging to +// this subscription are not removed, so we have to make +// sure the subscription keyed by this Data has actually +// expired before taking action beyond removing this pair. + +// A _Very large_ number of subscriptions expiring at once might +// block this thread too long. An alternative would be to return +// after processing the first (few?) subscriptions. + +// .dlb. manage clumping with a random jigger to expiration at time of +// subscription? + +void +SubDialogMgr::processExpirations() +{ + ExpirationMap_t::iterator iter = mExpirationMap.begin(); + while (( iter != mExpirationMap.end() ) && ( (iter->first) <= time(NULL) )) + { + DialogMap_t::iterator dlgIter = mDialogMap.find(iter->second); + if (dlgIter!=mDialogMap.end() + && (dlgIter->second)->expires() <= time(NULL)) + { + (dlgIter->second)->sendNotify(); + destroyDialog(dlgIter->second); + } + mExpirationMap.erase(iter); + // !dlbl! looks suspicious -- iter could be invalid? + ++iter; + } +} diff --git a/src/libs/resiprocate/presSvr/SubDialogMgr.h b/src/libs/resiprocate/presSvr/SubDialogMgr.h new file mode 100644 index 00000000..6f7ccdf6 --- /dev/null +++ b/src/libs/resiprocate/presSvr/SubDialogMgr.h @@ -0,0 +1,38 @@ +#ifndef SUBDIALOGMGR +#define SUBDIALOGMGR + +#include <map> +#include "resip/stack/SipMessage.hxx" +#include "rutil/Data.hxx" +#include "SubDialog.h" +#include "DialogSetMgr.h" + +using resip::SipMessage; +using resip::Data; + +// dialog key -> dialog object +typedef map<Data,SubDialog*> DialogMap_t; + +// expiration time -> dialog key +typedef multimap<time_t,Data> ExpirationMap_t; + +class SubDialogMgr { + public: + SubDialogMgr(SipStack* stack):mStack(stack),mDialogSetMgr(*this){} + void dispatchSubscribe(SipMessage* msg); + void dispatchNewSubscribe(SipMessage* msg); + void dispatchNotifyResponse(SipMessage* msg); + void processExpirations(); + bool dialogExists(SipMessage* msg); + private: + SubDialog* matchDialog(SipMessage* msg); + SubDialog* createDialog(SipMessage* msg); + Data getDialogKey(SipMessage* msg); + void destroyDialog(SubDialog* dlg); + SipStack *mStack; + DialogSetMgr mDialogSetMgr; + DialogMap_t mDialogMap; + ExpirationMap_t mExpirationMap; +}; + +#endif diff --git a/src/libs/resiprocate/presSvr/SubscriptionState.h b/src/libs/resiprocate/presSvr/SubscriptionState.h new file mode 100644 index 00000000..8f5d079a --- /dev/null +++ b/src/libs/resiprocate/presSvr/SubscriptionState.h @@ -0,0 +1,19 @@ +#ifndef SUBSCRIPTIONSTATE +#define SUBSCRIPTIONSTATE + +using namespace resip; + +class SubscriptionState{ + public: + Data & event() {return mEvent;} + Data & eventId() {return mEventId;} + Data & resource() {return mResource; } + time_t & expires() {return mExpires;} + private: + Data mEvent; + Data mEventId; + Data mResource; + time_t mExpires; +}; + +#endif diff --git a/src/libs/resiprocate/presSvr/TuPresSvr.cpp b/src/libs/resiprocate/presSvr/TuPresSvr.cpp new file mode 100644 index 00000000..4893c267 --- /dev/null +++ b/src/libs/resiprocate/presSvr/TuPresSvr.cpp @@ -0,0 +1,143 @@ +#include "resip/stack/Helper.hxx" + +#include "ResourceMgr.h" +#include "SubDialog.h" +#include "TuPresSvr.h" + +using namespace resip; + +bool +TuPresSvr::process() +{ + + bool done = 0; + FdSet fdset; + mStack->buildFdSet(fdset); +// int err = fdset.selectMilliSeconds(0); + int err = fdset.selectMilliSeconds(100); + assert( err != -1 ); + + mStack->process(fdset); + + SipMessage* msg = (mStack->receive()); + if (msg) + { + if (msg->isRequest()) + { + if (msg->header(h_RequestLine).getMethod() == SUBSCRIBE ) + { + processSubscribe(msg); + } + else if (msg->header(h_RequestLine).getMethod() == REGISTER ) + { + processPublish(msg); + } + else if (msg->header(h_RequestLine).getMethod() == OPTIONS ) + { + auto_ptr<SipMessage> resp( + Helper::makeResponse(*msg,500,"You Shot Me!")); + mStack->send(*resp); + done = 1; + } + else if (msg->header(h_RequestLine).getMethod() == PUBLISH) + { + processPublish(msg); + } + else + { + auto_ptr<SipMessage> resp(Helper::makeResponse(*msg,501,"")); + mStack->send(*resp); + } + } + else + { + /* + Nope - dialog key is currently overscoped to requests - bad. + assert(msg->isResponse()); + if (msg->header(h_CSeq).method()==NOTIFY) + mDialogMgr.dispatchNotifyResponse(msg); + */ + } + delete msg; + } else { + mDialogMgr.processExpirations(); + } + return done; +} + +void +TuPresSvr::processSubscribe(SipMessage* msg) +{ + // See if this subscribe matches a dialog we have in progress + if (mDialogMgr.dialogExists(msg)) + { + mDialogMgr.dispatchSubscribe(msg); + } + else + { + processNewSubscribe(msg); + } +} + +void TuPresSvr::processNewSubscribe(SipMessage* msg) +{ + static Token presence("presence"); + if ( !msg->exists(h_Event) + || msg->header(h_Event).value()!=presence.value() + ) + { + auto_ptr<SipMessage> resp(Helper::makeResponse(*msg,489,"")); + resp->header(h_AllowEvents).push_back(presence); + mStack->send(*resp); + return; + } + + if (ResourceMgr::instance() + .exists(msg->header(h_RequestLine).uri().getAorNoPort())) + { + mDialogMgr.dispatchNewSubscribe(msg); + } + else + { + auto_ptr<SipMessage> resp(Helper::makeResponse(*msg,404,"")); + mStack->send(*resp); + } + +} + +void TuPresSvr::processPublish(SipMessage* msg) +{ + //ignore any PUBLISH related headers and any contacts + //provided in a REGISTER + //This is a rather vile hack for SIMPLEt 1 + Data aor; + if ( msg->header(h_RequestLine).getMethod() == REGISTER ) + { + aor = msg->header(h_To).uri().getAorNoPort(); + } + else + { + aor = msg->header(h_RequestLine).uri().getAorNoPort(); + } + if (ResourceMgr::instance().exists(aor)) + { + Contents * contents = msg->getContents(); + if (contents) + { + int retcode = (ResourceMgr::instance().setPresenceDocument(aor,contents) + ?200:403); + auto_ptr<SipMessage> resp(Helper::makeResponse(*msg,retcode,"")); + mStack->send(*resp); + } + else + { + auto_ptr<SipMessage> resp(Helper::makeResponse(*msg,400,"This hacked-up service requires a body")); + mStack->send(*resp); + } + } + else + { + auto_ptr<SipMessage> resp(Helper::makeResponse(*msg,404,"")); + mStack->send(*resp); + } +} diff --git a/src/libs/resiprocate/presSvr/TuPresSvr.h b/src/libs/resiprocate/presSvr/TuPresSvr.h new file mode 100644 index 00000000..a8694667 --- /dev/null +++ b/src/libs/resiprocate/presSvr/TuPresSvr.h @@ -0,0 +1,22 @@ +#ifndef TUPRESSVR +#define TUPRESSVR + +#include "resip/stack/SipStack.hxx" +#include "resip/stack/SipMessage.hxx" +#include "SubDialogMgr.h" + +using namespace resip; + +class TuPresSvr { + public: + TuPresSvr(SipStack* stack):mStack(stack),mDialogMgr(stack){} + bool process(); + void processSubscribe(SipMessage* msg); + void processNewSubscribe(SipMessage* msg); + void processPublish(SipMessage* msg); + private: + SipStack* mStack; + SubDialogMgr mDialogMgr; +}; + +#endif diff --git a/src/libs/resiprocate/presSvr/presSvr.cpp b/src/libs/resiprocate/presSvr/presSvr.cpp new file mode 100644 index 00000000..78348299 --- /dev/null +++ b/src/libs/resiprocate/presSvr/presSvr.cpp @@ -0,0 +1,39 @@ +#include "resip/stack/SipStack.hxx" +#include "rutil/Logger.hxx" +#include "PresConfig.h" +#include "TuPresSvr.h" + + +#include <time.h> + +using namespace resip; +using namespace std; + +int +main (int argc, char* argv[]) +{ + Log::initialize(Log::Cout,Log::Debug,Data("PresSvr")); + + SipStack stack1; + + PresConfig::instance().initializeStack(stack1,argc,argv); + PresConfig::instance().initializeResources(argc,argv); + + TuPresSvr tu(&stack1); + + bool done = 0; + while(!done) + { + done = tu.process(); + } + + //this is bogus + time_t start; time(&start); + done = 0; + while (!done) + { + tu.process(); + done = ((time(0)-start)>64); + } + +} diff --git a/src/libs/resiprocate/reSIProcate_10_0.sln b/src/libs/resiprocate/reSIProcate_10_0.sln new file mode 100644 index 00000000..1ea56ca8 --- /dev/null +++ b/src/libs/resiprocate/reSIProcate_10_0.sln @@ -0,0 +1,135 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resiprocate", "resip\stack\resiprocate_10_0.vcxproj", "{2A8BE839-6466-4001-B224-8F1C3168D04A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dum", "resip\dum\dum_10_0.vcxproj", "{31B0654F-E08E-405F-909F-80F86CB14B9D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basicCall", "resip\dum\test\basicCall_10_0.vcxproj", "{5973C598-5CB7-4724-A1EB-EBE3D9F84927}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basicMessage", "resip\dum\test\basicMessage_10_0.vcxproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basicRegister", "resip\dum\test\basicRegister_10_0.vcxproj", "{34E29A7D-181B-4A13-9194-EB2300000000}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "rutil\rutil_10_0.vcxproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_static", "contrib\db\build_win32\db_static_10_0.vcxproj", "{9E5A7645-1502-4467-91F8-BCF2EB06EF72}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcre", "contrib\pcre\pcre_10_0.vcxproj", "{B933F895-8EFB-4FDD-A46D-09B8C00D1D26}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "repro", "repro\repro_10_0.vcxproj", "{9D8D2649-213F-49D3-A8B0-C1849C611654}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resip_test", "resip\stack\test\test_10_0.vcxproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "contrib\ares\ares_10_0.vcxproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" +EndProject +Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "ReproSetup", "repro\WinSetup\Setup_10_0.vdproj", "{02954DA6-5079-4717-BC3D-B3ACA815CFED}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + SSL-Debug|Win32 = SSL-Debug|Win32 + SSL-Release|Win32 = SSL-Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.ActiveCfg = Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.Build.0 = Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.ActiveCfg = Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.Build.0 = Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug|Win32.ActiveCfg = Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug|Win32.Build.0 = Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release|Win32.ActiveCfg = Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release|Win32.Build.0 = Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Debug|Win32.ActiveCfg = Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Debug|Win32.Build.0 = Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Release|Win32.ActiveCfg = Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Release|Win32.Build.0 = Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Debug|Win32.ActiveCfg = Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Debug|Win32.Build.0 = Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Release|Win32.ActiveCfg = Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Release|Win32.Build.0 = Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Debug|Win32.Build.0 = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Release|Win32.ActiveCfg = Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Release|Win32.Build.0 = Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Release|Win32.Build.0 = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug|Win32.ActiveCfg = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug|Win32.Build.0 = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release|Win32.ActiveCfg = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release|Win32.Build.0 = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Release|Win32.Build.0 = Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Debug|Win32.ActiveCfg = Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Debug|Win32.Build.0 = Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Release|Win32.ActiveCfg = Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Release|Win32.Build.0 = Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release|Win32.Build.0 = Release|Win32 + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.Debug|Win32.ActiveCfg = Debug + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.Debug|Win32.Build.0 = Debug + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.Release|Win32.ActiveCfg = Release + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.Release|Win32.Build.0 = Release + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.SSL-Debug|Win32.ActiveCfg = Debug + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.SSL-Debug|Win32.Build.0 = Debug + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.SSL-Release|Win32.ActiveCfg = Release + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.SSL-Release|Win32.Build.0 = Release + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/reSIProcate_7_1.sln b/src/libs/resiprocate/reSIProcate_7_1.sln new file mode 100644 index 00000000..f4675411 --- /dev/null +++ b/src/libs/resiprocate/reSIProcate_7_1.sln @@ -0,0 +1,205 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resiprocate", "resip\stack\resiprocate_7_1.vcproj", "{2A8BE839-6466-4001-B224-8F1C3168D04A}" + ProjectSection(ProjectDependencies) = postProject + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dum", "resip\dum\dum_7_1.vcproj", "{31B0654F-E08E-405F-909F-80F86CB14B9D}" + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basicCall", "resip\dum\test\basicCall_7_1.vcproj", "{5973C598-5CB7-4724-A1EB-EBE3D9F84927}" + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basicMessage", "resip\dum\test\basicMessage_7_1.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC6}" + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basicRegister", "resip\dum\test\basicRegister_7_1.vcproj", "{34E29A7D-181B-4A13-9194-EB2300000000}" + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "rutil\rutil_7_1.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" + ProjectSection(ProjectDependencies) = postProject + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_static", "contrib\db\build_win32\db_static_7_1.vcproj", "{9E5A7645-1502-4467-91F8-BCF2EB06EF72}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcre", "contrib\pcre\pcre_7_1.vcproj", "{B933F895-8EFB-4FDD-A46D-09B8C00D1D26}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "repro", "repro\repro_7_1.vcproj", "{9D8D2649-213F-49D3-A8B0-C1849C611654}" + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {9E5A7645-1502-4467-91F8-BCF2EB06EF72} = {9E5A7645-1502-4467-91F8-BCF2EB06EF72} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} = {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resip_test", "resip\stack\test\test_7_1.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC5}" + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "contrib\ares\ares_7_1.vcproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "ReproSetup", "repro\WinSetup\Setup.vdproj", "{D531ED96-F2C7-40A5-BFA6-A205E6F1F807}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Debug71 = Debug71 + Release = Release + SSL-Debug = SSL-Debug + SSL-Release = SSL-Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug.ActiveCfg = Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug.Build.0 = Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug71.ActiveCfg = Debug71|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug71.Build.0 = Debug71|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release.ActiveCfg = Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release.Build.0 = Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Debug.ActiveCfg = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Debug.Build.0 = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Release.ActiveCfg = SSL-Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Release.Build.0 = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug.ActiveCfg = Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug.Build.0 = Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug71.ActiveCfg = Debug71|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug71.Build.0 = Debug71|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release.ActiveCfg = Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release.Build.0 = Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Debug.ActiveCfg = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Debug.Build.0 = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Release.ActiveCfg = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Release.Build.0 = SSL-Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Debug.ActiveCfg = Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Debug.Build.0 = Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Debug71.ActiveCfg = Debug71|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Debug71.Build.0 = Debug71|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Release.ActiveCfg = Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Release.Build.0 = Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Debug.ActiveCfg = SSL-Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Debug.Build.0 = SSL-Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Release.ActiveCfg = Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Release.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Debug.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Debug.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Debug71.ActiveCfg = Debug71|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Debug71.Build.0 = Debug71|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Release.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Release.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Debug.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Debug.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Release.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Release.Build.0 = Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Debug.ActiveCfg = Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Debug.Build.0 = Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Debug71.ActiveCfg = Debug71|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Debug71.Build.0 = Debug71|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Release.ActiveCfg = Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Release.Build.0 = Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Debug.ActiveCfg = SSL-Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Debug.Build.0 = SSL-Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Release.ActiveCfg = SSL-Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Release.Build.0 = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug.ActiveCfg = Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug.Build.0 = Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug71.ActiveCfg = Debug71|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug71.Build.0 = Debug71|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release.ActiveCfg = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release.Build.0 = SSL-Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Debug.ActiveCfg = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Debug.Build.0 = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Debug71.ActiveCfg = Debug71|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Debug71.Build.0 = Debug71|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Release.ActiveCfg = Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Release.Build.0 = Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Debug.ActiveCfg = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Debug.Build.0 = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Release.ActiveCfg = Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Release.Build.0 = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug.ActiveCfg = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug.Build.0 = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug71.ActiveCfg = Debug71|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug71.Build.0 = Debug71|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release.ActiveCfg = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release.Build.0 = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Debug.ActiveCfg = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Debug.Build.0 = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Release.ActiveCfg = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Release.Build.0 = Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Debug.ActiveCfg = Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Debug.Build.0 = Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Debug71.ActiveCfg = Debug71|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Debug71.Build.0 = Debug71|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Release.ActiveCfg = Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Release.Build.0 = Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Debug.ActiveCfg = SSL-Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Debug.Build.0 = SSL-Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Release.ActiveCfg = SSL-Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Release.Build.0 = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Debug.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Debug.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Debug71.ActiveCfg = Debug71|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Debug71.Build.0 = Debug71|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Release.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Release.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Debug.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Debug.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Release.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Release.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug71.ActiveCfg = Debug71|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug71.Build.0 = Debug71|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release.Build.0 = Release|Win32 + {D531ED96-F2C7-40A5-BFA6-A205E6F1F807}.Debug.ActiveCfg = Debug + {D531ED96-F2C7-40A5-BFA6-A205E6F1F807}.Debug.Build.0 = Debug + {D531ED96-F2C7-40A5-BFA6-A205E6F1F807}.Debug71.ActiveCfg = Debug71 + {D531ED96-F2C7-40A5-BFA6-A205E6F1F807}.Debug71.Build.0 = Debug71 + {D531ED96-F2C7-40A5-BFA6-A205E6F1F807}.Release.ActiveCfg = Release + {D531ED96-F2C7-40A5-BFA6-A205E6F1F807}.Release.Build.0 = Release + {D531ED96-F2C7-40A5-BFA6-A205E6F1F807}.SSL-Debug.ActiveCfg = Debug + {D531ED96-F2C7-40A5-BFA6-A205E6F1F807}.SSL-Debug.Build.0 = Debug + {D531ED96-F2C7-40A5-BFA6-A205E6F1F807}.SSL-Release.ActiveCfg = Release + {D531ED96-F2C7-40A5-BFA6-A205E6F1F807}.SSL-Release.Build.0 = Release + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/reSIProcate_8_0.sln b/src/libs/resiprocate/reSIProcate_8_0.sln new file mode 100644 index 00000000..d224d3c0 --- /dev/null +++ b/src/libs/resiprocate/reSIProcate_8_0.sln @@ -0,0 +1,218 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resiprocate", "resip\stack\resiprocate_8_0.vcproj", "{2A8BE839-6466-4001-B224-8F1C3168D04A}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dum", "resip\dum\dum_8_0.vcproj", "{31B0654F-E08E-405F-909F-80F86CB14B9D}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basicCall", "resip\dum\test\basicCall_8_0.vcproj", "{5973C598-5CB7-4724-A1EB-EBE3D9F84927}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basicMessage", "resip\dum\test\basicMessage_8_0.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC6}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basicRegister", "resip\dum\test\basicRegister_8_0.vcproj", "{34E29A7D-181B-4A13-9194-EB2300000000}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "rutil\rutil_8_0.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_static", "contrib\db\build_win32\db_static_8_0.vcproj", "{9E5A7645-1502-4467-91F8-BCF2EB06EF72}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcre", "contrib\pcre\pcre_8_0.vcproj", "{B933F895-8EFB-4FDD-A46D-09B8C00D1D26}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "repro", "repro\repro_8_0.vcproj", "{9D8D2649-213F-49D3-A8B0-C1849C611654}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {9E5A7645-1502-4467-91F8-BCF2EB06EF72} = {9E5A7645-1502-4467-91F8-BCF2EB06EF72} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} = {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resip_test", "resip\stack\test\test_8_0.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC5}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "contrib\ares\ares_8_0.vcproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "ReproSetup", "repro\WinSetup\Setup_8_0.vdproj", "{02954DA6-5079-4717-BC3D-B3ACA815CFED}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + SSL-Debug|Win32 = SSL-Debug|Win32 + SSL-Release|Win32 = SSL-Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.ActiveCfg = Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.Build.0 = Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.ActiveCfg = Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.Build.0 = Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug|Win32.ActiveCfg = Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug|Win32.Build.0 = Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release|Win32.ActiveCfg = Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release|Win32.Build.0 = Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Debug|Win32.ActiveCfg = Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Debug|Win32.Build.0 = Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Release|Win32.ActiveCfg = Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Release|Win32.Build.0 = Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Debug|Win32.ActiveCfg = Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Debug|Win32.Build.0 = Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Release|Win32.ActiveCfg = Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Release|Win32.Build.0 = Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Debug|Win32.Build.0 = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Release|Win32.ActiveCfg = Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Release|Win32.Build.0 = Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Release|Win32.Build.0 = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug|Win32.ActiveCfg = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug|Win32.Build.0 = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release|Win32.ActiveCfg = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release|Win32.Build.0 = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Release|Win32.Build.0 = Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Debug|Win32.ActiveCfg = Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Debug|Win32.Build.0 = Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Release|Win32.ActiveCfg = Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Release|Win32.Build.0 = Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release|Win32.Build.0 = Release|Win32 + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.Debug|Win32.ActiveCfg = Debug + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.Debug|Win32.Build.0 = Debug + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.Release|Win32.ActiveCfg = Release + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.Release|Win32.Build.0 = Release + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.SSL-Debug|Win32.ActiveCfg = Debug + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.SSL-Debug|Win32.Build.0 = Debug + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.SSL-Release|Win32.ActiveCfg = Release + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.SSL-Release|Win32.Build.0 = Release + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/reSIProcate_9_0.sln b/src/libs/resiprocate/reSIProcate_9_0.sln new file mode 100644 index 00000000..f57af356 --- /dev/null +++ b/src/libs/resiprocate/reSIProcate_9_0.sln @@ -0,0 +1,170 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resiprocate", "resip\stack\resiprocate_9_0.vcproj", "{2A8BE839-6466-4001-B224-8F1C3168D04A}" + ProjectSection(ProjectDependencies) = postProject + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dum", "resip\dum\dum_9_0.vcproj", "{31B0654F-E08E-405F-909F-80F86CB14B9D}" + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basicCall", "resip\dum\test\basicCall_9_0.vcproj", "{5973C598-5CB7-4724-A1EB-EBE3D9F84927}" + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basicMessage", "resip\dum\test\basicMessage_9_0.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC6}" + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basicRegister", "resip\dum\test\basicRegister_9_0.vcproj", "{34E29A7D-181B-4A13-9194-EB2300000000}" + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "rutil\rutil_9_0.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" + ProjectSection(ProjectDependencies) = postProject + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db_static", "contrib\db\build_win32\db_static_9_0.vcproj", "{9E5A7645-1502-4467-91F8-BCF2EB06EF72}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcre", "contrib\pcre\pcre_9_0.vcproj", "{B933F895-8EFB-4FDD-A46D-09B8C00D1D26}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "repro", "repro\repro_9_0.vcproj", "{9D8D2649-213F-49D3-A8B0-C1849C611654}" + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {9E5A7645-1502-4467-91F8-BCF2EB06EF72} = {9E5A7645-1502-4467-91F8-BCF2EB06EF72} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} = {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resip_test", "resip\stack\test\test_9_0.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC5}" + ProjectSection(ProjectDependencies) = postProject + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "contrib\ares\ares_9_0.vcproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" +EndProject +Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "ReproSetup", "repro\WinSetup\Setup_9_0.vdproj", "{02954DA6-5079-4717-BC3D-B3ACA815CFED}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + SSL-Debug|Win32 = SSL-Debug|Win32 + SSL-Release|Win32 = SSL-Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.ActiveCfg = Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.Build.0 = Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.ActiveCfg = Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.Build.0 = Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug|Win32.ActiveCfg = Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug|Win32.Build.0 = Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release|Win32.ActiveCfg = Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release|Win32.Build.0 = Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Debug|Win32.ActiveCfg = Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Debug|Win32.Build.0 = Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Release|Win32.ActiveCfg = Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.Release|Win32.Build.0 = Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {5973C598-5CB7-4724-A1EB-EBE3D9F84927}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC6}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Debug|Win32.ActiveCfg = Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Debug|Win32.Build.0 = Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Release|Win32.ActiveCfg = Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.Release|Win32.Build.0 = Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {34E29A7D-181B-4A13-9194-EB2300000000}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Debug|Win32.Build.0 = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Release|Win32.ActiveCfg = Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.Release|Win32.Build.0 = Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {9E5A7645-1502-4467-91F8-BCF2EB06EF72}.SSL-Release|Win32.Build.0 = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug|Win32.ActiveCfg = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug|Win32.Build.0 = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release|Win32.ActiveCfg = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release|Win32.Build.0 = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.SSL-Release|Win32.Build.0 = Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Debug|Win32.ActiveCfg = Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Debug|Win32.Build.0 = Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Release|Win32.ActiveCfg = Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.Release|Win32.Build.0 = Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {9D8D2649-213F-49D3-A8B0-C1849C611654}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC5}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release|Win32.Build.0 = Release|Win32 + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.Debug|Win32.ActiveCfg = Debug + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.Debug|Win32.Build.0 = Debug + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.Release|Win32.ActiveCfg = Release + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.Release|Win32.Build.0 = Release + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.SSL-Debug|Win32.ActiveCfg = Debug + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.SSL-Debug|Win32.Build.0 = Debug + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.SSL-Release|Win32.ActiveCfg = Release + {02954DA6-5079-4717-BC3D-B3ACA815CFED}.SSL-Release|Win32.Build.0 = Release + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/reTurn/AsyncSocketBase.cxx b/src/libs/resiprocate/reTurn/AsyncSocketBase.cxx new file mode 100644 index 00000000..eec5a609 --- /dev/null +++ b/src/libs/resiprocate/reTurn/AsyncSocketBase.cxx @@ -0,0 +1,202 @@ +#include "AsyncSocketBase.hxx" +#include "AsyncSocketBaseHandler.hxx" +#include <boost/bind.hpp> +#include <rutil/WinLeakCheck.hxx> + +using namespace std; + +#define NO_CHANNEL ((unsigned short)-1) + +namespace reTurn { + +AsyncSocketBase::AsyncSocketBase(asio::io_service& ioService) : + mIOService(ioService), + mReceiving(false), + mConnected(false), + mAsyncSocketBaseHandler(0) +{ +} + +AsyncSocketBase::~AsyncSocketBase() +{ + if(mAsyncSocketBaseHandler) mAsyncSocketBaseHandler->onSocketDestroyed(); +} + +void +AsyncSocketBase::send(const StunTuple& destination, boost::shared_ptr<DataBuffer>& data) +{ + mIOService.post(boost::bind(&AsyncSocketBase::doSend, shared_from_this(), destination, data, 0)); +} + +void +AsyncSocketBase::send(const StunTuple& destination, unsigned short channel, boost::shared_ptr<DataBuffer>& data) +{ + mIOService.post(boost::bind(&AsyncSocketBase::doSend, shared_from_this(), destination, channel, data, 0)); +} + +void +AsyncSocketBase::doSend(const StunTuple& destination, boost::shared_ptr<DataBuffer>& data, unsigned int bufferStartPos) +{ + doSend(destination, NO_CHANNEL, data, bufferStartPos); +} + +void +AsyncSocketBase::doSend(const StunTuple& destination, unsigned short channel, boost::shared_ptr<DataBuffer>& data, unsigned int bufferStartPos) +{ + bool writeInProgress = !mSendDataQueue.empty(); + if(channel == NO_CHANNEL) + { + boost::shared_ptr<DataBuffer> empty; + mSendDataQueue.push_back(SendData(destination, empty, data, bufferStartPos)); + } + else + { + // Add Turn Framing + boost::shared_ptr<DataBuffer> frame = allocateBuffer(4); + channel = htons(channel); + memcpy(&(*frame)[0], &channel, 2); + unsigned short msgsize = htons((unsigned short)data->size()); + memcpy(&(*frame)[2], (void*)&msgsize, 2); // UDP doesn't need size - but shouldn't hurt to send it anyway + + mSendDataQueue.push_back(SendData(destination, frame, data, bufferStartPos)); + } + if (!writeInProgress) + { + sendFirstQueuedData(); + } +} + +void +AsyncSocketBase::handleSend(const asio::error_code& e) +{ + if(!e) + { + onSendSuccess(); + } + else + { + onSendFailure(e); + } + + // TODO - check if closed here, and if so don't try and send more + + // Clear this data from the queue and see if there is more data to send + mSendDataQueue.pop_front(); + if (!mSendDataQueue.empty()) + { + sendFirstQueuedData(); + } +} + +void +AsyncSocketBase::sendFirstQueuedData() +{ + std::vector<asio::const_buffer> bufs; + if(mSendDataQueue.front().mFrameData.get() != 0) // If we have frame data + { + bufs.push_back(asio::buffer(mSendDataQueue.front().mFrameData->data(), mSendDataQueue.front().mFrameData->size())); + } + bufs.push_back(asio::buffer(mSendDataQueue.front().mData->data()+mSendDataQueue.front().mBufferStartPos, mSendDataQueue.front().mData->size()-mSendDataQueue.front().mBufferStartPos)); + transportSend(mSendDataQueue.front().mDestination, bufs); +} + +void +AsyncSocketBase::receive() +{ + mIOService.post(boost::bind(&AsyncSocketBase::doReceive, shared_from_this())); +} + +void +AsyncSocketBase::doReceive() +{ + if(!mReceiving) + { + mReceiving=true; + mReceiveBuffer = allocateBuffer(RECEIVE_BUFFER_SIZE); + transportReceive(); + } +} + +void +AsyncSocketBase::framedReceive() +{ + mIOService.post(boost::bind(&AsyncSocketBase::doFramedReceive, shared_from_this())); +} + +void +AsyncSocketBase::doFramedReceive() +{ + if(!mReceiving) + { + mReceiving=true; + mReceiveBuffer = allocateBuffer(RECEIVE_BUFFER_SIZE); + transportFramedReceive(); + } +} + +void +AsyncSocketBase::handleReceive(const asio::error_code& e, std::size_t bytesTransferred) +{ + mReceiving = false; + + if(!e) + { + // Handoff received buffer to appliction, and prepare receive buffer for next call + mReceiveBuffer->truncate(bytesTransferred); + onReceiveSuccess(getSenderEndpointAddress(), getSenderEndpointPort(), mReceiveBuffer); + } + else + { + onReceiveFailure(e); + } +} + +void +AsyncSocketBase::close() +{ + mIOService.post(boost::bind(&AsyncSocketBase::transportClose, shared_from_this())); +} + +boost::shared_ptr<DataBuffer> +AsyncSocketBase::allocateBuffer(unsigned int size) +{ + return boost::shared_ptr<DataBuffer>(new DataBuffer(size)); +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/reTurn/AsyncSocketBase.hxx b/src/libs/resiprocate/reTurn/AsyncSocketBase.hxx new file mode 100644 index 00000000..6a201061 --- /dev/null +++ b/src/libs/resiprocate/reTurn/AsyncSocketBase.hxx @@ -0,0 +1,157 @@ +#ifndef ASYNC_SOCKET_BASE_HXX +#define ASYNC_SOCKET_BASE_HXX + +#include <deque> +#include <asio.hpp> +#include <boost/bind.hpp> +#include <boost/enable_shared_from_this.hpp> + +#include "DataBuffer.hxx" +#include "StunTuple.hxx" + +#define RECEIVE_BUFFER_SIZE 2048 // ?slg? should we shrink this to something closer to MTU (1500 bytes)? + +namespace reTurn { + +class AsyncSocketBaseHandler; +class AsyncSocketBaseDestroyedHandler; + +class AsyncSocketBase : + public boost::enable_shared_from_this<AsyncSocketBase> +{ +public: + AsyncSocketBase(asio::io_service& ioService); + virtual ~AsyncSocketBase(); + + virtual unsigned int getSocketDescriptor() = 0; + + virtual void registerAsyncSocketBaseHandler(AsyncSocketBaseHandler* handler) { mAsyncSocketBaseHandler = handler; } + + /// Note: The following API's are thread safe and queue the request to be handled by the ioService thread + virtual asio::error_code bind(const asio::ip::address& address, unsigned short port) = 0; + virtual void connect(const std::string& address, unsigned short port) = 0; + /// Note: destination is ignored for TCP and TLS connections + virtual void send(const StunTuple& destination, boost::shared_ptr<DataBuffer>& data); // Send unframed data + virtual void send(const StunTuple& destination, unsigned short channel, boost::shared_ptr<DataBuffer>& data); // send with turn framing + /// Overlapped calls to receive functions have no effect + virtual void receive(); + virtual void framedReceive(); + virtual void close(); + + bool isConnected() { return mConnected; } + asio::ip::address& getConnectedAddress() { return mConnectedAddress; } + unsigned short getConnectedPort() { return mConnectedPort; } + + /// Use these if you already operating within the ioService thread + virtual void doSend(const StunTuple& destination, unsigned short channel, boost::shared_ptr<DataBuffer>& data, unsigned int bufferStartPos=0); + virtual void doSend(const StunTuple& destination, boost::shared_ptr<DataBuffer>& data, unsigned int bufferStartPos=0); + virtual void doReceive(); + virtual void doFramedReceive(); + + /// Class override callbacks + virtual void onConnectSuccess() { assert(false); } + virtual void onConnectFailure(const asio::error_code& e) { assert(false); } + virtual void onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) = 0; + virtual void onReceiveFailure(const asio::error_code& e) = 0; + virtual void onSendSuccess() = 0; + virtual void onSendFailure(const asio::error_code& e) = 0; + + /// Utility API + static boost::shared_ptr<DataBuffer> allocateBuffer(unsigned int size); + + // Stubbed out async handlers needed by Protocol specific Subclasses of this - the requirement for these + // to be in the base class all revolves around the shared_from_this() use/requirement + virtual void start() { assert(false); } + virtual void stop() { assert(false); } + virtual void handleReadHeader(const asio::error_code& e) { assert(false); } + virtual void handleServerHandshake(const asio::error_code& e) { assert(false); } + virtual void handleTcpResolve(const asio::error_code& ec, asio::ip::tcp::resolver::iterator endpoint_iterator) { assert(false); } + virtual void handleUdpResolve(const asio::error_code& ec, asio::ip::udp::resolver::iterator endpoint_iterator) { assert(false); } + virtual void handleConnect(const asio::error_code& ec, asio::ip::tcp::resolver::iterator endpoint_iterator) { assert(false); } + virtual void handleClientHandshake(const asio::error_code& ec, asio::ip::tcp::resolver::iterator endpoint_iterator) { assert(false); } + +protected: + /// Handle completion of a sendData operation. + virtual void handleSend(const asio::error_code& e); + virtual void handleReceive(const asio::error_code& e, std::size_t bytesTransferred); + + /// The io_service used to perform asynchronous operations. + asio::io_service& mIOService; + + /// Receive Buffer and state + boost::shared_ptr<DataBuffer> mReceiveBuffer; + bool mReceiving; + + /// Connected Info and State + asio::ip::address mConnectedAddress; + unsigned short mConnectedPort; + bool mConnected; + + /// Handlers + AsyncSocketBaseHandler* mAsyncSocketBaseHandler; + +private: + virtual void transportSend(const StunTuple& destination, std::vector<asio::const_buffer>& buffers) = 0; + virtual void transportReceive() = 0; + virtual void transportFramedReceive() = 0; + virtual void transportClose() = 0; + + virtual const asio::ip::address getSenderEndpointAddress() = 0; + virtual unsigned short getSenderEndpointPort() = 0; + + virtual void sendFirstQueuedData(); + class SendData + { + public: + SendData(const StunTuple& destination, boost::shared_ptr<DataBuffer>& frameData, boost::shared_ptr<DataBuffer>& data, unsigned int bufferStartPos = 0) : + mDestination(destination), mFrameData(frameData), mData(data), mBufferStartPos(bufferStartPos) {} + StunTuple mDestination; + boost::shared_ptr<DataBuffer> mFrameData; + boost::shared_ptr<DataBuffer> mData; + unsigned int mBufferStartPos; + }; + /// Queue of data to send + typedef std::deque<SendData> SendDataQueue; + SendDataQueue mSendDataQueue; +}; + +typedef boost::shared_ptr<AsyncSocketBase> ConnectionPtr; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/AsyncSocketBaseHandler.hxx b/src/libs/resiprocate/reTurn/AsyncSocketBaseHandler.hxx new file mode 100644 index 00000000..b592fecc --- /dev/null +++ b/src/libs/resiprocate/reTurn/AsyncSocketBaseHandler.hxx @@ -0,0 +1,52 @@ +#ifndef ASYNC_SOCKET_BASE_HANDLER_HXX +#define ASYNC_SOCKET_BASE_HANDLER_HXX + +namespace reTurn { + +class AsyncSocketBaseHandler +{ +public: + AsyncSocketBaseHandler() {} + virtual ~AsyncSocketBaseHandler() {} + + virtual void onSocketDestroyed() = 0; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/AsyncTcpSocketBase.cxx b/src/libs/resiprocate/reTurn/AsyncTcpSocketBase.cxx new file mode 100644 index 00000000..40ebb488 --- /dev/null +++ b/src/libs/resiprocate/reTurn/AsyncTcpSocketBase.cxx @@ -0,0 +1,242 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <boost/bind.hpp> + +#include "AsyncTcpSocketBase.hxx" +#include "AsyncSocketBaseHandler.hxx" +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; + +namespace reTurn { + +AsyncTcpSocketBase::AsyncTcpSocketBase(asio::io_service& ioService) + : AsyncSocketBase(ioService), + mSocket(ioService), + mResolver(ioService) +{ +} + +AsyncTcpSocketBase::~AsyncTcpSocketBase() +{ +} + +unsigned int +AsyncTcpSocketBase::getSocketDescriptor() +{ + return mSocket.native(); +} + +asio::error_code +AsyncTcpSocketBase::bind(const asio::ip::address& address, unsigned short port) +{ + asio::error_code errorCode; + mSocket.open(address.is_v6() ? asio::ip::tcp::v6() : asio::ip::tcp::v4(), errorCode); + if(!errorCode) + { + mSocket.set_option(asio::ip::tcp::no_delay(true), errorCode); // ?slg? do we want this? + mSocket.set_option(asio::ip::tcp::socket::reuse_address(true), errorCode); + mSocket.bind(asio::ip::tcp::endpoint(address, port), errorCode); + } + return errorCode; +} + +void +AsyncTcpSocketBase::connect(const std::string& address, unsigned short port) +{ + // Start an asynchronous resolve to translate the address + // into a list of endpoints. + resip::Data service(port); + asio::ip::tcp::resolver::query query(address, service.c_str()); + mResolver.async_resolve(query, + boost::bind(&AsyncSocketBase::handleTcpResolve, shared_from_this(), + asio::placeholders::error, + asio::placeholders::iterator)); +} + +void +AsyncTcpSocketBase::handleTcpResolve(const asio::error_code& ec, + asio::ip::tcp::resolver::iterator endpoint_iterator) +{ + if (!ec) + { + // Attempt a connection to the first endpoint in the list. Each endpoint + // will be tried until we successfully establish a connection. + //asio::ip::tcp::endpoint endpoint = *endpoint_iterator; + mSocket.async_connect(endpoint_iterator->endpoint(), + boost::bind(&AsyncSocketBase::handleConnect, shared_from_this(), + asio::placeholders::error, endpoint_iterator)); + } + else + { + onConnectFailure(ec); + } +} + +void +AsyncTcpSocketBase::handleConnect(const asio::error_code& ec, + asio::ip::tcp::resolver::iterator endpoint_iterator) +{ + if (!ec) + { + // The connection was successful. + mConnected = true; + mConnectedAddress = endpoint_iterator->endpoint().address(); + mConnectedPort = endpoint_iterator->endpoint().port(); + + onConnectSuccess(); + } + else if (++endpoint_iterator != asio::ip::tcp::resolver::iterator()) + { + // The connection failed. Try the next endpoint in the list. + asio::error_code ec; + mSocket.close(ec); + mSocket.async_connect(endpoint_iterator->endpoint(), + boost::bind(&AsyncSocketBase::handleConnect, shared_from_this(), + asio::placeholders::error, endpoint_iterator)); + } + else + { + onConnectFailure(ec); + } +} + +void +AsyncTcpSocketBase::setConnectedAddressAndPort() +{ + asio::error_code ec; + mConnectedAddress = mSocket.remote_endpoint(ec).address(); + mConnectedPort = mSocket.remote_endpoint(ec).port(); +} + +const asio::ip::address +AsyncTcpSocketBase::getSenderEndpointAddress() +{ + return mConnectedAddress; +} + +unsigned short +AsyncTcpSocketBase::getSenderEndpointPort() +{ + return mConnectedPort; +} + +void +AsyncTcpSocketBase::transportSend(const StunTuple& destination, std::vector<asio::const_buffer>& buffers) +{ + // Note: destination is ignored for TCP + asio::async_write(mSocket, buffers, + boost::bind(&AsyncTcpSocketBase::handleSend, shared_from_this(), asio::placeholders::error)); +} + +void +AsyncTcpSocketBase::transportReceive() +{ + mSocket.async_read_some(asio::buffer((void*)mReceiveBuffer->data(), RECEIVE_BUFFER_SIZE), + boost::bind(&AsyncTcpSocketBase::handleReceive, shared_from_this(), asio::placeholders::error, asio::placeholders::bytes_transferred)); +} + +void +AsyncTcpSocketBase::transportFramedReceive() +{ + asio::async_read(mSocket, asio::buffer((void*)mReceiveBuffer->data(), 4), + boost::bind(&AsyncSocketBase::handleReadHeader, shared_from_this(), asio::placeholders::error)); +} + +void +AsyncTcpSocketBase::handleReadHeader(const asio::error_code& e) +{ + if (!e) + { + /* + std::cout << "Read header from tcp socket: " << std::endl; + for(unsigned int i = 0; i < 4; i++) + { + std::cout << (char)(*mReceiveBuffer)[i] << "(" << (int)(*mReceiveBuffer)[i] << ") "; + } + std::cout << std::endl; + */ + + // Note: For both StunMessages and ChannelData messages the length in bytes 3 and 4 + UInt16 dataLen; + memcpy(&dataLen, &(*mReceiveBuffer)[2], 2); + dataLen = ntohs(dataLen); + + if(((*mReceiveBuffer)[0] & 0xC0) == 0) // If first 2 bits are 00 then this is a stun message + { + dataLen += 16; // There are 20 bytes in total in the header, and we have already read 4 - read the rest of the header + the body + } + if(dataLen+4 < RECEIVE_BUFFER_SIZE) + { + asio::async_read(mSocket, asio::buffer(&(*mReceiveBuffer)[4], dataLen), + boost::bind(&AsyncTcpSocketBase::handleReceive, shared_from_this(), asio::placeholders::error, dataLen+4)); + } + else + { + WarningLog(<< "Receive buffer (" << RECEIVE_BUFFER_SIZE << ") is not large enough to accomdate incoming framed data (" << dataLen+4 << ") closing connection."); + close(); + } + } + else if (e != asio::error::operation_aborted) + { + if(e != asio::error::eof && +#ifdef _WIN32 + e.value() != ERROR_CONNECTION_ABORTED && // This happens on Windows 7 when closing the socket +#endif + e != asio::error::connection_reset) + { + WarningLog(<< "Read header error: " << e.value() << "-" << e.message()); + } + close(); + } +} + +void +AsyncTcpSocketBase::transportClose() +{ + asio::error_code ec; + mSocket.close(ec); +} + +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/reTurn/AsyncTcpSocketBase.hxx b/src/libs/resiprocate/reTurn/AsyncTcpSocketBase.hxx new file mode 100644 index 00000000..e0893e88 --- /dev/null +++ b/src/libs/resiprocate/reTurn/AsyncTcpSocketBase.hxx @@ -0,0 +1,79 @@ +#ifndef ASYNC_TCP_SOCKET_BASE_HXX +#define ASYNC_TCP_SOCKET_BASE_HXX + +#include <asio.hpp> +#include <boost/bind.hpp> + +#include "AsyncSocketBase.hxx" + +namespace reTurn { + +class AsyncTcpSocketBase : public AsyncSocketBase +{ +public: + AsyncTcpSocketBase(asio::io_service& ioService); + virtual ~AsyncTcpSocketBase(); + + virtual unsigned int getSocketDescriptor(); + + virtual asio::error_code bind(const asio::ip::address& address, unsigned short port); + virtual void connect(const std::string& address, unsigned short port); + + virtual void transportReceive(); + virtual void transportFramedReceive(); + virtual void transportSend(const StunTuple& destination, std::vector<asio::const_buffer>& buffers); + virtual void transportClose(); + + virtual void setConnectedAddressAndPort(); // Used by server side so that get fn's will work + virtual const asio::ip::address getSenderEndpointAddress(); + virtual unsigned short getSenderEndpointPort(); + +protected: + virtual void handleReadHeader(const asio::error_code& e); + virtual void handleTcpResolve(const asio::error_code& ec, asio::ip::tcp::resolver::iterator endpoint_iterator); + virtual void handleConnect(const asio::error_code& ec, asio::ip::tcp::resolver::iterator endpoint_iterator); + + asio::ip::tcp::socket mSocket; + asio::ip::tcp::resolver mResolver; + +private: +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/AsyncTlsSocketBase.cxx b/src/libs/resiprocate/reTurn/AsyncTlsSocketBase.cxx new file mode 100644 index 00000000..b0923e71 --- /dev/null +++ b/src/libs/resiprocate/reTurn/AsyncTlsSocketBase.cxx @@ -0,0 +1,397 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#ifdef USE_SSL +#include <boost/function.hpp> +#include <boost/bind.hpp> + +#include <openssl/x509.h> +#include <openssl/x509v3.h> + +#include "AsyncTlsSocketBase.hxx" +#include "AsyncSocketBaseHandler.hxx" +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; + +namespace reTurn { + +AsyncTlsSocketBase::AsyncTlsSocketBase(asio::io_service& ioService, asio::ssl::context& context, bool validateServerCertificateHostname) + : AsyncSocketBase(ioService), + mSocket(ioService, context), + mResolver(ioService), + mValidateServerCertificateHostname(validateServerCertificateHostname) +{ +} + +AsyncTlsSocketBase::~AsyncTlsSocketBase() +{ +} + +unsigned int +AsyncTlsSocketBase::getSocketDescriptor() +{ + return mSocket.lowest_layer().native(); +} + +asio::error_code +AsyncTlsSocketBase::bind(const asio::ip::address& address, unsigned short port) +{ + asio::error_code errorCode; + mSocket.lowest_layer().open(address.is_v6() ? asio::ip::tcp::v6() : asio::ip::tcp::v4(), errorCode); + if(!errorCode) + { + mSocket.lowest_layer().set_option(asio::ip::tcp::socket::reuse_address(true), errorCode); + mSocket.lowest_layer().set_option(asio::ip::tcp::no_delay(true), errorCode); // ?slg? do we want this? + mSocket.lowest_layer().bind(asio::ip::tcp::endpoint(address, port), errorCode); + } + return errorCode; +} + +void +AsyncTlsSocketBase::connect(const std::string& address, unsigned short port) +{ + mHostname = address; + + // Start an asynchronous resolve to translate the address + // into a list of endpoints. + resip::Data service(port); + asio::ip::tcp::resolver::query query(address, service.c_str()); + mResolver.async_resolve(query, + boost::bind(&AsyncSocketBase::handleTcpResolve, shared_from_this(), + asio::placeholders::error, + asio::placeholders::iterator)); +} + +void +AsyncTlsSocketBase::handleTcpResolve(const asio::error_code& ec, + asio::ip::tcp::resolver::iterator endpoint_iterator) +{ + if (!ec) + { + // Attempt a connection to the first endpoint in the list. Each endpoint + // will be tried until we successfully establish a connection. + //asio::ip::tcp::endpoint endpoint = *endpoint_iterator; + mSocket.lowest_layer().async_connect(endpoint_iterator->endpoint(), + boost::bind(&AsyncSocketBase::handleConnect, shared_from_this(), + asio::placeholders::error, endpoint_iterator)); + } + else + { + onConnectFailure(ec); + } +} + +void +AsyncTlsSocketBase::handleConnect(const asio::error_code& ec, + asio::ip::tcp::resolver::iterator endpoint_iterator) +{ + if (!ec) + { + // The connection was successful - now do handshake. + mSocket.async_handshake(asio::ssl::stream_base::client, + boost::bind(&AsyncSocketBase::handleClientHandshake, shared_from_this(), + asio::placeholders::error, endpoint_iterator)); + } + else if (++endpoint_iterator != asio::ip::tcp::resolver::iterator()) + { + // The connection failed. Try the next endpoint in the list. + asio::error_code ec; + mSocket.lowest_layer().close(ec); + mSocket.lowest_layer().async_connect(endpoint_iterator->endpoint(), + boost::bind(&AsyncSocketBase::handleConnect, shared_from_this(), + asio::placeholders::error, endpoint_iterator)); + } + else + { + onConnectFailure(ec); + } +} + +void +AsyncTlsSocketBase::handleClientHandshake(const asio::error_code& ec, + asio::ip::tcp::resolver::iterator endpoint_iterator) +{ + if (!ec) + { + // The handshake was successful. + mConnected = true; + mConnectedAddress = endpoint_iterator->endpoint().address(); + mConnectedPort = endpoint_iterator->endpoint().port(); + + // Validate that hostname in cert matches connection hostname + if(!mValidateServerCertificateHostname || validateServerCertificateHostname()) + { + onConnectSuccess(); + } + else + { + WarningLog(<< "Hostname in certificate does not match connection hostname!"); + onConnectFailure(asio::error::operation_aborted); + } + } + else if (++endpoint_iterator != asio::ip::tcp::resolver::iterator()) + { + // The handshake failed. Try the next endpoint in the list. + asio::error_code ec; + mSocket.lowest_layer().close(ec); + mSocket.lowest_layer().async_connect(endpoint_iterator->endpoint(), + boost::bind(&AsyncSocketBase::handleConnect, shared_from_this(), + asio::placeholders::error, endpoint_iterator)); + } + else + { + onConnectFailure(ec); + } +} + +bool +AsyncTlsSocketBase::validateServerCertificateHostname() +{ + bool valid = false; + + // print session info + const SSL_CIPHER *ciph; + ciph=SSL_get_current_cipher(mSocket.impl()->ssl); + InfoLog( << "TLS session set up with " + << SSL_get_version(mSocket.impl()->ssl) << " " + << SSL_CIPHER_get_version(ciph) << " " + << SSL_CIPHER_get_name(ciph) << " " ); + + // get the certificate - should always exist since mode is set for SSL to verify the cert first + X509* cert = SSL_get_peer_certificate(mSocket.impl()->ssl); + assert(cert); + + // Look at the SubjectAltName, and if found, set as peerName + bool hostnamePresentInSubjectAltName = false; + GENERAL_NAMES* gens; + gens = (GENERAL_NAMES*)X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0); + for(int i = 0; i < sk_GENERAL_NAME_num(gens); i++) + { + GENERAL_NAME* gen = sk_GENERAL_NAME_value(gens, i); + + DebugLog(<< "subjectAltName of cert contains type <" << gen->type << ">" ); + + if (gen->type == GEN_DNS) + { + ASN1_IA5STRING* asn = gen->d.dNSName; + resip::Data dns(asn->data, asn->length); + InfoLog(<< "subjectAltName of TLS session cert contains DNS <" << dns << ">" ); + hostnamePresentInSubjectAltName = true; + if(resip::isEqualNoCase(dns, mHostname.c_str())) + { + valid = true; + break; + } + } + + if (gen->type == GEN_EMAIL) + { + DebugLog(<< "subjectAltName of cert has EMAIL type" ); + } + + if(gen->type == GEN_URI) + { + DebugLog(<< "subjectAltName of cert has URI type" ); + } + } + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + + // If there are no peer names from the subjectAltName, then use the commonName + if(!hostnamePresentInSubjectAltName) + { + // look at the Common Name to find the peerName of the cert + X509_NAME* subject = X509_get_subject_name(cert); + if(!subject) + { + ErrLog( << "Invalid certificate: subject not found "); + } + + int i =-1; + while( !valid ) + { + i = X509_NAME_get_index_by_NID(subject, NID_commonName,i); + if ( i == -1 ) + { + break; + } + assert( i != -1 ); + X509_NAME_ENTRY* entry = X509_NAME_get_entry(subject,i); + assert( entry ); + + ASN1_STRING* s = X509_NAME_ENTRY_get_data(entry); + assert( s ); + + int t = M_ASN1_STRING_type(s); + int l = M_ASN1_STRING_length(s); + unsigned char* d = M_ASN1_STRING_data(s); + resip::Data name(d,l); + DebugLog( << "got x509 string type=" << t << " len="<< l << " data=" << d ); + assert( name.size() == (unsigned)l ); + + InfoLog( << "Found common name in cert: " << name ); + if(resip::isEqualNoCase(name, mHostname.c_str())) + { + valid = true; + } + } + } + + X509_free(cert); + return valid; +} + +void +AsyncTlsSocketBase::doHandshake() +{ + mSocket.async_handshake(asio::ssl::stream_base::server, + boost::bind(&AsyncSocketBase::handleServerHandshake, shared_from_this(), asio::placeholders::error)); +} + +void +AsyncTlsSocketBase::handleServerHandshake(const asio::error_code& e) +{ + if(e) + { + onServerHandshakeFailure(e); + } + else + { + asio::error_code ec; + mConnectedAddress = mSocket.lowest_layer().remote_endpoint(ec).address(); + mConnectedPort = mSocket.lowest_layer().remote_endpoint(ec).port(); + + onServerHandshakeSuccess(); + } +} + +const asio::ip::address +AsyncTlsSocketBase::getSenderEndpointAddress() +{ + return mConnectedAddress; +} + +unsigned short +AsyncTlsSocketBase::getSenderEndpointPort() +{ + return mConnectedPort; +} + +void +AsyncTlsSocketBase::transportSend(const StunTuple& destination, std::vector<asio::const_buffer>& buffers) +{ + // Note: destination is ignored for TLS + asio::async_write(mSocket, buffers, + boost::bind(&AsyncTlsSocketBase::handleSend, shared_from_this(), asio::placeholders::error)); +} + +void +AsyncTlsSocketBase::transportReceive() +{ + mSocket.async_read_some(asio::buffer((void*)mReceiveBuffer->data(), RECEIVE_BUFFER_SIZE), + boost::bind(&AsyncTlsSocketBase::handleReceive, shared_from_this(), asio::placeholders::error, asio::placeholders::bytes_transferred)); + +} + +void +AsyncTlsSocketBase::transportFramedReceive() +{ + asio::async_read(mSocket, asio::buffer((void*)mReceiveBuffer->data(), 4), + boost::bind(&AsyncSocketBase::handleReadHeader, shared_from_this(), asio::placeholders::error)); +} + +void +AsyncTlsSocketBase::transportClose() +{ + asio::error_code ec; + //mSocket.shutdown(ec); // ?slg? Should we use async_shutdown? !slg! note: this fn gives a stack overflow since ASIO 1.0.0 for some reason + mSocket.lowest_layer().close(ec); +} + +void +AsyncTlsSocketBase::handleReadHeader(const asio::error_code& e) +{ + if (!e) + { + /* + std::cout << "Read header from tls socket: " << std::endl; + for(unsigned int i = 0; i < 4; i++) + { + std::cout << (char)(*mReceiveBuffer)[i] << "(" << (int)(*mReceiveBuffer)[i] << ") "; + } + std::cout << std::endl; + */ + + // Note: For both StunMessages and ChannelData messages the length in bytes 3 and 4 + UInt16 dataLen; + memcpy(&dataLen, &(*mReceiveBuffer)[2], 2); + dataLen = ntohs(dataLen); + + if(((*mReceiveBuffer)[0] & 0xC0) == 0) // If first 2 bits are 00 then this is a stun message + { + dataLen += 16; // There are 20 bytes in total in the header, and we have already read 4 - read the rest of the header + the body + } + + if(dataLen+4 < RECEIVE_BUFFER_SIZE) + { + asio::async_read(mSocket, asio::buffer(&(*mReceiveBuffer)[4], dataLen), + boost::bind(&AsyncTlsSocketBase::handleReceive, shared_from_this(), asio::placeholders::error, dataLen+4)); + } + else + { + WarningLog(<< "Receive buffer (" << RECEIVE_BUFFER_SIZE << ") is not large enough to accomdate incoming framed data (" << dataLen+4 << ") closing connection."); + close(); + } + } + else if (e != asio::error::operation_aborted) + { + if(e != asio::error::eof && e != asio::error::connection_reset) + { + WarningLog(<< "Read header error: " << e.value() << "-" << e.message()); + } + close(); + } +} + +} +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/reTurn/AsyncTlsSocketBase.hxx b/src/libs/resiprocate/reTurn/AsyncTlsSocketBase.hxx new file mode 100644 index 00000000..2d746159 --- /dev/null +++ b/src/libs/resiprocate/reTurn/AsyncTlsSocketBase.hxx @@ -0,0 +1,95 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#ifdef USE_SSL +#ifndef ASYNC_TLS_SOCKET_BASE_HXX +#define ASYNC_TLS_SOCKET_BASE_HXX + +#include <asio.hpp> +#include <asio/ssl.hpp> +#include <boost/bind.hpp> + +#include "AsyncSocketBase.hxx" + +namespace reTurn { + +class AsyncTlsSocketBase : public AsyncSocketBase +{ +public: + AsyncTlsSocketBase(asio::io_service& ioService, asio::ssl::context& context, bool validateServerCertificateHostname); + virtual ~AsyncTlsSocketBase(); + + virtual unsigned int getSocketDescriptor(); + + virtual asio::error_code bind(const asio::ip::address& address, unsigned short port); + virtual void connect(const std::string& address, unsigned short port); + + void doHandshake(); + + virtual void transportReceive(); + virtual void transportFramedReceive(); + virtual void transportSend(const StunTuple& destination, std::vector<asio::const_buffer>& buffers); + virtual void transportClose(); + + virtual const asio::ip::address getSenderEndpointAddress(); + virtual unsigned short getSenderEndpointPort(); + +protected: + virtual void handleReadHeader(const asio::error_code& e); + virtual void handleServerHandshake(const asio::error_code& e); + virtual void handleTcpResolve(const asio::error_code& ec, asio::ip::tcp::resolver::iterator endpoint_iterator); + virtual void handleConnect(const asio::error_code& ec, asio::ip::tcp::resolver::iterator endpoint_iterator); + virtual void handleClientHandshake(const asio::error_code& ec, asio::ip::tcp::resolver::iterator endpoint_iterator); + virtual bool validateServerCertificateHostname(); + + virtual void onServerHandshakeSuccess() { assert(false); } + virtual void onServerHandshakeFailure(const asio::error_code& e) { assert(false); } + + asio::ssl::stream<asio::ip::tcp::socket> mSocket; + asio::ip::tcp::resolver mResolver; + +private: + std::string mHostname; + bool mValidateServerCertificateHostname; +}; + +} + +#endif +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/AsyncUdpSocketBase.cxx b/src/libs/resiprocate/reTurn/AsyncUdpSocketBase.cxx new file mode 100644 index 00000000..f89ef589 --- /dev/null +++ b/src/libs/resiprocate/reTurn/AsyncUdpSocketBase.cxx @@ -0,0 +1,155 @@ +#include <boost/bind.hpp> + +#include "AsyncUdpSocketBase.hxx" +#include "AsyncSocketBaseHandler.hxx" +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; + +namespace reTurn { + +AsyncUdpSocketBase::AsyncUdpSocketBase(asio::io_service& ioService) + : AsyncSocketBase(ioService), + mSocket(ioService), + mResolver(ioService) +{ +} + +AsyncUdpSocketBase::~AsyncUdpSocketBase() +{ +} + +unsigned int +AsyncUdpSocketBase::getSocketDescriptor() +{ + return mSocket.native(); +} + +asio::error_code +AsyncUdpSocketBase::bind(const asio::ip::address& address, unsigned short port) +{ + asio::error_code errorCode; + mSocket.open(address.is_v6() ? asio::ip::udp::v6() : asio::ip::udp::v4(), errorCode); + if(!errorCode) + { + mSocket.set_option(asio::ip::udp::socket::reuse_address(true), errorCode); + mSocket.bind(asio::ip::udp::endpoint(address, port), errorCode); + } + return errorCode; +} + +void +AsyncUdpSocketBase::connect(const std::string& address, unsigned short port) +{ + // Start an asynchronous resolve to translate the address + // into a list of endpoints. + resip::Data service(port); + asio::ip::udp::resolver::query query(address, service.c_str()); + mResolver.async_resolve(query, + boost::bind(&AsyncSocketBase::handleUdpResolve, shared_from_this(), + asio::placeholders::error, + asio::placeholders::iterator)); +} + +void +AsyncUdpSocketBase::handleUdpResolve(const asio::error_code& ec, + asio::ip::udp::resolver::iterator endpoint_iterator) +{ + if (!ec) + { + // Use the first endpoint in the list. + // Nothing to do for UDP except store the connected address/port + mConnected = true; + mConnectedAddress = endpoint_iterator->endpoint().address(); + mConnectedPort = endpoint_iterator->endpoint().port(); + + onConnectSuccess(); + } + else + { + onConnectFailure(ec); + } +} + +const asio::ip::address +AsyncUdpSocketBase::getSenderEndpointAddress() +{ + return mSenderEndpoint.address(); +} + +unsigned short +AsyncUdpSocketBase::getSenderEndpointPort() +{ + return mSenderEndpoint.port(); +} + +void +AsyncUdpSocketBase::transportSend(const StunTuple& destination, std::vector<asio::const_buffer>& buffers) +{ + //InfoLog(<< "AsyncUdpSocketBase::transportSend " << buffers.size() << " buffer(s) to " << destination << " - buf1 size=" << buffer_size(buffers.front())); + mSocket.async_send_to(buffers, + asio::ip::udp::endpoint(destination.getAddress(), destination.getPort()), + boost::bind(&AsyncUdpSocketBase::handleSend, shared_from_this(), asio::placeholders::error)); +} + +void +AsyncUdpSocketBase::transportReceive() +{ + mSocket.async_receive_from(asio::buffer((void*)mReceiveBuffer->data(), RECEIVE_BUFFER_SIZE), mSenderEndpoint, + boost::bind(&AsyncUdpSocketBase::handleReceive, shared_from_this(), asio::placeholders::error, asio::placeholders::bytes_transferred)); +} + +void +AsyncUdpSocketBase::transportFramedReceive() +{ + // For UDP these two functions are the same + transportReceive(); +} + +void +AsyncUdpSocketBase::transportClose() +{ + asio::error_code ec; + mSocket.close(ec); +} + +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/reTurn/AsyncUdpSocketBase.hxx b/src/libs/resiprocate/reTurn/AsyncUdpSocketBase.hxx new file mode 100644 index 00000000..c173db05 --- /dev/null +++ b/src/libs/resiprocate/reTurn/AsyncUdpSocketBase.hxx @@ -0,0 +1,81 @@ +#ifndef ASYNC_UDP_SOCKET_BASE_HXX +#define ASYNC_UDP_SOCKET_BASE_HXX + +#include <asio.hpp> +#include <boost/bind.hpp> + +#include "AsyncSocketBase.hxx" + +namespace reTurn { + +class AsyncUdpSocketBase : public AsyncSocketBase +{ +public: + AsyncUdpSocketBase(asio::io_service& ioService); + virtual ~AsyncUdpSocketBase(); + + virtual unsigned int getSocketDescriptor(); + + virtual asio::error_code bind(const asio::ip::address& address, unsigned short port); + virtual void connect(const std::string& address, unsigned short port); + + virtual void transportReceive(); + virtual void transportFramedReceive(); + virtual void transportSend(const StunTuple& destination, std::vector<asio::const_buffer>& buffers); + virtual void transportClose(); + + virtual const asio::ip::address getSenderEndpointAddress(); + virtual unsigned short getSenderEndpointPort(); + +protected: + asio::ip::udp::socket mSocket; + asio::ip::udp::resolver mResolver; + + /// Endpoint info for current sender + asio::ip::udp::endpoint mSenderEndpoint; + + virtual void handleUdpResolve(const asio::error_code& ec, + asio::ip::udp::resolver::iterator endpoint_iterator); + +private: + +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/ChannelManager.cxx b/src/libs/resiprocate/reTurn/ChannelManager.cxx new file mode 100644 index 00000000..7e5df935 --- /dev/null +++ b/src/libs/resiprocate/reTurn/ChannelManager.cxx @@ -0,0 +1,145 @@ +#include "ChannelManager.hxx" +#include <rutil/Random.hxx> +#include <rutil/WinLeakCheck.hxx> +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN +#define TURN_CHANNEL_BINDING_LIFETIME_SECONDS 600 // 10 minuntes +//#define TURN_CHANNEL_BINDING_LIFETIME_SECONDS 60 // TESTING only + +using namespace std; + +namespace reTurn { + +ChannelManager::ChannelManager() +{ + // make starting channel number random + int randInt = resip::Random::getRandom(); + mNextChannelNumber = MIN_CHANNEL_NUM + (unsigned short)(randInt % (MAX_CHANNEL_NUM-MIN_CHANNEL_NUM+1)); +} + +ChannelManager::~ChannelManager() +{ + // Cleanup RemotePeer Memory + TupleRemotePeerMap::iterator it; + for(it = mTupleRemotePeerMap.begin(); it != mTupleRemotePeerMap.end(); it++) + { + delete it->second; + } +} + +unsigned short +ChannelManager::getNextChannelNumber() +{ + if(mNextChannelNumber == MAX_CHANNEL_NUM) + { + mNextChannelNumber = MIN_CHANNEL_NUM; + } + else + { + mNextChannelNumber++; + } + return mNextChannelNumber; +} + +RemotePeer* +ChannelManager::createChannelBinding(const StunTuple& peerTuple) +{ + return createChannelBinding(peerTuple, getNextChannelNumber()); +} + +RemotePeer* +ChannelManager::createChannelBinding(const StunTuple& peerTuple, unsigned short channel) +{ + assert(findRemotePeerByPeerAddress(peerTuple) == 0); + + // Create New RemotePeer + RemotePeer* remotePeer = new RemotePeer(peerTuple, channel, TURN_CHANNEL_BINDING_LIFETIME_SECONDS); + + // Add RemoteAddress to the appropriate maps + mTupleRemotePeerMap[peerTuple] = remotePeer; + mChannelRemotePeerMap[channel] = remotePeer; + return remotePeer; +} + +RemotePeer* +ChannelManager::findRemotePeerByChannel(unsigned short channelNumber) +{ + ChannelRemotePeerMap::iterator it = mChannelRemotePeerMap.find(channelNumber); + if(it != mChannelRemotePeerMap.end()) + { + if(!it->second->isExpired()) + { + return it->second; + } + else + { + // cleanup expired channel binding + mTupleRemotePeerMap.erase(it->second->getPeerTuple()); + delete it->second; + mChannelRemotePeerMap.erase(it); + } + } + return 0; +} + +RemotePeer* +ChannelManager::findRemotePeerByPeerAddress(const StunTuple& peerAddress) +{ + // Find RemotePeer + TupleRemotePeerMap::iterator it = mTupleRemotePeerMap.find(peerAddress); + if(it != mTupleRemotePeerMap.end()) + { + if(!it->second->isExpired()) + { + return it->second; + } + else + { + // cleanup expired channel binding + mChannelRemotePeerMap.erase(it->second->getChannel()); + delete it->second; + mTupleRemotePeerMap.erase(it); + } + } + return 0; +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/reTurn/ChannelManager.hxx b/src/libs/resiprocate/reTurn/ChannelManager.hxx new file mode 100644 index 00000000..7fff0d7d --- /dev/null +++ b/src/libs/resiprocate/reTurn/ChannelManager.hxx @@ -0,0 +1,72 @@ +#ifndef CHANNELMANAGER_HXX +#define CHANNELMANAGER_HXX + +#include <asio.hpp> + +#include "RemotePeer.hxx" + +namespace reTurn { + +#define MIN_CHANNEL_NUM 0x4000 +#define MAX_CHANNEL_NUM 0x7FFF + +class ChannelManager +{ +public: + explicit ChannelManager(); + ~ChannelManager(); + + RemotePeer* createChannelBinding(const StunTuple& peerTuple); + RemotePeer* createChannelBinding(const StunTuple& peerTuple, unsigned short channel); + + RemotePeer* findRemotePeerByChannel(unsigned short channelNumber); + RemotePeer* findRemotePeerByPeerAddress(const StunTuple& peerAddress); + +private: + typedef std::map<unsigned short,RemotePeer*> ChannelRemotePeerMap; + typedef std::map<StunTuple,RemotePeer*> TupleRemotePeerMap; + ChannelRemotePeerMap mChannelRemotePeerMap; + TupleRemotePeerMap mTupleRemotePeerMap; + + unsigned short getNextChannelNumber(); + unsigned short mNextChannelNumber; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/ConnectionManager.cxx b/src/libs/resiprocate/reTurn/ConnectionManager.cxx new file mode 100644 index 00000000..c0d8d79f --- /dev/null +++ b/src/libs/resiprocate/reTurn/ConnectionManager.cxx @@ -0,0 +1,69 @@ +#include <algorithm> +#include <boost/bind.hpp> + +#include "ConnectionManager.hxx" + +namespace reTurn { + +void +ConnectionManager::start(ConnectionPtr c) +{ + mConnections.insert(c); + c->start(); +} + +void +ConnectionManager::stop(ConnectionPtr c) +{ + mConnections.erase(c); + c->stop(); +} + +void +ConnectionManager::stopAll() +{ + std::set<ConnectionPtr>::iterator it = mConnections.begin(); + + for(; it != mConnections.end(); it++) + { + (*it)->stop(); + } + mConnections.clear(); +} + +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/ConnectionManager.hxx b/src/libs/resiprocate/reTurn/ConnectionManager.hxx new file mode 100644 index 00000000..1d1d3f5d --- /dev/null +++ b/src/libs/resiprocate/reTurn/ConnectionManager.hxx @@ -0,0 +1,67 @@ +#ifndef CONNECTION_MANAGER_HXX +#define CONNECTION_MANAGER_HXX + +#include <set> +#include <boost/noncopyable.hpp> +#include "AsyncSocketBase.hxx" + +namespace reTurn { + +/// Manages open connections so that they may be cleanly stopped when the server +/// needs to shut down. +class ConnectionManager + : private boost::noncopyable +{ +public: + /// Add the specified connection to the manager and start it. + void start(ConnectionPtr c); + + /// Stop the specified connection. + void stop(ConnectionPtr c); + + /// Stop all connections. + void stopAll(); + +private: + /// The managed connections. + std::set<ConnectionPtr> mConnections; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/DataBuffer.cxx b/src/libs/resiprocate/reTurn/DataBuffer.cxx new file mode 100644 index 00000000..d0d8f23e --- /dev/null +++ b/src/libs/resiprocate/reTurn/DataBuffer.cxx @@ -0,0 +1,102 @@ +#include "DataBuffer.hxx" +#include <memory.h> +#include <assert.h> +#include <rutil/WinLeakCheck.hxx> + +namespace reTurn { + +DataBuffer::DataBuffer(const char* data, unsigned int size) : +mBuffer(size != 0 ? new char[size] : 0), mSize(size), mStart(mBuffer) +{ + memcpy(mBuffer, data, size); +} + +DataBuffer::DataBuffer(unsigned int size) : +mBuffer(size != 0 ? new char[size] : 0), mSize(size), mStart(mBuffer) +{ +} + +DataBuffer::~DataBuffer() +{ + delete[] mBuffer; +} + +const char* +DataBuffer::data() +{ + return mStart; +} + +unsigned int +DataBuffer::size() +{ + return mSize; +} + +char& +DataBuffer::operator[](unsigned int p) +{ + assert(p < mSize); + return mBuffer[p]; +} + +char +DataBuffer::operator[](unsigned int p) const +{ + assert(p < mSize); + return mBuffer[p]; +} + +unsigned int +DataBuffer::truncate(unsigned int newSize) +{ + assert(newSize <= mSize); + mSize = newSize; + return mSize; +} + +unsigned int +DataBuffer::offset(unsigned int bytes) +{ + assert(bytes < mSize); + mStart = mStart+bytes; + mSize = mSize-bytes; + return mSize; +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/DataBuffer.hxx b/src/libs/resiprocate/reTurn/DataBuffer.hxx new file mode 100644 index 00000000..462be1b5 --- /dev/null +++ b/src/libs/resiprocate/reTurn/DataBuffer.hxx @@ -0,0 +1,64 @@ +#ifndef DATA_BUFFER_HXX +#define DATA_BUFFER_HXX + +namespace reTurn { + +class DataBuffer +{ +public: + DataBuffer(const char* data, unsigned int size); + DataBuffer(unsigned int size); + ~DataBuffer(); + + const char* data(); + unsigned int size(); + char& operator[](unsigned int p); + char operator[](unsigned int p) const; + + unsigned int truncate(unsigned int newSize); + unsigned int offset(unsigned int bytes); + +private: + char* mBuffer; + unsigned int mSize; + char* mStart; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/Makefile b/src/libs/resiprocate/reTurn/Makefile new file mode 100644 index 00000000..cd39e224 --- /dev/null +++ b/src/libs/resiprocate/reTurn/Makefile @@ -0,0 +1,68 @@ +BUILD := ../build +include $(BUILD)/Makefile.pre + +PACKAGES += ASIO RUTIL ARES OPENSSL BOOST PTHREAD +TARGET_BINARY = reTurnServer + +SRC += \ + AsyncSocketBase.cxx \ + AsyncUdpSocketBase.cxx \ + AsyncTcpSocketBase.cxx \ + AsyncTlsSocketBase.cxx \ + ChannelManager.cxx \ + ConnectionManager.cxx \ + DataBuffer.cxx \ + RemotePeer.cxx \ + RequestHandler.cxx \ + ReTurnConfig.cxx \ + ReTurnSubsystem.cxx \ + StunAuth.cxx \ + StunMessage.cxx \ + StunTuple.cxx \ + TcpConnection.cxx \ + TcpServer.cxx \ + TlsConnection.cxx \ + TlsServer.cxx \ + TurnAllocation.cxx \ + TurnAllocationKey.cxx \ + TurnManager.cxx \ + TurnPermission.cxx \ + UdpRelayServer.cxx \ + UdpServer.cxx + +include $(BUILD)/Makefile.post + + +#################################################################### +# +# Copyright (c) 2007-2008, Plantronics, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of Plantronics nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#################################################################### diff --git a/src/libs/resiprocate/reTurn/README.txt b/src/libs/resiprocate/reTurn/README.txt new file mode 100644 index 00000000..088f9947 --- /dev/null +++ b/src/libs/resiprocate/reTurn/README.txt @@ -0,0 +1,228 @@ +reTurn Status +============= + +Original Author: Scott Godin +( s g o d i n AT s i p s p e c t r u m DOT c o m ) + + +What is reTurn? +--------------- +reTurn is a Stun/Turn server and client library implementation of the latest +Stun/Turn drafts: RFC5389, and draft-ietf-behave-turn-15 + + +Current External Library Usage +------------------------------ +- currently uses ASIO, BOOST and RUTIL +- ASIO - 1.2.0 + - Used for server sockets and transports + - Tuple information used in StunMessage uses asio::ip::udp::endpoint - easily changed + - StunMessage, TurnAllocation and RequestHandler use asio::ip:address to manipulate IPV6, + and IPV4 StunAddresses - easily changed + - StunTuple uses asio::ip::address - easily changed +- BOOST - 1.34.1 + - Using BOOST in no-lib mode is fine + - BOOST::bind is used in server transports + - BOOST::crc_optimal is used for fingerprint CRC calculations + - BOOST::shared_ptr, array, enable_shared_from_this is used in server transports +- RUTIL - Data class is used in StunMessage and StunAuth for strings and TurnData, SharedPtr is also used + + +Feature Implemented Tested Notes +------------------------------------------------------------------- +Configuration Framework partially yes Currently just uses a few command line parameters and hardcoded settings +RFC3489 support yes mostly +Multi-threaded Server no no Once Turn code is implemented consider asio threading model and provide locking +TLS Server Support yes yes +RFC5389 message parsing yes partly +IPV6 message parsing support yes no +Short Term Credentials yes yes Implementation currently only accepts one hardcoded username/password +Long Term Credentials mostly yes Implementation currently only accepts one hardcoded username/password +Finger Print Insertion and Validation yes yes Uses BOOST:crc_optimal +Checking for unknown attributes yes yes +Bandwidth Check no no +Turn Allocation yes yes Only UDP Relay's are implemented +Requested Props (Even, Pair) yes yes +Turn Permissions yes yes +Turn UDP Relay yes yes +Turn TCP Relay no no +Asyncronous Client APIs yes yes +Channel Binding yes yes +Don't Fragment Attribute no no Server will reject requests asking for DF option + + +General TODO +------------- +- reduce library use - remove BOOST and/or rutil requirement - remove ASIO for client?? +- allow multiple interfaces to be used for relay +- per user allocation quota enforcement +- cleanup stun message class so that there are accessors for all data members +- from chart above + - Configuration Framework + - Multi-threaded support in Server + - Bandwidth check + - TCP Relay +- Short Term passwords do not make any sense in reTurnServer (outside of RFC3489 backcompat) - they need to be supported on client APIs + +TURN TODO's +----------- +- CreatePermission requests can contain multiple addresses - need to modify StunMessage in order to support this +- Clients need to install permissions before data can be sent - need to queue outbound data until CreateChannel response is received +- ChannelData messages must be padded to a multiple of 4 bytes, the padding is not to be reflected in the encoded length +- When client receives a Data Ind - it should ensure it is from an endpoint that it believes that it has installed a permission for, otherwise drop +- It is recommended that the client check if a permission exists towards the peer that just send a ChannelData message, if not - discard +- Could add checking that ChannelData messages always begin with bits 0b01, since bits 0b10 and 0b11 are reserved +- Need to give clients the ability to add Don't Fragment header to Allocate request +- If request with Don't Fragment fails with 420 code, then it can be retried without Don't Fragment (this will likely remain the responsibilty of the reTurn client application) +- It is recommended that the server impose limits on both the number of allocations active at one time for a given username and on the amount of bandwidth those allocations use. - 486 (Allocation Quota Exceeded) +- Port allocation algorithm should be better to ensure we won't run into collisions with other applications - port allocations should be random +- If the client receives a 400 response to a channel-bind request, then it is recommended that the allocation be deleted, and the client start again with a new allocation + +RFC53389 TODO's +--------------- +-Username must contain UTF-8 sequence of bytes, and must have been processed by SASLprep +-Realm qdtext or quoted-pair - It must UTF-8 encoded and MUST be less than 128 characters (which can be as long as 763 bytes), and must be processed by SASLprep +-Nonce qdtext or quoted-pair - MUST be less than 128 characters (which can be as long as 763 bytes) +-Software must be a UTF-8 sequence of less than 128 characters (which can be as long as 763 byes) +-The Password used in the HMAC key must be SASLprep processed +-remove quotes and trailing nulls from username, realm. remove trailing nulls from password before forming MD5 hash for message integrity +-Errorcode Reason Phrase must be a UTF-8 sequence of less than 128 characters (which can be as long as 763 byes) +-need handling for 300 Try Alternate response - currently applications responsibility +-the following values should be configurable + - Initial RTO (default 500ms) + - Rc (default 7) + - Rm (default 16) +-actual RTO should be calculated +-UDP retransmissions should stop if a hard ICMP error is seen +-DNS SRV Discovery - currently only does host record lookup (using ASIO) - _stun._udp, _stun._tcp, _stuns._tcp, _turn._udp, _turn._tcp, _turns._tcp + +Client TODO +----------- +- rework synchronous sockets to use Asynchrous sockets to unify implementation better +- keepalive usage?? +- add option to require message integrity? - depends on usage - ICE +- add ability to install a permission or binding without sending data + +Client Notes +------------ +- retries should be paced at 500ms, 1000ms, 2000ms, etc. - after 442, 443, or 444 response - currently applications responsibility +- If a client receives a 437 allocation mismatch response to an allocate, then it should retry using a different client transport address - it should do this 3 times (this will likely remain the responsibilty of the reTurn client application) +- To prevent race conditions a client MUST wait 5 mins after the channel binding expires before attempting to bind the channel number to a different transport address or the transport address to a different channel number (within the same allocation?). + + +Client API +----------- +Current Asynchronous Implementation: +- Application must provide an asio::io_service object and is responsible for threading it out and calling run +- Async Turn sockets must be held in a shared pointer, in order to ensure safety of asio callbacks - this could be abstracted better +- When Async sockets are created a callback handler class is passed in to receive callback notifications when + operations are complete + +API Set - Wrapping in a Turn(Async)Socket - Turn(Async)UdpSocket, Turn(Async)TcpSocket, Turn(Async)TlsSocket + - bound to local socket + * setUsernameAndPassword() + * requestSharedSecret() - username and password are returned + * createAllocation(lifetime, + bandwidth, + requestedPortProps, + reservationToken, + requestedTransportType) + * refreshAllocation(lifetime) + * destroyAllocation() + * getRelayTuple() - (SYNC API ONLY) used to retrieve info about the allocation + * getReflexiveTuple() - (SYNC API ONLY) used to retrieve info about the allocation + * getLifetime() - (SYNC API ONLY) used to retrieve info about the allocation + * getBandwidth() - (SYNC API ONLY) used to retrieve info about the allocation + * setActiveDestination(destinationIP, destinationPort) + * clearActiveDestination() + * bindRequest() + * send(bufferToSend, bufferSize); + * sendTo(destinationIP, destinationPort, bufferToSend, bufferSize) + * receive(bufferToReceiveIn, bufferSize[in/out], senderIPAddress, senderPort) + - last 2 args are return args - if receive is non-blocking then this data is returned in callback instead + * receiveFrom(bufferToReceiveIn, bufferSize[in/out], senderIPAddress, senderPort) + - in this case last 2 args are input and specify endpoint we want to receive from + +NOTE: could also add a binding discovery API for attempting to detect NAT type using RFC3489 methods + +Asynchronous Callbacks: + +onConnectSuccess(unsigned int socketDesc, + const asio::ip::address& address, + unsigned short port) = 0; +onConnectFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + +onSharedSecretSuccess(unsigned int socketDesc, + const char* username, + unsigned int usernameSize, + const char* password, + unsigned int passwordSize) = 0; +onSharedSecretFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + +onBindSuccess(unsigned int socketDesc, const StunTuple& reflexiveTuple) = 0; +onBindFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + +onAllocationSuccess(unsigned int socketDesc, + const StunTuple& reflexiveTuple, + const StunTuple& relayTuple, + unsigned int lifetime, + unsigned int bandwidth, + UInt64& reservationToken) = 0; +onAllocationFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + +onRefreshSuccess(unsigned int socketDesc, unsigned int lifetime) = 0; +onRefreshFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + +onSetActiveDestinationSuccess(unsigned int socketDesc) = 0; +onSetActiveDestinationFailure(unsigned int socketDesc, const asio::error_code &e) = 0; +onClearActiveDestinationSuccess(unsigned int socketDesc) = 0; +onClearActiveDestinationFailure(unsigned int socketDesc, const asio::error_code &e) = 0; + +onReceiveSuccess(unsigned int socketDesc, + const asio::ip::address& address, + unsigned short port, + const char* buffer, + unsigned int size) = 0; +onReceiveFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + +onSendSuccess(unsigned int socketDesc) = 0; +onSendFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + + +License +------- + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/ReTurnConfig.cxx b/src/libs/resiprocate/reTurn/ReTurnConfig.cxx new file mode 100644 index 00000000..ddd721c2 --- /dev/null +++ b/src/libs/resiprocate/reTurn/ReTurnConfig.cxx @@ -0,0 +1,196 @@ +#include "ReTurnConfig.hxx" + +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; +using namespace resip; + +namespace reTurn { + +ReTurnConfig::ReTurnConfig() : + mTurnPort(3478), + mTlsTurnPort(5349), + mAltStunPort(0), // Note: The default is to disable RFC3489 binding support + mTurnAddress(asio::ip::address::from_string("0.0.0.0")), + mAltStunAddress(asio::ip::address::from_string("0.0.0.0")), + mAuthenticationMode(LongTermPassword), // required for TURN + mAuthenticationRealm("reTurn"), + mNonceLifetime(3600), // 1 hour - at least 1 hours is recommended by the draft + mAllocationPortRangeMin(49152), // must be even - This default range is the Dynamic and/or Private Port range - recommended by RFC + mAllocationPortRangeMax(65535), // must be odd + mDefaultAllocationLifetime(600), // 10 minutes + mMaxAllocationLifetime(3600), // 1 hour + mMaxAllocationsPerUser(0), // 0 - no max + mTlsServerCertificateFilename("server.pem"), + mTlsTempDhFilename("dh512.pem"), + mTlsPrivateKeyPassword("password"), + mLoggingType("cout"), + mLoggingLevel("INFO"), + mLoggingFilename("reTurnServer.log"), + mLoggingFileMaxLineCount(50000), // 50000 about 5M size + mDaemonize(false), + mPidFile("") +{ + mAuthenticationCredentials["test"] = "1234"; + calcUserAuthData(); +} + +void ReTurnConfig::parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename) +{ + resip::ConfigParse::parseConfig(argc, argv, defaultConfigFilename); + + mTurnPort = getConfigUnsignedShort("TurnPort", 3478); + mTlsTurnPort = getConfigUnsignedShort("TlsTurnPort", 5349); + mAltStunPort = getConfigUnsignedShort("AltStunPort", 0); + mTurnAddress = asio::ip::address::from_string(getConfigData("TurnAddress", "0.0.0.0").c_str()); + mAltStunAddress = asio::ip::address::from_string(getConfigData("AltStunAddress", "0.0.0.0").c_str()); + int authMode = getConfigUnsignedShort("AuthenticationMode", 2); + switch(authMode) + { + case 0: mAuthenticationMode = NoAuthentication; break; + case 1: mAuthenticationMode = ShortTermPassword; break; + case 2: mAuthenticationMode = LongTermPassword; break; + default: + throw std::runtime_error("Unsupported AuthenticationMode value in config"); + } + mAuthenticationRealm = getConfigData("AuthenticationRealm", "reTurn"); + mNonceLifetime = getConfigUnsignedLong("NonceLifetime", 3600); + mAllocationPortRangeMin = getConfigUnsignedShort("AllocationPortRangeMin", 49152); + mAllocationPortRangeMax = getConfigUnsignedShort("AllocationPortRangeMax", 65535); + mDefaultAllocationLifetime = getConfigUnsignedLong("DefaultAllocationLifetime", 600); + mMaxAllocationLifetime = getConfigUnsignedLong("MaxAllocationLifetime", 3600); + mMaxAllocationsPerUser = getConfigUnsignedLong("MaxAllocationsPerUser", 0); + mTlsServerCertificateFilename = getConfigData("TlsServerCertificateFilename", "server.pem"); + mTlsTempDhFilename = getConfigData("TlsTempDhFilename", "dh512.pem"); + mTlsPrivateKeyPassword = getConfigData("TlsPrivateKeyPassword", ""); + mLoggingType = getConfigData("LoggingType", "cout"); + mLoggingLevel = getConfigData("LoggingLevel", "INFO"); + mLoggingFilename = getConfigData("LogFilename", "reTurnServer.log"); + mLoggingFileMaxLineCount = getConfigUnsignedLong("LogFileMaxLines", 50000); + mDaemonize = getConfigBool("Daemonize", false); + mPidFile = getConfigData("PidFile", ""); + + // fork is not possible on Windows +#ifdef WIN32 + if(mDaemonize) + { + throw ConfigParse::Exception("Unable to fork/daemonize on Windows, please check the config", __FILE__, __LINE__); + } +#endif + + Data user(getConfigData("LongTermAuthUsername", "")); + Data password(getConfigData("LongTermAuthPassword", "")); + + if(user.size() == 0 || password.size() == 0) + { + throw ConfigParse::Exception("Missing or invalid credentials (LongTermAuthUsername/LongTermAuthPassword", __FILE__, __LINE__); + } + + mAuthenticationCredentials[user] = password; + calcUserAuthData(); +} + +ReTurnConfig::~ReTurnConfig() +{ +} + +void +ReTurnConfig::calcUserAuthData() +{ + RealmUsers& realmUsers(mUsers[mAuthenticationRealm]); + std::map<resip::Data,resip::Data>::const_iterator it = mAuthenticationCredentials.begin(); + while(it != mAuthenticationCredentials.end()) + { + UserAuthData newUser(UserAuthData::createFromPassword( + it->first, + mAuthenticationRealm, + it->second)); + realmUsers.insert(pair<resip::Data,UserAuthData>(it->first, newUser)); + it++; + } +} + +void +ReTurnConfig::printHelpText(int argc, char **argv) +{ + std::cerr << "Command line format is:" << std::endl; + std::cerr << " " << removePath(argv[0]) << " [<ConfigFilename>] [--<ConfigValueName>=<ConfigValue>] [--<ConfigValueName>=<ConfigValue>] ..." << std::endl; + std::cerr << "Sample Command lines:" << std::endl; + std::cerr << " " << removePath(argv[0]) << " reTurnServer.config --LogLevel=INFO" << std::endl; +} + +bool +ReTurnConfig::isUserNameValid(const resip::Data& username) const +{ + std::map<resip::Data,resip::Data>::const_iterator it = mAuthenticationCredentials.find(username); + return it != mAuthenticationCredentials.end(); +} + +const Data& +ReTurnConfig::getPasswordForUsername(const Data& username) const +{ + std::map<resip::Data,resip::Data>::const_iterator it = mAuthenticationCredentials.find(username); + if(it != mAuthenticationCredentials.end()) + { + return it->second; + } + else + { + return Data::Empty; + } +} + +const UserAuthData* +ReTurnConfig::getUser(const resip::Data& userName, const resip::Data& realm) const +{ + std::map<resip::Data,RealmUsers>::const_iterator it = mUsers.find(realm); + if(it == mUsers.end()) + return NULL; + + RealmUsers realmUsers = it->second; + RealmUsers::const_iterator it2 = realmUsers.find(userName); + if(it2 == realmUsers.end()) + return NULL; + + return &(it2->second); +} + + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/ReTurnConfig.hxx b/src/libs/resiprocate/reTurn/ReTurnConfig.hxx new file mode 100644 index 00000000..5a366fc6 --- /dev/null +++ b/src/libs/resiprocate/reTurn/ReTurnConfig.hxx @@ -0,0 +1,108 @@ +#if !defined(RETURN_CONFIG_HXX) +#define RETURN_CONFIG_HXX + +#include <map> +#include <asio.hpp> +#include <rutil/ConfigParse.hxx> +#include <rutil/Data.hxx> +#include <rutil/Log.hxx> + +#include <reTurn/UserAuthData.hxx> + +namespace reTurn { + +typedef std::map<resip::Data,reTurn::UserAuthData> RealmUsers; + +class ReTurnConfig : public resip::ConfigParse +{ +public: + ReTurnConfig(); + virtual ~ReTurnConfig(); + + virtual void parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename); + + void printHelpText(int argc, char **argv); + using resip::ConfigParse::getConfigValue; + + typedef enum + { + NoAuthentication = 0, + ShortTermPassword = 1, + LongTermPassword = 2 + } AuthenticationMode; + + unsigned short mTurnPort; + unsigned short mTlsTurnPort; + unsigned short mAltStunPort; + asio::ip::address mTurnAddress; + asio::ip::address mAltStunAddress; + + AuthenticationMode mAuthenticationMode; + resip::Data mAuthenticationRealm; + std::map<resip::Data,resip::Data> mAuthenticationCredentials; + std::map<resip::Data,RealmUsers> mUsers; + unsigned long mNonceLifetime; + + unsigned short mAllocationPortRangeMin; + unsigned short mAllocationPortRangeMax; + unsigned long mDefaultAllocationLifetime; + unsigned long mMaxAllocationLifetime; + unsigned long mMaxAllocationsPerUser; // TODO - enforcement needs to be implemented + + resip::Data mTlsServerCertificateFilename; + resip::Data mTlsTempDhFilename; + resip::Data mTlsPrivateKeyPassword; + + resip::Data mLoggingType; + resip::Data mLoggingLevel; + resip::Data mLoggingFilename; + unsigned int mLoggingFileMaxLineCount; + bool mDaemonize; + resip::Data mPidFile; + + bool isUserNameValid(const resip::Data& username) const; + const resip::Data& getPasswordForUsername(const resip::Data& username) const; + const UserAuthData* getUser(const resip::Data& userName, const resip::Data& realm) const; + +protected: + void calcUserAuthData(); +}; + +} // namespace + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/ReTurnSubsystem.cxx b/src/libs/resiprocate/reTurn/ReTurnSubsystem.cxx new file mode 100644 index 00000000..a86b48af --- /dev/null +++ b/src/libs/resiprocate/reTurn/ReTurnSubsystem.cxx @@ -0,0 +1,41 @@ +#ifdef WIN32 +#include <winsock2.h> +#endif +#include "ReTurnSubsystem.hxx" + +ReTurnSubsystem ReTurnSubsystem::RETURN("RETURN"); + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/ReTurnSubsystem.hxx b/src/libs/resiprocate/reTurn/ReTurnSubsystem.hxx new file mode 100644 index 00000000..93a34a5c --- /dev/null +++ b/src/libs/resiprocate/reTurn/ReTurnSubsystem.hxx @@ -0,0 +1,54 @@ +#if !defined(RETURN_SUBSYSTEM_HXX) +#define RETURN_SUBSYSTEM_HXX + +#include <iostream> +#include <rutil/Subsystem.hxx> + +class ReTurnSubsystem : public resip::Subsystem +{ + public: + // Add new systems below + static ReTurnSubsystem RETURN; + + private: + explicit ReTurnSubsystem(const char* rhs) : resip::Subsystem(rhs) {}; + explicit ReTurnSubsystem(const resip::Data& rhs); + ReTurnSubsystem& operator=(const resip::Data& rhs); +}; + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/RemotePeer.cxx b/src/libs/resiprocate/reTurn/RemotePeer.cxx new file mode 100644 index 00000000..9eb6421e --- /dev/null +++ b/src/libs/resiprocate/reTurn/RemotePeer.cxx @@ -0,0 +1,67 @@ +#include "RemotePeer.hxx" + +using namespace std; + +namespace reTurn { + +RemotePeer::RemotePeer(const StunTuple& peerTuple, unsigned short channel, unsigned int timeoutSeconds) : + mPeerTuple(peerTuple), + mChannel(channel), + mChannelConfirmed(false), + mExpires(time(0)+timeoutSeconds), + mTimeoutSeconds(timeoutSeconds) +{ +} + +void +RemotePeer::refresh() +{ + mExpires = time(0)+mTimeoutSeconds; +} + +bool +RemotePeer::isExpired() +{ + if(time(0) > mExpires) + { + return true; + } + return false; +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/RemotePeer.hxx b/src/libs/resiprocate/reTurn/RemotePeer.hxx new file mode 100644 index 00000000..6faab98d --- /dev/null +++ b/src/libs/resiprocate/reTurn/RemotePeer.hxx @@ -0,0 +1,73 @@ +#ifndef REMOTEPEER_HXX +#define REMOTEPEER_HXX + +#include <asio.hpp> + +#include "StunTuple.hxx" + +namespace reTurn { + + +class RemotePeer +{ +public: + explicit RemotePeer(const StunTuple& peerTuple, unsigned short channel, unsigned int timeoutSeconds); + + unsigned short getChannel() const { return mChannel; } + void setChannel(unsigned short channel) { mChannel = channel; } + bool isChannelConfirmed() const { return mChannelConfirmed; } + void setChannelConfirmed() { mChannelConfirmed = true; } + + const StunTuple& getPeerTuple() const { return mPeerTuple; } + + void refresh(); + bool isExpired(); + +private: + StunTuple mPeerTuple; + + unsigned short mChannel; + bool mChannelConfirmed; + + time_t mExpires; + unsigned int mTimeoutSeconds; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/RequestHandler.cxx b/src/libs/resiprocate/reTurn/RequestHandler.cxx new file mode 100644 index 00000000..e91c337d --- /dev/null +++ b/src/libs/resiprocate/reTurn/RequestHandler.cxx @@ -0,0 +1,977 @@ +#include "RequestHandler.hxx" +#include <fstream> +#include <sstream> +#include <string> + +#include "TurnAllocation.hxx" +#include "AsyncSocketBase.hxx" +#include "StunAuth.hxx" +#include <rutil/Random.hxx> +#include <rutil/Timer.hxx> +#include <rutil/ParseBuffer.hxx> +#include <rutil/WinLeakCheck.hxx> +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; +using namespace resip; + +namespace reTurn { + +// !slg! TODO these need to be made into settings +#define SOFTWARE_STRING "reTURNServer 0.4 - RFC5389/turn-12 " // Note padding size to a multiple of 4, to help compatibility with older clients +#define DEFAULT_BANDWIDTH 100 // 100 kbit/s - enough for G711 RTP ?slg? what do we want this to be? + +RequestHandler::RequestHandler(TurnManager& turnManager, + const asio::ip::address* prim3489Address, unsigned short* prim3489Port, + const asio::ip::address* alt3489Address, unsigned short* alt3489Port) + : mTurnManager(turnManager) +{ + if(prim3489Address && prim3489Port && alt3489Address && alt3489Port) + { + mRFC3489SupportEnabled = true; + mPrim3489Address = *prim3489Address; + mPrim3489Port = *prim3489Port; + mAlt3489Address = *alt3489Address; + mAlt3489Port = *alt3489Port; + } + else + { + mRFC3489SupportEnabled = false; + } + mPrivateNonceKey = Random::getRandomHex(24); +} + +RequestHandler::ProcessResult +RequestHandler::processStunMessage(AsyncSocketBase* turnSocket, StunMessage& request, StunMessage& response, bool isRFC3489BackwardsCompatServer) +{ + ProcessResult result = RespondFromReceiving; + + response.mRemoteTuple = request.mRemoteTuple; // Default to send response back to sender + + if(handleAuthentication(request, response)) + { + // Check if there were unknown require attributes + if(request.mUnknownRequiredAttributes.numAttributes > 0) + { + InfoLog(<< "Received Request with unknown comprehension-required attributes. Sending 420."); + buildErrorResponse(response, 420, "Unknown attribute", getConfig().mAuthenticationRealm.c_str()); + response.mHasUnknownAttributes = true; + response.mUnknownAttributes = request.mUnknownRequiredAttributes; + } + else + { + // Request is authenticated, process it + switch(request.mClass) + { + case StunMessage::StunClassRequest: + switch (request.mMethod) + { + case StunMessage::BindMethod: + result = processStunBindingRequest(request, response, isRFC3489BackwardsCompatServer); + break; + + case StunMessage::SharedSecretMethod: + result = processStunSharedSecretRequest(request, response); + break; + + case StunMessage::TurnAllocateMethod: + result = processTurnAllocateRequest(turnSocket, request, response); + if(result != NoResponseToSend) + { + // Add an XOrMappedAddress to all TurnAllocateResponses + response.mHasXorMappedAddress = true; + StunMessage::setStunAtrAddressFromTuple(response.mXorMappedAddress, request.mRemoteTuple); + } + break; + + case StunMessage::TurnRefreshMethod: + result = processTurnRefreshRequest(request, response); + break; + + case StunMessage::TurnCreatePermissionMethod: + result = processTurnCreatePermissionRequest(request, response); + break; + + case StunMessage::TurnChannelBindMethod: + result = processTurnChannelBindRequest(request, response); + break; + + default: + buildErrorResponse(response, 400, "Invalid Request Method"); + break; + } + break; + + case StunMessage::StunClassIndication: + result = NoResponseToSend; // Indications don't have responses + switch (request.mMethod) + { + case StunMessage::TurnSendMethod: + processTurnSendIndication(request); + break; + + case StunMessage::BindMethod: + // A Bind indication is simply a keepalive with no response required + break; + + case StunMessage::TurnDataMethod: // Don't need to handle these - only sent by server, never received + default: + // Unknown indication - just ignore + break; + } + break; + + case StunMessage::StunClassSuccessResponse: + case StunMessage::StunClassErrorResponse: + default: + // A server should never receive a response + result = NoResponseToSend; + break; + } + } + } + + if(result != NoResponseToSend) + { + // Fill in common response properties + response.mMethod = request.mMethod; + + // Copy over TransactionId + response.mHeader.magicCookieAndTid = request.mHeader.magicCookieAndTid; + + if (1) // add Software name - could be a setting in the future + { + response.setSoftware(SOFTWARE_STRING); + } + + // If fingerprint is used in request, then use fingerprint in response + if(request.mHasFingerprint) + { + response.mHasFingerprint = true; + } + } + + return result; +} + +void +RequestHandler::buildErrorResponse(StunMessage& response, unsigned short errorCode, const char* msg, const char* realm) +{ + response.mClass = StunMessage::StunClassErrorResponse; + response.setErrorCode(errorCode, msg); + if(realm) + { + response.setRealm(realm); + + // Add a random nonce value that is expirable + Data nonce(100, Data::Preallocate); + Data timestamp(Timer::getTimeMs()/1000); + generateNonce(timestamp, nonce); + response.setNonce(nonce.c_str()); + } +} + +void +RequestHandler::generateNonce(const Data& timestamp, Data& nonce) +{ + nonce += timestamp; + nonce += ":"; + Data noncePrivate(100, Data::Preallocate); + noncePrivate += timestamp; + noncePrivate += ":"; + //noncePrivate += user; // ?slg? What could we put here + noncePrivate += mPrivateNonceKey; + nonce += noncePrivate.md5(); +} + +RequestHandler::CheckNonceResult +RequestHandler::checkNonce(const Data& nonce) +{ + ParseBuffer pb(nonce.data(), nonce.size()); + if (!pb.eof() && !isdigit(*pb.position())) + { + DebugLog(<< "Invalid nonce. Expected timestamp."); + return NotValid; + } + const char* anchor = pb.position(); + pb.skipToChar(':'); + if (pb.eof()) + { + DebugLog(<< "Invalid nonce. Expected timestamp terminator."); + return NotValid; + } + UInt64 now = Timer::getTimeMs()/1000; + Data creationTimeData; + UInt64 creationTime; + pb.data(creationTimeData, anchor); + creationTime = creationTimeData.convertUInt64(); + if((now-creationTime) <= getConfig().mNonceLifetime) + { + // If nonce hasn't expired yet - ensure this is a nonce we generated + Data nonceToMatch(100, Data::Preallocate); + generateNonce(creationTimeData, nonceToMatch); + if(nonceToMatch == nonce) + { + return Valid; + } + else + { + DebugLog(<< "Invalid nonce. Not generated by this server."); + return NotValid; + } + } + else + { + DebugLog(<< "Invalid nonce. Expired."); + return Expired; + } +} + +bool +RequestHandler::handleAuthentication(StunMessage& request, StunMessage& response) +{ + // Don't authenticate shared secret requests, Binding Requests or Indications (if LongTermCredentials are used) + if((request.mClass == StunMessage::StunClassRequest && request.mMethod == StunMessage::SharedSecretMethod) || + (request.mClass == StunMessage::StunClassRequest && request.mMethod == StunMessage::BindMethod) || + (getConfig().mAuthenticationMode == ReTurnConfig::LongTermPassword && request.mClass == StunMessage::StunClassIndication)) + { + return true; + } + + if (!request.mHasMessageIntegrity) + { + if (getConfig().mAuthenticationMode == ReTurnConfig::ShortTermPassword) + { + InfoLog(<< "Received Request with no Message Integrity. Sending 400."); + buildErrorResponse(response, 400, "Bad Request (no MessageIntegrity)"); + return false; + } + else if(getConfig().mAuthenticationMode == ReTurnConfig::LongTermPassword) + { + InfoLog(<< "Received Request with no Message Integrity. Sending 401."); + buildErrorResponse(response, 401, "Unauthorized (no MessageIntegrity)", getConfig().mAuthenticationRealm.c_str()); + return false; + } + } + else + { + if (!request.mHasUsername) + { + WarningLog(<< "No Username and contains MessageIntegrity. Sending 400."); + buildErrorResponse(response, 400, "Bad Request (no Username and contains MessageIntegrity)"); + return false; + } + + if(getConfig().mAuthenticationMode == ReTurnConfig::LongTermPassword) + { + if(!request.mHasRealm) + { + WarningLog(<< "No Realm. Sending 400."); + buildErrorResponse(response, 400, "Bad Request (No Realm)"); + return false; + } + if(!request.mHasNonce) + { + WarningLog(<< "No Nonce and contains realm. Sending 400."); + buildErrorResponse(response, 400, "Bad Request (No Nonce and contains Realm)"); + return false; + } + switch(checkNonce(*request.mNonce)) + { + case Valid: + // Do nothing + break; + case Expired: + WarningLog(<< "Nonce expired. Sending 438."); + buildErrorResponse(response, 438, "Stale Nonce", getConfig().mAuthenticationRealm.c_str()); + return false; + break; + case NotValid: + default: + WarningLog(<< "Invalid Nonce. Sending 400."); + buildErrorResponse(response, 400, "BadRequest (Invalid Nonce)"); + return false; + break; + } + } + + if(getConfig().mAuthenticationMode == ReTurnConfig::ShortTermPassword) + { + // !slg! check if username field has expired + // !slg! we may want to delay this check for Turn Allocations so that expired + // authentications can still be accepted for existing allocation refreshes + // and removals + if(0) + { + WarningLog(<< "Username expired. Sending 430."); + buildErrorResponse(response, 430, "Stale Credentials"); + return false; + } + } + + DebugLog(<< "Validating username: " << *request.mUsername); + + // !slg! need to determine whether the USERNAME contains a known entity, and in the case of a long-term + // credential, known within the realm of the REALM attribute of the request + if (getConfig().mAuthenticationMode == ReTurnConfig::LongTermPassword && !getConfig().isUserNameValid(*request.mUsername)) + { + WarningLog(<< "Invalid username: " << *request.mUsername << ". Sending 401."); + buildErrorResponse(response, 401, "Unathorized", getConfig().mAuthenticationMode == ReTurnConfig::LongTermPassword ? getConfig().mAuthenticationRealm.c_str() : 0); + return false; + } + + DebugLog(<< "Validating MessageIntegrity"); + + // Need to calculate HMAC across entire message - for ShortTermAuthentication we use the password + // as the key - for LongTermAuthentication we use username:realm:password string as the key + Data hmacKey; + assert(request.mHasUsername); + + if(getConfig().mAuthenticationMode != ReTurnConfig::NoAuthentication) + { + request.calculateHmacKey(hmacKey, getConfig().getPasswordForUsername(*request.mUsername)); + } + + if(!request.checkMessageIntegrity(hmacKey)) + { + WarningLog(<< "MessageIntegrity is bad. Sending 401."); + buildErrorResponse(response, 401, "Unauthorized", getConfig().mAuthenticationMode == ReTurnConfig::LongTermPassword ? getConfig().mAuthenticationRealm.c_str() : 0); + return false; + } + + // need to compute this later after message is filled in + response.mHasMessageIntegrity = true; + response.mHmacKey = hmacKey; // Used to later calculate Message Integrity during encoding + } + + return true; +} + +RequestHandler::ProcessResult +RequestHandler::processStunBindingRequest(StunMessage& request, StunMessage& response, bool isRFC3489BackwardsCompatServer) +{ + ProcessResult result = RespondFromReceiving; + + // form the outgoing message + response.mClass = StunMessage::StunClassSuccessResponse; + + // Add XOrMappedAddress to response if RFC5389 sender + if(request.hasMagicCookie()) + { + response.mHasXorMappedAddress = true; + StunMessage::setStunAtrAddressFromTuple(response.mXorMappedAddress, request.mRemoteTuple); + } + else + { + // Add Mapped address to response + response.mHasMappedAddress = true; + StunMessage::setStunAtrAddressFromTuple(response.mMappedAddress, request.mRemoteTuple); + + if(0) // TODO - setting to add XOR address even if older client + { + response.mHasXorMappedAddress = true; + StunMessage::setStunAtrAddressFromTuple(response.mXorMappedAddress, request.mRemoteTuple); + } + } + + // the following code is for RFC3489 backward compatibility + if(mRFC3489SupportEnabled && isRFC3489BackwardsCompatServer) + { + StunTuple sendFromTuple; + StunTuple changeTuple; + + sendFromTuple.setTransportType(request.mLocalTuple.getTransportType()); + changeTuple.setTransportType(request.mLocalTuple.getTransportType()); + changeTuple.setAddress(request.mLocalTuple.getAddress() == mPrim3489Address ? mAlt3489Address : mPrim3489Address); + changeTuple.setPort(request.mLocalTuple.getPort() == mPrim3489Port ? mAlt3489Port : mPrim3489Port); + UInt32 changeRequest = request.mHasChangeRequest ? request.mChangeRequest : 0; + + if(changeRequest & StunMessage::ChangeIpFlag && changeRequest & StunMessage::ChangePortFlag) + { + result = RespondFromAlternateIpPort; + sendFromTuple.setAddress(changeTuple.getAddress()); + sendFromTuple.setPort(changeTuple.getPort()); + } + else if(changeRequest & StunMessage::ChangePortFlag) + { + result = RespondFromAlternatePort; + sendFromTuple.setAddress(request.mLocalTuple.getAddress()); + sendFromTuple.setPort(changeTuple.getPort()); + } + else if(changeRequest & StunMessage::ChangeIpFlag) + { + result = RespondFromAlternateIp; + sendFromTuple.setAddress(changeTuple.getAddress()); + sendFromTuple.setPort(request.mLocalTuple.getPort()); + } + else + { + // default to send from receiving transport + sendFromTuple.setAddress(request.mLocalTuple.getAddress()); + sendFromTuple.setPort(request.mLocalTuple.getPort()); + } + + // Add source address - for RFC3489 backwards compatibility + response.mHasSourceAddress = true; + StunMessage::setStunAtrAddressFromTuple(response.mSourceAddress, sendFromTuple); + + // Add changed address - for RFC3489 backward compatibility + response.mHasChangedAddress = true; + StunMessage::setStunAtrAddressFromTuple(response.mChangedAddress, changeTuple); + + // If Response-Address is present, then response should be sent here instead of source address to be + // compliant with RFC3489. In this case we need to add a REFLECTED-FROM attribute + if(request.mHasResponseAddress) + { + StunMessage::setTupleFromStunAtrAddress(response.mRemoteTuple, request.mResponseAddress); + + // If the username is present and is greater than or equal to 92 bytes long, then we assume this username + // was obtained from a shared secret request + if (request.mHasUsername && (request.mUsername->size() >= 92 ) ) + { + // Extract source address that sent the shared secret request from the encoded username and use this in response address + StunTuple responseTuple; + request.getTupleFromUsername(responseTuple); + + response.mHasReflectedFrom = true; + StunMessage::setStunAtrAddressFromTuple(response.mReflectedFrom, responseTuple); + } + else + { + response.mHasReflectedFrom = true; + StunMessage::setStunAtrAddressFromTuple(response.mReflectedFrom, request.mRemoteTuple); + } + } + } + + return result; +} + +RequestHandler::ProcessResult +RequestHandler::processStunSharedSecretRequest(StunMessage& request, StunMessage& response) +{ + // Only allow shared secret requests on TLS transport + if(request.mLocalTuple.getTransportType() != StunTuple::TLS) + { + WarningLog(<< "Invalid transport for shared secret request. TLS required. Sending 433."); + buildErrorResponse(response, 433, "Invalid transport. TLS required."); + return RespondFromReceiving; + } + + // form the outgoing success response + response.mClass = StunMessage::StunClassSuccessResponse; + + // Set the username and password + response.createUsernameAndPassword(); + + return RespondFromReceiving; +} + +RequestHandler::ProcessResult +RequestHandler::processTurnAllocateRequest(AsyncSocketBase* turnSocket, StunMessage& request, StunMessage& response) +{ + // Turn Allocate requests must be authenticated (note: if this attribute is present + // then handleAuthentication would have validated authentication info) + if(!request.mHasMessageIntegrity) + { + WarningLog(<< "Turn allocate request without authentication. Sending 401."); + buildErrorResponse(response, 401, "Missing Message Integrity", getConfig().mAuthenticationMode == ReTurnConfig::LongTermPassword ? getConfig().mAuthenticationRealm.c_str() : 0 ); + return RespondFromReceiving; + } + + Data hmacKey; + assert(request.mHasUsername); + request.calculateHmacKey(hmacKey, getConfig().getPasswordForUsername(*request.mUsername)); + + DebugLog(<< "Allocation request received: localTuple=" << request.mLocalTuple << ", remoteTuple=" << request.mRemoteTuple); + + TurnAllocation* allocation = mTurnManager.findTurnAllocation(TurnAllocationKey(request.mLocalTuple, request.mRemoteTuple)); + + // If this is a subsequent allocation request, return error + if(allocation) + { + WarningLog(<< "Allocation requested but already exists. Sending 437."); + buildErrorResponse(response, 437, "Allocation Mismatch"); + return RespondFromReceiving; + } + + // TODO - add a check that a per-user quota for number of allowed TurnAllocations + // has not been exceeded - if so send 486 (Allocation Quota Reached) + + // Build the Allocation Tuple + StunTuple allocationTuple(request.mLocalTuple.getTransportType(), // Default to receiving transport + request.mLocalTuple.getAddress(), // default ip address is at the discretion of the server + 0); // port to be populated later + + // Check for requested properties + if(request.mHasTurnRequestedTransport) + { + if(request.mTurnRequestedTransport != StunMessage::RequestedTransportUdp) // We only support UDP allocations right now + { + WarningLog(<< "Invalid transport requested. Sending 442."); + buildErrorResponse(response, 442, "Unsupported Transport Protocol"); + return RespondFromReceiving; + } + allocationTuple.setTransportType(StunTuple::UDP); + } + else + { + WarningLog(<< "Missing requested transport header. Sending 400."); + buildErrorResponse(response, 400, "Bad Request - Missing requested transport"); + return RespondFromReceiving; + } + + // Check if Don't Fragment attribute is present - if so return an error - TODO implement DF bit, then remove this check + if(request.mHasTurnDontFragment) + { + WarningLog(<< "Turn allocate request with Don't Fragment requested, not yet implemented. Sending 420."); + buildErrorResponse(response, 420, "Don't Fragment not yet implemented", getConfig().mAuthenticationMode == ReTurnConfig::LongTermPassword ? getConfig().mAuthenticationRealm.c_str() : 0 ); + return RespondFromReceiving; + } + + // Check if bandwidth is available + if(request.mHasTurnBandwidth) + { + // TODO - bandwidth check - if insufficient send 507 (Insufficient Bandwidth Capacity) + } + + unsigned short port = 0; // Default to Any free port + if(request.mHasTurnEvenPort) + { + if(request.mHasTurnReservationToken) + { + WarningLog(<< "Both Even Port and Reservation Token attributes are present. Sending 400."); + buildErrorResponse(response, 400, "Bad request - both Even Port and Reservation Token present"); + return RespondFromReceiving; + } + if(request.mTurnEvenPort.propType == StunMessage::PropsPortEven) + { + // Attempt to allocate an even port + port = mTurnManager.allocateEvenPort(allocationTuple.getTransportType()); + } + else if(request.mTurnEvenPort.propType == StunMessage::PropsPortPair) + { + // Attempt to allocate an even port, with a free adjacent odd port + port = mTurnManager.allocateEvenPortPair(allocationTuple.getTransportType()); + + // Add Reservation Token to response - for now just use reserved port number as token + response.mHasTurnReservationToken = true; + response.mTurnReservationToken = port + 1; + } + if(port == 0) + { + WarningLog(<< "Unable to allocate requested port. Sending 508."); + buildErrorResponse(response, 508, "Insufficient Port Capacity"); + return RespondFromReceiving; + } + } + + if(request.mHasTurnReservationToken) + { + // Try to allocate reserved port - for now reservation token is reserved port number + port = (unsigned short)request.mTurnReservationToken; + if(!mTurnManager.allocatePort(allocationTuple.getTransportType(), port, true /* allocate reserved */)) + { + WarningLog(<< "Unable to allocate requested port - bad reservation token. Sending 508."); + buildErrorResponse(response, 508, "Insufficient Port Capacity"); + return RespondFromReceiving; + } + } + + if(port == 0) + { + // Allocate any available port + port = mTurnManager.allocateAnyPort(allocationTuple.getTransportType()); + if(port == 0) + { + WarningLog(<< "Unable to allocate port. Sending 508."); + buildErrorResponse(response, 508, "Insufficient Port Capacity"); + return RespondFromReceiving; + } + } + + allocationTuple.setPort(port); + + UInt32 lifetime = getConfig().mDefaultAllocationLifetime; + if(request.mHasTurnLifetime) + { + // Check if the requested value is greater than the server max + if(request.mTurnLifetime > getConfig().mMaxAllocationLifetime) + { + lifetime = getConfig().mMaxAllocationLifetime; + } + // The server should ignore requests for a lifetime less than it's default + else if(request.mTurnLifetime > getConfig().mDefaultAllocationLifetime) + { + lifetime = request.mTurnLifetime; + } + } + + // We now have an internal 5-Tuple and an allocation tuple - create the allocation + + try + { + allocation = new TurnAllocation(mTurnManager, + turnSocket, + request.mLocalTuple, + request.mRemoteTuple, + StunAuth(*request.mUsername, hmacKey), + allocationTuple, + lifetime); + } + catch(asio::system_error e) + { + // TODO - handle port in use error better - try to allocate a new port or something? + ErrLog(<< "Error allocating socket for allocation. Sending 500."); + buildErrorResponse(response, 500, "Server Error"); + return RespondFromReceiving; + } + + // Add the new allocation to be managed + mTurnManager.addTurnAllocation(allocation); + + // form the outgoing success response + response.mClass = StunMessage::StunClassSuccessResponse; + + response.mHasTurnLifetime = true; + response.mTurnLifetime = lifetime; + + response.mHasTurnXorRelayedAddress = true; + StunMessage::setStunAtrAddressFromTuple(response.mTurnXorRelayedAddress, allocation->getRequestedTuple()); + + // Note: XorMappedAddress is added to all TurnAllocate responses in processStunMessage + + //Reserved for future draft + //response.mHasTurnBandwidth = true; + //response.mTurnBandwidth = request.mHasTurnBandwidth ? request.mTurnBandwidth : DEFAULT_BANDWIDTH; + + // Note: Message Integrity added by handleAuthentication + + return RespondFromReceiving; +} + +RequestHandler::ProcessResult +RequestHandler::processTurnRefreshRequest(StunMessage& request, StunMessage& response) +{ + // Turn Allocate requests must be authenticated (note: if this attribute is present + // then handleAuthentication would have validation authentication info) + if(!request.mHasMessageIntegrity) + { + WarningLog(<< "Turn refresh request without authentication. Sending 401."); + buildErrorResponse(response, 401, "Missing Message Integrity", getConfig().mAuthenticationMode == ReTurnConfig::LongTermPassword ? getConfig().mAuthenticationRealm.c_str() : 0 ); + return RespondFromReceiving; + } + + Data hmacKey; + assert(request.mHasUsername); + request.calculateHmacKey(hmacKey, getConfig().getPasswordForUsername(*request.mUsername)); + + TurnAllocation* allocation = mTurnManager.findTurnAllocation(TurnAllocationKey(request.mLocalTuple, request.mRemoteTuple)); + + if(!allocation) + { + WarningLog(<< "Refresh requested with non-matching allocation. Sending 437."); + buildErrorResponse(response, 437, "Allocation Mismatch"); + return RespondFromReceiving; + } + + // If allocation was found, then ensure that the same username and shared secret was used + if(allocation->getClientAuth().getClientUsername() != *request.mUsername) + { + WarningLog(<< "Refresh requested with username not matching allocation. Sending 441."); + buildErrorResponse(response, 441, "Wrong Credentials"); + return RespondFromReceiving; + } + if(allocation->getClientAuth().getClientSharedSecret() != hmacKey) + { + WarningLog(<< "Refresh requested with shared secret not matching allocation. Sending 441."); + buildErrorResponse(response, 441, "Wrong Credentials"); + return RespondFromReceiving; + } + + // check if Lifetime is 0, if so then just send success response + if(request.mHasTurnLifetime && request.mTurnLifetime == 0) + { + // form the outgoing success response + response.mClass = StunMessage::StunClassSuccessResponse; + + response.mHasTurnLifetime = true; + response.mTurnLifetime = 0; + + // If allocation exists then delete it + if(allocation) + { + mTurnManager.removeTurnAllocation(allocation->getKey()); // will delete allocation + } + + return RespondFromReceiving; + } + + UInt32 lifetime = getConfig().mDefaultAllocationLifetime; + if(request.mHasTurnLifetime) + { + // Check if the requested value is greater than the server max + if(request.mTurnLifetime > getConfig().mMaxAllocationLifetime) + { + lifetime = getConfig().mMaxAllocationLifetime; + } + // The server should ignore requests for a lifetime less than it's default + else if(request.mTurnLifetime > getConfig().mDefaultAllocationLifetime) + { + lifetime = request.mTurnLifetime; + } + } + + // Check if this is a subsequent allocate request + allocation->refresh(lifetime); + + // form the outgoing success response + response.mClass = StunMessage::StunClassSuccessResponse; + + response.mHasTurnLifetime = true; + response.mTurnLifetime = lifetime; + + //Reserved for future draft + //response.mHasTurnBandwidth = true; + //response.mTurnBandwidth = request.mHasTurnBandwidth ? request.mTurnBandwidth : DEFAULT_BANDWIDTH; + + // Note: Message Integrity added by handleAuthentication + + return RespondFromReceiving; +} + +RequestHandler::ProcessResult +RequestHandler::processTurnCreatePermissionRequest(StunMessage& request, StunMessage& response) +{ + // TurnCreatePermission requests must be authenticated + if(!request.mHasMessageIntegrity) + { + WarningLog(<< "Turn create permission request without authentication. Send 401."); + buildErrorResponse(response, 401, "Missing Message Integrity", getConfig().mAuthenticationMode == ReTurnConfig::LongTermPassword ? getConfig().mAuthenticationRealm.c_str() : 0 ); + return RespondFromReceiving; + } + + Data hmacKey; + assert(request.mHasUsername); + request.calculateHmacKey(hmacKey, getConfig().getPasswordForUsername(*request.mUsername)); + + TurnAllocation* allocation = mTurnManager.findTurnAllocation(TurnAllocationKey(request.mLocalTuple, request.mRemoteTuple)); + + if(!allocation) + { + WarningLog(<< "Turn create permission request for non-existing allocation. Send 437."); + buildErrorResponse(response, 437, "No Allocation"); + return RespondFromReceiving; + } + + // If allocation was found, then ensure that the same username and shared secret was used + if(allocation->getClientAuth().getClientUsername() != *request.mUsername) + { + WarningLog(<< "Create permission requested with username not matching allocation. Sending 441."); + buildErrorResponse(response, 441, "Wrong Credentials"); + return RespondFromReceiving; + } + if(allocation->getClientAuth().getClientSharedSecret() != hmacKey) + { + WarningLog(<< "Create permission requested with shared secret not matching allocation. Sending 441."); + buildErrorResponse(response, 441, "Wrong Credentials"); + return RespondFromReceiving; + } + + if(request.mCntTurnXorPeerAddress > 0) + { + StunTuple remoteAddress; + remoteAddress.setTransportType(allocation->getRequestedTuple().getTransportType()); + for (int i = 0; i < request.mCntTurnXorPeerAddress; i++) + { + StunMessage::setTupleFromStunAtrAddress(remoteAddress, request.mTurnXorPeerAddress[i]); + allocation->refreshPermission(remoteAddress.getAddress()); + } + } + else + { + WarningLog(<< "Create permission request missing peer address. Sending 400."); + buildErrorResponse(response, 400, "Bad Request - missing attribute"); + return RespondFromReceiving; + } + + // form the outgoing success response + response.mClass = StunMessage::StunClassSuccessResponse; + + // Note: Message Integrity added by handleAuthentication + + return RespondFromReceiving; +} + +RequestHandler::ProcessResult +RequestHandler::processTurnChannelBindRequest(StunMessage& request, StunMessage& response) +{ + // TurnChannelBind requests must be authenticated + if(!request.mHasMessageIntegrity) + { + WarningLog(<< "Turn channel bind request without authentication. Send 401."); + buildErrorResponse(response, 401, "Missing Message Integrity", getConfig().mAuthenticationMode == ReTurnConfig::LongTermPassword ? getConfig().mAuthenticationRealm.c_str() : 0 ); + return RespondFromReceiving; + } + + Data hmacKey; + assert(request.mHasUsername); + request.calculateHmacKey(hmacKey, getConfig().getPasswordForUsername(*request.mUsername)); + + TurnAllocation* allocation = mTurnManager.findTurnAllocation(TurnAllocationKey(request.mLocalTuple, request.mRemoteTuple)); + + if(!allocation) + { + WarningLog(<< "Turn channel bind request for non-existing allocation. Send 437."); + buildErrorResponse(response, 437, "No Allocation"); + return RespondFromReceiving; + } + + // If allocation was found, then ensure that the same username and shared secret was used + if(allocation->getClientAuth().getClientUsername() != *request.mUsername) + { + WarningLog(<< "Channel bind requested with username not matching allocation. Sending 441."); + buildErrorResponse(response, 441, "Wrong Credentials"); + return RespondFromReceiving; + } + if(allocation->getClientAuth().getClientSharedSecret() != hmacKey) + { + WarningLog(<< "Channel bind requested with shared secret not matching allocation. Sending 441."); + buildErrorResponse(response, 441, "Wrong Credentials"); + return RespondFromReceiving; + } + + if(request.mCntTurnXorPeerAddress > 0 && request.mHasTurnChannelNumber) + { + // Ensure channel number is in valid range + if(request.mTurnChannelNumber < MIN_CHANNEL_NUM || request.mTurnChannelNumber > MAX_CHANNEL_NUM) + { + WarningLog(<< "Channel bind requested with an out of range channel number=" << request.mTurnChannelNumber << ". Sending 400."); + buildErrorResponse(response, 400, "Bad Request - channel number out of range"); + return RespondFromReceiving; + } + + StunTuple remoteAddress; + remoteAddress.setTransportType(allocation->getRequestedTuple().getTransportType()); + // Shouldn't have more than one xor-peer-address attribute in this request + StunMessage::setTupleFromStunAtrAddress(remoteAddress, request.mTurnXorPeerAddress[0]); + + if(!allocation->addChannelBinding(remoteAddress, request.mTurnChannelNumber)) + { + WarningLog(<< "Channel bind request invalid. Sending 400."); + buildErrorResponse(response, 400, "Bad Request"); + return RespondFromReceiving; + } + } + else + { + WarningLog(<< "Channel bind request missing peer address and/or channel number. Sending 400."); + buildErrorResponse(response, 400, "Bad Request - missing attribute"); + return RespondFromReceiving; + } + + // form the outgoing success response + response.mClass = StunMessage::StunClassSuccessResponse; + + // Add the channel number to make the clients job easier + //response.mHasTurnChannelNumber = true; + //response.mTurnChannelNumber = request.mTurnChannelNumber; + + // Note: Message Integrity added by handleAuthentication + + return RespondFromReceiving; +} + +void +RequestHandler::processTurnSendIndication(StunMessage& request) +{ + TurnAllocation* allocation = mTurnManager.findTurnAllocation(TurnAllocationKey(request.mLocalTuple, request.mRemoteTuple)); + + if(!allocation) + { + WarningLog(<< "Turn send indication for non-existing allocation. Dropping."); + return; + } + + if(request.mCntTurnXorPeerAddress == 0 || !request.mHasTurnData) + { + WarningLog(<< "Turn send indication with no peer address or data. Dropping."); + return; + } + + // Check if Don't Fragment attribute is present - if so drop - TODO implement DF bit, then remove this check + if(request.mHasTurnDontFragment) + { + WarningLog(<< "Turn send indication with Don't Fragment requested, not yet implemented. Dropping."); + return; + } + + StunTuple remoteAddress; + remoteAddress.setTransportType(allocation->getRequestedTuple().getTransportType()); + // Shouldn't have more than one xor-peer-address attribute in this request + StunMessage::setTupleFromStunAtrAddress(remoteAddress, request.mTurnXorPeerAddress[0]); + + // Check if permission exists, if not then drop + if(!allocation->existsPermission(remoteAddress.getAddress())) + { + WarningLog(<< "Turn send indication for destination=" << remoteAddress << ", but no permission installed. Dropping."); + return; + } + + boost::shared_ptr<DataBuffer> data(new DataBuffer(request.mTurnData->data(), request.mTurnData->size())); + allocation->sendDataToPeer(remoteAddress, data, false /* isFramed? */); +} + +void +RequestHandler::processTurnData(unsigned short channelNumber, const StunTuple& localTuple, const StunTuple& remoteTuple, boost::shared_ptr<DataBuffer>& data) +{ + TurnAllocation* allocation = mTurnManager.findTurnAllocation(TurnAllocationKey(localTuple, remoteTuple)); + + if(!allocation) + { + WarningLog(<< "Turn data for non existing allocation. Dropping."); + return; + } + + allocation->sendDataToPeer(channelNumber, data, true /* isFramed? */); +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/RequestHandler.hxx b/src/libs/resiprocate/reTurn/RequestHandler.hxx new file mode 100644 index 00000000..25b24f6b --- /dev/null +++ b/src/libs/resiprocate/reTurn/RequestHandler.hxx @@ -0,0 +1,111 @@ +#ifndef REQUEST_HANDLER_HXX +#define REQUEST_HANDLER_HXX + +#include <string> +#include <boost/noncopyable.hpp> + +#include "DataBuffer.hxx" +#include "StunMessage.hxx" +#include "TurnManager.hxx" + +namespace reTurn { + +class AsyncSocketBase; + +/// The common handler for all incoming requests. +class RequestHandler + : private boost::noncopyable +{ +public: + explicit RequestHandler(TurnManager& turnManager, + const asio::ip::address* prim3489Address = 0, unsigned short* prim3489Port = 0, + const asio::ip::address* alt3489Address = 0, unsigned short* alt3489Port = 0); + + typedef enum + { + NoResponseToSend, + RespondFromReceiving, + RespondFromAlternatePort, + RespondFromAlternateIp, + RespondFromAlternateIpPort + } ProcessResult; + + /// Process a received StunMessage, and produce a reply + /// Returns true if the response message is to be sent + ProcessResult processStunMessage(AsyncSocketBase* turnSocket, StunMessage& request, StunMessage& response, bool isRFC3489BackwardsCompatServer=false); + void processTurnData(unsigned short channelNumber, const StunTuple& localTuple, const StunTuple& remoteTuple, boost::shared_ptr<DataBuffer>& data); + + const ReTurnConfig& getConfig() { return mTurnManager.getConfig(); } + +private: + + TurnManager& mTurnManager; + + // RFC3489 Server List + bool mRFC3489SupportEnabled; + asio::ip::address mPrim3489Address; + unsigned short mPrim3489Port; + asio::ip::address mAlt3489Address; + unsigned short mAlt3489Port; + + resip::Data mPrivateNonceKey; + + // Authentication handler + bool handleAuthentication(StunMessage& request, StunMessage& response); + + // Specific request processors + ProcessResult processStunBindingRequest(StunMessage& request, StunMessage& response, bool isRFC3489BackwardsCompatServer); + ProcessResult processStunSharedSecretRequest(StunMessage& request, StunMessage& response); + ProcessResult processTurnAllocateRequest(AsyncSocketBase* turnSocket, StunMessage& request, StunMessage& response); + ProcessResult processTurnRefreshRequest(StunMessage& request, StunMessage& response); + ProcessResult processTurnCreatePermissionRequest(StunMessage& request, StunMessage& response); + ProcessResult processTurnChannelBindRequest(StunMessage& request, StunMessage& response); + + // Specific Indication processors + void processTurnSendIndication(StunMessage& request); + + // Utility methods + void buildErrorResponse(StunMessage& response, unsigned short errorCode, const char* msg, const char* realm = 0); + void generateNonce(const resip::Data& timestamp, resip::Data& nonce); + enum CheckNonceResult { Valid, NotValid, Expired }; + CheckNonceResult checkNonce(const resip::Data& nonce); +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/StunAuth.cxx b/src/libs/resiprocate/reTurn/StunAuth.cxx new file mode 100644 index 00000000..732234ca --- /dev/null +++ b/src/libs/resiprocate/reTurn/StunAuth.cxx @@ -0,0 +1,50 @@ +#include "StunAuth.hxx" + +using namespace std; +using namespace resip; + +namespace reTurn { + +StunAuth::StunAuth(const Data& clientUsername, + const Data& clientSharedSecret) : + mClientUsername(clientUsername), + mClientSharedSecret(clientSharedSecret) +{ +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/StunAuth.hxx b/src/libs/resiprocate/reTurn/StunAuth.hxx new file mode 100644 index 00000000..fba8de8c --- /dev/null +++ b/src/libs/resiprocate/reTurn/StunAuth.hxx @@ -0,0 +1,59 @@ +#ifndef STUNAUTH_HXX +#define STUNAUTH_HXX + +#include <rutil/Data.hxx> + +namespace reTurn { + +class StunAuth +{ +public: + explicit StunAuth(const resip::Data& clientUsername, + const resip::Data& clientSharedSecret); + + const resip::Data& getClientUsername() const { return mClientUsername; } + const resip::Data& getClientSharedSecret() const { return mClientSharedSecret; } + +private: + resip::Data mClientUsername; + resip::Data mClientSharedSecret; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/StunMessage.cxx b/src/libs/resiprocate/reTurn/StunMessage.cxx new file mode 100644 index 00000000..750cee3f --- /dev/null +++ b/src/libs/resiprocate/reTurn/StunMessage.cxx @@ -0,0 +1,1775 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "StunMessage.hxx" + +#include <rutil/Timer.hxx> +#include <rutil/Random.hxx> +#include <rutil/DataStream.hxx> +#include <rutil/MD5Stream.hxx> +#include <boost/crc.hpp> +#include <rutil/WinLeakCheck.hxx> +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +#ifdef USE_SSL +#include <openssl/hmac.h> +#endif + +using namespace std; +using namespace resip; + +// What should we set these to? Used for short term password generation. +static const Data USERNAME_KEY("stunServerUsernameKey"); +static const Data PASSWORD_KEY("stunServerPasswordKey"); + +#define MAX_USERNAME_BYTES 512 +#define MAX_PASSWORD_BYTES 512 +#define MAX_REALM_BYTES 763 +#define MAX_NONCE_BYTES 763 +#define MAX_SOFTWARE_BYTES 763 +#define MAX_ERRORCODE_REASON_BYTES 763 + +#define STUN_CRC_FINAL_XOR 0x5354554e + +namespace reTurn { + +bool operator<(const UInt128& lhs, const UInt128& rhs) +{ + if(lhs.longpart[0] != rhs.longpart[0]) + { + return lhs.longpart[0] < rhs.longpart[0]; + } + else if(lhs.longpart[1] != rhs.longpart[1]) + { + return lhs.longpart[1] < rhs.longpart[1]; + } + else if(lhs.longpart[2] != rhs.longpart[2]) + { + return lhs.longpart[2] < rhs.longpart[2]; + } + + return lhs.longpart[3] < rhs.longpart[3]; +} + +bool operator==(const UInt128& lhs, const UInt128& rhs) +{ + return lhs.longpart[0] == rhs.longpart[0] && + lhs.longpart[1] == rhs.longpart[1] && + lhs.longpart[2] == rhs.longpart[2] && + lhs.longpart[3] == rhs.longpart[3]; +} + +StunMessage::StunMessage(const StunTuple& localTuple, + const StunTuple& remoteTuple, + char* buf, unsigned int bufLen) : + mLocalTuple(localTuple), + mRemoteTuple(remoteTuple), + mBuffer(buf, bufLen) // !slg! copies buffer from Socket buffer assuming for now that StunMessages will persist past one request/response transaction + // could make this more efficient by having the transports allocate buffer dynamically and pass ownership over +{ + init(); + mIsValid = stunParseMessage(buf, bufLen); + + if(mIsValid) + { + DebugLog(<< "Successfully parsed StunMessage: " << mHeader); + } +} + +StunMessage::StunMessage() : + mIsValid(true) +{ + init(); +} + +StunMessage::StunMessage(const StunMessage& from) +{ + *this = from; +} + +StunMessage& +StunMessage::operator=(const StunMessage& rhs) +{ + if (this != &rhs) + { + assert(false); + } + + return *this; +} + +StunMessage::~StunMessage() +{ + if(mErrorCode.reason) delete mErrorCode.reason; + if(mUsername) delete mUsername; + if(mPassword) delete mPassword; + if(mRealm) delete mRealm; + if(mNonce) delete mNonce; + if(mSoftware) delete mSoftware; + if(mTurnData) delete mTurnData; +} + +void +StunMessage::init() +{ + mHasMappedAddress = false; + mHasResponseAddress = false; + mHasChangeRequest = false; + mHasSourceAddress = false; + mHasChangedAddress = false; + mHasUsername = false; + mHasNonce = false; + mHasRealm = false; + mHasPassword = false; + mHasMessageIntegrity = false; + mHasErrorCode = false; + mHasUnknownAttributes = false; + mHasReflectedFrom = false; + mHasXorMappedAddress = false; + mHasFingerprint = false; + mHasSoftware = false; + mHasAlternateServer = false; + mHasSecondaryAddress = false; + mHasTurnChannelNumber = false; + mHasTurnLifetime = false; + mHasTurnBandwidth = false; + mHasTurnData = false; + mHasTurnXorRelayedAddress = false; + mHasTurnEvenPort = false; + mHasTurnRequestedTransport = false; + mHasTurnDontFragment = false; + mHasTurnReservationToken = false; + mHasTurnConnectStat = false; + mCntTurnXorPeerAddress = 0; + mErrorCode.reason = 0; + mUsername = 0; + mPassword = 0; + mRealm = 0; + mNonce = 0; + mSoftware = 0; + mTurnData = 0; + mMessageIntegrityMsgLength = 0; + mUnknownRequiredAttributes.numAttributes = 0; +} + +void +StunMessage::createHeader(UInt16 stunclass, UInt16 method) +{ + mClass = stunclass; + mMethod = method; + + // Assign a tid + mHeader.id.magicCookie = htonl(StunMagicCookie); + Data random = Random::getCryptoRandom(12); + memcpy(&mHeader.id.tid, random.data(), sizeof(mHeader.id.tid)); +} + +void +StunMessage::setErrorCode(unsigned short errorCode, const char* reason) +{ + assert(errorCode >= 100 && errorCode <= 699); + mHasErrorCode = true; + mErrorCode.errorClass = errorCode / 100; + mErrorCode.number = errorCode % 100; + if(mErrorCode.reason) + { + *mErrorCode.reason = reason; + } + else + { + mErrorCode.reason = new Data(reason); + } +} + +void +StunMessage::setUsername(const char* username) +{ + mHasUsername = true; + if(mUsername) + { + *mUsername = username; + } + else + { + mUsername = new Data(username); + } +} + +void +StunMessage::setPassword(const char* password) +{ + mHasPassword = true; + if(mPassword) + { + *mPassword = password; + } + else + { + mPassword = new Data(password); + } +} + +void +StunMessage::setRealm(const char* realm) +{ + mHasRealm = true; + if(mRealm) + { + *mRealm = realm; + } + else + { + mRealm = new Data(realm); + } +} + +void +StunMessage::setNonce(const char* nonce) +{ + mHasNonce = true; + if(mNonce) + { + *mNonce = nonce; + } + else + { + mNonce = new Data(nonce); + } +} + +void +StunMessage::setSoftware(const char* software) +{ + mHasSoftware = true; + if(mSoftware) + { + *mSoftware = software; + } + else + { + mSoftware = new Data(software); + } +} + +void +StunMessage::setTurnData(const char* data, unsigned int len) +{ + mHasTurnData = true; + if(mTurnData) + { + mTurnData->clear(); + mTurnData->append(data, len); + } + else + { + mTurnData = new Data(data, len); + } +} + +void +StunMessage::applyXorToAddress(const StunAtrAddress& in, StunAtrAddress& out) +{ + if(&in != &out) memcpy(&out, &in, sizeof(out)); + + out.port = out.port^(StunMessage::StunMagicCookie>>16); // Xor with most significate 16 bits of magic cookie + if(out.family == IPv6Family) + { + for(int i = 0; i < 4; i++) + { + // Note: MagicCookieAndTid are stored in network byte order + out.addr.ipv6.longpart[i] = out.addr.ipv6.longpart[i]^mHeader.magicCookieAndTid.longpart[i]; + } + } + else + { + out.addr.ipv4 = out.addr.ipv4^StunMessage::StunMagicCookie; + } +} + +void +StunMessage::setStunAtrAddressFromTuple(StunAtrAddress& address, const StunTuple& tuple) +{ + address.port = tuple.getPort(); + if(tuple.getAddress().is_v6()) + { + // Note: addr.ipv6 is stored in network byte order + address.family = StunMessage::IPv6Family; + memcpy(&address.addr.ipv6, tuple.getAddress().to_v6().to_bytes().c_array(), sizeof(address.addr.ipv6)); + } + else + { + // Note: addr.ipv4 is stored in host byte order + address.family = StunMessage::IPv4Family; + address.addr.ipv4 = tuple.getAddress().to_v4().to_ulong(); + } +} + +void +StunMessage::setTupleFromStunAtrAddress(StunTuple& tuple, const StunAtrAddress& address) +{ + tuple.setPort(address.port); + if(address.family == StunMessage::IPv6Family) + { + // Note: addr.ipv6 is stored in network byte order + asio::ip::address_v6::bytes_type bytes; + memcpy(bytes.c_array(), &address.addr.ipv6, bytes.size()); + asio::ip::address_v6 addr(bytes); + tuple.setAddress(addr); + } + else + { + // Note: addr.ipv4 is stored in host byte order + asio::ip::address_v4 addr(address.addr.ipv4); + tuple.setAddress(addr); + } +} + +bool +StunMessage::stunParseAtrXorAddress( char* body, unsigned int hdrLen, StunAtrAddress& result ) +{ + bool ret = stunParseAtrAddress(body, hdrLen, result); + if(ret) + { + applyXorToAddress(result, result); + } + return ret; +} + +bool +StunMessage::stunParseAtrAddress( char* body, unsigned int hdrLen, StunAtrAddress& result ) +{ + if ( hdrLen != 8 /* ipv4 size */ && hdrLen != 20 /* ipv6 size */ ) + { + WarningLog(<< "hdrLen wrong for Address"); + return false; + } + body++; // Skip pad + result.family = *body++; + + UInt16 nport; + memcpy(&nport, body, 2); body+=2; + result.port = ntohs(nport); + + if (result.family == IPv4Family) + { + UInt32 naddr; + memcpy(&naddr, body, sizeof(UInt32)); body+=sizeof(UInt32); + result.addr.ipv4 = ntohl(naddr); + // Note: addr.ipv4 is stored in host byte order + return true; + } + else if (result.family == IPv6Family) + { + memcpy(&result.addr.ipv6, body, sizeof(result.addr.ipv6)); body+=sizeof(result.addr.ipv6); + // Note: addr.ipv6 is stored in host byte order + return true; + } + else + { + WarningLog(<< "bad address family: " << result.family); + } + + return false; +} + +bool +StunMessage::stunParseAtrEvenPort( char* body, unsigned int hdrLen, TurnAtrEvenPort& result ) +{ + if ( hdrLen != 1 ) + { + WarningLog(<< "hdrLen wrong for EvenPort"); + return false; + } + result.propType = *body & 0x80; // copy first 8 bits into propType - but only look at highest order + + return true; +} + +bool +StunMessage::stunParseAtrUInt32( char* body, unsigned int hdrLen, UInt32& result ) +{ + if ( hdrLen != 4 ) + { + WarningLog(<< "hdrLen wrong for UInt32 attribute"); + return false; + } + else + { + memcpy(&result, body, 4); + result = ntohl(result); + return true; + } +} + +bool +StunMessage::stunParseAtrUInt64( char* body, unsigned int hdrLen, UInt64& result ) +{ + if ( hdrLen != 8 ) + { + WarningLog(<< "hdrLen wrong for UInt64 attribute"); + return false; + } + else + { + memcpy(&result, body, 8); + return true; + } +} + +bool +StunMessage::stunParseAtrError( char* body, unsigned int hdrLen, StunAtrError& result ) +{ + body+=2; // skip pad + result.errorClass = *body++ & 0x7; + result.number = *body++; + + int reasonLen = (hdrLen -4) > MAX_ERRORCODE_REASON_BYTES ? MAX_ERRORCODE_REASON_BYTES : hdrLen-4; + result.reason = new resip::Data(resip::Data::Share, body, reasonLen); + return true; +} + +bool +StunMessage::stunParseAtrUnknown( char* body, unsigned int hdrLen, StunAtrUnknown& result ) +{ + if ( hdrLen >= sizeof(result) ) + { + WarningLog(<< "hdrLen wrong for Unknown attribute or too many unknown attributes present"); + return false; + } + else + { + if (hdrLen % 2 != 0) return false; + result.numAttributes = hdrLen / 2; + for (int i=0; i<result.numAttributes; i++) + { + memcpy(&result.attrType[i], body, 2); body+=2; + result.attrType[i] = ntohs(result.attrType[i]); + } + return true; + } +} + +bool +StunMessage::stunParseAtrIntegrity( char* body, unsigned int hdrLen, StunAtrIntegrity& result ) +{ + if ( hdrLen != 20) + { + WarningLog(<< "hdrLen wrong for message integrity"); + return false; + } + else + { + memcpy(&result.hash, body, hdrLen); + return true; + } +} + + + +bool +StunMessage::stunParseMessage( char* buf, unsigned int bufLen) +{ + DebugLog(<< "Received stun message: " << bufLen << " bytes"); + + if (sizeof(StunMsgHdr) > bufLen) + { + WarningLog(<< "Bad message, bufLen=" << bufLen); + return false; + } + + memcpy(&mHeader, buf, sizeof(StunMsgHdr)); + mHeader.msgType = ntohs(mHeader.msgType); + mHeader.msgLength = ntohs(mHeader.msgLength); + + if (mHeader.msgLength + sizeof(StunMsgHdr) != bufLen) + { + WarningLog(<< "Message header length (" << mHeader.msgLength << ") + header size (" << sizeof(StunMsgHdr) << ") doesn't match message size (" << bufLen << ")"); + return false; + } + + // Check if class and method are valid + mClass = mHeader.msgType & 0x0110; + mMethod = mHeader.msgType & 0x000F; + + // Look for stun magic cookie + mHasMagicCookie = mHeader.id.magicCookie == htonl(StunMagicCookie); + if(!mHasMagicCookie) + { + StackLog(<< "stun magic cookie not found."); + } + + char* body = buf + sizeof(StunMsgHdr); + unsigned int size = mHeader.msgLength; + mUnknownRequiredAttributes.numAttributes = 0; + + StackLog(<< "bytes after header = " << size); + + while ( size > 0 ) + { + // !jf! should check that there are enough bytes left in the buffer + + StunAtrHdr* attr = reinterpret_cast<StunAtrHdr*>(body); + + unsigned int attrLen = ntohs(attr->length); + // attrLen may not be on 4 byte boundary, in which case we need to pad to 4 bytes when advancing to next attribute + unsigned int attrLenPad = attrLen % 4 == 0 ? 0 : 4 - (attrLen % 4); + int atrType = ntohs(attr->type); + + StackLog(<< "Found attribute type=" << atrType << " length=" << attrLen); + if ( attrLen+attrLenPad+4 > size ) + { + WarningLog(<< "claims attribute is larger than size of message " <<"(attribute type="<<atrType<<")"); + return false; + } + + body += 4; // skip the length and type in attribute header + size -= 4; + + switch ( atrType ) + { + case MappedAddress: + if(!mHasMappedAddress) + { + mHasMappedAddress = true; + if ( stunParseAtrAddress( body, attrLen, mMappedAddress )== false ) + { + WarningLog(<< "problem parsing MappedAddress"); + return false; + } + StackLog(<< "MappedAddress = " << mMappedAddress); + } + else + { + WarningLog(<< "Duplicate MappedAddress in message - ignoring."); + } + break; + + case ResponseAddress: // deprecated + if(!mHasResponseAddress) + { + mHasResponseAddress = true; + if ( stunParseAtrAddress( body, attrLen, mResponseAddress )== false ) + { + WarningLog(<< "problem parsing ResponseAddress"); + return false; + } + StackLog(<< "ResponseAddress = " << mResponseAddress); + } + else + { + WarningLog(<< "Duplicate ResponseAddress in message - ignoring."); + } + break; + + case ChangeRequest: // deprecated + if(!mHasChangeRequest) + { + mHasChangeRequest = true; + if (stunParseAtrUInt32( body, attrLen, mChangeRequest) == false) + { + WarningLog(<< "problem parsing ChangeRequest"); + return false; + } + StackLog(<< "ChangeRequest = " << mChangeRequest); + } + else + { + WarningLog(<< "Duplicate ChangeRequest in message - ignoring."); + } + break; + + case SourceAddress: // deprecated + if(!mHasSourceAddress) + { + mHasSourceAddress = true; + if ( stunParseAtrAddress( body, attrLen, mSourceAddress )== false ) + { + WarningLog(<< "problem parsing SourceAddress"); + return false; + } + StackLog(<< "SourceAddress = " << mSourceAddress); + } + else + { + WarningLog(<< "Duplicate SourceAddress in message - ignoring."); + } + break; + + case ChangedAddress: // deprecated + if(!mHasChangedAddress) + { + mHasChangedAddress = true; + if ( stunParseAtrAddress( body, attrLen, mChangedAddress )== false ) + { + WarningLog(<< "problem parsing ChangedAddress"); + return false; + } + StackLog(<< "ChangedAddress = " << mChangedAddress); + } + else + { + WarningLog(<< "Duplicate ChangedAddress in message - ignoring."); + } + break; + + case Username: + if(!mHasUsername) + { + if(attrLen > MAX_USERNAME_BYTES) + { + WarningLog(<< "Username length=" << attrLen << " is longer than max allowed=" << MAX_USERNAME_BYTES); + return false; + } + mHasUsername = true; + mUsername = new resip::Data(resip::Data::Share, body, attrLen); + StackLog(<< "Username = " << *mUsername); + } + else + { + WarningLog(<< "Duplicate Username in message - ignoring."); + } + break; + + case Password: + if(!mHasPassword) + { + if(attrLen > MAX_PASSWORD_BYTES) + { + WarningLog(<< "Password length=" << attrLen << " is longer than max allowed=" << MAX_PASSWORD_BYTES); + return false; + } + mHasPassword = true; + mPassword = new resip::Data(resip::Data::Share, body, attrLen); + StackLog(<< "Password = " << *mPassword); + } + else + { + WarningLog(<< "Duplicate Password in message - ignoring."); + } + break; + + case MessageIntegrity: + if(!mHasMessageIntegrity) + { + mHasMessageIntegrity = true; + if (stunParseAtrIntegrity( body, attrLen, mMessageIntegrity) == false) + { + WarningLog(<< "problem parsing MessageIntegrity"); + return false; + } + //StackLog(<< "MessageIntegrity = " << mMessageIntegrity.hash); + mMessageIntegrityMsgLength = body + attrLen - buf - sizeof(StunMsgHdr); + } + else + { + WarningLog(<< "Duplicate MessageIntegrity in message - ignoring."); + } + break; + + case ErrorCode: + if(!mHasErrorCode) + { + if(attrLen-4 > MAX_ERRORCODE_REASON_BYTES) + { + WarningLog(<< "ErrorCode reason length=" << attrLen-4 << " is longer than max allowed=" << MAX_ERRORCODE_REASON_BYTES); + return false; + } + mHasErrorCode = true; + if (stunParseAtrError(body, attrLen, mErrorCode) == false) + { + WarningLog(<< "problem parsing ErrorCode"); + return false; + } + StackLog(<< "ErrorCode = " << (int(mErrorCode.errorClass) * 100 + int(mErrorCode.number)) + << " (" << *mErrorCode.reason << ")"); + } + else + { + WarningLog(<< "Duplicate ErrorCode in message - ignoring."); + } + break; + + case UnknownAttribute: + if(!mHasUnknownAttributes) + { + mHasUnknownAttributes = true; + if (stunParseAtrUnknown(body, attrLen, mUnknownAttributes) == false) + { + WarningLog(<< "problem parsing UnknownAttribute"); + return false; + } + // TODO output + } + else + { + WarningLog(<< "Duplicate UnknownAttribute in message - ignoring."); + } + break; + + case ReflectedFrom: // deprecated + if(!mHasReflectedFrom) + { + mHasReflectedFrom = true; + if ( stunParseAtrAddress( body, attrLen, mReflectedFrom ) == false ) + { + WarningLog(<< "problem parsing ReflectedFrom"); + return false; + } + StackLog(<< "ReflectedFrom = " << mReflectedFrom); + } + else + { + WarningLog(<< "Duplicate ReflectedFrom in message - ignoring."); + } + break; + + case Realm: + if(!mHasRealm) + { + if(attrLen > MAX_REALM_BYTES) + { + WarningLog(<< "Realm length=" << attrLen << " is longer than max allowed=" << MAX_REALM_BYTES); + return false; + } + mHasRealm = true; + mRealm = new resip::Data(resip::Data::Share, body, attrLen); + StackLog(<< "Realm = " << *mRealm); + } + else + { + WarningLog(<< "Duplicate Realm in message - ignoring."); + } + break; + + case Nonce: + if(!mHasNonce) + { + if(attrLen > MAX_NONCE_BYTES) + { + WarningLog(<< "Nonce length=" << attrLen << " is longer than max allowed=" << MAX_NONCE_BYTES); + return false; + } + mHasNonce = true; + mNonce = new resip::Data(resip::Data::Share, body, attrLen); + StackLog(<< "Nonce = " << *mNonce); + } + else + { + WarningLog(<< "Duplicate Nonce in message - ignoring."); + } + break; + + case XorMappedAddress_old: + case XorMappedAddress: + if(!mHasXorMappedAddress) + { + mHasXorMappedAddress = true; + if ( stunParseAtrXorAddress( body, attrLen, mXorMappedAddress ) == false ) + { + WarningLog(<< "problem parsing XorMappedAddress"); + return false; + } + StackLog(<< "XorMappedAddress = " << mXorMappedAddress); + } + else + { + WarningLog(<< "Duplicate XorMappedAddress in message - ignoring."); + } + break; + + case Fingerprint: + if(!mHasFingerprint) + { + mHasFingerprint = true; + if (stunParseAtrUInt32( body, attrLen, mFingerprint) == false) + { + WarningLog(<< "problem parsing Fingerprint"); + return false; + } + StackLog(<< "Fingerprint = " << mFingerprint); + } + else + { + WarningLog(<< "Duplicate Fingerprint in message - ignoring."); + } + break; + + case Software: + if(!mHasSoftware) + { + if(attrLen > MAX_SOFTWARE_BYTES) + { + WarningLog(<< "Software length=" << attrLen << " is longer than max allowed=" << MAX_SOFTWARE_BYTES); + return false; + } + mHasSoftware = true; + mSoftware = new resip::Data(resip::Data::Share, body, attrLen); + StackLog(<< "Software = " << *mSoftware); + } + else + { + WarningLog(<< "Duplicate Software in message - ignoring."); + } + break; + + case AlternateServer: + if(!mHasAlternateServer) + { + mHasAlternateServer = true; + if ( stunParseAtrAddress( body, attrLen, mAlternateServer ) == false ) + { + WarningLog(<< "problem parsing AlternateServer"); + return false; + } + StackLog(<< "AlternateServer = " << mAlternateServer); + } + else + { + WarningLog(<< "Duplicate AlternateServer in message - ignoring."); + } + break; + + case SecondaryAddress: + if(!mHasSecondaryAddress) + { + mHasSecondaryAddress = true; + if ( stunParseAtrAddress( body, attrLen, mSecondaryAddress ) == false ) + { + WarningLog(<< "problem parsing secondaryAddress"); + return false; + } + StackLog(<< "SecondaryAddress = " << mSecondaryAddress); + } + else + { + WarningLog(<< "Duplicate SecondaryAddress in message - ignoring."); + } + break; + + // TURN attributes + + case TurnChannelNumber: + if(!mHasTurnChannelNumber) + { + UInt32 channelNumber; + mHasTurnChannelNumber = true; + if(stunParseAtrUInt32( body, attrLen, channelNumber) == false) + { + WarningLog(<< "problem parsing channel number"); + return false; + } + mTurnChannelNumber = (channelNumber & 0xFFFF0000) >> 16; + StackLog(<< "Turn ChannelNumber = " << mTurnChannelNumber); + } + else + { + WarningLog(<< "Duplicate TurnChannelNumber in message - ignoring."); + } + break; + + case TurnLifetime: + if(!mHasTurnLifetime) + { + mHasTurnLifetime = true; + if (stunParseAtrUInt32( body, attrLen, mTurnLifetime) == false) + { + WarningLog(<< "problem parsing turn lifetime"); + return false; + } + StackLog(<< "Turn Lifetime = " << mTurnLifetime); + } + else + { + WarningLog(<< "Duplicate TurnLifetime in message - ignoring."); + } + break; + + case TurnBandwidth: + if(!mHasTurnBandwidth) + { + mHasTurnBandwidth = true; + if (stunParseAtrUInt32( body, attrLen, mTurnBandwidth) == false) + { + WarningLog(<< "problem parsing turn bandwidth"); + return false; + } + StackLog(<< "Turn Bandwidth = " << mTurnBandwidth); + } + else + { + WarningLog(<< "Duplicate TurnBandwidth in message - ignoring."); + } + break; + + case TurnXorPeerAddress: + if(mCntTurnXorPeerAddress < TURN_MAX_XOR_PEER_ADDR) + { + if ( stunParseAtrXorAddress( body, attrLen, mTurnXorPeerAddress[mCntTurnXorPeerAddress]) == false ) + { + WarningLog(<< "problem parsing turn peer address"); + return false; + } + StackLog(<< "Turn Peer Address = " << mTurnXorPeerAddress[mCntTurnXorPeerAddress]); + mCntTurnXorPeerAddress++; + } + else + { + WarningLog(<< "Duplicate TurnXorPeerAddress in message - ignoring."); + } + break; + + //overlay on parse, ownership is buffer parsed from + case TurnData: + if(!mHasTurnData) + { + mHasTurnData = true; + mTurnData = new resip::Data(resip::Data::Share, body, attrLen); + } + else + { + WarningLog(<< "Duplicate TurnData in message - ignoring."); + } + break; + + case TurnXorRelayedAddress: + if(!mHasTurnXorRelayedAddress) + { + mHasTurnXorRelayedAddress = true; + if ( stunParseAtrXorAddress( body, attrLen, mTurnXorRelayedAddress ) == false ) + { + WarningLog(<< "problem parsing turn relay address"); + return false; + } + StackLog(<< "Turn Relayed Address = " << mTurnXorRelayedAddress); + } + else + { + WarningLog(<< "Duplicate TurnXorRelayedAddress in message - ignoring."); + } + break; + + case TurnEvenPort: + if(!mHasTurnEvenPort) + { + mHasTurnEvenPort = true; + if (stunParseAtrEvenPort( body, attrLen, mTurnEvenPort) == false) + { + WarningLog(<< "problem parsing turn even port"); + return false; + } + StackLog(<< "Turn Even Port = " << (int)mTurnEvenPort.propType); + } + else + { + WarningLog(<< "Duplicate TurnEvenPort in message - ignoring."); + } + break; + + case TurnRequestedTransport: + if(!mHasTurnRequestedTransport) + { + mHasTurnRequestedTransport = true; + UInt32 requestedTransport; + if (stunParseAtrUInt32( body, attrLen, requestedTransport) == false) + { + WarningLog(<< "problem parsing turn requested transport"); + return false; + } + mTurnRequestedTransport = requestedTransport >> 24; + StackLog(<< "Turn Requested Transport = " << (int)mTurnRequestedTransport); + } + else + { + WarningLog(<< "Duplicate TurnRequestedTransport in message - ignoring."); + } + break; + + case TurnDontFragment: + if(!mHasTurnDontFragment) + { + mHasTurnDontFragment = true; + if(attrLen != 0) + { + WarningLog(<< "invalid attribute length for DontFragment attribute"); + return false; + } + StackLog(<< "Turn DontFragement = <exists>"); + } + else + { + WarningLog(<< "Duplicate TurnDontFragment in message - ignoring."); + } + break; + + case TurnReservationToken: + if(!mHasTurnReservationToken) + { + mHasTurnReservationToken = true; + if ( stunParseAtrUInt64( body, attrLen, mTurnReservationToken ) == false ) + { + WarningLog(<< "problem parsing turn reservation token"); + return false; + } + StackLog(<< "Turn Reservation Token = " << mTurnReservationToken); + } + else + { + WarningLog(<< "Duplicate TurnReservationToken in message - ignoring."); + } + break; + + case TurnConnectStat: + if(!mHasTurnConnectStat) + { + mHasTurnConnectStat = true; + if (stunParseAtrUInt32( body, attrLen, mTurnConnectStat) == false) + { + WarningLog(<< "problem parsing turn connect stat"); + return false; + } + StackLog(<< "Turn Connect Stat = " << mTurnConnectStat); + } + else + { + WarningLog(<< "Duplicate TurnConnectStat in message - ignoring."); + } + break; + + default: + if ( atrType <= 0x7FFF ) + { + if(mUnknownRequiredAttributes.numAttributes < STUN_MAX_UNKNOWN_ATTRIBUTES) + { + mUnknownRequiredAttributes.attrType[mUnknownRequiredAttributes.numAttributes++] = atrType; + } + WarningLog(<< "Unknown comprehension required attribute: " << atrType); + } + else + { + InfoLog(<< "Ignoring unknown comprehension optional attribute: " << atrType); + } + } + + body += attrLen+attrLenPad; + size -= attrLen+attrLenPad; + } + + return true; +} + +EncodeStream& +operator<< ( EncodeStream& strm, const UInt128& r ) +{ + strm << int(r.longpart[0]); + for ( int i=1; i<4; i++ ) + { + strm << ':' << int(r.longpart[i]); + } + + return strm; +} + +EncodeStream& +operator<<( EncodeStream& strm, const StunMessage::StunAtrAddress& addr) +{ + if(addr.family == StunMessage::IPv6Family) + { + asio::ip::address_v6::bytes_type bytes; + memcpy(bytes.c_array(), &addr.addr.ipv6, bytes.size()); + asio::ip::address_v6 addrv6(bytes); + + strm << "[" << addrv6.to_string() << "]:" << addr.port; + } + else + { + UInt32 ip = addr.addr.ipv4; + strm << ((int)(ip>>24)&0xFF) << "."; + strm << ((int)(ip>>16)&0xFF) << "."; + strm << ((int)(ip>> 8)&0xFF) << "."; + strm << ((int)(ip>> 0)&0xFF) ; + + strm << ":" << addr.port; + } + + return strm; +} + +EncodeStream& +operator<<(EncodeStream& os, const StunMessage::StunMsgHdr& h) +{ + os << "STUN "; + bool outputMethod=true; + + switch(h.msgType & 0x0110) + { + case StunMessage::StunClassRequest: + os << "Request: "; + break; + case StunMessage::StunClassIndication: + os << "Indication: "; + outputMethod = false; + switch (h.msgType & 0x000F) + { + case StunMessage::TurnSendMethod: + os << "Send"; + break; + case StunMessage::TurnDataMethod: + os << "Data"; + break; + default: + os << "Unknown ind method (" << int(h.msgType & 0x000F) << ")"; + break; + } + break; + case StunMessage::StunClassSuccessResponse: + os << "Success Response: "; + break; + case StunMessage::StunClassErrorResponse: + os << "Error Response: "; + break; + default: + os << "Unknown class (" << int(h.msgType & 0x0110) << "): "; + } + + if(outputMethod) + { + switch (h.msgType & 0x000F) + { + case StunMessage::BindMethod: + os << "Bind"; + break; + case StunMessage::SharedSecretMethod: + os << "SharedSecret"; + break; + case StunMessage::TurnAllocateMethod: + os << "Allocate"; + break; + case StunMessage::TurnRefreshMethod: + os << "Refresh"; + break; + case StunMessage::TurnCreatePermissionMethod: + os << "CreatePermission"; + break; + case StunMessage::TurnChannelBindMethod: + os << "ChannelBind"; + break; + default: + os << "Unknown method (" << int(h.msgType & 0x000F) << ")"; + break; + } + } + + os << ", id "; + + os << std::hex; + for (unsigned int i = 0; i < 4; i++) { + os << static_cast<int>(h.magicCookieAndTid.longpart[i]); + } + os << std::dec; + + return os; +} + +char* +StunMessage::encode16(char* buf, UInt16 data) +{ + UInt16 ndata = htons(data); + memcpy(buf, reinterpret_cast<void*>(&ndata), sizeof(UInt16)); + return buf + sizeof(UInt16); +} + +char* +StunMessage::encode32(char* buf, UInt32 data) +{ + UInt32 ndata = htonl(data); + memcpy(buf, reinterpret_cast<void*>(&ndata), sizeof(UInt32)); + return buf + sizeof(UInt32); +} + +char* +StunMessage::encode(char* buf, const char* data, unsigned int length) +{ + memcpy(buf, data, length); + return buf + length; +} + +char* +StunMessage::encodeTurnData(char *ptr, const resip::Data* td) +{ + UInt16 padsize = (UInt16)td->size() % 4 == 0 ? 0 : 4 - ((UInt16)td->size() % 4); + + ptr = encode16(ptr, TurnData); + ptr = encode16(ptr, (UInt16)td->size()); + memcpy(ptr, td->data(), td->size()); + ptr += td->size(); + memset(ptr, 0, padsize); // zero out padded data (note: this is not required by the RFC) + return ptr+padsize; +} + +char* +StunMessage::encodeAtrUInt32(char* ptr, UInt16 type, UInt32 value) +{ + ptr = encode16(ptr, type); + ptr = encode16(ptr, 4); + ptr = encode32(ptr, value); + return ptr; +} + +char* +StunMessage::encodeAtrUInt64(char* ptr, UInt16 type, UInt64 value) +{ + ptr = encode16(ptr, type); + ptr = encode16(ptr, 8); + memcpy(ptr, reinterpret_cast<void*>(&value), sizeof(UInt64)); + return ptr + sizeof(UInt64); +} + +char* +StunMessage::encodeAtrXorAddress(char* ptr, UInt16 type, const StunAtrAddress& atr) +{ + StunAtrAddress xorAtr; + applyXorToAddress(atr, xorAtr); + return encodeAtrAddress(ptr, type, xorAtr); +} + +char* +StunMessage::encodeAtrAddress(char* ptr, UInt16 type, const StunAtrAddress& atr) +{ + ptr = encode16(ptr, type); + ptr = encode16(ptr, atr.family == IPv6Family ? 20 : 8); + *ptr++ = (UInt8)0; // pad + *ptr++ = atr.family; + ptr = encode16(ptr, atr.port); + if(atr.family == IPv6Family) + { + // Note: addr.ipv6 is stored in network byte order + memcpy(ptr, &atr.addr.ipv6, sizeof(atr.addr.ipv6)); + ptr += sizeof(atr.addr.ipv6); + } + else + { + // Note: addr.ipv4 is stored in host byte order - encode32 will conver to network byte order + ptr = encode32(ptr, atr.addr.ipv4); + } + + return ptr; +} + +char* +StunMessage::encodeAtrError(char* ptr, const StunAtrError& atr) +{ + assert(atr.reason); + UInt16 padsize = (unsigned int)atr.reason->size() % 4 == 0 ? 0 : 4 - ((unsigned int)atr.reason->size() % 4); + + ptr = encode16(ptr, ErrorCode); + ptr = encode16(ptr, 4 + (UInt16)atr.reason->size()); + ptr = encode16(ptr, 0); // pad + *ptr++ = atr.errorClass & 0x7; // first 3 bits only + *ptr++ = atr.number; + ptr = encode(ptr, atr.reason->data(), (unsigned int)atr.reason->size()); + memset(ptr, 0, padsize); + return ptr+padsize; +} + +char* +StunMessage::encodeAtrUnknown(char* ptr, const StunAtrUnknown& atr) +{ + UInt16 padsize = (2*atr.numAttributes) % 4 == 0 ? 0 : 4 - ((2*atr.numAttributes) % 4); + ptr = encode16(ptr, UnknownAttribute); + ptr = encode16(ptr, 2*atr.numAttributes); + for (int i=0; i<atr.numAttributes; i++) + { + ptr = encode16(ptr, atr.attrType[i]); + } + return ptr+padsize; +} + +char* +StunMessage::encodeAtrString(char* ptr, UInt16 type, const Data* atr, UInt16 maxBytes) +{ + assert(atr); + UInt16 size = atr->size() > maxBytes ? maxBytes : (UInt16)atr->size(); + UInt16 padsize = size % 4 == 0 ? 0 : 4 - (size % 4); + + ptr = encode16(ptr, type); + ptr = encode16(ptr, size); + ptr = encode(ptr, atr->data(), size); + memset(ptr, 0, padsize); // zero out padded data (note: this is not required by the RFC) + return ptr + padsize; +} + +char* +StunMessage::encodeAtrIntegrity(char* ptr, const StunAtrIntegrity& atr) +{ + ptr = encode16(ptr, MessageIntegrity); + ptr = encode16(ptr, 20); + ptr = encode(ptr, atr.hash, sizeof(atr.hash)); + return ptr; +} + +char* +StunMessage::encodeAtrEvenPort(char* ptr, const TurnAtrEvenPort& atr) +{ + ptr = encode16(ptr, TurnEvenPort); + ptr = encode16(ptr, 1); + *ptr++ = atr.propType; + *ptr++ = 0; // pad + ptr = encode16(ptr, 0); // pad + return ptr; +} + +bool +StunMessage::hasMagicCookie() +{ + return mHeader.id.magicCookie == htonl(StunMessage::StunMagicCookie); +} + +unsigned int +StunMessage::stunEncodeMessage(char* buf, unsigned int bufLen) +{ + assert(bufLen >= sizeof(StunMsgHdr)); + char* ptr = buf; + + mHeader.msgType = mClass | mMethod; + + ptr = encode16(ptr, mHeader.msgType); + char* lengthp = ptr; + ptr = encode16(ptr, 0); + ptr = encode(ptr, reinterpret_cast<const char*>(&mHeader.id), sizeof(mHeader.id)); + + StackLog(<< "Encoding stun message: " << mHeader); + + if (mHasMappedAddress) + { + StackLog(<< "Encoding MappedAddress: " << mMappedAddress); + ptr = encodeAtrAddress (ptr, MappedAddress, mMappedAddress); + } + if (mHasResponseAddress) + { + StackLog(<< "Encoding ResponseAddress: " << mResponseAddress); + ptr = encodeAtrAddress(ptr, ResponseAddress, mResponseAddress); + } + if (mHasChangeRequest) + { + StackLog(<< "Encoding ChangeRequest: " << mChangeRequest); + ptr = encodeAtrUInt32(ptr, ChangeRequest, mChangeRequest); + } + if (mHasSourceAddress) + { + StackLog(<< "Encoding SourceAddress: " << mSourceAddress); + ptr = encodeAtrAddress(ptr, SourceAddress, mSourceAddress); + } + if (mHasChangedAddress) + { + StackLog(<< "Encoding ChangedAddress: " << mChangedAddress); + ptr = encodeAtrAddress(ptr, ChangedAddress, mChangedAddress); + } + if (mHasUsername) + { + StackLog(<< "Encoding Username: " << *mUsername); + ptr = encodeAtrString(ptr, Username, mUsername, MAX_USERNAME_BYTES); + } + if (mHasPassword) + { + StackLog(<< "Encoding Password: " << *mPassword); + ptr = encodeAtrString(ptr, Password, mPassword, MAX_PASSWORD_BYTES); + } + if (mHasErrorCode) + { + StackLog(<< "Encoding ErrorCode: " + << int(mErrorCode.errorClass) + << " number=" << int(mErrorCode.number) + << " reason=" + << *mErrorCode.reason); + + ptr = encodeAtrError(ptr, mErrorCode); + } + if (mHasUnknownAttributes) + { + StackLog(<< "Encoding UnknownAttribute: ???"); + ptr = encodeAtrUnknown(ptr, mUnknownAttributes); + } + if (mHasReflectedFrom) + { + StackLog(<< "Encoding ReflectedFrom: " << mReflectedFrom); + ptr = encodeAtrAddress(ptr, ReflectedFrom, mReflectedFrom); + } + if (mHasRealm) + { + StackLog(<< "Encoding Realm: " << *mRealm); + ptr = encodeAtrString(ptr, Realm, mRealm, MAX_REALM_BYTES); + } + if (mHasNonce) + { + StackLog(<< "Encoding Nonce: " << *mNonce); + ptr = encodeAtrString(ptr, Nonce, mNonce, MAX_NONCE_BYTES); + } + if (mHasXorMappedAddress) + { + StackLog(<< "Encoding XorMappedAddress: " << mXorMappedAddress); + ptr = encodeAtrXorAddress(ptr, XorMappedAddress, mXorMappedAddress); + } + if (mHasSoftware) + { + StackLog(<< "Encoding Software: " << *mSoftware); + ptr = encodeAtrString(ptr, Software, mSoftware, MAX_SOFTWARE_BYTES); + } + if (mHasAlternateServer) + { + StackLog(<< "Encoding Alternate Server: " << mAlternateServer); + ptr = encodeAtrAddress(ptr, AlternateServer, mAlternateServer); + } + if (mHasSecondaryAddress) + { + StackLog(<< "Encoding SecondaryAddress: " << mSecondaryAddress); + ptr = encodeAtrAddress(ptr, SecondaryAddress, mSecondaryAddress); + } + + if (mHasTurnChannelNumber) + { + StackLog(<< "Encoding Turn ChannelNumber: " << mTurnChannelNumber); + ptr = encodeAtrUInt32(ptr, TurnChannelNumber, UInt32(mTurnChannelNumber << 16)); + } + if (mHasTurnLifetime) + { + StackLog(<< "Encoding Turn Lifetime: " << mTurnLifetime); + ptr = encodeAtrUInt32(ptr, TurnLifetime, mTurnLifetime); + } + if (mHasTurnBandwidth) + { + StackLog(<< "Encoding Turn Bandwidth: " << mTurnBandwidth); + ptr = encodeAtrUInt32(ptr, TurnBandwidth, mTurnBandwidth); + } + if (mCntTurnXorPeerAddress > 0) + { + for (int i = 0; i < mCntTurnXorPeerAddress; i++) + { + StackLog(<< "Encoding Turn XorPeerAddress: " << mTurnXorPeerAddress[i]); + ptr = encodeAtrXorAddress (ptr, TurnXorPeerAddress, mTurnXorPeerAddress[i]); + } + } + if (mHasTurnData) + { + StackLog(<< "Encoding TurnData (not shown)"); + ptr = encodeTurnData (ptr, mTurnData); + } + if (mHasTurnXorRelayedAddress) + { + StackLog(<< "Encoding Turn XorRelayedAddress: " << mTurnXorRelayedAddress); + ptr = encodeAtrXorAddress (ptr, TurnXorRelayedAddress, mTurnXorRelayedAddress); + } + if (mHasTurnEvenPort) + { + StackLog(<< "Encoding Turn EvenPort: " << (int)mTurnEvenPort.propType); + ptr = encodeAtrEvenPort(ptr, mTurnEvenPort); + } + if (mHasTurnRequestedTransport) + { + StackLog(<< "Encoding Turn RequestedTransport: " << (int)mTurnRequestedTransport); + ptr = encodeAtrUInt32(ptr, TurnRequestedTransport, UInt32(mTurnRequestedTransport << 24)); + } + if (mHasTurnDontFragment) + { + StackLog(<< "Encoding Turn DontFragment: <exists>"); + ptr = encode16(ptr, TurnDontFragment); + ptr = encode16(ptr, 0); // 0 attribute length + } + if (mHasTurnReservationToken) + { + StackLog(<< "Encoding Turn ReservationToken: " << mTurnReservationToken); + ptr = encodeAtrUInt64 (ptr, TurnReservationToken, mTurnReservationToken); + } + if (mHasTurnConnectStat) + { + StackLog(<< "Encoding Turn Connect Stat: " << mTurnConnectStat); + ptr = encodeAtrUInt32(ptr, TurnConnectStat, mTurnConnectStat); + } + + // Update Length in header now - needed in message integrity calculations + UInt16 msgSize = ptr - buf - sizeof(StunMsgHdr); + if(mHasMessageIntegrity) msgSize += 24; // 4 (attribute header) + 20 (attribute value) + encode16(lengthp, msgSize); + + if (mHasMessageIntegrity) + { + int len = ptr - buf; + StackLog(<< "Adding message integrity: buffer size=" << len << ", hmacKey=" << mHmacKey.hex()); + StunAtrIntegrity integrity; + computeHmac(integrity.hash, buf, len, mHmacKey.c_str(), (int)mHmacKey.size()); + ptr = encodeAtrIntegrity(ptr, integrity); + } + + // Update Length in header now - may be needed in fingerprint calculations + if(mHasFingerprint) msgSize += 8; // 4 (attribute header) + 4 (attribute value) + encode16(lengthp, msgSize); + + // add finger print if required + if (mHasFingerprint) + { + StackLog(<< "Calculating fingerprint for data of size " << ptr-buf); + boost::crc_32_type stun_crc; + stun_crc.process_bytes(buf, ptr-buf); // Calculate CRC across entire message, except the fingerprint attribute + UInt32 fingerprint = stun_crc.checksum() ^ STUN_CRC_FINAL_XOR; + ptr = encodeAtrUInt32(ptr, Fingerprint, fingerprint); + } + + return int(ptr - buf); +} + +unsigned int +StunMessage::stunEncodeFramedMessage(char* buf, unsigned int bufLen) +{ + unsigned short size = (unsigned short)stunEncodeMessage(&buf[4], bufLen-4); + + // Add Frame Header info + buf[0] = 0; // Channel 0 for Stun Messages + buf[1] = 0; + UInt16 frameSize = htons(size); + memcpy(&buf[2], (void*)&frameSize, 2); // size is not needed if udp - but should be harmless + return size+4; +} + +#ifndef USE_SSL +void +StunMessage::computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey) +{ + strncpy(hmac,"hmac-not-implemented",20); +} +#else +void +StunMessage::computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey) +{ + unsigned int resultSize=20; + HMAC(EVP_sha1(), + key, sizeKey, + reinterpret_cast<const unsigned char*>(input), length, + reinterpret_cast<unsigned char*>(hmac), &resultSize); + assert(resultSize == 20); +} +#endif + +void +StunMessage::createUsernameAndPassword() +{ + UInt64 time = resip::Timer::getTimeSecs(); + time -= (time % 20*60); // rounded time - current time modulo 20 minutes + //UInt64 hitime = time >> 32; + //UInt64 lotime = time & 0xFFFFFFFF; + + mHasUsername = true; + if(!mUsername) + { + mUsername = new Data; + } + assert(mUsername); + + if(mRemoteTuple.getAddress().is_v6()) + { + *mUsername = Data(mRemoteTuple.getAddress().to_v6().to_bytes().c_array(), mRemoteTuple.getAddress().to_v6().to_bytes().size()).base64encode() + ":"; + } + else + { + *mUsername = Data(mRemoteTuple.getAddress().to_v4().to_bytes().c_array(), mRemoteTuple.getAddress().to_v4().to_bytes().size()).base64encode() + ":"; + } + unsigned int port = mRemoteTuple.getPort(); + *mUsername += Data((char*)&port, sizeof(unsigned int)).base64encode() + ":"; + *mUsername += resip::Random::getCryptoRandomHex(8) + ":"; // 8 bytes, 64 bits of randomness + *mUsername += Data((char*)&time, sizeof(time)).hex() + ":"; + char hmac[20]; + computeHmac(hmac, mUsername->data(), (int)mUsername->size(), USERNAME_KEY.data(), (int)USERNAME_KEY.size()); + *mUsername += Data(hmac, sizeof(hmac)).hex(); + + assert( mUsername->size()%4 == 0 ); + + StackLog(<< "computed username=" << *mUsername); + + // Compute Password + mHasPassword = true; + + if(!mPassword) + { + mPassword = new Data; + } + assert(mPassword); + generateShortTermPasswordForUsername(*mPassword); + + StackLog(<< "computed password=" << *mPassword); +} + +void +StunMessage::generateShortTermPasswordForUsername(Data& password) +{ + char hmac[20]; + assert(mHasUsername && mUsername); + computeHmac(hmac, mUsername->data(), (int)mUsername->size(), PASSWORD_KEY.data(), (int)PASSWORD_KEY.size()); + password = Data(hmac, sizeof(hmac)).hex(); +} + +void +StunMessage::getTupleFromUsername(StunTuple& tuple) +{ + assert(mHasUsername); + assert(mUsername && mUsername->size() >= 92); + assert(mUsername->size() == 92 || mUsername->size() == 108); + + if(mUsername->size() > 92) // if over a certain size, then contains IPv6 address + { + Data addressPart(Data::Share, mUsername->data(), 24); + addressPart = addressPart.base64decode(); + asio::ip::address_v6::bytes_type bytes; + memcpy(bytes.c_array(), addressPart.data(), bytes.size()); + asio::ip::address_v6 addressv6(bytes); + tuple.setAddress(addressv6); + + unsigned int port; + Data portPart(Data::Share, mUsername->data()+25, 4); + portPart = portPart.base64decode(); + memcpy(&port, portPart.data(), sizeof(port)); + tuple.setPort(port); + } + else + { + Data addressPart(Data::Share, mUsername->data(), 8); + addressPart = addressPart.base64decode(); + asio::ip::address_v4::bytes_type bytes; + memcpy(bytes.c_array(), addressPart.data(), bytes.size()); + asio::ip::address_v4 addressv4(bytes); + tuple.setAddress(addressv4); + + unsigned int port; + Data portPart(Data::Share, mUsername->data()+9, 4); + portPart = portPart.base64decode(); + memcpy(&port, portPart.data(), sizeof(port)); + tuple.setPort(port); + } +} + +void +StunMessage::calculateHmacKey(Data& hmacKey, const Data& longtermAuthenticationPassword) +{ + assert(mHasUsername); + + if(mHasRealm) // Longterm authenicationmode + { + calculateHmacKey(hmacKey, *mUsername, *mRealm, longtermAuthenticationPassword); + } + else + { + generateShortTermPasswordForUsername(hmacKey); + } +} + +void +StunMessage::calculateHmacKey(Data& hmacKey, const Data& username, const Data& realm, const Data& longtermAuthenticationPassword) +{ + MD5Stream r; + r << username << ":" << realm << ":" << longtermAuthenticationPassword; + hmacKey = r.getBin(); + + DebugLog(<< "calculateHmacKey: '" << username << ":" << realm << ":" << longtermAuthenticationPassword << "' = '" << hmacKey.hex() << "'"); +} + +bool +StunMessage::checkMessageIntegrity(const Data& hmacKey) +{ + if(mHasMessageIntegrity) + { + unsigned char hmac[20]; + + // Store original stun message length from mBuffer + char *lengthposition = (char*)mBuffer.data() + 2; + UInt16 originalLength; + memcpy(&originalLength, lengthposition, 2); + + // Update stun message length in mBuffer for calculation + UInt16 tempLength = htons(mMessageIntegrityMsgLength); + memcpy(lengthposition, &tempLength, 2); + + // Calculate HMAC + int iHMACBufferSize = mMessageIntegrityMsgLength - 24 /* MessageIntegrity size */ + sizeof(StunMsgHdr); // The entire message proceeding the message integrity attribute + StackLog(<< "Checking message integrity: length=" << mMessageIntegrityMsgLength << ", size=" << iHMACBufferSize << ", hmacKey=" << hmacKey.hex()); + computeHmac((char*)hmac, mBuffer.data(), iHMACBufferSize, hmacKey.c_str(), hmacKey.size()); + + // Restore original stun message length in mBuffer + memcpy(lengthposition, &originalLength, 2); + + if (memcmp(mMessageIntegrity.hash, hmac, 20) == 0) + { + return true; + } + else + { + return false; + } + } + else + { + // No message integrity attribute present - return true + return true; + } +} + +bool +StunMessage::checkFingerprint() +{ + if(mHasFingerprint) + { + StackLog(<< "Calculating fingerprint to check for data of size " << mBuffer.size() - 8); + boost::crc_32_type stun_crc; + stun_crc.process_bytes(mBuffer.data(), mBuffer.size()-8); // Calculate CRC across entire message, except the fingerprint attribute + + unsigned long crc = stun_crc.checksum() ^ STUN_CRC_FINAL_XOR; + if(crc == mFingerprint) + { + return true; + } + else + { + WarningLog(<< "Fingerprint=" << mFingerprint << " does not match CRC=" << stun_crc.checksum()); + return false; + } + } + return true; +} + +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/StunMessage.hxx b/src/libs/resiprocate/reTurn/StunMessage.hxx new file mode 100644 index 00000000..38c17996 --- /dev/null +++ b/src/libs/resiprocate/reTurn/StunMessage.hxx @@ -0,0 +1,400 @@ +#if !defined(STUNMESSAGE_HXX) +#define STUNMESSAGE_HXX + +#include <ostream> +#include <rutil/compat.hxx> +#include <rutil/Data.hxx> +#include <asio.hpp> + +#include "StunTuple.hxx" + +#define STUN_MAX_UNKNOWN_ATTRIBUTES 8 +#define TURN_MAX_XOR_PEER_ADDR 8 + +namespace reTurn +{ + +typedef struct { UInt32 longpart[4]; } UInt128; +typedef struct { UInt32 longpart[3]; } UInt96; + +#ifdef __cplusplus +bool operator<(const UInt128&, const UInt128&); +bool operator==(const UInt128&, const UInt128&); +#endif + +class StunMessage +{ +public: + explicit StunMessage(const StunTuple& localTuple, + const StunTuple& remoteTuple, + char* buf, unsigned int bufLen); + + explicit StunMessage(); + + StunMessage(const StunMessage& message); + virtual ~StunMessage(); + StunMessage& operator=(const StunMessage& rhs); + + bool isValid() { return mIsValid; } + bool hasMagicCookie(); + + unsigned int stunEncodeMessage(char* buf, unsigned int bufLen); + unsigned int stunEncodeFramedMessage(char* buf, unsigned int bufLen); // Used for TURN-05 framing only + + void setErrorCode(unsigned short errorCode, const char* reason); + void setUsername(const char* username); + void setPassword(const char* password); + void setRealm(const char* realm); + void setNonce(const char* nonce); + void setSoftware(const char* software); + void setTurnData(const char* data, unsigned int len); + + void createHeader(UInt16 stunclass, UInt16 method); // Set info needed for a new stun message - set's tid as well + void createUsernameAndPassword(); // Ensure mRemoteTuple is set first + void generateShortTermPasswordForUsername(resip::Data& password); // Ensure username is set first + void getTupleFromUsername(StunTuple& tuple); // note: does not set transport type + void calculateHmacKey(resip::Data& hmacKey, const resip::Data& longtermAuthenticationPassword); + void calculateHmacKey(resip::Data& hmacKey, const resip::Data& username, const resip::Data& realm, const resip::Data& longtermAuthenticationPassword); + bool checkMessageIntegrity(const resip::Data& hmacKey); + bool checkFingerprint(); + + /// define stun address families + const static UInt8 IPv4Family = 0x01; + const static UInt8 IPv6Family = 0x02; + + const static UInt8 PropsPortEven = 0x00; + const static UInt8 PropsPortPair = 0x80; + const static UInt8 PropsNone = 0xFF; + + // The following are codepoints used in the requested transport header, they + // are the same values used in the IPv4 and IPv6 headers + const static UInt32 RequestedTransportUdp = 17; + const static UInt32 RequestedTransportTcp = 6; + + // define flags + const static UInt32 ChangeIpFlag = 0x04; + const static UInt32 ChangePortFlag = 0x02; + + + // Message Type - from RFC5389 + // + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |0 0| STUN Message Type | Message Length | + // | |M|M|M|M|M|C|M|M|M|C|M|M|M|M| | + // | |1|1|9|8|7|1|6|5|4|0|3|2|1|0| | + // | |1|0| | | | | | | | | | | | | | + // | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + // + // M11 through M0 represent a 12-bit encoding of the method + // C1 through C0 represent a 2 bit encoding of the class. + // 2-bit Class Values are: 00=Request, 01=Indicaiton, + // 10=Success Response, 11=Error Response + // + + const static UInt16 StunClassRequest = 0x0000; + const static UInt16 StunClassIndication = 0x0010; + const static UInt16 StunClassSuccessResponse = 0x0100; + const static UInt16 StunClassErrorResponse = 0x0110; + + // define types for a stun message - RFC5389 + const static UInt16 BindMethod = 0x001; + const static UInt16 SharedSecretMethod = 0x002; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only) + + // define types for a turn message - per RFC5766 + const static UInt16 TurnAllocateMethod = 0x003; + const static UInt16 TurnRefreshMethod = 0x004; + const static UInt16 TurnSendMethod = 0x006; // indication only + const static UInt16 TurnDataMethod = 0x007; // indication only + const static UInt16 TurnCreatePermissionMethod = 0x008; + const static UInt16 TurnChannelBindMethod = 0x009; + + // define stun attribute - RFC5389 + // Comprehension required attributes + const static UInt16 MappedAddress = 0x0001; + const static UInt16 ResponseAddress = 0x0002; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only) + const static UInt16 ChangeRequest = 0x0003; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only) + const static UInt16 SourceAddress = 0x0004; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only) + const static UInt16 ChangedAddress = 0x0005; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only) + const static UInt16 Username = 0x0006; + const static UInt16 Password = 0x0007; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only) + const static UInt16 MessageIntegrity = 0x0008; + const static UInt16 ErrorCode = 0x0009; + const static UInt16 UnknownAttribute = 0x000A; + const static UInt16 ReflectedFrom = 0x000B; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only) + const static UInt16 Realm = 0x0014; + const static UInt16 Nonce = 0x0015; + const static UInt16 XorMappedAddress = 0x0020; + const static UInt16 XorMappedAddress_old = 0x8020; // deprecated + // Comprehension Optional Attributes + const static UInt16 Software = 0x8022; + const static UInt16 AlternateServer = 0x8023; + const static UInt16 Fingerprint = 0x8028; + const static UInt16 SecondaryAddress = 0x8050; // Non standard extension + + // TURN specific message attributes - from behave-turn-12 + const static UInt16 TurnChannelNumber = 0x000C; + const static UInt16 TurnLifetime = 0x000D; + const static UInt16 TurnBandwidth = 0x0010; // reserved (removed from latest draft) + const static UInt16 TurnXorPeerAddress = 0x0012; + const static UInt16 TurnData = 0x0013; + const static UInt16 TurnXorRelayedAddress = 0x0016; + const static UInt16 TurnEvenPort = 0x0018; + const static UInt16 TurnRequestedTransport = 0x0019; + const static UInt16 TurnDontFragment = 0x001a; + //const static UInt16 TurnTimerVal = 0x0021; // reserved (removed from latest draft) + const static UInt16 TurnReservationToken = 0x0022; + const static UInt16 TurnConnectStat = 0x0023; // tcp allocations + + const static UInt32 StunMagicCookie = 0x2112A442; + typedef struct + { + UInt32 magicCookie; + UInt96 tid; + } Id; + + typedef struct + { + UInt16 msgType; + UInt16 msgLength; + union + { + UInt128 magicCookieAndTid; + Id id; + }; + } StunMsgHdr; + + typedef struct + { + UInt16 type; + UInt16 length; + } StunAtrHdr; + + typedef struct + { + UInt8 family; + UInt16 port; + union + { + UInt32 ipv4; // in host byte order + UInt128 ipv6; // in network byte order + } addr; + } StunAtrAddress; + + typedef struct + { + UInt8 errorClass; + UInt8 number; + resip::Data* reason; + } StunAtrError; + + typedef struct + { + UInt16 attrType[STUN_MAX_UNKNOWN_ATTRIBUTES]; + UInt16 numAttributes; + } StunAtrUnknown; + + typedef struct + { + char hash[20]; + } StunAtrIntegrity; + + typedef struct + { + UInt8 propType; + } TurnAtrEvenPort; + + enum StunHmacStatus + { + HmacUnknown=0, + HmacOK, + HmacBadUserName, + HmacUnknownUserName, + HmacFailed + }; + + // !slg! TODO make private and provide accessors + UInt16 mClass; // Request, Response, Indication + UInt16 mMethod; // Binding Request, Shared Secret Request, Allocation Request, etc. + bool mHasMagicCookie; // Set to true if stun magic cookie is in message header + StunTuple mLocalTuple; // Local address and port that received stun message + StunTuple mRemoteTuple; // Remote address and port that send stun message + resip::Data mBuffer; + resip::Data mHmacKey; + + UInt16 mMessageIntegrityMsgLength; + + StunMsgHdr mHeader; + + bool mHasMappedAddress; + StunAtrAddress mMappedAddress; + + bool mHasResponseAddress; + StunAtrAddress mResponseAddress; + + bool mHasChangeRequest; + UInt32 mChangeRequest; + + bool mHasSourceAddress; + StunAtrAddress mSourceAddress; + + bool mHasChangedAddress; + StunAtrAddress mChangedAddress; + + bool mHasUsername; + resip::Data* mUsername; + + bool mHasPassword; + resip::Data* mPassword; + + bool mHasMessageIntegrity; + StunAtrIntegrity mMessageIntegrity; + + bool mHasErrorCode; + StunAtrError mErrorCode; + + bool mHasUnknownAttributes; + StunAtrUnknown mUnknownAttributes; + + bool mHasReflectedFrom; + StunAtrAddress mReflectedFrom; + + bool mHasRealm; + resip::Data* mRealm; + + bool mHasNonce; + resip::Data* mNonce; + + bool mHasXorMappedAddress; + StunAtrAddress mXorMappedAddress; + + bool mHasFingerprint; + UInt32 mFingerprint; + + bool mHasSoftware; + resip::Data* mSoftware; + + bool mHasAlternateServer; + StunAtrAddress mAlternateServer; + + bool mHasSecondaryAddress; + StunAtrAddress mSecondaryAddress; + + // Turn Attributes + bool mHasTurnChannelNumber; + UInt16 mTurnChannelNumber; + + bool mHasTurnLifetime; + UInt32 mTurnLifetime; + + bool mHasTurnBandwidth; + UInt32 mTurnBandwidth; + + int mCntTurnXorPeerAddress; + StunAtrAddress mTurnXorPeerAddress[TURN_MAX_XOR_PEER_ADDR]; + + bool mHasTurnData; + resip::Data* mTurnData; + + bool mHasTurnXorRelayedAddress; + StunAtrAddress mTurnXorRelayedAddress; + + bool mHasTurnEvenPort; + TurnAtrEvenPort mTurnEvenPort; + + bool mHasTurnRequestedTransport; + UInt8 mTurnRequestedTransport; + + bool mHasTurnDontFragment; + // No attribute data + + bool mHasTurnReservationToken; + UInt64 mTurnReservationToken; + + bool mHasTurnConnectStat; + UInt32 mTurnConnectStat; + + StunAtrUnknown mUnknownRequiredAttributes; + + // Utility APIs + void applyXorToAddress(const StunAtrAddress& in, StunAtrAddress& out); // ensure tid is set first + static void setStunAtrAddressFromTuple(StunAtrAddress& address, const StunTuple& tuple); + static void setTupleFromStunAtrAddress(StunTuple& tuple, const StunAtrAddress& address); // Note: does not set transport type + +protected: + +private: + void init(); + + bool stunParseAtrXorAddress( char* body, unsigned int hdrLen, StunAtrAddress& result ); + bool stunParseAtrAddress( char* body, unsigned int hdrLen, StunAtrAddress& result ); + bool stunParseAtrUInt32( char* body, unsigned int hdrLen, UInt32& result ); + bool stunParseAtrUInt64( char* body, unsigned int hdrLen, UInt64& result ); + bool stunParseAtrError( char* body, unsigned int hdrLen, StunAtrError& result ); + bool stunParseAtrUnknown( char* body, unsigned int hdrLen, StunAtrUnknown& result ); + bool stunParseAtrIntegrity( char* body, unsigned int hdrLen, StunAtrIntegrity& result ); + bool stunParseAtrEvenPort( char* body, unsigned int hdrLen, TurnAtrEvenPort& result ); + + bool stunParseMessage( char* buf, unsigned int bufLen); + + char* encode16(char* buf, UInt16 data); + char* encode32(char* buf, UInt32 data); + char* encode(char* buf, const char* data, unsigned int length); + char* encodeTurnData(char *ptr, const resip::Data* td); + char* encodeAtrUInt32(char* ptr, UInt16 type, UInt32 value); + char* encodeAtrUInt64(char* ptr, UInt16 type, UInt64 value); + char* encodeAtrXorAddress(char* ptr, UInt16 type, const StunAtrAddress& atr); + char* encodeAtrAddress(char* ptr, UInt16 type, const StunAtrAddress& atr); + char* encodeAtrError(char* ptr, const StunAtrError& atr); + char* encodeAtrUnknown(char* ptr, const StunAtrUnknown& atr); + char* encodeAtrString(char* ptr, UInt16 type, const resip::Data* atr, UInt16 maxBytes); + char* encodeAtrIntegrity(char* ptr, const StunAtrIntegrity& atr); + char* encodeAtrEvenPort(char* ptr, const TurnAtrEvenPort& atr); + void computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey); + + bool mIsValid; +}; + +EncodeStream& operator<< ( EncodeStream& strm, const StunMessage::StunAtrAddress& addr); +EncodeStream& operator<< ( EncodeStream& strm, const UInt128& ); +EncodeStream& operator<< ( EncodeStream& strm, const StunMessage::StunMsgHdr& ); + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/StunTuple.cxx b/src/libs/resiprocate/reTurn/StunTuple.cxx new file mode 100644 index 00000000..39b2c905 --- /dev/null +++ b/src/libs/resiprocate/reTurn/StunTuple.cxx @@ -0,0 +1,116 @@ +#include "StunTuple.hxx" + +using namespace std; + +namespace reTurn { + +// Default constructor +StunTuple::StunTuple() : + mTransport(None), + mPort(0) +{ +} + +StunTuple::StunTuple(TransportType transport, const asio::ip::address& address, unsigned int port) : + mTransport(transport), + mAddress(address), + mPort(port) +{ +} + +bool +StunTuple::operator==(const StunTuple& rhs) const +{ + return mTransport == rhs.mTransport && + mAddress == rhs.mAddress && + mPort == rhs.mPort; +} + +bool +StunTuple::operator!=(const StunTuple& rhs) const +{ + return mTransport != rhs.mTransport || + mAddress != rhs.mAddress || + mPort != rhs.mPort; +} + +bool +StunTuple::operator<(const StunTuple& rhs) const +{ + if (mTransport < rhs.mTransport) + { + return true; + } + if (mTransport > rhs.mTransport) + { + return false; + } + if(mAddress < rhs.mAddress) + { + return true; + } + if(mAddress == rhs.mAddress) + { + return mPort < rhs.mPort; + } + return false; +} + +EncodeStream& +operator<<(EncodeStream& strm, const StunTuple& tuple) +{ + switch(tuple.mTransport) + { + case StunTuple::None: + strm << "[None "; + break; + case StunTuple::UDP: + strm << "[UDP "; + break; + case StunTuple::TCP: + strm << "[TCP "; + break; + case StunTuple::TLS: + strm << "[TLS "; + break; + } + strm << tuple.mAddress.to_string() << ":" << tuple.mPort << "]"; + return strm; +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/StunTuple.hxx b/src/libs/resiprocate/reTurn/StunTuple.hxx new file mode 100644 index 00000000..24fc8441 --- /dev/null +++ b/src/libs/resiprocate/reTurn/StunTuple.hxx @@ -0,0 +1,83 @@ +#ifndef STUNTUPLE_HXX +#define STUNTUPLE_HXX + +#include <asio.hpp> +#include <rutil/resipfaststreams.hxx> + +namespace reTurn { + +class StunTuple +{ +public: + typedef enum + { + None, + UDP, + TCP, + TLS + } TransportType; + + explicit StunTuple(); + explicit StunTuple(TransportType transport, const asio::ip::address& address, unsigned int port); + + bool operator==(const StunTuple& rhs) const; + bool operator!=(const StunTuple& rhs) const; + bool operator<(const StunTuple& rhs) const; + + TransportType getTransportType() const { return mTransport; } + void setTransportType(TransportType transport) { mTransport = transport; } + + const asio::ip::address& getAddress() const { return mAddress; } + void setAddress(const asio::ip::address& address) { mAddress = address; } + + unsigned int getPort() const { return mPort; } + void setPort(unsigned int port) { mPort = port; } + +private: + TransportType mTransport; + asio::ip::address mAddress; + unsigned int mPort; + + friend EncodeStream& operator<<(EncodeStream& strm, const StunTuple& tuple); +}; + +EncodeStream& operator<<(EncodeStream& strm, const StunTuple& tuple); + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TcpConnection.cxx b/src/libs/resiprocate/reTurn/TcpConnection.cxx new file mode 100644 index 00000000..95ad8108 --- /dev/null +++ b/src/libs/resiprocate/reTurn/TcpConnection.cxx @@ -0,0 +1,194 @@ +#include "TcpConnection.hxx" +#include <vector> +#include <boost/bind.hpp> +#include <rutil/SharedPtr.hxx> +#include "ConnectionManager.hxx" +#include "RequestHandler.hxx" +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; +using namespace resip; + +namespace reTurn { + +TcpConnection::TcpConnection(asio::io_service& ioService, + ConnectionManager& manager, RequestHandler& handler) + : AsyncTcpSocketBase(ioService), + mConnectionManager(manager), + mRequestHandler(handler) +{ +} + +TcpConnection::~TcpConnection() +{ + DebugLog(<< "TcpConnection destroyed."); +} + +asio::ip::tcp::socket& +TcpConnection::socket() +{ + return mSocket; +} + +void +TcpConnection::start() +{ + DebugLog(<< "TcpConnection started."); + setConnectedAddressAndPort(); + doFramedReceive(); +} + +void +TcpConnection::stop() +{ + asio::error_code ec; + mSocket.close(ec); +} + +void +TcpConnection::close() +{ + mConnectionManager.stop(shared_from_this()); +} + +void +TcpConnection::onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) +{ + if (data->size() > 4) + { + /* + std::cout << "Read " << bytesTransferred << " bytes from tcp socket (" << address.to_string() << ":" << port << "): " << std::endl; + cout << std::hex; + for(int i = 0; i < data->size(); i++) + { + std::cout << (char)(*data)[i] << "(" << int((*data)[i]) << ") "; + } + std::cout << std::dec << std::endl; + */ + + if(((*data)[0] & 0xC0) == 0) // Stun/Turn Messages always have bits 0 and 1 as 00 - otherwise ChannelData message + { + // Try to parse stun message + StunMessage request(StunTuple(StunTuple::TCP, mSocket.local_endpoint().address(), mSocket.local_endpoint().port()), + StunTuple(StunTuple::TCP, address, port), + (char*)&(*data)[0], data->size()); + if(request.isValid()) + { + StunMessage response; + RequestHandler::ProcessResult result = mRequestHandler.processStunMessage(this, request, response); + + switch(result) + { + case RequestHandler::NoResponseToSend: + // No response to send - just receive next message + doFramedReceive(); + return; + case RequestHandler::RespondFromAlternatePort: + case RequestHandler::RespondFromAlternateIp: + case RequestHandler::RespondFromAlternateIpPort: + // These only happen for UDP server for RFC3489 backwards compatibility + assert(false); + break; + case RequestHandler::RespondFromReceiving: + default: + break; + } +#define RESPONSE_BUFFER_SIZE 1024 + boost::shared_ptr<DataBuffer> buffer = allocateBuffer(RESPONSE_BUFFER_SIZE); + unsigned int responseSize; + responseSize = response.stunEncodeMessage((char*)buffer->data(), RESPONSE_BUFFER_SIZE); + buffer->truncate(responseSize); // set size to real size + + doSend(response.mRemoteTuple, buffer); + } + else + { + WarningLog(<< "Received invalid StunMessage. Dropping."); + } + } + else // ChannelData message + { + unsigned short channelNumber; + memcpy(&channelNumber, &(*data)[0], 2); + channelNumber = ntohs(channelNumber); + + mRequestHandler.processTurnData(channelNumber, + StunTuple(StunTuple::TCP, mSocket.local_endpoint().address(), mSocket.local_endpoint().port()), + StunTuple(StunTuple::TCP, address, port), + data); + } + } + else + { + WarningLog(<< "Not enough data for stun message or framed message. Closing connection."); + close(); + return; + } + + doFramedReceive(); +} + +void +TcpConnection::onReceiveFailure(const asio::error_code& e) +{ + if(e != asio::error::operation_aborted) + { + InfoLog(<< "TcpConnection::onReceiveFailure: " << e.value() << "-" << e.message()); + close(); + } +} + +void +TcpConnection::onSendSuccess() +{ +} + +void +TcpConnection::onSendFailure(const asio::error_code& error) +{ + if(error != asio::error::operation_aborted) + { + InfoLog(<< "TcpConnection::onSendFailure: " << error.value() << "-" << error.message()); + close(); + } +} + +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TcpConnection.hxx b/src/libs/resiprocate/reTurn/TcpConnection.hxx new file mode 100644 index 00000000..2c428e0d --- /dev/null +++ b/src/libs/resiprocate/reTurn/TcpConnection.hxx @@ -0,0 +1,93 @@ +#ifndef TCP_CONNECTION_HXX +#define TCP_CONNECTION_HXX + +#include <asio.hpp> +#include <boost/array.hpp> +#include <boost/noncopyable.hpp> +#include <boost/shared_ptr.hpp> +#include "RequestHandler.hxx" +#include "StunTuple.hxx" +#include "AsyncTcpSocketBase.hxx" + +namespace reTurn { + +class ConnectionManager; + +/// Represents a single connection from a client. +class TcpConnection + : public AsyncTcpSocketBase, + private boost::noncopyable +{ +public: + /// Construct a connection with the given io_service. + explicit TcpConnection(asio::io_service& ioService, ConnectionManager& manager, RequestHandler& handler); + ~TcpConnection(); + + /// Get the socket associated with the connection. + asio::ip::tcp::socket& socket(); + + /// Start the first asynchronous operation for the connection. + virtual void start(); + + /// Override close fn in AsyncTcpSocketBase so that we can remove ourselves from connection manager + virtual void close(); + + /// Stop all asynchronous operations associated with the connection. + virtual void stop(); + +protected: + /// Handle completion of a receive operation + virtual void onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data); + virtual void onReceiveFailure(const asio::error_code& e); + + /// Handle completion of a send operation + virtual void onSendSuccess(); + virtual void onSendFailure(const asio::error_code& e); + + /// The manager for this connection. + ConnectionManager& mConnectionManager; + + /// The handler used to process the incoming request. + RequestHandler& mRequestHandler; + +private: +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TcpServer.cxx b/src/libs/resiprocate/reTurn/TcpServer.cxx new file mode 100644 index 00000000..5fc3c2fe --- /dev/null +++ b/src/libs/resiprocate/reTurn/TcpServer.cxx @@ -0,0 +1,86 @@ +#include "TcpServer.hxx" +#include <boost/bind.hpp> +#include <rutil/WinLeakCheck.hxx> +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +namespace reTurn { + +TcpServer::TcpServer(asio::io_service& ioService, RequestHandler& requestHandler, const asio::ip::address& address, unsigned short port) +: mIOService(ioService), + mAcceptor(ioService), + mConnectionManager(), + mNewConnection(new TcpConnection(ioService, mConnectionManager, requestHandler)), + mRequestHandler(requestHandler) +{ + // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). + asio::ip::tcp::endpoint endpoint(address, port); + + mAcceptor.open(endpoint.protocol()); + mAcceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true)); + mAcceptor.bind(endpoint); + mAcceptor.listen(); + + InfoLog(<< "TcpServer started. Listening on " << address.to_string() << ":" << port); +} + +void +TcpServer::start() +{ + mAcceptor.async_accept(((TcpConnection*)mNewConnection.get())->socket(), boost::bind(&TcpServer::handleAccept, this, asio::placeholders::error)); +} + +void +TcpServer::handleAccept(const asio::error_code& e) +{ + if (!e) + { + mConnectionManager.start(mNewConnection); + + mNewConnection.reset(new TcpConnection(mIOService, mConnectionManager, mRequestHandler)); + mAcceptor.async_accept(((TcpConnection*)mNewConnection.get())->socket(), boost::bind(&TcpServer::handleAccept, this, asio::placeholders::error)); + } + else + { + ErrLog(<< "Error in handleAccept: " << e.value() << "-" << e.message()); + } +} + +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TcpServer.hxx b/src/libs/resiprocate/reTurn/TcpServer.hxx new file mode 100644 index 00000000..68f7df97 --- /dev/null +++ b/src/libs/resiprocate/reTurn/TcpServer.hxx @@ -0,0 +1,79 @@ +#ifndef TCP_SERVER_HXX +#define TCP_SERVER_HXX + +#include <asio.hpp> +#include <string> +#include <boost/noncopyable.hpp> +#include "TcpConnection.hxx" +#include "ConnectionManager.hxx" +#include "RequestHandler.hxx" + +namespace reTurn { + +class TcpServer + : private boost::noncopyable +{ +public: + /// Create the server to listen on the specified TCP address and port + explicit TcpServer(asio::io_service& ioService, RequestHandler& rqeuestHandler, const asio::ip::address& address, unsigned short port); + + void start(); + +private: + /// Handle completion of an asynchronous accept operation. + void handleAccept(const asio::error_code& e); + + /// The io_service used to perform asynchronous operations. + asio::io_service& mIOService; + + /// Acceptor used to listen for incoming connections. + asio::ip::tcp::acceptor mAcceptor; + + /// The connection manager which owns all live connections. + ConnectionManager mConnectionManager; + + /// The next connection to be accepted. + ConnectionPtr mNewConnection; + + /// The handler for all incoming requests. + RequestHandler& mRequestHandler; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TlsConnection.cxx b/src/libs/resiprocate/reTurn/TlsConnection.cxx new file mode 100644 index 00000000..255be679 --- /dev/null +++ b/src/libs/resiprocate/reTurn/TlsConnection.cxx @@ -0,0 +1,219 @@ +#ifdef WIN32 +#pragma warning(disable : 4267) +#endif + +#include "TlsConnection.hxx" +#include <vector> +#include <boost/bind.hpp> +#include "ConnectionManager.hxx" +#include "RequestHandler.hxx" +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; +using namespace resip; + +namespace reTurn { + +TlsConnection::TlsConnection(asio::io_service& ioService, + ConnectionManager& manager, + RequestHandler& handler, + asio::ssl::context& context) + : AsyncTlsSocketBase(ioService, context, false /* not needed in server */), + mConnectionManager(manager), + mRequestHandler(handler) +{ +} + +TlsConnection::~TlsConnection() +{ + DebugLog(<< "TlsConnection destroyed."); +} + +ssl_socket::lowest_layer_type& +TlsConnection::socket() +{ + return mSocket.lowest_layer(); +} + +void +TlsConnection::start() +{ + DebugLog(<< "TlsConnection started."); + + doHandshake(); +} + +void +TlsConnection::stop() +{ + asio::error_code ec; + //mSocket.shutdown(ec); // !slg! note: this fn gives a stack overflow since ASIO 1.0.0 for some reason + mSocket.lowest_layer().close(ec); + if(ec) + { + WarningLog(<< "TlsConnection shutdown, error=" << ec.value() << "-" << ec.message()); + } +} + +void +TlsConnection::close() +{ + mConnectionManager.stop(shared_from_this()); +} + +void +TlsConnection::onServerHandshakeSuccess() +{ + DebugLog(<< "TlsConnection handshake completed."); + doFramedReceive(); +} + +void +TlsConnection::onServerHandshakeFailure(const asio::error_code& e) +{ + WarningLog(<< "TlsConnection handshake failure, error=" << e.value() << "-" << e.message()); + close(); +} + +void +TlsConnection::onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) +{ + if (data->size() > 4) + { + /* + std::cout << "Read " << bytesTransferred << " bytes from tls socket (" << address.to_string() << ":" << port << "): " << std::endl; + cout << std::hex; + for(int i = 0; i < data->size(); i++) + { + std::cout << (char)(*data)[i] << "(" << int((*data)[i]) << ") "; + } + std::cout << std::dec << std::endl; + */ + + if(((*data)[0] & 0xC0) == 0) // Stun/Turn Messages always have bits 0 and 1 as 00 - otherwise ChannelData message + { + // Try to parse stun message + StunMessage request(StunTuple(StunTuple::TLS, mSocket.lowest_layer().local_endpoint().address(), mSocket.lowest_layer().local_endpoint().port()), + StunTuple(StunTuple::TLS, address, port), + (char*)&(*data)[0], data->size()); + if(request.isValid()) + { + StunMessage response; + RequestHandler::ProcessResult result = mRequestHandler.processStunMessage(this, request, response); + + switch(result) + { + case RequestHandler::NoResponseToSend: + // No response to send - just receive next message + doFramedReceive(); + return; + case RequestHandler::RespondFromAlternatePort: + case RequestHandler::RespondFromAlternateIp: + case RequestHandler::RespondFromAlternateIpPort: + // These only happen for UDP server for RFC3489 backwards compatibility + assert(false); + break; + case RequestHandler::RespondFromReceiving: + default: + break; + } +#define RESPONSE_BUFFER_SIZE 1024 + boost::shared_ptr<DataBuffer> buffer = allocateBuffer(RESPONSE_BUFFER_SIZE); + unsigned int responseSize; + responseSize = response.stunEncodeMessage((char*)buffer->data(), RESPONSE_BUFFER_SIZE); + buffer->truncate(responseSize); // set size to real size + + doSend(response.mRemoteTuple, buffer); + } + else + { + WarningLog(<< "Received invalid StunMessage. Dropping."); + } + } + else // ChannelData message + { + unsigned short channelNumber; + memcpy(&channelNumber, &(*data)[0], 2); + channelNumber = ntohs(channelNumber); + + mRequestHandler.processTurnData(channelNumber, + StunTuple(StunTuple::TLS, mSocket.lowest_layer().local_endpoint().address(), mSocket.lowest_layer().local_endpoint().port()), + StunTuple(StunTuple::TLS, address, port), + data); + } + } + else + { + WarningLog(<< "Not enough data for stun message or framed message. Closing connection."); + close(); + return; + } + + doFramedReceive(); +} + +void +TlsConnection::onReceiveFailure(const asio::error_code& e) +{ + if(e != asio::error::operation_aborted) + { + InfoLog(<< "TlsConnection::onReceiveFailure: " << e.value() << "-" << e.message()); + + close(); + } +} + +void +TlsConnection::onSendSuccess() +{ +} + +void +TlsConnection::onSendFailure(const asio::error_code& error) +{ + if(error != asio::error::operation_aborted) + { + InfoLog(<< "TlsConnection::onSendFailure: " << error.value() << "-" << error.message()); + close(); + } +} + +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TlsConnection.hxx b/src/libs/resiprocate/reTurn/TlsConnection.hxx new file mode 100644 index 00000000..73417922 --- /dev/null +++ b/src/libs/resiprocate/reTurn/TlsConnection.hxx @@ -0,0 +1,98 @@ +#ifndef TLS_CONNECTION_HXX +#define TLS_CONNECTION_HXX + +#include <asio.hpp> +#include <asio/ssl.hpp> +#include <boost/array.hpp> +#include <boost/noncopyable.hpp> +#include "RequestHandler.hxx" +#include "AsyncTlsSocketBase.hxx" + +namespace reTurn { + +class ConnectionManager; + +typedef asio::ssl::stream<asio::ip::tcp::socket> ssl_socket; + +/// Represents a single connection from a client. +class TlsConnection + : public AsyncTlsSocketBase, + private boost::noncopyable +{ +public: + /// Construct a connection with the given io_service. + explicit TlsConnection(asio::io_service& ioService, ConnectionManager& manager, RequestHandler& handler, asio::ssl::context& context); + ~TlsConnection(); + + /// Get the socket associated with the connection. + ssl_socket::lowest_layer_type& socket(); + + /// Start the first asynchronous operation for the connection. + virtual void start(); + + /// Override close fn in AsyncTcpSocketBase so that we can remove ourselves from connection manager + virtual void close(); + + /// Stop all asynchronous operations associated with the connection. + virtual void stop(); + +protected: + /// Handle completion of a handshake operation + virtual void onServerHandshakeSuccess(); + virtual void onServerHandshakeFailure(const asio::error_code& e); + + /// Handle completion of a receive operation + virtual void onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data); + virtual void onReceiveFailure(const asio::error_code& e); + + /// Handle completion of a send operation + virtual void onSendSuccess(); + virtual void onSendFailure(const asio::error_code& e); + + /// The manager for this connection. + ConnectionManager& mConnectionManager; + + /// The handler used to process the incoming request. + RequestHandler& mRequestHandler; + +private: +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TlsServer.cxx b/src/libs/resiprocate/reTurn/TlsServer.cxx new file mode 100644 index 00000000..999a5d72 --- /dev/null +++ b/src/libs/resiprocate/reTurn/TlsServer.cxx @@ -0,0 +1,121 @@ +#include "TlsServer.hxx" +#include <boost/bind.hpp> +#include <rutil/WinLeakCheck.hxx> +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +namespace reTurn { + +TlsServer::TlsServer(asio::io_service& ioService, RequestHandler& requestHandler, const asio::ip::address& address, unsigned short port) +: mIOService(ioService), + mAcceptor(ioService), + mContext(ioService, asio::ssl::context::tlsv1), // TLSv1.0 + mConnectionManager(), + mRequestHandler(requestHandler) +{ + // Set Context options + asio::error_code ec; + mContext.set_options(asio::ssl::context::default_workarounds | // Implement various bug workarounds. + asio::ssl::context::no_sslv2 | // Disable SSL v2. + asio::ssl::context::single_dh_use); // enforce recalculation of the DH key for eatch session + + mContext.set_password_callback(boost::bind(&TlsServer::getPassword, this)); + + // Use a certificate chain from a file. + mContext.use_certificate_chain_file(mRequestHandler.getConfig().mTlsServerCertificateFilename.c_str(), ec); + if(ec) + { + ErrLog(<< "Unable to load server cert chain file: " << mRequestHandler.getConfig().mTlsServerCertificateFilename << ", error=" << ec.value() << "(" << ec.message() << ")"); + } + + // Use a private key from a file. + mContext.use_private_key_file(mRequestHandler.getConfig().mTlsServerCertificateFilename.c_str(), asio::ssl::context::pem, ec); + if(ec) + { + ErrLog(<< "Unable to load server private key file: " << mRequestHandler.getConfig().mTlsServerCertificateFilename << ", error=" << ec.value() << "(" << ec.message() << ")"); + } + + // Use the specified file to obtain the temporary Diffie-Hellman parameters. + mContext.use_tmp_dh_file(mRequestHandler.getConfig().mTlsTempDhFilename.c_str(), ec); + if(ec) + { + ErrLog(<< "Unable to load temporary Diffie-Hellman parameters file: " << mRequestHandler.getConfig().mTlsTempDhFilename << ", error=" << ec.value() << "(" << ec.message() << ")"); + } + + // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). + asio::ip::tcp::endpoint endpoint(address, port); + + mAcceptor.open(endpoint.protocol()); + mAcceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true)); + mAcceptor.bind(endpoint); + mAcceptor.listen(); + + InfoLog(<< "TlsServer started. Listening on " << address.to_string() << ":" << port); +} + +void +TlsServer::start() +{ + mNewConnection.reset(new TlsConnection(mIOService, mConnectionManager, mRequestHandler, mContext)); + mAcceptor.async_accept(((TlsConnection*)mNewConnection.get())->socket(), boost::bind(&TlsServer::handleAccept, this, asio::placeholders::error)); +} + +std::string +TlsServer::getPassword() const +{ + return mRequestHandler.getConfig().mTlsPrivateKeyPassword.c_str(); +} + +void +TlsServer::handleAccept(const asio::error_code& e) +{ + if (!e) + { + mConnectionManager.start(mNewConnection); + + mNewConnection.reset(new TlsConnection(mIOService, mConnectionManager, mRequestHandler, mContext)); + mAcceptor.async_accept(((TlsConnection*)mNewConnection.get())->socket(), boost::bind(&TlsServer::handleAccept, this, asio::placeholders::error)); + } + else + { + ErrLog(<< "Error in handleAccept: " << e.value() << "-" << e.message()); + } +} + +} + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TlsServer.hxx b/src/libs/resiprocate/reTurn/TlsServer.hxx new file mode 100644 index 00000000..fb145c59 --- /dev/null +++ b/src/libs/resiprocate/reTurn/TlsServer.hxx @@ -0,0 +1,86 @@ +#ifndef TLS_SERVER_HXX +#define TLS_SERVER_HXX + +#include <asio.hpp> +#include <asio/ssl.hpp> +#include <string> +#include <boost/noncopyable.hpp> +#include "TlsConnection.hxx" +#include "ConnectionManager.hxx" +#include "RequestHandler.hxx" + +namespace reTurn { + +class TlsServer + : private boost::noncopyable +{ +public: + /// Create the server to listen on the specified TCP address and port + explicit TlsServer(asio::io_service& ioService, RequestHandler& requestHandler, const asio::ip::address& address, unsigned short port); + + void start(); + +private: + /// Handle completion of an asynchronous accept operation. + void handleAccept(const asio::error_code& e); + + /// Callback for private key password + std::string getPassword() const; + + /// The io_service used to perform asynchronous operations. + asio::io_service& mIOService; + + /// Acceptor used to listen for incoming connections. + asio::ip::tcp::acceptor mAcceptor; + + /// OpenSSL context + asio::ssl::context mContext; + + /// The connection manager which owns all live connections. + ConnectionManager mConnectionManager; + + /// The next connection to be accepted. + ConnectionPtr mNewConnection; + + /// The handler for all incoming requests. + RequestHandler& mRequestHandler; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TurnAllocation.cxx b/src/libs/resiprocate/reTurn/TurnAllocation.cxx new file mode 100644 index 00000000..f7fed23f --- /dev/null +++ b/src/libs/resiprocate/reTurn/TurnAllocation.cxx @@ -0,0 +1,290 @@ +#include <boost/bind.hpp> + +#include "TurnAllocation.hxx" +#include "TurnManager.hxx" +#include "TurnPermission.hxx" +#include "AsyncSocketBase.hxx" +#include "UdpRelayServer.hxx" +#include "RemotePeer.hxx" +#include <rutil/WinLeakCheck.hxx> +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; +using namespace resip; + +#define TURN_PERMISSION_LIFETIME_SECONDS 300 // 5 minuntes +//#define TURN_PERMISSION_LIFETIME_SECONDS 30 // TESTING only + +namespace reTurn { + +TurnAllocation::TurnAllocation(TurnManager& turnManager, + AsyncSocketBase* localTurnSocket, + const StunTuple& clientLocalTuple, + const StunTuple& clientRemoteTuple, + const StunAuth& clientAuth, + const StunTuple& requestedTuple, + unsigned int lifetime) : + mKey(clientLocalTuple, clientRemoteTuple), + mClientAuth(clientAuth), + mRequestedTuple(requestedTuple), + mTurnManager(turnManager), + mAllocationTimer(turnManager.getIOService()), + mLocalTurnSocket(localTurnSocket) +{ + InfoLog(<< "TurnAllocation created: clientLocal=" << clientLocalTuple << " clientRemote=" << + clientRemoteTuple << " allocation=" << requestedTuple << " lifetime=" << lifetime); + + refresh(lifetime); + + if(mRequestedTuple.getTransportType() == StunTuple::UDP) + { + mUdpRelayServer.reset(new UdpRelayServer(turnManager.getIOService(), *this)); + mUdpRelayServer->start(); + } + else + { + ErrLog(<< "Only UDP relay's are currently implemented!"); + assert(false); + } + + // Register for Turn Transport onDestroyed notification + mLocalTurnSocket->registerAsyncSocketBaseHandler(this); +} + +TurnAllocation::~TurnAllocation() +{ + InfoLog(<< "TurnAllocation destroyed: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple); + + // Delete Relay Servers + if(mUdpRelayServer) mUdpRelayServer->stop(); + + // Deallocate Port + mTurnManager.deallocatePort(mRequestedTuple.getTransportType(), mRequestedTuple.getPort()); + + // Cleanup Permission Memory + TurnPermissionMap::iterator it; + for(it = mTurnPermissionMap.begin(); it != mTurnPermissionMap.end(); it++) + { + delete it->second; + } + + // Unregister for TurnTransport notifications + mLocalTurnSocket->registerAsyncSocketBaseHandler(0); +} + +void +TurnAllocation::refresh(unsigned int lifetime) // update expiration time +{ + InfoLog(<< "TurnAllocation refreshed: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple << " lifetime=" << lifetime); + + mExpires = time(0) + lifetime; + + // start timer + mAllocationTimer.expires_from_now(boost::posix_time::seconds(lifetime)); + mAllocationTimer.async_wait(boost::bind(&TurnManager::allocationExpired, &mTurnManager, asio::placeholders::error, mKey)); +} + +bool +TurnAllocation::existsPermission(const asio::ip::address& address) +{ + TurnPermissionMap::iterator it = mTurnPermissionMap.find(address); + if(it != mTurnPermissionMap.end()) + { + if(it->second->isExpired()) // check if expired + { + InfoLog(<< "TurnAllocation has expired permission: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple << " exipred address=" << it->first.to_string()); + delete it->second; + mTurnPermissionMap.erase(it); + return false; + } + return true; + } + return false; +} + +void +TurnAllocation::refreshPermission(const asio::ip::address& address) +{ + TurnPermissionMap::iterator it = mTurnPermissionMap.find(address); + TurnPermission* turnPermission = 0; + if(it != mTurnPermissionMap.end()) + { + turnPermission = it->second; + } + if(!turnPermission) // create if doesn't exist + { + mTurnPermissionMap[address] = new TurnPermission(address, TURN_PERMISSION_LIFETIME_SECONDS); + InfoLog(<< "Permission for " << address.to_string() << " created: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple); + } + else + { + turnPermission->refresh(); + InfoLog(<< "Permission for " << address.to_string() << " refreshed: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple); + } +} + +void +TurnAllocation::onSocketDestroyed() +{ + mTurnManager.removeTurnAllocation(mKey); // will delete this +} + +void +TurnAllocation::sendDataToPeer(unsigned short channelNumber, boost::shared_ptr<DataBuffer>& data, bool isFramed) +{ + RemotePeer* remotePeer = mChannelManager.findRemotePeerByChannel(channelNumber); + if(remotePeer) + { + // channel found - send Data + sendDataToPeer(remotePeer->getPeerTuple(), data, isFramed); + } + else + { + WarningLog(<< "sendDataToPeer bad channel number - discarding data: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple << " channelNumber=" << channelNumber); + } +} + +void +TurnAllocation::sendDataToPeer(const StunTuple& peerAddress, boost::shared_ptr<DataBuffer>& data, bool isFramed) +{ + DebugLog(<< "TurnAllocation sendDataToPeer: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple << " peerAddress=" << peerAddress); + + if(mRequestedTuple.getTransportType() == StunTuple::UDP) + { + assert(mUdpRelayServer); + mUdpRelayServer->doSend(peerAddress, data, isFramed ? 4 /* bufferStartPos is 4 so that framing is skipped */ : 0); + } + else + { + if(data->size() <=4) + { + WarningLog(<< "Turn send indication with no data for non-UDP transport. Dropping."); + return; + } + // !SLG! TODO - implement TCP relays + assert(false); + } +} + +void +TurnAllocation::sendDataToClient(const StunTuple& peerAddress, boost::shared_ptr<DataBuffer>& data) +{ + // See if a channel binding exists - if so, use it + RemotePeer* remotePeer = mChannelManager.findRemotePeerByPeerAddress(peerAddress); + if(remotePeer) + { + // send data to local client + mLocalTurnSocket->doSend(mKey.getClientRemoteTuple(), remotePeer->getChannel(), data); + + DebugLog(<< "TurnAllocation sendDataToClient: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple << " peer=" << peerAddress << + " channelNumber=" << (int)remotePeer->getChannel()); + } + else + { + // No Channel Binding - use DataInd + StunMessage dataInd; + dataInd.createHeader(StunMessage::StunClassIndication, StunMessage::TurnDataMethod); + dataInd.mCntTurnXorPeerAddress = 1; + StunMessage::setStunAtrAddressFromTuple(dataInd.mTurnXorPeerAddress[0], peerAddress); + dataInd.setTurnData(data->data(), (unsigned int)data->size()); + + // send DataInd to local client + unsigned int bufferSize = (unsigned int)data->size() + 8 /* Stun Header */ + 36 /* Remote Address (v6) */ + 8 /* TurnData Header + potential pad */; + boost::shared_ptr<DataBuffer> buffer = AsyncSocketBase::allocateBuffer(bufferSize); + unsigned int size = dataInd.stunEncodeMessage((char*)buffer->data(), bufferSize); + buffer->truncate(size); // Set size to proper size + mLocalTurnSocket->doSend(mKey.getClientRemoteTuple(), buffer); + + DebugLog(<< "TurnAllocation sendDataToClient: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple << " peer=" << peerAddress << + " using DataInd."); + } +} + +bool +TurnAllocation::addChannelBinding(const StunTuple& peerAddress, unsigned short channelNumber) +{ + RemotePeer* remotePeer = mChannelManager.findRemotePeerByChannel(channelNumber); + if(remotePeer) + { + if(remotePeer->getPeerTuple() != peerAddress) + { + WarningLog(<< "addChannelBinding failed since channel is already in use: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple << " channelNumber=" << channelNumber << " peerAddress=" << peerAddress); + return false; + } + // refresh channel binding lifetime + remotePeer->refresh(); + + InfoLog(<< "Channel " << channelNumber << " binding to " << peerAddress << " refreshed: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple); + } + else + { + remotePeer = mChannelManager.findRemotePeerByPeerAddress(peerAddress); + if(remotePeer) + { + WarningLog(<< "addChannelBinding failed since peerAddress is alredy in use: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple << " channelNumber=" << channelNumber << " peerAddress=" << peerAddress); + return false; + } + mChannelManager.createChannelBinding(peerAddress, channelNumber); + + InfoLog(<< "Channel " << channelNumber << " binding to " << peerAddress << " created: clientLocal=" << mKey.getClientLocalTuple() << " clientRemote=" << + mKey.getClientRemoteTuple() << " allocation=" << mRequestedTuple); + } + + // Add or refresh permission + refreshPermission(peerAddress.getAddress()); + + return true; +} + + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TurnAllocation.hxx b/src/libs/resiprocate/reTurn/TurnAllocation.hxx new file mode 100644 index 00000000..116e0c47 --- /dev/null +++ b/src/libs/resiprocate/reTurn/TurnAllocation.hxx @@ -0,0 +1,121 @@ +#ifndef TURNALLOCATION_HXX +#define TURNALLOCATION_HXX + +#include <map> +#include <boost/noncopyable.hpp> +#include <asio.hpp> + +#include "StunTuple.hxx" +#include "StunAuth.hxx" +#include "TurnAllocationKey.hxx" +#include "AsyncSocketBaseHandler.hxx" +#include "DataBuffer.hxx" +#include "ChannelManager.hxx" + +namespace reTurn { + +class TurnPermission; +class TurnManager; +class AsyncSocketBase; +class UdpRelayServer; + +class TurnAllocation + : public AsyncSocketBaseHandler, + private boost::noncopyable +{ +public: + explicit TurnAllocation(TurnManager& turnManager, + AsyncSocketBase* localTurnSocket, + const StunTuple& clientLocalTuple, + const StunTuple& clientRemoteTuple, + const StunAuth& clientAuth, + const StunTuple& requestedTuple, + unsigned int lifetime); + ~TurnAllocation(); + + const TurnAllocationKey& getKey() { return mKey; } + void refresh(unsigned int lifetime); // update expiration time + + // checks if the permission exists or not - also checks for expired + // permissions + bool existsPermission(const asio::ip::address& address); + + // create Permission if not present, otherwise refresh permission timer + void refreshPermission(const asio::ip::address& address); + + // this get's called when being notified that the socket that the allocation came from + // has been destroyed + void onSocketDestroyed(); + + // Used when framed data is received from client, to forward data to peer + void sendDataToPeer(unsigned short channelNumber, boost::shared_ptr<DataBuffer>& data, bool isFramed); + // Used when Send Indication is received from client, to forward data to peer + void sendDataToPeer(const StunTuple& peerAddress, boost::shared_ptr<DataBuffer>& data, bool isFramed); + // Used when Data is received from peer, to forward data to client + void sendDataToClient(const StunTuple& peerAddress, boost::shared_ptr<DataBuffer>& data); + + // Called when a ChannelBind Request is received + bool addChannelBinding(const StunTuple& peerAddress, unsigned short channelNumber); + + const StunTuple& getRequestedTuple() const { return mRequestedTuple; } + time_t getExpires() const { return mExpires; } + const StunAuth& getClientAuth() const { return mClientAuth; } + +private: + TurnAllocationKey mKey; // contains ClientLocalTuple and clientRemoteTuple + StunAuth mClientAuth; + StunTuple mRequestedTuple; + + time_t mExpires; + //unsigned int mBandwidth; // future use + + typedef std::map<asio::ip::address,TurnPermission*> TurnPermissionMap; + TurnPermissionMap mTurnPermissionMap; + + TurnManager& mTurnManager; + asio::deadline_timer mAllocationTimer; + + AsyncSocketBase* mLocalTurnSocket; + boost::shared_ptr<UdpRelayServer> mUdpRelayServer; + + ChannelManager mChannelManager; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TurnAllocationKey.cxx b/src/libs/resiprocate/reTurn/TurnAllocationKey.cxx new file mode 100644 index 00000000..ef220d97 --- /dev/null +++ b/src/libs/resiprocate/reTurn/TurnAllocationKey.cxx @@ -0,0 +1,77 @@ +#include "TurnAllocationKey.hxx" +#include "StunTuple.hxx" + +using namespace std; + +namespace reTurn { + +TurnAllocationKey::TurnAllocationKey(const StunTuple& clientLocalTuple, + const StunTuple& clientRemoteTuple) : + mClientLocalTuple(clientLocalTuple), + mClientRemoteTuple(clientRemoteTuple) +{ +} + +bool +TurnAllocationKey::operator==(const TurnAllocationKey& rhs) const +{ + return mClientLocalTuple == rhs.mClientLocalTuple && mClientRemoteTuple == rhs.mClientRemoteTuple; +} + +bool +TurnAllocationKey::operator!=(const TurnAllocationKey& rhs) const +{ + return mClientLocalTuple != rhs.mClientLocalTuple || mClientRemoteTuple != rhs.mClientRemoteTuple; +} + +bool +TurnAllocationKey::operator<(const TurnAllocationKey& rhs) const +{ + if (mClientLocalTuple < rhs.mClientLocalTuple) + { + return true; + } + if (mClientLocalTuple == rhs.mClientLocalTuple) + { + return mClientRemoteTuple < rhs.mClientRemoteTuple; + } + return false; +} + + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TurnAllocationKey.hxx b/src/libs/resiprocate/reTurn/TurnAllocationKey.hxx new file mode 100644 index 00000000..0a981f57 --- /dev/null +++ b/src/libs/resiprocate/reTurn/TurnAllocationKey.hxx @@ -0,0 +1,65 @@ +#ifndef TURNALLOCATIONKEY_HXX +#define TURNALLOCATIONKEY_HXX + +#include "StunTuple.hxx" + +namespace reTurn { + +class StunTuple; + +class TurnAllocationKey +{ +public: + explicit TurnAllocationKey(const StunTuple& clientLocalTuple, + const StunTuple& clientRemoteTuple); + + bool operator==(const TurnAllocationKey& rhs) const; + bool operator!=(const TurnAllocationKey& rhs) const; + bool operator<(const TurnAllocationKey& rhs) const; + + const StunTuple& getClientLocalTuple() const { return mClientLocalTuple; } + const StunTuple& getClientRemoteTuple() const { return mClientRemoteTuple; } + +private: + StunTuple mClientLocalTuple; + StunTuple mClientRemoteTuple; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TurnManager.cxx b/src/libs/resiprocate/reTurn/TurnManager.cxx new file mode 100644 index 00000000..062f10e7 --- /dev/null +++ b/src/libs/resiprocate/reTurn/TurnManager.cxx @@ -0,0 +1,294 @@ +#include <rutil/Lock.hxx> + +#include "TurnManager.hxx" +#include "TurnAllocation.hxx" +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; + +namespace reTurn { + +TurnManager::TurnManager(asio::io_service& ioService, const ReTurnConfig& config) : + mLastAllocatedUdpPort(config.mAllocationPortRangeMin-1), + mLastAllocatedTcpPort(config.mAllocationPortRangeMin-1), + mIOService(ioService), + mConfig(config) +{ + // Initialize Allocation Ports + for(unsigned short i = config.mAllocationPortRangeMin; i <= config.mAllocationPortRangeMax && i != 0; i++) // i != 0 catches case where we increment 65535 (as an unsigned short) + { + mUdpAllocationPorts[i] = PortStateUnallocated; + mTcpAllocationPorts[i] = PortStateUnallocated; + } +} + +TurnManager::~TurnManager() +{ + TurnAllocationMap::iterator it = mTurnAllocationMap.begin(); + for(;it != mTurnAllocationMap.end();it++) + { + delete it->second; + } + + InfoLog(<< "Turn Manager destroyed."); +} + +void +TurnManager::addTurnAllocation(TurnAllocation* turnAllocation) +{ + assert(findTurnAllocation(turnAllocation->getKey()) == 0); + mTurnAllocationMap[turnAllocation->getKey()] = turnAllocation; +} + +void +TurnManager::removeTurnAllocation(const TurnAllocationKey& turnAllocationKey) +{ + TurnAllocationMap::iterator it = mTurnAllocationMap.find(turnAllocationKey); + if(it != mTurnAllocationMap.end()) + { + delete it->second; + mTurnAllocationMap.erase(it); + } +} + +TurnAllocation* +TurnManager::findTurnAllocation(const TurnAllocationKey& turnAllocationKey) +{ + TurnAllocationMap::iterator it = mTurnAllocationMap.find(turnAllocationKey); + if(it != mTurnAllocationMap.end()) + { + return it->second; + } + return 0; +} + +TurnAllocation* +TurnManager::findTurnAllocation(const StunTuple& requestedTuple) +{ + TurnAllocationMap::iterator it; + for(it = mTurnAllocationMap.begin(); it != mTurnAllocationMap.end(); it++) + { + if(it->second->getRequestedTuple() == requestedTuple) + { + return it->second; + } + } + return 0; +} + +void +TurnManager::allocationExpired(const asio::error_code& e, const TurnAllocationKey& turnAllocationKey) +{ + if (e != asio::error::operation_aborted) // Note: nothing currently stops timers + { + // Timer was not cancelled, take necessary action. + InfoLog(<< "Turn Allocation Expired! clientLocal=" << turnAllocationKey.getClientLocalTuple() << " clientRemote=" << turnAllocationKey.getClientRemoteTuple()); + + TurnAllocationMap::iterator it = mTurnAllocationMap.find(turnAllocationKey); + if(it != mTurnAllocationMap.end()) + { + if(time(0) >= it->second->getExpires()) + { + delete it->second; + mTurnAllocationMap.erase(it); + } + } + } +} + +unsigned short +TurnManager::allocateAnyPort(StunTuple::TransportType transport) +{ + PortAllocationMap& portAllocationMap = getPortAllocationMap(transport); + unsigned short startPortToCheck = advanceLastAllocatedPort(transport); + unsigned short portToCheck = startPortToCheck; + while(portAllocationMap[portToCheck] != PortStateUnallocated) + { + portToCheck = advanceLastAllocatedPort(transport); + if(portToCheck == startPortToCheck) return 0; // If we checked all available ports and none found - then return 0 + } + portAllocationMap[portToCheck] = PortStateAllocated; + return portToCheck; +} + +unsigned short +TurnManager::allocateEvenPort(StunTuple::TransportType transport) +{ + PortAllocationMap& portAllocationMap = getPortAllocationMap(transport); + unsigned short startPortToCheck = advanceLastAllocatedPort(transport); + // Ensure start port is even + if(startPortToCheck % 2 != 0) + { + startPortToCheck = advanceLastAllocatedPort(transport); + } + unsigned short portToCheck = startPortToCheck; + while(portAllocationMap[portToCheck] != PortStateUnallocated) + { + portToCheck = advanceLastAllocatedPort(transport, 2); + if(portToCheck == startPortToCheck) return 0; // If we checked all available ports and none found - then return 0 + } + portAllocationMap[portToCheck] = PortStateAllocated; + return portToCheck; +} + +// Note: This is not used, since requesting an odd port was removed +unsigned short +TurnManager::allocateOddPort(StunTuple::TransportType transport) +{ + PortAllocationMap& portAllocationMap = getPortAllocationMap(transport); + unsigned short startPortToCheck = advanceLastAllocatedPort(transport); + // Ensure start port is odd + if(startPortToCheck % 2 != 1) + { + startPortToCheck = advanceLastAllocatedPort(transport); + } + unsigned short portToCheck = startPortToCheck; + while(portAllocationMap[portToCheck] != PortStateUnallocated) + { + portToCheck = advanceLastAllocatedPort(transport, 2); + if(portToCheck == startPortToCheck) return 0; // If we checked all available ports and none found - then return 0 + } + portAllocationMap[portToCheck] = PortStateAllocated; + return portToCheck; +} + +unsigned short +TurnManager::allocateEvenPortPair(StunTuple::TransportType transport) +{ + PortAllocationMap& portAllocationMap = getPortAllocationMap(transport); + unsigned short startPortToCheck = advanceLastAllocatedPort(transport); + // Ensure start port is even + if(startPortToCheck % 2 != 0) + { + startPortToCheck = advanceLastAllocatedPort(transport); + } + unsigned short portToCheck = startPortToCheck; + while(portAllocationMap[portToCheck] != PortStateUnallocated || portAllocationMap[portToCheck+1] != PortStateUnallocated) + { + portToCheck = advanceLastAllocatedPort(transport, 2); + if(portToCheck == startPortToCheck) return 0; // If we checked all available ports and none found - then return 0 + } + portAllocationMap[portToCheck] = PortStateAllocated; + portAllocationMap[portToCheck+1] = PortStateReserved; + return portToCheck; +} + +bool +TurnManager::allocatePort(StunTuple::TransportType transport, unsigned short port, bool reserved) +{ + if(port >= mConfig.mAllocationPortRangeMin && port <= mConfig.mAllocationPortRangeMax) + { + PortAllocationMap& portAllocationMap = getPortAllocationMap(transport); + if(reserved) + { + if(portAllocationMap[port] == PortStateReserved) + { + portAllocationMap[port] = PortStateAllocated; + return true; + } + } + else + { + if(portAllocationMap[port] == PortStateUnallocated) + { + portAllocationMap[port] = PortStateAllocated; + return true; + } + } + } + return false; +} + +void +TurnManager::deallocatePort(StunTuple::TransportType transport, unsigned short port) +{ + if(port >= mConfig.mAllocationPortRangeMin && port <= mConfig.mAllocationPortRangeMax) + { + PortAllocationMap& portAllocationMap = getPortAllocationMap(transport); + portAllocationMap[port] = PortStateUnallocated; + + // If port is even - check if next higher port is reserved - if so unallocate it + if(port % 2 == 0 && portAllocationMap[port+1] == PortStateReserved) + { + portAllocationMap[port+1] = PortStateUnallocated; + } + } +} + +TurnManager::PortAllocationMap& +TurnManager::getPortAllocationMap(StunTuple::TransportType transport) +{ + switch(transport) + { + case StunTuple::TCP: + case StunTuple::TLS: + return mTcpAllocationPorts; + case StunTuple::UDP: + default: + return mUdpAllocationPorts; + } +} + +unsigned short +TurnManager::advanceLastAllocatedPort(StunTuple::TransportType transport, unsigned int numToAdvance) +{ + switch(transport) + { + case StunTuple::TCP: + case StunTuple::TLS: + mLastAllocatedTcpPort+=numToAdvance; + if(mLastAllocatedTcpPort > mConfig.mAllocationPortRangeMax) + { + mLastAllocatedTcpPort = mConfig.mAllocationPortRangeMin+(mLastAllocatedTcpPort-mConfig.mAllocationPortRangeMax-1); + } + return mLastAllocatedTcpPort; + case StunTuple::UDP: + default: + mLastAllocatedUdpPort+=numToAdvance; + if(mLastAllocatedUdpPort > mConfig.mAllocationPortRangeMax) + { + mLastAllocatedUdpPort = mConfig.mAllocationPortRangeMin+(mLastAllocatedUdpPort-mConfig.mAllocationPortRangeMax-1); + } + return mLastAllocatedUdpPort; + } +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TurnManager.hxx b/src/libs/resiprocate/reTurn/TurnManager.hxx new file mode 100644 index 00000000..7e44b26d --- /dev/null +++ b/src/libs/resiprocate/reTurn/TurnManager.hxx @@ -0,0 +1,100 @@ +#ifndef TURNMANAGER_HXX +#define TURNMANAGER_HXX + +#include <map> +#include <asio.hpp> +#include "TurnAllocationKey.hxx" +#include "ReTurnConfig.hxx" +#include "StunTuple.hxx" + +namespace reTurn { + +class TurnAllocation; + +class TurnManager +{ +public: + explicit TurnManager(asio::io_service& ioService, const ReTurnConfig& config); // ioService used to start timers + ~TurnManager(); + + void addTurnAllocation(TurnAllocation* turnAllocation); + void removeTurnAllocation(const TurnAllocationKey& turnAllocationKey); + + void startAllocationExpirationTimer(const TurnAllocationKey& turnAllocationKey, int lifetime); + + TurnAllocation* findTurnAllocation(const TurnAllocationKey& turnAllocationKey); + TurnAllocation* findTurnAllocation(const StunTuple& requestedTuple); + + asio::io_service& getIOService() { return mIOService; } + + void allocationExpired(const asio::error_code& e, const TurnAllocationKey& turnAllocationKey); + + unsigned short allocateAnyPort(StunTuple::TransportType transport); + unsigned short allocateEvenPort(StunTuple::TransportType transport); + unsigned short allocateOddPort(StunTuple::TransportType transport); + unsigned short allocateEvenPortPair(StunTuple::TransportType transport); + bool allocatePort(StunTuple::TransportType transport, unsigned short port, bool reserved = false); + void deallocatePort(StunTuple::TransportType transport, unsigned short port); + + const ReTurnConfig& getConfig() { return mConfig; } + +private: + typedef std::map<TurnAllocationKey, TurnAllocation*> TurnAllocationMap; // .slg. consider using hash table + TurnAllocationMap mTurnAllocationMap; + + typedef enum + { + PortStateUnallocated, + PortStateAllocated, + PortStateReserved + } PortState; + typedef std::map<unsigned short, PortState> PortAllocationMap; + PortAllocationMap mUdpAllocationPorts; // .slg. expand to be a map/hash table per ip address/interface + PortAllocationMap mTcpAllocationPorts; + unsigned short mLastAllocatedUdpPort; + unsigned short mLastAllocatedTcpPort; + PortAllocationMap& getPortAllocationMap(StunTuple::TransportType transport); + unsigned short advanceLastAllocatedPort(StunTuple::TransportType transport, unsigned int numToAdvance = 1); + + asio::io_service& mIOService; + const ReTurnConfig& mConfig; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TurnPermission.cxx b/src/libs/resiprocate/reTurn/TurnPermission.cxx new file mode 100644 index 00000000..86916217 --- /dev/null +++ b/src/libs/resiprocate/reTurn/TurnPermission.cxx @@ -0,0 +1,65 @@ +#include "TurnPermission.hxx" + +using namespace std; + +namespace reTurn { + +TurnPermission::TurnPermission(const asio::ip::address& address, unsigned int timeoutSeconds) : + mAddress(address), + mExpires(time(0)+timeoutSeconds), + mTimeoutSeconds(timeoutSeconds) +{ +} + +void +TurnPermission::refresh() +{ + mExpires = time(0)+mTimeoutSeconds; +} + +bool +TurnPermission::isExpired() +{ + if(time(0) > mExpires) + { + return true; + } + return false; +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/TurnPermission.hxx b/src/libs/resiprocate/reTurn/TurnPermission.hxx new file mode 100644 index 00000000..66bee376 --- /dev/null +++ b/src/libs/resiprocate/reTurn/TurnPermission.hxx @@ -0,0 +1,61 @@ +#ifndef TURNPERMISSION_HXX +#define TURNPERMISSION_HXX + +#include <asio.hpp> + +#include "StunTuple.hxx" + +namespace reTurn { + +class TurnPermission +{ +public: + explicit TurnPermission(const asio::ip::address& address, unsigned int timeoutSeconds); + + void refresh(); + bool isExpired(); + +private: + asio::ip::address mAddress; // we want to accept incoming requests (including connections) from any peer with this address + time_t mExpires; + unsigned int mTimeoutSeconds; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/UdpRelayServer.cxx b/src/libs/resiprocate/reTurn/UdpRelayServer.cxx new file mode 100644 index 00000000..f65e0fb1 --- /dev/null +++ b/src/libs/resiprocate/reTurn/UdpRelayServer.cxx @@ -0,0 +1,137 @@ +#include <boost/bind.hpp> + +#include "UdpRelayServer.hxx" +#include "StunMessage.hxx" +#include "TurnAllocation.hxx" +#include "StunTuple.hxx" +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; + +namespace reTurn { + +UdpRelayServer::UdpRelayServer(asio::io_service& ioService, TurnAllocation& turnAllocation) +: AsyncUdpSocketBase(ioService), + mTurnAllocation(turnAllocation), + mStopping(false) +{ + InfoLog(<< "UdpRelayServer started. Listening on " << mTurnAllocation.getRequestedTuple().getAddress().to_string() << ":" << mTurnAllocation.getRequestedTuple().getPort()); + + bind(turnAllocation.getRequestedTuple().getAddress(), turnAllocation.getRequestedTuple().getPort()); +} + +UdpRelayServer::~UdpRelayServer() +{ + DebugLog(<< "~UdpRelayServer - destroyed"); +} + +void +UdpRelayServer::start() +{ + // Note: This function is required, since you cannot call shared_from_this in the constructor: shared_from_this requires that at least one shared ptr exists already + doReceive(); +} + +void +UdpRelayServer::stop() +{ + asio::error_code ec; + mStopping = true; + mSocket.close(ec); +} + +void +UdpRelayServer::onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) +{ + if(mStopping) + { + return; + } + if (data->size() > 0) + { + DebugLog(<< "Read " << (int)data->size() << " bytes from udp relay socket (" << address.to_string() << ":" << port << "): "); + /* + cout << std::hex; + for(int i = 0; i < (int)data->size(); i++) + { + std::cout << (char)(*data)[i] << "(" << int((*data)[i]) << ") "; + } + std::cout << std::dec << std::endl; + */ + + // If no permission then just drop packet + if(mTurnAllocation.existsPermission(address)) + { + // If active destination is not set, then send to client as a DataInd, otherwise send packet as is + mTurnAllocation.sendDataToClient(StunTuple(StunTuple::UDP, address, port), data); + } + else + { + InfoLog(<< "No permission for " << address.to_string() << " dropping data."); + } + } + doReceive(); +} + +void +UdpRelayServer::onReceiveFailure(const asio::error_code& e) +{ + if(!mStopping && e != asio::error::operation_aborted && e != asio::error::bad_descriptor) + { + doReceive(); + } +} + +void +UdpRelayServer::onSendSuccess() +{ +} + +void +UdpRelayServer::onSendFailure(const asio::error_code& error) +{ + if(!mStopping && error != asio::error::operation_aborted) + { + WarningLog(<< "UdpRelayServer::onSendFailure: " << error.value() << "-" << error.message()); + } +} + +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/UdpRelayServer.hxx b/src/libs/resiprocate/reTurn/UdpRelayServer.hxx new file mode 100644 index 00000000..b0bc7db7 --- /dev/null +++ b/src/libs/resiprocate/reTurn/UdpRelayServer.hxx @@ -0,0 +1,81 @@ +#ifndef UDP_RELAY_SERVER_HXX +#define UDP_REALY_SERVER_HXX + +#include <asio.hpp> +#include <string> +#include <boost/noncopyable.hpp> +#include "RequestHandler.hxx" +#include "AsyncUdpSocketBase.hxx" + +namespace reTurn { + +class StunTuple; + +class UdpRelayServer + : public AsyncUdpSocketBase, + private boost::noncopyable +{ +public: + /// Create the server to listen on the specified UDP address and port + explicit UdpRelayServer(asio::io_service& ioService, TurnAllocation& turnAllocation); + ~UdpRelayServer(); + + /// Starts processing + void start(); + + /// Causes this object to destroy itself safely (ie. waiting for ayncronous callbacks to finish) + void stop(); + +private: + /// Handle completion of a receive_from operation + virtual void onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data); + virtual void onReceiveFailure(const asio::error_code& e); + + /// Handle completion of a send operation + virtual void onSendSuccess(); + virtual void onSendFailure(const asio::error_code& e); + + TurnAllocation& mTurnAllocation; + bool mStopping; +}; + +typedef boost::shared_ptr<UdpRelayServer> UdpRelayServerPtr; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/UdpServer.cxx b/src/libs/resiprocate/reTurn/UdpServer.cxx new file mode 100644 index 00000000..2cc126c3 --- /dev/null +++ b/src/libs/resiprocate/reTurn/UdpServer.cxx @@ -0,0 +1,263 @@ +#include "UdpServer.hxx" +#include "StunMessage.hxx" +#include <boost/bind.hpp> +#include <rutil/WinLeakCheck.hxx> +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; +using namespace resip; + +namespace reTurn { + +UdpServer::UdpServer(asio::io_service& ioService, RequestHandler& requestHandler, const asio::ip::address& address, unsigned short port) +: AsyncUdpSocketBase(ioService), + mRequestHandler(requestHandler), + mAlternatePortUdpServer(0), + mAlternateIpUdpServer(0), + mAlternateIpPortUdpServer(0) +{ + asio::error_code ec = bind(address, port); + if(ec) + { + ErrLog(<< "Unable to start UdpServer listening on " << address.to_string() << ":" << port << ", error=" << ec.value() << " - " << ec.message()); + } + else + { + InfoLog(<< "UdpServer started. Listening on " << address.to_string() << ":" << port); + } +} + +UdpServer::~UdpServer() +{ + ResponseMap::iterator it = mResponseMap.begin(); + for(;it != mResponseMap.end(); it++) + { + delete it->second; + } + mResponseMap.clear(); +} + +void +UdpServer::start() +{ + doReceive(); +} + +void +UdpServer::setAlternateUdpServers(UdpServer* alternatePort, UdpServer* alternateIp, UdpServer* alternateIpPort) +{ + assert(!mAlternatePortUdpServer); + assert(!mAlternateIpUdpServer); + assert(!mAlternateIpPortUdpServer); + mAlternatePortUdpServer = alternatePort; + mAlternateIpUdpServer = alternateIp; + mAlternateIpPortUdpServer = alternateIpPort; +} + +bool +UdpServer::isRFC3489BackwardsCompatServer() +{ + return mAlternatePortUdpServer != 0; // Just check that any of the alternate servers is populated - if so, we are running in back compat mode +} + +asio::ip::udp::socket& +UdpServer::getSocket() +{ + return mSocket; +} + +void +UdpServer::onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) +{ + if (data->size() > 4) + { + /* + std::cout << "Read " << bytesTransferred << " bytes from udp socket (" << address.to_string() << ":" << port << "): " << std::endl; + cout << std::hex; + for(int i = 0; i < data->size(); i++) + { + std::cout << (char)(*data)[i] << "(" << int((*data)[i]) << ") "; + } + std::cout << std::dec << std::endl; + */ + + if(((*data)[0] & 0xC0) == 0) // Stun/Turn Messages always have bits 0 and 1 as 00 - otherwise ChannelData message + { + // Try to parse stun message + StunMessage request(StunTuple(StunTuple::UDP, mSocket.local_endpoint().address(), mSocket.local_endpoint().port()), + StunTuple(StunTuple::UDP, address, port), + (char*)&(*data)[0], data->size()); + if(request.isValid()) + { + StunMessage* response; + UdpServer* responseUdpServer; + ResponseMap::iterator it = mResponseMap.find(request.mHeader.magicCookieAndTid); + if(it == mResponseMap.end()) + { + response = new StunMessage; + RequestHandler::ProcessResult result = mRequestHandler.processStunMessage(this, request, *response, isRFC3489BackwardsCompatServer()); + + switch(result) + { + case RequestHandler::NoResponseToSend: + // No response to send - just receive next message + delete response; + doReceive(); + return; + case RequestHandler::RespondFromAlternatePort: + responseUdpServer = mAlternatePortUdpServer; + break; + case RequestHandler::RespondFromAlternateIp: + responseUdpServer = mAlternateIpUdpServer; + break; + case RequestHandler::RespondFromAlternateIpPort: + responseUdpServer = mAlternateIpPortUdpServer; + break; + case RequestHandler::RespondFromReceiving: + default: + responseUdpServer = this; + break; + } + + // Store response in Map - to be resent if a retranmission is received + mResponseMap[response->mHeader.magicCookieAndTid] = new ResponseEntry(this, responseUdpServer, response); + } + else + { + InfoLog(<< "UdpServer: received retransmission of request with tid: " << request.mHeader.magicCookieAndTid); + response = it->second->mResponseMessage; + responseUdpServer = it->second->mResponseUdpServer; + } + +#define RESPONSE_BUFFER_SIZE 1024 + boost::shared_ptr<DataBuffer> buffer = allocateBuffer(RESPONSE_BUFFER_SIZE); + unsigned int responseSize; + responseSize = response->stunEncodeMessage((char*)buffer->data(), RESPONSE_BUFFER_SIZE); + buffer->truncate(responseSize); // set size to real size + + responseUdpServer->doSend(response->mRemoteTuple, buffer); + } + } + else // ChannelData message + { + unsigned short channelNumber; + memcpy(&channelNumber, &(*data)[0], 2); + channelNumber = ntohs(channelNumber); + + unsigned short dataLen; + memcpy(&dataLen, &(*data)[2], 2); + dataLen = ntohs(dataLen); + + // Check if the UDP datagram size is too short to contain the claimed length of the ChannelData message, then discard + if(data->size() < dataLen + 4) + { + WarningLog(<< "ChannelData message size=" << dataLen+4 << " too larger for UDP packet size=" << data->size() <<". Dropping."); + } + else + { + mRequestHandler.processTurnData(channelNumber, + StunTuple(StunTuple::UDP, mSocket.local_endpoint().address(), mSocket.local_endpoint().port()), + StunTuple(StunTuple::UDP, address, port), + data); + } + } + } + else + { + WarningLog(<< "Not enough data for stun message or framed message. Dropping."); + } + + doReceive(); +} + +void +UdpServer::onReceiveFailure(const asio::error_code& e) +{ + if(e != asio::error::operation_aborted) + { + InfoLog(<< "UdpServer::onReceiveFailure: " << e.value() << "-" << e.message()); + + doReceive(); + } +} + +void +UdpServer::onSendSuccess() +{ +} + +void +UdpServer::onSendFailure(const asio::error_code& error) +{ + if(error != asio::error::operation_aborted) + { + InfoLog(<< "UdpServer::onSendFailure: " << error.value() << "-" << error.message()); + } +} + +UdpServer::ResponseEntry::ResponseEntry(UdpServer* requestUdpServer, UdpServer* responseUdpServer, StunMessage* responseMessage) : + mResponseUdpServer(responseUdpServer), + mResponseMessage(responseMessage), + mCleanupTimer(requestUdpServer->mIOService) +{ + // start timer + mCleanupTimer.expires_from_now(boost::posix_time::seconds(10)); // Transaction Responses are cached for 10 seconds + mCleanupTimer.async_wait(boost::bind(&UdpServer::cleanupResponseMap, requestUdpServer, asio::placeholders::error, responseMessage->mHeader.magicCookieAndTid)); +} + +UdpServer::ResponseEntry::~ResponseEntry() +{ + delete mResponseMessage; +} + +void +UdpServer::cleanupResponseMap(const asio::error_code& e, UInt128 tid) +{ + ResponseMap::iterator it = mResponseMap.find(tid); + if(it != mResponseMap.end()) + { + DebugLog(<< "UdpServer::cleanupResponseMap - removing transaction id=" << tid); + delete it->second; + mResponseMap.erase(it); + } +} + +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/UdpServer.hxx b/src/libs/resiprocate/reTurn/UdpServer.hxx new file mode 100644 index 00000000..05fc9004 --- /dev/null +++ b/src/libs/resiprocate/reTurn/UdpServer.hxx @@ -0,0 +1,103 @@ +#ifndef UDP_SERVER_HXX +#define UDP_SERVER_HXX + +#include <asio.hpp> +#include <string> +#include <boost/noncopyable.hpp> +#include "RequestHandler.hxx" +#include "AsyncUdpSocketBase.hxx" + +namespace reTurn { + +class StunMessage; + +class UdpServer + : public AsyncUdpSocketBase, + private boost::noncopyable +{ +public: + /// Create the server to listen on the specified UDP address and port + explicit UdpServer(asio::io_service& ioService, RequestHandler& requestHandler, const asio::ip::address& address, unsigned short port); + ~UdpServer(); + + void start(); + + /// This method is used if this UdpServer supports RFC3489 operation - note turnFraming in contructor must be false + void setAlternateUdpServers(UdpServer* alternatePort, UdpServer* alternateIp, UdpServer* alternateIpPort); + bool isRFC3489BackwardsCompatServer(); + + ///// Returns the socket for this server + asio::ip::udp::socket& getSocket(); + + void cleanupResponseMap(const asio::error_code& e, UInt128 tid); + +private: + /// Handle completion of a receive operation + virtual void onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data); + virtual void onReceiveFailure(const asio::error_code& e); + + /// Handle completion of a send operation + virtual void onSendSuccess(); + virtual void onSendFailure(const asio::error_code& e); + + /// The handler for all incoming requests. + RequestHandler& mRequestHandler; + + /// The RFC3489 Alternate Server + UdpServer* mAlternatePortUdpServer; + UdpServer* mAlternateIpUdpServer; + UdpServer* mAlternateIpPortUdpServer; + + // Response map (for retransmissions) + class ResponseEntry + { + public: + ResponseEntry(UdpServer* requestUdpServer, UdpServer* responseUdpServer, StunMessage* responseMessage); + ~ResponseEntry(); + + UdpServer* mResponseUdpServer; + StunMessage* mResponseMessage; + asio::deadline_timer mCleanupTimer; + }; + typedef std::map<UInt128, ResponseEntry*> ResponseMap; + ResponseMap mResponseMap; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/UserAuthData.cxx b/src/libs/resiprocate/reTurn/UserAuthData.cxx new file mode 100644 index 00000000..30ac1ad6 --- /dev/null +++ b/src/libs/resiprocate/reTurn/UserAuthData.cxx @@ -0,0 +1,69 @@ +#include "UserAuthData.hxx" + +#include <rutil/MD5Stream.hxx> + +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; +using namespace resip; + +namespace reTurn { + +UserAuthData::UserAuthData(const resip::Data& userName, const resip::Data& realm, const resip::Data& ha1) : + mUserName(userName), + mRealm(realm), + mHa1(ha1) +{ +} + +UserAuthData::~UserAuthData() +{ +} + +UserAuthData +UserAuthData::createFromPassword(const resip::Data& userName, const resip::Data& realm, const resip::Data& password) +{ + MD5Stream r; + r << userName << ":" << realm << ":" << password; + Data ha1(r.getBin()); + return UserAuthData(userName, realm, ha1); +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2012, Ready Technology (UK) Limited + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Ready Technology nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/UserAuthData.hxx b/src/libs/resiprocate/reTurn/UserAuthData.hxx new file mode 100644 index 00000000..fd21a020 --- /dev/null +++ b/src/libs/resiprocate/reTurn/UserAuthData.hxx @@ -0,0 +1,64 @@ +#if !defined(USER_AUTH_DATA_HXX) +#define USER_AUTH_DATA_HXX + +#include <rutil/Data.hxx> +#include <rutil/Log.hxx> + +namespace reTurn { + +class UserAuthData +{ +public: + UserAuthData(const resip::Data& userName, const resip::Data& realm, const resip::Data& ha1); + virtual ~UserAuthData(); + + static UserAuthData createFromPassword(const resip::Data& userName, const resip::Data& realm, const resip::Data& password); + + resip::Data getUserName() { return mUserName; }; + resip::Data getRealm() { return mRealm; }; + resip::Data getHa1() { return mHa1; }; + +private: + resip::Data mUserName; + resip::Data mRealm; + resip::Data mHa1; +}; + +} // namespace + +#endif + + +/* ==================================================================== + + Copyright (c) 2012, Ready Technology (UK) Limited + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Ready Technology nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/ErrorCode.hxx b/src/libs/resiprocate/reTurn/client/ErrorCode.hxx new file mode 100644 index 00000000..754a82f6 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/ErrorCode.hxx @@ -0,0 +1,69 @@ +#ifndef ERRORCODE_HXX +#define ERRORCODE_HXX + +#include <asio/error_code.hpp> + +namespace reTurn { + +typedef asio::error_code::value_type ErrorType; + +static const ErrorType Success = 0; +static const ErrorType GeneralError = -1; + +static const ErrorType ErrorBase = 8000; + +static const ErrorType MissingAuthenticationAttributes = ErrorBase + 1; +static const ErrorType BufferTooSmall = ErrorBase + 2; +static const ErrorType BadMessageIntegrity = ErrorBase + 3; +static const ErrorType ErrorParsingMessage = ErrorBase + 4; +static const ErrorType NoAllocation = ErrorBase + 5; +static const ErrorType NoActiveDestination = ErrorBase + 6; +static const ErrorType ReadError = ErrorBase + 7; +static const ErrorType ResponseTimeout = ErrorBase + 8; +static const ErrorType FrameError = ErrorBase + 9; +static const ErrorType InvalidChannelNumberReceived = ErrorBase + 10; +static const ErrorType MissingAttributes = ErrorBase + 11; +static const ErrorType UnknownRemoteAddress = ErrorBase + 12; +static const ErrorType InvalidRequestedTransport = ErrorBase + 13; +static const ErrorType NotConnected = ErrorBase + 14; +static const ErrorType AlreadyAllocated = ErrorBase + 15; +static const ErrorType StrayResponse = ErrorBase + 16; +static const ErrorType UnknownRequiredAttributes = ErrorBase + 17; +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/Makefile b/src/libs/resiprocate/reTurn/client/Makefile new file mode 100644 index 00000000..d963f60f --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/Makefile @@ -0,0 +1,64 @@ +BUILD := ../../build +include $(BUILD)/Makefile.pre + +PACKAGES += ASIO RUTIL ARES OPENSSL BOOST PTHREAD +TARGET_LIBRARY = libreTurnClient + +SRC += \ + ../AsyncSocketBase.cxx \ + ../AsyncTcpSocketBase.cxx \ + ../AsyncTlsSocketBase.cxx \ + ../AsyncUdpSocketBase.cxx \ + ../ChannelManager.cxx \ + ../DataBuffer.cxx \ + ../RemotePeer.cxx \ + ../ReTurnSubsystem.cxx \ + ../StunMessage.cxx \ + ../StunTuple.cxx \ + TurnAsyncSocket.cxx \ + TurnAsyncSocketHandler.cxx \ + TurnAsyncTcpSocket.cxx \ + TurnAsyncTlsSocket.cxx \ + TurnAsyncUdpSocket.cxx \ + TurnSocket.cxx \ + TurnTcpSocket.cxx \ + TurnTlsSocket.cxx \ + TurnUdpSocket.cxx + + +include $(BUILD)/Makefile.post + + +#################################################################### +# +# Copyright (c) 2007-2008, Plantronics, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of Plantronics nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#################################################################### diff --git a/src/libs/resiprocate/reTurn/client/Makefile.am b/src/libs/resiprocate/reTurn/client/Makefile.am new file mode 100644 index 00000000..fd9ae858 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/Makefile.am @@ -0,0 +1,97 @@ +# $Id$ + +EXTRA_DIST = *.vcproj +EXTRA_DIST += *.vcxproj *.vcxproj.filters + +SUBDIRS = . +SUBDIRS += test + +#AM_CXXFLAGS = -I../../contrib/ares -DUSE_ARES + +lib_LTLIBRARIES = libreTurnClient.la + +libreTurnClient_la_LIBADD = @LIBSSL_LIBADD@ -lrt +libreTurnClient_la_LDFLAGS = @LIBTOOL_VERSION_RELEASE@ -export-dynamic + +libreTurnClient_la_SOURCES = \ + ../AsyncSocketBase.cxx \ + ../AsyncTcpSocketBase.cxx \ + ../AsyncTlsSocketBase.cxx \ + ../AsyncUdpSocketBase.cxx \ + ../ChannelManager.cxx \ + ../DataBuffer.cxx \ + ../RemotePeer.cxx \ + ../ReTurnSubsystem.cxx \ + ../StunMessage.cxx \ + ../StunTuple.cxx \ + TurnAsyncSocket.cxx \ + TurnAsyncSocketHandler.cxx \ + TurnAsyncTcpSocket.cxx \ + TurnAsyncTlsSocket.cxx \ + TurnAsyncUdpSocket.cxx \ + TurnSocket.cxx \ + TurnTcpSocket.cxx \ + TurnTlsSocket.cxx \ + TurnUdpSocket.cxx + +libreTurnClientincludedir = $(includedir)/reTurnClient +nobase_libreTurnClientinclude_HEADERS = ErrorCode.hxx \ + TurnAsyncSocketHandler.hxx \ + TurnAsyncSocket.hxx \ + TurnAsyncTcpSocket.hxx \ + TurnAsyncTlsSocket.hxx \ + TurnAsyncUdpSocket.hxx \ + TurnSocket.hxx \ + TurnTcpSocket.hxx \ + TurnTlsSocket.hxx \ + TurnUdpSocket.hxx + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# <http://www.vovida.org/>. +# +############################################################################## diff --git a/src/libs/resiprocate/reTurn/client/TurnAsyncSocket.cxx b/src/libs/resiprocate/reTurn/client/TurnAsyncSocket.cxx new file mode 100644 index 00000000..8c9a1b46 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnAsyncSocket.cxx @@ -0,0 +1,1317 @@ +#include "TurnAsyncSocket.hxx" +#include "../AsyncSocketBase.hxx" +#include "ErrorCode.hxx" +#include <boost/bind.hpp> +#include <rutil/WinLeakCheck.hxx> +#include <rutil/Logger.hxx> +#include "../ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; +using namespace resip; + +#define UDP_RT0 100 // RTO - Estimate of Roundtrip time - 100ms is recommened for fixed line transport - the initial value should be configurable + // Should also be calculation this on the fly +#define UDP_MAX_RETRANSMITS 7 // Defined by RFC5389 (Rc) - should be configurable +#define TCP_RESPONSE_TIME 39500 // Defined by RFC5389 (Ti) - should be configurable +#define UDP_Rm 16 // Defined by RFC5389 - should be configurable +#define UDP_FINAL_REQUEST_TIME (UDP_RT0 * UDP_Rm) // Defined by RFC5389 + +//#define TURN_CHANNEL_BINDING_REFRESH_SECONDS 20 // TESTING only +#define TURN_CHANNEL_BINDING_REFRESH_SECONDS 240 // 4 minuntes - this is one minute before the permission will expire, Note: ChannelBinding refreshes also refresh permissions + +#define SOFTWARE_STRING "reTURN Async Client 0.3 - RFC5389/turn-12 " // Note padding size to a multiple of 4, to help compatibility with older clients + +namespace reTurn { + +// Initialize static members +unsigned int TurnAsyncSocket::UnspecifiedLifetime = 0xFFFFFFFF; +unsigned int TurnAsyncSocket::UnspecifiedBandwidth = 0xFFFFFFFF; +unsigned short TurnAsyncSocket::UnspecifiedToken = 0; +asio::ip::address TurnAsyncSocket::UnspecifiedIpAddress = asio::ip::address::from_string("0.0.0.0"); + +TurnAsyncSocket::TurnAsyncSocket(asio::io_service& ioService, + AsyncSocketBase& asyncSocketBase, + TurnAsyncSocketHandler* turnAsyncSocketHandler, + const asio::ip::address& address, + unsigned short port) : + mIOService(ioService), + mTurnAsyncSocketHandler(turnAsyncSocketHandler), + mLocalBinding(StunTuple::None /* Set properly by sub class */, address, port), + mHaveAllocation(false), + mActiveDestination(0), + mAsyncSocketBase(asyncSocketBase), + mCloseAfterDestroyAllocationFinishes(false), + mAllocationTimer(ioService) +{ +} + +TurnAsyncSocket::~TurnAsyncSocket() +{ + clearActiveRequestMap(); + cancelAllocationTimer(); + cancelChannelBindingTimers(); + + DebugLog(<< "TurnAsyncSocket::~TurnAsyncSocket destroyed!"); +} + +void +TurnAsyncSocket::disableTurnAsyncHandler() +{ + mTurnAsyncSocketHandler = 0; +} + +void +TurnAsyncSocket::requestSharedSecret() +{ + mGuards.push(mAsyncSocketBase.shared_from_this()); + mIOService.post(boost::bind(&TurnAsyncSocket::doRequestSharedSecret, this)); +} + +void +TurnAsyncSocket::doRequestSharedSecret() +{ + GuardReleaser guardReleaser(mGuards); + // Should we check here if TLS and deny? + + // Ensure Connected + if(!mAsyncSocketBase.isConnected()) + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSharedSecretFailure(getSocketDescriptor(), asio::error_code(reTurn::NotConnected, asio::error::misc_category)); + } + else + { + // Form Shared Secret request + StunMessage* request = createNewStunMessage(StunMessage::StunClassRequest, StunMessage::SharedSecretMethod); + + // Send the Request and start transaction timers + sendStunMessage(request); + } +} + +void +TurnAsyncSocket::setUsernameAndPassword(const char* username, const char* password, bool shortTermAuth) +{ + mGuards.push(mAsyncSocketBase.shared_from_this()); + mIOService.post(boost::bind(&TurnAsyncSocket::doSetUsernameAndPassword, this, new Data(username), new Data(password), shortTermAuth)); +} + +void +TurnAsyncSocket::doSetUsernameAndPassword(Data* username, Data* password, bool shortTermAuth) +{ + GuardReleaser guardReleaser(mGuards); + mUsername = *username; + mPassword = *password; + if(shortTermAuth) + { + // If we are using short term auth, then use short term password as HMAC key + mHmacKey = *password; + } + delete username; + delete password; +} + +void +TurnAsyncSocket::bindRequest() +{ + mGuards.push(mAsyncSocketBase.shared_from_this()); + mIOService.post(boost::bind(&TurnAsyncSocket::doBindRequest, this)); +} + +void +TurnAsyncSocket::doBindRequest() +{ + GuardReleaser guardReleaser(mGuards); + // Ensure Connected + if(!mAsyncSocketBase.isConnected()) + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onBindFailure(getSocketDescriptor(), asio::error_code(reTurn::NotConnected, asio::error::misc_category)); + } + else + { + // Form Stun Bind request + StunMessage* request = createNewStunMessage(StunMessage::StunClassRequest, StunMessage::BindMethod); + sendStunMessage(request); + } +} + +void +TurnAsyncSocket::createAllocation(unsigned int lifetime, + unsigned int bandwidth, + unsigned char requestedProps, + UInt64 reservationToken, + StunTuple::TransportType requestedTransportType) +{ + mGuards.push(mAsyncSocketBase.shared_from_this()); + mIOService.post(boost::bind(&TurnAsyncSocket::doCreateAllocation, this, lifetime, + bandwidth, + requestedProps, + reservationToken, + requestedTransportType)); +} + +void +TurnAsyncSocket::doCreateAllocation(unsigned int lifetime, + unsigned int bandwidth, + unsigned char requestedProps, + UInt64 reservationToken, + StunTuple::TransportType requestedTransportType) +{ + GuardReleaser guardReleaser(mGuards); + + // Store Allocation Properties + mRequestedTransportType = requestedTransportType; + + // Relay Transport Type is requested type or socket type + if(mRequestedTransportType != StunTuple::None) + { + mRelayTransportType = mRequestedTransportType; + } + else + { + mRelayTransportType = mLocalBinding.getTransportType(); + } + + // Ensure Connected + if(!mAsyncSocketBase.isConnected()) + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onAllocationFailure(getSocketDescriptor(), asio::error_code(reTurn::NotConnected, asio::error::misc_category)); + return; + } + + if(mHaveAllocation) + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onAllocationFailure(getSocketDescriptor(), asio::error_code(reTurn::AlreadyAllocated, asio::error::misc_category)); + return; + } + + // Form Turn Allocate request + StunMessage* request = createNewStunMessage(StunMessage::StunClassRequest, StunMessage::TurnAllocateMethod); + if(lifetime != UnspecifiedLifetime) + { + request->mHasTurnLifetime = true; + request->mTurnLifetime = lifetime; + } + + if(bandwidth != UnspecifiedBandwidth) + { + request->mHasTurnBandwidth = true; + request->mTurnBandwidth = bandwidth; + } + + if(requestedTransportType == StunTuple::None) + { + requestedTransportType = mLocalBinding.getTransportType(); + } + request->mHasTurnRequestedTransport = true; + if(requestedTransportType == StunTuple::UDP) + { + request->mTurnRequestedTransport = StunMessage::RequestedTransportUdp; + } + else if(requestedTransportType == StunTuple::TCP && + mLocalBinding.getTransportType() != StunTuple::UDP) // Ensure client is not requesting TCP over a UDP transport + { + request->mTurnRequestedTransport = StunMessage::RequestedTransportTcp; + } + else + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onAllocationFailure(getSocketDescriptor(), asio::error_code(reTurn::InvalidRequestedTransport, asio::error::misc_category)); + delete request; + return; + } + + if(requestedProps != StunMessage::PropsNone) + { + request->mHasTurnEvenPort = true; + request->mTurnEvenPort.propType = requestedProps; + } + else if(reservationToken != 0) + { + request->mHasTurnReservationToken = true; + request->mTurnReservationToken = reservationToken; + } + + sendStunMessage(request); +} + +void +TurnAsyncSocket::refreshAllocation(unsigned int lifetime) +{ + mGuards.push(mAsyncSocketBase.shared_from_this()); + mIOService.post(boost::bind(&TurnAsyncSocket::doRefreshAllocation, this, lifetime)); +} + +void +TurnAsyncSocket::doRefreshAllocation(unsigned int lifetime) +{ + GuardReleaser guardReleaser(mGuards); + if(!mHaveAllocation) + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onRefreshFailure(getSocketDescriptor(), asio::error_code(NoAllocation, asio::error::misc_category)); + if(mCloseAfterDestroyAllocationFinishes) + { + mHaveAllocation = false; + actualClose(); + } + return; + } + + // Form Turn Refresh request + StunMessage* request = createNewStunMessage(StunMessage::StunClassRequest, StunMessage::TurnRefreshMethod); + if(lifetime != UnspecifiedLifetime) + { + request->mHasTurnLifetime = true; + request->mTurnLifetime = lifetime; + } + //if(mRequestedBandwidth != UnspecifiedBandwidth) + //{ + // request.mHasTurnBandwidth = true; + // request.mTurnBandwidth = mRequestedBandwidth; + //} + + sendStunMessage(request); +} + +void +TurnAsyncSocket::destroyAllocation() +{ + mGuards.push(mAsyncSocketBase.shared_from_this()); + mIOService.post(boost::bind(&TurnAsyncSocket::doDestroyAllocation, this)); +} + +void +TurnAsyncSocket::doDestroyAllocation() +{ + doRefreshAllocation(0); +} + +void +TurnAsyncSocket::setActiveDestination(const asio::ip::address& address, unsigned short port) +{ + mGuards.push(mAsyncSocketBase.shared_from_this()); + mIOService.post(boost::bind(&TurnAsyncSocket::doSetActiveDestination, this, address, port)); +} + +void +TurnAsyncSocket::doSetActiveDestination(const asio::ip::address& address, unsigned short port) +{ + GuardReleaser guardReleaser(mGuards); + + // Setup Remote Peer + StunTuple remoteTuple(mRelayTransportType, address, port); + RemotePeer* remotePeer = mChannelManager.findRemotePeerByPeerAddress(remoteTuple); + if(remotePeer) + { + mActiveDestination = remotePeer; + } + else + { + // No channel binding yet (ie. no data sent or received from remote peer) - so create one + mActiveDestination = mChannelManager.createChannelBinding(remoteTuple); + assert(mActiveDestination); + doChannelBinding(*mActiveDestination); + } + DebugLog(<< "TurnAsyncSocket::doSetActiveDestination: Active Destination set to: " << remoteTuple << ", channel=" << mActiveDestination->getChannel()); + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSetActiveDestinationSuccess(getSocketDescriptor()); +} + +void TurnAsyncSocket::doChannelBinding(RemotePeer& remotePeer) +{ + // Form Channel Bind request + StunMessage* request = createNewStunMessage(StunMessage::StunClassRequest, StunMessage::TurnChannelBindMethod); + + // Set headers + request->mHasTurnChannelNumber = true; + request->mTurnChannelNumber = remotePeer.getChannel(); + request->mCntTurnXorPeerAddress = 1; + StunMessage::setStunAtrAddressFromTuple(request->mTurnXorPeerAddress[0], remotePeer.getPeerTuple()); + + // Send the Request and start transaction timers + sendStunMessage(request); + + // If not using UDP - then mark channel as confirmed - otherwise wait for ChannelBind response + if(mLocalBinding.getTransportType() != StunTuple::UDP) + { + remotePeer.setChannelConfirmed(); + } +} + +void +TurnAsyncSocket::clearActiveDestination() +{ + mGuards.push(mAsyncSocketBase.shared_from_this()); + mIOService.post(boost::bind(&TurnAsyncSocket::doClearActiveDestination, this)); +} + +void +TurnAsyncSocket::doClearActiveDestination() +{ + GuardReleaser guardReleaser(mGuards); + + // ensure there is an allocation + if(!mHaveAllocation) + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onClearActiveDestinationFailure(getSocketDescriptor(), asio::error_code(reTurn::NoAllocation, asio::error::misc_category)); + return; + } + + mActiveDestination = 0; + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onClearActiveDestinationSuccess(getSocketDescriptor()); +} + +StunMessage* +TurnAsyncSocket::createNewStunMessage(UInt16 stunclass, UInt16 method, bool addAuthInfo) +{ + StunMessage* msg = new StunMessage(); + msg->createHeader(stunclass, method); + + // Add Software Attribute + msg->setSoftware(SOFTWARE_STRING); + + if(addAuthInfo && !mUsername.empty() && !mHmacKey.empty()) + { + msg->mHasMessageIntegrity = true; + msg->setUsername(mUsername.c_str()); + msg->mHmacKey = mHmacKey; + if(!mRealm.empty()) + { + msg->setRealm(mRealm.c_str()); + } + if(!mNonce.empty()) + { + msg->setNonce(mNonce.c_str()); + } + } + return msg; +} + +void +TurnAsyncSocket::sendStunMessage(StunMessage* message, bool reTransmission) +{ +#define REQUEST_BUFFER_SIZE 2048 + boost::shared_ptr<DataBuffer> buffer = AsyncSocketBase::allocateBuffer(REQUEST_BUFFER_SIZE); + unsigned int bufferSize; + bufferSize = message->stunEncodeMessage((char*)buffer->data(), REQUEST_BUFFER_SIZE); + buffer->truncate(bufferSize); // set size to real size + + if(!reTransmission) + { + // If message is a request, then start appropriate transaction and retranmission timers + if(message->mClass == StunMessage::StunClassRequest) + { + boost::shared_ptr<RequestEntry> requestEntry(new RequestEntry(mIOService, this, message)); + mActiveRequestMap[message->mHeader.magicCookieAndTid] = requestEntry; + requestEntry->startTimer(); + } + else + { + delete message; + } + } + + send(buffer); +} + +void +TurnAsyncSocket::handleReceivedData(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) +{ + if(data->size() > 4) + { + // Stun Message has first two bits as 00 + if((((*data)[0]) & 0xC0) == 0) + { + StunMessage* stunMsg = new StunMessage(mLocalBinding, + StunTuple(mLocalBinding.getTransportType(), mAsyncSocketBase.getConnectedAddress(), mAsyncSocketBase.getConnectedPort()), + &(*data)[0], data->size()); + if(stunMsg->isValid()) + { + handleStunMessage(*stunMsg); + delete stunMsg; + return; + } + delete stunMsg; + + // Not a stun message so assume normal data + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onReceiveSuccess(getSocketDescriptor(), + address, + port, + data); + } + else if(mHaveAllocation) // If we have an allocation then this is a Turn Channel Data Message + { + // Get Channel number + unsigned short channelNumber; + memcpy(&channelNumber, &(*data)[0], 2); + channelNumber = ntohs(channelNumber); + + if(mLocalBinding.getTransportType() == StunTuple::UDP) + { + // Check if the UDP datagram size is too short to contain the claimed length of the ChannelData message, then discard + unsigned short dataLen; + memcpy(&dataLen, &(*data)[2], 2); + dataLen = ntohs(dataLen); + + if(data->size() < (unsigned int)dataLen+4) + { + WarningLog(<< "ChannelData message size=" << dataLen+4 << " too large for UDP packet size=" << data->size() <<". Dropping."); + return; + } + } + + RemotePeer* remotePeer = mChannelManager.findRemotePeerByChannel(channelNumber); + if(remotePeer) + { + data->offset(4); // move buffer start past framing for callback + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onReceiveSuccess(getSocketDescriptor(), + remotePeer->getPeerTuple().getAddress(), + remotePeer->getPeerTuple().getPort(), + data); + } + else + { + WarningLog(<< "TurnAsyncSocket::handleReceivedData: receive channel data for non-existing channel - discarding!"); + } + } + else + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onReceiveSuccess(getSocketDescriptor(), + address, + port, + data); + } + } + else // size <= 4 + { + WarningLog(<< "TurnAsyncSocket::handleReceivedData: not enough data received (" << data->size() << " bytes) for stun or channel data message - discarding!"); + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onReceiveFailure(getSocketDescriptor(), asio::error_code(reTurn::FrameError, asio::error::misc_category)); + } +} + +asio::error_code +TurnAsyncSocket::handleStunMessage(StunMessage& stunMessage) +{ + asio::error_code errorCode; + if(stunMessage.isValid()) + { + if(!stunMessage.checkMessageIntegrity(mHmacKey)) + { + WarningLog(<< "TurnAsyncSocket::handleStunMessage: Stun message integrity is bad!"); + return asio::error_code(reTurn::BadMessageIntegrity, asio::error::misc_category); + } + + // Request is authenticated, process it + switch(stunMessage.mClass) + { + case StunMessage::StunClassRequest: + switch (stunMessage.mMethod) + { + case StunMessage::BindMethod: + if(stunMessage.mUnknownRequiredAttributes.numAttributes > 0) + { + // There were unknown comprehension-required attributes in the request + StunMessage* response = new StunMessage(); + response->mClass = StunMessage::StunClassErrorResponse; + response->mMethod = stunMessage.mMethod; + response->setErrorCode(420, "Unknown Attribute"); + // Copy over TransactionId + response->mHeader.magicCookieAndTid = stunMessage.mHeader.magicCookieAndTid; + // Add Unknown Attributes + response->mHasUnknownAttributes = true; + response->mUnknownAttributes = stunMessage.mUnknownRequiredAttributes; + // Add Software Attribute + response->setSoftware(SOFTWARE_STRING); + sendStunMessage(response); + } + else + { + errorCode = handleBindRequest(stunMessage); + } + break; + case StunMessage::SharedSecretMethod: + case StunMessage::TurnAllocateMethod: + case StunMessage::TurnRefreshMethod: + default: + // These requests are not handled by a client + StunMessage* response = new StunMessage(); + response->mClass = StunMessage::StunClassErrorResponse; + response->mMethod = stunMessage.mMethod; + response->setErrorCode(400, "Invalid Request Method"); + // Copy over TransactionId + response->mHeader.magicCookieAndTid = stunMessage.mHeader.magicCookieAndTid; + // Add Software Attribute + response->setSoftware(SOFTWARE_STRING); + sendStunMessage(response); + break; + } + break; + + case StunMessage::StunClassIndication: + switch (stunMessage.mMethod) + { + case StunMessage::TurnDataMethod: + if(stunMessage.mUnknownRequiredAttributes.numAttributes > 0) + { + // Unknown Comprehension-Required Attributes found + WarningLog(<< "Ignoring DataInd with unknown comprehension required attributes."); + errorCode = asio::error_code(reTurn::UnknownRequiredAttributes, asio::error::misc_category); + } + else + { + errorCode = handleDataInd(stunMessage); + } + break; + case StunMessage::BindMethod: + // A Bind indication is simply a keepalive with no response required + break; + case StunMessage::TurnSendMethod: // Don't need to handle these - only sent by client, never received + default: + // Unknown indication - just ignore + break; + } + break; + + case StunMessage::StunClassSuccessResponse: + case StunMessage::StunClassErrorResponse: + { + if(stunMessage.mUnknownRequiredAttributes.numAttributes > 0) + { + // Unknown Comprehension-Required Attributes found + WarningLog(<< "Ignoring Response with unknown comprehension required attributes."); + return asio::error_code(reTurn::UnknownRequiredAttributes, asio::error::misc_category); + } + + // First check if this response is for an active request + RequestMap::iterator it = mActiveRequestMap.find(stunMessage.mHeader.magicCookieAndTid); + if(it == mActiveRequestMap.end()) + { + // Stray response - dropping + return asio::error_code(reTurn::StrayResponse, asio::error::misc_category); + } + + boost::shared_ptr<RequestEntry> requestEntry = it->second; + mActiveRequestMap.erase(it); + requestEntry->stopTimer(); + + // If a realm and nonce attributes are present and the response is a 401 or 438 (Nonce Expired), + // then re-issue request with new auth attributes + if(stunMessage.mHasRealm && + stunMessage.mHasNonce && + stunMessage.mHasErrorCode && + stunMessage.mErrorCode.errorClass == 4 && + ((stunMessage.mErrorCode.number == 1 && mHmacKey.empty()) || // Note if 401 error then ensure we haven't already tried once - if we've tried then mHmacKey will be populated + stunMessage.mErrorCode.number == 38)) + { + mNonce = *stunMessage.mNonce; + mRealm = *stunMessage.mRealm; + stunMessage.calculateHmacKey(mHmacKey, mUsername, mRealm, mPassword); + + // Create a new transaction - by starting with old request + StunMessage* newRequest = requestEntry->mRequestMessage; + requestEntry->mRequestMessage = 0; // clear out pointer in mActiveRequestMap so that it will not be deleted + + newRequest->createHeader(newRequest->mClass, newRequest->mMethod); // updates TID + newRequest->mHasMessageIntegrity = true; + newRequest->setUsername(mUsername.c_str()); + newRequest->mHmacKey = mHmacKey; + newRequest->setRealm(mRealm.c_str()); + newRequest->setNonce(mNonce.c_str()); + sendStunMessage(newRequest); + return errorCode; + } + + switch (stunMessage.mMethod) + { + case StunMessage::BindMethod: + errorCode = handleBindResponse(*requestEntry->mRequestMessage, stunMessage); + break; + case StunMessage::SharedSecretMethod: + errorCode = handleSharedSecretResponse(*requestEntry->mRequestMessage, stunMessage); + break; + case StunMessage::TurnAllocateMethod: + errorCode = handleAllocateResponse(*requestEntry->mRequestMessage, stunMessage); + break; + case StunMessage::TurnRefreshMethod: + errorCode = handleRefreshResponse(*requestEntry->mRequestMessage, stunMessage); + break; + case StunMessage::TurnChannelBindMethod: + errorCode = handleChannelBindResponse(*requestEntry->mRequestMessage, stunMessage); + break; + default: + // Unknown method - just ignore + break; + } + } + break; + + default: + // Illegal message class - ignore + break; + } + } + else + { + WarningLog(<< "TurnAsyncSocket::handleStunMessage: Read Invalid StunMsg."); + return asio::error_code(reTurn::ErrorParsingMessage, asio::error::misc_category); + } + return errorCode; +} + +asio::error_code +TurnAsyncSocket::handleDataInd(StunMessage& stunMessage) +{ + if(stunMessage.mCntTurnXorPeerAddress == 0 || !stunMessage.mHasTurnData) + { + // Missing RemoteAddress or TurnData attribute + WarningLog(<< "TurnAsyncSocket::handleDataInd: DataInd missing attributes."); + return asio::error_code(reTurn::MissingAttributes, asio::error::misc_category); + } + + StunTuple remoteTuple; + remoteTuple.setTransportType(mRelayTransportType); + StunMessage::setTupleFromStunAtrAddress(remoteTuple, stunMessage.mTurnXorPeerAddress[0]); + + RemotePeer* remotePeer = mChannelManager.findRemotePeerByPeerAddress(remoteTuple); + if(!remotePeer) + { + // Remote Peer not found - discard data + WarningLog(<< "TurnAsyncSocket::handleDataInd: Data received from unknown RemotePeer " << remoteTuple << " - discarding"); + return asio::error_code(reTurn::UnknownRemoteAddress, asio::error::misc_category); + } + + boost::shared_ptr<DataBuffer> data(new DataBuffer(stunMessage.mTurnData->data(), stunMessage.mTurnData->size())); + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onReceiveSuccess(getSocketDescriptor(), + remoteTuple.getAddress(), + remoteTuple.getPort(), + data); + + return asio::error_code(); +} + +asio::error_code +TurnAsyncSocket::handleChannelBindResponse(StunMessage &request, StunMessage &response) +{ + if(response.mClass == StunMessage::StunClassSuccessResponse) + { + assert(request.mHasTurnChannelNumber); + + RemotePeer* remotePeer = mChannelManager.findRemotePeerByChannel(request.mTurnChannelNumber); + if(!remotePeer) + { + // Remote Peer not found - discard + WarningLog(<< "TurnAsyncSocket::handleChannelBindResponse: Received ChannelBindResponse for unknown channel (" << response.mTurnChannelNumber << ") - discarding"); + return asio::error_code(reTurn::InvalidChannelNumberReceived, asio::error::misc_category); + } + + DebugLog(<< "TurnAsyncSocket::handleChannelBindResponse: Channel " << remotePeer->getChannel() << " is now bound to " << remotePeer->getPeerTuple()); + remotePeer->refresh(); + remotePeer->setChannelConfirmed(); + startChannelBindingTimer(remotePeer->getChannel()); + } + else + { + // Check error code + if(response.mHasErrorCode) + { + ErrLog(<< "TurnAsyncSocket::handleChannelBindResponse: Received ChannelBindResponse error: " << response.mErrorCode.errorClass * 100 + response.mErrorCode.number); + return asio::error_code(response.mErrorCode.errorClass * 100 + response.mErrorCode.number, asio::error::misc_category); + } + else + { + ErrLog(<< "TurnAsyncSocket::handleChannelBindResponse: Received ChannelBindResponse error but no error code attribute found."); + return asio::error_code(MissingAttributes, asio::error::misc_category); + } + } + return asio::error_code(); +} + +asio::error_code +TurnAsyncSocket::handleSharedSecretResponse(StunMessage &request, StunMessage &response) +{ + if(response.mClass == StunMessage::StunClassSuccessResponse) + { + // Copy username and password to callers buffer - checking sizes first + if(!response.mHasUsername || !response.mHasPassword) + { + WarningLog(<< "TurnAsyncSocket::handleSharedSecretResponse: Stun response message for SharedSecretRequest is missing username and/or password!"); + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSharedSecretFailure(getSocketDescriptor(), asio::error_code(MissingAttributes, asio::error::misc_category)); + return asio::error_code(MissingAttributes, asio::error::misc_category); + } + + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSharedSecretSuccess(getSocketDescriptor(), response.mUsername->c_str(), response.mUsername->size(), + response.mPassword->c_str(), response.mPassword->size()); + } + else + { + // Check error code + if(response.mHasErrorCode) + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSharedSecretFailure(getSocketDescriptor(), asio::error_code(response.mErrorCode.errorClass * 100 + response.mErrorCode.number, asio::error::misc_category)); + } + else + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSharedSecretFailure(getSocketDescriptor(), asio::error_code(MissingAttributes, asio::error::misc_category)); + return asio::error_code(MissingAttributes, asio::error::misc_category); + } + } + return asio::error_code(); +} + +asio::error_code +TurnAsyncSocket::handleBindRequest(StunMessage& stunMessage) +{ + // Note: handling of BindRequest is not fully backwards compatible with RFC3489 - it is inline with RFC5389 + StunMessage* response = new StunMessage(); + + // form the outgoing message + response->mClass = StunMessage::StunClassSuccessResponse; + response->mMethod = StunMessage::BindMethod; + + // Copy over TransactionId + response->mHeader.magicCookieAndTid = stunMessage.mHeader.magicCookieAndTid; + + // Add XOrMappedAddress to response + response->mHasXorMappedAddress = true; + StunMessage::setStunAtrAddressFromTuple(response->mXorMappedAddress, stunMessage.mRemoteTuple); + + // Add Software Attribute + response->setSoftware(SOFTWARE_STRING); + + // send bindResponse to local client + sendStunMessage(response); + + return asio::error_code(); +} + +asio::error_code +TurnAsyncSocket::handleBindResponse(StunMessage &request, StunMessage &response) +{ + if(response.mClass == StunMessage::StunClassSuccessResponse) + { + StunTuple reflexiveTuple; + reflexiveTuple.setTransportType(mLocalBinding.getTransportType()); + if(response.mHasXorMappedAddress) + { + StunMessage::setTupleFromStunAtrAddress(reflexiveTuple, response.mXorMappedAddress); + } + else if(response.mHasMappedAddress) // Only look at MappedAddress if XorMappedAddress is not found - for backwards compatibility + { + StunMessage::setTupleFromStunAtrAddress(reflexiveTuple, response.mMappedAddress); + } + else + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onBindFailure(getSocketDescriptor(), asio::error_code(MissingAttributes, asio::error::misc_category)); + return asio::error_code(MissingAttributes, asio::error::misc_category); + } + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onBindSuccess(getSocketDescriptor(), reflexiveTuple); + } + else + { + // Check if success or not + if(response.mHasErrorCode) + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onBindFailure(getSocketDescriptor(), asio::error_code(response.mErrorCode.errorClass * 100 + response.mErrorCode.number, asio::error::misc_category)); + } + else + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onBindFailure(getSocketDescriptor(), asio::error_code(MissingAttributes, asio::error::misc_category)); + return asio::error_code(MissingAttributes, asio::error::misc_category); + } + } + return asio::error_code(); +} + +asio::error_code +TurnAsyncSocket::handleAllocateResponse(StunMessage &request, StunMessage &response) +{ + if(response.mClass == StunMessage::StunClassSuccessResponse) + { + StunTuple reflexiveTuple; + StunTuple relayTuple; + if(response.mHasXorMappedAddress) + { + reflexiveTuple.setTransportType(mLocalBinding.getTransportType()); + StunMessage::setTupleFromStunAtrAddress(reflexiveTuple, response.mXorMappedAddress); + } + if(response.mHasTurnXorRelayedAddress) + { + relayTuple.setTransportType(mRelayTransportType); + StunMessage::setTupleFromStunAtrAddress(relayTuple, response.mTurnXorRelayedAddress); + } + if(response.mHasTurnLifetime) + { + mLifetime = response.mTurnLifetime; + } + else + { + mLifetime = 0; + } + + // All was well - return 0 errorCode + if(mLifetime != 0) + { + mHaveAllocation = true; + startAllocationTimer(); + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onAllocationSuccess(getSocketDescriptor(), + reflexiveTuple, + relayTuple, + mLifetime, + response.mHasTurnBandwidth ? response.mTurnBandwidth : 0, + response.mHasTurnReservationToken ? response.mTurnReservationToken : 0); + } + else + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onAllocationFailure(getSocketDescriptor(), asio::error_code(MissingAttributes, asio::error::misc_category)); + } + } + else + { + // Check if success or not + if(response.mHasErrorCode) + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onAllocationFailure(getSocketDescriptor(), asio::error_code(response.mErrorCode.errorClass * 100 + response.mErrorCode.number, asio::error::misc_category)); + } + else + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onAllocationFailure(getSocketDescriptor(), asio::error_code(MissingAttributes, asio::error::misc_category)); + return asio::error_code(MissingAttributes, asio::error::misc_category); + } + } + return asio::error_code(); +} + +asio::error_code +TurnAsyncSocket::handleRefreshResponse(StunMessage &request, StunMessage &response) +{ + if(response.mClass == StunMessage::StunClassSuccessResponse) + { + if(response.mHasTurnLifetime) + { + mLifetime = response.mTurnLifetime; + } + else + { + mLifetime = 0; + } + if(mLifetime != 0) + { + mHaveAllocation = true; + startAllocationTimer(); + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onRefreshSuccess(getSocketDescriptor(), mLifetime); + if(mCloseAfterDestroyAllocationFinishes) + { + mHaveAllocation = false; + actualClose(); + } + } + else + { + cancelAllocationTimer(); + mHaveAllocation = false; + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onRefreshSuccess(getSocketDescriptor(), 0); + if(mCloseAfterDestroyAllocationFinishes) + { + actualClose(); + } + } + } + else + { + // Check if success or not + if(response.mHasErrorCode) + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onRefreshFailure(getSocketDescriptor(), asio::error_code(response.mErrorCode.errorClass * 100 + response.mErrorCode.number, asio::error::misc_category)); + if(mCloseAfterDestroyAllocationFinishes) + { + cancelAllocationTimer(); + mHaveAllocation = false; + actualClose(); + } + else if(response.mErrorCode.errorClass == 4 && response.mErrorCode.number == 37) // response is 437, then remove allocation + { + cancelAllocationTimer(); + mHaveAllocation = false; + } + } + else + { + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onRefreshFailure(getSocketDescriptor(), asio::error_code(MissingAttributes, asio::error::misc_category)); + if(mCloseAfterDestroyAllocationFinishes) + { + cancelAllocationTimer(); + mHaveAllocation = false; + actualClose(); + } + return asio::error_code(MissingAttributes, asio::error::misc_category); + } + } + return asio::error_code(); +} + +void +TurnAsyncSocket::send(const char* buffer, unsigned int size) +{ + boost::shared_ptr<DataBuffer> data(new DataBuffer(buffer, size)); + mGuards.push(mAsyncSocketBase.shared_from_this()); + mIOService.post(boost::bind(&TurnAsyncSocket::doSend, this, data)); +} + +void +TurnAsyncSocket::doSend(boost::shared_ptr<DataBuffer>& data) +{ + GuardReleaser guardReleaser(mGuards); + + // Allow raw data to be sent if there is no allocation + if(!mHaveAllocation) + { + send(data); + return; + } + + return sendTo(*mActiveDestination, data); +} + +void +TurnAsyncSocket::sendTo(const asio::ip::address& address, unsigned short port, const char* buffer, unsigned int size) +{ + boost::shared_ptr<DataBuffer> data(new DataBuffer(buffer, size)); + mGuards.push(mAsyncSocketBase.shared_from_this()); + mIOService.post(boost::bind(&TurnAsyncSocket::doSendTo, this, address, port, data)); +} + +void +TurnAsyncSocket::doSendTo(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) +{ + GuardReleaser guardReleaser(mGuards); + + // Allow raw data to be sent if there is no allocation + if(!mHaveAllocation) + { + StunTuple destination(mLocalBinding.getTransportType(), address, port); + mAsyncSocketBase.send(destination, data); + return; + } + + // Setup Remote Peer + StunTuple remoteTuple(mRelayTransportType, address, port); + RemotePeer* remotePeer = mChannelManager.findRemotePeerByPeerAddress(remoteTuple); + if(!remotePeer) + { + // No remote peer yet (ie. no data sent or received from remote peer) - so create one + remotePeer = mChannelManager.createChannelBinding(remoteTuple); + assert(remotePeer); + doChannelBinding(*remotePeer); + } + return sendTo(*remotePeer, data); +} + +void +TurnAsyncSocket::sendTo(RemotePeer& remotePeer, boost::shared_ptr<DataBuffer>& data) +{ + if(remotePeer.isChannelConfirmed()) + { + // send framed data to active destination + send(remotePeer.getChannel(), data); + //InfoLog( << "TurnAsyncSocket::sendTo: using channel " << remotePeer.getChannel() << " to send " << data->size() << " bytes."); + } + else + { + // Data must be wrapped in a Send Indication + // Wrap data in a SendInd + StunMessage* ind = createNewStunMessage(StunMessage::StunClassIndication, StunMessage::TurnSendMethod, false); + ind->mCntTurnXorPeerAddress = 1; + StunMessage::setStunAtrAddressFromTuple(ind->mTurnXorPeerAddress[0], remotePeer.getPeerTuple()); + if(data->size() > 0) + { + ind->setTurnData(data->data(), data->size()); + } + + // Send indication to Turn Server + sendStunMessage(ind); + } +} + +void +TurnAsyncSocket::connect(const std::string& address, unsigned short port) +{ + mAsyncSocketBase.connect(address,port); +} + +void +TurnAsyncSocket::close() +{ + mGuards.push(mAsyncSocketBase.shared_from_this()); + mIOService.post(boost::bind(&TurnAsyncSocket::doClose, this)); +} + +void +TurnAsyncSocket::doClose() +{ + GuardReleaser guardReleaser(mGuards); + + // If we have an allocation over UDP then we should send a refresh with lifetime 0 to destroy the allocation + // Note: For TCP and TLS, the socket disconnection will destroy the allocation automatically + if(mHaveAllocation && mLocalBinding.getTransportType() == StunTuple::UDP) + { + mCloseAfterDestroyAllocationFinishes = true; + destroyAllocation(); + } + else + { + actualClose(); + } +} + +void +TurnAsyncSocket::actualClose() +{ + clearActiveRequestMap(); + cancelAllocationTimer(); + cancelChannelBindingTimers(); + mAsyncSocketBase.close(); +} + +void +TurnAsyncSocket::turnReceive() +{ + if(mLocalBinding.getTransportType() == StunTuple::UDP) + { + //mAsyncSocketBase.receive(); + mAsyncSocketBase.doReceive(); + } + else + { + //mAsyncSocketBase.framedReceive(); + mAsyncSocketBase.doFramedReceive(); + } +} + +void +TurnAsyncSocket::send(boost::shared_ptr<DataBuffer>& data) +{ + StunTuple destination(mLocalBinding.getTransportType(), mAsyncSocketBase.getConnectedAddress(), mAsyncSocketBase.getConnectedPort()); + mAsyncSocketBase.send(destination, data); +} + +void +TurnAsyncSocket::send(unsigned short channel, boost::shared_ptr<DataBuffer>& data) +{ + StunTuple destination(mLocalBinding.getTransportType(), mAsyncSocketBase.getConnectedAddress(), mAsyncSocketBase.getConnectedPort()); + mAsyncSocketBase.send(destination, channel, data); +} + +TurnAsyncSocket::RequestEntry::RequestEntry(asio::io_service& ioService, + TurnAsyncSocket* turnAsyncSocket, + StunMessage* requestMessage) : + mIOService(ioService), + mTurnAsyncSocket(turnAsyncSocket), + mRequestMessage(requestMessage), + mRequestTimer(ioService), + mRequestsSent(1) +{ + mTimeout = mTurnAsyncSocket->mLocalBinding.getTransportType() == StunTuple::UDP ? UDP_RT0 : TCP_RESPONSE_TIME; +} + +void +TurnAsyncSocket::RequestEntry::startTimer() +{ + // start the request timer + mRequestTimer.expires_from_now(boost::posix_time::milliseconds(mTimeout)); + mRequestTimer.async_wait(boost::bind(&TurnAsyncSocket::RequestEntry::requestTimerExpired, shared_from_this(), asio::placeholders::error)); +} + +void +TurnAsyncSocket::RequestEntry::stopTimer() +{ + // stop the request timer + mRequestTimer.cancel(); +} + +TurnAsyncSocket::RequestEntry::~RequestEntry() +{ + delete mRequestMessage; + stopTimer(); +} + +void +TurnAsyncSocket::RequestEntry::requestTimerExpired(const asio::error_code& e) +{ + if(!e && mRequestMessage) // Note: There is a race condition with clearing out of mRequestMessage when 401 is received - check that mRequestMessage is not 0 avoids any resulting badness + { + if(mTurnAsyncSocket->mLocalBinding.getTransportType() != StunTuple::UDP || mRequestsSent == UDP_MAX_RETRANSMITS) + { + mTurnAsyncSocket->requestTimeout(mRequestMessage->mHeader.magicCookieAndTid); + return; + } + // timed out and should retransmit - calculate next timeout + if(mRequestsSent == UDP_MAX_RETRANSMITS - 1) + { + mTimeout = UDP_FINAL_REQUEST_TIME; + } + else + { + mTimeout = (mTimeout*2); + } + // retransmit + DebugLog(<< "RequestEntry::requestTimerExpired: retransmitting..."); + mRequestsSent++; + mTurnAsyncSocket->sendStunMessage(mRequestMessage, true); + + startTimer(); + } +} + +void +TurnAsyncSocket::requestTimeout(UInt128 tid) +{ + RequestMap::iterator it = mActiveRequestMap.find(tid); + if(it != mActiveRequestMap.end()) + { + boost::shared_ptr<RequestEntry> requestEntry = it->second; + mActiveRequestMap.erase(it); + + switch(requestEntry->mRequestMessage->mMethod) + { + case StunMessage::BindMethod: + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onBindFailure(getSocketDescriptor(), asio::error_code(reTurn::ResponseTimeout, asio::error::misc_category)); + break; + case StunMessage::SharedSecretMethod: + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSharedSecretFailure(getSocketDescriptor(), asio::error_code(reTurn::ResponseTimeout, asio::error::misc_category)); + break; + case StunMessage::TurnAllocateMethod: + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onAllocationFailure(getSocketDescriptor(), asio::error_code(reTurn::ResponseTimeout, asio::error::misc_category)); + break; + case StunMessage::TurnRefreshMethod: + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onRefreshFailure(getSocketDescriptor(), asio::error_code(reTurn::ResponseTimeout, asio::error::misc_category)); + if(mCloseAfterDestroyAllocationFinishes) + { + mHaveAllocation = false; + actualClose(); + } + break; + default: + assert(false); + } + } +} + +void +TurnAsyncSocket::clearActiveRequestMap() +{ + // Clear out active request map - !slg! TODO this really should happen from the io service thread + RequestMap::iterator it = mActiveRequestMap.begin(); + for(;it != mActiveRequestMap.end(); it++) + { + it->second->stopTimer(); + } + mActiveRequestMap.clear(); +} + +void +TurnAsyncSocket::startAllocationTimer() +{ + mAllocationTimer.expires_from_now(boost::posix_time::seconds((mLifetime*5)/8)); // Allocation refresh should sent before 3/4 lifetime - use 5/8 lifetime + mGuards.push(mAsyncSocketBase.shared_from_this()); + mAllocationTimer.async_wait(boost::bind(&TurnAsyncSocket::allocationTimerExpired, this, asio::placeholders::error)); +} + +void +TurnAsyncSocket::cancelAllocationTimer() +{ + mAllocationTimer.cancel(); +} + +void +TurnAsyncSocket::allocationTimerExpired(const asio::error_code& e) +{ + if(!e) + { + doRefreshAllocation(mLifetime); + } + else + { + // Note: only release guard if not calling doRefreshAllocation - since + // doRefreshAllocation will release the guard + GuardReleaser guardReleaser(mGuards); + } +} + +void +TurnAsyncSocket::startChannelBindingTimer(unsigned short channel) +{ + ChannelBindingTimerMap::iterator it = mChannelBindingTimers.find(channel); + if(it==mChannelBindingTimers.end()) + { + std::pair<ChannelBindingTimerMap::iterator,bool> ret = + mChannelBindingTimers.insert(std::pair<unsigned short, asio::deadline_timer*>(channel, new asio::deadline_timer(mIOService))); + assert(ret.second); + it = ret.first; + } + it->second->expires_from_now(boost::posix_time::seconds(TURN_CHANNEL_BINDING_REFRESH_SECONDS)); + mGuards.push(mAsyncSocketBase.shared_from_this()); + it->second->async_wait(boost::bind(&TurnAsyncSocket::channelBindingTimerExpired, this, asio::placeholders::error, channel)); +} + +void +TurnAsyncSocket::cancelChannelBindingTimers() +{ + // Cleanup ChannelBinding Timers + ChannelBindingTimerMap::iterator it = mChannelBindingTimers.begin(); + for(;it!=mChannelBindingTimers.end();it++) + { + it->second->cancel(); + delete it->second; + } + mChannelBindingTimers.clear(); +} + +void +TurnAsyncSocket::channelBindingTimerExpired(const asio::error_code& e, unsigned short channel) +{ + GuardReleaser guardReleaser(mGuards); + if(!e) + { + RemotePeer* remotePeer = mChannelManager.findRemotePeerByChannel(channel); + if(remotePeer) + { + doChannelBinding(*remotePeer); + } + } +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnAsyncSocket.hxx b/src/libs/resiprocate/reTurn/client/TurnAsyncSocket.hxx new file mode 100644 index 00000000..def33086 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnAsyncSocket.hxx @@ -0,0 +1,230 @@ +#ifndef TURNASYNCSOCKET_HXX +#define TURNASYNCSOCKET_HXX + +#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ + && !defined(ASIO_ENABLE_CANCELIO) +#error You must define ASIO_ENABLE_CANCELIO in your build settings. +#endif + +#include <map> +#include <queue> +#include <asio.hpp> +#include <rutil/Data.hxx> +#include <rutil/Mutex.hxx> + +#include "../StunTuple.hxx" +#include "../StunMessage.hxx" +#include "../ChannelManager.hxx" +#include "../AsyncSocketBase.hxx" +#include "TurnAsyncSocketHandler.hxx" + +namespace reTurn { + +class TurnAsyncSocket +{ +public: + static unsigned int UnspecifiedLifetime; + static unsigned int UnspecifiedBandwidth; + static unsigned short UnspecifiedToken; + static asio::ip::address UnspecifiedIpAddress; + + explicit TurnAsyncSocket(asio::io_service& ioService, + AsyncSocketBase& asyncSocketBase, + TurnAsyncSocketHandler* turnAsyncSocketHandler, + const asio::ip::address& address = UnspecifiedIpAddress, + unsigned short port = 0); + virtual ~TurnAsyncSocket(); + + virtual void disableTurnAsyncHandler(); + virtual unsigned int getSocketDescriptor() = 0; + + // Note: Shared Secret requests have been deprecated by RFC5389, and not + // widely implemented in RFC3489 - so not really needed at all + void requestSharedSecret(); + + // Set the username and password for all future requests + void setUsernameAndPassword(const char* username, const char* password, bool shortTermAuth=false); + void connect(const std::string& address, unsigned short port); + + // Stun Binding Method - use getReflexiveTuple() to get binding info + void bindRequest(); + + // Turn Allocation Methods + void createAllocation(unsigned int lifetime = UnspecifiedLifetime, + unsigned int bandwidth = UnspecifiedBandwidth, + unsigned char requestedPortProps = StunMessage::PropsNone, + UInt64 reservationToken = UnspecifiedToken, + StunTuple::TransportType requestedTransportType = StunTuple::None); + void refreshAllocation(unsigned int lifetime); + void destroyAllocation(); + + // Methods to control active destination + void setActiveDestination(const asio::ip::address& address, unsigned short port); + void clearActiveDestination(); + + asio::ip::address& getConnectedAddress() { return mAsyncSocketBase.getConnectedAddress(); } + unsigned short getConnectedPort() { return mAsyncSocketBase.getConnectedPort(); } + + // Turn Send Methods + virtual void send(const char* buffer, unsigned int size); + virtual void sendTo(const asio::ip::address& address, unsigned short port, const char* buffer, unsigned int size); + + // Receive Methods + //asio::error_code receive(char* buffer, unsigned int& size, unsigned int timeout, asio::ip::address* sourceAddress=0, unsigned short* sourcePort=0); + //asio::error_code receiveFrom(const asio::ip::address& address, unsigned short port, char* buffer, unsigned int& size, unsigned int timeout); + + virtual void close(); + virtual void turnReceive(); + +protected: + + void handleReceivedData(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data); + + asio::io_service& mIOService; + TurnAsyncSocketHandler* mTurnAsyncSocketHandler; + + // Local Binding Info + StunTuple mLocalBinding; + + // Authentication Info + resip::Data mUsername; + resip::Data mPassword; + resip::Data mHmacKey; + resip::Data mRealm; + resip::Data mNonce; + + // Turn Allocation Properties used in request + StunTuple::TransportType mRequestedTransportType; + + // Turn Allocation Properties from response + bool mHaveAllocation; + StunTuple::TransportType mRelayTransportType; + unsigned int mLifetime; + + ChannelManager mChannelManager; + RemotePeer* mActiveDestination; + +private: + AsyncSocketBase& mAsyncSocketBase; + bool mCloseAfterDestroyAllocationFinishes; + + // Request map (for retransmissions) + class RequestEntry : public boost::enable_shared_from_this<RequestEntry> + { + public: + RequestEntry(asio::io_service& ioService, TurnAsyncSocket* turnAsyncSocket, StunMessage* requestMessage); + ~RequestEntry(); + + void startTimer(); + void stopTimer(); + void requestTimerExpired(const asio::error_code& e); + + asio::io_service& mIOService; + TurnAsyncSocket* mTurnAsyncSocket; + StunMessage* mRequestMessage; + asio::deadline_timer mRequestTimer; + unsigned int mRequestsSent; + unsigned int mTimeout; + }; + typedef std::map<UInt128, boost::shared_ptr<RequestEntry> > RequestMap; + RequestMap mActiveRequestMap; + friend class RequestEntry; + void requestTimeout(UInt128 tid); + void clearActiveRequestMap(); + + // Async guards - holds shared pointers to AsyncSocketBase so that TurnAsyncSocket + // destruction will be delayed if there are outstanding async TurnAsyncSocket calls + std::queue<boost::shared_ptr<AsyncSocketBase> > mGuards; + class GuardReleaser + { + public: + GuardReleaser(std::queue<boost::shared_ptr<AsyncSocketBase> >& guards) : mGuards(guards) {} + ~GuardReleaser() { mGuards.pop(); } + private: + std::queue<boost::shared_ptr<AsyncSocketBase> >& mGuards; + }; + + asio::deadline_timer mAllocationTimer; + void startAllocationTimer(); + void cancelAllocationTimer(); + void allocationTimerExpired(const asio::error_code& e); + + typedef std::map<unsigned short, asio::deadline_timer*> ChannelBindingTimerMap; + ChannelBindingTimerMap mChannelBindingTimers; + void startChannelBindingTimer(unsigned short channel); + void cancelChannelBindingTimers(); + void channelBindingTimerExpired(const asio::error_code& e, unsigned short channel); + + void doRequestSharedSecret(); + void doSetUsernameAndPassword(resip::Data* username, resip::Data* password, bool shortTermAuth); + void doBindRequest(); + void doCreateAllocation(unsigned int lifetime = UnspecifiedLifetime, + unsigned int bandwidth = UnspecifiedBandwidth, + unsigned char requestedPortProps = StunMessage::PropsNone, + UInt64 reservationToken = 0, + StunTuple::TransportType requestedTransportType = StunTuple::None); + void doRefreshAllocation(unsigned int lifetime); + void doDestroyAllocation(); + void doSetActiveDestination(const asio::ip::address& address, unsigned short port); + void doClearActiveDestination(); + void doSend(boost::shared_ptr<DataBuffer>& data); + void doSendTo(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data); + void doClose(); + void actualClose(); + void doChannelBinding(RemotePeer& remotePeer); + + StunMessage* createNewStunMessage(UInt16 stunclass, UInt16 method, bool addAuthInfo=true); + void sendStunMessage(StunMessage* request, bool reTransmission=false); + void sendTo(RemotePeer& remotePeer, boost::shared_ptr<DataBuffer>& data); + void send(boost::shared_ptr<DataBuffer>& data); // Send unframed data + void send(unsigned short channel, boost::shared_ptr<DataBuffer>& data); // send with turn framing + + asio::error_code handleStunMessage(StunMessage& stunMessage); + asio::error_code handleDataInd(StunMessage& stunMessage); + asio::error_code handleChannelBindResponse(StunMessage &request, StunMessage &response); + asio::error_code handleSharedSecretResponse(StunMessage &request, StunMessage &response); + asio::error_code handleBindRequest(StunMessage& stunMessage); + asio::error_code handleBindResponse(StunMessage &request, StunMessage &response); + asio::error_code handleAllocateResponse(StunMessage &request, StunMessage &response); + asio::error_code handleRefreshResponse(StunMessage &request, StunMessage &response); +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnAsyncSocketHandler.cxx b/src/libs/resiprocate/reTurn/client/TurnAsyncSocketHandler.cxx new file mode 100644 index 00000000..e75315e4 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnAsyncSocketHandler.cxx @@ -0,0 +1,49 @@ +#include "TurnAsyncSocketHandler.hxx" +using namespace std; + +namespace reTurn { + +TurnAsyncSocketHandler::TurnAsyncSocketHandler() +{ +} + +TurnAsyncSocketHandler::~TurnAsyncSocketHandler() +{ +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnAsyncSocketHandler.hxx b/src/libs/resiprocate/reTurn/client/TurnAsyncSocketHandler.hxx new file mode 100644 index 00000000..b232ae89 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnAsyncSocketHandler.hxx @@ -0,0 +1,85 @@ +#ifndef TURNASYNCSOCKETHANDLER_HXX +#define TURNASYNCSOCKETHANDLER_HXX + +#include <rutil/compat.hxx> +#include <asio.hpp> +#include "../AsyncSocketBaseHandler.hxx" +#include "../DataBuffer.hxx" +#include "../StunTuple.hxx" + +namespace reTurn { + +class TurnAsyncSocketHandler +{ +public: + TurnAsyncSocketHandler(); + virtual ~TurnAsyncSocketHandler(); + + virtual void onConnectSuccess(unsigned int socketDesc, const asio::ip::address& address, unsigned short port) = 0; + virtual void onConnectFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + + virtual void onSharedSecretSuccess(unsigned int socketDesc, const char* username, unsigned int usernameSize, const char* password, unsigned int passwordSize) = 0; + virtual void onSharedSecretFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + + virtual void onBindSuccess(unsigned int socketDesc, const StunTuple& reflexiveTuple) = 0; + virtual void onBindFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + + virtual void onAllocationSuccess(unsigned int socketDesc, const StunTuple& reflexiveTuple, const StunTuple& relayTuple, unsigned int lifetime, unsigned int bandwidth, UInt64 reservationToken) = 0; + virtual void onAllocationFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + + virtual void onRefreshSuccess(unsigned int socketDesc, unsigned int lifetime) = 0; + virtual void onRefreshFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + + virtual void onSetActiveDestinationSuccess(unsigned int socketDesc) = 0; + virtual void onSetActiveDestinationFailure(unsigned int socketDesc, const asio::error_code &e) = 0; + virtual void onClearActiveDestinationSuccess(unsigned int socketDesc) = 0; + virtual void onClearActiveDestinationFailure(unsigned int socketDesc, const asio::error_code &e) = 0; + + //virtual void onReceiveSuccess(unsigned int socketDesc, const asio::ip::address& address, unsigned short port, const char* buffer, unsigned int size) = 0; + virtual void onReceiveSuccess(unsigned int socketDesc, const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) = 0; + virtual void onReceiveFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + + virtual void onSendSuccess(unsigned int socketDesc) = 0; + virtual void onSendFailure(unsigned int socketDesc, const asio::error_code& e) = 0; + +private: +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnAsyncTcpSocket.cxx b/src/libs/resiprocate/reTurn/client/TurnAsyncTcpSocket.cxx new file mode 100644 index 00000000..9d427d01 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnAsyncTcpSocket.cxx @@ -0,0 +1,101 @@ +#include "TurnAsyncTcpSocket.hxx" +#include <boost/bind.hpp> + +// Remove warning about 'this' use in initiator list - pointer is only stored +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) // using this in base member initializer list +#endif + +using namespace std; + +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) +#endif + +namespace reTurn { + +TurnAsyncTcpSocket::TurnAsyncTcpSocket(asio::io_service& ioService, + TurnAsyncSocketHandler* turnAsyncSocketHandler, + const asio::ip::address& address, + unsigned short port) : + TurnAsyncSocket(ioService, *this, turnAsyncSocketHandler, address, port), + AsyncTcpSocketBase(ioService) +{ + mLocalBinding.setTransportType(StunTuple::TCP); + bind(address, port); +} + +void +TurnAsyncTcpSocket::onConnectSuccess() +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onConnectSuccess(getSocketDescriptor(), mConnectedAddress, mConnectedPort); + turnReceive(); +} + +void +TurnAsyncTcpSocket::onConnectFailure(const asio::error_code& e) +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onConnectFailure(getSocketDescriptor(), e); +} + +void +TurnAsyncTcpSocket::onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) +{ + handleReceivedData(address, port, data); + turnReceive(); +} + +void +TurnAsyncTcpSocket::onReceiveFailure(const asio::error_code& e) +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onReceiveFailure(getSocketDescriptor(), e); +} + +void +TurnAsyncTcpSocket::onSendSuccess() +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSendSuccess(getSocketDescriptor()); +} + +void +TurnAsyncTcpSocket::onSendFailure(const asio::error_code& e) +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSendFailure(getSocketDescriptor(), e); +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnAsyncTcpSocket.hxx b/src/libs/resiprocate/reTurn/client/TurnAsyncTcpSocket.hxx new file mode 100644 index 00000000..0506222a --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnAsyncTcpSocket.hxx @@ -0,0 +1,70 @@ +#ifndef TURNASYNCTCPSOCKET_HXX +#define TURNASYNCTCPSOCKET_HXX + +#include <asio.hpp> + +#include "TurnAsyncSocket.hxx" +#include "../AsyncTcpSocketBase.hxx" + +namespace reTurn { + +class TurnAsyncTcpSocket : public TurnAsyncSocket, public AsyncTcpSocketBase +{ +public: + explicit TurnAsyncTcpSocket(asio::io_service& ioService, + TurnAsyncSocketHandler* turnAsyncSocketHandler, + const asio::ip::address& address = UnspecifiedIpAddress, + unsigned short port = 0); + + virtual unsigned int getSocketDescriptor() { return mSocket.native(); } + +protected: + +private: + // AsyncTcpSocketBase callbacks + virtual void onConnectSuccess(); + virtual void onConnectFailure(const asio::error_code& e); + virtual void onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data); + virtual void onReceiveFailure(const asio::error_code& e); + virtual void onSendSuccess(); + virtual void onSendFailure(const asio::error_code& e); +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnAsyncTlsSocket.cxx b/src/libs/resiprocate/reTurn/client/TurnAsyncTlsSocket.cxx new file mode 100644 index 00000000..5172cc4e --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnAsyncTlsSocket.cxx @@ -0,0 +1,105 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#ifdef USE_SSL +#include "TurnAsyncTlsSocket.hxx" +#include <boost/bind.hpp> + +using namespace std; + +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) +#endif + +namespace reTurn { + +TurnAsyncTlsSocket::TurnAsyncTlsSocket(asio::io_service& ioService, + asio::ssl::context& sslContext, + bool validateServerCertificateHostname, + TurnAsyncSocketHandler* turnAsyncSocketHandler, + const asio::ip::address& address, + unsigned short port) : + TurnAsyncSocket(ioService, *this, turnAsyncSocketHandler, address, port), + AsyncTlsSocketBase(ioService, sslContext, validateServerCertificateHostname) +{ + mLocalBinding.setTransportType(StunTuple::TLS); + + bind(address, port); +} + +void +TurnAsyncTlsSocket::onConnectSuccess() +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onConnectSuccess(getSocketDescriptor(), mConnectedAddress, mConnectedPort); + turnReceive(); +} + +void +TurnAsyncTlsSocket::onConnectFailure(const asio::error_code& e) +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onConnectFailure(getSocketDescriptor(), e); +} + +void +TurnAsyncTlsSocket::onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) +{ + handleReceivedData(address, port, data); + turnReceive(); +} + +void +TurnAsyncTlsSocket::onReceiveFailure(const asio::error_code& e) +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onReceiveFailure(getSocketDescriptor(), e); +} + +void +TurnAsyncTlsSocket::onSendSuccess() +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSendSuccess(getSocketDescriptor()); +} + +void +TurnAsyncTlsSocket::onSendFailure(const asio::error_code& e) +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSendFailure(getSocketDescriptor(), e); +} + +} // namespace +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnAsyncTlsSocket.hxx b/src/libs/resiprocate/reTurn/client/TurnAsyncTlsSocket.hxx new file mode 100644 index 00000000..7af6544d --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnAsyncTlsSocket.hxx @@ -0,0 +1,79 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#ifdef USE_SSL +#ifndef TURNASYNCTLSSOCKET_HXX +#define TURNASYNCTLSSOCKET_HXX + +#include <asio.hpp> +#include <asio/ssl.hpp> + +#include "TurnAsyncTcpSocket.hxx" +#include "../AsyncTlsSocketBase.hxx" + +namespace reTurn { + +class TurnAsyncTlsSocket : public TurnAsyncSocket, public AsyncTlsSocketBase +{ +public: + explicit TurnAsyncTlsSocket(asio::io_service& ioService, + asio::ssl::context& sslContext, + bool validateServerCertificateHostname, + TurnAsyncSocketHandler* turnAsyncSocketHandler, + const asio::ip::address& address = UnspecifiedIpAddress, + unsigned short port = 0); + + virtual unsigned int getSocketDescriptor() { return mSocket.lowest_layer().native(); } + +protected: + +private: + // AsyncTcpSocketBase callbacks + virtual void onConnectSuccess(); + virtual void onConnectFailure(const asio::error_code& e); + virtual void onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data); + virtual void onReceiveFailure(const asio::error_code& e); + virtual void onSendSuccess(); + virtual void onSendFailure(const asio::error_code& e); +}; + +} + +#endif +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnAsyncUdpSocket.cxx b/src/libs/resiprocate/reTurn/client/TurnAsyncUdpSocket.cxx new file mode 100644 index 00000000..09cbe1c4 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnAsyncUdpSocket.cxx @@ -0,0 +1,101 @@ +#include "TurnAsyncUdpSocket.hxx" +#include <boost/bind.hpp> + +// Remove warning about 'this' use in initiator list - pointer is only stored +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) // using this in base member initializer list +#endif + +using namespace std; + +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) +#endif + +namespace reTurn { + +TurnAsyncUdpSocket::TurnAsyncUdpSocket(asio::io_service& ioService, + TurnAsyncSocketHandler* turnAsyncSocketHandler, + const asio::ip::address& address, + unsigned short port) : + TurnAsyncSocket(ioService, *this, turnAsyncSocketHandler, address, port), + AsyncUdpSocketBase(ioService) +{ + mLocalBinding.setTransportType(StunTuple::UDP); + bind(address, port); +} + +void +TurnAsyncUdpSocket::onConnectSuccess() +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onConnectSuccess(getSocketDescriptor(), mConnectedAddress, mConnectedPort); + turnReceive(); +} + +void +TurnAsyncUdpSocket::onConnectFailure(const asio::error_code& e) +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onConnectFailure(getSocketDescriptor(), e); +} + +void +TurnAsyncUdpSocket::onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) +{ + handleReceivedData(address, port, data); + turnReceive(); +} + +void +TurnAsyncUdpSocket::onReceiveFailure(const asio::error_code& e) +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onReceiveFailure(getSocketDescriptor(), e); +} + +void +TurnAsyncUdpSocket::onSendSuccess() +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSendSuccess(getSocketDescriptor()); +} + +void +TurnAsyncUdpSocket::onSendFailure(const asio::error_code& e) +{ + if(mTurnAsyncSocketHandler) mTurnAsyncSocketHandler->onSendFailure(getSocketDescriptor(), e); +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnAsyncUdpSocket.hxx b/src/libs/resiprocate/reTurn/client/TurnAsyncUdpSocket.hxx new file mode 100644 index 00000000..5b8cf394 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnAsyncUdpSocket.hxx @@ -0,0 +1,70 @@ +#ifndef TURNASYNCUDPSOCKET_HXX +#define TURNASYNCUDPSOCKET_HXX + +#include <asio.hpp> + +#include "TurnAsyncSocket.hxx" +#include "../AsyncUdpSocketBase.hxx" + +namespace reTurn { + + class TurnAsyncUdpSocket : public TurnAsyncSocket, public AsyncUdpSocketBase +{ +public: + explicit TurnAsyncUdpSocket(asio::io_service& ioService, + TurnAsyncSocketHandler* turnAsyncSocketHandler, + const asio::ip::address& address, + unsigned short port); + + virtual unsigned int getSocketDescriptor() { return mSocket.native(); } + +protected: + +private: + // AsyncUdpSocketBase callbacks + virtual void onConnectSuccess(); + virtual void onConnectFailure(const asio::error_code& e); + virtual void onReceiveSuccess(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data); + virtual void onReceiveFailure(const asio::error_code& e); + virtual void onSendSuccess(); + virtual void onSendFailure(const asio::error_code& e); +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnSocket.cxx b/src/libs/resiprocate/reTurn/client/TurnSocket.cxx new file mode 100644 index 00000000..9313864c --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnSocket.cxx @@ -0,0 +1,1099 @@ +#include "TurnSocket.hxx" +#include "ErrorCode.hxx" +#include <boost/bind.hpp> +#include <rutil/Lock.hxx> +#include <rutil/WinLeakCheck.hxx> +#include <rutil/Logger.hxx> +#include "../ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; +using namespace resip; + +#define UDP_RT0 100 // RTO - Estimate of Roundtrip time - 100ms is recommened for fixed line transport - the initial value should be configurable + // Should also be calculation this on the fly +#define UDP_MAX_RETRANSMITS 7 // Defined by RFC5389 (Rc) - should be configurable +#define TCP_RESPONSE_TIME 39500 // Defined by RFC5389 (Ti) - should be configurable +#define UDP_Rm 16 // Defined by RFC5389 - should be configurable +#define UDP_FINAL_REQUEST_TIME (UDP_RT0 * UDP_Rm) // Defined by RFC5389 + +//#define TURN_CHANNEL_BINDING_REFRESH_SECONDS 20 // TESTING only +#define TURN_CHANNEL_BINDING_REFRESH_SECONDS 240 // 4 minuntes - this is one minute before the permission will expire, Note: ChannelBinding refreshes also refresh permissions + +#define SOFTWARE_STRING "reTURN Sync Client 0.3 - RFC5389/turn-12" + +namespace reTurn { + +// Initialize static members +unsigned int TurnSocket::UnspecifiedLifetime = 0xFFFFFFFF; +unsigned int TurnSocket::UnspecifiedBandwidth = 0xFFFFFFFF; +unsigned short TurnSocket::UnspecifiedToken = 0; +asio::ip::address TurnSocket::UnspecifiedIpAddress = asio::ip::address::from_string("0.0.0.0"); + +TurnSocket::TurnSocket(const asio::ip::address& address, unsigned short port) : + mLocalBinding(StunTuple::None /* Set properly by sub class */, address, port), + mHaveAllocation(false), + mActiveDestination(0), + mReadTimer(mIOService), + mConnected(false) +{ +} + +TurnSocket::~TurnSocket() +{ +} + +asio::error_code +TurnSocket::requestSharedSecret(char* username, unsigned int usernameSize, + char* password, unsigned int passwordSize) +{ + asio::error_code errorCode; + resip::Lock lock(mMutex); + + // Should we check here if TLS and deny? + + // Ensure Connected + if(!mConnected) + { + return asio::error_code(reTurn::NotConnected, asio::error::misc_category); + } + + // Form Shared Secret request + StunMessage request; + request.createHeader(StunMessage::StunClassRequest, StunMessage::SharedSecretMethod); + + // Get Response + StunMessage* response = sendRequestAndGetResponse(request, errorCode, false); + if(response == 0) + { + return errorCode; + } + + // Check if success or not + if(response->mHasErrorCode) + { + errorCode = asio::error_code(response->mErrorCode.errorClass * 100 + response->mErrorCode.number, asio::error::misc_category); + delete response; + return errorCode; + } + + // Copy username and password to callers buffer - checking sizes first + if(!response->mHasUsername || !response->mHasPassword) + { + WarningLog(<< "Stun response message for SharedSecretRequest is missing username and/or password!"); + errorCode = asio::error_code(reTurn::MissingAuthenticationAttributes, asio::error::misc_category); + delete response; + return errorCode; + } + + if(response->mUsername->size() > usernameSize || response->mPassword->size() > passwordSize) + { + WarningLog( << "Stun response message for SharedSecretRequest contains data that is too large to return!"); + errorCode = asio::error_code(reTurn::BufferTooSmall, asio::error::misc_category); + delete response; + return errorCode; + } + + // Copy username and password to passed in buffers + memcpy(username, response->mUsername->c_str(), response->mUsername->size()+1); + memcpy(password, response->mPassword->c_str(), response->mPassword->size()+1); + + // All was well - return 0 errorCode + delete response; + return errorCode; +} + +void +TurnSocket::setUsernameAndPassword(const char* username, const char* password, bool shortTermAuth) +{ + mUsername = username; + mPassword = password; + if(shortTermAuth) + { + // If we are using short term auth, then use short term password as HMAC key + mHmacKey = password; + } +} + +asio::error_code +TurnSocket::bindRequest() +{ + asio::error_code errorCode; + resip::Lock lock(mMutex); + + // Ensure Connected + if(!mConnected) + { + return asio::error_code(reTurn::NotConnected, asio::error::misc_category); + } + + // Form Stun Bind request + StunMessage request; + request.createHeader(StunMessage::StunClassRequest, StunMessage::BindMethod); + + StunMessage* response = sendRequestAndGetResponse(request, errorCode); + if(response == 0) + { + return errorCode; + } + + mReflexiveTuple.setTransportType(mLocalBinding.getTransportType()); + if(response->mHasXorMappedAddress) + { + StunMessage::setTupleFromStunAtrAddress(mReflexiveTuple, response->mXorMappedAddress); + } + else if(response->mHasMappedAddress) // Only look at MappedAddress if XorMappedAddress is not found - for backwards compatibility + { + StunMessage::setTupleFromStunAtrAddress(mReflexiveTuple, response->mMappedAddress); + } + + // Check if success or not + if(response->mHasErrorCode) + { + errorCode = asio::error_code(response->mErrorCode.errorClass * 100 + response->mErrorCode.number, asio::error::misc_category); + } + + delete response; + return errorCode; +} + +asio::error_code +TurnSocket::createAllocation(unsigned int lifetime, + unsigned int bandwidth, + unsigned char requestedProps, + UInt64 reservationToken, + StunTuple::TransportType requestedTransportType) +{ + asio::error_code errorCode; + resip::Lock lock(mMutex); + + // Store Allocation Properties + mRequestedLifetime = lifetime; + mRequestedBandwidth = bandwidth; + mRequestedProps = requestedProps; + mReservationToken = reservationToken; + mRequestedTransportType = requestedTransportType; + + // Ensure Connected + if(!mConnected) + { + return asio::error_code(reTurn::NotConnected, asio::error::misc_category); + } + + if(mHaveAllocation) + { + return asio::error_code(reTurn::AlreadyAllocated, asio::error::misc_category); + } + + // Form Turn Allocate request + StunMessage request; + request.createHeader(StunMessage::StunClassRequest, StunMessage::TurnAllocateMethod); + if(mRequestedLifetime != UnspecifiedLifetime) + { + request.mHasTurnLifetime = true; + request.mTurnLifetime = mRequestedLifetime; + } + + if(mRequestedBandwidth != UnspecifiedBandwidth) + { + request.mHasTurnBandwidth = true; + request.mTurnBandwidth = mRequestedBandwidth; + } + + if(mRequestedTransportType == StunTuple::None) + { + mRequestedTransportType = mLocalBinding.getTransportType(); + } + request.mHasTurnRequestedTransport = true; + if(mRequestedTransportType == StunTuple::UDP) + { + request.mTurnRequestedTransport = StunMessage::RequestedTransportUdp; + } + else if(mRequestedTransportType == StunTuple::TCP && + mLocalBinding.getTransportType() != StunTuple::UDP) // Ensure client is not requesting TCP over a UDP transport + { + request.mTurnRequestedTransport = StunMessage::RequestedTransportTcp; + } + else + { + return asio::error_code(reTurn::InvalidRequestedTransport, asio::error::misc_category); + } + + if(mRequestedProps != StunMessage::PropsNone) + { + request.mHasTurnEvenPort = true; + request.mTurnEvenPort.propType = mRequestedProps; + } + else if(mReservationToken != 0) + { + request.mHasTurnReservationToken = true; + request.mTurnReservationToken = mReservationToken; + } + + StunMessage* response = sendRequestAndGetResponse(request, errorCode); + if(response == 0) + { + return errorCode; + } + + if(response->mHasXorMappedAddress) + { + mReflexiveTuple.setTransportType(mLocalBinding.getTransportType()); + StunMessage::setTupleFromStunAtrAddress(mReflexiveTuple, response->mXorMappedAddress); + } + if(response->mHasTurnXorRelayedAddress) + { + // Transport Type is requested type or socket type + if(request.mHasTurnRequestedTransport) + { + mRelayTuple.setTransportType(request.mTurnRequestedTransport == StunMessage::RequestedTransportUdp ? StunTuple::UDP : StunTuple::TCP); + } + else + { + mRelayTuple.setTransportType(mLocalBinding.getTransportType()); + } + StunMessage::setTupleFromStunAtrAddress(mRelayTuple, response->mTurnXorRelayedAddress); + } + if(response->mHasTurnLifetime) + { + mLifetime = response->mTurnLifetime; + } + if(response->mHasTurnBandwidth) + { + mBandwidth = response->mTurnBandwidth; + } + + // Check if success or not + if(response->mHasErrorCode) + { + errorCode = asio::error_code(response->mErrorCode.errorClass * 100 + response->mErrorCode.number, asio::error::misc_category); + delete response; + return errorCode; + } + + // All was well - return 0 errorCode + if(mLifetime != 0) + { + mHaveAllocation = true; + mAllocationRefreshTime = time(0) + ((mLifetime*5)/8); // Allocation refresh should sent before 3/4 lifetime - use 5/8 lifetime + } + delete response; + return errorCode; +} + +asio::error_code +TurnSocket::refreshAllocation() +{ + asio::error_code errorCode; + resip::Lock lock(mMutex); + + // Form Turn Allocate request + StunMessage request; + request.createHeader(StunMessage::StunClassRequest, StunMessage::TurnRefreshMethod); + if(mRequestedLifetime != UnspecifiedLifetime) + { + request.mHasTurnLifetime = true; + request.mTurnLifetime = mRequestedLifetime; + } + if(mRequestedBandwidth != UnspecifiedBandwidth) + { + request.mHasTurnBandwidth = true; + request.mTurnBandwidth = mRequestedBandwidth; + } + + StunMessage* response = sendRequestAndGetResponse(request, errorCode); + if(response == 0) + { + return errorCode; + } + + // Check if success or not + if(response->mHasErrorCode) + { + if(mRequestedLifetime != 0 || + (response->mErrorCode.errorClass == 4 && response->mErrorCode.number == 37)) // if we receive a 437 response to a refresh, we should ensure the allocation is destroyed + { + mHaveAllocation = false; + } + + errorCode = asio::error_code(response->mErrorCode.errorClass * 100 + response->mErrorCode.number, asio::error::misc_category); + delete response; + return errorCode; + } + + // All was well - return 0 errorCode + if(mLifetime != 0) + { + mHaveAllocation = true; + mAllocationRefreshTime = time(0) + ((mLifetime*5)/8); // Allocation refresh should sent before 3/4 lifetime - use 5/8 lifetime + } + else + { + mHaveAllocation = false; + } + delete response; + return errorCode; +} + +asio::error_code +TurnSocket::destroyAllocation() +{ + resip::Lock lock(mMutex); + if(mHaveAllocation) + { + mRequestedLifetime = 0; + mRequestedBandwidth = UnspecifiedBandwidth; + mRequestedProps = StunMessage::PropsNone; + mReservationToken = UnspecifiedToken; + mRequestedTransportType = StunTuple::None; + + return refreshAllocation(); + } + else + { + return asio::error_code(reTurn::NoAllocation, asio::error::misc_category); + } +} + +StunTuple& +TurnSocket::getRelayTuple() +{ + return mRelayTuple; +} + +StunTuple& +TurnSocket::getReflexiveTuple() +{ + return mReflexiveTuple; +} + +unsigned int +TurnSocket::getLifetime() +{ + return mLifetime; +} + +unsigned int +TurnSocket::getBandwidth() +{ + return mBandwidth; +} + +asio::error_code +TurnSocket::setActiveDestination(const asio::ip::address& address, unsigned short port) +{ + asio::error_code errorCode; + resip::Lock lock(mMutex); + + // ensure there is an allocation + if(!mHaveAllocation) + { + if(mConnected) + { + // TODO - Disconnect + } + return connect(address.to_string(), port); + //return asio::error_code(reTurn::NoAllocation, asio::error::misc_category); + } + + // Ensure Connected + if(!mConnected) + { + return asio::error_code(reTurn::NotConnected, asio::error::misc_category); + } + + // Setup Remote Peer + StunTuple remoteTuple(mRelayTuple.getTransportType(), address, port); + RemotePeer* remotePeer = mChannelManager.findRemotePeerByPeerAddress(remoteTuple); + if(remotePeer) + { + mActiveDestination = remotePeer; + } + else + { + // No remote peer yet (ie. not data sent or received from remote peer) - so create one + mActiveDestination = mChannelManager.createChannelBinding(remoteTuple); + assert(mActiveDestination); + errorCode = channelBind(*mActiveDestination); + } + + return errorCode; +} + +asio::error_code +TurnSocket::channelBind(RemotePeer& remotePeer) +{ + asio::error_code ret; + + // Form Channel Bind request + StunMessage request; + request.createHeader(StunMessage::StunClassRequest, StunMessage::TurnChannelBindMethod); + + // Set headers + request.mHasTurnChannelNumber = true; + request.mTurnChannelNumber = remotePeer.getChannel(); + request.mCntTurnXorPeerAddress = 1; + StunMessage::setStunAtrAddressFromTuple(request.mTurnXorPeerAddress[0], remotePeer.getPeerTuple()); + + StunMessage* response = sendRequestAndGetResponse(request, ret); + if(response == 0) + { + return ret; + } + + // Check if success or not + if(response->mHasErrorCode) + { + ret = asio::error_code(response->mErrorCode.errorClass * 100 + response->mErrorCode.number, asio::error::misc_category); + delete response; + return ret; + } + + remotePeer.refresh(); + remotePeer.setChannelConfirmed(); + mChannelBindingRefreshTimes[remotePeer.getChannel()] = time(0) + TURN_CHANNEL_BINDING_REFRESH_SECONDS; + + return ret; +} + +asio::error_code +TurnSocket::clearActiveDestination() +{ + asio::error_code errorCode; + resip::Lock lock(mMutex); + + // ensure there is an allocation + if(!mHaveAllocation) + { + return asio::error_code(reTurn::NoAllocation, asio::error::misc_category); + } + + mActiveDestination = 0; + + return errorCode; +} + +asio::error_code +TurnSocket::send(const char* buffer, unsigned int size) +{ + // Allow raw data to be sent if there is no allocation + if(!mHaveAllocation && mConnected) + { + return rawWrite(buffer, size); + } + + if(!mActiveDestination) + { + return asio::error_code(reTurn::NoActiveDestination, asio::error::misc_category); + } + + return sendTo(*mActiveDestination, buffer, size); +} + +asio::error_code +TurnSocket::sendTo(const asio::ip::address& address, unsigned short port, const char* buffer, unsigned int size) +{ + resip::Lock lock(mMutex); + // ensure there is an allocation + if(!mHaveAllocation) + { + return asio::error_code(reTurn::NoAllocation, asio::error::misc_category); + } + + // Setup Remote Peer + StunTuple remoteTuple(mRelayTuple.getTransportType(), address, port); + RemotePeer* remotePeer = mChannelManager.findRemotePeerByPeerAddress(remoteTuple); + if(!remotePeer) + { + // No remote peer - then just create a temp one for sending + // For blocking TurnSocket we do not send ChannelBind unless setActiveDestination is used + // to avoid blocking on the sendTo call + RemotePeer remotePeer(remoteTuple, 0 /* channel - not important */, 0 /* lifetime - not important */); + return sendTo(remotePeer, buffer, size); + } + else + { + return sendTo(*remotePeer, buffer, size); + } +} + +asio::error_code +TurnSocket::sendTo(RemotePeer& remotePeer, const char* buffer, unsigned int size) +{ + resip::Lock lock(mMutex); + + // Check to see if an allocation refresh is required - if so send it and make sure it was sucessful + asio::error_code ret = checkIfAllocationRefreshRequired(); + if(ret) + { + return ret; + } + + // Check to see if a channel binding refresh is required - if so send it and make sure it was successful + ret = checkIfChannelBindingRefreshRequired(); + if(ret) + { + return ret; + } + + if(remotePeer.isChannelConfirmed()) + { + // send framed data to active destination + char framing[4]; + unsigned short channelNumber = remotePeer.getChannel(); + channelNumber = htons(channelNumber); + memcpy(&framing[0], &channelNumber, 2); + if(mLocalBinding.getTransportType() == StunTuple::UDP) + { + // No size in header for UDP + framing[2] = 0x00; + framing[3] = 0x00; + } + else + { + UInt16 turnDataSize = size; + turnDataSize = htons(turnDataSize); + memcpy((void*)&framing[2], &turnDataSize, 2); + } + std::vector<asio::const_buffer> bufs; + bufs.push_back(asio::buffer(framing, sizeof(framing))); + bufs.push_back(asio::buffer(buffer, size)); + + return rawWrite(bufs); + } + else + { + // Data must be wrapped in a Send Indication + // Wrap data in a SendInd + StunMessage ind; + ind.createHeader(StunMessage::StunClassIndication, StunMessage::TurnSendMethod); + ind.mCntTurnXorPeerAddress = 1; + ind.mTurnXorPeerAddress[0].port = remotePeer.getPeerTuple().getPort(); + if(remotePeer.getPeerTuple().getAddress().is_v6()) + { + ind.mTurnXorPeerAddress[0].family = StunMessage::IPv6Family; + memcpy(&ind.mTurnXorPeerAddress[0].addr.ipv6, remotePeer.getPeerTuple().getAddress().to_v6().to_bytes().c_array(), sizeof(ind.mTurnXorPeerAddress[0].addr.ipv6)); + } + else + { + ind.mTurnXorPeerAddress[0].family = StunMessage::IPv4Family; + ind.mTurnXorPeerAddress[0].addr.ipv4 = remotePeer.getPeerTuple().getAddress().to_v4().to_ulong(); + } + if(size > 0) + { + ind.setTurnData(buffer, size); + } + + // Send indication to Turn Server + unsigned int msgsize = ind.stunEncodeMessage(mWriteBuffer, sizeof(mWriteBuffer)); + return rawWrite(mWriteBuffer, msgsize); + } +} + +asio::error_code +TurnSocket::receive(char* buffer, unsigned int& size, unsigned int timeout, asio::ip::address* sourceAddress, unsigned short* sourcePort) +{ + asio::error_code errorCode; + resip::Lock lock(mMutex); + bool done = false; + + // TODO - rethink this scheme so that we don't need to copy recieved data + // TODO - if we loop around more than once - timeout needs to be adjusted + + while(!done) + { + done = true; + + // Wait for response + unsigned int readSize; + errorCode = rawRead(timeout, &readSize, sourceAddress, sourcePort); // Note: SourceAddress and sourcePort may be overwritten below if from Turn Relay + if(errorCode) + { + return errorCode; + } + + // Note if this is a UDP RFC3489 back compat socket, then allocations are not allowed and handleRawData will always be used + if(!mHaveAllocation) + { + return handleRawData(mReadBuffer, readSize, readSize, buffer, size); + } + + if(readSize > 4) + { + // Stun Message has first two bits as 00 + if((mReadBuffer[0] & 0xC0) == 0) + { + // StunMessage + StunMessage* stunMsg = new StunMessage(mLocalBinding, mConnectedTuple, &mReadBuffer[0], readSize); + unsigned int tempsize = size; + errorCode = handleStunMessage(*stunMsg, buffer, tempsize, sourceAddress, sourcePort); + if(!errorCode && tempsize == 0) // Signifies that a Stun/Turn request was received and there is nothing to return to receive caller + { + done = false; + } + else + { + size = tempsize; + } + } + else // Channel Data Message + { + unsigned short channelNumber; + memcpy(&channelNumber, &mReadBuffer[0], 2); + channelNumber = ntohs(channelNumber); + + RemotePeer* remotePeer = mChannelManager.findRemotePeerByChannel(channelNumber); + if(remotePeer) + { + UInt16 dataLen; + memcpy(&dataLen, &mReadBuffer[2], 2); + dataLen = ntohs(dataLen); + + if(sourceAddress) + { + *sourceAddress = remotePeer->getPeerTuple().getAddress(); + } + if(sourcePort) + { + *sourcePort = remotePeer->getPeerTuple().getPort(); + } + errorCode = handleRawData(&mReadBuffer[4], readSize-4, dataLen, buffer, size); + } + else + { + // Invalid Channel - teardown? + errorCode = asio::error_code(reTurn::InvalidChannelNumberReceived, asio::error::misc_category); + done = true; + } + } + } + else // size <= 4 + { + // Less data than frame size received + errorCode = asio::error_code(reTurn::FrameError, asio::error::misc_category); + done = true; + } + } + return errorCode; +} + +asio::error_code +TurnSocket::receiveFrom(const asio::ip::address& address, unsigned short port, char* buffer, unsigned int& size, unsigned int timeout) +{ + asio::ip::address sourceAddress; + unsigned short sourcePort; + bool done = false; + asio::error_code errorCode; + resip::Lock lock(mMutex); + + while(!done) + { + done = true; + errorCode = receive(buffer, size, timeout, &sourceAddress, &sourcePort); + if(!errorCode) + { + if(sourceAddress != address || sourcePort != port) + { + WarningLog(<< "Recevied message but not from requested address/port - Discarding."); + done = false; + } + } + } + return errorCode; +} + +asio::error_code +TurnSocket::handleRawData(char* data, unsigned int dataSize, unsigned int expectedSize, char* buffer, unsigned int& bufferSize) +{ + asio::error_code errorCode; + + if(dataSize != expectedSize) + { + // TODO - fix read logic so that we can read in chuncks + WarningLog(<< "Did not read entire message: read=" << dataSize << " wanted=" << expectedSize); + return asio::error_code(reTurn::ReadError, asio::error::misc_category); + } + + if(dataSize > bufferSize) + { + // Passed in buffer is not large enough + WarningLog(<< "Passed in buffer not large enough."); + return asio::error_code(reTurn::BufferTooSmall, asio::error::misc_category); + } + + // Copy data to return buffer + memcpy(buffer, data, dataSize); + bufferSize = dataSize; + + return errorCode; +} + +asio::error_code +TurnSocket::handleStunMessage(StunMessage& stunMessage, char* buffer, unsigned int& size, asio::ip::address* sourceAddress, unsigned short* sourcePort) +{ + asio::error_code errorCode; + if(stunMessage.isValid()) + { + if(stunMessage.mClass == StunMessage::StunClassIndication && stunMessage.mMethod == StunMessage::TurnDataMethod) + { + if(stunMessage.mUnknownRequiredAttributes.numAttributes > 0) + { + // Unknown Comprehension-Required Attributes found + WarningLog(<< "DataInd with unknown comprehension required attributes."); + return asio::error_code(reTurn::UnknownRequiredAttributes, asio::error::misc_category); + } + + if(stunMessage.mCntTurnXorPeerAddress == 0 || !stunMessage.mHasTurnData) + { + // Missing RemoteAddress or TurnData attribute + WarningLog(<< "DataInd missing attributes."); + return asio::error_code(reTurn::MissingAttributes, asio::error::misc_category); + } + + StunTuple remoteTuple; + remoteTuple.setTransportType(mRelayTuple.getTransportType()); + StunMessage::setTupleFromStunAtrAddress(remoteTuple, stunMessage.mTurnXorPeerAddress[0]); + + RemotePeer* remotePeer = mChannelManager.findRemotePeerByPeerAddress(remoteTuple); + if(!remotePeer) + { + // Remote Peer not found - discard data + WarningLog(<< "Data received from unknown RemotePeer - discarding"); + return asio::error_code(reTurn::UnknownRemoteAddress, asio::error::misc_category); + } + + if(stunMessage.mTurnData->size() > size) + { + // Passed in buffer is not large enough + WarningLog(<< "Passed in buffer not large enough."); + return asio::error_code(reTurn::BufferTooSmall, asio::error::misc_category); + } + + memcpy(buffer, stunMessage.mTurnData->data(), stunMessage.mTurnData->size()); + size = (unsigned int)stunMessage.mTurnData->size(); + + if(sourceAddress != 0) + { + *sourceAddress = remoteTuple.getAddress(); + } + if(sourcePort != 0) + { + *sourcePort = remoteTuple.getPort(); + } + } + else if(stunMessage.mClass == StunMessage::StunClassRequest && stunMessage.mMethod == StunMessage::BindMethod) + { + // Note: handling of BindRequest is not fully backwards compatible with RFC3489 - it is inline with RFC5389 + StunMessage response; + + // form the outgoing message + response.mMethod = StunMessage::BindMethod; + + // Copy over TransactionId + response.mHeader.magicCookieAndTid = stunMessage.mHeader.magicCookieAndTid; + + if(stunMessage.mUnknownRequiredAttributes.numAttributes > 0) + { + // Unknown Comprehension-Required Attributes found + WarningLog(<< "BindRequest with unknown comprehension required attributes."); + + response.mClass = StunMessage::StunClassErrorResponse; + + // Add unknown attributes + response.mHasUnknownAttributes = true; + response.mUnknownAttributes = stunMessage.mUnknownRequiredAttributes; + } + else + { + response.mClass = StunMessage::StunClassSuccessResponse; + + // Add XOrMappedAddress to response + response.mHasXorMappedAddress = true; + StunMessage::setStunAtrAddressFromTuple(response.mXorMappedAddress, stunMessage.mRemoteTuple); + } + + // Add Software Attribute + response.setSoftware(SOFTWARE_STRING); + + // send bind response to local client + unsigned int bufferSize = 512; // enough room for Stun Header + XorMapped Address (v6) or Unknown Attributes + Software Attribute; + resip::Data buffer(bufferSize, resip::Data::Preallocate); + unsigned int writeSize = response.stunEncodeMessage((char*)buffer.data(), bufferSize); + + errorCode = rawWrite(buffer.data(), writeSize); + size = 0; // go back to receiving + } + else if(stunMessage.mClass == StunMessage::StunClassIndication && stunMessage.mMethod == StunMessage::BindMethod) + { + // Nothing to do + size = 0; + } + else if(stunMessage.mClass == StunMessage::StunClassSuccessResponse || stunMessage.mClass == StunMessage::StunClassErrorResponse) + { + // Received a stray or response retranmission - ignore + size = 0; + } + else + { + // TODO - handle others ???? + } + } + else + { + WarningLog(<< "Read Invalid StunMsg."); + return asio::error_code(reTurn::ErrorParsingMessage, asio::error::misc_category); + } + return errorCode; +} + +void +TurnSocket::startReadTimer(unsigned int timeout) +{ + if(timeout != 0) + { + mReadTimer.expires_from_now(boost::posix_time::milliseconds(timeout)); + mReadTimer.async_wait(boost::bind(&TurnSocket::handleRawReadTimeout, this, asio::placeholders::error)); + } +} + +void +TurnSocket::handleRawRead(const asio::error_code& errorCode, size_t bytesRead) +{ + mBytesRead = bytesRead; + mReadErrorCode = errorCode; + mReadTimer.cancel(); +} + +void +TurnSocket::handleRawReadTimeout(const asio::error_code& errorCode) +{ + if(!errorCode) + { + cancelSocket(); + } +} + +asio::error_code +TurnSocket::checkIfAllocationRefreshRequired() +{ + if(mHaveAllocation && (time(0) >= mAllocationRefreshTime)) + { + // Do allocation refresh + return refreshAllocation(); + } + return asio::error_code(); // 0 +} + +asio::error_code +TurnSocket::checkIfChannelBindingRefreshRequired() +{ + asio::error_code ret; // 0 + if(mHaveAllocation) + { + time_t now = time(0); + ChannelBindingRefreshTimeMap::iterator it = mChannelBindingRefreshTimes.begin(); + for(;it!=mChannelBindingRefreshTimes.end();it++) + { + if(it->second != 0 && now >= it->second) + { + it->second = 0; // will be reset by channelBind if success + + // Do channel binding refresh + RemotePeer* remotePeer = mChannelManager.findRemotePeerByChannel(it->first); + if(remotePeer) + { + ret = channelBind(*remotePeer); + } + } + } + } + return ret; +} + +StunMessage* +TurnSocket::sendRequestAndGetResponse(StunMessage& request, asio::error_code& errorCode, bool addAuthInfo) +{ + bool sendRequest = true; + bool reliableTransport = mLocalBinding.getTransportType() != StunTuple::UDP; + unsigned int timeout = reliableTransport ? TCP_RESPONSE_TIME : UDP_RT0; + unsigned int totalTime = 0; + unsigned int requestsSent = 0; + unsigned int readsize = 0; + + // Add Software Attribute + request.setSoftware(SOFTWARE_STRING); + + if(addAuthInfo && !mUsername.empty() && !mHmacKey.empty()) + { + request.mHasMessageIntegrity = true; + request.setUsername(mUsername.c_str()); + request.mHmacKey = mHmacKey; + if(!mRealm.empty()) + { + request.setRealm(mRealm.c_str()); + } + if(!mNonce.empty()) + { + request.setNonce(mNonce.c_str()); + } + } + + unsigned int writesize = request.stunEncodeMessage(mWriteBuffer, sizeof(mWriteBuffer)); + + while(true) + { + if(sendRequest) + { + // Send request to Turn Server + if(requestsSent > 0) + { + DebugLog(<< "TurnSocket: retranmitting request..."); + } + requestsSent++; + errorCode = rawWrite(mWriteBuffer, writesize); + if(errorCode) + { + return 0; + } + sendRequest = false; + } + + // Wait for response + errorCode = rawRead(timeout, &readsize); + if(errorCode) + { + if(errorCode == asio::error::operation_aborted) + { + totalTime += timeout; + if(reliableTransport || requestsSent == UDP_MAX_RETRANSMITS) + { + InfoLog(<< "Timed out waiting for Stun response!"); + errorCode = asio::error_code(reTurn::ResponseTimeout, asio::error::misc_category); + return 0; + } + + // timed out and should retransmit - calculate next timeout + if(requestsSent == UDP_MAX_RETRANSMITS - 1) + { + timeout = UDP_FINAL_REQUEST_TIME; + } + else + { + timeout = (timeout*2); + } + sendRequest = true; + continue; + } + return 0; + } + + if(readsize > 4) + { + // Stun Message has first two bits as 00 + if((mReadBuffer[0] & 0xC0) == 0) + { + StunMessage* response = new StunMessage(mLocalBinding, mConnectedTuple, &mReadBuffer[0], readsize); + + // If response is valid and has no unknown comprehension-required attributes then we can process it + if(response->isValid() && response->mUnknownRequiredAttributes.numAttributes == 0) + { + if(!response->checkMessageIntegrity(request.mHmacKey)) + { + WarningLog(<< "Stun response message integrity is bad!"); + delete response; + errorCode = asio::error_code(reTurn::BadMessageIntegrity, asio::error::misc_category); + return 0; + } + + // Check that TID matches request + if(!(response->mHeader.magicCookieAndTid == request.mHeader.magicCookieAndTid)) + { + InfoLog(<< "Stun response TID does not match request - discarding!"); + delete response; + continue; // read next message + } + + // If response is a 401, then store Realm, nonce, and hmac key + // If a realm and nonce attributes are present and the response is a 401 or 438 (Nonce Expired), + // then re-issue request with new auth attributes + if(response->mHasRealm && + response->mHasNonce && + response->mHasErrorCode && + response->mErrorCode.errorClass == 4 && + ((response->mErrorCode.number == 1 && mHmacKey.empty()) || // Note if 401 error then ensure we haven't already tried once - if we've tried then mHmacKey will be populated + response->mErrorCode.number == 38)) + { + mNonce = *response->mNonce; + mRealm = *response->mRealm; + response->calculateHmacKey(mHmacKey, mUsername, mRealm, mPassword); + + // Re-Issue reques (with new TID) + request.createHeader(request.mClass, request.mMethod); // updates TID + delete response; + return sendRequestAndGetResponse(request, errorCode, true); + } + + errorCode = asio::error_code(reTurn::Success, asio::error::misc_category); + return response; + } + else + { + WarningLog(<< "Stun response message is invalid!"); + delete response; + errorCode = asio::error_code(reTurn::ErrorParsingMessage, asio::error::misc_category); + return 0; + } + } + else // Channel Data Message + { + // TODO - handle buffering of Turn data that is receive while waiting for a Request/Response + errorCode = asio::error_code(reTurn::FrameError, asio::error::misc_category); + return 0; + } + } + else + { + // Less data than frame size received + errorCode = asio::error_code(reTurn::FrameError, asio::error::misc_category); + return 0; + } + } +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnSocket.hxx b/src/libs/resiprocate/reTurn/client/TurnSocket.hxx new file mode 100644 index 00000000..8929eec2 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnSocket.hxx @@ -0,0 +1,174 @@ +#ifndef TURNSOCKET_HXX +#define TURNSOCKET_HXX + +#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ + && !defined(ASIO_ENABLE_CANCELIO) +#error You must define ASIO_ENABLE_CANCELIO in your build settings. +#endif + +#include <vector> +#include <asio.hpp> +#include <rutil/Data.hxx> +#include <rutil/Mutex.hxx> + +#include "../StunTuple.hxx" +#include "../StunMessage.hxx" +#include "../ChannelManager.hxx" + +namespace reTurn { + +class TurnSocket +{ +public: + static unsigned int UnspecifiedLifetime; + static unsigned int UnspecifiedBandwidth; + static unsigned short UnspecifiedToken; + static asio::ip::address UnspecifiedIpAddress; + + explicit TurnSocket(const asio::ip::address& address = UnspecifiedIpAddress, + unsigned short port = 0); + virtual ~TurnSocket(); + + virtual unsigned int getSocketDescriptor() = 0; + virtual asio::error_code connect(const std::string& address, unsigned short port) = 0; // !slg! modify port parameter later to be able to do SRV lookups + + // Note: Shared Secret requests have been deprecated by RFC5389, and not + // widely implemented in RFC3489 - so not really needed at all + asio::error_code requestSharedSecret(char* username, unsigned int usernameSize, + char* password, unsigned int passwordSize); + + // Set the username and password for all future requests + void setUsernameAndPassword(const char* username, const char* password, bool shortTermAuth=false); + + // Stun Binding Method - use getReflexiveTuple() to get binding info + asio::error_code bindRequest(); + + // Turn Allocation Methods + asio::error_code createAllocation(unsigned int lifetime = UnspecifiedLifetime, + unsigned int bandwidth = UnspecifiedBandwidth, + unsigned char requestedProps = StunMessage::PropsNone, + UInt64 reservationToken = UnspecifiedToken, + StunTuple::TransportType requestedTransportType = StunTuple::None); + asio::error_code refreshAllocation(); + asio::error_code destroyAllocation(); + + // Accessors for properties associated with an allocation + StunTuple& getRelayTuple(); + StunTuple& getReflexiveTuple(); + unsigned int getLifetime(); + unsigned int getBandwidth(); + + // Methods to control active destination + asio::error_code setActiveDestination(const asio::ip::address& address, unsigned short port); + asio::error_code clearActiveDestination(); + + // Turn Send Methods + asio::error_code send(const char* buffer, unsigned int size); + asio::error_code sendTo(const asio::ip::address& address, unsigned short port, const char* buffer, unsigned int size); + + // Receive Methods + asio::error_code receive(char* buffer, unsigned int& size, unsigned int timeout, asio::ip::address* sourceAddress=0, unsigned short* sourcePort=0); + asio::error_code receiveFrom(const asio::ip::address& address, unsigned short port, char* buffer, unsigned int& size, unsigned int timeout); + +protected: + virtual asio::error_code rawWrite(const char* buffer, unsigned int size) = 0; + virtual asio::error_code rawWrite(const std::vector<asio::const_buffer>& buffers) = 0; + virtual asio::error_code rawRead(unsigned int timeout, unsigned int* bytesRead, asio::ip::address* sourceAddress=0, unsigned short* sourcePort=0) = 0; + virtual void cancelSocket() = 0; + + // Local Binding Info + StunTuple mLocalBinding; + StunTuple mConnectedTuple; + + // Authentication Info + resip::Data mUsername; + resip::Data mPassword; + resip::Data mHmacKey; + resip::Data mRealm; + resip::Data mNonce; + + // Turn Allocation Properties used in request + unsigned int mRequestedLifetime; + unsigned int mRequestedBandwidth; + unsigned char mRequestedProps; + UInt64 mReservationToken; + StunTuple::TransportType mRequestedTransportType; + + // Turn Allocation Properties from response + bool mHaveAllocation; + time_t mAllocationRefreshTime; + StunTuple mRelayTuple; + StunTuple mReflexiveTuple; + unsigned int mLifetime; + unsigned int mBandwidth; + + ChannelManager mChannelManager; + typedef std::map<unsigned short, time_t> ChannelBindingRefreshTimeMap; + ChannelBindingRefreshTimeMap mChannelBindingRefreshTimes; + RemotePeer* mActiveDestination; + + asio::io_service mIOService; + + // handlers and timers required to do a timed out read + asio::deadline_timer mReadTimer; + size_t mBytesRead; + asio::error_code mReadErrorCode; + void startReadTimer(unsigned int timeout); + void handleRawRead(const asio::error_code& errorCode, size_t bytesRead); + void handleRawReadTimeout(const asio::error_code& errorCode); + + // Read/Write Buffers + char mReadBuffer[8192]; + char mWriteBuffer[8192]; + bool mConnected; + +private: + resip::Mutex mMutex; + asio::error_code channelBind(RemotePeer& remotePeer); + asio::error_code checkIfAllocationRefreshRequired(); + asio::error_code checkIfChannelBindingRefreshRequired(); + StunMessage* sendRequestAndGetResponse(StunMessage& request, asio::error_code& errorCode, bool addAuthInfo=true); + asio::error_code sendTo(RemotePeer& remotePeer, const char* buffer, unsigned int size); + asio::error_code handleStunMessage(StunMessage& stunMessage, char* buffer, unsigned int& size, asio::ip::address* sourceAddress=0, unsigned short* sourcePort=0); + asio::error_code handleRawData(char* data, unsigned int dataSize, unsigned int expectedSize, char* buffer, unsigned int& bufferSize); +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnTcpSocket.cxx b/src/libs/resiprocate/reTurn/client/TurnTcpSocket.cxx new file mode 100644 index 00000000..1a05f6b6 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnTcpSocket.cxx @@ -0,0 +1,197 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "TurnTcpSocket.hxx" +#include <boost/bind.hpp> +#include <rutil/Logger.hxx> +#include "../ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; + +namespace reTurn { + +TurnTcpSocket::TurnTcpSocket(const asio::ip::address& address, unsigned short port) : + TurnSocket(address,port), + mSocket(mIOService) +{ + mLocalBinding.setTransportType(StunTuple::TCP); + + asio::error_code errorCode; + mSocket.open(address.is_v6() ? asio::ip::tcp::v6() : asio::ip::tcp::v4(), errorCode); + if(!errorCode) + { + mSocket.set_option(asio::ip::tcp::no_delay(true)); // ?slg? do we want this? + mSocket.set_option(asio::ip::tcp::socket::reuse_address(true)); + mSocket.bind(asio::ip::tcp::endpoint(mLocalBinding.getAddress(), mLocalBinding.getPort()), errorCode); + } +} + +asio::error_code +TurnTcpSocket::connect(const std::string& address, unsigned short port) +{ + // Get a list of endpoints corresponding to the server name. + asio::ip::tcp::resolver resolver(mIOService); + resip::Data service(port); + asio::ip::tcp::resolver::query query(address, service.c_str()); + asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); + asio::ip::tcp::resolver::iterator end; + + // Try each endpoint until we successfully establish a connection. + asio::error_code errorCode = asio::error::host_not_found; + while (errorCode && endpoint_iterator != end) + { + mSocket.close(); + mSocket.connect(*endpoint_iterator, errorCode); + + if(!errorCode) + { + mConnected = true; + mConnectedTuple.setTransportType(StunTuple::TCP); + mConnectedTuple.setAddress(endpoint_iterator->endpoint().address()); + mConnectedTuple.setPort(endpoint_iterator->endpoint().port()); + } + endpoint_iterator++; + } + + return errorCode; +} + +asio::error_code +TurnTcpSocket::rawWrite(const char* buffer, unsigned int size) +{ + asio::error_code errorCode; + asio::write(mSocket, asio::buffer(buffer, size), asio::transfer_all(), errorCode); + return errorCode; +} + +asio::error_code +TurnTcpSocket::rawWrite(const std::vector<asio::const_buffer>& buffers) +{ + asio::error_code errorCode; + asio::write(mSocket, buffers, asio::transfer_all(), errorCode); + return errorCode; +} + +asio::error_code +TurnTcpSocket::rawRead(unsigned int timeout, unsigned int* bytesRead, asio::ip::address* sourceAddress, unsigned short* sourcePort) +{ + startReadTimer(timeout); + readHeader(); + + // Wait for timer and read to end + mIOService.run(); + mIOService.reset(); + + *bytesRead = (unsigned int)mBytesRead+4; + if(!mReadErrorCode) + { + if(sourceAddress) + { + *sourceAddress = mConnectedTuple.getAddress(); + } + if(sourcePort) + { + *sourcePort = mConnectedTuple.getPort(); + } + } + return mReadErrorCode; +} + +void +TurnTcpSocket::readHeader() +{ + asio::async_read(mSocket, asio::buffer(mReadBuffer, 4), + boost::bind(&TurnTcpSocket::handleReadHeader, this, asio::placeholders::error)); +} + +void +TurnTcpSocket::readBody(unsigned int len) +{ + asio::async_read(mSocket, asio::buffer(&mReadBuffer[4], len), + boost::bind(&TurnTcpSocket::handleRawRead, this, asio::placeholders::error, asio::placeholders::bytes_transferred)); +} + +void +TurnTcpSocket::cancelSocket() +{ + asio::error_code ec; + mSocket.cancel(ec); +} + +void +TurnTcpSocket::handleReadHeader(const asio::error_code& e) +{ + if (!e) + { + /* + std::cout << "Read header from turn tcp socket: " << std::endl; + for(unsigned int i = 0; i < 4; i++) + { + std::cout << (char)mReadBuffer[i] << "(" << (int)mReadBuffer[i] << ") "; + } + std::cout << std::endl; + */ + + // Note: For both StunMessages and ChannelData messages the length in bytes 3 and 4 + UInt16 dataLen; + memcpy(&dataLen, &mReadBuffer[2], 2); + dataLen = ntohs(dataLen); + + if((mReadBuffer[0] & 0xC0) == 0) // If first 2 bits are 00 then this is a stun message + { + dataLen += 16; // There are 20 bytes in total in the header, and we have already read 4 - read the rest of the header + the body + } + + readBody(dataLen); + } + else + { + mBytesRead = 0; + mReadErrorCode = e; + if (e != asio::error::operation_aborted) + { + WarningLog(<< "Read header error: " << e.value() << "-" << e.message()); + mReadTimer.cancel(); + } + } +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnTcpSocket.hxx b/src/libs/resiprocate/reTurn/client/TurnTcpSocket.hxx new file mode 100644 index 00000000..c057c4bb --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnTcpSocket.hxx @@ -0,0 +1,76 @@ +#ifndef TURNTCPSOCKET_HXX +#define TURNTCPSOCKET_HXX + +#include <asio.hpp> + +#include "TurnSocket.hxx" + +namespace reTurn { + + class TurnTcpSocket : public TurnSocket +{ +public: + explicit TurnTcpSocket(const asio::ip::address& address = UnspecifiedIpAddress, + unsigned short port = 0); + + virtual unsigned int getSocketDescriptor() { return mSocket.native(); } + + // To use this socket without a Turn Relay, use this connect call to connect directly + // to endpoint + virtual asio::error_code connect(const std::string& address, unsigned short port); + +protected: + virtual asio::error_code rawWrite(const char* buffer, unsigned int size); + virtual asio::error_code rawWrite(const std::vector<asio::const_buffer>& buffers); + virtual asio::error_code rawRead(unsigned int timeout, unsigned int* bytesRead, asio::ip::address* sourceAddress=0, unsigned short* sourcePort=0); + + virtual void readHeader(); + virtual void readBody(unsigned int len); + virtual void cancelSocket(); + + /// Handle completion of a read operation for first 32 bits + virtual void handleReadHeader(const asio::error_code& e); + +private: + + asio::ip::tcp::socket mSocket; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnTlsSocket.cxx b/src/libs/resiprocate/reTurn/client/TurnTlsSocket.cxx new file mode 100644 index 00000000..3ef06fd8 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnTlsSocket.cxx @@ -0,0 +1,265 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#ifdef USE_SSL +#include "TurnTlsSocket.hxx" +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <boost/bind.hpp> +#include <rutil/Logger.hxx> +#include "../ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +using namespace std; + +namespace reTurn { + +TurnTlsSocket::TurnTlsSocket(bool validateServerCertificateHostname, + const asio::ip::address& address, + unsigned short port) : + TurnTcpSocket(address,port), + mSslContext(mIOService, asio::ssl::context::tlsv1), // TLSv1.0 + mSocket(mIOService, mSslContext), + mValidateServerCertificateHostname(validateServerCertificateHostname) +{ + mLocalBinding.setTransportType(StunTuple::TLS); + + // Setup SSL context + + // Enable certificate validation + mSslContext.set_verify_mode(asio::ssl::context::verify_peer | // Verify the peer. + asio::ssl::context::verify_fail_if_no_peer_cert); // Fail verification if the peer has no certificate. + + // File that should contain all required root certificates + mSslContext.load_verify_file("ca.pem"); + + asio::error_code errorCode; + mSocket.lowest_layer().open(address.is_v6() ? asio::ip::tcp::v6() : asio::ip::tcp::v4(), errorCode); + if(!errorCode) + { + mSocket.lowest_layer().set_option(asio::ip::tcp::socket::reuse_address(true)); + mSocket.lowest_layer().set_option(asio::ip::tcp::no_delay(true)); // ?slg? do we want this? + mSocket.lowest_layer().bind(asio::ip::tcp::endpoint(mLocalBinding.getAddress(), mLocalBinding.getPort()), errorCode); + } +} + +asio::error_code +TurnTlsSocket::connect(const std::string& address, unsigned short port) +{ + // Get a list of endpoints corresponding to the server name. + asio::ip::tcp::resolver resolver(mIOService); + resip::Data service(port); + asio::ip::tcp::resolver::query query(address, service.c_str()); + asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); + asio::ip::tcp::resolver::iterator end; + + // Try each endpoint until we successfully establish a connection. + asio::error_code errorCode = asio::error::host_not_found; + while (errorCode && endpoint_iterator != end) + { + mSocket.lowest_layer().close(); + mSocket.lowest_layer().connect(*endpoint_iterator, errorCode); + if(!errorCode) + { + DebugLog(<< "Connected!"); + mSocket.handshake(asio::ssl::stream_base::client, errorCode); + if(!errorCode) + { + DebugLog(<< "Handshake complete!"); + + // Validate that hostname in cert matches connection hostname + if(!mValidateServerCertificateHostname || validateServerCertificateHostname(address)) + { + mConnected = true; + mConnectedTuple.setTransportType(StunTuple::TLS); + mConnectedTuple.setAddress(endpoint_iterator->endpoint().address()); + mConnectedTuple.setPort(endpoint_iterator->endpoint().port()); + } + else + { + WarningLog(<< "Hostname in certificate does not match connection hostname!"); + mSocket.lowest_layer().close(); + errorCode = asio::error::operation_aborted; + } + } + } + endpoint_iterator++; + } + + return errorCode; +} + +bool +TurnTlsSocket::validateServerCertificateHostname(const std::string& hostname) +{ + bool valid = false; + + // Validate that hostname in cert matches connection hostname + + // print session info + const SSL_CIPHER *ciph; + ciph=SSL_get_current_cipher(mSocket.impl()->ssl); + InfoLog( << "TLS session set up with " + << SSL_get_version(mSocket.impl()->ssl) << " " + << SSL_CIPHER_get_version(ciph) << " " + << SSL_CIPHER_get_name(ciph) << " " ); + + // get the certificate - should always exist since mode is set for SSL to verify the cert first + X509* cert = SSL_get_peer_certificate(mSocket.impl()->ssl); + assert(cert); + + // Look at the SubjectAltName, and if found, set as peerName + bool hostnamePresentInSubjectAltName = false; + GENERAL_NAMES* gens; + gens = (GENERAL_NAMES*)X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0); + for(int i = 0; i < sk_GENERAL_NAME_num(gens); i++) + { + GENERAL_NAME* gen = sk_GENERAL_NAME_value(gens, i); + + DebugLog(<< "subjectAltName of cert contains type <" << gen->type << ">" ); + + if (gen->type == GEN_DNS) + { + ASN1_IA5STRING* asn = gen->d.dNSName; + resip::Data dns(asn->data, asn->length); + InfoLog(<< "subjectAltName of TLS session cert contains DNS <" << dns << ">" ); + hostnamePresentInSubjectAltName = true; + if(resip::isEqualNoCase(dns, hostname.c_str())) + { + valid = true; + break; + } + } + + if (gen->type == GEN_EMAIL) + { + DebugLog(<< "subjectAltName of cert has EMAIL type" ); + } + + if(gen->type == GEN_URI) + { + DebugLog(<< "subjectAltName of cert has URI type" ); + } + } + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + + // If there are no peer names from the subjectAltName, then use the commonName + if(!hostnamePresentInSubjectAltName) + { + // look at the Common Name to find the peerName of the cert + X509_NAME* subject = X509_get_subject_name(cert); + if(!subject) + { + ErrLog( << "Invalid certificate: subject not found "); + } + + int i =-1; + while( !valid ) + { + i = X509_NAME_get_index_by_NID(subject, NID_commonName,i); + if ( i == -1 ) + { + break; + } + assert( i != -1 ); + X509_NAME_ENTRY* entry = X509_NAME_get_entry(subject,i); + assert( entry ); + + ASN1_STRING* s = X509_NAME_ENTRY_get_data(entry); + assert( s ); + + int t = M_ASN1_STRING_type(s); + int l = M_ASN1_STRING_length(s); + unsigned char* d = M_ASN1_STRING_data(s); + resip::Data name(d,l); + DebugLog( << "got x509 string type=" << t << " len="<< l << " data=" << d ); + assert( name.size() == (unsigned)l ); + + InfoLog( << "Found common name in cert: " << name ); + if(resip::isEqualNoCase(name, hostname.c_str())) + { + valid = true; + } + } + } + + X509_free(cert); + return valid; +} + +asio::error_code +TurnTlsSocket::rawWrite(const char* buffer, unsigned int size) +{ + asio::error_code errorCode; + asio::write(mSocket, asio::buffer(buffer, size), asio::transfer_all(), errorCode); + return errorCode; +} + +asio::error_code +TurnTlsSocket::rawWrite(const std::vector<asio::const_buffer>& buffers) +{ + asio::error_code errorCode; + asio::write(mSocket, buffers, asio::transfer_all(), errorCode); + return errorCode; +} + +void +TurnTlsSocket::readHeader() +{ + asio::async_read(mSocket, asio::buffer(mReadBuffer, 4), + boost::bind(&TurnTlsSocket::handleReadHeader, this, asio::placeholders::error)); +} + +void +TurnTlsSocket::readBody(unsigned int len) +{ + asio::async_read(mSocket, asio::buffer(&mReadBuffer[4], len), + boost::bind(&TurnTlsSocket::handleRawRead, this, asio::placeholders::error, asio::placeholders::bytes_transferred)); +} + +void +TurnTlsSocket::cancelSocket() +{ + asio::error_code ec; + mSocket.lowest_layer().cancel(ec); +} + +} // namespace +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnTlsSocket.hxx b/src/libs/resiprocate/reTurn/client/TurnTlsSocket.hxx new file mode 100644 index 00000000..38867653 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnTlsSocket.hxx @@ -0,0 +1,80 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#ifdef USE_SSL +#ifndef TURNTLSSOCKET_HXX +#define TURNTLSSOCKET_HXX + +#include <asio.hpp> +#include <asio/ssl.hpp> + +#include "TurnTcpSocket.hxx" + +namespace reTurn { + + class TurnTlsSocket : public TurnTcpSocket +{ +public: + explicit TurnTlsSocket(bool validateServerCertificateHostname, + const asio::ip::address& address = UnspecifiedIpAddress, + unsigned short port = 0); + + virtual unsigned int getSocketDescriptor() { return mSocket.lowest_layer().native(); } + virtual asio::error_code connect(const std::string& address, unsigned short port); + +protected: + virtual bool validateServerCertificateHostname(const std::string& hostname); + + virtual asio::error_code rawWrite(const char* buffer, unsigned int size); + virtual asio::error_code rawWrite(const std::vector<asio::const_buffer>& buffers); + + virtual void readHeader(); + virtual void readBody(unsigned int len); + virtual void cancelSocket(); + +private: + asio::ssl::context mSslContext; + asio::ssl::stream<asio::ip::tcp::socket> mSocket; + bool mValidateServerCertificateHostname; +}; + +} + +#endif +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnUdpSocket.cxx b/src/libs/resiprocate/reTurn/client/TurnUdpSocket.cxx new file mode 100644 index 00000000..d3815117 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnUdpSocket.cxx @@ -0,0 +1,141 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "TurnUdpSocket.hxx" +#include <boost/bind.hpp> + +using namespace std; + +namespace reTurn { + +TurnUdpSocket::TurnUdpSocket(const asio::ip::address& address, unsigned short port) : + TurnSocket(address,port), + mSocket(mIOService) +{ + mLocalBinding.setTransportType(StunTuple::UDP); + + asio::error_code errorCode; + mSocket.open(address.is_v6() ? asio::ip::udp::v6() : asio::ip::udp::v4(), errorCode); + if(!errorCode) + { + mSocket.set_option(asio::ip::udp::socket::reuse_address(true)); + mSocket.bind(asio::ip::udp::endpoint(mLocalBinding.getAddress(), mLocalBinding.getPort()), errorCode); + } +} + +asio::error_code +TurnUdpSocket::connect(const std::string& address, unsigned short port) +{ + asio::error_code errorCode; + + // Get a list of endpoints corresponding to the server name. + asio::ip::udp::resolver resolver(mIOService); + resip::Data service(port); + asio::ip::udp::resolver::query query(address, service.c_str()); + asio::ip::udp::resolver::iterator endpoint_iterator = resolver.resolve(query); + asio::ip::udp::resolver::iterator end; + + // Use first endpoint in list + if(endpoint_iterator == end) + { + return asio::error::host_not_found; + } + + // Nothing to do for UDP except store the remote endpoint + mRemoteEndpoint = endpoint_iterator->endpoint(); + + mConnected = true; + mConnectedTuple.setTransportType(StunTuple::UDP); + mConnectedTuple.setAddress(mRemoteEndpoint.address()); + mConnectedTuple.setPort(mRemoteEndpoint.port()); + + return errorCode; +} + +asio::error_code +TurnUdpSocket::rawWrite(const char* buffer, unsigned int size) +{ + asio::error_code errorCode; + mSocket.send_to(asio::buffer(buffer, size), mRemoteEndpoint, 0, errorCode); + return errorCode; +} + +asio::error_code +TurnUdpSocket::rawWrite(const std::vector<asio::const_buffer>& buffers) +{ + asio::error_code errorCode; + mSocket.send_to(buffers, mRemoteEndpoint, 0, errorCode); + return errorCode; +} + +asio::error_code +TurnUdpSocket::rawRead(unsigned int timeout, unsigned int* bytesRead, asio::ip::address* sourceAddress, unsigned short* sourcePort) +{ + startReadTimer(timeout); + + mSocket.async_receive_from(asio::buffer(mReadBuffer, sizeof(mReadBuffer)), mSenderEndpoint, 0, boost::bind(&TurnUdpSocket::handleRawRead, this, asio::placeholders::error, asio::placeholders::bytes_transferred)); + + // Wait for timer and read to end + mIOService.run(); + mIOService.reset(); + + *bytesRead = (unsigned int)mBytesRead; + + if(!mReadErrorCode) + { + if(sourceAddress) + { + *sourceAddress = mSenderEndpoint.address(); + } + if(sourcePort) + { + *sourcePort = mSenderEndpoint.port(); + } + } + return mReadErrorCode; +} + +void +TurnUdpSocket::cancelSocket() +{ + asio::error_code ec; + mSocket.cancel(ec); +} + +} // namespace + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/TurnUdpSocket.hxx b/src/libs/resiprocate/reTurn/client/TurnUdpSocket.hxx new file mode 100644 index 00000000..48099532 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/TurnUdpSocket.hxx @@ -0,0 +1,70 @@ +#ifndef TURNUDPSOCKET_HXX +#define TURNUDPSOCKET_HXX + +#include <asio.hpp> + +#include "TurnSocket.hxx" + +namespace reTurn { + + class TurnUdpSocket : public TurnSocket +{ +public: + explicit TurnUdpSocket(const asio::ip::address& address, unsigned short port); + + virtual unsigned int getSocketDescriptor() { return mSocket.native(); } + + virtual asio::error_code connect(const std::string& address, unsigned short port); + +protected: + virtual asio::error_code rawWrite(const char* buffer, unsigned int size); + virtual asio::error_code rawWrite(const std::vector<asio::const_buffer>& buffers); + virtual asio::error_code rawRead(unsigned int timeout, unsigned int* bytesRead, asio::ip::address* sourceAddress=0, unsigned short* sourcePort=0); + virtual void cancelSocket(); + +private: + asio::ip::udp::socket mSocket; + + // Remote binding info + asio::ip::udp::endpoint mRemoteEndpoint; + asio::ip::udp::endpoint mSenderEndpoint; // for read operations +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/reTurnClient_10_0.vcxproj b/src/libs/resiprocate/reTurn/client/reTurnClient_10_0.vcxproj new file mode 100644 index 00000000..3d980bd3 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/reTurnClient_10_0.vcxproj @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>reTurnClient</ProjectName> + <ProjectGuid>{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}</ProjectGuid> + <RootNamespace>reTurnClient</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>../../contrib/asio;../../contrib/boost_1_34_1;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32;../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_IPV6;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)reTurnClient.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>../../contrib/asio;../../contrib/boost_1_34_1;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32;../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_IPV6;USE_SSL;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)reTurnClient.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\AsyncSocketBase.cxx" /> + <ClCompile Include="..\AsyncTcpSocketBase.cxx" /> + <ClCompile Include="..\AsyncTlsSocketBase.cxx" /> + <ClCompile Include="..\AsyncUdpSocketBase.cxx" /> + <ClCompile Include="..\ChannelManager.cxx" /> + <ClCompile Include="..\DataBuffer.cxx" /> + <ClCompile Include="..\RemotePeer.cxx" /> + <ClCompile Include="..\ReTurnSubsystem.cxx" /> + <ClCompile Include="..\StunMessage.cxx" /> + <ClCompile Include="..\StunTuple.cxx" /> + <ClCompile Include="TurnAsyncSocket.cxx" /> + <ClCompile Include="TurnAsyncSocketHandler.cxx" /> + <ClCompile Include="TurnAsyncTcpSocket.cxx" /> + <ClCompile Include="TurnAsyncTlsSocket.cxx" /> + <ClCompile Include="TurnAsyncUdpSocket.cxx" /> + <ClCompile Include="TurnSocket.cxx" /> + <ClCompile Include="TurnTcpSocket.cxx" /> + <ClCompile Include="TurnTlsSocket.cxx" /> + <ClCompile Include="TurnUdpSocket.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\AsyncSocketBase.hxx" /> + <ClInclude Include="..\AsyncSocketBaseHandler.hxx" /> + <ClInclude Include="..\AsyncTcpSocketBase.hxx" /> + <ClInclude Include="..\AsyncTlsSocketBase.hxx" /> + <ClInclude Include="..\AsyncUdpSocketBase.hxx" /> + <ClInclude Include="..\ChannelManager.hxx" /> + <ClInclude Include="..\DataBuffer.hxx" /> + <ClInclude Include="ErrorCode.hxx" /> + <ClInclude Include="..\RemotePeer.hxx" /> + <ClInclude Include="..\ReTurnSubsystem.hxx" /> + <ClInclude Include="..\StunMessage.hxx" /> + <ClInclude Include="..\StunTuple.hxx" /> + <ClInclude Include="TurnAsyncSocket.hxx" /> + <ClInclude Include="TurnAsyncSocketHandler.hxx" /> + <ClInclude Include="TurnAsyncTcpSocket.hxx" /> + <ClInclude Include="TurnAsyncTlsSocket.hxx" /> + <ClInclude Include="TurnAsyncUdpSocket.hxx" /> + <ClInclude Include="TurnSocket.hxx" /> + <ClInclude Include="TurnTcpSocket.hxx" /> + <ClInclude Include="TurnTlsSocket.hxx" /> + <ClInclude Include="TurnUdpSocket.hxx" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/reTurn/client/reTurnClient_10_0.vcxproj.filters b/src/libs/resiprocate/reTurn/client/reTurnClient_10_0.vcxproj.filters new file mode 100644 index 00000000..8ae6f2f5 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/reTurnClient_10_0.vcxproj.filters @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\AsyncSocketBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\AsyncTcpSocketBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\AsyncTlsSocketBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\AsyncUdpSocketBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\ChannelManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\DataBuffer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\RemotePeer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\ReTurnSubsystem.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\StunMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\StunTuple.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnAsyncSocket.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnAsyncSocketHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnAsyncTcpSocket.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnAsyncTlsSocket.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnAsyncUdpSocket.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnSocket.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnTcpSocket.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnTlsSocket.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnUdpSocket.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\AsyncSocketBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\AsyncSocketBaseHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\AsyncTcpSocketBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\AsyncTlsSocketBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\AsyncUdpSocketBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\ChannelManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\DataBuffer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ErrorCode.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\RemotePeer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\ReTurnSubsystem.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\StunMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\StunTuple.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnAsyncSocket.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnAsyncSocketHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnAsyncTcpSocket.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnAsyncTlsSocket.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnAsyncUdpSocket.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnSocket.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnTcpSocket.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnTlsSocket.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnUdpSocket.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/reTurn/client/reTurnClient_7_1.vcproj b/src/libs/resiprocate/reTurn/client/reTurnClient_7_1.vcproj new file mode 100644 index 00000000..915c313a --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/reTurnClient_7_1.vcproj @@ -0,0 +1,238 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="reTurnClient" + ProjectGUID="{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../contrib/asio;../../contrib/boost_1_34_1;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32;../../" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/reTurnClient.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../../contrib/asio;../../contrib/boost_1_34_1;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32;../../" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;ASIO_ENABLE_CANCELIO" + RuntimeLibrary="2" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/reTurnClient.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath="..\AsyncSocketBase.cxx"> + </File> + <File + RelativePath="..\AsyncTcpSocketBase.cxx"> + </File> + <File + RelativePath="..\AsyncTlsSocketBase.cxx"> + </File> + <File + RelativePath="..\AsyncUdpSocketBase.cxx"> + </File> + <File + RelativePath="..\ChannelManager.cxx"> + </File> + <File + RelativePath="..\DataBuffer.cxx"> + </File> + <File + RelativePath="..\RemotePeer.cxx"> + </File> + <File + RelativePath="..\ReTurnSubsystem.cxx"> + </File> + <File + RelativePath="..\StunMessage.cxx"> + </File> + <File + RelativePath="..\StunTuple.cxx"> + </File> + <File + RelativePath=".\TurnAsyncSocket.cxx"> + </File> + <File + RelativePath=".\TurnAsyncSocketHandler.cxx"> + </File> + <File + RelativePath=".\TurnAsyncTcpSocket.cxx"> + </File> + <File + RelativePath=".\TurnAsyncTlsSocket.cxx"> + </File> + <File + RelativePath=".\TurnAsyncUdpSocket.cxx"> + </File> + <File + RelativePath=".\TurnSocket.cxx"> + </File> + <File + RelativePath=".\TurnTcpSocket.cxx"> + </File> + <File + RelativePath=".\TurnTlsSocket.cxx"> + </File> + <File + RelativePath=".\TurnUdpSocket.cxx"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath="..\AsyncSocketBase.hxx"> + </File> + <File + RelativePath="..\AsyncSocketBaseHandler.hxx"> + </File> + <File + RelativePath="..\AsyncTcpSocketBase.hxx"> + </File> + <File + RelativePath="..\AsyncTlsSocketBase.hxx"> + </File> + <File + RelativePath="..\AsyncUdpSocketBase.hxx"> + </File> + <File + RelativePath="..\ChannelManager.hxx"> + </File> + <File + RelativePath="..\DataBuffer.hxx"> + </File> + <File + RelativePath=".\ErrorCode.hxx"> + </File> + <File + RelativePath="..\RemotePeer.hxx"> + </File> + <File + RelativePath="..\ReTurnSubsystem.hxx"> + </File> + <File + RelativePath="..\StunMessage.hxx"> + </File> + <File + RelativePath="..\StunTuple.hxx"> + </File> + <File + RelativePath=".\TurnAsyncSocket.hxx"> + </File> + <File + RelativePath=".\TurnAsyncSocketHandler.hxx"> + </File> + <File + RelativePath=".\TurnAsyncTcpSocket.hxx"> + </File> + <File + RelativePath=".\TurnAsyncTlsSocket.hxx"> + </File> + <File + RelativePath=".\TurnAsyncUdpSocket.hxx"> + </File> + <File + RelativePath=".\TurnSocket.hxx"> + </File> + <File + RelativePath=".\TurnTcpSocket.hxx"> + </File> + <File + RelativePath=".\TurnTlsSocket.hxx"> + </File> + <File + RelativePath=".\TurnUdpSocket.hxx"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/client/reTurnClient_8_0.vcproj b/src/libs/resiprocate/reTurn/client/reTurnClient_8_0.vcproj new file mode 100644 index 00000000..1afc2c3f --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/reTurnClient_8_0.vcproj @@ -0,0 +1,332 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="reTurnClient" + ProjectGUID="{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" + RootNamespace="reTurnClient" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../contrib/asio;../../contrib/boost_1_34_1;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32;../../" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_IPV6;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/reTurnClient.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../../contrib/asio;../../contrib/boost_1_34_1;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32;../../" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_IPV6;USE_SSL;ASIO_ENABLE_CANCELIO" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/reTurnClient.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\AsyncSocketBase.cxx" + > + </File> + <File + RelativePath="..\AsyncTcpSocketBase.cxx" + > + </File> + <File + RelativePath="..\AsyncTlsSocketBase.cxx" + > + </File> + <File + RelativePath="..\AsyncUdpSocketBase.cxx" + > + </File> + <File + RelativePath="..\ChannelManager.cxx" + > + </File> + <File + RelativePath="..\DataBuffer.cxx" + > + </File> + <File + RelativePath="..\RemotePeer.cxx" + > + </File> + <File + RelativePath="..\ReTurnSubsystem.cxx" + > + </File> + <File + RelativePath="..\StunMessage.cxx" + > + </File> + <File + RelativePath="..\StunTuple.cxx" + > + </File> + <File + RelativePath=".\TurnAsyncSocket.cxx" + > + </File> + <File + RelativePath=".\TurnAsyncSocketHandler.cxx" + > + </File> + <File + RelativePath=".\TurnAsyncTcpSocket.cxx" + > + </File> + <File + RelativePath=".\TurnAsyncTlsSocket.cxx" + > + </File> + <File + RelativePath=".\TurnAsyncUdpSocket.cxx" + > + </File> + <File + RelativePath=".\TurnSocket.cxx" + > + </File> + <File + RelativePath=".\TurnTcpSocket.cxx" + > + </File> + <File + RelativePath=".\TurnTlsSocket.cxx" + > + </File> + <File + RelativePath=".\TurnUdpSocket.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\AsyncSocketBase.hxx" + > + </File> + <File + RelativePath="..\AsyncSocketBaseHandler.hxx" + > + </File> + <File + RelativePath="..\AsyncTcpSocketBase.hxx" + > + </File> + <File + RelativePath="..\AsyncTlsSocketBase.hxx" + > + </File> + <File + RelativePath="..\AsyncUdpSocketBase.hxx" + > + </File> + <File + RelativePath="..\ChannelManager.hxx" + > + </File> + <File + RelativePath="..\DataBuffer.hxx" + > + </File> + <File + RelativePath=".\ErrorCode.hxx" + > + </File> + <File + RelativePath="..\RemotePeer.hxx" + > + </File> + <File + RelativePath="..\ReTurnSubsystem.hxx" + > + </File> + <File + RelativePath="..\StunMessage.hxx" + > + </File> + <File + RelativePath="..\StunTuple.hxx" + > + </File> + <File + RelativePath=".\TurnAsyncSocket.hxx" + > + </File> + <File + RelativePath=".\TurnAsyncSocketHandler.hxx" + > + </File> + <File + RelativePath=".\TurnAsyncTcpSocket.hxx" + > + </File> + <File + RelativePath=".\TurnAsyncTlsSocket.hxx" + > + </File> + <File + RelativePath=".\TurnAsyncUdpSocket.hxx" + > + </File> + <File + RelativePath=".\TurnSocket.hxx" + > + </File> + <File + RelativePath=".\TurnTcpSocket.hxx" + > + </File> + <File + RelativePath=".\TurnTlsSocket.hxx" + > + </File> + <File + RelativePath=".\TurnUdpSocket.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/client/reTurnClient_9_0.vcproj b/src/libs/resiprocate/reTurn/client/reTurnClient_9_0.vcproj new file mode 100644 index 00000000..40daaa63 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/reTurnClient_9_0.vcproj @@ -0,0 +1,468 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="reTurnClient" + ProjectGUID="{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" + RootNamespace="reTurnClient" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="../../contrib/asio;../../contrib/boost_1_34_1;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32;../../" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_IPV6;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/reTurnClient.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="../../contrib/asio;../../contrib/boost_1_34_1;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32;../../" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_IPV6;ASIO_ENABLE_CANCELIO" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/reTurnClient.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="../../contrib/asio;../../contrib/boost_1_34_1;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32;../../" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_IPV6;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/reTurnClient.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="../../contrib/asio;../../contrib/boost_1_34_1;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32;../../" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_IPV6;USE_SSL;ASIO_ENABLE_CANCELIO" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/reTurnClient.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\AsyncSocketBase.cxx" + > + </File> + <File + RelativePath="..\AsyncTcpSocketBase.cxx" + > + </File> + <File + RelativePath="..\AsyncTlsSocketBase.cxx" + > + </File> + <File + RelativePath="..\AsyncUdpSocketBase.cxx" + > + </File> + <File + RelativePath="..\ChannelManager.cxx" + > + </File> + <File + RelativePath="..\DataBuffer.cxx" + > + </File> + <File + RelativePath="..\RemotePeer.cxx" + > + </File> + <File + RelativePath="..\ReTurnSubsystem.cxx" + > + </File> + <File + RelativePath="..\StunMessage.cxx" + > + </File> + <File + RelativePath="..\StunTuple.cxx" + > + </File> + <File + RelativePath=".\TurnAsyncSocket.cxx" + > + </File> + <File + RelativePath=".\TurnAsyncSocketHandler.cxx" + > + </File> + <File + RelativePath=".\TurnAsyncTcpSocket.cxx" + > + </File> + <File + RelativePath=".\TurnAsyncTlsSocket.cxx" + > + </File> + <File + RelativePath=".\TurnAsyncUdpSocket.cxx" + > + </File> + <File + RelativePath=".\TurnSocket.cxx" + > + </File> + <File + RelativePath=".\TurnTcpSocket.cxx" + > + </File> + <File + RelativePath=".\TurnTlsSocket.cxx" + > + </File> + <File + RelativePath=".\TurnUdpSocket.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\AsyncSocketBase.hxx" + > + </File> + <File + RelativePath="..\AsyncSocketBaseHandler.hxx" + > + </File> + <File + RelativePath="..\AsyncTcpSocketBase.hxx" + > + </File> + <File + RelativePath="..\AsyncTlsSocketBase.hxx" + > + </File> + <File + RelativePath="..\AsyncUdpSocketBase.hxx" + > + </File> + <File + RelativePath="..\ChannelManager.hxx" + > + </File> + <File + RelativePath="..\DataBuffer.hxx" + > + </File> + <File + RelativePath=".\ErrorCode.hxx" + > + </File> + <File + RelativePath="..\RemotePeer.hxx" + > + </File> + <File + RelativePath="..\ReTurnSubsystem.hxx" + > + </File> + <File + RelativePath="..\StunMessage.hxx" + > + </File> + <File + RelativePath="..\StunTuple.hxx" + > + </File> + <File + RelativePath=".\TurnAsyncSocket.hxx" + > + </File> + <File + RelativePath=".\TurnAsyncSocketHandler.hxx" + > + </File> + <File + RelativePath=".\TurnAsyncTcpSocket.hxx" + > + </File> + <File + RelativePath=".\TurnAsyncTlsSocket.hxx" + > + </File> + <File + RelativePath=".\TurnAsyncUdpSocket.hxx" + > + </File> + <File + RelativePath=".\TurnSocket.hxx" + > + </File> + <File + RelativePath=".\TurnTcpSocket.hxx" + > + </File> + <File + RelativePath=".\TurnTlsSocket.hxx" + > + </File> + <File + RelativePath=".\TurnUdpSocket.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/client/test/Makefile b/src/libs/resiprocate/reTurn/client/test/Makefile new file mode 100644 index 00000000..34f88040 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/Makefile @@ -0,0 +1,46 @@ +BUILD := ../../../build +include $(BUILD)/Makefile.pre + +PACKAGES += RETURNCLIENT ASIO RUTIL ARES OPENSSL BOOST PTHREAD + +TESTPROGRAMS += \ + TestClient.cxx \ + TestAsyncClient.cxx \ + TestRtpLoad.cxx + +include $(BUILD)/Makefile.post + + +#################################################################### +# +# Copyright (c) 2007-2008, Plantronics, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of Plantronics nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#################################################################### diff --git a/src/libs/resiprocate/reTurn/client/test/Makefile.am b/src/libs/resiprocate/reTurn/client/test/Makefile.am new file mode 100644 index 00000000..7f180619 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/Makefile.am @@ -0,0 +1,24 @@ + +EXTRA_DIST = ca.pem +EXTRA_DIST += *.vcxproj *.vcxproj.filters +EXTRA_DIST += *.vcproj + +LDADD = ../libreTurnClient.la +LDADD += ../../../rutil/librutil.la +LDADD += $(LIBSSL_LIBADD) -lpthread + +TESTS = \ + TestClient \ + TestAsyncClient \ + TestRtpLoad + +check_PROGRAMS = \ + TestClient \ + TestAsyncClient \ + TestRtpLoad + +TestClient_SOURCES = TestClient.cxx +TestAsyncClient_SOURCES = TestAsyncClient.cxx +TestRtpLoad_SOURCES = TestRtpLoad.cxx + + diff --git a/src/libs/resiprocate/reTurn/client/test/TestAsyncClient.cxx b/src/libs/resiprocate/reTurn/client/test/TestAsyncClient.cxx new file mode 100644 index 00000000..97c1b354 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestAsyncClient.cxx @@ -0,0 +1,328 @@ +#ifdef WIN32 +#pragma warning(disable : 4267) +#endif + +#include <iostream> +#include <string> +#include <asio.hpp> +#include <asio/ssl.hpp> +#include <rutil/ThreadIf.hxx> + +#include "../../StunTuple.hxx" +#include "../../StunMessage.hxx" +#include "../TurnUdpSocket.hxx" +#include "../TurnAsyncTcpSocket.hxx" +#include "../TurnAsyncTlsSocket.hxx" +#include "../TurnAsyncUdpSocket.hxx" +#include "../TurnAsyncSocketHandler.hxx" +#include <rutil/Logger.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/WinLeakCheck.hxx> + +using namespace reTurn; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST +//#define CONTINUOUSTESTMODE + +resip::Data address = resip::DnsUtil::getLocalIpAddress(); + +void sleepSeconds(unsigned int seconds) +{ +#ifdef WIN32 + Sleep(seconds*1000); +#else + sleep(seconds); +#endif +} + +// Simple UDP Echo Server +class TurnPeer : public resip::ThreadIf +{ +public: + TurnPeer() {} + + virtual ~TurnPeer() {} + + virtual void thread() + { + asio::error_code rc; + TurnUdpSocket turnSocket(asio::ip::address::from_string(address.c_str()), 2000); + + char buffer[1024]; + unsigned int size = sizeof(buffer); + asio::ip::address sourceAddress; + unsigned short sourcePort; + bool connected = false; + + // Receive Data + rc=turnSocket.receive(buffer, size, 1000, &sourceAddress, &sourcePort); + while((!rc || rc.value() == asio::error::operation_aborted) && !isShutdown()) + { + if(!rc) + { + if(!connected) + { + turnSocket.connect(sourceAddress.to_string(), sourcePort); + connected = true; + } + InfoLog(<< "PEER: Received data from " << sourceAddress.to_string() << ":" << sourcePort << " - [" << resip::Data(buffer, size).c_str() << "]"); + turnSocket.send(buffer, size); + } + size = sizeof(buffer); + rc=turnSocket.receive(buffer, size, 1000, &sourceAddress, &sourcePort); + } + + if(rc) + { + if(rc.value() != asio::error::operation_aborted) + { + ErrLog(<< "PEER: Receive error: " << rc.message()); + } + } + } +private: +}; + +class MyTurnAsyncSocketHandler : public TurnAsyncSocketHandler +{ +public: + MyTurnAsyncSocketHandler() : mNumReceives(0) {} + virtual ~MyTurnAsyncSocketHandler() {} + + virtual void onConnectSuccess(unsigned int socketDesc, const asio::ip::address& address, unsigned short port) + { + InfoLog( << "MyTurnAsyncSocketHandler::onConnectSuccess: socketDest=" << socketDesc << ", address=" << address.to_string() << ", port=" << port); + mTurnAsyncSocket->bindRequest(); + } + virtual void onConnectFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onConnectFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + virtual void onSharedSecretSuccess(unsigned int socketDesc, const char* username, unsigned int usernameSize, const char* password, unsigned int passwordSize) + { + InfoLog( << "MyTurnAsyncSocketHandler::onSharedSecretSuccess: socketDest=" << socketDesc << ", username=" << username << ", password=" << password); + } + + virtual void onSharedSecretFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onSharedSecretFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + virtual void onBindSuccess(unsigned int socketDesc, const StunTuple& reflexiveTuple) + { + InfoLog( << "MyTurnAsyncSocketHandler::onBindingSuccess: socketDest=" << socketDesc << ", reflexive=" << reflexiveTuple); + mTurnAsyncSocket->createAllocation(30, // TurnAsyncSocket::UnspecifiedLifetime, + TurnAsyncSocket::UnspecifiedBandwidth, + StunMessage::PropsPortPair, + TurnAsyncSocket::UnspecifiedToken, + StunTuple::UDP); + } + virtual void onBindFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onBindingFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + virtual void onAllocationSuccess(unsigned int socketDesc, const StunTuple& reflexiveTuple, const StunTuple& relayTuple, unsigned int lifetime, unsigned int bandwidth, UInt64 reservationToken) + { + InfoLog( << "MyTurnAsyncSocketHandler::onAllocationSuccess: socketDest=" << socketDesc << + ", reflexive=" << reflexiveTuple << + ", relay=" << relayTuple << + ", lifetime=" << lifetime << + ", bandwidth=" << bandwidth << + ", reservationToken=" << reservationToken); + + // Test Data sending and receiving over allocation + resip::Data turnData("This test is for wrapped Turn Data!"); + InfoLog( << "CLIENT: Sending: " << turnData); + mTurnAsyncSocket->sendTo(asio::ip::address::from_string(address.c_str()), 2000, turnData.c_str(), turnData.size()+1); + + turnData = "This test should be in ChannelData message in TCP/TLS but not in UDP - since ChannelBindResponse is not yet received."; + InfoLog( << "CLIENT: Sending: " << turnData); + mTurnAsyncSocket->setActiveDestination(asio::ip::address::from_string(address.c_str()), 2000); + mTurnAsyncSocket->send(turnData.c_str(), turnData.size()+1); + } + virtual void onAllocationFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onAllocationFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + virtual void onRefreshSuccess(unsigned int socketDesc, unsigned int lifetime) + { + InfoLog( << "MyTurnAsyncSocketHandler::onRefreshSuccess: socketDest=" << socketDesc << ", lifetime=" << lifetime); + if(lifetime == 0) + { + mTurnAsyncSocket->close(); + } + } + virtual void onRefreshFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onRefreshFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + virtual void onSetActiveDestinationSuccess(unsigned int socketDesc) + { + InfoLog( << "MyTurnAsyncSocketHandler::onSetActiveDestinationSuccess: socketDest=" << socketDesc); + } + virtual void onSetActiveDestinationFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onSetActiveDestinationFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + virtual void onClearActiveDestinationSuccess(unsigned int socketDesc) + { + InfoLog( << "MyTurnAsyncSocketHandler::onClearActiveDestinationSuccess: socketDest=" << socketDesc); + } + virtual void onClearActiveDestinationFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onClearActiveDestinationFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + virtual void onSendSuccess(unsigned int socketDesc) + { + //InfoLog( << "MyTurnAsyncSocketHandler::onSendSuccess: socketDest=" << socketDesc); + } + virtual void onSendFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onSendFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + virtual void onReceiveSuccess(unsigned int socketDesc, const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) + { + InfoLog( << "MyTurnAsyncSocketHandler::onReceiveSuccess: socketDest=" << socketDesc << ", fromAddress=" << address.to_string() << ", fromPort=" << port << ", size=" << data->size() << ", data=" << data->data()); + + switch(++mNumReceives) + { + case 1: + break; + case 2: + { + resip::Data turnData("This test is for ChannelData message!"); + InfoLog( << "CLIENT: Sending: " << turnData); + mTurnAsyncSocket->send(turnData.c_str(), turnData.size()+1); + } + break; + case 3: +#ifdef CONTINUOUSTESTMODE + default: + { + sleepSeconds(1); + resip::Data turnData("This test is for ChannelData message!"); + InfoLog( << "CLIENT: Sending: " << turnData); + mTurnAsyncSocket->send(turnData.c_str(), turnData.size()+1); + } +#else + mTurnAsyncSocket->destroyAllocation(); +#endif + //mTurnAsyncSocket->close(); + break; + } + } + virtual void onReceiveFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onReceiveFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + void setTurnAsyncSocket(TurnAsyncSocket* turnAsyncSocket) { mTurnAsyncSocket = turnAsyncSocket; } + +private: + TurnAsyncSocket* mTurnAsyncSocket; + unsigned int mNumReceives; +}; + +int main(int argc, char* argv[]) +{ +#if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK) + resip::FindMemoryLeaks fml; +#endif + //resip::Log::initialize(resip::Log::Cout, resip::Log::Stack, argv[0]); + + try + { + if (argc != 3 && argc != 4) + { + std::cerr << "Usage: TestAsyncClient <turn host> <turn port> [<local address>]\n"; + return 1; + } + unsigned int port = resip::Data(argv[2]).convertUnsignedLong(); + if(argc==4) + { + address = argv[3]; + } + + InfoLog(<< "Using " << address << " as local IP address."); + + asio::error_code rc; + char username[256] = "test"; + char password[256] = "1234"; + TurnPeer turnPeer; + turnPeer.run(); + asio::io_service ioService; + MyTurnAsyncSocketHandler handler; + + // Setup SSL context + asio::ssl::context sslContext(ioService, asio::ssl::context::tlsv1); + // Enable certificate validation + sslContext.set_verify_mode(asio::ssl::context::verify_peer | // Verify the peer. + asio::ssl::context::verify_fail_if_no_peer_cert); // Fail verification if the peer has no certificate. + sslContext.load_verify_file("ca.pem"); + + boost::shared_ptr<TurnAsyncSocket> turnSocket(new TurnAsyncUdpSocket(ioService, &handler, asio::ip::address::from_string(address.c_str()), 0)); + //boost::shared_ptr<TurnAsyncSocket> turnSocket(new TurnAsyncTcpSocket(ioService, &handler, asio::ip::address::from_string(address.c_str()), 0)); + //boost::shared_ptr<TurnAsyncSocket> turnSocket(new TurnAsyncTlsSocket(ioService, sslContext, false /* validateServerCertificateHostname */, &handler, asio::ip::address::from_string(address.c_str()), 0)); + //port=5349; + + handler.setTurnAsyncSocket(turnSocket.get()); + + // Connect to Stun/Turn Server + turnSocket->connect(argv[1], port); + + // Set the username and password + turnSocket->setUsernameAndPassword(username, password); + + ioService.run(); + + turnPeer.shutdown(); + turnPeer.join(); + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_10_0.vcxproj b/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_10_0.vcxproj new file mode 100644 index 00000000..b2585434 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_10_0.vcxproj @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>TestAsyncClient</ProjectName> + <ProjectGuid>{73151749-13F0-4093-97F1-A6952ECECDCF}</ProjectGuid> + <RootNamespace>TestAsyncClient</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <BuildLog> + <Path>$(IntDir)BuildLog-TestAsyncClient.htm</Path> + </BuildLog> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <ProgramDataBaseFileName>$(OutDir)TestAsyncClient.pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>winmm.lib;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)TestAsyncClient.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)TestAsyncClient.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <BuildLog> + <Path>$(IntDir)BuildLog-TestAsyncClient.htm</Path> + </BuildLog> + <ClCompile> + <AdditionalIncludeDirectories>../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <ProgramDataBaseFileName>$(OutDir)TestAsyncClient.pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>winmm.lib;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)TestAsyncClient.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="TestAsyncClient.cxx" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\rutil\rutil_10_0.vcxproj"> + <Project>{3d0e5ceb-93dc-4fdb-918b-d08fa369e106}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\reTurnClient_10_0.vcxproj"> + <Project>{67b5906c-5c9d-4d09-ac7e-af71d72175f8}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_10_0.vcxproj.filters b/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_10_0.vcxproj.filters new file mode 100644 index 00000000..8797e81f --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_10_0.vcxproj.filters @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="TestAsyncClient.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_7_1.vcproj b/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_7_1.vcproj new file mode 100644 index 00000000..0310cf1a --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_7_1.vcproj @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="TestAsyncClient" + ProjectGUID="{73151749-13F0-4093-97F1-A6952ECECDCF}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="&quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/TestAsyncClient.exe" + LinkIncremental="2" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/TestAsyncClient.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;ASIO_ENABLE_CANCELIO" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="&quot;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/TestAsyncClient.exe" + LinkIncremental="1" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath=".\TestAsyncClient.cxx"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_8_0.vcproj b/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_8_0.vcproj new file mode 100644 index 00000000..aaa22998 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_8_0.vcproj @@ -0,0 +1,211 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="TestAsyncClient" + ProjectGUID="{73151749-13F0-4093-97F1-A6952ECECDCF}" + RootNamespace="TestAsyncClient" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-TestAsyncClient.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(OutDir)/TestAsyncClient.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/TestAsyncClient.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/TestAsyncClient.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + DependencyInformationFile="$(IntDir)\mt-TestAsyncClient.dep" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-TestAsyncClient.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;ASIO_ENABLE_CANCELIO" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(OutDir)/TestAsyncClient.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/TestAsyncClient.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + DependencyInformationFile="$(IntDir)\mt-TestAsyncClient.dep" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\TestAsyncClient.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_9_0.vcproj b/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_9_0.vcproj new file mode 100644 index 00000000..f5fe4316 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestAsyncClient_9_0.vcproj @@ -0,0 +1,210 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="TestAsyncClient" + ProjectGUID="{73151749-13F0-4093-97F1-A6952ECECDCF}" + RootNamespace="TestAsyncClient" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-TestAsyncClient.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(OutDir)/TestAsyncClient.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/TestAsyncClient.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/TestAsyncClient.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + DependencyInformationFile="$(IntDir)\mt-TestAsyncClient.dep" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-TestAsyncClient.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;ASIO_ENABLE_CANCELIO" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(OutDir)/TestAsyncClient.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/TestAsyncClient.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + DependencyInformationFile="$(IntDir)\mt-TestAsyncClient.dep" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\TestAsyncClient.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/client/test/TestClient.cxx b/src/libs/resiprocate/reTurn/client/test/TestClient.cxx new file mode 100644 index 00000000..9d8c44f7 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestClient.cxx @@ -0,0 +1,266 @@ +#ifdef WIN32 +#pragma warning(disable : 4267) +#endif + +#include <iostream> +#include <string> +#include <asio.hpp> +#include <asio/ssl.hpp> +#include <rutil/ThreadIf.hxx> +#include <rutil/Logger.hxx> + +#include "../../StunTuple.hxx" +#include "../../StunMessage.hxx" +#include "../TurnTcpSocket.hxx" +#include "../TurnTlsSocket.hxx" +#include "../TurnUdpSocket.hxx" + +using namespace reTurn; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST + +//#define CONTINUOUSTESTMODE +#define NO_AUTHENTICATION + +void sleepSeconds(unsigned int seconds) +{ +#ifdef WIN32 + Sleep(seconds*1000); +#else + sleep(seconds); +#endif +} + +// Simple UDP Echo Server +class TurnPeer : public resip::ThreadIf +{ +public: + TurnPeer() {} + + virtual ~TurnPeer() {} + + virtual void thread() + { + asio::error_code rc; + TurnUdpSocket turnSocket(asio::ip::address::from_string("127.0.0.1"), 2000); + + char buffer[1024]; + unsigned int size = sizeof(buffer); + asio::ip::address sourceAddress; + unsigned short sourcePort; + bool connected = false; + + // Receive Data + rc=turnSocket.receive(buffer, size, 1000, &sourceAddress, &sourcePort); + while((!rc || rc.value() == asio::error::operation_aborted) && !isShutdown()) + { + if(!rc) + { + if(!connected) + { + turnSocket.connect(sourceAddress.to_string(), sourcePort); + connected = true; + } + InfoLog( << "PEER: Received data from " << sourceAddress.to_string() << ":" << sourcePort << " - [" << resip::Data(buffer, size).c_str() << "]"); + turnSocket.send(buffer, size); + } + size = sizeof(buffer); + rc=turnSocket.receive(buffer, size, 1000, &sourceAddress, &sourcePort); + } + + if(rc) + { + if(rc.value() != asio::error::operation_aborted) + { + ErrLog( << "PEER: Receive error: " << rc.message()); + } + } + } +private: +}; + +#define MAX_RUNS 1000 +int main(int argc, char* argv[]) +{ + try + { + if (argc != 3) + { + std::cerr << "Usage: TestClient <turn host> <turn port>\n"; + return 1; + } + unsigned int port = resip::Data(argv[2]).convertUnsignedLong(); + + asio::error_code rc; + char username[256] = "test"; + char password[256] = "1234"; + TurnPeer turnPeer; + turnPeer.run(); + +#ifndef NO_AUTHENTICATION + { // Connect via TLS, get SharedSecret, and disconnect + TurnTlsSocket tlsSocket(asio::ip::address::from_string("127.0.0.1"), 40001); + rc = tlsSocket.requestSharedSecret(asio::ip::address::from_string(argv[1]), + port.convertUnsignedLong()+1, + username, sizeof(username), + password, sizeof(password)); + } + + if(rc != 0) + { + std::cout << "Error getting shared secret: rc=" << rc..message() << std::endl; + return 1; + } + + std::cout << "CLIENT: SharedSecret obtained: Username=" << username + << " Password=" << password + << std::endl; +#endif + + TurnUdpSocket turnSocket(asio::ip::address::from_string("127.0.0.1"), 0); + //TurnTcpSocket turnSocket(asio::ip::address::from_string("127.0.0.1"), 0); + //TurnTlsSocket turnSocket(false /* validateServerCertificateHostname */, asio::ip::address::from_string("127.0.0.1"), 0); + //port=5349; + + // Connect to Stun/Turn Server + rc = turnSocket.connect(argv[1], port); + if(rc) + { + std::cout << "CLIENT: Error calling connect: rc=" << rc.message() << std::endl; + return 1; + } + + // Set the username and password + turnSocket.setUsernameAndPassword(username, password); + + // Test bind request + rc = turnSocket.bindRequest(); + if(rc) + { + InfoLog(<< "CLIENT: Error calling bindRequest: rc=" << rc.message() << ", value=" << rc.value()); + return 1; + } + else + { + InfoLog( << "CLIENT: Bind Successful! Reflexive=" << turnSocket.getReflexiveTuple()); + } + + // Test allocation + rc = turnSocket.createAllocation(30, // TurnSocket::UnspecifiedLifetime, + TurnSocket::UnspecifiedBandwidth, + StunMessage::PropsPortPair, + TurnSocket::UnspecifiedToken, + StunTuple::UDP); + if(rc) + { + InfoLog( << "CLIENT: Error creating allocation: rc=" << rc.message()); + } + else + { + InfoLog( << "CLIENT: Allocation Successful! Relay=" << turnSocket.getRelayTuple() + << " Reflexive=" << turnSocket.getReflexiveTuple() + << " Lifetime=" << turnSocket.getLifetime() + << " Bandwidth=" << turnSocket.getBandwidth()); + + char buffer[1024]; + unsigned int size = sizeof(buffer); + asio::ip::address sourceAddress; + unsigned short sourcePort; + + // Test Data sending and receiving over allocation + resip::Data turnData("This test is for wrapped Turn Data!"); + InfoLog(<< "CLIENT: Sending: " << turnData); + turnSocket.sendTo(asio::ip::address::from_string("127.0.0.1"), 2000, turnData.c_str(), turnData.size()); + + turnData = "This test should be a Channel Data message in TCP/TLS but not in UDP - since ChannelBindResponse is not yet received."; + InfoLog( << "CLIENT: Sending: " << turnData); + turnSocket.setActiveDestination(asio::ip::address::from_string("127.0.0.1"), 2000); + turnSocket.send(turnData.c_str(), turnData.size()); + + // Receive Data + while(!(rc=turnSocket.receive(buffer, size, 1000, &sourceAddress, &sourcePort))) + { + InfoLog(<< "CLIENT: Received data from " << sourceAddress.to_string() << ":" << sourcePort << " - [" << resip::Data(buffer, size).c_str() << "]"); + size = sizeof(buffer); + } + if(rc) + { + if(rc.value() != asio::error::operation_aborted) + { + InfoLog( << "CLIENT: Receive error: [" << rc.value() << "] " << rc.message()); + } + } + +#ifdef CONTINUOUSTESTMODE + while(!rc || rc.value() == asio::error::operation_aborted) { +#endif + turnData = "This test is for ChannelData message!"; + InfoLog( << "CLIENT: Sending: " << turnData); + turnSocket.send(turnData.c_str(), turnData.size()); + + + while(!(rc=turnSocket.receive(buffer, size, 1000, &sourceAddress, &sourcePort))) + { + InfoLog(<< "CLIENT: Received data from " << sourceAddress.to_string() << ":" << sourcePort << " - [" << resip::Data(buffer, size).c_str() << "]"); + size = sizeof(buffer); + } + if(rc) + { + if(rc.value() != asio::error::operation_aborted) + { + InfoLog( << "CLIENT: Receive error: [" << rc.value() << "] " << rc.message()); + } + } +#ifdef CONTINUOUSTESTMODE + sleepSeconds(1); + }//end while +#endif + turnSocket.destroyAllocation(); + } + + turnPeer.shutdown(); + turnPeer.join(); + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/test/TestClient_10_0.vcxproj b/src/libs/resiprocate/reTurn/client/test/TestClient_10_0.vcxproj new file mode 100644 index 00000000..e5d992b7 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestClient_10_0.vcxproj @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>TestClient</ProjectName> + <ProjectGuid>{73151749-13F0-4093-97F1-A6952ECECDBF}</ProjectGuid> + <RootNamespace>TestClient</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <BuildLog> + <Path>$(IntDir)BuildLog-TestClient.htm</Path> + </BuildLog> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;LEAK_CHECK;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <ProgramDataBaseFileName>$(OutDir)TestClient.pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>winmm.lib;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)TestClient.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)TestClient.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <BuildLog> + <Path>$(IntDir)BuildLog-TestClient.htm</Path> + </BuildLog> + <ClCompile> + <AdditionalIncludeDirectories>../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <ProgramDataBaseFileName>$(OutDir)TestClient.pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>winmm.lib;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)TestClient.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="TestClient.cxx" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\rutil\rutil_10_0.vcxproj"> + <Project>{3d0e5ceb-93dc-4fdb-918b-d08fa369e106}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\reTurnClient_10_0.vcxproj"> + <Project>{67b5906c-5c9d-4d09-ac7e-af71d72175f8}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/reTurn/client/test/TestClient_10_0.vcxproj.filters b/src/libs/resiprocate/reTurn/client/test/TestClient_10_0.vcxproj.filters new file mode 100644 index 00000000..345d4093 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestClient_10_0.vcxproj.filters @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="TestClient.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/reTurn/client/test/TestClient_7_1.vcproj b/src/libs/resiprocate/reTurn/client/test/TestClient_7_1.vcproj new file mode 100644 index 00000000..1ad6826f --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestClient_7_1.vcproj @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="TestClient" + ProjectGUID="{73151749-13F0-4093-97F1-A6952ECECDBF}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="&quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/TestClient.exe" + LinkIncremental="2" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/TestClient.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;ASIO_ENABLE_CANCELIO" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="&quot;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/TestClient.exe" + LinkIncremental="1" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath=".\TestClient.cxx"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/client/test/TestClient_8_0.vcproj b/src/libs/resiprocate/reTurn/client/test/TestClient_8_0.vcproj new file mode 100644 index 00000000..43143db9 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestClient_8_0.vcproj @@ -0,0 +1,211 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="TestClient" + ProjectGUID="{73151749-13F0-4093-97F1-A6952ECECDBF}" + RootNamespace="TestClient" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-TestClient.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;LEAK_CHECK;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(OutDir)/TestClient.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/TestClient.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/TestClient.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + DependencyInformationFile="$(IntDir)\mt-TestClient.dep" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-TestClient.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;LEAK_CHECK;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;ASIO_ENABLE_CANCELIO" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(OutDir)/TestClient.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/TestClient.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + DependencyInformationFile="$(IntDir)\mt-TestClient.dep" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\TestClient.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/client/test/TestClient_9_0.vcproj b/src/libs/resiprocate/reTurn/client/test/TestClient_9_0.vcproj new file mode 100644 index 00000000..e0e9706b --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestClient_9_0.vcproj @@ -0,0 +1,210 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="TestClient" + ProjectGUID="{73151749-13F0-4093-97F1-A6952ECECDBF}" + RootNamespace="TestClient" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-TestClient.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;LEAK_CHECK;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(OutDir)/TestClient.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/TestClient.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/TestClient.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + DependencyInformationFile="$(IntDir)\mt-TestClient.dep" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-TestClient.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../../../contrib/asio;../../../contrib/boost_1_34_1;../../../;../../../contrib/OpenSSL/include;../../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(OutDir)/TestClient.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/TestClient.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + DependencyInformationFile="$(IntDir)\mt-TestClient.dep" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\TestClient.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/client/test/TestRtpLoad.cxx b/src/libs/resiprocate/reTurn/client/test/TestRtpLoad.cxx new file mode 100644 index 00000000..31844053 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/TestRtpLoad.cxx @@ -0,0 +1,377 @@ +#ifdef WIN32 +#pragma warning(disable : 4267) +#endif + +#include <iostream> +#include <string> +#include <asio.hpp> +#include <asio/ssl.hpp> +#include <rutil/ThreadIf.hxx> + +#include "../../StunTuple.hxx" +#include "../../StunMessage.hxx" +#include "../TurnUdpSocket.hxx" +#include "../TurnAsyncTcpSocket.hxx" +#include "../TurnAsyncTlsSocket.hxx" +#include "../TurnAsyncUdpSocket.hxx" +#include "../TurnAsyncSocketHandler.hxx" +#include <rutil/Timer.hxx> +#include <rutil/Logger.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/WinLeakCheck.hxx> + +using namespace reTurn; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST + +static unsigned int NUM_RTP_PACKETS_TO_SIMULATE=1500; // 30 seconds worth of RTP data +static unsigned int PACKET_TIME_TO_SIMULATE=20; // 20 ms + +// Test Config 1 +//#define RECEIVE_ONLY +//#define ALLOC_PORT 50000 +//#define OTHER_PORT 50002 + +// Test Config 2 +//#define SEND_ONLY +//#define ALLOC_PORT 50002 +//#define OTHER_PORT 50000 + +// Test Config 3 +//#define EXTERNAL_ECHO_SERVER +//#define OTHER_HOST "192.168.1.69" +//#define OTHER_PORT 2000 + +// Test Config 4 +//#define ECHO_SERVER_ONLY + +resip::Data address = resip::DnsUtil::getLocalIpAddress(); +resip::Data turnAddress; +char rtpPayloadData[172]; // 172 bytes of random data to simulate RTP payload +resip::Data rtpPayload(rtpPayloadData, sizeof(rtpPayloadData)); + +void sleepMS(unsigned int ms) +{ +#ifdef WIN32 + Sleep(ms); +#else + usleep(ms*1000); +#endif +} + +// Simple UDP Echo Server +class TurnPeer : public resip::ThreadIf +{ +public: + TurnPeer() {} + + virtual ~TurnPeer() {} + + virtual void thread() + { + asio::error_code rc; + TurnUdpSocket turnSocket(asio::ip::address::from_string(address.c_str()), 2000); + + char buffer[1024]; + unsigned int size = sizeof(buffer); + asio::ip::address sourceAddress; + unsigned short sourcePort; + bool connected = false; + + // Receive Data + rc=turnSocket.receive(buffer, size, 1000, &sourceAddress, &sourcePort); + while((!rc || rc.value() == asio::error::operation_aborted) && !isShutdown()) + { + if(!rc) + { + if(!connected) + { + turnSocket.connect(sourceAddress.to_string(), sourcePort); + connected = true; + } + //InfoLog(<< "PEER: Received data from " << sourceAddress << ":" << sourcePort << " - [" << resip::Data(buffer, size).c_str() << "]"); + turnSocket.send(buffer, size); + } + size = sizeof(buffer); + rc=turnSocket.receive(buffer, size, 1000, &sourceAddress, &sourcePort); + } + + if(rc) + { + if(rc.value() != asio::error::operation_aborted) + { + ErrLog(<< "PEER: Receive error: " << rc.message()); + } + } + } +private: +}; + +class MyTurnAsyncSocketHandler : public TurnAsyncSocketHandler +{ +public: + MyTurnAsyncSocketHandler(asio::io_service& ioService) : mIOService(ioService), mTimer(ioService), mNumReceives(0), mNumSends(0) {} + virtual ~MyTurnAsyncSocketHandler() {} + + void sendRtpSimPacket() + { + if(++mNumSends <= NUM_RTP_PACKETS_TO_SIMULATE) + { + mTimer.expires_from_now(boost::posix_time::milliseconds(PACKET_TIME_TO_SIMULATE)); + mTimer.async_wait(boost::bind(&MyTurnAsyncSocketHandler::sendRtpSimPacket, this)); + //InfoLog(<< "Sending packet " << mNumReceives << "..."); + mTurnAsyncSocket->send(rtpPayload.data(), rtpPayload.size()); + } + else + { + InfoLog(<< "Done sending " << NUM_RTP_PACKETS_TO_SIMULATE << " packets (" << mNumReceives << " receives have already been completed)."); +#ifdef SEND_ONLY + mTurnAsyncSocket->destroyAllocation(); +#endif + } + } + + virtual void onConnectSuccess(unsigned int socketDesc, const asio::ip::address& address, unsigned short port) + { + InfoLog( << "MyTurnAsyncSocketHandler::onConnectSuccess: socketDest=" << socketDesc << ", address=" << address.to_string() << ", port=" << port); + mTurnAsyncSocket->bindRequest(); + } + virtual void onConnectFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onConnectFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + virtual void onSharedSecretSuccess(unsigned int socketDesc, const char* username, unsigned int usernameSize, const char* password, unsigned int passwordSize) + { + InfoLog( << "MyTurnAsyncSocketHandler::onSharedSecretSuccess: socketDest=" << socketDesc << ", username=" << username << ", password=" << password); + } + + virtual void onSharedSecretFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onSharedSecretFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + virtual void onBindSuccess(unsigned int socketDesc, const StunTuple& reflexiveTuple) + { + InfoLog( << "MyTurnAsyncSocketHandler::onBindingSuccess: socketDest=" << socketDesc << ", reflexive=" << reflexiveTuple); + mTurnAsyncSocket->createAllocation(30, // TurnSocket::UnspecifiedLifetime, + TurnSocket::UnspecifiedBandwidth, + StunMessage::PropsPortPair, + TurnAsyncSocket::UnspecifiedToken, + StunTuple::UDP); + } + virtual void onBindFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onBindingFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + virtual void onAllocationSuccess(unsigned int socketDesc, const StunTuple& reflexiveTuple, const StunTuple& relayTuple, unsigned int lifetime, unsigned int bandwidth, UInt64 reservationToken) + { + InfoLog( << "MyTurnAsyncSocketHandler::onAllocationSuccess: socketDest=" << socketDesc << + ", reflexive=" << reflexiveTuple << + ", relay=" << relayTuple << + ", lifetime=" << lifetime << + ", bandwidth=" << bandwidth << + ", reservationToken=" << reservationToken); + +#ifdef RECEIVE_ONLY + // Send one packet of data so that it opens permission + mTurnAsyncSocket->sendTo(asio::ip::address::from_string(turnAddress.c_str()), OTHER_PORT, rtpPayload.data(), rtpPayload.size()); +#else +#ifdef SEND_ONLY + mTurnAsyncSocket->setActiveDestination(asio::ip::address::from_string(turnAddress.c_str()), OTHER_PORT); +#else +#ifdef EXTERNAL_ECHO_SERVER + mTurnAsyncSocket->setActiveDestination(asio::ip::address::from_string(OTHER_HOST), OTHER_PORT); +#else + mTurnAsyncSocket->setActiveDestination(asio::ip::address::from_string(address.c_str()), 2000); +#endif +#endif +#endif + } + virtual void onAllocationFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onAllocationFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + virtual void onRefreshSuccess(unsigned int socketDesc, unsigned int lifetime) + { + InfoLog( << "MyTurnAsyncSocketHandler::onRefreshSuccess: socketDest=" << socketDesc << ", lifetime=" << lifetime); + if(lifetime == 0) + { + InfoLog(<< "It took " << (time(0) - mStartTime) << " seconds to do " << NUM_RTP_PACKETS_TO_SIMULATE << " receives paced at " << PACKET_TIME_TO_SIMULATE << "ms apart."); + + mTurnAsyncSocket->close(); + } + } + virtual void onRefreshFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onRefreshFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + virtual void onSetActiveDestinationSuccess(unsigned int socketDesc) + { + InfoLog( << "MyTurnAsyncSocketHandler::onSetActiveDestinationSuccess: socketDest=" << socketDesc); + InfoLog(<< "Sending RTP payload..."); + mStartTime = time(0); + sendRtpSimPacket(); + } + virtual void onSetActiveDestinationFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onSetActiveDestinationFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + virtual void onClearActiveDestinationSuccess(unsigned int socketDesc) + { + InfoLog( << "MyTurnAsyncSocketHandler::onClearActiveDestinationSuccess: socketDest=" << socketDesc); + } + virtual void onClearActiveDestinationFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onClearActiveDestinationFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + virtual void onSendSuccess(unsigned int socketDesc) + { + //InfoLog( << "MyTurnAsyncSocketHandler::onSendSuccess: socketDest=" << socketDesc); + } + virtual void onSendFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onSendFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + virtual void onReceiveSuccess(unsigned int socketDesc, const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) + { + //InfoLog( << "MyTurnAsyncSocketHandler::onReceiveSuccess: socketDest=" << socketDesc << ", fromAddress=" << address << ", fromPort=" << port << ", size=" << data->size() << ", data=" << data->data()); + if(++mNumReceives == NUM_RTP_PACKETS_TO_SIMULATE) + { + InfoLog(<< "Done receiving " << NUM_RTP_PACKETS_TO_SIMULATE << " packets."); + mTurnAsyncSocket->destroyAllocation(); + } + } + virtual void onReceiveFailure(unsigned int socketDesc, const asio::error_code& e) + { + InfoLog( << "MyTurnAsyncSocketHandler::onReceiveFailure: socketDest=" << socketDesc << " error=" << e.value() << "(" << e.message() << ")."); + } + + void setTurnAsyncSocket(TurnAsyncSocket* turnAsyncSocket) { mTurnAsyncSocket = turnAsyncSocket; } + +private: + asio::io_service& mIOService; + asio::deadline_timer mTimer; + TurnAsyncSocket* mTurnAsyncSocket; + unsigned int mNumReceives; + unsigned int mNumSends; + time_t mStartTime; + UInt64 mRTPSendTime; +}; + +int main(int argc, char* argv[]) +{ +#ifdef WIN32 + resip::FindMemoryLeaks fml; +#endif + try + { + //if (argc == 2) + //{ + // InfoLog(<< "Starting Echo server only..."); + // TurnPeer turnPeer; + // turnPeer.run(); + // turnPeer.join(); + // return 0; + //} + + if (argc < 3) + { + std::cerr << "Usage: stunTestClient <host> <port> [<PacketTime>]\n"; + return 1; + } + turnAddress = argv[1]; + unsigned int port = resip::Data(argv[2]).convertUnsignedLong(); + + if(argc == 4) + { + PACKET_TIME_TO_SIMULATE = atoi(argv[3]); + } + InfoLog(<< "Using " << address << " as local IP address."); + + asio::error_code rc; + char username[256] = "test"; + char password[256] = "1234"; +#ifndef OTHER_PORT + TurnPeer turnPeer; + turnPeer.run(); +#endif + +#ifndef ECHO_SERVER_ONLY + asio::io_service ioService; + MyTurnAsyncSocketHandler handler(ioService); + + asio::ssl::context sslContext(ioService, asio::ssl::context::tlsv1); + // Setup SSL context + sslContext.set_verify_mode(asio::ssl::context::verify_peer); + sslContext.load_verify_file("ca.pem"); + + boost::shared_ptr<TurnAsyncSocket> turnSocket(new TurnAsyncUdpSocket(ioService, &handler, asio::ip::address::from_string(address.c_str()), 0)); + //boost::shared_ptr<TurnAsyncSocket> turnSocket(new TurnAsyncTcpSocket(ioService, &handler, asio::ip::address::from_string(address.c_str()), 0)); + //boost::shared_ptr<TurnAsyncSocket> turnSocket(new TurnAsyncTlsSocket(ioService, sslContext, &handler, asio::ip::address::from_string(address.c_str()), 0)); port++; + + handler.setTurnAsyncSocket(turnSocket.get()); + + // Connect to Stun/Turn Server + turnSocket->connect(turnAddress.c_str(), port); + + // Set the username and password + turnSocket->setUsernameAndPassword(username, password); + + ioService.run(); + +#ifndef OTHER_PORT + turnPeer.shutdown(); + turnPeer.join(); +#endif +#else + turnPeer.join(); +#endif + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/client/test/ca.pem b/src/libs/resiprocate/reTurn/client/test/ca.pem new file mode 100644 index 00000000..083de374 --- /dev/null +++ b/src/libs/resiprocate/reTurn/client/test/ca.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJDCCAo2gAwIBAgIBADANBgkqhkiG9w0BAQUFADBwMQswCQYDVQQGEwJVUzET +MBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2UxDjAMBgNVBAoT +BXNpcGl0MSkwJwYDVQQLEyBTaXBpdCBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0 +eTAeFw0wMzA3MTgxMjIxNTJaFw0xMzA3MTUxMjIxNTJaMHAxCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9zZTEOMAwGA1UE +ChMFc2lwaXQxKTAnBgNVBAsTIFNpcGl0IFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9y +aXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDIh6DkcUDLDyK9BEUxkud ++nJ4xrCVGKfgjHm6XaSuHiEtnfELHM+9WymzkBNzZpJu30yzsxwfKoIKugdNUrD4 +N3viCicwcN35LgP/KnbN34cavXHr4ZlqxH+OdKB3hQTpQa38A7YXdaoz6goW2ft5 +Mi74z03GNKP/G9BoKOGd5QIDAQABo4HNMIHKMB0GA1UdDgQWBBRrRhcU6pR2JYBU +bhNU2qHjVBShtjCBmgYDVR0jBIGSMIGPgBRrRhcU6pR2JYBUbhNU2qHjVBShtqF0 +pHIwcDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcT +CFNhbiBKb3NlMQ4wDAYDVQQKEwVzaXBpdDEpMCcGA1UECxMgU2lwaXQgVGVzdCBD +ZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B +AQUFAAOBgQCWbRvv1ZGTRXxbH8/EqkdSCzSoUPrs+rQqR0xdQac9wNY/nlZbkR3O +qAezG6Sfmklvf+DOg5RxQq/+Y6I03LRepc7KeVDpaplMFGnpfKsibETMipwzayNQ +QgUf4cKBiF+65Ue7hZuDJa2EMv8qW4twEhGDYclpFU9YozyS1OhvUg== +-----END CERTIFICATE----- diff --git a/src/libs/resiprocate/reTurn/dh512.pem b/src/libs/resiprocate/reTurn/dh512.pem new file mode 100644 index 00000000..14c53b2a --- /dev/null +++ b/src/libs/resiprocate/reTurn/dh512.pem @@ -0,0 +1,12 @@ +Diffie-Hellman-Parameters: (512 bit) + prime: + 00:a0:bc:d0:c2:c3:a8:c7:a5:62:13:cd:f0:63:39: + ea:85:e0:f7:ca:00:8a:57:ec:12:dd:92:2b:20:70: + 38:6c:03:60:b1:19:e3:0b:e9:d3:05:f1:1b:cc:8c: + 9c:1a:30:3e:91:de:db:17:a7:19:cf:da:a0:2d:ee: + ef:35:95:8b:4b + generator: 5 (0x5) +-----BEGIN DH PARAMETERS----- +MEYCQQCgvNDCw6jHpWITzfBjOeqF4PfKAIpX7BLdkisgcDhsA2CxGeML6dMF8RvM +jJwaMD6R3tsXpxnP2qAt7u81lYtLAgEF +-----END DH PARAMETERS----- diff --git a/src/libs/resiprocate/reTurn/reTurnServer.cxx b/src/libs/resiprocate/reTurn/reTurnServer.cxx new file mode 100644 index 00000000..4851f5c2 --- /dev/null +++ b/src/libs/resiprocate/reTurn/reTurnServer.cxx @@ -0,0 +1,205 @@ +#include <iostream> +#include <string> +#include <asio.hpp> +#include <boost/bind.hpp> +#include <boost/function.hpp> +#include <boost/lexical_cast.hpp> +#include <rutil/Data.hxx> +#include "reTurnServer.hxx" +#include "TcpServer.hxx" +#include "TlsServer.hxx" +#include "UdpServer.hxx" +#include "ReTurnConfig.hxx" +#include "RequestHandler.hxx" +#include "TurnManager.hxx" +#include <rutil/WinLeakCheck.hxx> +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include "ReTurnSubsystem.hxx" + +#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN + +#if defined(_WIN32) + +boost::function0<void> console_ctrl_function; + +BOOL WINAPI console_ctrl_handler(DWORD ctrl_type) +{ + switch (ctrl_type) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + case CTRL_CLOSE_EVENT: + case CTRL_SHUTDOWN_EVENT: + console_ctrl_function(); + return TRUE; + default: + return FALSE; + } +} +#endif // defined(_WIN32) + +int main(int argc, char* argv[]) +{ + reTurn::ReTurnServerProcess proc; + return proc.main(argc, argv); +} + +reTurn::ReTurnServerProcess::ReTurnServerProcess() +{ +} + +reTurn::ReTurnServerProcess::~ReTurnServerProcess() +{ +} + +int +reTurn::ReTurnServerProcess::main(int argc, char* argv[]) +{ +#if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK) + resip::FindMemoryLeaks fml; +#endif + + resip::Data defaultConfig("reTurnServer.config"); + reTurn::ReTurnConfig reTurnConfig; + try + { + reTurnConfig.parseConfig(argc, argv, defaultConfig); + } + catch(std::exception& e) + { + ErrLog(<< "Exception parsing configuration: " << e.what()); + exit(-1); + } + + setPidFile(reTurnConfig.mPidFile); + // Daemonize if necessary + if(reTurnConfig.mDaemonize) + { + daemonize(); + } + + try + { + // Initialize Logging + resip::Log::initialize(reTurnConfig.mLoggingType, reTurnConfig.mLoggingLevel, "reTurnServer", reTurnConfig.mLoggingFilename.c_str()); + resip::GenericLogImpl::MaxLineCount = reTurnConfig.mLoggingFileMaxLineCount; + + // Initialize server. + asio::io_service ioService; // The one and only ioService for the stunServer + reTurn::TurnManager turnManager(ioService, reTurnConfig); // The one and only Turn Manager + + boost::shared_ptr<reTurn::UdpServer> udpTurnServer; // also a1p1StunUdpServer + boost::shared_ptr<reTurn::TcpServer> tcpTurnServer; + boost::shared_ptr<reTurn::TlsServer> tlsTurnServer; + boost::shared_ptr<reTurn::UdpServer> a1p2StunUdpServer; + boost::shared_ptr<reTurn::UdpServer> a2p1StunUdpServer; + boost::shared_ptr<reTurn::UdpServer> a2p2StunUdpServer; + + // The one and only RequestHandler - if altStunPort is non-zero, then assume RFC3489 support is enabled and pass settings to request handler + reTurn::RequestHandler requestHandler(turnManager, + reTurnConfig.mAltStunPort != 0 ? &reTurnConfig.mTurnAddress : 0, + reTurnConfig.mAltStunPort != 0 ? &reTurnConfig.mTurnPort : 0, + reTurnConfig.mAltStunPort != 0 ? &reTurnConfig.mAltStunAddress : 0, + reTurnConfig.mAltStunPort != 0 ? &reTurnConfig.mAltStunPort : 0); + + udpTurnServer.reset(new reTurn::UdpServer(ioService, requestHandler, reTurnConfig.mTurnAddress, reTurnConfig.mTurnPort)); + tcpTurnServer.reset(new reTurn::TcpServer(ioService, requestHandler, reTurnConfig.mTurnAddress, reTurnConfig.mTurnPort)); + tlsTurnServer.reset(new reTurn::TlsServer(ioService, requestHandler, reTurnConfig.mTurnAddress, reTurnConfig.mTlsTurnPort)); + + if(reTurnConfig.mAltStunPort != 0) // if alt stun port is non-zero, then RFC3489 support is enabled + { + a1p2StunUdpServer.reset(new reTurn::UdpServer(ioService, requestHandler, reTurnConfig.mTurnAddress, reTurnConfig.mAltStunPort)); + a2p1StunUdpServer.reset(new reTurn::UdpServer(ioService, requestHandler, reTurnConfig.mAltStunAddress, reTurnConfig.mTurnPort)); + a2p2StunUdpServer.reset(new reTurn::UdpServer(ioService, requestHandler, reTurnConfig.mAltStunAddress, reTurnConfig.mAltStunPort)); + udpTurnServer->setAlternateUdpServers(a1p2StunUdpServer.get(), a2p1StunUdpServer.get(), a2p2StunUdpServer.get()); + a1p2StunUdpServer->setAlternateUdpServers(udpTurnServer.get(), a2p2StunUdpServer.get(), a2p1StunUdpServer.get()); + a2p1StunUdpServer->setAlternateUdpServers(a2p2StunUdpServer.get(), udpTurnServer.get(), a1p2StunUdpServer.get()); + a2p2StunUdpServer->setAlternateUdpServers(a2p1StunUdpServer.get(), a1p2StunUdpServer.get(), udpTurnServer.get()); + a1p2StunUdpServer->start(); + a2p1StunUdpServer->start(); + a2p2StunUdpServer->start(); + } + + udpTurnServer->start(); + tcpTurnServer->start(); + tlsTurnServer->start(); + +#ifdef _WIN32 + // Set console control handler to allow server to be stopped. + console_ctrl_function = boost::bind(&asio::io_service::stop, &ioService); + SetConsoleCtrlHandler(console_ctrl_handler, TRUE); +#else + // Block all signals for background thread. + sigset_t new_mask; + sigfillset(&new_mask); + sigset_t old_mask; + pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); +#endif + + // Run the ioService until stopped. + // Create a pool of threads to run all of the io_services. + boost::shared_ptr<asio::thread> thread(new asio::thread( + boost::bind(&asio::io_service::run, &ioService))); + +#ifndef _WIN32 + // Restore previous signals. + pthread_sigmask(SIG_SETMASK, &old_mask, 0); + + // Wait for signal indicating time to shut down. + sigset_t wait_mask; + sigemptyset(&wait_mask); + sigaddset(&wait_mask, SIGINT); + sigaddset(&wait_mask, SIGQUIT); + sigaddset(&wait_mask, SIGTERM); + pthread_sigmask(SIG_BLOCK, &wait_mask, 0); + int sig = 0; + sigwait(&wait_mask, &sig); + ioService.stop(); +#endif + + // Wait for thread to exit + thread->join(); + } + catch (std::exception& e) + { + ErrLog(<< "exception: " << e.what()); + } + + return 0; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/reTurnServer.hxx b/src/libs/resiprocate/reTurn/reTurnServer.hxx new file mode 100644 index 00000000..6031da2b --- /dev/null +++ b/src/libs/resiprocate/reTurn/reTurnServer.hxx @@ -0,0 +1,70 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "rutil/ServerProcess.hxx" + +namespace reTurn +{ + +class ReTurnServerProcess : public resip::ServerProcess +{ +public: + ReTurnServerProcess(); + virtual ~ReTurnServerProcess(); + + virtual int main(int argc, char *argv[]); + +protected: +}; + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + */ +/* + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/reTurn/reTurnServer_10_0.vcxproj b/src/libs/resiprocate/reTurn/reTurnServer_10_0.vcxproj new file mode 100644 index 00000000..a505852c --- /dev/null +++ b/src/libs/resiprocate/reTurn/reTurnServer_10_0.vcxproj @@ -0,0 +1,317 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>reTurnServer</ProjectName> + <ProjectGuid>{EFA91988-1A0C-4739-9FF1-7471E933515C}</ProjectGuid> + <RootNamespace>reTurnServer</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>../contrib/asio;../contrib/boost_1_34_1;../contrib/OpenSSL/include;../contrib/OpenSSL/inc32;../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>winmm.lib;$(ProjectDir)..\contrib\openssl\lib\vc\static\libeay32MDd.lib;$(ProjectDir)..\contrib\openssl\lib\vc\static\ssleay32MDd.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)reTurnServer.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)reTurnServer.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>../contrib/asio;../contrib/boost_1_34_1;../contrib/OpenSSL/include;../contrib/OpenSSL/inc32;../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>winmm.lib;$(ProjectDir)..\contrib\openssl\out32\libeay32.lib;$(ProjectDir)..\contrib\openssl\out32\ssleay32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)reTurnServer.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="AsyncSocketBase.cxx" /> + <ClCompile Include="AsyncTcpSocketBase.cxx" /> + <ClCompile Include="AsyncTlsSocketBase.cxx" /> + <ClCompile Include="AsyncUdpSocketBase.cxx" /> + <ClCompile Include="ChannelManager.cxx" /> + <ClCompile Include="ConnectionManager.cxx" /> + <ClCompile Include="DataBuffer.cxx" /> + <ClCompile Include="RemotePeer.cxx" /> + <ClCompile Include="RequestHandler.cxx" /> + <ClCompile Include="ReTurnConfig.cxx" /> + <ClCompile Include="reTurnServer.cxx" /> + <ClCompile Include="ReTurnSubsystem.cxx" /> + <ClCompile Include="StunAuth.cxx" /> + <ClCompile Include="StunMessage.cxx" /> + <ClCompile Include="StunTuple.cxx" /> + <ClCompile Include="TcpConnection.cxx" /> + <ClCompile Include="TcpServer.cxx" /> + <ClCompile Include="TlsConnection.cxx" /> + <ClCompile Include="TlsServer.cxx" /> + <ClCompile Include="TurnAllocation.cxx" /> + <ClCompile Include="TurnAllocationKey.cxx" /> + <ClCompile Include="TurnManager.cxx" /> + <ClCompile Include="TurnPermission.cxx" /> + <ClCompile Include="UdpRelayServer.cxx" /> + <ClCompile Include="UdpServer.cxx" /> + <ClCompile Include="UserAuthData.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="AsyncSocketBase.hxx" /> + <ClInclude Include="AsyncSocketBaseHandler.hxx" /> + <ClInclude Include="AsyncTcpSocketBase.hxx" /> + <ClInclude Include="AsyncTlsSocketBase.hxx" /> + <ClInclude Include="AsyncUdpSocketBase.hxx" /> + <ClInclude Include="ChannelManager.hxx" /> + <ClInclude Include="ConnectionManager.hxx" /> + <ClInclude Include="DataBuffer.hxx" /> + <ClInclude Include="RemotePeer.hxx" /> + <ClInclude Include="RequestHandler.hxx" /> + <ClInclude Include="ReTurnConfig.hxx" /> + <ClInclude Include="ReTurnSubsystem.hxx" /> + <ClInclude Include="StunAuth.hxx" /> + <ClInclude Include="StunMessage.hxx" /> + <ClInclude Include="StunTuple.hxx" /> + <ClInclude Include="TcpConnection.hxx" /> + <ClInclude Include="TcpServer.hxx" /> + <ClInclude Include="TlsConnection.hxx" /> + <ClInclude Include="TlsServer.hxx" /> + <ClInclude Include="TurnAllocation.hxx" /> + <ClInclude Include="TurnAllocationKey.hxx" /> + <ClInclude Include="TurnManager.hxx" /> + <ClInclude Include="TurnPermission.hxx" /> + <ClInclude Include="UdpRelayServer.hxx" /> + <ClInclude Include="UdpServer.hxx" /> + <ClInclude Include="..\contrib\asio\asio.hpp" /> + <ClInclude Include="..\contrib\asio\asio\basic_datagram_socket.hpp" /> + <ClInclude Include="..\contrib\asio\asio\basic_deadline_timer.hpp" /> + <ClInclude Include="..\contrib\asio\asio\basic_io_object.hpp" /> + <ClInclude Include="..\contrib\asio\asio\basic_socket.hpp" /> + <ClInclude Include="..\contrib\asio\asio\basic_socket_acceptor.hpp" /> + <ClInclude Include="..\contrib\asio\asio\basic_socket_iostream.hpp" /> + <ClInclude Include="..\contrib\asio\asio\basic_socket_streambuf.hpp" /> + <ClInclude Include="..\contrib\asio\asio\basic_stream_socket.hpp" /> + <ClInclude Include="..\contrib\asio\asio\basic_streambuf.hpp" /> + <ClInclude Include="..\contrib\asio\asio\buffer.hpp" /> + <ClInclude Include="..\contrib\asio\asio\buffered_read_stream.hpp" /> + <ClInclude Include="..\contrib\asio\asio\buffered_read_stream_fwd.hpp" /> + <ClInclude Include="..\contrib\asio\asio\buffered_stream.hpp" /> + <ClInclude Include="..\contrib\asio\asio\buffered_stream_fwd.hpp" /> + <ClInclude Include="..\contrib\asio\asio\buffered_write_stream.hpp" /> + <ClInclude Include="..\contrib\asio\asio\buffered_write_stream_fwd.hpp" /> + <ClInclude Include="..\contrib\asio\asio\completion_condition.hpp" /> + <ClInclude Include="..\contrib\asio\asio\datagram_socket_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\deadline_timer.hpp" /> + <ClInclude Include="..\contrib\asio\asio\deadline_timer_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\error.hpp" /> + <ClInclude Include="..\contrib\asio\asio\error_code.hpp" /> + <ClInclude Include="..\contrib\asio\asio\handler_alloc_hook.hpp" /> + <ClInclude Include="..\contrib\asio\asio\handler_invoke_hook.hpp" /> + <ClInclude Include="..\contrib\asio\asio\io_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\is_read_buffered.hpp" /> + <ClInclude Include="..\contrib\asio\asio\is_write_buffered.hpp" /> + <ClInclude Include="..\contrib\asio\asio\placeholders.hpp" /> + <ClInclude Include="..\contrib\asio\asio\read.hpp" /> + <ClInclude Include="..\contrib\asio\asio\read_until.hpp" /> + <ClInclude Include="..\contrib\asio\asio\socket_acceptor_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\socket_base.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl.hpp" /> + <ClInclude Include="..\contrib\asio\asio\strand.hpp" /> + <ClInclude Include="..\contrib\asio\asio\stream_socket_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\streambuf.hpp" /> + <ClInclude Include="..\contrib\asio\asio\system_error.hpp" /> + <ClInclude Include="..\contrib\asio\asio\thread.hpp" /> + <ClInclude Include="..\contrib\asio\asio\time_traits.hpp" /> + <ClInclude Include="..\contrib\asio\asio\version.hpp" /> + <ClInclude Include="..\contrib\asio\asio\write.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\bind_handler.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\buffer_resize_guard.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\buffered_stream_storage.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\call_stack.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\const_buffers_iterator.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\consuming_buffers.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\deadline_timer_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\epoll_reactor.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\epoll_reactor_fwd.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\event.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\fd_set_adapter.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\handler_alloc_helpers.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\handler_invoke_helpers.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\hash_map.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\io_control.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\kqueue_reactor.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\kqueue_reactor_fwd.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\local_free_on_block_exit.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\mutex.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\noncopyable.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\null_event.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\null_mutex.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\null_signal_blocker.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\null_thread.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\null_tss_ptr.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\old_win_sdk_compat.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\pipe_select_interrupter.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\pop_options.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\posix_event.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\posix_fd_set_adapter.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\posix_mutex.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\posix_signal_blocker.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\posix_thread.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\posix_tss_ptr.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\push_options.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\reactive_socket_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\reactor_op_queue.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\resolver_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\scoped_lock.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\select_interrupter.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\select_reactor.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\select_reactor_fwd.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\service_base.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\service_id.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\service_registry.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\service_registry_fwd.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\signal_blocker.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\signal_init.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\socket_holder.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\socket_ops.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\socket_option.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\socket_select_interrupter.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\socket_types.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\strand_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\task_io_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\task_io_service_fwd.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\thread.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\throw_error.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\timer_queue.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\timer_queue_base.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\tss_ptr.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\win_event.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\win_fd_set_adapter.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\win_iocp_io_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\win_iocp_io_service_fwd.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\win_iocp_operation.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\win_iocp_socket_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\win_mutex.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\win_signal_blocker.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\win_thread.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\win_tss_ptr.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\winsock_init.hpp" /> + <ClInclude Include="..\contrib\asio\asio\detail\wrapped_handler.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\address.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\address_v4.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\address_v6.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\basic_endpoint.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\basic_resolver.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\basic_resolver_entry.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\basic_resolver_iterator.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\basic_resolver_query.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\host_name.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\multicast.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\resolver_query_base.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\resolver_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\tcp.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\udp.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\unicast.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\v6_only.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ip\detail\socket_option.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl\basic_context.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl\context.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl\context_base.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl\context_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl\stream.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl\stream_base.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl\stream_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl\detail\openssl_context_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl\detail\openssl_init.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl\detail\openssl_operation.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl\detail\openssl_stream_service.hpp" /> + <ClInclude Include="..\contrib\asio\asio\ssl\detail\openssl_types.hpp" /> + <ClInclude Include="UserAuthData.hxx" /> + </ItemGroup> + <ItemGroup> + <None Include="README.txt" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\rutil\rutil_10_0.vcxproj"> + <Project>{3d0e5ceb-93dc-4fdb-918b-d08fa369e106}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/reTurn/reTurnServer_10_0.vcxproj.filters b/src/libs/resiprocate/reTurn/reTurnServer_10_0.vcxproj.filters new file mode 100644 index 00000000..b48e010d --- /dev/null +++ b/src/libs/resiprocate/reTurn/reTurnServer_10_0.vcxproj.filters @@ -0,0 +1,633 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + <Filter Include="ASIO Header Files"> + <UniqueIdentifier>{5ff062c4-5808-4d60-9595-29397531617d}</UniqueIdentifier> + </Filter> + <Filter Include="ASIO Header Files\asio"> + <UniqueIdentifier>{6ee0fae4-1460-4634-83fc-8734352d2fb1}</UniqueIdentifier> + </Filter> + <Filter Include="ASIO Header Files\asio\detail"> + <UniqueIdentifier>{6b9ce753-4d1f-402b-9724-17756f497e2e}</UniqueIdentifier> + </Filter> + <Filter Include="ASIO Header Files\asio\ip"> + <UniqueIdentifier>{284af25b-93a5-4a58-a0cc-1565b02d3249}</UniqueIdentifier> + </Filter> + <Filter Include="ASIO Header Files\asio\ip\detail"> + <UniqueIdentifier>{22434ead-0da5-4189-87ac-e13267ce7256}</UniqueIdentifier> + </Filter> + <Filter Include="ASIO Header Files\asio\ssl"> + <UniqueIdentifier>{8a9d23d0-63ce-4c7f-8789-74dd8f24f938}</UniqueIdentifier> + </Filter> + <Filter Include="ASIO Header Files\asio\ssl\detail"> + <UniqueIdentifier>{690eb0b8-e049-48c3-a4fe-ba1f29741980}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="AsyncSocketBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="AsyncTcpSocketBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="AsyncTlsSocketBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="AsyncUdpSocketBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ChannelManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ConnectionManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DataBuffer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RemotePeer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RequestHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ReTurnConfig.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="reTurnServer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ReTurnSubsystem.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StunAuth.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StunMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StunTuple.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TcpConnection.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TcpServer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TlsConnection.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TlsServer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnAllocation.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnAllocationKey.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TurnPermission.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UdpRelayServer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UdpServer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UserAuthData.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="AsyncSocketBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AsyncSocketBaseHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AsyncTcpSocketBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AsyncTlsSocketBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AsyncUdpSocketBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ChannelManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConnectionManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DataBuffer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RemotePeer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RequestHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ReTurnConfig.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ReTurnSubsystem.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StunAuth.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StunMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StunTuple.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TcpConnection.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TcpServer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TlsConnection.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TlsServer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnAllocation.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnAllocationKey.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TurnPermission.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UdpRelayServer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UdpServer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio.hpp"> + <Filter>ASIO Header Files</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\basic_datagram_socket.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\basic_deadline_timer.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\basic_io_object.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\basic_socket.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\basic_socket_acceptor.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\basic_socket_iostream.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\basic_socket_streambuf.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\basic_stream_socket.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\basic_streambuf.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\buffer.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\buffered_read_stream.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\buffered_read_stream_fwd.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\buffered_stream.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\buffered_stream_fwd.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\buffered_write_stream.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\buffered_write_stream_fwd.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\completion_condition.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\datagram_socket_service.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\deadline_timer.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\deadline_timer_service.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\error.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\error_code.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\handler_alloc_hook.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\handler_invoke_hook.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\io_service.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\is_read_buffered.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\is_write_buffered.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\placeholders.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\read.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\read_until.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\socket_acceptor_service.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\socket_base.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\strand.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\stream_socket_service.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\streambuf.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\system_error.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\thread.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\time_traits.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\version.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\write.hpp"> + <Filter>ASIO Header Files\asio</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\bind_handler.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\buffer_resize_guard.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\buffered_stream_storage.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\call_stack.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\const_buffers_iterator.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\consuming_buffers.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\deadline_timer_service.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\epoll_reactor.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\epoll_reactor_fwd.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\event.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\fd_set_adapter.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\handler_alloc_helpers.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\handler_invoke_helpers.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\hash_map.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\io_control.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\kqueue_reactor.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\kqueue_reactor_fwd.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\local_free_on_block_exit.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\mutex.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\noncopyable.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\null_event.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\null_mutex.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\null_signal_blocker.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\null_thread.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\null_tss_ptr.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\old_win_sdk_compat.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\pipe_select_interrupter.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\pop_options.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\posix_event.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\posix_fd_set_adapter.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\posix_mutex.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\posix_signal_blocker.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\posix_thread.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\posix_tss_ptr.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\push_options.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\reactive_socket_service.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\reactor_op_queue.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\resolver_service.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\scoped_lock.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\select_interrupter.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\select_reactor.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\select_reactor_fwd.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\service_base.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\service_id.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\service_registry.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\service_registry_fwd.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\signal_blocker.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\signal_init.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\socket_holder.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\socket_ops.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\socket_option.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\socket_select_interrupter.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\socket_types.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\strand_service.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\task_io_service.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\task_io_service_fwd.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\thread.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\throw_error.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\timer_queue.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\timer_queue_base.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\tss_ptr.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\win_event.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\win_fd_set_adapter.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\win_iocp_io_service.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\win_iocp_io_service_fwd.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\win_iocp_operation.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\win_iocp_socket_service.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\win_mutex.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\win_signal_blocker.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\win_thread.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\win_tss_ptr.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\winsock_init.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\detail\wrapped_handler.hpp"> + <Filter>ASIO Header Files\asio\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\address.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\address_v4.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\address_v6.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\basic_endpoint.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\basic_resolver.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\basic_resolver_entry.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\basic_resolver_iterator.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\basic_resolver_query.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\host_name.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\multicast.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\resolver_query_base.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\resolver_service.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\tcp.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\udp.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\unicast.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\v6_only.hpp"> + <Filter>ASIO Header Files\asio\ip</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ip\detail\socket_option.hpp"> + <Filter>ASIO Header Files\asio\ip\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl\basic_context.hpp"> + <Filter>ASIO Header Files\asio\ssl</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl\context.hpp"> + <Filter>ASIO Header Files\asio\ssl</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl\context_base.hpp"> + <Filter>ASIO Header Files\asio\ssl</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl\context_service.hpp"> + <Filter>ASIO Header Files\asio\ssl</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl\stream.hpp"> + <Filter>ASIO Header Files\asio\ssl</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl\stream_base.hpp"> + <Filter>ASIO Header Files\asio\ssl</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl\stream_service.hpp"> + <Filter>ASIO Header Files\asio\ssl</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl\detail\openssl_context_service.hpp"> + <Filter>ASIO Header Files\asio\ssl\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl\detail\openssl_init.hpp"> + <Filter>ASIO Header Files\asio\ssl\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl\detail\openssl_operation.hpp"> + <Filter>ASIO Header Files\asio\ssl\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl\detail\openssl_stream_service.hpp"> + <Filter>ASIO Header Files\asio\ssl\detail</Filter> + </ClInclude> + <ClInclude Include="..\contrib\asio\asio\ssl\detail\openssl_types.hpp"> + <Filter>ASIO Header Files\asio\ssl\detail</Filter> + </ClInclude> + <ClInclude Include="UserAuthData.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="README.txt" /> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/reTurn/reTurnServer_7_1.vcproj b/src/libs/resiprocate/reTurn/reTurnServer_7_1.vcproj new file mode 100644 index 00000000..455b11bd --- /dev/null +++ b/src/libs/resiprocate/reTurn/reTurnServer_7_1.vcproj @@ -0,0 +1,739 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="reTurnServer" + ProjectGUID="{EFA91988-1A0C-4739-9FF1-7471E933515C}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../contrib/asio;../contrib/boost_1_34_1;../contrib/OpenSSL/include;../contrib/OpenSSL/inc32;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;LEAK_CHECK" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="&quot;$(ProjectDir)..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\contrib\openssl\out32.dbg\ssleay32.lib&quot;" + OutputFile="$(OutDir)/reTurnServer.exe" + LinkIncremental="2" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/reTurnServer.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../contrib/asio;../contrib/boost_1_34_1;../contrib/OpenSSL/include;../contrib/OpenSSL/inc32;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL" + RuntimeLibrary="2" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="&quot;$(ProjectDir)..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\contrib\openssl\out32\ssleay32.lib&quot;" + OutputFile="$(OutDir)/reTurnServer.exe" + LinkIncremental="1" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath=".\AsyncSocketBase.cxx"> + </File> + <File + RelativePath=".\AsyncTcpSocketBase.cxx"> + </File> + <File + RelativePath=".\AsyncTlsSocketBase.cxx"> + </File> + <File + RelativePath=".\AsyncUdpSocketBase.cxx"> + </File> + <File + RelativePath=".\ChannelManager.cxx"> + </File> + <File + RelativePath=".\ConnectionManager.cxx"> + </File> + <File + RelativePath=".\DataBuffer.cxx"> + </File> + <File + RelativePath=".\RemotePeer.cxx"> + </File> + <File + RelativePath=".\RequestHandler.cxx"> + </File> + <File + RelativePath=".\reTurnServer.cxx"> + </File> + <File + RelativePath=".\ReTurnSubsystem.cxx"> + </File> + <File + RelativePath=".\StunAuth.cxx"> + </File> + <File + RelativePath=".\StunMessage.cxx"> + </File> + <File + RelativePath=".\StunTuple.cxx"> + </File> + <File + RelativePath=".\TcpConnection.cxx"> + </File> + <File + RelativePath=".\TcpServer.cxx"> + </File> + <File + RelativePath=".\TlsConnection.cxx"> + </File> + <File + RelativePath=".\TlsServer.cxx"> + </File> + <File + RelativePath=".\TurnAllocation.cxx"> + </File> + <File + RelativePath=".\TurnAllocationKey.cxx"> + </File> + <File + RelativePath=".\TurnManager.cxx"> + </File> + <File + RelativePath=".\TurnPermission.cxx"> + </File> + <File + RelativePath=".\UdpRelayServer.cxx"> + </File> + <File + RelativePath=".\UdpServer.cxx"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath=".\AsyncSocketBase.hxx"> + </File> + <File + RelativePath=".\AsyncSocketBaseHandler.hxx"> + </File> + <File + RelativePath=".\AsyncTcpSocketBase.hxx"> + </File> + <File + RelativePath=".\AsyncTlsSocketBase.hxx"> + </File> + <File + RelativePath=".\AsyncUdpSocketBase.hxx"> + </File> + <File + RelativePath=".\ChannelManager.hxx"> + </File> + <File + RelativePath=".\ConnectionManager.hxx"> + </File> + <File + RelativePath=".\DataBuffer.hxx"> + </File> + <File + RelativePath=".\RemotePeer.hxx"> + </File> + <File + RelativePath=".\RequestHandler.hxx"> + </File> + <File + RelativePath=".\ReTurnSubsystem.hxx"> + </File> + <File + RelativePath=".\StunAuth.hxx"> + </File> + <File + RelativePath=".\StunMessage.hxx"> + </File> + <File + RelativePath=".\StunTuple.hxx"> + </File> + <File + RelativePath=".\TcpConnection.hxx"> + </File> + <File + RelativePath=".\TcpServer.hxx"> + </File> + <File + RelativePath=".\TlsConnection.hxx"> + </File> + <File + RelativePath=".\TlsServer.hxx"> + </File> + <File + RelativePath=".\TurnAllocation.hxx"> + </File> + <File + RelativePath=".\TurnAllocationKey.hxx"> + </File> + <File + RelativePath=".\TurnManager.hxx"> + </File> + <File + RelativePath=".\TurnPermission.hxx"> + </File> + <File + RelativePath=".\UdpRelayServer.hxx"> + </File> + <File + RelativePath=".\UdpServer.hxx"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + <Filter + Name="ASIO Header Files" + Filter=""> + <File + RelativePath="..\contrib\asio\asio.hpp"> + </File> + <Filter + Name="asio" + Filter=""> + <File + RelativePath="..\contrib\asio\asio\basic_datagram_socket.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\basic_deadline_timer.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\basic_io_object.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\basic_socket.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\basic_socket_acceptor.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\basic_socket_iostream.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\basic_socket_streambuf.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\basic_stream_socket.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\basic_streambuf.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\buffer.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_read_stream.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_read_stream_fwd.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_stream.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_stream_fwd.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_write_stream.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_write_stream_fwd.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\completion_condition.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\datagram_socket_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\deadline_timer.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\deadline_timer_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\error.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\error_code.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\handler_alloc_hook.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\handler_invoke_hook.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\io_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\is_read_buffered.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\is_write_buffered.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\placeholders.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\read.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\read_until.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\socket_acceptor_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\socket_base.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ssl.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\strand.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\stream_socket_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\streambuf.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\system_error.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\thread.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\time_traits.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\version.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\write.hpp"> + </File> + <Filter + Name="detail" + Filter=""> + <File + RelativePath="..\contrib\asio\asio\detail\bind_handler.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\buffer_resize_guard.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\buffered_stream_storage.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\call_stack.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\const_buffers_iterator.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\consuming_buffers.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\deadline_timer_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\epoll_reactor.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\epoll_reactor_fwd.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\event.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\fd_set_adapter.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\handler_alloc_helpers.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\handler_invoke_helpers.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\hash_map.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\io_control.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\kqueue_reactor.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\kqueue_reactor_fwd.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\local_free_on_block_exit.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\mutex.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\noncopyable.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_event.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_mutex.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_signal_blocker.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_thread.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_tss_ptr.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\old_win_sdk_compat.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\pipe_select_interrupter.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\pop_options.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_event.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_fd_set_adapter.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_mutex.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_signal_blocker.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_thread.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_tss_ptr.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\push_options.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\reactive_socket_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\reactor_op_queue.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\resolver_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\scoped_lock.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\select_interrupter.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\select_reactor.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\select_reactor_fwd.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\service_base.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\service_id.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\service_registry.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\service_registry_fwd.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\signal_blocker.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\signal_init.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_holder.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_ops.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_option.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_select_interrupter.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_types.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\strand_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\task_io_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\task_io_service_fwd.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\thread.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\throw_error.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\timer_queue.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\timer_queue_base.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\tss_ptr.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_event.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_fd_set_adapter.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_iocp_io_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_iocp_io_service_fwd.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_iocp_operation.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_iocp_socket_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_mutex.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_signal_blocker.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_thread.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_tss_ptr.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\winsock_init.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\detail\wrapped_handler.hpp"> + </File> + </Filter> + <Filter + Name="ip" + Filter=""> + <File + RelativePath="..\contrib\asio\asio\ip\address.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\address_v4.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\address_v6.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_endpoint.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_resolver.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_resolver_entry.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_resolver_iterator.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_resolver_query.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\host_name.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\multicast.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\resolver_query_base.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\resolver_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\tcp.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\udp.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\unicast.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ip\v6_only.hpp"> + </File> + <Filter + Name="detail" + Filter=""> + <File + RelativePath="..\contrib\asio\asio\ip\detail\socket_option.hpp"> + </File> + </Filter> + </Filter> + <Filter + Name="ssl" + Filter=""> + <File + RelativePath="..\contrib\asio\asio\ssl\basic_context.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\context.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\context_base.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\context_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\stream.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\stream_base.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\stream_service.hpp"> + </File> + <Filter + Name="detail" + Filter=""> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_context_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_init.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_operation.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_stream_service.hpp"> + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_types.hpp"> + </File> + </Filter> + </Filter> + </Filter> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/reTurnServer_8_0.vcproj b/src/libs/resiprocate/reTurn/reTurnServer_8_0.vcproj new file mode 100644 index 00000000..f5a18ad7 --- /dev/null +++ b/src/libs/resiprocate/reTurn/reTurnServer_8_0.vcproj @@ -0,0 +1,1019 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="reTurnServer" + ProjectGUID="{EFA91988-1A0C-4739-9FF1-7471E933515C}" + RootNamespace="reTurnServer" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../contrib/asio;../contrib/boost_1_34_1;../contrib/OpenSSL/include;../contrib/OpenSSL/inc32;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;LEAK_CHECK" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\contrib\openssl\out32.dbg\ssleay32.lib&quot;" + OutputFile="$(OutDir)/reTurnServer.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/reTurnServer.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../contrib/asio;../contrib/boost_1_34_1;../contrib/OpenSSL/include;../contrib/OpenSSL/inc32;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\contrib\openssl\out32\ssleay32.lib&quot;" + OutputFile="$(OutDir)/reTurnServer.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\AsyncSocketBase.cxx" + > + </File> + <File + RelativePath=".\AsyncTcpSocketBase.cxx" + > + </File> + <File + RelativePath=".\AsyncTlsSocketBase.cxx" + > + </File> + <File + RelativePath=".\AsyncUdpSocketBase.cxx" + > + </File> + <File + RelativePath=".\ChannelManager.cxx" + > + </File> + <File + RelativePath=".\ConnectionManager.cxx" + > + </File> + <File + RelativePath=".\DataBuffer.cxx" + > + </File> + <File + RelativePath=".\RemotePeer.cxx" + > + </File> + <File + RelativePath=".\RequestHandler.cxx" + > + </File> + <File + RelativePath=".\ReTurnConfig.cxx" + > + </File> + <File + RelativePath=".\reTurnServer.cxx" + > + </File> + <File + RelativePath=".\ReTurnSubsystem.cxx" + > + </File> + <File + RelativePath=".\StunAuth.cxx" + > + </File> + <File + RelativePath=".\StunMessage.cxx" + > + </File> + <File + RelativePath=".\StunTuple.cxx" + > + </File> + <File + RelativePath=".\TcpConnection.cxx" + > + </File> + <File + RelativePath=".\TcpServer.cxx" + > + </File> + <File + RelativePath=".\TlsConnection.cxx" + > + </File> + <File + RelativePath=".\TlsServer.cxx" + > + </File> + <File + RelativePath=".\TurnAllocation.cxx" + > + </File> + <File + RelativePath=".\TurnAllocationKey.cxx" + > + </File> + <File + RelativePath=".\TurnManager.cxx" + > + </File> + <File + RelativePath=".\TurnPermission.cxx" + > + </File> + <File + RelativePath=".\UdpRelayServer.cxx" + > + </File> + <File + RelativePath=".\UdpServer.cxx" + > + </File> + <File + RelativePath=".\UserAuthData.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\AsyncSocketBase.hxx" + > + </File> + <File + RelativePath=".\AsyncSocketBaseHandler.hxx" + > + </File> + <File + RelativePath=".\AsyncTcpSocketBase.hxx" + > + </File> + <File + RelativePath=".\AsyncTlsSocketBase.hxx" + > + </File> + <File + RelativePath=".\AsyncUdpSocketBase.hxx" + > + </File> + <File + RelativePath=".\ChannelManager.hxx" + > + </File> + <File + RelativePath=".\ConnectionManager.hxx" + > + </File> + <File + RelativePath=".\DataBuffer.hxx" + > + </File> + <File + RelativePath=".\RemotePeer.hxx" + > + </File> + <File + RelativePath=".\RequestHandler.hxx" + > + </File> + <File + RelativePath=".\ReTurnConfig.hxx" + > + </File> + <File + RelativePath=".\ReTurnSubsystem.hxx" + > + </File> + <File + RelativePath=".\StunAuth.hxx" + > + </File> + <File + RelativePath=".\StunMessage.hxx" + > + </File> + <File + RelativePath=".\StunTuple.hxx" + > + </File> + <File + RelativePath=".\TcpConnection.hxx" + > + </File> + <File + RelativePath=".\TcpServer.hxx" + > + </File> + <File + RelativePath=".\TlsConnection.hxx" + > + </File> + <File + RelativePath=".\TlsServer.hxx" + > + </File> + <File + RelativePath=".\TurnAllocation.hxx" + > + </File> + <File + RelativePath=".\TurnAllocationKey.hxx" + > + </File> + <File + RelativePath=".\TurnManager.hxx" + > + </File> + <File + RelativePath=".\TurnPermission.hxx" + > + </File> + <File + RelativePath=".\UdpRelayServer.hxx" + > + </File> + <File + RelativePath=".\UdpServer.hxx" + > + </File> + <File + RelativePath=".\UserAuthData.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <Filter + Name="ASIO Header Files" + > + <File + RelativePath="..\contrib\asio\asio.hpp" + > + </File> + <Filter + Name="asio" + > + <File + RelativePath="..\contrib\asio\asio\basic_datagram_socket.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_deadline_timer.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_io_object.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_socket.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_socket_acceptor.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_socket_iostream.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_socket_streambuf.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_stream_socket.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_streambuf.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffer.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_read_stream.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_read_stream_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_stream.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_stream_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_write_stream.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_write_stream_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\completion_condition.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\datagram_socket_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\deadline_timer.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\deadline_timer_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\error.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\error_code.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\handler_alloc_hook.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\handler_invoke_hook.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\io_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\is_read_buffered.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\is_write_buffered.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\placeholders.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\read.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\read_until.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\socket_acceptor_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\socket_base.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\strand.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\stream_socket_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\streambuf.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\system_error.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\thread.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\time_traits.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\version.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\write.hpp" + > + </File> + <Filter + Name="detail" + > + <File + RelativePath="..\contrib\asio\asio\detail\bind_handler.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\buffer_resize_guard.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\buffered_stream_storage.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\call_stack.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\const_buffers_iterator.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\consuming_buffers.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\deadline_timer_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\epoll_reactor.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\epoll_reactor_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\event.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\fd_set_adapter.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\handler_alloc_helpers.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\handler_invoke_helpers.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\hash_map.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\io_control.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\kqueue_reactor.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\kqueue_reactor_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\local_free_on_block_exit.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\mutex.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\noncopyable.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_event.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_mutex.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_signal_blocker.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_thread.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_tss_ptr.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\old_win_sdk_compat.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\pipe_select_interrupter.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\pop_options.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_event.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_fd_set_adapter.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_mutex.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_signal_blocker.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_thread.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_tss_ptr.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\push_options.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\reactive_socket_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\reactor_op_queue.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\resolver_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\scoped_lock.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\select_interrupter.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\select_reactor.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\select_reactor_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\service_base.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\service_id.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\service_registry.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\service_registry_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\signal_blocker.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\signal_init.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_holder.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_ops.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_option.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_select_interrupter.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_types.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\strand_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\task_io_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\task_io_service_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\thread.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\throw_error.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\timer_queue.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\timer_queue_base.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\tss_ptr.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_event.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_fd_set_adapter.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_iocp_io_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_iocp_io_service_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_iocp_operation.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_iocp_socket_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_mutex.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_signal_blocker.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_thread.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_tss_ptr.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\winsock_init.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\wrapped_handler.hpp" + > + </File> + </Filter> + <Filter + Name="ip" + > + <File + RelativePath="..\contrib\asio\asio\ip\address.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\address_v4.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\address_v6.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_endpoint.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_resolver.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_resolver_entry.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_resolver_iterator.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_resolver_query.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\host_name.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\multicast.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\resolver_query_base.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\resolver_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\tcp.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\udp.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\unicast.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\v6_only.hpp" + > + </File> + <Filter + Name="detail" + > + <File + RelativePath="..\contrib\asio\asio\ip\detail\socket_option.hpp" + > + </File> + </Filter> + </Filter> + <Filter + Name="ssl" + > + <File + RelativePath="..\contrib\asio\asio\ssl\basic_context.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\context.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\context_base.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\context_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\stream.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\stream_base.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\stream_service.hpp" + > + </File> + <Filter + Name="detail" + > + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_context_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_init.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_operation.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_stream_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_types.hpp" + > + </File> + </Filter> + </Filter> + </Filter> + </Filter> + <File + RelativePath=".\README.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/reTurnServer_9_0.vcproj b/src/libs/resiprocate/reTurn/reTurnServer_9_0.vcproj new file mode 100644 index 00000000..eecbfc65 --- /dev/null +++ b/src/libs/resiprocate/reTurn/reTurnServer_9_0.vcproj @@ -0,0 +1,1018 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="reTurnServer" + ProjectGUID="{EFA91988-1A0C-4739-9FF1-7471E933515C}" + RootNamespace="reTurnServer" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../contrib/asio;../contrib/boost_1_34_1;../contrib/OpenSSL/include;../contrib/OpenSSL/inc32;../" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;LEAK_CHECK" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\contrib\openssl\out32.dbg\ssleay32.lib&quot;" + OutputFile="$(OutDir)/reTurnServer.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/reTurnServer.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../contrib/asio;../contrib/boost_1_34_1;../contrib/OpenSSL/include;../contrib/OpenSSL/inc32;../" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\contrib\openssl\out32\ssleay32.lib&quot;" + OutputFile="$(OutDir)/reTurnServer.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\AsyncSocketBase.cxx" + > + </File> + <File + RelativePath=".\AsyncTcpSocketBase.cxx" + > + </File> + <File + RelativePath=".\AsyncTlsSocketBase.cxx" + > + </File> + <File + RelativePath=".\AsyncUdpSocketBase.cxx" + > + </File> + <File + RelativePath=".\ChannelManager.cxx" + > + </File> + <File + RelativePath=".\ConnectionManager.cxx" + > + </File> + <File + RelativePath=".\DataBuffer.cxx" + > + </File> + <File + RelativePath=".\RemotePeer.cxx" + > + </File> + <File + RelativePath=".\RequestHandler.cxx" + > + </File> + <File + RelativePath=".\ReTurnConfig.cxx" + > + </File> + <File + RelativePath=".\reTurnServer.cxx" + > + </File> + <File + RelativePath=".\ReTurnSubsystem.cxx" + > + </File> + <File + RelativePath=".\StunAuth.cxx" + > + </File> + <File + RelativePath=".\StunMessage.cxx" + > + </File> + <File + RelativePath=".\StunTuple.cxx" + > + </File> + <File + RelativePath=".\TcpConnection.cxx" + > + </File> + <File + RelativePath=".\TcpServer.cxx" + > + </File> + <File + RelativePath=".\TlsConnection.cxx" + > + </File> + <File + RelativePath=".\TlsServer.cxx" + > + </File> + <File + RelativePath=".\TurnAllocation.cxx" + > + </File> + <File + RelativePath=".\TurnAllocationKey.cxx" + > + </File> + <File + RelativePath=".\TurnManager.cxx" + > + </File> + <File + RelativePath=".\TurnPermission.cxx" + > + </File> + <File + RelativePath=".\UdpRelayServer.cxx" + > + </File> + <File + RelativePath=".\UdpServer.cxx" + > + </File> + <File + RelativePath=".\UserAuthData.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\AsyncSocketBase.hxx" + > + </File> + <File + RelativePath=".\AsyncSocketBaseHandler.hxx" + > + </File> + <File + RelativePath=".\AsyncTcpSocketBase.hxx" + > + </File> + <File + RelativePath=".\AsyncTlsSocketBase.hxx" + > + </File> + <File + RelativePath=".\AsyncUdpSocketBase.hxx" + > + </File> + <File + RelativePath=".\ChannelManager.hxx" + > + </File> + <File + RelativePath=".\ConnectionManager.hxx" + > + </File> + <File + RelativePath=".\DataBuffer.hxx" + > + </File> + <File + RelativePath=".\RemotePeer.hxx" + > + </File> + <File + RelativePath=".\RequestHandler.hxx" + > + </File> + <File + RelativePath=".\ReTurnConfig.hxx" + > + </File> + <File + RelativePath=".\ReTurnSubsystem.hxx" + > + </File> + <File + RelativePath=".\StunAuth.hxx" + > + </File> + <File + RelativePath=".\StunMessage.hxx" + > + </File> + <File + RelativePath=".\StunTuple.hxx" + > + </File> + <File + RelativePath=".\TcpConnection.hxx" + > + </File> + <File + RelativePath=".\TcpServer.hxx" + > + </File> + <File + RelativePath=".\TlsConnection.hxx" + > + </File> + <File + RelativePath=".\TlsServer.hxx" + > + </File> + <File + RelativePath=".\TurnAllocation.hxx" + > + </File> + <File + RelativePath=".\TurnAllocationKey.hxx" + > + </File> + <File + RelativePath=".\TurnManager.hxx" + > + </File> + <File + RelativePath=".\TurnPermission.hxx" + > + </File> + <File + RelativePath=".\UdpRelayServer.hxx" + > + </File> + <File + RelativePath=".\UdpServer.hxx" + > + </File> + <File + RelativePath=".\UserAuthData.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <Filter + Name="ASIO Header Files" + > + <File + RelativePath="..\contrib\asio\asio.hpp" + > + </File> + <Filter + Name="asio" + > + <File + RelativePath="..\contrib\asio\asio\basic_datagram_socket.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_deadline_timer.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_io_object.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_socket.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_socket_acceptor.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_socket_iostream.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_socket_streambuf.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_stream_socket.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\basic_streambuf.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffer.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_read_stream.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_read_stream_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_stream.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_stream_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_write_stream.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\buffered_write_stream_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\completion_condition.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\datagram_socket_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\deadline_timer.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\deadline_timer_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\error.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\error_code.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\handler_alloc_hook.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\handler_invoke_hook.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\io_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\is_read_buffered.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\is_write_buffered.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\placeholders.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\read.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\read_until.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\socket_acceptor_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\socket_base.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\strand.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\stream_socket_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\streambuf.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\system_error.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\thread.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\time_traits.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\version.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\write.hpp" + > + </File> + <Filter + Name="detail" + > + <File + RelativePath="..\contrib\asio\asio\detail\bind_handler.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\buffer_resize_guard.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\buffered_stream_storage.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\call_stack.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\const_buffers_iterator.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\consuming_buffers.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\deadline_timer_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\epoll_reactor.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\epoll_reactor_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\event.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\fd_set_adapter.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\handler_alloc_helpers.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\handler_invoke_helpers.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\hash_map.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\io_control.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\kqueue_reactor.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\kqueue_reactor_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\local_free_on_block_exit.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\mutex.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\noncopyable.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_event.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_mutex.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_signal_blocker.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_thread.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\null_tss_ptr.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\old_win_sdk_compat.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\pipe_select_interrupter.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\pop_options.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_event.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_fd_set_adapter.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_mutex.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_signal_blocker.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_thread.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\posix_tss_ptr.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\push_options.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\reactive_socket_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\reactor_op_queue.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\resolver_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\scoped_lock.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\select_interrupter.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\select_reactor.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\select_reactor_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\service_base.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\service_id.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\service_registry.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\service_registry_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\signal_blocker.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\signal_init.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_holder.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_ops.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_option.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_select_interrupter.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\socket_types.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\strand_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\task_io_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\task_io_service_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\thread.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\throw_error.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\timer_queue.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\timer_queue_base.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\tss_ptr.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_event.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_fd_set_adapter.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_iocp_io_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_iocp_io_service_fwd.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_iocp_operation.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_iocp_socket_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_mutex.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_signal_blocker.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_thread.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\win_tss_ptr.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\winsock_init.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\detail\wrapped_handler.hpp" + > + </File> + </Filter> + <Filter + Name="ip" + > + <File + RelativePath="..\contrib\asio\asio\ip\address.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\address_v4.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\address_v6.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_endpoint.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_resolver.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_resolver_entry.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_resolver_iterator.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\basic_resolver_query.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\host_name.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\multicast.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\resolver_query_base.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\resolver_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\tcp.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\udp.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\unicast.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ip\v6_only.hpp" + > + </File> + <Filter + Name="detail" + > + <File + RelativePath="..\contrib\asio\asio\ip\detail\socket_option.hpp" + > + </File> + </Filter> + </Filter> + <Filter + Name="ssl" + > + <File + RelativePath="..\contrib\asio\asio\ssl\basic_context.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\context.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\context_base.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\context_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\stream.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\stream_base.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\stream_service.hpp" + > + </File> + <Filter + Name="detail" + > + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_context_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_init.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_operation.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_stream_service.hpp" + > + </File> + <File + RelativePath="..\contrib\asio\asio\ssl\detail\openssl_types.hpp" + > + </File> + </Filter> + </Filter> + </Filter> + </Filter> + <File + RelativePath=".\README.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/reTurn_10_0.sln b/src/libs/resiprocate/reTurn/reTurn_10_0.sln new file mode 100644 index 00000000..52268660 --- /dev/null +++ b/src/libs/resiprocate/reTurn/reTurn_10_0.sln @@ -0,0 +1,84 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\rutil\rutil_10_0.vcxproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnServer", "reTurnServer_10_0.vcxproj", "{EFA91988-1A0C-4739-9FF1-7471E933515C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnClient", "client\reTurnClient_10_0.vcxproj", "{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\rutil\dns\ares\ares_10_0.vcxproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestClient", "client\test\TestClient_10_0.vcxproj", "{73151749-13F0-4093-97F1-A6952ECECDBF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestAsyncClient", "client\test\TestAsyncClient_10_0.vcxproj", "{73151749-13F0-4093-97F1-A6952ECECDCF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stunTestVectors", "test\stunTestVectors_10_0.vcxproj", "{73151749-13F0-4093-97F1-B6952ECECDCF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + SSL-Debug|Win32 = SSL-Debug|Win32 + SSL-Release|Win32 = SSL-Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Debug|Win32.ActiveCfg = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Debug|Win32.Build.0 = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Release|Win32.ActiveCfg = Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Release|Win32.Build.0 = Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.SSL-Release|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Release|Win32.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.SSL-Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.SSL-Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.SSL-Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/reTurn/reTurn_7_1.sln b/src/libs/resiprocate/reTurn/reTurn_7_1.sln new file mode 100644 index 00000000..e850003e --- /dev/null +++ b/src/libs/resiprocate/reTurn/reTurn_7_1.sln @@ -0,0 +1,70 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\rutil\rutil_7_1.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnServer", "reTurnServer_7_1.vcproj", "{EFA91988-1A0C-4739-9FF1-7471E933515C}" + ProjectSection(ProjectDependencies) = postProject + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnClient", "client\reTurnClient_7_1.vcproj", "{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\contrib\ares\ares_7_1.vcproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestClient", "client\test\TestClient_7_1.vcproj", "{73151749-13F0-4093-97F1-A6952ECECDBF}" + ProjectSection(ProjectDependencies) = postProject + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestAsyncClient", "client\test\TestAsyncClient_7_1.vcproj", "{73151749-13F0-4093-97F1-A6952ECECDCF}" + ProjectSection(ProjectDependencies) = postProject + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release.ActiveCfg = SSL-Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Debug.ActiveCfg = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Debug.Build.0 = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Release.ActiveCfg = Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Release.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Debug.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Debug.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Release.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Release.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Debug.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Debug.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Release.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/reTurn/reTurn_8_0.sln b/src/libs/resiprocate/reTurn/reTurn_8_0.sln new file mode 100644 index 00000000..6db52e97 --- /dev/null +++ b/src/libs/resiprocate/reTurn/reTurn_8_0.sln @@ -0,0 +1,101 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\rutil\rutil_8_0.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnServer", "reTurnServer_8_0.vcproj", "{EFA91988-1A0C-4739-9FF1-7471E933515C}" + ProjectSection(ProjectDependencies) = postProject + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnClient", "client\reTurnClient_8_0.vcproj", "{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\rutil\dns\ares\ares_8_0.vcproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestClient", "client\test\TestClient_8_0.vcproj", "{73151749-13F0-4093-97F1-A6952ECECDBF}" + ProjectSection(ProjectDependencies) = postProject + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestAsyncClient", "client\test\TestAsyncClient_8_0.vcproj", "{73151749-13F0-4093-97F1-A6952ECECDCF}" + ProjectSection(ProjectDependencies) = postProject + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stunTestVectors", "test\stunTestVectors_8_0.vcproj", "{73151749-13F0-4093-97F1-B6952ECECDCF}" + ProjectSection(ProjectDependencies) = postProject + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + SSL-Debug|Win32 = SSL-Debug|Win32 + SSL-Release|Win32 = SSL-Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Debug|Win32.ActiveCfg = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Debug|Win32.Build.0 = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Release|Win32.ActiveCfg = Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Release|Win32.Build.0 = Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.SSL-Release|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Release|Win32.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.SSL-Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.SSL-Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.SSL-Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/reTurn/reTurn_9_0.sln b/src/libs/resiprocate/reTurn/reTurn_9_0.sln new file mode 100644 index 00000000..c7626c6e --- /dev/null +++ b/src/libs/resiprocate/reTurn/reTurn_9_0.sln @@ -0,0 +1,101 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\rutil\rutil_9_0.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnServer", "reTurnServer_9_0.vcproj", "{EFA91988-1A0C-4739-9FF1-7471E933515C}" + ProjectSection(ProjectDependencies) = postProject + {96CD935E-1951-43B8-AF75-F1C06B3778C1} = {96CD935E-1951-43B8-AF75-F1C06B3778C1} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnClient", "client\reTurnClient_9_0.vcproj", "{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\rutil\dns\ares\ares_9_0.vcproj", "{96CD935E-1951-43B8-AF75-F1C06B3778C1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestClient", "client\test\TestClient_9_0.vcproj", "{73151749-13F0-4093-97F1-A6952ECECDBF}" + ProjectSection(ProjectDependencies) = postProject + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {96CD935E-1951-43B8-AF75-F1C06B3778C1} = {96CD935E-1951-43B8-AF75-F1C06B3778C1} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestAsyncClient", "client\test\TestAsyncClient_9_0.vcproj", "{73151749-13F0-4093-97F1-A6952ECECDCF}" + ProjectSection(ProjectDependencies) = postProject + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + {96CD935E-1951-43B8-AF75-F1C06B3778C1} = {96CD935E-1951-43B8-AF75-F1C06B3778C1} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stunTestVectors", "test\stunTestVectors_9_0.vcproj", "{73151749-13F0-4093-97F1-B6952ECECDCF}" + ProjectSection(ProjectDependencies) = postProject + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + SSL-Debug|Win32 = SSL-Debug|Win32 + SSL-Release|Win32 = SSL-Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Debug|Win32.ActiveCfg = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Debug|Win32.Build.0 = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Release|Win32.ActiveCfg = Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.Release|Win32.Build.0 = Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {EFA91988-1A0C-4739-9FF1-7471E933515C}.SSL-Release|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Release|Win32.Build.0 = Release|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.Debug|Win32.ActiveCfg = Debug|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.Debug|Win32.Build.0 = Debug|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.Release|Win32.ActiveCfg = Release|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.Release|Win32.Build.0 = Release|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.SSL-Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDBF}.SSL-Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-A6952ECECDCF}.SSL-Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.Release|Win32.Build.0 = Release|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {73151749-13F0-4093-97F1-B6952ECECDCF}.SSL-Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/reTurn/server.pem b/src/libs/resiprocate/reTurn/server.pem new file mode 100644 index 00000000..70348275 --- /dev/null +++ b/src/libs/resiprocate/reTurn/server.pem @@ -0,0 +1,43 @@ +-----BEGIN CERTIFICATE----- +MIICaTCCAdKgAwIBAgIIAQICRgIIAU0wDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCFNhbiBKb3NlMQ4w +DAYDVQQKEwVzaXBpdDEpMCcGA1UECxMgU2lwaXQgVGVzdCBDZXJ0aWZpY2F0ZSBB +dXRob3JpdHkwHhcNMDkwMTI4MTcwNzE0WhcNMTAwMTI4MTcwNzE0WjBhMQswCQYD +VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMITWlscGl0YXMx +DzANBgNVBAoTBnNpcGltcDEZMBcGA1UEAxMQcmV0dXJuc2VydmVyLmNvbTBcMA0G +CSqGSIb3DQEBAQUAA0sAMEgCQQDbTlRGots8cBt8Lks7kIzkbDhKs3XjB/KXf+yr +UBfVZDC0EugYE3Se/oO2fpdjLIemxdJoDJlsEy4eJWU81XhNAgMBAAGjXzBdMDEG +A1UdEQQqMCiCEHJldHVybnNlcnZlci5jb22GFHNpcDpyZXR1cm5zZXJ2ZXIuY29t +MAkGA1UdEwQCMAAwHQYDVR0OBBYEFEXE30liIiWvi/lVSxPXnIxu0j9xMA0GCSqG +SIb3DQEBBQUAA4GBACIHsj0qXsgEfM6mH9IsCxCn/AgnT4HqAI3kdfax8S1mxeyY +ITyP+lj1iEE9qm1MhYLrico7Bi7ST5PmDgnVVenZBsKw5j9LomgbqPwotDQIugQj +GB14D6RLxIeTIDRWsFjOvoHDd/ghakPk0oI16hU3ndCEYrKrvUhQOkjk/Bwp +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIBPAIBAAJBANtOVEai2zxwG3wuSzuQjORsOEqzdeMH8pd/7KtQF9VkMLQS6BgT +dJ7+g7Z+l2Msh6bF0mgMmWwTLh4lZTzVeE0CAwEAAQJAcHScFpSQI0/BaE482dBn +zwIHY5bezopWxYUdkUNC1XLVV/j+I0y6Q0aWnEVtX2AiZPa/plvdoq0N1V9fZ8xy +gQIhAP0A6lkFLYnglmkpzHULyEZ6davVYxFkJYEPVkjslx/9AiEA3ec+4LuzEIrv +YSTONzUtPcw3AfQwA5nY+4RLiC+r4pECIQCLG6++low9XREWbXcPfBT4O2jru/4m +l8vPNGGa4wsM+QIhALUYnRMxfBC7ImNoczdRGav+dsIMdAbsTs3tiOsK5L9RAiEA +zBQgWPOjuVz6SuXp6Gam0FORatslK2xcGFZk8QZj5g0= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDJDCCAo2gAwIBAgIBADANBgkqhkiG9w0BAQUFADBwMQswCQYDVQQGEwJVUzET +MBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2UxDjAMBgNVBAoT +BXNpcGl0MSkwJwYDVQQLEyBTaXBpdCBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0 +eTAeFw0wMzA3MTgxMjIxNTJaFw0xMzA3MTUxMjIxNTJaMHAxCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9zZTEOMAwGA1UE +ChMFc2lwaXQxKTAnBgNVBAsTIFNpcGl0IFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9y +aXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDIh6DkcUDLDyK9BEUxkud ++nJ4xrCVGKfgjHm6XaSuHiEtnfELHM+9WymzkBNzZpJu30yzsxwfKoIKugdNUrD4 +N3viCicwcN35LgP/KnbN34cavXHr4ZlqxH+OdKB3hQTpQa38A7YXdaoz6goW2ft5 +Mi74z03GNKP/G9BoKOGd5QIDAQABo4HNMIHKMB0GA1UdDgQWBBRrRhcU6pR2JYBU +bhNU2qHjVBShtjCBmgYDVR0jBIGSMIGPgBRrRhcU6pR2JYBUbhNU2qHjVBShtqF0 +pHIwcDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcT +CFNhbiBKb3NlMQ4wDAYDVQQKEwVzaXBpdDEpMCcGA1UECxMgU2lwaXQgVGVzdCBD +ZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B +AQUFAAOBgQCWbRvv1ZGTRXxbH8/EqkdSCzSoUPrs+rQqR0xdQac9wNY/nlZbkR3O +qAezG6Sfmklvf+DOg5RxQq/+Y6I03LRepc7KeVDpaplMFGnpfKsibETMipwzayNQ +QgUf4cKBiF+65Ue7hZuDJa2EMv8qW4twEhGDYclpFU9YozyS1OhvUg== +-----END CERTIFICATE----- diff --git a/src/libs/resiprocate/reTurn/test/Makefile.am b/src/libs/resiprocate/reTurn/test/Makefile.am new file mode 100644 index 00000000..6b445cc5 --- /dev/null +++ b/src/libs/resiprocate/reTurn/test/Makefile.am @@ -0,0 +1,68 @@ +# $Id$ + +EXTRA_DIST = stunTestVectors_10_0.vcxproj stunTestVectors_10_0.vcxproj.filters +EXTRA_DIST += *.vcproj + +#AM_CXXFLAGS = -DUSE_ARES + +LDADD = ../client/libreTurnClient.la +LDADD += ../../rutil/librutil.la +LDADD += $(LIBSSL_LIBADD) -lpthread + +TESTS = \ + stunTestVectors + +check_PROGRAMS = \ + stunTestVectors + +stunTestVectors_SOURCES = stunTestVectors.cxx + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# <http://www.vovida.org/>. +# +############################################################################## diff --git a/src/libs/resiprocate/reTurn/test/stunTestVectors.cxx b/src/libs/resiprocate/reTurn/test/stunTestVectors.cxx new file mode 100644 index 00000000..2fded949 --- /dev/null +++ b/src/libs/resiprocate/reTurn/test/stunTestVectors.cxx @@ -0,0 +1,194 @@ +// This file implements test vectors from: draft-ietf-behave-stun-test-vectors-04 + +#include <iostream> +#include <string> +#include <asio.hpp> + +#include "../StunTuple.hxx" +#include "../StunMessage.hxx" +#include <rutil/Logger.hxx> +#include <rutil/DnsUtil.hxx> + +using namespace reTurn; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST + +int main(int argc, char* argv[]) +{ + StunTuple local(StunTuple::UDP, asio::ip::address::from_string("10.0.0.1"), 5000); + StunTuple remote(StunTuple::UDP, asio::ip::address::from_string("10.0.0.2"), 5001); + + resip::Log::initialize(resip::Log::Cout, resip::Log::Info, ""); + + const unsigned char req[] = + "\x00\x01\x00\x58" + "\x21\x12\xa4\x42" + "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" + "\x80\x22\x00\x10" + "STUN test client" + "\x00\x24\x00\x04" + "\x6e\x00\x01\xff" + "\x80\x29\x00\x08" + "\x93\x2f\xf9\xb1\x51\x26\x3b\x36" + "\x00\x06\x00\x09" + "\x65\x76\x74\x6a\x3a\x68\x36\x76\x59\x20\x20\x20" + "\x00\x08\x00\x14" + "\x9a\xea\xa7\x0c\xbf\xd8\xcb\x56\x78\x1e\xf2\xb5" + "\xb2\xd3\xf2\x49\xc1\xb5\x71\xa2" + "\x80\x28\x00\x04" + "\xe5\x7a\x3b\xcf"; + + StunMessage reqMessage(local, remote, (char*)req, sizeof(req)-1); + + assert(reqMessage.isValid()); + assert(reqMessage.mHasMagicCookie); + assert(reqMessage.mUnknownRequiredAttributes.numAttributes == 1); // Test vector includes comprehension required Priority ICE attribute - we don't support this yet + assert(reqMessage.mHasSoftware); + assert(*reqMessage.mSoftware == "STUN test client"); + assert(reqMessage.mHasUsername); + assert(*reqMessage.mUsername == "evtj:h6vY"); + assert(reqMessage.mHasMessageIntegrity); + assert(reqMessage.checkMessageIntegrity("VOkJxbRl1RmTxUk/WvJxBt")); + assert(reqMessage.mHasFingerprint); + assert(reqMessage.checkFingerprint()); + + const unsigned char respv4[] = + "\x01\x01\x00\x3c" + "\x21\x12\xa4\x42" + "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" + "\x80\x22\x00\x0b" + "\x74\x65\x73\x74\x20\x76\x65\x63\x74\x6f\x72\x20" + "\x00\x20\x00\x08" + "\x00\x01\xa1\x47\xe1\x12\xa6\x43" + "\x00\x08\x00\x14" + "\x2b\x91\xf5\x99\xfd\x9e\x90\xc3\x8c\x74\x89\xf9" + "\x2a\xf9\xba\x53\xf0\x6b\xe7\xd7" + "\x80\x28\x00\x04" + "\xc0\x7d\x4c\x96"; + + StunMessage respv4Message(local, remote, (char*)respv4, sizeof(respv4)-1); + + assert(respv4Message.isValid()); + assert(respv4Message.mHasMagicCookie); + assert(respv4Message.mHasSoftware); + assert(*respv4Message.mSoftware == "test vector"); + assert(respv4Message.mHasXorMappedAddress); + assert(respv4Message.mXorMappedAddress.family == StunMessage::IPv4Family); + assert(respv4Message.mXorMappedAddress.port == 32853); + assert(respv4Message.mXorMappedAddress.addr.ipv4 == asio::ip::address::from_string("192.0.2.1").to_v4().to_ulong()); + assert(respv4Message.mHasMessageIntegrity); + assert(respv4Message.checkMessageIntegrity("VOkJxbRl1RmTxUk/WvJxBt")); + assert(respv4Message.mHasFingerprint); + assert(respv4Message.checkFingerprint()); + + const unsigned char respv6[] = + "\x01\x01\x00\x48" + "\x21\x12\xa4\x42" + "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" + "\x80\x22\x00\x0b" + "\x74\x65\x73\x74\x20\x76\x65\x63\x74\x6f\x72\x20" + "\x00\x20\x00\x14" + "\x00\x02\xa1\x47" + "\x01\x13\xa9\xfa\xa5\xd3\xf1\x79" + "\xbc\x25\xf4\xb5\xbe\xd2\xb9\xd9" + "\x00\x08\x00\x14" + "\xa3\x82\x95\x4e\x4b\xe6\x7b\xf1\x17\x84\xc9\x7c" + "\x82\x92\xc2\x75\xbf\xe3\xed\x41" + "\x80\x28\x00\x04" + "\xc8\xfb\x0b\x4c"; + + StunMessage respv6Message(local, remote, (char*)respv6, sizeof(respv6)-1); + + assert(respv6Message.isValid()); + assert(respv6Message.mHasMagicCookie); + assert(respv6Message.mHasSoftware); + assert(*respv6Message.mSoftware == "test vector"); + assert(respv6Message.mHasXorMappedAddress); + assert(respv6Message.mXorMappedAddress.family == StunMessage::IPv6Family); + assert(respv6Message.mXorMappedAddress.port == 32853); + asio::ip::address_v6::bytes_type v6addr = asio::ip::address::from_string("2001:db8:1234:5678:11:2233:4455:6677").to_v6().to_bytes(); + assert(memcmp(&respv6Message.mXorMappedAddress.addr.ipv6, v6addr.data(), sizeof(respv6Message.mXorMappedAddress.addr.ipv6)) == 0); + assert(respv6Message.mHasMessageIntegrity); + assert(respv6Message.checkMessageIntegrity("VOkJxbRl1RmTxUk/WvJxBt")); + assert(respv6Message.mHasFingerprint); + assert(respv6Message.checkFingerprint()); + + const unsigned char reqltc[] = + "\x00\x01\x00\x60" + "\x21\x12\xa4\x42" + "\x78\xad\x34\x33\xc6\xad\x72\xc0\x29\xda\x41\x2e" + "\x00\x06\x00\x12" + "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83" + "\xe3\x82\xaf\xe3\x82\xb9\x00\x00" + "\x00\x15\x00\x1c" + "\x66\x2f\x2f\x34\x39\x39\x6b\x39\x35\x34\x64\x36" + "\x4f\x4c\x33\x34\x6f\x4c\x39\x46\x53\x54\x76\x79" + "\x36\x34\x73\x41" + "\x00\x14\x00\x0b" + "\x65\x78\x61\x6d\x70\x6c\x65\x2e\x6f\x72\x67\x00" + "\x00\x08\x00\x14" + "\xf6\x70\x24\x65\x6d\xd6\x4a\x3e\x02\xb8\xe0\x71" + "\x2e\x85\xc9\xa2\x8c\xa8\x96\x66"; + + StunMessage reqltcMessage(local, remote, (char*)reqltc, sizeof(reqltc)-1); + + // Username: "<U+30DE><U+30C8><U+30EA><U+30C3><U+30AF><U+30B9>" + // (without quotes) unaffected by SASLprep[RFC4013] processing + char username[] = "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb9"; + + // Password: "The<U+00AD>M<U+00AA>tr<U+2168>" resp "TheMatrIX" (without + // quotes) before resp after SASLprep processing + char password[] = "TheMatrIX"; + + assert(reqltcMessage.isValid()); + assert(reqltcMessage.mHasMagicCookie); + assert(reqltcMessage.mHasUsername); + assert(*reqltcMessage.mUsername == username); + assert(reqltcMessage.mHasRealm); + assert(*reqltcMessage.mRealm == "example.org"); + assert(reqltcMessage.mHasNonce); + assert(*reqltcMessage.mNonce == "f//499k954d6OL34oL9FSTvy64sA"); + assert(reqltcMessage.mHasMessageIntegrity); + resip::Data hmacKey; + reqltcMessage.calculateHmacKey(hmacKey, password); + assert(reqltcMessage.checkMessageIntegrity(hmacKey)); + + InfoLog(<< "All tests passed!"); + return 0; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reTurn/test/stunTestVectors_10_0.vcxproj b/src/libs/resiprocate/reTurn/test/stunTestVectors_10_0.vcxproj new file mode 100644 index 00000000..399bc174 --- /dev/null +++ b/src/libs/resiprocate/reTurn/test/stunTestVectors_10_0.vcxproj @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>stunTestVectors</ProjectName> + <ProjectGuid>{73151749-13F0-4093-97F1-B6952ECECDCF}</ProjectGuid> + <RootNamespace>stunTestVectors</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>../../contrib/asio;../../contrib/boost_1_34_1;../../;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>winmm.lib;$(ProjectDir)..\..\contrib\openssl\out32.dbg\libeay32.lib;$(ProjectDir)..\..\contrib\openssl\out32.dbg\ssleay32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)stunTestVectors.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)stunTestVectors.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>../../contrib/asio;../../contrib/boost_1_34_1;../../;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>winmm.lib;$(ProjectDir)..\..\contrib\openssl\out32\libeay32.lib;$(ProjectDir)..\..\contrib\openssl\out32\ssleay32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)stunTestVectors.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\ReTurnSubsystem.cxx" /> + <ClCompile Include="..\StunMessage.cxx" /> + <ClCompile Include="stunTestVectors.cxx" /> + <ClCompile Include="..\StunTuple.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\ReTurnSubsystem.hxx" /> + <ClInclude Include="..\StunMessage.hxx" /> + <ClInclude Include="..\StunTuple.hxx" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\rutil\rutil_10_0.vcxproj"> + <Project>{3d0e5ceb-93dc-4fdb-918b-d08fa369e106}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/reTurn/test/stunTestVectors_10_0.vcxproj.filters b/src/libs/resiprocate/reTurn/test/stunTestVectors_10_0.vcxproj.filters new file mode 100644 index 00000000..4d0b1ba2 --- /dev/null +++ b/src/libs/resiprocate/reTurn/test/stunTestVectors_10_0.vcxproj.filters @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\ReTurnSubsystem.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\StunMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="stunTestVectors.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\StunTuple.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\ReTurnSubsystem.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\StunMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\StunTuple.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/reTurn/test/stunTestVectors_8_0.vcproj b/src/libs/resiprocate/reTurn/test/stunTestVectors_8_0.vcproj new file mode 100644 index 00000000..577f93b2 --- /dev/null +++ b/src/libs/resiprocate/reTurn/test/stunTestVectors_8_0.vcproj @@ -0,0 +1,229 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="stunTestVectors" + ProjectGUID="{73151749-13F0-4093-97F1-B6952ECECDCF}" + RootNamespace="stunTestVectors" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../contrib/asio;../../contrib/boost_1_34_1;../../;../../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/stunTestVectors.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/stunTestVectors.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../../contrib/asio;../../contrib/boost_1_34_1;../../;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0500;USE_SSL;ASIO_ENABLE_CANCELIO" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\contrib\openssl\out32\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/stunTestVectors.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\ReTurnSubsystem.cxx" + > + </File> + <File + RelativePath="..\StunMessage.cxx" + > + </File> + <File + RelativePath=".\stunTestVectors.cxx" + > + </File> + <File + RelativePath="..\StunTuple.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\ReTurnSubsystem.hxx" + > + </File> + <File + RelativePath="..\StunMessage.hxx" + > + </File> + <File + RelativePath="..\StunTuple.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reTurn/test/stunTestVectors_9_0.vcproj b/src/libs/resiprocate/reTurn/test/stunTestVectors_9_0.vcproj new file mode 100644 index 00000000..e97e3f45 --- /dev/null +++ b/src/libs/resiprocate/reTurn/test/stunTestVectors_9_0.vcproj @@ -0,0 +1,228 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="stunTestVectors" + ProjectGUID="{73151749-13F0-4093-97F1-B6952ECECDCF}" + RootNamespace="stunTestVectors" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../contrib/asio;../../contrib/boost_1_34_1;../../;../../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/stunTestVectors.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/stunTestVectors.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../../contrib/asio;../../contrib/boost_1_34_1;../../;../../contrib/OpenSSL/include;../../contrib/OpenSSL/inc32" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_ALL_NO_LIB;_WIN32_WINNT=0x0501;USE_SSL;ASIO_ENABLE_CANCELIO" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib &quot;$(ProjectDir)..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\contrib\openssl\out32\ssleay32.lib&quot; iphlpapi.lib" + OutputFile="$(OutDir)/stunTestVectors.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\ReTurnSubsystem.cxx" + > + </File> + <File + RelativePath="..\StunMessage.cxx" + > + </File> + <File + RelativePath=".\stunTestVectors.cxx" + > + </File> + <File + RelativePath="..\StunTuple.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\ReTurnSubsystem.hxx" + > + </File> + <File + RelativePath="..\StunMessage.hxx" + > + </File> + <File + RelativePath="..\StunTuple.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reflow/ErrorCode.hxx b/src/libs/resiprocate/reflow/ErrorCode.hxx new file mode 100644 index 00000000..90f36703 --- /dev/null +++ b/src/libs/resiprocate/reflow/ErrorCode.hxx @@ -0,0 +1,57 @@ +#ifndef FM_ERRORCODE_HXX +#define FM_ERRORCODE_HXX + +#include <asio/error_code.hpp> + +namespace flowmanager { + +typedef asio::error_code::value_type ErrorType; + +static const ErrorType Success = 0; +static const ErrorType GeneralError = -1; + +static const ErrorType ErrorBase = 9000; + +static const ErrorType BufferTooSmall = ErrorBase + 1; +static const ErrorType ReceiveTimeout = ErrorBase + 2; +static const ErrorType InvalidState = ErrorBase + 3; +static const ErrorType SRTPError = ErrorBase + 4; +static const ErrorType DtlsPacket = ErrorBase + 5; +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/FakeSelectSocketDescriptor.cxx b/src/libs/resiprocate/reflow/FakeSelectSocketDescriptor.cxx new file mode 100644 index 00000000..20e44adf --- /dev/null +++ b/src/libs/resiprocate/reflow/FakeSelectSocketDescriptor.cxx @@ -0,0 +1,123 @@ +#if defined(WIN32) +#include <winsock2.h> +#include <WS2TCPIP.H> +#else +#include <netinet/in.h> +#endif + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <assert.h> + +#include "FlowManagerSubsystem.hxx" +#include "FakeSelectSocketDescriptor.hxx" + +using namespace flowmanager; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM FlowManagerSubsystem::FLOWMANAGER + +FakeSelectSocketDescriptor::FakeSelectSocketDescriptor() +{ +#ifdef WIN32 + sockaddr socketAddr; + mSocket = ::socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + + sockaddr_in loopback; + memset(&loopback, 0, sizeof(loopback)); + loopback.sin_family = AF_INET; + loopback.sin_port = 0; + loopback.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + unsigned long noBlock = 1; + ioctlsocket( mSocket, FIONBIO , &noBlock ); + ::bind( mSocket, reinterpret_cast<sockaddr*>(&loopback), sizeof(loopback)); + memset(&socketAddr, 0, sizeof(socketAddr)); + int len = sizeof(socketAddr); + int error = getsockname(mSocket, (sockaddr *)&socketAddr, &len); + assert(error == 0); + error= connect(mSocket, &socketAddr, sizeof(socketAddr)); + assert(error == 0); +#else + pipe(mPipe); +#endif +} + +FakeSelectSocketDescriptor::~FakeSelectSocketDescriptor() +{ +#ifdef WIN32 + closesocket(mSocket); +#else + close(mPipe[0]); + close(mPipe[1]); +#endif +} + +unsigned int +FakeSelectSocketDescriptor::getSocketDescriptor() +{ +#ifdef WIN32 + return mSocket; +#else + return mPipe[0]; +#endif +} + +void +FakeSelectSocketDescriptor::send() +{ + static char fakeData[] = "*"; +#ifdef WIN32 + int count = ::send(mSocket, fakeData, 1, 0); + assert(count == 1); +#else + size_t res = ::write(mPipe[1], fakeData, 1); + assert(res == 1); +#endif +} + +void +FakeSelectSocketDescriptor::receive() +{ +#ifdef WIN32 + char rdBuf[1]; + ::recv(mSocket, rdBuf, 1, 0); +#else + char rdBuf[1]; + ::read(mPipe[0], rdBuf, 1); +#endif +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/FakeSelectSocketDescriptor.hxx b/src/libs/resiprocate/reflow/FakeSelectSocketDescriptor.hxx new file mode 100644 index 00000000..08a97dea --- /dev/null +++ b/src/libs/resiprocate/reflow/FakeSelectSocketDescriptor.hxx @@ -0,0 +1,84 @@ +#if !defined(FakeSelectSocketDescriptor_hxx) +#define FakeSelectSocketDescriptor_hxx + +namespace flowmanager +{ + +/** + This class is used to generate a fake socket descriptor + than can be used by applications that implement a select/process + loop. This is required so that STUN messages not related to the + actual data transmission, do not cause a select call to wake up + if using select on the actual socket descriptor. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class FakeSelectSocketDescriptor +{ +public: + FakeSelectSocketDescriptor(); + ~FakeSelectSocketDescriptor(); + + unsigned int getSocketDescriptor(); + + // queues fake data on the descriptor so that it signals + + void send(); + + // dequeue fake data from the descriptor + + void receive(); + + +private: +#ifndef WIN32 + + int mPipe[2]; + +#else + + int mSocket; + +#endif + +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/Flow.cxx b/src/libs/resiprocate/reflow/Flow.cxx new file mode 100644 index 00000000..9dfbecbc --- /dev/null +++ b/src/libs/resiprocate/reflow/Flow.cxx @@ -0,0 +1,907 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <asio.hpp> +#include <boost/function.hpp> +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/Timer.hxx> +#include <rutil/Lock.hxx> + +#include "FlowManagerSubsystem.hxx" +#include "ErrorCode.hxx" +#include "Flow.hxx" +#include "MediaStream.hxx" +#include "FlowDtlsSocketContext.hxx" + +using namespace flowmanager; +using namespace resip; + +#ifdef USE_SSL +using namespace dtls; +#endif + +using namespace std; + +#define MAX_RECEIVE_FIFO_DURATION 10 // seconds +#define MAX_RECEIVE_FIFO_SIZE (100 * MAX_RECEIVE_FIFO_DURATION) // 1000 = 1 message every 10 ms for 10 seconds - appropriate for RTP + +#define RESIPROCATE_SUBSYSTEM FlowManagerSubsystem::FLOWMANAGER + +char* srtp_error_string(err_status_t error) +{ + switch(error) + { + case err_status_ok: + return "nothing to report"; + break; + case err_status_fail: + return "unspecified failure"; + break; + case err_status_bad_param: + return "unsupported parameter"; + break; + case err_status_alloc_fail: + return "couldn't allocate memory"; + break; + case err_status_dealloc_fail: + return "couldn't deallocate properly"; + break; + case err_status_init_fail: + return "couldn't initialize"; + break; + case err_status_terminus: + return "can't process as much data as requested"; + break; + case err_status_auth_fail: + return "authentication failure"; + break; + case err_status_cipher_fail: + return "cipher failure"; + break; + case err_status_replay_fail: + return "replay check failed (bad index)"; + break; + case err_status_replay_old: + return "replay check failed (index too old)"; + break; + case err_status_algo_fail: + return "algorithm failed test routine"; + break; + case err_status_no_such_op: + return "unsupported operation"; + break; + case err_status_no_ctx: + return "no appropriate context found"; + break; + case err_status_cant_check: + return "unable to perform desired validation"; + break; + case err_status_key_expired: + return "can't use key any more"; + break; + case err_status_socket_err: + return "error in use of socket"; + break; + case err_status_signal_err: + return "error in use POSIX signals"; + break; + case err_status_nonce_bad: + return "nonce check failed"; + break; + case err_status_read_fail: + return "couldn't read data"; + break; + case err_status_write_fail: + return "couldn't write data"; + break; + case err_status_parse_err: + return "error pasring data"; + break; + case err_status_encode_err: + return "error encoding data"; + break; + case err_status_semaphore_err: + return "error while using semaphores"; + break; + case err_status_pfkey_err: + return "error while using pfkey"; + break; + default: + return "unrecognized error"; + } +} + +Flow::Flow(asio::io_service& ioService, +#ifdef USE_SSL + asio::ssl::context& sslContext, +#endif + unsigned int componentId, + const StunTuple& localBinding, + MediaStream& mediaStream) + : mIOService(ioService), +#ifdef USE_SSL + mSslContext(sslContext), +#endif + mComponentId(componentId), + mLocalBinding(localBinding), + mMediaStream(mediaStream), + mAllocationProps(StunMessage::PropsNone), + mReservationToken(0), + mFlowState(Unconnected), + mReceivedDataFifo(MAX_RECEIVE_FIFO_DURATION,MAX_RECEIVE_FIFO_SIZE) +{ + InfoLog(<< "Flow: flow created for " << mLocalBinding << " ComponentId=" << mComponentId); + + switch(mLocalBinding.getTransportType()) + { + case StunTuple::UDP: + mTurnSocket.reset(new TurnAsyncUdpSocket(mIOService, this, mLocalBinding.getAddress(), mLocalBinding.getPort())); + break; + case StunTuple::TCP: + mTurnSocket.reset(new TurnAsyncTcpSocket(mIOService, this, mLocalBinding.getAddress(), mLocalBinding.getPort())); + break; +#ifdef USE_SSL + case StunTuple::TLS: + mTurnSocket.reset(new TurnAsyncTlsSocket(mIOService, + mSslContext, + false, // validateServerCertificateHostname - TODO - make this configurable + this, + mLocalBinding.getAddress(), + mLocalBinding.getPort())); +#endif + break; + default: + // Bad Transport type! + assert(false); + } + + if(mTurnSocket.get() && + mMediaStream.mNatTraversalMode != MediaStream::NoNatTraversal && + !mMediaStream.mStunUsername.empty() && + !mMediaStream.mStunPassword.empty()) + { + mTurnSocket->setUsernameAndPassword(mMediaStream.mStunUsername.c_str(), mMediaStream.mStunPassword.c_str(), false); + } +} + +Flow::~Flow() +{ + InfoLog(<< "Flow: flow destroyed for " << mLocalBinding << " ComponentId=" << mComponentId); + + +#ifdef USE_SSL + // Cleanup DtlsSockets + { + Lock lock(mMutex); + std::map<reTurn::StunTuple, dtls::DtlsSocket*>::iterator it; + for(it = mDtlsSockets.begin(); it != mDtlsSockets.end(); it++) + { + delete it->second; + } + } + #endif //USE_SSL + + // Cleanup TurnSocket + if(mTurnSocket.get()) + { + mTurnSocket->disableTurnAsyncHandler(); + mTurnSocket->close(); + } +} + +void +Flow::activateFlow(UInt64 reservationToken) +{ + mReservationToken = reservationToken; + activateFlow(StunMessage::PropsNone); +} + +void +Flow::activateFlow(UInt8 allocationProps) +{ + mAllocationProps = allocationProps; + + if(mTurnSocket.get()) + { + if(mMediaStream.mNatTraversalMode != MediaStream::NoNatTraversal && + !mMediaStream.mNatTraversalServerHostname.empty()) + { + changeFlowState(ConnectingServer); + mTurnSocket->connect(mMediaStream.mNatTraversalServerHostname.c_str(), + mMediaStream.mNatTraversalServerPort); + } + else + { + changeFlowState(Ready); + mMediaStream.onFlowReady(mComponentId); + } + } +} + +unsigned int +Flow::getSelectSocketDescriptor() +{ + return mFakeSelectSocketDescriptor.getSocketDescriptor(); +} + +unsigned int +Flow::getSocketDescriptor() +{ + if(mTurnSocket.get() != 0) + { + return mTurnSocket->getSocketDescriptor(); + } + else + { + return 0; + } +} + +// Turn Send Methods +void +Flow::send(char* buffer, unsigned int size) +{ + assert(mTurnSocket.get()); + if(isReady()) + { + if(processSendData(buffer, size, mTurnSocket->getConnectedAddress(), mTurnSocket->getConnectedPort())) + { + mTurnSocket->send(buffer, size); + } + } + else + { + onSendFailure(mTurnSocket->getSocketDescriptor(), asio::error_code(flowmanager::InvalidState, asio::error::misc_category)); + } +} + +void +Flow::sendTo(const asio::ip::address& address, unsigned short port, char* buffer, unsigned int size) +{ + assert(mTurnSocket.get()); + if(isReady()) + { + if(processSendData(buffer, size, address, port)) + { + mTurnSocket->sendTo(address, port, buffer, size); + } + } + else + { + onSendFailure(mTurnSocket->getSocketDescriptor(), asio::error_code(flowmanager::InvalidState, asio::error::misc_category)); + } +} + +// Note: this fn is used to send raw data to the far end, without attempting to SRTP encrypt it - ie. used for sending DTLS traffic +void +Flow::rawSendTo(const asio::ip::address& address, unsigned short port, const char* buffer, unsigned int size) +{ + assert(mTurnSocket.get()); + mTurnSocket->sendTo(address, port, buffer, size); +} + + +bool +Flow::processSendData(char* buffer, unsigned int& size, const asio::ip::address& address, unsigned short port) +{ + if(mMediaStream.mSRTPSessionOutCreated) + { + err_status_t status = mMediaStream.srtpProtect((void*)buffer, (int*)&size, mComponentId == RTCP_COMPONENT_ID); + if(status != err_status_ok) + { + ErrLog(<< "Unable to SRTP protect the packet, error code=" << status << "(" << srtp_error_string(status) << ") ComponentId=" << mComponentId); + onSendFailure(mTurnSocket->getSocketDescriptor(), asio::error_code(flowmanager::SRTPError, asio::error::misc_category)); + return false; + } + } +#ifdef USE_SSL + else + { + Lock lock(mMutex); + DtlsSocket* dtlsSocket = getDtlsSocket(StunTuple(mLocalBinding.getTransportType(), address, port)); + if(dtlsSocket) + { + if(((FlowDtlsSocketContext*)dtlsSocket->getSocketContext())->isSrtpInitialized()) + { + err_status_t status = ((FlowDtlsSocketContext*)dtlsSocket->getSocketContext())->srtpProtect((void*)buffer, (int*)&size, mComponentId == RTCP_COMPONENT_ID); + if(status != err_status_ok) + { + ErrLog(<< "Unable to SRTP protect the packet, error code=" << status << "(" << srtp_error_string(status) << ") ComponentId=" << mComponentId); + onSendFailure(mTurnSocket->getSocketDescriptor(), asio::error_code(flowmanager::SRTPError, asio::error::misc_category)); + return false; + } + } + else + { + //WarningLog(<< "Unable to send packet yet - handshake is not completed yet, ComponentId=" << mComponentId); + onSendFailure(mTurnSocket->getSocketDescriptor(), asio::error_code(flowmanager::InvalidState, asio::error::misc_category)); + return false; + } + } + } +#endif //USE_SSL + + return true; +} + + + +// Receive Methods +asio::error_code +Flow::receiveFrom(const asio::ip::address& address, unsigned short port, char* buffer, unsigned int& size, unsigned int timeout) +{ + bool done = false; + asio::error_code errorCode; + + UInt64 startTime = Timer::getTimeMs(); + unsigned int recvTimeout; + while(!done) + { + // We define timeout of 0 differently then TimeLimitFifo - we want 0 to mean no-block at all + if(timeout == 0 && mReceivedDataFifo.empty()) + { + // timeout + return asio::error_code(flowmanager::ReceiveTimeout, asio::error::misc_category); + } + + recvTimeout = timeout ? timeout - (Timer::getTimeMs() - startTime) : 0; + if(timeout != 0 && recvTimeout <= 0) + { + // timeout + return asio::error_code(flowmanager::ReceiveTimeout, asio::error::misc_category); + } + ReceivedData* receivedData = mReceivedDataFifo.getNext(recvTimeout); + if(receivedData) + { + mFakeSelectSocketDescriptor.receive(); + + // discard any data not from address/port requested + if(address == receivedData->mAddress && port == receivedData->mPort) + { + errorCode = processReceivedData(buffer, size, receivedData); + done = true; + } + delete receivedData; + } + else + { + // timeout + errorCode = asio::error_code(flowmanager::ReceiveTimeout, asio::error::misc_category); + done = true; + } + } + return errorCode; +} + +asio::error_code +Flow::receive(char* buffer, unsigned int& size, unsigned int timeout, asio::ip::address* sourceAddress, unsigned short* sourcePort) +{ + asio::error_code errorCode; + + //InfoLog(<< "Flow::receive called with buffer size=" << size << ", timeout=" << timeout); + // We define timeout of 0 differently then TimeLimitFifo - we want 0 to mean no-block at all + if(timeout == 0 && mReceivedDataFifo.empty()) + { + // timeout + InfoLog(<< "Receive timeout (timeout==0 and fifo empty)!"); + return asio::error_code(flowmanager::ReceiveTimeout, asio::error::misc_category); + } + if(mReceivedDataFifo.empty()) + { + WarningLog(<< "Receive called when there is no data available! ComponentId=" << mComponentId); + } + + ReceivedData* receivedData = mReceivedDataFifo.getNext(timeout); + if(receivedData) + { + mFakeSelectSocketDescriptor.receive(); + errorCode = processReceivedData(buffer, size, receivedData, sourceAddress, sourcePort); + delete receivedData; + } + else + { + // timeout + InfoLog(<< "Receive timeout! ComponentId=" << mComponentId); + errorCode = asio::error_code(flowmanager::ReceiveTimeout, asio::error::misc_category); + } + return errorCode; +} + + +asio::error_code +Flow::processReceivedData(char* buffer, unsigned int& size, ReceivedData* receivedData, asio::ip::address* sourceAddress, unsigned short* sourcePort) +{ + asio::error_code errorCode; + unsigned int receivedsize = receivedData->mData->size(); + + // SRTP Unprotect (if required) + if(mMediaStream.mSRTPSessionInCreated) + { + err_status_t status = mMediaStream.srtpUnprotect((void*)receivedData->mData->data(), (int*)&receivedsize, mComponentId == RTCP_COMPONENT_ID); + if(status != err_status_ok) + { + ErrLog(<< "Unable to SRTP unprotect the packet (componentid=" << mComponentId << "), error code=" << status << "(" << srtp_error_string(status) << ")"); + //errorCode = asio::error_code(flowmanager::SRTPError, asio::error::misc_category); + } + } +#ifdef USE_SSL + else + { + Lock lock(mMutex); + DtlsSocket* dtlsSocket = getDtlsSocket(StunTuple(mLocalBinding.getTransportType(), receivedData->mAddress, receivedData->mPort)); + if(dtlsSocket) + { + if(((FlowDtlsSocketContext*)dtlsSocket->getSocketContext())->isSrtpInitialized()) + { + err_status_t status = ((FlowDtlsSocketContext*)dtlsSocket->getSocketContext())->srtpUnprotect((void*)receivedData->mData->data(), (int*)&receivedsize, mComponentId == RTCP_COMPONENT_ID); + if(status != err_status_ok) + { + ErrLog(<< "Unable to SRTP unprotect the packet (componentid=" << mComponentId << "), error code=" << status << "(" << srtp_error_string(status) << ")"); + //errorCode = asio::error_code(flowmanager::SRTPError, asio::error::misc_category); + } + } + else + { + //WarningLog(<< "Unable to send packet yet - handshake is not completed yet, ComponentId=" << mComponentId); + errorCode = asio::error_code(flowmanager::InvalidState, asio::error::misc_category); + } + } + } +#endif //USE_SSL + if(!errorCode) + { + if(size > receivedsize) + { + size = receivedsize; + memcpy(buffer, receivedData->mData->data(), size); + //InfoLog(<< "Received a buffer of size=" << receivedData->mData.size()); + } + else + { + // Receive buffer too small + InfoLog(<< "Receive buffer too small for data size=" << receivedsize << " ComponentId=" << mComponentId); + errorCode = asio::error_code(flowmanager::BufferTooSmall, asio::error::misc_category); + } + if(sourceAddress) + { + *sourceAddress = receivedData->mAddress; + } + if(sourcePort) + { + *sourcePort = receivedData->mPort; + } + } + return errorCode; +} + +void +Flow::setActiveDestination(const char* address, unsigned short port) +{ + if(mTurnSocket.get()) + { + if(mMediaStream.mNatTraversalMode != MediaStream::TurnAllocation) + { + changeFlowState(Connecting); + mTurnSocket->connect(address, port); + } + else + { + mTurnSocket->setActiveDestination(asio::ip::address::from_string(address), port); + + } + } +} + +#ifdef USE_SSL +void +Flow::startDtlsClient(const char* address, unsigned short port) +{ + Lock lock(mMutex); + createDtlsSocketClient(StunTuple(mLocalBinding.getTransportType(), asio::ip::address::from_string(address), port)); +} +#endif + +void +Flow::setRemoteSDPFingerprint(const resip::Data& fingerprint) +{ + Lock lock(mMutex); + mRemoteSDPFingerprint = fingerprint; + +#ifdef USE_SSL + // Check all existing DtlsSockets and tear down those that don't match + std::map<reTurn::StunTuple, dtls::DtlsSocket*>::iterator it; + for(it = mDtlsSockets.begin(); it != mDtlsSockets.end(); it++) + { + if(it->second->handshakeCompleted() && + !it->second->checkFingerprint(fingerprint.c_str(), fingerprint.size())) + { + InfoLog(<< "Marking Dtls socket bad with non-matching fingerprint!"); + ((FlowDtlsSocketContext*)it->second->getSocketContext())->fingerprintMismatch(); + } + } +#endif //USE_SSL +} + +const resip::Data +Flow::getRemoteSDPFingerprint() +{ + Lock lock(mMutex); + return mRemoteSDPFingerprint; +} + +const StunTuple& +Flow::getLocalTuple() +{ + return mLocalBinding; +} + +StunTuple +Flow::getSessionTuple() +{ + assert(mFlowState == Ready); + Lock lock(mMutex); + + if(mMediaStream.mNatTraversalMode == MediaStream::TurnAllocation) + { + return mRelayTuple; + } + else if(mMediaStream.mNatTraversalMode == MediaStream::StunBindDiscovery) + { + return mReflexiveTuple; + } + return mLocalBinding; +} + +StunTuple +Flow::getRelayTuple() +{ + assert(mFlowState == Ready); + Lock lock(mMutex); + return mRelayTuple; +} + +StunTuple +Flow::getReflexiveTuple() +{ + assert(mFlowState == Ready); + Lock lock(mMutex); + return mReflexiveTuple; +} + +UInt64 +Flow::getReservationToken() +{ + assert(mFlowState == Ready); + Lock lock(mMutex); + return mReservationToken; +} + +void +Flow::onConnectSuccess(unsigned int socketDesc, const asio::ip::address& address, unsigned short port) +{ + InfoLog(<< "Flow::onConnectSuccess: socketDesc=" << socketDesc << ", address=" << address.to_string() << ", port=" << port << ", componentId=" << mComponentId); + + // Start candidate discovery + switch(mMediaStream.mNatTraversalMode) + { + case MediaStream::StunBindDiscovery: + if(mFlowState == ConnectingServer) + { + changeFlowState(Binding); + mTurnSocket->bindRequest(); + } + else + { + changeFlowState(Ready); + mMediaStream.onFlowReady(mComponentId); + } + break; + case MediaStream::TurnAllocation: + changeFlowState(Allocating); + mTurnSocket->createAllocation(TurnAsyncSocket::UnspecifiedLifetime, + TurnAsyncSocket::UnspecifiedBandwidth, + mAllocationProps, + mReservationToken != 0 ? mReservationToken : TurnAsyncSocket::UnspecifiedToken, + StunTuple::UDP); // Always relay as UDP + break; + case MediaStream::NoNatTraversal: + default: + changeFlowState(Ready); + mMediaStream.onFlowReady(mComponentId); + break; + } +} + +void +Flow::onConnectFailure(unsigned int socketDesc, const asio::error_code& e) +{ + WarningLog(<< "Flow::onConnectFailure: socketDesc=" << socketDesc << " error=" << e.value() << "(" << e.message() << ", componentId=" << mComponentId); + changeFlowState(Unconnected); + mMediaStream.onFlowError(mComponentId, e.value()); // TODO define different error code? +} + + +void +Flow::onSharedSecretSuccess(unsigned int socketDesc, const char* username, unsigned int usernameSize, const char* password, unsigned int passwordSize) +{ + InfoLog(<< "Flow::onSharedSecretSuccess: socketDesc=" << socketDesc << ", username=" << username << ", password=" << password << ", componentId=" << mComponentId); +} + +void +Flow::onSharedSecretFailure(unsigned int socketDesc, const asio::error_code& e) +{ + WarningLog(<< "Flow::onSharedSecretFailure: socketDesc=" << socketDesc << " error=" << e.value() << "(" << e.message() << "), componentId=" << mComponentId ); +} + +void +Flow::onBindSuccess(unsigned int socketDesc, const StunTuple& reflexiveTuple) +{ + InfoLog(<< "Flow::onBindingSuccess: socketDesc=" << socketDesc << ", reflexive=" << reflexiveTuple << ", componentId=" << mComponentId); + { + Lock lock(mMutex); + mReflexiveTuple = reflexiveTuple; + } + changeFlowState(Ready); + mMediaStream.onFlowReady(mComponentId); +} +void +Flow::onBindFailure(unsigned int socketDesc, const asio::error_code& e) +{ + WarningLog(<< "Flow::onBindingFailure: socketDesc=" << socketDesc << " error=" << e.value() << "(" << e.message() << "), componentId=" << mComponentId ); + changeFlowState(Connected); + mMediaStream.onFlowError(mComponentId, e.value()); // TODO define different error code? +} + +void +Flow::onAllocationSuccess(unsigned int socketDesc, const StunTuple& reflexiveTuple, const StunTuple& relayTuple, unsigned int lifetime, unsigned int bandwidth, UInt64 reservationToken) +{ + InfoLog(<< "Flow::onAllocationSuccess: socketDesc=" << socketDesc << + ", reflexive=" << reflexiveTuple << + ", relay=" << relayTuple << + ", lifetime=" << lifetime << + ", bandwidth=" << bandwidth << + ", reservationToken=" << reservationToken << + ", componentId=" << mComponentId); + { + Lock lock(mMutex); + mReflexiveTuple = reflexiveTuple; + mRelayTuple = relayTuple; + mReservationToken = reservationToken; + } + changeFlowState(Ready); + mMediaStream.onFlowReady(mComponentId); +} + +void +Flow::onAllocationFailure(unsigned int socketDesc, const asio::error_code& e) +{ + WarningLog(<< "Flow::onAllocationFailure: socketDesc=" << socketDesc << " error=" << e.value() << "(" << e.message() << "), componentId=" << mComponentId ); + changeFlowState(Connected); + mMediaStream.onFlowError(mComponentId, e.value()); // TODO define different error code? +} + +void +Flow::onRefreshSuccess(unsigned int socketDesc, unsigned int lifetime) +{ + InfoLog(<< "Flow::onRefreshSuccess: socketDesc=" << socketDesc << ", lifetime=" << lifetime << ", componentId=" << mComponentId); + if(lifetime == 0) + { + changeFlowState(Connected); + } +} + +void +Flow::onRefreshFailure(unsigned int socketDesc, const asio::error_code& e) +{ + WarningLog(<< "Flow::onRefreshFailure: socketDesc=" << socketDesc << " error=" << e.value() << "(" << e.message() << "), componentId=" << mComponentId ); +} + +void +Flow::onSetActiveDestinationSuccess(unsigned int socketDesc) +{ + InfoLog(<< "Flow::onSetActiveDestinationSuccess: socketDesc=" << socketDesc << ", componentId=" << mComponentId); +} + +void +Flow::onSetActiveDestinationFailure(unsigned int socketDesc, const asio::error_code& e) +{ + WarningLog(<< "Flow::onSetActiveDestinationFailure: socketDesc=" << socketDesc << " error=" << e.value() << "(" << e.message() << "), componentId=" << mComponentId ); +} + +void +Flow::onClearActiveDestinationSuccess(unsigned int socketDesc) +{ + InfoLog(<< "Flow::onClearActiveDestinationSuccess: socketDesc=" << socketDesc << ", componentId=" << mComponentId); +} + +void +Flow::onClearActiveDestinationFailure(unsigned int socketDesc, const asio::error_code& e) +{ + WarningLog(<< "Flow::onClearActiveDestinationFailure: socketDesc=" << socketDesc << " error=" << e.value() << "(" << e.message() << "), componentId=" << mComponentId ); +} + +void +Flow::onSendSuccess(unsigned int socketDesc) +{ + //InfoLog(<< "Flow::onSendSuccess: socketDesc=" << socketDesc); +} + +void +Flow::onSendFailure(unsigned int socketDesc, const asio::error_code& e) +{ + if(e.value() == InvalidState) + { + // Note: if setActiveDestination is called it can take some time to "connect" the socket to the destination + // and send requests during this time, will be discarded - this can be considered normal + InfoLog(<< "Flow::onSendFailure: socketDesc=" << socketDesc << " socket is not in correct state to send yet, componentId=" << mComponentId ); + } + else + { + WarningLog(<< "Flow::onSendFailure: socketDesc=" << socketDesc << " error=" << e.value() << "(" << e.message() << "), componentId=" << mComponentId ); + } +} + +void +Flow::onReceiveSuccess(unsigned int socketDesc, const asio::ip::address& address, unsigned short port, boost::shared_ptr<reTurn::DataBuffer>& data) +{ + DebugLog(<< "Flow::onReceiveSuccess: socketDesc=" << socketDesc << ", fromAddress=" << address.to_string() << ", fromPort=" << port << ", size=" << data->size() << ", componentId=" << mComponentId); + +#ifdef USE_SSL + // Check if packet is a dtls packet - if so then process it + // Note: Stun messaging should be picked off by the reTurn library - so we only need to tell the difference between DTLS and SRTP here + if(DtlsFactory::demuxPacket((const unsigned char*) data->data(), data->size()) == DtlsFactory::dtls) + { + Lock lock(mMutex); + + StunTuple endpoint(mLocalBinding.getTransportType(), address, port); + DtlsSocket* dtlsSocket = getDtlsSocket(endpoint); + if(!dtlsSocket) + { + // If don't have a socket already for this endpoint and we are receiving data, then assume we are the server side of the DTLS connection + dtlsSocket = createDtlsSocketServer(endpoint); + } + if(dtlsSocket) + { + dtlsSocket->handlePacketMaybe((const unsigned char*) data->data(), data->size()); + } + + // Packet was a DTLS packet - do not queue for app + return; + } +#endif + + if(!mReceivedDataFifo.add(new ReceivedData(address, port, data), ReceivedDataFifo::EnforceTimeDepth)) + { + WarningLog(<< "Flow::onReceiveSuccess: TimeLimitFifo is full - discarding data! componentId=" << mComponentId); + } + else + { + mFakeSelectSocketDescriptor.send(); + } +} + +void +Flow::onReceiveFailure(unsigned int socketDesc, const asio::error_code& e) +{ + WarningLog(<< "Flow::onReceiveFailure: socketDesc=" << socketDesc << " error=" << e.value() << "(" << e.message() << "), componentId=" << mComponentId); + + // Make sure we keep receiving if we get an ICMP error on a UDP socket + if(e.value() == asio::error::connection_reset && mLocalBinding.getTransportType() == StunTuple::UDP) + { + assert(mTurnSocket.get()); + mTurnSocket->turnReceive(); + } +} + +void +Flow::changeFlowState(FlowState newState) +{ + InfoLog(<< "Flow::changeState: oldState=" << flowStateToString(mFlowState) << ", newState=" << flowStateToString(newState) << ", componentId=" << mComponentId); + mFlowState = newState; +} + +char* +Flow::flowStateToString(FlowState state) +{ + switch(state) + { + case Unconnected: + return "Unconnected"; + case ConnectingServer: + return "ConnectingServer"; + case Connecting: + return "Connecting"; + case Binding: + return "Binding"; + case Allocating: + return "Allocating"; + case Connected: + return "Connected"; + case Ready: + return "Ready"; + default: + assert(false); + return "Unknown"; + } +} + +#ifdef USE_SSL +DtlsSocket* +Flow::getDtlsSocket(const StunTuple& endpoint) +{ + std::map<reTurn::StunTuple, dtls::DtlsSocket*>::iterator it = mDtlsSockets.find(endpoint); + if(it != mDtlsSockets.end()) + { + return it->second; + } + return 0; +} + +DtlsSocket* +Flow::createDtlsSocketClient(const StunTuple& endpoint) +{ + DtlsSocket* dtlsSocket = getDtlsSocket(endpoint); + if(!dtlsSocket && mMediaStream.mDtlsFactory) + { + InfoLog(<< "Creating DTLS Client socket, componentId=" << mComponentId); + std::auto_ptr<DtlsSocketContext> socketContext(new FlowDtlsSocketContext(*this, endpoint.getAddress(), endpoint.getPort())); + dtlsSocket = mMediaStream.mDtlsFactory->createClient(socketContext); + dtlsSocket->startClient(); + mDtlsSockets[endpoint] = dtlsSocket; + } + + return dtlsSocket; +} + +DtlsSocket* +Flow::createDtlsSocketServer(const StunTuple& endpoint) +{ + DtlsSocket* dtlsSocket = getDtlsSocket(endpoint); + if(!dtlsSocket && mMediaStream.mDtlsFactory) + { + InfoLog(<< "Creating DTLS Server socket, componentId=" << mComponentId); + std::auto_ptr<DtlsSocketContext> socketContext(new FlowDtlsSocketContext(*this, endpoint.getAddress(), endpoint.getPort())); + dtlsSocket = mMediaStream.mDtlsFactory->createServer(socketContext); + mDtlsSockets[endpoint] = dtlsSocket; + } + + return dtlsSocket; +} + +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/Flow.hxx b/src/libs/resiprocate/reflow/Flow.hxx new file mode 100644 index 00000000..34452237 --- /dev/null +++ b/src/libs/resiprocate/reflow/Flow.hxx @@ -0,0 +1,240 @@ +#if !defined(Flow_hxx) +#define Flow_hxx + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <map> +#include <rutil/TimeLimitFifo.hxx> +#include <rutil/Mutex.hxx> + +#ifdef WIN32 +#include <srtp.h> +#else +#include <srtp/srtp.h> +#endif +#include <boost/shared_ptr.hpp> + +#include "reTurn/client/TurnAsyncUdpSocket.hxx" +#include "reTurn/client/TurnAsyncTcpSocket.hxx" +#include "reTurn/client/TurnAsyncTlsSocket.hxx" +#include "reTurn/client/TurnAsyncSocketHandler.hxx" +#include "reTurn/StunMessage.hxx" +#include "FakeSelectSocketDescriptor.hxx" +#include "dtls_wrapper/DtlsSocket.hxx" + +using namespace reTurn; + +namespace flowmanager +{ + +/** + This class represents a Flow that is created by the Flow Manager. A flow is a + bi-directional stream of data for communicating with an endpoint, that may use + UDP, TCP or TLS over TCP. A flow may also use a Turn Allocation to transmit + data to/from an endpoint. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ +class MediaStream; +class Flow; + +class Flow : public TurnAsyncSocketHandler +{ +public: + + enum FlowState + { + Unconnected, + ConnectingServer, + Connecting, + Binding, + Allocating, + Connected, + Ready + }; + + Flow(asio::io_service& ioService, +#ifdef USE_SSL + asio::ssl::context& sslContext, +#endif + unsigned int componentId, + const StunTuple& localBinding, + MediaStream& mediaStream); + ~Flow(); + + void activateFlow(UInt8 allocationProps = StunMessage::PropsNone); + void activateFlow(UInt64 reservationToken); + + bool isReady() { return mFlowState == Ready; } + + /// Returns a socket descriptor that can be used in a select call + /// WARNING - this descriptor should not be used for any other purpose + /// - do NOT set socket options, or send, receive from this descriptor, + /// instead use the Flow api's + unsigned int getSelectSocketDescriptor(); + + unsigned int getSocketDescriptor(); // returns the real socket descriptor - used to correlate callbacks + + /// Turn Send Methods + /// WARNING - if using Secure media, then there must be room at the + /// end of the passed in buffer for the SRTP HMAC code to be appended + /// ***It would be good to make this safer*** + void send(char* buffer, unsigned int size); + void sendTo(const asio::ip::address& address, unsigned short port, char* buffer, unsigned int size); + void rawSendTo(const asio::ip::address& address, unsigned short port, const char* buffer, unsigned int size); + + /// Receive Methods + asio::error_code receive(char* buffer, unsigned int& size, unsigned int timeout, asio::ip::address* sourceAddress=0, unsigned short* sourcePort=0); + asio::error_code receiveFrom(const asio::ip::address& address, unsigned short port, char* buffer, unsigned int& size, unsigned int timeout); + + /// Used to set where this flow should be sending to + void setActiveDestination(const char* address, unsigned short port); + + /// Dtls-Srtp Methods + + /// Starts the dtls client handshake process - (must call setActiveDestination first) + /// Call this method if this client has negotiated the "Active" role via SDP + void startDtlsClient(const char* address, unsigned short port); + + /// This method should be called when remote fingerprint is discovered + /// via SDP negotiation. After this is called only dtls-srtp connections + /// with a matching fingerprint will be maintained. + void setRemoteSDPFingerprint(const resip::Data& fingerprint); + + /// Retrieves the stored remote SDP Fingerprint. + const resip::Data getRemoteSDPFingerprint(); + + const StunTuple& getLocalTuple(); + StunTuple getSessionTuple(); // returns either local, reflexive, or relay tuple depending on NatTraversalMode + StunTuple getRelayTuple(); + StunTuple getReflexiveTuple(); + UInt64 getReservationToken(); + unsigned int getComponentId() { return mComponentId; } + +private: + asio::io_service& mIOService; +#ifdef USE_SSL + asio::ssl::context& mSslContext; +#endif + + // Note: these member variables are set at creation time and never changed, thus + // they do not require mutex protection + unsigned int mComponentId; + StunTuple mLocalBinding; + + // MediaStream that this Flow belongs too + MediaStream& mMediaStream; + + // mTurnSocket has it's own threading protection + boost::shared_ptr<TurnAsyncSocket> mTurnSocket; + + // These are only set once, then accessed - thus they do not require mutex protection + UInt8 mAllocationProps; + UInt64 mReservationToken; + + // Mutex to protect the following members that may be get/set from multiple threads + resip::Mutex mMutex; + StunTuple mReflexiveTuple; + StunTuple mRelayTuple; + resip::Data mRemoteSDPFingerprint; + +#ifdef USE_SSL + // Map to store all DtlsSockets - in forking cases there can be more than one + std::map<reTurn::StunTuple, dtls::DtlsSocket*> mDtlsSockets; + dtls::DtlsSocket* getDtlsSocket(const reTurn::StunTuple& endpoint); + dtls::DtlsSocket* createDtlsSocketClient(const StunTuple& endpoint); + dtls::DtlsSocket* createDtlsSocketServer(const StunTuple& endpoint); +#endif + + volatile FlowState mFlowState; + void changeFlowState(FlowState newState); + char* flowStateToString(FlowState state); + + class ReceivedData + { + public: + ReceivedData(const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data) : + mAddress(address), mPort(port), mData(data) {} + ~ReceivedData() {} + + asio::ip::address mAddress; + unsigned short mPort; + boost::shared_ptr<DataBuffer> mData; + }; + // FIFO for received data + typedef resip::TimeLimitFifo<ReceivedData> ReceivedDataFifo; + ReceivedDataFifo mReceivedDataFifo; + + // Helpers to perform SRTP protection/unprotection + bool processSendData(char* buffer, unsigned int& size, const asio::ip::address& address, unsigned short port); + asio::error_code processReceivedData(char* buffer, unsigned int& size, ReceivedData* receivedData, asio::ip::address* sourceAddress=0, unsigned short* sourcePort=0); + FakeSelectSocketDescriptor mFakeSelectSocketDescriptor; + + virtual void onConnectSuccess(unsigned int socketDesc, const asio::ip::address& address, unsigned short port); + virtual void onConnectFailure(unsigned int socketDesc, const asio::error_code& e); + + virtual void onSharedSecretSuccess(unsigned int socketDesc, const char* username, unsigned int usernameSize, const char* password, unsigned int passwordSize); + virtual void onSharedSecretFailure(unsigned int socketDesc, const asio::error_code& e); + + virtual void onBindSuccess(unsigned int socketDesc, const StunTuple& reflexiveTuple); + virtual void onBindFailure(unsigned int socketDesc, const asio::error_code& e); + + virtual void onAllocationSuccess(unsigned int socketDesc, const StunTuple& reflexiveTuple, const StunTuple& relayTuple, unsigned int lifetime, unsigned int bandwidth, UInt64 reservationToken); + virtual void onAllocationFailure(unsigned int socketDesc, const asio::error_code& e); + + virtual void onRefreshSuccess(unsigned int socketDesc, unsigned int lifetime); + virtual void onRefreshFailure(unsigned int socketDesc, const asio::error_code& e); + + virtual void onSetActiveDestinationSuccess(unsigned int socketDesc); + virtual void onSetActiveDestinationFailure(unsigned int socketDesc, const asio::error_code &e); + virtual void onClearActiveDestinationSuccess(unsigned int socketDesc); + virtual void onClearActiveDestinationFailure(unsigned int socketDesc, const asio::error_code &e); + + //virtual void onReceiveSuccess(unsigned int socketDesc, const asio::ip::address& address, unsigned short port, const char* buffer, unsigned int size); + virtual void onReceiveSuccess(unsigned int socketDesc, const asio::ip::address& address, unsigned short port, boost::shared_ptr<DataBuffer>& data); + virtual void onReceiveFailure(unsigned int socketDesc, const asio::error_code& e); + + virtual void onSendSuccess(unsigned int socketDesc); + virtual void onSendFailure(unsigned int socketDesc, const asio::error_code& e); +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/FlowDtlsSocketContext.cxx b/src/libs/resiprocate/reflow/FlowDtlsSocketContext.cxx new file mode 100644 index 00000000..bfccfa12 --- /dev/null +++ b/src/libs/resiprocate/reflow/FlowDtlsSocketContext.cxx @@ -0,0 +1,184 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_SSL +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/Timer.hxx> + +#include <asio.hpp> +#include <boost/function.hpp> +#include <iostream> + +#include "FlowDtlsSocketContext.hxx" +#include "FlowManagerSubsystem.hxx" + +using namespace flowmanager; +using namespace resip; +using namespace dtls; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM FlowManagerSubsystem::FLOWMANAGER + +FlowDtlsSocketContext::FlowDtlsSocketContext(Flow& flow, const asio::ip::address& address, unsigned short port) + : mFlow(flow), mAddress(address), mPort(port), mSrtpInitialized(false) +{ +} + +FlowDtlsSocketContext::~FlowDtlsSocketContext() +{ + if(mSrtpInitialized) + { + // Free the master key memory allocated in DtlsSocket::createSrtpSessionPolicies + delete mSRTPPolicyIn.key; + delete mSRTPPolicyOut.key; + } +} + +void +FlowDtlsSocketContext::write(const unsigned char* data, unsigned int len) +{ + InfoLog(<< "Dtls write to " << mAddress.to_string() << ":" << mPort << " called. ComponentId=" << mFlow.getComponentId()); + mFlow.rawSendTo(mAddress, mPort, (const char*)data, len); +} + +void +FlowDtlsSocketContext::handshakeCompleted() +{ + InfoLog(<< "Flow Dtls Handshake Completed! ComponentId=" << mFlow.getComponentId()); + + char fprint[100]; + SRTP_PROTECTION_PROFILE *srtp_profile; + int r; + + if(mSocket->getRemoteFingerprint(fprint)) + { + Data remoteSDPFingerprint = mFlow.getRemoteSDPFingerprint(); + if(!remoteSDPFingerprint.empty()) + { + if(!mSocket->checkFingerprint(remoteSDPFingerprint.c_str(), remoteSDPFingerprint.size())) + { + InfoLog(<< "Remote fingerprint = " << fprint << " is not valid! ComponentId=" << mFlow.getComponentId()); + return; + } + else + { + InfoLog(<< "Remote fingerprint = " << fprint << " is valid! ComponentId=" << mFlow.getComponentId()); + } + } + else + { + InfoLog(<< "Remote fingerprint = " << fprint << " ComponentId=" << mFlow.getComponentId()); + } + } + else + { + InfoLog(<< "Remote fingerprint cannot be obtained from Dtls handshake. ComponentId=" << mFlow.getComponentId()); + return; + } + + srtp_profile=mSocket->getSrtpProfile(); + + if(srtp_profile) + { + InfoLog(<< "SRTP Extension negotiated profile=" << srtp_profile->name << " ComponentId=" << mFlow.getComponentId()); + } + + mSocket->createSrtpSessionPolicies(mSRTPPolicyOut, mSRTPPolicyIn); + + r=srtp_create(&mSRTPSessionIn, &mSRTPPolicyIn); + assert(r==0); + r=srtp_create(&mSRTPSessionOut, &mSRTPPolicyOut); + assert(r==0); + mSrtpInitialized = true; +} + +void +FlowDtlsSocketContext::handshakeFailed(const char *err) +{ + ErrLog(<< "Flow Dtls Handshake failed! ComponentId=" << mFlow.getComponentId()); +} + +void FlowDtlsSocketContext::fingerprintMismatch() +{ + // Ensure Srtp is not initalized, so the will not process media packets from this endpoint + if(mSrtpInitialized) + { + // Free the master key memory allocated in DtlsSocket::createSrtpSessionPolicies + delete mSRTPPolicyIn.key; + delete mSRTPPolicyOut.key; + } + mSrtpInitialized = false; +} + +err_status_t +FlowDtlsSocketContext::srtpProtect(void* data, int* size, bool rtcp) +{ + err_status_t status = err_status_no_ctx; + if(mSrtpInitialized) + { + if(rtcp) + { + status = srtp_protect_rtcp(mSRTPSessionOut, data, size); + } + else + { + status = srtp_protect(mSRTPSessionOut, data, size); + } + } + return status; +} + +err_status_t +FlowDtlsSocketContext::srtpUnprotect(void* data, int* size, bool rtcp) +{ + err_status_t status = err_status_no_ctx; + if(mSrtpInitialized) + { + if(rtcp) + { + status = srtp_unprotect_rtcp(mSRTPSessionIn, data, size); + } + else + { + status = srtp_unprotect(mSRTPSessionIn, data, size); + } + } + return status; +} + +#endif +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/FlowDtlsSocketContext.hxx b/src/libs/resiprocate/reflow/FlowDtlsSocketContext.hxx new file mode 100644 index 00000000..d69d65fb --- /dev/null +++ b/src/libs/resiprocate/reflow/FlowDtlsSocketContext.hxx @@ -0,0 +1,99 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_SSL + +#if !defined(FlowDtlsSocketContext_hxx) +#define FlowDtlsSocketContext_hxx + +#include <asio.hpp> +#ifdef WIN32 +#include <srtp.h> +#else +#include <srtp/srtp.h> +#endif + +#include "dtls_wrapper/DtlsSocket.hxx" +#include "Flow.hxx" + +/** + This class is used during media sessions that use Dtls-Srtp + for a media transport. It handles callbacks from the Dtls + wrapper module and hold Srtp session policies for a particular + dtls endpoint. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +namespace flowmanager +{ + +class FlowDtlsSocketContext : public dtls::DtlsSocketContext +{ +public: + FlowDtlsSocketContext(Flow& flow, const asio::ip::address& address, unsigned short port); + virtual ~FlowDtlsSocketContext(); + + // DtlsSocketContext Virtual Fns + virtual void write(const unsigned char* data, unsigned int len); + virtual void handshakeCompleted(); + virtual void handshakeFailed(const char *err); + + srtp_t* getSrtpSessionIn() { return &mSRTPSessionIn; } + srtp_t* getSrtpSessionOut() { return &mSRTPSessionOut; } + bool isSrtpInitialized() { return mSrtpInitialized; } + void fingerprintMismatch(); + + err_status_t srtpProtect(void* data, int* size, bool rtcp); + err_status_t srtpUnprotect(void* data, int* size, bool rtcp); + +private: + Flow& mFlow; + asio::ip::address mAddress; + unsigned short mPort; + srtp_policy_t mSRTPPolicyIn; + srtp_policy_t mSRTPPolicyOut; + srtp_t mSRTPSessionIn; + srtp_t mSRTPSessionOut; + volatile bool mSrtpInitialized; +}; + +} + +#endif + +#endif //USE_SSL +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/FlowDtlsTimerContext.cxx b/src/libs/resiprocate/reflow/FlowDtlsTimerContext.cxx new file mode 100644 index 00000000..0659ab6f --- /dev/null +++ b/src/libs/resiprocate/reflow/FlowDtlsTimerContext.cxx @@ -0,0 +1,86 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_SSL + +#include <boost/bind.hpp> + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> + +#include "FlowDtlsTimerContext.hxx" +#include "FlowManagerSubsystem.hxx" + +using namespace flowmanager; +using namespace resip; +using namespace dtls; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM FlowManagerSubsystem::FLOWMANAGER + +FlowDtlsTimerContext::FlowDtlsTimerContext(asio::io_service& ioService) : + mIOService(ioService) +{ +} + +void +FlowDtlsTimerContext::addTimer(dtls::DtlsTimer *timer, unsigned int durationMs) +{ + resip::SharedPtr<asio::deadline_timer> deadlineTimer(new asio::deadline_timer(mIOService)); + deadlineTimer->expires_from_now(boost::posix_time::milliseconds(durationMs)); + deadlineTimer->async_wait(boost::bind(&FlowDtlsTimerContext::handleTimeout, this, timer, asio::placeholders::error)); + mDeadlineTimers[timer] = deadlineTimer; + //InfoLog(<< "FlowDtlsTimerContext: starting timer for " << durationMs << "ms."); +} + +void +FlowDtlsTimerContext::handleTimeout(dtls::DtlsTimer *timer, const asio::error_code& errorCode) +{ + if(!errorCode) + { + //InfoLog(<< "FlowDtlsTimerContext: timer expired!"); + timer->fire(); + } + else + { + ErrLog(<< "Timer error: " << errorCode.message()); + } + mDeadlineTimers.erase(timer); +} + +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/FlowDtlsTimerContext.hxx b/src/libs/resiprocate/reflow/FlowDtlsTimerContext.hxx new file mode 100644 index 00000000..b4cbd6c6 --- /dev/null +++ b/src/libs/resiprocate/reflow/FlowDtlsTimerContext.hxx @@ -0,0 +1,70 @@ +#ifdef USE_SSL + + +#if !defined(FlowDtlsTimerContext_hxx) +#define FlowDtlsTimerContext_hxx + +#include <asio.hpp> +#include <rutil/SharedPtr.hxx> +#include "dtls_wrapper/DtlsTimer.hxx" + +/** + This class is used to provide timer logic to the dtls + wrapper code, so that DTLS messages can be retransmitted. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ +namespace flowmanager +{ + +class FlowDtlsTimerContext: public dtls::DtlsTimerContext +{ + public: + FlowDtlsTimerContext(asio::io_service& ioService); + void addTimer(dtls::DtlsTimer *timer, unsigned int durationMs); + void handleTimeout(dtls::DtlsTimer *timer, const asio::error_code& errorCode); + + private: + asio::io_service& mIOService; + std::map<dtls::DtlsTimer*, resip::SharedPtr<asio::deadline_timer> > mDeadlineTimers; +}; + +} + +#endif + +#endif //USE_SSL + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/FlowManager.cxx b/src/libs/resiprocate/reflow/FlowManager.cxx new file mode 100644 index 00000000..c7351ffb --- /dev/null +++ b/src/libs/resiprocate/reflow/FlowManager.cxx @@ -0,0 +1,315 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/ThreadIf.hxx> +#include <rutil/Random.hxx> +#include <rutil/SharedPtr.hxx> +#include <rutil/Timer.hxx> + +#include <asio.hpp> +#include <boost/function.hpp> +#include <map> + +#ifdef WIN32 +#include <srtp.h> +#else +#include <srtp/srtp.h> +#endif + +#ifdef USE_SSL +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include "FlowDtlsTimerContext.hxx" +#endif //USE_SSL + +#include "FlowManagerSubsystem.hxx" +#include "FlowManager.hxx" + +using namespace flowmanager; +using namespace resip; +#ifdef USE_SSL +using namespace dtls; +#endif +using namespace std; + +#define RESIPROCATE_SUBSYSTEM FlowManagerSubsystem::FLOWMANAGER + +namespace flowmanager +{ +class IOServiceThread : public ThreadIf +{ +public: + IOServiceThread(asio::io_service& ioService) : mIOService(ioService) {} + + virtual ~IOServiceThread() {} + + virtual void thread() + { + mIOService.run(); + } +private: + asio::io_service& mIOService; +}; +} + +FlowManager::FlowManager() +#ifdef USE_SSL + : + mSslContext(mIOService, asio::ssl::context::tlsv1), + mClientCert(0), + mClientKey(0), + mDtlsFactory(0) +#endif +{ + mIOServiceWork = new asio::io_service::work(mIOService); + mIOServiceThread = new IOServiceThread(mIOService); + mIOServiceThread->run(); + +#ifdef USE_SSL + // Setup SSL context + asio::error_code ec; + mSslContext.set_verify_mode(asio::ssl::context::verify_peer | + asio::ssl::context::verify_fail_if_no_peer_cert); +#define VERIFY_FILE "ca.pem" + mSslContext.load_verify_file(VERIFY_FILE, ec); // TODO make a setting + if(ec) + { + ErrLog(<< "Unable to load verify file: " << VERIFY_FILE << ", error=" << ec.value() << "(" << ec.message() << ")"); + } +#endif + + // Initialize SRTP + err_status_t status = srtp_init(); + if(status && status != err_status_bad_param) // Note: err_status_bad_param happens if srtp_init is called twice - we allow this for test programs + { + ErrLog(<< "Unable to initialize SRTP engine, error code=" << status); + throw FlowManagerException("Unable to initialize SRTP engine", __FILE__, __LINE__); + } + status = srtp_install_event_handler(FlowManager::srtpEventHandler); +} + + +FlowManager::~FlowManager() +{ + delete mIOServiceWork; + mIOServiceThread->join(); + delete mIOServiceThread; + + #ifdef USE_SSL + if(mDtlsFactory) delete mDtlsFactory; + if(mClientCert) X509_free(mClientCert); + if(mClientKey) EVP_PKEY_free(mClientKey); + #endif +} + +#ifdef USE_SSL +void +FlowManager::initializeDtlsFactory(const char* certAor) +{ + if(mDtlsFactory) + { + ErrLog(<< "initializeDtlsFactory called when DtlsFactory is already initialized."); + return; + } + + Data aor(certAor); + if(createCert(aor, 365 /* expireDays */, 1024 /* keyLen */, mClientCert, mClientKey)) + { + FlowDtlsTimerContext* timerContext = new FlowDtlsTimerContext(mIOService); + mDtlsFactory = new DtlsFactory(std::auto_ptr<DtlsTimerContext>(timerContext), mClientCert, mClientKey); + assert(mDtlsFactory); + } + else + { + ErrLog(<< "Unable to create a client cert, cannot use Dtls-Srtp."); + } +} +#endif + +void +FlowManager::srtpEventHandler(srtp_event_data_t *data) +{ + switch(data->event) { + case event_ssrc_collision: + WarningLog(<< "SRTP SSRC collision"); + break; + case event_key_soft_limit: + WarningLog(<< "SRTP key usage soft limit reached"); + break; + case event_key_hard_limit: + WarningLog(<< "SRTP key usage hard limit reached"); + break; + case event_packet_index_limit: + WarningLog(<< "SRTP packet index limit reached"); + break; + default: + WarningLog(<< "SRTP unknown event reported to handler"); + } + } + +MediaStream* +FlowManager::createMediaStream(MediaStreamHandler& mediaStreamHandler, + const StunTuple& localBinding, + bool rtcpEnabled, + MediaStream::NatTraversalMode natTraversalMode, + const char* natTraversalServerHostname, + unsigned short natTraversalServerPort, + const char* stunUsername, + const char* stunPassword) +{ + MediaStream* newMediaStream = 0; + if(rtcpEnabled) + { + StunTuple localRtcpBinding(localBinding.getTransportType(), localBinding.getAddress(), localBinding.getPort() + 1); + newMediaStream = new MediaStream(mIOService, +#ifdef USE_SSL + mSslContext, +#endif + mediaStreamHandler, + localBinding, + localRtcpBinding, +#ifdef USE_SSL + mDtlsFactory, +#endif + natTraversalMode, + natTraversalServerHostname, + natTraversalServerPort, + stunUsername, + stunPassword); + } + else + { + StunTuple rtcpDisabled; // Default constructor sets transport type to None - this signals Rtcp is disabled + newMediaStream = new MediaStream(mIOService, +#ifdef USE_SSL + mSslContext, +#endif + mediaStreamHandler, + localBinding, + rtcpDisabled, +#ifdef USE_SSL + mDtlsFactory, +#endif + natTraversalMode, + natTraversalServerHostname, + natTraversalServerPort, + stunUsername, + stunPassword); + } + return newMediaStream; +} + +#ifdef USE_SSL +int +FlowManager::createCert(const resip::Data& pAor, int expireDays, int keyLen, X509*& outCert, EVP_PKEY*& outKey ) +{ + int ret; + + Data aor = "sip:" + pAor; + + // Make sure that necessary algorithms exist: + assert(EVP_sha1()); + + RSA* rsa = RSA_generate_key(keyLen, RSA_F4, NULL, NULL); + assert(rsa); // couldn't make key pair + + EVP_PKEY* privkey = EVP_PKEY_new(); + assert(privkey); + ret = EVP_PKEY_set1_RSA(privkey, rsa); + assert(ret); + + X509* cert = X509_new(); + assert(cert); + + X509_NAME* subject = X509_NAME_new(); + X509_EXTENSION* ext = X509_EXTENSION_new(); + + // set version to X509v3 (starts from 0) + X509_set_version(cert, 2L); + + int serial = Random::getRandom(); // get an int worth of randomness + assert(sizeof(int)==4); + ASN1_INTEGER_set(X509_get_serialNumber(cert),serial); + +// ret = X509_NAME_add_entry_by_txt( subject, "O", MBSTRING_ASC, +// (unsigned char *) domain.data(), domain.size(), +// -1, 0); + assert(ret); + ret = X509_NAME_add_entry_by_txt( subject, "CN", MBSTRING_ASC, + (unsigned char *) aor.data(), aor.size(), + -1, 0); + assert(ret); + + ret = X509_set_issuer_name(cert, subject); + assert(ret); + ret = X509_set_subject_name(cert, subject); + assert(ret); + + const long duration = 60*60*24*expireDays; + X509_gmtime_adj(X509_get_notBefore(cert),0); + X509_gmtime_adj(X509_get_notAfter(cert), duration); + + ret = X509_set_pubkey(cert, privkey); + assert(ret); + + Data subjectAltNameStr = Data("URI:sip:") + aor + + Data(",URI:im:")+aor + + Data(",URI:pres:")+aor; + ext = X509V3_EXT_conf_nid( NULL , NULL , NID_subject_alt_name, + (char*) subjectAltNameStr.c_str() ); + X509_add_ext( cert, ext, -1); + X509_EXTENSION_free(ext); + + static char CA_FALSE[] = "CA:FALSE"; + ext = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints, CA_FALSE); + ret = X509_add_ext( cert, ext, -1); + assert(ret); + X509_EXTENSION_free(ext); + + // TODO add extensions NID_subject_key_identifier and NID_authority_key_identifier + + ret = X509_sign(cert, privkey, EVP_sha1()); + assert(ret); + + outCert = cert; + outKey = privkey; + return ret; +} +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/FlowManager.hxx b/src/libs/resiprocate/reflow/FlowManager.hxx new file mode 100644 index 00000000..4975eeaf --- /dev/null +++ b/src/libs/resiprocate/reflow/FlowManager.hxx @@ -0,0 +1,116 @@ +#if !defined(FlowManager_hxx) +#define FlowManager_hxx + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "MediaStream.hxx" +#include "FlowManagerException.hxx" + +#ifdef USE_SSL +#include "dtls_wrapper/DtlsFactory.hxx" +#include <openssl/crypto.h> +#include <openssl/ssl.h> +#endif //USE_SSL + +#include <map> + +using namespace reTurn; + +namespace flowmanager +{ + +/** + This class represents the Flow Manager. It is responsible for sending/receiving + media and performing the necessary NAT traversal. + + Threading Notes: This class implements a thread + to manage the asyncrouns reTurn client library calls. Essentially all + asyncrounous operations for all Flows will be called from this one thread. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ +class IOServiceThread; + +class FlowManager +{ +public: + FlowManager(); // throws FlowManagerException + virtual ~FlowManager(); + + // This API assumes that RTCP localBinding is always the same as RTP binding but add one to the port number + // We can add a new API in the future to accomodate, custom RTCP bindings as required + MediaStream* createMediaStream(MediaStreamHandler& mediaStreamHandler, + const StunTuple& localBinding, + bool rtcpEnabled = true, + MediaStream::NatTraversalMode natTraversalMode = MediaStream::NoNatTraversal, + const char* natTraversalServerHostname = 0, + unsigned short natTraversalServerPort = 0, + const char* stunUsername = 0, + const char* stunPassword = 0); + +#ifdef USE_SSL + void initializeDtlsFactory(const char* certAor); + dtls::DtlsFactory* getDtlsFactory() { return mDtlsFactory; } +#endif //USE_SSL + +protected: + +private: + static void srtpEventHandler(srtp_event_data_t *data); + + // Member variables used to manager asio io service thread + asio::io_service mIOService; + IOServiceThread* mIOServiceThread; + asio::io_service::work* mIOServiceWork; +#ifdef USE_SSL + static int createCert (const resip::Data& pAor, int expireDays, int keyLen, X509*& outCert, EVP_PKEY*& outKey ); + asio::ssl::context mSslContext; +#endif + +#ifdef USE_SSL + X509* mClientCert; + EVP_PKEY* mClientKey; + dtls::DtlsFactory* mDtlsFactory; +#endif +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/FlowManagerException.hxx b/src/libs/resiprocate/reflow/FlowManagerException.hxx new file mode 100644 index 00000000..311247d4 --- /dev/null +++ b/src/libs/resiprocate/reflow/FlowManagerException.hxx @@ -0,0 +1,57 @@ +#if !defined(FlowManagerException_hxx) +#define FlowManagerException_hxx + +#include <rutil/BaseException.hxx> + +/** + This class is used to raise exceptions in the flow manager. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class FlowManagerException : public resip::BaseException +{ +public: + FlowManagerException(const resip::Data& msg, const resip::Data& file, const int line) + : resip::BaseException(msg, file, line) {} + + const char* name() const { return "FlowManagerException"; } +}; + + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/FlowManagerSubsystem.cxx b/src/libs/resiprocate/reflow/FlowManagerSubsystem.cxx new file mode 100644 index 00000000..c3cc4653 --- /dev/null +++ b/src/libs/resiprocate/reflow/FlowManagerSubsystem.cxx @@ -0,0 +1,39 @@ +#include "FlowManagerSubsystem.hxx" + +FlowManagerSubsystem FlowManagerSubsystem::FLOWMANAGER("FLOWMANAGER"); + + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/FlowManagerSubsystem.hxx b/src/libs/resiprocate/reflow/FlowManagerSubsystem.hxx new file mode 100644 index 00000000..2e296330 --- /dev/null +++ b/src/libs/resiprocate/reflow/FlowManagerSubsystem.hxx @@ -0,0 +1,61 @@ +#if !defined(FlowManagerSubsystem_hxx) +#define FlowManagerSubsystem_hxx + +#include <iostream> +#include <rutil/Subsystem.hxx> + +/** + This class is used in the logging subsystem to identify + logging messages generated from the FlowManager library. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class FlowManagerSubsystem : public resip::Subsystem +{ + public: + // Add new systems below + static FlowManagerSubsystem FLOWMANAGER; + + private: + explicit FlowManagerSubsystem(const char* rhs) : resip::Subsystem(rhs) {}; + explicit FlowManagerSubsystem(const resip::Data& rhs); + FlowManagerSubsystem& operator=(const resip::Data& rhs); +}; + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/Makefile b/src/libs/resiprocate/reflow/Makefile new file mode 100644 index 00000000..057e036d --- /dev/null +++ b/src/libs/resiprocate/reflow/Makefile @@ -0,0 +1,56 @@ +BUILD := ../build +include $(BUILD)/Makefile.pre + +PACKAGES += RETURNCLIENT ASIO RUTIL ARES OPENSSL SRTP BOOST PTHREAD +TARGET_LIBRARY = libreflow +CODE_SUBDIRS = dtls_wrapper + +SRC += \ + FakeSelectSocketDescriptor.cxx \ + Flow.cxx \ + FlowDtlsSocketContext.cxx \ + FlowDtlsTimerContext.cxx \ + FlowManager.cxx \ + FlowManagerSubsystem.cxx \ + MediaStream.cxx \ + dtls_wrapper/DtlsTimer.cxx \ + dtls_wrapper/DtlsSocket.cxx \ + dtls_wrapper/DtlsFactory.cxx \ + dtls_wrapper/bf_dwrap.c + +include $(BUILD)/Makefile.post + + +#################################################################### +# +# Copyright (c) 2007-2008, Plantronics, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of Plantronics nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#################################################################### diff --git a/src/libs/resiprocate/reflow/MediaStream.cxx b/src/libs/resiprocate/reflow/MediaStream.cxx new file mode 100644 index 00000000..3af21d49 --- /dev/null +++ b/src/libs/resiprocate/reflow/MediaStream.cxx @@ -0,0 +1,344 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/Timer.hxx> + +#include "FlowManagerSubsystem.hxx" +#include "FlowManager.hxx" +#include "MediaStream.hxx" + +using namespace flowmanager; +#ifdef USE_SSL +using namespace dtls; +#endif +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM FlowManagerSubsystem::FLOWMANAGER + +MediaStream::MediaStream(asio::io_service& ioService, +#ifdef USE_SSL + asio::ssl::context& sslContext, +#endif + MediaStreamHandler& mediaStreamHandler, + const StunTuple& localRtpBinding, + const StunTuple& localRtcpBinding, +#ifdef USE_SSL + DtlsFactory* dtlsFactory, +#endif + NatTraversalMode natTraversalMode, + const char* natTraversalServerHostname, + unsigned short natTraversalServerPort, + const char* stunUsername, + const char* stunPassword) : +#ifdef USE_SSL + mDtlsFactory(dtlsFactory), +#endif + mSRTPSessionInCreated(false), + mSRTPSessionOutCreated(false), + mNatTraversalMode(natTraversalMode), + mNatTraversalServerHostname(natTraversalServerHostname), + mNatTraversalServerPort(natTraversalServerPort), + mStunUsername(stunUsername), + mStunPassword(stunPassword), + mMediaStreamHandler(mediaStreamHandler) +{ + // Rtcp is enabled if localRtcpBinding transport type != None + mRtcpEnabled = localRtcpBinding.getTransportType() != StunTuple::None; + + if(mRtcpEnabled) + { + mRtpFlow = new Flow(ioService, +#ifdef USE_SSL + sslContext, +#endif + RTP_COMPONENT_ID, + localRtpBinding, + *this); + + mRtcpFlow = new Flow(ioService, +#ifdef USE_SSL + sslContext, +#endif + RTCP_COMPONENT_ID, + localRtcpBinding, + *this); + + mRtpFlow->activateFlow(StunMessage::PropsPortPair); + + // If doing an allocation then wait until RTP flow is allocated, then activate RTCP flow + if(natTraversalMode != TurnAllocation) + { + mRtcpFlow->activateFlow(); + } + } + else + { + mRtpFlow = new Flow(ioService, +#ifdef USE_SSL + sslContext, +#endif + RTP_COMPONENT_ID, + localRtpBinding, + *this); + mRtpFlow->activateFlow(StunMessage::PropsPortEven); + mRtcpFlow = 0; + } +} + +MediaStream::~MediaStream() +{ + { + Lock lock(mMutex); + + if(mSRTPSessionOutCreated) + { + mSRTPSessionOutCreated = false; + srtp_dealloc(mSRTPSessionOut); + } + if(mSRTPSessionInCreated) + { + mSRTPSessionInCreated = false; + srtp_dealloc(mSRTPSessionIn); + } + } + delete mRtpFlow; + if(mRtcpEnabled) + { + delete mRtcpFlow; + } +} + +bool +MediaStream::createOutboundSRTPSession(SrtpCryptoSuite cryptoSuite, const char* key, unsigned int keyLen) +{ + if(keyLen != SRTP_MASTER_KEY_LEN) + { + ErrLog(<< "Unable to create outbound SRTP session, invalid keyLen=" << keyLen); + return false; + } + + err_status_t status; + Lock lock(mMutex); + if(mSRTPSessionOutCreated) + { + // Check if settings are the same - if so just return true + if(cryptoSuite == mCryptoSuiteOut && memcmp(mSRTPMasterKeyOut, key, keyLen) == 0) + { + InfoLog(<< "Outbound SRTP session settings unchanged."); + return true; + } + else + { + InfoLog(<< "Re-creating outbound SRTP session with new settings."); + mSRTPSessionOutCreated = false; + srtp_dealloc(mSRTPSessionOut); + } + } + + // Copy key locally + memcpy(mSRTPMasterKeyOut, key, SRTP_MASTER_KEY_LEN); + + // load default srtp/srtcp policy settings + mCryptoSuiteOut = cryptoSuite; + switch(cryptoSuite) + { + case SRTP_AES_CM_128_HMAC_SHA1_80: + crypto_policy_set_aes_cm_128_hmac_sha1_80(&mSRTPPolicyOut.rtp); + crypto_policy_set_aes_cm_128_hmac_sha1_80(&mSRTPPolicyOut.rtcp); + break; + case SRTP_AES_CM_128_HMAC_SHA1_32: + crypto_policy_set_aes_cm_128_hmac_sha1_32(&mSRTPPolicyOut.rtp); + crypto_policy_set_aes_cm_128_hmac_sha1_32(&mSRTPPolicyOut.rtcp); + break; + default: + ErrLog(<< "Unable to create outbound SRTP session, invalid crypto suite=" << cryptoSuite); + return false; + } + + // set remaining policy settings + mSRTPPolicyOut.ssrc.type = ssrc_any_outbound; + mSRTPPolicyOut.key = mSRTPMasterKeyOut; + mSRTPPolicyOut.next = 0; + + // Allocate and initailize the SRTP sessions + status = srtp_create(&mSRTPSessionOut, &mSRTPPolicyOut); + if(status) + { + ErrLog(<< "Unable to create srtp out session, error code=" << status); + return false; + } + mSRTPSessionOutCreated = true; + + return true; +} + +bool +MediaStream::createInboundSRTPSession(SrtpCryptoSuite cryptoSuite, const char* key, unsigned int keyLen) +{ + if(keyLen != SRTP_MASTER_KEY_LEN) + { + ErrLog(<< "Unable to create inbound SRTP session, invalid keyLen=" << keyLen); + return false; + } + + err_status_t status; + Lock lock(mMutex); + if(mSRTPSessionInCreated) + { + // Check if settings are the same - if so just return true + if(cryptoSuite == mCryptoSuiteIn && memcmp(mSRTPMasterKeyIn, key, keyLen) == 0) + { + InfoLog(<< "Inbound SRTP session settings unchanged."); + return true; + } + else + { + InfoLog(<< "Re-creating inbound SRTP session with new settings."); + mSRTPSessionInCreated = false; + srtp_dealloc(mSRTPSessionIn); + } + } + + // Copy key locally + memcpy(mSRTPMasterKeyIn, key, SRTP_MASTER_KEY_LEN); + + // load default srtp/srtcp policy settings + mCryptoSuiteIn = cryptoSuite; + switch(cryptoSuite) + { + case SRTP_AES_CM_128_HMAC_SHA1_80: + crypto_policy_set_aes_cm_128_hmac_sha1_80(&mSRTPPolicyIn.rtp); + crypto_policy_set_aes_cm_128_hmac_sha1_80(&mSRTPPolicyIn.rtcp); + break; + case SRTP_AES_CM_128_HMAC_SHA1_32: + crypto_policy_set_aes_cm_128_hmac_sha1_32(&mSRTPPolicyIn.rtp); + crypto_policy_set_aes_cm_128_hmac_sha1_32(&mSRTPPolicyIn.rtcp); + break; + default: + ErrLog(<< "Unable to create inbound SRTP session, invalid crypto suite=" << cryptoSuite); + return false; + } + + // set remaining policy settings + mSRTPPolicyIn.ssrc.type = ssrc_any_inbound; + mSRTPPolicyIn.key = mSRTPMasterKeyIn; + mSRTPPolicyIn.next = 0; + + // Allocate and initailize the SRTP sessions + status = srtp_create(&mSRTPSessionIn, &mSRTPPolicyIn); + if(status) + { + ErrLog(<< "Unable to create srtp in session, error code=" << status); + return false; + } + mSRTPSessionInCreated = true; + + return true; +} + +err_status_t +MediaStream::srtpProtect(void* data, int* size, bool rtcp) +{ + Lock lock(mMutex); + err_status_t status = err_status_no_ctx; + if(mSRTPSessionOutCreated) + { + if(rtcp) + { + status = srtp_protect_rtcp(mSRTPSessionOut, data, size); + } + else + { + status = srtp_protect(mSRTPSessionOut, data, size); + } + } + return status; +} + +err_status_t +MediaStream::srtpUnprotect(void* data, int* size, bool rtcp) +{ + Lock lock(mMutex); + err_status_t status = err_status_no_ctx; + if(mSRTPSessionInCreated) + { + if(rtcp) + { + status = srtp_unprotect_rtcp(mSRTPSessionIn, data, size); + } + else + { + status = srtp_unprotect(mSRTPSessionIn, data, size); + } + } + return status; +} + +void +MediaStream::onFlowReady(unsigned int componentId) +{ + if(componentId == RTP_COMPONENT_ID && mNatTraversalMode == TurnAllocation && mRtcpFlow) + { + // RTP Flow is ready - we can now activate RTCP flow using the reservation token + mRtcpFlow->activateFlow(mRtpFlow->getReservationToken()); + } + else + { + if(mRtpFlow && mRtcpFlow) + { + if(mRtpFlow->isReady() && mRtcpFlow->isReady()) + { + mMediaStreamHandler.onMediaStreamReady(mRtpFlow->getSessionTuple(), mRtcpFlow->getSessionTuple()); + } + } + else if(mRtpFlow && mRtpFlow->isReady()) + { + mMediaStreamHandler.onMediaStreamReady(mRtpFlow->getSessionTuple(), StunTuple()); + } + } +} + +void +MediaStream::onFlowError(unsigned int componentId, unsigned int errorCode) +{ + mMediaStreamHandler.onMediaStreamError(errorCode); // TODO assign real error code +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/MediaStream.hxx b/src/libs/resiprocate/reflow/MediaStream.hxx new file mode 100644 index 00000000..49564dcd --- /dev/null +++ b/src/libs/resiprocate/reflow/MediaStream.hxx @@ -0,0 +1,165 @@ +#if !defined(MediaStream_hxx) +#define MediaStream_hxx + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <asio.hpp> +#ifdef USE_SSL +#include <asio/ssl.hpp> +#endif +#ifdef WIN32 +#include <srtp.h> +#else +#include <srtp/srtp.h> +#endif + +#include "dtls_wrapper/DtlsFactory.hxx" +#include "Flow.hxx" + +using namespace reTurn; + +namespace flowmanager +{ + +/** + This class represents a media stream, that consists of a series of componenets + or flows. For media streams based on RTP, there are two components per media + stream - one for RTP, and one for RTCP. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ +class MediaStreamHandler +{ +public: + MediaStreamHandler() {} + virtual ~MediaStreamHandler() {} + + virtual void onMediaStreamReady(const StunTuple& rtpTuple, const StunTuple& rtcpTuple) = 0; + virtual void onMediaStreamError(unsigned int errorCode) = 0; +}; + +#define RTP_COMPONENT_ID 1 +#define RTCP_COMPONENT_ID 2 + +class MediaStream +{ +public: + enum NatTraversalMode + { + NoNatTraversal, + StunBindDiscovery, + TurnAllocation + }; + + enum SrtpCryptoSuite + { + SRTP_AES_CM_128_HMAC_SHA1_32, + SRTP_AES_CM_128_HMAC_SHA1_80 + }; + + MediaStream(asio::io_service& ioService, +#ifdef USE_SSL + asio::ssl::context& sslContext, +#endif + MediaStreamHandler& mediaStreamHandler, + const StunTuple& localRtpBinding, + const StunTuple& localRtcpBinding, // pass in transport type = None to disable RTCP + #ifdef USE_SSL + dtls::DtlsFactory* dtlsFactory = 0, + #endif + NatTraversalMode natTraversalMode = NoNatTraversal, + const char* natTraversalServerHostname = 0, + unsigned short natTraversalServerPort = 0, + const char* stunUsername = 0, + const char* stunPassword = 0); + virtual ~MediaStream(); + + Flow* getRtpFlow() { return mRtpFlow; } + Flow* getRtcpFlow() { return mRtcpFlow; } + + // SRTP methods - should be called before sending or receiving on RTP or RTCP flows + bool createOutboundSRTPSession(SrtpCryptoSuite cryptoSuite, const char* key, unsigned int keyLen); + bool createInboundSRTPSession(SrtpCryptoSuite cryptoSuite, const char* key, unsigned int keyLen); + +protected: + friend class Flow; + + // SRTP members +#ifdef USE_SSL + dtls::DtlsFactory* mDtlsFactory; +#endif + volatile bool mSRTPSessionInCreated; + volatile bool mSRTPSessionOutCreated; + resip::Mutex mMutex; + SrtpCryptoSuite mCryptoSuiteIn; + SrtpCryptoSuite mCryptoSuiteOut; + uint8_t mSRTPMasterKeyIn[SRTP_MASTER_KEY_LEN]; + uint8_t mSRTPMasterKeyOut[SRTP_MASTER_KEY_LEN]; + srtp_policy_t mSRTPPolicyIn; + srtp_policy_t mSRTPPolicyOut; + srtp_t mSRTPSessionIn; + srtp_t mSRTPSessionOut; + + err_status_t srtpProtect(void* data, int* size, bool rtcp); + err_status_t srtpUnprotect(void* data, int* size, bool rtcp); + + // Nat Traversal Members + NatTraversalMode mNatTraversalMode; + resip::Data mNatTraversalServerHostname; + unsigned short mNatTraversalServerPort; + resip::Data mStunUsername; + resip::Data mStunPassword; + +private: + // Note: these member variables are set at creation time and never changed, thus + // they do not require mutex protection + MediaStreamHandler& mMediaStreamHandler; + bool mRtcpEnabled; + + Flow* mRtpFlow; + Flow* mRtcpFlow; + + virtual void onFlowReady(unsigned int componentId); + virtual void onFlowError(unsigned int componentId, unsigned int errorCode); +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/ReadMe.txt b/src/libs/resiprocate/reflow/ReadMe.txt new file mode 100644 index 00000000..3c777b54 --- /dev/null +++ b/src/libs/resiprocate/reflow/ReadMe.txt @@ -0,0 +1,163 @@ +reflow (FlowManager) +==================== + +The flow manager is a layer that faciltates the flow of media to/from a media based application. +It is responsible for any NAT traversal logic, and will eventually implement ICE as a Nat +traversal solution. + +Currently the Flow Manager allows NAT traversal via static configuration only. + +An application should create one instance of the FlowManager object. Once an application +determines that an audio media stream is needed it uses the following API call on the +FlowManager object to create a MediaStream object. + + MediaStream* createMediaStream(MediaStreamHandler& mediaStreamHandler, + const StunTuple& localBinding, + bool rtcpEnabled = true, + Flow::NatTraversalMode natTraversalMode = Flow::NoNatTraversal, + const char* natTraversalServerHostname = 0, + unsigned short natTraversalServerPort = 0, + const char* stunUsername = 0, + const char* stunPassword = 0); + +Possible NatTraversalModes are: + +NoNatTraveral - just send media to/from localBinding + +StunBindDiscovery - send STUN bind request to stun server specified and fire an event when + discovered reflexive mapping is retrieved + +TurnUdpAllocation - send a TURN allocation request via UDP to the turn server specified and + fire an event when the allocation is complete and allocated address is + known + +TurnTcpAllocation - send a TURN allocation request via TCP to the turn server specified and + fire an event when the allocation is complete and allocated address is + known - this allows us to tunnel media via TCP to the TURN server which + is relayed via UDP to the peer + +TurnTlsAllocation - send a TURN allocation request via TLS to the turn server specified and + fire an event when the allocation is complete and allocated address is + known - this allows us to tunnel media via TCP to the TURN server which + is relayed via UDP to the peer + +MediaStreamHandler class passed in will receive event notifications: + + virtual void onMediaStreamReady(const StunTuple& rtpTuple, const StunTuple& rtcpTuple) = 0; + virtual void onMediaStreamError(unsigned int errorCode) = 0; + + + +Each created Media Stream consists of one or two flows, depending on whether RTCP is enabled +or not. The Flow objects can be obtained from the MediaStream via the following MediaStream +API's: + + Flow* getRtpFlow(); + Flow* getRtcpFlow(); + + +Each Flow can then be used to send/receive media after the onMediaStreamReady callback has +been received. The following Flow API's are available: + + bool isReady(); // will return true after onMediaStreamReady callback has fired + + /// Returns a socket descriptor that can be used in a select call + /// WARNING - this descriptor should not be used for any other purpose + /// - do NOT set socket options, or send, receive from this descriptor, + /// instead use the Flow api's + unsigned int getSelectSocketDescriptor(); + unsigned int getSocketDescriptor(); // returns the real socket descriptor - can be used to + // correlate callbacks + + /// Turn Send Methods + void send(const char* buffer, unsigned int size); + void sendTo(const asio::ip::address& address, unsigned short port, const char* buffer, + unsigned int size); + + /// Receive Methods + asio::error_code receive(char* buffer, unsigned int& size, unsigned int timeout, + asio::ip::address* sourceAddress=0, unsigned short* sourcePort=0); + asio::error_code receiveFrom(const asio::ip::address& address, unsigned short port, + char* buffer, unsigned int& size, unsigned int timeout); + + /// Used to set where this flow should be sending to + void setActiveDestination(const char* address, unsigned short port); + + const StunTuple& getLocalTuple(); + StunTuple getSessionTuple(); // returns either local, reflexive, or relay tuple depending + // on NatTraversalMode + StunTuple getRelayTuple(); + StunTuple getReflexiveTuple(); + + + +Using SRTP support in FlowManager +--------------------------------- + +DTLS-SRTP Support +----------------- + +FlowManager::initializeDtlsFactory must be called during application +initialization by passing in an AOR to use in the automatically generated +client certificate that may be used with dtls-srtp. + +The following API's on the Flow object are then used to control dtls-srtp: + /// Starts the dtls client handshake process - (must call setActiveDestination first) + /// Call this method if this client has negotiated the "Active" role via SDP + void startDtlsClient(const char* address, unsigned short port); + + /// This method should be called when remote fingerprint is discovered + /// via SDP negotiation. After this is called only dtls-srtp connections + /// with a matching fingerprint will be maintained. + void setRemoteSDPFingerprint(const resip::Data& fingerprint); + + +SDES SRTP Support +----------------- + +If using SDES srtp key negotiation, then the following two API's on the +MediaStream object are used in order to initialize the SRTP sessions before +sending or receiving on the RTP or RTCP flows. + + bool createOutboundSRTPSession(SrtpCryptoSuite cryptoSuite, const char* key, unsigned int keyLen); + bool createInboundSRTPSession(SrtpCryptoSuite cryptoSuite, const char* key, unsigned int keyLen); + + + +License +------- + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/DtlsFactory.cxx b/src/libs/resiprocate/reflow/dtls_wrapper/DtlsFactory.cxx new file mode 100644 index 00000000..2ec2130a --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/DtlsFactory.cxx @@ -0,0 +1,136 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_SSL + +#include <cassert> +#include <iostream> +#include <rutil/ssl/OpenSSLInit.hxx> + +#include <openssl/e_os2.h> +#include <openssl/rand.h> +#include <openssl/err.h> +#include <openssl/crypto.h> +#include <openssl/ssl.h> + +#include "DtlsFactory.hxx" +#include "DtlsSocket.hxx" + +using namespace dtls; +const char* DtlsFactory::DefaultSrtpProfile = "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32"; + +DtlsFactory::DtlsFactory(std::auto_ptr<DtlsTimerContext> tc,X509 *cert, EVP_PKEY *privkey): + mTimerContext(tc), + mCert(cert) +{ + int r; + + mContext=SSL_CTX_new(DTLSv1_method()); + assert(mContext); + + r=SSL_CTX_use_certificate(mContext, cert); + assert(r==1); + + r=SSL_CTX_use_PrivateKey(mContext, privkey); + assert(r==1); + + // Set SRTP profiles + r=SSL_CTX_set_tlsext_use_srtp(mContext, DefaultSrtpProfile); + assert(r==0); +} + +DtlsFactory::~DtlsFactory() +{ + SSL_CTX_free(mContext); +} + + +DtlsSocket* +DtlsFactory::createClient(std::auto_ptr<DtlsSocketContext> context) +{ + return new DtlsSocket(context,this,DtlsSocket::Client); +} + +DtlsSocket* +DtlsFactory::createServer(std::auto_ptr<DtlsSocketContext> context) +{ + return new DtlsSocket(context,this,DtlsSocket::Server); +} + +void +DtlsFactory::getMyCertFingerprint(char *fingerprint) +{ + DtlsSocket::computeFingerprint(mCert,fingerprint); +} + +void +DtlsFactory::setSrtpProfiles(const char *str) +{ + int r; + + r=SSL_CTX_set_tlsext_use_srtp(mContext,str); + + assert(r==0); +} + +void +DtlsFactory::setCipherSuites(const char *str) +{ + int r; + + r=SSL_CTX_set_cipher_list(mContext,str); + assert(r==1); +} + +DtlsFactory::PacketType +DtlsFactory::demuxPacket(const unsigned char *data, unsigned int len) +{ + assert(len>=1); + + if((data[0]==0) || (data[0]==1)) + return stun; + if((data[0]>=128) && (data[0]<=191)) + return rtp; + if((data[0]>=20) && (data[0]<=64)) + return dtls; + + return unknown; +} + +#endif //USE_SSL + + +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/DtlsFactory.hxx b/src/libs/resiprocate/reflow/dtls_wrapper/DtlsFactory.hxx new file mode 100644 index 00000000..fcaedd38 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/DtlsFactory.hxx @@ -0,0 +1,103 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_SSL + +#ifndef DtlsFactory_hxx +#define DtlsFactory_hxx + +#include <memory> +#include "DtlsTimer.hxx" + +typedef struct x509_st X509; +typedef struct ssl_ctx_st SSL_CTX; +typedef struct evp_pkey_st EVP_PKEY; + +namespace dtls +{ +class DtlsSocket; +class DtlsSocketContext; +class DtlsTimerContext; + +//Not threadsafe. Timers must fire in the same thread as dtls processing. +class DtlsFactory +{ + public: + enum PacketType { rtp, dtls, stun, unknown}; + + // Creates a DTLS SSL Context and enables srtp extension, also sets the private and public key cert + DtlsFactory(std::auto_ptr<DtlsTimerContext> tc, X509 *cert, EVP_PKEY *privkey); + + // Note: this orphans any DtlsSockets you were stupid enough + // not to free + ~DtlsFactory(); + + // Creates a new DtlsSocket to be used as a client + DtlsSocket* createClient(std::auto_ptr<DtlsSocketContext> context); + + // Creates a new DtlsSocket to be used as a server + DtlsSocket* createServer(std::auto_ptr<DtlsSocketContext> context); + + // Returns the fingerprint of the user cert that was passed into the constructor + void getMyCertFingerprint(char *fingerprint); + + // Returns a reference to the timer context that was passed into the constructor + DtlsTimerContext& getTimerContext() {return *mTimerContext;} + + // The default SrtpProfile used at construction time (default is: SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32) + static const char* DefaultSrtpProfile; + + // Changes the default SRTP profiles supported (default is: SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32) + void setSrtpProfiles(const char *policyStr); + + // Changes the default DTLS Cipher Suites supported + void setCipherSuites(const char *cipherSuites); + + // Examines the first few bits of a packet to determine its type: rtp, dtls, stun or unknown + static PacketType demuxPacket(const unsigned char *buf, unsigned int len); + +private: + friend class DtlsSocket; + SSL_CTX* mContext; + std::auto_ptr<DtlsTimerContext> mTimerContext; + X509 *mCert; +}; + +} +#endif + +#endif +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/DtlsSocket.cxx b/src/libs/resiprocate/reflow/dtls_wrapper/DtlsSocket.cxx new file mode 100644 index 00000000..643ecee2 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/DtlsSocket.cxx @@ -0,0 +1,421 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_SSL + +#include <iostream> +#include <cassert> +#include <string.h> + +#include "DtlsFactory.hxx" +#include "DtlsSocket.hxx" +#include "bf_dwrap.h" +using namespace std; +using namespace dtls; + +// Our local timers +class dtls::DtlsSocketTimer : public DtlsTimer +{ + public: + DtlsSocketTimer(unsigned int seq,DtlsSocket *socket): DtlsTimer(seq),mSocket(socket){} + ~DtlsSocketTimer() + { + } + + void expired() + { + mSocket->expired(this); + } + private: + DtlsSocket *mSocket; +}; + +int dummy_cb(int d, X509_STORE_CTX *x) +{ + return 1; +} + +DtlsSocket::DtlsSocket(std::auto_ptr<DtlsSocketContext> socketContext, DtlsFactory* factory, enum SocketType type): + mSocketContext(socketContext), + mFactory(factory), + mReadTimer(0), + mSocketType(type), + mHandshakeCompleted(false) +{ + mSocketContext->setDtlsSocket(this); + + assert(factory->mContext); + mSsl=SSL_new(factory->mContext); + assert(mSsl!=0); + + switch(type) + { + case Client: + SSL_set_connect_state(mSsl); + break; + case Server: + SSL_set_accept_state(mSsl); + SSL_set_verify(mSsl,SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, dummy_cb); + break; + default: + assert(0); + } + + mInBio=BIO_new(BIO_f_dwrap()); + BIO_push(mInBio,BIO_new(BIO_s_mem())); + + mOutBio=BIO_new(BIO_f_dwrap()); + BIO_push(mOutBio,BIO_new(BIO_s_mem())); + + SSL_set_bio(mSsl,mInBio,mOutBio); +} + +DtlsSocket::~DtlsSocket() +{ + if(mReadTimer) mReadTimer->invalidate(); + + // Properly shutdown the socket and free it - note: this also free's the BIO's + SSL_shutdown(mSsl); + SSL_free(mSsl); +} + +void +DtlsSocket::expired(DtlsSocketTimer* timer) +{ + forceRetransmit(); + //delete timer; + + //assert(timer == mReadTimer); + //mReadTimer = 0; +} + +void +DtlsSocket::startClient() +{ + assert(mSocketType == Client); + + doHandshakeIteration(); +} + +bool +DtlsSocket::handlePacketMaybe(const unsigned char* bytes, unsigned int len) +{ + DtlsFactory::PacketType pType=DtlsFactory::demuxPacket(bytes,len); + + if(pType!=DtlsFactory::dtls) + return false; + + int r; + BIO_reset(mInBio); + BIO_reset(mOutBio); + + r=BIO_write(mInBio,bytes,len); + assert(r==(int)len); // Can't happen + + // Note: we must catch any below exceptions--if there are any + doHandshakeIteration(); + + return true; +} + +void +DtlsSocket::forceRetransmit() +{ + BIO_reset(mInBio); + BIO_reset(mOutBio); + BIO_ctrl(mInBio,BIO_CTRL_DGRAM_SET_RECV_TIMEOUT,0,0); + + doHandshakeIteration(); +} + +void +DtlsSocket::doHandshakeIteration() +{ + int r; + char errbuf[1024]; + int sslerr; + + if(mHandshakeCompleted) + return; + + r=SSL_do_handshake(mSsl); + errbuf[0]=0; + ERR_error_string_n(ERR_peek_error(),errbuf,sizeof(errbuf)); + + // See what was written + int outBioLen; + unsigned char *outBioData; + outBioLen=BIO_get_mem_data(mOutBio,&outBioData); + + // Now handle handshake errors */ + switch(sslerr=SSL_get_error(mSsl,r)) + { + case SSL_ERROR_NONE: + mHandshakeCompleted = true; + mSocketContext->handshakeCompleted(); + if(mReadTimer) mReadTimer->invalidate(); + mReadTimer = 0; + break; + case SSL_ERROR_WANT_READ: + // There are two cases here: + // (1) We didn't get enough data. In this case we leave the + // timers alone and wait for more packets. + // (2) We did get a full flight and then handled it, but then + // wrote some more message and now we need to flush them + // to the network and now reset the timers + // + // If data was written then this means we got a complete + // something or a retransmit so we need to reset the timer + if(outBioLen) + { + if(mReadTimer) mReadTimer->invalidate(); + mReadTimer=new DtlsSocketTimer(0,this); + mFactory->mTimerContext->addTimer(mReadTimer,getReadTimeout()); + } + + break; + default: + cerr << "SSL error " << sslerr << endl; + + mSocketContext->handshakeFailed(errbuf); + // Note: need to fall through to propagate alerts, if any + break; + } + + // If mOutBio is now nonzero-length, then we need to write the + // data to the network. TODO: warning, MTU issues! + if(outBioLen) + { + //cerr << "Writing data: "; + //cerr.write((char*)outBioData, outBioLen); + //cerr << " length " << outBioLen << endl; + mSocketContext->write(outBioData,outBioLen); + } +} + +bool +DtlsSocket::getRemoteFingerprint(char *fprint) +{ + X509 *x; + + x=SSL_get_peer_certificate(mSsl); + if(!x) // No certificate + return false; + + computeFingerprint(x,fprint); + + return true; +} + +bool +DtlsSocket::checkFingerprint(const char* fingerprint, unsigned int len) +{ + char fprint[100]; + + if(getRemoteFingerprint(fprint)==false) + return false; + + // used to be strncasecmp + if(strncmp(fprint,fingerprint,len)){ + cerr << "Fingerprint mismatch, got " << fprint << "expecting " << fingerprint << endl; + return false; + } + + return true; +} + +void +DtlsSocket::getMyCertFingerprint(char *fingerprint) +{ + mFactory->getMyCertFingerprint(fingerprint); +} + +SrtpSessionKeys +DtlsSocket::getSrtpSessionKeys() +{ + //TODO: probably an exception candidate + assert(mHandshakeCompleted); + SrtpSessionKeys keys; + + memset(&keys, 0x00, sizeof(keys)); + + SSL_get_srtp_key_info(mSsl, + &keys.clientMasterKey, + &keys.clientMasterKeyLen, + &keys.serverMasterKey, + &keys.serverMasterKeyLen, + &keys.clientMasterSalt, + &keys.clientMasterSaltLen, + &keys.serverMasterSalt, + &keys.serverMasterSaltLen); + return keys; +} + +SRTP_PROTECTION_PROFILE* +DtlsSocket::getSrtpProfile() +{ + //TODO: probably an exception candidate + assert(mHandshakeCompleted); + return SSL_get_selected_srtp_profile(mSsl); +} + +// Fingerprint is assumed to be long enough +void +DtlsSocket::computeFingerprint(X509 *cert, char *fingerprint) +{ + unsigned char md[EVP_MAX_MD_SIZE]; + int r; + unsigned int i,n; + + r=X509_digest(cert,EVP_sha1(),md,&n); + assert(r==1); + + for(i=0;i<n;i++) + { + sprintf(fingerprint,"%02X",md[i]); + fingerprint+=2; + + if(i<(n-1)) + *fingerprint++=':'; + else + *fingerprint++=0; + } +} + +//TODO: assert(0) into exception, as elsewhere +void +DtlsSocket::createSrtpSessionPolicies(srtp_policy_t& outboundPolicy, srtp_policy_t& inboundPolicy) +{ + assert(mHandshakeCompleted); + + /* we assume that the default profile is in effect, for now */ + srtp_profile_t profile = srtp_profile_aes128_cm_sha1_80; + int key_len = srtp_profile_get_master_key_length(profile); + int salt_len = srtp_profile_get_master_salt_length(profile); + + /* get keys from srtp_key and initialize the inbound and outbound sessions */ + uint8_t *client_master_key_and_salt=new uint8_t[SRTP_MAX_KEY_LEN]; + uint8_t *server_master_key_and_salt=new uint8_t[SRTP_MAX_KEY_LEN]; + srtp_policy_t client_policy; + srtp_policy_t server_policy; + + SrtpSessionKeys srtp_key = getSrtpSessionKeys(); + /* set client_write key */ + client_policy.key = client_master_key_and_salt; + if (srtp_key.clientMasterKeyLen != key_len) + { + cout << "error: unexpected client key length" << endl; + assert(0); + } + if (srtp_key.clientMasterSaltLen != salt_len) + { + cout << "error: unexpected client salt length" << endl; + assert(0); + } + + memcpy(client_master_key_and_salt, srtp_key.clientMasterKey, key_len); + memcpy(client_master_key_and_salt + key_len, srtp_key.clientMasterSalt, salt_len); + + //cout << "client master key and salt: " << + // octet_string_hex_string(client_master_key_and_salt, key_len + salt_len) << endl; + + /* initialize client SRTP policy from profile */ + err_status_t err = crypto_policy_set_from_profile_for_rtp(&client_policy.rtp, profile); + if (err) assert(0); + + err = crypto_policy_set_from_profile_for_rtcp(&client_policy.rtcp, profile); + if (err) assert(0); + client_policy.next = NULL; + + /* set server_write key */ + server_policy.key = server_master_key_and_salt; + + if (srtp_key.serverMasterKeyLen != key_len) + { + cout << "error: unexpected server key length" << endl; + assert(0); + } + if (srtp_key.serverMasterSaltLen != salt_len) + { + cout << "error: unexpected salt length" << endl; + assert(0); + } + + memcpy(server_master_key_and_salt, srtp_key.serverMasterKey, key_len); + memcpy(server_master_key_and_salt + key_len, srtp_key.serverMasterSalt, salt_len); + //cout << "server master key and salt: " << + // octet_string_hex_string(server_master_key_and_salt, key_len + salt_len) << endl; + + /* initialize server SRTP policy from profile */ + err = crypto_policy_set_from_profile_for_rtp(&server_policy.rtp, profile); + if (err) assert(0); + + err = crypto_policy_set_from_profile_for_rtcp(&server_policy.rtcp, profile); + if (err) assert(0); + server_policy.next = NULL; + + if (mSocketType == Client) + { + client_policy.ssrc.type = ssrc_any_outbound; + outboundPolicy = client_policy; + + server_policy.ssrc.type = ssrc_any_inbound; + inboundPolicy = server_policy; + } + else + { + server_policy.ssrc.type = ssrc_any_outbound; + outboundPolicy = server_policy; + + client_policy.ssrc.type = ssrc_any_inbound; + inboundPolicy = client_policy; + } + /* zeroize the input keys (but not the srtp session keys that are in use) */ + //not done...not much of a security whole imho...the lifetime of these seems odd though + // memset(client_master_key_and_salt, 0x00, SRTP_MAX_KEY_LEN); + // memset(server_master_key_and_salt, 0x00, SRTP_MAX_KEY_LEN); + // memset(&srtp_key, 0x00, sizeof(srtp_key)); +} + +// Wrapper for currently nonexistent OpenSSL fxn +int +DtlsSocket::getReadTimeout() +{ + return 500; +} + +#endif +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/DtlsSocket.hxx b/src/libs/resiprocate/reflow/dtls_wrapper/DtlsSocket.hxx new file mode 100644 index 00000000..300512c1 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/DtlsSocket.hxx @@ -0,0 +1,177 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_SSL + +#ifndef DtlsSocket_hxx +#define DtlsSocket_hxx + +#include <memory> +extern "C" +{ +#ifdef WIN32 +#include <srtp.h> +#else +#include <srtp/srtp.h> +#endif +} + +#include <openssl/e_os2.h> +#include <openssl/rand.h> +#include <openssl/err.h> +#include <openssl/crypto.h> +#include <openssl/ssl.h> + +namespace dtls +{ +class DtlsFactory; +class DtlsSocket; +class DtlsTimer; + +class DtlsSocketContext +{ + public: + //memory is only valid for duration of callback; must be copied if queueing + //is required + virtual ~DtlsSocketContext(){} + virtual void write(const unsigned char* data, unsigned int len)=0; + virtual void handshakeCompleted()=0; + virtual void handshakeFailed(const char *err)=0; + + protected: + DtlsSocket *mSocket; + + private: + friend class DtlsSocket; + + void setDtlsSocket(DtlsSocket *sock) {mSocket=sock;} +}; + +class SrtpSessionKeys +{ + public: + unsigned char *clientMasterKey; + int clientMasterKeyLen; + unsigned char *serverMasterKey; + int serverMasterKeyLen; + unsigned char *clientMasterSalt; + int clientMasterSaltLen; + unsigned char *serverMasterSalt; + int serverMasterSaltLen; +}; + +class DtlsSocketTimer; + +class DtlsSocket +{ + public: + enum SocketType { Client, Server}; + ~DtlsSocket(); + + // Inspects packet to see if it's a DTLS packet, if so continue processing + bool handlePacketMaybe(const unsigned char* bytes, unsigned int len); + + // Called by DtlSocketTimer when timer expires - causes a retransmission (forceRetransmit) + void expired(DtlsSocketTimer*); + + // Retrieves the finger print of the certificate presented by the remote party + bool getRemoteFingerprint(char *fingerprint); + + // Retrieves the finger print of the certificate presented by the remote party and checks + // it agains the passed in certificate + bool checkFingerprint(const char* fingerprint, unsigned int len); + + // Retrieves the finger print of our local certificate, same as getMyCertFingerprint from DtlsFactory + void getMyCertFingerprint(char *fingerprint); + + // For client sockets only - causes a client handshake to start (doHandshakeIteration) + void startClient(); + + // Returns the socket type: Client or Server + SocketType getSocketType() {return mSocketType;} + + // Retreives the SRTP session keys from the Dtls session + SrtpSessionKeys getSrtpSessionKeys(); + + // Utility fn to compute a certificates fingerprint + static void computeFingerprint(X509 *cert, char *fingerprint); + + // Retrieves the DTLS negotiated SRTP profile - may return 0 if profile selection failed + SRTP_PROTECTION_PROFILE* getSrtpProfile(); + + // Creates SRTP session policies appropriately based on socket type (client vs server) and keys + // extracted from the DTLS handshake process + void createSrtpSessionPolicies(srtp_policy_t& outboundPolicy, srtp_policy_t& inboundPolicy); + + // returns true if the DTLS handshake has completed + bool handshakeCompleted() { return mHandshakeCompleted; } + + DtlsSocketContext* getSocketContext() { return mSocketContext.get(); } + + private: + friend class DtlsFactory; + + // Causes an immediate handshake iteration to happen, which will retransmit the handshake + void forceRetransmit(); + + // Creates an SSL socket, and if client sets state to connect_state and if server sets state to accept_state. Sets SSL BIO's. + DtlsSocket(std::auto_ptr<DtlsSocketContext> socketContext, DtlsFactory* factory, enum SocketType); + + // Give CPU cyces to the handshake process - checks current state and acts appropraitely + void doHandshakeIteration(); + + // returns the amount of time between handshake retranmssions (500ms) + int getReadTimeout(); + + // Internals + std::auto_ptr<DtlsSocketContext> mSocketContext; + DtlsFactory* mFactory; + DtlsTimer *mReadTimer; // Timer used during handshake process + + // OpenSSL context data + SSL *mSsl; + BIO *mInBio; + BIO *mOutBio; + + SocketType mSocketType; + bool mHandshakeCompleted; +}; + +} +#endif + +#endif +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/DtlsTimer.cxx b/src/libs/resiprocate/reflow/dtls_wrapper/DtlsTimer.cxx new file mode 100644 index 00000000..a6ee2ba0 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/DtlsTimer.cxx @@ -0,0 +1,75 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_SSL + +#include "DtlsTimer.hxx" + +using namespace dtls; + +DtlsTimer::DtlsTimer(unsigned int seq) +{ + mValid=true; +} + +DtlsTimer::~DtlsTimer() +{ +} + +void +DtlsTimer::fire() +{ + if(mValid) + { + expired(); + } + else + { + //memory mangement is overly tricky and possibly wrong...deleted by target + //if valid is the contract. weak pointers would help. + delete this; + } +} + +void +DtlsTimerContext::fire(DtlsTimer *timer) +{ + timer->fire(); +} + +#endif //USE_SSL + +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/DtlsTimer.hxx b/src/libs/resiprocate/reflow/dtls_wrapper/DtlsTimer.hxx new file mode 100644 index 00000000..37418727 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/DtlsTimer.hxx @@ -0,0 +1,78 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_SSL + +#ifndef DTLS_Timer_hxx +#define DTLS_Timer_hxx + +namespace dtls +{ + +class DtlsTimer +{ + public: + DtlsTimer(unsigned int seq); + virtual ~DtlsTimer(); + + virtual void expired()=0; + virtual void fire(); + unsigned int getSeq() { return mSeq; } + //invalid could call though to context and call an external cancel + void invalidate() { mValid = false; } + private: + unsigned int mSeq; + bool mValid; +}; + + +class DtlsTimerContext +{ + public: + virtual ~DtlsTimerContext() {} + virtual void addTimer(DtlsTimer* timer, unsigned int waitMs)=0; + //could add cancel here + protected: + void fire(DtlsTimer *timer); +}; + + +} + +#endif + +#endif +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/bf_dwrap.c b/src/libs/resiprocate/reflow/dtls_wrapper/bf_dwrap.c new file mode 100644 index 00000000..dffe4518 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/bf_dwrap.c @@ -0,0 +1,182 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_SSL + +#include <stdio.h> +#include <errno.h> +#include <openssl/bio.h> +#include <assert.h> +#include <memory.h> + +#define BIO_TYPE_DWRAP (50 | 0x0400 | 0x0200) + +static int dwrap_new(BIO *bio); +static int dwrap_free(BIO *a); +static int dwrap_read(BIO *b, char *out, int outl); +static int dwrap_write(BIO *b, const char *in, int inl); +static int dwrap_puts(BIO *b, const char *in); +static int dwrap_gets(BIO *b, char *buf, int size); +static long dwrap_ctrl(BIO *b, int cmd, long num, void *ptr); +static long dwrap_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp); + +static BIO_METHOD methods_dwrap= +{ + BIO_TYPE_DWRAP, + "dtls_wrapper", + dwrap_write, + dwrap_read, + dwrap_puts, + dwrap_gets, + dwrap_ctrl, + dwrap_new, + dwrap_free, + dwrap_callback_ctrl +}; + +typedef struct BIO_F_DWRAP_CTX_ +{ + int dgram_timer_exp; +} BIO_F_DWRAP_CTX; + + +BIO_METHOD *BIO_f_dwrap(void) +{ + return(&methods_dwrap); +} + +static int dwrap_new(BIO *bi) +{ + BIO_F_DWRAP_CTX *ctx=OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX)); + if(!ctx) return(0); + + memset(ctx,0,sizeof(BIO_F_BUFFER_CTX)); + + bi->init=1; + bi->ptr=(char *)ctx; + bi->flags=0; + + return 1; +} + +static int dwrap_free(BIO *a) +{ + if(a) return 0; + + free(a); + return 1; +} + +static int dwrap_read(BIO *b, char *out, int outl) +{ + int ret; + if(!b || !out) return 0; + + + BIO_clear_retry_flags(b); + + ret=BIO_read(b->next_bio,out,outl); + + if(ret<=0) + BIO_copy_next_retry(b); + + return ret; +} + +static int dwrap_write(BIO *b, const char *in, int inl) +{ + if(!b || !in || (inl<=0)) return 0; + + return BIO_write(b->next_bio,in,inl); +} + +static int dwrap_puts(BIO *b, const char *in) +{ + assert(0); + + return 0; +} + +static int dwrap_gets(BIO *b, char *buf, int size) +{ + assert(0); + + return 0; +} + +static long dwrap_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret; + BIO_F_DWRAP_CTX *ctx; + + ctx=b->ptr; + + switch(cmd){ + case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: + if(ctx->dgram_timer_exp){ + ret=1; + ctx->dgram_timer_exp=0; + } + else + ret=0; + break; + + /* Overloading this */ + case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: + ctx->dgram_timer_exp=1; + ret=1; + break; + default: + ret=BIO_ctrl(b->next_bio,cmd,num,ptr); + break; + } + + return ret; +} + +static long dwrap_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret; + + ret=BIO_callback_ctrl(b->next_bio,cmd,fp); + + return ret; +} + +#endif //USE_SSL + + +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/bf_dwrap.h b/src/libs/resiprocate/reflow/dtls_wrapper/bf_dwrap.h new file mode 100644 index 00000000..c610a256 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/bf_dwrap.h @@ -0,0 +1,45 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_SSL + +extern "C" +{ + BIO_METHOD *BIO_f_dwrap(void); +} + +#endif +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/CreateCert.cxx b/src/libs/resiprocate/reflow/dtls_wrapper/test/CreateCert.cxx new file mode 100644 index 00000000..90b5b339 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/CreateCert.cxx @@ -0,0 +1,123 @@ +#include "CreateCert.hxx" + +#include <openssl/x509.h> +#include <openssl/x509v3.h> + + +#include <string> +#include <rutil/Random.hxx> + +using namespace std; +using namespace dtls; +using namespace resip; + +int dtls::createCert (const resip::Data& pAor, int expireDays, int keyLen, X509*& outCert, EVP_PKEY*& outKey ) +{ + int ret; + + cerr << "Generating new user cert for " << pAor << endl; + Data aor = "sip:" + pAor; + + // Make sure that necessary algorithms exist: + assert(EVP_sha1()); + + RSA* rsa = RSA_generate_key(keyLen, RSA_F4, NULL, NULL); + assert(rsa); // couldn't make key pair + + EVP_PKEY* privkey = EVP_PKEY_new(); + assert(privkey); + ret = EVP_PKEY_set1_RSA(privkey, rsa); + assert(ret); + + X509* cert = X509_new(); + assert(cert); + + X509_NAME* subject = X509_NAME_new(); + X509_EXTENSION* ext = X509_EXTENSION_new(); + + // set version to X509v3 (starts from 0) + X509_set_version(cert, 2L); + + int serial = Random::getRandom(); // get an int worth of randomness + assert(sizeof(int)==4); + ASN1_INTEGER_set(X509_get_serialNumber(cert),serial); + +// ret = X509_NAME_add_entry_by_txt( subject, "O", MBSTRING_ASC, +// (unsigned char *) domain.data(), domain.size(), +// -1, 0); + assert(ret); + ret = X509_NAME_add_entry_by_txt( subject, "CN", MBSTRING_ASC, + (unsigned char *) aor.data(), aor.size(), + -1, 0); + assert(ret); + + ret = X509_set_issuer_name(cert, subject); + assert(ret); + ret = X509_set_subject_name(cert, subject); + assert(ret); + + const long duration = 60*60*24*expireDays; + X509_gmtime_adj(X509_get_notBefore(cert),0); + X509_gmtime_adj(X509_get_notAfter(cert), duration); + + ret = X509_set_pubkey(cert, privkey); + assert(ret); + + Data subjectAltNameStr = Data("URI:sip:") + aor + + Data(",URI:im:")+aor + + Data(",URI:pres:")+aor; + ext = X509V3_EXT_conf_nid( NULL , NULL , NID_subject_alt_name, + (char*) subjectAltNameStr.c_str() ); + X509_add_ext( cert, ext, -1); + X509_EXTENSION_free(ext); + + static char CA_FALSE[] = "CA:FALSE"; + ext = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints, CA_FALSE); + ret = X509_add_ext( cert, ext, -1); + assert(ret); + X509_EXTENSION_free(ext); + + // TODO add extensions NID_subject_key_identifier and NID_authority_key_identifier + + ret = X509_sign(cert, privkey, EVP_sha1()); + assert(ret); + + outCert = cert; + outKey = privkey; + return ret; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/CreateCert.hxx b/src/libs/resiprocate/reflow/dtls_wrapper/test/CreateCert.hxx new file mode 100644 index 00000000..3e543cfe --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/CreateCert.hxx @@ -0,0 +1,54 @@ +#ifndef DTLS_CreateCert_hxx +#define DTLS_CreateCert_hxx + +#include <openssl/crypto.h> +#include <openssl/ssl.h> + +namespace resip +{ +class Data; +} + +namespace dtls +{ + +int createCert (const resip::Data& pAor, int expireDays, int keyLen, X509*& outCert, EVP_PKEY*& outKey ); + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/Makefile b/src/libs/resiprocate/reflow/dtls_wrapper/test/Makefile new file mode 100644 index 00000000..fa72c8fd --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/Makefile @@ -0,0 +1,53 @@ +# $Id: Makefile,v 1.144 2004/05/18 01:40:48 jason Exp $ + +BUILD = ../../../build +include $(BUILD)/Makefile.pre + +PACKAGES += REFLOW RUTIL OPENSSL PTHREAD SRTP ARES +CXXFLAGS += -I../ + +SRC = CreateCert.cxx \ + TestDtlsUdp.cxx \ + TestTimerContext.cxx + +TESTPROGRAMS = \ + testDtlsWrapper.cxx \ + testDtlsClient.cxx \ + testDtlsServer.cxx + +include $(BUILD)/Makefile.post + + +#################################################################### +# +# Copyright (c) 2007-2008, Plantronics, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of Plantronics nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#################################################################### \ No newline at end of file diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/TestDtlsUdp.cxx b/src/libs/resiprocate/reflow/dtls_wrapper/test/TestDtlsUdp.cxx new file mode 100644 index 00000000..d0b99d3b --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/TestDtlsUdp.cxx @@ -0,0 +1,263 @@ + #include <iostream> + +#if !defined(WIN32) +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#endif + +#include <memory.h> + +#include <openssl/ssl.h> +#include <openssl/srtp.h> + +#include <rutil/Data.hxx> +#include <rutil/Socket.hxx> + +#include "DtlsFactory.hxx" +#include "DtlsSocket.hxx" +#include "CreateCert.hxx" +#include "TestDtlsUdp.hxx" + +extern "C" +{ +#include <srtp/srtp.h> +#include <srtp/srtp_priv.h> +} + +void DumpHexa2(const unsigned char* pInMsg, unsigned long ulInMsgLen, std::string &rOutDump) +{ + if(ulInMsgLen == 0 || NULL == pInMsg) + { + return; + } + + char tmp[5]; + const unsigned char* pp = pInMsg; + + rOutDump += "\n\n***new data*** length: "; + rOutDump += ulInMsgLen; + rOutDump += " dump: "; + + for (unsigned int z=0; z < ulInMsgLen; z++) + { + memset(tmp, 0, sizeof(tmp)); + sprintf(tmp, "%02X ",pp[z]); + pp++; + rOutDump += tmp; + } +} + +using namespace std; +using namespace dtls; +using namespace resip; + +TestDtlsUdpSocketContext::TestDtlsUdpSocketContext(int fd,sockaddr_in *peerAddr) +{ + mFd=fd; + memcpy(&mPeerAddr,peerAddr,sizeof(sockaddr_in)); +} + +void +TestDtlsUdpSocketContext::write(const unsigned char* data, unsigned int len) +{ + std::string cdata; + DumpHexa2(data, len, cdata); + +#if 0 + //FILE *f = fopen("c:\\testDtlsClient.txt", "a"); + //if(f) + //{ + // fprintf(f, cdata.c_str()); + // fclose(f); + //} + FILE *f = fopen("c:\\testDtlsClient_binary.txt", "ab"); + if(f) + { + fwrite(data, 1, len, f); + fclose(f); + } +#else + cout << cdata <<endl; +#endif + + int s = sendto(mFd, (const char*)data, len, 0, (const sockaddr *)&mPeerAddr, sizeof(struct sockaddr_in)); + + if ( s == SOCKET_ERROR ) + { + int e = errno; + switch (e) + { + case ECONNREFUSED: + case EHOSTDOWN: + case EHOSTUNREACH: + { + // quietly ignore this + } + break; + case EAFNOSUPPORT: + { + clog << "err EAFNOSUPPORT in send" << endl; + } + break; + default: + { + clog << "err " << e << " " << strerror(e) << " in send" << endl; + } + } + assert(0); + } + + if ( s == 0 ) + { + clog << "no data sent in send" << endl; + assert(0); + } + + cerr << "Wrote " << len << " bytes" << endl; +} + +void +TestDtlsUdpSocketContext::handshakeCompleted() +{ + char fprint[100]; + SRTP_PROTECTION_PROFILE *srtp_profile; + int r; + + cout << "Hey, amazing, it worked\n"; + + if(mSocket->getRemoteFingerprint(fprint)) + { + cout << "Remote fingerprint == " << fprint << endl; + } + srtp_profile=mSocket->getSrtpProfile(); + + if(srtp_profile) + { + cout <<"SRTP Extension negotiated profile="<<srtp_profile->name << endl; + } + + mSocket->createSrtpSessionPolicies(srtpPolicyIn,srtpPolicyOut); + + r=srtp_create(&srtpIn,&srtpPolicyIn); + assert(r==0); + r=srtp_create(&srtpOut,&srtpPolicyOut); + assert(r==0); + + useSrtp=true; + + cout << "Made SRTP policies\n"; + if(mSocket->getSocketType()==DtlsSocket::Client) + { + char *testData="test data"; + sendRtpData((const unsigned char *)testData,strlen(testData)+1); + + +#if defined(WIN32) + char *testData2="test bobo"; + sendRtpData((const unsigned char *)testData2,strlen(testData)+1); +#endif + } +} + +void +TestDtlsUdpSocketContext::handshakeFailed(const char *err) +{ + cout << "Bummer, handshake failure "<<err<<endl; +} + + +void +TestDtlsUdpSocketContext::sendRtpData(const unsigned char *data, unsigned int len) +{ + srtp_hdr_t *hdr; + unsigned char *ptr; + int l=0; + + cerr << "Sending RTP packet of length " << len << endl; + + ptr=(unsigned char *)malloc(sizeof(srtp_hdr_t)+len+SRTP_MAX_TRAILER_LEN+4); + assert(ptr!=0); + hdr=(srtp_hdr_t *)ptr; + ptr+=sizeof(srtp_hdr_t); + l+=sizeof(srtp_hdr_t); + + hdr->version = 2; /* RTP version two */ + hdr->p = 0; /* no padding needed */ + hdr->x = 0; /* no header extension */ + hdr->cc = 0; /* no CSRCs */ + hdr->m = 0; /* marker bit */ + hdr->pt = 0xf; /* payload type */ + hdr->seq = mRtpSeq++; /* sequence number */ + hdr->ts = htonl(0xdecafbad); /* timestamp */ + hdr->ssrc = htonl(ssrc); /* synch. source */ + + memcpy(ptr,data,len); + l+=len; + + if(useSrtp) + { + int r=srtp_protect(srtpOut,(unsigned char *)hdr,&l); + assert(r==0); + } + write((unsigned char *)hdr,l); +} + +void +TestDtlsUdpSocketContext::recvRtpData(unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int *outlen,unsigned int maxoutlen) +{ + srtp_hdr_t *hdr; + int len_int=(int)inlen; + hdr=(srtp_hdr_t *)in; + + if(useSrtp) + { + int r=srtp_unprotect(srtpIn,hdr,&len_int); + assert(r==0); + inlen=(unsigned int)len_int; + } + + in+=sizeof(srtp_hdr_t); + inlen-=sizeof(srtp_hdr_t); + + assert(inlen<maxoutlen); + memcpy(out,in,inlen); + *outlen=inlen; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/TestDtlsUdp.hxx b/src/libs/resiprocate/reflow/dtls_wrapper/test/TestDtlsUdp.hxx new file mode 100644 index 00000000..913c4a29 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/TestDtlsUdp.hxx @@ -0,0 +1,74 @@ +#ifndef testDtlsUdp_hxx +#define testDtlsUdp_hxx + +#include <memory> +#include "DtlsSocket.hxx" + +extern "C" +{ +#include <srtp/srtp.h> +} + +namespace dtls +{ + +class TestDtlsUdpSocketContext: public DtlsSocketContext { + public: + TestDtlsUdpSocketContext(int fd,struct sockaddr_in *peerAddr); + virtual ~TestDtlsUdpSocketContext(){}; + virtual void write(const unsigned char* data, unsigned int len); + virtual void handshakeCompleted(); + virtual void handshakeFailed(const char *err); + void sendRtpData(const unsigned char *data, unsigned int len); + void recvRtpData(unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int *outlen,unsigned int maxoutlen); + + private: + int mFd; + struct sockaddr_in mPeerAddr; + uint32_t ssrc; // TODO: initialize with something + srtp_policy_t srtpPolicyIn; + srtp_policy_t srtpPolicyOut; + srtp_t srtpIn; + srtp_t srtpOut; + bool useSrtp; + uint16_t mRtpSeq; // TODO: initialize with something +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/TestTimerContext.cxx b/src/libs/resiprocate/reflow/dtls_wrapper/test/TestTimerContext.cxx new file mode 100644 index 00000000..ca562854 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/TestTimerContext.cxx @@ -0,0 +1,96 @@ +#include <iostream> +#include "DtlsTimer.hxx" +#include "TestTimerContext.hxx" +#include "rutil/Timer.hxx" + +using namespace std; +using namespace dtls; +using namespace resip; + +TestTimerContext::TestTimerContext() +{ + mTimer=0; +} + +void +TestTimerContext::addTimer(DtlsTimer *timer, unsigned int lifetime) +{ + if(mTimer) + delete mTimer; + + mTimer=timer; + UInt64 timeMs=Timer::getTimeMs(); + mExpiryTime=timeMs+lifetime; + + cerr << "Setting a timer for " << lifetime << " ms from now" << endl; +} + +UInt64 +TestTimerContext::getRemainingTime() +{ + UInt64 timeMs=Timer::getTimeMs(); + + if(mTimer) + { + if(mExpiryTime<timeMs) + return(0); + + return(mExpiryTime-timeMs); + } + else + { + return Timer::getForever(); + } +} + +void +TestTimerContext::updateTimer() +{ + UInt64 timeMs=Timer::getTimeMs(); + + if(mTimer) + { + if(mExpiryTime<timeMs) + { + DtlsTimer *tmpTimer=mTimer; + mTimer=0; + + fire(tmpTimer); + } + } +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/TestTimerContext.hxx b/src/libs/resiprocate/reflow/dtls_wrapper/test/TestTimerContext.hxx new file mode 100644 index 00000000..e136e52c --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/TestTimerContext.hxx @@ -0,0 +1,56 @@ +// World's lamest timer implementation +#ifndef TestTimerContext_hxx +#define TestTimerContext_hxx + +#include "rutil/Timer.hxx" + +namespace dtls { + +class TestTimerContext: public DtlsTimerContext{ + public: + TestTimerContext(); + void addTimer(DtlsTimer *timer, unsigned int seq); + UInt64 getRemainingTime(); + void updateTimer(); + + DtlsTimer *mTimer; + UInt64 mExpiryTime; +}; + +} +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/dtls_wrapper_test_7_1.sln b/src/libs/resiprocate/reflow/dtls_wrapper/test/dtls_wrapper_test_7_1.sln new file mode 100644 index 00000000..3416d660 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/dtls_wrapper_test_7_1.sln @@ -0,0 +1,81 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testDtlsClient", "testDtlsClient_7_1.vcproj", "{44225649-C937-4BD8-A6AF-C53477BBD7F3}" + ProjectSection(ProjectDependencies) = postProject + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9} = {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9} + {D2AB531B-86AC-43DD-A330-9809B4F1BB53} = {D2AB531B-86AC-43DD-A330-9809B4F1BB53} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testDtlsServer", "testDtlsServer_7_1.vcproj", "{EBDC3586-55A6-442F-B779-7372FF7B0DE4}" + ProjectSection(ProjectDependencies) = postProject + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9} = {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9} + {D2AB531B-86AC-43DD-A330-9809B4F1BB53} = {D2AB531B-86AC-43DD-A330-9809B4F1BB53} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\..\..\rutil\rutil_7_1.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\..\..\contrib\ares\ares_7_1.vcproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reflow", "..\..\reflow_7_1.vcproj", "{D2AB531B-86AC-43DD-A330-9809B4F1BB53}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnClient", "..\..\..\reTurn\client\reTurnClient_7_1.vcproj", "{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libSRTP", "..\..\..\contrib\srtp\srtp7.vcproj", "{7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.Debug.ActiveCfg = Debug|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.Debug.Build.0 = Debug|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.Release.ActiveCfg = Release|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.Release.Build.0 = Release|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.Debug.ActiveCfg = Debug|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.Debug.Build.0 = Debug|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.Release.ActiveCfg = Release|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.Release.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release.Build.0 = SSL-Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release.Build.0 = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug.ActiveCfg = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug.Build.0 = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release.ActiveCfg = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release.Build.0 = Release|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Debug.ActiveCfg = Debug|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Debug.Build.0 = Debug|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Release.ActiveCfg = Release|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/dtls_wrapper_test_8_0.sln b/src/libs/resiprocate/reflow/dtls_wrapper/test/dtls_wrapper_test_8_0.sln new file mode 100644 index 00000000..d2751a22 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/dtls_wrapper_test_8_0.sln @@ -0,0 +1,157 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testDtlsClient", "testDtlsClient_8_0.vcproj", "{44225649-C937-4BD8-A6AF-C53477BBD7F3}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {D2AB531B-86AC-43DD-A330-9809B4F1BB53} = {D2AB531B-86AC-43DD-A330-9809B4F1BB53} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testDtlsServer", "testDtlsServer_8_0.vcproj", "{EBDC3586-55A6-442F-B779-7372FF7B0DE4}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {D2AB531B-86AC-43DD-A330-9809B4F1BB53} = {D2AB531B-86AC-43DD-A330-9809B4F1BB53} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\..\..\rutil\rutil_8_0.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\..\..\contrib\ares\ares_8_0.vcproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reflow", "..\..\reflow_8_0.vcproj", "{D2AB531B-86AC-43DD-A330-9809B4F1BB53}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "srtp", "..\..\..\contrib\srtp\srtp.vcproj", "{EEF031CB-FED8-451E-A471-91EC8D4F6750}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnClient", "..\..\..\reTurn\client\reTurnClient_8_0.vcproj", "{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug Dll|Win32 = Debug Dll|Win32 + Debug|Win32 = Debug|Win32 + Release Dll|Win32 = Release Dll|Win32 + Release|Win32 = Release|Win32 + SSL-Debug|Win32 = SSL-Debug|Win32 + SSL-Release|Win32 = SSL-Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.Debug Dll|Win32.ActiveCfg = Debug|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.Debug Dll|Win32.Build.0 = Debug|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.Debug|Win32.ActiveCfg = Debug|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.Debug|Win32.Build.0 = Debug|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.Release Dll|Win32.ActiveCfg = Release|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.Release Dll|Win32.Build.0 = Release|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.Release|Win32.ActiveCfg = Release|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.Release|Win32.Build.0 = Release|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {44225649-C937-4BD8-A6AF-C53477BBD7F3}.SSL-Release|Win32.Build.0 = Release|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.Debug Dll|Win32.ActiveCfg = Debug|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.Debug Dll|Win32.Build.0 = Debug|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.Debug|Win32.ActiveCfg = Debug|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.Debug|Win32.Build.0 = Debug|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.Release Dll|Win32.ActiveCfg = Release|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.Release Dll|Win32.Build.0 = Release|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.Release|Win32.ActiveCfg = Release|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.Release|Win32.Build.0 = Release|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {EBDC3586-55A6-442F-B779-7372FF7B0DE4}.SSL-Release|Win32.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug Dll|Win32.ActiveCfg = Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug Dll|Win32.Build.0 = Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release Dll|Win32.ActiveCfg = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release Dll|Win32.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.Build.0 = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug Dll|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug Dll|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release Dll|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release Dll|Win32.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.SSL-Release|Win32.Build.0 = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug Dll|Win32.ActiveCfg = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug Dll|Win32.Build.0 = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug|Win32.ActiveCfg = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug|Win32.Build.0 = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release Dll|Win32.ActiveCfg = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release Dll|Win32.Build.0 = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release|Win32.ActiveCfg = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release|Win32.Build.0 = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.SSL-Release|Win32.Build.0 = Release|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug Dll|Win32.ActiveCfg = Debug Dll|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug Dll|Win32.Build.0 = Debug Dll|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug|Win32.ActiveCfg = Debug|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug|Win32.Build.0 = Debug|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release Dll|Win32.ActiveCfg = Release Dll|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release Dll|Win32.Build.0 = Release Dll|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release|Win32.ActiveCfg = Release|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release|Win32.Build.0 = Release|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.SSL-Release|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug Dll|Win32.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug Dll|Win32.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release Dll|Win32.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release Dll|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsClient.cxx b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsClient.cxx new file mode 100644 index 00000000..b9449b07 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsClient.cxx @@ -0,0 +1,169 @@ +#include <iostream> + +#include <openssl/ssl.h> +#include <openssl/srtp.h> + +#include <rutil/Data.hxx> +#include <rutil/Socket.hxx> + +#include "DtlsFactory.hxx" +#include "DtlsSocket.hxx" +#include "TestTimerContext.hxx" +#include "TestDtlsUdp.hxx" +#include "CreateCert.hxx" + + +using namespace std; +using namespace dtls; +using namespace resip; + + +int main(int argc,char **argv) +{ + X509 *clientCert; + EVP_PKEY *clientKey; + + resip::initNetwork(); + srtp_init(); + + assert(argc==3); + + createCert(resip::Data("sip:client@example.com"),365,1024,clientCert,clientKey); + + TestTimerContext *ourTimer=new TestTimerContext(); + DtlsFactory *clientFactory=new DtlsFactory(std::auto_ptr<DtlsTimerContext>(ourTimer),clientCert,clientKey); + + cout << "Created the factory\n"; + + Socket fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if ( fd == -1 ) + { + assert(0); + } + + // Make the UDP socket context + char *host=argv[1]; + int port=atoi(argv[2]); + struct hostent *hp=gethostbyname(host); + struct sockaddr_in peer_addr; + assert(hp!=0); + memset(&peer_addr,0,sizeof(struct in_addr)); + peer_addr.sin_addr=*(struct in_addr*) + hp->h_addr_list[0]; + peer_addr.sin_family=AF_INET; + peer_addr.sin_port=htons(port); + + cout << "Made our UDP socket\n"; + + TestDtlsUdpSocketContext *sockContext=new TestDtlsUdpSocketContext(fd,&peer_addr); + + cout << "Made the socket context\n"; + + DtlsSocket *dtlsSocket=clientFactory->createClient(std::auto_ptr<DtlsSocketContext>(sockContext)); + + cout << "Made the DTLS socket\n"; + + // Now kick things off + dtlsSocket->startClient(); + + cout << "Sent first packet, entering wait loop\n"; + + while(1) + { + FdSet fdset; + unsigned char buffer[4096]; + struct sockaddr_in src; + socklen_t srclen; + int r; + + fdset.setRead(fd); +#if !defined(WIN32) + fdset.setRead(0); +#endif + + UInt64 towait=ourTimer->getRemainingTime(); + + // cerr << "Invoking select for time " << towait << endl; + + int toread=fdset.selectMilliSeconds(towait); + + ourTimer->updateTimer(); + + if(toread >=0) + { + if (fdset.readyToRead(0)) + { + char inbuf[1024]; + cin.getline(inbuf, 1024); + cout << "Read from stdin " << inbuf << endl; + sockContext->sendRtpData((const unsigned char *)inbuf,strlen(inbuf)); + } + if (fdset.readyToRead(fd)) + { + srclen=sizeof(src); + r=recvfrom(fd, reinterpret_cast<char*>(buffer), + sizeof(buffer), 0, (sockaddr *)&src,&srclen); + assert(r>=0); + + cerr << "Read bytes from peer, len = " << r << endl; + + switch(DtlsFactory::demuxPacket(buffer,r)) + { + case DtlsFactory::dtls: + dtlsSocket->handlePacketMaybe(buffer,r); + break; + case DtlsFactory::rtp: + unsigned char buf2[4096]; + unsigned int buf2l; + + // Read data + sockContext->recvRtpData(buffer,r,buf2,&buf2l,sizeof(buf2)); + + cout << "Read RTP data of length " << buf2l << endl; + cout.write(reinterpret_cast<char *>(buf2),buf2l); + cout << endl; + break; + default: + break; + } + } + } + } + + exit(0); +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsClient_7_1.vcproj b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsClient_7_1.vcproj new file mode 100644 index 00000000..99533b74 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsClient_7_1.vcproj @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="testDtlsClient" + ProjectGUID="{44225649-C937-4BD8-A6AF-C53477BBD7F3}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\contrib\openssl\inc32;..\..\..\contrib\srtp\include;..\..\..\contrib\srtp\crypto\include;..\;..\..\..\" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_SSL" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libeay32.lib ssleay32.lib Ws2_32.lib libsrtp.lib Iphlpapi.lib Dnsapi.lib rutil.lib" + OutputFile="$(OutDir)/testDtlsClient.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="..\..\..\contrib\openssl\out32.dbg;..\..\..\rutil\SSL-Debug;..\Debug;..\..\..\contrib\srtp\Debug" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/testDtlsClient.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\..\..\contrib\openssl\inc32;..\..\..\contrib\srtp\include;..\..\..\contrib\srtp\crypto\include;..\;..\..\..\" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libeay32.lib ssleay32.lib Ws2_32.lib libsrtp.lib Iphlpapi.lib Dnsapi.lib rutil.lib" + OutputFile="$(OutDir)/testDtlsClient.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="..\..\..\contrib\openssl\out32;..\..\..\rutil\SSL-Release;..\Debug;..\..\..\contrib\srtp\Release" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath=".\CreateCert.cxx"> + </File> + <File + RelativePath=".\testDtlsClient.cxx"> + </File> + <File + RelativePath=".\TestDtlsUdp.cxx"> + </File> + <File + RelativePath=".\TestTimerContext.cxx"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath=".\CreateCert.hxx"> + </File> + <File + RelativePath=".\TestDtlsUdp.hxx"> + </File> + <File + RelativePath=".\TestTimerContext.hxx"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsClient_8_0.vcproj b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsClient_8_0.vcproj new file mode 100644 index 00000000..18803435 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsClient_8_0.vcproj @@ -0,0 +1,231 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="testDtlsClient" + ProjectGUID="{44225649-C937-4BD8-A6AF-C53477BBD7F3}" + RootNamespace="testDtlsClient" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\contrib\openssl\inc32;..\..\..\contrib\srtp\include;..\..\..\contrib\srtp\crypto\include;..\;..\..\..\" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_SSL" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libeay32.lib ssleay32.lib Ws2_32.lib Iphlpapi.lib Dnsapi.lib libreflow.lib" + OutputFile="$(OutDir)/testDtlsClient.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="..\..\..\contrib\openssl\out32.dbg;..\..\Debug" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/testDtlsClient.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\..\..\contrib\openssl\inc32;..\..\..\contrib\srtp\include;..\..\..\contrib\srtp\crypto\include;..\;..\..\..\" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libeay32.lib ssleay32.lib Ws2_32.lib libsrtp.lib Iphlpapi.lib Dnsapi.lib rutil.lib" + OutputFile="$(OutDir)/testDtlsClient.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="..\..\..\contrib\openssl\out32;..\..\..\rutil\Release;..\Debug;..\..\..\contrib\srtp\Release" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\CreateCert.cxx" + > + </File> + <File + RelativePath=".\testDtlsClient.cxx" + > + </File> + <File + RelativePath=".\TestDtlsUdp.cxx" + > + </File> + <File + RelativePath=".\TestTimerContext.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\CreateCert.hxx" + > + </File> + <File + RelativePath=".\TestDtlsUdp.hxx" + > + </File> + <File + RelativePath=".\TestTimerContext.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsServer.cxx b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsServer.cxx new file mode 100644 index 00000000..038a3adb --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsServer.cxx @@ -0,0 +1,159 @@ +#include <ctype.h> +#include <iostream> + +#include <rutil/Data.hxx> +#include <rutil/Socket.hxx> +#include <openssl/ssl.h> +#include <openssl/srtp.h> + +#include "DtlsFactory.hxx" +#include "DtlsSocket.hxx" +#include "TestTimerContext.hxx" +#include "TestDtlsUdp.hxx" +#include "CreateCert.hxx" + +using namespace std; +using namespace dtls; +using namespace resip; + +int main(int argc,char **argv) +{ + X509 *serverCert; + EVP_PKEY *serverKey; + + resip::initNetwork(); + srtp_init(); + + assert(argc==2); + + createCert(resip::Data("sip:server@example.com"),365,1024,serverCert,serverKey); + + TestTimerContext *ourTimer=new TestTimerContext(); + DtlsFactory *serverFactory=new DtlsFactory(std::auto_ptr<DtlsTimerContext>(ourTimer),serverCert,serverKey); + + cout << "Created the factory\n"; + + Socket fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if ( fd == -1 ) + { + assert(0); + } + + // Make the UDP socket context + int port=atoi(argv[1]); + struct sockaddr_in myaddr; + memset((char*) &(myaddr),0, sizeof((myaddr))); + myaddr.sin_family = AF_INET; + myaddr.sin_addr.s_addr = htonl(INADDR_ANY); + myaddr.sin_port = htons(port); + int r=bind( fd,(struct sockaddr*)&myaddr, sizeof(myaddr)); + assert(r==0); + + cout << "Made our UDP socket\n"; + + cout << "Entering wait loop\n"; + TestDtlsUdpSocketContext *sockContext=0; + DtlsSocket *dtlsSocket; + + while(1) + { + FdSet fdset; + unsigned char buffer[4096]; + struct sockaddr_in src; + socklen_t srclen; + int r; + + fdset.setRead(fd); + + UInt64 towait=ourTimer->getRemainingTime(); + // cerr << "Invoking select for time " << towait << endl; + int toread=fdset.selectMilliSeconds(towait); + ourTimer->updateTimer(); + + if (toread >= 0) + { + if (fdset.readyToRead(fd)) + { + srclen=sizeof(src); + r=recvfrom(fd, (char*)buffer, sizeof(buffer), 0, (sockaddr *)&src,&srclen); + assert(r>=0); + + // The first packet initiates the association + if(!sockContext) + { + sockContext=new TestDtlsUdpSocketContext(fd,&src); + + cout << "Made the socket context\n"; + + dtlsSocket=serverFactory->createServer(std::auto_ptr<DtlsSocketContext>(sockContext)); + + cout << "Made the DTLS socket\n"; + } + + switch(DtlsFactory::demuxPacket(buffer,r)) + { + case DtlsFactory::dtls: + dtlsSocket->handlePacketMaybe(buffer,r); + break; + case DtlsFactory::rtp: + unsigned char buf2[4096]; + unsigned int buf2l; + + sockContext->recvRtpData(buffer,r,buf2,&buf2l,sizeof(buf2)); + + cout << "Read RTP data of length " << buf2l << endl; + cout << buf2 << endl; + + for(unsigned int i=0;i<buf2l;i++) + { + buf2[i]=toupper(buf2[i]); + } + + // Now echo it back + sockContext->sendRtpData((const unsigned char *)buf2,buf2l); + + break; + default: + break; + } + } + } + } + + exit(0); +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. None of the contributors names may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsServer_7_1.vcproj b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsServer_7_1.vcproj new file mode 100644 index 00000000..8812ce72 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsServer_7_1.vcproj @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="testDtlsServer" + ProjectGUID="{EBDC3586-55A6-442F-B779-7372FF7B0DE4}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\contrib\openssl\inc32;..\..\..\contrib\srtp\include;..\..\..\contrib\srtp\crypto\include;..\;..\..\..\" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_SSL" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libeay32.lib ssleay32.lib Ws2_32.lib libsrtp.lib Iphlpapi.lib Dnsapi.lib rutil.lib" + OutputFile="$(OutDir)/testDtlsServer.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="..\..\..\contrib\openssl\out32.dbg;..\..\..\rutil\SSL-Debug;..\Debug;..\..\..\contrib\srtp\Debug" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/dtls_wrapper_server_test.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\..\..\contrib\openssl\inc32;..\..\..\contrib\srtp\include;..\..\..\contrib\srtp\crypto\include;..\;..\..\..\" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="2" + UsePrecompiledHeader="3" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libeay32.lib ssleay32.lib Ws2_32.lib libsrtp.lib Iphlpapi.lib Dnsapi.lib rutil.lib" + OutputFile="$(OutDir)/dtls_wrapper_server_test.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="..\..\..\contrib\openssl\out32;..\..\..\rutil\SSL-Release;..\Debug;..\..\..\contrib\srtp\Release" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath=".\CreateCert.cxx"> + </File> + <File + RelativePath=".\testDtlsServer.cxx"> + </File> + <File + RelativePath=".\TestDtlsUdp.cxx"> + </File> + <File + RelativePath=".\TestTimerContext.cxx"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath=".\CreateCert.hxx"> + </File> + <File + RelativePath=".\TestDtlsUdp.hxx"> + </File> + <File + RelativePath=".\TestTimerContext.hxx"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsServer_8_0.vcproj b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsServer_8_0.vcproj new file mode 100644 index 00000000..06b216c4 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsServer_8_0.vcproj @@ -0,0 +1,231 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="testDtlsServer" + ProjectGUID="{EBDC3586-55A6-442F-B779-7372FF7B0DE4}" + RootNamespace="testDtlsServer" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\contrib\openssl\inc32;..\..\..\contrib\srtp\include;..\..\..\contrib\srtp\crypto\include;..\;..\..\..\" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_SSL" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libeay32.lib ssleay32.lib Ws2_32.lib libsrtp.lib Iphlpapi.lib Dnsapi.lib rutil.lib" + OutputFile="$(OutDir)/testDtlsServer.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="..\..\..\contrib\openssl\out32.dbg;..\..\..\rutil\SSL-Debug;..\Debug;..\..\..\contrib\srtp\Debug" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/dtls_wrapper_server_test.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\..\..\contrib\openssl\inc32;..\..\..\contrib\srtp\include;..\..\..\contrib\srtp\crypto\include;..\;..\..\..\" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="2" + UsePrecompiledHeader="2" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libeay32.lib ssleay32.lib Ws2_32.lib libsrtp.lib Iphlpapi.lib Dnsapi.lib rutil.lib" + OutputFile="$(OutDir)/dtls_wrapper_server_test.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="..\..\..\contrib\openssl\out32;..\..\..\rutil\SSL-Release;..\Debug;..\..\..\contrib\srtp\Release" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\CreateCert.cxx" + > + </File> + <File + RelativePath=".\testDtlsServer.cxx" + > + </File> + <File + RelativePath=".\TestDtlsUdp.cxx" + > + </File> + <File + RelativePath=".\TestTimerContext.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\CreateCert.hxx" + > + </File> + <File + RelativePath=".\TestDtlsUdp.hxx" + > + </File> + <File + RelativePath=".\TestTimerContext.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsWrapper.cxx b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsWrapper.cxx new file mode 100644 index 00000000..a13c9035 --- /dev/null +++ b/src/libs/resiprocate/reflow/dtls_wrapper/test/testDtlsWrapper.cxx @@ -0,0 +1,98 @@ +#include <iostream> + +#include "DtlsFactory.hxx" +#include "DtlsSocket.hxx" +#include "rutil/Data.hxx" +#include "CreateCert.hxx" +#include "TestTimerContext.hxx" +#include <openssl/srtp.h> + +using namespace std; +using namespace dtls; +using namespace resip; + +class TestDtlsSocketContext : public DtlsSocketContext +{ + public: + DtlsSocket *mOtherSocket; + char *mName; + + //memory is only valid for duration of callback; must be copied if queueing + //is required + TestDtlsSocketContext(char *name): + mName(name){} + + virtual ~TestDtlsSocketContext(){} + + virtual void write(const unsigned char* data, unsigned int len) + { + cout << mName << ": DTLS Wrapper called write...len = " << len << endl; + + // Discard data and force retransmit +// mSocket->forceRetransmit(); + mOtherSocket->handlePacketMaybe(data, len); + } + + virtual void handshakeCompleted() + { + char fprint[100]; + SRTP_PROTECTION_PROFILE *srtp_profile; + + cout << mName<< ": Hey, amazing, it worked\n"; + + if(mSocket->getRemoteFingerprint(fprint)){ + cout << mName << ": Remote fingerprint == " << fprint << endl; + + mOtherSocket->getMyCertFingerprint(fprint); + + bool check=mSocket->checkFingerprint(fprint,strlen(fprint)); + + cout << mName << ": Fingerprint check == " << check << endl; + } + else { + cout << mName << ": Peer did not authenticate" << endl; + } + + srtp_profile=mSocket->getSrtpProfile(); + + if(srtp_profile){ + cout << mName << ": SRTP Extension negotiated profile="<<srtp_profile->name << endl; + } + } + + virtual void handshakeFailed(const char *err) + { + cout << mName << ": Bummer, handshake failure "<<err<<endl; + } +}; + +int main(int argc,char **argv) +{ + SSL_library_init(); + SSL_load_error_strings(); + ERR_load_crypto_strings(); + srtp_init(); + + X509 *clientCert,*serverCert; + EVP_PKEY *clientKey,*serverKey; + + createCert(resip::Data("sip:client@example.com"),365,1024,clientCert,clientKey); + createCert(resip::Data("sip:server@example.com"),365,1024,serverCert,serverKey); + + DtlsFactory *clientFactory=new DtlsFactory(std::auto_ptr<DtlsTimerContext>(new TestTimerContext()),clientCert,clientKey); + DtlsFactory *serverFactory=new DtlsFactory(std::auto_ptr<DtlsTimerContext>(new TestTimerContext()),serverCert,serverKey); + + cout << "Created the factories\n"; + + TestDtlsSocketContext *clientContext=new TestDtlsSocketContext("Client"); + TestDtlsSocketContext *serverContext=new TestDtlsSocketContext("Server"); + + DtlsSocket *clientSocket=clientFactory->createClient(std::auto_ptr<DtlsSocketContext>(clientContext)); + DtlsSocket *serverSocket=serverFactory->createServer(std::auto_ptr<DtlsSocketContext>(serverContext)); + + clientContext->mOtherSocket=serverSocket; + serverContext->mOtherSocket=clientSocket; + + clientSocket->startClient(); +} + diff --git a/src/libs/resiprocate/reflow/reflow_7_1.vcproj b/src/libs/resiprocate/reflow/reflow_7_1.vcproj new file mode 100644 index 00000000..87486a1c --- /dev/null +++ b/src/libs/resiprocate/reflow/reflow_7_1.vcproj @@ -0,0 +1,194 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="reflow" + ProjectGUID="{D2AB531B-86AC-43DD-A330-9809B4F1BB53}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/..&quot;;&quot;$(ProjectDir)/../reTurn&quot;;&quot;$(ProjectDir)/../contrib/asio&quot;;&quot;$(ProjectDir)/../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../contrib/srtp/crypto/include&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_WIN32_WINNT=0x0501;USE_IPV6;USE_ARES;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="TRUE" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libreflow.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/..&quot;;&quot;$(ProjectDir)/../reTurn&quot;;&quot;$(ProjectDir)/../contrib/asio&quot;;&quot;$(ProjectDir)/../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../contrib/srtp/crypto/include&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WIN32_WINNT=0x0501;USE_ARES;BOOST_ALL_NO_LIB;USE_SSL;ASIO_ENABLE_CANCELIO" + RuntimeLibrary="2" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libreflow.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath=".\dtls_wrapper\bf_dwrap.c"> + </File> + <File + RelativePath=".\dtls_wrapper\DtlsFactory.cxx"> + </File> + <File + RelativePath=".\dtls_wrapper\DtlsSocket.cxx"> + </File> + <File + RelativePath=".\dtls_wrapper\DtlsTimer.cxx"> + </File> + <File + RelativePath=".\FakeSelectSocketDescriptor.cxx"> + </File> + <File + RelativePath=".\Flow.cxx"> + </File> + <File + RelativePath=".\FlowDtlsSocketContext.cxx"> + </File> + <File + RelativePath=".\FlowDtlsTimerContext.cxx"> + </File> + <File + RelativePath=".\FlowManager.cxx"> + </File> + <File + RelativePath=".\FlowManagerSubsystem.cxx"> + </File> + <File + RelativePath=".\MediaStream.cxx"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath=".\dtls_wrapper\bf_dwrap.h"> + </File> + <File + RelativePath=".\dtls_wrapper\DtlsFactory.hxx"> + </File> + <File + RelativePath=".\dtls_wrapper\DtlsSocket.hxx"> + </File> + <File + RelativePath=".\dtls_wrapper\DtlsTimer.hxx"> + </File> + <File + RelativePath=".\ErrorCode.hxx"> + </File> + <File + RelativePath=".\FakeSelectSocketDescriptor.hxx"> + </File> + <File + RelativePath=".\Flow.hxx"> + </File> + <File + RelativePath=".\FlowDtlsSocketContext.hxx"> + </File> + <File + RelativePath=".\FlowDtlsTimerContext.hxx"> + </File> + <File + RelativePath=".\FlowManager.hxx"> + </File> + <File + RelativePath=".\FlowManagerException.hxx"> + </File> + <File + RelativePath=".\FlowManagerSubsystem.hxx"> + </File> + <File + RelativePath=".\MediaStream.hxx"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + <File + RelativePath=".\ReadMe.txt"> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reflow/reflow_8_0.vcproj b/src/libs/resiprocate/reflow/reflow_8_0.vcproj new file mode 100644 index 00000000..2aed021f --- /dev/null +++ b/src/libs/resiprocate/reflow/reflow_8_0.vcproj @@ -0,0 +1,273 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="reflow" + ProjectGUID="{D2AB531B-86AC-43DD-A330-9809B4F1BB53}" + RootNamespace="reflow" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/..&quot;;&quot;$(ProjectDir)/../reTurn&quot;;&quot;$(ProjectDir)/../contrib/asio&quot;;&quot;$(ProjectDir)/../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../contrib/srtp/crypto/include&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_WIN32_WINNT=0x0501;USE_IPV6;USE_ARES;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libreflow.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/..&quot;;&quot;$(ProjectDir)/../reTurn&quot;;&quot;$(ProjectDir)/../contrib/asio&quot;;&quot;$(ProjectDir)/../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../contrib/srtp/crypto/include&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WIN32_WINNT=0x0501;USE_IPV6;USE_ARES;BOOST_ALL_NO_LIB;USE_SSL;ASIO_ENABLE_CANCELIO" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libreflow.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\dtls_wrapper\bf_dwrap.c" + > + </File> + <File + RelativePath=".\dtls_wrapper\DtlsFactory.cxx" + > + </File> + <File + RelativePath=".\dtls_wrapper\DtlsSocket.cxx" + > + </File> + <File + RelativePath=".\dtls_wrapper\DtlsTimer.cxx" + > + </File> + <File + RelativePath=".\FakeSelectSocketDescriptor.cxx" + > + </File> + <File + RelativePath=".\Flow.cxx" + > + </File> + <File + RelativePath=".\FlowDtlsSocketContext.cxx" + > + </File> + <File + RelativePath=".\FlowDtlsTimerContext.cxx" + > + </File> + <File + RelativePath=".\FlowManager.cxx" + > + </File> + <File + RelativePath=".\FlowManagerSubsystem.cxx" + > + </File> + <File + RelativePath=".\MediaStream.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\dtls_wrapper\bf_dwrap.h" + > + </File> + <File + RelativePath=".\dtls_wrapper\DtlsFactory.hxx" + > + </File> + <File + RelativePath=".\dtls_wrapper\DtlsSocket.hxx" + > + </File> + <File + RelativePath=".\dtls_wrapper\DtlsTimer.hxx" + > + </File> + <File + RelativePath=".\ErrorCode.hxx" + > + </File> + <File + RelativePath=".\FakeSelectSocketDescriptor.hxx" + > + </File> + <File + RelativePath=".\Flow.hxx" + > + </File> + <File + RelativePath=".\FlowDtlsSocketContext.hxx" + > + </File> + <File + RelativePath=".\FlowDtlsTimerContext.hxx" + > + </File> + <File + RelativePath=".\FlowManager.hxx" + > + </File> + <File + RelativePath=".\FlowManagerException.hxx" + > + </File> + <File + RelativePath=".\FlowManagerSubsystem.hxx" + > + </File> + <File + RelativePath=".\MediaStream.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <File + RelativePath=".\ReadMe.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/reflow/reflow_9_0.vcproj b/src/libs/resiprocate/reflow/reflow_9_0.vcproj new file mode 100644 index 00000000..28e4ad72 --- /dev/null +++ b/src/libs/resiprocate/reflow/reflow_9_0.vcproj @@ -0,0 +1,410 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="reflow" + ProjectGUID="{D2AB531B-86AC-43DD-A330-9809B4F1BB53}" + RootNamespace="reflow" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/..&quot;;&quot;$(ProjectDir)/../reTurn&quot;;&quot;$(ProjectDir)/../contrib/asio&quot;;&quot;$(ProjectDir)/../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../contrib/srtp/crypto/include&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_WIN32_WINNT=0x0501;USE_IPV6;USE_ARES;BOOST_ALL_NO_LIB;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libreflow.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/..&quot;;&quot;$(ProjectDir)/../reTurn&quot;;&quot;$(ProjectDir)/../contrib/asio&quot;;&quot;$(ProjectDir)/../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../contrib/srtp/crypto/include&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WIN32_WINNT=0x0501;USE_IPV6;USE_ARES;BOOST_ALL_NO_LIB;ASIO_ENABLE_CANCELIO" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libreflow.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/..&quot;;&quot;$(ProjectDir)/../reTurn&quot;;&quot;$(ProjectDir)/../contrib/asio&quot;;&quot;$(ProjectDir)/../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../contrib/srtp/crypto/include&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_WIN32_WINNT=0x0501;USE_IPV6;USE_ARES;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libreflow.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/..&quot;;&quot;$(ProjectDir)/../reTurn&quot;;&quot;$(ProjectDir)/../contrib/asio&quot;;&quot;$(ProjectDir)/../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../contrib/srtp/crypto/include&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WIN32_WINNT=0x0501;USE_IPV6;USE_ARES;BOOST_ALL_NO_LIB;USE_SSL;ASIO_ENABLE_CANCELIO" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libreflow.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\dtls_wrapper\bf_dwrap.c" + > + </File> + <File + RelativePath=".\dtls_wrapper\DtlsFactory.cxx" + > + </File> + <File + RelativePath=".\dtls_wrapper\DtlsSocket.cxx" + > + </File> + <File + RelativePath=".\dtls_wrapper\DtlsTimer.cxx" + > + </File> + <File + RelativePath=".\FakeSelectSocketDescriptor.cxx" + > + </File> + <File + RelativePath=".\Flow.cxx" + > + </File> + <File + RelativePath=".\FlowDtlsSocketContext.cxx" + > + </File> + <File + RelativePath=".\FlowDtlsTimerContext.cxx" + > + </File> + <File + RelativePath=".\FlowManager.cxx" + > + </File> + <File + RelativePath=".\FlowManagerSubsystem.cxx" + > + </File> + <File + RelativePath=".\MediaStream.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\dtls_wrapper\bf_dwrap.h" + > + </File> + <File + RelativePath=".\dtls_wrapper\DtlsFactory.hxx" + > + </File> + <File + RelativePath=".\dtls_wrapper\DtlsSocket.hxx" + > + </File> + <File + RelativePath=".\dtls_wrapper\DtlsTimer.hxx" + > + </File> + <File + RelativePath=".\ErrorCode.hxx" + > + </File> + <File + RelativePath=".\FakeSelectSocketDescriptor.hxx" + > + </File> + <File + RelativePath=".\Flow.hxx" + > + </File> + <File + RelativePath=".\FlowDtlsSocketContext.hxx" + > + </File> + <File + RelativePath=".\FlowDtlsTimerContext.hxx" + > + </File> + <File + RelativePath=".\FlowManager.hxx" + > + </File> + <File + RelativePath=".\FlowManagerException.hxx" + > + </File> + <File + RelativePath=".\FlowManagerSubsystem.hxx" + > + </File> + <File + RelativePath=".\MediaStream.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <File + RelativePath=".\ReadMe.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/repro/.cvsignore b/src/libs/resiprocate/repro/.cvsignore new file mode 100644 index 00000000..27117411 --- /dev/null +++ b/src/libs/resiprocate/repro/.cvsignore @@ -0,0 +1,21 @@ +.dependlibs +.gdb_history +bin.* +foo +genUsers +identity-in +identity-in-base64 +identity-in-hash +identity-in-rsa +obj.* +repro +repro +repro_acl.db +repro_config.db +repro_route.db +repro_user.db +userAdmin +Debug +Release +SSL-Debug +SSL-Release diff --git a/src/libs/resiprocate/repro/AbstractDb.cxx b/src/libs/resiprocate/repro/AbstractDb.cxx new file mode 100644 index 00000000..5445bb01 --- /dev/null +++ b/src/libs/resiprocate/repro/AbstractDb.cxx @@ -0,0 +1,934 @@ +#include <cassert> + +#include "rutil/Data.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/ParseBuffer.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/Logger.hxx" + + +#include "repro/UserStore.hxx" +#include "repro/AbstractDb.hxx" + + +using namespace resip; +using namespace repro; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +#define REPRO_DB_VERSION_USERS 3 + +static void +encodeString(oDataStream& s, const Data& data) +{ + short len = (short)data.size(); + s.write( (char*)(&len) , sizeof( len ) ); + s.write( data.data(), len ); +} + + +static void +decodeString(iDataStream& s, Data& data) +{ + data.clear(); + + if(s.eof()) return; + + short len; + s.read((char*)(&len), sizeof(len)); + if(s.eof()) return; + + // [TODO] This is probably OK for now, but we can do better than this. + if (len > 8192) + { + ErrLog( << "Tried to decode a database record that was much larger (>8k) than expected. Returning an empty Data instead." ); + return; + } + + s.read(data.getBuf(len), len); +} + + +AbstractDb::AbstractDb() +{ +} + + +AbstractDb::~AbstractDb() +{ +} + + +Data +AbstractDb::dbFirstKey(const AbstractDb::Table table) +{ + return dbNextKey(table,true/*first*/); +} + + +bool +AbstractDb::dbFirstRecord(const AbstractDb::Table table, + const Data& key, + Data& data, + bool forUpdate) +{ + return dbNextRecord(table, key, data, forUpdate, true/*first*/); +} + + +// Callback used by BerkeleyDb for secondary table support. Returns key to use in +// secondary database table +// secondaryKey should point to persistent data (ie. typically something from data itself) +int +AbstractDb::getSecondaryKey(const Table table, + const Key& key, + const Data& data, + void** secondaryKey, + unsigned int* secondaryKeyLen) +{ + if(table == SiloTable) + { + // Secondary Key for Silo table is DestUri + Data nonConstData(Data::Share, data.data(), data.size()); + iDataStream s(nonConstData); + + short version; + assert(sizeof(version) == 2); + s.read((char*)(&version), sizeof(version)); + assert(version == 1); + if (version == 1) + { + // DestUri is first element after version + short len; + s.read( (char*)(&len), sizeof(len)); + *secondaryKeyLen = (unsigned int)len; + *secondaryKey = (void*)(nonConstData.data() + (sizeof(version)+sizeof(len))); + return 0; + } + } + return -1; +} + + +void +AbstractDb::encodeUser(const UserRecord& rec, resip::Data& data) +{ + oDataStream s(data); + + short version = REPRO_DB_VERSION_USERS; + assert( sizeof( version) == 2 ); + s.write( (char*)(&version) , sizeof(version) ); + + encodeString( s, rec.user ); + encodeString( s, rec.domain); + encodeString( s, rec.realm); + encodeString( s, rec.passwordHash); + encodeString( s, rec.passwordHashAlt); + encodeString( s, rec.name); + encodeString( s, rec.email); + encodeString( s, rec.forwardAddress); + s.flush(); +} + +bool +AbstractDb::addUser( const AbstractDb::Key& key, const AbstractDb::UserRecord& rec ) +{ + assert( !key.empty() ); + + Data data; + encodeUser(rec, data); + + return dbWriteRecord(UserTable,key,data); +} + + +void +AbstractDb::eraseUser( const AbstractDb::Key& key ) +{ + dbEraseRecord( UserTable, key); +} + + +AbstractDb::UserRecord +AbstractDb::getUser( const AbstractDb::Key& key ) const +{ + AbstractDb::UserRecord rec; + Data data; + bool stat = dbReadRecord( UserTable, key, data ); + if ( !stat ) + { + return rec; + } + if ( data.empty() ) + { + return rec; + } + + iDataStream s(data); + + short version; + assert( sizeof(version) == 2 ); + s.read( (char*)(&version), sizeof(version) ); + + if ( version == REPRO_DB_VERSION_USERS ) + { + decodeString(s, rec.user); + decodeString(s, rec.domain); + decodeString(s, rec.realm); + decodeString(s, rec.passwordHash); + decodeString(s, rec.passwordHashAlt); + decodeString(s, rec.name); + decodeString(s, rec.email); + decodeString(s, rec.forwardAddress); + } + else if ( version == 2 ) + { + // We can read from the older version DB, but the entry + // will be written back in the new format with + // passwordHashAlt blank + decodeString(s, rec.user); + decodeString(s, rec.domain); + decodeString(s, rec.realm); + decodeString(s, rec.passwordHash); + decodeString(s, rec.name); + decodeString(s, rec.email); + decodeString(s, rec.forwardAddress); + rec.passwordHashAlt = Data::Empty; + } + else + { + // unknown version + ErrLog( <<"Data in user database with unknown version " << version ); + ErrLog( <<"record size is " << data.size() ); + } + + return rec; +} + + +Data +AbstractDb::getUserAuthInfo( const AbstractDb::Key& key ) const +{ + AbstractDb::UserRecord rec = getUser(key); + + return rec.passwordHash; +} + + +AbstractDb::Key +AbstractDb::firstUserKey() +{ + return dbFirstKey(UserTable); +} + + +AbstractDb::Key +AbstractDb::nextUserKey() +{ + return dbNextKey(UserTable); +} + + +void +AbstractDb::encodeRoute(const RouteRecord& rec, resip::Data& data) +{ + oDataStream s(data); + + short version=1; + assert( sizeof( version) == 2 ); + s.write( (char*)(&version) , sizeof(version) ); + + encodeString( s, rec.mMethod ); + encodeString( s, rec.mEvent ); + encodeString( s, rec.mMatchingPattern ); + encodeString( s, rec.mRewriteExpression ); + s.write( (char*)(&rec.mOrder) , sizeof( rec.mOrder ) ); + assert( sizeof( rec.mOrder) == 2 ); + + //!cj! TODO - add the extra local use only flag + + s.flush(); +} + + +bool +AbstractDb::addRoute( const AbstractDb::Key& key, + const AbstractDb::RouteRecord& rec ) +{ + assert( !key.empty() ); + + Data data; + encodeRoute(rec, data); + + return dbWriteRecord( RouteTable, key, data ); +} + + +void +AbstractDb::eraseRoute( const AbstractDb::Key& key ) +{ + dbEraseRecord (RouteTable, key); +} + + +AbstractDb::RouteRecord +AbstractDb::getRoute( const AbstractDb::Key& key) const +{ + AbstractDb::RouteRecord rec; + Data data; + bool stat = dbReadRecord( RouteTable, key, data ); + if ( !stat ) + { + return rec; + } + if ( data.empty() ) + { + return rec; + } + + iDataStream s(data); + + short version; + assert( sizeof(version) == 2 ); + s.read( (char*)(&version), sizeof(version) ); + + if ( version == 1 ) + { + decodeString(s, rec.mMethod); + decodeString(s, rec.mEvent); + decodeString(s, rec.mMatchingPattern); + decodeString(s, rec.mRewriteExpression); + s.read( (char*)(&rec.mOrder), sizeof(rec.mOrder) ); + assert( sizeof( rec.mOrder) == 2 ); + } + else + { + // unknown version + ErrLog( <<"Data in route database with unknown version " << version ); + ErrLog( <<"record size is " << data.size() ); + } + + return rec; +} + + +AbstractDb::RouteRecordList +AbstractDb::getAllRoutes() +{ + AbstractDb::RouteRecordList ret; + + AbstractDb::Key key = firstRouteKey(); + while ( !key.empty() ) + { + AbstractDb::RouteRecord rec = getRoute(key); + + ret.push_back(rec); + + key = nextRouteKey(); + } + + return ret; +} + + +AbstractDb::Key +AbstractDb::firstRouteKey() +{ + return dbFirstKey(RouteTable); +} + + +AbstractDb::Key +AbstractDb::nextRouteKey() +{ + return dbNextKey(RouteTable); +} + + +bool +AbstractDb::addAcl( const AbstractDb::Key& key, + const AbstractDb::AclRecord& rec ) +{ + assert( !key.empty() ); + + Data data; + { + oDataStream s(data); + + short version=1; + assert( sizeof( version) == 2 ); + s.write( (char*)(&version) , sizeof(version) ); + + encodeString( s, rec.mTlsPeerName ); + encodeString( s, rec.mAddress ); + s.write( (char*)(&rec.mMask) , sizeof( rec.mMask ) ); + s.write( (char*)(&rec.mPort) , sizeof( rec.mPort ) ); + s.write( (char*)(&rec.mFamily) , sizeof( rec.mFamily ) ); + s.write( (char*)(&rec.mTransport) , sizeof( rec.mTransport ) ); + + s.flush(); + } + + return dbWriteRecord( AclTable, key, data ); +} + + +void +AbstractDb::eraseAcl( const AbstractDb::Key& key ) +{ + dbEraseRecord (AclTable, key); +} + + +AbstractDb::AclRecord +AbstractDb::getAcl( const AbstractDb::Key& key) const +{ + AbstractDb::AclRecord rec; + Data data; + bool stat = dbReadRecord( AclTable, key, data ); + if ( !stat ) + { + return rec; + } + if ( data.empty() ) + { + return rec; + } + + iDataStream s(data); + + short version; + assert( sizeof(version) == 2 ); + s.read( (char*)(&version), sizeof(version) ); + + if ( version == 1 ) + { + decodeString(s, rec.mTlsPeerName); + decodeString(s, rec.mAddress); + s.read( (char*)(&rec.mMask), sizeof(rec.mMask) ); + s.read( (char*)(&rec.mPort), sizeof(rec.mPort) ); + s.read( (char*)(&rec.mFamily), sizeof(rec.mFamily) ); + s.read( (char*)(&rec.mTransport), sizeof(rec.mTransport) ); + } + else + { + // unknown version + ErrLog( <<"Data in ACL database with unknown version " << version ); + ErrLog( <<"record size is " << data.size() ); + } + + return rec; +} + + +AbstractDb::AclRecordList +AbstractDb::getAllAcls() +{ + AbstractDb::AclRecordList ret; + + AbstractDb::Key key = firstAclKey(); + while ( !key.empty() ) + { + AbstractDb::AclRecord rec = getAcl(key); + + ret.push_back(rec); + + key = nextAclKey(); + } + + return ret; +} + + +AbstractDb::Key +AbstractDb::firstAclKey() +{ + return dbFirstKey(AclTable); +} + + +AbstractDb::Key +AbstractDb::nextAclKey() +{ + return dbNextKey(AclTable); +} + + +bool +AbstractDb::addConfig( const AbstractDb::Key& key, + const AbstractDb::ConfigRecord& rec ) +{ + assert( !key.empty() ); + + Data data; + { + oDataStream s(data); + + short version=1; + assert( sizeof( version) == 2 ); + s.write( (char*)(&version) , sizeof(version) ); + + encodeString( s, rec.mDomain ); + s.write( (char*)(&rec.mTlsPort) , sizeof( rec.mTlsPort ) ); + assert( sizeof(rec.mTlsPort) == 2 ); + + s.flush(); + } + + return dbWriteRecord( ConfigTable, key, data ); +} + + +void +AbstractDb::eraseConfig( const AbstractDb::Key& key ) +{ + dbEraseRecord (ConfigTable, key); +} + + +AbstractDb::ConfigRecord +AbstractDb::getConfig( const AbstractDb::Key& key) const +{ + AbstractDb::ConfigRecord rec; + Data data; + bool stat = dbReadRecord( ConfigTable, key, data ); + if ( !stat ) + { + return rec; + } + if ( data.empty() ) + { + return rec; + } + + iDataStream s(data); + + short version; + assert( sizeof(version) == 2 ); + s.read( (char*)(&version), sizeof(version) ); + + if ( version == 1 ) + { + decodeString(s, rec.mDomain); + + s.read( (char*)(&rec.mTlsPort), sizeof(rec.mTlsPort) ); + assert( sizeof( rec.mTlsPort) == 2 ); + } + else + { + // unknown version + ErrLog( <<"Data in ACL database with unknown version " << version ); + ErrLog( <<"record size is " << data.size() ); + } + + return rec; +} + + +AbstractDb::ConfigRecordList +AbstractDb::getAllConfigs() +{ + AbstractDb::ConfigRecordList ret; + + AbstractDb::Key key = firstConfigKey(); + while ( !key.empty() ) + { + AbstractDb::ConfigRecord rec = getConfig(key); + + ret.push_back(rec); + + key = nextConfigKey(); + } + + return ret; +} + + +AbstractDb::Key +AbstractDb::firstConfigKey() +{ + return dbFirstKey(ConfigTable); +} + + +AbstractDb::Key +AbstractDb::nextConfigKey() +{ + return dbNextKey(ConfigTable); +} + + +bool +AbstractDb::addStaticReg( const AbstractDb::Key& key, + const AbstractDb::StaticRegRecord& rec ) +{ + assert( !key.empty() ); + + Data data; + { + oDataStream s(data); + + short version=1; + assert( sizeof( version) == 2 ); + s.write( (char*)(&version) , sizeof(version) ); + + encodeString( s, rec.mAor ); + encodeString( s, rec.mContact ); + encodeString( s, rec.mPath ); + + s.flush(); + } + + return dbWriteRecord( StaticRegTable, key, data ); +} + + +void +AbstractDb::eraseStaticReg( const AbstractDb::Key& key ) +{ + dbEraseRecord (StaticRegTable, key); +} + + +AbstractDb::StaticRegRecord +AbstractDb::getStaticReg( const AbstractDb::Key& key) const +{ + AbstractDb::StaticRegRecord rec; + Data data; + bool stat = dbReadRecord( StaticRegTable, key, data ); + if ( !stat ) + { + return rec; + } + if ( data.empty() ) + { + return rec; + } + + iDataStream s(data); + + short version; + assert( sizeof(version) == 2 ); + s.read( (char*)(&version), sizeof(version) ); + + if ( version == 1 ) + { + decodeString(s, rec.mAor); + decodeString(s, rec.mContact); + decodeString(s, rec.mPath); + } + else + { + // unknown version + ErrLog( <<"Data in StaticReg database with unknown version " << version ); + ErrLog( <<"record size is " << data.size() ); + } + + return rec; +} + + +AbstractDb::StaticRegRecordList +AbstractDb::getAllStaticRegs() +{ + AbstractDb::StaticRegRecordList ret; + + AbstractDb::Key key = firstStaticRegKey(); + while ( !key.empty() ) + { + AbstractDb::StaticRegRecord rec = getStaticReg(key); + + ret.push_back(rec); + + key = nextStaticRegKey(); + } + + return ret; +} + + +AbstractDb::Key +AbstractDb::firstStaticRegKey() +{ + return dbFirstKey(StaticRegTable); +} + + +AbstractDb::Key +AbstractDb::nextStaticRegKey() +{ + return dbNextKey(StaticRegTable); +} + + +void +AbstractDb::encodeFilter(const FilterRecord& rec, resip::Data& data) +{ + oDataStream s(data); + + short version=1; + assert(sizeof( version) == 2); + s.write((char*)(&version) , sizeof(version)); + + encodeString(s, rec.mCondition1Header); + encodeString(s, rec.mCondition1Regex); + encodeString(s, rec.mCondition2Header); + encodeString(s, rec.mCondition2Regex); + encodeString(s, rec.mMethod); + encodeString(s, rec.mEvent); + s.write((char*)(&rec.mAction), sizeof (rec.mAction)); + assert(sizeof(rec.mAction) == 2); + encodeString(s, rec.mActionData); + s.write((char*)(&rec.mOrder), sizeof(rec.mOrder)); + assert(sizeof(rec.mOrder) == 2); + + s.flush(); +} + + +bool +AbstractDb::addFilter(const AbstractDb::Key& key, + const AbstractDb::FilterRecord& rec) +{ + assert( !key.empty() ); + + Data data; + encodeFilter(rec, data); + return dbWriteRecord(FilterTable, key, data); +} + + +void +AbstractDb::eraseFilter(const AbstractDb::Key& key) +{ + dbEraseRecord(FilterTable, key); +} + + +AbstractDb::FilterRecord +AbstractDb::getFilter( const AbstractDb::Key& key) const +{ + AbstractDb::FilterRecord rec; + Data data; + bool stat = dbReadRecord(FilterTable, key, data); + if (!stat) + { + return rec; + } + if (data.empty()) + { + return rec; + } + + iDataStream s(data); + + short version; + assert(sizeof(version) == 2); + s.read((char*)(&version), sizeof(version)); + + if (version == 1) + { + decodeString(s, rec.mCondition1Header); + decodeString(s, rec.mCondition1Regex); + decodeString(s, rec.mCondition2Header); + decodeString(s, rec.mCondition2Regex); + decodeString(s, rec.mMethod); + decodeString(s, rec.mEvent); + s.read((char*)(&rec.mAction), sizeof(rec.mAction)); + assert(sizeof(rec.mAction) == 2); + decodeString(s, rec.mActionData); + s.read((char*)(&rec.mOrder), sizeof(rec.mOrder)); + assert(sizeof(rec.mOrder) == 2); + } + else + { + // unknown version + ErrLog( <<"Data in filter database with unknown version " << version ); + ErrLog( <<"record size is " << data.size() ); + } + + return rec; +} + + +AbstractDb::FilterRecordList +AbstractDb::getAllFilters() +{ + AbstractDb::FilterRecordList ret; + + AbstractDb::Key key = firstFilterKey(); + while ( !key.empty() ) + { + AbstractDb::FilterRecord rec = getFilter(key); + + ret.push_back(rec); + + key = nextFilterKey(); + } + + return ret; +} + + +AbstractDb::Key +AbstractDb::firstFilterKey() +{ + return dbFirstKey(FilterTable); +} + + +AbstractDb::Key +AbstractDb::nextFilterKey() +{ + return dbNextKey(FilterTable); +} + +bool +AbstractDb::addToSilo(const Key& key, const SiloRecord& rec) +{ + assert( !key.empty() ); + + Data data; + { + oDataStream s(data); + + short version=1; + assert(sizeof( version) == 2); + s.write((char*)(&version) , sizeof(version)); + + encodeString(s, rec.mDestUri); + encodeString(s, rec.mSourceUri); + s.write((char*)(&rec.mOriginalSentTime), sizeof (rec.mOriginalSentTime)); + assert(sizeof(rec.mOriginalSentTime) == 8); + encodeString(s, rec.mTid); + encodeString(s, rec.mMimeType); + encodeString(s, rec.mMessageBody); + + s.flush(); + } + return dbWriteRecord(SiloTable, key, data); +} + +void +AbstractDb::decodeSiloRecord(Data& data, SiloRecord& rec) +{ + iDataStream s(data); + + short version; + assert(sizeof(version) == 2); + s.read((char*)(&version), sizeof(version)); + + if (version == 1) + { + decodeString(s, rec.mDestUri); + decodeString(s, rec.mSourceUri); + s.read((char*)(&rec.mOriginalSentTime), sizeof(rec.mOriginalSentTime)); + assert(sizeof(rec.mOriginalSentTime) == 8); + decodeString(s, rec.mTid); + decodeString(s, rec.mMimeType); + decodeString(s, rec.mMessageBody); + } + else + { + // unknown version + ErrLog( <<"Data in silo database with unknown version " << version ); + ErrLog( <<"record size is " << data.size() ); + } +} + +bool +AbstractDb::getSiloRecords(const Key& skey, AbstractDb::SiloRecordList& recordList) +{ + AbstractDb::SiloRecord rec; + + Data data; + bool moreRecords = dbFirstRecord(SiloTable, skey, data, false /* forUpdate? */); + if(moreRecords) + { + // Decode and store data + decodeSiloRecord(data,rec); + recordList.push_back(rec); + while((moreRecords = dbNextRecord(SiloTable, skey, data, false /* forUpdate? */))) + { + // Decode and store data + decodeSiloRecord(data,rec); + recordList.push_back(rec); + } + } + + return true; +} + +void +AbstractDb::eraseSiloRecord(const Key& key) +{ + dbEraseRecord(SiloTable, key); +} + +void +AbstractDb::cleanupExpiredSiloRecords(UInt64 now, unsigned long expirationTime) +{ + AbstractDb::Key key = dbFirstKey(SiloTable); // Iterate on primary key + // Iterate through all silo records - retrieve Original send time embedded into the + // primary key and see if the record has expired. + Data originalSendTimeData; + UInt64 originalSendTime; + while(!key.empty()) + { + ParseBuffer pb(key); + const char* anchor = pb.position(); + pb.skipToChar(':'); + pb.data(originalSendTimeData, anchor); + originalSendTime = originalSendTimeData.convertUInt64(); + if((unsigned long)(now - originalSendTime) > expirationTime) + { + eraseSiloRecord(key); + } + key = dbNextKey(SiloTable); + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/AbstractDb.hxx b/src/libs/resiprocate/repro/AbstractDb.hxx new file mode 100644 index 00000000..6426663a --- /dev/null +++ b/src/libs/resiprocate/repro/AbstractDb.hxx @@ -0,0 +1,261 @@ +#if !defined(RESIP_ABSTRACTDB_HXX) +#define RESIP_ABSTRACTDB_HXX + +#include "rutil/Data.hxx" +#include "rutil/Fifo.hxx" +#include "resip/stack/Message.hxx" +#include <vector> + +namespace resip +{ + class TransactionUser; +} + +namespace repro +{ + +class AbstractDb +{ + public: + AbstractDb(); + virtual ~AbstractDb(); + + class UserRecord + { + public: + resip::Data user; + resip::Data domain; + resip::Data realm; + resip::Data passwordHash; + resip::Data passwordHashAlt; + resip::Data name; + resip::Data email; + resip::Data forwardAddress; + }; + + class RouteRecord + { + public: + resip::Data mMethod; + resip::Data mEvent; + resip::Data mMatchingPattern; + resip::Data mRewriteExpression; + short mOrder; + //bool mLocalUserOnly; + }; + + class AclRecord + { + public: + resip::Data mTlsPeerName; + resip::Data mAddress; + short mMask; + short mPort; + short mFamily; + short mTransport; + }; + + class ConfigRecord + { + public: + resip::Data mDomain; + short mTlsPort; + }; + + class StaticRegRecord + { + public: + resip::Data mAor; + resip::Data mContact; + resip::Data mPath; + }; + + class FilterRecord + { + public: + resip::Data mCondition1Header; + resip::Data mCondition1Regex; + resip::Data mCondition2Header; + resip::Data mCondition2Regex; + resip::Data mMethod; + resip::Data mEvent; + short mAction; // 0 - Accept, 1 - Reject, 2 - SQL Query + resip::Data mActionData; + short mOrder; + }; + + class SiloRecord + { + public: + resip::Data mDestUri; + resip::Data mSourceUri; + UInt64 mOriginalSentTime; + resip::Data mTid; + resip::Data mMimeType; + resip::Data mMessageBody; + }; + + typedef resip::Data Key; + typedef std::vector<RouteRecord> RouteRecordList; + typedef std::vector<AclRecord> AclRecordList; + typedef std::vector<ConfigRecord> ConfigRecordList; + typedef std::vector<StaticRegRecord> StaticRegRecordList; + typedef std::vector<FilterRecord> FilterRecordList; + typedef std::vector<SiloRecord> SiloRecordList; + + virtual bool isSane() = 0; + + // functions for User Records + virtual bool addUser(const Key& key, const UserRecord& rec); + virtual void eraseUser(const Key& key); + virtual UserRecord getUser(const Key& key) const; + virtual resip::Data getUserAuthInfo(const Key& key) const; + virtual Key firstUserKey();// return empty if no more + virtual Key nextUserKey(); // return empty if no more + + // functions for Route Records + virtual bool addRoute(const Key& key, const RouteRecord& rec); + virtual void eraseRoute(const Key& key); + virtual RouteRecord getRoute(const Key& key) const; + virtual RouteRecordList getAllRoutes(); + virtual Key firstRouteKey();// return empty if no more + virtual Key nextRouteKey(); // return empty if no more + + // functions for Acl Records + virtual bool addAcl(const Key& key, const AclRecord& rec); + virtual void eraseAcl(const Key& key); + virtual AclRecordList getAllAcls(); + virtual AclRecord getAcl(const Key& key) const; + virtual Key firstAclKey();// return empty if no more + virtual Key nextAclKey(); // return empty if no more + + // functions for Config Records + virtual bool addConfig(const Key& key, const ConfigRecord& rec); + virtual void eraseConfig(const Key& key); + virtual ConfigRecordList getAllConfigs(); + virtual ConfigRecord getConfig(const Key& key) const; + virtual Key firstConfigKey();// return empty if no more + virtual Key nextConfigKey(); // return empty if no more + + // functions for StaticReg Records + virtual bool addStaticReg(const Key& key, const StaticRegRecord& rec); + virtual void eraseStaticReg(const Key& key ); + virtual StaticRegRecordList getAllStaticRegs(); + virtual StaticRegRecord getStaticReg( const Key& key) const; + virtual Key firstStaticRegKey();// return empty if no more + virtual Key nextStaticRegKey(); // return empty if no more + + // functions for Filter Records + virtual bool addFilter(const Key& key, const FilterRecord& rec); + virtual void eraseFilter(const Key& key); + virtual FilterRecord getFilter(const Key& key) const; + virtual FilterRecordList getAllFilters(); + virtual Key firstFilterKey();// return empty if no more + virtual Key nextFilterKey(); // return empty if no more + + // functions for Silo Records + virtual bool addToSilo(const Key& key, const SiloRecord& rec); + virtual bool getSiloRecords(const Key& skey, SiloRecordList& recordList); + virtual void eraseSiloRecord(const Key& key); + virtual void cleanupExpiredSiloRecords(UInt64 now, unsigned long expirationTime); + + protected: + typedef enum + { + UserTable=0, + RouteTable, + AclTable, + ConfigTable, + StaticRegTable, + FilterTable, + SiloTable, + MaxTable // This one MUST be last + } Table; + + virtual int getSecondaryKey(const Table table, + const Key& key, + const resip::Data& data, + void** secondaryKey, + unsigned int* secondaryKeyLen); + + // Db manipulation routines + virtual bool dbWriteRecord(const Table table, + const resip::Data& key, + const resip::Data& data) =0; + /// return false if not found + virtual bool dbReadRecord(const Table table, + const resip::Data& key, + resip::Data& data) const =0; + virtual void dbEraseRecord(const Table table, + const resip::Data& key, + bool isSecondaryKey=false) =0; // allows deleting records from a table that supports secondary keying using a secondary key + virtual resip::Data dbFirstKey(const Table table); + virtual resip::Data dbNextKey(const Table table, + bool first=false) = 0; // return empty if no more + + // Methods for tables that allow duplicate keys + virtual bool dbFirstRecord(const Table table, + const resip::Data& key, + resip::Data& data, + bool forUpdate); + virtual bool dbNextRecord(const Table table, + const resip::Data& key, + resip::Data& data, + bool forUpdate, + bool first=false) = 0; // return false if no more + virtual bool dbBeginTransaction(const Table table) = 0; + virtual bool dbCommitTransaction(const Table table) = 0; + virtual bool dbRollbackTransaction(const Table table) = 0; + + virtual void encodeUser(const UserRecord& rec, resip::Data& buffer); + virtual void encodeRoute(const RouteRecord& rec, resip::Data& buffer); + virtual void encodeFilter(const FilterRecord& rec, resip::Data& buffer); + virtual void decodeSiloRecord(resip::Data& data, SiloRecord& rec); +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/AccountingCollector.cxx b/src/libs/resiprocate/repro/AccountingCollector.cxx new file mode 100644 index 00000000..895569ad --- /dev/null +++ b/src/libs/resiprocate/repro/AccountingCollector.cxx @@ -0,0 +1,759 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <iostream> + +// JSON library includes +#include "rutil/cajun/json/reader.h" +#include "rutil/cajun/json/writer.h" +#include "rutil/cajun/json/elements.h" + +#include "repro/AccountingCollector.hxx" +#include "repro/RequestContext.hxx" +#include "repro/ProxyConfig.hxx" +#include "repro/PersistentMessageQueue.hxx" +#include "resip/stack/Tuple.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Logger.hxx" + +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace json; +using namespace std; + +const static Data sessionEventQueueName = "sessioneventqueue"; +const static Data registrationEventQueueName = "regeventqueue"; + +AccountingCollector::AccountingCollector(ProxyConfig& config) : + mDbBaseDir(config.getConfigData("DatabasePath", "./", true)), + mSessionEventQueue(0), + mRegistrationEventQueue(0), + mSessionAccountingAddRoutingHeaders(config.getConfigBool("SessionAccountingAddRoutingHeaders", false)), + mSessionAccountingAddViaHeaders(config.getConfigBool("SessionAccountingAddViaHeaders", false)), + mRegistrationAccountingAddRoutingHeaders(config.getConfigBool("RegistrationAccountingAddRoutingHeaders", false)), + mRegistrationAccountingAddViaHeaders(config.getConfigBool("RegistrationAccountingAddViaHeaders", false)), + mRegistrationAccountingLogRefreshes(config.getConfigBool("RegistrationAccountingLogRefreshes", false)), + mFifo(0, 0) // not limited by time or size +{ + if(config.getConfigBool("SessionAccountingEnabled", false)) + { + if(!initializeEventQueue(SessionEventType)) + { + ErrLog(<< "AccountingCollector: cannot initialize session event queue!"); + } + } + if(config.getConfigBool("RegistrationAccountingEnabled", false)) + { + if(!initializeEventQueue(RegistrationEventType)) + { + ErrLog(<< "AccountingCollector: cannot initialize registration event queue!"); + } + } + + run(); // Start thread +} + +AccountingCollector::~AccountingCollector() +{ + // Shutdown thread and wait for it to complete + shutdown(); + join(); + + delete mSessionEventQueue; + delete mRegistrationEventQueue; +} + +void +AccountingCollector::doRegistrationAccounting(AccountingCollector::RegistrationEvent regevent, const resip::SipMessage& msg) +{ + assert(msg.isRequest()); + assert(msg.method() == REGISTER); + + if(regevent == RegistrationRefreshed && !mRegistrationAccountingLogRefreshes) + { + // if mRegistrationAccountingLogRefreshes is false then don't log refreshes + return; + } + + DateCategory datetime; + if(!msg.exists(h_CallId) || !msg.header(h_CallId).isWellFormed()) + { + ErrLog(<< "AccountingCollector::doRegistrationAccounting: missing proper callId header: " << msg); + return; + } + Object regEvent; + regEvent["EventId"] = Number(regevent); + switch(regevent) + { + case RegistrationAdded: + regEvent["EventName"] = String("Registration Added"); + break; + case RegistrationRefreshed: + regEvent["EventName"] = String("Registration Refreshed"); + break; + case RegistrationRemoved: + regEvent["EventName"] = String("Registration Removed"); + break; + case RegistrationRemovedAll: + regEvent["EventName"] = String("Registration Removed All"); + break; + } + regEvent["Datetime"] = String(Data::from(datetime).c_str()); + regEvent["CallId"] = String(msg.header(h_CallId).value().c_str()); + if(msg.exists(h_To) && msg.header(h_To).isWellFormed()) + { + if(!msg.header(h_To).displayName().empty()) + { + regEvent["User"]["DisplayName"] = String(msg.header(h_To).displayName().c_str()); + } + regEvent["User"]["Aor"] = String(Data::from(msg.header(h_To).uri().getAorAsUri(msg.getSource().getType())).c_str()); + } + if(msg.exists(h_From) && msg.header(h_From).isWellFormed()) + { + if(msg.header(h_From).uri() != msg.header(h_To).uri()) // Only log from is different from To + { + if(!msg.header(h_From).displayName().empty()) + { + regEvent["From"]["DisplayName"] = String(msg.header(h_From).displayName().c_str()); + } + regEvent["From"]["Uri"] = String(Data::from(msg.header(h_From).uri()).c_str()); + } + } + if(msg.exists(h_Contacts) && !msg.header(h_Contacts).empty()) + { + Array arrayContacts; + NameAddrs::const_iterator contactIt = msg.header(h_Contacts).begin(); + for(; contactIt != msg.header(h_Contacts).end(); contactIt++) + { + if(contactIt->isWellFormed()) + { + arrayContacts.Insert(String(Data::from(*contactIt).c_str())); + } + } + if(!arrayContacts.Empty()) + { + regEvent["Contacts"] = arrayContacts; + } + } + if(msg.exists(h_Expires) && msg.header(h_Expires).isWellFormed()) + { + regEvent["Expires"] = Number(msg.header(h_Expires).value()); + } + if(mRegistrationAccountingAddViaHeaders && + msg.exists(h_Vias) && !msg.header(h_Vias).empty()) + { + Array arrayVias; + Vias::const_iterator viaIt = msg.header(h_Vias).begin(); + for(; viaIt != msg.header(h_Vias).end(); viaIt++) + { + if(viaIt->isWellFormed()) + { + arrayVias.Insert(String(Data::from(*viaIt).c_str())); + } + } + if(!arrayVias.Empty()) + { + regEvent["Vias"] = arrayVias; + } + } + Tuple publicAddress = Helper::getClientPublicAddress(msg); + if(publicAddress.getType() != UNKNOWN_TRANSPORT) + { + regEvent["ClientPublicAddress"]["Transport"] = String(Tuple::toData(publicAddress.getType()).c_str()); + regEvent["ClientPublicAddress"]["IP"] = String(Tuple::inet_ntop(publicAddress).c_str()); + regEvent["ClientPublicAddress"]["Port"] = Number(publicAddress.getPort()); + } + if(mRegistrationAccountingAddRoutingHeaders && + msg.exists(h_Routes) && !msg.header(h_Routes).empty()) + { + Array arrayRoutes; + NameAddrs::const_iterator routeIt = msg.header(h_Routes).begin(); + for(; routeIt != msg.header(h_Routes).end(); routeIt++) + { + if(routeIt->isWellFormed()) + { + arrayRoutes.Insert(String(Data::from(*routeIt).c_str())); + } + } + if(!arrayRoutes.Empty()) + { + regEvent["Routes"] = arrayRoutes; + } + } + if(mRegistrationAccountingAddRoutingHeaders && + msg.exists(h_Paths) && !msg.header(h_Paths).empty()) + { + Array arrayPaths; + NameAddrs::const_iterator pathIt = msg.header(h_Paths).begin(); + for(; pathIt != msg.header(h_Paths).end(); pathIt++) + { + if(pathIt->isWellFormed()) + { + arrayPaths.Insert(String(Data::from(*pathIt).c_str())); + } + } + if(!arrayPaths.Empty()) + { + regEvent["Paths"] = arrayPaths; + } + } + if(msg.exists(h_UserAgent) && msg.header(h_UserAgent).isWellFormed()) + { + regEvent["UserAgent"] = String(msg.header(h_UserAgent).value().c_str()); + } + pushEventObjectToQueue(regEvent, RegistrationEventType); +} + +void +AccountingCollector::doSessionAccounting(const resip::SipMessage& msg, bool received, RequestContext& context) +{ + //DebugLog(<< "AccountingCollector::doSessionAccounting: " << msg.brief()); + if(msg.isRequest()) + { + if(msg.method() == INVITE && !msg.header(h_To).exists(p_tag)) + { + // Dialog creating INVITE + if(received) + { + // This came from the wire - so it is new session + DateCategory datetime; + if(!msg.exists(h_CallId) || !msg.header(h_CallId).isWellFormed()) + { + ErrLog(<< "AccountingCollector::doSessionAccounting: missing proper callId header: " << msg); + return; + } + Object sessionEvent; + sessionEvent["EventId"] = Number(SessionCreated); + sessionEvent["EventName"] = String("Session Created"); + sessionEvent["Datetime"] = String(Data::from(datetime).c_str()); + sessionEvent["CallId"] = String(msg.header(h_CallId).value().c_str()); + sessionEvent["RequestUri"] = String(Data::from(msg.header(h_RequestLine).uri()).c_str()); + if(msg.exists(h_To) && msg.header(h_To).isWellFormed()) + { + if(!msg.header(h_To).displayName().empty()) + { + sessionEvent["To"]["DisplayName"] = String(msg.header(h_To).displayName().c_str()); + } + sessionEvent["To"]["Uri"] = String(Data::from(msg.header(h_To).uri()).c_str()); + } + if(msg.exists(h_From) && msg.header(h_From).isWellFormed()) + { + if(!msg.header(h_From).displayName().empty()) + { + sessionEvent["From"]["DisplayName"] = String(msg.header(h_From).displayName().c_str()); + } + sessionEvent["From"]["Uri"] = String(Data::from(msg.header(h_From).uri()).c_str()); + } + if(msg.exists(h_Contacts) && !msg.header(h_Contacts).empty() && msg.header(h_Contacts).front().isWellFormed()) + { + sessionEvent["Contact"] = String(Data::from(msg.header(h_Contacts).front()).c_str()); + } + if(mSessionAccountingAddViaHeaders && + msg.exists(h_Vias) && !msg.header(h_Vias).empty()) + { + Array arrayVias; + Vias::const_iterator viaIt = msg.header(h_Vias).begin(); + for(; viaIt != msg.header(h_Vias).end(); viaIt++) + { + if(viaIt->isWellFormed()) + { + arrayVias.Insert(String(Data::from(*viaIt).c_str())); + } + } + if(!arrayVias.Empty()) + { + sessionEvent["Vias"] = arrayVias; + } + } + Tuple publicAddress = Helper::getClientPublicAddress(msg); + if(publicAddress.getType() != UNKNOWN_TRANSPORT) + { + sessionEvent["ClientPublicAddress"]["Transport"] = String(Tuple::toData(publicAddress.getType()).c_str()); + sessionEvent["ClientPublicAddress"]["IP"] = String(Tuple::inet_ntop(publicAddress).c_str()); + sessionEvent["ClientPublicAddress"]["Port"] = Number(publicAddress.getPort()); + } + if(mSessionAccountingAddRoutingHeaders && + msg.exists(h_Routes) && !msg.header(h_Routes).empty()) + { + Array arrayRoutes; + NameAddrs::const_iterator routeIt = msg.header(h_Routes).begin(); + for(; routeIt != msg.header(h_Routes).end(); routeIt++) + { + if(routeIt->isWellFormed()) + { + arrayRoutes.Insert(String(Data::from(*routeIt).c_str())); + } + } + if(!arrayRoutes.Empty()) + { + sessionEvent["Routes"] = arrayRoutes; + } + } + if(mSessionAccountingAddRoutingHeaders && + msg.exists(h_RecordRoutes) && !msg.header(h_RecordRoutes).empty()) + { + Array arrayRecordRoutes; + NameAddrs::const_iterator recordRouteIt = msg.header(h_RecordRoutes).begin(); + for(; recordRouteIt != msg.header(h_RecordRoutes).end(); recordRouteIt++) + { + if(recordRouteIt->isWellFormed()) + { + arrayRecordRoutes.Insert(String(Data::from(*recordRouteIt).c_str())); + } + } + if(!arrayRecordRoutes.Empty()) + { + sessionEvent["RecordRoutes"] = arrayRecordRoutes; + } + } + if(msg.exists(h_UserAgent) && msg.header(h_UserAgent).isWellFormed()) + { + sessionEvent["UserAgent"] = String(msg.header(h_UserAgent).value().c_str()); + } + context.setSessionCreatedEventSent(); + pushEventObjectToQueue(sessionEvent, SessionEventType); + } + else + { + // This is being forwarded to a target + DateCategory datetime; + if(!msg.exists(h_CallId) || !msg.header(h_CallId).isWellFormed()) + { + ErrLog(<< "AccountingCollector::doSessionAccounting: missing proper callId header: " << msg); + return; + } + Object sessionEvent; + sessionEvent["EventId"] = Number(SessionRouted); + sessionEvent["EventName"] = String("Session Routed"); + sessionEvent["Datetime"] = String(Data::from(datetime).c_str()); + sessionEvent["CallId"] = String(msg.header(h_CallId).value().c_str()); + sessionEvent["TargetUri"] = String(Data::from(msg.header(h_RequestLine).uri()).c_str()); + if(mSessionAccountingAddRoutingHeaders && + msg.exists(h_Routes) && !msg.header(h_Routes).empty()) + { + Array arrayRoutes; + NameAddrs::const_iterator routeIt = msg.header(h_Routes).begin(); + for(; routeIt != msg.header(h_Routes).end(); routeIt++) + { + if(routeIt->isWellFormed()) + { + arrayRoutes.Insert(String(Data::from(*routeIt).c_str())); + } + } + if(!arrayRoutes.Empty()) + { + sessionEvent["Routes"] = arrayRoutes; + } + } + pushEventObjectToQueue(sessionEvent, SessionEventType); + } + } + else if(msg.method() == BYE && received) + { + // Session Ended + DateCategory datetime; + if(!msg.exists(h_CallId) || !msg.header(h_CallId).isWellFormed()) + { + ErrLog(<< "AccountingCollector::doSessionAccounting: missing proper callId header: " << msg); + return; + } + Object sessionEvent; + sessionEvent["EventId"] = Number(SessionEnded); + sessionEvent["EventName"] = String("Session Ended"); + sessionEvent["Datetime"] = String(Data::from(datetime).c_str()); + sessionEvent["CallId"] = String(msg.header(h_CallId).value().c_str()); + if(msg.exists(h_From) && msg.header(h_From).isWellFormed()) + { + if(!msg.header(h_From).displayName().empty()) + { + sessionEvent["From"]["DisplayName"] = String(msg.header(h_From).displayName().c_str()); + } + sessionEvent["From"]["Uri"] = String(Data::from(msg.header(h_From).uri()).c_str()); + } + if(msg.exists(h_Reasons) && !msg.header(h_Reasons).empty() && msg.header(h_Reasons).front().isWellFormed()) + { + // Just look at first occurance + sessionEvent["Reason"]["Value"] = String(msg.header(h_Reasons).front().value().c_str()); + if(msg.header(h_Reasons).front().exists(p_cause)) + { + sessionEvent["Reason"]["Cause"] = Number(msg.header(h_Reasons).front().param(p_cause)); + } + if(msg.header(h_Reasons).front().exists(p_text) && !msg.header(h_Reasons).front().param(p_text).empty()) + { + sessionEvent["Reason"]["Text"] = String(msg.header(h_Reasons).front().param(p_text).c_str()); + } + } + pushEventObjectToQueue(sessionEvent, SessionEventType); + } + else if(msg.method() == CANCEL && received) + { + // Session Cancelled + DateCategory datetime; + if(!msg.exists(h_CallId) || !msg.header(h_CallId).isWellFormed()) + { + ErrLog(<< "AccountingCollector::doSessionAccounting: missing proper callId header: " << msg); + return; + } + Object sessionEvent; + sessionEvent["EventId"] = Number(SessionCancelled); + sessionEvent["EventName"] = String("Session Cancelled"); + sessionEvent["Datetime"] = String(Data::from(datetime).c_str()); + sessionEvent["CallId"] = String(msg.header(h_CallId).value().c_str()); + if(msg.exists(h_Reasons) && !msg.header(h_Reasons).empty() && msg.header(h_Reasons).front().isWellFormed()) + { + // Just look at first occurance + sessionEvent["Reason"]["Value"] = String(msg.header(h_Reasons).front().value().c_str()); + if(msg.header(h_Reasons).front().exists(p_cause)) + { + sessionEvent["Reason"]["Cause"] = Number(msg.header(h_Reasons).front().param(p_cause)); + } + if(msg.header(h_Reasons).front().exists(p_text) && !msg.header(h_Reasons).front().param(p_text).empty()) + { + sessionEvent["Reason"]["Text"] = String(msg.header(h_Reasons).front().param(p_text).c_str()); + } + } + pushEventObjectToQueue(sessionEvent, SessionEventType); + } + else if(msg.method() == REFER && received && msg.header(h_To).exists(p_tag)) + { + // Only handle mid-dialog REFERs for now + // Session Redirected + DateCategory datetime; + if(!msg.exists(h_CallId) || !msg.header(h_CallId).isWellFormed()) + { + ErrLog(<< "AccountingCollector::doSessionAccounting: missing proper callId header: " << msg); + return; + } + Object sessionEvent; + sessionEvent["EventId"] = Number(SessionRedirected); + sessionEvent["EventName"] = String("Session Redirected"); + sessionEvent["Datetime"] = String(Data::from(datetime).c_str()); + sessionEvent["CallId"] = String(msg.header(h_CallId).value().c_str()); + if(msg.exists(h_From) && msg.header(h_From).isWellFormed()) + { + if(!msg.header(h_From).displayName().empty()) + { + sessionEvent["ReferredBy"]["DisplayName"] = String(msg.header(h_From).displayName().c_str()); + } + sessionEvent["ReferredBy"]["Uri"] = String(Data::from(msg.header(h_From).uri()).c_str()); + } + if(msg.exists(h_ReferTo) && msg.header(h_ReferTo).isWellFormed()) + { + sessionEvent["TargetUri"] = String(Data::from(msg.header(h_ReferTo).uri()).c_str()); + } + pushEventObjectToQueue(sessionEvent, SessionEventType); + } + } + // Response + else + { + if(!received && msg.method() == INVITE) + { + if(msg.header(h_StatusLine).statusCode() >= 200 && + msg.header(h_StatusLine).statusCode() < 300) + { + // Session Answered + DateCategory datetime; + if(!msg.exists(h_CallId) || !msg.header(h_CallId).isWellFormed()) + { + ErrLog(<< "AccountingCollector::doSessionAccounting: missing proper callId header: " << msg); + return; + } + Object sessionEvent; + sessionEvent["EventId"] = Number(SessionEstablished); + sessionEvent["EventName"] = String("Session Established"); + sessionEvent["Datetime"] = String(Data::from(datetime).c_str()); + sessionEvent["CallId"] = String(msg.header(h_CallId).value().c_str()); + if(msg.exists(h_Contacts) && !msg.header(h_Contacts).empty() && msg.header(h_Contacts).front().isWellFormed()) + { + sessionEvent["Contact"] = String(Data::from(msg.header(h_Contacts).front()).c_str()); + } + if(mSessionAccountingAddRoutingHeaders && + msg.exists(h_RecordRoutes) && !msg.header(h_RecordRoutes).empty()) + { + Array arrayRecordRoutes; + NameAddrs::const_iterator recordRouteIt = msg.header(h_RecordRoutes).begin(); + for(; recordRouteIt != msg.header(h_RecordRoutes).end(); recordRouteIt++) + { + if(recordRouteIt->isWellFormed()) + { + arrayRecordRoutes.Insert(String(Data::from(*recordRouteIt).c_str())); + } + } + if(!arrayRecordRoutes.Empty()) + { + sessionEvent["RecordRoutes"] = arrayRecordRoutes; + } + } + if(msg.exists(h_UserAgent) && msg.header(h_UserAgent).isWellFormed()) + { + sessionEvent["UserAgent"] = String(msg.header(h_UserAgent).value().c_str()); + } + context.setSessionEstablishedEventSent(); + pushEventObjectToQueue(sessionEvent, SessionEventType); + } + else if(msg.header(h_StatusLine).statusCode() >= 300 && + msg.header(h_StatusLine).statusCode() < 400) + { + // Session Redirected + // Session Answered + DateCategory datetime; + if(!msg.exists(h_CallId) || !msg.header(h_CallId).isWellFormed()) + { + ErrLog(<< "AccountingCollector::doSessionAccounting: missing proper callId header: " << msg); + return; + } + Object sessionEvent; + sessionEvent["EventId"] = Number(SessionRedirected); + sessionEvent["EventName"] = String("Session Redirected"); + sessionEvent["Datetime"] = String(Data::from(datetime).c_str()); + sessionEvent["CallId"] = String(msg.header(h_CallId).value().c_str()); + if(msg.exists(h_Contacts) && !msg.header(h_Contacts).empty()) + { + Array arrayContacts; + NameAddrs::const_iterator contactIt = msg.header(h_Contacts).begin(); + for(; contactIt != msg.header(h_Contacts).end(); contactIt++) + { + if(contactIt->isWellFormed()) + { + arrayContacts.Insert(String(Data::from(*contactIt).c_str())); + } + } + if(!arrayContacts.Empty()) + { + sessionEvent["TargetUris"] = arrayContacts; + } + } + if(msg.exists(h_UserAgent) && msg.header(h_UserAgent).isWellFormed()) + { + sessionEvent["UserAgent"] = String(msg.header(h_UserAgent).value().c_str()); + } + pushEventObjectToQueue(sessionEvent, SessionEventType); + } + else if(msg.header(h_StatusLine).statusCode() >= 400 && + msg.header(h_StatusLine).statusCode() < 700) + { + // Session Error + Object sessionEvent; + // Session Answered + DateCategory datetime; + if(!msg.exists(h_CallId) || !msg.header(h_CallId).isWellFormed()) + { + ErrLog(<< "AccountingCollector::doSessionAccounting: missing proper callId header: " << msg); + return; + } + sessionEvent["EventId"] = Number(SessionError); + sessionEvent["EventName"] = String("Session Error"); + sessionEvent["Datetime"] = String(Data::from(datetime).c_str()); + sessionEvent["CallId"] = String(msg.header(h_CallId).value().c_str()); + sessionEvent["Status"]["Code"] = Number(msg.header(h_StatusLine).statusCode()); + if(!msg.header(h_StatusLine).reason().empty()) + { + sessionEvent["Status"]["Text"] = String(msg.header(h_StatusLine).reason().c_str()); + } + if(msg.exists(h_Warnings) && !msg.header(h_Warnings).empty() && msg.header(h_Warnings).front().isWellFormed()) + { + // Just look at first occurance + sessionEvent["Warning"]["Code"] = Number(msg.header(h_Warnings).front().code()); + if(!msg.header(h_Warnings).front().text().empty()) + { + sessionEvent["Warning"]["Text"] = String(msg.header(h_Warnings).front().text().c_str()); + } + } + // Note: a reason header is not usually present on a response - but we will use one if it is + if(msg.exists(h_Reasons) && !msg.header(h_Reasons).empty() && msg.header(h_Reasons).front().isWellFormed()) + { + // Just look at first occurance + sessionEvent["Reason"]["Value"] = String(msg.header(h_Reasons).front().value().c_str()); + if(msg.header(h_Reasons).front().exists(p_cause)) + { + sessionEvent["Reason"]["Cause"] = Number(msg.header(h_Reasons).front().param(p_cause)); + } + if(msg.header(h_Reasons).front().exists(p_text) && !msg.header(h_Reasons).front().param(p_text).empty()) + { + sessionEvent["Reason"]["Text"] = String(msg.header(h_Reasons).front().param(p_text).c_str()); + } + } + if(msg.exists(h_UserAgent) && msg.header(h_UserAgent).isWellFormed()) + { + sessionEvent["UserAgent"] = String(msg.header(h_UserAgent).value().c_str()); + } + pushEventObjectToQueue(sessionEvent, SessionEventType); + } + } + } +} + +PersistentMessageEnqueue* +AccountingCollector::initializeEventQueue(FifoEventType type, bool destroyFirst) +{ + switch(type) + { + case SessionEventType: + if(destroyFirst) + { + delete mSessionEventQueue; + mSessionEventQueue = 0; + } + if(!mSessionEventQueue) + { + mSessionEventQueue = new PersistentMessageEnqueue(mDbBaseDir); + if(!mSessionEventQueue->init(true, sessionEventQueueName)) + { + delete mSessionEventQueue; + mSessionEventQueue = 0; + } + } + return mSessionEventQueue; + case RegistrationEventType: + if(destroyFirst) + { + delete mRegistrationEventQueue; + mRegistrationEventQueue = 0; + } + if(!mRegistrationEventQueue) + { + mRegistrationEventQueue = new PersistentMessageEnqueue(mDbBaseDir); + if(!mRegistrationEventQueue->init(true, registrationEventQueueName)) + { + delete mRegistrationEventQueue; + mRegistrationEventQueue = 0; + } + } + return mRegistrationEventQueue; + default: + assert(false); + break; + } + return 0; +} + +void +AccountingCollector::pushEventObjectToQueue(Object& eventObject, AccountingCollector::FifoEventType type) +{ + FifoEvent* eventData = new FifoEvent; + eventData->mType = type; + { + DataStream ds(eventData->mData); + Writer::Write(eventObject, ds); + } + + // Note: BerkeleyDb calls can block (ie. deaklock after consumer crash), so we use a + // Fifo and thread to ensure we don't block the core proxy processing + mFifo.add(eventData, TimeLimitFifo<FifoEvent>::InternalElement); +} + +void +AccountingCollector::internalProcess(std::auto_ptr<FifoEvent> eventData) +{ + InfoLog(<< "AccountingCollector::internalProcess: JSON=" << endl << eventData->mData); + + PersistentMessageEnqueue* queue = initializeEventQueue(eventData->mType); + + if(!queue) + { + ErrLog(<< "AccountingCollector: cannot initialize PersistentMessageQueue - dropping event!"); + return; + } + + if(!queue->push(eventData->mData)) + { + // Error pushing - see if db recovery is needed + if(queue->isRecoveryNeeded()) + { + if((queue = initializeEventQueue(eventData->mType, true /* destoryFirst */)) == 0) + { + ErrLog(<< "AccountingCollector: cannot initialize PersistentMessageQueue - dropping event!"); + return; + } + else + { + if(!queue->push(eventData->mData)) + { + ErrLog(<< "AccountingCollector: error pushing event to queue - dropping event!"); + } + } + } + else + { + ErrLog(<< "AccountingCollector: error pushing event to queue - dropping event!"); + } + } +} + +void +AccountingCollector::thread() +{ + while (!isShutdown() || !mFifo.empty()) // Ensure we drain the queue before shutting down + { + try + { + std::auto_ptr<FifoEvent> eventData(mFifo.getNext(1000)); // Only need to wake up to see if we are shutdown + if (eventData.get()) + { + internalProcess(eventData); + } + } + catch (BaseException& e) + { + WarningLog (<< "Unhandled exception: " << e); + } + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/AccountingCollector.hxx b/src/libs/resiprocate/repro/AccountingCollector.hxx new file mode 100644 index 00000000..916aa284 --- /dev/null +++ b/src/libs/resiprocate/repro/AccountingCollector.hxx @@ -0,0 +1,129 @@ +#if !defined(RESIP_ACCOUNTINGCOLLECTOR_HXX) +#define RESIP_ACCOUNTINGCOLLECTOR_HXX + +#include <memory> +#include "rutil/ThreadIf.hxx" +#include "rutil/TimeLimitFifo.hxx" +#include "resip/stack/SipMessage.hxx" + +namespace json +{ + class Object; +} + +namespace repro +{ +class RequestContext; +class PersistentMessageEnqueue; +class ProxyConfig; + +class AccountingCollector : public resip::ThreadIf +{ +public: + typedef enum + { + RegistrationAdded = 1, + RegistrationRefreshed = 2, + RegistrationRemoved = 3, + RegistrationRemovedAll = 4 + } RegistrationEvent; + + typedef enum + { + SessionCreated = 1, + SessionRouted = 2, + SessionRedirected = 3, + SessionEstablished = 4, + SessionCancelled = 5, + SessionEnded = 6, + SessionError = 7 + } SessionEvent; + + AccountingCollector(ProxyConfig& config); + virtual ~AccountingCollector(); + + virtual void doSessionAccounting(const resip::SipMessage& sip, bool received, RequestContext& context); + virtual void doRegistrationAccounting(RegistrationEvent regevent, const resip::SipMessage& sip); + +private: + resip::Data mDbBaseDir; + PersistentMessageEnqueue* mSessionEventQueue; + PersistentMessageEnqueue* mRegistrationEventQueue; + bool mSessionAccountingAddRoutingHeaders; + bool mSessionAccountingAddViaHeaders; + bool mRegistrationAccountingAddRoutingHeaders; + bool mRegistrationAccountingAddViaHeaders; + bool mRegistrationAccountingLogRefreshes; + + virtual void thread(); + + enum FifoEventType + { + SessionEventType, + RegistrationEventType + }; + class FifoEvent + { + public: + FifoEventType mType; + resip::Data mData; + }; + resip::TimeLimitFifo<FifoEvent> mFifo; + PersistentMessageEnqueue* initializeEventQueue(FifoEventType type, bool destroyFirst=false); + void pushEventObjectToQueue(json::Object& object, FifoEventType type); + void internalProcess(std::auto_ptr<FifoEvent> eventData); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/Ack200DoneMessage.hxx b/src/libs/resiprocate/repro/Ack200DoneMessage.hxx new file mode 100644 index 00000000..a00b433e --- /dev/null +++ b/src/libs/resiprocate/repro/Ack200DoneMessage.hxx @@ -0,0 +1,73 @@ +#ifndef RESIP_Ack200DoneMessage_hxx +#define RESIP_Ack200DoneMessage_hxx + +#include "assert.h" +#include "resip/stack/ApplicationMessage.hxx" + +namespace repro +{ + +class Ack200DoneMessage : public resip::ApplicationMessage +{ + public: + Ack200DoneMessage(const resip::Data& tid) {mTid=tid;} + virtual ~Ack200DoneMessage() {} + + virtual const resip::Data& getTransactionId() const { return mTid; } + virtual Ack200DoneMessage* clone() const {return new Ack200DoneMessage(mTid);} + virtual EncodeStream& encode(EncodeStream& ostr) const { ostr << "Ack200DoneMessage(tid="<<mTid<<")"; return ostr; } + virtual EncodeStream& encodeBrief(EncodeStream& ostr) const { return encode(ostr);} + private: + resip::Data mTid; +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/AclStore.cxx b/src/libs/resiprocate/repro/AclStore.cxx new file mode 100644 index 00000000..328d1c44 --- /dev/null +++ b/src/libs/resiprocate/repro/AclStore.cxx @@ -0,0 +1,582 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "rutil/Socket.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Lock.hxx" +#include "resip/stack/Uri.hxx" +#include "resip/stack/ConnectionManager.hxx" +#include "resip/stack/SipMessage.hxx" + +#include "repro/AclStore.hxx" + +#ifdef USE_SSL +#include "resip/stack/ssl/TlsConnection.hxx" +#include "resip/stack/ssl/TlsTransport.hxx" +#endif + +using namespace resip; +using namespace repro; +using namespace std; + + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +AclStore::AclStore(AbstractDb& db): + mDb(db) +{ + AbstractDb::Key key = mDb.firstAclKey(); + while ( !key.empty() ) + { + AbstractDb::AclRecord rec = mDb.getAcl(key); + if(rec.mTlsPeerName.empty()) // If there is no TlsPeerName then record is an Address ACL + { + AddressRecord addressRecord(rec.mAddress, rec.mPort, (resip::TransportType)rec.mTransport); + addressRecord.mMask = rec.mMask; + addressRecord.key = buildKey(Data::Empty, rec.mAddress, rec.mMask, rec.mPort, rec.mFamily, rec.mTransport); + mAddressList.push_back(addressRecord); + } + else + { + TlsPeerNameRecord tlsPeerNameRecord; + tlsPeerNameRecord.mTlsPeerName = rec.mTlsPeerName; + tlsPeerNameRecord.key = buildKey(rec.mTlsPeerName, Data::Empty, 0, 0, 0, 0); + mTlsPeerNameList.push_back(tlsPeerNameRecord); + } + key = mDb.nextAclKey(); + } + mTlsPeerNameCursor = mTlsPeerNameList.begin(); + mAddressCursor = mAddressList.begin(); +} + + +AclStore::~AclStore() +{ +} + + +bool +AclStore::addAcl(const resip::Data& tlsPeerName, + const resip::Data& address, + const short& mask, + const short& port, + const short& family, + const short& transport) +{ + Data key = buildKey(tlsPeerName, address, mask, port, family, transport); + InfoLog( << "Add ACL: key=" << key); + + AbstractDb::AclRecord rec; + rec.mTlsPeerName = tlsPeerName; + rec.mAddress = address; + rec.mMask = mask; + rec.mPort = port; + rec.mFamily = family; + rec.mTransport = transport; + + // Add DB record + if(!mDb.addAcl(key, rec)) + { + return false; + } + + // Add local storage + if(rec.mTlsPeerName.empty()) // If there is no TlsPeerName then record is an Address ACL + { + AddressRecord addressRecord(rec.mAddress, rec.mPort, (resip::TransportType)rec.mTransport); + addressRecord.mMask = rec.mMask; + addressRecord.key = buildKey(Data::Empty, rec.mAddress, rec.mMask, rec.mPort, rec.mFamily, rec.mTransport); + { + WriteLock lock(mMutex); + mAddressList.push_back(addressRecord); + } + } + else + { + TlsPeerNameRecord tlsPeerNameRecord; + tlsPeerNameRecord.mTlsPeerName = rec.mTlsPeerName; + tlsPeerNameRecord.key = buildKey(rec.mTlsPeerName, Data::Empty, 0, 0, 0, 0); + { + WriteLock lock(mMutex); + mTlsPeerNameList.push_back(tlsPeerNameRecord); + } + } + return true; +} + + +bool +AclStore::addAcl(const resip::Data& tlsPeerNameOrAddress, + const short& port, + const short& transport) +{ + // Input can be in any of these formats + // localhost localhost (becomes 127.0.0.1/8, ::1/128 and fe80::1/64) + // bare hostname server1 + // FQDN server1.example.com + // IPv4 address 192.168.1.100 + // IPv4 + mask 192.168.1.0/24 + // IPv6 address :341:0:23:4bb:0011:2435:abcd + // IPv6 + mask :341:0:23:4bb:0011:2435:abcd/80 + // IPv6 reference [:341:0:23:4bb:0011:2435:abcd] + // IPv6 ref + mask [:341:0:23:4bb:0011:2435:abcd]/64 + + try + { + ParseBuffer pb(tlsPeerNameOrAddress); + const char* anchor = pb.start(); + + bool ipv4 = false; + bool ipv6 = false; + Data hostOrIp; + //u_char in[28]; + struct in_addr in4; +#ifdef USE_IPV6 + struct in6_addr in6; +#endif + int mask; + + if (*pb.position() == '[') // encountered beginning of IPv6 reference + { + anchor = pb.skipChar(); + pb.skipToEndQuote(']'); + + pb.data(hostOrIp, anchor); // copy the presentation form of the IPv6 address + anchor = pb.skipChar(); + + // try to convert into IPv6 network form +#ifdef USE_IPV6 + if (!DnsUtil::inet_pton( hostOrIp.c_str(), in6)) +#endif + { + return false; + } + ipv6 = true; + } + else + { + pb.skipToOneOf(".:"); + if (pb.position() == pb.end()) // We probably have a bare hostname + { + pb.data(hostOrIp, anchor); + if (hostOrIp.lowercase() == "localhost") + { + // add special localhost addresses for v4 and v6 to list and return + addAcl(Data::Empty, "127.0.0.1", 8, port, resip::V4, transport); + addAcl(Data::Empty, "::1", 128, port, resip::V6, transport); + return addAcl(Data::Empty, "fe80::1", 64, port, resip::V6, transport); + } + else + { + // hostOrIp += default domain name (future) + return addAcl(hostOrIp, Data::Empty, 0, 0, 0, 0); + } + } + else if (*pb.position() == ':') // Must be an IPv6 address + { + pb.skipToChar('/'); + pb.data(hostOrIp, anchor); // copy the presentation form of the IPv6 address + + // try to convert into IPv6 network form +#ifdef USE_IPV6 + if (!DnsUtil::inet_pton( hostOrIp.c_str(), in6)) +#endif + { + return false; + } + ipv6 = true; + } + else // *pb.position() == '.' + { + // Could be either an IPv4 address or an FQDN + pb.skipToChar('/'); + pb.data(hostOrIp, anchor); // copy the presentation form of the address + + // try to interpret as an IPv4 address, if that fails look it up in DNS + if (DnsUtil::inet_pton( hostOrIp.c_str(), in4)) + { + // it was an IPv4 address + ipv4 = true; + } + else + { + // hopefully it is a legal FQDN, try it. + return addAcl(hostOrIp, Data::Empty, 0, 0, 0, 0); + } + } + } + + if (!pb.eof() && *pb.position() == '/') // grab the mask as well + { + anchor = pb.skipChar(); + mask = pb.integer(); + + if (ipv4) + { + if (mask < 8 || mask > 32) + { + return false; + } + } + else if (ipv6) + { + if (mask < 64 || mask > 128) + { + return false; + } + } + } + else + { + if (ipv4) + { + mask = 32; + } + else // ipv6 + { + mask = 128; + } + } + + if(pb.eof()) + { + bool ret; + if (ipv6) + { + ret = addAcl(Data::Empty, hostOrIp, mask, port, resip::V6, transport); + } + + if (ipv4) + { + ret = addAcl(Data::Empty, hostOrIp, mask, port, resip::V4, transport); + } + return ret; + } + } + catch(ParseException& e) + { + ErrLog(<< "Exception caught:" << e); + } + return false; +} + + +void +AclStore::eraseAcl(const resip::Data& key) +{ + // Erase DB record + mDb.eraseAcl( key ); + + // Erase local storage + if(key.prefix(":")) // a key that starts with a : has no peer name - thus a Address key + { + WriteLock lock(mMutex); + if(findAddressKey(key)) + { + mAddressList.erase(mAddressCursor); + } + } + else + { + WriteLock lock(mMutex); + if(findTlsPeerNameKey(key)) + { + mTlsPeerNameCursor = mTlsPeerNameList.erase(mTlsPeerNameCursor); + } + } +} + + +AbstractDb::Key +AclStore::buildKey(const resip::Data& tlsPeerName, + const resip::Data& address, + const short& mask, + const short& port, + const short& family, + const short& transport) const +{ + Data pKey = tlsPeerName+":"+address+"/"+Data(mask)+":"+Data(port)+":"+Data(family)+":"+Data(transport); + return pKey; +} + + +AclStore::Key +AclStore::getFirstTlsPeerNameKey() +{ + ReadLock lock(mMutex); + mTlsPeerNameCursor = mTlsPeerNameList.begin(); + if ( mTlsPeerNameCursor == mTlsPeerNameList.end() ) + { + return Key( Data::Empty ); + } + + return mTlsPeerNameCursor->key; +} + + +bool +AclStore::findTlsPeerNameKey(const Key& key) +{ + // check if cursor happens to be at the key + if ( mTlsPeerNameCursor != mTlsPeerNameList.end() ) + { + if ( mTlsPeerNameCursor->key == key ) + { + return true; + } + } + + // search for the key + mTlsPeerNameCursor = mTlsPeerNameList.begin(); + while ( mTlsPeerNameCursor != mTlsPeerNameList.end() ) + { + if ( mTlsPeerNameCursor->key == key ) + { + return true; // found the key + } + mTlsPeerNameCursor++; + } + return false; // key was not found +} + + +AclStore::Key +AclStore::getNextTlsPeerNameKey(Key& key) +{ + ReadLock lock(mMutex); + if ( !findTlsPeerNameKey(key) ) + { + return Key(Data::Empty); + } + + mTlsPeerNameCursor++; + + if ( mTlsPeerNameCursor == mTlsPeerNameList.end() ) + { + return Key( Data::Empty ); + } + + return mTlsPeerNameCursor->key; +} + + +AclStore::Key +AclStore::getFirstAddressKey() +{ + ReadLock lock(mMutex); + mAddressCursor = mAddressList.begin(); + if ( mAddressCursor == mAddressList.end() ) + { + return Key( Data::Empty ); + } + + return mAddressCursor->key; +} + + +bool +AclStore::findAddressKey(const Key& key) +{ + // check if cursor happens to be at the key + if ( mAddressCursor != mAddressList.end() ) + { + if ( mAddressCursor->key == key ) + { + return true; + } + } + + // search for the key + mAddressCursor = mAddressList.begin(); + while ( mAddressCursor != mAddressList.end() ) + { + if ( mAddressCursor->key == key ) + { + return true; // found the key + } + mAddressCursor++; + } + return false; // key was not found +} + + +AclStore::Key +AclStore::getNextAddressKey(Key& key) +{ + ReadLock lock(mMutex); + if ( !findAddressKey(key) ) + { + return Key(Data::Empty); + } + + mAddressCursor++; + + if ( mAddressCursor == mAddressList.end() ) + { + return Key( Data::Empty ); + } + + return mAddressCursor->key; +} + + +resip::Data +AclStore::getTlsPeerName( const resip::Data& key ) +{ + ReadLock lock(mMutex); + if ( !findTlsPeerNameKey(key) ) + { + return Data::Empty; + } + return mTlsPeerNameCursor->mTlsPeerName; +} + + +resip::Tuple +AclStore::getAddressTuple( const resip::Data& key ) +{ + ReadLock lock(mMutex); + if ( !findAddressKey(key) ) + { + return Tuple(); + } + return mAddressCursor->mAddressTuple; +} + + +short +AclStore::getAddressMask( const resip::Data& key ) +{ + ReadLock lock(mMutex); + if ( !findAddressKey(key) ) + { + return 0; + } + return mAddressCursor->mMask; +} + + +bool +AclStore::isTlsPeerNameTrusted(const std::list<Data>& tlsPeerNames) +{ + ReadLock lock(mMutex); + for(std::list<Data>::const_iterator it = tlsPeerNames.begin(); it != tlsPeerNames.end(); it++) + { + for(TlsPeerNameList::iterator i = mTlsPeerNameList.begin(); i != mTlsPeerNameList.end(); i++) + { + if(isEqualNoCase(i->mTlsPeerName, *it)) + { + InfoLog (<< "AclStore - Tls peer name IS trusted: " << *it); + return true; + } + } + } + return false; +} + + +bool +AclStore::isAddressTrusted(const Tuple& address) +{ + ReadLock lock(mMutex); + for(AddressList::iterator i = mAddressList.begin(); i != mAddressList.end(); i++) + { + if(i->mAddressTuple.isEqualWithMask(address, i->mMask, i->mAddressTuple.getPort() == 0)) + { + return true; + } + } + return false; +} + + +// check the sender of the message via source IP address or identity from TLS +bool +AclStore::isRequestTrusted(const SipMessage& request) +{ + bool trusted = false; + Tuple source = request.getSource(); + + // check if the request came over a secure channel and sucessfully authenticated + // (ex: TLS or DTLS) + const Data& receivedTransport = request.header(h_Vias).front().transport(); +#ifdef USE_SSL + if(receivedTransport == Symbols::TLS +#ifdef USE_DTLS + || receivedTransport == Symbols::DTLS +#endif + ) + { + const std::list<Data>& tlsPeerNames = request.getTlsPeerNames(); + if(!tlsPeerNames.empty() && isTlsPeerNameTrusted(tlsPeerNames)) + { + trusted = true; + } + } +#endif + + // check the source address against the TrustedNode list + if(!trusted) + { + if(isAddressTrusted(source)) + { + InfoLog (<< "AclStore - source address IS trusted: " << source.presentationFormat() << ":" << source.getPort() << " " << Tuple::toData(source.getType())); + trusted = true; + } + else + { + InfoLog (<< "AclStore - source address NOT trusted: " << source.presentationFormat() << ":" << source.getPort() << " " << Tuple::toData(source.getType())); + } + } + + return trusted; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/AclStore.hxx b/src/libs/resiprocate/repro/AclStore.hxx new file mode 100644 index 00000000..aa5ee98b --- /dev/null +++ b/src/libs/resiprocate/repro/AclStore.hxx @@ -0,0 +1,131 @@ +#if !defined(REPRO_ACLSTORE_HXX) +#define REPRO_ACLSTORE_HXX + +#include <list> +#include "rutil/Data.hxx" +#include "rutil/RWMutex.hxx" +#include "resip/stack/Tuple.hxx" +#include "repro/AbstractDb.hxx" + +namespace repro +{ + +class AclStore +{ + public: + class TlsPeerNameRecord + { + public: + resip::Data key; + resip::Data mTlsPeerName; + }; + + class AddressRecord + { + public: + AddressRecord(const resip::Data& printableAddress, const int port, const resip::TransportType type) : mAddressTuple(printableAddress, port, type) {}; + resip::Data key; + resip::Tuple mAddressTuple; + short mMask; + }; + + typedef resip::Data Key; + typedef std::vector<TlsPeerNameRecord> TlsPeerNameList; + typedef std::vector<AddressRecord> AddressList; + + AclStore(AbstractDb& db); + ~AclStore(); + + bool addAcl(const resip::Data& tlsPeerName, + const resip::Data& address, + const short& mask, + const short& port, + const short& family, + const short& transport); + + bool addAcl(const resip::Data& tlsPeerNameOrAddress, + const short& port, + const short& transport); + + void eraseAcl(const resip::Data& key); + + resip::Data getTlsPeerName( const resip::Data& key ); + resip::Tuple getAddressTuple( const resip::Data& key ); + short getAddressMask( const resip::Data& key ); + + Key getFirstTlsPeerNameKey(); // return empty if no more + Key getNextTlsPeerNameKey(Key& key); // return empty if no more + Key getFirstAddressKey(); // return empty if no more + Key getNextAddressKey(Key& key); // return empty if no more + + bool isTlsPeerNameTrusted(const std::list<resip::Data>& tlsPeerNames); + bool isAddressTrusted(const resip::Tuple& address); + bool isRequestTrusted(const resip::SipMessage& request); + + + private: + AbstractDb& mDb; + + Key buildKey(const resip::Data& tlsPeerName, + const resip::Data& address, + const short& mask, + const short& port, + const short& family, + const short& transport) const; + + bool findTlsPeerNameKey(const Key& key); // move cursor to key + bool findAddressKey(const Key& key); // move cursor to key + + resip::RWMutex mMutex; + TlsPeerNameList mTlsPeerNameList; + TlsPeerNameList::iterator mTlsPeerNameCursor; + AddressList mAddressList; + AddressList::iterator mAddressCursor; +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/AsyncProcessor.hxx b/src/libs/resiprocate/repro/AsyncProcessor.hxx new file mode 100644 index 00000000..1dfeb5da --- /dev/null +++ b/src/libs/resiprocate/repro/AsyncProcessor.hxx @@ -0,0 +1,178 @@ +#if !defined(RESIP_ASYNC_PROCESSOR_HXX) +#define RESIP_ASYNC_PROCESSOR_HXX + +#include <iosfwd> +#include <vector> +#include "repro/Processor.hxx" +#include "repro/ProcessorMessage.hxx" +#include "repro/Dispatcher.hxx" + +namespace repro +{ +class AsyncProcessorMessage; + +// This class is used to create Processors that need to accomplish blocking +// tasks, such as database access. The request/event is delivered to this +// Processor, like any other via the virtual method: +// virtual processor_action_t process(RequestContext &) +// +// When a blocking task is required, it can be queued up for the thread pool +// of workers, that are implemented in the constructor provided asyncDispatcher, by +// constructing a new AsyncProcessorMessage and calling mAsyncDispatcher->post +// AsyncProcessorMessage implementations should contain any data needed by the +// threads and contain any members required to hold the blocking functions +// return data or results. +// +// When a worker thread picks up the message it will call the virtual method: +// virtual void asyncProcess(AsyncProcessorMessage* msg) +// The implementation of this method should perform the actual blocking function +// calls - ie. database access call. If there is any data to return it should be +// set in the provided AsyncProcessorMessage before returning from asyncProcess. +// +// The dispatcher will then queue this message up to be sent back to the +// AsyncProcessor, via the virtual method: +// virtual processor_action_t process(RequestContext &) +// This virtual method will need to examine the event type to see if the event is +// a new request or an asynchronous result message (AsyncProcessorMessage). +// + +/* Example: +class MyAsyncProcessorAsyncMessage : public AsyncProcessorMessage +{ +public: + MyAsyncProcessorAsyncMessage(AsyncProcessor& proc, + const resip::Data& tid, + resip::TransactionUser* passedtu): + AsyncProcessorMessage(proc,tid,passedtu) { } + + virtual EncodeStream& encode(EncodeStream& strm) const + { + strm << "MyAsyncProcessorAsyncMessage(tid="<<mTid<<")"; return strm; + } + + Data mDataRequiredToCallBlockingFunction; + Data mDataReturnedFromBlockingFunction; +}; + +class MyAsyncProcessor : public AsyncProcessor +{ + public: + MyAsyncProcessor(ProxyConfig& config, Dispatcher* asyncDispatcher) : + AsyncProcessor("MyAsyncProcessor", asyncDispatcher) {} + ~MyAsyncProcessor() {} + + // Processor virtual method + virtual processor_action_t process(RequestContext &rc) + { + Message *message = rc.getCurrentEvent(); + + MyAsyncProcessorAsyncMessage *async = dynamic_cast<MyAsyncProcessorAsyncMessage*>(message); + if (async) + { + // Async Function is complete - do something with results and continue + InfoLog(<< "Async function is complete, results are: " << async->mDataReturnedFromBlockingFunction); + return Continue; + } + else + { + // Control enters here when request arrives and is passed through process chain + // Dispatch async request to worker thread pool + MyAsyncProcessorAsyncMessage* async = new MyAsyncProcessorAsyncMessage(*this, rc.getTransactionId(), &rc.getProxy()); + async->mDataRequiredToCallBlockingFunction = "foo"; + mAsyncDispatcher->post(std::auto_ptr<ApplicationMessage>(async)); + return WaitingForEvent; + } + } + + // Virtual method called from WorkerThreads - return true to queue to stack when complete, + // false when no response is required + virtual bool asyncProcess(AsyncProcessorMessage* msg) + { + MyAsyncProcessorAsyncMessage* async = dynamic_cast<MyAsyncProcessorAsyncMessage*>(msg); + if(async) + { + // Running inside a worker thread here, do blocking work here + // set any results in MyAsyncProcessorAsyncMessage and return control to Dispatcher + // that will queue this message back to this processor. + async->mDataReturnedFromBlockingFunction = "bar"; + } + } + + private: +}; +*/ + + +class AsyncProcessor : public Processor +{ + public: + AsyncProcessor(const resip::Data& name, Dispatcher* asyncDispatcher, ChainType type=NO_TYPE) : + Processor(name, type), + mAsyncDispatcher(asyncDispatcher) {} + virtual ~AsyncProcessor() {} + + // Processor virtual method + virtual processor_action_t process(RequestContext &)=0; + + // Virtual method called from WorkerThreads + // return true to queue to stack when complete, false when no response is required + virtual bool asyncProcess(AsyncProcessorMessage* msg)=0; + + protected: + Dispatcher* mAsyncDispatcher; +}; + +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/AsyncProcessorMessage.hxx b/src/libs/resiprocate/repro/AsyncProcessorMessage.hxx new file mode 100644 index 00000000..a1cd062c --- /dev/null +++ b/src/libs/resiprocate/repro/AsyncProcessorMessage.hxx @@ -0,0 +1,82 @@ +#ifndef ASYNCPROCESSOR_MESSAGE_HXX +#define ASYNCPROCESSOR_MESSAGE_HXX 1 + +#include "repro/ProcessorMessage.hxx" +#include "repro/AsyncProcessor.hxx" + +namespace repro +{ + +class AsyncProcessorMessage : public ProcessorMessage +{ +public: + AsyncProcessorMessage(AsyncProcessor& proc, + const resip::Data& tid, + resip::TransactionUser* passedtu): + ProcessorMessage(proc, tid, passedtu), + mAsyncProcessor(proc) + { + } + + virtual Message* clone() const { assert(false); return 0; } + + virtual EncodeStream& encode(EncodeStream& strm) const { strm << "AsyncProcessorMessage(tid="<<mTid<<")"; return strm; } + virtual EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm);} + + virtual AsyncProcessor& getAsyncProcessor() { return mAsyncProcessor; } +protected: + AsyncProcessor& mAsyncProcessor; +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/AsyncProcessorWorker.hxx b/src/libs/resiprocate/repro/AsyncProcessorWorker.hxx new file mode 100644 index 00000000..a0867161 --- /dev/null +++ b/src/libs/resiprocate/repro/AsyncProcessorWorker.hxx @@ -0,0 +1,84 @@ +#ifndef ASYNCPROCESSOR_WORKER_HXX +#define ASYNCPROCESSOR_WORKER_HXX 1 + +#include "repro/Worker.hxx" +#include "repro/AsyncProcessor.hxx" +#include "repro/AsyncProcessorMessage.hxx" + +namespace repro +{ + +class AsyncProcessorWorker : public Worker +{ +public: + AsyncProcessorWorker() {} + virtual ~AsyncProcessorWorker() {} + + virtual bool process(resip::ApplicationMessage* msg) + { + AsyncProcessorMessage* pmsg = dynamic_cast<AsyncProcessorMessage*>(msg); + if(pmsg) + { + return pmsg->getAsyncProcessor().asyncProcess(pmsg); + } + assert(false); // unexpected message type + return false; + } + virtual Worker* clone() const + { + return new AsyncProcessorWorker(); + } +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/BerkeleyDb.cxx b/src/libs/resiprocate/repro/BerkeleyDb.cxx new file mode 100644 index 00000000..996af349 --- /dev/null +++ b/src/libs/resiprocate/repro/BerkeleyDb.cxx @@ -0,0 +1,587 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <fcntl.h> +#include <cassert> +#include <cstdlib> + +#include "rutil/Data.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/Logger.hxx" + +#include "repro/AbstractDb.hxx" +#include "repro/BerkeleyDb.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace repro; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO +//#define USE_DBENV // Required for transaction support + +BerkeleyDb::BerkeleyDb() +{ + init(Data::Empty, Data::Empty); +} + + +BerkeleyDb::BerkeleyDb( const Data& dbPath, const Data& dbName ) +{ + init(dbPath, dbName); +} + + +void +BerkeleyDb::init( const Data& dbPath, const Data& dbName ) +{ + Data filePath(dbPath); + + // An empty path is how you specify the current working directory as a path + if ( !filePath.empty() ) + { +#ifdef WIN32 + filePath += '\\'; +#else + filePath += '/'; +#endif + } + + if ( dbName.empty() ) + { + DebugLog( << "No BerkeleyDb prefix specified - using default" ); + filePath += "repro"; + } + else + { + filePath += dbName; + } + + InfoLog( << "Using BerkeleyDb prefixed with " << filePath ); + + mSane = true; + + // Create Environment + int ret; +#ifdef USE_DBENV + mEnv = new DbEnv(DB_CXX_NO_EXCEPTIONS); + assert(mEnv); + ret = mEnv->open(0, DB_CREATE | // If the env does not exist, then create it + DB_INIT_LOCK | // Initialize Locking (needed for transactions) + DB_INIT_LOG | // Initialize Logging (needed for transactions) + DB_INIT_MPOOL | // Initialize the cache (needed for transactions) + DB_INIT_TXN | // Initialize transactions + DB_RECOVER | // Run normal recovery + DB_THREAD, // Free-thread the env handle + 0 /* mode */); + if(ret != 0) + { + ErrLog( <<"Could not open environment: " << db_strerror(ret)); + mSane = false; + return; + } + mEnv->txn_checkpoint(0, 0, 0); // Note: a checkpoint is run when this last is created and when it is destroyed +#else + mEnv = 0; +#endif + + bool enableTransactions = false; + bool secondaryIndex = false; + Data secondaryFileName; + for (int i=0;i<MaxTable;i++) + { + enableTransactions = false; + // if the line bellow seems wrong, you need to check which version + // of db you have - it is likely an very out of date version + // still trying to figure this out so email fluffy if you have + // problems and include your version the DB_VERSION_STRING found + // in your db4/db.h file. + Data fileName( filePath ); + switch (i) + { + case UserTable: + fileName += "_user"; break; + case RouteTable: + fileName += "_route"; break; + case AclTable: + fileName += "_acl"; break; + case ConfigTable: + fileName += "_config"; break; + case StaticRegTable: + fileName += "_staticreg"; break; + case FilterTable: + fileName += "_filter"; break; + case SiloTable: + fileName += "_silo"; + enableTransactions = true; + secondaryIndex = true; + break; + default: + assert(0); + } + + if(!secondaryIndex) + { + fileName += ".db"; + } + else + { + secondaryFileName = fileName; + fileName += ".db"; + secondaryFileName += "_idx1.db"; + } + + mTableInfo[i].mDb = new Db(mEnv, DB_CXX_NO_EXCEPTIONS); + assert(mTableInfo[i].mDb); + + DebugLog( << "About to open Berkeley DB: " << fileName ); + ret = mTableInfo[i].mDb->open(0, + fileName.c_str(), + 0, + DB_BTREE, +#ifdef USE_DBENV + DB_CREATE | DB_THREAD | (enableTransactions ? DB_AUTO_COMMIT : 0), +#else + DB_CREATE | DB_THREAD, +#endif + 0); + if(ret != 0) + { + ErrLog( <<"Could not open database " << fileName << ": " << db_strerror(ret)); + mSane = false; + return; + } + + // Open a cursor on the database + ret = mTableInfo[i].mDb->cursor(0, &mTableInfo[i].mCursor, 0); + if(ret != 0) + { + ErrLog( <<"Could not cursor on database " << fileName << ": " << db_strerror(ret)); + mSane = false; + return; + } + assert(mTableInfo[i].mCursor); + + DebugLog( << "Opened Berkeley DB: " << fileName ); + + + if(secondaryIndex) + { + mTableInfo[i].mSecondaryDb = new Db(mEnv, DB_CXX_NO_EXCEPTIONS); + assert(mTableInfo[i].mSecondaryDb); + + ret = mTableInfo[i].mSecondaryDb->set_flags(DB_DUP); + if(ret!=0) + { + ErrLog( <<"Could not set database " << secondaryFileName << " to allow duplicates: " << db_strerror(ret)); + mSane = false; + return; + } + + DebugLog( << "About to open secondary Berkeley DB: " << secondaryFileName ); + ret = mTableInfo[i].mSecondaryDb->open(0, + secondaryFileName.c_str(), + 0, + DB_BTREE, +#ifdef USE_DBENV + DB_CREATE | DB_THREAD | (enableTransactions ? DB_AUTO_COMMIT : 0), +#else + DB_CREATE | DB_THREAD, +#endif + 0); + if(ret != 0) + { + ErrLog( <<"Could not open secondary database " << secondaryFileName << ": " << db_strerror(ret)); + mSane = false; + return; + } + + // Associate Secondary Database with Primary + mTableInfo[i].mSecondaryDb->set_app_private(this); // retrievable from callback so we can have access to this BerkeleyDb instance + ret = mTableInfo[i].mDb->associate(0, mTableInfo[i].mSecondaryDb, &getSecondaryKeyCallback, 0 /* flags */); + if(ret != 0) + { + ErrLog( <<"Could not associate secondary database " << secondaryFileName << ": " << db_strerror(ret)); + mSane = false; + return; + } + DebugLog( << "Opened secondary Berkeley DB: " << secondaryFileName ); + + ret = mTableInfo[i].mSecondaryDb->cursor(0, &mTableInfo[i].mSecondaryCursor, 0); + if(ret != 0) + { + ErrLog( <<"Could not secondary cursor on database " << secondaryFileName << ": " << db_strerror(ret)); + mSane = false; + return; + } + assert(mTableInfo[i].mSecondaryCursor); + } + } +} + + +BerkeleyDb::~BerkeleyDb() +{ + for (int i=0;i<MaxTable;i++) + { + if(mTableInfo[i].mSecondaryCursor) + { + mTableInfo[i].mSecondaryCursor->close(); + mTableInfo[i].mSecondaryCursor = 0; + } + + if(mTableInfo[i].mCursor) + { + mTableInfo[i].mCursor->close(); + mTableInfo[i].mCursor = 0; + } + + if(mTableInfo[i].mTransaction) + { + dbRollbackTransaction((Table)i); + } + + // Secondary DB should be closed before primary + if(mTableInfo[i].mSecondaryDb) + { + mTableInfo[i].mSecondaryDb->close(0); + delete mTableInfo[i].mSecondaryDb; + mTableInfo[i].mSecondaryDb = 0; + } + + if(mTableInfo[i].mDb) + { + mTableInfo[i].mDb->close(0); + delete mTableInfo[i].mDb; + mTableInfo[i].mDb = 0; + } + } + if(mEnv) + { + mEnv->txn_checkpoint(0, 0, 0); // Note: a checkpoint is run when this last is created and when it is destroyed + delete mEnv; + } +} + + +int +BerkeleyDb::getSecondaryKeyCallback(Db *db, const Dbt *pkey, const Dbt *pdata, Dbt *skey) +{ + BerkeleyDb* bdb = (BerkeleyDb*)db->get_app_private(); + + // Find associated table using db pointer + Table table = MaxTable; + for (int i=MaxTable-1; i >= 0; i--) // search backwards, since tables at the end have the secondary indexes + { + if(bdb->mTableInfo[i].mSecondaryDb == db) + { + table = (Table)i; + break; + } + } + assert(table != MaxTable); + + Data primaryKey(Data::Share, reinterpret_cast<const char*>(pkey->get_data()), pkey->get_size()); + Data primaryData(Data::Share, reinterpret_cast<const char*>(pdata->get_data()), pdata->get_size()); + void* secondaryKey; + unsigned int secondaryKeyLen; + int rc = bdb->getSecondaryKey(table, primaryKey, primaryData, &secondaryKey, &secondaryKeyLen); + skey->set_data(secondaryKey); + skey->set_size(secondaryKeyLen); + return rc; +} + + +bool +BerkeleyDb::dbWriteRecord(const Table table, + const resip::Data& pKey, + const resip::Data& pData ) +{ + Dbt key((void*)pKey.data(), (::u_int32_t)pKey.size()); + Dbt data((void*)pData.data(), (::u_int32_t)pData.size()); + int ret; + + assert(mTableInfo[table].mDb); + ret = mTableInfo[table].mDb->put(mTableInfo[table].mTransaction, &key, &data, 0); + + if(ret == 0 && mTableInfo[table].mTransaction == 0) + { + // If we are in a transaction, then it will sync on commit + mTableInfo[table].mDb->sync(0); + if(mTableInfo[table].mSecondaryDb) + { + mTableInfo[table].mSecondaryDb->sync(0); + } + } + return ret == 0; +} + + +bool +BerkeleyDb::dbReadRecord(const Table table, + const resip::Data& pKey, + resip::Data& pData) const +{ + Dbt key((void*)pKey.data(), (::u_int32_t)pKey.size()); + Dbt data; + data.set_flags(DB_DBT_MALLOC); // required for DB_THREAD flag use + + int ret; + + assert(mTableInfo[table].mDb); + ret = mTableInfo[table].mDb->get(mTableInfo[table].mTransaction, &key, &data, 0); + + if (ret == DB_NOTFOUND) + { + // key not found + if (data.get_data()) + { + free(data.get_data()); + } + return false; + } + assert(ret != DB_KEYEMPTY); + assert(ret == 0); + pData.copy(reinterpret_cast<const char*>(data.get_data()), data.get_size()); + if (data.get_data()) + { + free(data.get_data()); + } + if(pData.empty()) + { + // this should never happen + return false; + } + + return true; +} + + +void +BerkeleyDb::dbEraseRecord(const Table table, + const resip::Data& pKey, + bool isSecondaryKey) // allows deleting records from a table that supports secondary keying using a secondary key +{ + Dbt key((void*) pKey.data(), (::u_int32_t)pKey.size()); + + Db* db = mTableInfo[table].mDb; + if(isSecondaryKey && mTableInfo[table].mSecondaryDb) + { + db = mTableInfo[table].mSecondaryDb; + } + assert(db); + db->del(mTableInfo[table].mTransaction, &key, 0); + if(mTableInfo[table].mTransaction == 0) + { + // If we are in a transaction, then it will sync on commit + mTableInfo[table].mDb->sync(0); + if(mTableInfo[table].mSecondaryDb) + { + mTableInfo[table].mSecondaryDb->sync(0); + } + } +} + + +resip::Data +BerkeleyDb::dbNextKey(const Table table, + bool first) +{ + Dbt key, data; + int ret; + + assert(mTableInfo[table].mDb); + ret = mTableInfo[table].mCursor->get(&key, &data, first ? DB_FIRST : DB_NEXT); + if (ret == DB_NOTFOUND) + { + return Data::Empty; + } + assert(ret == 0); + + Data d(Data::Share, reinterpret_cast<const char*>(key.get_data()), key.get_size()); + return d; +} + + +bool +BerkeleyDb::dbNextRecord(const Table table, + const resip::Data& key, + resip::Data& data, + bool forUpdate, // specifies to use DB_RMW flag to write lock reads + bool first) +{ + Dbt dbkey((void*) key.data(), (::u_int32_t)key.size()); + Dbt dbdata; + int ret; + + assert(mTableInfo[table].mSecondaryCursor); + if(mTableInfo[table].mSecondaryCursor == 0) + { + // Iterating across multiple records with a common key is only + // supported on Seconday databases where duplicate keys exist + return false; + } + + unsigned int flags = 0; + if(key.empty()) + { + flags = first ? DB_FIRST : DB_NEXT; + } + else + { + flags = first ? DB_SET : DB_NEXT_DUP; + } + +#ifdef USE_DBENV + if(forUpdate) + { + flags |= DB_RMW; + } +#endif + + ret = mTableInfo[table].mSecondaryCursor->get(&dbkey, &dbdata, flags); + if (ret == DB_NOTFOUND) + { + return false; + } + assert(ret == 0); + data.copy(reinterpret_cast<const char*>(dbdata.get_data()), dbdata.get_size()); + + return true; +} + +bool +BerkeleyDb::dbBeginTransaction(const Table table) +{ +#ifdef USE_DBENV + // For now - we support transactions on the primary table only + assert(mDb); + assert(mTableInfo[table].mTransaction == 0); + int ret = mTableInfo[table].mDb->get_env()->txn_begin(0 /* parent trans*/, &mTableInfo[table].mTransaction, 0); + if(ret != 0) + { + ErrLog( <<"Could not begin transaction: " << db_strerror(ret)); + return false; + } + + // Open new Cursors - since cursors used in a transaction must be opened and closed within the transation + if(mTableInfo[table].mCursor) + { + mTableInfo[table].mCursor->close(); + mTableInfo[table].mCursor = 0; + } + + ret = mTableInfo[table].mDb->cursor(mTableInfo[table].mTransaction, &mTableInfo[table].mCursor, 0); + if(ret != 0) + { + ErrLog( <<"Could not open cursor for transaction: " << db_strerror(ret)); + } +#endif + + return true; +} + +bool +BerkeleyDb::dbCommitTransaction(const Table table) +{ + bool success = true; +#ifdef USE_DBENV + assert(mDb); + assert(mTableInfo[table].mTransaction); + + // Close the cursor - since cursors used in a transaction must be opened and closed within the transation + if(mTableInfo[table].mCursor) + { + mTableInfo[table].mCursor->close(); + mTableInfo[table].mCursor = 0; + } + + int ret = mTableInfo[table].mTransaction->commit(0); + mTableInfo[table].mTransaction = 0; + if(ret != 0) + { + ErrLog( <<"Could not commit transaction: " << db_strerror(ret)); + success = false; + } + + // Reopen a cursor for general use + mTableInfo[table].mDb->cursor(0, &mTableInfo[table].mCursor, 0); +#endif + + return success; +} + +bool +BerkeleyDb::dbRollbackTransaction(const Table table) +{ + bool success = true; +#ifdef USE_DBENV + assert(mDb); + assert(mTableInfo[table].mTransaction); + + // Close the cursor - since cursors used in a transaction must be opened and closed within the transation + if(mTableInfo[table].mCursor) + { + mTableInfo[table].mCursor->close(); + mTableInfo[table].mCursor = 0; + } + + int ret = mTableInfo[table].mTransaction->abort(); + mTableInfo[table].mTransaction = 0; + if(ret != 0) + { + success = false; + } + + // Reopen a cursor for general use + mTableInfo[table].mDb->cursor(0, &mTableInfo[table].mCursor, 0); +#endif + + return success; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/BerkeleyDb.hxx b/src/libs/resiprocate/repro/BerkeleyDb.hxx new file mode 100644 index 00000000..234990c8 --- /dev/null +++ b/src/libs/resiprocate/repro/BerkeleyDb.hxx @@ -0,0 +1,129 @@ +#if !defined(RESIP_BERKELEYDB_HXX) +#define RESIP_BERKELEYDB_HXX + +#ifdef WIN32 +#include <db_cxx.h> +#elif HAVE_CONFIG_H +#include "config.h" +#include DB_HEADER +//#elif defined(__APPLE__) +//#include <db42/db_cxx.h> +#else +#include <db_cxx.h> +#endif + +#include "rutil/Data.hxx" +#include "repro/AbstractDb.hxx" + +namespace resip +{ + class TransactionUser; +} + +namespace repro +{ + +class BerkeleyDb: public AbstractDb +{ + public: + BerkeleyDb(); + BerkeleyDb( const resip::Data& dbPath, const resip::Data& dbName = resip::Data::Empty ); + + virtual ~BerkeleyDb(); + + virtual bool isSane() {return mSane; } + + private: + void init(const resip::Data& dbPath, const resip::Data& dbName); + static int getSecondaryKeyCallback(Db *db, const Dbt *pkey, const Dbt *pdata, Dbt *skey); + + class TableInfo + { + public: + TableInfo() : mDb(0), mCursor(0), mTransaction(0), mSecondaryDb(0), mSecondaryCursor(0) {} + Db* mDb; + Dbc* mCursor; + DbTxn* mTransaction; + Db* mSecondaryDb; + Dbc* mSecondaryCursor; + }; + + DbEnv* mEnv; + TableInfo mTableInfo[MaxTable]; + + bool mSane; + + // Db manipulation routines + virtual bool dbWriteRecord(const Table table, + const resip::Data& key, + const resip::Data& data); + virtual bool dbReadRecord(const Table table, + const resip::Data& key, + resip::Data& data) const; // return false if not found + virtual void dbEraseRecord(const Table table, + const resip::Data& key, + bool isSecondaryKey=false); // allows deleting records from a table that supports secondary keying using a secondary key + virtual resip::Data dbNextKey(const Table table, + bool first=true); // return empty if no more + virtual bool dbNextRecord(const Table table, + const resip::Data& key, + resip::Data& data, + bool forUpdate, + bool first=false); // return false if no more + virtual bool dbBeginTransaction(const Table table); + virtual bool dbCommitTransaction(const Table table); + virtual bool dbRollbackTransaction(const Table table); +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/ChainTraverser.hxx b/src/libs/resiprocate/repro/ChainTraverser.hxx new file mode 100644 index 00000000..92baaec3 --- /dev/null +++ b/src/libs/resiprocate/repro/ChainTraverser.hxx @@ -0,0 +1,111 @@ +#ifndef CHAIN_TRAVERSAL_INTERFACE_HXX +#define CHAIN_TRAVERSAL_INTERFACE_HXX 1 + +#include <deque> +#include "repro/Processor.hxx" + +namespace repro +{ + + +class ChainTraverser +{ + public: + + ChainTraverser(const Processor& proc) + { + mReturnAddress=proc.getAddress(); + mType=proc.getChainType(); + } + + ChainTraverser(const ChainTraverser& orig) + { + mReturnAddress=orig.mReturnAddress; + mType=orig.mType; + } + + ~ChainTraverser(){} + + + void pushAddr(int addr) + { + mReturnAddress.push_back(addr); + } + + int popAddr() + { + if(mReturnAddress.empty()) + { + return 0; + } + + int addr = mReturnAddress.back(); + mReturnAddress.pop_back(); + return addr; + } + + Processor::ChainType chainType() const + { + return mType; + } + + protected: + std::vector<short> mReturnAddress; + Processor::ChainType mType; + + + +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/CommandLineParser.cxx b/src/libs/resiprocate/repro/CommandLineParser.cxx new file mode 100644 index 00000000..a2daffe0 --- /dev/null +++ b/src/libs/resiprocate/repro/CommandLineParser.cxx @@ -0,0 +1,319 @@ +#ifdef HAVE_CONFIG_H +#include <config.hxx> +#endif + +#if HAVE_POPT_H +#include <popt.h> +#endif + +#include "CommandLineParser.hxx" +#include "repro/ReproVersion.hxx" +#include "rutil/Logger.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/ParseException.hxx" +#include "resip/stack/InteropHelper.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +CommandLineParser::CommandLineParser(int argc, char** argv) +{ + const char* logType = "cout"; + const char* logLevel = "INFO"; + char* tlsDomain = 0; + int forceRecordRoute = 0; + char* recordRouteUri = 0; + int udpPort = 5060; + int tcpPort = 5060; +#if defined(USE_SSL) + int tlsPort = 5061; +#else + int tlsPort = 0; +#endif + int dtlsPort = 0; + int disableV4 = false; + int enableV6 = false; + char* domains = 0; + char* interfaces = 0; + char* routeSet = 0; + char certPathBuf[256]; + char* certPath = certPathBuf; + char* dbPath = "./"; + int noChallenge = false; + int noAuthIntChallenge = false; + int rejectBadNonces = false; + int noWebChallenge = false; + + int noRegistrar = false; + int noIdentityHeaders = false; + int certServer = false; + + const char* reqChainName = "default"; + char* mySqlServer = 0; + char* httpHostname = 0; + int httpPort = 5080; + int recursiveRedirect = 0; + int doQValue=0; + const char* forkBehavior="EQUAL_Q_PARALLEL"; + bool cancelBetweenForkGroups=true; + bool waitForTerminate=true; + int msBetweenForkGroups=3000;//Moot by default + int msBeforeCancel=3000; + + char* enumSuffix = 0; + int allowBadReg = 0; + int parallelForkStaticRoutes = 0; + int showVersion = 0; + int timerC=180; + + const char* adminPassword = ""; + int outboundDisabled=0; + int outboundVersion=11; + int rrTokenHackEnabled=0; + + mHttpHostname = DnsUtil::getLocalHostName(); + +#ifdef WIN32 +#ifndef HAVE_POPT_H + noChallenge = 1; // If no POPT, then default to no digest challenges +#endif + strcpy(certPath,"C:\\sipCerts"); +#else + strcpy(certPath, getenv("HOME")); + strcat(certPath, "/.sipCerts"); +#endif + +#ifdef HAVE_POPT_H + struct poptOption table[] = { + {"log-type", 'l', POPT_ARG_STRING| POPT_ARGFLAG_SHOW_DEFAULT, &logType, 0, "where to send logging messages", "syslog|cerr|cout"}, + {"log-level", 'v', POPT_ARG_STRING| POPT_ARGFLAG_SHOW_DEFAULT, &logLevel, 0, "specify the default log level", "STACK|DEBUG|INFO|WARNING|ALERT"}, + {"db-path", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &dbPath, 0, "path to databases", 0}, + {"record-route", 'r', POPT_ARG_STRING, &recordRouteUri, 0, "specify uri to use as Record-Route", "sip:example.com"}, + {"force-record-route", 0, POPT_ARG_NONE | POPT_ARGFLAG_SHOW_DEFAULT, &forceRecordRoute, 0, "force record-routing", 0}, +#if defined(USE_MYSQL) + {"mysqlServer", 'x', POPT_ARG_STRING| POPT_ARGFLAG_SHOW_DEFAULT, &mySqlServer, 0, "enable MySQL and provide name of server", "localhost"}, +#endif + {"udp", 0, POPT_ARG_INT| POPT_ARGFLAG_SHOW_DEFAULT, &udpPort, 0, "listen on UDP port", "5060"}, + {"tcp", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &tcpPort, 0, "listen on TCP port", "5060"}, +#if defined(USE_SSL) + {"tls-domain", 't', POPT_ARG_STRING, &tlsDomain, 0, "act as a TLS server for specified domain", "example.com"}, + {"tls", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &tlsPort, 0, "add TLS transport on specified port", "5061"}, + {"dtls", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &dtlsPort, 0, "add DTLS transport on specified port", "0"}, + {"enable-cert-server", 0, POPT_ARG_NONE | POPT_ARGFLAG_SHOW_DEFAULT, &certServer, 0, "run a cert server", 0}, +#ifdef WIN32 + {"cert-path", 'c', POPT_ARG_STRING| POPT_ARGFLAG_SHOW_DEFAULT, &certPath, 0, "path to certificates", 0}, +#else + {"cert-path", 'c', POPT_ARG_STRING| POPT_ARGFLAG_SHOW_DEFAULT, &certPath, 0, "path to certificates", 0}, +#endif +#endif + {"enable-v6", 0, POPT_ARG_NONE, &enableV6, 0, "enable IPV6", 0}, + {"disable-v4", 0, POPT_ARG_NONE, &disableV4, 0, "disable IPV4", 0}, + {"disable-auth", 0, POPT_ARG_NONE, &noChallenge, 0, "disable DIGEST challenges", 0}, + {"disable-auth-int", 0, POPT_ARG_NONE, &noAuthIntChallenge,0, "disable auth-int DIGEST challenges", 0}, + {"reject-bad-nonces", 0, POPT_ARG_NONE, &rejectBadNonces,0, "Send 403 if a client sends a bad nonce in their credentials (will send a new challenge otherwise)", 0}, + {"disable-web-auth", 0, POPT_ARG_NONE, &noWebChallenge, 0, "disable HTTP challenges", 0}, + {"disable-reg", 0, POPT_ARG_NONE, &noRegistrar, 0, "disable registrar", 0}, + {"disable-identity", 0, POPT_ARG_NONE, &noIdentityHeaders, 0, "disable adding identity headers", 0}, + {"interfaces", 'i', POPT_ARG_STRING, &interfaces, 0, "specify interfaces to add transports to", "sip:10.1.1.1:5065;transport=tls;tls=tlsdomain.com"}, + {"domains", 'd', POPT_ARG_STRING, &domains, 0, "specify domains that this proxy is authorative", "example.com,foo.com"}, + {"route", 'R', POPT_ARG_STRING, &routeSet, 0, "specify where to route requests that are in this proxy's domain", "sip:p1.example.com,sip:p2.example.com"}, + {"reqChainName", 0, POPT_ARG_STRING, &reqChainName, 0, "name of request chain (default: default)", 0}, + {"http", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &httpPort, 0, "run HTTP server on specified port", 0}, + {"http-hostname", 0, POPT_ARG_STRING, &httpHostname, 0, "http hostname for this server (used in Identity headers)", 0}, + {"recursive-redirect",0, POPT_ARG_NONE, &recursiveRedirect, 0, "Handle 3xx responses in the proxy", 0}, + {"q-value", 0, POPT_ARG_NONE, &doQValue, 0, "Enable sequential q-value processing", 0}, + {"q-value-behavior", 0, POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &forkBehavior, 0, "Specify forking behavior for q-value targets: FULL_SEQUENTIAL, EQUAL_Q_PARALLEL, or FULL_PARALLEL", 0}, + {"q-value-cancel-btw-fork-groups",0,POPT_ARG_NONE, &cancelBetweenForkGroups, 0, "Whether to cancel groups of parallel forks after the period specified by the --q-value-ms-before-cancel parameter.", 0}, + {"q-value-wait-for-terminate-btw-fork-groups",0,POPT_ARG_NONE, &waitForTerminate, 0, "Whether to wait for parallel fork groups to terminate before starting new fork-groups.", 0}, + {"q-value-ms-between-fork-groups",0,POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &msBetweenForkGroups, 0, "msec to wait before starting new groups of parallel forks", 0}, + {"q-value-ms-before-cancel",0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &msBeforeCancel, 0, "msec to wait before cancelling parallel fork groups", 0}, + {"enum-suffix", 'e', POPT_ARG_STRING, &enumSuffix, 0, "specify enum suffix to search", "e164.arpa"}, + {"allow-bad-reg", 'b', POPT_ARG_NONE, &allowBadReg, 0, "allow To tag in registrations", 0}, + {"parallel-fork-static-routes",'p',POPT_ARG_NONE, &parallelForkStaticRoutes, 0, "paralled fork to all matching static routes and (first batch) registrations", 0}, + {"timer-C", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &timerC, 0, "specify length of timer C in sec (0 or negative will disable timer C)", 0}, + {"admin-password", 'a', POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &adminPassword, 0, "set web administrator password", 0}, + {"disable-outbound",0, POPT_ARG_NONE, &outboundDisabled,0, "disable outbound support (draft-ietf-sip-outbound)", 0}, + {"outbound-version",0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &outboundVersion, 0, "set the version of outbound to support", 0}, + {"enable-flow-tokens",0, POPT_ARG_NONE, &rrTokenHackEnabled,0, "enable use of flow-tokens in non-outbound cases (This is a workaround, and it is broken. Only use it if you have to.)", 0}, + {"version", 'V', POPT_ARG_NONE, &showVersion, 0, "show the version number and exit", 0}, + POPT_AUTOHELP + { NULL, 0, 0, NULL, 0 } + }; + + poptContext context = poptGetContext(NULL, argc, const_cast<const char**>(argv), table, 0); + if (poptGetNextOpt(context) < -1) + { + cerr << "Bad command line argument entered" << endl; + poptPrintHelp(context, stderr, 0); + exit(-1); + } +#endif + + mHttpPort = httpPort; + mLogType = logType; + mLogLevel = logLevel; + + if (showVersion) + { + cout << repro::VersionUtils::instance().displayVersion() << endl; + exit(0); + } + + if (tlsDomain) + { + mTlsDomain = tlsDomain; + } + + mForceRecordRoute = (forceRecordRoute!=0); + + if (recordRouteUri) + { + mRecordRoute = toUri(recordRouteUri, "Record-Route"); + // .bwc. You must give a fully specified hostname for the record-route. + // Furthermore, you should ensure that this uri will allow a + // 3263-compliant sender to know what transports this proxy supports, and + // how to reach it over any of these transports. (ie, set up your full + // NAPTR->SRV->A or AAAA DNS zone for this uri) For senders that don't + // support 3263 (ie, they just assume that a proxy supports a given + // ip-version and protocol, and do A or AAAA lookups), this won't work all + // the time. This is their fault, not yours. + assert(!mRecordRoute.host().empty()); + } + + mUdpPort = udpPort; + mTcpPort = tcpPort; + mTlsPort = tlsPort; + mDtlsPort = dtlsPort; + mUseV4 = !disableV4; + mUseV6 = enableV6?true:false; + mInterfaces = toVector(interfaces, "interfaces"); + mDomains = toVector(domains, "domains"); + mRouteSet = toVector(routeSet, "routeSet"); + mCertPath = certPath; + mNoChallenge = noChallenge != 0; + mNoAuthIntChallenge = noAuthIntChallenge != 0; + mRejectBadNonces = rejectBadNonces != 0; + mNoWebChallenge = noWebChallenge != 0; + mNoRegistrar = noRegistrar != 0 ; + mNoIdentityHeaders = noIdentityHeaders != 0; + mCertServer = certServer !=0 ; + mRequestProcessorChainName=reqChainName; + mRecursiveRedirect = recursiveRedirect?true:false; + mDoQValue = doQValue?true:false; + mForkBehavior=forkBehavior; + mCancelBetweenForkGroups=cancelBetweenForkGroups?true:false; + mWaitForTerminate=waitForTerminate?true:false; + mMsBetweenForkGroups=msBetweenForkGroups; + mMsBeforeCancel=msBeforeCancel; + mAllowBadReg = allowBadReg?true:false; + mParallelForkStaticRoutes = parallelForkStaticRoutes?true:false; + if (enumSuffix) mEnumSuffix = enumSuffix; + + if (mySqlServer) + { + mMySqlServer = mySqlServer; + } + + if (dbPath) + { + mDbPath = dbPath; + } + + if(httpHostname) + { + mHttpHostname = httpHostname; + } + + if(timerC >0) + { + mTimerC=timerC; + } + else + { + mTimerC=0; + } + + mAdminPassword = adminPassword; + + InteropHelper::setOutboundVersion(outboundVersion); + InteropHelper::setOutboundSupported(outboundDisabled ? false : true); + InteropHelper::setRRTokenHackEnabled((rrTokenHackEnabled==0) ? false : true); + + if((InteropHelper::getOutboundSupported() + || InteropHelper::getRRTokenHackEnabled() + || mForceRecordRoute + ) + && !recordRouteUri) + { + CritLog(<< "In order for outbound support, the Record-Route flow-token" + " hack, or force-record-route to work, you MUST specify a Record-Route URI. Launching " + "without..."); + InteropHelper::setOutboundSupported(false); + InteropHelper::setRRTokenHackEnabled(false); + mForceRecordRoute=false; + } + +#ifdef HAVE_POPT_H + poptFreeContext(context); +#endif +} + +resip::Uri +CommandLineParser::toUri(const char* input, const char* description) +{ + resip::Uri uri; + try + { + if (input) + { + uri = Uri(input); + } + else + { + std::cerr << "No " << description << " specified" << std::endl; + } + } + catch (ParseException& e) + { + std::cerr << "Caught: " << e << std::endl; + std::cerr << "Can't parse " << description << " : " << input << std::endl; + exit(-1); + } + return uri; +} + +std::vector<resip::Data> +CommandLineParser::toVector(const char* input, const char* description) +{ + std::vector<Data> domains; + + if (input) + { + Data buffer = input; + if (input) + { + for (char* token = strtok(const_cast<char*>(buffer.c_str()), ","); token != 0; token = strtok(0, ",")) + { + try + { + domains.push_back(token); + } + catch (ParseException& e) + { + std::cout << "Caught: " << e << std::endl; + std::cerr << "Can't parse " << description << " : " << token << std::endl; + exit(-1); + } + catch (...) + { + std::cout << "Caught some exception" <<std::endl; + std::cerr << "Some problem parsing " << description << " : " << token << std::endl; + } + } + } + } + return domains; +} + diff --git a/src/libs/resiprocate/repro/CommandLineParser.hxx b/src/libs/resiprocate/repro/CommandLineParser.hxx new file mode 100644 index 00000000..a467c5d4 --- /dev/null +++ b/src/libs/resiprocate/repro/CommandLineParser.hxx @@ -0,0 +1,62 @@ +#if !defined(DUM_CommandLineParser_hxx) +#define DUM_CommandLineParser_hxx + +#include <vector> +#include "resip/stack/Uri.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +class CommandLineParser +{ + public: + CommandLineParser(int argc, char** argv); + static resip::Uri toUri(const char* input, const char* description); + static std::vector<resip::Data> toVector(const char* input, const char* description); + + Data mLogType; + Data mLogLevel; + Data mTlsDomain; + Data mEnumSuffix; + bool mForceRecordRoute; + resip::Uri mRecordRoute; + int mUdpPort; + int mTcpPort; + int mTlsPort; + int mDtlsPort; + bool mUseV4; + bool mUseV6; + std::vector<Data> mDomains; + std::vector<Data> mInterfaces; + std::vector<Data> mRouteSet; + Data mCertPath; + Data mDbPath; + bool mNoChallenge; + bool mNoAuthIntChallenge; + bool mRejectBadNonces; + bool mNoWebChallenge; + bool mNoRegistrar; + bool mNoIdentityHeaders; + bool mCertServer; + Data mRequestProcessorChainName; + Data mMySqlServer; + Data mHttpHostname; + int mHttpPort; + bool mRecursiveRedirect; + bool mDoQValue; + Data mForkBehavior; + bool mCancelBetweenForkGroups; + bool mWaitForTerminate; + int mMsBetweenForkGroups; + int mMsBeforeCancel; + bool mAllowBadReg; + bool mParallelForkStaticRoutes; + int mTimerC; + Data mAdminPassword; +}; + +} + +#endif + diff --git a/src/libs/resiprocate/repro/CommandServer.cxx b/src/libs/resiprocate/repro/CommandServer.cxx new file mode 100644 index 00000000..a23cc16b --- /dev/null +++ b/src/libs/resiprocate/repro/CommandServer.cxx @@ -0,0 +1,435 @@ +#include <cassert> +#include <sstream> +#include <signal.h> + +#include <resip/stack/Symbols.hxx> +#include <resip/stack/Tuple.hxx> +#include <resip/stack/SipStack.hxx> +#include <rutil/GeneralCongestionManager.hxx> +#include <rutil/Data.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/Logger.hxx> +#include <rutil/ParseBuffer.hxx> +#include <rutil/Socket.hxx> +#include <rutil/TransportType.hxx> +#include <rutil/Timer.hxx> + +#include "repro/XmlRpcServerBase.hxx" +#include "repro/XmlRpcConnection.hxx" +#include "repro/ReproRunner.hxx" +#include "repro/CommandServer.hxx" + +using namespace repro; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + + +CommandServer::CommandServer(ReproRunner& reproRunner, + int port, + IpVersion version) : + XmlRpcServerBase(port, version), + mReproRunner(reproRunner) +{ + reproRunner.getProxy()->getStack().setExternalStatsHandler(this); +} + +CommandServer::~CommandServer() +{ +} + +void +CommandServer::sendResponse(unsigned int connectionId, + unsigned int requestId, + const Data& responseData, + unsigned int resultCode, + const Data& resultText) +{ + std::stringstream ss; + ss << Symbols::CRLF << " <Result Code=\"" << resultCode << "\""; + ss << ">" << resultText.xmlCharDataEncode() << "</Result>" << Symbols::CRLF; + if(!responseData.empty()) + { + ss << " <Data>" << Symbols::CRLF; + ss << responseData; + ss << " </Data>" << Symbols::CRLF; + } + XmlRpcServerBase::sendResponse(connectionId, requestId, ss.str().c_str(), resultCode >= 200 /* isFinal */); +} + +void +CommandServer::handleRequest(unsigned int connectionId, unsigned int requestId, const resip::Data& request) +{ + DebugLog (<< "CommandServer::handleRequest: connectionId=" << connectionId << ", requestId=" << requestId << ", request=\r\n" << request); + + try + { + ParseBuffer pb(request); + XMLCursor xml(pb); + + if(!mReproRunner.getProxy()) + { + sendResponse(connectionId, requestId, Data::Empty, 400, "Proxy not running."); + return; + } + + if(isEqualNoCase(xml.getTag(), "GetStackInfo")) + { + handleGetStackInfoRequest(connectionId, requestId, xml); + } + else if(isEqualNoCase(xml.getTag(), "GetStackStats")) + { + handleGetStackStatsRequest(connectionId, requestId, xml); + } + else if(isEqualNoCase(xml.getTag(), "ResetStackStats")) + { + handleResetStackStatsRequest(connectionId, requestId, xml); + } + else if(isEqualNoCase(xml.getTag(), "LogDnsCache")) + { + handleLogDnsCacheRequest(connectionId, requestId, xml); + } + else if(isEqualNoCase(xml.getTag(), "ClearDnsCache")) + { + handleClearDnsCacheRequest(connectionId, requestId, xml); + } + else if(isEqualNoCase(xml.getTag(), "GetDnsCache")) + { + handleGetDnsCacheRequest(connectionId, requestId, xml); + } + else if(isEqualNoCase(xml.getTag(), "GetCongestionStats")) + { + handleGetCongestionStatsRequest(connectionId, requestId, xml); + } + else if(isEqualNoCase(xml.getTag(), "SetCongestionTolerance")) + { + handleSetCongestionToleranceRequest(connectionId, requestId, xml); + } + else if(isEqualNoCase(xml.getTag(), "Shutdown")) + { + handleShutdownRequest(connectionId, requestId, xml); + } + else if(isEqualNoCase(xml.getTag(), "GetProxyConfig")) + { + handleGetProxyConfigRequest(connectionId, requestId, xml); + } + else if(isEqualNoCase(xml.getTag(), "Restart")) + { + handleRestartRequest(connectionId, requestId, xml); + } + else + { + WarningLog(<< "CommandServer::handleRequest: Received XML message with unknown method: " << xml.getTag()); + sendResponse(connectionId, requestId, Data::Empty, 400, "Unknown method"); + } + } + catch(resip::BaseException& e) + { + WarningLog(<< "CommandServer::handleRequest: ParseException: " << e); + sendResponse(connectionId, requestId, Data::Empty, 400, "Parse error"); + } +} + +void +CommandServer::handleGetStackInfoRequest(unsigned int connectionId, unsigned int requestId, XMLCursor& xml) +{ + InfoLog(<< "CommandServer::handleGetStackInfoRequest"); + + Data buffer; + DataStream strm(buffer); + mReproRunner.getProxy()->getStack().dump(strm); + strm.flush(); + + sendResponse(connectionId, requestId, buffer, 200, "Stack info retrieved."); +} + +void +CommandServer::handleGetStackStatsRequest(unsigned int connectionId, unsigned int requestId, XMLCursor& xml) +{ + InfoLog(<< "CommandServer::handleGetStackStatsRequest"); + + Lock lock(mStatisticsWaitersMutex); + mStatisticsWaiters.push_back(std::make_pair(connectionId, requestId)); + + if(!mReproRunner.getProxy()->getStack().pollStatistics()) + { + sendResponse(connectionId, requestId, Data::Empty, 400, "Statistics Manager is not enabled."); + } +} + +bool +CommandServer::operator()(resip::StatisticsMessage &statsMessage) +{ + Lock lock(mStatisticsWaitersMutex); + if(mStatisticsWaiters.size() > 0) + { + Data buffer; + DataStream strm(buffer); + StatisticsMessage::Payload payload; + statsMessage.loadOut(payload); // !slg! could optimize by providing stream operator on StatisticsMessage + strm << payload << endl; + + StatisticsWaitersList::iterator it = mStatisticsWaiters.begin(); + for(; it != mStatisticsWaiters.end(); it++) + { + sendResponse(it->first, it->second, buffer, 200, "Stack stats retrieved."); + } + } + return true; +} + +void +CommandServer::handleResetStackStatsRequest(unsigned int connectionId, unsigned int requestId, XMLCursor& xml) +{ + InfoLog(<< "CommandServer::handleResetStackStatsRequest"); + + mReproRunner.getProxy()->getStack().zeroOutStatistics(); + sendResponse(connectionId, requestId, Data::Empty, 200, "Stack stats reset."); +} + +void +CommandServer::handleLogDnsCacheRequest(unsigned int connectionId, unsigned int requestId, XMLCursor& xml) +{ + InfoLog(<< "CommandServer::handleLogDnsCacheRequest"); + + mReproRunner.getProxy()->getStack().logDnsCache(); + sendResponse(connectionId, requestId, Data::Empty, 200, "DNS cache logged."); +} + +void +CommandServer::handleClearDnsCacheRequest(unsigned int connectionId, unsigned int requestId, XMLCursor& xml) +{ + InfoLog(<< "CommandServer::handleQueryDnsCacheRequest"); + + mReproRunner.getProxy()->getStack().clearDnsCache(); + sendResponse(connectionId, requestId, Data::Empty, 200, "DNS cache cleared."); +} + +void +CommandServer::handleGetDnsCacheRequest(unsigned int connectionId, unsigned int requestId, XMLCursor& xml) +{ + InfoLog(<< "CommandServer::handleGetDnsCacheRequest"); + + mReproRunner.getProxy()->getStack().getDnsCacheDump(make_pair((unsigned long)connectionId, (unsigned long)requestId), this); + // Note: Response will be sent when callback is invoked +} + +void +CommandServer::onDnsCacheDumpRetrieved(std::pair<unsigned long, unsigned long> key, const Data& dnsCache) +{ + if(dnsCache.empty()) + { + sendResponse(key.first, key.second, "empty\r\n", 200, "DNS cache retrieved."); + } + else + { + sendResponse(key.first, key.second, dnsCache, 200, "DNS cache retrieved."); + } +} + +void +CommandServer::handleGetCongestionStatsRequest(unsigned int connectionId, unsigned int requestId, XMLCursor& xml) +{ + InfoLog(<< "CommandServer::handleGetCongestionStatsRequest"); + + CongestionManager* congestionManager = mReproRunner.getProxy()->getStack().getCongestionManager(); + if(congestionManager != 0) + { + Data buffer; + DataStream strm(buffer); + congestionManager->encodeCurrentState(strm); + + sendResponse(connectionId, requestId, buffer, 200, "Congestion stats retrieved."); + } + else + { + sendResponse(connectionId, requestId, Data::Empty, 400, "Congestion Manager is not enabled."); + } +} + +void +CommandServer::handleSetCongestionToleranceRequest(unsigned int connectionId, unsigned int requestId, XMLCursor& xml) +{ + InfoLog(<< "CommandServer::handleSetCongestionToleranceRequest"); + + Data fifoDescription; + Data metricData; + GeneralCongestionManager::MetricType metric; + unsigned long maxTolerance=0; + + GeneralCongestionManager* congestionManager = dynamic_cast<GeneralCongestionManager*>(mReproRunner.getProxy()->getStack().getCongestionManager()); + if(congestionManager != 0) + { + // Check for Parameters + if(xml.firstChild()) + { + if(isEqualNoCase(xml.getTag(), "request")) + { + if(xml.firstChild()) + { + while(true) + { + if(isEqualNoCase(xml.getTag(), "fifoDescription")) + { + if(xml.firstChild()) + { + fifoDescription = xml.getValue(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "metric")) + { + if(xml.firstChild()) + { + metricData = xml.getValue(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "maxtolerance")) + { + if(xml.firstChild()) + { + maxTolerance = xml.getValue().convertUnsignedLong(); + xml.parent(); + } + } + if(!xml.nextSibling()) + { + // break on no more sibilings + break; + } + } + xml.parent(); + } + } + xml.parent(); + } + + if(isEqualNoCase(metricData, "WAIT_TIME")) + { + metric = GeneralCongestionManager::WAIT_TIME; + } + else if(isEqualNoCase(metricData, "TIME_DEPTH")) + { + metric = GeneralCongestionManager::TIME_DEPTH; + } + else if(isEqualNoCase(metricData, "SIZE")) + { + metric = GeneralCongestionManager::SIZE; + } + else + { + sendResponse(connectionId, requestId, Data::Empty, 400, "Invalid metric specified: must be SIZE, TIME_DEPTH or WAIT_TIME."); + return; + } + + if(maxTolerance == 0) + { + sendResponse(connectionId, requestId, Data::Empty, 400, "Invalid MaxTolerance specified: must be greater than 0."); + return; + } + + if(congestionManager->updateFifoTolerances(fifoDescription, metric, maxTolerance)) + { + sendResponse(connectionId, requestId, Data::Empty, 200, "Congestion Tolerance set."); + } + else + { + sendResponse(connectionId, requestId, Data::Empty, 400, "Invalid fifo description provided."); + } + } + else + { + sendResponse(connectionId, requestId, Data::Empty, 400, "Congestion Manager is not enabled."); + } +} + +void +CommandServer::handleShutdownRequest(unsigned int connectionId, unsigned int requestId, XMLCursor& xml) +{ + InfoLog(<< "CommandServer::handleShutdownRequest"); + + sendResponse(connectionId, requestId, Data::Empty, 200, "Shutdown initiated."); + raise(SIGTERM); +} + +void +CommandServer::handleGetProxyConfigRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml) +{ + InfoLog(<< "CommandServer::handleGetProxyConfigRequest"); + + Data buffer; + DataStream strm(buffer); + strm << mReproRunner.getProxy()->getConfig(); + + sendResponse(connectionId, requestId, buffer, 200, "Proxy config retrieved."); +} + +void +CommandServer::handleRestartRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml) +{ + InfoLog(<< "CommandServer::handleRestartRequest"); + + mReproRunner.restart(); + if(mReproRunner.getProxy()) + { + mReproRunner.getProxy()->getStack().setExternalStatsHandler(this); + sendResponse(connectionId, requestId, Data::Empty, 200, "Restart completed."); + } + else + { + sendResponse(connectionId, requestId, Data::Empty, 200, "Restart failed."); + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/CommandServer.hxx b/src/libs/resiprocate/repro/CommandServer.hxx new file mode 100644 index 00000000..42bbd52a --- /dev/null +++ b/src/libs/resiprocate/repro/CommandServer.hxx @@ -0,0 +1,121 @@ +#if !defined(CommandServer_hxx) +#define CommandServer_hxx + +#include <rutil/Data.hxx> +#include <rutil/dns/DnsStub.hxx> +#include <rutil/TransportType.hxx> +#include <rutil/XMLCursor.hxx> +#include <resip/stack/StatisticsHandler.hxx> +#include <resip/stack/StatisticsMessage.hxx> +#include <resip/dum/InMemorySyncRegDb.hxx> +#include "repro/XmlRpcServerBase.hxx" +#include "repro/Proxy.hxx" + +namespace resip +{ +class SipStack; +} + +namespace repro +{ +class ReproRunner; + +class CommandServer: public XmlRpcServerBase, + public resip::GetDnsCacheDumpHandler, + public resip::ExternalStatsHandler +{ +public: + CommandServer(ReproRunner& reproRunner, + int port, + resip::IpVersion version); + virtual ~CommandServer(); + + // thread safe + virtual void sendResponse(unsigned int connectionId, + unsigned int requestId, + const resip::Data& responseData, + unsigned int resultCode, + const resip::Data& resultText); + +protected: + virtual void handleRequest(unsigned int connectionId, + unsigned int requestId, + const resip::Data& request); + + // Handlers + virtual void onDnsCacheDumpRetrieved(std::pair<unsigned long, unsigned long> key, const resip::Data& dnsEntryStrings); + virtual bool operator()(resip::StatisticsMessage &statsMessage); + +private: + void handleGetStackInfoRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml); + void handleGetStackStatsRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml); + void handleResetStackStatsRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml); + void handleLogDnsCacheRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml); + void handleClearDnsCacheRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml); + void handleGetDnsCacheRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml); + void handleGetCongestionStatsRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml); + void handleSetCongestionToleranceRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml); + void handleShutdownRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml); + void handleGetProxyConfigRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml); + void handleRestartRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml); + + ReproRunner& mReproRunner; + resip::Mutex mStatisticsWaitersMutex; + typedef std::list<std::pair<unsigned int, unsigned int> > StatisticsWaitersList; + StatisticsWaitersList mStatisticsWaiters; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/CommandServerThread.cxx b/src/libs/resiprocate/repro/CommandServerThread.cxx new file mode 100644 index 00000000..aa6b1f9e --- /dev/null +++ b/src/libs/resiprocate/repro/CommandServerThread.cxx @@ -0,0 +1,98 @@ +#include <rutil/Socket.hxx> +#include <rutil/Logger.hxx> + +#include "repro/CommandServer.hxx" +#include "repro/CommandServerThread.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +using namespace repro; +using namespace resip; +using namespace std; + +CommandServerThread::CommandServerThread(const std::list<CommandServer*>& commandServerList) + : mCommandServerList(commandServerList) +{ +} + +void +CommandServerThread::thread() +{ + while (!isShutdown()) + { + try + { + FdSet fdset; + + std::list<CommandServer*>::iterator it = mCommandServerList.begin(); + for(;it!=mCommandServerList.end();it++) + { + (*it)->buildFdSet(fdset); + } + fdset.selectMilliSeconds( 2*1000 ); + + it = mCommandServerList.begin(); + for(;it!=mCommandServerList.end();it++) + { + (*it)->process(fdset); + } + } + catch (...) + { + ErrLog (<< "CommandServerThread::thread: Unhandled exception: " ); + } + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/repro/CommandServerThread.hxx b/src/libs/resiprocate/repro/CommandServerThread.hxx new file mode 100644 index 00000000..5e8f2422 --- /dev/null +++ b/src/libs/resiprocate/repro/CommandServerThread.hxx @@ -0,0 +1,80 @@ +#if !defined(CommandServerThread_hxx) +#define CommandServerThread_hxx + +#include <list> +#include <rutil/ThreadIf.hxx> +#include <rutil/Socket.hxx> + +namespace repro +{ +class CommandServer; + +class CommandServerThread : public resip::ThreadIf +{ +public: + CommandServerThread(const std::list<CommandServer*>& commandServerList); + +protected: + +private: + virtual void thread(); + std::list<CommandServer*> mCommandServerList; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + + diff --git a/src/libs/resiprocate/repro/ConfigStore.cxx b/src/libs/resiprocate/repro/ConfigStore.cxx new file mode 100644 index 00000000..a8694c38 --- /dev/null +++ b/src/libs/resiprocate/repro/ConfigStore.cxx @@ -0,0 +1,142 @@ + +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Lock.hxx" +#include "resip/stack/Uri.hxx" + +#include "repro/ConfigStore.hxx" + + +using namespace resip; +using namespace repro; +using namespace std; + + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + + +ConfigStore::ConfigStore(AbstractDb& db): + mDb(db) +{ + AbstractDb::ConfigRecordList input = mDb.getAllConfigs(); + for (AbstractDb::ConfigRecordList::const_iterator it = input.begin(); + it != input.end(); it++) + { + mCachedConfigData[it->mDomain] = *it; + } +} + + +ConfigStore::~ConfigStore() +{ +} + + +bool +ConfigStore::addDomain(const resip::Data& domain, + const int tlsPort ) +{ + InfoLog( << "Add domain " << domain << " to config." ); + + AbstractDb::ConfigRecord rec; + rec.mDomain = domain; + rec.mTlsPort = tlsPort; + + if(!mDb.addConfig(buildKey(domain), rec)) + { + return false; + } + + { + Lock lock(mMutex, VOCAL_WRITELOCK); + mCachedConfigData[domain] = rec; + } + return true; +} + + +const ConfigStore::ConfigData& +ConfigStore::getConfigs() const +{ + // LOCKING NOTE: From an API perspective this method dangerous, but we know that the WebAdmin Thread is currently + // the only thread requiring a WRITE lock and is the only thread calling this function, so + // locking is not required + return mCachedConfigData; +} + + +int +ConfigStore::getTlsPort(const resip::Data& domain) +{ + Lock lock(mMutex, VOCAL_READLOCK); + ConfigData::const_iterator it = mCachedConfigData.find(domain); + if(it != mCachedConfigData.end()) + { + return it->second.mTlsPort; + } + + return 0; +} + + +void +ConfigStore::eraseDomain(const resip::Data& domain) +{ + mDb.eraseConfig( buildKey(domain) ); + { + Lock lock(mMutex, VOCAL_WRITELOCK); + mCachedConfigData.erase(domain); + } +} + + +AbstractDb::Key +ConfigStore::buildKey(const resip::Data& domain ) const +{ + return domain; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/ConfigStore.hxx b/src/libs/resiprocate/repro/ConfigStore.hxx new file mode 100644 index 00000000..11e2655c --- /dev/null +++ b/src/libs/resiprocate/repro/ConfigStore.hxx @@ -0,0 +1,83 @@ +#if !defined(REPRO_CONFIGSTORE_HXX) +#define REPRO_CONFIGSTORE_HXX + +#include "rutil/Data.hxx" +#include "rutil/RWMutex.hxx" + +#include "repro/AbstractDb.hxx" +#include <map> + + +namespace repro +{ + +class ConfigStore +{ + public: + typedef std::map<resip::Data,AbstractDb::ConfigRecord> ConfigData; + + ConfigStore(AbstractDb& db); + ~ConfigStore(); + + bool addDomain(const resip::Data& domain, + const int tlsPort); + + const ConfigData& getConfigs() const; + int getTlsPort(const resip::Data& domain); + + void eraseDomain(const resip::Data& domain); + + private: + AbstractDb& mDb; + + AbstractDb::Key buildKey(const resip::Data& domain) const; + resip::RWMutex mMutex; + ConfigData mCachedConfigData; +}; + + } +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/Dispatcher.cxx b/src/libs/resiprocate/repro/Dispatcher.cxx new file mode 100644 index 00000000..f3d5520e --- /dev/null +++ b/src/libs/resiprocate/repro/Dispatcher.cxx @@ -0,0 +1,187 @@ +#include "repro/Dispatcher.hxx" +#include "resip/stack/Message.hxx" +#include "resip/stack/SipStack.hxx" +#include "rutil/WinLeakCheck.hxx" + + +namespace repro +{ + +Dispatcher::Dispatcher(std::auto_ptr<Worker> prototype, + resip::SipStack* stack, + int workers, + bool startImmediately): + mStack(stack), + mFifo(0,0), + mAcceptingWork(false), + mShutdown(false), + mStarted(false), + mWorkerPrototype(prototype.release()) +{ + for(int i=0; i<workers;i++) + { + mWorkerThreads.push_back(new WorkerThread(mWorkerPrototype->clone(),mFifo,mStack)); + } + + if(startImmediately) + { + startAll(); + } +} + +Dispatcher::~Dispatcher() +{ + shutdownAll(); + + std::vector<WorkerThread*>::iterator i; + for(i=mWorkerThreads.begin(); i!=mWorkerThreads.end(); ++i) + { + delete *i; + } + + mWorkerThreads.clear(); + + while(!mFifo.empty()) + { + delete mFifo.getNext(); + } + + delete mWorkerPrototype; + +} + +bool +Dispatcher::post(std::auto_ptr<resip::ApplicationMessage>& work) +{ + resip::ReadLock r(mMutex); + if(mAcceptingWork) + { + mFifo.add(work.release(), + resip::TimeLimitFifo<resip::ApplicationMessage>::InternalElement); + return true; + } + + return false; + + //If we aren't accepting work, the auto ptr is not released. (We don't + // take ownership, and the caller gets to handle the contents of the + // auto_ptr) +} + +size_t +Dispatcher::fifoCountDepth() const +{ + return mFifo.getCountDepth(); +} + +time_t +Dispatcher::fifoTimeDepth() const +{ + return mFifo.getTimeDepth(); +} + +int +Dispatcher::workPoolSize() const +{ + return (int)mWorkerThreads.size(); +} + +void +Dispatcher::stop() +{ + resip::WriteLock w(mMutex); + mAcceptingWork=false; +} + +void +Dispatcher::resume() +{ + resip::WriteLock w(mMutex); + mAcceptingWork = !mShutdown; +} + +void +Dispatcher::shutdownAll() +{ + resip::WriteLock w(mMutex); + if(!mShutdown) + { + mAcceptingWork=false; + mShutdown=true; + + std::vector<WorkerThread*>::iterator i; + for(i=mWorkerThreads.begin(); i!=mWorkerThreads.end(); ++i) + { + (*i)->shutdown(); + (*i)->join(); + } + } +} + +void +Dispatcher::startAll() +{ + resip::WriteLock w(mMutex); + if(!mShutdown && !mStarted) + { + std::vector<WorkerThread*>::iterator i; + for(i=mWorkerThreads.begin(); i!=mWorkerThreads.end(); ++i) + { + (*i)->run(); + } + mStarted=true; + mAcceptingWork=true; + } +} + +} //namespace repro + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/Dispatcher.hxx b/src/libs/resiprocate/repro/Dispatcher.hxx new file mode 100644 index 00000000..fc347d96 --- /dev/null +++ b/src/libs/resiprocate/repro/Dispatcher.hxx @@ -0,0 +1,187 @@ +#ifndef DISPATCHER_HXX +#define DISPATCHER_HXX 1 + +#include "repro/WorkerThread.hxx" +#include "repro/Worker.hxx" +#include "resip/stack/ApplicationMessage.hxx" +#include "rutil/TimeLimitFifo.hxx" +#include "rutil/RWMutex.hxx" +#include "rutil/Lock.hxx" +#include <vector> + +namespace resip +{ + class SipStack; + class ApplicationMessage; +}; + +namespace repro +{ + +/** + @class Dispatcher + + @brief A generic thread-bank class. + + This is intended to be a generic thread-bank class that operates under + the paradigm of accepting messages, modifying those messages, and posting + the messages back to the originator through the SipStack. (Since this uses + ApplicationMessages, the message will automatically get back to the correct + TransactionUser; what happens from there is the coder's business.) + + This class gets + generality by using prototyping of a very simple class, Worker. All the + user must do is subclass Worker to do the work needed, and pass an instance + of this class when constructing the Dispatcher. Dispatcher will clone this + Worker as many times as needed to fill the thread bank. + + @note The functions in this class are intended to be thread-safe. +*/ + +class Dispatcher +{ + public: + + /** + @param prototype The prototypical instance of Worker. + + @param stack The stack to post messages to. + + @param workers The number of threads in this bank. + + @param startImmediately Whether to start this thread bank on + construction. + */ + Dispatcher(std::auto_ptr<Worker> prototype, + resip::SipStack* stack, + int workers=2, + bool startImmediately=true); + + virtual ~Dispatcher(); + + /** + Posts a message to this thread bank. + + @param work The message that conveys the work that needs to be done. + It is understood that any information that needs to be conveyed + back to the originator will be placed in the message by the Workers + in the thread bank. + + @returns true iff this message was successfully posted. (This may not + be the case if this Dispatcher is in the process of shutting down) + */ + virtual bool post(std::auto_ptr<resip::ApplicationMessage>& work); + + /** + @returns The number of messages in this Dispatcher's queue + */ + size_t fifoCountDepth() const; + + /** + @returns The time between which the front of the queue was posted and + the back of the queue was posted. + */ + time_t fifoTimeDepth() const; + + /** + @returns The number of workers in this thread bank. + */ + int workPoolSize() const; + + /** + This Dispatcher will stop accepting new + work, but processing will continue normally on the messages already + in the queue. + */ + void stop(); + + /** + Resumes accepting work. + */ + void resume(); + + /** + Shuts down the thread-bank. + */ + void shutdownAll(); + + + /** + Starts the thread bank. + */ + void startAll(); + + resip::SipStack* mStack; + + + protected: + + resip::TimeLimitFifo<resip::ApplicationMessage> mFifo; + bool mAcceptingWork; + bool mShutdown; + bool mStarted; + Worker* mWorkerPrototype; + + resip::RWMutex mMutex; + + std::vector<WorkerThread*> mWorkerThreads; + + private: + //No copying! + Dispatcher(const Dispatcher& toCopy); + Dispatcher& operator=(const Dispatcher& toCopy); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/Doxyfile b/src/libs/resiprocate/repro/Doxyfile new file mode 100644 index 00000000..ce54de91 --- /dev/null +++ b/src/libs/resiprocate/repro/Doxyfile @@ -0,0 +1,267 @@ +# Doxyfile 1.4.1 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = Repro +PROJECT_NUMBER = HEAD +OUTPUT_DIRECTORY = ./doxygen.out +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = . +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = YES +STRIP_CODE_COMMENTS = NO +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = YES +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = /Applications/Graphviz.app/Contents/MacOS +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/src/libs/resiprocate/repro/FilterStore.cxx b/src/libs/resiprocate/repro/FilterStore.cxx new file mode 100644 index 00000000..728c75d7 --- /dev/null +++ b/src/libs/resiprocate/repro/FilterStore.cxx @@ -0,0 +1,607 @@ + +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Lock.hxx" + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/ExtensionHeader.hxx" + +#include "repro/FilterStore.hxx" +#include "rutil/WinLeakCheck.hxx" + + +using namespace resip; +using namespace repro; +using namespace std; + + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +bool FilterStore::FilterOp::operator<(const FilterOp& rhs) const +{ + return filterRecord.mOrder < rhs.filterRecord.mOrder; +} + + +FilterStore::FilterStore(AbstractDb& db): + mDb(db) +{ + Key key = mDb.firstFilterKey(); + while ( !key.empty() ) + { + FilterOp filter; + filter.filterRecord = mDb.getFilter(key); + filter.key = key; + filter.pcond1 = 0; + filter.pcond2 = 0; + + int flags = REG_EXTENDED; + if(filter.filterRecord.mActionData.find("$") == Data::npos) + { + flags |= REG_NOSUB; + } + + if(!filter.filterRecord.mCondition1Regex.empty()) + { + filter.pcond1 = new regex_t; + int ret = regcomp(filter.pcond1, filter.filterRecord.mCondition1Regex.c_str(), flags); + if(ret != 0) + { + delete filter.pcond1; + ErrLog( << "Condition1Regex has invalid match expression: " + << filter.filterRecord.mCondition1Regex); + filter.pcond1 = 0; + } + } + + if(!filter.filterRecord.mCondition2Regex.empty()) + { + filter.pcond2 = new regex_t; + int ret = regcomp(filter.pcond2, filter.filterRecord.mCondition2Regex.c_str(), flags); + if(ret != 0) + { + delete filter.pcond2; + ErrLog( << "Condition2Regex has invalid match expression: " + << filter.filterRecord.mCondition2Regex); + filter.pcond2 = 0; + } + } + + mFilterOperators.insert(filter); + + key = mDb.nextFilterKey(); + } + mCursor = mFilterOperators.begin(); +} + + +FilterStore::~FilterStore() +{ + for(FilterOpList::iterator i = mFilterOperators.begin(); i != mFilterOperators.end(); i++) + { + if (i->pcond1) + { + regfree(i->pcond1); + delete i->pcond1; + } + if (i->pcond2) + { + regfree(i->pcond2); + delete i->pcond2; + } + } + mFilterOperators.clear(); +} + + +bool +FilterStore::addFilter(const resip::Data& cond1Header, + const resip::Data& cond1Regex, + const resip::Data& cond2Header, + const resip::Data& cond2Regex, + const resip::Data& method, + const resip::Data& event, + short action, + const resip::Data& actionData, + const short order) +{ + InfoLog( << "Add filter" ); + + FilterOp filter; + + Key key = buildKey(cond1Header, cond1Regex, cond2Header, cond2Regex, method, event); + + if(findKey(key)) return false; + + filter.filterRecord.mCondition1Header = cond1Header; + filter.filterRecord.mCondition1Regex = cond1Regex; + filter.filterRecord.mCondition2Header = cond2Header; + filter.filterRecord.mCondition2Regex = cond2Regex; + filter.filterRecord.mMethod = method; + filter.filterRecord.mEvent = event; + filter.filterRecord.mAction = action; + filter.filterRecord.mActionData = actionData; + filter.filterRecord.mOrder = order; + + if(!mDb.addFilter(key , filter.filterRecord)) + { + return false; + } + + filter.key = key; + filter.pcond1 = 0; + filter.pcond2 = 0; + int flags = REG_EXTENDED; + if(filter.filterRecord.mActionData.find("$") == Data::npos) + { + flags |= REG_NOSUB; + } + if(!filter.filterRecord.mCondition1Regex.empty()) + { + filter.pcond1 = new regex_t; + int ret = regcomp(filter.pcond1, filter.filterRecord.mCondition1Regex.c_str(), flags); + if(ret != 0) + { + delete filter.pcond1; + filter.pcond1 = 0; + } + } + if(!filter.filterRecord.mCondition2Regex.empty()) + { + filter.pcond2 = new regex_t; + int ret = regcomp(filter.pcond2, filter.filterRecord.mCondition2Regex.c_str(), flags); + if(ret != 0) + { + delete filter.pcond2; + filter.pcond2 = 0; + } + } + + { + WriteLock lock(mMutex); + mFilterOperators.insert( filter ); + } + mCursor = mFilterOperators.begin(); + + return true; +} + + +/* +AbstractDb::FilterRecordList +FilterStore::getFilters() const +{ + AbstractDb::FilterRecordList result; + result.reserve(mFilterOperators.size()); + + for (FilterOpList::const_iterator it = mFilterOperators.begin(); + it != mFilterOperators.end(); it++) + { + result.push_back(it->filterRecord); + } + return result; +} +*/ + + +void +FilterStore::eraseFilter(const resip::Data& cond1Header, + const resip::Data& cond1Regex, + const resip::Data& cond2Header, + const resip::Data& cond2Regex, + const resip::Data& method, + const resip::Data& event) +{ + Key key = buildKey(cond1Header, cond1Regex, cond2Header, cond2Regex, method, event); + eraseFilter(key); +} + + +void +FilterStore::eraseFilter(const resip::Data& key) +{ + mDb.eraseFilter(key); + + { + WriteLock lock(mMutex); + + FilterOpList::iterator it = mFilterOperators.begin(); + while (it != mFilterOperators.end()) + { + if (it->key == key) + { + FilterOpList::iterator i = it; + it++; + if(i->pcond1) + { + regfree(i->pcond1); + delete i->pcond1; + } + if(i->pcond2) + { + regfree(i->pcond2); + delete i->pcond2; + } + mFilterOperators.erase(i); + } + else + { + it++; + } + } + } + mCursor = mFilterOperators.begin(); // reset the cursor since it may have been on deleted filter +} + + +bool +FilterStore::updateFilter(const resip::Data& originalKey, + const resip::Data& cond1Header, + const resip::Data& cond1Regex, + const resip::Data& cond2Header, + const resip::Data& cond2Regex, + const resip::Data& method, + const resip::Data& event, + short action, + const resip::Data& actionData, + const short order) +{ + eraseFilter(originalKey); + return addFilter(cond1Header, cond1Regex, cond2Header, cond2Regex, method, event, action, actionData, order); +} + + +FilterStore::Key +FilterStore::getFirstKey() +{ + ReadLock lock(mMutex); + + mCursor = mFilterOperators.begin(); + if ( mCursor == mFilterOperators.end() ) + { + return Key( Data::Empty ); + } + + return mCursor->key; +} + +bool +FilterStore::findKey(const Key& key) +{ + // check if cursor happens to be at the key + if ( mCursor != mFilterOperators.end() ) + { + if ( mCursor->key == key ) + { + return true; + } + } + + // search for the key + mCursor = mFilterOperators.begin(); + while ( mCursor != mFilterOperators.end() ) + { + if ( mCursor->key == key ) + { + return true; // found the key + } + mCursor++; + } + return false; // key was not found +} + +FilterStore::Key +FilterStore::getNextKey(Key& key) +{ + ReadLock lock(mMutex); + + if ( !findKey(key) ) + { + return Key(Data::Empty); + } + + mCursor++; + + if ( mCursor == mFilterOperators.end() ) + { + return Key( Data::Empty ); + } + + return mCursor->key; +} + + +AbstractDb::FilterRecord +FilterStore::getFilterRecord(const resip::Data& key) +{ + ReadLock lock(mMutex); + + if (!findKey(key)) + { + return AbstractDb::FilterRecord(); + } + return mCursor->filterRecord; +} + + +void +FilterStore::getHeaderFromSipMessage(const SipMessage& msg, const Data& headerName, list<Data>& headerList) +{ + // First see if header string is "request-line" + if(isEqualNoCase(headerName, "request-line")) + { + headerList.push_back(Data::from(msg.header(h_RequestLine))); + return; + } + + // Next check to see if it is a standard header + Headers::Type headerType = Headers::getType(headerName.c_str(), headerName.size()); + if(headerType != Headers::UNKNOWN) + { + Data headerData; + const HeaderFieldValueList* hfv = msg.getRawHeader(headerType); + for(HeaderFieldValueList::const_iterator it = hfv->begin(); it != hfv->end(); it++) + { + it->toShareData(headerData); + headerList.push_back(headerData); + } + } + else // Check if custom header + { + ExtensionHeader exHeader(headerName); + if(msg.exists(exHeader)) + { + const StringCategories& exHeaders = msg.header(exHeader); + for(StringCategories::const_iterator it = exHeaders.begin(); it != exHeaders.end(); it++) + { + headerList.push_back(it->value()); + } + } + } +} + +bool +FilterStore::applyRegex(int conditionNum, const Data& header, const Data& match, regex_t *regex, Data& rewrite) +{ + int ret; + assert(conditionNum < 10); + + // TODO - !cj! www.pcre.org looks like it has better performance + // !mbg! is this true now that the compiled regexp is used? + + const int nmatch=10; // replacements $x1-$x9 are allowed, where x is the condition number + regmatch_t pmatch[nmatch]; + + ret = regexec(regex, header.c_str(), nmatch, pmatch, 0/*eflags*/); + if (ret != 0) + { + // did not match + return false; + } + + DebugLog( << " Filter matched: header=" << header << ", regex=" << match); + + if (rewrite.find("$") != Data::npos) + { + for (int i=1; i<nmatch; i++) + { + if (pmatch[i].rm_so != -1) + { + Data subExp(header.substr(pmatch[i].rm_so, + pmatch[i].rm_eo-pmatch[i].rm_so)); + DebugLog( << " subExpression[" <<i <<"]="<< subExp ); + + Data result; + { + DataStream s(result); + ParseBuffer pb(rewrite); + + while (true) + { + const char* a = pb.position(); + pb.skipToChars(Data("$") + char('0' + conditionNum) + char('0' + i)); + if (pb.eof()) + { + s << pb.data(a); + break; + } + else + { + s << pb.data(a); + pb.skipN(3); + s << subExp; + } + } + s.flush(); + } + rewrite = result; + } + } + } + return true; +} + +bool +FilterStore::process(const SipMessage& request, + short& action, + Data& actionData) +{ + if(mFilterOperators.empty()) return false; // If there are no filters bail early to save a few cycles (size check is atomic enough, we don't need a lock) + + ReadLock lock(mMutex); + + Data method(request.methodStr()); + Data event(request.exists(h_Event) ? request.header(h_Event).value() : Data::Empty); + + for (FilterOpList::iterator it = mFilterOperators.begin(); + it != mFilterOperators.end(); it++) + { + const AbstractDb::FilterRecord& rec = it->filterRecord; + + if(!rec.mMethod.empty()) + { + if(!isEqualNoCase(rec.mMethod, method)) + { + DebugLog( << " Skipped - method did not match" ); + continue; + } + } + if(!rec.mEvent.empty()) + { + if(!isEqualNoCase(rec.mEvent,event)) + { + DebugLog( << " Skipped - event did not match" ); + continue; + } + } + + // Get requests SIP headers from SipMessage + list<Data> condition1Headers; + list<Data> condition2Headers; + actionData = rec.mActionData; + if(!rec.mCondition1Header.empty() && it->pcond1) + { + getHeaderFromSipMessage(request, rec.mCondition1Header, condition1Headers); + + // Check condition 1 regex + list<Data>::iterator hit = condition1Headers.begin(); + bool match = false; + for(; hit != condition1Headers.end() && match == false; hit++) + { + match = applyRegex(1, *hit, rec.mCondition1Regex, it->pcond1, actionData); + DebugLog( << " Cond1 HeaderName=" << rec.mCondition1Header << ", Value=" << *hit << ", Regex=" << rec.mCondition1Regex << ", match=" << match); + } + if(!match) + { + DebugLog( << " Skipped - request did not match first condition: " << request.brief()); + continue; + } + } + if(!rec.mCondition2Header.empty() && it->pcond2) + { + getHeaderFromSipMessage(request, rec.mCondition2Header, condition2Headers); + + // Check condition 2 regex + list<Data>::iterator hit = condition2Headers.begin(); + bool match = false; + for(; hit != condition2Headers.end() && match == false; hit++) + { + match = applyRegex(2, *hit, rec.mCondition2Regex, it->pcond2, actionData); + DebugLog( << " Cond2 HeaderName=" << rec.mCondition2Header << ", Value=" << *hit << ", Regex=" << rec.mCondition2Regex << ", match=" << match); + } + if(!match) + { + DebugLog( << " Skipped - request did not match second condition: " << request.brief()); + continue; + } + } + // If we make it here Method, Event and both conditions matched - return configured action + action = rec.mAction; + return true; + } + + // If we make it here, then none of the conditions matched - return false + return false; +} + + +bool +FilterStore::test(const resip::Data& cond1Header, + const resip::Data& cond2Header, + short& action, + resip::Data& actionData) +{ + ReadLock lock(mMutex); + + for (FilterOpList::iterator it = mFilterOperators.begin(); + it != mFilterOperators.end(); it++) + { + const AbstractDb::FilterRecord& rec = it->filterRecord; + actionData = rec.mActionData; + + // Check condition 1 regex + if(!rec.mCondition1Header.empty() && it->pcond1) + { + if(!applyRegex(1, cond1Header, rec.mCondition1Regex, it->pcond1, actionData)) + { + continue; + } + } + + // Check condition 2 regex + if(!rec.mCondition2Header.empty() && it->pcond2) + { + if(!applyRegex(2, cond2Header, rec.mCondition2Regex, it->pcond2, actionData)) + { + continue; + } + } + + // If we make it here both conditions matched - return configured action + action = rec.mAction; + return true; + } + + // If we make it here, then none of the conditions matched - return false + return false; +} + + +FilterStore::Key +FilterStore::buildKey(const resip::Data& cond1Header, + const resip::Data& cond1Regex, + const resip::Data& cond2Header, + const resip::Data& cond2Regex, + const resip::Data& method, + const resip::Data& event) const +{ + Data pKey = cond1Header + ":" + cond1Regex + ":" + + cond2Header + ":" + cond2Regex + ":" + + method + ":" + event; + return pKey; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/FilterStore.hxx b/src/libs/resiprocate/repro/FilterStore.hxx new file mode 100644 index 00000000..afa127e6 --- /dev/null +++ b/src/libs/resiprocate/repro/FilterStore.hxx @@ -0,0 +1,166 @@ +#if !defined(REPRO_FILTERSTORE_HXX) +#define REPRO_FILTERSTORE_HXX + +#ifdef WIN32 +#include <pcreposix.h> +#else +#include <regex.h> +#endif + +#include <set> +#include <list> + +#include "rutil/Data.hxx" +#include "rutil/RWMutex.hxx" + +#include "repro/AbstractDb.hxx" + +namespace resip +{ + class SipMessage; +} + +namespace repro +{ + +class FilterStore +{ + public: + typedef resip::Data Key; + + enum FilterResult + { + Accept, + Reject, + SQLQuery + }; + + FilterStore(AbstractDb& db); + ~FilterStore(); + + bool addFilter(const resip::Data& cond1Header, + const resip::Data& cond1Regex, + const resip::Data& cond2Header, + const resip::Data& cond2Regex, + const resip::Data& method, + const resip::Data& event, + short action, + const resip::Data& actionData, + const short order); + + void eraseFilter(const resip::Data& cond1Header, + const resip::Data& cond1Regex, + const resip::Data& cond2Header, + const resip::Data& cond2Regex, + const resip::Data& method, + const resip::Data& event); + void eraseFilter(const resip::Data& key); + + bool updateFilter(const resip::Data& originalKey, + const resip::Data& cond1Header, + const resip::Data& cond1Regex, + const resip::Data& cond2Header, + const resip::Data& cond2Regex, + const resip::Data& method, + const resip::Data& event, + short action, + const resip::Data& actionData, + const short order); + + AbstractDb::FilterRecord getFilterRecord(const resip::Data& key); + + Key getFirstKey();// return empty if no more + Key getNextKey(Key& key); // return empty if no more + + bool process(const resip::SipMessage& request, + short& action, + resip::Data& actionData); + + bool test(const resip::Data& cond1Header, + const resip::Data& cond2Header, + short& action, + resip::Data& actionData); + + private: + bool findKey(const Key& key); // move cursor to key + + Key buildKey(const resip::Data& cond1Header, + const resip::Data& cond1Regex, + const resip::Data& cond2Header, + const resip::Data& cond2Regex, + const resip::Data& method, + const resip::Data& event) const; + + void getHeaderFromSipMessage(const resip::SipMessage& msg, + const resip::Data& headerName, + std::list<resip::Data>& headerList); + bool applyRegex(int conditionNum, + const resip::Data& header, + const resip::Data& match, + regex_t *regex, + resip::Data& rewrite); + + AbstractDb& mDb; + + class FilterOp + { + public: + Key key; + regex_t *pcond1; + regex_t *pcond2; + AbstractDb::FilterRecord filterRecord; + bool operator<(const FilterOp&) const; + }; + + resip::RWMutex mMutex; + typedef std::multiset<FilterOp> FilterOpList; + FilterOpList mFilterOperators; + FilterOpList::iterator mCursor; +}; + + } +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/ForkControlMessage.hxx b/src/libs/resiprocate/repro/ForkControlMessage.hxx new file mode 100644 index 00000000..e6f33ae6 --- /dev/null +++ b/src/libs/resiprocate/repro/ForkControlMessage.hxx @@ -0,0 +1,100 @@ +#ifndef FORK_CONTROL_MESSAGE_HXX +#define FORK_CONTROL_MESSAGE_HXX 1 + +#include "repro/ProcessorMessage.hxx" +#include "resip/stack/NameAddr.hxx" +#include "rutil/Data.hxx" +#include "rutil/Inserter.hxx" + +namespace repro +{ + +class ForkControlMessage : public ProcessorMessage +{ + public: + ForkControlMessage( const repro::Processor& proc, + const resip::Data& tid, + resip::TransactionUser* tuPassed, + bool cancelAllClientTransactions=false): + ProcessorMessage(proc,tid,tuPassed) + { + mShouldCancelAll=cancelAllClientTransactions; + } + + ForkControlMessage(const ForkControlMessage& orig): + ProcessorMessage(orig) + { + mShouldCancelAll=orig.mShouldCancelAll; + mTransactionsToProcess=orig.mTransactionsToProcess; + mTransactionsToCancel=orig.mTransactionsToCancel; + } + + virtual ~ForkControlMessage(){} + + virtual ForkControlMessage* clone() const + { + return new ForkControlMessage(*this); + } + + virtual EncodeStream& encode(EncodeStream& ostr) const + { + ostr << "ForkControlMessage(tid="<<mTid<<"): " << + ostr << " newTrans=" << resip::Inserter(mTransactionsToProcess) << + ostr << " cancelTrans=" << resip::Inserter(mTransactionsToCancel) << + ostr << " cancelAll=" << mShouldCancelAll; + return ostr; + } + virtual EncodeStream& encodeBrief(EncodeStream& ostr) const { return encode(ostr);} + + std::vector<resip::Data> mTransactionsToProcess; + std::vector<resip::Data> mTransactionsToCancel; + bool mShouldCancelAll; +}; //class + +} //namespace repro +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/HttpBase.cxx b/src/libs/resiprocate/repro/HttpBase.cxx new file mode 100644 index 00000000..cbcbcaf1 --- /dev/null +++ b/src/libs/resiprocate/repro/HttpBase.cxx @@ -0,0 +1,269 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <cassert> + +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/TransportType.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/Tuple.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/ParseBuffer.hxx" +#include "resip/stack/Transport.hxx" + +#include "repro/HttpBase.hxx" +#include "repro/HttpConnection.hxx" +#include "repro/WebAdmin.hxx" +#include "rutil/WinLeakCheck.hxx" + + +using namespace resip; +using namespace repro; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + + +HttpBase::~HttpBase() +{ +#if defined(WIN32) + closesocket(mFd); +#else + close(mFd); +#endif + mFd=0; + for( int i=0; i<MaxConnections; i++) + { + if ( mConnection[i] ) + { + delete mConnection[i] ; mConnection[i]=0; + } + } +} + + +HttpBase::HttpBase( int port, IpVersion ipVer, const Data& realm ): + mRealm(realm), + nextConnection(0), + mTuple(Data::Empty,port,ipVer,TCP,Data::Empty) +{ + // !rwm! [TODO] check that this works for IPv6 + //assert( ipVer == V4 ); + + sane = true; + + for ( int i=0 ; i<MaxConnections; i++) + { + mConnection[i]=0; + } + +#ifdef USE_IPV6 + mFd = ::socket(ipVer == V4 ? PF_INET : PF_INET6, SOCK_STREAM, 0); +#else + mFd = ::socket(PF_INET, SOCK_STREAM, 0); +#endif + + if ( mFd == INVALID_SOCKET ) + { + int e = getErrno(); + ErrLog (<< "Failed to create socket: " << strerror(e)); + sane = false; + return; + } + + DebugLog (<< "Creating fd=" << (int)mFd + << (ipVer == V4 ? " V4/" : " V6/") ); + + int on = 1; +#if !defined(WIN32) + if ( ::setsockopt ( mFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) ) +#else + if ( ::setsockopt ( mFd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) ) +#endif + { + int e = getErrno(); + ErrLog (<< "Couldn't set sockoptions SO_REUSEPORT | SO_REUSEADDR: " << strerror(e)); + sane = false; + return; + } + + DebugLog (<< "Binding to " << Tuple::inet_ntop(mTuple)); + + if ( ::bind( mFd, &mTuple.getMutableSockaddr(), mTuple.length()) == SOCKET_ERROR ) + { + int e = getErrno(); + if ( e == EADDRINUSE ) + { + ErrLog (<< mTuple << " already in use "); + } + else + { + ErrLog (<< "Could not bind to " << mTuple); + } + sane = false; + return; + } + + bool ok = makeSocketNonBlocking(mFd); + if ( !ok ) + { + ErrLog (<< "Could not make HTTP socket non-blocking " << port ); + sane = false; + return; + } + + // do the listen, seting the maximum queue size for compeletly established + // sockets -- on linux, tcp_max_syn_backlog should be used for the incomplete + // queue size(see man listen) + int e = listen(mFd,5 ); + + if (e != 0 ) + { + int e = getErrno(); + InfoLog (<< "Failed listen " << strerror(e)); + sane = false; + return; + } +} + + +void +HttpBase::buildFdSet(FdSet& fdset) +{ + fdset.setRead( mFd ); + + for( int i=0; i<MaxConnections; i++) + { + if ( mConnection[i] ) + { + mConnection[i]->buildFdSet(fdset); + } + } +} + + +void +HttpBase::process(FdSet& fdset) +{ + if (fdset.readyToRead(mFd)) + { + Tuple tuple(mTuple); + struct sockaddr& peer = tuple.getMutableSockaddr(); + socklen_t peerLen = tuple.length(); + Socket sock = accept( mFd, &peer, &peerLen); + if ( sock == SOCKET_ERROR ) + { + int e = getErrno(); + switch (e) + { + case EWOULDBLOCK: + // !jf! this can not be ready in some cases + return; + default: + ErrLog(<< "Some error reading from socket: " << e); + // .bwc. This is almost certainly a bad assert that a nefarious + // endpoint could hit. + // assert(0); // Transport::error(e); + } + return; + } + makeSocketNonBlocking(sock); + + int c = nextConnection; + nextConnection = ( nextConnection+1 ) % MaxConnections; + + if ( mConnection[c] ) + { + delete mConnection[c]; mConnection[c] = 0; + } + + mConnection[c] = new HttpConnection(*this,sock); + + DebugLog (<< "Received TCP connection as connection=" << c << " fd=" << (int)sock); + } + + for( int i=0; i<MaxConnections; i++) + { + if ( mConnection[i] ) + { + bool ok = mConnection[i]->process(fdset); + if ( !ok ) + { + delete mConnection[i]; mConnection[i]=0; + } + } + } +} + + +void HttpBase::setPage( const Data& page, int pageNumber, int response, const Mime& type ) +{ + for ( int i=0 ; i<MaxConnections; i++) + { + if ( mConnection[i] ) + { + if ( mConnection[i]->mPageNumber == pageNumber ) + { + mConnection[i]->setPage( page,response,type ); + } + } + } +} + +bool HttpBase::isSane() +{ + return sane; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/HttpBase.hxx b/src/libs/resiprocate/repro/HttpBase.hxx new file mode 100644 index 00000000..b8416d6f --- /dev/null +++ b/src/libs/resiprocate/repro/HttpBase.hxx @@ -0,0 +1,104 @@ +#if !defined(REPRO_HTTPBASE_HXX) +#define REPRO_HTTPBASE_HXX + +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/TransportType.hxx" +#include "resip/stack/Tuple.hxx" +#include "resip/stack/Mime.hxx" + +namespace repro +{ +class HttpConnection; + +class HttpBase +{ + friend class HttpConnection; + + public: + HttpBase( int port, resip::IpVersion version, const resip::Data& realm ); + virtual ~HttpBase(); + + void buildFdSet(resip::FdSet& fdset); + void process(resip::FdSet& fdset); + + bool isSane(); + + protected: + virtual void buildPage( const resip::Data& uri, + int pageNumber, + const resip::Data& user, + const resip::Data& password )=0; + void setPage( const resip::Data& page, + int pageNumber, + int response=200, + const resip::Mime& pType = resip::Mime("text","html") ); + + const resip::Data mRealm; + + private: + static const int MaxConnections = 30; + + resip::Socket mFd; + int nextConnection; + resip::Tuple mTuple; + + bool sane; + + HttpConnection* mConnection[MaxConnections]; + +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/HttpConnection.cxx b/src/libs/resiprocate/repro/HttpConnection.cxx new file mode 100644 index 00000000..6a4c7df1 --- /dev/null +++ b/src/libs/resiprocate/repro/HttpConnection.cxx @@ -0,0 +1,431 @@ +#include <cassert> + +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/TransportType.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/Tuple.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/ParseBuffer.hxx" + +#include "repro/ReproVersion.hxx" +#include "repro/HttpBase.hxx" +#include "repro/HttpConnection.hxx" + + +using namespace resip; +using namespace repro; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +int HttpConnection::nextPageNumber=1; + + + + +HttpConnection::HttpConnection( HttpBase& base, Socket pSock ): + mHttpBase( base ), + mPageNumber(nextPageNumber++), + mSock(pSock), + mParsedRequest(false) +{ + assert( mSock > 0 ); +} + + +HttpConnection::~HttpConnection() +{ + assert( mSock > 0 ); +#ifdef WIN32 + closesocket(mSock); mSock=0; +#else + close(mSock); mSock=0; +#endif +} + + +void +HttpConnection::buildFdSet(FdSet& fdset) +{ + if ( !mTxBuffer.empty() ) + { + fdset.setWrite(mSock); + } + fdset.setRead(mSock); +} + + +bool +HttpConnection::process(FdSet& fdset) +{ + if ( fdset.hasException(mSock) ) + { + int errNum = 0; + int errNumSize = sizeof(errNum); + getsockopt(mSock,SOL_SOCKET,SO_ERROR,(char *)&errNum,(socklen_t *)&errNumSize); + InfoLog (<< "Exception reading from socket " + << (int)mSock << " code: " << errNum << "; closing connection"); + return false; + } + + if ( fdset.readyToRead( mSock ) ) + { + bool ok = processSomeReads(); + if ( !ok ) + { + return false; + } + } + if ( (!mTxBuffer.empty()) && fdset.readyToWrite( mSock ) ) + { + bool ok = processSomeWrites(); + if ( !ok ) + { + return false; + } + } + + return true; +} + + +void +HttpConnection::setPage(const Data& pPage,int response,const Mime& pType) +{ + Data page(pPage); + + switch (response) + { + case 401: + { + mTxBuffer += "HTTP/1.0 401 Unauthorized"; mTxBuffer += Symbols::CRLF; + + page = ("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">" + "<html><head>" + "<title>401 Unauthorized</title>" + "</head><body>" + "<h1>Unauthorized</h1>" + "</body></html>" ); + } + break; + + case 404: + { + mTxBuffer += "HTTP/1.0 404 Not Found"; mTxBuffer += Symbols::CRLF; + + page = ("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">" + "<html><head>" + "<title>404 Not Found</title>" + "</head><body>" + "<h1>Unauthorized</h1>" + "</body></html>" ); + } + break; + + case 301: + { + mTxBuffer += "HTTP/1.0 301 Moved Permanently"; mTxBuffer += Symbols::CRLF; + mTxBuffer += "Location: http:/index.html"; mTxBuffer += Symbols::CRLF; + + page = ("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">" + "<html><head>" + "<title>301 Moved Permanently</title>" + "</head><body>" + "<h1>Moved</h1>" + "</body></html>" ); + } + break; + + case 200: + { + mTxBuffer += "HTTP/1.0 200 OK" ; mTxBuffer += Symbols::CRLF; + } + break; + + default: + { + assert(0); + + Data resp; + { + DataStream s(resp); + s << response; + s.flush(); + } + + mTxBuffer += "HTTP/1.0 "; + mTxBuffer += resp; + mTxBuffer += "OK" ; mTxBuffer += Symbols::CRLF; + } + break; + } + + Data len; + { + DataStream s(len); + s << page.size(); + s.flush(); + } + + mTxBuffer += "WWW-Authenticate: Basic realm=\""; + if ( mHttpBase.mRealm.empty() ) + { + mTxBuffer += resip::DnsUtil::getLocalHostName(); + } + else + { + mTxBuffer += mHttpBase.mRealm; + } + mTxBuffer += "\" "; + mTxBuffer += Symbols::CRLF; + + mTxBuffer += "Server: Repro Proxy " ; + mTxBuffer += Data(VersionUtils::instance().displayVersion()); + mTxBuffer += Symbols::CRLF; + mTxBuffer += "Mime-version: 1.0 " ; mTxBuffer += Symbols::CRLF; + mTxBuffer += "Pragma: no-cache " ; mTxBuffer += Symbols::CRLF; + mTxBuffer += "Content-Length: "; mTxBuffer += len; mTxBuffer += Symbols::CRLF; + + mTxBuffer += "Content-Type: " ; + mTxBuffer += pType.type() ; + mTxBuffer +="/" ; + mTxBuffer += pType.subType() ; mTxBuffer += Symbols::CRLF; + + mTxBuffer += Symbols::CRLF; + + mTxBuffer += page; +} + + +bool +HttpConnection::processSomeReads() +{ + const int bufSize = 8000; + char buf[bufSize]; + + +#if defined(WIN32) + int bytesRead = ::recv(mSock, buf, bufSize, 0); +#else + int bytesRead = ::read(mSock, buf, bufSize); +#endif + + if (bytesRead == INVALID_SOCKET) + { + int e = getErrno(); + switch (e) + { + case EAGAIN: + InfoLog (<< "No data ready to read"); + return true; + case EINTR: + InfoLog (<< "The call was interrupted by a signal before any data was read."); + break; + case EIO: + InfoLog (<< "I/O error"); + break; + case EBADF: + InfoLog (<< "fd is not a valid file descriptor or is not open for reading."); + break; + case EINVAL: + InfoLog (<< "fd is attached to an object which is unsuitable for reading."); + break; + case EFAULT: + InfoLog (<< "buf is outside your accessible address space."); + break; + default: + InfoLog (<< "Some other error"); + break; + } + InfoLog (<< "Failed read on " << (int)mSock << " " << strerror(e)); + return false; + } + else if (bytesRead == 0) + { + InfoLog (<< "Connection closed by remote " ); + return false; + } + + //DebugLog (<< "HttpConnection::processSomeReads() " + // << " read=" << bytesRead); + + mRxBuffer += Data( buf, bytesRead ); + + tryParse(); + + return true; +} + + +void +HttpConnection::tryParse() +{ + //DebugLog (<< "parse " << mRxBuffer ); + + ParseBuffer pb(mRxBuffer); + + // See if we have the entire message + pb.skipToChars(Symbols::CRLFCRLF); + if(pb.eof()) + { + // End of message not found - keep reading + return; + } + pb.reset(pb.start()); + + pb.skipToChar(Symbols::SPACE[0]); + const char* start = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + + if (pb.eof()) + { + // parse failed - just return + return; + } + + Data uri; + pb.data( uri, start ); + + DebugLog (<< "parse found URI " << uri ); + mParsedRequest = true; + + + Data user; + Data password; + + try + { + pb.skipToChars("Authorization"); + if (!pb.eof()) + { + if ( pb.eof() ) DebugLog( << "Did not find Authorization header" ); + pb.skipToChars( "Basic" ); pb.skipN(6); + if ( pb.eof() ) DebugLog( << "Did not find Authorization basic " ); + pb.skipWhitespace(); + if ( pb.eof() ) DebugLog( << "Something weird in Auhtorization header " ); + if ( !pb.eof() ) + { + const char* a = pb.position(); + pb.skipNonWhitespace(); + Data buf = pb.data(a); + + DebugLog (<< "parse found basic base64 auth data of " << buf ); + Data auth = buf.base64decode(); + + //DebugLog (<< "parse found basic auth data of " << auth ); + + ParseBuffer p(auth); + const char* a1 = p.position(); + p.skipToChar(':'); + user = p.data(a1); + const char* a2 = p.skipChar(':'); + p.skipToEnd(); + password = p.data(a2); + + //DebugLog (<< "parse found basic auth data with user=" << user + // << " password=" << password ); + } + } + } + catch ( ... ) + { + ErrLog (<< "Some problem finding Authorization header in HTTP request" ); + } + + mHttpBase.buildPage(uri,mPageNumber,user,password); +} + + +bool +HttpConnection::processSomeWrites() +{ + if ( mTxBuffer.empty() ) + { + return true; + } + + //DebugLog (<< "Writing " << mTxBuffer ); + +#if defined(WIN32) + int bytesWritten = ::send( mSock, mTxBuffer.data(), (int)mTxBuffer.size(), 0); +#else + int bytesWritten = ::write(mSock, mTxBuffer.data(), (int)mTxBuffer.size() ); +#endif + + if (bytesWritten == INVALID_SOCKET) + { + int e = getErrno(); + InfoLog (<< "HttpConnection failed write on " << mSock << " " << strerror(e)); + + return false; + } + + if (bytesWritten == (int)mTxBuffer.size() ) + { + DebugLog (<< "Wrote it all" ); + mTxBuffer = Data::Empty; + + return false; // return false causes connection to close and clean up + } + else + { + Data rest = mTxBuffer.substr(bytesWritten); + mTxBuffer = rest; + DebugLog( << "Wrote " << bytesWritten << " bytes - still need to do " << mTxBuffer ); + } + + return true; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/HttpConnection.hxx b/src/libs/resiprocate/repro/HttpConnection.hxx new file mode 100644 index 00000000..c397cb1b --- /dev/null +++ b/src/libs/resiprocate/repro/HttpConnection.hxx @@ -0,0 +1,98 @@ +#if !defined(REPRO_HTTPCONNECTION_HXX) +#define REPRO_HTTPCONNECTION_HXX + +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/TransportType.hxx" +#include "resip/stack/Tuple.hxx" +#include "resip/stack/Mime.hxx" + +#include "repro/UserStore.hxx" +#include "repro/HttpBase.hxx" + +namespace repro +{ + +class HttpConnection +{ + friend class HttpBase; + + public: + HttpConnection( HttpBase& webAdmin, resip::Socket pSock ); + ~HttpConnection(); + + void buildFdSet(resip::FdSet& fdset); + bool process(resip::FdSet& fdset); + + void setPage(const resip::Data& page, + int response, + const resip::Mime& pType ); + + private: + bool processSomeReads(); + bool processSomeWrites(); + void tryParse(); + + HttpBase& mHttpBase; + const int mPageNumber; + static int nextPageNumber; + + resip::Socket mSock; + resip::Data mRxBuffer; + resip::Data mTxBuffer; + bool mParsedRequest; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/INSTALL b/src/libs/resiprocate/repro/INSTALL new file mode 100644 index 00000000..2fdd704f --- /dev/null +++ b/src/libs/resiprocate/repro/INSTALL @@ -0,0 +1,47 @@ +INSTALL + +1) Download + +Downloads are available at: + + http:// + +source is here: + +2) Get required libraries + +You need the following libraries: +openssl +berkeley db libraries + +On the Mac, the easiest way to get these packages is using Fink or darwinports + +fink.sourceforge.net +darwinports.com + + +3) Compile if using the source + + +4) Install the executable + +The file you downloaded is a standalone executable file. Copy the appropriate file to the directory where you would like to put the proxy (for example: /usr/local/bin/repro) + +mkdir /usr/local/repro +mv ~/repro-fedora-0.1-RC1 /usr/local//repro/repro +cd /usr/local/repro +chown repro:repro repro +chmod +x repro + + +make a link to + + +Tested in these configurations +Linux + Redhat Enterprise 9 + Fedora Core 3 +Mac OS X + 10.3 +Windows + XP and 2000 diff --git a/src/libs/resiprocate/repro/INSTALL.html b/src/libs/resiprocate/repro/INSTALL.html new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/resiprocate/repro/Makefile b/src/libs/resiprocate/repro/Makefile new file mode 100644 index 00000000..2182aa5a --- /dev/null +++ b/src/libs/resiprocate/repro/Makefile @@ -0,0 +1,222 @@ +# $Id: Makefile,v 1.9 2004/05/10 01:12:46 jason Exp $ +VERSION:=$(shell cat VERSION) +REPRO_USER?=repro + +# repro is not GPL so if you want to link in MySQL, you needs a +# a comercial license for MySQL that is not GPL +USE_MYSQL = false + +BUILD = ../build +include $(BUILD)/Makefile.pre + +CXXFLAGS += -I.. +ifneq ($(DB_HEADERS),/usr/include) +CXXFLAGS += -I$(DB_HEADERS) +endif +PACKAGES += DUM RESIP RUTIL OPENSSL ARES DB4CXX PTHREAD OPENSIGCOMP RADIUSCLIENTNG + +ifeq ($(OSTYPE),MinGW) +PACKAGES += PCRE +endif + +ifeq ($(USE_MYSQL),yes) +PACKAGES += MYSQL +SRC += MySqlDb.cxx +endif + +CODE_SUBDIRS = monkeys +TARGET_LIBRARY = librepro +TARGET_BINARY = repro + +TESTPROGRAMS = \ +# repro.cxx \ +# genUsers.cxx \ +# userAdmin.cxx + +SRC += \ + RouteStore.cxx \ + UserStore.cxx \ + ConfigStore.cxx \ + AclStore.cxx \ + Store.cxx \ + AbstractDb.cxx \ + BerkeleyDb.cxx \ + \ + ProxyConfig.cxx \ + ReproVersion.cxx \ + HttpBase.cxx \ + HttpConnection.cxx \ + WebAdmin.cxx \ + WebAdminThread.cxx \ + \ + Proxy.cxx \ + Registrar.cxx \ + RegSyncClient.cxx \ + RegSyncServer.cxx \ + RegSyncServerThread.cxx \ + ReproServerAuthManager.cxx \ + RequestContext.cxx \ + ResponseContext.cxx \ + RRDecorator.cxx \ + Processor.cxx \ + ProcessorChain.cxx \ + Target.cxx \ + WorkerThread.cxx \ + XmlRpcConnection.cxx \ + XmlRpcServerBase.cxx \ + Dispatcher.cxx \ + OutboundTarget.cxx \ + QValueTarget.cxx \ + \ + monkeys/DigestAuthenticator.cxx \ + monkeys/StrictRouteFixup.cxx \ + monkeys/AmIResponsible.cxx \ + monkeys/IsTrustedNode.cxx \ + monkeys/ConstantLocationMonkey.cxx \ + monkeys/LocationServer.cxx \ + monkeys/OutboundTargetHandler.cxx \ + monkeys/RecursiveRedirect.cxx \ + monkeys/SimpleStaticRoute.cxx \ + monkeys/StaticRoute.cxx \ + monkeys/StrictRouteFixup.cxx \ + monkeys/QValueTargetHandler.cxx \ + monkeys/SimpleTargetHandler.cxx \ + \ + + +ifeq ($(USE_SSL), yes) +SRC += stateAgents/CertServer.cxx \ + stateAgents/CertPublicationHandler.cxx \ + stateAgents/CertSubscriptionHandler.cxx \ + stateAgents/PrivateKeyPublicationHandler.cxx \ + stateAgents/PrivateKeySubscriptionHandler.cxx +CODE_SUBDIRS += stateAgents +endif + +reproSvnVersion=$(shell cat ../SVN-VERSION) +reproBuildHost=$(shell hostname) + + +reproInfo.hxx: ../SVN-VERSION VERSION + @echo "#define REPRO_BUILD_REV \"$(reproSvnVersion)\"" > reproInfo.hxx + @echo "#define REPRO_BUILD_HOST \"$(reproBuildHost)\"" >> reproInfo.hxx + @echo "#define REPRO_RELEASE_VERSION \"$(VERSION)\"" >> reproInfo.hxx + cat reproInfo.hxx + +ReproVersion.cxx: reproInfo.hxx + +../SVN-VERSION: + $(MAKE) -C .. SVN-VERSION + +include $(BUILD)/Makefile.post + +##################################################################### +# Redhat-esque system configuration install target +# (Should work with fairly recent versions of Redhat, RHEL, FC) +# +# Create configuration file: /etc/repro.conf +# Create rc file: /etc/rc.d/init.d +# Create db files directory: /var/lib/repro +# + +install-rh-config: \ + $(DESTDIR)/etc/repro.conf \ + $(DESTDIR)/etc/init.d/repro \ + $(DESTDIR)/var/lib/repro \ + $(DESTDIR)/var/run/repro \ + $(DESTDIR)$(INSTALL_PREFIX)/share/man/man8/repro.8 + +$(DESTDIR)/etc/repro.conf: etc/repro.conf.inst + if [ -e $@ ]; \ + then \ + echo " Using existing $@"; \ + install -D etc/repro.conf.inst $(DESTDIR)/etc/repro.conf.NEW; \ + else \ + install -D etc/repro.conf.inst $(DESTDIR)/etc/repro.conf; \ + fi + +$(DESTDIR)/etc/init.d/repro: etc/init.d/repro.inst + install -D etc/init.d/repro.inst $(DESTDIR)/etc/init.d/repro + +localize = sed \ + -e 's,@REPROUSER@,$(REPRO_USER),g' \ + -e 's,@REPRO_INSTALL@,$(INSTALL_PREFIX),g' \ + -e 's,@REPRO_RUNDIR@,/var/run/repro,g' \ + -e 's,@REPRO_CONFDIR@,/etc,g' \ + -e 's,@REPRO_CWD@,/var/lib/repro,g' \ + -e 's,@bindir@,$(INSTALL_PREFIX)/sbin,g' \ + -e 's,@VERSION@,$(VERSION),g' \ + +%.inst: % + $(localize) < $< > $@ + +$(DESTDIR)/var/run/repro: + install -d $(DESTDIR)/var/run/repro + +$(DESTDIR)/var/lib/repro: + install -d $(DESTDIR)/var/lib/repro + +$(DESTDIR)$(INSTALL_PREFIX)/share/man/man8/repro.8: doc/repro.8 + install -D $< $@ + +clean: clean-inst clean-build + +clean-build: + rm -f reproInfo.hxx + +clean-inst: + rm -f etc/init.d/repro.inst etc/repro.conf.inst + + +testVersion: ReproVersion.cxx ReproVersion.hxx + g++ -I.. -DTESTDRIVER ReproVersion.cxx -o testVersion + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# <http://www.vovida.org/>. +# +############################################################################## diff --git a/src/libs/resiprocate/repro/Makefile.am b/src/libs/resiprocate/repro/Makefile.am new file mode 100644 index 00000000..26b97c4c --- /dev/null +++ b/src/libs/resiprocate/repro/Makefile.am @@ -0,0 +1,252 @@ +# $Id$ + +EXTRA_DIST = *.html +EXTRA_DIST += doc +EXTRA_DIST += Doxyfile +EXTRA_DIST += etc +EXTRA_DIST += php +EXTRA_DIST += README_MySQL.txt +EXTRA_DIST += repro_10_0.vcxproj repro_10_0.vcxproj.filters +EXTRA_DIST += reprolib_10_0.vcxproj reprolib_10_0.vcxproj.filters +EXTRA_DIST += *.vcproj +#EXTRA_DIST += *.db +EXTRA_DIST += repro.spec +EXTRA_DIST += VERSION +EXTRA_DIST += webadmin +EXTRA_DIST += WinSetup WinSetupx64 +EXTRA_DIST += repro.config +EXTRA_DIST += create_mysql_reprodb.sql + +SUBDIRS = . test reprocmd accountingconsumers + +#AM_CXXFLAGS = -DUSE_ARES + +sbin_PROGRAMS = repro +repro_SOURCES = repro.cxx +repro_LDADD = librepro.la +repro_LDADD += ../resip/dum/libdum.la +repro_LDADD += ../resip/stack/libresip.la ../rutil/librutil.la +#repro_LDADD += ../contrib/ares/libares.a +#repro_LDADD += -L../contrib/ares -lares +repro_LDADD += @LIBSSL_LIBADD@ -lpthread + +lib_LTLIBRARIES = librepro.la + +librepro_la_LDFLAGS = @LIBTOOL_VERSION_RELEASE@ -export-dynamic +librepro_la_LIBADD = -ldb_cxx + +librepro_la_SOURCES = \ + RouteStore.cxx \ + UserStore.cxx \ + ConfigStore.cxx \ + AclStore.cxx \ + StaticRegStore.cxx \ + FilterStore.cxx \ + SiloStore.cxx \ + Store.cxx \ + AbstractDb.cxx \ + BerkeleyDb.cxx \ + \ + CommandServer.cxx \ + CommandServerThread.cxx \ + ProxyConfig.cxx \ + ReproVersion.cxx \ + HttpBase.cxx \ + HttpConnection.cxx \ + WebAdmin.cxx \ + WebAdminThread.cxx \ + \ + AccountingCollector.cxx \ + Proxy.cxx \ + Registrar.cxx \ + RegSyncClient.cxx \ + RegSyncServer.cxx \ + RegSyncServerThread.cxx \ + ReproRunner.cxx \ + ReproServerAuthManager.cxx \ + RequestContext.cxx \ + ResponseContext.cxx \ + RRDecorator.cxx \ + Processor.cxx \ + ProcessorChain.cxx \ + Target.cxx \ + WorkerThread.cxx \ + XmlRpcConnection.cxx \ + XmlRpcServerBase.cxx \ + Dispatcher.cxx \ + OutboundTarget.cxx \ + PersistentMessageQueue.cxx \ + QValueTarget.cxx \ + \ + monkeys/CertificateAuthenticator.cxx \ + monkeys/DigestAuthenticator.cxx \ + monkeys/StrictRouteFixup.cxx \ + monkeys/AmIResponsible.cxx \ + monkeys/IsTrustedNode.cxx \ + monkeys/ConstantLocationMonkey.cxx \ + monkeys/LocationServer.cxx \ + monkeys/OutboundTargetHandler.cxx \ + monkeys/RecursiveRedirect.cxx \ + monkeys/SimpleStaticRoute.cxx \ + monkeys/StaticRoute.cxx \ + monkeys/QValueTargetHandler.cxx \ + monkeys/SimpleTargetHandler.cxx \ + monkeys/GeoProximityTargetSorter.cxx \ + monkeys/RequestFilter.cxx \ + monkeys/MessageSilo.cxx + +reproincludedir = $(includedir)/repro +nobase_reproinclude_HEADERS = AbstractDb.hxx \ + AccountingCollector.hxx \ + Ack200DoneMessage.hxx \ + AclStore.hxx \ + AsyncProcessor.hxx \ + AsyncProcessorMessage.hxx \ + AsyncProcessorWorker.hxx \ + BerkeleyDb.hxx \ + CommandServer.hxx \ + CommandServerThread.hxx \ + ConfigStore.hxx \ + Dispatcher.hxx \ + FilterStore.hxx \ + ForkControlMessage.hxx \ + HttpBase.hxx \ + HttpConnection.hxx \ + monkeys/AmIResponsible.hxx \ + monkeys/CertificateAuthenticator.hxx \ + monkeys/ConstantLocationMonkey.hxx \ + monkeys/DigestAuthenticator.hxx \ + monkeys/GruuMonkey.hxx \ + monkeys/IsTrustedNode.hxx \ + monkeys/LocationServer.hxx \ + monkeys/OutboundTargetHandler.hxx \ + monkeys/QValueTargetHandler.hxx \ + monkeys/RecursiveRedirect.hxx \ + monkeys/SimpleStaticRoute.hxx \ + monkeys/SimpleTargetHandler.hxx \ + monkeys/StaticRoute.hxx \ + monkeys/StrictRouteFixup.hxx \ + monkeys/GeoProximityTargetSorter.hxx \ + monkeys/RequestFilter.hxx \ + monkeys/MessageSilo.hxx \ + MySqlDb.hxx \ + OutboundTarget.hxx \ + PersistentMessageQueue.hxx \ + ProcessorChain.hxx \ + Processor.hxx \ + ProcessorMessage.hxx \ + Proxy.hxx \ + ProxyConfig.hxx \ + QValueTarget.hxx \ + Registrar.hxx \ + RegSyncClient.hxx \ + RegSyncServer.hxx \ + RegSyncServerThread.hxx \ + reproInfo.hxx \ + ReproServerAuthManager.hxx \ + ReproRunner.hxx \ + ReproVersion.hxx \ + RequestContext.hxx \ + ResponseContext.hxx \ + RouteStore.hxx \ + RRDecorator.hxx \ + SiloStore.hxx \ + stateAgents/CertPublicationHandler.hxx \ + stateAgents/CertServer.hxx \ + stateAgents/CertSubscriptionHandler.hxx \ + stateAgents/PrivateKeyPublicationHandler.hxx \ + stateAgents/PrivateKeySubscriptionHandler.hxx \ + StaticRegStore.hxx \ + Store.hxx \ + Target.hxx \ + TimerCMessage.hxx \ + UserAuthGrabber.hxx \ + UserInfoMessage.hxx \ + UserStore.hxx \ + WebAdmin.hxx \ + WebAdminThread.hxx \ + Worker.hxx \ + WorkerThread.hxx \ + XmlRpcConnection.hxx \ + XmlRpcServerBase.hxx + +if USE_SSL +librepro_la_SOURCES += \ + stateAgents/CertServer.cxx \ + stateAgents/CertPublicationHandler.cxx \ + stateAgents/CertSubscriptionHandler.cxx \ + stateAgents/PrivateKeyPublicationHandler.cxx \ + stateAgents/PrivateKeySubscriptionHandler.cxx +endif + +if USE_MYSQL +librepro_la_SOURCES += MySqlDb.cxx +librepro_la_LIBADD += @LIBMYSQL_LIBADD@ +endif + +if USE_MAXMIND_GEOIP +librepro_la_LIBADD += @LIBGEOIP_LIBADD@ +endif + +# reproInfo.hxx is created manually be other build systems +# but here we just delegate to the autoconf generated config.h +reproInfo.hxx: + @echo "#include \"config.h\"" > reproInfo.hxx + cat reproInfo.hxx + +ReproVersion.cxx: reproInfo.hxx + +dist_man_MANS = doc/repro.8 +dist_man_MANS += doc/reprocmd.8 + +sysconf_DATA = etc/repro.conf + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# <http://www.vovida.org/>. +# +############################################################################## diff --git a/src/libs/resiprocate/repro/MySqlDb.cxx b/src/libs/resiprocate/repro/MySqlDb.cxx new file mode 100644 index 00000000..9087afc0 --- /dev/null +++ b/src/libs/resiprocate/repro/MySqlDb.cxx @@ -0,0 +1,792 @@ +#include <cassert> +#include <fcntl.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_MYSQL + +#ifdef WIN32 +#include <errmsg.h> +#else +#include <mysql/errmsg.h> +#endif + +#include "rutil/Data.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" + +#include "repro/AbstractDb.hxx" +#include "repro/MySqlDb.hxx" + + +using namespace resip; +using namespace repro; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +extern "C" +{ + void mysqlThreadEnd(void*) + { + mysql_thread_end(); + } +} + +// This class helps ensure that each thread using the MySQL API's +// initialize by calling mysql_thread_init before calling any mySQL functions +class MySQLInitializer +{ + public: + MySQLInitializer() + { + ThreadIf::tlsKeyCreate(mThreadStorage, mysqlThreadEnd); + } + ~MySQLInitializer() + { + ThreadIf::tlsKeyDelete(mThreadStorage); + } + void setInitialized() + { + ThreadIf::tlsSetValue(mThreadStorage, (void*) true); + } + bool isInitialized() + { + // Note: if value is not set yet then 0 (false) is returned + return ThreadIf::tlsGetValue(mThreadStorage) != 0; + } + + private: + ThreadIf::TlsKey mThreadStorage; +}; +static MySQLInitializer g_MySQLInitializer; + +MySqlDb::MySqlDb(const Data& server, + const Data& user, + const Data& password, + const Data& databaseName, + unsigned int port, + const Data& customUserAuthQuery) : + mDBServer(server), + mDBUser(user), + mDBPassword(password), + mDBName(databaseName), + mDBPort(port), + mCustomUserAuthQuery(customUserAuthQuery), + mConn(0), + mConnected(false) +{ + InfoLog( << "Using MySQL DB with server=" << server << ", user=" << user << ", dbName=" << databaseName << ", port=" << port); + + for (int i=0;i<MaxTable;i++) + { + mResult[i]=0; + } + + mysql_library_init(0, 0, 0); + if(!mysql_thread_safe()) + { + ErrLog( << "Repro uses MySQL from multiple threads - you MUST link with a thread safe version of the mySQL client library!"); + } + else + { + connectToDatabase(); + } +} + + +MySqlDb::~MySqlDb() +{ + disconnectFromDatabase(); +} + +void +MySqlDb::initialize() const +{ + if(!g_MySQLInitializer.isInitialized()) + { + g_MySQLInitializer.setInitialized(); + mysql_thread_init(); + } +} + +void +MySqlDb::disconnectFromDatabase() const +{ + if(mConn) + { + for (int i=0;i<MaxTable;i++) + { + if (mResult[i]) + { + mysql_free_result(mResult[i]); + mResult[i]=0; + } + } + + mysql_close(mConn); + mConn = 0; + mConnected = false; + } +} + +int +MySqlDb::connectToDatabase() const +{ + // Disconnect from database first (if required) + disconnectFromDatabase(); + + // Now try to connect + assert(mConn == 0); + assert(mConnected == false); + + mConn = mysql_init(0); + if(mConn == 0) + { + ErrLog( << "MySQL init failed: insufficient memory."); + return CR_OUT_OF_MEMORY; + } + + MYSQL* ret = mysql_real_connect(mConn, + mDBServer.c_str(), // hostname + mDBUser.c_str(), // user + mDBPassword.c_str(), // password + mDBName.c_str(), // DB + mDBPort, // port + 0, // unix socket file + CLIENT_MULTI_RESULTS); // client flags (enable multiple results, since some custom stored procedures might require this) + + if (ret == 0) + { + int rc = mysql_errno(mConn); + ErrLog( << "MySQL connect failed: error=" << rc << ": " << mysql_error(mConn)); + mysql_close(mConn); + mConn = 0; + mConnected = false; + return rc; + } + else + { + mConnected = true; + return 0; + } +} + +int +MySqlDb::query(const Data& queryCommand, MYSQL_RES** result) const +{ + int rc = 0; + + initialize(); + + DebugLog( << "MySqlDb::query: executing query: " << queryCommand); + + Lock lock(mMutex); + if(mConn == 0 || !mConnected) + { + rc = connectToDatabase(); + } + if(rc == 0) + { + assert(mConn!=0); + assert(mConnected); + rc = mysql_query(mConn,queryCommand.c_str()); + if(rc != 0) + { + rc = mysql_errno(mConn); + if(rc == CR_SERVER_GONE_ERROR || + rc == CR_SERVER_LOST) + { + // First failure is a connection error - try to re-connect and then try again + rc = connectToDatabase(); + if(rc == 0) + { + // OK - we reconnected - try query again + rc = mysql_query(mConn,queryCommand.c_str()); + if( rc != 0) + { + ErrLog( << "MySQL query failed: error=" << mysql_errno(mConn) << ": " << mysql_error(mConn)); + } + } + } + else + { + ErrLog( << "MySQL query failed: error=" << mysql_errno(mConn) << ": " << mysql_error(mConn)); + } + } + } + + // Now store result - if pointer to result pointer was supplied and no errors + if(rc == 0 && result) + { + *result = mysql_store_result(mConn); + if(*result == 0) + { + rc = mysql_errno(mConn); + if(rc != 0) + { + ErrLog( << "MySQL store result failed: error=" << rc << ": " << mysql_error(mConn)); + } + } + } + + if(rc != 0) + { + ErrLog( << " SQL Command was: " << queryCommand) ; + } + return rc; +} + +int +MySqlDb::singleResultQuery(const Data& queryCommand, std::vector<Data>& fields) const +{ + MYSQL_RES* result=0; + int rc = query(queryCommand, &result); + + if(rc == 0) + { + if(result == 0) + { + return rc; + } + + MYSQL_ROW row = mysql_fetch_row(result); + if(row) + { + for(unsigned int i = 0; i < result->field_count; i++) + { + fields.push_back(Data(row[i])); + } + } + else + { + rc = mysql_errno(mConn); + if(rc != 0) + { + ErrLog( << "MySQL fetch row failed: error=" << rc << ": " << mysql_error(mConn)); + } + } + mysql_free_result(result); + } + return rc; +} + +resip::Data& +MySqlDb::escapeString(const resip::Data& str, resip::Data& escapedStr) const +{ + escapedStr.truncate2(mysql_real_escape_string(mConn, (char*)escapedStr.getBuf(str.size()*2+1), str.c_str(), str.size())); + return escapedStr; +} + +bool +MySqlDb::addUser(const AbstractDb::Key& key, const AbstractDb::UserRecord& rec) +{ + Data command; + { + DataStream ds(command); + ds << "INSERT INTO users (user, domain, realm, passwordHash, passwordHashAlt, name, email, forwardAddress)" + << " VALUES('" + << rec.user << "', '" + << rec.domain << "', '" + << rec.realm << "', '" + << rec.passwordHash << "', '" + << rec.passwordHashAlt << "', '" + << rec.name << "', '" + << rec.email << "', '" + << rec.forwardAddress << "')" + << " ON DUPLICATE KEY UPDATE" + << " user='" << rec.user + << "', domain='" << rec.domain + << "', realm='" << rec.realm + << "', passwordHash='" << rec.passwordHash + << "', passwordHashAlt='" << rec.passwordHashAlt + << "', name='" << rec.name + << "', email='" << rec.email + << "', forwardAddress='" << rec.forwardAddress + << "'"; + } + return query(command, 0) == 0; +} + + +void +MySqlDb::eraseUser(const AbstractDb::Key& key ) +{ + Data command; + { + DataStream ds(command); + ds << "DELETE FROM users "; + userWhereClauseToDataStream(key, ds); + } + query(command, 0); +} + + +AbstractDb::UserRecord +MySqlDb::getUser( const AbstractDb::Key& key ) const +{ + AbstractDb::UserRecord ret; + + Data command; + { + DataStream ds(command); + ds << "SELECT user, domain, realm, passwordHash, passwordHashAlt, name, email, forwardAddress FROM users "; + userWhereClauseToDataStream(key, ds); + } + + MYSQL_RES* result=0; + if(query(command, &result) != 0) + { + return ret; + } + + if (result==0) + { + ErrLog( << "MySQL store result failed: error=" << mysql_errno(mConn) << ": " << mysql_error(mConn)); + return ret; + } + + MYSQL_ROW row = mysql_fetch_row(result); + if (row) + { + int col = 0; + ret.user = Data(row[col++]); + ret.domain = Data(row[col++]); + ret.realm = Data(row[col++]); + ret.passwordHash = Data(row[col++]); + ret.passwordHashAlt = Data(row[col++]); + ret.name = Data(row[col++]); + ret.email = Data(row[col++]); + ret.forwardAddress = Data(row[col++]); + } + + mysql_free_result(result); + + return ret; +} + + +resip::Data +MySqlDb::getUserAuthInfo( const AbstractDb::Key& key ) const +{ + std::vector<Data> ret; + + Data command; + { + DataStream ds(command); + Data user; + Data domain; + getUserAndDomainFromKey(key, user, domain); + ds << "SELECT passwordHash FROM users WHERE user = '" << user << "' AND domain = '" << domain << "' "; + + // Note: domain is empty when querying for HTTP admin user - for this special user, + // we will only check the repro db, by not adding the UNION statement below + if(!mCustomUserAuthQuery.empty() && !domain.empty()) + { + ds << " UNION " << mCustomUserAuthQuery; + ds.flush(); + command.replace("$user", user); + command.replace("$domain", domain); + } + } + + if(singleResultQuery(command, ret) != 0 || ret.size() == 0) + { + return Data::Empty; + } + + DebugLog( << "Auth password is " << ret.front()); + + return ret.front(); +} + + +AbstractDb::Key +MySqlDb::firstUserKey() +{ + // free memory from previous search + if (mResult[UserTable]) + { + mysql_free_result(mResult[UserTable]); + mResult[UserTable] = 0; + } + + Data command("SELECT user, domain FROM users"); + + if(query(command, &mResult[UserTable]) != 0) + { + return Data::Empty; + } + + if(mResult[UserTable] == 0) + { + ErrLog( << "MySQL store result failed: error=" << mysql_errno(mConn) << ": " << mysql_error(mConn)); + return Data::Empty; + } + + return nextUserKey(); +} + + +AbstractDb::Key +MySqlDb::nextUserKey() +{ + if(mResult[UserTable] == 0) + { + return Data::Empty; + } + + MYSQL_ROW row = mysql_fetch_row(mResult[UserTable]); + if (!row) + { + mysql_free_result(mResult[UserTable]); + mResult[UserTable] = 0; + return Data::Empty; + } + Data user(row[0]); + Data domain(row[1]); + + return user+"@"+domain; +} + + +bool +MySqlDb::dbWriteRecord(const Table table, + const resip::Data& pKey, + const resip::Data& pData) +{ + Data command; + + // Check if there is a secondary key or not and get it's value + char* secondaryKey; + unsigned int secondaryKeyLen; + Data escapedKey; + if(AbstractDb::getSecondaryKey(table, pKey, pData, (void**)&secondaryKey, &secondaryKeyLen) == 0) + { + Data escapedSKey; + Data sKey(Data::Share, secondaryKey, secondaryKeyLen); + DataStream ds(command); + ds << "REPLACE INTO " << tableName(table) + << " SET attr='" << escapeString(pKey, escapedKey) + << "', attr2='" << escapeString(sKey, escapedSKey) + << "', value='" << pData.base64encode() + << "'"; + } + else + { + DataStream ds(command); + ds << "REPLACE INTO " << tableName(table) + << " SET attr='" << escapeString(pKey, escapedKey) + << "', value='" << pData.base64encode() + << "'"; + } + + return query(command, 0) == 0; +} + +bool +MySqlDb::dbReadRecord(const Table table, + const resip::Data& pKey, + resip::Data& pData) const +{ + Data command; + Data escapedKey; + { + DataStream ds(command); + ds << "SELECT value FROM " << tableName(table) + << " WHERE attr='" << escapeString(pKey, escapedKey) + << "'"; + } + + MYSQL_RES* result = 0; + if(query(command, &result) != 0) + { + return false; + } + + if (result == 0) + { + ErrLog( << "MySQL store result failed: error=" << mysql_errno(mConn) << ": " << mysql_error(mConn)); + return false; + } + else + { + bool success = false; + MYSQL_ROW row=mysql_fetch_row(result); + if(row) + { + pData = Data(Data::Share, row[0], (Data::size_type)strlen(row[0])).base64decode(); + success = true; + } + mysql_free_result(result); + return success; + } +} + + +void +MySqlDb::dbEraseRecord(const Table table, + const resip::Data& pKey, + bool isSecondaryKey) // allows deleting records from a table that supports secondary keying using a secondary key +{ + Data command; + { + DataStream ds(command); + Data escapedKey; + ds << "DELETE FROM " << tableName(table); + if(isSecondaryKey) + { + ds << " WHERE attr2='" << escapeString(pKey, escapedKey) << "'"; + } + else + { + ds << " WHERE attr='" << escapeString(pKey, escapedKey) << "'"; + } + } + query(command, 0); +} + + +resip::Data +MySqlDb::dbNextKey(const Table table, bool first) +{ + if(first) + { + // free memory from previous search + if (mResult[table]) + { + mysql_free_result(mResult[table]); + mResult[table] = 0; + } + + Data command; + { + DataStream ds(command); + ds << "SELECT attr FROM " << tableName(table); + } + + if(query(command, &mResult[table]) != 0) + { + return Data::Empty; + } + + if (mResult[table] == 0) + { + ErrLog( << "MySQL store result failed: error=" << mysql_errno(mConn) << ": " << mysql_error(mConn)); + return Data::Empty; + } + } + else + { + if (mResult[table] == 0) + { + return Data::Empty; + } + } + + MYSQL_ROW row = mysql_fetch_row(mResult[table]); + if (!row) + { + mysql_free_result(mResult[table]); + mResult[table] = 0; + return Data::Empty; + } + + return Data(row[0]); +} + + +bool +MySqlDb::dbNextRecord(const Table table, + const resip::Data& key, + resip::Data& data, + bool forUpdate, // specifying to add SELECT ... FOR UPDATE so the rows are locked + bool first) // return false if no more +{ + if(first) + { + // free memory from previous search + if (mResult[table]) + { + mysql_free_result(mResult[table]); + mResult[table] = 0; + } + + Data command; + { + DataStream ds(command); + ds << "SELECT value FROM " << tableName(table); + if(!key.empty()) + { + Data escapedKey; + // dbNextRecord is used to iterator through database tables that support duplication records + // it is only appropriate for MySQL tables that contain the attr2 non-unique index (secondary key) + ds << " WHERE attr2='" << escapeString(key, escapedKey) << "'"; + } + if(forUpdate) + { + ds << " FOR UPDATE"; + } + } + + if(query(command, &mResult[table]) != 0) + { + return false; + } + + if (mResult[table] == 0) + { + ErrLog( << "MySQL store result failed: error=" << mysql_errno(mConn) << ": " << mysql_error(mConn)); + return false; + } + } + + if (mResult[table] == 0) + { + return false; + } + + MYSQL_ROW row = mysql_fetch_row(mResult[table]); + if (!row) + { + mysql_free_result(mResult[table]); + mResult[table] = 0; + return false; + } + + data = Data(Data::Share, row[0], (Data::size_type)strlen(row[0])).base64decode(); + + return true; +} + +bool +MySqlDb::dbBeginTransaction(const Table table) +{ + Data command("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ"); + if(query(command, 0) == 0) + { + command = "START TRANSACTION"; + return query(command, 0) == 0; + } + return false; +} + +bool +MySqlDb::dbCommitTransaction(const Table table) +{ + Data command("COMMIT"); + return query(command, 0) == 0; +} + +bool +MySqlDb::dbRollbackTransaction(const Table table) +{ + Data command("ROLLBACK"); + return query(command, 0) == 0; +} + +static const char usersavp[] = "usersavp"; +static const char routesavp[] = "routesavp"; +static const char aclsavp[] = "aclsavp"; +static const char configsavp[] = "configsavp"; +static const char staticregsavp[] = "staticregsavp"; +static const char filtersavp[] = "filtersavp"; +static const char siloavp[] = "siloavp"; + +const char* +MySqlDb::tableName(Table table) const +{ + switch (table) + { + case UserTable: + assert(false); // usersavp is not used! + return usersavp; + case RouteTable: + return routesavp; + case AclTable: + return aclsavp; + case ConfigTable: + return configsavp; + case StaticRegTable: + return staticregsavp; + case FilterTable: + return filtersavp; + case SiloTable: + return siloavp; + default: + assert(0); + } + return 0; +} + +void +MySqlDb::userWhereClauseToDataStream(const Key& key, DataStream& ds) const +{ + Data user; + Data domain; + getUserAndDomainFromKey(key, user, domain); + ds << " WHERE user='" << user + << "' AND domain='" << domain + << "'"; +} + +void +MySqlDb::getUserAndDomainFromKey(const Key& key, Data& user, Data& domain) const +{ + ParseBuffer pb(key); + const char* start = pb.position(); + pb.skipToOneOf("@"); + pb.data(user, start); + const char* anchor = pb.skipChar(); + pb.skipToEnd(); + pb.data(domain, anchor); +} + +#endif // USE_MYSQL + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/MySqlDb.hxx b/src/libs/resiprocate/repro/MySqlDb.hxx new file mode 100644 index 00000000..6286c83a --- /dev/null +++ b/src/libs/resiprocate/repro/MySqlDb.hxx @@ -0,0 +1,138 @@ +#if !defined(RESIP_MYSQLDB_HXX) +#define RESIP_MYSQLDB_HXX + +#ifdef WIN32 +#include <mysql.h> +#else +#include <mysql/mysql.h> +#endif + +#include "rutil/Data.hxx" +#include "repro/AbstractDb.hxx" + +namespace resip +{ + class TransactionUser; +} + +namespace repro +{ + +class MySqlDb: public AbstractDb +{ + public: + MySqlDb(const resip::Data& dbServer, + const resip::Data& user, + const resip::Data& password, + const resip::Data& databaseName, + unsigned int port, + const resip::Data& customUserAuthQuery); + + virtual ~MySqlDb(); + + virtual bool isSane() {return mConnected;} + + virtual bool addUser( const Key& key, const UserRecord& rec ); + virtual void eraseUser( const Key& key ); + virtual UserRecord getUser( const Key& key ) const; + virtual resip::Data getUserAuthInfo( const Key& key ) const; + virtual Key firstUserKey();// return empty if no more + virtual Key nextUserKey(); // return empty if no more + + // Perform a query that expects a single result/row - returns all column/field data in a vector + virtual int singleResultQuery(const resip::Data& queryCommand, std::vector<resip::Data>& fields) const; + + private: + // Db manipulation routines + virtual bool dbWriteRecord(const Table table, + const resip::Data& key, + const resip::Data& data); + virtual bool dbReadRecord(const Table table, + const resip::Data& key, + resip::Data& data) const; // return false if not found + virtual void dbEraseRecord(const Table table, + const resip::Data& key, + bool isSecondaryKey=false); // allows deleting records from a table that supports secondary keying using a secondary key + virtual resip::Data dbNextKey(const Table table, + bool first=true); // return empty if no more + virtual bool dbNextRecord(const Table table, + const resip::Data& key, + resip::Data& data, + bool forUpdate, // specifying to add SELECT ... FOR UPDATE so the rows are locked + bool first=false); // return false if no more + virtual bool dbBeginTransaction(const Table table); + virtual bool dbCommitTransaction(const Table table); + virtual bool dbRollbackTransaction(const Table table); + + void initialize() const; + void disconnectFromDatabase() const; + int connectToDatabase() const; + int query(const resip::Data& queryCommand, MYSQL_RES** result) const; + resip::Data& escapeString(const resip::Data& str, resip::Data& escapedStr) const; + + resip::Data mDBServer; + resip::Data mDBUser; + resip::Data mDBPassword; + resip::Data mDBName; + unsigned int mDBPort; + resip::Data mCustomUserAuthQuery; + + mutable MYSQL* mConn; + mutable MYSQL_RES* mResult[MaxTable]; + mutable volatile bool mConnected; + // when multiple threads are in use with the same connection, you need to + // mutex calls to mysql_query and mysql_store_result: + // http://dev.mysql.com/doc/refman/5.1/en/threaded-clients.html + mutable resip::Mutex mMutex; + + const char* tableName( Table table ) const; + void userWhereClauseToDataStream(const Key& key, resip::DataStream& ds) const; + void getUserAndDomainFromKey(const AbstractDb::Key& key, resip::Data& user, resip::Data& domain) const; +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/OutboundTarget.cxx b/src/libs/resiprocate/repro/OutboundTarget.cxx new file mode 100644 index 00000000..95fd4fbd --- /dev/null +++ b/src/libs/resiprocate/repro/OutboundTarget.cxx @@ -0,0 +1,84 @@ +#include "repro/OutboundTarget.hxx" + +namespace repro +{ + +OutboundTarget::OutboundTarget(const resip::Data& aor, + const resip::ContactList& recs) : + QValueTarget(recs.empty() ? resip::ContactInstanceRecord() : recs.front()), + mAor(aor), + mList(recs) +{ + if(!mList.empty()) + { + mList.pop_front(); + } +} + +OutboundTarget::~OutboundTarget() +{} + +OutboundTarget* +OutboundTarget::nextInstance() +{ + if(mList.size() <= 1) + { + return 0; + } + + mList.pop_front(); + return new OutboundTarget(mAor, mList); +} + +OutboundTarget* +OutboundTarget::clone() const +{ + return new OutboundTarget(*this); +} + +} // of namespace repro + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ + diff --git a/src/libs/resiprocate/repro/OutboundTarget.hxx b/src/libs/resiprocate/repro/OutboundTarget.hxx new file mode 100644 index 00000000..8bba91b2 --- /dev/null +++ b/src/libs/resiprocate/repro/OutboundTarget.hxx @@ -0,0 +1,79 @@ +#ifndef OutboundTarget_Include_Guard +#define OutboundTarget_Include_Guard + +#include "repro/QValueTarget.hxx" + +namespace repro +{ +class OutboundTarget : public QValueTarget +{ + public: + OutboundTarget(const resip::Data& aor, + const resip::ContactList& recs); + virtual ~OutboundTarget(); + + OutboundTarget* nextInstance(); + + virtual OutboundTarget* clone() const; + + static bool instanceCompare(const resip::ContactInstanceRecord& lhs, + const resip::ContactInstanceRecord& rhs) + { + return lhs.mLastUpdated > rhs.mLastUpdated; + } + + inline const resip::Data& getAor() const { return mAor;} + + protected: + resip::Data mAor; + resip::ContactList mList; +}; // class OutboundTarget + +} // namespace repro + +#endif // include guard + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ + diff --git a/src/libs/resiprocate/repro/PersistentMessageQueue.cxx b/src/libs/resiprocate/repro/PersistentMessageQueue.cxx new file mode 100644 index 00000000..c916c7da --- /dev/null +++ b/src/libs/resiprocate/repro/PersistentMessageQueue.cxx @@ -0,0 +1,458 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +//#include <fcntl.h> +//#include <cassert> +//#include <cstdlib> + +#include "rutil/Data.hxx" +#include "rutil/FileSystem.hxx" +#include "rutil/Logger.hxx" + +#include "repro/PersistentMessageQueue.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace repro; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +struct Transaction +{ + Transaction() : mDbTxn(0) + { + } + + void init(DbEnv * dbenv) + { + // let caller catch exceptions + dbenv->txn_begin(NULL, &mDbTxn, 0); + } + + ~Transaction() + { + abort(); + } + + void abort() + { + // don't throw exceptions since this is called in destructor + if(mDbTxn !=0 ) + { + try + { + mDbTxn->abort(); + } + catch(DbException&) {} + catch(std::exception&) {} + catch(...) {} + + mDbTxn = 0; + } + } + + void commit() + { + // let caller catch exceptions + if(mDbTxn !=0 ) + { + mDbTxn->commit(0); + mDbTxn = 0; + } + } + + DbTxn* mDbTxn; +}; + +struct Cursor +{ + Cursor() : mDbc(0) + { + } + + void init(Db* db, DbTxn* t) + { + // let caller catch exceptions + db->cursor(t, &mDbc, 0); + } + + ~Cursor() + { + close(); + } + + void close() + { + // don't throw exceptions since this is called in destructor + if(mDbc) + { + try + { + mDbc->close(); + } + catch(DbException&) {} + catch(std::exception&) {} + catch(...) {} + + mDbc = 0; + } + } + + Dbc* mDbc; +}; + +PersistentMessageQueue::PersistentMessageQueue(const Data& baseDir) : + DbEnv(0), + mDb(0), + mBaseDir(baseDir), + mRecoveryNeeded(false) +{ +} + +PersistentMessageQueue::~PersistentMessageQueue() +{ + if(mDb) + { + try + { + mDb->close(0); + } + catch(DbException&) {} + catch(std::exception&) {} + catch(...) {} + } + + try + { + delete mDb; + close(0); + } + catch(DbException&) {} + catch(std::exception&) {} + catch(...) {} +} + +bool +PersistentMessageQueue::init(bool sync, const resip::Data& queueName) +{ + try + { + // For Berkeley DB Concurrent Data Store applications, perform locking on an environment-wide basis rather than per-database. + set_flags(DB_CDB_ALLDB, 1); + + if(sync) + { + // Write changes to disk on transaction commit + set_flags(DB_TXN_NOSYNC, 0); + } + else + { + set_flags(DB_TXN_NOSYNC, 1); + } + + Data homeDir; + if (mBaseDir.postfix("/") || + mBaseDir.postfix("\\") || + mBaseDir.empty()) + { + homeDir = mBaseDir + queueName; + } + else + { + homeDir = mBaseDir + Data("/") + queueName; + } + + // Create directory if it doesn't exist + FileSystem::Directory dir(homeDir); + dir.create(); + + open(homeDir.c_str(), // home directory + DB_INIT_LOCK // Initialize Locking (needed for transactions) + | DB_INIT_LOG // Initialize Logging (needed for transactions) + | DB_INIT_TXN // Initialize transactions + | DB_INIT_MPOOL // Initialize the cache (needed for transactions) + | DB_REGISTER // Check to see if recovery needs to be performed before opening the database environment + | DB_RECOVER // Run normal recovery + | DB_CREATE // If the env does not exist, then create it + | DB_THREAD, // Free-thread the env handle + 0); // mode + + mDb = new Db(this, 0); + + // cause the logical record numbers to be mutable, and change as records are added to and deleted from the database. + mDb->set_flags(DB_RENUMBER); + + mDb->open(0, // txnid + "msgqueue", // filename + 0, // database name + DB_RECNO, // database type + DB_AUTO_COMMIT // enclose db->open within a transaction + | DB_CREATE // create the database if it doesn't already exist + | DB_THREAD, // allow free-threaded db access + 0); // mode + + return true; + } + catch(DbException& e) + { + if(e.get_errno() == DB_RUNRECOVERY) + { + mRecoveryNeeded = true; + } + WarningLog( << "PersistentMessageQueue::init - DBException: " << e.what()); + } + catch(std::exception& e) + { + WarningLog( << "PersistentMessageQueue::init - std::exception: " << e.what()); + } + catch(...) + { + WarningLog( << "PersistentMessageQueue::init - unknown exception"); + } + + return false; +} + +bool +PersistentMessageQueue::isRecoveryNeeded() +{ + return mRecoveryNeeded; +} + +bool +PersistentMessageEnqueue::push(const resip::Data& data) +{ + int res; + + try + { + Transaction transaction; + transaction.init(this); + + db_recno_t recno; + recno = 0; + Dbt val((void*)data.c_str(), data.size()); + Dbt key((void*)&recno, sizeof(recno)); + + key.set_ulen(sizeof(recno)); + key.set_flags(DB_DBT_USERMEM); + + res = mDb->put(transaction.mDbTxn, &key, &val, DB_APPEND); + if(res == 0) + { + transaction.commit(); + return true; + } + else + { + WarningLog( << "PersistentMessageEnqueue::push - put failed: " << db_strerror(res)); + return false; + } + } + catch(DbException& e) + { + if(e.get_errno() == DB_RUNRECOVERY) + { + mRecoveryNeeded = true; + } + WarningLog( << "PersistentMessageEnqueue::push - DBException: " << e.what()); + } + catch(std::exception& e) + { + WarningLog( << "PersistentMessageEnqueue::push - std::exception: " << e.what()); + } + catch(...) + { + WarningLog( << "PersistentMessageEnqueue::push - unknown exception"); + } + return false; +} + +// returns true for success, false for failure - can return true and 0 records if none available +// Note: if autoCommit is used then it is safe to allow multiple consumers +bool +PersistentMessageDequeue::pop(size_t numRecords, std::vector<resip::Data>& records, bool autoCommit) +{ + if(mNumRecords != 0) // TODO, warning previous pop wasn't committed + { + abort(); + } + records.clear(); + + // Get a cursor and Read + try + { + Transaction transaction; // Only used with auto-commit + Cursor cursor; + if(autoCommit) + { + transaction.init(this); + } + cursor.init(mDb, transaction.mDbTxn); // If autoCommit is false then mDbTxn is 0 + + Dbt val; + db_recno_t recno = 0; + Dbt key((void*)&recno, sizeof(recno)); + + for(size_t i = 0; i < numRecords; i ++ ) + { + int get_res = cursor.mDbc->get(&key, &val, DB_NEXT | (autoCommit ? DB_RMW : 0)); + + if(get_res == 0) + { + records.push_back(Data((const char *)val.get_data(), val.get_size())); + if(autoCommit) + { + cursor.mDbc->del(0); + } + } + else + { + break; + } + } + + cursor.close(); + if(autoCommit) + { + transaction.commit(); + } + else + { + mNumRecords = records.size(); + } + return true; + } + catch(DbException& e) + { + if(e.get_errno() == DB_RUNRECOVERY) + { + mRecoveryNeeded = true; + } + WarningLog( << "PersistentMessageDequeue::pop - DBException: " << e.what()); + abort(); + return false; + } + catch(std::exception& e) + { + WarningLog( << "PersistentMessageDequeue::pop - std::exception: " << e.what()); + abort(); + return false; + } + catch(...) + { + WarningLog( << "PersistentMessageDequeue::pop - unknown exception"); + } +} + +bool +PersistentMessageDequeue::commit() +{ + if(mNumRecords == 0) + { + return true; + } + + // Read and delete + try + { + Transaction transaction; + Cursor cursor; + + transaction.init(this); + cursor.init(mDb, transaction.mDbTxn); + + Dbt val; + db_recno_t recno = 0; + Dbt key((void*)&recno, sizeof(recno)); + + for(size_t i = 0; i < mNumRecords; i++) + { + int get_res = cursor.mDbc->get(&key, &val, DB_NEXT | DB_RMW); + if(get_res == 0) + { + cursor.mDbc->del(0); + } + else + { + break; // this is bad! + } + } + + mNumRecords = 0; + cursor.close(); + transaction.commit(); + + return true; + } + catch(DbException& e) + { + if(e.get_errno() == DB_RUNRECOVERY) + { + mRecoveryNeeded = true; + } + WarningLog( << "PersistentMessageDequeue::commit - DBException: " << e.what()); + } + catch(std::exception& e) + { + WarningLog( << "PersistentMessageDequeue::commit - std::exception: " << e.what()); + } + catch(...) + { + WarningLog( << "PersistentMessageDequeue::commit - unknown exception"); + } + return false; +} + +void +PersistentMessageDequeue::abort() +{ + mNumRecords = 0; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/PersistentMessageQueue.hxx b/src/libs/resiprocate/repro/PersistentMessageQueue.hxx new file mode 100644 index 00000000..01e21dac --- /dev/null +++ b/src/libs/resiprocate/repro/PersistentMessageQueue.hxx @@ -0,0 +1,214 @@ +#if !defined(RESIP_PERSISTENTMESSAGEQUEUE_HXX) +#define RESIP_PERSISTENTMESSAGEQUEUE_HXX + +#ifdef WIN32 +#include <db_cxx.h> +#elif HAVE_CONFIG_H +#include "config.h" +#include DB_HEADER +//#elif defined(__APPLE__) +//#include <db42/db_cxx.h> +#else +#include <db_cxx.h> +#endif + +#include "rutil/Data.hxx" +#include <vector> + +// This class implements a persistent message queue that utilizes a BerkeleyDb backing store. +// Messages are persisted out to disk and can be consumed from another process using the +// PeristentMessageDequeue class. +// +// If PersistentMessageEnqueue::push or +// PersistentMessageDequeue::pop or +// PersistentMessageDequeue::commit +// even fail, then the isRecoveryNeeded should be called. If this returns true, then the +// PersistentMessageQueue in use should be destroyed and a new one created in order to "recover" +// the backing store. +// +// Warning: If autoCommit is not used on PersistentMessageDequeue::pop then there can only be 1 +// consumer. +// +// Producer example: +// ----------------- +// PersistentMessageEnqueue* queue = new PersistentMessageEnqueue; +// if(queue->init(true, "msgqueue")) +// { +// for(int i = 0; i < 1000; i++) +// { +// Data qstr("test string" + Data(i)); +// if(!queue->push(qstr)) +// { +// if(queue->isRecoveryNeeded()) +// { +// delete queue; +// queue = new PersistentMessageEnqueue; +// if(!queue->init(true, "msgqueue")) break; +// if(queue->push(qstr)) +// { +// cout << "Queued: " << qstr << endl; +// } +// else +// { +// cout << "Error queuing - exiting!" << endl; +// break; +// } +// } +// else +// { +// cout << "Error queuing - exiting!" << endl; +// break; +// } +// } +// else +// { +// cout << "Queued: " << qstr << endl; +// } +// } +//} +//delete queue; +// +// +// Consumer example: +// ----------------- +//PersistentMessageDequeue* queue = new PersistentMessageDequeue; +//if(queue->init(true, "msgqueue")) +//{ +// vector<resip::Data> recs; +// while(true) +// { +// if(queue->pop(5, recs, false)) +// { +// if(recs.size() > 0) +// { +// for(int i = 0; i < recs.size(); i++) +// { +// cout << "Popped(" << i << "): " << recs[i] << endl; +// } +// queue->commit(); +// } +// else +// { +// cout << "No records to pop." << endl; +// Sleep(1000); +// //break; +// } +// } +// else +// { +// if(queue->isRecoveryNeeded()) +// { +// delete queue; +// queue = new PersistentMessageDequeue; +// if(!queue->init(true, "msgqueue")) break; +// } +// else +// { +// cout << "Error Dequeuing!" << endl; +// break; +// } +// } +// } +//} +//delete queue; + + +namespace repro +{ +class PersistentMessageQueue : public DbEnv +{ +public: + PersistentMessageQueue(const resip::Data& baseDir); + virtual ~PersistentMessageQueue(); + + bool init(bool sync, const resip::Data& queueName); + bool isRecoveryNeeded(); + +protected: + Db* mDb; + resip::Data mBaseDir; + bool mRecoveryNeeded; +}; + +class PersistentMessageEnqueue : public PersistentMessageQueue +{ +public: + PersistentMessageEnqueue(const resip::Data& baseDir) : + PersistentMessageQueue(baseDir) {} + virtual ~PersistentMessageEnqueue() {} + + // Note: this has a potential to block if the a consumer crashes and leaves a lock open on the database (deadlock) + // typically restarting the consumer will "recover" the "dead" lock and allow this call to unblock + bool push(const resip::Data& data); +}; + +class PersistentMessageDequeue : public PersistentMessageQueue +{ +public: + PersistentMessageDequeue(const resip::Data& baseDir) : + PersistentMessageQueue(baseDir), + mNumRecords(0) {} + virtual ~PersistentMessageDequeue () {} + + // returns true for success, false for failure - can return true and 0 records if none available + // Note: if autoCommit is used then it is safe to allow multiple consumers + bool pop(size_t numRecords, std::vector<resip::Data>& records, bool autoCommit); + bool commit(); + void abort(); + +private: + size_t mNumRecords; + }; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/Processor.cxx b/src/libs/resiprocate/repro/Processor.cxx new file mode 100644 index 00000000..295f4f97 --- /dev/null +++ b/src/libs/resiprocate/repro/Processor.cxx @@ -0,0 +1,124 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <ostream> +#include "resip/stack/SipMessage.hxx" +#include "repro/Processor.hxx" + +using namespace resip; +using namespace repro; +using namespace std; + +Processor::Processor(const resip::Data& name, ChainType type) : + mType(type), + mName(name) +{ +} + +Processor::~Processor() +{ +} + +void +Processor::pushAddress(const std::vector<short>& address) +{ + for(std::vector<short>::const_iterator i=address.begin();i!=address.end();++i) + { + mAddress.push_back(*i); + } +} + +void +Processor::pushAddress(const short address) +{ + mAddress.push_back(address); +} + +void +Processor::setChainType(ChainType type) +{ + mType=type; +} + +Processor::ChainType +Processor::getChainType() const +{ + return mType; +} + +void +Processor::setName(const resip::Data& name) +{ + mName = name; +} + +const resip::Data& +Processor::getName() const +{ + return mName; +} + +const std::vector<short>& +Processor::getAddress() const +{ + return mAddress; +} + +EncodeStream & +repro::operator << (EncodeStream &os, const repro::Processor &rp) +{ + os << rp.getName(); + return os; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/Processor.hxx b/src/libs/resiprocate/repro/Processor.hxx new file mode 100644 index 00000000..f71e149c --- /dev/null +++ b/src/libs/resiprocate/repro/Processor.hxx @@ -0,0 +1,109 @@ +#if !defined(RESIP_REQUEST_PROCESSOR_HXX) +#define RESIP_REQUEST_PROCESSOR_HXX + +#include <iosfwd> +#include <vector> +#include "rutil/resipfaststreams.hxx" +#include "rutil/Data.hxx" + +namespace repro +{ +class RequestContext; + +class Processor +{ + public: + typedef enum + { + NO_TYPE=0, + REQUEST_CHAIN, + RESPONSE_CHAIN, + TARGET_CHAIN + } ChainType; + + Processor(const resip::Data& name, ChainType type=NO_TYPE); + virtual ~Processor(); + + typedef enum + { + Continue, // move onto the next Processor + WaitingForEvent, // stop Processor chain and wait for async response + SkipThisChain, + SkipAllChains + } + processor_action_t; + + virtual processor_action_t process(RequestContext &)=0; + + virtual void setChainType(ChainType type); + virtual ChainType getChainType() const; + + virtual void setName(const resip::Data& name); + virtual const resip::Data& getName() const; + + virtual void pushAddress(const std::vector<short>& address); + virtual void pushAddress(const short address); + + virtual const std::vector<short>& getAddress() const; + + protected: + std::vector<short> mAddress; + ChainType mType; + resip::Data mName; +}; + +EncodeStream &operator<<(EncodeStream &os, const repro::Processor &rp); +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/ProcessorChain.cxx b/src/libs/resiprocate/repro/ProcessorChain.cxx new file mode 100644 index 00000000..9a655dfe --- /dev/null +++ b/src/libs/resiprocate/repro/ProcessorChain.cxx @@ -0,0 +1,202 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <iostream> + +#include "repro/ProcessorChain.hxx" +#include "resip/stack/SipMessage.hxx" +#include "repro/ProcessorMessage.hxx" +#include "repro/RequestContext.hxx" + +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + + +ProcessorChain::ProcessorChain(Processor::ChainType type) : + Processor(Data::Empty, type) +{ + switch(type) + { + case REQUEST_CHAIN: + setName("RequestProcessor"); + break; + case RESPONSE_CHAIN: + setName("ResponseProcessor"); + break; + case TARGET_CHAIN: + setName("TargetProcessor"); + break; + case NO_TYPE: + default: + setName("UnknownProcessor"); + break; + } + DebugLog(<< "Instantiating new " << mName << " chain"); +} + +repro::ProcessorChain::~ProcessorChain() +{ + //DebugLog (<< "Deleting Chain: " << this); + for (Chain::iterator i = mChain.begin(); i != mChain.end(); ++i) + { + //DebugLog (<< "Deleting RP: " << *i << " : " << **i); + delete *i; + } + mChain.clear(); +} + +void +repro::ProcessorChain::addProcessor(auto_ptr<Processor> rp) +{ + DebugLog(<< "Adding new " << mName << " to chain: " << *(rp.get())); + rp->pushAddress((short)mChain.size()); + rp->pushAddress(mAddress); + rp->setChainType(mType); + mChain.push_back(rp.release()); +} + +repro::Processor::processor_action_t +repro::ProcessorChain::process(RequestContext &rc) +{ + //DebugLog(<< mName << " handling request: " << *this << "; reqcontext = " << rc); + + processor_action_t action; + unsigned int position=0; + + resip::Message* msg = rc.getCurrentEvent(); + + if(msg) + { + ProcessorMessage* proc = dynamic_cast<ProcessorMessage*>(msg); + + if(proc) + { + position=proc->popAddr(); + } + } + + for (; (position >=0 && position < mChain.size()); ++position) + { + DebugLog(<< "Chain invoking " << mName << ": " << *(mChain[position])); + + action = mChain[position]->process(rc); + + if (action == SkipAllChains) + { + DebugLog(<< mName << " aborted all chains: " << *(mChain[position])); + return SkipAllChains; + } + + if (action == WaitingForEvent) + { + DebugLog(<< mName << " waiting for async response: " << *(mChain[position])); + return WaitingForEvent; + } + + if (action == SkipThisChain) + { + DebugLog(<< mName << " skipping current chain: " << *(mChain[position])); + return Continue; + } + + } + //DebugLog(<< "Monkey done processing: " << *(mChain[position])); + return Continue; +} + +void +ProcessorChain::pushAddress(const std::vector<short>& address) +{ + Processor::pushAddress(address); + for(std::vector<Processor*>::iterator i=mChain.begin();i!=mChain.end();++i) + { + (**i).pushAddress(address); + } +} + +void +ProcessorChain::pushAddress(const short address) +{ + Processor::pushAddress(address); + for(std::vector<Processor*>::iterator i=mChain.begin();i!=mChain.end();++i) + { + (**i).pushAddress(address); + } +} + + +void +ProcessorChain::setChainType(ChainType type) +{ + mType=type; + std::vector<Processor*>::iterator i; + for(i=mChain.begin();i!=mChain.end();++i) + { + (*i)->setChainType(type); + } +} + +EncodeStream & +repro::operator << (EncodeStream &os, const repro::ProcessorChain &pc) +{ + os << pc.getName() << " chain: " << InserterP(pc.mChain); + return os; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/ProcessorChain.hxx b/src/libs/resiprocate/repro/ProcessorChain.hxx new file mode 100644 index 00000000..53bf7436 --- /dev/null +++ b/src/libs/resiprocate/repro/ProcessorChain.hxx @@ -0,0 +1,86 @@ +#if !defined(RESIP_REQUEST_PROCESSOR_CHAIN_HXX) +#define RESIP_REQUEST_PROCESSOR_CHAIN_HXX + +#include <memory> +#include <vector> +#include "repro/Processor.hxx" +#include "rutil/resipfaststreams.hxx" + +namespace repro +{ +class ProcessorChain : public Processor +{ + public: + ProcessorChain(ChainType type); + virtual ~ProcessorChain(); + + void addProcessor(std::auto_ptr<Processor>); + + virtual processor_action_t process(RequestContext &); + + typedef std::vector<Processor*> Chain; + + virtual void setChainType(ChainType type); + + virtual void pushAddress(const std::vector<short>& address); + virtual void pushAddress(const short address); + + private: + Chain mChain; + + friend EncodeStream &operator<<(EncodeStream &os, const repro::ProcessorChain &pc); +}; + +EncodeStream &operator<<(EncodeStream &os, const repro::ProcessorChain &pc); +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/ProcessorMessage.hxx b/src/libs/resiprocate/repro/ProcessorMessage.hxx new file mode 100644 index 00000000..b152c40b --- /dev/null +++ b/src/libs/resiprocate/repro/ProcessorMessage.hxx @@ -0,0 +1,132 @@ +#ifndef PROCESSOR_MESSAGE_HXX +#define PROCESSOR_MESSAGE_HXX 1 + +#include "resip/stack/ApplicationMessage.hxx" +#include "resip/stack/TransactionUser.hxx" +#include "repro/Processor.hxx" + +namespace repro +{ + +class ProcessorMessage : public resip::ApplicationMessage +{ + public: + + ProcessorMessage(const Processor& proc, + const resip::Data& tid, + resip::TransactionUser* tupassed): + mTid(tid) + { + mTu = tupassed; + mReturnAddress = proc.getAddress(); + mOriginatorAddress = mReturnAddress; + mType = proc.getChainType(); + } + + ProcessorMessage(const ProcessorMessage& orig) : + resip::ApplicationMessage(orig), + mTid(orig.mTid) + { + mReturnAddress=orig.mReturnAddress; + mOriginatorAddress=orig.mOriginatorAddress; + mType=orig.mType; + } + + virtual ~ProcessorMessage(){} + + void pushAddr(int addr) + { + mReturnAddress.push_back(addr); + } + + int popAddr() + { + if(mReturnAddress.empty()) + { + return 0; + } + + int addr = mReturnAddress.back(); + mReturnAddress.pop_back(); + return addr; + } + + std::vector<short>& getOriginatorAddress() + { + return mOriginatorAddress; + } + + Processor::ChainType chainType() const + { + return mType; + } + + virtual Message* clone() const = 0; + + virtual EncodeStream& encode(EncodeStream& strm) const = 0; + virtual EncodeStream& encodeBrief(EncodeStream& strm) const = 0; + + virtual const resip::Data& getTransactionId() const + { + return mTid; + } + + protected: + resip::Data mTid; + std::vector<short> mReturnAddress; + std::vector<short> mOriginatorAddress; + Processor::ChainType mType; +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/Proxy.cxx b/src/libs/resiprocate/repro/Proxy.cxx new file mode 100644 index 00000000..cd7b3c68 --- /dev/null +++ b/src/libs/resiprocate/repro/Proxy.cxx @@ -0,0 +1,697 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "repro/ProcessorChain.hxx" +#include "repro/Proxy.hxx" +#include "repro/Ack200DoneMessage.hxx" +#include "repro/UserStore.hxx" +#include "repro/Dispatcher.hxx" + +#include "resip/stack/TransactionTerminated.hxx" +#include "resip/stack/ApplicationMessage.hxx" +#include "resip/stack/SipStack.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/InteropHelper.hxx" +#include "rutil/Random.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +// Initialize statics +Data Proxy::FlowTokenSalt; + +// Use Static fn with static local object to ensure KeyValueStoreKeyAllocator is created before +// static calls to allocate new keys in the monkey classes +KeyValueStore::KeyValueStoreKeyAllocator* Proxy::getGlobalKeyValueStoreKeyAllocator() +{ + static KeyValueStore::KeyValueStoreKeyAllocator* globalAllocator = new KeyValueStore::KeyValueStoreKeyAllocator(); + return globalAllocator; +} + +KeyValueStore::KeyValueStoreKeyAllocator* Proxy::getRequestKeyValueStoreKeyAllocator() +{ + static KeyValueStore::KeyValueStoreKeyAllocator* requestAllocator = new KeyValueStore::KeyValueStoreKeyAllocator(); + return requestAllocator; +} + +KeyValueStore::KeyValueStoreKeyAllocator* Proxy::getTargetKeyValueStoreKeyAllocator() +{ + static KeyValueStore::KeyValueStoreKeyAllocator* targetAllocator = new KeyValueStore::KeyValueStoreKeyAllocator(); + return targetAllocator; +} + +KeyValueStore::Key Proxy::allocateGlobalKeyValueStoreKey() +{ + return getGlobalKeyValueStoreKeyAllocator()->allocateNewKey(); +} + +KeyValueStore::Key Proxy::allocateRequestKeyValueStoreKey() +{ + return getRequestKeyValueStoreKeyAllocator()->allocateNewKey(); +} + +KeyValueStore::Key Proxy::allocateTargetKeyValueStoreKey() +{ + return getTargetKeyValueStoreKeyAllocator()->allocateNewKey(); +} + +RequestContext* +RequestContextFactory::createRequestContext(Proxy& proxy, + ProcessorChain& requestP, // monkeys + ProcessorChain& responseP, // lemurs + ProcessorChain& targetP) // baboons +{ + return new RequestContext(proxy, requestP, responseP, targetP); +} + +Proxy::Proxy(SipStack& stack, + ProxyConfig& config, + ProcessorChain& requestP, + ProcessorChain& responseP, + ProcessorChain& targetP) + : TransactionUser(TransactionUser::RegisterForTransactionTermination), + mStack(stack), + mConfig(config), + mRecordRoute(config.getConfigUri("RecordRouteUri", Uri())), + mRecordRouteForced(config.getConfigBool("ForceRecordRouting", false)), + mAssumePath(config.getConfigBool("AssumePath", false)), + mPAssertedIdentityProcessing(config.getConfigBool("EnablePAssertedIdentityProcessing", false)), + mServerText(config.getConfigData("ServerText", "")), + mTimerC(config.getConfigInt("TimerC", 180)), + mKeyValueStore(*Proxy::getGlobalKeyValueStoreKeyAllocator()), + mRequestProcessorChain(requestP), + mResponseProcessorChain(responseP), + mTargetProcessorChain(targetP), + mUserStore(config.getDataStore()->mUserStore), + mOptionsHandler(0), + mRequestContextFactory(new RequestContextFactory), + mSessionAccountingEnabled(config.getConfigBool("SessionAccountingEnabled", false)), + mRegistrationAccountingEnabled(config.getConfigBool("RegistrationAccountingEnabled", false)), + mAccountingCollector(0) +{ + FlowTokenSalt = Random::getCryptoRandom(20); // 20-octet Crypto Random Key for Salting Flow Token HMACs + + mFifo.setDescription("Proxy::mFifo"); + + if(InteropHelper::getOutboundSupported()) + { + addSupportedOption("outbound"); + } + + // Create Accounting Collector if enabled + if(mSessionAccountingEnabled || mRegistrationAccountingEnabled) + { + mAccountingCollector = new AccountingCollector(config); + } +} + + +Proxy::~Proxy() +{ + shutdown(); + join(); + delete mAccountingCollector; + InfoLog (<< "Proxy::thread shutdown with " << mServerRequestContexts.size() << " ServerRequestContexts and " << mClientRequestContexts.size() << " ClientRequestContexts."); +} + +void +Proxy::setOptionsHandler(OptionsHandler* handler) +{ + mOptionsHandler = handler; +} + +void +Proxy::setRequestContextFactory(std::auto_ptr<RequestContextFactory> requestContextFactory) +{ + mRequestContextFactory = requestContextFactory; +} + +bool +Proxy::isShutDown() const +{ + return false; +} + + +UserStore& +Proxy::getUserStore() +{ + return mUserStore; +} + + +void +Proxy::thread() +{ + InfoLog (<< "Proxy::thread start"); + + while (!isShutdown()) + { + Message* msg=0; + //DebugLog (<< "TransactionUser::postToTransactionUser " << " &=" << &mFifo << " size=" << mFifo.size()); + + try + { + if ((msg = mFifo.getNext(100)) != 0) + { + DebugLog (<< "Got: " << *msg); + + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + ApplicationMessage* app = dynamic_cast<ApplicationMessage*>(msg); + TransactionTerminated* term = dynamic_cast<TransactionTerminated*>(msg); + + if (sip) + { + Data tid(sip->getTransactionId()); + tid.lowercase(); + if (sip->isRequest()) + { + // Verify that the request has all the mandatory headers + // (To, From, Call-ID, CSeq) Via is already checked by stack. + // See RFC 3261 Section 16.3 Step 1 + if (!sip->exists(h_To) || + !sip->exists(h_From) || + !sip->exists(h_CallID) || + !sip->exists(h_CSeq) ) + { + // skip this message and move on to the next one + delete sip; + continue; + } + + // The TU selector already checks the URI scheme for us (Sect 16.3, Step 2) + if(sip->method()==OPTIONS && + isMyUri(sip->header(h_RequestLine).uri())) + { + if(mOptionsHandler) + { + std::auto_ptr<SipMessage> resp(new SipMessage); + Helper::makeResponse(*resp,*sip,200); + if(mOptionsHandler->onOptionsRequest(*sip, *resp)) + { + mStack.send(*resp,this); + delete sip; + continue; + } + } + else if(sip->header(h_RequestLine).uri().user().empty()) + { + std::auto_ptr<SipMessage> resp(new SipMessage); + Helper::makeResponse(*resp,*sip,200); + + if(resip::InteropHelper::getOutboundSupported()) + { + resp->header(h_Supporteds).push_back(Token("outbound")); + } + mStack.send(*resp,this); + delete sip; + continue; + } + } + + // check the MaxForwards isn't too low + if (!sip->exists(h_MaxForwards)) + { + // .bwc. Add Max-Forwards header if not found. + sip->header(h_MaxForwards).value()=20; + } + + if(!sip->header(h_MaxForwards).isWellFormed()) + { + //Malformed Max-Forwards! (Maybe we can be lenient and set + // it to 70...) + std::auto_ptr<SipMessage> response(Helper::makeResponse(*sip,400)); + response->header(h_StatusLine).reason()="Malformed Max-Forwards"; + mStack.send(*response,this); + delete sip; + continue; + } + + // .bwc. Unacceptable values for Max-Forwards + // !bwc! TODO make this ceiling configurable + if(sip->header(h_MaxForwards).value() > 255) + { + sip->header(h_MaxForwards).value() = 20; + } + else if(sip->header(h_MaxForwards).value() <= 0) + { + if (sip->header(h_RequestLine).method() != OPTIONS) + { + std::auto_ptr<SipMessage> response(Helper::makeResponse(*sip, 483)); + mStack.send(*response, this); + } + else // If the request is an OPTIONS, send an appropriate response + { + std::auto_ptr<SipMessage> response(Helper::makeResponse(*sip, 200)); + mStack.send(*response, this); + } + // in either case get rid of the request and process the next one + delete sip; + continue; + } + + if(!sip->empty(h_ProxyRequires)) + { + std::auto_ptr<SipMessage> response(0); + + for(Tokens::iterator i=sip->header(h_ProxyRequires).begin(); + i!=sip->header(h_ProxyRequires).end(); + ++i) + { + if(!i->isWellFormed() || + !mSupportedOptions.count(i->value()) ) + { + if(!response.get()) + { + response.reset(Helper::makeResponse(*sip, 420, "Bad extension")); + } + response->header(h_Unsupporteds).push_back(*i); + } + } + + if(response.get()) + { + mStack.send(*response, this); + delete sip; + continue; + } + } + + + if (sip->method() == CANCEL) + { + HashMap<Data,RequestContext*>::iterator i = mServerRequestContexts.find(tid); + + if(i == mServerRequestContexts.end()) + { + SipMessage response; + Helper::makeResponse(response,*sip,481); + mStack.send(response,this); + delete sip; + } + else + { + try + { + i->second->process(std::auto_ptr<resip::SipMessage>(sip)); + } + catch(resip::BaseException& e) + { + // .bwc. Some sort of unhandled error in process. + // This is very bad; we cannot form a response + // at this point because we do not know + // whether the original request still exists. + ErrLog(<<"Uncaught exception in process on a CANCEL " + "request: " << e); + mStack.abandonServerTransaction(tid); + } + } + } + else if (sip->method() == ACK) + { + // .bwc. This is going to be treated as a new transaction. + // The stack is maintaining no state whatsoever for this. + // We should treat this exactly like a new transaction. + if(sip->mIsBadAck200) + { + static Data ack("ack"); + tid+=ack; + } + + RequestContext* context=0; + + HashMap<Data,RequestContext*>::iterator i = mServerRequestContexts.find(tid); + + // .bwc. This might be an ACK/200, or a stray ACK/failure + if(i == mServerRequestContexts.end()) + { + context = mRequestContextFactory->createRequestContext(*this, + mRequestProcessorChain, + mResponseProcessorChain, + mTargetProcessorChain); + mServerRequestContexts[tid] = context; + } + else // .bwc. ACK/failure + { + context = i->second; + } + + // The stack will send TransactionTerminated messages for + // client and server transaction which will clean up this + // RequestContext + try + { + context->process(std::auto_ptr<resip::SipMessage>(sip)); + } + catch(resip::BaseException& e) + { + // .bwc. Some sort of unhandled error in process. + ErrLog(<<"Uncaught exception in process on an ACK " + "request: " << e); + } + } + else + { + // This is a new request, so create a Request Context for it + InfoLog (<< "New RequestContext tid=" << tid << " : " << sip->brief()); + + + if(mServerRequestContexts.count(tid) == 0) + { + RequestContext* context = mRequestContextFactory->createRequestContext(*this, + mRequestProcessorChain, + mResponseProcessorChain, + mTargetProcessorChain); + InfoLog (<< "Inserting new RequestContext tid=" << tid + << " -> " << *context); + mServerRequestContexts[tid] = context; + //DebugLog (<< "RequestContexts: " << InserterP(mServerRequestContexts)); For a busy proxy - this generates a HUGE log statement! + try + { + context->process(std::auto_ptr<resip::SipMessage>(sip)); + } + catch(resip::BaseException& e) + { + // .bwc. Some sort of unhandled error in process. + // This is very bad; we cannot form a response + // at this point because we do not know + // whether the original request still exists. + ErrLog(<<"Uncaught exception in process on a new " + "request: " << e); + mStack.abandonServerTransaction(tid); + } + } + else + { + InfoLog(<<"Got a new non-ACK request " + "with an already existing transaction ID. This can " + "happen if a new request collides with a previously " + "received ACK/200."); + SipMessage response; + Helper::makeResponse(response,*sip,400,"Transaction-id " + "collision"); + mStack.send(response,this); + delete sip; + } + } + } + else if (sip->isResponse()) + { + InfoLog (<< "Looking up RequestContext tid=" << tid); + + // TODO is there a problem with a stray 200? + HashMap<Data,RequestContext*>::iterator i = mClientRequestContexts.find(tid); + if (i != mClientRequestContexts.end()) + { + try + { + i->second->process(std::auto_ptr<resip::SipMessage>(sip)); + } + catch(resip::BaseException& e) + { + // .bwc. Some sort of unhandled error in process. + ErrLog(<<"Uncaught exception in process on a response: " << e); + } + } + else + { + // throw away stray responses + InfoLog (<< "Unmatched response (stray?) : " << endl << *msg); + delete sip; + } + } + } + else if (app) + { + Data tid(app->getTransactionId()); + tid.lowercase(); + DebugLog(<< "Trying to dispatch : " << *app ); + HashMap<Data,RequestContext*>::iterator i=mServerRequestContexts.find(tid); + // the underlying RequestContext may not exist + if (i != mServerRequestContexts.end()) + { + DebugLog(<< "Sending " << *app << " to " << *(i->second)); + // This goes in as a Message and not an ApplicationMessage + // so that we have one peice of code doing dispatch to Monkeys + // (the intent is that Monkeys may eventually handle non-SIP + // application messages). + bool eraseThisTid = (dynamic_cast<Ack200DoneMessage*>(app)!=0); + try + { + i->second->process(std::auto_ptr<resip::ApplicationMessage>(app)); + } + catch(resip::BaseException& e) + { + ErrLog(<<"Uncaught exception in process: " << e); + } + + if (eraseThisTid) + { + mServerRequestContexts.erase(i); + } + } + else + { + InfoLog (<< "No matching request context...ignoring " << *app); + delete app; + } + } + else if (term) + { + Data tid(term->getTransactionId()); + tid.lowercase(); + if (term->isClientTransaction()) + { + HashMap<Data,RequestContext*>::iterator i=mClientRequestContexts.find(tid); + if (i != mClientRequestContexts.end()) + { + try + { + i->second->process(*term); + } + catch(resip::BaseException& e) + { + ErrLog(<<"Uncaught exception in process: " << e); + } + mClientRequestContexts.erase(i); + } + else + { + InfoLog (<< "No matching request context...ignoring " << *term); + } + } + else + { + HashMap<Data,RequestContext*>::iterator i=mServerRequestContexts.find(tid); + if (i != mServerRequestContexts.end()) + { + try + { + i->second->process(*term); + } + catch(resip::BaseException& e) + { + ErrLog(<<"Uncaught exception in process: " << e); + } + mServerRequestContexts.erase(i); + } + else + { + InfoLog (<< "No matching request context...ignoring " << *term); + } + } + delete term; + } + } + } + catch (BaseException& e) + { + ErrLog (<< "Caught: " << e); + } + catch (...) + { + ErrLog (<< "Caught unknown exception"); + } + } + InfoLog (<< "Proxy::thread exit"); +} + +void +Proxy::send(const SipMessage& msg) +{ + mStack.send(msg, this); +} + +void +Proxy::addClientTransaction(const Data& transactionId, RequestContext* rc) +{ + if(mClientRequestContexts.count(transactionId) == 0) + { + InfoLog (<< "add client transaction tid=" << transactionId << " " << rc); + mClientRequestContexts[transactionId] = rc; + } + else + { + ErrLog(<< "Received a client request context whose transaction id matches that of an existing request context. Ignoring."); + } +} + +void +Proxy::postTimerC(std::auto_ptr<TimerCMessage> tc) +{ + if(mTimerC > 0) + { + InfoLog(<<"Posting timer C"); + mStack.post(*tc,mTimerC,this); + } +} + + +void +Proxy::postMS(std::auto_ptr<resip::ApplicationMessage> msg, int msec) +{ + mStack.postMS(*msg,msec,this); +} + + +const Data& +Proxy::name() const +{ + static Data n("Proxy"); + return n; +} + +bool +Proxy::isMyUri(const Uri& uri) const +{ + bool ret = mStack.isMyDomain(uri.host(), uri.port()); + if(!ret) + { + ret = isMyDomain(uri.host()); + + if(ret) + { + // check if we are listening on the specified port + // .slg. this is not perfect, but it will allow us to operate in most environments + // where the repro proxy and a UA are running on the same machine. + // Note: There is a scenario that we cannot correctly handle - when a UA and + // repro are running on the same machine, and they are using the same port but on + // different transports types or interfaces. In this case we cannot tell, by looking + // at a requestUri or From header if the uri is ours or the UA's, and things will break. + if(uri.port() != 0) + { + ret = mStack.isMyPort(uri.port()); + } + } + } + DebugLog( << "Proxy::isMyUri " << uri << " " << ret); + return ret; +} + +const resip::NameAddr& +Proxy::getRecordRoute(const Transport* transport) const +{ + assert(transport); + if(transport->hasRecordRoute()) + { + // Transport specific record-route found + return transport->getRecordRoute(); + } + return mRecordRoute; +} + +bool +Proxy::getRecordRouteForced() const +{ + return mRecordRouteForced; +} + +bool +Proxy::compressionEnabled() const +{ + return mStack.getCompression().getAlgorithm() != resip::Compression::NONE; +} + +void +Proxy::addSupportedOption(const resip::Data& option) +{ + mSupportedOptions.insert(option); +} + +void +Proxy::removeSupportedOption(const resip::Data& option) +{ + mSupportedOptions.erase(option); +} + +void +Proxy::doSessionAccounting(const resip::SipMessage& sip, bool received, RequestContext& context) +{ + if(mSessionAccountingEnabled) + { + assert(mAccountingCollector); + mAccountingCollector->doSessionAccounting(sip, received, context); + } +} + +void +Proxy::doRegistrationAccounting(AccountingCollector::RegistrationEvent regEvent, const resip::SipMessage& sip) +{ + if(mRegistrationAccountingEnabled) + { + assert(mAccountingCollector); + mAccountingCollector->doRegistrationAccounting(regEvent, sip); + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/Proxy.hxx b/src/libs/resiprocate/repro/Proxy.hxx new file mode 100644 index 00000000..3831553c --- /dev/null +++ b/src/libs/resiprocate/repro/Proxy.hxx @@ -0,0 +1,197 @@ +#if !defined(RESIP_PROXY_HXX) +#define RESIP_PROXY_HXX + +#include <memory> + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/TransactionUser.hxx" +#include "rutil/HashMap.hxx" +#include "rutil/ThreadIf.hxx" +#include "rutil/KeyValueStore.hxx" +#include "repro/AccountingCollector.hxx" +#include "repro/RequestContext.hxx" +#include "repro/TimerCMessage.hxx" +#include "repro/ProxyConfig.hxx" + +namespace resip +{ +class SipStack; +class Transport; +} + +namespace repro +{ + +class UserStore; +class ProcessorChain; + +class OptionsHandler +{ +public: + OptionsHandler() {} + virtual ~OptionsHandler() {} + + // return true if handled and response should be sent, false to route normally through proxy + virtual bool onOptionsRequest(const resip::SipMessage& request, resip::SipMessage& response) = 0; +}; + +class RequestContextFactory +{ + public: + virtual RequestContext* createRequestContext(Proxy& proxy, + ProcessorChain& requestP, // monkeys + ProcessorChain& responseP, // lemurs + ProcessorChain& targetP); // baboons + virtual ~RequestContextFactory() {} +}; + +class Proxy : public resip::TransactionUser, public resip::ThreadIf +{ + public: + Proxy(resip::SipStack&, + ProxyConfig& config, + ProcessorChain& requestP, + ProcessorChain& responseP, + ProcessorChain& targetP); + virtual ~Proxy(); + + // Crypto Random Key for Salting Flow Token HMACs + static resip::Data FlowTokenSalt; + static resip::KeyValueStore::KeyValueStoreKeyAllocator* getGlobalKeyValueStoreKeyAllocator(); + static resip::KeyValueStore::KeyValueStoreKeyAllocator* getRequestKeyValueStoreKeyAllocator(); + static resip::KeyValueStore::KeyValueStoreKeyAllocator* getTargetKeyValueStoreKeyAllocator(); + static resip::KeyValueStore::Key allocateGlobalKeyValueStoreKey(); // should only be called at static initialization time + static resip::KeyValueStore::Key allocateRequestKeyValueStoreKey(); // should only be called at static initialization time + static resip::KeyValueStore::Key allocateTargetKeyValueStoreKey(); // should only be called at static initialization time + + // Note: These are not thread safe and should be called before run() only + void setOptionsHandler(OptionsHandler* handler); + void setRequestContextFactory(std::auto_ptr<RequestContextFactory> requestContextFactory); + + virtual bool isShutDown() const ; + virtual void thread(); + + bool isMyUri(const resip::Uri& uri) const; + const resip::NameAddr& getRecordRoute(const resip::Transport* transport) const; + bool getRecordRouteForced() const; + + void setAssumePath(bool f) { mAssumePath = f; } + bool getAssumePath() const { return mAssumePath; } + + bool isPAssertedIdentityProcessingEnabled() { return mPAssertedIdentityProcessing; } + + UserStore& getUserStore(); + resip::SipStack& getStack(){return mStack;} + ProxyConfig& getConfig(){return mConfig;} + void send(const resip::SipMessage& msg); + void addClientTransaction(const resip::Data& transactionId, RequestContext* rc); + + void postTimerC(std::auto_ptr<TimerCMessage> tc); + + void postMS(std::auto_ptr<resip::ApplicationMessage> msg, int msec); + + bool compressionEnabled() const; + + void addSupportedOption(const resip::Data& option); + void removeSupportedOption(const resip::Data& option); + + void setServerText(const resip::Data& text) { mServerText = text; } + const resip::Data& getServerText() const { return mServerText; } + + // Accessor for global extensible state storage for monkeys + resip::KeyValueStore& getKeyValueStore() { return mKeyValueStore; } + + void doSessionAccounting(const resip::SipMessage& sip, bool received, RequestContext& context); + void doRegistrationAccounting(repro::AccountingCollector::RegistrationEvent regEvent, const resip::SipMessage& sip); + + protected: + virtual const resip::Data& name() const; + + private: + resip::SipStack& mStack; + ProxyConfig& mConfig; + resip::NameAddr mRecordRoute; + bool mRecordRouteForced; + bool mAssumePath; + bool mPAssertedIdentityProcessing; + resip::Data mServerText; + int mTimerC; + resip::KeyValueStore mKeyValueStore; + + // needs to be a reference since parent owns it + ProcessorChain& mRequestProcessorChain; + ProcessorChain& mResponseProcessorChain; + ProcessorChain& mTargetProcessorChain; + + /** a map from transaction id to RequestContext. Store the server + transaction and client transactions in this map. The + TransactionTerminated events from the stack will be passed to the + RequestContext + */ + HashMap<resip::Data, RequestContext*> mClientRequestContexts; + HashMap<resip::Data, RequestContext*> mServerRequestContexts; + + UserStore &mUserStore; + std::set<resip::Data> mSupportedOptions; + OptionsHandler* mOptionsHandler; + std::auto_ptr<RequestContextFactory> mRequestContextFactory; + + bool mSessionAccountingEnabled; + bool mRegistrationAccountingEnabled; + AccountingCollector* mAccountingCollector; + + // disabled + Proxy(); +}; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/ProxyConfig.cxx b/src/libs/resiprocate/repro/ProxyConfig.cxx new file mode 100644 index 00000000..d8a56844 --- /dev/null +++ b/src/libs/resiprocate/repro/ProxyConfig.cxx @@ -0,0 +1,151 @@ +#include "ProxyConfig.hxx" + +#include <iostream> +#include <fstream> +#include <iterator> + +//#include <rutil/DnsUtil.hxx> +#include <resip/stack/NameAddr.hxx> +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/WinLeakCheck.hxx> + +using namespace repro; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +namespace repro +{ + +ProxyConfig::ProxyConfig() : mStore(0) +{ +} + +ProxyConfig::~ProxyConfig() +{ + delete mStore; + mStore=0; +} + +bool +ProxyConfig::getConfigValue(const resip::Data& name, resip::Uri &value) +{ + Data lowerName(name); lowerName.lowercase(); + ConfigValuesMap::iterator it = mConfigValues.find(lowerName); + if(it != mConfigValues.end()) + { + try + { + if(!it->second.empty()) + { + NameAddr tempNameAddr(it->second); + value = tempNameAddr.uri(); + return true; + } + else + { + value = Uri(); // return an empty Uri + return true; + } + } + catch(resip::BaseException& e) + { + // Try adding sip: to value to see if it will be valid + try + { + NameAddr tempNameAddr(Data("sip:" + it->second)); + value = tempNameAddr.uri(); + return true; + } + catch(resip::BaseException&) + { + cerr << "Invalid Uri setting: " << name << " = " << it->second << ": " << e << endl; + return false; + } + } + } + // Not found + return false; +} + +resip::Uri +ProxyConfig::getConfigUri(const resip::Data& name, const resip::Uri defaultValue, bool useDefaultIfEmpty) +{ + Uri ret(defaultValue); + if(getConfigValue(name, ret) && ret.host().empty() && useDefaultIfEmpty) + { + return defaultValue; + } + return ret; +} + +void +ProxyConfig::printHelpText(int argc, char **argv) +{ + cout << "Command line format is:" << endl; + cout << " " << removePath(argv[0]) << " [<ConfigFilename>] [--<ConfigValueName>=<ConfigValue>] [--<ConfigValueName>=<ConfigValue>] ..." << endl; + cout << "Sample Command lines:" << endl; + cout << " " << removePath(argv[0]) << " repro.config --RecordRouteUri=sip:proxy.sipdomain.com --ForceRecordRouting=true" << endl; + cout << " " << removePath(argv[0]) << " repro.config /RecordRouteUri:sip:proxy.sipdomain.com /ForceRecordRouting:true" << endl; +} + +void +ProxyConfig::createDataStore(AbstractDb* db, AbstractDb* runtimedb) +{ + assert(db); + mStore = new Store(*db, runtimedb); +} + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/ProxyConfig.hxx b/src/libs/resiprocate/repro/ProxyConfig.hxx new file mode 100644 index 00000000..8ba484ba --- /dev/null +++ b/src/libs/resiprocate/repro/ProxyConfig.hxx @@ -0,0 +1,86 @@ +#if !defined(ProxyConfig_hxx) +#define ProxyConfig_hxx + +#include <map> +#include "repro/Store.hxx" +#include <resip/stack/Uri.hxx> +#include <rutil/ConfigParse.hxx> +#include <rutil/Data.hxx> + +namespace repro +{ + +class ProxyConfig : public resip::ConfigParse +{ +public: + ProxyConfig(); + virtual ~ProxyConfig(); + + virtual void printHelpText(int argc, char **argv); + + void createDataStore(AbstractDb* db, AbstractDb* runtimedb=0); + Store* getDataStore() { return mStore; } + + using resip::ConfigParse::getConfigValue; + bool getConfigValue(const resip::Data& name, resip::Uri &value); + resip::Uri getConfigUri(const resip::Data& name, const resip::Uri defaultValue, bool useDefaultIfEmpty=false); + +protected: + + // Database Store + Store* mStore; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/QValueTarget.cxx b/src/libs/resiprocate/repro/QValueTarget.cxx new file mode 100644 index 00000000..72c816f2 --- /dev/null +++ b/src/libs/resiprocate/repro/QValueTarget.cxx @@ -0,0 +1,103 @@ +#include "repro/QValueTarget.hxx" +#include "rutil/WinLeakCheck.hxx" + + +namespace repro +{ + +static int DefaultPriorityMetric = 1000; // If no q-value is present, when we treat the target as having a 1.0 priority + +QValueTarget::QValueTarget(const resip::Uri& target) : + Target(target) +{ + // Note: no neeed to call storePriorityMetric(), since q value parameter + // is a NameAddr parameter and all we have here is a URI +} + +QValueTarget::QValueTarget(const resip::NameAddr& target) : + Target(target) +{ + storePriorityMetric(); +} + +QValueTarget::QValueTarget(const resip::ContactInstanceRecord& rec) : + Target(rec) +{ + storePriorityMetric(); +} + +QValueTarget::~QValueTarget() +{ +} + +QValueTarget* +QValueTarget::clone() const +{ + return new QValueTarget(*this); +} + +void +QValueTarget::storePriorityMetric() +{ + if(mRec.mContact.exists(resip::p_q)) + { + try + { + mPriorityMetric=mRec.mContact.param(resip::p_q); + } + catch(resip::ParseBuffer::Exception& /*e*/) + { + mPriorityMetric=DefaultPriorityMetric; + } + } + else + { + mPriorityMetric=DefaultPriorityMetric; + } +} + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/QValueTarget.hxx b/src/libs/resiprocate/repro/QValueTarget.hxx new file mode 100644 index 00000000..aed82e31 --- /dev/null +++ b/src/libs/resiprocate/repro/QValueTarget.hxx @@ -0,0 +1,71 @@ +#ifndef Q_VALUE_TARGET_HXX +#define Q_VALUE_TARGET_HXX 1 + +#include "repro/Target.hxx" + +#include "resip/stack/Uri.hxx" +#include "resip/stack/NameAddr.hxx" + +namespace repro +{ + +class QValueTarget : public Target +{ + public: + QValueTarget(const resip::Uri& target); + QValueTarget(const resip::NameAddr& target); + QValueTarget(const resip::ContactInstanceRecord& rec); + + virtual ~QValueTarget(); + + virtual QValueTarget* clone() const; + + private: + void storePriorityMetric(); +}; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/README.LOGGING b/src/libs/resiprocate/repro/README.LOGGING new file mode 100644 index 00000000..8b9a1e6e --- /dev/null +++ b/src/libs/resiprocate/repro/README.LOGGING @@ -0,0 +1,5 @@ +#include "resiprocate/os/Logger.hxx" +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +// DebugLog (<< "this is a DEBUG log " << a); +// InfoLog (<< "this is an INFO log " << complexObj); diff --git a/src/libs/resiprocate/repro/README_MySQL.txt b/src/libs/resiprocate/repro/README_MySQL.txt new file mode 100644 index 00000000..e5690e1a --- /dev/null +++ b/src/libs/resiprocate/repro/README_MySQL.txt @@ -0,0 +1,67 @@ +To create the repro MySQL database tables, run the create_mysql_reprodb.sql script +against your MySQL server instance, by using one of the following two commands: + +Option 1 +======== +mysql -u root -p < create_mysql_reprodb.sql + +It will prompt for root password, alternatively you can use a different user if has "create" privileges. + + +Option 2 +======== +Login to mysql using root or a user which has 'create' privileges, then at mysql prompt run: + +mysql>source create_mysql_reprodb.sql + + + +Other Potentially Useful Commands +================================= + +Start DB +sudo /sw/bin/mysqld_safe & + +Remove REPRO DB with +mysqladmin -u root -p DROP repro + +Create a user called repro that can use the DB +mysql -u root -p -e "GRANT ALL PRIVILEGES ON *.* TO root@localhost WITH GRANT OPTION" +mysql -u root -p -e "GRANT ALL PRIVILEGES ON repro.* TO repro@localhost" +mysql -u root -p -e "FLUSH PRIVILEGES" + +you can view permissions with +mysqlaccess -U root -P <pwd> \* \* repro --brief + +Can make sure all is flushed with +mysqladmin -u root -p refresh + + +passwordHashAlt +=============== + +The schema contains a passwordHashAlt column + +This is much the same as the ha1b column used by Kamailio + + passwordHash = h(A1) = md5(user:realm:password) + + passwordHashAlt = h(A1) = md5(user@domain:realm:password) + +repro will update the value in this column each time a user is added +or their password is changed. However, it is not currently consulted +as part of the authentication process. + +To explicitly use this column instead of the regular passwordHash +column, use this custom auth query: + +MySQLCustomUserAuthQuery = \ + SELECT passwordHashAlt + FROM users + WHERE user = '$user' + AND concat(domain, '@', domain) = '$domain' + +A future version of repro will be able to use both columns during +the authentication process, to concurrently support UAs using +either authentication style. + diff --git a/src/libs/resiprocate/repro/RRDecorator.cxx b/src/libs/resiprocate/repro/RRDecorator.cxx new file mode 100644 index 00000000..e7142abb --- /dev/null +++ b/src/libs/resiprocate/repro/RRDecorator.cxx @@ -0,0 +1,268 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "repro/RRDecorator.hxx" + +#include "repro/Proxy.hxx" + +#include "resip/stack/ExtensionParameter.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/InteropHelper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Tuple.hxx" +#include "resip/stack/Transport.hxx" + +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using resip::ExtensionParameter; +using resip::NameAddr; +using resip::UDP; +using resip::h_RecordRoutes; +using resip::h_Paths; +using resip::h_RequestLine; +using resip::h_Routes; +using resip::p_comp; + +namespace repro +{ +RRDecorator::RRDecorator(const Proxy& proxy, + const resip::Transport* receivedTransport, + bool alreadySingleRecordRouted, + bool hasInboundFlowToken, + bool forceRecordRouteEnabled, + bool doPath, + bool isOriginalSenderBehindNAT) : + mProxy(proxy), + mAddedRecordRoute(0), + mAlreadySingleRecordRouted(alreadySingleRecordRouted), + mHasInboundFlowToken(hasInboundFlowToken), + mForceRecordRouteEnabled(forceRecordRouteEnabled), + mDoPath(doPath), + mIsOriginalSenderBehindNAT(isOriginalSenderBehindNAT), + mReceivedTransport(receivedTransport) +{} + +RRDecorator::~RRDecorator() +{} + +void +RRDecorator::decorateMessage(resip::SipMessage& request, + const resip::Tuple &source, + const resip::Tuple &destination, + const resip::Data& sigcompId) +{ + DebugLog(<<"Proxy::decorateMessage called."); + resip::NameAddr rt; + + if(isTransportSwitch(source)) + { + if(mAlreadySingleRecordRouted) + { + singleRecordRoute(request, source, destination, sigcompId); + } + else + { + doubleRecordRoute(request, source, destination, sigcompId); + } + } + else + { + // We might still want to record-route in this case; if we need an + // outbound flow token or we've already added an inbound flow token + if(outboundFlowTokenNeeded(request, source, destination, sigcompId) || + mHasInboundFlowToken) // or we have an inbound flow + { + assert(mAlreadySingleRecordRouted); + singleRecordRoute(request, source, destination, sigcompId); + } + } + + static ExtensionParameter p_drr("drr"); + resip::NameAddrs* routes=0; + if(mDoPath) + { + routes=&(request.header(resip::h_Paths)); + } + else + { + routes=&(request.header(resip::h_RecordRoutes)); + } + + if(routes->size() > 1 && + mAddedRecordRoute && + routes->front().uri().exists(p_drr)) + { + // .bwc. It is possible that we have duplicate Record-Routes at this + // point, if we have done a transport switch but both transports use the + // same FQDN. + resip::NameAddrs::iterator second = ++(routes->begin()); + if(*second == routes->front()) + { + // Duplicated record-routes; pare down to a single one. + routes->pop_front(); + --mAddedRecordRoute; + routes->front().uri().remove(p_drr); + } + } +} + +void +RRDecorator::singleRecordRoute(resip::SipMessage& request, + const resip::Tuple &source, + const resip::Tuple &destination, + const resip::Data& sigcompId) +{ + resip::NameAddr rt; + // .bwc. outboundFlowTokenNeeded means that we are assuming that whoever is + // just downstream will remain in the call-path throughout the dialog. + if(outboundFlowTokenNeeded(request, source, destination, sigcompId)) + { + if(destination.getType()==resip::TLS || + destination.getType()==resip::DTLS) + { + rt = mProxy.getRecordRoute(destination.transport); + rt.uri().scheme()="sips"; + } + else + { + // .bwc. It is safe to put ip+port+proto here, since we have an + // existing flow to the next hop. + rt.uri().host()=resip::Tuple::inet_ntop(source); + rt.uri().port()=source.getPort(); + rt.uri().param(resip::p_transport)=resip::Tuple::toDataLower(source.getType()); + } + // .bwc. If our target has an outbound flow to us, we need to put a flow + // token in a Record-Route. + resip::Helper::massageRoute(request,rt); + resip::Data binaryFlowToken; + resip::Tuple::writeBinaryToken(destination,binaryFlowToken, Proxy::FlowTokenSalt); + + rt.uri().user()=binaryFlowToken.base64encode(); + } + else + { + // No need for a flow-token; just use an ordinary record-route. + rt = mProxy.getRecordRoute(destination.transport); + resip::Helper::massageRoute(request,rt); + } + +#ifdef USE_SIGCOMP + if(mProxy.compressionEnabled() && !sigcompId.empty()) + { + rt.uri().param(p_comp)="sigcomp"; + } +#endif + + static ExtensionParameter p_drr("drr"); + rt.uri().param(p_drr); + + resip::NameAddrs* routes=0; + if(mDoPath) + { + routes=&(request.header(resip::h_Paths)); + InfoLog(<< "Adding outbound Path: " << rt); + } + else + { + routes=&(request.header(resip::h_RecordRoutes)); + InfoLog(<< "Adding outbound Record-Route: " << rt); + } + + routes->front().uri().param(p_drr); + routes->push_front(rt); + ++mAddedRecordRoute; +} + +void +RRDecorator::doubleRecordRoute(resip::SipMessage& request, + const resip::Tuple &source, + const resip::Tuple &destination, + const resip::Data& sigcompId) +{ + // We only use this on transport switch when we have not yet Record-Routed. + // If we needed a flow-token in the inbound Record-Route, it would have been + // added already. + resip::NameAddr rt(mProxy.getRecordRoute(mReceivedTransport)); + resip::Helper::massageRoute(request,rt); + if(mDoPath) + { + request.header(h_Paths).push_front(rt); + } + else + { + request.header(h_RecordRoutes).push_front(rt); + } + ++mAddedRecordRoute; + singleRecordRoute(request, source, destination, sigcompId); +} + +bool +RRDecorator::isTransportSwitch(const resip::Tuple& sendingFrom) +{ + if(mForceRecordRouteEnabled) + { + // If we are forcing record routes to be added, then DRR on any transport switch + return mReceivedTransport != sendingFrom.transport; + } + else + { + // If record routing is not forced then only DRR if we are switching transport types or + // protocol versions, since the interfaces themselves may all be equally reachable + // !slg! - could make this behavior more configurable + return sendingFrom.getType() != mReceivedTransport->getTuple().getType() || + sendingFrom.ipVersion() != mReceivedTransport->getTuple().ipVersion(); + } +} + +bool +RRDecorator::outboundFlowTokenNeeded(resip::SipMessage &msg, + const resip::Tuple &source, + const resip::Tuple &destination, + const resip::Data& sigcompId) +{ + return (destination.onlyUseExistingConnection // destination is an outbound target + || resip::InteropHelper::getRRTokenHackEnabled() // or the token is enabled + || mIsOriginalSenderBehindNAT // or the nat detection hack is enabled + || !sigcompId.empty()); // or we are routing to a SigComp transport + // ?slg? For Sigcomp are we guaranteed to always have + // single RR at this point? If not, then strangeness + // will happen when singleRecordRoute adds a ;drr param +} + +void +RRDecorator::rollbackMessage(resip::SipMessage& request) +{ + resip::NameAddrs* routes=0; + if(mDoPath) + { + routes=&(request.header(resip::h_Paths)); + } + else + { + routes=&(request.header(resip::h_RecordRoutes)); + } + + while(mAddedRecordRoute--) + { + assert(!routes->empty()); + routes->pop_front(); + } + + if(mAlreadySingleRecordRouted) + { + // Make sure we remove the drr param if it is there. + static ExtensionParameter p_drr("drr"); + routes->front().uri().remove(p_drr); + } +} + +resip::MessageDecorator* +RRDecorator::clone() const +{ + return new RRDecorator(*this); +} + +} // of namespace repro diff --git a/src/libs/resiprocate/repro/RRDecorator.hxx b/src/libs/resiprocate/repro/RRDecorator.hxx new file mode 100644 index 00000000..6368158a --- /dev/null +++ b/src/libs/resiprocate/repro/RRDecorator.hxx @@ -0,0 +1,67 @@ +#ifndef RRDecorator_Include_Guard +#define RRDecorator_Include_Guard + +#include "resip/stack/MessageDecorator.hxx" +#include "resip/stack/Tuple.hxx" + + +namespace resip +{ +class Transport; +} + +namespace repro +{ +class Proxy; + +class RRDecorator : public resip::MessageDecorator +{ + public: + RRDecorator(const Proxy& proxy, + const resip::Transport* receivedTransport, + bool alreadySingleRecordRouted, + bool hasInboundFlowToken, + bool forceRecordRouteEnabled, + bool doPath=false, + bool isOriginalSenderBehindNAT=false); + virtual ~RRDecorator(); + +/////////////////// Must implement unless abstract /// + + virtual void decorateMessage(resip::SipMessage &msg, + const resip::Tuple &source, + const resip::Tuple &destination, + const resip::Data& sigcompId) ; + virtual void rollbackMessage(resip::SipMessage& msg) ; + virtual MessageDecorator* clone() const ; + + private: + void singleRecordRoute(resip::SipMessage &msg, + const resip::Tuple &source, + const resip::Tuple &destination, + const resip::Data& sigcompId); + void doubleRecordRoute(resip::SipMessage &msg, + const resip::Tuple &source, + const resip::Tuple &destination, + const resip::Data& sigcompId); + bool isTransportSwitch(const resip::Tuple& sendingFrom); + bool outboundFlowTokenNeeded(resip::SipMessage &msg, + const resip::Tuple &source, + const resip::Tuple &destination, + const resip::Data& sigcompId); + const Proxy& mProxy; + int mAddedRecordRoute; + bool mAlreadySingleRecordRouted; + bool mHasInboundFlowToken; + bool mForceRecordRouteEnabled; + bool mDoPath; + const bool mIsOriginalSenderBehindNAT; + const resip::Transport* mReceivedTransport; + + //disabled + RRDecorator(); +}; // class RRDecorator + +} // namespace resip + +#endif // include guard diff --git a/src/libs/resiprocate/repro/RegSyncClient.cxx b/src/libs/resiprocate/repro/RegSyncClient.cxx new file mode 100644 index 00000000..2b9e7a61 --- /dev/null +++ b/src/libs/resiprocate/repro/RegSyncClient.cxx @@ -0,0 +1,445 @@ +#include <cassert> +#include <sstream> + +#include <resip/stack/Symbols.hxx> +#include <resip/stack/Tuple.hxx> +#include <rutil/Data.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/Logger.hxx> +#include <rutil/ParseBuffer.hxx> +#include <rutil/Socket.hxx> +#include <rutil/TransportType.hxx> +#include <rutil/Timer.hxx> + +#include "repro/RegSyncClient.hxx" +#include "repro/RegSyncServer.hxx" + +using namespace repro; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +RegSyncClient::RegSyncClient(InMemorySyncRegDb* regDb, + Data address, + unsigned short port) : + mRegDb(regDb), + mAddress(address), + mPort(port), + mSocketDesc(0) +{ + assert(mRegDb); +} + +void +RegSyncClient::delaySeconds(unsigned int seconds) +{ + // Delay for requested number of seconds - but check every second if we are shutdown or not + for(unsigned int i = 0; i < seconds && !mShutdown; i++) + { +#ifdef WIN32 + Sleep(1000); +#else + sleep(1); +#endif + } +} + +void +RegSyncClient::shutdown() +{ + ThreadIf::shutdown(); + if(mSocketDesc) + { +#ifdef WIN32 + closesocket(mSocketDesc); + mSocketDesc = 0; +#else + ::shutdown(mSocketDesc, SHUT_RDWR); +#endif + } +} + +void +RegSyncClient::thread() +{ + int rc; + + addrinfo* results; + addrinfo hint; + memset(&hint, 0, sizeof(hint)); + hint.ai_family = AF_UNSPEC; + hint.ai_flags = AI_PASSIVE; + hint.ai_socktype = SOCK_STREAM; + + rc = getaddrinfo(mAddress.c_str(), 0, &hint, &results); + if(rc != 0) + { + ErrLog(<< "RegSyncClient: unknown host " << mAddress); + return; + } + + // Use first address resolved if there are more than one. + Tuple servAddr(*results->ai_addr, TCP); + servAddr.setPort(mPort); + Tuple localAddr(Data::Empty /* all interfaces */, 0, servAddr.ipVersion(), TCP); + //InfoLog(<< "**********" << servAddr << " " << localAddr << " " << localAddr.isAnyInterface()); + + freeaddrinfo(results); + + while(!mShutdown) + { + // Create TCP Socket + mSocketDesc = (int)socket(servAddr.ipVersion() == V6 ? PF_INET6 : PF_INET , SOCK_STREAM, 0); + if(mSocketDesc < 0) + { + ErrLog(<< "RegSyncClient: cannot open socket"); + mSocketDesc = 0; + return; + } + + // bind to any local interface/port + rc = ::bind(mSocketDesc, &localAddr.getMutableSockaddr(), localAddr.length()); + if(rc < 0) + { + ErrLog(<<"RegSyncClient: error binding locally"); + closeSocket(mSocketDesc); + mSocketDesc = 0; + return; + } + + // Connect to server + rc = ::connect(mSocketDesc, &servAddr.getMutableSockaddr(), servAddr.length()); + if(rc < 0) + { + if(!mShutdown) ErrLog(<< "RegSyncClient: error connecting to " << mAddress << ":" << mPort); + closeSocket(mSocketDesc); + mSocketDesc = 0; + delaySeconds(30); + continue; + } + + Data request( + "<InitialSync>\r\n" + " <Request>\r\n" + " <Version>" + Data(REGSYNC_VERSION) + "</Version>\r\n" // For use in detecting if client/server are a compatible version + " </Request>\r\n" + "</InitialSync>\r\n"); + rc = ::send(mSocketDesc, request.c_str(), (int)request.size(), 0); + if(rc < 0) + { + if(!mShutdown) ErrLog(<< "RegSyncClient: error sending"); + closeSocket(mSocketDesc); + mSocketDesc = 0; + continue; + } + + while(rc > 0) + { + rc = ::recv(mSocketDesc, (char*)&mRxBuffer, sizeof(mRxBuffer), 0); + if(rc < 0) + { + if(!mShutdown) ErrLog(<< "RegSyncClient: error receiving"); + closeSocket(mSocketDesc); + mSocketDesc = 0; + break; + } + + if(rc > 0) + { + mRxDataBuffer += Data(Data::Borrow, (const char*)&mRxBuffer, rc); + while(tryParse()); + } + } + } // end while + + if(mSocketDesc) closeSocket(mSocketDesc); +} + +bool +RegSyncClient::tryParse() +{ + ParseBuffer pb(mRxDataBuffer); + Data initialTag; + const char* start = pb.position(); + pb.skipWhitespace(); + pb.skipToChar('<'); + if(!pb.eof()) + { + pb.skipChar(); + const char* anchor = pb.position(); + pb.skipToChar('>'); + if(!pb.eof()) + { + initialTag = pb.data(anchor); + // Find end of initial tag + pb.skipToChars("</" + initialTag + ">"); + if (!pb.eof()) + { + pb.skipN((int)initialTag.size() + 3); // Skip past </InitialTag> + handleXml(pb.data(start)); + + // Remove processed data from RxBuffer + pb.skipWhitespace(); + if(!pb.eof()) + { + anchor = pb.position(); + pb.skipToEnd(); + mRxDataBuffer = pb.data(anchor); + return true; + } + else + { + mRxDataBuffer.clear(); + } + } + } + } + return false; +} + +void +RegSyncClient::handleXml(const Data& xmlData) +{ + //InfoLog(<< "RegSyncClient::handleXml received: " << xmlData); + + try + { + ParseBuffer pb(xmlData); + XMLCursor xml(pb); + + if(isEqualNoCase(xml.getTag(), "InitialSync")) + { + // Must be an InitialSync response + InfoLog(<< "RegSyncClient::handleXml: InitialSync complete."); + } + else if(isEqualNoCase(xml.getTag(), "reginfo")) + { + try + { + handleRegInfoEvent(xml); + } + catch(BaseException& e) + { + ErrLog(<< "RegSyncClient::handleXml: exception: " << e); + } + } + else + { + WarningLog(<< "RegSyncClient::handleXml: Ignoring XML message with unknown method: " << xml.getTag()); + } + } + catch(resip::BaseException& e) + { + WarningLog(<< "RegSyncClient::handleXml: Ignoring XML message due to ParseException: " << e); + } +} + +void +RegSyncClient::handleRegInfoEvent(resip::XMLCursor& xml) +{ + UInt64 now = Timer::getTimeSecs(); + Uri aor; + ContactList contacts; + DebugLog(<< "RegSyncClient::handleRegInfoEvent"); + if(xml.firstChild()) + { + do + { + if(isEqualNoCase(xml.getTag(), "aor")) + { + if(xml.firstChild()) + { + aor = Uri(xml.getValue().xmlCharDataDecode()); + xml.parent(); + } + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: aor=" << aor); + } + else if(isEqualNoCase(xml.getTag(), "contactinfo")) + { + if(xml.firstChild()) + { + ContactInstanceRecord rec; + do + { + if(isEqualNoCase(xml.getTag(), "contacturi")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: contacturi=" << xml.getValue()); + rec.mContact = NameAddr(xml.getValue().xmlCharDataDecode()); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "expires")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: expires=" << xml.getValue()); + UInt64 expires = xml.getValue().convertUInt64(); + rec.mRegExpires = (expires == 0 ? 0 : now+expires); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "lastupdate")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: lastupdate=" << xml.getValue()); + rec.mLastUpdated = now-xml.getValue().convertUInt64(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "receivedfrom")) + { + if(xml.firstChild()) + { + rec.mReceivedFrom = Tuple::makeTupleFromBinaryToken(xml.getValue().base64decode()); + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: receivedfrom=" << xml.getValue() << " tuple=" << rec.mReceivedFrom); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "publicaddress")) + { + if(xml.firstChild()) + { + rec.mPublicAddress = Tuple::makeTupleFromBinaryToken(xml.getValue().base64decode()); + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: publicaddress=" << xml.getValue() << " tuple=" << rec.mPublicAddress); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "sippath")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: sippath=" << xml.getValue()); + rec.mSipPath.push_back(NameAddr(xml.getValue().xmlCharDataDecode())); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "instance")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: instance=" << xml.getValue()); + rec.mInstance = xml.getValue().xmlCharDataDecode(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "regid")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: regid=" << xml.getValue()); + rec.mRegId = xml.getValue().convertUnsignedLong(); + xml.parent(); + } + } + } while(xml.nextSibling()); + xml.parent(); + + // Add record to list + rec.mSyncContact = true; // This ContactInstanceRecord came from registration sync process + contacts.push_back(rec); + } + } + } while(xml.nextSibling()); + xml.parent(); + } + xml.parent(); + + processModify(aor, contacts); +} + +void +RegSyncClient::processModify(const resip::Uri& aor, ContactList& syncContacts) +{ + ContactList currentContacts; + + mRegDb->lockRecord(aor); + mRegDb->getContacts(aor, currentContacts); + + InfoLog(<< "RegSyncClient::processModify: for aor=" << aor << + ", numSyncContacts=" << syncContacts.size() << + ", numCurrentContacts=" << currentContacts.size()); + + // Iteratate through new syncContact List + ContactList::iterator itSync = syncContacts.begin(); + ContactList::iterator itCurrent; + bool found; + for(; itSync != syncContacts.end(); itSync++) + { + // See if contact already exists in currentContacts + found = false; + for(itCurrent = currentContacts.begin(); itCurrent != currentContacts.end(); itCurrent++) + { + if(*itSync == *itCurrent) + { + found = true; + // We found a match - check if sycnContacts LastUpdated time is newer + if(itSync->mLastUpdated > itCurrent->mLastUpdated) + { + // Replace current contact with Sync contact + mRegDb->updateContact(aor, *itSync); + } + } + } + if(!found) + { + mRegDb->updateContact(aor, *itSync); + } + } + mRegDb->unlockRecord(aor); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/repro/RegSyncClient.hxx b/src/libs/resiprocate/repro/RegSyncClient.hxx new file mode 100644 index 00000000..4e0b086a --- /dev/null +++ b/src/libs/resiprocate/repro/RegSyncClient.hxx @@ -0,0 +1,91 @@ +#if !defined(RegSyncClient_hxx) +#define RegSyncClient_hxx + +#include <rutil/Data.hxx> +#include <rutil/XMLCursor.hxx> +#include <resip/dum/InMemorySyncRegDb.hxx> +#include <rutil/ThreadIf.hxx> + +namespace repro +{ + +class RegSyncClient : public resip::ThreadIf +{ +public: + RegSyncClient(resip::InMemorySyncRegDb* regDb, + resip::Data address, + unsigned short port); + + virtual void thread(); + virtual void shutdown(); + +private: + void delaySeconds(unsigned int seconds); + bool tryParse(); // returns true if we processed something and there is more data in the buffer + void handleXml(const resip::Data& xmlData); + void handleRegInfoEvent(resip::XMLCursor& xml); + void processModify(const resip::Uri& aor, resip::ContactList& syncContacts); + + resip::InMemorySyncRegDb* mRegDb; + resip::Data mAddress; + unsigned short mPort; + char mRxBuffer[8000]; + resip::Data mRxDataBuffer; + int mSocketDesc; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/repro/RegSyncServer.cxx b/src/libs/resiprocate/repro/RegSyncServer.cxx new file mode 100644 index 00000000..c7963124 --- /dev/null +++ b/src/libs/resiprocate/repro/RegSyncServer.cxx @@ -0,0 +1,252 @@ +#include <cassert> +#include <sstream> + +#include <resip/stack/Symbols.hxx> +#include <resip/stack/Tuple.hxx> +#include <rutil/Data.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/Logger.hxx> +#include <rutil/ParseBuffer.hxx> +#include <rutil/Socket.hxx> +#include <rutil/TransportType.hxx> +#include <rutil/Timer.hxx> + +#include "repro/XmlRpcServerBase.hxx" +#include "repro/XmlRpcConnection.hxx" +#include "repro/RegSyncServer.hxx" + +using namespace repro; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + + +RegSyncServer::RegSyncServer(resip::InMemorySyncRegDb* regDb, + int port, + IpVersion version) : + XmlRpcServerBase(port, version), + mRegDb(regDb) +{ + assert(mRegDb); + mRegDb->setHandler(this); +} + +RegSyncServer::~RegSyncServer() +{ + mRegDb->setHandler(0); +} + +void +RegSyncServer::sendResponse(unsigned int connectionId, + unsigned int requestId, + const Data& responseData, + unsigned int resultCode, + const Data& resultText) +{ + std::stringstream ss; + ss << Symbols::CRLF << responseData << " <Result Code=\"" << resultCode << "\""; + ss << ">" << resultText.xmlCharDataEncode() << "</Result>" << Symbols::CRLF; + XmlRpcServerBase::sendResponse(connectionId, requestId, ss.str().c_str(), resultCode >= 200 /* isFinal */); +} + +void +RegSyncServer::sendRegistrationModifiedEvent(unsigned int connectionId, const resip::Uri& aor) +{ + ContactList contacts; + + mRegDb->getContacts(aor, contacts); + sendRegistrationModifiedEvent(connectionId, aor, contacts); +} + +void +RegSyncServer::sendRegistrationModifiedEvent(unsigned int connectionId, const resip::Uri& aor, const ContactList& contacts) +{ + std::stringstream ss; + bool infoFound = false; + + ss << "<reginfo>" << Symbols::CRLF; + ss << " <aor>" << Data::from(aor).xmlCharDataEncode() << "</aor>" << Symbols::CRLF; + ContactList::const_iterator cit = contacts.begin(); + for(; cit != contacts.end(); cit++) + { + const ContactInstanceRecord& rec = *cit; + if(!rec.mReceivedFrom.onlyUseExistingConnection) + { + streamContactInstanceRecord(ss, rec); + infoFound = true; + } + } + ss << "</reginfo>" << Symbols::CRLF; + + if(infoFound) + { + sendEvent(connectionId, ss.str().c_str()); + } +} + +void +RegSyncServer::handleRequest(unsigned int connectionId, unsigned int requestId, const resip::Data& request) +{ + DebugLog (<< "RegSyncServer::handleRequest: connectionId=" << connectionId << ", requestId=" << requestId << ", request=" << request); + + try + { + ParseBuffer pb(request); + XMLCursor xml(pb); + + if(isEqualNoCase(xml.getTag(), "InitialSync")) + { + handleInitialSyncRequest(connectionId, requestId, xml); + } + else + { + WarningLog(<< "RegSyncServer::handleRequest: Received XML message with unknown method: " << xml.getTag()); + sendResponse(connectionId, requestId, Data::Empty, 400, "Unknown method"); + } + } + catch(resip::BaseException& e) + { + WarningLog(<< "RegSyncServer::handleRequest: ParseException: " << e); + sendResponse(connectionId, requestId, Data::Empty, 400, "Parse error"); + } +} + +void +RegSyncServer::handleInitialSyncRequest(unsigned int connectionId, unsigned int requestId, XMLCursor& xml) +{ + InfoLog(<< "RegSyncServer::handleInitialSyncRequest"); + + // Check for correct Version + unsigned int version = 0; + if(xml.firstChild()) + { + if(isEqualNoCase(xml.getTag(), "request")) + { + if(xml.firstChild()) + { + if(isEqualNoCase(xml.getTag(), "version")) + { + if(xml.firstChild()) + { + version = xml.getValue().convertUnsignedLong(); + xml.parent(); + } + } + xml.parent(); + } + } + xml.parent(); + } + + if(version == REGSYNC_VERSION) + { + mRegDb->initialSync(connectionId); + sendResponse(connectionId, requestId, Data::Empty, 200, "Initial Sync Completed."); + } + else + { + sendResponse(connectionId, requestId, Data::Empty, 505, "Version not supported."); + } +} + +void +RegSyncServer::streamContactInstanceRecord(std::stringstream& ss, const ContactInstanceRecord& rec) +{ + UInt64 now = Timer::getTimeSecs(); + + ss << " <contactinfo>" << Symbols::CRLF; + ss << " <contacturi>" << Data::from(rec.mContact.uri()).xmlCharDataEncode() << "</contacturi>" << Symbols::CRLF; + // If contact is expired or removed, then pass expires time as 0, otherwise send number of seconds until expirey + ss << " <expires>" << (((rec.mRegExpires == 0) || (rec.mRegExpires <= now)) ? 0 : (rec.mRegExpires-now)) << "</expires>" << Symbols::CRLF; + ss << " <lastupdate>" << now-rec.mLastUpdated << "</lastupdate>" << Symbols::CRLF; + if(rec.mReceivedFrom.getPort() != 0) + { + resip::Data binaryFlowToken; + Tuple::writeBinaryToken(rec.mReceivedFrom,binaryFlowToken); + ss << " <receivedfrom>" << binaryFlowToken.base64encode() << "</receivedfrom>" << Symbols::CRLF; + } + if(rec.mPublicAddress.getType() != UNKNOWN_TRANSPORT) + { + resip::Data binaryFlowToken; + Tuple::writeBinaryToken(rec.mPublicAddress,binaryFlowToken); + ss << " <publicaddress>" << binaryFlowToken.base64encode() << "</publicaddress>" << Symbols::CRLF; + } + NameAddrs::const_iterator naIt = rec.mSipPath.begin(); + for(; naIt != rec.mSipPath.end(); naIt++) + { + ss << " <sippath>" << Data::from(naIt->uri()).xmlCharDataEncode() << "</sippath>" << Symbols::CRLF; + } + if(!rec.mInstance.empty()) + { + ss << " <instance>" << rec.mInstance.xmlCharDataEncode() << "</instance>" << Symbols::CRLF; + } + if(rec.mRegId != 0) + { + ss << " <regid>" << rec.mRegId << "</regid>" << Symbols::CRLF; + } + ss << " </contactinfo>" << Symbols::CRLF; +} + +void +RegSyncServer::onAorModified(const resip::Uri& aor, const ContactList& contacts) +{ + sendRegistrationModifiedEvent(0, aor, contacts); +} + +void +RegSyncServer::onInitialSyncAor(unsigned int connectionId, const resip::Uri& aor, const ContactList& contacts) +{ + sendRegistrationModifiedEvent(connectionId, aor, contacts); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/RegSyncServer.hxx b/src/libs/resiprocate/repro/RegSyncServer.hxx new file mode 100644 index 00000000..06b15a7a --- /dev/null +++ b/src/libs/resiprocate/repro/RegSyncServer.hxx @@ -0,0 +1,102 @@ +#if !defined(RegSyncServer_hxx) +#define RegSyncServer_hxx + +#include <rutil/Data.hxx> +#include <rutil/TransportType.hxx> +#include <rutil/XMLCursor.hxx> +#include <resip/dum/InMemorySyncRegDb.hxx> +#include "repro/XmlRpcServerBase.hxx" + +#define REGSYNC_VERSION 3 + +namespace repro +{ +class RegSyncServer; + +class RegSyncServer: public XmlRpcServerBase, public resip::InMemorySyncRegDbHandler +{ +public: + RegSyncServer(resip::InMemorySyncRegDb* regDb, + int port, + resip::IpVersion version); + virtual ~RegSyncServer(); + + // thread safe + virtual void sendResponse(unsigned int connectionId, + unsigned int requestId, + const resip::Data& responseData, + unsigned int resultCode, + const resip::Data& resultText); + // Use connectionId == 0 to send to all connections + virtual void sendRegistrationModifiedEvent(unsigned int connectionId, const resip::Uri& aor); + virtual void sendRegistrationModifiedEvent(unsigned int connectionId, const resip::Uri& aor, const resip::ContactList& contacts); + +protected: + virtual void handleRequest(unsigned int connectionId, + unsigned int requestId, + const resip::Data& request); + + virtual void onAorModified(const resip::Uri& aor, const resip::ContactList& contacts); + virtual void onInitialSyncAor(unsigned int connectionId, const resip::Uri& aor, const resip::ContactList& contacts); + +private: + void handleInitialSyncRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml); + void streamContactInstanceRecord(std::stringstream& ss, const resip::ContactInstanceRecord& rec); + + resip::InMemorySyncRegDb* mRegDb; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/RegSyncServerThread.cxx b/src/libs/resiprocate/repro/RegSyncServerThread.cxx new file mode 100644 index 00000000..abf019f2 --- /dev/null +++ b/src/libs/resiprocate/repro/RegSyncServerThread.cxx @@ -0,0 +1,99 @@ +#include <rutil/Socket.hxx> +#include <rutil/Logger.hxx> + +#include "repro/RegSyncServer.hxx" +#include "repro/RegSyncClient.hxx" +#include "repro/RegSyncServerThread.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +using namespace repro; +using namespace resip; +using namespace std; + +RegSyncServerThread::RegSyncServerThread(const std::list<RegSyncServer*>& regSyncServerList) + : mRegSyncServerList(regSyncServerList) +{ +} + +void +RegSyncServerThread::thread() +{ + while (!isShutdown()) + { + try + { + FdSet fdset; + + std::list<RegSyncServer*>::iterator it = mRegSyncServerList.begin(); + for(;it!=mRegSyncServerList.end();it++) + { + (*it)->buildFdSet(fdset); + } + fdset.selectMilliSeconds( 2*1000 ); + + it = mRegSyncServerList.begin(); + for(;it!=mRegSyncServerList.end();it++) + { + (*it)->process(fdset); + } + } + catch (...) + { + ErrLog (<< "RegSyncServerThread::thread: Unhandled exception: " ); + } + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/repro/RegSyncServerThread.hxx b/src/libs/resiprocate/repro/RegSyncServerThread.hxx new file mode 100644 index 00000000..332e71a2 --- /dev/null +++ b/src/libs/resiprocate/repro/RegSyncServerThread.hxx @@ -0,0 +1,81 @@ +#if !defined(RegSyncServerThread_hxx) +#define RegSyncServerThread_hxx + +#include <list> +#include <rutil/ThreadIf.hxx> +#include <rutil/Socket.hxx> + +namespace repro +{ +class RegSyncServer; +class RegSyncClient; + +class RegSyncServerThread : public resip::ThreadIf +{ +public: + RegSyncServerThread(const std::list<RegSyncServer*>& regSyncServerList); + +protected: + +private: + virtual void thread(); + std::list<RegSyncServer*> mRegSyncServerList; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + + diff --git a/src/libs/resiprocate/repro/Registrar.cxx b/src/libs/resiprocate/repro/Registrar.cxx new file mode 100644 index 00000000..b3603124 --- /dev/null +++ b/src/libs/resiprocate/repro/Registrar.cxx @@ -0,0 +1,178 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "repro/Registrar.hxx" +#include "repro/Proxy.hxx" +#include "resip/dum/ServerRegistration.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +Registrar::Registrar() : mProxy(0) +{ +} + +Registrar::~Registrar() +{ +} + +void +Registrar::addRegistrarHandler(RegistrarHandler* handler) +{ + mRegistrarHandlers.push_back(handler); +} + +void +Registrar::onRefresh(resip::ServerRegistrationHandle sr, + const resip::SipMessage& reg) +{ + DebugLog (<< "Registrar::onRefresh " << reg.brief()); + std::list<RegistrarHandler*>::iterator it = mRegistrarHandlers.begin(); + bool continueProcessing = true; + for(; it != mRegistrarHandlers.end() && continueProcessing; it++) + { + continueProcessing = (*it)->onRefresh(sr, reg); + } + if(continueProcessing) + { + if(mProxy) + { + mProxy->doRegistrationAccounting(AccountingCollector::RegistrationRefreshed, reg); + } + sr->accept(); + } +} + +void +Registrar::onRemove(resip::ServerRegistrationHandle sr, + const resip::SipMessage& reg) +{ + DebugLog (<< "Registrar::onRemove " << reg.brief()); + std::list<RegistrarHandler*>::iterator it = mRegistrarHandlers.begin(); + bool continueProcessing = true; + for(; it != mRegistrarHandlers.end() && continueProcessing; it++) + { + continueProcessing = (*it)->onRemove(sr, reg); + } + if(continueProcessing) + { + if(mProxy) + { + mProxy->doRegistrationAccounting(AccountingCollector::RegistrationRemoved, reg); + } + sr->accept(); + } +} + +void +Registrar::onRemoveAll(resip::ServerRegistrationHandle sr, + const resip::SipMessage& reg) +{ + DebugLog (<< "Registrar::onRemoveAll " << reg.brief()); + std::list<RegistrarHandler*>::iterator it = mRegistrarHandlers.begin(); + bool continueProcessing = true; + for(; it != mRegistrarHandlers.end() && continueProcessing; it++) + { + continueProcessing = (*it)->onRemoveAll(sr, reg); + } + if(continueProcessing) + { + if(mProxy) + { + mProxy->doRegistrationAccounting(AccountingCollector::RegistrationRemovedAll, reg); + } + sr->accept(); + } +} + +void +Registrar::onAdd(resip::ServerRegistrationHandle sr, + const resip::SipMessage& reg) +{ + DebugLog (<< "Registrar::onAdd " << reg.brief()); + std::list<RegistrarHandler*>::iterator it = mRegistrarHandlers.begin(); + bool continueProcessing = true; + for(; it != mRegistrarHandlers.end() && continueProcessing; it++) + { + continueProcessing = (*it)->onAdd(sr, reg); + } + if(continueProcessing) + { + if(mProxy) + { + mProxy->doRegistrationAccounting(AccountingCollector::RegistrationAdded, reg); + } + sr->accept(); + } +} + +void +Registrar::onQuery(resip::ServerRegistrationHandle sr, + const resip::SipMessage& reg) +{ + std::list<RegistrarHandler*>::iterator it = mRegistrarHandlers.begin(); + bool continueProcessing = true; + for(; it != mRegistrarHandlers.end() && continueProcessing; it++) + { + continueProcessing = (*it)->onQuery(sr, reg); + } + if(continueProcessing) + { + sr->accept(); + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/Registrar.hxx b/src/libs/resiprocate/repro/Registrar.hxx new file mode 100644 index 00000000..d5e0eab2 --- /dev/null +++ b/src/libs/resiprocate/repro/Registrar.hxx @@ -0,0 +1,111 @@ +#if !defined(RESIP_REGISTRAR_HXX) +#define RESIP_REGISTRAR_HXX + +#include "resip/dum/RegistrationHandler.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/InMemoryRegistrationDatabase.hxx" +#include "resip/dum/MasterProfile.hxx" + +namespace repro +{ +class Proxy; + +class RegistrarHandler +{ + public: + virtual ~RegistrarHandler() {} + + /// Note: These very closely mimic the ServerRegistrationHandler callbacks + + /// For all of the below callbacks - return true if no response was generated and processing + /// should continue. If all handlers return true, then the Registrar will accept the request. + + /// Called when registration is refreshed + virtual bool onRefresh(resip::ServerRegistrationHandle, const resip::SipMessage& reg)=0; + + /// called when one or more specified contacts is removed + virtual bool onRemove(resip::ServerRegistrationHandle, const resip::SipMessage& reg)=0; + + /// Called when all the contacts are removed using "Contact: *" + virtual bool onRemoveAll(resip::ServerRegistrationHandle, const resip::SipMessage& reg)=0; + + /** Called when one or more contacts are added. This is after + authentication has all succeeded */ + virtual bool onAdd(resip::ServerRegistrationHandle, const resip::SipMessage& reg)=0; + + /// Called when a client queries for the list of current registrations + virtual bool onQuery(resip::ServerRegistrationHandle, const resip::SipMessage& reg)=0; +}; + +class Registrar: public resip::ServerRegistrationHandler +{ + public: + Registrar(); + virtual ~Registrar(); + + void setProxy(Proxy* proxy) { mProxy = proxy; } + + virtual void addRegistrarHandler(RegistrarHandler* handler); + + virtual void onRefresh(resip::ServerRegistrationHandle, const resip::SipMessage& reg); + virtual void onRemove(resip::ServerRegistrationHandle, const resip::SipMessage& reg); + virtual void onRemoveAll(resip::ServerRegistrationHandle, const resip::SipMessage& reg); + virtual void onAdd(resip::ServerRegistrationHandle, const resip::SipMessage& reg); + virtual void onQuery(resip::ServerRegistrationHandle, const resip::SipMessage& reg); + + private: + std::list<RegistrarHandler*> mRegistrarHandlers; + Proxy* mProxy; +}; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/ReproRunner.cxx b/src/libs/resiprocate/repro/ReproRunner.cxx new file mode 100644 index 00000000..889c09f9 --- /dev/null +++ b/src/libs/resiprocate/repro/ReproRunner.cxx @@ -0,0 +1,1467 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <iostream> +#include <fstream> +#include <stdexcept> + +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/dns/DnsStub.hxx" +#include "rutil/GeneralCongestionManager.hxx" + +#include "resip/stack/SipStack.hxx" +#include "resip/stack/Compression.hxx" +#include "resip/stack/EventStackThread.hxx" +#include "resip/stack/InteropHelper.hxx" +#include "resip/stack/ConnectionManager.hxx" + +#include "resip/dum/InMemorySyncRegDb.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/DumThread.hxx" +#include "resip/dum/TlsPeerAuthManager.hxx" + +#include "repro/AsyncProcessorWorker.hxx" +#include "repro/ReproRunner.hxx" +#include "repro/Proxy.hxx" +#include "repro/ProxyConfig.hxx" +#include "repro/BerkeleyDb.hxx" +#include "repro/Dispatcher.hxx" +#include "repro/UserAuthGrabber.hxx" +#include "repro/ProcessorChain.hxx" +#include "repro/ReproVersion.hxx" +#include "repro/WebAdmin.hxx" +#include "repro/WebAdminThread.hxx" +#include "repro/Registrar.hxx" +#include "repro/ReproServerAuthManager.hxx" +#include "repro/RegSyncClient.hxx" +#include "repro/RegSyncServer.hxx" +#include "repro/RegSyncServerThread.hxx" +#include "repro/CommandServer.hxx" +#include "repro/CommandServerThread.hxx" +#include "repro/monkeys/IsTrustedNode.hxx" +#include "repro/monkeys/AmIResponsible.hxx" +#include "repro/monkeys/DigestAuthenticator.hxx" +#include "repro/monkeys/LocationServer.hxx" +#include "repro/monkeys/RecursiveRedirect.hxx" +#include "repro/monkeys/SimpleStaticRoute.hxx" +#include "repro/monkeys/StaticRoute.hxx" +#include "repro/monkeys/StrictRouteFixup.hxx" +#include "repro/monkeys/OutboundTargetHandler.hxx" +#include "repro/monkeys/QValueTargetHandler.hxx" +#include "repro/monkeys/SimpleTargetHandler.hxx" +#include "repro/monkeys/GeoProximityTargetSorter.hxx" +#include "repro/monkeys/RequestFilter.hxx" +#include "repro/monkeys/MessageSilo.hxx" +#include "repro/monkeys/CertificateAuthenticator.hxx" + +#if defined(USE_SSL) +#include "repro/stateAgents/CertServer.hxx" +#include "resip/stack/ssl/Security.hxx" +#endif + +#if defined(USE_MYSQL) +#include "repro/MySqlDb.hxx" +#endif + +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +class ReproLogger : public ExternalLogger +{ +public: + virtual ~ReproLogger() {} + /** return true to also do default logging, false to supress default logging. */ + virtual bool operator()(Log::Level level, + const Subsystem& subsystem, + const Data& appName, + const char* file, + int line, + const Data& message, + const Data& messageWithHeaders) + { + // Log any errors to the screen + if(level <= Log::Err) + { + resipCout << messageWithHeaders << endl; + } + return true; + } +}; +ReproLogger g_ReproLogger; + +ReproRunner::ReproRunner() + : mRunning(false) + , mRestarting(false) + , mThreadedStack(false) + , mSipAuthDisabled(false) + , mUseV4(true) + , mUseV6 (false) + , mRegSyncPort(0) + , mProxyConfig(0) + , mFdPollGrp(0) + , mAsyncProcessHandler(0) + , mSipStack(0) + , mStackThread(0) + , mAbstractDb(0) + , mRuntimeAbstractDb(0) + , mRegistrationPersistenceManager(0) + , mAuthRequestDispatcher(0) + , mAsyncProcessorDispatcher(0) + , mMonkeys(0) + , mLemurs(0) + , mBaboons(0) + , mProxy(0) + , mWebAdmin(0) + , mWebAdminThread(0) + , mRegistrar(0) + , mDum(0) + , mDumThread(0) + , mCertServer(0) + , mRegSyncClient(0) + , mRegSyncServerV4(0) + , mRegSyncServerV6(0) + , mRegSyncServerThread(0) + , mCommandServerV4(0) + , mCommandServerV6(0) + , mCommandServerThread(0) + , mCongestionManager(0) +{ +} + +ReproRunner::~ReproRunner() +{ + if(mRunning) shutdown(); +} + +bool +ReproRunner::run(int argc, char** argv) +{ + if(mRunning) return false; + + if(!mRestarting) + { + // Store original arc and argv - so we can reuse them on restart request + mArgc = argc; + mArgv = argv; + } + + // Parse command line and configuration file + assert(!mProxyConfig); + Data defaultConfigFilename("repro.config"); + try + { + mProxyConfig = new ProxyConfig(); + mProxyConfig->parseConfig(mArgc, mArgv, defaultConfigFilename); + } + catch(BaseException& ex) + { + std::cerr << "Error parsing configuration: " << ex << std::endl; + return false; + } + + // Non-Windows server process stuff + if(!mRestarting) + { + setPidFile(mProxyConfig->getConfigData("PidFile", "", true)); + if(mProxyConfig->getConfigBool("Daemonize", false)) + { + daemonize(); + } + } + + // Initialize resip logger + GenericLogImpl::MaxByteCount = mProxyConfig->getConfigUnsignedLong("LogFileMaxBytes", 5242880 /*5 Mb */); + Data loggingType = mProxyConfig->getConfigData("LoggingType", "cout", true); + Log::initialize(loggingType, + mProxyConfig->getConfigData("LogLevel", "INFO", true), + mArgv[0], + mProxyConfig->getConfigData("LogFilename", "repro.log", true).c_str(), + isEqualNoCase(loggingType, "file") ? &g_ReproLogger : 0); // if logging to file then write WARNINGS, and Errors to console still + + InfoLog( << "Starting repro version " << VersionUtils::instance().releaseVersion() << "..."); + + // Create SipStack and associated objects + if(!createSipStack()) + { + return false; + } + + // Create datastore + if(!createDatastore()) + { + return false; + } + + // Create DialogUsageManager that handles ServerRegistration, + // and potentially certificate subscription server + createDialogUsageManager(); + + // Create the Proxy and associate objects + if(!createProxy()) + { + return false; + } + + // Create HTTP WebAdmin and Thread + if(!createWebAdmin()) + { + return false; + } + + // Create reg sync components if required + createRegSync(); + + // Create command server if required + if(!mRestarting) + { + createCommandServer(); + } + + // Make it all go - startup all threads + mThreadedStack = mProxyConfig->getConfigBool("ThreadedStack", true); + if(mThreadedStack) + { + // If configured, then start the sub-threads within the stack + mSipStack->run(); + } + mStackThread->run(); + if(mDumThread) + { + mDumThread->run(); + } + mProxy->run(); + if(mWebAdminThread) + { + mWebAdminThread->run(); + } + if(!mRestarting && mCommandServerThread) + { + mCommandServerThread->run(); + } + if(mRegSyncServerThread) + { + mRegSyncServerThread->run(); + } + if(mRegSyncClient) + { + mRegSyncClient->run(); + } + + mRunning = true; + + return true; +} + +void +ReproRunner::shutdown() +{ + if(!mRunning) return; + + // Tell all threads to shutdown + if(mWebAdminThread) + { + mWebAdminThread->shutdown(); + } + if(mDumThread) + { + mDumThread->shutdown(); + } + mProxy->shutdown(); + mStackThread->shutdown(); + if(!mRestarting && mCommandServerThread) // leave command server running if we are restarting + { + mCommandServerThread->shutdown(); + } + if(mRegSyncServerThread) + { + mRegSyncServerThread->shutdown(); + } + if(mRegSyncClient) + { + mRegSyncClient->shutdown(); + } + + // Wait for all threads to shutdown, and destroy objects + mProxy->join(); + if(mThreadedStack) + { + mSipStack->shutdownAndJoinThreads(); + } + mStackThread->join(); + if(mWebAdminThread) + { + mWebAdminThread->join(); + } + if(mDumThread) + { + mDumThread->join(); + } + if(mAuthRequestDispatcher) + { + // Both proxy and dum threads are down at this point, we can + // destroy the authRequest dispatcher and associated threads now + delete mAuthRequestDispatcher; + mAuthRequestDispatcher = 0; + } + if(mAsyncProcessorDispatcher) + { + // Both proxy and dum threads are down at this point, we can + // destroy the async processor dispatcher and associated threads now + delete mAsyncProcessorDispatcher; + mAsyncProcessorDispatcher = 0; + } + if(!mRestarting && mCommandServerThread) // we leave command server running during restart + { + mCommandServerThread->join(); + } + if(mRegSyncServerThread) + { + mRegSyncServerThread->join(); + } + if(mRegSyncClient) + { + mRegSyncClient->join(); + } + + mSipStack->setCongestionManager(0); + + cleanupObjects(); + mRunning = false; +} + +void +ReproRunner::restart() +{ + if(!mRunning) return; + mRestarting = true; + shutdown(); + run(0, 0); + mRestarting = false; +} + +void +ReproRunner::cleanupObjects() +{ + delete mCongestionManager; mCongestionManager = 0; + if(!mRestarting) + { + // We leave command server running during restart + delete mCommandServerThread; mCommandServerThread = 0; + delete mCommandServerV6; mCommandServerV6 = 0; + delete mCommandServerV4; mCommandServerV4 = 0; + } + delete mRegSyncServerThread; mRegSyncServerThread = 0; + delete mRegSyncServerV6; mRegSyncServerV6 = 0; + delete mRegSyncServerV4; mRegSyncServerV4 = 0; + delete mRegSyncClient; mRegSyncClient = 0; +#if defined(USE_SSL) + delete mCertServer; mCertServer = 0; +#endif + delete mDumThread; mDumThread = 0; + delete mDum; mDum = 0; + delete mRegistrar; mRegistrar = 0; + delete mWebAdminThread; mWebAdminThread = 0; + delete mWebAdmin; mWebAdmin = 0; + delete mProxy; mProxy = 0; + delete mBaboons; mBaboons = 0; + delete mLemurs; mLemurs = 0; + delete mMonkeys; mMonkeys = 0; + delete mAuthRequestDispatcher; mAuthRequestDispatcher = 0; + delete mAsyncProcessorDispatcher; mAsyncProcessorDispatcher = 0; + if(!mRestarting) + { + // If we are restarting then leave the In Memory Registration database intact + delete mRegistrationPersistenceManager; mRegistrationPersistenceManager = 0; + } + delete mAbstractDb; mAbstractDb = 0; + delete mRuntimeAbstractDb; mRuntimeAbstractDb = 0; + delete mStackThread; mStackThread = 0; + delete mSipStack; mSipStack = 0; + delete mAsyncProcessHandler; mAsyncProcessHandler = 0; + delete mFdPollGrp; mFdPollGrp = 0; + delete mProxyConfig; mProxyConfig = 0; +} + +bool +ReproRunner::createSipStack() +{ + // Override T1 timer if configured to do so + unsigned long overrideT1 = mProxyConfig->getConfigInt("TimerT1", 0); + if(overrideT1) + { + WarningLog(<< "Overriding T1! (new value is " << + overrideT1 << ")"); + resip::Timer::resetT1(overrideT1); + } + + // Create Security (TLS / Certificates) and Compression (SigComp) objects if + // pre-precessor defines are enabled + Security* security = 0; + Compression* compression = 0; +#ifdef USE_SSL +#ifdef WIN32 + Data certPath("C:\\sipCerts"); +#else + Data certPath(getenv("HOME")); + certPath += "/.sipCerts"; +#endif + mProxyConfig->getConfigValue("CertificatePath", certPath); + security = new Security(certPath); + Data caDir; + mProxyConfig->getConfigValue("CADirectory", caDir); + if(!caDir.empty()) + { + security->addCADirectory(caDir); + } + Data caFile; + mProxyConfig->getConfigValue("CAFile", caFile); + if(!caFile.empty()) + { + security->addCAFile(caFile); + } +#endif + +#ifdef USE_SIGCOMP + compression = new Compression(Compression::DEFLATE); +#endif + + // Create EventThreadInterruptor used to wake up the stack for + // for reasons other than an Fd signalling + assert(!mFdPollGrp); + mFdPollGrp = FdPollGrp::create(); + assert(!mAsyncProcessHandler); + mAsyncProcessHandler = new EventThreadInterruptor(*mFdPollGrp); + + // Set Flags that will enable/disable IPv4 and/or IPv6, based on + // configuration and pre-processor flags + mUseV4 = !mProxyConfig->getConfigBool("DisableIPv4", false); +#ifdef USE_IPV6 + mUseV6 = mProxyConfig->getConfigBool("EnableIPv6", true); +#else + bool useV6 = false; +#endif + if (mUseV4) InfoLog (<< "V4 enabled"); + if (mUseV6) InfoLog (<< "V6 enabled"); + + // Build DNS Server list from config + DnsStub::NameserverList dnsServers; + std::vector<resip::Data> dnsServersConfig; + mProxyConfig->getConfigValue("DNSServers", dnsServersConfig); + for(std::vector<resip::Data>::iterator it = dnsServersConfig.begin(); it != dnsServersConfig.end(); it++) + { + if((mUseV4 && DnsUtil::isIpV4Address(*it)) || (mUseV6 && DnsUtil::isIpV6Address(*it))) + { + InfoLog(<< "Using DNS Server from config: " << *it); + dnsServers.push_back(Tuple(*it, 0, UNKNOWN_TRANSPORT).toGenericIPAddress()); + } + } + + // Create the SipStack Object + assert(!mSipStack); + mSipStack = new SipStack(security, + dnsServers, + mAsyncProcessHandler, + /*stateless*/false, + /*socketFunc*/0, + compression, + mFdPollGrp); + + // Set any enum suffixes from configuration + std::vector<Data> enumSuffixes; + mProxyConfig->getConfigValue("EnumSuffixes", enumSuffixes); + if (enumSuffixes.size() > 0) + { + mSipStack->setEnumSuffixes(enumSuffixes); + } + + // Set any enum domains from configuration + std::map<Data,Data> enumDomains; + std::vector<Data> _enumDomains; + mProxyConfig->getConfigValue("EnumDomains", _enumDomains); + if (enumSuffixes.size() > 0) + { + for(std::vector<Data>::iterator it = _enumDomains.begin(); it != _enumDomains.end(); it++) + { + enumDomains[*it] = *it; + } + mSipStack->setEnumDomains(enumDomains); + } + + // Add stack transports + bool allTransportsSpecifyRecordRoute=false; + if(!addTransports(allTransportsSpecifyRecordRoute)) + { + cleanupObjects(); + return false; + } + + // Enable and configure RFC5626 Outbound support + InteropHelper::setOutboundVersion(mProxyConfig->getConfigInt("OutboundVersion", 5626)); + InteropHelper::setOutboundSupported(mProxyConfig->getConfigBool("DisableOutbound", false) ? false : true); + InteropHelper::setRRTokenHackEnabled(mProxyConfig->getConfigBool("EnableFlowTokens", false)); + InteropHelper::setAssumeFirstHopSupportsOutboundEnabled(mProxyConfig->getConfigBool("AssumeFirstHopSupportsOutbound", false)); + Data clientNATDetectionMode = mProxyConfig->getConfigData("ClientNatDetectionMode", "DISABLED"); + if(isEqualNoCase(clientNATDetectionMode, "ENABLED")) + { + InteropHelper::setClientNATDetectionMode(InteropHelper::ClientNATDetectionEnabled); + } + else if(isEqualNoCase(clientNATDetectionMode, "PRIVATE_TO_PUBLIC")) + { + InteropHelper::setClientNATDetectionMode(InteropHelper::ClientNATDetectionPrivateToPublicOnly); + } + unsigned long outboundFlowTimer = mProxyConfig->getConfigUnsignedLong("FlowTimer", 0); + if(outboundFlowTimer > 0) + { + InteropHelper::setFlowTimerSeconds(outboundFlowTimer); + ConnectionManager::MinimumGcAge = 7200000; // Timeout connections not related to a flow timer after 2 hours - TODO make configurable + ConnectionManager::EnableAgressiveGc = true; + } + + // Check Path and RecordRoute settings, print warning if features are enabled that + // require record-routing and record-route uri(s) is not configured + bool assumePath = mProxyConfig->getConfigBool("AssumePath", false); + bool forceRecordRoute = mProxyConfig->getConfigBool("ForceRecordRouting", false); + Uri recordRouteUri; + mProxyConfig->getConfigValue("RecordRouteUri", recordRouteUri); + if((InteropHelper::getOutboundSupported() + || InteropHelper::getRRTokenHackEnabled() + || InteropHelper::getClientNATDetectionMode() != InteropHelper::ClientNATDetectionDisabled + || assumePath + || forceRecordRoute + ) + && !(allTransportsSpecifyRecordRoute || !recordRouteUri.host().empty())) + { + CritLog(<< "In order for outbound support, the Record-Route flow-token" + " hack, or force-record-route to work, you MUST specify a Record-Route URI. Launching " + "without..."); + InteropHelper::setOutboundSupported(false); + InteropHelper::setRRTokenHackEnabled(false); + InteropHelper::setClientNATDetectionMode(InteropHelper::ClientNATDetectionDisabled); + assumePath = false; + forceRecordRoute=false; + } + + // Configure misc. stack settings + mSipStack->setFixBadDialogIdentifiers(false); + mSipStack->setFixBadCSeqNumbers(false); + int statsLogInterval = mProxyConfig->getConfigInt("StatisticsLogInterval", 60); + if(statsLogInterval > 0) + { + mSipStack->setStatisticsInterval(statsLogInterval); + mSipStack->statisticsManagerEnabled() = true; + } + else + { + mSipStack->statisticsManagerEnabled() = false; + } + + // Create Congestion Manager, if required + assert(!mCongestionManager); + if(mProxyConfig->getConfigBool("CongestionManagement", true)) + { + Data metricData = mProxyConfig->getConfigData("CongestionManagementMetric", "WAIT_TIME", true); + GeneralCongestionManager::MetricType metric = GeneralCongestionManager::WAIT_TIME; + if(isEqualNoCase(metricData, "TIME_DEPTH")) + { + metric = GeneralCongestionManager::TIME_DEPTH; + } + else if(isEqualNoCase(metricData, "SIZE")) + { + metric = GeneralCongestionManager::SIZE; + } + else if(!isEqualNoCase(metricData, "WAIT_TIME")) + { + WarningLog( << "CongestionManagementMetric specified as an unknown value (" << metricData << "), defaulting to WAIT_TIME."); + } + mCongestionManager = new GeneralCongestionManager( + metric, + mProxyConfig->getConfigUnsignedLong("CongestionManagementTolerance", 200)); + mSipStack->setCongestionManager(mCongestionManager); + } + + // Create base thread to run stack in (note: stack may use other sub-threads, depending on configuration) + assert(!mStackThread); + mStackThread = new EventStackThread(*mSipStack, + *dynamic_cast<EventThreadInterruptor*>(mAsyncProcessHandler), + *mFdPollGrp); + return true; +} + +bool +ReproRunner::createDatastore() +{ + // Create Database access objects + assert(!mAbstractDb); + assert(!mRuntimeAbstractDb); +#ifdef USE_MYSQL + Data mySQLServer; + mProxyConfig->getConfigValue("MySQLServer", mySQLServer); + if(!mySQLServer.empty()) + { + mAbstractDb = new MySqlDb(mySQLServer, + mProxyConfig->getConfigData("MySQLUser", ""), + mProxyConfig->getConfigData("MySQLPassword", ""), + mProxyConfig->getConfigData("MySQLDatabaseName", ""), + mProxyConfig->getConfigUnsignedLong("MySQLPort", 0), + mProxyConfig->getConfigData("MySQLCustomUserAuthQuery", "")); + } + Data runtimeMySQLServer; + mProxyConfig->getConfigValue("RuntimeMySQLServer", runtimeMySQLServer); + if(!runtimeMySQLServer.empty()) + { + mRuntimeAbstractDb = new MySqlDb(runtimeMySQLServer, + mProxyConfig->getConfigData("RuntimeMySQLUser", ""), + mProxyConfig->getConfigData("RuntimeMySQLPassword", ""), + mProxyConfig->getConfigData("RuntimeMySQLDatabaseName", ""), + mProxyConfig->getConfigUnsignedLong("RuntimeMySQLPort", 0), + mProxyConfig->getConfigData("MySQLCustomUserAuthQuery", "")); + } +#endif + if (!mAbstractDb) + { + mAbstractDb = new BerkeleyDb(mProxyConfig->getConfigData("DatabasePath", "./", true)); + } + assert(mAbstractDb); + if(!mAbstractDb->isSane()) + { + CritLog(<<"Failed to open configuration database"); + cleanupObjects(); + return false; + } + if(mRuntimeAbstractDb && !mRuntimeAbstractDb->isSane()) + { + CritLog(<<"Failed to open runtime configuration database"); + cleanupObjects(); + return false; + } + mProxyConfig->createDataStore(mAbstractDb, mRuntimeAbstractDb); + + // Create ImMemory Registration Database + mRegSyncPort = mProxyConfig->getConfigInt("RegSyncPort", 0); + // We only need removed records to linger if we have reg sync enabled + if(!mRestarting) // If we are restarting then we left the InMemoryRegistrationDb intact at shutdown - don't recreate + { + assert(!mRegistrationPersistenceManager); + mRegistrationPersistenceManager = new InMemorySyncRegDb(mRegSyncPort ? 86400 /* 24 hours */ : 0 /* removeLingerSecs */); // !slg! could make linger time a setting + } + assert(mRegistrationPersistenceManager); + + // Copy contacts from the StaticRegStore to the RegistrationPersistanceManager + populateRegistrations(); + + return true; +} + +void +ReproRunner::createDialogUsageManager() +{ + // Create Profile settings for DUM Instance that handles ServerRegistration, + // and potentially certificate subscription server + SharedPtr<MasterProfile> profile(new MasterProfile); + profile->clearSupportedMethods(); + profile->addSupportedMethod(resip::REGISTER); +#ifdef USE_SSL + profile->addSupportedScheme(Symbols::Sips); +#endif + if(InteropHelper::getOutboundSupported()) + { + profile->addSupportedOptionTag(Token(Symbols::Outbound)); + } + profile->addSupportedOptionTag(Token(Symbols::Path)); + if(mProxyConfig->getConfigBool("AllowBadReg", false)) + { + profile->allowBadRegistrationEnabled() = true; + } + + // Create DialogeUsageManager if Registrar or Certificate Server are enabled + assert(!mRegistrar); + assert(!mDum); + assert(!mDumThread); + mRegistrar = new Registrar; + resip::MessageFilterRuleList ruleList; + bool registrarEnabled = !mProxyConfig->getConfigBool("DisableRegistrar", false); + bool certServerEnabled = mProxyConfig->getConfigBool("EnableCertServer", false); + if (registrarEnabled || certServerEnabled) + { + mDum = new DialogUsageManager(*mSipStack); + mDum->setMasterProfile(profile); + addDomains(*mDum, false /* log? already logged when adding to Proxy - no need to log again*/); + } + + // If registrar is enabled, configure DUM to handle REGISTER requests + if (registrarEnabled) + { + assert(mDum); + assert(mRegistrationPersistenceManager); + mDum->setServerRegistrationHandler(mRegistrar); + mDum->setRegistrationPersistenceManager(mRegistrationPersistenceManager); + + // Install rules so that the registrar only gets REGISTERs + resip::MessageFilterRule::MethodList methodList; + methodList.push_back(resip::REGISTER); + ruleList.push_back(MessageFilterRule(resip::MessageFilterRule::SchemeList(), + resip::MessageFilterRule::DomainIsMe, + methodList) ); + } + + // If Certificate Server is enabled, configure DUM to handle SUBSCRIBE and + // PUBLISH requests for events: credential and certificate + assert(!mCertServer); + if (certServerEnabled) + { +#if defined(USE_SSL) + mCertServer = new CertServer(*mDum); + + // Install rules so that the cert server receives SUBSCRIBEs and PUBLISHs + resip::MessageFilterRule::MethodList methodList; + resip::MessageFilterRule::EventList eventList; + methodList.push_back(resip::SUBSCRIBE); + methodList.push_back(resip::PUBLISH); + eventList.push_back(resip::Symbols::Credential); + eventList.push_back(resip::Symbols::Certificate); + ruleList.push_back(MessageFilterRule(resip::MessageFilterRule::SchemeList(), + resip::MessageFilterRule::DomainIsMe, + methodList, + eventList)); +#endif + } + + if (mDum) + { + bool enableCertAuth = mProxyConfig->getConfigBool("EnableCertificateAuthenticator", false); + // Maintains existing behavior for non-TLS cert auth users + bool digestChallengeThirdParties = !enableCertAuth; + + if(enableCertAuth) + { + // TODO: perhaps this should be initialised from the trusted node + // monkey? Or should the list of trusted TLS peers be independent + // from the trusted node list? + std::set<Data> trustedPeers; + loadCommonNameMappings(); + SharedPtr<TlsPeerAuthManager> certAuth(new TlsPeerAuthManager(*mDum, mDum->dumIncomingTarget(), trustedPeers, true, mCommonNameMappings)); + mDum->addIncomingFeature(certAuth); + } + + mSipAuthDisabled = mProxyConfig->getConfigBool("DisableAuth", false); + + // If Authentication is enabled, then configure DUM to authenticate requests + if (!mSipAuthDisabled) + { + // Create UserAuthGrabber Worker Thread Pool if auth is enabled + assert(!mAuthRequestDispatcher); + int numAuthGrabberWorkerThreads = mProxyConfig->getConfigInt("NumAuthGrabberWorkerThreads", 2); + if(numAuthGrabberWorkerThreads < 1) numAuthGrabberWorkerThreads = 1; // must have at least one thread + std::auto_ptr<Worker> grabber(new UserAuthGrabber(mProxyConfig->getDataStore()->mUserStore)); + mAuthRequestDispatcher = new Dispatcher(grabber, mSipStack, numAuthGrabberWorkerThreads); + + SharedPtr<ServerAuthManager> + uasAuth( new ReproServerAuthManager(*mDum, + mAuthRequestDispatcher, + mProxyConfig->getDataStore()->mAclStore, + !mProxyConfig->getConfigBool("DisableAuthInt", false) /*useAuthInt*/, + mProxyConfig->getConfigBool("RejectBadNonces", false), + digestChallengeThirdParties)); + mDum->setServerAuthManager(uasAuth); + } + + // Set the MessageFilterRuleList on DUM and create a thread to run DUM in + mDum->setMessageFilterRuleList(ruleList); + mDumThread = new DumThread(*mDum); + } +} + +bool +ReproRunner::createProxy() +{ + // Create AsyncProcessorDispatcher thread pool that is shared by the processsors for + // any asyncronous tasks (ie: RequestFilter and MessageSilo processors) + int numAsyncProcessorWorkerThreads = mProxyConfig->getConfigInt("NumAsyncProcessorWorkerThreads", 2); + if(numAsyncProcessorWorkerThreads > 0) + { + assert(!mAsyncProcessorDispatcher); + mAsyncProcessorDispatcher = new Dispatcher(std::auto_ptr<Worker>(new AsyncProcessorWorker), + mSipStack, + numAsyncProcessorWorkerThreads); + } + + // Create proxy processor chains + /* Explanation: "Monkeys" are processors which operate on incoming requests + "Lemurs" are processors which operate on incoming responses + "Baboons" are processors which operate on a request for each target + as the request is about to be forwarded to that target */ + // Make Monkeys + assert(!mMonkeys); + mMonkeys = new ProcessorChain(Processor::REQUEST_CHAIN); + makeRequestProcessorChain(*mMonkeys); + InfoLog(<< *mMonkeys); + + // Make Lemurs + assert(!mLemurs); + mLemurs = new ProcessorChain(Processor::RESPONSE_CHAIN); + makeResponseProcessorChain(*mLemurs); + InfoLog(<< *mLemurs); + + // Make Baboons + assert(!mBaboons); + mBaboons = new ProcessorChain(Processor::TARGET_CHAIN); + makeTargetProcessorChain(*mBaboons); + InfoLog(<< *mBaboons); + + // Create main Proxy class + assert(!mProxy); + mProxy = new Proxy(*mSipStack, + *mProxyConfig, + *mMonkeys, + *mLemurs, + *mBaboons); + mHttpRealm = addDomains(*mProxy, true); + + // Register the Proxy class a stack transaction user + // Note: This is done after creating the DialogUsageManager so that it acts + // like a catchall and will handle all requests the DUM does not + mSipStack->registerTransactionUser(*mProxy); + + if(mRegistrar) + { + mRegistrar->setProxy(mProxy); + } + return true; +} + +void +ReproRunner::populateRegistrations() +{ + assert(mRegistrationPersistenceManager); + assert(mProxyConfig); + assert(mProxyConfig->getDataStore()); + + // Copy contacts from the StaticRegStore to the RegistrationPersistanceManager + StaticRegStore::StaticRegRecordMap& staticRegList = mProxyConfig->getDataStore()->mStaticRegStore.getStaticRegList(); + StaticRegStore::StaticRegRecordMap::iterator it = staticRegList.begin(); + for(; it != staticRegList.end(); it++) + { + try + { + Uri aor(it->second.mAor); + + ContactInstanceRecord rec; + rec.mContact = NameAddr(it->second.mContact); + rec.mSipPath = NameAddrs(it->second.mPath); + rec.mRegExpires = NeverExpire; + rec.mSyncContact = true; // Tag this permanent contact as being a syncronized contact so that it will + // be syncronized to a paired server (this is actually configuration information) + mRegistrationPersistenceManager->updateContact(aor, rec); + } + catch(resip::ParseBuffer::Exception& e) + { + // This should never happen, since the format should be verified before writing to DB + ErrLog(<<"Failed to apply a static registration due to parse error: " << e); + } + } +} + +bool +ReproRunner::createWebAdmin() +{ + assert(!mWebAdmin); + assert(!mWebAdminThread); + int httpPort = mProxyConfig->getConfigInt("HttpPort", 5080); + if (httpPort) + { + mWebAdmin = new WebAdmin(*mProxy, + *mRegistrationPersistenceManager, + mHttpRealm, + httpPort); + if (!mWebAdmin->isSane()) + { + CritLog(<<"Failed to start the WebAdmin"); + cleanupObjects(); + return false; + } + mWebAdminThread = new WebAdminThread(*mWebAdmin); + } + return true; +} + +void +ReproRunner::createRegSync() +{ + assert(!mRegSyncClient); + assert(!mRegSyncServerV4); + assert(!mRegSyncServerV6); + assert(!mRegSyncServerThread); + if(mRegSyncPort != 0) + { + std::list<RegSyncServer*> regSyncServerList; + if(mUseV4) + { + mRegSyncServerV4 = new RegSyncServer(dynamic_cast<InMemorySyncRegDb*>(mRegistrationPersistenceManager), mRegSyncPort, V4); + regSyncServerList.push_back(mRegSyncServerV4); + } + if(mUseV6) + { + mRegSyncServerV6 = new RegSyncServer(dynamic_cast<InMemorySyncRegDb*>(mRegistrationPersistenceManager), mRegSyncPort, V6); + regSyncServerList.push_back(mRegSyncServerV6); + } + if(!regSyncServerList.empty()) + { + mRegSyncServerThread = new RegSyncServerThread(regSyncServerList); + } + Data regSyncPeerAddress(mProxyConfig->getConfigData("RegSyncPeer", "")); + if(!regSyncPeerAddress.empty()) + { + mRegSyncClient = new RegSyncClient(dynamic_cast<InMemorySyncRegDb*>(mRegistrationPersistenceManager), regSyncPeerAddress, mRegSyncPort); + } + } +} + +void +ReproRunner::createCommandServer() +{ + assert(!mCommandServerV4); + assert(!mCommandServerV6); + assert(!mCommandServerThread); + int commandPort = mProxyConfig->getConfigInt("CommandPort", 5081); + if(commandPort != 0) + { + std::list<CommandServer*> commandServerList; + if(mUseV4) + { + mCommandServerV4 = new CommandServer(*this, commandPort, V4); + commandServerList.push_back(mCommandServerV4); + } + if(mUseV6) + { + mCommandServerV6 = new CommandServer(*this, commandPort, V6); + commandServerList.push_back(mCommandServerV6); + } + if(!commandServerList.empty()) + { + mCommandServerThread = new CommandServerThread(commandServerList); + } + } +} + +Data +ReproRunner::addDomains(TransactionUser& tu, bool log) +{ + assert(mProxyConfig); + Data realm; + + std::vector<Data> configDomains; + if(mProxyConfig->getConfigValue("Domains", configDomains)) + { + for (std::vector<Data>::const_iterator i=configDomains.begin(); + i != configDomains.end(); ++i) + { + if(log) InfoLog (<< "Adding domain " << *i << " from command line"); + tu.addDomain(*i); + if ( realm.empty() ) + { + realm = *i; + } + } + } + + const ConfigStore::ConfigData& dList = mProxyConfig->getDataStore()->mConfigStore.getConfigs(); + for (ConfigStore::ConfigData::const_iterator i=dList.begin(); + i != dList.end(); ++i) + { + if(log) InfoLog (<< "Adding domain " << i->second.mDomain << " from config"); + tu.addDomain( i->second.mDomain ); + if ( realm.empty() ) + { + realm = i->second.mDomain; + } + } + + /* All of this logic has been commented out - the sysadmin must explicitly + add any of the items below to the Domains config option in repro.config + + Data localhostname(DnsUtil::getLocalHostName()); + if(log) InfoLog (<< "Adding local hostname domain " << localhostname ); + tu.addDomain(localhostname); + if ( realm.empty() ) + { + realm = localhostname; + } + + if(log) InfoLog (<< "Adding localhost domain."); + tu.addDomain("localhost"); + if ( realm.empty() ) + { + realm = "localhost"; + } + + list<pair<Data,Data> > ips = DnsUtil::getInterfaces(); + for ( list<pair<Data,Data> >::const_iterator i=ips.begin(); i!=ips.end(); i++) + { + if(log) InfoLog( << "Adding domain for IP " << i->second << " from interface " << i->first ); + tu.addDomain(i->second); + } + + if(log) InfoLog (<< "Adding 127.0.0.1 domain."); + tu.addDomain("127.0.0.1"); */ + + if( realm.empty() ) + realm = "Unconfigured"; + + return realm; +} + +bool +ReproRunner::addTransports(bool& allTransportsSpecifyRecordRoute) +{ + assert(mProxyConfig); + assert(mSipStack); + allTransportsSpecifyRecordRoute=false; + bool useEmailAsSIP = mProxyConfig->getConfigBool("TLSUseEmailAsSIP", false); + try + { + // Check if advanced transport settings are provided + unsigned int transportNum = 1; + Data settingKeyBase("Transport" + Data(transportNum)); + Data interfaceSettingKey(settingKeyBase + "Interface"); + Data interfaceSettings = mProxyConfig->getConfigData(interfaceSettingKey, "", true); + if(!interfaceSettings.empty()) + { + // Sample config file format for advanced transport settings + // Transport1Interface = 192.168.1.106:5061 + // Transport1Type = TLS + // Transport1TlsDomain = sipdomain.com + // Transport1TlsClientVerification = None + // Transport1RecordRouteUri = sip:sipdomain.com;transport=TLS + // Transport1RcvBufLen = 2000 + + allTransportsSpecifyRecordRoute = true; + + const char *anchor; + while(!interfaceSettings.empty()) + { + Data typeSettingKey(settingKeyBase + "Type"); + Data tlsDomainSettingKey(settingKeyBase + "TlsDomain"); + Data tlsCVMSettingKey(settingKeyBase + "TlsClientVerification"); + Data recordRouteUriSettingKey(settingKeyBase + "RecordRouteUri"); + Data rcvBufSettingKey(settingKeyBase + "RcvBufLen"); + + // Parse out interface settings + ParseBuffer pb(interfaceSettings); + anchor = pb.position(); + pb.skipToChar(':'); + if(!pb.eof()) + { + Data ipAddr; + Data portData; + pb.data(ipAddr, anchor); + pb.skipChar(); + anchor = pb.position(); + pb.skipToEnd(); + pb.data(portData, anchor); + if(!DnsUtil::isIpAddress(ipAddr)) + { + CritLog(<< "Malformed IP-address found in " << interfaceSettingKey << " setting: " << ipAddr); + } + int port = portData.convertInt(); + if(port == 0) + { + CritLog(<< "Invalid port found in " << interfaceSettingKey << " setting: " << port); + } + TransportType tt = Tuple::toTransport(mProxyConfig->getConfigData(typeSettingKey, "UDP")); + if(tt == UNKNOWN_TRANSPORT) + { + CritLog(<< "Unknown transport type found in " << typeSettingKey << " setting: " << mProxyConfig->getConfigData(typeSettingKey, "UDP")); + } + Data tlsDomain = mProxyConfig->getConfigData(tlsDomainSettingKey, ""); + Data tlsCVMValue = mProxyConfig->getConfigData(tlsCVMSettingKey, "NONE"); + SecurityTypes::TlsClientVerificationMode cvm = SecurityTypes::None; + if(isEqualNoCase(tlsCVMValue, "Optional")) + { + cvm = SecurityTypes::Optional; + } + else if(isEqualNoCase(tlsCVMValue, "Mandatory")) + { + cvm = SecurityTypes::Mandatory; + } + else if(!isEqualNoCase(tlsCVMValue, "None")) + { + CritLog(<< "Unknown TLS client verification mode found in " << tlsCVMSettingKey << " setting: " << tlsCVMValue); + } + int rcvBufLen = mProxyConfig->getConfigInt(rcvBufSettingKey, 0); + Transport *t = mSipStack->addTransport(tt, + port, + DnsUtil::isIpV6Address(ipAddr) ? V6 : V4, + StunEnabled, + ipAddr, // interface to bind to + tlsDomain, + Data::Empty, // private key passphrase - not currently used + SecurityTypes::TLSv1, // sslType + 0, // transport flags + cvm, // tls client verification mode + useEmailAsSIP); + + if (t && rcvBufLen>0 ) + { +#if defined(RESIP_SIPSTACK_HAVE_FDPOLL) + // this new method is part of the epoll changeset, + // which isn't commited yet. + t->setRcvBufLen(rcvBufLen); +#else + assert(0); +#endif + } + + Data recordRouteUri = mProxyConfig->getConfigData(recordRouteUriSettingKey, ""); + if(!recordRouteUri.empty()) + { + try + { + if(isEqualNoCase(recordRouteUri, "auto")) // auto generated record route uri + { + if(tt == TLS || tt == DTLS) + { + NameAddr rr; + rr.uri().host()=tlsDomain; + rr.uri().port()=port; + rr.uri().param(resip::p_transport)=resip::Tuple::toDataLower(tt); + t->setRecordRoute(rr); + InfoLog (<< "Transport specific record-route enabled (generated): " << rr); + } + else + { + NameAddr rr; + rr.uri().host()=ipAddr; + rr.uri().port()=port; + rr.uri().param(resip::p_transport)=resip::Tuple::toDataLower(tt); + t->setRecordRoute(rr); + InfoLog (<< "Transport specific record-route enabled (generated): " << rr); + } + } + else + { + NameAddr rr(recordRouteUri); + t->setRecordRoute(rr); + InfoLog (<< "Transport specific record-route enabled: " << rr); + } + } + catch(BaseException& e) + { + ErrLog (<< "Invalid uri provided in " << recordRouteUriSettingKey << " setting (ignoring): " << e); + allTransportsSpecifyRecordRoute = false; + } + } + else + { + allTransportsSpecifyRecordRoute = false; + } + } + else + { + CritLog(<< "Port not specified in " << interfaceSettingKey << " setting: expected format is <IPAddress>:<Port>"); + return false; + } + + // Check if there is another transport + transportNum++; + settingKeyBase = Data("Transport" + Data(transportNum)); + interfaceSettingKey = Data(settingKeyBase + "Interface"); + interfaceSettings = mProxyConfig->getConfigData(interfaceSettingKey, "", true); + } + } + else + { + int udpPort = mProxyConfig->getConfigInt("UDPPort", 5060); + int tcpPort = mProxyConfig->getConfigInt("TCPPort", 5060); + int tlsPort = mProxyConfig->getConfigInt("TLSPort", 5061); + int dtlsPort = mProxyConfig->getConfigInt("DTLSPort", 0); + Data tlsDomain = mProxyConfig->getConfigData("TLSDomainName", ""); + Data tlsCVMValue = mProxyConfig->getConfigData("TLSClientVerification", "NONE"); + SecurityTypes::TlsClientVerificationMode cvm = SecurityTypes::None; + if(isEqualNoCase(tlsCVMValue, "Optional")) + { + cvm = SecurityTypes::Optional; + } + else if(isEqualNoCase(tlsCVMValue, "Mandatory")) + { + cvm = SecurityTypes::Mandatory; + } + else if(!isEqualNoCase(tlsCVMValue, "None")) + { + CritLog(<< "Unknown TLS client verification mode found in TLSClientVerification setting: " << tlsCVMValue); + } + + if (udpPort) + { + if (mUseV4) mSipStack->addTransport(UDP, udpPort, V4, StunEnabled); + if (mUseV6) mSipStack->addTransport(UDP, udpPort, V6, StunEnabled); + } + if (tcpPort) + { + if (mUseV4) mSipStack->addTransport(TCP, tcpPort, V4, StunEnabled); + if (mUseV6) mSipStack->addTransport(TCP, tcpPort, V6, StunEnabled); + } + if (tlsPort) + { + if (mUseV4) mSipStack->addTransport(TLS, tlsPort, V4, StunEnabled, Data::Empty, tlsDomain, Data::Empty, SecurityTypes::TLSv1, 0, cvm, useEmailAsSIP); + if (mUseV6) mSipStack->addTransport(TLS, tlsPort, V6, StunEnabled, Data::Empty, tlsDomain, Data::Empty, SecurityTypes::TLSv1, 0, cvm, useEmailAsSIP); + } + if (dtlsPort) + { + if (mUseV4) mSipStack->addTransport(DTLS, dtlsPort, V4, StunEnabled, Data::Empty, tlsDomain); + if (mUseV6) mSipStack->addTransport(DTLS, dtlsPort, V6, StunEnabled, Data::Empty, tlsDomain); + } + } + } + catch (BaseException& e) + { + std::cerr << "Likely a port is already in use" << endl; + InfoLog (<< "Caught: " << e); + return false; + } + return true; +} + +void +ReproRunner::addProcessor(repro::ProcessorChain& chain, std::auto_ptr<Processor> processor) +{ + chain.addProcessor(processor); +} + +void +ReproRunner::loadCommonNameMappings() +{ + // Already loaded? + if(!mCommonNameMappings.empty()) + return; + + Data mappingsFileName = mProxyConfig->getConfigData("CommonNameMappings", ""); + if(mappingsFileName.empty()) + return; + + InfoLog(<< "trying to load common name mappings from file: " << mappingsFileName); + + ifstream mappingsFile(mappingsFileName.c_str()); + if(!mappingsFile) + { + throw std::runtime_error("Error opening/reading mappings file"); + } + + string sline; + while(getline(mappingsFile, sline)) + { + Data line(sline); + Data cn; + PermittedFromAddresses permitted; + ParseBuffer pb(line); + + pb.skipWhitespace(); + const char * anchor = pb.position(); + if(pb.eof() || *anchor == '#') continue; // if line is a comment or blank then skip it + + // Look for end of name + pb.skipToOneOf("\t"); + pb.data(cn, anchor); + pb.skipChar('\t'); + + while(!pb.eof()) + { + pb.skipWhitespace(); + if(pb.eof()) + continue; + + Data value; + anchor = pb.position(); + pb.skipToOneOf(",\r\n "); + pb.data(value, anchor); + if(!value.empty()) + { + StackLog(<< "Loading CN '" << cn << "', found mapping '" << value << "'"); + permitted.insert(value); + } + if(!pb.eof()) + pb.skipChar(); + } + + DebugLog(<< "Loaded mapping for CN '" << cn << "', " << permitted.size() << " mapping(s)"); + mCommonNameMappings[cn] = permitted; + } +} + +void // Monkeys +ReproRunner::makeRequestProcessorChain(ProcessorChain& chain) +{ + assert(mProxyConfig); + assert(mRegistrationPersistenceManager); + + // Add strict route fixup monkey + addProcessor(chain, std::auto_ptr<Processor>(new StrictRouteFixup)); + + // Add is trusted node monkey + addProcessor(chain, std::auto_ptr<Processor>(new IsTrustedNode(*mProxyConfig))); + + // Add Certificate Authenticator - if required + if(mProxyConfig->getConfigBool("EnableCertificateAuthenticator", false)) + { + // TODO: perhaps this should be initialised from the trusted node + // monkey? Or should the list of trusted TLS peers be independent + // from the trusted node list? + // Should we used the same trustedPeers object that was + // passed to TlsPeerAuthManager perhaps? + std::set<Data> trustedPeers; + loadCommonNameMappings(); + addProcessor(chain, std::auto_ptr<Processor>(new CertificateAuthenticator(*mProxyConfig, mSipStack, trustedPeers, true, mCommonNameMappings))); + } + + // Add digest authenticator monkey - if required + if (!mSipAuthDisabled) + { + assert(mAuthRequestDispatcher); + DigestAuthenticator* da = new DigestAuthenticator(*mProxyConfig, mAuthRequestDispatcher); + + addProcessor(chain, std::auto_ptr<Processor>(da)); + } + + // Add am I responsible monkey + addProcessor(chain, std::auto_ptr<Processor>(new AmIResponsible)); + + // Add RequestFilter monkey + if(!mProxyConfig->getConfigBool("DisableRequestFilterProcessor", false)) + { + if(mAsyncProcessorDispatcher) + { + addProcessor(chain, std::auto_ptr<Processor>(new RequestFilter(*mProxyConfig, mAsyncProcessorDispatcher))); + } + else + { + WarningLog(<< "Could not start RequestFilter Processor due to no worker thread pool (NumAsyncProcessorWorkerThreads=0)"); + } + } + + // [TODO] support for GRUU is on roadmap. When it is added the GruuMonkey will go here + + // [TODO] support for Manipulating Tel URIs is on the roadmap. + // When added, the telUriMonkey will go here + + std::vector<Data> routeSet; + mProxyConfig->getConfigValue("Routes", routeSet); + if (routeSet.empty()) + { + // add static route monkey + addProcessor(chain, std::auto_ptr<Processor>(new StaticRoute(*mProxyConfig))); + } + else + { + // add simple static route monkey + addProcessor(chain, std::auto_ptr<Processor>(new SimpleStaticRoute(*mProxyConfig))); + } + + // Add location server monkey + addProcessor(chain, std::auto_ptr<Processor>(new LocationServer(*mProxyConfig, *mRegistrationPersistenceManager, mAuthRequestDispatcher))); + + // Add message silo monkey + if(mProxyConfig->getConfigBool("MessageSiloEnabled", false)) + { + if(mAsyncProcessorDispatcher && mRegistrar) + { + MessageSilo* silo = new MessageSilo(*mProxyConfig, mAsyncProcessorDispatcher); + mRegistrar->addRegistrarHandler(silo); + addProcessor(chain, std::auto_ptr<Processor>(silo)); + } + else + { + WarningLog(<< "Could not start MessageSilo Processor due to no worker thread pool (NumAsyncProcessorWorkerThreads=0) or Registrar"); + } + } +} + +void // Lemurs +ReproRunner::makeResponseProcessorChain(ProcessorChain& chain) +{ + assert(mProxyConfig); + assert(mRegistrationPersistenceManager); + + // Add outbound target handler lemur + addProcessor(chain, std::auto_ptr<Processor>(new OutboundTargetHandler(*mRegistrationPersistenceManager))); + + if (mProxyConfig->getConfigBool("RecursiveRedirect", false)) + { + // Add recursive redirect lemur + addProcessor(chain, std::auto_ptr<Processor>(new RecursiveRedirect)); + } +} + +void // Baboons +ReproRunner::makeTargetProcessorChain(ProcessorChain& chain) +{ + assert(mProxyConfig); + +#ifndef RESIP_FIXED_POINT + if(mProxyConfig->getConfigBool("GeoProximityTargetSorting", false)) + { + addProcessor(chain, std::auto_ptr<Processor>(new GeoProximityTargetSorter(*mProxyConfig))); + } +#endif + + if(mProxyConfig->getConfigBool("QValue", true)) + { + // Add q value target handler baboon + addProcessor(chain, std::auto_ptr<Processor>(new QValueTargetHandler(*mProxyConfig))); + } + + // Add simple target handler baboon + addProcessor(chain, std::auto_ptr<Processor>(new SimpleTargetHandler)); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/ReproRunner.hxx b/src/libs/resiprocate/repro/ReproRunner.hxx new file mode 100644 index 00000000..41b96879 --- /dev/null +++ b/src/libs/resiprocate/repro/ReproRunner.hxx @@ -0,0 +1,166 @@ +#if !defined(RESIP_REPRORUNNER_HXX) +#define RESIP_REPRORUNNER_HXX + +#include "rutil/Data.hxx" +#include "rutil/ServerProcess.hxx" +#include "resip/dum/TlsPeerAuthManager.hxx" +#include <memory> + +namespace resip +{ + class TransactionUser; + class SipStack; + class RegistrationPersistenceManager; + class FdPollGrp; + class AsyncProcessHandler; + class ThreadIf; + class DialogUsageManager; + class CongestionManager; +} + +namespace repro +{ +class ProxyConfig; +class ProcessorChain; +class Dispatcher; +class AbstractDb; +class ProcessorChain; +class Proxy; +class WebAdmin; +class WebAdminThread; +class Registrar; +class CertServer; +class RegSyncClient; +class RegSyncServer; +class RegSyncServerThread; +class CommandServer; +class CommandServerThread; +class Processor; + +class ReproRunner : public resip::ServerProcess +{ +public: + ReproRunner(); + virtual ~ReproRunner(); + + virtual bool run(int argc, char** argv); + virtual void shutdown(); + virtual void restart(); // brings everydown and then backup again - leaves InMemoryRegistrationDb intact + + virtual Proxy* getProxy() { return mProxy; } + +protected: + virtual void cleanupObjects(); + + virtual bool createSipStack(); + virtual bool createDatastore(); + virtual bool createProxy(); + virtual void populateRegistrations(); + virtual bool createWebAdmin(); + virtual void createDialogUsageManager(); + virtual void createRegSync(); + virtual void createCommandServer(); + + virtual resip::Data addDomains(resip::TransactionUser& tu, bool log); + virtual bool addTransports(bool& allTransportsSpecifyRecordRoute); + // Override this and examine the processor name to selectively add custom processors before or after the standard ones + virtual void addProcessor(repro::ProcessorChain& chain, std::auto_ptr<repro::Processor> processor); + virtual void makeRequestProcessorChain(repro::ProcessorChain& chain); + virtual void makeResponseProcessorChain(repro::ProcessorChain& chain); + virtual void makeTargetProcessorChain(repro::ProcessorChain& chain); + + virtual void loadCommonNameMappings(); + + bool mRunning; + bool mRestarting; + int mArgc; + char** mArgv; + bool mThreadedStack; + resip::Data mHttpRealm; + bool mSipAuthDisabled; + bool mUseV4; + bool mUseV6; + int mRegSyncPort; + ProxyConfig* mProxyConfig; + resip::FdPollGrp* mFdPollGrp; + resip::AsyncProcessHandler* mAsyncProcessHandler; + resip::SipStack* mSipStack; + resip::ThreadIf* mStackThread; + AbstractDb* mAbstractDb; + AbstractDb* mRuntimeAbstractDb; + resip::RegistrationPersistenceManager* mRegistrationPersistenceManager; + Dispatcher* mAuthRequestDispatcher; + Dispatcher* mAsyncProcessorDispatcher; + ProcessorChain* mMonkeys; + ProcessorChain* mLemurs; + ProcessorChain* mBaboons; + Proxy* mProxy; + WebAdmin* mWebAdmin; + WebAdminThread* mWebAdminThread; + Registrar* mRegistrar; + resip::DialogUsageManager* mDum; + resip::ThreadIf* mDumThread; + CertServer* mCertServer; + RegSyncClient* mRegSyncClient; + RegSyncServer* mRegSyncServerV4; + RegSyncServer* mRegSyncServerV6; + RegSyncServerThread* mRegSyncServerThread; + CommandServer* mCommandServerV4; + CommandServer* mCommandServerV6; + CommandServerThread* mCommandServerThread; + resip::CongestionManager* mCongestionManager; + resip::CommonNameMappings mCommonNameMappings; +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/ReproServerAuthManager.cxx b/src/libs/resiprocate/repro/ReproServerAuthManager.cxx new file mode 100644 index 00000000..cfc29d69 --- /dev/null +++ b/src/libs/resiprocate/repro/ReproServerAuthManager.cxx @@ -0,0 +1,123 @@ +#include <cassert> + +#include "resip/dum/DialogUsageManager.hxx" +#include "repro/ReproServerAuthManager.hxx" +#include "resip/dum/ServerAuthManager.hxx" +#include "resip/dum/UserAuthInfo.hxx" +#include "repro/UserStore.hxx" +#include "repro/AclStore.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +using namespace resip; +using namespace repro; + + +ReproServerAuthManager::ReproServerAuthManager(DialogUsageManager& dum, + Dispatcher* authRequestDispatcher, + AclStore& aclDb, + bool useAuthInt, + bool rejectBadNonces, + bool challengeThirdParties): + ServerAuthManager(dum, dum.dumIncomingTarget(), challengeThirdParties), + mDum(dum), + mAuthRequestDispatcher(authRequestDispatcher), + mAclDb(aclDb), + mUseAuthInt(useAuthInt), + mRejectBadNonces(rejectBadNonces) +{ +} + +ReproServerAuthManager::~ReproServerAuthManager() +{ +} + +bool +ReproServerAuthManager::useAuthInt() const +{ + return mUseAuthInt; +} + +bool +ReproServerAuthManager::rejectBadNonces() const +{ + return mRejectBadNonces; +} + +ServerAuthManager::AsyncBool +ReproServerAuthManager::requiresChallenge(const SipMessage& msg) +{ + assert(msg.isRequest()); + if(!mAclDb.isRequestTrusted(msg)) + { + return ServerAuthManager::requiresChallenge(msg); + } + else + { + return False; + } +} + +void +ReproServerAuthManager::requestCredential(const Data& user, + const Data& realm, + const SipMessage& msg, + const Auth& auth, + const Data& transactionId ) +{ + // Build a UserAuthInfo object and pass to UserAuthGrabber to have a1 password filled in + UserAuthInfo* async = new UserAuthInfo(user,realm,transactionId,&mDum); + std::auto_ptr<ApplicationMessage> app(async); + mAuthRequestDispatcher->post(app); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/ReproServerAuthManager.hxx b/src/libs/resiprocate/repro/ReproServerAuthManager.hxx new file mode 100644 index 00000000..5cd7cf77 --- /dev/null +++ b/src/libs/resiprocate/repro/ReproServerAuthManager.hxx @@ -0,0 +1,101 @@ +#if !defined(REPRO_SERVERAUTHMANAGER_HXX) +#define REPRO_SERVERAUTHMANAGER_HXX + +#include <map> + +#include "resip/stack/Auth.hxx" +#include "resip/stack/Message.hxx" +#include "resip/dum/UserProfile.hxx" +#include "resip/dum/ServerAuthManager.hxx" +#include "repro/Dispatcher.hxx" + +namespace resip +{ +class Profile; +class DialogUsageManager; +} + +namespace repro +{ +class AclStore; + +class ReproServerAuthManager: public resip::ServerAuthManager +{ + public: + ReproServerAuthManager(resip::DialogUsageManager& dum, + Dispatcher* authRequestDispatcher, + AclStore& aclDb, + bool useAuthInt, + bool rejectBadNonces, + bool challengeThirdParties); + + ~ReproServerAuthManager(); + + protected: + // this call back should async cause a post of UserAuthInfo + virtual void requestCredential(const resip::Data& user, + const resip::Data& realm, + const resip::SipMessage& msg, + const resip::Auth& auth, + const resip::Data& transactionId ); + + virtual bool useAuthInt() const; + virtual bool rejectBadNonces() const; + virtual AsyncBool requiresChallenge(const resip::SipMessage& msg); + + private: + resip::DialogUsageManager& mDum; + Dispatcher* mAuthRequestDispatcher; + AclStore& mAclDb; + bool mUseAuthInt; + bool mRejectBadNonces; +}; + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/ReproVersion.cxx b/src/libs/resiprocate/repro/ReproVersion.cxx new file mode 100644 index 00000000..4004cb63 --- /dev/null +++ b/src/libs/resiprocate/repro/ReproVersion.cxx @@ -0,0 +1,159 @@ + +/* +** Build system provides these. +** VERSION comes from a file and is the 'marketing' version +** of repro (major.minor) +** BUILD_REV is the subversion svnversion output (lightly formatted) +** (ends in M if there are local modifications) +** RELEASE_VERSION +*/ + +#include <string> + +#if defined(TESTDRIVER) +#include <iostream> +#endif + +#include "repro/ReproVersion.hxx" +#include "repro/reproInfo.hxx" +#if !defined(REPRO_BUILD_REV) +# define REPRO_BUILD_REV "000000" +#endif + +#if !defined(REPRO_BUILD_HOST) +# define REPRO_BUILD_HOST "unknown.invalid" +#endif + +#if !defined(REPRO_RELEASE_VERSION) +# define REPRO_RELEASE_VERSION "0.0" +#endif + +#if !defined(REPRO_NAME) +# define REPRO_NAME "Repro" +#endif + + + +namespace repro +{ + VersionUtils::VersionUtils(): + mBuildHost(REPRO_BUILD_HOST), + mReleaseVersion(REPRO_RELEASE_VERSION), + mScmRevision(REPRO_BUILD_REV), + mDisplayVersion(REPRO_NAME), + mBuildStamp(REPRO_BUILD_REV) + { + mDisplayVersion += ' '; + mDisplayVersion += mReleaseVersion; + mDisplayVersion += '/'; + + mBuildStamp += '@'; + mBuildStamp += mBuildHost; + + mDisplayVersion += mBuildStamp; + } + + VersionUtils* VersionUtils::sVU = 0; + + const VersionUtils& + VersionUtils::instance() + { + if (sVU == 0) + { + sVU = new VersionUtils; + } + return *sVU; + } + + VersionUtils::~VersionUtils() {}; + + const std::string& + VersionUtils::buildStamp() const + { + return mBuildStamp; + } + + const std::string& + VersionUtils::releaseVersion() const + { + return mReleaseVersion; + } + + + const std::string& + VersionUtils::buildHost() const + { + return mBuildHost; + } + + const std::string& + VersionUtils::displayVersion() const + { + return mDisplayVersion; + } + + const std::string& + VersionUtils::scmRevision() const + { + return mScmRevision; + } + +}; + + +#if defined(TESTDRIVER) +int main() +{ +#define T(x) std::cout << #x << " = " << repro::VersionUtils::instance().x() << std::endl; + T(displayVersion); + T(buildStamp); + T(scmRevision); + T(releaseVersion); + T(buildHost); + return 0; +} +#undef T +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/ReproVersion.hxx b/src/libs/resiprocate/repro/ReproVersion.hxx new file mode 100644 index 00000000..b58fc044 --- /dev/null +++ b/src/libs/resiprocate/repro/ReproVersion.hxx @@ -0,0 +1,70 @@ +#if !defined(REPROVERSION_HXX) +#define REPROVERSION_HXX + +namespace repro +{ + class VersionUtils + { + public: + static const VersionUtils & instance(); + const std::string & displayVersion() const; + const std::string & buildStamp() const; + const std::string & scmRevision() const; + const std::string & releaseVersion() const; + const std::string & buildHost() const; + private: + VersionUtils(); + virtual ~VersionUtils(); + std::string mBuildHost; + std::string mReleaseVersion; + std::string mScmRevision; + std::string mDisplayVersion; + std::string mBuildStamp; + static VersionUtils * sVU; + + }; +}; +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/RequestContext.cxx b/src/libs/resiprocate/repro/RequestContext.cxx new file mode 100644 index 00000000..02c9bfee --- /dev/null +++ b/src/libs/resiprocate/repro/RequestContext.cxx @@ -0,0 +1,1114 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <iostream> + +#include "repro/Proxy.hxx" +#include "repro/RequestContext.hxx" +#include "resip/stack/ExtensionParameter.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/TransactionTerminated.hxx" +#include "resip/stack/SipStack.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/InteropHelper.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/Logger.hxx" + +#include "repro/Ack200DoneMessage.hxx" +#include "repro/ForkControlMessage.hxx" +#include "repro/ProcessorMessage.hxx" +#include "rutil/WinLeakCheck.hxx" + +// Remove warning about 'this' use in initiator list +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) // using this in base member initializer list +#endif + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +RequestContext::RequestContext(Proxy& proxy, + ProcessorChain& requestP, + ProcessorChain& responseP, + ProcessorChain& targetP) : + mHaveSentFinalResponse(false), + mOriginalRequest(0), + mCurrentEvent(0), + mAck200ToRetransmit(0), + mRequestProcessorChain(requestP), + mResponseProcessorChain(responseP), + mTargetProcessorChain(targetP), + mTransactionCount(1), + mProxy(proxy), + mResponseContext(*this), + mTCSerial(0), + mSessionCreatedEventSent(false), + mSessionEstablishedEventSent(false), + mKeyValueStore(*Proxy::getRequestKeyValueStoreKeyAllocator()) +{ + mInitialTimerCSet=false; +} + +RequestContext::~RequestContext() +{ + DebugLog (<< "RequestContext::~RequestContext() " << this); + if (mOriginalRequest != mCurrentEvent) + { + delete mOriginalRequest; + mOriginalRequest = 0; + } + delete mCurrentEvent; + mCurrentEvent = 0; + delete mAck200ToRetransmit; + mAck200ToRetransmit=0; +} + + +void +RequestContext::process(resip::TransactionTerminated& msg) +{ + InfoLog (<< "RequestContext::process(TransactionTerminated) " + << msg.getTransactionId() << " : " << *this); + + if (msg.isClientTransaction()) + { + mResponseContext.removeClientTransaction(msg.getTransactionId()); + } + mTransactionCount--; + if (mTransactionCount == 0) + { + delete this; + } +} + +void +RequestContext::process(std::auto_ptr<resip::SipMessage> sipMessage) +{ + bool original = false; + InfoLog (<< "RequestContext::process(SipMessage) " << sipMessage->getTransactionId()); + + if (mCurrentEvent != mOriginalRequest) + { + delete mCurrentEvent; + } + mCurrentEvent = sipMessage.release(); + + SipMessage* sip = dynamic_cast<SipMessage*>(mCurrentEvent); + if (!mOriginalRequest) + { + assert(sip); + mOriginalRequest=sip; + original = true; + mResponseContext.mIsClientBehindNAT = InteropHelper::getClientNATDetectionMode() != InteropHelper::ClientNATDetectionDisabled && + Helper::isClientBehindNAT(*sip, + InteropHelper::getClientNATDetectionMode() == InteropHelper::ClientNATDetectionPrivateToPublicOnly); + + // RFC 3261 Section 16.4 + try + { + fixStrictRouterDamage(); + removeTopRouteIfSelf(); + } + catch(resip::ParseException& e) + { + InfoLog(<<"Parse failure Exception caught: " << e); + if(mOriginalRequest->method()==ACK) + { + postAck200Done(); + } + else + { + resip::SipMessage response; + Helper::makeResponse(response, *mOriginalRequest,400); + response.header(h_StatusLine).reason()="Malformed header-field-value: " + e.getMessage(); + sendResponse(response); + } + return; + } + catch(resip::BaseException& e) + { + ErrLog(<<"Exception caught: " << e); + if(mOriginalRequest->method()==ACK) + { + postAck200Done(); + } + else + { + resip::SipMessage response; + Helper::makeResponse(response, *mOriginalRequest,500); + response.header(h_StatusLine).reason()="Server error: " + e.getMessage(); + sendResponse(response); + } + return; + } + } + + if (sip->isRequest()) + { + DebugLog(<<"Got a request."); + bool postProcess=false; + switch(mOriginalRequest->method()) + { + case ACK: + processRequestAckTransaction(sip,original); + break; + case INVITE: + postProcess=processRequestInviteTransaction(sip,original); + if(postProcess) doPostRequestProcessing(sip,original); + break; + default: + postProcess=processRequestNonInviteTransaction(sip,original); + if(postProcess) doPostRequestProcessing(sip,original); + } + } + else if (sip->isResponse()) + { + assert(!original); + bool postProcess=false; + switch(mOriginalRequest->method()) + { + case ACK: + // !bwc! Got a response to an ACK? + // Why did the stack let this through? + assert(0); + break; + case INVITE: + postProcess=processResponseInviteTransaction(sip); + break; + default: + postProcess=processResponseNonInviteTransaction(sip); + } + + if(postProcess) + { + doPostResponseProcessing(sip); + } + } +} + +bool +RequestContext::processRequestInviteTransaction(SipMessage* msg, bool original) +{ + bool doPostProcess=false; + assert(msg->isRequest()); + + if(original) + { + assert(msg->method()==INVITE); + + try + { + Processor::processor_action_t ret=Processor::Continue; + ret = mRequestProcessorChain.process(*this); + if(ret!=Processor::WaitingForEvent && !mHaveSentFinalResponse) + { + doPostProcess=true; + } + } + catch(resip::BaseException& e) + { + SipMessage response; + Helper::makeResponse(response,*mOriginalRequest,500); + response.header(h_StatusLine).reason()="Server error: " + e.getMessage(); + ErrLog(<<"Exception caught: " << e); + sendResponse(response); + } + } + else + { + if(msg->method()==CANCEL) + { + if(mSessionCreatedEventSent && !mSessionEstablishedEventSent) + { + getProxy().doSessionAccounting(*msg, true /* received */, *this); + } + mResponseContext.processCancel(*msg); + doPostProcess=true; + } + else if(msg->method()==ACK) + { + // .bwc. The stack should not be forwarding ACK/failure to the TU, + // nor should we be getting a bad ACK/200. (There is code further + // up that makes bad ACK/200 look like a new transaction, like it + // is supposed to be.) + // TODO Remove this code block entirely. + assert(0); + + DebugLog(<<"This ACK has the same tid as the original INVITE."); + DebugLog(<<"The reponse we sent back was a " + << mResponseContext.mBestResponse.header(h_StatusLine).statusCode()); + // .bwc. Since this is not an ACK transaction, the stack will let + // us know when we need to clean up. + if(!mHaveSentFinalResponse) + { + // .bwc. Whoa, something went wrong here. We got an ACK, but we + // haven't sent back a final response. The stack shouldn't have + // allowed this through! + ErrLog(<<"Got an ACK, but haven't sent a final response. " + "What happened here?"); + } + else if(mResponseContext.mBestResponse.header(h_StatusLine).statusCode() / 100 == 2) + { + InfoLog(<<"Got an ACK within an INVITE transaction, but our " + "response was a 2xx. Someone didn't change their tid " + "like they were supposed to..."); + if( + ( + msg->exists(h_Routes) && + !msg->header(h_Routes).empty() + ) + || + ( + !getProxy().isMyUri(msg->header(h_RequestLine).uri()) && + (msg->header(h_From).isWellFormed() && getProxy().isMyUri(msg->header(h_From).uri())) + ) + ) + { + forwardAck200(*msg); + } + } + } + else + { + // .bwc. The stack should not have done this. This indicates either a + // bug in the stack, processInvite was called in a non-invite + // RequestContext, or this RequestContext was leaked and hit with a + // subsequent transaction + ErrLog(<<"We got an unexpected request from " + "the stack in an invite RequestContext. " + "Why?" + " Orig: " << mOriginalRequest->brief() << + " This: " << msg->brief()); + assert(0); + } + } + + return doPostProcess; + +} + +bool +RequestContext::processRequestNonInviteTransaction(SipMessage* msg, bool original) +{ + assert(msg->isRequest()); + bool doPostProcess=false; + + if(original) + { + assert(msg->method()==mOriginalRequest->method()); + try + { + Processor::processor_action_t ret=Processor::Continue; + ret = mRequestProcessorChain.process(*this); + if(ret!=Processor::WaitingForEvent && !mHaveSentFinalResponse) + { + doPostProcess=true; + } + } + catch(resip::BaseException& e) + { + SipMessage response; + Helper::makeResponse(response,*mOriginalRequest,500); + response.header(h_StatusLine).reason()="Server error: " + e.getMessage(); + ErrLog(<<"Exception caught: " << e); + sendResponse(response); + } + } + else + { + if(msg->method()==CANCEL) + { + // .bwc. Got a CANCEL in a non-invite transaction. Just respond with + // 200 and ignore. + SipMessage response; + Helper::makeResponse(response,*msg,200); + send(response); + } + else + { + // ?bwc? We got a second request from the stack. Why? + ErrLog(<<"We got a second non-invite request from the" + " stack in an already-established non-" + "invite RequestContext. " + "Why?" + " Orig: " << mOriginalRequest->brief() << + " This: " << msg->brief()); + if(msg->method()!=ACK) + { + SipMessage response; + Helper::makeResponse(response,*msg,500); + response.header(h_StatusLine).reason()="Server error: got an " + "unexpected request in a non-invite RequestContext"; + send(response); + } + assert(0); + } + } + + return doPostProcess; +} + +void +RequestContext::processRequestAckTransaction(SipMessage* msg, bool original) +{ + assert(msg->isRequest()); + if(msg->method()!=ACK) + { + // !bwc! Somebody collided with an ACK/200. Send a failure response. + SipMessage response; + Helper::makeResponse(response,*msg,400); + response.header(h_StatusLine).reason()="Transaction-id collision"; + send(response); + return; + } + + DebugLog(<<"This ACK has its own tid."); + + try + { + // .slg. look at mOriginalRequest for Routes since removeTopRouteIfSelf() is only called on mOriginalRequest + if((!mOriginalRequest->exists(h_Routes) || mOriginalRequest->header(h_Routes).empty()) && + getProxy().isMyUri(msg->header(h_RequestLine).uri())) + { + // .bwc. Someone sent an ACK with us in the Request-Uri, and no + // Route headers (after we have removed ourself). We will never perform + // location service or retargeting on an ACK, and we shouldn't send + // it to ourselves. So, just drop the thing. + handleSelfAimedStrayAck(msg); + } + // Note: mTopRoute is only populated if RemoveTopRouteIfSelf successfully removes the top route. + else if(!mTopRoute.uri().host().empty() || getProxy().isMyUri(msg->header(h_From).uri())) + { + // Top most route is us, or From header uri is ours. Note: The From check is + // required to interoperate with endpoints that configure outbound proxy + // settings, and do not place the outbound proxy in a Route header. + mResponseContext.cancelAllClientTransactions(); + forwardAck200(*mOriginalRequest); + } + else + { + // .slg. Someone is using us to relay an ACK, but we are not the + // top-most route and the host in From isn't ours. Refusing to do so. + InfoLog(<<"Top most route or From header are not ours. We do not allow relaying ACKs. Dropping it..."); + } + } + catch(resip::ParseException&) + { + InfoLog(<<"Parse error processing ACK. Dropping it..."); + } + + if(original) // Only queue Ack200Done if this is the original request + { + postAck200Done(); + } +} + +void +RequestContext::doPostRequestProcessing(SipMessage* msg, bool original) +{ + assert(msg->isRequest()); + + // .bwc. This is called after an incoming request is done processing. This + // IS NOT called if the request-processor chain goes async, and IS NOT called + // when async work finishes. The intent of this function is to prompt either: + // 1) The initiation of new client transactions. + // 2) Failing 1, the sending of a failure response to the original request. + + + // if target list is empty return a 480 + if (!mResponseContext.hasTargets()) + { + // make 480, send, dispose of memory + resip::SipMessage response; + InfoLog (<< *this << ": no targets for " + << mOriginalRequest->header(h_RequestLine).uri() + << " send 480"); + Helper::makeResponse(response, *mOriginalRequest, 480); + sendResponse(response); + } + else + { + Processor::processor_action_t ret=Processor::Continue; + InfoLog (<< *this << " there are " + << mResponseContext.mCandidateTransactionMap.size() + << " candidates -> continue"); + + try + { + ret = mTargetProcessorChain.process(*this); + } + catch(resip::BaseException& e) + { + if(mResponseContext.hasActiveTransactions()) + { + // .bwc. Whoops. We may have just forwarded garbage upstream. + // TODO is it appropriate to try to CANCEL here? + ErrLog(<<"Server error caught after" + " request was forwarded. Exception was: "<<e); + } + else + { + mResponseContext.clearCandidateTransactions(); + SipMessage response; + Helper::makeResponse(response,*mOriginalRequest,500); + response.header(h_StatusLine).reason()="Server error: " + e.getMessage(); + ErrLog(<<"Exception caught: " << e); + sendResponse(response); + } + } + + if(ret != Processor::WaitingForEvent && + !mHaveSentFinalResponse && + !mResponseContext.hasActiveTransactions()) + { + if(mResponseContext.hasCandidateTransactions()) + { + // Someone forgot to start any of the targets they just added. + // Send a 500 response + resip::SipMessage response; + ErrLog( << "In RequestContext, target processor chain appears " + << "to have failed to process any targets. (Bad baboon?)" + << "Sending a 500 response for this request:" + << mOriginalRequest->header(h_RequestLine).uri() ); + Helper::makeResponse(response, *mOriginalRequest, 500); + sendResponse(response); + } + else + { + ErrLog(<< "In RequestContext, request processor chain " + << " appears to have added Targets, but all of these Targets" + << " are already Terminated. Further, there are no candidate" + << " Targets. (Bad monkey?)"); + // Send best response + mResponseContext.forwardBestResponse(); + } + } + } +} + +bool +RequestContext::processResponseInviteTransaction(SipMessage* msg) +{ + assert(msg->isResponse()); + + bool doPostProcessing=false; + resip::Data tid(msg->getTransactionId()); + tid.lowercase(); + if(msg->method()==INVITE) + { + try + { + Processor::processor_action_t ret = Processor::Continue; + ret = mResponseProcessorChain.process(*this); + assert(ret != Processor::WaitingForEvent); + + if (ret == Processor::Continue) + { + doPostProcessing=true; + } + else + { + // This means the response has been eaten. Do not forward back. + mResponseContext.terminateClientTransaction(tid); + } + } + catch(resip::ParseException& e) + { + InfoLog(<<"Garbage in response; dropping message. " << e); + mResponseContext.terminateClientTransaction(tid); + } + catch(resip::BaseException& e) + { + ErrLog(<<"Exception thrown in response processor chain: " << e); + // ?bwc? TODO what do we do here? Continue processing? Give up? + mResponseContext.terminateClientTransaction(tid); + } + } + else if(msg->method()==CANCEL) + { + // .bwc. Do nothing. + } + else + { + // ?bwc? Is this possible? + assert(0); + } + + return doPostProcessing; +} + +bool +RequestContext::processResponseNonInviteTransaction(SipMessage* msg) +{ + assert(msg->isResponse()); + + resip::Data tid(msg->getTransactionId()); + tid.lowercase(); + bool doPostProcessing=false; + if(msg->method()==mOriginalRequest->method()) + { + try + { + Processor::processor_action_t ret = Processor::Continue; + ret = mResponseProcessorChain.process(*this); + assert(ret != Processor::WaitingForEvent); + + if (ret == Processor::Continue) + { + doPostProcessing=true; + } + else + { + // This means the response has been eaten. Do not forward back. + mResponseContext.terminateClientTransaction(tid); + } + } + catch(resip::ParseException& e) + { + InfoLog(<<"Garbage in response; dropping message. " << e); + mResponseContext.terminateClientTransaction(tid); + } + catch(resip::BaseException& e) + { + ErrLog(<<"Exception thrown in response processor chain: " << e); + // ?bwc? TODO what do we do here? Continue processing? Give up? + mResponseContext.terminateClientTransaction(tid); + } + } + else + { + // ?bwc? Is this possible? + assert(0); + } + + return doPostProcessing; + +} + +void +RequestContext::doPostResponseProcessing(SipMessage* msg) +{ + bool nit408 = msg->method() != INVITE && msg->header(resip::h_StatusLine).statusCode() == 408; + + mResponseContext.processResponse(*msg); + + //If everything we have tried so far has gone quiescent, we + //need to fire up some more Targets (if there are any left) + mTargetProcessorChain.process(*this); + + if(!mHaveSentFinalResponse && + !mResponseContext.hasActiveTransactions()) + { + if(mResponseContext.hasCandidateTransactions()) + { + resip::SipMessage response; + Helper::makeResponse(response, *mOriginalRequest, 500); + // The last active transaction has ended, and the response processors + // did not start any of the pending transactions. + // Send a 500 response. + ErrLog( << "In RequestContext, after processing a sip response:" + << " We have no active transactions, but there are candidates " + << " remaining. (Bad baboon?)" + << "Sending a 500 response for this request:" + << mOriginalRequest->header(h_RequestLine).uri() ); + sendResponse(response); + } + else if(nit408) + { + InfoLog(<<"In RequestContext, after processing a NIT/408, all" + << " transactions are terminated. In this case, we do not send a" + << " final response."); + } + else + { + ErrLog(<<"In RequestContext, after processing " + << "a sip response (_not_ a NIT/408): all transactions are terminated," + << " but we have not sent a final response. (What happened here?) "); + + // Send best response + mResponseContext.forwardBestResponse(); + } + } +} + +void +RequestContext::process(std::auto_ptr<ApplicationMessage> app) +{ + InfoLog (<< "RequestContext::process(ApplicationMessage) " << *app); + + if (mCurrentEvent != mOriginalRequest) + { + delete mCurrentEvent; + } + mCurrentEvent = app.release(); + + Ack200DoneMessage* ackDone = dynamic_cast<Ack200DoneMessage*>(mCurrentEvent); + if (ackDone) + { + delete this; + return; + } + + TimerCMessage* tc = dynamic_cast<TimerCMessage*>(mCurrentEvent); + + if(tc) + { + if(tc->mSerial == mTCSerial) + { + mResponseContext.processTimerC(); + } + + return; + } + + ProcessorMessage* proc=dynamic_cast<ProcessorMessage*>(mCurrentEvent); + + if(proc) + { + Processor::ChainType type = proc->chainType(); + Processor::processor_action_t ret=Processor::Continue; + + switch(type) + { + case Processor::REQUEST_CHAIN: + try + { + ret = mRequestProcessorChain.process(*this); + } + catch(resip::BaseException& e) + { + resip::SipMessage response; + Helper::makeResponse(response,*mOriginalRequest,500); + response.header(h_StatusLine).reason()="Server error: " + e.getMessage(); + ErrLog(<<"Exception caught: " << e); + sendResponse(response); + } + + if(ret != Processor::WaitingForEvent && !mHaveSentFinalResponse) + { + if (!mResponseContext.hasTargets()) + { + // make 480, send, dispose of memory + resip::SipMessage response; + Helper::makeResponse(response, *mOriginalRequest, 480); + InfoLog (<< *this << ": no targets for " + << mOriginalRequest->header(h_RequestLine).uri() + << " send 480"); + sendResponse(response); + } + else + { + InfoLog (<< *this << " there are " + << mResponseContext.mCandidateTransactionMap.size() + << " candidates -> continue"); + + try + { + ret = mTargetProcessorChain.process(*this); + } + catch(resip::BaseException& e) + { + if(mResponseContext.hasActiveTransactions()) + { + // .bwc. Whoops. We may have just forwarded garbage upstream. + // ?bwc? TODO is it appropriate to try to CANCEL here? + ErrLog(<<"Server error caught after" + " request was forwarded. Exception was: "<<e); + } + else + { + mResponseContext.clearCandidateTransactions(); + resip::SipMessage response; + Helper::makeResponse(response,*mOriginalRequest,500); + response.header(h_StatusLine).reason()="Server error: " + e.getMessage(); + ErrLog(<<"Exception caught: " << e); + sendResponse(response); + } + } + + if(ret != Processor::WaitingForEvent && + !mHaveSentFinalResponse && + !mResponseContext.hasActiveTransactions()) + { + if(mResponseContext.hasCandidateTransactions()) + { + resip::SipMessage response; + Helper::makeResponse(response, *mOriginalRequest, 500); + // Someone forgot to start any of the targets they just added. + // Send a 500 response + ErrLog( << "In RequestContext, request and target processor" + << " chains have run, and we have some Candidate Targets," + << " but no active Targets. (Bad baboon?)" + << "Sending a 500 response for this request:" + << mOriginalRequest->header(h_RequestLine).uri() ); + sendResponse(response); + } + else if(mResponseContext.mBestResponse.header(h_StatusLine).statusCode() != 408) + { + ErrLog(<< "In RequestContext, request and target processor " + << "chains have run, and all Targets are now Terminated." + << " However, we have not sent a final response, and our " + << "best final response is not a 408.(What happened here?)"); + + // Send best response + mResponseContext.forwardBestResponse(); + } + } + } + } + break; + + case Processor::RESPONSE_CHAIN: + ret = mResponseProcessorChain.process(*this); + + mTargetProcessorChain.process(*this); + break; + + case Processor::TARGET_CHAIN: + ret = mTargetProcessorChain.process(*this); + break; + + default: + ErrLog(<<"RequestContext " << getTransactionId() << " got a " + << "ProcessorMessage addressed to a non existent chain " + << type); + } + } +} + +void +RequestContext::handleSelfAimedStrayAck(SipMessage* sip) +{ + InfoLog(<<"Stray ACK aimed at us that routes back to us. Dropping it..."); +} + +void +RequestContext::cancelClientTransaction(const resip::Data& tid) +{ + getProxy().getStack().cancelClientInviteTransaction(tid); +} + +void +RequestContext::forwardAck200(const resip::SipMessage& ack) +{ + if(!mAck200ToRetransmit) + { + mAck200ToRetransmit = new SipMessage(ack); + mAck200ToRetransmit->header(h_MaxForwards).value()--; + Helper::processStrictRoute(*mAck200ToRetransmit); + + mAck200ToRetransmit->header(h_Vias).push_front(Via()); + + // .bwc. Check for flow-token + if(!mTopRoute.uri().user().empty()) + { + resip::Tuple dest(Tuple::makeTupleFromBinaryToken(mTopRoute.uri().user().base64decode(), Proxy::FlowTokenSalt)); + if(!(dest==resip::Tuple())) + { + // valid flow token + mAck200ToRetransmit->setDestination(dest); + } + } + } + + send(*mAck200ToRetransmit); +} + +resip::SipMessage& +RequestContext::getOriginalRequest() +{ + return *mOriginalRequest; +} + +const resip::SipMessage& +RequestContext::getOriginalRequest() const +{ + return *mOriginalRequest; +} + +resip::Data +RequestContext::getTransactionId() const +{ + if(mOriginalRequest->mIsBadAck200) + { + static Data ack("ack"); + return mOriginalRequest->getTransactionId()+ack; + } + else + { + return mOriginalRequest->getTransactionId(); + } +} + +resip::Message* +RequestContext::getCurrentEvent() +{ + return mCurrentEvent; +} + +const resip::Message* +RequestContext::getCurrentEvent() const +{ + return mCurrentEvent; +} + +void +RequestContext::setDigestIdentity (const resip::Data& data) +{ + mDigestIdentity = data; +} + +const resip::Data& +RequestContext::getDigestIdentity() const +{ + return mDigestIdentity; +} + +void +RequestContext::updateTimerC() +{ + InfoLog(<<"Updating timer C."); + mTCSerial++; + TimerCMessage* tc = new TimerCMessage(this->getTransactionId(),mTCSerial); + mProxy.postTimerC(std::auto_ptr<TimerCMessage>(tc)); +} + +void +RequestContext::postTimedMessage(std::auto_ptr<resip::ApplicationMessage> msg,int seconds) +{ + mProxy.postMS(msg,seconds); +} + +void +RequestContext::postAck200Done() +{ + assert(mOriginalRequest->method()==ACK); + DebugLog(<<"Posting Ack200DoneMessage"); + // .bwc. This needs to have a timer attached to it. (We need to + // wait until all potential retransmissions of the ACK/200 have + // stopped. However, we must be mindful that we may receive a new, + // non-ACK transaction with the same tid during this time, and make + // sure we don't explode violently when this happens.) + mProxy.postMS( + std::auto_ptr<ApplicationMessage>(new Ack200DoneMessage(getTransactionId())), + 64*resip::Timer::T1); +} + +void +RequestContext::send(SipMessage& msg) +{ + mProxy.send(msg); +} + +void +RequestContext::sendResponse(SipMessage& msg) +{ + assert (msg.isResponse()); + + // We can't respond to an ACK request - so just drop it and generate an Ack200DoneMessage so the request context + // gets cleaned up properly + if(mOriginalRequest->method() == ACK) + { + ErrLog(<<"Posting Ack200DoneMessage: due to sendResponse(). This is probably a bug."); + postAck200Done(); + } + else + { + DebugLog(<< "tid of orig req: " << mOriginalRequest->getTransactionId()); + resip::Data tid; + try + { + tid=msg.getTransactionId(); + } + catch(SipMessage::Exception&) + { + InfoLog(<< "Bad tid in response. Trying to replace with 2543 tid " + "from orig request."); + tid=mOriginalRequest->getRFC2543TransactionId(); + // .bwc. If the original request didn't have a proper transaction- + // id, the response will not either. We need to set the tid in the + // response in order to make sure that this response hits the + // correct transaction down in the stack. + msg.setRFC2543TransactionId(tid); + } + + if(tid!=mOriginalRequest->getTransactionId()) + { + InfoLog(<<"Someone messed with the Via stack in a response. This " + "is not only bad behavior, but potentially malicious. " + "Response came from: " << msg.getSource() << + " Request came from: " << + mOriginalRequest->getSource() << + " Via after modification (in response): " << + msg.header(h_Vias).front() << + " Via before modification (in orig request): " << + mOriginalRequest->header(h_Vias).front()); + // .bwc. Compensate for malicous/broken UAS fiddling with Via stack. + msg.header(h_Vias).front()=mOriginalRequest->header(h_Vias).front(); + } + + DebugLog(<<"Ensuring orig tid matches tid of response: " << + msg.getTransactionId() << " == " << + mOriginalRequest->getTransactionId()); + assert(msg.getTransactionId()==mOriginalRequest->getTransactionId()); + + // .bwc. Provisionals are not final responses, and CANCEL/200 is not a final + //response in this context. + if (msg.header(h_StatusLine).statusCode()>199 && msg.method()!=CANCEL) + { + DebugLog(<<"Sending final response."); + mHaveSentFinalResponse=true; + } + const resip::Data& serverText = mProxy.getServerText(); + if (!serverText.empty() && !msg.exists(h_Server) ) + { + msg.header(h_Server).value() = serverText; + } + if(mSessionCreatedEventSent && !mSessionEstablishedEventSent) + { + getProxy().doSessionAccounting(msg, false /* received */, *this); + } + send(msg); + } +} + +// This function assumes that if ;lr shows up in the RURI, that it's a URI +// we put in a Record-Route header earlier. It will do the wrong thing if +// some other malbehaving implementation lobs something at us with +// ;lr in the RURI and it wasn't us. (from Section 16.4 of RFC 3261) +void +RequestContext::fixStrictRouterDamage() +{ + if(mOriginalRequest->header(h_RequestLine).uri().exists(p_lr)) + { + if (mOriginalRequest->exists(h_Routes) + && !mOriginalRequest->header(h_Routes).empty()) + { + mOriginalRequest->header(h_RequestLine).uri() = mOriginalRequest->header(h_Routes).back().uri(); + mOriginalRequest->header(h_Routes).pop_back(); + } + else + { + //!RjS! When we wire this class for logging, here's a + // place to log a warning + } + } +} + +/** @brief Pops the topmost route if it's us */ +void +RequestContext::removeTopRouteIfSelf() +{ + if(mOriginalRequest->exists(h_Routes) + && !mOriginalRequest->header(h_Routes).empty() + && mProxy.isMyUri(mOriginalRequest->header(h_Routes).front().uri())) + { + // save the top-most Route header field so monkeys can check it later + mTopRoute = mOriginalRequest->header(h_Routes).front(); + + mOriginalRequest->header(h_Routes).pop_front(); + + static ExtensionParameter p_drr("drr"); + if(mTopRoute.uri().exists(p_drr)) + { + if(!mOriginalRequest->header(h_Routes).empty() + && mProxy.isMyUri(mOriginalRequest->header(h_Routes).front().uri())) + { + // .bwc. Do double-record routing logic + mTopRoute = mOriginalRequest->header(h_Routes).front(); + + mOriginalRequest->header(h_Routes).pop_front(); + } + else + { + // ?bwc? Somebody messed with our record-routes. Just ignore? Or + // should we reject? + } + } + } +} + +Proxy& +RequestContext::getProxy() +{ + return mProxy; +} + +ResponseContext& +RequestContext::getResponseContext() +{ + return mResponseContext; +} + +NameAddr& +RequestContext::getTopRoute() +{ + return mTopRoute; +} + +EncodeStream& +repro::operator<<(EncodeStream& strm, const RequestContext& rc) +{ + strm << "numtrans=" << rc.mTransactionCount + << " final=" << rc.mHaveSentFinalResponse; + if(!rc.mDigestIdentity.empty()) strm << " identity=" << rc.mDigestIdentity; + if (rc.mOriginalRequest) strm << " req=" << rc.mOriginalRequest->brief(); + //if (rc.mCurrentEvent) strm << " current=" << rc.mCurrentEvent->brief(); + return strm; +} + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/RequestContext.hxx b/src/libs/resiprocate/repro/RequestContext.hxx new file mode 100644 index 00000000..04181f64 --- /dev/null +++ b/src/libs/resiprocate/repro/RequestContext.hxx @@ -0,0 +1,176 @@ +#if !defined(RESIP_REQUEST_CONTEXT_HXX) +#define RESIP_REQUEST_CONTEXT_HXX + +#include <vector> +#include <iosfwd> +#include "resip/stack/Uri.hxx" +#include "repro/ProcessorChain.hxx" +#include "repro/ResponseContext.hxx" +#include "resip/stack/NameAddr.hxx" +#include "repro/ResponseContext.hxx" +#include "repro/TimerCMessage.hxx" +#include "rutil/resipfaststreams.hxx" +#include "rutil/KeyValueStore.hxx" + +namespace resip +{ +class SipMessage; +class TransactionTerminated; +} + + +namespace repro +{ +class Proxy; + +class RequestContext +{ + public: + RequestContext(Proxy& proxy, + ProcessorChain& requestP, // monkeys + ProcessorChain& responseP, // lemurs + ProcessorChain& targetP); // baboons + virtual ~RequestContext(); + + virtual void process(resip::TransactionTerminated& msg); + virtual void process(std::auto_ptr<resip::SipMessage> sip); + virtual void process(std::auto_ptr<resip::ApplicationMessage> app); + + virtual void handleSelfAimedStrayAck(resip::SipMessage* sip); + virtual void cancelClientTransaction(const resip::Data& tid); + + /// Returns the SipMessage associated with the server transaction + resip::SipMessage& getOriginalRequest(); + const resip::SipMessage& getOriginalRequest() const; + resip::Data getTransactionId() const; + + /** Returns the event that we are currently working on. Use a pointer + since users need to check for null */ + resip::Message* getCurrentEvent(); + const resip::Message* getCurrentEvent() const; + + void setDigestIdentity (const resip::Data&); + const resip::Data& getDigestIdentity() const; + + Proxy& getProxy(); + ResponseContext& getResponseContext(); + + resip::NameAddr& getTopRoute(); + + virtual void send(resip::SipMessage& msg); + void sendResponse(resip::SipMessage& response); + + void forwardAck200(const resip::SipMessage& ack); + void postAck200Done(); + + void updateTimerC(); + bool mInitialTimerCSet; + + void setSessionCreatedEventSent() { mSessionCreatedEventSent = true; } + void setSessionEstablishedEventSent() { mSessionEstablishedEventSent = true; } + + void postTimedMessage(std::auto_ptr<resip::ApplicationMessage> msg,int seconds); + + // Accessor for per-requset extensible state storage for monkeys + resip::KeyValueStore& getKeyValueStore() { return mKeyValueStore; } + + bool mHaveSentFinalResponse; + protected: + resip::SipMessage* mOriginalRequest; + resip::Message* mCurrentEvent; + resip::SipMessage* mAck200ToRetransmit; + ProcessorChain& mRequestProcessorChain; // monkeys + ProcessorChain& mResponseProcessorChain; // lemurs + ProcessorChain& mTargetProcessorChain; // baboons + + bool processRequestInviteTransaction(resip::SipMessage* msg,bool original); + bool processRequestNonInviteTransaction(resip::SipMessage* msg,bool original); + void processRequestAckTransaction(resip::SipMessage* msg,bool original); + void doPostRequestProcessing(resip::SipMessage* msg, bool original); + bool processResponseInviteTransaction(resip::SipMessage* msg); + bool processResponseNonInviteTransaction(resip::SipMessage* msg); + void processResponseAckTransaction(resip::SipMessage* msg); + void doPostResponseProcessing(resip::SipMessage* msg); + + resip::Data mDigestIdentity; + int mTransactionCount; + Proxy& mProxy; + resip::NameAddr mTopRoute; + ResponseContext mResponseContext; + int mTCSerial; + resip::KeyValueStore mKeyValueStore; + bool mSessionCreatedEventSent; + bool mSessionEstablishedEventSent; + + typedef std::vector<ProcessorChain::Chain::iterator> + + /** Stack of iterators used to keep track of where + we are in the request processor chain(s) for + async processing */ + ChainIteratorStack; + ChainIteratorStack mChainIteratorStack; + + void fixStrictRouterDamage(); + void removeTopRouteIfSelf(); + + friend class ResponseContext; + friend EncodeStream& operator<<(EncodeStream& strm, const repro::RequestContext& rc); +}; + +EncodeStream& +operator<<(EncodeStream& strm, const repro::RequestContext& rc); + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/ResponseContext.cxx b/src/libs/resiprocate/repro/ResponseContext.cxx new file mode 100644 index 00000000..10ac16b3 --- /dev/null +++ b/src/libs/resiprocate/repro/ResponseContext.cxx @@ -0,0 +1,1491 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <iostream> + +#include "resip/stack/ExtensionParameter.hxx" +#include "resip/stack/InteropHelper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/SipStack.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Inserter.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/Logger.hxx" +#include "repro/Proxy.hxx" +#include "repro/ResponseContext.hxx" +#include "repro/RequestContext.hxx" +#include "repro/RRDecorator.hxx" +#include "repro/Ack200DoneMessage.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +ResponseContext::ResponseContext(RequestContext& context) : + mRequestContext(context), + mBestPriority(50), + mSecure(false), //context.getOriginalRequest().header(h_RequestLine).uri().scheme() == Symbols::Sips) + mIsClientBehindNAT(false) +{ +} + + +ResponseContext::~ResponseContext() +{ + TransactionMap::iterator i; + + for(i=mTerminatedTransactionMap.begin(); i!=mTerminatedTransactionMap.end();++i) + { + delete i->second; + } + mTerminatedTransactionMap.clear(); + + for(i=mActiveTransactionMap.begin(); i!=mActiveTransactionMap.end();++i) + { + delete i->second; + } + mActiveTransactionMap.clear(); + + for(i=mCandidateTransactionMap.begin(); i!=mCandidateTransactionMap.end();++i) + { + delete i->second; + } + mCandidateTransactionMap.clear(); +} + +resip::Data +ResponseContext::addTarget(const NameAddr& addr, bool beginImmediately) +{ + InfoLog (<< "Adding candidate " << addr); + std::auto_ptr<Target> target(new Target(addr)); + Data tid=target->tid(); + addTarget(target, beginImmediately); + return tid; +} + +bool +ResponseContext::addTarget(std::auto_ptr<repro::Target> target, bool beginImmediately) +{ + if(mRequestContext.mHaveSentFinalResponse || !target.get()) + { + return false; + } + + //Disallow sip: if secure + if(mSecure && target->uri().scheme() != Symbols::Sips) + { + return false; + } + + //Make sure we don't have Targets with an invalid initial state. + if(target->status() != Target::Candidate) + { + return false; + } + + if(beginImmediately) + { + if(isDuplicate(target.get())) + { + return false; + } + + mTargetList.push_back(target->rec()); + + beginClientTransaction(target.get()); + target->status()=Target::Started; + Target* toAdd=target.release(); + mActiveTransactionMap[toAdd->tid()]=toAdd; + } + else + { + if(target->mShouldAutoProcess) // note: for base repro - this is always true + { + std::list<resip::Data> queue; + queue.push_back(target->tid()); + mTransactionQueueCollection.push_back(queue); + } + + Target* toAdd=target.release(); + mCandidateTransactionMap[toAdd->tid()]=toAdd; + } + + return true; +} + +bool +ResponseContext::addTargetBatch(TargetPtrList& targets, + bool highPriority) +{ + std::list<resip::Data> queue; + Target* target=0; + TargetPtrList::iterator it; + + if(mRequestContext.mHaveSentFinalResponse || targets.empty()) + { + for(it=targets.begin();it!=targets.end();it++) + { + delete *it; + } + + targets.clear(); + return false; + } + + for(it=targets.begin();it!=targets.end();it++) + { + target=*it; + + if((!mSecure || target->uri().scheme() == Symbols::Sips) && + target->status() == Target::Candidate) + { + if(target->mShouldAutoProcess) + { + queue.push_back(target->tid()); + } + DebugLog(<<"Adding Target to Candidates: " << target->uri() << " tid=" << target->tid()); + mCandidateTransactionMap[target->tid()]=target; + } + else + { + DebugLog(<<"Bad Target: " << target->uri()); + delete target; + } + } + + targets.clear(); + + if(highPriority) // note: for base repro - this is always false + { + mTransactionQueueCollection.push_front(queue); + } + else + { + mTransactionQueueCollection.push_back(queue); + } + + return true; +} + +bool +ResponseContext::beginClientTransactions() +{ + bool result=false; + + if(mCandidateTransactionMap.empty()) + { + return result; + } + + for (TransactionMap::iterator i=mCandidateTransactionMap.begin(); i != mCandidateTransactionMap.end(); ) + { + if(!isDuplicate(i->second) && !mRequestContext.mHaveSentFinalResponse) + { + mTargetList.push_back(i->second->rec()); // Add to Target list for future duplicate detection + beginClientTransaction(i->second); + result=true; + // see rfc 3261 section 16.6 + //This code moves the Target from mCandidateTransactionMap to mActiveTransactionMap, + //and begins the transaction. + mActiveTransactionMap[i->second->tid()] = i->second; + InfoLog (<< "Creating new client transaction " << i->second->tid() << " -> " << i->second->uri()); + } + else + { + i->second->status() = Target::Terminated; + mTerminatedTransactionMap[i->second->tid()] = i->second; + DebugLog(<<"Found a repeated target."); + } + + TransactionMap::iterator temp=i; + i++; + mCandidateTransactionMap.erase(temp); + } + + return result; +} + +bool +ResponseContext::beginClientTransaction(const resip::Data& tid) +{ + TransactionMap::iterator i = mCandidateTransactionMap.find(tid); + if(i==mCandidateTransactionMap.end()) + { + return false; + } + + if(isDuplicate(i->second) || mRequestContext.mHaveSentFinalResponse) + { + i->second->status() = Target::Terminated; + mTerminatedTransactionMap[i->second->tid()] = i->second; + mCandidateTransactionMap.erase(i); + return false; + } + + mTargetList.push_back(i->second->rec()); // Add to Target list for future duplicate detection + + beginClientTransaction(i->second); + mActiveTransactionMap[i->second->tid()] = i->second; + InfoLog(<< "Creating new client transaction " << i->second->tid() << " -> " << i->second->uri()); + mCandidateTransactionMap.erase(i); + + return true; +} + +bool +ResponseContext::cancelActiveClientTransactions() +{ + if(mRequestContext.mHaveSentFinalResponse) + { + return false; + } + + InfoLog (<< "Cancel all proceeding client transactions: " << (mCandidateTransactionMap.size() + + mActiveTransactionMap.size())); + + if(mActiveTransactionMap.empty()) + { + return false; + } + + // CANCEL INVITE branches + for (TransactionMap::iterator i = mActiveTransactionMap.begin(); + i != mActiveTransactionMap.end(); ++i) + { + cancelClientTransaction(i->second); + } + + return true; + +} + +bool +ResponseContext::cancelAllClientTransactions() +{ + + InfoLog (<< "Cancel ALL client transactions: " << mCandidateTransactionMap.size() + << " pending, " << mActiveTransactionMap.size() << " active."); + + if(mActiveTransactionMap.empty() && mCandidateTransactionMap.empty()) + { + return false; + } + + // CANCEL INVITE branches + if(mRequestContext.getOriginalRequest().method()==INVITE) + { + for (TransactionMap::iterator i = mActiveTransactionMap.begin(); + i != mActiveTransactionMap.end(); ++i) + { + cancelClientTransaction(i->second); + } + } + + clearCandidateTransactions(); + + return true; + +} + +bool +ResponseContext::clearCandidateTransactions() +{ + bool result=false; + for (TransactionMap::iterator j = mCandidateTransactionMap.begin(); + j != mCandidateTransactionMap.end();) + { + result=true; + cancelClientTransaction(j->second); + mTerminatedTransactionMap[j->second->tid()] = j->second; + TransactionMap::iterator temp = j; + j++; + mCandidateTransactionMap.erase(temp); + } + + return result; +} + +bool +ResponseContext::cancelClientTransaction(const resip::Data& tid) +{ + + TransactionMap::iterator i = mActiveTransactionMap.find(tid); + if(mRequestContext.getOriginalRequest().method()==INVITE) + { + if(i!=mActiveTransactionMap.end()) + { + cancelClientTransaction(i->second); + return true; + } + } + + TransactionMap::iterator j = mCandidateTransactionMap.find(tid); + if(j != mCandidateTransactionMap.end()) + { + cancelClientTransaction(j->second); + mTerminatedTransactionMap[tid] = j->second; + mCandidateTransactionMap.erase(j); + return true; + } + + return false; +} + +Target* +ResponseContext::getTarget(const resip::Data& tid) const +{ + // .bwc. This tid is most likely to be found in either the Candidate targets, + // or the Active targets. + TransactionMap::const_iterator pend = mCandidateTransactionMap.find(tid); + if(pend != mCandidateTransactionMap.end()) + { + assert(pend->second->status()==Target::Candidate); + return pend->second; + } + + TransactionMap::const_iterator act = mActiveTransactionMap.find(tid); + if(act != mActiveTransactionMap.end()) + { + assert(!(act->second->status()==Target::Candidate || act->second->status()==Target::Terminated)); + return act->second; + } + + TransactionMap::const_iterator term = mTerminatedTransactionMap.find(tid); + if(term != mTerminatedTransactionMap.end()) + { + assert(term->second->status()==Target::Terminated); + return term->second; + } + + return 0; +} + +const ResponseContext::TransactionMap& +ResponseContext::getCandidateTransactionMap() const +{ + return mCandidateTransactionMap; +} + +bool +ResponseContext::hasCandidateTransactions() const +{ + return !mRequestContext.mHaveSentFinalResponse && !mCandidateTransactionMap.empty(); +} + +bool +ResponseContext::hasActiveTransactions() const +{ + return !mActiveTransactionMap.empty(); +} + +bool +ResponseContext::hasTerminatedTransactions() const +{ + return !mTerminatedTransactionMap.empty(); +} + +bool +ResponseContext::hasTargets() const +{ + return (hasCandidateTransactions() || + hasActiveTransactions() || + hasTerminatedTransactions()); +} + +bool +ResponseContext::areAllTransactionsTerminated() const +{ + return (mCandidateTransactionMap.empty() && mActiveTransactionMap.empty()); +} + +bool +ResponseContext::isCandidate(const resip::Data& tid) const +{ + TransactionMap::const_iterator i=mCandidateTransactionMap.find(tid); + return i!=mCandidateTransactionMap.end(); +} + +bool +ResponseContext::isActive(const resip::Data& tid) const +{ + TransactionMap::const_iterator i=mActiveTransactionMap.find(tid); + return i!=mActiveTransactionMap.end(); +} + +bool +ResponseContext::isTerminated(const resip::Data& tid) const +{ + TransactionMap::const_iterator i=mTerminatedTransactionMap.find(tid); + return i!=mTerminatedTransactionMap.end(); +} + +void +ResponseContext::removeClientTransaction(const resip::Data& transactionId) +{ + // .bwc. This tid will most likely be found in the map of terminated + // transactions, under normal circumstances. + // NOTE: This does not remove the corresponding entry in mTargetList. + // This is the intended behavior, because the same target should not + // be added again later. + + TransactionMap::iterator i = mTerminatedTransactionMap.find(transactionId); + if(i!=mTerminatedTransactionMap.end()) + { + delete i->second; + mTerminatedTransactionMap.erase(i); + return; + } + + i=mCandidateTransactionMap.find(transactionId); + if(i!=mCandidateTransactionMap.end()) + { + delete i->second; + mCandidateTransactionMap.erase(i); + return; + } + + i=mActiveTransactionMap.find(transactionId); + if(i!=mActiveTransactionMap.end()) + { + delete i->second; + mActiveTransactionMap.erase(i); + WarningLog(<< "Something removed an active transaction, " << transactionId + << ". It is very likely that something is broken here. "); + return; + } + +} + +bool +ResponseContext::isDuplicate(const repro::Target* target) const +{ + resip::ContactList::const_iterator i; + // make sure each target is only inserted once + + // !bwc! We can not optimize this by using stl, because operator + // == does not conform to the partial-ordering established by operator + // < (We can very easily have a < b and a==b simultaneously). + // [TODO] Once we have a canonicalized form, we can improve this. + + for(i=mTargetList.begin();i!=mTargetList.end();i++) + { + if(*i==target->rec()) + { + return true; + } + } + + return false; +} + +void +ResponseContext::beginClientTransaction(repro::Target* target) +{ + // .bwc. This is a private function, and if anything calls this with a + // target in an invalid state, it is a bug. + assert(target->status() == Target::Candidate); + + SipMessage& orig=mRequestContext.getOriginalRequest(); + SipMessage request(orig); + + // If the target has a ;lr parameter, then perform loose routing + if(target->uri().exists(p_lr)) + { + request.header(h_Routes).push_front(NameAddr(target->uri())); + } + else + { + request.header(h_RequestLine).uri() = target->uri(); + } + + // .bwc. Proxy checks whether this is valid, and rejects if not. + request.header(h_MaxForwards).value()--; + + bool inDialog=false; + + try + { + inDialog=request.header(h_To).exists(p_tag); + } + catch(resip::ParseException&) + { + // ?bwc? Do we ignore this and just say this is a dialog-creating + // request? + } + + // Potential source Record-Route addition only for new dialogs + // !bwc! It looks like we really ought to be record-routing in-dialog + // stuff. + + // only add record route if configured to do so + if(!mRequestContext.mProxy.getRecordRoute(orig.getReceivedTransport()).uri().host().empty()) + { + if (!inDialog && // only for dialog-creating request + (request.method() == INVITE || + request.method() == SUBSCRIBE || + request.method() == REFER)) + { + insertRecordRoute(request, + orig.getReceivedTransport(), + target); + } + else if(request.method()==REGISTER) + { + insertRecordRoute(request, + orig.getReceivedTransport(), + target, + true /* do Path instead */); + } + } + + if((resip::InteropHelper::getOutboundSupported() || + resip::InteropHelper::getRRTokenHackEnabled() || + mIsClientBehindNAT) && + target->rec().mUseFlowRouting && + target->rec().mReceivedFrom.mFlowKey) + { + // .bwc. We only override the destination if we are sending to an + // outbound contact. If this is not an outbound contact, but the + // endpoint has given us a Contact with the correct ip-address and + // port, we might be able to find the connection they formed when they + // registered earlier, but that will happen down in TransportSelector. + request.setDestination(target->rec().mReceivedFrom); + } + + DebugLog(<<"Set tuple dest: " << request.getDestination()); + + // .bwc. Path header addition. + if(!target->rec().mSipPath.empty()) + { + request.header(h_Routes).append(target->rec().mSipPath); + } + + // a baboon might adorn the message, record call logs or CDRs, might + // insert loose routes on the way to the next hop + Helper::processStrictRoute(request); + + //This is where the request acquires the tid of the Target. The tids + //should be the same from here on out. + request.header(h_Vias).push_front(target->via()); + + if(!mRequestContext.mInitialTimerCSet && + mRequestContext.getOriginalRequest().method()==INVITE) + { + mRequestContext.mInitialTimerCSet=true; + mRequestContext.updateTimerC(); + } + + // the rest of 16.6 is implemented by the transaction layer of resip + // - determining the next hop (tuple) + // - adding a content-length if needed + // - sending the request + sendRequest(request); + + target->status() = Target::Started; +} + +void +ResponseContext::insertRecordRoute(SipMessage& outgoing, + const Transport* receivedTransport, + Target* target, + bool doPathInstead) +{ + resip::Data inboundFlowToken=getInboundFlowToken(doPathInstead); + bool needsOutboundFlowToken=outboundFlowTokenNeeded(target); + bool recordRouted=false; + // .bwc. If we have a flow-token we need to insert, we need to record-route. + // Also, we might record-route if we are configured to do so. + if( !inboundFlowToken.empty() + || needsOutboundFlowToken + || mRequestContext.mProxy.getRecordRouteForced() ) + { + resip::NameAddr rt; + if(inboundFlowToken.empty()) + { + rt=mRequestContext.mProxy.getRecordRoute(receivedTransport); + } + else + { + if(receivedTransport->getTuple().getType()==TLS || + receivedTransport->getTuple().getType()==DTLS) + { + // .bwc. Debatable. Should we be willing to reuse a TLS connection + // at the behest of a Route header with no hostname in it? + rt=mRequestContext.mProxy.getRecordRoute(receivedTransport); + rt.uri().scheme() = "sips"; + } + else + { + if(receivedTransport->getTuple().isAnyInterface()) + { + rt=mRequestContext.mProxy.getRecordRoute(receivedTransport); + } + else + { + rt.uri().host()=resip::Tuple::inet_ntop(receivedTransport->getTuple()); + } + rt.uri().port()=receivedTransport->getTuple().getPort(); + rt.uri().param(resip::p_transport)=resip::Tuple::toDataLower(receivedTransport->getTuple().getType()); + } + rt.uri().user()=inboundFlowToken; + } + Helper::massageRoute(outgoing,rt); + +#ifdef USE_SIGCOMP + if(mRequestContext.getProxy().compressionEnabled() && + target->uri().exists(p_comp) && + target->uri().param(p_comp)=="sigcomp") + { + rt.uri().param(p_comp)="sigcomp"; + } +#endif + + recordRouted=true; + if(doPathInstead) + { + if(!inboundFlowToken.empty()) + { + // Only add ;ob parameter if client really supports outbound (ie. not for NAT detection mode or flow token hack) + if(!mRequestContext.getOriginalRequest().empty(h_Supporteds) && + mRequestContext.getOriginalRequest().header(h_Supporteds).find(Token(Symbols::Outbound))) + { + rt.uri().param(p_ob); + } + } + outgoing.header(h_Paths).push_front(rt); + if(!outgoing.header(h_Supporteds).find(Token("path"))) + { + outgoing.header(h_Supporteds).push_back(Token("path")); + } + InfoLog (<< "Added Path: " << rt); + } + else + { + outgoing.header(h_RecordRoutes).push_front(rt); + InfoLog (<< "Added Record-Route: " << rt); + } + } + + // .bwc. We always need to add this, since we never know if a transport + // switch is going to happen. (Except for Path headers; we don't care about + // transport switches on REGISTER requests. If we already put a Path header + // in, we do care though.) + if(!doPathInstead || recordRouted) + { + std::auto_ptr<resip::MessageDecorator> rrDecorator( + new RRDecorator(mRequestContext.mProxy, + receivedTransport, + recordRouted, + !inboundFlowToken.empty(), + mRequestContext.mProxy.getRecordRouteForced(), + doPathInstead, + mIsClientBehindNAT)); + outgoing.addOutboundDecorator(rrDecorator); + } +} + +resip::Data +ResponseContext::getInboundFlowToken(bool doPathInstead) +{ + resip::Data flowToken=resip::Data::Empty; + resip::SipMessage& orig=mRequestContext.getOriginalRequest(); + if(orig.empty(h_Contacts) || !orig.header(h_Contacts).front().isWellFormed()) + { + return flowToken; + } + + const resip::NameAddr& contact(orig.header(h_Contacts).front()); + + if(InteropHelper::getOutboundSupported() && + (contact.uri().exists(p_ob) || contact.exists(p_regid))) + { + if(orig.header(h_Vias).size()==1) + { + // This arrived over an outbound flow (or so the endpoint claims) + // (See outbound-09 Sec 4.3 para 3) + resip::Data binaryFlowToken; + resip::Tuple source(orig.getSource()); + source.onlyUseExistingConnection=true; + Tuple::writeBinaryToken(source, binaryFlowToken, Proxy::FlowTokenSalt); + flowToken = binaryFlowToken.base64encode(); + } + else if(doPathInstead) + { + // Need to try to detect Path failures + if(orig.empty(h_Paths) || !orig.header(h_Paths).back().uri().exists(p_ob)) + { + // Yikes! Client is trying to use outbound, but edge-proxy did not + // support it. The registrar will either reject this (if it supports + // outbound), or will not indicate outbound support (which should + // let the client know that the flow setup failed) + WarningLog(<<"Client asked for outbound processing, but the edge " + "proxy did not support it. There's nothing we can do to " + "salvage this. The registrar might end up rejecting the " + "registration (if is supports outbound), or it might just " + "fail to add a Supported: outbound. In either case, the " + "client should know what's up, so we just let it all " + "happen."); + } + } + } + + if(flowToken.empty() && orig.header(h_Vias).size()==1) + { + if(resip::InteropHelper::getRRTokenHackEnabled() || + mIsClientBehindNAT || + needsFlowTokenToWork(contact)) + { + // !bwc! TODO remove this when flow-token hack is no longer needed. + // Poor-man's outbound. Shouldn't be our default behavior, because it + // breaks target-refreshes (once a flow-token is in the Route-Set, the + // flow-token cannot be changed, and will override any update to the + // Contact) + resip::Data binaryFlowToken; + Tuple::writeBinaryToken(orig.getSource(), binaryFlowToken, Proxy::FlowTokenSalt); + flowToken = binaryFlowToken.base64encode(); + } + } + + return flowToken; +} + +bool +ResponseContext::outboundFlowTokenNeeded(Target* target) +{ + if(mRequestContext.mProxy.isMyUri(target->uri())) + { + // .bwc. We don't need to put flow-tokens pointed at ourselves. + return false; + } + + if((target->rec().mReceivedFrom.mFlowKey && + target->rec().mUseFlowRouting) + || resip::InteropHelper::getRRTokenHackEnabled() + || mIsClientBehindNAT) + { + target->rec().mReceivedFrom.onlyUseExistingConnection=true; + return true; + } + + return false; +} + +bool +ResponseContext::needsFlowTokenToWork(const resip::NameAddr& contact) const +{ + if(DnsUtil::isIpAddress(contact.uri().host())) + { + // IP address in host-part. + if(contact.uri().scheme()=="sips") + { + // TLS with no FQDN. Impossible without flow-token fixup, even if no + // NAT is involved. + return true; + } + + if(contact.uri().exists(p_transport)) + { + TransportType type = toTransportType(contact.uri().param(p_transport)); + if(type==TLS || type == DTLS) + { + // TLS with no FQDN. Impossible without flow-token fixup, even if no + // NAT is involved. + return true; + } + } + } + + if(contact.uri().exists(p_sigcompId)) + { + if(contact.uri().exists(p_transport)) + { + TransportType type = toTransportType(contact.uri().param(p_transport)); + if(type == TLS || type == TCP) + { + // Client is using sigcomp on the first hop using a connection- + // oriented transport. For this to work, that connection has to be + // reused for all traffic. + return true; + } + } + } + return false; +} + +bool +ResponseContext::sendingToSelf(Target* target) +{ + if(mRequestContext.mProxy.isMyUri(target->uri())) + { + return true; + } + return false; +} + +void +ResponseContext::sendRequest(resip::SipMessage& request) +{ + assert (request.isRequest()); + + // Do any required session accounting with this forward request - allows Session Routed event + mRequestContext.getProxy().doSessionAccounting(request, false /* received */, mRequestContext); + + if (request.method() != CANCEL && + request.method() != ACK) + { + mRequestContext.getProxy().addClientTransaction(request.getTransactionId(), &mRequestContext); + mRequestContext.mTransactionCount++; +// if(!mRequestContext.getDigestIdentity().empty()) +// { +// requestPtr->header(h_Identity); +// // !bwc! Need to fill in the Identity-Info header telling where our +// // cert can be found. +// } + } + + // TODO - P-Asserted-Identity Processing + // RFC3325 - section 5 + // When a proxy forwards a message to another node, it must first + // determine if it trusts that node or not. If it trusts the node, the + // proxy does not remove any P-Asserted-Identity header fields that it + // generated itself, or that it received from a trusted source. If it + // does not trust the element, then the proxy MUST examine the Privacy + // header field (if present) to determine if the user requested that + // asserted identity information be kept private. + + // Note: Since we have no better mechanism to determine if destination is trusted or + // not we will assume that all destinations outside our domain are not-trusted + // and will remove the P-Asserted-Identity header, if Privacy is set to "id" + if(mRequestContext.getProxy().isPAssertedIdentityProcessingEnabled() && + request.exists(h_Privacies) && + request.header(h_Privacies).size() > 0 && + request.exists(h_PAssertedIdentities) && + !mRequestContext.getProxy().isMyUri(request.header(h_RequestLine).uri())) + { + // Look for "id" token + bool found = false; + PrivacyCategories::iterator it = request.header(h_Privacies).begin(); + for(; it != request.header(h_Privacies).end() && !found; it++) + { + std::vector<Data>::iterator itToken = it->value().begin(); + for(; itToken != it->value().end() && !found; itToken++) + { + if(*itToken == "id") + { + request.remove(h_PAssertedIdentities); + found = true; + } + } + } + } + + if (request.method() == ACK) + { + DebugLog(<<"Posting Ack200DoneMessage"); + mRequestContext.getProxy().post(new Ack200DoneMessage(mRequestContext.getTransactionId())); + } + + mRequestContext.send(request); +} + + +void +ResponseContext::processCancel(const SipMessage& request) +{ + assert(request.isRequest()); + assert(request.method() == CANCEL); + + std::auto_ptr<SipMessage> ok(Helper::makeResponse(request, 200)); + mRequestContext.sendResponse(*ok); + + if (!mRequestContext.mHaveSentFinalResponse) + { + cancelAllClientTransactions(); + if(!hasActiveTransactions()) + { + SipMessage reqterm; + Helper::makeResponse(reqterm,mRequestContext.getOriginalRequest(),487); + mRequestContext.sendResponse(reqterm); + } + } +} + +void +ResponseContext::processTimerC() +{ + if (!mRequestContext.mHaveSentFinalResponse) + { + InfoLog(<<"Canceling client transactions due to timer C."); + cancelAllClientTransactions(); + } +} + +void +ResponseContext::processResponse(SipMessage& response) +{ + InfoLog (<< "processResponse: " << endl << response); + + // store this before we pop the via and lose the branch tag + mCurrentResponseTid = response.getTransactionId(); + + assert (response.isResponse()); + assert (response.exists(h_Vias) && !response.header(h_Vias).empty()); + response.header(h_Vias).pop_front(); + + // Stop processing responses that have nowhere else to go + if (response.header(h_Vias).empty()) + { + // CANCEL/200s only have one Via. Likewise 100s only have one Via + // Silently stop processing the CANCEL responses. + // We will handle the 100 responses later + // Log other responses we can't forward + + if(response.method()==CANCEL) + { + return; + } + else if (response.header(h_StatusLine).statusCode() > 199) + { + InfoLog( << "Received final response, but can't forward as there are " + "no more Vias. Considering this branch failed. " + << response.brief() ); + // .bwc. Treat as server error. + terminateClientTransaction(mCurrentResponseTid); + return; + } + else if(response.header(h_StatusLine).statusCode() != 100) + { + InfoLog( << "Received provisional response, but can't forward as there" + " are no more Vias. Ignoring. " << response.brief() ); + return; + } + } + else // We have a second Via + { + if(!mRequestContext.getOriginalRequest().getRFC2543TransactionId().empty()) + { + // .bwc. Original request had an RFC 2543 transaction-id. Set in + // response. + response.setRFC2543TransactionId(mRequestContext.getOriginalRequest().getRFC2543TransactionId()); + } + + const Via& via = response.header(h_Vias).front(); + + if(!via.isWellFormed()) + { + // .bwc. Garbage via. Unrecoverable. Ignore if provisional, terminate + // transaction if not. + DebugLog(<<"Some endpoint has corrupted one of our Vias" + " in their response. (Via is malformed) This is not fixable."); + if(response.header(h_StatusLine).statusCode() > 199) + { + terminateClientTransaction(mCurrentResponseTid); + } + + return; + } + + const Via& origVia = mRequestContext.getOriginalRequest().header(h_Vias).front(); + const Data& branch=(via.exists(p_branch) ? via.param(p_branch).getTransactionId() : Data::Empty); + const Data& origBranch=(origVia.exists(p_branch) ? origVia.param(p_branch).getTransactionId() : Data::Empty); + + if(!isEqualNoCase(branch,origBranch)) + { + // .bwc. Someone altered our branch. Ignore if provisional, terminate + // transaction otherwise. + DebugLog(<<"Some endpoint has altered one of our Vias" + " in their response. (branch is different) This is not fixable."); + if(response.header(h_StatusLine).statusCode() > 199) + { + terminateClientTransaction(mCurrentResponseTid); + } + + return; + } + } + + DebugLog (<< "Search for " << mCurrentResponseTid << " in " << InserterP(mActiveTransactionMap)); + + TransactionMap::iterator i = mActiveTransactionMap.find(mCurrentResponseTid); + + int code = response.header(h_StatusLine).statusCode(); + if (i == mActiveTransactionMap.end()) + { + // This is a response for a transaction that is no longer/was never active. + // This is probably a useless response (at best) or a malicious response (at worst). + // Log the response here: + if ((code / 100) != 2) + { + InfoLog( << "Discarding stray response" ); + } + // Even though this is a tremendously bad idea, some developers may + // decide they want to statelessly forward the response + // Here is the gun. Don't say we didn't warn you! + else + { + // !abr! Because we don't run timers on the transaction after + // it has terminated and because the ACKs on INVITE + // 200-class responses are end-to-end, we don't discard + // 200 responses. To do this properly, we should run a + // transaction timer for 64*T1 and remove transactions from + // the ActiveTransactionMap *only* after that timer expires. + // IN OTHER WORDS, REMOVE THIS CODE. + mRequestContext.sendResponse(response); + } + return; + } + + switch (code / 100) + { + case 1: + if(mRequestContext.getOriginalRequest().method()==INVITE) + { + mRequestContext.updateTimerC(); + } + + if (!mRequestContext.mHaveSentFinalResponse) + { + if (code == 100) + { + return; // stop processing 100 responses + } + + mRequestContext.sendResponse(response); + return; + } + break; + + case 2: + terminateClientTransaction(mCurrentResponseTid); + if (mRequestContext.getOriginalRequest().method() == INVITE) + { + cancelAllClientTransactions(); + mRequestContext.mHaveSentFinalResponse = true; + mBestResponse.header(h_StatusLine).statusCode()= + response.header(h_StatusLine).statusCode(); + mRequestContext.sendResponse(response); + } + else if (!mRequestContext.mHaveSentFinalResponse) + { + clearCandidateTransactions(); + mRequestContext.mHaveSentFinalResponse = true; + mBestResponse.header(h_StatusLine).statusCode()= + response.header(h_StatusLine).statusCode(); + + // If this is a registration response and we have flow timers enabled, and + // we are doing outbound for this registration and there is no FlowTimer + // header present already, then add a FlowTimer header + if(response.method() == REGISTER && + InteropHelper::getFlowTimerSeconds() > 0 && + response.empty(h_FlowTimer) && + ((!response.empty(h_Paths) && response.header(h_Paths).back().uri().exists(p_ob)) || + (!response.empty(h_Requires) && response.header(h_Requires).find(Token(Symbols::Outbound))))) + { + response.header(h_FlowTimer).value() = InteropHelper::getFlowTimerSeconds(); + mRequestContext.getProxy().getStack().enableFlowTimer(mRequestContext.getOriginalRequest().getSource()); + } + + mRequestContext.sendResponse(response); + } + break; + + case 3: + case 4: + case 5: + DebugLog (<< "forwardedFinal=" << mRequestContext.mHaveSentFinalResponse + << " outstanding client transactions: " << InserterP(mActiveTransactionMap)); + terminateClientTransaction(mCurrentResponseTid); + if (!mRequestContext.mHaveSentFinalResponse) + { + int priority = getPriority(response); + if (priority == mBestPriority) + { + if (code == 401 || code == 407) + { + if (response.exists(h_WWWAuthenticates)) + { + for ( Auths::iterator i=response.header(h_WWWAuthenticates).begin(); + i != response.header(h_WWWAuthenticates).end() ; ++i) + { + mBestResponse.header(h_WWWAuthenticates).push_back(*i); + } + } + + if (response.exists(h_ProxyAuthenticates)) + { + for ( Auths::iterator i=response.header(h_ProxyAuthenticates).begin(); + i != response.header(h_ProxyAuthenticates).end() ; ++i) + { + mBestResponse.header(h_ProxyAuthenticates).push_back(*i); + } + mBestResponse.header(h_StatusLine).statusCode() = 407; + } + } + else if (code / 100 == 3) // merge 3xx + { + + if(mBestResponse.header(h_StatusLine).statusCode()/100!=3) + { + // .bwc. Do not merge contacts in 3xx with contacts from a + // previous 4xx or 5xx + mBestResponse.header(h_Contacts).clear(); + } + + for (NameAddrs::iterator i=response.header(h_Contacts).begin(); + i != response.header(h_Contacts).end(); ++i) + { + // TODO ?bwc? if we are going to be checking whether + // this is "*", we should see if it is well-formed + // first. If we shouldn't be doing any checks on + // the contacts, we should simply remove all of this + // checking code and just blindly copy the contacts over. + + if(!i->isWellFormed() || i->isAllContacts()) + { + // .bwc. Garbage contact; ignore it. + continue; + } + + mBestResponse.header(h_Contacts).push_back(*i); + } + + // ?bwc? it is possible for this code to end up with a 300 + // with no Contacts in it (because they were all malformed) + // Is this acceptable? Also, is 300 the code we want here? + mBestResponse.header(h_StatusLine).statusCode() = 300; + } + } + else if (priority < mBestPriority) + { + mBestPriority = priority; + mBestResponse = response; + } + + if (areAllTransactionsTerminated()) + { + forwardBestResponse(); + } + } + break; + + case 6: + terminateClientTransaction(mCurrentResponseTid); + if (!mRequestContext.mHaveSentFinalResponse) + { + if (mBestResponse.header(h_StatusLine).statusCode() / 100 != 6) + { + mBestResponse = response; + mBestPriority=0; //6xx class responses take precedence over all 3xx,4xx, and 5xx + if (mRequestContext.getOriginalRequest().method() == INVITE) + { + // CANCEL INVITE branches + cancelAllClientTransactions(); + } + } + + if (areAllTransactionsTerminated()) + { + forwardBestResponse(); + } + } + break; + + default: + assert(0); + break; + } +} + +void +ResponseContext::cancelClientTransaction(repro::Target* target) +{ + if (target->status() == Target::Started) + { + InfoLog (<< "Cancel client transaction: " << target); + mRequestContext.cancelClientTransaction(target->via().param(p_branch).getTransactionId()); + + DebugLog(<< "Canceling a transaction with uri: " + << resip::Data::from(target->uri()) << " , to host: " + << target->via().sentHost()); + target->status() = Target::Cancelled; + } + else if (target->status() == Target::Candidate) + { + target->status() = Target::Terminated; + } +} + +void +ResponseContext::terminateClientTransaction(const resip::Data& tid) +{ + + InfoLog (<< "Terminating client transaction: " << tid << " all = " << areAllTransactionsTerminated()); + + TransactionMap::iterator i = mActiveTransactionMap.find(tid); + if(i != mActiveTransactionMap.end()) + { + InfoLog (<< "client transactions: " << InserterP(mActiveTransactionMap)); + i->second->status() = Target::Terminated; + mTerminatedTransactionMap[tid] = i->second; + mActiveTransactionMap.erase(i); + return; + } + + TransactionMap::iterator j = mCandidateTransactionMap.find(tid); + if(j != mCandidateTransactionMap.end()) + { + InfoLog (<< "client transactions: " << InserterP(mCandidateTransactionMap)); + j->second->status() = Target::Terminated; + mTerminatedTransactionMap[tid] = j->second; + mCandidateTransactionMap.erase(j); + return; + } + +} + + +int +ResponseContext::getPriority(const resip::SipMessage& msg) +{ + int responseCode = msg.header(h_StatusLine).statusCode(); + int p = 0; // "p" is the relative priority of the response + + assert(responseCode >= 300 && responseCode <= 599); + if (responseCode <= 399) // 3xx response + { + return 5; // response priority is 5 + } + if (responseCode >= 500) + { + switch(responseCode) + { + case 501: // these four have different priorities + case 503: // which are addressed in the case statement + case 580: // below (with the 4xx responses) + case 513: + break; + default: + return 42; // response priority of other 5xx is 42 + } + } + + switch(responseCode) + { + // Easy to Repair Responses: 412, 484, 422, 423, 407, 401, 300..399, 402 + case 412: // Publish ETag was stale + return 1; + case 484: // overlap dialing + return 2; + case 422: // Session-Timer duration too long + case 423: // Expires too short + return 3; + case 407: // Proxy-Auth + case 401: // UA Digest challenge + return 4; + + // 3xx responses have p = 5 + case 402: // Payment required + return 6; + + // Responses used for negotiation: 493, 429, 420, 406, 415, 488 + case 493: // Undecipherable, try again unencrypted + return 10; + + case 420: // Required Extension not supported, try again without + return 12; + + case 406: // Not Acceptable + case 415: // Unsupported Media Type + case 488: // Not Acceptable Here + return 13; + + // Possibly useful for negotiation, but less likely: 421, 416, 417, 494, 580, 485, 405, 501, 413, 414 + + case 416: // Unsupported scheme + case 417: // Unknown Resource-Priority + return 20; + + case 405: // Method not allowed (both used for negotiating REFER, PUBLISH, etc.. + case 501: // Usually used when the method is not OK + return 21; + + case 580: // Preconditions failure + return 22; + + case 485: // Ambiguous userpart. A bit better than 404? + return 23; + + case 428: // Use Identity header + case 429: // Provide Referrer Identity + case 494: // Use the sec-agree mechanism + return 24; + + case 413: // Request too big + case 414: // URI too big + return 25; + + case 421: // An extension required by the server was not in the Supported header + return 26; + + // The request isn't repairable, but at least we can try to provide some + // useful information: 486, 480, 410, 404, 403, 487 + + case 486: // Busy Here + return 30; + + case 480: // Temporarily unavailable + return 31; + + case 410: // Gone + return 32; + + case 436: // Bad Identity-Info + case 437: // Unsupported Certificate + case 513: // Message too large + return 33; + + case 403: // Forbidden + return 34; + + case 404: // Not Found + return 35; + + case 487: // Some branches were cancelled, if the UAC sent a CANCEL this is good news + return 36; + + // We are hosed: 503, 483, 482, 481, other 5xx, 400, 491, 408 // totally useless + + case 503: // bad news, we should never forward this back anyway + return 43; + + case 483: // loops, encountered + case 482: + return 41; + + // other 5xx p = 42 + + // UAS is seriously confused: p = 43 + // case 481: + // case 400: + // case 491: + // default: + + case 408: // very, very bad (even worse than the remaining 4xx responses) + return 49; + + default: + return 43; + } + return p; +} + +bool +ResponseContext::CompareStatus::operator()(const resip::SipMessage& lhs, const resip::SipMessage& rhs) const +{ + assert(lhs.isResponse()); + assert(rhs.isResponse()); + + // !rwm! replace with correct thingy here + return lhs.header(h_StatusLine).statusCode() < rhs.header(h_StatusLine).statusCode(); +} + +void +ResponseContext::forwardBestResponse() +{ + InfoLog (<< "Forwarding best response: " << mBestResponse.brief()); + + clearCandidateTransactions(); + + if(mRequestContext.getOriginalRequest().method()==INVITE) + { + cancelActiveClientTransactions(); + } + + if(mBestResponse.header(h_StatusLine).statusCode() == 503) + { + //See RFC 3261 sec 16.7, page 110, paragraph 2 + mBestResponse.header(h_StatusLine).statusCode() = 480; + } + + if(mBestResponse.header(h_StatusLine).statusCode() == 408 && + mBestResponse.method()!=INVITE) + { + // We don't forward back NIT 408; we just silently abandon the transaction - RFC4321 - section 1.4 408 for non-INVITE is not useful + DebugLog(<< "Got NIT 408, abandoning: "<<mRequestContext.getTransactionId()); + mRequestContext.getProxy().getStack().abandonServerTransaction(mRequestContext.getTransactionId()); + mRequestContext.mHaveSentFinalResponse = true; // To avoid Request context from sending a response + } + else + { + mRequestContext.sendResponse(mBestResponse); + } +} + +EncodeStream& +repro::operator<<(EncodeStream& strm, const ResponseContext& rc) +{ + strm << "ResponseContext: " + << " identity=" << rc.mRequestContext.getDigestIdentity() + << " best=" << rc.mBestPriority << " " << rc.mBestResponse.brief() + << " forwarded=" << rc.mRequestContext.mHaveSentFinalResponse + << " pending=" << InserterP(rc.mCandidateTransactionMap) + << " active=" << InserterP(rc.mActiveTransactionMap) + << " terminated=" << InserterP(rc.mTerminatedTransactionMap); + + return strm; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/ResponseContext.hxx b/src/libs/resiprocate/repro/ResponseContext.hxx new file mode 100644 index 00000000..4b6a5af1 --- /dev/null +++ b/src/libs/resiprocate/repro/ResponseContext.hxx @@ -0,0 +1,328 @@ +#if !defined(RESIP_RESPONSE_CONTEXT_HXX) +#define RESIP_RESPONSE_CONTEXT_HXX + +#include <iosfwd> +#include <map> +#include <list> + +#include "rutil/HashMap.hxx" +#include "resip/stack/NameAddr.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Via.hxx" +#include "resip/stack/Uri.hxx" +#include "resip/stack/MessageDecorator.hxx" + +#include "repro/Target.hxx" +#include "rutil/resipfaststreams.hxx" + +namespace resip +{ +class SipMessage; +class Transport; +} + +namespace repro +{ + +class RequestContext; + +class ResponseContext +{ + public: + class CompareStatus : public std::binary_function<const resip::SipMessage&, const resip::SipMessage&, bool> + { + public: + bool operator()(const resip::SipMessage& lhs, const resip::SipMessage& rhs) const; + }; + + ~ResponseContext(); + + /** + Adds this Target as a SimpleTarget to the collection of Targets. + + @param target The NameAdder used to form the Target to add. + + @param beginImmediately Whether to immediately start a transaction for this target. + + @returns tid of the newly added target + + @note Targets are not checked for duplicate uris until an attempt is made to begin them. + */ + resip::Data addTarget(const resip::NameAddr& target, bool beginImmediately=false); + + /** + Adds this Target to the collection of Targets. + + @param target The Target to add. + + @param beginImmediately Whether to immediately start a transaction + for this target. + + @returns If beginImmediately=false, true iff the Target was + successfully added (could happen if a final response has already + been forwarded). If beginImmediately=true, true iff a transaction + was successfully started for the Target (could fail due to the + presence of a duplicate contact, or when a final response has + already been forwarded.) + + @note Targets are not checked for duplicate uris until an attempt + is made to start them. + */ + bool addTarget(std::auto_ptr<repro::Target> target, bool beginImmediately=false); + + /** + Adds a batch of Targets. + + @note RESPONSECONTEXT ASSUMES OWNERSHIP OF THE TARGETS POINTED + TO IN THIS LIST! + + @param targets A list of (sorted) Target*. This list is consumed. + + @param highPriority Whether or not the Target ProccessorChain should + prioritize this batch above other batches of the same type. + (This is primarily intended to let multiple recursive redirection + work properly, but can be used for other purposes.) + + @returns true iff any Targets were added. + + @note It is assumed that all of these Targets are + the same subclass of Target, and that they are already sorted in the + order of their priority. If these assumptions do not hold, things + will not break per se, but oddball target processing behavior might + result. + */ + bool addTargetBatch(TargetPtrList& targets, bool highPriority=false); + + /** + Begins all Candidate client transactions. + + @returns true iff any transactions were started + */ + bool beginClientTransactions(); + + /** + Begins a client transaction. + + @param serial The transaction id to start. + + @returns true iff the transaction was started (could fail if there was + a duplicate contact) + + */ + bool beginClientTransaction(const resip::Data& serial); + + /** + Cancels all active client transactions. Does not clear Candidate + transactions. + + @returns true iff any transaction was placed in either the + WaitingToCancel or Cancelled state. + */ + bool cancelActiveClientTransactions(); + + /** + Cancels all active client transactions. Also clears Candidate + transactions (they are transitioned directly to Terminated) + + @returns true iff any transaction was placed in either the + WaitingToCancel, Cancelled, or Terminated state. + */ + bool cancelAllClientTransactions(); + + /** + Removes all Candidate transactions. + + @returns true iff at least one Candidate transaction was removed. + */ + bool clearCandidateTransactions(); + + /** + Cancels this client transaction if active, or Terminates it if + Candidate. + + @returns true iff this transaction was placed in either the + WaitingToCancel, Cancelled, or Terminated state. + */ + bool cancelClientTransaction(const resip::Data& serial); + + /** + Self-explanatory + */ + Target* getTarget(const resip::Data& serial) const; + + //Keyed by transaction id + typedef std::map<resip::Data,repro::Target*> TransactionMap; + + /** + Self-explanatory. + + @note Can be used to decide which targets should be processed next, + although this assumes a great deal of interdependency btw + the various processor chains and homogeneity in how the Targets are + prioritized, and can be inefficient if there + are large numbers of Candidate Targets. A more structured approach + exists in the functions dealing with TransactionBatch. + */ + const TransactionMap& getCandidateTransactionMap() const; + + /** + @returns true iff there are Candidate targets + */ + bool hasCandidateTransactions() const; + + /** + @returns true iff there are active targets (in state Trying, + Proceeding, WaitingForCancel or Cancelled) + */ + bool hasActiveTransactions() const; + + /** + @returns true iff there are Terminated targets. + */ + bool hasTerminatedTransactions() const; + + bool hasTargets() const; + + /** + @returns true iff this target is in state Candidate + */ + bool isCandidate(const resip::Data& tid) const; + + /** + @returns true iff this target is active (Trying, Proceeding, + WaitingForCancel, or Cancelled) + */ + bool isActive(const resip::Data& tid) const; + + /** + @returns true iff this target is in state Terminated + */ + bool isTerminated(const resip::Data& tid) const; + + /** + @returns true iff all targets are in state Terminated + */ + bool areAllTransactionsTerminated() const; + + + int getPriority(const resip::SipMessage& msg); + + //!bwc! This should probably not be private, since these two classes are + //tightly coupled. + RequestContext& mRequestContext; + + std::list<std::list<resip::Data> > mTransactionQueueCollection; + resip::Data mCurrentResponseTid; + + private: + // only constructed by RequestContext + ResponseContext(RequestContext& parent); + + // These methods are really private. These are not intended to be used + // by anything other than RequestContext or ResponseContext. + + // call this from RequestContext when a CANCEL comes in + void processCancel(const resip::SipMessage& request); + + // call this from RequestContext after the lemur chain for any response + void processResponse(resip::SipMessage& response); + + void processTimerC(); + + void beginClientTransaction(repro::Target* target); + void cancelClientTransaction(repro::Target* target); + + + void terminateClientTransaction(const resip::Data& tid); + void removeClientTransaction(const resip::Data& transactionId); + + //There is no terminateClientTransaction(Target target) since terminating + //a branch is very simple. The guts can be found in the API functions. + + void insertRecordRoute(resip::SipMessage& outgoing, + const resip::Transport* receivedTransport, + Target* target, + bool doPathInstead=false); + resip::Data getInboundFlowToken(bool doPathInstead); + bool outboundFlowTokenNeeded(Target* target); + bool needsFlowTokenToWork(const resip::NameAddr& contact) const; + bool sendingToSelf(Target* target); + + void sendRequest(resip::SipMessage& request); + + TransactionMap mCandidateTransactionMap; //Targets with status Candidate. + TransactionMap mActiveTransactionMap; //Targets with status Trying, Proceeding, or WaitingToCancel. + TransactionMap mTerminatedTransactionMap; //Targets with status Terminated. + + //Maybe someday canonicalized Uris will go here, and checking for duplicates + //will be much faster + resip::ContactList mTargetList; + + bool isDuplicate(const repro::Target* target) const; + + resip::SipMessage mBestResponse; + int mBestPriority; + bool mSecure; + bool mIsClientBehindNAT; // Only set if InteropHelper::getClientNATDetectionEnabled() is true + + void forwardBestResponse(); + + friend class RequestContext; + friend EncodeStream& operator<<(EncodeStream& strm, const repro::ResponseContext& rc); +}; + +EncodeStream& +operator<<(EncodeStream& strm, const repro::ResponseContext& rc); + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/RouteStore.cxx b/src/libs/resiprocate/repro/RouteStore.cxx new file mode 100644 index 00000000..50e844d8 --- /dev/null +++ b/src/libs/resiprocate/repro/RouteStore.cxx @@ -0,0 +1,466 @@ + +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Lock.hxx" +#include "resip/stack/Uri.hxx" + +#include "repro/RouteStore.hxx" +#include "rutil/WinLeakCheck.hxx" + + +using namespace resip; +using namespace repro; +using namespace std; + + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +bool RouteStore::RouteOp::operator<(const RouteOp& rhs) const +{ + return routeRecord.mOrder < rhs.routeRecord.mOrder; +} + + +RouteStore::RouteStore(AbstractDb& db): + mDb(db) +{ + Key key = mDb.firstRouteKey(); + while ( !key.empty() ) + { + RouteOp route; + route.routeRecord = mDb.getRoute(key); + route.key = key; + route.preq = 0; + + if(!route.routeRecord.mMatchingPattern.empty()) + { + int flags = REG_EXTENDED; + if(route.routeRecord.mRewriteExpression.find("$") == Data::npos) + { + flags |= REG_NOSUB; + } + route.preq = new regex_t; + int ret = regcomp(route.preq, route.routeRecord.mMatchingPattern.c_str(), flags); + if(ret != 0) + { + delete route.preq; + ErrLog(<< "Routing rule has invalid match expression: " + << route.routeRecord.mMatchingPattern); + route.preq = 0; + } + } + + mRouteOperators.insert( route ); + + key = mDb.nextRouteKey(); + } + mCursor = mRouteOperators.begin(); +} + + +RouteStore::~RouteStore() +{ + for(RouteOpList::iterator i = mRouteOperators.begin(); i != mRouteOperators.end(); i++) + { + if ( i->preq ) + { + regfree ( i->preq ); + delete i->preq; + + // !abr! Can't modify elements in a set + // i->preq = 0; + + } + } + mRouteOperators.clear(); +} + + +bool +RouteStore::addRoute(const resip::Data& method, + const resip::Data& event, + const resip::Data& matchingPattern, + const resip::Data& rewriteExpression, + const int order ) +{ + InfoLog( << "Add route" ); + + RouteOp route; + + Key key = buildKey(method, event, matchingPattern); + + if(findKey(key)) return false; + + route.routeRecord.mMethod = method; + route.routeRecord.mEvent = event; + route.routeRecord.mMatchingPattern = matchingPattern; + route.routeRecord.mRewriteExpression = rewriteExpression; + route.routeRecord.mOrder = order; + + if(!mDb.addRoute(key , route.routeRecord)) + { + return false; + } + + route.key = key; + route.preq = 0; + if( !route.routeRecord.mMatchingPattern.empty() ) + { + int flags = REG_EXTENDED; + if( route.routeRecord.mRewriteExpression.find("$") == Data::npos ) + { + flags |= REG_NOSUB; + } + route.preq = new regex_t; + int ret = regcomp( route.preq, route.routeRecord.mMatchingPattern.c_str(), flags ); + if( ret != 0 ) + { + delete route.preq; + route.preq = 0; + } + } + + { + WriteLock lock(mMutex); + mRouteOperators.insert( route ); + } + mCursor = mRouteOperators.begin(); + + return true; +} + + +/* +AbstractDb::RouteRecordList +RouteStore::getRoutes() const +{ + AbstractDb::RouteRecordList result; + result.reserve(mRouteOperators.size()); + + for (RouteOpList::const_iterator it = mRouteOperators.begin(); + it != mRouteOperators.end(); it++) + { + result.push_back(it->routeRecord); + } + return result; +} +*/ + + +void +RouteStore::eraseRoute(const resip::Data& method, + const resip::Data& event, + const resip::Data& matchingPattern) +{ + Key key = buildKey(method, event, matchingPattern); + eraseRoute(key); +} + + +void +RouteStore::eraseRoute(const resip::Data& key ) +{ + mDb.eraseRoute(key); + + { + WriteLock lock(mMutex); + + RouteOpList::iterator it = mRouteOperators.begin(); + while ( it != mRouteOperators.end() ) + { + if (it->key == key ) + { + RouteOpList::iterator i = it; + it++; + if ( i->preq ) + { + regfree ( i->preq ); + delete i->preq; + + // !abr! Can't modify elements in a set + //i->preq = 0; + + } + mRouteOperators.erase(i); + } + else + { + it++; + } + } + } + mCursor = mRouteOperators.begin(); // reset the cursor since it may have been on deleted route +} + + +bool +RouteStore::updateRoute( const resip::Data& originalKey, + const resip::Data& method, + const resip::Data& event, + const resip::Data& matchingPattern, + const resip::Data& rewriteExpression, + const int order ) +{ + eraseRoute(originalKey); + return addRoute(method, event, matchingPattern, rewriteExpression, order); +} + + +RouteStore::Key +RouteStore::getFirstKey() +{ + ReadLock lock(mMutex); + + mCursor = mRouteOperators.begin(); + if ( mCursor == mRouteOperators.end() ) + { + return Key( Data::Empty ); + } + + return mCursor->key; +} + +bool +RouteStore::findKey(const Key& key) +{ + // check if cursor happens to be at the key + if ( mCursor != mRouteOperators.end() ) + { + if ( mCursor->key == key ) + { + return true; + } + } + + // search for the key + mCursor = mRouteOperators.begin(); + while ( mCursor != mRouteOperators.end() ) + { + if ( mCursor->key == key ) + { + return true; // found the key + } + mCursor++; + } + return false; // key was not found +} + +RouteStore::Key +RouteStore::getNextKey(Key& key) +{ + ReadLock lock(mMutex); + + if ( !findKey(key) ) + { + return Key(Data::Empty); + } + + mCursor++; + + if ( mCursor == mRouteOperators.end() ) + { + return Key( Data::Empty ); + } + + return mCursor->key; +} + + +AbstractDb::RouteRecord +RouteStore::getRouteRecord(const resip::Data& key) +{ + ReadLock lock(mMutex); + + if (!findKey(key)) + { + return AbstractDb::RouteRecord(); + } + return mCursor->routeRecord; +} + + +RouteStore::UriList +RouteStore::process(const resip::Uri& ruri, + const resip::Data& method, + const resip::Data& event ) +{ + RouteStore::UriList targetSet; + if(mRouteOperators.empty()) return targetSet; // If there are no routes bail early to save a few cycles (size check is atomic enough, we don't need a lock) + + ReadLock lock(mMutex); + + for (RouteOpList::iterator it = mRouteOperators.begin(); + it != mRouteOperators.end(); it++) + { + DebugLog( << "Consider route " // << *it + << " reqUri=" << ruri + << " method=" << method + << " event=" << event ); + + const AbstractDb::RouteRecord& rec = it->routeRecord; + + if(!rec.mMethod.empty()) + { + if(!isEqualNoCase(rec.mMethod,method)) + { + DebugLog( << " Skipped - method did not match" ); + continue; + } + + } + if(!rec.mEvent.empty()) + { + if(!isEqualNoCase(rec.mEvent, event)) + { + DebugLog( << " Skipped - event did not match" ); + continue; + } + } + const Data& rewrite = rec.mRewriteExpression; + const Data& match = rec.mMatchingPattern; + if ( it->preq ) + { + int ret; + // TODO - !cj! www.pcre.org looks like it has better performance + // !mbg! is this true now that the compiled regexp is used? + Data uri; + { + DataStream s(uri); + s << ruri; + s.flush(); + } + + const int nmatch=10; + regmatch_t pmatch[nmatch]; + + ret = regexec(it->preq, uri.c_str(), nmatch, pmatch, 0/*eflags*/); + if ( ret != 0 ) + { + // did not match + DebugLog( << " Skipped - request URI "<< uri << " did not match " << match ); + continue; + } + + DebugLog( << " Route matched" ); + Data target = rewrite; + + if ( rewrite.find("$") != Data::npos ) + { + for ( int i=1; i<nmatch; i++) + { + if ( pmatch[i].rm_so != -1 ) + { + Data subExp(uri.substr(pmatch[i].rm_so, + pmatch[i].rm_eo-pmatch[i].rm_so)); + DebugLog( << " subExpression[" <<i <<"]="<< subExp ); + + Data result; + { + DataStream s(result); + + ParseBuffer pb(target); + + while (true) + { + const char* a = pb.position(); + pb.skipToChars( Data("$") + char('0'+i) ); + if ( pb.eof() ) + { + s << pb.data(a); + break; + } + else + { + s << pb.data(a); + pb.skipN(2); + s << subExp; + } + } + s.flush(); + } + target = result; + } + } + } + + Uri targetUri; + try + { + targetUri = Uri(target); + } + catch( BaseException& ) + { + ErrLog( << "Routing rule transform " << rewrite << " gave invalid URI " << target ); + try + { + targetUri = Uri( Data("sip:")+target); + } + catch( BaseException& ) + { + ErrLog( << "Routing rule transform " << rewrite << " gave invalid URI sip:" << target ); + continue; + } + } + targetSet.push_back( targetUri ); + } + } + + return targetSet; +} + + +RouteStore::Key +RouteStore::buildKey(const resip::Data& method, + const resip::Data& event, + const resip::Data& matchingPattern ) const +{ + // missing mOrder + // Data pKey = Data(order) + ":" + method + ":" + event + ":" + matchingPattern; + Data pKey = method+":"+event+":"+matchingPattern; + return pKey; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/RouteStore.hxx b/src/libs/resiprocate/repro/RouteStore.hxx new file mode 100644 index 00000000..d331c392 --- /dev/null +++ b/src/libs/resiprocate/repro/RouteStore.hxx @@ -0,0 +1,128 @@ +#if !defined(REPRO_ROUTESTORE_HXX) +#define REPRO_ROUTESTORE_HXX + +#ifdef WIN32 +#include <pcreposix.h> +#else +#include <regex.h> +#endif + +#include <set> + +#include "rutil/Data.hxx" +#include "rutil/RWMutex.hxx" +#include "resip/stack/Uri.hxx" + +#include "repro/AbstractDb.hxx" + + +namespace repro +{ +//class AbstractDb; + +class RouteStore +{ + public: + typedef std::vector<resip::Uri> UriList; + typedef resip::Data Key; + + RouteStore(AbstractDb& db); + ~RouteStore(); + + bool addRoute(const resip::Data& method, + const resip::Data& event, + const resip::Data& matchingPattern, + const resip::Data& rewriteExpression, + const int order ); + + void eraseRoute(const resip::Data& method, + const resip::Data& event, + const resip::Data& matchingPattern); + void eraseRoute( const resip::Data& key ); + + bool updateRoute( const resip::Data& originalKey, + const resip::Data& method, + const resip::Data& event, + const resip::Data& matchingPattern, + const resip::Data& rewriteExpression, + const int order ); + + AbstractDb::RouteRecord getRouteRecord(const resip::Data& key); + + Key getFirstKey();// return empty if no more + Key getNextKey(Key& key); // return empty if no more + + UriList process(const resip::Uri& ruri, + const resip::Data& method, + const resip::Data& event ); + + private: + bool findKey(const Key& key); // move cursor to key + + Key buildKey(const resip::Data& method, + const resip::Data& event, + const resip::Data& matchingPattern ) const; + + AbstractDb& mDb; + + class RouteOp + { + public: + Key key; + regex_t *preq; + AbstractDb::RouteRecord routeRecord; + bool operator<(const RouteOp&) const; + }; + + resip::RWMutex mMutex; + typedef std::multiset<RouteOp> RouteOpList; + RouteOpList mRouteOperators; + RouteOpList::iterator mCursor; +}; + + } +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/SiloStore.cxx b/src/libs/resiprocate/repro/SiloStore.cxx new file mode 100644 index 00000000..9f083dee --- /dev/null +++ b/src/libs/resiprocate/repro/SiloStore.cxx @@ -0,0 +1,119 @@ +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Lock.hxx" + +#include "resip/stack/SipMessage.hxx" + +#include "repro/SiloStore.hxx" +#include "rutil/WinLeakCheck.hxx" + + +using namespace resip; +using namespace repro; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + + +SiloStore::SiloStore(AbstractDb& db): + mDb(db) +{ +} + +SiloStore::~SiloStore() +{ +} + +bool +SiloStore::addMessage(const resip::Data& destUri, + const resip::Data& sourceUri, + time_t originalSendTime, + const resip::Data& tid, + const resip::Data& mimeType, + const resip::Data& messageBody) +{ + AbstractDb::SiloRecord rec; + rec.mDestUri = destUri; + rec.mSourceUri = sourceUri; + rec.mOriginalSentTime = originalSendTime; + rec.mTid = tid; + rec.mMimeType = mimeType; + rec.mMessageBody = messageBody; + + Key key = buildKey(originalSendTime, tid); + return mDb.addToSilo(key, rec); +} + +bool +SiloStore::getSiloRecords(const Data& uri, AbstractDb::SiloRecordList& recordList) +{ + // Note: This fn uses the secondary cursor, and cleanupExpiredSiloRecords uses the + // primary cursor, so there should be no need to provide locking at this level (at + // least that's the theory - assuming the db performs it's own locking properly) + return mDb.getSiloRecords(uri, recordList); +} + +void +SiloStore::deleteSiloRecord(time_t originalSendTime, const resip::Data& tid) +{ + Key key = buildKey(originalSendTime, tid); + mDb.eraseSiloRecord(key); +} + +void +SiloStore::cleanupExpiredSiloRecords(UInt64 now, unsigned long expirationTime) +{ + mDb.cleanupExpiredSiloRecords(now, expirationTime); +} + +SiloStore::Key +SiloStore::buildKey(time_t originalSendTime, const resip::Data& tid) const +{ + Key key((UInt64)originalSendTime); + key += ":" + tid; + return key; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/SiloStore.hxx b/src/libs/resiprocate/repro/SiloStore.hxx new file mode 100644 index 00000000..f3165092 --- /dev/null +++ b/src/libs/resiprocate/repro/SiloStore.hxx @@ -0,0 +1,87 @@ +#if !defined(REPRO_SILOSTORE_HXX) +#define REPRO_SILOSTORE_HXX + +#include <time.h> +#include "rutil/Data.hxx" +#include "rutil/RWMutex.hxx" +#include "repro/AbstractDb.hxx" + +namespace resip +{ + class SipMessage; +} + +namespace repro +{ + +class SiloStore +{ + public: + typedef resip::Data Key; + + SiloStore(AbstractDb& db); + ~SiloStore(); + + bool addMessage(const resip::Data& destUri, + const resip::Data& sourceUri, + time_t originalSendTime, + const resip::Data& tid, + const resip::Data& mimeType, + const resip::Data& messageBody); + + bool getSiloRecords(const resip::Data& uri, AbstractDb::SiloRecordList& recordList); + void deleteSiloRecord(time_t originalSendTime, const resip::Data& tid); + void cleanupExpiredSiloRecords(UInt64 now, unsigned long expirationTime); + + private: + Key buildKey(time_t originalSendTime, const resip::Data& tid) const; + + AbstractDb& mDb; +}; + + } +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/StaticRegStore.cxx b/src/libs/resiprocate/repro/StaticRegStore.cxx new file mode 100644 index 00000000..55f228a7 --- /dev/null +++ b/src/libs/resiprocate/repro/StaticRegStore.cxx @@ -0,0 +1,197 @@ + +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Lock.hxx" + +#include "repro/StaticRegStore.hxx" + +using namespace resip; +using namespace repro; +using namespace std; + + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +StaticRegStore::StaticRegStore(AbstractDb& db): + mDb(db) +{ + AbstractDb::Key key = mDb.firstStaticRegKey(); + while (!key.empty()) + { + AbstractDb::StaticRegRecord rec = mDb.getStaticReg(key); + + try + { + Uri aor(rec.mAor); + NameAddr contact(rec.mContact); + NameAddrs paths; + Data path; + ParseBuffer pb(rec.mPath); + const char* anchor = pb.position(); + while(!pb.eof()) + { + pb.skipToChar(Symbols::COMMA[0]); + pb.data(path, anchor); + paths.push_back(NameAddr(path)); + if(!pb.eof()) pb.skipChar(); // skip over comma + anchor = pb.position(); + } + + mStaticRegList[make_pair(aor, contact.uri())] = StaticRegRecord(aor, contact, paths); + } + catch(resip::ParseBuffer::Exception& e) + { + // This should never happen, since the format should be verified before writing to DB + ErrLog(<<"Failed to load a static registration due to parse error: " << e); + } + + key = mDb.nextStaticRegKey(); + } +} + + +StaticRegStore::~StaticRegStore() +{ +} + + +bool +StaticRegStore::addStaticReg(const resip::Uri& aor, + const resip::NameAddr& contact, + const resip::NameAddrs& path) +{ + Data aorData(Data::from(aor)); + Data contactData(Data::from(contact)); + + // Add new Db Record + Key addKey = buildKey(aorData, contactData); + AbstractDb::StaticRegRecord rec; + rec.mAor = aorData; + rec.mContact = contactData; + NameAddrs::const_iterator it = path.begin(); + for(; it != path.end(); it++) + { + if(it != path.begin()) + { + rec.mPath += ","; + } + rec.mPath += Data::from(*it); + } + + InfoLog( << "Add StaticReg: key=" << addKey); + + if(!mDb.addStaticReg(addKey, rec)) + { + return false; + } + + Key removeKey; + { + WriteLock lock(mMutex); + std::pair<Uri, Uri> mapKey = make_pair(aor, contact.uri()); + StaticRegRecordMap::iterator it = mStaticRegList.find(mapKey); + if(it != mStaticRegList.end()) + { + // Exists already (Uri equalitiy for both aor and Uri portion of contact)- updatedb by removing + removeKey = buildKey(Data::from(it->second.mAor), Data::from(it->second.mContact)); + + // Update Map + it->second.mAor = aor; + it->second.mContact = contact; + it->second.mPath = path; + } + else + { + mStaticRegList[mapKey] = StaticRegRecord(aor, contact, path); + } + } + + // Do DB Work outside of local lock + if(!removeKey.empty()) + { + // Erase old DB record + mDb.eraseStaticReg(removeKey); + } + + return true; +} + + +void +StaticRegStore::eraseStaticReg(const resip::Uri& aor, + const resip::NameAddr& contact) +{ + Key removeKey; + { + WriteLock lock(mMutex); + StaticRegRecordMap::iterator it = mStaticRegList.find(make_pair(aor, contact.uri())); + if(it != mStaticRegList.end()) + { + // Exists (Uri equalitiy for both aor and Uri portion of contact) + removeKey = buildKey(Data::from(it->second.mAor), Data::from(it->second.mContact)); + + // Erase from local storage + mStaticRegList.erase(it); + } + } + + if(!removeKey.empty()) + { + // Erase DB record + mDb.eraseStaticReg(removeKey); + } +} + + +StaticRegStore::Key +StaticRegStore::buildKey(const resip::Data& aor, + const resip::Data& contact) const +{ + Data pKey = aor+":"+contact; + return pKey; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/StaticRegStore.hxx b/src/libs/resiprocate/repro/StaticRegStore.hxx new file mode 100644 index 00000000..6b7cbd00 --- /dev/null +++ b/src/libs/resiprocate/repro/StaticRegStore.hxx @@ -0,0 +1,100 @@ +#if !defined(REPRO_STATICREGSTORE_HXX) +#define REPRO_STATICREGSTORE_HXX + +#include <map> +#include "rutil/Data.hxx" +#include "rutil/RWMutex.hxx" +#include "resip/stack/NameAddr.hxx" +#include "repro/AbstractDb.hxx" + +namespace repro +{ + +class StaticRegStore +{ + public: + + typedef resip::Data Key; + + class StaticRegRecord + { + public: + StaticRegRecord() {} + StaticRegRecord(const resip::Uri& aor, const resip::NameAddr& contact, const resip::NameAddrs& path) : + mAor(aor), mContact(contact), mPath(path) {} + resip::Uri mAor; + resip::NameAddr mContact; + resip::NameAddrs mPath; + }; + // Note: The map key takes the contact uri and not the full NameAddr + typedef std::map<std::pair<resip::Uri, resip::Uri>, StaticRegRecord> StaticRegRecordMap; + + StaticRegStore(AbstractDb& db); + ~StaticRegStore(); + + bool addStaticReg(const resip::Uri& aor, + const resip::NameAddr& contact, + const resip::NameAddrs& path); + + void eraseStaticReg(const resip::Uri& aor, + const resip::NameAddr& contact); + + // Not thread safe + StaticRegRecordMap& getStaticRegList() { return mStaticRegList; } + + private: + AbstractDb& mDb; + + Key buildKey(const resip::Data& aor, + const resip::Data& contact) const; + + resip::RWMutex mMutex; + StaticRegRecordMap mStaticRegList; +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/Store.cxx b/src/libs/resiprocate/repro/Store.cxx new file mode 100644 index 00000000..a745b36c --- /dev/null +++ b/src/libs/resiprocate/repro/Store.cxx @@ -0,0 +1,82 @@ +#include <cassert> + +#include "rutil/Logger.hxx" + +#include "repro/Store.hxx" +#include "repro/AbstractDb.hxx" + + +using namespace resip; +using namespace repro; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + + +Store::Store(AbstractDb& db, AbstractDb* runtimedb): + mUserStore(runtimedb ? *runtimedb : db), + mRouteStore(db), + mAclStore(db), + mConfigStore(db), + mStaticRegStore(db), + mFilterStore(db), + mSiloStore(runtimedb ? *runtimedb : db) +{ +} + + +Store::~Store() +{ +} + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/Store.hxx b/src/libs/resiprocate/repro/Store.hxx new file mode 100644 index 00000000..95b4259f --- /dev/null +++ b/src/libs/resiprocate/repro/Store.hxx @@ -0,0 +1,88 @@ +#if !defined(REPRO_STORE_HXX) +#define REPRO_STORE_HXX + +#include "repro/AbstractDb.hxx" +#include "repro/UserStore.hxx" +#include "repro/RouteStore.hxx" +#include "repro/AclStore.hxx" +#include "repro/ConfigStore.hxx" +#include "repro/StaticRegStore.hxx" +#include "repro/FilterStore.hxx" +#include "repro/SiloStore.hxx" + +namespace repro +{ +class AbstractDb; + +/** The Store contains differnt types of stores such as user, route, etc. These + * use the AbstractDb to persist their data. */ +class Store +{ + public: + // If a seperate instance of AbstractDb is desired for the runtime database tables + // (ie. UserStore and SiloStore), then is can be provided, otherwise pass NULL. + // The Users and MessageSilo database tables are different from the other repro + // configuration database tables, in that they are accessed at runtime as SIP + // requests arrive. It may be desirable to use BerkeleyDb for the other repro + // tables (which are read at starup time, then cached in memory), and MySQL for + // the runtime accessed tables; or two seperate MySQL instances for these different + // table sets. + Store(AbstractDb& db, AbstractDb* runtimedb=0); + ~Store(); + + UserStore mUserStore; + RouteStore mRouteStore; + AclStore mAclStore; + ConfigStore mConfigStore; + StaticRegStore mStaticRegStore; + FilterStore mFilterStore; + SiloStore mSiloStore; + private: +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/Target.cxx b/src/libs/resiprocate/repro/Target.cxx new file mode 100644 index 00000000..9eba1b8c --- /dev/null +++ b/src/libs/resiprocate/repro/Target.cxx @@ -0,0 +1,173 @@ +#include "repro/Target.hxx" + +#include "resip/stack/Uri.hxx" +#include "resip/stack/NameAddr.hxx" +#include "rutil/Data.hxx" +#include "resip/stack/Via.hxx" +#include "repro/Proxy.hxx" +#include "rutil/WinLeakCheck.hxx" + +namespace repro +{ + +Target::Target() + :mPriorityMetric(0), + mShouldAutoProcess(true), + mStatus(Candidate), + mKeyValueStore(*Proxy::getTargetKeyValueStoreKeyAllocator()) +{} + +Target::Target(const resip::Uri& uri) + :mPriorityMetric(0), + mShouldAutoProcess(true), + mStatus(Candidate), + mKeyValueStore(*Proxy::getTargetKeyValueStoreKeyAllocator()) +{ + mRec.mContact.uri()=uri; +} + +Target::Target(const resip::NameAddr& target) + :mPriorityMetric(0), + mShouldAutoProcess(true), + mStatus(Candidate), + mKeyValueStore(*Proxy::getTargetKeyValueStoreKeyAllocator()) +{ + mRec.mContact=target; +} + +Target::Target(const resip::ContactInstanceRecord& rec) + :mPriorityMetric(0), + mShouldAutoProcess(true), + mStatus(Candidate), + mRec(rec) +{ +} + +Target::~Target() +{ +} + +const resip::Data& +Target::tid() const +{ + return mVia.param(resip::p_branch).getTransactionId(); +} + +Target::Status& +Target::status() +{ + return mStatus; +} + +const Target::Status& +Target::status() const +{ + return mStatus; +} + +const resip::Via& +Target::setVia(const resip::Via& via) +{ + return mVia=via; +} + +const resip::Via& +Target::via() const +{ + return mVia; +} + +const resip::ContactInstanceRecord& +Target::rec() const +{ + return mRec; +} + +resip::ContactInstanceRecord& +Target::rec() +{ + return mRec; +} + +void +Target::setRec(const resip::ContactInstanceRecord& rec) +{ + mRec=rec; +} + +Target* +Target::clone() const +{ + return new Target(*this); +} + +int +Target::getPriority() const +{ + return mPriorityMetric; +} + +bool +Target::shouldAutoProcess() const +{ + return mShouldAutoProcess; +} + +EncodeStream& +operator<<(EncodeStream& strm, const repro::Target& t) +{ + strm << "Target: " << t.uri() << " status=" << t.status(); + return strm; +} + +} // namespace repro + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/Target.hxx b/src/libs/resiprocate/repro/Target.hxx new file mode 100644 index 00000000..cf4406ec --- /dev/null +++ b/src/libs/resiprocate/repro/Target.hxx @@ -0,0 +1,139 @@ +#ifndef TARGET_HXX +#define TARGET_HXX 1 + +#include <list> +#include <vector> + +#include "resip/stack/Uri.hxx" +#include "resip/stack/NameAddr.hxx" +#include "rutil/Data.hxx" +#include "resip/stack/Via.hxx" +#include "resip/dum/ContactInstanceRecord.hxx" +#include "rutil/KeyValueStore.hxx" + +namespace repro +{ + +class Target +{ + public: + + typedef enum + { + Candidate, //Transaction has not started + Started, //Transaction has started, no final responses + Cancelled, //Transaction has been cancelled, but no final response yet + Terminated, //Transaction has received a final response + NonExistent //The state of transactions that do not exist + } Status; + + Target(); + Target(const resip::Uri& uri); + Target(const resip::NameAddr& target); + Target(const resip::ContactInstanceRecord& record); + + virtual ~Target(); + + virtual const resip::Data& tid() const; + + virtual Status& status(); + virtual const Status& status() const; + + virtual const resip::Via& setVia(const resip::Via& via); + virtual const resip::Via& via() const; + + virtual const resip::Uri& uri() const {return mRec.mContact.uri();} + + virtual const resip::ContactInstanceRecord& rec() const; + virtual resip::ContactInstanceRecord& rec(); + virtual void setRec(const resip::ContactInstanceRecord& rec); + + virtual Target* clone() const; + + //In case you need const accessors to keep things happy. + virtual int getPriority() const; + virtual bool shouldAutoProcess() const; + + // Accessor for per-target extensible state storage for monkeys + resip::KeyValueStore& getKeyValueStore() { return mKeyValueStore; } + + static bool priorityMetricCompare(const Target* lhs, const Target* rhs) + { + return lhs->mPriorityMetric > rhs->mPriorityMetric; + } + + /** + Higher value denotes higher priority. + */ + int mPriorityMetric; + bool mShouldAutoProcess; + + protected: + Status mStatus; + resip::Via mVia; + resip::ContactInstanceRecord mRec; + resip::KeyValueStore mKeyValueStore; +};// class Target + +#ifdef __SUNPRO_CC +typedef std::vector<Target*> TargetPtrList; +#else +typedef std::list<Target*> TargetPtrList; +#endif + +EncodeStream& +operator<<(EncodeStream& strm, const repro::Target& t); + +}// namespace repro + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/TimerCMessage.hxx b/src/libs/resiprocate/repro/TimerCMessage.hxx new file mode 100644 index 00000000..da482297 --- /dev/null +++ b/src/libs/resiprocate/repro/TimerCMessage.hxx @@ -0,0 +1,36 @@ +#ifndef TIMER_C_MESSAGE_HXX +#define TIMER_C_MESSAGE_HXX 1 + +#include "resip/stack/ApplicationMessage.hxx" + +#include "rutil/Data.hxx" +#include <time.h> +#include "rutil/resipfaststreams.hxx" + +namespace repro +{ + +class TimerCMessage : public resip::ApplicationMessage +{ + public: + TimerCMessage(resip::Data tid,int serial): + mSerial(serial), + mTid(tid) + {} + + ~TimerCMessage(){} + + virtual const resip::Data& getTransactionId() const { return mTid; } + virtual TimerCMessage* clone() const {return new TimerCMessage(mTid,mSerial);} + virtual EncodeStream& encode(EncodeStream& ostr) const { ostr << "TimerCMessage(tid="<<mTid<<")"; return ostr; } + virtual EncodeStream& encodeBrief(EncodeStream& ostr) const { return encode(ostr);} + + int mSerial; + + private: + TimerCMessage(){} + resip::Data mTid; + +}; +} +#endif diff --git a/src/libs/resiprocate/repro/USING b/src/libs/resiprocate/repro/USING new file mode 100644 index 00000000..79a3c199 --- /dev/null +++ b/src/libs/resiprocate/repro/USING @@ -0,0 +1,105 @@ +USING REPRO +This guide describes briefly how to get started using repro. For help +compiling or installing repro, please see the INSTALL file. + +1) Run repro +Run the executable from the command line. A number of command line options +are available. For a summary of options run repro with the help option: + +%repro --help + +Usage: repro [OPTION...] + -l, --log-type=syslog|cerr|cout where to send logging messages + (default: "cout") + -v, --log-level=DEBUG|INFO|WARNING|ALERT specify the default log level + (default: "INFO") + -t, --tls-domain=example.com act as a TLS server for + specified domain + -x, --mysqlServer=localhost enable MySQL and provide name + of server (default: null) + --udp=5060 add UDP transport on specified + port (default: 5060) + --tcp=5060 add TCP transport on specified + port (default: 5060) + --tls=5061 add TLS transport on specified + port (default: 5061) + --dtls=5061 add DTLS transport on specified + port (default: 0) + --enable-v6 disable IPV6 + --disable-v4 disable IPV4 + --disable-auth disable DIGEST challenges + --disable-web-auth disable HTTP challenges + --disable-reg disable registrar + --enable-cert-server run a cert server + -d, --domains=example.com,foo.com specify domains that this proxy + is authorative + -c, --cert-path=STRING path for certificates (default: + ~/.sipCerts) (default: + "/Users/rohan/.sipCerts") + --reqChainName=STRING name of request chain (default: + default) + --http=5080 run HTTP server on specified + port (default: 5080) + +Help options: + -?, --help Show this help message + --usage Display brief usage message +% + +Running the proxy server with the default options is fine. If you are +troubleshooting, we recommend that you enable DEBUG level logging: + +% ./repro -v DEBUG + + +2) Access the WebAdmin pages +Now access the HTTP WebAdmin. The WebAdmin run on port 5080 by default, or a +specific port if you specified it on the command line with the "--http" +command-line option. + +Login for the first time with the initial username: admin and the password +"admin". + +3) Add domains +You must add at least one "domain" before you can use the proxy server. The +domains are names that the proxy recognizes after the at-sign (@) in the +SIP URI. The list of domains is used by the proxy and the registrar to decide +if repro is responsible for SIP requests it receives. The WebAdmin also uses +the list of domains to make sure users you add are in one of the domains. + +For example, if you want the proxy to answer requests for atlanta.com, you +need to add atlanta.com to the list of domains. You still need to make sure +that you configure DNS so that SIP requests for that domain resolve to repro. + +If you don't have a fully qualified domain name, you can use your IP address +as a "domain". + +4) Add users +Next add users. The mandatory fields are the username and the domain. The +password is the SIP Digest password. + +You can view the existing users from the Show Users page. + +5) Make a test call +After adding a user you should try to register. You can check the status of +the registration from the Registrations page on the WebAdmin. + +6) About Routes and ACLs +Routes are used by repro to send certain requests to a particular location. +The static routes use (POSIX-standard) regular expression to match and +rewrite SIP URIs. The screenshot shows an example of sending all requests +that consist of only digits in the userpart of the SIP URI to a gateway. +Note that to match characters that have a special meaning in regular expression +(like a "."), you need to escape these. You can also use variable substitution +in the rewrite expression. The string inside the first set of parentheses () +is referenced in the rewrite string as $1, the second is $2, etc. + +Since it is easy to make mistakes entering regular expressions, you can test +your static routes in the Show Routes page. Type in a SIP URI, click Test Route. +You should see the rewritten URL below. + +Access Control Lists (ACLs) are not used by the proxy in this release, but will +be used to allow unauthenticated access to relay requests and access routes in +a future release. + + diff --git a/src/libs/resiprocate/repro/USING.html b/src/libs/resiprocate/repro/USING.html new file mode 100644 index 00000000..b81d6102 --- /dev/null +++ b/src/libs/resiprocate/repro/USING.html @@ -0,0 +1,134 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + <meta content="text/html; charset=ISO-8859-1" + http-equiv="content-type"> + <title>Using Repro</title> +</head> +<body> +<h1>Using Repro</h1> +This guide describes briefly how to get started using repro. For +help compiling or installing repro, please see the <a + href="http://scm.sipfoundry.org/rep/resiprocate/main/sip/repro/INSTALL.html">INSTALL</a> +file.<br> +<br> +<h2>1) Run repro</h2> +Run the executable from the command line. A number of command +line options are available. For a summary of options run repro +with the help option:<br> +<br> +<pre>%repro --help</pre> +<pre>Usage: repro [OPTION...]</pre> +<pre> -l, --log-type=syslog|cerr|cout where to send logging messages</pre> +<pre> (default: "cout")</pre> +<pre> -v, --log-level=DEBUG|INFO|WARNING|ALERT specify the default log level</pre> +<pre> (default: "INFO")</pre> +<pre> -t, --tls-domain=example.com act as a TLS server for</pre> +<pre> specified domain</pre> +<pre> -x, --mysqlServer=localhost enable MySQL and provide name</pre> +<pre> of server (default: null)</pre> +<pre> --udp=5060 add UDP transport on specified</pre> +<pre> port (default: 5060)</pre> +<pre> --tcp=5060 add TCP transport on specified</pre> +<pre> port (default: 5060)</pre> +<pre> --tls=5061 add TLS transport on specified</pre> +<pre> port (default: 5061)</pre> +<pre> --dtls=5061 add DTLS transport on specified</pre> +<pre> port (default: 0)</pre> +<pre> --enable-v6 enable IPV6</pre> +<pre> --disable-v4 disable IPV4</pre> +<pre> --disable-auth disable DIGEST challenges</pre> +<pre> --disable-web-auth disable HTTP challenges</pre> +<pre> --disable-reg disable registrar</pre> +<pre> --enable-cert-server run a cert server</pre> +<pre> -d, --domains=example.com,foo.com specify domains that this proxy</pre> +<pre> is authorative</pre> +<pre> -c, --cert-path=STRING path for certificates (default:</pre> +<pre> ~/.sipCerts) (default:</pre> +<pre> "/Users/rohan/.sipCerts")</pre> +<pre> --reqChainName=STRING name of request chain (default:</pre> +<pre> default)</pre> +<pre> --http=5080 run HTTP server on specified</pre> +<pre> port (default: 5080)</pre> +<pre><br>Help options:</pre> +<pre> -?, --help Show this help message</pre> +<pre> --usage Display brief usage message</pre> +<pre>%</pre> +<br> +Running the proxy server with the default options is fine. If you +are troubleshooting, we recommend that you enable DEBUG level logging:<br> +<pre>% ./repro -v DEBUG</pre> +<br> +<h2>2) Access the WebAdmin pages</h2> +Now access the HTTP WebAdmin. The WebAdmin run on port 5080 by default, +or a specific port if you specified it on the command line with the +"--http" command-line option.<br> +<br> +Login for the first time with the initial username: admin and the +password "admin".<br> +<br> +<img alt="login screenshot" src="doc/repro-login.png" + style="width: 446px; height: 192px;"><br> +<h2>3) Add domains</h2> +You must add at least one "domain" before you can use the proxy server. +The domains are names that the proxy recognizes after the at-sign (@) +in the SIP URI. The list of domains is used by the proxy and the +registrar to decide if repro is responsible for SIP requests it +receives. The WebAdmin also uses the list of domains to make sure +users you add are in one of the domains. <br> +<br> +For example, if you want the proxy to answer requests for atlanta.com, +you need to add atlanta.com to the list of domains. You still +need to make sure that you configure DNS so that SIP requests for that +domain resolve to repro.<br> +<br> +If you don't have a fully qualified domain name, you can use your IP +address as a "domain".<br> +<br> +<img alt="domain page screenshot" src="doc/repro-domains.png" + style="width: 701px; height: 300px;"><br> +<br> +<h2>4) Add users</h2> +Next add users. The mandatory fields are the username and the +domain. The password is the SIP Digest password.<br> +<br> +<img alt="addUser page screenshot" src="doc/repro-addUser.png" + style="width: 474px; height: 310px;"><br> +<br> +You can view the existing users from the Show Users page.<br> +<br> +<img alt="showUsers page screenshot" src="doc/repro-showUsers.png" + style="width: 608px; height: 356px;"><br> +<br> +<h2>5) Make a test call</h2> +After adding a user you should try to register. You can check the +status of the registration from the Registrations page on the WebAdmin.<br> +<br> +<h2>6) About Routes and ACLs</h2> +Routes are used by repro to send certain requests to a particular +location. The static routes use (POSIX-standard) regular expression to +match and rewrite SIP URIs. The screenshot shows an example of +sending all requests that consist of only digits in the userpart of the +SIP URI to a gateway. Note that to match characters that have a +special meaning in regular expression (like a "."), you need to escape +these. You can also use variable substitution in the rewrite +expression. The string inside the first set of parentheses () is +referenced in the rewrite string as $1, the second is $2, etc.<br> +<br> +<img alt="addRoute page screenshot" src="doc/repro-addRoute.png" + style="width: 464px; height: 298px;"><br> +<br> +Since it is easy to make mistakes entering regular expressions, you can +test your static routes in the Show Routes page. Type in a SIP URI, +click Test Route. You should see the rewritten URL below.<br> +<br> +<img alt="showRoutes page screenshot" src="doc/repro-showRoutes.png" + style="width: 769px; height: 316px;"><br> +<br> +Access Control Lists (ACLs) are not used by the proxy in this release, +but will be used to allow unauthenticated access to relay requests and +access routes in a future release.<br> +<br> +<br> +</body> +</html> diff --git a/src/libs/resiprocate/repro/UserAuthGrabber.hxx b/src/libs/resiprocate/repro/UserAuthGrabber.hxx new file mode 100644 index 00000000..1a0d02da --- /dev/null +++ b/src/libs/resiprocate/repro/UserAuthGrabber.hxx @@ -0,0 +1,117 @@ +#ifndef USER_AUTH_GRABBER +#define USER_AUTH_GRABBER 1 + +#include "repro/Worker.hxx" +#include "repro/AbstractDb.hxx" +#include "repro/UserStore.hxx" +#include "resip/stack/Message.hxx" +#include "repro/UserInfoMessage.hxx" +#include "resip/dum/UserAuthInfo.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + + +namespace repro +{ + +class UserAuthGrabber : public Worker +{ + public: + UserAuthGrabber(repro::UserStore& userStore ): + mUserStore(userStore) + {} + + virtual ~UserAuthGrabber(){} + + virtual bool process(resip::ApplicationMessage* msg) + { + repro::UserInfoMessage* uinf = dynamic_cast<UserInfoMessage*>(msg); // auth for repro's DigestAuthenticator + resip::UserAuthInfo* uainf = dynamic_cast<resip::UserAuthInfo*>(msg); // auth for DUM's ServerAuthManager + if(uinf) + { + uinf->mRec.passwordHash = mUserStore.getUserAuthInfo(uinf->user(), uinf->realm()); + DebugLog(<<"Grabbed user info for " + << uinf->user() <<"@"<<uinf->realm() + << " : " << uinf->A1()); + return true; + } + else if(uainf) + { + uainf->setA1(mUserStore.getUserAuthInfo(uainf->getUser(), uainf->getRealm())); + if(uainf->getA1().empty()) + { + uainf->setMode(resip::UserAuthInfo::UserUnknown); + } + DebugLog(<<"Grabbed user info for " + << uainf->getUser() <<"@"<<uainf->getRealm() + << " : " << uainf->getA1()); + return true; + } + else + { + WarningLog(<<"Did not recognize message type..."); + } + return false; + } + + virtual UserAuthGrabber* clone() const + { + return new UserAuthGrabber(mUserStore); + } + + protected: + UserStore& mUserStore; +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/UserInfoMessage.hxx b/src/libs/resiprocate/repro/UserInfoMessage.hxx new file mode 100644 index 00000000..421f2cbb --- /dev/null +++ b/src/libs/resiprocate/repro/UserInfoMessage.hxx @@ -0,0 +1,97 @@ +#ifndef USER_INFO_MESSAGE_HXX +#define USER_INFO_MESSAGE_HXX 1 + +#include "repro/ProcessorMessage.hxx" +#include "repro/AbstractDb.hxx" + +namespace repro +{ + +class UserInfoMessage : public ProcessorMessage +{ + public: + UserInfoMessage(Processor& proc, + const resip::Data& tid, + resip::TransactionUser* passedtu): + ProcessorMessage(proc,tid,passedtu) + { + } + + UserInfoMessage(const UserInfoMessage& orig): + ProcessorMessage(orig) + { + mRec=orig.mRec; + } + + const resip::Data& user() const{return mRec.user;} + resip::Data& user(){return mRec.user;} + + const resip::Data& realm() const{return mRec.realm;} + resip::Data& realm(){return mRec.realm;} + + const resip::Data& domain() const{return mRec.domain;} + resip::Data& domain(){return mRec.domain;} + + const resip::Data& A1() const{return mRec.passwordHash;} + resip::Data& A1(){return mRec.passwordHash;} + + virtual UserInfoMessage* clone() const {return new UserInfoMessage(*this);}; + + virtual EncodeStream& encode(EncodeStream& ostr) const { ostr << "UserInfoMessage(tid="<<mTid<<")"; return ostr; }; + virtual EncodeStream& encodeBrief(EncodeStream& ostr) const { return encode(ostr);} + + AbstractDb::UserRecord mRec; +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/UserStore.cxx b/src/libs/resiprocate/repro/UserStore.cxx new file mode 100644 index 00000000..eddd6298 --- /dev/null +++ b/src/libs/resiprocate/repro/UserStore.cxx @@ -0,0 +1,201 @@ + + +#include <cassert> + +#include "rutil/Data.hxx" +#include "rutil/MD5Stream.hxx" +#include "rutil/DataStream.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/TransactionUser.hxx" +#include "resip/dum/UserAuthInfo.hxx" + +#include "repro/UserStore.hxx" +#include "repro/AbstractDb.hxx" +#include "rutil/WinLeakCheck.hxx" + + +using namespace resip; +using namespace repro; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +UserStore::UserStore(AbstractDb& db ): + mDb(db) +{ +} + +UserStore::~UserStore() +{ +} + + +AbstractDb::UserRecord +UserStore::getUserInfo( const Key& key ) const +{ + return mDb.getUser(key); +} + + +Data +UserStore::getUserAuthInfo( const resip::Data& user, + const resip::Data& realm ) const +{ + Key key = buildKey(user, realm); + return mDb.getUserAuthInfo( key ); +} + + +bool +UserStore::addUser( const Data& username, + const Data& domain, + const Data& realm, + const Data& password, + bool applyA1HashToPassword, + const Data& fullName, + const Data& emailAddress, + const Data& passwordHashAlt) +{ + AbstractDb::UserRecord rec; + rec.user = username; + rec.domain = domain; + rec.realm = realm; + if(applyA1HashToPassword) + { + MD5Stream a1; + a1 << username + << Symbols::COLON + << realm + << Symbols::COLON + << password; + a1.flush(); + rec.passwordHash = a1.getHex(); + + // Some UAs might calculate A1 + // using user@domain:realm:password + // so we store the hash of that permutation too + MD5Stream a1b; + a1b << username << Symbols::AT_SIGN << domain + << Symbols::COLON + << realm + << Symbols::COLON + << password; + a1b.flush(); + rec.passwordHashAlt = a1b.getHex(); + } + else + { + rec.passwordHash = password; + rec.passwordHashAlt = passwordHashAlt; + } + rec.name = fullName; + rec.email = emailAddress; + rec.forwardAddress = Data::Empty; + + return mDb.addUser( buildKey(username,domain), rec); +} + + +void +UserStore::eraseUser( const Key& key ) +{ + mDb.eraseUser( key ); +} + +bool +UserStore::updateUser( const Key& originalKey, + const resip::Data& user, + const resip::Data& domain, + const resip::Data& realm, + const resip::Data& password, + bool applyA1HashToPassword, + const resip::Data& fullName, + const resip::Data& emailAddress, + const resip::Data& passwordHashAlt) +{ + Key newkey = buildKey(user, domain); + + bool ret = addUser(user, domain, realm, password, applyA1HashToPassword, fullName, emailAddress, passwordHashAlt); + if ( newkey != originalKey ) + { + eraseUser(originalKey); + } + return ret; +} + + +UserStore::Key +UserStore::getFirstKey() +{ + return mDb.firstUserKey(); +} + + +UserStore::Key +UserStore::getNextKey() +{ + return mDb.nextUserKey(); +} + + +UserStore::Key +UserStore::buildKey( const resip::Data& user, + const resip::Data& realm) const +{ + Data ret = user + Data("@") + realm; + return ret; +} + + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/UserStore.hxx b/src/libs/resiprocate/repro/UserStore.hxx new file mode 100644 index 00000000..154aaf75 --- /dev/null +++ b/src/libs/resiprocate/repro/UserStore.hxx @@ -0,0 +1,110 @@ +#if !defined(REPRO_USERSTORE_HXX) +#define REPRO_USERSTORE_HXX + +#include "rutil/Data.hxx" +#include "rutil/Fifo.hxx" +#include "resip/stack/Message.hxx" + +#include "repro/AbstractDb.hxx" + +namespace resip +{ + class TransactionUser; +} + +namespace repro +{ + +typedef resip::Fifo<resip::Message> MessageFifo; + +class UserStore +{ + public: + typedef resip::Data Key; + + UserStore(AbstractDb& db); + + virtual ~UserStore(); + + AbstractDb::UserRecord getUserInfo( const Key& key ) const; + + resip::Data getUserAuthInfo( const resip::Data& user, + const resip::Data& realm ) const; + + bool addUser( const resip::Data& user, + const resip::Data& domain, + const resip::Data& realm, + const resip::Data& password, + bool applyA1HashToPassword, + const resip::Data& fullName, + const resip::Data& emailAddress, + const resip::Data& passwordHashAlt = resip::Data::Empty); // Only required if applyA1HashToPassword is false + + void eraseUser( const Key& key ); + + bool updateUser( const Key& originalKey, + const resip::Data& user, + const resip::Data& domain, + const resip::Data& realm, + const resip::Data& password, + bool applyA1HashToPassword, + const resip::Data& fullName, + const resip::Data& emailAddress, + const resip::Data& passwordHashAlt = resip::Data::Empty); // Only required if applyA1HashToPassword is false + + Key getFirstKey();// return empty if no more + Key getNextKey(); // return empty if no more + + private: + Key buildKey( const resip::Data& user, + const resip::Data& domain) const; + + AbstractDb& mDb; +}; + + } +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/VERSION b/src/libs/resiprocate/repro/VERSION new file mode 100644 index 00000000..2e0e38c6 --- /dev/null +++ b/src/libs/resiprocate/repro/VERSION @@ -0,0 +1 @@ +1.9 diff --git a/src/libs/resiprocate/repro/WebAdmin.cxx b/src/libs/resiprocate/repro/WebAdmin.cxx new file mode 100644 index 00000000..6935516b --- /dev/null +++ b/src/libs/resiprocate/repro/WebAdmin.cxx @@ -0,0 +1,2022 @@ +#include <cassert> +#include <time.h> + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "resip/dum/RegistrationPersistenceManager.hxx" +#include "resip/stack/Symbols.hxx" +#include "resip/stack/Tuple.hxx" +#include "resip/stack/SipStack.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/MD5Stream.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Timer.hxx" +#include "rutil/TransportType.hxx" + +#include "repro/ReproVersion.hxx" +#include "repro/Proxy.hxx" +#include "repro/HttpBase.hxx" +#include "repro/HttpConnection.hxx" +#include "repro/WebAdmin.hxx" +#include "repro/RouteStore.hxx" +#include "repro/UserStore.hxx" +#include "repro/FilterStore.hxx" +#include "repro/Store.hxx" + +#ifdef USE_SSL +#include "resip/stack/ssl/Security.hxx" +#endif + +using namespace resip; +using namespace repro; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +#define REPRO_BORDERLESS_TABLE_PROPS " border=\"0\" cellspacing=\"2\" cellpadding=\"0\"" +#define REPRO_BORDERED_TABLE_PROPS " border=\"1\" cellspacing=\"1\" cellpadding=\"1\" bgcolor=\"#ffffff\"" + +WebAdmin::RemoveKey::RemoveKey(const Data &key1, const Data &key2) : mKey1(key1), mKey2(key2) +{ +}; + +bool +WebAdmin::RemoveKey::operator<(const RemoveKey& rhs) const +{ + if(mKey1 < rhs.mKey1) + { + return true; + } + else if(mKey1 == rhs.mKey1 && mKey2 < rhs.mKey2) + { + return true; + } + else + { + return false; + } +} + +WebAdmin::WebAdmin(Proxy& proxy, + RegistrationPersistenceManager& regDb, + const Data& realm, // this realm is used for http challenges + int port, + IpVersion version ): + HttpBase(port, version, realm), + mProxy(proxy), + mStore(*mProxy.getConfig().getDataStore()), + mRegDb(regDb), + mNoWebChallenges(proxy.getConfig().getConfigBool("DisableHttpAuth", false)), + mPageOutlinePre( +#include "repro/webadmin/pageOutlinePre.ixx" + ), + mPageOutlinePost( +#include "repro/webadmin/pageOutlinePost.ixx" + ) +{ + const Data adminName("admin"); + const Data adminPassword= mProxy.getConfig().getConfigData("HttpAdminPassword", "admin"); + + // Place repro version into PageOutlinePre + mPageOutlinePre.replace("VERSION", VersionUtils::instance().releaseVersion().c_str()); + + Data dbA1 = mStore.mUserStore.getUserAuthInfo( adminName, Data::Empty ); + + DebugLog(<< " Looking to see if admin user exists (creating WebAdmin)"); + if ( dbA1.empty() ) // if the admin user does not exist, add it + { + DebugLog(<< "Creating admin user" ); + + mStore.mUserStore.addUser(adminName, // user + Data::Empty, // domain + Data::Empty, // realm + (adminPassword == "" ? Data("admin") : adminPassword), // password + true, // applyA1HashToPassword + Data::Empty, // name + Data::Empty ); // email + dbA1 = mStore.mUserStore.getUserAuthInfo( adminName, Data::Empty ); + assert(!dbA1.empty()); + } + else if (adminPassword!=Data("")) + { + //All we're using for admin is the password. + //This next bit of code relies on it being ok that we + //blow away any other information + //in that row. It also expects addUser to replace anything matching the existing key + DebugLog(<< "Changing the web admin password" ); + mStore.mUserStore.addUser(adminName, + Data::Empty, + Data::Empty, + adminPassword, + true, // applyA1HashToPassword + Data::Empty, + Data::Empty); + } +} + + +void +WebAdmin::buildPage( const Data& uri, + int pageNumber, + const resip::Data& pUser, + const resip::Data& pPassword ) +{ + ParseBuffer pb(uri); + + DebugLog (<< "Parsing URL" << uri ); + + const char* anchor = pb.skipChar('/'); + pb.skipToChar('?'); + Data pageName; + pb.data(pageName,anchor); + + DebugLog (<< " got page name: " << pageName ); + + // if this is not a valid page, redirect it + if ( + ( pageName != Data("index.html") ) && + ( pageName != Data("input") ) && + ( pageName != Data("cert.cer") ) && + ( ! pageName.prefix("cert") ) && + ( pageName != Data("userTest.html") ) && + ( pageName != Data("domains.html") ) && + ( pageName != Data("acls.html") ) && + ( pageName != Data("addUser.html") ) && + ( pageName != Data("editUser.html") ) && + ( pageName != Data("showUsers.html") ) && + ( pageName != Data("addFilter.html") ) && + ( pageName != Data("editFilter.html") ) && + ( pageName != Data("showFilters.html") )&& + ( pageName != Data("addRoute.html") ) && + ( pageName != Data("editRoute.html") ) && + ( pageName != Data("showRoutes.html") )&& + ( pageName != Data("registrations.html") ) && + ( pageName != Data("settings.html") ) && + ( pageName != Data("restart.html") ) && + ( pageName != Data("user.html") ) ) + { + setPage( resip::Data::Empty, pageNumber, 301 ); + return; + } + + // pages anyone can use + if ( pageName == Data("index.html") ) + { + setPage( buildDefaultPage(), pageNumber, 200); + return; + } + + // certificate pages + if ( pageName.prefix("cert") || pageName == Data("cert.cer") ) + { +#ifdef USE_SSL + Data domain = mRealm; + try + { + const char* anchor = pb.skipChar('?'); + pb.skipToChar('='); + Data query; + pb.data(query, anchor); + InfoLog( << "query is " << query ); + if ( query == "domain" ) + { + anchor = pb.skipChar('='); + pb.skipToEnd(); + pb.data(domain, anchor); + } + } + catch (ParseException& ) + { + } + + if ( !domain.empty() ) + { + InfoLog( << "domain is " << domain ); + try + { + setPage( buildCertPage(domain), pageNumber, 200, Mime("application","pkix-cert") ); + } + catch(BaseSecurity::Exception&) + { + setPage( resip::Data::Empty, pageNumber, 404 ); + } + return; + } + else + { + setPage( resip::Data::Empty, pageNumber, 404 ); + return; + } +#else + // ?bwc? Probably could use a better indication? + setPage(resip::Data::Empty, pageNumber, 404); +#endif + } + + Data authenticatedUser; + if (mNoWebChallenges) + { + // do't do authentication - give everyone admin privilages + authenticatedUser = Data("admin"); + } + else + { + // TODO !cj! - this code is broken - the user name in the web digest should be + // moved to alice@example.com instead of alice and assuming the realm is + // empty + + // all pages after this, user must authenticate + if ( pUser.empty() ) + { + setPage( resip::Data::Empty, pageNumber,401 ); + return; + } + + // check that authentication is correct + Data dbA1 = mStore.mUserStore.getUserAuthInfo( pUser, Data::Empty ); + +#if 0 + if ( dbA1.empty() ) // if the admin user does not exist, add it + { + mStore.mUserStore.addUser( pUser, // user + Data::Empty, // domain + Data::Empty, // realm + Data("admin"), // password + Data::Empty, // name + Data::Empty ); // email + dbA1 = mStore.mUserStore.getUserAuthInfo( pUser, Data::Empty ); + assert( !dbA1.empty() ); + } +#endif + + if ( !dbA1.empty() ) + { + MD5Stream a1; + a1 << pUser // username + << Symbols::COLON + << Data::Empty // realm + << Symbols::COLON + << pPassword; + Data compA1 = a1.getHex(); + + if ( dbA1 == compA1 ) + { + authenticatedUser = pUser; + } + else + { + InfoLog( << "user " << pUser << " failed to authenticate to web server" ); + DebugLog( << " compA1="<<compA1<< " dbA1="<<dbA1 ); + setPage( resip::Data::Empty, pageNumber,401 ); + return; + } + } + else //No A1, so we must assume this user does not exist. + { + setPage( "User does not exist.", pageNumber,401 ); + return; + } + } + + // parse any URI tags from form entry + mRemoveSet.clear(); + mHttpParams.clear(); + + if (!pb.eof()) + { + pb.skipChar('?'); + + while ( !pb.eof() ) + { + const char* anchor1 = pb.position(); + pb.skipToChar('='); + Data key; + pb.data(key,anchor1); + + const char* anchor2 = pb.skipChar('='); + pb.skipToChar('&'); + Data value; + pb.data(value,anchor2); + + if ( !pb.eof() ) + { + pb.skipChar('&'); + } + + if ( key.prefix("remove.") ) // special case of parameters to delete one or more records + { + Data tmp = key.substr(7); // the ID is everything after the dot + if (!tmp.empty()) + { + DebugLog (<< " remove key=" << tmp.urlDecoded()); + mRemoveSet.insert(RemoveKey(tmp.urlDecoded(),value.urlDecoded())); // add to the set of records to remove + } + } + else if ( !key.empty() && !value.empty() ) // make sure both exist + { + DebugLog (<< " key=" << key << " value=" << value << " & unencoded form: " << value.urlDecoded() ); + mHttpParams[key] = value.urlDecoded(); // add other parameters to the Map + } + } + } + + DebugLog( << "building page for user=" << authenticatedUser ); + + Data page; + if ( authenticatedUser == Data("admin") ) + { + DataStream s(page); + s << mPageOutlinePre; + + // admin only pages + if ( pageName == Data("user.html") ) {}; /* do nothing */ + //if ( pageName == Data("input") ) ; /* do nothing */ + if ( pageName == Data("domains.html") ) buildDomainsSubPage(s); + if ( pageName == Data("acls.html") ) buildAclsSubPage(s); + + if ( pageName == Data("addUser.html") ) buildAddUserSubPage(s); + if ( pageName == Data("editUser.html") ) buildEditUserSubPage(s); + if ( pageName == Data("showUsers.html") ) buildShowUsersSubPage(s); + + if ( pageName == Data("addFilter.html") ) buildAddFilterSubPage(s); + if ( pageName == Data("editFilter.html") ) buildEditFilterSubPage(s); + if ( pageName == Data("showFilters.html") ) buildShowFiltersSubPage(s); + + if ( pageName == Data("addRoute.html") ) buildAddRouteSubPage(s); + if ( pageName == Data("editRoute.html") ) buildEditRouteSubPage(s); + if ( pageName == Data("showRoutes.html") ) buildShowRoutesSubPage(s); + + if ( pageName == Data("registrations.html")) buildRegistrationsSubPage(s); + if ( pageName == Data("settings.html")) buildSettingsSubPage(s); + if ( pageName == Data("restart.html")) buildRestartSubPage(s); + + s << mPageOutlinePost; + s.flush(); + + if ( pageName == Data("userTest.html") ) page=buildUserPage(); + } + else if ( !authenticatedUser.empty() ) + { + // user only pages + if ( pageName == Data("user.html") ) page=buildUserPage(); + //if ( pageName == Data("input") ) page=buildUserPage(); + } + + assert( !authenticatedUser.empty() ); + assert( !page.empty() ); + + setPage( page, pageNumber,200 ); +} + + +void +WebAdmin::buildDomainsSubPage(DataStream& s) +{ + Data domainUri; + int domainTlsPort; + + if (!mRemoveSet.empty() && (mHttpParams["action"] == "Remove")) + { + int j = 0; + for (set<RemoveKey>::iterator i = mRemoveSet.begin(); i != mRemoveSet.end(); ++i) + { + mStore.mConfigStore.eraseDomain(i->mKey1); + ++j; + } + s << "<p><em>Removed:</em> " << j << " records</p>" << endl; + } + + Dictionary::iterator pos = mHttpParams.find("domainUri"); + if (pos != mHttpParams.end() && (mHttpParams["action"] == "Add")) // found domainUri key + { + domainUri = pos->second; + domainTlsPort = mHttpParams["domainTlsPort"].convertInt(); + if(mStore.mConfigStore.addDomain(domainUri,domainTlsPort)) + { + s << "<p><em>Added</em> domain: " << domainUri << "</p>" << endl; + } + else + { + s << "<p><em>Error</em> adding domain: likely database error (check logs).</p>\n"; + } + } + + s << + " <h2>Domains</h2>" << endl << + " <form id=\"domainForm\" method=\"get\" action=\"domains.html\" name=\"domainForm\">" << endl << + " <table" REPRO_BORDERLESS_TABLE_PROPS ">" << endl << + " <tr>" << endl << + " <td align=\"right\">New Domain:</td>" << endl << + " <td><input type=\"text\" name=\"domainUri\" size=\"24\"/></td>" << endl << + " <td><input type=\"text\" name=\"domainTlsPort\" size=\"4\"/></td>" << endl << + " <td><input type=\"submit\" name=\"action\" value=\"Add\"/></td>" << endl << + " </tr>" << endl << + " </table>" << endl << + " <div class=space>" << endl << + " <br>" << endl << + " </div>" << endl << + " <table" REPRO_BORDERED_TABLE_PROPS ">" << endl << + " <thead>" << endl << + " <tr>" << endl << + " <td>Domain</td>" << endl << + " <td align=\"center\">TLS Port</td>" << endl << + " <td><input type=\"submit\" name=\"action\" value=\"Remove\"/></td>" << endl << + " </tr>" << endl << + " </thead>" << endl << + " <tbody>" << endl; + + const ConfigStore::ConfigData& configs = mStore.mConfigStore.getConfigs(); + for ( ConfigStore::ConfigData::const_iterator i = configs.begin(); + i != configs.end(); i++ ) + { + s << + " <tr>" << endl << + " <td>" << i->second.mDomain << "</td>" << endl << + " <td align=\"center\">" << i->second.mTlsPort << "</td>" << endl << + " <td><input type=\"checkbox\" name=\"remove." << i->second.mDomain << "\"/></td>" << endl << + " </tr>" << endl; + } + + s << + " </tbody>" << endl << + " </table>" << endl << + " </form>" << endl << + "<p><em>WARNING:</em> You must restart repro after adding domains.</p>" << endl; +} + + +void +WebAdmin::buildAclsSubPage(DataStream& s) +{ + if (!mRemoveSet.empty() && (mHttpParams["action"] == "Remove")) + { + int j = 0; + for (set<RemoveKey>::iterator i = mRemoveSet.begin(); i != mRemoveSet.end(); ++i) + { + mStore.mAclStore.eraseAcl(i->mKey1); + ++j; + } + s << "<p><em>Removed:</em> " << j << " records</p>" << endl; + } + + Dictionary::iterator pos = mHttpParams.find("aclUri"); + if (pos != mHttpParams.end() && (mHttpParams["action"] == "Add")) // found + { + Data hostOrIp = mHttpParams["aclUri"]; + int port = mHttpParams["aclPort"].convertInt(); + TransportType transport = Tuple::toTransport(mHttpParams["aclTransport"]); + + if (mStore.mAclStore.addAcl(hostOrIp, port, transport)) + { + s << "<p><em>Added</em> trusted access for: " << hostOrIp << "</p>\n"; + } + else + { + s << "<p>Error parsing: " << hostOrIp << "</p>\n"; + } + } + + s << + " <h2>ACLs</h2>" << endl << + " <form id=\"aclsForm\" method=\"get\" action=\"acls.html\" name=\"aclsForm\">" << endl << + " <div class=space>" << endl << + " </div>" << endl << + " <table" REPRO_BORDERLESS_TABLE_PROPS ">" << endl << + " <tr>" << endl << + " <td align=\"right\">Host or IP:</td>" << endl << + " <td><input type=\"text\" name=\"aclUri\" size=\"24\"/></td>" << endl << + " <td><input type=\"text\" name=\"aclPort\" value=\"0\" size=\"5\"/></td>" << endl << + " <td><select name=\"aclTransport\">" << endl << + " <option selected=\"selected\">UDP</option>" << endl << + " <option>TCP</option>" << endl << +#ifdef USE_SSL + " <option>TLS</option>" << endl << +#endif +#ifdef USE_DTLS + " <option>DTLS</option>" << endl << +#endif + " </select></td>" << endl << + " <td><input type=\"submit\" name=\"action\" value=\"Add\"/></td>" << endl << + " </tr>" << endl << + " </table>" << endl << + " <br>" << endl << + " <table" REPRO_BORDERED_TABLE_PROPS ">" << endl << + " <thead>" << endl << + " <tr>" << endl << + " <td>Host Address or Peer Name</td>" << endl << + " <td>Port</td>" << endl << + " <td>Transport</td>" << endl << + " <td><input type=\"submit\" name=\"action\" value=\"Remove\"/></td>" << endl << + " </tr>" << endl << + " </thead>" << endl << + " <tbody>" << endl; + + AclStore::Key key = mStore.mAclStore.getFirstTlsPeerNameKey(); + while (key != Data::Empty) + { + s << + " <tr>" << endl << + " <td colspan=\"2\">" << mStore.mAclStore.getTlsPeerName(key) << "</td>" << endl << + " <td>TLS auth</td>" << endl << + " <td><input type=\"checkbox\" name=\"remove." << key << "\"/></td>" << endl << + "</tr>" << endl; + + key = mStore.mAclStore.getNextTlsPeerNameKey(key); + } + key = mStore.mAclStore.getFirstAddressKey(); + while (key != Data::Empty) + { + s << + " <tr>" << endl << + " <td>" << mStore.mAclStore.getAddressTuple(key).presentationFormat() << "/" + << mStore.mAclStore.getAddressMask(key) << "</td>" << endl << + " <td>" << mStore.mAclStore.getAddressTuple(key).getPort() << "</td>" << endl << + " <td>" << Tuple::toData(mStore.mAclStore.getAddressTuple(key).getType()) << "</td>" << endl << + " <td><input type=\"checkbox\" name=\"remove." << key << "\"/></td>" << endl << + " </tr>" << endl; + key = mStore.mAclStore.getNextAddressKey(key); + } + + s << + " </tbody>" << endl << + " </table>" << endl << + " </form>" << endl << + + "<pre>" << endl << + " Input can be in any of these formats" << endl << + " localhost localhost (becomes 127.0.0.1/8, ::1/128 and fe80::1/64)" << endl << + " bare hostname server1" << endl << + " FQDN server1.example.com" << endl << + " IPv4 address 192.168.1.100" << endl << + " IPv4 + mask 192.168.1.0/24" << endl << + " IPv6 address ::341:0:23:4bb:0011:2435:abcd" << endl << + " IPv6 + mask ::341:0:23:4bb:0011:2435:abcd/80" << endl << + " IPv6 reference [::341:0:23:4bb:0011:2435:abcd]" << endl << + " IPv6 ref + mask [::341:0:23:4bb:0011:2435:abcd]/64" << endl << + "</pre>" << endl << + + "<p>Access lists are used as a whitelist to allow " << endl << + "gateways and other trusted nodes to skip authentication.</p>" << endl << + "<p>Note: If hostnames or FQDN's are used then a TLS transport type is" << endl << + "assumed. All other transport types must specify ACLs by address.</p>" << endl; +} + + +void +WebAdmin::buildAddUserSubPage(DataStream& s) +{ + Dictionary::iterator pos; + Data user; + + pos = mHttpParams.find("user"); + if (pos != mHttpParams.end()) // found user key + { + user = pos->second; + Data domain = mHttpParams["domain"]; + +// pos = mHttpParams.find("realm"); +// if (pos == mHttpParams.end()) +// { +// realm = mHttpParams["domain"]; +// } + + if(mStore.mUserStore.addUser(user,domain,domain,mHttpParams["password"],true,mHttpParams["name"],mHttpParams["email"])) + { + s << "<p><em>Added:</em> " << user << "@" << domain << "</p>\n"; + } + else + { + s << "<p><em>Error</em> adding user: likely database error (check logs).</p>\n"; + } + } + + s << + "<h2>Add User</h2>" << endl << + "<form id=\"addUserForm\" action=\"addUser.html\" method=\"get\" name=\"addUserForm\" enctype=\"application/x-www-form-urlencoded\">" << endl << + "<table" REPRO_BORDERLESS_TABLE_PROPS ">" << endl << + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">User Name:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"user\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + //"<tr>" << endl << + //"<td align=\"right\" valign=\"middle\" >Realm:</td>" << endl << + //"<td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"realm\" size=\"40\"/></td>" << endl << + //"</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\" >Domain:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><select name=\"domain\">" << endl + ; + + // for each domain, add an option in the pulldown + const ConfigStore::ConfigData& list = mStore.mConfigStore.getConfigs(); + for ( ConfigStore::ConfigData::const_iterator i = list.begin(); + i != list.end(); i++ ) + { + s << " <option"; + + // if i->Domain is the default domain + // { + // s << " selected=\"true\""; + // } + + s << ">" << i->second.mDomain << "</option>" << endl; + } + + s << + "</select></td></tr>" << endl << + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\" >Password:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"password\" name=\"password\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\" >Full Name:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"name\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\" >Email:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"email\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td colspan=\"2\" align=\"right\" valign=\"middle\">" << endl << + " <input type=\"reset\" value=\"Cancel\"/>" << endl << + " <input type=\"submit\" name=\"submit\" value=\"Add\"/>" << endl << + " </td>" << endl << + "</tr>" << endl << + + "</table>" << endl << + "</form>" << endl + ; +} + + +void +WebAdmin::buildEditUserSubPage(DataStream& s) +{ + Dictionary::iterator pos; + pos = mHttpParams.find("key"); + if (pos != mHttpParams.end()) + { + Data key = pos->second; + AbstractDb::UserRecord rec = mStore.mUserStore.getUserInfo(key); + // !rwm! TODO check to see if we actually found a record corresponding to the key. how do we do that? + + s << "<h2>Edit User</h2>" << endl << + "<p>Editing Record with key: " << key << "</p>" << endl << + "<p>Note: If the username is not modified and you leave the password field empty the users current password will not be reset.</p>" << endl; + + s << + "<form id=\"editUserForm\" action=\"showUsers.html\" method=\"get\" name=\"editUserForm\" enctype=\"application/x-www-form-urlencoded\">" << endl << + "<table" REPRO_BORDERLESS_TABLE_PROPS ">" << endl << + "<input type=\"hidden\" name=\"key\" value=\"" << key << "\"/>" << endl << + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">User Name:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"user\" value=\"" << rec.user << "\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + //"<tr>" << endl << + //"<td align=\"right\" valign=\"middle\" >Realm:</td>" << endl << + //"<td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"realm\" size=\"40\"/></td>" << endl << + //"</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\" >Domain:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><select name=\"domain\">" << endl + ; + + // for each domain, add an option in the pulldown + const ConfigStore::ConfigData& list = mStore.mConfigStore.getConfigs(); + for ( ConfigStore::ConfigData::const_iterator i = list.begin(); + i != list.end(); i++ ) + { + s << " <option"; + + if ( i->second.mDomain == rec.domain) + { + s << " selected=\"true\""; + } + + s << ">" << i->second.mDomain << "</option>" << endl; + } + + s << + "</select></td></tr>" << endl << + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\" >Password:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"password\" name=\"password\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + // Note that the UserStore only stores a passwordHash, so we will collect a password. If one is provided in the + // edit page, we will use it to generate a new passwordHash, otherwise we will leave the hash alone. + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\" >Full Name:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"name\" value=\"" << rec.name << + "\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\" >Email:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"email\" value=\"" << rec.email << + "\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td colspan=\"2\" align=\"right\" valign=\"middle\">" << endl << + " <input type=\"submit\" name=\"submit\" value=\"Update\"/>" << endl << + " </td>" << endl << + "</tr>" << endl << + + "</table>" << endl << + "</form>" << endl + ; + } + else + { + // go back to show users page + } +} + + +void +WebAdmin::buildShowUsersSubPage(DataStream& s) +{ + Dictionary::iterator pos; + Data key; + AbstractDb::UserRecord rec; + + if (!mRemoveSet.empty()) + { + int j = 0; + for (set<RemoveKey>::iterator i = mRemoveSet.begin(); i != mRemoveSet.end(); ++i) + { + mStore.mUserStore.eraseUser(i->mKey1); + ++j; + } + s << "<p><em>Removed:</em> " << j << " records</p>" << endl; + } + + pos = mHttpParams.find("key"); + if (pos != mHttpParams.end()) // check if the user parameter exists, if so, use as a key to update the record + { + key = pos->second; + rec = mStore.mUserStore.getUserInfo(key); + // check to see if we actually found a record corresponding to the key + if (!rec.user.empty()) + { + Data user = mHttpParams["user"]; + Data domain = mHttpParams["domain"]; + Data realm = mHttpParams["domain"]; // eventually sort out realms + Data password = mHttpParams["password"]; + Data passwordHashAlt = Data::Empty; + Data name = mHttpParams["name"]; + Data email = mHttpParams["email"]; + bool applyA1HashToPassword = true; + + // if no password was specified, then leave current password untouched + if(password == "" && user == rec.user && realm == rec.realm) + { + password = rec.passwordHash; + passwordHashAlt = rec.passwordHashAlt; + applyA1HashToPassword = false; + } + // write out the updated record to the database now + if(mStore.mUserStore.updateUser(key, user, domain, realm, password, applyA1HashToPassword, name, email, passwordHashAlt)) + { + s << "<p><em>Updated:</em> " << key << "</p>" << endl; + } + else + { + s << "<p><em>Error</em> updating user: likely database error (check logs).</p>\n"; + } + } + } + + + s << + "<h2>Users</h2>" << endl << + "<form id=\"showUsers\" method=\"get\" action=\"showUsers.html\" name=\"showUsers\" enctype=\"application/x-www-form-urlencoded\">" << endl << + "<table" REPRO_BORDERED_TABLE_PROPS ">" << endl << + "<tr>" << endl << + " <td>User@Domain</td>" << endl << + // " <td>Realm</td>" << endl << + " <td>Name</td>" << endl << + " <td>Email</td>" << endl << + " <td><input type=\"submit\" value=\"Remove\"/></td>" << endl << + "</tr>" << endl; + + s << endl; + + int count =0; + + key = mStore.mUserStore.getFirstKey(); + while ( !key.empty() ) + { + rec = mStore.mUserStore.getUserInfo(key); + + if ((rec.domain == Data::Empty) && (rec.user == "admin")) + { + key = mStore.mUserStore.getNextKey(); + continue; // skip the row for the admin web user + } + + s << "<tr>" << endl + << " <td><a href=\"editUser.html?key="; + key.urlEncode(s); + s << "\">" << rec.user << "@" << rec.domain << "</a></td>" << endl + << " <td>" << rec.name << "</td>" << endl + << " <td>" << rec.email << "</td>" << endl + << " <td><input type=\"checkbox\" name=\"remove." << key << "\"/></td>" << endl + << "</tr>" << endl; + + key = mStore.mUserStore.getNextKey(); + + // make a limit to how many users are displayed + if ( ++count > 1000 ) + { + break; + } + } + + if ( !key.empty() ) + { + s << "<tr><td>Only first 1000 users were displayed<td></tr>" << endl; + } + + s << + "</table>" << endl << + "</form>" << endl; +} + +void +WebAdmin::buildAddFilterSubPage(DataStream& s) +{ + Dictionary::iterator pos; + + pos = mHttpParams.find("cond1header"); + if (pos != mHttpParams.end()) + { + Data action = mHttpParams["action"]; + Data actionData = mHttpParams["actiondata"]; + + if (action != "Accept" && actionData.empty()) + { + s << "<p><em>Error</em> adding request filter. You must provide appropriate Action Data for non-Accept action.</p>\n"; + } + else + { + short actionShort = 0; // 0 - Accept, 1 - Reject, 2 - SQL Query + if(action == "Reject") actionShort = 1; + else if(action == "SQL Query") actionShort = 2; + + if(mStore.mFilterStore.addFilter(mHttpParams["cond1header"], + mHttpParams["cond1regex"], + mHttpParams["cond2header"], + mHttpParams["cond2regex"], + mHttpParams["method"], + mHttpParams["event"], + actionShort, + actionData, + mHttpParams["order"].convertInt())) + { + s << "<p><em>Added</em> request filter: " << mHttpParams["cond1header"] << "=" << mHttpParams["cond1regex"] << ", " + << mHttpParams["cond2header"] << "=" << mHttpParams["cond2regex"] << "</p>\n"; + } + else + { + s << "<p><em>Error</em> adding request filter, likely duplicate found.</p>\n"; + } + } + } + + s << + "<h2>Add Request Filter</h2>" << endl << + "<form id=\"addFilterForm\" method=\"get\" action=\"addFilter.html\" name=\"addFilterForm\">" << endl << + "<table" REPRO_BORDERLESS_TABLE_PROPS ">" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Condition1 Header:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"cond1header\" size=\"40\" value=\"From\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Condition1 Regex:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"cond1regex\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Condition2 Header:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"cond2header\" size=\"40\" value=\"To\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Condition2 Regex:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"cond2regex\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Method:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"method\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Event:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"event\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Action:</td>" << endl << + " <td align=\"left\" valign=\"middle\">" << endl << + " <select name=\"action\">" << endl << + " <option>Reject</option>" << endl << + " <option>Accept</option>" << endl << +#ifdef USE_MYSQL + " <option>SQL Query</option>" << endl << +#endif + " </select>" << endl << + " </td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Action Data:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"actiondata\" size=\"40\" value=\"403, Request Blocked\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Order:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"order\" size=\"4\" value=\"0\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td colspan=\"2\" align=\"right\" valign=\"middle\">" << endl << + " <input type=\"reset\" value=\"Cancel\"/>" << endl << + " <input type=\"submit\" name=\"filterAdd\" value=\"Add\"/>" << endl << + " </td>" << endl << + "</tr>" << endl << + + "</table>" << endl << + "</form>" << endl << + + "<pre>" << endl << + "If Action is Accept, then Action Data is ignored." << endl << + "If Action is Reject, then Action Data should be set to: SIPRejectionCode[, SIPReason]" << endl << +#ifdef USE_MYSQL + "If Action is SQL Query, then Action Data should be set to the SQL Query to execute." << endl << + "Replacement strings from the Regex's above can be used in the query, and the query" << endl << + "must return a string that is formated similar to Action Data when the action is" << endl << + "Reject. Alternatively it can return a string with status code of 0 to accept the" << endl << + "request." << endl << +#endif + "</pre>" << endl; +} + + +void +WebAdmin::buildEditFilterSubPage(DataStream& s) +{ + Dictionary::iterator pos; + pos = mHttpParams.find("key"); + if (pos != mHttpParams.end()) + { + Data key = pos->second; + + // !rwm! TODO check to see if we actually found a record corresponding to the key. how do we do that? + DebugLog( << "Creating page to edit filter " << key ); + + AbstractDb::FilterRecord rec = mStore.mFilterStore.getFilterRecord(key); + + s <<"<h2>Edit Request Filter</h2>" << endl << + "<p>Editing Record with conditions: " << rec.mCondition1Header << "=" << rec.mCondition1Regex << ", " + << rec.mCondition2Header << "=" << rec.mCondition2Regex << "</p>" << endl; + + s << + "<form id=\"editFilterForm\" method=\"get\" action=\"showFilters.html\" name=\"editFilterForm\">" << endl << + "<table" REPRO_BORDERLESS_TABLE_PROPS ">" << endl << + "<input type=\"hidden\" name=\"key\" value=\"" << key << "\"/>" << endl << + "<tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Condition1 Header:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"cond1header\" size=\"40\" value=\"" << rec.mCondition1Header.xmlCharDataEncode() << "\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Condition1 Regex:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"cond1regex\" size=\"40\" value=\"" << rec.mCondition1Regex.xmlCharDataEncode() << "\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Condition2 Header:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"cond2header\" size=\"40\" value=\"" << rec.mCondition2Header.xmlCharDataEncode() << "\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Condition2 Regex:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"cond2regex\" size=\"40\" value=\"" << rec.mCondition2Regex.xmlCharDataEncode() << "\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Method:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"method\" size=\"40\" value=\"" << rec.mMethod << "\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Event:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"event\" size=\"40\" value=\"" << rec.mEvent << "\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Action:</td>" << endl << + " <td align=\"left\" valign=\"middle\">" << endl << + " <select name=\"action\">" << endl << + " <option" << (rec.mAction == FilterStore::Reject ? " selected=\"selected\"" : "") << ">Reject</option>" << endl << + " <option" << (rec.mAction == FilterStore::Accept ? " selected=\"selected\"" : "") << ">Accept</option>" << endl << +#ifdef USE_MYSQL + " <option" << (rec.mAction == FilterStore::SQLQuery ? " selected=\"selected\"" : "") << ">SQL Query</option>" << endl << +#endif + " </select>" << endl << + " </td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Action Data:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"actiondata\" size=\"40\" value=\"" << rec.mActionData.xmlCharDataEncode() << "\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Order:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"order\" size=\"4\" value=\"" << rec.mOrder << "\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td colspan=\"2\" align=\"right\" valign=\"middle\">" << endl << + " <input type=\"submit\" name=\"routeEdit\" value=\"Update\"/>" << endl << + " </td>" << endl << + "</tr>" << endl << + + "</table>" << endl << + "</form>" << endl; + } + else + { + // go back to show filter page + } +} + + +void +WebAdmin::buildShowFiltersSubPage(DataStream& s) +{ + Dictionary::iterator pos; + Data key; + AbstractDb::RouteRecord rec; + + if (!mRemoveSet.empty()) + { + int j = 0; + for (set<RemoveKey>::iterator i = mRemoveSet.begin(); i != mRemoveSet.end(); ++i) + { + mStore.mFilterStore.eraseFilter(i->mKey1); + ++j; + } + s << "<p><em>Removed:</em> " << j << " records</p>" << endl; + } + + pos = mHttpParams.find("key"); + if (pos != mHttpParams.end()) // if a key parameter exists, use the key to update the record + { + key = pos->second; + + // !rwm! TODO check to see if we actually found a record corresponding to the key. how do we do that? + if (1) + { + Data action = mHttpParams["action"]; + Data actionData = mHttpParams["actiondata"]; + + if (action != "Accept" && actionData.empty()) + { + s << "<p><em>Error</em> updating request filter. You must provide appropriate Action Data for non-Accept action.</p>\n"; + } + else + { + short actionShort = 0; // 0 - Accept, 1 - Reject, 2 - SQL Query + if(action == "Reject") actionShort = 1; + else if(action == "SQL Query") actionShort = 2; + + if(mStore.mFilterStore.updateFilter(key, + mHttpParams["cond1header"], + mHttpParams["cond1regex"], + mHttpParams["cond2header"], + mHttpParams["cond2regex"], + mHttpParams["method"], + mHttpParams["event"], + actionShort, + actionData, + mHttpParams["order"].convertInt())) + { + s << "<p><em>Updated</em> request filter: " << mHttpParams["cond1header"] << "=" << mHttpParams["cond1regex"] << ", " + << mHttpParams["cond2header"] << "=" << mHttpParams["cond2regex"] << "</p>\n"; + } + else + { + s << "<p><em>Error</em> updating request filter: likely database error (check logs).</p>\n"; + } + } + } + } + + s << + "<h2>Request Filters</h2>" << endl << + "<form id=\"showFilters\" action=\"showFilters.html\" method=\"get\" name=\"showFilters\" enctype=\"application/x-www-form-urlencoded\">" << endl << + // " <button name=\"removeAllRoute\" value=\"\" type=\"submit\">Remove All</button>" << endl << + "<table" REPRO_BORDERED_TABLE_PROPS ">" << endl << + "<thead><tr>" << endl << + " <td>Condition 1</td>" << endl << + " <td>Condition 2</td>" << endl << + " <td>Method</td>" << endl << + " <td>Event</td>" << endl << + " <td>Action</td>" << endl << + " <td>Action Data</td>" << endl << + " <td>Order</td>" << endl << + " <td><input type=\"submit\" value=\"Remove\"/></td>" << endl << + "</tr></thead>" << endl << + "<tbody>" << endl; + + for(FilterStore::Key key = mStore.mFilterStore.getFirstKey(); + !key.empty(); + key = mStore.mFilterStore.getNextKey(key)) + { + AbstractDb::FilterRecord rec = mStore.mFilterStore.getFilterRecord(key); + Data action("Accept"); + if(rec.mAction == FilterStore::Reject) + { + action = "Reject"; + } + else if(rec.mAction == FilterStore::SQLQuery) + { + action = "SQL Query"; + } + s << "<tr>" << endl << + "<td><a href=\"editFilter.html?key="; + key.urlEncode(s); + s << + "\">" << rec.mCondition1Header << "=" << rec.mCondition1Regex << "</a></td>" << endl << + "<td>" << rec.mCondition2Header << "=" << rec.mCondition2Regex << "</td>" << endl << + "<td>" << rec.mMethod << "</td>" << endl << + "<td>" << rec.mEvent << "</td>" << endl << + "<td>" << action << "</td>" << endl << + "<td>" << rec.mActionData << "</td>" << endl << + "<td>" << rec.mOrder << "</td>" << endl << + "<td><input type=\"checkbox\" name=\"remove." << key << "\"/></td>" << endl << + "</tr>" << endl; + } + + s << + "</tbody>" << endl << + "</table>" << endl << + "</form>" << endl; + + Data cond1TestHeader; + pos = mHttpParams.find("cond1TestHeader"); + if (pos != mHttpParams.end()) // found it + { + cond1TestHeader = pos->second; + } + Data cond2TestHeader; + pos = mHttpParams.find("cond2TestHeader"); + if (pos != mHttpParams.end()) // found it + { + cond2TestHeader = pos->second; + } + + s << + "<br><form id=\"testFilter\" action=\"showFilters.html\" method=\"get\" name=\"testFilter\" enctype=\"application/x-www-form-urlencoded\">" << endl << + "<table" REPRO_BORDERLESS_TABLE_PROPS ">" << endl << + "<tr>" << endl << + " <td align=\"right\">Condition 1 Header:</td>" << endl << + " <td><input type=\"text\" name=\"cond1TestHeader\" value=\"" << cond1TestHeader.xmlCharDataEncode() << "\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + "<tr>" << endl << + " <td align=\"right\">Condition 2 Header:</td>" << endl << + " <td><input type=\"text\" name=\"cond2TestHeader\" value=\"" << cond2TestHeader.xmlCharDataEncode() << "\" size=\"40\"/></td>" << endl << + " <td><input type=\"submit\" name=\"testFilter\" value=\"Test Filters\"/></td>" << endl << + "</tr>" << endl << + "</table>" << endl << + "</form>" << endl << + "<br>" << endl; + + if(!cond1TestHeader.empty()) + { + s << "<em>Test Result: </em>"; + short action; + Data actionData; + if(mStore.mFilterStore.test(cond1TestHeader, cond2TestHeader, action, actionData)) + { + switch(action) + { + case FilterStore::Reject: + s << "Match found, action=Reject " << actionData << endl; + break; + case FilterStore::SQLQuery: + s << "Match found, action=SQL Query '" << actionData << "'" << endl; + break; + case FilterStore::Accept: + default: + s << "Match found, action=Accept" << endl; + break; + } + } + else + { + s << "No Match"; + } + } +} + + +void +WebAdmin::buildAddRouteSubPage(DataStream& s) +{ + Dictionary::iterator pos; + + pos = mHttpParams.find("routeUri"); + if (pos != mHttpParams.end()) + { + Data routeUri = mHttpParams["routeUri"]; + Data routeDestination = mHttpParams["routeDestination"]; + + if (!routeUri.empty() && !routeDestination.empty()) + { + if(mStore.mRouteStore.addRoute(mHttpParams["routeMethod"], + mHttpParams["routeEvent"], + routeUri, + routeDestination, + mHttpParams["routeOrder"].convertInt())) + { + s << "<p><em>Added</em> route for: " << routeUri << "</p>\n"; + } + else + { + s << "<p><em>Error</em> adding route, likely duplicate found.</p>\n"; + } + } + else + { + s << "<p><em>Error</em> adding route. You must provide a URI and a route destination.</p>\n"; + } + } + + s << + "<h2>Add Route</h2>" << endl << + "<form id=\"addRouteForm\" method=\"get\" action=\"addRoute.html\" name=\"addRouteForm\">" << endl << + "<table" REPRO_BORDERLESS_TABLE_PROPS ">" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">URI:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"routeUri\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Method:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"routeMethod\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Event:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"routeEvent\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Destination:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"routeDestination\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td align=\"right\" valign=\"middle\">Order:</td>" << endl << + " <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"routeOrder\" size=\"4\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td colspan=\"2\" align=\"right\" valign=\"middle\">" << endl << + " <input type=\"reset\" value=\"Cancel\"/>" << endl << + " <input type=\"submit\" name=\"routeAdd\" value=\"Add\"/>" << endl << + " </td>" << endl << + "</tr>" << endl << + + "</table>" << endl << + "</form>" << endl << + + "<pre>" << endl << + "Static routes use (POSIX-standard) regular expression to match" << endl << + "and rewrite SIP URIs. The following is an example of sending" << endl << + "all requests that consist of only digits in the userpart of the" << endl << + "SIP URI to a gateway:" << endl << endl << + " URI: ^sip:([0-9]+)@example\\.com" << endl << + " Destination: sip:$1@gateway.example.com" << endl << + "</pre>" << endl; +} + + +void +WebAdmin::buildEditRouteSubPage(DataStream& s) +{ + Dictionary::iterator pos; + pos = mHttpParams.find("key"); + if (pos != mHttpParams.end()) + { + Data key = pos->second; + + // !rwm! TODO check to see if we actually found a record corresponding to the key. how do we do that? + DebugLog( << "Creating page to edit route " << key ); + + AbstractDb::RouteRecord rec = mStore.mRouteStore.getRouteRecord(key); + + s <<"<h2>Edit Route</h2>" << endl << + "<p>Editing Record with matching pattern: " << rec.mMatchingPattern << "</p>" << endl; + + s << + "<form id=\"editRouteForm\" method=\"get\" action=\"showRoutes.html\" name=\"editRouteForm\">" << endl << + "<table" REPRO_BORDERLESS_TABLE_PROPS ">" << endl << + "<input type=\"hidden\" name=\"key\" value=\"" << key << "\"/>" << endl << + "<tr>" << endl << + "<td align=\"right\" valign=\"middle\">URI:</td>" << endl << + "<td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"routeUri\" value=\"" << rec.mMatchingPattern << "\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + "<td align=\"right\" valign=\"middle\">Method:</td>" << endl << + "<td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"routeMethod\" value=\"" << rec.mMethod << "\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + "<td align=\"right\" valign=\"middle\">Event:</td>" << endl << + "<td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"routeEvent\" value=\"" << rec.mEvent << "\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + "<td align=\"right\" valign=\"middle\">Destination:</td>" << endl << + "<td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"routeDestination\" value=\"" << rec.mRewriteExpression << + "\" size=\"40\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + "<td align=\"right\" valign=\"middle\">Order:</td>" << endl << + "<td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"routeOrder\" value=\"" << rec.mOrder << + "\" size=\"4\"/></td>" << endl << + "</tr>" << endl << + + "<tr>" << endl << + " <td colspan=\"2\" align=\"right\" valign=\"middle\">" << endl << + " <input type=\"submit\" name=\"routeEdit\" value=\"Update\"/>" << endl << + " </td>" << endl << + "</tr>" << endl << + + "</table>" << endl << + "</form>" << endl; + } + else + { + // go back to show route page + } +} + + +void +WebAdmin::buildShowRoutesSubPage(DataStream& s) +{ + Dictionary::iterator pos; + Data key; + AbstractDb::RouteRecord rec; + + if (!mRemoveSet.empty()) + { + int j = 0; + for (set<RemoveKey>::iterator i = mRemoveSet.begin(); i != mRemoveSet.end(); ++i) + { + mStore.mRouteStore.eraseRoute(i->mKey1); + ++j; + } + s << "<p><em>Removed:</em> " << j << " records</p>" << endl; + } + + pos = mHttpParams.find("key"); + if (pos != mHttpParams.end()) // if a key parameter exists, use the key to update the record + { + key = pos->second; + + // !rwm! TODO check to see if we actually found a record corresponding to the key. how do we do that? + if (1) + { + Data method = mHttpParams["routeMethod"]; + Data event = mHttpParams["routeEvent"]; + Data matchingPattern = mHttpParams["routeUri"]; + Data rewriteExpression = mHttpParams["routeDestination"]; + int order = mHttpParams["routeOrder"].convertInt(); + + if (!matchingPattern.empty() && !rewriteExpression.empty()) + { + // write out the updated record to the database now + if(mStore.mRouteStore.updateRoute(key, method, event, matchingPattern, rewriteExpression, order)) + { + s << "<p><em>Updated:</em> " << rec.mMatchingPattern << "</p>" << endl; + } + else + { + s << "<p><em>Error</em> updating route: likely database error (check logs).</p>\n"; + } + } + else + { + s << "<p><em>Error</em> updating route. You must provide a URI and a route destination.</p>\n"; + } + } + } + + s << + "<h2>Routes</h2>" << endl << + "<form id=\"showRoutes\" action=\"showRoutes.html\" method=\"get\" name=\"showRoutes\" enctype=\"application/x-www-form-urlencoded\">" << endl << + // " <button name=\"removeAllRoute\" value=\"\" type=\"submit\">Remove All</button>" << endl << + "<table" REPRO_BORDERED_TABLE_PROPS ">" << endl << + "<thead><tr>" << endl << + " <td>URI</td>" << endl << + " <td>Method</td>" << endl << + " <td>Event</td>" << endl << + " <td>Destination</td>" << endl << + " <td>Order</td>" << endl << + " <td><input type=\"submit\" value=\"Remove\"/></td>" << endl << + "</tr></thead>" << endl << + "<tbody>" << endl; + + for ( RouteStore::Key key = mStore.mRouteStore.getFirstKey(); + !key.empty(); + key = mStore.mRouteStore.getNextKey(key) ) + { + AbstractDb::RouteRecord rec = mStore.mRouteStore.getRouteRecord(key); + + s << "<tr>" << endl << + "<td><a href=\"editRoute.html?key="; + key.urlEncode(s); + s << + "\">" << rec.mMatchingPattern << "</a></td>" << endl << + "<td>" << rec.mMethod << "</td>" << endl << + "<td>" << rec.mEvent << "</td>" << endl << + "<td>" << rec.mRewriteExpression << "</td>" << endl << + "<td>" << rec.mOrder << "</td>" << endl << + "<td><input type=\"checkbox\" name=\"remove." << key << "\"/></td>" << endl << + "</tr>" << endl; + } + + s << + "</tbody>" << endl << + "</table>" << endl << + "</form>" << endl; + + int badUri = true; + Uri uri; + Data routeTestUri; + + pos = mHttpParams.find("routeTestUri"); + if (pos != mHttpParams.end()) // found it + { + routeTestUri = pos->second; + if ( routeTestUri != "sip:" ) + { + try + { + uri = Uri(routeTestUri); + badUri=false; + } + catch( BaseException& ) + { + try + { + uri = Uri( Data("sip:")+routeTestUri ); + badUri=false; + } + catch( BaseException& ) + { + } + } + } + } + + // !cj! - TODO - should input method and event type to test + RouteStore::UriList routeList; + if (!badUri) + { + routeList = mStore.mRouteStore.process(uri, Data("INVITE"), Data::Empty); + } + + s << + "<br><form id=\"testRoute\" action=\"showRoutes.html\" method=\"get\" name=\"testRoute\" enctype=\"application/x-www-form-urlencoded\">" << endl << + "<table" REPRO_BORDERLESS_TABLE_PROPS ">" << endl << + "<tr>" << endl << + " <td align=\"right\">Input:</td>" << endl << + " <td><input type=\"text\" name=\"routeTestUri\" value=\"" << uri << "\" size=\"40\"/></td>" << endl << + " <td><input type=\"submit\" name=\"testRoute\" value=\"Test Routes\"/></td>" << endl << + "</tr>" << endl; + + bool first=true; + for ( RouteStore::UriList::const_iterator i=routeList.begin(); + i != routeList.end(); i++) + { + s<<" <tr>" << endl; + if (first) + { + first=false; + s<<" <td align=\"right\">Targets:</td>" << endl; + } + else + { + s<<" <td align=\"right\"></td>" << endl; + } + s<<" <td><label>" << *i << "</label></td>" << endl; + s<<" <td></td>" << endl; + s<<" </tr>" << endl; + } + + s<< + "</table>" << endl << + "</form>" << endl; +} + + +void +WebAdmin::buildRegistrationsSubPage(DataStream& s) +{ + if (!mRemoveSet.empty()) + { + int j = 0; + for (set<RemoveKey>::iterator i = mRemoveSet.begin(); i != mRemoveSet.end(); ++i) + { + Uri aor(i->mKey1); + ContactInstanceRecord rec; + size_t bar1 = i->mKey2.find("|"); + size_t bar2 = i->mKey2.find("|",bar1+1); + size_t bar3 = i->mKey2.find("|",bar2+1); + + if(bar1==Data::npos || bar2 == Data::npos || bar3==Data::npos) + { + InfoLog(<< "Registration removal key was malformed: " << i->mKey2); + continue; + } + + bool staticRegContact=false; + try + { + resip::Data rawNameAddr = i->mKey2.substr(0,bar1).urlDecoded(); + rec.mContact = NameAddr(rawNameAddr); + rec.mInstance = i->mKey2.substr(bar1+1,bar2-bar1-1).urlDecoded(); + rec.mRegId = i->mKey2.substr(bar2+1,Data::npos).convertInt(); + staticRegContact = i->mKey2.substr(bar3+1,Data::npos).convertInt() == 1; + + // Remove from RegistrationPersistanceManager + mRegDb.removeContact(aor, rec); + + if(staticRegContact) + { + // Remove from StateRegStore + mStore.mStaticRegStore.eraseStaticReg(aor, rec.mContact); + } + + ++j; + } + catch(resip::ParseBuffer::Exception& e) + { + InfoLog(<< "Registration removal key was malformed: " << e << + " Key was: " << i->mKey2); + } + } + s << "<p><em>Removed:</em> " << j << " records</p>" << endl; + } + + Dictionary::iterator pos = mHttpParams.find("regAor"); + if (pos != mHttpParams.end() && (mHttpParams["action"] == "Add")) // found + { + Data regAor = mHttpParams["regAor"]; + Data regContact = mHttpParams["regContact"]; + Data regPath = mHttpParams["regPath"]; + + ContactInstanceRecord rec; + try + { + rec.mContact = NameAddr(regContact); + try + { + ParseBuffer pb(regPath); + Data path; + const char* anchor = pb.position(); + while(!pb.eof()) + { + pb.skipToChar(Symbols::COMMA[0]); + pb.data(path, anchor); + rec.mSipPath.push_back(NameAddr(path)); + if(!pb.eof()) pb.skipChar(); // skip over comma + anchor = pb.position(); + } + try + { + rec.mRegExpires = NeverExpire; + rec.mSyncContact = true; // Tag this permanent contact as being a syncronized contact so that it will + // be syncronized to a paired server (this is actually configuration information) + + // Add to DB Store + Uri aor(regAor); + if(mStore.mStaticRegStore.addStaticReg(aor, rec.mContact, rec.mSipPath)) + { + // Add to RegistrationPersistanceManager + mRegDb.updateContact(aor, rec); + + s << "<p><em>Added</em> permanent registered contact for: " << regAor << "</p>\n"; + } + else + { + s << "<p><em>Error</em> adding static registration: likely database error (check logs).</p>\n"; + } + } + catch(resip::ParseBuffer::Exception& e) + { + InfoLog(<< "Registration add: aor " << regAor << " was malformed: " << e); + s << "<p>Error parsing: AOR=" << regAor << "</p>\n"; + } + } + catch(resip::ParseBuffer::Exception& e) + { + InfoLog(<< "Registration add: path " << regPath << " was malformed: " << e); + s << "<p>Error parsing: Path=" << regPath << "</p>\n"; + } + } + catch(resip::ParseBuffer::Exception& e) + { + InfoLog(<< "Registration add: contact " << regContact << " was malformed: " << e); + s << "<p>Error parsing: Contact=" << regContact << "</p>\n"; + } + } + + s << + "<h2>Registrations</h2>" << endl << + "<form id=\"showReg\" method=\"get\" action=\"registrations.html\" name=\"showReg\" enctype=\"application/x-www-form-urlencoded\">" << endl << + //"<button name=\"removeAllReg\" value=\"\" type=\"button\">Remove All</button>" << endl << + //"<hr/>" << endl << + + "<div class=space>" << endl << + "</div>" << endl << + "<table" REPRO_BORDERLESS_TABLE_PROPS ">" << endl << + " <tr>" << endl << + " <td align=\"right\">AOR:</td>" << endl << + " <td><input type=\"text\" name=\"regAor\" size=\"40\"/></td>" << endl << + " <td align=\"right\">Contact:</td>" << endl << + " <td><input type=\"text\" name=\"regContact\" size=\"40\"/></td>" << endl << + " </tr>" << endl << + " <tr>" << endl << + " <td align=\"right\">Path:</td>" << endl << + " <td><input type=\"text\" name=\"regPath\" size=\"40\"/></td>" << endl << + " <td></td>" << endl << + " <td align=\"right\"><input type=\"submit\" name=\"action\" value=\"Add\"/></td>" << endl << + " </tr>" << endl << + " </tr>" << endl << + "</table>" << endl << + "<br>" << endl << + + "<table" REPRO_BORDERED_TABLE_PROPS ">" << endl << + + "<tr>" << endl << + " <td>AOR</td>" << endl << + " <td>Contact</td>" << endl << + " <td>Instance ID</td>" << endl << + " <td>Reg ID</td>" << endl << + " <td>QValue</td>" << endl << + " <td>Path</td>" << endl << + " <td>Expires In</td>" << endl << + " <td><input type=\"submit\" value=\"Remove\"/></td>" << endl << + "</tr>" << endl; + + RegistrationPersistenceManager::UriList aors; + mRegDb.getAors(aors); + for ( RegistrationPersistenceManager::UriList::const_iterator + aor = aors.begin(); aor != aors.end(); ++aor ) + { + Uri uri = *aor; + ContactList contacts; + mRegDb.getContacts(uri, contacts); + + bool first = true; + UInt64 now = Timer::getTimeSecs(); + for (ContactList::iterator i = contacts.begin(); + i != contacts.end(); ++i ) + { + if(i->mRegExpires > now) + { + UInt64 secondsRemaining = i->mRegExpires - now; + + s << "<tr>" << endl + << " <td>" ; + if (first) + { + s << uri; + first = false; + } + s << "</td>" << endl + << " <td>"; + + const ContactInstanceRecord& r = *i; + const NameAddr& contact = r.mContact; + const Data& instanceId = r.mInstance; + int regId = r.mRegId; + + s << contact.uri(); + s <<"</td>" << endl + << "<td>" << instanceId.xmlCharDataEncode() + << "</td><td>" << regId + << "</td><td>"; +#ifdef RESIP_FIXED_POINT + // If RESIP_FIXED_POINT is enabled then q-value is shown as an integer in the range of 0..1000 where 1000 = qvalue of 1.0 + s << (contact.exists(p_q) ? contact.param(p_q) : 1000) << "</td><td>"; +#else + s << (contact.exists(p_q) ? contact.param(p_q).floatVal() : 1.0f) << "</td><td>"; +#endif + NameAddrs::const_iterator naIt = r.mSipPath.begin(); + for(;naIt != r.mSipPath.end(); naIt++) + { + s << naIt->uri() << "<br>" << endl; + } + bool staticRegContact = r.mRegExpires == NeverExpire; + if(!staticRegContact) + { + s <<"</td><td>" << secondsRemaining << "s</td>" << endl; + } + else + { + s <<"</td><td>Never</td>" << endl; + } + s << " <td>" + << "<input type=\"checkbox\" name=\"remove." << uri << "\" value=\"" << Data::from(contact.uri()).urlEncoded() + << "|" << instanceId.urlEncoded() + << "|" << regId + << "|" << (staticRegContact ? "1" : "0") + << "\"/></td>" << endl + << "</tr>" << endl; + } + else + { + // remove expired contact + mRegDb.removeContact(uri, *i); + } + } + } + + s << "</table>" << endl << + "</form>" << endl; +} + + +void +WebAdmin::buildSettingsSubPage(DataStream& s) +{ + if (mHttpParams["action"] == "Clear DNS Cache") + { + mProxy.getStack().clearDnsCache(); + } + + s << "<h2>Settings</h2>" << endl << + "<pre>" << mProxy.getConfig() << "</pre>"; + + { + Data buffer; + DataStream strm(buffer); + mProxy.getStack().dump(strm); + strm.flush(); + s << "<br>Stack Info<br>" + << "<pre>" << buffer << "</pre>" + << endl; + } + + if(mProxy.getStack().getCongestionManager()) + { + Data buffer; + DataStream strm(buffer); + mProxy.getStack().getCongestionManager()->encodeCurrentState(strm); + s << "<br>Congestion Manager Statistics<br>" + << "<pre>" << buffer << "</pre>" + << endl; + } + + // Get Dns Cache + { + Lock lock(mDnsCacheMutex); + mProxy.getStack().getDnsCacheDump(make_pair(0, 0), this); + // Retrieving DNS cache is asyncronous + // Use condition variable to wait for DNS results to be returned in onDnsCacheDumpRetrieved + mDnsCacheCondition.wait(mDnsCacheMutex); + s << "<br>DNS Cache<br>" + << "<pre>" << mDnsCache << "</pre>" + << endl; + } + + s << "<form id=\"clearDnsCache\" method=\"get\" action=\"settings.html\" name=\"clearDnsCache\">" << endl + << " <br><input type=\"submit\" name=\"action\" value=\"Clear DNS Cache\"/>" << endl + << "</form>" << endl; + + if(mProxy.getConfig().getConfigUnsignedShort("CommandPort", 0) != 0) + { + s << "<form id=\"restartProxy\" method=\"get\" action=\"restart.html\" name=\"restart\">" << endl + << " <input type=\"submit\" name=\"action\" value=\"Restart Proxy\"/>" << endl + << "</form>" << endl; + } +} + +void +WebAdmin::onDnsCacheDumpRetrieved(std::pair<unsigned long, unsigned long> key, const resip::Data& dnsEntryStrings) +{ + Lock lock(mDnsCacheMutex); (void)lock; + if(dnsEntryStrings.empty()) + { + mDnsCache = "<i>empty</i>"; + } + else + { + mDnsCache = dnsEntryStrings; + } + mDnsCacheCondition.signal(); +} + +void +WebAdmin::buildRestartSubPage(DataStream& s) +{ + unsigned short port = mProxy.getConfig().getConfigUnsignedShort("CommandPort", 0); + if(port != 0) + { + // Send restart command to command server - it is not safe to invoke a restart from here + // since the webadmin thread and server is destroyed on the blocking ReproRunner::restart call + int sd, rc; + struct sockaddr_in localAddr, servAddr; + struct hostent *h; + char* host = "127.0.0.1"; + h = gethostbyname(host); + if(h!=0) + { + servAddr.sin_family = h->h_addrtype; + memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length); + servAddr.sin_port = htons(port); + + // Create TCP Socket + sd = (int)socket(AF_INET, SOCK_STREAM, 0); + if(sd > 0) + { + // bind to any local interface/port + localAddr.sin_family = AF_INET; + localAddr.sin_addr.s_addr = htonl(INADDR_ANY); + localAddr.sin_port = 0; + + rc = ::bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr)); + if(rc >= 0) + { + // Connect to server + rc = ::connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr)); + if(rc >= 0) + { + Data request("<Restart>\r\n <Request>\r\b </Request>\r\n</Restart>\r\n"); + rc = send(sd, request.c_str(), request.size(), 0); + if(rc >= 0) + { + s << "Restarting proxy..." << endl; + closeSocket(sd); + return; + } + } + } + closeSocket(sd); + } + } + s << "Error issuing restart command." << endl; + } + else + { + s << "CommandServer must be running to use restart feature." << endl; + } +} + +Data +WebAdmin::buildUserPage() +{ + Data ret; + { + DataStream s(ret); + + s << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << endl + << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl + << "" << endl + << "<html xmlns=\"http://www.w3.org/1999/xhtml\">" << endl + << "" << endl + << "<head>" << endl + << "<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />" << endl + << "<title>Repro Proxy</title>" << endl + << "</head>" << endl + << "" << endl + << "<body bgcolor=\"#ffffff\">" << endl; + + //buildAddUserSubPage(s); // !cj! TODO - should do beter page here + + s << "</body>" << endl + << "" << endl + << "</html>" << endl; + + s.flush(); + } + return ret; +} + + +Data +WebAdmin::buildCertPage(const Data& domain) +{ + assert(!domain.empty()); +#ifdef USE_SSL + assert( mProxy.getStack().getSecurity() ); + return mProxy.getStack().getSecurity()->getDomainCertDER(domain); +#else + ErrLog( << "Proxy not build with support for certificates" ); + return Data::Empty; +#endif +} + + +Data +WebAdmin::buildDefaultPage() +{ + Data ret; + { + DataStream s(ret); + + s << + "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << endl << + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl << + "<html xmlns=\"http://www.w3.org/1999/xhtml\">" << endl << + "<head>" << endl << + "<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />" << endl << + "<title>Repro Proxy Login</title>" << endl << + "</head>" << endl << + + "<body bgcolor=\"#ffffff\">" << endl << + " <h1><a href=\"user.html\">Login</a></h1>" << endl << + " <p>The default account is 'admin' with password 'admin', but if you're wise, you've already changed that using the command line</p>" << endl << + "</body>" << endl << + "</html>" << endl; + + s.flush(); + } + return ret; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/WebAdmin.hxx b/src/libs/resiprocate/repro/WebAdmin.hxx new file mode 100644 index 00000000..72f75848 --- /dev/null +++ b/src/libs/resiprocate/repro/WebAdmin.hxx @@ -0,0 +1,154 @@ +#if !defined(RESIP_WEBADMIN_HXX) +#define RESIP_WEBADMIN_HXX + +#include "rutil/Data.hxx" +#include "rutil/Condition.hxx" +#include "rutil/dns/DnsStub.hxx" +#include "rutil/TransportType.hxx" +#include "resip/stack/Tuple.hxx" +#include "repro/HttpBase.hxx" + +#include <map> + +namespace resip +{ +class RegistrationPersistenceManager; +class Security; +class DataStream; +} + + +namespace repro +{ +class Store; +class UserStore; +class RouteStore; +typedef std::map<resip::Data, resip::Data> Dictionary; +class Proxy; + +class WebAdmin : public HttpBase, + public resip::GetDnsCacheDumpHandler +{ + public: + WebAdmin(Proxy& proxy, + resip::RegistrationPersistenceManager& regDb, + const resip::Data& realm, // this realm is used for http challenges + int port=5080, + resip::IpVersion version=resip::V4); + + protected: + virtual void buildPage( const resip::Data& uri, + int pageNumber, + const resip::Data& user, + const resip::Data& password); + + // Handler + virtual void onDnsCacheDumpRetrieved(std::pair<unsigned long, unsigned long> key, const resip::Data& dnsEntryStrings); + + private: + resip::Data buildDefaultPage(); + resip::Data buildUserPage(); + + void buildDomainsSubPage(resip::DataStream& s); + void buildAclsSubPage(resip::DataStream& s); + + void buildAddUserSubPage(resip::DataStream& s); + void buildEditUserSubPage(resip::DataStream& s); + void buildShowUsersSubPage(resip::DataStream& s); + + void buildAddFilterSubPage(resip::DataStream& s); + void buildEditFilterSubPage(resip::DataStream& s); + void buildShowFiltersSubPage(resip::DataStream& s); + + void buildAddRouteSubPage(resip::DataStream& s); + void buildEditRouteSubPage(resip::DataStream& s); + void buildShowRoutesSubPage(resip::DataStream& s); + + void buildRegistrationsSubPage(resip::DataStream& s); + void buildSettingsSubPage(resip::DataStream& s); + void buildRestartSubPage(resip::DataStream& s); + + resip::Data buildCertPage(const resip::Data& domain); + + Proxy& mProxy; + Store& mStore; + resip::RegistrationPersistenceManager& mRegDb; + + resip::Data mDnsCache; + resip::Mutex mDnsCacheMutex; + resip::Condition mDnsCacheCondition; + + bool mNoWebChallenges; + + Dictionary mHttpParams; + + // list of the keys of records that should be deleted + class RemoveKey + { + public: + RemoveKey(const resip::Data &key1, const resip::Data &key2); + bool operator<(const RemoveKey& rhs) const; + resip::Data mKey1; + resip::Data mKey2; + }; + std::set<RemoveKey> mRemoveSet; + + resip::Data mPageOutlinePre; + resip::Data mPageOutlinePost; +}; + + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/WebAdminThread.cxx b/src/libs/resiprocate/repro/WebAdminThread.cxx new file mode 100644 index 00000000..29311462 --- /dev/null +++ b/src/libs/resiprocate/repro/WebAdminThread.cxx @@ -0,0 +1,91 @@ + +#include "rutil/Socket.hxx" +#include "rutil/Logger.hxx" + +#include "repro/WebAdmin.hxx" +#include "repro/WebAdminThread.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + + +WebAdminThread::WebAdminThread(WebAdmin& web) + : mWeb(web) +{ +} + + +void +WebAdminThread::thread() +{ + while (!isShutdown()) + { + try + { + FdSet fdset; + + mWeb.buildFdSet(fdset); + fdset.selectMilliSeconds( 10*1000 ); + + mWeb.process(fdset); + } + catch (...) + { + ErrLog (<< "Unhandled exception: " ); + } + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/WebAdminThread.hxx b/src/libs/resiprocate/repro/WebAdminThread.hxx new file mode 100644 index 00000000..e70ed2c4 --- /dev/null +++ b/src/libs/resiprocate/repro/WebAdminThread.hxx @@ -0,0 +1,80 @@ +#ifndef REPRO_WebAdminThread__hxx +#define REPRO_WebAdminThread__hxx + +#include "rutil/ThreadIf.hxx" +#include "rutil/Socket.hxx" + +namespace repro +{ + +class WebAdmin; + +class WebAdminThread : public resip::ThreadIf +{ + public: + WebAdminThread(WebAdmin& web); + + virtual void thread(); + + protected: + // virtual void buildFdSet(FdSet& fdset); + // virtual unsigned int getTimeTillNextProcessMS() const; + + private: + WebAdmin& mWeb; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/WinSetup/Setup.vdproj b/src/libs/resiprocate/repro/WinSetup/Setup.vdproj new file mode 100644 index 00000000..f1e86859 --- /dev/null +++ b/src/libs/resiprocate/repro/WinSetup/Setup.vdproj @@ -0,0 +1,787 @@ +"DeployProject" +{ +"VSVersion" = "3:701" +"ProjectType" = "8:{2C2AF0D9-9B47-4FE5-BEF2-169778172667}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:ReproSetup" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:" +"SccLocalPath" = "8:" +"SccAuxPath" = "8:" +"SccProvider" = "8:" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5752D824D4BA4CC4AE9A4129533CC084" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B0B648F097BA49E5AF24FE8FAAAA3E44" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Debug" + { + "DisplayName" = "8:Debug" + "IsDebugOnly" = "11:TRUE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug\\Setup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + } + "Debug71" + { + "DisplayName" = "8:Debug71" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug71\\Setup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + } + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:TRUE" + "OutputFilename" = "8:Release\\Setup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + } + } + "Deployable" + { + "CustomAction" + { + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "ExternalPersistence" + { + "LaunchCondition" + { + } + } + "Feature" + { + } + "File" + { + "{A582A373-4685-4296-BEFE-614B80A702C3}:_5752D824D4BA4CC4AE9A4129533CC084" + { + "SourcePath" = "8:readme.txt" + "TargetName" = "8:readme.txt" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{A582A373-4685-4296-BEFE-614B80A702C3}:_B0B648F097BA49E5AF24FE8FAAAA3E44" + { + "SourcePath" = "8:..\\VERSION" + "TargetName" = "8:VERSION" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + } + "FileType" + { + } + "Folder" + { + "{78BAF5CE-F2E5-45BE-83BC-DB6AF387E941}:_660157A3B47741D29DE272F721459B84" + { + "Name" = "8:#1919" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramMenuFolder" + "Folders" + { + "{F27BD5C5-A65D-4608-96D4-7C5DA1F76302}:_ADAE71E3079D4A2691B0E37C4D87E8F8" + { + "Name" = "8:Repro SIP Proxy" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_AF021D3F7DAB4BC09DEE7EB935F2F237" + "Folders" + { + } + } + } + } + "{58C0ADA3-3CEA-43BD-A3B3-2EA121BC8217}:_96F138CFF79546568B8B0A6277D34A78" + { + "DefaultLocation" = "8:[ProgramFilesFolder]ReproSIPProxy" + "Name" = "8:#1925" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:TARGETDIR" + "Folders" + { + } + } + "{78BAF5CE-F2E5-45BE-83BC-DB6AF387E941}:_C7E885D6EFDA4457AF7FABB767CBA37B" + { + "Name" = "8:#1916" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:DesktopFolder" + "Folders" + { + } + } + } + "LaunchCondition" + { + } + "Locator" + { + } + "MsiBootstrapper" + { + "LangId" = "3:1033" + } + "Product" + { + "Name" = "8:Microsoft Visual Studio" + "ProductName" = "8:Repro SIP Proxy" + "ProductCode" = "8:{1D66F08D-5168-4EC9-B809-CC792E780CA9}" + "PackageCode" = "8:{FB3E028B-C8D1-4BB7-877B-DB02256660BB}" + "UpgradeCode" = "8:{7BD08495-64E4-4565-A1DC-93954D304A2E}" + "RestartWWWService" = "11:FALSE" + "RemovePreviousVersions" = "11:FALSE" + "DetectNewerInstalledVersion" = "11:TRUE" + "ProductVersion" = "8:0.2" + "Manufacturer" = "8:Repro" + "ARPHELPTELEPHONE" = "8:" + "ARPHELPLINK" = "8:http://wiki.resiprocate.org/wiki/index.php?title=Using_Repro" + "Title" = "8:Repro SIP Proxy" + "Subject" = "8:" + "ARPCONTACT" = "8:SipFoundry" + "Keywords" = "8:" + "ARPCOMMENTS" = "8:" + "ARPURLINFOABOUT" = "8:" + "ARPPRODUCTICON" = "8:" + "ARPIconIndex" = "3:0" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + } + "Registry" + { + "HKLM" + { + "Keys" + { + "{6A471EEF-D31B-40F8-BCF6-C9E8EC783F36}:_92E6ABE1FA314948BC368F2227E98153" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{6A471EEF-D31B-40F8-BCF6-C9E8EC783F36}:_B99A52144BE048DC97DC3EFE173710FB" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCU" + { + "Keys" + { + "{6A471EEF-D31B-40F8-BCF6-C9E8EC783F36}:_779A5EB500A34267856D2F430EF79FD1" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{6A471EEF-D31B-40F8-BCF6-C9E8EC783F36}:_2065B4B43D344B57B1F5826325588D10" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Sequences" + { + } + "Shortcut" + { + "{478F747B-8505-45D1-9AAE-8C3B645C26E3}:_19AE3ADF28B64972A3AE92ABD0E11F16" + { + "Name" = "8:Repro SIP Proxy" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "Folder" = "8:_C7E885D6EFDA4457AF7FABB767CBA37B" + "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Icon" = "8:" + "Feature" = "8:" + } + "{478F747B-8505-45D1-9AAE-8C3B645C26E3}:_7CDB993AF3BD44E495FF253FB8E164D9" + { + "Name" = "8:Repro SIP Proxy" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8" + "WorkingFolder" = "8:" + "Icon" = "8:" + "Feature" = "8:" + } + "{478F747B-8505-45D1-9AAE-8C3B645C26E3}:_86981A780076446AB0844591EB5D0967" + { + "Name" = "8:readme.txt" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_5752D824D4BA4CC4AE9A4129533CC084" + "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8" + "WorkingFolder" = "8:" + "Icon" = "8:" + "Feature" = "8:" + } + } + "UserInterface" + { + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_0376427C0CA34D53820774350966F1DB" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_7ADB556CFA0F42DB80B8860C395B68F9" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_2C9F632D652A4EEFAC63A316A3429D76" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_49844F3A786C4BF29F1B64CC7FAFD275" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{B654A020-6903-4E6A-A86C-75DC463DB54B}:_63F207E5C4CA45DEBDC12AAA6E25B32D" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdUserInterface.wim" + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_893CE464B4224560A271C1C8B9D92069" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_85BD74E229434647BDF0C9F179358FA8" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{B654A020-6903-4E6A-A86C-75DC463DB54B}:_93BCC5296412423AB284A32561B4567C" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdBasicDialogs.wim" + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_AEF90AD425CB472D86F931163E5110D3" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_3F5A326588074D9B833D96FA0C920BB3" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_95175F109973424F921309862DF9C903" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_B822F582B0A041BA8B8246347F410FCB" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_B02018E0266C4A6895A1E4193DEAF383" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_6EF7D671153B442FBDB087409CB29241" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_897AFADA01E14F5E83F52464EF958637" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_A2D3E1A1366B497CBB7D52660282E240" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_E61C02CFB002496793768CBD78D89BF5" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_531668423BC24EE9B2A3E847DE11EE3A" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + } + "ProjectOutput" + { + "{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_449747DB7BDE448E8557B9834BB2A62D" + { + "SourcePath" = "8:..\\debug\\repro.exe" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{9D8D2649-213F-49D3-A8B0-C1849C611654}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + } + } +} diff --git a/src/libs/resiprocate/repro/WinSetup/Setup_10_0.vdproj b/src/libs/resiprocate/repro/WinSetup/Setup_10_0.vdproj new file mode 100644 index 00000000..1c1e876d --- /dev/null +++ b/src/libs/resiprocate/repro/WinSetup/Setup_10_0.vdproj @@ -0,0 +1,902 @@ +"DeployProject" +{ +"VSVersion" = "3:800" +"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:ReproSetup" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:" +"SccLocalPath" = "8:" +"SccAuxPath" = "8:" +"SccProvider" = "8:" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_0741BCA175681B47B523D2552E9B8CD5" + "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_35F69CCBB8D2405A81D61032D3055B77" + "OwnerKey" = "8:_442757485B394E61869D01D8D1BBCC92" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_442757485B394E61869D01D8D1BBCC92" + "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5752D824D4BA4CC4AE9A4129533CC084" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_731AD5DF4FB949D3A731B82C4CA70F0D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B0B648F097BA49E5AF24FE8FAAAA3E44" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Debug" + { + "DisplayName" = "8:Debug" + "IsDebugOnly" = "11:TRUE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug\\reproSetup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + } + } + } + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:TRUE" + "OutputFilename" = "8:Release\\reproSetup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + } + } + } + } + "Deployable" + { + "CustomAction" + { + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "ExternalPersistence" + { + "LaunchCondition" + { + } + } + "File" + { + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_0741BCA175681B47B523D2552E9B8CD5" + { + "SourcePath" = "8:IPHLPAPI.DLL" + "TargetName" = "8:IPHLPAPI.DLL" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5752D824D4BA4CC4AE9A4129533CC084" + { + "SourcePath" = "8:readme.txt" + "TargetName" = "8:readme.txt" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_731AD5DF4FB949D3A731B82C4CA70F0D" + { + "SourcePath" = "8:..\\repro.config" + "TargetName" = "8:repro.config" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B0B648F097BA49E5AF24FE8FAAAA3E44" + { + "SourcePath" = "8:..\\VERSION" + "TargetName" = "8:VERSION" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + } + "FileType" + { + } + "Folder" + { + "{1525181F-901A-416C-8A58-119130FE478E}:_660157A3B47741D29DE272F721459B84" + { + "Name" = "8:#1919" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramMenuFolder" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_ADAE71E3079D4A2691B0E37C4D87E8F8" + { + "Name" = "8:Repro SIP Proxy" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_AF021D3F7DAB4BC09DEE7EB935F2F237" + "Folders" + { + } + } + } + } + "{3C67513D-01DD-4637-8A68-80971EB9504F}:_96F138CFF79546568B8B0A6277D34A78" + { + "DefaultLocation" = "8:[ProgramFilesFolder]ReproSIPProxy" + "Name" = "8:#1925" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:TARGETDIR" + "Folders" + { + } + } + "{1525181F-901A-416C-8A58-119130FE478E}:_C7E885D6EFDA4457AF7FABB767CBA37B" + { + "Name" = "8:#1916" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:DesktopFolder" + "Folders" + { + } + } + } + "LaunchCondition" + { + } + "Locator" + { + } + "MsiBootstrapper" + { + "LangId" = "3:1033" + "RequiresElevation" = "11:FALSE" + } + "Product" + { + "Name" = "8:Microsoft Visual Studio" + "ProductName" = "8:Repro SIP Proxy" + "ProductCode" = "8:{1D66F08D-5168-4EC9-B809-CC792E780CA9}" + "PackageCode" = "8:{37A4D1C2-0CC9-4345-BFF9-C0049A9D0C72}" + "UpgradeCode" = "8:{7BD08495-64E4-4565-A1DC-93954D304A2E}" + "AspNetVersion" = "8:4.0.30319.0" + "RestartWWWService" = "11:FALSE" + "RemovePreviousVersions" = "11:FALSE" + "DetectNewerInstalledVersion" = "11:TRUE" + "InstallAllUsers" = "11:FALSE" + "ProductVersion" = "8:0.2" + "Manufacturer" = "8:Repro" + "ARPHELPTELEPHONE" = "8:" + "ARPHELPLINK" = "8:http://wiki.resiprocate.org/wiki/index.php?title=Using_Repro" + "Title" = "8:Repro SIP Proxy" + "Subject" = "8:" + "ARPCONTACT" = "8:reSIP" + "Keywords" = "8:" + "ARPCOMMENTS" = "8:" + "ARPURLINFOABOUT" = "8:" + "ARPPRODUCTICON" = "8:" + "ARPIconIndex" = "3:0" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + "TargetPlatform" = "3:0" + "PreBuildEvent" = "8:" + "PostBuildEvent" = "8:" + "RunPostBuildEvent" = "3:0" + } + "Registry" + { + "HKLM" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_92E6ABE1FA314948BC368F2227E98153" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_B99A52144BE048DC97DC3EFE173710FB" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCU" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_779A5EB500A34267856D2F430EF79FD1" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_2065B4B43D344B57B1F5826325588D10" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Sequences" + { + } + "Shortcut" + { + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_19AE3ADF28B64972A3AE92ABD0E11F16" + { + "Name" = "8:Repro SIP Proxy" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "Folder" = "8:_C7E885D6EFDA4457AF7FABB767CBA37B" + "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Icon" = "8:" + "Feature" = "8:" + } + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_7CDB993AF3BD44E495FF253FB8E164D9" + { + "Name" = "8:Repro SIP Proxy" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8" + "WorkingFolder" = "8:" + "Icon" = "8:" + "Feature" = "8:" + } + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_86981A780076446AB0844591EB5D0967" + { + "Name" = "8:readme.txt" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_5752D824D4BA4CC4AE9A4129533CC084" + "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8" + "WorkingFolder" = "8:" + "Icon" = "8:" + "Feature" = "8:" + } + } + "UserInterface" + { + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_0376427C0CA34D53820774350966F1DB" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_7ADB556CFA0F42DB80B8860C395B68F9" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_2C9F632D652A4EEFAC63A316A3429D76" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_49844F3A786C4BF29F1B64CC7FAFD275" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_63F207E5C4CA45DEBDC12AAA6E25B32D" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdUserInterface.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_893CE464B4224560A271C1C8B9D92069" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_85BD74E229434647BDF0C9F179358FA8" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_93BCC5296412423AB284A32561B4567C" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdBasicDialogs.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_AEF90AD425CB472D86F931163E5110D3" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_3F5A326588074D9B833D96FA0C920BB3" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_95175F109973424F921309862DF9C903" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_B822F582B0A041BA8B8246347F410FCB" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_B02018E0266C4A6895A1E4193DEAF383" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_6EF7D671153B442FBDB087409CB29241" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "InstallAllUsersVisible" + { + "Name" = "8:InstallAllUsersVisible" + "DisplayName" = "8:#1059" + "Description" = "8:#1159" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_897AFADA01E14F5E83F52464EF958637" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_A2D3E1A1366B497CBB7D52660282E240" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_E61C02CFB002496793768CBD78D89BF5" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_531668423BC24EE9B2A3E847DE11EE3A" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_35F69CCBB8D2405A81D61032D3055B77" + { + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:TRUE" + "SourcePath" = "8:microsoft_vc90_debugcrt_x86.msm" + "Properties" + { + } + "LanguageId" = "3:0" + "Exclude" = "11:FALSE" + "Folder" = "8:" + "Feature" = "8:" + "IsolateTo" = "8:" + } + "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_442757485B394E61869D01D8D1BBCC92" + { + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:TRUE" + "SourcePath" = "8:policy_9_0_Microsoft_VC90_DebugCRT_x86.msm" + "Properties" + { + } + "LanguageId" = "3:0" + "Exclude" = "11:FALSE" + "Folder" = "8:" + "Feature" = "8:" + "IsolateTo" = "8:" + } + } + "ProjectOutput" + { + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_449747DB7BDE448E8557B9834BB2A62D" + { + "SourcePath" = "8:..\\Debug\\repro.exe" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{9D8D2649-213F-49D3-A8B0-C1849C611654}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + } + } +} diff --git a/src/libs/resiprocate/repro/WinSetup/Setup_8_0.vdproj b/src/libs/resiprocate/repro/WinSetup/Setup_8_0.vdproj new file mode 100644 index 00000000..05b3f2ec --- /dev/null +++ b/src/libs/resiprocate/repro/WinSetup/Setup_8_0.vdproj @@ -0,0 +1,877 @@ +"DeployProject" +{ +"VSVersion" = "3:800" +"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:ReproSetup" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:" +"SccLocalPath" = "8:" +"SccAuxPath" = "8:" +"SccProvider" = "8:" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5752D824D4BA4CC4AE9A4129533CC084" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_589E4F8781B6EFF5018F0646F96CD14B" + "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8E41C4D12C3648E1BC1DFEC42392972E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B0B648F097BA49E5AF24FE8FAAAA3E44" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Debug" + { + "DisplayName" = "8:Debug" + "IsDebugOnly" = "11:TRUE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug\\Setup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + } + } + } + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:TRUE" + "OutputFilename" = "8:Release\\Setup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + } + } + } + } + "Deployable" + { + "CustomAction" + { + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "ExternalPersistence" + { + "LaunchCondition" + { + } + } + "File" + { + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5752D824D4BA4CC4AE9A4129533CC084" + { + "SourcePath" = "8:readme.txt" + "TargetName" = "8:readme.txt" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_589E4F8781B6EFF5018F0646F96CD14B" + { + "SourcePath" = "8:IPHLPAPI.DLL" + "TargetName" = "8:IPHLPAPI.DLL" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8E41C4D12C3648E1BC1DFEC42392972E" + { + "SourcePath" = "8:..\\repro.config" + "TargetName" = "8:repro.config" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B0B648F097BA49E5AF24FE8FAAAA3E44" + { + "SourcePath" = "8:..\\VERSION" + "TargetName" = "8:VERSION" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + } + "FileType" + { + } + "Folder" + { + "{1525181F-901A-416C-8A58-119130FE478E}:_660157A3B47741D29DE272F721459B84" + { + "Name" = "8:#1919" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramMenuFolder" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_ADAE71E3079D4A2691B0E37C4D87E8F8" + { + "Name" = "8:Repro SIP Proxy" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_AF021D3F7DAB4BC09DEE7EB935F2F237" + "Folders" + { + } + } + } + } + "{3C67513D-01DD-4637-8A68-80971EB9504F}:_96F138CFF79546568B8B0A6277D34A78" + { + "DefaultLocation" = "8:[ProgramFilesFolder]ReproSIPProxy" + "Name" = "8:#1925" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:TARGETDIR" + "Folders" + { + } + } + "{1525181F-901A-416C-8A58-119130FE478E}:_C7E885D6EFDA4457AF7FABB767CBA37B" + { + "Name" = "8:#1916" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:DesktopFolder" + "Folders" + { + } + } + } + "LaunchCondition" + { + } + "Locator" + { + } + "MsiBootstrapper" + { + "LangId" = "3:1033" + } + "Product" + { + "Name" = "8:Microsoft Visual Studio" + "ProductName" = "8:Repro SIP Proxy" + "ProductCode" = "8:{1D66F08D-5168-4EC9-B809-CC792E780CA9}" + "PackageCode" = "8:{71DB4193-5C16-494E-82E5-0224E42063DE}" + "UpgradeCode" = "8:{7BD08495-64E4-4565-A1DC-93954D304A2E}" + "RestartWWWService" = "11:FALSE" + "RemovePreviousVersions" = "11:FALSE" + "DetectNewerInstalledVersion" = "11:TRUE" + "InstallAllUsers" = "11:FALSE" + "ProductVersion" = "8:0.2" + "Manufacturer" = "8:Repro" + "ARPHELPTELEPHONE" = "8:" + "ARPHELPLINK" = "8:http://wiki.resiprocate.org/wiki/index.php?title=Using_Repro" + "Title" = "8:Repro SIP Proxy" + "Subject" = "8:" + "ARPCONTACT" = "8:SipFoundry" + "Keywords" = "8:" + "ARPCOMMENTS" = "8:" + "ARPURLINFOABOUT" = "8:" + "ARPPRODUCTICON" = "8:" + "ARPIconIndex" = "3:0" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + "TargetPlatform" = "3:0" + "PreBuildEvent" = "8:" + "PostBuildEvent" = "8:" + "RunPostBuildEvent" = "3:0" + } + "Registry" + { + "HKLM" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_92E6ABE1FA314948BC368F2227E98153" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_B99A52144BE048DC97DC3EFE173710FB" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCU" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_779A5EB500A34267856D2F430EF79FD1" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_2065B4B43D344B57B1F5826325588D10" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Sequences" + { + } + "Shortcut" + { + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_19AE3ADF28B64972A3AE92ABD0E11F16" + { + "Name" = "8:Repro SIP Proxy" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "Folder" = "8:_C7E885D6EFDA4457AF7FABB767CBA37B" + "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Icon" = "8:" + "Feature" = "8:" + } + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_67AC6DE8B6E64AC1A2DE2739B887577F" + { + "Name" = "8:repro.config" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_8E41C4D12C3648E1BC1DFEC42392972E" + "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8" + "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Icon" = "8:" + "Feature" = "8:" + } + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_7CDB993AF3BD44E495FF253FB8E164D9" + { + "Name" = "8:Repro SIP Proxy" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8" + "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Icon" = "8:" + "Feature" = "8:" + } + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_86981A780076446AB0844591EB5D0967" + { + "Name" = "8:readme.txt" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_5752D824D4BA4CC4AE9A4129533CC084" + "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8" + "WorkingFolder" = "8:" + "Icon" = "8:" + "Feature" = "8:" + } + } + "UserInterface" + { + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_0376427C0CA34D53820774350966F1DB" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_7ADB556CFA0F42DB80B8860C395B68F9" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_2C9F632D652A4EEFAC63A316A3429D76" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_49844F3A786C4BF29F1B64CC7FAFD275" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_63F207E5C4CA45DEBDC12AAA6E25B32D" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdUserInterface.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_893CE464B4224560A271C1C8B9D92069" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_85BD74E229434647BDF0C9F179358FA8" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_93BCC5296412423AB284A32561B4567C" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdBasicDialogs.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_AEF90AD425CB472D86F931163E5110D3" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_3F5A326588074D9B833D96FA0C920BB3" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_95175F109973424F921309862DF9C903" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_B822F582B0A041BA8B8246347F410FCB" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_B02018E0266C4A6895A1E4193DEAF383" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_6EF7D671153B442FBDB087409CB29241" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "InstallAllUsersVisible" + { + "Name" = "8:InstallAllUsersVisible" + "DisplayName" = "8:#1059" + "Description" = "8:#1159" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_897AFADA01E14F5E83F52464EF958637" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_A2D3E1A1366B497CBB7D52660282E240" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_E61C02CFB002496793768CBD78D89BF5" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_531668423BC24EE9B2A3E847DE11EE3A" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + } + "ProjectOutput" + { + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_449747DB7BDE448E8557B9834BB2A62D" + { + "SourcePath" = "8:..\\Debug\\repro.exe" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{9D8D2649-213F-49D3-A8B0-C1849C611654}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + } + "VJSharpPlugin" + { + } + } +} diff --git a/src/libs/resiprocate/repro/WinSetup/Setup_9_0.vdproj b/src/libs/resiprocate/repro/WinSetup/Setup_9_0.vdproj new file mode 100644 index 00000000..6fe71379 --- /dev/null +++ b/src/libs/resiprocate/repro/WinSetup/Setup_9_0.vdproj @@ -0,0 +1,967 @@ +"DeployProject" +{ +"VSVersion" = "3:800" +"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:ReproSetup" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:" +"SccLocalPath" = "8:" +"SccAuxPath" = "8:" +"SccProvider" = "8:" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_2373C74A3C1D452DB473A7DE76DF0713" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_39755B03FA034DFEA236706B87226B76" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_4D212C1D21C34639B306B0B60769803D" + "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5752D824D4BA4CC4AE9A4129533CC084" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_589E4F8781B6EFF5018F0646F96CD14B" + "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_9B970858111B46D498BB6728C709EE22" + "OwnerKey" = "8:_4D212C1D21C34639B306B0B60769803D" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_A06A2BC6896346A8AC7E4F2FDC2B11DF" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B0B648F097BA49E5AF24FE8FAAAA3E44" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Debug" + { + "DisplayName" = "8:Debug" + "IsDebugOnly" = "11:TRUE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug\\Setup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + } + } + } + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:TRUE" + "OutputFilename" = "8:Release\\Setup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + } + } + } + } + "Deployable" + { + "CustomAction" + { + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "ExternalPersistence" + { + "LaunchCondition" + { + } + } + "File" + { + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2373C74A3C1D452DB473A7DE76DF0713" + { + "SourcePath" = "8:..\\GeoIP.dll" + "TargetName" = "8:GeoIP.dll" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_39755B03FA034DFEA236706B87226B76" + { + "SourcePath" = "8:..\\..\\contrib\\MySQLConnectorC\\lib\\opt\\libmysql.dll" + "TargetName" = "8:libmysql.dll" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5752D824D4BA4CC4AE9A4129533CC084" + { + "SourcePath" = "8:readme.txt" + "TargetName" = "8:readme.txt" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_589E4F8781B6EFF5018F0646F96CD14B" + { + "SourcePath" = "8:IPHLPAPI.DLL" + "TargetName" = "8:iphlpapi.dll" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A06A2BC6896346A8AC7E4F2FDC2B11DF" + { + "SourcePath" = "8:..\\repro.config" + "TargetName" = "8:repro.config" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B0B648F097BA49E5AF24FE8FAAAA3E44" + { + "SourcePath" = "8:..\\VERSION" + "TargetName" = "8:VERSION" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + } + "FileType" + { + } + "Folder" + { + "{1525181F-901A-416C-8A58-119130FE478E}:_660157A3B47741D29DE272F721459B84" + { + "Name" = "8:#1919" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramMenuFolder" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_ADAE71E3079D4A2691B0E37C4D87E8F8" + { + "Name" = "8:Repro SIP Proxy" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_AF021D3F7DAB4BC09DEE7EB935F2F237" + "Folders" + { + } + } + } + } + "{3C67513D-01DD-4637-8A68-80971EB9504F}:_96F138CFF79546568B8B0A6277D34A78" + { + "DefaultLocation" = "8:[ProgramFilesFolder]ReproSIPProxy" + "Name" = "8:#1925" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:TARGETDIR" + "Folders" + { + } + } + "{1525181F-901A-416C-8A58-119130FE478E}:_C7E885D6EFDA4457AF7FABB767CBA37B" + { + "Name" = "8:#1916" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:DesktopFolder" + "Folders" + { + } + } + } + "LaunchCondition" + { + } + "Locator" + { + } + "MsiBootstrapper" + { + "LangId" = "3:1033" + "RequiresElevation" = "11:FALSE" + } + "Product" + { + "Name" = "8:Microsoft Visual Studio" + "ProductName" = "8:Repro SIP Proxy" + "ProductCode" = "8:{1D66F08D-5168-4EC9-B809-CC792E780CA9}" + "PackageCode" = "8:{BFCE542D-12FA-45E4-B61E-18BFDCF126C1}" + "UpgradeCode" = "8:{7BD08495-64E4-4565-A1DC-93954D304A2E}" + "RestartWWWService" = "11:FALSE" + "RemovePreviousVersions" = "11:FALSE" + "DetectNewerInstalledVersion" = "11:TRUE" + "InstallAllUsers" = "11:FALSE" + "ProductVersion" = "8:0.2" + "Manufacturer" = "8:Repro" + "ARPHELPTELEPHONE" = "8:" + "ARPHELPLINK" = "8:http://wiki.resiprocate.org/wiki/index.php?title=Using_Repro" + "Title" = "8:Repro SIP Proxy" + "Subject" = "8:" + "ARPCONTACT" = "8:SipFoundry" + "Keywords" = "8:" + "ARPCOMMENTS" = "8:" + "ARPURLINFOABOUT" = "8:" + "ARPPRODUCTICON" = "8:" + "ARPIconIndex" = "3:0" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + "TargetPlatform" = "3:0" + "PreBuildEvent" = "8:" + "PostBuildEvent" = "8:" + "RunPostBuildEvent" = "3:0" + } + "Registry" + { + "HKLM" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_92E6ABE1FA314948BC368F2227E98153" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_B99A52144BE048DC97DC3EFE173710FB" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCU" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_779A5EB500A34267856D2F430EF79FD1" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_2065B4B43D344B57B1F5826325588D10" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Sequences" + { + } + "Shortcut" + { + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_19AE3ADF28B64972A3AE92ABD0E11F16" + { + "Name" = "8:Repro SIP Proxy" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "Folder" = "8:_C7E885D6EFDA4457AF7FABB767CBA37B" + "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Icon" = "8:" + "Feature" = "8:" + } + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_7CDB993AF3BD44E495FF253FB8E164D9" + { + "Name" = "8:Repro SIP Proxy" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8" + "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Icon" = "8:" + "Feature" = "8:" + } + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_86981A780076446AB0844591EB5D0967" + { + "Name" = "8:readme.txt" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_5752D824D4BA4CC4AE9A4129533CC084" + "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8" + "WorkingFolder" = "8:" + "Icon" = "8:" + "Feature" = "8:" + } + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_E3DD708E008F4D00A29C2A04F00D7F0C" + { + "Name" = "8:repro.config" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_A06A2BC6896346A8AC7E4F2FDC2B11DF" + "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8" + "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Icon" = "8:" + "Feature" = "8:" + } + } + "UserInterface" + { + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_0376427C0CA34D53820774350966F1DB" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_7ADB556CFA0F42DB80B8860C395B68F9" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_2C9F632D652A4EEFAC63A316A3429D76" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_49844F3A786C4BF29F1B64CC7FAFD275" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_63F207E5C4CA45DEBDC12AAA6E25B32D" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdUserInterface.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_893CE464B4224560A271C1C8B9D92069" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_85BD74E229434647BDF0C9F179358FA8" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_93BCC5296412423AB284A32561B4567C" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdBasicDialogs.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_AEF90AD425CB472D86F931163E5110D3" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_3F5A326588074D9B833D96FA0C920BB3" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_95175F109973424F921309862DF9C903" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_B822F582B0A041BA8B8246347F410FCB" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_B02018E0266C4A6895A1E4193DEAF383" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_6EF7D671153B442FBDB087409CB29241" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "InstallAllUsersVisible" + { + "Name" = "8:InstallAllUsersVisible" + "DisplayName" = "8:#1059" + "Description" = "8:#1159" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_897AFADA01E14F5E83F52464EF958637" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_A2D3E1A1366B497CBB7D52660282E240" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_E61C02CFB002496793768CBD78D89BF5" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_531668423BC24EE9B2A3E847DE11EE3A" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_4D212C1D21C34639B306B0B60769803D" + { + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:TRUE" + "SourcePath" = "8:policy_9_0_Microsoft_VC90_DebugCRT_x86.msm" + "Properties" + { + } + "LanguageId" = "3:0" + "Exclude" = "11:FALSE" + "Folder" = "8:" + "Feature" = "8:" + "IsolateTo" = "8:" + } + "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_9B970858111B46D498BB6728C709EE22" + { + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:TRUE" + "SourcePath" = "8:microsoft_vc90_debugcrt_x86.msm" + "Properties" + { + } + "LanguageId" = "3:0" + "Exclude" = "11:FALSE" + "Folder" = "8:" + "Feature" = "8:" + "IsolateTo" = "8:" + } + } + "ProjectOutput" + { + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_449747DB7BDE448E8557B9834BB2A62D" + { + "SourcePath" = "8:..\\SSL-Debug\\repro.exe" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{9D8D2649-213F-49D3-A8B0-C1849C611654}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + } + } +} diff --git a/src/libs/resiprocate/repro/WinSetup/readme.txt b/src/libs/resiprocate/repro/WinSetup/readme.txt new file mode 100644 index 00000000..179141d2 --- /dev/null +++ b/src/libs/resiprocate/repro/WinSetup/readme.txt @@ -0,0 +1,17 @@ +Main Web Site: +http://www.sipfoundry.org/repro/ + +For the latest documentation please see: +http://wiki.resiprocate.org/wiki/index.php?title=Main_Page#Repro_SIP_Proxy_Server or +http://wiki.resiprocate.org/ + +**WARNING - command line options in version 1.8 are not backwards compatible with older releases. + +Command line format is: + +repro [<ConfigFilename>] [--<ConfigValueName>=<ConfigValue>] [--<ConfigValueName>=<ConfigValue>] + +Sample Command lines: +repro repro.config --RecordRouteUri=sip:proxy.sipdomain.com --ForceRecordRouting=true +repro repro.config /RecordRouteUri:sip:proxy.sipdomain.com /ForceRecordRouting:true + diff --git a/src/libs/resiprocate/repro/WinSetupx64/Setupx64_10_0.vdproj b/src/libs/resiprocate/repro/WinSetupx64/Setupx64_10_0.vdproj new file mode 100644 index 00000000..7826d2d0 --- /dev/null +++ b/src/libs/resiprocate/repro/WinSetupx64/Setupx64_10_0.vdproj @@ -0,0 +1,902 @@ +"DeployProject" +{ +"VSVersion" = "3:800" +"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:ReproSetupx64" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:" +"SccLocalPath" = "8:" +"SccAuxPath" = "8:" +"SccProvider" = "8:" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_0741BCA175681B47B523D2552E9B8CD5" + "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5752D824D4BA4CC4AE9A4129533CC084" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_71F618E7C4DC4C8BB9951979ACAAE6D0" + "OwnerKey" = "8:_CB0C4F3295DA49D9A1651EA26C9ED155" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8D12D2A1F5184F799E9F0D5FD0668526" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B0B648F097BA49E5AF24FE8FAAAA3E44" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_CB0C4F3295DA49D9A1651EA26C9ED155" + "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Debug" + { + "DisplayName" = "8:Debug" + "IsDebugOnly" = "11:TRUE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug\\reproSetup64.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + } + } + } + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:TRUE" + "OutputFilename" = "8:Release\\reproSetup64.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + } + } + } + } + "Deployable" + { + "CustomAction" + { + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "ExternalPersistence" + { + "LaunchCondition" + { + } + } + "File" + { + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_0741BCA175681B47B523D2552E9B8CD5" + { + "SourcePath" = "8:IPHLPAPI.DLL" + "TargetName" = "8:IPHLPAPI.DLL" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5752D824D4BA4CC4AE9A4129533CC084" + { + "SourcePath" = "8:readme.txt" + "TargetName" = "8:readme.txt" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8D12D2A1F5184F799E9F0D5FD0668526" + { + "SourcePath" = "8:..\\repro.config" + "TargetName" = "8:repro.config" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B0B648F097BA49E5AF24FE8FAAAA3E44" + { + "SourcePath" = "8:..\\VERSION" + "TargetName" = "8:VERSION" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + } + "FileType" + { + } + "Folder" + { + "{1525181F-901A-416C-8A58-119130FE478E}:_660157A3B47741D29DE272F721459B84" + { + "Name" = "8:#1919" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramMenuFolder" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_ADAE71E3079D4A2691B0E37C4D87E8F8" + { + "Name" = "8:Repro SIP Proxy" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_AF021D3F7DAB4BC09DEE7EB935F2F237" + "Folders" + { + } + } + } + } + "{3C67513D-01DD-4637-8A68-80971EB9504F}:_96F138CFF79546568B8B0A6277D34A78" + { + "DefaultLocation" = "8:[ProgramFilesFolder]ReproSIPProxy" + "Name" = "8:#1925" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:TARGETDIR" + "Folders" + { + } + } + "{1525181F-901A-416C-8A58-119130FE478E}:_C7E885D6EFDA4457AF7FABB767CBA37B" + { + "Name" = "8:#1916" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:DesktopFolder" + "Folders" + { + } + } + } + "LaunchCondition" + { + } + "Locator" + { + } + "MsiBootstrapper" + { + "LangId" = "3:1033" + "RequiresElevation" = "11:FALSE" + } + "Product" + { + "Name" = "8:Microsoft Visual Studio" + "ProductName" = "8:Repro SIP Proxy" + "ProductCode" = "8:{1D66F08D-5168-4EC9-B809-CC792E780CA9}" + "PackageCode" = "8:{C2A7BF2A-F92D-4D3B-B230-4ACC470A2FCD}" + "UpgradeCode" = "8:{7BD08495-64E4-4565-A1DC-93954D304A2E}" + "AspNetVersion" = "8:4.0.30319.0" + "RestartWWWService" = "11:FALSE" + "RemovePreviousVersions" = "11:FALSE" + "DetectNewerInstalledVersion" = "11:TRUE" + "InstallAllUsers" = "11:FALSE" + "ProductVersion" = "8:0.2" + "Manufacturer" = "8:Repro" + "ARPHELPTELEPHONE" = "8:" + "ARPHELPLINK" = "8:http://wiki.resiprocate.org/wiki/index.php?title=Using_Repro" + "Title" = "8:Repro SIP Proxy" + "Subject" = "8:" + "ARPCONTACT" = "8:reSIP" + "Keywords" = "8:" + "ARPCOMMENTS" = "8:" + "ARPURLINFOABOUT" = "8:" + "ARPPRODUCTICON" = "8:" + "ARPIconIndex" = "3:0" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + "TargetPlatform" = "3:1" + "PreBuildEvent" = "8:" + "PostBuildEvent" = "8:" + "RunPostBuildEvent" = "3:0" + } + "Registry" + { + "HKLM" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_92E6ABE1FA314948BC368F2227E98153" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_B99A52144BE048DC97DC3EFE173710FB" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCU" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_779A5EB500A34267856D2F430EF79FD1" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_2065B4B43D344B57B1F5826325588D10" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Sequences" + { + } + "Shortcut" + { + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_19AE3ADF28B64972A3AE92ABD0E11F16" + { + "Name" = "8:Repro SIP Proxy" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "Folder" = "8:_C7E885D6EFDA4457AF7FABB767CBA37B" + "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Icon" = "8:" + "Feature" = "8:" + } + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_7CDB993AF3BD44E495FF253FB8E164D9" + { + "Name" = "8:Repro SIP Proxy" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_449747DB7BDE448E8557B9834BB2A62D" + "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8" + "WorkingFolder" = "8:" + "Icon" = "8:" + "Feature" = "8:" + } + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_86981A780076446AB0844591EB5D0967" + { + "Name" = "8:readme.txt" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_5752D824D4BA4CC4AE9A4129533CC084" + "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8" + "WorkingFolder" = "8:" + "Icon" = "8:" + "Feature" = "8:" + } + } + "UserInterface" + { + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_0376427C0CA34D53820774350966F1DB" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_7ADB556CFA0F42DB80B8860C395B68F9" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_2C9F632D652A4EEFAC63A316A3429D76" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_49844F3A786C4BF29F1B64CC7FAFD275" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_63F207E5C4CA45DEBDC12AAA6E25B32D" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdUserInterface.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_893CE464B4224560A271C1C8B9D92069" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_85BD74E229434647BDF0C9F179358FA8" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_93BCC5296412423AB284A32561B4567C" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdBasicDialogs.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_AEF90AD425CB472D86F931163E5110D3" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_3F5A326588074D9B833D96FA0C920BB3" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_95175F109973424F921309862DF9C903" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_B822F582B0A041BA8B8246347F410FCB" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_B02018E0266C4A6895A1E4193DEAF383" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_6EF7D671153B442FBDB087409CB29241" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "InstallAllUsersVisible" + { + "Name" = "8:InstallAllUsersVisible" + "DisplayName" = "8:#1059" + "Description" = "8:#1159" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_897AFADA01E14F5E83F52464EF958637" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_A2D3E1A1366B497CBB7D52660282E240" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_E61C02CFB002496793768CBD78D89BF5" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_531668423BC24EE9B2A3E847DE11EE3A" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_71F618E7C4DC4C8BB9951979ACAAE6D0" + { + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:TRUE" + "SourcePath" = "8:microsoft_vc90_debugcrt_x86.msm" + "Properties" + { + } + "LanguageId" = "3:0" + "Exclude" = "11:FALSE" + "Folder" = "8:" + "Feature" = "8:" + "IsolateTo" = "8:" + } + "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_CB0C4F3295DA49D9A1651EA26C9ED155" + { + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:TRUE" + "SourcePath" = "8:policy_9_0_Microsoft_VC90_DebugCRT_x86.msm" + "Properties" + { + } + "LanguageId" = "3:0" + "Exclude" = "11:FALSE" + "Folder" = "8:" + "Feature" = "8:" + "IsolateTo" = "8:" + } + } + "ProjectOutput" + { + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_449747DB7BDE448E8557B9834BB2A62D" + { + "SourcePath" = "8:..\\Debug\\repro.exe" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{9D8D2649-213F-49D3-A8B0-C1849C611654}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + } + } +} diff --git a/src/libs/resiprocate/repro/WinSetupx64/readme.txt b/src/libs/resiprocate/repro/WinSetupx64/readme.txt new file mode 100644 index 00000000..253762c9 --- /dev/null +++ b/src/libs/resiprocate/repro/WinSetupx64/readme.txt @@ -0,0 +1,98 @@ +Repro Version: Capuchin 0.2 - Feb, 2006 + +Main Web Site: +http://www.sipfoundry.org/repro/ + +For the latest documentation please see: +http://wiki.resiprocate.org/wiki/index.php?title=Main_Page#Repro_SIP_Proxy_Server or +http://wiki.resiprocate.org/ + +repro --help +Usage: SSL-Debug\repro [OPTION...] + -l, --log-type=syslog|cerr|cout where to send logging + messages (default: + "cout") + -v, --log-level=STACK|DEBUG|INFO|WARNING|ALERT specify the default + log level (default: + "INFO") + -r, --record-route=sip:example.com specify uri to use as + Record-Route + --udp=5060 listen on UDP port + (default: 5060) + --tcp=5060 listen on TCP port + (default: 5060) + -t, --tls-domain=example.com act as a TLS server + for specified domain + --tls=5061 add TLS transport on + specified port + (default: 5061) + --dtls=0 add DTLS transport on + specified port + (default: 0) + --enable-cert-server run a cert server + -c, --cert-path=STRING path for certificates + (default: c:\sipCerts) + (default: + "C:\sipCerts") + --enable-v6 enable IPV6 + --disable-v4 disable IPV4 + --disable-auth disable DIGEST + challenges + --disable-web-auth disable HTTP challenges + --disable-reg disable registrar + -i, --interfaces=sip:10.1.1.1:5065;transport=tls specify interfaces to + add transports to + -d, --domains=example.com,foo.com specify domains that + this proxy is + authorative + -R, --route=sip:p1.example.com,sip:p2.example.com specify where to route + requests that are in + this proxy's domain + --reqChainName=STRING name of request chain + (default: default) + --http=5080 run HTTP server on + specified port + (default: 5080) + --recursive-redirect Handle 3xx responses + in the proxy + --q-value Enable sequential + q-value processing + --q-value-behavior=STRING Specify forking + behavior for q-value + targets: + FULL_SEQUENTIAL, + EQUAL_Q_PARALLEL, or + FULL_PARALLEL + --q-value-cancel-btw-fork-groups Whether to cancel + groups of parallel + forks after the period + specified by the + --q-value-ms-before-cancel + parameter. + --q-value-wait-for-terminate-btw-fork-groups Whether to wait for + parallel fork groups + to terminate before + starting new + fork-groups. + --q-value-ms-between-fork-groups=INT msec to wait before + starting new groups of + parallel forks + --q-value-ms-before-cancel=INT msec to wait before + cancelling parallel + fork groups + -e, --enum-suffix=e164.arpa specify enum suffix to + search + -b, --allow-bad-reg allow To tag in + registrations + --timer-C=180 specify length of + timer C in sec (0 or + negative will disable + timer C) + -a, --admin-password= set web administrator + password + -V, --version show the version number + +Help options: + -?, --help Show this help message + --usage Display brief usage + message diff --git a/src/libs/resiprocate/repro/Worker.hxx b/src/libs/resiprocate/repro/Worker.hxx new file mode 100644 index 00000000..b76999ed --- /dev/null +++ b/src/libs/resiprocate/repro/Worker.hxx @@ -0,0 +1,71 @@ +#ifndef WORKER_HXX +#define WORKER_HXX 1 + +#include "resip/stack/ApplicationMessage.hxx" +#include <cassert> + +namespace repro +{ + +class Worker +{ + public: + Worker(){}; + virtual ~Worker(){}; + + // return true to queue to stack when complete, false when no response is required + virtual bool process(resip::ApplicationMessage* msg)=0; + virtual Worker* clone() const=0; +}; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/WorkerThread.cxx b/src/libs/resiprocate/repro/WorkerThread.cxx new file mode 100644 index 00000000..665aae62 --- /dev/null +++ b/src/libs/resiprocate/repro/WorkerThread.cxx @@ -0,0 +1,103 @@ +#include "repro/WorkerThread.hxx" + +#include "resip/stack/SipStack.hxx" +#include "resip/stack/ApplicationMessage.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +namespace repro +{ + +WorkerThread::WorkerThread(Worker* worker, + resip::TimeLimitFifo<resip::ApplicationMessage>& fifo, + resip::SipStack* stack): + mWorker(worker), + mFifo(fifo), + mStack(stack) +{} + +WorkerThread::~WorkerThread() +{ + shutdown(); + join(); + delete mWorker; +} + +void +WorkerThread::thread() +{ + resip::ApplicationMessage* msg; + bool queueToStack; + while(mWorker && !isShutdown()) + { + if( (msg=mFifo.getNext(100)) != 0 ) + { + queueToStack = mWorker->process(msg); + + if(queueToStack && mStack) + { + // Post to stack instead of directly to TU, since stack does + // some safety checks to ensure the TU still exists before posting + mStack->post(std::auto_ptr<resip::ApplicationMessage>(msg)); + } + else + { + //ErrLog(<<"Stack pointer not set!"); + delete msg; + } + } + } +} + +}//namespace repro + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/WorkerThread.hxx b/src/libs/resiprocate/repro/WorkerThread.hxx new file mode 100644 index 00000000..322b14eb --- /dev/null +++ b/src/libs/resiprocate/repro/WorkerThread.hxx @@ -0,0 +1,83 @@ +#ifndef WORKER_THREAD_HXX +#define WORKER_THREAD_HXX 1 + +#include "rutil/ThreadIf.hxx" +#include "repro/Worker.hxx" +#include "rutil/TimeLimitFifo.hxx" +#include "resip/stack/ApplicationMessage.hxx" + +namespace resip +{ +class SipStack; +} + +namespace repro +{ + +class WorkerThread : public resip::ThreadIf +{ + + public: + WorkerThread(Worker* impl,resip::TimeLimitFifo<resip::ApplicationMessage>& fifo,resip::SipStack* stack); + virtual ~WorkerThread(); + void thread(); + + protected: + Worker* mWorker; + resip::TimeLimitFifo<resip::ApplicationMessage>& mFifo; + resip::SipStack* mStack; + +}; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/XmlRpcConnection.cxx b/src/libs/resiprocate/repro/XmlRpcConnection.cxx new file mode 100644 index 00000000..f2c2b97c --- /dev/null +++ b/src/libs/resiprocate/repro/XmlRpcConnection.cxx @@ -0,0 +1,316 @@ +#include <cassert> + +#include <rutil/Data.hxx> +#include <rutil/Socket.hxx> +#include <resip/stack/Symbols.hxx> +#include <rutil/TransportType.hxx> +#include <rutil/Logger.hxx> +#include <resip/stack/Tuple.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/ParseBuffer.hxx> + +#include "repro/XmlRpcServerBase.hxx" +#include "repro/XmlRpcConnection.hxx" + +using namespace repro; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + +unsigned int XmlRpcConnection::NextConnectionId = 1; + + +XmlRpcConnection::XmlRpcConnection(XmlRpcServerBase& server, resip::Socket sock): + mXmlRcpServer(server), + mConnectionId(NextConnectionId++), + mNextRequestId(1), + mSock(sock) +{ + assert(mSock > 0); +} + + +XmlRpcConnection::~XmlRpcConnection() +{ + assert(mSock > 0); +#ifdef WIN32 + closesocket(mSock); +#else + close(mSock); +#endif + mSock=0; +} + + +void +XmlRpcConnection::buildFdSet(FdSet& fdset) +{ + if (!mTxBuffer.empty()) + { + fdset.setWrite(mSock); + } + fdset.setRead(mSock); +} + + +bool +XmlRpcConnection::process(FdSet& fdset) +{ + if (fdset.hasException(mSock)) + { + int errNum = 0; + int errNumSize = sizeof(errNum); + getsockopt(mSock,SOL_SOCKET,SO_ERROR,(char *)&errNum,(socklen_t *)&errNumSize); + InfoLog (<< "XmlRpcConnection::process: Exception reading from socket " + << (int)mSock << " code: " << errNum << "; closing connection"); + return false; + } + + if (fdset.readyToRead(mSock)) + { + bool ok = processSomeReads(); + if (!ok) + { + return false; + } + } + if ((!mTxBuffer.empty()) && fdset.readyToWrite(mSock)) + { + bool ok = processSomeWrites(); + if (!ok) + { + return false; + } + } + + return true; +} + +bool +XmlRpcConnection::processSomeReads() +{ + const int bufSize = 8000; + char buf[bufSize]; + + +#if defined(WIN32) + int bytesRead = ::recv(mSock, buf, bufSize, 0); +#else + int bytesRead = ::read(mSock, buf, bufSize); +#endif + + if (bytesRead == INVALID_SOCKET) + { + int e = getErrno(); + XmlRpcServerBase::logSocketError(e); + InfoLog (<< "XmlRpcConnection::processSomeReads: Failed read on " << (int)mSock); + return false; + } + else if(bytesRead == 0) + { + DebugLog (<< "XmlRpcConnection::processSomeReads: Connection closed by remote"); + return false; + } + + //DebugLog (<< "XmlRpcConnection::processSomeReads: read=" << bytesRead); + + mRxBuffer += Data( buf, bytesRead ); + + while(tryParse()); + + return true; +} + + +bool +XmlRpcConnection::tryParse() +{ + ParseBuffer pb(mRxBuffer); + Data initialTag; + const char* start = pb.position(); + pb.skipWhitespace(); + pb.skipToChar('<'); + if(!pb.eof()) + { + pb.skipChar(); + const char* anchor = pb.position(); + pb.skipToChar('>'); + if(!pb.eof()) + { + initialTag = pb.data(anchor); + // Find end of initial tag + pb.skipToChars("</" + initialTag + ">"); + if (!pb.eof()) + { + pb.skipN((int)initialTag.size() + 3); // Skip past </InitialTag> + mRequests[mNextRequestId] = pb.data(start); + mXmlRcpServer.handleRequest(mConnectionId, mNextRequestId, mRequests[mNextRequestId]); + mNextRequestId++; + + // Remove processed data from RxBuffer + pb.skipWhitespace(); + if(!pb.eof()) + { + anchor = pb.position(); + pb.skipToEnd(); + mRxBuffer = pb.data(anchor); + return true; + } + else + { + mRxBuffer.clear(); + } + } + } + } + return false; +} + +bool +XmlRpcConnection::processSomeWrites() +{ + if (mTxBuffer.empty()) + { + return true; + } + + //DebugLog (<< "XmlRpcConnection::processSomeWrites: Writing " << mTxBuffer ); + +#if defined(WIN32) + int bytesWritten = ::send(mSock, mTxBuffer.data(), (int)mTxBuffer.size(), 0); +#else + int bytesWritten = ::write(mSock, mTxBuffer.data(), mTxBuffer.size() ); +#endif + + if (bytesWritten == INVALID_SOCKET) + { + int e = getErrno(); + XmlRpcServerBase::logSocketError(e); + InfoLog (<< "XmlRpcConnection::processSomeWrites - failed write on " << mSock << " " << strerror(e)); + + return false; + } + + if (bytesWritten == (int)mTxBuffer.size()) + { + DebugLog (<< "XmlRpcConnection::processSomeWrites - Wrote it all" ); + mTxBuffer = Data::Empty; + + //return false; // return false causes connection to close and clean up + return true; // keep connection up + } + else + { + Data rest = mTxBuffer.substr(bytesWritten); + mTxBuffer = rest; + DebugLog( << "XmlRpcConnection::processSomeWrites - Wrote " << bytesWritten << " bytes - still need to do " << mTxBuffer ); + } + + return true; +} + +bool +XmlRpcConnection::sendResponse(unsigned int requestId, const Data& responseData, bool isFinal) +{ + RequestMap::iterator it = mRequests.find(requestId); + if(it != mRequests.end()) + { + Data& request = it->second; + Data response(request.size() + responseData.size() + 30, Data::Preallocate); + ParseBuffer pb(request); + + // A response is formed by starting with the request and inserting the + // ResponseData between <Response> tags at the same level as the <Request> tags + const char* start = pb.position(); + pb.skipToChars("</Request>"); + if (!pb.eof()) + { + pb.skipN(10); // Skip past </Request> + pb.skipWhitespace(); + + // Response starts with request message up to end of Request tag + response = pb.data(start); + + // Add in response data + response += Symbols::CRLF; + response += " <Response>" + responseData + " </Response>"; + response += Symbols::CRLF; + + // Add remainder of request message + start = pb.position(); + pb.skipToEnd(); + response += pb.data(start); + } + else + { + // No Request in message - just send bare response + response = "<Response>" + responseData + "</Response>"; + } + mTxBuffer += response; + if(isFinal) + { + mRequests.erase(it); + } + return true; + } + return false; +} + +void +XmlRpcConnection::sendEvent(const Data& eventData) +{ + mTxBuffer += eventData; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/repro/XmlRpcConnection.hxx b/src/libs/resiprocate/repro/XmlRpcConnection.hxx new file mode 100644 index 00000000..ed997d2c --- /dev/null +++ b/src/libs/resiprocate/repro/XmlRpcConnection.hxx @@ -0,0 +1,101 @@ +#if !defined(XmlRpcConnection_hxx) +#define XmlRpcConnection_hxx + +#include <map> +#include <rutil/Data.hxx> +#include <rutil/Socket.hxx> +#include <rutil/TransportType.hxx> +#include <resip/stack/Tuple.hxx> + +#include "repro/XmlRpcServerBase.hxx" + +namespace repro +{ + +class XmlRpcConnection +{ + friend class XmlRpcServerBase; + +public: + XmlRpcConnection(XmlRpcServerBase& server, resip::Socket sock); + ~XmlRpcConnection(); + + unsigned int getConnectionId() const { return mConnectionId; } + void buildFdSet(resip::FdSet& fdset); + bool process(resip::FdSet& fdset); + + virtual bool sendResponse(unsigned int requestId, const resip::Data& responseData, bool isFinal); + virtual void sendEvent(const resip::Data& eventData); + +private: + bool processSomeReads(); + bool processSomeWrites(); + bool tryParse(); // returns true if we processed something and there is more data in the buffer + + XmlRpcServerBase& mXmlRcpServer; + const unsigned int mConnectionId; + static unsigned int NextConnectionId; + + unsigned int mNextRequestId; + typedef std::map<unsigned int, resip::Data> RequestMap; + RequestMap mRequests; + + resip::Socket mSock; + resip::Data mRxBuffer; + resip::Data mTxBuffer; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/XmlRpcServerBase.cxx b/src/libs/resiprocate/repro/XmlRpcServerBase.cxx new file mode 100644 index 00000000..2bd59035 --- /dev/null +++ b/src/libs/resiprocate/repro/XmlRpcServerBase.cxx @@ -0,0 +1,446 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <cassert> + +#include <rutil/Data.hxx> +#include <rutil/Socket.hxx> +#include <resip/stack/Symbols.hxx> +#include <rutil/TransportType.hxx> +#include <rutil/Logger.hxx> +#include <resip/stack/Tuple.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/ParseBuffer.hxx> +#include <resip/stack/Transport.hxx> + +#include "repro/XmlRpcServerBase.hxx" +#include "repro/XmlRpcConnection.hxx" +#include <rutil/WinLeakCheck.hxx> + +using namespace repro; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + + +XmlRpcServerBase::XmlRpcServerBase(int port, IpVersion ipVer) : + mTuple(Data::Empty,port,ipVer,TCP,Data::Empty), + mSane(true) +{ +#ifdef USE_IPV6 + mFd = ::socket(ipVer == V4 ? PF_INET : PF_INET6, SOCK_STREAM, 0); +#else + mFd = ::socket(PF_INET, SOCK_STREAM, 0); +#endif + + if (mFd == INVALID_SOCKET) + { + int e = getErrno(); + logSocketError(e); + ErrLog(<< "XmlRpcServerBase::XmlRpcServerBase: Failed to create socket: " << strerror(e)); + mSane = false; + return; + } + + DebugLog (<< "XmlRpcServerBase::XmlRpcServerBase: Creating fd=" << (int)mFd + << (ipVer == V4 ? " V4/" : " V6/") ); + + int on = 1; +#if !defined(WIN32) + if (::setsockopt(mFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) +#else + if (::setsockopt(mFd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on))) +#endif + { + int e = getErrno(); + logSocketError(e); + ErrLog(<< "XmlRpcServerBase::XmlRpcServerBase: Couldn't set sockoptions SO_REUSEPORT | SO_REUSEADDR: " << strerror(e)); + mSane = false; + return; + } + + DebugLog(<< "XmlRpcServerBase::XmlRpcServerBase: Binding to " << Tuple::inet_ntop(mTuple)); + + if (::bind( mFd, &mTuple.getMutableSockaddr(), mTuple.length()) == SOCKET_ERROR) + { + int e = getErrno(); + logSocketError(e); + if (e == EADDRINUSE) + { + ErrLog(<< "XmlRpcServerBase::XmlRpcServerBase: " << mTuple << " already in use "); + } + else + { + ErrLog(<< "XmlRpcServerBase::XmlRpcServerBase: Could not bind to " << mTuple); + } + mSane = false; + return; + } + + bool ok = makeSocketNonBlocking(mFd); + if (!ok) + { + int e = getErrno(); + logSocketError(e); + ErrLog(<< "XmlRpcServerBase::XmlRpcServerBase: Could not make HTTP socket non-blocking " << port); + mSane = false; + return; + } + + // do the listen, seting the maximum queue size for compeletly established + // sockets -- on linux, tcp_max_syn_backlog should be used for the incomplete + // queue size(see man listen) + int e = listen(mFd,5); + + if (e != 0) + { + int e = getErrno(); + InfoLog(<< "XmlRpcServerBase::XmlRpcServerBase: Failed listen " << strerror(e)); + mSane = false; + return; + } +} + + +XmlRpcServerBase::~XmlRpcServerBase() +{ +#if defined(WIN32) + closesocket(mFd); +#else + close(mFd); +#endif + mFd = 0; + ConnectionMap::iterator it = mConnections.begin(); + for(; it != mConnections.end(); it++) + { + delete it->second; + } +} + + +void +XmlRpcServerBase::buildFdSet(FdSet& fdset) +{ + mSelectInterruptor.buildFdSet(fdset); + + fdset.setRead(mFd); // listen socket for server + + ConnectionMap::iterator it = mConnections.begin(); + for(; it != mConnections.end(); it++) + { + it->second->buildFdSet(fdset); + } +} + + +void +XmlRpcServerBase::process(FdSet& fdset) +{ + // Process Response fifo first + while (mResponseFifo.messageAvailable()) + { + ResponseInfo* responseInfo = mResponseFifo.getNext(); + if(responseInfo->getRequestId() == 0) + { + // This is an event and not a response - dispatch to appropriate connection or all connections + if(responseInfo->getConnectionId() == 0) + { + ConnectionMap::iterator it = mConnections.begin(); + for(; it != mConnections.end(); it++) + { + it->second->sendEvent(responseInfo->getResponseData()); + } + } + else + { + ConnectionMap::iterator it = mConnections.find(responseInfo->getConnectionId()); + if(it != mConnections.end()) + { + it->second->sendEvent(responseInfo->getResponseData()); + } + } + } + else + { + // This is a response to a request - dispatch to appropriate connection + ConnectionMap::iterator it = mConnections.find(responseInfo->getConnectionId()); + if(it != mConnections.end()) + { + it->second->sendResponse(responseInfo->getRequestId(), responseInfo->getResponseData(), responseInfo->getIsFinal()); + } + } + delete responseInfo; + } + + mSelectInterruptor.process(fdset); + + if (fdset.readyToRead(mFd)) + { + Tuple tuple(mTuple); + struct sockaddr& peer = tuple.getMutableSockaddr(); + socklen_t peerLen = tuple.length(); + Socket sock = accept( mFd, &peer, &peerLen); + if (sock == SOCKET_ERROR) + { + int e = getErrno(); + switch (e) + { + case EWOULDBLOCK: + return; + default: + logSocketError(e); + ErrLog(<< "XmlRpcServerBase::process: Some error reading from socket: " << e); + } + return; + } + makeSocketNonBlocking(sock); + + if(mConnections.size() == MaxConnections) + { + closeOldestConnection(); + } + + XmlRpcConnection* connection = new XmlRpcConnection(*this,sock); + mConnections[connection->getConnectionId()] = connection; + + DebugLog (<< "XmlRpcServerBase::process: Received TCP connection as connection=" << connection->getConnectionId() << " fd=" << (int)sock); + } + + // Call process on each connection + ConnectionMap::iterator it = mConnections.begin(); + for(; it != mConnections.end(); ) + { + bool ok = it->second->process(fdset); + if (!ok) + { + delete it->second; + mConnections.erase(it++); + } + else + { + it++; + } + } +} + +void +XmlRpcServerBase::sendResponse(unsigned int connectionId, + unsigned int requestId, + const Data& responseData, + bool isFinal) +{ + mResponseFifo.add(new ResponseInfo(connectionId, requestId, responseData, isFinal)); + mSelectInterruptor.interrupt(); +} + +void +XmlRpcServerBase::sendEvent(unsigned int connectionId, + const Data& eventData) +{ + mResponseFifo.add(new ResponseInfo(connectionId, 0 /* requestId */, eventData, true /* isFinal */)); + mSelectInterruptor.interrupt(); +} + +bool +XmlRpcServerBase::isSane() +{ + return mSane; +} + +void +XmlRpcServerBase::closeOldestConnection() +{ + if(mConnections.empty()) return; + + // Oldest Connection is the one with the lowest Id + ConnectionMap::iterator lowestConnectionIdIt = mConnections.end(); + ConnectionMap::iterator it = mConnections.begin(); + for(; it != mConnections.end(); it++) + { + if(it->second->getConnectionId() < lowestConnectionIdIt->second->getConnectionId()) + { + lowestConnectionIdIt = it; + } + } + delete lowestConnectionIdIt->second; + mConnections.erase(lowestConnectionIdIt); +} + +void +XmlRpcServerBase::logSocketError(int e) +{ + switch (e) + { + case EAGAIN: + InfoLog (<< "No data ready to read" << strerror(e)); + break; + case EINTR: + InfoLog (<< "The call was interrupted by a signal before any data was read : " << strerror(e)); + break; + case EIO: + InfoLog (<< "I/O error : " << strerror(e)); + break; + case EBADF: + InfoLog (<< "fd is not a valid file descriptor or is not open for reading : " << strerror(e)); + break; + case EINVAL: + InfoLog (<< "fd is attached to an object which is unsuitable for reading : " << strerror(e)); + break; + case EFAULT: + InfoLog (<< "buf is outside your accessible address space : " << strerror(e)); + break; + +#if defined(WIN32) + case WSAENETDOWN: + InfoLog (<<" The network subsystem has failed. "); + break; + case WSAEFAULT: + InfoLog (<<" The buf or from parameters are not part of the user address space, " + "or the fromlen parameter is too small to accommodate the peer address. "); + break; + case WSAEINTR: + InfoLog (<<" The (blocking) call was canceled through WSACancelBlockingCall. "); + break; + case WSAEINPROGRESS: + InfoLog (<<" A blocking Windows Sockets 1.1 call is in progress, or the " + "service provider is still processing a callback function. "); + break; + case WSAEINVAL: + InfoLog (<<" The socket has not been bound with bind, or an unknown flag was specified, " + "or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, " + "or (for byte stream-style sockets only) len was zero or negative. "); + break; + case WSAEISCONN : + InfoLog (<<"The socket is connected. This function is not permitted with a connected socket, " + "whether the socket is connection-oriented or connectionless. "); + break; + case WSAENETRESET: + InfoLog (<<" The connection has been broken due to the keep-alive activity " + "detecting a failure while the operation was in progress. "); + break; + case WSAENOTSOCK : + InfoLog (<<"The descriptor is not a socket. "); + break; + case WSAEOPNOTSUPP: + InfoLog (<<" MSG_OOB was specified, but the socket is not stream-style such as type " + "SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, " + "or the socket is unidirectional and supports only send operations. "); + break; + case WSAESHUTDOWN: + InfoLog (<<"The socket has been shut down; it is not possible to recvfrom on a socket after " + "shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH. "); + break; + case WSAEMSGSIZE: + InfoLog (<<" The message was too large to fit into the specified buffer and was truncated. "); + break; + case WSAETIMEDOUT: + InfoLog (<<" The connection has been dropped, because of a network failure or because the " + "system on the other end went down without notice. "); + break; + case WSAECONNRESET : + InfoLog (<<"Connection reset "); + break; + + case WSAEWOULDBLOCK: + DebugLog (<<"Would Block "); + break; + + case WSAEHOSTUNREACH: + InfoLog (<<"A socket operation was attempted to an unreachable host "); + break; + case WSANOTINITIALISED: + InfoLog (<<"Either the application has not called WSAStartup or WSAStartup failed. " + "The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks)," + "or WSACleanup has been called too many times. "); + break; + case WSAEACCES: + InfoLog (<<"An attempt was made to access a socket in a way forbidden by its access permissions "); + break; + case WSAENOBUFS: + InfoLog (<<"An operation on a socket could not be performed because the system lacked sufficient " + "buffer space or because a queue was full"); + break; + case WSAENOTCONN: + InfoLog (<<"A request to send or receive data was disallowed because the socket is not connected " + "and (when sending on a datagram socket using sendto) no address was supplied"); + break; + case WSAECONNABORTED: + InfoLog (<<"An established connection was aborted by the software in your host computer, possibly " + "due to a data transmission time-out or protocol error"); + break; + case WSAEADDRNOTAVAIL: + InfoLog (<<"The requested address is not valid in its context. This normally results from an attempt to " + "bind to an address that is not valid for the local computer"); + break; + case WSAEAFNOSUPPORT: + InfoLog (<<"An address incompatible with the requested protocol was used"); + break; + case WSAEDESTADDRREQ: + InfoLog (<<"A required address was omitted from an operation on a socket"); + break; + case WSAENETUNREACH: + InfoLog (<<"A socket operation was attempted to an unreachable network"); + break; + +#endif + + default: + InfoLog (<< "Some other error (" << e << "): " << strerror(e)); + break; + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/repro/XmlRpcServerBase.hxx b/src/libs/resiprocate/repro/XmlRpcServerBase.hxx new file mode 100644 index 00000000..8a6aa8e6 --- /dev/null +++ b/src/libs/resiprocate/repro/XmlRpcServerBase.hxx @@ -0,0 +1,144 @@ +#if !defined(XmlRpcServerBase_hxx) +#define XmlRpcServerBase_hxx + +#include <map> +#include <rutil/Data.hxx> +#include <rutil/Socket.hxx> +#include <rutil/TransportType.hxx> +#include <rutil/Fifo.hxx> +#include <resip/stack/Tuple.hxx> +#include <rutil/SelectInterruptor.hxx> + +/// This Class is used to implement a primitive form of RPC using loose XML formatting. +/// The XML formatting used is specific to this implementation and is NOT currently intended to +/// be compatible with the XML-RPC protocol defined by the following: http://www.xmlrpc.com/ + +namespace repro +{ +class XmlRpcConnection; + +class ResponseInfo +{ +public: + ResponseInfo(unsigned int connectionId, + unsigned int requestId, + const resip::Data& responseData, + bool isFinal) : + mConnectionId(connectionId), + mRequestId(requestId), + mResponseData(responseData), + mIsFinal(isFinal) {} + + ~ResponseInfo() {} + + unsigned int getConnectionId() const { return mConnectionId; } + unsigned int getRequestId() const { return mRequestId; } + const resip::Data& getResponseData() const { return mResponseData; } + bool getIsFinal() const { return mIsFinal; } + +private: + unsigned int mConnectionId; + unsigned int mRequestId; + resip::Data mResponseData; + bool mIsFinal; +}; + +class XmlRpcServerBase +{ + friend class XmlRpcConnection; + +public: + XmlRpcServerBase(int port, resip::IpVersion version); + virtual ~XmlRpcServerBase(); + + void buildFdSet(resip::FdSet& fdset); + void process(resip::FdSet& fdset); + + bool isSane(); + static void logSocketError(int e); + + // thread safe - uses fifo + void sendResponse(unsigned int connectionId, + unsigned int requestId, + const resip::Data& responseData, + bool isFinal=true); + + // thread safe - uses fifo (use connectionId == 0 to send to all connections) + void sendEvent(unsigned int connectionId, + const resip::Data& eventData); + +protected: + virtual void handleRequest(unsigned int connectionId, + unsigned int requestId, + const resip::Data& request) = 0; + +private: + static const unsigned int MaxConnections = 60; // Note: use caution if making this any bigger, default fd_set size in windows is 64 + + resip::Socket mFd; + resip::Tuple mTuple; + bool mSane; + + typedef std::map<unsigned int, XmlRpcConnection*> ConnectionMap; + ConnectionMap mConnections; + void closeOldestConnection(); + + resip::Fifo<ResponseInfo> mResponseFifo; + resip::SelectInterruptor mSelectInterruptor; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/repro/accountingconsumers/Makefile.am b/src/libs/resiprocate/repro/accountingconsumers/Makefile.am new file mode 100644 index 00000000..91410675 --- /dev/null +++ b/src/libs/resiprocate/repro/accountingconsumers/Makefile.am @@ -0,0 +1,63 @@ +# $Id$ + +EXTRA_DIST = *.vcxproj *.vcxproj.filters +EXTRA_DIST += *.vcproj + +#AM_CXXFLAGS = -DUSE_ARES + +sbin_PROGRAMS = queuetostream +queuetostream_SOURCES = queuetostream.cpp +queuetostream_LDADD = ../librepro.la +queuetostream_LDADD += ../../resip/dum/libdum.la +queuetostream_LDADD += ../../resip/stack/libresip.la ../../rutil/librutil.la +queuetostream_LDADD += @LIBSSL_LIBADD@ -lpthread + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# <http://www.vovida.org/>. +# +############################################################################## diff --git a/src/libs/resiprocate/repro/accountingconsumers/queuetostream.cpp b/src/libs/resiprocate/repro/accountingconsumers/queuetostream.cpp new file mode 100644 index 00000000..d9e54ae8 --- /dev/null +++ b/src/libs/resiprocate/repro/accountingconsumers/queuetostream.cpp @@ -0,0 +1,160 @@ +#include <signal.h> + +#include "repro/PersistentMessageQueue.hxx" +#include <rutil/Logger.hxx> +#include <rutil/WinLeakCheck.hxx> + +using namespace resip; +using namespace std; +using namespace repro; + +static bool finished = false; + +static void +signalHandler(int signo) +{ + std::cerr << "Shutting down" << endl; + finished = true; +} + +void sleepSeconds(unsigned int seconds) +{ +#ifdef WIN32 + Sleep(seconds*1000); +#else + sleep(seconds); +#endif +} + +int +main (int argc, char** argv) +{ + // Install signal handlers +#ifndef _WIN32 + if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR) + { + cerr << "Couldn't install signal handler for SIGPIPE" << endl; + exit(-1); + } +#endif + + if ( signal( SIGINT, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGINT" << endl; + exit( -1 ); + } + + if ( signal( SIGTERM, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGTERM" << endl; + exit( -1 ); + } + + // Log any resip logs to cerr, since session events are logged to cout + Log::initialize(Log::Cerr, Log::Info, ""); + + Data msgQueueName("sessioneventqueue"); + if(argc >= 2) + { + msgQueueName = argv[1]; + } + PersistentMessageDequeue* queue = new PersistentMessageDequeue(""); + if(queue->init(true, msgQueueName)) + { + vector<resip::Data> recs; + while(!finished) + { + if(queue->pop(5, recs, true)) + { + if(recs.size() > 0) + { + for(size_t i = 0; i < recs.size(); i++) + { + cout << recs[i] << endl; + } + } + else + { + sleepSeconds(1); + } + } + else + { + if(queue->isRecoveryNeeded()) + { + delete queue; + queue = new PersistentMessageDequeue(""); + if(!queue->init(true, msgQueueName)) + { + cerr << "Error initializing message queue after error!" << endl; + break; + } + } + else + { + cerr << "Error dequeuing!" << endl; + break; + } + } + } + } + else + { + cerr << "Error initializing message queue!" << endl; + } + delete queue; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2012 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ +/* + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/repro/accountingconsumers/queuetostream_10_0.vcxproj b/src/libs/resiprocate/repro/accountingconsumers/queuetostream_10_0.vcxproj new file mode 100644 index 00000000..10c3fd54 --- /dev/null +++ b/src/libs/resiprocate/repro/accountingconsumers/queuetostream_10_0.vcxproj @@ -0,0 +1,218 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|Win32"> + <Configuration>SSL-Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|Win32"> + <Configuration>SSL-Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>queuetostream</ProjectName> + <ProjectGuid>{02C11EC5-9AB9-44F1-9B60-B719C1728356}</ProjectGuid> + <RootNamespace>queuetostream</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">false</LinkIncremental> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../../;$(ProjectDir)../../contrib/db/build_windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)queuetostream.exe</OutputFile> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)queuetostream.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> + <AdditionalIncludeDirectories>$(ProjectDir)../../;$(ProjectDir)../../contrib/db/build_windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)queuetostream.exe</OutputFile> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <ClCompile> + <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../../;$(ProjectDir)../../contrib/db/build_windows;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;USE_SSL;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;Dnsapi.lib;Iphlpapi.lib;winmm.lib;crypt32.lib;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\libeay32MDd.lib;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\ssleay32MDd.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)queuetostream.exe</OutputFile> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)queuetostream.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <ClCompile> + <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> + <AdditionalIncludeDirectories>$(ProjectDir)../../;$(ProjectDir)../../contrib/db/build_windows;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;USE_SSL;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;Dnsapi.lib;Iphlpapi.lib;winmm.lib;crypt32.lib;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\libeay32MD.lib;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\ssleay32MD.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)queuetostream.exe</OutputFile> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="queuetostream.cpp" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\contrib\db\build_windows\db_static_10_0.vcxproj"> + <Project>{9e5a7645-1502-4467-91f8-bcf2eb06ef72}</Project> + </ProjectReference> + <ProjectReference Include="..\..\rutil\rutil_10_0.vcxproj"> + <Project>{3d0e5ceb-93dc-4fdb-918b-d08fa369e106}</Project> + </ProjectReference> + <ProjectReference Include="..\reprolib_10_0.vcxproj"> + <Project>{31b0654f-e08e-405f-909f-80f86cb14b9e}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/repro/accountingconsumers/queuetostream_10_0.vcxproj.filters b/src/libs/resiprocate/repro/accountingconsumers/queuetostream_10_0.vcxproj.filters new file mode 100644 index 00000000..9706cfde --- /dev/null +++ b/src/libs/resiprocate/repro/accountingconsumers/queuetostream_10_0.vcxproj.filters @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="queuetostream.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/repro/accountingconsumers/queuetostream_9_0.vcproj b/src/libs/resiprocate/repro/accountingconsumers/queuetostream_9_0.vcproj new file mode 100644 index 00000000..9fa0df8e --- /dev/null +++ b/src/libs/resiprocate/repro/accountingconsumers/queuetostream_9_0.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="queuetostream" + ProjectGUID="{02C11EC5-9AB9-44F1-9B60-B719C1728356}" + RootNamespace="queuetostream" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../contrib/db/build_windows&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_IPV6;LEAK_CHECK" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Iphlpapi.lib winmm.lib Dnsapi.lib" + OutputFile="$(OutDir)/queuetostream.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/queuetostream.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../contrib/db/build_windows&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_IPV6" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Iphlpapi.lib winmm.lib Dnsapi.lib" + OutputFile="$(OutDir)/queuetostream.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../contrib/db/build_windows&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_SSL;USE_IPV6;LEAK_CHECK" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib Iphlpapi.lib winmm.lib crypt32.lib &quot;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\libeay32MDd.lib&quot; &quot;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\ssleay32MDd.lib&quot;" + OutputFile="$(OutDir)/queuetostream.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/queuetostream.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../contrib/db/build_windows&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_SSL;USE_IPV6" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib Iphlpapi.lib winmm.lib crypt32.lib &quot;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\libeay32MD.lib&quot; &quot;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\ssleay32MD.lib&quot;" + OutputFile="$(OutDir)/queuetostream.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\queuetostream.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/repro/addUser.html b/src/libs/resiprocate/repro/addUser.html new file mode 100644 index 00000000..fcb60e58 --- /dev/null +++ b/src/libs/resiprocate/repro/addUser.html @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + + <head> + <meta http-equiv="content-type" content="text/html;charset=utf-8" /> + <title>Repo Proxy</title> + </head> + + <body bgcolor="#ffffff"> + <table width="100%" border="0" cellspacing="2" cellpadding="0" align="left"> + <tr> + <td> + <h1>Repro Proxy</h1> + </td> + </tr> + <tr> + <td> + <table width="95%" border="0" cellspacing="2" cellpadding="0"> + <tr> + <td> + <table border="0" cellspacing="2" cellpadding="0"> + <tr> + <td> + <h3>Add User</h3> + </td> + </tr> + <tr> + <td> + <h3>Users</h3> + </td> + </tr> + <tr> + <td> + <h3>Config</h3> + </td> + </tr> + <tr> + <td> + <h3>Stats</h3> + </td> + </tr> + </table> + </td> + <td align="left" valign="top" width="85%"> + <form id="addUserForm" action="" method="get" name="addUserForm" enctype="application/x-www-form-urlencoded"> + <table width="90%" border="0" cellspacing="2" cellpadding="0"> + <tr> + <td align="right" valign="middle" width="30%">User Name:</td> + <td align="left" valign="middle"><input type="text" name="user" size="24"/></td> + </tr> + <tr> + <td align="right" valign="middle" width="30%">Password:</td> + <td align="left" valign="middle"><input type="password" name="password" size="24"/></td> + </tr> + <tr> + <td align="right" valign="middle" width="30%">Full Name:</td> + <td align="left" valign="middle"><input type="text" name="name" size="24"/></td> + </tr> + <tr> + <td align="right" valign="middle" width="30%">Email:</td> + <td align="left" valign="middle"><input type="text" name="email" size="24"/></td> + </tr> + </table> + <input type="reset" value="Reset"/> + <input type="submit" name="submit" value="OK"/> + </form> + </td> + </tr> + </table> + </td> + </tr> + </table> + </body> + +</html> diff --git a/src/libs/resiprocate/repro/create_mysql_reprodb.sql b/src/libs/resiprocate/repro/create_mysql_reprodb.sql new file mode 100644 index 00000000..6dab272a --- /dev/null +++ b/src/libs/resiprocate/repro/create_mysql_reprodb.sql @@ -0,0 +1,104 @@ + +-- execute statements like those below to create the empty +-- database. It is also necessary to create the repro +-- user and grant the necessary privileges +-- CREATE DATABASE repro; +-- USE repro; + +-- Uncomment the following to have all tables re-created +-- DROP TABLE IF EXISTS `users`; +-- DROP TABLE IF EXISTS `routesavp`; +-- DROP TABLE IF EXISTS `aclsavp`; +-- DROP TABLE IF EXISTS `configsavp`; +-- DROP TABLE IF EXISTS `staticregsavp`; +-- DROP TABLE IF EXISTS `filtersavp`; +-- DROP TABLE IF EXISTS `siloavp`; + + +-- +-- Table structure for table `users` +-- +CREATE TABLE IF NOT EXISTS `users` ( + `id` INT PRIMARY KEY AUTO_INCREMENT, + `user` VARCHAR(64) NOT NULL, + `domain` VARCHAR(253), + `realm` VARCHAR(253), + `passwordHash` VARCHAR(32), + `passwordHashAlt` VARCHAR(32), + `name` VARCHAR(256), + `email` VARCHAR(256), + `forwardAddress` VARCHAR(256), + CONSTRAINT c_user_domain UNIQUE INDEX idx_user_domain (`user`, `domain`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Upgrade from version 2 schema to version 3 +ALTER TABLE `users` + ADD COLUMN `id` INT NULL AUTO_INCREMENT FIRST , + ADD COLUMN `passwordHashAlt` VARCHAR(32) NULL DEFAULT NULL AFTER `passwordHash` , + CHANGE COLUMN `domain` `domain` VARCHAR(253) NULL DEFAULT NULL +, DROP PRIMARY KEY +, ADD PRIMARY KEY (`id`) +, ADD UNIQUE INDEX `idx_user_domain` (`user` ASC, `domain` ASC) ; + +-- +-- Table structure for table `routesavp` +-- + +CREATE TABLE IF NOT EXISTS `routesavp` ( + `attr` VARCHAR(255) NOT NULL, + `value` VARCHAR(4096), + PRIMARY KEY (`attr`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `aclsavp` +-- + +CREATE TABLE IF NOT EXISTS `aclsavp` ( + `attr` VARCHAR(255) NOT NULL, + `value` VARCHAR(4096), + PRIMARY KEY (`attr`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `configsavp` +-- + +CREATE TABLE IF NOT EXISTS `configsavp` ( + `attr` VARCHAR(255) NOT NULL, + `value` VARCHAR(4096), + PRIMARY KEY (`attr`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `staticregsavp` +-- + +CREATE TABLE IF NOT EXISTS `staticregsavp` ( + `attr` VARCHAR(255) NOT NULL, + `value` VARCHAR(4096), + PRIMARY KEY (`attr`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `filtersavp` +-- + +CREATE TABLE IF NOT EXISTS `filtersavp` ( + `attr` VARCHAR(255) NOT NULL, + `value` VARCHAR(4096), + PRIMARY KEY (`attr`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `siloavp` +-- Note: This table contains 2 indexes +-- + +CREATE TABLE IF NOT EXISTS `siloavp` ( + `attr` VARCHAR(255) NOT NULL, + `attr2` VARCHAR(255) NOT NULL, + `value` VARCHAR(20315), + PRIMARY KEY (`attr`), + KEY `SECONDARY` (`attr2`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/src/libs/resiprocate/repro/debian/README b/src/libs/resiprocate/repro/debian/README new file mode 100644 index 00000000..a11b55d2 --- /dev/null +++ b/src/libs/resiprocate/repro/debian/README @@ -0,0 +1,10 @@ +This directory contains the files necessary for building a +Debian package for repro. Currently, we are building a single +package containing a statically linked version of repro. This +will change in the future with extra packages for resip, repro, +etc. + +In order to make this work, you have to copy the debian directory +one level up, ie., from ./repro/debian to ./debian and then run +dpk-buildpackage in that directory. You may also use the source +package available from <http://www.sipfoundry.org/pub/repro/>. diff --git a/src/libs/resiprocate/repro/debian/changelog b/src/libs/resiprocate/repro/debian/changelog new file mode 100644 index 00000000..f73de501 --- /dev/null +++ b/src/libs/resiprocate/repro/debian/changelog @@ -0,0 +1,6 @@ +repro (0.2-0) unstable; urgency=low + + * initial release + + -- Martin Hoffmann <hn@nvnc.de> Fri, 18 Feb 2006 17:03:22 +0100 + diff --git a/src/libs/resiprocate/repro/debian/conffiles b/src/libs/resiprocate/repro/debian/conffiles new file mode 100644 index 00000000..ce502127 --- /dev/null +++ b/src/libs/resiprocate/repro/debian/conffiles @@ -0,0 +1 @@ +/etc/repro.conf diff --git a/src/libs/resiprocate/repro/debian/control b/src/libs/resiprocate/repro/debian/control new file mode 100644 index 00000000..c92e001b --- /dev/null +++ b/src/libs/resiprocate/repro/debian/control @@ -0,0 +1,17 @@ +Source: repro +Section: net +Priority: optional +Maintainer: Martin Hoffmann <hn@nvnc.de> +Build-Depends: debhelper (>= 4.1), dpatch, libpopt-dev, libssl-dev, libdb4.4++-dev, libboost-dev, libboost-regex-dev +Standards-Version: 3.6.2 + +Package: repro +Architecture: any +Depends: ${shlibs:Depends} +Description: Repro SIP proxy + The repro SIP server provides SIP proxy, registrar, redirect and identity + services. It can be used as the central rendezvous service for peer-to-peer + voice, IM, and presence services, as the core of large scale internet + telephony services, and as a tool to enforce policy at the boundary between + networks or domains. + diff --git a/src/libs/resiprocate/repro/debian/copyright b/src/libs/resiprocate/repro/debian/copyright new file mode 100644 index 00000000..d89d18ac --- /dev/null +++ b/src/libs/resiprocate/repro/debian/copyright @@ -0,0 +1,60 @@ +This package was debianized by Josip Rodin <joy-mg@debian.org> on +Wed, 11 Nov 1998 21:02:14 +0100. + +It was downloaded from: https://scm.sipfoundry.org/rep/resiprocate/main + +Upstream Authors: + <Add authors and their mail-addresses here< + +Copyright: + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/repro/debian/dirs b/src/libs/resiprocate/repro/debian/dirs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/src/libs/resiprocate/repro/debian/dirs @@ -0,0 +1 @@ + diff --git a/src/libs/resiprocate/repro/debian/init.d b/src/libs/resiprocate/repro/debian/init.d new file mode 100644 index 00000000..7bd87dea --- /dev/null +++ b/src/libs/resiprocate/repro/debian/init.d @@ -0,0 +1,89 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: repro +# Required-Start: $local_fs $remote_fs +# Required-Stop: $local_fs $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: S 0 1 6 +# Short-Description: Repro initscript +### END INIT INFO +# +# Author: Martin Hoffmann <hn@nvnc.de> +# +# Version: @(#)repro 0.2 18-Feb-2006 hn@nvnc.de +# + +set -e + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +DESC="Repro SIP Proxy" +NAME=repro +DAEMON=/usr/sbin/$NAME +PIDFILE=/var/run/$NAME.pid +SCRIPTNAME=/etc/init.d/$NAME +RUNDIR=/var/lib/$NAME +RUNUSER=repro:repro + +# Gracefully exit if the package has been removed. +test -x $DAEMON || exit 0 + +# Read config file if it is present. +#if [ -r /etc/default/$NAME ] +#then +# . /etc/default/$NAME +#fi + +# +# Function that starts the daemon/service. +# +d_start() { + CMDARGS=`sed s/#.*// /etc/repro.conf` + start-stop-daemon --start --quiet --pidfile $PIDFILE --background \ + --make-pidfile --chuid $RUNUSER --chdir $RUNDIR \ + --exec $DAEMON -- $CMDARGS \ + || echo -n " already running" +} + +# +# Function that stops the daemon/service. +# +d_stop() { + start-stop-daemon --stop --quiet --pidfile $PIDFILE \ + --name $NAME \ + || echo -n " not running" +} + +# +# Function that sends a SIGHUP to the daemon/service. +# +d_reload() { + start-stop-daemon --stop --quiet --pidfile $PIDFILE \ + --name $NAME --signal 1 +} + +case "$1" in + start) + echo -n "Starting $DESC: $NAME" + d_start + echo "." + ;; + stop) + echo -n "Stopping $DESC: $NAME" + d_stop + echo "." + ;; + restart|force-reload) + echo -n "Restarting $DESC: $NAME" + d_stop + sleep 1 + d_start + echo "." + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 + diff --git a/src/libs/resiprocate/repro/debian/postinst b/src/libs/resiprocate/repro/debian/postinst new file mode 100644 index 00000000..aa3c8115 --- /dev/null +++ b/src/libs/resiprocate/repro/debian/postinst @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e + +add_user_if_missing() { + if [ -x /usr/sbin/adduser ]; then + if ! id -u repro > /dev/null 2>&1; then + adduser --system --group --home /var/lib/repro \ + --no-create-home --disabled-password \ + --shell /bin/false \ + repro + fi + fi + if [ ! -e /var/lib/repro ]; then + mkdir /var/lib/repro + chown repro:repro /var/lib/repro + fi +} +link_down_docs() { + if [ -d /usr/doc -a ! -e /usr/doc/repro -a -d /usr/share/doc/repro ] + then + ln -sf ../share/doc/repro /usr/doc/repro + fi +} + +case "$1" in + configure) + add_user_if_missing + #link_down_docs + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \'$1\'" >&2 + exit 1 + ;; +esac + +if [ -x "/etc/init.d/repro" ]; then + update-rc.d repro defaults 23 > /dev/null + if ! invoke-rc.d repro restart ; then + echo "" + echo "Repro failed to (re)start." + fi +fi + +exit 0 diff --git a/src/libs/resiprocate/repro/debian/rules b/src/libs/resiprocate/repro/debian/rules new file mode 100644 index 00000000..40188eff --- /dev/null +++ b/src/libs/resiprocate/repro/debian/rules @@ -0,0 +1,79 @@ +#!/usr/bin/make -f +# +# based on the sample debian/rules file for debhelper + +# get dpatch +include /usr/share/dpatch/dpatch.make + +# Uncomment this to turn on verbose mode +#export DH_VERBOSE=1 + +build: build-stamp +build-stamp: patch + dh_testdir + + $(CURDIR)/configure -y --with-toolchain=gnu --with-compile-type=debug --with-cross-compiler-dir="" --disable-shared-libs --disable-distcc --disable-dtls --enable-ssl --enable-popt --disable-curl --disable-google-malloc --disable-google-cpuperf --disable-ipv6 --prefix="/usr" + $(MAKE) all + + touch build-stamp + +clean: clean-patched unpatch +clean-patched: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + -$(MAKE) clean + -$(MAKE) distclean + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/<packagename> + $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install-repro + install -D $(CURDIR)/repro/doc/repro.8 $(CURDIR)/debian/tmp/usr/share/man/man8/repro.8 + install -D $(CURDIR)/repro/etc/repro.conf $(CURDIR)/debian/tmp/etc/repro.conf + gzip $(CURDIR)/debian/tmp/usr/share/man/man8/repro.8 + + dh_install + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples + dh_install +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installcatalogs +# dh_installpam +# dh_installmime + dh_installinit +# dh_installcron +# dh_installinfo +# dh_undocumented + dh_installman + dh_link +# dh_strip + dh_compress + dh_fixperms +# dh_perl +# dh_python +# dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/src/libs/resiprocate/repro/doc/repro-addRoute.png b/src/libs/resiprocate/repro/doc/repro-addRoute.png new file mode 100644 index 00000000..0b79a698 Binary files /dev/null and b/src/libs/resiprocate/repro/doc/repro-addRoute.png differ diff --git a/src/libs/resiprocate/repro/doc/repro-addUser.png b/src/libs/resiprocate/repro/doc/repro-addUser.png new file mode 100644 index 00000000..10f940b9 Binary files /dev/null and b/src/libs/resiprocate/repro/doc/repro-addUser.png differ diff --git a/src/libs/resiprocate/repro/doc/repro-domains.png b/src/libs/resiprocate/repro/doc/repro-domains.png new file mode 100644 index 00000000..cbf8c635 Binary files /dev/null and b/src/libs/resiprocate/repro/doc/repro-domains.png differ diff --git a/src/libs/resiprocate/repro/doc/repro-login.png b/src/libs/resiprocate/repro/doc/repro-login.png new file mode 100644 index 00000000..86988c1d Binary files /dev/null and b/src/libs/resiprocate/repro/doc/repro-login.png differ diff --git a/src/libs/resiprocate/repro/doc/repro-showRoutes.png b/src/libs/resiprocate/repro/doc/repro-showRoutes.png new file mode 100644 index 00000000..70e1e183 Binary files /dev/null and b/src/libs/resiprocate/repro/doc/repro-showRoutes.png differ diff --git a/src/libs/resiprocate/repro/doc/repro-showUsers.png b/src/libs/resiprocate/repro/doc/repro-showUsers.png new file mode 100644 index 00000000..377ac60e Binary files /dev/null and b/src/libs/resiprocate/repro/doc/repro-showUsers.png differ diff --git a/src/libs/resiprocate/repro/doc/repro.8 b/src/libs/resiprocate/repro/doc/repro.8 new file mode 100644 index 00000000..7a5c34ed --- /dev/null +++ b/src/libs/resiprocate/repro/doc/repro.8 @@ -0,0 +1,226 @@ +.TH repro 8 "February 2006" +.\" ==================================================================== +.\" The Vovida Software License, Version 1.0 +.\" +.\" Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. The names "VOCAL", "Vovida Open Communication Application Library", +.\" and "Vovida Open Communication Application Library (VOCAL)" must +.\" not be used to endorse or promote products derived from this +.\" software without prior written permission. For written +.\" permission, please contact vocal@vovida.org. +.\" +.\" 4. Products derived from this software may not be called "VOCAL", nor +.\" may "VOCAL" appear in their name, without prior written +.\" permission of Vovida Networks, Inc. +.\" +.\" THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +.\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +.\" NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +.\" NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +.\" IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +.\" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +.\" OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +.\" USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +.\" DAMAGE. +.\" +.\" ==================================================================== +.\" +.\" This software consists of voluntary contributions made by Vovida +.\" Networks, Inc. and many individuals on behalf of Vovida Networks, +.\" Inc. For more information on Vovida Networks, Inc., please see +.\" <http://www.vovida.org/>. +.\" +.\" +.SH NAME +repro \- repro SIP proxy server +.SH SYNOPSIS +.B +repro [OPTIONS...] + +.SH DESCRIPTION +.B repro +is an open-source, free SIP server. SIP is changing the way people communicate +using the Internet. It is not only about making phone calls over the Net. The +SIP protocol and its extensions defines the way of establishing, modifying and +ending interactive sessions, no matter if they are voice, video, IM or a +combination of them. At the heart of SIP architecture, there are certain +services which needs to be provided at some place of the network. +.B repro +provides SIP proxy, registrar, redirect, and identity services. These services +are the foundation needed to run a SIP service. + +.SH OPTIONS +.TP +\fB\-l\fR, \fB\-\-log\-type\fR=\fBcout\fR|\fBsyslog\fR|\fBcerr\fR +Set where to send logging messages. The default \fBcout\fR sends the +messages to standard output, \fBcerr\fR uses the standard error pipe. +With \fBsyslog\fR the messages are send to the system log using the logging +facility \fBlocal6\fR. See +.BR syslogd (8) +or +.BR syslog.conf (5) +for more information. +.TP +\fB\-v\fR, \fB\-\-log\-level\fR=\fBSTACK\fR|\fBDEBUG\fR|\fBINFO\fR|\fBWARNING\fR|\fBALERT\fR +Set the minimum level a logging message needs to have in order to by +written. The severity rises from left to right in the above order. The +default is to log messages with level \fBINFO\fR or above. +.TP +\fB\-r\fR, \fB\-\-record\-route\fR=\fIsip:example.com\fR +Activate record routing. The argument is the URI used in the Record-Route +header field. +.TP +\fB\-\-udp\fR=\fI5060\fR +Specify the port to use for the UDP transport. Set to 0 to turn +UDP off. Defaults to port 5060. +.TP +\fB\-\-tcp\fR=\fI5060\fR +Specify the port to use for the TCP transport. Set to 0 to turn TCP +off. Defaults to port 5060. +.TP +\fB\-t\fR, \fB\-\-tls\-domain\fR=\fIexample.com\fR +Act as a TLS server for specified domain. +.TP +\fB\-\-tls\fR=\fI5061\fR +Set the port to use for the TLS transport. Set to 0 to turn TLS off. +Defaults to port 5061. +.TP +\fB\-\-dtls\fR=\fI0\fR +Set the port to use for the DTLS transport. Set to 0 to turn DTLS off +which is the default. +.TP +\fB\-\-enable\-cert\-server +Run a cert server. +.TP +\fB\-c\fR, \fB\-\-cert\-path\fR=\fISTRING\fR +Set the path for certificates. Defaults to \fB~/.sipCerts\fR. +.TP +\fB\-\-enable\-v6\fR +Enable IPv6. +.TP +\fB\-\-disable\-v4\fR +Disable IPv4. +.TP +\fB\-\-disable\-auth\fR +Disable DIGEST challenges for certain SIP requests. +.TP +\fB\-\-disable\-web\-auth\fR +Disable authentication for the web administration server. +.TP +\fB\-\-disable\-reg\fR +Disable the registrar. +.TP +\fB\-i\fR, \fB\-\-interfaces\fR=\fIsip:10.1.1.1:5065;transport=tls\fR +Specify interfaces to add transports to. Each transport is given as a +SIP-URI with the IP address and port of the local interface as the +hostport part and the transport protocol as a \fBtransport\fR parameter. +Several transports are separated by a comma. + +For example, to set up two transports, one for TLS and one for UDP use +.B sip:192.168.1.200:5060;transport=tls,sip:192.168.1.200:5060;transport=udp +.TP +\fB\-d\fR, \fB\-\-domains\fR=\fIexample.com,foo.com\fR +Specify the list of domains this proxy is authorative for separated by +comma. +.TP +\fB\-R\fR, \fB\-\-route\fR=\fIsip:p1.example.com,sip:p2.example.com\fR +Specify a route set where all requests this proxy is authorative for are +sent to. Using this option overides the routes set through the web +interface. +.TP +\fB\-\-reqChainName\fR=\fISTRING\fR +Name of request chain used for processing requests. Currently, the only +chain available is \fBdefault\fR. +.TP +\fB\-\-http\fR=\fI5080\fR +Specify the port used by the HTTP server. Defaults to 5080. +.TP +\fB\-\-recursive\-redirect\fR +Enable to handle of 3xx responses in the proxy. +.TP +\fB\-\-q\-value\fR +Enable q-value processing. The q-value can be given in registrations and is +used by the location server to order forwarding for multiple registrations. +Without this option a request is forked to all registrations. +.TP +\fB\-\-q\-value\-behavior\fR=\fBFULL_SEQUENTIAL\fR|\fBEQUAL_Q_PARALLEL\fR|\fBFULL_PARALLEL\fR +Specify forking behavior if \fB\-\-q\-value\fR is given. +With \fBFULL_SEQUENTIAL\fR one target is called after another in the order +of their q values. Using \fBEQUAL_Q_PARALLEL\fR (the default), the request +is sent in +batches of all registrations with the same q value. The batches are again +ordered by the q value. +\fBFULL_PARALLEL\fR causes the request to be sent in parallel to all +registrations. +.TP +\fB\-\-q\-value\-cancel\-btw\-fork\-groups\fR +If given, groups of parallel forks are canceled after the period specified +by the \fB\-\-q\-value\-ms\-before\-cancel\fR option if no response was +received. +.TP +\fB\-\-q\-value\-wait\-for\-terminate\-btw\-fork\-groups\fR +If given, the proxy waits for groups of parallel forks to terminate before +a new group is started. Otherwise, the next group is started once the +waiting time has passed. +.TP +\fB\-\-q\-value\-ms\-between\-fork\-groups\fR=\fIINT\fR +Specify the number of milliseconds to wait for a response from a group of +parallel forks before starting another group. +.TP +\fB\-\-q\-value\-ms\-before\-cancel\fR=\fIINT\fR +Specify the number of milliseconds to wait before cancelling a group of +parallel forks if the \fB\-\-q\-value\-cancel\-btw\-fork\-groups\fR option +is given. +.TP +\fB\-e\fR, \fB\-\-enum\-suffix\fR=\fIe164.arpa\fR +Specify enum suffix to search. +.TP +\fB\-b\fR, \fB\-\-allow\-bad\-reg\fR +Allow To tag in registrations. +.TP +\fB\-\-timer\-C\fR=\fI180\fR +Specify the length of timer C in sec which specifies the time a proxy +waits before generating a timeout response. Set to 0 or a negative value +to turn timer C of completely. +.TP +\fB\-\-admin\-password\fR=\fISTRING\fR +Set the web administrator password. +.PP +Help options: +.TP +\fB\-?\fR, \fB\-\-help\fR +Show a help message. +.TP +\fB\-\-usage +Display brief usage message. +.TP +\fB\-\-version\fR +Display the version information. + +.SH SEE ALSO +Repro web site at +.B http://www.sipfoundry.org/repro/ + +.\".SH AUTHORS + +.\".SH BUGS + + + diff --git a/src/libs/resiprocate/repro/doc/reprocmd.8 b/src/libs/resiprocate/repro/doc/reprocmd.8 new file mode 100644 index 00000000..c3e33866 --- /dev/null +++ b/src/libs/resiprocate/repro/doc/reprocmd.8 @@ -0,0 +1,58 @@ +.TH reprocmd 8 "May 2012" +.\" ==================================================================== +.\" Copyright 2012 Daniel Pocock. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" 3. Neither the name of the author(s) nor the names of any contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" ==================================================================== +.\" +.\" +.\" +.SH NAME +reprocmd \- control the repro SIP proxy server +.SH SYNOPSIS +.B +reprocmd [OPTIONS...] + +.SH DESCRIPTION +.B reprocmd +controls the +.B repro +SIP proxy server. + +.SH SEE ALSO +Repro web site at +.B http://www.resiprocate.org/About_Repro/ + +.\".SH AUTHORS + +.\".SH BUGS + + + diff --git a/src/libs/resiprocate/repro/etc/init.d/repro b/src/libs/resiprocate/repro/etc/init.d/repro new file mode 100644 index 00000000..0643a756 --- /dev/null +++ b/src/libs/resiprocate/repro/etc/init.d/repro @@ -0,0 +1,142 @@ +#!/bin/sh +# +# chkconfig: 35 90 10 +# description: This script starts up the repro processes. +# +# processname: repro +# pidfile: @REPRO_RUNDIR@/repro.pid +# +# Copyright (C) 2006 SIPfoundry Inc. +# Licensed by SIPfoundry under the Vovida +# +# Copyright (C) 2004 Pingtel Corp. +# Licensed to SIPfoundry under a Contributor Agreement. +# + +# This is an interactive program; we need the current locale. +[ -f /etc/profile.d/lang.sh ] && . /etc/profile.d/lang.sh + +if [ "$LANG" = "ja" -o "$LANG" = "ja_JP.eucJP" ]; then + # We can't Japanese on normal console at boot time. + # So, force to set LANG=C + if [ "$TERM" = "linux" ] ; then + LANG=C + fi +fi + +## Source function library. + +# Set up correctly depending on the distribution +if [ ! -f /etc/redhat-release ] +then + # Non-Redhat (Gentoo, Debian, and perhaps others) + echo_success() + { + echo success + } + echo_failure() + { + echo failure + } + . /etc/init.d/functions.sh + +else + # Redhat + . /etc/init.d/functions +fi + +## allow core files +ulimit -c unlimited + +pidfile=@REPRO_RUNDIR@/repro.pid + +# See how we were called. +case "$1" in + ## this is called from start below to get the pid in the background process + doit) + echo $$ > $pidfile + cmdargs=`sed 's/#.*//' @REPRO_CONFDIR@/repro.conf` + cd @REPRO_CWD@ || exit 1 + exec @bindir@/repro ${cmdargs} + ;; + + start) + ### Verify that repro is not already running. + if [ -e $pidfile ] + then + echo " Found ${pidfile} - checking for running repro process" + running=`cat ${pidfile} 2> /dev/null` + if [ -n "$running" -a -e /proc/$running ] + then + echo -n " repro may already be running. Try stop or restart." + echo_failure + echo + else + # stale pid file found? - do stop just in case + echo " repro not found - running restart." + $0 restart + fi + else + iam=`whoami` + if [ $iam = @REPROUSER@ ] + then + ( $0 doit ) < /dev/null & + elif [ $iam = root ] + then + su @REPROUSER@ -c "$0 doit" < /dev/null & + else + echo "You must be able to start as @REPROUSER@" 1>&2 + echo_failure + exit 1 + fi + fi + ;; + + stop) + echo -n " Stopping: repro " + STATUS=0 + + if [ ! -r ${pidfile} ] + then + echo "(Not started) " + else + PID=`cat ${pidfile} 2> /dev/null` + + if [ ! -e /proc/$PID ] + then + echo "(Started but not running) " + rm -f ${pidfile} + else + echo "" + kill $PID 2> /dev/null + fi + fi + ;; + + status) + echo -n "Checking repro: " + if [ ! -r $pidfile ] + then + echo "[Not Running] " + else + PID=`cat $pidfile 2> /dev/null` + + if [ -e /proc/$PID ] + then + echo_success; echo '' + else + echo_failure; echo '' + fi + fi + ;; + + restart) + $0 stop + $0 start + ;; + *) + echo $"Usage: $0 {start|stop|status|restart}" + exit 1 +esac + +exit $? diff --git a/src/libs/resiprocate/repro/etc/repro.conf b/src/libs/resiprocate/repro/etc/repro.conf new file mode 100644 index 00000000..4a6c1d6d --- /dev/null +++ b/src/libs/resiprocate/repro/etc/repro.conf @@ -0,0 +1,79 @@ +# Anything in this file not preceeded by '#' will be +# passed as arguments to repro when it is started by /etc/init.d/repro +# +# -l, --log-type=syslog|cerr|cout +# where to send logging messages (default: "cout") +# for syslog, the facility is LOG_LOCAL6 +--log-type=syslog + +# -v, --log-level=STACK|DEBUG|INFO|WARNING|ALERT +# specify the default log level (default: "INFO") +# +# -r, --record-route=sip:example.com +# specify uri to use as Record-Route +# +# --udp=5060 +# listen on UDP port (default: 5060) +# +# --tcp=5060 +# listen on TCP port (default: 5060) +# +# -t, --tls-domain=example.com +# act as a TLS server for specified domain +# +# --tls=5061 +# add TLS transport on specified port (default: 5061) +# +# --dtls=0 +# add DTLS transport on specified port (default: 0) +# +# --enable-cert-server +# run a cert server +# +# -c, --cert-path=STRING +# path for certificates (default: "${HOME}/.sipCerts") +# +# --enable-v6 +# enable IPV6 +# +# --disable-v4 +# disable IPV4 +# +# --disable-auth +# disable DIGEST challenges +# +# --disable-web-auth +# disable HTTP challenges +# +# --disable-reg +# disable registrar +# +# -i, --interfaces=sip:10.1.1.1:5065;transport=tls +# specify interfaces to add transports to +# +# -d, --domains=example.com,foo.com +# specify domains that this proxy is authorative +# +# -R, --route=sip:p1.example.com,sip:p2.example.com +# specify where to route requests that are in this proxy's domain +# +# --reqChainName=STRING +# name of request chain (default: default) +# +# --http=5080 +# run HTTP server on specified port (default: 5080) +# +# --recursive-redirect +# Handle 3xx responses in the proxy +# +# --q-value +# Enable sequential q-value processing +# +# -e, --enum-suffix=e164.arpa +# specify enum suffix to search +# +# -b, --allow-bad-reg +# allow To tag in registrations +# +# --timer-C=180 +# specify length of timer C in sec (0 or negative will disable timer C) diff --git a/src/libs/resiprocate/repro/genUsers.cxx b/src/libs/resiprocate/repro/genUsers.cxx new file mode 100644 index 00000000..f8dbcefd --- /dev/null +++ b/src/libs/resiprocate/repro/genUsers.cxx @@ -0,0 +1,49 @@ + +#include <cassert> +#include <iostream> + +#include "repro/UserStore.hxx" +#include "repro/AbstractDb.hxx" +#include "repro/BerkeleyDb.hxx" +#include "rutil/Data.hxx" +#include "rutil/Logger.hxx" + +using namespace resip; +using namespace repro; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + + +int +main(int argc, char* argv[]) +{ + Log::initialize(Log::Cerr, Log::Err, argv[0]); + Log::setLevel(Log::Info); + + const int numUsers = 100*1000; + + AbstractDb* db = new BerkeleyDb; + + UserStore store( *db ); + + for ( int i=0; i<numUsers;i++) + { + Data user = Data("User") + Data(i); + + store.addUser( user, + "localhost", // domain + "localhost", // realm + "password", // password + true, // apply hash to password + "Alice W. Here", // fullName + "alice@example.com" /*email*/ ); + + if ( i%100 == 0 ) + { + InfoLog( << "Created " << user ); + } + } + + return 0; +} diff --git a/src/libs/resiprocate/repro/monkeys/AmIResponsible.cxx b/src/libs/resiprocate/repro/monkeys/AmIResponsible.cxx new file mode 100644 index 00000000..fba4a05e --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/AmIResponsible.cxx @@ -0,0 +1,199 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Helper.hxx" +#include "repro/monkeys/AmIResponsible.hxx" +#include "repro/monkeys/IsTrustedNode.hxx" +#include "repro/RequestContext.hxx" +#include "repro/Proxy.hxx" +#include <ostream> + +#include "rutil/Logger.hxx" +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +AmIResponsible::AmIResponsible() : + Processor("AmIResponsible") +{} + +AmIResponsible::~AmIResponsible() +{} + +Processor::processor_action_t +AmIResponsible::process(RequestContext& context) +{ + DebugLog(<< "Monkey handling request: " << *this + << "; reqcontext = " << context); + + resip::SipMessage& request = context.getOriginalRequest(); + + // This call is placed after the DigestAuthenticator, so that we only account for + // authenticated sessions. + context.getProxy().doSessionAccounting(request, true /* received */, context); + + // There should be no Routes on the request at this point, if there was a route, then + // the StrictRouteFixup monkey would have routed to it already + assert (!request.exists(h_Routes) || + request.header(h_Routes).empty()); + + // Topmost route had a flow-token; this is our problem + if(!context.getTopRoute().uri().user().empty()) + { + resip::Tuple dest(Tuple::makeTupleFromBinaryToken(context.getTopRoute().uri().user().base64decode(), Proxy::FlowTokenSalt)); + if(!(dest==resip::Tuple())) + { + // .bwc. Valid flow token + std::auto_ptr<Target> target(new Target(request.header(h_RequestLine).uri())); + target->rec().mReceivedFrom = dest; + target->rec().mUseFlowRouting = true; + context.getResponseContext().addTarget(target); + return SkipThisChain; + } + } + + // this if is just to be safe + if (!request.exists(h_Routes) || + request.header(h_Routes).empty()) + { + // !RjS! - Jason - check the RURI to see if the domain is + // something this request is responsible for. If yes, then + // just return Continue. If no make this call below. + const Uri& uri = request.header(h_RequestLine).uri(); + if (!context.getProxy().isMyUri(uri)) + { + // if this is not for a domain for which the proxy is responsible, + // check that this sender is in our domain and send to the Request URI + + // Ensure To header is well formed + if(!request.header(h_To).isWellFormed()) + { + resip::SipMessage response; + InfoLog(<<"Garbage in To header: needed for relay check."); + Helper::makeResponse(response,context.getOriginalRequest(), 400, "Malformed To: header"); + context.sendResponse(response); + return Processor::SkipThisChain; + } + + // only perform relay check for out-of-dialog requests + // !bwc! Um, then all anyone has to do to get us to be their relay + // is throw in a spurious to-tag... + // This smells funny. I am commenting it out. + // .slg. Putting the ood check back in and clarifying the funny smell... + // We only want to do this check for out of dialog requests, since + // mid-dialog requests could be 403'd otherwise. Consider + // an INVITE request from a repro domain user to a user in + // another domain. The resulting ACK/200, BYE or any other + // mid-dialog request coming from the remote domain, will contain + // the repro users contact address in the RequestUri and a + // foreign domain in the from header. We want to ensure these + // requests are not 403'd. Byron's comment about an endpoint getting + // us to relay by placing a spurious to tag in the request still + // stands. Perhaps we ought to be checking the To header domain in + // this case - however that is also weak, since the To header is not + // used in routing and can easily be set to a URI in our domain to + // trick repro into forwarding. Note: From header domain checking is + // stronger than To header domain checking, since if the domain is + // ours, then it must pass Digest Authentication (at least for non + // ACK and BYE requests). + // .bwc. I think that the only real way to solve the + // I-don't-want-to-be-used-as-a-relay problem is crypto; specifically + // Record-Route with crypto that states "Yeah, I set up this dialog, + // let it through". + if (!request.header(h_To).exists(p_tag)) + { + // Ensure From header is well formed + if(!request.header(h_From).isWellFormed()) + { + resip::SipMessage response; + InfoLog(<<"Garbage in From header: needed for relay check."); + Helper::makeResponse(response,context.getOriginalRequest(), 400, "Malformed From: header"); + context.sendResponse(response); + return Processor::SkipThisChain; + } + + // !rwm! verify the AuthenticatioInfo object here. + + // !rwm! TODO check some kind of relay list here + // for now, just see if the sender claims to be from one of our domains + // send a 403 if not on the list + + // .slg. Allow trusted nodes to relay + if (!context.getKeyValueStore().getBoolValue(IsTrustedNode::mFromTrustedNodeKey) && + !context.getProxy().isMyUri(request.header(h_From).uri())) + { + // make 403, send, dispose of memory + resip::SipMessage response; + InfoLog (<< *this << ": will not relay to " << uri << " from " + << request.header(h_From).uri() << ", send 403"); + Helper::makeResponse(response, context.getOriginalRequest(), 403, "Relaying Forbidden"); + context.sendResponse(response); + return Processor::SkipThisChain; + } + } + + std::auto_ptr<Target> target(new Target(request.header(h_RequestLine).uri())); + context.getResponseContext().addTarget(target); + + InfoLog (<< "Sending to requri: " << request.header(h_RequestLine).uri()); + // skip the rest of the monkeys + return Processor::SkipThisChain; + } + } + return Processor::Continue; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/AmIResponsible.hxx b/src/libs/resiprocate/repro/monkeys/AmIResponsible.hxx new file mode 100644 index 00000000..7474f871 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/AmIResponsible.hxx @@ -0,0 +1,69 @@ +#if !defined(RESIP_AMIRESPONSIBLE_REQUEST_PROCESSOR_HXX) +#define RESIP_AMIRESPONSIBLE_REQUEST_PROCESSOR_HXX +#include "repro/Processor.hxx" +#include <iosfwd> +#include "rutil/resipfaststreams.hxx" + +namespace repro +{ + + class AmIResponsible: public Processor + { + public: + AmIResponsible(); + virtual ~AmIResponsible(); + + virtual processor_action_t process(RequestContext &); + }; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/CertificateAuthenticator.cxx b/src/libs/resiprocate/repro/monkeys/CertificateAuthenticator.cxx new file mode 100644 index 00000000..8b0cdaff --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/CertificateAuthenticator.cxx @@ -0,0 +1,238 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "rutil/DnsUtil.hxx" +#include "resip/stack/Message.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Auth.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/Logger.hxx" + +#include "repro/monkeys/CertificateAuthenticator.hxx" +#include "repro/monkeys/IsTrustedNode.hxx" +#include "repro/RequestContext.hxx" +#include "repro/Proxy.hxx" +#include "repro/UserInfoMessage.hxx" +#include "repro/UserStore.hxx" +#include "repro/Dispatcher.hxx" +#include "resip/stack/SipStack.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +KeyValueStore::Key CertificateAuthenticator::mCertificateVerifiedKey = Proxy::allocateRequestKeyValueStoreKey(); + +CertificateAuthenticator::CertificateAuthenticator(ProxyConfig& config, + resip::SipStack* stack, + std::set<Data>& trustedPeers, + bool thirdPartyRequiresCertificate) : + Processor("CertificateAuthenticator"), + mTrustedPeers(trustedPeers), + mThirdPartyRequiresCertificate(thirdPartyRequiresCertificate) +{ +} + +CertificateAuthenticator::CertificateAuthenticator(ProxyConfig& config, + resip::SipStack* stack, + std::set<Data>& trustedPeers, + bool thirdPartyRequiresCertificate, + CommonNameMappings& commonNameMappings) : + Processor("CertificateAuthenticator"), + mTrustedPeers(trustedPeers), + mThirdPartyRequiresCertificate(thirdPartyRequiresCertificate), + mCommonNameMappings(commonNameMappings) +{ +} + +CertificateAuthenticator::~CertificateAuthenticator() +{ +} + +repro::Processor::processor_action_t +CertificateAuthenticator::process(repro::RequestContext &rc) +{ + DebugLog(<< "Monkey handling request: " << *this << "; reqcontext = " << rc); + + Message *message = rc.getCurrentEvent(); + + SipMessage *sipMessage = dynamic_cast<SipMessage*>(message); + Proxy &proxy = rc.getProxy(); + + if (sipMessage) + { + if (sipMessage->method() == ACK || + sipMessage->method() == BYE) + { + return Continue; + } + + // if there was no Proxy-Auth header already, and the request is purportedly From + // one of our domains, send a challenge, unless this is from a trusted node in one + // of "our" domains (ex: from a gateway). + // + // Note that other monkeys can still challenge the request later if needed + // for other reasons (for example, the StaticRoute monkey) + if(!sipMessage->header(h_From).isWellFormed() || + sipMessage->header(h_From).isAllContacts() ) + { + InfoLog(<<"Malformed From header: cannot verify against any certificate. Rejecting."); + rc.sendResponse(*auto_ptr<SipMessage> + (Helper::makeResponse(*sipMessage, 400, "Malformed From header"))); + return SkipAllChains; + } + + // Get the certificate from the peer + if(sipMessage->isExternal() && sipMessage->getSource().getType() != TLS) + { + DebugLog(<<"Can't validate certificate on non-TLS connection"); + return Continue; + } + + const std::list<resip::Data> &peerNames = sipMessage->getTlsPeerNames(); + if (proxy.isMyDomain(sipMessage->header(h_From).uri().host())) + { + if (!rc.getKeyValueStore().getBoolValue(IsTrustedNode::mFromTrustedNodeKey)) + { + // peerNames is empty if client certificate mode is `optional' + // or if the message didn't come in on TLS transport + if(peerNames.empty()) + return Continue; + if(authorizedForThisIdentity(peerNames, sipMessage->header(h_From).uri())) + { + rc.getKeyValueStore().setBoolValue(CertificateAuthenticator::mCertificateVerifiedKey, true); + return Continue; + } + rc.sendResponse(*auto_ptr<SipMessage> + (Helper::makeResponse(*sipMessage, 403, "Authentication Failed for peer cert"))); + return SkipAllChains; + } + else + return Continue; + } + else + { + // peerNames is empty if client certificate mode is `optional' + // or if the message didn't come in on TLS transport + if(peerNames.empty()) + { + if(mThirdPartyRequiresCertificate) + { + rc.sendResponse(*auto_ptr<SipMessage> + (Helper::makeResponse(*sipMessage, 403, "Mutual TLS required to handle that message"))); + return SkipAllChains; + } + else + return Continue; + } + if(authorizedForThisIdentity(peerNames, sipMessage->header(h_From).uri())) + { + rc.getKeyValueStore().setBoolValue(CertificateAuthenticator::mCertificateVerifiedKey, true); + return Continue; + } + rc.sendResponse(*auto_ptr<SipMessage> + (Helper::makeResponse(*sipMessage, 403, "Authentication Failed for peer cert"))); + return SkipAllChains; + } + } + + return Continue; +} + +bool +CertificateAuthenticator::authorizedForThisIdentity(const std::list<Data>& peerNames, + resip::Uri &fromUri) +{ + Data aor = fromUri.getAorNoPort(); + Data domain = fromUri.host(); + + std::list<Data>::const_iterator it = peerNames.begin(); + for(; it != peerNames.end(); ++it) + { + const Data& i = *it; + if(mTrustedPeers.find(i) != mTrustedPeers.end()) + { + DebugLog(<< "Matched certificate name " << i << " is a trusted peer, not checking against From URI"); + return true; + } + if(i == aor) + { + DebugLog(<< "Matched certificate name " << i << " against full AoR " << aor); + return true; + } + if(i == domain) + { + DebugLog(<< "Matched certificate name " << i << " against domain " << domain); + return true; + } + CommonNameMappings::iterator _mapping = + mCommonNameMappings.find(i); + if(_mapping != mCommonNameMappings.end()) + { + DebugLog(<< "CN mapping(s) exist for the certificate " << i); + PermittedFromAddresses& permitted = _mapping->second; + if(permitted.find(aor) != permitted.end()) + { + DebugLog(<< "Matched certificate name " << i << " against full AoR " << aor << " by common name mappings"); + return true; + } + if(permitted.find(domain) != permitted.end()) + { + DebugLog(<< "Matched certificate name " << i << " against domain " << domain << " by common name mappings"); + return true; + } + } + DebugLog(<< "Certificate name " << i << " doesn't match AoR " << aor << " or domain " << domain); + } + + // catch-all: access denied + return false; +} + +void +CertificateAuthenticator::dump(EncodeStream &os) const +{ + os << "CertificateAuthentication monkey" << std::endl; +} + +/* ==================================================================== + * + * Copyright (c) 2012 Daniel Pocock All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/CertificateAuthenticator.hxx b/src/libs/resiprocate/repro/monkeys/CertificateAuthenticator.hxx new file mode 100644 index 00000000..42203965 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/CertificateAuthenticator.hxx @@ -0,0 +1,78 @@ +#if !defined(RESIP_CERTIFICATE_AUTHENTICATOR_HXX) +#define RESIP_CERTIFICATE_AUTHENTICATOR_HXX + +#include <set> + +#include "rutil/Data.hxx" +#include "rutil/KeyValueStore.hxx" +#include "resip/dum/TlsPeerAuthManager.hxx" +#include "repro/Processor.hxx" +#include "repro/Dispatcher.hxx" +#include "repro/ProxyConfig.hxx" + +namespace resip +{ + class SipStack; +} + +namespace repro +{ + class CertificateAuthenticator : public Processor + { + public: + static resip::KeyValueStore::Key mCertificateVerifiedKey; + + CertificateAuthenticator(ProxyConfig& config, resip::SipStack* stack, std::set<resip::Data>& trustedPeers, bool thirdPartyRequiresCertificate = true); + CertificateAuthenticator(ProxyConfig& config, resip::SipStack* stack, std::set<resip::Data>& trustedPeers, bool thirdPartyRequiresCertificate, resip::CommonNameMappings& commonNameMappings); + ~CertificateAuthenticator(); + + virtual processor_action_t process(RequestContext &); + virtual void dump(EncodeStream &os) const; + + private: + bool authorizedForThisIdentity(const std::list<resip::Data>& peerNames, resip::Uri &fromUri); + + std::set<resip::Data> mTrustedPeers; + bool mThirdPartyRequiresCertificate; + resip::CommonNameMappings mCommonNameMappings; + }; + +} +#endif + +/* ==================================================================== + * + * Copyright (c) 2012 Daniel Pocock All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ + diff --git a/src/libs/resiprocate/repro/monkeys/ConstantLocationMonkey.cxx b/src/libs/resiprocate/repro/monkeys/ConstantLocationMonkey.cxx new file mode 100644 index 00000000..d4dee1b4 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/ConstantLocationMonkey.cxx @@ -0,0 +1,91 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/SipMessage.hxx" +#include "repro/monkeys/ConstantLocationMonkey.hxx" +#include "repro/RequestContext.hxx" + +#include "rutil/Logger.hxx" +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + + +ConstantLocationMonkey::ConstantLocationMonkey() : + Processor("ConstantLocationMonkey") +{} + +ConstantLocationMonkey::~ConstantLocationMonkey() +{} + +Processor::processor_action_t +ConstantLocationMonkey::process(RequestContext& context) +{ + DebugLog(<< "Monkey handling request: " << *this + << "; reqcontext = " << context); + + if (context.getOriginalRequest().header(h_RequestLine).uri().user() == "inner") + { + context.getResponseContext().addTarget(NameAddr("<sip:inner@72.29.230.162>")); + } + else if (context.getOriginalRequest().header(h_RequestLine).uri().user() == "outer") + { + context.getResponseContext().addTarget(NameAddr("<sip:101@sipedge.sipit.net>")); + } + + return Processor::Continue; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/ConstantLocationMonkey.hxx b/src/libs/resiprocate/repro/monkeys/ConstantLocationMonkey.hxx new file mode 100644 index 00000000..858f276c --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/ConstantLocationMonkey.hxx @@ -0,0 +1,67 @@ +#if !defined(RESIP_CONSTANTMONKEY_REQUEST_PROCESSOR_HXX) +#define RESIP_CONSTANTMONKEY_REQUEST_PROCESSOR_HXX +#include "repro/Processor.hxx" + +namespace repro +{ + + class ConstantLocationMonkey: public Processor + { + public: + ConstantLocationMonkey(); + virtual ~ConstantLocationMonkey(); + + virtual processor_action_t process(RequestContext &); + }; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/DigestAuthenticator.cxx b/src/libs/resiprocate/repro/monkeys/DigestAuthenticator.cxx new file mode 100644 index 00000000..c3a8af3e --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/DigestAuthenticator.cxx @@ -0,0 +1,484 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "rutil/DnsUtil.hxx" +#include "resip/stack/Message.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Auth.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/Logger.hxx" + +#include "repro/monkeys/DigestAuthenticator.hxx" +#include "repro/monkeys/IsTrustedNode.hxx" +#include "repro/RequestContext.hxx" +#include "repro/Proxy.hxx" +#include "repro/UserInfoMessage.hxx" +#include "repro/UserStore.hxx" +#include "repro/Dispatcher.hxx" +#include "resip/stack/SipStack.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +DigestAuthenticator::DigestAuthenticator(ProxyConfig& config, + Dispatcher* authRequestDispatcher) : + Processor("DigestAuthenticator"), + mAuthRequestDispatcher(authRequestDispatcher), + mNoIdentityHeaders(config.getConfigBool("DisableIdentity", false)), + mHttpHostname(config.getConfigData("HttpHostname", "")), + mHttpPort(config.getConfigInt("HttpPort", 5080)), + mUseAuthInt(!config.getConfigBool("DisableAuthInt", false)), + mRejectBadNonces(config.getConfigBool("RejectBadNonces", false)) +{ +} + +DigestAuthenticator::~DigestAuthenticator() +{ +} + +repro::Processor::processor_action_t +DigestAuthenticator::process(repro::RequestContext &rc) +{ + DebugLog(<< "Monkey handling request: " << *this << "; reqcontext = " << rc); + + Message *message = rc.getCurrentEvent(); + + SipMessage *sipMessage = dynamic_cast<SipMessage*>(message); + UserInfoMessage *userInfo = dynamic_cast<UserInfoMessage*>(message); + Proxy &proxy = rc.getProxy(); + + if (sipMessage) + { + if (sipMessage->method() == ACK || + sipMessage->method() == BYE) + { + // Don't challenge ACK and BYE requests + return Continue; + } + + if (sipMessage->exists(h_ProxyAuthorizations)) + { + Auths &authHeaders = sipMessage->header(h_ProxyAuthorizations); + + // if we find a Proxy-Authorization header for a realm we handle, + // asynchronously fetch the relevant userAuthInfo from the database + for (Auths::iterator i = authHeaders.begin() ; i != authHeaders.end() ; ++i) + { + // !rwm! TODO sometime we need to have a separate isMyRealm() function + if (proxy.isMyDomain(i->param(p_realm))) + { + return requestUserAuthInfo(rc, i->param(p_realm)); + } + } + } + + // if there was no Proxy-Auth header already, and the request is purportedly From + // one of our domains, send a challenge, unless this is from a trusted node in one + // of "our" domains (ex: from a gateway). + // + // Note that other monkeys can still challenge the request later if needed + // for other reasons (for example, the StaticRoute monkey) + if(!sipMessage->header(h_From).isWellFormed() || + sipMessage->header(h_From).isAllContacts() ) + { + InfoLog(<<"Malformed From header: cannot get realm to challenge with. Rejecting."); + rc.sendResponse(*auto_ptr<SipMessage> + (Helper::makeResponse(*sipMessage, 400, "Malformed From header"))); + return SkipAllChains; + } + + if (proxy.isMyDomain(sipMessage->header(h_From).uri().host())) + { + if (!rc.getKeyValueStore().getBoolValue(IsTrustedNode::mFromTrustedNodeKey)) + { + challengeRequest(rc, false); + return SkipAllChains; + } + } + } + else if (userInfo) + { + // Handle response from user authentication database + sipMessage = &rc.getOriginalRequest(); + const Data& a1 = userInfo->A1(); + const Data& realm = userInfo->realm(); + const Data& user = userInfo->user(); + InfoLog (<< "Received user auth info for " << user << " at realm " << realm + << " a1 is " << a1); + + pair<Helper::AuthResult,Data> result = + Helper::advancedAuthenticateRequest(*sipMessage, realm, a1, 3000); // was 15 + +// Auths &authHeaders = sipMessage->header(h_ProxyAuthorizations); + switch (result.first) + { + case Helper::Failed: + InfoLog (<< "Authentication failed for " << user << " at realm " << realm << ". Sending 403"); + rc.sendResponse(*auto_ptr<SipMessage> + (Helper::makeResponse(*sipMessage, 403, "Authentication Failed"))); + return SkipAllChains; + + // !abr! Eventually, this should just append a counter to + // the nonce, and increment it on each challenge. + // If this count is smaller than some reasonable limit, + // then we re-challenge; otherwise, we send a 403 instead. + + case Helper::Authenticated: + InfoLog (<< "Authentication ok for " << user); + + // Delete the Proxy-Auth header for this realm. + // other Proxy-Auth headers might be needed by a downsteram node +/* + Auths::iterator i = authHeaders.begin(); + Auths::iterator j = authHeaders.begin(); + while( i != authHeaders.end() ) + { + if (proxy.isMyDomain(i->param(p_realm))) + { + j = i++; + authHeaders.erase(j); + } + else + { + ++i; + } + } +*/ + if(!sipMessage->header(h_From).isWellFormed() || + sipMessage->header(h_From).isAllContacts()) + { + InfoLog(<<"From header is malformed in" + " digest response."); + rc.sendResponse(*auto_ptr<SipMessage> + (Helper::makeResponse(*sipMessage, 400, "Malformed From header"))); + return SkipAllChains; + } + + if (authorizedForThisIdentity(user, realm, sipMessage->header(h_From).uri())) + { + rc.setDigestIdentity(user); + + if(rc.getProxy().isPAssertedIdentityProcessingEnabled()) + { + if (sipMessage->exists(h_PPreferredIdentities)) + { + // Ensure any P-AssertedIdentities present are removed (note: this is an illegal condidition) + sipMessage->remove(h_PAssertedIdentities); + + // TODO - when we have a concept of multiple identities per user + // find the first sip or sips P-Preferred-Identity header and the first tel + // bool haveSip = false; + // bool haveTel = false; + // for (;;) + // { + // if ((i->uri().scheme() == Symbols::SIP) || (i->uri().scheme() == Symbols::SIPS)) + // { + // if (haveSip) + // { + // continue; // skip all but the first sip: or sips: URL + // } + // haveSip = true; + // + // if (knownSipIdentity( user, realm, i->uri() ) // should be NameAddr? + // { + // sipMessage->header(h_PAssertedIdentities).push_back( i->uri() ); + // } + // else + // { + // sipMessage->header(h_PAssertedIdentities).push_back(getDefaultIdentity(user, realm)); + // } + // } + // else if ((i->uri().scheme() == Symbols::TEL)) + // { + // if (haveTel) + // { + // continue; // skip all but the first tel: URL + // } + // haveTel = true; + // + // if (knownTelIdentity( user, realm, i->uri() )) + // { + // sipMessage->header(h_PAssertedIdentities).push_back( i->uri() ); + // } + // } + // } + + // We currently don't do anything special with the P-Peferred-Identity hint - just + // add default identity + sipMessage->header(h_PAssertedIdentities).push_back(getDefaultIdentity(user, realm, sipMessage->header(h_From))); + + // Remove the P-Preferered-Identity header + sipMessage->remove(h_PPreferredIdentities); + } + else + { + if (!sipMessage->exists(h_PAssertedIdentities)) + { + sipMessage->header(h_PAssertedIdentities).push_back(getDefaultIdentity(user, realm, sipMessage->header(h_From))); + } + // else TODO + // - should implement guidlines in RFC5876 4.5 - whereby the proxy should remove + // ignored URI's (ie. a 2nd SIP, SIPS or TEL URI, unknown scheme) + } + } + +#if defined(USE_SSL) + if(!mNoIdentityHeaders) + { + static Data http("http://" + mHttpHostname + ":" + Data(mHttpPort) + "/cert?domain="); + // .bwc. Leave pre-existing Identity headers alone. + if(!sipMessage->exists(h_Identity)) + { + sipMessage->header(h_Identity).value() = Data::Empty; // This is a signal to have the TransportSelector fill in the identity header + if(sipMessage->exists(h_IdentityInfo)) + { + InfoLog(<<"Somebody sent us a" + " request with an Identity-Info, but no Identity" + " header. Removing it."); + if(!sipMessage->header(h_IdentityInfo).isWellFormed()) + { + InfoLog(<<"...and this " + "Identity-Info header was malformed!"); + } + + sipMessage->remove(h_IdentityInfo); + } + + sipMessage->header(h_IdentityInfo).uri() = http + realm; + InfoLog (<< "Identity-Info=" << sipMessage->header(h_IdentityInfo).uri()); + } + } +#endif + } + else + { + // !rwm! The user is trying to forge a request. Respond with a 403 + InfoLog (<< "User: " << user << " at realm: " << realm << + " trying to forge request from: " << sipMessage->header(h_From).uri()); + rc.sendResponse(*auto_ptr<SipMessage> + (Helper::makeResponse(*sipMessage, 403))); + return SkipAllChains; + } + + return Continue; + + case Helper::Expired: + InfoLog (<< "Authentication expired for " << user); + challengeRequest(rc, true); + return SkipAllChains; + + case Helper::BadlyFormed: + InfoLog (<< "Authentication nonce badly formed for " << user); + if(mRejectBadNonces) + { + rc.sendResponse(*auto_ptr<SipMessage> + (Helper::makeResponse(*sipMessage, 403, "Where on earth did you get that nonce?"))); + } + else + { + challengeRequest(rc, true); + } + return SkipAllChains; + } + } + + return Continue; +} + +bool +DigestAuthenticator::authorizedForThisIdentity(const resip::Data &user, const resip::Data &realm, + resip::Uri &fromUri) +{ + // !rwm! good enough for now. TODO eventually consult a database to see what + // combinations of user/realm combos are authorized for an identity + if (fromUri.host() == realm) + { + if ((fromUri.user() == user) || (fromUri.user() == "anonymous")) + return true; + + // Now try the form where the username parameter in the auth + // header is the full fromUri, e.g. + // Proxy-Authorization: Digest username="user@domain" ... + // + if (fromUri.getAorNoPort() == user) + return true; + } + + // catch-all: access denied + return false; +} + +NameAddr +DigestAuthenticator::getDefaultIdentity(const resip::Data &user, const resip::Data &realm, resip::NameAddr &from) +{ + NameAddr defaultIdentity; + defaultIdentity.displayName() = from.displayName(); + defaultIdentity.uri().scheme() = from.uri().scheme(); + defaultIdentity.uri().user() = user; + defaultIdentity.uri().host() = realm; + return defaultIdentity; +} + +void +DigestAuthenticator::challengeRequest(repro::RequestContext &rc, + bool stale) +{ + SipMessage &sipMessage = rc.getOriginalRequest(); + Data realm = getRealm(rc); + + SipMessage *challenge = Helper::makeProxyChallenge(sipMessage, realm, + mUseAuthInt /*auth-int*/, stale); + rc.sendResponse(*challenge); + delete challenge; +} + + +repro::Processor::processor_action_t +DigestAuthenticator::requestUserAuthInfo(repro::RequestContext &rc, resip::Data &realm) +{ + Message *message = rc.getCurrentEvent(); + SipMessage *sipMessage = dynamic_cast<SipMessage*>(message); + assert(sipMessage); + + + // Extract the user from the appropriate Proxy-Authorization header + Auths &authorizationHeaders = sipMessage->header(h_ProxyAuthorizations); + Auths::iterator i; + Data user; + + for (i = authorizationHeaders.begin(); + i != authorizationHeaders.end(); i++) + { + if ( i->exists(p_realm) && + i->param(p_realm) == realm + && i->exists(p_username)) + { + user = i->param(p_username); + + InfoLog (<< "Request user auth info for " << user + << " at realm " << realm); + break; + } + } + + if (!user.empty()) + { + UserInfoMessage* async = new UserInfoMessage(*this, rc.getTransactionId(), &(rc.getProxy())); + async->user()=user; + async->realm()=realm; + if(sipMessage->header(h_From).isWellFormed()) + { + async->domain()=sipMessage->header(h_From).uri().host(); + } + else + { + async->domain()=realm; + } + std::auto_ptr<ApplicationMessage> app(async); + mAuthRequestDispatcher->post(app); + return WaitingForEvent; + } + else + { + challengeRequest(rc, false); + return SkipAllChains; + } +} + +resip::Data +DigestAuthenticator::getRealm(RequestContext &rc) +{ + Data realm; + + Proxy &proxy = rc.getProxy(); + SipMessage& sipMessage = rc.getOriginalRequest(); + + // (1) Check Preferred Identity + if (sipMessage.exists(h_PPreferredIdentities)) + { + // !abr! Add this when we get a chance + // find the fist sip or sips P-Preferred-Identity header + // for (;;) + // { + // if ((i->uri().scheme() == Symbols::SIP) || (i->uri().scheme() == Symbols::SIPS)) + // { + // return i->uri().host(); + // } + // } + } + + // (2) Check From domain + if (proxy.isMyDomain(sipMessage.header(h_From).uri().host())) + { + return sipMessage.header(h_From).uri().host(); + } + + // (3) Check Top Route Header + if (sipMessage.exists(h_Routes) && + sipMessage.header(h_Routes).size()!=0 && + sipMessage.header(h_Routes).front().isWellFormed()) + { + // !abr! Add this when we get a chance + } + + // (4) Punt: Use Request URI + return sipMessage.header(h_RequestLine).uri().host(); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/DigestAuthenticator.hxx b/src/libs/resiprocate/repro/monkeys/DigestAuthenticator.hxx new file mode 100644 index 00000000..360de384 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/DigestAuthenticator.hxx @@ -0,0 +1,90 @@ +#if !defined(RESIP_DIGEST_AUTHENTICATOR_HXX) +#define RESIP_DIGEST_AUTHENTICATOR_HXX + +#include "rutil/Data.hxx" +#include "repro/Processor.hxx" +#include "repro/Dispatcher.hxx" +#include "repro/ProxyConfig.hxx" + +namespace resip +{ + class SipStack; +} + +namespace repro +{ + class DigestAuthenticator : public Processor + { + public: + DigestAuthenticator(ProxyConfig& config, Dispatcher* authRequestDispatcher); + ~DigestAuthenticator(); + + virtual processor_action_t process(RequestContext &); + + private: + bool authorizedForThisIdentity(const resip::Data &user, const resip::Data &realm, resip::Uri &fromUri); + resip::NameAddr getDefaultIdentity(const resip::Data &user, const resip::Data &realm, resip::NameAddr &from); + void challengeRequest(RequestContext &, bool stale = false); + processor_action_t requestUserAuthInfo(RequestContext &, resip::Data & realm); + virtual resip::Data getRealm(RequestContext &); + + Dispatcher* mAuthRequestDispatcher; + bool mNoIdentityHeaders; + resip::Data mHttpHostname; // Used in identity headers + int mHttpPort; + bool mUseAuthInt; + bool mRejectBadNonces; + }; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/GeoProximityTargetSorter.cxx b/src/libs/resiprocate/repro/monkeys/GeoProximityTargetSorter.cxx new file mode 100644 index 00000000..347e7fe3 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/GeoProximityTargetSorter.cxx @@ -0,0 +1,532 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef RESIP_FIXED_POINT +#include <algorithm> + +#ifdef USE_MAXMIND_GEOIP +// MaxMind GeoIP header +#include <GeoIP.h> +#include <GeoIPCity.h> +#endif + +#include "repro/monkeys/GeoProximityTargetSorter.hxx" + +#include "repro/RequestContext.hxx" +#include "repro/ResponseContext.hxx" +#include "repro/Proxy.hxx" +#include "repro/Target.hxx" + +#include "resip/stack/ExtensionParameter.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/Data.hxx" +#include "rutil/Random.hxx" +#include "rutil/Logger.hxx" +#include "repro/ProxyConfig.hxx" +#include "rutil/WinLeakCheck.hxx" + + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +KeyValueStore::Key GeoProximityTargetSorter::mGeoTargetSortingDoneKey = Proxy::allocateRequestKeyValueStoreKey(); + +// Custom NameAddr parameter that Regitering party or request sender can use on their Contact +// header to pass their geo location information to repro, so that a lookup in the MaxMind +// Geo IP tables is not required +static ExtensionParameter p_geolocation("x-repro-geolocation"); + +void* GeoProximityTargetSorter::mGeoIPv4 = 0; +void* GeoProximityTargetSorter::mGeoIPv6 = 0; + +class GeoProximityTargetContainer +{ +public: + GeoProximityTargetContainer(double distance, Target* target) : mDistance(distance), mTarget(target) {} + ~GeoProximityTargetContainer() {} + + // Sort targets by distance from client + static bool instanceCompare(const GeoProximityTargetContainer& lhs, + const GeoProximityTargetContainer& rhs) + { + return lhs.mDistance < rhs.mDistance; + } + + Target* getTarget() { return mTarget; } + double getDistance() { return mDistance; } + +private: + double mDistance; + Target* mTarget; +}; + +GeoProximityTargetSorter::GeoProximityTargetSorter(ProxyConfig& config) : + Processor("GeoProximityTargetHandler"), + mRUriRegularExpressionData(config.getConfigData("GeoProximityRequestUriFilter", "")), + mRUriRegularExpression(0), + mDefaultDistance(config.getConfigUnsignedLong("GeoProximityDefaultDistance", 0)), + mLoadBalanceEqualDistantTargets(config.getConfigBool("LoadBalanceEqualDistantTargets", true)) +{ + int flags = REG_EXTENDED | REG_NOSUB; + + if(!mRUriRegularExpressionData.empty()) + { + mRUriRegularExpression = new regex_t; + int ret = regcomp(mRUriRegularExpression, mRUriRegularExpressionData.c_str(), flags); + if( ret != 0 ) + { + delete mRUriRegularExpression; + ErrLog( << "GeoProximityRequestUriFilter rule has invalid match expression: " + << mRUriRegularExpressionData); + mRUriRegularExpression = 0; + } + } + else + { + mRUriRegularExpression = 0; + } + +#ifdef USE_MAXMIND_GEOIP + // Initialize GeoIP library - load data + Data geoIPv4Database = config.getConfigData("GeoProximityIPv4CityDatabaseFile", "GeoLiteCity.dat", false); + if(!geoIPv4Database.empty()) + { + mGeoIPv4 = (GeoIP*)GeoIP_open(geoIPv4Database.c_str(), GEOIP_MEMORY_CACHE); // Cache entire DB in memory - could make this configurable + if(mGeoIPv4 != 0) + { + InfoLog(<< "GeoProximityTargetSorter: IPv4 db info: " << GeoIP_database_info((GeoIP*)mGeoIPv4)); + + int i = GeoIP_database_edition((GeoIP*)mGeoIPv4); + + if(i != GEOIP_CITY_EDITION_REV0 /* 6 */ && + i != GEOIP_CITY_EDITION_REV1 /* 2 */ && + i != GEOIP_CITYCONFIDENCE_EDITION /* 15 */ && + i != GEOIP_CITYCONFIDENCEDIST_EDITION /* 16 */) + { + // Wrong DB Type + ErrLog(<< "GeoProximityTargetSorter: IPv4 GeoIP database is not of the correct type, IPv4 geo lookups will not take place."); + GeoIP_delete((GeoIP*)mGeoIPv4); + mGeoIPv4 = 0; + } + } + else + { + ErrLog(<< "GeoProximityTargetSorter: Failed to open IPv4 GeoIP database, IPv4 geo lookups will not take place: " << geoIPv4Database); + } + } + else + { + InfoLog(<< "GeoProximityTargetSorter: No IPv4 GeoIP database specified, IPv4 geo lookups will not take place."); + } + +#ifdef USE_IPV6 + Data geoIPv6Database = config.getConfigData("GeoProximityIPv6CityDatabaseFile", "GeoLiteCityv6.dat", false); + if(!geoIPv6Database.empty()) + { + mGeoIPv6 = (GeoIP*)GeoIP_open(geoIPv6Database.c_str(), GEOIP_MEMORY_CACHE); // Cache entire DB in memory - could make this configurable + if(mGeoIPv6 != 0) + { + InfoLog(<< "GeoProximityTargetSorter: IPv6 db info: " << GeoIP_database_info((GeoIP*)mGeoIPv6)); + + int i = GeoIP_database_edition((GeoIP*)mGeoIPv6); + + if(i != GEOIP_CITY_EDITION_REV1_V6 /* 30 */ && + i != GEOIP_CITY_EDITION_REV0_V6 /* 31 */) + { + // Wrong DB Type + ErrLog(<< "GeoProximityTargetSorter: IPv6 GeoIP database is not of the correct type, IPv6 geo lookups will not take place."); + GeoIP_delete((GeoIP*)mGeoIPv6); + mGeoIPv6 = 0; + } + } + else + { + ErrLog(<< "GeoProximityTargetSorter: Failed to open IPv6 GeoIP database, IPv6 geo lookups will not take place: " << geoIPv6Database); + } + } + else + { + InfoLog(<< "GeoProximityTargetSorter: No IPv6 GeoIP database specified, IPv6 geo lookups will not take place."); + } +#else + mGeoIPv6 = 0; +#endif + +#endif +} + +GeoProximityTargetSorter::~GeoProximityTargetSorter() +{ + if(mRUriRegularExpression) + { + regfree(mRUriRegularExpression); + delete mRUriRegularExpression; + mRUriRegularExpression = 0; + } +#ifdef USE_MAXMIND_GEOIP + if(mGeoIPv4) + { + GeoIP_delete((GeoIP*)mGeoIPv4); + mGeoIPv4 = 0; + } + if(mGeoIPv6) + { + GeoIP_delete((GeoIP*)mGeoIPv6); + mGeoIPv6 = 0; + } +#endif +} + +Processor::processor_action_t +GeoProximityTargetSorter::process(RequestContext &rc) +{ + // Check if we've already run this Baboon or not - if not, then run it. Baboons + // are dispatched multiple times, once when the Monkeys are done, and once for each + // response received (after the Lemurs have run). + // + // Note: This check causes us to only sort the Targets once (ie. the first time + // the Monkeys are complete). In the future we may want to allow GeoProximity + // sorting of multiple contacts returned in a 3xx response (when + // RecursiveRedirect is enabled). + if(!rc.getKeyValueStore().getBoolValue(mGeoTargetSortingDoneKey)) + { + rc.getKeyValueStore().setBoolValue(mGeoTargetSortingDoneKey, true); + + ResponseContext& rsp=rc.getResponseContext(); + + // If there is not 2 or more candidate targets then there is nothing to sort + if(rsp.getCandidateTransactionMap().size() >= 2) + { + // This is the first run, no Targets should be active yet + assert(rsp.hasCandidateTransactions() && + !rsp.hasActiveTransactions() && + !rsp.hasTerminatedTransactions()); + + // Check if request meets filter criteria + if(!mRUriRegularExpressionData.empty()) // If empty we consider all URI's matched + { + if(mRUriRegularExpression) + { + if(regexec(mRUriRegularExpression, Data::from(rc.getOriginalRequest().header(h_RequestLine).uri()).c_str(), 0 /*ignored*/, 0 /*ignored*/, 0/*eflags*/) != 0) + { + // did not match + DebugLog( << "GeoProximityTargetSorter: Skipped - request URI "<< rc.getOriginalRequest().header(h_RequestLine).uri() << " did not match."); + return Processor::Continue; + } + } + else + { + // Regular expression provided is bad - error was logged at startup time + return Processor::Continue; + } + } + + SipMessage& request = rc.getOriginalRequest(); + double clientLatitude; + double clientLongitude; + getClientGeoLocation(request, clientLatitude, clientLongitude); + + DebugLog(<< "GeoProximityTargetSorter: numCandidates=" << rsp.getCandidateTransactionMap().size() + << ", clientLatitude=" << clientLatitude << ", clientLongitude=" << clientLongitude); + + std::vector<GeoProximityTargetContainer> flatTargetList; + + std::list<std::list<resip::Data> >& targetCollection = rsp.mTransactionQueueCollection; + std::list<std::list<resip::Data> >::iterator outer = targetCollection.begin(); + std::list<resip::Data>::iterator inner; + int outerCounter=1; + for(; outer!=targetCollection.end(); outer++, outerCounter++) + { + inner=outer->begin(); + for(; inner != outer->end(); inner++) + { + assert(rsp.isCandidate(*inner)); + Target* target = rsp.getTarget(*inner); + if(target) + { + resip::ContactInstanceRecord& rec = target->rec(); + double distance = getTargetDistance(*target, clientLatitude, clientLongitude); + + if(rec.mPublicAddress.getType() != UNKNOWN_TRANSPORT) + { + DebugLog(<< "GeoProximityTargetSorter: TransactionQueueCollection[" << outerCounter << "]: Target=" << rec.mContact + << ", PublicAddress=" << rec.mPublicAddress + << ", DistanceFromClient=" << distance); + } + else + { + DebugLog(<< "GeoProximityTargetSorter: TransactionQueueCollection[" << outerCounter << "]: Target=" << rec.mContact + << ", DistanceFromClient=" << distance); + } + + // Flatten batches - since we will be serial routing + flatTargetList.push_back(GeoProximityTargetContainer(distance, target)); + } + else + { + WarningLog(<< "GeoProximityTargetSorter: TransactionQueueCollection[" << outerCounter << "]: TID=" << *inner << " - Couldn't find target"); + } + } + } + + if(mLoadBalanceEqualDistantTargets) + { + // Shuffle Targets - so that targets of equal distance will be in random order + random_shuffle(flatTargetList.begin(), flatTargetList.end()); + } + + // Sort List by distance - note: if we don't know the client location, there is no point in sorting + // just use the newly flattened / shuffled target list in the existing order + if(clientLatitude != 0 && clientLongitude != 0) + { + sort(flatTargetList.begin(), flatTargetList.end(), GeoProximityTargetContainer::instanceCompare); + } + + // Rebuild targetCollection - Note: All batches are split up to individual / serial targets + targetCollection.clear(); + std::vector<GeoProximityTargetContainer>::iterator it = flatTargetList.begin(); + outerCounter=1; + for(; it != flatTargetList.end(); it++, outerCounter++) + { + std::list<resip::Data> queue; + queue.push_back(it->getTarget()->tid()); + targetCollection.push_back(queue); + + DebugLog(<< "GeoProximityTargetSorter: Sorted TransactionQueueCollection[" << outerCounter << "]: Target=" << it->getTarget()->rec().mContact + << ", DistanceFromClient=" << it->getDistance()); + } + } + else + { + DebugLog( << "GeoProximityTargetSorter: Skipped since only one target for request URI "<< rc.getOriginalRequest().header(h_RequestLine).uri()); + } + } + + return Processor::Continue; +} + +void +GeoProximityTargetSorter::getClientGeoLocation(const SipMessage& request, double& latitude, double& longitude) +{ + assert(request.isRequest()); + + // First check to see if x-repro-geolocation parameter is on Contact header + if(request.exists(h_Contacts) && request.header(h_Contacts).size() >= 1) + { + // Only need to look at first contact - this won't be called for REGISTER messages or 3xx responses + if(request.header(h_Contacts).front().exists(p_geolocation)) + { + parseGeoLocationParameter(request.header(h_Contacts).front().param(p_geolocation), latitude, longitude); + return; + } + } + + // If we cannot determine geo location of target - then return 0,0 + latitude = 0; + longitude = 0; + + // Next - try and find the public IP of the client that sent the request + Tuple publicAddress = Helper::getClientPublicAddress(request); + if(publicAddress.getType() != UNKNOWN_TRANSPORT) + { + // Do a MaxMind GeoIP lookup to determine latitude and longitude + geoIPLookup(publicAddress, &latitude, &longitude); + } +} + +void +GeoProximityTargetSorter::getTargetGeoLocation(const Target& target, double& latitude, double& longitude) +{ + // First check to see if x-repro-geolocation parameter is on Contact header + if(target.rec().mContact.exists(p_geolocation)) + { + parseGeoLocationParameter(target.rec().mContact.param(p_geolocation), latitude, longitude); + return; + } + + // If we cannot determine geo location of client - then return 0,0 + latitude = 0; + longitude = 0; + + // Next - see if we stored a public IP of the client at registration time + if(target.rec().mPublicAddress.getType() != UNKNOWN_TRANSPORT) + { + // Do a MaxMind GeoIP lookup to determine latitude and longitude + geoIPLookup(target.rec().mPublicAddress, &latitude, &longitude); + } + else + { + // Next - see if contact address is public or not + Tuple contactAddress(target.rec().mContact.uri().host(), 0, UNKNOWN_TRANSPORT); + if(!contactAddress.isPrivateAddress()) + { + // Do a MaxMind GeoIP lookup to determine latitude and longitude + geoIPLookup(contactAddress, &latitude, &longitude); + } + } +} + +double +GeoProximityTargetSorter::getTargetDistance(const Target& target, double clientLatitude, double clientLongitude) +{ + if(clientLatitude == 0 && clientLongitude == 0) + { + return (double)mDefaultDistance; + } + double targetLatitude; + double targetLongitude; + getTargetGeoLocation(target, targetLatitude, targetLongitude); + if(targetLatitude == 0 && targetLongitude == 0) + { + return (double)mDefaultDistance; + } + + return calculateDistance(clientLatitude, clientLongitude, targetLatitude, targetLongitude); +} + +void +GeoProximityTargetSorter::parseGeoLocationParameter(const Data& parameter, double& latitude, double& longitude) +{ + ParseBuffer pb(parameter); + + latitude = 0.0; + longitude = 0.0; + Data token; + const char* anchor = pb.position(); + pb.skipToChar(Symbols::COMMA[0]); + pb.data(token, anchor); + latitude = token.convertDouble(); + if(!pb.eof()) + { + pb.skipChar(); + if(!pb.eof()) + { + anchor = pb.position(); + pb.skipToOneOf(",\""); // Skip to comma or end double quote - be tolerant of altitude being specified + pb.data(token, anchor); + longitude = token.convertDouble(); + return; + } + } + DebugLog(<< "GeoProximityTargetSorter: parseGeoLocationParameter - invalid parameter format: " << parameter); +} + +static const double DEG_TO_RAD = 0.017453292519943295769236907684886; +static const double EARTH_RADIUS = 6372.797560856; // km +//static const double EARTH_RADIUS = 3963.0; // miles +double +GeoProximityTargetSorter::calculateDistance(double lat1, double long1, double lat2, double long2) +{ + double dLat = (lat1 - lat2) * DEG_TO_RAD; + double dLong = (long1 - long2) * DEG_TO_RAD; + double hLat = sin(dLat * 0.5); + double hLong = sin(dLong * 0.5); + double distance; + + hLat *= hLat; + hLong *= hLong; + + distance = 2.0 * asin(sqrt(hLat + (cos(lat1*DEG_TO_RAD) * cos(lat2*DEG_TO_RAD)) *hLong)) * EARTH_RADIUS; + return distance; +} + +bool +GeoProximityTargetSorter::geoIPLookup(const Tuple& address, double* latitude, double* longitude, Data* country, Data* region, Data* city) +{ +#ifdef USE_MAXMIND_GEOIP + GeoIPRecord *gir = 0; + // ?slg? - should we introduce a local cache? or is GeoIP library performance good enough? + if(address.ipVersion() == V6) + { + if(mGeoIPv6) + { + gir = GeoIP_record_by_ipnum_v6((GeoIP*)mGeoIPv6, reinterpret_cast<const sockaddr_in6&>(address.getSockaddr()).sin6_addr); + } + } + else + { + if(mGeoIPv4) + { + gir = GeoIP_record_by_ipnum((GeoIP*)mGeoIPv4, ntohl(reinterpret_cast<const sockaddr_in&>(address.getSockaddr()).sin_addr.s_addr)); + } + } + + if(gir != 0) + { + Data countryData(Data::Share, gir->country_code ? gir->country_code : ""); + Data regionData(Data::Share, gir->region ? gir->region : ""); + Data cityData(Data::Share, gir->city ? gir->city : ""); + if(latitude) *latitude = gir->latitude; + if(longitude) *longitude = gir->longitude; + if(country) *country = countryData; + if(region) *region = regionData; + if(city) *city = cityData; + + DebugLog(<< "GeoProximityTargetSorter::geoIPLookup: Tuple=" << address + << ", Country=" << countryData + << ", Region=" << regionData + << ", City=" << cityData + << ", Lat/Long=" << gir->latitude << "/" << gir->longitude); + + GeoIPRecord_delete(gir); + return true; + } + else + { + DebugLog(<< "GeoProximityTargetSorter::geoIPLookup: no geo location information found for Tuple=" << address); + } +#endif + + return false; +} + + +#endif // ndef RESIP_FIXED_POINT + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/monkeys/GeoProximityTargetSorter.hxx b/src/libs/resiprocate/repro/monkeys/GeoProximityTargetSorter.hxx new file mode 100644 index 00000000..a12e77ec --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/GeoProximityTargetSorter.hxx @@ -0,0 +1,164 @@ +#ifndef GEO_PROXIMITY_TARGET_SORTER_HXX +#define GEO_PROXIMITY_TARGET_SORTER_HXX 1 + +#ifndef RESIP_FIXED_POINT + +#ifdef WIN32 +#include <pcreposix.h> +#else +#include <regex.h> +#endif + +#include "repro/Processor.hxx" +#include "repro/ResponseContext.hxx" +#include "repro/ProxyConfig.hxx" + +#include "rutil/Data.hxx" + +namespace resip +{ + class SipMessage; +} + +namespace repro +{ + +class RequestContext; + +/* + If enabled, then this baboon can post-process the target list. + This includes targets from the StaticRoute monkey and/or targets + from the LocationServer monkey. Requests that meet the filter + criteria will have their Target list, flatened (serialized) and + ordered based on the proximity of the target to the client sending + the request. Proximity is determined by looking for a + x-repro-geolocation="<latitude>,<longitude>" parameter on the Contact + header of a received request, or the Contact headers of Registration + requests. If this parameter is not found, then this processor will + attempt to determine the public IP address closest to the client or + target and use the MaxMind Geo IP library to lookup the geo location. + + There are several requirements for using this Processor/Baboon: + 1. RESIP_FIXED_POINT preprocessor define is required to allow floating + point operations required for distance calculations. + 2. USE_MAXMIND_GEOIP preprocessor define is required to allow linking + with the MaxMind Geo IP library for looking up lat/long information + for an IP address. + 3. A copy of the GeoIP City database is required for looking up lat/long + information for an IP address. A free version of the databases can + be downloaded from here: + http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz + and here (v6): + http://geolite.maxmind.com/download/geoip/database/GeoLiteCityv6-beta/ + For a more accurate database, please see the details here: + http://www.maxmind.com/app/city + The location of these files are specifed in the following setting2: + GeoProximityIPv4CityDatabaseFile and GeoProximityIPv6CityDatabaseFile + 4. A request URI filter must be defined in the repro configuration. This + filter uses a PCRE compliant regular expression to attempt + to match against the request URI of inbound requests. Any requests + matching this expression, will have its Targets sorted as described + above. + ie: GeoProximityRequestUriFilter = ^sip:mediaserver.*@mydomain.com$ + + Some additional settings are: + GeoProximityDefaultDistance - The distance (in Kilometers) to use for + proximity sorting, when the Geo Location of a target cannot be + determined. + + LoadBalanceEqualDistantTargets - If enabled, then targets that are + determined to be of equal distance from the client, will be placed in + a random order. +*/ + + +class GeoProximityTargetSorter : public Processor +{ + public: + + static resip::KeyValueStore::Key mGeoTargetSortingDoneKey; + + GeoProximityTargetSorter(ProxyConfig& config); + virtual ~GeoProximityTargetSorter(); + + virtual processor_action_t process(RequestContext &); + + // static fn available for other parts of repro to access the geoip library + // fills in any non-null field + static bool geoIPLookup(const resip::Tuple& address, + double* latitude, + double* longitude, + resip::Data* country=0, + resip::Data* region=0, + resip::Data* city=0); + + protected: + void getClientGeoLocation(const resip::SipMessage& request, double& latitude, double& longitude); + void getTargetGeoLocation(const Target& target, double& latitude, double& longitude); + double getTargetDistance(const Target& target, double clientLatitude, double clientLongitude); + void parseGeoLocationParameter(const resip::Data& parameter, double& latitude, double& longitude); + double calculateDistance(double latitude1, double longitude1, double latitude2, double longitude2); + + resip::Data mRUriRegularExpressionData; + regex_t* mRUriRegularExpression; + + unsigned long mDefaultDistance; + bool mLoadBalanceEqualDistantTargets; + + // Use static instance of the GeoIP library + // - allows static geoIPLookup method + // - reduces memory in cases where multiple instances of GeoProximityTargetSorter are needed + // (take care when creating multipleinstances since static initialization is not mutexed) + static void* mGeoIPv4; + static void* mGeoIPv6; +}; + +} + +#endif // ndef RESIP_FIXED_POINT + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/monkeys/GruuMonkey.cxx b/src/libs/resiprocate/repro/monkeys/GruuMonkey.cxx new file mode 100644 index 00000000..d2306b50 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/GruuMonkey.cxx @@ -0,0 +1,185 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Helper.hxx" +#include "repro/monkeys/GruuMonkey.hxx" +#include "repro/RequestContext.hxx" +#include "repro/Proxy.hxx" +#include "resip/dum/RegistrationPersistence +#include <ostream> + +#include "rutil/Logger.hxx" +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +GruuMonkey::GruuMonkey() +{} + +GruuMonkey::~GruuMonkey() +{} + +Processor::processor_action_t +GruuMonkey::process(RequestContext& context) +{ + DebugLog(<< "Monkey handling request: " << *this + << "; reqcontext = " << context); + + resip::SipMessage& request = context.getOriginalRequest(); + + // sip:alice;uuid:urn:00000-000-8....@example.com;user=gruu + // + // Looking for a Request URI which contains ";user=gruu" + + + // This monkey looks for a Request URIs such as: + // sip:alice@example.com;opaque=uuid:urn:0000-000-89akkskhnasd + // + // Looking for a Request URI which contains an opaque parameter + + + Uri reqUri = request.header(h_RequestLine).uri(); + + if (reqUri.exists(p_opaque)) + { + Uri aor = reqUri.getAor(); + Data instance = reqUri.param(p_opaque); + + // find the GRUU from the AOR and instance + + if (!mStore.mUserStore.aorExists(aor)) + { + // send 404 Not Found + resip::SipMessage response; + InfoLog (<< *this << ": no AOR matching this GRUU found. Gruu: <" << uri << ">, sending 404"); + Helper::makeResponse(response, request, 404); + context.sendResponse(response); + return Processor::SkipThisChain; + } + + if (mStore.isContactRegistered(reqUri.getAor(), reqUri.param(p_opaque))) + { + // grab the grid from the Request URI + Data grid; + if (reqUri.exists(p_grid)) + { + grid = reqUri.params(p_grid); + } + + // walk through the entries that match the instance and aor + RegistrationPersistenceManager::ContactList records = mStore.getRegistrationBinding(aor)->mContacts; + RegistrationPersistenceManager::ContactList::const_iterator i; + + for (i = records.begin(); i != records.end(); ++i) + { + if (i->mInstance == reqUri.param(p_opaque)) + { + NameAddr newTarget = i->mContact.uri(); + // strip caller prefs + // strip instance and flowId + // preserve q-values + if (i->mContact.exists(p_q)) + { + newTarget.param(p_q) = i->mContact.param(p_q); + } + + // copy the grid over from the request URI + if (!grid.empty()) + { + newTarget.uri().param(p_grid) = grid; + } + + // populate the targetSet with appropriate tuple (or sessionId) and URI combo + // !rwm! TODO add a version of addTarget that take the server session id or the Path + // and only uses sendOverExistingConnection + if (i->mSipPath.empty()) + { + assert(i->mServerSessionId) // make sure there is either a Path or a sessionId + context.addTarget(newTarget, i->mServerSessionId); + } + else + { + context.addTarget(newTarget, i->mSipPath); + } + } + + + InfoLog (<< "Sending to requri: " << request.header(h_RequestLine).uri()); + // skip the rest of the monkeys + return Processor::SkipThisChain; + } + else // nobody home with that GRUU + { + // send 480 Temporarily Unavailable + resip::SipMessage response; + InfoLog (<< *this << ": no contacts matching this GRUU found. Gruu: <" << uri << ">, sending 480"); + Helper::makeResponse(response, request, 480); + context.sendResponse(response); + return Processor::SkipThisChain; + } + } + } + return Processor::Continue; +} + + +void +GruuMonkey::dump(std::ostream &os) const +{ + os << "Gruu Monkey" << std::endl; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/GruuMonkey.hxx b/src/libs/resiprocate/repro/monkeys/GruuMonkey.hxx new file mode 100644 index 00000000..237f116c --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/GruuMonkey.hxx @@ -0,0 +1,70 @@ +#if !defined(RESIP_GRUU_REQUEST_PROCESSOR_HXX) +#define RESIP_GRUU_REQUEST_PROCESSOR_HXX +#include "repro/Processor.hxx" + +#include <iosfwd> + +namespace repro +{ + + class GruuMonkey: public Processor + { + public: + GruuMonkey(); + virtual ~GruuMonkey(); + + virtual processor_action_t process(RequestContext &); + virtual void dump(std::ostream &os) const; + }; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/IsTrustedNode.cxx b/src/libs/resiprocate/repro/monkeys/IsTrustedNode.cxx new file mode 100644 index 00000000..184f1a2a --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/IsTrustedNode.cxx @@ -0,0 +1,107 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Transport.hxx" +#include "resip/stack/Helper.hxx" +#include "repro/monkeys/IsTrustedNode.hxx" +#include "repro/RequestContext.hxx" +#include "repro/Proxy.hxx" +#include "repro/ProxyConfig.hxx" +#include "repro/AclStore.hxx" +#include <ostream> + +#include "rutil/Logger.hxx" +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +KeyValueStore::Key IsTrustedNode::mFromTrustedNodeKey = Proxy::allocateRequestKeyValueStoreKey(); + +IsTrustedNode::IsTrustedNode(ProxyConfig& config) : + Processor("IsTrustedNode"), + mAclStore(config.getDataStore()->mAclStore) +{} + +IsTrustedNode::~IsTrustedNode() +{} + +Processor::processor_action_t +IsTrustedNode::process(RequestContext& context) +{ + DebugLog(<< "Monkey handling request: " << *this + << "; reqcontext = " << context); + + resip::SipMessage& request = context.getOriginalRequest(); + + if(mAclStore.isRequestTrusted(request)) + { + context.getKeyValueStore().setBoolValue(mFromTrustedNodeKey, true); + } + else + { + context.getKeyValueStore().setBoolValue(mFromTrustedNodeKey, false); + + // strip PAI headers that we don't trust + if(request.exists(h_PAssertedIdentities)) + { + request.remove(h_PAssertedIdentities); + } + } + + return Processor::Continue; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/IsTrustedNode.hxx b/src/libs/resiprocate/repro/monkeys/IsTrustedNode.hxx new file mode 100644 index 00000000..d9110514 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/IsTrustedNode.hxx @@ -0,0 +1,77 @@ +#if !defined(RESIP_ISTRUSTEDNODE_REQUEST_PROCESSOR_HXX) +#define RESIP_ISTRUSTEDNODE_REQUEST_PROCESSOR_HXX +#include "repro/Processor.hxx" +#include "rutil/KeyValueStore.hxx" + +#include <iosfwd> + +namespace repro +{ + class AclStore; + class ProxyConfig; + + class IsTrustedNode: public Processor + { + public: + static resip::KeyValueStore::Key mFromTrustedNodeKey; + + IsTrustedNode(ProxyConfig& config); + virtual ~IsTrustedNode(); + + virtual processor_action_t process(RequestContext &); + + private: + AclStore& mAclStore; + }; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/LocationServer.cxx b/src/libs/resiprocate/repro/monkeys/LocationServer.cxx new file mode 100644 index 00000000..c5761f0a --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/LocationServer.cxx @@ -0,0 +1,197 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <algorithm> + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/ExtensionParameter.hxx" +#include "repro/monkeys/LocationServer.hxx" +#include "repro/RequestContext.hxx" +#include "repro/UserInfoMessage.hxx" +#include "repro/OutboundTarget.hxx" +#include "repro/QValueTarget.hxx" +#include "repro/Proxy.hxx" +#include "resip/stack/SipStack.hxx" + +#include "rutil/WinLeakCheck.hxx" + + +#include "rutil/Logger.hxx" +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + + +Processor::processor_action_t +LocationServer::process(RequestContext& context) +{ + DebugLog(<< "Monkey handling request: " << *this << "; reqcontext = " << context); + + // UserInfoMessage is used to look for existence of user if we cannot find + // them in the Regisration Database. This code handles the asynchronous + // lookup. + UserInfoMessage *userInfo = dynamic_cast<UserInfoMessage*>(context.getCurrentEvent()); + if(userInfo && userInfo->getOriginatorAddress() == getAddress()) // Ensure we generated the UserInfo - it could be from the Digest Authenticator + { + // If A1 is empty, then user does not exist - return 404 + if(userInfo->A1().empty()) + { + resip::SipMessage response; + Helper::makeResponse(response, context.getOriginalRequest(), 404); + context.sendResponse(response); + return Processor::SkipThisChain; + } + else + { + // User exists, but is just not registered - continue processing + return Processor::Continue; + } + } + + resip::Uri inputUri = context.getOriginalRequest().header(h_RequestLine).uri().getAorAsUri(context.getOriginalRequest().getSource().getType()); + + //!RjS! This doesn't look exception safe - need guards + mStore.lockRecord(inputUri); + + resip::ContactList contacts; + mStore.getContacts(inputUri,contacts); + + if(contacts.size() > 0) + { + TargetPtrList batch; + std::map<resip::Data,resip::ContactList> outboundBatch; + UInt64 now = Timer::getTimeSecs(); + for(resip::ContactList::iterator i = contacts.begin(); i != contacts.end(); ++i) + { + resip::ContactInstanceRecord contact = *i; + if (contact.mRegExpires > now) + { + InfoLog (<< *this << " adding target " << contact.mContact << + " with tuple " << contact.mReceivedFrom); + if(contact.mInstance.empty() || contact.mRegId==0) + { + QValueTarget* target = new QValueTarget(contact); + batch.push_back(target); + } + else + { + outboundBatch[contact.mInstance].push_back(contact); + } + } + else + { + // remove expired contact + mStore.removeContact(inputUri, contact); + } + } + + mStore.unlockRecord(inputUri); + + std::map<resip::Data,resip::ContactList>::iterator o; + + for(o=outboundBatch.begin(); o!=outboundBatch.end(); ++o) + { + o->second.sort(OutboundTarget::instanceCompare); // Orders records by lastUpdate time + OutboundTarget* ot = new OutboundTarget(o->first, o->second); + batch.push_back(ot); + } + + if(!batch.empty()) + { + // Note: some elements of list are already in a sorted order (see outbound bactch sorting + // above), however list::sort is stable, so it's safe to sort twice, as relative order + // of equal elements is preserved +#ifdef __SUNPRO_CC + sort(batch.begin(), batch.end(), Target::priorityMetricCompare); +#else + batch.sort(Target::priorityMetricCompare); +#endif + context.getResponseContext().addTargetBatch(batch, false /* high priority */); + //ResponseContext should be consuming the vector + assert(batch.empty()); + } + } + else + { + mStore.unlockRecord(inputUri); + + if(mUserInfoDispatcher) + { + // User does not have an active registration - check if they even exist or not + // so we know if should send a 404 vs a 480. + // Since users are not kept in memory we need to go to the database asynchrounously + // to look for existance. We will use the existing mechanism in place for asynhcronous + // authentication lookups in order to check for existance - we don't need the returned + // A1 hash, but the efficiency of this request is more than adequate for this purpose. + // Currently repro authentication treats authentication realm the same as users aor domain, + // if this changes in the future we may need to add a different mechanism to check for + // existance. + // Note: repro authentication must be enabled in order for mUserInfoDispatcher to be + // defined and for 404 responses to work + UserInfoMessage* async = new UserInfoMessage(*this, context.getTransactionId(), &(context.getProxy())); + async->user() = inputUri.user(); + async->realm() = inputUri.host(); + async->domain() = inputUri.host(); + std::auto_ptr<ApplicationMessage> app(async); + mUserInfoDispatcher->post(app); + return WaitingForEvent; + } + } + + return Processor::Continue; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/LocationServer.hxx b/src/libs/resiprocate/repro/monkeys/LocationServer.hxx new file mode 100644 index 00000000..4b26095a --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/LocationServer.hxx @@ -0,0 +1,81 @@ +#if !defined(RESIP_LOCATIONSSERVER_REQUEST_PROCESSOR_HXX) +#define RESIP_LOCATIONSERVER_REQUEST_PROCESSOR_HXX +#include "repro/Processor.hxx" +#include "repro/ProxyConfig.hxx" +#include "repro/Dispatcher.hxx" +#include "resip/dum/RegistrationPersistenceManager.hxx" + +namespace repro +{ + + class LocationServer: public Processor + { + public: + LocationServer(ProxyConfig& config, + resip::RegistrationPersistenceManager& store, + Dispatcher* userInfoDispatcher) : + Processor("LocationServer"), + mStore(store), + mUserInfoDispatcher(userInfoDispatcher) + {}; + + virtual ~LocationServer() {}; + + virtual processor_action_t process(RequestContext &); + + private: + resip::RegistrationPersistenceManager& mStore; + Dispatcher* mUserInfoDispatcher; + }; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/MessageSilo.cxx b/src/libs/resiprocate/repro/monkeys/MessageSilo.cxx new file mode 100644 index 00000000..d2dc3bec --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/MessageSilo.cxx @@ -0,0 +1,388 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/dum/ServerRegistration.hxx" +#include "repro/monkeys/MessageSilo.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/PlainContents.hxx" +#include "resip/stack/Helper.hxx" +#include "repro/RequestContext.hxx" +#include "repro/Proxy.hxx" +#include "repro/AsyncProcessorMessage.hxx" +#include "resip/stack/SipStack.hxx" +#include "rutil/Logger.hxx" + +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +#define SILO_CLEANUP_PERIOD 86400 // look for expired records at most every 24 hours (86400 seconds) + +class AsyncAddToSiloMessage : public AsyncProcessorMessage +{ +public: + AsyncAddToSiloMessage(AsyncProcessor& proc, + const resip::Data& tid, + resip::TransactionUser* passedtu): + AsyncProcessorMessage(proc, tid, passedtu) + { + } + + virtual EncodeStream& encode(EncodeStream& strm) const { strm << "AsyncAddToSiloMessage(tid=" << mTid << ", aor=" << mDestUri << ")"; return strm; } + + Data mDestUri; + Data mSourceUri; + time_t mOriginalSendTime; + Data mMimeType; + Data mMessageBody; +}; + +class AsyncDrainSiloMessage : public AsyncProcessorMessage +{ +public: + AsyncDrainSiloMessage(AsyncProcessor& proc, + const resip::Data& tid, + resip::TransactionUser* passedtu): + AsyncProcessorMessage(proc, tid, passedtu) + { + } + + virtual EncodeStream& encode(EncodeStream& strm) const { strm << "AsyncDrainSiloMessage(aor=" << mAor << ")"; return strm; } + + Data mAor; + ContactList mRequestContacts; +}; + +MessageSilo::MessageSilo(ProxyConfig& config, Dispatcher* asyncDispatcher) : + AsyncProcessor("MessageSilo", asyncDispatcher), + mSiloStore(config.getDataStore()->mSiloStore), + mDestFilterRegex(0), + mMimeTypeFilterRegex(0), + mExpirationTime(config.getConfigUnsignedLong("MessageSiloExpirationTime", 2592000 /* 30 days */)), + mAddDateHeader(config.getConfigBool("MessageSiloAddDateHeader", true)), + mMaxContentLength(config.getConfigUnsignedLong("MessageSiloMaxContentLength", 4096)), + mSuccessStatusCode(config.getConfigUnsignedShort("MessageSiloSuccessStatusCode", 202)), + mFilteredMimeTypeStatusCode(config.getConfigUnsignedShort("MessageSiloFilteredMimeTypeStatusCode", 200)), + mFailureStatusCode(config.getConfigUnsignedShort("MessageSiloFailureStatusCode", 480)), + mLastSiloCleanupTime(time(0)) // set to now +{ + Data destFilterRegex = config.getConfigData("MessageSiloDestFilterRegex", "", false); + Data mimeTypeFilterRegex = config.getConfigData("MessageSiloMimeTypeFilterRegex", "application\\/im\\-iscomposing\\+xml", false); + if(!destFilterRegex.empty()) + { + mDestFilterRegex= new regex_t; + int ret = regcomp(mDestFilterRegex, destFilterRegex.c_str(), REG_EXTENDED | REG_NOSUB); + if( ret != 0 ) + { + delete mDestFilterRegex; + ErrLog( << "MessageSilo has invalid destination filter regular expression: " << destFilterRegex); + mDestFilterRegex = 0; + } + } + if(!mimeTypeFilterRegex.empty()) + { + mMimeTypeFilterRegex= new regex_t; + int ret = regcomp(mMimeTypeFilterRegex, mimeTypeFilterRegex.c_str(), REG_EXTENDED | REG_NOSUB); + if( ret != 0 ) + { + delete mMimeTypeFilterRegex; + ErrLog( << "MessageSilo has invalid mime-type filter regular expression: " << mimeTypeFilterRegex); + mMimeTypeFilterRegex = 0; + } + } +} + +MessageSilo::~MessageSilo() +{ + // Clean up pcre memory + if(mDestFilterRegex) + { + regfree(mDestFilterRegex); + delete mDestFilterRegex; + mDestFilterRegex = 0; + } + if(mMimeTypeFilterRegex) + { + regfree(mMimeTypeFilterRegex); + delete mMimeTypeFilterRegex; + mMimeTypeFilterRegex = 0; + } +} + +Processor::processor_action_t +MessageSilo::process(RequestContext& context) +{ + DebugLog(<< "Monkey handling request: " << *this << "; reqcontext = " << context); + SipMessage& originalRequest = context.getOriginalRequest(); + + // Note: A potential enhancement could be to also silo messages that fail to route due to a + // 408 or 503 error. In order to do this, this processor needs to be part of the ResponseChain + // as well. + + // Check if request is a MESSAGE request and if there were no targets found + if(originalRequest.method() == MESSAGE && + !context.getResponseContext().hasTargets()) + { + // There are no targets for this request - silo candidate + + // Only need to silo if there is a message body + Contents* contents = originalRequest.getContents(); + if(contents) + { + // Create async message now, so we can use it's storage and avoid some copies + AsyncAddToSiloMessage* async = new AsyncAddToSiloMessage(*this, context.getTransactionId(), &context.getProxy()); + std::auto_ptr<ApplicationMessage> async_ptr(async); + + // Check Max ContentLength setting + async->mMessageBody = contents->getBodyData(); + if(async->mMessageBody.size() > mMaxContentLength) + { + InfoLog( << " MESSAGE not silo'd due to content-length exceeding max: " << async->mMessageBody.size()); + SipMessage response; + Helper::makeResponse(response, originalRequest, mFailureStatusCode); + context.sendResponse(response); + return SkipThisChain; + } + + // Check if message passes Mime-type filter + async->mMimeType = Data::from(contents->getType()); + if (mMimeTypeFilterRegex) + { + int ret = regexec(mMimeTypeFilterRegex, async->mMimeType.c_str(), 0, 0, 0/*eflags*/); + if (ret == 0) + { + // match + DebugLog( << " MESSAGE not silo'd due to Mime-Type filter: " << async->mMimeType); + if(mFilteredMimeTypeStatusCode == 0) + { + return Processor::Continue; + } + else + { + SipMessage response; + Helper::makeResponse(response, originalRequest, mFilteredMimeTypeStatusCode); + context.sendResponse(response); + return SkipThisChain; + } + } + } + + // Check if message passes Destination filter + async->mDestUri = originalRequest.header(h_To).uri().getAOR(false /* addPort? */); + if (mDestFilterRegex) + { + int ret = regexec(mDestFilterRegex, async->mDestUri.c_str(), 0, 0, 0/*eflags*/); + if (ret == 0) + { + // match + DebugLog( << " MESSAGE not silo'd due to destination filter: " << async->mDestUri); + return Processor::Continue; + } + } + + // TODO (future) - check a max messages per user setting + + NameAddr from(originalRequest.header(h_From)); + from.remove(p_tag); // remove from tag + async->mSourceUri = Data::from(from); + time(&async->mOriginalSendTime); // Get now timestamp + + // Dispatch async request to worker thread pool + mAsyncDispatcher->post(async_ptr); + + SipMessage response; + InfoLog(<<"Message was Silo'd responding with a " << mSuccessStatusCode); + Helper::makeResponse(response, context.getOriginalRequest(), mSuccessStatusCode); + context.sendResponse(response); + return SkipThisChain; + } + } + + // In all cases we continue - this is just a passive monkey that stores MESSAGES for later replay to recipient + return Processor::Continue; +} + +bool +MessageSilo::asyncProcess(AsyncProcessorMessage* msg) +{ + // Running inside a worker thread here + AsyncAddToSiloMessage* addToSilo = dynamic_cast<AsyncAddToSiloMessage*>(msg); + if(addToSilo) + { + // Check if database cleanup period has passed, and if so run a cleanup pass through the database to remove + // silo'd messages that have been stored beyond the MessageSiloExpirationTime. If mExpirationTime is configured + // as 0, then records never expire, so no need to peform the cleanup. + // Note: addToSilo->mOriginalSendTime is always now - so no need to requery current time + // Run cleanup before adding new records to save iterating through 1 extra item + if(mExpirationTime > 0 && (addToSilo->mOriginalSendTime - mLastSiloCleanupTime) > SILO_CLEANUP_PERIOD) + { + mLastSiloCleanupTime = addToSilo->mOriginalSendTime; // reset stored silo cleanup time + + mSiloStore.cleanupExpiredSiloRecords(addToSilo->mOriginalSendTime, mExpirationTime); + } + + // TODO - look for addMessage failures and queue up to be attempted to be written later (ie. when db is back and live) + mSiloStore.addMessage(addToSilo->mDestUri, addToSilo->mSourceUri, addToSilo->mOriginalSendTime, addToSilo->getTransactionId(), addToSilo->mMimeType, addToSilo->mMessageBody); + return false; + } + + AsyncDrainSiloMessage* drainSilo = dynamic_cast<AsyncDrainSiloMessage*>(msg); + if(drainSilo) + { + AbstractDb::SiloRecordList recordList; + if(mSiloStore.getSiloRecords(drainSilo->mAor, recordList)) + { + time_t now = time(0); + + // Note: Tesing with BerkeleyDb and MySQL reveals that these databases return the records in insert order + // so there is no need to sort the records here. + + AbstractDb::SiloRecordList::iterator siloIt = recordList.begin(); + for(; siloIt != recordList.end(); siloIt++) + { + DebugLog(<< "DrainSilo: Dest=" << siloIt->mDestUri << ", Source=" << siloIt->mSourceUri << ", Datetime=" << Data::from(DateCategory(siloIt->mOriginalSentTime)) << ", MimeType=" << siloIt->mMimeType << ", Body=" << siloIt->mMessageBody); + + // Only send if not too old + if((unsigned long)(now - siloIt->mOriginalSentTime) <= mExpirationTime) + { + ContactList::iterator contactIt = drainSilo->mRequestContacts.begin(); + for(; contactIt != drainSilo->mRequestContacts.end(); contactIt++) + { + // send messages to each contact from register message - honour path + ContactInstanceRecord& rec = *contactIt; + + // Removed contacts can be in the list, but they will be expired, don't send to them + if(rec.mRegExpires > (UInt64)now) + { + std::auto_ptr<SipMessage> msg(new SipMessage); + RequestLine rLine(MESSAGE); + rLine.uri() = rec.mContact.uri(); + msg->header(h_RequestLine) = rLine; + msg->header(h_To) = NameAddr(siloIt->mDestUri); + msg->header(h_MaxForwards).value() = 20; + msg->header(h_CSeq).method() = MESSAGE; + msg->header(h_CSeq).sequence() = 1; + msg->header(h_From) = NameAddr(siloIt->mSourceUri); + msg->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); + msg->header(h_CallId).value() = Helper::computeCallId(); + Via via; + msg->header(h_Vias).push_back(via); + + // add routes from registration path + if(!rec.mSipPath.empty()) + { + msg->header(h_Routes).append(rec.mSipPath); + } + + // Add Date Header if enabled + if(mAddDateHeader) + { + msg->header(h_Date) = DateCategory(siloIt->mOriginalSentTime); + } + + if(rec.mUseFlowRouting && + rec.mReceivedFrom.mFlowKey) + { + // .bwc. We only override the destination if we are sending to an + // outbound contact. If this is not an outbound contact, but the + // endpoint has given us a Contact with the correct ip-address and + // port, we might be able to find the connection they formed when they + // registered earlier, but that will happen down in TransportSelector. + msg->setDestination(rec.mReceivedFrom); + } + + // Helper::processStrictRoute(*msg.get()); // Path headers must have ;lr so this isn't required + + // Add mime body + HeaderFieldValue hfv(siloIt->mMessageBody.data(), siloIt->mMessageBody.size()); + Mime type; + ParseBuffer pb(siloIt->mMimeType); + type.parse(pb); + PlainContents contents(hfv, type); + msg->setContents(&contents); // need to clone since body data isn't owned by message yet + + mAsyncDispatcher->mStack->send(msg); + } + } + } + + // Delete record from database + // Note: A potential feature enhancement would be to monitor the MESSAGE reponses and only remove + // from the database when a 200 reponses is seen. Care must be taken to avoid + // looping and handle scenarios when a user never uses a device capable of IM. + mSiloStore.deleteSiloRecord(siloIt->mOriginalSentTime, siloIt->mTid); + } + } + return false; + } + + return false; // Nothing to queue to stack +} + +bool +MessageSilo::onAdd(resip::ServerRegistrationHandle h, const resip::SipMessage& reg) +{ + // Dispatch request to check message silo for newly registered user + AsyncDrainSiloMessage* async = new AsyncDrainSiloMessage(*this, Data::Empty, 0); // tid and tu not needed since no response expected + async->mAor = reg.header(h_To).uri().getAOR(false /* addPort? */); + async->mRequestContacts = h->getRequestContacts(); + std::auto_ptr<ApplicationMessage> async_ptr(async); + mAsyncDispatcher->post(async_ptr); + return true; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/MessageSilo.hxx b/src/libs/resiprocate/repro/monkeys/MessageSilo.hxx new file mode 100644 index 00000000..929de426 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/MessageSilo.hxx @@ -0,0 +1,98 @@ +#if !defined(RESIP_MESSAGESILO_REQUEST_PROCESSOR_HXX) +#define RESIP_MESSAGESILO_REQUEST_PROCESSOR_HXX + +#ifdef WIN32 +#include <pcreposix.h> +#else +#include <regex.h> +#endif + +#include "repro/AsyncProcessor.hxx" +#include "repro/ProxyConfig.hxx" +#include "repro/Registrar.hxx" + +namespace repro +{ + +class MessageSilo: public AsyncProcessor, + public RegistrarHandler +{ +public: + MessageSilo(ProxyConfig& config, Dispatcher* asyncDispatcher); + virtual ~MessageSilo(); + + virtual processor_action_t process(RequestContext &); + virtual bool asyncProcess(AsyncProcessorMessage* msg); + + // Registrar Handlers + virtual bool onRefresh(resip::ServerRegistrationHandle, const resip::SipMessage& reg) { return true; } + virtual bool onRemove(resip::ServerRegistrationHandle, const resip::SipMessage& reg) { return true; } + virtual bool onRemoveAll(resip::ServerRegistrationHandle, const resip::SipMessage& reg) { return true; } + virtual bool onAdd(resip::ServerRegistrationHandle, const resip::SipMessage& reg); + virtual bool onQuery(resip::ServerRegistrationHandle, const resip::SipMessage& reg) { return true; } + +private: + SiloStore& mSiloStore; + regex_t *mDestFilterRegex; + regex_t *mMimeTypeFilterRegex; + unsigned long mExpirationTime; + bool mAddDateHeader; + unsigned long mMaxContentLength; + unsigned short mSuccessStatusCode; + unsigned short mFilteredMimeTypeStatusCode; + unsigned short mFailureStatusCode; + time_t mLastSiloCleanupTime; +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/OutboundTargetHandler.cxx b/src/libs/resiprocate/repro/monkeys/OutboundTargetHandler.cxx new file mode 100644 index 00000000..87edd04d --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/OutboundTargetHandler.cxx @@ -0,0 +1,126 @@ +#include "repro/monkeys/OutboundTargetHandler.hxx" + +#include "rutil/Logger.hxx" +#include "resip/stack/InteropHelper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "repro/OutboundTarget.hxx" +#include "repro/ResponseContext.hxx" +#include "repro/RequestContext.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +namespace repro +{ + +OutboundTargetHandler::OutboundTargetHandler(resip::RegistrationPersistenceManager& store) : + Processor("OutboundTargetHandler"), + mRegStore(store) +{ +} + +OutboundTargetHandler::~OutboundTargetHandler() +{ +} + +Processor::processor_action_t +OutboundTargetHandler::process(RequestContext & rc) +{ + resip::Message* msg = rc.getCurrentEvent(); + ResponseContext& rsp = rc.getResponseContext(); + if(!msg) + { + return Processor::Continue; + } + + // !bwc! Check to see whether we need to move on to another reg-id + resip::SipMessage* sip = dynamic_cast<resip::SipMessage*>(msg); + if(sip && sip->isResponse() && sip->header(resip::h_StatusLine).responseCode() > 299) + { + const resip::Data& tid=sip->getTransactionId(); + DebugLog(<<"Looking for tid " << tid); + Target* target = rsp.getTarget(tid); + assert(target); + OutboundTarget* ot = dynamic_cast<OutboundTarget*>(target); + if(ot) + { + int flowDeadCode; + if(resip::InteropHelper::getOutboundVersion() >= 5) + { + flowDeadCode=430; + } + else + { + flowDeadCode=410; + } + if(sip->header(resip::h_StatusLine).responseCode()==flowDeadCode || // Remote or locally(stack) generate 430 + (sip->getReceivedTransport() == 0 && + (sip->header(resip::h_StatusLine).responseCode()==408 || // Locally (stack) generated 408 or 503 + sip->header(resip::h_StatusLine).responseCode()==503))) + { + // Flow is dead remove contact from Location Database + resip::Uri inputUri(ot->getAor()); + + //!RjS! This doesn't look exception safe - need guards + mRegStore.lockRecord(inputUri); + mRegStore.removeContact(inputUri,ot->rec()); + mRegStore.unlockRecord(inputUri); + + std::auto_ptr<Target> newTarget(ot->nextInstance()); + if(newTarget.get()) + { + // Try next reg-id + rsp.addTarget(newTarget); + return Processor::SkipAllChains; + } + } + } + } + + return Processor::Continue; +} + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/monkeys/OutboundTargetHandler.hxx b/src/libs/resiprocate/repro/monkeys/OutboundTargetHandler.hxx new file mode 100644 index 00000000..361b90c2 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/OutboundTargetHandler.hxx @@ -0,0 +1,68 @@ +#ifndef OUTBOUND_TARGET_HANDLER +#define OUTBOUND_TARGET_HANDLER 1 + +#include "repro/Processor.hxx" +#include "resip/dum/RegistrationPersistenceManager.hxx" + +namespace repro +{ + +class OutboundTargetHandler : public Processor +{ + public: + OutboundTargetHandler(resip::RegistrationPersistenceManager& store); + virtual ~OutboundTargetHandler(); + + virtual processor_action_t process(RequestContext &); + + private: + resip::RegistrationPersistenceManager& mRegStore; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/monkeys/QValueTargetHandler.cxx b/src/libs/resiprocate/repro/monkeys/QValueTargetHandler.cxx new file mode 100644 index 00000000..64665f47 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/QValueTargetHandler.cxx @@ -0,0 +1,411 @@ +#include "repro/monkeys/QValueTargetHandler.hxx" + + +#include "repro/RequestContext.hxx" +#include "repro/ResponseContext.hxx" +#include "repro/Proxy.hxx" +#include "repro/ForkControlMessage.hxx" +#include "repro/QValueTarget.hxx" + +#include "rutil/Data.hxx" +#include "rutil/Logger.hxx" +#include "repro/ProxyConfig.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +namespace repro +{ + +QValueTargetHandler::QValueTargetHandler(ProxyConfig& config) : + Processor("QValueTargetHandler") +{ + mForkBehavior=QValueTargetHandler::EQUAL_Q_PARALLEL; + + if(config.getConfigData("QValueBehavior", "") =="FULL_SEQUENTIAL") + { + mForkBehavior=QValueTargetHandler::FULL_SEQUENTIAL; + } + else if(config.getConfigData("QValueBehavior", "") == "FULL_PARALLEL") + { + mForkBehavior=QValueTargetHandler::FULL_PARALLEL; + } + + mCancelBetweenForkGroups=config.getConfigBool("QValueCancelBetweenForkGroups", true); + mWaitForTerminate=config.getConfigBool("QValueWaitForTerminateBetweenForkGroups", true); + mDelayBetweenForkGroups=config.getConfigInt("QValueMsBetweenForkGroups", 3000); + mCancellationDelay=config.getConfigInt("QValueMsBeforeCancel", 30000); +} + +QValueTargetHandler::~QValueTargetHandler() +{ +} + +Processor::processor_action_t +QValueTargetHandler::process(RequestContext &rc) +{ + std::vector<resip::Data> nextCancelTids; + std::vector<resip::Data> nextBeginTids; + + Proxy* proxy=&(rc.getProxy()); + + resip::Data tid = rc.getTransactionId(); + ResponseContext& rsp=rc.getResponseContext(); + bool shouldContinue=true; + + //Use this as a loop invariant. + bool bail=false; + + resip::Message* msg = rc.getCurrentEvent(); + assert(msg); + + if(msg) + { + repro::ForkControlMessage* fc = dynamic_cast<repro::ForkControlMessage*>(msg); + + if(fc) + { + shouldContinue=false; + std::vector<resip::Data>::iterator i; + + //Might we have scheduled cancellations? If so, is there anything else + //worth trying? (We won't cancel stuff if there is nothing else left + //to try) + if(mCancelBetweenForkGroups && rsp.hasCandidateTransactions()) + { + std::vector<resip::Data>& cancelTids=fc->mTransactionsToCancel; + for(i=cancelTids.begin();i!=cancelTids.end();i++) + { + //Calling cancelClientTransaction on an already cancelled + //target is safe, and usually more efficient than checking + //beforehand. + rsp.cancelClientTransaction(*i); + } + } + + //Might we have scheduled some transactions to start? + //(and if we did, should we now schedule them for cancellation later?) + if(!mWaitForTerminate) + { + std::vector<resip::Data>& beginTids=fc->mTransactionsToProcess; + for(i=beginTids.begin();i!=beginTids.end();i++) + { + //Calling beginClientTransaction on an already active + // (or Terminated) transaction is safe, and more + // efficient than checking beforehand. + rsp.beginClientTransaction(*i); + if(mCancelBetweenForkGroups) + { + nextCancelTids.push_back(*i); + } + } + } + } + else + { + DebugLog(<<"No ForkControlMessage for me."); + } + } + + std::list<std::list<resip::Data> >& targetCollection = + rsp.mTransactionQueueCollection; + std::list<std::list<resip::Data> >::iterator outer; + std::list<std::list<resip::Data> >::iterator temp; + std::list<resip::Data>::iterator inner; + bool activeTargets=false; + bool startedTargets=false; + + for(outer=targetCollection.begin(); + outer!=targetCollection.end() && !activeTargets;) + { + inner=outer->begin(); + + if(inner!=outer->end() && isMyType(rsp.getTarget(*inner))) + { + DebugLog(<<"QValueTargetHandler: " + <<"Found a queue of QValueTargets. Are any of them active?"); + //Are there active targets in this queue already? + bail=false; + for(;inner!=outer->end() && !bail;inner++) + { + if(rsp.isActive(*inner)) + { + activeTargets=true; + DebugLog(<<"There are active targets. " + <<"I don't need to do anything else yet."); + bail=true; + } + } + + //If no active targets, we need to start some new ones. + //(and schedule their cancellation if configured to) + //However, calling beginClientTransaction does not guarantee that a + //target will start, since that target may be a duplicate. + //So, we keep firing up target groups until something sticks, or we hit + //the end of this queue. + bail=false; + while(!activeTargets && !bail) + { + DebugLog(<<"There are no active targets here. " + <<"Looking for a group to start."); + std::vector<resip::Data> beginTargets; + + fillNextTargetGroup(beginTargets,*outer,rsp); + + if(beginTargets.empty()) + { + DebugLog(<<"There are no more targets to start in this queue." + <<" Trying to find another queue to work on."); + bail=true; + } + else + { + DebugLog(<<"This queue has a group of targets in it. " + <<"Trying to start this group."); + std::vector<resip::Data>::iterator i; + for(i=beginTargets.begin();i!=beginTargets.end();i++) + { + bool success = rsp.beginClientTransaction(*i); + if(success && mCancelBetweenForkGroups) + { + nextCancelTids.push_back(*i); + } + + activeTargets |= success; + startedTargets |= success; + } + if(startedTargets) + { + DebugLog(<<"Successfully started some targets."); + } + else + { + DebugLog(<<"None of these Targets were valid!" + << " Moving on to another group."); + } + } + } + + if(!startedTargets) + { + DebugLog(<< "There weren't any valid Targets in this queue!"); + } + //If we just started some targets, and we are not supposed to wait + //for these targets to terminate before beginning the next group + //in this queue, we should schedule the next group now. + //If there is no next group, nextBeginTids will be empty. + if(startedTargets && !mWaitForTerminate) + { + DebugLog(<<"Now I need to schedule the next group of Targets."); + fillNextTargetGroup(nextBeginTids,*outer,rsp); + } + + //Clean up the queue we just tried + removeTerminated(*outer,rsp); + } + + if(outer->empty()) + { + temp=outer; + outer++; + targetCollection.erase(temp); + } + else + { + outer++; + } + + assert(activeTargets || !startedTargets); + } + + //Do we have anything to schedule for later? + if(!nextCancelTids.empty() || !nextBeginTids.empty()) + { + // If the delays are equal, then put both cancel and nextBeginTids in one ForkControlMessage + if(mCancellationDelay == mDelayBetweenForkGroups) + { + ForkControlMessage* fork = new ForkControlMessage(*this,tid,proxy); + fork->mTransactionsToProcess=nextBeginTids; + fork->mTransactionsToCancel=nextCancelTids; + + resip::ApplicationMessage* app= + dynamic_cast<resip::ApplicationMessage*>(fork); + + proxy->postMS(std::auto_ptr<resip::ApplicationMessage>(app), + mDelayBetweenForkGroups); + } + else // Issue two seperate ForkControlMessages + { + if(!nextCancelTids.empty()) + { + ForkControlMessage* cancel = new ForkControlMessage(*this,tid,proxy); + cancel->mTransactionsToCancel=nextCancelTids; + + resip::ApplicationMessage* app= + dynamic_cast<resip::ApplicationMessage*>(cancel); + + rc.getProxy().postMS(std::auto_ptr<resip::ApplicationMessage>(app), + mCancellationDelay); + } + if(!nextBeginTids.empty()) + { + ForkControlMessage* begin = new ForkControlMessage(*this,tid,proxy); + begin->mTransactionsToProcess=nextBeginTids; + + resip::ApplicationMessage* app + =dynamic_cast<resip::ApplicationMessage*>(begin); + + proxy->postMS(std::auto_ptr<resip::ApplicationMessage>(app), + mDelayBetweenForkGroups); + } + } + } + + //We should not pass control on to the rest of the chain until all + //of the QValueTargets have been taken care of. Also, we should not + //pass control to the rest of the chain if we received a + //ForkControlMessage explicitly intended for us. + //(this could confuse the other Target Processors) + if(!activeTargets && shouldContinue) + { + return Processor::Continue; + } + else + { + return Processor::SkipAllChains; + } +} + +void +QValueTargetHandler::fillNextTargetGroup(std::vector<resip::Data>& fillHere, + const std::list<resip::Data> & queue, + const ResponseContext& rsp) const +{ + if(queue.empty()) + { + return; + } + + std::list<resip::Data>::const_iterator i = queue.begin(); + int currentQ=0; + + //Find the first Candidate target in the queue. + for(i=queue.begin();i!=queue.end();i++) + { + if(rsp.isCandidate(*i)) + { + currentQ=rsp.getTarget(*i)->getPriority(); + break; + } + } + + switch(mForkBehavior) + { + case FULL_SEQUENTIAL: + if(i!=queue.end()) + { + fillHere.push_back(*i); + } + break; + + case EQUAL_Q_PARALLEL: + while(i!=queue.end() && rsp.getTarget(*i)->getPriority()==currentQ) + { + fillHere.push_back(*i); + i++; + } + break; + + case FULL_PARALLEL: + while(i!=queue.end()) + { + fillHere.push_back(*i); + i++; + } + break; + + default: + ErrLog(<<"mForkBehavior is not defined! How did this happen?"); + } +} + +bool +QValueTargetHandler::isMyType( Target* target) const +{ + QValueTarget* qt = dynamic_cast<QValueTarget*>(target); + if(qt) + { + return true; + } + else + { + return false; + } +} + +void +QValueTargetHandler::removeTerminated(std::list<resip::Data> & queue, + const ResponseContext& rsp) const +{ + std::list<resip::Data>::iterator i = queue.begin(); + + while(i!=queue.end()) + { + if(rsp.isTerminated(*i)) + { + std::list<resip::Data>::iterator temp=i; + i++; + queue.erase(temp); + } + else + { + i++; + } + } +} + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/monkeys/QValueTargetHandler.hxx b/src/libs/resiprocate/repro/monkeys/QValueTargetHandler.hxx new file mode 100644 index 00000000..c7cc360a --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/QValueTargetHandler.hxx @@ -0,0 +1,95 @@ +#ifndef Q_VALUE_TARGET_HANDLER_HXX +#define Q_VALUE_TARGET_HANDLER_HXX 1 + +#include "repro/Processor.hxx" +#include "repro/ResponseContext.hxx" +#include "repro/ProxyConfig.hxx" + +#include "rutil/Data.hxx" +#include <vector> + +namespace repro +{ + +class RequestContext; + +class QValueTargetHandler : public Processor +{ + public: + + typedef enum + { + FULL_SEQUENTIAL, + EQUAL_Q_PARALLEL, + FULL_PARALLEL + } ForkBehavior; + + QValueTargetHandler(ProxyConfig& config); + virtual ~QValueTargetHandler(); + + virtual processor_action_t process(RequestContext &); + + void fillNextTargetGroup(std::vector<resip::Data>& fillHere, + const std::list<resip::Data>& queue, + const ResponseContext& rsp) const; + + virtual bool isMyType( Target* target) const; + + virtual void removeTerminated(std::list<resip::Data>& queue, + const ResponseContext& rsp) const; + + protected: + ForkBehavior mForkBehavior; + bool mCancelBetweenForkGroups; + bool mWaitForTerminate; + int mDelayBetweenForkGroups; + int mCancellationDelay; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/monkeys/RecursiveRedirect.cxx b/src/libs/resiprocate/repro/monkeys/RecursiveRedirect.cxx new file mode 100644 index 00000000..cd97869d --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/RecursiveRedirect.cxx @@ -0,0 +1,109 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <algorithm> + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/NameAddr.hxx" +#include "repro/monkeys/RecursiveRedirect.hxx" +#include "repro/RequestContext.hxx" +#include "repro/QValueTarget.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +RecursiveRedirect::RecursiveRedirect() : + Processor("RecursiveRedirectHandler") +{} + + +RecursiveRedirect::~RecursiveRedirect() +{} + + +Processor::processor_action_t +RecursiveRedirect::process(RequestContext& context) +{ + DebugLog(<< "Lemur handling request: " << *this + << "; reqcontext = " << context); + + const SipMessage* response = dynamic_cast<const SipMessage*>(context.getCurrentEvent()); + if (response && + response->isResponse() && + response->header(h_StatusLine).statusCode() / 100 == 3) + { + TargetPtrList batch; + for (NameAddrs::const_iterator i=response->header(h_Contacts).begin(); + i != response->header(h_Contacts).end(); ++i) + { + if(i->isWellFormed() && !i->isAllContacts()) + { + QValueTarget* target = new QValueTarget(*i); + batch.push_back(target); + } + } + if(!batch.empty()) + { +#ifdef __SUNPRO_CC + sort(batch.begin(), batch.end(), Target::priorityMetricCompare); +#else + batch.sort(Target::priorityMetricCompare); +#endif + context.getResponseContext().addTargetBatch(batch); + //ResponseContext should be consuming the vector + assert(batch.empty()); + } + return Processor::SkipAllChains; + } + return Processor::Continue; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/monkeys/RecursiveRedirect.hxx b/src/libs/resiprocate/repro/monkeys/RecursiveRedirect.hxx new file mode 100644 index 00000000..d61914ca --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/RecursiveRedirect.hxx @@ -0,0 +1,69 @@ +#if !defined(RESIP_RECURSIVE_REDIRECT_HXX) +#define RESIP_RECURSIVE_REDIRECT_HXX + +#include "repro/Processor.hxx" + +namespace repro +{ + +class RecursiveRedirect: public Processor +{ + public: + RecursiveRedirect(); + virtual ~RecursiveRedirect(); + + virtual processor_action_t process(RequestContext &); +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/RequestFilter.cxx b/src/libs/resiprocate/repro/monkeys/RequestFilter.cxx new file mode 100644 index 00000000..4dced32d --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/RequestFilter.cxx @@ -0,0 +1,262 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/Logger.hxx" + +#include "repro/AsyncProcessorMessage.hxx" +#include "repro/monkeys/RequestFilter.hxx" +#include "repro/RequestContext.hxx" +#include "repro/FilterStore.hxx" +#include "repro/Proxy.hxx" +#ifdef USE_MYSQL +#include "repro/MySqlDb.hxx" +#endif +#include "resip/stack/SipStack.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +class RequestFilterAsyncMessage : public AsyncProcessorMessage +{ +public: + RequestFilterAsyncMessage(AsyncProcessor& proc, + const resip::Data& tid, + TransactionUser* passedtu, + Data& query) : + AsyncProcessorMessage(proc,tid,passedtu), + mQuery(query) + { + } + + virtual EncodeStream& encode(EncodeStream& strm) const { strm << "RequestFilterAsyncMessage(tid=" << mTid << ")"; return strm; } + + Data mQuery; + int mQueryResult; + std::vector<Data> mQueryResultData; +}; + +RequestFilter::RequestFilter(ProxyConfig& config, + Dispatcher* asyncDispatcher) : + AsyncProcessor("RequestFilter", asyncDispatcher), + mFilterStore(config.getDataStore()->mFilterStore), + mMySqlDb(0), + mDefaultNoMatchBehavior(config.getConfigData("RequestFilterDefaultNoMatchBehavior", "")), // Default: empty string = Continue Processing + mDefaultDBErrorBehavior(config.getConfigData("RequestFilterDefaultDBErrorBehavior", "500, Server Internal DB Error")) +{ +#ifdef USE_MYSQL + Data mySQLSettingPrefix("RequestFilter"); + Data mySQLServer = config.getConfigData("RequestFilterMySQLServer", ""); + if(mySQLServer.empty()) + { + // If RequestFilterMySQLServer setting is blank, then fallback to + // RuntimeMySql settings + mySQLSettingPrefix = "Runtime"; + mySQLServer = config.getConfigData("RuntimeMySQLServer", ""); + if(mySQLServer.empty()) + { + // If RuntimeMySQLServer setting is blank, then fallback to + // global MySql settings + mySQLSettingPrefix.clear(); + mySQLServer = config.getConfigData("MySQLServer", ""); + } + } + + if(!mySQLServer.empty()) + { + // Initialize My SQL using Global settings + mMySqlDb = new MySqlDb(mySQLServer, + config.getConfigData(mySQLSettingPrefix + "MySQLUser", ""), + config.getConfigData(mySQLSettingPrefix + "MySQLPassword", ""), + config.getConfigData(mySQLSettingPrefix + "MySQLDatabaseName", ""), + config.getConfigUnsignedLong(mySQLSettingPrefix + "MySQLPort", 0), + Data::Empty); + } +#endif +} + +RequestFilter::~RequestFilter() +{ +} + +short +RequestFilter::parseActionResult(const Data& result, Data& rejectReason) +{ + Data rejectionStatusCode; + ParseBuffer pb(result); + const char* anchor = pb.position(); + pb.skipToChar(','); + pb.data(rejectionStatusCode, anchor); + if(pb.position()[0] == ',') + { + pb.skipChar(); + pb.skipWhitespace(); + anchor = pb.position(); + pb.skipToEnd(); + pb.data(rejectReason, anchor); + } + return (short)rejectionStatusCode.convertInt(); +} + + +Processor::processor_action_t +RequestFilter::applyActionResult(RequestContext &rc, const Data& actionResult) +{ + if(!actionResult.empty()) + { + Data rejectionReason; + short rejectionStatusCode = parseActionResult(actionResult, rejectionReason); + + if(rejectionStatusCode >= 400 && rejectionStatusCode < 600) + { + // Blocked - reject request + SipMessage response; + InfoLog(<<"Request is blocked - responding with a " << rejectionStatusCode << ", customReason=" << rejectionReason); + Helper::makeResponse(response, rc.getOriginalRequest(), rejectionStatusCode, rejectionReason); + rc.sendResponse(response); + return SkipThisChain; + } + } + + // Not blocked - continue processing + DebugLog(<< "Request is accepted"); + return Continue; +} + +Processor::processor_action_t +RequestFilter::process(RequestContext &rc) +{ + DebugLog(<< "Monkey handling request: " << *this << "; reqcontext = " << rc); + + Message *message = rc.getCurrentEvent(); + + RequestFilterAsyncMessage *async = dynamic_cast<RequestFilterAsyncMessage*>(message); + + if (async) + { + if(async->mQueryResult == 0 && async->mQueryResultData.size() > 0) // If query was successful, then get query result + { + InfoLog(<< "RequestFilter query completed successfully: queryResult=" << async->mQueryResult << ", resultData=" << async->mQueryResultData.front()); + + return applyActionResult(rc, async->mQueryResultData.front()); + } + else + { + InfoLog(<< "RequestFilter query failed: queryResult=" << async->mQueryResult); + + return applyActionResult(rc, mDefaultDBErrorBehavior); + } + } + else + { + short action; + Data actionData; + if(mFilterStore.process(rc.getOriginalRequest(), action, actionData)) + { + // Match found + switch(action) + { + case FilterStore::Reject: + return applyActionResult(rc, actionData); + case FilterStore::SQLQuery: + if(mMySqlDb) + { + // Dispatch async + std::auto_ptr<ApplicationMessage> async(new RequestFilterAsyncMessage(*this, rc.getTransactionId(), &rc.getProxy(), actionData)); + mAsyncDispatcher->post(async); + return WaitingForEvent; + } + else + { + // No DB - use default DB Error behavior + WarningLog(<< "Request filter with action type SQL Query exists, however there is no MySQL support compiled in, using DefaultDBErrorBehavior"); + return applyActionResult(rc, mDefaultDBErrorBehavior); + } + case FilterStore::Accept: + default: + DebugLog(<< "Request is accepted"); + return Continue; + } + } + else + { + // No Match found - apply default behavior + return applyActionResult(rc, mDefaultNoMatchBehavior); + } + } +} + +bool +RequestFilter::asyncProcess(AsyncProcessorMessage* msg) +{ + RequestFilterAsyncMessage* async = dynamic_cast<RequestFilterAsyncMessage*>(msg); + assert(async); + +#ifdef USE_MYSQL + if(mMySqlDb) + { + async->mQueryResult = mMySqlDb->singleResultQuery(async->mQuery, async->mQueryResultData); + return true; + } +#else + assert(false); + async->mQueryResult = -1; +#endif + return false; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/RequestFilter.hxx b/src/libs/resiprocate/repro/monkeys/RequestFilter.hxx new file mode 100644 index 00000000..25838969 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/RequestFilter.hxx @@ -0,0 +1,91 @@ +#if !defined(RESIP_REQUESTFILTER_HXX) +#define RESIP_REQUESTFILTER_HXX + +#include "rutil/Data.hxx" +#include "repro/AsyncProcessor.hxx" +#include "repro/ProxyConfig.hxx" + +namespace resip +{ + class SipStack; +} + +namespace repro +{ +class MySqlDb; +class FilterStore; + +class RequestFilter : public AsyncProcessor +{ + public: + RequestFilter(ProxyConfig& config, Dispatcher* asyncDispatcher); + ~RequestFilter(); + + // Processor virutal method + virtual processor_action_t process(RequestContext &); + + // Virtual method called from WorkerThreads + virtual bool asyncProcess(AsyncProcessorMessage* msg); + + private: + short parseActionResult(const resip::Data& result, resip::Data& rejectReason); + processor_action_t applyActionResult(RequestContext &rc, const resip::Data& actionResult); + + FilterStore& mFilterStore; + MySqlDb* mMySqlDb; + resip::Data mDefaultNoMatchBehavior; + resip::Data mDefaultDBErrorBehavior; +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/SimpleStaticRoute.cxx b/src/libs/resiprocate/repro/monkeys/SimpleStaticRoute.cxx new file mode 100644 index 00000000..14176888 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/SimpleStaticRoute.cxx @@ -0,0 +1,115 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "repro/Proxy.hxx" +#include "repro/ProxyConfig.hxx" +#include "repro/RequestContext.hxx" +#include "repro/monkeys/SimpleStaticRoute.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/NameAddr.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + + +SimpleStaticRoute::SimpleStaticRoute(ProxyConfig& config) : + Processor("SimpleStaticRoute") +{ + std::vector<Data> routeSet; + config.getConfigValue("Routes", routeSet); + + resip::NameAddrs routes; + for (std::vector<Data>::iterator i=routeSet.begin(); + i != routeSet.end(); ++i) + { + try + { + mRouteSet.push_back(NameAddr(*i)); + } + catch(BaseException& ex) + { + WarningLog(<< "SimpleStaticRoute: Skipping invalid route (" << *i << "): " << ex); + } + } +} + +SimpleStaticRoute::~SimpleStaticRoute() +{} + + +Processor::processor_action_t +SimpleStaticRoute::process(RequestContext& context) +{ + DebugLog(<< "Monkey handling request: " << *this + << "; reqcontext = " << context); + + resip::SipMessage& request = context.getOriginalRequest(); + const Uri& uri = request.header(h_RequestLine).uri(); + if (context.getProxy().isMyUri(uri)) + { + const resip::NameAddrs& current = request.header(h_Routes); + resip::NameAddrs replace = mRouteSet; + for (resip::NameAddrs::const_iterator i=current.begin(); i != current.end(); ++i) + { + replace.push_back(*i); + } + request.header(h_Routes) = replace; + context.getResponseContext().addTarget(NameAddr(uri)); + + InfoLog (<< "New route set is " << Inserter(request.header(h_Routes))); + } + + return Processor::Continue; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/monkeys/SimpleStaticRoute.hxx b/src/libs/resiprocate/repro/monkeys/SimpleStaticRoute.hxx new file mode 100644 index 00000000..83a4f637 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/SimpleStaticRoute.hxx @@ -0,0 +1,74 @@ +#if !defined(RESIP_SIMPLESTATICROUTE_HXX) +#define RESIP_SIMPLESTATICROUTE_HXX + +#include "repro/Processor.hxx" + +namespace repro +{ +class RouteStore; +class ProxyConfig; + +class SimpleStaticRoute: public Processor +{ + public: + SimpleStaticRoute(ProxyConfig& config); + virtual ~SimpleStaticRoute(); + + virtual processor_action_t process(RequestContext &); + + private: + resip::NameAddrs mRouteSet; +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/SimpleTargetHandler.cxx b/src/libs/resiprocate/repro/monkeys/SimpleTargetHandler.cxx new file mode 100644 index 00000000..9b388b1f --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/SimpleTargetHandler.cxx @@ -0,0 +1,94 @@ +#include "repro/monkeys/SimpleTargetHandler.hxx" + +#include "repro/RequestContext.hxx" +#include "repro/ResponseContext.hxx" + +namespace repro +{ + +SimpleTargetHandler::SimpleTargetHandler() : + Processor("SimpleTargetHandler") +{ +} + +SimpleTargetHandler::~SimpleTargetHandler() +{ +} + +Processor::processor_action_t +SimpleTargetHandler::process(RequestContext &rc) +{ + ResponseContext& rsp=rc.getResponseContext(); + + std::list<std::list<resip::Data> >& tidBank = rsp.mTransactionQueueCollection; + std::list<std::list<resip::Data> >::iterator outer=tidBank.begin(); + while(!rsp.hasActiveTransactions() && outer!=tidBank.end()) + { + for(; outer!=tidBank.end() && !rsp.hasActiveTransactions(); outer++) + { + std::list<resip::Data>::const_iterator i; + for(i=outer->begin();i!=outer->end();i++) + { + rsp.beginClientTransaction(*i); + } + } + } + + if(rsp.hasActiveTransactions()) + { + return Processor::SkipAllChains; + } + else + { + //If after all this we still don't have any active transactions, + //make it a free-for-all. + rsp.beginClientTransactions(); + return Processor::Continue; + } +} + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/monkeys/SimpleTargetHandler.hxx b/src/libs/resiprocate/repro/monkeys/SimpleTargetHandler.hxx new file mode 100644 index 00000000..24949f48 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/SimpleTargetHandler.hxx @@ -0,0 +1,65 @@ +#ifndef SIMPLE_TARGET_HANDLER_HXX +#define SIMPLE_TARGET_HANDLER_HXX 1 + +#include "repro/Processor.hxx" + +namespace repro +{ +class RequestContext; + +class SimpleTargetHandler : public Processor +{ + public: + SimpleTargetHandler(); + virtual ~SimpleTargetHandler(); + + virtual processor_action_t process(RequestContext &); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/monkeys/StaticRoute.cxx b/src/libs/resiprocate/repro/monkeys/StaticRoute.cxx new file mode 100644 index 00000000..fd36936b --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/StaticRoute.cxx @@ -0,0 +1,168 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Helper.hxx" +#include "repro/monkeys/CertificateAuthenticator.hxx" +#include "repro/monkeys/StaticRoute.hxx" +#include "repro/monkeys/IsTrustedNode.hxx" +#include "repro/RequestContext.hxx" +#include "repro/QValueTarget.hxx" + +#include "rutil/Logger.hxx" +#include "repro/RouteStore.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + +StaticRoute::StaticRoute(ProxyConfig& config) : + Processor("StaticRoute"), + mRouteStore(config.getDataStore()->mRouteStore), + mNoChallenge(config.getConfigBool("DisableAuth", false)), + mParallelForkStaticRoutes(config.getConfigBool("ParallelForkStaticRoutes", false)), + mContinueProcessingAfterRoutesFound(config.getConfigBool("ContinueProcessingAfterRoutesFound", false)), + mUseAuthInt(!config.getConfigBool("DisableAuthInt", false)) +{} + +StaticRoute::~StaticRoute() +{} + +Processor::processor_action_t +StaticRoute::process(RequestContext& context) +{ + DebugLog(<< "Monkey handling request: " << *this + << "; reqcontext = " << context); + + SipMessage& msg = context.getOriginalRequest(); + + Uri ruri(msg.header(h_RequestLine).uri()); + Data method(getMethodName(msg.header(h_RequestLine).method())); + Data event; + if ( msg.exists(h_Event) && msg.header(h_Event).isWellFormed()) + { + event = msg.header(h_Event).value() ; + } + + RouteStore::UriList targets(mRouteStore.process( ruri, + method, + event)); + bool requireAuth = false; + if(!context.getKeyValueStore().getBoolValue(IsTrustedNode::mFromTrustedNodeKey) && + msg.method() != ACK && // Don't challenge ACK and BYE requests + msg.method() != BYE) + { + requireAuth = !mNoChallenge; + //for ( RouteStore::UriList::const_iterator i = targets.begin(); + // i != targets.end(); i++ ) + //{ + // !rwm! TODO would be useful to check if these targets require authentication + // but for know we will just fail safe and assume that all routes require auth + // if the sender is not trusted + // requireAuth |= !mNoChallenge; + //} + } + + if (requireAuth && context.getDigestIdentity().empty() && + !context.getKeyValueStore().getBoolValue(CertificateAuthenticator::mCertificateVerifiedKey)) + { + // !rwm! TODO do we need anything more sophisticated to figure out the realm? + Data realm = msg.header(h_RequestLine).uri().host(); + + challengeRequest(context, realm); + return Processor::SkipAllChains; + } + else + { + TargetPtrList parallelBatch; + for (RouteStore::UriList::const_iterator i = targets.begin(); + i != targets.end(); i++ ) + { + //Targets are only added after authentication + InfoLog(<< "Adding target " << *i ); + + if(mParallelForkStaticRoutes) + { + Target* target = new Target(*i); + parallelBatch.push_back(target); + } + else + { + // Add Simple Target + context.getResponseContext().addTarget(NameAddr(*i)); + } + } + if(parallelBatch.size() > 0) + { + context.getResponseContext().addTargetBatch(parallelBatch, false /* highPriority */); + } + + if(!targets.empty() && !mContinueProcessingAfterRoutesFound) + { + return Processor::SkipThisChain; + } + } + + return Processor::Continue; +} + +void +StaticRoute::challengeRequest(repro::RequestContext &rc, resip::Data &realm) +{ + Message *message = rc.getCurrentEvent(); + SipMessage *sipMessage = dynamic_cast<SipMessage*>(message); + assert(sipMessage); + + SipMessage *challenge = Helper::makeProxyChallenge(*sipMessage, realm, mUseAuthInt /*auth-int*/, false /*stale*/); + rc.sendResponse(*challenge); + + delete challenge; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/repro/monkeys/StaticRoute.hxx b/src/libs/resiprocate/repro/monkeys/StaticRoute.hxx new file mode 100644 index 00000000..e3ca6631 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/StaticRoute.hxx @@ -0,0 +1,79 @@ +#if !defined(RESIP_STATICROUTE_HXX) +#define RESIP_STATICROUTE_HXX + +#include "repro/Processor.hxx" +#include "repro/ProxyConfig.hxx" + +namespace repro +{ +class RouteStore; + +class StaticRoute: public Processor +{ + public: + StaticRoute(ProxyConfig& config); + virtual ~StaticRoute(); + + virtual processor_action_t process(RequestContext &); + + private: + RouteStore& mRouteStore; + bool mNoChallenge; + bool mParallelForkStaticRoutes; + bool mContinueProcessingAfterRoutesFound; + bool mUseAuthInt; + void challengeRequest(repro::RequestContext &rc, resip::Data &realm); +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/StrictRouteFixup.cxx b/src/libs/resiprocate/repro/monkeys/StrictRouteFixup.cxx new file mode 100644 index 00000000..d304c178 --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/StrictRouteFixup.cxx @@ -0,0 +1,128 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/SipMessage.hxx" +#include "repro/monkeys/StrictRouteFixup.hxx" +#include "repro/RequestContext.hxx" +#include "repro/Proxy.hxx" + +#include "resip/stack/Helper.hxx" + +#include "rutil/Logger.hxx" +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace resip; +using namespace repro; +using namespace std; + + +StrictRouteFixup::StrictRouteFixup() : + Processor("StrictRouteFixup") +{} + +StrictRouteFixup::~StrictRouteFixup() +{} + +/** @brief This monkey looks to see if the request has + * a Route header (the RequestContext has already + * done preprocessing, and has removed any topmost + * route that was self). If there is, the previous + * hop was a strict routing proxy and the candidate + * set is exactly the RURI of the received request + * (after the above preprocessing). + */ +Processor::processor_action_t +StrictRouteFixup::process(RequestContext& context) +{ + DebugLog(<< "Monkey handling request: " << *this + << "; reqcontext = " << context); + + resip::SipMessage& request = context.getOriginalRequest(); + + if (request.exists(h_Routes) && + !request.header(h_Routes).empty()) + { + if(!request.header(h_Routes).front().isWellFormed()) + { + // Garbage topmost Route, reject + SipMessage resp; + resip::Helper::makeResponse(resp, request, 400, "Garbage Route Header."); + context.sendResponse(resp); + return SkipAllChains; + } + + // Do any required session accounting + context.getProxy().doSessionAccounting(request, true /* received */, context); + + //Will cancel any active transactions (ideally there should be none) + //and terminate any pending transactions. + context.getResponseContext().cancelAllClientTransactions(); + std::auto_ptr<Target> target(new Target(request.header(h_RequestLine).uri())); + if(!context.getTopRoute().uri().user().empty()) + { + resip::Tuple source(Tuple::makeTupleFromBinaryToken(context.getTopRoute().uri().user().base64decode(), Proxy::FlowTokenSalt)); + if(!(source==resip::Tuple())) + { + // valid flow token + target->rec().mReceivedFrom = source; + target->rec().mUseFlowRouting = true; + } + } + context.getResponseContext().addTarget(target); + return Processor::SkipThisChain; + } + + return Processor::Continue; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/monkeys/StrictRouteFixup.hxx b/src/libs/resiprocate/repro/monkeys/StrictRouteFixup.hxx new file mode 100644 index 00000000..fa325f5f --- /dev/null +++ b/src/libs/resiprocate/repro/monkeys/StrictRouteFixup.hxx @@ -0,0 +1,67 @@ +#if !defined(RESIP_STRICT_ROUTE_FIXUP_HXX) +#define RESIP_STRICT_ROUTE_FIXUP_HXX +#include "repro/Processor.hxx" + +namespace repro +{ + + class StrictRouteFixup: public Processor + { + public: + StrictRouteFixup(); + virtual ~StrictRouteFixup(); + + virtual processor_action_t process(RequestContext &); + }; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/repro/php/NOTES.text b/src/libs/resiprocate/repro/php/NOTES.text new file mode 100644 index 00000000..279e625c --- /dev/null +++ b/src/libs/resiprocate/repro/php/NOTES.text @@ -0,0 +1,17 @@ +repro-2005-08-25.tar +-- full set of php files and database create scripts +-- all functionality is implemented and lightly tested +-- about to go back and fix the inconsistent naming of aor in the code + +repro-2005-08-24.tar +-- full set of php files and database create scripts +-- includes the userhome sub-pages except edit resource + +repro-2005-08-22-a.tar +-- full set of php files and database create scripts +-- fixed activateaccount.php + +repro-2005-08-22.tar +-- full set of php files and database create scripts +-- activateaccount.php file was corrupted by a mistake during the tar process + diff --git a/src/libs/resiprocate/repro/php/TODO.text b/src/libs/resiprocate/repro/php/TODO.text new file mode 100644 index 00000000..9eaf78c0 --- /dev/null +++ b/src/libs/resiprocate/repro/php/TODO.text @@ -0,0 +1,39 @@ +security test + -- turn down sessionDuration and verify that all secure pages + correctly block access for non-authenticated users + -- test by directly entering URL's + -- verify that changing the SALT blocks access & forces + reauthentication + +database hardening + -- change queries to explicitly list the columns they are selecting + -- set max lengths on input fields to match database column sizes + -- take out hardcoded database login and passwords + +Https + -- make the page redirect URL's stay secured + +clean up + -- Move all file headers to the top of files + ** get all the MD5 calls down into shared functions + -- delete imagefiles after verification + +document +-- the reason why reset password doesn't take you to a change password +screen that doesn't require the original password to be re-entered +is that I would know Jason's user name and I could guess his email +... that would let me make the change right there, by emailing the +new password to Jason, I ensure he has to authenticate to something +(his email system) before he can get the new password + + +error handling + -- need to define where errors that the admins need to look at will + be logged and what information will be provided + +validation --- + aor -- any pattern match + forward + voicemail + + put the pattern as a constant diff --git a/src/libs/resiprocate/repro/php/activateaccount.php b/src/libs/resiprocate/repro/php/activateaccount.php new file mode 100644 index 00000000..8bcf5b00 --- /dev/null +++ b/src/libs/resiprocate/repro/php/activateaccount.php @@ -0,0 +1,86 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: activateaccount.php +Purpose: Accepts a username and an activation code. If that user exists, + is in unverified state, and the activationcode matches, then the + account is activated. + + If any of those things are not true, an appropriate error message + is shown. +Author: S. Chanin +--> + +<?php + +require('reprofunctions.php'); + +$msgHeading = ""; +$msgBody = ""; + +// check if username and activationCode were passed in as GET params +// and are non-empty + +if ((isset($_GET['user'])) && (!empty($_GET['user'])) && + (isset($_GET['code'])) && (!empty($_GET['code']))) { + $username = $_GET['user']; + $activationCode = $_GET['code']; + + // let's lookup the activation state of the user + $state = getUserState($username,$activationCode); + + if ("A" == $state) { + // active user ... shouldn't be activated a second time + $msgHeading = "Duplicate activation request"; + $msgBody = "This account is already active. It cannot be activated a second time. Please log in from the Welcome Page."; + } else if ("U" == $state) { + // unverified user ... so we'll activate + if (activateUser($username,$activationCode)) { + $msgHeading = "Congratulations $username."; + $msgBody = "Your account is now active. Please follow the link below back to the Welcome Page to log in."; + } else { + // activation failed + $msgHeading = "Error while activating your account."; + $msgBody = "An error occurred while activating your account. Please contact an administrator for assistance."; + } + } else if ("D" == $state) { + // disabled user ... shouldn't be activated. should be handled by + // the administrator + $msgHeading = "Request to activate a disabled account"; + $msgBody = "This account has been disabled. It cannot be reactivated without action by the administrators. Please contact an administrator for assistance."; + } else if ("N" == $state) { + // no match (either user is unknown or activationCode is wrong) + $msgHeading = "Invalid activation information"; + $msgBody = "The parameters that were passed in are incorrect. Please recheck the link in your email. If you see this error again, please try manually cutting and pasting the link into your browser."; + } else { + // internal error ... state should always be one of the previous + // four values. + $msgHeading = "Internal error during activation"; + $msgBody = "An error occurred while attempting to activate your account. Please contact an administrator for assistance."; + } + } else { + // bad parameters + $msgHeading = "Invalid activation information"; + $msgBody = "The parameters that were passed in are incorrect. Please recheck the link in your email. If you see this error again, please try manually cutting and pasting the link into your browser."; + } +?> + +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> +<title>Account Activated</title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1><?php echo $msgHeading ?></h1> +<hr /> +<p><?php echo $msgBody ?></p> + +<br /><hr /> +<a href="index.php">Return to Welcome Page</a> +<br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/addresource.php b/src/libs/resiprocate/repro/php/addresource.php new file mode 100644 index 00000000..f724f1c7 --- /dev/null +++ b/src/libs/resiprocate/repro/php/addresource.php @@ -0,0 +1,95 @@ +<?php +require('reprofunctions.php'); +dbgSquirt("============= Add Resource ==============="); + +$result = checkCookies($forceLogin,$error,FALSE); +if (!($result) || $forceLogin) { + // we got an error back that occurred while checkCookies was being run, + // or authentication failed. Either way, bounce them back to the login screen + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/index.php?error=$error"); + exit; + } +$username = $_COOKIE['user']; +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: addresource.php +Purpose: Allows an authenticated user to add additional resources to their + profile +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> +<title>Add Resource</title> +<script type="text/javascript"> +<!-- +function disableForward() { + document.resourceForm.forward.value = "" + document.resourceForm.forward.disabled = true +} + +function enableForward() { + document.resourceForm.forward.disabled = false +} +//--> +</script> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1>Add Resource</h1> +<hr /> + +<?php +// if we've looped back due to an error, show the message +if (isset($_GET["error"]) && !empty($_GET['error'])) { + echo '<p class="error">' . $_GET["error"] . "</p>\n"; +} +?> +<form method="POST" action="savenewresource.php" name="resourceForm" id="resourceForm"> +<table> +<tr> +<td>Address</td> +<td><input type="text" name="aor" id="aor" value="<?php echo $_GET['aor']; ?>"/></td> +</tr> +<tr> +<td>Forward</td> + <td><input type="radio" name="forwardType" id="forwardType" value="Yes" + onclick="enableForward()" + <?php if (!isset($_GET['forwardType']) || $_GET['forwardType'] == "Yes") + echo 'checked="checked"'; ?> + >Yes</td> +</tr> +<tr><td>&nbsp</td> +<td><input type="radio" name="forwardType" id="forwardType" value="No" + onclick="disableForward()" + <?php if ($_GET['forwardType'] == "No") echo 'checked="checked"'; ?> + >No</td></tr> +<tr><td>Forward Address</td> +<td><input type="text" name="forward" id="forward" value="<?php echo $_GET['forward']; ?>"/> +</td> +</tr> +<tr> +<td>Voicemail</td> +<td><input type="text" name="voicemail" id="voicemail" value="<?php echo $_GET['voicemail']; ?>"/></td> +</tr> +<tr> +<td>&nbsp</td> +<td> +<input type="submit" name="submit" id="submit" value="Save" /> +<input type="submit" name="submit" id="submit" value="Cancel" /> +</td> +</tr> +</table> +</form> + +<br /><hr /> +<a href="userhome.php">Return to User Home</a><br /> +<a href="logout.php">Logout</a><br /> +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/changeemail.php b/src/libs/resiprocate/repro/php/changeemail.php new file mode 100644 index 00000000..687001b4 --- /dev/null +++ b/src/libs/resiprocate/repro/php/changeemail.php @@ -0,0 +1,71 @@ +<?php +require('reprofunctions.php'); +dbgSquirt("============= Change Email ==============="); + +$result = checkCookies($forceLogin,$error,FALSE); +if (!($result) || $forceLogin) { + // we got an error back that occurred while checkCookies was being run, + // or authentication failed. Either way, bounce them back to the login screen + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/index.php?error=$error"); + exit; + } +$username = $_COOKIE['user']; +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: changeemail.php +Purpose: Allow an authenticated user to change the email address stored for them +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> + <title>Change Email</title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1>Change Email</h1> +<hr /> +<?php +// if we've looped back due to an error, show the message +if (isset($_GET["error"])) { + echo '<p class="error">' . $_GET["error"] . "</p>\n"; +} +if (lookupUserInformation($username,$id,$fullname,$domain,$email)) { + // lookup successful + echo "<p>Current Email is: <em>$email</em></p>\n"; +?> +<form method="POST" action="updateemail.php"> +<table> +<tr> +<td>New Email</td> +<td><input type="text" name="newemail" id="newemail" value=""/></td> +</tr> +<tr> +<td>&nbsp</td> +<td> +<input type="submit" name="submit" id="submit" value="Save" /> +<input type="submit" name="submit" id="submit" value="Cancel" /> +</td> +</tr> +</table> +</form> + +<?php + } else { + echo "<p>Internal Error while accessing user information.</p>\n"; + echo "<p>Please contact an administrator.</p>\n"; + } +?> + +<br /><hr /> +<a href="userhome.php">Return to User Home</a><br /> +<a href="logout.php">Logout</a><br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/changefullname.php b/src/libs/resiprocate/repro/php/changefullname.php new file mode 100644 index 00000000..a62c0993 --- /dev/null +++ b/src/libs/resiprocate/repro/php/changefullname.php @@ -0,0 +1,71 @@ +<?php +require('reprofunctions.php'); +dbgSquirt("============= Change Fullname ==============="); + +$result = checkCookies($forceLogin,$error,FALSE); +if (!($result) || $forceLogin) { + // we got an error back that occurred while checkCookies was being run, + // or authentication failed. Either way, bounce them back to the login screen + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/index.php?error=$error"); + exit; + } +$username = $_COOKIE['user']; +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: changefullname.php +Purpose: Allow an authenticated user to change the fullname stored for them +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> + <title>Change Fullname</title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1>Change Fullname</h1> +<hr /> +<?php +// if we've looped back due to an error, show the message +if (isset($_GET["error"])) { + echo '<p class="error">' . $_GET["error"] . "</p>\n"; +} +if (lookupUserInformation($username,$id,$fullname,$domain,$email)) { + // lookup successful + echo "<p>Current Fullname is: <em>$fullname</em></p>\n"; +?> +<form method="POST" action="updatefullname.php"> +<table> +<tr> +<td>New Fullname</td> +<td><input type="text" name="newfullname" id="newfullname" value=""/></td> +</tr> +<tr> +<td>&nbsp</td> +<td> +<input type="submit" name="submit" id="submit" value="Save" /> +<input type="submit" name="submit" id="submit" value="Cancel" /> +</td> +</tr> +</table> +</form> + +<?php + } else { + echo "<p>Internal Error while accessing user information.</p>\n"; + echo "<p>Please contact an administrator.</p>\n"; + } +?> + +<br /><hr /> +<a href="userhome.php">Return to User Home</a><br /> +<a href="logout.php">Logout</a><br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/changepassword.php b/src/libs/resiprocate/repro/php/changepassword.php new file mode 100644 index 00000000..1a58fa88 --- /dev/null +++ b/src/libs/resiprocate/repro/php/changepassword.php @@ -0,0 +1,78 @@ +<?php +require('reprofunctions.php'); +dbgSquirt("============= Change Password ==============="); + +$result = checkCookies($forceLogin,$error,FALSE); +if (!($result) || $forceLogin) { + // we got an error back that occurred while checkCookies was being run, + // or authentication failed. Either way, bounce them back to the login screen + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/index.php?error=$error"); + exit; + } +$username = $_COOKIE['user']; +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: changepassword.php +Purpose: Allow an authenticated user to change the password stored for them +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> + <title>Change Password</title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1>Change Password</h1> +<hr /> +<?php +// if we've looped back due to an error, show the message +if (isset($_GET["error"])) { + echo '<p class="error">' . $_GET["error"] . "</p>\n"; +} +if (lookupUserInformation($username,$id,$fullname,$domain,$email)) { + // lookup successful +?> +<form method="POST" action="updatepassword.php"> +<table> +<tr> +<td>Current Password</td> +<td><input type="password" name="current" id="current" value=""/></td> +</tr> +<tr> +<td>New Password</td> +<td><input type="password" name="newpassword" id="newpassword" value=""/></td> +</tr> +<tr> +<td>Retype New Password</td> +<td><input type="password" name="newpassword2" id="newpassword2" value=""/></td> +</tr> +<tr> +<td>&nbsp</td> +<td> +<input type="submit" name="submit" id="submit" value="Save" /> +<input type="submit" name="submit" id="submit" value="Cancel" /> +</td> +</tr> +</table> +</form> + +<?php + } else { + echo "<p>Internal Error while accessing user information.</p>\n"; + echo "<p>Please contact an administrator.</p>\n"; + } +?> + +<br /><hr /> +<a href="userhome.php">Return to User Home</a><br /> +<a href="logout.php">Logout</a><br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/conversion.text b/src/libs/resiprocate/repro/php/conversion.text new file mode 100644 index 00000000..a27a79f9 --- /dev/null +++ b/src/libs/resiprocate/repro/php/conversion.text @@ -0,0 +1,13 @@ +*index.php +*reprofunctions.php +*userhome.php +*activateaccount.php +*addresource.php +*createaccount.php +*emailactivationnotice.php +*forgotpassword.php +*generatepassword.php +*logout.php +*modifyresource.php +*template.php +*validate.php diff --git a/src/libs/resiprocate/repro/php/createaccount.php b/src/libs/resiprocate/repro/php/createaccount.php new file mode 100644 index 00000000..0b0898f8 --- /dev/null +++ b/src/libs/resiprocate/repro/php/createaccount.php @@ -0,0 +1,135 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: createaccount.php +Purpose: Collect information necessary to enroll a new user. +Author: S. Chanin +--> + +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> +<title>Create Account</title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1>Create Account</h1> +<hr /> + +<!-- if we've looped back due to an error, show the message --> +<?php +if (isset($_GET["error"])) { + echo '<p class="error">' . $_GET["error"] . "</p>\n"; +} +?> + +<?php +// create an image of a random string of characters to use to ensure that a person +// is creating the account. + +$image = imagecreate(120,30); + +$white = imagecolorallocate($image,0xFF, 0xFF, 0xFF); +$gray = imagecolorallocate($image, 0xC0, 0xC0, 0xC0); +$darkgray = imagecolorallocate($image, 0x50, 0x50, 0x50); + +srand((double)microtime()*1000000); + +for ($i=0; $i<30; $i++) { + $x1 = rand(0,120); + $y1 = rand(0,30); + $x2 = rand(0,120); + $y2 = rand(0,30); + + imageline($image, $x1, $y1, $x2, $y2, $gray); +} + +for ($i=0; $i < 5; $i++) { + $type = rand(0,2); + + if (0 == $type) { + // generate a lower case letter + $cnum[$i] = chr(rand(97,122)); + } else if (1 == $type) { + // generate an upper case letter + $cnum[$i] = chr(rand(65,90)); + } else { + // generate a number + $cnum[$i] = chr(rand(48,57)); + } +} + +$x = 0; +for ($i=0; $i<5; $i++) { + $fnt = rand(3,5); + $x = $x + rand(12,20); + $y = rand(7,12); + + imagestring($image,$fnt, $x, $y, $cnum[$i], $darkgray); +} + +$string = "$cnum[0]$cnum[1]$cnum[2]$cnum[3]$cnum[4]"; +$stringMD5 = md5($string); +$stringfile = "images/" . $stringMD5 . ".pgn"; + +imagepng($image,$stringfile); +imagedestroy($image); + +?> + +<form method="POST" action="emailactivationnotice.php"> +<table> +<tr> +<td>Username</td> +<td><input type="text" id="username" name="username" value="<?php echo $_GET["username"]?>" /></td> +</tr> +<tr> +<td>Password</td> +<td><input type="password" id="password" name="password" /></td> +</tr> +<tr> +<td>Retype Password</td> +<td><input type="password" id="password2" name="password2" /></td> +</tr> +<tr> +<td>Full Name</td> +<td><input type="text" id="fullname" name="fullname" value="<?php echo $_GET["fullname"]?>"/></td> +</tr> +<tr> +<td>Domain</td> +<td><input type="text" id="domain" name="domain" readonly="readonly" value="XXX" class="readonly"/></td> +</tr> +<tr> +<td>Email</td> +<td><input type="text" id="email" name="email" value="<?php echo $_GET["email"]?>"/></td> +</tr> +<tr> +<td>Retype Email</td> +<td><input type="text" id="email2" name="email2" value="<?php echo $_GET["email2"]?>" /></td> +</tr> +<tr> +<td>Retype the characters displayed below</td> +</tr> +<tr> +<td><img width=120 height=30 src="<?php echo $stringfile ?>" border="1" /></td> +<td><input type="text" size="5" maxlength="5" name="userkey" id="userkey" value=""/> + <input type="hidden" name="keyvalue" id="keyvalue" value="<?php echo $stringMD5 ?>" /> +</td> +</tr> +<tr> +<td>&nbsp</td> +<td align="right"> + <input type="submit" id="submit" name="submit" value="Create" /> + <input type="reset" id="reset" name="reset" value="Reset" /> +</td> +<tr> +</table> +</form> +<hr /> +<a href="index.php">Return to Welcome Page</a> +<br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/dbsetup/Parameters.sql b/src/libs/resiprocate/repro/php/dbsetup/Parameters.sql new file mode 100644 index 00000000..472f0873 --- /dev/null +++ b/src/libs/resiprocate/repro/php/dbsetup/Parameters.sql @@ -0,0 +1,7 @@ +drop table if exists Parameters; + +create table Parameters ( + parameter varchar(20) not null, + value varchar(255) not null); + +insert into Parameters(parameter,value) values('salt','Pilot#$Floss'); diff --git a/src/libs/resiprocate/repro/php/dbsetup/Resources.sql b/src/libs/resiprocate/repro/php/dbsetup/Resources.sql new file mode 100644 index 00000000..d570cd6b --- /dev/null +++ b/src/libs/resiprocate/repro/php/dbsetup/Resources.sql @@ -0,0 +1,13 @@ +drop table if exists Resources; + +create table Resources ( + id int unsigned not null auto_increment, + userid int unsigned not null, + aor varchar(255) not null, + forwardType char(1) not null, + forwardDestination varchar(255), + voicemail varchar(255), + primary key(id), + unique index(userid,aor)); + + diff --git a/src/libs/resiprocate/repro/php/dbsetup/Users.sql b/src/libs/resiprocate/repro/php/dbsetup/Users.sql new file mode 100644 index 00000000..af4cf6b1 --- /dev/null +++ b/src/libs/resiprocate/repro/php/dbsetup/Users.sql @@ -0,0 +1,14 @@ +drop table if exists Users; + +create table Users ( + id int unsigned not null auto_increment, + username varchar(255) not null, + password varchar(32) not null, + fullname varchar(255) not null, + domain long not null, + email varchar(255) not null, + state char(1) not null, + activationDate date, + activationCode varchar(32), + primary key(id)); + diff --git a/src/libs/resiprocate/repro/php/dbsetup/readme b/src/libs/resiprocate/repro/php/dbsetup/readme new file mode 100644 index 00000000..43e74260 --- /dev/null +++ b/src/libs/resiprocate/repro/php/dbsetup/readme @@ -0,0 +1,19 @@ +to initialize a mysql database to an empty state, run the following commands: + + mysql -u $user -p$pass $dbname < Users.sql + mysql -u $user -p$pass $dbname < Resources.sql + +these assume that you have an alias bound for mysql, or you have added the +mysql /bin directory to your path. + +you should also replace $user and $pass with the username and +password you want to use to create the tables. + +I recommend creating a separate database for the repro tables (called, +creatively, "repro" in my case) and locating them there. In any case, the +name of the database you want to use should be passed as the third argument +$dbname. + +Note -- there is no space between the -p and the $pass. If you put a space +there, mysql will choke. + diff --git a/src/libs/resiprocate/repro/php/editresource.php b/src/libs/resiprocate/repro/php/editresource.php new file mode 100644 index 00000000..fbe1de94 --- /dev/null +++ b/src/libs/resiprocate/repro/php/editresource.php @@ -0,0 +1,139 @@ +<?php +require('reprofunctions.php'); +dbgSquirt("============= Edit Resource ==============="); +dbgSquirt("GET --" . dbgShowFile($_GET)); + +$result = checkCookies($forceLogin,$error,FALSE); +if (!($result) || $forceLogin) { + // we got an error back that occurred while checkCookies was being run, + // or authentication failed. Either way, bounce them back to the login screen + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/index.php?error=$error"); + exit; + } +$username = $_COOKIE['user']; + +$bounceURL = "Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . "/userhome.php?error="; + +// this page is only entered via GET's +// all of these should be set all the time, even though they might be +// empty... if they aren't set, something is strange about how we got to this +// page +if (!isset($_GET['resourceId']) || !isset($_GET['aor']) || + !isset($_GET['forwardType']) || !isset($_GET['forward']) || + !isset($_GET['voicemail'])) { + header($bounceURL . "Information missing in request to modify a resource. Please try again. If this error reoccurs, please contact an administrator."); + exit(); + } + +$resourceId = $_GET['resourceId']; +$aor = $_GET['aor']; +$forwardType = $_GET['forwardType']; +$forward = $_GET['forward']; +$voicemail = $_GET['voicemail']; + +// make sure resourceId isn't blank. Other fields could be blank +if (empty($resourceId)) { + header($bounceURL . "Information missing in request to modify a resource. Please try again. If this error reoccurs, please contact an administrator."); + exit(); + } + +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!-- +System: Repro +File: editresource.php +Purpose: display the current information for a resource. Allow an + authenticated user to edit that information. +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> +<title></title> +<script type="text/javascript"> +<!-- +function disableForward() { + document.resourceForm.forward.value = "" + document.resourceForm.forward.disabled = true +} + +function enableForward() { + document.resourceForm.forward.disabled = false +} +//--> +</script> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1>Edit Resource</h1> +<hr /> + +<?php +// if we've looped back due to an error, show the message +if (isset($_GET["error"]) && !empty($_GET['error'])) { + echo '<p class="error">' . $_GET["error"] . "</p>\n"; +} +?> + +<form method="POST" action="savemodifiedresource.php" name="resourceForm" id="resourceForm"> + <table> +<input type="hidden" name="resourceId" id="resourceId" value="<?php echo $resourceId ?>"/> +<tr> +<td>Address</td> +<td><input type="text" name="aor" id="aor" value="<?php echo $aor ?>"/></td> +</tr> +<tr> +<td>Forward</td> +<td><input type="radio" name="forwardType" id="forwardType" value="Yes" + onclick="enableForward()" + <?php if ("Y" == $forwardType || "" == $forwardType) + echo 'checked="checked"'; ?> + >Yes</td></tr> +<tr><td>&nbsp</td> +<td><input type="radio" name="forwardType" id="forwardType" value="No" + onclick="disableForward()" + <?php if ("N" == $forwardType) echo 'checked="checked"'; ?> + >No</td></tr> + <tr><td>Forward Address</td> + <td><input type="text" name="forward" id="forward" value="<?php echo $forward; ?>"/> + </td> +</tr> +<tr> +<td>Voicemail</td> +<td><input type="text" name="voicemail" id="voicemail" value="<?php echo $voicemail; ?>"/></td> +</tr> +<tr> +<td>&nbsp</td> +<td> +<input type="submit" name="submit" id="submit" value="Save" /> +<input type="submit" name="submit" id="submit" value="Cancel" /> +</td> +</tr> +</table> + +<?php +// if forwardType is "N" we also need to disable the forward address box + if ("N" == $forwardType) { +?> +<script type="text/javascript"> +<!-- +disableForward() +//--> +</script> +<?php + } +?> + +</form> + +<br /><hr /> +<a href="userhome.php">Return to User Home</a><br /> +<a href="logout.php">Logout</a><br /> +<br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/emailactivationnotice.php b/src/libs/resiprocate/repro/php/emailactivationnotice.php new file mode 100644 index 00000000..ab52f211 --- /dev/null +++ b/src/libs/resiprocate/repro/php/emailactivationnotice.php @@ -0,0 +1,185 @@ +<?php +/* +System: Repro +File: emailactivationnotice.php +Purpose: validate the information entered in the account setup screen, create + an account based on this, and email an activation code to the user. +Author: S. Chanin +*/ + +require('reprofunctions.php'); + +// edit checks on values entered +$error=""; + +// pull out the post variables +$username=$_POST['username']; +$password=$_POST['password']; +$password2=$_POST['password2']; +$fullname=$_POST['fullname']; +$domain=$_POST['domain']; +$email=$_POST['email']; +$email2=$_POST['email2']; +$userkey=$_POST['userkey']; +$keyvalue=$_POST['keyvalue']; + +// ensure that all required values have been filled in +if (empty($username)) { + $error = $error . "Username must be non-blank.<br />"; } +if (empty($password)) { + $error = $error . "Password must be non-blank.<br />"; } +if (empty($password2)) { + $error = $error . "Retyped Password must be non-blank.<br />"; } +if (empty($fullname)) { + $error = $error . "Full Name must be non-blank.<br />"; } +if (empty($email)) { + $error = $error . "Email must be non-blank.<br />"; } +if (empty($email2)) { + $error = $error . "Retyped Email must be non-blank.<br />"; } + +// ensure that double entered values match +if ($password != $password2) { + $error = $error . "Values entered for passord do not match.<br />"; } +if ($email != $email2) { + $error = $error . "Values entered for email address do not match.<br />"; } + +// ensure that the CAPTCHA key was correctly read and reentered +if (md5($userkey) != $keyvalue) { + $error = $error . "Security key does not match.<br />"; } + +// validate that username isn't already in use +if (usernameInUse($username) == "Y") { + $error = $error . "That username is already in use.<br />"; +} + +// verify that they have passed the automated turing test +// verify the email address passes a sniff test + +if (!empty($error)) { + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/createaccount.php?username=$username&fullname=$fullname&email=$email&email2=$email2&error=" . urlencode($error)); + exit; +} + +//create an activation code +/* there may be a better way to do this. My thought is that md5 gives me a +string that is pretty random and long enough that it is essentially impossible +to guess. By seeding it with microtime and username the key should be different +for each user it would take a couple of thousand guesses to get a match if you +tried to brute force create every possible activationKey for the time around +when the attackers account was created. +*/ +$activationCode = md5(microtime() . $username); + +// create the actual account +$encryptedPassword = createPassword($username,$password); + +if (!createAccount($username,$encryptedPassword,$fullname,$domain,$email,$activationCode)) { + // oops ... got an error creating the account + $error = $error . "Error while creating account."; + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/createaccount.php?username=$username&fullname=$fullname&email=$email&email2=$email2&error=" . urlencode($error)); + exit; +} + +// create a default resource +$defaultAOR = $username . '@' . $domain; +if (!createResource($username,$defaultAOR,'N','','')) { + // oops ... got an error creating the default resource + $error = $error . "Error while creating account (default resource)."; + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/createaccount.php?username=$username&fullname=$fullname&email=$email&email2=$email2&error=" . urlencode($error)); + exit; +} + +// email the activation notice +// create activation link +$link = "http://" . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . + "/activateaccount.php?user=$username&code=$activationCode"; + +// subject +$subject = "$provider Activation Notice"; + +// message +$message = ' +<html> +<head> + <title>' . $provider . ' Activation Notice</title> +</head> +<body> +<h1>Welcome to '. $provider . +'</h1> + +<p>This email address has recently been used to create a new +account at ' . $provider . '</p><br /> +<p>In order to ensure this account was actually requested by you, +we send an email to the address provided and ask that you confirm the +new account request by clicking the link below:</p> +<br />' . $link . '<br /> +If you do not click this link, the account will not be activated. +<br /> +<br /> +Sincerely,<br />' . $provider . +'</body> +</html> +'; + +// To send HTML mail, the Content-type header must be set +$headers = 'MIME-Version: 1.0' . "\r\n"; +$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n"; + +// Additional headers +$headers .= "From: $providerEmail". "\r\n"; + +// Mail it +if (!mail($email, $subject, $message, $headers)) { + // mail returned an error + $error = $error . "Error while emailing activation notice."; + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/createaccount.php?username=$username&fullname=$fullname&email=$email&email2=$email2&error=" . urlencode($error)); + exit; +} +?> + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> +<title>Activation Notice</title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1>Activation Notice</h1> +<hr /> +<p>Congratulatins <?php echo $fullname ?> and welcome to <?php echo $provider ?>. +Your account has been established on our server. In order to ensure all +the information provided is correct, we have sent an email with an activation +link to the address you provided in the signup process.</p> + +<p>Please read that message and click the link provided, or follow the +instructions in the email for manual activiation.</p> + +<hr /> +<p>Since I don't have an SMTP server running on this machine, I can't send out messages. +As a result, I can't test that the above email code actually works.</p> + +<p>So for this version, here is the same link to click that is in the email. Clicking +this link will activate your account.</p> + +<a href="<?php echo $link ?>">Click here to activate</a> +<br /> +Or copy the following link into your browser: <br /> +<?php echo $link ?> + +<br /><hr /> +<a href="index.php">Return to Welcome Page</a> +<br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/forgotpassword.php b/src/libs/resiprocate/repro/php/forgotpassword.php new file mode 100644 index 00000000..fb6c44bf --- /dev/null +++ b/src/libs/resiprocate/repro/php/forgotpassword.php @@ -0,0 +1,55 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: forgotpassword.php +Purpose: Reset password & email to address on file for the user +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> +<title>Forgot Password</title> +</head> + +<body> +<h1 class="title">Repro</h1> + +<h1>Forgot Password</h1> +<hr /> + +<!-- if we've looped back due to an error, show the message --> +<?php +if (isset($_GET["error"])) { + echo '<p class="error">' . $_GET["error"] . "</p>\n"; +} +?> + +<p>If you have forgotten your password, please enter your email address below +and the system will generate a new password for you and email that password +to you.</p> + +<form action="generatepassword.php" method="post"> +<table> +<tr> +<td>Username:</td> +<td><input type="text" name="username" id="username" value="<?php echo $_GET['username']; ?>" /></td> +</tr> + +<tr> +<td>Email address:</td> +<td><input type="text" name="email" id="email" value="<?php echo $_GET['email']; ?>" /></td> +</tr> + +<tr> +<td>&nbsp</td> +<td><input type="submit" name="submit" id="submit" value="Reset Password" /> +</tr> +</table> +</form> + +<br /><hr /> +<a href="index.php">Return to Welcome Page</a> +<br /> +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/generatepassword.php b/src/libs/resiprocate/repro/php/generatepassword.php new file mode 100644 index 00000000..fb7ac127 --- /dev/null +++ b/src/libs/resiprocate/repro/php/generatepassword.php @@ -0,0 +1,141 @@ +<?php +/* +System: Repro +File: generatepassword +Purpose: Take a username and an email address and, if that email address matches +the username, then generate a new, random, password, set that users +password to the new password, and email the password to the user. +Author: S. Chanin +*/ + +require('reprofunctions.php'); + +// edit checks on values entered +$error=""; + +// pull out the post variables +$username=$_POST['username']; +$email=$_POST['email']; + +// ensure that all required values have been filled in +if (empty($username)) { + $error = $error . "Username must be non-blank.<br />"; } +if (empty($email)) { + $error = $error . "Email must be non-blank.<br />"; } + +/* validate that the username and email address match a known user. + note -- this error could occur either because the username is unknown + or because the email address doesn't match. I don't show this + distinction to avoid creating an easy way to fish for usernames. + + This function also requires that the username correspond to an active account. + We do not allow passwords to be reset for unverified or disabled accounts. +*/ +if (!matchUserAndEmail($username,$email)) { + $error = $error . "That username does not match the email address provided for any of our active accounts.<br />"; +} + +if (!empty($error)) { + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/forgotpassword.php?username=$username&email=$email&error=" . urlencode($error)); + exit; +} +?> + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> +<title>Sending New Password</title> +</head> + + +<body> +<h1 class="title">Repro</h1> + +<?php +// generate a random password +// TODO -- think about whether this works in a unicode, non-english environment +$password = ""; +for($i=0; $i<8; $i++) { + $type = rand(0,2); + + if (0 == $type) { + // generate a lower case letter + $password .= chr(rand(97,122)); + } else if (1 == $type) { + // generate an upper case letter + $password .= chr(rand(65,90)); + } else { + // generate a number + $password .= chr(rand(48,57)); + } +} + +// update the account to use that password +$encryptedPassword = createPassword($username,$password); + +if (!updatePassword($username,$encryptedPassword)) { + // an error occurred while updating the password + ?> + <h2>Error -- Internal Error Saving New Password.</h2> + <p>An internal error occurred while attempting to change the password on + your account. Please contact an administrator for assistance.</p> + <?php +} else { + // generate the email + // subject + $subject = "Password Reset Notice"; + + // message + $message = ' +<html> +<head><title>Password Reset Notice</title></head> +<body> +<p>At your request, we have reset the password on your account to a new, random +password. Your new password is:</p><p>' . $password . +'</p><p>Please change the password to one that you will remember on your next +log in.</p></body></html>'; + + // To send HTML mail, the Content-type header must be set + $headers = 'MIME-Version: 1.0' . "\r\n"; + $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n"; + + // Additional headers + $headers .= "From: $providerEmail". "\r\n"; + + // Mail it + if (!mail($email, $subject, $message, $headers)) { + // mail returned an error + ?> + <h2>Error -- Internal Error Sending Confirmation Email.</h2> + <p>An internal error occurred while sending you the email with your + new password. Please contact an administrator for assistance.</p> + <?php + } else { + // show confirmation message + // also my temp copy of the message since email isn't working + ?> + <h2>Email sent</h2> + <p>An email has been sent to <?php echo $email ?> with a new temporary + password that has been created for you. Please use that password to + log back into the site and then change your password to one that you + can remember.</p> + + <br /><hr /> + <p>Since I don't have a working SMTP server on this machine, I need to + echo the new password to this page so I can test it.</p><br /> + <p>Your new password is:</p> + <?php echo $password; + } +} +?> + +<br /><hr /> +<a href="index.php">Return to Welcome Page</a> +<br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/index.php b/src/libs/resiprocate/repro/php/index.php new file mode 100644 index 00000000..59388e78 --- /dev/null +++ b/src/libs/resiprocate/repro/php/index.php @@ -0,0 +1,56 @@ +<?php +require('reprofunctions.php'); + +clearCookies(); +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: Index +Purpose: Collect users name and password to validate his credentials +Author: Steven Chanin +--> + +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> +<title>Login</title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1>Login</h1> +<hr /> + +<!-- if we've looped back due to an error, show the message --> +<?php +if (isset($_GET["error"])) { + echo '<p class="error">' . $_GET["error"] . "</p>\n"; +} +?> + +<form method="POST" action="userhome.php"> +<table> +<tr> +<td>Username</td> +<td><input type="text" id="username" name="username" value="<?php echo $_GET["username"]?>"/></td> +</tr> +<tr> +<td>Password</td> +<td><input type="password" id="password" name="password" /></td> +</tr> +<tr> +<td>&nbsp</td> +<td align="right"> + <input type="submit" id="submit" name="submit" value="Login" /></td> +<tr> +</table> +</form> +<hr /> +<a href="forgotpassword.php">Forgot password</a> +<br /> +<a href="createaccount.php">Sign up for an account</a> +<br /> +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/logout.php b/src/libs/resiprocate/repro/php/logout.php new file mode 100644 index 00000000..35a2e0db --- /dev/null +++ b/src/libs/resiprocate/repro/php/logout.php @@ -0,0 +1,35 @@ +<?php +require('reprofunctions.php'); + +clearCookies(); +?> + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: logout.php +Purpose: Clears cookies and logs the user out of the system +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> +<title>Logout</title> +</head> + +<body> +<h1 class="title">Repro</h1> + +<h1>Logout</h1> +<hr /> + + +<p>You have been safely logged out.</p> + +<br /><hr /> +<a href="index.php">Return to Welcome Page</a> +<br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/modifyresource.php b/src/libs/resiprocate/repro/php/modifyresource.php new file mode 100644 index 00000000..e06ae188 --- /dev/null +++ b/src/libs/resiprocate/repro/php/modifyresource.php @@ -0,0 +1,93 @@ +<?php +require('reprofunctions.php'); +dbgSquirt("============= Modify Resource ==============="); +dbgSquirt("GET --" . dbgShowFile($_GET)); +dbgSquirt("POST --" . dbgShowFile($_POST)); + +$result = checkCookies($forceLogin,$error,FALSE); +if (!($result) || $forceLogin) { + // we got an error back that occurred while checkCookies was being run, + // or authentication failed. Either way, bounce them back to the login screen + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/index.php?error=$error"); + exit; + } +$username = $_COOKIE['user']; + +$bounceURL = "Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . "/userhome.php?error="; + +// make sure post variables have arrived. We should always get a resourceId, +// name, and either an edit or a delete +if (!(isset($_POST['resourceId']) && isset($_POST['aor']) && + (isset($_POST['edit']) || isset($_POST['delete'])))) { + header($bounceURL . "The information to modify a resource was not provided. Please enter the information and click Save. If this error reoccurs, contact an administrator."); + exit; + } + +// check that resourceId is non-blank ... this shouldn't happen since this is +// a system provided invisible field +if (empty($_POST['resourceId']) || empty($_POST['aor'])) { + header($bounceURL . "The resource to be modified was not specified. Please click one of the Add or Delete buttons. If you see this message again, please contact an administrator."); + exit; + } +$resourceId = $_POST['resourceId']; +$aor = $_POST['aor']; + +//see if the operation is Edit or Delete +if ("Delete" == $_POST['delete']) { + // delete that resouce + if (deleteResource($username,$resourceId)) { + // success + $title = "Resource Deleted"; + $heading = "Resource Deleted"; + $msg = "Successfully deleted the resource: <em>$aor</em>"; + } else { + // delete failed + $title = "Error while deleting"; + $heading = "Error while deleting"; + $msg = "An error occurred while deleting the resource <em>$aor</em>. Please contact an administrator."; + } + } else if ("Edit" == $_POST['edit']) { + // get displayed values + $forwardType = $_POST['forwardType']; + $forward = $_POST['forward']; + $voicemail = $_POST['voicemail']; + + // redirect to a new page for handling edits to an existing URL + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . "/editresource.php?resourceId=$resourceId&aor=$aor&forwardType=$forwardType&forward=$forward&voicemail=$voicemail"); + exit; + } else { + // shouldn't get here ... this means no valid action was requested + header($bounceURL . "Error while modifying resources. Please contact an administrator."); + exit; + } + +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: modifyresource.php +Purpose: Allows a user to edit or delete a resource that is attached to their account +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> + <title><?php echo $title; ?></title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1><?php echo $heading; ?></h1> +<hr /> +<p><?php echo $msg; ?></p> +<br /><hr /> +<a href="userhome.php">Return to User Home</a><br /> +<a href="logout.php">Logout</a><br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/repro_style.css b/src/libs/resiprocate/repro/php/repro_style.css new file mode 100644 index 00000000..0c5026aa --- /dev/null +++ b/src/libs/resiprocate/repro/php/repro_style.css @@ -0,0 +1,7 @@ +h1.title { text-align:center; background-color: rgb(192,0,192) } + +p.error { color:rgb(255,0,0); border-style:solid; padding:2px } + +input.readonly { background-color: rgb(192,192,192) } + +th.header { background-color: rgb(128,128,128) } diff --git a/src/libs/resiprocate/repro/php/reprofunctions.php b/src/libs/resiprocate/repro/php/reprofunctions.php new file mode 100644 index 00000000..a21c28f0 --- /dev/null +++ b/src/libs/resiprocate/repro/php/reprofunctions.php @@ -0,0 +1,681 @@ +<?php +/* +System: Repro +File: reprofunctions.php +Purpose: shared functions used by multiple pages +Author: S. Chanin +*/ +/* because I don't have a final database abstraction to work with and I don't +know how to save db connection state in a cookie (or even if that's possible for +all the db's we need to support, I'm going to make every function open and close +it's own connection. This is inefficient, but at least it's clean. */ + +// shared constants (the alternative for this would be to define them +// as constants +$provider = "XYZ"; +$providerEmail = "XYZ Activation <activation@xyz.com>"; +$sessionDuration = 600; /* 600 seconds = 10 min */ + +/* +Purpose: Used for debugging. Can pretty print a variable to the browser + or can stuff the pretty printed version in a string (in Broswer format). + +return values are: + if $return_str is FALSE or not passed: "" + if $return_str is TRUE: the printable representation of the $data +*/ +function dbgShowBroswer($data, $return_str = false, $func = "print_r"){ + ob_start(); + $func($data); + $output = '<pre>'.htmlspecialchars(ob_get_contents()).'</pre>'; + ob_end_clean(); + if($return_str) { + return $output; + } else { + echo $output; + return(""); + } +} + +/* +Purpose: Used for debugging. Stuffs the pretty printed version in a string into + a string which is returned so it can be stored in a file. + +return values are: + the storable representation of the $data +*/ +function dbgShowFile($data, $func = "print_r"){ + ob_start(); + $func($data); + $output = ob_get_contents(); + ob_end_clean(); + return $output; +} + + +/* +Purpose: Used for debugging. Appens a string ($) to the file /tmp/squirt. + Use tail -f /tmp/squirt in a terminal window to watch the output. +*/ +function dbgSquirt($s, $stamp=1) { + $fp = fopen ("/tmp/squirt", "a+"); + if ($stamp == 1) { + fputs($fp, date('ymd H:i:s ')); + } + fputs($fp, $s."\n"); + fclose($fp); +} + +/* +Purpose: checks if the supplied user/password combination matches a known user. + +If so, the state of that user is returned. + +return values are: + A = matches an active user + U = matches an unverified user + D = matches a disabled user + N = does not match */ +function validateUser($u, $p) { + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + $query="select * from Users where username='$u' and password='$p'"; + $result = mysql_query($query) or die(mysql_error()); + + $count=mysql_num_rows($result); + + if ($count == 1) { + // we matched, so lets get the state of the user + $state = mysql_result($result,0,"state"); + } else { + $state = "N"; } + + mysql_free_result($result); + mysql_close($db); + return $state; +} + +/* +Purpose: Used to get the state of a user. The state will only be returned if +the function is called with an activationCode that matches the one set for that +user in the database. + +return values are: + A = matches an active user + U = matches an unverified user + D = matches a disabled user + N = does not match */ +function getUserState($user, $code) { + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + $query="select * from Users where username='$user' and activationCode='$code'"; + $result = mysql_query($query) or die(mysql_error()); + + $count=mysql_num_rows($result); + + if ($count == 1) { + // we matched, so lets get the state of the user + $state = mysql_result($result,0,"state"); + } else { + $state = "N"; } + + mysql_free_result($result); + mysql_close($db); + return $state; +} + + + +/* +Purpose: Check to see if a user name is already in use + +return values are: + Y = username is in use + N = username is not in use + +Note -- it is not possible to reuse a user name. */ +function usernameInUse($u) { + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + $query="select * from Users where username='$u'"; + $result = mysql_query($query) or die(mysql_error()); + + $count=mysql_num_rows($result); + if ($count == 1) { + // we matched, so that name is in use + $state = "Y"; + } else { + $state = "N"; } + + mysql_free_result($result); + mysql_close($db); + return $state; +} + +/* +Purpose: create a new account in the system. New accounts are automatically + created in U (unverified) state and have the current date used for + the activationDate. + +return values are: + True = account creation succeeded. + False = account creation failed. */ +function createAccount($username, $passwordMD5, $fullname, $domain, $email,$activationCode) { + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + $activationDate = date("Y-m-d"); + $query="insert into Users (username,password,fullname,domain,email,state,activationDate,activationCode) values('$username','$passwordMD5','$fullname','$domain','$email','U','$activationDate','$activationCode')"; + + $result = mysql_query($query) or die(mysql_error()); + + $count = mysql_affected_rows(); + + if ((1 == $count) && (TRUE == $result)) { + // no error and 1 row inserted + $state = TRUE; + } else { + $state = FALSE; } + + mysql_close($db); + return $state; +} + +/* +Purpose: set a new account to active status + +return values are: + TRUE = account activation succeeded. + FALSE = account activation failed. */ +function activateUser($username, $activationCode) { + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + $activationDate = date("Y-m-d"); + $query="update Users set state = 'A' where username = '$username' and activationCode = '$activationCode'"; + + $result = mysql_query($query) or die(mysql_error()); + + $count = mysql_affected_rows(); + + if ((1 == $count) && (TRUE == $result)) { + // no error and 1 row updated + $state = TRUE; + } else { + $state = FALSE; } + + mysql_close($db); + return $state; +} + +/* +Purpose: Check to see if the supplied username and email address match a known + active user (can't do password resets for unverified or disabled + users) + +return values are: + TRUE = username/email combination are a match + FALSE = the combination does not match +*/ +function matchUserAndEmail($username,$email) { + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + $query="select * from Users where username='$username' and email='$email' and state = 'A'"; + $result = mysql_query($query) or die(mysql_error()); + + $count=mysql_num_rows($result); + if ($count == 1) { + // we matched, so that user/email combination is valid + $state = TRUE; + } else { + $state = FALSE; } + + mysql_free_result($result); + mysql_close($db); + return $state; +} + +/* +Purpose: Create a new resource for a user. + +return values are: + TRUE = create succeeded. + FALSE = create failed. */ +function createResource($username, $aor, $forwardType, $forwardDestination, $voicemail) { + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + + // first we need to get the userid from the username + $query="select id from Users where username = '$username'"; + $result = mysql_query($query) or die(mysql_error()); + + $count=mysql_num_rows($result); + if ($count == 1) { + // we matched, so lets get the userid of the user + $userid = mysql_result($result,0,"id"); + mysql_free_result($result); + + // if there are any constraints (e.g. AOR must be unique, etc, check + // for them here + + // add the resource to the Resources table + $query = "insert into Resources (userid,aor,forwardType,forwardDestination,voicemail) values($userid,'$aor','$forwardType','$forwardDestination','$voicemail')"; + + $result = mysql_query($query) or die(mysql_error()); + $count = mysql_affected_rows(); + + if ((1 == $count) && (TRUE == $result)) { + // no error and 1 row inserted + $state = TRUE; + } else { + $state = FALSE; } + } else { + $state = FALSE; } + + mysql_free_result($result); + mysql_close($db); + return $state; +} + +/* +Purpose: Looks up other info tied to a user. + +Since arguments are passed by reference, they are set to the values returned +by the select. The functions return value is used to indicate whether execution +succeed or failed. + +return values are: + TRUE == lookup suceeded. + FALSE == error during lookup +*/ + +function lookupUserInformation($username,&$id,&$fullname,&$domain,&$email) { + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + $query="select * from Users where username='$username'"; + $result = mysql_query($query) or die(mysql_error()); + + $count=mysql_num_rows($result); + + if ($count == 1) { + // we matched, so lets get the state of the user + $id = mysql_result($result,0,"id"); + $fullname = mysql_result($result,0,"fullname"); + $domain = mysql_result($result,0,"domain"); + $email = mysql_result($result,0,"email"); + + $state = TRUE; + } else { + $state = FALSE; } + + mysql_free_result($result); + mysql_close($db); + return $state; +} + +/* +Purpose: Builds an associative array containing all the resources associated + with a username. This is extra work, but it should isolate any dependency + on mysql here and allow the function to be re-implemented for other + databases without affecting the surrounding code. + +return values are: + TRUE == lookup succeeded + FALSE == lookup failed +*/ +function getResourcesByUsername($username,&$resources) { + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + + // first we need to get the userid from the username + $query="select id from Users where username = '$username'"; + $result = mysql_query($query) or die(mysql_error()); + + $count=mysql_num_rows($result); + // print "Query -- $query<br />\nCount -- $count<br \>\n"; + + if ($count == 1) { + // we matched, so lets get the userid of the user + $userid = mysql_result($result,0,"id"); + mysql_free_result($result); + + $query = "select id,aor,forwardType,forwardDestination,voicemail from Resources where userid = '$userid'"; + $result = mysql_query($query) or die(mysql_error()); + + // print "Query -- $query<br />\nResult -- $result<br />\n"; + + $state = TRUE; + while (($myrow = mysql_fetch_array($result))) { + // print "Row -- "; + // print_r($myrow); + $newRow = array($myrow['id'],$myrow['aor'],$myrow['forwardType'],$myrow['forwardDestination'],$myrow['voicemail']); + + // print "<br />New Row --"; + // print_r($newRow); + $resources[] = $newRow; + // print "<br />Resource -- "; + // print_r($resources); + } + } else { + $state = FALSE; + } + + mysql_free_result($result); + mysql_close($db); + return $state; +} + +/* +Purpose: gets the shared salt from the database to use in creating authentication +tokens. + +return values are: + TRUE == salt successfully retrieved + FALSE == error while retreiving salt +*/ +function getSalt(&$salt) { + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + $query="select value from Parameters where parameter='salt'"; + $result = mysql_query($query) or die(mysql_error()); + + $count=mysql_num_rows($result); + + if ($count == 1) { + // we matched, so lets get the state of the user + $salt = mysql_result($result,0,"value"); + $state = TRUE; + } else { + $salt = ""; + $state = FALSE; } + + mysql_free_result($result); + mysql_close($db); + return $state; +} + +/* +Purpose: clears authentication cookies + +return values are: + TRUE == no errors reported from setcookie + FALSE == errors were reported +*/ +function clearCookies() { + +dbgSquirt("==============Function: Clear Cookies =============="); +dbgSquirt('Cookie --' . dbgShowFile($_COOKIE)); + + + $result = setcookie("user","",mktime(12,0,0,1,1,1970)); + $result1 = setcookie("authentication","",mktime(12,0,0,1,1,1970)); + + return ($result && $result1); +} + +/* +Purpose: checks whether the current cookies validate the user or if additional + authentication is needed. + + if the cookies are unset or are blank, $ignoreBlanks is checked. + if $ignoreBlanks is TRUE, no error is reported in this case. + if $ignoreBlanks is FALSE, then this case is treated as an error. + ...in either case, blank or unset cookies will result in $forceLogin + being true. + +return values are: + TRUE == no errors reported + FALSE == errors were reported + +mutates the following: + $forceLogin: TRUE == cookies contain valid authentication data + FALSE == user is NOT authenticated + $error: "" == no errors + otherwise contains displayable text of error +*/ +function checkCookies(&$forceLogin,&$error,$ignoreBlanks) { + $forceLogin = TRUE; + $error = ""; + global $sessionDuration; + + dbgSquirt("==============Function: checkCoookies =============="); + dbgSquirt('Cookie --' . dbgShowFile($_COOKIE)); + + if (isset($_COOKIE['user']) && !empty($_COOKIE['user']) && + isset($_COOKIE['authentication']) && !empty($_COOKIE['authentication'])) { + // both user and authentication cookies are set and non-blank + // dbgSquirt("Cookies set and non-empty"); + $userCookie = $_COOKIE['user']; + $authenticationCookie = $_COOKIE['authentication']; + $time = time(); + + // dbgSquirt("Getting salt"); + if (getSalt($salt)) { + // dbgSquirt("...salt gotten"); + // dbgSquirt("Encrypting"); + if (sha1($userCookie . $salt) == $authenticationCookie) { + // authentication passed + // so reset expiration on cookies + // dbgSquirt("Cookie matches encryption"); + // dbgSquirt("Resetting cookies"); + // dbgSquirt("Time -- $time"); + // dbgSquirt("Time + Duration -- ". ($time+$sessionDuration)); + $result = setcookie("user",$userCookie,$time+$sessionDuration); + $result1 = setcookie("authentication",$authenticationCookie, + $time+$sessionDuration); + if ((TRUE == $result) && (TRUE == $result1)) { + // everything worked + // dbgSquirt("Everything worked ... no need to forceLogin"); + $forceLogin = FALSE; + } else { + $error = "Internal error -- problem while creating cookies. Please contact an administrator."; + } + } else { + // credentials in cookies don't match. + // dbgSquirt("Cookie does NOT match encryption"); + $error = "Authentication error -- The supplied credentials don't match our stored values. Please reauthenticate and try again."; + } + } else { + // dbgSquirt("...error while getting salt"); + // error while trying to get salt value + $error = "Internal error -- unable to validate supplied credentials. Please reauthenticate and try again."; + } + } else { + // cookies were unset or contained empty values + // dbgSquirt("Cookies unset or empty"); + if (FALSE == $ignoreBlanks) { + $error = "Please log in."; } + } + + dbgSquirt("Returning -- ". empty($error)); + return(empty($error)); +} + +/* +Purpose: change the fullname saved for a user + +return values are: + TRUE = change succeeded. + FALSE = change failed. */ +function updateFullname($username, $newFullname) { + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + $query="update Users set fullname = '$newFullname' where username = '$username'"; + + $result = mysql_query($query) or die(mysql_error()); + + $count = mysql_affected_rows(); + + if ((1 == $count) && (TRUE == $result)) { + // no error and 1 row updated + $state = TRUE; + } else { + $state = FALSE; } + + mysql_close($db); + return $state; +} + +/* +Purpose: Create an encrypted password based on the username and supplied + cleartext password. + +Returns encrypted password */ +function createPassword($username, $password) { + $encryptedPassword = md5($username . "::" . $password); + return $encryptedPassword; +} + +/* +Purpose: change the password saved for a user + +Note: expects the password to come in already encrypted + +return values are: + TRUE = change succeeded. + FALSE = change failed. */ +function updatePassword($username, $newPassword) { + dbgSquirt("============= Function: updatePassword ==========="); + + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + $query="update Users set password = '$newPassword' where username = '$username'"; + dbgSquirt("Query -- $query"); + + $result = mysql_query($query) or die(mysql_error()); + + $count = mysql_affected_rows(); + + if ((1 == $count) && (TRUE == $result)) { + // no error and 1 row updated + $state = TRUE; + } else { + $state = FALSE; } + + mysql_close($db); + return $state; +} + +/* +Purpose: change the email saved for a user + +return values are: + TRUE = change succeeded. + FALSE = change failed. */ +function updateEmail($username, $newEmail) { + dbgSquirt("============= Function: updateEmail ==========="); + + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + $query="update Users set email = '$newEmail' where username = '$username'"; + dbgSquirt("Query -- $query"); + + $result = mysql_query($query) or die(mysql_error()); + + $count = mysql_affected_rows(); + + if ((1 == $count) && (TRUE == $result)) { + // no error and 1 row updated + $state = TRUE; + } else { + $state = FALSE; } + + mysql_close($db); + return $state; +} + +/* +Purpose: Delete a resource + +Note: to limit risk this function makes sure the resourceId that is being + flagged for deletion is owned by the user passed in (which should be the + username from the authentication cookies) + +return values are: + TRUE = delete succeeded. + FALSE = delete failed. */ +function deleteResource($username, $resourceId) { + dbgSquirt("============= Function: deleteResource ==========="); + + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + + // first we need to get the userid from the username + $query="select id from Users where username = '$username'"; + dbgSquirt("Query -- $query"); + $result = mysql_query($query) or die(mysql_error()); + + $count=mysql_num_rows($result); + dbgSquirt("Rows -- $count"); + if ($count == 1) { + // we matched, so lets get the userid of the user + $userid = mysql_result($result,0,"id"); + mysql_free_result($result); + + // delete the resource + $query = "delete from Resources where userid = '$userid' and id = '$resourceId'"; + dbgSquirt("Query2 -- $query"); + + $result = mysql_query($query) or die(mysql_error()); + $count = mysql_affected_rows(); + + dbgSquirt("Rows -- $count"); + if ((1 == $count) && (TRUE == $result)) { + // no error and 1 row deleted (should only be 1 row since id is + // the primary key) + $state = TRUE; + } else { + $state = FALSE; } + } else { + $state = FALSE; } + + mysql_free_result($result); + mysql_close($db); + return $state; +} + +/* +Purpose: update a resource based on the resourceId + +return values are: + TRUE = update succeeded. + FALSE = update failed. */ +function updateResource($resourceId,$username,$resource,$forwardType, + $forward,$voicemail) { + dbgSquirt("============= Function: updateResource ==========="); + + $db = mysql_connect("localhost","apache","apache") or die(mysql_error()); + mysql_select_db("repro",$db) or die (mysql_error()); + + // first we need to get the userid from the username + $query="select id from Users where username = '$username'"; + dbgSquirt("Query -- $query"); + $result = mysql_query($query) or die(mysql_error()); + + $count=mysql_num_rows($result); + dbgSquirt("Rows -- $count"); + if ($count == 1) { + // we matched, so lets get the userid of the user + $userid = mysql_result($result,0,"id"); + mysql_free_result($result); + + // delete the resource + $query = "update Resources set aor='$resource',forwardType='$forwardType',forwardDestination='$forward',voicemail='$voicemail' where userid = '$userid' and id = '$resourceId'"; + dbgSquirt("Query2 -- $query"); + + $result = mysql_query($query) or die(mysql_error()); + $count = mysql_affected_rows(); + + dbgSquirt("Rows -- $count"); + if ((1 == $count) && (TRUE == $result)) { + // no error and 1 row modified (should only be 1 row since id is + // the primary key) + $state = TRUE; + } else { + $state = FALSE; } + } else { + $state = FALSE; } + + mysql_free_result($result); + mysql_close($db); + return $state; +} +?> diff --git a/src/libs/resiprocate/repro/php/savemodifiedresource.php b/src/libs/resiprocate/repro/php/savemodifiedresource.php new file mode 100644 index 00000000..29c4a73e --- /dev/null +++ b/src/libs/resiprocate/repro/php/savemodifiedresource.php @@ -0,0 +1,118 @@ +<?php +require('reprofunctions.php'); +dbgSquirt("============= Save Modified Resource ==============="); +dbgSquirt(dbgShowFile($_POST)); + +$result = checkCookies($forceLogin,$error,FALSE); +if (!($result) || $forceLogin) { + // we got an error back that occurred while checkCookies was being run, + // or authentication failed. Either way, bounce them back to the login screen + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/index.php?error=$error"); + exit; + } +$username = $_COOKIE['user']; +$bounceURL = "Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/editresource.php?aor=" . $_POST['aor'] . + "&forwardType=" . $_POST['forwardType'] . + "&forward=" . $_POST['forward'] . + "&voicemail=" . $_POST['voicemail'] . + "&error="; + +// make sure post variables have arrived +// note -- can't check for forward because if it was diabled on the previous +// screen by clicking No, it will not be sent as a POST variable +if (!isset($_POST['resourceId']) || !isset($_POST['aor']) || + !isset($_POST['forwardType']) || !isset($_POST['voicemail'])) { + header($bounceURL . "The information to modify a resource was not provided. Please enter the information and click Save. If this error reoccurs, contact an administrator."); + exit; + } + +// check if the user pressed cancel ... if so, back to user home +if ("Cancel" == $_POST['submit']) { + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . "/userhome.php"); + exit; + } + +// check that resourceId only contains digits +// the valid number check is for security to make sure that no one hacks the +// URL and replaces the resourceId param with something designed to screw up +// the database. In this case, there is nothing the user can fix, so send them +// back to userhome. +$resourceId = $_POST['resourceId']; +if (!ereg("^[0-9]+$",$resourceId)) { + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . "/userhome.php?error=The information to modify a resource was not provided. Please enter the information and click Save. If this error reoccurs, contact an administrator."); + exit; + } + +// check that resource name is non-blank +if (empty($_POST['aor'])) { + header($bounceURL . "The address must be filled in."); + exit; + } +$aor = $_POST['aor']; + +// check that if forwarding is Yes, then a forward address must be provided +// in this case we need to check forwardType against "Yes" rather than "Y since +// the value comes from the previous form rather than that database (which only +// stores 1 char) +if (($_POST['forwardType'] == "Yes") && empty($_POST['forward'])) { + header($bounceURL . "If forwarding is turned on, a forwarding address must be provided."); + exit; + } +$forwardType = $_POST['forwardType']; +$forward = $_POST['forward']; +$voicemail = $_POST['voicemail']; + +// TODO: add code to validate that the forwarding address and voicemail +// address are valid SIP URI's + +// update the resource to the database +// note: as an additional security measure, we pass in username and only update +// the resourceId if that resourceId matches the authenticated user. As a +// consequence, even if the user hacks the URL and replaces the resourceId +// with a new value, they will be unable to modify any resources not associated +// with the user they are logged in as ... so they can't do any damage since +// all the resourceId's associated with their user are available to them +// anyway +if (updateResource($resourceId,$username,$aor,$forwardType,$forward,$voicemail)) { + // resource modified successfully + $title = "Resource Modified"; + $heading = "Resource Modified"; + $msg = "Successfully updated the resource <em>$aor.</em>"; + } else { + $title = "Error While Updating Resource"; + $heading = "Error While Updating Resource"; + $msg = "An error occurred while attempting to update this resource. Please contact an administrator."; + } +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: savenewresource.php +Purpose: Validate the user provided information about a new resource and then + add that resource to their profile +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> + <title><?php echo $title; ?></title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1><?php echo $heading; ?></h1> +<hr /> +<p><?php echo $msg; ?></p> +<br /><hr /> +<a href="userhome.php">Return to User Home</a><br /> +<a href="logout.php">Logout</a><br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/savenewresource.php b/src/libs/resiprocate/repro/php/savenewresource.php new file mode 100644 index 00000000..569d5bf6 --- /dev/null +++ b/src/libs/resiprocate/repro/php/savenewresource.php @@ -0,0 +1,100 @@ +<?php +require('reprofunctions.php'); +dbgSquirt("============= Save New Resource ==============="); +dbgSquirt(dbgShowFile($_POST)); + +$result = checkCookies($forceLogin,$error,FALSE); +if (!($result) || $forceLogin) { + // we got an error back that occurred while checkCookies was being run, + // or authentication failed. Either way, bounce them back to the login screen + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/index.php?error=$error"); + exit; + } +$username = $_COOKIE['user']; + +$bounceURL = "Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/addresource.php?aor=" . $_POST['aor'] . + "&forwardType=" . $_POST['forwardType'] . + "&forward=" . $_POST['forward'] . + "&voicemail=" . $_POST['voicemail'] . + "&error="; + +// make sure post variables have arrived +// note -- can't check for forward because if it was diabled on the previous +// screen by clicking No, it will not be sent as a POST variable +if (!isset($_POST['aor']) || !isset($_POST['forwardType']) || + !isset($_POST['voicemail'])) { + header($bounceURL . "The information to create a new resource was not provided. Please enter the information and click Save. If this error reoccurs, contact an administrator."); + exit; + } + +// check if the user pressed cancel ... if so, back to user home +if ("Cancel" == $_POST['submit']) { + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . "/userhome.php"); + exit; + } + +// check that resource name is non-blank +if (empty($_POST['aor'])) { + header($bounceURL . "The address must be filled in."); + exit; + } +$aor = $_POST['aor']; + +// check that if forwarding is Yes, then a forward address must be provided +// in this case we need to check forwardType against "Yes" rather than "Y since +// the value comes from the previous form rather than that database (which only +// stores 1 char) +if (($_POST['forwardType'] == "Yes") && empty($_POST['forward'])) { + header($bounceURL . "If forwarding is turned on, a forwarding address must be provided."); + exit; + } +$forwardType = $_POST['forwardType']; +$forward = $_POST['forward']; +$voicemail = $_POST['voicemail']; + +// TODO: add code to validate that the forwarding address and voicemail +// address are valid SIP URI's + +// save the resource to the database +if (createResource($username,$aor,$forwardType,$forward,$voicemail)) { + // new resource added successfully + $title = "New Resource Added"; + $heading = "New Resource Added"; + $msg = "Successfully added the new resource <em>$aor.</em>"; + } else { + $title = "Error While Adding Resource"; + $heading = "Error While Adding Resource"; + $msg = "An error occurred while attempting to add this resource. Please contact an administrator."; + } +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: savenewresource.php +Purpose: Validate the user provided information about a new resource and then + add that resource to their profile +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> + <title><?php echo $title; ?></title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1><?php echo $heading; ?></h1> +<hr /> +<p><?php echo $msg; ?></p> +<br /><hr /> +<a href="userhome.php">Return to User Home</a><br /> +<a href="logout.php">Logout</a><br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/security.text b/src/libs/resiprocate/repro/php/security.text new file mode 100644 index 00000000..0f6eeb1e --- /dev/null +++ b/src/libs/resiprocate/repro/php/security.text @@ -0,0 +1,27 @@ +when user logs in, get username and password +create password string (username:realm:password), md5, and check against db + +then they are authenticated + +create a cookie called "authentication" with + sha1 (username + salt) + expiration of now() + 15 min + +on each secure page, + verify that the user and authentication cookies are set + compare the value of the cookie to sha1 (username+salt) + + if not set or not valid + (initial page only) -- if there are post values for user name + and password, try to log in + + (non initial page, or login fails) + redirect to login page with error message + else + reset expiration on cookie to now()+15 min + + + +** what about making the salt a global variable to avoid having to hit the DB +each page? In that design, how do you reset the value? Does it require a stop +& restart of web server? diff --git a/src/libs/resiprocate/repro/php/template.php b/src/libs/resiprocate/repro/php/template.php new file mode 100644 index 00000000..f91ffe2f --- /dev/null +++ b/src/libs/resiprocate/repro/php/template.php @@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: +Purpose: +Author: +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> +<title></title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1></h1> +<hr /> + +<br /><hr /> +<a href="index.php">Return to Welcome Page</a> +<br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/updateemail.php b/src/libs/resiprocate/repro/php/updateemail.php new file mode 100644 index 00000000..1869581e --- /dev/null +++ b/src/libs/resiprocate/repro/php/updateemail.php @@ -0,0 +1,90 @@ +<?php +require('reprofunctions.php'); +dbgSquirt("============= Update Email ==============="); + +// check that the user has authenticated +$result = checkCookies($forceLogin,$error,FALSE); +if (!($result) || $forceLogin) { + // we got an error back that occurred while checkCookies was being run, + // or authentication failed. Either way, bounce them back to the login screen + dbgSquirt("Authentication failed"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/index.php?error=$error"); + exit; + } +$username = $_COOKIE['user']; + +// check if we got to this page due to a submit or a cancel +dbgSquirt("Checking for cancel"); +if ("Cancel" == $_POST['submit']) { + dbgSquirt("...cancel"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/userhome.php"); + exit; + } + + +// verify that a new email was provided via POST +dbgSquirt("Checking post"); +if (!isset($_POST['newemail'])) { + // error .. no post variable provided ... possibly because they've jumped + // directly to this page? + dbgSquirt("...not set"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/changeemail.php?error=No new email was provided. Please enter one and click Save. If this error reoccurs, contact an administrator."); + exit; + } + +// verify that the new email is non-blank +$newEmail = $_POST['newemail']; +dbgSquirt("Checking blank -- $newEmail"); +if (empty($newEmail)) { + // error ... requested email is blank... bounce them back to change email page + dbgSquirt("...Empty"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/changeemail.php?error=The new email must not be blank."); + exit; + } + +// update the email for this user with the provided value +if (updateEmail($username,$newEmail)) { + // update successful + $title = "Email changed"; + $heading = "Email changed"; + $msg = "Email changed to <em>$newEmail</em>."; + } else { + // update failed + $title = "Error while changing email"; + $heading = "Error while changing email"; + $msg = "An error occurred while attempting to change your email. Please contact an administrator."; + } +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: updatefilename.php +Purpose: Check permissions, verify requested change, and update email +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> + <title><?php echo $title; ?></title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1><?php echo $heading; ?></h1> +<hr /> +<p><?php echo $msg; ?></p> +<br /><hr /> +<a href="userhome.php">Return to User Home</a><br /> +<a href="logout.php">Logout</a><br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/updatefullname.php b/src/libs/resiprocate/repro/php/updatefullname.php new file mode 100644 index 00000000..bca64d56 --- /dev/null +++ b/src/libs/resiprocate/repro/php/updatefullname.php @@ -0,0 +1,90 @@ +<?php +require('reprofunctions.php'); +dbgSquirt("============= Update Fullname ==============="); + +// check that the user has authenticated +$result = checkCookies($forceLogin,$error,FALSE); +if (!($result) || $forceLogin) { + // we got an error back that occurred while checkCookies was being run, + // or authentication failed. Either way, bounce them back to the login screen + dbgSquirt("Authentication failed"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/index.php?error=$error"); + exit; + } +$username = $_COOKIE['user']; + +// check if we got to this page due to a submit or a cancel +dbgSquirt("Checking for cancel"); +if ("Cancel" == $_POST['submit']) { + dbgSquirt("...cancel"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/userhome.php"); + exit; + } + + +// verify that a new fullname was provided via POST +dbgSquirt("Checking post"); +if (!isset($_POST['newfullname'])) { + // error .. no post variable provided ... possibly because they've jumped + // directly to this page? + dbgSquirt("...not set"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/changefullname.php?error=No new fullname was provided. Please enter one and click Save. If this error reoccurs, contact an administrator."); + exit; + } + +// verify that the new fullname is non-blank +$newFullname = $_POST['newfullname']; +dbgSquirt("Checking blank -- $newFullname"); +if (empty($newFullname)) { + // error ... requested name is blank... bounce them back to change name page + dbgSquirt("...Empty"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/changefullname.php?error=The new fullname must not be blank."); + exit; + } + +// update the fullname for this user with the provided value +if (updateFullname($username,$newFullname)) { + // update successful + $title = "Fullname changed"; + $heading = "Fullname changed"; + $msg = "Fullname changed to <em>$newFullname</em>."; + } else { + // update failed + $title = "Error while changing fullname"; + $heading = "Error while changing fullname"; + $msg = "An error occurred while attempting to change your fullname. Please contact an administrator."; + } +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: updatefilename.php +Purpose: Check permissions, verify requested change, and update fullname +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> + <title><?php echo $title; ?></title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1><?php echo $heading; ?></h1> +<hr /> +<p><?php echo $msg; ?></p> +<br /><hr /> +<a href="userhome.php">Return to User Home</a><br /> +<a href="logout.php">Logout</a><br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/updatepassword.php b/src/libs/resiprocate/repro/php/updatepassword.php new file mode 100644 index 00000000..45488982 --- /dev/null +++ b/src/libs/resiprocate/repro/php/updatepassword.php @@ -0,0 +1,135 @@ +<?php +require('reprofunctions.php'); +dbgSquirt("============= Update Password ==============="); + +// check that the user has authenticated +$result = checkCookies($forceLogin,$error,FALSE); +if (!($result) || $forceLogin) { + // we got an error back that occurred while checkCookies was being run, + // or authentication failed. Either way, bounce them back to the login screen + dbgSquirt("Authentication failed"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/index.php?error=$error"); + exit; + } +$username = $_COOKIE['user']; + +// check if we got to this page due to a submit or a cancel +dbgSquirt("Checking for cancel"); +if ("Cancel" == $_POST['submit']) { + dbgSquirt("...cancel"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/userhome.php"); + exit; + } + +// verify that a new password was provided via POST (and retyped) +dbgSquirt("Checking post"); +if (!isset($_POST['current']) || !isset($_POST['newpassword']) || + !isset($_POST['newpassword2'])) { + // error .. no post variables provided ... possibly because they've jumped + // directly to this page? + dbgSquirt("...not set"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/changepassword.php?error=No new password was provided. Please enter one and click Save. If this error reoccurs, contact an administrator."); + exit; + } + +// verify that the new password is non-blank +$newPassword = $_POST['newpassword']; +dbgSquirt("Checking blank -- $newPassword"); +if (empty($newPassword)) { + // error ... requested password is blank... bounce them back to change + // password page + dbgSquirt("...Empty"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/changepassword.php?error=The new password must not be blank."); + exit; + } + +// verify that the retype of the new password matches +$newPassword2 = $_POST['newpassword2']; +dbgSquirt("Checking match -- $newPassword and $newPassword2"); +if ($newPassword != $newPassword2) { + // error ... password entries don't match... bounce them back to change + // password page + dbgSquirt("...NO. Don't match"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/changepassword.php?error=Password and retyped password don't match"); + exit; + } + +// verify that the new password is actually different +$currentPassword = $_POST['current']; +dbgSquirt("Checking that new password is different -- $newPassword and $currentPassword"); +if ($newPassword == $currentPassword) { + // error ... password entries shouldn't match ... what's the point of changing + dbgSquirt("Trying to reuse the current password"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/changepassword.php?error=The new password is the same as the existing password."); + exit; + } + +// make sure the current password they entered matches +$encryptedPassword = createPassword($username,$currentPassword); +$result = validateUser($username,$encryptedPassword); +dbgSquirt("Verifying current password"); +if ("A" != $result) { + // either didn't match, or user is unverified or disabled + // only way a user should end up here and be unverified or disabled is if + // an admin changed their account status in the middle of a session. + // but we'll check for it anyway... + dbgSquirt("...doesn't match an active user"); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/changepassword.php?error=Current password doesn't match an active user. Please try again. If you receive this error again, contact an administrator."); + exit; + + } + +// update the password for this user with the provided value +$encryptedPassword = createPassword($username,$newPassword); + +if (updatePassword($username,$encryptedPassword)) { + // update successful + $title = "Password changed"; + $heading = "Password changed"; + $msg = "Password successfully updated."; + } else { + // update failed + $title = "Error while changing password"; + $heading = "Error while changing password"; + $msg = "An error occurred while attempting to change your password. Please contact an administrator."; + } +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: updatepassword.php +Purpose: Check permissions, verify requested change, and update password +Author: S. Chanin +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> + <title><?php echo $title; ?></title> +</head> + +<body> +<h1 class="title">Repro</h1> +<h1><?php echo $heading; ?></h1> +<hr /> +<p><?php echo $msg; ?></p> +<br /><hr /> +<a href="userhome.php">Return to User Home</a><br /> +<a href="logout.php">Logout</a><br /> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/php/userhome.php b/src/libs/resiprocate/repro/php/userhome.php new file mode 100644 index 00000000..634d6ec5 --- /dev/null +++ b/src/libs/resiprocate/repro/php/userhome.php @@ -0,0 +1,236 @@ +<?php + +require('reprofunctions.php'); +dbgSquirt("============= userhome ==============="); + +// TODO +/* There is a bug here ... if a user has authenticated successfully (and hence + the cookies for username and passwordMD5 are set) and then they use BACK + to go back to the login page, enter some values for username and + password, and click login, then what they just typed will be ignored, + and they will remain logged in under their original credentials. */ + +// this variable controls whether the user is forced back to the main page to +// login. For safety, the default value is to force you back. +$forceLogin = TRUE; +$error = ""; +$time = time(); + +if (!checkCookies($forceLogin,$error,TRUE)) { + // we got an error back that occurred while checkCookies was being run + dbgSquirt('Error from checkCookies'); + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . "/index.php?error=$error"); + exit; + } + +// if the cookie's didn't pass authentication, or if the cookie's passed BUT +// we've received new values for POST that don't match on username (they did +// a BACK to the login page w/o a logout and then did a new login), then +// try to authenticate via the POSTED values been supplied. +if (isset($_POST['username']) && ($_POST['username'] != $_COOKIE['user'])) + $forceLogin = TRUE; + +if ($forceLogin) { + dbgSquirt('forceLogin is still true... checking post variables'); + if (isset($_POST['username']) || isset($_POST['password'])) { + // we have one or more post variables + dbgSquirt('Post variables are set'); + if (empty($_POST['username']) || empty($_POST['password'])) { + // can't have empty values for username or password + dbgSquirt('...but one is empty'); + $error = "Authentication error -- you must enter a username and password."; + } else { + // we have non-empty values for username and password from POST so + // lets validate them + dbgSquirt('...both are non-empty [good]'); + $username = $_POST['username']; + $password = $_POST['password']; + $encryptedPassword = createPassword($username,$password); + + $state = validateUser($username,$encryptedPassword); + if ("N" == $state) { + dbgSquirt('Not a valid user'); + $error = "Authentication error -- Invalid username/password combination."; + } else if ("A" == $state) { + // active account and username/password match + dbgSquirt('Active account matched.'); + + // if we haven't already looked up the salt, do so now + $result = TRUE; + if (empty($salt)) { + dbgSquirt('Getting salt'); + $result = getSalt($salt); } + + if (FALSE == $result) { + // uh-oh ... we got an error getting the salt + dbgSquirt('Error in getSalt'); + $error = "Internal error -- failure while processing login. Please contact an administrator."; + } else { + dbgSquirt('Extending cookies'); + dbgSquirt("Time -- $time"); + dbgSquirt("Time + Duration -- ". ($time+$sessionDuration)); + $result = setcookie("user",$username,$time+$sessionDuration); + $result1 = setcookie("authentication",sha1($username . $salt), + $time+$sessionDuration); + + if ((TRUE == $result) && (TRUE == $result1)) { + // everything worked + dbgSquirt('Everything worked.'); + $forceLogin = FALSE; + } else { + dbgSquirt('Error while creating cookies'); + $error = "Internal error -- problem while creating cookies. Please contact an administrator."; + } + } + } else if ("U" == $state) { + // unverified account + dbgSquirt('Unverified Account'); + $error="This account has not been verified. Please check for the verification email you were sent as part of the signup process."; + } else if ("D" == $state) { + // disabled account + dbgSquirt('Disabled Account'); + $error = "This account has been disabled."; + } else { + // should not happen ... checked return value from validateUser + dbgSquirt('Unknown return code from validateUser'); + $error = "Internal Error -- error validating username/password. Please try again. This this error reoccurs, please contact an administrator."; + } + } + } else { + // no post variables supplied + dbgSquirt('No post variables'); + $error = "Authentication error -- you must enter a username and password."; + } + } else { + // forceLogin was FALSE ... that means the cookie's were valid + // so get username from the cookie + $username = $_COOKIE['user']; + } + +// after checking cookies and post variables, if a login is still needed, then +// redirect +dbgSquirt("After post check -- forceLogin = $forceLogin"); +if ($forceLogin) { + header("Location: http://" . $_SERVER['HTTP_HOST'] . + dirname($_SERVER['PHP_SELF']) . + "/index.php?error=$error"); + exit; + } +?> + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<!-- +System: Repro +File: userhome.php +Purpose: User Home Page. This displays the users personal information and + allows changes to be made. +Author: S. Chanin +--> + +<html> +<head> +<link rel="stylesheet" type="text/css" href="repro_style.css" /> +<title></title> +</head> + +<body> +<h1 class="title">Repro</h1> + +<h1>User Home Page</h1> +<hr /> + +<?php +// if we've looped back due to an error, show the message +if (isset($_GET["error"]) && !empty($_GET['error'])) { + echo '<p class="error">' . $_GET["error"] . "</p>\n"; +} +if (!lookupUserInformation($username,$id,$fullname,$domain,$email)) { + echo "<h2>Error -- Error while accessing account information</h2>\n"; + echo "<p>Please contact your administrator for assistance.</p>\n"; +} else { +?> +<!-- show basic user information with the user --> +<table border="0" cellpadding="5"> +<tr> +<td>Username</td> +<td><h2><?php echo $username ?></h2></td> +</tr> + +<tr> +<td>Fullname</td> +<td><?php echo $fullname ?></td> +<td><a href="changefullname.php">Change Fullname</a></td> +</tr> + +<tr> +<td>Password</td> +<td>********</td> +<td><a href="changepassword.php">Change Password</a></td> +</tr> + +<tr> +<td>Email</td> +<td><?php echo $email ?></td> +<td><a href="changeemail.php">Change Email</a></td> +</tr> + +<tr> +<td>Domain</td> +<td><?php echo $domain ?></td> +</tr> +</table> + +<!-- now show the resources associated with the user --> +<br /> +<table border="1"> +<th class="header">Address</th><th class="header">Forward</th> +<th class="header">Voicemail</th><th class="header">Edit</th><th class="header">Delete</th> + +<?php +$result = getResourcesByUsername($username,$resources); +// print "<br />Final Result --"; +// print_r($resources); +foreach ($resources as $r) { + // print "Row -- "; + // print_r($r); + // print "<br />"; + + $id = $r[0]; + $aor = $r[1]; + $forwardType = $r[2]; + $forward = $r[3]; + $voicemail = $r[4]; + + echo "<tr>"; + echo '<form method="post" action="modifyresource.php">'."\n"; + echo "<td>$aor</td>\n"; + if ("Y" == $forwardType) + echo "<td>$forward</td>\n"; + else + echo "<td>&nbsp</td>\n"; + echo "<td>$voicemail</td>\n"; + + echo '<td><input type="submit" name="edit" id="edit" value="Edit"/></td>'."\n"; + echo '<td><input type="submit" name="delete" id="delete" value="Delete"/></td>'."\n"; + echo '<input type="hidden" name="resourceId" id="resourceId" value="' . $id .'" />'."\n"; + echo '<input type="hidden" name="aor" id="aor" value="' . $aor .'" />'."\n"; + echo '<input type="hidden" name="forwardType" id="forwardType" value="' . $forwardType .'" />'."\n"; + echo '<input type="hidden" name="forward" id="forward" value="' . $forward .'" />'."\n"; + echo '<input type="hidden" name="voicemail" id="voicemail" value="' . $voicemail .'" />'."\n"; + echo "</form>\n"; + echo "</tr>\n"; +} +?> +</table> +<form method="post" action="addresource.php"> +<input type="submit" name="addResource" id="addResource" value="Add Resource" /> +</form> + +<?php +} ?> +<br /><hr /><a href="logout.php">Logout</a> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/repro.config b/src/libs/resiprocate/repro/repro.config new file mode 100644 index 00000000..7617e0cc --- /dev/null +++ b/src/libs/resiprocate/repro/repro.config @@ -0,0 +1,720 @@ +######################################################## +# repro configuration file +######################################################## + + +######################################################## +# Log settings +######################################################## + +# Logging Type: syslog|cerr|cout|file +# Note: Logging to cout can negatively effect performance. +# When repro is placed into production 'file' or +# 'syslog' should be used. +LoggingType = cout + +# Logging level: NONE|CRIT|ERR|WARNING|INFO|DEBUG|STACK +LogLevel = INFO + +# Log Filename +LogFilename = repro.log + +# Log file Max Bytes +LogFileMaxBytes = 5242880 + + +######################################################## +# Transport settings +######################################################## + +# Local IP Address to bind SIP transports to. If left blank +# repro will bind to all adapters. +#IPAddress = 192.168.1.106 +#IPAddress = 2001:5c0:1000:a::6d +IPAddress = + +# Local port to listen on for SIP messages over UDP - 0 to disable +UDPPort = 5060 + +# Local port to listen on for SIP messages over TCP - 0 to disable +TCPPort = 5060 + +# Local port to listen on for SIP messages over TLS - 0 to disable +TLSPort = 0 + +# Local port to listen on for SIP messages over DTLS - 0 to disable +DTLSPort = 0 + +# TLS domain name for this server (note: domain cert for this domain must be present) +TLSDomainName = + +# Whether or not we ask for (Optional) or expect (Mandatory) TLS +# clients to present a client certificate +# Possible values: +# None: client can connect without any cert, if a cert is sent, it is not checked +# Optional: client can connect without any cert, if a cert is sent, it must be acceptable to us +# Mandatory: client can not connect without any cert, cert must be acceptable to us +# How we decide if a cert is acceptable: it must meet two criteria: +# 1. it must be signed by a CA that we trust (see CADirectory) +# 2. the domain or full sip: URI in the cert must match the From: URI of all +# SIP messages coming from the peer +TLSClientVerification = None + +# Whether we accept the subjectAltName email address as if it was a SIP +# address (when checking the validity of a client certificate) +# Very few commercial CAs offer support for SIP addresses in subjectAltName +# For many purposes, an email address subjectAltName may be considered +# equivalent within a specific domain. +# Currently, this accepts such certs globally (for any incoming connection), +# not just for connections from the local users. +TLSUseEmailAsSIP = false + +# Alternate and more flexible method to specify transports to bind to. If specified here +# then IPAddress, and port settings above are ignored. +# Transports MUST be numbered in sequential order, starting from 1. Possible settings are: +# Transport<Num>Interface = <IPAddress>:<Port> +# Transport<Num>Type = <'TCP'|'UDP'|'TLS'|'DTLS'> - default is UDP if missing +# Transport<Num>TlsDomain = <TLSDomain> - only required if transport is TLS or DTLS +# Transport<Num>TlsClientVerification = <'None'|'Optional'|'Mandatory'> - default is None +# Transport<Num>RecordRouteUri = <'auto'|URI> - if set to auto then record route URI +# is automatically generated from the other +# transport settings. Otherwise explicity +# enter the full URI you want repro to use. +# Do not specify 'auto' if you specified +# the IPAddress as INADDR_ANY (0.0.0.0). +# If nothing is specified then repro will +# use the global RecordRouteUri setting. +# +# Transport<Num>RcvBufLen = <SocketReceiveBufferSize> - currently only applies to UDP transports, +# leave empty to use OS default +# Example: +# Transport1Interface = 192.168.1.106:5060 +# Transport1Type = TCP +# Transport1RecordRouteUri = auto +# +# Transport2Interface = 192.168.1.106:5060 +# Transport2Type = UDP +# Transport2RecordRouteUri = auto +# Transport2RcvBufLen = 10000 +# +# Transport3Interface = 192.168.1.106:5061 +# Transport3Type = TLS +# Transport3TlsDomain = sipdomain.com +# Transport3TlsClientVerification = Mandatory +# Transport3RecordRouteUri = sip:h1.sipdomain.com;transport=TLS + + +# Comma separated list of DNS servers, overrides default OS detected list (leave blank +# for default) +DNSServers = + +# Enable IPv6 +EnableIPv6 = false + +# Enable IPv4 +DisableIPv4 = false + +# Port on which to run the HTTP configuration interface and/or certificate server +# 0 to disable (default: 5080) +HttpPort = 5080 + +# disable HTTP challenges for web based configuration GUI +DisableHttpAuth = false + +# Web administrator password +HttpAdminPassword = admin + +# Port on which to listen for and send XML RPC messaging used in command processing +# 0 to disable (default: 5081) +CommandPort = 5081 + +# Port on which to listen for and send XML RPC messaging used in registration sync +# process - 0 to disable (default: 0) +RegSyncPort = 0 + +# Hostname/ip address of another instance of repro to synchronize registrations with +# (note xmlrpcport must also be specified) +RegSyncPeer = + + +######################################################## +# Misc settings +######################################################## + +# Must be true or false, default = false, not supported on Windows +Daemonize = false + +# On UNIX it is normal to create a PID file +# if unspecified, no attempt will be made to create a PID file +#PidFile = /var/run/repro/repro.pid + +# Path to load certificates from (default: "$(HOME)/.sipCerts on *nix, and c:\sipCerts +# on windows) +# Note that repro loads ALL root certificates found by the settings +# CertificatePath, CADirectory and CAFile. Setting one option does +# not disable the other options. +# Certificates in this location have to match one of the filename +# patterns expected by the legacy reSIProcate SSL code: +# domain_cert_NAME.pem, root_cert_NAME.pem, ... +CertificatePath = + +# Path to load root certificates from +# Iff this directory is specified, all files in the directory +# will be loaded as root certificates, prefixes and suffixes are +# not considered +# Note that repro loads ALL root certificates found by the settings +# CertificatePath, CADirectory and CAFile. Setting one option does +# not disable the other options. +# On Debian, the typical location is /etc/ssl/certs +#CADirectory = /etc/ssl/certs + +# Specify a single file containing one or more root certificates +# and possible chain/intermediate certificates to be loaded +# Iff this filename is specified, the certificates in the file will +# be loaded as root certificates +# +# This does NOT currently support bundles of unrelated root certificates +# stored in the same PEM file, it ONLY supports related/chained root +# certificates. If multiple roots must be supported, use the CADirectory +# option. +# +# In the future, this behavior may change to load a bundle, +# such as /etc/ssl/certs/ca-certificates.txt on Debian and +# /etc/pki/tls/cert.pem on Red Hat/CentOS +# +# Note that repro loads ALL root certificates found by the settings +# CertificatePath, CADirectory and CAFile. Setting one option does +# not disable the other options. +# +# This example loads just the CACert.org chain, which typically +# includes the class 1 root and the class 3 root (signed by the class 1 root) +#CAFile = /etc/ssl/certs/cacert.org.pem + +# The Path to read and write Berkely DB database files +DatabasePath = ./ + +# The hostname running MySQL server to connect to, leave blank to use BerkelyDB. +# The value of host may be either a host name or an IP address. If host is "localhost", +# a connection to the local host is assumed. For Windows, the client connects using a +# shared-memory connection, if the server has shared-memory connections enabled. Otherwise, +# TCP/IP is used. For Unix, the client connects using a Unix socket file. For a host value of +# "." on Windows, the client connects using a named pipe, if the server has named-pipe +# connections enabled. If named-pipe connections are not enabled, an error occurs. +# WARNING: repro must be compiled with the USE_MYSQL flag in order for this work. +MySQLServer = + +# The MySQL login ID to use when connecting to the MySQL Server. If user is empty string "", +# the current user is assumed. Under Unix, this is the current login name. Under Windows, +# the current user name must be specified explicitly. +MySQLUser = root + +# The password for the MySQL login ID specified. +MySQLPassword = root + +# The database name on the MySQL server that contains the repro tables +MySQLDatabaseName = repro + +# If port is not 0, the value is used as the port number for the TCP/IP connection. Note that +# the host parameter determines the type of the connection. +MySQLPort = 3306 + +# The Users and MessageSilo database tables are different from the other repro configuration +# database tables, in that they are accessed at runtime as SIP requests arrive. It may be +# desirable to use BerkeleyDb for the other repro tables (which are read at starup time, then +# cached in memory), and MySQL for the runtime accessed tables; or two seperate MySQL instances +# for these different table sets. Use the following settings in order to specify a seperate +# MySQL instance for use by the Users and MessageSilo tables. +# +# WARNING: repro must be compiled with the USE_MYSQL flag in order for this work. +# +# Note: If this setting is left blank then repro will fallback all remaining my sql +# settings to use the global MySQLServer settings. If the MySQLServer setting is also +# blank, then repro will use BerkelyDB for all configuration tables. See the +# documentation on the global MySQLServer settings for more details on the following +# individual settings. +RuntimeMySQLServer = +RuntimeMySQLUser = root +RuntimeMySQLPassword = root +RuntimeMySQLDatabaseName = repro +RuntimeMySQLPort = 3306 + +# If you would like to be able to authenticate users from a MySQL source other than the repro user +# database table itself, then specify the query here. The following conditions apply: +# 1. The database table must reside on the same MySQL server instance as the repro database +# or Runtime tables database. +# 2. The statement provided will be UNION'd with the hardcoded repro query, so that auth from +# both sources is possible. Note: If the same user exists in both tables, then the repro +# auth info will be used. +# 3. The provided SELECT statement must return the SIP A1 password hash of the user in question. +# 4. The provided SELECT statement must contain two tags embedded into the query: $user and $domain +# These tags should be used in the WHERE clause, and repro will replace these tags with the +# actual user and domain being queried. +# Example: SELECT sip_password_ha1 FROM directory.users WHERE sip_userid = '$user' AND +# sip_domain = '$domain' AND account_status = 'active' +MySQLCustomUserAuthQuery = + +# Session Accounting - When enabled resiprocate will push a JSON formatted +# events for sip session related messaging that the proxy receives, +# to a persistent message queue that uses berkeleydb backed storage. +# The following session events are logged: +# Session Created - INVITE passing authentication was received +# Session Routed - received INVITE was forward to a target +# Session Redirected - session was 3xx redirected or REFERed +# Session Established - there was 2xx answer to an INVITE (only generate for first 2xx) +# Session Cancelled - CANCEL was received +# Session Ended - BYE was received from either end +# Session Error - a 4xx, 5xx, or 6xx response was sent to the inviter +# Consuming Accounting Events: +# Users must ensure that this message queue is consumed, or it will grow without +# bound. A queuetostream consumer process is provided, that will consume the +# events from the message queue and stream them to stdout. This output stream can +# be consumed by linux scripting tools and converted to database records or some +# other relevant representation of the data. +# For example: ./queuetostream ./sessioneventqueue > streamconsumer +# In the future a MySQL consumer may also be provided in order to update +# session accounting records in a MySQL database table. +SessionAccountingEnabled = false + +# The following setting determines if repro will add routing header information +# (ie. Route, and Record-Route headers)to the Session Created, Session Routed +# and Session Established events. +SessionAccountingAddRoutingHeaders = false + +# The following setting determines if we will add via header information to +# the Session Created event. +SessionAccountingAddViaHeaders = false + +# Registration Accounting - When enabled resiprocate will push a JSON formatted +# events for every registration, re-registration, and unregistration message +# received to a persistent message queue that uses berkeleydb backed storage. +# The following registration events are logged: +# Registration Added - initial registration received +# Registration Refreshed - registration refresh received / re-register +# Registration Removed - registration removed by client / unregister +# Registration Removed All - all contacts registration remove / unregister +# Consuming Accounting Events: +# Users must ensure that this message queue is consumed, or it will grow without +# bound. A queuetostream consumer process is provided, that will consume the +# events from the message queue and stream them to stdout. This output stream can +# be consumed by linux scripting tools and converted to database records or some +# other relevant representation of the data. +# For example: ./queuetostream ./regeventqueue > streamconsumer +# In the future a MySQL consumer may also be provided in order to update +# login/registration accounting records in a MySQL database table. +RegistrationAccountingEnabled = false + +# The following setting determines if repro will add routing header information +# (ie. Route and Path headers)to registration accounting events. +RegistrationAccountingAddRoutingHeaders = false + +# The following setting determines if we will add via header information to +# the registration accounting events. +RegistrationAccountingAddViaHeaders = false + +# The following setting determines if we log the RegistrationRefreshed events +RegistrationAccountingLogRefreshes = false + +# Run a Certificate Server - Allows PUBLISH and SUBSCRIBE for certificates +EnableCertServer = false + +# Value of server header for local UAS responses +ServerText = + +# Enables Congestion Management +CongestionManagement = true + +# Congestion Management Metric - can take one of the following values: +# SIZE : Based solely on the number of messages in each fifo +# TIME_DEPTH : Based on the age of the oldest (front-most) message +# in each fifo. +# WAIT_TIME : Based on the expected wait time for each fifo; this is +# calculated by multiplying the size by the average service time. +# This is the recommended metric. +CongestionManagementMetric = WAIT_TIME + +# Congestion Management Tolerance for the given metric. This determines when the RejectionBehavior +# changes. +# 0-80 percent of max tolerance -> NORMAL (Not rejecting any work.) +# 80-100 percent of max tolerance -> REJECTING_NEW_WORK (Refuses new work, +# not continuation of old work.) +# >100 percent of max tolerance -> REJECTING_NON_ESSENTIAL (Rejecting all work +# that is non-essential to the health of the system (ie, if dropping +# something is liable to cause a leak, instability, or state-bloat, don't drop it. +# Otherwise, reject it.) +# Units specified are dependent on Metric specified above: +# If Metric is SIZE then units are number of messages +# If Metric is TIME_DEPTH then units are the number seconds old the oldest message is +# If Metric is WAIT_TIME then units are the expected wait time of each fifo in milliseconds +CongestionManagementTolerance = 200 + +# Specify the number of seconds between writes of the stack statistics block to the log files. +# Specifying 0 will disable the statistics collection entirely. If disabled the statistics +# also cannot be retreived using the reprocmd interface. +StatisticsLogInterval = 3600 + +# Use MultipleThreads stack processing. +ThreadedStack = true + +# The number of worker threads used to asynchronously retrieve user authentication information +# from the database store. +NumAuthGrabberWorkerThreads = 2 + +# The number of worker threads in Async Processor tread pool. Used by all Async Processors +# (ie. RequestFilter) +NumAsyncProcessorWorkerThreads = 2 + +# Specify domains for which this proxy is authorative (in addition to those specified on web +# interface) - comma separate list +# Notes: * Domains specified here cannot be used when creating users, domains used in user +# AORs must be specified on the web interface. +# * In previous versions of repro, localhost, 127.0.0.1, the machine's hostname, +# and all interface addresses would automatically be appended to this +# configuration parameter. From now on, such values must be listed +# here explicitly if required, e.g. +# +# Domains = localhost, 127.0.0.1, sip-server.example.org, 10.83.73.80 +# +# although when using TLS only, it is not desirable or necessary to +# add such values. +# +Domains = + +# Uri to use as Record-Route +RecordRouteUri = + +# Force record-routing +# WARNING: Before enabling this, ensure you have a RecordRouteUri setup, or are using +# the alternate transport specification mechanism and defining a RecordRouteUri per +# transport: TransportXRecordRouteUri +ForceRecordRouting = false + +# Assume path option +AssumePath = false + +# Disable registrar +DisableRegistrar = false + +# Specify a comma separate list of enum suffixes to search for enum dns resolution +EnumSuffixes = + +# Specify the target domain(s) for ENUM logic support. When a dialed SIP URI +# is addressed to +number@somedomain, +# where somedomain is an element of EnumDomains, +# the ENUM logic will be applied for the number +# If empty, ENUM is never used +EnumDomains = + +# Specify length of timer C in sec (0 or negative will disable timer C) - default 180 +TimerC = 180 + +# Override the default value of T1 in ms (you probably should not change this) - leave +# as 0 to use default of 500ms) +TimerT1 = 0 + +# Disable outbound support (RFC5626) +# WARNING: Before enabling this, ensure you have a RecordRouteUri setup, or are using +# the alternate transport specification mechanism and defining a RecordRouteUri per +# transport: TransportXRecordRouteUri +DisableOutbound = true + +# Set the draft version of outbound to support (default: RFC5626) +# Other accepted values are the versions of the IETF drafts, before RFC5626 was issued +# (ie. 5, 8, etc.) +OutboundVersion = 5626 + +# There are cases where the first hop in a particular network supports the concept of outbound +# and ensures all messaging for a client is delivered over the same connection used for +# registration. This could be a SBC or other NAT traversal aid router that uses the Path +# header. However such endpoints may not be 100% compliant with outbound RFC and may not +# include a ;ob parameter in the path header. This parameter is required in order for repro +# to have knowledge that the first hop does support outbound, and it will reject registrations +# that appear to be using outboud (ie. instanceId and regId) with a 439 (First Hop Lacks Outbound +# Support). In this case it can be desirable when using repro as the registrar to not reject +# REGISTRATION requests that contain an instanceId and regId with a 439. +# If this setting is enabled, then repro will assume the first hop supports outbound +# and not return this error. +AssumeFirstHopSupportsOutbound = false + +# Enable use of flow-tokens in non-outbound cases +# WARNING: Before enabling this, ensure you have a RecordRouteUri setup, or are using +# the alternate transport specification mechanism and defining a RecordRouteUri per +# transport: TransportXRecordRouteUri +EnableFlowTokens = false + +# Enable use of flow-tokens in non-outbound cases for clients detected to be behind a NAT. +# This a more selective flow token hack mode for clients not supporting RFC5626. The +# original flow token hack (EnableFlowTokens) will use flow tokens on all client requests. +# Possible values are: DISABLED, ENABLED and PRIVATE_TO_PUBLIC. +# WARNING: Before enabling this, ensure you have a RecordRouteUri setup, or are using +# the alternate transport specification mechanism and defining a RecordRouteUri per +# transport: TransportXRecordRouteUri +ClientNatDetectionMode = DISABLED + +# Set to greater than 0 to enable addition of Flow-Timer header to REGISTER responses if +# outbound is enabled (default: 0) +FlowTimer = 0 + + +######################################################## +# CertificateAuthenticator Monkey Settings +######################################################## + +# Enables certificate authenticator - note you MUST use a TlsTransport +# with TlsClientVerification set to Optional or Mandatory. +# There are two levels of checking: +# a) cert must be signed by a CA trusted by the stack +# b) the CN or one of the subjectAltName values must match the From: +# header of each SIP message on the TlsConnection +# Examples: +# Cert 1: +# common name = daniel@pocock.com.au +# => From: <daniel@pocock.com.au> is the only value that will pass +# Cert 2: +# subjectAltName = pocock.com.au +# => From: <<anything>@pocock.com.au> will be accepted +# Typically, case 1 is for a real client connection (e.g. Jitsi), case 2 +# (whole domain) is for federated SIP proxy-to-proxy communication (RFC 5922) +EnableCertificateAuthenticator = false + +# A static text file that contains mappings of X.509 Common Names to +# permitted SIP `From:' addresses +# +# Without this file, the default behavior of the CertificateAuthenticator +# ensures that the `From:' address in SIP messages must match the +# Common Name or one of the subjectAltNames from the X.509 certificate +# +# When this file is supplied, the CertificateAuthenticator will continue +# to allow SIP messages where there is an exact match between the +# certificate and the `From:' address, but it will also allow +# the holder of a particular certificate to use any of the `mapped' +# `From:' addresses specified in the mappings file +# +# File format: +# common name<TAB><mapping>,<mapping>,... +# +# where: +# <TAB> is exactly one tab +# <mapping> is `user@domain' or just `domain' +# +CommonNameMappings = /etc/repro/tlsUserMappings.txt + + +######################################################## +# DigestAuthenticator Monkey Settings +######################################################## + +# Disable DIGEST challenges - disables this monkey +DisableAuth = false + +# Http hostname for this server (used in Identity headers) +HttpHostname = + +# Disable adding identity headers +DisableIdentity = false + +# Enable addition and processing of P-Asserted-Identity headers +EnablePAssertedIdentityProcessing = false + +# Disable auth-int DIGEST challenges +DisableAuthInt = false + +# Send 403 if a client sends a bad nonce in their credentials (will send a new +# challenge otherwise) +RejectBadNonces = false + +# allow To tag in registrations +AllowBadReg = false + + +######################################################## +# RequestFilter Monkey Settings +######################################################## + +# Disable RequestFilter monkey processing +DisableRequestFilterProcessor = false + +# Default behavior for when no matching filter is found. Leave empty to allow +# request processing to continue. Otherwise set to a SIP status error code +# (400-699) that should be used to reject the request (ie. 500, Server Internal +# Error). +# The status code can optionally be followed by a , and SIP reason text. +RequestFilterDefaultNoMatchBehavior = + +# Default behavior for SQL Query db errors. Leave empty to allow request processing +# to continue. Otherwise set to a SIP status error code (400-699) that should be +# used to reject the request (ie. 500 - Server Internal Error). +# The status code can optionally be followed by a , and SIP reason text. +# Note: DB support for this action requires MySQL support. +RequestFilterDefaultDBErrorBehavior = 500, Server Internal DB Error + +# The hostname running MySQL server to connect to for any blocked entries +# that are configured to used a SQL statement. +# WARNING: repro must be compiled with the USE_MYSQL flag in order for this work. +# +# Note: If this setting is left blank then repro will fallback all remaining my sql +# settings to use the global RuntimeMySQLServer or MySQLServer settings. See the +# documentation on the global MySQLServer settings for more details on the following +# individual settings. +RequestFilterMySQLServer = +RequestFilterMySQLUser = root +RequestFilterMySQLPassword = root +RequestFilterMySQLDatabaseName = +RequestFilterMySQLPort = 3306 + + +######################################################## +# StaticRoute Monkey Settings +######################################################## + +# Specify where to route requests that are in this proxy's domain - disables the +# routes in the web interface and uses a SimpleStaticRoute monkey instead. +# A comma seperated list of routes can be specified here and each route will +# be added to the outbound Requests with the RequestUri left in tact. +Routes = + +# Parallel fork to all matching static routes +ParallelForkStaticRoutes = false + +# By default (false) we will stop looking for more Targets if we have found +# matching routes. Setting this value to true will allow the LocationServer Monkey +# to run after StaticRoutes have been found. In this case the matching +# StaticRoutes become fallback targets, processed only after all location server +# targets fail. +ContinueProcessingAfterRoutesFound = false + + +######################################################## +# Message Silo Monkey Settings +######################################################## + +# Specify where the Message Silo is enabled or not. If enabled, +# then repro will store MESSAGE requests for users that are not online. +# When the user is back online (ie. registers with repro), the stored +# messages will be delivered. +MessageSiloEnabled = false + +# A regular expression that can be used to filter which URI's not to +# do message storage (siloing) for. Destination/To URI's matching +# this regular expression will not be silo'd. +MessageSiloDestFilterRegex = + +# A regular expression that can be used to filter which body/content/mime +# types not to do message storage (siloing) for. Content-Type's matching +# this regular expression will not be silo'd. +MessageSiloMimeTypeFilterRegex = application\/im\-iscomposing\+xml + +# The number of seconds a message request will be stored in the message silo. +# Messages older than this time, are candidates for deletion. +# Default (259200 seconds = 30 days) +MessageSiloExpirationTime = 2592000 + +# Flag to indicate if a Date header should be added to replayed SIP +# MESSAGEs from the silo, when a user registers. +MessageSiloAddDateHeader = true + +# Defines the maximum message content length (bytes) that will be stored in +# the message silo. Messages with a Content-Length larger than this +# value will be discarded. +# WARNING: Do not increasing this value beyond the capabilities of the +# database storage or internal buffers. +# Note: AbstractDb uses a read buffer size of 8192 - do not exceed this size. +MessageSiloMaxContentLength = 4096 + +# The status code returned to the sender when a messages is successfully +# silo'd. +MessageSiloSuccessStatusCode = 202 + +# The status code returned to the sender when a messages mime-type matches +# the MessageSiloMimeTypeFilterRegex. Can be used to avoid sending errors +# to isComposing mime bodies that don't need to be silod. Set to 0 to use +# repro standard response (ie. 480). +MessageSiloFilteredMimeTypeStatusCode = 200 + +# The status code returned to the sender when a messages is not silo'd due +# to the MaxContentLength being exceeded. +MessageSiloFailureStatusCode = 480 + + +######################################################## +# Recursive Redirect Lemur Settings +######################################################## + +# Handle 3xx responses in the proxy - enables the Recursive Redirect Lemur +RecursiveRedirect = false + + +######################################################## +# Geo Proximity Target Sorter Baboon Settings +######################################################## + +# If enabled, then this baboon can post-process the target list. +# This includes targets from the StaticRoute monkey and/or targets +# from the LocationServer monkey. Requests that meet the filter +# criteria will have their Target list, flatened (serialized) and +# ordered based on the proximity of the target to the client sending +# the request. Proximity is determined by looking for a +# x-repro-geolocation="<latitude>,<longitude>" parameter on the Contact +# header of a received request, or the Contact headers of Registration +# requests. If this parameter is not found, then this processor will +# attempt to determine the public IP address closest to the client or +# target and use the MaxMind Geo IP library to lookup the geo location. +GeoProximityTargetSorting = false + +# Specify the full path to the IPv4 Geo City database file +# Note: A free version of the database can be downloaded from here: +# http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz +# For a more accurate database, please see the details here: +# http://www.maxmind.com/app/city +GeoProximityIPv4CityDatabaseFile = GeoLiteCity.dat + +# Specify the full path to the IPv6 Geo City database file +# Note: A free version of the database can be downloaded from here: +# http://geolite.maxmind.com/download/geoip/database/GeoLiteCityv6-beta/ +# For a more accurate database, please see the details here: +# http://www.maxmind.com/app/city +# Leave blank to disable V6 lookups. Saves memory (if not required). +#GeoProximityIPv6CityDatabaseFile = GeoLiteCityv6.dat +GeoProximityIPv6CityDatabaseFile = + +# This setting specifies a PCRE compliant regular expression to attempt +# to match against the request URI of inbound requests. Any requests +# matching this expression, will have their targets sorted as described +# above. Leave blank to match all requests. +GeoProximityRequestUriFilter = ^sip:mediaserver.*@mydomain.com$ + +# The distance (in Kilometers) to use for proximity sorting, when the +# Geo Location of a target cannot be determined. +GeoProximityDefaultDistance = 0 + +# If enabled, then targets that are determined to be of equal distance +# from the client, will be placed in a random order. +LoadBalanceEqualDistantTargets = true + + +######################################################## +# Q-Value Target Handler Baboon Settings +######################################################## + +# Enable sequential q-value processing - enables the Baboon +QValue = true + +# Specify forking behavior for q-value targets: FULL_SEQUENTIAL, EQUAL_Q_PARALLEL, +# or FULL_PARALLEL +QValueBehavior = EQUAL_Q_PARALLEL + +# Whether to cancel groups of parallel forks after the period specified by the +# QValueMsBeforeCancel parameter. +QValueCancelBetweenForkGroups = true + +# msec to wait before cancelling parallel fork groups when QValueCancelBetweenForkGroups +# is true +QValueMsBeforeCancel = 30000 + +# Whether to wait for parallel fork groups to terminate before starting new fork-groups. +QValueWaitForTerminateBetweenForkGroups = true + +# msec to wait before starting new groups of parallel forks when +# QValueWaitForTerminateBetweenForkGroups is false +QValueMsBetweenForkGroups = 3000 + + diff --git a/src/libs/resiprocate/repro/repro.cxx b/src/libs/resiprocate/repro/repro.cxx new file mode 100644 index 00000000..c7ba0c8d --- /dev/null +++ b/src/libs/resiprocate/repro/repro.cxx @@ -0,0 +1,202 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include <signal.h> +#include "repro/ReproRunner.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" + +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO + +using namespace repro; +using namespace resip; +using namespace std; + +static bool finished = false; + +static void +signalHandler(int signo) +{ + std::cerr << "Shutting down" << endl; + finished = true; +} + +/* + Extending Repro by adding custom processors to the chain is as easy as overriding one of the + ReproRunner class virtual methods: + virtual void addProcessor(repro::ProcessorChain& chain, std::auto_ptr<repro::Processor> processor); + virtual void makeRequestProcessorChain(repro::ProcessorChain& chain); + virtual void makeResponseProcessorChain(repro::ProcessorChain& chain); + virtual void makeTargetProcessorChain(repro::ProcessorChain& chain); + + Override the makeXXXProcessorChain methods to add processors to the beginning or end of any chain, + or override the addProcessor method, and you can examine the name of the processor being + added and add your own process either before or after the correct processor. + + WARNING: Be careful when checking for names of optional processors. Depending on + the configuration some processors may not be enabled. + + Create an instance of your overridden ReproRunner class and call run to start everything + up. + + Example: + + class MyCustomProcessor : public Processor + { + public: + MyCustomProcessor(ProxyConfig& config) : Processor("MyCustomProcessor") {} + virtual ~MyCustomProcessor() {} + + virtual processor_action_t process(RequestContext &context) + { + DebugLog(<< "Monkey handling request: " << *this << "; reqcontext = " << context); + + ...Do something interesting here.... + + return Processor::Continue; + } + } + }; + + class MyReproRunner : public ReproRunner + { + public: + MyReproRunner() {} + virtual ~MyReproRunner() {} + + protected: + virtual void addProcessor(repro::ProcessorChain& chain, std::auto_ptr<repro::Processor> processor) + { + if(processor->getName() == "LocationServer") + { + // Add MyCustomProcessor before LocationServer + addProcessor(chain, std::auto_ptr<Processor>(new MyCustomProcessor(*mProxyConfig))); + } + ReproRunner::addProcessor(chain, processor); // call base class implementation + } + }; + + There is also generic storage available for custom Processor at three different + scope levels via a KeyValueStore: + -Global Proxy Scope - Proxy::getKeyValueStore + -Request Scope - RequestContext::getKeyValueStore + -Target Scope - Target::getKeyValueStore + Before this storage can be used you must statically allocate a storage key. + See mFromTrustedNodeKey use in the IsTrustedNode class for an example. + +*/ + +int +main(int argc, char** argv) +{ + // Install signal handlers +#ifndef _WIN32 + if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR) + { + cerr << "Couldn't install signal handler for SIGPIPE" << endl; + exit(-1); + } +#endif + + if ( signal( SIGINT, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGINT" << endl; + exit( -1 ); + } + + if ( signal( SIGTERM, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGTERM" << endl; + exit( -1 ); + } + + // Initialize network + initNetwork(); + +#if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK) + { FindMemoryLeaks fml; +#endif + + ReproRunner repro; + if(!repro.run(argc, argv)) + { + cerr << "Failed to start repro, exiting..." << endl; + exit(-1); + } + + // Main program thread, just waits here for a signal to shutdown + while (!finished) + { +#ifdef WIN32 + Sleep(1000); +#else + usleep(100000); +#endif + } + + repro.shutdown(); + +#if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK) + } +#endif + return 0; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ +/* + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/repro/repro.spec b/src/libs/resiprocate/repro/repro.spec new file mode 100644 index 00000000..8e4b7de1 --- /dev/null +++ b/src/libs/resiprocate/repro/repro.spec @@ -0,0 +1,73 @@ +Name: repro +Version: @VERSION@ +Release: %{buildno} + +Summary: Repro SIP Proxy +License: Vovida Software License http://opensource.org/licenses/vovidapl.php +Group: Productivity/Telephony/SIP/Servers +Vendor: SIPfoundry +Packager: SIPfoundry <repro-devel@list.sipfoundry.org> +Url: http://www.sipfoundry.org/repro + +Source: %name-%version.tar.gz + +BuildRequires: openssl-devel >= 0.9.7 +BuildRequires: db4-devel +BuildRequires: boost-devel + +Requires: openssl >= 0.9.7 +Requires: chkconfig + +Prefix: %_prefix +BuildRoot: %{_tmppath}/%name-%version-root + +%description +The repro SIP server provides SIP proxy, registrar, redirect and identity +services. It can be used as the central rendezvous service for peer-to-peer +voice, IM, and presence services, as the core of large scale internet +telephony services, and as a tool to enforce policy at the boundary between +networks or domains. + +%prep +%setup -q + +%build +./configure -y --prefix=/usr +make repro + +%install +# makeinstall RPM macro doesn't leverage DESTDIR but instead overrides +# libdir, bindir, etc just for make install. This not copesetic w/how +# our makefiles are built, they'd rather preserve libdir, and use +# DESTDIR when copying/moving/creating files. The approach we're taking +# is quite standard, so it's surprising RPM's makeinstall macro is +# the way it is. +rm -rf $RPM_BUILD_ROOT +make DESTDIR=$RPM_BUILD_ROOT install-repro +make -C repro DESTDIR=$RPM_BUILD_ROOT install-rh-config + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(644,root,root,755) +%attr(750,root,@REPROUSER@) %{_sbindir}/repro +%attr(750,root,@REPROUSER@) %{_sysconfdir}/init.d/repro +%{_mandir}/man8/repro.8.gz + +# The configuration directory needs to be writeable because +# the configuration web interface modifies them. +%config(noreplace) %attr(644,root,root) %{_sysconfdir}/repro.conf + +# the directory where repro is executed and stores its configuration files +%dir %attr(750,@REPROUSER@,@REPROUSER@) @REPRO_CWD@ +# the directory where repro puts its pid file +%dir %attr(770,root,@REPROUSER@) @REPRO_RUNDIR@ + +%pre +id --user @REPROUSER@ > /dev/null 2>&1 || /usr/sbin/useradd -M -c "repro sip proxy daemon" -r @REPROUSER@ + +%post +# Arrange for sipX to be started every time the system starts up. +# It starts in runlevels 3 and 5. +chkconfig --add repro diff --git a/src/libs/resiprocate/repro/repro_10_0.vcxproj b/src/libs/resiprocate/repro/repro_10_0.vcxproj new file mode 100644 index 00000000..651f19d5 --- /dev/null +++ b/src/libs/resiprocate/repro/repro_10_0.vcxproj @@ -0,0 +1,576 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|Win32"> + <Configuration>SSL-Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|x64"> + <Configuration>SSL-Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|Win32"> + <Configuration>SSL-Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|x64"> + <Configuration>SSL-Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>repro</ProjectName> + <ProjectGuid>{9D8D2649-213F-49D3-A8B0-C1849C611654}</ProjectGuid> + <RootNamespace>repro</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Debug\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Release\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">true</LinkIncremental> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">false</LinkIncremental> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">false</LinkIncremental> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <PreBuildEvent> + <Command>echo Generating reproInfo.hxx + +@echo off &amp; setlocal enableextensions enabledelayedexpansion +echo #define REPRO_BUILD_HOST "%COMPUTERNAME%" &gt; reproInfo.hxx + +:: Get VERSION in a variable +set lineNro_= +for /f "tokens=* delims=" %%r in ('type VERSION') do ( +set /a lineNro_+=1 +echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd) +call %temp%\tmp$$$.cmd +del %temp%\tmp$$$.cmd + +echo #define REPRO_RELEASE_VERSION "%line1_%" &gt;&gt; reproInfo.hxx + +endlocal +</Command> + </PreBuildEvent> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/db/build_windows;$(ProjectDir)../contrib/pcre;$(ProjectDir)../contrib/MySQLConnectorC/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;USE_IPV6;USE_MYSQL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)repro.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + <AdditionalDependencies>Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;"$(ProjectDir)..\contrib\MySQLConnectorC\lib\debug\libmysql.lib";%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <PreBuildEvent> + <Command>echo Generating reproInfo.hxx + +@echo off &amp; setlocal enableextensions enabledelayedexpansion +echo #define REPRO_BUILD_HOST "%COMPUTERNAME%" &gt; reproInfo.hxx + +:: Get VERSION in a variable +set lineNro_= +for /f "tokens=* delims=" %%r in ('type VERSION') do ( +set /a lineNro_+=1 +echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd) +call %temp%\tmp$$$.cmd +del %temp%\tmp$$$.cmd + +echo #define REPRO_RELEASE_VERSION "%line1_%" &gt;&gt; reproInfo.hxx + +endlocal +</Command> + </PreBuildEvent> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../contrib/pcre;$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/db/build_windows;$(ProjectDir)../contrib/pcre;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>$(TargetDir)reprolib.lib;Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)repro.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <PreBuildEvent> + <Command>echo Generating reproInfo.hxx + +@echo off &amp; setlocal enableextensions enabledelayedexpansion +echo #define REPRO_BUILD_HOST "%COMPUTERNAME%" &gt; reproInfo.hxx + +:: Get VERSION in a variable +set lineNro_= +for /f "tokens=* delims=" %%r in ('type VERSION') do ( +set /a lineNro_+=1 +echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd) +call %temp%\tmp$$$.cmd +del %temp%\tmp$$$.cmd + +echo #define REPRO_RELEASE_VERSION "%line1_%" &gt;&gt; reproInfo.hxx + +endlocal +</Command> + </PreBuildEvent> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/db/build_windows;$(ProjectDir)../contrib/MySQLConnectorC/include;$(ProjectDir)../contrib/pcre;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;USE_IPV6;USE_MYSQL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;"$(ProjectDir)..\contrib\MySQLConnectorC\lib\opt\libmysql.lib";%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <PreBuildEvent> + <Command>echo Generating reproInfo.hxx + +@echo off &amp; setlocal enableextensions enabledelayedexpansion +echo #define REPRO_BUILD_HOST "%COMPUTERNAME%" &gt; reproInfo.hxx + +:: Get VERSION in a variable +set lineNro_= +for /f "tokens=* delims=" %%r in ('type VERSION') do ( +set /a lineNro_+=1 +echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd) +call %temp%\tmp$$$.cmd +del %temp%\tmp$$$.cmd + +echo #define REPRO_RELEASE_VERSION "%line1_%" &gt;&gt; reproInfo.hxx + +endlocal +</Command> + </PreBuildEvent> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)../contrib/pcre;$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/db/build_windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>$(TargetDir)reprolib.lib;Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <PreBuildEvent> + <Command>echo Generating reproInfo.hxx + +@echo off &amp; setlocal enableextensions enabledelayedexpansion +echo #define REPRO_BUILD_HOST "%COMPUTERNAME%" &gt; reproInfo.hxx + +:: Get VERSION in a variable +set lineNro_= +for /f "tokens=* delims=" %%r in ('type VERSION') do ( +set /a lineNro_+=1 +echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd) +call %temp%\tmp$$$.cmd +del %temp%\tmp$$$.cmd + +echo #define REPRO_RELEASE_VERSION "%line1_%" &gt;&gt; reproInfo.hxx + +endlocal +</Command> + </PreBuildEvent> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/db/build_windows;$(ProjectDir)../contrib/pcre;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;$(ProjectDir)../contrib/MySQLConnectorC/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;USE_SSL;USE_IPV6;USE_MYSQL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;Dnsapi.lib;Iphlpapi.lib;winmm.lib;crypt32.lib;$(ProjectDir)..\contrib\openssl\lib\vc\static\libeay32MDd.lib;$(ProjectDir)..\contrib\openssl\lib\vc\static\ssleay32MDd.lib;$(ProjectDir)..\contrib\MySQLConnectorC\lib\debug\libmysql.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)repro.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'"> + <PreBuildEvent> + <Command>echo Generating reproInfo.hxx + +@echo off &amp; setlocal enableextensions enabledelayedexpansion +echo #define REPRO_BUILD_HOST "%COMPUTERNAME%" &gt; reproInfo.hxx + +:: Get VERSION in a variable +set lineNro_= +for /f "tokens=* delims=" %%r in ('type VERSION') do ( +set /a lineNro_+=1 +echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd) +call %temp%\tmp$$$.cmd +del %temp%\tmp$$$.cmd + +echo #define REPRO_RELEASE_VERSION "%line1_%" &gt;&gt; reproInfo.hxx + +endlocal +</Command> + </PreBuildEvent> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../contrib/pcre;$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/db/build_windows;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;USE_SSL;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>$(TargetDir)reprolib.lib;Ws2_32.lib;Dnsapi.lib;Iphlpapi.lib;winmm.lib;crypt32.lib;$(ProjectDir)..\contrib\opensslx64\lib\vc\static\libeay32MDd.lib;$(ProjectDir)..\contrib\opensslx64\lib\vc\static\ssleay32MDd.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)repro.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <PreBuildEvent> + <Command>echo Generating reproInfo.hxx + +@echo off &amp; setlocal enableextensions enabledelayedexpansion +echo #define REPRO_BUILD_HOST "%COMPUTERNAME%" &gt; reproInfo.hxx + +:: Get VERSION in a variable +set lineNro_= +for /f "tokens=* delims=" %%r in ('type VERSION') do ( +set /a lineNro_+=1 +echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd) +call %temp%\tmp$$$.cmd +del %temp%\tmp$$$.cmd + +echo #define REPRO_RELEASE_VERSION "%line1_%" &gt;&gt; reproInfo.hxx + +endlocal +</Command> + </PreBuildEvent> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/db/build_windows;$(ProjectDir)../contrib/pcre;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;$(ProjectDir)../contrib/MySQLConnectorC/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;USE_SSL;USE_IPV6;USE_MYSQL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;Dnsapi.lib;Iphlpapi.lib;winmm.lib;crypt32.lib;$(ProjectDir)..\contrib\openssl\lib\vc\static\libeay32MD.lib;$(ProjectDir)..\contrib\openssl\lib\vc\static\ssleay32MD.lib;$(ProjectDir)..\contrib\MySQLConnectorC\lib\opt\libmysql.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'"> + <PreBuildEvent> + <Command>echo Generating reproInfo.hxx + +@echo off &amp; setlocal enableextensions enabledelayedexpansion +echo #define REPRO_BUILD_HOST "%COMPUTERNAME%" &gt; reproInfo.hxx + +:: Get VERSION in a variable +set lineNro_= +for /f "tokens=* delims=" %%r in ('type VERSION') do ( +set /a lineNro_+=1 +echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd) +call %temp%\tmp$$$.cmd +del %temp%\tmp$$$.cmd + +echo #define REPRO_RELEASE_VERSION "%line1_%" &gt;&gt; reproInfo.hxx + +endlocal +</Command> + </PreBuildEvent> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)../contrib/pcre;$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/db/build_windows;$(ProjectDir)../contrib/pcre;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;USE_SSL;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>$(TargetDir)reprolib.lib;Ws2_32.lib;Dnsapi.lib;Iphlpapi.lib;winmm.lib;crypt32.lib;$(ProjectDir)..\contrib\opensslx64\lib\vc\static\libeay32MD.lib;$(ProjectDir)..\contrib\opensslx64\lib\vc\static\ssleay32MD.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="BerkeleyDb.cxx" /> + <ClCompile Include="HttpBase.cxx" /> + <ClCompile Include="HttpConnection.cxx" /> + <ClCompile Include="MySqlDb.cxx" /> + <ClCompile Include="repro.cxx" /> + <ClCompile Include="ReproRunner.cxx" /> + <ClCompile Include="ReproVersion.cxx" /> + <ClCompile Include="WebAdmin.cxx" /> + <ClCompile Include="WebAdminThread.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="BerkeleyDb.hxx" /> + <ClInclude Include="HttpBase.hxx" /> + <ClInclude Include="HttpConnection.hxx" /> + <ClInclude Include="MySqlDb.hxx" /> + <ClInclude Include="ReproRunner.hxx" /> + <ClInclude Include="ReproVersion.hxx" /> + <ClInclude Include="WebAdmin.hxx" /> + <ClInclude Include="WebAdminThread.hxx" /> + </ItemGroup> + <ItemGroup> + <None Include="repro.config" /> + <None Include="webadmin\pageOutlinePost.ixx" /> + <None Include="webadmin\pageOutlinePre.ixx" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\contrib\db\build_windows\db_static_10_0.vcxproj"> + <Project>{9e5a7645-1502-4467-91f8-bcf2eb06ef72}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\contrib\GeoIP\GeoIP_10_0.vcxproj"> + <Project>{6527d843-ee53-4f1e-b0a9-12abba8e75cc}</Project> + <Private>true</Private> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies> + <LinkLibraryDependencies>true</LinkLibraryDependencies> + <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs> + </ProjectReference> + <ProjectReference Include="..\contrib\pcre\pcre_10_0.vcxproj"> + <Project>{b933f895-8efb-4fdd-a46d-09b8c00d1d26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\contrib\popt\popt_10_0.vcxproj"> + <Project>{b204bd08-3991-731b-60a3-a5bd16f2b208}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\resip\dum\dum_10_0.vcxproj"> + <Project>{31b0654f-e08e-405f-909f-80f86cb14b9d}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\resip\stack\resiprocate_10_0.vcxproj"> + <Project>{2a8be839-6466-4001-b224-8f1c3168d04a}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\rutil\rutil_10_0.vcxproj"> + <Project>{3d0e5ceb-93dc-4fdb-918b-d08fa369e106}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="reprolib_10_0.vcxproj"> + <Project>{31b0654f-e08e-405f-909f-80f86cb14b9e}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/repro/repro_10_0.vcxproj.filters b/src/libs/resiprocate/repro/repro_10_0.vcxproj.filters new file mode 100644 index 00000000..294c8ed4 --- /dev/null +++ b/src/libs/resiprocate/repro/repro_10_0.vcxproj.filters @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="BerkeleyDb.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HttpBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HttpConnection.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="repro.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ReproRunner.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ReproVersion.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="WebAdmin.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="WebAdminThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MySqlDb.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="BerkeleyDb.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HttpBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HttpConnection.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ReproRunner.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ReproVersion.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="WebAdmin.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="WebAdminThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MySqlDb.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="webadmin\pageOutlinePost.ixx" /> + <None Include="webadmin\pageOutlinePre.ixx" /> + <None Include="repro.config" /> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/repro/repro_7_1.vcproj b/src/libs/resiprocate/repro/repro_7_1.vcproj new file mode 100644 index 00000000..1d8b60e7 --- /dev/null +++ b/src/libs/resiprocate/repro/repro_7_1.vcproj @@ -0,0 +1,352 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="repro" + ProjectGUID="{9D8D2649-213F-49D3-A8B0-C1849C611654}" + RootNamespace="repro" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/db/build_win32&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_IPV6" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Iphlpapi.lib Dnsapi.lib winmm.lib" + OutputFile="$(OutDir)/repro.exe" + LinkIncremental="2" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/repro.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool" + CommandLine="echo Generating reproInfo.hxx + +@echo off &amp; setlocal enableextensions enabledelayedexpansion +echo #define REPRO_BUILD_HOST &quot;%COMPUTERNAME%&quot; &gt; reproInfo.hxx + +:: Get VERSION in a variable +set lineNro_= +for /f &quot;tokens=* delims=&quot; %%r in (&apos;type VERSION&apos;) do ( +set /a lineNro_+=1 +echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd) +call %temp%\tmp$$$.cmd +del %temp%\tmp$$$.cmd + +echo #define REPRO_RELEASE_VERSION &quot;%line1_%&quot; &gt;&gt; reproInfo.hxx + +endlocal +"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/db/build_win32&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_IPV6" + RuntimeLibrary="2" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Iphlpapi.lib Dnsapi.lib winmm.lib" + OutputFile="$(OutDir)/repro.exe" + LinkIncremental="1" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool" + CommandLine="echo Generating reproInfo.hxx + +@echo off &amp; setlocal enableextensions enabledelayedexpansion +echo #define REPRO_BUILD_HOST &quot;%COMPUTERNAME%&quot; &gt; reproInfo.hxx + +:: Get VERSION in a variable +set lineNro_= +for /f &quot;tokens=* delims=&quot; %%r in (&apos;type VERSION&apos;) do ( +set /a lineNro_+=1 +echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd) +call %temp%\tmp$$$.cmd +del %temp%\tmp$$$.cmd + +echo #define REPRO_RELEASE_VERSION &quot;%line1_%&quot; &gt;&gt; reproInfo.hxx + +endlocal +"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/db/build_win32&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_SSL;USE_IPV6" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib Iphlpapi.lib winmm.lib crypt32.lib &quot;$(ProjectDir)..\contrib\openssl\lib\vc\libeay32MDd.lib&quot; &quot;$(ProjectDir)..\contrib\openssl\lib\vc\ssleay32MDd.lib&quot;" + OutputFile="$(OutDir)/repro.exe" + LinkIncremental="2" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/repro.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool" + CommandLine="echo Generating reproInfo.hxx + +@echo off &amp; setlocal enableextensions enabledelayedexpansion +echo #define REPRO_BUILD_HOST &quot;%COMPUTERNAME%&quot; &gt; reproInfo.hxx + +:: Get VERSION in a variable +set lineNro_= +for /f &quot;tokens=* delims=&quot; %%r in (&apos;type VERSION&apos;) do ( +set /a lineNro_+=1 +echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd) +call %temp%\tmp$$$.cmd +del %temp%\tmp$$$.cmd + +echo #define REPRO_RELEASE_VERSION &quot;%line1_%&quot; &gt;&gt; reproInfo.hxx + +endlocal +"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/db/build_win32&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_SSL;USE_IPV6" + RuntimeLibrary="2" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib Iphlpapi.lib crypt32.lib &quot;$(ProjectDir)..\contrib\openssl\lib\vc\libeay32MD.lib&quot; &quot;$(ProjectDir)..\contrib\openssl\lib\vc\ssleay32MD.lib&quot;" + OutputFile="$(OutDir)/repro.exe" + LinkIncremental="1" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool" + CommandLine="echo Generating reproInfo.hxx + +@echo off &amp; setlocal enableextensions enabledelayedexpansion +echo #define REPRO_BUILD_HOST &quot;%COMPUTERNAME%&quot; &gt; reproInfo.hxx + +:: Get VERSION in a variable +set lineNro_= +for /f &quot;tokens=* delims=&quot; %%r in (&apos;type VERSION&apos;) do ( +set /a lineNro_+=1 +echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd) +call %temp%\tmp$$$.cmd +del %temp%\tmp$$$.cmd + +echo #define REPRO_RELEASE_VERSION &quot;%line1_%&quot; &gt;&gt; reproInfo.hxx + +endlocal +"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath=".\BerkeleyDb.cxx"> + </File> + <File + RelativePath=".\HttpBase.cxx"> + </File> + <File + RelativePath=".\HttpConnection.cxx"> + </File> + <File + RelativePath=".\repro.cxx"> + </File> + <File + RelativePath=".\ReproVersion.cxx"> + </File> + <File + RelativePath=".\WebAdmin.cxx"> + </File> + <File + RelativePath=".\WebAdminThread.cxx"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath=".\BerkeleyDb.hxx"> + </File> + <File + RelativePath=".\HttpBase.hxx"> + </File> + <File + RelativePath=".\HttpConnection.hxx"> + </File> + <File + RelativePath=".\ReproVersion.hxx"> + </File> + <File + RelativePath=".\WebAdmin.hxx"> + </File> + <File + RelativePath=".\WebAdminThread.hxx"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + <File + RelativePath=".\webadmin\pageOutlinePost.ixx"> + </File> + <File + RelativePath=".\webadmin\pageOutlinePre.ixx"> + </File> + <File + RelativePath=".\repro.config"> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/repro/repro_8_0.vcproj b/src/libs/resiprocate/repro/repro_8_0.vcproj new file mode 100644 index 00000000..6b83ee44 --- /dev/null +++ b/src/libs/resiprocate/repro/repro_8_0.vcproj @@ -0,0 +1,439 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="repro" + ProjectGUID="{9D8D2649-213F-49D3-A8B0-C1849C611654}" + RootNamespace="repro" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + CommandLine="echo Generating reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;@echo off &amp; setlocal enableextensions enabledelayedexpansion&#x0D;&#x0A;echo #define REPRO_BUILD_HOST &quot;%COMPUTERNAME%&quot; &gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;:: Get VERSION in a variable&#x0D;&#x0A;set lineNro_=&#x0D;&#x0A;for /f &quot;tokens=* delims=&quot; %%r in (&apos;type VERSION&apos;) do (&#x0D;&#x0A;set /a lineNro_+=1&#x0D;&#x0A;echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd)&#x0D;&#x0A;call %temp%\tmp$$$.cmd&#x0D;&#x0A;del %temp%\tmp$$$.cmd&#x0D;&#x0A;&#x0D;&#x0A;echo #define REPRO_RELEASE_VERSION &quot;%line1_%&quot; &gt;&gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;endlocal&#x0D;&#x0A;" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_IPV6;LEAK_CHECK" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Iphlpapi.lib Dnsapi.lib winmm.lib" + OutputFile="$(OutDir)/repro.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/repro.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + CommandLine="echo Generating reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;@echo off &amp; setlocal enableextensions enabledelayedexpansion&#x0D;&#x0A;echo #define REPRO_BUILD_HOST &quot;%COMPUTERNAME%&quot; &gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;:: Get VERSION in a variable&#x0D;&#x0A;set lineNro_=&#x0D;&#x0A;for /f &quot;tokens=* delims=&quot; %%r in (&apos;type VERSION&apos;) do (&#x0D;&#x0A;set /a lineNro_+=1&#x0D;&#x0A;echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd)&#x0D;&#x0A;call %temp%\tmp$$$.cmd&#x0D;&#x0A;del %temp%\tmp$$$.cmd&#x0D;&#x0A;&#x0D;&#x0A;echo #define REPRO_RELEASE_VERSION &quot;%line1_%&quot; &gt;&gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;endlocal&#x0D;&#x0A;" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_IPV6" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Iphlpapi.lib Dnsapi.lib winmm.lib" + OutputFile="$(OutDir)/repro.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + CommandLine="echo Generating reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;@echo off &amp; setlocal enableextensions enabledelayedexpansion&#x0D;&#x0A;echo #define REPRO_BUILD_HOST &quot;%COMPUTERNAME%&quot; &gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;:: Get VERSION in a variable&#x0D;&#x0A;set lineNro_=&#x0D;&#x0A;for /f &quot;tokens=* delims=&quot; %%r in (&apos;type VERSION&apos;) do (&#x0D;&#x0A;set /a lineNro_+=1&#x0D;&#x0A;echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd)&#x0D;&#x0A;call %temp%\tmp$$$.cmd&#x0D;&#x0A;del %temp%\tmp$$$.cmd&#x0D;&#x0A;&#x0D;&#x0A;echo #define REPRO_RELEASE_VERSION &quot;%line1_%&quot; &gt;&gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;endlocal&#x0D;&#x0A;" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_SSL;USE_IPV6;LEAK_CHECK" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib Iphlpapi.lib winmm.lib crypt32.lib &quot;$(ProjectDir)..\contrib\openssl\lib\vc\static\libeay32MDd.lib&quot; &quot;$(ProjectDir)..\contrib\openssl\lib\vc\static\ssleay32MDd.lib&quot;" + OutputFile="$(OutDir)/repro.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/repro.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + CommandLine="echo Generating reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;@echo off &amp; setlocal enableextensions enabledelayedexpansion&#x0D;&#x0A;echo #define REPRO_BUILD_HOST &quot;%COMPUTERNAME%&quot; &gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;:: Get VERSION in a variable&#x0D;&#x0A;set lineNro_=&#x0D;&#x0A;for /f &quot;tokens=* delims=&quot; %%r in (&apos;type VERSION&apos;) do (&#x0D;&#x0A;set /a lineNro_+=1&#x0D;&#x0A;echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd)&#x0D;&#x0A;call %temp%\tmp$$$.cmd&#x0D;&#x0A;del %temp%\tmp$$$.cmd&#x0D;&#x0A;&#x0D;&#x0A;echo #define REPRO_RELEASE_VERSION &quot;%line1_%&quot; &gt;&gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;endlocal&#x0D;&#x0A;" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_SSL;USE_IPV6" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib Iphlpapi.lib winmm.lib crypt32.lib &quot;$(ProjectDir)..\contrib\openssl\lib\vc\static\libeay32MD.lib&quot; &quot;$(ProjectDir)..\contrib\openssl\lib\vc\static\ssleay32MD.lib&quot;" + OutputFile="$(OutDir)/repro.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\BerkeleyDb.cxx" + > + </File> + <File + RelativePath=".\HttpBase.cxx" + > + </File> + <File + RelativePath=".\HttpConnection.cxx" + > + </File> + <File + RelativePath=".\repro.cxx" + > + </File> + <File + RelativePath=".\ReproRunner.cxx" + > + </File> + <File + RelativePath=".\ReproVersion.cxx" + > + </File> + <File + RelativePath=".\WebAdmin.cxx" + > + </File> + <File + RelativePath=".\WebAdminThread.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\BerkeleyDb.hxx" + > + </File> + <File + RelativePath=".\HttpBase.hxx" + > + </File> + <File + RelativePath=".\HttpConnection.hxx" + > + </File> + <File + RelativePath=".\ReproRunner.hxx" + > + </File> + <File + RelativePath=".\ReproVersion.hxx" + > + </File> + <File + RelativePath=".\WebAdmin.hxx" + > + </File> + <File + RelativePath=".\WebAdminThread.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <File + RelativePath=".\webadmin\pageOutlinePost.ixx" + > + </File> + <File + RelativePath=".\webadmin\pageOutlinePre.ixx" + > + </File> + <File + RelativePath=".\repro.config" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/repro/repro_9_0.vcproj b/src/libs/resiprocate/repro/repro_9_0.vcproj new file mode 100644 index 00000000..f1d855d0 --- /dev/null +++ b/src/libs/resiprocate/repro/repro_9_0.vcproj @@ -0,0 +1,470 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="repro" + ProjectGUID="{9D8D2649-213F-49D3-A8B0-C1849C611654}" + RootNamespace="repro" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + CommandLine="echo Generating reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;@echo off &amp; setlocal enableextensions enabledelayedexpansion&#x0D;&#x0A;echo #define REPRO_BUILD_HOST &quot;%COMPUTERNAME%&quot; &gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;:: Get VERSION in a variable&#x0D;&#x0A;set lineNro_=&#x0D;&#x0A;for /f &quot;tokens=* delims=&quot; %%r in (&apos;type VERSION&apos;) do (&#x0D;&#x0A;set /a lineNro_+=1&#x0D;&#x0A;echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd)&#x0D;&#x0A;call %temp%\tmp$$$.cmd&#x0D;&#x0A;del %temp%\tmp$$$.cmd&#x0D;&#x0A;&#x0D;&#x0A;echo #define REPRO_RELEASE_VERSION &quot;%line1_%&quot; &gt;&gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;endlocal&#x0D;&#x0A;" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/MySQLConnectorC/include&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_IPV6;USE_MYSQL;LEAK_CHECK" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Iphlpapi.lib winmm.lib Dnsapi.lib &quot;$(ProjectDir)..\contrib\MySQLConnectorC\lib\debug\libmysql.lib&quot;" + OutputFile="$(OutDir)/repro.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/repro.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + CommandLine="echo Generating reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;@echo off &amp; setlocal enableextensions enabledelayedexpansion&#x0D;&#x0A;echo #define REPRO_BUILD_HOST &quot;%COMPUTERNAME%&quot; &gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;:: Get VERSION in a variable&#x0D;&#x0A;set lineNro_=&#x0D;&#x0A;for /f &quot;tokens=* delims=&quot; %%r in (&apos;type VERSION&apos;) do (&#x0D;&#x0A;set /a lineNro_+=1&#x0D;&#x0A;echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd)&#x0D;&#x0A;call %temp%\tmp$$$.cmd&#x0D;&#x0A;del %temp%\tmp$$$.cmd&#x0D;&#x0A;&#x0D;&#x0A;echo #define REPRO_RELEASE_VERSION &quot;%line1_%&quot; &gt;&gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;endlocal&#x0D;&#x0A;" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/MySQLConnectorC/include&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_IPV6;USE_MYSQL" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Iphlpapi.lib winmm.lib Dnsapi.lib &quot;$(ProjectDir)..\contrib\MySQLConnectorC\lib\opt\libmysql.lib&quot;" + OutputFile="$(OutDir)/repro.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + CommandLine="echo Generating reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;@echo off &amp; setlocal enableextensions enabledelayedexpansion&#x0D;&#x0A;echo #define REPRO_BUILD_HOST &quot;%COMPUTERNAME%&quot; &gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;:: Get VERSION in a variable&#x0D;&#x0A;set lineNro_=&#x0D;&#x0A;for /f &quot;tokens=* delims=&quot; %%r in (&apos;type VERSION&apos;) do (&#x0D;&#x0A;set /a lineNro_+=1&#x0D;&#x0A;echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd)&#x0D;&#x0A;call %temp%\tmp$$$.cmd&#x0D;&#x0A;del %temp%\tmp$$$.cmd&#x0D;&#x0A;&#x0D;&#x0A;echo #define REPRO_RELEASE_VERSION &quot;%line1_%&quot; &gt;&gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;endlocal&#x0D;&#x0A;" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)../contrib/MySQLConnectorC/include&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_SSL;USE_IPV6;USE_MYSQL;LEAK_CHECK" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib Iphlpapi.lib winmm.lib crypt32.lib &quot;$(ProjectDir)..\contrib\openssl\lib\vc\static\libeay32MDd.lib&quot; &quot;$(ProjectDir)..\contrib\openssl\lib\vc\static\ssleay32MDd.lib&quot; &quot;$(ProjectDir)..\contrib\MySQLConnectorC\lib\debug\libmysql.lib&quot;" + OutputFile="$(OutDir)/repro.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/repro.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + CommandLine="echo Generating reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;@echo off &amp; setlocal enableextensions enabledelayedexpansion&#x0D;&#x0A;echo #define REPRO_BUILD_HOST &quot;%COMPUTERNAME%&quot; &gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;:: Get VERSION in a variable&#x0D;&#x0A;set lineNro_=&#x0D;&#x0A;for /f &quot;tokens=* delims=&quot; %%r in (&apos;type VERSION&apos;) do (&#x0D;&#x0A;set /a lineNro_+=1&#x0D;&#x0A;echo @set line!lineNro_!_=%%r&gt;&gt;%temp%\tmp$$$.cmd)&#x0D;&#x0A;call %temp%\tmp$$$.cmd&#x0D;&#x0A;del %temp%\tmp$$$.cmd&#x0D;&#x0A;&#x0D;&#x0A;echo #define REPRO_RELEASE_VERSION &quot;%line1_%&quot; &gt;&gt; reproInfo.hxx&#x0D;&#x0A;&#x0D;&#x0A;endlocal&#x0D;&#x0A;" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)../contrib/MySQLConnectorC/include&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_SSL;USE_IPV6;USE_MYSQL" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib Iphlpapi.lib winmm.lib crypt32.lib &quot;$(ProjectDir)..\contrib\openssl\lib\vc\static\libeay32MD.lib&quot; &quot;$(ProjectDir)..\contrib\openssl\lib\vc\static\ssleay32MD.lib&quot; &quot;$(ProjectDir)..\contrib\MySQLConnectorC\lib\opt\libmysql.lib&quot;" + OutputFile="$(OutDir)/repro.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\BerkeleyDb.cxx" + > + </File> + <File + RelativePath=".\CommandServer.cxx" + > + </File> + <File + RelativePath=".\CommandServerThread.cxx" + > + </File> + <File + RelativePath=".\HttpBase.cxx" + > + </File> + <File + RelativePath=".\HttpConnection.cxx" + > + </File> + <File + RelativePath=".\MySqlDb.cxx" + > + </File> + <File + RelativePath=".\repro.cxx" + > + </File> + <File + RelativePath=".\ReproRunner.cxx" + > + </File> + <File + RelativePath=".\ReproVersion.cxx" + > + </File> + <File + RelativePath=".\WebAdmin.cxx" + > + </File> + <File + RelativePath=".\WebAdminThread.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\BerkeleyDb.hxx" + > + </File> + <File + RelativePath=".\CommandServer.hxx" + > + </File> + <File + RelativePath=".\CommandServerThread.hxx" + > + </File> + <File + RelativePath=".\HttpBase.hxx" + > + </File> + <File + RelativePath=".\HttpConnection.hxx" + > + </File> + <File + RelativePath=".\MySqlDb.hxx" + > + </File> + <File + RelativePath=".\ReproRunner.hxx" + > + </File> + <File + RelativePath=".\ReproVersion.hxx" + > + </File> + <File + RelativePath=".\WebAdmin.hxx" + > + </File> + <File + RelativePath=".\WebAdminThread.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <File + RelativePath=".\webadmin\pageOutlinePost.ixx" + > + </File> + <File + RelativePath=".\webadmin\pageOutlinePre.ixx" + > + </File> + <File + RelativePath=".\repro.config" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/repro/reprocmd/Makefile.am b/src/libs/resiprocate/repro/reprocmd/Makefile.am new file mode 100644 index 00000000..30a7fc53 --- /dev/null +++ b/src/libs/resiprocate/repro/reprocmd/Makefile.am @@ -0,0 +1,65 @@ +# $Id$ + +EXTRA_DIST = reprocmd_10_0.vcxproj reprocmd_10_0.vcxproj.filters +EXTRA_DIST += *.vcproj + +#AM_CXXFLAGS = -DUSE_ARES + +sbin_PROGRAMS = reprocmd +reprocmd_SOURCES = reprocmd.cpp +reprocmd_LDADD = ../librepro.la +reprocmd_LDADD += ../../resip/dum/libdum.la +reprocmd_LDADD += ../../resip/stack/libresip.la ../../rutil/librutil.la +#reprocmd_LDADD += ../contrib/ares/libares.a +#reprocmd_LDADD += -L../contrib/ares -lares +reprocmd_LDADD += @LIBSSL_LIBADD@ -lpthread + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# <http://www.vovida.org/>. +# +############################################################################## diff --git a/src/libs/resiprocate/repro/reprocmd/reprocmd.cpp b/src/libs/resiprocate/repro/reprocmd/reprocmd.cpp new file mode 100644 index 00000000..fe430d83 --- /dev/null +++ b/src/libs/resiprocate/repro/reprocmd/reprocmd.cpp @@ -0,0 +1,269 @@ +#include <rutil/DnsUtil.hxx> +#include <rutil/BaseException.hxx> +#include <rutil/XMLCursor.hxx> +#include <rutil/WinLeakCheck.hxx> + +using namespace resip; +using namespace std; + +void sleepSeconds(unsigned int seconds) +{ +#ifdef WIN32 + Sleep(seconds*1000); +#else + sleep(seconds); +#endif +} + +int +main (int argc, char** argv) +{ +#ifdef WIN32 + initNetwork(); +#endif + + int sd, rc; + struct sockaddr_in localAddr, servAddr; + struct hostent *h; + + if(argc != 2 && argc != 4) + { + cerr << "usage: " << argv[0] <<" [<server> <port>] <command> [<parm>=<value>]" << endl; + cerr << " Valid Commands are:" << endl; + cerr << " GetStackInfo - retrieves low level information about the stack state" << endl; + cerr << " GetStackStats - retrieves a dump of the stack statistics" << endl; + cerr << " ResetStackStats - resets all cumulative stack statistics to zero" << endl; + cerr << " LogDnsCache - causes the DNS cache contents to be written to the resip logs" << endl; + cerr << " ClearDnsCache - empties the stacks DNS cache" << endl; + cerr << " GetDnsCache - retrieves the DNS cache contents" << endl; + cerr << " GetCongestionStats - retrieves the stacks congestion manager stats and state" << endl; + cerr << " SetCongestionTolerance metric=<SIZE|WAIT_TIME|TIME_DEPTH> maxTolerance=<value>" << endl; + cerr << " [fifoDescription=<desc>] - sets congestion tolerances" << endl; + cerr << " Shutdown - signal the proxy to shut down." << endl; + cerr << " Restart - signal the proxy to restart - leaving active registrations in place." << endl; + cerr << " GetProxyConfig - retrieves the all of configuration file settings currently" << endl; + cerr << " being used by the proxy" << endl; + exit(1); + } + + char* host = "127.0.0.1"; + short port = 5081; + int cmdIndex=1; + + if(argc == 4) + { + host = argv[1]; + port = (short)atoi(argv[2]); + cmdIndex = 3; + } + + h = gethostbyname(host); + if(h==0) + { + cerr << "unknown host " << host << endl; + exit(1); + } + + servAddr.sin_family = h->h_addrtype; + memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length); + servAddr.sin_port = htons(port); + + // Create TCP Socket + sd = (int)socket(AF_INET, SOCK_STREAM, 0); + if(sd < 0) + { + cerr << "cannot open socket" << endl; + exit(1); + } + + // bind to any local interface/port + localAddr.sin_family = AF_INET; + localAddr.sin_addr.s_addr = htonl(INADDR_ANY); + localAddr.sin_port = 0; + + rc = bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr)); + if(rc < 0) + { + cerr <<"error binding locally" << endl; + exit(1); + } + + // Connect to server + rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr)); + if(rc < 0) + { + cerr << "error connecting" << endl; + exit(1); + } + + Data request(1024, Data::Preallocate); + request += "<"; + request += argv[cmdIndex]; + request += ">\r\n <Request>\r\n"; + for(int i = cmdIndex+1; i < argc; i++) + { + Data parm; + Data value; + Data arg(argv[i]); + ParseBuffer pb(arg); + const char *anchor = pb.position(); + pb.skipToChar('='); + if(!pb.eof()) + { + pb.data(parm, anchor); + pb.skipChar(); + anchor = pb.position(); + pb.skipToEnd(); + pb.data(value, anchor); + } + request += " <"; + request += parm; + request += ">"; + request += value; + request += "</"; + request += parm; + request += ">\r\n"; + } + request += " </Request>\r\n"; + request += "</"; + request += argv[cmdIndex]; + request += ">\r\n"; + + //cout << "Sending:\r\n" << request << endl; + + rc = send(sd, request.c_str(), request.size(), 0); + if(rc < 0) + { + cerr << "error sending request on socket." << endl; + closeSocket(sd); + exit(1); + } + + char readBuffer[8000]; + while(rc > 0) + { + rc = recv(sd, (char*)&readBuffer, sizeof(readBuffer), 0); + if(rc < 0) + { + cerr << "error receiving response from socket." << endl; + closeSocket(sd); + exit(1); + } + + if(rc > 0) + { + Data response(Data::Borrow, (const char*)&readBuffer, rc); + //cout << "Received response: \r\n" << response.xmlCharDataDecode() << endl; + + ParseBuffer pb(response); + XMLCursor xml(pb); + bool responseOK = false; + if(xml.firstChild() && xml.nextSibling() && xml.firstChild()) // Move to Response node + { + while(true) + { + if(isEqualNoCase(xml.getTag(), "Result")) + { + unsigned int code=0; + Data text; + XMLCursor::AttributeMap::const_iterator it = xml.getAttributes().find("Code"); + if(it != xml.getAttributes().end()) + { + code = it->second.convertUnsignedLong(); + } + if(xml.firstChild()) + { + text = xml.getValue(); + xml.parent(); + } + if(code >= 200 && code < 300) + { + // Success + cout << text << endl; + } + else + { + cout << "Error " << code << " processing request: " << text << endl; + } + responseOK = true; + } + else if(isEqualNoCase(xml.getTag(), "Data")) + { + if(xml.firstChild()) + { + cout << xml.getValue().xmlCharDataDecode() << endl; + xml.parent(); + } + } + if(!xml.nextSibling()) + { + // break on no more sibilings + break; + } + } + } + if(!responseOK) + { + cout << "Unable to parse response:" << endl << response << endl; + } + + closeSocket(sd); + break; + } + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2012 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ +/* + * vi: set shiftwidth=3 expandtab: + */ + diff --git a/src/libs/resiprocate/repro/reprocmd/reprocmd_10_0.vcxproj b/src/libs/resiprocate/repro/reprocmd/reprocmd_10_0.vcxproj new file mode 100644 index 00000000..4818b4fb --- /dev/null +++ b/src/libs/resiprocate/repro/reprocmd/reprocmd_10_0.vcxproj @@ -0,0 +1,412 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|Win32"> + <Configuration>SSL-Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|x64"> + <Configuration>SSL-Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|Win32"> + <Configuration>SSL-Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|x64"> + <Configuration>SSL-Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>reprocmd</ProjectName> + <ProjectGuid>{16CD976A-5D3B-4329-88BA-A32560CDFCC8}</ProjectGuid> + <RootNamespace>reprocmd</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Debug\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Release\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">true</LinkIncremental> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">false</LinkIncremental> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">false</LinkIncremental> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../../;$(ProjectDir)../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;USE_ARES;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)reprocmd.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)test.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../../;$(ProjectDir)../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;USE_ARES;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)reprocmd.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)test.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <OmitFramePointers>true</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)../../;$(ProjectDir)../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;USE_ARES;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalOptions>/FIXED:NO %(AdditionalOptions)</AdditionalOptions> + <AdditionalDependencies>Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)reprocmd.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <OmitFramePointers>true</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)../../;$(ProjectDir)../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;USE_ARES;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalOptions>/FIXED:NO %(AdditionalOptions)</AdditionalOptions> + <AdditionalDependencies>Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)reprocmd.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../../;$(ProjectDir)../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;USE_ARES;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;crypt32.lib;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\libeay32MDd.lib;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\ssleay32MDd.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)reprocmd.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)test.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../../;$(ProjectDir)../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;USE_ARES;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;crypt32.lib;$(ProjectDir)..\..\contrib\opensslx64\lib\vc\static\libeay32MDd.lib;$(ProjectDir)..\..\contrib\opensslx64\lib\vc\static\ssleay32MDd.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)reprocmd.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)test.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <OmitFramePointers>true</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)../../;$(ProjectDir)../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;USE_ARES;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalOptions>/FIXED:NO %(AdditionalOptions)</AdditionalOptions> + <AdditionalDependencies>Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;crypt32.lib;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\libeay32MD.lib;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\ssleay32MD.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)reprocmd.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <OmitFramePointers>true</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)../../;$(ProjectDir)../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;USE_ARES;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalOptions>/FIXED:NO %(AdditionalOptions)</AdditionalOptions> + <AdditionalDependencies>Ws2_32.lib;Iphlpapi.lib;winmm.lib;Dnsapi.lib;crypt32.lib;$(ProjectDir)..\..\contrib\opensslx64\lib\vc\static\libeay32MD.lib;$(ProjectDir)..\..\contrib\opensslx64\lib\vc\static\ssleay32MD.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)reprocmd.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectReference Include="..\..\rutil\rutil_10_0.vcxproj"> + <Project>{3d0e5ceb-93dc-4fdb-918b-d08fa369e106}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <ClCompile Include="reprocmd.cpp" /> + </ItemGroup> + <ItemGroup> + <None Include="ReadMe.txt" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/repro/reprocmd/reprocmd_10_0.vcxproj.filters b/src/libs/resiprocate/repro/reprocmd/reprocmd_10_0.vcxproj.filters new file mode 100644 index 00000000..699e1725 --- /dev/null +++ b/src/libs/resiprocate/repro/reprocmd/reprocmd_10_0.vcxproj.filters @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{7a1c8c04-28e6-444a-a566-73886c8c9286}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{847686eb-f7db-475c-aea3-d307d0ee8f2e}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{0c807615-2b0a-47f1-b814-9cb17284f973}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="reprocmd.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="ReadMe.txt" /> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/repro/reprocmd/reprocmd_9_0.vcproj b/src/libs/resiprocate/repro/reprocmd/reprocmd_9_0.vcproj new file mode 100644 index 00000000..6f7d84fd --- /dev/null +++ b/src/libs/resiprocate/repro/reprocmd/reprocmd_9_0.vcproj @@ -0,0 +1,389 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="reprocmd" + ProjectGUID="{16CD976A-5D3B-4329-88BA-A32560CDFCC8}" + RootNamespace="reprocmd" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../../&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_ARES" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Iphlpapi.lib winmm.lib Dnsapi.lib" + OutputFile="$(OutDir)/reprocmd.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/test.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../../&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_ARES" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Iphlpapi.lib winmm.lib Dnsapi.lib" + OutputFile="$(OutDir)/reprocmd.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../../&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_ARES" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib Iphlpapi.lib winmm.lib Dnsapi.lib crypt32.lib &quot;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\libeay32MDd.lib&quot; &quot;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\ssleay32MDd.lib&quot;" + OutputFile="$(OutDir)/reprocmd.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/test.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../../&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_ARES" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Iphlpapi.lib winmm.lib Dnsapi.lib crypt32.lib &quot;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\libeay32MD.lib&quot; &quot;$(ProjectDir)..\..\contrib\openssl\lib\vc\static\ssleay32MD.lib&quot;" + OutputFile="$(OutDir)/reprocmd.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + <ProjectReference + ReferencedProjectIdentifier="{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" + RelativePathToProject=".\rutil\rutil_9_0.vcproj" + /> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath=".\reprocmd.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + > + </Filter> + <File + RelativePath="ReadMe.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/repro/reprolib_10_0.vcxproj b/src/libs/resiprocate/repro/reprolib_10_0.vcxproj new file mode 100644 index 00000000..a3b1dc44 --- /dev/null +++ b/src/libs/resiprocate/repro/reprolib_10_0.vcxproj @@ -0,0 +1,441 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|Win32"> + <Configuration>SSL-Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|x64"> + <Configuration>SSL-Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|Win32"> + <Configuration>SSL-Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|x64"> + <Configuration>SSL-Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>reprolib</ProjectName> + <ProjectGuid>{31B0654F-E08E-405F-909F-80F86CB14B9E}</ProjectGuid> + <RootNamespace>reprolib</RootNamespace> + <Keyword>ManagedCProj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">$(Configuration)\</IntDir> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/pcre;$(ProjectDir)../contrib/GeoIP/libGeoIP;$(ProjectDir)../contrib/MySQLConnectorC/include;$(ProjectDir)../contrib/db/build_windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;USE_ARES;USE_IPV6;USE_MYSQL;USE_MAXMIND_GEOIP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks> + </BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/pcre;$(ProjectDir)../contrib/GeoIP/libGeoIP;$(ProjectDir)../contrib/db/build_windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;USE_ARES;USE_IPV6;USE_MAXMIND_GEOIP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks> + </BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/pcre;$(ProjectDir)../contrib/GeoIP/libGeoIP;$(ProjectDir)../contrib/MySQLConnectorC/include;$(ProjectDir)../contrib/db/build_windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_MYSQL;USE_MAXMIND_GEOIP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/pcre;$(ProjectDir)../contrib/GeoIP/libGeoIP;$(ProjectDir)../contrib/db/build_windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_MAXMIND_GEOIP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/pcre;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;$(ProjectDir)../contrib/GeoIP/libGeoIP;$(ProjectDir)../contrib/MySQLConnectorC/include;$(ProjectDir)../contrib/db/build_windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_MYSQL;USE_SSL;USE_MAXMIND_GEOIP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks> + </BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/pcre;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;$(ProjectDir)../contrib/GeoIP/libGeoIP;$(ProjectDir)../contrib/db/build_windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;USE_MAXMIND_GEOIP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks> + </BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/pcre;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;$(ProjectDir)../contrib/GeoIP/libGeoIP;$(ProjectDir)../contrib/MySQLConnectorC/include;$(ProjectDir)../contrib/db/build_windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;USE_MYSQL;USE_MAXMIND_GEOIP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../resip/stack;$(ProjectDir)../contrib/pcre;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;$(ProjectDir)../contrib/GeoIP/libGeoIP;$(ProjectDir)../contrib/db/build_windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;USE_MAXMIND_GEOIP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <Reference Include="mscorlib"> + <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + </Reference> + <Reference Include="System"> + <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + </Reference> + <Reference Include="System.Data"> + <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + </Reference> + </ItemGroup> + <ItemGroup> + <ClCompile Include="AbstractDb.cxx" /> + <ClCompile Include="AccountingCollector.cxx" /> + <ClCompile Include="AclStore.cxx" /> + <ClCompile Include="FilterStore.cxx" /> + <ClCompile Include="monkeys\AmIResponsible.cxx" /> + <ClCompile Include="monkeys\CertificateAuthenticator.cxx" /> + <ClCompile Include="monkeys\GeoProximityTargetSorter.cxx" /> + <ClCompile Include="monkeys\MessageSilo.cxx" /> + <ClCompile Include="monkeys\RequestFilter.cxx" /> + <ClCompile Include="PersistentMessageQueue.cxx" /> + <ClCompile Include="ProxyConfig.cxx" /> + <ClCompile Include="SiloStore.cxx" /> + <ClCompile Include="stateAgents\CertPublicationHandler.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="stateAgents\CertServer.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="stateAgents\CertSubscriptionHandler.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="CommandServer.cxx" /> + <ClCompile Include="CommandServerThread.cxx" /> + <ClCompile Include="ConfigStore.cxx" /> + <ClCompile Include="monkeys\ConstantLocationMonkey.cxx" /> + <ClCompile Include="monkeys\DigestAuthenticator.cxx" /> + <ClCompile Include="Dispatcher.cxx" /> + <ClCompile Include="monkeys\IsTrustedNode.cxx" /> + <ClCompile Include="monkeys\LocationServer.cxx" /> + <ClCompile Include="OutboundTarget.cxx" /> + <ClCompile Include="monkeys\OutboundTargetHandler.cxx" /> + <ClCompile Include="stateAgents\PrivateKeyPublicationHandler.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="stateAgents\PrivateKeySubscriptionHandler.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="Processor.cxx" /> + <ClCompile Include="ProcessorChain.cxx" /> + <ClCompile Include="Proxy.cxx" /> + <ClCompile Include="QValueTarget.cxx" /> + <ClCompile Include="monkeys\QValueTargetHandler.cxx" /> + <ClCompile Include="monkeys\RecursiveRedirect.cxx" /> + <ClCompile Include="Registrar.cxx" /> + <ClCompile Include="RegSyncClient.cxx" /> + <ClCompile Include="RegSyncServer.cxx" /> + <ClCompile Include="RegSyncServerThread.cxx" /> + <ClCompile Include="ReproServerAuthManager.cxx" /> + <ClCompile Include="RequestContext.cxx" /> + <ClCompile Include="ResponseContext.cxx" /> + <ClCompile Include="RouteStore.cxx" /> + <ClCompile Include="RRDecorator.cxx" /> + <ClCompile Include="monkeys\SimpleStaticRoute.cxx" /> + <ClCompile Include="monkeys\SimpleTargetHandler.cxx" /> + <ClCompile Include="StaticRegStore.cxx" /> + <ClCompile Include="monkeys\StaticRoute.cxx" /> + <ClCompile Include="Store.cxx" /> + <ClCompile Include="monkeys\StrictRouteFixup.cxx" /> + <ClCompile Include="Target.cxx" /> + <ClCompile Include="UserStore.cxx" /> + <ClCompile Include="WorkerThread.cxx" /> + <ClCompile Include="XmlRpcConnection.cxx" /> + <ClCompile Include="XmlRpcServerBase.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="AbstractDb.hxx" /> + <ClInclude Include="AccountingCollector.hxx" /> + <ClInclude Include="Ack200DoneMessage.hxx" /> + <ClInclude Include="AclStore.hxx" /> + <ClInclude Include="AsyncProcessor.hxx" /> + <ClInclude Include="AsyncProcessorMessage.hxx" /> + <ClInclude Include="AsyncProcessorWorker.hxx" /> + <ClInclude Include="FilterStore.hxx" /> + <ClInclude Include="ForkControlMessage.hxx" /> + <ClInclude Include="monkeys\AmIResponsible.hxx" /> + <ClInclude Include="monkeys\CertificateAuthenticator.hxx" /> + <ClInclude Include="monkeys\GeoProximityTargetSorter.hxx" /> + <ClInclude Include="monkeys\MessageSilo.hxx" /> + <ClInclude Include="monkeys\RequestFilter.hxx" /> + <ClInclude Include="PersistentMessageQueue.hxx" /> + <ClInclude Include="ProxyConfig.hxx" /> + <ClInclude Include="SiloStore.hxx" /> + <ClInclude Include="stateAgents\CertPublicationHandler.hxx" /> + <ClInclude Include="stateAgents\CertServer.hxx" /> + <ClInclude Include="stateAgents\CertSubscriptionHandler.hxx" /> + <ClInclude Include="ChainTraverser.hxx" /> + <ClInclude Include="CommandServer.hxx" /> + <ClInclude Include="CommandServerThread.hxx" /> + <ClInclude Include="ConfigStore.hxx" /> + <ClInclude Include="monkeys\ConstantLocationMonkey.hxx" /> + <ClInclude Include="monkeys\DigestAuthenticator.hxx" /> + <ClInclude Include="Dispatcher.hxx" /> + <ClInclude Include="monkeys\IsTrustedNode.hxx" /> + <ClInclude Include="monkeys\LocationServer.hxx" /> + <ClInclude Include="OutboundTarget.hxx" /> + <ClInclude Include="monkeys\OutboundTargetHandler.hxx" /> + <ClInclude Include="stateAgents\PrivateKeyPublicationHandler.hxx" /> + <ClInclude Include="stateAgents\PrivateKeySubscriptionHandler.hxx" /> + <ClInclude Include="Processor.hxx" /> + <ClInclude Include="ProcessorChain.hxx" /> + <ClInclude Include="Proxy.hxx" /> + <ClInclude Include="QValueTarget.hxx" /> + <ClInclude Include="monkeys\QValueTargetHandler.hxx" /> + <ClInclude Include="monkeys\RecursiveRedirect.hxx" /> + <ClInclude Include="Registrar.hxx" /> + <ClInclude Include="RegSyncClient.hxx" /> + <ClInclude Include="RegSyncServer.hxx" /> + <ClInclude Include="RegSyncServerThread.hxx" /> + <ClInclude Include="ReproServerAuthManager.hxx" /> + <ClInclude Include="RequestContext.hxx" /> + <ClInclude Include="ResponseContext.hxx" /> + <ClInclude Include="RouteStore.hxx" /> + <ClInclude Include="RRDecorator.hxx" /> + <ClInclude Include="monkeys\SimpleStaticRoute.hxx" /> + <ClInclude Include="monkeys\SimpleTargetHandler.hxx" /> + <ClInclude Include="StaticRegStore.hxx" /> + <ClInclude Include="monkeys\StaticRoute.hxx" /> + <ClInclude Include="Store.hxx" /> + <ClInclude Include="monkeys\StrictRouteFixup.hxx" /> + <ClInclude Include="Target.hxx" /> + <ClInclude Include="TimerCMessage.hxx" /> + <ClInclude Include="UserAuthGrabber.hxx" /> + <ClInclude Include="UserInfoMessage.hxx" /> + <ClInclude Include="UserStore.hxx" /> + <ClInclude Include="Worker.hxx" /> + <ClInclude Include="WorkerThread.hxx" /> + <ClInclude Include="XmlRpcConnection.hxx" /> + <ClInclude Include="XmlRpcServerBase.hxx" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/repro/reprolib_10_0.vcxproj.filters b/src/libs/resiprocate/repro/reprolib_10_0.vcxproj.filters new file mode 100644 index 00000000..dce87d31 --- /dev/null +++ b/src/libs/resiprocate/repro/reprolib_10_0.vcxproj.filters @@ -0,0 +1,369 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="AbstractDb.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="AclStore.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="CommandServer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="CommandServerThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ConfigStore.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Dispatcher.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\AmIResponsible.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\ConstantLocationMonkey.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\DigestAuthenticator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\IsTrustedNode.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\LocationServer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\OutboundTargetHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\QValueTargetHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\RecursiveRedirect.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\SimpleStaticRoute.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\SimpleTargetHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\StaticRoute.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\StrictRouteFixup.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="OutboundTarget.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Processor.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ProcessorChain.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Proxy.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="QValueTarget.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Registrar.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RegSyncClient.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RegSyncServer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RegSyncServerThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ReproServerAuthManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RequestContext.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ResponseContext.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RouteStore.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RRDecorator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="stateAgents\CertPublicationHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="stateAgents\CertServer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="stateAgents\CertSubscriptionHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="stateAgents\PrivateKeyPublicationHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="stateAgents\PrivateKeySubscriptionHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Store.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Target.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UserStore.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="WorkerThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="XmlRpcConnection.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="XmlRpcServerBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ProxyConfig.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\CertificateAuthenticator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StaticRegStore.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\GeoProximityTargetSorter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\RequestFilter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="FilterStore.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SiloStore.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="monkeys\MessageSilo.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="PersistentMessageQueue.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="AccountingCollector.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="AbstractDb.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Ack200DoneMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AclStore.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ChainTraverser.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CommandServer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CommandServerThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConfigStore.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Dispatcher.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\AmIResponsible.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\ConstantLocationMonkey.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\DigestAuthenticator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\IsTrustedNode.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\LocationServer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\OutboundTargetHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\QValueTargetHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\RecursiveRedirect.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\SimpleStaticRoute.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\SimpleTargetHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\StaticRoute.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\StrictRouteFixup.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="OutboundTarget.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Processor.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ProcessorChain.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Proxy.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="QValueTarget.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Registrar.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ReproServerAuthManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RequestContext.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ResponseContext.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RouteStore.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RRDecorator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="stateAgents\CertPublicationHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="stateAgents\CertServer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="stateAgents\CertSubscriptionHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="stateAgents\PrivateKeyPublicationHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="stateAgents\PrivateKeySubscriptionHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Store.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Target.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TimerCMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserAuthGrabber.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserInfoMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserStore.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="WorkerThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="XmlRpcConnection.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="XmlRpcServerBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RegSyncClient.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RegSyncServer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RegSyncServerThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ProxyConfig.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\CertificateAuthenticator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StaticRegStore.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\GeoProximityTargetSorter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\RequestFilter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ForkControlMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AsyncProcessor.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AsyncProcessorMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AsyncProcessorWorker.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="FilterStore.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SiloStore.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="monkeys\MessageSilo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PersistentMessageQueue.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Worker.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AccountingCollector.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/repro/reprolib_8_0.vcproj b/src/libs/resiprocate/repro/reprolib_8_0.vcproj new file mode 100644 index 00000000..bc3f828c --- /dev/null +++ b/src/libs/resiprocate/repro/reprolib_8_0.vcproj @@ -0,0 +1,855 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="reprolib" + ProjectGUID="{31B0654F-E08E-405F-909F-80F86CB14B9E}" + RootNamespace="reprolib" + Keyword="ManagedCProj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK" + MinimalRebuild="false" + BasicRuntimeChecks="0" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;USE_ARES;USE_IPV6" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL" + MinimalRebuild="false" + BasicRuntimeChecks="0" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + <AssemblyReference + RelativePath="mscorlib.dll" + AssemblyName="mscorlib, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=IA64" + /> + <AssemblyReference + RelativePath="System.dll" + AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" + /> + <AssemblyReference + RelativePath="System.Data.dll" + AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86" + /> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\AbstractDb.cxx" + > + </File> + <File + RelativePath=".\AccountingCollector.cxx" + > + </File> + <File + RelativePath=".\AclStore.cxx" + > + </File> + <File + RelativePath=".\monkeys\AmIResponsible.cxx" + > + </File> + <File + RelativePath=".\monkeys\CertificateAuthenticator.cxx" + > + </File> + <File + RelativePath=".\stateAgents\CertPublicationHandler.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\stateAgents\CertServer.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\stateAgents\CertSubscriptionHandler.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\CommandServer.cxx" + > + </File> + <File + RelativePath=".\CommandServerThread.cxx" + > + </File> + <File + RelativePath=".\ConfigStore.cxx" + > + </File> + <File + RelativePath=".\monkeys\ConstantLocationMonkey.cxx" + > + </File> + <File + RelativePath=".\monkeys\DigestAuthenticator.cxx" + > + </File> + <File + RelativePath=".\Dispatcher.cxx" + > + </File> + <File + RelativePath=".\FilterStore.cxx" + > + </File> + <File + RelativePath=".\monkeys\GeoProximityTargetSorter.cxx" + > + </File> + <File + RelativePath=".\monkeys\IsTrustedNode.cxx" + > + </File> + <File + RelativePath=".\monkeys\LocationServer.cxx" + > + </File> + <File + RelativePath=".\monkeys\MessageSilo.cxx" + > + </File> + <File + RelativePath=".\OutboundTarget.cxx" + > + </File> + <File + RelativePath=".\monkeys\OutboundTargetHandler.cxx" + > + </File> + <File + RelativePath=".\PersistentMessageQueue.cxx" + > + </File> + <File + RelativePath=".\stateAgents\PrivateKeyPublicationHandler.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\stateAgents\PrivateKeySubscriptionHandler.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\Processor.cxx" + > + </File> + <File + RelativePath=".\ProcessorChain.cxx" + > + </File> + <File + RelativePath=".\Proxy.cxx" + > + </File> + <File + RelativePath=".\ProxyConfig.cxx" + > + </File> + <File + RelativePath=".\QValueTarget.cxx" + > + </File> + <File + RelativePath=".\monkeys\QValueTargetHandler.cxx" + > + </File> + <File + RelativePath=".\monkeys\RecursiveRedirect.cxx" + > + </File> + <File + RelativePath=".\Registrar.cxx" + > + </File> + <File + RelativePath=".\RegSyncClient.cxx" + > + </File> + <File + RelativePath=".\RegSyncServer.cxx" + > + </File> + <File + RelativePath=".\RegSyncServerThread.cxx" + > + </File> + <File + RelativePath=".\ReproServerAuthManager.cxx" + > + </File> + <File + RelativePath=".\RequestContext.cxx" + > + </File> + <File + RelativePath=".\monkeys\RequestFilter.cxx" + > + </File> + <File + RelativePath=".\ResponseContext.cxx" + > + </File> + <File + RelativePath=".\RouteStore.cxx" + > + </File> + <File + RelativePath=".\RRDecorator.cxx" + > + </File> + <File + RelativePath=".\SiloStore.cxx" + > + </File> + <File + RelativePath=".\monkeys\SimpleStaticRoute.cxx" + > + </File> + <File + RelativePath=".\monkeys\SimpleTargetHandler.cxx" + > + </File> + <File + RelativePath=".\StaticRegStore.cxx" + > + </File> + <File + RelativePath=".\monkeys\StaticRoute.cxx" + > + </File> + <File + RelativePath=".\Store.cxx" + > + </File> + <File + RelativePath=".\monkeys\StrictRouteFixup.cxx" + > + </File> + <File + RelativePath=".\Target.cxx" + > + </File> + <File + RelativePath=".\UserStore.cxx" + > + </File> + <File + RelativePath=".\WorkerThread.cxx" + > + </File> + <File + RelativePath=".\XmlRpcConnection.cxx" + > + </File> + <File + RelativePath=".\XmlRpcServerBase.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\AbstractDb.hxx" + > + </File> + <File + RelativePath=".\AccountingCollector.hxx" + > + </File> + <File + RelativePath=".\Ack200DoneMessage.hxx" + > + </File> + <File + RelativePath=".\AclStore.hxx" + > + </File> + <File + RelativePath=".\monkeys\AmIResponsible.hxx" + > + </File> + <File + RelativePath=".\AsyncProcessor.hxx" + > + </File> + <File + RelativePath=".\AsyncProcessorMessage.hxx" + > + </File> + <File + RelativePath=".\AsyncProcessorWorker.hxx" + > + </File> + <File + RelativePath=".\monkeys\CertificateAuthenticator.hxx" + > + </File> + <File + RelativePath=".\stateAgents\CertPublicationHandler.hxx" + > + </File> + <File + RelativePath=".\stateAgents\CertServer.hxx" + > + </File> + <File + RelativePath=".\stateAgents\CertSubscriptionHandler.hxx" + > + </File> + <File + RelativePath=".\ChainTraverser.hxx" + > + </File> + <File + RelativePath=".\CommandServer.hxx" + > + </File> + <File + RelativePath=".\CommandServerThread.hxx" + > + </File> + <File + RelativePath=".\ConfigStore.hxx" + > + </File> + <File + RelativePath=".\monkeys\ConstantLocationMonkey.hxx" + > + </File> + <File + RelativePath=".\monkeys\DigestAuthenticator.hxx" + > + </File> + <File + RelativePath=".\Dispatcher.hxx" + > + </File> + <File + RelativePath=".\FilterStore.hxx" + > + </File> + <File + RelativePath=".\ForkControlMessage.hxx" + > + </File> + <File + RelativePath=".\monkeys\GeoProximityTargetSorter.hxx" + > + </File> + <File + RelativePath=".\monkeys\IsTrustedNode.hxx" + > + </File> + <File + RelativePath=".\monkeys\LocationServer.hxx" + > + </File> + <File + RelativePath=".\monkeys\MessageSilo.hxx" + > + </File> + <File + RelativePath=".\OutboundTarget.hxx" + > + </File> + <File + RelativePath=".\monkeys\OutboundTargetHandler.hxx" + > + </File> + <File + RelativePath=".\PersistentMessageQueue.hxx" + > + </File> + <File + RelativePath=".\stateAgents\PrivateKeyPublicationHandler.hxx" + > + </File> + <File + RelativePath=".\stateAgents\PrivateKeySubscriptionHandler.hxx" + > + </File> + <File + RelativePath=".\Processor.hxx" + > + </File> + <File + RelativePath=".\ProcessorChain.hxx" + > + </File> + <File + RelativePath=".\Proxy.hxx" + > + </File> + <File + RelativePath=".\ProxyConfig.hxx" + > + </File> + <File + RelativePath=".\QValueTarget.hxx" + > + </File> + <File + RelativePath=".\monkeys\QValueTargetHandler.hxx" + > + </File> + <File + RelativePath=".\monkeys\RecursiveRedirect.hxx" + > + </File> + <File + RelativePath=".\Registrar.hxx" + > + </File> + <File + RelativePath=".\RegSyncClient.hxx" + > + </File> + <File + RelativePath=".\RegSyncServer.hxx" + > + </File> + <File + RelativePath=".\RegSyncServerThread.hxx" + > + </File> + <File + RelativePath=".\ReproServerAuthManager.hxx" + > + </File> + <File + RelativePath=".\RequestContext.hxx" + > + </File> + <File + RelativePath=".\monkeys\RequestFilter.hxx" + > + </File> + <File + RelativePath=".\ResponseContext.hxx" + > + </File> + <File + RelativePath=".\RouteStore.hxx" + > + </File> + <File + RelativePath=".\RRDecorator.hxx" + > + </File> + <File + RelativePath=".\SiloStore.hxx" + > + </File> + <File + RelativePath=".\monkeys\SimpleStaticRoute.hxx" + > + </File> + <File + RelativePath=".\monkeys\SimpleTargetHandler.hxx" + > + </File> + <File + RelativePath=".\StaticRegStore.hxx" + > + </File> + <File + RelativePath=".\monkeys\StaticRoute.hxx" + > + </File> + <File + RelativePath=".\Store.hxx" + > + </File> + <File + RelativePath=".\monkeys\StrictRouteFixup.hxx" + > + </File> + <File + RelativePath=".\Target.hxx" + > + </File> + <File + RelativePath=".\TimerCMessage.hxx" + > + </File> + <File + RelativePath=".\UserAuthGrabber.hxx" + > + </File> + <File + RelativePath=".\UserInfoMessage.hxx" + > + </File> + <File + RelativePath=".\UserStore.hxx" + > + </File> + <File + RelativePath=".\Worker.hxx" + > + </File> + <File + RelativePath=".\WorkerThread.hxx" + > + </File> + <File + RelativePath=".\XmlRpcConnection.hxx" + > + </File> + <File + RelativePath=".\XmlRpcServerBase.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/repro/reprolib_9_0.vcproj b/src/libs/resiprocate/repro/reprolib_9_0.vcproj new file mode 100644 index 00000000..518d7747 --- /dev/null +++ b/src/libs/resiprocate/repro/reprolib_9_0.vcproj @@ -0,0 +1,847 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="reprolib" + ProjectGUID="{31B0654F-E08E-405F-909F-80F86CB14B9E}" + RootNamespace="reprolib" + Keyword="ManagedCProj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/GeoIP/libGeoIP&quot;;&quot;$(ProjectDir)../contrib/MySQLConnectorC/include&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;;USE_MYSQL;USE_MAXMIND_GEOIP" + MinimalRebuild="false" + BasicRuntimeChecks="0" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/GeoIP/libGeoIP&quot;;&quot;$(ProjectDir)../contrib/MySQLConnectorC/include&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_MYSQL;USE_MAXMIND_GEOIP" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)../contrib/GeoIP/libGeoIP&quot;;&quot;$(ProjectDir)../contrib/MySQLConnectorC/include&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;USE_MYSQL;USE_MAXMIND_GEOIP" + MinimalRebuild="false" + BasicRuntimeChecks="0" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../resip/stack&quot;;&quot;$(ProjectDir)../contrib/pcre&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)../contrib/GeoIP/libGeoIP&quot;;&quot;$(ProjectDir)../contrib/MySQLConnectorC/include&quot;;&quot;$(ProjectDir)../contrib/db/build_windows&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;USE_MYSQL;USE_MAXMIND_GEOIP" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + <AssemblyReference + RelativePath="mscorlib.dll" + AssemblyName="mscorlib, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=IA64" + MinFrameworkVersion="131072" + /> + <AssemblyReference + RelativePath="System.dll" + AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" + MinFrameworkVersion="131072" + /> + <AssemblyReference + RelativePath="System.Data.dll" + AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86" + MinFrameworkVersion="131072" + /> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\AbstractDb.cxx" + > + </File> + <File + RelativePath=".\AccountingCollector.cxx" + > + </File> + <File + RelativePath=".\AclStore.cxx" + > + </File> + <File + RelativePath=".\monkeys\AmIResponsible.cxx" + > + </File> + <File + RelativePath=".\monkeys\CertificateAuthenticator.cxx" + > + </File> + <File + RelativePath=".\stateAgents\CertPublicationHandler.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\stateAgents\CertServer.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\stateAgents\CertSubscriptionHandler.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\ConfigStore.cxx" + > + </File> + <File + RelativePath=".\monkeys\ConstantLocationMonkey.cxx" + > + </File> + <File + RelativePath=".\monkeys\DigestAuthenticator.cxx" + > + </File> + <File + RelativePath=".\Dispatcher.cxx" + > + </File> + <File + RelativePath=".\FilterStore.cxx" + > + </File> + <File + RelativePath=".\monkeys\GeoProximityTargetSorter.cxx" + > + </File> + <File + RelativePath=".\monkeys\IsTrustedNode.cxx" + > + </File> + <File + RelativePath=".\monkeys\LocationServer.cxx" + > + </File> + <File + RelativePath=".\monkeys\MessageSilo.cxx" + > + </File> + <File + RelativePath=".\OutboundTarget.cxx" + > + </File> + <File + RelativePath=".\monkeys\OutboundTargetHandler.cxx" + > + </File> + <File + RelativePath=".\PersistentMessageQueue.cxx" + > + </File> + <File + RelativePath=".\stateAgents\PrivateKeyPublicationHandler.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\stateAgents\PrivateKeySubscriptionHandler.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\Processor.cxx" + > + </File> + <File + RelativePath=".\ProcessorChain.cxx" + > + </File> + <File + RelativePath=".\Proxy.cxx" + > + </File> + <File + RelativePath=".\ProxyConfig.cxx" + > + </File> + <File + RelativePath=".\QValueTarget.cxx" + > + </File> + <File + RelativePath=".\monkeys\QValueTargetHandler.cxx" + > + </File> + <File + RelativePath=".\monkeys\RecursiveRedirect.cxx" + > + </File> + <File + RelativePath=".\Registrar.cxx" + > + </File> + <File + RelativePath=".\RegSyncClient.cxx" + > + </File> + <File + RelativePath=".\RegSyncServer.cxx" + > + </File> + <File + RelativePath=".\RegSyncServerThread.cxx" + > + </File> + <File + RelativePath=".\ReproServerAuthManager.cxx" + > + </File> + <File + RelativePath=".\RequestContext.cxx" + > + </File> + <File + RelativePath=".\monkeys\RequestFilter.cxx" + > + </File> + <File + RelativePath=".\ResponseContext.cxx" + > + </File> + <File + RelativePath=".\RouteStore.cxx" + > + </File> + <File + RelativePath=".\RRDecorator.cxx" + > + </File> + <File + RelativePath=".\SiloStore.cxx" + > + </File> + <File + RelativePath=".\monkeys\SimpleStaticRoute.cxx" + > + </File> + <File + RelativePath=".\monkeys\SimpleTargetHandler.cxx" + > + </File> + <File + RelativePath=".\StaticRegStore.cxx" + > + </File> + <File + RelativePath=".\monkeys\StaticRoute.cxx" + > + </File> + <File + RelativePath=".\Store.cxx" + > + </File> + <File + RelativePath=".\monkeys\StrictRouteFixup.cxx" + > + </File> + <File + RelativePath=".\Target.cxx" + > + </File> + <File + RelativePath=".\UserStore.cxx" + > + </File> + <File + RelativePath=".\WorkerThread.cxx" + > + </File> + <File + RelativePath=".\XmlRpcConnection.cxx" + > + </File> + <File + RelativePath=".\XmlRpcServerBase.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\AbstractDb.hxx" + > + </File> + <File + RelativePath=".\AccountingCollector.hxx" + > + </File> + <File + RelativePath=".\Ack200DoneMessage.hxx" + > + </File> + <File + RelativePath=".\AclStore.hxx" + > + </File> + <File + RelativePath=".\monkeys\AmIResponsible.hxx" + > + </File> + <File + RelativePath=".\AsyncProcessor.hxx" + > + </File> + <File + RelativePath=".\AsyncProcessorMessage.hxx" + > + </File> + <File + RelativePath=".\AsyncProcessorWorker.hxx" + > + </File> + <File + RelativePath=".\monkeys\CertificateAuthenticator.hxx" + > + </File> + <File + RelativePath=".\stateAgents\CertPublicationHandler.hxx" + > + </File> + <File + RelativePath=".\stateAgents\CertServer.hxx" + > + </File> + <File + RelativePath=".\stateAgents\CertSubscriptionHandler.hxx" + > + </File> + <File + RelativePath=".\ChainTraverser.hxx" + > + </File> + <File + RelativePath=".\ConfigStore.hxx" + > + </File> + <File + RelativePath=".\monkeys\ConstantLocationMonkey.hxx" + > + </File> + <File + RelativePath=".\monkeys\DigestAuthenticator.hxx" + > + </File> + <File + RelativePath=".\Dispatcher.hxx" + > + </File> + <File + RelativePath=".\FilterStore.hxx" + > + </File> + <File + RelativePath=".\ForkControlMessage.hxx" + > + </File> + <File + RelativePath=".\monkeys\GeoProximityTargetSorter.hxx" + > + </File> + <File + RelativePath=".\monkeys\IsTrustedNode.hxx" + > + </File> + <File + RelativePath=".\monkeys\LocationServer.hxx" + > + </File> + <File + RelativePath=".\monkeys\MessageSilo.hxx" + > + </File> + <File + RelativePath=".\OutboundTarget.hxx" + > + </File> + <File + RelativePath=".\monkeys\OutboundTargetHandler.hxx" + > + </File> + <File + RelativePath=".\PersistentMessageQueue.hxx" + > + </File> + <File + RelativePath=".\stateAgents\PrivateKeyPublicationHandler.hxx" + > + </File> + <File + RelativePath=".\stateAgents\PrivateKeySubscriptionHandler.hxx" + > + </File> + <File + RelativePath=".\Processor.hxx" + > + </File> + <File + RelativePath=".\ProcessorChain.hxx" + > + </File> + <File + RelativePath=".\Proxy.hxx" + > + </File> + <File + RelativePath=".\ProxyConfig.hxx" + > + </File> + <File + RelativePath=".\QValueTarget.hxx" + > + </File> + <File + RelativePath=".\monkeys\QValueTargetHandler.hxx" + > + </File> + <File + RelativePath=".\monkeys\RecursiveRedirect.hxx" + > + </File> + <File + RelativePath=".\Registrar.hxx" + > + </File> + <File + RelativePath=".\RegSyncClient.hxx" + > + </File> + <File + RelativePath=".\RegSyncServer.hxx" + > + </File> + <File + RelativePath=".\RegSyncServerThread.hxx" + > + </File> + <File + RelativePath=".\ReproServerAuthManager.hxx" + > + </File> + <File + RelativePath=".\RequestContext.hxx" + > + </File> + <File + RelativePath=".\monkeys\RequestFilter.hxx" + > + </File> + <File + RelativePath=".\ResponseContext.hxx" + > + </File> + <File + RelativePath=".\RouteStore.hxx" + > + </File> + <File + RelativePath=".\RRDecorator.hxx" + > + </File> + <File + RelativePath=".\SiloStore.hxx" + > + </File> + <File + RelativePath=".\monkeys\SimpleStaticRoute.hxx" + > + </File> + <File + RelativePath=".\monkeys\SimpleTargetHandler.hxx" + > + </File> + <File + RelativePath=".\StaticRegStore.hxx" + > + </File> + <File + RelativePath=".\monkeys\StaticRoute.hxx" + > + </File> + <File + RelativePath=".\Store.hxx" + > + </File> + <File + RelativePath=".\monkeys\StrictRouteFixup.hxx" + > + </File> + <File + RelativePath=".\Target.hxx" + > + </File> + <File + RelativePath=".\TimerCMessage.hxx" + > + </File> + <File + RelativePath=".\UserAuthGrabber.hxx" + > + </File> + <File + RelativePath=".\UserInfoMessage.hxx" + > + </File> + <File + RelativePath=".\UserStore.hxx" + > + </File> + <File + RelativePath=".\Worker.hxx" + > + </File> + <File + RelativePath=".\WorkerThread.hxx" + > + </File> + <File + RelativePath=".\XmlRpcConnection.hxx" + > + </File> + <File + RelativePath=".\XmlRpcServerBase.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/repro/stateAgents/CertPublicationHandler.cxx b/src/libs/resiprocate/repro/stateAgents/CertPublicationHandler.cxx new file mode 100644 index 00000000..754829cb --- /dev/null +++ b/src/libs/resiprocate/repro/stateAgents/CertPublicationHandler.cxx @@ -0,0 +1,72 @@ +#include "resip/stack/ssl/Security.hxx" +#include "resip/stack/X509Contents.hxx" +#include "resip/dum/ServerPublication.hxx" +#include "repro/stateAgents/CertPublicationHandler.hxx" + +using namespace repro; +using namespace resip; + +CertPublicationHandler::CertPublicationHandler(Security& security) : mSecurity(security) +{ +} + +void +CertPublicationHandler::onInitial(ServerPublicationHandle h, + const Data& etag, + const SipMessage& pub, + const Contents* contents, + const SecurityAttributes* attrs, + UInt32 expires) +{ + add(h, contents); +} + +void +CertPublicationHandler::onExpired(ServerPublicationHandle h, const Data& etag) +{ + mSecurity.removeUserCert(h->getPublisher()); +} + +void +CertPublicationHandler::onRefresh(ServerPublicationHandle, + const Data& etag, + const SipMessage& pub, + const Contents* contents, + const SecurityAttributes* attrs, + UInt32 expires) +{ +} + +void +CertPublicationHandler::onUpdate(ServerPublicationHandle h, + const Data& etag, + const SipMessage& pub, + const Contents* contents, + const SecurityAttributes* attrs, + UInt32 expires) +{ + add(h, contents); +} + +void +CertPublicationHandler::onRemoved(ServerPublicationHandle h, const Data& etag, const SipMessage& pub, UInt32 expires) +{ + mSecurity.removeUserCert(h->getPublisher()); +} + +void +CertPublicationHandler::add(ServerPublicationHandle h, const Contents* contents) +{ + if (h->getDocumentKey() == h->getPublisher()) + { + const X509Contents* x509 = dynamic_cast<const X509Contents*>(contents); + assert(x509); + mSecurity.addUserCertDER(h->getPublisher(), x509->getBodyData()); + h->send(h->accept(200)); + } + else + { + h->send(h->accept(403)); // !jf! is this the correct code? + } +} + diff --git a/src/libs/resiprocate/repro/stateAgents/CertPublicationHandler.hxx b/src/libs/resiprocate/repro/stateAgents/CertPublicationHandler.hxx new file mode 100644 index 00000000..b701fa6d --- /dev/null +++ b/src/libs/resiprocate/repro/stateAgents/CertPublicationHandler.hxx @@ -0,0 +1,51 @@ +#if !defined(Repro_CertPublicationHandler_hxx) +#define Repro_CertPublicationHandler_hxx + +#include "resip/dum/PublicationHandler.hxx" + +namespace resip +{ +class Security; +class SipMessage; +class SecurityAttributes; +class Data; +class Contents; +} + +namespace repro +{ + +class CertPublicationHandler : public resip::ServerPublicationHandler +{ + public: + CertPublicationHandler(resip::Security& security); + virtual void onInitial(resip::ServerPublicationHandle h, + const resip::Data& etag, + const resip::SipMessage& pub, + const resip::Contents* contents, + const resip::SecurityAttributes* attrs, + UInt32 expires); + virtual void onExpired(resip::ServerPublicationHandle h, const resip::Data& etag); + virtual void onRefresh(resip::ServerPublicationHandle, + const resip::Data& etag, + const resip::SipMessage& pub, + const resip::Contents* contents, + const resip::SecurityAttributes* attrs, + UInt32 expires); + virtual void onUpdate(resip::ServerPublicationHandle h, + const resip::Data& etag, + const resip::SipMessage& pub, + const resip::Contents* contents, + const resip::SecurityAttributes* attrs, + UInt32 expires); + virtual void onRemoved(resip::ServerPublicationHandle h, const resip::Data& etag, const resip::SipMessage& pub, UInt32 expires); + + private: + void add(resip::ServerPublicationHandle h, const resip::Contents* contents); + + resip::Security& mSecurity; +}; + +} + +#endif diff --git a/src/libs/resiprocate/repro/stateAgents/CertServer.cxx b/src/libs/resiprocate/repro/stateAgents/CertServer.cxx new file mode 100644 index 00000000..dce5f76b --- /dev/null +++ b/src/libs/resiprocate/repro/stateAgents/CertServer.cxx @@ -0,0 +1,39 @@ +#include "resip/stack/ssl/Security.hxx" +#include "resip/stack/Pkcs8Contents.hxx" +#include "resip/stack/X509Contents.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "repro/stateAgents/CertServer.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace repro; + +CertServer::CertServer(DialogUsageManager& dum) : + mDum(dum), + mPrivateKeyServer(*mDum.getSecurity()), + mPrivateKeyUpdater(*mDum.getSecurity()), + mCertServer(*mDum.getSecurity()), + mCertUpdater(*mDum.getSecurity()) +{ + MasterProfile& profile = *mDum.getMasterProfile(); + profile.addSupportedMethod(PUBLISH); + profile.addSupportedMethod(SUBSCRIBE); + //profile.validateAcceptEnabled() = true; // !slg! this causes Accept validation for registration requests as well, which is not really desired + profile.validateContentEnabled() = true; + profile.addSupportedMimeType(PUBLISH, Pkcs8Contents::getStaticType()); + profile.addSupportedMimeType(SUBSCRIBE, Pkcs8Contents::getStaticType()); + profile.addSupportedMimeType(PUBLISH, X509Contents::getStaticType()); + profile.addSupportedMimeType(SUBSCRIBE, X509Contents::getStaticType()); + + mDum.addServerSubscriptionHandler(Symbols::Credential, &mPrivateKeyServer); + mDum.addServerSubscriptionHandler(Symbols::Certificate, &mCertServer); + mDum.addServerPublicationHandler(Symbols::Credential, &mPrivateKeyUpdater); + mDum.addServerPublicationHandler(Symbols::Certificate, &mCertUpdater); + //setServerAuthManager(std::auto_ptr<ServerAuthManager>(new ServerAuthManager(profile))); +} + +CertServer::~CertServer() +{ +} + diff --git a/src/libs/resiprocate/repro/stateAgents/CertServer.hxx b/src/libs/resiprocate/repro/stateAgents/CertServer.hxx new file mode 100644 index 00000000..699d3b8f --- /dev/null +++ b/src/libs/resiprocate/repro/stateAgents/CertServer.hxx @@ -0,0 +1,33 @@ +#if !defined(Repro_CertServer_hxx) +#define Repro_CertServer_hxx + +#include "repro/stateAgents/CertPublicationHandler.hxx" +#include "repro/stateAgents/CertSubscriptionHandler.hxx" +#include "repro/stateAgents/PrivateKeyPublicationHandler.hxx" +#include "repro/stateAgents/PrivateKeySubscriptionHandler.hxx" + +namespace resip +{ +class DialogUsageManager; +} + +namespace repro +{ + +class CertServer +{ + public: + CertServer(resip::DialogUsageManager& dum); + ~CertServer(); + + private: + resip::DialogUsageManager& mDum; + + PrivateKeySubscriptionHandler mPrivateKeyServer; + PrivateKeyPublicationHandler mPrivateKeyUpdater; + CertSubscriptionHandler mCertServer; + CertPublicationHandler mCertUpdater; +}; + +} +#endif diff --git a/src/libs/resiprocate/repro/stateAgents/CertSubscriptionHandler.cxx b/src/libs/resiprocate/repro/stateAgents/CertSubscriptionHandler.cxx new file mode 100644 index 00000000..cd497715 --- /dev/null +++ b/src/libs/resiprocate/repro/stateAgents/CertSubscriptionHandler.cxx @@ -0,0 +1,52 @@ +#include "resip/stack/ssl/Security.hxx" +#include "resip/stack/X509Contents.hxx" +#include "repro/stateAgents/CertSubscriptionHandler.hxx" + +using namespace repro; +using namespace resip; + +CertSubscriptionHandler::CertSubscriptionHandler(Security& security) : mSecurity(security) +{ +} + +void +CertSubscriptionHandler::onNewSubscription(ServerSubscriptionHandle h, const SipMessage& sub) +{ + if (!mSecurity.hasUserCert(h->getDocumentKey())) + { + // !jf! really need to do this async. send neutral state in the meantime, + // blah blah blah + mSecurity.generateUserCert(h->getDocumentKey()); + } + + if (mSecurity.hasUserCert(h->getDocumentKey())) + { + X509Contents x509(mSecurity.getUserCertDER(h->getDocumentKey())); + h->send(h->update(&x509)); + } + else + { + h->reject(404); + } +} + +void +CertSubscriptionHandler::onPublished(ServerSubscriptionHandle associated, + ServerPublicationHandle publication, + const Contents* contents, + const SecurityAttributes* attrs) +{ + associated->send(associated->update(contents)); +} + + +void +CertSubscriptionHandler::onTerminated(ServerSubscriptionHandle) +{ +} + +void +CertSubscriptionHandler::onError(ServerSubscriptionHandle, const SipMessage& msg) +{ +} + diff --git a/src/libs/resiprocate/repro/stateAgents/CertSubscriptionHandler.hxx b/src/libs/resiprocate/repro/stateAgents/CertSubscriptionHandler.hxx new file mode 100644 index 00000000..f53f62bf --- /dev/null +++ b/src/libs/resiprocate/repro/stateAgents/CertSubscriptionHandler.hxx @@ -0,0 +1,38 @@ +#if !defined(Repro_CertSubscriptionHandler_hxx) +#define Repro_CertSubscriptionHandler_hxx + +#include "resip/dum/ServerPublication.hxx" +#include "resip/dum/ServerSubscription.hxx" +#include "resip/dum/SubscriptionHandler.hxx" + +namespace resip +{ +class Security; +class SipMessage; +class SecurityAttributes; +class Data; +class Contents; +} + +namespace repro +{ + +class CertSubscriptionHandler : public resip::ServerSubscriptionHandler +{ + public: + CertSubscriptionHandler(resip::Security& security); + virtual void onNewSubscription(resip::ServerSubscriptionHandle h, const resip::SipMessage& sub); + virtual void onPublished(resip::ServerSubscriptionHandle associated, + resip::ServerPublicationHandle publication, + const resip::Contents* contents, + const resip::SecurityAttributes* attrs); + virtual void onTerminated(resip::ServerSubscriptionHandle); + virtual void onError(resip::ServerSubscriptionHandle, const resip::SipMessage& msg); + + private: + resip::Security& mSecurity; +}; + +} + +#endif diff --git a/src/libs/resiprocate/repro/stateAgents/PrivateKeyPublicationHandler.cxx b/src/libs/resiprocate/repro/stateAgents/PrivateKeyPublicationHandler.cxx new file mode 100644 index 00000000..885b2f94 --- /dev/null +++ b/src/libs/resiprocate/repro/stateAgents/PrivateKeyPublicationHandler.cxx @@ -0,0 +1,71 @@ +#include "resip/stack/ssl/Security.hxx" +#include "resip/stack/Pkcs8Contents.hxx" +#include "resip/dum/ServerPublication.hxx" +#include "repro/stateAgents/PrivateKeyPublicationHandler.hxx" + +using namespace repro; +using namespace resip; + +PrivateKeyPublicationHandler::PrivateKeyPublicationHandler(Security& security) : mSecurity(security) +{ +} + +void +PrivateKeyPublicationHandler::onInitial(ServerPublicationHandle h, + const Data& etag, + const SipMessage& pub, + const Contents* contents, + const SecurityAttributes* attrs, + UInt32 expires) +{ + add(h, contents); +} + +void +PrivateKeyPublicationHandler::onExpired(ServerPublicationHandle h, const Data& etag) +{ + mSecurity.removeUserPrivateKey(h->getPublisher()); +} + +void +PrivateKeyPublicationHandler::onRefresh(ServerPublicationHandle, + const Data& etag, + const SipMessage& pub, + const Contents* contents, + const SecurityAttributes* attrs, + UInt32 expires) +{ +} + +void +PrivateKeyPublicationHandler::onUpdate(ServerPublicationHandle h, + const Data& etag, + const SipMessage& pub, + const Contents* contents, + const SecurityAttributes* attrs, + UInt32 expires) +{ + add(h, contents); +} + +void +PrivateKeyPublicationHandler::onRemoved(ServerPublicationHandle h, const Data& etag, const SipMessage& pub, UInt32 expires) +{ + mSecurity.removeUserPrivateKey(h->getPublisher()); +} + +void +PrivateKeyPublicationHandler::add(ServerPublicationHandle h, const Contents* contents) +{ + if (h->getDocumentKey() == h->getPublisher()) + { + const Pkcs8Contents* pkcs8 = dynamic_cast<const Pkcs8Contents*>(contents); + assert(pkcs8); + mSecurity.addUserPrivateKeyDER(h->getPublisher(), pkcs8->getBodyData()); + } + else + { + h->send(h->accept(403)); // !jf! is this the correct code? + } +} + diff --git a/src/libs/resiprocate/repro/stateAgents/PrivateKeyPublicationHandler.hxx b/src/libs/resiprocate/repro/stateAgents/PrivateKeyPublicationHandler.hxx new file mode 100644 index 00000000..d159266e --- /dev/null +++ b/src/libs/resiprocate/repro/stateAgents/PrivateKeyPublicationHandler.hxx @@ -0,0 +1,55 @@ +#if !defined(Repro_PrivateKeyPublicationHandler_hxx) +#define Repro_PrivateKeyPublicationHandler_hxx + +#include "resip/dum/PublicationHandler.hxx" + +namespace resip +{ +class Security; +class SipMessage; +class SecurityAttributes; +class Data; +class Contents; + +} + +namespace repro +{ + +class PrivateKeyPublicationHandler : public resip::ServerPublicationHandler +{ + public: + PrivateKeyPublicationHandler(resip::Security& security); + virtual void onInitial(resip::ServerPublicationHandle h, + const resip::Data& etag, + const resip::SipMessage& pub, + const resip::Contents* contents, + const resip::SecurityAttributes* attrs, + UInt32 expires); + virtual void onExpired(resip::ServerPublicationHandle h, const resip::Data& etag); + virtual void onRefresh(resip::ServerPublicationHandle, + const resip::Data& etag, + const resip::SipMessage& pub, + const resip::Contents* contents, + const resip::SecurityAttributes* attrs, + UInt32 expires); + virtual void onUpdate(resip::ServerPublicationHandle h, + const resip::Data& etag, + const resip::SipMessage& pub, + const resip::Contents* contents, + const resip::SecurityAttributes* attrs, + UInt32 expires); + virtual void onRemoved(resip::ServerPublicationHandle h, + const resip::Data& etag, + const resip::SipMessage& pub, + UInt32 expires); + + private: + void add(resip::ServerPublicationHandle h, const resip::Contents* contents); + + resip::Security& mSecurity; +}; + +} + +#endif diff --git a/src/libs/resiprocate/repro/stateAgents/PrivateKeySubscriptionHandler.cxx b/src/libs/resiprocate/repro/stateAgents/PrivateKeySubscriptionHandler.cxx new file mode 100644 index 00000000..dd106623 --- /dev/null +++ b/src/libs/resiprocate/repro/stateAgents/PrivateKeySubscriptionHandler.cxx @@ -0,0 +1,49 @@ +#include "resip/stack/Pkcs8Contents.hxx" +#include "resip/stack/ssl/Security.hxx" +#include "resip/dum/ServerSubscription.hxx" +#include "resip/dum/ServerPublication.hxx" +#include "repro/stateAgents/PrivateKeySubscriptionHandler.hxx" + +using namespace repro; +using namespace resip; + +PrivateKeySubscriptionHandler::PrivateKeySubscriptionHandler(resip::Security& security) : mSecurity(security) +{ +} + +void +PrivateKeySubscriptionHandler::onNewSubscription(ServerSubscriptionHandle h, const SipMessage& sub) +{ + if (h->getDocumentKey() != h->getSubscriber()) + { + h->send(h->accept(403)); // !jf! is this the correct code? + } + else if (mSecurity.hasUserCert(h->getDocumentKey())) + { + Pkcs8Contents pkcs(mSecurity.getUserPrivateKeyDER(h->getDocumentKey())); + h->send(h->update(&pkcs)); + } + else + { + h->reject(404); + } +} + +void +PrivateKeySubscriptionHandler::onPublished(ServerSubscriptionHandle associated, + ServerPublicationHandle publication, + const Contents* contents, + const SecurityAttributes* attrs) +{ + associated->send(associated->update(contents)); +} + +void +PrivateKeySubscriptionHandler::onTerminated(ServerSubscriptionHandle) +{ +} + +void +PrivateKeySubscriptionHandler::onError(ServerSubscriptionHandle, const SipMessage& msg) +{ +} diff --git a/src/libs/resiprocate/repro/stateAgents/PrivateKeySubscriptionHandler.hxx b/src/libs/resiprocate/repro/stateAgents/PrivateKeySubscriptionHandler.hxx new file mode 100644 index 00000000..b572bda2 --- /dev/null +++ b/src/libs/resiprocate/repro/stateAgents/PrivateKeySubscriptionHandler.hxx @@ -0,0 +1,36 @@ +#if !defined(Repro_PrivateKeySubscriptionHandler_hxx) +#define Repro_PrivateKeySubscriptionHandler_hxx + +#include "resip/dum/SubscriptionHandler.hxx" + +namespace resip +{ +class Security; +class SipMessage; +class SecurityAttributes; +class Data; +class Contents; +} + +namespace repro +{ + +class PrivateKeySubscriptionHandler : public resip::ServerSubscriptionHandler +{ + public: + PrivateKeySubscriptionHandler(resip::Security& security); + virtual void onNewSubscription(resip::ServerSubscriptionHandle h, const resip::SipMessage& sub); + virtual void onPublished(resip::ServerSubscriptionHandle associated, + resip::ServerPublicationHandle publication, + const resip::Contents* contents, + const resip::SecurityAttributes* attrs); + virtual void onTerminated(resip::ServerSubscriptionHandle); + virtual void onError(resip::ServerSubscriptionHandle, const resip::SipMessage& msg); + + private: + resip::Security& mSecurity; +}; + +} + +#endif diff --git a/src/libs/resiprocate/repro/test/Makefile b/src/libs/resiprocate/repro/test/Makefile new file mode 100644 index 00000000..63d41075 --- /dev/null +++ b/src/libs/resiprocate/repro/test/Makefile @@ -0,0 +1,67 @@ +# $Id: Makefile,v 1.70 2006/02/02 11:09 bcampen Exp $ + +BUILD = ../../build +CONTRIB = ../../contrib + +include $(BUILD)/Makefile.pre + +PACKAGES += REPRO RESIP RUTIL ARES OPENSSL PTHREAD POPT RADIUSCLIENTNG + + +TESTPROGRAMS += testDispatcher.cxx + +# Strip -DNDEBUG out of CFLAGS and CXXFLAGS, since these are test programs +CFLAGS := $(shell echo "${CFLAGS}" | sed s/-DNDEBUG//g) +CXXFLAGS := $(shell echo "${CXXFLAGS}" | sed s/-DNDEBUG//g) + +include $(BUILD)/Makefile.post + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# <http://www.vovida.org/>. +# +############################################################################## diff --git a/src/libs/resiprocate/repro/test/Makefile.am b/src/libs/resiprocate/repro/test/Makefile.am new file mode 100644 index 00000000..05d5ec56 --- /dev/null +++ b/src/libs/resiprocate/repro/test/Makefile.am @@ -0,0 +1,74 @@ +# $Id$ + +EXTRA_DIST = reg.py + +#AM_CXXFLAGS = -DUSE_ARES + +LDADD = ../librepro.la +LDADD += ../../resip/dum/libdum.la +LDADD += ../../resip/stack/libresip.la +LDADD += ../../rutil/librutil.la +#LDADD += ../../contrib/ares/libares.a +LDADD += $(LIBSSL_LIBADD) -lpthread + +# +# this test case doesn't appear to be up to date so it has been commented +# out during the migration to autotools +# +#TESTS = \ +# testDispatcher + +#check_PROGRAMS = \ +# testDispatcher + +#testDispatcher_SOURCES = testDispatcher.cxx + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# <http://www.vovida.org/>. +# +############################################################################## diff --git a/src/libs/resiprocate/repro/test/reg.py b/src/libs/resiprocate/repro/test/reg.py new file mode 100644 index 00000000..acdac206 --- /dev/null +++ b/src/libs/resiprocate/repro/test/reg.py @@ -0,0 +1,70 @@ +#!/usr/bin/python +# program to sent test registrations + +from socket import * +from random import * +from time import * + +proxyHost = "10.0.1.6" +proxyPort = "5060" +domain = "localhost" + +myHost = "10.0.1.3" +myPort = "5074" + +print "Will register to ", proxyHost, ":", proxyPort +randGen = Random() +randGen.seed() + +sock = socket( AF_INET, SOCK_DGRAM ) +sock.bind(('',int(myPort))) + +startTime = time() + +n = 0 +numUsers = 5000 +outstanding = 0; + +while ( n < numUsers ): + n = n+1 + user = "User" + str(n) + rand = str(randGen.randrange(1,2000000000,1)) + data = "\ +REGISTER sip:" +domain+ " SIP/2.0\r\n\ +To: <sip:" + user + "@" +domain+ ">\r\n\ +From: <sip:" +user+ "@" +domain+ ">;tag=90538639\r\n\ +Via: SIP/2.0/UDP " +myHost+ ":" +myPort+ ";branch=z9hG4bK-" + rand + ";rport\r\n\ +Call-ID: " + rand + "@bG9jYWxob3N0YWlu\r\n\ +CSeq: 1 REGISTER\r\n\ +Route: <sip:" +proxyHost+ ":" +proxyPort+ ">\r\n\ +Contact: <sip:" +user+ "@" +myHost+ ":" +myPort+ ">;expires=3600\r\n\ +Expires: 3600\r\n\ +Max-Forwards: 70\r\n\ +User-Agent: repro-test-python-reg/0.1 (pyton test register)\r\n\ +Content-Length: 0\r\n\ +\r\n" + s = sock.sendto(data,(proxyHost,int(proxyPort))) + outstanding = outstanding+1 + + if ( n%100 == 0 ): + print "Send registration for",user," in ",s,"octets" + + if ( outstanding > 40 ): + junk = sock.recv(8192) + outstanding = outstanding - 1 + #print "got packet" + +# pick up the remaingin responses +while ( outstanding > 50 ) : + print "oustanding=", outstanding + junk = sock.recv(8192) + outstanding = outstanding - 1 + +endTime = time(); +sock.close() + +print "Did",n," registration in ",endTime-startTime,"seconds or",n/(endTime-startTime),"tps" + + + + diff --git a/src/libs/resiprocate/repro/test/testDispatcher.cxx b/src/libs/resiprocate/repro/test/testDispatcher.cxx new file mode 100644 index 00000000..54e72c96 --- /dev/null +++ b/src/libs/resiprocate/repro/test/testDispatcher.cxx @@ -0,0 +1,309 @@ +#include "repro/Worker.hxx" +#include "repro/Dispatcher.hxx" + +#include "resip/stack/SipStack.hxx" +#include "resip/stack/StackThread.hxx" +#include "resip/stack/TransactionUser.hxx" +#include "resip/stack/ApplicationMessage.hxx" + +#include "rutil/Data.hxx" + +#include <iostream> +#include <cassert> + +//main is way down at the bottom. + +namespace test +{ + +class DummyWorkMessage : public resip::ApplicationMessage +{ + public: + DummyWorkMessage(resip::TransactionUser* passedTU, resip::Data string=resip::Data::Empty) + { + tu=passedTU; + mTid=""; + mQuery=string; + wait=false; + } + + + DummyWorkMessage(const DummyWorkMessage& orig) + { + tu=orig.tu; + mTid=orig.mTid; + mQuery=orig.mQuery; + mResult=orig.mResult; + wait=orig.wait; + } + + virtual ~DummyWorkMessage(){} + + resip::Data& result() + { + return mResult; + } + + resip::Data& query() + { + return mQuery; + } + + virtual DummyWorkMessage* clone() const {return new DummyWorkMessage(*this);}; + virtual const resip::Data& getTransactionId() const {return mTid;}; + + virtual std::ostream& encode(std::ostream& ostr) const { ostr << "DummyWorkMessage("<<mTid<<") "; return ostr; }; + virtual std::ostream& encodeBrief(std::ostream& ostr) const{ ostr << "DummyWorkMessage("<<mTid<<") "; return ostr; }; + + bool wait; + + private: + resip::Data mResult; + resip::Data mQuery; + resip::Data mTid; +}; + +class DummyWorker : public repro::Worker +{ + public: + DummyWorker(){} + virtual ~DummyWorker(){} + + virtual void process(resip::ApplicationMessage* app) + { + DummyWorkMessage* dwm = dynamic_cast<DummyWorkMessage*>(app); + if(dwm) + { + dwm->result()=" I got that thing you sent me."; + if(dwm->wait) + { + sleep(1); + } + } + + } + + virtual DummyWorker* clone() const + { + return new DummyWorker; + } +}; + + + +class DummyTU : public resip::TransactionUser +{ + public: + DummyTU(resip::SipStack* stack) + { + mName="DummyTU"; + mStack=stack; + mStack->registerTransactionUser(*this); + DummyWorker* dw = new DummyWorker; + std::auto_ptr<repro::Worker> worker(dw); + mDispatcher = new repro::Dispatcher(worker,mStack,3,false); + } + + virtual ~DummyTU() + { + delete mDispatcher; + } + + virtual void go() + { + assert(mDispatcher); + DummyWorkMessage* lost = new DummyWorkMessage(this); + + //Dispatcher should not be accepting work yet + assert(!mDispatcher->post(std::auto_ptr<resip::ApplicationMessage>(lost))); + + mDispatcher->startAll(); + + DummyWorkMessage* a = new DummyWorkMessage(this,"A"); + DummyWorkMessage* b = new DummyWorkMessage(this,"B"); + DummyWorkMessage* c = new DummyWorkMessage(this,"C"); + DummyWorkMessage* d = new DummyWorkMessage(this,"D"); + + std::auto_ptr<resip::ApplicationMessage> aa(a); + std::auto_ptr<resip::ApplicationMessage> ab(b); + std::auto_ptr<resip::ApplicationMessage> ac(c); + std::auto_ptr<resip::ApplicationMessage> ad(d); + + assert(mDispatcher->post(aa)); + assert(mDispatcher->post(ab)); + assert(mDispatcher->post(ac)); + assert(mDispatcher->post(ad)); + + bool gotA=false; + bool gotB=false; + bool gotC=false; + bool gotD=false; + int i=0; + resip::Message* msg; + + for( i=0; i<4 ;i++) + { + assert(msg = mFifo.getNext(1000)); + + DummyWorkMessage* dwm = dynamic_cast<DummyWorkMessage*>(msg); + + assert(dwm); + + if(dwm->result()==" I got that thing you sent me.") + { + if(dwm->query()=="A") gotA=true; + if(dwm->query()=="B") gotB=true; + if(dwm->query()=="C") gotC=true; + if(dwm->query()=="D") gotD=true; + } + + delete dwm; + + } + + assert(i==4); + assert(gotA && gotB && gotC && gotD); + + mDispatcher->stop(); + + lost = new DummyWorkMessage(this,""); + + //We stopped the thread bank, it should not be accepting work. + assert(!mDispatcher->post(std::auto_ptr<resip::ApplicationMessage>(lost))); + + mDispatcher->resume(); + + DummyWorkMessage* wasteTime1 = new DummyWorkMessage(this,"Take your time."); + DummyWorkMessage* wasteTime2 = new DummyWorkMessage(this,"Take your time."); + DummyWorkMessage* wasteTime3 = new DummyWorkMessage(this,"Take your time."); + DummyWorkMessage* wasteTime4 = new DummyWorkMessage(this,"Take your time."); + wasteTime1->wait=true; + wasteTime2->wait=true; + wasteTime3->wait=true; + wasteTime4->wait=true; + + assert(mDispatcher->fifoCountDepth()==0); + + mDispatcher->post(std::auto_ptr<resip::ApplicationMessage>(wasteTime1)); + mDispatcher->post(std::auto_ptr<resip::ApplicationMessage>(wasteTime2)); + mDispatcher->post(std::auto_ptr<resip::ApplicationMessage>(wasteTime3)); + mDispatcher->post(std::auto_ptr<resip::ApplicationMessage>(wasteTime4)); + mDispatcher->stop(); + + usleep(1000); + //Three in the thread bank, one in the queue. + assert(mDispatcher->fifoCountDepth()==1); + + for( i=0; i<4 ;i++) + { + assert(msg = mFifo.getNext(2000)); + + DummyWorkMessage* dwm = dynamic_cast<DummyWorkMessage*>(msg); + + assert(dwm); + + assert(dwm->result()==" I got that thing you sent me."); + + delete dwm; + } + + assert(!(msg=mFifo.getNext(1000))); + + mDispatcher->resume(); + + DummyWorkMessage* clog1 = new DummyWorkMessage(this); + DummyWorkMessage* clog2 = new DummyWorkMessage(this); + DummyWorkMessage* clog3 = new DummyWorkMessage(this); + clog1->wait=true; + clog2->wait=true; + clog3->wait=true; + + //Three threads in the bank, each waiting for 1 sec + mDispatcher->post(std::auto_ptr<resip::ApplicationMessage>(clog1)); + mDispatcher->post(std::auto_ptr<resip::ApplicationMessage>(clog2)); + mDispatcher->post(std::auto_ptr<resip::ApplicationMessage>(clog3)); + + usleep(100); + + for(i=0;i<1000;i++) + { + DummyWorkMessage* pummel = new DummyWorkMessage(this); + std::auto_ptr<resip::ApplicationMessage>batter(pummel); + assert(mDispatcher->post(batter)); + } + + + usleep(100000); + + assert(msg=mFifo.getNext(1000)); + + delete msg; + + + + for(i=0;i<1002;i++) + { + msg=mFifo.getNext(10); + assert(msg); + delete msg; + } + + mDispatcher->shutdownAll(); + + + lost = new DummyWorkMessage(this); + assert(!(mDispatcher->post(std::auto_ptr<resip::ApplicationMessage>(lost)))); + + + + delete mDispatcher; + + + DummyWorker* dw = new DummyWorker; + std::auto_ptr<repro::Worker> worker(dw); + //Stack ptr set to null. + mDispatcher = new repro::Dispatcher(worker,0,3,true); + + std::cout << "The following error message is intentional." << std::endl; + + lost = new DummyWorkMessage(this); + assert(mDispatcher->post(std::auto_ptr<resip::ApplicationMessage>(lost))); + + assert(!(msg=mFifo.getNext(100))); + + + + } + + virtual const resip::Data& name() const + { + return mName; + } + + + private: + repro::Dispatcher* mDispatcher; + resip::SipStack* mStack; + resip::Data mName; + +}; + + +} + + +int +main() +{ + resip::SipStack mStack; + resip::StackThread stackThread(mStack); + test::DummyTU mTU(&mStack); + stackThread.run(); + + mTU.go(); + std::cout << "PASSED" << std::endl; + stackThread.shutdown(); + stackThread.join(); + mStack.shutdown(); +} + diff --git a/src/libs/resiprocate/repro/userAdmin.cxx b/src/libs/resiprocate/repro/userAdmin.cxx new file mode 100644 index 00000000..83202f2e --- /dev/null +++ b/src/libs/resiprocate/repro/userAdmin.cxx @@ -0,0 +1,142 @@ + +#include <cassert> +#include <iostream> + +#include "repro/UserDb.hxx" +#include "repro/WebAdmin.hxx" +#include "rutil/Data.hxx" +#include "rutil/Logger.hxx" + +using namespace resip; +using namespace repro; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO + + +void +add( char* pUsername, char* pRealm, char* pPasswd ) +{ + UserDb db; + + Data fullName = Data::Empty; + Data email = Data::Empty; + + db.addUser( Data(pUsername), + Data(pRealm), + Data(pRealm), + Data(pPasswd), + fullName, + email ); +} + + +void +remove( char* pAor ) +{ + UserDb db; + + db.removeUser( Data(pAor) ); +} + + +void +web(int port) +{ + assert(0); +#if 0 + UserDb db; + + WebAdmin webAdmin( db, port ); + + while (1) + { + FdSet fdset; + + webAdmin.buildFdSet(fdset); + fdset.selectMilliSeconds( 10*1000 ); + + webAdmin.process(fdset); + } +#endif +} + + +void +list() +{ + UserDb db; + + Data key = db.getFirstKey(); + while ( !key.empty() ) + { + Data hash = db.getUserAuthInfo(key); + + clog << "Key: " << key << endl; + clog << " passwordHash = " << hash << endl; + + key = db.getNextKey(); + } +} + + +void +usage() +{ + clog << "Command line options are" << endl + << " -list" << endl + << " -add user realm password" << endl + << " -remove aor" << endl + << " -web" << endl; +} + + +int +main(int argc, char* argv[]) +{ + Log::initialize(Log::Cerr, Log::Err, argv[0]); + Log::setLevel(Log::Info); + + for ( int i=1; i<argc; i++ ) + { + if ( !strcmp(argv[i],"-list" ) ) + { + list(); + } + if ( !strcmp(argv[i],"-web" ) ) + { + int port=5080; + web(port); + } + else if (!strcmp(argv[i],"-add")) + { + i++; + assert( i<argc ); + char* username = argv[i]; + + i++; + assert( i<argc ); + char* realm = argv[i]; + + i++; + assert( i<argc ); + char* passwd = argv[i]; + + add( username, realm, passwd ); + } + else if (!strcmp(argv[i],"-remove")) + { + i++; + assert( i<argc ); + char* aor = argv[i]; + remove( aor ); + } + else + { + usage(); + exit(1); + } + } + + return 0; +} diff --git a/src/libs/resiprocate/repro/webadmin/AclAdmin.cxx b/src/libs/resiprocate/repro/webadmin/AclAdmin.cxx new file mode 100644 index 00000000..1e2c9d70 --- /dev/null +++ b/src/libs/resiprocate/repro/webadmin/AclAdmin.cxx @@ -0,0 +1,174 @@ +class Acl +{ + + + private: + class V6AddrMask + { + public: + V6AddrMask(in_addr6 ip6Addr = v6Loopback, int mask = 128) + friend: + in_addr6 mIp6Addr; // ?? check these types + int mMask; + }; + + class V4AddrMask + { + public: + V4AddrMask(in_addr ip4Addr = v4Loopback, int mask = 32) + friend: + in_addr mIp4Addr; // ?? check these types + int mMask; + }; + + typedef list<V6AddrMask> v6addrMaskList; + typedef list<V4AddrMask> v4addrMaskList; + + v6addrMaskList mV6AclList; + v4addrMaskList mV4AclList; +}; + + + +bool Acl::parseAcl(Data& rawInput) +{ + // Input can be in any of these formats + // localhost localhost (becomes 127.0.0.1/8, ::1/128 and fe80::1/64) + // bare hostname server1 + // FQDN server1.example.com + // IPv4 address 192.168.1.100 + // IPv4 + mask 192.168.1.0/24 + // IPv6 address :341:0:23:4bb:0011:2435:abcd + // IPv6 + mask :341:0:23:4bb:0011:2435:abcd/80 + // IPv6 reference [:341:0:23:4bb:0011:2435:abcd] + // IPv6 ref + mask [:341:0:23:4bb:0011:2435:abcd]/64 + + ParseBuffer pb(rawInput); + const char* anchor = pb.start(); + + bool ipv4 = false; + bool ipv6 = false; + bool fqdn = false; + Data hostOrIp; + u_char in6[20]; + u_char in4[4]; + int mask; + + if (*pb.position() == '[') // encountered beginning of IPv6 reference + { + anchor = pb.skipChar(); + skipToEndQuote(']'); + // TODO check for end of stream here + + pb.data(hostOrIp, anchor); // copy the presentation form of the IPv6 address + anchor = pb.skipChar(); + + // try to convert into IPv6 network form + if (!inet_pton6(hostOrIp.c_str(), in6)) // is this correct? + { + return INVALID; + } + ipv6 = true; + } + else + { + pb.skipToOneOf(".:"); + if (pb.position() == pb.end()) // We probably have a bare hostname + { + pb.data(hostOrIp, anchor); + if (hostOrIp.lowercase() == "localhost") + { + // add special localhost addresses for v4 and v6 to list and return + return SUCCESS; + } + // hostOrIp += default domain name + } + else if (*pb.position() == ':') // Must be an IPv6 address + { + pb.skipToChar('/'); + + pb.data(hostOrIp, anchor); // copy the presentation form of the IPv6 address + anchor = pb.skipChar(); + + // try to convert into IPv6 network form + if (!inet_pton6(hostOrIp.c_str(), in6)) // is this correct? + { + return INVALID; + } + ipv6 = true; + } + else // *pb.position() == '.' + { + assert( *pb.position() == '.'); + + // Could be either an IPv4 address or an FQDN + pb.skipToChar('/'); + pb.data(hostOrIp, anchor); // copy the presentation form of the address + + // try to interpret as an IPv4 address, if that fails look it up in DNS + if (inet_pton4(hostOrIp.c_str(), in4)) // is this correct? + { + // it was an IPv4 address + ipv4 = true; + } + else + { + // hopefully it is a legal FQDN, try it. + fqdn = true; + } + } + } + + if (fqdn) + { + // do DNS A and AAAA lookups and store the results with the default (host) mask + return; + } + + if (*pb.position() == '/') // grab the mask as well + { + anchor = pb.skipChar(); + mask = pb.integer(); + + if (ipv4) + { + if (mask < 8 || mask > 32) + { + return INVALID; + } + } + else if (ipv6) + { + if (mask < 64 || mask > 128) + { + return INVALID; + } + } + } + else + { + if (ipv4) + { + mask = 32; + } + else // ipv6 + { + mask = 128; + } + } + + if pb.position() == pb.end()) + { + if (ipv6) + { + mV6AclList.pushback(V6AddrMask(in6,mask)); + } + + if (ipv4) + { + mV4AclList.pushback(V4AddrMask(in4,mask)); + } + return SUCCESS; + } + return INVALID; +}; diff --git a/src/libs/resiprocate/repro/webadmin/addUser.html b/src/libs/resiprocate/repro/webadmin/addUser.html new file mode 100644 index 00000000..d6f1a149 --- /dev/null +++ b/src/libs/resiprocate/repro/webadmin/addUser.html @@ -0,0 +1,44 @@ +<html> +<body> + +<form id="addUserForm" action="input" method="get" name="addUserForm" enctype="application/x-www-form-urlencoded"> +<table border="0" cellspacing="2" cellpadding="0" align="left"> +<tr> + <td align="right" valign="middle">User Name:</td> + <td align="left" valign="middle"><input type="text" name="user" size="24"/></td> +</tr> +<tr> + <td align="right" valign="middle" >Domain:</td> + <td align="left" valign="middle"> + <select name="domain"> + <option selected="true">default: localhost</option> + <option>example.com</option> + <option>example.org</option> + </select> + </td> +</tr> +<tr> + + <td align="right" valign="middle" >Password:</td> + <td align="left" valign="middle"><input type="password" name="password" size="24"/></td> +</tr> +<tr> + <td align="right" valign="middle" >Full Name:</td> + <td align="left" valign="middle"><input type="text" name="name" size="24"/></td> +</tr> +<tr> + <td align="right" valign="middle" >Email:</td> + + <td align="left" valign="middle"><input type="text" name="email" size="24"/></td> +</tr> +<tr> + <td colspan="2" align="right" valign="middle"> + <input type="reset" value="Cancel"/> + <input type="submit" name="submit" value="Add"/> + </td> +</tr> +</table> +</form> + +</body> +</html> diff --git a/src/libs/resiprocate/repro/webadmin/doublequoteme b/src/libs/resiprocate/repro/webadmin/doublequoteme new file mode 100644 index 00000000..2e80c2ed --- /dev/null +++ b/src/libs/resiprocate/repro/webadmin/doublequoteme @@ -0,0 +1,32 @@ +#!/usr/bin/perl + +$usage = "Usage: doublequoteme sourcefile [destfile]\n\n"; + +if ($#ARGV < 0 || $#ARGV > 1) {print $usage; exit; } + +if ($#ARGV == 1) { ($src, $dst) = @ARGV; } +else +{ + ($src) = @ARGV; +# $dst = "$src" . ".fixme"; + $_ = $src; + s/^([A-Za-z0-9-]+)\.html$/$1.ixx/; + $dst = $_; +} + +open (SRC, "<$src"); +open (DST, ">$dst"); + +while (<SRC>) +{ + chomp; + s'\\'\\\\'g; + s/"/\\"/g; + print DST "\"$_\\n\"\n"; +} + +close SRC; +close DST; + +# if ($#ARGV == 0) {unlink $dst}; + diff --git a/src/libs/resiprocate/repro/webadmin/pageOutlinePost.html b/src/libs/resiprocate/repro/webadmin/pageOutlinePost.html new file mode 100644 index 00000000..980960da --- /dev/null +++ b/src/libs/resiprocate/repro/webadmin/pageOutlinePost.html @@ -0,0 +1,3 @@ + </div> + </body> +</html> diff --git a/src/libs/resiprocate/repro/webadmin/pageOutlinePost.ixx b/src/libs/resiprocate/repro/webadmin/pageOutlinePost.ixx new file mode 100644 index 00000000..20ce56ac --- /dev/null +++ b/src/libs/resiprocate/repro/webadmin/pageOutlinePost.ixx @@ -0,0 +1,6 @@ +" </div>\n" +" <div style=\"clear:both;height: 10px\"><br /></div>\n" +" <div id=\"footer\" style=\"color: white; background-color: #395af6; text-align:center; padding-top: 10px; padding-bottom: 10px\">\n" +" <a href=\"http://www.resiprocate.org/About_Repro\">www.resiprocate.org</a></div>\n" +" </body>\n" +"</html>\n" diff --git a/src/libs/resiprocate/repro/webadmin/pageOutlinePre.html b/src/libs/resiprocate/repro/webadmin/pageOutlinePre.html new file mode 100644 index 00000000..584d5ad4 --- /dev/null +++ b/src/libs/resiprocate/repro/webadmin/pageOutlinePre.html @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="content-type" content="text/html;charset=utf-8" /> + <title>Repro Proxy</title> + </head> + <style> +body { bgcolor: white; font-size: 90%; font-family: Arial, Helvetica, sans-serif } +h1 { font-size: 200%; font-weight: bold } +h2 { font-size: 100%; font-weight: bold; text-transform: uppercase } +h3 { font-size: 100%; font-weight: normal } +h4 { font-size: 100%; font-style: oblique; font-weight: normal } +hr { line-height: 2px; margin-top: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0; height: 10px } +div.title { color: white; background-color: #395af6; padding-top: 10px; padding-bottom: 10px; padding-left: 10px } +div.title h1 { text-transform: uppercase; margin-top: 0; margin-bottom: 0 } +div.menu { color: black; background-color: #ff8d09; padding: 0 10px 10px; + width: 9em; float: left; clear: none; overflow: hidden } +div.menu p { font-weight: bold; text-transform: uppercase; list-style-type: none; + margin-top: 0; margin-bottom: 0; margin-left: 10px } +div.menu h2 { margin-top: 10px; margin-bottom: 0 ; text-transform: uppercase; } +div.main { color: black; background-color: #dae1ed; margin-left: 11em } +div.space { font-size: 5px; height: 10px } + </style> + <body> + + <div class="title" > + <h1>Repro</h1> + </div> + <div class="space"> + <br /> + </div> + <div class="menu" > + <h2>Configure</h2> + + <p><a href="domains.html">Domains</a></p> + <p><a href="acls.html">ACLs</a></p> + <h2>Users</h2> + <p><a href="addUser.html">Add User</a></p> + <p><a href="showUsers.html">Show Users</a></p> + <h2>Routes</h2> + + <p><a href="addRoute.html">Add Route</a></p> + <p><a href="showRoutes.html">Show Routes</a></p> + <h2>Statistics</h2> + <p><a href="registrations.html">Registrations</a></p> + </div> + <div class="main"> diff --git a/src/libs/resiprocate/repro/webadmin/pageOutlinePre.ixx b/src/libs/resiprocate/repro/webadmin/pageOutlinePre.ixx new file mode 100644 index 00000000..c3937c09 --- /dev/null +++ b/src/libs/resiprocate/repro/webadmin/pageOutlinePre.ixx @@ -0,0 +1,50 @@ +"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n" +"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" +" <head>\n" +" <meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />\n" +" <title>Repro Proxy</title>\n" +" </head>\n" +" <style>\n" +"body { bgcolor: white; font-size: 90%; font-family: Arial, Helvetica, sans-serif }\n" +"h1 { font-size: 200%; font-weight: bold }\n" +"h2 { font-size: 100%; font-weight: bold; text-transform: uppercase }\n" +"h3 { font-size: 100%; font-weight: normal }\n" +"h4 { font-size: 100%; font-style: oblique; font-weight: normal } \n" +"hr { line-height: 2px; margin-top: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0; height: 10px }\n" +"div.title { color: white; background-color: #395af6; padding-top: 10px; padding-bottom: 10px; padding-left: 10px }\n" +"div.title h1 { text-transform: uppercase; margin-top: 0; margin-bottom: 0 } \n" +"div.menu { color: black; background-color: #ff8d09; padding: 0 10px 10px; \n" +" width: 9em; float: left; clear: none; overflow: hidden }\n" +"div.menu p { font-weight: bold; text-transform: uppercase; list-style-type: none; \n" +" margin-top: 0; margin-bottom: 0; margin-left: 10px }\n" +"div.menu h2 { margin-top: 10px; margin-bottom: 0 ; text-transform: uppercase; }\n" +"div.main { color: black; background-color: #dae1ed; margin-left: 11em; padding-top: 10px; padding-bottom: 10px; padding-left: 10px }\n" +"div.space { font-size: 5px; height: 10px }\n" +" </style>\n" +" <body>\n" +"\n" +" <div class=\"title\" >\n" +" <table width=\"100%\"><tr><td><h1>Repro</h1></td><td align=\"right\"><small><i>vVERSION</i></small></td></tr></table>\n" +" </div>\n" +" <div class=\"space\">\n" +" <br />\n" +" </div>\n" +" <div class=\"menu\" >\n" +" <h2>Configure</h2>\n" +" <p><a href=\"domains.html\">Domains</a></p>\n" +" <p><a href=\"acls.html\">ACLs</a></p>\n" +" <h2>Users</h2>\n" +" <p><a href=\"addUser.html\">Add User</a></p>\n" +" <p><a href=\"showUsers.html\">Show Users</a></p>\n" +" <h2>Request Filters</h2>\n" +" <p><a href=\"addFilter.html\">Add Filter</a></p>\n" +" <p><a href=\"showFilters.html\">Show Filters</a></p>\n" +" <h2>Routes</h2>\n" +" <p><a href=\"addRoute.html\">Add Route</a></p>\n" +" <p><a href=\"showRoutes.html\">Show Routes</a></p>\n" +" <h2>Statistics</h2>\n" +" <p><a href=\"settings.html\">Settings</a></p>\n" +" <p><a href=\"registrations.html\">Registrations</a></p>\n" +" </div>\n" +" <div class=\"main\">\n" diff --git a/src/libs/resiprocate/resip.spec b/src/libs/resiprocate/resip.spec new file mode 100644 index 00000000..902440fb --- /dev/null +++ b/src/libs/resiprocate/resip.spec @@ -0,0 +1,83 @@ +Name: resiprocate +Version: 1.1 +Release: 1 + +Summary: Resiprocate SIP Stack +License: Vovida Software License http://opensource.org/licenses/vovidapl.php +Group: Productivity/Telephony/SIP/Servers +Vendor: resiprocate.org +Packager: Alfred E. Heggestad <aeh@db.org> +Url: http://www.resiprocate.org + +Source: %name-%version.tar.gz + +BuildRequires: openssl-devel >= 0.9.7 +BuildRequires: popt +BuildRequires: boost-devel + +Requires: openssl >= 0.9.7 +Requires: chkconfig + +Prefix: %_prefix +BuildRoot: %{_tmppath}/%name-%version-root + +%description +The reSIProcate components, particularly the SIP stack, are in use in both +commercial and open-source products. The project is dedicated to maintaining +a complete, correct, and commercially usable implementation of SIP and a few +related protocols. + +%package devel +Summary: Resiprocate development files +Group: Development/Libraries +Requires: %{name} = %{version} + +%description devel +Resiprocate SIP Stack development files. + +%prep +%setup -q + +%build +./configure -y --with-compile-type=opt --enable-shared-libs --disable-ssl --disable-sigcomp --disable-ipv6 --prefix=/usr --ares-prefix=/usr +make resiprocate + +%install +# makeinstall RPM macro doesn't leverage DESTDIR but instead overrides +# libdir, bindir, etc just for make install. This not copesetic w/how +# our makefiles are built, they'd rather preserve libdir, and use +# DESTDIR when copying/moving/creating files. The approach we're taking +# is quite standard, so it's surprising RPM's makeinstall macro is +# the way it is. +rm -rf $RPM_BUILD_ROOT +make DESTDIR=$RPM_BUILD_ROOT INSTALL_PREFIX=/usr install-rutil install-resip +make DESTDIR=$RPM_BUILD_ROOT ARES_PREFIX=/usr install-ares + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig + +%files +%defattr(644,root,root,755) +%{_libdir}/librutil.so +%{_libdir}/libresip.so + +%files devel +%defattr(644,root,root,755) +%{_includedir}/rutil/*.hxx +%{_includedir}/rutil/dns/*.hxx +%{_includedir}/rutil/stun/*.hxx +%{_includedir}/resip/stack/*.hxx +%{_includedir}/resip/stack/config.hxx.in +#%{_libdir}/librutil.a +#%{_libdir}/libresip.a +%{_libdir}/libares.a +#%{_mandir}/man3/ares*gz +/usr/man/man3/ares*.gz + +%changelog +* Thu May 24 2007 Alfred E. Heggestad <aeh@db.org> - +- Initial build. + diff --git a/src/libs/resiprocate/resip/.cvsignore b/src/libs/resiprocate/resip/.cvsignore new file mode 100644 index 00000000..22f96b59 --- /dev/null +++ b/src/libs/resiprocate/resip/.cvsignore @@ -0,0 +1,19 @@ +*.ncb +*.suo +.DS_Store +.make_prefs +Makefile.in +autom4te*.cache +autoscan.log +config.log +config.status +configure.scan +lib.debug.Linux.i686 +lib.opt.Linux.i686 +lib.prof.Linux.i686 +libtool +resiprocate-old-junk +depcomp +install-sh +compile +proj diff --git a/src/libs/resiprocate/resip/COPYING b/src/libs/resiprocate/resip/COPYING new file mode 100644 index 00000000..25841bd7 --- /dev/null +++ b/src/libs/resiprocate/resip/COPYING @@ -0,0 +1,43 @@ +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/resip/README.windows b/src/libs/resiprocate/resip/README.windows new file mode 100644 index 00000000..490fbe44 --- /dev/null +++ b/src/libs/resiprocate/resip/README.windows @@ -0,0 +1,11 @@ +We've had success compiling reciprocate under Visual Studio .NET version 7.0, 7.1, and 8.0 It will not work older compilers. Here's what we did: + +1) Checked out the "sip" repository so that it became C:\sip on your machine. + +2) In Visual Studio, opened the project file C:\sip\resiprocate_X.sln + (where X matches the version of Visual Studio you are using) + +3) Start a build + + + diff --git a/src/libs/resiprocate/resip/certs/.cvsignore b/src/libs/resiprocate/resip/certs/.cvsignore new file mode 100644 index 00000000..5ebb112c --- /dev/null +++ b/src/libs/resiprocate/resip/certs/.cvsignore @@ -0,0 +1,109 @@ +. +.DS_Store +alice@a.example.com.p12 +alice@a.example.com_cert.pem +alice@a.example.com_key.pem +alice@a.example.com_req.pem +bob@b.example.com.p12 +bob@b.example.com_cert.pem +bob@b.example.com_key.pem +bob@b.example.com_req.pem +cj.cisco.sipit.net.p12 +cj.cisco.sipit.net_cert.pem +cj.cisco.sipit.net_key.pem +cj.cisco.sipit.net_req.pem +demoCA +fluffy@h0.ntt2.sipit.net.p12 +fluffy@h0.ntt2.sipit.net_cert.pem +fluffy@h0.ntt2.sipit.net_key.pem +fluffy@h0.ntt2.sipit.net_req.pem +fluffy@h1.cisco1.sipit.net.p12 +fluffy@h1.cisco1.sipit.net_cert.pem +fluffy@h1.cisco1.sipit.net_key.pem +fluffy@h1.cisco1.sipit.net_req.pem +foo.com.p12 +foo.com_cert.pem +foo.com_key.pem +foo.com_req.pem +h0.sipit.net.p12 +h0.sipit.net_cert.pem +h0.sipit.net_key.pem +h0.sipit.net_req.pem +h1.cisco1.sipit.net.p12 +h1.cisco1.sipit.net_cert.pem +h1.cisco1.sipit.net_key.pem +h1.cisco1.sipit.net_req.pem +h1.m5t.sipit.net.p12 +h1.m5t.sipit.net_cert.pem +h1.m5t.sipit.net_key.pem +h1.m5t.sipit.net_req.pem +h1.nnl1.sipit.net.p12 +h1.nnl1.sipit.net_cert.pem +h1.nnl1.sipit.net_key.pem +h1.nnl1.sipit.net_req.pem +h6.cisco.sipit.net.p12 +h6.cisco.sipit.net_cert.pem +h6.cisco.sipit.net_key.pem +h6.cisco.sipit.net_req.pem +h6.cisco3.sipit.net.p12 +h6.cisco3.sipit.net_cert.pem +h6.cisco3.sipit.net_key.pem +h6.cisco3.sipit.net_req.pem +host1.ntt.sipit.net_cert.pem +host1.ntt.sipit.net_privatekey.pem +id.pem +id_key.pem +igor.sipit.net.p12 +igor.sipit.net_cert.pem +igor.sipit.net_key.pem +igor.sipit.net_req.pem +itoh@host1.ntt.sipit.net_cert.pem +itoh@host1.ntt.sipit.net_privatekey.pem +krishna.nrc1.sipit.net.p12 +krishna.nrc1.sipit.net_cert.pem +krishna.nrc1.sipit.net_key.pem +krishna.nrc1.sipit.net_req.pem +ofra.rv2.sipit.net.p12 +ofra.rv2.sipit.net_cert.pem +ofra.rv2.sipit.net_key.pem +ofra.rv2.sipit.net_req.pem +ofra.sipit.net.p12 +ofra.sipit.net_cert.pem +ofra.sipit.net_key.pem +ofra.sipit.net_req.pem +ofra6.rv2.sipit.net.p12 +ofra6.rv2.sipit.net_cert.pem +ofra6.rv2.sipit.net_key.pem +ofra6.rv2.sipit.net_req.pem +ofra6.sipit.net.p12 +ofra6.sipit.net_cert.pem +ofra6.sipit.net_key.pem +ofra6.sipit.net_req.pem +openssl.cnf +pc.cisco.sipit.net_cert.pem +pekka.nrc1.sipit.net.p12 +pekka.nrc1.sipit.net_cert.pem +pekka.nrc1.sipit.net_key.pem +pekka.nrc1.sipit.net_req.pem +proxy.rv3.sipit.net.p12 +proxy.rv3.sipit.net_cert.pem +proxy.rv3.sipit.net_key.pem +proxy.rv3.sipit.net_req.pem +rohan@pc.cisco.sipit.net_cert.pem +root-certificate.pem +rv2.sipit.net.p12 +rv2.sipit.net_cert.pem +rv2.sipit.net_key.pem +rv2.sipit.net_req.pem +rv3.sipit.net.p12 +rv3.sipit.net_cert.pem +rv3.sipit.net_key.pem +rv3.sipit.net_req.pem +rvsipserver.rv3.sipit.net.p12 +rvsipserver.rv3.sipit.net_cert.pem +rvsipserver.rv3.sipit.net_key.pem +rvsipserver.rv3.sipit.net_req.pem +sua.rv3.sipit.net.p12 +sua.rv3.sipit.net_cert.pem +sua.rv3.sipit.net_key.pem +sua.rv3.sipit.net_req.pem diff --git a/src/libs/resiprocate/resip/certs/Notes b/src/libs/resiprocate/resip/certs/Notes new file mode 100644 index 00000000..ac8ede11 --- /dev/null +++ b/src/libs/resiprocate/resip/certs/Notes @@ -0,0 +1,95 @@ + + These scripts allow you to make certificates for test purposes. The + certificates will all share a common CA root so that everyone running + these scripts can have interoperable certificates. WARNING - these + certificates are totally insecure and are for test purposes only. All + the CA created by this script share the same private key to + facilitate interoperation testing, but this totally breaks the + security since the private key of the CA is well known. + + The instructions assume a Unix-like environment with openssl + installed, but openssl does work in Windows too. Make sure you have + openssl installed by trying to run "openssl". Run the makeCA script + found in section XXX; this creates a subdirectory called demoCA. If + the makeCA script cannot find where your openssl is installed you + will have to set an environment variable called OPENSSLDIR to + whatever directory contains the file openssl.cnf. You can find this + with a "locate openssl.cnf". You are not ready to make certificates. + + To create certs for use with TLS, run the makeCert script found in + section XXX with the fully qualified domain name of the proxy you are + making the certificate for. For example, "makeCert host.example.net". + This will generate a private key and a certificate. The private key + will be left in a file named host.example.net_key.pem in pem format. + The certificate will be in host.example.net_cert.pem. Some programs + expect both the certificate and private key combined together in a + PKCS12 format file. This is created by the script and left in a file + named host.example.net.p12. Some programs expect this file to have a + .pfx extension instead of .p12 - just rename the file if needed. + + A second argument indicating the number of days the certificate + should be valid for can be passed to the makeCert script. It is + possible to make an expired certificate using the command "makeCert + host.example.net 0". + + Anywhere that a password is used to protect a certificate, the + password is set to the string "password". + + The root certificate for the CA is in the file demoCA/cacert.pem and + a PKCS#7 version of it is in demoCA/cacert.p7c. + + For things that need DER format certificates, a certificate can be + converted from PEM to DER with "openssl x509 -in cert.pem -inform PEM + -out cert.der -outform DER". + + Some programs expect certificates in PKCS#7 format (with a file + extension of .p7c). You can convert these from PEM format with to + PKCS#7 with "openssl crl2pkcs7 -nocrl -certfile cert.pem -certfile + demoCA/cacert.pem -outform DER -out cert.p7c" + + IE, Outlook, and Netscape can import and export .p12 files and .p7c + files. You can convert a pkcs7 certificate to PEM format with + "openssl pkcs7 -in cert.p7c -inform DER -outform PEM -out cert.pem". + + The private key can be converted to pkcs8 format with "openssl pkcs8 + -in a_key.pem -topk8 -outform DER -out a_key.p8c" + + In general, a TLS client will just need the root certificate of the + CA. A TLS server will need its private key and its certificate. These + could be in two PEM files or one .p12 file. An S/MIME program will + need its private key and certificate, the root certificate of the CA, + and the certificate for every other user it communicates with. + + When validating a chain of certificates, make sure that the basic + constraints on any non leaf node allow the certificate to be used for + a CA. For example, if the domain example.com issues a certificate for + alice@example.com, alice should not be able to use this to sign a + certificate for bob@example.com. + + + +Some useful commands + +hexdump -e '"%07.7_ad " 10/1 "%_p" "\n"' + +openssl asn1parse -inform DER -in j1 -i -offset 895 + +openssl pkcs7 -inform DER -in j2 -print_certs -text -noout + +openssl pkcs7 -inform DER -in j2 -outform PEM -out j3 + + + setenv SIP ~/.sip_alice + setenv SIP ~/.sip_bob + +limp -contact sip:alice@a.example.com:5070 -aor sip:alice@a.example.com -port 5070 -to sip:bob@b.example.com -noRegister -tlsPort 0 +limp -contact sip:bob@b.example.com:5060 -aor sip:bob@b.example.com -noRegister -tlsPort 0 + +openssl base 64 -in foo -out bar -e ( or the -d to decode) + + + openssl pkcs7 -inform DER -in resip-encrpt-out -text -noout -print_certs + openssl asn1parse -inform DER -in resip-encrpt-out -i + + + dumpasn1 -l -t resip-asn-decrypt diff --git a/src/libs/resiprocate/resip/certs/Readme.txt b/src/libs/resiprocate/resip/certs/Readme.txt new file mode 100644 index 00000000..492e5122 --- /dev/null +++ b/src/libs/resiprocate/resip/certs/Readme.txt @@ -0,0 +1,69 @@ + +Working with public keys: + +You can download a public certificate from verisign in .p7c format or export it from outlook or netscape. This can be converted to a public cert with: + +openssl pkcs7 -in fluffy.p7c -inform DER -print_certs -outform PEM -out fluffy.pem + + + +Working with private keys: + +You can export a pkcs12 (.p12 or .pfx) file from outlook. This can be convered to a private key with. + +openssl pkcs12 -in fluffy.pfx -passin pass:password -passout pass:password -out id_key.pem -nocerts + +The public cert can also be extracted with +openssl pkcs12 -in fluffy.pfx -passin pass:password -out id.pem -nokeys + +The root certifcates can be extracted with +openssl pkcs12 -in fluffy.pfx -passin pass:password -out root.pem -cacerts -nokeys + + +Notes: + +To encrypt for someone ... +echo hello | openssl smime -encrypt -out foo.msg -des fluffy.pem + +To decrypt +openssl smime -decrypt -in foo.msg -inkey fluffy_key.pem -recip fluffy.pem -passin pass:password + +Sign a message +echo hello | openssl smime -sign -text -signer fluffy.pem -passin pass:password -inkey fluffy_key.pem -certfile fluffy.pem -nodetach > bar.msg + +Verify a message +openssl smime -verify -in bar.msg -signer fluffy.pem -CAfile root.pem + + +-- Generating a self signed cert and key -- +openssl genrsa -out id_key.pem 512 +openssl req -x509 -new -config extn.cnf -sha1 -key id_key.pem -days 500 -out id.pem + + +--- Generating a cert for TLS use --- +openssl req -new -out server.csr +- when asked for common name - enter domainname +- don't use abreviation for state - ie use California not CA +openssl rsa -in privkey.pem -out server.key + +This server.csr file can be used to get a free test certificate from Thawte or verisign. Put +result back form the CA in server.crt + +Can read the cert with +openssl x509 -in server.crt -text -noout + +Can read the request with +openssl req -in server.csr -text -noout + +Convert certificate in DER to PRM +openssl x509 -in root_der.crt -inform DER -out root.pem + +---- + +Dumping asn + +openssl asn1parse -inform der -i -in resip-asn-decrypt + +or + +resiprocate/test/dumpasn1 resip-encrpt-out diff --git a/src/libs/resiprocate/resip/certs/extn.cnf b/src/libs/resiprocate/resip/certs/extn.cnf new file mode 100644 index 00000000..afa5460e --- /dev/null +++ b/src/libs/resiprocate/resip/certs/extn.cnf @@ -0,0 +1,248 @@ +# +# OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +# Extra OBJECT IDENTIFIER info: +#oid_file = $ENV::HOME/.oid +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] + +# We can add new OIDs in here for use by 'ca' and 'req'. +# Add a simple OID like this: +# testoid1=1.2.3.4 +# Or use config file substitution like this: +# testoid2=${testoid1}.5.6 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = ./demoCA # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem# The private key +RANDFILE = $dir/private/.rand # private random number file + +x509_extensions = usr_cert # The extentions to add to the cert + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crl_extensions = crl_ext + +default_days = 365 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = sha1 # which md to use. +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied3Demail: +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 1024 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extentions to add to the self signed cert + +# Passwords for private keys if notopenssl req -x509 -new -key id_key.pem -days 180 -out id.pem -config extn.cnf present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString. +# utf8only: only UTF8Strings. +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings +# so use this option with caution! +string_mask = nombstr + +req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = California + +localityName = Locality Name (eg, city) +localityName_default = San Jose + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = sipit.net + +# we can do this but it is not needed normally :-) +#1.organizationName = Second Organization Name (eg, company) +#1.organizationName_default = World Wide Web Pty Ltd + +#organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = + +commonName = Common Name (eg, YOUR name) +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 40 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +unstructuredName = An optional company name + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer:always + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] + + +# Extensions for a typical CA + + +# PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer:always + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. However since it will +# prevent it being used as an test self-signed certificate it is best +# left out by default. +# keyUsage = cRLSign, keyCertSign + +# Some might want this also +# nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +#subjectAltName=email:copy +#subjectAltName=URI:sip:fluffy.proxy.com +#subjectAltName=URI:copy +subjectAltName=email:fluffy@foo.com +# Copy issuer details +# issuerAltName=issuer:copy + +# DER hex encoding of an extension: beware experts only! +# obj=DER:02:03 +# Where 'obj' is a standard or added object +# You can even override a supported extension: +# basicConstraints= critical, DER:30:03:01:01:FF + +[ crl_ext ] + +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always,issuer:always diff --git a/src/libs/resiprocate/resip/certs/hosts.txt b/src/libs/resiprocate/resip/certs/hosts.txt new file mode 100644 index 00000000..720c1671 --- /dev/null +++ b/src/libs/resiprocate/resip/certs/hosts.txt @@ -0,0 +1,7 @@ +h1.esta.sipit.net +h2.esta.sipit.net +h3.esta.sipit.net +h4.esta.sipit.net +h1.sipez.sipit.net +h2.sipez.sipit.net +h3.sipez.sipit.net diff --git a/src/libs/resiprocate/resip/certs/makeAll b/src/libs/resiprocate/resip/certs/makeAll new file mode 100644 index 00000000..c705b25d --- /dev/null +++ b/src/libs/resiprocate/resip/certs/makeAll @@ -0,0 +1,9 @@ +#!/bin/csh + +foreach nm ( ` cat hosts.txt ` ) + echo $nm + ./makeCert $nm +end + +tar cvfz allCerts.tgz domain*pem *.p12 + diff --git a/src/libs/resiprocate/resip/certs/makeCA b/src/libs/resiprocate/resip/certs/makeCA new file mode 100644 index 00000000..fe6b1245 --- /dev/null +++ b/src/libs/resiprocate/resip/certs/makeCA @@ -0,0 +1,108 @@ +#!/bin/sh +#set -x + +rm -rf demoCA + +mkdir demoCA +mkdir demoCA/certs +mkdir demoCA/crl +mkdir demoCA/newcerts +mkdir demoCA/private +echo "01" > demoCA/serial +hexdump -n 4 -e '4/1 "%04u"' /dev/random > demoCA/serial +touch demoCA/index.txt + +# You may need to modify this for where your default file is +# you can find where yours in by typing "openssl ca" +for D in $OPENSSLDIR /etc/ssl /usr/local/ssl /sw/etc/ssl /sw/share/ssl /System/Library/OpenSSL /opt/local/etc/openssl; do + CONF=$D/openssl.cnf + [ -f ${CONF} ] && break +done + +if [ ! -f $CONF ]; then + echo "Can not find file $CONF - set your OPENSSLDIR variable" + exit +fi +cp $CONF openssl.cnf + +cat >> openssl.cnf <<EOF +[ cj_cert ] +subjectAltName=\${ENV::ALTNAME} +basicConstraints=CA:FALSE +subjectKeyIdentifier=hash +#authorityKeyIdentifier=keyid,issuer:always + +[ cj_req ] +basicConstraints = CA:FALSE +subjectAltName=\${ENV::ALTNAME} +subjectKeyIdentifier=hash +#authorityKeyIdentifier=keyid,issuer:always +#keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +EOF + +cat > demoCA/private/cakey.pem <<EOF +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,4B47A0A73ADE342E + +aHmlPa+ZrOV6v+Jk0SClxzpxoG3j0ZuyoVkF9rzq2bZkzVBKLU6xhWwjMDqwA8dH +3fCRLhMGIUVnmymXYhTW9svI1gpFxMBQHJcKpV/SmgFn/fbYk98Smo2izHOniIiu +NOu2zr+bMiaBphOAZ/OCtVUxUOoBDKN9lR39UCDOgkEQzp9Vbw7l736yu5H9GMHP +JtGLJyx3RhS3TvLfLAJZhjm/wZ/9QM8GjyJEiDhMQRJVeIZGvv4Yr1u6yYHiHfjX +tX2eds8Luc83HbSvjAyjnkLtJsAZ/8cFzrd7pjFzbogLdWuil+kpkkf5h1uzh7oa +um0M1EXBE4tcDHsfg1iqEsDMIei/U+/rWfk1PrzYlklwZp8S03vulkDm1fT76W7d +mRBg4+CrHA6qYn6EPWB37OBtfEqAfINnIcI1dWzso9A0bTPD4EJO0JA0PcZ/2JgT +PaKySgooHQ8AHNQebelch6M5LFExpaOADJKrqauKcc2HeUxXaYIpac5/7drIl3io +UloqUnMlGa3eLP7BZIMsZKCfHZ8oqwU4g6mmmJath2gODRDx3mfhH6yaimDL7v4i +SAIIkrEHXfSyovrTJymfSfQtYxUraVZDqax6oj/eGllRxliGfMLYG9ceU+yU/8FN +LE7P+Cs19H5tHHzx1LlieaK43u/XvbXHlB5mqL/fZdkUIBJsjbBVx0HR8eQl2CH9 +YJDMOPLADecwHoyKA0AY59oN9d41oF7yZtN9KwNdslROYH7mNJlqMMenhXCLN+Nz +vVU5/7/ugZFhZqfS46c1WdmSvuqpDp7TBtMeaH/PXjysBr0iZffOxQ== +-----END RSA PRIVATE KEY----- +EOF + +cat > demoCA/cacert.pem <<EOF +-----BEGIN CERTIFICATE----- +MIIDJDCCAo2gAwIBAgIBADANBgkqhkiG9w0BAQUFADBwMQswCQYDVQQGEwJVUzET +MBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2UxDjAMBgNVBAoT +BXNpcGl0MSkwJwYDVQQLEyBTaXBpdCBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0 +eTAeFw0wMzA3MTgxMjIxNTJaFw0xMzA3MTUxMjIxNTJaMHAxCzAJBgNVBAYTAlVT +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9zZTEOMAwGA1UE +ChMFc2lwaXQxKTAnBgNVBAsTIFNpcGl0IFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9y +aXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDIh6DkcUDLDyK9BEUxkud ++nJ4xrCVGKfgjHm6XaSuHiEtnfELHM+9WymzkBNzZpJu30yzsxwfKoIKugdNUrD4 +N3viCicwcN35LgP/KnbN34cavXHr4ZlqxH+OdKB3hQTpQa38A7YXdaoz6goW2ft5 +Mi74z03GNKP/G9BoKOGd5QIDAQABo4HNMIHKMB0GA1UdDgQWBBRrRhcU6pR2JYBU +bhNU2qHjVBShtjCBmgYDVR0jBIGSMIGPgBRrRhcU6pR2JYBUbhNU2qHjVBShtqF0 +pHIwcDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcT +CFNhbiBKb3NlMQ4wDAYDVQQKEwVzaXBpdDEpMCcGA1UECxMgU2lwaXQgVGVzdCBD +ZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B +AQUFAAOBgQCWbRvv1ZGTRXxbH8/EqkdSCzSoUPrs+rQqR0xdQac9wNY/nlZbkR3O +qAezG6Sfmklvf+DOg5RxQq/+Y6I03LRepc7KeVDpaplMFGnpfKsibETMipwzayNQ +QgUf4cKBiF+65Ue7hZuDJa2EMv8qW4twEhGDYclpFU9YozyS1OhvUg== +-----END CERTIFICATE----- +EOF + + +# uncomment the following lines to generate your own key pair + +#openssl req -newkey rsa:1024 -passin pass:password \ +# -passout pass:password \ +# -sha1 -x509 -keyout demoCA/private/cakey.pem \ +# -out demoCA/cacert.pem -days 3650 <<EOF +#US +#California +#San Jose +#sipit +#Sipit Test Certificate Authority +# +# +#EOF + +openssl crl2pkcs7 -nocrl -certfile demoCA/cacert.pem \ + -outform DER -out demoCA/cacert.p7c + +cp demoCA/cacert.pem root_cert_fluffyCA.pem + + diff --git a/src/libs/resiprocate/resip/certs/makeCert b/src/libs/resiprocate/resip/certs/makeCert new file mode 100644 index 00000000..2a9704b5 --- /dev/null +++ b/src/libs/resiprocate/resip/certs/makeCert @@ -0,0 +1,79 @@ +#!/bin/sh +#set -x + +if [ $# == 1 ]; then + DAYS=1095 +elif [ $# == 2 ]; then + DAYS=$2 +else + echo "Usage: makeCert test.example.org [days]" + echo " makeCert alice@example.org [days]" + echo "days is how long the certificate is valid" + echo "days set to 0 generates an invalid certificate" + exit 0 +fi + +DOMAIN=`echo $1 | perl -ne '{print "$1\n" if (/\.(.*)$/)}' ` +ADDR=$1 + +echo "making cert for ${DOMAIN} ${ADDR}" + +rm -f ${ADDR}_*.pem +rm -f ${ADDR}.p12 + +case ${ADDR} in +*:*) ALTNAME="URI:${ADDR}" ;; +*@*) ALTNAME="URI:sip:${ADDR},URI:im:${ADDR},URI:pres:${ADDR}" ;; +*) ALTNAME="DNS:${DOMAIN},DNS:${ADDR},URI:sip:${ADDR}" ;; +esac + +#ALTNAME="URI:sip:pekka.nrc.sipit.net,URI:sip:nrc.sipit.net" + +rm -f demoCA/index.txt +touch demoCA/index.txt +rm -f demoCA/newcerts/* + +export ALTNAME + +openssl genrsa -out ${ADDR}_key.pem 2048 +openssl req -new -config openssl.cnf -reqexts cj_req \ + -sha1 -key ${ADDR}_key.pem \ + -out ${ADDR}.csr -days ${DAYS} <<EOF +US +California +San Jose +sipit + +${ADDR} + + + +EOF + +if [ $DAYS == 0 ]; then +openssl ca -extensions cj_cert -config openssl.cnf \ + -passin pass:password -policy policy_anything \ + -md sha1 -batch -notext -out ${ADDR}_cert.pem \ + -startdate 990101000000Z \ + -enddate 000101000000Z \ + -infiles ${ADDR}.csr +else +openssl ca -extensions cj_cert -config openssl.cnf \ + -passin pass:password -policy policy_anything \ + -md sha1 -days ${DAYS} -batch -notext -out ${ADDR}_cert.pem \ + -infiles ${ADDR}.csr +fi + +openssl pkcs12 -passin pass:password \ + -passout pass:password -export \ + -out ${ADDR}.p12 -in ${ADDR}_cert.pem \ + -inkey ${ADDR}_key.pem -name ${ADDR} -certfile demoCA/cacert.pem + +openssl x509 -in ${ADDR}_cert.pem -noout -text + +case ${ADDR} in +*@*) mv ${ADDR}_key.pem user_key_${ADDR}.pem; \ + mv ${ADDR}_cert.pem user_cert_${ADDR}.pem ;; +*) mv ${ADDR}_key.pem domain_key_${ADDR}.pem; \ + mv ${ADDR}_cert.pem domain_cert_${ADDR}.pem ;; +esac diff --git a/src/libs/resiprocate/resip/dum/.cvsignore b/src/libs/resiprocate/resip/dum/.cvsignore new file mode 100644 index 00000000..6022eea7 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/.cvsignore @@ -0,0 +1,13 @@ +.dependlibs +bin.debug.Darwin.ppc +bin.debug.Linux.i686 +html +obj.* +bin.* +.gdb_history +Makefile.in +Release +Debug +SSL-Release +SSL-Debug +*.user \ No newline at end of file diff --git a/src/libs/resiprocate/resip/dum/AppDialog.cxx b/src/libs/resiprocate/resip/dum/AppDialog.cxx new file mode 100644 index 00000000..63ddb450 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/AppDialog.cxx @@ -0,0 +1,122 @@ +#include "resip/dum/Dialog.hxx" +#include "resip/dum/AppDialog.hxx" + +using namespace resip; +using namespace std; + +AppDialog::AppDialog(HandleManager& ham) : + Handled(ham), + mDialog(0) +{ +} + +AppDialog::~AppDialog() +{ +} + +AppDialogHandle +AppDialog::getHandle() +{ + return AppDialogHandle(mHam, mId); +} + +vector<ClientSubscriptionHandle> +AppDialog::getClientSubscriptions() +{ + return mDialog->getClientSubscriptions(); +} + +vector<ClientSubscriptionHandle> +AppDialog::findClientSubscriptions(const Data& event) +{ + return mDialog->findClientSubscriptions(event); +} + +vector<ServerSubscriptionHandle> +AppDialog::getServerSubscriptions() +{ + return mDialog->getServerSubscriptions(); +} + + +vector<ServerSubscriptionHandle> +AppDialog::findServerSubscriptions(const Data& event) +{ + return mDialog->findServerSubscriptions(event); +} + +InviteSessionHandle +AppDialog::getInviteSession() +{ + return mDialog->getInviteSession(); +} + +DialogId +AppDialog::getDialogId() const +{ + return mDialog->getId(); +} + +NameAddr& +AppDialog::getContact() +{ + return mDialog->mLocalContact; +} + +EncodeStream& +AppDialog::dump(EncodeStream& strm) const +{ + strm << "AppDialog " << mId; + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/dum/AppDialog.hxx b/src/libs/resiprocate/resip/dum/AppDialog.hxx new file mode 100644 index 00000000..934bef43 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/AppDialog.hxx @@ -0,0 +1,102 @@ +#if !defined(RESIP_APPDIALOG_HXX) +#define RESIP_APPDIALOG_HXX + +#include "resip/dum/Handles.hxx" +#include "resip/dum/Handled.hxx" +#include "resip/dum/DialogId.hxx" + + +#include <vector> + +namespace resip +{ + +class HandleManager; +class Dialog; +class Data; +class NameAddr; + +class AppDialog : public Handled +{ + public: + AppDialog(HandleManager& ham); + virtual ~AppDialog(); + + AppDialogHandle getHandle(); + DialogId getDialogId() const; + + //?dcm? -- further evidence that this should possbily be a dialog + //subclass(cancel gets tricky). List vs vector?(here and in Dialog) + std::vector<ClientSubscriptionHandle> getClientSubscriptions(); + std::vector<ClientSubscriptionHandle> findClientSubscriptions(const Data& event); + + std::vector<ServerSubscriptionHandle> getServerSubscriptions(); + std::vector<ServerSubscriptionHandle> findServerSubscriptions(const Data& event); + + //returns an invalid handle if there is no session + InviteSessionHandle getInviteSession(); + + // !dlb! less hacked approach to SUBSCRIBE contact issue + // modify contact only onNew + NameAddr& getContact(); + + virtual EncodeStream& dump(EncodeStream& strm) const; + + private: + friend class DialogSet; + Dialog* mDialog; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/AppDialogSet.cxx b/src/libs/resiprocate/resip/dum/AppDialogSet.cxx new file mode 100644 index 00000000..2079e4bb --- /dev/null +++ b/src/libs/resiprocate/resip/dum/AppDialogSet.cxx @@ -0,0 +1,164 @@ +#include "resip/dum/AppDialogSet.hxx" +#include "resip/dum/AppDialog.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +AppDialogSet::AppDialogSet(DialogUsageManager& dum) : + Handled(dum), + mDum(dum), + mDialogSet(0), + mIsReUsed(false) +{} + +AppDialogSet::~AppDialogSet() +{} + +AppDialogSetHandle +AppDialogSet::getHandle() +{ + return AppDialogSetHandle(mHam, mId); +} + +void +AppDialogSet::destroy() +{ + delete this; +} + +void +AppDialogSet::end() +{ + if (mDialogSet) + { + mDialogSet->end(); + } +} + +void +AppDialogSet::endCommand() +{ + AppDialogSetHandle handle = getHandle(); + mDum.post(new AppDialogSetEndCommand(handle)); +} + +SharedPtr<UserProfile> +AppDialogSet::selectUASUserProfile(const SipMessage&) +{ + // Default is Master Profile - override this method to select a different userProfile for UAS DialogSets + return mDum.getMasterUserProfile(); +} + +SharedPtr<UserProfile> +AppDialogSet::getUserProfile() +{ + if(mDialogSet) + { + return mDialogSet->getUserProfile(); + } + else + { + return SharedPtr<UserProfile>(); + } +} + +AppDialog* +AppDialogSet::createAppDialog(const SipMessage&) +{ + return new AppDialog(mDum); +} + +DialogSetId +AppDialogSet::getDialogSetId() +{ + if (mDialogSet) + { + return mDialogSet->getId(); + } + else + { + return DialogSetId(Data::Empty, Data::Empty); + } +} + +AppDialogSet* +AppDialogSet::reuse() +{ + assert(mDialogSet); + mDialogSet->appDissociate(); + mDialogSet = 0; + + mIsReUsed = true; + return this; +} + +bool +AppDialogSet::isReUsed() const +{ + return mIsReUsed; +} + +const Data +AppDialogSet::getClassName() +{ + return "AppDialogSet"; +} + +EncodeStream& +AppDialogSet::dump(EncodeStream& strm) const +{ + strm << "AppDialogSet " << mId; + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/AppDialogSet.hxx b/src/libs/resiprocate/resip/dum/AppDialogSet.hxx new file mode 100644 index 00000000..33a97e1f --- /dev/null +++ b/src/libs/resiprocate/resip/dum/AppDialogSet.hxx @@ -0,0 +1,143 @@ +#if !defined(RESIP_APPDIALOGSET_HXX) +#define RESIP_APPDIALOGSET_HXX + +#include "resip/dum/Handles.hxx" +#include "resip/dum/Handled.hxx" +#include "resip/dum/DialogSet.hxx" +#include "resip/dum/DialogSetId.hxx" +#include "resip/dum/UserProfile.hxx" +#include "resip/dum/DumCommand.hxx" + +namespace resip +{ + +class SipMessage; +class DialogUsageManager; + +class AppDialogSet : public Handled +{ + public: + + // by default, dum calls the destructor. application can override this if it + // wants to manage memory on its own. + virtual void destroy(); + + virtual void end(); + + // Asynchronously calls end() through a DUM command + virtual void endCommand(); + + virtual SharedPtr<UserProfile> getUserProfile(); + + virtual AppDialog* createAppDialog(const SipMessage&); + + AppDialogSetHandle getHandle(); + DialogSetId getDialogSetId(); + + virtual const Data getClassName(); + + virtual EncodeStream& dump(EncodeStream& strm) const; + + protected: + + class AppDialogSetEndCommand : public DumCommandAdapter + { + public: + AppDialogSetEndCommand(const AppDialogSetHandle& dialogSet) + : mAppDialogSet(dialogSet) + { + } + + virtual void executeCommand() + { + if(mAppDialogSet.isValid()) + { + mAppDialogSet->end(); + } + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "AppDialogSetEndCommand"; + } + private: + AppDialogSetHandle mAppDialogSet; + }; + + AppDialogSet(DialogUsageManager& dum); + + DialogUsageManager& mDum; + virtual ~AppDialogSet(); + // This is called by the DialogUsageManager to select an userProfile to assign to a UAS DialogSet. + // The application should not call this directly, but should override it, in order to assign + // an userProfile other than the MasterProfile + virtual SharedPtr<UserProfile> selectUASUserProfile(const SipMessage&); + + private: + /// Prepare for association with a different dialog set id. Need this + /// when the initial message changes (408/Retry-After) but the application + /// doesn't want to know. + AppDialogSet* reuse(); + bool isReUsed() const; + + friend class DialogUsageManager; + friend class AppDialogSetFactory; + friend class ClientSubscription; + + DialogSet* mDialogSet; + bool mIsReUsed; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/AppDialogSetFactory.cxx b/src/libs/resiprocate/resip/dum/AppDialogSetFactory.cxx new file mode 100644 index 00000000..0331ba85 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/AppDialogSetFactory.cxx @@ -0,0 +1,65 @@ +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/AppDialogSetFactory.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/AppDialogSet.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +AppDialogSet* +AppDialogSetFactory::createAppDialogSet(DialogUsageManager& dum, const SipMessage&) +{ + //!dcm! -- inefficient, but state may creep in and the handles add trickyness + return new AppDialogSet(dum); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/AppDialogSetFactory.hxx b/src/libs/resiprocate/resip/dum/AppDialogSetFactory.hxx new file mode 100644 index 00000000..b11a07da --- /dev/null +++ b/src/libs/resiprocate/resip/dum/AppDialogSetFactory.hxx @@ -0,0 +1,71 @@ +#if !defined(RESIP_APPDIALOGSETFACTORY_HXX) +#define RESIP_APPDIALOGSETFACTORY_HXX + + +namespace resip +{ + +class AppDialogSet; +class DialogUsageManager; +class SipMessage; + +class AppDialogSetFactory +{ + public: + virtual AppDialogSet* createAppDialogSet(DialogUsageManager&, const SipMessage&); + virtual ~AppDialogSetFactory() {} +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/BaseCreator.cxx b/src/libs/resiprocate/resip/dum/BaseCreator.cxx new file mode 100644 index 00000000..e133744d --- /dev/null +++ b/src/libs/resiprocate/resip/dum/BaseCreator.cxx @@ -0,0 +1,219 @@ +#include "rutil/Logger.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/BaseCreator.hxx" +#include "resip/dum/DumHelper.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +BaseCreator::BaseCreator(DialogUsageManager& dum, + const SharedPtr<UserProfile>& userProfile) + : mLastRequest(new SipMessage), + mDum(dum), + mUserProfile(userProfile) +{} + +BaseCreator::~BaseCreator() +{} + +SharedPtr<SipMessage> +BaseCreator::getLastRequest() +{ + return mLastRequest; +} + +/* +const SipMessage& +BaseCreator::getLastRequest() const +{ + return mLastRequest; +} +*/ + +SharedPtr<UserProfile> +BaseCreator::getUserProfile() +{ + return mUserProfile; +} + +void +BaseCreator::makeInitialRequest(const NameAddr& target, MethodTypes method) +{ + assert(mUserProfile.get()); + makeInitialRequest(target, mUserProfile->getDefaultFrom(), method); +} + + +void +BaseCreator::makeInitialRequest(const NameAddr& target, const NameAddr& from, MethodTypes method) +{ + RequestLine rLine(method); + rLine.uri() = target.uri(); + mLastRequest->header(h_RequestLine) = rLine; + + mLastRequest->header(h_To) = target; + mLastRequest->header(h_MaxForwards).value() = 70; + mLastRequest->header(h_CSeq).method() = method; + mLastRequest->header(h_CSeq).sequence() = 1; + mLastRequest->header(h_From) = from; + mLastRequest->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); + mLastRequest->header(h_CallId).value() = Helper::computeCallId(); + + assert(mUserProfile.get()); + if (!mUserProfile->getImsAuthUserName().empty()) + { + Auth auth; + auth.scheme() = Symbols::Digest; + auth.param(p_username) = mUserProfile->getImsAuthUserName(); + auth.param(p_realm) = mUserProfile->getImsAuthHost(); + auth.param(p_uri) = "sip:" + mUserProfile->getImsAuthHost(); + auth.param(p_nonce) = Data::Empty; + auth.param(p_response) = Data::Empty; + mLastRequest->header(h_Authorizations).push_back(auth); + DebugLog ( << "Adding auth header to inital reg for IMS: " << auth); + } + + NameAddr contact; // if no GRUU, let the stack fill in the contact + + if(mUserProfile->hasUserAgentCapabilities()) + { + contact = mUserProfile->getUserAgentCapabilities(); + } + + //.dcm. If we want to use userprofiles oacross multiple registration we will + //need the lookup-rtype hasGruu methods + //if (mUserProfile->hasGruu(target.uri().getAor())) + //?dcm? handle selction of anon vs pub gruu in profile? + //if (mUserProfile->hasGruu(target.uri().getAor())) + //!dcm! - clunky, have userprofile provide appropriate gruu or contact... + if (!mUserProfile->isAnonymous() && mUserProfile->hasPublicGruu() && method != REGISTER) //why not use GRUU for publish/etc? + { + contact.uri() = mUserProfile->getPublicGruu(); + mLastRequest->header(h_Contacts).push_front(contact); + } + else if(mUserProfile->isAnonymous() && mUserProfile->hasTempGruu() && method != REGISTER) + { + contact.uri() = mUserProfile->getTempGruu(); + mLastRequest->header(h_Contacts).push_front(contact); + } + else + { + if (mUserProfile->hasOverrideHostAndPort()) + { + contact.uri() = mUserProfile->getOverrideHostAndPort(); + } + contact.uri().user() = from.uri().user(); + + // .jjg. there isn't anything in the outbound [11] draft that says we + // aren't allowed to include p_Instance in this case... + // odds are it will be useful (or necessary) for some implementations + const Data& instanceId = mUserProfile->getInstanceId(); + if (!contact.uri().exists(p_gr) && !instanceId.empty()) + { + contact.param(p_Instance) = instanceId; + } + mLastRequest->header(h_Contacts).push_front(contact); + + if (method != REGISTER) + { + const NameAddrs& sRoute = mUserProfile->getServiceRoute(); + if (!sRoute.empty()) + { + mLastRequest->header(h_Routes) = sRoute; + } + } + } + + if(mUserProfile->clientOutboundEnabled() && method != REGISTER) + { + // Add ;ob parm to non-register requests - RFC5626 pg17 + mLastRequest->header(h_Contacts).front().uri().param(p_ob); + } + + Via via; + mLastRequest->header(h_Vias).push_front(via); + + if(mUserProfile->isAdvertisedCapability(Headers::Allow)) + { + mLastRequest->header(h_Allows) = mDum.getMasterProfile()->getAllowedMethods(); + } + if(mUserProfile->isAdvertisedCapability(Headers::AcceptEncoding)) + { + mLastRequest->header(h_AcceptEncodings) = mDum.getMasterProfile()->getSupportedEncodings(); + } + if(mUserProfile->isAdvertisedCapability(Headers::AcceptLanguage)) + { + mLastRequest->header(h_AcceptLanguages) = mDum.getMasterProfile()->getSupportedLanguages(); + } + if(mUserProfile->isAdvertisedCapability(Headers::AllowEvents)) + { + mLastRequest->header(h_AllowEvents) = mDum.getMasterProfile()->getAllowedEvents(); + } + if(mUserProfile->isAdvertisedCapability(Headers::Supported)) + { + mLastRequest->header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags(); + } + + // Merge Embedded parameters + mLastRequest->mergeUri(target.uri()); + + //DumHelper::setOutgoingEncryptionLevel(mLastRequest, mEncryptionLevel); + + DebugLog ( << "BaseCreator::makeInitialRequest: " << std::endl << std::endl << mLastRequest); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/dum/BaseCreator.hxx b/src/libs/resiprocate/resip/dum/BaseCreator.hxx new file mode 100644 index 00000000..82b8adea --- /dev/null +++ b/src/libs/resiprocate/resip/dum/BaseCreator.hxx @@ -0,0 +1,85 @@ +#if !defined(RESIP_BASECREATOR_HXX) +#define RESIP_BASECREATOR_HXX + +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/UserProfile.hxx" +#include "resip/dum/DialogUsageManager.hxx" + +namespace resip +{ + +class DialogUsageManager; + +class BaseCreator +{ + public: + BaseCreator(DialogUsageManager& dum, const SharedPtr<UserProfile>& userProfile); + virtual ~BaseCreator(); + SharedPtr<SipMessage> getLastRequest(); + SharedPtr<UserProfile> getUserProfile(); + //const SipMessage& getLastRequest() const; + + protected: + void makeInitialRequest(const NameAddr& target, MethodTypes method); + void makeInitialRequest(const NameAddr& target, const NameAddr& from, MethodTypes method); + + // this will get updated when an initial request is challenged. where we + // store the credentials and last cseq + SharedPtr<SipMessage> mLastRequest; + DialogUsageManager& mDum; + SharedPtr<UserProfile> mUserProfile; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/BaseSubscription.cxx b/src/libs/resiprocate/resip/dum/BaseSubscription.cxx new file mode 100644 index 00000000..79c3aa97 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/BaseSubscription.cxx @@ -0,0 +1,121 @@ +#include "resip/dum/BaseSubscription.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +BaseSubscription::BaseSubscription(DialogUsageManager& dum, Dialog& dialog, const SipMessage& request) : + DialogUsage(dum, dialog), + mSubDlgState(SubDlgInitial), + mLastRequest(new SipMessage), + mLastResponse(new SipMessage), + mDocumentKey(request.header(h_RequestLine).uri().getAor()), + mSubscriptionId(Data::Empty), + mTimerSeq(0), + mSubscriptionState(Invalid) + +{ + if (request.exists(h_Event)) + { + mEventType = request.header(h_Event).value(); + if (request.header(h_Event).exists(p_id)) + { + mSubscriptionId = request.header(h_Event).param(p_id); + } + mLastRequest->header(h_Event) = request.header(h_Event); + } + else if (request.header(h_RequestLine).method() == REFER + || request.header(h_RequestLine).method() == NOTIFY) + { + mEventType = "refer"; + mLastRequest->header(h_Event).value() = mEventType; + } +} + +bool +BaseSubscription::matches(const SipMessage& msg) +{ + if (msg.isResponse() && msg.header(h_CSeq) == mLastRequest->header(h_CSeq)) + { + return true; + } + else + { + if (msg.exists(h_Event)) + { + return msg.header(h_Event).value() == mEventType + && ( !msg.header(h_Event).exists(p_id) || + msg.header(h_Event).param(p_id) == mSubscriptionId); + + } + else + { + return (mEventType == "refer" && + Data(msg.header(h_CSeq).sequence()) == mSubscriptionId); + } + } +} + + +BaseSubscription::~BaseSubscription() +{ +} + +SubscriptionState +BaseSubscription::getSubscriptionState() +{ + return mSubscriptionState; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/BaseSubscription.hxx b/src/libs/resiprocate/resip/dum/BaseSubscription.hxx new file mode 100644 index 00000000..88b963f4 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/BaseSubscription.hxx @@ -0,0 +1,110 @@ +#if !defined(RESIP_BASESUBSCRIPTION_HXX) +#define RESIP_BASESUBSCRIPTION_HXX + +#include "resip/dum/DialogUsage.hxx" +#include "resip/dum/SubscriptionState.hxx" +#include "resip/stack/SipMessage.hxx" + +namespace resip +{ + +class DialogUsageManager; + +//!dcm! -- update contact in dialog if required + +class BaseSubscription: public DialogUsage +{ + public: + bool matches(const SipMessage& subOrNotify); + const Data& getDocumentKey() const { return mDocumentKey; } + const Data& getEventType() const { return mEventType; } + const Data& getId() const { return mSubscriptionId; } + + protected: + friend class Dialog; + + enum SubDlgState + { + SubDlgInitial, + SubDlgEstablished, + SubDlgTerminating + }; + + // state of the dialog that carries the subscription + // this is similar to the DialogSet::State, but different + // set of states + SubDlgState mSubDlgState; + + BaseSubscription(DialogUsageManager& dum, Dialog& dialog, const SipMessage& request); + + SubscriptionState getSubscriptionState(); + + virtual ~BaseSubscription(); + + SharedPtr<SipMessage> mLastRequest; + SharedPtr<SipMessage> mLastResponse; + + Data mDocumentKey; + Data mEventType; + Data mSubscriptionId; + unsigned int mTimerSeq; + SubscriptionState mSubscriptionState; + + // disabled + BaseSubscription(const BaseSubscription&); + BaseSubscription& operator=(const BaseSubscription&); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/BaseUsage.cxx b/src/libs/resiprocate/resip/dum/BaseUsage.cxx new file mode 100644 index 00000000..8311c7f1 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/BaseUsage.cxx @@ -0,0 +1,100 @@ +#include "resip/dum/AppDialog.hxx" +#include "resip/dum/AppDialogSet.hxx" +#include "resip/dum/BaseUsage.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/DialogSet.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +BaseUsage::Exception::Exception(const Data& msg,const Data& file,int line) + : BaseException(msg, file, line) +{ +} + +const char* +BaseUsage::Exception::name() const +{ + return "BaseUsage::Exception"; +} + +BaseUsage::BaseUsage(DialogUsageManager& dum) : + Handled(dum), + mDum(dum), + mHandle(dum, mId) +{ +} + +BaseUsage::~BaseUsage() +{ +} + +BaseUsageHandle +BaseUsage::getBaseHandle() +{ + return mHandle; +} + +#if 0 +EncodeStream& +BaseUsage::dump(EncodeStream& strm) const +{ + strm << "BaseUsage: " << mId; + return strm; +} +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/BaseUsage.hxx b/src/libs/resiprocate/resip/dum/BaseUsage.hxx new file mode 100644 index 00000000..38a7ea52 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/BaseUsage.hxx @@ -0,0 +1,99 @@ +#if !defined(RESIP_BASEUSAGE_HXX) +#define RESIP_BASEUSAGE_HXX + +#include "rutil/BaseException.hxx" +#include "resip/dum/Handled.hxx" +#include "resip/dum/Handles.hxx" + +namespace resip +{ + +class DialogUsageManager; +class Dialog; +class DumTimeout; +class SipMessage; +class NameAddr; + +class BaseUsage : public Handled +{ + public: + class Exception : public BaseException + { + public: + Exception(const Data& msg,const Data& file,int line); + virtual const char* name() const; + }; + + virtual void end()=0; + virtual EncodeStream& dump(EncodeStream& strm) const=0; + + protected: + BaseUsage(DialogUsageManager& dum); + virtual ~BaseUsage(); + + virtual void dispatch(const SipMessage& msg) = 0; + virtual void dispatch(const DumTimeout& timer) = 0; + + BaseUsageHandle getBaseHandle(); + + DialogUsageManager& mDum; + private: + BaseUsageHandle mHandle; + + friend class DestroyUsage; + friend class DialogUsageManager; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/CertMessage.cxx b/src/libs/resiprocate/resip/dum/CertMessage.cxx new file mode 100644 index 00000000..9d767a13 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/CertMessage.cxx @@ -0,0 +1,91 @@ +#include <ostream> +#include "rutil/Data.hxx" +#include "resip/dum/CertMessage.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +CertMessage::CertMessage(const MessageId& id, + bool success, + const Data& body) + : mId(id), + mSuccess(success), + mBody(body) +{ +} + +EncodeStream& +CertMessage::encodeBrief(EncodeStream& str) const +{ + return str << "CertMessage: " << mId; +} + +EncodeStream& +CertMessage::encode(EncodeStream& strm) const +{ + return strm << brief() << "body: " << mBody; +} + +Message* +CertMessage::clone() const +{ + return new CertMessage(mId, mSuccess, mBody); +} + +EncodeStream& resip::operator<<(EncodeStream& strm, const MessageId& id) +{ + strm << endl; + strm << "Id: " << id.mId << "Aor :" << id.mAor << "Type: " << ((id.mType==MessageId::UserCert)? "Cert" : "Private Key") << endl; + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/CertMessage.hxx b/src/libs/resiprocate/resip/dum/CertMessage.hxx new file mode 100644 index 00000000..ecaa8993 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/CertMessage.hxx @@ -0,0 +1,92 @@ +#ifndef RESIP_CertMessage_hxx +#define RESIP_CertMessage_hxx + +#include "resip/stack/Message.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +class MessageId +{ + public: + typedef enum + { + UserCert, + UserPrivateKey + } Type; + + MessageId(const Data& id, const Data& aor, Type type) : mId(id), mAor(aor), mType(type) {} + friend EncodeStream& operator<<(EncodeStream& strm, const MessageId& id); + Data mId; + Data mAor; + Type mType; +}; + +class CertMessage : public Message +{ + public: + CertMessage(const MessageId& id, bool success, const Data& body); + bool success() const { return mSuccess; } + const Data& body() const { return mBody; } + const MessageId& id() const { return mId; } + virtual Message* clone() const; + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + MessageId mId; + bool mSuccess; + Data mBody; +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ChallengeInfo.cxx b/src/libs/resiprocate/resip/dum/ChallengeInfo.cxx new file mode 100644 index 00000000..39c737d8 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ChallengeInfo.cxx @@ -0,0 +1,123 @@ + +#include <cassert> + +#include "resip/dum/ChallengeInfo.hxx" +#include "rutil/Data.hxx" +#include "rutil/Logger.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + + +ChallengeInfo::ChallengeInfo( bool failed, + bool challengeRequired, + const Data& transactionId ): + DumFeatureMessage(transactionId), + mFailed(failed), + mChallengeRequired(challengeRequired) +{ +} + +ChallengeInfo::~ChallengeInfo() +{ +} + +bool +ChallengeInfo::isFailed() const +{ + return mFailed; +} + +bool +ChallengeInfo::isChallengeRequired() const +{ + return mChallengeRequired; +} + +Data +ChallengeInfo::brief() const +{ + Data buffer; + DataStream strm(buffer); + strm << "ChallengeInfo " << mFailed << " : " << mChallengeRequired; + strm.flush(); + return buffer; +} + +resip::Message* +ChallengeInfo::clone() const +{ + assert(false); return NULL; +} + +std::ostream& +ChallengeInfo::encode(std::ostream& strm) const +{ + strm << brief(); + return strm; +} + +std::ostream& +ChallengeInfo::encodeBrief(std::ostream& strm) const +{ + return encode(strm); +} + +std::ostream& +resip::operator<<(std::ostream& strm, const ChallengeInfo& msg) +{ + return msg.encode(strm); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/dum/ChallengeInfo.hxx b/src/libs/resiprocate/resip/dum/ChallengeInfo.hxx new file mode 100644 index 00000000..00e6142c --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ChallengeInfo.hxx @@ -0,0 +1,88 @@ +#if !defined(RESIP_CHALLENGE_INFO_HXX) +#define RESIP_CHALLENGE_INFO_HXX + +#include "rutil/Data.hxx" +#include "resip/dum/DumFeatureMessage.hxx" + +namespace resip +{ + +class ChallengeInfo : public resip::DumFeatureMessage +{ + public: + ChallengeInfo( bool failed, + bool challengeRequired, + const Data& transactionId); + ~ChallengeInfo(); + + bool isFailed() const; + bool isChallengeRequired() const; + + virtual resip::Data brief() const; + virtual resip::Message* clone() const; + + virtual std::ostream& encode(std::ostream& strm) const; + virtual std::ostream& encodeBrief(std::ostream& strm) const; + + private: + bool mFailed; + bool mChallengeRequired; +}; + +std::ostream& +operator<<(std::ostream& strm, const ChallengeInfo& msg); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/dum/ClientAuthExtension.cxx b/src/libs/resiprocate/resip/dum/ClientAuthExtension.cxx new file mode 100644 index 00000000..142db06f --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientAuthExtension.cxx @@ -0,0 +1,46 @@ +#include "resip/dum/ClientAuthExtension.hxx" + +using namespace resip; + +std::auto_ptr<ClientAuthExtension> ClientAuthExtension::mInstance = std::auto_ptr<ClientAuthExtension>(new ClientAuthExtension()); + +void +ClientAuthExtension::setInstance(std::auto_ptr<ClientAuthExtension> ext) +{ + mInstance = ext; +} + + +void +ClientAuthExtension::makeChallengeResponseAuth(const SipMessage& request, + const Data& username, + const Data& password, + const Auth& challenge, + const Data& cnonce, + const Data& authQop, + const Data& nonceCountString, + Auth& auth) +{ + assert(0); +} + +void +ClientAuthExtension::makeChallengeResponseAuthWithA1(const SipMessage& request, + const Data& username, + const Data& passwordHashA1, + const Auth& challenge, + const Data& cnonce, + const Data& authQop, + const Data& nonceCountString, + Auth& auth) +{ + assert(0); +} + + +bool +ClientAuthExtension::algorithmAndQopSupported(const Auth& challenge) +{ + return false; +} + diff --git a/src/libs/resiprocate/resip/dum/ClientAuthExtension.hxx b/src/libs/resiprocate/resip/dum/ClientAuthExtension.hxx new file mode 100644 index 00000000..3c77762d --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientAuthExtension.hxx @@ -0,0 +1,113 @@ +#if !defined(CLIENT_AUTH_EXTENSION_HXX) +#define CLIENT_AUTH_EXTENSION_HXX + +#include <time.h> + +#include <time.h> + +#include "resip/stack/NonceHelper.hxx" +#include "resip/stack/Symbols.hxx" +#include "resip/stack/Uri.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/Data.hxx" +#include "resip/stack/Contents.hxx" +#include "resip/stack/SecurityAttributes.hxx" + +namespace resip +{ + +class SipMessage; +class NameAddr; +class SecurityAttributes; +class Security; + +class ClientAuthExtension +{ + public: + virtual ~ClientAuthExtension() {} + virtual void makeChallengeResponseAuth(const SipMessage& request, + const Data& username, + const Data& password, + const Auth& challenge, + const Data& cnonce, + const Data& authQop, + const Data& nonceCountString, + Auth& auth); + virtual void makeChallengeResponseAuthWithA1(const SipMessage& request, + const Data& username, + const Data& passwordHashA1, + const Auth& challenge, + const Data& cnonce, + const Data& authQop, + const Data& nonceCountString, + Auth& auth); + + virtual bool algorithmAndQopSupported(const Auth& challenge); + + static void setInstance(std::auto_ptr<ClientAuthExtension> ext); + static ClientAuthExtension& instance() + { + return *mInstance; + } + protected: + ClientAuthExtension() {} + + + static std::auto_ptr<ClientAuthExtension> mInstance; + +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientAuthManager.cxx b/src/libs/resiprocate/resip/dum/ClientAuthManager.cxx new file mode 100644 index 00000000..dad6f072 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientAuthManager.cxx @@ -0,0 +1,495 @@ +#include <cassert> + +#include "resip/stack/Helper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/ClientAuthManager.hxx" +#include "resip/dum/UserProfile.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Random.hxx" +#include "resip/dum/ClientAuthExtension.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; +using namespace std; + +class ClientAuthDecorator : public MessageDecorator +{ +public: + ClientAuthDecorator(bool isProxyCredential, const Auth& auth, const UserProfile::DigestCredential& credential, const Data& authQop, const Data& nonceCountString) : + mIsProxyCredential(isProxyCredential), mAuth(auth), mCredential(credential), mAuthQop(authQop), mNonceCountString(nonceCountString) {} + virtual ~ClientAuthDecorator() {} + virtual void decorateMessage(SipMessage &msg, + const Tuple &source, + const Tuple &destination, + const Data& sigcompId) + { + Data cnonce = Random::getCryptoRandomHex(16); + + Auths & target = mIsProxyCredential ? msg.header(h_ProxyAuthorizations) : msg.header(h_Authorizations); + + DebugLog( << " Add auth, " << this << " in response to: " << mAuth); + Auth auth; + if (ClientAuthExtension::instance().algorithmAndQopSupported(mAuth)) + { + DebugLog(<<"Using extension to make auth response"); + + if(mCredential.isPasswordA1Hash) + { + ClientAuthExtension::instance().makeChallengeResponseAuthWithA1(msg, + mCredential.user, + mCredential.password, + mAuth, + cnonce, + mAuthQop, + mNonceCountString, + auth); + } + else + { + ClientAuthExtension::instance().makeChallengeResponseAuth(msg, + mCredential.user, + mCredential.password, + mAuth, + cnonce, + mAuthQop, + mNonceCountString, + auth); + } + } + else + { + if(mCredential.isPasswordA1Hash) + { + Helper::makeChallengeResponseAuthWithA1(msg, + mCredential.user, + mCredential.password, + mAuth, + cnonce, + mAuthQop, + mNonceCountString, + auth); + } + else + { + Helper::makeChallengeResponseAuth(msg, + mCredential.user, + mCredential.password, + mAuth, + cnonce, + mAuthQop, + mNonceCountString, + auth); + } + } + target.push_back(auth); + + DebugLog(<<"ClientAuthDecorator, proxy: " << mIsProxyCredential << " " << target.back()); + } + virtual void rollbackMessage(SipMessage& msg) + { + Auths & target = mIsProxyCredential ? msg.header(h_ProxyAuthorizations) : msg.header(h_Authorizations); + target.pop_back(); + } + virtual MessageDecorator* clone() const { return new ClientAuthDecorator(mIsProxyCredential, mAuth, mCredential, mAuthQop, mNonceCountString); } +private: + bool mIsProxyCredential; + Auth mAuth; + UserProfile::DigestCredential mCredential; + Data mAuthQop; + Data mNonceCountString; +}; + +ClientAuthManager::ClientAuthManager() +{ +} + + +bool +ClientAuthManager::handle(UserProfile& userProfile, SipMessage& origRequest, const SipMessage& response) +{ + try + { + assert( response.isResponse() ); + assert( origRequest.isRequest() ); + + DialogSetId id(origRequest); + + const int& code = response.header(h_StatusLine).statusCode(); + if (code < 101 || code >= 500) + { + return false; + } + else if (! ( code == 401 || code == 407 )) // challenge success + { + AttemptedAuthMap::iterator it = mAttemptedAuths.find(id); + if (it != mAttemptedAuths.end()) + { + DebugLog (<< "ClientAuthManager::handle: transitioning " << id << "to cached"); + + // cache the result + it->second.authSucceeded(); + } + return false; + } + + if (!(response.exists(h_WWWAuthenticates) || response.exists(h_ProxyAuthenticates))) + { + DebugLog (<< "Invalid challenge for " << id << ", nothing to respond to; fail"); + return false; + } + + AuthState& authState = mAttemptedAuths[id]; + + // based on the UserProfile and the challenge, store credentials in the + // AuthState associated with this DialogSet if the algorithm is supported + if (authState.handleChallenge(userProfile, response)) + { + assert(origRequest.header(h_Vias).size() == 1); + origRequest.header(h_CSeq).sequence()++; + DebugLog (<< "Produced response to digest challenge for " << userProfile ); + return true; + } + else + { + return false; + } + } + catch(BaseException& e) + { + assert(0); + ErrLog(<< "Unexpected exception in ClientAuthManager::handle " << e); + return false; + } +} + +void +ClientAuthManager::addAuthentication(SipMessage& request) +{ + AttemptedAuthMap::iterator it = mAttemptedAuths.find(DialogSetId(request)); + if (it != mAttemptedAuths.end()) + { + it->second.addAuthentication(request); + } +} + +void +ClientAuthManager::clearAuthenticationState(const DialogSetId& dsId) +{ + dialogSetDestroyed(dsId); +} + +ClientAuthManager::AuthState::AuthState() : + mFailed(false) +{ +} + + +bool +ClientAuthManager::AuthState::handleChallenge(UserProfile& userProfile, const SipMessage& challenge) +{ + if (mFailed) + { + return false; + } + bool handled = true; + if (challenge.exists(h_WWWAuthenticates)) + { + for (Auths::const_iterator i = challenge.header(h_WWWAuthenticates).begin(); + i != challenge.header(h_WWWAuthenticates).end(); ++i) + { + if (i->exists(p_realm)) + { + if (!mRealms[i->param(p_realm)].handleAuth(userProfile, *i, false)) + { + handled = false; + break; + } + } + else + { + return false; + } + } + } + if (challenge.exists(h_ProxyAuthenticates)) + { + for (Auths::const_iterator i = challenge.header(h_ProxyAuthenticates).begin(); + i != challenge.header(h_ProxyAuthenticates).end(); ++i) + { + if (i->exists(p_realm)) + { + if (!mRealms[i->param(p_realm)].handleAuth(userProfile, *i, true)) + { + handled = false; + break; + } + } + else + { + return false; + } + } + if(!handled) + { + InfoLog( << "ClientAuthManager::AuthState::handleChallenge failed for: " << challenge); + } + } + return handled; +} + +void +ClientAuthManager::AuthState::authSucceeded() +{ + for(RealmStates::iterator i = mRealms.begin(); i!=mRealms.end(); i++) + { + i->second.authSucceeded(); + } +} + +void +ClientAuthManager::AuthState::addAuthentication(SipMessage& request) +{ + request.remove(h_ProxyAuthorizations); + request.remove(h_Authorizations); + + if (mFailed) return; + + for(RealmStates::iterator i = mRealms.begin(); i!=mRealms.end(); i++) + { + i->second.addAuthentication(request); + } +} + + +ClientAuthManager::RealmState::RealmState() : + mIsProxyCredential(false), + mState(Invalid), + mNonceCount(0), + mAuthPtr(NULL) +{ +} + +Data RealmStates[] = +{ + "invalid", + "cached", + "current", + "tryonce", + "failed", +}; + +const Data& +ClientAuthManager::RealmState::getStateString(State s) +{ + return RealmStates[s]; +} + +void +ClientAuthManager::RealmState::transition(State s) +{ + DebugLog(<< "ClientAuthManager::RealmState::transition from " << getStateString(mState) << " to " << getStateString(s)); + mState = s; +} + +void +ClientAuthManager::RealmState::authSucceeded() +{ + switch(mState) + { + case Invalid: + assert(0); + break; + case Current: + case Cached: + case TryOnce: + transition(Cached); + break; + case Failed: + assert(0); + break; + }; +} + +bool +ClientAuthManager::RealmState::handleAuth(UserProfile& userProfile, const Auth& auth, bool isProxyCredential) +{ + DebugLog( << "ClientAuthManager::RealmState::handleAuth: " << this << " " << auth << " is proxy: " << isProxyCredential); + mIsProxyCredential = isProxyCredential; //this changing dynamically would + //be very bizarre..should trap w/ enum + switch(mState) + { + case Invalid: + mAuth = auth; + transition(Current); + break; + case Current: + if (auth.exists(p_stale) && auth.param(p_stale) == "true") + { + DebugLog (<< "Stale nonce:" << auth); + mAuth = auth; + clear(); + } + else if(auth.exists(p_nonce) && auth.param(p_nonce) != mAuth.param(p_nonce)) + { + DebugLog (<< "Different nonce, was: " << mAuth.param(p_nonce) << " now " << auth.param(p_nonce)); + mAuth = auth; + clear(); + transition(TryOnce); + } + else + { + DebugLog( << "Challenge response already failed for: " << auth); + transition(Failed); + return false; + } + break; + case TryOnce: + DebugLog( << "Extra chance still failed: " << auth); + transition(Failed); + return false; + case Cached: //basically 1 free chance, here for interop, may not be + //required w/ nonce check in current + mAuth = auth; + clear(); + transition(Current); + break; + case Failed: + return false; + } + + if (findCredential(userProfile, auth)) + { + return true; + } + else + { + transition(Failed); + return false; + } +} + +void +ClientAuthManager::RealmState::clear() +{ + mNonceCount = 0; +} + +bool +ClientAuthManager::RealmState::findCredential(UserProfile& userProfile, const Auth& auth) +{ + if (!(Helper::algorithmAndQopSupported(auth) + || (ClientAuthExtension::instance().algorithmAndQopSupported(auth)))) + { + DebugLog(<<"Unsupported algorithm or qop: " << auth); + return false; + } + + const Data& realm = auth.param(p_realm); + //!dcm! -- icky, expose static empty soon...ptr instead of reference? + mCredential = userProfile.getDigestCredential(realm); + if ( mCredential.realm.empty() ) + { + DebugLog( << "Got a 401 or 407 but could not find credentials for realm: " << realm); +// DebugLog (<< auth); +// DebugLog (<< response); + return false; + } + return true; +} + +void +ClientAuthManager::RealmState::addAuthentication(SipMessage& request) +{ + assert(mState != Failed); + if (mState == Failed) return; + + Data nonceCountString; + Data authQop = Helper::qopOption(mAuth); + if(!authQop.empty()) + { + Helper::updateNonceCount(mNonceCount, nonceCountString); + } + + // Add client auth decorator so that we ensure any body hashes are calcuated after user defined outbound decorators that + // may be modifying the message body + std::auto_ptr<MessageDecorator> clientAuthDecorator(new ClientAuthDecorator(mIsProxyCredential, mAuth, mCredential, authQop, nonceCountString)); + request.addOutboundDecorator(clientAuthDecorator); +} + +void ClientAuthManager::dialogSetDestroyed(const DialogSetId& id) +{ + if ( mAttemptedAuths.find(id) != mAttemptedAuths.end()) + { + mAttemptedAuths.erase(id); + } +} + +// bool +// ClientAuthManager::CompareAuth::operator()(const Auth& lhs, const Auth& rhs) const +// { +// if (lhs.param(p_realm) < rhs.param(p_realm)) +// { +// return true; +// } +// else if (lhs.param(p_realm) > rhs.param(p_realm)) +// { +// return false; +// } +// else +// { +// return lhs.param(p_username) < rhs.param(p_username); +// } +// } + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientAuthManager.hxx b/src/libs/resiprocate/resip/dum/ClientAuthManager.hxx new file mode 100644 index 00000000..684e588b --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientAuthManager.hxx @@ -0,0 +1,156 @@ +#if !defined(RESIP_CLIENTAUTHMANAGER_HXX) +#define RESIP_CLIENTAUTHMANAGER_HXX + +#include "resip/dum/DialogSetId.hxx" +#include "resip/dum/UserProfile.hxx" +#include "rutil/SharedPtr.hxx" + +#include <map> +#include <functional> + +namespace resip +{ + +class Auth; +class SipMessage; +class ClientAuthExtension; + + +class ClientAuthManager +{ + public: + ClientAuthManager(); + virtual ~ClientAuthManager() {} + + // For any response received by the UAC, handle will be + // called. origRequest is the request that generated the 401/407. + // return true if the challenge can be handled with an updated request. + // This will increment the CSeq on origRequest + virtual bool handle(UserProfile& userProfile, SipMessage& origRequest, const SipMessage& response); + + // + virtual void addAuthentication(SipMessage& origRequest); + virtual void clearAuthenticationState(const DialogSetId& dsId); + + private: + friend class DialogSet; + virtual void dialogSetDestroyed(const DialogSetId& dsId); + +// class CompareAuth : public std::binary_function<const Auth&, const Auth&, bool> +// { +// public: +// bool operator()(const Auth& lhs, const Auth& rhs) const; +// }; + + + class RealmState + { + public: + RealmState(); + + void clear(); + + bool handleAuth(UserProfile& userProfile, const Auth& auth, bool isProxyCredential); + void authSucceeded(); + + void addAuthentication(SipMessage& origRequest); + private: + typedef enum + { + Invalid, + Cached, + Current, + TryOnce, + Failed + } State; + + void transition(State s); + static const Data& getStateString(State s); + bool findCredential(UserProfile& userProfile, const Auth& auth); + UserProfile::DigestCredential mCredential; + bool mIsProxyCredential; + + State mState; + unsigned int mNonceCount; + Auth mAuth; + + // FH add the realm state so it can change + Auth *mAuthPtr; + +// .dcm. only one credential per realm per challenge supported +// typedef std::map<Auth, UserProfile::DigestCredential, CompareAuth > CredentialMap; +// CredentialMap proxyCredentials; +// CredentialMap wwwCredentials; + }; + + class AuthState + { + public: + AuthState(); + bool handleChallenge(UserProfile& userProfile, const SipMessage& challenge); + void addAuthentication(SipMessage& origRequest); + void authSucceeded(); + + private: + typedef std::map<Data, RealmState> RealmStates; + RealmStates mRealms; + bool mFailed; + }; + + typedef std::map<DialogSetId, AuthState> AttemptedAuthMap; + AttemptedAuthMap mAttemptedAuths; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientInviteSession.cxx b/src/libs/resiprocate/resip/dum/ClientInviteSession.cxx new file mode 100644 index 00000000..7c5e3764 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientInviteSession.cxx @@ -0,0 +1,1545 @@ + +#include "resip/stack/Contents.hxx" +#include "resip/dum/ClientInviteSession.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/DialogEventStateManager.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/InviteSessionHandler.hxx" +#include "resip/dum/DumTimeout.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/ServerInviteSession.hxx" +#include "resip/dum/ServerSubscription.hxx" +#include "resip/dum/UsageUseException.hxx" +#include "resip/dum/DumHelper.hxx" +#include "resip/stack/SipFrag.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Random.hxx" +#include "rutil/compat.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; +using namespace std; + +ClientInviteSession::ClientInviteSession(DialogUsageManager& dum, + Dialog& dialog, + SharedPtr<SipMessage> request, + const Contents* initialOffer, + DialogUsageManager::EncryptionLevel level, + ServerSubscriptionHandle serverSub) : + InviteSession(dum, dialog), + mStaleCallTimerSeq(1), + mCancelledTimerSeq(1), + mServerSub(serverSub) +{ + assert(request->isRequest()); + if(initialOffer) + { + mProposedLocalOfferAnswer = auto_ptr<Contents>(initialOffer->clone()); + mProposedEncryptionLevel = level; + } + *mLastLocalSessionModification = *request; // Copy message, so that modifications to mLastLocalSessionModification don't effect creator->getLastRequest + + mState=UAC_Start; +} + +ClientInviteSessionHandle +ClientInviteSession::getHandle() +{ + return ClientInviteSessionHandle(mDum, getBaseHandle().getId()); +} + +const Contents& +ClientInviteSession::getEarlyMedia() const +{ + return *mEarlyMedia; +} + +void +ClientInviteSession::provideOffer(const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative) +{ + InfoLog (<< toData(mState) << ": provideOffer"); + + switch(mState) + { + case UAC_EarlyWithAnswer: + { + transition(UAC_SentUpdateEarly); + + // Creates an UPDATE request with application supplied offer. + mDialog.makeRequest(*mLastLocalSessionModification, UPDATE); + InviteSession::setOfferAnswer(*mLastLocalSessionModification, offer); + + // Remember proposed local offferAnswer. + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); + mProposedEncryptionLevel = level; + + // Send the req and do state transition. + DumHelper::setOutgoingEncryptionLevel(*mLastLocalSessionModification, mProposedEncryptionLevel); + send(mLastLocalSessionModification); + break; + } + + case UAC_SentAnswer: + // just queue it for later + transition(UAC_QueuedUpdate); + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); + mProposedEncryptionLevel = level; + break; + + case UAC_Start: + case UAC_Early: + case UAC_EarlyWithOffer: + case UAC_Answered: + case UAC_SentUpdateEarly: + case UAC_ReceivedUpdateEarly: + case UAC_Cancelled: + case UAC_QueuedUpdate: + case Terminated: + assert(0); + break; + + default: + InviteSession::provideOffer(offer, level, alternative); + break; + } +} + +void +ClientInviteSession::provideOffer (const Contents& offer) +{ + this->provideOffer(offer, mCurrentEncryptionLevel, 0); +} + +void +ClientInviteSession::provideAnswer (const Contents& answer) +{ + InfoLog (<< toData(mState) << ": provideAnswer"); + + switch(mState) + { + case UAC_EarlyWithOffer: + { + transition(UAC_SentAnswer); + + // Remember proposed local offerAnswer. + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + + // Creates an PRACK request with application supplied offer. + sendPrack(answer); + break; + } + + case UAC_Answered: + { + transition(Connected); + sendAck(&answer); + + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + // mLastSessionModification = ack; // ?slg? is this needed? + break; + } + case UAC_ReceivedUpdateEarly: + { + transition(UAC_EarlyWithAnswer); //.dcm. earlyWithAnwer is a strange + //name...maybe earlyEstablished? + //this sequence is repeated in many places...due for refactoring. + //see ReceivedUpdate handling in InviteSession. + //?dcm? are session timers allowed in the early dialog? + + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, *mLastRemoteSessionModification, 200); + InviteSession::setOfferAnswer(*response, answer, 0); + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + InfoLog (<< "Sending " << response->brief()); + DumHelper::setOutgoingEncryptionLevel(*response, mCurrentEncryptionLevel); + send(response); + break; + } + + case UAC_Start: + case UAC_Early: + case UAC_EarlyWithAnswer: + case UAC_SentUpdateEarly: + case UAC_SentAnswer: + case UAC_Cancelled: + case UAC_QueuedUpdate: + case Terminated: + assert(0); + break; + + default: + InviteSession::provideAnswer(answer); + break; + } +} + +void +ClientInviteSession::end() +{ + end(NotSpecified); +} + +void +ClientInviteSession::end(const Data& userReason) +{ + mUserEndReason = userReason; + end(InviteSession::UserSpecified); +} + +void +ClientInviteSession::end(EndReason reason) +{ + InfoLog (<< toData(mState) << ": end"); + if (mEndReason == NotSpecified) + { + mEndReason = reason; + } + + switch(mState) + { + case UAC_Early: + case UAC_EarlyWithOffer: + case UAC_EarlyWithAnswer: + case UAC_Answered: + case UAC_SentUpdateEarly: + case UAC_ReceivedUpdateEarly: + case UAC_SentAnswer: + case UAC_QueuedUpdate: + case UAC_Cancelled: // !jf! possibly incorrect to always BYE in UAC_Cancelled + { + SharedPtr<SipMessage> msg = sendBye(); + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); + break; + } + + case UAC_Start: + WarningLog (<< "Try to end when in state=" << toData(mState)); + assert(0); + break; + + case Terminated: + // no-op + break; + + default: + InviteSession::end(reason); + break; + } +} + +void +ClientInviteSession::reject (int statusCode, WarningCategory *warning) +{ + InfoLog (<< toData(mState) << ": reject(" << statusCode << ")"); + + switch(mState) + { + case UAC_ReceivedUpdateEarly: + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, *mLastRemoteSessionModification, statusCode); + if(warning) + { + response->header(h_Warnings).push_back(*warning); + } + + // Send the req and do state transition. + send(response); + transition(UAC_EarlyWithAnswer); + break; + } + + case UAC_Answered:{ + // We received an offer in a 2xx response, and we want to reject it + // ACK with no body, then send bye + sendAck(); + SharedPtr<SipMessage> msg = sendBye(); + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); + break; + } + + case UAC_Start: + case UAC_Early: + case UAC_EarlyWithOffer: + case UAC_EarlyWithAnswer: + case UAC_SentUpdateEarly: + case UAC_SentAnswer: + case UAC_Cancelled: + WarningLog (<< "Try to reject when in state=" << toData(mState)); + assert(0); + break; + + default: + InviteSession::reject(statusCode, warning); + break; + } +} + +void +ClientInviteSession::cancel() +{ + switch(mState) + { + case UAC_Early: + case UAC_EarlyWithOffer: + case UAC_EarlyWithAnswer: + case UAC_SentUpdateEarly: + case UAC_ReceivedUpdateEarly: + case UAC_SentAnswer: + InfoLog (<< toData(mState) << ": cancel"); + startCancelTimer(); + transition(UAC_Cancelled); + break; + + case UAC_Cancelled: + case Terminated: + // no-op already cancelled or ended + break; + + default: + assert(0); + break; + } +} + +void +ClientInviteSession::onForkAccepted() +{ + switch(mState) + { + case UAC_Early: + case UAC_EarlyWithOffer: + case UAC_EarlyWithAnswer: + case UAC_SentUpdateEarly: + case UAC_ReceivedUpdateEarly: + InfoLog (<< toData(mState) << ": onForkAccepted"); + // !jf! should we avoid creating another timer here? I don't think it + // matters. Default timer is for 32secs. This is here to handle the + // cleanup on forked INVITEs that have sent a provisional response but + // don't ever receive a final response. + mDum.addTimerMs(DumTimeout::WaitingForForked2xx, Timer::TH, getBaseHandle(), 1); + break; + default: + // If the dialog is already set up (or cancelled) we disregard. + break; + } +} + +void +ClientInviteSession::startCancelTimer() +{ + InfoLog (<< toData(mState) << ": startCancelTimer"); + mDum.addTimerMs(DumTimeout::Cancelled, Timer::TH, getBaseHandle(), ++mCancelledTimerSeq); +} + +void +ClientInviteSession::startStaleCallTimer() +{ + InfoLog (<< toData(mState) << ": startStaleCallTimer"); + unsigned long when = mDialog.mDialogSet.getUserProfile()->getDefaultStaleCallTime(); + when += Random::getRandom() % 120; + + mDum.addTimer(DumTimeout::StaleCall, + when, + getBaseHandle(), + ++mStaleCallTimerSeq); +} + +void +ClientInviteSession::sendSipFrag(const SipMessage& msg) +{ + if (mServerSub.isValid()) + { + if (msg.isResponse() && mState >= UAC_Start && mState <= UAC_Cancelled) + { + int code = msg.header(h_StatusLine).statusCode(); + if (code > 100) + { + SipFrag contents; + contents.message().header(h_StatusLine) = msg.header(h_StatusLine); + if(mDialog.mDialogSet.getUserProfile()->getExtraHeadersInReferNotifySipFragEnabled()) + { + contents.message().header(h_Vias) = msg.header(h_Vias); + contents.message().header(h_From) = msg.header(h_From); + contents.message().header(h_To) = msg.header(h_To); + contents.message().header(h_CallId) = msg.header(h_CallId); + contents.message().header(h_CSeq) = msg.header(h_CSeq); + contents.message().header(h_Contacts) = msg.header(h_Contacts); + } + if (code < 200) + { + mServerSub->send(mServerSub->update(&contents)); + } + else + { + mServerSub->end(NoResource, &contents); + } + } + } + } +} + +void +ClientInviteSession::dispatch(const SipMessage& msg) +{ + try + { + if (msg.isRequest()) + { + if (msg.header(h_RequestLine).method() == INFO) + { + InviteSession::dispatchInfo(msg); + return; + } + if (msg.header(h_RequestLine).method() == MESSAGE) + { + InviteSession::dispatchMessage(msg); + return; + } + } + + if (checkRseq(msg)) + { + return; + } + + sendSipFrag(msg); + switch(mState) + { + case UAC_Start: + dispatchStart(msg); + break; + case UAC_Early: + dispatchEarly(msg); + break; + case UAC_EarlyWithOffer: + dispatchEarlyWithOffer(msg); + break; + case UAC_EarlyWithAnswer: + dispatchEarlyWithAnswer(msg); + break; + case UAC_Answered: + dispatchAnswered(msg); + break; + case UAC_SentUpdateEarly: + dispatchSentUpdateEarly(msg); + break; + case UAC_SentUpdateEarlyGlare: + dispatchSentUpdateEarlyGlare(msg); + break; + case UAC_ReceivedUpdateEarly: + dispatchReceivedUpdateEarly(msg); + break; + case UAC_SentAnswer: + dispatchSentAnswer(msg); + break; + case UAC_QueuedUpdate: + dispatchQueuedUpdate(msg); + break; + case UAC_Cancelled: + dispatchCancelled(msg); + break; + default: + InviteSession::dispatch(msg); + break; + } + } + catch (BaseException& e) + { + WarningLog (<< "Caught: " << e); + onFailureAspect(getHandle(), msg); + end(NotSpecified); + } +} + +void +ClientInviteSession::dispatch(const DumTimeout& timer) +{ + if (timer.type() == DumTimeout::Cancelled) + { + if(timer.seq() == mCancelledTimerSeq) + { + if (mServerSub.isValid()) + { + SipMessage response; + mDialog.makeResponse(response, *mLastLocalSessionModification, 487); + sendSipFrag(response); + } + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalCancel); + mDum.destroy(this); + } + } + else if (timer.type() == DumTimeout::StaleCall) + { + if(timer.seq() == mStaleCallTimerSeq) + { + mDum.mInviteSessionHandler->onStaleCallTimeout(getHandle()); + mDum.mInviteSessionHandler->terminate(getHandle()); + } + } + else if (timer.type() == DumTimeout::WaitingForForked2xx) + { + transition(Terminated); + mDum.mInviteSessionHandler->onForkDestroyed(getHandle()); + mDum.destroy(this); + } + else if (timer.type() == DumTimeout::Glare) + { + if (mState == UAC_SentUpdateEarlyGlare) + { + transition(UAC_SentUpdateEarly); + InfoLog (<< "Retransmitting the UPDATE (glare condition timer)"); + mDialog.makeRequest(*mLastLocalSessionModification, UPDATE); // increments CSeq + send(mLastLocalSessionModification); + } + else + { + InviteSession::dispatch(timer); + } + } + else + { + InviteSession::dispatch(timer); + } +} + +void +ClientInviteSession::handleRedirect (const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + transition(Terminated); + + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTerminated(mDialog, msg, InviteSessionHandler::Rejected); + } + + handler->onRedirected(getHandle(), msg); + mDum.destroy(this); +} + +void +ClientInviteSession::handleProvisional(const SipMessage& msg) +{ + assert(msg.isResponse()); + assert(msg.header(h_StatusLine).statusCode() < 200); + assert(msg.header(h_StatusLine).statusCode() > 100); + + //.dcm. Kept the following checks here rather than discardMessage as the + // state machine can be affected(termination). + + // !dcm! should we really end the InviteSession or should be discard the 1xx instead? + if (msg.header(h_CSeq).sequence() != mLastLocalSessionModification->header(h_CSeq).sequence()) + { + InfoLog (<< "Failure: CSeq doesn't match invite: " << msg.brief()); + onFailureAspect(getHandle(), msg); + end(NotSpecified); + return; + } + else if (isReliable(msg)) + { + if (!msg.exists(h_RSeq)) + { + InfoLog (<< "Failure: No RSeq in 1xx: " << msg.brief()); + onFailureAspect(getHandle(), msg); + end(NotSpecified); + return; + } + } + + startStaleCallTimer(); + onProvisionalAspect(getHandle(), msg); +} + +void +ClientInviteSession::handleFinalResponse(const SipMessage& msg) +{ + assert(msg.isResponse()); + assert(msg.header(h_StatusLine).statusCode() >= 200); + assert(msg.header(h_StatusLine).statusCode() < 300); + + handleSessionTimerResponse(msg); + storePeerCapabilities(msg); + ++mStaleCallTimerSeq; // disable stale call timer +} + +void +ClientInviteSession::handleOffer (const SipMessage& msg, const Contents& offer) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + + handleProvisional(msg); + mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(offer); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + handler->onOffer(getSessionHandle(), msg, offer); +} + +void +ClientInviteSession::handleAnswer(const SipMessage& msg, const Contents& answer) +{ + //mCurrentLocalOfferAnswer = mProposedLocalOfferAnswer; + setCurrentLocalOfferAnswer(msg); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(answer); + + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + handleProvisional(msg); + handler->onAnswer(getSessionHandle(), msg, answer); + + sendPrackIfNeeded(msg); +} + +// will not include SDP (this is a subsequent 1xx) +void +ClientInviteSession::sendPrackIfNeeded(const SipMessage& msg) +{ + assert(msg.isResponse()); + assert(msg.header(h_StatusLine).statusCode() < 200); + assert(msg.header(h_StatusLine).statusCode() > 100); + + if (isReliable(msg)) + { + SharedPtr<SipMessage> prack(new SipMessage); + mDialog.makeRequest(*prack, PRACK); + prack->header(h_RAck) = mRelRespInfo; + send(prack); + } +} + +// This version is used to send an answer to the UAS in PRACK +// from EarlyWithOffer state. Assumes that it is the first PRACK. Subsequent +// PRACK will not have SDP +void +ClientInviteSession::sendPrack(const Contents& offerAnswer) +{ + SharedPtr<SipMessage> prack(new SipMessage); + mDialog.makeRequest(*prack, PRACK); + prack->header(h_RAck)= mRelRespInfo; + + InviteSession::setOfferAnswer(*prack, offerAnswer); + + // Remember last session modification. + // mLastSessionModification = prack; // ?slg? is this needed? + + DumHelper::setOutgoingEncryptionLevel(*prack, mCurrentEncryptionLevel); + send(prack); +} + + +/* +bool +ClientInviteSession::isNextProvisional(const SipMessage& msg) +{ +} + +bool +ClientInviteSession::isRetransmission(const SipMessage& msg) +{ + if ( mLastReceivedRSeq == 0 || + msg.header(h_RSeq).value() <= mLastReceivedRSeq) + { + return false; + } + else + { + return true; + } +} +*/ + +void +ClientInviteSession::dispatchStart (const SipMessage& msg) +{ + assert(msg.isResponse()); + assert(msg.header(h_StatusLine).statusCode() > 100); + assert(msg.header(h_CSeq).method() == INVITE); + + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + InviteSession::Event event = toEvent(msg, offerAnswer.get()); + + switch (event) + { + case On1xx: + transition(UAC_Early); + handler->onNewSession(getHandle(), InviteSession::None, msg); + if(!isTerminated()) + { + handleProvisional(msg); + sendPrackIfNeeded(msg); //may wish to move emprty PRACK handling + //outside the state machine + } + break; + + case On1xxEarly: + //!dcm! according to draft-ietf-sipping-offeranswer there can be a non + // reliable 1xx followed by a reliable 1xx. Also, the intial 1xx + // doesn't have to have an offer. However, DUM will only generate + // reliabled 1xx responses when 100rel is available. + + transition(UAC_Early); + mEarlyMedia = InviteSession::makeOfferAnswer(*offerAnswer); + handler->onNewSession(getHandle(), InviteSession::None, msg); + if(!isTerminated()) + { + handleProvisional(msg); + if(!isTerminated()) + { + handler->onEarlyMedia(getHandle(), msg, *offerAnswer); + } + } + break; + + case On1xxOffer: + transition(UAC_EarlyWithOffer); + handler->onNewSession(getHandle(), InviteSession::Offer, msg); + if(!isTerminated()) + { + handleOffer(msg, *offerAnswer); + } + break; + + case On1xxAnswer: + transition(UAC_EarlyWithAnswer); + handler->onNewSession(getHandle(), InviteSession::Answer, msg); + if(!isTerminated()) + { + handleAnswer(msg, *offerAnswer); + } + break; + + case On2xxOffer: + transition(UAC_Answered); + handleFinalResponse(msg); + mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + handler->onNewSession(getHandle(), InviteSession::Offer, msg); + assert(mProposedLocalOfferAnswer.get() == 0); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + if(!isTerminated()) + { + handler->onOffer(getSessionHandle(), msg, *offerAnswer); + if(!isTerminated()) //?jf? can this be terminated here but not above? .slg. yes application can call end() + { + onConnectedAspect(getHandle(), msg); + } + } + break; + + case On2xxAnswer: + transition(Connected); + sendAck(); + handleFinalResponse(msg); + //mCurrentLocalOfferAnswer = mProposedLocalOfferAnswer; + setCurrentLocalOfferAnswer(msg); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + handler->onNewSession(getHandle(), InviteSession::Answer, msg); + if(!isTerminated()) // onNewSession callback may call end() or reject() + { + handler->onAnswer(getSessionHandle(), msg, *offerAnswer); + if(!isTerminated()) // onAnswer callback may call end() or reject() + { + onConnectedAspect(getHandle(), msg); + } + } + break; + + case On2xx: + { + sendAck(); + sendBye(); + InfoLog (<< "Failure: 2xx with no answer: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + break; + } + + case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure + case OnInviteFailure: + case OnGeneralFailure: + case On422Invite: + case On487Invite: + case On491Invite: + InfoLog (<< "Failure: error response: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + mDum.destroy(this); + break; + + case OnBye: + dispatchBye(msg); + break; + + default: + // !kh! + // should not assert here for peer sent us garbage. + WarningLog (<< "Don't know what this is : " << msg); + break; + } +} + +void +ClientInviteSession::dispatchEarly (const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case On1xx: + transition(UAC_Early); + handleProvisional(msg); + break; + + case On1xxEarly: // only unreliable + transition(UAC_Early); + handleProvisional(msg); + if(!isTerminated()) + { + mEarlyMedia = InviteSession::makeOfferAnswer(*offerAnswer); + handler->onEarlyMedia(getHandle(), msg, *offerAnswer); + } + break; + + case On1xxOffer: + transition(UAC_EarlyWithOffer); + handleOffer(msg, *offerAnswer); + break; + + case On1xxAnswer: + transition(UAC_EarlyWithAnswer); + handleAnswer(msg, *offerAnswer); + break; + + case On2xxOffer: + transition(UAC_Answered); + handleFinalResponse(msg); + + assert(mProposedLocalOfferAnswer.get() == 0); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + + handler->onOffer(getSessionHandle(), msg, *offerAnswer); + if(!isTerminated()) + { + onConnectedAspect(getHandle(), msg); + } + break; + + case On2xxAnswer: + transition(Connected); + sendAck(); + handleFinalResponse(msg); + //mCurrentLocalOfferAnswer = mProposedLocalOfferAnswer; + setCurrentLocalOfferAnswer(msg); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + handler->onAnswer(getSessionHandle(), msg, *offerAnswer); + if(!isTerminated()) // onNewSession callback may call end() or reject() + { + onConnectedAspect(getHandle(), msg); + } + break; + + case On2xx: + { + sendAck(); + sendBye(); + InfoLog (<< "Failure: 2xx with no answer: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + break; + } + + case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure + case OnInviteFailure: + case OnGeneralFailure: + case On422Invite: + case On487Invite: + InfoLog (<< "Failure: error response: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + mDum.destroy(this); + break; + + case OnBye: + dispatchBye(msg); + break; + + case OnUpdateOffer: + if(mProposedLocalOfferAnswer.get()) + { + WarningLog (<< "Invalid UPDATE with offer received in early state with pending offer: " << msg.brief()); + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 500); // RFC3311 - section 5.2 + InfoLog (<< "Sending " << response->brief()); + send(response); + } + else + { + *mLastRemoteSessionModification = msg; + transition(UAC_ReceivedUpdateEarly); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + handler->onOffer(getSessionHandle(), msg, *offerAnswer); + } + break; + + case OnUpdate: + { + // ?slg? no offerAnswer in update - just respond immediately - do we need a callback? + SharedPtr<SipMessage> response(new SipMessage); + *mLastRemoteSessionModification = msg; + mDialog.makeResponse(*response, msg, 200); + send(response); + break; + } + + default: + // !kh! + // should not assert here for peer sent us garbage. + WarningLog (<< "Don't know what this is : " << msg); + break; + } +} + +void +ClientInviteSession::dispatchAnswered (const SipMessage& msg) +{ + //InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case On1xx: + case On1xxEarly: + case On1xxOffer: + // late, so ignore + break; + + case On2xxOffer: + case On2xx: + case On2xxAnswer: + // retransmission + break; + + case OnRedirect: + // too late + break; + + // .slg. This doesn't really make sense (after a 2xx) + case OnGeneralFailure: + case On422Invite: + break; +#if 0 // !jf! don't think this is right + { + sendBye(); + InfoLog (<< "Failure: error response: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + mDum.destroy(this); + break; + } +#endif + case OnBye: + dispatchBye(msg); + break; + + default: + // !kh! + // should not assert here for peer sent us garbage. + WarningLog (<< "Don't know what this is : " << msg); + break; + } + +} + +void +ClientInviteSession::dispatchEarlyWithOffer (const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case On1xx: // must be reliable + handleProvisional(msg); + sendPrackIfNeeded(msg); + break; + + case On2xx: + case On2xxAnswer: + sendAck(); + sendBye(); + InfoLog (<< "Failure: no answer sent: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + break; + + case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure + case OnInviteFailure: + case OnGeneralFailure: + case On422Invite: + case On487Invite: + case On491Invite: + InfoLog (<< "Failure: error response: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + mDum.destroy(this); + break; + + case OnBye: + dispatchBye(msg); + break; + + case OnUpdateOffer: + { + WarningLog (<< "Invalid UPDATE with offer received in early state with pending offer: " << msg.brief()); + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 500); // RFC3311 - section 5.2 + InfoLog (<< "Sending " << response->brief()); + send(response); + break; + } + + case OnUpdate: + { + // ?slg? no offerAnswer in update - just respond immediately - do we need a callback? + SharedPtr<SipMessage> response(new SipMessage); + *mLastRemoteSessionModification = msg; + mDialog.makeResponse(*response, msg, 200); + send(response); + break; + } + + default: + // !kh! + // should not assert here for peer sent us garbage. + WarningLog (<< "Don't know what this is : " << msg); + break; + } +} + +void +ClientInviteSession::dispatchSentAnswer (const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case On200Prack: + transition(UAC_EarlyWithAnswer); + break; + + case On2xx: + transition(Connected); + sendAck(); + handleFinalResponse(msg); + onConnectedAspect(getHandle(), msg); + break; + + case On2xxAnswer: + case On2xxOffer: + case On1xxAnswer: + case On1xxOffer: + sendAck(); + sendBye(); + InfoLog (<< "Failure: illegal offer/answer: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + break; + + case On1xx: + handleProvisional(msg); + sendPrackIfNeeded(msg); + break; + + case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure + case OnInviteFailure: + case OnGeneralFailure: + case On422Invite: + case On487Invite: + case On491Invite: + InfoLog (<< "Failure: error response: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + mDum.destroy(this); + break; + + case OnBye: + dispatchBye(msg); + break; + + default: + // !kh! + // should not assert here for peer sent us garbage. + WarningLog (<< "Don't know what this is : " << msg); + break; + } +} + +void +ClientInviteSession::dispatchQueuedUpdate (const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case On200Prack: + transition(UAC_SentUpdateEarly); + { + mDialog.makeRequest(*mLastLocalSessionModification, UPDATE); + InviteSession::setOfferAnswer(*mLastLocalSessionModification, mProposedLocalOfferAnswer.get()); + + DumHelper::setOutgoingEncryptionLevel(*mLastLocalSessionModification, mProposedEncryptionLevel); + send(mLastLocalSessionModification); + } + break; + + case On2xx: + transition(SentUpdate); + { + sendAck(); + + SharedPtr<SipMessage> update(new SipMessage); + mDialog.makeRequest(*update, UPDATE); + InviteSession::setOfferAnswer(*update, mProposedLocalOfferAnswer.get()); + DumHelper::setOutgoingEncryptionLevel(*update, mProposedEncryptionLevel); + send(update); + } + handleFinalResponse(msg); + onConnectedAspect(getHandle(), msg); + break; + + case On2xxAnswer: + case On2xxOffer: + case On1xxAnswer: + case On1xxOffer: + sendAck(); + sendBye(); + InfoLog (<< "Failure: illegal offer/answer: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + break; + + case On1xx: + handleProvisional(msg); + sendPrackIfNeeded(msg); + break; + + case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure + case OnInviteFailure: + case OnGeneralFailure: + case On422Invite: + case On487Invite: + case On491Invite: + InfoLog (<< "Failure: error response: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + mDum.destroy(this); + break; + + case OnBye: + dispatchBye(msg); + break; + + default: + // !kh! + // should not assert here for peer sent us garbage. + WarningLog (<< "Don't know what this is : " << msg); + break; + } +} + + + +void +ClientInviteSession::dispatchEarlyWithAnswer (const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case On1xx: + handleProvisional(msg); + sendPrackIfNeeded(msg); + break; + case On1xxOffer: + if(!isTerminated()) + { + transition(UAC_EarlyWithOffer); + handleOffer(msg, *offerAnswer); + } + break; + case On2xx: + transition(Connected); + sendAck(); + handleFinalResponse(msg); + onConnectedAspect(getHandle(), msg); + break; + + case On2xxAnswer: + case On2xxOffer: + sendAck(); + sendBye(); + InfoLog (<< "Failure: illegal offer/answer: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + break; + + case OnUpdateOffer: + *mLastRemoteSessionModification = msg; + transition(UAC_ReceivedUpdateEarly); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + handler->onOffer(getSessionHandle(), msg, *offerAnswer); + break; + + case OnUpdate: + { + // ?slg? no offerAnswer in update - just respond immediately - do we need a callback? + SharedPtr<SipMessage> response(new SipMessage); + *mLastRemoteSessionModification = msg; + mDialog.makeResponse(*response, msg, 200); + send(response); + break; + } + + case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets here then it's because the redirect was intentionaly not handled and should be treated as an INVITE failure + case OnInviteFailure: + case OnGeneralFailure: + case On422Invite: + case On487Invite: + case On491Invite: + InfoLog (<< "Failure: error response: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + mDum.destroy(this); + break; + + case OnBye: + dispatchBye(msg); + break; + + default: + // !kh! + // should not assert here for peer sent us garbage. + WarningLog (<< "Don't know what this is : " << msg); + break; + } +} + +void +ClientInviteSession::dispatchSentUpdateEarly (const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case On200Update: + transition(UAC_EarlyWithAnswer); + setCurrentLocalOfferAnswer(msg); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + handler->onAnswer(getSessionHandle(), msg, *offerAnswer); + break; + + case OnUpdateOffer: + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 491); + send(response); + } + break; + + case OnUpdate: + { + // ?slg? no offerAnswer in update - just respond immediately - do we need a callback? + SharedPtr<SipMessage> response(new SipMessage); + *mLastRemoteSessionModification = msg; + mDialog.makeResponse(*response, msg, 200); + send(response); + break; + } + + case On491Update: + transition(UAC_SentUpdateEarlyGlare); + start491Timer(); + break; + + case On2xx: + transition(SentUpdate); + sendAck(); + break; + + case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets + // here then it's because the redirect was intentionaly + // not handled and should be treated as an INVITE failure + case OnInviteFailure: + case OnGeneralFailure: + case On422Invite: + case On487Invite: + InfoLog (<< "Failure: error response: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + mDum.destroy(this); + break; + + default: + WarningLog (<< "Don't know what this is : " << msg); + break; + } +} + +void +ClientInviteSession::dispatchSentUpdateEarlyGlare (const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnUpdateOffer: + handler->onOfferRejected(getSessionHandle(), &msg); + //will cause transition to UAC_ReceivedUpdateEarly + dispatchEarlyWithAnswer(msg); + break; + + case On2xx: + //transition to connected state machine + transition(SentUpdateGlare); + sendAck(); + break; + //!dcm! TODO This block below is repeated many, many times...refactor + //!into a method. Prob. represents the effective ClientInvite superstate. + case OnRedirect: // Redirects are handled by the DialogSet - if a 3xx gets + // here then it's because the redirect was intentionaly + // not handled and should be treated as an INVITE failure + case OnInviteFailure: + case OnGeneralFailure: + case On422Invite: + case On487Invite: + InfoLog (<< "Failure: error response: " << msg.brief()); + transition(Terminated); + onFailureAspect(getHandle(), msg); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + mDum.destroy(this); + break; + + default: + WarningLog (<< "Don't know what this is : " << msg); + break; + } +} + +void +ClientInviteSession::dispatchReceivedUpdateEarly (const SipMessage& msg) +{ + /* + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + default: + // !kh! + // should not assert here for peer sent us garbage. + WarningLog (<< "Don't know what this is : " << msg); + break; + } + */ + WarningLog (<< "Ignoring message received in ReceivedUpdateEarly: " << msg); +} + +void +ClientInviteSession::dispatchCancelled (const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnGeneralFailure: + case OnCancelFailure: + case On487Invite: + case OnRedirect: + case On422Invite: + case On491Invite: + case OnInviteFailure: + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalCancel, &msg); + mDum.destroy(this); + break; + + case On2xx: + case On2xxOffer: + case On2xxAnswer: + { + // this is the 2xx crossing the CANCEL case + sendAck(); + sendBye(); + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalCancel, &msg); + mCancelledTimerSeq++; + break; + } + + case OnBye: + dispatchBye(msg); + break; + + default: + break; + } +} + +//true if 180rel should be ignored. Saves rseq as a side effect. +bool +ClientInviteSession::checkRseq(const SipMessage& msg) +{ + int code = msg.isResponse() ? msg.header(h_StatusLine).statusCode() : 0; + if (msg.method() == INVITE && code > 100 && code < 200) + { + if (msg.exists(h_RSeq)) + { + // store state about the provisional if reliable, so we can detect retransmissions + unsigned int rseq = (unsigned int) msg.header(h_RSeq).value(); + unsigned int lastRseq = (unsigned int) mRelRespInfo.rSequence(); + + if (rseq == lastRseq) + { + DebugLog(<< "Discarding reliable 1xx retranmission with rseq " << rseq); + return true; + } + else if (lastRseq != 0 && rseq > lastRseq + 1) + { + DebugLog(<< "Discarding out of order reliable 1xx with rseq " << rseq); + return true; + } + mRelRespInfo.rSequence() = rseq; + mRelRespInfo.cSequence() = msg.header(h_CSeq).sequence(); + mRelRespInfo.method() = msg.header(h_CSeq).method(); + } + } + return false; +} + +void +ClientInviteSession::onConnectedAspect(ClientInviteSessionHandle c, const SipMessage& msg) +{ + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onConfirmed(mDialog, getSessionHandle()); + } + mDum.mInviteSessionHandler->onConnected(c, msg); +} + +void +ClientInviteSession::onProvisionalAspect(ClientInviteSessionHandle c, const SipMessage& msg) +{ + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onEarly(mDialog, getSessionHandle()); + } + mDum.mInviteSessionHandler->onProvisional(c, msg); +} + +void +ClientInviteSession::onFailureAspect(ClientInviteSessionHandle c, const SipMessage& msg) +{ + if (mDum.mDialogEventStateManager) + { + InviteSessionHandler::TerminatedReason reason = InviteSessionHandler::Rejected; + if (msg.isResponse()) + { + if (msg.header(h_StatusLine).responseCode() == 408) + { + reason = InviteSessionHandler::Timeout; + } + else if (msg.header(h_StatusLine).responseCode() / 100 == 5) + { + reason = InviteSessionHandler::Error; + } + } + mDum.mDialogEventStateManager->onTerminated(mDialog, msg, reason); + } + mDum.mInviteSessionHandler->onFailure(c, msg); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientInviteSession.hxx b/src/libs/resiprocate/resip/dum/ClientInviteSession.hxx new file mode 100644 index 00000000..6ce73641 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientInviteSession.hxx @@ -0,0 +1,155 @@ +#if !defined(RESIP_CLIENTINVITESESSION_HXX) +#define RESIP_CLIENTINVITESESSION_HXX + +#include "resip/dum/InviteSession.hxx" +#include "resip/dum/Handles.hxx" + +namespace resip +{ +class SipMessage; +class Contents; + +class ClientInviteSession : public InviteSession +{ + public: + ClientInviteSession(DialogUsageManager& dum, + Dialog& dialog, + SharedPtr<SipMessage> request, + const Contents* initialOffer, + DialogUsageManager::EncryptionLevel level, + ServerSubscriptionHandle serverSub = ServerSubscriptionHandle::NotValid()); + + ClientInviteSessionHandle getHandle(); + + public: + /** Called to set the offer that will be used in the next message that + sends an offer. For a UAC in an early dialog, this can be used to send + an UPDATE request with an offer. */ + virtual void provideOffer (const Contents& offer); + virtual void provideOffer(const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative); + + /** Similar to provideOffer - called to set the answer to be signalled to + the peer. May result in message being sent synchronously depending on + the state. */ + virtual void provideAnswer (const Contents& answer); + + /** Makes the specific dialog end. Will send a BYE (not a CANCEL) */ + virtual void end(const Data& userReason); + virtual void end(EndReason reason); + virtual void end(); + + /** Rejects an offer at the SIP level. For a UAC in an early dialog + this typically only makes sense, when rejecting an UPDATE request + that contains an offer in an early dialog. */ + virtual void reject (int statusCode, WarningCategory *warning = 0); + + const Contents& getEarlyMedia() const; + + private: + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + void dispatchStart (const SipMessage& msg); + void dispatchEarly (const SipMessage& msg); + void dispatchEarlyWithOffer (const SipMessage& msg); + void dispatchEarlyWithAnswer (const SipMessage& msg); + void dispatchAnswered (const SipMessage& msg); + void dispatchSentUpdateEarly (const SipMessage& msg); + void dispatchSentUpdateEarlyGlare (const SipMessage& msg); + void dispatchReceivedUpdateEarly (const SipMessage& msg); + void dispatchSentAnswer (const SipMessage& msg); + void dispatchQueuedUpdate (const SipMessage& msg); + void dispatchCancelled (const SipMessage& msg); + + void handleRedirect (const SipMessage& msg); + void handleProvisional (const SipMessage& msg); + void handleFinalResponse (const SipMessage& msg); + void handleOffer (const SipMessage& msg, const Contents& offer); + void handleAnswer (const SipMessage& msg, const Contents& answer); + void sendPrackIfNeeded(const SipMessage& msg); + void sendPrack(const Contents& offerAnswer); + + // Called by the DialogSet (friend) when the app has CANCELed the request + void cancel(); + + // Called by the DialogSet when it receives a 2xx response + void onForkAccepted(); + + bool checkRseq(const SipMessage& msg); + private: + void startCancelTimer(); + void startStaleCallTimer(); + void sendSipFrag(const SipMessage& response); + + void onConnectedAspect(ClientInviteSessionHandle h, const SipMessage& msg); + void onProvisionalAspect(ClientInviteSessionHandle c, const SipMessage& msg); + void onFailureAspect(ClientInviteSessionHandle c, const SipMessage& msg); + + std::auto_ptr<Contents> mEarlyMedia; + + RAckCategory mRelRespInfo; + unsigned int mStaleCallTimerSeq; + unsigned int mCancelledTimerSeq; + ServerSubscriptionHandle mServerSub; + + // disabled + ClientInviteSession(const ClientInviteSession&); + ClientInviteSession& operator=(const ClientInviteSession&); + + friend class Dialog; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientOutOfDialogReq.cxx b/src/libs/resiprocate/resip/dum/ClientOutOfDialogReq.cxx new file mode 100644 index 00000000..1824a51e --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientOutOfDialogReq.cxx @@ -0,0 +1,159 @@ +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "resip/dum/ClientOutOfDialogReq.hxx" +#include "resip/dum/OutOfDialogHandler.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/Dialog.hxx" +#include "rutil/Logger.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +ClientOutOfDialogReqHandle +ClientOutOfDialogReq::getHandle() +{ + return ClientOutOfDialogReqHandle(mDum, getBaseHandle().getId()); +} + +ClientOutOfDialogReq::ClientOutOfDialogReq(DialogUsageManager& dum, + DialogSet& dialogSet, + const SipMessage& req) + : NonDialogUsage(dum, dialogSet), + mRequest(req) +{ +} + +ClientOutOfDialogReq::~ClientOutOfDialogReq() +{ + mDialogSet.mClientOutOfDialogRequests.remove(this); +} + +void +ClientOutOfDialogReq::end() +{ + delete this; +} + +void +ClientOutOfDialogReq::dispatch(const SipMessage& msg) +{ + assert(msg.isResponse()); + + if (msg.header(h_StatusLine).statusCode() >= 200) + { + OutOfDialogHandler *handler = mDum.getOutOfDialogHandler(msg.header(h_CSeq).method()); + if(handler != NULL) + { + + if(msg.header(h_StatusLine).statusCode() >= 200 && msg.header(h_StatusLine).statusCode() < 300) + { + // Pass Response to Handler + DebugLog ( << "ClientOutOfDialogReq::dispatch - handler found for " + << getMethodName(msg.header(h_CSeq).method()) + << " method success response."); + handler->onSuccess(getHandle(), msg); + } + else + { + // Pass Response to Handler + DebugLog ( << "ClientOutOfDialogReq::dispatch - handler found for " + << getMethodName(msg.header(h_CSeq).method()) + << " method failure response."); + handler->onFailure(getHandle(), msg); + } + } + else + { + DebugLog ( << "ClientOutOfDialogReq::dispatch - handler not found for " + << getMethodName(msg.header(h_CSeq).method()) + << " method response."); + } + + delete this; + } + else + { + // Wait for final response + DebugLog ( << "ClientOutOfDialogReq::dispatch - encountered provisional response" << msg.brief() ); + } +} + +const SipMessage& +ClientOutOfDialogReq::getRequest() const +{ + return mRequest; +} + +void +ClientOutOfDialogReq::dispatch(const DumTimeout& timer) +{ +} + +bool +ClientOutOfDialogReq::matches(const SipMessage& msg) const +{ + return (DialogSetId(mRequest) == DialogSetId(msg)); +} + +EncodeStream& +ClientOutOfDialogReq::dump(EncodeStream& strm) const +{ + strm << "ClientOutOfDialogReq " << getMethodName(mRequest.header(h_RequestLine).method()) + << " cseq=" << mRequest.header(h_CSeq).sequence(); + return strm; +} + + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientOutOfDialogReq.hxx b/src/libs/resiprocate/resip/dum/ClientOutOfDialogReq.hxx new file mode 100644 index 00000000..5fbf1e90 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientOutOfDialogReq.hxx @@ -0,0 +1,94 @@ +#if !defined(RESIP_CLIENTOUTOFDIALOGREQ_HXX) +#define RESIP_CLIENTOUTOFDIALOGREQ_HXX + +#include "resip/dum/NonDialogUsage.hxx" +#include "resip/stack/CSeqCategory.hxx" +#include "resip/stack/SipMessage.hxx" + +namespace resip +{ +class SipMessage; + +class ClientOutOfDialogReq : public NonDialogUsage +{ + public: + ClientOutOfDialogReq(DialogUsageManager& dum, DialogSet& dialogSet, const SipMessage& req); + ClientOutOfDialogReqHandle getHandle(); + + bool matches(const SipMessage& msg) const; + const SipMessage& getRequest() const; + + virtual void end(); + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + virtual EncodeStream& dump(EncodeStream& strm) const; + + protected: + virtual ~ClientOutOfDialogReq(); + + private: + friend class DialogSet; + CSeqCategory mCSeq; + SipMessage mRequest; + + // disabled + ClientOutOfDialogReq(const ClientOutOfDialogReq&); + ClientOutOfDialogReq& operator=(const ClientOutOfDialogReq&); + +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientPagerMessage.cxx b/src/libs/resiprocate/resip/dum/ClientPagerMessage.cxx new file mode 100644 index 00000000..06672341 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientPagerMessage.cxx @@ -0,0 +1,343 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "resip/stack/TransactionUser.hxx" +#include "resip/dum/PagerMessageCreator.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/ClientPagerMessage.hxx" +#include "resip/dum/PagerMessageHandler.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/UsageUseException.hxx" +#include "resip/dum/DumHelper.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/Helper.hxx" + +#ifdef USE_SSL +#include "resip/stack/ssl/Security.hxx" +#endif + +using namespace resip; + +#if(0) +// for appcliation behaves like ICQ +app::onSendButtonClicked(im) +{ + disableSendButton(); + mPageManager.page(im); +} + +app::onSuccess(...) +{ + enableSendButton(); +} + +app::onFailure(...) +{ + reportFailueToUI(); + enableSendButton(); +} + +// for application behaves like MSN +app::onSendButtonClicked(im) +{ + mPageManager.page(im); +} + +app::onSuccess(...) +{ + // most likely no-op +} + +app::onFailure(...) +{ + reportFailueToUI(); +} + +// for application behaves like MSN but wants to limit number of pages queued. +app::onSendButtonClicked(im) +{ + if(mPageManager.msgQueued() > 5 - 1) + { + disableSendButton(); + } + mPageManager.page(im); +} + +app::onSuccess(...) +{ + if(mPageManager.msgQueued() < 5) + { + enableSendButton(); + } +} + +app::onFailure(...) +{ + reportFailueToUI(); + if(mPageManager.msgQueued() < 5) + { + enableSendButton(); + } +} +#endif + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +ClientPagerMessageHandle +ClientPagerMessage::getHandle() +{ + return ClientPagerMessageHandle(mDum, getBaseHandle().getId()); +} + +ClientPagerMessage::ClientPagerMessage(DialogUsageManager& dum, DialogSet& dialogSet) + : NonDialogUsage(dum, dialogSet), + mRequest(dialogSet.getCreator()->getLastRequest()), + mEnded(false) +{ +} + +ClientPagerMessage::~ClientPagerMessage() +{ + this->clearMsgQueued(); + mDialogSet.mClientPagerMessage = 0; +} + +SipMessage& +ClientPagerMessage::getMessageRequest() +{ + return *mRequest; +} + +void +ClientPagerMessage::page(std::auto_ptr<Contents> contents, + DialogUsageManager::EncryptionLevel level) +{ + assert(contents.get() != 0); + bool do_page = mMsgQueue.empty(); + Item item; + item.contents = contents.release(); + item.encryptionLevel = level; + mMsgQueue.push_back(item); + if(do_page) + { + this->pageFirstMsgQueued(); + } +} + +class ClientPagerMessagePageCommand : public DumCommandAdapter +{ +public: + ClientPagerMessagePageCommand(ClientPagerMessage& clientPagerMessage, + std::auto_ptr<Contents> contents, + DialogUsageManager::EncryptionLevel level) + : mClientPagerMessage(clientPagerMessage), + mContents(contents), + mLevel(level) + { + + } + + virtual void executeCommand() + { + mClientPagerMessage.page(mContents, mLevel); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ClientPagerMessagePageCommand"; + } +private: + ClientPagerMessage& mClientPagerMessage; + std::auto_ptr<Contents> mContents; + DialogUsageManager::EncryptionLevel mLevel; +}; + +void +ClientPagerMessage::pageCommand(std::auto_ptr<Contents> contents, + DialogUsageManager::EncryptionLevel level) +{ + mDum.post(new ClientPagerMessagePageCommand(*this, contents, level)); +} + +void +ClientPagerMessage::dispatch(const SipMessage& msg) +{ + assert(msg.isResponse()); + + ClientPagerMessageHandler* handler = mDum.mClientPagerMessageHandler; + assert(handler); + + int code = msg.header(h_StatusLine).statusCode(); + + DebugLog ( << "ClientPagerMessageReq::dispatch(msg)" << msg.brief() ); + { + assert(mMsgQueue.empty() == false); + if (code < 200) + { + DebugLog ( << "ClientPagerMessageReq::dispatch - encountered provisional response" << msg.brief() ); + } + else if (code < 300) + { + if(mMsgQueue.empty() == false) + { + delete mMsgQueue.front().contents; + mMsgQueue.pop_front(); + if(mMsgQueue.empty() == false) + { + this->pageFirstMsgQueued(); + } + + handler->onSuccess(getHandle(), msg); + } + } + else + { + SipMessage errResponse; + MsgQueue::iterator contents; + for(contents = mMsgQueue.begin(); contents != mMsgQueue.end(); ++contents) + { + Contents* p = contents->contents; + WarningLog ( << "Paging failed " << *p ); + Helper::makeResponse(errResponse, *mRequest, code); + handler->onFailure(getHandle(), errResponse, std::auto_ptr<Contents>(p)); + contents->contents = 0; + } + mMsgQueue.clear(); + } + } +} + +void +ClientPagerMessage::dispatch(const DumTimeout& timer) +{ +} + +void +ClientPagerMessage::end() +{ + if(!mEnded) + { + mEnded = true; + mDum.destroy(this); + } +} + +class ClientPagerMessageEndCommand : public DumCommandAdapter +{ +public: + ClientPagerMessageEndCommand(ClientPagerMessage& clientPagerMessage) + : mClientPagerMessage(clientPagerMessage) + { + } + + virtual void executeCommand() + { + mClientPagerMessage.end(); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ClientPagerMessageEndCommand"; + } +private: + ClientPagerMessage& mClientPagerMessage; +}; + +void +ClientPagerMessage::endCommand() +{ + mDum.post(new ClientPagerMessageEndCommand(*this)); +} + +size_t +ClientPagerMessage::msgQueued () const +{ + return mMsgQueue.size(); +} + +void +ClientPagerMessage::pageFirstMsgQueued () +{ + assert(mMsgQueue.empty() == false); + mRequest->header(h_CSeq).sequence()++; + mRequest->setContents(mMsgQueue.front().contents); + DumHelper::setOutgoingEncryptionLevel(*mRequest, mMsgQueue.front().encryptionLevel); + DebugLog(<< "ClientPagerMessage::pageFirstMsgQueued: " << *mRequest); + mDum.send(mRequest); +} + +void +ClientPagerMessage::clearMsgQueued () +{ + MsgQueue::iterator contents; + for(contents = mMsgQueue.begin(); contents != mMsgQueue.end(); ++contents) + { + Contents* p = contents->contents; + delete p; + } + mMsgQueue.clear(); +} + +EncodeStream& +ClientPagerMessage::dump(EncodeStream& strm) const +{ + strm << "ClientPagerMessage queued: " << mMsgQueue.size(); + return strm; +} + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientPagerMessage.hxx b/src/libs/resiprocate/resip/dum/ClientPagerMessage.hxx new file mode 100644 index 00000000..26747c3d --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientPagerMessage.hxx @@ -0,0 +1,128 @@ +#if !defined(RESIP_CLIENTPAGERMESSAGE_HXX) +#define RESIP_CLIENTPAGERMESSAGE_HXX + +#include "resip/dum/NonDialogUsage.hxx" +#include "resip/stack/CSeqCategory.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include <deque> +#include <memory> + +namespace resip +{ +class SipMessage; + +class ClientPagerMessage : public NonDialogUsage +{ + public: + ClientPagerMessage(DialogUsageManager& dum, DialogSet& dialogSet); + ClientPagerMessageHandle getHandle(); + + //allow the user to adorn the MESSAGE message if desired + //!kh! + //I don't know how this would interact with the queuing mechanism. + //Will come back to re-visit this in the future. + SipMessage& getMessageRequest(); + + //!kh! + //queues the message if there is one sent but not yet received a response + //for it. + //asserts if contents->get() is NULL. + virtual void page(std::auto_ptr<Contents> contents, DialogUsageManager::EncryptionLevel level=DialogUsageManager::None); + virtual void end(); + + /** + * Provide asynchronous method access by using command + */ + virtual void endCommand(); + virtual void pageCommand(std::auto_ptr<Contents> contents, DialogUsageManager::EncryptionLevel level=DialogUsageManager::None); + + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + size_t msgQueued () const; + + virtual EncodeStream& dump(EncodeStream& strm) const; + + protected: + virtual ~ClientPagerMessage(); + + private: + friend class DialogSet; + + //uses memory from creator + //SipMessage& mRequest; + SharedPtr<SipMessage> mRequest; + + typedef struct + { + DialogUsageManager::EncryptionLevel encryptionLevel; + Contents* contents; + } Item; + + typedef std::deque<Item> MsgQueue; + MsgQueue mMsgQueue; + bool mEnded; + + // disabled + ClientPagerMessage(const ClientPagerMessage&); + ClientPagerMessage& operator=(const ClientPagerMessage&); + + void pageFirstMsgQueued (); + void clearMsgQueued (); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientPublication.cxx b/src/libs/resiprocate/resip/dum/ClientPublication.cxx new file mode 100644 index 00000000..5348b112 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientPublication.cxx @@ -0,0 +1,406 @@ +#include <cassert> + +#include "resip/stack/Helper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/ClientPublication.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/DumTimeout.hxx" +#include "rutil/Logger.hxx" +#include "resip/dum/PublicationHandler.hxx" + + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +ClientPublicationHandle +ClientPublication::getHandle() +{ + return ClientPublicationHandle(mDum, getBaseHandle().getId()); +} + +ClientPublication::ClientPublication(DialogUsageManager& dum, + DialogSet& dialogSet, + SharedPtr<SipMessage> req) + : NonDialogUsage(dum, dialogSet), + mWaitingForResponse(false), + mPendingPublish(false), + mPublish(req), + mEventType(req->header(h_Event).value()), + mTimerSeq(0), + mDocument(mPublish->releaseContents().release()) +{ + DebugLog( << "ClientPublication::ClientPublication: " << mId); +} + +ClientPublication::~ClientPublication() +{ + DebugLog( << "ClientPublication::~ClientPublication: " << mId); + mDialogSet.mClientPublication = 0; + delete mDocument; +} + +void +ClientPublication::end() +{ + end(false); +} + +void +ClientPublication::end(bool immediate) +{ + InfoLog (<< "End client publication to " << mPublish->header(h_RequestLine).uri()); + if(!immediate) + { + mPublish->header(h_Expires).value() = 0; + send(mPublish); + } + else + { + delete this; + } +} + +class ClientPublicationEndCommand : public DumCommandAdapter +{ +public: + ClientPublicationEndCommand(ClientPublication& clientPublication, bool immediate) + : mClientPublication(clientPublication), mImmediate(immediate) + { + + } + + virtual void executeCommand() + { + mClientPublication.end(mImmediate); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ClientPublicationEndCommand"; + } +private: + ClientPublication& mClientPublication; + bool mImmediate; +}; + +void +ClientPublication::endCommand(bool immediate) +{ + mDum.post(new ClientPublicationEndCommand(*this, immediate)); +} + +void +ClientPublication::dispatch(const SipMessage& msg) +{ + ClientPublicationHandler* handler = mDum.getClientPublicationHandler(mEventType); + assert(handler); + + if (msg.isRequest()) + { + DebugLog( << "Dropping stray request to ClientPublication usage: " << msg); + } + else + { + const int code = msg.header(h_StatusLine).statusCode(); + if (code < 200) + { + return; + } + + assert(code >= 200); + mWaitingForResponse = false; + + if (code < 300) + { + if (mPublish->exists(h_Expires) && mPublish->header(h_Expires).value() == 0) + { + handler->onRemove(getHandle(), msg); + delete this; + return; + } + else if (msg.exists(h_SIPETag) && msg.exists(h_Expires)) + { + mPublish->header(h_SIPIfMatch) = msg.header(h_SIPETag); + if(!mPendingPublish) + { + mPublish->releaseContents(); + } + mDum.addTimer(DumTimeout::Publication, + Helper::aBitSmallerThan(msg.header(h_Expires).value()), + getBaseHandle(), + ++mTimerSeq); + handler->onSuccess(getHandle(), msg); + } + else + { + // Any PUBLISH/200 must have an ETag. This should not happen. Not + // sure what the app can do in this case. + WarningLog (<< "PUBLISH/200 received with no ETag " << mPublish->header(h_From).uri()); + handler->onFailure(getHandle(), msg); + delete this; + return; + } + } + else + { + if (code == 412) + { + InfoLog(<< "SIPIfMatch failed -- republish"); + mPublish->remove(h_SIPIfMatch); + update(mDocument); + return; + } + else if (code == 423) // interval too short + { + if (msg.exists(h_MinExpires)) + { + mPublish->header(h_Expires).value() = msg.header(h_MinExpires).value(); + update(mDocument); // !dys! since contents not released until on success, no need to call update any more. + } + else + { + handler->onFailure(getHandle(), msg); + delete this; + return; + } + } + else if (code == 408 || + (code == 503 && msg.getReceivedTransport() == 0) || + ((code == 404 || + code == 413 || + code == 480 || + code == 486 || + code == 500 || + code == 503 || + code == 600 || + code == 603) && + msg.exists(h_RetryAfter))) + { + int retryMinimum = 0; + if (msg.exists(h_RetryAfter)) + { + retryMinimum = msg.header(h_RetryAfter).value(); + } + + // RFC 3261:20.33 Retry-After + int retry = handler->onRequestRetry(getHandle(), retryMinimum, msg); + if (retry < 0) + { + DebugLog(<< "Application requested failure on Retry-After"); + handler->onFailure(getHandle(), msg); + delete this; + return; + } + else if (retry == 0 && retryMinimum == 0) + { + DebugLog(<< "Application requested immediate retry on Retry-After"); + refresh(); + return; + } + else + { + retry = resipMax(retry, retryMinimum); + DebugLog(<< "Application requested delayed retry on Retry-After: " << retry); + mDum.addTimer(DumTimeout::Publication, + retry, + getBaseHandle(), + ++mTimerSeq); + return; + + } + } + else + { + handler->onFailure(getHandle(), msg); + delete this; + return; + } + + } + + if (mPendingPublish) + { + InfoLog (<< "Sending pending PUBLISH: " << mPublish->brief()); + send(mPublish); + } + } +} + +void +ClientPublication::dispatch(const DumTimeout& timer) +{ + if (timer.seq() == mTimerSeq) + { + refresh(); + } +} + +void +ClientPublication::refresh(unsigned int expiration) +{ + if (expiration == 0 && mPublish->exists(h_Expires)) + { + expiration = mPublish->header(h_Expires).value(); + } + send(mPublish); +} + +class ClientPublicationRefreshCommand : public DumCommandAdapter +{ +public: + ClientPublicationRefreshCommand(ClientPublication& clientPublication, unsigned int expiration) + : mClientPublication(clientPublication), + mExpiration(expiration) + { + + } + + virtual void executeCommand() + { + mClientPublication.refresh(mExpiration); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ClientPublicationRefreshCommand"; + } + +private: + ClientPublication& mClientPublication; + unsigned int mExpiration; +}; + +void +ClientPublication::refreshCommand(unsigned int expiration) +{ + mDum.post(new ClientPublicationRefreshCommand(*this, expiration)); +} + +void +ClientPublication::update(const Contents* body) +{ + InfoLog (<< "Updating presence document: " << mPublish->header(h_To).uri()); + + if (mDocument != body) + { + delete mDocument; + if (body) + { + mDocument = body->clone(); + } + else + { + mDocument = body; + } + } + + mPublish->setContents(mDocument); + send(mPublish); +} + +class ClientPublicationUpdateCommand : public DumCommandAdapter +{ +public: + ClientPublicationUpdateCommand(ClientPublication& clientPublication, const Contents* body) + : mClientPublication(clientPublication), + mBody(body?body->clone():0) + { + + } + + virtual void executeCommand() + { + mClientPublication.update(mBody.get()); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ClientPublicationUpdateCommand"; + } + +private: + ClientPublication& mClientPublication; + std::auto_ptr<Contents> mBody; +}; + +void +ClientPublication::updateCommand(const Contents* body) +{ + mDum.post(new ClientPublicationUpdateCommand(*this, body)); +} + +void +ClientPublication::send(SharedPtr<SipMessage> request) +{ + if (mWaitingForResponse) + { + mPendingPublish = true; + } + else + { + request->header(h_CSeq).sequence()++; + mDum.send(request); + mWaitingForResponse = true; + mPendingPublish = false; + } +} + +EncodeStream& +ClientPublication::dump(EncodeStream& strm) const +{ + strm << "ClientPublication " << mId << " " << mPublish->header(h_From).uri(); + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientPublication.hxx b/src/libs/resiprocate/resip/dum/ClientPublication.hxx new file mode 100644 index 00000000..c602f0df --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientPublication.hxx @@ -0,0 +1,110 @@ +#if !defined(RESIP_CLIENTPUBLICATION_HXX) +#define RESIP_CLIENTPUBLICATION_HXX + +#include "resip/dum/NonDialogUsage.hxx" + +namespace resip +{ + +class ClientPublication : public NonDialogUsage +{ + public: + ClientPublication(DialogUsageManager& dum, DialogSet& dialogSet, SharedPtr<SipMessage> pub); + + typedef Handle<ClientPublication> ClientPublicationHandle; + ClientPublicationHandle getHandle(); + const Data& getEventType() { return mEventType; } + const Contents* getContents() const { return mDocument; } + + //0 means the last value of Expires will be used. + void refresh(unsigned int expiration=0); + void update(const Contents* body); + virtual void end(); + void end(bool immediate); // If immediate is true then usage is destroyed with no further messaging + + /** + * Provide asynchronous method access by using command + */ + void updateCommand(const Contents* body); + void refreshCommand(unsigned int expiration=0); + virtual void endCommand(bool immediate=false); // If immediate is true then usage is destroyed with no further messaging + + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + virtual EncodeStream& dump(EncodeStream& strm) const; + + protected: + virtual ~ClientPublication(); + virtual void send(SharedPtr<SipMessage> request); + + private: + friend class DialogSet; + + bool mWaitingForResponse; + bool mPendingPublish; + + SharedPtr<SipMessage> mPublish; + Data mEventType; + unsigned int mTimerSeq; // expected timer seq (all < are stale) + const Contents* mDocument; + + // disabled + ClientPublication(const ClientPublication&); + ClientPublication& operator=(const ClientPublication&); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientRegistration.cxx b/src/libs/resiprocate/resip/dum/ClientRegistration.cxx new file mode 100644 index 00000000..eabbd448 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientRegistration.cxx @@ -0,0 +1,1022 @@ +#include <algorithm> +#include <iterator> + +#include "resip/stack/Helper.hxx" +#include "resip/stack/ExtensionHeader.hxx" +#include "resip/dum/BaseCreator.hxx" +#include "resip/dum/ClientAuthManager.hxx" +#include "resip/dum/ClientRegistration.hxx" +#include "resip/dum/RegistrationHandler.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/UsageUseException.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/Random.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" +#include "rutil/AtomicCounter.hxx" +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +ClientRegistrationHandle +ClientRegistration::getHandle() +{ + return ClientRegistrationHandle(mDum, getBaseHandle().getId()); +} + +AtomicCounter ClientRegistration::InstanceCounter; + +ClientRegistration::ClientRegistration(DialogUsageManager& dum, + DialogSet& dialogSet, + SharedPtr<SipMessage> request) + : NonDialogUsage(dum, dialogSet), + mLastRequest(request), + mTimerSeq(0), + mState(mLastRequest->exists(h_Contacts) ? Adding : Querying), + mEndWhenDone(false), + mUserRefresh(false), + mRegistrationTime(mDialogSet.mUserProfile->getDefaultRegistrationTime()), + mExpires(0), + mQueuedState(None), + mQueuedRequest(new SipMessage), + mCustomHeader(false) +{ + InstanceCounter.increment(); + // If no Contacts header, this is a query + if (mLastRequest->exists(h_Contacts)) + { + mMyContacts = mLastRequest->header(h_Contacts); + } + + if(mLastRequest->exists(h_Expires) && + mLastRequest->header(h_Expires).isWellFormed()) + { + mRegistrationTime = mLastRequest->header(h_Expires).value(); + } + + mNetworkAssociation.setDum(&dum); +} + +ClientRegistration::~ClientRegistration() +{ + DebugLog ( << "ClientRegistration::~ClientRegistration" ); + mDialogSet.mClientRegistration = 0; + + // !dcm! Will not interact well with multiple registrations from the same AOR + mDialogSet.mUserProfile->setServiceRoute(NameAddrs()); + InstanceCounter.decrement(); +} + +void +ClientRegistration::addBinding(const NameAddr& contact) +{ + addBinding(contact, mDialogSet.mUserProfile->getDefaultRegistrationTime()); +} + +SharedPtr<SipMessage> +ClientRegistration::tryModification(ClientRegistration::State state) +{ + if (mState != Registered) + { + if(mState != RetryAdding && mState != RetryRefreshing) + { + if (mQueuedState != None) + { + WarningLog (<< "Trying to modify bindings when another request is already queued"); + throw UsageUseException("Queuing multiple requests for Registration Bindings", __FILE__,__LINE__); + } + + *mQueuedRequest = *mLastRequest; + mQueuedState = state; + + return mQueuedRequest; + } + else + { + ++mTimerSeq; // disable retry timer + } + } + + assert(mQueuedState == None); + mState = state; + + return mLastRequest; +} + +void +ClientRegistration::addBinding(const NameAddr& contact, UInt32 registrationTime) +{ + SharedPtr<SipMessage> next = tryModification(Adding); + mMyContacts.push_back(contact); + tagContact(mMyContacts.back()); + + next->header(h_Contacts) = mMyContacts; + mRegistrationTime = registrationTime; + next->header(h_Expires).value() = mRegistrationTime; + next->header(h_CSeq).sequence()++; + updateWithCustomHeader(next); + + // caller prefs + + if (mQueuedState == None) + { + send(next); + } +} + +void +ClientRegistration::removeBinding(const NameAddr& contact) +{ + if (mState == Removing) + { + WarningLog (<< "Already removing a binding"); + throw UsageUseException("Can't remove binding when already removing registration bindings", __FILE__,__LINE__); + } + + SharedPtr<SipMessage> next = tryModification(Removing); + for (NameAddrs::iterator i=mMyContacts.begin(); i != mMyContacts.end(); i++) + { + if (i->uri() == contact.uri()) + { + next->header(h_Contacts).clear(); + next->header(h_Contacts).push_back(*i); + next->header(h_Expires).value() = 0; + next->header(h_CSeq).sequence()++; + updateWithCustomHeader(next); + + if (mQueuedState == None) + { + send(next); + } + + mMyContacts.erase(i); + return; + } + } + + // !jf! What state are we left in now? + throw Exception("No such binding", __FILE__, __LINE__); +} + +void +ClientRegistration::removeAll(bool stopRegisteringWhenDone) +{ + if (mState == Removing) + { + WarningLog (<< "Already removing a binding"); + throw UsageUseException("Can't remove binding when already removing registration bindings", __FILE__,__LINE__); + } + + SharedPtr<SipMessage> next = tryModification(Removing); + + mAllContacts.clear(); + mMyContacts.clear(); + + NameAddr all; + all.setAllContacts(); + next->header(h_Contacts).clear(); + next->header(h_Contacts).push_back(all); + next->header(h_Expires).value() = 0; + next->header(h_CSeq).sequence()++; + mEndWhenDone = stopRegisteringWhenDone; + updateWithCustomHeader(next); + if (mQueuedState == None) + { + send(next); + } +} + +void +ClientRegistration::removeMyBindings(bool stopRegisteringWhenDone) +{ + InfoLog (<< "Removing binding"); + + if (mState == Removing) + { + WarningLog (<< "Already removing a binding"); + throw UsageUseException("Can't remove binding when already removing registration bindings", __FILE__,__LINE__); + } + + if (mMyContacts.empty()) + { + WarningLog (<< "No bindings to remove"); + throw UsageUseException("No bindings to remove", __FILE__,__LINE__); + } + + SharedPtr<SipMessage> next = tryModification(Removing); + + next->header(h_Contacts) = mMyContacts; + mMyContacts.clear(); + + NameAddrs& myContacts = next->header(h_Contacts); + + for (NameAddrs::iterator i=myContacts.begin(); i != myContacts.end(); i++) + { + i->param(p_expires) = 0; + } + + next->remove(h_Expires); + next->header(h_CSeq).sequence()++; + + // !jf! is this ok if queued + mEndWhenDone = stopRegisteringWhenDone; + + if (mQueuedState == None) + { + send(next); + } +} + +class ClientRegistrationRemoveMyBindings : public DumCommandAdapter +{ +public: + ClientRegistrationRemoveMyBindings(ClientRegistration& clientRegistration, bool stopRegisteringWhenDone) + : mClientRegistration(clientRegistration), + mStopRegisteringWhenDone(stopRegisteringWhenDone) + { + } + + virtual void executeCommand() + { + mClientRegistration.removeMyBindings(mStopRegisteringWhenDone); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ClientRegistrationRemoveMyBindings"; + } +private: + ClientRegistration& mClientRegistration; + bool mStopRegisteringWhenDone; +}; + +void +ClientRegistration::removeMyBindingsCommand(bool stopRegisteringWhenDone) +{ + mDum.post(new ClientRegistrationRemoveMyBindings(*this, stopRegisteringWhenDone)); +} + +void +ClientRegistration::stopRegistering() +{ + //timers aren't a concern, as DUM checks for Handle validity before firing. + delete this; +} + +void +ClientRegistration::requestRefresh(UInt32 expires) +{ + // Set flag so that handlers get called for success/failure + mUserRefresh = true; + internalRequestRefresh(expires); +} + +void +ClientRegistration::internalRequestRefresh(UInt32 expires) +{ + if(mState == RetryAdding && mState == RetryRefreshing) + { + // disable retry time and try refresh immediately + ++mTimerSeq; + } + else if (mState != Registered) + { + InfoLog (<< "a request is already in progress, no need to refresh " << *this); + return; + } + + InfoLog (<< "requesting refresh of " << *this); + + mState = Refreshing; + mLastRequest->header(h_CSeq).sequence()++; + mLastRequest->header(h_Contacts)=mMyContacts; + + updateWithCustomHeader(mLastRequest); + + if(expires > 0) + { + mRegistrationTime = expires; + } + mLastRequest->header(h_Expires).value()=mRegistrationTime; + + send(mLastRequest); +} + +const NameAddrs& +ClientRegistration::myContacts() +{ + return mMyContacts; +} + +const NameAddrs& +ClientRegistration::allContacts() +{ + return mAllContacts; +} + +UInt32 +ClientRegistration::whenExpires() const +{ +// !cj! - TODO - I'm suspisious these time are getting confused on what units they are in + UInt64 now = Timer::getTimeSecs(); + UInt64 ret = mExpires - now; + return (UInt32)ret; +} + +void +ClientRegistration::end() +{ + removeMyBindings(true); +} + +class ClientRegistrationEndCommand : public DumCommandAdapter +{ +public: + ClientRegistrationEndCommand(ClientRegistration& clientRegistration) + : mClientRegistration(clientRegistration) + { + + } + + virtual void executeCommand() + { + mClientRegistration.end(); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ClientRegistrationEndCommand"; + } +private: + ClientRegistration& mClientRegistration; +}; + +void +ClientRegistration::endCommand() +{ + mDum.post(new ClientRegistrationEndCommand(*this)); +} + +EncodeStream& +ClientRegistration::dump(EncodeStream& strm) const +{ + strm << "ClientRegistration " << mLastRequest->header(h_From).uri(); + return strm; +} + +void +ClientRegistration::dispatch(const SipMessage& msg) +{ + try + { + // !jf! there may be repairable errors that we can handle here + assert(msg.isResponse()); + const int& code = msg.header(h_StatusLine).statusCode(); + bool nextHopSupportsOutbound = false; + int keepAliveTime = 0; + + // If registration was successful - look for next hop indicating support for outbound + if(mDialogSet.mUserProfile->clientOutboundEnabled() && msg.isExternal() && code >= 200 && code < 300) + { + // If ClientOutbound support is enabled and the registration response contains + // Requires: outbound or a Path with outbound then outbound is supported by the + // server, so store the flow key in the UserProfile + // and use it for sending all messages (DialogUsageManager::sendUsingOutboundIfAppropriate) + try + { + if((!msg.empty(h_Paths) && msg.header(h_Paths).back().uri().exists(p_ob)) || + (!msg.empty(h_Requires) && msg.header(h_Requires).find(Token(Symbols::Outbound)))) + { + mDialogSet.mUserProfile->mClientOutboundFlowTuple = msg.getSource(); + mDialogSet.mUserProfile->mClientOutboundFlowTuple.onlyUseExistingConnection = true; + nextHopSupportsOutbound = true; + if(!msg.empty(h_FlowTimer)) + { + keepAliveTime = msg.header(h_FlowTimer).value(); + } + } + } + catch(BaseException&e) + { + ErrLog(<<"Error parsing Path or Requires:" << e); + } + } + + if(msg.isExternal()) + { + const Data& receivedTransport = msg.header(h_Vias).front().transport(); + if(keepAliveTime == 0) + { + if(receivedTransport == Symbols::TCP || + receivedTransport == Symbols::TLS || + receivedTransport == Symbols::SCTP) + { + keepAliveTime = mDialogSet.mUserProfile->getKeepAliveTimeForStream(); + } + else + { + keepAliveTime = mDialogSet.mUserProfile->getKeepAliveTimeForDatagram(); + } + } + + if(keepAliveTime > 0) + { + mNetworkAssociation.update(msg, keepAliveTime, nextHopSupportsOutbound); + } + } + + if (code < 200) + { + // throw it away + return; + } + else if (code < 300) // success + { + try + { + if (msg.exists(h_ServiceRoutes)) + { + InfoLog(<< "Updating service route: " << Inserter(msg.header(h_ServiceRoutes))); + mDialogSet.mUserProfile->setServiceRoute(msg.header(h_ServiceRoutes)); + } + else + { + DebugLog(<< "Clearing service route (" << Inserter(getUserProfile()->getServiceRoute()) << ")"); + mDialogSet.mUserProfile->setServiceRoute(NameAddrs()); + } + } + catch(BaseException &e) + { + ErrLog(<< "Error Parsing Service Route:" << e); + } + + //gruu update, should be optimized + try + { + if(mDialogSet.mUserProfile->gruuEnabled() && msg.exists(h_Contacts)) + { + for (NameAddrs::const_iterator it = msg.header(h_Contacts).begin(); + it != msg.header(h_Contacts).end(); it++) + { + if (it->exists(p_Instance) && it->param(p_Instance) == mDialogSet.mUserProfile->getInstanceId()) + { + if(it->exists(p_pubGruu)) + { + mDialogSet.mUserProfile->setPublicGruu(Uri(it->param(p_pubGruu))); + } + if(it->exists(p_tempGruu)) + { + mDialogSet.mUserProfile->setTempGruu(Uri(it->param(p_tempGruu))); + } + break; + } + } + } + } + catch(BaseException&e) + { + ErrLog(<<"Error parsing GRUU:" << e); + } + + // !jf! consider what to do if no contacts + // !ah! take list of ctcs and push into mMy or mOther as required. + + // make timers to re-register + UInt32 expiry = calculateExpiry(msg); + if(msg.exists(h_Contacts)) + { + mAllContacts = msg.header(h_Contacts); + } + else + { + mAllContacts.clear(); + } + + if (expiry != 0 && expiry != UINT_MAX) + { + if(expiry>=7) + { + int exp = Helper::aBitSmallerThan(expiry); + mExpires = exp + Timer::getTimeSecs(); + mDum.addTimer(DumTimeout::Registration, + exp, + getBaseHandle(), + ++mTimerSeq); + } + else + { + WarningLog(<< "Server is using an unreasonably low expiry: " + << expiry + << " We're just going to end this registration."); + end(); + return; + } + } + + switch (mState) + { + case Querying: + case Adding: + if(expiry != 0) + { + mState = Registered; + mDum.mClientRegistrationHandler->onSuccess(getHandle(), msg); + } + else + { + mDum.mClientRegistrationHandler->onRemoved(getHandle(), msg); + checkProfileRetry(msg); + } + break; + + case Removing: + //mDum.mClientRegistrationHandler->onSuccess(getHandle(), msg); + mDum.mClientRegistrationHandler->onRemoved(getHandle(), msg); + InfoLog (<< "Finished removing registration " << *this << " mEndWhenDone=" << mEndWhenDone); + if (mEndWhenDone) + { + // !kh! + // stopRegistering() deletes 'this' + // furthur processing makes no sense + //assert(mQueuedState == None); + stopRegistering(); + return; + } + break; + + case Registered: + case Refreshing: + mState = Registered; + if(expiry != 0) + { + if(mUserRefresh) + { + mUserRefresh = false; + mDum.mClientRegistrationHandler->onSuccess(getHandle(), msg); + } + } + else + { + mDum.mClientRegistrationHandler->onRemoved(getHandle(), msg); + checkProfileRetry(msg); + } + break; + + default: + break; + } + + if (mQueuedState != None) + { + InfoLog (<< "Sending queued request: " << *mQueuedRequest); + mState = mQueuedState; + mQueuedState = None; + *mLastRequest = *mQueuedRequest; + send(mLastRequest); + } + } + else + { + if((mState == Adding || mState == Refreshing) && !mEndWhenDone) + { + if (code == 423) // interval too short + { + UInt32 maxRegistrationTime = mDialogSet.mUserProfile->getDefaultMaxRegistrationTime(); + if (msg.exists(h_MinExpires) && + (maxRegistrationTime == 0 || msg.header(h_MinExpires).value() < maxRegistrationTime)) // If maxRegistrationTime is enabled, then check it + { + mRegistrationTime = msg.header(h_MinExpires).value(); + mLastRequest->header(h_Expires).value() = mRegistrationTime; + mLastRequest->header(h_CSeq).sequence()++; + send(mLastRequest); + return; + } + } + else if (code == 408 || (code == 503 && msg.getReceivedTransport() == 0)) + { + int retry = mDum.mClientRegistrationHandler->onRequestRetry(getHandle(), 0, msg); + + if (retry < 0) + { + DebugLog(<< "Application requested failure on Retry-After"); + } + else if (retry == 0) + { + DebugLog(<< "Application requested immediate retry on 408 or internal 503"); + + mLastRequest->header(h_CSeq).sequence()++; + send(mLastRequest); + mUserRefresh = true; // Reset this flag, so that the onSuccess callback will be called if we are successful when re-trying + return; + } + else + { + DebugLog(<< "Application requested delayed retry on 408 or internal 503: " << retry); + mExpires = 0; + switch(mState) + { + case Adding: + mState = RetryAdding; + break; + case Refreshing: + mState = RetryRefreshing; + break; + default: + assert(false); + break; + } + if(mDum.mClientAuthManager.get()) mDum.mClientAuthManager.get()->clearAuthenticationState(DialogSetId(*mLastRequest)); + mDum.addTimer(DumTimeout::RegistrationRetry, + retry, + getBaseHandle(), + ++mTimerSeq); + mUserRefresh = true; // Reset this flag, so that the onSuccess callback will be called if we are successful when re-trying + return; + } + } + } + + mDum.mClientRegistrationHandler->onFailure(getHandle(), msg); + mUserRefresh = true; // Reset this flag, so that the onSuccess callback will be called if we are successful when re-trying + + // Retry if Profile setting is set + unsigned int retryInterval = checkProfileRetry(msg); + if(retryInterval > 0) + { + InfoLog( << "Registration error " << code << " for " << msg.header(h_To) << ", retrying in " << retryInterval << " seconds."); + return; + } + + // assume that if a failure occurred, the bindings are gone + if (mEndWhenDone) + { + mDum.mClientRegistrationHandler->onRemoved(getHandle(), msg); + } + delete this; + } + } + catch(BaseException& e) + { + InfoLog( << "Exception in ClientRegistration::dispatch: " << e.getMessage()); + mDum.mClientRegistrationHandler->onFailure(getHandle(), msg); + delete this; + } +} + +void +ClientRegistration::tagContact(NameAddr& contact) const +{ + tagContact(contact, mDum, mDialogSet.mUserProfile); +} + +void +ClientRegistration::tagContact(NameAddr& contact, DialogUsageManager& dum, SharedPtr<UserProfile>& userProfile) +{ + if(contact.uri().host().empty() || + dum.getSipStack().isMyDomain(contact.uri().host(), contact.uri().port())) + { + // Contact points at us; it is appropriate to add a +sip.instance to + // this Contact. We don't need to have full gruu support enabled to add + // a +sip.instance either... + if(userProfile->hasInstanceId()) + { + contact.param(p_Instance) = userProfile->getInstanceId(); + if(userProfile->getRegId() != 0) + { + contact.param(p_regid) = userProfile->getRegId(); + } + } + else if(userProfile->getRinstanceEnabled()) + { + // !slg! poor mans instance id so that we can tell which contacts + // are ours - to be replaced by gruu someday. + InfoLog(<< "You really should consider setting an instance id in" + " the UserProfile (see UserProfile::setInstanceId())." + " This is really easy, and makes this class much less " + "likely to clash with another endpoint registering at " + "the same AOR."); + contact.uri().param(p_rinstance) = Random::getCryptoRandomHex(8); + } + else if(!contact.uri().user().empty()) + { + WarningLog(<< "Ok, not only have you not specified an instance id, " + "you have disabled the rinstance hack (ie; resip's \"poor" + " man's +sip.instance\"). We will try to match Contacts" + " based on what you've put in the user-part of your " + "Contact, but this can be dicey, especially if you've put" + " something there that another endpoint is likely to " + "use."); + } + else + { + ErrLog(<< "Ok, not only have you not specified an instance id, " + "you have disabled the rinstance hack (ie; resip's \"poor" + " man's +sip.instance\"), _and_ you haven't put anything" + " in the user-part of your Contact. This is asking for " + "confusion later. We'll do our best to try to match things" + " up later when the response comes in..."); + } + } + else + { + // Looks like a third-party registration. +sip.instance is out of the + // question, but we can still use rinstance. + if(userProfile->getRinstanceEnabled()) + { + // !slg! poor mans instance id so that we can tell which contacts + // are ours - to be replaced by gruu someday. + contact.uri().param(p_rinstance) = Random::getCryptoRandomHex(8); + } + else if(!contact.uri().user().empty()) + { + WarningLog(<< "You're trying to do a third-party registration, but " + "you have disabled the rinstance hack (ie; resip's \"poor" + " man's +sip.instance\"). We will try to match Contacts" + " based on what you've put in the user-part of your " + "Contact, but this can be dicey, especially if you've put" + " something there that another endpoint is likely to " + "use."); + } + else + { + ErrLog(<< "You're trying to do a third-party registration, and " + "not only have you disabled the rinstance hack (ie; " + "resip's \"poor man's +sip.instance\"), you haven't" + " put anything in the user-part of your Contact. This is " + "asking for confusion later. We'll do our best to try to " + "match things up later when the response comes in..."); + } + } + + if (userProfile->getMethodsParamEnabled()) + { + contact.param(p_methods) = dum.getMasterProfile()->getAllowedMethodsData(); + } + + // ?bwc? Host and port override? +} + +unsigned long +ClientRegistration::calculateExpiry(const SipMessage& reg200) const +{ + unsigned long expiry=mRegistrationTime; + if(reg200.exists(h_Expires) && + reg200.header(h_Expires).isWellFormed() && + reg200.header(h_Expires).value() < expiry) + { + expiry=reg200.header(h_Expires).value(); + } + + if(!reg200.exists(h_Contacts)) + { + return expiry; + } + + const NameAddrs& contacts(reg200.header(h_Contacts)); + + for(NameAddrs::const_iterator c=contacts.begin();c!=contacts.end();++c) + { + // Our expiry is never going to increase if we find one of our contacts, + // so if the expiry is not lower, we just ignore it. For registrars that + // leave our requested expiry alone, this code ends up being pretty quick, + // especially if there aren't contacts from other endpoints laying around. + if(c->isWellFormed() && + c->exists(p_expires) && + c->param(p_expires) < expiry && + contactIsMine(*c)) + { + expiry=c->param(p_expires); + } + } + return expiry; +} + +bool +ClientRegistration::contactIsMine(const NameAddr& contact) const +{ + // Try to find this contact in mMyContacts + if(mDialogSet.mUserProfile->hasInstanceId() && + contact.exists(p_Instance)) + { + return contact.param(p_Instance)==mDialogSet.mUserProfile->getInstanceId(); + } + else if(mDialogSet.mUserProfile->getRinstanceEnabled() && + contact.uri().exists(p_rinstance)) + { + return rinstanceIsMine(contact.uri().param(p_rinstance)); + } + else + { + return searchByUri(contact.uri()); + } +} + +bool +ClientRegistration::rinstanceIsMine(const Data& rinstance) const +{ + // !bwc! This could be made faster if we used a single rinstance... + for(NameAddrs::const_iterator m=mMyContacts.begin(); m!=mMyContacts.end(); ++m) + { + if(m->uri().exists(p_rinstance) && m->uri().param(p_rinstance)==rinstance) + { + return true; + } + } + return false; +} + +bool +ClientRegistration::searchByUri(const Uri& cUri) const +{ + for(NameAddrs::const_iterator m=mMyContacts.begin(); m!=mMyContacts.end(); ++m) + { + if(m->uri()==cUri) + { + return true; + } + else if(m->uri().host().empty() && + m->uri().user()==cUri.user() && + m->uri().scheme()==cUri.scheme() && + mDum.getSipStack().isMyDomain(cUri.host(), cUri.port())) + { + // Empty host-part in our contact; this means we're relying on the + // stack to fill out this Contact header. Also, the user-part matches. + return true; + } + } + return false; +} + +unsigned int +ClientRegistration::checkProfileRetry(const SipMessage& msg) +{ + unsigned int retryInterval = mDialogSet.mUserProfile->getDefaultRegistrationRetryTime(); + if (retryInterval > 0 && + (mState == Adding || mState == Refreshing) && + !mEndWhenDone) + { + if (msg.exists(h_RetryAfter) && msg.header(h_RetryAfter).value() > 0) + { + // Use retry interval from error response + retryInterval = msg.header(h_RetryAfter).value(); + } + mExpires = 0; + switch(mState) + { + case Adding: + mState = RetryAdding; + break; + case Refreshing: + mState = RetryRefreshing; + break; + default: + assert(false); + break; + } + + if(mDum.mClientAuthManager.get()) mDum.mClientAuthManager.get()->clearAuthenticationState(DialogSetId(*mLastRequest)); + mDum.addTimer(DumTimeout::RegistrationRetry, + retryInterval, + getBaseHandle(), + ++mTimerSeq); + return retryInterval; + } + return 0; +} + +void +ClientRegistration::dispatch(const DumTimeout& timer) +{ + switch(timer.type()) + { + case DumTimeout::Registration: + // If you happen to be Adding/Updating when the timer goes off, you should just ignore + // it since a new timer will get added when the 2xx is received. + if (timer.seq() == mTimerSeq && mState == Registered) + { + if (!mMyContacts.empty()) + { + internalRequestRefresh(); + } + } + break; + + case DumTimeout::RegistrationRetry: + if (timer.seq() == mTimerSeq) + { + switch(mState) + { + case RetryAdding: + mState = Adding; + break; + case RetryRefreshing: + mState = Refreshing; + break; + default: + assert(false); + break; + } + + // Resend last request + mLastRequest->header(h_CSeq).sequence()++; + mLastRequest->remove(h_ProxyAuthorizations); + mLastRequest->remove(h_Authorizations); + send(mLastRequest); + } + break; + default: + break; + } +} + +void +ClientRegistration::flowTerminated() +{ + // Clear the network association + mNetworkAssociation.clear(); + + // Notify application - not default handler implementation is to immediately attempt + // a re-registration in order to form a new flow + mDum.mClientRegistrationHandler->onFlowTerminated(getHandle()); +} + +void +ClientRegistration::setCustomHeader(const resip::Data& name, const resip::Data& value) +{ + mCustomHeader = true; + mCustomHeaderName = name; + mCustomHeaderValue = value; +} + +void +ClientRegistration::unsetCustomHeader() +{ + mCustomHeader = false; +} + +void +ClientRegistration::updateWithCustomHeader(SharedPtr<SipMessage> msg) +{ + if (mCustomHeader) + { + ExtensionHeader hdr(mCustomHeaderName); + msg->header(hdr).clear(); + StringCategory sc(mCustomHeaderValue); + msg->header(hdr).push_back(sc); + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/dum/ClientRegistration.hxx b/src/libs/resiprocate/resip/dum/ClientRegistration.hxx new file mode 100644 index 00000000..3c6476b1 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientRegistration.hxx @@ -0,0 +1,185 @@ +#if !defined(RESIP_CLIENTREGISTRATION_HXX) +#define RESIP_CLIENTREGISTRATION_HXX + +#include "resip/dum/NonDialogUsage.hxx" +#include "resip/stack/NameAddr.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/NetworkAssociation.hxx" + +namespace resip +{ + +class SipMessage; +class BaseCreator; +class AtomicCounter; + +//!dcm! -- shutdown/deletion API -- end? +class ClientRegistration: public NonDialogUsage +{ + public: + static AtomicCounter InstanceCounter; + + //ClientRegistration(DialogUsageManager& dum, DialogSet& dialog, + //SipMessage& req); + ClientRegistration(DialogUsageManager& dum, DialogSet& dialog, SharedPtr<SipMessage> req); + ClientRegistrationHandle getHandle(); + + /** Adds a registration binding, using the registration from the UserProfile */ + void addBinding(const NameAddr& contact); + + /** Adds a registration binding, using the specified registration time */ + void addBinding(const NameAddr& contact, UInt32 registrationTime); + + /** Removes one particular binding */ + void removeBinding(const NameAddr& contact); + + /** Removes all bindings associated with the AOR - even those that may have been + by a another UA. Note: Set's contact header to '*'. Set flag to true + to end the usage when complete. */ + void removeAll(bool stopRegisteringWhenDone=false); + + /** Removes all bindings added by addBinding. Set flag to true to end the usage + when complete */ + void removeMyBindings(bool stopRegisteringWhenDone=false); + + + /** Request a manual refresh of the registration. If 0 then default to using original + expires value (to remove use removeXXX() instead) */ + void requestRefresh(UInt32 expires = 0); + + /** kills the usgage, does not unregister, call removeMyBindings to unregister */ + void stopRegistering(); + + /** returns a list of contacts added by addBinding */ + const NameAddrs& myContacts(); + + /** returns a list of all contacts for this AOR - may include those added by other UA's */ + const NameAddrs& allContacts(); + + /** returns the number of seconds until the registration expires - relative */ + UInt32 whenExpires() const; + + /** Calls removeMyBindings and ends usage when complete */ + virtual void end(); + + /** + * Provide asynchronous method access by using command + */ + void removeMyBindingsCommand(bool stopRegisteringWhenDone=false); + virtual void endCommand(); + + + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + virtual EncodeStream& dump(EncodeStream& strm) const; + void setCustomHeader(const resip::Data& name, const resip::Data& value); + void unsetCustomHeader(); + + static void tagContact(NameAddr& contact, DialogUsageManager& dum, SharedPtr<UserProfile>& userProfile); + + protected: + virtual ~ClientRegistration(); + + private: + typedef enum + { + Querying, + Adding, + Refreshing, + Registered, + Removing, + RetryAdding, // Waiting to retry an add + RetryRefreshing, // Waiting to retry a refresh + None // for queued only + } State; + + SharedPtr<SipMessage> tryModification(ClientRegistration::State state); + void internalRequestRefresh(UInt32 expires = 0); // 0 defaults to using original expires value (to remove use removeXXX() instead) + unsigned int checkProfileRetry(const SipMessage& msg); + void tagContact(NameAddr& contact) const; + unsigned long calculateExpiry(const SipMessage& reg200) const; + bool contactIsMine(const NameAddr& contact) const; + bool rinstanceIsMine(const Data& rinstance) const; + bool searchByUri(const Uri& cUri) const; + void updateWithCustomHeader(SharedPtr<SipMessage> msg); + + friend class DialogSet; + void flowTerminated(); + + //SipMessage& mLastRequest; + SharedPtr<SipMessage> mLastRequest; + NameAddrs mMyContacts; // Contacts that this UA is requesting + NameAddrs mAllContacts; // All the contacts Registrar knows about + unsigned int mTimerSeq; // expected timer seq (all < are stale) + + State mState; + bool mEndWhenDone; + bool mUserRefresh; + UInt32 mRegistrationTime; + UInt64 mExpires; + State mQueuedState; + SharedPtr<SipMessage> mQueuedRequest; + resip::Data mCustomHeaderName, mCustomHeaderValue; + bool mCustomHeader; + NetworkAssociation mNetworkAssociation; + + // disabled + ClientRegistration(const ClientRegistration&); + ClientRegistration& operator=(const ClientRegistration&); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientSubscription.cxx b/src/libs/resiprocate/resip/dum/ClientSubscription.cxx new file mode 100644 index 00000000..f98c96f5 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientSubscription.cxx @@ -0,0 +1,905 @@ +#include <queue> + +#include "resip/stack/Helper.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/SipFrag.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/ClientSubscription.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/SubscriptionHandler.hxx" +#include "resip/dum/SubscriptionCreator.hxx" +#include "resip/dum/UsageUseException.hxx" + +#include "resip/dum/AppDialogSet.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + + +ClientSubscription::ClientSubscription(DialogUsageManager& dum, Dialog& dialog, + const SipMessage& request, UInt32 defaultSubExpiration) + : BaseSubscription(dum, dialog, request), + mOnNewSubscriptionCalled(mEventType == "refer"), // don't call onNewSubscription for Refer subscriptions + mEnded(false), + mNextRefreshSecs(0), + mLastSubSecs(Timer::getTimeSecs()), // Not exactly, but more forgiving + mDefaultExpires(defaultSubExpiration), + mRefreshing(false), + mHaveQueuedRefresh(false), + mQueuedRefreshInterval(-1), + mLargestNotifyCSeq(0) +{ + DebugLog (<< "ClientSubscription::ClientSubscription from " << request.brief()); + if(request.method() == SUBSCRIBE) + { + *mLastRequest = request; + if (defaultSubExpiration > 0) + { + mLastRequest->header(h_Expires).value() = defaultSubExpiration; + } + } + else + { + // If a NOTIFY request is use to make this ClientSubscription, then create the implied SUBSCRIBE + // request as the mLastRequest + mDialog.makeRequest(*mLastRequest, SUBSCRIBE); + } +} + +ClientSubscription::~ClientSubscription() +{ + mDialog.mClientSubscriptions.remove(this); + + while (!mQueuedNotifies.empty()) + { + delete mQueuedNotifies.front(); + mQueuedNotifies.pop_front(); + } + + clearDustbin(); +} + +ClientSubscriptionHandle +ClientSubscription::getHandle() +{ + return ClientSubscriptionHandle(mDum, getBaseHandle().getId()); +} + +void +ClientSubscription::dispatch(const SipMessage& msg) +{ + DebugLog (<< "ClientSubscription::dispatch " << msg.brief()); + + ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); + assert(handler); + + clearDustbin(); + + // asserts are checks the correctness of Dialog::dispatch + if (msg.isRequest() ) + { + assert( msg.header(h_RequestLine).getMethod() == NOTIFY ); + mRefreshing = false; + + // !dlb! 481 NOTIFY iff state is dead? + + //!dcm! -- heavy, should just store enough information to make response + //mLastNotify = msg; + + if (!mOnNewSubscriptionCalled && !getAppDialogSet()->isReUsed()) + { + InfoLog (<< "[ClientSubscription] " << mLastRequest->header(h_To)); + if (msg.exists(h_Contacts)) + { + mDialog.mRemoteTarget = msg.header(h_Contacts).front(); + } + + handler->onNewSubscription(getHandle(), msg); + mOnNewSubscriptionCalled = true; + } + + bool outOfOrder = mLargestNotifyCSeq > msg.header(h_CSeq).sequence(); + if (!outOfOrder) + { + mLargestNotifyCSeq = msg.header(h_CSeq).sequence(); + } + else + { + DebugLog(<< "received out of order notify"); + } + + mQueuedNotifies.push_back(new QueuedNotify(msg, outOfOrder)); + if (mQueuedNotifies.size() == 1) + { + DebugLog(<< "no queued notify"); + processNextNotify(); + return; + } + else + { + DebugLog(<< "Notify gets queued"); + } + } + else + { + DebugLog(<< "processing client subscription response"); + processResponse(msg); + } +} + +void +ClientSubscription::processResponse(const SipMessage& msg) +{ + ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); + assert(handler); + + mRefreshing = false; + int statusCode = msg.header(h_StatusLine).statusCode(); + + if (statusCode >= 200 && statusCode <300) + { + if (msg.exists(h_Expires)) + { + // grab the expires from the 2xx in case there is not one on the NOTIFY .mjf. + UInt32 expires = msg.header(h_Expires).value(); + UInt32 lastExpires = mLastRequest->header(h_Expires).value(); + if (expires < lastExpires) + { + mLastRequest->header(h_Expires).value() = expires; + } + } + + if(!mOnNewSubscriptionCalled) + { + // Timer for initial NOTIFY; since we don't know when the initial + // SUBSRIBE is sent, we have to set the timer when the 200 comes in, if + // it beat the NOTIFY. + mDum.addTimer(DumTimeout::WaitForNotify, + 64*Timer::T1, + getBaseHandle(), + ++mTimerSeq); + } + + sendQueuedRefreshRequest(); + } + else if (!mEnded && + statusCode == 481 && + msg.exists(h_Expires) && msg.header(h_Expires).value() > 0) + { + InfoLog (<< "Received 481 to SUBSCRIBE, reSUBSCRIBEing (presence server probably restarted) " + << mLastRequest->header(h_To)); + + reSubscribe(); // will delete "this" + return; + } + else if (!mEnded && + (statusCode == 408 || + (statusCode == 503 && msg.getReceivedTransport() == 0) || + ((statusCode == 413 || + statusCode == 480 || + statusCode == 486 || + statusCode == 500 || + statusCode == 503 || + statusCode == 600 || + statusCode == 603) && + msg.exists(h_RetryAfter)))) + { + int retry; + int retryAfter = 0; + if(msg.exists(h_RetryAfter)) + { + retryAfter = msg.header(h_RetryAfter).value(); + } + + InfoLog (<< "Received " << statusCode << " to SUBSCRIBE " + << mLastRequest->header(h_To)); + retry = handler->onRequestRetry(getHandle(), retryAfter, msg); + + if (retry < 0) + { + DebugLog(<< "Application requested failure on Retry-After"); + mEnded = true; + handler->onTerminated(getHandle(), &msg); + delete this; + return; + } + else if (retry == 0) + { + DebugLog(<< "Application requested immediate retry on Retry-After"); + + if (mOnNewSubscriptionCalled) + { + // If we already have a dialog, then just refresh again + requestRefresh(); + } + else + { + reSubscribe(); // will delete "this" + return; + } + } + else + { + // leave the usage around until the timeout + // !dlb! would be nice to set the state to something dead, but not used + mDum.addTimer(DumTimeout::SubscriptionRetry, + retry, + getBaseHandle(), + ++mTimerSeq); + // leave the usage around until the timeout + return; + } + } + else if (msg.header(h_StatusLine).statusCode() >= 300) + { + if (msg.header(h_StatusLine).statusCode() == 423 + && msg.exists(h_MinExpires)) + { + requestRefresh(msg.header(h_MinExpires).value()); + } + else + { + mEnded = true; + handler->onTerminated(getHandle(), &msg); + delete this; + return; + } + } +} + +void +ClientSubscription::processNextNotify() +{ + //!dcm! There is a timing issue in this code which can cause this to be + //!called when there are no queued NOTIFY messages. Probably a subscription + //!teardown/timer crossover. + //assert(!mQueuedNotifies.empty()); + if (mQueuedNotifies.empty()) + { + return; + } + + QueuedNotify* qn = mQueuedNotifies.front(); + ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); + assert(handler); + + unsigned long refreshInterval = 0; + bool setRefreshTimer=false; + if (!qn->outOfOrder()) + { + UInt32 expires = 0; + //default to 3600 seconds so non-compliant endpoints don't result in leaked usages + if (qn->notify().exists(h_SubscriptionState) && qn->notify().header(h_SubscriptionState).exists(p_expires)) + { + expires = qn->notify().header(h_SubscriptionState).param(p_expires); + } + else if (mLastRequest->exists(h_Expires)) + { + expires = mLastRequest->header(h_Expires).value(); + } + else if (mDefaultExpires) + { + /* if we haven't gotten an expires value from: + 1. the subscription state from this notify + 2. the last request + then use the default expires (meaning it came from the 2xx in response + to the initial SUBSCRIBE). .mjf. + */ + expires = mDefaultExpires; + } + else + { + expires = 3600; + } + + if (!mLastRequest->exists(h_Expires)) + { + DebugLog(<< "No expires header in last request, set to " << expires); + mLastRequest->header(h_Expires).value() = expires; + } + + if(!qn->notify().exists(h_SubscriptionState) || + !isEqualNoCase(qn->notify().header(h_SubscriptionState).value(), Symbols::Terminated)) + { + // Don't do this stuff for a NOTIFY terminated. + UInt64 now = Timer::getTimeSecs(); + refreshInterval = Helper::aBitSmallerThan((signed long)expires); + + if (mNextRefreshSecs == 0 || now + refreshInterval < mNextRefreshSecs) + { + mNextRefreshSecs = now + refreshInterval; + setRefreshTimer = true; + } + } + } + //if no subscription state header, treat as an extension. Only allow for + //refer to handle non-compliant implementations + if (!qn->notify().exists(h_SubscriptionState)) + { + if (qn->notify().exists(h_Event) && qn->notify().header(h_Event).value() == "refer") + { + SipFrag* frag = dynamic_cast<SipFrag*>(qn->notify().getContents()); + if (frag) + { + if (frag->message().isResponse()) + { + int code = frag->message().header(h_StatusLine).statusCode(); + if (code < 200) + { + handler->onUpdateExtension(getHandle(), qn->notify(), qn->outOfOrder()); + } + else + { + acceptUpdate(); + mEnded = true; + handler->onTerminated(getHandle(), &qn->notify()); + delete this; + } + } + else + { + acceptUpdate(); + mEnded = true; + handler->onTerminated(getHandle(), &qn->notify()); + delete this; + } + } + else + { + acceptUpdate(); + mEnded = true; + handler->onTerminated(getHandle(), &qn->notify()); + delete this; + } + } + else + { + mDialog.makeResponse(*mLastResponse, qn->notify(), 400); + mLastResponse->header(h_StatusLine).reason() = "Missing Subscription-State header"; + send(mLastResponse); + mEnded = true; + handler->onTerminated(getHandle(), &qn->notify()); + delete this; + } + return; + } + + if (!mEnded && isEqualNoCase(qn->notify().header(h_SubscriptionState).value(), Symbols::Active)) + { + if (setRefreshTimer) + { + scheduleRefresh(refreshInterval); + } + + handler->onUpdateActive(getHandle(), qn->notify(), qn->outOfOrder()); + } + else if (!mEnded && isEqualNoCase(qn->notify().header(h_SubscriptionState).value(), Symbols::Pending)) + { + if (setRefreshTimer) + { + scheduleRefresh(refreshInterval); + } + + handler->onUpdatePending(getHandle(), qn->notify(), qn->outOfOrder()); + } + else if (isEqualNoCase(qn->notify().header(h_SubscriptionState).value(), Symbols::Terminated)) + { + if(mLastRequest->header(h_Expires).value()!=0 && + isEqualNoCase(qn->notify().header(h_SubscriptionState).param(p_reason), "timeout")) + { + // Unexpected timeout of some sort. Look closer. + if(mNextRefreshSecs==0) + { + // No refresh scheduled; maybe we are trying to avoid a tight SUB/ + // NOT loop here? + if(Helper::aBitSmallerThan((signed long)(Timer::getTimeSecs() - mLastSubSecs)) < 2) + { + acceptUpdate(200, "I just sent a refresh, what more do you want " + "from me?"); + } + else + { + acceptUpdate(200, "Why didn't I refresh here?"); + } + } + else + { + acceptUpdate(200, "You terminated my subscription early! What " + "gives?"); + } + } + else + { + acceptUpdate(); + } + mEnded = true; + handler->onTerminated(getHandle(), &qn->notify()); + DebugLog (<< "[ClientSubscription] " << mLastRequest->header(h_To) << "[ClientSubscription] Terminated"); + delete this; + return; + } + else if (!mEnded) + { + handler->onUpdateExtension(getHandle(), qn->notify(), qn->outOfOrder()); + } + else if (mEnded) + { + // We received a NOTIFY message when we thought the subscription was + // ended. This can happen, for example, when a previously sent NOTIFY gets + // resent while we (ClientSubscription) are trying to terminate the + // subscription. If we don't accept/reject this NOTIFY, it will stay into + // the mQueuedNotifies queue and we'll never terminate the subscription + // even if the server sends a NOTIFY/terminated. All received NOTIFY would + // get piled up on mQueuedNotifies and they will never get processed. + // + // Note that if that NOTIFY is in fact the terminated one, it will get + // caught by another if statement above and acted upon appropriately. + // + //!fjoanis! Is 481 a proper error code in this case? + InfoLog(<< "[ClientSubscription] received NOTIFY when subscription was ended, rejecting it..."); + rejectUpdate(481); + } +} + +void +ClientSubscription::dispatch(const DumTimeout& timer) +{ + if (timer.seq() == mTimerSeq) + { + if(timer.type() == DumTimeout::WaitForNotify) + { + ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); + if(mOnNewSubscriptionCalled && mEnded) + { + // NOTIFY terminated didn't come in + handler->onTerminated(getHandle(),0); + delete this; + return; + } + + // Initial NOTIFY never came in; let app decide what to do + handler->onNotifyNotReceived(getHandle()); + } + else if (timer.type() == DumTimeout::SubscriptionRetry) + { + // this indicates that the ClientSubscription was created by a 408 + if (mOnNewSubscriptionCalled) + { + InfoLog(<< "ClientSubscription: application retry refresh"); + requestRefresh(); + } + else + { + InfoLog(<< "ClientSubscription: application retry new request"); + reSubscribe(); // will delete "this" + return; + } + } + else if(timer.type() == DumTimeout::Subscription) + { + requestRefresh(); + } + } + else if(timer.seq() == 0 && timer.type() == DumTimeout::SendNextNotify) + { + DebugLog(<< "got DumTimeout::SendNextNotify"); + processNextNotify(); + } +} + +void +ClientSubscription::requestRefresh(UInt32 expires) +{ + if (!mEnded) + { + if (mRefreshing) + { + DebugLog(<< "queue up refresh request"); + mHaveQueuedRefresh = true; + mQueuedRefreshInterval = expires; + return; + } + + mDialog.makeRequest(*mLastRequest, SUBSCRIBE); + //!dcm! -- need a mechanism to retrieve this for the event package...part of + //the map that stores the handlers, or part of the handler API + if(expires > 0) + { + mLastRequest->header(h_Expires).value() = expires; + } + mNextRefreshSecs = 0; + InfoLog (<< "Refresh subscription: " << mLastRequest->header(h_Contacts).front()); + mRefreshing = true; + mLastSubSecs = Timer::getTimeSecs(); + send(mLastRequest); + // Timer for reSUB NOTIFY. + mDum.addTimer(DumTimeout::WaitForNotify, + 64*Timer::T1, + getBaseHandle(), + ++mTimerSeq); + } +} + +class ClientSubscriptionRefreshCommand : public DumCommandAdapter +{ +public: + ClientSubscriptionRefreshCommand(ClientSubscription& clientSubscription, UInt32 expires) + : mClientSubscription(clientSubscription), + mExpires(expires) + { + + } + virtual void executeCommand() + { + mClientSubscription.requestRefresh(mExpires); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ClientSubscriptionRefreshCommand"; + } +private: + ClientSubscription& mClientSubscription; + UInt32 mExpires; +}; + +void +ClientSubscription::requestRefreshCommand(UInt32 expires) +{ + mDum.post(new ClientSubscriptionRefreshCommand(*this, expires)); +} + +void +ClientSubscription::end() +{ + end(false /* immediate? */); +} + +void +ClientSubscription::end(bool immediate) +{ + InfoLog (<< "End subscription: " << mLastRequest->header(h_RequestLine).uri()); + + if (!mEnded) + { + if(!immediate) + { + mDialog.makeRequest(*mLastRequest, SUBSCRIBE); + mLastRequest->header(h_Expires).value() = 0; + mEnded = true; + send(mLastRequest); + // Timer for NOTIFY terminated + mDum.addTimer(DumTimeout::WaitForNotify, + 64*Timer::T1, + getBaseHandle(), + ++mTimerSeq); + } + else + { + delete this; + } + } +} + +class ClientSubscriptionEndCommand : public DumCommandAdapter +{ +public: + ClientSubscriptionEndCommand(ClientSubscription& clientSubscription, bool immediate) + :mClientSubscription(clientSubscription), mImmediate(immediate) + { + + } + + virtual void executeCommand() + { + mClientSubscription.end(mImmediate); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ClientSubscriptionEndCommand"; + } +private: + ClientSubscription& mClientSubscription; + bool mImmediate; +}; + +void +ClientSubscription::endCommand(bool immediate) +{ + mDum.post(new ClientSubscriptionEndCommand(*this, immediate)); +} + +void +ClientSubscription::acceptUpdate(int statusCode, const char* reason) +{ + assert(!mQueuedNotifies.empty()); + if (mQueuedNotifies.empty()) + { + InfoLog(<< "No queued notify to accept"); + return; + } + + QueuedNotify* qn = mQueuedNotifies.front(); + mQueuedNotifies.pop_front(); + mDustbin.push_back(qn); + mDialog.makeResponse(*mLastResponse, qn->notify(), statusCode); + if(reason) + { + mLastResponse->header(h_StatusLine).reason()=reason; + } + send(mLastResponse); +} + +class ClientSubscriptionAcceptUpdateCommand : public DumCommandAdapter +{ +public: + ClientSubscriptionAcceptUpdateCommand(ClientSubscription& clientSubscription, int statusCode, const char* reason) + : mClientSubscription(clientSubscription), + mStatusCode(statusCode), + mReason(reason ? Data(reason) : Data::Empty) + { + + } + + virtual void executeCommand() + { + mClientSubscription.acceptUpdate(mStatusCode, mReason.c_str()); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ClientSubscriptionAcceptUpdateCommand"; + } +private: + ClientSubscription& mClientSubscription; + int mStatusCode; + Data mReason; +}; + +void +ClientSubscription::acceptUpdateCommand(int statusCode, const char* reason) +{ + mDum.post(new ClientSubscriptionAcceptUpdateCommand(*this, statusCode, reason)); +} + +void +ClientSubscription::reSubscribe() +{ + NameAddr target(mLastRequest->header(h_To)); + target.remove(p_tag); // ensure To tag is removed + SharedPtr<SipMessage> sub = mDum.makeSubscription(target, getUserProfile(), getEventType(), getAppDialogSet()->reuse()); + mDum.send(sub); + + delete this; +} + +void +ClientSubscription::send(SharedPtr<SipMessage> msg) +{ + DialogUsage::send(msg); + + if (!mEnded) + { + if (!mQueuedNotifies.empty() && msg->isResponse()) + { + mDum.addTimer(DumTimeout::SendNextNotify, + 0, + getBaseHandle(), + 0); + } + } + +} + +void +ClientSubscription::rejectUpdate(int statusCode, const Data& reasonPhrase) +{ + ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); + assert(handler); + assert(!mQueuedNotifies.empty()); + if (mQueuedNotifies.empty()) + { + InfoLog(<< "No queued notify to reject"); + return; + } + + QueuedNotify* qn = mQueuedNotifies.front(); + mQueuedNotifies.pop_front(); + mDustbin.push_back(qn); + + mDialog.makeResponse(*mLastResponse, qn->notify(), statusCode); + if (!reasonPhrase.empty()) + { + mLastResponse->header(h_StatusLine).reason() = reasonPhrase; + } + + send(mLastResponse); + switch (Helper::determineFailureMessageEffect(*mLastResponse)) + { + case Helper::TransactionTermination: + case Helper::RetryAfter: + break; + case Helper::OptionalRetryAfter: + case Helper::ApplicationDependant: + throw UsageUseException("Not a reasonable code to reject a NOTIFY with inside an established dialog.", + __FILE__, __LINE__); + break; + case Helper::DialogTermination: //?dcm? -- throw or destroy this? + case Helper::UsageTermination: + mEnded = true; + handler->onTerminated(getHandle(), mLastResponse.get()); + delete this; + break; + } +} + +class ClientSubscriptionRejectUpdateCommand : public DumCommandAdapter +{ +public: + ClientSubscriptionRejectUpdateCommand(ClientSubscription& clientSubscription, int statusCode, const Data& reasonPhrase) + : mClientSubscription(clientSubscription), + mStatusCode(statusCode), + mReasonPhrase(reasonPhrase) + { + } + + virtual void executeCommand() + { + mClientSubscription.rejectUpdate(mStatusCode, mReasonPhrase); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ClientSubscriptionRejectUpdateCommand"; + } +private: + ClientSubscription& mClientSubscription; + int mStatusCode; + Data mReasonPhrase; +}; + +void +ClientSubscription::rejectUpdateCommand(int statusCode, const Data& reasonPhrase) +{ + mDum.post(new ClientSubscriptionRejectUpdateCommand(*this, statusCode, reasonPhrase)); +} + +void ClientSubscription::dialogDestroyed(const SipMessage& msg) +{ + ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); + assert(handler); + mEnded = true; + handler->onTerminated(getHandle(), &msg); + delete this; +} + +EncodeStream& +ClientSubscription::dump(EncodeStream& strm) const +{ + strm << "ClientSubscription " << mLastRequest->header(h_From).uri(); + return strm; +} + +void +ClientSubscription::onReadyToSend(SipMessage& msg) +{ + ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); + assert(handler); + handler->onReadyToSend(getHandle(), msg); +} + +void +ClientSubscription::flowTerminated() +{ + // notify handler + ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); + assert(handler); + handler->onFlowTerminated(getHandle()); +} + +void +ClientSubscription::sendQueuedRefreshRequest() +{ + assert(!mRefreshing); + + if (mHaveQueuedRefresh) + { + DebugLog(<< "send queued refresh request"); + mHaveQueuedRefresh = false; + requestRefresh(mQueuedRefreshInterval); + } +} + +void +ClientSubscription::clearDustbin() +{ + for (Dustbin::iterator it = mDustbin.begin(); it != mDustbin.end(); ++it) + { + delete *it; + } + + mDustbin.clear(); + +} + +void +ClientSubscription::scheduleRefresh(unsigned long refreshInterval) +{ + if(mNextRefreshSecs-mLastSubSecs < 2) + { + // Server is using an unreasonably short expiry; we sent a SUB + // very recently, and the server has told us to refresh almost + // immediately. By the time our refresh timer pops, less than two + // seconds will have elapsed since our last SUBSCRIBE. This is + // unacceptable. Just let the subscription end. + // It is also possible that our refresh SUB has crossed an update NOTIFY + // on the wire; in this case, the right thing to do is to wait until a + // NOTIFY for our refresh SUB comes in, which is exactly what this code + // ends up doing in this case. + // ?bwc? Make this minimum inter-SUBSCRIBE time configurable? + WarningLog(<< "Server is using an unacceptably short expiry. " + "Letting the subscription end so we don't get in a" + " tight SUB/NOT loop."); + mNextRefreshSecs=0; + } + else + { + mDum.addTimer(DumTimeout::Subscription, refreshInterval, getBaseHandle(), ++mTimerSeq); + InfoLog (<< "[ClientSubscription] reSUBSCRIBE in " << refreshInterval); + } +} + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientSubscription.hxx b/src/libs/resiprocate/resip/dum/ClientSubscription.hxx new file mode 100644 index 00000000..09546d33 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientSubscription.hxx @@ -0,0 +1,153 @@ +#if !defined(RESIP_CLIENTSUBSCRIPTION_HXX) +#define RESIP_CLIENTSUBSCRIPTION_HXX + +#include <deque> +#include "resip/dum/BaseSubscription.hxx" + +namespace resip +{ + +class DialogUsageManager; + +//!dcm! -- update contact in dialog if required + +class ClientSubscription: public BaseSubscription +{ + public: + ClientSubscription(DialogUsageManager& dum, Dialog& dialog, + const SipMessage& request, UInt32 defaultSubExpiration); + + typedef Handle<ClientSubscription> ClientSubscriptionHandle; + ClientSubscriptionHandle getHandle(); + + //.dcm. no adornment for ease of use, can add if there is a use case + void acceptUpdate(int statusCode = 200, const char* reason=0); + void rejectUpdate(int statusCode = 400, const Data& reasonPhrase = Data::Empty); + void requestRefresh(UInt32 expires = 0); // 0 defaults to using original expires value (to remove call end() instead) + virtual void end(); + void end(bool immediate); // If immediate is true then usage is destroyed with no further messaging + virtual void reSubscribe(); // forms a new Subscription dialog - reusing the same target and AppDialogSet + /** + * Provide asynchronous method access by using command + */ + void acceptUpdateCommand(int statusCode = 200, const char* reason=0); + void rejectUpdateCommand(int statusCode = 400, const Data& reasonPhrase = Data::Empty); + void requestRefreshCommand(UInt32 expires = 0); // 0 defaults to using original expires value (to remove call endCommand() instead) + virtual void endCommand(bool immediate=false); // If immediate is true then usage is destroyed with no further messaging + + virtual EncodeStream& dump(EncodeStream& strm) const; + + protected: + virtual ~ClientSubscription(); + virtual void dialogDestroyed(const SipMessage& msg); + virtual void onReadyToSend(SipMessage& msg); + virtual void send(SharedPtr<SipMessage> msg); + virtual void flowTerminated(); + + private: + friend class Dialog; + friend class InviteSession; + + class QueuedNotify + { + public: + QueuedNotify(const SipMessage& notify, bool outOfOrder) + : mNotify(notify), mOutOfOrder(outOfOrder) {} + + SipMessage& notify() { return mNotify; } + bool outOfOrder() { return mOutOfOrder; } + + private: + SipMessage mNotify; + bool mOutOfOrder; + }; + + typedef std::deque<QueuedNotify*> NotifyQueue; + NotifyQueue mQueuedNotifies; + + typedef std::vector<QueuedNotify*> Dustbin; + Dustbin mDustbin; + + bool mOnNewSubscriptionCalled; + //SipMessage mLastNotify; + bool mEnded; + // .bwc. This is when our next reSUB is scheduled to happen. + UInt64 mNextRefreshSecs; + UInt64 mLastSubSecs; + + // this is the expires value from the 2xx coming from the SUB message + UInt32 mDefaultExpires; + + bool mRefreshing; + bool mHaveQueuedRefresh; + int mQueuedRefreshInterval; + + unsigned int mLargestNotifyCSeq; + + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + void sendQueuedRefreshRequest(); + void processNextNotify(); + void processResponse(const SipMessage& response); + void clearDustbin(); + void scheduleRefresh(unsigned long refreshInterval); + + // disabled + ClientSubscription(const ClientSubscription&); + ClientSubscription& operator=(const ClientSubscription&); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ClientSubscriptionFunctor.hxx b/src/libs/resiprocate/resip/dum/ClientSubscriptionFunctor.hxx new file mode 100644 index 00000000..eb24843f --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ClientSubscriptionFunctor.hxx @@ -0,0 +1,70 @@ +#if !defined(RESIP_CLIENTSUBSCRIPTIONFUNCTOR_HXX) +#define RESIP_CLIENTSUBSCRIPTIONFUNCTOR_HXX + + +namespace resip +{ + +class ClientSubscriptionFunctor +{ + public: + virtual ~ClientSubscriptionFunctor() + { + } + + virtual void apply(ClientSubscriptionHandle) = 0; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ContactInstanceRecord.cxx b/src/libs/resiprocate/resip/dum/ContactInstanceRecord.cxx new file mode 100644 index 00000000..fb4ab122 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ContactInstanceRecord.cxx @@ -0,0 +1,72 @@ +#include "resip/dum/ContactInstanceRecord.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/Timer.hxx" +#include "resip/stack/SipMessage.hxx" + +using namespace resip; + +ContactInstanceRecord::ContactInstanceRecord() : + mRegExpires(0), + mLastUpdated(Timer::getTimeSecs()), + mRegId(0), + mSyncContact(false), + mUseFlowRouting(false), + mUserInfo(0) +{ +} + +bool +ContactInstanceRecord::operator==(const ContactInstanceRecord& rhs) const +{ + if((mRegId != 0 && !mInstance.empty()) || + (rhs.mRegId != 0 && !rhs.mInstance.empty())) + { + // If regId and instanceId is specified on either, then outbound RFC5626 is + // in use - match only if both instance id and reg-id match - ignore contact URI + return mInstance == rhs.mInstance && + mRegId == rhs.mRegId; + } + else + { + // otherwise both instance (if specified) and contact must match + return mInstance == rhs.mInstance && + mContact.uri() == rhs.mContact.uri(); + } +} + +ContactInstanceRecord +ContactInstanceRecord::makeRemoveDelta(const NameAddr& contact) +{ + ContactInstanceRecord c; + c.mContact = contact; + return c; +} + +ContactInstanceRecord +ContactInstanceRecord::makeUpdateDelta(const NameAddr& contact, + UInt64 expires, // absolute time in secs + const SipMessage& msg) +{ + ContactInstanceRecord c; + c.mContact = contact; + c.mRegExpires = expires; + c.mReceivedFrom = msg.getSource(); + c.mPublicAddress = Helper::getClientPublicAddress(msg); + if (msg.exists(h_Paths)) + { + c.mSipPath = msg.header(h_Paths); + } + if (contact.exists(p_Instance)) + { + c.mInstance = contact.param(p_Instance); + } + if (contact.exists(p_regid)) + { + c.mRegId = contact.param(p_regid); + } + // !jf! need to fill in mServerSessionId here + return c; + +} + + diff --git a/src/libs/resiprocate/resip/dum/ContactInstanceRecord.hxx b/src/libs/resiprocate/resip/dum/ContactInstanceRecord.hxx new file mode 100644 index 00000000..ff7f7b0a --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ContactInstanceRecord.hxx @@ -0,0 +1,103 @@ +#if !defined(resip_ContactInstanceRecord_hxx) +#define resip_ContactInstanceRecord_hxx + +#include <vector> +#include <list> +#include <deque> + +#include "resip/stack/NameAddr.hxx" +#include "rutil/Data.hxx" +#include "resip/stack/Tuple.hxx" +#include "rutil/SharedPtr.hxx" + +namespace resip +{ +static const UInt64 NeverExpire = 0xFFFFFFFFFFFFFFFFULL; + +/** A single contact record, bound to an Aor during registration. +*/ +class ContactInstanceRecord +{ + public: + ContactInstanceRecord(); + static ContactInstanceRecord makeRemoveDelta(const NameAddr& contact); + static ContactInstanceRecord makeUpdateDelta(const NameAddr& contact, + UInt64 expires, // absolute time in secs + const SipMessage& msg); + + NameAddr mContact; // can contain callee caps and q-values + UInt64 mRegExpires; // in seconds + UInt64 mLastUpdated; // in seconds + Tuple mReceivedFrom; // source transport, IP address, and port + Tuple mPublicAddress; // Public IP address closest to the client (from Via headers): note: Tuple::getType == UNKNOWN_TRANPORT if no public address was found + NameAddrs mSipPath; // Value of SIP Path header from the request + Data mInstance; // From the instance parameter; usually a UUID URI + UInt32 mRegId; // From regid parameter of Contact header + bool mSyncContact; // This contact came from registration sync process, instead of direct SIP registration + bool mUseFlowRouting; // Set to true when routing to this contact should use flow routing + // Note: There is no need to regsync this field, since such records will also have + // onlyUseExistingConnection set, and such contacts are not replicated. + // Data mServerSessionId;// if there is no SIP Path header, the connection/session identifier + // Uri gruu; (GRUU is currently derived) + void *mUserInfo; //!< can be used to map user record information (database record id for faster updates?) + + bool operator==(const ContactInstanceRecord& rhs) const; +}; + +typedef std::list<ContactInstanceRecord> ContactList; + +/** Used to reduce copying ContactInstanceRecord objects when processing registration. +*/ +typedef std::list<resip::SharedPtr<ContactInstanceRecord> > ContactPtrList; + +/** Records a log of the database transacations that were performed when processing a local registration using the + ServerRegistration::AsyncLocalStore. +*/ +class ContactRecordTransaction +{ + public: + + typedef enum Operation + { + none, + update, + create, + remove, + removeAll + } Operation; + + ContactRecordTransaction() + :mOp(none) + {} + + ContactRecordTransaction(Operation op, resip::SharedPtr<ContactInstanceRecord> rec) + :mOp(op),mRec(rec) + {} + + Operation mOp; //!< the operation that was performed in this transaction. + /** For create & update: the newly modified record; for remove: the removed record; for removeAll: 0. + */ + resip::SharedPtr<ContactInstanceRecord> mRec; +}; + +/** Contains a collection of database operations that were performed during REGISTER processing. +*/ +typedef std::deque<resip::SharedPtr<ContactRecordTransaction> > ContactRecordTransactionLog; + +class RegistrationBinding +{ + public: + Data mAor; // canonical URI for this AOR and its aliases + ContactList mContacts; + std::vector<Uri> mAliases; +}; + +struct RegistrationBindingDelta +{ + Data mAor; + std::vector<ContactInstanceRecord> mInserts; + std::vector<ContactInstanceRecord> mUpdates; + std::vector<ContactInstanceRecord> mRemoves; +}; +} +#endif diff --git a/src/libs/resiprocate/resip/dum/DefaultServerReferHandler.cxx b/src/libs/resiprocate/resip/dum/DefaultServerReferHandler.cxx new file mode 100644 index 00000000..e1391d40 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DefaultServerReferHandler.cxx @@ -0,0 +1,97 @@ + +#include "resip/dum/DefaultServerReferHandler.hxx" +#include "resip/dum/ServerSubscription.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +void +DefaultServerReferHandler::onNewSubscription(ServerSubscriptionHandle, const SipMessage& sub) +{} + +void +DefaultServerReferHandler::onNewSubscriptionFromRefer(ServerSubscriptionHandle, const SipMessage& sub) +{} + +void +DefaultServerReferHandler::onRefresh(ServerSubscriptionHandle, const SipMessage& sub) +{} + +void +DefaultServerReferHandler::onTerminated(ServerSubscriptionHandle) +{} + +void DefaultServerReferHandler::onReadyToSend(ServerSubscriptionHandle, SipMessage&) +{} + +////!dcm! -- not thread-safe +//DefaultServerReferHandler* DefaultServerReferHandler::Instance() +//{ +// static DefaultServerReferHandler mInstance; +// return &mInstance; +//} + + +bool +DefaultServerReferHandler::hasDefaultExpires() const +{ + return true; +} + +UInt32 +DefaultServerReferHandler::getDefaultExpires() const +{ + return 60; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DefaultServerReferHandler.hxx b/src/libs/resiprocate/resip/dum/DefaultServerReferHandler.hxx new file mode 100644 index 00000000..e63e002b --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DefaultServerReferHandler.hxx @@ -0,0 +1,80 @@ +#if !defined(RESIP_DEFAULTSERVERREFERHANDLER_HXX) +#define RESIP__DEFAULTSERVERREFERHANDLER_HXX + +#include "resip/dum/SubscriptionHandler.hxx" + +namespace resip +{ + +class DefaultServerReferHandler : public ServerSubscriptionHandler +{ + public: + DefaultServerReferHandler() {} + virtual ~DefaultServerReferHandler() {} + + virtual void onNewSubscription(ServerSubscriptionHandle, const SipMessage& sub); + virtual void onNewSubscriptionFromRefer(ServerSubscriptionHandle, const SipMessage& sub); + virtual void onRefresh(ServerSubscriptionHandle, const SipMessage& sub); + virtual void onTerminated(ServerSubscriptionHandle); + virtual void onReadyToSend(ServerSubscriptionHandle, SipMessage&); + + //static DefaultServerReferHandler* Instance(); + + virtual bool hasDefaultExpires() const; + virtual UInt32 getDefaultExpires() const; + protected: +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DestroyUsage.cxx b/src/libs/resiprocate/resip/dum/DestroyUsage.cxx new file mode 100644 index 00000000..9c7deb52 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DestroyUsage.cxx @@ -0,0 +1,137 @@ +#include "resip/dum/DestroyUsage.hxx" +#include "rutil/Logger.hxx" +#include "resip/dum/BaseUsage.hxx" +#include "resip/dum/DialogSet.hxx" +#include "resip/dum/Dialog.hxx" +#include "rutil/WinLeakCheck.hxx" +#include <cassert> + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +DestroyUsage::DestroyUsage(BaseUsageHandle target) + :mHandle(target), + mDialogSet(0), + mDialog(0) +{} + +DestroyUsage::DestroyUsage(DialogSet* dialogSet) + :mHandle(), + mDialogSet(dialogSet), + mDialog(0) +{} + +DestroyUsage::DestroyUsage(Dialog* dialog) + :mHandle(), + mDialogSet(0), + mDialog(dialog) +{} + +DestroyUsage::DestroyUsage(const DestroyUsage& other) : + mHandle(other.mHandle), + mDialogSet(other.mDialogSet), + mDialog(other.mDialog) +{} + +DestroyUsage::~DestroyUsage() +{} + +Message* +DestroyUsage::clone() const +{ + return new DestroyUsage(*this); +} + +EncodeStream& +DestroyUsage::encodeBrief(EncodeStream& strm) const +{ + if (mDialogSet) + { + static Data d("DestroyDialogSet"); + strm << d << " " << mDialogSet->getId(); + } + else if (mDialog) + { + static Data d("DestroyDialog"); + strm << d << " " << mDialog->getId(); + } + else + { + static Data d("DestroyUsage"); + strm << d << " " << *mHandle; + } + + return strm; +} + +EncodeStream& +DestroyUsage::encode(EncodeStream& strm) const +{ + return strm << brief(); +} + +void +DestroyUsage::destroy() +{ + if (mDialogSet) + { + delete mDialogSet; + } + else if (mDialog) + { + delete mDialog; + } + else if (mHandle.isValid()) + { + delete mHandle.get(); + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DestroyUsage.hxx b/src/libs/resiprocate/resip/dum/DestroyUsage.hxx new file mode 100644 index 00000000..aaf4eb22 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DestroyUsage.hxx @@ -0,0 +1,87 @@ +#if !defined(RESIP_DESTORYUSAGE_HXX) +#define RESIP_DESTORYUSAGE_HXX + +#include <iosfwd> +#include "resip/stack/ApplicationMessage.hxx" +#include "resip/dum/Handles.hxx" + +namespace resip +{ + +class Dialog; +class DialogSet; + +class DestroyUsage : public ApplicationMessage +{ + public: + DestroyUsage(BaseUsageHandle target); + DestroyUsage(Dialog* dialog); + DestroyUsage(DialogSet* dialogSet); + + virtual ~DestroyUsage(); + + virtual Message* clone() const; + void destroy(); + + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + DestroyUsage(const DestroyUsage& other); + + BaseUsageHandle mHandle; + DialogSet* mDialogSet; + Dialog* mDialog; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/Dialog.cxx b/src/libs/resiprocate/resip/dum/Dialog.cxx new file mode 100644 index 00000000..11253177 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Dialog.cxx @@ -0,0 +1,1288 @@ +#include "resip/stack/Contents.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/AppDialog.hxx" +#include "resip/dum/BaseCreator.hxx" +#include "resip/dum/ClientAuthManager.hxx" +#include "resip/dum/ClientInviteSession.hxx" +#include "resip/dum/ClientSubscription.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/InviteSessionCreator.hxx" +#include "resip/dum/InviteSessionHandler.hxx" +#include "resip/dum/ServerInviteSession.hxx" +#include "resip/dum/ServerSubscription.hxx" +#include "resip/dum/SubscriptionHandler.hxx" +#include "resip/dum/UsageUseException.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; +using namespace std; + +Dialog::Dialog(DialogUsageManager& dum, const SipMessage& msg, DialogSet& ds) + : mDum(dum), + mDialogSet(ds), + mId("INVALID", "INVALID", "INVALID"), + mClientSubscriptions(), + mServerSubscriptions(), + mInviteSession(0), + mType(Fake), + mRouteSet(), + mLocalContact(), + mLocalCSeq(0), + mRemoteCSeq(0), + mRemoteTarget(), + mLocalNameAddr(), + mRemoteNameAddr(), + mCallId(msg.header(h_CallID)), + mDefaultSubExpiration(0), + mAppDialog(0), + mDestroying(false), + mReUseDialogSet(false) +{ + assert(msg.isExternal()); + + assert(msg.header(h_CSeq).method() != MESSAGE); + assert(msg.header(h_CSeq).method() != REGISTER); + assert(msg.header(h_CSeq).method() != PUBLISH); + + mNetworkAssociation.setDum(&dum); + + if (msg.isRequest()) // UAS + { + const SipMessage& request = msg; + + switch (request.header(h_CSeq).method()) + { + case INVITE: + mType = Invitation; + break; + + case SUBSCRIBE: + case REFER: + case NOTIFY: + //!dcm! -- event header check + mType = Subscription; + break; + + default: + mType = Fake; + } + if (request.exists(h_RecordRoutes)) + { + mRouteSet = request.header(h_RecordRoutes); + } + + switch (request.header(h_CSeq).method()) + { + case INVITE: + case SUBSCRIBE: + case REFER: + case NOTIFY: + DebugLog ( << "UAS dialog ID creation, DS: " << ds.getId()); + mId = DialogId(ds.getId(), + request.header(h_From).exists(p_tag) ? request.header(h_From).param(p_tag) : Data::Empty); + + mRemoteNameAddr = request.header(h_From); + mLocalNameAddr = request.header(h_To); + mLocalNameAddr.param(p_tag) = mId.getLocalTag(); + if (request.exists(h_Contacts) && request.header(h_Contacts).size() == 1) + { + const NameAddr& contact = request.header(h_Contacts).front(); + if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) || + isEqualNoCase(contact.uri().scheme(), Symbols::Sip)) + { + // Store Remote Target + mRemoteTarget = contact; + + // Create Local Contact + if(mDialogSet.mUserProfile->hasUserAgentCapabilities()) + { + mLocalContact = mDialogSet.mUserProfile->getUserAgentCapabilities(); + } + if(!mDialogSet.mUserProfile->isAnonymous() && mDialogSet.mUserProfile->hasPublicGruu()) + { + mLocalContact.uri() = mDialogSet.mUserProfile->getPublicGruu(); + } + else if(mDialogSet.mUserProfile->isAnonymous() && mDialogSet.mUserProfile->hasTempGruu()) + { + mLocalContact.uri() = mDialogSet.mUserProfile->getTempGruu(); + } + else + { + if (mDialogSet.mUserProfile->hasOverrideHostAndPort()) + { + mLocalContact.uri() = mDialogSet.mUserProfile->getOverrideHostAndPort(); + } + if(request.header(h_RequestLine).uri().user().empty()) + { + mLocalContact.uri().user() = request.header(h_To).uri().user(); + } + else + { + mLocalContact.uri().user() = request.header(h_RequestLine).uri().user(); + } + const Data& instanceId = mDialogSet.mUserProfile->getInstanceId(); + if (!contact.uri().exists(p_gr) && !instanceId.empty()) + { + mLocalContact.param(p_Instance) = instanceId; + } + } + if(mDialogSet.mUserProfile->clientOutboundEnabled()) + { + // Add ;ob parm to non-register requests - RFC5626 pg17 + mLocalContact.uri().param(p_ob); + } + } + else + { + InfoLog(<< "Got an INVITE or SUBSCRIBE with invalid scheme"); + InfoLog(<< request); + throw Exception("Invalid scheme in request", __FILE__, __LINE__); + } + } + else + { + InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact"); + InfoLog (<< request); + throw Exception("Too many (or no contact) contacts in request", __FILE__, __LINE__); + } + break; + default: + break; + } + + mRemoteCSeq = request.header(h_CSeq).sequence(); + + // This may actually be a UAC dialogset - ie. the case where the first NOTIFY creates the + // SUBSCRIPTION dialog, instead of the 200/SUB. If so, then we need to make sure the local + // CSeq is correct - it's value may be greator than 1, if the original request (SUBSCRIBE) + // got digest challenged. + BaseCreator* creator = mDialogSet.getCreator(); + if(creator) + { + mLocalCSeq = creator->getLastRequest()->header(h_CSeq).sequence(); + } + else + { + mLocalCSeq = 1; + } + + DebugLog ( << "************** Created Dialog as UAS **************" ); + DebugLog ( << "mRemoteNameAddr: " << mRemoteNameAddr ); + DebugLog ( << "mLocalNameAddr: " << mLocalNameAddr ); + DebugLog ( << "mLocalContact: " << mLocalContact ); + DebugLog ( << "mRemoteTarget: " << mRemoteTarget ); + } + else if (msg.isResponse()) + { + mId = DialogId(msg); + const SipMessage& response = msg; + mRemoteNameAddr = response.header(h_To); + mLocalNameAddr = response.header(h_From); + + switch (msg.header(h_CSeq).method()) + { + case INVITE: + mType = Invitation; + break; + + case SUBSCRIBE: + case REFER: + mType = Subscription; + break; + + default: + mType = Fake; + } + + if (response.exists(h_RecordRoutes)) + { + mRouteSet = response.header(h_RecordRoutes).reverse(); + } + + switch (response.header(h_CSeq).method()) + { + case INVITE: + case SUBSCRIBE: + case REFER: + if (response.header(h_StatusLine).statusCode() > 100 && + response.header(h_StatusLine).statusCode() < 300) + { + + if (response.exists(h_Contacts) && response.header(h_Contacts).size() == 1) + { + const NameAddr& contact = response.header(h_Contacts).front(); + if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) || + isEqualNoCase(contact.uri().scheme(), Symbols::Sip)) + { + BaseCreator* creator = mDialogSet.getCreator(); + if(0 == creator) + { + ErrLog(<< "BaseCreator is null for DialogSet"); + ErrLog(<< response); + throw Exception("BaseCreator is null for DialogSet", __FILE__, __LINE__); + } + + SharedPtr<SipMessage> lastRequest(creator->getLastRequest()); + + if( 0 == lastRequest.get() || + !lastRequest->exists(h_Contacts) || + lastRequest->header(h_Contacts).empty()) + { + InfoLog(<< "lastRequest does not contain a valid contact"); + InfoLog(<< response); + throw Exception("lastRequest does not contain a valid contact.", __FILE__, __LINE__); + } + mLocalContact = creator->getLastRequest()->header(h_Contacts).front(); + mRemoteTarget = contact; + } + else + { + InfoLog (<< "Got an INVITE or SUBSCRIBE with invalid scheme"); + DebugLog (<< response); + throw Exception("Bad scheme in contact in response", __FILE__, __LINE__); + } + } + else + { + InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact"); + DebugLog (<< response); + throw Exception("Too many contacts (or no contact) in response", __FILE__, __LINE__); + } + break; + default: + break; + } + } + + mLocalCSeq = response.header(h_CSeq).sequence(); + mRemoteCSeq = 0; + DebugLog ( << "************** Created Dialog as UAC **************" ); + DebugLog ( << "mRemoteNameAddr: " << mRemoteNameAddr ); + DebugLog ( << "mLocalNameAddr: " << mLocalNameAddr ); + DebugLog ( << "mLocalContact: " << mLocalContact ); + DebugLog ( << "mRemoteTarget: " << mRemoteTarget ); + } + mDialogSet.addDialog(this); + DebugLog ( <<"Dialog::Dialog " << mId); +} + +Dialog::~Dialog() +{ + DebugLog ( <<"Dialog::~Dialog() "); + + mDestroying = true; + + while (!mClientSubscriptions.empty()) + { + delete *mClientSubscriptions.begin(); + } + + while (!mServerSubscriptions.empty()) + { + delete *mServerSubscriptions.begin(); + } + + delete mInviteSession; + mDialogSet.mDialogs.erase(this->getId()); + delete mAppDialog; + if(!mReUseDialogSet) + { + mDialogSet.possiblyDie(); + } +} + +const DialogId& +Dialog::getId() const +{ + return mId; +} + +const NameAddr& +Dialog::getLocalNameAddr() const +{ + return mLocalNameAddr; +} + +const NameAddr& +Dialog::getLocalContact() const +{ + return mLocalContact; +} + +const NameAddr& +Dialog::getRemoteNameAddr() const +{ + return mRemoteNameAddr; +} + +const NameAddr& +Dialog::getRemoteTarget() const +{ + return mRemoteTarget; +} + +const NameAddrs& +Dialog::getRouteSet() const +{ + return mRouteSet; +} + +void +Dialog::cancel() +{ + assert(mType == Invitation); + ClientInviteSession* uac = dynamic_cast<ClientInviteSession*>(mInviteSession); + assert (uac); + uac->cancel(); +} + +void +Dialog::end() +{ + if (mInviteSession) + { + mInviteSession->end(); + } + + // End Subscriptions + // !jrm! WARN ClientSubscription and ServerSubscription have access to this dialog and will remove themselves + // from the m<client|server>Subscriptions collections in the call to end(). + for (list<ClientSubscription*>::iterator it(mClientSubscriptions.begin()); + it != mClientSubscriptions.end();) + { + ClientSubscription* c = *it; + it++; + c->end(); + } + + for (list<ServerSubscription*>::iterator it2(mServerSubscriptions.begin()); + it2 != mServerSubscriptions.end();) + { + ServerSubscription* s = *it2; + it2++; + s->end(); + } +} + +void +Dialog::handleTargetRefresh(const SipMessage& msg) +{ + switch(msg.header(h_CSeq).method()) + { + case INVITE: + case UPDATE: + if (msg.isRequest() || (msg.isResponse() && msg.header(h_StatusLine).statusCode()/100 == 2)) + { + //?dcm? modify local target; 12.2.2 of 3261 implies that the remote + //target is immediately modified. Should we wait until a 2xx class + //reponse is sent to a re-invite(easy when all send requests go + //through Dialog) + if (msg.exists(h_Contacts)) + { + //.dcm. replace or check then replace + mRemoteTarget = msg.header(h_Contacts).front(); + } + } + break; + default: + return; + } +} + +void +Dialog::dispatch(const SipMessage& msg) +{ + // !jf! Should be checking for messages with out of order CSeq and rejecting + + DebugLog ( << "Dialog::dispatch: " << msg.brief()); + + if(msg.isExternal()) + { + const Data& receivedTransport = msg.header(h_Vias).front().transport(); + int keepAliveTime = 0; + if(receivedTransport == Symbols::TCP || + receivedTransport == Symbols::TLS || + receivedTransport == Symbols::SCTP) + { + keepAliveTime = mDialogSet.mUserProfile->getKeepAliveTimeForStream(); + } + else + { + keepAliveTime = mDialogSet.mUserProfile->getKeepAliveTimeForDatagram(); + } + + if(keepAliveTime > 0) + { + mNetworkAssociation.update(msg, keepAliveTime, false /* targetSupportsOutbound */); // target supports outbound is detected in registration responses only + } + } + + handleTargetRefresh(msg); + if (msg.isRequest()) + { + const SipMessage& request = msg; + switch (request.header(h_CSeq).method()) + { + case INVITE: // new INVITE + if (mInviteSession == 0) + { + DebugLog ( << "Dialog::dispatch -- Created new server invite session" << msg.brief()); + mInviteSession = makeServerInviteSession(request); + } + mInviteSession->dispatch(request); + break; + //refactor, send bad request for BYE, INFO, CANCEL? + case BYE: + if (mInviteSession == 0) + { + InfoLog ( << "Spurious BYE" ); + return; + } + else + { + mInviteSession->dispatch(request); + } + break; + case UPDATE: + if (mInviteSession == 0) + { + InfoLog ( << "Spurious UPDATE" ); + return; + } + else + { + mInviteSession->dispatch(request); + } + break; + case INFO: + if (mInviteSession == 0) + { + InfoLog ( << "Spurious INFO" ); + return; + } + else + { + mInviteSession->dispatch(request); + } + break; + case MESSAGE: + if (mInviteSession == 0) + { + InfoLog ( << "Spurious MESSAGE" ); + return; + } + else + { + mInviteSession->dispatch(request); + } + break; + case ACK: + case CANCEL: + if (mInviteSession == 0) + { + InfoLog (<< "Drop stray ACK or CANCEL in dialog on the floor"); + DebugLog (<< request); + } + else + { + mInviteSession->dispatch(request); + } + break; + case SUBSCRIBE: + { + ServerSubscription* server = findMatchingServerSub(request); + if (server) + { + server->dispatch(request); + } + else + { + if (request.exists(h_Event) && request.header(h_Event).value() == "refer") + { + InfoLog (<< "Received a subscribe to a non-existent refer subscription: " << request.brief()); + SipMessage failure; + makeResponse(failure, request, 403); + mDum.sendResponse(failure); + return; + } + else + { + if (mDum.checkEventPackage(request)) + { + server = makeServerSubscription(request); + mServerSubscriptions.push_back(server); + server->dispatch(request); + } + } + } + } + break; + case REFER: + { +// if (mInviteSession == 0) +// { +// InfoLog (<< "Received an in dialog refer in a non-invite dialog: " << request.brief()); +// SipMessage failure; +// makeResponse(failure, request, 603); +// mDum.sendResponse(failure); +// return; +// } +// else + + if (!request.exists(h_ReferTo)) + { + InfoLog (<< "Received refer w/out a Refer-To: " << request.brief()); + SipMessage failure; + makeResponse(failure, request, 400); + mDum.sendResponse(failure); + return; + } + else + { + if ((request.exists(h_ReferSub) && + request.header(h_ReferSub).isWellFormed() && + request.header(h_ReferSub).value()=="false") || + (request.exists(h_Requires) && + request.header(h_Requires).find(Token("norefersub")))) + { + assert(mInviteSession); + mInviteSession->referNoSub(msg); + } + else + { + ServerSubscription* server = findMatchingServerSub(request); + ServerSubscriptionHandle serverHandle; + if (server) + { + serverHandle = server->getHandle(); + server->dispatch(request); + } + else + { + server = makeServerSubscription(request); + mServerSubscriptions.push_back(server); + serverHandle = server->getHandle(); + server->dispatch(request); + } + + if (mInviteSession) + { + mDum.mInviteSessionHandler->onRefer(mInviteSession->getSessionHandle(), serverHandle, msg); + } + + } + } + } + break; + case NOTIFY: + { + ClientSubscription* client = findMatchingClientSub(request); + if (client) + { + client->dispatch(request); + } + else + { + BaseCreator* creator = mDialogSet.getCreator(); + if (creator && (creator->getLastRequest()->header(h_RequestLine).method() == SUBSCRIBE || + creator->getLastRequest()->header(h_RequestLine).method() == REFER)) + { + DebugLog (<< "Making subscription (from creator) request: " << *creator->getLastRequest()); + ClientSubscription* sub = makeClientSubscription(*creator->getLastRequest()); + mClientSubscriptions.push_back(sub); + sub->dispatch(request); + } + else + { + if (mInviteSession != 0 && (!msg.exists(h_Event) || msg.header(h_Event).value() == "refer") && + mDum.getClientSubscriptionHandler("refer")!=0) + { + DebugLog (<< "Making subscription from NOTIFY: " << msg); + ClientSubscription* sub = makeClientSubscription(msg); + mClientSubscriptions.push_back(sub); + ClientSubscriptionHandle client = sub->getHandle(); + mDum.mInviteSessionHandler->onReferAccepted(mInviteSession->getSessionHandle(), client, msg); + sub->dispatch(request); + } + else + { + SharedPtr<SipMessage> response(new SipMessage); + makeResponse(*response, msg, 406); + send(response); + } + } + } + } + break; + default: + assert(0); + return; + } + } + else if (msg.isResponse()) + { + // !jf! There is a substantial change in how this works in teltel-branch + // from how it worked in main branch pre merge. + // If the response doesn't match a cseq for a request I've sent, ignore + // the response + {//scope 'r' as it is invalidated below + RequestMap::iterator r = mRequests.find(msg.header(h_CSeq).sequence()); + if (r != mRequests.end()) + { + bool handledByAuth = false; + if (mDum.mClientAuthManager.get() && + mDum.mClientAuthManager->handle(*mDialogSet.mUserProfile, *r->second, msg)) + { + InfoLog( << "about to re-send request with digest credentials" << r->second->brief()); + + assert (r->second->isRequest()); + + mLocalCSeq++; + send(r->second); + handledByAuth = true; + } + mRequests.erase(r); + if (handledByAuth) return; + } + } + + const SipMessage& response = msg; + int code = response.header(h_StatusLine).statusCode(); + // If this is a 200 response to the initial request, then store the routeset (if present) + BaseCreator* creator = mDialogSet.getCreator(); + if (creator && (creator->getLastRequest()->header(h_CSeq) == response.header(h_CSeq)) && code >=200 && code < 300) + { + if (response.exists(h_RecordRoutes)) + { + mRouteSet = response.header(h_RecordRoutes).reverse(); + } + else + { + // Ensure that if the route-set in the 200 is empty, then we overwrite any existing route-sets + mRouteSet.clear(); + } + } + + // !jf! should this only be for 2xx responses? !jf! Propose no as an + // answer !dcm! what is he on? + switch (response.header(h_CSeq).method()) + { + case INVITE: + if (mInviteSession == 0) + { + DebugLog ( << "Dialog::dispatch -- Created new client invite session" << msg.brief()); + + mInviteSession = makeClientInviteSession(response); + if (mInviteSession) + { + mInviteSession->dispatch(response); + } + else + { + ErrLog( << "Dialog::dispatch -- Unable to create invite session from response" << msg.brief()); + } + } + else + { + mInviteSession->dispatch(response); + } + break; + case BYE: + case ACK: + case CANCEL: + case INFO: + case MESSAGE: + case UPDATE: + if (mInviteSession) + { + mInviteSession->dispatch(response); + } + // else drop on the floor + break; + + case REFER: + if(mInviteSession) + { + if (code >= 300) + { + mDum.mInviteSessionHandler->onReferRejected(mInviteSession->getSessionHandle(), msg); + } + else + { + //!dys! the OR condition below is not draft compliant. + if (!mInviteSession->mReferSub && + ((msg.exists(h_ReferSub) && msg.header(h_ReferSub).value()=="false") || + !msg.exists(h_ReferSub))) + { + DebugLog(<< "refer accepted with norefersub"); + mDum.mInviteSessionHandler->onReferAccepted(mInviteSession->getSessionHandle(), ClientSubscriptionHandle::NotValid(), msg); + } + // else no need for action - first Notify will cause onReferAccepted to be called + } + mInviteSession->nitComplete(); + break; + } + // fall through, out of dialog refer was sent. + + case SUBSCRIBE: + { + int code = response.header(h_StatusLine).statusCode(); + ClientSubscription* client = findMatchingClientSub(response); + if (client) + { + client->dispatch(response); + } + else if (code < 300) + { + /* + we're capturing the value from the expires header off + the 2xx because the ClientSubscription is only created + after receiving the NOTIFY that comes (usually) after + this 2xx. We really should be creating the + ClientSubscription at either the 2xx or the NOTIFY + whichever arrives first. .mjf. + Note: we're capturing a duration here (not the + absolute time because all the inputs to + ClientSubscription desling with the expiration are expecting + duration type values from the headers. .mjf. + */ + if(response.exists(h_Expires)) + { + mDefaultSubExpiration = response.header(h_Expires).value(); + } + else + { + //?dcm? defaults to 3600 in ClientSubscription if no expires value + //is provided anywhere...should we assume the value from the + //sub in the basecreator if it exists? + mDefaultSubExpiration = 0; + } + return; + } + else + { + //!dcm! -- can't subscribe in an existing Dialog, this is all + //a bit of a hack; currently, spurious failure messages may cause callbacks + BaseCreator* creator = mDialogSet.getCreator(); + if (!creator || !creator->getLastRequest()->exists(h_Event)) + { + return; + } + else + { + ClientSubscriptionHandler* handler = + mDum.getClientSubscriptionHandler(creator->getLastRequest()->header(h_Event).value()); + if (handler) + { + ClientSubscription* sub = makeClientSubscription(*creator->getLastRequest()); + mClientSubscriptions.push_back(sub); + sub->dispatch(response); + } + } + } + + } + break; + case NOTIFY: + { + //2xx responses are treated as retransmission quenchers(handled by + //the stack). Failures are dispatched to all ServerSubsscriptions, + //which may not be correct. + + int code = msg.header(h_StatusLine).statusCode(); + if (code >= 300) + { + //!dcm! -- ick, write guard + mDestroying = true; + for (list<ServerSubscription*>::iterator it = mServerSubscriptions.begin(); + it != mServerSubscriptions.end(); ) + { + ServerSubscription* s = *it; + it++; + s->dispatch(msg); + } + mDestroying = false; + possiblyDie(); + } +// ServerSubscription* server = findMatchingServerSub(response); +// if (server) +// { +// server->dispatch(response); +// } + } + break; + default: + assert(0); + return; + } + +#if 0 // merged from head back to teltel-branch + if (msg.header(h_StatusLine).statusCode() >= 400 + && Helper::determineFailureMessageEffect(msg) == Helper::DialogTermination) + { + //kill all usages + mDestroying = true; + + for (list<ServerSubscription*>::iterator it = mServerSubscriptions.begin(); + it != mServerSubscriptions.end(); ) + { + ServerSubscription* s = *it; + it++; + s->dialogDestroyed(msg); + } + + for (list<ClientSubscription*>::iterator it = mClientSubscriptions.begin(); + it != mClientSubscriptions.end(); ) + { + ClientSubscription* s = *it; + it++; + s->dialogDestroyed(msg); + } + if (mInviteSession) + { + mInviteSession->dialogDestroyed(msg); + } + mDestroying = false; + possiblyDie(); //should aways result in destruction of this + return; + } +#endif + } +} + +ServerSubscription* +Dialog::findMatchingServerSub(const SipMessage& msg) +{ + for (std::list<ServerSubscription*>::iterator i=mServerSubscriptions.begin(); + i != mServerSubscriptions.end(); ++i) + { + if ((*i)->matches(msg)) + { + return *i; + } + } + return 0; +} + +ClientSubscription* +Dialog::findMatchingClientSub(const SipMessage& msg) +{ + for (std::list<ClientSubscription*>::iterator i=mClientSubscriptions.begin(); + i != mClientSubscriptions.end(); ++i) + { + if ((*i)->matches(msg)) + { + return *i; + } + } + return 0; +} + +InviteSessionHandle +Dialog::getInviteSession() +{ + if (mInviteSession) + { + return mInviteSession->getSessionHandle(); + } + else + { + return InviteSessionHandle::NotValid(); + } +} + +std::vector<ClientSubscriptionHandle> +Dialog::findClientSubscriptions(const Data& event) +{ + std::vector<ClientSubscriptionHandle> handles; + + for (std::list<ClientSubscription*>::const_iterator i = mClientSubscriptions.begin(); + i != mClientSubscriptions.end(); ++i) + { + if ( (*i)->getEventType() == event) + { + handles.push_back((*i)->getHandle()); + } + } + return handles; +} + +std::vector<ServerSubscriptionHandle> +Dialog::findServerSubscriptions(const Data& event) +{ + std::vector<ServerSubscriptionHandle> handles; + + for (std::list<ServerSubscription*>::const_iterator i = mServerSubscriptions.begin(); + i != mServerSubscriptions.end(); ++i) + { + if ( (*i)->getEventType() == event) + { + handles.push_back((*i)->getHandle()); + } + } + return handles; +} + +std::vector<ClientSubscriptionHandle> +Dialog::getClientSubscriptions() +{ + std::vector<ClientSubscriptionHandle> handles; + + for (std::list<ClientSubscription*>::const_iterator i = mClientSubscriptions.begin(); + i != mClientSubscriptions.end(); ++i) + { + handles.push_back((*i)->getHandle()); + } + + return handles; +} + +std::vector<ServerSubscriptionHandle> +Dialog::getServerSubscriptions() +{ + std::vector<ServerSubscriptionHandle> handles; + + for (std::list<ServerSubscription*>::const_iterator i = mServerSubscriptions.begin(); + i != mServerSubscriptions.end(); ++i) + { + handles.push_back((*i)->getHandle()); + } + + return handles; +} + +void +Dialog::redirected(const SipMessage& msg) +{ + //Established dialogs are not destroyed by a redirect + if (!mClientSubscriptions.empty() || !mServerSubscriptions.empty()) + { + return; + } + if (mInviteSession) + { + ClientInviteSession* cInv = dynamic_cast<ClientInviteSession*>(mInviteSession); + if (cInv) + { + cInv->handleRedirect(msg); + mReUseDialogSet = true; // Set flag so that DialogSet will not be destroyed and new Request can use it + } + } +} + +void +Dialog::makeRequest(SipMessage& request, MethodTypes method) +{ + RequestLine rLine(method); + + rLine.uri() = mRemoteTarget.uri(); + + request.header(h_RequestLine) = rLine; + request.header(h_To) = mRemoteNameAddr; +// request.header(h_To).param(p_tag) = mId.getRemoteTag(); + request.header(h_From) = mLocalNameAddr; +// request.header(h_From).param(p_tag) = mId.getLocalTag(); + + request.header(h_CallId) = mCallId; + + request.remove(h_RecordRoutes); //!dcm! -- all of this is rather messy + request.remove(h_Replaces); + + request.remove(h_Contacts); + request.header(h_Contacts).push_front(mLocalContact); + + request.header(h_CSeq).method() = method; + request.header(h_MaxForwards).value() = 70; + + //must keep old via for cancel + if (method != CANCEL) + { + request.header(h_Routes) = mRouteSet; + request.remove(h_Vias); + Via via; + via.param(p_branch); // will create the branch + request.header(h_Vias).push_front(via); + } + else + { + assert(request.exists(h_Vias)); + } + + //don't increment CSeq for ACK or CANCEL + if (method != ACK && method != CANCEL) + { + request.header(h_CSeq).sequence() = ++mLocalCSeq; + } + else + { + // ACK and cancel have a minimal header set + request.remove(h_Accepts); + request.remove(h_AcceptEncodings); + request.remove(h_AcceptLanguages); + request.remove(h_Allows); + request.remove(h_Requires); + request.remove(h_ProxyRequires); + request.remove(h_Supporteds); + // request.header(h_CSeq).sequence() = ?; // Caller should provide original request, or modify CSeq to proper value after calling this method + } + + // If method is INVITE then advertise required headers + if(method == INVITE || method == UPDATE) + { + if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::Allow)) request.header(h_Allows) = mDum.getMasterProfile()->getAllowedMethods(); + if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::AcceptEncoding)) request.header(h_AcceptEncodings) = mDum.getMasterProfile()->getSupportedEncodings(); + if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::AcceptLanguage)) request.header(h_AcceptLanguages) = mDum.getMasterProfile()->getSupportedLanguages(); + if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::AllowEvents)) request.header(h_AllowEvents) = mDum.getMasterProfile()->getAllowedEvents(); + if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::Supported)) request.header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags(); + } + + if (mDialogSet.mUserProfile->isAnonymous()) + { + request.header(h_Privacys).push_back(PrivacyCategory(Symbols::id)); + } + + DebugLog ( << "Dialog::makeRequest: " << std::endl << std::endl << request ); +} + + +void +Dialog::makeResponse(SipMessage& response, const SipMessage& request, int code) +{ + assert( code >= 100 ); + response.remove(h_Contacts); + if (code < 300 && code > 100) + { + assert(request.isRequest()); + assert(request.header(h_RequestLine).getMethod() == INVITE || + request.header(h_RequestLine).getMethod() == SUBSCRIBE || + request.header(h_RequestLine).getMethod() == BYE || + request.header(h_RequestLine).getMethod() == CANCEL || + request.header(h_RequestLine).getMethod() == REFER || + request.header(h_RequestLine).getMethod() == MESSAGE || + request.header(h_RequestLine).getMethod() == NOTIFY || + request.header(h_RequestLine).getMethod() == INFO || + request.header(h_RequestLine).getMethod() == OPTIONS || + request.header(h_RequestLine).getMethod() == UPDATE + ); + +// assert (request.header(h_RequestLine).getMethod() == CANCEL || // Contact header is not required for Requests that do not form a dialog +// request.header(h_RequestLine).getMethod() == BYE || +// request.header(h_Contacts).size() == 1); + Helper::makeResponse(response, request, code, mLocalContact); + response.header(h_To).param(p_tag) = mId.getLocalTag(); + + if((request.header(h_RequestLine).getMethod() == INVITE || + request.header(h_RequestLine).getMethod() == UPDATE) + && code >= 200 && code < 300) + { + // Check if we should add our capabilites to the invite success response + if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::Allow)) + { + response.header(h_Allows) = mDum.getMasterProfile()->getAllowedMethods(); + } + if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::AcceptEncoding)) + { + response.header(h_AcceptEncodings) = mDum.getMasterProfile()->getSupportedEncodings(); + } + if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::AcceptLanguage)) + { + response.header(h_AcceptLanguages) = mDum.getMasterProfile()->getSupportedLanguages(); + } + if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::AllowEvents)) + { + response.header(h_AllowEvents) = mDum.getMasterProfile()->getAllowedEvents(); + } + if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::Supported)) + { + response.header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags(); + } + } + } + else + { + Helper::makeResponse(response, request, code); + response.header(h_To).param(p_tag) = mId.getLocalTag(); + } + + DebugLog ( << "Dialog::makeResponse: " << std::endl << std::endl << response); +} + + +ClientInviteSession* +Dialog::makeClientInviteSession(const SipMessage& response) +{ + InviteSessionCreator* creator = dynamic_cast<InviteSessionCreator*>(mDialogSet.getCreator()); + if (!creator) + { + assert(0); // !jf! this maybe can assert by evil UAS + return 0; + } + //return mDum.createAppClientInviteSession(*this, *creator); + return new ClientInviteSession(mDum, *this, creator->getLastRequest(), + creator->getInitialOffer(), creator->getEncryptionLevel(), creator->getServerSubscription()); +} + + + +ClientSubscription* +Dialog::makeClientSubscription(const SipMessage& request) +{ + return new ClientSubscription(mDum, *this, request, mDefaultSubExpiration); +} + + +ServerInviteSession* +Dialog::makeServerInviteSession(const SipMessage& request) +{ + return new ServerInviteSession(mDum, *this, request); +} + +ServerSubscription* +Dialog::makeServerSubscription(const SipMessage& request) +{ + return new ServerSubscription(mDum, *this, request); +} + +Dialog::Exception::Exception(const Data& msg, const Data& file, int line) + : BaseException(msg, file, line) +{ +} + + +void +Dialog::send(SharedPtr<SipMessage> msg) +{ + if (msg->isRequest() && msg->header(h_CSeq).method() != ACK) + { + mRequests[msg->header(h_CSeq).sequence()] = msg; + } + mDum.send(msg); +} + +void +Dialog::onForkAccepted() +{ + ClientInviteSession* uac = dynamic_cast<ClientInviteSession*>(mInviteSession); + if (uac) + { + uac->onForkAccepted(); + } +} + +void +Dialog::possiblyDie() +{ + if (!mDestroying) + { + if (mClientSubscriptions.empty() && + mServerSubscriptions.empty() && + !mInviteSession) + { + mDestroying = true; + mDum.destroy(this); + } + } +} + +void +Dialog::flowTerminated() +{ + // Clear the network association + mNetworkAssociation.clear(); + + // notify server subscirption dialogs + std::list<ServerSubscription*> tempServerList = mServerSubscriptions; // Create copy since subscription can be deleted + for (std::list<ServerSubscription*>::iterator is=tempServerList.begin(); + is != tempServerList.end(); ++is) + { + (*is)->flowTerminated(); + } + + // notify client subscription dialogs + std::list<ClientSubscription*> tempClientList = mClientSubscriptions; // Create copy since subscription can be deleted + for (std::list<ClientSubscription*>::iterator ic=tempClientList.begin(); + ic != tempClientList.end(); ++ic) + { + (*ic)->flowTerminated(); + } + + // notify invite session dialog + if (mInviteSession) + { + mInviteSession->flowTerminated(); + } +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const Dialog& dialog) +{ + strm + << "mClientSubscriptions(" + << dialog.mClientSubscriptions.size() + << "), " + << "mServerSubscriptions(" + << dialog.mServerSubscriptions.size() + << ")"; + return strm; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + + + diff --git a/src/libs/resiprocate/resip/dum/Dialog.hxx b/src/libs/resiprocate/resip/dum/Dialog.hxx new file mode 100644 index 00000000..385537cc --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Dialog.hxx @@ -0,0 +1,220 @@ +#if !defined(RESIP_CLIENTDIALOG_HXX) +#define RESIP_CLIENTDIALOG_HXX + +#include <iosfwd> +#include <vector> +#include <list> +#include <map> + +#include "resip/dum/DialogId.hxx" +#include "resip/dum/Handles.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "resip/stack/NameAddr.hxx" +#include "resip/stack/CallId.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/NetworkAssociation.hxx" +#include "resip/dum/DialogUsageManager.hxx" + +namespace resip +{ +class BaseUsage; +class SipMessage; +class DialogUsageManager; +class DialogSet; +class AppDialog; + +//!dcm! -- kill typedef std::list<DialogId> DialogIdSet; + +class Dialog +{ + public: + class Exception : public BaseException + { + public: + Exception(const Data& msg, const Data& file, int line); + virtual const char* name() const {return "Dialog::Exception";} + }; + + // different behavior from request vs. response + // (request creates to tag) + Dialog(DialogUsageManager& dum, const SipMessage& msg, DialogSet& ds); + + const DialogId& getId() const; + const NameAddr& getLocalNameAddr() const; + const NameAddr& getLocalContact() const; + const NameAddr& getRemoteNameAddr() const; + const NameAddr& getRemoteTarget() const; + const NameAddrs& getRouteSet() const; + + // pass dialog sip messages through dialog so we can cache the requests on + // the way out to be able to respond to digest authenticate requests + void send(SharedPtr<SipMessage> msg); + //void send(SipMessage& msg); + + void makeRequest(SipMessage& request, MethodTypes method); + void makeResponse(SipMessage& response, const SipMessage& request, int responseCode); + + //void setLocalContact(const NameAddr& localContact); + //void setRemoteTarget(const NameAddr& remoteTarget); + + std::vector<ClientSubscriptionHandle> getClientSubscriptions(); + std::vector<ClientSubscriptionHandle> findClientSubscriptions(const Data& event); + + std::vector<ServerSubscriptionHandle> getServerSubscriptions(); + std::vector<ServerSubscriptionHandle> findServerSubscriptions(const Data& event); + + //returns an invalid handle if there is no session + InviteSessionHandle getInviteSession(); + + void end(); + void dispatch(const SipMessage& msg); + void processNotify(const SipMessage& notify); + + //will end this dialog(if it makes sense) + void redirected(const SipMessage& msg); + + void onForkAccepted(); + void cancel(); + + bool isDestroying() { return mDestroying; }; + + private: + virtual ~Dialog(); + friend class DialogUsage; + friend class DialogSet; + friend class DialogUsageManager; + friend class DestroyUsage; + + friend class ClientSubscription; + friend class InviteSession; + friend class ClientInviteSession; + friend class ServerInviteSession; + friend class ServerSubscription; + friend class ClientRegistration; + friend class ServerRegistration; + friend class ClientPublication; + friend class ServerPublication; + friend class ClientOutOfDialogReq; + friend class ServerOutOfDialogReq; + + friend class AppDialog; + void possiblyDie(); + + ClientSubscription* findMatchingClientSub(const SipMessage& msg); + ServerSubscription* findMatchingServerSub(const SipMessage& msg); + + void addUsage(BaseUsage* usage); + ClientInviteSession* makeClientInviteSession(const SipMessage& msg); + ClientSubscription* makeClientSubscription(const SipMessage& msg); + + ServerInviteSession* makeServerInviteSession(const SipMessage& msg); + ServerSubscription* makeServerSubscription(const SipMessage& msg); + + //matches using tid of response + bool matches(const SipMessage& msg); + void handleTargetRefresh(const SipMessage& msg); + + void flowTerminated(); + + DialogUsageManager& mDum; + DialogSet& mDialogSet; + DialogId mId; + + std::list<ClientSubscription*> mClientSubscriptions; + std::list<ServerSubscription*> mServerSubscriptions; + InviteSession* mInviteSession; + + NetworkAssociation mNetworkAssociation; + + //invariants + typedef enum // need to add + { + Invitation, // INVITE dialog + Subscription, // Created by a SUBSCRIBE / NOTIFY / REFER + Fake // Not really a dialog (e.g. created by a REGISTER) + } DialogType; + + DialogType mType; // !jf! is this necessary? + NameAddrs mRouteSet; + + //variants + NameAddr mLocalContact; + unsigned int mLocalCSeq; + unsigned int mRemoteCSeq; + NameAddr mRemoteTarget; + NameAddr mLocalNameAddr; + NameAddr mRemoteNameAddr; + CallID mCallId; + + // used to capture the 2xx expiration value for the initial subscription response + UInt32 mDefaultSubExpiration; + + // store until we get a response (non-401/407) + // !jf! this shouldn't be necessary + // !dcm! -- no longer used for subscriptions, INVITE will take more thought/work + typedef std::map<int, SharedPtr<SipMessage> > RequestMap; + RequestMap mRequests; + + AppDialog* mAppDialog; + + bool mDestroying; + bool mReUseDialogSet; + + friend EncodeStream& operator<<(EncodeStream& strm, const Dialog& dialog); +}; + +EncodeStream& operator<<(EncodeStream& strm, const Dialog& dialog); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogEventHandler.hxx b/src/libs/resiprocate/resip/dum/DialogEventHandler.hxx new file mode 100644 index 00000000..8dac81af --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogEventHandler.hxx @@ -0,0 +1,210 @@ +#if !defined(RESIP_DialogEventHandler_HXX) +#define RESIP_DialogEventHandler_HXX + +#include "resip/dum/DialogEventInfo.hxx" +#include "resip/dum/InviteSessionHandler.hxx" + +namespace resip +{ + +class DialogEvent +{ +public: + DialogEvent() {} + DialogEvent(const DialogEvent& rhs) {} + virtual ~DialogEvent() {} + + enum DialogEventType + { + DialogEventType_Trying, + DialogEventType_Proceeding, + DialogEventType_Early, + DialogEventType_Confirmed, + DialogEventType_Terminated, + DialogEventType_MultipleEvents + }; + virtual DialogEventType getType() const = 0; +}; + +class TryingDialogEvent : public DialogEvent +{ +public: + TryingDialogEvent(const DialogEventInfo& info, const SipMessage& initialInvite) + : mEventInfo(info), mInitialInvite(initialInvite) + {} + TryingDialogEvent(const TryingDialogEvent& rhs) + : mEventInfo(rhs.mEventInfo), mInitialInvite(rhs.mInitialInvite) + {} + virtual ~TryingDialogEvent() {} + + const DialogEventInfo& getEventInfo() const { return mEventInfo; } + const SipMessage& getInitialInvite() const { return mInitialInvite; } + DialogEventType getType() const { return DialogEvent::DialogEventType_Trying; } + +private: + DialogEventInfo mEventInfo; + SipMessage mInitialInvite; +}; + +class ProceedingDialogEvent : public DialogEvent +{ +public: + ProceedingDialogEvent(const DialogEventInfo& info) + : mEventInfo(info) + {} + ProceedingDialogEvent(const ProceedingDialogEvent& rhs) + : mEventInfo(rhs.mEventInfo) + {} + virtual ~ProceedingDialogEvent() {} + + const DialogEventInfo& getEventInfo() const { return mEventInfo; } + DialogEventType getType() const { return DialogEvent::DialogEventType_Proceeding; } + +private: + DialogEventInfo mEventInfo; +}; + +class EarlyDialogEvent : public DialogEvent +{ +public: + EarlyDialogEvent(const DialogEventInfo& info) + : mEventInfo(info) + {} + EarlyDialogEvent(const EarlyDialogEvent& rhs) + : mEventInfo(rhs.mEventInfo) + { + } + virtual ~EarlyDialogEvent() {} + + const DialogEventInfo& getEventInfo() const { return mEventInfo; } + DialogEventType getType() const { return DialogEvent::DialogEventType_Early; } + +private: + DialogEventInfo mEventInfo; +}; + +class ConfirmedDialogEvent : public DialogEvent +{ +public: + ConfirmedDialogEvent(const DialogEventInfo& info) + : mEventInfo(info) + {} + ConfirmedDialogEvent(const ConfirmedDialogEvent& rhs) + : mEventInfo(rhs.mEventInfo) + {} + virtual ~ConfirmedDialogEvent() {} + + const DialogEventInfo& getEventInfo() const { return mEventInfo; } + DialogEventType getType() const { return DialogEvent::DialogEventType_Confirmed; } + +private: + DialogEventInfo mEventInfo; +}; + +class TerminatedDialogEvent : public DialogEvent +{ +public: + TerminatedDialogEvent(const DialogEventInfo& info, InviteSessionHandler::TerminatedReason reason, int code) + : mEventInfo(info), mReason(reason), mCode(code) + {} + TerminatedDialogEvent(const TerminatedDialogEvent& rhs) + : mEventInfo(rhs.mEventInfo), mReason(rhs.mReason), mCode(rhs.mCode) + {} + virtual ~TerminatedDialogEvent() {} + + const DialogEventInfo& getEventInfo() const { return mEventInfo; } + InviteSessionHandler::TerminatedReason getTerminatedReason() const { return mReason; } + int getResponseCode() const { return mCode; } + DialogEventType getType() const { return DialogEvent::DialogEventType_Terminated; } + +private: + DialogEventInfo mEventInfo; + InviteSessionHandler::TerminatedReason mReason; + int mCode; +}; + +class MultipleEventDialogEvent : public DialogEvent +{ +public: + typedef std::vector< SharedPtr<DialogEvent> > EventVector; + MultipleEventDialogEvent(EventVector& events) + : mEvents(events) + {} + MultipleEventDialogEvent(const MultipleEventDialogEvent& rhs) + : mEvents(rhs.mEvents) + {} + virtual ~MultipleEventDialogEvent() {} + + const EventVector& getEvents() const { return mEvents; } + DialogEventType getType() const { return DialogEvent::DialogEventType_MultipleEvents; } + +private: + EventVector mEvents; +}; + +class DialogEventHandler +{ + public: + virtual ~DialogEventHandler() {} + virtual void onTrying(const TryingDialogEvent& evt)=0; + virtual void onProceeding(const ProceedingDialogEvent& evt)=0; + virtual void onEarly(const EarlyDialogEvent& evt)=0; + virtual void onConfirmed(const ConfirmedDialogEvent& evt)=0; + virtual void onTerminated(const TerminatedDialogEvent& evt)=0; + virtual void onMultipleEvents(const MultipleEventDialogEvent& evt)=0; +}; + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogEventInfo.cxx b/src/libs/resiprocate/resip/dum/DialogEventInfo.cxx new file mode 100644 index 00000000..9e6186ba --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogEventInfo.cxx @@ -0,0 +1,325 @@ +#include "resip/dum/DialogEventInfo.hxx" +#include "resip/dum/InviteSession.hxx" + +namespace resip +{ + +DialogEventInfo::DialogEventInfo() +: mState(DialogEventInfo::Trying), + mDialogId(Data::Empty, Data::Empty, Data::Empty), + mDirection(DialogEventInfo::Initiator), + mInviteSession(InviteSessionHandle::NotValid()), + mCreationTimeSeconds(0), + mReplaced(false) +{ +} + +DialogEventInfo::DialogEventInfo(const DialogEventInfo& rhs) +: mState(rhs.mState), + mDialogEventId(rhs.mDialogEventId), + mDialogId(rhs.mDialogId), + mDirection(rhs.mDirection), + mInviteSession(rhs.mInviteSession), + mReferredBy(rhs.mReferredBy.get() ? new NameAddr(*rhs.mReferredBy) : 0), + mRouteSet(rhs.mRouteSet), + mLocalIdentity(rhs.mLocalIdentity), + mRemoteIdentity(rhs.mRemoteIdentity), + mLocalTarget(rhs.mLocalTarget), + mRemoteTarget(rhs.mRemoteTarget.get() ? new Uri(*rhs.mRemoteTarget) : 0), + mCreationTimeSeconds(rhs.mCreationTimeSeconds), + mReplaced(rhs.mReplaced) +{ + if (rhs.mReplacesId.get()) + { + mReplacesId = std::auto_ptr<DialogId>(new DialogId(rhs.mReplacesId->getCallId(), + rhs.mReplacesId->getLocalTag(), + rhs.mReplacesId->getRemoteTag())); + } + if (rhs.mLocalOfferAnswer.get()) + { + mLocalOfferAnswer = std::auto_ptr<Contents>(rhs.mLocalOfferAnswer->clone()); + } + if (rhs.mRemoteOfferAnswer.get()) + { + mRemoteOfferAnswer = std::auto_ptr<Contents>(rhs.mRemoteOfferAnswer->clone()); + } +} + +DialogEventInfo& +DialogEventInfo::operator=(const DialogEventInfo& dialogEventInfo) +{ + if (this != &dialogEventInfo) + { + mDialogId = dialogEventInfo.mDialogId; + mState = dialogEventInfo.mState; + mCreationTimeSeconds = dialogEventInfo.mCreationTimeSeconds; + mDialogEventId = dialogEventInfo.mDialogEventId; + mDirection = dialogEventInfo.mDirection; + mInviteSession = dialogEventInfo.mInviteSession; + mLocalIdentity = dialogEventInfo.mLocalIdentity; + + mLocalOfferAnswer.reset(0); + mReferredBy.reset(0); + mRemoteOfferAnswer.reset(0); + mRemoteTarget.reset(0); + mReplacesId.reset(0); + + if(dialogEventInfo.mLocalOfferAnswer.get()) + { + mLocalOfferAnswer.reset(dialogEventInfo.mLocalOfferAnswer->clone()); + } + + if(dialogEventInfo.mReferredBy.get()) + { + mReferredBy.reset((NameAddr*)(dialogEventInfo.mReferredBy->clone())); + } + + if(dialogEventInfo.mRemoteOfferAnswer.get()) + { + mRemoteOfferAnswer.reset(dialogEventInfo.mRemoteOfferAnswer->clone()); + } + + if(dialogEventInfo.mRemoteTarget.get()) + { + mRemoteTarget.reset((Uri*)dialogEventInfo.mRemoteTarget->clone()); + } + + if(dialogEventInfo.mReplacesId.get()) + { + mReplacesId.reset( + new DialogId(dialogEventInfo.mReplacesId->getDialogSetId(), + dialogEventInfo.mReplacesId->getRemoteTag())); + } + + mLocalTarget = dialogEventInfo.mLocalTarget; + mRemoteIdentity = dialogEventInfo.mRemoteIdentity; + mRouteSet = dialogEventInfo.mRouteSet; + mReplaced = dialogEventInfo.mReplaced; + } + return *this; +} + +bool +DialogEventInfo::operator==(const DialogEventInfo& rhs) const +{ + return (mDialogEventId == rhs.mDialogEventId); +} + +bool +DialogEventInfo::operator!=(const DialogEventInfo& rhs) const +{ + return (mDialogEventId != rhs.mDialogEventId); +} + +bool +DialogEventInfo::operator<(const DialogEventInfo& rhs) const +{ + return (mDialogEventId < rhs.mDialogEventId); +} + +const DialogEventInfo::State& +DialogEventInfo::getState() const +{ + return mState; +} + +const Data& +DialogEventInfo::getDialogEventId() const +{ + return mDialogEventId; +} + +const Data& +DialogEventInfo::getCallId() const +{ + return mDialogId.getCallId(); +} + +const Data& +DialogEventInfo::getLocalTag() const +{ + return mDialogId.getLocalTag(); +} + +bool +DialogEventInfo::hasRemoteTag() const +{ + return (mDialogId.getRemoteTag() != Data::Empty); +} + +const Data& +DialogEventInfo::getRemoteTag() const +{ + return mDialogId.getRemoteTag(); +} + +bool +DialogEventInfo::hasRefferedBy() const +{ + return (mReferredBy.get() != NULL); +} + +const NameAddr& +DialogEventInfo::getRefferredBy() const +{ + return *mReferredBy; +} + +const NameAddr& +DialogEventInfo::getLocalIdentity() const +{ + return mLocalIdentity; +} + +const NameAddr& +DialogEventInfo::getRemoteIdentity() const +{ + return mRemoteIdentity; +} + +const Uri& +DialogEventInfo::getLocalTarget() const +{ + return mLocalTarget; +} + +bool +DialogEventInfo::hasRouteSet() const +{ + return false; +} + +const NameAddrs& +DialogEventInfo::getRouteSet() const +{ + return mRouteSet; +} + +bool +DialogEventInfo::hasRemoteTarget() const +{ + return (mRemoteTarget.get() != NULL); +} + +const Uri& +DialogEventInfo::getRemoteTarget() const +{ + return *mRemoteTarget; +} + +const Contents& +DialogEventInfo::getLocalOfferAnswer() const +{ + if (mInviteSession.isValid()) + { + if (mInviteSession->hasLocalOfferAnswer()) + { + return mInviteSession->getLocalOfferAnswer(); + } + } + assert(mLocalOfferAnswer.get() != NULL); + return *mLocalOfferAnswer; +} + +const Contents& +DialogEventInfo::getRemoteOfferAnswer() const +{ + if (mInviteSession.isValid()) + { + if (mInviteSession->hasRemoteOfferAnswer()) + { + return mInviteSession->getRemoteOfferAnswer(); + } + } + assert(mRemoteOfferAnswer.get() != NULL); + return *mRemoteOfferAnswer; +} + +bool +DialogEventInfo::hasLocalOfferAnswer() const +{ + return (mInviteSession.isValid() ? mInviteSession->hasLocalOfferAnswer() : mLocalOfferAnswer.get() != 0); +} + +bool +DialogEventInfo::hasRemoteOfferAnswer() const +{ + return (mInviteSession.isValid() ? mInviteSession->hasRemoteOfferAnswer() : mRemoteOfferAnswer.get() != 0); +} + +UInt64 +DialogEventInfo::getDurationSeconds() const +{ + UInt64 delta = Timer::getTimeSecs() - mCreationTimeSeconds; + return delta; +} + +bool +DialogEventInfo::hasReplacesId() const +{ + return (mReplacesId.get() != 0); +} + +const DialogId& +DialogEventInfo::getReplacesId() const +{ + return *mReplacesId; +} + +DialogEventInfo::Direction +DialogEventInfo::getDirection() const +{ + return mDirection; +} + +} // namespace resip + +/* ==================================================================== +* The Vovida Software License, Version 1.0 +* +* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. The names "VOCAL", "Vovida Open Communication Application Library", +* and "Vovida Open Communication Application Library (VOCAL)" must +* not be used to endorse or promote products derived from this +* software without prior written permission. For written +* permission, please contact vocal@vovida.org. +* +* 4. Products derived from this software may not be called "VOCAL", nor +* may "VOCAL" appear in their name, without prior written +* permission of Vovida Networks, Inc. +* +* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +* +* ==================================================================== +* +* This software consists of voluntary contributions made by Vovida +* Networks, Inc. and many individuals on behalf of Vovida Networks, +* Inc. For more information on Vovida Networks, Inc., please see +* <http://www.vovida.org/>. +* +*/ diff --git a/src/libs/resiprocate/resip/dum/DialogEventInfo.hxx b/src/libs/resiprocate/resip/dum/DialogEventInfo.hxx new file mode 100644 index 00000000..d93c2aea --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogEventInfo.hxx @@ -0,0 +1,160 @@ +#if !defined(RESIP_DialogEventInfo_hxx) +#define RESIP_DialogEventInfo_hxx + +#include <memory> +#include "resip/stack/NameAddr.hxx" +#include "resip/dum/DialogId.hxx" +#include "resip/dum/Handles.hxx" +#include "resip/stack/Contents.hxx" + +namespace resip +{ + +//As uac, one is created for DialogSet; given to first dialog, new instances are +//generated for each fork. As uas, created at the same time as a Dialog. +class DialogEventInfo +{ + public: + DialogEventInfo(void); + DialogEventInfo(const DialogEventInfo& rhs); + DialogEventInfo& operator=(const DialogEventInfo& dialogEventInfo); + + //based on DialogEventId + bool operator==(const DialogEventInfo& rhs) const; + bool operator!=(const DialogEventInfo& rhs) const; + bool operator<(const DialogEventInfo& rhs) const; + + enum Direction + { + Initiator, + Recipient + }; + + enum State + { + Trying = 0, + Proceeding, + Early, + Confirmed, + Terminated + }; + + const State& getState() const; + + const Data& getDialogEventId() const; + + const Data& getCallId() const; + const Data& getLocalTag() const; + bool hasRemoteTag() const; + const Data& getRemoteTag() const; + + bool hasRefferedBy() const; + const NameAddr& getRefferredBy() const; + + const NameAddr& getLocalIdentity() const; + const NameAddr& getRemoteIdentity() const; + const Uri& getLocalTarget() const; + //has... below only applicable when direction is outgoing + bool hasRouteSet() const; + const NameAddrs& getRouteSet() const; + bool hasRemoteTarget() const; + const Uri& getRemoteTarget() const; + + // cache the first one, then forevermore lookup from InviteSession + const Contents& getLocalOfferAnswer() const; + const Contents& getRemoteOfferAnswer() const; + bool hasLocalOfferAnswer() const; + bool hasRemoteOfferAnswer() const; + + UInt64 getDurationSeconds() const; // in seconds + + bool hasReplacesId() const; + const DialogId& getReplacesId() const; + + Direction getDirection() const; + + protected: + friend class DialogEventStateManager; + + State mState; + Data mDialogEventId; //unique for all Dialogs at this ua...may hash local + + //callid, all 3 tags for forks. Or could cycles an + //integer...hash memory location+salt at cons time(might be easiest). + DialogId mDialogId; + Direction mDirection; + //ID of the dialog this dialog replaced. + std::auto_ptr<DialogId> mReplacesId; + InviteSessionHandle mInviteSession; + + std::auto_ptr<NameAddr> mReferredBy; + +//could back-point to dialog for this information to save space + NameAddrs mRouteSet; + NameAddr mLocalIdentity; + NameAddr mRemoteIdentity; + Uri mLocalTarget; + std::auto_ptr<Uri> mRemoteTarget; + + UInt64 mCreationTimeSeconds; + + std::auto_ptr<Contents> mLocalOfferAnswer; + std::auto_ptr<Contents> mRemoteOfferAnswer; + + private: + bool mReplaced; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogEventStateManager.cxx b/src/libs/resiprocate/resip/dum/DialogEventStateManager.cxx new file mode 100644 index 00000000..dcac20cd --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogEventStateManager.cxx @@ -0,0 +1,474 @@ +#include "resip/dum/DialogEventStateManager.hxx" +#include "rutil/Random.hxx" +#include "rutil/Logger.hxx" + +namespace resip +{ + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +DialogEventStateManager::DialogEventStateManager() + : mDialogEventHandler(0) +{ +} + +DialogEventStateManager::~DialogEventStateManager() +{ +} + +// we've received an INVITE +void +DialogEventStateManager::onTryingUas(Dialog& dialog, const SipMessage& invite) +{ + DialogEventInfo* eventInfo = new DialogEventInfo(); + eventInfo->mDialogEventId = Random::getVersion4UuidUrn(); // !jjg! is this right? + eventInfo->mDialogId = dialog.getId(); + eventInfo->mDirection = DialogEventInfo::Recipient; + eventInfo->mCreationTimeSeconds = Timer::getTimeSecs(); + eventInfo->mInviteSession = InviteSessionHandle::NotValid(); + eventInfo->mRemoteOfferAnswer = (invite.getContents() != NULL ? std::auto_ptr<Contents>(invite.getContents()->clone()) : std::auto_ptr<Contents>()); + eventInfo->mLocalIdentity = dialog.getLocalNameAddr(); + eventInfo->mLocalTarget = dialog.getLocalContact().uri(); // !slg! TODO - fix me - the Dialog stored local contact has an empty hostname so that the stack will fill it in + eventInfo->mRemoteIdentity = dialog.getRemoteNameAddr(); + eventInfo->mRemoteTarget = std::auto_ptr<Uri>(new Uri(dialog.getRemoteTarget().uri())); + eventInfo->mRouteSet = dialog.getRouteSet(); + eventInfo->mState = DialogEventInfo::Trying; + + if (invite.exists(h_Replaces) && + invite.header(h_Replaces).isWellFormed()) + { + Data replacesToTag = invite.header(h_Replaces).exists(p_toTag) ? invite.header(h_Replaces).param(p_toTag) : Data::Empty; + Data replacesFromTag = invite.header(h_Replaces).exists(p_fromTag) ? invite.header(h_Replaces).param(p_fromTag) : Data::Empty; + + eventInfo->mReplacesId = std::auto_ptr<DialogId>(new DialogId(invite.header(h_Replaces).value(), + replacesToTag, + replacesFromTag)); + + std::map<DialogId, DialogEventInfo*, DialogIdComparator>::iterator it = mDialogIdToEventInfo.find(*(eventInfo->mReplacesId)); + if (it != mDialogIdToEventInfo.end()) + { + it->second->mReplaced = true; + } + } + if (invite.exists(h_ReferredBy) && + invite.header(h_ReferredBy).isWellFormed()) + { + eventInfo->mReferredBy = std::auto_ptr<NameAddr>(new NameAddr(invite.header(h_ReferredBy))); + } + + mDialogIdToEventInfo[dialog.getId()] = eventInfo; + + TryingDialogEvent evt(*eventInfo, invite); + mDialogEventHandler->onTrying(evt); +} + +// we've sent an INVITE +void +DialogEventStateManager::onTryingUac(DialogSet& dialogSet, const SipMessage& invite) +{ + DialogId fakeId(dialogSet.getId(), Data::Empty); + std::map<DialogId, DialogEventInfo*, DialogIdComparator>::iterator it = mDialogIdToEventInfo.find(fakeId); + + DialogEventInfo* eventInfo = 0; + + if (it != mDialogIdToEventInfo.end()) + { + // .jjg. we will get in here if our INVITE gets challenged; just swallow the onTrying event in this case + eventInfo = it->second; + if (eventInfo->mState == DialogEventInfo::Trying) + { + return; + } + } + else + { + eventInfo = new DialogEventInfo(); + } + + eventInfo->mDialogEventId = Random::getVersion4UuidUrn(); + eventInfo->mDialogId = DialogId(dialogSet.getId(), Data::Empty); + eventInfo->mDirection = DialogEventInfo::Initiator; + eventInfo->mCreationTimeSeconds = Timer::getTimeSecs(); + eventInfo->mInviteSession = InviteSessionHandle::NotValid(); + eventInfo->mLocalIdentity = invite.header(h_From); + // ?bwc? Has something already checked for well-formedness here? + // Maybe DialogSet? We need to be absolutely certain that this exists and is + // well-formed. Assert for now. + assert(!invite.empty(h_Contacts)); + assert(invite.header(h_Contacts).front().isWellFormed()); + eventInfo->mLocalTarget = invite.header(h_Contacts).front().uri(); + eventInfo->mRemoteIdentity = invite.header(h_To); + eventInfo->mLocalOfferAnswer = (invite.getContents() != NULL ? std::auto_ptr<Contents>(invite.getContents()->clone()) : std::auto_ptr<Contents>()); + eventInfo->mState = DialogEventInfo::Trying; + + if (invite.exists(h_ReferredBy) && + invite.header(h_ReferredBy).isWellFormed()) + { + eventInfo->mReferredBy = std::auto_ptr<NameAddr>(new NameAddr(invite.header(h_ReferredBy))); + } + + mDialogIdToEventInfo[eventInfo->mDialogId] = eventInfo; + + TryingDialogEvent evt(*eventInfo, invite); + mDialogEventHandler->onTrying(evt); +} + +// we've received a 1xx response without a remote tag +void +DialogEventStateManager::onProceedingUac(const DialogSet& dialogSet, const SipMessage& response) +{ + DialogId fakeId(dialogSet.getId(), Data::Empty); + std::map<DialogId, DialogEventInfo*, DialogIdComparator>::iterator it = mDialogIdToEventInfo.lower_bound(fakeId); + if (it != mDialogIdToEventInfo.end() && + it->first.getDialogSetId() == dialogSet.getId()) + { + if (it->first.getRemoteTag().empty()) + { + // happy day case; no forks yet; e.g INVITE/1xx (no tag)/1xx (no tag) + DialogEventInfo* eventInfo = it->second; + eventInfo->mState = DialogEventInfo::Proceeding; + if (!response.empty(h_Contacts)) + { + // ?bwc? Has something already checked for well-formedness here? + // Maybe DialogSet? Assert for now. + assert(response.header(h_Contacts).front().isWellFormed()); + eventInfo->mRemoteTarget = std::auto_ptr<Uri>(new Uri(response.header(h_Contacts).front().uri())); + } + ProceedingDialogEvent evt(*eventInfo); + mDialogEventHandler->onProceeding(evt); + } + else + { + // forking; e.g. INVITE/180 (tag #1)/180 (no tag) + + // .jjg. The remote sender of the 180 (no tag) should either 'put up or shut up' as Byron put it + // so we'll just ignore this... + } + } +} + +// UAC: we've received a 1xx response WITH a remote tag +// UAS: we've sent a 1xx response WITH a local tag +void +DialogEventStateManager::onEarly(const Dialog& dialog, InviteSessionHandle is) +{ + DialogEventInfo* eventInfo = findOrCreateDialogInfo(dialog); + + if (eventInfo) + { + eventInfo->mState = DialogEventInfo::Early; + eventInfo->mRouteSet = dialog.getRouteSet(); + eventInfo->mInviteSession = is; + + // local or remote target might change due to an UPDATE or re-INVITE + eventInfo->mLocalTarget = dialog.getLocalContact().uri(); // !slg! TODO - fix me - the Dialog stored local contact has an empty hostname so that the stack will fill it in + eventInfo->mRemoteTarget = std::auto_ptr<Uri>(new Uri(dialog.getRemoteTarget().uri())); + + EarlyDialogEvent evt(*eventInfo); + mDialogEventHandler->onEarly(evt); + } +} + +void +DialogEventStateManager::onConfirmed(const Dialog& dialog, InviteSessionHandle is) +{ + DialogEventInfo* eventInfo = findOrCreateDialogInfo(dialog); + + if (eventInfo) + { + eventInfo->mInviteSession = is; + eventInfo->mRouteSet = dialog.getRouteSet(); // won't change due to re-INVITEs, but is + // needed for the Trying --> Confirmed transition + eventInfo->mState = DialogEventInfo::Confirmed; + + // local or remote target might change due to an UPDATE or re-INVITE + eventInfo->mLocalTarget = dialog.getLocalContact().uri(); // !slg! TODO - fix me - the Dialog stored local contact has an empty hostname so that the stack will fill it in + eventInfo->mRemoteTarget = std::auto_ptr<Uri>(new Uri(dialog.getRemoteTarget().uri())); + + // for the dialog that got the 200 OK + SharedPtr<ConfirmedDialogEvent> confirmedEvt(new ConfirmedDialogEvent(*eventInfo)); + + //mDialogEventHandler->onConfirmed(confirmedEvt); + MultipleEventDialogEvent::EventVector events; + + // kill off any other dialogs in this dialog set, since certain proxy/registrars (like SER and sipX) + // won't bother giving us updates on their status anyways! + const DialogSetId& dialogSetId = dialog.getId().getDialogSetId(); + DialogId fakeId(dialogSetId, Data::Empty); + std::map<DialogId, DialogEventInfo*, DialogIdComparator>::iterator it = mDialogIdToEventInfo.lower_bound(fakeId); + while (it != mDialogIdToEventInfo.end() && + it->first.getDialogSetId() == dialogSetId) + { + DialogEventInfo::State dialogState = it->second->getState(); + if (dialogState == DialogEventInfo::Proceeding || dialogState == DialogEventInfo::Early) + { + // .jjg. we're killing a *specific* dialog *after* the successful completion of the initial INVITE transaction; + // so just elminate this dialog, not the entire dialogset + SharedPtr<TerminatedDialogEvent> evt(onDialogTerminatedImpl(it->second, InviteSessionHandler::RemoteCancel)); + events.push_back(evt); + delete it->second; + mDialogIdToEventInfo.erase(it++); + } + else + { + it++; + } + } + + if (events.size() > 0) + { + events.push_back(confirmedEvt); + MultipleEventDialogEvent multipleEvt(events); + mDialogEventHandler->onMultipleEvents(multipleEvt); + } + else + { + mDialogEventHandler->onConfirmed(*confirmedEvt); + } + } +} + +void +DialogEventStateManager::onTerminated(const Dialog& dialog, const SipMessage& msg, InviteSessionHandler::TerminatedReason reason) +{ + std::map<DialogId, DialogEventInfo*, DialogIdComparator>::iterator it = mDialogIdToEventInfo.find(dialog.getId()); + if (it != mDialogIdToEventInfo.end()) + { + DialogEventInfo::State dialogState = it->second->getState(); + if (dialogState == DialogEventInfo::Confirmed) + { + // .jjg. we're killing a *specific* dialog *after* the successful completion of the initial INVITE transaction; + // so just elminate this dialog, not the entire dialogset + std::auto_ptr<TerminatedDialogEvent> evt(onDialogTerminatedImpl(it->second, reason, getResponseCode(msg), getFrontContact(msg))); + mDialogEventHandler->onTerminated(*evt); + delete it->second; + mDialogIdToEventInfo.erase(it++); + } + else + { + onDialogSetTerminatedImpl(dialog.getId().getDialogSetId(), msg, reason); + } + } + else + { + onDialogSetTerminatedImpl(dialog.getId().getDialogSetId(), msg, reason); + } +} + +void +DialogEventStateManager::onTerminated(const DialogSet& dialogSet, const SipMessage& msg, InviteSessionHandler::TerminatedReason reason) +{ + onDialogSetTerminatedImpl(dialogSet.getId(), msg, reason); +} + +void +DialogEventStateManager::onDialogSetTerminatedImpl(const DialogSetId& dialogSetId, const SipMessage& msg, InviteSessionHandler::TerminatedReason reason) +{ + DialogEventInfo* eventInfo = NULL; + + /** + * cases: + * 1) UAC: INVITE/180 (tag #1)/180 (tag #2)/486 (tag #2) + * 2) UAS: INVITE/100/486 (tag #1) + * 3) UAS: INVITE/100/180 (tag #1)/486 (tag #1) + */ + + //find dialogSet. All non-confirmed dialogs are destroyed by this event. + //Confirmed dialogs are only destroyed by an exact match. + + DialogId fakeId(dialogSetId, Data::Empty); + std::map<DialogId, DialogEventInfo*, DialogIdComparator>::iterator it = mDialogIdToEventInfo.lower_bound(fakeId); + + while (it != mDialogIdToEventInfo.end() && + it->first.getDialogSetId() == dialogSetId) + { + eventInfo = it->second; + std::auto_ptr<TerminatedDialogEvent> evt(onDialogTerminatedImpl(eventInfo, reason, getResponseCode(msg), getFrontContact(msg))); + mDialogEventHandler->onTerminated(*evt); + delete it->second; + mDialogIdToEventInfo.erase(it++); + } +} + +TerminatedDialogEvent* +DialogEventStateManager::onDialogTerminatedImpl(DialogEventInfo* eventInfo, + InviteSessionHandler::TerminatedReason reason, + int responseCode, + Uri* remoteTarget) +{ + eventInfo->mState = DialogEventInfo::Terminated; + + // .jjg. when we get an INVITE w/Replaces, we mark the replaced dialog event info + // as 'replaced' (see onTryingUas); + // when the replaced dialog is ended, it will be ended normally with a BYE or CANCEL, + // but since we've marked it as 'replaced' we can update the termination reason + InviteSessionHandler::TerminatedReason actualReason = reason; + + if (eventInfo->mReplaced) + { + actualReason = InviteSessionHandler::Replaced; + } + + if (remoteTarget) + { + eventInfo->mRemoteTarget = std::auto_ptr<Uri>(remoteTarget); + } + + TerminatedDialogEvent* evt = new TerminatedDialogEvent(*eventInfo, actualReason, responseCode); + return evt; + //mDialogEventHandler->onTerminated(evt); +} + +int +DialogEventStateManager::getResponseCode(const SipMessage& msg) +{ + int respCode = 0; + if (msg.isResponse()) + { + respCode = msg.header(h_StatusLine).responseCode(); + } + return respCode; +} + +Uri* +DialogEventStateManager::getFrontContact(const SipMessage& msg) +{ + Uri* pContact = NULL; + if (msg.isResponse()) + { + if (!msg.empty(h_Contacts)) + { + // ?bwc? Has something already checked for well-formedness here? + // Maybe DialogSet? Assert for now. + assert(msg.header(h_Contacts).front().isWellFormed()); + pContact = new Uri(msg.header(h_Contacts).front().uri()); + } + } + return pContact; +} + +DialogEventStateManager::DialogEventInfos +DialogEventStateManager::getDialogEventInfo() const +{ + DialogEventStateManager::DialogEventInfos infos; + std::map<DialogId, DialogEventInfo*, DialogIdComparator>::const_iterator it = mDialogIdToEventInfo.begin(); + for (; it != mDialogIdToEventInfo.end(); it++) + { + infos.push_back(*(it->second)); + } + return infos; +} + +DialogEventInfo* +DialogEventStateManager::findOrCreateDialogInfo(const Dialog& dialog) +{ + DialogEventInfo* eventInfo = NULL; + + /** + * cases: + * 1) INVITE/180 (no tag)/183 (tag) + * 2) INVITE/180 (tag) + * 3) INVITE/180 (tag #1)/180 (tag #2) + * + */ + + std::map<DialogId, DialogEventInfo*, DialogIdComparator>::iterator it = mDialogIdToEventInfo.find(dialog.getId()); + + if (it != mDialogIdToEventInfo.end()) + { + return it->second; + } + else + { + // either we have a dialog set id with an empty remote tag, or we have other dialog(s) with different + // remote tag(s) + DialogId fakeId(dialog.getId().getDialogSetId(), Data::Empty); + it = mDialogIdToEventInfo.lower_bound(fakeId); + + if (it != mDialogIdToEventInfo.end() && + it->first.getDialogSetId() == dialog.getId().getDialogSetId()) + { + if (it->first.getRemoteTag().empty()) + { + // convert this bad boy into a full on Dialog + eventInfo = it->second; + mDialogIdToEventInfo.erase(it); + eventInfo->mDialogId = dialog.getId(); + } + else + { + // clone this fellow member dialog, initializing it with a new id and creation time + DialogEventInfo* newForkInfo = new DialogEventInfo(*(it->second)); + newForkInfo->mDialogEventId = Random::getVersion4UuidUrn(); + newForkInfo->mCreationTimeSeconds = Timer::getTimeSecs(); + newForkInfo->mDialogId = dialog.getId(); + newForkInfo->mRemoteIdentity = dialog.getRemoteNameAddr(); + newForkInfo->mRemoteTarget = std::auto_ptr<Uri>(new Uri(dialog.getRemoteTarget().uri())); + newForkInfo->mRouteSet = dialog.getRouteSet(); + eventInfo = newForkInfo; + } + } + else + { + // .jjg. this can happen if onTryingUax(..) wasn't called yet for this dialog (set) id + DebugLog(<< "DialogSetId " << fakeId << " was not found! This indicates a bug; onTryingUax() should have been called first!"); + return 0; + } + } + + mDialogIdToEventInfo[dialog.getId()] = eventInfo; + + return eventInfo; +} + +} // namespace resip + +/* ==================================================================== +* The Vovida Software License, Version 1.0 +* +* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. The names "VOCAL", "Vovida Open Communication Application Library", +* and "Vovida Open Communication Application Library (VOCAL)" must +* not be used to endorse or promote products derived from this +* software without prior written permission. For written +* permission, please contact vocal@vovida.org. +* +* 4. Products derived from this software may not be called "VOCAL", nor +* may "VOCAL" appear in their name, without prior written +* permission of Vovida Networks, Inc. +* +* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +* +* ==================================================================== +* +* This software consists of voluntary contributions made by Vovida +* Networks, Inc. and many individuals on behalf of Vovida Networks, +* Inc. For more information on Vovida Networks, Inc., please see +* <http://www.vovida.org/>. +* +*/ diff --git a/src/libs/resiprocate/resip/dum/DialogEventStateManager.hxx b/src/libs/resiprocate/resip/dum/DialogEventStateManager.hxx new file mode 100644 index 00000000..d9547b81 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogEventStateManager.hxx @@ -0,0 +1,94 @@ +#if !defined(RESIP_DialogEventStateManager_HXX) +#define RESIP_DialogEventStateManager_HXX + +#include "resip/dum/DialogEventInfo.hxx" +#include "resip/dum/DialogEventHandler.hxx" +#include "resip/dum/InviteSessionHandler.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/DialogSet.hxx" + +namespace resip +{ + +/** + * Implements the FSM for dialog state as spec'd in RFC 4235. + * Called from DialogSet, ClientInviteSession, and ServerInviteSession. + */ +class DialogEventStateManager +{ + public: + typedef std::vector<DialogEventInfo> DialogEventInfos; + DialogEventInfos getDialogEventInfo() const; + + virtual ~DialogEventStateManager(); + +private: + DialogEventStateManager(); + + void onTryingUas(Dialog& dialog, const SipMessage& invite); + void onTryingUac(DialogSet& dialogSet, const SipMessage& invite); + void onProceedingUac(const DialogSet& dialogSet, const SipMessage& response); + + //?dcm? how is direction determined when the onEarly is the first use of + //this dialog? + void onEarly(const Dialog& dialog, InviteSessionHandle is); + + void onConfirmed(const Dialog& dialog, InviteSessionHandle is); + void onTerminated(const Dialog& dialog, const SipMessage& msg, InviteSessionHandler::TerminatedReason reason); + + void onTerminated(const DialogSet& dialogSet, const SipMessage& msg, InviteSessionHandler::TerminatedReason reason); + + + // order by DialogSet, such that the following ordering occurs + // DialogSetId remoteTag + // a null + // a 1 + // a 2 + // b 1 + // b 2 + class DialogIdComparator + { + public: + bool operator()(const DialogId& x, const DialogId& y) const + { + if (x.getDialogSetId() == y.getDialogSetId()) + { + return (x.getRemoteTag() < y.getRemoteTag()); + } + return (x.getDialogSetId() < y.getDialogSetId()); + } + }; + + DialogEventInfo* findOrCreateDialogInfo(const Dialog& dialog); + + void onDialogSetTerminatedImpl(const DialogSetId& dialogSetId, const SipMessage& msg, InviteSessionHandler::TerminatedReason reason); + TerminatedDialogEvent* onDialogTerminatedImpl(DialogEventInfo* eventInfo, InviteSessionHandler::TerminatedReason reason, + int responseCode = 0, Uri* remoteTarget = NULL); + + static int getResponseCode(const SipMessage& msg); + static Uri* getFrontContact(const SipMessage& msg); + +private: + + friend class DialogUsageManager; + friend class ServerInviteSession; + friend class ClientInviteSession; + friend class InviteSession; + friend class DialogSet; + + // disabled + DialogEventStateManager(const DialogEventStateManager& orig); + + // .jjg. we'll only have the DialogSetId if we aren't yet in the 'early' state; + // once we get to early, we'll remove the DialogSetId in favour of the DialogId. + // The comparator/key of the map must have an ordering so that a key can be + // contructed which points to the beginning of a dialogSet. This could be done by + // no remote tag being always, which might be the existing behaviour, but + // shouldn't be relied on. + std::map<DialogId, DialogEventInfo*, DialogIdComparator> mDialogIdToEventInfo; + + DialogEventHandler* mDialogEventHandler; +}; + +} +#endif diff --git a/src/libs/resiprocate/resip/dum/DialogId.cxx b/src/libs/resiprocate/resip/dum/DialogId.cxx new file mode 100644 index 00000000..2c7f6a32 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogId.cxx @@ -0,0 +1,179 @@ +#include "DialogId.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +DialogId::DialogId(const SipMessage& msg) : + mDialogSetId(msg), + mRemoteTag(Data::Empty) +{ + //find remote tag, which may not exist + if (msg.isExternal()) + { + if(msg.isResponse()) + { + if (msg.header(h_To).exists(p_tag)) + { + mRemoteTag = msg.header(h_To).param(p_tag); + } + } + else + { + if (msg.header(h_From).exists(p_tag)) + { + mRemoteTag = msg.header(h_From).param(p_tag); + } + } + } + else + { + if(msg.isRequest()) + { + //?dcm? -- is this just for 2543? At this point, we will have to have + //established a dialog(or else we would just have a dialogset) + if (msg.header(h_To).exists(p_tag)) + { + mRemoteTag = msg.header(h_To).param(p_tag); + } + } + else + { + if (msg.header(h_From).exists(p_tag)) + { + mRemoteTag = msg.header(h_From).param(p_tag); + } + } + } + DebugLog ( << "DialogId::DialogId: " << *this); +} + +DialogId::DialogId(const Data& callId, const Data& localTag, const Data& remoteTag) : + mDialogSetId(callId, localTag), + mRemoteTag(remoteTag) +{ +} + +DialogId::DialogId(const DialogSetId& id, const Data& remoteTag) : + mDialogSetId(id), + mRemoteTag(remoteTag) +{ + DebugLog ( << "DialogId::DialogId: " << *this); +} + +bool +DialogId::operator==(const DialogId& rhs) const +{ + return mDialogSetId == rhs.mDialogSetId && mRemoteTag == rhs.mRemoteTag; +} + +bool +DialogId::operator!=(const DialogId& rhs) const +{ + return mDialogSetId != rhs.mDialogSetId || mRemoteTag != rhs.mRemoteTag; +} + +bool +DialogId::operator<(const DialogId& rhs) const +{ + if (mDialogSetId < rhs.mDialogSetId) + { + return true; + } + if (mDialogSetId > rhs.mDialogSetId) + { + return false; + } + return mRemoteTag < rhs.mRemoteTag; +} + +const DialogSetId& +DialogId::getDialogSetId() const +{ + return mDialogSetId; +} + +const Data& +DialogId::getCallId() const +{ + return getDialogSetId().getCallId(); +} + +const Data& +DialogId::getLocalTag() const +{ + return getDialogSetId().getLocalTag(); +} + +const Data& +DialogId::getRemoteTag() const +{ + return mRemoteTag; +} + + +EncodeStream& +resip::operator<<(EncodeStream& os, const DialogId& id) +{ + return os << id.mDialogSetId << "-" << id.mRemoteTag; +} + + +size_t DialogId::hash() const +{ + return mDialogSetId.hash() ^ mRemoteTag.hash(); +} + +HashValueImp(resip::DialogId, data.hash()); + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogId.hxx b/src/libs/resiprocate/resip/dum/DialogId.hxx new file mode 100644 index 00000000..7bde89d3 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogId.hxx @@ -0,0 +1,88 @@ +#if !defined(RESIP_DIALOG_ID_HXX) +#define RESIP_DIALOG_ID_HXX + +#include "rutil/Data.hxx" +#include "resip/dum/DialogSetId.hxx" + +namespace resip +{ + +class DialogId +{ + public: + DialogId(const SipMessage& msg ); + DialogId(const Data& callId, const Data& localTag, const Data& remoteTag ); + DialogId(const DialogSetId& id, const Data& remoteTag ); + + bool operator==(const DialogId& rhs) const; + bool operator!=(const DialogId& rhs) const; + bool operator<(const DialogId& rhs) const; + + const DialogSetId& getDialogSetId() const; + + const Data& getCallId() const; + const Data& getLocalTag() const; + const Data& getRemoteTag() const; + + size_t hash() const; + + private: + friend EncodeStream& operator<<(EncodeStream&, const DialogId& id); + DialogSetId mDialogSetId; + Data mRemoteTag; +}; +} + +HashValue(resip::DialogId); + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogSet.cxx b/src/libs/resiprocate/resip/dum/DialogSet.cxx new file mode 100644 index 00000000..25053bf5 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogSet.cxx @@ -0,0 +1,1211 @@ + +#include "resip/stack/Helper.hxx" +#include "resip/dum/AppDialog.hxx" +#include "resip/dum/AppDialogSet.hxx" +#include "resip/dum/BaseCreator.hxx" +#include "resip/dum/ClientAuthManager.hxx" +#include "resip/dum/ClientOutOfDialogReq.hxx" +#include "resip/dum/ClientPublication.hxx" +#include "resip/dum/ClientRegistration.hxx" +#include "resip/dum/ClientPagerMessage.hxx" +#include "resip/dum/ServerPagerMessage.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/DialogSet.hxx" +#include "resip/dum/DialogSetHandler.hxx" +#include "resip/dum/DialogEventStateManager.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/RedirectManager.hxx" +#include "resip/dum/UsageUseException.hxx" +#include "resip/dum/ServerOutOfDialogReq.hxx" +#include "resip/dum/ServerRegistration.hxx" +#include "resip/dum/DumHelper.hxx" +#include "resip/dum/SubscriptionCreator.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; +using namespace std; + +// UAC +DialogSet::DialogSet(BaseCreator* creator, DialogUsageManager& dum) : + mMergeKey(), + mDialogs(), + mCreator(creator), + mId(*creator->getLastRequest()), + mDum(dum), + mAppDialogSet(0), + mState(Initial), + mClientRegistration(0), + mServerRegistration(0), + mClientPublication(0), + mClientOutOfDialogRequests(), + mServerOutOfDialogRequest(0), + mClientPagerMessage(0), + mServerPagerMessage(0) +{ + setUserProfile(creator->getUserProfile()); + assert(!creator->getLastRequest()->isExternal()); + DebugLog ( << " ************* Created DialogSet(UAC) -- " << mId << "*************" ); +} + +// UAS +DialogSet::DialogSet(const SipMessage& request, DialogUsageManager& dum) : + mMergeKey(request, dum.getMasterProfile()->checkReqUriInMergeDetectionEnabled()), + mDialogs(), + mCreator(0), + mId(request), + mDum(dum), + mAppDialogSet(0), + mState(Established), + mClientRegistration(0), + mServerRegistration(0), + mClientPublication(0), + mClientOutOfDialogRequests(), + mServerOutOfDialogRequest(0), + mClientPagerMessage(0), + mServerPagerMessage(0) +{ + assert(request.isRequest()); + assert(request.isExternal()); + mDum.mMergedRequests.insert(mMergeKey); + if (request.header(h_RequestLine).method() == INVITE) + { + if(mDum.mCancelMap.count(request.getTransactionId()) != 0) + { + WarningLog ( << "An endpoint is using the same tid in multiple INVITE requests, ability to match CANCEL requests correctly may be comprimised, tid=" << request.getTransactionId() ); + } + mCancelKey = request.getTransactionId(); + mDum.mCancelMap[mCancelKey] = this; + } + DebugLog ( << " ************* Created DialogSet(UAS) *************: " << mId); +} + +DialogSet::~DialogSet() +{ + if (mDum.mClientAuthManager.get()) + { + mDum.mClientAuthManager->dialogSetDestroyed(getId()); + } + + if (mMergeKey != MergedRequestKey::Empty) + { + mDum.requestMergedRequestRemoval(mMergeKey); + } + + if (!mCancelKey.empty()) + { + mDum.mCancelMap.erase(mCancelKey); + } + + delete mCreator; + while(!mDialogs.empty()) + { + delete mDialogs.begin()->second; + } + + delete mClientRegistration; + delete mServerRegistration; + delete mClientPublication; + delete mServerOutOfDialogRequest; + delete mClientPagerMessage; + delete mServerPagerMessage; + + while (!mClientOutOfDialogRequests.empty()) + { + delete *mClientOutOfDialogRequests.begin(); + } + + DebugLog ( << " ********** DialogSet::~DialogSet: " << mId << "*************" ); + // !dcm! -- very delicate code, change the order things go horribly wrong + + mDum.removeDialogSet(this->getId()); + if (mAppDialogSet) + { + mAppDialogSet->destroy(); + } +} + +void DialogSet::possiblyDie() +{ + if(mState != Destroying && + mDialogs.empty() && + // The following check ensures we are not a UAC DialogSet in the Initial or + // ReceivedProvisional states. + // .slg. this check fixes a case where we might receive a short term usuage + // request (such as OPTIONS) in the same dialogset as a UAC dialogset + // for which we have not created any Dialogs yet - in this case + // we don't want the dialogset to die, since the UAC usage is not complete. + (mCreator == 0 || (mState != Initial && mState != ReceivedProvisional)) && + mClientOutOfDialogRequests.empty() && + !(mClientPublication || + mServerOutOfDialogRequest || + mClientPagerMessage || + mServerPagerMessage || + mClientRegistration || + mServerRegistration)) + { + mState = Destroying; + mDum.destroy(this); + } +} + +DialogSetId +DialogSet::getId() const +{ + return mId; +} + +void +DialogSet::addDialog(Dialog *dialog) +{ + mDialogs[dialog->getId()] = dialog; +} + +BaseCreator* +DialogSet::getCreator() +{ + return mCreator; +} + +Dialog* +DialogSet::findDialog(const SipMessage& msg) +{ + if (msg.isResponse() && msg.header(h_StatusLine).statusCode() == 100) + { + return 0; + } + return findDialog(DialogId(msg)); +#if 0 + DialogId id(msg); + Dialog* dlog = findDialog(id); + //vonage/2543 matching here + if (dlog) + { + return dlog; + } + //match off transaction ID + else if (msg.isResponse() && !msg.header(h_To).exists(p_tag)) + { + for(DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); it++) + { + if (it->second->matches(msg)) + { + return it->second; + } + } + } + else if (msg.exists(h_Contacts) && !msg.header(h_Contacts).empty() + && msg.isResponse() + && mDum.getProfile()->looseToTagMatching() + && msg.header(h_To).exists(p_tag)) + { + const Uri& contact = msg.header(h_Contacts).front().uri(); + + //match by contact + for(DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); it++) + { + if (it->second->mRemoteTarget.uri() == msg.header(h_Contacts).front().uri()) + { + // !dcm! in the vonage case, the to tag should be updated to match the fake + //vonage tag introduced in the 200 which is also used for the BYE. + //find out how deep this rabbit hole goes, may just have a pugabble + //filter api that can be added for dialog matching if things get any + //more specific--this is the VonageKludgeFilter + Dialog* dialog = it->second; + DialogId old = dialog->getId(); + dialog->mId = DialogId(old.getCallId(), old.getLocalTag(), msg.header(h_To).param(p_tag)); + dialog->mRemoteNameAddr.param(p_tag) = msg.header(h_To).param(p_tag); + mDialogs.erase(it); + mDialogs[dialog->getId()] = dialog; + return dialog; + } + } + } + return 0; +#endif +} + +bool +DialogSet::empty() const +{ + return mDialogs.empty(); +} + +bool +DialogSet::handledByAuthOrRedirect(const SipMessage& msg) +{ + if (msg.isResponse() && !(mState == Terminating || + mState == WaitingToEnd || + mState == Destroying || + mState == Cancelling)) + { + // !dcm! -- multiple usage grief...only one of each method type allowed + if (getCreator() && + msg.header(h_CSeq) == getCreator()->getLastRequest()->header(h_CSeq)) + { + if (mDum.mClientAuthManager.get()) + { + if (mDum.mClientAuthManager->handle(*getUserProfile().get(), *getCreator()->getLastRequest(), msg)) + { + // Note: ClientAuthManager->handle will end up incrementing the CSeq sequence of getLastRequest + DebugLog( << "about to re-send request with digest credentials" ); + StackLog( << getCreator()->getLastRequest() ); + + mDum.send(getCreator()->getLastRequest()); + return true; + } + } + // !dcm! -- need to protect against 3xx highjacking a dialogset which + //has a fully established dialog. also could case strange behaviour + //by sending 401/407 at the wrong time. + if (mDum.mRedirectManager.get() && mState != Established) // !slg! for now don't handle redirect in established dialogs - alternatively we could treat as a target referesh (using 1st Contact) and reissue request + { + if (mDum.mRedirectManager->handle(*this, *getCreator()->getLastRequest(), msg)) + { + //terminating existing dialogs(branches) as this is a final + //response--?dcm?--merge w/ forking logic somehow? + // !dcm! -- really, really horrible. Should make a don't die + //scoped guard + mState = Initial; + for (DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end();) + { + (it++)->second->redirected(msg); + } + + if (mDialogs.size() == 0) + { + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTerminated(*this, msg, InviteSessionHandler::Rejected); + } + } + + InfoLog( << "about to re-send request to redirect destination" ); + DebugLog( << getCreator()->getLastRequest() ); + + mDum.send(getCreator()->getLastRequest()); + return true; + } + + // Check if a 422 response to initial Invite (RFC4028) + if(msg.header(h_StatusLine).statusCode() == 422 && msg.exists(h_MinSE)) + { + // Change interval to min from 422 response + getCreator()->getLastRequest()->header(h_SessionExpires).value() = msg.header(h_MinSE).value(); + getCreator()->getLastRequest()->header(h_MinSE).value() = msg.header(h_MinSE).value(); + getCreator()->getLastRequest()->header(h_CSeq).sequence()++; + + InfoLog( << "about to re-send request with new session expiration time" ); + DebugLog( << getCreator()->getLastRequest() ); + + mDum.send(getCreator()->getLastRequest()); + return true; + } + } + } + } + return false; +} + + +void +DialogSet::dispatch(const SipMessage& msg) +{ + if(!mAppDialogSet) + { + // !bwc! There are conditions where reuse of the AppDialogSet will cause + // us to hit this code. This is because the teardown of DialogSets is not + // atomic, causing the DialogSet to hang around for a short time after it + // has given up its AppDialogSet. Also, if we have multiple Usages in + // this DialogSet, one of the Usages may decide to re-establish itself in + // a new Dialog, and take the AppDialogSet with it, leaving all the others + // high and dry. This is a design issue that will take some real effort to + // fix properly. This is a band-aid for now. + // TODO fix this properly + if(msg.isRequest()) + { + if(msg.method() != ACK) + { + SipMessage err; + Helper::makeResponse(err, msg, 500, "DialogSet: My AppDialogSet is " + "missing!"); + mDum.sendResponse(err); + } + } + else + { + ErrLog(<<"Response came in, but no AppDialogSet! Dropping this is very" + "likely to cause leaks, but continuing to process it is " + "likely to cause a core. Taking the lesser of two evils..."); + } + return; + } + + assert(msg.isRequest() || msg.isResponse()); + + if (mState == WaitingToEnd) + { + assert(mDialogs.empty()); + if (msg.isResponse()) + { + int code = msg.header(h_StatusLine).statusCode(); + switch(mCreator->getLastRequest()->header(h_CSeq).method()) + { + case INVITE: + if (code / 100 == 1) + { + mState = ReceivedProvisional; + end(); + } + else if (code / 100 == 2) + { + Dialog dialog(mDum, msg, *this); + + SharedPtr<SipMessage> ack(new SipMessage); + dialog.makeRequest(*ack, ACK); + ack->header(h_CSeq).sequence() = msg.header(h_CSeq).sequence(); + dialog.send(ack); + + SharedPtr<SipMessage> bye(new SipMessage); + dialog.makeRequest(*bye, BYE); + dialog.send(bye); + + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTerminated(dialog, *bye, InviteSessionHandler::LocalBye); + } + // Note: Destruction of this dialog object will cause DialogSet::possiblyDie to be called thus invoking mDum.destroy + } + else + { + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTerminated(*this, msg, InviteSessionHandler::Rejected); + } + mState = Destroying; + mDum.destroy(this); + } + break; + case SUBSCRIBE: + if (code / 100 == 1) + { + // do nothing - wait for final response + } + else if (code / 100 == 2) + { + Dialog dialog(mDum, msg, *this); + + SharedPtr<SipMessage> unsubscribe(new SipMessage(*mCreator->getLastRequest().get())); // create message from initial request so we get proper headers + dialog.makeRequest(*unsubscribe, SUBSCRIBE); + unsubscribe->header(h_Expires).value() = 0; + dialog.send(unsubscribe); + + // Note: Destruction of this dialog object will cause DialogSet::possiblyDie to be called thus invoking mDum.destroy + } + else + { + mState = Destroying; + mDum.destroy(this); + } + break; + case PUBLISH: + if (code / 100 == 1) + { + // do nothing - wait for final response + } + else if (code / 100 == 2) + { + Dialog dialog(mDum, msg, *this); + + SharedPtr<SipMessage> unpublish(new SipMessage(*mCreator->getLastRequest().get())); // create message from initial request so we get proper headers + dialog.makeRequest(*unpublish, PUBLISH); + unpublish->header(h_Expires).value() = 0; + dialog.send(unpublish); + + // Note: Destruction of this dialog object will cause DialogSet::possiblyDie to be called thus invoking mDum.destroy + } + else + { + mState = Destroying; + mDum.destroy(this); + } + break; + // ?slg? shouldn't we handle register, ood and refer here too? + default: + mState = Destroying; + mDum.destroy(this); + break; + } + } + else + { + SharedPtr<SipMessage> response(new SipMessage); + mDum.makeResponse(*response, msg, 481); + mDum.send(response); + } + return; + } + else if(mState == Cancelling) + { + assert(mDialogs.empty()); + if (msg.isResponse()) + { + int code = msg.header(h_StatusLine).statusCode(); + if(mCreator->getLastRequest()->header(h_CSeq).method() == INVITE) + { + if (code / 100 == 1) + { + // do nothing - wait for final response + } + // 200/Inv crossing CANCEL case + else if (code / 100 == 2) + { + Dialog dialog(mDum, msg, *this); + + SharedPtr<SipMessage> ack(new SipMessage); + dialog.makeRequest(*ack, ACK); + ack->header(h_CSeq).sequence() = msg.header(h_CSeq).sequence(); + dialog.send(ack); + + SharedPtr<SipMessage> bye(new SipMessage); + dialog.makeRequest(*bye, BYE); + dialog.send(bye); + + // Note: Destruction of this dialog object will cause DialogSet::possiblyDie to be called thus invoking mDum.destroy + } + else + { + mState = Destroying; + mDum.destroy(this); + } + } + } + else // is a request + { + SharedPtr<SipMessage> response(new SipMessage); + mDum.makeResponse(*response, msg, 481); + mDum.send(response); + } + return; + } + + if (handledByAuthOrRedirect(msg)) + { + return; + } + + Dialog* dialog = 0; + if (!(msg.isResponse() && msg.header(h_StatusLine).statusCode() == 100)) // Don't look for dialog if msg is a 100 response + { + DialogMap::iterator i = mDialogs.find(DialogId(msg)); + if (i != mDialogs.end()) + { + dialog = i->second; + } + } + if (dialog) + { + if(dialog->isDestroying()) + { + if( msg.isRequest() ) + { + StackLog (<< "Matching dialog is destroying, sending 481 " << endl << msg); + SharedPtr<SipMessage> response(new SipMessage); + mDum.makeResponse(*response, msg, 481); + mDum.send(response); + } + else + { + StackLog (<< "Matching dialog is destroying, dropping response message " << endl << msg); + } + return; + } + else + { + DebugLog (<< "Found matching dialog " << *dialog << " for " << endl << endl << msg); + } + } + else + { + StackLog (<< "No matching dialog for " << endl << endl << msg); + } + + if (msg.isRequest()) + { + const SipMessage& request = msg; + switch (request.header(h_CSeq).method()) + { + case INVITE: + case CANCEL: //cancel needs work + case SUBSCRIBE: + break; //dialog creating/handled by dialog + + case BYE: + case INFO: + case ACK: + case UPDATE: + if(!dialog) + { + SharedPtr<SipMessage> response(new SipMessage); + mDum.makeResponse(*response, msg, 481); + mDum.send(response); + return; + } + break; + + case REFER: + if (request.header(h_To).exists(p_tag) || findDialog(request)) + { + DebugLog(<< "in dialog refer request"); + break; // in dialog + } + else if((request.exists(h_ReferSub) && + request.header(h_ReferSub).isWellFormed() && + request.header(h_ReferSub).value()=="false") || + (request.exists(h_Requires) && + request.header(h_Requires).find(Token("norefersub"))))// out of dialog & noReferSub=true + { + DebugLog(<< "out of dialog refer request with norefersub"); + assert(mServerOutOfDialogRequest == 0); + mServerOutOfDialogRequest = makeServerOutOfDialog(request); + mServerOutOfDialogRequest->dispatch(request); + return; + } + else + { + DebugLog(<< "out of dialog refer request with refer sub"); + break; // dialog creating + } + break; + case NOTIFY: + + // !jf! there shouldn't be a dialogset for ServerOutOfDialogReq + if (request.header(h_To).exists(p_tag) || findDialog(request)) + { + break; //dialog creating/handled by dialog + } + else // no to tag - unsolicited notify + { + // unsolicited - not allowed but commonly implemented + // by large companies with a bridge as their logo + assert(mServerOutOfDialogRequest == 0); + mServerOutOfDialogRequest = makeServerOutOfDialog(request); + mServerOutOfDialogRequest->dispatch(request); + return; + } + break; + + case PUBLISH: + assert(false); // handled in DialogUsageManager + return; + + case REGISTER: + // !jf! move this to DialogUsageManager + if (mServerRegistration == 0) + { + mServerRegistration = makeServerRegistration(request); + } + mServerRegistration->dispatch(request); + return; + + case MESSAGE: + // !jf! move this to DialogUsageManager + if(!dialog) + { + mServerPagerMessage = makeServerPagerMessage(request); + mServerPagerMessage->dispatch(request); + return; + } + break; + + default: + // !jf! move this to DialogUsageManager + DebugLog ( << "In DialogSet::dispatch, default(ServerOutOfDialogRequest), msg: " << msg ); + // only can be one ServerOutOfDialogReq at a time + assert(mServerOutOfDialogRequest == 0); + mServerOutOfDialogRequest = makeServerOutOfDialog(request); + mServerOutOfDialogRequest->dispatch(request); + return; + } + } + else // the message is a response + { + const SipMessage& response = msg; + + int code = msg.header(h_StatusLine).statusCode(); + if (code == 423 + && msg.header(h_CSeq).method() == SUBSCRIBE + && msg.exists(h_MinExpires) + && getCreator() + && msg.header(h_CSeq) == getCreator()->getLastRequest()->header(h_CSeq)) + { + getCreator()->getLastRequest()->header(h_CSeq).sequence()++; + getCreator()->getLastRequest()->header(h_Expires).value() = msg.header(h_MinExpires).value(); + DebugLog( << "Re sending inital(dialog forming) SUBSCRIBE due to 423, MinExpires is: " << msg.header(h_MinExpires).value()); + mDum.send(getCreator()->getLastRequest()); + return; + } + + // We should only do DialogState processing if this is a response to our initial request + if(getCreator() && + msg.header(h_CSeq) == getCreator()->getLastRequest()->header(h_CSeq)) + { + switch(mState) + { + case Initial: + if (code < 200) + { + mState = ReceivedProvisional; + } + else if(code < 300) + { + mState = Established; + } + else + { + mState = Established; + if (!mDialogs.empty()) + { + dispatchToAllDialogs(msg); + return; + } + } + break; + case ReceivedProvisional: + if (code < 200) + { + // fall through + } + else if (code < 300) + { + mState = Established; + for (DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); it++) + { + if (it->second != dialog) // this is dialog that accepted + { + it->second->onForkAccepted(); + } + } + } + else // failure response + { + mState = Established; + if (!mDialogs.empty()) + { + dispatchToAllDialogs(msg); + return; + } + } + break; + default: + // !jf! + break; + } + } + + if (response.header(h_StatusLine).statusCode() == 100) + { + if (mDum.mDialogSetHandler) + { + mDum.mDialogSetHandler->onTrying(mAppDialogSet->getHandle(), msg); + } + return; + } + + switch (response.header(h_CSeq).method()) + { + case INVITE: + case SUBSCRIBE: + case BYE: + case ACK: + case CANCEL: + break; + + case PUBLISH: + if (mClientPublication == 0) + { + mClientPublication = makeClientPublication(response); + } + mClientPublication->dispatch(response); + return; + + case REGISTER: + if (mClientRegistration == 0) + { + mClientRegistration = makeClientRegistration(response); + } + mClientRegistration->dispatch(response); + return; + + case MESSAGE: + if (dialog) + { + break; + } + else if (mClientPagerMessage) + { + mClientPagerMessage->dispatch(response); + } + return; + + case INFO: + case UPDATE: + if (dialog) + { + break; + } + else // not allowed + { + return; + } + case REFER: + if (dynamic_cast<SubscriptionCreator*>(getCreator())) + { + break; + } + case NOTIFY: + if (dialog) + { + break; + } + + default: + { + ClientOutOfDialogReq* req = findMatchingClientOutOfDialogReq(response); + if (req == 0) + { + req = makeClientOutOfDialogReq(response); + mClientOutOfDialogRequests.push_back(req); + } + req->dispatch(response); + return; + } + } + } + + if (dialog == 0) + { + if (msg.isRequest() && msg.header(h_RequestLine).method() == CANCEL) + { + dispatchToAllDialogs(msg); + return; + } + + if (msg.isResponse()) + { + if( mCreator ) + { + SharedPtr<SipMessage> lastRequest(mCreator->getLastRequest()); + if( 0 != lastRequest.get() && !(lastRequest->header(h_CSeq) == msg.header(h_CSeq))) + { + InfoLog(<< "Cannot create a dialog, cseq does not match initial dialog request (illegal mid-dialog fork? see 3261 14.1)."); + return; + } + } + else + { + ErrLog(<< "Can't create a dialog, on a UAS response."); + return; + } + + int code = msg.header(h_StatusLine).statusCode(); + + if (code > 100 && code < 200 && + (!msg.exists(h_Contacts) || + !msg.exists(h_To) || !msg.header(h_To).exists(p_tag))) + { + InfoLog ( << "Cannot create a dialog, no Contact or To tag in 1xx." ); + if (mDum.mDialogSetHandler) + { + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onProceedingUac(*this, msg); + } + mDum.mDialogSetHandler->onNonDialogCreatingProvisional(mAppDialogSet->getHandle(), msg); + } + return; + } + // If failure response and no dialogs, create a dialog, otherwise + else if (code >= 300 && !mDialogs.empty()) + { + dispatchToAllDialogs(msg); + return; + } + } + + DebugLog ( << "mState == " << mState << " Creating a new Dialog from msg: " << std::endl << std::endl <<msg); + try + { + // !jf! This could throw due to bad header in msg, should we catch and rethrow + dialog = new Dialog(mDum, msg, *this); + } + catch(BaseException& e) + { + InfoLog( << "Unable to create dialog: " << e.getMessage()); + if (msg.isResponse()) + { + //don't delete on provisional responses, as FWD will eventually send a + //valid 200 + if(mDialogs.empty() && + msg.header(h_StatusLine).statusCode() >= 200) + { + // really we should wait around 32s before deleting this + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTerminated(*this, msg, InviteSessionHandler::Error); + } + + mState = Destroying; + mDum.destroy(this); + } + } + else + { + // !jf! derek thinks we should destroy only on invalid CANCEL or + // BYE, hmmphh. see draft-sparks-sipping-dialogusage-01.txt + SharedPtr<SipMessage> response(new SipMessage); + mDum.makeResponse(*response, msg, 400); + mDum.send(response); + if(mDialogs.empty()) + { + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTerminated(*this, msg, InviteSessionHandler::Error); + } + mState = Destroying; + mDum.destroy(this); + } + } + return; + } + + assert(mState != WaitingToEnd); + DebugLog ( << "### Calling CreateAppDialog ###: " << std::endl << std::endl <<msg); + AppDialog* appDialog = mAppDialogSet->createAppDialog(msg); + dialog->mAppDialog = appDialog; + appDialog->mDialog = dialog; + dialog->dispatch(msg); + } + else + { + dialog->dispatch(msg); + } +} + + +ClientOutOfDialogReq* +DialogSet::findMatchingClientOutOfDialogReq(const SipMessage& msg) +{ + for (std::list<ClientOutOfDialogReq*>::iterator i=mClientOutOfDialogRequests.begin(); + i != mClientOutOfDialogRequests.end(); ++i) + { + if ((*i)->matches(msg)) + { + return *i; + } + } + return 0; +} + +Dialog* +DialogSet::findDialog(const DialogId id) +{ + StackLog (<< "findDialog: " << id << " in " << InserterP(mDialogs)); + + DialogMap::iterator i = mDialogs.find(id); + if (i == mDialogs.end()) + { + return 0; + } + else + { + if(i->second->isDestroying()) + { + return 0; + } + else + { + return i->second; + } + } +} + +void +DialogSet::end() +{ + switch(mState) + { + case Initial: + mState = WaitingToEnd; + break; + case WaitingToEnd: + break; + case ReceivedProvisional: + { + assert (mCreator->getLastRequest()->header(h_CSeq).method() == INVITE); + mState = Terminating; + // !jf! this should be made exception safe + SharedPtr<SipMessage> cancel(Helper::makeCancel(*getCreator()->getLastRequest())); + mDum.send(cancel); + + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTerminated(*this, *cancel, InviteSessionHandler::LocalCancel); + } + + if (mDialogs.empty()) + { + mState = Cancelling; + } + else + { + //need to lag and do last element ouside of look as this DialogSet will be + //deleted if all dialogs are destroyed + for (DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); it++) + { + try + { + it->second->cancel(); + } + catch(UsageUseException& e) + { + InfoLog (<< "Caught: " << e); + } + } + } + } + break; + case Established: + { + for (DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); ++it) + { + try + { + it->second->end(); + } + catch(UsageUseException& e) + { + InfoLog (<< "Caught: " << e); + } + } + mState = Terminating; + break; + } + case Terminating: + case Cancelling: + case Destroying: + DebugLog (<< "DialogSet::end() called on a DialogSet that is already Terminating"); + //assert(0); + } +} + + +ClientRegistrationHandle +DialogSet::getClientRegistration() +{ + if (mClientRegistration) + { + return mClientRegistration->getHandle(); + } + else + { + return ClientRegistrationHandle::NotValid(); + } +} + +ServerRegistrationHandle +DialogSet::getServerRegistration() +{ + if (mServerRegistration) + { + return mServerRegistration->getHandle(); + } + else + { + return ServerRegistrationHandle::NotValid(); + } +} + +ClientPublicationHandle +DialogSet::getClientPublication() +{ + if (mClientPublication) + { + return mClientPublication->getHandle(); + } + else + { + return ClientPublicationHandle::NotValid(); + } +} + +ClientRegistration* +DialogSet::makeClientRegistration(const SipMessage& response) +{ + BaseCreator* creator = getCreator(); + assert(creator); + return new ClientRegistration(mDum, *this, creator->getLastRequest()); +} + +ClientPublication* +DialogSet::makeClientPublication(const SipMessage& response) +{ + BaseCreator* creator = getCreator(); + assert(creator); + return new ClientPublication(mDum, *this, creator->getLastRequest()); +} + +ClientOutOfDialogReq* +DialogSet::makeClientOutOfDialogReq(const SipMessage& response) +{ + BaseCreator* creator = getCreator(); + assert(creator); + return new ClientOutOfDialogReq(mDum, *this, *creator->getLastRequest()); +} + +ServerRegistration* +DialogSet::makeServerRegistration(const SipMessage& request) +{ + return new ServerRegistration(mDum, *this, request); +} + +ServerOutOfDialogReq* +DialogSet::makeServerOutOfDialog(const SipMessage& request) +{ + return new ServerOutOfDialogReq(mDum, *this, request); +} + +ServerPagerMessage* +DialogSet::makeServerPagerMessage(const SipMessage& request) +{ + return new ServerPagerMessage(mDum, *this, request); +} + +ServerOutOfDialogReqHandle +DialogSet::getServerOutOfDialog() +{ + if (mServerOutOfDialogRequest) + { + return mServerOutOfDialogRequest->getHandle(); + } + else + { + return ServerOutOfDialogReqHandle::NotValid(); + } +} + +void DialogSet::dispatchToAllDialogs(const SipMessage& msg) +{ + if (!mDialogs.empty()) + { + for(DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); it++) + { + it->second->dispatch(msg); + } + } +} + +SharedPtr<UserProfile> +DialogSet::getUserProfile() const +{ + if(mUserProfile.get()) + { + return mUserProfile; + } + else + { + // If no UserProfile set then use UserProfile of the MasterProfile + return mDum.getMasterUserProfile(); + } +} + +void +DialogSet::setUserProfile(SharedPtr<UserProfile> userProfile) +{ + assert(userProfile.get()); + mUserProfile = userProfile; +} + +void +DialogSet::flowTerminated(const Tuple& flow) +{ + // The flow has failed - clear the flow key/tuple in the UserProfile + mUserProfile->clearClientOutboundFlowTuple(); + + // If this profile is configured for client outbound and the connectionTerminated + // matches the connection stored in the profile, then notify the client registration + // and all dialogs in this dialogset that the flow has terminated + // Check other usage types that we send requests on + if(mClientRegistration) + { + mClientRegistration->flowTerminated(); + } + + for(DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); it++) + { + it->second->flowTerminated(); + } +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const DialogSet& ds) +{ + // Used in Inserter, so keeping brief (ie. Id is already logged by Inserter) + strm << "state=" << ds.mState; + return strm; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written +1 * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogSet.hxx b/src/libs/resiprocate/resip/dum/DialogSet.hxx new file mode 100644 index 00000000..b9aaae06 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogSet.hxx @@ -0,0 +1,184 @@ +#if !defined(RESIP_CLIENTDIALOGSET_HXX) +#define RESIP_CLIENTDIALOGSET_HXX + +#include <map> +#include <list> + +#include "resip/dum/DialogId.hxx" +#include "resip/dum/DialogSetId.hxx" +#include "resip/dum/MergedRequestKey.hxx" +#include "resip/dum/Handles.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/SharedPtr.hxx" + +namespace resip +{ + +class BaseCreator; +class Dialog; +class DialogUsageManager; +class AppDialogSet; +class ClientOutOfDialogReq; +class UserProfile; + +class DialogSet +{ + public: + DialogSet(BaseCreator* creator, DialogUsageManager& dum); + DialogSet(const SipMessage& request, DialogUsageManager& dum); + virtual ~DialogSet(); + + DialogSetId getId() const; + void addDialog(Dialog*); + bool empty() const; + BaseCreator* getCreator(); + + SharedPtr<UserProfile> getUserProfile() const; + void setUserProfile(SharedPtr<UserProfile> userProfile); + + void end(); + void dispatch(const SipMessage& msg); + + ClientRegistrationHandle getClientRegistration(); + ServerRegistrationHandle getServerRegistration(); + ClientPublicationHandle getClientPublication(); + ClientOutOfDialogReqHandle getClientOutOfDialog(); + ServerOutOfDialogReqHandle getServerOutOfDialog(); + + bool isDestroying() { return mState == Destroying; }; + + private: + friend class Dialog; + friend class DialogUsage; + friend class ClientInviteSession; + friend class NonDialogUsage; + friend class DialogUsageManager; + friend class ClientRegistration; + friend class ServerRegistration; + friend class ClientOutOfDialogReq; + friend class ServerOutOfDialogReq; + friend class ClientPublication; + friend class RedirectManager; + friend class ClientPagerMessage; + friend class ServerPagerMessage; + + typedef enum + { + Initial, // No session setup yet + WaitingToEnd, + ReceivedProvisional, + Established, + Terminating, + Cancelling, // only used when cancelling and no dialogs exist + Destroying + } State; + + void possiblyDie(); + + void onForkAccepted(); + bool handledByAuthOrRedirect(const SipMessage& msg); + + /// Abandon this dialog set, but keep the AppDialogSet around + void appDissociate() + { + assert(mAppDialogSet); + mAppDialogSet = 0; + } + friend class AppDialogSet; + + Dialog* findDialog(const SipMessage& msg); + Dialog* findDialog(const DialogId id); + + ClientOutOfDialogReq* findMatchingClientOutOfDialogReq(const SipMessage& msg); + + ClientRegistration* makeClientRegistration(const SipMessage& msg); + ClientPublication* makeClientPublication( const SipMessage& msg); + ClientOutOfDialogReq* makeClientOutOfDialogReq(const SipMessage& msg); + + ServerRegistration* makeServerRegistration(const SipMessage& msg); + ServerOutOfDialogReq* makeServerOutOfDialog(const SipMessage& msg); + + ServerPagerMessage* makeServerPagerMessage(const SipMessage& request); + + void dispatchToAllDialogs(const SipMessage& msg); + + void flowTerminated(const Tuple& flow); + + MergedRequestKey mMergeKey; + Data mCancelKey; + typedef std::map<DialogId,Dialog*> DialogMap; + DialogMap mDialogs; + BaseCreator* mCreator; + DialogSetId mId; + DialogUsageManager& mDum; + AppDialogSet* mAppDialogSet; + State mState; + ClientRegistration* mClientRegistration; + ServerRegistration* mServerRegistration; + ClientPublication* mClientPublication; + std::list<ClientOutOfDialogReq*> mClientOutOfDialogRequests; + ServerOutOfDialogReq* mServerOutOfDialogRequest; + + ClientPagerMessage* mClientPagerMessage; + ServerPagerMessage* mServerPagerMessage; + SharedPtr<UserProfile> mUserProfile; + + friend EncodeStream& operator<<(EncodeStream& strm, const DialogSet& ds); +}; + +EncodeStream& +operator<<(EncodeStream& strm, const DialogSet& ds); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogSetHandler.hxx b/src/libs/resiprocate/resip/dum/DialogSetHandler.hxx new file mode 100644 index 00000000..6a6d7393 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogSetHandler.hxx @@ -0,0 +1,78 @@ +#if !defined(RESIP_DIALOGSETHANDLER_HXX) +#define RESIP_DIALOGSETHANDLER_HXX + +#include "resip/dum/DialogSet.hxx" +#include "resip/dum/Handles.hxx" + +namespace resip +{ + +class SipMessage; + +class DialogSetHandler +{ + public: + virtual ~DialogSetHandler() {} + + //called when a 100 is received + virtual void onTrying(AppDialogSetHandle, const SipMessage& msg)=0; + + //called when a provisional response that does not create a dialog arrives + //usually, this is a 180 w/out a contact + virtual void onNonDialogCreatingProvisional(AppDialogSetHandle, const SipMessage& msg)=0; +}; + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogSetId.cxx b/src/libs/resiprocate/resip/dum/DialogSetId.cxx new file mode 100644 index 00000000..64f5b893 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogSetId.cxx @@ -0,0 +1,168 @@ +#include "DialogSetId.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +const DialogSetId DialogSetId::Empty; + +DialogSetId::DialogSetId(const SipMessage& msg) : + mCallId(msg.header(h_CallID).value()) +{ + //find local tag, generate one as necessary + if (msg.isExternal()) + { + if(msg.isResponse()) + { + if(msg.header(h_From).exists(p_tag)) + { + // .bwc. If no tag, leave mTag empty. + mTag = msg.header(h_From).param(p_tag); + } + } + else //external request; generate to tag if not present + { + if (msg.header(h_To).exists(p_tag)) + { + mTag = msg.header(h_To).param(p_tag); + } + else + { + //DebugLog ( << "********** Generated Local Tag *********** " ); + mTag = Helper::computeTag(Helper::tagSize); + } + } + } + else + { + if(msg.isRequest()) + { + assert(msg.header(h_From).exists(p_tag)); + mTag = msg.header(h_From).param(p_tag); + } + else + { + assert(msg.header(h_To).exists(p_tag)); + mTag = msg.header(h_To).param(p_tag); + } + } +} + +DialogSetId::DialogSetId(const Data& callId, const Data& tag) + : mCallId(callId), + mTag(tag) +{ +} + +DialogSetId::DialogSetId() + : mCallId(), + mTag() +{ +} + +bool +DialogSetId::operator==(const DialogSetId& rhs) const +{ + return mCallId == rhs.mCallId && mTag == rhs.mTag; +} + +bool +DialogSetId::operator!=(const DialogSetId& rhs) const +{ + return mCallId != rhs.mCallId || mTag != rhs.mTag; +} + +bool +DialogSetId::operator<(const DialogSetId& rhs) const +{ + if (mCallId < rhs.mCallId) + { + return true; + } + if (mCallId > rhs.mCallId) + { + return false; + } + return mTag < rhs.mTag; +} + +bool +DialogSetId::operator>(const DialogSetId& rhs) const +{ + if (mCallId > rhs.mCallId) + { + return true; + } + if (mCallId < rhs.mCallId) + { + return false; + } + return mTag > rhs.mTag; +} + +size_t DialogSetId::hash() const +{ + return mCallId.hash() ^ mTag.hash(); +} + + +EncodeStream& +resip::operator<<(EncodeStream& os, const DialogSetId& id) +{ + return os << id.mCallId << '-' << id.mTag ; +} + +HashValueImp(resip::DialogSetId, data.hash()); + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogSetId.hxx b/src/libs/resiprocate/resip/dum/DialogSetId.hxx new file mode 100644 index 00000000..08867e3e --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogSetId.hxx @@ -0,0 +1,92 @@ +#if !defined(RESIP_DIALOGSETID_HXX) +#define RESIP_DIALOGSETID_HXX + +#include "rutil/HashMap.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +class SipMessage; + +class DialogSetId +{ + public: + static const DialogSetId Empty; + + DialogSetId(const SipMessage& msg); + DialogSetId(const Data& callId, const Data& senderRequestFromTag); + + bool operator==(const DialogSetId& rhs) const; + bool operator!=(const DialogSetId& rhs) const; + bool operator<(const DialogSetId& rhs) const; + bool operator>(const DialogSetId& rhs) const; + size_t hash() const; + friend EncodeStream& operator<<(EncodeStream&, const DialogSetId& id); + + const Data& getCallId() const { return mCallId; } + const Data& getLocalTag() const { return mTag; } + private: + DialogSetId(); + + Data mCallId; + Data mTag; +}; + + EncodeStream& operator<<(EncodeStream&, const DialogSetId&); + +} + +HashValue(resip::DialogSetId); + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogUsage.cxx b/src/libs/resiprocate/resip/dum/DialogUsage.cxx new file mode 100644 index 00000000..84377fe1 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogUsage.cxx @@ -0,0 +1,178 @@ +#include "resip/dum/AppDialog.hxx" +#include "resip/dum/AppDialogSet.hxx" +#include "resip/dum/DialogUsage.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/DialogSet.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/stack/ExtensionHeader.hxx" +#include "resip/stack/ExtensionParameter.hxx" +#include "rutil/Logger.hxx" + + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +static void putUserHeaders(const std::map<std::string, std::string>& hdr, SipMessage& msg) +{ + for (std::map<std::string, std::string>::const_iterator iter = hdr.begin(); iter != hdr.end(); iter++) + { + const std::string& name = iter->first; + const std::string& value = iter->second; + + msg.header(ExtensionHeader(name.c_str())).push_back(StringCategory(value.c_str())); + } +} + +DialogUsage::Exception::Exception(const Data& msg,const Data& file,int line) + : BaseException(msg, file, line) +{ +} + +const char* +DialogUsage::Exception::name() const +{ + return "DialogUsage::Exception"; +} + +DialogUsage::DialogUsage(DialogUsageManager& dum, Dialog& dialog) : + BaseUsage(dum), + mDialog(dialog) +{ +} + +DialogUsage::~DialogUsage() +{ + mDialog.possiblyDie(); +} + +AppDialogSetHandle +DialogUsage::getAppDialogSet() +{ + return mDialog.mDialogSet.mAppDialogSet->getHandle(); +} + +AppDialogHandle +DialogUsage::getAppDialog() +{ + return mDialog.mAppDialog->getHandle(); +} + +const NameAddr& +DialogUsage::myAddr() const +{ + return mDialog.mLocalNameAddr; +} + +const NameAddr& +DialogUsage::peerAddr() const +{ + return mDialog.mRemoteNameAddr; +} + +const NameAddr& +DialogUsage::remoteTarget() const +{ + return mDialog.mRemoteTarget; +} + +const DialogId& +DialogUsage::getDialogId() const +{ + return mDialog.getId(); +} + +const Data& +DialogUsage::getCallId() const +{ + return mDialog.getId().getCallId(); +} + +SharedPtr<UserProfile> +DialogUsage::getUserProfile() +{ + return mDialog.mDialogSet.getUserProfile(); +} + +void +DialogUsage::send(SharedPtr<SipMessage> msg) +{ + // give app an chance to adorn the message. + onReadyToSend(*msg); + + putUserHeaders(mUserHeaders, *msg); + + mDialog.send(msg); +} + +void +DialogUsage::sendCommand(SharedPtr<SipMessage> message) +{ + mDum.post(new DialogUsageSendCommand(*this, message)); +} + +void +DialogUsage::setUserHeaders(const std::map<std::string, std::string> &headers) +{ + mUserHeaders = headers; +} + +/* +void +DialogUsage::send(SipMessage& msg) +{ + assert(msg.isResponse() || msg.header(h_RequestLine).method() == ACK); + mDialog.send(msg); +} +*/ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogUsage.hxx b/src/libs/resiprocate/resip/dum/DialogUsage.hxx new file mode 100644 index 00000000..cc8b6151 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogUsage.hxx @@ -0,0 +1,147 @@ +#if !defined(RESIP_DIALOGUSAGE_HXX) +#define RESIP_DIALOGUSAGE_HXX + +#include "rutil/BaseException.hxx" +#include "rutil/SharedPtr.hxx" +#include "resip/dum/DumCommand.hxx" +#include "resip/dum/UserProfile.hxx" +#include "resip/dum/BaseUsage.hxx" +#include "resip/dum/Handles.hxx" +#include <map> +#include <string> + +namespace resip +{ + +class DialogUsageManager; +class Dialog; +class DialogId; +class DumTimeout; +class SipMessage; +class NameAddr; + +class DialogUsage : public BaseUsage +{ + public: + class Exception : public BaseException + { + public: + Exception(const Data& msg,const Data& file,int line); + virtual const char* name() const; + }; + + AppDialogSetHandle getAppDialogSet(); + AppDialogHandle getAppDialog(); + + // Convenience methods for accessing attributes of a dialog. + const NameAddr& myAddr() const; + const NameAddr& peerAddr() const; + const NameAddr& remoteTarget() const; + const DialogId& getDialogId() const; + const Data& getCallId() const; + SharedPtr<UserProfile> getUserProfile(); + void setUserHeaders(const std::map<std::string, std::string>& headers); + + protected: + friend class DialogSet; + friend class DialogUsageManager; + friend class DialogUsageSendCommand; + + class DialogUsageSendCommand : public DumCommandAdapter + { + public: + DialogUsageSendCommand(DialogUsage& usage, SharedPtr<SipMessage> msg) + : mDialogUsage(usage), + mMessage(msg) + { + } + + virtual void executeCommand() + { + mDialogUsage.send(mMessage); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "DialogUsageSendCommand"; + } + private: + DialogUsage& mDialogUsage; + SharedPtr<SipMessage> mMessage; + }; + + + //virtual void send(SipMessage& msg); + virtual void send(SharedPtr<SipMessage> msg); + virtual void sendCommand(SharedPtr<SipMessage> msg); + + // any usage that wants to give app a chance to adorn the message + // should override this method. + virtual void onReadyToSend(SipMessage&) {} + + DialogUsage(DialogUsageManager& dum, Dialog& dialog); + virtual ~DialogUsage(); + + //virtual void sendToDialog(SharedPtr<SipMessage> msg); + + virtual void dialogDestroyed(const SipMessage& msg) = 0; + + Dialog& mDialog; + + // Custom headers + std::map<std::string, std::string> mUserHeaders; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogUsageManager.cxx b/src/libs/resiprocate/resip/dum/DialogUsageManager.cxx new file mode 100644 index 00000000..6207133b --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogUsageManager.cxx @@ -0,0 +1,2535 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "resip/stack/SecurityAttributes.hxx" +#include "resip/stack/ShutdownMessage.hxx" +#include "resip/stack/SipFrag.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/SipStack.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/TransactionUserMessage.hxx" +#include "resip/stack/ConnectionTerminated.hxx" +#include "resip/stack/KeepAlivePong.hxx" +#include "resip/dum/AppDialog.hxx" +#include "resip/dum/AppDialogSet.hxx" +#include "resip/dum/AppDialogSetFactory.hxx" +#include "resip/dum/BaseUsage.hxx" +#include "resip/dum/ClientAuthManager.hxx" +#include "resip/dum/ClientInviteSession.hxx" +#include "resip/dum/ClientOutOfDialogReq.hxx" +#include "resip/dum/ClientPublication.hxx" +#include "resip/dum/ClientRegistration.hxx" +#include "resip/dum/ClientSubscription.hxx" +#include "resip/dum/DefaultServerReferHandler.hxx" +#include "resip/dum/DestroyUsage.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/DialogEventStateManager.hxx" +#include "resip/dum/DialogEventHandler.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/ClientPagerMessage.hxx" +#include "resip/dum/DumException.hxx" +#include "resip/dum/DumShutdownHandler.hxx" +#include "resip/dum/DumFeatureMessage.hxx" +#include "resip/dum/ExternalMessageBase.hxx" +#include "resip/dum/ExternalMessageHandler.hxx" +#include "resip/dum/InviteSessionCreator.hxx" +#include "resip/dum/InviteSessionHandler.hxx" +#include "resip/dum/KeepAliveManager.hxx" +#include "resip/dum/KeepAliveTimeout.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/OutOfDialogReqCreator.hxx" +#include "resip/dum/PagerMessageCreator.hxx" +#include "resip/dum/PublicationCreator.hxx" +#include "resip/dum/RedirectManager.hxx" +#include "resip/dum/RegistrationCreator.hxx" +#include "resip/dum/RemoteCertStore.hxx" +#include "resip/dum/RequestValidationHandler.hxx" +#include "resip/dum/ServerAuthManager.hxx" +#include "resip/dum/ServerInviteSession.hxx" +#include "resip/dum/ServerPublication.hxx" +#include "resip/dum/ServerSubscription.hxx" +#include "resip/dum/SubscriptionCreator.hxx" +#include "resip/dum/SubscriptionHandler.hxx" +#include "resip/dum/UserAuthInfo.hxx" +#include "resip/dum/DumFeature.hxx" +#include "resip/dum/IdentityHandler.hxx" +#include "resip/dum/DumDecrypted.hxx" +#include "resip/dum/CertMessage.hxx" +#include "resip/dum/OutgoingEvent.hxx" +#include "resip/dum/DumHelper.hxx" +#include "resip/dum/MergedRequestRemovalCommand.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Random.hxx" +#include "rutil/Lockable.hxx" +#include "rutil/WinLeakCheck.hxx" +#include "rutil/Timer.hxx" + +#ifdef USE_SSL +#include "resip/stack/ssl/Security.hxx" +#include "resip/dum/ssl/EncryptionManager.hxx" +#endif + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; +using namespace std; + +#ifdef RESIP_DUM_THREAD_DEBUG +#define threadCheck() \ + do \ + { \ + if(mThreadDebugKey) \ + { \ + assert(ThreadIf::tlsGetValue(mThreadDebugKey)); \ + } \ + } while (false) +#else +#define threadCheck() void() +#endif + + +DialogUsageManager::DialogUsageManager(SipStack& stack, bool createDefaultFeatures) : + TransactionUser(TransactionUser::DoNotRegisterForTransactionTermination, + TransactionUser::RegisterForConnectionTermination, + TransactionUser::RegisterForKeepAlivePongs), + mRedirectManager(new RedirectManager()), + mInviteSessionHandler(0), + mClientRegistrationHandler(0), + mServerRegistrationHandler(0), + mRedirectHandler(0), + mDialogSetHandler(0), + mRequestValidationHandler(0), + mRegistrationPersistenceManager(0), + mIsDefaultServerReferHandler(true), + mClientPagerMessageHandler(0), + mServerPagerMessageHandler(0), + mDialogEventStateManager(0), + mAppDialogSetFactory(new AppDialogSetFactory()), + mStack(stack), + mDumShutdownHandler(0), + mShutdownState(Running), + mThreadDebugKey(0), + mHiddenThreadDebugKey(0) +{ + //TODO -- create default features + mStack.registerTransactionUser(*this); + addServerSubscriptionHandler("refer", new DefaultServerReferHandler()); + + mFifo.setDescription("DialogUsageManager::mFifo"); + + mIncomingTarget = new IncomingTarget(*this); + mOutgoingTarget = new OutgoingTarget(*this); + + if (createDefaultFeatures) + { + SharedPtr<IdentityHandler> identity = SharedPtr<IdentityHandler>(new IdentityHandler(*this, *mIncomingTarget)); + +#if defined (USE_SSL) + SharedPtr<EncryptionManager> encryptionIncoming = SharedPtr<EncryptionManager>(new EncryptionManager(*this, *mIncomingTarget)); + SharedPtr<EncryptionManager> encryptionOutgoing = SharedPtr<EncryptionManager>(new EncryptionManager(*this, *mOutgoingTarget)); +#endif + + // default incoming features. + addIncomingFeature(identity); +#if defined (USE_SSL) + addIncomingFeature(encryptionIncoming); +#endif + + // default outgoing features. +#if defined (USE_SSL) + addOutgoingFeature(encryptionOutgoing); +#endif + + } + +} + +DialogUsageManager::~DialogUsageManager() +{ + mShutdownState = Destroying; + //InfoLog ( << "~DialogUsageManager" ); + +#if(0) + // !kh! + DialogSetMap::iterator dialogSet = mDialogSetMap.begin(); + for (; dialogSet != mDialogSetMap.end(); ++dialogSet) + { + delete dialogSet->second; + } +#endif + if(!mDialogSetMap.empty()) + { + DebugLog(<< "DialogUsageManager::mDialogSetMap has " << mDialogSetMap.size() << " DialogSets"); + DialogSetMap::const_iterator ds = mDialogSetMap.begin(); + for(; ds != mDialogSetMap.end(); ++ds) + { + DebugLog(<< "DialgSetId:" << ds->first); + DialogSet::DialogMap::const_iterator d = ds->second->mDialogs.begin(); + for(; d != ds->second->mDialogs.end(); ++d) + { + //const Dialog* p = &(d->second); + DebugLog(<<"DialogId:" << d->first << ", " << *d->second); + } + } + } + + while(!mDialogSetMap.empty()) + { + DialogSet* ds = mDialogSetMap.begin()->second; + delete ds; + } + + if(mIsDefaultServerReferHandler) + { + delete mServerSubscriptionHandlers["refer"]; + } + + delete mIncomingTarget; + delete mOutgoingTarget; + + //InfoLog ( << "~DialogUsageManager done" ); +} + +const Data& +DialogUsageManager::name() const +{ + static Data n("DialogUsageManager"); + return n; +} + +void +DialogUsageManager::addTransport( TransportType protocol, + int port, + IpVersion version, + const Data& ipInterface, + const Data& sipDomainname, // only used + const Data& privateKeyPassPhrase, + SecurityTypes::SSLType sslType, + unsigned transportFlags) +{ + mStack.addTransport(protocol, port, version, StunDisabled, ipInterface, + sipDomainname, privateKeyPassPhrase, sslType, + transportFlags); +} + +SipStack& +DialogUsageManager::getSipStack() +{ + return mStack; +} + +const SipStack& +DialogUsageManager::getSipStack() const +{ + return mStack; +} + +Security* +DialogUsageManager::getSecurity() +{ + return mStack.getSecurity(); +} + +Data +DialogUsageManager::getHostAddress() +{ + return mStack.getHostAddress(); +} + +void +DialogUsageManager::onAllHandlesDestroyed() +{ + if (mDumShutdownHandler) + { + switch (mShutdownState) + { + case ShutdownRequested: + InfoLog (<< "DialogUsageManager::onAllHandlesDestroyed: removing TU"); + //assert(mHandleMap.empty()); + mShutdownState = RemovingTransactionUser; + mStack.unregisterTransactionUser(*this); + break; + default: + break; + } + } +} + + +void +DialogUsageManager::shutdown(DumShutdownHandler* h) +{ + InfoLog (<< "shutdown: dialogSets=" << mDialogSetMap.size()); + + mDumShutdownHandler = h; + mShutdownState = ShutdownRequested; + mStack.requestTransactionUserShutdown(*this); + shutdownWhenEmpty(); +} + +// void +// DialogUsageManager::shutdownIfNoUsages(DumShutdownHandler* h) +// { +// InfoLog (<< "shutdown when no usages"); +// +// mDumShutdownHandler = h; +// mShutdownState = ShutdownRequested; +// assert(0); +// } + +void +DialogUsageManager::forceShutdown(DumShutdownHandler* h) +{ + WarningLog (<< "force shutdown "); + dumpHandles(); + + mDumShutdownHandler = h; + //HandleManager::shutdown(); // clear out usages + mShutdownState = ShutdownRequested; + DialogUsageManager::onAllHandlesDestroyed(); +} + +void DialogUsageManager::setAppDialogSetFactory(std::auto_ptr<AppDialogSetFactory> factory) +{ + mAppDialogSetFactory = factory; +} + +SharedPtr<MasterProfile>& +DialogUsageManager::getMasterProfile() +{ + assert(mMasterProfile.get()); + return mMasterProfile; +} + +SharedPtr<UserProfile>& +DialogUsageManager::getMasterUserProfile() +{ + assert(mMasterUserProfile.get()); + return mMasterUserProfile; +} + +void DialogUsageManager::setMasterProfile(const SharedPtr<MasterProfile>& masterProfile) +{ + assert(!mMasterProfile.get()); + mMasterProfile = masterProfile; + mMasterUserProfile = masterProfile; // required so that we can return a reference to SharedPtr<UserProfile> in getMasterUserProfile +} + +void DialogUsageManager::setKeepAliveManager(std::auto_ptr<KeepAliveManager> manager) +{ + mKeepAliveManager = manager; + mKeepAliveManager->setDialogUsageManager(this); +} + +void DialogUsageManager::setRedirectManager(std::auto_ptr<RedirectManager> manager) +{ + mRedirectManager = manager; +} + +void DialogUsageManager::setRedirectHandler(RedirectHandler* handler) +{ + mRedirectHandler = handler; +} + +RedirectHandler* DialogUsageManager::getRedirectHandler() +{ + return mRedirectHandler; +} + +void +DialogUsageManager::setClientAuthManager(std::auto_ptr<ClientAuthManager> manager) +{ + mClientAuthManager = manager; +} + +void +DialogUsageManager::setServerAuthManager(SharedPtr<ServerAuthManager> manager) +{ + mIncomingFeatureList.insert(mIncomingFeatureList.begin(), manager); +} + +void +DialogUsageManager::setClientRegistrationHandler(ClientRegistrationHandler* handler) +{ + assert(!mClientRegistrationHandler); + mClientRegistrationHandler = handler; +} + +void +DialogUsageManager::setServerRegistrationHandler(ServerRegistrationHandler* handler) +{ + assert(!mServerRegistrationHandler); + mServerRegistrationHandler = handler; +} + +void +DialogUsageManager::setDialogSetHandler(DialogSetHandler* handler) +{ + mDialogSetHandler = handler; +} + +void +DialogUsageManager::setInviteSessionHandler(InviteSessionHandler* handler) +{ + assert(!mInviteSessionHandler); + mInviteSessionHandler = handler; +} + +void +DialogUsageManager::setRequestValidationHandler(RequestValidationHandler* handler) +{ + assert(!mRequestValidationHandler); + mRequestValidationHandler = handler; +} + +void +DialogUsageManager::setRegistrationPersistenceManager(RegistrationPersistenceManager* manager) +{ + assert(!mRegistrationPersistenceManager); + mRegistrationPersistenceManager = manager; +} + +void +DialogUsageManager::setRemoteCertStore(auto_ptr<RemoteCertStore> store) +{ +} + +void +DialogUsageManager::addTimer(DumTimeout::Type type, unsigned long duration, + BaseUsageHandle target, unsigned int cseq, unsigned int rseq) +{ + DumTimeout t(type, duration, target, cseq, rseq); + mStack.post(t, duration, this); +} + +void +DialogUsageManager::addTimerMs(DumTimeout::Type type, unsigned long duration, + BaseUsageHandle target, unsigned int cseq, unsigned int rseq, + const Data &transactionId /*= Data::Empty*/) +{ + DumTimeout t(type, duration, target, cseq, rseq, transactionId); + mStack.postMS(t, duration, this); +} + +void +DialogUsageManager::addClientSubscriptionHandler(const Data& eventType, ClientSubscriptionHandler* handler) +{ + assert(handler); + assert(mClientSubscriptionHandlers.count(eventType) == 0); + mClientSubscriptionHandlers[eventType] = handler; +} + +void +DialogUsageManager::addServerSubscriptionHandler(const Data& eventType, ServerSubscriptionHandler* handler) +{ + assert(handler); + //default do-nothing server side refer handler can be replaced + if (eventType == "refer" && mServerSubscriptionHandlers.count(eventType)) + { + delete mServerSubscriptionHandlers[eventType]; + mIsDefaultServerReferHandler = false; + //mServerSubscriptionHandlers.erase(eventType); + } + + mServerSubscriptionHandlers[eventType] = handler; +} + +void +DialogUsageManager::addClientPublicationHandler(const Data& eventType, ClientPublicationHandler* handler) +{ + assert(handler); + assert(mClientPublicationHandlers.count(eventType) == 0); + mClientPublicationHandlers[eventType] = handler; +} + +void +DialogUsageManager::addServerPublicationHandler(const Data& eventType, ServerPublicationHandler* handler) +{ + assert(handler); + assert(mServerPublicationHandlers.count(eventType) == 0); + mServerPublicationHandlers[eventType] = handler; +} + +void +DialogUsageManager::addOutOfDialogHandler(MethodTypes type, OutOfDialogHandler* handler) +{ + assert(handler); + assert(mOutOfDialogHandlers.count(type) == 0); + mOutOfDialogHandlers[type] = handler; +} + +void +DialogUsageManager::setClientPagerMessageHandler(ClientPagerMessageHandler* handler) +{ + mClientPagerMessageHandler = handler; +} + +void +DialogUsageManager::setServerPagerMessageHandler(ServerPagerMessageHandler* handler) +{ + mServerPagerMessageHandler = handler; +} + +void +DialogUsageManager::addExternalMessageHandler(ExternalMessageHandler* handler) +{ + std::vector<ExternalMessageHandler*>::iterator found = std::find(mExternalMessageHandlers.begin(), mExternalMessageHandlers.end(), handler); + if (found == mExternalMessageHandlers.end()) + { + mExternalMessageHandlers.push_back(handler); + } +} + +void +DialogUsageManager::removeExternalMessageHandler(ExternalMessageHandler* handler) +{ + std::vector<ExternalMessageHandler*>::iterator found = std::find(mExternalMessageHandlers.begin(), mExternalMessageHandlers.end(), handler); + if (found != mExternalMessageHandlers.end()) + { + mExternalMessageHandlers.erase(found); + } +} + +void +DialogUsageManager::clearExternalMessageHandler() +{ + std::vector<ExternalMessageHandler*> empty; + empty.swap(mExternalMessageHandlers); +} + + +DialogSet* +DialogUsageManager::makeUacDialogSet(BaseCreator* creator, AppDialogSet* appDs) +{ + threadCheck(); + if (mDumShutdownHandler) + { + throw DumException("Cannot create new sessions when DUM is shutting down.", __FILE__, __LINE__); + } + + if (appDs == 0) + { + appDs = new AppDialogSet(*this); + } + DialogSet* ds = new DialogSet(creator, *this); + + appDs->mDialogSet = ds; + ds->mAppDialogSet = appDs; + + StackLog ( << "************* Adding DialogSet ***************: " << ds->getId()); + //StackLog ( << "Before: " << InserterP(mDialogSetMap) ); + mDialogSetMap[ds->getId()] = ds; + StackLog ( << "DialogSetMap: " << InserterP(mDialogSetMap) ); + return ds; +} + +SharedPtr<SipMessage> +DialogUsageManager::makeNewSession(BaseCreator* creator, AppDialogSet* appDs) +{ + makeUacDialogSet(creator, appDs); + return creator->getLastRequest(); +} + +void +DialogUsageManager::makeResponse(SipMessage& response, + const SipMessage& request, + int responseCode, + const Data& reason) const +{ + assert(request.isRequest()); + Helper::makeResponse(response, request, responseCode, reason); +} + +void +DialogUsageManager::sendResponse(const SipMessage& response) +{ + assert(response.isResponse()); + mStack.send(response, this); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeInviteSession(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const Contents* initialOffer, AppDialogSet* appDs) +{ + return makeInviteSession(target, userProfile, initialOffer, None, 0, appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeInviteSession(const NameAddr& target, const Contents* initialOffer, AppDialogSet* appDs) +{ + return makeInviteSession(target, getMasterUserProfile(), initialOffer, None, 0, appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeInviteSession(const NameAddr& target, + const SharedPtr<UserProfile>& userProfile, + const Contents* initialOffer, + EncryptionLevel level, + const Contents* alternative, + AppDialogSet* appDs) +{ + SharedPtr<SipMessage> inv = makeNewSession(new InviteSessionCreator(*this, target, userProfile, initialOffer, level, alternative), appDs); + DumHelper::setOutgoingEncryptionLevel(*inv, level); + return inv; +} + +SharedPtr<SipMessage> +DialogUsageManager::makeInviteSession(const NameAddr& target, + const Contents* initialOffer, + EncryptionLevel level, + const Contents* alternative, + AppDialogSet* appDs) +{ + return makeInviteSession(target, getMasterUserProfile(), initialOffer, level, alternative, appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeInviteSession(const NameAddr& target, + InviteSessionHandle sessionToReplace, + const SharedPtr<UserProfile>& userProfile, + const Contents* initialOffer, + AppDialogSet* ads) +{ + SharedPtr<SipMessage> inv = makeInviteSession(target, userProfile, initialOffer, ads); + // add replaces header + assert(sessionToReplace.isValid()); + if(sessionToReplace.isValid()) + { + CallId replaces; + DialogId id = sessionToReplace->getDialogId(); + replaces.value() = id.getCallId(); + replaces.param(p_toTag) = id.getRemoteTag(); + replaces.param(p_fromTag) = id.getLocalTag(); + inv->header(h_Replaces) = replaces; + } + return inv; +} + +SharedPtr<SipMessage> +DialogUsageManager::makeInviteSession(const NameAddr& target, + InviteSessionHandle sessionToReplace, + const SharedPtr<UserProfile>& userProfile, + const Contents* initialOffer, + EncryptionLevel level, + const Contents* alternative, + AppDialogSet* ads) +{ + SharedPtr<SipMessage> inv = makeInviteSession(target, userProfile, initialOffer, level, alternative, ads); + // add replaces header + assert(sessionToReplace.isValid()); + if(sessionToReplace.isValid()) + { + CallId replaces; + DialogId id = sessionToReplace->getDialogId(); + replaces.value() = id.getCallId(); + replaces.param(p_toTag) = id.getRemoteTag(); + replaces.param(p_fromTag) = id.getLocalTag(); + inv->header(h_Replaces) = replaces; + } + return inv; +} + +SharedPtr<SipMessage> +DialogUsageManager::makeInviteSession(const NameAddr& target, + InviteSessionHandle sessionToReplace, + const Contents* initialOffer, + EncryptionLevel level, + const Contents* alternative , + AppDialogSet* ads) +{ + SharedPtr<SipMessage> inv = makeInviteSession(target, initialOffer, level, alternative, ads); + // add replaces header + assert(sessionToReplace.isValid()); + if(sessionToReplace.isValid()) + { + CallId replaces; + DialogId id = sessionToReplace->getDialogId(); + replaces.value() = id.getCallId(); + replaces.param(p_toTag) = id.getRemoteTag(); + replaces.param(p_fromTag) = id.getLocalTag(); + inv->header(h_Replaces) = replaces; + } + return inv; +} + +SharedPtr<SipMessage> +DialogUsageManager::makeInviteSessionFromRefer(const SipMessage& refer, + ServerSubscriptionHandle serverSub, + const Contents* initialOffer, + AppDialogSet* appDs) +{ + return makeInviteSessionFromRefer(refer, serverSub, initialOffer, None, 0, appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeInviteSessionFromRefer(const SipMessage& refer, + const SharedPtr<UserProfile>& userProfile, + const Contents* initialOffer, + AppDialogSet* appDs) +{ + ServerSubscriptionHandle empty; + return makeInviteSessionFromRefer(refer, userProfile, empty, initialOffer, None, 0, appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeInviteSessionFromRefer(const SipMessage& refer, + ServerSubscriptionHandle serverSub, + const Contents* initialOffer, + EncryptionLevel level, + const Contents* alternative, + AppDialogSet* appDs) +{ + return makeInviteSessionFromRefer(refer, serverSub.isValid() ? serverSub->mDialog.mDialogSet.getUserProfile() : getMasterUserProfile(), serverSub, initialOffer, level, alternative, appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeInviteSessionFromRefer(const SipMessage& refer, + const SharedPtr<UserProfile>& userProfile, + ServerSubscriptionHandle serverSub, + const Contents* initialOffer, + EncryptionLevel level, + const Contents* alternative, + AppDialogSet* appDs) +{ + if (serverSub.isValid()) + { + DebugLog(<< "implicit subscription"); + //generate and send 100 + SipFrag contents; + contents.message().header(h_StatusLine).statusCode() = 100; + contents.message().header(h_StatusLine).reason() = "Trying"; + //will be cloned...ServerSub may not have the most efficient API possible + serverSub->setSubscriptionState(Active); + SharedPtr<SipMessage> notify = serverSub->update(&contents); +// mInviteSessionHandler->onReadyToSend(InviteSessionHandle::NotValid(), notify); + serverSub->send(notify); + } + + //19.1.5 + NameAddr target = refer.header(h_ReferTo); + target.uri().removeEmbedded(); + target.uri().remove(p_method); + + // !jf! this code assumes you have a UserProfile + SharedPtr<SipMessage> inv = makeNewSession(new InviteSessionCreator(*this, + target, + userProfile, + initialOffer, level, alternative, serverSub), appDs); + DumHelper::setOutgoingEncryptionLevel(*inv, level); + + //could pass dummy target, then apply merge rules from 19.1.5...or + //makeNewSession would use rules from 19.1.5 + if (refer.exists(h_ReferredBy)) + { + inv->header(h_ReferredBy) = refer.header(h_ReferredBy); + } + + const Uri& referTo = refer.header(h_ReferTo).uri(); + //19.1.5 + if (referTo.hasEmbedded() && referTo.embedded().exists(h_Replaces)) + { + inv->header(h_Replaces) = referTo.embedded().header(h_Replaces); + } + + return inv; +} + +SharedPtr<SipMessage> +DialogUsageManager::makeRefer(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const H_ReferTo::Type& referTo, AppDialogSet* appDs) +{ + return makeNewSession(new SubscriptionCreator(*this, target, userProfile, referTo), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeRefer(const NameAddr& target, const H_ReferTo::Type& referTo, AppDialogSet* appDs) +{ + return makeNewSession(new SubscriptionCreator(*this, target, getMasterUserProfile(), referTo), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeSubscription(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const Data& eventType, AppDialogSet* appDs) +{ + assert(userProfile.get()); + return makeNewSession(new SubscriptionCreator(*this, target, userProfile, eventType, userProfile->getDefaultSubscriptionTime()), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeSubscription(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const Data& eventType, + UInt32 subscriptionTime, AppDialogSet* appDs) +{ + return makeNewSession(new SubscriptionCreator(*this, target, userProfile, eventType, subscriptionTime), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeSubscription(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const Data& eventType, + UInt32 subscriptionTime, int refreshInterval, AppDialogSet* appDs) +{ + return makeNewSession(new SubscriptionCreator(*this, target, userProfile, eventType, subscriptionTime, refreshInterval), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeSubscription(const NameAddr& target, const Data& eventType, AppDialogSet* appDs) +{ + return makeNewSession(new SubscriptionCreator(*this, target, getMasterUserProfile(), eventType, getMasterProfile()->getDefaultSubscriptionTime()), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeSubscription(const NameAddr& target, const Data& eventType, + UInt32 subscriptionTime, AppDialogSet* appDs) +{ + return makeNewSession(new SubscriptionCreator(*this, target, getMasterUserProfile(), eventType, subscriptionTime), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeSubscription(const NameAddr& target, const Data& eventType, + UInt32 subscriptionTime, int refreshInterval, AppDialogSet* appDs) +{ + return makeNewSession(new SubscriptionCreator(*this, target, getMasterUserProfile(), eventType, subscriptionTime, refreshInterval), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeRegistration(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, AppDialogSet* appDs) +{ + assert(userProfile.get()); + return makeNewSession(new RegistrationCreator(*this, target, userProfile, userProfile->getDefaultRegistrationTime()), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeRegistration(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, UInt32 registrationTime, AppDialogSet* appDs) +{ + return makeNewSession(new RegistrationCreator(*this, target, userProfile, registrationTime), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeRegistration(const NameAddr& target, AppDialogSet* appDs) +{ + return makeNewSession(new RegistrationCreator(*this, target, getMasterUserProfile(), getMasterProfile()->getDefaultRegistrationTime()), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeRegistration(const NameAddr& target, UInt32 registrationTime, AppDialogSet* appDs) +{ + return makeNewSession(new RegistrationCreator(*this, target, getMasterUserProfile(), registrationTime), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makePublication(const NameAddr& targetDocument, + const SharedPtr<UserProfile>& userProfile, + const Contents& body, + const Data& eventType, + UInt32 expiresSeconds, + AppDialogSet* appDs) +{ + return makeNewSession(new PublicationCreator(*this, targetDocument, userProfile, body, eventType, expiresSeconds), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makePublication(const NameAddr& targetDocument, + const Contents& body, + const Data& eventType, + UInt32 expiresSeconds, + AppDialogSet* appDs) +{ + return makeNewSession(new PublicationCreator(*this, targetDocument, getMasterUserProfile(), body, eventType, expiresSeconds), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeOutOfDialogRequest(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const MethodTypes meth, AppDialogSet* appDs) +{ + return makeNewSession(new OutOfDialogReqCreator(*this, meth, target, userProfile), appDs); +} + +SharedPtr<SipMessage> +DialogUsageManager::makeOutOfDialogRequest(const NameAddr& target, const MethodTypes meth, AppDialogSet* appDs) +{ + return makeNewSession(new OutOfDialogReqCreator(*this, meth, target, getMasterUserProfile()), appDs); +} + +ClientPagerMessageHandle +DialogUsageManager::makePagerMessage(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, AppDialogSet* appDs) +{ + if (!mClientPagerMessageHandler) + { + throw DumException("Cannot send MESSAGE messages without a ClientPagerMessageHandler", __FILE__, __LINE__); + } + DialogSet* ds = makeUacDialogSet(new PagerMessageCreator(*this, target, userProfile), appDs); + ClientPagerMessage* cpm = new ClientPagerMessage(*this, *ds); + ds->mClientPagerMessage = cpm; + return cpm->getHandle(); +} + +ClientPagerMessageHandle +DialogUsageManager::makePagerMessage(const NameAddr& target, AppDialogSet* appDs) +{ + return makePagerMessage(target, getMasterUserProfile(), appDs); +} + +void +DialogUsageManager::send(SharedPtr<SipMessage> msg) +{ + // !slg! There is probably a more efficient way to get the userProfile here (pass it in?) + DialogSet* ds = findDialogSet(DialogSetId(*msg)); + UserProfile* userProfile; + if (ds == 0) + { + userProfile = getMasterUserProfile().get(); + } + else + { + userProfile = ds->getUserProfile().get(); + } + + assert(userProfile); + if (!userProfile->isAnonymous() && userProfile->hasUserAgent()) + { + msg->header(h_UserAgent).value() = userProfile->getUserAgent(); + } + if (userProfile->isAnonymous()) + { + msg->remove(h_ReplyTo); + msg->remove(h_UserAgent); + msg->remove(h_Organization); + msg->remove(h_Server); + msg->remove(h_Subject); + msg->remove(h_InReplyTo); + + msg->remove(h_CallInfos); + msg->remove(h_Warnings); + } + + assert(userProfile); + if (msg->isRequest() + && userProfile->hasProxyRequires() + && msg->header(h_RequestLine).method() != ACK + && msg->header(h_RequestLine).method() != CANCEL) + { + msg->header(h_ProxyRequires) = userProfile->getProxyRequires(); + } + + // .bwc. This is to avoid leaving extra copies of the decorator in msg, + // when the caller of this function holds onto the reference (and this + // happens quite often in DUM). I would prefer to refactor such that we + // are operating on a copy in this function, but this would require a lot + // of work on the DumFeatureChain stuff (or, require an extra copy on top + // of the one we're doing when we send the message to the stack, which + // would chew up a lot of extra cycles). + msg->clearOutboundDecorators(); + + // Add outbound decorator from userprofile - note: it is important that this is + // done before the call to mClientAuthManager->addAuthentication, since the ClientAuthManager + // will install outbound decorators and we want these to run after the user provided ones, in + // case a user provided decorator modifes the message body used in auth. + SharedPtr<MessageDecorator> outboundDecorator = userProfile->getOutboundDecorator(); + if (outboundDecorator.get()) + { + msg->addOutboundDecorator(std::auto_ptr<MessageDecorator>(outboundDecorator->clone())); + } + else + { + DebugLog(<< "No outbound decorator for message"); + } + + if (msg->isRequest()) + { + // We may not need to call reset() if makeRequest is always used. + if (msg->header(h_RequestLine).method() != CANCEL && + msg->header(h_RequestLine).method() != ACK && + msg->exists(h_Vias)) + { + msg->header(h_Vias).front().param(p_branch).reset(); + } + + if (msg->exists(h_Vias)) + { + if(!userProfile->getRportEnabled()) + { + msg->header(h_Vias).front().remove(p_rport); + } + int fixedTransportPort = userProfile->getFixedTransportPort(); + if(fixedTransportPort != 0) + { + msg->header(h_Vias).front().sentPort() = fixedTransportPort; + } + const Data& fixedTransportInterface = userProfile->getFixedTransportInterface(); + if(!fixedTransportInterface.empty()) + { + msg->header(h_Vias).front().sentHost() = fixedTransportInterface; + } + } + + if (mClientAuthManager.get() && msg->header(h_RequestLine).method() != ACK) + { + mClientAuthManager->addAuthentication(*msg); + } + + if (msg->header(h_RequestLine).method() == INVITE) + { + if (ds != 0) + { + if (mDialogEventStateManager) + { + Dialog* d = ds->findDialog(*msg); + if (d != 0) + { + mDialogEventStateManager->onConfirmed(*d, d->getInviteSession()); + } + else + { + mDialogEventStateManager->onTryingUac(*ds, *msg); + } + } + } + } + } + + DebugLog (<< "SEND: " << std::endl << std::endl << *msg); + + OutgoingEvent* event = new OutgoingEvent(msg); + outgoingProcess(auto_ptr<Message>(event)); +} + +void +DialogUsageManager::sendCommand(SharedPtr<SipMessage> request) +{ + SendCommand* s=new SendCommand(request, *this); + post(s); +} + + +void DialogUsageManager::outgoingProcess(auto_ptr<Message> message) +{ + Data tid = Data::Empty; + { + OutgoingEvent* sipMsg = dynamic_cast<OutgoingEvent*>(message.get()); + if (sipMsg) + { + tid = sipMsg->getTransactionId(); + } + + DumFeatureMessage* featureMsg = dynamic_cast<DumFeatureMessage*>(message.get()); + if (featureMsg) + { + InfoLog(<<"Got a DumFeatureMessage" << featureMsg); + tid = featureMsg->getTransactionId(); + } + } + + if (tid == Data::Empty && mOutgoingMessageInterceptor.get()) + { + mOutgoingMessageInterceptor->process(message.get()); + return; + } + else if (tid != Data::Empty && !mOutgoingFeatureList.empty()) + { + FeatureChainMap::iterator it; + //efficiently find or create FeatureChain, should prob. be a utility template + { + FeatureChainMap::iterator lb = mOutgoingFeatureChainMap.lower_bound(tid); + if (lb != mOutgoingFeatureChainMap.end() && !(mOutgoingFeatureChainMap.key_comp()(tid, lb->first))) + { + it = lb; + } + else + { + it = mOutgoingFeatureChainMap.insert(lb, FeatureChainMap::value_type(tid, new DumFeatureChain(*this, mOutgoingFeatureList, *mOutgoingTarget))); + } + } + + DumFeatureChain::ProcessingResult res = it->second->process(message.get()); + + if (res & DumFeatureChain::ChainDoneBit) + { + delete it->second; + mOutgoingFeatureChainMap.erase(it); + } + + if (res & DumFeatureChain::EventTakenBit) + { + message.release(); + return; + } + } + + OutgoingEvent* event = dynamic_cast<OutgoingEvent*>(message.get()); + //assert(event); + //.dcm. a TID collision can cause a message to be delivered to a finished + //chain. This is probably because pseudorandom was being used on Win32. + if (event) + { + if (event->message()->isRequest()) + { + DialogSet* ds = findDialogSet(DialogSetId(*event->message())); + UserProfile* userProfile; + if (ds == 0) + { + userProfile = getMasterUserProfile().get(); + } + else + { + userProfile = ds->getUserProfile().get(); + } + + assert(userProfile); + + //!dcm! -- unique SharedPtr to auto_ptr conversion prob. a worthwhile + //optimzation here. SharedPtr would have to be changed; would + //throw/assert if not unique. + std::auto_ptr<SipMessage> toSend(static_cast<SipMessage*>(event->message()->clone())); + + // .bwc. Protect ourselves from garbage with an isWellFormed() check. + // (Code in Dialog doesn't check for well-formedness in the + // Record-Route stack, so bad stuff there can end up here) + if (event->message()->exists(h_Routes) && + !event->message()->header(h_Routes).empty() && + event->message()->header(h_Routes).front().isWellFormed() && + !event->message()->header(h_Routes).front().uri().exists(p_lr)) + { + Helper::processStrictRoute(*toSend); + sendUsingOutboundIfAppropriate(*userProfile, toSend); + } + else + { + sendUsingOutboundIfAppropriate(*userProfile, toSend); + } + } + else + { + sendResponse(*event->message()); + } + } +} + +void +DialogUsageManager::sendUsingOutboundIfAppropriate(UserProfile& userProfile, auto_ptr<SipMessage> msg) +{ + //a little inefficient, branch parameter might be better + DialogId id(*msg); + if (userProfile.hasOutboundProxy() && + (!findDialog(id) || userProfile.getForceOutboundProxyOnAllRequestsEnabled())) + { + DebugLog ( << "Using outbound proxy: " + << userProfile.getOutboundProxy().uri() + << " -> " << msg->brief()); + + if (userProfile.getExpressOutboundAsRouteSetEnabled()) + { + // prepend the outbound proxy to the service route + msg->header(h_Routes).push_front(NameAddr(userProfile.getOutboundProxy().uri())); + if(userProfile.clientOutboundEnabled() && userProfile.mClientOutboundFlowTuple.mFlowKey != 0) + { + DebugLog ( << "Sending with client outbound flow tuple to express outbound" ); + DebugLog ( << "Flow Tuple: " << userProfile.mClientOutboundFlowTuple << " and key: " << userProfile.mClientOutboundFlowTuple.mFlowKey); + mStack.sendTo(msg, userProfile.mClientOutboundFlowTuple, this); + } + else + { + DebugLog ( << "Sending to express outbound w/o flow tuple"); + mStack.send(msg, this); + } + } + else + { + if(userProfile.clientOutboundEnabled() && userProfile.mClientOutboundFlowTuple.mFlowKey != 0) + { + DebugLog ( << "Sending to outbound (no express) with flow tuple"); + mStack.sendTo(msg, userProfile.mClientOutboundFlowTuple, this); + } + else + { + DebugLog ( << "Sending to outbound uri"); + mStack.sendTo(msg, userProfile.getOutboundProxy().uri(), this); + } + } + } + else + { + DebugLog (<< "Send: " << msg->brief()); + if(userProfile.clientOutboundEnabled() && userProfile.mClientOutboundFlowTuple.mFlowKey != 0) + { + mStack.sendTo(msg, userProfile.mClientOutboundFlowTuple, this); + } + else + { + mStack.send(msg, this); + } + } +} + + +void +DialogUsageManager::end(DialogSetId setid) +{ + DialogSet* ds = findDialogSet(setid); + if (ds == 0) + { + throw Exception("Request no longer exists", __FILE__, __LINE__); + } + else + { + ds->end(); + } +} + +void +DialogUsageManager::destroy(const BaseUsage* usage) +{ + if (mShutdownState != Destroying) + { + post(new DestroyUsage(usage->mHandle)); + } + else + { + InfoLog(<< "DialogUsageManager::destroy() not posting to stack"); + } +} + +void +DialogUsageManager::destroy(DialogSet* dset) +{ + if (mShutdownState != Destroying) + { + post(new DestroyUsage(dset)); + } + else + { + InfoLog(<< "DialogUsageManager::destroy() not posting to stack"); + } +} + +void +DialogUsageManager::destroy(Dialog* d) +{ + if (mShutdownState != Destroying) + { + post(new DestroyUsage(d)); + } + else + { + InfoLog(<< "DialogUsageManager::destroy() not posting to stack"); + } +} + + +Dialog* +DialogUsageManager::findDialog(const DialogId& id) +{ + DialogSet* ds = findDialogSet(id.getDialogSetId()); + if (ds) + { + return ds->findDialog(id); + } + else + { + return 0; + } +} + + +InviteSessionHandle +DialogUsageManager::findInviteSession(DialogId id) +{ + Dialog* dialog = findDialog(id); + if (dialog && dialog->mInviteSession) + { + return dialog->mInviteSession->getSessionHandle(); + } + + return InviteSessionHandle::NotValid(); +} + +pair<InviteSessionHandle, int> +DialogUsageManager::findInviteSession(CallId replaces) +{ + //486/481/603 decision making logic where? App may not wish to keep track of + //invitesession state + //Logic is here for now. + InviteSessionHandle is = findInviteSession(DialogId(replaces.value(), + replaces.param(p_toTag), + replaces.param(p_fromTag))); + int ErrorStatusCode = 481; // Call/Transaction Does Not Exist + + // If we matched a session - Do RFC3891 Section 3 Processing + if(is.isValid()) + { + // Note some missing checks are: + // 1. If the Replaces header field matches more than one dialog, the UA must act as + // if no match was found + // 2. Verify that the initiator of the new Invite is authorized + if(is->isTerminated()) + { + ErrorStatusCode = 603; // Declined + is = InviteSessionHandle::NotValid(); + } + else if(is->isConnected()) + { + // Check if early-only flag is present in replaces header + if(replaces.exists(p_earlyOnly)) + { + ErrorStatusCode = 486; // Busy Here + is = InviteSessionHandle::NotValid(); + } + } + else if(!is->isEarly()) + { + // replaces can't be used on early dialogs that were not initiated by this UA - ie. InviteSession::Proceeding state + ErrorStatusCode = 481; // Call/Transaction Does Not Exist + is = InviteSessionHandle::NotValid(); + } + } + return make_pair(is, ErrorStatusCode); +} + +AppDialogHandle DialogUsageManager::findAppDialog(const DialogId& id) +{ + Dialog* pDialog = findDialog(id); + + if(pDialog && pDialog->mAppDialog) + { + return pDialog->mAppDialog->getHandle(); + } + + // Return an invalid handle + return AppDialogHandle(); +} + +AppDialogSetHandle DialogUsageManager::findAppDialogSet(const DialogSetId& id) +{ + DialogSet* pDialogSet = findDialogSet(id); + + if(pDialogSet && pDialogSet->mAppDialogSet) + { + return pDialogSet->mAppDialogSet->getHandle(); + } + + // Return an invalid handle + return AppDialogSetHandle(); +} + +void +DialogUsageManager::internalProcess(std::auto_ptr<Message> msg) +{ +#ifdef RESIP_DUM_THREAD_DEBUG + if(!mThreadDebugKey) + { + // .bwc. Probably means multiple threads are trying to give DUM cycles + // simultaneously. + assert(!mHiddenThreadDebugKey); + // No d'tor needed, since we're just going to use a pointer to this. + if(!ThreadIf::tlsKeyCreate(mThreadDebugKey, 0)) + { + // .bwc. We really could pass anything here, but for the sake of + // passing a valid pointer, I have (completely arbitrarily) chosen a + // pointer to the DUM. All that matters is that this value is non-null + ThreadIf::tlsSetValue(mThreadDebugKey, this); + } + else + { + ErrLog(<< "ThreadIf::tlsKeyCreate() failed!"); + } + } +#endif + + threadCheck(); + + // After a Stack ShutdownMessage has been received, don't do anything else in dum + if (mShutdownState == Shutdown) + { + return; + } + + { + TransactionUserMessage* tuMsg = dynamic_cast<TransactionUserMessage*>(msg.get()); + if (tuMsg) + { + InfoLog (<< "TU unregistered "); + assert(mShutdownState == RemovingTransactionUser); + assert(tuMsg->type() == TransactionUserMessage::TransactionUserRemoved); + mShutdownState = Shutdown; + if (mDumShutdownHandler) + { + mDumShutdownHandler->onDumCanBeDeleted(); + mDumShutdownHandler = 0; // prevent mDumShutdownHandler getting called more than once + } + return; + } + } + + { + KeepAlivePong* pong = dynamic_cast<KeepAlivePong*>(msg.get()); + if (pong) + { + DebugLog(<< "keepalive pong received from " << pong->getFlow()); + if (mKeepAliveManager.get()) + { + mKeepAliveManager->receivedPong(pong->getFlow()); + } + return; + } + } + + { + DestroyUsage* destroyUsage = dynamic_cast<DestroyUsage*>(msg.get()); + if (destroyUsage) + { + //DebugLog(<< "Destroying usage" ); + destroyUsage->destroy(); + return; + } + } + + { + DumTimeout* dumMsg = dynamic_cast<DumTimeout*>(msg.get()); + if (dumMsg) + { + //DebugLog(<< "Timeout Message" ); + if (!dumMsg->getBaseUsage().isValid()) + { + return; + } + dumMsg->getBaseUsage()->dispatch(*dumMsg); + return; + } + } + + { + KeepAliveTimeout* keepAliveMsg = dynamic_cast<KeepAliveTimeout*>(msg.get()); + if (keepAliveMsg) + { + //DebugLog(<< "Keep Alive Message" ); + if (mKeepAliveManager.get()) + { + mKeepAliveManager->process(*keepAliveMsg); + } + return; + } + } + + { + KeepAlivePongTimeout* keepAlivePongMsg = dynamic_cast<KeepAlivePongTimeout*>(msg.get()); + if (keepAlivePongMsg) + { + //DebugLog(<< "Keep Alive Pong Message" ); + if (mKeepAliveManager.get()) + { + mKeepAliveManager->process(*keepAlivePongMsg); + } + return; + } + } + + { + ConnectionTerminated* terminated = dynamic_cast<ConnectionTerminated*>(msg.get()); + if (terminated) + { + // Notify all dialogSets, in case they need to react (ie. client outbound support) + // First find all applicable dialogsets, since flow token in user profile will + // be cleared by first dialogset we notify, then notify all dialogset's + std::list<DialogSet*> dialogSetsToNotify; + DialogSetMap::iterator it = mDialogSetMap.begin(); + for(; it != mDialogSetMap.end(); it++) + { + if(it->second->mUserProfile->clientOutboundEnabled() && + it->second->mUserProfile->getClientOutboundFlowTuple().mFlowKey == terminated->getFlow().mFlowKey && // Flow key is not part of Tuple operator=, check it first + it->second->mUserProfile->getClientOutboundFlowTuple() == terminated->getFlow()) + { + if(it->second->getClientRegistration().isValid()) + { + // ensure client registrations are notified first + dialogSetsToNotify.push_front(it->second); + } + else + { + dialogSetsToNotify.push_back(it->second); + } + } + } + // Now dispatch notification to all dialogsets found above + std::list<DialogSet*>::iterator it2 = dialogSetsToNotify.begin(); + for(; it2 != dialogSetsToNotify.end();it2++) + { + (*it2)->flowTerminated(terminated->getFlow()); + } + + DebugLog(<< "connection terminated message"); + if (mConnectionTerminatedEventDispatcher.dispatch(msg.get())) + { + msg.release(); + } + return; + } + } + + { + DumCommand* command = dynamic_cast<DumCommand*>(msg.get()); + if (command) + { + //DebugLog(<< "DumCommand" ); + command->executeCommand(); + return; + } + } + + { + ExternalMessageBase* externalMessage = dynamic_cast<ExternalMessageBase*>(msg.get()); + if (externalMessage) + { + processExternalMessage(externalMessage); + return; + } + } + + incomingProcess(msg); +} + +void +DialogUsageManager::processExternalMessage(ExternalMessageBase* externalMessage) +{ + bool handled = false; + for(std::vector<ExternalMessageHandler*>::iterator i = mExternalMessageHandlers.begin(); + i != mExternalMessageHandlers.end(); ++i) + { + (*i)->onMessage(externalMessage, handled); + if (handled) + { + break; + } + } +} + +void +DialogUsageManager::incomingProcess(std::auto_ptr<Message> msg) +{ + //call or create feature chain if appropriate + Data tid = Data::Empty; + { + SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg.get()); + if (sipMsg) + { + tid = sipMsg->getTransactionId(); + bool garbage=false; + Data reason; + + if(!sipMsg->header(h_From).isWellFormed()) + { + garbage=true; + reason.append("Malformed From, ",16); + } + + if(!sipMsg->header(h_To).isWellFormed()) + { + garbage=true; + reason.append("Malformed To, ",14); + } + + if(!sipMsg->header(h_CallId).isWellFormed()) + { + garbage=true; + reason.append("Malformed Call-Id, ",19); + } + + if(garbage) + { + if(sipMsg->isRequest() && sipMsg->method()!=ACK) + { + // .bwc. Either we need to trim the last comma off, or make this + // a proper sentence fragment. This is more fun. + reason.append("fix your code!",14); + SipMessage failure; + makeResponse(failure, *sipMsg, 400, reason); + sendResponse(failure); + } + + InfoLog (<< "Malformed header in message (" << reason << ") - rejecting/discarding: " << *sipMsg); + + // .bwc. Only forge a response when appropriate, but return in any + // case. + return; + } + } + + DumFeatureMessage* featureMsg = dynamic_cast<DumFeatureMessage*>(msg.get()); + if (featureMsg) + { + //DebugLog(<<"Got a DumFeatureMessage" << featureMsg); + tid = featureMsg->getTransactionId(); + } + } + if (tid != Data::Empty && !mIncomingFeatureList.empty()) + { + FeatureChainMap::iterator it; + //efficiently find or create FeatureChain, should prob. be a utility template + { + FeatureChainMap::iterator lb = mIncomingFeatureChainMap.lower_bound(tid); + if (lb != mIncomingFeatureChainMap.end() && !(mIncomingFeatureChainMap.key_comp()(tid, lb->first))) + { + it = lb; + } + else + { + assert(dynamic_cast<SipMessage*>(msg.get())); + it = mIncomingFeatureChainMap.insert(lb, FeatureChainMap::value_type(tid, new DumFeatureChain(*this, mIncomingFeatureList, *mIncomingTarget))); + } + } + + DumFeatureChain::ProcessingResult res = it->second->process(msg.get()); + + if (res & DumFeatureChain::ChainDoneBit) + { + delete it->second; + mIncomingFeatureChainMap.erase(it); + //DebugLog(<< "feature chain deleted" << endl); + } + + if (res & DumFeatureChain::EventTakenBit) + { + msg.release(); + //DebugLog(<< "event taken"); + return; + } + } + + try + { + InfoLog (<< "Got: " << msg->brief()); + DumDecrypted* decryptedMsg = dynamic_cast<DumDecrypted*>(msg.get()); + SipMessage* sipMsg = 0; + if (decryptedMsg) + { + sipMsg = decryptedMsg->decrypted(); + } + else + { + sipMsg = dynamic_cast<SipMessage*>(msg.get()); + } + + if (sipMsg) + { + //DebugLog ( << "DialogUsageManager::process: " << sipMsg->brief()); + if (sipMsg->isRequest()) + { + // Validate Request URI + if( !validateRequestURI(*sipMsg) ) + { + DebugLog (<< "Failed RequestURI validation " << *sipMsg); + return; + } + + // Continue validation on all requests, except ACK and CANCEL + if(sipMsg->header(h_RequestLine).method() != ACK && + sipMsg->header(h_RequestLine).method() != CANCEL) + { + if( !validateRequiredOptions(*sipMsg) ) + { + DebugLog (<< "Failed required options validation " << *sipMsg); + return; + } + if( !validate100RelSuport(*sipMsg) ) + { + DebugLog (<< "Remote party does not support 100rel " << *sipMsg); + return; + } + if( getMasterProfile()->validateContentEnabled() && !validateContent(*sipMsg) ) + { + DebugLog (<< "Failed content validation " << *sipMsg); + return; + } + if( getMasterProfile()->validateAcceptEnabled() && !validateAccept(*sipMsg) ) + { + DebugLog (<< "Failed accept validation " << *sipMsg); + return; + } + } + if (sipMsg->header(h_From).exists(p_tag)) + { + if (mergeRequest(*sipMsg) ) + { + InfoLog (<< "Merged request: " << *sipMsg); + return; + } + } + processRequest(*sipMsg); + } + else + { + processResponse(*sipMsg); + } + } + } + catch(BaseException& e) + { + //unparseable, bad 403 w/ 2543 trans it from FWD, etc + ErrLog(<<"Illegal message rejected: " << e.getMessage()); + } +} + +bool +DialogUsageManager::hasEvents() const +{ + return mFifo.messageAvailable(); +} + +// return true if there is more to do +bool +DialogUsageManager::process(resip::Lockable* mutex) +{ + if (mFifo.messageAvailable()) + { + resip::PtrLock lock(mutex); +#ifdef RESIP_DUM_THREAD_DEBUG + mThreadDebugKey=mHiddenThreadDebugKey; +#endif + internalProcess(std::auto_ptr<Message>(mFifo.getNext())); +#ifdef RESIP_DUM_THREAD_DEBUG + // .bwc. Thread checking is disabled if mThreadDebugKey is 0; if the app + // is using this mutex-locked process() call, we only enable thread- + // checking while the mutex is locked. Accesses from another thread while + // the mutex is not locked are probably intentional. However, if the app + // accesses the DUM inappropriately anyway, we'll probably detect it if + // it happens during the internalProcess() call. + mHiddenThreadDebugKey=mThreadDebugKey; + mThreadDebugKey=0; +#endif + } + return mFifo.messageAvailable(); +} + +bool +DialogUsageManager::process(int timeoutMs, resip::Lockable* mutex) +{ + std::auto_ptr<Message> message; + + if(timeoutMs == -1) + { + message.reset(mFifo.getNext()); + } + else + { + message.reset(mFifo.getNext(timeoutMs)); + } + if (message.get()) + { + resip::PtrLock lock(mutex); +#ifdef RESIP_DUM_THREAD_DEBUG + mThreadDebugKey=mHiddenThreadDebugKey; +#endif + internalProcess(message); +#ifdef RESIP_DUM_THREAD_DEBUG + // .bwc. Thread checking is disabled if mThreadDebugKey is 0; if the app + // is using this mutex-locked process() call, we only enable thread- + // checking while the mutex is locked. Accesses from another thread while + // the mutex is not locked are probably intentional. However, if the app + // accesses the DUM inappropriately anyway, we'll probably detect it if + // it happens during the internalProcess() call. + mHiddenThreadDebugKey=mThreadDebugKey; + mThreadDebugKey=0; +#endif + } + return mFifo.messageAvailable(); +} + +bool +DialogUsageManager::validateRequestURI(const SipMessage& request) +{ + // RFC3261 - 8.2.1 + if (!getMasterProfile()->isMethodSupported(request.header(h_RequestLine).getMethod())) + { + InfoLog (<< "Received an unsupported method: " << request.brief()); + + SipMessage failure; + makeResponse(failure, request, 405); + failure.header(h_Allows) = getMasterProfile()->getAllowedMethods(); + sendResponse(failure); + + if(mRequestValidationHandler) + mRequestValidationHandler->onInvalidMethod(request); + + return false; + } + + // RFC3261 - 8.2.2 + if (!getMasterProfile()->isSchemeSupported(request.header(h_RequestLine).uri().scheme())) + { + InfoLog (<< "Received an unsupported scheme: " << request.brief()); + SipMessage failure; + makeResponse(failure, request, 416); + sendResponse(failure); + + if(mRequestValidationHandler) + mRequestValidationHandler->onInvalidScheme(request); + + return false; + } + + return true; +} + + +bool +DialogUsageManager::validateRequiredOptions(const SipMessage& request) +{ + // RFC 2162 - 8.2.2 + if(request.exists(h_Requires) && // Don't check requires if method is ACK or CANCEL + (request.header(h_RequestLine).getMethod() != ACK || + request.header(h_RequestLine).getMethod() != CANCEL)) + { + Tokens unsupported = getMasterProfile()->getUnsupportedOptionsTags(request.header(h_Requires)); + if (!unsupported.empty()) + { + InfoLog (<< "Received an unsupported option tag(s): " << request.brief()); + + SipMessage failure; + makeResponse(failure, request, 420); + failure.header(h_Unsupporteds) = unsupported; + sendResponse(failure); + + if(mRequestValidationHandler) + mRequestValidationHandler->onInvalidRequiredOptions(request); + + return false; + } + } + + return true; +} + + +bool +DialogUsageManager::validate100RelSuport(const SipMessage& request) +{ + if(request.header(h_RequestLine).getMethod() == INVITE) + { + if (getMasterProfile()->getUasReliableProvisionalMode() == MasterProfile::Required) + { + if (!((request.exists(h_Requires) && request.header(h_Requires).find(Token(Symbols::C100rel))) + || (request.exists(h_Supporteds) && request.header(h_Supporteds).find(Token(Symbols::C100rel))))) + { + SipMessage failure; + makeResponse(failure, request, 421); + failure.header(h_Requires).push_back(Token(Symbols::C100rel)); + sendResponse(failure); + + if(mRequestValidationHandler) + mRequestValidationHandler->on100RelNotSupportedByRemote(request); + + return false; + } + } + } + return true; +} + +bool +DialogUsageManager::validateContent(const SipMessage& request) +{ + // RFC3261 - 8.2.3 + // Don't need to validate content headers if they are specified as optional in the content-disposition + if (!(request.exists(h_ContentDisposition) && + request.header(h_ContentDisposition).isWellFormed() && + request.header(h_ContentDisposition).exists(p_handling) && + isEqualNoCase(request.header(h_ContentDisposition).param(p_handling), Symbols::Optional))) + { + if (request.exists(h_ContentType) && !getMasterProfile()->isMimeTypeSupported(request.header(h_RequestLine).method(), request.header(h_ContentType))) + { + InfoLog (<< "Received an unsupported mime type: " << request.header(h_ContentType) << " for " << request.brief()); + + SipMessage failure; + makeResponse(failure, request, 415); + failure.header(h_Accepts) = getMasterProfile()->getSupportedMimeTypes(request.header(h_RequestLine).method()); + sendResponse(failure); + + if(mRequestValidationHandler) + mRequestValidationHandler->onInvalidContentType(request); + + return false; + } + + if (request.exists(h_ContentEncoding) && !getMasterProfile()->isContentEncodingSupported(request.header(h_ContentEncoding))) + { + InfoLog (<< "Received an unsupported mime type: " << request.header(h_ContentEncoding) << " for " << request.brief()); + SipMessage failure; + makeResponse(failure, request, 415); + failure.header(h_AcceptEncodings) = getMasterProfile()->getSupportedEncodings(); + sendResponse(failure); + + if(mRequestValidationHandler) + mRequestValidationHandler->onInvalidContentEncoding(request); + + return false; + } + + if (getMasterProfile()->validateContentLanguageEnabled() && + request.exists(h_ContentLanguages) && !getMasterProfile()->isLanguageSupported(request.header(h_ContentLanguages))) + { + InfoLog (<< "Received an unsupported language: " << request.header(h_ContentLanguages).front() << " for " << request.brief()); + + SipMessage failure; + makeResponse(failure, request, 415); + failure.header(h_AcceptLanguages) = getMasterProfile()->getSupportedLanguages(); + sendResponse(failure); + + if(mRequestValidationHandler) + mRequestValidationHandler->onInvalidContentLanguage(request); + + return false; + } + } + + return true; +} + +bool +DialogUsageManager::validateAccept(const SipMessage& request) +{ + MethodTypes method = request.header(h_RequestLine).method(); + // checks for Accept to comply with SFTF test case 216 + if(request.exists(h_Accepts)) + { + for (Mimes::const_iterator i = request.header(h_Accepts).begin(); + i != request.header(h_Accepts).end(); i++) + { + if (getMasterProfile()->isMimeTypeSupported(method, *i)) + { + return true; // Accept header passes validation if we support as least one of the mime types + } + } + } + // If no Accept header then application/sdp should be assumed for certain methods + else if(method == INVITE || + method == OPTIONS || + method == PRACK || + method == UPDATE) + { + if (getMasterProfile()->isMimeTypeSupported(request.header(h_RequestLine).method(), Mime("application", "sdp"))) + { + return true; + } + } + else + { + // Other method without an Accept Header + return true; + } + + InfoLog (<< "Received unsupported mime types in accept header: " << request.brief()); + SipMessage failure; + makeResponse(failure, request, 406); + failure.header(h_Accepts) = getMasterProfile()->getSupportedMimeTypes(method); + sendResponse(failure); + + if(mRequestValidationHandler) + mRequestValidationHandler->onInvalidAccept(request); + + return false; +} + +bool +DialogUsageManager::mergeRequest(const SipMessage& request) +{ + assert(request.isRequest()); + assert(request.isExternal()); + + if (!request.header(h_To).exists(p_tag)) + { + if (mMergedRequests.count(MergedRequestKey(request, getMasterProfile()->checkReqUriInMergeDetectionEnabled()))) + { + SipMessage failure; + makeResponse(failure, request, 482, "Merged Request"); + failure.header(h_AcceptLanguages) = getMasterProfile()->getSupportedLanguages(); + sendResponse(failure); + return true; + } + } + + return false; +} + +void +DialogUsageManager::processRequest(const SipMessage& request) +{ + DebugLog ( << "DialogUsageManager::processRequest: " << request.brief()); + + if (mShutdownState != Running && mShutdownState != ShutdownRequested) + { + WarningLog (<< "Ignoring a request since we are shutting down " << request.brief()); + + SipMessage failure; + makeResponse(failure, request, 480, "UAS is shutting down"); + sendResponse(failure); + return; + } + + if (request.header(h_RequestLine).method() == PUBLISH) + { + processPublish(request); + return; + } + + bool toTag = request.header(h_To).exists(p_tag); + if(request.header(h_RequestLine).getMethod() == REGISTER && toTag && getMasterProfile()->allowBadRegistrationEnabled()) + { + toTag = false; + } + + assert(mAppDialogSetFactory.get()); + // !jf! note, the logic was reversed during ye great merge of March of Ought 5 + if (toTag || + findDialogSet(DialogSetId(request))) + { + switch (request.header(h_RequestLine).getMethod()) + { + case REGISTER: + { + SipMessage failure; + makeResponse(failure, request, 400, "Registration requests can't have To: tags."); + failure.header(h_AcceptLanguages) = getMasterProfile()->getSupportedLanguages(); + sendResponse(failure); + break; + } + + default: + { + DialogSet* ds = findDialogSet(DialogSetId(request)); + if (ds == 0) + { + if (request.header(h_RequestLine).method() != ACK) + { + SipMessage failure; + makeResponse(failure, request, 481); + failure.header(h_AcceptLanguages) = getMasterProfile()->getSupportedLanguages(); + InfoLog (<< "Rejected request (which was in a dialog) " << request.brief()); + sendResponse(failure); + } + else + { + InfoLog (<< "ACK doesn't match any dialog" << request.brief()); + } + } + else + { + InfoLog (<< "Handling in-dialog request: " << request.brief()); + ds->dispatch(request); + } + } + } + } + else + { + switch (request.header(h_RequestLine).getMethod()) + { + case ACK: + DebugLog (<< "Discarding request: " << request.brief()); + break; + + case PRACK: + case BYE: + case UPDATE: + case INFO: // !rm! in an ideal world + { + SipMessage failure; + makeResponse(failure, request, 481); + failure.header(h_AcceptLanguages) = getMasterProfile()->getSupportedLanguages(); + sendResponse(failure); + break; + } + case CANCEL: + { + // find the appropropriate ServerInvSession + CancelMap::iterator i = mCancelMap.find(request.getTransactionId()); + if (i != mCancelMap.end()) + { + i->second->dispatch(request); + } + else + { + InfoLog (<< "Received a CANCEL on a non-existent transaction "); + SipMessage failure; + makeResponse(failure, request, 481); + sendResponse(failure); + } + break; + } + case PUBLISH: + assert(false); + return; + case SUBSCRIBE: + if (!checkEventPackage(request)) + { + InfoLog (<< "Rejecting request (unsupported package) " + << request.brief()); + return; + } + /*FALLTHRU*/ + case NOTIFY : // handle unsolicited (illegal) NOTIFYs + case INVITE: // new INVITE + case REFER: // out-of-dialog REFER + //case INFO : // handle non-dialog (illegal) INFOs + case OPTIONS : // handle non-dialog OPTIONS + case MESSAGE : + case REGISTER: + { + { + DialogSetId id(request); + //cryptographically dangerous + if(mDialogSetMap.find(id) != mDialogSetMap.end()) + { + // this can only happen if someone sends us a request with the same callid and from tag as one + // that is in the process of destroying - since this is bad endpoint behaviour - we will + // reject the request with a 400 response + SipMessage badrequest; + makeResponse(badrequest, request, 400); + badrequest.header(h_AcceptLanguages) = getMasterProfile()->getSupportedLanguages(); + sendResponse(badrequest); + return; + } + } + if (mDumShutdownHandler) + { + SipMessage forbidden; + makeResponse(forbidden, request, 480); + forbidden.header(h_AcceptLanguages) = getMasterProfile()->getSupportedLanguages(); + sendResponse(forbidden); + return; + } + try + { + DialogSet* dset = new DialogSet(request, *this); + + StackLog ( << "*********** Calling AppDialogSetFactory *************: " << dset->getId()); + AppDialogSet* appDs = mAppDialogSetFactory->createAppDialogSet(*this, request); + appDs->mDialogSet = dset; + dset->setUserProfile(appDs->selectUASUserProfile(request)); + dset->mAppDialogSet = appDs; + + StackLog ( << "************* Adding DialogSet ***************: " << dset->getId()); + //StackLog ( << "Before: " << Inserter(mDialogSetMap) ); + mDialogSetMap[dset->getId()] = dset; + StackLog ( << "DialogSetMap: " << InserterP(mDialogSetMap) ); + + dset->dispatch(request); + } + catch (BaseException& e) + { + SipMessage failure; + makeResponse(failure, request, 400, e.getMessage()); + failure.header(h_AcceptLanguages) = getMasterProfile()->getSupportedLanguages(); + sendResponse(failure); + } + + break; + } + case RESPONSE: + case SERVICE: + assert(false); + break; + case UNKNOWN: + case MAX_METHODS: + assert(false); + break; + } + } +} + +void +DialogUsageManager::processResponse(const SipMessage& response) +{ + if (response.header(h_CSeq).method() != CANCEL) + { + DialogSet* ds = findDialogSet(DialogSetId(response)); + + if (ds) + { + DebugLog ( << "DialogUsageManager::processResponse: " << std::endl << std::endl << response.brief()); + ds->dispatch(response); + } + else + { + InfoLog (<< "Throwing away stray response: " << std::endl << std::endl << response.brief()); + } + } +} + +void +DialogUsageManager::processPublish(const SipMessage& request) +{ + if (!checkEventPackage(request)) + { + InfoLog(<< "Rejecting request (unsupported package) " << request.brief()); + return; + } + + if (request.exists(h_SIPIfMatch)) + { + ServerPublications::iterator i = mServerPublications.find(request.header(h_SIPIfMatch).value()); + if (i != mServerPublications.end()) + { + i->second->dispatch(request); + } + else + { + SharedPtr<SipMessage> response(new SipMessage); + makeResponse(*response, request, 412); + send(response); + } + } + else + { + Data etag = Random::getCryptoRandomHex(8); + while (mServerPublications.find(etag) != mServerPublications.end()) + { + etag = Random::getCryptoRandomHex(8); + } + + if (request.getContents()) + { + ServerPublication* sp = new ServerPublication(*this, etag, request); + mServerPublications[etag] = sp; + sp->dispatch(request); + } + else + { + // per 3903 (sec 6.5), a PUB w/ no SIPIfMatch must have contents. .mjf. + SharedPtr<SipMessage> response(new SipMessage); + makeResponse(*response, request, 400); + send(response); + } + } +} + +bool +DialogUsageManager::checkEventPackage(const SipMessage& request) +{ + int failureCode = 0; + MethodTypes method = request.header(h_RequestLine).method(); + +// || (method == NOTIFY && !request.exists(h_SubscriptionState))) + + if (!request.exists(h_Event)) + { + InfoLog (<< "No Event header in " << request.header(h_RequestLine).unknownMethodName()); + failureCode = 400; + } + else + { + switch(method) + { + case SUBSCRIBE: + if (!getServerSubscriptionHandler(request.header(h_Event).value())) + { + InfoLog (<< "No handler for event package for SUBSCRIBE: " + << request.header(h_Event).value()); + failureCode = 489; + } + break; + case NOTIFY: + if (!getClientSubscriptionHandler(request.header(h_Event).value())) + { + InfoLog (<< "No handler for event package for NOTIFY: " + << request.header(h_Event).value()); + failureCode = 489; + } + break; + case PUBLISH: + if (!getServerPublicationHandler(request.header(h_Event).value())) + { + InfoLog (<< "No handler for event package for PUBLISH: " + << request.header(h_Event).value()); + failureCode = 489; + } + break; + default: + assert(0); + } + } + + if (failureCode > 0) + { + SharedPtr<SipMessage> response(new SipMessage); + makeResponse(*response, request, failureCode); + send(response); + return false; + } + return true; +} + +DialogSet* +DialogUsageManager::findDialogSet(const DialogSetId& id) +{ + threadCheck(); + StackLog ( << "Looking for dialogSet: " << id << " in map:"); + StackLog ( << "DialogSetMap: " << InserterP(mDialogSetMap) ); + DialogSetMap::const_iterator it = mDialogSetMap.find(id); + + if (it == mDialogSetMap.end()) + { + return 0; + } + else + { + if(it->second->isDestroying()) + { + return 0; + } + else + { + return it->second; + } + } +} + +BaseCreator* +DialogUsageManager::findCreator(const DialogId& id) +{ + DialogSet* ds = findDialogSet(id.getDialogSetId()); + if (ds) + { + return ds->getCreator(); + } + else + { + return 0; + } +} + +void +DialogUsageManager::removeDialogSet(const DialogSetId& dsId) +{ + StackLog ( << "************* Removing DialogSet ***************: " << dsId); + //StackLog ( << "Before: " << Inserter(mDialogSetMap) ); + mDialogSetMap.erase(dsId); + StackLog ( << "DialogSetMap: " << InserterP(mDialogSetMap) ); + if (mRedirectManager.get()) + { + mRedirectManager->removeDialogSet(dsId); + } +} + +ClientSubscriptionHandler* +DialogUsageManager::getClientSubscriptionHandler(const Data& eventType) +{ + map<Data, ClientSubscriptionHandler*>::iterator res = mClientSubscriptionHandlers.find(eventType); + if (res != mClientSubscriptionHandlers.end()) + { + return res->second; + } + else + { + return 0; + } +} + +ServerSubscriptionHandler* +DialogUsageManager::getServerSubscriptionHandler(const Data& eventType) +{ + map<Data, ServerSubscriptionHandler*>::iterator res = mServerSubscriptionHandlers.find(eventType); + if (res != mServerSubscriptionHandlers.end()) + { + return res->second; + } + else + { + return 0; + } +} + +ClientPublicationHandler* +DialogUsageManager::getClientPublicationHandler(const Data& eventType) +{ + map<Data, ClientPublicationHandler*>::iterator res = mClientPublicationHandlers.find(eventType); + if (res != mClientPublicationHandlers.end()) + { + return res->second; + } + else + { + return 0; + } +} + +ServerPublicationHandler* +DialogUsageManager::getServerPublicationHandler(const Data& eventType) +{ + map<Data, ServerPublicationHandler*>::iterator res = mServerPublicationHandlers.find(eventType); + if (res != mServerPublicationHandlers.end()) + { + return res->second; + } + else + { + return 0; + } +} + +OutOfDialogHandler* +DialogUsageManager::getOutOfDialogHandler(const MethodTypes type) +{ + map<MethodTypes, OutOfDialogHandler*>::iterator res = mOutOfDialogHandlers.find(type); + if (res != mOutOfDialogHandlers.end()) + { + return res->second; + } + else + { + return 0; + } +} + +void +DialogUsageManager::addIncomingFeature(resip::SharedPtr<DumFeature> feat) +{ + mIncomingFeatureList.push_back(feat); +} + +void +DialogUsageManager::addOutgoingFeature(resip::SharedPtr<DumFeature> feat) +{ + // make sure EncryptionManager is the last feature in the list. + mOutgoingFeatureList.insert(mOutgoingFeatureList.begin(), feat); +} + +void +DialogUsageManager::setOutgoingMessageInterceptor(SharedPtr<DumFeature> feat) +{ + mOutgoingMessageInterceptor = feat; +} + +void +DialogUsageManager::applyToAllServerSubscriptions(ServerSubscriptionFunctor* functor) +{ + assert(functor); + for (DialogSetMap::iterator it = mDialogSetMap.begin(); it != mDialogSetMap.end(); ++it) + { + for (DialogSet::DialogMap::iterator i = it->second->mDialogs.begin(); i != it->second->mDialogs.end(); ++i) + { + std::vector<ServerSubscriptionHandle> serverSubs = i->second->getServerSubscriptions(); + for (std::vector<ServerSubscriptionHandle>::iterator iss = serverSubs.begin(); iss != serverSubs.end(); ++iss) + { + functor->apply(*iss); + } + } + } +} + +void +DialogUsageManager::applyToAllClientSubscriptions(ClientSubscriptionFunctor* functor) +{ + assert(functor); + for (DialogSetMap::iterator it = mDialogSetMap.begin(); it != mDialogSetMap.end(); ++it) + { + for (DialogSet::DialogMap::iterator i = it->second->mDialogs.begin(); i != it->second->mDialogs.end(); ++i) + { + std::vector<ClientSubscriptionHandle> clientSubs = i->second->getClientSubscriptions(); + for (std::vector<ClientSubscriptionHandle>::iterator ics = clientSubs.begin(); ics != clientSubs.end(); ++ics) + { + functor->apply(*ics); + } + } + } +} + +void +DialogUsageManager::registerForConnectionTermination(Postable* listener) +{ + mConnectionTerminatedEventDispatcher.addListener(listener); +} + +void +DialogUsageManager::unRegisterForConnectionTermination(Postable* listener) +{ + mConnectionTerminatedEventDispatcher.removeListener(listener); +} + +void +DialogUsageManager::requestMergedRequestRemoval(const MergedRequestKey& key) +{ + DebugLog(<< "Got merged request removal request"); + MergedRequestRemovalCommand command(*this, key); + mStack.postMS(command, Timer::TF, this); +} + +void +DialogUsageManager::removeMergedRequest(const MergedRequestKey& key) +{ + DebugLog(<< "Merged request removed"); + mMergedRequests.erase(key); +} + +TargetCommand::Target& +DialogUsageManager::dumIncomingTarget() +{ + return *mIncomingTarget; +} + +TargetCommand::Target& +DialogUsageManager::dumOutgoingTarget() +{ + return *mOutgoingTarget; +} + +DialogEventStateManager* +DialogUsageManager::createDialogEventStateManager(DialogEventHandler* handler) +{ + if(handler) + { + mDialogEventStateManager = new DialogEventStateManager(); + mDialogEventStateManager->mDialogEventHandler = handler; + } + else + { + delete mDialogEventStateManager; + mDialogEventStateManager=0; + } + return mDialogEventStateManager; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DialogUsageManager.hxx b/src/libs/resiprocate/resip/dum/DialogUsageManager.hxx new file mode 100644 index 00000000..cb51445c --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DialogUsageManager.hxx @@ -0,0 +1,613 @@ +#if !defined(RESIP_DIALOGUSAGEMANAGER_HXX) +#define RESIP_DIALOGUSAGEMANAGER_HXX + +#include <vector> +#include <set> +#include <map> + +#include "resip/stack/Headers.hxx" +#include "resip/dum/EventDispatcher.hxx" +#include "resip/dum/DialogEventInfo.hxx" +#include "resip/dum/DialogSet.hxx" +#include "resip/dum/DumTimeout.hxx" +#include "resip/dum/HandleManager.hxx" +#include "resip/dum/Handles.hxx" +#include "resip/dum/MergedRequestKey.hxx" +#include "resip/dum/RegistrationPersistenceManager.hxx" +#include "resip/dum/ServerSubscription.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/SharedPtr.hxx" +#include "rutil/ThreadIf.hxx" +#include "resip/stack/SipStack.hxx" +#include "resip/stack/TransactionUser.hxx" +#include "resip/dum/DumFeature.hxx" +#include "resip/dum/DumFeatureChain.hxx" +#include "resip/dum/DumFeatureMessage.hxx" +#include "resip/dum/TargetCommand.hxx" +#include "resip/dum/ClientSubscriptionFunctor.hxx" +#include "resip/dum/ServerSubscriptionFunctor.hxx" + +namespace resip +{ + +class Security; +class SipStack; +class FdSet; +class MasterProfile; +class RedirectManager; +class ClientAuthManager; +class ServerAuthManager; +class Uri; +class Contents; + +class ClientRegistrationHandler; +class ServerRegistrationHandler; +class InviteSessionHandler; +class ClientSubscriptionHandler; +class ServerSubscriptionHandler; +class ClientPublicationHandler; +class ServerPublicationHandler; +class ClientPagerMessageHandler; +class ServerPagerMessageHandler; +class OutOfDialogHandler; +class RedirectHandler; +class DialogSetHandler; +class RequestValidationHandler; + +class Dialog; +class InviteSessionCreator; + +class AppDialogSetFactory; +class DumShutdownHandler; +class RemoteCertStore; + +class KeepAliveManager; +class HttpGetMessage; + +class ConnectionTerminated; + +class Lockable; + +class ExternalMessageBase; +class ExternalMessageHandler; + +class DialogEventStateManager; +class DialogEventHandler; + +class DialogUsageManager : public HandleManager, public TransactionUser +{ + public: + class Exception : public BaseException + { + public: + Exception(const Data& msg, + const Data& file, + int line) + : BaseException(msg, file, line) + {} + + virtual const char* name() const {return "DialogUsageManager::Exception";} + }; + + typedef enum + { + None = 0, + Sign, + Encrypt, + SignAndEncrypt + } EncryptionLevel; + + // If createDefaultFeatures is true dum will construct a + // IdentityHandler->EncryptionManager chain. + DialogUsageManager(SipStack& stack, bool createDefaultFeatures=false); + virtual ~DialogUsageManager(); + + // !bwc! Maybe add a giveUpSeconds param to these. + void shutdown(DumShutdownHandler*); + + // !bwc! This is not properly implemented (has an assert(0) in it). + // I am removing this declaration. + // void shutdownIfNoUsages(DumShutdownHandler*); + + void forceShutdown(DumShutdownHandler*); + + void addTransport( TransportType protocol, + int port=0, + IpVersion version=V4, + const Data& ipInterface = Data::Empty, + const Data& sipDomainname = Data::Empty, // only used + // for TLS + // based stuff + const Data& privateKeyPassPhrase = Data::Empty, + SecurityTypes::SSLType sslType = SecurityTypes::TLSv1, + unsigned transportFlags = 0); + + SipStack& getSipStack(); + const SipStack& getSipStack() const; + Security* getSecurity(); + + Data getHostAddress(); + + void setAppDialogSetFactory(std::auto_ptr<AppDialogSetFactory>); + + void setMasterProfile(const SharedPtr<MasterProfile>& masterProfile); + SharedPtr<MasterProfile>& getMasterProfile(); + SharedPtr<UserProfile>& getMasterUserProfile(); + + //optional handler to track the progress of DialogSets + void setDialogSetHandler(DialogSetHandler* handler); + + void setKeepAliveManager(std::auto_ptr<KeepAliveManager> keepAlive); + + //There is a default RedirectManager. Setting one may cause the old one + //to be deleted. + void setRedirectManager(std::auto_ptr<RedirectManager> redirect); + //informational, so a RedirectHandler is not required + void setRedirectHandler(RedirectHandler* handler); + RedirectHandler* getRedirectHandler(); + + /// If there is no ClientAuthManager, when the client receives a 401/407, + /// pass it up through the normal BaseUsageHandler + void setClientAuthManager(std::auto_ptr<ClientAuthManager> client); + + /// If there is no ServerAuthManager, the server does not authenticate requests + void setServerAuthManager(resip::SharedPtr<ServerAuthManager> server); + + /// If there is no such handler, calling makeInviteSession will throw and + /// receiving an INVITE as a UAS will respond with 405 Method Not Allowed. + void setInviteSessionHandler(InviteSessionHandler*); + + /// If there is no such handler, calling makeRegistration will throw + void setClientRegistrationHandler(ClientRegistrationHandler*); + + /// If no such handler, UAS will respond to REGISTER with 405 Method Not Allowed + void setServerRegistrationHandler(ServerRegistrationHandler*); + + /// If there is no such handler, calling makeSubscription will throw + void addClientSubscriptionHandler(const Data& eventType, ClientSubscriptionHandler*); + + /// If there is no such handler, calling makePublication will throw + void addClientPublicationHandler(const Data& eventType, ClientPublicationHandler*); + + void addServerSubscriptionHandler(const Data& eventType, ServerSubscriptionHandler*); + void addServerPublicationHandler(const Data& eventType, ServerPublicationHandler*); + + void addOutOfDialogHandler(MethodTypes, OutOfDialogHandler*); + + void setRequestValidationHandler(RequestValidationHandler*); + + void setClientPagerMessageHandler(ClientPagerMessageHandler*); + void setServerPagerMessageHandler(ServerPagerMessageHandler*); + + /// Add/Remove External Message Handler + /// do following op when processing thread in not running + void addExternalMessageHandler(ExternalMessageHandler* handler); + void removeExternalMessageHandler(ExternalMessageHandler* handler); + void clearExternalMessageHandler(); + + /// Sets a manager to handle storage of registration state + void setRegistrationPersistenceManager(RegistrationPersistenceManager*); + + void setRemoteCertStore(std::auto_ptr<RemoteCertStore> store); + + // The message is owned by the underlying datastructure and may go away in + // the future. If the caller wants to keep it, it should make a copy. The + // memory will exist at least up until the point where the application + // calls DialogUsageManager::send(msg); + SharedPtr<SipMessage> makeInviteSession(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const Contents* initialOffer, AppDialogSet* ads = 0); + SharedPtr<SipMessage> makeInviteSession(const NameAddr& target, const Contents* initialOffer, AppDialogSet* ads = 0); + SharedPtr<SipMessage> makeInviteSession(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const Contents* initialOffer, EncryptionLevel level, const Contents* alternative = 0, AppDialogSet* ads = 0); + SharedPtr<SipMessage> makeInviteSession(const NameAddr& target, const Contents* initialOffer, EncryptionLevel level, const Contents* alternative = 0, AppDialogSet* ads = 0); + // Versions that add a replaces header + SharedPtr<SipMessage> makeInviteSession(const NameAddr& target, InviteSessionHandle sessionToReplace, const SharedPtr<UserProfile>& userProfile, const Contents* initialOffer, AppDialogSet* ads = 0); + SharedPtr<SipMessage> makeInviteSession(const NameAddr& target, InviteSessionHandle sessionToReplace, const SharedPtr<UserProfile>& userProfile, const Contents* initialOffer, EncryptionLevel level = None, const Contents* alternative = 0, AppDialogSet* ads = 0); + SharedPtr<SipMessage> makeInviteSession(const NameAddr& target, InviteSessionHandle sessionToReplace, const Contents* initialOffer, EncryptionLevel level = None, const Contents* alternative = 0, AppDialogSet* ads = 0); + + //will send a Notify(100)...currently can be decorated through the + //OnReadyToSend callback. Probably will change it's own callback/handler soon + SharedPtr<SipMessage> makeInviteSessionFromRefer(const SipMessage& refer, ServerSubscriptionHandle, + const Contents* initialOffer, AppDialogSet* = 0); + SharedPtr<SipMessage> makeInviteSessionFromRefer(const SipMessage& refer, const SharedPtr<UserProfile>& userProfile, + const Contents* initialOffer, AppDialogSet* appDs = 0); + SharedPtr<SipMessage> makeInviteSessionFromRefer(const SipMessage& refer, ServerSubscriptionHandle, + const Contents* initialOffer, EncryptionLevel level = None, const Contents* alternative = 0, AppDialogSet* = 0); + SharedPtr<SipMessage> makeInviteSessionFromRefer(const SipMessage& refer, const SharedPtr<UserProfile>& userProfile, ServerSubscriptionHandle, + const Contents* initialOffer, EncryptionLevel level = None, const Contents* alternative = 0, AppDialogSet* = 0); + + SharedPtr<SipMessage> makeSubscription(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const Data& eventType, AppDialogSet* = 0); + SharedPtr<SipMessage> makeSubscription(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const Data& eventType, + UInt32 subscriptionTime, AppDialogSet* = 0); + SharedPtr<SipMessage> makeSubscription(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const Data& eventType, + UInt32 subscriptionTime, int refreshInterval, AppDialogSet* = 0); + SharedPtr<SipMessage> makeSubscription(const NameAddr& target, const Data& eventType, AppDialogSet* = 0); + SharedPtr<SipMessage> makeSubscription(const NameAddr& target, const Data& eventType, UInt32 subscriptionTime, AppDialogSet* = 0); + SharedPtr<SipMessage> makeSubscription(const NameAddr& target, const Data& eventType, + UInt32 subscriptionTime, int refreshInterval, AppDialogSet* = 0); + + //unsolicited refer + SharedPtr<SipMessage> makeRefer(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const H_ReferTo::Type& referTo, AppDialogSet* = 0); + SharedPtr<SipMessage> makeRefer(const NameAddr& target, const H_ReferTo::Type& referTo, AppDialogSet* = 0); + + SharedPtr<SipMessage> makePublication(const NameAddr& target, + const SharedPtr<UserProfile>& userProfile, + const Contents& body, + const Data& eventType, + UInt32 expiresSeconds, + AppDialogSet* = 0); + SharedPtr<SipMessage> makePublication(const NameAddr& target, + const Contents& body, + const Data& eventType, + UInt32 expiresSeconds, + AppDialogSet* = 0); + + SharedPtr<SipMessage> makeRegistration(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, AppDialogSet* = 0); + SharedPtr<SipMessage> makeRegistration(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, UInt32 registrationTime, AppDialogSet* = 0); + SharedPtr<SipMessage> makeRegistration(const NameAddr& target, AppDialogSet* = 0); + SharedPtr<SipMessage> makeRegistration(const NameAddr& target, UInt32 registrationTime, AppDialogSet* = 0); + + SharedPtr<SipMessage> makeOutOfDialogRequest(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, const MethodTypes meth, AppDialogSet* = 0); + SharedPtr<SipMessage> makeOutOfDialogRequest(const NameAddr& target, const MethodTypes meth, AppDialogSet* = 0); + + ClientPagerMessageHandle makePagerMessage(const NameAddr& target, const SharedPtr<UserProfile>& userProfile, AppDialogSet* = 0); + ClientPagerMessageHandle makePagerMessage(const NameAddr& target, AppDialogSet* = 0); + + void end(DialogSetId invSessionId); + void send(SharedPtr<SipMessage> request); + void sendCommand(SharedPtr<SipMessage> request); + + class SendCommand : public DumCommandAdapter + { + public: + SendCommand(SharedPtr<SipMessage> request, + DialogUsageManager& dum): + mRequest(request), + mDum(dum) + {} + + virtual ~SendCommand(){} + + virtual void executeCommand() + { + mDum.send(mRequest); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "DialogUsageManager::SendCommand" << std::endl; + } + + protected: + SharedPtr<SipMessage> mRequest; + DialogUsageManager& mDum; + }; + + //void send(SipMessage& request, EncryptionLevel level); + + // give dum an opportunity to handle its events. If process() returns true + // there are more events to process. + bool hasEvents() const; + bool process(Lockable* mutex = NULL); // non-blocking + bool process(int timeoutMs, Lockable* mutex = NULL); // Specify -1 for infinte timeout + + AppDialogHandle findAppDialog(const DialogId& id); + AppDialogSetHandle findAppDialogSet(const DialogSetId& id); + + InviteSessionHandle findInviteSession(DialogId id); + //if the handle is inValid, int represents the errorcode + std::pair<InviteSessionHandle, int> findInviteSession(CallId replaces); + + ClientPublicationHandler* getClientPublicationHandler(const Data& eventType); + ServerPublicationHandler* getServerPublicationHandler(const Data& eventType); + + ClientSubscriptionHandler* getClientSubscriptionHandler(const Data& eventType); + ServerSubscriptionHandler* getServerSubscriptionHandler(const Data& eventType); + + // will apply the specified functor(which takes a + //ServerSubscriptionHandle) to each matching ServerSubscription. + //Returns the functor after the last application. + template<typename UnaryFunction> + UnaryFunction applyToServerSubscriptions(const Data& aor, + const Data& eventType, + UnaryFunction applyFn) + { + Data key = eventType + aor; + std::pair<ServerSubscriptions::iterator,ServerSubscriptions::iterator> + range = mServerSubscriptions.equal_range(key); + + for (ServerSubscriptions::iterator i=range.first; i!=range.second; ++i) + { + ServerSubscriptionHandle h = i->second->getHandle(); + applyFn(h); + } + return applyFn; + } + + //DUM will delete features in its destructor. Feature manipulation should + //be done before any processing starts. + //ServerAuthManager is now a DumFeature; setServerAuthManager is a special + //case of addFeature; the ServerAuthManager should always be the first + //feature in the chain. + void addIncomingFeature(resip::SharedPtr<DumFeature> feat); + void addOutgoingFeature(resip::SharedPtr<DumFeature> feat); + + void setOutgoingMessageInterceptor(resip::SharedPtr<DumFeature> feat); + + TargetCommand::Target& dumIncomingTarget(); + + TargetCommand::Target& dumOutgoingTarget(); + + //exposed so DumThread variants can be written + Message* getNext(int ms) { return mFifo.getNext(ms); } + void internalProcess(std::auto_ptr<Message> msg); + bool messageAvailable(void) { return mFifo.messageAvailable(); } + + void applyToAllClientSubscriptions(ClientSubscriptionFunctor*); + void applyToAllServerSubscriptions(ServerSubscriptionFunctor*); + + /// Note: Implementations of Postable must delete the message passed via post + void registerForConnectionTermination(Postable*); + void unRegisterForConnectionTermination(Postable*); + + // The DialogEventStateManager is returned so that the client can query it for + // the current set of active dialogs (useful when accepting a dialog event subscription). + // The caller is responsible for deleting the DialogEventStateManager + // at the same time it deletes other handlers when DUM is destroyed. + DialogEventStateManager* createDialogEventStateManager(DialogEventHandler* handler); + + protected: + virtual void onAllHandlesDestroyed(); + //TransactionUser virtuals + virtual const Data& name() const; + friend class DumThread; + + DumFeatureChain::FeatureList mIncomingFeatureList; + DumFeatureChain::FeatureList mOutgoingFeatureList; + + SharedPtr<DumFeature> mOutgoingMessageInterceptor; + + typedef std::map<Data, DumFeatureChain*> FeatureChainMap; + FeatureChainMap mIncomingFeatureChainMap; + FeatureChainMap mOutgoingFeatureChainMap; + + private: + friend class Dialog; + friend class DialogSet; + + friend class ClientInviteSession; + friend class ClientOutOfDialogReq; + friend class ClientPublication; + friend class ClientRegistration; + friend class ClientSubscription; + friend class InviteSession; + friend class ServerInviteSession; + friend class ServerOutOfDialogReq; + friend class ServerPublication; + friend class ServerRegistration; + friend class ServerSubscription; + friend class BaseUsage; + friend class ClientPagerMessage; + friend class ServerPagerMessage; + friend class KeepAliveAssociation; + friend class NetworkAssociation; + + friend class MergedRequestRemovalCommand; + friend class TargetCommand::Target; + + class IncomingTarget : public TargetCommand::Target + { + public: + IncomingTarget(DialogUsageManager& dum) : TargetCommand::Target(dum) + { + } + + virtual void post(std::auto_ptr<Message> msg) + { + mDum.incomingProcess(msg); + } + }; + + class OutgoingTarget : public TargetCommand::Target + { + public: + OutgoingTarget(DialogUsageManager& dum) : TargetCommand::Target(dum) + { + } + + virtual void post(std::auto_ptr<Message> msg) + { + mDum.outgoingProcess(msg); + } + }; + + DialogSet* makeUacDialogSet(BaseCreator* creator, AppDialogSet* appDs); + SharedPtr<SipMessage> makeNewSession(BaseCreator* creator, AppDialogSet* appDs); + + // makes a proto response to a request + void makeResponse(SipMessage& response, + const SipMessage& request, + int responseCode, + const Data& reason = Data::Empty) const; + // May call a callback to let the app adorn + void sendResponse(const SipMessage& response); + + void sendUsingOutboundIfAppropriate(UserProfile& userProfile, std::auto_ptr<SipMessage> msg); + + void addTimer(DumTimeout::Type type, + unsigned long durationSeconds, + BaseUsageHandle target, + unsigned int seq, + unsigned int altseq=0); + + void addTimerMs(DumTimeout::Type type, + unsigned long duration, + BaseUsageHandle target, + unsigned int seq, + unsigned int altseq=0, + const Data &transactionId = Data::Empty); + + Dialog& findOrCreateDialog(const SipMessage* msg); + Dialog* findDialog(const DialogId& id); + DialogSet* findDialogSet(const DialogSetId& id); + + // return 0, if no matching BaseCreator + BaseCreator* findCreator(const DialogId& id); + + void processRequest(const SipMessage& request); + void processResponse(const SipMessage& response); + bool validateRequestURI(const SipMessage& request); + bool validateRequiredOptions(const SipMessage& request); + bool validateContent(const SipMessage& request); + bool validateAccept(const SipMessage& request); + bool validateTo(const SipMessage& request); + bool validate100RelSuport(const SipMessage& request); + + bool mergeRequest(const SipMessage& request); + + void processPublish(const SipMessage& publish); + + void removeDialogSet(const DialogSetId& ); + + bool checkEventPackage(const SipMessage& request); + + bool queueForIdentityCheck(SipMessage* msg); + void processIdentityCheckResponse(const HttpGetMessage& msg); + + void incomingProcess(std::auto_ptr<Message> msg); + void outgoingProcess(std::auto_ptr<Message> msg); + void processExternalMessage(ExternalMessageBase* externalMessage); + + // For delayed delete of a Usage + void destroy(const BaseUsage* usage); + void destroy(DialogSet*); + void destroy(Dialog*); + + void requestMergedRequestRemoval(const MergedRequestKey&); + void removeMergedRequest(const MergedRequestKey&); + + typedef std::set<MergedRequestKey> MergedRequests; + MergedRequests mMergedRequests; + + typedef std::map<Data, DialogSet*> CancelMap; + CancelMap mCancelMap; + + typedef HashMap<DialogSetId, DialogSet*> DialogSetMap; + DialogSetMap mDialogSetMap; + + SharedPtr<MasterProfile> mMasterProfile; + SharedPtr<UserProfile> mMasterUserProfile; + std::auto_ptr<RedirectManager> mRedirectManager; + std::auto_ptr<ClientAuthManager> mClientAuthManager; + //std::auto_ptr<ServerAuthManager> mServerAuthManager; + + InviteSessionHandler* mInviteSessionHandler; + ClientRegistrationHandler* mClientRegistrationHandler; + ServerRegistrationHandler* mServerRegistrationHandler; + RedirectHandler* mRedirectHandler; + DialogSetHandler* mDialogSetHandler; + RequestValidationHandler* mRequestValidationHandler; + + RegistrationPersistenceManager *mRegistrationPersistenceManager; + + OutOfDialogHandler* getOutOfDialogHandler(const MethodTypes type); + + std::map<Data, ClientSubscriptionHandler*> mClientSubscriptionHandlers; + std::map<Data, ServerSubscriptionHandler*> mServerSubscriptionHandlers; + std::map<Data, ClientPublicationHandler*> mClientPublicationHandlers; + std::map<Data, ServerPublicationHandler*> mServerPublicationHandlers; + std::map<MethodTypes, OutOfDialogHandler*> mOutOfDialogHandlers; + std::auto_ptr<KeepAliveManager> mKeepAliveManager; + bool mIsDefaultServerReferHandler; + + ClientPagerMessageHandler* mClientPagerMessageHandler; + ServerPagerMessageHandler* mServerPagerMessageHandler; + std::vector<ExternalMessageHandler*> mExternalMessageHandlers; + + // a pointer because we'll only initialize if we add a + // server subscription handler for the 'dialog' event... + DialogEventStateManager* mDialogEventStateManager; + + std::auto_ptr<AppDialogSetFactory> mAppDialogSetFactory; + + SipStack& mStack; + DumShutdownHandler* mDumShutdownHandler; + typedef enum + { + Running, + ShutdownRequested, // while ending usages + RemovingTransactionUser, // while removing TU from stack + Shutdown, // after TU has been removed from stack + Destroying // while calling destructor + } ShutdownState; + ShutdownState mShutdownState; + + // from ETag -> ServerPublication + typedef std::map<Data, ServerPublication*> ServerPublications; + ServerPublications mServerPublications; + typedef std::map<Data, SipMessage*> RequiresCerts; + RequiresCerts mRequiresCerts; + // from Event-Type+document-aor -> ServerSubscription + // Managed by ServerSubscription + typedef std::multimap<Data, ServerSubscription*> ServerSubscriptions; + ServerSubscriptions mServerSubscriptions; + + IncomingTarget* mIncomingTarget; + OutgoingTarget* mOutgoingTarget; + ThreadIf::TlsKey mThreadDebugKey; + ThreadIf::TlsKey mHiddenThreadDebugKey; + + EventDispatcher<ConnectionTerminated> mConnectionTerminatedEventDispatcher; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/Doxyfile b/src/libs/resiprocate/resip/dum/Doxyfile new file mode 100644 index 00000000..534a4c86 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Doxyfile @@ -0,0 +1,1124 @@ +# Doxyfile 1.3.6-20040307 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Resiprocate/DialogUsageManager + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with English messages), Korean, Korean-en, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is used +# as the annotated text. Otherwise, the brief description is used as-is. If left +# blank, the following values are used ("$name" is automatically replaced with the +# name of the entity): "The $name class" "The $name widget" "The $name file" +# "is" "provides" "specifies" "contains" "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = test + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superseded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = NO + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/src/libs/resiprocate/resip/dum/DumCommand.hxx b/src/libs/resiprocate/resip/dum/DumCommand.hxx new file mode 100644 index 00000000..21c137e8 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumCommand.hxx @@ -0,0 +1,35 @@ +#if !defined(RESIP_DUMCOMMAND_HXX) +#define RESIP_DUMCOMMAND_HXX + +#include "resip/stack/ApplicationMessage.hxx" + +namespace resip +{ + +class DumCommand : public ApplicationMessage +{ + public: + virtual ~DumCommand() {} + virtual void executeCommand() = 0; +}; + +class DumCommandAdapter : public DumCommand +{ +public: + virtual ~DumCommandAdapter() {} + + virtual Message* clone() const + { + assert(false); + return NULL; + } + + virtual EncodeStream& encode(EncodeStream& strm) const + { + return encodeBrief(strm); + } +}; +} + +#endif + diff --git a/src/libs/resiprocate/resip/dum/DumDecrypted.cxx b/src/libs/resiprocate/resip/dum/DumDecrypted.cxx new file mode 100644 index 00000000..70127c20 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumDecrypted.cxx @@ -0,0 +1,100 @@ +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/DumDecrypted.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +DumDecrypted::DumDecrypted(const SipMessage& msg) + : mDecrypted(msg) +{ +} + +DumDecrypted::DumDecrypted(const DumDecrypted& src) + : mDecrypted(src.mDecrypted) +{ +} + +DumDecrypted::~DumDecrypted() +{ +} + +Message* +DumDecrypted::clone() const +{ + return new DumDecrypted(*this); +} + +const SipMessage& +DumDecrypted::decrypted() const +{ + return mDecrypted; +} + +SipMessage* +DumDecrypted::decrypted() +{ + return &mDecrypted; +} + +EncodeStream& +DumDecrypted::encodeBrief(EncodeStream& strm) const +{ + return encode(strm); +} + +EncodeStream& +DumDecrypted::encode(EncodeStream& strm) const +{ + return mDecrypted.encode(strm); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DumDecrypted.hxx b/src/libs/resiprocate/resip/dum/DumDecrypted.hxx new file mode 100644 index 00000000..98507ba6 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumDecrypted.hxx @@ -0,0 +1,79 @@ +#if !defined(RESIP_DUMDECRYPTED_HXX) +#define RESIP_DUMDECRYPTED_HXX + +#include "resip/stack/ApplicationMessage.hxx" +#include "resip/stack/SipMessage.hxx" + +namespace resip +{ + +class DumDecrypted : public Message +{ + public: + DumDecrypted(const SipMessage& msg); + DumDecrypted(const DumDecrypted&); + ~DumDecrypted(); + + SipMessage* decrypted(); + const SipMessage& decrypted() const; + Message* clone() const; + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + SipMessage mDecrypted; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DumException.hxx b/src/libs/resiprocate/resip/dum/DumException.hxx new file mode 100644 index 00000000..fa42bd6b --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumException.hxx @@ -0,0 +1,70 @@ +#if !defined(RESIP_DUMEXCEPTION_HXX) +#define RESIP__DUMEXCEPTION_HXX + +#include "rutil/BaseException.hxx" + +namespace resip +{ + +class DumException : public BaseException +{ + public: + DumException(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) {} + const char* name() const { return "DumException"; } +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/dum/DumFeature.cxx b/src/libs/resiprocate/resip/dum/DumFeature.cxx new file mode 100644 index 00000000..162be72a --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumFeature.cxx @@ -0,0 +1,22 @@ +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/stack/Message.hxx" +#include "resip/dum/DumFeature.hxx" +#include "resip/dum/TargetCommand.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + + +DumFeature::DumFeature(DialogUsageManager& dum, TargetCommand::Target& target) + : mDum(dum), mTarget(target) +{ +} + +DumFeature::~DumFeature() +{ +} + +void DumFeature::postCommand(std::auto_ptr<Message> message) +{ + mDum.post(new TargetCommand(mTarget, message)); +} diff --git a/src/libs/resiprocate/resip/dum/DumFeature.hxx b/src/libs/resiprocate/resip/dum/DumFeature.hxx new file mode 100644 index 00000000..00f5d5a6 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumFeature.hxx @@ -0,0 +1,52 @@ +#ifndef RESIP_DumFeature_HXX +#define RESIP_DumFeature_HXX + +#include <memory> +#include "resip/dum/TargetCommand.hxx" + +namespace resip +{ + +class DialogUsageManager; +class Message; + +class DumFeature +{ + public: + DumFeature(DialogUsageManager& dum, TargetCommand::Target& target); + virtual ~DumFeature(); + + enum ProcessingResultMask + { + EventDoneBit = 1 << 0, + EventTakenBit = 1 << 1, + FeatureDoneBit = 1 << 2, + ChainDoneBit = 1 << 3 + }; + + //legal combinations + enum ProcessingResult + { + EventTaken = EventTakenBit, + FeatureDone = FeatureDoneBit, + FeatureDoneAndEventDone = FeatureDoneBit | EventDoneBit, + FeatureDoneAndEventTaken = FeatureDoneBit | EventTakenBit, + ChainDoneAndEventDone = ChainDoneBit | EventDoneBit, + ChainDoneAndEventTaken = ChainDoneBit | EventTakenBit + }; + + // !bwc! We absolutely, positively, MUST NOT throw here. This is because + // in DialogUsageManager::process(), we do not know if a DumFeature has + // taken ownership of msg until we get a return. If we throw, the + // ownership of msg is unknown. This is unacceptable. + virtual ProcessingResult process(Message* msg) = 0; + virtual void postCommand(std::auto_ptr<Message> message); + + protected: + DialogUsageManager& mDum; + TargetCommand::Target& mTarget; +}; + +} + +#endif diff --git a/src/libs/resiprocate/resip/dum/DumFeatureChain.cxx b/src/libs/resiprocate/resip/dum/DumFeatureChain.cxx new file mode 100644 index 00000000..b53c36cf --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumFeatureChain.cxx @@ -0,0 +1,96 @@ +#include <vector> + +#include "rutil/SharedPtr.hxx" +#include "resip/dum/TargetCommand.hxx" +#include "resip/dum/DumFeature.hxx" +#include "resip/dum/DumFeatureChain.hxx" +#include "resip/stack/Message.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +class GuardFeature : public DumFeature +{ + public: + GuardFeature(DialogUsageManager& dum, TargetCommand::Target& target) + : DumFeature(dum, target) + {} + + virtual ProcessingResult process(Message* msg) + { + return DumFeature::FeatureDone; + } +}; + +DumFeatureChain::DumFeatureChain(DialogUsageManager& dum, + const FeatureList& features, + TargetCommand::Target& target) + :mFeatures(features) +{ + mFeatures.push_back(SharedPtr<DumFeature>(new GuardFeature(dum, target))); + for (FeatureList::size_type i = 0; i < mFeatures.size(); ++i) + { + mActiveFeatures.push_back(true); + } +} + +DumFeatureChain::ProcessingResult DumFeatureChain::process(Message* msg) +{ + FeatureList::iterator feat = mFeatures.begin(); + vector<bool>::iterator active = mActiveFeatures.begin(); + bool stop = false; + + DumFeature::ProcessingResult pres = DumFeature::FeatureDone; + do + { + if (*active) + { + pres = (*feat)->process(msg); + + switch(pres) + { + case DumFeature::EventTaken: + stop = true; + break; + case DumFeature::FeatureDone: + *active = false; + break; + case DumFeature::FeatureDoneAndEventDone: + case DumFeature::FeatureDoneAndEventTaken: //?? + case DumFeature::ChainDoneAndEventTaken: + case DumFeature::ChainDoneAndEventDone: + *active = false; + stop = true; + break; + } + + if (pres & DumFeature::EventDoneBit) + { + delete msg; + int bits = pres; + bits ^= DumFeature::EventDoneBit; + bits |= DumFeature::EventTaken; + pres = static_cast<DumFeature::ProcessingResult>(bits); + } + } + + active++; + feat++; + } + while(!stop && feat != mFeatures.end()); + + + int chainBits = 0; + if (pres & DumFeature::ChainDoneBit || feat == mFeatures.end()) + { + chainBits |= ChainDoneBit; + } + + if (pres & DumFeature::EventTakenBit) + { + chainBits |= EventTakenBit; + } + + return static_cast<DumFeatureChain::ProcessingResult>(chainBits); +} diff --git a/src/libs/resiprocate/resip/dum/DumFeatureChain.hxx b/src/libs/resiprocate/resip/dum/DumFeatureChain.hxx new file mode 100644 index 00000000..6a498ab0 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumFeatureChain.hxx @@ -0,0 +1,45 @@ +#ifndef RESIP_DumFeatureChain_HXX +#define RESIP_DumFeatureChain_HXX + +#include <vector> +#include "rutil/SharedPtr.hxx" + +namespace resip +{ + +class DumFeature; + +class DumFeatureChain +{ + public: + typedef std::vector<SharedPtr<DumFeature> > FeatureList; + + enum ProcessingResultMask + { + EventTakenBit = 1 << 0, //don't pass on, don't delete event + ChainDoneBit = 1 << 1 //if true chain can be deleted + }; + + //legal combinations + enum ProcessingResult + { + EventTaken = EventTakenBit, //don't delete event + ChainDone = ChainDoneBit, //event not consumed by chain + ChainDoneAndEventTaken = ChainDoneBit | EventTakenBit + }; + + DumFeatureChain(DialogUsageManager& dum, const FeatureList& features, TargetCommand::Target& target); + + ProcessingResult process(Message* msg); + + private: + // std::bit_vector mActiveFeatures; //vector<bool> is the correct way on most platforms + std::vector<bool> mActiveFeatures; + FeatureList mFeatures; +}; + +} + +#endif + + diff --git a/src/libs/resiprocate/resip/dum/DumFeatureMessage.cxx b/src/libs/resiprocate/resip/dum/DumFeatureMessage.cxx new file mode 100644 index 00000000..3a0d7c11 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumFeatureMessage.cxx @@ -0,0 +1,36 @@ +#include <cassert> +#include "DumFeatureMessage.hxx" +#include "rutil/WinLeakCheck.hxx" +#include "resip/dum/BaseUsage.hxx" + +using namespace resip; + +DumFeatureMessage::DumFeatureMessage(const Data& tid) + : mTransactionId(tid) +{} + +DumFeatureMessage::DumFeatureMessage(const DumFeatureMessage& source) + : mTransactionId(source.mTransactionId) +{} + +DumFeatureMessage::~DumFeatureMessage() +{} + +Message* +DumFeatureMessage::clone() const +{ + return new DumFeatureMessage(*this); +} + +EncodeStream& +DumFeatureMessage::encodeBrief(EncodeStream& strm) const +{ + return encode(strm); +} + +EncodeStream& +DumFeatureMessage::encode(EncodeStream& strm) const +{ + strm << "DumFeatureMessage::" << mTransactionId; + return strm; +} diff --git a/src/libs/resiprocate/resip/dum/DumFeatureMessage.hxx b/src/libs/resiprocate/resip/dum/DumFeatureMessage.hxx new file mode 100644 index 00000000..be649ca9 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumFeatureMessage.hxx @@ -0,0 +1,33 @@ +#if !defined(RESIP_DumFeatureMessage_hxx) +#define RESIP_DumFeatureMessage_hxx + +#include <iosfwd> +#include "resip/stack/ApplicationMessage.hxx" + +namespace resip +{ + +//!dcm! -- what is the intent of ApplicationMessage, especially as used in +//repro? Is this really what ApplicationMessage should be(always has tid) + +class DumFeatureMessage : public ApplicationMessage +{ + public: + DumFeatureMessage(const Data& tid); + DumFeatureMessage(const DumFeatureMessage&); + ~DumFeatureMessage(); + + Message* clone() const; + + virtual EncodeStream& encode(EncodeStream& strm) const; + /// output a brief description to stream + virtual EncodeStream& encodeBrief(EncodeStream& str) const; + + virtual const Data& getTransactionId() const { return mTransactionId; } + private: + Data mTransactionId; +}; + +} + +#endif diff --git a/src/libs/resiprocate/resip/dum/DumHelper.cxx b/src/libs/resiprocate/resip/dum/DumHelper.cxx new file mode 100644 index 00000000..1926abdc --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumHelper.cxx @@ -0,0 +1,98 @@ +#include "resip/dum/DumHelper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +void DumHelper::setOutgoingEncryptionLevel(SipMessage& message, + DialogUsageManager::EncryptionLevel level) +{ + SecurityAttributes* attr = new SecurityAttributes(); + attr->setOutgoingEncryptionLevel(convert(level)); + message.setSecurityAttributes(auto_ptr<SecurityAttributes>(attr)); +} + +void DumHelper::setEncryptionPerformed(SipMessage& message) +{ + SecurityAttributes* attr = new SecurityAttributes(); + attr->setOutgoingEncryptionLevel(message.getSecurityAttributes()->getOutgoingEncryptionLevel()); + attr->setEncryptionPerformed(true); + message.setSecurityAttributes(auto_ptr<SecurityAttributes>(attr)); +} + +SecurityAttributes::OutgoingEncryptionLevel DumHelper::convert(DialogUsageManager::EncryptionLevel level) +{ + SecurityAttributes::OutgoingEncryptionLevel ret = SecurityAttributes::None; + + switch(level) + { + case DialogUsageManager::None: + ret = SecurityAttributes::None; + break; + case DialogUsageManager::Encrypt: + ret = SecurityAttributes::Encrypt; + break; + case DialogUsageManager::Sign: + ret = SecurityAttributes::Sign; + break; + case DialogUsageManager::SignAndEncrypt: + ret = SecurityAttributes::SignAndEncrypt; + break; + } + + return ret; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DumHelper.hxx b/src/libs/resiprocate/resip/dum/DumHelper.hxx new file mode 100644 index 00000000..80668c18 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumHelper.hxx @@ -0,0 +1,76 @@ +#if !defined(RESIP_DUMHELPER_HXX) +#define RESIP_DUMHELPER_HXX + +#include "rutil/BaseException.hxx" +#include "resip/stack/SecurityAttributes.hxx" +#include "resip/dum/DialogUsageManager.hxx" + +namespace resip +{ + +class SipMessage; +class SecurityAttributes; + +class DumHelper +{ + public: + static void setOutgoingEncryptionLevel(SipMessage& message, DialogUsageManager::EncryptionLevel level); + static void setEncryptionPerformed(SipMessage& message); + + private: + static SecurityAttributes::OutgoingEncryptionLevel convert(DialogUsageManager::EncryptionLevel level); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DumProcessHandler.cxx b/src/libs/resiprocate/resip/dum/DumProcessHandler.cxx new file mode 100644 index 00000000..11ec9f11 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumProcessHandler.cxx @@ -0,0 +1,138 @@ +#include "resip/stack/SipStack.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/DumProcessHandler.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +namespace resip { + +DumProcessHandler::DumProcessHandler(ExternalTimer* et) : + mHaveActiveTimer(false), + mDum(0), + mExternalTimer(et), + mStopped(false), + mCurrentlyProcessing(false) +{ +} + +void +DumProcessHandler::start(DialogUsageManager* dum) +{ + mDum = dum; + mExternalTimer->setHandler(this); + mTimerID = mExternalTimer->generateAsyncID(); +} + +void +DumProcessHandler::handleProcessNotification() +{ +#if 0 // !dcm! this needs to be fixed in the new model + //only works when there is exactly one thread causing notifications; could be + //made thread safecancelled + if (!mCurrentlyProcessing && !mStopped) + { + mCurrentlyProcessing = true; + //very temporary + //FD_ISSET ?? + FdSet fds; + mDum->buildFdSet(fds); + if (fds.size > 0) + { + fds.selectMilliSeconds((long)0); + } + + int timeTillProcess = 0; + do + { + mDum->process(fds); + timeTillProcess = mDum->getTimeTillNextProcessMS(); + } + while (timeTillProcess == 0); + if (timeTillProcess != INT_MAX) + { + if (mHaveActiveTimer) + { + mExternalTimer->deleteTimer(mTimerID); + } + assert(timeTillProcess < 60*4*60*1000); //4hr sanity check + mTimerID = mExternalTimer->generateAsyncID(); + DebugLog ( << "Setting dum process timer: " << timeTillProcess); + mExternalTimer->createTimer(mTimerID, timeTillProcess); + mHaveActiveTimer = true; + } + mCurrentlyProcessing = false; + } +#endif +} + +void +DumProcessHandler::handleTimeout(AsyncID timerID) +{ + assert(timerID == mTimerID); + mHaveActiveTimer = false; + handleProcessNotification(); +} + + +void +DumProcessHandler::stop() +{ + mStopped = true; + if (mHaveActiveTimer) + { + mExternalTimer->deleteTimer(mTimerID); + } +} + +} // namespace resip + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DumProcessHandler.hxx b/src/libs/resiprocate/resip/dum/DumProcessHandler.hxx new file mode 100644 index 00000000..c7041d39 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumProcessHandler.hxx @@ -0,0 +1,85 @@ +#if !defined(RESIP_DUM_PROCESS_HANDLER_HXX) +#define RESIP_DUM_PROCESS_HANDLER_HXX + +#include "rutil/AsyncProcessHandler.hxx" +#include "resip/dum/ExternalTimer.hxx" + + +namespace resip +{ + +class DialogUsageManager; + + +class DumProcessHandler : public AsyncProcessHandler, public ExternalTimerHandler +{ + public: + DumProcessHandler(ExternalTimer*); + virtual void handleProcessNotification(); + virtual void handleTimeout(AsyncID timerID); + + //would put in constructor, but things are circular + void start(DialogUsageManager*); + void stop();//!dcm! -- temporary + private: + bool mHaveActiveTimer; + AsyncID mTimerID; + DialogUsageManager* mDum; + ExternalTimer* mExternalTimer; + bool mStopped; + bool mCurrentlyProcessing; +}; + +} // namespace resip + +#endif // !RESIP_DUM_PROCESS_HANDLER_HXX + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DumShutdownHandler.hxx b/src/libs/resiprocate/resip/dum/DumShutdownHandler.hxx new file mode 100644 index 00000000..712091be --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumShutdownHandler.hxx @@ -0,0 +1,67 @@ +#if !defined(RESIP_DUMSHUTDOWNHANDLER_HXX) +#define RESIP_DUMSHUTDOWNHANDLER_HXX + +namespace resip +{ + +class DumShutdownHandler +{ + public: + virtual ~DumShutdownHandler() {} + virtual void onDumCanBeDeleted()=0; +}; + +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DumThread.cxx b/src/libs/resiprocate/resip/dum/DumThread.cxx new file mode 100644 index 00000000..343202db --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumThread.cxx @@ -0,0 +1,82 @@ +#include "resip/dum/DumThread.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +DumThread::DumThread(DialogUsageManager& dum) + : mDum(dum) +{ +} + +void +DumThread::thread() +{ + while (!isShutdown()) + { + try + { + std::auto_ptr<Message> msg(mDum.mFifo.getNext(1000)); // Only need to wake up to see if we are shutdown + if (msg.get()) + { + mDum.internalProcess(msg); + } + } + catch (BaseException& e) + { + WarningLog (<< "Unhandled exception: " << e); + } + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DumThread.hxx b/src/libs/resiprocate/resip/dum/DumThread.hxx new file mode 100644 index 00000000..a7747d04 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumThread.hxx @@ -0,0 +1,74 @@ +#ifndef RESIP_DumThread__hxx +#define RESIP_DumThread__hxx + +#include "rutil/ThreadIf.hxx" + +namespace resip +{ + +class DialogUsageManager; + +class DumThread : public ThreadIf +{ + public: + DumThread(DialogUsageManager& dum); + virtual void thread(); + + private: + DialogUsageManager& mDum; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DumTimeout.cxx b/src/libs/resiprocate/resip/dum/DumTimeout.cxx new file mode 100644 index 00000000..dc3a11a4 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumTimeout.cxx @@ -0,0 +1,207 @@ +#include <cassert> +#include "DumTimeout.hxx" +#include "rutil/WinLeakCheck.hxx" +#include "resip/dum/BaseUsage.hxx" + +using namespace resip; + +DumTimeout::DumTimeout(Type type, + unsigned long duration, + BaseUsageHandle targetBu, + unsigned int seq, + unsigned int altSeq, + const Data &transactionId) + : mType(type), + mDuration(duration), + mUsageHandle(targetBu), + mSeq(seq), + mSecondarySeq(altSeq), + mTransactionId(transactionId) +{} + +DumTimeout::DumTimeout(const DumTimeout& source) + : mType(source.mType), + mDuration(source.mDuration), + mUsageHandle(source.mUsageHandle), + mSeq(source.mSeq), + mSecondarySeq(source.mSecondarySeq), + mTransactionId(source.mTransactionId) +{} + +DumTimeout::~DumTimeout() +{} + +Message* +DumTimeout::clone() const +{ + return new DumTimeout(*this); +} + +DumTimeout::Type +DumTimeout::type() const +{ + return mType; +} + +unsigned int +DumTimeout::seq() const +{ + return mSeq; +} + +unsigned int +DumTimeout::secondarySeq() const +{ + return mSecondarySeq; +} + +const Data & DumTimeout::transactionId() const +{ + return mTransactionId; +} + +bool +DumTimeout::isClientTransaction() const +{ + assert(0); + return false; +} + +EncodeStream& +DumTimeout::encodeBrief(EncodeStream& strm) const +{ + return encode(strm); +} + +EncodeStream& +DumTimeout::encode(EncodeStream& strm) const +{ + strm << "DumTimeout::"; + switch (mType) + { + case SessionExpiration: + strm <<"SessionExpiration"; + break; + case SessionRefresh: + strm <<"SessionRefresh"; + break; + case Registration: + strm <<"Registration"; + break; + case RegistrationRetry: + strm <<"RegistrationRetry"; + break; + case Publication: + strm <<"Publication"; + break; + case Retransmit200: + strm <<"Retransmit200"; + break; + case Retransmit1xx: + strm <<"Retransmit1xx"; + break; + case WaitForAck: + strm <<"WaitForAck"; + break; + case CanDiscardAck: + strm <<"CanDiscardAck"; + break; + case StaleCall: + strm <<"StaleCall"; + break; + case Subscription: + strm <<"Subscription"; + break; + case SubscriptionRetry: + strm <<"SubscriptionRetry"; + break; + case WaitForNotify: + strm <<"WaitForNotify"; + break; + case StaleReInvite: + strm <<"StaleReInvite"; + break; + case Glare: + strm <<"Glare"; + break; + case Cancelled: + strm <<"Cancelled"; + break; + case WaitingForForked2xx: + strm <<"WaitingForForked2xx"; + break; + case SendNextNotify: + strm <<"SendNextNotify"; + break; + } + // Accessing mUsageHandle is not threadsafe, and this encode method is used outside + // the dum thread, in the stack thread via the TuSelector::add method for logging. + //if (mUsageHandle.isValid()) + //{ + // strm << " " << *mUsageHandle; + //} + //else + //{ + // strm << " defunct"; + //} + + strm << ": duration=" << mDuration << " seq=" << mSeq; + return strm; +} + +BaseUsageHandle +DumTimeout::getBaseUsage() const +{ + return mUsageHandle; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/DumTimeout.hxx b/src/libs/resiprocate/resip/dum/DumTimeout.hxx new file mode 100644 index 00000000..4f68cb48 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/DumTimeout.hxx @@ -0,0 +1,121 @@ +#if !defined(RESIP_DUMTIMER_HXX) +#define RESIP_DUMTIMER_HXX + +#include <iosfwd> +#include "resip/stack/ApplicationMessage.hxx" +#include "resip/dum/Handles.hxx" + +namespace resip +{ + +class DumTimeout : public ApplicationMessage +{ + public: + typedef enum + { + SessionExpiration, + SessionRefresh, + Registration, + RegistrationRetry, + Publication, + Retransmit200, + Retransmit1xx, + WaitForAck, // UAS gets no ACK + CanDiscardAck, + StaleCall, // UAC gets no final response + Subscription, + SubscriptionRetry, + WaitForNotify, + StaleReInvite, + Glare, + Cancelled, + WaitingForForked2xx, + SendNextNotify + } Type; + static const unsigned long StaleCallTimeout; + + DumTimeout(Type type, + unsigned long duration, + BaseUsageHandle target, + unsigned int seq, + unsigned int aseq = 0, + const Data &transactionId = Data::Empty); + DumTimeout(const DumTimeout&); + ~DumTimeout(); + + Message* clone() const; + + Type type() const; + unsigned int seq() const; + unsigned int secondarySeq() const; + const Data & transactionId() const; + + BaseUsageHandle getBaseUsage() const; + + virtual bool isClientTransaction() const; + + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + Type mType; + unsigned long mDuration; + BaseUsageHandle mUsageHandle; + unsigned int mSeq; + unsigned int mSecondarySeq; + Data mTransactionId; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/EncryptionRequest.cxx b/src/libs/resiprocate/resip/dum/EncryptionRequest.cxx new file mode 100644 index 00000000..c22b5281 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/EncryptionRequest.cxx @@ -0,0 +1,103 @@ +#include "resip/dum/EncryptionRequest.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +EncryptionRequest::EncryptionRequest(const SipMessage& msg, DialogUsageManager::EncryptionLevel level) + : mMessage(msg), + mLevel(level) +{ +} + +EncryptionRequest::EncryptionRequest(const EncryptionRequest& from) + : mMessage(from.mMessage), + mLevel(from.mLevel) +{ +} + +EncryptionRequest::~EncryptionRequest() +{ +} + +Message* +EncryptionRequest::clone() const +{ + return new EncryptionRequest(*this); +} + +SipMessage& +EncryptionRequest::message() +{ + return mMessage; +} + +DialogUsageManager::EncryptionLevel +EncryptionRequest::encryptionLevel() const +{ + return mLevel; +} + +EncodeStream& +EncryptionRequest::encodeBrief(EncodeStream& strm) const +{ + return encode(strm); +} + +EncodeStream& +EncryptionRequest::encode(EncodeStream& strm) const +{ + mMessage.encode(strm); + strm << "Encryption level: " << mLevel << endl; + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/EncryptionRequest.hxx b/src/libs/resiprocate/resip/dum/EncryptionRequest.hxx new file mode 100644 index 00000000..200c5d6f --- /dev/null +++ b/src/libs/resiprocate/resip/dum/EncryptionRequest.hxx @@ -0,0 +1,82 @@ +#if !defined(RESIP_ENCRYPTIONREQUEST_HXX) +#define RESIP_ENCRYPTIONREQUEST_HXX + +#include "resip/stack/Message.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/DialogUsageManager.hxx" + +namespace resip +{ + +class EncryptionRequest : public Message +{ + public: + EncryptionRequest(const SipMessage& msg, DialogUsageManager::EncryptionLevel level); + EncryptionRequest(const EncryptionRequest&); + ~EncryptionRequest(); + + SipMessage& message(); + DialogUsageManager::EncryptionLevel encryptionLevel() const; + + virtual Message* clone() const; + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + SipMessage mMessage; + DialogUsageManager::EncryptionLevel mLevel; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/EventDispatcher.hxx b/src/libs/resiprocate/resip/dum/EventDispatcher.hxx new file mode 100644 index 00000000..76b25b0f --- /dev/null +++ b/src/libs/resiprocate/resip/dum/EventDispatcher.hxx @@ -0,0 +1,144 @@ +#ifndef RESIP_EventDispatcher_hxx +#define RESIP_EventDispatcher_hxx + +#include <vector> + +#include "resip/dum/DumCommand.hxx" +#include "resip/dum/Postable.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/Lock.hxx" + +namespace resip +{ + +template<class E> +class EventDispatcher +{ + public: + EventDispatcher() + { + } + + bool dispatch(Message* msg) + { + Lock lock(mMutex); + bool ret = false; + + E* event = dynamic_cast<E*>(msg); + if (event) + { + if(mListeners.size() > 0) + { + ret = true; + unsigned int counter = 1; + for (std::vector<Postable*>::iterator it = mListeners.begin(); it != mListeners.end(); ++it) + { + if (counter == mListeners.size()) + { + (*it)->post(msg); + } + else + { + ++counter; + (*it)->post(msg->clone()); + } + } + } + } + + return ret; + } + + void addListener(Postable* listener) + { + Lock lock(mMutex); + std::vector<Postable*>::iterator it = find(listener); + if (it == mListeners.end()) + { + mListeners.push_back(listener); + } + } + + void removeListener(Postable* listener) + { + Lock lock(mMutex); + std::vector<Postable*>::iterator it = find(listener); + if (it != mListeners.end()) + { + mListeners.erase(it); + } + } + + private: + std::vector<Postable*> mListeners; + Mutex mMutex; + + std::vector<Postable*>::iterator find(Postable* listener) + { + std::vector<Postable*>::iterator it; + for (it = mListeners.begin(); it != mListeners.end(); ++it) + { + if (listener == *it) + { + break; + } + } + return it; + } +}; + +} + + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ExternalMessageBase.hxx b/src/libs/resiprocate/resip/dum/ExternalMessageBase.hxx new file mode 100644 index 00000000..a635be1e --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ExternalMessageBase.hxx @@ -0,0 +1,68 @@ +#ifndef RESIP_ExternalMessageBase_hxx +#define RESIP_ExternalMessageBase_hxx + +#include "resip/stack/Message.hxx" + +namespace resip +{ + class ExternalMessageBase : public Message + { + public: + ExternalMessageBase() {} + + virtual Message* clone() const=0; + virtual std::ostream& encode(std::ostream& strm) const = 0; + virtual std::ostream& encodeBrief(std::ostream& strm) const = 0; + }; +} + +#endif +/* ==================================================================== +* The Vovida Software License, Version 1.0 +* +* Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. The names "VOCAL", "Vovida Open Communication Application Library", +* and "Vovida Open Communication Application Library (VOCAL)" must +* not be used to endorse or promote products derived from this +* software without prior written permission. For written +* permission, please contact vocal@vovida.org. +* +* 4. Products derived from this software may not be called "VOCAL", nor +* may "VOCAL" appear in their name, without prior written +* permission of Vovida Networks, Inc. +* +* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +* +* ==================================================================== +* +* This software consists of voluntary contributions made by Vovida +* Networks, Inc. and many individuals on behalf of Vovida Networks, +* Inc. For more information on Vovida Networks, Inc., please see +* <http://www.vovida.org/>. +* +*/ diff --git a/src/libs/resiprocate/resip/dum/ExternalMessageHandler.hxx b/src/libs/resiprocate/resip/dum/ExternalMessageHandler.hxx new file mode 100644 index 00000000..dea84ff0 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ExternalMessageHandler.hxx @@ -0,0 +1,68 @@ +#if !defined(RESIP_EXTERNALMESSAGEHANDLER_HXX) +#define RESIP_EXTERNALMESSAGEHANDLER_HXX + +namespace resip +{ +class ExternalMessageBase; +class ExternalMessageHandler +{ + public: + virtual ~ExternalMessageHandler() + { + }; + + virtual void onMessage(ExternalMessageBase* externalMessage, bool& handled)=0; +}; +} + +#endif + +/* ==================================================================== +* The Vovida Software License, Version 1.0 +* +* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. The names "VOCAL", "Vovida Open Communication Application Library", +* and "Vovida Open Communication Application Library (VOCAL)" must +* not be used to endorse or promote products derived from this +* software without prior written permission. For written +* permission, please contact vocal@vovida.org. +* +* 4. Products derived from this software may not be called "VOCAL", nor +* may "VOCAL" appear in their name, without prior written +* permission of Vovida Networks, Inc. +* +* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +* +* ==================================================================== +* +* This software consists of voluntary contributions made by Vovida +* Networks, Inc. and many individuals on behalf of Vovida Networks, +* Inc. For more information on Vovida Networks, Inc., please see +* <http://www.vovida.org/>. +* +*/ diff --git a/src/libs/resiprocate/resip/dum/ExternalTimer.hxx b/src/libs/resiprocate/resip/dum/ExternalTimer.hxx new file mode 100644 index 00000000..642a5fc9 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ExternalTimer.hxx @@ -0,0 +1,82 @@ +#if !defined(RESIP_EXTERNAL_TIMER_HXX) +#define RESIP_EXTERNAL_TIMER_HXX + +#include "rutil/AsyncID.hxx" + +namespace resip +{ + +class ExternalTimerHandler +{ + public: + virtual ~ExternalTimerHandler() {} + virtual void handleTimeout(AsyncID timerID)=0; +}; + +//used by the asynchronous executive +class ExternalTimer +{ + public: + virtual ~ExternalTimer() {} + + virtual AsyncID generateAsyncID()=0; + virtual void setHandler(ExternalTimerHandler* handler)=0; + + virtual void createTimer(AsyncID timerID, unsigned long ms)=0; + virtual void createRecurringTimer(AsyncID timerID, unsigned long every_ms)=0; + virtual void deleteTimer(AsyncID timerID)=0; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/Handle.cxx b/src/libs/resiprocate/resip/dum/Handle.cxx new file mode 100644 index 00000000..17cb3e0d --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Handle.cxx @@ -0,0 +1,50 @@ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/Handle.hxx b/src/libs/resiprocate/resip/dum/Handle.hxx new file mode 100644 index 00000000..5ae74899 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Handle.hxx @@ -0,0 +1,164 @@ +#if !defined(RESIP_HANDLE_HXX) +#define RESIP_HANDLE_HXX + +#include <iosfwd> +#include <cassert> +#include "resip/dum/Handled.hxx" +#include "resip/dum/HandleManager.hxx" +#include "resip/dum/HandleException.hxx" + +namespace resip +{ + +template <class T> +class Handle +{ + public: + Handle(HandleManager& ham, Handled::Id id) : mHam(&ham), mId(id) + { + } + + Handle() : mHam(0), mId(0) + { + } + + bool isValid() const + { + if (!mHam) + { + return false; + } + else + { + return mHam->isValidHandle(mId); + } + } + + // throws if not found + T* get() + { + if (!mHam) + { + //assert(0); + throw HandleException("Reference to unitialized handle.", __FILE__, __LINE__); + } + return static_cast<T*>(mHam->getHandled(mId)); + } + + const T* get() const + { + if (!mHam) + { + //assert(0); + throw HandleException("Reference to unitialized handle.", __FILE__, __LINE__); + } + return static_cast<T*>(mHam->getHandled(mId)); + } + + T* operator->() + { + return get(); + } + + const T* operator->() const + { + return get(); + } + + T& operator*() + { + return *get(); + } + + const T& operator*() const + { + return *get(); + } + + + Handled::Id getId() const + { + return mId; + } + + static Handle<T> NotValid() + { + static Handle<T> notValid; + return notValid; + } + + bool operator==(const Handle<T>& other) + { + return (mHam == other.mHam) && (mId == other.mId); + } + + // !nash! to be able to use Handle in Set or Map container + bool operator<(const Handle<T>& other) const + { + assert(mHam); + assert(other.mHam); + return mId < other.mId; + } + + private: + HandleManager* mHam; + + protected: + Handled::Id mId; + + friend class Handled; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/HandleException.cxx b/src/libs/resiprocate/resip/dum/HandleException.cxx new file mode 100644 index 00000000..e627ee64 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/HandleException.cxx @@ -0,0 +1,65 @@ +#include "resip/dum/HandleException.hxx" + +using namespace resip; + +HandleException::HandleException(const Data& msg,const Data& file,int line) + : BaseException(msg, file, line) +{ +} + +const char* +HandleException::name() const +{ + return "HandleException"; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/HandleException.hxx b/src/libs/resiprocate/resip/dum/HandleException.hxx new file mode 100644 index 00000000..94030770 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/HandleException.hxx @@ -0,0 +1,68 @@ +#if !defined(RESIP_HANDLEEXCEPTION_HXX) +#define RESIP_HANDLEEXCEPTION_HXX + +#include "rutil/BaseException.hxx" + +namespace resip +{ + +class HandleException : public BaseException +{ + public: + HandleException(const Data& msg, const Data& file, int line); + virtual const char* name() const; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/HandleManager.cxx b/src/libs/resiprocate/resip/dum/HandleManager.cxx new file mode 100644 index 00000000..c20ebf51 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/HandleManager.cxx @@ -0,0 +1,221 @@ +#include <cassert> +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" +#include "resip/dum/HandleManager.hxx" +#include "resip/dum/HandleException.hxx" + +using namespace resip; +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +HandleManager::HandleManager() : + mShuttingDown(false), + mLastId(Handled::npos) +{ +} + +HandleManager::~HandleManager() +{ + // !jf! do nothing? + // !dcm! -- this is the best we can do w/out a back-ptr to each handle + // DUM currently cleans up properly, so not an issue unless users make their + // own handled objects, could clean up memeory, but the app will crash first + // handle deference regardless. + if (!mHandleMap.empty()) + { + DebugLog ( << "&&&&&& HandleManager::~HandleManager: Deleting handlemanager that still has Handled objects: " ); + DebugLog ( << InserterP(mHandleMap)); + //throw HandleException("Deleting handlemanager that still has Handled objects", __FILE__, __LINE__); + } +} + +Handled::Id +HandleManager::create(Handled* handled) +{ + mHandleMap[++mLastId] = handled; + return mLastId; +} + +void HandleManager::shutdownWhenEmpty() +{ + mShuttingDown = true; + if (mHandleMap.empty()) + { + onAllHandlesDestroyed(); + } + else + { + DebugLog (<< "Shutdown waiting for all usages to be deleted (" << mHandleMap.size() << ")"); +#if 1 + for (HandleMap::iterator i=mHandleMap.begin() ; i != mHandleMap.end(); ++i) + { + DebugLog (<< i->first << " -> " << *(i->second)); + } +#endif + } +} + +#if 0 +// !jf! this will leak if there are active usages +void HandleManager::onAllHandlesDestroyed() +{ + WarningLog(<< "Forcing shutdown " << mHandleMap.size() << " active usages"); + for (HandleMap::const_iterator i = mHandleMap.begin(); + i != mHandleMap.end(); ++i) + { + InfoLog(<< "Handled left at force shutdown: " << *i->second); + } + mHandleMap.clear(); +} +#endif + +void +HandleManager::remove(Handled::Id id) +{ + HandleMap::iterator i = mHandleMap.find(id); + assert (i != mHandleMap.end()); + mHandleMap.erase(i); + if (mShuttingDown) + { + if(mHandleMap.empty()) + { + onAllHandlesDestroyed(); + } + else + { + DebugLog (<< "Waiting for usages to be deleted (" << mHandleMap.size() << ")"); + } + } +} + +void +HandleManager::dumpHandles() const +{ + DebugLog (<< "Waiting for usages to be deleted (" << mHandleMap.size() << ")"); + for (HandleMap::const_iterator i=mHandleMap.begin() ; i != mHandleMap.end(); ++i) + { + DebugLog (<< i->first << " -> " << *(i->second)); + } +} + +bool +HandleManager::isValidHandle(Handled::Id id) const +{ + return mHandleMap.find(id) != mHandleMap.end(); +} + +Handled* +HandleManager::getHandled(Handled::Id id) const +{ + HandleMap::const_iterator i = mHandleMap.find(id); + if (i == mHandleMap.end()) + { + InfoLog (<< "Reference to stale handle: " << id); + assert(0); + throw HandleException("Stale handle", __FILE__, __LINE__); + } + else + { + assert(i->second); + return i->second; + } +} + + +/* ==================================================================== + + * The Vovida Software License, Version 1.0 + + * + + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + + * + + * Redistribution and use in source and binary forms, with or without + + * modification, are permitted provided that the following conditions + + * are met: + + * + + * 1. Redistributions of source code must retain the above copyright + + * notice, this list of conditions and the following disclaimer. + + * + + * 2. Redistributions in binary form must reproduce the above copyright + + * notice, this list of conditions and the following disclaimer in + + * the documentation and/or other materials provided with the + + * distribution. + + * + + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + + * and "Vovida Open Communication Application Library (VOCAL)" must + + * not be used to endorse or promote products derived from this + + * software without prior written permission. For written + + * permission, please contact vocal@vovida.org. + + * + + * 4. Products derived from this software may not be called "VOCAL", nor + + * may "VOCAL" appear in their name, without prior written + + * permission of Vovida Networks, Inc. + + * + + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + + * DAMAGE. + + * + + * ==================================================================== + + * + + * This software consists of voluntary contributions made by Vovida + + * Networks, Inc. and many individuals on behalf of Vovida Networks, + + * Inc. For more information on Vovida Networks, Inc., please see + + * <http://www.vovida.org/>. + + * + + */ + diff --git a/src/libs/resiprocate/resip/dum/HandleManager.hxx b/src/libs/resiprocate/resip/dum/HandleManager.hxx new file mode 100644 index 00000000..c6a93e01 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/HandleManager.hxx @@ -0,0 +1,99 @@ +#if !defined(RESIP_HandleManager_HXX) +#define RESIP_HandleManager_HXX + +#include "rutil/HashMap.hxx" +#include "resip/dum/Handled.hxx" + +namespace resip +{ + + + +class HandleManager +{ + public: + HandleManager(); + virtual ~HandleManager(); + + bool isValidHandle(Handled::Id) const; + Handled* getHandled(Handled::Id) const; + + virtual void shutdownWhenEmpty(); + //subclasses(for now DUM) overload this method to handle shutdown + protected: + virtual void onAllHandlesDestroyed()=0; + virtual void dumpHandles() const; + + //private: + friend class Handled; + + Handled::Id create(Handled* handled); + void remove(Handled::Id id); + + typedef HashMap<Handled::Id, Handled*> HandleMap; + HandleMap mHandleMap; + bool mShuttingDown; + Handled::Id mLastId; + + public: + /// Returns the number of handles in use. + HandleMap::size_type handleCount(void) const + { + return mHandleMap.size(); + } + +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/Handled.cxx b/src/libs/resiprocate/resip/dum/Handled.cxx new file mode 100644 index 00000000..5a3bae00 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Handled.cxx @@ -0,0 +1,83 @@ +#include "resip/dum/HandleManager.hxx" +#include "resip/dum/Handled.hxx" +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + + +using namespace resip; + +Handled::Handled(HandleManager& ham) : + mHam(ham), + mId(Handled::npos) +{ + mId = mHam.create(this); + StackLog ( << "&&&&&& Handled::Handled " << mId << " this(" << this << ") " << &ham ); +} + +Handled::~Handled() +{ + if (mId != Handled::npos) + { + StackLog ( << "&&&&&& ~Handled " << mId << " this(" << this << ") " << &mHam ); + mHam.remove(mId); + } +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const Handled& handled) +{ + return handled.dump(strm); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/Handled.hxx b/src/libs/resiprocate/resip/dum/Handled.hxx new file mode 100644 index 00000000..8f3f3d7a --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Handled.hxx @@ -0,0 +1,83 @@ +#if !defined(RESIP_HANDLED_HXX) +#define RESIP_HANDLED_HXX + +#include <iosfwd> + +#include "rutil/resipfaststreams.hxx" + +namespace resip +{ +class HandleManager; + +class Handled +{ + public: + typedef unsigned long Id; // make this a UInt64, fix the hash + enum { npos = 0 }; + + Handled(HandleManager& ham); + virtual ~Handled(); + + virtual EncodeStream& dump(EncodeStream& strm) const=0; + + protected: + HandleManager& mHam; + Handled::Id mId; +}; + +EncodeStream& +operator<<(EncodeStream& strm, const Handled& usage); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/Handles.hxx b/src/libs/resiprocate/resip/dum/Handles.hxx new file mode 100644 index 00000000..138c51a0 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Handles.hxx @@ -0,0 +1,97 @@ +#if !defined(RESIP_Handles_hxx) +#define RESIP_Handles_hxx + +#include "resip/dum/Handle.hxx" + +namespace resip +{ + +class AppDialogSet; +class AppDialog; + +class ClientInviteSession; +class ClientOutOfDialogReq; +class ClientPublication; +class ClientRegistration; +class ClientSubscription; +class ClientPagerMessage; +class ServerPagerMessage; +class InviteSession; +class ServerInviteSession; +class ServerOutOfDialogReq; +class ServerPublication; +class ServerRegistration; +class ServerSubscription; +class BaseUsage; + +typedef Handle<AppDialogSet> AppDialogSetHandle; +typedef Handle<AppDialog> AppDialogHandle; +typedef Handle<BaseUsage> BaseUsageHandle; +typedef Handle<ClientOutOfDialogReq> ClientOutOfDialogReqHandle; +typedef Handle<ClientPublication> ClientPublicationHandle; +typedef Handle<ClientRegistration> ClientRegistrationHandle; +typedef Handle<ClientSubscription> ClientSubscriptionHandle; +typedef Handle<ClientPagerMessage> ClientPagerMessageHandle; +typedef Handle<ServerPagerMessage> ServerPagerMessageHandle; +typedef Handle<ClientInviteSession> ClientInviteSessionHandle; +typedef Handle<ServerInviteSession> ServerInviteSessionHandle; +typedef Handle<InviteSession> InviteSessionHandle; +typedef Handle<ServerOutOfDialogReq> ServerOutOfDialogReqHandle; +typedef Handle<ServerPublication> ServerPublicationHandle; +typedef Handle<ServerRegistration> ServerRegistrationHandle; +typedef Handle<ServerSubscription> ServerSubscriptionHandle; + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/HttpGetMessage.cxx b/src/libs/resiprocate/resip/dum/HttpGetMessage.cxx new file mode 100644 index 00000000..35fba8f7 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/HttpGetMessage.cxx @@ -0,0 +1,84 @@ +#include "resip/dum/HttpGetMessage.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + + +HttpGetMessage::HttpGetMessage(const Data& tid, + bool success, + const Data& body, + const Mime& type) : + DumFeatureMessage(tid), + mSuccess(success), + mBody(body), + mType(type) +{ +} + +EncodeStream& +HttpGetMessage::encodeBrief(EncodeStream& str) const +{ + return str << "HttpGetMessage: " << getTransactionId() << " " << mType; +} + +EncodeStream& +HttpGetMessage::encode(EncodeStream& strm) const +{ + return strm << brief() << "body: " << mBody; +} + +Message* +HttpGetMessage::clone() const +{ + return new HttpGetMessage(getTransactionId(), mSuccess, mBody, mType); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/HttpGetMessage.hxx b/src/libs/resiprocate/resip/dum/HttpGetMessage.hxx new file mode 100644 index 00000000..bb2380a1 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/HttpGetMessage.hxx @@ -0,0 +1,78 @@ +#ifndef RESIP_HttpGetMessage_hxx +#define RESIP_HttpGetMessage_hxx + +#include "resip/dum/DumFeatureMessage.hxx" +#include "resip/stack/Mime.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +class HttpGetMessage : public DumFeatureMessage +{ + public: + HttpGetMessage(const Data& tid, bool success, const Data& x509, const Mime& type); + + bool success() const { return mSuccess; } + const Data& getBodyData() const { return mBody; } + const Mime& getType() const {return mType;} + + virtual Message* clone() const; + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& strm) const; + private: + bool mSuccess; + Data mBody; + Mime mType; +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/HttpProvider.cxx b/src/libs/resiprocate/resip/dum/HttpProvider.cxx new file mode 100644 index 00000000..7b7aa751 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/HttpProvider.cxx @@ -0,0 +1,81 @@ +#include "HttpProvider.hxx" +#include "rutil/Lock.hxx" + +using namespace resip; + +HttpProvider* HttpProvider::mInstance = 0; +std::auto_ptr<HttpProviderFactory> HttpProvider::mFactory; +Mutex HttpProvider::mMutex; + +void +HttpProvider::setFactory(std::auto_ptr<HttpProviderFactory> fact) +{ + mFactory = fact; +} + +HttpProvider* +HttpProvider::instance() +{ + if (mFactory.get() && mInstance == 0) + { + Lock lock(mMutex); + if (mInstance == 0) + { + mInstance = mFactory.get()->createHttpProvider(); + } + } + return mInstance; +} + + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/HttpProvider.hxx b/src/libs/resiprocate/resip/dum/HttpProvider.hxx new file mode 100644 index 00000000..b2ef4fe9 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/HttpProvider.hxx @@ -0,0 +1,95 @@ +#ifndef RESIP_HttpProvider +#define RESIP_HttpProvider + +#include "rutil/Mutex.hxx" +#include "resip/dum/TargetCommand.hxx" +#include <memory> + +namespace resip +{ +class TransactionUser; +class Data; +class GenericUri; +class TargetCommand; + +//To provide this functionality, plug in an instance of +//HttpProviderFactory(before any instances of DialogUsageManager/SipStack are +//created. Null will be returned by default. +class HttpProviderFactory; + +class HttpProvider +{ + public: + //HttpProvider assumes memory + static void setFactory(std::auto_ptr<HttpProviderFactory> fact); + //ptr so users can check for existence + static HttpProvider* instance(); + + //.dcm. tu param will become a postable + virtual void get(const GenericUri& target, const Data& tid, TransactionUser& tu, TargetCommand::Target& commandTarget)=0; + virtual ~HttpProvider(){} //impl. singleton destructor pattern later + private: + static HttpProvider* mInstance; + static std::auto_ptr<HttpProviderFactory> mFactory; + static Mutex mMutex; +}; + +class HttpProviderFactory +{ + public: + virtual HttpProvider* createHttpProvider()=0; + virtual ~HttpProviderFactory(){} +}; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/IdentityHandler.cxx b/src/libs/resiprocate/resip/dum/IdentityHandler.cxx new file mode 100644 index 00000000..19d06b17 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/IdentityHandler.cxx @@ -0,0 +1,121 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "rutil/Logger.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/IdentityHandler.hxx" +#include "resip/dum/HttpProvider.hxx" +#include "resip/dum/HttpGetMessage.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "rutil/WinLeakCheck.hxx" + +#ifdef USE_SSL +#include "resip/stack/ssl/Security.hxx" +#endif + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +IdentityHandler::IdentityHandler(DialogUsageManager& dum, TargetCommand::Target& target) + : DumFeature(dum, target) +{ +} + +IdentityHandler::~IdentityHandler() +{ + for (RequiresCerts::iterator it = mRequiresCerts.begin(); it != mRequiresCerts.end(); ++it) + { + delete it->second; + } +} + +DumFeature::ProcessingResult +IdentityHandler::process(Message* msg) +{ + SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg); + if (sipMsg) + { + if (queueForIdentityCheck(sipMsg)) + { + return EventTaken; + } + else + { + return FeatureDone; + } + } + + HttpGetMessage* httpMsg = dynamic_cast<HttpGetMessage*>(msg); + if (httpMsg) + { + processIdentityCheckResponse(*httpMsg); + return FeatureDoneAndEventDone; + } + + return FeatureDone; +} + +bool +IdentityHandler::queueForIdentityCheck(SipMessage* sipMsg) +{ +#if defined(USE_SSL) + if (sipMsg->exists(h_Identity) && + sipMsg->exists(h_IdentityInfo) && + sipMsg->exists(h_Date)) + { + if (mDum.getSecurity()->hasDomainCert(sipMsg->header(h_From).uri().host())) + { + mDum.getSecurity()->checkAndSetIdentity(*sipMsg); + return false; + } + else + { + if (!HttpProvider::instance()) + { + return false; + } + + try + { + mRequiresCerts[sipMsg->getTransactionId()] = sipMsg; + InfoLog( << "Dum::queueForIdentityCheck, sending http request to: " + << sipMsg->header(h_IdentityInfo)); + + HttpProvider::instance()->get(sipMsg->header(h_IdentityInfo), + sipMsg->getTransactionId(), + mDum, + mDum.dumIncomingTarget()); + return true; + } + catch (BaseException&) + { + } + } + } +#endif + + std::auto_ptr<SecurityAttributes> sec(new SecurityAttributes); + sec->setIdentity(sipMsg->header(h_From).uri().getAor()); + sec->setIdentityStrength(SecurityAttributes::From); + sipMsg->setSecurityAttributes(sec); + return false; +} + +void +IdentityHandler::processIdentityCheckResponse(const HttpGetMessage& msg) +{ +#if defined(USE_SSL) + InfoLog(<< "DialogUsageManager::processIdentityCheckResponse: " << msg.brief()); + RequiresCerts::iterator it = mRequiresCerts.find(msg.getTransactionId()); + if (it != mRequiresCerts.end()) + { + mDum.getSecurity()->checkAndSetIdentity( *it->second, msg.getBodyData() ); + postCommand(auto_ptr<Message>(it->second)); + mRequiresCerts.erase(it); + } +#endif +} diff --git a/src/libs/resiprocate/resip/dum/IdentityHandler.hxx b/src/libs/resiprocate/resip/dum/IdentityHandler.hxx new file mode 100644 index 00000000..ce6938f5 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/IdentityHandler.hxx @@ -0,0 +1,83 @@ +#ifndef RESIP_IdentityHandler_HXX +#define RESIP_IdentityHandler_HXX + +#include "resip/dum/DumFeature.hxx" +#include <map> + +namespace resip +{ + +class HttpGetMessage; +class DumFeature; + +class IdentityHandler : public DumFeature +{ + public: + IdentityHandler(DialogUsageManager& dum, TargetCommand::Target& target); + ~IdentityHandler(); + + virtual ProcessingResult process(Message* msg); + + private: + void processIdentityCheckResponse(const HttpGetMessage& msg); + bool queueForIdentityCheck(SipMessage* sipMsg); + + typedef std::map<Data, SipMessage*> RequiresCerts; + RequiresCerts mRequiresCerts; +}; + +} + + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.cxx b/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.cxx new file mode 100644 index 00000000..8df05967 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.cxx @@ -0,0 +1,310 @@ +#include <ctime> + +#include "resip/dum/InMemoryRegistrationDatabase.hxx" +#include "rutil/Timer.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +InMemoryRegistrationDatabase::InMemoryRegistrationDatabase(bool checkExpiry) : + mCheckExpiry(checkExpiry) +{ +} + +InMemoryRegistrationDatabase::~InMemoryRegistrationDatabase() +{ + for( database_map_t::const_iterator it = mDatabase.begin(); + it != mDatabase.end(); it++) + { + delete it->second; + } + mDatabase.clear(); +} + +void +InMemoryRegistrationDatabase::addAor(const Uri& aor, + const ContactList& contacts) +{ + Lock g(mDatabaseMutex); + mDatabase[aor] = new ContactList(contacts); +} + +void +InMemoryRegistrationDatabase::removeAor(const Uri& aor) +{ + database_map_t::iterator i; + + Lock g(mDatabaseMutex); + i = mDatabase.find(aor); + //DebugLog (<< "Removing registration bindings " << aor); + if (i != mDatabase.end()) + { + if (i->second) + { + DebugLog (<< "Removed " << i->second->size() << " entries"); + delete i->second; + // Setting this to 0 causes it to be removed when we unlock the AOR. + i->second = 0; + } + } +} + +void +InMemoryRegistrationDatabase::getAors(InMemoryRegistrationDatabase::UriList& container) +{ + container.clear(); + Lock g(mDatabaseMutex); + for( database_map_t::const_iterator it = mDatabase.begin(); + it != mDatabase.end(); it++) + { + container.push_back(it->first); + } +} + +bool +InMemoryRegistrationDatabase::aorIsRegistered(const Uri& aor) +{ + Lock g(mDatabaseMutex); + database_map_t::iterator i = findNotExpired(aor); + if (i == mDatabase.end() || i->second == 0) + { + return false; + } + return true; +} + +void +InMemoryRegistrationDatabase::lockRecord(const Uri& aor) +{ + Lock g2(mLockedRecordsMutex); + + { + Lock g1(mDatabaseMutex); + // This forces insertion if the record does not yet exist. + mDatabase[aor]; + } + + while (mLockedRecords.count(aor)) + { + mRecordUnlocked.wait(mLockedRecordsMutex); + } + + mLockedRecords.insert(aor); +} + +void +InMemoryRegistrationDatabase::unlockRecord(const Uri& aor) +{ + Lock g2(mLockedRecordsMutex); + + { + Lock g1(mDatabaseMutex); + // If the pointer is null, we remove the record from the map. + database_map_t::iterator i = mDatabase.find(aor); + + // The record must have been inserted when we locked it in the first place + assert (i != mDatabase.end()); + + if (i->second == 0) + { + mDatabase.erase(i); + } + } + + mLockedRecords.erase(aor); + mRecordUnlocked.broadcast(); +} + +RegistrationPersistenceManager::update_status_t +InMemoryRegistrationDatabase::updateContact(const resip::Uri& aor, + const ContactInstanceRecord& rec) +{ + ContactList *contactList = 0; + + { + Lock g(mDatabaseMutex); + + database_map_t::iterator i; + i = mDatabase.find(aor); + if (i == mDatabase.end() || i->second == 0) + { + contactList = new ContactList(); + mDatabase[aor] = contactList; + } + else + { + contactList = i->second; + } + + } + + assert(contactList); + + ContactList::iterator j; + + // See if the contact is already present. We use URI matching rules here. + for (j = contactList->begin(); j != contactList->end(); j++) + { + if (*j == rec) + { + *j=rec; + return CONTACT_UPDATED; + } + } + + // This is a new contact, so we add it to the list. + contactList->push_back(rec); + return CONTACT_CREATED; +} + +void +InMemoryRegistrationDatabase::removeContact(const Uri& aor, + const ContactInstanceRecord& rec) +{ + ContactList *contactList = 0; + + { + Lock g(mDatabaseMutex); + + database_map_t::iterator i; + i = mDatabase.find(aor); + if (i == mDatabase.end() || i->second == 0) + { + return; + } + contactList = i->second; + } + + ContactList::iterator j; + + // See if the contact is present. We use URI matching rules here. + for (j = contactList->begin(); j != contactList->end(); j++) + { + if (*j == rec) + { + contactList->erase(j); + if (contactList->empty()) + { + removeAor(aor); + } + return; + } + } +} + +void +InMemoryRegistrationDatabase::getContacts(const Uri& aor, ContactList& container) +{ + Lock g(mDatabaseMutex); + database_map_t::iterator i = findNotExpired(aor); + if (i == mDatabase.end() || i->second == 0) + { + container.clear(); + return; + } + container = *(i->second); +} + +class RemoveIfExpired +{ +protected: + UInt64 now; +public: + RemoveIfExpired() + { + now = Timer::getTimeSecs(); + } + bool operator () (const ContactInstanceRecord& rec) + { + return expired(rec); + } + bool expired(const ContactInstanceRecord& rec) + { + if(rec.mRegExpires <= now) + { + DebugLog(<< "ContactInstanceRecord expired: " << rec.mContact); + return true; + } + return false; + } +}; + +bool expired(const ContactInstanceRecord& rec) +{ + RemoveIfExpired rei; + return rei.expired(rec); +} + +InMemoryRegistrationDatabase::database_map_t::iterator +InMemoryRegistrationDatabase::findNotExpired(const Uri& aor) +{ + database_map_t::iterator i; + i = mDatabase.find(aor); + if (i == mDatabase.end() || i->second == 0) + { + return i; + } + if(mCheckExpiry) + { + ContactList *contacts = i->second; +#ifdef __SUNPRO_CC + contacts->remove_if(expired); +#else + contacts->remove_if(RemoveIfExpired()); +#endif + } + return i; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.hxx b/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.hxx new file mode 100644 index 00000000..e06e4d05 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.hxx @@ -0,0 +1,123 @@ +#if !defined(RESIP_INMEMORYREGISTRATIONDATABASE_HXX) +#define RESIP_INMEMORYREGISTRATIONDATABASE_HXX + +#include <map> +#include <set> + +#include "resip/dum/RegistrationPersistenceManager.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/Condition.hxx" +#include "rutil/Lock.hxx" + +namespace resip +{ + +/** + Trivial implementation of a persistence manager. This class keeps + all registrations in memory, and has no schemes for disk storage + or replication of any kind. It's good for testing, but probably + inappropriate for any commercially deployable products. +*/ +class InMemoryRegistrationDatabase : public RegistrationPersistenceManager +{ + public: + + /** + * @param checkExpiry if set, then the methods aorIsRegistered() and + * getContacts() will check that contacts are + * not expired before returning an answer. + */ + InMemoryRegistrationDatabase(bool checkExpiry = false); + virtual ~InMemoryRegistrationDatabase(); + + virtual void addAor(const Uri& aor, const ContactList& contacts); + virtual void removeAor(const Uri& aor); + virtual bool aorIsRegistered(const Uri& aor); + + virtual void lockRecord(const Uri& aor); + virtual void unlockRecord(const Uri& aor); + + virtual update_status_t updateContact(const resip::Uri& aor, + const ContactInstanceRecord& rec); + virtual void removeContact(const Uri& aor, + const ContactInstanceRecord& rec); + + virtual void getContacts(const Uri& aor, ContactList& container); + + /// return all the AOR in the DB + virtual void getAors(UriList& container); + + private: + typedef std::map<Uri,ContactList *> database_map_t; + database_map_t mDatabase; + Mutex mDatabaseMutex; + + std::set<Uri> mLockedRecords; + Mutex mLockedRecordsMutex; + Condition mRecordUnlocked; + + bool mCheckExpiry; + + protected: + /** + * Find aor in mDatabase + * Before returning the iterator pointing to aor, + * delete all expired contacts + */ + database_map_t::iterator findNotExpired(const Uri& aor); + +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.cxx b/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.cxx new file mode 100644 index 00000000..c694a5f1 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.cxx @@ -0,0 +1,434 @@ +#include "resip/dum/InMemorySyncRegDb.hxx" +#include "rutil/Timer.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +class RemoveIfRequired +{ +protected: + UInt64 mNow; + unsigned int mRemoveLingerSecs; +public: + RemoveIfRequired(UInt64& now, unsigned int removeLingerSecs) : + mNow(now), + mRemoveLingerSecs(removeLingerSecs) {} + bool operator () (const ContactInstanceRecord& rec) + { + return mustRemove(rec); + } + bool mustRemove(const ContactInstanceRecord& rec) + { + if((rec.mRegExpires <= mNow) && ((mNow - rec.mLastUpdated) > mRemoveLingerSecs)) + { + DebugLog(<< "ContactInstanceRecord removed after linger: " << rec.mContact); + return true; + } + return false; + } +}; + +/* Solaris with libCstd seems to choke on the use of an + object (such as RemoveIfRequired) as a predicate for remove_if. + Therefore, this wrapper function implements a workaround, + iterating the list explicitly and using erase(). */ +void +contactsRemoveIfRequired(ContactList& contacts, UInt64& now, + unsigned int removeLingerSecs) +{ + RemoveIfRequired rei(now, removeLingerSecs); +#ifdef __SUNPRO_CC + for(ContactList::iterator i = contacts.begin(); i != contacts.end(); ) + { + if(rei.mustRemove(*i)) + i = contacts.erase(i); + else + ++i; + } +#else + contacts.remove_if(rei); +#endif +} + +InMemorySyncRegDb::InMemorySyncRegDb(unsigned int removeLingerSecs) : + mRemoveLingerSecs(removeLingerSecs), + mHandler(0) +{ +} + +InMemorySyncRegDb::~InMemorySyncRegDb() +{ + for( database_map_t::const_iterator it = mDatabase.begin(); + it != mDatabase.end(); it++) + { + delete it->second; + } + mDatabase.clear(); +} + +void +InMemorySyncRegDb::initialSync(unsigned int connectionId) +{ + Lock g(mDatabaseMutex); + UInt64 now = Timer::getTimeSecs(); + for(database_map_t::iterator it = mDatabase.begin(); it != mDatabase.end(); it++) + { + if(it->second) + { + ContactList& contacts = *(it->second); + if(mRemoveLingerSecs > 0) + { + contactsRemoveIfRequired(contacts, now, mRemoveLingerSecs); + } + if(mHandler) mHandler->onInitialSyncAor(connectionId, it->first, contacts); + } + } +} + +void +InMemorySyncRegDb::addAor(const Uri& aor, + const ContactList& contacts) +{ + Lock g(mDatabaseMutex); + database_map_t::iterator it = mDatabase.find(aor); + if(it != mDatabase.end()) + { + if(it->second) + { + *(it->second) = contacts; + } + else + { + it->second = new ContactList(contacts); + } + } + else + { + mDatabase[aor] = new ContactList(contacts); + } + if(mHandler) mHandler->onAorModified(aor, contacts); +} + +void +InMemorySyncRegDb::removeAor(const Uri& aor) +{ + database_map_t::iterator i; + + Lock g(mDatabaseMutex); + i = mDatabase.find(aor); + //DebugLog (<< "Removing registration bindings " << aor); + if (i != mDatabase.end()) + { + if (i->second) + { + if(mRemoveLingerSecs > 0) + { + ContactList& contacts = *(i->second); + UInt64 now = Timer::getTimeSecs(); + for(ContactList::iterator it = contacts.begin(); it != contacts.end(); it++) + { + // Don't delete record - set expires to 0 + it->mRegExpires = 0; + it->mLastUpdated = now; + } + if(mHandler) mHandler->onAorModified(aor, contacts); + } + else + { + delete i->second; + // Setting this to 0 causes it to be removed when we unlock the AOR. + i->second = 0; + ContactList emptyList; + if(mHandler) mHandler->onAorModified(aor, emptyList); + } + } + } +} + +void +InMemorySyncRegDb::getAors(InMemorySyncRegDb::UriList& container) +{ + container.clear(); + Lock g(mDatabaseMutex); + for( database_map_t::const_iterator it = mDatabase.begin(); + it != mDatabase.end(); it++) + { + container.push_back(it->first); + } +} + +bool +InMemorySyncRegDb::aorIsRegistered(const Uri& aor) +{ + Lock g(mDatabaseMutex); + database_map_t::iterator i = mDatabase.find(aor); + if (i != mDatabase.end() && i->second == 0) + { + if(mRemoveLingerSecs > 0) + { + ContactList& contacts = *(i->second); + UInt64 now = Timer::getTimeSecs(); + for(ContactList::iterator it = contacts.begin(); it != contacts.end(); it++) + { + if(it->mRegExpires > now) + { + return true; + } + } + } + else + { + return true; + } + } + return false; +} + +void +InMemorySyncRegDb::lockRecord(const Uri& aor) +{ + Lock g2(mLockedRecordsMutex); + + DebugLog(<< "InMemorySyncRegDb::lockRecord: aor=" << aor << " threadid=" << ThreadIf::selfId()); + + { + Lock g1(mDatabaseMutex); + // This forces insertion if the record does not yet exist. + mDatabase[aor]; + } + + while (mLockedRecords.count(aor)) + { + mRecordUnlocked.wait(mLockedRecordsMutex); + } + + mLockedRecords.insert(aor); +} + +void +InMemorySyncRegDb::unlockRecord(const Uri& aor) +{ + Lock g2(mLockedRecordsMutex); + + DebugLog(<< "InMemorySyncRegDb::unlockRecord: aor=" << aor << " threadid=" << ThreadIf::selfId()); + + { + Lock g1(mDatabaseMutex); + // If the pointer is null, we remove the record from the map. + database_map_t::iterator i = mDatabase.find(aor); + + // The record must have been inserted when we locked it in the first place + assert (i != mDatabase.end()); + + if (i->second == 0) + { + mDatabase.erase(i); + } + } + + mLockedRecords.erase(aor); + mRecordUnlocked.broadcast(); +} + +RegistrationPersistenceManager::update_status_t +InMemorySyncRegDb::updateContact(const resip::Uri& aor, + const ContactInstanceRecord& rec) +{ + ContactList *contactList = 0; + + { + Lock g(mDatabaseMutex); + + database_map_t::iterator i; + i = mDatabase.find(aor); + if (i == mDatabase.end() || i->second == 0) + { + contactList = new ContactList(); + mDatabase[aor] = contactList; + } + else + { + contactList = i->second; + } + } + + assert(contactList); + + ContactList::iterator j; + + // See if the contact is already present. We use URI matching rules here. + for (j = contactList->begin(); j != contactList->end(); j++) + { + if (*j == rec) + { + update_status_t status = CONTACT_UPDATED; + if(mRemoveLingerSecs > 0 && j->mRegExpires == 0) + { + // If records linger, then check if updating a lingering record, if so + // modify status to CREATED so that ServerRegistration will properly generate + // an onAdd callback, instead of onRefresh. + // When contacts linger, their expires time is set to 0 + status = CONTACT_CREATED; + } + *j=rec; + if(mHandler && !rec.mSyncContact) mHandler->onAorModified(aor, *contactList); + return status; + } + } + + // This is a new contact, so we add it to the list. + contactList->push_back(rec); + if(mHandler && !rec.mSyncContact) mHandler->onAorModified(aor, *contactList); + return CONTACT_CREATED; +} + +void +InMemorySyncRegDb::removeContact(const Uri& aor, + const ContactInstanceRecord& rec) +{ + ContactList *contactList = 0; + + { + Lock g(mDatabaseMutex); + + database_map_t::iterator i; + i = mDatabase.find(aor); + if (i == mDatabase.end() || i->second == 0) + { + return; + } + contactList = i->second; + } + + ContactList::iterator j; + + // See if the contact is present. We use URI matching rules here. + for (j = contactList->begin(); j != contactList->end(); j++) + { + if (*j == rec) + { + if(mRemoveLingerSecs > 0) + { + j->mRegExpires = 0; + j->mLastUpdated = Timer::getTimeSecs(); + if(mHandler && !rec.mSyncContact) mHandler->onAorModified(aor, *contactList); + } + else + { + contactList->erase(j); + if (contactList->empty()) + { + removeAor(aor); + } + else + { + if(mHandler && !rec.mSyncContact) mHandler->onAorModified(aor, *contactList); + } + } + return; + } + } +} + +void +InMemorySyncRegDb::getContacts(const Uri& aor, ContactList& container) +{ + Lock g(mDatabaseMutex); + database_map_t::iterator i = mDatabase.find(aor); + if (i == mDatabase.end() || i->second == 0) + { + container.clear(); + return; + } + if(mRemoveLingerSecs > 0) + { + ContactList& contacts = *(i->second); + UInt64 now = Timer::getTimeSecs(); + contactsRemoveIfRequired(contacts, now, mRemoveLingerSecs); + container.clear(); + for(ContactList::iterator it = contacts.begin(); it != contacts.end(); it++) + { + if(it->mRegExpires > now) + { + container.push_back(*it); + } + } + } + else + { + container = *(i->second); + } +} + +void +InMemorySyncRegDb::getContactsFull(const Uri& aor, ContactList& container) +{ + Lock g(mDatabaseMutex); + database_map_t::iterator i = mDatabase.find(aor); + if (i == mDatabase.end() || i->second == 0) + { + container.clear(); + return; + } + ContactList& contacts = *(i->second); + if(mRemoveLingerSecs > 0) + { + UInt64 now = Timer::getTimeSecs(); + contactsRemoveIfRequired(contacts, now, mRemoveLingerSecs); + } + container = contacts; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.hxx b/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.hxx new file mode 100644 index 00000000..6e21c718 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.hxx @@ -0,0 +1,134 @@ +#if !defined(RESIP_INMEMORYSYNCREGDB_HXX) +#define RESIP_INMEMORYSYNCREGDB_HXX + +#include <map> +#include <set> + +#include "resip/dum/RegistrationPersistenceManager.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/Condition.hxx" +#include "rutil/Lock.hxx" + +namespace resip +{ + +class InMemorySyncRegDbHandler +{ +public: + virtual ~InMemorySyncRegDbHandler(){} + virtual void onAorModified(const resip::Uri& aor, const ContactList& contacts) = 0; + virtual void onInitialSyncAor(unsigned int connectionId, const resip::Uri& aor, const ContactList& contacts) = 0; +}; + +/** + Implementation of a persistence manager. This class keeps + all registrations in memory, and is used for remote replication. + + Removed contact bindings are kept in memory with a RegExpires time + of 0. This is required in order to properly syncronize removed + contact bindings with a peer instance. Contacts are not deleted + from memory until they have been removed for "removeLingerSecs". + The removeLingerSecs parameter is passed into the contructor. + If removeLingerSecs is set to 0, then contacts are removed from + memory immediately and this class behaves very similar to the + InMemoryRegistrationDatabase class. + + The InMemorySyncRegDbHandler can be used by an external mechanism to + transport registration bindings to a remote peer for replication. + See the RegSyncClient and RegSyncServer implementations in the repro + project. +*/ +class InMemorySyncRegDb : public RegistrationPersistenceManager +{ + public: + + InMemorySyncRegDb(unsigned int removeLingerSecs = 0); + virtual ~InMemorySyncRegDb(); + + virtual void setHandler(InMemorySyncRegDbHandler* handler) { mHandler = handler; } + virtual void initialSync(unsigned int connectionId); + + virtual void addAor(const Uri& aor, const ContactList& contacts); + virtual void removeAor(const Uri& aor); + virtual bool aorIsRegistered(const Uri& aor); + + virtual void lockRecord(const Uri& aor); + virtual void unlockRecord(const Uri& aor); + + virtual update_status_t updateContact(const resip::Uri& aor, + const ContactInstanceRecord& rec); + virtual void removeContact(const Uri& aor, + const ContactInstanceRecord& rec); + + virtual void getContacts(const Uri& aor, ContactList& container); + virtual void getContactsFull(const Uri& aor, ContactList& container); + + /// return all the AOR in the DB + virtual void getAors(UriList& container); + + private: + typedef std::map<Uri,ContactList *> database_map_t; + database_map_t mDatabase; + Mutex mDatabaseMutex; + + std::set<Uri> mLockedRecords; + Mutex mLockedRecordsMutex; + Condition mRecordUnlocked; + + unsigned int mRemoveLingerSecs; + InMemorySyncRegDbHandler* mHandler; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/InviteDialogs.hxx b/src/libs/resiprocate/resip/dum/InviteDialogs.hxx new file mode 100644 index 00000000..3eeaffc6 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InviteDialogs.hxx @@ -0,0 +1,82 @@ +#if !defined(RESIP_DialogEventHandler_HXX) +#define RESIP_DialogEventHandler_HXX + +namespace resip +{ + + class InviteDialogs + { + public: + enum TerminatedReason + { + Error, + Timeout, + Replaced, + LocalBye, + RemoteBye + }; + virtual ~DialogEventHandler() {} + + virtual void onNewSession(InviteSessionHandle h); + virtual void onSessionTransition(InviteSessionHandle h); + //generate doc, update. remove from map + virtual void onSessionTerminated(InviteSessionHandle h, TerminatedReason); + + + private: + std::multimap<Data, InviteSessionHandle> + }; + +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/InviteSession.cxx b/src/libs/resiprocate/resip/dum/InviteSession.cxx new file mode 100644 index 00000000..9a2dfa48 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InviteSession.cxx @@ -0,0 +1,3234 @@ +#include "resip/stack/MultipartMixedContents.hxx" +#include "resip/stack/MultipartAlternativeContents.hxx" +#include "resip/stack/SdpContents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/dum/BaseCreator.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/DialogEventStateManager.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/InviteSession.hxx" +#include "resip/dum/ServerInviteSession.hxx" +#include "resip/dum/ClientSubscription.hxx" +#include "resip/dum/ServerSubscription.hxx" +#include "resip/dum/ClientInviteSession.hxx" +#include "resip/dum/InviteSessionHandler.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/UsageUseException.hxx" +#include "resip/dum/DumHelper.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/Logger.hxx" +#include "rutil/MD5Stream.hxx" +#include "rutil/Timer.hxx" +#include "rutil/Random.hxx" +#include "rutil/compat.hxx" +#include "rutil/WinLeakCheck.hxx" + +// Remove warning about 'this' use in initiator list - pointer is only stored +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) // using this in base member initializer list +#pragma warning( disable : 4800 ) // forcing value to bool (performance warning) +#endif + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM +#define THROW(msg) throw DialogUsage::Exception(msg, __FILE__,__LINE__); + +using namespace resip; +using namespace std; + +Data EndReasons[] = +{ + "Not Specified", + "User Hung Up", + "Application Rejected Sdp(usually no common codec)", + "Illegal Sdp Negotiation", + "ACK not received", + "Session Timer Expired", + "Stale re-Invite" +}; + +const Data& InviteSession::getEndReasonString(InviteSession::EndReason reason) +{ + if(reason != InviteSession::UserSpecified) + { + assert(reason >= InviteSession::NotSpecified && reason < InviteSession::ENDREASON_MAX); //!dcm! -- necessary? + return EndReasons[reason]; + } + else + { + return mUserEndReason; + } +} + +InviteSession::InviteSession(DialogUsageManager& dum, Dialog& dialog) + : DialogUsage(dum, dialog), + mState(Undefined), + mNitState(NitComplete), + mServerNitState(NitComplete), + mLastLocalSessionModification(new SipMessage), + mLastRemoteSessionModification(new SipMessage), + mInvite200(new SipMessage), + mLastNitResponse(new SipMessage), + mCurrentRetransmit200(0), + mStaleReInviteTimerSeq(1), + mSessionInterval(0), + mMinSE(90), + mSessionRefresher(false), + mSessionTimerSeq(0), + mSessionRefreshReInvite(false), + mReferSub(true), + mCurrentEncryptionLevel(DialogUsageManager::None), + mProposedEncryptionLevel(DialogUsageManager::None), + mEndReason(NotSpecified) +{ + DebugLog ( << "^^^ InviteSession::InviteSession " << this); + assert(mDum.mInviteSessionHandler); +} + +InviteSession::~InviteSession() +{ + DebugLog ( << "^^^ InviteSession::~InviteSession " << this); + mDialog.mInviteSession = 0; + while(!mNITQueue.empty()) + { + delete mNITQueue.front(); + mNITQueue.pop(); + } +} + +void +InviteSession::dialogDestroyed(const SipMessage& msg) +{ + assert(0); + + // !jf! Is this correct? Merged from main... + // !jf! what reason - guessed for now? + //mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::PeerEnded, msg); + //delete this; +} + +bool +InviteSession::hasLocalOfferAnswer() const +{ + return (mCurrentLocalOfferAnswer.get()); +} + +const Contents& +InviteSession::getLocalOfferAnswer() const +{ + if(mCurrentLocalOfferAnswer.get()) + { + return *mCurrentLocalOfferAnswer; + } + else + { + return SdpContents::Empty; + } +} + +bool +InviteSession::hasRemoteOfferAnswer() const +{ + return (mCurrentRemoteOfferAnswer.get()); +} + +const Contents& +InviteSession::getRemoteOfferAnswer() const +{ + if(mCurrentRemoteOfferAnswer.get()) + { + return *mCurrentRemoteOfferAnswer; + } + else + { + return SdpContents::Empty; + } +} + +bool +InviteSession::hasProposedRemoteOfferAnswer() const +{ + return (mProposedRemoteOfferAnswer.get()); +} + +const Contents& +InviteSession::getProposedRemoteOfferAnswer() const +{ + if(mProposedRemoteOfferAnswer.get()) + { + return *mProposedRemoteOfferAnswer; + } + else + { + return SdpContents::Empty; + } +} + +bool +InviteSession::hasLocalSdp() const +{ + assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); + return (mCurrentLocalOfferAnswer.get()); +} + +const SdpContents& +InviteSession::getLocalSdp() const +{ + assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); + if(mCurrentLocalOfferAnswer.get()) + { + const SdpContents* sdp = dynamic_cast<const SdpContents*>(mCurrentLocalOfferAnswer.get()); + assert(sdp); + return *sdp; + } + else + { + return SdpContents::Empty; + } +} + +bool +InviteSession::hasRemoteSdp() const +{ + assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); + return (mCurrentRemoteOfferAnswer.get()); +} + +const SdpContents& +InviteSession::getRemoteSdp() const +{ + assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); + if(mCurrentRemoteOfferAnswer.get()) + { + const SdpContents* sdp = dynamic_cast<const SdpContents*>(mCurrentRemoteOfferAnswer.get()); + assert(sdp); + return *sdp; + } + else + { + return SdpContents::Empty; + } +} + +bool +InviteSession::hasProposedRemoteSdp() const +{ + assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); + return (mProposedRemoteOfferAnswer.get()); +} + +const SdpContents& +InviteSession::getProposedRemoteSdp() const +{ + assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); + if(mProposedRemoteOfferAnswer.get()) + { + const SdpContents* sdp = dynamic_cast<const SdpContents*>(mProposedRemoteOfferAnswer.get()); + assert(sdp); + return *sdp; + } + else + { + return SdpContents::Empty; + } +} + +InviteSessionHandle +InviteSession::getSessionHandle() +{ + return InviteSessionHandle(mDum, getBaseHandle().getId()); +} + +void InviteSession::storePeerCapabilities(const SipMessage& msg) +{ + if (msg.exists(h_Allows)) + { + mPeerSupportedMethods = msg.header(h_Allows); + } + if (msg.exists(h_Supporteds)) + { + mPeerSupportedOptionTags = msg.header(h_Supporteds); + } + if (msg.exists(h_AcceptEncodings)) + { + mPeerSupportedEncodings = msg.header(h_AcceptEncodings); + } + if (msg.exists(h_AcceptLanguages)) + { + mPeerSupportedLanguages = msg.header(h_AcceptLanguages); + } + if (msg.exists(h_AllowEvents)) + { + mPeerAllowedEvents = msg.header(h_AllowEvents); + } + if (msg.exists(h_Accepts)) + { + mPeerSupportedMimeTypes = msg.header(h_Accepts); + } + if (msg.exists(h_UserAgent)) + { + mPeerUserAgent = msg.header(h_UserAgent).value(); + } +} + +bool +InviteSession::updateMethodSupported() const +{ + // Check if Update is supported locally + if(mDum.getMasterProfile()->isMethodSupported(UPDATE)) + { + // Check if peer supports UPDATE + return mPeerSupportedMethods.find(Token("UPDATE")); + } + return false; +} + +bool +InviteSession::isConnected() const +{ + switch (mState) + { + case Connected: + case SentUpdate: + case SentUpdateGlare: + case SentReinvite: + case SentReinviteGlare: + case SentReinviteNoOffer: + case SentReinviteAnswered: + case SentReinviteNoOfferGlare: + case ReceivedUpdate: + case ReceivedReinvite: + case ReceivedReinviteNoOffer: + case ReceivedReinviteSentOffer: + case Answered: + case WaitingToOffer: + case WaitingToRequestOffer: + return true; + + default: + return false; + } +} + +bool +InviteSession::isEarly() const +{ + switch (mState) + { + case UAC_Early: + case UAC_EarlyWithOffer: + case UAC_EarlyWithAnswer: + case UAC_SentUpdateEarly: + case UAC_ReceivedUpdateEarly: + case UAC_SentAnswer: + case UAC_QueuedUpdate: + return true; + default: + return false; + } +} + +bool +InviteSession::isAccepted() const +{ + switch (mState) + { + case UAS_Start: + case UAS_Offer: + case UAS_NoOffer: + case UAS_NoOfferReliable: + case UAS_ProvidedOffer: + case UAS_OfferProvidedAnswer: + case UAS_EarlyOffer: + case UAS_EarlyProvidedOffer: + case UAS_EarlyProvidedAnswer: + case UAS_EarlyNoOffer: + case UAS_FirstSentAnswerReliable: + case UAS_FirstSentOfferReliable: + case UAS_NegotiatedReliable: + return false; + default: + return true; + } +} + +bool +InviteSession::isTerminated() const +{ + switch (mState) + { + case Terminated: + case WaitingToTerminate: + case WaitingToHangup: + case UAC_Cancelled: + case UAS_WaitingToTerminate: + case UAS_WaitingToHangup: + return true; + default: + return false; + } +} + +EncodeStream& +InviteSession::dump(EncodeStream& strm) const +{ + strm << "INVITE: " << mId + << " " << toData(mState) + << " ADDR=" << myAddr() + << " PEER=" << peerAddr(); + return strm; +} + +void +InviteSession::requestOffer() +{ + switch (mState) + { + case Connected: + case WaitingToRequestOffer: + case UAS_WaitingToRequestOffer: + transition(SentReinviteNoOffer); + mDialog.makeRequest(*mLastLocalSessionModification, INVITE); + startStaleReInviteTimer(); + mLastLocalSessionModification->setContents(0); // Clear the contents from the INVITE + setSessionTimerHeaders(*mLastLocalSessionModification); + + InfoLog (<< "Sending " << mLastLocalSessionModification->brief()); + + // call send to give app an chance to adorn the message. + send(mLastLocalSessionModification); + break; + + case Answered: + // queue the offer to be sent after the ACK is received + transition(WaitingToRequestOffer); + break; + + // ?slg? Can we handle all of the states listed in isConnected() ??? + default: + WarningLog (<< "Can't requestOffer when not in Connected state"); + throw DialogUsage::Exception("Can't request an offer", __FILE__,__LINE__); + } +} + +bool +InviteSession::canProvideOffer() +{ + switch (mState) + { + case Connected: + case WaitingToOffer: + case UAS_WaitingToOffer: + case Answered: + case ReceivedReinviteNoOffer: + return true; + default: + return false; + } +} + + + +void +InviteSession::provideOffer(const Contents& offer, + DialogUsageManager::EncryptionLevel level, + const Contents* alternative) +{ + switch (mState) + { + case Connected: + case WaitingToOffer: + case UAS_WaitingToOffer: + transition(SentReinvite); + mDialog.makeRequest(*mLastLocalSessionModification, INVITE); + startStaleReInviteTimer(); + + setSessionTimerHeaders(*mLastLocalSessionModification); + + InfoLog (<< "Sending " << mLastLocalSessionModification->brief()); + InviteSession::setOfferAnswer(*mLastLocalSessionModification, offer, alternative); + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); + mProposedEncryptionLevel = level; + DumHelper::setOutgoingEncryptionLevel(*mLastLocalSessionModification, mProposedEncryptionLevel); + + // call send to give app an chance to adorn the message. + send(mLastLocalSessionModification); + break; + + case Answered: + // queue the offer to be sent after the ACK is received + transition(WaitingToOffer); + mProposedEncryptionLevel = level; + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); + break; + + case ReceivedReinviteNoOffer: + assert(!mProposedRemoteOfferAnswer.get()); + transition(ReceivedReinviteSentOffer); + mDialog.makeResponse(*mInvite200, *mLastRemoteSessionModification, 200); + handleSessionTimerRequest(*mInvite200, *mLastRemoteSessionModification); + InviteSession::setOfferAnswer(*mInvite200, offer, 0); + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer); + + InfoLog (<< "Sending " << mInvite200->brief()); + DumHelper::setOutgoingEncryptionLevel(*mInvite200, mCurrentEncryptionLevel); + send(mInvite200); + startRetransmit200Timer(); + break; + + default: + WarningLog (<< "Incorrect state to provideOffer: " << toData(mState)); + throw DialogUsage::Exception("Can't provide an offer", __FILE__,__LINE__); + } +} + +class InviteSessionProvideOfferExCommand : public DumCommandAdapter +{ +public: + InviteSessionProvideOfferExCommand(InviteSession& inviteSession, + const Contents& offer, + DialogUsageManager::EncryptionLevel level, + const Contents* alternative) + : mInviteSession(inviteSession), + mOffer(offer.clone()), + mLevel(level), + mAlternative(alternative ? alternative->clone() : 0) + { + } + + virtual void executeCommand() + { + mInviteSession.provideOffer(*mOffer, mLevel, mAlternative.get()); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "InviteSessionProvideOfferExCommand"; + } +private: + InviteSession& mInviteSession; + std::auto_ptr<const Contents> mOffer; + DialogUsageManager::EncryptionLevel mLevel; + std::auto_ptr<const Contents> mAlternative; +}; + +void +InviteSession::provideOfferCommand(const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative) +{ + mDum.post(new InviteSessionProvideOfferExCommand(*this, offer, level, alternative)); +} + +void +InviteSession::provideOffer(const Contents& offer) +{ + return provideOffer(offer, mCurrentEncryptionLevel, 0); +} + +class InviteSessionProvideOfferCommand : public DumCommandAdapter +{ +public: + InviteSessionProvideOfferCommand(InviteSession& inviteSession, const Contents& offer) + : mInviteSession(inviteSession), + mOffer(offer.clone()) + { + } + + virtual void executeCommand() + { + mInviteSession.provideOffer(*mOffer); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "InviteSessionProvideOfferCommand"; + } +private: + InviteSession& mInviteSession; + std::auto_ptr<const Contents> mOffer; +}; + +void +InviteSession::provideOfferCommand(const Contents& offer) +{ + mDum.post(new InviteSessionProvideOfferCommand(*this, offer)); +} + +void +InviteSession::provideAnswer(const Contents& answer) +{ + switch (mState) + { + case ReceivedReinvite: + transition(Connected); + mDialog.makeResponse(*mInvite200, *mLastRemoteSessionModification, 200); + handleSessionTimerRequest(*mInvite200, *mLastRemoteSessionModification); + InviteSession::setOfferAnswer(*mInvite200, answer, 0); + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + InfoLog (<< "Sending " << mInvite200->brief()); + DumHelper::setOutgoingEncryptionLevel(*mInvite200, mCurrentEncryptionLevel); + send(mInvite200); + startRetransmit200Timer(); + break; + + case ReceivedUpdate: // same as ReceivedReinvite case. + { + transition(Connected); + + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, *mLastRemoteSessionModification, 200); + handleSessionTimerRequest(*response, *mLastRemoteSessionModification); + InviteSession::setOfferAnswer(*response, answer, 0); + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + InfoLog (<< "Sending " << response->brief()); + DumHelper::setOutgoingEncryptionLevel(*response, mCurrentEncryptionLevel); + send(response); + break; + } + + case SentReinviteAnswered: + transition(Connected); + sendAck(&answer); + + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + break; + + default: + WarningLog (<< "Incorrect state to provideAnswer: " << toData(mState)); + throw DialogUsage::Exception("Can't provide an answer", __FILE__,__LINE__); + } +} + +class InviteSessionProvideAnswerCommand : public DumCommandAdapter +{ +public: + InviteSessionProvideAnswerCommand(InviteSession& inviteSession, const Contents& answer) + : mInviteSession(inviteSession), + mAnswer(answer.clone()) + { + } + + virtual void executeCommand() + { + mInviteSession.provideAnswer(*mAnswer); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "InviteSessionProvideAnswerCommand"; + } +private: + InviteSession& mInviteSession; + std::auto_ptr<const Contents> mAnswer; +}; + +void +InviteSession::provideAnswerCommand(const Contents& answer) +{ + mDum.post(new InviteSessionProvideAnswerCommand(*this, answer)); +} + +void +InviteSession::end() +{ + end(NotSpecified); +} + +void +InviteSession::end(const Data& userReason) +{ + mUserEndReason = userReason; + end(UserSpecified); +} + +void +InviteSession::end(EndReason reason) +{ + if (mEndReason == NotSpecified) + { + mEndReason = reason; + } + + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + + switch (mState) + { + case Connected: + case SentUpdate: + case SentUpdateGlare: + case SentReinviteGlare: + case SentReinviteNoOfferGlare: + case SentReinviteAnswered: + { + // !jf! do we need to store the BYE somewhere? + // .dw. BYE message handled + SharedPtr<SipMessage> msg = sendBye(); + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); + break; + } + + case SentReinvite: + case SentReinviteNoOffer: + transition(WaitingToTerminate); + break; + + case Answered: + case WaitingToOffer: + case WaitingToRequestOffer: + case ReceivedReinviteSentOffer: + if(mCurrentRetransmit200) // If retransmit200 timer is active then ACK is not received yet - wait for it + { + transition(WaitingToHangup); + } + else + { + // ACK has likely timedout - hangup immediately + SharedPtr<SipMessage> msg = sendBye(); + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); + } + break; + + case ReceivedUpdate: + case ReceivedReinvite: + case ReceivedReinviteNoOffer: + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, *mLastRemoteSessionModification, 488); + InfoLog (<< "Sending " << response->brief()); + send(response); + + SharedPtr<SipMessage> msg = sendBye(); + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); + break; + } + + case WaitingToTerminate: // ?slg? Why is this here? + { + SharedPtr<SipMessage> msg = sendBye(); + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); + break; + } + + case Terminated: + // no-op. + break; + + default: + assert(0); + break; + } +} + +class InviteSessionEndCommand : public DumCommandAdapter +{ +public: + InviteSessionEndCommand(InviteSession& inviteSession, InviteSession::EndReason reason) + : mInviteSession(inviteSession), + mReason(reason) + { + } + + virtual void executeCommand() + { + mInviteSession.end(mReason); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "InviteSessionEndCommand"; + } +private: + InviteSession& mInviteSession; + InviteSession::EndReason mReason; +}; + +void +InviteSession::endCommand(EndReason reason) +{ + mDum.post(new InviteSessionEndCommand(*this, reason)); +} + +void +InviteSession::reject(int statusCode, WarningCategory *warning) +{ + switch (mState) + { + case ReceivedUpdate: + case ReceivedReinvite: + case ReceivedReinviteNoOffer: + { + transition(Connected); + + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, *mLastRemoteSessionModification, statusCode); + if(warning) + { + response->header(h_Warnings).push_back(*warning); + } + InfoLog (<< "Sending " << response->brief()); + send(response); + break; + } + // Sent a reINVITE no offer and received a 200-offer. + // Simply send an ACK without an answer and stay in Connected. + case SentReinviteAnswered: + { + InfoLog (<< "Not sending " << statusCode << " error since transaction" + "already completed, sending answer-less ACK"); + transition(Connected); + sendAck(); + break; + } + default: + assert(0); + break; + } +} + +class InviteSessionRejectCommand : public DumCommandAdapter +{ +public: + InviteSessionRejectCommand(InviteSession& inviteSession, int code, WarningCategory* warning) + : mInviteSession(inviteSession), + mCode(code), + mWarning(warning?new WarningCategory(*warning):0) + { + } + + virtual void executeCommand() + { + mInviteSession.reject(mCode, mWarning.get()); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "InviteSessionRejectCommand"; + } +private: + InviteSession& mInviteSession; + int mCode; + std::auto_ptr<WarningCategory> mWarning; +}; + +void +InviteSession::rejectCommand(int code, WarningCategory *warning) +{ + mDum.post(new InviteSessionRejectCommand(*this, code, warning)); +} + +void +InviteSession::targetRefresh(const NameAddr& localUri) +{ + if (isConnected()) // ?slg? likely not safe in any state except Connected - what should behaviour be if state is ReceivedReinvite? + { + mDialog.mLocalContact = localUri; + sessionRefresh(); + } + else + { + WarningLog (<< "Can't targetRefresh before Connected"); + throw UsageUseException("targetRefresh not allowed in this context", __FILE__, __LINE__); + } +} + +void +InviteSession::refer(const NameAddr& referTo, bool referSub) +{ + refer(referTo,std::auto_ptr<resip::Contents>(0),referSub); +} +void +InviteSession::refer(const NameAddr& referTo, std::auto_ptr<resip::Contents> contents,bool referSub) +{ + if (isConnected()) // ?slg? likely not safe in any state except Connected - what should behaviour be if state is ReceivedReinvite? + { + SharedPtr<SipMessage> refer(new SipMessage()); + mDialog.makeRequest(*refer, REFER); + refer->header(h_ReferTo) = referTo; + refer->header(h_ReferredBy) = myAddr(); + refer->header(h_ReferredBy).remove(p_tag); // tag-param not permitted in rfc3892; not the same as generic-param + refer->setContents(contents); + if (!referSub) + { + refer->header(h_ReferSub).value() = "false"; + refer->header(h_Supporteds).push_back(Token(Symbols::NoReferSub)); + } + + if(mNitState == NitComplete) + { + mNitState = NitProceeding; + mReferSub = referSub; + mLastSentNITRequest = refer; + send(refer); + return; + } + mNITQueue.push(new QueuedNIT(refer,referSub)); + InfoLog(<< "refer - queuing NIT:" << refer->brief()); + return; + } + else + { + WarningLog (<< "Can't refer before Connected"); + assert(0); + throw UsageUseException("REFER not allowed in this context", __FILE__, __LINE__); + } +} + +const SharedPtr<SipMessage> +InviteSession::getLastSentNITRequest() const +{ + return mLastSentNITRequest; +} + +void +InviteSession::nitComplete() +{ + mNitState = NitComplete; + if (mNITQueue.size()) + { + QueuedNIT *qn=mNITQueue.front(); + mNITQueue.pop(); + mNitState = NitProceeding; + mReferSub = qn->referSubscription(); + mLastSentNITRequest = qn->getNIT(); + InfoLog(<< "checkNITQueue - sending queued NIT:" << mLastSentNITRequest->brief()); + send(mLastSentNITRequest); + delete qn; + } +} + +class InviteSessionReferCommand : public DumCommandAdapter +{ +public: + InviteSessionReferCommand(InviteSession& inviteSession, const NameAddr& referTo, bool referSub) + : mInviteSession(inviteSession), + mReferTo(referTo), + mReferSub(referSub) + { + + } + + virtual void executeCommand() + { + mInviteSession.refer(mReferTo, mReferSub); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "InviteSessionReferCommand"; + } + +private: + InviteSession& mInviteSession; + NameAddr mReferTo; + bool mReferSub; +}; + +void +InviteSession::referCommand(const NameAddr& referTo, bool referSub) +{ + mDum.post(new InviteSessionReferCommand(*this, referTo, referSub)); +} + +void +InviteSession::refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub) +{ + refer(referTo,sessionToReplace,std::auto_ptr<resip::Contents>(0),referSub); +} + +void +InviteSession::refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, std::auto_ptr<resip::Contents> contents, bool referSub) +{ + if (!sessionToReplace.isValid()) + { + throw UsageUseException("Attempted to make a refer w/ and invalid replacement target", __FILE__, __LINE__); + } + + CallId replaces; + DialogId id = sessionToReplace->mDialog.getId(); + replaces.value() = id.getCallId(); + replaces.param(p_toTag) = id.getRemoteTag(); + replaces.param(p_fromTag) = id.getLocalTag(); + + refer(referTo, replaces, contents, referSub); +} + +void +InviteSession::refer(const NameAddr& referTo, const CallId& replaces, bool referSub) +{ + refer(referTo,replaces,std::auto_ptr<resip::Contents>(0),referSub); +} + +void +InviteSession::refer(const NameAddr& referTo, const CallId& replaces, std::auto_ptr<resip::Contents> contents, bool referSub) +{ + if (isConnected()) // ?slg? likely not safe in any state except Connected - what should behaviour be if state is ReceivedReinvite? + { + SharedPtr<SipMessage> refer(new SipMessage()); + mDialog.makeRequest(*refer, REFER); + refer->setContents(contents); + refer->header(h_ReferTo) = referTo; + refer->header(h_ReferredBy) = myAddr(); + refer->header(h_ReferredBy).remove(p_tag); + + refer->header(h_ReferTo).uri().embedded().header(h_Replaces) = replaces; + + if (!referSub) + { + refer->header(h_ReferSub).value() = "false"; + refer->header(h_Supporteds).push_back(Token(Symbols::NoReferSub)); + } + + if(mNitState == NitComplete) + { + mNitState = NitProceeding; + mReferSub = referSub; + mLastSentNITRequest = refer; + send(refer); + return; + } + mNITQueue.push(new QueuedNIT(refer,referSub)); + InfoLog(<< "refer/replace - queuing NIT:" << refer->brief()); + return; + } + else + { + WarningLog (<< "Can't refer before Connected"); + assert(0); + throw UsageUseException("REFER not allowed in this context", __FILE__, __LINE__); + } +} + +class InviteSessionReferExCommand : public DumCommandAdapter +{ +public: + InviteSessionReferExCommand(InviteSession& inviteSession, const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub) + : mInviteSession(inviteSession), + mSessionToReplace(sessionToReplace), + mReferTo(referTo), + mReferSub(referSub) + { + } + + virtual void executeCommand() + { + mInviteSession.refer(mReferTo, mSessionToReplace, mReferSub); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "InviteSessionReferExCommand"; + } + +private: + InviteSession& mInviteSession; + InviteSessionHandle mSessionToReplace; + NameAddr mReferTo; + bool mReferSub; +}; + +void +InviteSession::referCommand(const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub) +{ + mDum.post(new InviteSessionReferExCommand(*this, referTo, sessionToReplace, referSub)); +} + +void +InviteSession::info(const Contents& contents) +{ + SharedPtr<SipMessage> info(new SipMessage()); + mDialog.makeRequest(*info, INFO); + // !jf! handle multipart here + info->setContents(&contents); + DumHelper::setOutgoingEncryptionLevel(*info, mCurrentEncryptionLevel); + if (mNitState == NitComplete) + { + mNitState = NitProceeding; + mLastSentNITRequest = info; + send(info); + return; + } + mNITQueue.push(new QueuedNIT(info)); + InfoLog(<< "info - queuing NIT:" << info->brief()); + return; +} + +class InviteSessionInfoCommand : public DumCommandAdapter +{ +public: + InviteSessionInfoCommand(InviteSession& inviteSession, const Contents& contents) + : mInviteSession(inviteSession), + mContents(contents.clone()) + { + } + + virtual void executeCommand() + { + mInviteSession.info(*mContents); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "InviteSessionInfoCommand"; + } +private: + InviteSession& mInviteSession; + std::auto_ptr<Contents> mContents; +}; + +void +InviteSession::infoCommand(const Contents& contents) +{ + mDum.post(new InviteSessionInfoCommand(*this, contents)); +} + +void +InviteSession::message(const Contents& contents) +{ + SharedPtr<SipMessage> message(new SipMessage()); + mDialog.makeRequest(*message, MESSAGE); + // !jf! handle multipart here + message->setContents(&contents); + DumHelper::setOutgoingEncryptionLevel(*message, mCurrentEncryptionLevel); + InfoLog (<< "Trying to send MESSAGE: " << message); + if (mNitState == NitComplete) + { + mNitState = NitProceeding; + mLastSentNITRequest = message; + send(message); + return; + } + mNITQueue.push(new QueuedNIT(message)); + InfoLog(<< "message - queuing NIT:" << message->brief()); + return; +} + +class InviteSessionMessageCommand : public DumCommandAdapter +{ +public: + InviteSessionMessageCommand(InviteSession& inviteSession, const Contents& contents) + : mInviteSession(inviteSession), + mContents(contents.clone()) + { + } + + virtual void executeCommand() + { + mInviteSession.message(*mContents); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "InviteSessionMessageCommand"; + } +private: + InviteSession& mInviteSession; + std::auto_ptr<Contents> mContents; +}; + + +void +InviteSession::messageCommand(const Contents& contents) +{ + mDum.post(new InviteSessionMessageCommand(*this, contents)); +} + +void +InviteSession::dispatch(const SipMessage& msg) +{ + // Look for 2xx retransmissions - resend ACK and filter out of state machine + if(msg.header(h_CSeq).method() == INVITE && msg.isResponse() && msg.header(h_StatusLine).statusCode() / 100 == 2) + { + AckMap::iterator i = mAcks.find(msg.getTransactionId()); + if (i != mAcks.end()) + { + send(i->second); // resend ACK + return; + } + } + + // !jf! do we need to handle 3xx here or is it handled elsewhere? + switch (mState) + { + case Connected: + dispatchConnected(msg); + break; + case SentUpdate: + dispatchSentUpdate(msg); + break; + case SentReinvite: + dispatchSentReinvite(msg); + break; + case SentReinviteNoOffer: + dispatchSentReinviteNoOffer(msg); + break; + case SentReinviteAnswered: + dispatchSentReinviteAnswered(msg); + break; + case SentUpdateGlare: + case SentReinviteGlare: + // The behavior is the same except for timer which is handled in dispatch(Timer) + dispatchGlare(msg); + break; + case SentReinviteNoOfferGlare: + dispatchReinviteNoOfferGlare(msg); + break; + case ReceivedUpdate: + case ReceivedReinvite: + case ReceivedReinviteNoOffer: + dispatchReceivedUpdateOrReinvite(msg); + break; + case ReceivedReinviteSentOffer: + dispatchReceivedReinviteSentOffer(msg); + break; + case Answered: + dispatchAnswered(msg); + break; + case WaitingToOffer: + dispatchWaitingToOffer(msg); + break; + case WaitingToRequestOffer: + dispatchWaitingToRequestOffer(msg); + break; + case WaitingToTerminate: + dispatchWaitingToTerminate(msg); + break; + case WaitingToHangup: + dispatchWaitingToHangup(msg); + break; + case Terminated: + dispatchTerminated(msg); + break; + case Undefined: + default: + assert(0); + break; + } +} + +void +InviteSession::dispatch(const DumTimeout& timeout) +{ + if (timeout.type() == DumTimeout::Retransmit200) + { + if (mCurrentRetransmit200) + { + InfoLog (<< "Retransmitting: " << endl << mInvite200->brief()); + //DumHelper::setOutgoingEncryptionLevel(*mInvite200, mCurrentEncryptionLevel); + send(mInvite200); + mCurrentRetransmit200 *= 2; + mDum.addTimerMs(DumTimeout::Retransmit200, resipMin(Timer::T2, mCurrentRetransmit200), getBaseHandle(), timeout.seq()); + } + } + else if (timeout.type() == DumTimeout::WaitForAck) + { + if(mCurrentRetransmit200) // If retransmit200 timer is active then ACK is not received yet + { + if (timeout.seq() == mLastRemoteSessionModification->header(h_CSeq).sequence()) + { + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + + // If we are waiting for an Ack and it times out, then end with a BYE + if(mState == UAS_WaitingToHangup || + mState == WaitingToHangup) + { + SharedPtr<SipMessage> msg = sendBye(); + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); + } + else if(mState == ReceivedReinviteSentOffer) + { + transition(Connected); + mProposedLocalOfferAnswer.reset(); + mProposedEncryptionLevel = DialogUsageManager::None; + //!dcm! -- should this be onIllegalNegotiation? + mDum.mInviteSessionHandler->onOfferRejected(getSessionHandle(), 0); + } + else if(mState == WaitingToOffer || + mState == UAS_WaitingToOffer) + { + assert(mProposedLocalOfferAnswer.get()); + mDum.mInviteSessionHandler->onAckNotReceived(getSessionHandle()); + if(!isTerminated()) + { + provideProposedOffer(); + } + } + else if(mState == WaitingToRequestOffer || + mState == UAS_WaitingToRequestOffer) + { + mDum.mInviteSessionHandler->onAckNotReceived(getSessionHandle()); + if(!isTerminated()) + { + requestOffer(); + } + } + else + { + // this is so the app can decided to ignore this. default implementation + // will call end next + mDum.mInviteSessionHandler->onAckNotReceived(getSessionHandle()); + } + } + } + } + else if (timeout.type() == DumTimeout::CanDiscardAck) + { + AckMap::iterator i = mAcks.find(timeout.transactionId()); + if (i != mAcks.end()) + { + mAcks.erase(i); + } + } + else if (timeout.type() == DumTimeout::Glare) + { + if (mState == SentUpdateGlare) + { + transition(SentUpdate); + + InfoLog (<< "Retransmitting the UPDATE (glare condition timer)"); + mDialog.makeRequest(*mLastLocalSessionModification, UPDATE); // increments CSeq + send(mLastLocalSessionModification); + } + else if (mState == SentReinviteGlare) + { + transition(SentReinvite); + + InfoLog (<< "Retransmitting the reINVITE (glare condition timer)"); + mDialog.makeRequest(*mLastLocalSessionModification, INVITE); // increments CSeq + startStaleReInviteTimer(); + send(mLastLocalSessionModification); + } + else if (mState == SentReinviteNoOfferGlare) + { + transition(SentReinviteNoOffer); + + InfoLog (<< "Retransmitting the reINVITE-nooffer (glare condition timer)"); + mDialog.makeRequest(*mLastLocalSessionModification, INVITE); // increments CSeq + startStaleReInviteTimer(); + send(mLastLocalSessionModification); + } + } + else if (timeout.type() == DumTimeout::StaleReInvite) + { + if(timeout.seq() == mStaleReInviteTimerSeq) + { + if(mState == WaitingToTerminate) + { + SharedPtr<SipMessage> msg = sendBye(); + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); + } + else if(mState == SentReinvite || + mState == SentReinviteNoOffer) + { + transition(Connected); + mProposedLocalOfferAnswer.reset(); + mProposedEncryptionLevel = DialogUsageManager::None; + + // this is so the app can decide to ignore this. default implementation + // will call end next - which will send a BYE + mDum.mInviteSessionHandler->onStaleReInviteTimeout(getSessionHandle()); + } + } + } + else if (timeout.type() == DumTimeout::SessionExpiration) + { + if(timeout.seq() == mSessionTimerSeq) + { + // this is so the app can decide to ignore this. default implementation + // will call end next - which will send a BYE + mDum.mInviteSessionHandler->onSessionExpired(getSessionHandle()); + } + } + else if (timeout.type() == DumTimeout::SessionRefresh) + { + if(timeout.seq() == mSessionTimerSeq) + { + // Note: If not connected then we must be issueing a reinvite/update or + // receiving one - in either case the session timer stuff will get + // reset/renegotiated - thus just ignore this referesh + if(mState == Connected) + { + sessionRefresh(); + } + } + } +} + +void +InviteSession::dispatchConnected(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnInvite: + case OnInviteReliable: + *mLastRemoteSessionModification = msg; + transition(ReceivedReinviteNoOffer); + handler->onOfferRequired(getSessionHandle(), msg); + break; + + case OnInviteOffer: + case OnInviteReliableOffer: + *mLastRemoteSessionModification = msg; + transition(ReceivedReinvite); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mProposedRemoteOfferAnswer = offerAnswer; + + handler->onOffer(getSessionHandle(), msg, *mProposedRemoteOfferAnswer); + break; + + case On2xx: + case On2xxOffer: + case On2xxAnswer: + // retransmission of 200I + // !jf! Need to include the answer here. + sendAck(); + break; + + case OnUpdateOffer: + transition(ReceivedUpdate); + + // !kh! + // Find out if it's an UPDATE requiring state change. + // See rfc3311 5.2, 4th paragraph. + *mLastRemoteSessionModification = msg; + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mProposedRemoteOfferAnswer = offerAnswer; + handler->onOffer(getSessionHandle(), msg, *mProposedRemoteOfferAnswer); + break; + + case OnUpdate: + { + // ?slg? no offerAnswer in update - just respond immediately (likely session timer) - do we need a callback? + SharedPtr<SipMessage> response(new SipMessage); + *mLastRemoteSessionModification = msg; + mDialog.makeResponse(*response, *mLastRemoteSessionModification, 200); + + handleSessionTimerRequest(*response, *mLastRemoteSessionModification); + send(response); + break; + } + + case OnUpdateRejected: + case On200Update: + WarningLog (<< "DUM delivered an UPDATE response in an incorrect state " << endl << msg); + assert(0); + break; + + case OnAck: + case OnAckAnswer: // .bwc. Don't drop ACK with SDP! + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + handler->onAckReceived(getSessionHandle(), msg); + break; + + default: + dispatchOthers(msg); + break; + } +} + +void +InviteSession::dispatchSentUpdate(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnInvite: + case OnInviteReliable: + case OnInviteOffer: + case OnInviteReliableOffer: + case OnUpdate: + case OnUpdateOffer: + { + // glare + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 491); + send(response); + break; + } + + case On200Update: + transition(Connected); + handleSessionTimerResponse(msg); + if (offerAnswer.get() && mProposedLocalOfferAnswer.get()) + { + mCurrentEncryptionLevel = getEncryptionLevel(msg); + setCurrentLocalOfferAnswer(msg); + + mCurrentRemoteOfferAnswer = offerAnswer; + handler->onAnswer(getSessionHandle(), msg, *mCurrentRemoteOfferAnswer); + } + else if(mProposedLocalOfferAnswer.get()) + { + // If we sent an offer in the Update Request and no answer is received + handler->onIllegalNegotiation(getSessionHandle(), msg); + mProposedLocalOfferAnswer.reset(); + mProposedEncryptionLevel = DialogUsageManager::None; + } + break; + + case On491Update: + transition(SentUpdateGlare); + start491Timer(); + break; + + case On422Update: // session timer + if(msg.exists(h_MinSE)) + { + // Change interval to min from 422 response + mSessionInterval = msg.header(h_MinSE).value(); + mMinSE = mSessionInterval; + sessionRefresh(); + } + else + { + // Response must contain Min_SE - if not - just ignore + // ?slg? callback? + transition(Connected); + mProposedLocalOfferAnswer.reset(); + mProposedEncryptionLevel = DialogUsageManager::None; + } + break; + + case OnUpdateRejected: + transition(Connected); + mProposedLocalOfferAnswer.reset(); + handler->onOfferRejected(getSessionHandle(), &msg); + break; + + case OnGeneralFailure: + sendBye(); + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + break; + + default: + dispatchOthers(msg); + break; + } +} + +void +InviteSession::dispatchSentReinvite(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnInvite: + case OnInviteReliable: + case OnInviteOffer: + case OnInviteReliableOffer: + case OnUpdate: + case OnUpdateOffer: + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 491); + send(response); + break; + } + + case On1xx: + case On1xxEarly: + // Some UA's send a 100 response to a ReInvite - just ignore it + break; + + case On2xxAnswer: + case On2xxOffer: // .slg. doesn't really make sense + { + mStaleReInviteTimerSeq++; + transition(Connected); + handleSessionTimerResponse(msg); + setCurrentLocalOfferAnswer(msg); + + // !jf! I need to potentially include an answer in the ACK here + sendAck(); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + + if (mSessionRefreshReInvite) + { + mSessionRefreshReInvite = false; + + MD5Stream currentRemote; + currentRemote<< *mCurrentRemoteOfferAnswer; + MD5Stream newRemote; + newRemote << *offerAnswer; + bool changed = currentRemote.getHex() != newRemote.getHex(); + + if (changed) + { + mCurrentRemoteOfferAnswer = offerAnswer; + handler->onRemoteAnswerChanged(getSessionHandle(), msg, *mCurrentRemoteOfferAnswer); + } + } + else + { + mCurrentRemoteOfferAnswer = offerAnswer; + handler->onAnswer(getSessionHandle(), msg, *mCurrentRemoteOfferAnswer); + } + + // !jf! do I need to allow a reINVITE overlapping the retransmission of + // the ACK when a 200I is received? If yes, then I need to store all + // ACK messages for 64*T1 + break; + } + case On2xx: + mStaleReInviteTimerSeq++; + sendAck(); + transition(Connected); + handleSessionTimerResponse(msg); + handler->onIllegalNegotiation(getSessionHandle(), msg); + mProposedLocalOfferAnswer.reset(); + mProposedEncryptionLevel = DialogUsageManager::None; + break; + + case On422Invite: + mStaleReInviteTimerSeq++; + if(msg.exists(h_MinSE)) + { + // Change interval to min from 422 response + mSessionInterval = msg.header(h_MinSE).value(); + mMinSE = mSessionInterval; + sessionRefresh(); + } + else + { + // Response must contact Min_SE - if not - just ignore + // ?slg? callback? + transition(Connected); + mProposedLocalOfferAnswer.reset(); + mProposedEncryptionLevel = DialogUsageManager::None; + } + break; + + case On491Invite: + mStaleReInviteTimerSeq++; + transition(SentReinviteGlare); + start491Timer(); + break; + + case OnGeneralFailure: + mStaleReInviteTimerSeq++; + sendBye(); + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + break; + + case OnInviteFailure: + case On487Invite: + mStaleReInviteTimerSeq++; + transition(Connected); + mProposedLocalOfferAnswer.reset(); + handler->onOfferRejected(getSessionHandle(), &msg); + break; + + default: + dispatchOthers(msg); + break; + } +} + +void +InviteSession::dispatchSentReinviteNoOffer(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnInvite: + case OnInviteReliable: + case OnInviteOffer: + case OnInviteReliableOffer: + case OnUpdate: + case OnUpdateOffer: + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 491); + send(response); + break; + } + + case On1xx: + case On1xxEarly: + // Some UA's send a 100 response to a ReInvite - just ignore it + break; + + case On2xxAnswer: // .slg. doesn't really make sense + case On2xxOffer: + { + mStaleReInviteTimerSeq++; + transition(SentReinviteAnswered); + handleSessionTimerResponse(msg); + // mLastSessionModification = msg; // ?slg? why are we storing 200's? + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mProposedRemoteOfferAnswer = offerAnswer; + handler->onOffer(getSessionHandle(), msg, *mProposedRemoteOfferAnswer); + break; + } + + case On2xx: + mStaleReInviteTimerSeq++; + sendAck(); + transition(Connected); + handleSessionTimerResponse(msg); + handler->onIllegalNegotiation(getSessionHandle(), msg); + mProposedLocalOfferAnswer.reset(); + mProposedEncryptionLevel = DialogUsageManager::None; + break; + + case On422Invite: + mStaleReInviteTimerSeq++; + if(msg.exists(h_MinSE)) + { + // Change interval to min from 422 response + mSessionInterval = msg.header(h_MinSE).value(); + mMinSE = mSessionInterval; + sessionRefresh(); + } + else + { + // Response must contact Min_SE - if not - just ignore + // ?slg? callback? + transition(Connected); + mProposedLocalOfferAnswer.reset(); + mProposedEncryptionLevel = DialogUsageManager::None; + } + break; + + case On491Invite: + mStaleReInviteTimerSeq++; + transition(SentReinviteNoOfferGlare); + start491Timer(); + break; + + case OnGeneralFailure: + mStaleReInviteTimerSeq++; + sendBye(); + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + break; + + case OnInviteFailure: + case On487Invite: + mStaleReInviteTimerSeq++; + transition(Connected); + mProposedLocalOfferAnswer.reset(); + handler->onOfferRejected(getSessionHandle(), &msg); + break; + + default: + dispatchOthers(msg); + break; + } +} + +void +InviteSession::dispatchReceivedReinviteSentOffer(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnInvite: + case OnInviteReliable: + case OnInviteOffer: + case OnInviteReliableOffer: + case OnUpdate: + case OnUpdateOffer: + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 491); + send(response); + break; + } + case OnAckAnswer: + transition(Connected); + setCurrentLocalOfferAnswer(msg); + mCurrentRemoteOfferAnswer = offerAnswer; + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + + handler->onAnswer(getSessionHandle(), msg, *mCurrentRemoteOfferAnswer); + break; + case OnAck: + if (mLastRemoteSessionModification->header(h_CSeq).sequence() > msg.header(h_CSeq).sequence()) + { + InfoLog(<< "dropped stale ACK"); + } + else + { + InfoLog(<< "Got Ack with no answer"); + transition(Connected); + mProposedLocalOfferAnswer.reset(); + mProposedEncryptionLevel = DialogUsageManager::None; + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + //!dcm! -- should this be onIllegalNegotiation? + handler->onOfferRejected(getSessionHandle(), &msg); + } + break; + default: + dispatchOthers(msg); + break; + } +} + +void +InviteSession::dispatchGlare(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + MethodTypes method = msg.header(h_CSeq).method(); + if (msg.isRequest() && (method == INVITE || method == UPDATE)) + { + DebugLog(<< "Re-INVITE or UPDATE received when in SentReinviteGlare or SentUpdateGlare" << endl); + // Received inbound reinvite or update, when waiting to resend outbound reinvite or update + handler->onOfferRejected(getSessionHandle(), &msg); + if(!isTerminated()) // make sure application didn't call end() + { + dispatchConnected(msg); // act as if we received message in Connected state + } + else + { + dispatchTerminated(msg); + } + } + else + { + dispatchOthers(msg); + } +} + +void +InviteSession::dispatchReinviteNoOfferGlare(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + MethodTypes method = msg.header(h_CSeq).method(); + if (msg.isRequest() && (method == INVITE || method == UPDATE)) + { + // Received inbound reinvite or update, when waiting to resend outbound reinvite or update + handler->onOfferRequestRejected(getSessionHandle(), msg); + if(!isTerminated()) // make sure application didn't call end() + { + dispatchConnected(msg); // act as if we received message in Connected state + } + else + { + dispatchTerminated(msg); + } + } + else + { + dispatchOthers(msg); + } +} + +void +InviteSession::dispatchReceivedUpdateOrReinvite(const SipMessage& msg) +{ + // InviteSessionHandler* handler = mDum.mInviteSessionHandler; // unused + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnInvite: + case OnInviteReliable: + case OnInviteOffer: + case OnInviteReliableOffer: + case OnUpdate: + case OnUpdateOffer: + { + // Means that the UAC has sent us a second reINVITE or UPDATE before we + // responded to the first one. Bastard! + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 500); + response->header(h_RetryAfter).value() = Random::getRandom() % 10; + send(response); + break; + } + case OnBye: + { + // BYE received after a reINVITE, terminate the reINVITE transaction. + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, *mLastRemoteSessionModification, 487); // Request Terminated + handleSessionTimerRequest(*response, *mLastRemoteSessionModification); + send(response); + + dispatchBye(msg); + break; + } + default: + dispatchOthers(msg); + break; + } +} + + +void +InviteSession::dispatchAnswered(const SipMessage& msg) +{ + if (msg.isRequest() && msg.header(h_RequestLine).method() == ACK) + { + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + transition(Connected); + } + else + { + dispatchOthers(msg); + } +} + +void +InviteSession::dispatchSentReinviteAnswered(const SipMessage& msg) +{ + if (msg.isResponse() && + msg.header(h_CSeq).method() == INVITE && + msg.header(h_StatusLine).statusCode() / 200 == 1) + { + // Receving a 200 retransmission is possible - but we don't have an ACK response yet - we are still waiting for provideAnswer to be + // called by the app - so just drop the retransmission + return; + } + dispatchOthers(msg); +} + +void +InviteSession::dispatchWaitingToOffer(const SipMessage& msg) +{ + if (msg.isRequest() && msg.header(h_RequestLine).method() == ACK) + { + assert(mProposedLocalOfferAnswer.get()); + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + provideProposedOffer(); + } + else + { + dispatchOthers(msg); + } +} + +void +InviteSession::dispatchWaitingToRequestOffer(const SipMessage& msg) +{ + if (msg.isRequest() && msg.header(h_RequestLine).method() == ACK) + { + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + requestOffer(); + } + else + { + dispatchOthers(msg); + } +} + +void +InviteSession::dispatchWaitingToTerminate(const SipMessage& msg) +{ + if (msg.isResponse() && + msg.header(h_CSeq).method() == INVITE) + { + if(msg.header(h_StatusLine).statusCode() / 200 == 1) // Note: stack ACK's non-2xx final responses only + { + // !jf! Need to include the answer here. + sendAck(); + } + SharedPtr<SipMessage> msg = sendBye(); + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); + } + else if(msg.isRequest()) + { + if(msg.method() == BYE) + { + dispatchBye(msg); + } + else + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 400 /* Bad Request */); + send(response); + } + } +} + +void +InviteSession::dispatchWaitingToHangup(const SipMessage& msg) +{ + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnAck: + case OnAckAnswer: + { + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + + SharedPtr<SipMessage> msg = sendBye(); + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); + break; + } + + default: + break; + } +} + +void +InviteSession::dispatchTerminated(const SipMessage& msg) +{ + InfoLog (<< "InviteSession::dispatchTerminated " << msg.brief()); + + if (msg.isRequest()) + { + if (BYE == msg.header(h_CSeq).method()) + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 200); + send(response); + } + else + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 481); + send(response); + } + + // !jf! means the peer sent BYE while we are waiting for response to BYE + //mDum.destroy(this); + } + else + { + mDum.destroy(this); + } +} + +void +InviteSession::dispatchOthers(const SipMessage& msg) +{ + // handle OnGeneralFailure + // handle OnRedirect + + switch (msg.header(h_CSeq).method()) + { + case PRACK: + dispatchPrack(msg); + break; + case CANCEL: + dispatchCancel(msg); + break; + case BYE: + dispatchBye(msg); + break; + case INFO: + dispatchInfo(msg); + break; + case MESSAGE: + dispatchMessage(msg); + break; + case ACK: + // Ignore duplicate ACKs from 2xx reTransmissions + break; + default: + // handled in Dialog + WarningLog (<< "DUM delivered a " + << msg.header(h_CSeq).unknownMethodName() + << " to the InviteSession in state: " << toData(mState) + << endl + << msg); + assert(0); + break; + } +} + +void +InviteSession::dispatchUnhandledInvite(const SipMessage& msg) +{ + assert(msg.isRequest()); + assert(msg.header(h_CSeq).method() == INVITE); + + // If we get an INVITE request from the wire and we are not in + // Connected state, reject the request and send a BYE + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 400); // !jf! what code to use? + InfoLog (<< "Sending " << response->brief()); + send(response); + + sendBye(); + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); +} + +void +InviteSession::dispatchPrack(const SipMessage& msg) +{ + assert(msg.header(h_CSeq).method() == PRACK); + if(msg.isRequest()) + { + SharedPtr<SipMessage> rsp(new SipMessage); + mDialog.makeResponse(*rsp, msg, 481); + send(rsp); + + sendBye(); + // !jf! should we make some other callback here + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + } + else + { + // ignore. could be PRACK/200 + } +} + +void +InviteSession::dispatchCancel(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + assert(msg.header(h_CSeq).method() == CANCEL); + if(msg.isRequest()) + { + SharedPtr<SipMessage> rsp(new SipMessage); + mDialog.makeResponse(*rsp, msg, 200); + send(rsp); + + sendBye(); + // !jf! should we make some other callback here + transition(Terminated); + + handler->onTerminated(getSessionHandle(), InviteSessionHandler::RemoteCancel, &msg); + } + else + { + WarningLog (<< "DUM let me send a CANCEL at an incorrect state " << endl << msg); + assert(0); + } +} + +void +InviteSession::dispatchBye(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + + if (msg.isRequest()) + { + // Check for any non-invite server transactions (e.g. INFO) + // that have not been responded yet and terminate them. + if (mServerNitState == NitProceeding) + { + mLastNitResponse->header(h_StatusLine).statusCode() = 487; + mLastNitResponse->setContents(0); + Helper::getResponseCodeReason(487, mLastNitResponse->header(h_StatusLine).reason()); + send(mLastNitResponse); + mServerNitState = NitComplete; + } + + SharedPtr<SipMessage> rsp(new SipMessage); + InfoLog (<< "Received " << msg.brief()); + mDialog.makeResponse(*rsp, msg, 200); + send(rsp); + + // !jf! should we make some other callback here + transition(Terminated); + + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTerminated(mDialog, msg, InviteSessionHandler::RemoteBye); + } + + handler->onTerminated(getSessionHandle(), InviteSessionHandler::RemoteBye, &msg); + mDum.destroy(this); + } + else + { + WarningLog (<< "DUM let me send a BYE at an incorrect state " << endl << msg); + assert(0); + } +} + +void +InviteSession::dispatchInfo(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + if (msg.isRequest()) + { + if (mServerNitState == NitProceeding) + { + // Means that the UAC has sent us a second INFO before we + // responded to the first one. + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 500); + response->header(h_RetryAfter).value() = Random::getRandom() % 10; + send(response); + } + else + { + InfoLog (<< "Received " << msg.brief()); + mServerNitState = NitProceeding; + mDialog.makeResponse(*mLastNitResponse, msg, 200); + handler->onInfo(getSessionHandle(), msg); + } + } + else + { + assert(mNitState == NitProceeding); + //!dcm! -- toss away 1xx to an info? + if (msg.header(h_StatusLine).statusCode() >= 300) + { + handler->onInfoFailure(getSessionHandle(), msg); + } + else if (msg.header(h_StatusLine).statusCode() >= 200) + { + handler->onInfoSuccess(getSessionHandle(), msg); + } + nitComplete(); + } +} + +void +InviteSession::acceptNIT(int statusCode, const Contents * contents) +{ + if (statusCode / 100 != 2) + { + throw UsageUseException("Must accept with a 2xx", __FILE__, __LINE__); + } + + if (mServerNitState != NitProceeding ) + { + throw UsageUseException("No transaction to accept", __FILE__, __LINE__); + } + + mLastNitResponse->header(h_StatusLine).statusCode() = statusCode; + mLastNitResponse->setContents(contents); + Helper::getResponseCodeReason(statusCode, mLastNitResponse->header(h_StatusLine).reason()); + send(mLastNitResponse); + mServerNitState = NitComplete; +} + +class InviteSessionAcceptNITCommand : public DumCommandAdapter +{ +public: + InviteSessionAcceptNITCommand(InviteSession& inviteSession, int statusCode, const Contents* contents) + : mInviteSession(inviteSession), + mStatusCode(statusCode), + mContents(contents?contents->clone():0) + { + + } + + virtual void executeCommand() + { + mInviteSession.acceptNITCommand(mStatusCode, mContents.get()); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "InviteSessionAcceptNITCommand"; + } +private: + InviteSession& mInviteSession; + int mStatusCode; + std::auto_ptr<Contents> mContents; +}; + +void +InviteSession::acceptNITCommand(int statusCode, const Contents* contents) +{ + mDum.post(new InviteSessionAcceptNITCommand(*this, statusCode, contents)); +} + +void +InviteSession::rejectNIT(int statusCode) +{ + if (statusCode < 400) + { + throw UsageUseException("Must reject with a >= 4xx", __FILE__, __LINE__); + } + + if (mServerNitState != NitProceeding ) + { + throw UsageUseException("No transaction to reject", __FILE__, __LINE__); + } + + mLastNitResponse->header(h_StatusLine).statusCode() = statusCode; + mLastNitResponse->setContents(0); + Helper::getResponseCodeReason(statusCode, mLastNitResponse->header(h_StatusLine).reason()); + send(mLastNitResponse); + mServerNitState = NitComplete; +} + +class InviteSessionRejectNITCommand : public DumCommandAdapter +{ +public: + InviteSessionRejectNITCommand(InviteSession& inviteSession, int statusCode) + : mInviteSession(inviteSession), + mStatusCode(statusCode) + { + } + + virtual void executeCommand() + { + mInviteSession.rejectNITCommand(mStatusCode); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "InviteSessionRejectNITCommand"; + } +private: + InviteSession& mInviteSession; + int mStatusCode; +}; + +void +InviteSession::rejectNITCommand(int statusCode) +{ + mDum.post(new InviteSessionRejectNITCommand(*this, statusCode)); +} + +void +InviteSession::dispatchMessage(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + if (msg.isRequest()) + { + if (mServerNitState == NitProceeding) + { + // Means that the UAC has sent us a second NIT message before we + // responded to the first one. + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 500); + response->header(h_RetryAfter).value() = Random::getRandom() % 10; + send(response); + } + else + { + InfoLog (<< "Received " << msg.brief()); + mServerNitState = NitProceeding; + mDialog.makeResponse(*mLastNitResponse, msg, 200); + mLastNitResponse->header(h_Contacts).clear(); + handler->onMessage(getSessionHandle(), msg); + } + } + else + { + assert(mNitState == NitProceeding); + //!dcm! -- toss away 1xx to an message? + if (msg.header(h_StatusLine).statusCode() >= 300) + { + handler->onMessageFailure(getSessionHandle(), msg); + } + else if (msg.header(h_StatusLine).statusCode() >= 200) + { + handler->onMessageSuccess(getSessionHandle(), msg); + } + nitComplete(); + } +} + +void +InviteSession::startRetransmit200Timer() +{ + mCurrentRetransmit200 = Timer::T1; + unsigned int seq = mLastRemoteSessionModification->header(h_CSeq).sequence(); + mDum.addTimerMs(DumTimeout::Retransmit200, mCurrentRetransmit200, getBaseHandle(), seq); + mDum.addTimerMs(DumTimeout::WaitForAck, Timer::TH, getBaseHandle(), seq); +} + +// RFC3261 section 14.1 +// If a UAC receives a 491 response to a re-INVITE, it SHOULD start a timer with +// a value T chosen as follows: +// 1. If the UAC is the owner of the Call-ID of the dialog ID, T has a randomly +// chosen value between 2.1 and 4 seconds in units of 10 ms. +// 2. If the UAC is not the owner of the Call-ID of the dialog ID, T has a +// randomly chosen value of between 0 and 2 seconds in units of 10 ms. +void +InviteSession::start491Timer() +{ + unsigned int seq = mLastLocalSessionModification->header(h_CSeq).sequence(); + + if (dynamic_cast<ClientInviteSession*>(this)) + { + int timer = Random::getRandom() % (4000 - 2100); + timer += 2100; + timer -= timer % 10; + + DebugLog(<< "491 timer value: " << timer << "ms" << endl); + mDum.addTimerMs(DumTimeout::Glare, timer, getBaseHandle(), seq); + } + else + { + int timer = Random::getRandom() % 2000; + timer -= timer % 10; + DebugLog(<< "491 timer value: " << timer << "ms" << endl); + mDum.addTimerMs(DumTimeout::Glare, timer, getBaseHandle(), seq); + } +} + +void +InviteSession::startStaleReInviteTimer() +{ + InfoLog (<< toData(mState) << ": startStaleReInviteTimer"); + unsigned long when = mDialog.mDialogSet.getUserProfile()->getDefaultStaleReInviteTime(); + + mDum.addTimer(DumTimeout::StaleReInvite, + when, + getBaseHandle(), + ++mStaleReInviteTimerSeq); +} + +void +InviteSession::setSessionTimerHeaders(SipMessage &msg) +{ + if(mSessionInterval >= 90) // If mSessionInterval is 0 then SessionTimers are considered disabled + { + msg.header(h_SessionExpires).value() = mSessionInterval; + if(msg.isRequest()) + { + msg.header(h_SessionExpires).param(p_refresher) = Data(mSessionRefresher ? "uac" : "uas"); + } + else + { + msg.header(h_SessionExpires).param(p_refresher) = Data(mSessionRefresher ? "uas" : "uac"); + } + msg.header(h_MinSE).value() = mMinSE; + } + else + { + msg.remove(h_SessionExpires); + msg.remove(h_MinSE); + } +} + +void +InviteSession::sessionRefresh() +{ + if (updateMethodSupported()) + { + transition(SentUpdate); + mDialog.makeRequest(*mLastLocalSessionModification, UPDATE); + mLastLocalSessionModification->setContents(0); // Don't send SDP + } + else + { + transition(SentReinvite); + mDialog.makeRequest(*mLastLocalSessionModification, INVITE); + startStaleReInviteTimer(); + InviteSession::setOfferAnswer(*mLastLocalSessionModification, mCurrentLocalOfferAnswer.get()); + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(*mCurrentLocalOfferAnswer.get(), 0); + mSessionRefreshReInvite = true; + } + setSessionTimerHeaders(*mLastLocalSessionModification); + + InfoLog (<< "sessionRefresh: Sending " << mLastLocalSessionModification->brief()); + DumHelper::setOutgoingEncryptionLevel(*mLastLocalSessionModification, mCurrentEncryptionLevel); + send(mLastLocalSessionModification); +} + +void +InviteSession::setSessionTimerPreferences() +{ + mSessionInterval = mDialog.mDialogSet.getUserProfile()->getDefaultSessionTime(); // Used only if remote doesn't request a time + if(mSessionInterval != 0) + { + // If session timers are no disabled then ensure interval is greater than or equal to MinSE + mSessionInterval = resipMax(mMinSE, mSessionInterval); + } + switch(mDialog.mDialogSet.getUserProfile()->getDefaultSessionTimerMode()) + { + case Profile::PreferLocalRefreshes: + mSessionRefresher = true; // Default refresher is Local + break; + case Profile::PreferRemoteRefreshes: + mSessionRefresher = false; // Default refresher is Remote + break; + case Profile::PreferCalleeRefreshes: + mSessionRefresher = dynamic_cast<ServerInviteSession*>(this) != NULL; // Default refresher is callee + break; + case Profile::PreferCallerRefreshes: + mSessionRefresher = dynamic_cast<ClientInviteSession*>(this) != NULL; // Default refresher is caller + break; + } +} + +void +InviteSession::startSessionTimer() +{ + if(mSessionInterval >= 90) // 90 is the absolute minimum - RFC4028 + { + // Check if we are the refresher + if(mSessionRefresher) + { + // Start Session-Refresh Timer to mSessionInterval / 2 (recommended by RFC4028) + mDum.addTimer(DumTimeout::SessionRefresh, mSessionInterval / 2, getBaseHandle(), ++mSessionTimerSeq); + } + else + { + // Start Session-Expiration Timer to mSessionInterval - BYE should be sent a minimum of 32 and one third of the SessionInterval, seconds before the session expires (recommended by RFC4028) + mDum.addTimer(DumTimeout::SessionExpiration, mSessionInterval - resipMin((UInt32)32,mSessionInterval/3), getBaseHandle(), ++mSessionTimerSeq); + } + } + else // Session Interval less than 90 - consider timers disabled + { + ++mSessionTimerSeq; // increment seq, incase old timers are running and now session timers are disabled + } +} + +void +InviteSession::handleSessionTimerResponse(const SipMessage& msg) +{ + assert(msg.header(h_CSeq).method() == INVITE || msg.header(h_CSeq).method() == UPDATE); + + // Allow Re-Invites and Updates to update the Peer P-Asserted-Identity + if (msg.exists(h_PAssertedIdentities)) + { + mPeerPAssertedIdentities = msg.header(h_PAssertedIdentities); + } + + // If session timers are locally supported then handle response + if(mDum.getMasterProfile()->getSupportedOptionTags().find(Token(Symbols::Timer))) + { + setSessionTimerPreferences(); + + if(msg.exists(h_Requires) && msg.header(h_Requires).find(Token(Symbols::Timer)) + && !msg.exists(h_SessionExpires)) + { + // If no Session Expires in response and Requires header is present then session timer is to be 'turned off' + mSessionInterval = 0; + } + // Process Session Timer headers + else if(msg.exists(h_SessionExpires)) + { + mSessionInterval = msg.header(h_SessionExpires).value(); + if(msg.header(h_SessionExpires).exists(p_refresher)) + { + // Remote end specified refresher preference + mSessionRefresher = (msg.header(h_SessionExpires).param(p_refresher) == Data("uac")); + } + } + else + { + // Note: If no Requires or Session-Expires, then UAS does not support Session Timers + // - we are free to use our SessionInterval settings (set above as a default) + // If far end doesn't support then refresher must be local + mSessionRefresher = true; + } + + // Update MinSE if specified and longer than current value + if(msg.exists(h_MinSE)) + { + mMinSE = resipMax(mMinSE, msg.header(h_MinSE).value()); + } + + startSessionTimer(); + } +} + +void +InviteSession::handleSessionTimerRequest(SipMessage &response, const SipMessage& request) +{ + assert(request.header(h_CSeq).method() == INVITE || request.header(h_CSeq).method() == UPDATE); + + // Allow Re-Invites and Updates to update the Peer P-Asserted-Identity + if (request.exists(h_PAssertedIdentities)) + { + mPeerPAssertedIdentities = request.header(h_PAssertedIdentities); + } + + // If session timers are locally supported then add necessary headers to response + if(mDum.getMasterProfile()->getSupportedOptionTags().find(Token(Symbols::Timer))) + { + setSessionTimerPreferences(); + + // Check if far-end supports + bool farEndSupportsTimer = false; + if(request.exists(h_Supporteds) && request.header(h_Supporteds).find(Token(Symbols::Timer))) + { + farEndSupportsTimer = true; + if(request.exists(h_SessionExpires)) + { + // Use Session Interval requested by remote - if none then use local settings + mSessionInterval = request.header(h_SessionExpires).value(); + if(request.header(h_SessionExpires).exists(p_refresher)) + { + mSessionRefresher = (request.header(h_SessionExpires).param(p_refresher) == Data("uas")); + } + } + + // Update MinSE if specified and longer than current value + if(request.exists(h_MinSE)) + { + mMinSE = resipMax(mMinSE, request.header(h_MinSE).value()); + } + } + else + { + // If far end doesn't support then refresher must be local + mSessionRefresher = true; + } + + // Add Session-Expires to response if required + if(mSessionInterval >= 90) + { + if(farEndSupportsTimer) + { + // If far end supports session-timer then require it, if not already present + if(!response.header(h_Requires).find(Token(Symbols::Timer))) + { + response.header(h_Requires).push_back(Token(Symbols::Timer)); + } + } + setSessionTimerHeaders(response); + } + + startSessionTimer(); + } +} + +Data +InviteSession::toData(State state) +{ + switch (state) + { + case Undefined: + return "InviteSession::Undefined"; + case Connected: + return "InviteSession::Connected"; + case SentUpdate: + return "InviteSession::SentUpdate"; + case SentUpdateGlare: + return "InviteSession::SentUpdateGlare"; + case SentReinvite: + return "InviteSession::SentReinvite"; + case SentReinviteGlare: + return "InviteSession::SentReinviteGlare"; + case SentReinviteNoOffer: + return "InviteSession::SentReinviteNoOffer"; + case SentReinviteAnswered: + return "InviteSession::SentReinviteAnswered"; + case SentReinviteNoOfferGlare: + return "InviteSession::SentReinviteNoOfferGlare"; + case ReceivedUpdate: + return "InviteSession::ReceivedUpdate"; + case ReceivedReinvite: + return "InviteSession::ReceivedReinvite"; + case ReceivedReinviteNoOffer: + return "InviteSession::ReceivedReinviteNoOffer"; + case ReceivedReinviteSentOffer: + return "InviteSession::ReceivedReinviteSentOffer"; + case Answered: + return "InviteSession::Answered"; + case WaitingToOffer: + return "InviteSession::WaitingToOffer"; + case WaitingToRequestOffer: + return "InviteSession::WaitingToRequestOffer"; + case WaitingToTerminate: + return "InviteSession::WaitingToTerminate"; + case WaitingToHangup: + return "InviteSession::WaitingToHangup"; + case Terminated: + return "InviteSession::Terminated"; + + case UAC_Start: + return "UAC_Start"; + case UAS_Offer: + return "UAS_Offer"; + case UAS_OfferProvidedAnswer: + return "UAS_OfferProvidedAnswer"; + case UAS_EarlyOffer: + return "UAS_EarlyOffer"; + case UAS_EarlyProvidedAnswer: + return "UAS_EarlyProvidedAnswer"; + case UAS_NoOffer: + return "UAS_NoOffer"; + case UAS_ProvidedOffer: + return "UAS_ProvidedOffer"; + case UAS_EarlyNoOffer: + return "UAS_EarlyNoOffer"; + case UAS_EarlyProvidedOffer: + return "UAS_EarlyProvidedOffer"; + case UAS_Accepted: + return "UAS_Accepted"; + case UAS_WaitingToOffer: + return "UAS_WaitingToOffer"; + case UAS_AcceptedWaitingAnswer: + return "UAS_AcceptedWaitingAnswer"; + case UAC_Early: + return "UAC_Early"; + case UAC_EarlyWithOffer: + return "UAC_EarlyWithOffer"; + case UAC_EarlyWithAnswer: + return "UAC_EarlyWithAnswer"; + case UAC_Answered: + return "UAC_Answered"; + case UAC_SentUpdateEarly: + return "UAC_SentUpdateEarly"; + case UAC_SentUpdateEarlyGlare: + return "UAC_SentUpdateEarlyGlare"; + case UAC_ReceivedUpdateEarly: + return "UAC_ReceivedUpdateEarly"; + case UAC_SentAnswer: + return "UAC_SentAnswer"; + case UAC_QueuedUpdate: + return "UAC_QueuedUpdate"; + case UAC_Cancelled: + return "UAC_Cancelled"; + + case UAS_Start: + return "UAS_Start"; + case UAS_ReceivedOfferReliable: + return "UAS_ReceivedOfferReliable"; + case UAS_NoOfferReliable: + return "UAS_NoOfferReliable"; + case UAS_FirstSentOfferReliable: + return "UAS_FirstSentOfferReliable"; + case UAS_FirstSentAnswerReliable: + return "UAS_FirstSentAnswerReliable"; + case UAS_NegotiatedReliable: + return "UAS_NegotiatedReliable"; + case UAS_SentUpdate: + return "UAS_SentUpdate"; + case UAS_SentUpdateAccepted: + return "UAS_SentUpdateAccepted"; + case UAS_ReceivedUpdate: + return "UAS_ReceivedUpdate"; + case UAS_ReceivedUpdateWaitingAnswer: + return "UAS_ReceivedUpdateWaitingAnswer"; + case UAS_WaitingToTerminate: + return "UAS_WaitingToTerminate"; + case UAS_WaitingToHangup: + return "UAS_WaitingToHangup"; + case UAS_WaitingToRequestOffer: + return "UAS_WaitingToRequestOffer"; + } + assert(0); + return "Undefined"; +} + + +void +InviteSession::transition(State target) +{ + InfoLog (<< "Transition " << toData(mState) << " -> " << toData(target)); + mState = target; +} + +bool +InviteSession::isReliable(const SipMessage& msg) +{ + if(msg.method() != INVITE) + { + return false; + } + if(msg.isRequest()) + { + return mDum.getMasterProfile()->getUasReliableProvisionalMode() > MasterProfile::Never + && ((msg.exists(h_Supporteds) && msg.header(h_Supporteds).find(Token(Symbols::C100rel))) + || (msg.exists(h_Requires) && msg.header(h_Requires).find(Token(Symbols::C100rel)))); + } + else + { + return mDum.getMasterProfile()->getUacReliableProvisionalMode() > MasterProfile::Never + && msg.exists(h_Requires) && msg.header(h_Requires).find(Token(Symbols::C100rel)); + } +} + +//static std::auto_ptr<SdpContents> emptySdp; +std::auto_ptr<Contents> +InviteSession::getOfferAnswer(const SipMessage& msg) +{ + if(mDum.mInviteSessionHandler->isGenericOfferAnswer()) + { + if(msg.getContents()) + { + return std::auto_ptr<Contents>(msg.getContents()->clone()); + } + else + { + return std::auto_ptr<Contents>(); + } + } + else + { + return std::auto_ptr<Contents>(Helper::getSdp(msg.getContents())); + } +} + +std::auto_ptr<Contents> +InviteSession::makeOfferAnswer(const Contents& offerAnswer) +{ + return std::auto_ptr<Contents>(static_cast<Contents*>(offerAnswer.clone())); +} + +auto_ptr<Contents> +InviteSession::makeOfferAnswer(const Contents& offerAnswer, + const Contents* alternative) +{ + if (alternative) + { + MultipartAlternativeContents* mac = new MultipartAlternativeContents; + mac->parts().push_back(alternative->clone()); + mac->parts().push_back(offerAnswer.clone()); + return auto_ptr<Contents>(mac); + } + else + { + return auto_ptr<Contents>(offerAnswer.clone()); + } +} + +void +InviteSession::setOfferAnswer(SipMessage& msg, const Contents& offerAnswer, const Contents* alternative) +{ + // !jf! should deal with multipart here + + // This will clone the offerAnswer since the InviteSession also wants to keep its own + // copy of the offerAnswer around for the application to access + if (alternative) + { + MultipartAlternativeContents* mac = new MultipartAlternativeContents; + mac->parts().push_back(alternative->clone()); + mac->parts().push_back(offerAnswer.clone()); + msg.setContents(auto_ptr<Contents>(mac)); + } + else + { + msg.setContents(&offerAnswer); + } +} + +void +InviteSession::setOfferAnswer(SipMessage& msg, const Contents* offerAnswer) +{ + assert(offerAnswer); + msg.setContents(offerAnswer); +} + +void +InviteSession::provideProposedOffer() +{ + MultipartAlternativeContents* mp_ans = + dynamic_cast<MultipartAlternativeContents*>(mProposedLocalOfferAnswer.get()); + if (mp_ans) + { + // .kw. can cast below ever be NULL? Need assert/throw? + provideOffer( *(dynamic_cast<Contents*>((mp_ans)->parts().back())), + mProposedEncryptionLevel, + dynamic_cast<Contents*>((mp_ans)->parts().front())); + } + else + { + // .kw. can cast below ever be NULL? Need assert/throw? + provideOffer(*(dynamic_cast<Contents*>(mProposedLocalOfferAnswer.get())), mProposedEncryptionLevel, 0); + } +} + +InviteSession::Event +InviteSession::toEvent(const SipMessage& msg, const Contents* offerAnswer) +{ + MethodTypes method = msg.header(h_CSeq).method(); + int code = msg.isResponse() ? msg.header(h_StatusLine).statusCode() : 0; + + //.dcm. Treat an invite as reliable if UAS 100rel support is enabled. For + //responses, reiable provisionals should only be received if the invite was + //sent reliably. Spurious reliable provisional respnoses are dropped outside + //the state machine. + bool reliable = isReliable(msg); + bool sentOffer = mProposedLocalOfferAnswer.get(); + + if (code == 481 || code == 408) + { + return OnGeneralFailure; + } + else if (code >= 300 && code <= 399) + { + return OnRedirect; + } + else if (method == INVITE && code == 0) + { + if (offerAnswer) + { + if (reliable) + { + return OnInviteReliableOffer; + } + else + { + return OnInviteOffer; + } + } + else + { + if (reliable) + { + return OnInviteReliable; + } + else + { + return OnInvite; + } + } + } + else if (method == INVITE && code > 100 && code < 200) + { + if (reliable) + { + if (offerAnswer) + { + if (sentOffer) + { + return On1xxAnswer; + } + else + { + return On1xxOffer; + } + } + else + { + return On1xx; + } + } + else + { + if (offerAnswer) + { + return On1xxEarly; + } + else + { + return On1xx; + } + } + } + else if (method == INVITE && code >= 200 && code < 300) + { + if (offerAnswer) + { + if (sentOffer) + { + return On2xxAnswer; + } + else + { + return On2xxOffer; + } + } + else + { + return On2xx; + } + } + else if (method == INVITE && code == 422) + { + return On422Invite; + } + else if (method == INVITE && code == 487) + { + return On487Invite; + } + else if (method == INVITE && code == 491) + { + return On491Invite; + } + else if (method == INVITE && code >= 400) + { + return OnInviteFailure; + } + else if (method == ACK) + { + if (offerAnswer) + { + return OnAckAnswer; + } + else + { + return OnAck; + } + } + else if (method == CANCEL && code == 0) + { + return OnCancel; + } + else if (method == CANCEL && code / 200 == 1) + { + return On200Cancel; + } + else if (method == CANCEL && code >= 400) + { + return OnCancelFailure; + } + else if (method == BYE && code == 0) + { + return OnBye; + } + else if (method == BYE && code / 200 == 1) + { + return On200Bye; + } + else if (method == PRACK && code == 0) + { + return OnPrack; + } + else if (method == PRACK && code / 200 == 1) + { + return On200Prack; + } + else if (method == UPDATE && code == 0) + { + if (offerAnswer) + { + return OnUpdateOffer; + } + else + { + return OnUpdate; + } + } + else if (method == UPDATE && code / 200 == 1) + { + return On200Update; + } + else if (method == UPDATE && code == 422) + { + return On422Update; + } + else if (method == UPDATE && code == 491) + { + return On491Update; + } + else if (method == UPDATE && code >= 400) + { + return OnUpdateRejected; + } + else + { + //assert(0); // dispatchOthers will throw if the message type is really unknown + return Unknown; + } +} + +void +InviteSession::sendAck(const Contents *answer) +{ + SharedPtr<SipMessage> ack(new SipMessage); + + SharedPtr<SipMessage> source; + + if (mLastLocalSessionModification->method() == UPDATE) + { + //.dcm. scary--we could make a special ClientInviteSession variable/sendAck + source = mDialog.mDialogSet.getCreator()->getLastRequest(); + } + else + { + source = mLastLocalSessionModification; + } + + assert(mAcks.count(source->getTransactionId()) == 0); + + mDialog.makeRequest(*ack, ACK); + + // Copy Authorization and Proxy Authorization headers from + // mLastLocalSessionModification; regardless of whether this was the original + // INVITE or not, this is the correct place to go for auth headers. + if(mLastLocalSessionModification->exists(h_Authorizations)) + { + ack->header(h_Authorizations) = mLastLocalSessionModification->header(h_Authorizations); + } + if(mLastLocalSessionModification->exists(h_ProxyAuthorizations)) + { + ack->header(h_ProxyAuthorizations) = mLastLocalSessionModification->header(h_ProxyAuthorizations); + } + + // Copy CSeq from original INVITE + ack->header(h_CSeq).sequence() = source->header(h_CSeq).sequence(); + + if(answer != 0) + { + setOfferAnswer(*ack, *answer); + } + mAcks[source->getTransactionId()] = ack; + mDum.addTimerMs(DumTimeout::CanDiscardAck, Timer::TH, getBaseHandle(), ack->header(h_CSeq).sequence(), 0, source->getTransactionId()); + + InfoLog (<< "Sending " << ack->brief()); + send(ack); +} + +SharedPtr<SipMessage> +InviteSession::sendBye() +{ + SharedPtr<SipMessage> bye(new SipMessage()); + mDialog.makeRequest(*bye, BYE); + Data txt; + if (mEndReason != NotSpecified) + { + Token reason("SIP"); + txt = getEndReasonString(mEndReason); + reason.param(p_text) = txt; + bye->header(h_Reasons).push_back(reason); + } + + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTerminated(mDialog, *bye, InviteSessionHandler::LocalBye); + } + + InfoLog (<< myAddr() << " Sending BYE " << txt); + send(bye); + return bye; +} + +DialogUsageManager::EncryptionLevel +InviteSession::getEncryptionLevel(const SipMessage& msg) +{ + DialogUsageManager::EncryptionLevel level = DialogUsageManager::None; + const SecurityAttributes* secAttr = msg.getSecurityAttributes(); + if (secAttr) + { + SignatureStatus sig = secAttr->getSignatureStatus(); + bool sign = (SignatureTrusted == sig || SignatureCATrusted == sig || SignatureSelfSigned == sig); + bool encrypted = secAttr->isEncrypted(); + if (encrypted && sign ) level = DialogUsageManager::SignAndEncrypt; + else if (encrypted) level = DialogUsageManager::Encrypt; + else if (sign) level = DialogUsageManager::Sign; + } + return level; +} + +void +InviteSession::setCurrentLocalOfferAnswer(const SipMessage& msg) +{ + assert(mProposedLocalOfferAnswer.get()); + if (dynamic_cast<MultipartAlternativeContents*>(mProposedLocalOfferAnswer.get())) + { + if (DialogUsageManager::Encrypt == getEncryptionLevel(msg) || DialogUsageManager::SignAndEncrypt == getEncryptionLevel(msg)) + { + mCurrentLocalOfferAnswer = auto_ptr<Contents>(static_cast<Contents*>((dynamic_cast<MultipartAlternativeContents*>(mProposedLocalOfferAnswer.get()))->parts().back()->clone())); + } + else + { + mCurrentLocalOfferAnswer = auto_ptr<Contents>(static_cast<Contents*>((dynamic_cast<MultipartAlternativeContents*>(mProposedLocalOfferAnswer.get()))->parts().front()->clone())); + } + } + else + { + mCurrentLocalOfferAnswer = auto_ptr<Contents>(static_cast<Contents*>(mProposedLocalOfferAnswer.get()->clone())); + } + mProposedLocalOfferAnswer.reset(); +} + +void +InviteSession::onReadyToSend(SipMessage& msg) +{ + mDum.mInviteSessionHandler->onReadyToSend(getSessionHandle(), msg); +} + +void +InviteSession::flowTerminated() +{ + // notify handler + mDum.mInviteSessionHandler->onFlowTerminated(getSessionHandle()); +} + +void +InviteSession::referNoSub(const SipMessage& msg) +{ + assert(msg.isRequest() && msg.header(h_CSeq).method()==REFER); + mLastReferNoSubRequest = msg; + mDum.mInviteSessionHandler->onReferNoSub(getSessionHandle(), mLastReferNoSubRequest); +} + +void +InviteSession::acceptReferNoSub(int statusCode) +{ + if (statusCode / 100 != 2) + { + throw UsageUseException("Must accept with a 2xx", __FILE__, __LINE__); + } + + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, mLastReferNoSubRequest, statusCode); + response->header(h_ReferSub).value() = "false"; + //response->header(h_Supporteds).push_back(Token(Symbols::NoReferSub)); + + send(response); +} + +void +InviteSession::rejectReferNoSub(int responseCode) +{ + if (responseCode < 400) + { + throw UsageUseException("Must reject with a >= 4xx", __FILE__, __LINE__); + } + + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, mLastReferNoSubRequest, responseCode); + send(response); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + + + diff --git a/src/libs/resiprocate/resip/dum/InviteSession.hxx b/src/libs/resiprocate/resip/dum/InviteSession.hxx new file mode 100644 index 00000000..9fdda3c6 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InviteSession.hxx @@ -0,0 +1,481 @@ +#if !defined(RESIP_INVITESESSION_HXX) +#define RESIP_INVITESESSION_HXX + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Contents.hxx" +#include "resip/dum/DialogUsage.hxx" +#include "resip/dum/DialogUsageManager.hxx" + +#include <map> +#include <queue> + +namespace resip +{ + +class Contents; +class SdpContents; + +/** Base class for class ClientInviteSession and class ServerInviteSession. + Implements common attributes and behavior (i.e.t post connected) of the two + classes. +*/ +class InviteSession : public DialogUsage +{ + public: + bool canProvideOffer(); + + /** Called to set the offer that will be used in the next message that + sends an offer. If possible, this will synchronously send the + appropriate request or response. In some cases, the UAS might have to + call accept in order to cause the message to be sent. */ + virtual void provideOffer(const Contents& offer); + virtual void provideOffer(const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative); + + /** Similar to provideOffer - called to set the answer to be signalled to + the peer. May result in message being sent synchronously depending on + the state. */ + virtual void provideAnswer(const Contents& answer); + + /** Called to request that the far end provide an offer. This will cause a + reinvite with no body to be sent. */ + virtual void requestOffer(); + + typedef enum + { + None, // means no Offer or Answer (may have body) + Offer, + Answer + } OfferAnswerType; + + // WARNING: Do not change this list without appropriately adjusting the + // EndReasons array in InviteSession.cxx + enum EndReason + { + NotSpecified=0, + UserHangup, + AppRejectedSdp, + IllegalNegotiation, + AckNotReceived, + SessionExpired, + StaleReInvite, + ENDREASON_MAX, // Maximum used by the global array in InviteSession.cxx + UserSpecified // User-specified reason - doesn't use the array in InviteSession.cxx + }; + + /** Makes the specific dialog end. Will send a BYE (not a CANCEL) */ + virtual void end(const Data& userReason); + virtual void end(EndReason reason); + virtual void end(); // reason == NotSpecified ; same as above - required for BaseUsage pure virtual + + /** Rejects an offer at the SIP level. Can also be used to + send a 488 to a reINVITE or UPDATE */ + virtual void reject(int statusCode, WarningCategory *warning = 0); + + /** will send a reINVITE (current offerAnswer) or UPDATE with new Contact header */ + virtual void targetRefresh(const NameAddr& localUri); + + // Following methods are for sending requests within a dialog + + /** sends a refer request */ + virtual void refer(const NameAddr& referTo, bool referSub = true); + virtual void refer(const NameAddr& referTo, std::auto_ptr<resip::Contents> contents, bool referSub = true); + + /** sends a refer request with a replaces header */ + virtual void refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub = true); + virtual void refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, std::auto_ptr<resip::Contents> contents, bool referSub = true); + virtual void refer(const NameAddr& referTo, const CallId& replaces, bool referSub = true); + virtual void refer(const NameAddr& referTo, const CallId& replaces, std::auto_ptr<resip::Contents> contents, bool referSub = true); + + /** sends an info request */ + virtual void info(const Contents& contents); + + /** sends a message request + + @warning From RFC3428 - The authors recognize that there may be valid reasons to + send MESSAGE requests in the context of a dialog. For + example, one participant in a voice session may wish to + send an IM to another participant, and associate that IM + with the session. But implementations SHOULD NOT create + dialogs for the primary purpose of associating MESSAGE + requests with one another. + */ + virtual void message(const Contents& contents); + + /** accepts an INFO or MESSAGE request with a 2xx and an optional contents */ + virtual void acceptNIT(int statusCode = 200, const Contents * contents = 0); + + /** rejects an INFO or MESSAGE request with an error status code */ + virtual void rejectNIT(int statusCode = 488); + + /** gets the last NIT request that was sent by the session + + @warning Can return a NULL SharedPtr if none was sent + */ + const SharedPtr<SipMessage> getLastSentNITRequest() const; + + /** + * Provide asynchronous method access by using command + */ + virtual void provideOfferCommand(const Contents& offer); + virtual void provideOfferCommand(const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative); + virtual void provideAnswerCommand(const Contents& answer); + /** Asynchronously makes the specific dialog end. Will send a BYE (not a CANCEL) */ + virtual void endCommand(EndReason reason = NotSpecified); + /** Asynchronously rejects an offer at the SIP level. Can also be used to + send a 488 to a reINVITE or UPDATE */ + virtual void rejectCommand(int statusCode, WarningCategory *warning = 0); + virtual void referCommand(const NameAddr& referTo, bool referSub = true); + virtual void referCommand(const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub = true); + virtual void infoCommand(const Contents& contents); + virtual void messageCommand(const Contents& contents); + /** Asynchronously accepts an INFO or MESSAGE request with a 2xx and an optional contents */ + virtual void acceptNITCommand(int statusCode = 200, const Contents * contents = 0); + /** Asynchronously rejects an INFO or MESSAGE request with an error status code */ + virtual void rejectNITCommand(int statusCode = 488); + + virtual void acceptReferNoSub(int statusCode = 200); + virtual void rejectReferNoSub(int responseCode); + + bool hasLocalOfferAnswer() const; + const Contents& getLocalOfferAnswer() const; + bool hasRemoteOfferAnswer() const; + const Contents& getRemoteOfferAnswer() const; + bool hasProposedRemoteOfferAnswer() const; + const Contents& getProposedRemoteOfferAnswer() const; + + // Note: The following fn's are for backwards compatibility and are only valid to call + // if the InviteSessionHandler is not in Generic mode (ie. + // InviteSessionHandler::isGenericOfferAnswer is false) + bool hasLocalSdp() const; + const SdpContents& getLocalSdp() const; + bool hasRemoteSdp() const; + const SdpContents& getRemoteSdp() const; + bool hasProposedRemoteSdp() const; + const SdpContents& getProposedRemoteSdp() const; + + bool isConnected() const; + bool isTerminated() const; + bool isEarly() const; // UAC Early states + bool isAccepted() const; // UAS States after accept is called + + Tokens& getPeerSupportedMethods() { return mPeerSupportedMethods; } + Tokens& getPeerSupportedOptionTags() { return mPeerSupportedOptionTags; } + Mimes& getPeerSupportedMimeTypes() { return mPeerSupportedMimeTypes; } + Tokens& getPeerSupportedEncodings() { return mPeerSupportedEncodings; } + Tokens& getPeerSupportedLanguages() { return mPeerSupportedLanguages; } + Tokens& getPeerAllowedEvents() { return mPeerAllowedEvents; } + Data& getPeerUserAgent() { return mPeerUserAgent; } + NameAddrs& getPeerPAssertedIdentities() { return mPeerPAssertedIdentities; } + + virtual EncodeStream& dump(EncodeStream& strm) const; + InviteSessionHandle getSessionHandle(); + + protected: + + typedef enum + { + Undefined, // Not used + Connected, + SentUpdate, // Sent an UPDATE + SentUpdateGlare, // got a 491 + SentReinvite, // Sent a reINVITE + SentReinviteGlare, // Got a 491 + SentReinviteNoOffer, // Sent a reINVITE with no offer (requestOffer) + SentReinviteAnswered, // Sent a reINVITE no offer and received a 200-offer + SentReinviteNoOfferGlare, // Got a 491 + ReceivedUpdate, // Received an UPDATE + ReceivedReinvite, // Received a reINVITE + ReceivedReinviteNoOffer, // Received a reINVITE with no offer + ReceivedReinviteSentOffer, // Sent a 200 to a reINVITE with no offer + Answered, + WaitingToOffer, + WaitingToRequestOffer, + WaitingToTerminate, // Waiting for 2xx response before sending BYE + WaitingToHangup, // Waiting for ACK before sending BYE + Terminated, // Ended. waiting to delete + + UAC_Start, + UAC_Early, + UAC_EarlyWithOffer, + UAC_EarlyWithAnswer, + UAC_Answered, + UAC_SentUpdateEarly, + UAC_SentUpdateEarlyGlare, + UAC_ReceivedUpdateEarly, + UAC_SentAnswer, + UAC_QueuedUpdate, + UAC_Cancelled, + + UAS_Start, + UAS_Offer, + UAS_OfferProvidedAnswer, + UAS_EarlyOffer, + UAS_EarlyProvidedAnswer, + + UAS_NoOffer, + UAS_ProvidedOffer, + UAS_EarlyNoOffer, + UAS_EarlyProvidedOffer, + UAS_Accepted, + UAS_WaitingToOffer, + UAS_WaitingToRequestOffer, + + UAS_AcceptedWaitingAnswer, + UAS_ReceivedOfferReliable, + UAS_NoOfferReliable, + UAS_FirstSentOfferReliable, + UAS_FirstSentAnswerReliable, + UAS_NegotiatedReliable, + UAS_SentUpdate, + UAS_SentUpdateAccepted, + UAS_ReceivedUpdate, + UAS_ReceivedUpdateWaitingAnswer, + UAS_WaitingToTerminate, + UAS_WaitingToHangup + } State; + + typedef enum + { + OnRedirect, // 3xx + OnGeneralFailure, // 481 or 408 + OnInvite, // UAS + OnInviteOffer,// UAS + OnInviteReliableOffer, // UAS + OnInviteReliable, // UAS + OnCancel, // UAS + OnBye, + On200Bye, + On1xx, // UAC + On1xxEarly, // UAC + On1xxOffer, // UAC + On1xxAnswer, // UAC + On2xx, + On2xxOffer, + On2xxAnswer, + On422Invite, + On487Invite, + On491Invite, + OnInviteFailure, + OnAck, + OnAckAnswer, + On200Cancel, // UAC + OnCancelFailure, // UAC + OnUpdate, + OnUpdateOffer, + OnUpdateRejected, + On422Update, + On491Update, + On200Update, + OnPrack, // UAS + On200Prack, // UAC + Unknown + } Event; + + typedef enum + { + NitComplete, + NitProceeding + } NitState; + + InviteSession(DialogUsageManager& dum, Dialog& dialog); + virtual ~InviteSession(); + virtual void dialogDestroyed(const SipMessage& msg); + virtual void onReadyToSend(SipMessage& msg); + virtual void flowTerminated(); + + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + // Utility methods (one for each State) + void dispatchConnected(const SipMessage& msg); + void dispatchSentUpdate(const SipMessage& msg); + void dispatchSentReinvite(const SipMessage& msg); + void dispatchSentReinviteNoOffer(const SipMessage& msg); + void dispatchSentReinviteAnswered(const SipMessage& msg); + void dispatchGlare(const SipMessage& msg); + void dispatchReinviteNoOfferGlare(const SipMessage& msg); + void dispatchReceivedUpdateOrReinvite(const SipMessage& msg); + void dispatchReceivedReinviteSentOffer(const SipMessage& msg); + void dispatchAnswered(const SipMessage& msg); + void dispatchWaitingToOffer(const SipMessage& msg); + void dispatchWaitingToRequestOffer(const SipMessage& msg); + void dispatchWaitingToTerminate(const SipMessage& msg); + void dispatchWaitingToHangup(const SipMessage& msg); + void dispatchTerminated(const SipMessage& msg); + void dispatchBye(const SipMessage& msg); + void dispatchInfo(const SipMessage& msg); + void dispatchMessage(const SipMessage& msg); + + void startRetransmit200Timer(); + void start491Timer(); + void startStaleReInviteTimer(); + + void setSessionTimerHeaders(SipMessage& msg); + void sessionRefresh(); + void setSessionTimerPreferences(); + void startSessionTimer(); + void handleSessionTimerResponse(const SipMessage& msg); + void handleSessionTimerRequest(SipMessage &response, const SipMessage& request); + + static Data toData(State state); + void transition(State target); + + std::auto_ptr<Contents> getOfferAnswer(const SipMessage& msg); + bool isReliable(const SipMessage& msg); + static std::auto_ptr<Contents> makeOfferAnswer(const Contents& offerAnswer); + static std::auto_ptr<Contents> makeOfferAnswer(const Contents& offerAnswer, const Contents* alternative); + static void setOfferAnswer(SipMessage& msg, const Contents& offerAnswer, const Contents* alternative = 0); + static void setOfferAnswer(SipMessage& msg, const Contents* offerAnswer); + void provideProposedOffer(); + + void storePeerCapabilities(const SipMessage& msg); + bool updateMethodSupported() const; + + void sendAck(const Contents *answer=0); + SharedPtr<SipMessage> sendBye(); + + const Data& getEndReasonString(InviteSession::EndReason reason); + + DialogUsageManager::EncryptionLevel getEncryptionLevel(const SipMessage& msg); + void setCurrentLocalOfferAnswer(const SipMessage& msg); + void referNoSub(const SipMessage& msg); + + Tokens mPeerSupportedMethods; + Tokens mPeerSupportedOptionTags; + Mimes mPeerSupportedMimeTypes; + Tokens mPeerSupportedEncodings; + Tokens mPeerSupportedLanguages; + Tokens mPeerAllowedEvents; + Data mPeerUserAgent; + NameAddrs mPeerPAssertedIdentities; + + Event toEvent(const SipMessage& msg, const Contents* offeranswer); + + State mState; + NitState mNitState; + NitState mServerNitState; + + std::auto_ptr<Contents> mCurrentLocalOfferAnswer; + std::auto_ptr<Contents> mProposedLocalOfferAnswer; + + std::auto_ptr<Contents> mCurrentRemoteOfferAnswer; + std::auto_ptr<Contents> mProposedRemoteOfferAnswer; + + SharedPtr<SipMessage> mLastLocalSessionModification; // last UPDATE or reINVITE sent + SharedPtr<SipMessage> mLastRemoteSessionModification; // last UPDATE or reINVITE received + SharedPtr<SipMessage> mInvite200; // 200 OK for reINVITE for retransmissions + SharedPtr<SipMessage> mLastNitResponse; // + //?dcm? -- ptr, delete when not needed? + + SipMessage mLastReferNoSubRequest; + + unsigned long mCurrentRetransmit200; + unsigned int mStaleReInviteTimerSeq; + + // Session Timer settings + UInt32 mSessionInterval; + UInt32 mMinSE; + bool mSessionRefresher; + unsigned int mSessionTimerSeq; + bool mSessionRefreshReInvite; + + class QueuedNIT + { + public: + QueuedNIT(SharedPtr<SipMessage> NIT, bool referSub=false) + : mNIT(NIT), mReferSubscription(referSub) {} + SharedPtr<SipMessage>& getNIT() { return mNIT; } + bool referSubscription() { return mReferSubscription; } + private: + SharedPtr<SipMessage> mNIT; + bool mReferSubscription; + }; + std::queue<QueuedNIT*> mNITQueue; + void nitComplete(); + bool mReferSub; + SharedPtr<SipMessage> mLastSentNITRequest; + + DialogUsageManager::EncryptionLevel mCurrentEncryptionLevel; + DialogUsageManager::EncryptionLevel mProposedEncryptionLevel; // UPDATE or RE-INVITE + + EndReason mEndReason; + + // Used when a user-specified EndReason is needed + Data mUserEndReason; + + // Used to respond to 2xx retransmissions. + typedef HashMap<Data, SharedPtr<SipMessage> > AckMap; + AckMap mAcks; + + private: + friend class Dialog; + friend class DialogUsageManager; + + // disabled + InviteSession(const InviteSession&); + InviteSession& operator=(const InviteSession&); + + // Utility methods for handling particular methods + void dispatchOthers(const SipMessage& msg); + void dispatchUnhandledInvite(const SipMessage& msg); + void dispatchPrack(const SipMessage& msg); + void dispatchCancel(const SipMessage& msg); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + + + + diff --git a/src/libs/resiprocate/resip/dum/InviteSessionCreator.cxx b/src/libs/resiprocate/resip/dum/InviteSessionCreator.cxx new file mode 100644 index 00000000..54b8c9a8 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InviteSessionCreator.cxx @@ -0,0 +1,145 @@ +#include "resip/stack/MultipartMixedContents.hxx" +#include "resip/stack/MultipartAlternativeContents.hxx" +#include "resip/dum/InviteSessionCreator.hxx" +#include "resip/stack/SdpContents.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/DumHelper.hxx" + +using namespace resip; + +InviteSessionCreator::InviteSessionCreator(DialogUsageManager& dum, + const NameAddr& target, + SharedPtr<UserProfile> userProfile, + const Contents* initial, + DialogUsageManager::EncryptionLevel level, + const Contents* alternative, + ServerSubscriptionHandle serverSub) + : BaseCreator(dum, userProfile), + mState(Initialized), + mServerSub(serverSub), + mEncryptionLevel(level) +{ + makeInitialRequest(target, INVITE); + if (userProfile->isAnonymous()) + { + mLastRequest->header(h_Privacys).push_back(PrivacyCategory(Symbols::id)); + } + + DumHelper::setOutgoingEncryptionLevel(*mLastRequest, level); + if(mDum.getMasterProfile()->getSupportedOptionTags().find(Token(Symbols::Timer))) + { + assert(userProfile.get()); + if(userProfile->getDefaultSessionTime() >= 90) + { + getLastRequest()->header(h_SessionExpires).value() = userProfile->getDefaultSessionTime(); + getLastRequest()->header(h_MinSE).value() = 90; // Absolute minimum specified by RFC4028 + } + } + + std::auto_ptr<Contents> initialOffer; + if (initial) + { + if (alternative) + { + MultipartAlternativeContents* mac = new MultipartAlternativeContents; + mac->parts().push_back(alternative->clone()); + mac->parts().push_back(initial->clone()); + initialOffer.reset(mac); + } + else + { + initialOffer.reset(initial->clone()); + } + getLastRequest()->setContents(initialOffer); + } + //100rel + switch(mDum.getMasterProfile()->getUacReliableProvisionalMode()) + { + case MasterProfile::Never: + //no support, do nothing + break; + case MasterProfile::Supported: + getLastRequest()->header(h_Supporteds).push_back(Token(Symbols::C100rel)); + break; + case MasterProfile::Required: + getLastRequest()->header(h_Requires).push_back(Token(Symbols::C100rel)); + break; + default: + assert(0); + } +} + +InviteSessionCreator::~InviteSessionCreator() +{ +} + +void +InviteSessionCreator::end() +{ + assert(0); +} + +void +InviteSessionCreator::dispatch(const SipMessage& msg) +{ + // !jf! does this have to do with CANCELing all of the branches associated + // with a single invite request +} + +const Contents* +InviteSessionCreator::getInitialOffer() +{ + return getLastRequest()->getContents(); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/InviteSessionCreator.hxx b/src/libs/resiprocate/resip/dum/InviteSessionCreator.hxx new file mode 100644 index 00000000..ee80a634 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InviteSessionCreator.hxx @@ -0,0 +1,104 @@ +#if !defined(RESIP_INVITESESSIONCREATOR_HXX) +#define RESIP_INVITESESSIONCREATOR_HXX + +#include "resip/dum/BaseCreator.hxx" +#include "resip/dum/Handles.hxx" +#include "resip/dum/DialogUsageManager.hxx" + +namespace resip +{ + +class DialogUsageManager; +class Uri; +class Contents; + +class InviteSessionCreator : public BaseCreator +{ + public: + InviteSessionCreator(DialogUsageManager& dum, + const NameAddr& target, + SharedPtr<UserProfile> userProfile, + const Contents* initial, + DialogUsageManager::EncryptionLevel level, + const Contents* alternative, + ServerSubscriptionHandle serverSub = ServerSubscriptionHandle::NotValid()); + + virtual ~InviteSessionCreator(); + void end(); + + virtual void dispatch(const SipMessage& msg); + const Contents* getInitialOffer(); + + ServerSubscriptionHandle getServerSubscription() { return mServerSub; } + + DialogUsageManager::EncryptionLevel getEncryptionLevel() const + { + return mEncryptionLevel; + } + + private: + typedef enum + { + Initialized, + Trying, + Proceeding + } State; + + State mState; + ServerSubscriptionHandle mServerSub; + DialogUsageManager::EncryptionLevel mEncryptionLevel; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/InviteSessionHandler.cxx b/src/libs/resiprocate/resip/dum/InviteSessionHandler.cxx new file mode 100644 index 00000000..167c1099 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InviteSessionHandler.cxx @@ -0,0 +1,175 @@ +#include "resip/dum/AppDialogSet.hxx" +#include "resip/dum/InviteSessionHandler.hxx" +#include "resip/dum/ClientInviteSession.hxx" +#include "resip/stack/SdpContents.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +void +InviteSessionHandler::onEarlyMedia(ClientInviteSessionHandle h, const SipMessage& msg, const Contents& body) +{ + if(!mGenericOfferAnswer) + { + const SdpContents* sdp = dynamic_cast<const SdpContents*>(&body); + assert(sdp); + onEarlyMedia(h, msg, *sdp); + } +} + +void +InviteSessionHandler::onStaleCallTimeout(ClientInviteSessionHandle handle) +{ + InfoLog(<< "InviteSessionHandler::onStaleCallTimeout"); +} + +void +InviteSessionHandler::terminate(ClientInviteSessionHandle h) +{ + h->getAppDialogSet()->end(); +} + +void +InviteSessionHandler::onAckReceived(InviteSessionHandle, const SipMessage& msg) +{ +} + +void +InviteSessionHandler::onAckNotReceived(InviteSessionHandle handle) +{ + InfoLog(<< "InviteSessionHandler::onAckNotReceived"); + handle->end(InviteSession::AckNotReceived); +} + +void +InviteSessionHandler::onStaleReInviteTimeout(InviteSessionHandle handle) +{ + InfoLog(<< "InviteSessionHandler::onStaleReInviteTimeout"); + handle->end(InviteSession::StaleReInvite); +} + +void +InviteSessionHandler::onIllegalNegotiation(InviteSessionHandle handle, const SipMessage& msg) +{ + InfoLog(<< "InviteSessionHandler::onIllegalNegotiation"); +} + +void +InviteSessionHandler::onSessionExpired(InviteSessionHandle handle) +{ + InfoLog(<< "InviteSessionHandler::onSessionExpired"); + handle->end(InviteSession::SessionExpired); +} + +void +InviteSessionHandler::onAnswer(InviteSessionHandle h, const SipMessage& msg, const Contents& body) +{ + if(!mGenericOfferAnswer) + { + const SdpContents* sdp = dynamic_cast<const SdpContents*>(&body); + assert(sdp); + onAnswer(h, msg, *sdp); + } +} + +void +InviteSessionHandler::onOffer(InviteSessionHandle h, const SipMessage& msg, const Contents& body) +{ + if(!mGenericOfferAnswer) + { + const SdpContents* sdp = dynamic_cast<const SdpContents*>(&body); + assert(sdp); + onOffer(h, msg, *sdp); + } +} + +void +InviteSessionHandler::onRemoteSdpChanged(InviteSessionHandle, const SipMessage& msg, const SdpContents&) +{ +} + +void +InviteSessionHandler::onRemoteAnswerChanged(InviteSessionHandle h, const SipMessage& msg, const Contents& body) +{ + if(!mGenericOfferAnswer) + { + const SdpContents* sdp = dynamic_cast<const SdpContents*>(&body); + assert(sdp); + onRemoteSdpChanged(h, msg, *sdp); + } +} + +void +InviteSessionHandler::onReadyToSend(InviteSessionHandle, SipMessage& msg) +{ + // default is to do nothing. this is for adornment +} + +void +InviteSessionHandler::onOfferRequestRejected(InviteSessionHandle, const SipMessage& msg) +{ +} + +void +InviteSessionHandler::onConnectedConfirmed(InviteSessionHandle handle, const SipMessage& msg) +{ +} + +void +InviteSessionHandler::onFlowTerminated(InviteSessionHandle) +{ + InfoLog(<< "InviteSessionHandler::onFlowTerminated"); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/InviteSessionHandler.hxx b/src/libs/resiprocate/resip/dum/InviteSessionHandler.hxx new file mode 100644 index 00000000..05fcc705 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InviteSessionHandler.hxx @@ -0,0 +1,251 @@ +#if !defined(RESIP_INVITESESSIONHANDLER_HXX) +#define RESIP_INVITESESSIONHANDLER_HXX + +#include "resip/dum/InviteSession.hxx" +#include "resip/dum/Handles.hxx" + +namespace resip +{ + +class SipMessage; +class SdpContents; +class Contents; + +/** + Base class for class InviteSessionHandler. The application must override this class + and provide an imlementation of the handlers below. The class must then be set as + an invite session handler on dum (DialogUsageManager::setInviteSessionHandler()). + + If you wish to handle invite session offer/answers using generic contents instead of + SDP, then construct this class with a bool argument of true, and be sure to add + implementations of all of the handlers below that take a Contents parameter type + (ie. onEarlyMedia, onOffer, onAnswer, and onRemoteAnswerChanged). Overriding these + methods will cause their SdpContent counterparts to not be called. You can then provide + a basic empty body implementation of these SdpContent versions of the callbacks. + + Example handler for generic (non-sdp only) invite sessions: + class MyInviteSessionHandler : public InviteSessionHandler + { + MyInviteSessionHandler() : InviteSessionHandler(true) {}; + ... + virtual void onOffer(InviteSessionHandle, const SipMessage& msg, const SdpContents&) + {} // No body required + virtual void onOffer(InviteSessionHandle, const SipMessage& msg, const Contents&) + { + // Add handler body here + } + ... + }; +*/ +class InviteSessionHandler +{ + public: + InviteSessionHandler(bool genericOfferAnswer=false) : mGenericOfferAnswer(genericOfferAnswer) {} + virtual ~InviteSessionHandler() {} + virtual bool isGenericOfferAnswer() { return mGenericOfferAnswer; } + + /// called when an initial INVITE or the intial response to an outoing invite + virtual void onNewSession(ClientInviteSessionHandle, InviteSession::OfferAnswerType oat, const SipMessage& msg)=0; + virtual void onNewSession(ServerInviteSessionHandle, InviteSession::OfferAnswerType oat, const SipMessage& msg)=0; + + /// Received a failure response from UAS + virtual void onFailure(ClientInviteSessionHandle, const SipMessage& msg)=0; + + /// called when an in-dialog provisional response is received that contains a body + virtual void onEarlyMedia(ClientInviteSessionHandle, const SipMessage&, const SdpContents&)=0; + virtual void onEarlyMedia(ClientInviteSessionHandle, const SipMessage&, const Contents&); + + /// called when dialog enters the Early state - typically after getting 18x + virtual void onProvisional(ClientInviteSessionHandle, const SipMessage&)=0; + + /// called when a dialog initiated as a UAC enters the connected state + virtual void onConnected(ClientInviteSessionHandle, const SipMessage& msg)=0; + + /// called when a dialog initiated as a UAS enters the connected state + virtual void onConnected(InviteSessionHandle, const SipMessage& msg)=0; + + /// called when ACK (with out an answer) is received for initial invite (UAS) + virtual void onConnectedConfirmed(InviteSessionHandle, const SipMessage &msg); + + /** UAC gets no final response within the stale call timeout (default is 3 + * minutes). This is just a notification. After the notification is + * called, the InviteSession will then call + * InviteSessionHandler::terminate() */ + virtual void onStaleCallTimeout(ClientInviteSessionHandle h); + + /** called when an early dialog decides it wants to terminate the + * dialog. Default behavior is to CANCEL all related early dialogs as + * well. */ + virtual void terminate(ClientInviteSessionHandle h); + + /// called when an dialog enters the terminated state - this can happen + /// after getting a BYE, Cancel, or 4xx,5xx,6xx response - or the session + /// times out + enum TerminatedReason + { + Error, + Timeout, + Replaced, + LocalBye, + RemoteBye, + LocalCancel, + RemoteCancel, + Rejected, //Only as UAS, UAC has distinct onFailure callback + Referred + }; + + virtual void onTerminated(InviteSessionHandle, InviteSessionHandler::TerminatedReason reason, const SipMessage* related=0)=0; + + /// called when a fork that was created through a 1xx never receives a 2xx + /// because another fork answered and this fork was canceled by a proxy. + virtual void onForkDestroyed(ClientInviteSessionHandle)=0; + + /// called when a 3xx with valid targets is encountered in an early dialog + /// This is different then getting a 3xx in onTerminated, as another + /// request will be attempted, so the DialogSet will not be destroyed. + /// Basically an onTermintated that conveys more information. + /// checking for 3xx respones in onTerminated will not work as there may + /// be no valid targets. + virtual void onRedirected(ClientInviteSessionHandle, const SipMessage& msg)=0; + + /// called to allow app to adorn a message. default is to send immediately + virtual void onReadyToSend(InviteSessionHandle, SipMessage& msg); + + /// called when an answer is received - has nothing to do with user + /// answering the call + virtual void onAnswer(InviteSessionHandle, const SipMessage& msg, const SdpContents&)=0; + // You should only override the following method if genericOfferAnswer is true + virtual void onAnswer(InviteSessionHandle, const SipMessage& msg, const Contents&); + + /// called when an offer is received - must send an answer soon after this + virtual void onOffer(InviteSessionHandle, const SipMessage& msg, const SdpContents&)=0; + // You should only override the following method if genericOfferAnswer is true + virtual void onOffer(InviteSessionHandle, const SipMessage& msg, const Contents&); + + /// called when a modified body is received in a 2xx response to a + /// session-timer reINVITE. Under normal circumstances where the response + /// body is unchanged from current remote body no handler is called + virtual void onRemoteSdpChanged(InviteSessionHandle, const SipMessage& msg, const SdpContents&); + // You should only override the following method if genericOfferAnswer is true + virtual void onRemoteAnswerChanged(InviteSessionHandle, const SipMessage& msg, const Contents&); + + /// Called when an error response is received for a reinvite-nobody request (via requestOffer) + virtual void onOfferRequestRejected(InviteSessionHandle, const SipMessage& msg); + + /// called when an Invite w/out offer is sent, or any other context which + /// requires an offer from the user + virtual void onOfferRequired(InviteSessionHandle, const SipMessage& msg)=0; + + /// called if an offer in a UPDATE or re-INVITE was rejected - not real + /// useful. A SipMessage is provided if one is available + virtual void onOfferRejected(InviteSessionHandle, const SipMessage* msg)=0; + + /// called when INFO message is received + virtual void onInfo(InviteSessionHandle, const SipMessage& msg)=0; + + /// called when response to INFO message is received + virtual void onInfoSuccess(InviteSessionHandle, const SipMessage& msg)=0; + virtual void onInfoFailure(InviteSessionHandle, const SipMessage& msg)=0; + + /// called when MESSAGE message is received + virtual void onMessage(InviteSessionHandle, const SipMessage& msg)=0; + + /// called when response to MESSAGE message is received + virtual void onMessageSuccess(InviteSessionHandle, const SipMessage& msg)=0; + virtual void onMessageFailure(InviteSessionHandle, const SipMessage& msg)=0; + + /// called when an REFER message is received. The refer is accepted or + /// rejected using the server subscription. If the offer is accepted, + /// DialogUsageManager::makeInviteSessionFromRefer can be used to create an + /// InviteSession that will send notify messages using the ServerSubscription + virtual void onRefer(InviteSessionHandle, ServerSubscriptionHandle, const SipMessage& msg)=0; + + virtual void onReferNoSub(InviteSessionHandle, const SipMessage& msg)=0; + + /// called when an REFER message receives a failure response + virtual void onReferRejected(InviteSessionHandle, const SipMessage& msg)=0; + + /// called when an REFER message receives an accepted response + virtual void onReferAccepted(InviteSessionHandle, ClientSubscriptionHandle, const SipMessage& msg)=0; + + /// called when ACK is received + virtual void onAckReceived(InviteSessionHandle, const SipMessage& msg); + + /// default behaviour is to send a BYE to end the dialog + virtual void onAckNotReceived(InviteSessionHandle); + + /// UAC gets no final response within the stale re-invite timeout (default is 40 + /// seconds). Default behaviour is to send a BYE to end the dialog. + virtual void onStaleReInviteTimeout(InviteSessionHandle h); + + /// will be called if reINVITE or UPDATE in dialog fails + virtual void onIllegalNegotiation(InviteSessionHandle, const SipMessage& msg); + + /// will be called if Session-Timers are used and Session Timer expires + /// default behaviour is to send a BYE to send the dialog + virtual void onSessionExpired(InviteSessionHandle); + + /// Called when a TCP or TLS flow to the server has terminated. This can be caused by socket + /// errors, or missing CRLF keep alives pong responses from the server. + // Called only if clientOutbound is enabled on the UserProfile and the first hop server + /// supports RFC5626 (outbound). + /// Default implementation is to do nothing + virtual void onFlowTerminated(InviteSessionHandle); + + private: + bool mGenericOfferAnswer; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/KeepAliveManager.cxx b/src/libs/resiprocate/resip/dum/KeepAliveManager.cxx new file mode 100644 index 00000000..4b10f248 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/KeepAliveManager.cxx @@ -0,0 +1,207 @@ +#include "resip/stack/KeepAliveMessage.hxx" +#include "resip/stack/InteropHelper.hxx" +#include "resip/dum/KeepAliveManager.hxx" +#include "resip/dum/KeepAliveTimeout.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/SipStack.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; +using namespace std; + +int KeepAliveManager::mKeepAlivePongTimeoutMs = 10000; // Defaults to 10000ms (10s) as specified in RFC5626 section 4.4.1 + +void +KeepAliveManager::add(const Tuple& target, int keepAliveInterval, bool targetSupportsOutbound) +{ + assert(mDum); + NetworkAssociationMap::iterator it = mNetworkAssociations.find(target); + if (it == mNetworkAssociations.end()) + { + DebugLog(<< "First keep alive for id=" << mCurrentId << ": " << target << ", interval=" + << keepAliveInterval << "s, supportsOutbound=" << (targetSupportsOutbound ? "true" : "false")); + + NetworkAssociationInfo info; + info.refCount = 1; + info.keepAliveInterval = keepAliveInterval; + info.id = mCurrentId; + info.supportsOutbound = targetSupportsOutbound; + info.pongReceivedForLastPing = false; + mNetworkAssociations.insert(NetworkAssociationMap::value_type(target, info)); + KeepAliveTimeout t(target, mCurrentId); + SipStack &stack = mDum->getSipStack(); + if(targetSupportsOutbound) + { + // Used randomized timeout between 80% and 100% of keepalivetime + stack.post(t, Helper::jitterValue(keepAliveInterval, 80, 100), mDum); + } + else + { + stack.post(t, keepAliveInterval, mDum); + } + ++mCurrentId; + } + else + { + it->second.refCount++; + if(keepAliveInterval < it->second.keepAliveInterval || targetSupportsOutbound) // if targetSupportsOutbound, then always update the interval, as value may be from Flow-Timer header + { + // ?slg? only allow value to be shortened??? What if 2 different profiles + // with different keepAliveTime settings are sharing this network association? + it->second.keepAliveInterval = keepAliveInterval; + } + if(targetSupportsOutbound) + { + // allow this to be updated to true only. If any usage get's an indication of + // outbound support on this flow, then we accept it + it->second.supportsOutbound = targetSupportsOutbound; + } + DebugLog(<< "Association added for keep alive id=" << it->second.id << ": " << target + << ", interval=" << it->second.keepAliveInterval << "s, supportsOutbound=" + << (it->second.supportsOutbound ? "true" : "false") + << ", refCount=" << it->second.refCount); + } +} + +void +KeepAliveManager::remove(const Tuple& target) +{ + NetworkAssociationMap::iterator it = mNetworkAssociations.find(target); + if (it != mNetworkAssociations.end()) + { + if (0 == --it->second.refCount) + { + DebugLog(<< "Last association removed for keep alive id=" << it->second.id << ": " << target); + mNetworkAssociations.erase(it); + } + else + { + DebugLog(<< "Association removed for keep alive id=" << it->second.id << ": " << target << ", refCount=" << it->second.refCount); + } + } +} + +void +KeepAliveManager::process(KeepAliveTimeout& timeout) +{ + assert(mDum); + static KeepAliveMessage msg; + NetworkAssociationMap::iterator it = mNetworkAssociations.find(timeout.target()); + if (it != mNetworkAssociations.end() && timeout.id() == it->second.id) + { + SipStack &stack = mDum->getSipStack(); + DebugLog(<< "Refreshing keepalive for id=" << it->second.id << ": " << it->first + << ", interval=" << it->second.keepAliveInterval << "s, supportsOutbound=" + << (it->second.supportsOutbound ? "true" : "false") + << ", refCount=" << it->second.refCount); + + if(InteropHelper::getOutboundVersion()>=8 && it->second.supportsOutbound && mKeepAlivePongTimeoutMs > 0) + { + // Assert if keep alive interval is too short in order to properly detect + // missing pong responses - ie. interval must be greater than 10s + assert((it->second.keepAliveInterval*1000) > mKeepAlivePongTimeoutMs); + + // Start pong timeout if transport is TCP based (note: pong processing of Stun messaging is currently not implemented) + if(it->first.getType() == TCP || it->first.getType() == TLS) + { + DebugLog( << "Starting pong timeout for keepalive id " << it->second.id); + KeepAlivePongTimeout t(it->first, it->second.id); + stack.postMS(t, mKeepAlivePongTimeoutMs, mDum); + } + } + it->second.pongReceivedForLastPing = false; // reset flag + + stack.sendTo(msg, timeout.target(), mDum); + KeepAliveTimeout t(it->first, it->second.id); + if(it->second.supportsOutbound) + { + // Used randomized timeout between 80% and 100% of keepalivetime + stack.post(t, Helper::jitterValue(it->second.keepAliveInterval, 80, 100), mDum); + } + else + { + stack.post(t, it->second.keepAliveInterval, mDum); + } + } +} + +void +KeepAliveManager::process(KeepAlivePongTimeout& timeout) +{ + assert(mDum); + NetworkAssociationMap::iterator it = mNetworkAssociations.find(timeout.target()); + if (it != mNetworkAssociations.end() && timeout.id() == it->second.id) + { + if(!it->second.pongReceivedForLastPing) + { + // Timeout expecting pong response + InfoLog(<< "Timed out expecting pong response for keep alive id=" << it->second.id << ": " << it->first); + mDum->getSipStack().terminateFlow(it->first); + } + } +} + +void +KeepAliveManager::receivedPong(const Tuple& flow) +{ + NetworkAssociationMap::iterator it = mNetworkAssociations.find(flow); + if (it != mNetworkAssociations.end()) + { + DebugLog(<< "Received pong response for keep alive id=" << it->second.id << ": " << it->first); + it->second.pongReceivedForLastPing = true; + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/KeepAliveManager.hxx b/src/libs/resiprocate/resip/dum/KeepAliveManager.hxx new file mode 100644 index 00000000..fbf2d0df --- /dev/null +++ b/src/libs/resiprocate/resip/dum/KeepAliveManager.hxx @@ -0,0 +1,106 @@ +#ifndef RESIP_KEEPALIVE_MANAGER_HXX +#define RESIP_KEEPALIVE_MANAGER_HXX + +#include <map> +#include "resip/stack/Tuple.hxx" + +namespace resip +{ + +class KeepAliveTimeout; +class KeepAlivePongTimeout; +class DialogUsageManager; + +class KeepAliveManager +{ + public: + // Defaults to 10000ms (10s) as specified in RFC5626 section 4.4.1 + static int mKeepAlivePongTimeoutMs; // ?slg? move to Profile setting? + + struct NetworkAssociationInfo + { + int refCount; + int keepAliveInterval; // In seconds + int id; + bool supportsOutbound; + bool pongReceivedForLastPing; + }; + + // .slg. We track unique Network Associations per transport transport type, transport family, + // target ip addr, target port, and source/transport flow key + // This means that if we have two different TCP connections to the same destination, + // each originating from a different NIC, then we will send keepalives on each separately. + // For UDP, this is not currently the case, when the transport is bound to any interface + // (ie. 0.0.0.0), as the flow key will be same regardless of the source interface used to + // send the UDP message - fixing this for UDP remains an outstanding item. + typedef std::map<Tuple, NetworkAssociationInfo, Tuple::FlowKeyCompare> NetworkAssociationMap; + + KeepAliveManager() : mCurrentId(0) {} + virtual ~KeepAliveManager() {} + void setDialogUsageManager(DialogUsageManager* dum) { mDum = dum; } + virtual void add(const Tuple& target, int keepAliveInterval, bool targetSupportsOutbound); + virtual void remove(const Tuple& target); + virtual void process(KeepAliveTimeout& timeout); + virtual void process(KeepAlivePongTimeout& timeout); + virtual void receivedPong(const Tuple& flow); + + protected: + DialogUsageManager* mDum; + NetworkAssociationMap mNetworkAssociations; + unsigned int mCurrentId; +}; + +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/KeepAliveTimeout.cxx b/src/libs/resiprocate/resip/dum/KeepAliveTimeout.cxx new file mode 100644 index 00000000..4b74178b --- /dev/null +++ b/src/libs/resiprocate/resip/dum/KeepAliveTimeout.cxx @@ -0,0 +1,120 @@ +#include "resip/stack/ApplicationMessage.hxx" +#include "resip/dum/Handles.hxx" +#include "resip/dum/KeepAliveTimeout.hxx" +#include "resip/stack/Message.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +KeepAliveTimeout::KeepAliveTimeout(const Tuple& target,int id) + : mTarget(target), + mId(id) +{} + +KeepAliveTimeout::KeepAliveTimeout(const KeepAliveTimeout& timeout) + : mTarget(timeout.mTarget), + mId(timeout.mId) +{ +} + +KeepAliveTimeout::~KeepAliveTimeout() +{} + +Message* +KeepAliveTimeout::clone() const +{ + return new KeepAliveTimeout(*this); +} + +EncodeStream& +KeepAliveTimeout::encodeBrief(EncodeStream& strm) const +{ + return encode(strm); +} + +EncodeStream& +KeepAliveTimeout::encode(EncodeStream& strm) const +{ + return strm << "KeepAliveTimeout" << mTarget << "(" << mId << ")"; +} + +KeepAlivePongTimeout::KeepAlivePongTimeout(const Tuple& target,int id) + : mTarget(target), + mId(id) +{} + +KeepAlivePongTimeout::KeepAlivePongTimeout(const KeepAlivePongTimeout& timeout) + : mTarget(timeout.mTarget), + mId(timeout.mId) +{ +} + +KeepAlivePongTimeout::~KeepAlivePongTimeout() +{} + +Message* +KeepAlivePongTimeout::clone() const +{ + return new KeepAlivePongTimeout(*this); +} + +EncodeStream& +KeepAlivePongTimeout::encodeBrief(EncodeStream& strm) const +{ + return encode(strm); +} + +EncodeStream& +KeepAlivePongTimeout::encode(EncodeStream& strm) const +{ + return strm << "KeepAlivePongTimeout" << mTarget << "(" << mId << ")"; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/KeepAliveTimeout.hxx b/src/libs/resiprocate/resip/dum/KeepAliveTimeout.hxx new file mode 100644 index 00000000..e2c54f7f --- /dev/null +++ b/src/libs/resiprocate/resip/dum/KeepAliveTimeout.hxx @@ -0,0 +1,98 @@ +#if !defined(RESIP_KEEPALIVE_TIMEOUT_HXX) +#define RESIP_KEEPALIVE_TIMEOUT_HXX + + +#include "resip/stack/ApplicationMessage.hxx" +#include "resip/stack/Tuple.hxx" +#include "resip/dum/Handles.hxx" + +namespace resip +{ + +class KeepAliveTimeout : public ApplicationMessage +{ + public: + KeepAliveTimeout(const Tuple& target, int id); + KeepAliveTimeout(const KeepAliveTimeout&); + virtual ~KeepAliveTimeout(); + + const Tuple& target() const { return mTarget; } + int id() const { return mId; } + virtual Message* clone() const; + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + Tuple mTarget; + int mId; +}; + +class KeepAlivePongTimeout : public ApplicationMessage +{ + public: + + KeepAlivePongTimeout(const Tuple& target, int id); + KeepAlivePongTimeout(const KeepAlivePongTimeout&); + virtual ~KeepAlivePongTimeout(); + + const Tuple& target() const { return mTarget; } + int id() const { return mId; } + virtual Message* clone() const; + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& strm) const; + private: + Tuple mTarget; + int mId; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/Makefile b/src/libs/resiprocate/resip/dum/Makefile new file mode 100644 index 00000000..d3f532b0 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Makefile @@ -0,0 +1,157 @@ +############################################################################# +# Makefile for building: dum +# Generated by qmake (2.01a) (Qt 4.7.4) on: ?? 19. ??? 13:56:25 2011 +# Project: dum.pro +# Template: lib +# Command: d:\tools\qtsdk\desktop\qt\4.7.4\msvc2008\bin\qmake.exe -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile dum.pro +############################################################################# + +first: debug +install: debug-install +uninstall: debug-uninstall +MAKEFILE = Makefile +QMAKE = d:\tools\qtsdk\desktop\qt\4.7.4\msvc2008\bin\qmake.exe +DEL_FILE = del +CHK_DIR_EXISTS= if not exist +MKDIR = mkdir +COPY = copy /y +COPY_FILE = $(COPY) +COPY_DIR = xcopy /s /q /y /i +INSTALL_FILE = $(COPY_FILE) +INSTALL_PROGRAM = $(COPY_FILE) +INSTALL_DIR = $(COPY_DIR) +DEL_FILE = del +SYMLINK = +DEL_DIR = rmdir +MOVE = move +CHK_DIR_EXISTS= if not exist +MKDIR = mkdir +SUBTARGETS = \ + debug \ + release + +debug: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug +debug-make_default: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug +debug-make_first: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug first +debug-all: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug all +debug-clean: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug clean +debug-distclean: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug distclean +debug-install: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug install +debug-uninstall: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug uninstall +release: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release +release-make_default: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release +release-make_first: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release first +release-all: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release all +release-clean: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release clean +release-distclean: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release distclean +release-install: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release install +release-uninstall: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release uninstall + +Makefile: dum.pro d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008\qmake.conf d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\qconfig.pri \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\modules\qt_webkit_version.pri \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_functions.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_config.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\exclusive_builds.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_pre.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_pre.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug_and_release.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_post.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_post.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\staticlib.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\static.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\rtti.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\exceptions.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\stl.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_exe.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_dll.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\warn_on.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\thread.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\moc.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\windows.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\resources.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\uic.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\yacc.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\lex.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\incredibuild_xge.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\include_source_dir.prf + $(QMAKE) -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile dum.pro +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\qconfig.pri: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\modules\qt_webkit_version.pri: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_functions.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_config.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\exclusive_builds.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_pre.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_pre.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug_and_release.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_post.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_post.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\staticlib.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\static.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\rtti.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\exceptions.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\stl.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_exe.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_dll.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\warn_on.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\thread.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\moc.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\windows.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\resources.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\uic.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\yacc.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\lex.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\incredibuild_xge.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\include_source_dir.prf: +qmake: qmake_all FORCE + @$(QMAKE) -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile dum.pro + +qmake_all: FORCE + +make_default: debug-make_default release-make_default FORCE +make_first: debug-make_first release-make_first FORCE +all: debug-all release-all FORCE +clean: debug-clean release-clean FORCE + -$(DEL_FILE) ..\..\..\..\Libs\compiled\win\dum.ilk + -$(DEL_FILE) vc*.pdb + -$(DEL_FILE) vc*.idb +distclean: debug-distclean release-distclean FORCE + -$(DEL_FILE) Makefile + -$(DEL_FILE) ..\..\..\..\Libs\compiled\win\dum.pdb + +check: first + +debug-mocclean: $(MAKEFILE).Debug + $(MAKE) -f $(MAKEFILE).Debug mocclean +release-mocclean: $(MAKEFILE).Release + $(MAKE) -f $(MAKEFILE).Release mocclean +mocclean: debug-mocclean release-mocclean + +debug-mocables: $(MAKEFILE).Debug + $(MAKE) -f $(MAKEFILE).Debug mocables +release-mocables: $(MAKEFILE).Release + $(MAKE) -f $(MAKEFILE).Release mocables +mocables: debug-mocables release-mocables +FORCE: + +$(MAKEFILE).Debug: Makefile +$(MAKEFILE).Release: Makefile diff --git a/src/libs/resiprocate/resip/dum/MasterProfile.cxx b/src/libs/resiprocate/resip/dum/MasterProfile.cxx new file mode 100644 index 00000000..e1454531 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/MasterProfile.cxx @@ -0,0 +1,483 @@ + +#include "resip/dum/Profile.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/stack/HeaderTypes.hxx" + +using namespace resip; +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + + +// Be sure to look at the documentation of the accessors for +// the members being set by this constructor in the .hxx file +// for the implications of these default values. + +MasterProfile::MasterProfile() : + mValidateContentEnabled(true), + mValidateContentLanguageEnabled(false), + mValidateAcceptEnabled(false), + mAllowBadRegistrationEnabled(false), + mHasServerRegistrationMinExpires(false), + mCheckReqUriInMergeDetectionEnabled(false), + mUacReliableProvisionalMode(Never), + mUasReliableProvisionalMode(Never), + mServerRegistrationMinExpires(0), + mServerRegistrationMaxExpires(UINT_MAX), + mServerRegistrationDefaultExpires(3600) +{ + // Default settings + addSupportedMimeType(INVITE, Mime("application", "sdp")); + addSupportedMimeType(OPTIONS, Mime("application", "sdp")); + addSupportedMimeType(PRACK, Mime("application", "sdp")); + addSupportedMimeType(UPDATE, Mime("application", "sdp")); + addSupportedLanguage(Token("en")); + addSupportedMethod(INVITE); + addSupportedMethod(ACK); + addSupportedMethod(CANCEL); + addSupportedMethod(OPTIONS); + addSupportedMethod(BYE); + addSupportedMethod(UPDATE); + addSupportedScheme(Symbols::Sip); +} + +void +MasterProfile::addSupportedScheme(const Data& scheme) +{ + mSupportedSchemes.insert(scheme); +} + +bool +MasterProfile::isSchemeSupported(const Data& scheme) const +{ + return mSupportedSchemes.count(scheme) != 0; +} + +void +MasterProfile::clearSupportedSchemes() +{ + mSupportedSchemes.clear(); +} + +void +MasterProfile::addSupportedMethod(const MethodTypes& method) +{ + mSupportedMethodTypes.insert(method); + mSupportedMethods.push_back(Token(getMethodName(method))); +} + +bool +MasterProfile::isMethodSupported(MethodTypes method) const +{ + return mSupportedMethodTypes.count(method) != 0; +} + +Tokens +MasterProfile::getAllowedMethods() const +{ + return mSupportedMethods; +} + +Data +MasterProfile::getAllowedMethodsData() const +{ + Data result; + + for (Tokens::const_iterator i = mSupportedMethods.begin(); + i != mSupportedMethods.end(); ++i) + { + if (i != mSupportedMethods.begin()) + { + result += Symbols::COMMA[0]; + } + result += i->value(); + } + + return result; +} + +void +MasterProfile::clearSupportedMethods() +{ + mSupportedMethodTypes.clear(); + mSupportedMethods.clear(); +} + +void +MasterProfile::addSupportedOptionTag(const Token& tag) +{ + if (tag == Token(Symbols::C100rel)) + { + //use enablePrackUas and enablePrackUac + assert(0); + } + mSupportedOptionTags.push_back(tag); +} + +Tokens +MasterProfile::getUnsupportedOptionsTags(const Tokens& requiresOptionTags) +{ + Tokens tokens; + for (Tokens::const_iterator i=requiresOptionTags.begin(); i != requiresOptionTags.end(); ++i) + { + if (!i->isWellFormed()) + { + tokens.push_back(Token("malformedTag")); + } + else if (*i == Token(Symbols::C100rel) && mUasReliableProvisionalMode == Never) + { + tokens.push_back(*i); + } + // if this option is not supported + else if (!mSupportedOptionTags.find(*i)) + { + tokens.push_back(*i); + } + } + + return tokens; +} + +Tokens +MasterProfile::getSupportedOptionTags() const +{ + return mSupportedOptionTags; +} + +void +MasterProfile::clearSupportedOptionTags() +{ + mSupportedOptionTags.clear(); +} + +void +MasterProfile::setUacReliableProvisionalMode(ReliableProvisionalMode mode) +{ + mUacReliableProvisionalMode = mode; +} + +void +MasterProfile::setUasReliableProvisionalMode(ReliableProvisionalMode mode) +{ + //.dcm. not supported yet + assert(0); + mUasReliableProvisionalMode = mode; +} + +MasterProfile::ReliableProvisionalMode +MasterProfile::getUacReliableProvisionalMode() const +{ + return mUacReliableProvisionalMode; +} + +MasterProfile::ReliableProvisionalMode +MasterProfile::getUasReliableProvisionalMode() const +{ + return mUasReliableProvisionalMode; +} + +void +MasterProfile::addSupportedMimeType(const MethodTypes& method, const Mime& mimeType) +{ + mSupportedMimeTypes[method].push_back(mimeType); +} + +bool +MasterProfile::removeSupportedMimeType(const MethodTypes& method, const Mime& mimeType) +{ + std::map<MethodTypes, Mimes>::iterator foundMethod = mSupportedMimeTypes.find(method); + if (foundMethod != mSupportedMimeTypes.end()) + { + for (Mimes::iterator i = foundMethod->second.begin(); + i != foundMethod->second.end(); ++i) + { + if (mimeType.isEqual(*i)) + { + foundMethod->second.erase(i); + return true; + } + } + } + return false; +} + +bool +MasterProfile::isMimeTypeSupported(const MethodTypes& method, const Mime& mimeType) +{ + if(!mimeType.isWellFormed()) + { + return false; + } + + std::map<MethodTypes, Mimes>::iterator found = mSupportedMimeTypes.find(method); + if (found != mSupportedMimeTypes.end()) + { + return found->second.find(mimeType); + } + return false; +} + +Mimes +MasterProfile::getSupportedMimeTypes(const MethodTypes& method) +{ + std::map<MethodTypes, Mimes>::iterator found = mSupportedMimeTypes.find(method); + if (found != mSupportedMimeTypes.end()) + { + return found->second; + } + return Mimes(); +} + +void +MasterProfile::clearSupportedMimeTypes(const MethodTypes& method) +{ + std::map<MethodTypes, Mimes>::iterator found = mSupportedMimeTypes.find(method); + if (found != mSupportedMimeTypes.end()) + { + found->second.clear(); + } +} + +void +MasterProfile::clearSupportedMimeTypes() +{ + mSupportedMimeTypes.clear(); +} + +void +MasterProfile::addSupportedEncoding(const Token& encoding) +{ + mSupportedEncodings.push_back(encoding); +} + +bool +MasterProfile::isContentEncodingSupported(const Token& encoding) const +{ + return encoding.isWellFormed() && mSupportedEncodings.find(encoding); +} + +Tokens +MasterProfile::getSupportedEncodings() const +{ + return mSupportedEncodings; +} + +void +MasterProfile::clearSupportedEncodings() +{ + mSupportedEncodings.clear(); +} + +void +MasterProfile::addSupportedLanguage(const Token& lang) +{ + mSupportedLanguages.push_back(lang); +} + +bool +MasterProfile::isLanguageSupported(const Tokens& langs) const +{ + for (Tokens::const_iterator i=langs.begin(); i != langs.end(); ++i) + { + if (!i->isWellFormed() || mSupportedLanguages.find(*i) == false) + { + return false; + } + } + return true; +} + +Tokens +MasterProfile::getSupportedLanguages() const +{ + return mSupportedLanguages; +} + +void +MasterProfile::clearSupportedLanguages() +{ + mSupportedLanguages.clear(); +} + +void +MasterProfile::addAllowedEvent(const Token& event) +{ + mAllowedEvents.push_back(event); +} + +bool +MasterProfile::isEventAllowed(const Tokens& events) const +{ + for (Tokens::const_iterator i=events.begin(); i != events.end(); ++i) + { + if (!i->isWellFormed() || mAllowedEvents.find(*i) == false) + { + return false; + } + } + return true; +} + +Tokens +MasterProfile::getAllowedEvents() const +{ + return mAllowedEvents; +} + +void +MasterProfile::clearAllowedEvents() +{ + mAllowedEvents.clear(); +} + +bool& +MasterProfile::validateContentEnabled() +{ + return mValidateContentEnabled; +} + +bool +MasterProfile::validateContentEnabled() const +{ + return mValidateContentEnabled; +} + +bool& +MasterProfile::validateContentLanguageEnabled() +{ + return mValidateContentLanguageEnabled; +} + +bool +MasterProfile::validateContentLanguageEnabled() const +{ + return mValidateContentLanguageEnabled; +} + +bool& +MasterProfile::validateAcceptEnabled() +{ + return mValidateAcceptEnabled; +} + +bool +MasterProfile::validateAcceptEnabled() const +{ + return mValidateAcceptEnabled; +} + +bool +MasterProfile::allowBadRegistrationEnabled() const +{ + return mAllowBadRegistrationEnabled; +} + +bool& +MasterProfile::allowBadRegistrationEnabled() +{ + return mAllowBadRegistrationEnabled; +} + + +UInt32 & +MasterProfile::serverRegistrationMinExpiresTime(void) +{ + return mServerRegistrationMinExpires; +} + +const UInt32 +MasterProfile::serverRegistrationMinExpiresTime(void) const +{ + return mServerRegistrationMinExpires; +} + +UInt32 & +MasterProfile::serverRegistrationMaxExpiresTime(void) +{ + return mServerRegistrationMaxExpires; +} + +const UInt32 +MasterProfile::serverRegistrationMaxExpiresTime(void) const +{ + return mServerRegistrationMaxExpires; +} + +UInt32 & +MasterProfile::serverRegistrationDefaultExpiresTime(void) +{ + return mServerRegistrationDefaultExpires; +} + +const UInt32 +MasterProfile::serverRegistrationDefaultExpiresTime(void) const +{ + return mServerRegistrationDefaultExpires; +} + +bool +MasterProfile::checkReqUriInMergeDetectionEnabled() const +{ + return mCheckReqUriInMergeDetectionEnabled; +} + +bool& +MasterProfile::checkReqUriInMergeDetectionEnabled() +{ + return mCheckReqUriInMergeDetectionEnabled; +} + +UserProfile* +MasterProfile::clone() const +{ + return new MasterProfile(*this); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/dum/MasterProfile.hxx b/src/libs/resiprocate/resip/dum/MasterProfile.hxx new file mode 100644 index 00000000..aef3201f --- /dev/null +++ b/src/libs/resiprocate/resip/dum/MasterProfile.hxx @@ -0,0 +1,231 @@ +#ifndef RESIP_MasterProfile_hxx +#define RESIP_MasterProfile_hxx + +#include <iosfwd> +#include <set> +#include <map> +#include "resip/stack/Headers.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "resip/stack/Token.hxx" +#include "resip/dum/UserProfile.hxx" + +namespace resip +{ + +class Data; + +class MasterProfile : public UserProfile +{ + public: + + /// Creates an Indentity/Profile with no BaseProfile - this is the root of all profiles + MasterProfile(); + + /// Default is "sip" + virtual void addSupportedScheme(const Data& scheme); + virtual bool isSchemeSupported(const Data& scheme) const; + virtual void clearSupportedSchemes(void); + + /// Defaults are: INVITE, ACK, CANCEL, OPTIONS, BYE, UPDATE + virtual void addSupportedMethod(const MethodTypes& method); + virtual bool isMethodSupported(MethodTypes method) const; + virtual Tokens getAllowedMethods() const; + virtual Data getAllowedMethodsData() const; + + virtual void clearSupportedMethods(void); + + /// Default is none. Do not use to enable PRACK(100rel) support. + virtual void addSupportedOptionTag(const Token& tag); + virtual Tokens getUnsupportedOptionsTags(const Tokens& requires); // Returns list of unsupported option tags + virtual Tokens getSupportedOptionTags() const; + virtual void clearSupportedOptionTags(void); + + typedef enum + { + Never, + Supported, + Required + } ReliableProvisionalMode; + + + // UAC PRACK support. UPDATE must be enabled(currently defaults to on, do + // not disable w/out disabling UAC PRACK support). + // + // Flows where an an answer is received in a 180rel and subsequent O/A + // exchanges using UPDATE occur in the early dialog + // have been tested. + // + // A subsequent O/A exchange using 180rel/PRACK is also supported. This is + // a really bad idea, as an answer must be generated; the offer cannot be + // rejected. UPDATE should always be used for O/A exchanges once the + // dialog is established. + // Invite/18x(offer)/PRACK(ans) should work but has not been tested. + // + // Explicit limitations are: + // Overlapping reliable provisional responses that contain a body are not + // handled. + // Offers in a 200(PRACK) are not supported, and anyone who generates them + // should be summarily executed. + + virtual void setUacReliableProvisionalMode(ReliableProvisionalMode mode); + virtual ReliableProvisionalMode getUacReliableProvisionalMode() const; + + //Not supported as UAS. Calling setUacReliableProvisionalMode will result + //in an assert. + virtual void setUasReliableProvisionalMode(ReliableProvisionalMode mode); + virtual ReliableProvisionalMode getUasReliableProvisionalMode() const; + + /// Default is application/sdp for INVITE, OPTIONS, PRACK and UPDATE Methods + virtual void addSupportedMimeType(const MethodTypes& method, const Mime& mimeType); + virtual bool removeSupportedMimeType(const MethodTypes& method, const Mime& mimeType); + virtual bool isMimeTypeSupported(const MethodTypes& method, const Mime& mimeType); + virtual Mimes getSupportedMimeTypes(const MethodTypes& method); + virtual void clearSupportedMimeTypes(const MethodTypes& method); + virtual void clearSupportedMimeTypes(void); // Clear for all Methods + + /// Default is no encoding + virtual void addSupportedEncoding(const Token& encoding); + virtual bool isContentEncodingSupported(const Token& contentEncoding) const; + virtual Tokens getSupportedEncodings() const; + virtual void clearSupportedEncodings(void); + + /// Default is all - if nothing is set, then all are allowed + virtual void addSupportedLanguage(const Token& lang); + virtual bool isLanguageSupported(const Tokens& lang) const; + virtual Tokens getSupportedLanguages() const; + virtual void clearSupportedLanguages(void); + + /// Default is to not send an Allow-Events header. + virtual void addAllowedEvent(const Token& event); + virtual bool isEventAllowed(const Tokens& event) const; + virtual Tokens getAllowedEvents() const; + virtual void clearAllowedEvents(void); + + ///enable/disable content validation + virtual bool& validateContentEnabled(); + virtual bool validateContentEnabled() const; + + ///enable/disable content language validation + virtual bool& validateContentLanguageEnabled(); + virtual bool validateContentLanguageEnabled() const; + + ///enable/disable Accept header validation + virtual bool& validateAcceptEnabled(); + virtual bool validateAcceptEnabled() const; + + ///Set this to allow the Registration Server to accept registration requests that contain + ///a To Tag. + virtual bool& allowBadRegistrationEnabled(); + virtual bool allowBadRegistrationEnabled() const; + + + /// + /// Used when receiveing a REGISTER request, if the expires value in the request + /// is less than this time, then dum will reject the message with a 423 and set the + /// min-expires header to the value specified here. + /// + virtual UInt32& serverRegistrationMinExpiresTime(void); + virtual const UInt32 serverRegistrationMinExpiresTime(void) const; + + /// + /// If an inbound REGISTER has an Expires header or any individual contact bindings with expires greater + /// than this value, use this Max expires instead of the one given by the client. + virtual UInt32& serverRegistrationMaxExpiresTime(void); + virtual const UInt32 serverRegistrationMaxExpiresTime(void) const; + + /// If no Expires header or individual contact bindings specify an expiration value, use this value. + virtual UInt32& serverRegistrationDefaultExpiresTime(void); + virtual const UInt32 serverRegistrationDefaultExpiresTime(void) const; + + ///Set this to include the RequestURI in merge request detection. + ///*!*!*!*!*!*! RED FLASHING LIGHT *!*!*!*!*!*! + ///When false, DUM implements the policy that all RURIs that arrive are equivalent, + ///so if a request forks and arives here with different RURIs, we reject all but one + ///of them as merged requests. This makes sense for single-line endpoints. Nodes + ///responsible for multiple simultaneous resources (like gateways, media-servers, + ///B2BUAs, etc) need to set this to true. Applications like multi-line business + ///phones will want to carefully consider the edge case of a request that forks + ///to more than one line - if you want only one line to ring, leave this false. + ///If you want them all to ring, set it to true. + + virtual bool& checkReqUriInMergeDetectionEnabled(); + virtual bool checkReqUriInMergeDetectionEnabled() const; + + private: + virtual UserProfile* clone() const; + std::set<Data> mSupportedSchemes; + std::set<MethodTypes> mSupportedMethodTypes; + Tokens mSupportedMethods; + Tokens mSupportedOptionTags; + std::map<MethodTypes, Mimes> mSupportedMimeTypes; + Tokens mSupportedEncodings; + Tokens mSupportedLanguages; + Tokens mAllowedEvents; + + bool mValidateContentEnabled; + bool mValidateContentLanguageEnabled; + bool mValidateAcceptEnabled; + bool mAllowBadRegistrationEnabled; + bool mHasServerRegistrationMinExpires; + bool mCheckReqUriInMergeDetectionEnabled; + ReliableProvisionalMode mUacReliableProvisionalMode; + ReliableProvisionalMode mUasReliableProvisionalMode; + UInt32 mServerRegistrationMinExpires; + UInt32 mServerRegistrationMaxExpires; + UInt32 mServerRegistrationDefaultExpires; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/dum/MergedRequestKey.cxx b/src/libs/resiprocate/resip/dum/MergedRequestKey.cxx new file mode 100644 index 00000000..b557b26c --- /dev/null +++ b/src/libs/resiprocate/resip/dum/MergedRequestKey.cxx @@ -0,0 +1,137 @@ +#include "resip/dum/MergedRequestKey.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/CSeqCategory.hxx" + +using namespace resip; + +const MergedRequestKey MergedRequestKey::Empty; + +MergedRequestKey::MergedRequestKey(): + mCheckRequestUri(true) +{ +} + +MergedRequestKey::MergedRequestKey(const SipMessage& req, bool checkRequestUri) : + mRequestUri(Data::from(req.header(h_RequestLine).uri())), + mCSeq(Data::from(req.header(h_CSeq))), + mTag(req.header(h_From).exists(p_tag) ? req.header(h_From).param(p_tag) : Data::Empty), + mCallId(req.header(h_CallID).value()), + mCheckRequestUri(checkRequestUri) +{ +} + +bool +MergedRequestKey::operator==(const MergedRequestKey& other) const +{ + return (mCallId == other.mCallId && + mTag == other.mTag && + mCSeq == other.mCSeq && + (!mCheckRequestUri || (mRequestUri == other.mRequestUri))); +} + +bool +MergedRequestKey::operator!=(const MergedRequestKey& other) const +{ + return !(*this == other); +} + +bool +MergedRequestKey::operator<(const MergedRequestKey& other) const +{ + if ( mCallId < other.mCallId) + { + return true; + } + else if (mCallId > other.mCallId) + { + return false; + } + + if (mTag < other.mTag) + { + return true; + } + else if (mTag > other.mTag) + { + return false; + } + + if(!mCheckRequestUri) + { + return (mCSeq < other.mCSeq); + } + else + { + if (mCSeq < other.mCSeq) + { + return true; + } + else if (mCSeq > other.mCSeq) + { + return false; + } + + return (mRequestUri < other.mRequestUri); + } +} + +Data& MergedRequestKey::cseq() +{ + return mCSeq; +} + +const Data& MergedRequestKey::cseq() const +{ + return mCSeq; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/MergedRequestKey.hxx b/src/libs/resiprocate/resip/dum/MergedRequestKey.hxx new file mode 100644 index 00000000..f9c83fa2 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/MergedRequestKey.hxx @@ -0,0 +1,83 @@ +#if !defined(RESIP_MERGEDREQUESTKEY_HXX) +#define RESIP_MERGEDREQUESTKEY_HXX + +#include "rutil/Data.hxx" + +namespace resip +{ +class SipMessage; + +class MergedRequestKey +{ + public: + MergedRequestKey(); + MergedRequestKey(const SipMessage& request, bool checkRequestUri); + bool operator==(const MergedRequestKey& other) const; + bool operator!=(const MergedRequestKey& other) const; + bool operator<(const MergedRequestKey& other) const; + + Data& cseq(); + const Data& cseq() const; + static const MergedRequestKey Empty; + + private: + Data mRequestUri; + Data mCSeq; + Data mTag; + Data mCallId; + bool mCheckRequestUri; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/MergedRequestRemovalCommand.cxx b/src/libs/resiprocate/resip/dum/MergedRequestRemovalCommand.cxx new file mode 100644 index 00000000..e0151800 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/MergedRequestRemovalCommand.cxx @@ -0,0 +1,43 @@ +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/MergedRequestKey.hxx" +#include "resip/dum/MergedRequestRemovalCommand.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + + +MergedRequestRemovalCommand::MergedRequestRemovalCommand(DialogUsageManager& dum, + const MergedRequestKey& key) + : mDum(dum), + mKey(key) +{ +} + +MergedRequestRemovalCommand::MergedRequestRemovalCommand(const MergedRequestRemovalCommand& from) + : mDum(from.mDum), + mKey(from.mKey) +{ +} + +void MergedRequestRemovalCommand::executeCommand() +{ + mDum.removeMergedRequest(mKey); +} + +Message* MergedRequestRemovalCommand::clone() const +{ + return new MergedRequestRemovalCommand(*this); +} + +EncodeStream& +MergedRequestRemovalCommand::encode(EncodeStream& strm) const +{ + return strm; +} + +EncodeStream& +MergedRequestRemovalCommand::encodeBrief(EncodeStream& strm) const +{ + return strm; +} diff --git a/src/libs/resiprocate/resip/dum/MergedRequestRemovalCommand.hxx b/src/libs/resiprocate/resip/dum/MergedRequestRemovalCommand.hxx new file mode 100644 index 00000000..fb50f169 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/MergedRequestRemovalCommand.hxx @@ -0,0 +1,30 @@ +#if !defined(RESIP_MergedRequestRemovalCommand_HXX) +#define RESIP_MergedRequestRemovalCommand_HXX + +#include "resip/dum/DumCommand.hxx" + +namespace resip +{ + +class DialogUsageManager; + +class MergedRequestRemovalCommand : public DumCommand +{ + public: + MergedRequestRemovalCommand(DialogUsageManager& dum, const MergedRequestKey& key); + MergedRequestRemovalCommand(const MergedRequestRemovalCommand&); + void executeCommand(); + + + Message* clone() const; + EncodeStream& encode(EncodeStream& strm) const; + EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + DialogUsageManager& mDum; + MergedRequestKey mKey; +}; + +} + +#endif diff --git a/src/libs/resiprocate/resip/dum/NetworkAssociation.cxx b/src/libs/resiprocate/resip/dum/NetworkAssociation.cxx new file mode 100644 index 00000000..37267c12 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/NetworkAssociation.cxx @@ -0,0 +1,104 @@ +#include "rutil/Logger.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/NetworkAssociation.hxx" +#include "resip/dum/KeepAliveManager.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +bool +NetworkAssociation::update(const SipMessage& msg, int keepAliveInterval, bool targetSupportsOutbound) +{ + if (mDum && mDum->mKeepAliveManager.get()) + { + const Tuple& source = msg.getSource(); + if(source.getType() != 0 && // if source is populated in message + (!(source == mTarget) || // and (target is different from current + source.mFlowKey != mTarget.mFlowKey || // or flow key is different + mTargetSupportsOutbound != targetSupportsOutbound || // or outbound support flag is different + mKeepAliveInterval != keepAliveInterval)) // or keepaliveinterval is different) -> add to keepalivemanager + { + mDum->mKeepAliveManager->remove(mTarget); + mTarget = source; + mTarget.onlyUseExistingConnection = true; // Ensure that keepalives never open up a new connection + mTargetSupportsOutbound = targetSupportsOutbound; + mDum->mKeepAliveManager->add(mTarget, keepAliveInterval, targetSupportsOutbound); + return true; + } + } + return false; +} + +void +NetworkAssociation::clear() +{ + if (mDum && mDum->mKeepAliveManager.get()) + { + mDum->mKeepAliveManager->remove(mTarget); + mTarget = Tuple(); + mTargetSupportsOutbound = false; + mKeepAliveInterval = 0; + } +} + +NetworkAssociation::~NetworkAssociation() +{ + if (mDum && mDum->mKeepAliveManager.get()) + { + mDum->mKeepAliveManager->remove(mTarget); + } +} + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/NetworkAssociation.hxx b/src/libs/resiprocate/resip/dum/NetworkAssociation.hxx new file mode 100644 index 00000000..802bbc8c --- /dev/null +++ b/src/libs/resiprocate/resip/dum/NetworkAssociation.hxx @@ -0,0 +1,80 @@ +#ifndef RESIP_NETWORKASSOCIATION_HXX +#define RESIP_NETWORKASSOCIATION_HXX + +#include "resip/stack/Tuple.hxx" + +namespace resip +{ + +class SipMessage; +class DialogUsageManager; + +class NetworkAssociation +{ + public: + NetworkAssociation() : mDum(0), mTargetSupportsOutbound(false), mKeepAliveInterval(0) {} + void setDum(DialogUsageManager* dum) { mDum = dum; } + bool update(const SipMessage& msg, int keepAliveInterval, bool targetSupportsOutbound); // returns true if an update was required + void clear(); + ~NetworkAssociation(); + private: + Tuple mTarget; + DialogUsageManager* mDum; + bool mTargetSupportsOutbound; + int mKeepAliveInterval; +}; + +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/NonDialogUsage.cxx b/src/libs/resiprocate/resip/dum/NonDialogUsage.cxx new file mode 100644 index 00000000..a08e6efb --- /dev/null +++ b/src/libs/resiprocate/resip/dum/NonDialogUsage.cxx @@ -0,0 +1,150 @@ +#include "resip/dum/AppDialogSet.hxx" +#include "resip/dum/NonDialogUsage.hxx" +#include "resip/dum/DialogSet.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +NonDialogUsage::Exception::Exception(const Data& msg,const Data& file,int line) + : BaseException(msg, file, line) +{ +} + +const char* +NonDialogUsage::Exception::name() const +{ + return "NonDialogUsage::Exception"; +} + +NonDialogUsage::NonDialogUsage(DialogUsageManager& dum, DialogSet& dialogSet) : + BaseUsage(dum), + mDialogSet(dialogSet) +{ +} + +NonDialogUsage::~NonDialogUsage() +{ + mDialogSet.possiblyDie(); +} + +AppDialogSetHandle +NonDialogUsage::getAppDialogSet() +{ + return mDialogSet.mAppDialogSet->getHandle(); +} + +SharedPtr<UserProfile> +NonDialogUsage::getUserProfile() +{ + return mDialogSet.mUserProfile; +} + +void +NonDialogUsage::send(SharedPtr<SipMessage> msg) +{ + const NameAddrs& sRoute = getUserProfile()->getServiceRoute(); + + // Clear the routes if there was previously a service_route. Otherwise + // keep the route incase there exists custom routes + + if (!sRoute.empty()) + { + if (msg->header(h_RequestLine).method() == REGISTER) + { + const NameAddrs emptyRoute; + msg->remove(h_Routes); + getUserProfile()->setServiceRoute(emptyRoute); + } + else + { + InfoLog(<< "Applying service route: " << Inserter(getUserProfile()->getServiceRoute()) << " to " << msg->brief()); + msg->header(h_Routes) = sRoute; + } + } + + mDum.send(msg); +} + +class NonDialogUsageSendCommand : public DumCommandAdapter +{ +public: + NonDialogUsageSendCommand(NonDialogUsage& usage, SharedPtr<SipMessage> msg) + : mNonDialogUsage(usage), + mMessage(msg) + { + } + + virtual void executeCommand() + { + mNonDialogUsage.send(mMessage); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "NonDialogUsageSendCommand"; + } +private: + NonDialogUsage& mNonDialogUsage; + SharedPtr<SipMessage> mMessage; +}; + +void +NonDialogUsage::sendCommand(SharedPtr<SipMessage> message) +{ + mDum.post(new NonDialogUsageSendCommand(*this, message)); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/NonDialogUsage.hxx b/src/libs/resiprocate/resip/dum/NonDialogUsage.hxx new file mode 100644 index 00000000..c1114d2f --- /dev/null +++ b/src/libs/resiprocate/resip/dum/NonDialogUsage.hxx @@ -0,0 +1,94 @@ +#if !defined(RESIP_NONDIALOGUSAGE_HXX) +#define RESIP_NONDIALOGUSAGE_HXX + +#include "rutil/BaseException.hxx" +#include "rutil/SharedPtr.hxx" +#include "resip/dum/UserProfile.hxx" +#include "resip/dum/BaseUsage.hxx" +#include "resip/dum/Handles.hxx" + +namespace resip +{ + +class DialogUsageManager; +class DialogSet; +class DumTimeout; +class SipMessage; +class NameAddr; + +class NonDialogUsage : public BaseUsage +{ + public: + class Exception : public BaseException + { + public: + Exception(const Data& msg,const Data& file,int line); + virtual const char* name() const; + }; + + AppDialogSetHandle getAppDialogSet(); + SharedPtr<UserProfile> getUserProfile(); + //virtual void send(SipMessage& msg); + virtual void send(SharedPtr<SipMessage> msg); + virtual void sendCommand(SharedPtr<SipMessage> msg); + + protected: + NonDialogUsage(DialogUsageManager& dum, DialogSet& dialogSet); + virtual ~NonDialogUsage(); + + DialogSet& mDialogSet; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/OutOfDialogHandler.hxx b/src/libs/resiprocate/resip/dum/OutOfDialogHandler.hxx new file mode 100644 index 00000000..cf8ab626 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/OutOfDialogHandler.hxx @@ -0,0 +1,78 @@ +#if !defined(RESIP_OutOfDialogHandler_hxx) +#define RESIP_OutOfDialogHandler_hxx + +#include "resip/dum/Handles.hxx" +#include "resip/stack/SipMessage.hxx" + +namespace resip +{ + +/** @file OutOfDialogHandler.hxx + * @todo This file is empty + */ + +class OutOfDialogHandler +{ + public: + virtual ~OutOfDialogHandler() {} + // Client Handlers + virtual void onSuccess(ClientOutOfDialogReqHandle, const SipMessage& successResponse)=0; + virtual void onFailure(ClientOutOfDialogReqHandle, const SipMessage& errorResponse)=0; + + // Server Handlers + virtual void onReceivedRequest(ServerOutOfDialogReqHandle, const SipMessage& request)=0; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/OutOfDialogReqCreator.cxx b/src/libs/resiprocate/resip/dum/OutOfDialogReqCreator.cxx new file mode 100644 index 00000000..f016f25a --- /dev/null +++ b/src/libs/resiprocate/resip/dum/OutOfDialogReqCreator.cxx @@ -0,0 +1,68 @@ +#include "OutOfDialogReqCreator.hxx" + +using namespace resip; + +OutOfDialogReqCreator::OutOfDialogReqCreator(DialogUsageManager& dum, + MethodTypes method, + const NameAddr& target, + SharedPtr<UserProfile> userProfile) + : BaseCreator(dum, userProfile) +{ + makeInitialRequest(target, method); +} + +void +OutOfDialogReqCreator::dispatch(SipMessage& msg) +{ +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/OutOfDialogReqCreator.hxx b/src/libs/resiprocate/resip/dum/OutOfDialogReqCreator.hxx new file mode 100644 index 00000000..21dee6cb --- /dev/null +++ b/src/libs/resiprocate/resip/dum/OutOfDialogReqCreator.hxx @@ -0,0 +1,71 @@ +#if !defined(RESIP_OUTOFDIALOGREQCREATOR_HXX) +#define RESIP_OUTOFDIALOGREQCREATOR_HXX + +#include "resip/dum/BaseCreator.hxx" + +namespace resip +{ + +class Uri; +class SipMessage; + +class OutOfDialogReqCreator: public BaseCreator +{ + public: + OutOfDialogReqCreator(DialogUsageManager& dum, MethodTypes method, const NameAddr& target, SharedPtr<UserProfile> userProfile); + virtual void dispatch(SipMessage& msg); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/OutgoingEvent.cxx b/src/libs/resiprocate/resip/dum/OutgoingEvent.cxx new file mode 100644 index 00000000..5a43d130 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/OutgoingEvent.cxx @@ -0,0 +1,101 @@ +#include "resip/dum/OutgoingEvent.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +OutgoingEvent::OutgoingEvent(SharedPtr<SipMessage> msg) + : mMessage(msg) +{ +} + +OutgoingEvent::OutgoingEvent(const OutgoingEvent& from) + : mMessage(from.mMessage) +{ +} + +OutgoingEvent::~OutgoingEvent() +{ +} + +Message* +OutgoingEvent::clone() const +{ + return new OutgoingEvent(*this); +} + +SharedPtr<SipMessage> +OutgoingEvent::message() +{ + return mMessage; +} + +/*void +OutgoingEvent::releaseMessage() +{ + mMessage.release(); +} +*/ + +EncodeStream& +OutgoingEvent::encodeBrief(EncodeStream& strm) const +{ + return encode(strm); +} + +EncodeStream& +OutgoingEvent::encode(EncodeStream& strm) const +{ + mMessage->encode(strm); + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/OutgoingEvent.hxx b/src/libs/resiprocate/resip/dum/OutgoingEvent.hxx new file mode 100644 index 00000000..12ab9b9b --- /dev/null +++ b/src/libs/resiprocate/resip/dum/OutgoingEvent.hxx @@ -0,0 +1,86 @@ +#if !defined(RESIP_OUTGOINGEVENT_HXX) +#define RESIP_OUTGOINGEVENT_HXX + +#include "rutil/SharedPtr.hxx" +#include "resip/stack/Message.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/DialogUsageManager.hxx" + +namespace resip +{ + +class OutgoingEvent : public Message +{ + public: + //OutgoingEvent(std::auto_ptr<SipMessage> msg); + OutgoingEvent(SharedPtr<SipMessage> msg); + OutgoingEvent(const OutgoingEvent&); + ~OutgoingEvent(); + + SharedPtr<SipMessage> message(); + const Data& getTransactionId() const { return mMessage->getTransactionId(); } + + //void releaseMessage(); + + virtual Message* clone() const; + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + //mutable std::auto_ptr<SipMessage> mMessage; + SharedPtr<SipMessage> mMessage; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/PagerMessageCreator.cxx b/src/libs/resiprocate/resip/dum/PagerMessageCreator.cxx new file mode 100644 index 00000000..b947f8af --- /dev/null +++ b/src/libs/resiprocate/resip/dum/PagerMessageCreator.cxx @@ -0,0 +1,67 @@ +#include "PagerMessageCreator.hxx" + +using namespace resip; + +PagerMessageCreator::PagerMessageCreator(DialogUsageManager& dum, + const NameAddr& target, + SharedPtr<UserProfile> userProfile) + : BaseCreator(dum, userProfile) +{ + makeInitialRequest(target, MESSAGE); + //rfc3428 section 9 - remove the header that may have been added by the BaseCreator and are not allowed + mLastRequest->remove(h_Supporteds); + mLastRequest->remove(h_AcceptEncodings); + mLastRequest->remove(h_AcceptLanguages); + mLastRequest->remove(h_Contacts); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/PagerMessageCreator.hxx b/src/libs/resiprocate/resip/dum/PagerMessageCreator.hxx new file mode 100644 index 00000000..20e5b816 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/PagerMessageCreator.hxx @@ -0,0 +1,70 @@ +#if !defined(RESIP_PAGERMESSAGECREATOR_HXX) +#define RESIP_PAGERMESSAGECREATOR_HXX + +#include "resip/dum/BaseCreator.hxx" + +namespace resip +{ + +class Uri; +class SipMessage; + +class PagerMessageCreator: public BaseCreator +{ + public: + PagerMessageCreator(DialogUsageManager& dum, const NameAddr& target, SharedPtr<UserProfile> userProfile); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/PagerMessageHandler.hxx b/src/libs/resiprocate/resip/dum/PagerMessageHandler.hxx new file mode 100644 index 00000000..cfd154d1 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/PagerMessageHandler.hxx @@ -0,0 +1,88 @@ +#if !defined(RESIP_PAGERMESSAGEHANDLER_HXX) +#define RESIP_PAGERMESSAGEHANDLER_HXX + +#include "resip/dum/Handles.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Contents.hxx" + +namespace resip +{ +class ClientMessage; +class ServerMessage; +class SipMessage; + +class ClientPagerMessageHandler +{ + public: + virtual ~ClientPagerMessageHandler() {} + + // Note: end() must be explicitly called to terminate the usage + + // Called when a MESSAGE has been successfully sent + virtual void onSuccess(ClientPagerMessageHandle, const SipMessage& status)=0; + //!kh! + // Application could re-page the failed contents or just ingore it. + virtual void onFailure(ClientPagerMessageHandle, const SipMessage& status, std::auto_ptr<Contents> contents)=0; +}; + +class ServerPagerMessageHandler +{ + public: + virtual ~ServerPagerMessageHandler() {} + + virtual void onMessageArrived(ServerPagerMessageHandle, const SipMessage& message)=0; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/Postable.hxx b/src/libs/resiprocate/resip/dum/Postable.hxx new file mode 100644 index 00000000..27f2b914 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Postable.hxx @@ -0,0 +1,66 @@ +#ifndef RESIP_Postable_hxx +#define RESIP_Postable_hxx + +namespace resip +{ + +class Postable +{ + public: + virtual ~Postable(){} + virtual void post(Message*)=0; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/Profile.cxx b/src/libs/resiprocate/resip/dum/Profile.cxx new file mode 100644 index 00000000..6b1a829d --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Profile.cxx @@ -0,0 +1,1010 @@ + +#include "resip/dum/Profile.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/HeaderTypes.hxx" + +using namespace resip; +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +Profile::Profile() : + mHasOutboundDecorator(false) +{ + reset(); // set defaults +} + +Profile::Profile(SharedPtr<Profile> baseProfile) : + mHasOutboundDecorator(false), + mBaseProfile(baseProfile) +{ + assert(baseProfile.get()); + + reset(); // default all settings to fallthrough to mBaseProfile +} + +Profile::~Profile() +{ +} + +void +Profile::reset() +{ + unsetDefaultRegistrationTime(); + unsetDefaultMaxRegistrationTime(); + unsetDefaultRegistrationRetryTime(); + unsetDefaultSubscriptionTime(); + unsetDefaultPublicationTime(); + unsetDefaultStaleCallTime(); + unsetDefaultStaleReInviteTime(); + unsetDefaultSessionTime(); + unsetDefaultSessionTimerMode(); + unset1xxRetransmissionTime(); + unsetOverrideHostAndPort(); + unsetAdvertisedCapabilities(); + unsetOutboundProxy(); + unsetForceOutboundProxyOnAllRequestsEnabled(); + unsetExpressOutboundAsRouteSetEnabled(); + unsetRportEnabled(); + unsetUserAgent(); + unsetProxyRequires(); + unsetKeepAliveTimeForDatagram(); + unsetKeepAliveTimeForStream(); + unsetFixedTransportPort(); + unsetFixedTransportInterface(); + unsetRinstanceEnabled(); + unsetOutboundDecorator(); + unsetMethodsParamEnabled(); + unsetUserAgentCapabilities(); + unsetExtraHeadersInReferNotifySipFragEnabled(); +} + +void +Profile::setDefaultRegistrationTime(UInt32 secs) +{ + mDefaultRegistrationExpires = secs; + mHasDefaultRegistrationExpires = true; +} + +UInt32 +Profile::getDefaultRegistrationTime() const +{ + // Fall through seting (if required) + if(!mHasDefaultRegistrationExpires && mBaseProfile.get()) + { + return mBaseProfile->getDefaultRegistrationTime(); + } + return mDefaultRegistrationExpires; +} + +void +Profile::unsetDefaultRegistrationTime() +{ + if(mBaseProfile.get()) + { + mHasDefaultRegistrationExpires = false; + } + else // No Base profile - so return to default setting + { + mHasDefaultRegistrationExpires = true; + mDefaultRegistrationExpires = 3600; // 1 hour + } +} + +void +Profile::setDefaultMaxRegistrationTime(UInt32 secs) +{ + mDefaultMaxRegistrationExpires = secs; + mHasDefaultMaxRegistrationExpires = true; +} + +UInt32 +Profile::getDefaultMaxRegistrationTime() const +{ + // Fall through seting (if required) + if(!mHasDefaultMaxRegistrationExpires && mBaseProfile.get()) + { + return mBaseProfile->getDefaultMaxRegistrationTime(); + } + return mDefaultMaxRegistrationExpires; +} + +void +Profile::unsetDefaultMaxRegistrationTime() +{ + if(mBaseProfile.get()) + { + mHasDefaultMaxRegistrationExpires = false; + } + else // No Base profile - so return to default setting + { + mHasDefaultMaxRegistrationExpires = true; + mDefaultMaxRegistrationExpires = 0; // No restriction + } +} + +void +Profile::setDefaultRegistrationRetryTime(int secs) +{ + mDefaultRegistrationRetryInterval = secs; + mHasDefaultRegistrationRetryInterval = true; +} + +int +Profile::getDefaultRegistrationRetryTime() const +{ + // Fall through seting (if required) + if(!mHasDefaultRegistrationRetryInterval && mBaseProfile.get()) + { + return mBaseProfile->getDefaultRegistrationRetryTime(); + } + return mDefaultRegistrationRetryInterval; +} + +void +Profile::unsetDefaultRegistrationRetryTime() +{ + if(mBaseProfile.get()) + { + mHasDefaultRegistrationRetryInterval = false; + } + else // No Base profile - so return to default setting + { + mHasDefaultRegistrationRetryInterval = true; + mDefaultRegistrationRetryInterval = 0; // Retries disabled + } +} + +void +Profile::setDefaultSubscriptionTime(UInt32 secs) +{ + mDefaultSubscriptionExpires = secs; + mHasDefaultSubscriptionExpires = true; +} + +UInt32 +Profile::getDefaultSubscriptionTime() const +{ + // Fall through seting (if required) + if(!mHasDefaultSubscriptionExpires && mBaseProfile.get()) + { + return mBaseProfile->getDefaultSubscriptionTime(); + } + return mDefaultSubscriptionExpires; +} + +void +Profile::unsetDefaultSubscriptionTime() +{ + if(mBaseProfile.get()) + { + mHasDefaultSubscriptionExpires = false; + } + else // No Base profile - so return to default setting + { + mHasDefaultSubscriptionExpires = true; + mDefaultSubscriptionExpires = 3600; // 1 hour + } +} + +void +Profile::setDefaultPublicationTime(UInt32 secs) +{ + mDefaultPublicationExpires = secs; + mHasDefaultPublicationExpires = true; +} + +UInt32 +Profile::getDefaultPublicationTime() const +{ + // Fall through seting (if required) + if(!mHasDefaultPublicationExpires && mBaseProfile.get()) + { + return mBaseProfile->getDefaultPublicationTime(); + } + return mDefaultPublicationExpires; +} + +void +Profile::unsetDefaultPublicationTime() +{ + if(mBaseProfile.get()) + { + mHasDefaultPublicationExpires = false; + } + else // No Base profile - so return to default setting + { + mHasDefaultPublicationExpires = true; + mDefaultPublicationExpires = 3600; // 1 hour + } +} + +void +Profile::setDefaultStaleCallTime(int secs) +{ + mDefaultStaleCallTime = secs; + mHasDefaultStaleCallTime = true; +} + +int +Profile::getDefaultStaleCallTime() const +{ + // Fall through seting (if required) + if(!mHasDefaultStaleCallTime && mBaseProfile.get()) + { + return mBaseProfile->getDefaultStaleCallTime(); + } + return mDefaultStaleCallTime; +} + +void +Profile::unsetDefaultStaleCallTime() +{ + if(mBaseProfile.get()) + { + mHasDefaultStaleCallTime = false; + } + else // No Base profile - so return to default setting + { + mHasDefaultStaleCallTime = true; + mDefaultStaleCallTime = 180; // 3 minutes + } +} + +void +Profile::setDefaultStaleReInviteTime(int secs) +{ + mDefaultStaleReInviteTime = secs; + mHasDefaultStaleReInviteTime = true; +} + +int +Profile::getDefaultStaleReInviteTime() const +{ + // Fall through seting (if required) + if(!mHasDefaultStaleReInviteTime && mBaseProfile.get()) + { + return mBaseProfile->getDefaultStaleReInviteTime(); + } + return mDefaultStaleReInviteTime; +} + +void +Profile::unsetDefaultStaleReInviteTime() +{ + if(mBaseProfile.get()) + { + mHasDefaultStaleReInviteTime = false; + } + else // No Base profile - so return to default setting + { + mHasDefaultStaleReInviteTime = true; + mDefaultStaleReInviteTime = 40; // 40 Seconds (slightly longer than T1*64) + } +} + +void +Profile::setDefaultSessionTime(UInt32 secs) +{ + mDefaultSessionExpires = secs; + mHasDefaultSessionExpires = true; +} + +UInt32 +Profile::getDefaultSessionTime() const +{ + // Fall through seting (if required) + if(!mHasDefaultSessionExpires && mBaseProfile.get()) + { + return mBaseProfile->getDefaultSessionTime(); + } + return mDefaultSessionExpires; +} + +void +Profile::unsetDefaultSessionTime() +{ + if(mBaseProfile.get()) + { + mHasDefaultSessionExpires = false; + } + else // No Base profile - so return to default setting + { + mHasDefaultSessionExpires = true; + mDefaultSessionExpires = 1800; // 30 minutes + } +} + +void +Profile::setDefaultSessionTimerMode(Profile::SessionTimerMode mode) +{ + mDefaultSessionTimerMode = mode; + mHasDefaultSessionTimerMode = true; +} + +Profile::SessionTimerMode +Profile::getDefaultSessionTimerMode() const +{ + // Fall through seting (if required) + if(!mHasDefaultSessionTimerMode && mBaseProfile.get()) + { + return mBaseProfile->getDefaultSessionTimerMode(); + } + return mDefaultSessionTimerMode; +} + +void +Profile::unsetDefaultSessionTimerMode() +{ + if(mBaseProfile.get()) + { + mHasDefaultSessionTimerMode = false; + } + else // No Base profile - so return to default setting + { + mHasDefaultSessionTimerMode = true; + mDefaultSessionTimerMode = Profile::PreferCallerRefreshes; + } +} + +void +Profile::set1xxRetransmissionTime(int secs) +{ + m1xxRetransmissionTime = secs; + mHas1xxRetransmissionTime = true; +} + +int +Profile::get1xxRetransmissionTime() const +{ + // Fall through seting (if required) + if(!mHas1xxRetransmissionTime && mBaseProfile.get()) + { + return mBaseProfile->get1xxRetransmissionTime(); + } + return m1xxRetransmissionTime; +} + +void +Profile::unset1xxRetransmissionTime() +{ + if(mBaseProfile.get()) + { + mHas1xxRetransmissionTime = false; + } + else // No Base profile - so return to default setting + { + mHas1xxRetransmissionTime = true; + m1xxRetransmissionTime = 60; // RFC3261 13.3.1 specifies this timeout should be 1 minute + } +} + +void +Profile::setOverrideHostAndPort(const Uri& hostPort) +{ + mOverrideHostPort = hostPort; + mHasOverrideHostPort = true; +} + +bool +Profile::hasOverrideHostAndPort() const +{ + // Fall through seting (if required) + if(!mHasOverrideHostPort && mBaseProfile.get()) + { + return mBaseProfile->hasOverrideHostAndPort(); + } + return mHasOverrideHostPort; +} + +const Uri& +Profile::getOverrideHostAndPort() const +{ + // Fall through seting (if required) + if(!mHasOverrideHostPort && mBaseProfile.get()) + { + return mBaseProfile->getOverrideHostAndPort(); + } + return mOverrideHostPort; +} + +void +Profile::unsetOverrideHostAndPort() +{ + mHasOverrideHostPort = false; +} + +void +Profile::addAdvertisedCapability(const Headers::Type header) +{ + assert(header == Headers::Allow || + header == Headers::AcceptEncoding || + header == Headers::AcceptLanguage || + header == Headers::Supported); + + mAdvertisedCapabilities.insert(header); + mHasAdvertisedCapabilities = true; +} + +bool +Profile::isAdvertisedCapability(const Headers::Type header) const +{ + // Fall through seting (if required) + if(!mHasAdvertisedCapabilities && mBaseProfile.get()) + { + return mBaseProfile->isAdvertisedCapability(header); + } + return mAdvertisedCapabilities.count(header) != 0; +} + +void +Profile::clearAdvertisedCapabilities(void) +{ + mHasAdvertisedCapabilities = true; + return mAdvertisedCapabilities.clear(); +} + +void +Profile::unsetAdvertisedCapabilities() +{ + if(mBaseProfile.get()) + { + mHasAdvertisedCapabilities = false; + } + else // No Base profile - so return to default setting + { + mHasAdvertisedCapabilities = true; + addAdvertisedCapability(Headers::Allow); + addAdvertisedCapability(Headers::Supported); + } +} + +void +Profile::setOutboundProxy( const Uri& uri ) +{ + Uri tmpUri(uri); + tmpUri.param(p_lr); + mOutboundProxy = NameAddr(tmpUri); + mHasOutboundProxy = true; +} + +const NameAddr& +Profile::getOutboundProxy() const +{ + // Fall through seting (if required) + if(!mHasOutboundProxy && mBaseProfile.get()) + { + return mBaseProfile->getOutboundProxy(); + } + assert(mHasOutboundProxy); + return mOutboundProxy; +} + +bool +Profile::hasOutboundProxy() const +{ + // Fall through seting (if required) + if(!mHasOutboundProxy && mBaseProfile.get()) + { + return mBaseProfile->hasOutboundProxy(); + } + return mHasOutboundProxy; +} + +void +Profile::unsetOutboundProxy() +{ + mHasOutboundProxy = false; +} + +void +Profile::setForceOutboundProxyOnAllRequestsEnabled(bool enabled) +{ + mForceOutboundProxyOnAllRequestsEnabled = enabled; + mHasForceOutboundProxyOnAllRequestsEnabled = true; +} + +bool +Profile::getForceOutboundProxyOnAllRequestsEnabled() const +{ + // Fall through seting (if required) + if(!mHasForceOutboundProxyOnAllRequestsEnabled && mBaseProfile.get()) + { + return mBaseProfile->getForceOutboundProxyOnAllRequestsEnabled(); + } + return mForceOutboundProxyOnAllRequestsEnabled; +} + +void +Profile::unsetForceOutboundProxyOnAllRequestsEnabled() +{ + if(mBaseProfile.get()) + { + mHasForceOutboundProxyOnAllRequestsEnabled = false; + } + else + { + mHasForceOutboundProxyOnAllRequestsEnabled = true; + mForceOutboundProxyOnAllRequestsEnabled = false; + } +} + +void +Profile::setExpressOutboundAsRouteSetEnabled(bool enabled) +{ + mExpressOutboundAsRouteSetEnabled = enabled; + mHasExpressOutboundAsRouteSetEnabled = true; +} + +bool +Profile::getExpressOutboundAsRouteSetEnabled() const +{ + // Fall through seting (if required) + if(!mHasExpressOutboundAsRouteSetEnabled && mBaseProfile.get()) + { + return mBaseProfile->getExpressOutboundAsRouteSetEnabled(); + } + return mExpressOutboundAsRouteSetEnabled; +} + +void +Profile::unsetExpressOutboundAsRouteSetEnabled() +{ + if(mBaseProfile.get()) + { + mHasExpressOutboundAsRouteSetEnabled = false; + } + else + { + mHasExpressOutboundAsRouteSetEnabled = true; + mExpressOutboundAsRouteSetEnabled = false; + } +} + +void +Profile::setRportEnabled(bool enabled) +{ + mRportEnabled = enabled; + mHasRportEnabled = true; +} + +bool +Profile::getRportEnabled() const +{ + // Fall through seting (if required) + if(!mHasRportEnabled && mBaseProfile.get()) + { + return mBaseProfile->getRportEnabled(); + } + return mRportEnabled; +} + +void +Profile::unsetRportEnabled() +{ + if(mBaseProfile.get()) + { + mHasRportEnabled = false; + } + else // No Base profile - so return to default setting + { + mHasRportEnabled = true; + mRportEnabled = true; + } +} + +void +Profile::setUserAgent( const Data& userAgent ) +{ + mUserAgent = userAgent; + mHasUserAgent = true; +} + +const Data& +Profile::getUserAgent() const +{ + // Fall through seting (if required) + if(!mHasUserAgent && mBaseProfile.get()) + { + return mBaseProfile->getUserAgent(); + } + assert(mHasUserAgent); + return mUserAgent; +} + +bool +Profile::hasUserAgent() const +{ + // Fall through seting (if required) + if(!mHasUserAgent && mBaseProfile.get()) + { + return mBaseProfile->hasUserAgent(); + } + return mHasUserAgent; +} + +void +Profile::unsetUserAgent() +{ + mHasUserAgent = false; +} + +void +Profile::setProxyRequires( const Tokens& proxyRequires ) +{ + mProxyRequires = proxyRequires; + mHasProxyRequires = true; +} + +const Tokens& +Profile::getProxyRequires() const +{ + // Fall through seting (if required) + if(!mHasProxyRequires && mBaseProfile.get()) + { + return mBaseProfile->getProxyRequires(); + } + assert(mHasProxyRequires); + return mProxyRequires; +} + +bool +Profile::hasProxyRequires() const +{ + // Fall through seting (if required) + if(!mHasProxyRequires && mBaseProfile.get()) + { + return mBaseProfile->hasProxyRequires(); + } + return mHasProxyRequires; +} + +void +Profile::unsetProxyRequires() +{ + mHasProxyRequires = false; +} + +void +Profile::setKeepAliveTimeForDatagram(int keepAliveTime) +{ + mKeepAliveTimeForDatagram = keepAliveTime; + mHasKeepAliveTimeForDatagram = true; +} + +int +Profile::getKeepAliveTimeForDatagram() const +{ + // Fall through seting (if required) + if(!mHasKeepAliveTimeForDatagram && mBaseProfile.get()) + { + return mBaseProfile->getKeepAliveTimeForDatagram(); + } + return mKeepAliveTimeForDatagram; +} + +void +Profile::unsetKeepAliveTimeForDatagram() +{ + if(mBaseProfile.get()) + { + mHasKeepAliveTimeForDatagram = false; + } + else // No Base profile - so return to default setting + { + mHasKeepAliveTimeForDatagram = true; + mKeepAliveTimeForDatagram = 30; // 30 seconds. + } +} + +void +Profile::setKeepAliveTimeForStream(int keepAliveTime) +{ + mKeepAliveTimeForStream = keepAliveTime; + mHasKeepAliveTimeForStream = true; +} + +int +Profile::getKeepAliveTimeForStream() const +{ + // Fall through seting (if required) + if(!mHasKeepAliveTimeForStream && mBaseProfile.get()) + { + return mBaseProfile->getKeepAliveTimeForStream(); + } + return mKeepAliveTimeForStream; +} + +void +Profile::unsetKeepAliveTimeForStream() +{ + if(mBaseProfile.get()) + { + mHasKeepAliveTimeForStream = false; + } + else // No Base profile - so return to default setting + { + mHasKeepAliveTimeForStream = true; + mKeepAliveTimeForStream = 180; // 3 minutes. + } +} + +void +Profile::setFixedTransportPort(int fixedTransportPort) +{ + mFixedTransportPort = fixedTransportPort; + mHasFixedTransportPort = true; +} + +int +Profile::getFixedTransportPort() const +{ + // Fall through seting (if required) + if(!mHasFixedTransportPort && mBaseProfile.get()) + { + return mBaseProfile->getFixedTransportPort(); + } + return mFixedTransportPort; +} + +void +Profile::unsetFixedTransportPort() +{ + if(mBaseProfile.get()) + { + mHasFixedTransportPort = false; + } + else // No Base profile - so return to default setting + { + mHasFixedTransportPort = true; + mFixedTransportPort = 0; + } +} + +void +Profile::setFixedTransportInterface(const Data& fixedTransportInterface) +{ + mFixedTransportInterface = fixedTransportInterface; + mHasFixedTransportInterface = true; +} + +const Data& +Profile::getFixedTransportInterface() const +{ + // Fall through seting (if required) + if(!mHasFixedTransportInterface && mBaseProfile.get()) + { + return mBaseProfile->getFixedTransportInterface(); + } + return mFixedTransportInterface; +} + +void +Profile::unsetFixedTransportInterface() +{ + if(mBaseProfile.get()) + { + mHasFixedTransportInterface = false; + } + else // No Base profile - so return to default setting + { + mHasFixedTransportInterface = true; + mFixedTransportInterface = Data::Empty; + } +} + + +void +Profile::setRinstanceEnabled(bool enabled) +{ + mRinstanceEnabled = enabled; + mHasRinstanceEnabled = true; +} + +bool +Profile::getRinstanceEnabled() const +{ + // Fall through seting (if required) + if(!mHasRinstanceEnabled && mBaseProfile.get()) + { + return mBaseProfile->getRinstanceEnabled(); + } + return mRinstanceEnabled; +} + +void +Profile::unsetRinstanceEnabled() +{ + if(mBaseProfile.get()) + { + mHasRinstanceEnabled = false; + } + else + { + mHasRinstanceEnabled = true; + mRinstanceEnabled = true; + } +} + + ////If set then dum will add this MessageDecorator to all outbound messages + //virtual void setOutboundDecorator(SharedPtr<MessageDecorator> outboundDecorator); + //virtual SharedPtr<MessageDecorator> getOutboundDecorator(); + //virtual void unsetOutboundDecorator(); + +void +Profile::setOutboundDecorator(SharedPtr<MessageDecorator> outboundDecorator) +{ + mOutboundDecorator = outboundDecorator; + mHasOutboundDecorator = true; +} + +SharedPtr<MessageDecorator> +Profile::getOutboundDecorator() +{ + // Fall through seting (if required) + if(!mHasOutboundDecorator && mBaseProfile.get()) + { + return mBaseProfile->getOutboundDecorator(); + } + return mOutboundDecorator; +} + +void +Profile::unsetOutboundDecorator() +{ + if (mHasOutboundDecorator) + { + mOutboundDecorator.reset(); + } + + mHasOutboundDecorator = false; +} + +void +Profile::setMethodsParamEnabled(bool enabled) +{ + mMethodsParamEnabled = enabled; + mHasMethodsParamEnabled = true; +} + +bool +Profile::getMethodsParamEnabled() const +{ + // Fall through seting (if required) + if(!mHasMethodsParamEnabled && mBaseProfile.get()) + { + return mBaseProfile->getMethodsParamEnabled(); + } + return mMethodsParamEnabled; +} + +void +Profile::unsetMethodsParamEnabled() +{ + if(mBaseProfile.get()) + { + mHasMethodsParamEnabled = false; + } + else + { + mHasMethodsParamEnabled = true; + mMethodsParamEnabled = false; + } +} + +void +Profile::setUserAgentCapabilities(const NameAddr& capabilities) +{ + mUserAgentCapabilities = capabilities; + mHasUserAgentCapabilities = true; +} + +const NameAddr& +Profile::getUserAgentCapabilities() const +{ + // Fall through seting (if required) + if(!mHasUserAgentCapabilities && mBaseProfile.get()) + { + return mBaseProfile->getUserAgentCapabilities(); + } + assert(mHasUserAgentCapabilities); + return mUserAgentCapabilities; +} + +bool +Profile::hasUserAgentCapabilities() const +{ + // Fall through seting (if required) + if(!mHasUserAgentCapabilities && mBaseProfile.get()) + { + return mBaseProfile->hasUserAgentCapabilities(); + } + return mHasUserAgentCapabilities; +} + +void +Profile::unsetUserAgentCapabilities() +{ + mHasUserAgentCapabilities = false; +} + +void +Profile::setExtraHeadersInReferNotifySipFragEnabled(bool enabled) +{ + mExtraHeadersInReferNotifySipFragEnabled = enabled; + mHasExtraHeadersInReferNotifySipFragEnabled = true; +} + +bool +Profile::getExtraHeadersInReferNotifySipFragEnabled() const +{ + // Fall through seting (if required) + if(!mHasExtraHeadersInReferNotifySipFragEnabled && mBaseProfile.get()) + { + return mBaseProfile->getExtraHeadersInReferNotifySipFragEnabled(); + } + return mExtraHeadersInReferNotifySipFragEnabled; +} + +void +Profile::unsetExtraHeadersInReferNotifySipFragEnabled() +{ + if(mBaseProfile.get()) + { + mHasExtraHeadersInReferNotifySipFragEnabled = false; + } + else + { + mHasExtraHeadersInReferNotifySipFragEnabled = true; + mExtraHeadersInReferNotifySipFragEnabled = false; + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/Profile.hxx b/src/libs/resiprocate/resip/dum/Profile.hxx new file mode 100644 index 00000000..3599508d --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Profile.hxx @@ -0,0 +1,371 @@ +#if !defined(RESIP_PROFILE_HXX) +#define RESIP_PROFILE_HXX + +#include <iosfwd> +#include <set> +#include "resip/stack/Headers.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "rutil/SharedPtr.hxx" +#include "resip/stack/MessageDecorator.hxx" + +namespace resip +{ + +class Data; + +class Profile +{ + public: + Profile(); // Default to no base profile + Profile(SharedPtr<Profile> baseProfile); + virtual ~Profile(); + + /// Reset this profile to it's initial state - (same as calling unsetXXX for each setting) + /// If no fall through (base) profile was provided as creation time + /// - Reset all settings to Default settings + /// else + /// - Reset all setting to fall through to base profile + virtual void reset(); + + /// Note: + /// setXXXX methods will set this setting internally in this object. If you do not call + /// a particular setXXX method on this object then a corresponding getXXXX call will attempt + /// to retrieve that value from the BaseProfile (provided in the constructor). This allows + /// you to setup a heirarchy of profiles and settings. + /// unsetXXX methods are used to re-enable fallthrough after calling a setXXXX method. If + /// you call an unsetXXXX method on an object with a NULL BaseProfile the setting will return to + /// it's creation time default. Note: Defaults are described below. + + /// This default is used if no value is passed in when creating a registration + virtual void setDefaultRegistrationTime(UInt32 secs); + virtual UInt32 getDefaultRegistrationTime() const; + virtual void unsetDefaultRegistrationTime(); + + /// If a registration gets rejected with a 423, then we ensure the MinExpires value is less than this before re-registering + /// Set to 0 to disable this check and accept any time suggested by the server. + virtual void setDefaultMaxRegistrationTime(UInt32 secs); + virtual UInt32 getDefaultMaxRegistrationTime() const; + virtual void unsetDefaultMaxRegistrationTime(); + + /// The time to retry registrations on error responses (if Retry-After header is not present in error) + /// Set to 0 to never retry on errors. Note: onRequestRetry is called before this setting is + /// checked. Return -1 from onRequestRetry in order to use this setting. + virtual void setDefaultRegistrationRetryTime(int secs); + virtual int getDefaultRegistrationRetryTime() const; + virtual void unsetDefaultRegistrationRetryTime(); + + /// This default is used if no value is passed in when creating a subscription + virtual void setDefaultSubscriptionTime(UInt32 secs); + virtual UInt32 getDefaultSubscriptionTime() const; + virtual void unsetDefaultSubscriptionTime(); + + /// This default is used if no value is passed in when creating a publication + virtual void setDefaultPublicationTime(UInt32 secs); + virtual UInt32 getDefaultPublicationTime() const; + virtual void unsetDefaultPublicationTime(); + + /// Call is stale if UAC gets no final response within the stale call timeout (default 3 minutes) + virtual void setDefaultStaleCallTime(int secs); + virtual int getDefaultStaleCallTime() const; + virtual void unsetDefaultStaleCallTime(); + + /// ReInvite is stale if UAC gets no final response within the stale reinvite timeout (default 40 seconds) + virtual void setDefaultStaleReInviteTime(int secs); + virtual int getDefaultStaleReInviteTime() const; + virtual void unsetDefaultStaleReInviteTime(); + + /// Only used if timer option tag is set in MasterProfile. + /// Note: Value must be higher than 90 (as specified in RFC 4028) + virtual void setDefaultSessionTime(UInt32 secs); + virtual UInt32 getDefaultSessionTime() const; + virtual void unsetDefaultSessionTime(); + + /// Only used if timer option tag is set in MasterProfile. + /// Set to PreferLocalRefreshes if you prefer that the local UA performs the refreshes. + /// Set to PreferRemoteRefreshes if you prefer that the remote UA peforms the refreshes. + /// Set to PreferCallerRefreshes if you prefer that the Caller performs the refreshes. + /// Set to PreferCalleeRefreshes if you prefer that the Callee (called party) performs the refreshes. + /// Note: determining the refresher is a negotiation, so despite this setting the remote + /// end may end up enforcing their preference. Also if the remote end doesn't support + /// SessionTimers then the refresher will always be local. + /// This implementation follows the RECOMMENDED practices from section 7.1 of the draft + /// and does not specify a refresher parameter in UAC requests. + typedef enum + { + PreferLocalRefreshes, + PreferRemoteRefreshes, + PreferCallerRefreshes, + PreferCalleeRefreshes + } SessionTimerMode; + virtual void setDefaultSessionTimerMode(Profile::SessionTimerMode mode); + virtual Profile::SessionTimerMode getDefaultSessionTimerMode() const; + virtual void unsetDefaultSessionTimerMode(); + + /// The amount of time that can pass before dum will resubmit an unreliable provisional response + virtual void set1xxRetransmissionTime(int secs); + virtual int get1xxRetransmissionTime() const; + virtual void unset1xxRetransmissionTime(); + + ///overrides the value used to populate the contact + ///?dcm? -- also change via entries? Also, dum currently uses(as a uas) + ///the request uri of the dialog constructing request for the local contact + ///within that dialog. A transport paramter here could also be used to + ///force tcp vs udp vs tls? + virtual void setOverrideHostAndPort(const Uri& hostPort); + virtual bool hasOverrideHostAndPort() const; + virtual const Uri& getOverrideHostAndPort() const; + virtual void unsetOverrideHostAndPort(); + + ///enable/disable sending of Allow/Supported/Accept-Language/Accept-Encoding headers + ///on initial outbound requests (ie. Initial INVITE, REGISTER, etc.) and Invite 200 responses + ///Note: Default is to advertise Headers::Allow and Headers::Supported, use clearAdvertisedCapabilities to remove these + /// Currently implemented header values are: Headers::Allow, + /// Headers::AcceptEncoding, Headers::AcceptLanguage, Headers::Supported + virtual void addAdvertisedCapability(const Headers::Type header); + virtual bool isAdvertisedCapability(const Headers::Type header) const; + virtual void clearAdvertisedCapabilities(); + virtual void unsetAdvertisedCapabilities(); + + /// Use to route all outbound requests through a particular proxy + virtual void setOutboundProxy( const Uri& uri ); + virtual const NameAddr& getOutboundProxy() const; + virtual bool hasOutboundProxy() const; + virtual void unsetOutboundProxy(); + + ///If enabled, forces use of outbound proxy on all requests, including + ///mid-dialog requests. WARNING: Using this setting breaks 3261 mid-dialog + ///routing and disables any ability to react to target refreshes. However + ///there are certain scenarios/endpoints for which this setting may make + ///sense - for example: to communicate with an endpoint that never populates + ///it's Contact header correctly. + virtual void setForceOutboundProxyOnAllRequestsEnabled(bool enabled) ; + virtual bool getForceOutboundProxyOnAllRequestsEnabled() const; + virtual void unsetForceOutboundProxyOnAllRequestsEnabled(); + + ///If enabled, add a route header for the outbound proxy + virtual void setExpressOutboundAsRouteSetEnabled(bool enabled) ; + virtual bool getExpressOutboundAsRouteSetEnabled() const; + virtual void unsetExpressOutboundAsRouteSetEnabled(); + + ///enable/disable rport for requests. rport is enabled by default + virtual void setRportEnabled(bool enabled); + virtual bool getRportEnabled() const; + virtual void unsetRportEnabled(); + + ///if set then UserAgent header is added to outbound messages + virtual void setUserAgent( const Data& userAgent ); + virtual const Data& getUserAgent() const; + virtual bool hasUserAgent() const; + virtual void unsetUserAgent(); + + ///if set then ProxyRequires header is added to outbound messages + virtual void setProxyRequires( const Tokens& proxyRequires ); + virtual const Tokens& getProxyRequires() const; + virtual bool hasProxyRequires() const; + virtual void unsetProxyRequires(); + + ///time between CR/LF keepalive messages in seconds. Set to 0 to disable. + ///Default is 30 seconds for datagram and 180 seconds for stream. + ///Note: You must set a KeepAliveManager on DUM for this to work. + virtual void setKeepAliveTimeForDatagram(int keepAliveTime); + virtual int getKeepAliveTimeForDatagram() const; + virtual void unsetKeepAliveTimeForDatagram(); + virtual void setKeepAliveTimeForStream(int keepAliveTime); + virtual int getKeepAliveTimeForStream() const; + virtual void unsetKeepAliveTimeForStream(); + + ///If set dum will provide a port in the via for requests sent down to the stack. This + ///will tell the transport selector to only look at those transports using this port. + ///Default is 0 (Disabled). + ///WARNING: Setting this can cause undesirable behaviour in the case when you want + /// DNS entries to decided your transport and you are supporting TLS. + /// For example: if you add UDP:5060, TCP:5060 and TLS:5061 and setFixedTransportPort + /// to 5060 - then the TLS transport cannot be used. + virtual void setFixedTransportPort(int fixedTransportPort); + virtual int getFixedTransportPort() const; + virtual void unsetFixedTransportPort(); + + ///If set dum will provide a interface in the via for requests sent down to the stack. This + ///will tell the transport selector to only look at those transports using this interface. + ///Default is Data::Empty (Disabled). + virtual void setFixedTransportInterface(const Data& fixedTransportInterface); + virtual const Data& getFixedTransportInterface() const; + virtual void unsetFixedTransportInterface(); + + ///If enabled then rinstance parameter is added to contacts. The rinstance + ///parameter is added by default. + virtual void setRinstanceEnabled(bool enabled); + virtual bool getRinstanceEnabled() const; + virtual void unsetRinstanceEnabled(); + + //If set then dum will add this MessageDecorator to all outbound messages + virtual void setOutboundDecorator(SharedPtr<MessageDecorator> outboundDecorator); + virtual SharedPtr<MessageDecorator> getOutboundDecorator(); + virtual void unsetOutboundDecorator(); + + ///If enabled then methods parameter is added to contacts. + virtual void setMethodsParamEnabled(bool enabled) ; + virtual bool getMethodsParamEnabled() const; + virtual void unsetMethodsParamEnabled(); + + ///If set, the parameters on the provided NameAddr are used in the contact header + ///Example: + /// #include <resip/stack/ExtensionParameter.hxx> + /// static const resip::ExtensionParameter p_automaton("automaton"); + /// static const resip::ExtensionParameter p_byeless("+sip.byeless"); + /// static const resip::ExtensionParameter p_rendering("+sip.rendering"); + /// ... + /// NameAddr capabilities; + /// capabilities.param(p_automaton); + /// capabilities.param(p_byeless); + /// capabilities.param(p_rendering) = "\"no\""; + /// profile->setUserAgentCapabilities(capabilities); + virtual void setUserAgentCapabilities(const NameAddr& capabilities) ; + virtual bool hasUserAgentCapabilities() const; + virtual const NameAddr& getUserAgentCapabilities() const; + virtual void unsetUserAgentCapabilities(); + + ///If enabled then dialog identifying headers are added to SipFrag bodies + ///that are generated in an InviteSession + virtual void setExtraHeadersInReferNotifySipFragEnabled(bool enabled) ; + virtual bool getExtraHeadersInReferNotifySipFragEnabled() const; + virtual void unsetExtraHeadersInReferNotifySipFragEnabled(); + + private: + bool mHasDefaultRegistrationExpires; + UInt32 mDefaultRegistrationExpires; + + bool mHasDefaultMaxRegistrationExpires; + UInt32 mDefaultMaxRegistrationExpires; + + bool mHasDefaultRegistrationRetryInterval; + int mDefaultRegistrationRetryInterval; + + bool mHasDefaultSubscriptionExpires; + UInt32 mDefaultSubscriptionExpires; + + bool mHasDefaultPublicationExpires; + UInt32 mDefaultPublicationExpires; + + bool mHasDefaultStaleCallTime; + int mDefaultStaleCallTime; + + bool mHasDefaultStaleReInviteTime; + int mDefaultStaleReInviteTime; + + bool mHasDefaultSessionExpires; + UInt32 mDefaultSessionExpires; + + bool mHasDefaultSessionTimerMode; + SessionTimerMode mDefaultSessionTimerMode; + + bool mHas1xxRetransmissionTime; + int m1xxRetransmissionTime; + + bool mHasOutboundProxy; + NameAddr mOutboundProxy; + + bool mHasForceOutboundProxyOnAllRequestsEnabled; + bool mForceOutboundProxyOnAllRequestsEnabled; + + bool mHasExpressOutboundAsRouteSetEnabled; + bool mExpressOutboundAsRouteSetEnabled; + + bool mHasAdvertisedCapabilities; + std::set<Headers::Type> mAdvertisedCapabilities; + + bool mHasRportEnabled; + bool mRportEnabled; + + bool mHasUserAgent; + Data mUserAgent; + + bool mHasOverrideHostPort; + Uri mOverrideHostPort; + + bool mHasKeepAliveTimeForDatagram; + int mKeepAliveTimeForDatagram; + + bool mHasKeepAliveTimeForStream; + int mKeepAliveTimeForStream; + + bool mHasFixedTransportPort; + int mFixedTransportPort; + + bool mHasFixedTransportInterface; + Data mFixedTransportInterface; + + bool mHasProxyRequires; + Tokens mProxyRequires; + + bool mHasRinstanceEnabled; + bool mRinstanceEnabled; + + bool mHasOutboundDecorator; + SharedPtr<MessageDecorator> mOutboundDecorator; + + bool mHasMethodsParamEnabled; + bool mMethodsParamEnabled; + + bool mHasUserAgentCapabilities; + NameAddr mUserAgentCapabilities; + + bool mHasExtraHeadersInReferNotifySipFragEnabled; + bool mExtraHeadersInReferNotifySipFragEnabled; + + SharedPtr<Profile> mBaseProfile; // All non-set settings will fall through to this Profile (if set) +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/PublicationCreator.cxx b/src/libs/resiprocate/resip/dum/PublicationCreator.cxx new file mode 100644 index 00000000..22e46976 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/PublicationCreator.cxx @@ -0,0 +1,70 @@ +#include "PublicationCreator.hxx" +#include "resip/stack/SipMessage.hxx" + +using namespace resip; + +PublicationCreator::PublicationCreator(DialogUsageManager& dum, + const NameAddr& target, + SharedPtr<UserProfile> userProfile, + const Contents& body, + const Data& eventType, + UInt32 expireSeconds ) + : BaseCreator(dum, userProfile) +{ + makeInitialRequest(target, PUBLISH); + + mLastRequest->header(h_Event).value() = eventType; + mLastRequest->setContents(&body); + mLastRequest->header(h_Expires).value() = expireSeconds; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/PublicationCreator.hxx b/src/libs/resiprocate/resip/dum/PublicationCreator.hxx new file mode 100644 index 00000000..8648451b --- /dev/null +++ b/src/libs/resiprocate/resip/dum/PublicationCreator.hxx @@ -0,0 +1,74 @@ +#if !defined(RESIP_PUBLICATIONCREATOR_HXX) +#define RESIP_PUBLICATIONCREATOR_HXX + +#include "resip/dum/BaseCreator.hxx" + +namespace resip +{ + +class Contents; + +class PublicationCreator: public BaseCreator +{ + public: + PublicationCreator(DialogUsageManager& dum, + const NameAddr& targetDocument, + SharedPtr<UserProfile> userProfile, + const Contents& body, + const Data& eventType, + UInt32 expireSeconds ); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/PublicationHandler.hxx b/src/libs/resiprocate/resip/dum/PublicationHandler.hxx new file mode 100644 index 00000000..69887edf --- /dev/null +++ b/src/libs/resiprocate/resip/dum/PublicationHandler.hxx @@ -0,0 +1,123 @@ +#if !defined(RESIP_PUBLICATIONHANDLER_HXX) +#define RESIP_PUBLICATIONHANDLER_HXX + +#include "resip/dum/Handles.hxx" +#include "resip/stack/Mime.hxx" + +namespace resip +{ + +class ClientPublication; +class ServerPublication; +class SipMessage; +class SecurityAttributes; + +class ClientPublicationHandler +{ + public: + virtual ~ClientPublicationHandler() {} + + /// Called when the publication succeeds or each time it is sucessfully + /// refreshed. + virtual void onSuccess(ClientPublicationHandle, const SipMessage& status)=0; + + //publication was successfully removed + virtual void onRemove(ClientPublicationHandle, const SipMessage& status)=0; + + //call on failure. The usage will be destroyed. Note that this may not + //necessarily be 4xx...a malformed 200, etc. could also reach here. + virtual void onFailure(ClientPublicationHandle, const SipMessage& status)=0; + + /// call on Retry-After failure. + /// return values: -1 = fail, 0 = retry immediately, N = retry in N seconds + virtual int onRequestRetry(ClientPublicationHandle, int retrySeconds, const SipMessage& status)=0; + + // ?dcm? -- when should this be called + virtual void onStaleUpdate(ClientPublicationHandle, const SipMessage& /*status*/) + {} +}; + +class ServerPublicationHandler +{ + public: + virtual ~ServerPublicationHandler() {} + + virtual void onInitial(ServerPublicationHandle, + const Data& etag, + const SipMessage& pub, + const Contents* contents, + const SecurityAttributes* attrs, + UInt32 expires)=0; + virtual void onExpired(ServerPublicationHandle, const Data& etag)=0; + virtual void onRefresh(ServerPublicationHandle, const Data& etag, + const SipMessage& pub, + const Contents* contents, + const SecurityAttributes* attrs, + UInt32 expires)=0; + virtual void onUpdate(ServerPublicationHandle, + const Data& etag, + const SipMessage& pub, + const Contents* contents, + const SecurityAttributes* attrs, + UInt32 expires)=0; + virtual void onRemoved(ServerPublicationHandle, + const Data& etag, + const SipMessage& pub, + UInt32 expires)=0; + + const Mimes& getSupportedMimeTypes() const; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/RADIUSServerAuthManager.cxx b/src/libs/resiprocate/resip/dum/RADIUSServerAuthManager.cxx new file mode 100644 index 00000000..efc6d386 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RADIUSServerAuthManager.cxx @@ -0,0 +1,152 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include <sstream> + +#include "resip/dum/ChallengeInfo.hxx" +#include "resip/dum/ClientInviteSession.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/UserAuthInfo.hxx" +#include "resip/dum/RADIUSServerAuthManager.hxx" +#include "resip/stack/ExtensionHeader.hxx" +#include "rutil/Data.hxx" +#include "rutil/Logger.hxx" +#include "rutil/MD5Stream.hxx" + +#ifdef USE_RADIUS_CLIENT + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +RADIUSServerAuthManager::RADIUSServerAuthManager(resip::DialogUsageManager& dum) : ServerAuthManager(dum, dum.dumIncomingTarget()), dum(dum) { + + RADIUSDigestAuthenticator::init(NULL); +} + +RADIUSServerAuthManager::~RADIUSServerAuthManager() { +} + +ServerAuthManager::AsyncBool RADIUSServerAuthManager::requiresChallenge(const SipMessage& msg) { + + ostringstream s; + s << msg.header(h_RequestLine).uri(); + DebugLog(<<"RADIUSServerAuthManager::requiresChallenge, uri = " << s.str().c_str()); + + // default behaviour is to challenge + ChallengeInfo *cmsg = new ChallengeInfo(false, true, msg.getTransactionId()); + dum.post(cmsg); + return Async; +} + +void RADIUSServerAuthManager::requestCredential(const resip::Data& user, const resip::Data& realm, const resip::SipMessage& msg, const resip::Auth& auth, const resip::Data& transactionId) { + + ostringstream s; + s << msg.header(h_RequestLine).uri(); + DebugLog(<<"RADIUSServerAuthManager::requestCredential, uri = " << s << " authUser = " << user); + + MyRADIUSDigestAuthListener *radiusListener = NULL; + try { + + radiusListener = new MyRADIUSDigestAuthListener(user, realm, dum, transactionId); + Data radiusUser(user + "@" + realm); + DebugLog(<< "radiusUser = " << radiusUser.c_str() << ", " << "user = " << user.c_str()); + Data reqUri(""); + Data reqMethod(""); + if(msg.isRequest()) { + //reqUri = Data(msg.header(h_RequestLine).uri()); + // ostringstream s; + // s << msg.header(h_RequestLine).uri(); + //reqUri = Data(s.str()); + reqUri = auth.param(p_uri); + reqMethod = Data(resip::getMethodName(msg.header(h_RequestLine).getMethod())); + } + RADIUSDigestAuthenticator *radius = NULL; + if(auth.exists(p_qop)) { + if(auth.param(p_qop) == Symbols::auth) { + Data myQop("auth"); + radius = new RADIUSDigestAuthenticator(radiusUser, user, realm, auth.param(p_nonce), reqUri, reqMethod, myQop, auth.param(p_nc), auth.param(p_cnonce), auth.param(p_response), radiusListener); + } else if(auth.param(p_qop) == Symbols::authInt) { + Data myQop("auth-int"); + radius = new RADIUSDigestAuthenticator(radiusUser, user, realm, auth.param(p_nonce), reqUri, reqMethod, myQop, auth.param(p_nc), auth.param(p_cnonce), auth.param(p_opaque), auth.param(p_response), radiusListener); + } + } + if(radius == NULL) { + radius = new RADIUSDigestAuthenticator(radiusUser, user, realm, auth.param(p_nonce), reqUri, reqMethod, auth.param(p_response), radiusListener); + } + int result = radius->doRADIUSCheck(); + if(result < 0) { + ErrLog(<<"RADIUSServerAuthManager::requestCredential, uri = " << s <<" failed to start thread, error = " << result); + } + } catch(...) { + WarningLog(<<"RADIUSServerAuthManager::requestCredential, uri = " << s <<" exception"); + delete radiusListener; + } +} + +bool RADIUSServerAuthManager::useAuthInt() const { + return true; +} + +bool RADIUSServerAuthManager::authorizedForThisIdentity(const resip::Data &user, const resip::Data &realm, resip::Uri &fromUri) { + // Always returns true: in other words, any user can send any from URI + // or forge any CLI + return true; +} + +void +RADIUSServerAuthManager::onAuthSuccess(const resip::SipMessage& msg) { +} + +void +RADIUSServerAuthManager::onAuthFailure(resip::ServerAuthManager::AuthFailureReason reason, const resip::SipMessage& msg) { + Data failureMsg("unknown failure"); + switch(reason) { + case InvalidRequest: + failureMsg = Data("InvalidRequest"); + break; + case BadCredentials: + failureMsg = Data("BadCredentials"); + break; + case Error: + failureMsg = Data("Error"); + break; + } + Tuple sourceTuple = msg.getSource(); + Data sourceIp = Data(inet_ntoa(sourceTuple.toGenericIPAddress().v4Address.sin_addr)); + WarningLog(<<"auth failure: " << failureMsg << ": src IP=" << sourceIp << ", uri=" << msg.header(h_RequestLine).uri().user() << ", from=" <<msg.header(h_From).uri().user() << ", to=" << msg.header(h_To).uri().user()); +} + +MyRADIUSDigestAuthListener::MyRADIUSDigestAuthListener(const resip::Data& user, const resip::Data& realm, resip::TransactionUser& tu, const resip::Data& transactionId) : user(user), realm(realm), tu(tu), transactionId(transactionId) { +} + +MyRADIUSDigestAuthListener::~MyRADIUSDigestAuthListener() { +} + +void MyRADIUSDigestAuthListener::onSuccess(const resip::Data& rpid) { + DebugLog(<<"MyRADIUSDigestAuthListener::onSuccess"); + if(!rpid.empty()) + DebugLog(<<"MyRADIUSDigestAuthListener::onSuccess rpid = " << rpid.c_str()); + else + DebugLog(<<"MyRADIUSDigestAuthListener::onSuccess, no rpid"); + UserAuthInfo *uai = new UserAuthInfo(user, realm, UserAuthInfo::DigestAccepted, transactionId); + tu.post(uai); +} + +void MyRADIUSDigestAuthListener::onAccessDenied() { + DebugLog(<<"MyRADIUSDigestAuthListener::onAccessDenied"); + UserAuthInfo *uai = new UserAuthInfo(user, realm, UserAuthInfo::DigestNotAccepted, transactionId); + tu.post(uai); +} + +void MyRADIUSDigestAuthListener::onError() { + WarningLog(<<"MyRADIUSDigestAuthListener::onError"); + UserAuthInfo *uai = new UserAuthInfo(user, realm, UserAuthInfo::Error, transactionId); + tu.post(uai); +} + +#endif + diff --git a/src/libs/resiprocate/resip/dum/RADIUSServerAuthManager.hxx b/src/libs/resiprocate/resip/dum/RADIUSServerAuthManager.hxx new file mode 100644 index 00000000..c6d5717d --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RADIUSServerAuthManager.hxx @@ -0,0 +1,57 @@ + +#ifndef __RADIUSServerAuthManager_h +#define __RADIUSServerAuthManager_h + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_RADIUS_CLIENT + +#include "rutil/RADIUSDigestAuthenticator.hxx" +#include "resip/dum/ServerAuthManager.hxx" + +namespace resip +{ + +class RADIUSServerAuthManager : public resip::ServerAuthManager { + +private: + resip::DialogUsageManager& dum; + +public: + RADIUSServerAuthManager(resip::DialogUsageManager& dum); + virtual ~RADIUSServerAuthManager(); + +protected: + resip::ServerAuthManager::AsyncBool requiresChallenge(const resip::SipMessage& msg); + void requestCredential(const resip::Data& user, const resip::Data& realm, const resip::SipMessage& msg, const resip::Auth& auth, const resip::Data& transactionId); + bool useAuthInt() const; + + bool authorizedForThisIdentity(const resip::Data &user, const resip::Data &realm, resip::Uri &fromUri); + + void onAuthSuccess(const resip::SipMessage& msg); + void onAuthFailure(resip::ServerAuthManager::AuthFailureReason reason, const resip::SipMessage& msg); + +}; + +class MyRADIUSDigestAuthListener : public RADIUSDigestAuthListener { +private: + resip::Data user; + resip::Data realm; + resip::TransactionUser& tu; + resip::Data transactionId; +public: + MyRADIUSDigestAuthListener(const resip::Data& user, const resip::Data& realm, resip::TransactionUser& tu, const resip::Data& transactionId); + virtual ~MyRADIUSDigestAuthListener(); + void onSuccess(const resip::Data& rpid); + void onAccessDenied(); + void onError(); +}; + +} + +#endif + +#endif + diff --git a/src/libs/resiprocate/resip/dum/RedirectHandler.hxx b/src/libs/resiprocate/resip/dum/RedirectHandler.hxx new file mode 100644 index 00000000..982fadc6 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RedirectHandler.hxx @@ -0,0 +1,76 @@ +#if !defined(RESIP_REDIRECTHANDLER_HXX) +#define RESIP_REDIRECTHANDLER_HXX + + +namespace resip +{ + +class SipMessage; +class NameAddr; + +class RedirectHandler +{ + public: + virtual ~RedirectHandler() {} + + //3xx that isn't 380 or 305 has been received + virtual void onRedirectReceived(AppDialogSetHandle, const SipMessage& response)=0; + + //return true if this target is acceptable + virtual bool onTryingNextTarget(AppDialogSetHandle, const SipMessage& request)=0; +}; + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/RedirectManager.cxx b/src/libs/resiprocate/resip/dum/RedirectManager.cxx new file mode 100644 index 00000000..c51cd682 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RedirectManager.cxx @@ -0,0 +1,207 @@ +#include "resip/dum/RedirectManager.hxx" +#include "resip/stack/NameAddr.hxx" +#include "rutil/Logger.hxx" +#include "resip/dum/RedirectHandler.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/DialogSet.hxx" +#include "resip/dum/AppDialogSet.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +bool +RedirectManager::handle(DialogSet& dSet, SipMessage& origRequest, const SipMessage& response) +{ + assert( response.isResponse() ); + assert( origRequest.isRequest() ); + + //380, 305 fall through to the application + int code = response.header(h_StatusLine).statusCode(); + if (code < 300 || code == 380 || code == 305) + { + return false; + } + else if (code >= 300 && code < 400) + { + RedirectHandler* handler = dSet.mDum.getRedirectHandler(); + DialogSetId id(origRequest); + RedirectedRequestMap::iterator it = mRedirectedRequestMap.find(id); + + if (it == mRedirectedRequestMap.end()) + { + DebugLog( << "RedirectManager::handle: new TargetSet: " << id); + mRedirectedRequestMap[id] = new TargetSet(origRequest, mOrdering); + it = mRedirectedRequestMap.find(id); + } + if (handler) + { + handler->onRedirectReceived(dSet.mAppDialogSet->getHandle(), response); + } + TargetSet& tSet = *it->second; + tSet.addTargets(response); + + while(tSet.makeNextRequest(origRequest)) + { + if (handler) + { + if (handler->onTryingNextTarget(dSet.mAppDialogSet->getHandle(), origRequest)) + { + return true; + } + } + else //!dcm! -- accept all if no handler--should a handler be required? + { + return true; + } + } + delete it->second; + mRedirectedRequestMap.erase(it); + return false; + } + //5xx, 6xx different? + return false; +} + +void +RedirectManager::setOrdering(const Ordering& order) +{ + mOrdering = order; +} + +void +RedirectManager::TargetSet::addTargets(const SipMessage& msg) +{ + if (msg.exists(h_Contacts)) + { + for (NameAddrs::const_iterator it = msg.header(h_Contacts).begin(); it != msg.header(h_Contacts).end(); it++) + { + if (mTargetSet.find(*it) == mTargetSet.end()) + { + DebugLog( << "RedirectManager::TargetSet::addTargets:target: " << *it); + mTargetSet.insert(*it); + mTargetQueue.push(*it); + } + } + } +} + +bool +RedirectManager::TargetSet::makeNextRequest(SipMessage& request) +{ + request = mRequest; + //dispaly name, check if it's an invite, recurse if it isn't, throw if + //exhausted? Or make a boolean, elimnate hasTarget + while(!mTargetQueue.empty()) + { + try + { + request.mergeUri(mTargetQueue.top().uri()); + mTargetQueue.pop(); + if (request.isRequest()) + { + switch(request.header(h_RequestLine).method()) + { + case ACK: + case BYE: + case CANCEL: + case PRACK: + break; + default: + DebugLog(<< "RedirectManager::TargetSet::makeNextRequest: " << request); + request.header(h_CSeq).sequence()++; + return true; + } + } + } + catch(BaseException&) + { + DebugLog(<< "RedirectManager::TargetSet::makeNextRequest: error generating request"); + mTargetQueue.pop(); + } + } + return false; +} + +bool RedirectManager::Ordering::operator()(const NameAddr& lhs, const NameAddr& rhs) const +{ + if (lhs.exists(p_q)) + { + if (rhs.exists(p_q)) + { + return lhs.param(p_q) < rhs.param(p_q); + } + else + { + return lhs.param(p_q) < 1000; // 1.0 + } + } + else + { + // Note: if lhs is not present and treated as 1.0, it will never to less than rhs + return false; + } +} + +void RedirectManager::removeDialogSet(DialogSetId id) +{ + RedirectedRequestMap::iterator it = mRedirectedRequestMap.find(id); + + if (it != mRedirectedRequestMap.end()) + { + delete it->second; + mRedirectedRequestMap.erase(it); + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/RedirectManager.hxx b/src/libs/resiprocate/resip/dum/RedirectManager.hxx new file mode 100644 index 00000000..2e763302 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RedirectManager.hxx @@ -0,0 +1,129 @@ +#if !defined(RESIP_REDIRECTMANAGER_HXX) +#define RESIP_REDIRECTMANAGER_HXX + + +#include <set> +#include <queue> +#include <functional> +#include <vector> + +#include "resip/dum/Handles.hxx" +#include "resip/stack/NameAddr.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/DialogSetId.hxx" +#include "rutil/HashMap.hxx" + +//8.1.3.4 +//19.1.5 + +namespace resip +{ + +class DialogSet; + +class RedirectManager +{ + public: + class Ordering : public std::binary_function<const NameAddr&, const NameAddr&, bool> + { + public: + virtual ~Ordering() {} + virtual bool operator()(const NameAddr& lhs, const NameAddr& rhs) const; + }; + virtual ~RedirectManager() {} + virtual bool handle(DialogSet& dSet, SipMessage& origRequest, const SipMessage& response); + + //deafult is by q-value, no q-value treated as 1.0 + void setOrdering(const Ordering& order); + + void removeDialogSet(DialogSetId id); + + //based on follows 8.1.3.4 of 3261. Overload to interject user decisions + //or to process 301, 305 or 380 reponses. +// virtual void onRedirect(AppDialogSetHandle, const SipMessage& response); + //use a priority queue by q-value, and a list(linear, set too heavy?) of + //values that have been tried. Do q-values really have any meaning across + //different 3xx values? Or should the first 3xx always win. + protected: + class TargetSet + { + public: + TargetSet(const SipMessage& request, const Ordering& order) : + mTargetQueue(order), + mRequest(request) + {} + + void addTargets(const SipMessage& msg); + //pass in the message stored in the creator + bool makeNextRequest(SipMessage& request); + protected: + typedef std::set<NameAddr> EncounteredTargetSet; + typedef std::priority_queue<NameAddr, std::vector<NameAddr>, Ordering> TargetQueue; + + EncounteredTargetSet mTargetSet; + TargetQueue mTargetQueue; + //mLastRequest in creator is kept in sync with this, this is needed + //so that embedded information in a target uri does not migrate to + //the wrong attempt + SipMessage mRequest; + }; + + typedef HashMap<DialogSetId, TargetSet*> RedirectedRequestMap; + RedirectedRequestMap mRedirectedRequestMap; + Ordering mOrdering; +}; + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/RefCountedDestroyer.hxx b/src/libs/resiprocate/resip/dum/RefCountedDestroyer.hxx new file mode 100644 index 00000000..9466dd30 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RefCountedDestroyer.hxx @@ -0,0 +1,108 @@ +#if !defined(RESIP_REFCOUNTEDDESTROYER_HXX) +#define RESIP_REFCOUNTEDDESTROYER_HXX + +namespace resip +{ + +//designed to be used by composition, does not destroy itself. +template<class T> +class RefCountedDestroyer +{ + public: + class Guard + { + public: + void destroy() + { + mRefCountedDestroyer.mDestroying = true; + } + + bool destroyed() + { + return mRefCountedDestroyer.mDestroying; + } + + Guard(RefCountedDestroyer& rcd) + : mRefCountedDestroyer(rcd) + { + mRefCountedDestroyer.mCount++; + } + + ~Guard() + { + mRefCountedDestroyer.mCount--; + if (mRefCountedDestroyer.mDestroying && mRefCountedDestroyer.mCount == 0) + { + delete mRefCountedDestroyer.mTarget; + } + } + private: + RefCountedDestroyer& mRefCountedDestroyer; + }; + + RefCountedDestroyer(T* target) : + mTarget(target), + mCount(0), + mDestroying(false) + { + } + private: + friend class Guard; + T* mTarget; + int mCount; + bool mDestroying; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/RegistrationCreator.cxx b/src/libs/resiprocate/resip/dum/RegistrationCreator.cxx new file mode 100644 index 00000000..5a7f6c6e --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RegistrationCreator.cxx @@ -0,0 +1,76 @@ +#include "resip/dum/RegistrationCreator.hxx" +#include "resip/dum/ClientRegistration.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "rutil/Random.hxx" +#include "rutil/Logger.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +RegistrationCreator::RegistrationCreator(DialogUsageManager& dum, + const NameAddr& target, + SharedPtr<UserProfile> userProfile, + UInt32 registrationTime) + : BaseCreator(dum, userProfile) +{ + makeInitialRequest(target, target, REGISTER); + mLastRequest->header(h_RequestLine).uri().user() = Data::Empty; + mLastRequest->header(h_Expires).value() = registrationTime; + + // Tag Contact with rInstance, InstanceId, regId, and/or methods parameter according to profile settings + ClientRegistration::tagContact(mLastRequest->header(h_Contacts).front(), dum, userProfile); + + DebugLog ( << "RegistrationCreator::RegistrationCreator: " << mLastRequest); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/RegistrationCreator.hxx b/src/libs/resiprocate/resip/dum/RegistrationCreator.hxx new file mode 100644 index 00000000..b379e187 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RegistrationCreator.hxx @@ -0,0 +1,75 @@ +#if !defined(RESIP_REGISTRATIONCREATOR_HXX) +#define RESIP_REGISTRATIONCREATOR_HXX + +#include "resip/dum/BaseCreator.hxx" + +namespace resip +{ + +class DialogUsageManager; +class NameAddr; + +/** + This class creates registration requests on behalf of a client. + It has nothing to do with server handling of registration requests. + */ + +class RegistrationCreator : public BaseCreator +{ + public: + RegistrationCreator(DialogUsageManager& dum, const NameAddr& target, SharedPtr<UserProfile> userProfile, UInt32 RegistrationTime); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/RegistrationHandler.cxx b/src/libs/resiprocate/resip/dum/RegistrationHandler.cxx new file mode 100644 index 00000000..efd2e8d5 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RegistrationHandler.cxx @@ -0,0 +1,153 @@ +#include "resip/dum/MasterProfile.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/dum/RegistrationHandler.hxx" +#include "resip/dum/ClientRegistration.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +void +ClientRegistrationHandler::onFlowTerminated(ClientRegistrationHandle h) +{ + InfoLog (<< "ClientRegistrationHandler::onFlowTerminated, refreshing registration to open new flow"); + h->requestRefresh(); +} + +void +ServerRegistrationHandler::getGlobalExpires(const SipMessage& msg, SharedPtr<MasterProfile> masterProfile, + UInt32 &expires, UInt32 &returnCode) +{ + if (!masterProfile) + { + returnCode = 500; + assert(0); + return; + } + + expires=3600; + returnCode=0; + + if (!msg.empty(h_Expires) && msg.header(h_Expires).isWellFormed()) + { + //only client specified Expires value is subject to the min/max constraints, default is used if none specified. + expires = msg.header(h_Expires).value(); + + if (expires != 0) + { + //check min expires first since max expires will not return an error and will just change the expires value. + UInt32 minExpires = masterProfile->serverRegistrationMinExpiresTime(); + + if (expires < minExpires) + { + returnCode = 423; + expires = minExpires; + } + else + { + UInt32 maxExpires = masterProfile->serverRegistrationMaxExpiresTime(); + + if (expires > maxExpires) + { + expires = maxExpires; + } + } + } + } + else + { + expires = masterProfile->serverRegistrationDefaultExpiresTime(); + } +} + +void +ServerRegistrationHandler::getContactExpires(const NameAddr &contact, SharedPtr<MasterProfile> masterProfile, + UInt32 &expires, UInt32 &returnCode) +{ + if (!masterProfile) + { + returnCode = 500; + assert(0); + return; + } + + returnCode=0; + + if (contact.exists(p_expires)) + { + expires = contact.param(p_expires); + + if (expires != 0) + { + //check min expires first since max expires will not return an error and will just change the expires value. + UInt32 minExpires = masterProfile->serverRegistrationMinExpiresTime(); + + if (expires < minExpires) + { + returnCode = 423; + expires = minExpires; + } + else + { + UInt32 maxExpires = masterProfile->serverRegistrationMaxExpiresTime(); + + if (expires > maxExpires) + { + expires = maxExpires; + } + } + } + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/RegistrationHandler.hxx b/src/libs/resiprocate/resip/dum/RegistrationHandler.hxx new file mode 100644 index 00000000..9d3a4894 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RegistrationHandler.hxx @@ -0,0 +1,172 @@ +#if !defined(RESIP_REGISTRATIONHANDLER_HXX) +#define RESIP_REGISTRATIONHANDLER_HXX + +#include "resip/dum/Handles.hxx" +#include "rutil/SharedPtr.hxx" +#include "resip/dum/ContactInstanceRecord.hxx" + +namespace resip +{ + +class SipMessage; +class NameAddr; +class MasterProfile; + +class ClientRegistrationHandler +{ + public: + virtual ~ClientRegistrationHandler() { } + /// Called when registraion succeeds or each time it is sucessfully + /// refreshed (manual refreshes only). + virtual void onSuccess(ClientRegistrationHandle, const SipMessage& response)=0; + + // Called when all of my bindings have been removed + virtual void onRemoved(ClientRegistrationHandle, const SipMessage& response) = 0; + + /// call on Retry-After failure. + /// return values: -1 = fail, 0 = retry immediately, N = retry in N seconds + virtual int onRequestRetry(ClientRegistrationHandle, int retrySeconds, const SipMessage& response)=0; + + /// Called if registration fails, usage will be destroyed (unless a + /// Registration retry interval is enabled in the Profile) + virtual void onFailure(ClientRegistrationHandle, const SipMessage& response)=0; + + /// Called when a TCP or TLS flow to the server has terminated. This can be caused by socket + /// errors, or missing CRLF keep alives pong responses from the server. + // Called only if clientOutbound is enabled on the UserProfile and the first hop server + /// supports RFC5626 (outbound). + /// Default implementation is to immediately re-Register in an attempt to form a new flow. + virtual void onFlowTerminated(ClientRegistrationHandle); +}; + +class ServerRegistrationHandler +{ + public: + virtual ~ServerRegistrationHandler() {} + + /// Called when registration is refreshed + virtual void onRefresh(ServerRegistrationHandle, const SipMessage& reg)=0; + + /// called when one or more specified contacts is removed + virtual void onRemove(ServerRegistrationHandle, const SipMessage& reg)=0; + + /// Called when all the contacts are removed using "Contact: *" + virtual void onRemoveAll(ServerRegistrationHandle, const SipMessage& reg)=0; + + /** Called when one or more contacts are added. This is after + authentication has all succeeded */ + virtual void onAdd(ServerRegistrationHandle, const SipMessage& reg)=0; + + /// Called when a client queries for the list of current registrations + virtual void onQuery(ServerRegistrationHandle, const SipMessage& reg)=0; + + /// When processing a REGISTER request, return the desired expires value when processing the "Expires" header. + ///@param expires Set this to the desired expiration value for the set of contacts that do not explicitely + /// set the "expires" param. + ///@param returnCode If the REGISTER should be rejected, use this return code. A value of 423 will result in + ///the Min-Expires header added to the response. + /// + virtual void getGlobalExpires(const SipMessage& msg, + SharedPtr<MasterProfile> masterProfile, + UInt32 &expires, + UInt32 &returnCode); + + /// When processing a REGISTER request, return the desired expires value by processing this contact's expires + /// parameter. If the expires value is not modified in this function the global expires will be used. + /// @param expires Set this to the desired expiration value for this contact. + /// @param returnCode If the REGISTER should be rejected, use this return code. A value of 423 will result in + /// the Min-Expires header added to the response. + /// + virtual void getContactExpires(const NameAddr &contact, + SharedPtr<MasterProfile> masterProfile, + UInt32 &expires, + UInt32 &returnCode); + + /** If true, the registration processing will use the async* functions here and will not use the RegistrationPersistenceManager. + */ + virtual bool asyncProcessing(void) const + { + return false; + } + + /** Called when a REGISTER is first received to retrieve the current list. This list is then updated by the + registration logic in DUM. When the list is ready, call asyncProvideContacts() on the specified ServerRegistration. + */ + virtual void asyncGetContacts(ServerRegistrationHandle, const Uri& aor) + { + } + + /** Notifies the handler to update the current contact list for the AOR to the specified list that has been updated by + DUM's registration processing. This is normally called after the REGISTER has been processed and accepted by the user + (ServerRegistration::accept()) + */ + virtual void asyncUpdateContacts(ServerRegistrationHandle, + const Uri& aor, + std::auto_ptr<ContactPtrList> modifiedContactList, + std::auto_ptr<ContactRecordTransactionLog> transactionLog) + { + } + + /** Notifies the handler to remove the entries specified in the contacts parameter. + No further processing is required after receiving this message. + */ + virtual void asyncRemoveExpired(ServerRegistrationHandle, + const resip::Uri& aor, + std::auto_ptr<resip::ContactPtrList> contacts) + { + } +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/RegistrationPersistenceManager.hxx b/src/libs/resiprocate/resip/dum/RegistrationPersistenceManager.hxx new file mode 100644 index 00000000..3e19bf75 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RegistrationPersistenceManager.hxx @@ -0,0 +1,98 @@ +#if !defined(RESIP_REGISTRATIONPERSISTENCEMANAGER_HXX) +#define RESIP_REGISTRATIONPERSISTENCEMANAGER_HXX + +#include <list> +#include "resip/stack/Uri.hxx" +#include "resip/dum/ContactInstanceRecord.hxx" + +namespace resip +{ + +/** Abstract interface of a datastore of all registered endpoints processed by DUM. Derived classes implement the + actual storage of AOR's mapped to contact information. resip::InMemoryRegistrationDatabase is an example of a local datastore. + */ +class RegistrationPersistenceManager +{ + public: + typedef std::list<Uri> UriList; + + typedef enum + { + CONTACT_CREATED, + CONTACT_UPDATED + } update_status_t; + + RegistrationPersistenceManager() {} + virtual ~RegistrationPersistenceManager() {} + + virtual void addAor(const Uri& aor, const ContactList& contacts) = 0; + virtual void removeAor(const Uri& aor) = 0; + virtual bool aorIsRegistered(const Uri& aor) = 0; + + virtual void lockRecord(const Uri& aor) = 0; + virtual void unlockRecord(const Uri& aor) = 0; + + virtual void getAors(UriList& container) = 0; + + virtual update_status_t updateContact(const Uri& aor, + const ContactInstanceRecord& rec) = 0; + + virtual void removeContact(const Uri& aor, + const ContactInstanceRecord& rec) = 0; + + virtual void getContacts(const Uri& aor, ContactList& container) = 0; + +}; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/RemoteCertStore.hxx b/src/libs/resiprocate/resip/dum/RemoteCertStore.hxx new file mode 100644 index 00000000..4c3b23e8 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RemoteCertStore.hxx @@ -0,0 +1,70 @@ +#if !defined(RESIP_REMOTECERTSTORE_HXX) +#define RESIP_REMOTECERTSTORE_HXX + +#include "rutil/Data.hxx" +#include "resip/dum/CertMessage.hxx" + +namespace resip +{ + +class RemoteCertStore +{ + public: + RemoteCertStore() {} + virtual ~RemoteCertStore() {} + virtual void fetch(const Data& target, MessageId::Type type, const MessageId& id, TransactionUser& tu) = 0; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/RequestValidationHandler.hxx b/src/libs/resiprocate/resip/dum/RequestValidationHandler.hxx new file mode 100644 index 00000000..409bd24f --- /dev/null +++ b/src/libs/resiprocate/resip/dum/RequestValidationHandler.hxx @@ -0,0 +1,90 @@ +#if !defined(RESIP_REQUESTVALIDATIONHANDLER_HXX) +#define RESIP_REQUESTVALIDATIONHANDLER_HXX + +namespace resip +{ + +class SipMessage; + +/** + * Handler used to know when an incoming request failed validation. + * + * The callbacks are mostly useful to know that validation failed: + * they are not able to change SIP call flow (like the various + * failure responses sent back). + */ +class RequestValidationHandler +{ + public: + virtual ~RequestValidationHandler() {} + + virtual void onInvalidMethod(const SipMessage& request) = 0; + + virtual void onInvalidScheme(const SipMessage& request) = 0; + + virtual void onInvalidRequiredOptions(const SipMessage& request) = 0; + + virtual void on100RelNotSupportedByRemote(const SipMessage& request) = 0; + + virtual void onInvalidContentType(const SipMessage& request) = 0; + + virtual void onInvalidContentEncoding(const SipMessage& request) = 0; + + virtual void onInvalidContentLanguage(const SipMessage& request) = 0; + + virtual void onInvalidAccept(const SipMessage& request) = 0; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/AppDialog.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/AppDialog.obj new file mode 100644 index 00000000..38701021 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/AppDialog.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/AppDialogSet.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/AppDialogSet.obj new file mode 100644 index 00000000..7bf8113a Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/AppDialogSet.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/AppDialogSetFactory.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/AppDialogSetFactory.obj new file mode 100644 index 00000000..98350e58 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/AppDialogSetFactory.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/BaseCreator.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/BaseCreator.obj new file mode 100644 index 00000000..7d424c22 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/BaseCreator.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/BaseSubscription.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/BaseSubscription.obj new file mode 100644 index 00000000..c726a0c8 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/BaseSubscription.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/BaseUsage.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/BaseUsage.obj new file mode 100644 index 00000000..01e6a55f Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/BaseUsage.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/CertMessage.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/CertMessage.obj new file mode 100644 index 00000000..f049bd16 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/CertMessage.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ChallengeInfo.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ChallengeInfo.obj new file mode 100644 index 00000000..c38d027b Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ChallengeInfo.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ClientAuthExtension.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientAuthExtension.obj new file mode 100644 index 00000000..147b01cd Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientAuthExtension.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ClientAuthManager.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientAuthManager.obj new file mode 100644 index 00000000..41767f22 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientAuthManager.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ClientInviteSession.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientInviteSession.obj new file mode 100644 index 00000000..33263635 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientInviteSession.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ClientOutOfDialogReq.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientOutOfDialogReq.obj new file mode 100644 index 00000000..9f5e79ed Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientOutOfDialogReq.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ClientPagerMessage.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientPagerMessage.obj new file mode 100644 index 00000000..d588ac04 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientPagerMessage.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ClientPublication.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientPublication.obj new file mode 100644 index 00000000..e085a764 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientPublication.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ClientRegistration.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientRegistration.obj new file mode 100644 index 00000000..c48d4024 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientRegistration.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ClientSubscription.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientSubscription.obj new file mode 100644 index 00000000..38c89983 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ClientSubscription.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ContactInstanceRecord.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ContactInstanceRecord.obj new file mode 100644 index 00000000..39adec05 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ContactInstanceRecord.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DefaultServerReferHandler.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DefaultServerReferHandler.obj new file mode 100644 index 00000000..dea20c98 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DefaultServerReferHandler.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DestroyUsage.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DestroyUsage.obj new file mode 100644 index 00000000..fbcd2e42 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DestroyUsage.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/Dialog.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/Dialog.obj new file mode 100644 index 00000000..c1dc7b34 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/Dialog.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DialogEventInfo.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogEventInfo.obj new file mode 100644 index 00000000..9bf37085 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogEventInfo.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DialogEventStateManager.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogEventStateManager.obj new file mode 100644 index 00000000..540bbaa7 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogEventStateManager.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DialogId.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogId.obj new file mode 100644 index 00000000..192a49d3 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogId.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DialogSet.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogSet.obj new file mode 100644 index 00000000..a6b9e37e Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogSet.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DialogSetId.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogSetId.obj new file mode 100644 index 00000000..fd583304 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogSetId.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DialogUsage.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogUsage.obj new file mode 100644 index 00000000..d0eda339 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogUsage.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DialogUsageManager.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogUsageManager.obj new file mode 100644 index 00000000..ab8980e1 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DialogUsageManager.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DumDecrypted.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DumDecrypted.obj new file mode 100644 index 00000000..fa31ebe1 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DumDecrypted.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DumFeature.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DumFeature.obj new file mode 100644 index 00000000..57e8075b Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DumFeature.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DumFeatureChain.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DumFeatureChain.obj new file mode 100644 index 00000000..28b99fbb Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DumFeatureChain.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DumFeatureMessage.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DumFeatureMessage.obj new file mode 100644 index 00000000..34477b91 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DumFeatureMessage.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DumHelper.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DumHelper.obj new file mode 100644 index 00000000..e564e32d Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DumHelper.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DumProcessHandler.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DumProcessHandler.obj new file mode 100644 index 00000000..dbea4d4f Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DumProcessHandler.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DumThread.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DumThread.obj new file mode 100644 index 00000000..b5636fcf Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DumThread.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/DumTimeout.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/DumTimeout.obj new file mode 100644 index 00000000..49c50d65 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/DumTimeout.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/EncryptionManager.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/EncryptionManager.obj new file mode 100644 index 00000000..be8ebd91 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/EncryptionManager.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/EncryptionRequest.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/EncryptionRequest.obj new file mode 100644 index 00000000..e669017e Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/EncryptionRequest.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/Handle.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/Handle.obj new file mode 100644 index 00000000..26fe0a73 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/Handle.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/HandleException.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/HandleException.obj new file mode 100644 index 00000000..5a86789f Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/HandleException.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/HandleManager.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/HandleManager.obj new file mode 100644 index 00000000..c9dff5b9 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/HandleManager.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/Handled.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/Handled.obj new file mode 100644 index 00000000..28f53fb9 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/Handled.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/HttpGetMessage.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/HttpGetMessage.obj new file mode 100644 index 00000000..56e7adfd Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/HttpGetMessage.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/HttpProvider.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/HttpProvider.obj new file mode 100644 index 00000000..f474cda8 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/HttpProvider.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/IdentityHandler.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/IdentityHandler.obj new file mode 100644 index 00000000..fc246e23 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/IdentityHandler.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/InMemoryRegistrationDatabase.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/InMemoryRegistrationDatabase.obj new file mode 100644 index 00000000..08d4062a Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/InMemoryRegistrationDatabase.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/InMemorySyncRegDb.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/InMemorySyncRegDb.obj new file mode 100644 index 00000000..a1bc1357 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/InMemorySyncRegDb.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/InviteSession.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/InviteSession.obj new file mode 100644 index 00000000..3f03237e Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/InviteSession.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/InviteSessionCreator.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/InviteSessionCreator.obj new file mode 100644 index 00000000..26d1cef8 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/InviteSessionCreator.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/InviteSessionHandler.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/InviteSessionHandler.obj new file mode 100644 index 00000000..fb37d5ca Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/InviteSessionHandler.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/KeepAliveManager.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/KeepAliveManager.obj new file mode 100644 index 00000000..5b7be461 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/KeepAliveManager.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/KeepAliveTimeout.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/KeepAliveTimeout.obj new file mode 100644 index 00000000..8f57c4cb Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/KeepAliveTimeout.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/MasterProfile.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/MasterProfile.obj new file mode 100644 index 00000000..3bf807d0 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/MasterProfile.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/MergedRequestKey.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/MergedRequestKey.obj new file mode 100644 index 00000000..dc4cf2ea Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/MergedRequestKey.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/MergedRequestRemovalCommand.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/MergedRequestRemovalCommand.obj new file mode 100644 index 00000000..ffa77110 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/MergedRequestRemovalCommand.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/NetworkAssociation.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/NetworkAssociation.obj new file mode 100644 index 00000000..e4a464ee Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/NetworkAssociation.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/NonDialogUsage.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/NonDialogUsage.obj new file mode 100644 index 00000000..759cbd77 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/NonDialogUsage.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/OutOfDialogReqCreator.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/OutOfDialogReqCreator.obj new file mode 100644 index 00000000..81cbca1f Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/OutOfDialogReqCreator.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/OutgoingEvent.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/OutgoingEvent.obj new file mode 100644 index 00000000..69487d78 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/OutgoingEvent.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/PagerMessageCreator.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/PagerMessageCreator.obj new file mode 100644 index 00000000..fc11cee5 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/PagerMessageCreator.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/Profile.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/Profile.obj new file mode 100644 index 00000000..5f9127b5 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/Profile.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/PublicationCreator.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/PublicationCreator.obj new file mode 100644 index 00000000..922cf198 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/PublicationCreator.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/RedirectManager.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/RedirectManager.obj new file mode 100644 index 00000000..18ab5f02 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/RedirectManager.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/RegistrationCreator.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/RegistrationCreator.obj new file mode 100644 index 00000000..4942c650 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/RegistrationCreator.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/RegistrationHandler.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/RegistrationHandler.obj new file mode 100644 index 00000000..e265f1b9 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/RegistrationHandler.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ServerAuthManager.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerAuthManager.obj new file mode 100644 index 00000000..4ba9fb7c Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerAuthManager.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ServerInviteSession.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerInviteSession.obj new file mode 100644 index 00000000..d4bee047 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerInviteSession.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ServerOutOfDialogReq.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerOutOfDialogReq.obj new file mode 100644 index 00000000..b6e89c26 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerOutOfDialogReq.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ServerPagerMessage.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerPagerMessage.obj new file mode 100644 index 00000000..82892dc0 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerPagerMessage.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ServerPublication.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerPublication.obj new file mode 100644 index 00000000..ce04b860 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerPublication.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ServerRegistration.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerRegistration.obj new file mode 100644 index 00000000..cd6b4849 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerRegistration.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/ServerSubscription.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerSubscription.obj new file mode 100644 index 00000000..b4738481 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/ServerSubscription.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/SubscriptionCreator.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/SubscriptionCreator.obj new file mode 100644 index 00000000..22680727 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/SubscriptionCreator.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/SubscriptionHandler.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/SubscriptionHandler.obj new file mode 100644 index 00000000..48c46938 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/SubscriptionHandler.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/SubscriptionState.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/SubscriptionState.obj new file mode 100644 index 00000000..f0305b2c Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/SubscriptionState.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/TargetCommand.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/TargetCommand.obj new file mode 100644 index 00000000..d6977e8a Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/TargetCommand.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/TlsPeerAuthManager.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/TlsPeerAuthManager.obj new file mode 100644 index 00000000..8e6119fa Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/TlsPeerAuthManager.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/UserAuthInfo.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/UserAuthInfo.obj new file mode 100644 index 00000000..f2651966 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/UserAuthInfo.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/UserProfile.obj b/src/libs/resiprocate/resip/dum/SSL-Debug/UserProfile.obj new file mode 100644 index 00000000..0cef7f51 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/UserProfile.obj differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/dum.Build.CppClean.log b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.Build.CppClean.log new file mode 100644 index 00000000..97e177e7 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.Build.CppClean.log @@ -0,0 +1,87 @@ +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\vc120.pdb +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dum.lib +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dum_9_0.vcxprojresolveassemblyreference.cache +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\appdialog.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\appdialogset.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\appdialogsetfactory.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\basecreator.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\basesubscription.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\baseusage.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\certmessage.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\challengeinfo.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\clientauthextension.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\clientauthmanager.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\clientinvitesession.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\clientoutofdialogreq.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\clientpagermessage.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\clientpublication.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\clientregistration.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\clientsubscription.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\contactinstancerecord.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\defaultserverreferhandler.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\destroyusage.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dialog.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dialogeventinfo.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dialogeventstatemanager.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dialogid.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dialogset.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dialogsetid.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dialogusage.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dialogusagemanager.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dumdecrypted.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dumfeature.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dumfeaturechain.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dumfeaturemessage.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dumhelper.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dumprocesshandler.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dumthread.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dumtimeout.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\encryptionmanager.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\encryptionrequest.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\handle.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\handled.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\handleexception.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\handlemanager.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\httpgetmessage.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\httpprovider.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\identityhandler.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\inmemoryregistrationdatabase.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\inmemorysyncregdb.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\invitesession.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\invitesessioncreator.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\invitesessionhandler.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\keepalivemanager.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\keepalivetimeout.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\masterprofile.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\mergedrequestkey.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\mergedrequestremovalcommand.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\networkassociation.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\nondialogusage.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\outgoingevent.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\outofdialogreqcreator.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\pagermessagecreator.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\profile.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\publicationcreator.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\redirectmanager.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\registrationcreator.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\registrationhandler.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\serverauthmanager.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\serverinvitesession.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\serveroutofdialogreq.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\serverpagermessage.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\serverpublication.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\serverregistration.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\serversubscription.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\subscriptioncreator.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\subscriptionhandler.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\subscriptionstate.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\targetcommand.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\tlspeerauthmanager.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\userauthinfo.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\userprofile.obj +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dum.tlog\cl.command.1.tlog +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dum.tlog\cl.read.1.tlog +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dum.tlog\cl.write.1.tlog +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dum.tlog\lib-link.read.1.tlog +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dum.tlog\lib-link.write.1.tlog +c:\works\own\rtphone\libs\resiprocate\resip\dum\ssl-debug\dum.tlog\lib.command.1.tlog diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/dum.lib b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.lib new file mode 100644 index 00000000..15b5b42e Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.lib differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/CL.read.1.tlog b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/CL.read.1.tlog new file mode 100644 index 00000000..ea597600 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/CL.read.1.tlog differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/Lib-link.read.1.tlog b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/Lib-link.read.1.tlog new file mode 100644 index 00000000..14b37b4f Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/Lib-link.read.1.tlog differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/Lib-link.write.1.tlog b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/Lib-link.write.1.tlog new file mode 100644 index 00000000..ffc8f236 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/Lib-link.write.1.tlog differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/cl.command.1.tlog b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/cl.command.1.tlog new file mode 100644 index 00000000..7815d818 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/cl.command.1.tlog differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/cl.write.1.tlog b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/cl.write.1.tlog new file mode 100644 index 00000000..71b8e1fb Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/cl.write.1.tlog differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/dum.lastbuildstate b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/dum.lastbuildstate new file mode 100644 index 00000000..9849a2df --- /dev/null +++ b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/dum.lastbuildstate @@ -0,0 +1,2 @@ +#TargetFrameworkVersion=v4.0:PlatformToolSet=v120:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit +SSL-Debug|Win32|C:\works\own\rtphone\| diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/lib.command.1.tlog b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/lib.command.1.tlog new file mode 100644 index 00000000..b90df362 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/dum.tlog/lib.command.1.tlog differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/dum_9_0.log b/src/libs/resiprocate/resip/dum/SSL-Debug/dum_9_0.log new file mode 100644 index 00000000..f95da97f --- /dev/null +++ b/src/libs/resiprocate/resip/dum/SSL-Debug/dum_9_0.log @@ -0,0 +1,167 @@ +Build started 10/22/2015 4:21:53 PM. + 1>Project "C:\works\own\rtphone\Libs\resiprocate\resip\dum\dum_9_0.vcxproj" on node 3 (Rebuild target(s)). + 1>ClCompile: + C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\CL.exe /c /IC:\works\own\rtphone\Libs\resiprocate\resip\dum\/../../ /IC:\works\own\rtphone\Libs\resiprocate\resip\dum\/../../../ /IC:\works\own\rtphone\Libs\resiprocate\resip\dum\../../../openssl/include /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D USE_ARES /D LEAK_CHECK /D USE_IPV6 /D USE_SSL /D _VC80_UPGRADE=0x0710 /D _MBCS /Gm- /EHsc /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /GR /Fo"SSL-Debug\\" /Fd"SSL-Debug\vc120.pdb" /Gd /TP /analyze- /errorReport:prompt /MP AppDialog.cxx AppDialogSet.cxx AppDialogSetFactory.cxx BaseCreator.cxx BaseSubscription.cxx BaseUsage.cxx CertMessage.cxx ChallengeInfo.cxx ClientAuthExtension.cxx ClientAuthManager.cxx ClientInviteSession.cxx ClientOutOfDialogReq.cxx ClientPagerMessage.cxx ClientPublication.cxx ClientRegistration.cxx ClientSubscription.cxx ContactInstanceRecord.cxx DefaultServerReferHandler.cxx DestroyUsage.cxx Dialog.cxx DialogEventInfo.cxx DialogEventStateManager.cxx DialogId.cxx DialogSet.cxx DialogSetId.cxx DialogUsage.cxx DialogUsageManager.cxx DumDecrypted.cxx DumFeature.cxx DumFeatureChain.cxx DumFeatureMessage.cxx DumHelper.cxx DumProcessHandler.cxx DumThread.cxx DumTimeout.cxx ssl\EncryptionManager.cxx EncryptionRequest.cxx Handle.cxx Handled.cxx HandleException.cxx HandleManager.cxx HttpGetMessage.cxx HttpProvider.cxx IdentityHandler.cxx InMemoryRegistrationDatabase.cxx InMemorySyncRegDb.cxx InviteSession.cxx InviteSessionCreator.cxx InviteSessionHandler.cxx KeepAliveManager.cxx KeepAliveTimeout.cxx MasterProfile.cxx MergedRequestKey.cxx MergedRequestRemovalCommand.cxx NetworkAssociation.cxx NonDialogUsage.cxx OutgoingEvent.cxx OutOfDialogReqCreator.cxx PagerMessageCreator.cxx Profile.cxx PublicationCreator.cxx RedirectManager.cxx RegistrationCreator.cxx RegistrationHandler.cxx ServerAuthManager.cxx ServerInviteSession.cxx ServerOutOfDialogReq.cxx ServerPagerMessage.cxx ServerPublication.cxx ServerRegistration.cxx ServerSubscription.cxx SubscriptionCreator.cxx SubscriptionHandler.cxx SubscriptionState.cxx TargetCommand.cxx TlsPeerAuthManager.cxx UserAuthInfo.cxx UserProfile.cxx + AppDialog.cxx + AppDialogSet.cxx + AppDialogSetFactory.cxx + BaseCreator.cxx + BaseSubscription.cxx + BaseUsage.cxx + CertMessage.cxx + ChallengeInfo.cxx + ClientAuthExtension.cxx + ClientAuthManager.cxx + ClientInviteSession.cxx + ClientOutOfDialogReq.cxx + ClientPagerMessage.cxx + ClientPublication.cxx + ClientRegistration.cxx + ClientSubscription.cxx + ContactInstanceRecord.cxx + DefaultServerReferHandler.cxx + DestroyUsage.cxx + Dialog.cxx + DialogEventInfo.cxx + DialogEventStateManager.cxx + DialogId.cxx + DialogSet.cxx + DialogSetId.cxx + DialogUsage.cxx + DialogUsageManager.cxx + DumDecrypted.cxx + DumFeature.cxx + DumFeatureChain.cxx + DumFeatureMessage.cxx + DumHelper.cxx + DumProcessHandler.cxx + DumThread.cxx + DumTimeout.cxx + EncryptionManager.cxx + EncryptionRequest.cxx + Handle.cxx + Handled.cxx + HandleException.cxx + HandleManager.cxx + HttpGetMessage.cxx + HttpProvider.cxx + IdentityHandler.cxx + InMemoryRegistrationDatabase.cxx + InMemorySyncRegDb.cxx + InviteSession.cxx + InviteSessionCreator.cxx + InviteSessionHandler.cxx + KeepAliveManager.cxx + KeepAliveTimeout.cxx + MasterProfile.cxx + MergedRequestKey.cxx + MergedRequestRemovalCommand.cxx + NetworkAssociation.cxx + NonDialogUsage.cxx + OutgoingEvent.cxx + OutOfDialogReqCreator.cxx + PagerMessageCreator.cxx + Profile.cxx + PublicationCreator.cxx + RedirectManager.cxx + RegistrationCreator.cxx + RegistrationHandler.cxx + ServerAuthManager.cxx + ServerInviteSession.cxx + ServerOutOfDialogReq.cxx + ServerPagerMessage.cxx + ServerPublication.cxx + ServerRegistration.cxx + ServerSubscription.cxx + SubscriptionCreator.cxx + SubscriptionHandler.cxx + SubscriptionState.cxx + TargetCommand.cxx + TlsPeerAuthManager.cxx + UserAuthInfo.cxx + UserProfile.cxx + Lib: + C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\Lib.exe /OUT:"SSL-Debug\dum.lib" /NOLOGO "SSL-Debug\AppDialog.obj" + "SSL-Debug\AppDialogSet.obj" + "SSL-Debug\AppDialogSetFactory.obj" + "SSL-Debug\BaseCreator.obj" + "SSL-Debug\BaseSubscription.obj" + "SSL-Debug\BaseUsage.obj" + "SSL-Debug\CertMessage.obj" + "SSL-Debug\ChallengeInfo.obj" + "SSL-Debug\ClientAuthExtension.obj" + "SSL-Debug\ClientAuthManager.obj" + "SSL-Debug\ClientInviteSession.obj" + "SSL-Debug\ClientOutOfDialogReq.obj" + "SSL-Debug\ClientPagerMessage.obj" + "SSL-Debug\ClientPublication.obj" + "SSL-Debug\ClientRegistration.obj" + "SSL-Debug\ClientSubscription.obj" + "SSL-Debug\ContactInstanceRecord.obj" + "SSL-Debug\DefaultServerReferHandler.obj" + "SSL-Debug\DestroyUsage.obj" + "SSL-Debug\Dialog.obj" + "SSL-Debug\DialogEventInfo.obj" + "SSL-Debug\DialogEventStateManager.obj" + "SSL-Debug\DialogId.obj" + "SSL-Debug\DialogSet.obj" + "SSL-Debug\DialogSetId.obj" + "SSL-Debug\DialogUsage.obj" + "SSL-Debug\DialogUsageManager.obj" + "SSL-Debug\DumDecrypted.obj" + "SSL-Debug\DumFeature.obj" + "SSL-Debug\DumFeatureChain.obj" + "SSL-Debug\DumFeatureMessage.obj" + "SSL-Debug\DumHelper.obj" + "SSL-Debug\DumProcessHandler.obj" + "SSL-Debug\DumThread.obj" + "SSL-Debug\DumTimeout.obj" + "SSL-Debug\EncryptionManager.obj" + "SSL-Debug\EncryptionRequest.obj" + "SSL-Debug\Handle.obj" + "SSL-Debug\Handled.obj" + "SSL-Debug\HandleException.obj" + "SSL-Debug\HandleManager.obj" + "SSL-Debug\HttpGetMessage.obj" + "SSL-Debug\HttpProvider.obj" + "SSL-Debug\IdentityHandler.obj" + "SSL-Debug\InMemoryRegistrationDatabase.obj" + "SSL-Debug\InMemorySyncRegDb.obj" + "SSL-Debug\InviteSession.obj" + "SSL-Debug\InviteSessionCreator.obj" + "SSL-Debug\InviteSessionHandler.obj" + "SSL-Debug\KeepAliveManager.obj" + "SSL-Debug\KeepAliveTimeout.obj" + "SSL-Debug\MasterProfile.obj" + "SSL-Debug\MergedRequestKey.obj" + "SSL-Debug\MergedRequestRemovalCommand.obj" + "SSL-Debug\NetworkAssociation.obj" + "SSL-Debug\NonDialogUsage.obj" + "SSL-Debug\OutgoingEvent.obj" + "SSL-Debug\OutOfDialogReqCreator.obj" + "SSL-Debug\PagerMessageCreator.obj" + "SSL-Debug\Profile.obj" + "SSL-Debug\PublicationCreator.obj" + "SSL-Debug\RedirectManager.obj" + "SSL-Debug\RegistrationCreator.obj" + "SSL-Debug\RegistrationHandler.obj" + "SSL-Debug\ServerAuthManager.obj" + "SSL-Debug\ServerInviteSession.obj" + "SSL-Debug\ServerOutOfDialogReq.obj" + "SSL-Debug\ServerPagerMessage.obj" + "SSL-Debug\ServerPublication.obj" + "SSL-Debug\ServerRegistration.obj" + "SSL-Debug\ServerSubscription.obj" + "SSL-Debug\SubscriptionCreator.obj" + "SSL-Debug\SubscriptionHandler.obj" + "SSL-Debug\SubscriptionState.obj" + "SSL-Debug\TargetCommand.obj" + "SSL-Debug\TlsPeerAuthManager.obj" + "SSL-Debug\UserAuthInfo.obj" + "SSL-Debug\UserProfile.obj" + dum_9_0.vcxproj -> C:\works\own\rtphone\Libs\resiprocate\resip\dum\SSL-Debug\dum.lib + 1>Done Building Project "C:\works\own\rtphone\Libs\resiprocate\resip\dum\dum_9_0.vcxproj" (Rebuild target(s)). + +Build succeeded. + +Time Elapsed 00:04:49.17 diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/dum_9_0.vcxprojResolveAssemblyReference.cache b/src/libs/resiprocate/resip/dum/SSL-Debug/dum_9_0.vcxprojResolveAssemblyReference.cache new file mode 100644 index 00000000..c8b91cce Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/dum_9_0.vcxprojResolveAssemblyReference.cache differ diff --git a/src/libs/resiprocate/resip/dum/SSL-Debug/vc120.pdb b/src/libs/resiprocate/resip/dum/SSL-Debug/vc120.pdb new file mode 100644 index 00000000..106ac109 Binary files /dev/null and b/src/libs/resiprocate/resip/dum/SSL-Debug/vc120.pdb differ diff --git a/src/libs/resiprocate/resip/dum/ServerAuthManager.cxx b/src/libs/resiprocate/resip/dum/ServerAuthManager.cxx new file mode 100644 index 00000000..9fe4f4a3 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerAuthManager.cxx @@ -0,0 +1,481 @@ +#include <cassert> + +#include "resip/dum/ChallengeInfo.hxx" +#include "resip/dum/DumFeature.hxx" +#include "resip/dum/DumFeatureChain.hxx" +#include "resip/dum/ServerAuthManager.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/TargetCommand.hxx" +#include "rutil/Logger.hxx" +#include "resip/dum/UserAuthInfo.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; +using namespace std; + +ServerAuthManager::ServerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, bool challengeThirdParties) : + DumFeature(dum, target), + mChallengeThirdParties(challengeThirdParties) +{ +} + + +ServerAuthManager::~ServerAuthManager() +{ + InfoLog(<< "~ServerAuthManager: " << mMessages.size() << " messages in memory when destroying."); +} + +// !bwc! We absolutely, positively, MUST NOT throw here. This is because in +// DialogUsageManager::process(), we do not know if a DumFeature has taken +// ownership of msg until we get a return. If we throw, the ownership of msg +// is unknown. This is unacceptable. +DumFeature::ProcessingResult +ServerAuthManager::process(Message* msg) +{ + SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg); + + if (sipMsg) + { + //!dcm! -- unecessary happens in handle + switch ( handle(sipMsg) ) + { + case ServerAuthManager::Challenged: + InfoLog(<< "ServerAuth challenged request " << sipMsg->brief()); + return DumFeature::ChainDoneAndEventDone; + case ServerAuthManager::RequestedInfo: + InfoLog(<< "ServerAuth requested info (requiresChallenge) " << sipMsg->brief()); + return DumFeature::EventTaken; + case ServerAuthManager::RequestedCredentials: + InfoLog(<< "ServerAuth requested credentials " << sipMsg->brief()); + return DumFeature::EventTaken; + case ServerAuthManager::Rejected: + InfoLog(<< "ServerAuth rejected request " << sipMsg->brief()); + return DumFeature::ChainDoneAndEventDone; + default: // includes Skipped + return DumFeature::FeatureDone; + } + } + + ChallengeInfo* challengeInfo = dynamic_cast<ChallengeInfo*>(msg); + if(challengeInfo) + { + InfoLog(<< "ServerAuth got ChallengeInfo " << challengeInfo->brief()); + MessageMap::iterator it = mMessages.find(challengeInfo->getTransactionId()); + assert(it != mMessages.end()); + std::auto_ptr<SipMessage> sipMsg(it->second); + mMessages.erase(it); + + if(challengeInfo->isFailed()) + { + // some kind of failure occurred while checking whether a + // challenge is required + InfoLog(<< "ServerAuth requiresChallenge() async failed"); + SharedPtr<SipMessage> response(new SipMessage); + Helper::makeResponse(*response, *sipMsg, 500, "Server Internal Error"); + mDum.send(response); + return DumFeature::ChainDoneAndEventDone; + } + + if(challengeInfo->isChallengeRequired()) + { + issueChallenge(sipMsg.get()); + InfoLog(<< "ServerAuth challenged request (after async) " << sipMsg->brief()); + return DumFeature::ChainDoneAndEventDone; + } + else + { + // challenge is not required, re-instate original message + postCommand(auto_ptr<Message>(sipMsg)); + return FeatureDoneAndEventDone; + } + } + + UserAuthInfo* userAuth = dynamic_cast<UserAuthInfo*>(msg); + if (userAuth) + { + //InfoLog(<< "Got UserAuthInfo"); + UserAuthInfo* userAuth = dynamic_cast<UserAuthInfo*>(msg); + if (userAuth) + { + Message* result = handleUserAuthInfo(userAuth); + if (result) + { + postCommand(auto_ptr<Message>(result)); + return FeatureDoneAndEventDone; + } + else + { + InfoLog(<< "ServerAuth rejected request " << *userAuth); + return ChainDoneAndEventDone; + } + } + } + return FeatureDone; +} + +SipMessage* +ServerAuthManager::handleUserAuthInfo(UserAuthInfo* userAuth) +{ + assert(userAuth); + + MessageMap::iterator it = mMessages.find(userAuth->getTransactionId()); + assert(it != mMessages.end()); + SipMessage* requestWithAuth = it->second; + mMessages.erase(it); + + InfoLog( << "Checking for auth result in realm=" << userAuth->getRealm() + << " A1=" << userAuth->getA1()); + + if (userAuth->getMode() == UserAuthInfo::UserUnknown || + (userAuth->getMode() == UserAuthInfo::RetrievedA1 && userAuth->getA1().empty())) + { + InfoLog (<< "User unknown " << userAuth->getUser() << " in " << userAuth->getRealm()); + SharedPtr<SipMessage> response(new SipMessage); + Helper::makeResponse(*response, *requestWithAuth, 404, "User unknown."); + mDum.send(response); + onAuthFailure(BadCredentials, *requestWithAuth); + delete requestWithAuth; + return 0; + } + + if (userAuth->getMode() == UserAuthInfo::Error) + { + InfoLog (<< "Error in auth procedure for " << userAuth->getUser() << " in " << userAuth->getRealm()); + SharedPtr<SipMessage> response(new SipMessage); + Helper::makeResponse(*response, *requestWithAuth, 503, "Server Error."); + mDum.send(response); + onAuthFailure(Error, *requestWithAuth); + delete requestWithAuth; + return 0; + } + + bool stale = false; + bool digestAccepted = (userAuth->getMode() == UserAuthInfo::DigestAccepted); + if(userAuth->getMode() == UserAuthInfo::RetrievedA1) + { + //!dcm! -- need to handle stale/unit test advancedAuthenticateRequest + //!dcm! -- delta? deal with. + std::pair<Helper::AuthResult,Data> resPair = + Helper::advancedAuthenticateRequest(*requestWithAuth, + userAuth->getRealm(), + userAuth->getA1(), + 3000, + proxyAuthenticationMode()); + + switch (resPair.first) + { + case Helper::Authenticated: + digestAccepted = true; + break; + case Helper::Failed: + // digestAccepted = false; // already false by default + break; + case Helper::BadlyFormed: + if(rejectBadNonces()) + { + InfoLog (<< "Authentication nonce badly formed for " << userAuth->getUser()); + + SharedPtr<SipMessage> response(new SipMessage); + Helper::makeResponse(*response, *requestWithAuth, 403, "Invalid nonce"); + mDum.send(response); + onAuthFailure(InvalidRequest, *requestWithAuth); + delete requestWithAuth; + return 0; + } + else + { + stale=true; + } + break; + case Helper::Expired: + stale = true; + break; + default: + break; + } + } + + if(stale || userAuth->getMode() == UserAuthInfo::Stale) + { + InfoLog (<< "Nonce expired for " << userAuth->getUser()); + + issueChallenge(requestWithAuth); + delete requestWithAuth; + return 0; + } + + if(digestAccepted) + { + if (authorizedForThisIdentity(userAuth->getUser(), userAuth->getRealm(), + requestWithAuth->header(h_From).uri())) + { + InfoLog (<< "Authorized request for " << userAuth->getRealm()); + onAuthSuccess(*requestWithAuth); + return requestWithAuth; + } + else + { + // !rwm! The user is trying to forge a request. Respond with a 403 + InfoLog (<< "User: " << userAuth->getUser() << " at realm: " << userAuth->getRealm() << + " trying to forge request from: " << requestWithAuth->header(h_From).uri()); + + SharedPtr<SipMessage> response(new SipMessage); + Helper::makeResponse(*response, *requestWithAuth, 403, "Invalid user name provided"); + mDum.send(response); + onAuthFailure(InvalidRequest, *requestWithAuth); + delete requestWithAuth; + return 0; + } + } + else + { + // Handles digestAccepted == false, DigestNotAccepted and any other + // case that is not recognised by the foregoing logic + + InfoLog (<< "Invalid password provided for " << userAuth->getUser() << " in " << userAuth->getRealm()); + InfoLog (<< " a1 hash of password from db was " << userAuth->getA1() ); + + SharedPtr<SipMessage> response(new SipMessage); + Helper::makeResponse(*response, *requestWithAuth, 403, "Invalid password provided"); + mDum.send(response); + onAuthFailure(BadCredentials, *requestWithAuth); + delete requestWithAuth; + return 0; + } +} + + +bool +ServerAuthManager::useAuthInt() const +{ + return false; +} + + +bool +ServerAuthManager::proxyAuthenticationMode() const +{ + return true; +} + + +bool +ServerAuthManager::rejectBadNonces() const +{ + return true; +} + + +ServerAuthManager::AsyncBool +ServerAuthManager::requiresChallenge(const SipMessage& msg) +{ + if(!mChallengeThirdParties) + { + const Uri& fromUri = msg.header(h_From).uri(); + if(!mDum.isMyDomain(fromUri.host())) + return False; + } + return True; +} + + +bool +ServerAuthManager::authorizedForThisIdentity(const resip::Data &user, + const resip::Data &realm, + resip::Uri &fromUri) +{ + // !rwm! good enough for now. TODO eventually consult a database to see what + // combinations of user/realm combos are authorized for an identity + + // First try the form where the username parameter in the auth + // header is just the username component of the fromUri + // + if ((fromUri.user() == user) && (fromUri.host() == realm)) + return true; + + // Now try the form where the username parameter in the auth + // header is the full fromUri, e.g. + // Proxy-Authorization: Digest username="user@domain" ... + // + if ((fromUri.getAorNoPort() == user) && (fromUri.host() == realm)) + return true; + + // catch-all: access denied + return false; +} + + +const Data& +ServerAuthManager::getChallengeRealm(const SipMessage& msg) +{ + return msg.header(h_RequestLine).uri().host(); +} + + +bool +ServerAuthManager::isMyRealm(const Data& realm) +{ + return mDum.isMyDomain(realm); +} + + +// return true if request has been consumed +ServerAuthManager::Result +ServerAuthManager::handle(SipMessage* sipMsg) +{ + //InfoLog( << "trying to do auth" ); + if (sipMsg->isRequest() && + sipMsg->header(h_RequestLine).method() != ACK && + sipMsg->header(h_RequestLine).method() != CANCEL) // Do not challenge ACKs or CANCELs + { + ParserContainer<Auth>* auths; + if (proxyAuthenticationMode()) + { + if(!sipMsg->exists(h_ProxyAuthorizations)) + { + return issueChallengeIfRequired(sipMsg); + } + auths = &sipMsg->header(h_ProxyAuthorizations); + } + else + { + if(!sipMsg->exists(h_Authorizations)) + { + return issueChallengeIfRequired(sipMsg); + } + auths = &sipMsg->header(h_Authorizations); + } + + try + { + for(Auths::iterator it = auths->begin(); it != auths->end(); it++) + { + if (isMyRealm(it->param(p_realm))) + { + InfoLog (<< "Requesting credential for " + << it->param(p_username) << " @ " << it->param(p_realm)); + + requestCredential(it->param(p_username), + it->param(p_realm), + *sipMsg, + *it, + sipMsg->getTransactionId()); + mMessages[sipMsg->getTransactionId()] = sipMsg; + return RequestedCredentials; + } + } + + InfoLog (<< "Didn't find matching realm "); + return issueChallengeIfRequired(sipMsg); + } + catch(BaseException& e) + { + InfoLog (<< "Invalid auth header provided " << e); + SharedPtr<SipMessage> response(new SipMessage); + Helper::makeResponse(*response, *sipMsg, 400, "Invalid auth header"); + mDum.send(response); + onAuthFailure(InvalidRequest, *sipMsg); + return Rejected; + } + } + return Skipped; +} + +ServerAuthManager::Result +ServerAuthManager::issueChallengeIfRequired(SipMessage *sipMsg) +{ + // Is challenge required for this message + AsyncBool required = requiresChallenge(*sipMsg); + switch(required) + { + case False: + return Skipped; + case Async: + mMessages[sipMsg->getTransactionId()] = sipMsg; + return RequestedInfo; + case True: + default: + issueChallenge(sipMsg); + return Challenged; + } +} + +void +ServerAuthManager::issueChallenge(SipMessage *sipMsg) +{ + //assume TransactionUser has matched/repaired a realm + SharedPtr<SipMessage> challenge(Helper::makeChallenge(*sipMsg, + getChallengeRealm(*sipMsg), + useAuthInt(), + false /*stale*/, + proxyAuthenticationMode())); + + InfoLog (<< "Sending challenge to " << sipMsg->brief()); + mDum.send(challenge); +} + +void +ServerAuthManager::onAuthSuccess(const SipMessage& msg) +{ + // sub class may want to create a log entry +} + +void +ServerAuthManager::onAuthFailure(AuthFailureReason reason, const SipMessage& msg) +{ + // sub class may want to create a log entry +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerAuthManager.hxx b/src/libs/resiprocate/resip/dum/ServerAuthManager.hxx new file mode 100644 index 00000000..cd30b2b2 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerAuthManager.hxx @@ -0,0 +1,160 @@ +#if !defined(RESIP_SERVERAUTHMANAGER_HXX) +#define RESIP_SERVERAUTHMANAGER_HXX + +#include <map> + +#include "resip/stack/Auth.hxx" +#include "resip/stack/SipMessage.hxx" +#include "DumFeature.hxx" + +namespace resip +{ +class UserAuthInfo; +class DialogUsageManager; + + +class ServerAuthManager : public DumFeature +{ + public: + enum Result + { + //Authorized, + RequestedInfo, + RequestedCredentials, + Challenged, + Skipped, + Rejected + }; + + ServerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, bool challengeThirdParties = true); + virtual ~ServerAuthManager(); + + virtual ProcessingResult process(Message* msg); + + // can return Authorized, Rejected or Skipped + //Result handleUserAuthInfo(Message* msg); + + // returns the SipMessage that was authorized if succeeded or returns 0 if + // rejected. + virtual SipMessage* handleUserAuthInfo(UserAuthInfo* auth); + + // can return Challenged, RequestedCredentials, Rejected, Skipped + virtual Result handle(SipMessage* sipMsg); + + protected: + + enum AsyncBool + { + True, // response is true + False, // response is false + Async // response will be sent asynchronously + }; + + enum AuthFailureReason + { + InvalidRequest, // some aspect of the request (e.g. nonce) + // is not valid/tampered with + BadCredentials, // credentials didn't match + Error // processing/network error + }; + + // this call back should async cause a post of UserAuthInfo + virtual void requestCredential(const Data& user, + const Data& realm, + const SipMessage& msg, + const Auth& auth, // the auth line we have chosen to authenticate against + const Data& transactionToken ) = 0; + + virtual bool useAuthInt() const; + virtual bool proxyAuthenticationMode() const; + virtual bool rejectBadNonces() const; + + typedef std::map<Data, SipMessage*> MessageMap; + MessageMap mMessages; + + /// should return true if the request must be challenged + /// The default is to challenge all requests - override this class to change this beviour + virtual AsyncBool requiresChallenge(const SipMessage& msg); + + /// should return true if the passed in user is authorized for the provided uri + virtual bool authorizedForThisIdentity(const resip::Data &user, + const resip::Data &realm, + resip::Uri &fromUri); + + /// returns the realm to be used for the challenge + virtual const Data& getChallengeRealm(const SipMessage& msg); + + /// should return true if realm passed in is ours and we can challenge + virtual bool isMyRealm(const Data& realm); + + // Either + // a) issues a challenge if necessary and returns `Challenged' + // b) returns `Skipped' if no challenge necessary + // c) waits asynchronously to find out if challenge required, + // and returns `RequestedInfo' + Result issueChallengeIfRequired(SipMessage *sipMsg); + + // sends a 407 challenge to the UAC who sent sipMsg + void issueChallenge(SipMessage *sipMsg); + + virtual void onAuthSuccess(const SipMessage& msg); + virtual void onAuthFailure(AuthFailureReason reason, const SipMessage& msg); + + private: + bool mChallengeThirdParties; +}; + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerInviteSession.cxx b/src/libs/resiprocate/resip/dum/ServerInviteSession.cxx new file mode 100644 index 00000000..6c784d79 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerInviteSession.cxx @@ -0,0 +1,1350 @@ +#include "resip/stack/MultipartMixedContents.hxx" +#include "resip/stack/MultipartAlternativeContents.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/DialogEventStateManager.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/DumTimeout.hxx" +#include "resip/dum/InviteSessionHandler.hxx" +#include "resip/dum/ServerInviteSession.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/UsageUseException.hxx" +#include "resip/dum/DumHelper.hxx" +#include "resip/dum/DumCommand.hxx" +#include "rutil/Logger.hxx" +#include "rutil/compat.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +ServerInviteSession::ServerInviteSession(DialogUsageManager& dum, Dialog& dialog, const SipMessage& request) + : InviteSession(dum, dialog), + mFirstRequest(request), + m1xx(new SipMessage), + mCurrentRetransmit1xx(0) +{ + assert(request.isRequest()); + mState = UAS_Start; +} + +ServerInviteSessionHandle +ServerInviteSession::getHandle() +{ + return ServerInviteSessionHandle(mDum, getBaseHandle().getId()); +} + +void +ServerInviteSession::redirect(const NameAddrs& contacts, int code) +{ + InfoLog (<< toData(mState) << ": redirect(" << code << ")"); // -> " << contacts); + + switch (mState) + { + case UAS_EarlyNoOffer: + case UAS_EarlyOffer: + case UAS_EarlyProvidedAnswer: + case UAS_EarlyProvidedOffer: + case UAS_NegotiatedReliable: + case UAS_FirstSentAnswerReliable: + case UAS_FirstSentOfferReliable: + case UAS_NoOffer: + case UAS_NoOfferReliable: + case UAS_Offer: + case UAS_OfferProvidedAnswer: + case UAS_ReceivedOfferReliable: + case UAS_ProvidedOffer: + case UAS_ReceivedUpdate: + case UAS_ReceivedUpdateWaitingAnswer: + case UAS_SentUpdate: + { + // !jf! the cleanup for 3xx may be a bit strange if we are in the middle of + // an offer/answer exchange with PRACK. + // e.g. we sent 183 reliably and then 302 before PRACK was received. Ideally, + // we should send 200PRACK + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, mFirstRequest, code); + response->header(h_Contacts) = contacts; + send(response); + + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTerminated(mDialog, *response, InviteSessionHandler::Rejected); + } + + transition(Terminated); + + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Referred); + mDum.destroy(this); + break; + } + + case UAS_Accepted: + case UAS_WaitingToOffer: + case UAS_WaitingToRequestOffer: + case UAS_WaitingToHangup: + case UAS_WaitingToTerminate: + case UAS_SentUpdateAccepted: + case UAS_Start: + default: + assert(0); + throw UsageUseException("Can't redirect after accepted", __FILE__, __LINE__); + break; + } +} + +class ServerInviteSessionRedirectCommand : public DumCommandAdapter +{ +public: + ServerInviteSessionRedirectCommand(ServerInviteSession& serverInviteSession, const NameAddrs& contacts, int code) + : mServerInviteSession(serverInviteSession), + mContacts(contacts), + mCode(code) + { + + } + + virtual void executeCommand() + { + mServerInviteSession.redirect(mContacts, mCode); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ServerInviteSessionRedirectCommand"; + } +private: + ServerInviteSession& mServerInviteSession; + NameAddrs mContacts; + int mCode; +}; + +void +ServerInviteSession::redirectCommand(const NameAddrs& contacts, int code) +{ + mDum.post(new ServerInviteSessionRedirectCommand(*this, contacts, code)); +} + +void +ServerInviteSession::provisional(int code, bool earlyFlag) +{ + InfoLog (<< toData(mState) << ": provisional(" << code << ")"); + + switch (mState) + { + case UAS_Offer: + transition(UAS_EarlyOffer); + sendProvisional(code, earlyFlag); + break; + + case UAS_OfferProvidedAnswer: + case UAS_EarlyProvidedAnswer: + transition(UAS_EarlyProvidedAnswer); + sendProvisional(code, earlyFlag); + break; + + case UAS_ProvidedOffer: + case UAS_EarlyProvidedOffer: + transition(UAS_EarlyProvidedOffer); + sendProvisional(code, earlyFlag); + break; + + case UAS_EarlyOffer: + transition(UAS_EarlyOffer); + sendProvisional(code, earlyFlag); + break; + + case UAS_NoOffer: + case UAS_EarlyNoOffer: + transition(UAS_EarlyNoOffer); + sendProvisional(code, earlyFlag); + break; + + + case UAS_NoOfferReliable: + case UAS_NegotiatedReliable: + // TBD + assert(0); + break; + + case UAS_Accepted: + case UAS_WaitingToOffer: + case UAS_WaitingToRequestOffer: + case UAS_FirstSentAnswerReliable: + case UAS_FirstSentOfferReliable: + case UAS_ReceivedOfferReliable: + case UAS_ReceivedUpdate: + case UAS_ReceivedUpdateWaitingAnswer: + case UAS_SentUpdate: + case UAS_SentUpdateAccepted: + case UAS_Start: + case UAS_WaitingToHangup: + case UAS_WaitingToTerminate: + default: + assert(0); + break; + } +} + +class ServerInviteSessionProvisionalCommand : public DumCommandAdapter +{ +public: + ServerInviteSessionProvisionalCommand(ServerInviteSession& serverInviteSession, int statusCode) + : mServerInviteSession(serverInviteSession), + mStatusCode(statusCode) + { + } + + virtual void executeCommand() + { + mServerInviteSession.provisional(mStatusCode); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ServerInviteSessionProvisionalCommand"; + } +private: + ServerInviteSession& mServerInviteSession; + int mStatusCode; +}; + +void +ServerInviteSession::provisionalCommand(int statusCode) +{ + mDum.post(new ServerInviteSessionProvisionalCommand(*this, statusCode)); +} + +void +ServerInviteSession::provideOffer(const Contents& offer, + DialogUsageManager::EncryptionLevel level, + const Contents* alternative) +{ + InfoLog (<< toData(mState) << ": provideOffer"); + switch (mState) + { + case UAS_NoOffer: + transition(UAS_ProvidedOffer); + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); + mProposedEncryptionLevel = level; + break; + + case UAS_EarlyNoOffer: + transition(UAS_EarlyProvidedOffer); + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); + mProposedEncryptionLevel = level; + break; + + case UAS_NoOfferReliable: + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); + mProposedEncryptionLevel = level; + // !jf! transition ? + break; + + case UAS_NegotiatedReliable: + // queue offer + transition(UAS_SentUpdate); + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); + mProposedEncryptionLevel = level; + sendUpdate(offer); + break; + + case UAS_Accepted: + // queue the offer to be sent after the ACK is received + transition(UAS_WaitingToOffer); + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer); + mProposedEncryptionLevel = level; + break; + + case UAS_WaitingToOffer: + InviteSession::provideOffer(offer, level, alternative); + break; + + case UAS_EarlyProvidedAnswer: + case UAS_EarlyProvidedOffer: + case UAS_FirstSentAnswerReliable: + case UAS_FirstSentOfferReliable: + case UAS_Offer: + case UAS_EarlyOffer: + case UAS_ReceivedOfferReliable: + case UAS_OfferProvidedAnswer: + case UAS_ProvidedOffer: + case UAS_ReceivedUpdate: + case UAS_ReceivedUpdateWaitingAnswer: + case UAS_SentUpdate: + case UAS_SentUpdateAccepted: + case UAS_Start: + case UAS_WaitingToHangup: + case UAS_WaitingToTerminate: + case UAS_WaitingToRequestOffer: + case UAS_AcceptedWaitingAnswer: + assert(0); + break; + default: + InviteSession::provideOffer(offer, level, alternative); + break; + } +} + +void +ServerInviteSession::provideOffer(const Contents& offer) +{ + this->provideOffer(offer, mCurrentEncryptionLevel, 0); +} + + +void +ServerInviteSession::requestOffer() +{ + InfoLog (<< toData(mState) << ": requestOffer"); + switch (mState) + { + case UAS_Accepted: + // queue the request to be sent after the ACK is received + transition(UAS_WaitingToRequestOffer); + break; + + case UAS_WaitingToRequestOffer: + InviteSession::requestOffer(); + break; + + default: + InviteSession::requestOffer(); + break; + } +} + +void +ServerInviteSession::provideAnswer(const Contents& answer) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + InfoLog (<< toData(mState) << ": provideAnswer"); + switch (mState) + { + case UAS_Offer: + transition(UAS_OfferProvidedAnswer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + break; + + case UAS_EarlyOffer: + transition(UAS_EarlyProvidedAnswer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + break; + + case UAS_ReceivedOfferReliable: + // send1XX-answer, timer::1xx + transition(UAS_FirstSentAnswerReliable); + break; + + case UAS_ReceivedUpdate: + // send::200U-answer + transition(UAS_NegotiatedReliable); + break; + + case UAS_ReceivedUpdateWaitingAnswer: + // send::2XXU-answer + // send::2XXI + transition(Connected); + handler->onConnected(getSessionHandle(), *mInvite200); + break; + + case UAS_Accepted: + case UAS_WaitingToOffer: + case UAS_WaitingToRequestOffer: + case UAS_EarlyNoOffer: + case UAS_EarlyProvidedAnswer: + case UAS_EarlyProvidedOffer: + case UAS_NegotiatedReliable: + case UAS_FirstSentAnswerReliable: + case UAS_FirstSentOfferReliable: + case UAS_NoOffer: + case UAS_NoOfferReliable: + case UAS_OfferProvidedAnswer: + case UAS_ProvidedOffer: + case UAS_SentUpdate: + case UAS_SentUpdateAccepted: + case UAS_Start: + case UAS_WaitingToHangup: + case UAS_WaitingToTerminate: + case UAS_AcceptedWaitingAnswer: + assert(0); + break; + default: + InviteSession::provideAnswer(answer); + break; + } +} + +void +ServerInviteSession::end() +{ + end(NotSpecified); +} + +void +ServerInviteSession::end(const Data& userReason) +{ + mUserEndReason = userReason; + end(InviteSession::UserSpecified); +} + +void +ServerInviteSession::end(EndReason reason) +{ + InfoLog (<< toData(mState) << ": end"); + if (mEndReason == NotSpecified) + { + mEndReason = reason; + } + + switch (mState) + { + case UAS_EarlyNoOffer: + case UAS_EarlyOffer: + case UAS_EarlyProvidedAnswer: + case UAS_EarlyProvidedOffer: + case UAS_NoOffer: + case UAS_Offer: + case UAS_OfferProvidedAnswer: + case UAS_ProvidedOffer: + reject(480); + break; + + case UAS_ReceivedOfferReliable: + case UAS_NegotiatedReliable: + case UAS_FirstSentOfferReliable: + case UAS_FirstSentAnswerReliable: + case UAS_NoOfferReliable: + case UAS_ReceivedUpdate: // !slg! todo: send 488U + case UAS_ReceivedUpdateWaitingAnswer: // !slg! todo: send 488U + case UAS_SentUpdate: + case UAS_WaitingToTerminate: + reject(480); + break; + + case UAS_Start: + assert(0); + break; + + case UAS_Accepted: + case UAS_WaitingToOffer: + case UAS_WaitingToRequestOffer: + case UAS_SentUpdateAccepted: + case UAS_AcceptedWaitingAnswer: + if(mCurrentRetransmit200) // If retransmit200 timer is active then ACK is not received yet - wait for it + { + transition(UAS_WaitingToHangup); + } + else + { + // ACK has likely timedout - hangup immediately + SharedPtr<SipMessage> msg = sendBye(); + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); + } + break; + + case UAS_WaitingToHangup: // This can happen if we are waiting for an ACK to hangup and the ACK timesout + break; + + default: + InviteSession::end(reason); + break; + } +} + +void +ServerInviteSession::reject(int code, WarningCategory *warning) +{ + InfoLog (<< toData(mState) << ": reject(" << code << ")"); + + switch (mState) + { + case UAS_EarlyNoOffer: + case UAS_EarlyOffer: + case UAS_EarlyProvidedAnswer: + case UAS_EarlyProvidedOffer: + case UAS_NoOffer: + case UAS_Offer: + case UAS_OfferProvidedAnswer: + case UAS_ProvidedOffer: + + case UAS_NegotiatedReliable: + case UAS_FirstSentAnswerReliable: + case UAS_FirstSentOfferReliable: + case UAS_NoOfferReliable: + case UAS_ReceivedOfferReliable: + case UAS_ReceivedUpdate: + case UAS_SentUpdate: + { + // !jf! the cleanup for 3xx may be a bit strange if we are in the middle of + // an offer/answer exchange with PRACK. + // e.g. we sent 183 reliably and then 302 before PRACK was received. Ideally, + // we should send 200PRACK + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, mFirstRequest, code); + if(warning) + { + response->header(h_Warnings).push_back(*warning); + } + send(response); + + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Rejected); + mDum.destroy(this); + break; + } + + case UAS_Accepted: + case UAS_WaitingToOffer: + case UAS_WaitingToRequestOffer: + case UAS_ReceivedUpdateWaitingAnswer: + case UAS_SentUpdateAccepted: + case UAS_Start: + case UAS_WaitingToHangup: + case UAS_WaitingToTerminate: + assert(0); + break; + + default: + InviteSession::reject(code); + break; + } +} + +void +ServerInviteSession::accept(int code) +{ + InfoLog (<< toData(mState) << ": accept(" << code << ")"); + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + switch (mState) + { + case UAS_Offer: + case UAS_EarlyOffer: + assert(0); + break; + + case UAS_OfferProvidedAnswer: + case UAS_EarlyProvidedAnswer: + transition(UAS_Accepted); + sendAccept(code, mCurrentLocalOfferAnswer.get()); + handler->onConnected(getSessionHandle(), *mInvite200); + break; + + case UAS_NoOffer: + case UAS_EarlyNoOffer: + assert(0); + break; + + case UAS_ProvidedOffer: + case UAS_EarlyProvidedOffer: + transition(UAS_AcceptedWaitingAnswer); + sendAccept(code, mProposedLocalOfferAnswer.get()); + break; + + case UAS_Accepted: + case UAS_WaitingToOffer: + case UAS_WaitingToRequestOffer: + assert(0); // Already Accepted + break; + + case UAS_FirstSentAnswerReliable: + // queue 2xx + // waiting for PRACK + transition(UAS_Accepted); + mDialog.makeResponse(*mInvite200, mFirstRequest, code); + handleSessionTimerRequest(*mInvite200, mFirstRequest); + break; + + case UAS_NegotiatedReliable: + transition(Connected); + sendAccept(code, 0); + handler->onConnected(getSessionHandle(), *mInvite200); + break; + + case UAS_SentUpdate: + transition(UAS_SentUpdateAccepted); + sendAccept(code, 0); + break; + + case UAS_ReceivedUpdate: + transition(UAS_ReceivedUpdateWaitingAnswer); + mDialog.makeResponse(*mInvite200, mFirstRequest, code);// queue 2xx + handleSessionTimerRequest(*mInvite200, mFirstRequest); + break; + + case UAS_FirstSentOfferReliable: + case UAS_NoOfferReliable: + case UAS_ReceivedOfferReliable: + case UAS_ReceivedUpdateWaitingAnswer: + case UAS_SentUpdateAccepted: + case UAS_Start: + case UAS_WaitingToHangup: + case UAS_WaitingToTerminate: + default: + assert(0); + break; + } +} + +class ServerInviteSessionAcceptCommand : public DumCommandAdapter +{ +public: + ServerInviteSessionAcceptCommand(ServerInviteSession& serverInviteSession, int statusCode) + : mServerInviteSession(serverInviteSession), + mStatusCode(statusCode) + { + } + + virtual void executeCommand() + { + mServerInviteSession.accept(mStatusCode); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ServerInviteSessionAcceptCommand"; + } +private: + ServerInviteSession& mServerInviteSession; + int mStatusCode; +}; + +void +ServerInviteSession::acceptCommand(int statusCode) +{ + mDum.post(new ServerInviteSessionAcceptCommand(*this, statusCode)); +} + +void +ServerInviteSession::dispatch(const SipMessage& msg) +{ + if (msg.isRequest()) + { + if (msg.header(h_RequestLine).method() == INFO) + { + InviteSession::dispatchInfo(msg); + return; + } + if (msg.header(h_RequestLine).method() == MESSAGE) + { + InviteSession::dispatchMessage(msg); + return; + } + } + + switch (mState) + { + case UAS_Start: + dispatchStart(msg); + break; + + case UAS_Offer: + case UAS_EarlyOffer: + case UAS_EarlyProvidedAnswer: + case UAS_NoOffer: + case UAS_ProvidedOffer: + case UAS_EarlyNoOffer: + case UAS_EarlyProvidedOffer: + case UAS_OfferProvidedAnswer: + dispatchOfferOrEarly(msg); + break; + case UAS_Accepted: + dispatchAccepted(msg); + break; + case UAS_WaitingToOffer: + dispatchWaitingToOffer(msg); + break; + case UAS_WaitingToRequestOffer: + dispatchWaitingToRequestOffer(msg); + break; + case UAS_AcceptedWaitingAnswer: + dispatchAcceptedWaitingAnswer(msg); + break; + case UAS_NegotiatedReliable: + dispatchEarlyReliable(msg); + break; + case UAS_FirstSentAnswerReliable: + dispatchFirstEarlyReliable(msg); + break; + case UAS_FirstSentOfferReliable: + dispatchFirstSentOfferReliable(msg); + break; + case UAS_NoOfferReliable: + dispatchNoOfferReliable(msg); + break; + case UAS_ReceivedOfferReliable: + dispatchOfferReliable(msg); + break; + case UAS_ReceivedUpdate: + dispatchReceivedUpdate(msg); + break; + case UAS_ReceivedUpdateWaitingAnswer: + dispatchReceivedUpdateWaitingAnswer(msg); + break; + case UAS_SentUpdate: + dispatchSentUpdate(msg); + break; + case UAS_WaitingToHangup: + dispatchWaitingToHangup(msg); + break; + case UAS_WaitingToTerminate: + dispatchWaitingToTerminate(msg); + break; + case UAS_SentUpdateAccepted: + dispatchSentUpdateAccepted(msg); + break; + default: + InviteSession::dispatch(msg); + break; + } +} + +void +ServerInviteSession::dispatch(const DumTimeout& timeout) +{ + if (timeout.type() == DumTimeout::Retransmit1xx) + { + if (mCurrentRetransmit1xx && m1xx->header(h_CSeq).sequence() == timeout.seq()) // If timer isn't stopped and this timer is for last 1xx sent, then resend + { + send(m1xx); + startRetransmit1xxTimer(); + } + } + else + { + InviteSession::dispatch(timeout); + } +} + +void +ServerInviteSession::dispatchStart(const SipMessage& msg) +{ + assert(msg.isRequest()); + assert(msg.header(h_CSeq).method() == INVITE); + + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + storePeerCapabilities(msg); + + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTryingUas(mDialog, msg); + } + + switch (toEvent(msg, offerAnswer.get())) + { + case OnInviteOffer: + *mLastRemoteSessionModification = msg; + transition(UAS_Offer); + mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + handler->onNewSession(getHandle(), InviteSession::Offer, msg); + if(!isTerminated()) + { + handler->onOffer(getSessionHandle(), msg, *offerAnswer); + } + break; + case OnInvite: + *mLastRemoteSessionModification = msg; + transition(UAS_NoOffer); + handler->onNewSession(getHandle(), InviteSession::None, msg); + if(!isTerminated()) + { + handler->onOfferRequired(getSessionHandle(), msg); + } + break; + case OnInviteReliableOffer: + *mLastRemoteSessionModification = msg; + transition(UAS_ReceivedOfferReliable); + mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + handler->onNewSession(getHandle(), InviteSession::Offer, msg); + if(!isTerminated()) + { + handler->onOffer(getSessionHandle(), msg, *offerAnswer); + } + break; + case OnInviteReliable: + *mLastRemoteSessionModification = msg; + transition(UAS_NoOfferReliable); + handler->onNewSession(getHandle(), InviteSession::None, msg); + if(!isTerminated()) + { + handler->onOfferRequired(getSessionHandle(), msg); + } + break; + default: + assert(0); + break; + } +} + +// Offer, Early, EarlyNoOffer, NoOffer +void +ServerInviteSession::dispatchOfferOrEarly(const SipMessage& msg) +{ + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + switch (toEvent(msg, offerAnswer.get())) + { + case OnCancel: + dispatchCancel(msg); + break; + case OnBye: + dispatchBye(msg); + break; + default: + assert(msg.isRequest()); + dispatchUnknown(msg); + break; + } +} + +void +ServerInviteSession::dispatchAccepted(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + InfoLog (<< "dispatchAccepted: " << msg.brief()); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnInvite: + case OnInviteReliable: + case OnInviteOffer: + case OnInviteReliableOffer: + case OnUpdate: + case OnUpdateOffer: + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 491); + send(response); + break; + } + + case OnAck: + case OnAckAnswer: // .bwc. unsolicited body in ACK; it would probably make sense to just ignore. + { + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + transition(Connected); + handler->onConnectedConfirmed(getSessionHandle(), msg); + break; + } + + case OnCancel: + { + // Cancel and 200 crossed + SharedPtr<SipMessage> c200(new SipMessage); + mDialog.makeResponse(*c200, msg, 200); + send(c200); + break; + } + + case OnBye: + { + SharedPtr<SipMessage> b200(new SipMessage); + mDialog.makeResponse(*b200, msg, 200); + send(b200); + + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::RemoteBye, &msg); + mDum.destroy(this); + break; + } + + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } +} + +void +ServerInviteSession::dispatchWaitingToOffer(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + InfoLog (<< "dispatchWaitingToOffer: " << msg.brief()); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnInvite: + case OnInviteReliable: + case OnInviteOffer: + case OnInviteReliableOffer: + case OnUpdate: + case OnUpdateOffer: + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 491); + send(response); + break; + } + + case OnAck: + { + assert(mProposedLocalOfferAnswer.get()); + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + provideProposedOffer(); + break; + } + + case OnAckAnswer: + { + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + sendBye(); + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + break; + } + + case OnCancel: + { + // Cancel and 200 crossed + SharedPtr<SipMessage> c200(new SipMessage); + mDialog.makeResponse(*c200, msg, 200); + send(c200); + break; + } + + case OnBye: + { + SharedPtr<SipMessage> b200(new SipMessage); + mDialog.makeResponse(*b200, msg, 200); + send(b200); + + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::RemoteBye, &msg); + mDum.destroy(this); + break; + } + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } +} + +void +ServerInviteSession::dispatchWaitingToRequestOffer(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + InfoLog (<< "dispatchWaitingToRequestOffer: " << msg.brief()); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnInvite: + case OnInviteReliable: + case OnInviteOffer: + case OnInviteReliableOffer: + case OnUpdate: + case OnUpdateOffer: + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 491); + send(response); + break; + } + + case OnAck: + { + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + requestOffer(); + break; + } + + case OnAckAnswer: + { + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + sendBye(); + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + break; + } + + case OnCancel: + { + // Cancel and 200 crossed + SharedPtr<SipMessage> c200(new SipMessage); + mDialog.makeResponse(*c200, msg, 200); + send(c200); + break; + } + + case OnBye: + { + SharedPtr<SipMessage> b200(new SipMessage); + mDialog.makeResponse(*b200, msg, 200); + send(b200); + + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::RemoteBye, &msg); + mDum.destroy(this); + break; + } + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } +} + +void +ServerInviteSession::dispatchAcceptedWaitingAnswer(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnInvite: + case OnInviteReliable: + case OnInviteOffer: + case OnInviteReliableOffer: + case OnUpdate: + case OnUpdateOffer: + { + SharedPtr<SipMessage> response(new SipMessage); + mDialog.makeResponse(*response, msg, 491); + send(response); + break; + } + + case OnAckAnswer: + { + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + transition(Connected); + setCurrentLocalOfferAnswer(msg); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + handler->onAnswer(getSessionHandle(), msg, *offerAnswer); + if(!isTerminated()) // onAnswer callback may call end() or reject() + { + handler->onConnected(getSessionHandle(), msg); + } + break; + } + + case OnAck: + { + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + mEndReason = IllegalNegotiation; + sendBye(); + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + break; + } + + case OnCancel: + { + // no transition + + SharedPtr<SipMessage> c200(new SipMessage); + mDialog.makeResponse(*c200, msg, 200); + send(c200); + break; + } + + case OnPrack: // broken + { + // no transition + + SharedPtr<SipMessage> p200(new SipMessage); + mDialog.makeResponse(*p200, msg, 200); + send(p200); + + sendAccept(200, 0); + break; + } + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } +} + +void +ServerInviteSession::dispatchOfferReliable(const SipMessage& msg) +{ +} + +void +ServerInviteSession::dispatchNoOfferReliable(const SipMessage& msg) +{ +} + +void +ServerInviteSession::dispatchFirstSentOfferReliable(const SipMessage& msg) +{ +} + +void +ServerInviteSession::dispatchFirstEarlyReliable(const SipMessage& msg) +{ +} + +void +ServerInviteSession::dispatchEarlyReliable(const SipMessage& msg) +{ +} + +void +ServerInviteSession::dispatchSentUpdate(const SipMessage& msg) +{ +} + +void +ServerInviteSession::dispatchSentUpdateAccepted(const SipMessage& msg) +{ +} + +void +ServerInviteSession::dispatchReceivedUpdate(const SipMessage& msg) +{ +} + +void +ServerInviteSession::dispatchReceivedUpdateWaitingAnswer(const SipMessage& msg) +{ +} + +void +ServerInviteSession::dispatchWaitingToTerminate(const SipMessage& msg) +{ +} + +void +ServerInviteSession::dispatchWaitingToHangup(const SipMessage& msg) +{ + std::auto_ptr<Contents> offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnPrack: + case OnAck: + case OnAckAnswer: + { + mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + + SharedPtr<SipMessage> msg = sendBye(); + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); + break; + } + + default: + break; + } +} + +void +ServerInviteSession::dispatchCancel(const SipMessage& msg) +{ + SharedPtr<SipMessage> c200(new SipMessage); + mDialog.makeResponse(*c200, msg, 200); + send(c200); + + SharedPtr<SipMessage> i487(new SipMessage); + mDialog.makeResponse(*i487, mFirstRequest, 487); + send(i487); + + transition(Terminated); + + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTerminated(mDialog, msg, InviteSessionHandler::RemoteCancel); + } + + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::RemoteCancel, &msg); + mDum.destroy(this); +} + +void +ServerInviteSession::dispatchBye(const SipMessage& msg) +{ + SharedPtr<SipMessage> b200(new SipMessage); + mDialog.makeResponse(*b200, msg, 200); + send(b200); +// !dcm! -- pretty sure we shouldn't 487 after the BYE/200 + SharedPtr<SipMessage> i487(new SipMessage); + mDialog.makeResponse(*i487, mFirstRequest, 487); + send(i487); + + transition(Terminated); + + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::RemoteBye, &msg); + mDum.destroy(this); +} + +void +ServerInviteSession::dispatchUnknown(const SipMessage& msg) +{ + SharedPtr<SipMessage> r481(new SipMessage); // !jf! what should we send here? + mDialog.makeResponse(*r481, msg, 481); + send(r481); + + SharedPtr<SipMessage> i400(new SipMessage); + mDialog.makeResponse(*i400, mFirstRequest, 400); + send(i400); + + transition(Terminated); + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + mDum.destroy(this); +} + +void +ServerInviteSession::startRetransmit1xxTimer() +{ + // RFC3261 13.3.1 says the UAS must send a non-100 provisional response every minute, to handle the possiblity of lost provisional responses + mCurrentRetransmit1xx = mDialog.mDialogSet.getUserProfile()->get1xxRetransmissionTime(); + if(mCurrentRetransmit1xx > 0) + { + unsigned int seq = m1xx->header(h_CSeq).sequence(); + mDum.addTimer(DumTimeout::Retransmit1xx, mCurrentRetransmit1xx, getBaseHandle(), seq); + } +} + +void +ServerInviteSession::sendProvisional(int code, bool earlyFlag) +{ + mDialog.makeResponse(*m1xx, mFirstRequest, code); + if(!earlyFlag) + { + m1xx->setContents(0); // clear contents if present + } + else + { + switch (mState) + { + case UAS_OfferProvidedAnswer: + case UAS_EarlyProvidedAnswer: + if (mCurrentLocalOfferAnswer.get()) // early media + { + setOfferAnswer(*m1xx, mCurrentLocalOfferAnswer.get()); + } + break; + case UAS_ProvidedOffer: + case UAS_EarlyProvidedOffer: + if (mProposedLocalOfferAnswer.get()) + { + setOfferAnswer(*m1xx, mProposedLocalOfferAnswer.get()); + } + break; + + default: + break; + } + } + startRetransmit1xxTimer(); + DumHelper::setOutgoingEncryptionLevel(*m1xx, mProposedEncryptionLevel); + + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onEarly(mDialog, getSessionHandle()); + } + + send(m1xx); +} + +void +ServerInviteSession::sendAccept(int code, Contents* offerAnswer) +{ + mDialog.makeResponse(*mInvite200, mFirstRequest, code); + handleSessionTimerRequest(*mInvite200, mFirstRequest); + if (offerAnswer) + { + setOfferAnswer(*mInvite200, offerAnswer); + } + mCurrentRetransmit1xx = 0; // Stop the 1xx timer + startRetransmit200Timer(); // 2xx timer + DumHelper::setOutgoingEncryptionLevel(*mInvite200, mCurrentEncryptionLevel); + + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onConfirmed(mDialog, getSessionHandle()); + } + + send(mInvite200); +} + +void +ServerInviteSession::sendUpdate(const Contents& offerAnswer) +{ + if (updateMethodSupported()) + { + mDialog.makeRequest(*mLastLocalSessionModification, UPDATE); + InviteSession::setOfferAnswer(*mLastLocalSessionModification, offerAnswer); + DumHelper::setOutgoingEncryptionLevel(*mLastLocalSessionModification, mProposedEncryptionLevel); + send(mLastLocalSessionModification); + } + else + { + throw UsageUseException("Can't send UPDATE to peer", __FILE__, __LINE__); + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerInviteSession.hxx b/src/libs/resiprocate/resip/dum/ServerInviteSession.hxx new file mode 100644 index 00000000..7cb05c61 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerInviteSession.hxx @@ -0,0 +1,163 @@ +#if !defined(RESIP_SERVERINVITESESSION_HXX) +#define RESIP_SERVERINVITESESSION_HXX + +#include "resip/dum/InviteSession.hxx" +#include "resip/stack/SipMessage.hxx" + +#include <deque> + +namespace resip +{ + +class ServerInviteSession: public InviteSession +{ + public: + typedef Handle<ServerInviteSession> ServerInviteSessionHandle; + ServerInviteSessionHandle getHandle(); + + /** send a 3xx */ + void redirect(const NameAddrs& contacts, int code=302); + + /** send a 1xx - provisional response. If you set earlyFlag to true, and have provided + an answer, then DUM will attach the answer to the provisional response, as an + early media indication */ + void provisional(int code=180, bool earlyFlag=true); + + /** Called to set the offer that will be used in the next message that + sends an offer. If possible, this will synchronously send the + appropriate request or response. In some cases, the UAS might have to + call accept in order to cause the message to be sent. */ + virtual void provideOffer(const Contents& offer); + virtual void provideOffer(const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative); + + /** Called to request that the far end provide an offer. This will cause a + reinvite with no body to be sent. */ + virtual void requestOffer(); + + /** Similar to provideOffer - called to set the answer to be signalled to + the peer. May result in message being sent synchronously depending on + the state. */ + virtual void provideAnswer(const Contents& answer); + + /** Makes the specific dialog end. Will send a 480. */ + virtual void end(const Data& userReason); + virtual void end(EndReason reason); + virtual void end(); + + /** Rejects an offer at the SIP level. So this can send a 488 to a + reINVITE or UPDATE */ + virtual void reject(int statusCode, WarningCategory *warning = 0); + + /** accept an initial invite (2xx) - this is only applicable to the UAS */ + void accept(int statusCode=200); + + /** + * Provide asynchronous method access by using command + */ + void redirectCommand(const NameAddrs& contacts, int code=302); + void provisionalCommand(int code=180); + void acceptCommand(int statusCode=200); + + private: + friend class Dialog; + + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + void dispatchStart(const SipMessage& msg); + void dispatchOfferOrEarly(const SipMessage& msg); + void dispatchAccepted(const SipMessage& msg); + void dispatchWaitingToOffer(const SipMessage& msg); + void dispatchWaitingToRequestOffer(const SipMessage& msg); + void dispatchAcceptedWaitingAnswer(const SipMessage& msg); + void dispatchOfferReliable(const SipMessage& msg); + void dispatchNoOfferReliable(const SipMessage& msg); + void dispatchFirstSentOfferReliable(const SipMessage& msg); + void dispatchFirstEarlyReliable(const SipMessage& msg); + void dispatchEarlyReliable(const SipMessage& msg); + void dispatchSentUpdate(const SipMessage& msg); + void dispatchSentUpdateAccepted(const SipMessage& msg); + void dispatchReceivedUpdate(const SipMessage& msg); + void dispatchReceivedUpdateWaitingAnswer(const SipMessage& msg); + void dispatchWaitingToTerminate(const SipMessage& msg); + void dispatchWaitingToHangup(const SipMessage& msg); + + void dispatchCancel(const SipMessage& msg); + void dispatchBye(const SipMessage& msg); + void dispatchUnknown(const SipMessage& msg); + + // utilities + void startRetransmit1xxTimer(); + void sendAccept(int code, Contents* offerAnswer); // sends 2xxI + void sendProvisional(int code, bool earlyFlag); + void sendUpdate(const Contents& offerAnswer); + + ServerInviteSession(DialogUsageManager& dum, Dialog& dialog, const SipMessage& msg); + + // disabled + ServerInviteSession(const ServerInviteSession&); + ServerInviteSession& operator=(const ServerInviteSession&); + + // stores the original request + const SipMessage mFirstRequest; + SharedPtr<SipMessage> m1xx; // for 1xx retransmissions + unsigned long mCurrentRetransmit1xx; + + //std::deque<SipMessage> mUnacknowledgedProvisionals; // all of them + //SipMessage m200; // for retransmission +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerOutOfDialogReq.cxx b/src/libs/resiprocate/resip/dum/ServerOutOfDialogReq.cxx new file mode 100644 index 00000000..be95b130 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerOutOfDialogReq.cxx @@ -0,0 +1,186 @@ +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "resip/dum/ServerOutOfDialogReq.hxx" +#include "resip/dum/OutOfDialogHandler.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +ServerOutOfDialogReqHandle +ServerOutOfDialogReq::getHandle() +{ + return ServerOutOfDialogReqHandle(mDum, getBaseHandle().getId()); +} + + +ServerOutOfDialogReq::ServerOutOfDialogReq(DialogUsageManager& dum, + DialogSet& dialogSet, + const SipMessage& req) + : NonDialogUsage(dum, dialogSet), + mResponse(new SipMessage) +{ + +} + +ServerOutOfDialogReq::~ServerOutOfDialogReq() +{ + mDialogSet.mServerOutOfDialogRequest = 0; +} + +void +ServerOutOfDialogReq::end() +{ + delete this; +} + +void +ServerOutOfDialogReq::dispatch(const SipMessage& msg) +{ + assert(msg.isRequest()); + + OutOfDialogHandler *pHandler = mDum.getOutOfDialogHandler(msg.header(h_CSeq).method()); + if(pHandler != NULL) + { + // Let handler deal with message + mRequest = msg; + DebugLog ( << "ServerOutOfDialogReq::dispatch - handler found for " << getMethodName(msg.header(h_CSeq).method()) << " method."); + pHandler->onReceivedRequest(getHandle(), msg); // Wait for application to send response + } + else + { + if(msg.header(h_CSeq).method() == OPTIONS) + { + DebugLog ( << "ServerOutOfDialogReq::dispatch - handler not found for OPTIONS - sending autoresponse."); + // If no handler exists for OPTIONS then handle internally + mRequest = msg; + mDum.send(answerOptions()); + delete this; + } + else + { + DebugLog ( << "ServerOutOfDialogReq::dispatch - handler not found for " << getMethodName(msg.header(h_CSeq).method()) << " method - sending 405."); + // No handler found for out of dialog request - return a 405 + mDum.makeResponse(*mResponse, msg, 405); + mDum.send(mResponse); + delete this; + } + } +} + +void +ServerOutOfDialogReq::dispatch(const DumTimeout& msg) +{ +} + +SharedPtr<SipMessage> +ServerOutOfDialogReq::answerOptions() +{ + mDum.makeResponse(*mResponse, mRequest, 200); + + // Add in Allow, Accept, Accept-Encoding, Accept-Language, and Supported Headers from Profile + mResponse->header(h_Allows) = mDum.getMasterProfile()->getAllowedMethods(); + mResponse->header(h_Accepts) = mDum.getMasterProfile()->getSupportedMimeTypes(INVITE); + mResponse->header(h_AcceptEncodings) = mDum.getMasterProfile()->getSupportedEncodings(); + mResponse->header(h_AcceptLanguages) = mDum.getMasterProfile()->getSupportedLanguages(); + mResponse->header(h_AllowEvents) = mDum.getMasterProfile()->getAllowedEvents(); + mResponse->header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags(); + + return mResponse; +} + +void +ServerOutOfDialogReq::send(SharedPtr<SipMessage> response) +{ + assert(response->isResponse()); + mDum.send(response); + delete this; +} + +SharedPtr<SipMessage> +ServerOutOfDialogReq::accept(int statusCode) +{ + //!dcm! -- should any responses should include a contact? + mDum.makeResponse(*mResponse, mRequest, statusCode); + return mResponse; +} + +SharedPtr<SipMessage> +ServerOutOfDialogReq::reject(int statusCode) +{ + //!dcm! -- should any responses should include a contact? + mDum.makeResponse(*mResponse, mRequest, statusCode); + return mResponse; +} + +EncodeStream& +ServerOutOfDialogReq::dump(EncodeStream& strm) const +{ + if(mRequest.exists(h_CSeq)) + { + strm << "ServerOutOfDialogReq " << getMethodName(mRequest.header(h_RequestLine).method()) + << " cseq=" << mRequest.header(h_CSeq).sequence(); + } + else + { + strm << "ServerOutOfDialogReq, dispatch has not occured yet."; + } + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/dum/ServerOutOfDialogReq.hxx b/src/libs/resiprocate/resip/dum/ServerOutOfDialogReq.hxx new file mode 100644 index 00000000..5e266ab5 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerOutOfDialogReq.hxx @@ -0,0 +1,98 @@ +#if !defined(RESIP_SERVEROUTOFDIALOGREQ_HXX) +#define RESIP_SERVEROUTOFDIALOGREQ_HXX + +#include "rutil/SharedPtr.hxx" +#include "resip/dum/NonDialogUsage.hxx" + +namespace resip +{ + +class ServerOutOfDialogReq : public NonDialogUsage +{ + public: + typedef Handle<ServerOutOfDialogReq> ServerOutOfDialogReqHandle; + ServerOutOfDialogReqHandle getHandle(); + + SharedPtr<SipMessage> accept(int statusCode = 200); + SharedPtr<SipMessage> reject(int statusCode); + + virtual void end(); + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + // Return Options response based on current MasterProfile settings - application may need to add SDP Contents before + // sending + virtual SharedPtr<SipMessage> answerOptions(); + virtual void send(SharedPtr<SipMessage> msg); + + virtual EncodeStream& dump(EncodeStream& strm) const; + + protected: + virtual ~ServerOutOfDialogReq(); + + private: + friend class DialogSet; + ServerOutOfDialogReq(DialogUsageManager& dum, DialogSet& dialogSet, const SipMessage& req); + + SipMessage mRequest; + SharedPtr<SipMessage> mResponse; + + // disabled + ServerOutOfDialogReq(const ServerOutOfDialogReq&); + ServerOutOfDialogReq& operator=(const ServerOutOfDialogReq&); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerPagerMessage.cxx b/src/libs/resiprocate/resip/dum/ServerPagerMessage.cxx new file mode 100644 index 00000000..8245905a --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerPagerMessage.cxx @@ -0,0 +1,233 @@ +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "resip/dum/ServerPagerMessage.hxx" +#include "resip/dum/OutOfDialogHandler.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/PagerMessageHandler.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +ServerPagerMessageHandle +ServerPagerMessage::getHandle() +{ + return ServerPagerMessageHandle(mDum, getBaseHandle().getId()); +} + +ServerPagerMessage::ServerPagerMessage(DialogUsageManager& dum, + DialogSet& dialogSet, + const SipMessage& req) : + NonDialogUsage(dum, dialogSet), + mRequest(req), + mResponse(new SipMessage) +{ +} + +ServerPagerMessage::~ServerPagerMessage() +{ + mDialogSet.mServerPagerMessage = 0; +} + + +void +ServerPagerMessage::end() +{ + delete this; +} + +class ServerPagerMessageEndCommand : public DumCommandAdapter +{ +public: + ServerPagerMessageEndCommand(ServerPagerMessage& serverPagerMessage) + : mServerPagerMessage(serverPagerMessage) + { + + } + + virtual void executeCommand() + { + mServerPagerMessage.end(); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ServerPagerMessageEndCommand"; + } +private: + ServerPagerMessage& mServerPagerMessage; +}; + +void ServerPagerMessage::endCommand() +{ + mDum.post(new ServerPagerMessageEndCommand(*this)); +} + +void +ServerPagerMessage::dispatch(const SipMessage& msg) +{ + assert(msg.isRequest()); + ServerPagerMessageHandler* handler = mDum.mServerPagerMessageHandler; + + //?dcm? check in DialogUsageManager + if (!handler) + { + mDum.makeResponse(*mResponse, msg, 405); + mDum.send(mResponse); + delete this; + return; + } + handler->onMessageArrived(getHandle(), msg); +} + +void +ServerPagerMessage::dispatch(const DumTimeout& msg) +{ +} + +void +ServerPagerMessage::send(SharedPtr<SipMessage> response) +{ + assert(response->isResponse()); + mDum.send(response); + delete this; +} + +SharedPtr<SipMessage> +ServerPagerMessage::accept(int statusCode) +{ + //!dcm! -- should any responses include a contact? + mDum.makeResponse(*mResponse, mRequest, statusCode); + mResponse->remove(h_Contacts); + return mResponse; +} + +class ServerPagerMessageAcceptCommand : public DumCommandAdapter +{ +public: + ServerPagerMessageAcceptCommand(ServerPagerMessage& serverPagerMessage, int statusCode) + : mServerPagerMessage(serverPagerMessage), + mStatusCode(statusCode) + { + } + + virtual void executeCommand() + { + mServerPagerMessage.accept(mStatusCode); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ServerPagerMessageAcceptCommand"; + } +private: + ServerPagerMessage& mServerPagerMessage; + int mStatusCode; +}; + +void +ServerPagerMessage::acceptCommand(int statusCode) +{ + mDum.post(new ServerPagerMessageAcceptCommand(*this, statusCode)); +} + +SharedPtr<SipMessage> +ServerPagerMessage::reject(int statusCode) +{ + //!dcm! -- should any responses include a contact? + mDum.makeResponse(*mResponse, mRequest, statusCode); + return mResponse; +} + +class ServerPagerMessageRejectCommand : public DumCommandAdapter +{ +public: + ServerPagerMessageRejectCommand(ServerPagerMessage& serverPagerMessage, int statusCode) + : mServerPagerMessage(serverPagerMessage), + mStatusCode(statusCode) + { + } + + virtual void executeCommand() + { + mServerPagerMessage.reject(mStatusCode); + } + + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ServerPagerMessageRejectCommand"; + } +private: + ServerPagerMessage& mServerPagerMessage; + int mStatusCode; +}; + +void +ServerPagerMessage::rejectCommand(int statusCode) +{ + mDum.post(new ServerPagerMessageRejectCommand(*this, statusCode)); +} + +EncodeStream& +ServerPagerMessage::dump(EncodeStream& strm) const +{ + strm << "ServerPagerMessage "; + mRequest.encodeBrief(strm); + return strm; +} + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerPagerMessage.hxx b/src/libs/resiprocate/resip/dum/ServerPagerMessage.hxx new file mode 100644 index 00000000..67ee0141 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerPagerMessage.hxx @@ -0,0 +1,102 @@ +#if !defined(RESIP_SERVERPAGERMESSAGE_HXX) +#define RESIP_SERVERPAGERMESSAGE_HXX + +#include "resip/dum/NonDialogUsage.hxx" +#include "resip/stack/SipMessage.hxx" + +namespace resip +{ + +class ServerPagerMessage : public NonDialogUsage +{ + public: + typedef Handle<ServerPagerMessage> ServerPagerMessageHandle; + ServerPagerMessageHandle getHandle(); + + SharedPtr<SipMessage> accept(int statusCode = 200); + SharedPtr<SipMessage> reject(int statusCode); + + virtual void end(); + + /** + * Provide asynchronous method access by using command + */ + void acceptCommand(int statusCode = 200); + void rejectCommand(int statusCode); + void endCommand(); + + virtual void send(SharedPtr<SipMessage> msg); + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + virtual EncodeStream& dump(EncodeStream& strm) const; + + protected: + virtual ~ServerPagerMessage(); + + private: + friend class DialogSet; + ServerPagerMessage(DialogUsageManager& dum, DialogSet& dialogSet, const SipMessage& req); + + SipMessage mRequest; + SharedPtr<SipMessage> mResponse; + + // disabled + ServerPagerMessage(const ServerPagerMessage&); + ServerPagerMessage& operator=(const ServerPagerMessage&); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerPublication.cxx b/src/libs/resiprocate/resip/dum/ServerPublication.cxx new file mode 100644 index 00000000..aa2e4449 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerPublication.cxx @@ -0,0 +1,229 @@ +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/ServerPublication.hxx" +#include "resip/dum/PublicationHandler.hxx" +#include "resip/dum/ServerSubscription.hxx" +#include "resip/dum/SubscriptionHandler.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/SecurityAttributes.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +ServerPublication::ServerPublication(DialogUsageManager& dum, + const Data& etag, + const SipMessage& msg) + : BaseUsage(dum), + mLastResponse(new SipMessage), + mEtag(etag), + mEventType(msg.header(h_Event).value()), + mTimerSeq(0) +{ +} + +ServerPublication::~ServerPublication() +{ + mDum.mServerPublications.erase(getEtag()); +} + +ServerPublicationHandle +ServerPublication::getHandle() +{ + return ServerPublicationHandle(mDum, getBaseHandle().getId()); +} + +const Data& +ServerPublication::getEtag() const +{ + return mEtag; +} + +const Data& +ServerPublication::getDocumentKey() const +{ + return mDocumentKey; +} + +Data +ServerPublication::getPublisher() const +{ + return mLastRequest.header(h_From).uri().getAor(); +} + +void +ServerPublication::updateMatchingSubscriptions() +{ + Data key = mEventType + mLastRequest.header(h_RequestLine).uri().getAor(); + std::pair<DialogUsageManager::ServerSubscriptions::iterator,DialogUsageManager::ServerSubscriptions::iterator> subs; + subs = mDum.mServerSubscriptions.equal_range(key); + + ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); + for (DialogUsageManager::ServerSubscriptions::iterator i=subs.first; i!=subs.second; ++i) + { + handler->onPublished(i->second->getHandle(), + getHandle(), + mLastBody.mContents.get(), + mLastBody.mAttributes.get()); + } + mLastBody.mContents.reset(); + mLastBody.mAttributes.reset(); +} + + +SharedPtr<SipMessage> +ServerPublication::accept(int statusCode) +{ + Helper::makeResponse(*mLastResponse, mLastRequest, statusCode); + mLastResponse->header(h_Expires).value() = mExpires; + + updateMatchingSubscriptions(); + + return mLastResponse; +} + +SharedPtr<SipMessage> +ServerPublication::reject(int statusCode) +{ + Helper::makeResponse(*mLastResponse, mLastRequest, statusCode); + mLastResponse->header(h_Expires).value() = mExpires; + return mLastResponse; +} + +void +ServerPublication::end() +{ + delete this; +} + +void +ServerPublication::dispatch(const SipMessage& msg) +{ + assert(msg.isRequest()); + ServerPublicationHandler* handler = mDum.getServerPublicationHandler(mEventType); + mLastRequest = msg; + mExpires = 3600; //bad + if (msg.exists(h_Expires)) + { + mExpires = msg.header(h_Expires).value(); + } + if (msg.exists(h_SIPIfMatch)) + { + if (mExpires == 0) + { + handler->onRemoved(getHandle(), mEtag, msg, mExpires); + Helper::makeResponse(*mLastResponse, mLastRequest, 200); + mLastResponse->header(h_Expires).value() = mExpires; + mDum.send(mLastResponse); + delete this; + return; + } + mLastBody = Helper::extractFromPkcs7(msg, *mDum.getSecurity()); + if (msg.getContents()) + { + handler->onUpdate(getHandle(), mEtag, msg, + mLastBody.mContents.get(), + mLastBody.mAttributes.get(), + mExpires); + } + else + { + handler->onRefresh(getHandle(), mEtag, msg, + mLastBody.mContents.get(), + mLastBody.mAttributes.get(), + mExpires); + } + } + else + { + mLastBody = Helper::extractFromPkcs7(msg, *mDum.getSecurity()); + handler->onInitial(getHandle(), mEtag, msg, + mLastBody.mContents.get(), + mLastBody.mAttributes.get(), + mExpires); + } +} + +void +ServerPublication::dispatch(const DumTimeout& msg) +{ + if (msg.seq() == mTimerSeq) + { + ServerPublicationHandler* handler = mDum.getServerPublicationHandler(mEventType); + handler->onExpired(getHandle(), mEtag); + delete this; + } +} + +void +ServerPublication::send(SharedPtr<SipMessage> response) +{ + assert(response->isResponse()); + response->header(h_SIPETag).value() = mEtag; + mDum.send(response); + if (response->header(h_StatusLine).statusCode() >= 300) + { + delete this; + } + else + { + mDum.addTimer(DumTimeout::Publication, response->header(h_Expires).value(), getBaseHandle(), ++mTimerSeq); + } +} + +EncodeStream& +ServerPublication::dump(EncodeStream& strm) const +{ + strm << "ServerPublication " << mDocumentKey << " " << mEventType; + return strm; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerPublication.hxx b/src/libs/resiprocate/resip/dum/ServerPublication.hxx new file mode 100644 index 00000000..ea36124a --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerPublication.hxx @@ -0,0 +1,105 @@ +#if !defined(RESIP_SERVERPUBLICATION_HXX) +#define RESIP_SERVERPUBLICATION_HXX + +#include "rutil/SharedPtr.hxx" +#include "resip/dum/BaseUsage.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Helper.hxx" + +namespace resip +{ + +class ServerPublication : public BaseUsage +{ + public: + typedef Handle<ServerPublication> ServerPublicationHandle; + ServerPublicationHandle getHandle(); + + const Data& getEtag() const; + const Data& getDocumentKey() const; + + SharedPtr<SipMessage> accept(int statusCode = 200); + SharedPtr<SipMessage> reject(int responseCode); + + virtual void end(); + + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + void send(SharedPtr<SipMessage> response); + + Data getPublisher() const; // aor of From + virtual EncodeStream& dump(EncodeStream& strm) const; + + protected: + virtual ~ServerPublication(); + void updateMatchingSubscriptions(); + + private: + friend class DialogUsageManager; + ServerPublication(DialogUsageManager& dum, const Data& etag, const SipMessage& request); + + SipMessage mLastRequest; + SharedPtr<SipMessage> mLastResponse; + const Data mEtag; + const Data mEventType; + const Data mDocumentKey; + Helper::ContentsSecAttrs mLastBody; + unsigned int mTimerSeq; + UInt32 mExpires; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerRegistration.cxx b/src/libs/resiprocate/resip/dum/ServerRegistration.cxx new file mode 100644 index 00000000..44fe12a9 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerRegistration.cxx @@ -0,0 +1,884 @@ +#include "resip/stack/ExtensionParameter.hxx" +#include "resip/stack/InteropHelper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/MasterProfile.hxx" +#include "resip/dum/ServerRegistration.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/RegistrationHandler.hxx" +#include "resip/dum/RegistrationPersistenceManager.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Timer.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +ServerRegistrationHandle +ServerRegistration::getHandle() +{ + return ServerRegistrationHandle(mDum, getBaseHandle().getId()); +} + +ServerRegistration::ServerRegistration(DialogUsageManager& dum, DialogSet& dialogSet, const SipMessage& request) + : NonDialogUsage(dum, dialogSet), + mRequest(request), + mDidOutbound(false), + mAsyncState(asyncStateNone) +{} + +ServerRegistration::~ServerRegistration() +{ + mDialogSet.mServerRegistration = 0; +} + +void +ServerRegistration::end() +{ +} + +static Token outbound(Symbols::Outbound); +void +ServerRegistration::accept(SipMessage& ok) +{ + ok.remove(h_Contacts); + + InfoLog( << "accepted a registration " << mAor ); + + if (mDidOutbound) + { + ok.header(h_Requires).push_back(outbound); + if(InteropHelper::getFlowTimerSeconds() > 0) + { + ok.header(h_FlowTimer).value() = InteropHelper::getFlowTimerSeconds(); + mDum.getSipStack().enableFlowTimer(mRequest.getSource()); + } + } + + if (!mDum.mServerRegistrationHandler->asyncProcessing()) + { + // Add all registered contacts to the message. + RegistrationPersistenceManager *database = mDum.mRegistrationPersistenceManager; + + ContactList contacts; + database->getContacts(mAor, contacts); + + //removes expired entries from the ok msg as well as calls the database to remove expired contacts. + processFinalOkMsg(ok,contacts); + + database->unlockRecord(mAor); + + SharedPtr<SipMessage> msg(static_cast<SipMessage*>(ok.clone())); + mDum.send(msg); + delete(this); + } + else + { + if (mAsyncState == asyncStateQueryOnly) + { + if (!mAsyncLocalStore.get()) + { + assert(0); + } + else + { + std::auto_ptr<ContactRecordTransactionLog> log; + std::auto_ptr<ContactPtrList> contacts; + + mAsyncLocalStore->releaseLog(log,contacts); + + if (contacts.get()) + { + asyncProcessFinalOkMsg(ok,*contacts); + } + } + + SharedPtr<SipMessage> msg(static_cast<SipMessage*>(ok.clone())); + mDum.send(msg); + delete(this); + } + else + { + if (!mAsyncLocalStore.get()) + { + assert(0); + return; + } + //This register was accepted, but still need to apply the changes made by this register and then + //receive a final contact list before sending the 200. + mAsyncState = asyncStateAcceptedWaitingForFinalContactList; + + std::auto_ptr<ContactRecordTransactionLog> log; + std::auto_ptr<ContactPtrList> modifiedContacts; + + mAsyncLocalStore->releaseLog(log,modifiedContacts); + + mAsyncOkMsg = SharedPtr<SipMessage>(static_cast<SipMessage*>(ok.clone())); + mDum.mServerRegistrationHandler->asyncUpdateContacts(getHandle(),mAor,modifiedContacts,log); + //!WARN! Must not access this object beyond this point. The client my call reject() or accept(), deleting this object. Also, watch out for local objects that are still in scope and access this object on destruction. + return; + } + } +} + +void +ServerRegistration::accept(int statusCode) +{ + SipMessage success; + mDum.makeResponse(success, mRequest, statusCode); + // .bwc. Copy Path headers if present, indicate Path support + // ?bwc? If path headers are present, but client indicates no path support, + // RFC 3327 says it is a matter of policy of whether to accept the + // registration or not. What should we do here? Is it worth it to make this + // configurable? + if(!mRequest.empty(h_Paths)) + { + success.header(h_Paths)=mRequest.header(h_Paths); + success.header(h_Supporteds).push_back(Token(Symbols::Path)); + } + accept(success); +} + +void +ServerRegistration::reject(int statusCode) +{ + InfoLog( << "rejected a registration " << mAor << " with statusCode=" << statusCode ); + + // First, we roll back the contact database to + // the state it was before the registration request. + + // Async processing hasn't actually updated the database yet, so no need to roll back. + if (mDum.mServerRegistrationHandler && !mDum.mServerRegistrationHandler->asyncProcessing()) + { + // Rollback changes, since rejected + RegistrationPersistenceManager *database = mDum.mRegistrationPersistenceManager; + database->removeAor(mAor); + if (mOriginalContacts.get()) + { + database->addAor(mAor, *mOriginalContacts); + } + database->unlockRecord(mAor); + } + + SharedPtr<SipMessage> failure(new SipMessage); + mDum.makeResponse(*failure, mRequest, statusCode); + failure->remove(h_Contacts); + mDum.send(failure); + delete(this); +} + +void +ServerRegistration::dispatch(const SipMessage& msg) +{ + DebugLog( << "got a registration" ); + + assert(msg.isRequest()); + ServerRegistrationHandler* handler = mDum.mServerRegistrationHandler; + RegistrationPersistenceManager *database = mDum.mRegistrationPersistenceManager; + + if (!handler || (!handler->asyncProcessing() && !database)) + { + // ?bwc? This is a server error; why are we sending a 4xx? + // ?jmatthewsr? Possibly because of the note in section 21.5.2 about recognizing the method, but not supporting it? + DebugLog( << "No handler or DB - sending 405" ); + + SharedPtr<SipMessage> failure(new SipMessage); + mDum.makeResponse(*failure, msg, 405); + mDum.send(failure); + delete(this); + return; + } + + mAor = msg.header(h_To).uri().getAorAsUri(msg.getSource().getType()); + + // Checks to see whether this scheme is valid, and supported. + if (!((mAor.scheme()=="sip" || mAor.scheme()=="sips") + && mDum.getMasterProfile()->isSchemeSupported(mAor.scheme()))) + { + DebugLog( << "Bad scheme in Aor" ); + + SharedPtr<SipMessage> failure(new SipMessage); + mDum.makeResponse(*failure, msg, 400); + failure->header(h_StatusLine).reason() = "Bad/unsupported scheme in To: " + mAor.scheme(); + mDum.send(failure); + delete(this); + return; + } + + if (handler->asyncProcessing()) + { + mAsyncState = asyncStateWaitingForInitialContactList; + handler->asyncGetContacts(getHandle(),mAor); + //!WARN! Must not access this object beyond this point. The client my call reject() or accept(), deleting this object. Also, watch out for local objects that are still in scope and access this object on destruction. + return; + } + + processRegistration(msg); +} + +void +ServerRegistration::processRegistration(const SipMessage& msg) +{ + ServerRegistrationHandler* handler = mDum.mServerRegistrationHandler; + RegistrationPersistenceManager *database = mDum.mRegistrationPersistenceManager; + + enum {ADD, REMOVE, REFRESH} operation = REFRESH; + + UInt32 globalExpires=3600; + UInt32 returnCode=0; + handler->getGlobalExpires(msg,mDum.getMasterProfile(),globalExpires,returnCode); + + bool async = handler->asyncProcessing(); + + if (returnCode >= 400) + { + SharedPtr<SipMessage> failure(new SipMessage); + mDum.makeResponse(*failure, msg, returnCode); + if (423 == returnCode) + { + failure->header(h_StatusLine).reason() = "Interval Too Brief"; + failure->header(h_MinExpires).value() = globalExpires; + } + mDum.send(failure); + delete(this); + return; + } + + if (!async) + { + database->lockRecord(mAor); + + mOriginalContacts = resip::SharedPtr<ContactList>(new ContactList); + database->getContacts(mAor, *mOriginalContacts); + } + + // If no contacts are present in the request, this is simply a query. + if (!msg.exists(h_Contacts)) + { + if (async) + { + mAsyncState = asyncStateQueryOnly; + } + handler->onQuery(getHandle(), msg); + //!WARN! Must not access this object beyond this point. The client my call reject() or accept(), deleting this object. Also, watch out for local objects that are still in scope and access this object on destruction. + return; + } + + ParserContainer<NameAddr> contactList(msg.header(h_Contacts)); + ParserContainer<NameAddr>::iterator i(contactList.begin()); + ParserContainer<NameAddr>::iterator iEnd(contactList.end()); + UInt64 now=Timer::getTimeSecs(); + UInt32 expires=0; + + for (; i != iEnd; ++i) + { + if (!i->isWellFormed()) + { + SharedPtr<SipMessage> failure(new SipMessage); + mDum.makeResponse(*failure, msg, 400, "Malformed Contact"); + mDum.send(failure); + if (!async) + { + database->unlockRecord(mAor); + } + delete(this); + return; + } + + expires = globalExpires; + handler->getContactExpires(*i, mDum.getMasterProfile(), expires, returnCode); + + // Check for "Contact: *" style deregistration + if (i->isAllContacts()) + { + if (contactList.size() > 1 || expires != 0) + { + SharedPtr<SipMessage> failure(new SipMessage); + mDum.makeResponse(*failure, msg, 400, "Invalid use of 'Contact: *'"); + mDum.send(failure); + if (!async) + { + database->unlockRecord(mAor); + } + delete(this); + return; + } + + if (!async) + { + database->removeAor(mAor); + } + else + { + mAsyncLocalStore->removeAllContacts(); + mAsyncState = asyncStateWaitingForAcceptReject; + } + + handler->onRemoveAll(getHandle(), msg); + //!WARN! Must not access this object beyond this point. The client my call reject() or accept(), deleting this object. Also, watch out for local objects that are still in scope and access this object on destruction. + return; + } + + ContactInstanceRecord rec; + rec.mContact=*i; + rec.mRegExpires=(UInt64)expires+now; + + if(i->exists(p_Instance)) + { + rec.mInstance=i->param(p_Instance); + } + + if(!msg.empty(h_Paths)) + { + rec.mSipPath=msg.header(h_Paths); + } + + rec.mLastUpdated=now; + rec.mReceivedFrom=msg.getSource(); + rec.mPublicAddress=Helper::getClientPublicAddress(msg); + + bool hasFlow = tryFlow(rec,msg); + + if(!testFlowRequirements(rec, msg, hasFlow)) + { + // We have rejected the request. Bail. + if (!async) + { + database->unlockRecord(mAor); + } + delete(this); + return; + } + + // Add ContactInstanceRecord to List + mRequestContacts.push_back(rec); + + // Check to see if this is a removal. + if (expires == 0) + { + if (operation == REFRESH) + { + operation = REMOVE; + } + + if (!async) + { + database->removeContact(mAor, rec); + } + else + { + mAsyncLocalStore->removeContact(rec); + } + } + else // Otherwise, it's an addition or refresh. + { + RegistrationPersistenceManager::update_status_t status; + InfoLog(<< "Adding " << mAor << " -> " << *i); + DebugLog(<< "Contact has tuple " << rec.mReceivedFrom << " and detected public address " << rec.mPublicAddress); + + if (!async) + { + status = database->updateContact(mAor, rec); + } + else + { + status = mAsyncLocalStore->updateContact(rec); + } + + if (status == RegistrationPersistenceManager::CONTACT_CREATED) + { + operation = ADD; + } + } + } + + // The way this works is: + // + // - If no additions or removals are performed, this is a refresh + // + // - If at least one contact is removed and none are added, this + // is a removal. + // + // - If at least one contact is added, this is an addition, *even* + // *if* a contact was also removed. + + //for async processing, need to wait for accept()/reject(). If accepted, the modifications made here will be + //sent to the user via asyncUpdateContacts(). The user then returns a final contact list, which is then processed + //and sent back in the 200. + if (async) + { + mAsyncState = asyncStateWaitingForAcceptReject; + } + + switch (operation) + { + case REFRESH: + handler->onRefresh(getHandle(), msg); + //!WARN! Must not access this object beyond this point. The client my call reject() or accept(), deleting this object. Also, watch out for local objects that are still in scope and access this object on destruction. + return; + + case REMOVE: + handler->onRemove(getHandle(), msg); + //!WARN! Must not access this object beyond this point. The client my call reject() or accept(), deleting this object. Also, watch out for local objects that are still in scope and access this object on destruction. + return; + + case ADD: + handler->onAdd(getHandle(), msg); + //!WARN! Must not access this object beyond this point. The client my call reject() or accept(), deleting this object. Also, watch out for local objects that are still in scope and access this object on destruction. + return; + + default: + assert(0); + } +} + +void +ServerRegistration::dispatch(const DumTimeout& msg) +{ +} + +EncodeStream& +ServerRegistration::dump(EncodeStream& strm) const +{ + strm << "ServerRegistration " << mAor; + return strm; +} + +bool +ServerRegistration::tryFlow(ContactInstanceRecord& rec, + const resip::SipMessage& msg) +{ + // .bwc. ie. Can we assure that the connection the client is using on the + // first hop can be re-used later? + try + { + // Outbound logic + if(InteropHelper::getOutboundSupported()) + { + resip::NameAddr& contact(rec.mContact); + if(contact.exists(p_Instance) && contact.exists(p_regid)) + { + if(!msg.empty(h_Paths) && (msg.header(h_Paths).back().uri().exists(p_ob) || + InteropHelper::getAssumeFirstHopSupportsOutboundEnabled())) + { + rec.mRegId=contact.param(p_regid); + // Edge-proxy is directly connected to the client, and ready to + // send traffic down the "connection" (TCP connection, or NAT + // pinhole, or what-have-you). + mDidOutbound=true; + return true; + } + else if(msg.header(h_Vias).size() == 1) + { + rec.mRegId=contact.param(p_regid); + // We are directly connected to the client. + // .bwc. In the outbound case, we should fail if the connection + // is gone. No recovery should be attempted by the server. + rec.mUseFlowRouting = true; + rec.mReceivedFrom.onlyUseExistingConnection=true; + mDidOutbound=true; + return true; + } + } + } + + // Record-Route flow token hack, or client NAT detect hack; use with caution + if(msg.header(h_Vias).size() == 1) // client is directly connected to this server + { + if(InteropHelper::getRRTokenHackEnabled() || + flowTokenNeededForTls(rec) || + flowTokenNeededForSigcomp(rec) || + (InteropHelper::getClientNATDetectionMode() != InteropHelper::ClientNATDetectionDisabled && + Helper::isClientBehindNAT(msg, InteropHelper::getClientNATDetectionMode() == InteropHelper::ClientNATDetectionPrivateToPublicOnly))) + { + rec.mUseFlowRouting = true; + rec.mReceivedFrom.onlyUseExistingConnection=false; + return true; + } + } + } + catch(resip::ParseBuffer::Exception&) + {} + return false; +} + +bool +ServerRegistration::testFlowRequirements(ContactInstanceRecord &rec, + const resip::SipMessage& msg, + bool hasFlow) const +{ + const resip::NameAddr& contact(rec.mContact); + + if(contact.exists(p_Instance) && contact.exists(p_regid)) + { + // Client has explicitly requested Outbound processing, which requires us + // to have a flow. + if(!hasFlow) + { + SharedPtr<SipMessage> failure(new SipMessage); + mDum.makeResponse(*failure, msg, 439); + mDum.send(failure); + return false; + } + } + + if(!hasFlow && flowTokenNeededForTls(rec)) + { + SharedPtr<SipMessage> failure(new SipMessage); + mDum.makeResponse(*failure, msg, 400, "Trying to use TLS with an IP-address in your Contact header won't work if you don't have a flow. Consider implementing outbound, or putting an FQDN in your contact header."); + mDum.send(failure); + return false; + } + + if(!hasFlow && flowTokenNeededForSigcomp(rec)) + { + SharedPtr<SipMessage> failure(new SipMessage); + mDum.makeResponse(*failure, msg, 400, "Trying to use sigcomp on a connection-oriented protocol won't work if you don't have a flow. Consider implementing outbound, or using UDP/DTLS for this case."); + mDum.send(failure); + return false; + } + + return true; +} + +bool +ServerRegistration::flowTokenNeededForTls(const ContactInstanceRecord &rec) const +{ + const resip::NameAddr& contact(rec.mContact); + if(DnsUtil::isIpAddress(contact.uri().host())) + { + // IP address in host-part. + if(contact.uri().scheme()=="sips") + { + // sips: and IP-address in contact. This will probably not work anyway. + return true; + } + + if(contact.uri().exists(p_transport)) + { + TransportType type = Tuple::toTransport(contact.uri().param(p_transport)); + if(type==TLS || type == DTLS) + { + // secure transport and IP-address. Almost certainly won't work, but + // we'll try anyway. + return true; + } + } + } + return false; +} + +bool +ServerRegistration::flowTokenNeededForSigcomp(const ContactInstanceRecord &rec) const +{ + const resip::NameAddr& contact(rec.mContact); + + if(contact.uri().exists(p_sigcompId)) + { + if(contact.uri().exists(p_transport)) + { + TransportType type = Tuple::toTransport(contact.uri().param(p_transport)); + if(type == TLS || type == TCP) + { + // Client is using sigcomp on the first hop using a connection- + // oriented transport. For this to work, that connection has to be + // reused for all traffic. + return true; + } + } + else + { + // ?bwc? Client is using sigcomp, but we're not sure whether this is + // over a connection-oriented transport or not. + DebugLog(<< "Client is using sigcomp, but we're not sure whether this " + "is over a connection-oriented transport or not, because " + "the contact doesn't have a transport param in it. It is " + "possible this will work though, so we'll let it proceed." + ); + } + } + return false; +} + + +void +ServerRegistration::asyncProcessFinalOkMsg(SipMessage &msg, ContactPtrList &contacts) +{ + if (contacts.size() > 0) + { + ContactPtrList::iterator it(contacts.begin()); + ContactPtrList::iterator itEnd(contacts.end()); + + std::auto_ptr<ContactPtrList> expired; + + UInt64 now=Timer::getTimeSecs(); + + for (;it != itEnd;++it) + { + resip::SharedPtr<ContactInstanceRecord> rec(*it); + + if (!rec) + { + assert(0); + continue; + } + + if (rec->mRegExpires <= now) + { + if (!expired.get()) + { + expired = std::auto_ptr<ContactPtrList>(new ContactPtrList()); + } + expired->push_back(rec); + continue; + } + + rec->mContact.param(p_expires) = UInt32(rec->mRegExpires - now); + msg.header(h_Contacts).push_back(rec->mContact); + } + + if (expired.get() && expired->size() > 0) + { + mDum.mServerRegistrationHandler->asyncRemoveExpired(getHandle(),mAor,expired); + //!WARN! Must not access this object beyond this point. The client my call reject() or accept(), deleting this object. Also, watch out for local objects that are still in scope and access this object on destruction. + return; + } + } +} + +void +ServerRegistration::processFinalOkMsg(SipMessage &msg, ContactList &contacts) +{ + //build the 200Ok and remove any expired entries. + //the non-asynchronous behavior is to call the database directly, the async behavior is to build a + //list of all expired entries and send it to the handler. + if (contacts.size() > 0) + { + ContactList::iterator it(contacts.begin()); + ContactList::iterator itEnd(contacts.end()); + + RegistrationPersistenceManager *database = mDum.mRegistrationPersistenceManager; + UInt64 now=Timer::getTimeSecs(); + + for (;it != itEnd;++it) + { + if (it->mRegExpires <= now) + { + database->removeContact(mAor,*it); + continue; + } + it->mContact.param(p_expires) = UInt32(it->mRegExpires - now); + msg.header(h_Contacts).push_back(it->mContact); + } + } +} + +bool +ServerRegistration::asyncProvideContacts(std::auto_ptr<resip::ContactPtrList> contacts) +{ + switch (mAsyncState) + { + case asyncStateWaitingForInitialContactList: + { + assert(mAsyncLocalStore.get() == 0); + mAsyncLocalStore = resip::SharedPtr<AsyncLocalStore>(new AsyncLocalStore(contacts)); + mAsyncState = asyncStateProcessingRegistration; + processRegistration(mRequest); + break; + } + case asyncStateWaitingForAcceptReject: + { + assert(0); //need to call accept() or reject(), wait for asyncUpdateContacts(), then call this function. + return false; + } + case asyncStateAcceptedWaitingForFinalContactList: + { + mAsyncState = asyncStateProvidedFinalContacts; + asyncProcessFinalContacts(contacts); + break; + } + default: + { + assert(0); + return false; + } + } + + return true; +} + +void +ServerRegistration::asyncProcessFinalContacts(std::auto_ptr<resip::ContactPtrList> contacts) +{ + if (contacts.get()) + { + if (!mAsyncOkMsg.get()) + { + assert(0); + } + else + { + asyncProcessFinalOkMsg(*mAsyncOkMsg,*contacts); + } + } + + mAsyncState = asyncStateNone; + mDum.send(mAsyncOkMsg); + mAsyncOkMsg.reset(); + delete(this); +} + +void +ServerRegistration::AsyncLocalStore::create(std::auto_ptr<ContactPtrList> originalContacts) +{ + mModifiedContacts = originalContacts; + mLog = std::auto_ptr<ContactRecordTransactionLog>(new ContactRecordTransactionLog()); +} + +void +ServerRegistration::AsyncLocalStore::destroy(void) +{ + mModifiedContacts.reset(); + mLog.reset(); +} + +RegistrationPersistenceManager::update_status_t +ServerRegistration::AsyncLocalStore::updateContact(const ContactInstanceRecord &rec) +{ + if (!mModifiedContacts.get() || !mLog.get()) + { + assert(0); + return RegistrationPersistenceManager::CONTACT_UPDATED; + } + + ContactPtrList::iterator it(mModifiedContacts->begin()); + ContactPtrList::iterator itEnd(mModifiedContacts->end()); + + resip::SharedPtr<ContactRecordTransaction> logEntry; + + // See if the contact is already present. We use URI matching rules here. + for (; it != itEnd; ++it) + { + if ((*it) && **it == rec) + { + **it = rec; + + logEntry = resip::SharedPtr<ContactRecordTransaction>(new ContactRecordTransaction(ContactRecordTransaction::update,*it)); + mLog->push_back(logEntry); + + return RegistrationPersistenceManager::CONTACT_UPDATED; + } + } + + // This is a new contact, so we add it to the list. + resip::SharedPtr<ContactInstanceRecord> newRec(new ContactInstanceRecord(rec)); + + logEntry = resip::SharedPtr<ContactRecordTransaction>(new ContactRecordTransaction(ContactRecordTransaction::create,newRec)); + mLog->push_back(logEntry); + + mModifiedContacts->push_back(newRec); + + return RegistrationPersistenceManager::CONTACT_CREATED; +} + +void +ServerRegistration::AsyncLocalStore::removeContact(const ContactInstanceRecord &rec) +{ + if (!mModifiedContacts.get() || !mLog.get()) + { + assert(0); + return; + } + + ContactPtrList::iterator it(mModifiedContacts->begin()); + ContactPtrList::iterator itEnd(mModifiedContacts->end()); + + // See if the contact is present. We use URI matching rules here. + for (; it != itEnd; ++it) + { + if ((*it) && **it == rec) + { + resip::SharedPtr<ContactRecordTransaction> + logEntry(resip::SharedPtr<ContactRecordTransaction> + (new ContactRecordTransaction(ContactRecordTransaction::remove,*it))); + + mLog->push_back(logEntry); + + mModifiedContacts->erase(it); + return; + } + } +} + +void +ServerRegistration::AsyncLocalStore::removeAllContacts(void) +{ + if (!mModifiedContacts.get() || !mLog.get()) + { + return; + } + + resip::SharedPtr<ContactInstanceRecord> recNull; + + resip::SharedPtr<ContactRecordTransaction> + logEntry(resip::SharedPtr<ContactRecordTransaction>(new ContactRecordTransaction(ContactRecordTransaction::removeAll,recNull))); + + mLog->push_back(logEntry); + + mModifiedContacts->clear(); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerRegistration.hxx b/src/libs/resiprocate/resip/dum/ServerRegistration.hxx new file mode 100644 index 00000000..dc11b03d --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerRegistration.hxx @@ -0,0 +1,246 @@ +#if !defined(RESIP_SERVERREGISTRATION_HXX) +#define RESIP_SERVERREGISTRATION_HXX + +#include "resip/dum/NonDialogUsage.hxx" +#include "resip/dum/RegistrationPersistenceManager.hxx" +#include "resip/stack/SipMessage.hxx" + +namespace resip +{ + +class ServerRegistration: public NonDialogUsage +{ + public: + ServerRegistrationHandle getHandle(); + + /** Accept a SIP registration with a specific response. Any contacts in this message will be deleted and replaced with the list created during REGISTER processing. + + !Warning! After calling this function from a ServerRegistrationHandle, do not access the handle as this function + may delete this object. Use ServerRegistrationHandle::isValidHandle() to test if it's deleted. + */ + void accept(SipMessage& ok); + + /** Accept a SIP registration. + + !Warning! After calling this function from a ServerRegistrationHandle, do not access the handle as this function + may delete this object. Use ServerRegistrationHandle::isValidHandle() to test if it's deleted. + */ + void accept(int statusCode = 200); + + /** Reject a SIP registration. + + !Warning! After calling this function from a ServerRegistrationHandle, do not access the handle as this function + may delete this object. Use ServerRegistrationHandle::isValidHandle() to test if it's deleted. + */ + void reject(int statusCode); + + virtual void end(); + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + virtual EncodeStream& dump(EncodeStream& strm) const; + + /** Used when useAsyncProcessing() is true. Provide the current set of contacts for this registration for + * processing. This is required during initial registration processing to provide a local copy of the registered contacts, which + are then updated by the registration processing. At the end of the registration processing this function must provide a + final list of contacts after any user-defined manipulation. + + !CAUTION! This function must be called from the DUM thread. + */ + bool asyncProvideContacts(std::auto_ptr<resip::ContactPtrList> contacts); + + resip::SharedPtr<ContactList> getOriginalContacts() { return mOriginalContacts; } // WARNING - use this only if async mode is not used + const ContactList& getRequestContacts() { return mRequestContacts; } + + protected: + virtual ~ServerRegistration(); + private: + friend class DialogSet; + ServerRegistration(DialogUsageManager& dum, DialogSet& dialogSet, const SipMessage& request); + + bool tryFlow(ContactInstanceRecord& rec, + const resip::SipMessage& msg); + bool flowTokenNeededForTls(const ContactInstanceRecord &rec) const; + bool flowTokenNeededForSigcomp(const ContactInstanceRecord &rec) const; + bool testFlowRequirements(ContactInstanceRecord &rec, + const resip::SipMessage& msg, + bool hasFlow) const; + + SipMessage mRequest; + Uri mAor; + resip::SharedPtr<ContactList> mOriginalContacts; // Used only for non-async processing + ContactList mRequestContacts; // Contains the Contacts from the REGISTER request + bool mDidOutbound; + + // disabled + ServerRegistration(const ServerRegistration&); + ServerRegistration& operator=(const ServerRegistration&); + + /** States are used to keep track of asynchronous requests made to the database. + Typical activity & state progression for a successful registration (onQuery & reject() are slightly different): + + DUM ServerRegistration RegistrationHandler + _____________________________________________________________________________________________________ + + 1) dispatch()/asyncStateNone---> + 2) asyncGetContacts()/asyncStateWaitingForInitialContactList---> + ====================================================================================================== + 3) <---asyncProvideContacts()/asyncStateProcessingRegistration + 4) processRegistration() + 5) (onRefresh()|onRemove()|onAdd()|onRemoveAll()|onQuery)/asyncStateWaitingForAcceptReject---> + ====================================================================================================== + 6) <---accept() + 7) asyncUpdateContacts/asyncStateAcceptedWaitingForFinalContactList---> + ====================================================================================================== + 8) <---asyncProvideContacts()/asyncStateProvidedFinalContacts + 9) asyncProcessFinalContacts()/asyncStateNone + 10) <---send(200Ok) + ______________________________________________________________________________________________________ + + * onQuery processing is similar, except it immediately sends the 200Ok after handling the accept(). + + * ServerRegistration::reject() does not require roll-back and the error is immediately sent back to DUM. + + * It is possible to call ServerRegistration::reject() after calling accept() (DB failure, app failure, etc) + + */ + typedef enum AsyncState + { + asyncStateNone, + asyncStateWaitingForInitialContactList, //!< Sent an asynchronous request to get the current contact list from the DB. + asyncStateProcessingRegistration, //!< received the initial contact list, processing the current REGISTER request and updating the contact list. + asyncStateWaitingForAcceptReject, //!< RegistrationHandler called, waiting for accept() or reject() from user. + asyncStateAcceptedWaitingForFinalContactList, //!< asyncUpdateContacts() has been called, waiting for final list. + asyncStateProvidedFinalContacts, //!< After receiving the final contact list; process the accepted register and send response. + asyncStateQueryOnly //!< The REGISTER is a query, so just send back the current list in accept(). + } AsyncState; + + AsyncState mAsyncState; + + /** Look at the contacts provided by the incoming REGISTER. + */ + void processRegistration(const SipMessage& msg); + + void asyncProcessFinalOkMsg(SipMessage &msg, ContactPtrList &contacts); + + /** Add contacs to msg, adding expires param. Also removes expired entries from contacts and calls the + * appropriate DB functions to remove them. + */ + void processFinalOkMsg(SipMessage &msg, ContactList &contacts); + + /** After the user calls accept(), ServerRegistration will apply the local contact list and wait for a final + * contact list. Once the final list is received via asyncProvideContacts(), this function finishes the REGISTER + * processing. + */ + void asyncProcessFinalContacts(std::auto_ptr<resip::ContactPtrList> contacts); + + /** Local datastore used to aggregate all changes to the current contact list when using the asynchronous logic. + */ + class AsyncLocalStore + { + public: + + AsyncLocalStore(std::auto_ptr<ContactPtrList> originalContacts) + { + create(originalContacts); + } + + ~AsyncLocalStore(void) + { + destroy(); + } + + /** Setup this object in preparation for updating the records. Updates occur when processing a REGISTER + message. + */ + void create(std::auto_ptr<ContactPtrList> originalContacts); + + void destroy(void); + + void removeContact(const ContactInstanceRecord &rec); + /** All original contacts are to be removed, move them all to the removed list + */ + void removeAllContacts(void); + + /** Could be an addition or refresh. + */ + RegistrationPersistenceManager::update_status_t + updateContact(const ContactInstanceRecord &rec); + + /** Remove the transacation log and updated contact list. This object should be considered destroyed and + not used after releasing. + */ + void releaseLog(std::auto_ptr<ContactRecordTransactionLog> &log, std::auto_ptr<ContactPtrList> &modifiedContacts) + { + log = mLog; + modifiedContacts = mModifiedContacts; + } + + unsigned int numContacts() { if(mModifiedContacts.get()) return (unsigned int)mModifiedContacts->size(); return 0; } + private: + std::auto_ptr<ContactRecordTransactionLog> mLog; + std::auto_ptr<ContactPtrList> mModifiedContacts; + }; + + resip::SharedPtr<AsyncLocalStore> mAsyncLocalStore; + + /** Message stored during accept() call when waiting for final contact list from database. + * Is eventually used as the 200Ok sent back to DUM when all is finished. + */ + resip::SharedPtr<SipMessage> mAsyncOkMsg; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerSubscription.cxx b/src/libs/resiprocate/resip/dum/ServerSubscription.cxx new file mode 100644 index 00000000..8a3775d7 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerSubscription.cxx @@ -0,0 +1,490 @@ +#include "resip/dum/AppDialog.hxx" +#include "resip/dum/Dialog.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/ServerSubscription.hxx" +#include "resip/dum/SubscriptionHandler.hxx" +#include "resip/dum/UsageUseException.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/Logger.hxx" + +#include <time.h> + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +ServerSubscriptionHandle +ServerSubscription::getHandle() +{ + return ServerSubscriptionHandle(mDum, getBaseHandle().getId()); +} + +ServerSubscription::ServerSubscription(DialogUsageManager& dum, + Dialog& dialog, + const SipMessage& req) + : BaseSubscription(dum, dialog, req), + mSubscriber(req.header(h_From).uri().getAor()), + mExpires(60), + mAbsoluteExpiry(0) +{ + if (req.header(h_RequestLine).method() == REFER && req.header(h_To).exists(p_tag)) + { + // If this is an in-dialog REFER, then use a subscription id + mSubscriptionId = Data(req.header(h_CSeq).sequence()); + } + Data key = getEventType() + getDocumentKey(); + mDum.mServerSubscriptions.insert(DialogUsageManager::ServerSubscriptions::value_type(key, this)); +} + +ServerSubscription::~ServerSubscription() +{ + DebugLog(<< "ServerSubscription::~ServerSubscription"); + + Data key = getEventType() + getDocumentKey(); + + std::pair<DialogUsageManager::ServerSubscriptions::iterator,DialogUsageManager::ServerSubscriptions::iterator> subs; + subs = mDum.mServerSubscriptions.equal_range(key); + for (DialogUsageManager::ServerSubscriptions::iterator i=subs.first; i!=subs.second; ++i) + { + if (i->second == this) + { + mDum.mServerSubscriptions.erase(i); + break; + } + } + + mDialog.mServerSubscriptions.remove(this); +} + +UInt32 +ServerSubscription::getTimeLeft() +{ + UInt32 timeleft = UInt32(mAbsoluteExpiry - Timer::getTimeSecs()); + if (timeleft < 0) // .kw. this can NEVER happen since unsigned! + { + return 0; + } + else + { + return timeleft; + } +} + +SharedPtr<SipMessage> +ServerSubscription::accept(int statusCode) +{ + mDialog.makeResponse(*mLastResponse, mLastSubscribe, statusCode); + mLastResponse->header(h_Expires).value() = mExpires; + return mLastResponse; +} + +SharedPtr<SipMessage> +ServerSubscription::reject(int statusCode) +{ + if (statusCode < 300) + { + throw UsageUseException("Must reject with a code greater than or equal to 300", __FILE__, __LINE__); + } + mDialog.makeResponse(*mLastResponse, mLastSubscribe, statusCode); + return mLastResponse; +} + + +void +ServerSubscription::send(SharedPtr<SipMessage> msg) +{ + ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); + assert(handler); + if (msg->isResponse()) + { + int code = msg->header(h_StatusLine).statusCode(); + if (code < 200) + { + DialogUsage::send(msg); + } + else if (code < 300) + { + if(msg->exists(h_Expires)) + { + mDum.addTimer(DumTimeout::Subscription, msg->header(h_Expires).value(), getBaseHandle(), ++mTimerSeq); + DialogUsage::send(msg); + mAbsoluteExpiry = Timer::getTimeSecs() + msg->header(h_Expires).value(); + mSubDlgState = SubDlgEstablished; + } + else + { + throw UsageUseException("2xx to a Subscribe MUST contain an Expires header", __FILE__, __LINE__); + } + } + else if (code < 400) + { + DialogUsage::send(msg); + handler->onTerminated(getHandle()); + delete this; + return; + } + else + { + if (shouldDestroyAfterSendingFailure(*msg)) + { + DialogUsage::send(msg); + handler->onTerminated(getHandle()); + delete this; + return; + } + else + { + DialogUsage::send(msg); + } + } + } + else + { + DialogUsage::send(msg); + if (mSubscriptionState == Terminated) + { + handler->onTerminated(getHandle()); + delete this; + } + } +} + +bool +ServerSubscription::shouldDestroyAfterSendingFailure(const SipMessage& msg) +{ + int code = msg.header(h_StatusLine).statusCode(); + switch(mSubDlgState) + { + case SubDlgInitial: + return true; + case SubDlgTerminating: //terminated state not using in ServerSubscription + assert(0); + return true; + case SubDlgEstablished: + { + if (code == 405) + { + return true; + } + switch (Helper::determineFailureMessageEffect(*mLastResponse)) + { + case Helper::TransactionTermination: + case Helper::RetryAfter: + break; + case Helper::OptionalRetryAfter: + case Helper::ApplicationDependant: + // .bwc. Uh, no. ApplicationDependent should imply that the + // app-writer has decided what to do. We don't decide here. And + // OptionalRetryAfter certainly doesn't mean we should tear the + // Usage down. +// throw UsageUseException("Not a reasonable code to reject a SUBSCIRBE(refresh) inside a dialog.", +// __FILE__, __LINE__); + break; + case Helper::DialogTermination: //?dcm? -- throw or destroy this? + case Helper::UsageTermination: + return true; + } + break; + } + default: // !jf! + assert(0); + break; + + } + return false; +} + +void +ServerSubscription::setSubscriptionState(SubscriptionState state) +{ + mSubscriptionState = state; +} + +void +ServerSubscription::dispatch(const SipMessage& msg) +{ + DebugLog( << "ServerSubscriptionHandler::dispatch: " << msg.brief()); + + ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); + assert(handler); + + if (msg.isRequest()) + { + //!dcm! -- need to have a mechanism to retrieve default & acceptable + //expiration times for an event package--part of handler API? + //added to handler for now. + mLastSubscribe = msg; + + int errorResponseCode = 0; + handler->getExpires(msg,mExpires,errorResponseCode); + if (errorResponseCode >= 400) + { + handler->onError(getHandle(), msg); + SharedPtr<SipMessage> response = reject(errorResponseCode); + + if (errorResponseCode == 423 && handler->hasMinExpires()) + { + response->header(h_MinExpires).value() = handler->getMinExpires(); + } + send(response); + return; + } + + InviteSessionHandle invSession; + if (getAppDialog().isValid()) + { + invSession = getAppDialog()->getInviteSession(); + } + + if (mExpires == 0) + { + /* This is to handle the case where mExpires is zero because the client + is attempting to poll. In order for polling to work, the subscription + handler needs to get the onNewSubscription call. .mjf. + */ + if (mSubscriptionState == Invalid) + { + mSubscriptionState = Terminated; + if (mEventType != "refer" ) + { + handler->onNewSubscription(getHandle(), msg); + } + else if (!invSession.isValid()) + { + handler->onNewSubscriptionFromRefer(getHandle(), msg); + } + } + + makeNotifyExpires(); + handler->onExpiredByClient(getHandle(), msg, *mLastRequest); + + mDialog.makeResponse(*mLastResponse, mLastSubscribe, 200); + mLastResponse->header(h_Expires).value() = mExpires; + send(mLastResponse); + + send(mLastRequest); // Send Notify Expires + return; + } + if (mSubscriptionState == Invalid) + { + //!dcm! -- should initial state be pending? + mSubscriptionState = Init; + if (mEventType != "refer") + { + DebugLog(<< "onNewSubscription called"); + handler->onNewSubscription(getHandle(), msg); + } + else if (!invSession.isValid()) + { + DebugLog(<< "onNewSubscriptionFromRefer called"); + handler->onNewSubscriptionFromRefer(getHandle(), msg); + } + } + else + { + DebugLog(<< "onRefresh called"); + handler->onRefresh(getHandle(), msg); + } + } + else + { + //.dcm. - will need to change if retry-afters are reaching here + mLastRequest->releaseContents(); + int code = msg.header(h_StatusLine).statusCode(); + if (code < 300) + { + return; + } + else if (code < 400) + { + //in dialog NOTIFY got redirected? Bizarre... + handler->onError(getHandle(), msg); + handler->onTerminated(getHandle()); + delete this; + } + else + { + switch(Helper::determineFailureMessageEffect(msg)) + { + case Helper::TransactionTermination: + DebugLog( << "ServerSubscriptionHandler::TransactionTermination: " << msg.brief()); + handler->onNotifyRejected(getHandle(), msg); + break; + case Helper::UsageTermination: + case Helper::RetryAfter: + case Helper::OptionalRetryAfter: + case Helper::ApplicationDependant: + case Helper::DialogTermination: + DebugLog( << "ServerSubscriptionHandler::UsageTermination: " << msg.brief()); + handler->onError(getHandle(), msg); + handler->onTerminated(getHandle()); + delete this; + break; + } + } + } +} + +void +ServerSubscription::makeNotifyExpires() +{ + mSubscriptionState = Terminated; + makeNotify(); + mLastRequest->header(h_SubscriptionState).param(p_reason) = getTerminateReasonString(Timeout); +} + +void +ServerSubscription::makeNotify() +{ + mDialog.makeRequest(*mLastRequest, NOTIFY); + mLastRequest->header(h_SubscriptionState).value() = getSubscriptionStateString(mSubscriptionState); + if (mSubscriptionState == Terminated) + { + mLastRequest->header(h_SubscriptionState).remove(p_expires); + } + else + { + mLastRequest->header(h_SubscriptionState).param(p_expires) = getTimeLeft(); + } + + mLastRequest->header(h_Event).value() = mEventType; + if (!mSubscriptionId.empty()) + { + mLastRequest->header(h_Event).param(p_id) = mSubscriptionId; + } +} + + +void +ServerSubscription::end(TerminateReason reason, const Contents* document) +{ + mSubscriptionState = Terminated; + makeNotify(); + mLastRequest->header(h_SubscriptionState).param(p_reason) = getTerminateReasonString(reason); + if (document) + { + mLastRequest->setContents(document); + } + send(mLastRequest); +} + +void +ServerSubscription::end() +{ + end(Timeout); +} + +void +ServerSubscription::dispatch(const DumTimeout& timeout) +{ + assert(timeout.type() == DumTimeout::Subscription); + if (timeout.seq() == mTimerSeq) + { + ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); + assert(handler); + makeNotifyExpires(); + handler->onExpired(getHandle(), *mLastRequest); + send(mLastRequest); + } +} + +SharedPtr<SipMessage> +ServerSubscription::update(const Contents* document) +{ + makeNotify(); + mLastRequest->setContents(document); + return mLastRequest; +} + +SharedPtr<SipMessage> +ServerSubscription::neutralNotify() +{ + makeNotify(); + mLastRequest->releaseContents(); + return mLastRequest; +} + +void +ServerSubscription::dialogDestroyed(const SipMessage& msg) +{ + ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); + assert(handler); + handler->onError(getHandle(), msg); + handler->onTerminated(getHandle()); + delete this; +} + +void +ServerSubscription::onReadyToSend(SipMessage& msg) +{ + ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); + assert(handler); + handler->onReadyToSend(getHandle(), msg); +} + +void +ServerSubscription::flowTerminated() +{ + // notify handler + ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); + assert(handler); + handler->onFlowTerminated(getHandle()); +} + +EncodeStream& +ServerSubscription::dump(EncodeStream& strm) const +{ + strm << "ServerSubscription " << mSubscriber; + return strm; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerSubscription.hxx b/src/libs/resiprocate/resip/dum/ServerSubscription.hxx new file mode 100644 index 00000000..a990b06d --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerSubscription.hxx @@ -0,0 +1,131 @@ +#if !defined(RESIP_SERVERSUBSCRIPTION_HXX) +#define RESIP_SERVERSUBSCRIPTION_HXX + +#include "resip/dum/BaseSubscription.hxx" + +namespace resip +{ + +class DialogUsageManager; + +//!dcm! -- no Subscription State expires parameter generation yet. +class ServerSubscription : public BaseSubscription +{ + public: + typedef Handle<ServerSubscription> ServerSubscriptionHandle; + ServerSubscriptionHandle getHandle(); + + const Data& getSubscriber() const { return mSubscriber; } + UInt32 getTimeLeft(); + + //only 200 and 202 are permissable. SubscriptionState is not affected. + //currently must be called for a refresh as well as initial creation. + SharedPtr<SipMessage> accept(int statusCode = 202); + SharedPtr<SipMessage> reject(int responseCode); + + //used to accept a reresh when there is no useful state to convey to the + //client + SharedPtr<SipMessage> neutralNotify(); + + void setSubscriptionState(SubscriptionState state); + + SharedPtr<SipMessage> update(const Contents* document); + void end(TerminateReason reason, const Contents* document = 0); + + virtual void end(); + virtual void send(SharedPtr<SipMessage> msg); + virtual void sendCommand(SharedPtr<SipMessage> msg) + { + BaseSubscription::sendCommand(msg); + } + +// void setTerminationState(TerminateReason reason); +// void setCurrentEventDocument(const Contents* document); + + virtual void dispatch(const SipMessage& msg); + virtual void dispatch(const DumTimeout& timer); + + virtual EncodeStream& dump(EncodeStream& strm) const; + + protected: + virtual ~ServerSubscription(); + virtual void dialogDestroyed(const SipMessage& msg); + void onReadyToSend(SipMessage& msg); + virtual void flowTerminated(); + + private: + friend class Dialog; + + ServerSubscription(DialogUsageManager& dum, Dialog& dialog, const SipMessage& req); + + void makeNotifyExpires(); + void makeNotify(); + + bool shouldDestroyAfterSendingFailure(const SipMessage& msg); + + Data mSubscriber; + +// const Contents* mCurrentEventDocument; + SipMessage mLastSubscribe; + + UInt32 mExpires; + + // disabled + ServerSubscription(const ServerSubscription&); + ServerSubscription& operator=(const ServerSubscription&); + UInt64 mAbsoluteExpiry; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ServerSubscriptionFunctor.hxx b/src/libs/resiprocate/resip/dum/ServerSubscriptionFunctor.hxx new file mode 100644 index 00000000..a364cb4d --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ServerSubscriptionFunctor.hxx @@ -0,0 +1,72 @@ +#if !defined(RESIP_SERVERSUBSCRIPTIONFUNCTOR_HXX) +#define RESIP_SERVERSUBSCRIPTIONFUNCTOR_HXX + +#include "resip/dum/Handles.hxx" + + +namespace resip +{ + +class ServerSubscriptionFunctor +{ + public: + virtual ~ServerSubscriptionFunctor() + { + } + + virtual void apply(ServerSubscriptionHandle) = 0; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/SubscriptionCreator.cxx b/src/libs/resiprocate/resip/dum/SubscriptionCreator.cxx new file mode 100644 index 00000000..1351246a --- /dev/null +++ b/src/libs/resiprocate/resip/dum/SubscriptionCreator.cxx @@ -0,0 +1,108 @@ +#include "SubscriptionCreator.hxx" +#include "DialogUsageManager.hxx" + +using namespace resip; + +SubscriptionCreator::SubscriptionCreator(DialogUsageManager& dum, + const NameAddr& target, + SharedPtr<UserProfile> userProfile, + const Data& event, + UInt32 subscriptionTime) + : BaseCreator(dum, userProfile), + mRefreshInterval(-1) +{ + makeInitialRequest(target, SUBSCRIBE); + + mLastRequest->header(h_Event).value() = event; + mLastRequest->header(h_Expires).value() = subscriptionTime; +} + +SubscriptionCreator::SubscriptionCreator(DialogUsageManager& dum, + const NameAddr& target, + SharedPtr<UserProfile> userProfile, + const Data& event, + UInt32 subscriptionTime, + int refreshInterval) + : BaseCreator(dum, userProfile), + mRefreshInterval(refreshInterval) +{ + makeInitialRequest(target, SUBSCRIBE); + + mLastRequest->header(h_Event).value() = event; + mLastRequest->header(h_Expires).value() = subscriptionTime; +} + +SubscriptionCreator::SubscriptionCreator(DialogUsageManager& dum, + const NameAddr& target, + SharedPtr<UserProfile> userProfile, + const H_ReferTo::Type& referTo) + : BaseCreator(dum, userProfile), + mRefreshInterval(-1) +{ + makeInitialRequest(target, REFER); + mLastRequest->header(h_ReferTo) = referTo; + mLastRequest->header(h_Event).value() = "refer"; +} + +bool +SubscriptionCreator::hasRefreshInterval() const +{ + return mRefreshInterval > 0; +} + +int +SubscriptionCreator::getRefreshInterval() const +{ + return mRefreshInterval; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/SubscriptionCreator.hxx b/src/libs/resiprocate/resip/dum/SubscriptionCreator.hxx new file mode 100644 index 00000000..53c33445 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/SubscriptionCreator.hxx @@ -0,0 +1,81 @@ +#if !defined(RESIP_SUBSCRIPTIONCREATOR_HXX) +#define RESIP_SUBSCRIPTIONCREATOR_HXX + +#include "resip/dum/BaseCreator.hxx" + +namespace resip +{ + +class SubscriptionCreator : public BaseCreator +{ + public: + + //probably want to have things like the Accept list here too + SubscriptionCreator(DialogUsageManager& dum, const NameAddr& target, SharedPtr<UserProfile> userProfile, const Data& event, + UInt32 subscriptionTime); + SubscriptionCreator(DialogUsageManager& dum, const NameAddr& target, SharedPtr<UserProfile> userProfile, const Data& event, + UInt32 subscriptionTime, int refreshInterval); + + // for out of dialog refer + SubscriptionCreator(DialogUsageManager& dum, const NameAddr& target, SharedPtr<UserProfile> userProfile, const H_ReferTo::Type& referTo); + + bool hasRefreshInterval() const; + int getRefreshInterval() const; + private: + int mRefreshInterval; + Data mEvent; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/SubscriptionHandler.cxx b/src/libs/resiprocate/resip/dum/SubscriptionHandler.cxx new file mode 100644 index 00000000..b3ca43f8 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/SubscriptionHandler.cxx @@ -0,0 +1,211 @@ +#include "resip/dum/SubscriptionHandler.hxx" +#include "resip/dum/ServerSubscription.hxx" +#include "resip/dum/ClientSubscription.hxx" +#include "resip/stack/SecurityAttributes.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; + +static Mimes empty; + +void +ClientSubscriptionHandler::onReadyToSend(ClientSubscriptionHandle h, SipMessage& msg) +{ + // default is to do nothing. this is for adornment +} + +void +ClientSubscriptionHandler::onNotifyNotReceived(ClientSubscriptionHandle h) +{ + // By default, tear down the sub. + h->end(); +} + +void +ClientSubscriptionHandler::onFlowTerminated(ClientSubscriptionHandle h) +{ + // re-Subscribe + InfoLog(<< "ClientSubscriptionHandler::onFlowTerminated"); + h->reSubscribe(); +} + +const Mimes& +ServerSubscriptionHandler::getSupportedMimeTypes() const +{ + return empty; +} + +void +ServerSubscriptionHandler::onError(ServerSubscriptionHandle, const SipMessage& msg) +{ +} + +void +ServerSubscriptionHandler::onExpiredByClient(ServerSubscriptionHandle, const SipMessage& sub, SipMessage& notify) +{ +} + +void +ServerSubscriptionHandler::onExpired(ServerSubscriptionHandle, SipMessage& notify) +{ +} + +//!dcm! -- a bit clunky, but really want these objects to not have state +bool +ServerSubscriptionHandler::hasDefaultExpires() const +{ + return false; +} + +UInt32 +ServerSubscriptionHandler::getDefaultExpires() const +{ + return 0; +} + +bool +ServerSubscriptionHandler::hasMinExpires() const +{ + return false; +} + +UInt32 +ServerSubscriptionHandler::getMinExpires() const +{ + return 0; +} +bool +ServerSubscriptionHandler::hasMaxExpires() const +{ + return false; +} + +UInt32 +ServerSubscriptionHandler::getMaxExpires() const +{ + return 0; +} + +void +ServerSubscriptionHandler::getExpires(const SipMessage &msg, UInt32 &expires, int &errorResponseCode) +{ + if (msg.exists(h_Expires)) + { + expires = msg.header(h_Expires).value(); + + if (expires > 0) + { + if (hasMinExpires() && (expires < getMinExpires())) + { + errorResponseCode = 423; + } + else if (hasMaxExpires() && (expires > getMaxExpires())) + { + expires = getMaxExpires(); + } + } + } + else if (hasDefaultExpires()) + { + expires = getDefaultExpires(); + } + else + { + errorResponseCode = 400; + } +} + +void +ServerSubscriptionHandler::onRefresh(ServerSubscriptionHandle handle, const SipMessage& sub) +{ + handle->send(handle->accept(200)); + handle->send(handle->neutralNotify()); +} + +void +ServerSubscriptionHandler::onPublished(ServerSubscriptionHandle associated, + ServerPublicationHandle publication, + const Contents* contents, + const SecurityAttributes* attrs) +{ + // do nothing by default +} + + +void +ServerSubscriptionHandler::onNotifyRejected(ServerSubscriptionHandle h, const SipMessage& msg) +{ +} + +void +ServerSubscriptionHandler::onReadyToSend(ServerSubscriptionHandle h, SipMessage& msg) +{ + // default is to do nothing. this is for adornment +} + +void +ServerSubscriptionHandler::onNewSubscriptionFromRefer(ServerSubscriptionHandle, const SipMessage& sub) +{ +} + +void +ServerSubscriptionHandler::onFlowTerminated(ServerSubscriptionHandle h) +{ + InfoLog(<< "ServerSubscriptionHandler::onFlowTerminated"); + // By default, tear down the sub. + h->end(); +} + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/SubscriptionHandler.hxx b/src/libs/resiprocate/resip/dum/SubscriptionHandler.hxx new file mode 100644 index 00000000..98e31263 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/SubscriptionHandler.hxx @@ -0,0 +1,152 @@ +#if !defined(RESIP_SUBSCRIPTIONHANDLER_HXX) +#define RESIP_SUBSCRIPTIONHANDLER_HXX + +#include "resip/dum/Handles.hxx" +#include "resip/stack/Mime.hxx" +#include "resip/stack/Contents.hxx" + +namespace resip +{ +class SipMessage; +class SecurityAttributes; + +class ClientSubscriptionHandler +{ + public: + virtual ~ClientSubscriptionHandler() { } + + //Client must call acceptUpdate or rejectUpdate for any onUpdateFoo + virtual void onUpdatePending(ClientSubscriptionHandle, const SipMessage& notify, bool outOfOrder)=0; + virtual void onUpdateActive(ClientSubscriptionHandle, const SipMessage& notify, bool outOfOrder)=0; + //unknown Subscription-State value + virtual void onUpdateExtension(ClientSubscriptionHandle, const SipMessage& notify, bool outOfOrder)=0; + + virtual int onRequestRetry(ClientSubscriptionHandle, int retrySeconds, const SipMessage& notify)=0; + + //subscription can be ended through a notify or a failure response. + virtual void onTerminated(ClientSubscriptionHandle, const SipMessage* msg)=0; + //not sure if this has any value. + virtual void onNewSubscription(ClientSubscriptionHandle, const SipMessage& notify)=0; + + /// called to allow app to adorn a message. + virtual void onReadyToSend(ClientSubscriptionHandle, SipMessage& msg); + virtual void onNotifyNotReceived(ClientSubscriptionHandle); + + /// Called when a TCP or TLS flow to the server has terminated. This can be caused by socket + /// errors, or missing CRLF keep alives pong responses from the server. + // Called only if clientOutbound is enabled on the UserProfile and the first hop server + /// supports RFC5626 (outbound). + /// Default implementation is to re-form the subscription using a new flow + virtual void onFlowTerminated(ClientSubscriptionHandle); +}; + +class ServerSubscriptionHandler +{ + public: + virtual ~ServerSubscriptionHandler() {} + + virtual void onNewSubscription(ServerSubscriptionHandle, const SipMessage& sub)=0; + virtual void onNewSubscriptionFromRefer(ServerSubscriptionHandle, const SipMessage& sub); + virtual void onRefresh(ServerSubscriptionHandle, const SipMessage& sub); + virtual void onPublished(ServerSubscriptionHandle associated, + ServerPublicationHandle publication, + const Contents* contents, + const SecurityAttributes* attrs); + + virtual void onNotifyRejected(ServerSubscriptionHandle, const SipMessage& msg); + + //called when this usage is destroyed for any reason. One of the following + //three methods will always be called before this, but this is the only + //method that MUST be implemented by a handler + virtual void onTerminated(ServerSubscriptionHandle)=0; + + virtual void onReadyToSend(ServerSubscriptionHandle, SipMessage& msg); + + //will be called when a NOTIFY is not delivered(with a usage terminating + //statusCode), or the Dialog is destroyed + virtual void onError(ServerSubscriptionHandle, const SipMessage& msg); + + //app can synchronously decorate terminating NOTIFY messages. The only + //graceful termination mechanism is expiration, but the client can + //explicity end a subscription with an Expires header of 0. + virtual void onExpiredByClient(ServerSubscriptionHandle, const SipMessage& sub, SipMessage& notify); + virtual void onExpired(ServerSubscriptionHandle, SipMessage& notify); + + /// Called when a TCP or TLS flow to the server has terminated. This can be caused by socket + /// errors, or missing CRLF keep alives pong responses from the server. + // Called only if clientOutbound is enabled on the UserProfile and the first hop server + /// supports RFC5626 (outbound). + /// Default implementation is to tear down the subscription + virtual void onFlowTerminated(ServerSubscriptionHandle); + + /** Default behavior is to use the expires value in the SipMessage, if it exists. Then verify the expires >= Min and <= Max (if set). If an expires value does + * not exists, use getDefaultExpires(). If hasDefaultExpires() is false, then reject the message with a 400. + * Set errorReturnCode to an error code >= 400 to reject this subscription. + */ + virtual void getExpires(const SipMessage &msg, UInt32 &expires, int &errorResponseCode);//ivr mod + + virtual bool hasDefaultExpires() const; + virtual UInt32 getDefaultExpires() const; + + virtual bool hasMinExpires() const; + virtual UInt32 getMinExpires() const; + + virtual bool hasMaxExpires() const; + virtual UInt32 getMaxExpires() const; + + const Mimes& getSupportedMimeTypes() const; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/SubscriptionPersistenceManager.hxx b/src/libs/resiprocate/resip/dum/SubscriptionPersistenceManager.hxx new file mode 100644 index 00000000..84d63c97 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/SubscriptionPersistenceManager.hxx @@ -0,0 +1,65 @@ +#if !defined(RESIP_SUBSCRIPTIONPERSISTENCEMANAGER_HXX) +#define RESIP_SUBSCRIPTIONPERSISTENCEMANAGER_HXX + +namespace resip +{ + +class SubscriptionPersistenceManager +{ +}; + + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/SubscriptionState.cxx b/src/libs/resiprocate/resip/dum/SubscriptionState.cxx new file mode 100644 index 00000000..20ec7bbf --- /dev/null +++ b/src/libs/resiprocate/resip/dum/SubscriptionState.cxx @@ -0,0 +1,97 @@ +#include "resip/dum/SubscriptionState.hxx" +#include "rutil/Data.hxx" + +using namespace resip; + +Data SubscriptionStates[] = +{ + "invalid", + "init", + "pending", + "active", + "waiting", + "terminated", + "unknown" +}; + +Data TerminateReasons[] = +{ + "deactivated", + "probation", + "rejected", + "timeout", + "giveup", + "noresource", + "invariant", + "unknown" +}; + +const Data& +resip::getSubscriptionStateString(SubscriptionState state) +{ + if (state > Unknown || state < Invalid) + { + state = Unknown; + } + return SubscriptionStates[state]; +} + +const Data& +resip::getTerminateReasonString(TerminateReason state) +{ +// if (state > Unknown || state < Deactivated) +// { +// state = Unknown; +// } + return TerminateReasons[state]; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/SubscriptionState.hxx b/src/libs/resiprocate/resip/dum/SubscriptionState.hxx new file mode 100644 index 00000000..839807dd --- /dev/null +++ b/src/libs/resiprocate/resip/dum/SubscriptionState.hxx @@ -0,0 +1,91 @@ +#ifndef RESIP_SubscriptionState_hxx +#define RESIP_SubscriptionState_hxx + +namespace resip +{ +class Data; + +typedef enum +{ + Invalid=0, + Init, + Pending, + Active, + Waiting, + Terminated, + Unknown +} SubscriptionState; + +typedef enum +{ + //Invalid=0, + Deactivated=0, + Probation, + Rejected, + Timeout, + Giveup, + NoResource, + Invariant +} TerminateReason; + + +const Data& +getSubscriptionStateString(SubscriptionState state); + +const Data& +getTerminateReasonString(TerminateReason state); + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/TargetCommand.cxx b/src/libs/resiprocate/resip/dum/TargetCommand.cxx new file mode 100644 index 00000000..152286f5 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/TargetCommand.cxx @@ -0,0 +1,46 @@ +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/TargetCommand.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + + +TargetCommand::TargetCommand(Target& target, + auto_ptr<Message> message) + : mTarget(target), + mMessage(message) +{ +} + +TargetCommand::TargetCommand(const TargetCommand& from) + : mTarget(from.mTarget), + mMessage(from.mMessage) +{ +} + +void TargetCommand::executeCommand() +{ + mTarget.post(mMessage); +} + +Message* TargetCommand::clone() const +{ + return new TargetCommand(*this); +} + +EncodeStream& +TargetCommand::encode(EncodeStream& strm) const +{ + return strm; +} + +EncodeStream& +TargetCommand::encodeBrief(EncodeStream& strm) const +{ + return strm; +} + +TargetCommand::Target::~Target() +{ +} diff --git a/src/libs/resiprocate/resip/dum/TargetCommand.hxx b/src/libs/resiprocate/resip/dum/TargetCommand.hxx new file mode 100644 index 00000000..e980796a --- /dev/null +++ b/src/libs/resiprocate/resip/dum/TargetCommand.hxx @@ -0,0 +1,44 @@ +#if !defined(RESIP_TARGETCOMMAND_HXX) +#define RESIP_TARGETCOMMAND_HXX + +#include <memory> +#include "resip/dum/DumCommand.hxx" + +namespace resip +{ + +class DialogUsageManager; + +class TargetCommand : public DumCommand +{ + public: + class Target + { + public: + Target(DialogUsageManager& dum) : mDum(dum) + { + } + virtual ~Target()=0; + virtual void post(std::auto_ptr<Message>)=0; + + protected: + DialogUsageManager& mDum; + }; + + TargetCommand(Target& target, std::auto_ptr<Message> message); + TargetCommand(const TargetCommand&); + void executeCommand(); + + + Message* clone() const; + EncodeStream& encode(EncodeStream& strm) const; + EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + Target& mTarget; + mutable std::auto_ptr<Message> mMessage; +}; + +} + +#endif diff --git a/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.cxx b/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.cxx new file mode 100644 index 00000000..6a592284 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.cxx @@ -0,0 +1,231 @@ +#include <cassert> + +#include "resip/dum/DumFeature.hxx" +#include "resip/dum/DumFeatureChain.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/TargetCommand.hxx" +#include "resip/dum/TlsPeerAuthManager.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; +using namespace std; + +TlsPeerAuthManager::TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, std::set<Data>& trustedPeers, bool thirdPartyRequiresCertificate) : + DumFeature(dum, target), + mTrustedPeers(trustedPeers), + mThirdPartyRequiresCertificate(thirdPartyRequiresCertificate) +{ +} + +TlsPeerAuthManager::TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, std::set<Data>& trustedPeers, bool thirdPartyRequiresCertificate, CommonNameMappings& commonNameMappings) : + DumFeature(dum, target), + mTrustedPeers(trustedPeers), + mThirdPartyRequiresCertificate(thirdPartyRequiresCertificate), + mCommonNameMappings(commonNameMappings) +{ +} + +TlsPeerAuthManager::~TlsPeerAuthManager() +{ + InfoLog(<< "~TlsPeerAuthManager"); +} + +// !bwc! We absolutely, positively, MUST NOT throw here. This is because in +// DialogUsageManager::process(), we do not know if a DumFeature has taken +// ownership of msg until we get a return. If we throw, the ownership of msg +// is unknown. This is unacceptable. +DumFeature::ProcessingResult +TlsPeerAuthManager::process(Message* msg) +{ + SipMessage* sipMessage = dynamic_cast<SipMessage*>(msg); + + if (sipMessage) + { + //!dcm! -- unecessary happens in handle + switch ( handle(sipMessage) ) + { + case TlsPeerAuthManager::Rejected: + InfoLog(<< "TlsPeerAuth rejected request " << sipMessage->brief()); + return DumFeature::ChainDoneAndEventDone; + default: // includes Authorized, Skipped + return DumFeature::FeatureDone; + } + } + + // Catch-all (handles something that was not a SipMessage) + return FeatureDone; +} + +bool +TlsPeerAuthManager::authorizedForThisIdentity( + const std::list<resip::Data> &peerNames, + resip::Uri &fromUri) +{ + Data aor = fromUri.getAorNoPort(); + Data domain = fromUri.host(); + + std::list<Data>::const_iterator it = peerNames.begin(); + for(; it != peerNames.end(); ++it) + { + const Data& i = *it; + if(mTrustedPeers.find(i) != mTrustedPeers.end()) + { + DebugLog(<< "Matched certificate name " << i << " is a trusted peer, not checking against From URI"); + return true; + } + if(i == aor) + { + DebugLog(<< "Matched certificate name " << i << " against full AoR " << aor); + return true; + } + if(i == domain) + { + DebugLog(<< "Matched certificate name " << i << " against domain " << domain); + return true; + } + CommonNameMappings::iterator _mapping = + mCommonNameMappings.find(i); + if(_mapping != mCommonNameMappings.end()) + { + DebugLog(<< "CN mapping(s) exist for the certificate " << i); + PermittedFromAddresses& permitted = _mapping->second; + if(permitted.find(aor) != permitted.end()) + { + DebugLog(<< "Matched certificate name " << i << " against full AoR " << aor << " by common name mappings"); + return true; + } + if(permitted.find(domain) != permitted.end()) + { + DebugLog(<< "Matched certificate name " << i << " against domain " << domain << " by common name mappings"); + return true; + } + } + DebugLog(<< "Certificate name " << i << " doesn't match AoR " << aor << " or domain " << domain); + } + + // catch-all: access denied + return false; +} + +// return true if request has been consumed +TlsPeerAuthManager::Result +TlsPeerAuthManager::handle(SipMessage* sipMessage) +{ + //InfoLog( << "trying to do auth" ); + if (!sipMessage->isRequest() || + sipMessage->header(h_RequestLine).method() == ACK || + sipMessage->header(h_RequestLine).method() == CANCEL) + { + // Do not inspect ACKs or CANCELs + return Skipped; + } + + if(!sipMessage->header(h_From).isWellFormed() || + sipMessage->header(h_From).isAllContacts() ) + { + InfoLog(<<"Malformed From header: cannot verify against any certificate. Rejecting."); + SharedPtr<SipMessage> response(new SipMessage); + Helper::makeResponse(*response, *sipMessage, 400, "Malformed From header"); + mDum.send(response); + return Rejected; + } + + // We are only concerned with connections over TLS + if(!sipMessage->isExternal() || sipMessage->getSource().getType() != TLS) + { + DebugLog(<<"Can't validate certificate on non-TLS connection"); + return Skipped; + } + + const std::list<resip::Data> &peerNames = sipMessage->getTlsPeerNames(); + if (mDum.isMyDomain(sipMessage->header(h_From).uri().host())) + { + // peerNames is empty if client certificate mode is `optional' + // or if the message didn't come in on TLS transport + if (requiresAuthorization(*sipMessage) && !peerNames.empty()) + { + if(authorizedForThisIdentity(peerNames, sipMessage->header(h_From).uri())) + return Authorized; + SharedPtr<SipMessage> response(new SipMessage); + Helper::makeResponse(*response, *sipMessage, 403, "Authorization Failed for peer cert"); + mDum.send(response); + return Rejected; + } + else + return Skipped; + } + else + { + // peerNames is empty if client certificate mode is `optional' + // or if the message didn't come in on TLS transport + if(peerNames.empty()) + { + if(mThirdPartyRequiresCertificate) + { + SharedPtr<SipMessage> response(new SipMessage); + Helper::makeResponse(*response, *sipMessage, 403, "Mutual TLS required to handle that message"); + mDum.send(response); + return Rejected; + } + else + return Skipped; + } + if(authorizedForThisIdentity(peerNames, sipMessage->header(h_From).uri())) + return Authorized; + SharedPtr<SipMessage> response(new SipMessage); + Helper::makeResponse(*response, *sipMessage, 403, "Authorization Failed for peer cert"); + mDum.send(response); + return Rejected; + } + + InfoLog(<< "Skipping some message that we didn't explicitly handle"); + return Skipped; +} + +bool +TlsPeerAuthManager::requiresAuthorization(const SipMessage& msg) +{ + // everything must be authorized, over-ride this method + // to implement some other policy + return true; +} + +/* ==================================================================== + * + * Copyright (c) 2012 Daniel Pocock All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.hxx b/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.hxx new file mode 100644 index 00000000..ddb377c3 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.hxx @@ -0,0 +1,92 @@ +#if !defined(RESIP_TLSPEERAUTHMANAGER_HXX) +#define RESIP_TLSPEERAUTHMANAGER_HXX + +#include <map> +#include <set> + +#include "resip/stack/SipMessage.hxx" +#include "DumFeature.hxx" + +namespace resip +{ +class DialogUsageManager; + +typedef std::set<Data> PermittedFromAddresses; +typedef std::map<Data, PermittedFromAddresses> CommonNameMappings; + +class TlsPeerAuthManager : public DumFeature +{ + public: + enum Result + { + Authorized, + Skipped, + Rejected + }; + + TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, std::set<Data>& trustedPeers, bool thirdPartyRequiresCertificate = true); + TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, std::set<Data>& trustedPeers, bool thirdPartyRequiresCertificate, CommonNameMappings& commonNameMappings); + virtual ~TlsPeerAuthManager(); + + virtual ProcessingResult process(Message* msg); + + protected: + + // can return Authorized, Rejected, Skipped + virtual Result handle(SipMessage* sipMsg); + + /// should return true if the passed in user is authorized for the provided uri + virtual bool authorizedForThisIdentity(const std::list<resip::Data> &peerNames, + resip::Uri &fromUri); + + /// should return true if the request must be challenged + /// The default is to challenge all requests - override this class to change this beviour + virtual bool requiresAuthorization(const SipMessage& msg); + + private: + std::set<Data> mTrustedPeers; + CommonNameMappings mCommonNameMappings; + bool mThirdPartyRequiresCertificate; +}; + + +} + +#endif + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2012 Daniel Pocock All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/dum/UsageUseException.hxx b/src/libs/resiprocate/resip/dum/UsageUseException.hxx new file mode 100644 index 00000000..8c47f316 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/UsageUseException.hxx @@ -0,0 +1,69 @@ +#if !defined(RESIP_USAGEUSEEXCEPTION_HXX) +#define RESIP_USAGEUSEEXCEPTION_HXX + +#include "rutil/BaseException.hxx" + +namespace resip +{ + +class UsageUseException : public BaseException +{ + public: + UsageUseException(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) {} + const char* name() const { return "UsageUseException"; } +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/UserAuthInfo.cxx b/src/libs/resiprocate/resip/dum/UserAuthInfo.cxx new file mode 100644 index 00000000..bb448516 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/UserAuthInfo.cxx @@ -0,0 +1,172 @@ + +#include <cassert> + +#include "resip/dum/UserAuthInfo.hxx" +#include "rutil/Data.hxx" +#include "rutil/Logger.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +UserAuthInfo::UserAuthInfo(const Data& user, + const Data& realm, + InfoMode mode, + const Data& transactionId): + DumFeatureMessage(transactionId), + mMode(mode), + mUser(user), + mRealm(realm) +{ +} + +UserAuthInfo::UserAuthInfo(const Data& user, + const Data& realm, + const Data& a1, + const Data& transactionId): + DumFeatureMessage(transactionId), + mMode(RetrievedA1), + mUser(user), + mRealm(realm), + mA1(a1) +{ +} + +UserAuthInfo::UserAuthInfo( const resip::Data& user, + const resip::Data& realm, + const resip::Data& transactionId, + resip::TransactionUser* transactionUser): + DumFeatureMessage(transactionId), + mMode(RetrievedA1), + mUser(user), + mRealm(realm) +{ + mTu = transactionUser; +} + +UserAuthInfo::~UserAuthInfo() +{ +} + +UserAuthInfo::InfoMode +UserAuthInfo::getMode() const +{ + return mMode; +} + +const Data& +UserAuthInfo::getA1() const +{ + return mA1; +} + +const Data& +UserAuthInfo::getRealm() const +{ + return mRealm; +} + +const Data& +UserAuthInfo::getUser() const +{ + return mUser; +} + +void +UserAuthInfo::setMode(InfoMode mode) +{ + mMode = mode; +} + +void +UserAuthInfo::setA1(const resip::Data& a1) +{ + mA1 = a1; +} + +Data +UserAuthInfo::brief() const +{ + Data buffer; + DataStream strm(buffer); + strm << "UserAuthInfo " << mUser << " @ " << mRealm << " A1=" << mA1; + strm.flush(); + return buffer; +} + +resip::Message* +UserAuthInfo::clone() const +{ + assert(false); return NULL; +} + +EncodeStream& +UserAuthInfo::encode(EncodeStream& strm) const +{ + strm << brief(); + return strm; +} + +EncodeStream& +UserAuthInfo::encodeBrief(EncodeStream& strm) const +{ + return encode(strm); +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const UserAuthInfo& msg) +{ + return msg.encode(strm); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/UserAuthInfo.hxx b/src/libs/resiprocate/resip/dum/UserAuthInfo.hxx new file mode 100644 index 00000000..3afb9110 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/UserAuthInfo.hxx @@ -0,0 +1,117 @@ +#if !defined(RESIP_USER_AUTH_INFO_HXX) +#define RESIP_USER_AUTH_INFO_HXX + +#include "rutil/Data.hxx" +#include "resip/dum/DumFeatureMessage.hxx" + +namespace resip +{ + +class UserAuthInfo : public resip::DumFeatureMessage +{ + public: + + enum InfoMode + { + UserUnknown, // the user/realm is not known + RetrievedA1, // the A1 string has been retrieved + Stale, // the nonce is stale, challenge again + DigestAccepted, // the digest was accepted, no A1 returned + DigestNotAccepted, // the digest was wrong, challenge again/deny + Error // some error occurred + }; + + UserAuthInfo( const resip::Data& user, + const resip::Data& realm, + InfoMode mode, + const resip::Data& transactionId); + + UserAuthInfo( const resip::Data& user, + const resip::Data& realm, + const resip::Data& a1, + const resip::Data& transactionId); + + UserAuthInfo( const resip::Data& user, + const resip::Data& realm, + const resip::Data& transactionId, + resip::TransactionUser* transactionUser); + ~UserAuthInfo(); + + InfoMode getMode() const; + + // returns a blank Data("") if (mode != RetrievedA1) + const resip::Data& getA1() const; + const resip::Data& getRealm() const; + const resip::Data& getUser() const; + + void setMode(InfoMode mode); + void setA1(const resip::Data& a1); + + virtual resip::Data brief() const; + virtual resip::Message* clone() const; + + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + InfoMode mMode; + resip::Data mUser; + resip::Data mRealm; + resip::Data mA1; +}; + +EncodeStream& +operator<<(EncodeStream& strm, const UserAuthInfo& msg); + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/UserProfile.cxx b/src/libs/resiprocate/resip/dum/UserProfile.cxx new file mode 100644 index 00000000..c20a9cf1 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/UserProfile.cxx @@ -0,0 +1,262 @@ + +#include "resip/dum/Profile.hxx" +#include "resip/dum/UserProfile.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/MD5Stream.hxx" + +using namespace resip; +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +const resip::NameAddr UserProfile::mAnonymous("\"Anonymous\" <sip:anonymous@anonymous.invalid>", true /* preCacheAor */); + +UserProfile::UserProfile() : Profile(), + mGruuEnabled(false), + mRegId(0), + mClientOutboundEnabled(false) +{ + //InfoLog (<< "************ UserProfile created (no base)!: " << *this); +} + +UserProfile::UserProfile(SharedPtr<Profile> baseProfile) : Profile(baseProfile), + mGruuEnabled(false), + mRegId(0), + mClientOutboundEnabled(false) +{ + //InfoLog (<< "************ UserProfile created (with base)!: " << *this); +} + +UserProfile::~UserProfile() +{ + //InfoLog (<< "************ UserProfile destroyed!: " << *this); +} + +SharedPtr<UserProfile> +UserProfile::getAnonymousUserProfile() const +{ + SharedPtr<UserProfile> anon(this->clone()); + anon->setDefaultFrom(mAnonymous); + return anon; +} + +UserProfile* +UserProfile::clone() const +{ + return new UserProfile(*this); +} + +bool +UserProfile::isAnonymous() const +{ + return (mDefaultFrom.uri().getAor() == mAnonymous.uri().getAor()); +} + +void +UserProfile::setDefaultFrom(const NameAddr& from) +{ + mDefaultFrom = from; +} + +NameAddr& +UserProfile::getDefaultFrom() +{ + return mDefaultFrom; +} + +void +UserProfile::setServiceRoute(const NameAddrs& sRoute) +{ + mServiceRoute = sRoute; +} + +NameAddrs& +UserProfile::getServiceRoute() +{ + return mServiceRoute; +} + +bool +UserProfile::hasInstanceId() +{ + return !mInstanceId.empty(); +} + +void +UserProfile::setInstanceId(const Data& id) +{ + mInstanceId = id; +} + +const Data& +UserProfile::getInstanceId() const +{ + return mInstanceId; +} + +void +UserProfile::addGruu(const Data& aor, const NameAddr& contact) +{ +} + +bool +UserProfile::hasGruu(const Data& aor) const +{ + return false; +} + +bool +UserProfile::hasGruu(const Data& aor, const Data& instance) const +{ + return false; +} + +NameAddr& +UserProfile:: getGruu(const Data& aor) +{ + assert(0); + static NameAddr gruu; + return gruu; +} + +NameAddr& +UserProfile:: getGruu(const Data& aor, const NameAddr& contact) +{ + assert(0); + static NameAddr gruu; + return gruu; +} + +void +UserProfile::clearDigestCredentials() +{ + mDigestCredentials.clear(); +} + +void +UserProfile::setDigestCredential( const Data& realm, const Data& user, const Data& password, bool isPasswordA1Hash) +{ + DigestCredential cred(realm, user, password, isPasswordA1Hash); + + DebugLog (<< "Adding credential: " << cred); + mDigestCredentials.erase(cred); + mDigestCredentials.insert(cred); +} + +static const UserProfile::DigestCredential emptyDigestCredential; +const UserProfile::DigestCredential& +UserProfile::getDigestCredential( const Data& realm ) +{ + if(mDigestCredentials.empty()) + { + // !jf! why not just throw here? + return emptyDigestCredential; + } + + DigestCredentials::const_iterator it = mDigestCredentials.find(DigestCredential(realm)); + if (it == mDigestCredentials.end()) + { + DebugLog(<< "Didn't find credential for realm: " << realm << " " << *mDigestCredentials.begin()); + return *mDigestCredentials.begin(); + } + else + { + DebugLog(<< "Found credential for realm: " << *it << realm); + return *it; + } +} + +UserProfile::DigestCredential::DigestCredential(const Data& r, const Data& u, const Data& pwd, bool pwdA1Hash) : + realm(r), + user(u), + password(pwd), + isPasswordA1Hash(pwdA1Hash) +{ +} + +UserProfile::DigestCredential::DigestCredential() : + realm(Data::Empty), + user(Data::Empty), + password(Data::Empty), + isPasswordA1Hash(false) +{ +} + +UserProfile::DigestCredential::DigestCredential(const Data& pRealm) : + realm(pRealm), + user(Data::Empty), + password(Data::Empty), + isPasswordA1Hash(false) +{ +} + +bool +UserProfile::DigestCredential::operator<(const DigestCredential& rhs) const +{ + return realm < rhs.realm; +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const UserProfile& profile) +{ + strm << "UserProfile: " << profile.mDefaultFrom << Inserter(profile.mDigestCredentials); + return strm; +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const UserProfile::DigestCredential& cred) +{ + strm << "realm=" << cred.realm << " user=" << cred.user ; + return strm; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/UserProfile.hxx b/src/libs/resiprocate/resip/dum/UserProfile.hxx new file mode 100644 index 00000000..622d5143 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/UserProfile.hxx @@ -0,0 +1,201 @@ +#if !defined(RESIP_USERPROFILE_HXX) +#define RESIP_USERPROFILE_HXX + +#include <iosfwd> +#include <set> +#include "resip/stack/Headers.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "resip/stack/Tuple.hxx" +#include "resip/dum/Profile.hxx" + +namespace resip +{ + +class Data; + +class UserProfile : public Profile +{ + public: + UserProfile(); + UserProfile(SharedPtr<Profile> baseProfile); + virtual ~UserProfile(); + + virtual void setDefaultFrom(const NameAddr& from); + virtual NameAddr& getDefaultFrom(); + + virtual void setServiceRoute(const NameAddrs& sRoute); + virtual NameAddrs& getServiceRoute(); + + virtual void setImsAuthUser(const Data& userName, const Data& host) { mImsAuthUserName = userName; mImsAuthHost = host; } + virtual Data& getImsAuthUserName() { return mImsAuthUserName; } + virtual Data& getImsAuthHost() { return mImsAuthHost; } + + // Returns a UserProfile that will return a UserProfile that can be used + // to send requests according to RFC 3323 and RFC 3325 + virtual SharedPtr<UserProfile> getAnonymousUserProfile() const; + bool isAnonymous() const; + + // !cj! - this GRUU stuff looks very suspect + // !dcm! -- yep, I don't think you can adda gruu..and disabling is weird. + //Anon should be on a per-call level...all of these will prob. go away. + //.dcm. anonymous gruu's will be used by making annon userprofile where + //one is avail. Up to the ap to keep the req'd reg up. + //1 gruu per userprofile for now. + virtual void addGruu(const Data& aor, const NameAddr& contact); + virtual bool hasGruu(const Data& aor) const; + virtual bool hasGruu(const Data& aor, const Data& instance) const; + virtual NameAddr& getGruu(const Data& aor); + virtual NameAddr& getGruu(const Data& aor, const NameAddr& contact); + + //should do Supported wrangling--but what if required is desired? Same as 100rel? + virtual bool& gruuEnabled() { return mGruuEnabled; } + virtual bool gruuEnabled() const { return mGruuEnabled; } + + virtual bool hasPublicGruu() const { return !mPubGruu.host().empty(); } + virtual const Uri& getPublicGruu() { return mPubGruu; } + virtual void setPublicGruu(const Uri& gruu) { mPubGruu = gruu; } + + virtual bool hasTempGruu() const { return !mTempGruu.host().empty(); } + virtual const Uri& getTempGruu() { return mTempGruu; } + virtual void setTempGruu(const Uri& gruu) { mTempGruu = gruu; } + + struct DigestCredential + { + DigestCredential(); + DigestCredential(const Data& realm, + const Data& username, + const Data& pwd, + bool isPasswordA1Hash); + DigestCredential(const Data& realm); + + Data realm; + Data user; + Data password; + bool isPasswordA1Hash; + + bool operator<(const DigestCredential& rhs) const; + }; + + /// The following functions deal with clearing, setting and getting of digest credentals + virtual void clearDigestCredentials(); + /// For the password you may either provide the plain text password (isPasswordA1Hash = false) + /// or the Digest A1 MD5 Hash (isPasswordA1Hash = true). Note: If the A1 hash is provided + /// then the realm MUST match the realm in the challenge or authentication will fail. If the + /// plain text password is provided, then we will form the A1 hash using the realm from + /// the challenge. + virtual void setDigestCredential( const Data& realm, + const Data& user, + const Data& password, + bool isPasswordA1Hash=false); + virtual const DigestCredential& getDigestCredential( const Data& realm ); + + // Enable this to enable RFC5626 support in DUM - adds regId to registrations, and + // ;ob parameter to Path, Route, and Contact headers + // Warning: You MUST set an instanceId, a regId and an outbound proxy if you enable + // clientOutbound support. You MUST also ensure that you add the following Supported + // options: + // profile->addSupportedOptionTag(Token(Symbols::Outbound)); // RFC 5626 - outbound + // profile->addSupportedOptionTag(Token(Symbols::Path)); // RFC 3327 - path + virtual bool& clientOutboundEnabled() { return mClientOutboundEnabled; } + virtual bool clientOutboundEnabled() const { return mClientOutboundEnabled; } + + // Outbound (RFC5626) instanceId used in contact headers + virtual bool hasInstanceId(); + virtual void setInstanceId(const Data& id); + virtual const Data& getInstanceId() const; + + // Outbound (RFC5626) regId used in registrations + virtual void setRegId(int regId) { mRegId = regId; } + virtual int getRegId() { return mRegId; } + + // Returns the current Flow Tuple that is being used for communication on usages + // that use this profile + const Tuple& getClientOutboundFlowTuple() const { return mClientOutboundFlowTuple; } + void clearClientOutboundFlowTuple() { mClientOutboundFlowTuple = Tuple(); } + + protected: + virtual UserProfile* clone() const; + + private: + NameAddr mDefaultFrom; + Data mInstanceId; + NameAddrs mServiceRoute; + Data mImsAuthUserName; + Data mImsAuthHost; + bool mGruuEnabled; + Uri mPubGruu; + Uri mTempGruu; + const static NameAddr mAnonymous; + + int mRegId; + bool mClientOutboundEnabled; + friend class DialogUsageManager; // Give DialogUsageManager, ClientRegistration, and Dialog access to mClientOutboundFlowKey + friend class ClientRegistration; + friend class Dialog; + Tuple mClientOutboundFlowTuple; + + typedef std::set<DigestCredential> DigestCredentials; + DigestCredentials mDigestCredentials; + + friend EncodeStream& operator<<(EncodeStream&, const UserProfile& profile); +}; + +EncodeStream& +operator<<(EncodeStream&, const UserProfile& profile); + +EncodeStream& +operator<<(EncodeStream&, const UserProfile::DigestCredential& cred); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/dum.pro b/src/libs/resiprocate/resip/dum/dum.pro new file mode 100644 index 00000000..e26d8a51 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/dum.pro @@ -0,0 +1,206 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2010-11-29T22:23:29 +# +#------------------------------------------------- + +QT -= core gui + +TARGET = dum +TEMPLATE = lib +CONFIG += staticlib +INCLUDEPATH += ../../ +DEFINES += USE_IPV6 WINVER=0x0501 + +win32 { + DESTDIR = ../../../../Libs/compiled/win/ +} + +SOURCES += \ + UserProfile.cxx \ + UserAuthInfo.cxx \ + TargetCommand.cxx \ + SubscriptionState.cxx \ + SubscriptionHandler.cxx \ + SubscriptionCreator.cxx \ + ServerSubscription.cxx \ + ServerRegistration.cxx \ + ServerPublication.cxx \ + ServerPagerMessage.cxx \ + ServerOutOfDialogReq.cxx \ + ServerInviteSession.cxx \ + ServerAuthManager.cxx \ + RegistrationHandler.cxx \ + RegistrationCreator.cxx \ + RedirectManager.cxx \ + RADIUSServerAuthManager.cxx \ + PublicationCreator.cxx \ + Profile.cxx \ + PagerMessageCreator.cxx \ + OutOfDialogReqCreator.cxx \ + OutgoingEvent.cxx \ + NonDialogUsage.cxx \ + NetworkAssociation.cxx \ + MergedRequestRemovalCommand.cxx \ + MergedRequestKey.cxx \ + MasterProfile.cxx \ + KeepAliveTimeout.cxx \ + KeepAliveManager.cxx \ + InviteSessionHandler.cxx \ + InviteSessionCreator.cxx \ + InviteSession.cxx \ + InMemoryRegistrationDatabase.cxx \ + IdentityHandler.cxx \ + HttpProvider.cxx \ + HttpGetMessage.cxx \ + HandleManager.cxx \ + HandleException.cxx \ + Handled.cxx \ + Handle.cxx \ + EncryptionRequest.cxx \ + DumTimeout.cxx \ + DumThread.cxx \ + DumProcessHandler.cxx \ + DumHelper.cxx \ + DumFeatureMessage.cxx \ + DumFeatureChain.cxx \ + DumFeature.cxx \ + DumDecrypted.cxx \ + DialogUsageManager.cxx \ + DialogUsage.cxx \ + DialogSetId.cxx \ + DialogSet.cxx \ + DialogId.cxx \ + DialogEventStateManager.cxx \ + DialogEventInfo.cxx \ + Dialog.cxx \ + DestroyUsage.cxx \ + DefaultServerReferHandler.cxx \ + ContactInstanceRecord.cxx \ + ClientSubscription.cxx \ + ClientRegistration.cxx \ + ClientPublication.cxx \ + ClientPagerMessage.cxx \ + ClientOutOfDialogReq.cxx \ + ClientInviteSession.cxx \ + ClientAuthManager.cxx \ + ClientAuthExtension.cxx \ + ChallengeInfo.cxx \ + CertMessage.cxx \ + BaseUsage.cxx \ + BaseSubscription.cxx \ + BaseCreator.cxx \ + AppDialogSetFactory.cxx \ + AppDialogSet.cxx \ + AppDialog.cxx + +HEADERS += \ + UserProfile.hxx \ + UserAuthInfo.hxx \ + UsageUseException.hxx \ + TargetCommand.hxx \ + SubscriptionState.hxx \ + SubscriptionPersistenceManager.hxx \ + SubscriptionHandler.hxx \ + SubscriptionCreator.hxx \ + ServerSubscriptionFunctor.hxx \ + ServerSubscription.hxx \ + ServerRegistration.hxx \ + ServerPublication.hxx \ + ServerPagerMessage.hxx \ + ServerOutOfDialogReq.hxx \ + ServerInviteSession.hxx \ + ServerAuthManager.hxx \ + RemoteCertStore.hxx \ + RegistrationPersistenceManager.hxx \ + RegistrationHandler.hxx \ + RegistrationCreator.hxx \ + RefCountedDestroyer.hxx \ + RedirectManager.hxx \ + RedirectHandler.hxx \ + RADIUSServerAuthManager.hxx \ + PublicationHandler.hxx \ + PublicationCreator.hxx \ + Profile.hxx \ + Postable.hxx \ + PagerMessageHandler.hxx \ + PagerMessageCreator.hxx \ + OutOfDialogReqCreator.hxx \ + OutOfDialogHandler.hxx \ + OutgoingEvent.hxx \ + NonDialogUsage.hxx \ + NetworkAssociation.hxx \ + MergedRequestRemovalCommand.hxx \ + MergedRequestKey.hxx \ + MasterProfile.hxx \ + KeepAliveTimeout.hxx \ + KeepAliveManager.hxx \ + InviteSessionHandler.hxx \ + InviteSessionCreator.hxx \ + InviteSession.hxx \ + InviteDialogs.hxx \ + InMemoryRegistrationDatabase.hxx \ + IdentityHandler.hxx \ + HttpProvider.hxx \ + HttpGetMessage.hxx \ + Handles.hxx \ + HandleManager.hxx \ + HandleException.hxx \ + Handled.hxx \ + Handle.hxx \ + ExternalTimer.hxx \ + ExternalMessageHandler.hxx \ + ExternalMessageBase.hxx \ + EventDispatcher.hxx \ + EncryptionRequest.hxx \ + DumTimeout.hxx \ + DumThread.hxx \ + DumShutdownHandler.hxx \ + DumProcessHandler.hxx \ + DumHelper.hxx \ + DumFeatureMessage.hxx \ + DumFeatureChain.hxx \ + DumFeature.hxx \ + DumException.hxx \ + DumDecrypted.hxx \ + DumCommand.hxx \ + DialogUsageManager.hxx \ + DialogUsage.hxx \ + DialogSetId.hxx \ + DialogSetHandler.hxx \ + DialogSet.hxx \ + DialogId.hxx \ + DialogEventStateManager.hxx \ + DialogEventInfo.hxx \ + DialogEventHandler.hxx \ + Dialog.hxx \ + DestroyUsage.hxx \ + DefaultServerReferHandler.hxx \ + ContactInstanceRecord.hxx \ + ClientSubscriptionFunctor.hxx \ + ClientSubscription.hxx \ + ClientRegistration.hxx \ + ClientPublication.hxx \ + ClientPagerMessage.hxx \ + ClientOutOfDialogReq.hxx \ + ClientInviteSession.hxx \ + ClientAuthManager.hxx \ + ClientAuthExtension.hxx \ + ChallengeInfo.hxx \ + CertMessage.hxx \ + BaseUsage.hxx \ + BaseSubscription.hxx \ + BaseCreator.hxx \ + AppDialogSetFactory.hxx \ + AppDialogSet.hxx \ + AppDialog.hxx +unix:!symbian { + maemo5 { + target.path = /opt/usr/lib + } else { + target.path = /usr/local/lib + } + INSTALLS += target +} + +OTHER_FILES += diff --git a/src/libs/resiprocate/resip/dum/dum_10_0.vcxproj b/src/libs/resiprocate/resip/dum/dum_10_0.vcxproj new file mode 100644 index 00000000..43897b8d --- /dev/null +++ b/src/libs/resiprocate/resip/dum/dum_10_0.vcxproj @@ -0,0 +1,494 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|Win32"> + <Configuration>SSL-Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|x64"> + <Configuration>SSL-Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|Win32"> + <Configuration>SSL-Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|x64"> + <Configuration>SSL-Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>dum</ProjectName> + <ProjectGuid>{31B0654F-E08E-405F-909F-80F86CB14B9D}</ProjectGuid> + <RootNamespace>dum</RootNamespace> + <Keyword>ManagedCProj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">$(Configuration)\</IntDir> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks> + </BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks> + </BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;USE_ARES;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;USE_ARES;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks> + </BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks> + </BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <Reference Include="mscorlib"> + <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + </Reference> + <Reference Include="System"> + <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + </Reference> + <Reference Include="System.Data"> + <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + </Reference> + </ItemGroup> + <ItemGroup> + <ClCompile Include="AppDialog.cxx" /> + <ClCompile Include="AppDialogSet.cxx" /> + <ClCompile Include="AppDialogSetFactory.cxx" /> + <ClCompile Include="BaseCreator.cxx" /> + <ClCompile Include="BaseSubscription.cxx" /> + <ClCompile Include="BaseUsage.cxx" /> + <ClCompile Include="CertMessage.cxx" /> + <ClCompile Include="ChallengeInfo.cxx" /> + <ClCompile Include="ClientAuthExtension.cxx" /> + <ClCompile Include="ClientAuthManager.cxx" /> + <ClCompile Include="ClientInviteSession.cxx" /> + <ClCompile Include="ClientOutOfDialogReq.cxx" /> + <ClCompile Include="ClientPagerMessage.cxx" /> + <ClCompile Include="ClientPublication.cxx" /> + <ClCompile Include="ClientRegistration.cxx" /> + <ClCompile Include="ClientSubscription.cxx" /> + <ClCompile Include="ContactInstanceRecord.cxx" /> + <ClCompile Include="DefaultServerReferHandler.cxx" /> + <ClCompile Include="DestroyUsage.cxx" /> + <ClCompile Include="Dialog.cxx" /> + <ClCompile Include="DialogEventInfo.cxx" /> + <ClCompile Include="DialogEventStateManager.cxx" /> + <ClCompile Include="DialogId.cxx" /> + <ClCompile Include="DialogSet.cxx" /> + <ClCompile Include="DialogSetId.cxx" /> + <ClCompile Include="DialogUsage.cxx" /> + <ClCompile Include="DialogUsageManager.cxx" /> + <ClCompile Include="DumDecrypted.cxx" /> + <ClCompile Include="DumFeature.cxx" /> + <ClCompile Include="DumFeatureChain.cxx" /> + <ClCompile Include="DumFeatureMessage.cxx" /> + <ClCompile Include="DumHelper.cxx" /> + <ClCompile Include="DumProcessHandler.cxx" /> + <ClCompile Include="DumThread.cxx" /> + <ClCompile Include="DumTimeout.cxx" /> + <ClCompile Include="ssl\EncryptionManager.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="EncryptionRequest.cxx" /> + <ClCompile Include="Handle.cxx" /> + <ClCompile Include="Handled.cxx" /> + <ClCompile Include="HandleException.cxx" /> + <ClCompile Include="HandleManager.cxx" /> + <ClCompile Include="HttpGetMessage.cxx" /> + <ClCompile Include="HttpProvider.cxx" /> + <ClCompile Include="IdentityHandler.cxx" /> + <ClCompile Include="InMemoryRegistrationDatabase.cxx" /> + <ClCompile Include="InMemorySyncRegDb.cxx" /> + <ClCompile Include="InviteSession.cxx" /> + <ClCompile Include="InviteSessionCreator.cxx" /> + <ClCompile Include="InviteSessionHandler.cxx" /> + <ClCompile Include="KeepAliveManager.cxx" /> + <ClCompile Include="KeepAliveTimeout.cxx" /> + <ClCompile Include="MasterProfile.cxx" /> + <ClCompile Include="MergedRequestKey.cxx" /> + <ClCompile Include="MergedRequestRemovalCommand.cxx" /> + <ClCompile Include="NetworkAssociation.cxx" /> + <ClCompile Include="NonDialogUsage.cxx" /> + <ClCompile Include="OutgoingEvent.cxx" /> + <ClCompile Include="OutOfDialogReqCreator.cxx" /> + <ClCompile Include="PagerMessageCreator.cxx" /> + <ClCompile Include="Profile.cxx" /> + <ClCompile Include="PublicationCreator.cxx" /> + <ClCompile Include="RedirectManager.cxx" /> + <ClCompile Include="RegistrationCreator.cxx" /> + <ClCompile Include="RegistrationHandler.cxx" /> + <ClCompile Include="ServerAuthManager.cxx" /> + <ClCompile Include="ServerInviteSession.cxx" /> + <ClCompile Include="ServerOutOfDialogReq.cxx" /> + <ClCompile Include="ServerPagerMessage.cxx" /> + <ClCompile Include="ServerPublication.cxx" /> + <ClCompile Include="ServerRegistration.cxx" /> + <ClCompile Include="ServerSubscription.cxx" /> + <ClCompile Include="SubscriptionCreator.cxx" /> + <ClCompile Include="SubscriptionHandler.cxx" /> + <ClCompile Include="SubscriptionState.cxx" /> + <ClCompile Include="TargetCommand.cxx" /> + <ClCompile Include="TlsPeerAuthManager.cxx" /> + <ClCompile Include="UserAuthInfo.cxx" /> + <ClCompile Include="UserProfile.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="AppDialog.hxx" /> + <ClInclude Include="AppDialogSet.hxx" /> + <ClInclude Include="AppDialogSetFactory.hxx" /> + <ClInclude Include="BaseCreator.hxx" /> + <ClInclude Include="BaseSubscription.hxx" /> + <ClInclude Include="BaseUsage.hxx" /> + <ClInclude Include="CertMessage.hxx" /> + <ClInclude Include="ChallengeInfo.hxx" /> + <ClInclude Include="ClientAuthExtension.hxx" /> + <ClInclude Include="ClientAuthManager.hxx" /> + <ClInclude Include="ClientInviteSession.hxx" /> + <ClInclude Include="ClientOutOfDialogReq.hxx" /> + <ClInclude Include="ClientPagerMessage.hxx" /> + <ClInclude Include="ClientPublication.hxx" /> + <ClInclude Include="ClientRegistration.hxx" /> + <ClInclude Include="ClientSubscription.hxx" /> + <ClInclude Include="ContactInstanceRecord.hxx" /> + <ClInclude Include="DefaultServerReferHandler.hxx" /> + <ClInclude Include="DestroyUsage.hxx" /> + <ClInclude Include="Dialog.hxx" /> + <ClInclude Include="DialogEventHandler.hxx" /> + <ClInclude Include="DialogEventInfo.hxx" /> + <ClInclude Include="DialogEventStateManager.hxx" /> + <ClInclude Include="DialogId.hxx" /> + <ClInclude Include="DialogSet.hxx" /> + <ClInclude Include="DialogSetHandler.hxx" /> + <ClInclude Include="DialogSetId.hxx" /> + <ClInclude Include="DialogUsage.hxx" /> + <ClInclude Include="DialogUsageManager.hxx" /> + <ClInclude Include="DumCommand.hxx" /> + <ClInclude Include="DumDecrypted.hxx" /> + <ClInclude Include="DumException.hxx" /> + <ClInclude Include="DumFeature.hxx" /> + <ClInclude Include="DumFeatureChain.hxx" /> + <ClInclude Include="DumFeatureMessage.hxx" /> + <ClInclude Include="DumHelper.hxx" /> + <ClInclude Include="DumProcessHandler.hxx" /> + <ClInclude Include="DumShutdownHandler.hxx" /> + <ClInclude Include="DumThread.hxx" /> + <ClInclude Include="DumTimeout.hxx" /> + <ClInclude Include="ssl\EncryptionManager.hxx" /> + <ClInclude Include="EncryptionRequest.hxx" /> + <ClInclude Include="EventDispatcher.hxx" /> + <ClInclude Include="ExternalTimer.hxx" /> + <ClInclude Include="Handle.hxx" /> + <ClInclude Include="Handled.hxx" /> + <ClInclude Include="HandleException.hxx" /> + <ClInclude Include="HandleManager.hxx" /> + <ClInclude Include="Handles.hxx" /> + <ClInclude Include="HttpGetMessage.hxx" /> + <ClInclude Include="HttpProvider.hxx" /> + <ClInclude Include="IdentityHandler.hxx" /> + <ClInclude Include="InMemoryRegistrationDatabase.hxx" /> + <ClInclude Include="InMemorySyncRegDb.hxx" /> + <ClInclude Include="InviteSession.hxx" /> + <ClInclude Include="InviteSessionCreator.hxx" /> + <ClInclude Include="InviteSessionHandler.hxx" /> + <ClInclude Include="KeepAliveManager.hxx" /> + <ClInclude Include="KeepAliveTimeout.hxx" /> + <ClInclude Include="MasterProfile.hxx" /> + <ClInclude Include="MergedRequestKey.hxx" /> + <ClInclude Include="MergedRequestRemovalCommand.hxx" /> + <ClInclude Include="NetworkAssociation.hxx" /> + <ClInclude Include="NonDialogUsage.hxx" /> + <ClInclude Include="OutgoingEvent.hxx" /> + <ClInclude Include="OutOfDialogHandler.hxx" /> + <ClInclude Include="OutOfDialogReqCreator.hxx" /> + <ClInclude Include="PagerMessageCreator.hxx" /> + <ClInclude Include="PagerMessageHandler.hxx" /> + <ClInclude Include="Postable.hxx" /> + <ClInclude Include="Profile.hxx" /> + <ClInclude Include="PublicationCreator.hxx" /> + <ClInclude Include="PublicationHandler.hxx" /> + <ClInclude Include="RedirectHandler.hxx" /> + <ClInclude Include="RedirectManager.hxx" /> + <ClInclude Include="RefCountedDestroyer.hxx" /> + <ClInclude Include="RegistrationCreator.hxx" /> + <ClInclude Include="RegistrationHandler.hxx" /> + <ClInclude Include="RegistrationPersistenceManager.hxx" /> + <ClInclude Include="RemoteCertStore.hxx" /> + <ClInclude Include="RequestValidationHandler.hxx" /> + <ClInclude Include="ServerAuthManager.hxx" /> + <ClInclude Include="ServerInviteSession.hxx" /> + <ClInclude Include="ServerOutOfDialogReq.hxx" /> + <ClInclude Include="ServerPagerMessage.hxx" /> + <ClInclude Include="ServerPublication.hxx" /> + <ClInclude Include="ServerRegistration.hxx" /> + <ClInclude Include="ServerSubscription.hxx" /> + <ClInclude Include="SubscriptionCreator.hxx" /> + <ClInclude Include="SubscriptionHandler.hxx" /> + <ClInclude Include="SubscriptionPersistenceManager.hxx" /> + <ClInclude Include="SubscriptionState.hxx" /> + <ClInclude Include="TargetCommand.hxx" /> + <ClInclude Include="TlsPeerAuthManager.hxx" /> + <ClInclude Include="UsageUseException.hxx" /> + <ClInclude Include="UserAuthInfo.hxx" /> + <ClInclude Include="UserProfile.hxx" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\stack\resiprocate_10_0.vcxproj"> + <Project>{2a8be839-6466-4001-b224-8f1c3168d04a}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/dum/dum_10_0.vcxproj.filters b/src/libs/resiprocate/resip/dum/dum_10_0.vcxproj.filters new file mode 100644 index 00000000..d6ad4579 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/dum_10_0.vcxproj.filters @@ -0,0 +1,546 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="AppDialog.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="AppDialogSet.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="AppDialogSetFactory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BaseCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BaseSubscription.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BaseUsage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="CertMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ChallengeInfo.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientAuthExtension.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientAuthManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientInviteSession.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientOutOfDialogReq.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientPagerMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientPublication.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientRegistration.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientSubscription.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ContactInstanceRecord.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DefaultServerReferHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DestroyUsage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Dialog.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogEventInfo.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogEventStateManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogId.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogSet.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogSetId.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogUsage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogUsageManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumDecrypted.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumFeature.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumFeatureChain.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumFeatureMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumHelper.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumProcessHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumTimeout.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="EncryptionRequest.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Handle.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Handled.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HandleException.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HandleManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HttpGetMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HttpProvider.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="IdentityHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InMemoryRegistrationDatabase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InMemorySyncRegDb.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InviteSession.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InviteSessionCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InviteSessionHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="KeepAliveManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="KeepAliveTimeout.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MasterProfile.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MergedRequestKey.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MergedRequestRemovalCommand.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="NetworkAssociation.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="NonDialogUsage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="OutgoingEvent.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="OutOfDialogReqCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="PagerMessageCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Profile.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="PublicationCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RedirectManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RegistrationCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RegistrationHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerAuthManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerInviteSession.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerOutOfDialogReq.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerPagerMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerPublication.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerRegistration.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerSubscription.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\EncryptionManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SubscriptionCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SubscriptionHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SubscriptionState.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TargetCommand.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UserAuthInfo.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UserProfile.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TlsPeerAuthManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="AppDialog.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AppDialogSet.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AppDialogSetFactory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BaseCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BaseSubscription.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BaseUsage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CertMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ChallengeInfo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientAuthExtension.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientAuthManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientInviteSession.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientOutOfDialogReq.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientPagerMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientPublication.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientRegistration.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientSubscription.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ContactInstanceRecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DefaultServerReferHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DestroyUsage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Dialog.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogEventHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogEventInfo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogEventStateManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogId.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogSet.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogSetHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogSetId.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogUsage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogUsageManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumCommand.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumDecrypted.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumException.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumFeature.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumFeatureChain.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumFeatureMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumHelper.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumProcessHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumShutdownHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumTimeout.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="EncryptionRequest.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="EventDispatcher.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExternalTimer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Handle.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Handled.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HandleException.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HandleManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Handles.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HttpGetMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HttpProvider.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="IdentityHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InMemoryRegistrationDatabase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InMemorySyncRegDb.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InviteSession.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InviteSessionCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InviteSessionHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="KeepAliveManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="KeepAliveTimeout.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MasterProfile.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MergedRequestKey.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MergedRequestRemovalCommand.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="NetworkAssociation.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="NonDialogUsage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="OutgoingEvent.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="OutOfDialogHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="OutOfDialogReqCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PagerMessageCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PagerMessageHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Postable.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Profile.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PublicationCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PublicationHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RedirectHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RedirectManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RefCountedDestroyer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RegistrationCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RegistrationHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RegistrationPersistenceManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RemoteCertStore.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerAuthManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerInviteSession.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerOutOfDialogReq.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerPagerMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerPublication.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerRegistration.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerSubscription.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\EncryptionManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SubscriptionCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SubscriptionHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SubscriptionPersistenceManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SubscriptionState.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TargetCommand.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UsageUseException.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserAuthInfo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserProfile.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RequestValidationHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TlsPeerAuthManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/dum/dum_7_1.vcproj b/src/libs/resiprocate/resip/dum/dum_7_1.vcproj new file mode 100644 index 00000000..ead08395 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/dum_7_1.vcproj @@ -0,0 +1,744 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="dum" + ProjectGUID="{31B0654F-E08E-405F-909F-80F86CB14B9D}" + RootNamespace="dum" + Keyword="ManagedCProj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="2" + ManagedExtensions="FALSE"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;USE_ARES;USE_IPV6" + MinimalRebuild="FALSE" + BasicRuntimeChecks="0" + RuntimeLibrary="3" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="2" + ManagedExtensions="FALSE"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;USE_ARES;USE_IPV6" + MinimalRebuild="FALSE" + RuntimeLibrary="2" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="2" + ManagedExtensions="FALSE"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL" + MinimalRebuild="FALSE" + BasicRuntimeChecks="0" + RuntimeLibrary="3" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="2" + ManagedExtensions="FALSE"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL" + MinimalRebuild="FALSE" + RuntimeLibrary="2" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + <AssemblyReference + RelativePath="mscorlib.dll"/> + <AssemblyReference + RelativePath="System.dll"/> + <AssemblyReference + RelativePath="System.Data.dll"/> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath=".\AppDialog.cxx"> + </File> + <File + RelativePath=".\AppDialogSet.cxx"> + </File> + <File + RelativePath=".\AppDialogSetFactory.cxx"> + </File> + <File + RelativePath=".\BaseCreator.cxx"> + </File> + <File + RelativePath=".\BaseSubscription.cxx"> + </File> + <File + RelativePath=".\BaseUsage.cxx"> + </File> + <File + RelativePath=".\CertMessage.cxx"> + </File> + <File + RelativePath=".\ChallengeInfo.cxx"> + </File> + <File + RelativePath=".\ClientAuthExtension.cxx"> + </File> + <File + RelativePath=".\ClientAuthManager.cxx"> + </File> + <File + RelativePath=".\ClientInviteSession.cxx"> + </File> + <File + RelativePath=".\ClientOutOfDialogReq.cxx"> + </File> + <File + RelativePath=".\ClientPagerMessage.cxx"> + </File> + <File + RelativePath=".\ClientPublication.cxx"> + </File> + <File + RelativePath=".\ClientRegistration.cxx"> + </File> + <File + RelativePath=".\ClientSubscription.cxx"> + </File> + <File + RelativePath=".\ContactInstanceRecord.cxx"> + </File> + <File + RelativePath=".\DefaultServerReferHandler.cxx"> + </File> + <File + RelativePath=".\DestroyUsage.cxx"> + </File> + <File + RelativePath=".\Dialog.cxx"> + </File> + <File + RelativePath=".\DialogEventInfo.cxx"> + </File> + <File + RelativePath=".\DialogEventStateManager.cxx"> + </File> + <File + RelativePath=".\DialogId.cxx"> + </File> + <File + RelativePath=".\DialogSet.cxx"> + </File> + <File + RelativePath=".\DialogSetId.cxx"> + </File> + <File + RelativePath=".\DialogUsage.cxx"> + </File> + <File + RelativePath=".\DialogUsageManager.cxx"> + </File> + <File + RelativePath=".\DumDecrypted.cxx"> + </File> + <File + RelativePath=".\DumFeature.cxx"> + </File> + <File + RelativePath=".\DumFeatureChain.cxx"> + </File> + <File + RelativePath=".\DumFeatureMessage.cxx"> + </File> + <File + RelativePath=".\DumHelper.cxx"> + </File> + <File + RelativePath=".\DumProcessHandler.cxx"> + </File> + <File + RelativePath=".\DumThread.cxx"> + </File> + <File + RelativePath=".\DumTimeout.cxx"> + </File> + <File + RelativePath=".\ssl\EncryptionManager.cxx"> + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + </File> + <File + RelativePath=".\EncryptionRequest.cxx"> + </File> + <File + RelativePath=".\Handle.cxx"> + </File> + <File + RelativePath=".\Handled.cxx"> + </File> + <File + RelativePath=".\HandleException.cxx"> + </File> + <File + RelativePath=".\HandleManager.cxx"> + </File> + <File + RelativePath=".\HttpGetMessage.cxx"> + </File> + <File + RelativePath=".\HttpProvider.cxx"> + </File> + <File + RelativePath=".\IdentityHandler.cxx"> + </File> + <File + RelativePath=".\InMemoryRegistrationDatabase.cxx"> + </File> + <File + RelativePath=".\InMemorySyncRegDb.cxx"> + </File> + <File + RelativePath=".\InviteSession.cxx"> + </File> + <File + RelativePath=".\InviteSessionCreator.cxx"> + </File> + <File + RelativePath=".\InviteSessionHandler.cxx"> + </File> + <File + RelativePath=".\KeepAliveManager.cxx"> + </File> + <File + RelativePath=".\KeepAliveTimeout.cxx"> + </File> + <File + RelativePath=".\MasterProfile.cxx"> + </File> + <File + RelativePath=".\MergedRequestKey.cxx"> + </File> + <File + RelativePath=".\MergedRequestRemovalCommand.cxx"> + </File> + <File + RelativePath=".\NetworkAssociation.cxx"> + </File> + <File + RelativePath=".\NonDialogUsage.cxx"> + </File> + <File + RelativePath=".\OutgoingEvent.cxx"> + </File> + <File + RelativePath=".\OutOfDialogReqCreator.cxx"> + </File> + <File + RelativePath=".\PagerMessageCreator.cxx"> + </File> + <File + RelativePath=".\Profile.cxx"> + </File> + <File + RelativePath=".\PublicationCreator.cxx"> + </File> + <File + RelativePath=".\RedirectManager.cxx"> + </File> + <File + RelativePath=".\RegistrationCreator.cxx"> + </File> + <File + RelativePath=".\RegistrationHandler.cxx"> + </File> + <File + RelativePath=".\ServerAuthManager.cxx"> + </File> + <File + RelativePath=".\ServerInviteSession.cxx"> + </File> + <File + RelativePath=".\ServerOutOfDialogReq.cxx"> + </File> + <File + RelativePath=".\ServerPagerMessage.cxx"> + </File> + <File + RelativePath=".\ServerPublication.cxx"> + </File> + <File + RelativePath=".\ServerRegistration.cxx"> + </File> + <File + RelativePath=".\ServerSubscription.cxx"> + </File> + <File + RelativePath=".\SubscriptionCreator.cxx"> + </File> + <File + RelativePath=".\SubscriptionHandler.cxx"> + </File> + <File + RelativePath=".\SubscriptionState.cxx"> + </File> + <File + RelativePath=".\TargetCommand.cxx"> + </File> + <File + RelativePath=".\UserAuthInfo.cxx"> + </File> + <File + RelativePath=".\UserProfile.cxx"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath=".\AppDialog.hxx"> + </File> + <File + RelativePath=".\AppDialogSet.hxx"> + </File> + <File + RelativePath=".\AppDialogSetFactory.hxx"> + </File> + <File + RelativePath=".\BaseCreator.hxx"> + </File> + <File + RelativePath=".\BaseSubscription.hxx"> + </File> + <File + RelativePath=".\BaseUsage.hxx"> + </File> + <File + RelativePath=".\CertMessage.hxx"> + </File> + <File + RelativePath=".\ChallengeInfo.hxx"> + </File> + <File + RelativePath=".\ClientAuthExtension.hxx"> + </File> + <File + RelativePath=".\ClientAuthManager.hxx"> + </File> + <File + RelativePath=".\ClientInviteSession.hxx"> + </File> + <File + RelativePath=".\ClientOutOfDialogReq.hxx"> + </File> + <File + RelativePath=".\ClientPagerMessage.hxx"> + </File> + <File + RelativePath=".\ClientPublication.hxx"> + </File> + <File + RelativePath=".\ClientRegistration.hxx"> + </File> + <File + RelativePath=".\ClientSubscription.hxx"> + </File> + <File + RelativePath=".\ContactInstanceRecord.hxx"> + </File> + <File + RelativePath=".\DefaultServerReferHandler.hxx"> + </File> + <File + RelativePath=".\DestroyUsage.hxx"> + </File> + <File + RelativePath=".\Dialog.hxx"> + </File> + <File + RelativePath=".\DialogEventHandler.hxx"> + </File> + <File + RelativePath=".\DialogEventInfo.hxx"> + </File> + <File + RelativePath=".\DialogEventStateManager.hxx"> + </File> + <File + RelativePath=".\DialogId.hxx"> + </File> + <File + RelativePath=".\DialogSet.hxx"> + </File> + <File + RelativePath=".\DialogSetHandler.hxx"> + </File> + <File + RelativePath=".\DialogSetId.hxx"> + </File> + <File + RelativePath=".\DialogUsage.hxx"> + </File> + <File + RelativePath=".\DialogUsageManager.hxx"> + </File> + <File + RelativePath=".\DumCommand.hxx"> + </File> + <File + RelativePath=".\DumDecrypted.hxx"> + </File> + <File + RelativePath=".\DumException.hxx"> + </File> + <File + RelativePath=".\DumFeature.hxx"> + </File> + <File + RelativePath=".\DumFeatureChain.hxx"> + </File> + <File + RelativePath=".\DumFeatureMessage.hxx"> + </File> + <File + RelativePath=".\DumHelper.hxx"> + </File> + <File + RelativePath=".\DumProcessHandler.hxx"> + </File> + <File + RelativePath=".\DumShutdownHandler.hxx"> + </File> + <File + RelativePath=".\DumThread.hxx"> + </File> + <File + RelativePath=".\DumTimeout.hxx"> + </File> + <File + RelativePath=".\ssl\EncryptionManager.hxx"> + </File> + <File + RelativePath=".\EncryptionRequest.hxx"> + </File> + <File + RelativePath=".\EventDispatcher.hxx"> + </File> + <File + RelativePath=".\ExternalMessageBase.hxx"> + </File> + <File + RelativePath=".\ExternalMessageHandler.hxx"> + </File> + <File + RelativePath=".\ExternalTimer.hxx"> + </File> + <File + RelativePath=".\Handle.hxx"> + </File> + <File + RelativePath=".\Handled.hxx"> + </File> + <File + RelativePath=".\HandleException.hxx"> + </File> + <File + RelativePath=".\HandleManager.hxx"> + </File> + <File + RelativePath=".\Handles.hxx"> + </File> + <File + RelativePath=".\HttpGetMessage.hxx"> + </File> + <File + RelativePath=".\HttpProvider.hxx"> + </File> + <File + RelativePath=".\IdentityHandler.hxx"> + </File> + <File + RelativePath=".\InMemoryRegistrationDatabase.hxx"> + </File> + <File + RelativePath=".\InMemorySyncRegDb.hxx"> + </File> + <File + RelativePath=".\InviteSession.hxx"> + </File> + <File + RelativePath=".\InviteSessionCreator.hxx"> + </File> + <File + RelativePath=".\InviteSessionHandler.hxx"> + </File> + <File + RelativePath=".\KeepAliveManager.hxx"> + </File> + <File + RelativePath=".\KeepAliveTimeout.hxx"> + </File> + <File + RelativePath=".\MasterProfile.hxx"> + </File> + <File + RelativePath=".\MergedRequestKey.hxx"> + </File> + <File + RelativePath=".\MergedRequestRemovalCommand.hxx"> + </File> + <File + RelativePath=".\NetworkAssociation.hxx"> + </File> + <File + RelativePath=".\NonDialogUsage.hxx"> + </File> + <File + RelativePath=".\OutgoingEvent.hxx"> + </File> + <File + RelativePath=".\OutOfDialogHandler.hxx"> + </File> + <File + RelativePath=".\OutOfDialogReqCreator.hxx"> + </File> + <File + RelativePath=".\PagerMessageCreator.hxx"> + </File> + <File + RelativePath=".\PagerMessageHandler.hxx"> + </File> + <File + RelativePath=".\Postable.hxx"> + </File> + <File + RelativePath=".\Profile.hxx"> + </File> + <File + RelativePath=".\PublicationCreator.hxx"> + </File> + <File + RelativePath=".\PublicationHandler.hxx"> + </File> + <File + RelativePath=".\RedirectHandler.hxx"> + </File> + <File + RelativePath=".\RedirectManager.hxx"> + </File> + <File + RelativePath=".\RefCountedDestroyer.hxx"> + </File> + <File + RelativePath=".\RegistrationCreator.hxx"> + </File> + <File + RelativePath=".\RegistrationHandler.hxx"> + </File> + <File + RelativePath=".\RegistrationPersistenceManager.hxx"> + </File> + <File + RelativePath=".\RemoteCertStore.hxx"> + </File> + <File + RelativePath=".\RequestValidationHandler.hxx" + > + </File> + <File + RelativePath=".\ServerAuthManager.hxx"> + </File> + <File + RelativePath=".\ServerInviteSession.hxx"> + </File> + <File + RelativePath=".\ServerOutOfDialogReq.hxx"> + </File> + <File + RelativePath=".\ServerPagerMessage.hxx"> + </File> + <File + RelativePath=".\ServerPublication.hxx"> + </File> + <File + RelativePath=".\ServerRegistration.hxx"> + </File> + <File + RelativePath=".\ServerSubscription.hxx"> + </File> + <File + RelativePath=".\SubscriptionCreator.hxx"> + </File> + <File + RelativePath=".\SubscriptionHandler.hxx"> + </File> + <File + RelativePath=".\SubscriptionPersistenceManager.hxx"> + </File> + <File + RelativePath=".\SubscriptionState.hxx"> + </File> + <File + RelativePath=".\TargetCommand.hxx"> + </File> + <File + RelativePath=".\UsageUseException.hxx"> + </File> + <File + RelativePath=".\UserAuthInfo.hxx"> + </File> + <File + RelativePath=".\UserProfile.hxx"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/dum/dum_8_0.vcproj b/src/libs/resiprocate/resip/dum/dum_8_0.vcproj new file mode 100644 index 00000000..8dc07263 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/dum_8_0.vcproj @@ -0,0 +1,1027 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="dum" + ProjectGUID="{31B0654F-E08E-405F-909F-80F86CB14B9D}" + RootNamespace="dum" + Keyword="ManagedCProj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK" + MinimalRebuild="false" + BasicRuntimeChecks="0" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;USE_ARES;USE_IPV6" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL" + MinimalRebuild="false" + BasicRuntimeChecks="0" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + <AssemblyReference + RelativePath="mscorlib.dll" + AssemblyName="mscorlib, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=IA64" + /> + <AssemblyReference + RelativePath="System.dll" + AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" + /> + <AssemblyReference + RelativePath="System.Data.dll" + AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86" + /> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\AppDialog.cxx" + > + </File> + <File + RelativePath=".\AppDialogSet.cxx" + > + </File> + <File + RelativePath=".\AppDialogSetFactory.cxx" + > + </File> + <File + RelativePath=".\BaseCreator.cxx" + > + </File> + <File + RelativePath=".\BaseSubscription.cxx" + > + </File> + <File + RelativePath=".\BaseUsage.cxx" + > + </File> + <File + RelativePath=".\CertMessage.cxx" + > + </File> + <File + RelativePath=".\ChallengeInfo.cxx" + > + </File> + <File + RelativePath=".\ClientAuthExtension.cxx" + > + </File> + <File + RelativePath=".\ClientAuthManager.cxx" + > + </File> + <File + RelativePath=".\ClientInviteSession.cxx" + > + </File> + <File + RelativePath=".\ClientOutOfDialogReq.cxx" + > + </File> + <File + RelativePath=".\ClientPagerMessage.cxx" + > + </File> + <File + RelativePath=".\ClientPublication.cxx" + > + </File> + <File + RelativePath=".\ClientRegistration.cxx" + > + </File> + <File + RelativePath=".\ClientSubscription.cxx" + > + </File> + <File + RelativePath=".\ContactInstanceRecord.cxx" + > + </File> + <File + RelativePath=".\DefaultServerReferHandler.cxx" + > + </File> + <File + RelativePath=".\DestroyUsage.cxx" + > + </File> + <File + RelativePath=".\Dialog.cxx" + > + </File> + <File + RelativePath=".\DialogEventInfo.cxx" + > + </File> + <File + RelativePath=".\DialogEventStateManager.cxx" + > + </File> + <File + RelativePath=".\DialogId.cxx" + > + </File> + <File + RelativePath=".\DialogSet.cxx" + > + </File> + <File + RelativePath=".\DialogSetId.cxx" + > + </File> + <File + RelativePath=".\DialogUsage.cxx" + > + </File> + <File + RelativePath=".\DialogUsageManager.cxx" + > + </File> + <File + RelativePath=".\DumDecrypted.cxx" + > + </File> + <File + RelativePath=".\DumFeature.cxx" + > + </File> + <File + RelativePath=".\DumFeatureChain.cxx" + > + </File> + <File + RelativePath=".\DumFeatureMessage.cxx" + > + </File> + <File + RelativePath=".\DumHelper.cxx" + > + </File> + <File + RelativePath=".\DumProcessHandler.cxx" + > + </File> + <File + RelativePath=".\DumThread.cxx" + > + </File> + <File + RelativePath=".\DumTimeout.cxx" + > + </File> + <File + RelativePath=".\ssl\EncryptionManager.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\EncryptionRequest.cxx" + > + </File> + <File + RelativePath=".\Handle.cxx" + > + </File> + <File + RelativePath=".\Handled.cxx" + > + </File> + <File + RelativePath=".\HandleException.cxx" + > + </File> + <File + RelativePath=".\HandleManager.cxx" + > + </File> + <File + RelativePath=".\HttpGetMessage.cxx" + > + </File> + <File + RelativePath=".\HttpProvider.cxx" + > + </File> + <File + RelativePath=".\IdentityHandler.cxx" + > + </File> + <File + RelativePath=".\InMemoryRegistrationDatabase.cxx" + > + </File> + <File + RelativePath=".\InMemorySyncRegDb.cxx" + > + </File> + <File + RelativePath=".\InviteSession.cxx" + > + </File> + <File + RelativePath=".\InviteSessionCreator.cxx" + > + </File> + <File + RelativePath=".\InviteSessionHandler.cxx" + > + </File> + <File + RelativePath=".\KeepAliveManager.cxx" + > + </File> + <File + RelativePath=".\KeepAliveTimeout.cxx" + > + </File> + <File + RelativePath=".\MasterProfile.cxx" + > + </File> + <File + RelativePath=".\MergedRequestKey.cxx" + > + </File> + <File + RelativePath=".\MergedRequestRemovalCommand.cxx" + > + </File> + <File + RelativePath=".\NetworkAssociation.cxx" + > + </File> + <File + RelativePath=".\NonDialogUsage.cxx" + > + </File> + <File + RelativePath=".\OutgoingEvent.cxx" + > + </File> + <File + RelativePath=".\OutOfDialogReqCreator.cxx" + > + </File> + <File + RelativePath=".\PagerMessageCreator.cxx" + > + </File> + <File + RelativePath=".\Profile.cxx" + > + </File> + <File + RelativePath=".\PublicationCreator.cxx" + > + </File> + <File + RelativePath=".\RedirectManager.cxx" + > + </File> + <File + RelativePath=".\RegistrationCreator.cxx" + > + </File> + <File + RelativePath=".\RegistrationHandler.cxx" + > + </File> + <File + RelativePath=".\ServerAuthManager.cxx" + > + </File> + <File + RelativePath=".\ServerInviteSession.cxx" + > + </File> + <File + RelativePath=".\ServerOutOfDialogReq.cxx" + > + </File> + <File + RelativePath=".\ServerPagerMessage.cxx" + > + </File> + <File + RelativePath=".\ServerPublication.cxx" + > + </File> + <File + RelativePath=".\ServerRegistration.cxx" + > + </File> + <File + RelativePath=".\ServerSubscription.cxx" + > + </File> + <File + RelativePath=".\SubscriptionCreator.cxx" + > + </File> + <File + RelativePath=".\SubscriptionHandler.cxx" + > + </File> + <File + RelativePath=".\SubscriptionState.cxx" + > + </File> + <File + RelativePath=".\TargetCommand.cxx" + > + </File> + <File + RelativePath=".\TlsPeerAuthManager.cxx" + > + </File> + <File + RelativePath=".\UserAuthInfo.cxx" + > + </File> + <File + RelativePath=".\UserProfile.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\AppDialog.hxx" + > + </File> + <File + RelativePath=".\AppDialogSet.hxx" + > + </File> + <File + RelativePath=".\AppDialogSetFactory.hxx" + > + </File> + <File + RelativePath=".\BaseCreator.hxx" + > + </File> + <File + RelativePath=".\BaseSubscription.hxx" + > + </File> + <File + RelativePath=".\BaseUsage.hxx" + > + </File> + <File + RelativePath=".\CertMessage.hxx" + > + </File> + <File + RelativePath=".\ChallengeInfo.hxx" + > + </File> + <File + RelativePath=".\ClientAuthExtension.hxx" + > + </File> + <File + RelativePath=".\ClientAuthManager.hxx" + > + </File> + <File + RelativePath=".\ClientInviteSession.hxx" + > + </File> + <File + RelativePath=".\ClientOutOfDialogReq.hxx" + > + </File> + <File + RelativePath=".\ClientPagerMessage.hxx" + > + </File> + <File + RelativePath=".\ClientPublication.hxx" + > + </File> + <File + RelativePath=".\ClientRegistration.hxx" + > + </File> + <File + RelativePath=".\ClientSubscription.hxx" + > + </File> + <File + RelativePath=".\ContactInstanceRecord.hxx" + > + </File> + <File + RelativePath=".\DefaultServerReferHandler.hxx" + > + </File> + <File + RelativePath=".\DestroyUsage.hxx" + > + </File> + <File + RelativePath=".\Dialog.hxx" + > + </File> + <File + RelativePath=".\DialogEventHandler.hxx" + > + </File> + <File + RelativePath=".\DialogEventInfo.hxx" + > + </File> + <File + RelativePath=".\DialogEventStateManager.hxx" + > + </File> + <File + RelativePath=".\DialogId.hxx" + > + </File> + <File + RelativePath=".\DialogSet.hxx" + > + </File> + <File + RelativePath=".\DialogSetHandler.hxx" + > + </File> + <File + RelativePath=".\DialogSetId.hxx" + > + </File> + <File + RelativePath=".\DialogUsage.hxx" + > + </File> + <File + RelativePath=".\DialogUsageManager.hxx" + > + </File> + <File + RelativePath=".\DumCommand.hxx" + > + </File> + <File + RelativePath=".\DumDecrypted.hxx" + > + </File> + <File + RelativePath=".\DumException.hxx" + > + </File> + <File + RelativePath=".\DumFeature.hxx" + > + </File> + <File + RelativePath=".\DumFeatureChain.hxx" + > + </File> + <File + RelativePath=".\DumFeatureMessage.hxx" + > + </File> + <File + RelativePath=".\DumHelper.hxx" + > + </File> + <File + RelativePath=".\DumProcessHandler.hxx" + > + </File> + <File + RelativePath=".\DumShutdownHandler.hxx" + > + </File> + <File + RelativePath=".\DumThread.hxx" + > + </File> + <File + RelativePath=".\DumTimeout.hxx" + > + </File> + <File + RelativePath=".\ssl\EncryptionManager.hxx" + > + </File> + <File + RelativePath=".\EncryptionRequest.hxx" + > + </File> + <File + RelativePath=".\EventDispatcher.hxx" + > + </File> + <File + RelativePath=".\ExternalTimer.hxx" + > + </File> + <File + RelativePath=".\Handle.hxx" + > + </File> + <File + RelativePath=".\Handled.hxx" + > + </File> + <File + RelativePath=".\HandleException.hxx" + > + </File> + <File + RelativePath=".\HandleManager.hxx" + > + </File> + <File + RelativePath=".\Handles.hxx" + > + </File> + <File + RelativePath=".\HttpGetMessage.hxx" + > + </File> + <File + RelativePath=".\HttpProvider.hxx" + > + </File> + <File + RelativePath=".\IdentityHandler.hxx" + > + </File> + <File + RelativePath=".\InMemoryRegistrationDatabase.hxx" + > + </File> + <File + RelativePath=".\InMemorySyncRegDb.hxx" + > + </File> + <File + RelativePath=".\InviteSession.hxx" + > + </File> + <File + RelativePath=".\InviteSessionCreator.hxx" + > + </File> + <File + RelativePath=".\InviteSessionHandler.hxx" + > + </File> + <File + RelativePath=".\KeepAliveManager.hxx" + > + </File> + <File + RelativePath=".\KeepAliveTimeout.hxx" + > + </File> + <File + RelativePath=".\MasterProfile.hxx" + > + </File> + <File + RelativePath=".\MergedRequestKey.hxx" + > + </File> + <File + RelativePath=".\MergedRequestRemovalCommand.hxx" + > + </File> + <File + RelativePath=".\NetworkAssociation.hxx" + > + </File> + <File + RelativePath=".\NonDialogUsage.hxx" + > + </File> + <File + RelativePath=".\OutgoingEvent.hxx" + > + </File> + <File + RelativePath=".\OutOfDialogHandler.hxx" + > + </File> + <File + RelativePath=".\OutOfDialogReqCreator.hxx" + > + </File> + <File + RelativePath=".\PagerMessageCreator.hxx" + > + </File> + <File + RelativePath=".\PagerMessageHandler.hxx" + > + </File> + <File + RelativePath=".\Postable.hxx" + > + </File> + <File + RelativePath=".\Profile.hxx" + > + </File> + <File + RelativePath=".\PublicationCreator.hxx" + > + </File> + <File + RelativePath=".\PublicationHandler.hxx" + > + </File> + <File + RelativePath=".\RedirectHandler.hxx" + > + </File> + <File + RelativePath=".\RedirectManager.hxx" + > + </File> + <File + RelativePath=".\RefCountedDestroyer.hxx" + > + </File> + <File + RelativePath=".\RegistrationCreator.hxx" + > + </File> + <File + RelativePath=".\RegistrationHandler.hxx" + > + </File> + <File + RelativePath=".\RegistrationPersistenceManager.hxx" + > + </File> + <File + RelativePath=".\RemoteCertStore.hxx" + > + </File> + <File + RelativePath=".\RequestValidationHandler.hxx" + > + </File> + <File + RelativePath=".\ServerAuthManager.hxx" + > + </File> + <File + RelativePath=".\ServerInviteSession.hxx" + > + </File> + <File + RelativePath=".\ServerOutOfDialogReq.hxx" + > + </File> + <File + RelativePath=".\ServerPagerMessage.hxx" + > + </File> + <File + RelativePath=".\ServerPublication.hxx" + > + </File> + <File + RelativePath=".\ServerRegistration.hxx" + > + </File> + <File + RelativePath=".\ServerSubscription.hxx" + > + </File> + <File + RelativePath=".\SubscriptionCreator.hxx" + > + </File> + <File + RelativePath=".\SubscriptionHandler.hxx" + > + </File> + <File + RelativePath=".\SubscriptionPersistenceManager.hxx" + > + </File> + <File + RelativePath=".\SubscriptionState.hxx" + > + </File> + <File + RelativePath=".\TargetCommand.hxx" + > + </File> + <File + RelativePath=".\TlsPeerAuthManager.hxx" + > + </File> + <File + RelativePath=".\UsageUseException.hxx" + > + </File> + <File + RelativePath=".\UserAuthInfo.hxx" + > + </File> + <File + RelativePath=".\UserProfile.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/dum/dum_9_0.vcproj b/src/libs/resiprocate/resip/dum/dum_9_0.vcproj new file mode 100644 index 00000000..c77209d7 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/dum_9_0.vcproj @@ -0,0 +1,1035 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="dum" + ProjectGUID="{12720B4D-F4FC-4502-8FA9-589BF5166216}" + RootNamespace="dum" + Keyword="ManagedCProj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;USE_SSL" + MinimalRebuild="false" + BasicRuntimeChecks="0" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)../../../openssl/include&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL" + MinimalRebuild="false" + BasicRuntimeChecks="0" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)../../../openssl/include&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL" + MinimalRebuild="false" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + <AssemblyReference + RelativePath="mscorlib.dll" + AssemblyName="mscorlib, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=IA64" + MinFrameworkVersion="131072" + /> + <AssemblyReference + RelativePath="System.dll" + AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" + MinFrameworkVersion="131072" + /> + <AssemblyReference + RelativePath="System.Data.dll" + AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86" + MinFrameworkVersion="131072" + /> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\AppDialog.cxx" + > + </File> + <File + RelativePath=".\AppDialogSet.cxx" + > + </File> + <File + RelativePath=".\AppDialogSetFactory.cxx" + > + </File> + <File + RelativePath=".\BaseCreator.cxx" + > + </File> + <File + RelativePath=".\BaseSubscription.cxx" + > + </File> + <File + RelativePath=".\BaseUsage.cxx" + > + </File> + <File + RelativePath=".\CertMessage.cxx" + > + </File> + <File + RelativePath=".\ChallengeInfo.cxx" + > + </File> + <File + RelativePath=".\ClientAuthExtension.cxx" + > + </File> + <File + RelativePath=".\ClientAuthManager.cxx" + > + </File> + <File + RelativePath=".\ClientInviteSession.cxx" + > + </File> + <File + RelativePath=".\ClientOutOfDialogReq.cxx" + > + </File> + <File + RelativePath=".\ClientPagerMessage.cxx" + > + </File> + <File + RelativePath=".\ClientPublication.cxx" + > + </File> + <File + RelativePath=".\ClientRegistration.cxx" + > + </File> + <File + RelativePath=".\ClientSubscription.cxx" + > + </File> + <File + RelativePath=".\ContactInstanceRecord.cxx" + > + </File> + <File + RelativePath=".\DefaultServerReferHandler.cxx" + > + </File> + <File + RelativePath=".\DestroyUsage.cxx" + > + </File> + <File + RelativePath=".\Dialog.cxx" + > + </File> + <File + RelativePath=".\DialogEventInfo.cxx" + > + </File> + <File + RelativePath=".\DialogEventStateManager.cxx" + > + </File> + <File + RelativePath=".\DialogId.cxx" + > + </File> + <File + RelativePath=".\DialogSet.cxx" + > + </File> + <File + RelativePath=".\DialogSetId.cxx" + > + </File> + <File + RelativePath=".\DialogUsage.cxx" + > + </File> + <File + RelativePath=".\DialogUsageManager.cxx" + > + </File> + <File + RelativePath=".\DumDecrypted.cxx" + > + </File> + <File + RelativePath=".\DumFeature.cxx" + > + </File> + <File + RelativePath=".\DumFeatureChain.cxx" + > + </File> + <File + RelativePath=".\DumFeatureMessage.cxx" + > + </File> + <File + RelativePath=".\DumHelper.cxx" + > + </File> + <File + RelativePath=".\DumProcessHandler.cxx" + > + </File> + <File + RelativePath=".\DumThread.cxx" + > + </File> + <File + RelativePath=".\DumTimeout.cxx" + > + </File> + <File + RelativePath=".\ssl\EncryptionManager.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\EncryptionRequest.cxx" + > + </File> + <File + RelativePath=".\Handle.cxx" + > + </File> + <File + RelativePath=".\Handled.cxx" + > + </File> + <File + RelativePath=".\HandleException.cxx" + > + </File> + <File + RelativePath=".\HandleManager.cxx" + > + </File> + <File + RelativePath=".\HttpGetMessage.cxx" + > + </File> + <File + RelativePath=".\HttpProvider.cxx" + > + </File> + <File + RelativePath=".\IdentityHandler.cxx" + > + </File> + <File + RelativePath=".\InMemoryRegistrationDatabase.cxx" + > + </File> + <File + RelativePath=".\InMemorySyncRegDb.cxx" + > + </File> + <File + RelativePath=".\InviteSession.cxx" + > + </File> + <File + RelativePath=".\InviteSessionCreator.cxx" + > + </File> + <File + RelativePath=".\InviteSessionHandler.cxx" + > + </File> + <File + RelativePath=".\KeepAliveManager.cxx" + > + </File> + <File + RelativePath=".\KeepAliveTimeout.cxx" + > + </File> + <File + RelativePath=".\MasterProfile.cxx" + > + </File> + <File + RelativePath=".\MergedRequestKey.cxx" + > + </File> + <File + RelativePath=".\MergedRequestRemovalCommand.cxx" + > + </File> + <File + RelativePath=".\NetworkAssociation.cxx" + > + </File> + <File + RelativePath=".\NonDialogUsage.cxx" + > + </File> + <File + RelativePath=".\OutgoingEvent.cxx" + > + </File> + <File + RelativePath=".\OutOfDialogReqCreator.cxx" + > + </File> + <File + RelativePath=".\PagerMessageCreator.cxx" + > + </File> + <File + RelativePath=".\Profile.cxx" + > + </File> + <File + RelativePath=".\PublicationCreator.cxx" + > + </File> + <File + RelativePath=".\RedirectManager.cxx" + > + </File> + <File + RelativePath=".\RegistrationCreator.cxx" + > + </File> + <File + RelativePath=".\RegistrationHandler.cxx" + > + </File> + <File + RelativePath=".\ServerAuthManager.cxx" + > + </File> + <File + RelativePath=".\ServerInviteSession.cxx" + > + </File> + <File + RelativePath=".\ServerOutOfDialogReq.cxx" + > + </File> + <File + RelativePath=".\ServerPagerMessage.cxx" + > + </File> + <File + RelativePath=".\ServerPublication.cxx" + > + </File> + <File + RelativePath=".\ServerRegistration.cxx" + > + </File> + <File + RelativePath=".\ServerSubscription.cxx" + > + </File> + <File + RelativePath=".\SubscriptionCreator.cxx" + > + </File> + <File + RelativePath=".\SubscriptionHandler.cxx" + > + </File> + <File + RelativePath=".\SubscriptionState.cxx" + > + </File> + <File + RelativePath=".\TargetCommand.cxx" + > + </File> + <File + RelativePath=".\TlsPeerAuthManager.cxx" + > + </File> + <File + RelativePath=".\UserAuthInfo.cxx" + > + </File> + <File + RelativePath=".\UserProfile.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\AppDialog.hxx" + > + </File> + <File + RelativePath=".\AppDialogSet.hxx" + > + </File> + <File + RelativePath=".\AppDialogSetFactory.hxx" + > + </File> + <File + RelativePath=".\BaseCreator.hxx" + > + </File> + <File + RelativePath=".\BaseSubscription.hxx" + > + </File> + <File + RelativePath=".\BaseUsage.hxx" + > + </File> + <File + RelativePath=".\CertMessage.hxx" + > + </File> + <File + RelativePath=".\ChallengeInfo.hxx" + > + </File> + <File + RelativePath=".\ClientAuthExtension.hxx" + > + </File> + <File + RelativePath=".\ClientAuthManager.hxx" + > + </File> + <File + RelativePath=".\ClientInviteSession.hxx" + > + </File> + <File + RelativePath=".\ClientOutOfDialogReq.hxx" + > + </File> + <File + RelativePath=".\ClientPagerMessage.hxx" + > + </File> + <File + RelativePath=".\ClientPublication.hxx" + > + </File> + <File + RelativePath=".\ClientRegistration.hxx" + > + </File> + <File + RelativePath=".\ClientSubscription.hxx" + > + </File> + <File + RelativePath=".\ContactInstanceRecord.hxx" + > + </File> + <File + RelativePath=".\DefaultServerReferHandler.hxx" + > + </File> + <File + RelativePath=".\DestroyUsage.hxx" + > + </File> + <File + RelativePath=".\Dialog.hxx" + > + </File> + <File + RelativePath=".\DialogEventHandler.hxx" + > + </File> + <File + RelativePath=".\DialogEventInfo.hxx" + > + </File> + <File + RelativePath=".\DialogEventStateManager.hxx" + > + </File> + <File + RelativePath=".\DialogId.hxx" + > + </File> + <File + RelativePath=".\DialogSet.hxx" + > + </File> + <File + RelativePath=".\DialogSetHandler.hxx" + > + </File> + <File + RelativePath=".\DialogSetId.hxx" + > + </File> + <File + RelativePath=".\DialogUsage.hxx" + > + </File> + <File + RelativePath=".\DialogUsageManager.hxx" + > + </File> + <File + RelativePath=".\DumCommand.hxx" + > + </File> + <File + RelativePath=".\DumDecrypted.hxx" + > + </File> + <File + RelativePath=".\DumException.hxx" + > + </File> + <File + RelativePath=".\DumFeature.hxx" + > + </File> + <File + RelativePath=".\DumFeatureChain.hxx" + > + </File> + <File + RelativePath=".\DumFeatureMessage.hxx" + > + </File> + <File + RelativePath=".\DumHelper.hxx" + > + </File> + <File + RelativePath=".\DumProcessHandler.hxx" + > + </File> + <File + RelativePath=".\DumShutdownHandler.hxx" + > + </File> + <File + RelativePath=".\DumThread.hxx" + > + </File> + <File + RelativePath=".\DumTimeout.hxx" + > + </File> + <File + RelativePath=".\ssl\EncryptionManager.hxx" + > + </File> + <File + RelativePath=".\EncryptionRequest.hxx" + > + </File> + <File + RelativePath=".\EventDispatcher.hxx" + > + </File> + <File + RelativePath=".\ExternalTimer.hxx" + > + </File> + <File + RelativePath=".\Handle.hxx" + > + </File> + <File + RelativePath=".\Handled.hxx" + > + </File> + <File + RelativePath=".\HandleException.hxx" + > + </File> + <File + RelativePath=".\HandleManager.hxx" + > + </File> + <File + RelativePath=".\Handles.hxx" + > + </File> + <File + RelativePath=".\HttpGetMessage.hxx" + > + </File> + <File + RelativePath=".\HttpProvider.hxx" + > + </File> + <File + RelativePath=".\IdentityHandler.hxx" + > + </File> + <File + RelativePath=".\InMemoryRegistrationDatabase.hxx" + > + </File> + <File + RelativePath=".\InMemorySyncRegDb.hxx" + > + </File> + <File + RelativePath=".\InviteSession.hxx" + > + </File> + <File + RelativePath=".\InviteSessionCreator.hxx" + > + </File> + <File + RelativePath=".\InviteSessionHandler.hxx" + > + </File> + <File + RelativePath=".\KeepAliveManager.hxx" + > + </File> + <File + RelativePath=".\KeepAliveTimeout.hxx" + > + </File> + <File + RelativePath=".\MasterProfile.hxx" + > + </File> + <File + RelativePath=".\MergedRequestKey.hxx" + > + </File> + <File + RelativePath=".\MergedRequestRemovalCommand.hxx" + > + </File> + <File + RelativePath=".\NetworkAssociation.hxx" + > + </File> + <File + RelativePath=".\NonDialogUsage.hxx" + > + </File> + <File + RelativePath=".\OutgoingEvent.hxx" + > + </File> + <File + RelativePath=".\OutOfDialogHandler.hxx" + > + </File> + <File + RelativePath=".\OutOfDialogReqCreator.hxx" + > + </File> + <File + RelativePath=".\PagerMessageCreator.hxx" + > + </File> + <File + RelativePath=".\PagerMessageHandler.hxx" + > + </File> + <File + RelativePath=".\Postable.hxx" + > + </File> + <File + RelativePath=".\Profile.hxx" + > + </File> + <File + RelativePath=".\PublicationCreator.hxx" + > + </File> + <File + RelativePath=".\PublicationHandler.hxx" + > + </File> + <File + RelativePath=".\RedirectHandler.hxx" + > + </File> + <File + RelativePath=".\RedirectManager.hxx" + > + </File> + <File + RelativePath=".\RefCountedDestroyer.hxx" + > + </File> + <File + RelativePath=".\RegistrationCreator.hxx" + > + </File> + <File + RelativePath=".\RegistrationHandler.hxx" + > + </File> + <File + RelativePath=".\RegistrationPersistenceManager.hxx" + > + </File> + <File + RelativePath=".\RemoteCertStore.hxx" + > + </File> + <File + RelativePath=".\RequestValidationHandler.hxx" + > + </File> + <File + RelativePath=".\ServerAuthManager.hxx" + > + </File> + <File + RelativePath=".\ServerInviteSession.hxx" + > + </File> + <File + RelativePath=".\ServerOutOfDialogReq.hxx" + > + </File> + <File + RelativePath=".\ServerPagerMessage.hxx" + > + </File> + <File + RelativePath=".\ServerPublication.hxx" + > + </File> + <File + RelativePath=".\ServerRegistration.hxx" + > + </File> + <File + RelativePath=".\ServerSubscription.hxx" + > + </File> + <File + RelativePath=".\SubscriptionCreator.hxx" + > + </File> + <File + RelativePath=".\SubscriptionHandler.hxx" + > + </File> + <File + RelativePath=".\SubscriptionPersistenceManager.hxx" + > + </File> + <File + RelativePath=".\SubscriptionState.hxx" + > + </File> + <File + RelativePath=".\TargetCommand.hxx" + > + </File> + <File + RelativePath=".\TlsPeerAuthManager.hxx" + > + </File> + <File + RelativePath=".\UsageUseException.hxx" + > + </File> + <File + RelativePath=".\UserAuthInfo.hxx" + > + </File> + <File + RelativePath=".\UserProfile.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj b/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj new file mode 100644 index 00000000..b27a9536 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj @@ -0,0 +1,346 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|Win32"> + <Configuration>SSL-Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|Win32"> + <Configuration>SSL-Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>dum</ProjectName> + <ProjectGuid>{12720B4D-F4FC-4502-8FA9-589BF5166216}</ProjectGuid> + <RootNamespace>dum</RootNamespace> + <Keyword>ManagedCProj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120_xp</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + <CLRSupport>false</CLRSupport> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <OutDir>$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <OutDir>$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;USE_SSL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks>Default</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <ClCompile> + <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../../openssl/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks>Default</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <ClCompile> + <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../../openssl/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <Reference Include="mscorlib"> + <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + </Reference> + <Reference Include="System"> + <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + </Reference> + <Reference Include="System.Data"> + <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + </Reference> + </ItemGroup> + <ItemGroup> + <ClCompile Include="AppDialog.cxx" /> + <ClCompile Include="AppDialogSet.cxx" /> + <ClCompile Include="AppDialogSetFactory.cxx" /> + <ClCompile Include="BaseCreator.cxx" /> + <ClCompile Include="BaseSubscription.cxx" /> + <ClCompile Include="BaseUsage.cxx" /> + <ClCompile Include="CertMessage.cxx" /> + <ClCompile Include="ChallengeInfo.cxx" /> + <ClCompile Include="ClientAuthExtension.cxx" /> + <ClCompile Include="ClientAuthManager.cxx" /> + <ClCompile Include="ClientInviteSession.cxx" /> + <ClCompile Include="ClientOutOfDialogReq.cxx" /> + <ClCompile Include="ClientPagerMessage.cxx" /> + <ClCompile Include="ClientPublication.cxx" /> + <ClCompile Include="ClientRegistration.cxx" /> + <ClCompile Include="ClientSubscription.cxx" /> + <ClCompile Include="ContactInstanceRecord.cxx" /> + <ClCompile Include="DefaultServerReferHandler.cxx" /> + <ClCompile Include="DestroyUsage.cxx" /> + <ClCompile Include="Dialog.cxx" /> + <ClCompile Include="DialogEventInfo.cxx" /> + <ClCompile Include="DialogEventStateManager.cxx" /> + <ClCompile Include="DialogId.cxx" /> + <ClCompile Include="DialogSet.cxx" /> + <ClCompile Include="DialogSetId.cxx" /> + <ClCompile Include="DialogUsage.cxx" /> + <ClCompile Include="DialogUsageManager.cxx" /> + <ClCompile Include="DumDecrypted.cxx" /> + <ClCompile Include="DumFeature.cxx" /> + <ClCompile Include="DumFeatureChain.cxx" /> + <ClCompile Include="DumFeatureMessage.cxx" /> + <ClCompile Include="DumHelper.cxx" /> + <ClCompile Include="DumProcessHandler.cxx" /> + <ClCompile Include="DumThread.cxx" /> + <ClCompile Include="DumTimeout.cxx" /> + <ClCompile Include="ssl\EncryptionManager.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="EncryptionRequest.cxx" /> + <ClCompile Include="Handle.cxx" /> + <ClCompile Include="Handled.cxx" /> + <ClCompile Include="HandleException.cxx" /> + <ClCompile Include="HandleManager.cxx" /> + <ClCompile Include="HttpGetMessage.cxx" /> + <ClCompile Include="HttpProvider.cxx" /> + <ClCompile Include="IdentityHandler.cxx" /> + <ClCompile Include="InMemoryRegistrationDatabase.cxx" /> + <ClCompile Include="InMemorySyncRegDb.cxx" /> + <ClCompile Include="InviteSession.cxx" /> + <ClCompile Include="InviteSessionCreator.cxx" /> + <ClCompile Include="InviteSessionHandler.cxx" /> + <ClCompile Include="KeepAliveManager.cxx" /> + <ClCompile Include="KeepAliveTimeout.cxx" /> + <ClCompile Include="MasterProfile.cxx" /> + <ClCompile Include="MergedRequestKey.cxx" /> + <ClCompile Include="MergedRequestRemovalCommand.cxx" /> + <ClCompile Include="NetworkAssociation.cxx" /> + <ClCompile Include="NonDialogUsage.cxx" /> + <ClCompile Include="OutgoingEvent.cxx" /> + <ClCompile Include="OutOfDialogReqCreator.cxx" /> + <ClCompile Include="PagerMessageCreator.cxx" /> + <ClCompile Include="Profile.cxx" /> + <ClCompile Include="PublicationCreator.cxx" /> + <ClCompile Include="RedirectManager.cxx" /> + <ClCompile Include="RegistrationCreator.cxx" /> + <ClCompile Include="RegistrationHandler.cxx" /> + <ClCompile Include="ServerAuthManager.cxx" /> + <ClCompile Include="ServerInviteSession.cxx" /> + <ClCompile Include="ServerOutOfDialogReq.cxx" /> + <ClCompile Include="ServerPagerMessage.cxx" /> + <ClCompile Include="ServerPublication.cxx" /> + <ClCompile Include="ServerRegistration.cxx" /> + <ClCompile Include="ServerSubscription.cxx" /> + <ClCompile Include="SubscriptionCreator.cxx" /> + <ClCompile Include="SubscriptionHandler.cxx" /> + <ClCompile Include="SubscriptionState.cxx" /> + <ClCompile Include="TargetCommand.cxx" /> + <ClCompile Include="TlsPeerAuthManager.cxx" /> + <ClCompile Include="UserAuthInfo.cxx" /> + <ClCompile Include="UserProfile.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="AppDialog.hxx" /> + <ClInclude Include="AppDialogSet.hxx" /> + <ClInclude Include="AppDialogSetFactory.hxx" /> + <ClInclude Include="BaseCreator.hxx" /> + <ClInclude Include="BaseSubscription.hxx" /> + <ClInclude Include="BaseUsage.hxx" /> + <ClInclude Include="CertMessage.hxx" /> + <ClInclude Include="ChallengeInfo.hxx" /> + <ClInclude Include="ClientAuthExtension.hxx" /> + <ClInclude Include="ClientAuthManager.hxx" /> + <ClInclude Include="ClientInviteSession.hxx" /> + <ClInclude Include="ClientOutOfDialogReq.hxx" /> + <ClInclude Include="ClientPagerMessage.hxx" /> + <ClInclude Include="ClientPublication.hxx" /> + <ClInclude Include="ClientRegistration.hxx" /> + <ClInclude Include="ClientSubscription.hxx" /> + <ClInclude Include="ContactInstanceRecord.hxx" /> + <ClInclude Include="DefaultServerReferHandler.hxx" /> + <ClInclude Include="DestroyUsage.hxx" /> + <ClInclude Include="Dialog.hxx" /> + <ClInclude Include="DialogEventHandler.hxx" /> + <ClInclude Include="DialogEventInfo.hxx" /> + <ClInclude Include="DialogEventStateManager.hxx" /> + <ClInclude Include="DialogId.hxx" /> + <ClInclude Include="DialogSet.hxx" /> + <ClInclude Include="DialogSetHandler.hxx" /> + <ClInclude Include="DialogSetId.hxx" /> + <ClInclude Include="DialogUsage.hxx" /> + <ClInclude Include="DialogUsageManager.hxx" /> + <ClInclude Include="DumCommand.hxx" /> + <ClInclude Include="DumDecrypted.hxx" /> + <ClInclude Include="DumException.hxx" /> + <ClInclude Include="DumFeature.hxx" /> + <ClInclude Include="DumFeatureChain.hxx" /> + <ClInclude Include="DumFeatureMessage.hxx" /> + <ClInclude Include="DumHelper.hxx" /> + <ClInclude Include="DumProcessHandler.hxx" /> + <ClInclude Include="DumShutdownHandler.hxx" /> + <ClInclude Include="DumThread.hxx" /> + <ClInclude Include="DumTimeout.hxx" /> + <ClInclude Include="ssl\EncryptionManager.hxx" /> + <ClInclude Include="EncryptionRequest.hxx" /> + <ClInclude Include="EventDispatcher.hxx" /> + <ClInclude Include="ExternalTimer.hxx" /> + <ClInclude Include="Handle.hxx" /> + <ClInclude Include="Handled.hxx" /> + <ClInclude Include="HandleException.hxx" /> + <ClInclude Include="HandleManager.hxx" /> + <ClInclude Include="Handles.hxx" /> + <ClInclude Include="HttpGetMessage.hxx" /> + <ClInclude Include="HttpProvider.hxx" /> + <ClInclude Include="IdentityHandler.hxx" /> + <ClInclude Include="InMemoryRegistrationDatabase.hxx" /> + <ClInclude Include="InMemorySyncRegDb.hxx" /> + <ClInclude Include="InviteSession.hxx" /> + <ClInclude Include="InviteSessionCreator.hxx" /> + <ClInclude Include="InviteSessionHandler.hxx" /> + <ClInclude Include="KeepAliveManager.hxx" /> + <ClInclude Include="KeepAliveTimeout.hxx" /> + <ClInclude Include="MasterProfile.hxx" /> + <ClInclude Include="MergedRequestKey.hxx" /> + <ClInclude Include="MergedRequestRemovalCommand.hxx" /> + <ClInclude Include="NetworkAssociation.hxx" /> + <ClInclude Include="NonDialogUsage.hxx" /> + <ClInclude Include="OutgoingEvent.hxx" /> + <ClInclude Include="OutOfDialogHandler.hxx" /> + <ClInclude Include="OutOfDialogReqCreator.hxx" /> + <ClInclude Include="PagerMessageCreator.hxx" /> + <ClInclude Include="PagerMessageHandler.hxx" /> + <ClInclude Include="Postable.hxx" /> + <ClInclude Include="Profile.hxx" /> + <ClInclude Include="PublicationCreator.hxx" /> + <ClInclude Include="PublicationHandler.hxx" /> + <ClInclude Include="RedirectHandler.hxx" /> + <ClInclude Include="RedirectManager.hxx" /> + <ClInclude Include="RefCountedDestroyer.hxx" /> + <ClInclude Include="RegistrationCreator.hxx" /> + <ClInclude Include="RegistrationHandler.hxx" /> + <ClInclude Include="RegistrationPersistenceManager.hxx" /> + <ClInclude Include="RemoteCertStore.hxx" /> + <ClInclude Include="RequestValidationHandler.hxx" /> + <ClInclude Include="ServerAuthManager.hxx" /> + <ClInclude Include="ServerInviteSession.hxx" /> + <ClInclude Include="ServerOutOfDialogReq.hxx" /> + <ClInclude Include="ServerPagerMessage.hxx" /> + <ClInclude Include="ServerPublication.hxx" /> + <ClInclude Include="ServerRegistration.hxx" /> + <ClInclude Include="ServerSubscription.hxx" /> + <ClInclude Include="SubscriptionCreator.hxx" /> + <ClInclude Include="SubscriptionHandler.hxx" /> + <ClInclude Include="SubscriptionPersistenceManager.hxx" /> + <ClInclude Include="SubscriptionState.hxx" /> + <ClInclude Include="TargetCommand.hxx" /> + <ClInclude Include="TlsPeerAuthManager.hxx" /> + <ClInclude Include="UsageUseException.hxx" /> + <ClInclude Include="UserAuthInfo.hxx" /> + <ClInclude Include="UserProfile.hxx" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.filters b/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.filters new file mode 100644 index 00000000..0f299758 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.filters @@ -0,0 +1,546 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="AppDialog.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="AppDialogSet.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="AppDialogSetFactory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BaseCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BaseSubscription.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BaseUsage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="CertMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ChallengeInfo.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientAuthExtension.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientAuthManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientInviteSession.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientOutOfDialogReq.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientPagerMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientPublication.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientRegistration.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ClientSubscription.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ContactInstanceRecord.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DefaultServerReferHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DestroyUsage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Dialog.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogEventInfo.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogEventStateManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogId.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogSet.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogSetId.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogUsage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DialogUsageManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumDecrypted.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumFeature.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumFeatureChain.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumFeatureMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumHelper.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumProcessHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumTimeout.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\EncryptionManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="EncryptionRequest.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Handle.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Handled.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HandleException.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HandleManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HttpGetMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HttpProvider.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="IdentityHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InMemoryRegistrationDatabase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InMemorySyncRegDb.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InviteSession.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InviteSessionCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InviteSessionHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="KeepAliveManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="KeepAliveTimeout.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MasterProfile.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MergedRequestKey.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MergedRequestRemovalCommand.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="NetworkAssociation.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="NonDialogUsage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="OutgoingEvent.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="OutOfDialogReqCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="PagerMessageCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Profile.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="PublicationCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RedirectManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RegistrationCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RegistrationHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerAuthManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerInviteSession.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerOutOfDialogReq.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerPagerMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerPublication.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerRegistration.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerSubscription.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SubscriptionCreator.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SubscriptionHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SubscriptionState.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TargetCommand.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TlsPeerAuthManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UserAuthInfo.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UserProfile.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="AppDialog.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AppDialogSet.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AppDialogSetFactory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BaseCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BaseSubscription.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BaseUsage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CertMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ChallengeInfo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientAuthExtension.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientAuthManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientInviteSession.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientOutOfDialogReq.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientPagerMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientPublication.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientRegistration.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ClientSubscription.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ContactInstanceRecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DefaultServerReferHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DestroyUsage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Dialog.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogEventHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogEventInfo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogEventStateManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogId.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogSet.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogSetHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogSetId.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogUsage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DialogUsageManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumCommand.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumDecrypted.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumException.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumFeature.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumFeatureChain.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumFeatureMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumHelper.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumProcessHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumShutdownHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumTimeout.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\EncryptionManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="EncryptionRequest.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="EventDispatcher.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExternalTimer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Handle.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Handled.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HandleException.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HandleManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Handles.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HttpGetMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HttpProvider.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="IdentityHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InMemoryRegistrationDatabase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InMemorySyncRegDb.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InviteSession.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InviteSessionCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InviteSessionHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="KeepAliveManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="KeepAliveTimeout.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MasterProfile.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MergedRequestKey.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MergedRequestRemovalCommand.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="NetworkAssociation.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="NonDialogUsage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="OutgoingEvent.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="OutOfDialogHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="OutOfDialogReqCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PagerMessageCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PagerMessageHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Postable.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Profile.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PublicationCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PublicationHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RedirectHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RedirectManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RefCountedDestroyer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RegistrationCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RegistrationHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RegistrationPersistenceManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RemoteCertStore.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RequestValidationHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerAuthManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerInviteSession.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerOutOfDialogReq.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerPagerMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerPublication.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerRegistration.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerSubscription.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SubscriptionCreator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SubscriptionHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SubscriptionPersistenceManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SubscriptionState.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TargetCommand.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TlsPeerAuthManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UsageUseException.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserAuthInfo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserProfile.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.user b/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.user new file mode 100644 index 00000000..abe8dd89 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.user @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup /> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.cxx b/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.cxx new file mode 100644 index 00000000..3722c993 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.cxx @@ -0,0 +1,1412 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "resip/dum/ssl/EncryptionManager.hxx" + +#include "resip/stack/ssl/Security.hxx" + +#include <cassert> +#include <list> +#include "rutil/BaseException.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/dum/BaseUsage.hxx" +#include "resip/dum/Handles.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/stack/Contents.hxx" +#include "resip/stack/MultipartSignedContents.hxx" +#include "resip/stack/MultipartMixedContents.hxx" +#include "resip/stack/MultipartAlternativeContents.hxx" +#include "resip/stack/MultipartRelatedContents.hxx" +#include "resip/stack/Pkcs7Contents.hxx" +#include "resip/dum/RemoteCertStore.hxx" +#include "resip/stack/SecurityAttributes.hxx" +#include "resip/dum/CertMessage.hxx" +#include "resip/dum/TargetCommand.hxx" +#include "resip/dum/DumDecrypted.hxx" +#include "resip/dum/DumFeature.hxx" +#include "resip/dum/DumFeatureChain.hxx" +#include "resip/dum/OutgoingEvent.hxx" +#include "resip/dum/DumHelper.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +#if defined(USE_SSL) + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +static bool isAckOrCancelOrBye(const SipMessage& msg) +{ + MethodTypes method = msg.header(h_RequestLine).getMethod(); + return (method == ACK || method == CANCEL || method == BYE); +} + +EncryptionManager::Exception::Exception(const Data& msg, const Data& file, const int line) + : BaseException(msg,file,line) +{ +} + +EncryptionManager::EncryptionManager(DialogUsageManager& dum, TargetCommand::Target& target) + : DumFeature(dum, target) +{ +} + +EncryptionManager::~EncryptionManager() +{ + for (list<Request*>::iterator it = mRequests.begin(); it != mRequests.end(); ++it) + { + delete *it; + } + mRequests.clear(); +} + +void EncryptionManager::setRemoteCertStore(std::auto_ptr<RemoteCertStore> store) +{ + ErrLog(<< "Async currently is not supported"); + assert(0); + //mRemoteCertStore = store; +} + +DumFeature::ProcessingResult EncryptionManager::process(Message* msg) +{ + SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg); + + if (sipMsg) + { + if (sipMsg->getContents()) + { + if (decrypt(sipMsg)) + { + DebugLog(<< "Decrypted message:" << sipMsg << endl); + return DumFeature::FeatureDone; + } + else + { + return DumFeature::EventTaken; + } + } + else + { + return DumFeature::FeatureDone; + } + } + + OutgoingEvent* event = dynamic_cast<OutgoingEvent*>(msg); + if (event) + { + if (!event->message()->getContents()) + { + return DumFeature::FeatureDone; + } + + if (!event->message()->getSecurityAttributes() || + event->message()->getSecurityAttributes()->getOutgoingEncryptionLevel() == SecurityAttributes::None || + event->message()->getSecurityAttributes()->encryptionPerformed()) + { + return DumFeature::FeatureDone; + } + + Data senderAor; + Data recipAor; + if (event->message()->isRequest()) + { + senderAor = event->message()->header(h_From).uri().getAor(); + recipAor = event->message()->header(h_To).uri().getAor(); + } + else + { + senderAor = event->message()->header(h_To).uri().getAor(); + recipAor = event->message()->header(h_From).uri().getAor(); + } + + Contents* contents = event->message()->getContents(); + bool setContents = true; + bool noCerts = false; + + switch (event->message()->getSecurityAttributes()->getOutgoingEncryptionLevel()) + { + case SecurityAttributes::None: + setContents = false; + break; + case SecurityAttributes::Encrypt: + contents = encrypt(event->message(), recipAor, &noCerts); + break; + case SecurityAttributes::Sign: + contents = sign(event->message(), senderAor, &noCerts); + break; + case SecurityAttributes::SignAndEncrypt: + contents = signAndEncrypt(event->message(), senderAor, recipAor, &noCerts); + break; + } + + if (contents) + { + if (setContents) + { + event->message()->setContents(auto_ptr<Contents>(contents)); + DumHelper::setEncryptionPerformed(*event->message()); + } + return DumFeature::FeatureDone; + } + else + { + if (noCerts) + { + return DumFeature::ChainDoneAndEventDone; + } + else + { + //event->releaseMessage(); + return DumFeature::EventTaken; + } + } + } + + // Todo: change CertMessage to DumFeatureMessage. + CertMessage* certMsg = dynamic_cast<CertMessage*>(msg); + if (certMsg) + { + EncryptionManager::Result result = processCertMessage(certMsg); + if (result == Complete) + { + return DumFeature::FeatureDone; + } + else + { + delete msg; + return DumFeature::EventTaken; + } + } + + return DumFeature::FeatureDone; +} + +EncryptionManager::Result EncryptionManager::processCertMessage(CertMessage* message) +{ + InfoLog( << "Received a cert message: " << *message << endl); + Result ret = Pending; + list<Request*>::iterator it; + for (it = mRequests.begin(); it != mRequests.end(); ++it) + { + if ((*it)->getId() == message->id().mId) break; + } + + if (it != mRequests.end()) + { + InfoLog ( << "Processing the cert message" << endl); + ret = (*it)->received(message->success(), message->id().mType, message->id().mAor, message->body()); + if (Complete == ret) + { + delete *it; + mRequests.erase(it); + } + } + + return ret; +} + +Contents* EncryptionManager::sign(SharedPtr<SipMessage> msg, + const Data& senderAor, + bool* noCerts) +{ + Sign* request = new Sign(mDum, mRemoteCertStore.get(), msg, senderAor, *this); + Contents* contents; + *noCerts = false; + bool async = request->sign(&contents, noCerts); + if (async) + { + InfoLog(<< "Async sign" << endl); + //request->setTaken(); + mRequests.push_back(request); + } + else + { + delete request; + } + return contents; +} + +Contents* EncryptionManager::encrypt(SharedPtr<SipMessage> msg, + const Data& recipientAor, + bool* noCerts) +{ + Encrypt* request = new Encrypt(mDum, mRemoteCertStore.get(), msg, recipientAor, *this); + Contents* contents; + *noCerts = false; + bool async = request->encrypt(&contents, noCerts); + if (async) + { + InfoLog(<< "Async encrypt" << endl); + //request->setTaken(); + mRequests.push_back(request); + } + else + { + delete request; + } + return contents; +} + +Contents* EncryptionManager::signAndEncrypt(SharedPtr<SipMessage> msg, + const Data& senderAor, + const Data& recipAor, + bool* noCerts) +{ + SignAndEncrypt* request = new SignAndEncrypt(mDum, mRemoteCertStore.get(), msg, senderAor, recipAor, *this); + Contents* contents; + *noCerts = false; + bool async = request->signAndEncrypt(&contents, noCerts); + if (!async) + { + delete request; + } + else + { + InfoLog(<< "Async sign and encrypt" << endl); + //request->setTaken(); + mRequests.push_back(request); + } + return contents; +} + +bool EncryptionManager::decrypt(SipMessage* msg) +{ + Decrypt* request = new Decrypt(mDum, mRemoteCertStore.get(), msg, *this); + bool ret = true; + + Helper::ContentsSecAttrs csa; + ret = request->decrypt(csa); + + if (ret) + { + if (csa.mContents.get()) + { + msg->setContents(csa.mContents); + + if (csa.mAttributes.get()) + { + // Security Attributes might already exist on the message if the Identity Handler is enabled + // if so, ensure we maintain the Identity Strength + const SecurityAttributes *origSecurityAttributes = msg->getSecurityAttributes(); + if(origSecurityAttributes) + { + csa.mAttributes->setIdentityStrength(origSecurityAttributes->getIdentityStrength()); + } + msg->setSecurityAttributes(csa.mAttributes); + } + } + else + { + // no valid contents. + request->handleInvalidContents(); + + if (msg->isRequest() && !isAckOrCancelOrBye(*msg)) + { + ret = false; + } + } + delete request; + } + else + { + InfoLog(<< "Async decrypt" << endl); + mRequests.push_back(request); + } + + return ret; +} + +EncryptionManager::Request::Request(DialogUsageManager& dum, + RemoteCertStore* store, + SharedPtr<SipMessage> msg, + DumFeature& feature) + : mDum(dum), + mStore(store), + mMsgToEncrypt(msg), + mPendingRequests(0), + mFeature(feature) + //mTaken(false) +{ +} + +EncryptionManager::Request::~Request() +{ + /* + if (mTaken) + { + delete mMsg; + } + */ +} + +void EncryptionManager::Request::response415() +{ + SipMessage* response = Helper::makeResponse(*mMsgToEncrypt, 415); + mDum.post(response); + InfoLog(<< "Generated 415" << endl); +} + +EncryptionManager::Sign::Sign(DialogUsageManager& dum, + RemoteCertStore* store, + SharedPtr<SipMessage> msg, + const Data& senderAor, + DumFeature& feature) + : Request(dum, store, msg, feature), + mSenderAor(senderAor) +{ +} + +EncryptionManager::Sign::~Sign() +{ +} + +bool EncryptionManager::Sign::sign(Contents** contents, bool* noCerts) +{ + *contents = 0; + *noCerts = false; + bool async = false; + + MultipartSignedContents* msc = 0; + bool missingCert = !mDum.getSecurity()->hasUserCert(mSenderAor); + bool missingKey = !mDum.getSecurity()->hasUserPrivateKey(mSenderAor); + + if (!missingCert && !missingKey) + { + InfoLog(<< "Signing message" << endl); + msc = mDum.getSecurity()->sign(mSenderAor, mMsgToEncrypt->getContents()); + *contents = msc; + } + else + { + if (mStore) + { + if (missingCert) + { + InfoLog(<< "Fetching cert for " << mSenderAor << endl); + ++mPendingRequests; + MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserCert); + mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum); + } + if (missingKey) + { + InfoLog(<< "Fetching private key for " << mSenderAor << endl); + ++mPendingRequests; + MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserPrivateKey); + mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum); + } + async = true; + } + else + { + InfoLog(<< "No remote cert store installed" << endl); + *noCerts = true; + response415(); + } + } + + return async; +} + +EncryptionManager::Result EncryptionManager::Sign::received(bool success, + MessageId::Type type, + const Data& aor, + const Data& data) +{ + assert(mSenderAor==aor); + assert(mPendingRequests>0&&mPendingRequests<=2); + Result result = Pending; + + if (success) + { + if (type == MessageId::UserCert) + { + InfoLog(<< "Adding cert for: " << aor << endl); + mDum.getSecurity()->addUserCertDER(aor, data); + } + else + { + InfoLog(<< "Adding private key for " << aor << endl); + mDum.getSecurity()->addUserPrivateKeyDER(aor, data); + } + if (--mPendingRequests == 0) + { + InfoLog(<< "Signing message" << endl); + MultipartSignedContents* msc = mDum.getSecurity()->sign(aor, mMsgToEncrypt->getContents()); + mMsgToEncrypt->setContents(auto_ptr<Contents>(msc)); + DumHelper::setEncryptionPerformed(*mMsgToEncrypt); + OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt); + //mTaken = false; + mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), auto_ptr<Message>(event))); + result = Complete; + } + } + else + { + InfoLog(<< "Failed to fetch " << ((type==MessageId::UserCert)? "cert " : "private key ") << "for " << aor <<endl); + response415(); + result = Complete; + } + return result; +} + +EncryptionManager::Encrypt::Encrypt(DialogUsageManager& dum, + RemoteCertStore* store, + SharedPtr<SipMessage> msg, + const Data& recipientAor, + DumFeature& feature) + : Request(dum, store, msg, feature), + mRecipientAor(recipientAor) +{ +} + +EncryptionManager::Encrypt::~Encrypt() +{ +} + +bool EncryptionManager::Encrypt::encrypt(Contents** contents, bool* noCerts) +{ + *contents = 0; + *noCerts = false; + bool async = false; + + if (mDum.getSecurity()->hasUserCert(mRecipientAor)) + { + InfoLog(<< "Encrypting message" << endl); + MultipartAlternativeContents* alt = dynamic_cast<MultipartAlternativeContents*>(mMsgToEncrypt->getContents()); + if (alt) + { + // encrypt the last part. + MultipartMixedContents::Parts parts = alt->parts(); + Contents* last = mDum.getSecurity()->encrypt(parts.back(), mRecipientAor); + if (last) + { + MultipartAlternativeContents* mac = new MultipartAlternativeContents(*alt); + delete mac->parts().back(); + mac->parts().pop_back(); + mac->parts().push_back(last); + *contents = mac; + } + } + else + { + *contents = mDum.getSecurity()->encrypt(mMsgToEncrypt->getContents(), mRecipientAor); + } + } + else + { + if (mStore) + { + InfoLog(<< "Fetching cert for " << mRecipientAor << endl); + ++mPendingRequests; + MessageId id(mMsgToEncrypt->getTransactionId(), mRecipientAor, MessageId::UserCert); + mStore->fetch(mRecipientAor, MessageId::UserCert, id, mDum); + async = true; + } + else + { + InfoLog(<< "No remote cert store installed" << endl); + *noCerts = true; + response415(); + } + } + return async; +} + +EncryptionManager::Result EncryptionManager::Encrypt::received(bool success, + MessageId::Type type, + const Data& aor, + const Data& data) +{ + assert(mRecipientAor==aor); + assert(type==MessageId::UserCert); + assert(mPendingRequests==1); + if (success) + { + InfoLog(<< "Adding user cert for " << aor << endl); + mDum.getSecurity()->addUserCertDER(aor, data); + --mPendingRequests; + InfoLog(<< "Encrypting message" << endl); + Pkcs7Contents* encrypted = mDum.getSecurity()->encrypt(mMsgToEncrypt->getContents(), aor); + mMsgToEncrypt->setContents(auto_ptr<Contents>(encrypted)); + DumHelper::setEncryptionPerformed(*mMsgToEncrypt); + OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt); + //mTaken = false; + mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), auto_ptr<Message>(event))); + } + else + { + InfoLog(<< "Failed to fetch cert for " << aor << endl); + response415(); + } + return Complete; +} + +EncryptionManager::SignAndEncrypt::SignAndEncrypt(DialogUsageManager& dum, + RemoteCertStore* store, + SharedPtr<SipMessage> msg, + const Data& senderAor, + const Data& recipientAor, + DumFeature& feature) + : Request(dum, store, msg, feature), + mSenderAor(senderAor), + mRecipientAor(recipientAor) +{ +} + +EncryptionManager::SignAndEncrypt::~SignAndEncrypt() +{ +} + +bool EncryptionManager::SignAndEncrypt::signAndEncrypt(Contents** contents, bool* noCerts) +{ + *contents = 0; + *noCerts = false; + bool async = false; + bool missingCert = !mDum.getSecurity()->hasUserCert(mSenderAor); + bool missingKey = !mDum.getSecurity()->hasUserPrivateKey(mSenderAor); + bool missingRecipCert = !mDum.getSecurity()->hasUserCert(mRecipientAor); + + if (!missingCert && !missingKey && !missingRecipCert) + { + InfoLog(<< "Encrypting and signing message" << endl); + *contents = doWork(); + } + else + { + if (mStore) + { + if (missingCert) + { + InfoLog(<< "Fetching cert for " << mSenderAor << endl); + ++mPendingRequests; + MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserCert); + mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum); + } + if (missingKey) + { + InfoLog(<< "Fetching private key for " << mSenderAor << endl); + ++mPendingRequests; + MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserPrivateKey); + mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum); + } + if (missingRecipCert) + { + InfoLog(<< "Fetching cert for " << mRecipientAor << endl); + ++mPendingRequests; + MessageId id(mMsgToEncrypt->getTransactionId(), mRecipientAor, MessageId::UserCert); + mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum); + } + async = true; + } + else + { + InfoLog(<< "No remote cert store installed" << endl); + *noCerts = true; + response415(); + } + } + + return async; +} + +EncryptionManager::Result EncryptionManager::SignAndEncrypt::received(bool success, + MessageId::Type type, + const Data& aor, + const Data& data) +{ + assert(mPendingRequests>0&&mPendingRequests<=3); + Result result = Pending; + if (success) + { + if (type == MessageId::UserCert) + { + assert(aor==mSenderAor||aor==mRecipientAor); + InfoLog(<< "Adding user cert for " << aor << endl); + mDum.getSecurity()->addUserCertDER(aor, data); + } + else + { + assert(aor==mSenderAor); + InfoLog(<< "Adding private key for " << aor << endl); + mDum.getSecurity()->addUserPrivateKeyDER(aor, data); + } + + if (--mPendingRequests == 0) + { + InfoLog(<< "Encrypting and signing message" << endl); + Contents* contents = doWork(); + mMsgToEncrypt->setContents(auto_ptr<Contents>(contents)); + DumHelper::setEncryptionPerformed(*mMsgToEncrypt); + OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt); + //mTaken = false; + mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), auto_ptr<Message>(event))); + result = Complete; + } + } + else + { + InfoLog(<< "Failed to fetch cert for " << aor << endl); + response415(); + result = Complete; + } + return result; +} + +Contents* EncryptionManager::SignAndEncrypt::doWork() +{ + Contents* contents = 0; + MultipartAlternativeContents* mac = dynamic_cast<MultipartAlternativeContents*>(mMsgToEncrypt->getContents()); + if (mac) + { + MultipartMixedContents::Parts parts = mac->parts(); + Pkcs7Contents* pkcs7 = mDum.getSecurity()->encrypt(parts.back(), mRecipientAor); + if (pkcs7) + { + MultipartAlternativeContents* alt = new MultipartAlternativeContents(*mac); + delete alt->parts().back(); + alt->parts().pop_back(); + alt->parts().push_back(pkcs7); + contents = alt; + } + } + else + { + contents = mDum.getSecurity()->encrypt(mMsgToEncrypt->getContents() , mRecipientAor); + } + + if (contents) + { + contents = mDum.getSecurity()->sign(mSenderAor, contents); + } + + return contents; +} + +EncryptionManager::Decrypt::Decrypt(DialogUsageManager& dum, + RemoteCertStore* store, + SipMessage* msg, + DumFeature& feature) + : Request(dum, store, SharedPtr<SipMessage>(), feature), + mIsEncrypted(false), + mMsgToDecrypt(msg), + mMessageTaken(false) +{ + if (msg->isResponse()) + { + mDecryptor = msg->header(h_From).uri().getAor(); + mSigner = msg->header(h_To).uri().getAor(); + } + else + { + mDecryptor = msg->header(h_To).uri().getAor(); + mSigner = msg->header(h_From).uri().getAor(); + } +} + +EncryptionManager::Decrypt::~Decrypt() +{ + if (mMessageTaken) + { + delete mMsgToDecrypt; + } +} + +bool EncryptionManager::Decrypt::decrypt(Helper::ContentsSecAttrs& csa) +{ + bool noDecryptionKey = false; + + if (!dynamic_cast<Pkcs7Contents*>(mMsgToDecrypt->getContents())) + { + mOriginalMsgContents = Data(mMsgToDecrypt->getContents()->getHeaderField().getBuffer(), mMsgToDecrypt->getContents()->getHeaderField().getLength()); + mOriginalMsgContentsType = mMsgToDecrypt->getContents()->getType(); + } + else + { + mIsEncrypted = true; + } + + if (isEncrypted()) + { + bool missingDecryptorCert = !mDum.getSecurity()->hasUserCert(mDecryptor); + bool missingDecryptorKey = !mDum.getSecurity()->hasUserPrivateKey(mDecryptor); + if (missingDecryptorCert || missingDecryptorKey) + { + if (mStore) + { + if (missingDecryptorCert) + { + InfoLog(<< "Fetching user cert for " << mDecryptor << endl); + ++mPendingRequests; + MessageId id(mMsgToDecrypt->getTransactionId(), mDecryptor, MessageId::UserCert); + mStore->fetch(mDecryptor, MessageId::UserCert, id, mDum); + } + + if (missingDecryptorKey) + { + InfoLog(<< "Fetching private key for " << mDecryptor << endl); + ++mPendingRequests; + MessageId id(mMsgToDecrypt->getTransactionId(), mDecryptor, MessageId::UserPrivateKey); + mStore->fetch(mDecryptor, MessageId::UserPrivateKey, id, mDum); + } + mMessageTaken = true; + return false; + } + else + { + InfoLog(<< "No remote cert store installed" << endl); + noDecryptionKey = true; + } + } + } + + if (isSigned(noDecryptionKey)) + { + if (!mDum.getSecurity()->hasUserCert(mSigner)) + { + if (mStore) + { + InfoLog(<< "Fetching user cert for " << mSigner << endl); + ++mPendingRequests; + MessageId id(mMsgToDecrypt->getTransactionId(), mSigner, MessageId::UserCert); + mStore->fetch(mSigner, MessageId::UserCert, id, mDum); + mMessageTaken = true; + return false; + } + else + { + InfoLog(<< "No remote cert store installed" << endl); + } + } + } + + csa = getContents(mMsgToDecrypt, *mDum.getSecurity(), noDecryptionKey); + return true; +} + +EncryptionManager::Result EncryptionManager::Decrypt::received(bool success, + MessageId::Type type, + const Data& aor, + const Data& data) +{ + Result result = Complete; + assert(mPendingRequests>0 && mPendingRequests<=2); + if (success) + { + if (aor == mSigner) + { + assert(MessageId::UserCert == type); + assert(mPendingRequests==1); + --mPendingRequests; + InfoLog(<< "Adding user cert for " << aor << endl); + mDum.getSecurity()->addUserCertDER(aor, data); + } + else + { + assert(aor == mDecryptor); + if (MessageId::UserCert == type) + { + InfoLog(<< "Adding user cert for " << aor << endl); + mDum.getSecurity()->addUserCertDER(aor, data); + } + else + { + InfoLog(<< "Adding private key for " << aor << endl); + mDum.getSecurity()->addUserPrivateKeyDER(aor, data); + } + + if (--mPendingRequests == 0) + { + if (isSigned(false)) + { + if (!mDum.getSecurity()->hasUserCert(mSigner)) + { + InfoLog(<< "Fetching user cert for " << mSigner << endl); + ++mPendingRequests; + MessageId id(mMsgToDecrypt->getTransactionId(), mSigner, MessageId::UserCert); + mStore->fetch(mSigner, MessageId::UserCert, id, mDum); + result = Pending; + } + } + } + else + { + result = Pending; + } + } + } + else + { + InfoLog(<< "Failed to fetch cert for " << aor << endl); + } + + if (Complete == result) + { + Helper::ContentsSecAttrs csa; + csa = getContents(mMsgToDecrypt, *mDum.getSecurity(), + (!mDum.getSecurity()->hasUserCert(mDecryptor) || !mDum.getSecurity()->hasUserPrivateKey(mDecryptor))); + + + if (csa.mContents.get()) + { + csa.mContents->checkParsed(); + mMsgToDecrypt->setContents(csa.mContents); + + if (csa.mAttributes.get()) + { + mMsgToDecrypt->setSecurityAttributes(csa.mAttributes); + } + } + else + { + // no valid contents. + ErrLog(<< "No valid contents in message received" << endl); + handleInvalidContents(); + + if (mMsgToDecrypt->isRequest() && !isAckOrCancelOrBye(*mMsgToDecrypt)) + { + return result; + } + } + + // Todo: make CertMessage DumFeatureMessage and get rid of DumDecrypted. + // Currently the message will not be processed by + // any features in the chain after EncryptionManager. + DumDecrypted* decrypted = new DumDecrypted(*mMsgToDecrypt); + mDum.post(decrypted); + } + + return result; +} + +bool EncryptionManager::Decrypt::isEncrypted() +{ + Contents* contents = mMsgToDecrypt->getContents(); + return isEncryptedRecurse(&contents); +} + +bool EncryptionManager::Decrypt::isSigned(bool noDecryptionKey) +{ + Contents* contents = mMsgToDecrypt->getContents(); + return isSignedRecurse(&contents, mDecryptor, noDecryptionKey); +} + +bool EncryptionManager::Decrypt::isEncryptedRecurse(Contents** contents) +{ + InvalidContents* ic; + if ((ic = dynamic_cast<InvalidContents*>(*contents))) + { + return false; + } + + Pkcs7Contents* pk; + if ((pk = dynamic_cast<Pkcs7Contents*>(*contents))) + { + return true; + } + + MultipartSignedContents* mps; + if ((mps = dynamic_cast<MultipartSignedContents*>(*contents))) + { + try + { + mps->parts(); + } + catch (BaseException& e) + { + // structure of multipart is bad. this is unrecoverable error, + // replace the whole multipart contents with an InvalidContents. + ErrLog(<< e.name() << endl << e.getMessage()); + + if (*contents == mMsgToDecrypt->getContents()) + { + mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(mps))); + } + else + { + *contents = createInvalidContents(mps); + delete mps; + } + return false; + } + + return isEncryptedRecurse(&(*(mps->parts().begin()))); + } + + MultipartAlternativeContents* alt = dynamic_cast<MultipartAlternativeContents*>(*contents); + if (alt) + { + try + { + alt->parts(); + } + catch (BaseException& e) + { + ErrLog(<< e.name() << endl << e.getMessage()); + if (*contents == mMsgToDecrypt->getContents()) + { + mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(alt))); + } + else + { + *contents = createInvalidContents(alt); + delete alt; + } + return false; + } + + for (MultipartAlternativeContents::Parts::reverse_iterator i = alt->parts().rbegin(); + i != alt->parts().rend(); ++i) + { + if (isEncryptedRecurse(&(*i))) + { + return true; + } + } + + return false; + } + + if (dynamic_cast<MultipartMixedContents*>(*contents)) + { + return false; + } + + return false; +} + +bool EncryptionManager::Decrypt::isSignedRecurse(Contents** contents, + const Data& decryptorAor, + bool noDecryptionKey) +{ + InvalidContents* ic; + if ((ic = dynamic_cast<InvalidContents*>(*contents))) + { + return false; + } + + Pkcs7Contents* pk; + if ((pk = dynamic_cast<Pkcs7Contents*>(*contents))) + { + if (noDecryptionKey) + { + return false; + } + + Contents* decrypted = mDum.getSecurity()->decrypt(decryptorAor, pk); + bool ret = false; + + if (decrypted) + { + if (*contents == mMsgToDecrypt->getContents()) + { + mOriginalMsgContents = Data(decrypted->getHeaderField().getBuffer(), decrypted->getHeaderField().getLength()); + mOriginalMsgContentsType = decrypted->getType(); + } + + try + { + decrypted->checkParsed(); + if (isMultipart(decrypted)) + { + if (dynamic_cast<MultipartSignedContents*>(decrypted)) + { + ret = true; + } + else + { + if (*contents == mMsgToDecrypt->getContents()) + { + mMsgToDecrypt->setContents(auto_ptr<Contents>(decrypted)); + *contents = mMsgToDecrypt->getContents(); + } + else + { + *contents = decrypted; + delete pk; + } + return isSignedRecurse(contents, decryptorAor, noDecryptionKey); + } + } + } + catch (BaseException& e) + { + ErrLog(<< e.name() << endl << e.getMessage()); + + if (*contents == mMsgToDecrypt->getContents()) + { + mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(decrypted))); + } + else + { + *contents = createInvalidContents(decrypted); + delete pk; + } + } + + delete decrypted; + } + + return ret; + } + + MultipartSignedContents* mps; + if ((mps = dynamic_cast<MultipartSignedContents*>(*contents))) + { + return true; + } + + MultipartAlternativeContents* alt = dynamic_cast<MultipartAlternativeContents*>(*contents); + if (alt) + { + try + { + alt->parts(); + } + catch (BaseException& e) + { + // structure of multipart is bad. this is unrecoverable error, + // replace the whole multipart contents with an InvalidContents. + ErrLog(<< e.name() << endl << e.getMessage()); + + if (*contents == mMsgToDecrypt->getContents()) + { + mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(alt))); + } + else + { + *contents = createInvalidContents(alt); + delete alt; + } + + return false; + } + + for (MultipartAlternativeContents::Parts::reverse_iterator i = alt->parts().rbegin(); + i != alt->parts().rend(); ++i) + { + if (isSignedRecurse(&(*i), decryptorAor, noDecryptionKey)) + { + return true; + } + } + + return false; + } + + if (dynamic_cast<MultipartMixedContents*>(*contents)) + { + return false; + } + + return false; +} + +Helper::ContentsSecAttrs EncryptionManager::Decrypt::getContents(SipMessage* message, + Security& security, + bool noDecryptionKey) +{ + SecurityAttributes* attr = new SecurityAttributes; + attr->setIdentity(message->header(h_From).uri().getAor()); + Contents* contents = message->getContents(); + if (contents) + { + contents = getContentsRecurse(&contents, security, noDecryptionKey, attr); + } + + if (contents) + { + if (mIsEncrypted) + { + attr->setEncrypted(); + } + } + + std::auto_ptr<Contents> c(contents); + std::auto_ptr<SecurityAttributes> a(attr); + return Helper::ContentsSecAttrs(c, a); +} + +Contents* EncryptionManager::Decrypt::getContentsRecurse(Contents** tree, + Security& security, + bool noDecryptionKey, + SecurityAttributes* attributes) +{ + InvalidContents* ic; + if ((ic = dynamic_cast<InvalidContents*>(*tree))) + { + return 0; + } + + Pkcs7Contents* pk; + if ((pk = dynamic_cast<Pkcs7Contents*>(*tree))) + { + if (noDecryptionKey) + { + return 0; + } + + Contents* contents = security.decrypt(mDecryptor, pk); + if (contents) + { + if (*tree == mMsgToDecrypt->getContents()) + { + mOriginalMsgContents = Data(contents->getHeaderField().getBuffer(), contents->getHeaderField().getLength()); + mOriginalMsgContentsType = contents->getType(); + } + + try + { + contents->checkParsed(); + if (isMultipart(contents)) + { + if (*tree == mMsgToDecrypt->getContents()) + { + mMsgToDecrypt->setContents(auto_ptr<Contents>(contents)); + *tree = mMsgToDecrypt->getContents(); + } + else + { + *tree = contents; + delete pk; + } + + return getContentsRecurse(tree, security, noDecryptionKey, attributes); + } + else + { + attributes->setEncrypted(); + } + } + catch (BaseException& e) + { + ErrLog(<< e.name() << endl << e.getMessage()); + + if (*tree == mMsgToDecrypt->getContents()) + { + mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(contents))); + } + else + { + *tree = createInvalidContents(contents); + delete pk; + } + + delete contents; + return 0; + } + } + + return contents; + } + + MultipartSignedContents* mps; + if ((mps = dynamic_cast<MultipartSignedContents*>(*tree))) + { + Data signer; + SignatureStatus sigStatus = SignatureIsBad; + Contents* tmp = security.checkSignature(mps, &signer, &sigStatus); + Contents* contents = getContentsRecurse(&tmp, + security, noDecryptionKey, attributes); + attributes->setSigner(signer); + attributes->setSignatureStatus(sigStatus); + return contents; + } + + MultipartAlternativeContents* alt; + if ((alt = dynamic_cast<MultipartAlternativeContents*>(*tree))) + { + try + { + alt->parts(); + } + catch (BaseException& e) + { + // structure of multipart is bad. this is an unrecoverable error, + // replace the whole multipart contents with an InvalidContents. + ErrLog(<< e.name() << endl << e.getMessage()); + + if (*tree == mMsgToDecrypt->getContents()) + { + mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(alt))); + } + else + { + *tree = createInvalidContents(alt); + delete alt; + } + + return 0; + } + + for (MultipartAlternativeContents::Parts::reverse_iterator i = alt->parts().rbegin(); + i != alt->parts().rend(); ++i) + { + Contents* contents = getContentsRecurse(&(*i), security, noDecryptionKey, attributes); + if (contents) + { + return contents; + } + } + + return 0; + } + + MultipartMixedContents* mult; + if ((mult = dynamic_cast<MultipartMixedContents*>(*tree))) + { + try + { + mult->parts(); + } + catch (BaseException& e) + { + // structure of multipart is bad. this is unrecoverable error, + // replace the whole multipart contents with an InvalidContents. + ErrLog(<< e.name() << endl << e.getMessage()); + + if (*tree == mMsgToDecrypt->getContents()) + { + mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(mult))); + } + else + { + *tree = createInvalidContents(mult); + delete mult; + } + + return 0; + } + + // for now, the multipart/mixed is returned untouched. + return mult->clone(); + } + + Contents* ret = 0; + + try + { + (*tree)->checkParsed(); + ret = (*tree)->clone(); + } + catch (BaseException& e) + { + ErrLog(<< e.name() << endl << e.getMessage()); + + if (*tree == mMsgToDecrypt->getContents()) + { + mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(*tree))); + } + else + { + Contents* tmp = *tree; + *tree = createInvalidContents(*tree); + delete tmp; + } + } + + return ret; + +} + +// Todo: move to DumHelper. +InvalidContents* +EncryptionManager::Decrypt::createInvalidContents(Contents* orig) +{ + Data original(orig->getHeaderField().getBuffer(), orig->getHeaderField().getLength()); + return new InvalidContents(original, orig->getType()); +} + +bool +EncryptionManager::Decrypt::isMultipart(Contents* contents) +{ + return ( + dynamic_cast<MultipartSignedContents*>(contents) || + dynamic_cast<MultipartAlternativeContents*>(contents) || + dynamic_cast<MultipartMixedContents*>(contents) + ); +} + +void +EncryptionManager::Decrypt::handleInvalidContents() +{ + if (mMsgToDecrypt->isRequest()) + { + if (isAckOrCancelOrBye(*mMsgToDecrypt)) + { + DebugLog(<< "No valid contents in the request" << endl); + InvalidContents* invalid = new InvalidContents(mOriginalMsgContents, mOriginalMsgContentsType); + mMsgToDecrypt->setContents(auto_ptr<Contents>(invalid)); + } + else + { + DebugLog(<< "No valid contents in the request -- reject with 400" << endl); + SipMessage response; + Helper::makeResponse(response, *mMsgToDecrypt, 400, Data::Empty, mMsgToDecrypt->header(h_RequestLine).uri().host() , "Invalid message body"); + mDum.getSipStack().send(response); + } + } + else + { + DebugLog(<< "No valid contents in the response" << endl); + InvalidContents* invalid = new InvalidContents(mOriginalMsgContents, mOriginalMsgContentsType); + mMsgToDecrypt->setContents(auto_ptr<Contents>(invalid)); + } +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.hxx b/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.hxx new file mode 100644 index 00000000..10015e89 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.hxx @@ -0,0 +1,204 @@ +#if !defined(RESIP_ENCRYPTIONMANAGER_HXX) +#define RESIP_ENCRYPTIONMANAGER_HXX + +#include <memory> + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "rutil/SharedPtr.hxx" +#include "rutil/Data.hxx" +#include "rutil/BaseException.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Contents.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/dum/CertMessage.hxx" +#include "resip/dum/RemoteCertStore.hxx" +#include "resip/dum/DumFeature.hxx" +#include "resip/stack/InvalidContents.hxx" + +namespace resip +{ +class Security; + +class EncryptionManager : public DumFeature +{ + public: + class Exception : public BaseException + { + public: + Exception(const Data& msg, const Data& file, const int line); + const char* name() const { return "EncryptionManagerException"; } + }; + + EncryptionManager(DialogUsageManager& dum, TargetCommand::Target& target); + virtual ~EncryptionManager(); + void setRemoteCertStore(std::auto_ptr<RemoteCertStore> store); + virtual DumFeature::ProcessingResult process(Message* msg); + + private: + + typedef enum + { + Pending, + Complete + } Result; + + EncryptionManager::Result processCertMessage(CertMessage* cert); + Contents* sign(SharedPtr<SipMessage> msg, const Data& senderAor, bool* noCerts); + Contents* encrypt(SharedPtr<SipMessage> msg, const Data& recipientAor, bool* noCerts); + Contents* signAndEncrypt(SharedPtr<SipMessage> msg, const Data& senderAor, const Data& recipientAor, bool* noCerts); + bool decrypt(SipMessage* msg); + + class Request + { + public: + Request(DialogUsageManager& dum, RemoteCertStore* store, SharedPtr<SipMessage> msg, DumFeature& feature); + virtual ~Request(); + virtual Result received(bool success, MessageId::Type type, const Data& aor, const Data& data) = 0; + Data getId() const { return mMsgToEncrypt->getTransactionId(); } + //void setTaken() { mTaken = true; } + //void handleInvalidContents(SipMessage*, const Data& originalBody, const Mime& originalType); + + protected: + DialogUsageManager& mDum; + RemoteCertStore* mStore; + SharedPtr<SipMessage> mMsgToEncrypt; // initial message. + int mPendingRequests; + DumFeature& mFeature; + //bool mTaken; + + void response415(); + }; + + class Sign : public Request + { + public: + Sign(DialogUsageManager& dum, RemoteCertStore* store, SharedPtr<SipMessage> msg, const Data& senderAor, DumFeature& feature); + virtual ~Sign(); + Result received(bool success, MessageId::Type type, const Data& aor, const Data& data); + bool sign(Contents**, bool* noCerts); + + protected: + Data mSenderAor; + }; + + class Encrypt : public Request + { + public: + Encrypt(DialogUsageManager& dum, RemoteCertStore* store, SharedPtr<SipMessage> msg, const Data& recipientAor, DumFeature& feature); + virtual ~Encrypt(); + Result received(bool success, MessageId::Type type, const Data& aor, const Data& data); + bool encrypt(Contents**, bool* noCerts); + + protected: + Data mRecipientAor; + }; + + class SignAndEncrypt : public Request + { + public: + SignAndEncrypt(DialogUsageManager& dum, RemoteCertStore* store, SharedPtr<SipMessage> msg, const Data& senderAor, const Data& recipientAor, DumFeature& feature); + ~SignAndEncrypt(); + Result received(bool success, MessageId::Type type, const Data& aor, const Data& data); + bool signAndEncrypt(Contents**, bool* noCerts); + + protected: + Data mSenderAor; + Data mRecipientAor; + + private: + Contents* doWork(); + }; + + class Decrypt : public Request + { + public: + Decrypt(DialogUsageManager& dum, RemoteCertStore* store, SipMessage* msg, DumFeature& feature); + virtual ~Decrypt(); + Result received(bool success, MessageId::Type type, const Data& aor, const Data& data); + bool decrypt(Helper::ContentsSecAttrs& csa); + const Mime& getOriginalContentsType() const { return mOriginalMsgContentsType; } + const Data& getOriginalContents() const { return mOriginalMsgContents; } + void handleInvalidContents(); + Data getId() const { return mMsgToDecrypt->getTransactionId(); } + + private: + bool isEncrypted(); + bool isSigned(bool noDecryptionKey); + bool isEncryptedRecurse(Contents**); + bool isSignedRecurse(Contents**, const Data& decryptorAor, bool noDecryptionKey); + Helper::ContentsSecAttrs getContents(SipMessage* msg, Security& security, bool noDecryption); + Contents* getContentsRecurse(Contents**, Security&, bool, SecurityAttributes* attr); + InvalidContents* createInvalidContents(Contents*); + bool isMultipart(Contents*); + Data mDecryptor; + Data mSigner; + Data mOriginalMsgContents; + Mime mOriginalMsgContentsType; + bool mIsEncrypted; // the whole body is encrypted in original message. + SipMessage* mMsgToDecrypt; // original messge. + bool mMessageTaken; + }; + + std::auto_ptr<RemoteCertStore> mRemoteCertStore; + + typedef std::list<Request*> RequestList; + RequestList mRequests; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/recon/BridgeMixer.cxx b/src/libs/resiprocate/resip/recon/BridgeMixer.cxx new file mode 100644 index 00000000..8f7b3c58 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/BridgeMixer.cxx @@ -0,0 +1,185 @@ +#include "BridgeMixer.hxx" +#include "ReconSubsystem.hxx" +#include "Participant.hxx" +#include "RemoteParticipant.hxx" +#include "Conversation.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> + +#ifndef max +#define max(x,y) (((x)>(y))?(x):(y)) +#endif + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +BridgeMixer::BridgeMixer(CpMediaInterface& mediaInterface) : + mMediaInterface(mediaInterface) +{ + // Set default to 0 gain for entire matrix + memset(mMixMatrix, 0, sizeof(mMixMatrix)); +} + +BridgeMixer::~BridgeMixer() +{ +} + +void +BridgeMixer::calculateMixWeightsForParticipant(Participant* participant) +{ + int bridgePort = participant->getConnectionPortOnBridge(); + MpBridgeGain inputBridgeWeights[DEFAULT_BRIDGE_MAX_IN_OUTPUTS]; + + InfoLog( << "calculatingMixWeigthsForParticipant, handle=" << participant->getParticipantHandle() << ", bridgePort=" << bridgePort); + + if(bridgePort != -1) + { + // Default All Inputs/Outputs to 0, then calculate non-zero inputs/outputs + for(int i = 0; i < DEFAULT_BRIDGE_MAX_IN_OUTPUTS; i++) + { + mMixMatrix[i][bridgePort] = 0; + inputBridgeWeights[i] = 0; + mMixMatrix[bridgePort][i] = 0; + } + + // Walk through all Conversations this Participant is in + const Participant::ConversationMap& partConvs = participant->getConversations(); + + Participant::ConversationMap::const_iterator it1; + for(it1 = partConvs.begin(); it1 != partConvs.end(); it1++) + { + //InfoLog( << "calculateMixWeightsForParticipant: part=" << participant->getParticipantHandle() << ", conv=" << it1->second->getHandle()); + // Walk through each participant in this Conversation + Conversation::ParticipantMap& convParts = it1->second->getParticipants(); + Conversation::ParticipantMap::iterator it2; + it2 = convParts.find(participant->getParticipantHandle()); // Get the participants gain settings in this conversation + unsigned int participantOutputGain = 0; + unsigned int participantInputGain = 0; + if(it2 != convParts.end()) // if we are in the middle of removing a participant from a conversation then they may not exist in the conversation list any more + { + participantOutputGain = it2->second.getOutputGain(); + participantInputGain = it2->second.getInputGain(); + } + for(it2 = convParts.begin(); it2 != convParts.end(); it2++) + { + //InfoLog( << "calculateMixWeightsForParticipant: part=" << participant->getParticipantHandle() << ", conv=" << it1->second->getHandle() << ", part=" << it2->second.getParticipant()->getParticipantHandle()); + // If we found a participant that is not ourself + if(it2->second.getParticipant()->getParticipantHandle() != participant->getParticipantHandle()) + { + int otherBridgePort = it2->second.getParticipant()->getConnectionPortOnBridge(); + if(otherBridgePort != -1 && otherBridgePort != bridgePort) // Note otherBridgePort can equal bridge port if multiple media participants of the same type exist + { + //InfoLog( << "Setting mix level for bridge ports: " << bridgePort << " and " << otherBridgePort); + // Calculate the mixed output gain + unsigned int outputGain = ((it2->second.getOutputGain() * participantInputGain) / 100) * 10; // 10 factor is to bring inline with MrpBridgeWeight int type + mMixMatrix[bridgePort][otherBridgePort] = max((int)outputGain, mMixMatrix[bridgePort][otherBridgePort]); + + // Calculate the mixed input gain + unsigned int inputGain = ((it2->second.getInputGain() * participantOutputGain) / 100) * 10; // 10 factor is to bring inline with MrpBridgeWeight int type + inputBridgeWeights[otherBridgePort] = mMixMatrix[otherBridgePort][bridgePort] = max((int)inputGain, mMixMatrix[otherBridgePort][bridgePort]); + } + } + } + } + + //outputBridgeMixWeights(); + + // Apply new bridge weights + MprBridge::setMixWeightsForOutput(DEFAULT_BRIDGE_RESOURCE_NAME, *mMediaInterface.getMsgQ(), bridgePort, DEFAULT_BRIDGE_MAX_IN_OUTPUTS, mMixMatrix[bridgePort]); + MprBridge::setMixWeightsForInput(DEFAULT_BRIDGE_RESOURCE_NAME, *mMediaInterface.getMsgQ(), bridgePort, DEFAULT_BRIDGE_MAX_IN_OUTPUTS, inputBridgeWeights); + } +} + +void +BridgeMixer::outputBridgeMixWeights() +{ + int i; + Data data; + data = " "; + for(i = 0; i < DEFAULT_BRIDGE_MAX_IN_OUTPUTS; i++) + { + if(i < 10) + { + data += " " + Data(i); + } + else + { + data += " " + Data(i); + } + } + InfoLog( << data); + + data = "-"; + for(i = 0; i < DEFAULT_BRIDGE_MAX_IN_OUTPUTS; i++) + { + data += "----"; + } + InfoLog( << data); + + for(i = 0; i < DEFAULT_BRIDGE_MAX_IN_OUTPUTS; i++) + { + if(i < 10) + { + data = Data(i) + " |"; + } + else + { + data = Data(i) + "|"; + } + for(int j = 0; j < DEFAULT_BRIDGE_MAX_IN_OUTPUTS; j++) + { + if(mMixMatrix[i][j]/10 < 10) + { + data += " " + Data(mMixMatrix[i][j]/10) + " "; + } + else if(mMixMatrix[i][j]/10 < 100) + { + data += Data(mMixMatrix[i][j]/10) + " "; + } + else + { + data += Data(mMixMatrix[i][j]/10) + " "; + } + } + InfoLog( << data); + } +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/BridgeMixer.hxx b/src/libs/resiprocate/resip/recon/BridgeMixer.hxx new file mode 100644 index 00000000..5ce6ab39 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/BridgeMixer.hxx @@ -0,0 +1,92 @@ +#if !defined(BridgeMixer_hxx) +#define BridgeMixer_hxx + +#include <mp/MprBridge.h> +#include <mp/MpResourceTopology.h> +#include <mi/CpMediaInterface.h> + +namespace recon +{ +class ConversationManager; +class Participant; + +/** + This class is used to control the sipX Bridge Mixer mix matrix. + + If there is ever a change required in the mixer bridge, the + application should call calculateMixWeightsForParticipant + in order to have the changes detected and applied. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class BridgeMixer +{ +public: + /** + Constructor + + @param mediaInterface + */ + BridgeMixer(CpMediaInterface& mediaInterface); + virtual ~BridgeMixer(); + + /** + Calculates all of the current mixer settings required + for the passed in participant and applies them. + Calculations are based off of Participants membership + into Conversations and the input/output gain settings. + + @param participant Participant to calculate mixer weights for + */ + void calculateMixWeightsForParticipant(Participant* participant); + + /** + Logs a multiline representation of the current state + of the mixing matrix. + */ + void outputBridgeMixWeights(); + +private: + MpBridgeGain mMixMatrix[DEFAULT_BRIDGE_MAX_IN_OUTPUTS][DEFAULT_BRIDGE_MAX_IN_OUTPUTS]; + CpMediaInterface& mMediaInterface; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/Conversation.cxx b/src/libs/resiprocate/resip/recon/Conversation.cxx new file mode 100644 index 00000000..190d0c8f --- /dev/null +++ b/src/libs/resiprocate/resip/recon/Conversation.cxx @@ -0,0 +1,365 @@ +#include "Conversation.hxx" +#include "Participant.hxx" +#include "LocalParticipant.hxx" +#include "RemoteParticipant.hxx" +#include "MediaResourceParticipant.hxx" +#include "UserAgent.hxx" +#include "RelatedConversationSet.hxx" +#include "ReconSubsystem.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/WinLeakCheck.hxx> + +using namespace recon; +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +Conversation::Conversation(ConversationHandle handle, + ConversationManager& conversationManager, + RelatedConversationSet* relatedConversationSet, + bool broadcastOnly) +: mHandle(handle), + mConversationManager(conversationManager), + mDestroying(false), + mNumLocalParticipants(0), + mNumRemoteParticipants(0), + mNumMediaParticipants(0), + mBroadcastOnly(broadcastOnly), + mBridgeMixer(0) +{ + mConversationManager.registerConversation(this); + + if(relatedConversationSet) + { + mRelatedConversationSet = relatedConversationSet; + mRelatedConversationSet->addRelatedConversation(mHandle, this); + } + else + { + mRelatedConversationSet = new RelatedConversationSet(mConversationManager, mHandle, this); + } + InfoLog(<< "Conversation created, handle=" << mHandle); + + if(mConversationManager.getMediaInterfaceMode() == ConversationManager::sipXConversationMediaInterfaceMode) + { + mConversationManager.createMediaInterfaceAndMixer(false /* giveFocus?*/, // Focus will be given when local participant is added + mHandle, + mMediaInterface, + &mBridgeMixer); + } +} + +Conversation::~Conversation() +{ + mConversationManager.unregisterConversation(this); + if(mRelatedConversationSet) + { + mRelatedConversationSet->removeConversation(mHandle); + } + mConversationManager.onConversationDestroyed(mHandle); + delete mBridgeMixer; + InfoLog(<< "Conversation destroyed, handle=" << mHandle); +} + +Participant* +Conversation::getParticipant(ParticipantHandle partHandle) +{ + ParticipantMap::iterator it = mParticipants.find(partHandle); + if(it != mParticipants.end()) + { + return it->second.getParticipant(); + } + else + { + return 0; + } +} + +void +Conversation::addParticipant(Participant* participant, unsigned int inputGain, unsigned int outputGain) +{ + // If participant doesn't already exist in this conversation - then add them + if(getParticipant(participant->getParticipantHandle()) == 0) + { + participant->addToConversation(this, inputGain, outputGain); + } +} + +void +Conversation::removeParticipant(Participant* participant) +{ + // If participant exists in this conversation - then remove them + if(getParticipant(participant->getParticipantHandle()) != 0) + { + participant->removeFromConversation(this); // Can cause this to be deleted + } +} + +void +Conversation::modifyParticipantContribution(Participant* participant, unsigned int inputGain, unsigned int outputGain) +{ + ParticipantMap::iterator it = mParticipants.find(participant->getParticipantHandle()); + if(it != mParticipants.end()) + { + it->second.setInputGain(inputGain); + it->second.setOutputGain(outputGain); + participant->applyBridgeMixWeights(); + } +} + +bool +Conversation::shouldHold() +{ + // We should be offering a hold SDP if there is no LocalParticipant + // in the conversation and there are no other remote participants or + // there are no remote participants at all + return mBroadcastOnly || + mNumRemoteParticipants == 0 || + (mNumLocalParticipants == 0 && (mNumRemoteParticipants+mNumMediaParticipants) <= 1); +} + +bool +Conversation::broadcastOnly() +{ + return mBroadcastOnly; +} + +void +Conversation::notifyRemoteParticipantsOfHoldChange() +{ + ParticipantMap::iterator i; + for(i = mParticipants.begin(); i != mParticipants.end(); i++) + { + RemoteParticipant* remoteParticipant = dynamic_cast<RemoteParticipant*>(i->second.getParticipant()); + if(remoteParticipant) + { + remoteParticipant->checkHoldCondition(); + } + } +} + +void +Conversation::createRelatedConversation(RemoteParticipant* newForkedParticipant, ParticipantHandle origParticipantHandle) +{ + // Create new Related Conversation + ConversationHandle relatedConvHandle = mConversationManager.getNewConversationHandle(); + Conversation* conversation = new Conversation(relatedConvHandle, mConversationManager, mRelatedConversationSet, mBroadcastOnly); + + // Copy all participants to new Conversation, except origParticipant + ParticipantMap::iterator i; + for(i = mParticipants.begin(); i != mParticipants.end(); i++) + { + if(i->second.getParticipant()->getParticipantHandle() != origParticipantHandle) + { + conversation->addParticipant(i->second.getParticipant(), i->second.getInputGain(), i->second.getOutputGain()); + } + } + // add new forked participant to new Conversation + conversation->addParticipant(newForkedParticipant); + + // Send onRelatedConversation event + mConversationManager.onRelatedConversation(relatedConvHandle, newForkedParticipant->getParticipantHandle(), + mHandle, origParticipantHandle); +} + +void +Conversation::join(Conversation* conversation) +{ + // Copy all participants to new Conversation + ParticipantMap::iterator i; + for(i = mParticipants.begin(); i != mParticipants.end(); i++) + { + conversation->addParticipant(i->second.getParticipant(), i->second.getInputGain(), i->second.getOutputGain()); // checks for duplicates + } + destroy(); // destroy this conversation +} + +void +Conversation::destroy() +{ + if(mParticipants.size() == 0) + { + delete this; + } + else + { + // End each Participant - for local participants just remove them + mDestroying = true; + ParticipantMap temp = mParticipants; // Need to copy since member list can be changed by terminating participants + ParticipantMap::iterator i; + for(i = temp.begin(); i != temp.end(); i++) + { + LocalParticipant* localParticipant = dynamic_cast<LocalParticipant*>(i->second.getParticipant()); + if(localParticipant) + { + removeParticipant(localParticipant); + } + else + { + if(i->second.getParticipant()->getNumConversations() == 1) + { + // Destroy participant if it is only in this conversation + i->second.getParticipant()->destroyParticipant(); + } + else + { + removeParticipant(i->second.getParticipant()); + } + } + } + } +} + +void +Conversation::registerParticipant(Participant *participant, unsigned int inputGain, unsigned int outputGain) +{ + // Only increment count if registering new participant + if(getParticipant(participant->getParticipantHandle()) == 0) + { + bool prevShouldHold = shouldHold(); + RemoteParticipant* remote; + MediaResourceParticipant* media; + if(dynamic_cast<LocalParticipant*>(participant)) + { + mNumLocalParticipants++; + } + else if((remote = dynamic_cast<RemoteParticipant*>(participant))) + { + mNumRemoteParticipants++; + } + else if((media = dynamic_cast<MediaResourceParticipant*>(participant))) + { + mNumMediaParticipants++; + } + if(prevShouldHold != shouldHold()) + { + notifyRemoteParticipantsOfHoldChange(); // Note: no need to notify party just added + } + } + + mParticipants[participant->getParticipantHandle()] = ConversationParticipantAssignment(participant, inputGain, outputGain); + + InfoLog(<< "Participant handle=" << participant->getParticipantHandle() << " added to conversation handle=" << mHandle << " (BridgePort=" << participant->getConnectionPortOnBridge() << ")"); + + participant->applyBridgeMixWeights(); +} + +void +Conversation::unregisterParticipant(Participant *participant) +{ + // For some reason: Since this is called from the Subclasses Participant Destructor, the dynamic_casts + // don't work. + if(getParticipant(participant->getParticipantHandle()) != 0) + { + mParticipants.erase(participant->getParticipantHandle()); // No need to notify this party, remove from map first + + RemoteParticipant* remote; + MediaResourceParticipant* media; + bool prevShouldHold = shouldHold(); + if(dynamic_cast<LocalParticipant*>(participant)) + { + mNumLocalParticipants--; + } + else if((remote = dynamic_cast<RemoteParticipant*>(participant))) + { + mNumRemoteParticipants--; + } + else if((media = dynamic_cast<MediaResourceParticipant*>(participant))) + { + mNumMediaParticipants--; + } + if(!mDestroying && prevShouldHold != shouldHold()) + { + notifyRemoteParticipantsOfHoldChange(); + } + + participant->applyBridgeMixWeights(this); + InfoLog(<< "Participant handle=" << participant->getParticipantHandle() << " removed from conversation handle=" << mHandle); + + if(mDestroying && mParticipants.size() == 0) + { + delete this; + } + } +} + +void +Conversation::notifyMediaEvent(int mediaConnectionId, MediaEvent::MediaEventType eventType) +{ + assert(eventType == MediaEvent::PLAY_FINISHED); + + if(eventType == MediaEvent::PLAY_FINISHED) + { + // sipX only allows you to have one active media participant per media interface + // actually playing a file (or from cache) at a time, so for now it is sufficient to have + // this event indicate that any active media participants (playing a file/cache) should be destroyed. + ParticipantMap::iterator it; + for(it = mParticipants.begin(); it != mParticipants.end();) + { + MediaResourceParticipant* mrPart = dynamic_cast<MediaResourceParticipant*>(it->second.getParticipant()); + it++; // increment iterator here, since destroy may end up calling unregisterParticipant + if(mrPart) + { + if(mrPart->getResourceType() == MediaResourceParticipant::File || + mrPart->getResourceType() == MediaResourceParticipant::Cache) + { + mrPart->destroyParticipant(); + } + } + } + } +} + +void +Conversation::notifyDtmfEvent(int mediaConnectionId, int dtmf, int duration, bool up) +{ + ParticipantMap::iterator i = mParticipants.begin(); + for(; i != mParticipants.end(); i++) + { + RemoteParticipant* remoteParticipant = dynamic_cast<RemoteParticipant*>(i->second.getParticipant()); + if(remoteParticipant) + { + if(remoteParticipant->getMediaConnectionId() == mediaConnectionId) + { + mConversationManager.onDtmfEvent(remoteParticipant->getParticipantHandle(), dtmf, duration, up); + } + } + } +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/Conversation.hxx b/src/libs/resiprocate/resip/recon/Conversation.hxx new file mode 100644 index 00000000..0a890183 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/Conversation.hxx @@ -0,0 +1,129 @@ +#if !defined(Conversation_hxx) +#define Conversation_hxx + +#include "ConversationManager.hxx" +#include "ConversationParticipantAssignment.hxx" + +namespace recon +{ +class Participant; +class LocalParticipant; +class RemoteParticipant; +class RelatedConversationSet; +class BridgeMixer; + +/** + This class is used to manage membership of participants. + + Conversations are used to designate the audio properties + between a number of managed participants. By default all + participants in a Conversation can talk to and hear all + other participants. A modified participants contribution + setting to a conversation can change this. + + If a remote participant is a sole member in a conversation, + then he/she will be put on hold. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class Conversation +{ +public: + Conversation(ConversationHandle handle, + ConversationManager& conversationManager, + RelatedConversationSet* relatedConversationSet=0, // Pass NULL to create new RelatedConversationSet + bool broadcastOnly = false); + ~Conversation(); + + void addParticipant(Participant* participant, unsigned int inputGain = 100, unsigned int outputGain = 100); + void removeParticipant(Participant* participant); + void modifyParticipantContribution(Participant* participant, unsigned int inputGain, unsigned int outputGain); + + unsigned int getNumLocalParticipants() { return mNumLocalParticipants; } + unsigned int getNumRemoteParticipants() { return mNumRemoteParticipants; } + bool shouldHold(); + bool broadcastOnly(); + void notifyRemoteParticipantsOfHoldChange(); + + void createRelatedConversation(RemoteParticipant* newForkedParticipant, ParticipantHandle origParticipantHandle); + void join(Conversation* conversation); // move all non-duplicate participants from this conversation to passed in conversation and destroy this one + + void destroy(); + + ConversationHandle getHandle() { return mHandle; } + + void notifyMediaEvent(int mediaConnectionId, MediaEvent::MediaEventType eventType); + void notifyDtmfEvent(int mediaConnectionId, int dtmf, int duration, bool up); + +protected: + friend class Participant; + friend class LocalParticipant; + friend class RemoteParticipant; + friend class MediaResourceParticipant; + void registerParticipant(Participant *, unsigned int inputGain=100, unsigned int outputGain=100); + void unregisterParticipant(Participant *); + + friend class BridgeMixer; + typedef std::map<ParticipantHandle, ConversationParticipantAssignment> ParticipantMap; + ParticipantMap& getParticipants() { return mParticipants; } + + resip::SharedPtr<MediaInterface> getMediaInterface() const { assert(mMediaInterface); return mMediaInterface; } + +private: + ConversationHandle mHandle; + ConversationManager& mConversationManager; + RelatedConversationSet *mRelatedConversationSet; + + ParticipantMap mParticipants; + Participant* getParticipant(ParticipantHandle partHandle); + bool mDestroying; + unsigned int mNumLocalParticipants; + unsigned int mNumRemoteParticipants; + unsigned int mNumMediaParticipants; + bool mBroadcastOnly; + + // sipX Media related members + BridgeMixer* getBridgeMixer() { return mBridgeMixer; } + resip::SharedPtr<MediaInterface> mMediaInterface; + BridgeMixer* mBridgeMixer; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/ConversationManager.cxx b/src/libs/resiprocate/resip/recon/ConversationManager.cxx new file mode 100644 index 00000000..c118f286 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/ConversationManager.cxx @@ -0,0 +1,1201 @@ +// sipX includes +#include <sdp/SdpCodec.h> +#include <os/OsConfigDb.h> +#include <mp/MpCodecFactory.h> +#include <mp/MprBridge.h> +#include <mp/MpResourceTopology.h> +#include <mi/CpMediaInterfaceFactoryFactory.h> +#include <mi/CpMediaInterface.h> + +// resip includes +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/Lock.hxx> +#include <rutil/Random.hxx> +#include <resip/dum/DialogUsageManager.hxx> +#include <resip/dum/ClientInviteSession.hxx> +#include <resip/dum/ServerInviteSession.hxx> +#include <resip/dum/ClientSubscription.hxx> +#include <resip/dum/ServerOutOfDialogReq.hxx> + +#include "ReconSubsystem.hxx" +#include "UserAgent.hxx" +#include "ConversationManager.hxx" +#include "ConversationManagerCmds.hxx" +#include "Conversation.hxx" +#include "Participant.hxx" +#include "BridgeMixer.hxx" +#include "DtmfEvent.hxx" +#include <rutil/WinLeakCheck.hxx> + +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) +#endif + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +ConversationManager::ConversationManager(bool localAudioEnabled, MediaInterfaceMode mediaInterfaceMode) +: mUserAgent(0), + mCurrentConversationHandle(1), + mCurrentParticipantHandle(1), + mLocalAudioEnabled(localAudioEnabled), + mMediaInterfaceMode(mediaInterfaceMode), + mMediaFactory(0), + mBridgeMixer(0), + mSipXTOSValue(0) +{ +#ifdef _DEBUG + UtlString codecPaths[] = {".", "../../../../sipXtapi/sipXmediaLib/bin"}; +#else + UtlString codecPaths[] = {"."}; +#endif + int codecPathsNum = sizeof(codecPaths)/sizeof(codecPaths[0]); + OsStatus rc = CpMediaInterfaceFactory::addCodecPaths(codecPathsNum, codecPaths); + assert(OS_SUCCESS == rc); + + if(mMediaInterfaceMode == sipXConversationMediaInterfaceMode) + { + OsConfigDb sipXconfig; + sipXconfig.set("PHONESET_MAX_ACTIVE_CALLS_ALLOWED",300); // This controls the maximum number of flowgraphs allowed - default is 16 + mMediaFactory = sipXmediaFactoryFactory(&sipXconfig, 0, 0, 0, mLocalAudioEnabled); + } + else + { + mMediaFactory = sipXmediaFactoryFactory(NULL, 0, 0, 0, mLocalAudioEnabled); + } + + // Create MediaInterface + MpCodecFactory *pCodecFactory = MpCodecFactory::getMpCodecFactory(); + unsigned int count = 0; + const MppCodecInfoV1_1 **codecInfoArray; + pCodecFactory->getCodecInfoArray(count, codecInfoArray); + + if(count == 0) + { + ErrLog( << "No codec plugins found. Cannot start."); + exit(-1); + } + + InfoLog( << "Loaded codecs are:"); + for(unsigned int i =0; i < count; i++) + { + InfoLog( << " " << codecInfoArray[i]->codecName + << "(" << codecInfoArray[i]->codecManufacturer << ") " + << codecInfoArray[i]->codecVersion + << " MimeSubtype: " << codecInfoArray[i]->mimeSubtype + << " Rate: " << codecInfoArray[i]->sampleRate + << " Channels: " << codecInfoArray[i]->numChannels); + } + + if(mMediaInterfaceMode == sipXGlobalMediaInterfaceMode) + { + createMediaInterfaceAndMixer(mLocalAudioEnabled /* giveFocus?*/, // This is the one and only media interface - give it focus + 0, + mMediaInterface, + &mBridgeMixer); + } +} + +ConversationManager::~ConversationManager() +{ + assert(mConversations.empty()); + assert(mParticipants.empty()); + delete mBridgeMixer; + if(mMediaInterface) mMediaInterface.reset(); // Make sure inteface is destroyed before factory + sipxDestroyMediaFactoryFactory(); +} + +void +ConversationManager::setUserAgent(UserAgent* userAgent) +{ + mUserAgent = userAgent; + + // Note: This is not really required, since we are managing the port allocation - but no harm done + // Really not needed now - since FlowManager integration + //mMediaFactory->getFactoryImplementation()->setRtpPortRange(mUserAgent->getUserAgentMasterProfile()->rtpPortRangeMin(), + // mUserAgent->getUserAgentMasterProfile()->rtpPortRangeMax()); + + initRTPPortFreeList(); +} + +void +ConversationManager::shutdown() +{ + // Destroy each Conversation + ConversationMap tempConvs = mConversations; // Create copy for safety, since ending conversations can immediately remove themselves from map + ConversationMap::iterator i; + for(i = tempConvs.begin(); i != tempConvs.end(); i++) + { + InfoLog(<< "Destroying conversation: " << i->second->getHandle()); + i->second->destroy(); + } + + // End each Participant + ParticipantMap tempParts = mParticipants; + ParticipantMap::iterator j; + int j2=0; + for(j = tempParts.begin(); j != tempParts.end(); j++, j2++) + { + InfoLog(<< "Destroying participant: " << j->second->getParticipantHandle()); + j->second->destroyParticipant(); + } +} + +ConversationHandle +ConversationManager::createConversation(bool broadcastOnly) +{ + ConversationHandle convHandle = getNewConversationHandle(); + + CreateConversationCmd* cmd = new CreateConversationCmd(this, convHandle, broadcastOnly); + post(cmd); + return convHandle; +} + +void +ConversationManager::destroyConversation(ConversationHandle convHandle) +{ + DestroyConversationCmd* cmd = new DestroyConversationCmd(this, convHandle); + post(cmd); +} + +void +ConversationManager::joinConversation(ConversationHandle sourceConvHandle, ConversationHandle destConvHandle) +{ + JoinConversationCmd* cmd = new JoinConversationCmd(this, sourceConvHandle, destConvHandle); + post(cmd); +} + +ParticipantHandle +ConversationManager::createRemoteParticipant(ConversationHandle convHandle, const NameAddr& destination, ParticipantForkSelectMode forkSelectMode) +{ + ParticipantHandle partHandle = getNewParticipantHandle(); + + CreateRemoteParticipantCmd* cmd = new CreateRemoteParticipantCmd(this, partHandle, convHandle, destination, forkSelectMode); + post(cmd); + + return partHandle; +} + +ParticipantHandle +ConversationManager::createMediaResourceParticipant(ConversationHandle convHandle, const Uri& mediaUrl) +{ + ParticipantHandle partHandle = getNewParticipantHandle(); + + CreateMediaResourceParticipantCmd* cmd = new CreateMediaResourceParticipantCmd(this, partHandle, convHandle, mediaUrl); + post(cmd); + + return partHandle; +} + +ParticipantHandle +ConversationManager::createLocalParticipant() +{ + ParticipantHandle partHandle = 0; + if(mLocalAudioEnabled) + { + partHandle = getNewParticipantHandle(); + + CreateLocalParticipantCmd* cmd = new CreateLocalParticipantCmd(this, partHandle); + post(cmd); + } + else + { + WarningLog(<< "createLocalParticipant called when local audio support is disabled."); + } + + return partHandle; +} + +void +ConversationManager::destroyParticipant(ParticipantHandle partHandle) +{ + DestroyParticipantCmd* cmd = new DestroyParticipantCmd(this, partHandle); + post(cmd); +} + +void +ConversationManager::addParticipant(ConversationHandle convHandle, ParticipantHandle partHandle) +{ + AddParticipantCmd* cmd = new AddParticipantCmd(this, convHandle, partHandle); + post(cmd); +} + +void +ConversationManager::removeParticipant(ConversationHandle convHandle, ParticipantHandle partHandle) +{ + RemoveParticipantCmd* cmd = new RemoveParticipantCmd(this, convHandle, partHandle); + post(cmd); +} + +void +ConversationManager::moveParticipant(ParticipantHandle partHandle, ConversationHandle sourceConvHandle, ConversationHandle destConvHandle) +{ + MoveParticipantCmd* cmd = new MoveParticipantCmd(this, partHandle, sourceConvHandle, destConvHandle); + post(cmd); +} + +void +ConversationManager::modifyParticipantContribution(ConversationHandle convHandle, ParticipantHandle partHandle, unsigned int inputGain, unsigned int outputGain) +{ + ModifyParticipantContributionCmd* cmd = new ModifyParticipantContributionCmd(this, convHandle, partHandle, inputGain, outputGain); + post(cmd); +} + +void +ConversationManager::outputBridgeMatrix() +{ + if(mMediaInterfaceMode == sipXGlobalMediaInterfaceMode) + { + OutputBridgeMixWeightsCmd* cmd = new OutputBridgeMixWeightsCmd(this); + post(cmd); + } + else + { + WarningLog(<< "ConversationManager::outputBridgeMatrix not supported in current Media Interface Mode"); + } +} + +void +ConversationManager::alertParticipant(ParticipantHandle partHandle, bool earlyFlag) +{ + AlertParticipantCmd* cmd = new AlertParticipantCmd(this, partHandle, earlyFlag); + post(cmd); +} + +void +ConversationManager::answerParticipant(ParticipantHandle partHandle) +{ + AnswerParticipantCmd* cmd = new AnswerParticipantCmd(this, partHandle); + post(cmd); +} + +void +ConversationManager::rejectParticipant(ParticipantHandle partHandle, unsigned int rejectCode) +{ + RejectParticipantCmd* cmd = new RejectParticipantCmd(this, partHandle, rejectCode); + post(cmd); +} + +void +ConversationManager::redirectParticipant(ParticipantHandle partHandle, const NameAddr& destination) +{ + RedirectParticipantCmd* cmd = new RedirectParticipantCmd(this, partHandle, destination); + post(cmd); +} + +void +ConversationManager::redirectToParticipant(ParticipantHandle partHandle, ParticipantHandle destPartHandle) +{ + RedirectToParticipantCmd* cmd = new RedirectToParticipantCmd(this, partHandle, destPartHandle); + post(cmd); +} + +ConversationHandle +ConversationManager::getNewConversationHandle() +{ + Lock lock(mConversationHandleMutex); + return mCurrentConversationHandle++; +} + +void +ConversationManager::registerConversation(Conversation *conversation) +{ + mConversations[conversation->getHandle()] = conversation; +} + +void +ConversationManager::unregisterConversation(Conversation *conversation) +{ + mConversations.erase(conversation->getHandle()); +} + +ParticipantHandle +ConversationManager::getNewParticipantHandle() +{ + Lock lock(mParticipantHandleMutex); + return mCurrentParticipantHandle++; +} + +void +ConversationManager::registerParticipant(Participant *participant) +{ + mParticipants[participant->getParticipantHandle()] = participant; +} + +void +ConversationManager::unregisterParticipant(Participant *participant) +{ + InfoLog(<< "participant unregistered, handle=" << participant->getParticipantHandle()); + mParticipants.erase(participant->getParticipantHandle()); +} + +void +ConversationManager::post(resip::Message *msg) +{ + mUserAgent->getDialogUsageManager().post(msg); +} + +void +ConversationManager::post(resip::ApplicationMessage& message, unsigned int ms) +{ + mUserAgent->post(message, ms); +} + +void +ConversationManager::initRTPPortFreeList() +{ + mRTPPortFreeList.clear(); + for(unsigned int i = mUserAgent->getUserAgentMasterProfile()->rtpPortRangeMin(); i <= mUserAgent->getUserAgentMasterProfile()->rtpPortRangeMax();) + { + mRTPPortFreeList.push_back(i); + i=i+2; // only add even ports - note we are assuming rtpPortRangeMin is even + } +} + +unsigned int +ConversationManager::allocateRTPPort() +{ + unsigned int port = 0; + if(!mRTPPortFreeList.empty()) + { + port = mRTPPortFreeList.front(); + mRTPPortFreeList.pop_front(); + } + return port; +} + +void +ConversationManager::freeRTPPort(unsigned int port) +{ + assert(port >= mUserAgent->getUserAgentMasterProfile()->rtpPortRangeMin() && port <= mUserAgent->getUserAgentMasterProfile()->rtpPortRangeMax()); + mRTPPortFreeList.push_back(port); +} + +void +ConversationManager::buildSdpOffer(ConversationProfile* profile, SdpContents& offer) +{ + // copy over session capabilities + offer = profile->sessionCaps(); + + // Set sessionid and version for this offer + UInt64 currentTime = Timer::getTimeMicroSec(); + offer.session().origin().getSessionId() = currentTime; + offer.session().origin().getVersion() = currentTime; + + // Set local port in offer + // for now we only allow 1 audio media + assert(offer.session().media().size() == 1); + assert(offer.session().media().front().name() == "audio"); +} + +void +ConversationManager::setSpeakerVolume(int volume) +{ + OsStatus status = mMediaFactory->getFactoryImplementation()->setSpeakerVolume(volume); + if(status != OS_SUCCESS) + { + WarningLog(<< "setSpeakerVolume failed: status=" << status); + } +} + +void +ConversationManager::setMicrophoneGain(int gain) +{ + OsStatus status = mMediaFactory->getFactoryImplementation()->setMicrophoneGain(gain); + if(status != OS_SUCCESS) + { + WarningLog(<< "setMicrophoneGain failed: status=" << status); + } +} + +void +ConversationManager::muteMicrophone(bool mute) +{ + OsStatus status = mMediaFactory->getFactoryImplementation()->muteMicrophone(mute? TRUE : FALSE); + if(status != OS_SUCCESS) + { + WarningLog(<< "muteMicrophone failed: status=" << status); + } +} + +void +ConversationManager::enableEchoCancel(bool enable) +{ + OsStatus status = mMediaFactory->getFactoryImplementation()->setAudioAECMode(enable ? MEDIA_AEC_CANCEL : MEDIA_AEC_DISABLED); + if(status != OS_SUCCESS) + { + WarningLog(<< "enableEchoCancel failed: status=" << status); + } + if(mMediaInterfaceMode == sipXGlobalMediaInterfaceMode) // Note for sipXConversationMediaInterfaceMode - setting will apply on next conversation given focus + { + mMediaInterface->getInterface()->defocus(); // required to apply changes + mMediaInterface->getInterface()->giveFocus(); + } +} + +void +ConversationManager::enableAutoGainControl(bool enable) +{ + OsStatus status = mMediaFactory->getFactoryImplementation()->enableAGC(enable ? TRUE : FALSE); + if(status != OS_SUCCESS) + { + WarningLog(<< "enableAutoGainControl failed: status=" << status); + } + if(mMediaInterfaceMode == sipXGlobalMediaInterfaceMode) // Note for sipXConversationMediaInterfaceMode - setting will apply on next conversation given focus + { + mMediaInterface->getInterface()->defocus(); // required to apply changes + mMediaInterface->getInterface()->giveFocus(); + } +} + +void +ConversationManager::enableNoiseReduction(bool enable) +{ + OsStatus status = mMediaFactory->getFactoryImplementation()->setAudioNoiseReductionMode(enable ? MEDIA_NOISE_REDUCTION_MEDIUM /* arbitrary */ : MEDIA_NOISE_REDUCTION_DISABLED); + if(status != OS_SUCCESS) + { + WarningLog(<< "enableAutoGainControl failed: status=" << status); + } + if(mMediaInterfaceMode == sipXGlobalMediaInterfaceMode) // Note for sipXConversationMediaInterfaceMode - setting will apply on next conversation given focus + { + mMediaInterface->getInterface()->defocus(); // required to apply changes + mMediaInterface->getInterface()->giveFocus(); + } +} + +Participant* +ConversationManager::getParticipant(ParticipantHandle partHandle) +{ + ParticipantMap::iterator i = mParticipants.find(partHandle); + if(i != mParticipants.end()) + { + return i->second; + } + else + { + return 0; + } +} + +Conversation* +ConversationManager::getConversation(ConversationHandle convHandle) +{ + ConversationMap::iterator i = mConversations.find(convHandle); + if(i != mConversations.end()) + { + return i->second; + } + else + { + return 0; + } +} + +void +ConversationManager::addBufferToMediaResourceCache(const resip::Data& name, const resip::Data& buffer, int type) +{ + mMediaResourceCache.addToCache(name, buffer, type); +} + +void +ConversationManager::buildSessionCapabilities(const resip::Data& ipaddress, unsigned int numCodecIds, + unsigned int codecIds[], resip::SdpContents& sessionCaps) +{ + sessionCaps = SdpContents::Empty; // clear out passed in SdpContents + + // Check if ipaddress is V4 or V6 + bool v6 = false; + if(!ipaddress.empty()) + { + Tuple testTuple(ipaddress, 0, UDP); + if(testTuple.ipVersion() == V6) + { + v6 = true; + } + } + + // Create Session Capabilities + // Note: port, sessionId and version will be replaced in actual offer/answer + // Build s=, o=, t=, and c= lines + SdpContents::Session::Origin origin("-", 0 /* sessionId */, 0 /* version */, v6 ? SdpContents::IP6 : SdpContents::IP4, ipaddress.empty() ? "0.0.0.0" : ipaddress); // o= + SdpContents::Session session(0, origin, "-" /* s= */); + session.connection() = SdpContents::Session::Connection(v6 ? SdpContents::IP6 : SdpContents::IP4, ipaddress.empty() ? "0.0.0.0" : ipaddress); // c= + session.addTime(SdpContents::Session::Time(0, 0)); + + MpCodecFactory *pCodecFactory = MpCodecFactory::getMpCodecFactory(); + SdpCodecList codecList; + pCodecFactory->addCodecsToList(codecList); + codecList.bindPayloadTypes(); + + //UtlString output; + //codecList.toString(output); + //InfoLog( << "Codec List: " << output.data()); + + // Auto-Create Session Codec Capabilities + // Note: port, and potentially payloadid will be replaced in actual offer/answer + + // Build Codecs and media offering + SdpContents::Session::Medium medium("audio", 0, 1, "RTP/AVP"); + + bool firstCodecAdded = false; + for(unsigned int idIter = 0; idIter < numCodecIds; idIter++) + { + const SdpCodec* sdpcodec = codecList.getCodec((SdpCodec::SdpCodecTypes)codecIds[idIter]); + if(sdpcodec) + { + UtlString mediaType; + sdpcodec->getMediaType(mediaType); + // Ensure this codec is an audio codec + if(mediaType.compareTo("audio", UtlString::ignoreCase) == 0) + { + UtlString mimeSubType; + sdpcodec->getEncodingName(mimeSubType); + //mimeSubType.toUpper(); + + SdpContents::Session::Codec codec(mimeSubType.data(), sdpcodec->getSampleRate()); + codec.payloadType() = sdpcodec->getCodecPayloadFormat(); + + // Check for telephone-event and add fmtp manually + if(mimeSubType.compareTo("telephone-event", UtlString::ignoreCase) == 0) + { + codec.parameters() = Data("0-15"); + } + else + { + UtlString fmtpField; + sdpcodec->getSdpFmtpField(fmtpField); + if(fmtpField.length() != 0) + { + codec.parameters() = Data(fmtpField.data()); + } + } + + DebugLog(<< "Added codec to session capabilites: id=" << codecIds[idIter] + << " type=" << mimeSubType.data() + << " rate=" << sdpcodec->getSampleRate() + << " plen=" << sdpcodec->getPacketLength() + << " payloadid=" << sdpcodec->getCodecPayloadFormat() + << " fmtp=" << codec.parameters()); + + medium.addCodec(codec); + if(!firstCodecAdded) + { + firstCodecAdded = true; + + // 20 ms of speech per frame (note G711 has 10ms samples, so this is 2 samples per frame) + // Note: There are known problems with SDP and the ptime attribute. For now we will choose an + // appropriate ptime from the first codec + medium.addAttribute("ptime", Data(sdpcodec->getPacketLength() / 1000)); + } + } + } + } + + session.addMedium(medium); + sessionCaps.session() = session; +} + +void +ConversationManager::notifyMediaEvent(ConversationHandle conversationHandle, int mediaConnectionId, MediaEvent::MediaEventType eventType) +{ + assert(eventType == MediaEvent::PLAY_FINISHED); + + if(conversationHandle == 0) // sipXGlobalMediaInterfaceMode + { + if(eventType == MediaEvent::PLAY_FINISHED) + { + // Using sipXGlobalMediaInterfaceMode it is only possible to have one active media participant + // actually playing a file (or from cache) at a time, so for now it is sufficient to have + // this event indicate that any active media participants (playing a file/cache) should be destroyed. + ParticipantMap::iterator it; + for(it = mParticipants.begin(); it != mParticipants.end();) + { + MediaResourceParticipant* mrPart = dynamic_cast<MediaResourceParticipant*>(it->second); + it++; // increment iterator here, since destroy may end up calling unregisterParticipant + if(mrPart) + { + if(mrPart->getResourceType() == MediaResourceParticipant::File || + mrPart->getResourceType() == MediaResourceParticipant::Cache) + { + mrPart->destroyParticipant(); + } + } + } + } + } + else + { + Conversation* conversation = getConversation(conversationHandle); + if(conversation) + { + conversation->notifyMediaEvent(mediaConnectionId, eventType); + } + } +} + +void +ConversationManager::notifyDtmfEvent(ConversationHandle conversationHandle, int mediaConnectionId, int dtmf, int duration, bool up) +{ + if(conversationHandle == 0) // sipXGlobalMediaInterfaceMode + { + ParticipantMap::iterator i = mParticipants.begin(); + for(; i != mParticipants.end(); i++) + { + RemoteParticipant* remoteParticipant = dynamic_cast<RemoteParticipant*>(i->second); + if(remoteParticipant) + { + if(remoteParticipant->getMediaConnectionId() == mediaConnectionId) + { + onDtmfEvent(remoteParticipant->getParticipantHandle(), dtmf, duration, up); + } + } + } + } + else + { + Conversation* conversation = getConversation(conversationHandle); + if(conversation) + { + conversation->notifyDtmfEvent(mediaConnectionId, dtmf, duration, up); + } + } +} + +void +ConversationManager::createMediaInterfaceAndMixer(bool giveFocus, + ConversationHandle ownerConversationHandle, + SharedPtr<MediaInterface>& mediaInterface, + BridgeMixer** bridgeMixer) +{ + UtlString localRtpInterfaceAddress("127.0.0.1"); // Will be overridden in RemoteParticipantDialogSet, when connection is created anyway + + // Note: STUN and TURN capabilities of the sipX media stack are not used - the FlowManager is responsible for STUN/TURN + mediaInterface = SharedPtr<MediaInterface>(new MediaInterface(*this, ownerConversationHandle, mMediaFactory->createMediaInterface(NULL, + localRtpInterfaceAddress, + 0, /* numCodecs - not required at this point */ + 0, /* codecArray - not required at this point */ + NULL, /* local */ + mSipXTOSValue, /* TOS Options */ + NULL, /* STUN Server Address */ + 0, /* STUN Options */ + 25, /* STUN Keepalive period (seconds) */ + NULL, /* TURN Server Address */ + 0, /* TURN Port */ + NULL, /* TURN User */ + NULL, /* TURN Password */ + 25, /* TURN Keepalive period (seconds) */ + false))); /* enable ICE? */ + + // Register the NotificationDispatcher class (derived from OsMsgDispatcher) + // as the sipX notification dispatcher + mediaInterface->getInterface()->setNotificationDispatcher(mediaInterface.get()); + + // Turn on notifications for all resources... + mediaInterface->getInterface()->setNotificationsEnabled(true); + + if(giveFocus) + { + mediaInterface->getInterface()->giveFocus(); + } + + *bridgeMixer = new BridgeMixer(*(mediaInterface->getInterface())); +} + +void +ConversationManager::onNewSession(ClientInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onNewSession(h, oat, msg); +} + +void +ConversationManager::onNewSession(ServerInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onNewSession(h, oat, msg); +} + +void +ConversationManager::onFailure(ClientInviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onFailure(h, msg); +} + +void +ConversationManager::onEarlyMedia(ClientInviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onEarlyMedia(h, msg, sdp); +} + +void +ConversationManager::onProvisional(ClientInviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onProvisional(h, msg); +} + +void +ConversationManager::onConnected(ClientInviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onConnected(h, msg); +} + +void +ConversationManager::onConnected(InviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onConnected(h, msg); +} + +void +ConversationManager::onConnectedConfirmed(InviteSessionHandle h, const SipMessage &msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onConnectedConfirmed(h, msg); +} + +void +ConversationManager::onStaleCallTimeout(ClientInviteSessionHandle h) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onStaleCallTimeout(h); +} + +void +ConversationManager::onTerminated(InviteSessionHandle h, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onTerminated(h, reason, msg); +} + +void +ConversationManager::onRedirected(ClientInviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onRedirected(h, msg); +} + +void +ConversationManager::onAnswer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onAnswer(h, msg, sdp); +} + +void +ConversationManager::onOffer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onOffer(h, msg, sdp); +} + +void +ConversationManager::onOfferRequired(InviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onOfferRequired(h, msg); +} + +void +ConversationManager::onOfferRejected(InviteSessionHandle h, const SipMessage* msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onOfferRejected(h, msg); +} + +void +ConversationManager::onOfferRequestRejected(InviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onOfferRequestRejected(h, msg); +} + +void +ConversationManager::onRemoteSdpChanged(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onRemoteSdpChanged(h, msg, sdp); +} + +void +ConversationManager::onInfo(InviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onInfo(h, msg); +} + +void +ConversationManager::onInfoSuccess(InviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onInfoSuccess(h, msg); +} + +void +ConversationManager::onInfoFailure(InviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onInfoFailure(h, msg); +} + +void +ConversationManager::onRefer(InviteSessionHandle h, ServerSubscriptionHandle ssh, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onRefer(h, ssh, msg); +} + +void +ConversationManager::onReferAccepted(InviteSessionHandle h, ClientSubscriptionHandle csh, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onReferAccepted(h, csh, msg); +} + +void +ConversationManager::onReferRejected(InviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onReferRejected(h, msg); +} + +void +ConversationManager::onReferNoSub(InviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onReferNoSub(h, msg); +} + +void +ConversationManager::onMessage(InviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onMessage(h, msg); +} + +void +ConversationManager::onMessageSuccess(InviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onMessageSuccess(h, msg); +} + +void +ConversationManager::onMessageFailure(InviteSessionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onMessageFailure(h, msg); +} + +void +ConversationManager::onForkDestroyed(ClientInviteSessionHandle h) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onForkDestroyed(h); +} + +//////////////////////////////////////////////////////////////////////////////// +// DialogSetHandler /////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void +ConversationManager::onTrying(AppDialogSetHandle h, const SipMessage& msg) +{ + RemoteParticipantDialogSet *remoteParticipantDialogSet = dynamic_cast<RemoteParticipantDialogSet *>(h.get()); + if(remoteParticipantDialogSet) + { + remoteParticipantDialogSet->onTrying(h, msg); + } + else + { + InfoLog(<< "onTrying(AppDialogSetHandle): " << msg.brief()); + } +} + +void +ConversationManager::onNonDialogCreatingProvisional(AppDialogSetHandle h, const SipMessage& msg) +{ + RemoteParticipantDialogSet *remoteParticipantDialogSet = dynamic_cast<RemoteParticipantDialogSet *>(h.get()); + if(remoteParticipantDialogSet) + { + remoteParticipantDialogSet->onNonDialogCreatingProvisional(h, msg); + } + else + { + InfoLog(<< "onNonDialogCreatingProvisional(AppDialogSetHandle): " << msg.brief()); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// ClientSubscriptionHandler /////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void +ConversationManager::onUpdatePending(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onUpdatePending(h, msg, outOfOrder); +} + +void +ConversationManager::onUpdateActive(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onUpdateActive(h, msg, outOfOrder); +} + +void +ConversationManager::onUpdateExtension(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onUpdateExtension(h, msg, outOfOrder); +} + +void +ConversationManager::onTerminated(ClientSubscriptionHandle h, const SipMessage* msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onTerminated(h, msg); +} + +void +ConversationManager::onNewSubscription(ClientSubscriptionHandle h, const SipMessage& msg) +{ + dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onNewSubscription(h, msg); +} + +int +ConversationManager::onRequestRetry(ClientSubscriptionHandle h, int retryMinimum, const SipMessage& msg) +{ + return dynamic_cast<RemoteParticipant *>(h->getAppDialog().get())->onRequestRetry(h, retryMinimum, msg); + +} + +//////////////////////////////////////////////////////////////////////////////// +// ServerSubscriptionHandler /////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void +ConversationManager::onNewSubscription(ServerSubscriptionHandle, const SipMessage& msg) +{ + InfoLog(<< "onNewSubscription(ServerSubscriptionHandle): " << msg.brief()); +} + +void +ConversationManager::onNewSubscriptionFromRefer(ServerSubscriptionHandle ss, const SipMessage& msg) +{ + InfoLog(<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): " << msg.brief()); + // Received an out-of-dialog refer request with implicit subscription + try + { + if(msg.exists(h_ReferTo)) + { + // Check if TargetDialog header is present + if(msg.exists(h_TargetDialog)) + { + pair<InviteSessionHandle, int> presult; + presult = mUserAgent->getDialogUsageManager().findInviteSession(msg.header(h_TargetDialog)); + if(!(presult.first == InviteSessionHandle::NotValid())) + { + RemoteParticipant* participantToRefer = (RemoteParticipant*)presult.first->getAppDialog().get(); + + participantToRefer->onRefer(presult.first, ss, msg); + return; + } + } + + // Create new Participant + RemoteParticipantDialogSet *participantDialogSet = new RemoteParticipantDialogSet(*this); + RemoteParticipant *participant = participantDialogSet->createUACOriginalRemoteParticipant(getNewParticipantHandle()); + + // Set pending OOD info in Participant - causes accept or reject to be called later + participant->setPendingOODReferInfo(ss, msg); + + // Notify application + ConversationProfile* profile = dynamic_cast<ConversationProfile*>(ss->getUserProfile().get()); + assert(profile); + onRequestOutgoingParticipant(participant->getParticipantHandle(), msg, *profile); + } + else + { + WarningLog (<< "Received refer w/out a Refer-To: " << msg.brief()); + ss->send(ss->reject(400)); + } + } + catch(BaseException &e) + { + WarningLog(<< "onNewSubscriptionFromRefer exception: " << e); + } + catch(...) + { + WarningLog(<< "onNewSubscriptionFromRefer unknown exception"); + } +} + +void +ConversationManager::onRefresh(ServerSubscriptionHandle, const SipMessage& msg) +{ + InfoLog(<< "onRefresh(ServerSubscriptionHandle): " << msg.brief()); +} + +void +ConversationManager::onTerminated(ServerSubscriptionHandle) +{ + InfoLog(<< "onTerminated(ServerSubscriptionHandle)"); +} + +void +ConversationManager::onReadyToSend(ServerSubscriptionHandle, SipMessage&) +{ +} + +void +ConversationManager::onNotifyRejected(ServerSubscriptionHandle, const SipMessage& msg) +{ + WarningLog(<< "onNotifyRejected(ServerSubscriptionHandle): " << msg.brief()); +} + +void +ConversationManager::onError(ServerSubscriptionHandle, const SipMessage& msg) +{ + WarningLog(<< "onError(ServerSubscriptionHandle): " << msg.brief()); +} + +void +ConversationManager::onExpiredByClient(ServerSubscriptionHandle, const SipMessage& sub, SipMessage& notify) +{ + InfoLog(<< "onExpiredByClient(ServerSubscriptionHandle): " << notify.brief()); +} + +void +ConversationManager::onExpired(ServerSubscriptionHandle, SipMessage& msg) +{ + InfoLog(<< "onExpired(ServerSubscriptionHandle): " << msg.brief()); +} + +bool +ConversationManager::hasDefaultExpires() const +{ + return true; +} + +UInt32 +ConversationManager::getDefaultExpires() const +{ + return 60; +} + +//////////////////////////////////////////////////////////////////////////////// +// OutOfDialogHandler ////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void +ConversationManager::onSuccess(ClientOutOfDialogReqHandle, const SipMessage& msg) +{ + InfoLog(<< "onSuccess(ClientOutOfDialogReqHandle): " << msg.brief()); +} + +void +ConversationManager::onFailure(ClientOutOfDialogReqHandle, const SipMessage& msg) +{ + InfoLog(<< "onFailure(ClientOutOfDialogReqHandle): " << msg.brief()); +} + +void +ConversationManager::onReceivedRequest(ServerOutOfDialogReqHandle ood, const SipMessage& msg) +{ + InfoLog(<< "onReceivedRequest(ServerOutOfDialogReqHandle): " << msg.brief()); + + switch(msg.method()) + { + case OPTIONS: + { + SharedPtr<SipMessage> optionsAnswer = ood->answerOptions(); + + // Attach an offer to the options request + SdpContents sdp; + buildSdpOffer(mUserAgent->getIncomingConversationProfile(msg).get(), sdp); + optionsAnswer->setContents(&sdp); + ood->send(optionsAnswer); + break; + } + case REFER: + { + // Received an OOD refer request with no refer subscription + try + { + if(msg.exists(h_ReferTo)) + { + // Check if TargetDialog header is present + if(msg.exists(h_TargetDialog)) + { + pair<InviteSessionHandle, int> presult; + presult = mUserAgent->getDialogUsageManager().findInviteSession(msg.header(h_TargetDialog)); + if(!(presult.first == InviteSessionHandle::NotValid())) + { + RemoteParticipant* participantToRefer = (RemoteParticipant*)presult.first->getAppDialog().get(); + + // Accept the Refer + ood->send(ood->accept(202 /* Refer Accepted */)); + + participantToRefer->doReferNoSub(msg); + return; + } + } + + // Create new Participant + RemoteParticipantDialogSet *participantDialogSet = new RemoteParticipantDialogSet(*this); + RemoteParticipant *participant = participantDialogSet->createUACOriginalRemoteParticipant(getNewParticipantHandle()); + + // Set pending OOD info in Participant - causes accept or reject to be called later + participant->setPendingOODReferInfo(ood, msg); + + // Notify application + ConversationProfile* profile = dynamic_cast<ConversationProfile*>(ood->getUserProfile().get()); + assert(profile); + onRequestOutgoingParticipant(participant->getParticipantHandle(), msg, *profile); + } + else + { + WarningLog (<< "onReceivedRequest(ServerOutOfDialogReqHandle): Received refer w/out a Refer-To: " << msg.brief()); + ood->send(ood->reject(400)); + } + } + catch(BaseException &e) + { + WarningLog(<< "onReceivedRequest(ServerOutOfDialogReqHandle): exception " << e); + } + catch(...) + { + WarningLog(<< "onReceivedRequest(ServerOutOfDialogReqHandle): unknown exception"); + } + + break; + } + default: + break; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// RedirectHandler ///////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void +ConversationManager::onRedirectReceived(AppDialogSetHandle, const SipMessage& msg) +{ + InfoLog(<< "onRedirectReceived(AppDialogSetHandle): " << msg.brief()); +} + +bool +ConversationManager::onTryingNextTarget(AppDialogSetHandle, const SipMessage& msg) +{ + InfoLog(<< "onTryingNextTarget(AppDialogSetHandle): " << msg.brief()); + // Always allow redirection for now + return true; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/ConversationManager.hxx b/src/libs/resiprocate/resip/recon/ConversationManager.hxx new file mode 100644 index 00000000..f08e6b0a --- /dev/null +++ b/src/libs/resiprocate/resip/recon/ConversationManager.hxx @@ -0,0 +1,703 @@ +#if !defined(ConversationManager_hxx) +#define ConversationManager_hxx + +#ifdef WIN32 +#define BOOST__STDC_CONSTANT_MACROS_DEFINED // elminate duplicate define warnings under windows +#endif + +#include "BridgeMixer.hxx" + +#include <resip/stack/Uri.hxx> +#include <resip/dum/InviteSessionHandler.hxx> +#include <resip/dum/DialogSetHandler.hxx> +#include <resip/dum/SubscriptionHandler.hxx> +#include <resip/dum/OutOfDialogHandler.hxx> +#include <resip/dum/RedirectHandler.hxx> +#include <rutil/Mutex.hxx> +#include <rutil/SharedPtr.hxx> + +#include "MediaResourceCache.hxx" +#include "MediaEvent.hxx" +#include "HandleTypes.hxx" +#include "MediaInterface.hxx" + +#include "FlowManager.hxx" + +class CpMediaInterfaceFactory; + +namespace resip +{ +class DialogUsageManager; +} + +namespace recon +{ +class Conversation; +class Participant; +class UserAgent; +class ConversationProfile; +class RemoteParticipant; + + +/** + This class is one of two main classes of concern to an application + using the UserAgent library. This class should be subclassed by + the application and the ConversationManager handlers should be + implemented by it. + + This class is responsible for handling tasks that are directly + related to managing Conversations. All non-conversation + handling is done via the UserAgent class. + + This class handles tasks such as: + -Creation and destruction of Conversations + -Participant management and creation + -Placing and receiving calls + -Playing audio and/or tones into a conversation + -Managing local audio properties + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class ConversationManager : public resip::InviteSessionHandler, + public resip::DialogSetHandler, + public resip::OutOfDialogHandler, + public resip::ClientSubscriptionHandler, + public resip::ServerSubscriptionHandler, + public resip::RedirectHandler +{ +public: + + /** + Note: sipXtapi Media Interfaces have a finite number of supported endpoints + that are allowed in each bridge mixer - by default this value is 10 + (2 are used for local mic / speaker, 1 for a MediaParticipant, leaving + 7 remaining for RemoteParticipants). This limit is controlled by the + preprocessor define DEFAULT_BRIDGE_MAX_IN_OUTPUTS (see + http://www.resiprocate.org/Limitations_with_sipXtapi_media_Integration + for more details. + + sipXGlobalMediaInterfaceMode - uses 1 global sipXtapi media interface and + allows for participants to exist in multiple conversations at the same + time and have the bridge mixer properly control their mixing. In this + mode, there can only be a single MediaParticipant for all conversations. + This architecture/mode is appropriate for single user agent devices (ie. + sip phones). + + sipXConversationMediaInterfaceMode - uses 1 sipXtapi media interface per + conversation. Using this mode, participants cannot exist in multiple + conversations at the same time, however the limit of 7 participants is + no longer global, it now applies to each conversation. A separate + media participant for each conversation can also exist. + This architecture/mode is appropriate for server applications, such as + multi-party conference servers (up to 7 participants per conference), + music on hold servers and call park servers. Other API's that won't + function in this mode are: + -joinConversation + -addParticipant - only applies to the LocalParticipant + -moveParticipant - only applies to the LocalParticipant + Note: For inbound (UAS) Remote Participant sessions, ensure that you + add the Remote Participant to a conversation before you return + call accept() for alert() with early media. + */ + typedef enum + { + sipXGlobalMediaInterfaceMode, + sipXConversationMediaInterfaceMode + } MediaInterfaceMode; + + ConversationManager(bool localAudioEnabled=true, MediaInterfaceMode mediaInterfaceMode = sipXGlobalMediaInterfaceMode); + virtual ~ConversationManager(); + + typedef enum + { + ForkSelectAutomatic, // create a conversation for each early fork. accept the first fork from which a 200 is received. automatically kill other forks + ForkSelectManual // create a conversation for each early fork. let the application dispose of extra forks. ex: app may form conference. + } ParticipantForkSelectMode; + + /////////////////////////////////////////////////////////////////////// + // Conversation methods ////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////// + + /** + Create a new empty Conversation to which participants + can be added. + + @param broadcastOnly - if set to true, then all participants in + the conversation will be SIP held and will + receive media from an added MediaParticipant. + This option is useful for implementing music + on hold servers. + + @return A handle to the newly created conversation. + */ + virtual ConversationHandle createConversation(bool broadcastOnly=false); + + /** + Destroys an existing Conversation, and ends all + participants that solely belong to this conversation. + + @param handle Handle of conversation to destroy + */ + virtual void destroyConversation(ConversationHandle convHandle); + + /** + Joins all participants from source conversation into + destination conversation and destroys source conversation. + + @param sourceConvHandle Handle of source conversation + @param destConvHandle Handle of destination conversation + + @note This API cannot be used when sipXConversationMediaInterfaceMode + is enabled. + */ + virtual void joinConversation(ConversationHandle sourceConvHandle, ConversationHandle destConvHandle); + + /////////////////////////////////////////////////////////////////////// + // Participant methods /////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////// + + /** + Creates a new remote participant in the specified conversation + that is attempted to be reached at the specified address. + For SIP the address is a URI. ForkSelectMode can be set to either + automatic or manual. When ForkSelectMode is set to auto the + conversation manager will automatically dispose of any related + conversations that were created, due to forking. + + @param convHandle Handle of the conversation to create the + RemoteParticipant in + @param destination Uri of the remote participant to reach + @param forkSelectMode Determines behavior if forking occurs + + @return A handle to the newly created remote participant + */ + virtual ParticipantHandle createRemoteParticipant(ConversationHandle convHandle, const resip::NameAddr& destination, ParticipantForkSelectMode forkSelectMode = ForkSelectAutomatic); + + /** + Creates a new media resource participant in the specified conversation. + Media is played from a source specified by the url and may be a local + audio file, audio file fetched via HTTP or tones. The URL can contain + parameters that specify properties of the media playback, such as + number of repeats. + + Media Urls are of the following format: + tone:<tone> - Tones can be any DTMF digit 0-9,*,#,A-D or a special tone: + dialtone, busy, fastbusy, ringback, ring, backspace, callwaiting, + holding, or loudfastbusy + file:<filepath> - If filename only, then reads from application directory + (Use | instead of : for drive specifier) + http:<http-url> - Standard HTTP url that reference an audio file to be fetched + cache:<cache-name> - You can play from a memory buffer/cache any items you + have added with the addBufferToMediaResourceCache api. + + optional arguments are: [;duration=<duration>][;local-only][;remote-only][;repeat][;prefetch] + + @note 'repeat' option only makes sense for file and http URLs + @note 'prefetch' option only makes sense for http URLs + @note audio files may be AU, WAV or RAW formats. Audiofiles + should be 16bit mono, 8khz, PCM to avoid runtime conversion. + @note http referenced audio files must be WAV files, + 16 or 8bit, 8Khz, Mono. + + Sample mediaUrls: + tone:0 - play DTMF tone 0 until participant is destroyed + tone:*;duration=1000 - play DTMF tone 1 for 1000ms, then automatically destroy participant + tone:dialtone;local-only - play special tone "Dialtone" to local speaker only, until participant is destroyed + tone:ringback;remote-only - play special tone "Ringback" to remote participants only, until participant is destroyed + file://ringback.wav;local-only - play the file ringback.wav to local speaker only, until completed (automatically destroyed) or participant is manually destroyed + file://ringback.wav;duration=1000 - play the file ringback.wav for 1000ms (or until completed, if shorter), then automatically destroy participant + file://ringback.wav;repeat - play the file ringback.wav, repeating when complete until participant is destroyed + file://hi.wav;repeat;duration=9000 - play the file hi.wav for 9000ms, repeating as required, then automatically destroy the participant + cache:welcomeprompt;local-only - plays a prompt from the media cache with key/name "welcomeprompt" to the local speaker only + http://www.wav.com/test.wav;repeat - play the file test.wav, repeating when complete until participant is destroyed + http://www.wav.com/test.wav;prefetch - play the file test.wav, ensure that some audio is prefetched in order to assure smooth playback, + until completed (automatically destroyed) or participant is manually destroyed + + @param convHandle Handle of the conversation to create the + RemoteParticipant in + @param mediaUrl Url of media to play. See above. + + @return A handle to the newly created media participant + */ + virtual ParticipantHandle createMediaResourceParticipant(ConversationHandle convHandle, const resip::Uri& mediaUrl); + + /** + Creates a new local participant in the specified conversation. + A local participant is a representation of the local source (speaker) + and sink (microphone). The local participant is generally only + created once and is added to conversations in which the local speaker + and/or microphone should be involved. + + @return A handle to the newly created local participant + */ + virtual ParticipantHandle createLocalParticipant(); + + /** + Ends connections to the participant and removes it from all active + conversations. + + @param partHandle Handle of the participant to destroy + */ + virtual void destroyParticipant(ParticipantHandle partHandle); + + /** + Adds the specified participant to the specified conversation. + + @param convHandle Handle of the conversation to add to + @param partHandle Handle of the participant to add + + @note When running in sipXConversationMediaInterfaceMode you cannot + add a participant to more than one conversation. + */ + virtual void addParticipant(ConversationHandle convHandle, ParticipantHandle partHandle); + + /** + Removed the specified participant from the specified conversation. + The participants media to/from the conversation is stopped. If the + participant no longer exists in any conversation, then they are destroyed. + For a remote participant this means the call will be released. + + @param convHandle Handle of the conversation to remove from + @param partHandle Handle of the participant to remove + + @note When running in sipXConversationMediaInterfaceMode this method + can only be used on the LocalPartipant. + */ + virtual void removeParticipant(ConversationHandle convHandle, ParticipantHandle partHandle); + + /** + Removed the specified participant from the specified conversation. + The participants media to/from the conversation is stopped. If the + participant no longer exists in any conversation, then they are destroyed. + For a remote participant this means the call will be released. + + @param partHandle Handle of the participant to move + @param sourceConvHandle Handle of the conversation to move from + @param destConvHandle Handle of the conversation to move to + + @note When running in sipXConversationMediaInterfaceMode this method + can only be used on the LocalPartipant. + */ + virtual void moveParticipant(ParticipantHandle partHandle, ConversationHandle sourceConvHandle, ConversationHandle destConvHandle); + + /** + Modifies how the participant contributes to the particular conversation. + The send and receive gain can be set to a number between 0 and 100. + + @param convHandle Handle of the conversation to apply modication to + @param partHandle Handle of the participant to modify + */ + virtual void modifyParticipantContribution(ConversationHandle convHandle, ParticipantHandle partHandle, unsigned int inputGain, unsigned int outputGain); + + /** + Logs a multiline representation of the current state + of the mixing matrix. + */ + virtual void outputBridgeMatrix(); + + /** + Signal to the participant that it should provide ringback. Only + applicable to RemoteParticipants. For SIP this causes a 180 to be sent. + The early flag indicates if we are sending early media or not. + (ie. For SIP - SDP in 180). + + @param partHandle Handle of the participant to alert + @param earlyFlag Set to true to send early media + */ + virtual void alertParticipant(ParticipantHandle partHandle, bool earlyFlag = true); + + /** + Signal to the participant that the call is answered. Only applicable + to RemoteParticipants. For SIP this causes a 200 to be sent. + + @param partHandle Handle of the participant to answer + */ + virtual void answerParticipant(ParticipantHandle partHandle); + + /** + Rejects an incoming remote participant with the specified code. + Can also be used to reject an outbound participant request (due to REFER). + + @param partHandle Handle of the participant to reject + @param rejectCode Code sent to remote participant for rejection + */ + virtual void rejectParticipant(ParticipantHandle partHandle, unsigned int rejectCode); + + /** + Redirects the participant to another endpoint. For SIP this would + either be a 302 response or would initiate blind transfer (REFER) + request, depending on the state. + + @param partHandle Handle of the participant to redirect + @param destination Uri of destination to redirect to + */ + virtual void redirectParticipant(ParticipantHandle partHandle, const resip::NameAddr& destination); + + /** + This is used for attended transfer scenarios where both participants + are no longer managed by the conversation manager for SIP this will + send a REFER with embedded Replaces header. Note: Replace option cannot + be used with early dialogs in SIP. + + @param partHandle Handle of the participant to redirect + @param destPartHandle Handle ot the participant to redirect to + */ + virtual void redirectToParticipant(ParticipantHandle partHandle, ParticipantHandle destPartHandle); + + /** + This function is used to add a chunk of memory to a media/prompt cache. + Cached prompts can later be played back via createMediaParticipant. + Note: The caller is free to dispose of the memory upon return. + + @param name name of the cached item - used for playback + @param buffer Data object containing the media + @param type Type of media that is being added. (RAW_PCM_16 = 0) + */ + virtual void addBufferToMediaResourceCache(const resip::Data& name, const resip::Data& buffer, int type); + + /** + Builds a session capabilties SDPContents based on the passed in ipaddress + and codec ordering. + Note: Codec ordering is an array of sipX internal codecId's. Id's for + codecs not loaded are ignored. + */ + virtual void buildSessionCapabilities(const resip::Data& ipaddress, unsigned int numCodecIds, + unsigned int codecIds[], resip::SdpContents& sessionCaps); + + /////////////////////////////////////////////////////////////////////// + // Conversation Manager Handlers ////////////////////////////////////// + /////////////////////////////////////////////////////////////////////// + + // !slg! Note: We should eventually be passing back a generic ParticipantInfo object + // and not the entire SipMessage for these callbacks + + /** + Notifies an application about a new remote participant that is attempting + to contact it. + + @param partHandle Handle of the new incoming participant + @param msg Includes information about the caller such as name and address + @param autoAnswer Set to true if auto answer has been requested + */ + virtual void onIncomingParticipant(ParticipantHandle partHandle, const resip::SipMessage& msg, bool autoAnswer, ConversationProfile& conversationProfile) = 0; + + /** + Notifies an application about a new remote participant that is trying + to be contacted. This event is required to notify the application if a + call request has been initiated by a signaling mechanism other than + the application, such as an out-of-dialog REFER request. + + @param partHandle Handle of the new remote participant + @param msg Includes information about the destination requested + to be attempted + */ + virtual void onRequestOutgoingParticipant(ParticipantHandle partHandle, const resip::SipMessage& msg, ConversationProfile& conversationProfile) = 0; + + /** + Notifies an application about a disconnect by a remote participant. + For SIP this could be a BYE or a CANCEL request. + + @param partHandle Handle of the participant that terminated + @param statusCode The status Code for the termination. + */ + virtual void onParticipantTerminated(ParticipantHandle partHandle, unsigned int statusCode) = 0; + + /** + Notifies an application when a conversation has been destroyed. + This is useful for tracking conversations that get created when forking + occurs, and are destroyed when forked call is answered or ended. + + @param convHandle Handle of the destroyed conversation + */ + virtual void onConversationDestroyed(ConversationHandle convHandle) = 0; + + /** + Notifies an application when a Participant has been destroyed. This is + useful for tracking when audio playback via MediaResourceParticipants has + stopped. + + @param partHandle Handle of the destroyed participant + */ + virtual void onParticipantDestroyed(ParticipantHandle partHandle) = 0; + + /** + Notifies an applications that a outbound remote participant request has + forked. A new Related Conversation and Participant are created. + Both new handles and original handles are conveyed to the application + so it can track related conversations. + + @param relatedConvHandle Handle of newly created related conversation + @param relatedPartHandle Handle of the newly created related participant + @param origConvHandle Handle of the conversation that contained the + participant that forked + @param origParticipant Handle of the participant that forked + */ + virtual void onRelatedConversation(ConversationHandle relatedConvHandle, ParticipantHandle relatedPartHandle, + ConversationHandle origConvHandle, ParticipantHandle origPartHandle) = 0; + + /** + Notifies an application that a remote participant call attempt is + alerting the remote party. + + @param partHandle Handle of the participant that is alerting + @param msg SIP message that caused the alerting + */ + virtual void onParticipantAlerting(ParticipantHandle partHandle, const resip::SipMessage& msg) = 0; + + /** + Notifies an application that a remote participant call attempt is + now connected. + + @param partHandle Handle of the participant that is connected + @param msg SIP message that caused the connection + */ + virtual void onParticipantConnected(ParticipantHandle partHandle, const resip::SipMessage& msg) = 0; + + /** + Notifies an application that a redirect request has succeeded. + Indicates blind transfer or attended transfer status. + + @param partHandle Handle of the participant that was redirected + */ + virtual void onParticipantRedirectSuccess(ParticipantHandle partHandle) = 0; + + /** + Notifies an application that a redirect request has failed. + Indicates blind transfer or attended transfer status. + + @param partHandle Handle of the participant that was redirected + */ + virtual void onParticipantRedirectFailure(ParticipantHandle partHandle, unsigned int statusCode) = 0; + + /** + Notifies an application when an RFC2833 DTMF event is received from a + particular remote participant. + + @param partHandle Handle of the participant that received the digit + @param dtmf Integer representation of the DTMF tone received + @param duration Duration of the DTMF tone received + @param up Set to true if the DTMF key is up (otherwise down) + */ + virtual void onDtmfEvent(ParticipantHandle partHandle, int dtmf, int duration, bool up) = 0; + + /////////////////////////////////////////////////////////////////////// + // Media Related Methods - this may not be the right spot for these - move to LocalParticipant? + /////////////////////////////////////////////////////////////////////// + + virtual void setSpeakerVolume(int volume); + virtual void setMicrophoneGain(int gain); + virtual void muteMicrophone(bool mute); + virtual void enableEchoCancel(bool enable); + virtual void enableAutoGainControl(bool enable); + virtual void enableNoiseReduction(bool enable); + virtual void setSipXTOSValue(int tos) { mSipXTOSValue = tos; } + +protected: + + // Invite Session Handler ///////////////////////////////////////////////////// + virtual void onNewSession(resip::ClientInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg); + virtual void onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg); + virtual void onFailure(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg); + virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&); + virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage& msg); + virtual void onConnected(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg); + virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onConnectedConfirmed(resip::InviteSessionHandle, const resip::SipMessage &msg); + virtual void onStaleCallTimeout(resip::ClientInviteSessionHandle); + virtual void onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* msg); + virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg); + virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&); + virtual void onOffer(resip::InviteSessionHandle handle, const resip::SipMessage& msg, const resip::SdpContents& offer); + virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg); + virtual void onOfferRequestRejected(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onRemoteSdpChanged(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents& sdp); + virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg); + virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg); + virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onForkDestroyed(resip::ClientInviteSessionHandle); + + // DialogSetHandler ////////////////////////////////////////////// + virtual void onTrying(resip::AppDialogSetHandle, const resip::SipMessage& msg); + virtual void onNonDialogCreatingProvisional(resip::AppDialogSetHandle, const resip::SipMessage& msg); + + // ClientSubscriptionHandler /////////////////////////////////////////////////// + virtual void onUpdatePending(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder); + virtual void onUpdateActive(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder); + virtual void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder); + virtual void onTerminated(resip::ClientSubscriptionHandle h, const resip::SipMessage* notify); + virtual void onNewSubscription(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify); + virtual int onRequestRetry(resip::ClientSubscriptionHandle h, int retryMinimum, const resip::SipMessage& notify); + + // ServerSubscriptionHandler /////////////////////////////////////////////////// + virtual void onNewSubscription(resip::ServerSubscriptionHandle, const resip::SipMessage& sub); + virtual void onNewSubscriptionFromRefer(resip::ServerSubscriptionHandle, const resip::SipMessage& sub); + virtual void onRefresh(resip::ServerSubscriptionHandle, const resip::SipMessage& sub); + virtual void onTerminated(resip::ServerSubscriptionHandle); + virtual void onReadyToSend(resip::ServerSubscriptionHandle, resip::SipMessage&); + virtual void onNotifyRejected(resip::ServerSubscriptionHandle, const resip::SipMessage& msg); + virtual void onError(resip::ServerSubscriptionHandle, const resip::SipMessage& msg); + virtual void onExpiredByClient(resip::ServerSubscriptionHandle, const resip::SipMessage& sub, resip::SipMessage& notify); + virtual void onExpired(resip::ServerSubscriptionHandle, resip::SipMessage& notify); + virtual bool hasDefaultExpires() const; + virtual UInt32 getDefaultExpires() const; + + // OutOfDialogHandler ////////////////////////////////////////////////////////// + virtual void onSuccess(resip::ClientOutOfDialogReqHandle, const resip::SipMessage& response); + virtual void onFailure(resip::ClientOutOfDialogReqHandle, const resip::SipMessage& response); + virtual void onReceivedRequest(resip::ServerOutOfDialogReqHandle, const resip::SipMessage& request); + + // RedirectHandler ///////////////////////////////////////////////////////////// + virtual void onRedirectReceived(resip::AppDialogSetHandle, const resip::SipMessage& response); + virtual bool onTryingNextTarget(resip::AppDialogSetHandle, const resip::SipMessage& request); + + UserAgent* getUserAgent() { return mUserAgent; } + +private: + friend class DefaultDialogSet; + friend class Subscription; + + friend class UserAgentShutdownCmd; + void shutdown(void); + + // Note: In general the following fns are not thread safe and must be called from dum process + // loop only + friend class Conversation; + friend class OutputBridgeMixWeightsCmd; + void registerConversation(Conversation *); + void unregisterConversation(Conversation *); + + friend class Participant; + void registerParticipant(Participant *); + void unregisterParticipant(Participant *); + + friend class RemoteParticipant; + friend class UserAgent; + void setUserAgent(UserAgent *userAgent); + + friend class DtmfEvent; + friend class MediaEvent; + void notifyMediaEvent(ConversationHandle conversationHandle, int mediaConnectionId, MediaEvent::MediaEventType eventType); + void notifyDtmfEvent(ConversationHandle conversationHandle, int connectionId, int dtmf, int duration, bool up); + + friend class RemoteParticipantDialogSet; + friend class MediaResourceParticipant; + friend class LocalParticipant; + friend class BridgeMixer; + friend class MediaInterface; + unsigned int allocateRTPPort(); + void freeRTPPort(unsigned int port); + + flowmanager::FlowManager& getFlowManager() { return mFlowManager; } + + // exists here (as opposed to RemoteParticipant) - since it is required for OPTIONS responses + virtual void buildSdpOffer(ConversationProfile* profile, resip::SdpContents& offer); + + friend class MediaResourceParticipantDeleterCmd; + friend class CreateConversationCmd; + friend class DestroyConversationCmd; + friend class JoinConversationCmd; + friend class CreateRemoteParticipantCmd; + friend class CreateMediaResourceParticipantCmd; + friend class CreateLocalParticipantCmd; + friend class DestroyParticipantCmd; + friend class AddParticipantCmd; + friend class RemoveParticipantCmd; + friend class MoveParticipantCmd; + friend class ModifyParticipantContributionCmd; + friend class AlertParticipantCmd; + friend class AnswerParticipantCmd; + friend class RejectParticipantCmd; + friend class RedirectParticipantCmd; + friend class RedirectToParticipantCmd; + +private: + UserAgent* mUserAgent; + + typedef std::map<ConversationHandle, Conversation *> ConversationMap; + ConversationMap mConversations; + resip::Mutex mConversationHandleMutex; + ConversationHandle mCurrentConversationHandle; + ConversationHandle getNewConversationHandle(); // thread safe + Conversation* getConversation(ConversationHandle convHandle); + + typedef std::map<ParticipantHandle, Participant *> ParticipantMap; + ParticipantMap mParticipants; + resip::Mutex mParticipantHandleMutex; + ParticipantHandle mCurrentParticipantHandle; + ParticipantHandle getNewParticipantHandle(); // thread safe + Participant* getParticipant(ParticipantHandle partHandle); + + bool mLocalAudioEnabled; + MediaInterfaceMode mMediaInterfaceMode; + MediaInterfaceMode getMediaInterfaceMode() const { return mMediaInterfaceMode; } + + void post(resip::Message *message); + void post(resip::ApplicationMessage& message, unsigned int ms=0); + + std::deque<unsigned int> mRTPPortFreeList; + void initRTPPortFreeList(); + + MediaResourceCache mMediaResourceCache; + + // FlowManager Instance + flowmanager::FlowManager mFlowManager; + + // sipX Media related members + void createMediaInterfaceAndMixer(bool giveFocus, ConversationHandle ownerConversationHandle, + resip::SharedPtr<MediaInterface>& mediaInterface, BridgeMixer** bridgeMixer); + resip::SharedPtr<MediaInterface> getMediaInterface() const { assert(mMediaInterface.get()); return mMediaInterface; } + CpMediaInterfaceFactory* getMediaInterfaceFactory() { return mMediaFactory; } + BridgeMixer* getBridgeMixer() { return mBridgeMixer; } + CpMediaInterfaceFactory* mMediaFactory; + resip::SharedPtr<MediaInterface> mMediaInterface; + BridgeMixer* mBridgeMixer; + int mSipXTOSValue; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/ConversationManagerCmds.hxx b/src/libs/resiprocate/resip/recon/ConversationManagerCmds.hxx new file mode 100644 index 00000000..995b270d --- /dev/null +++ b/src/libs/resiprocate/resip/recon/ConversationManagerCmds.hxx @@ -0,0 +1,693 @@ +#if !defined(ConversationManagerCmds_hxx) +#define ConversationManagerCmds_hxx + +#include <resip/dum/DumCommand.hxx> + +#include "ConversationManager.hxx" +#include "Conversation.hxx" +#include "RemoteParticipant.hxx" +#include "LocalParticipant.hxx" +#include "MediaResourceParticipant.hxx" + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +namespace recon +{ + +/** + The classes defined here are used to pass commands from the + application thread to the UserAgent thread (process loop). + This ensures thread safety of the Conversation Manager methods that are + available to an application. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ +class CreateConversationCmd : public resip::DumCommand +{ + public: + CreateConversationCmd(ConversationManager* conversationManager, + ConversationHandle convHandle, + bool broadcastOnly) + : mConversationManager(conversationManager), + mConvHandle(convHandle), + mBroadcastOnly(broadcastOnly) {} + virtual void executeCommand() + { + Conversation* conversation = new Conversation(mConvHandle, *mConversationManager, 0, mBroadcastOnly); + assert(conversation); + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " CreateConversationCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ConversationHandle mConvHandle; + bool mBroadcastOnly; +}; + +class DestroyConversationCmd : public resip::DumCommand +{ + public: + DestroyConversationCmd(ConversationManager* conversationManager, + ConversationHandle convHandle) + : mConversationManager(conversationManager), + mConvHandle(convHandle) {} + virtual void executeCommand() + { + Conversation* conversation = mConversationManager->getConversation(mConvHandle); + if(conversation) + { + conversation->destroy(); + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " DestroyConversationCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ConversationHandle mConvHandle; +}; + +class JoinConversationCmd : public resip::DumCommand +{ + public: + JoinConversationCmd(ConversationManager* conversationManager, + ConversationHandle sourceConvHandle, + ConversationHandle destConvHandle) + : mConversationManager(conversationManager), + mSourceConvHandle(sourceConvHandle), + mDestConvHandle(destConvHandle) {} + virtual void executeCommand() + { + if(mConversationManager->getMediaInterfaceMode() == ConversationManager::sipXConversationMediaInterfaceMode) + { + WarningLog(<< "JoinConversationCmd: command not allowed in sipXConversationMediaInterfaceMode."); + } + else + { + Conversation* sourceConversation = mConversationManager->getConversation(mSourceConvHandle); + Conversation* destConversation = mConversationManager->getConversation(mDestConvHandle); + if(sourceConversation && destConversation) + { + if(sourceConversation == destConversation) + { + // NoOp + return; + } + sourceConversation->join(destConversation); // Join source Conversation into dest Conversation and destroy source conversation + } + else + { + if(!sourceConversation) + { + WarningLog(<< "JoinConversationCmd: invalid source conversation handle."); + } + if(!destConversation) + { + WarningLog(<< "JoinConversationCmd: invalid destination conversation handle."); + } + } + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " JoinConversationCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ConversationHandle mSourceConvHandle; + ConversationHandle mDestConvHandle; +}; + +class CreateRemoteParticipantCmd : public resip::DumCommand +{ + public: + CreateRemoteParticipantCmd(ConversationManager* conversationManager, + ParticipantHandle partHandle, + ConversationHandle convHandle, + const resip::NameAddr& destination, + ConversationManager::ParticipantForkSelectMode forkSelectMode) + : mConversationManager(conversationManager), + mPartHandle(partHandle), + mConvHandle(convHandle), + mDestination(destination), + mForkSelectMode(forkSelectMode) {} + virtual void executeCommand() + { + Conversation* conversation = mConversationManager->getConversation(mConvHandle); + if(conversation) + { + RemoteParticipantDialogSet* participantDialogSet = new RemoteParticipantDialogSet(*mConversationManager, mForkSelectMode); + RemoteParticipant *participant = participantDialogSet->createUACOriginalRemoteParticipant(mPartHandle); + if(participant) + { + conversation->addParticipant(participant); + participant->initiateRemoteCall(mDestination); + } + else + { + WarningLog(<< "CreateRemoteParticipantCmd: error creating UACOriginalRemoteParticipant."); + mConversationManager->onParticipantDestroyed(mPartHandle); + } + } + else + { + WarningLog(<< "CreateRemoteParticipantCmd: invalid conversation handle."); + mConversationManager->onParticipantDestroyed(mPartHandle); + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " CreateRemoteParticipantCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ParticipantHandle mPartHandle; + ConversationHandle mConvHandle; + resip::NameAddr mDestination; + ConversationManager::ParticipantForkSelectMode mForkSelectMode; +}; + +class CreateMediaResourceParticipantCmd : public resip::DumCommand +{ + public: + CreateMediaResourceParticipantCmd(ConversationManager* conversationManager, + ParticipantHandle partHandle, + ConversationHandle convHandle, + const resip::Uri& mediaUrl) + : mConversationManager(conversationManager), + mPartHandle(partHandle), + mConvHandle(convHandle), + mMediaUrl(mediaUrl) {} + virtual void executeCommand() + { + Conversation* conversation = mConversationManager->getConversation(mConvHandle); + if(conversation) + { + MediaResourceParticipant* mediaResourceParticipant = new MediaResourceParticipant(mPartHandle, *mConversationManager, mMediaUrl); + if(mediaResourceParticipant) + { + conversation->addParticipant(mediaResourceParticipant); + mediaResourceParticipant->startPlay(); + } + else + { + WarningLog(<< "CreateMediaResourceParticipantCmd: error creating MediaResourceParticipant."); + mConversationManager->onParticipantDestroyed(mPartHandle); + } + } + else + { + WarningLog(<< "CreateMediaResourceParticipantCmd: invalid conversation handle."); + mConversationManager->onParticipantDestroyed(mPartHandle); + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " CreateMediaResourceParticipantCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ParticipantHandle mPartHandle; + ConversationHandle mConvHandle; + resip::Uri mMediaUrl; +}; + +class CreateLocalParticipantCmd : public resip::DumCommand +{ + public: + CreateLocalParticipantCmd(ConversationManager* conversationManager, + ParticipantHandle partHandle) + : mConversationManager(conversationManager), + mPartHandle(partHandle) {} + virtual void executeCommand() + { + new LocalParticipant(mPartHandle, *mConversationManager); + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " CreateLocalParticipantCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ParticipantHandle mPartHandle; +}; + +class DestroyParticipantCmd : public resip::DumCommand +{ + public: + DestroyParticipantCmd(ConversationManager* conversationManager, + ParticipantHandle partHandle) + : mConversationManager(conversationManager), mPartHandle(partHandle) {} + DestroyParticipantCmd(const DestroyParticipantCmd& rhs) + : mConversationManager(rhs.mConversationManager), mPartHandle(rhs.mPartHandle) {} + virtual void executeCommand() + { + Participant* participant = mConversationManager->getParticipant(mPartHandle); + if(participant) + { + participant->destroyParticipant(); + } + } + resip::Message* clone() const { return new DestroyParticipantCmd(*this); } + EncodeStream& encode(EncodeStream& strm) const { strm << " DestroyParticipantCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ParticipantHandle mPartHandle; +}; + +class AddParticipantCmd : public resip::DumCommand +{ + public: + AddParticipantCmd(ConversationManager* conversationManager, + ConversationHandle convHandle, + ParticipantHandle partHandle) + : mConversationManager(conversationManager), + mConvHandle(convHandle), + mPartHandle(partHandle) {} + virtual void executeCommand() + { + Participant* participant = mConversationManager->getParticipant(mPartHandle); + Conversation* conversation = mConversationManager->getConversation(mConvHandle); + + if(participant && conversation) + { + if(mConversationManager->getMediaInterfaceMode() == ConversationManager::sipXConversationMediaInterfaceMode) + { + // Need to ensure, that we are not adding the participant to more than one conversation. + if(participant->getConversations().size() > 0) + { + WarningLog(<< "AddParticipantCmd: participants cannot belong to multiple conversations in sipXConversationMediaInterfaceMode."); + return; + } + } + conversation->addParticipant(participant); + } + else + { + if(!participant) + { + WarningLog(<< "AddParticipantCmd: invalid participant handle."); + } + if(!conversation) + { + WarningLog(<< "AddParticipantCmd: invalid conversation handle."); + } + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " AddParticipantCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ConversationHandle mConvHandle; + ParticipantHandle mPartHandle; +}; + +class RemoveParticipantCmd : public resip::DumCommand +{ + public: + RemoveParticipantCmd(ConversationManager* conversationManager, + ConversationHandle convHandle, + ParticipantHandle partHandle) + : mConversationManager(conversationManager), + mConvHandle(convHandle), + mPartHandle(partHandle) {} + virtual void executeCommand() + { + Participant* participant = mConversationManager->getParticipant(mPartHandle); + Conversation* conversation = mConversationManager->getConversation(mConvHandle); + if(participant && conversation) + { + if(mConversationManager->getMediaInterfaceMode() == ConversationManager::sipXConversationMediaInterfaceMode) + { + // Need to ensure, that only local participants can be removed from conversations + if(!dynamic_cast<LocalParticipant*>(participant)) + { + WarningLog(<< "RemoveParticipantCmd: only local participants can be removed from conversations in sipXConversationMediaInterfaceMode."); + return; + } + } + conversation->removeParticipant(participant); + } + else + { + if(!participant) + { + WarningLog(<< "RemoveParticipantCmd: invalid participant handle."); + } + if(!conversation) + { + WarningLog(<< "RemoveParticipantCmd: invalid conversation handle."); + } + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " RemoveParticipantCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ConversationHandle mConvHandle; + ParticipantHandle mPartHandle; +}; + +class MoveParticipantCmd : public resip::DumCommand +{ + public: + MoveParticipantCmd(ConversationManager* conversationManager, + ParticipantHandle partHandle, + ConversationHandle sourceConvHandle, + ConversationHandle destConvHandle) + : mConversationManager(conversationManager), + mPartHandle(partHandle), + mSourceConvHandle(sourceConvHandle), + mDestConvHandle(destConvHandle) {} + virtual void executeCommand() + { + Participant* participant = mConversationManager->getParticipant(mPartHandle); + Conversation* sourceConversation = mConversationManager->getConversation(mSourceConvHandle); + Conversation* destConversation = mConversationManager->getConversation(mDestConvHandle); + if(participant && sourceConversation && destConversation) + { + if(sourceConversation == destConversation) + { + // No-Op + return; + } + if(mConversationManager->getMediaInterfaceMode() == ConversationManager::sipXConversationMediaInterfaceMode) + { + // Need to ensure, that only local participants can be moved between conversations + if(!dynamic_cast<LocalParticipant*>(participant)) + { + WarningLog(<< "MoveParticipantCmd: only local participants can be moved between conversations in sipXConversationMediaInterfaceMode."); + return; + } + // Remove from old before adding to new conversation (since participants can't belong to multiple conversations + // and only local participants can be moved in sipXConversationMediaInterfaceMode - no need to worry about the + // hold/unhold issue that is mentioned in the 2nd half of the else statement for sipXGlobalMediaInterfaceMode) + sourceConversation->removeParticipant(participant); + destConversation->addParticipant(participant); + } + else + { + // Add to new conversation and remove from old (add before remove, so that hold/unhold won't happen) + destConversation->addParticipant(participant); + sourceConversation->removeParticipant(participant); + } + } + else + { + if(!participant) + { + WarningLog(<< "MoveParticipantCmd: invalid participant handle."); + } + if(!sourceConversation) + { + WarningLog(<< "MoveParticipantCmd: invalid source conversation handle."); + } + if(!destConversation) + { + WarningLog(<< "MoveParticipantCmd: invalid destination conversation handle."); + } + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " RemoveParticipantCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ParticipantHandle mPartHandle; + ConversationHandle mSourceConvHandle; + ConversationHandle mDestConvHandle; +}; + +class ModifyParticipantContributionCmd : public resip::DumCommand +{ + public: + ModifyParticipantContributionCmd(ConversationManager* conversationManager, + ConversationHandle convHandle, + ParticipantHandle partHandle, + unsigned int inputGain, + unsigned int outputGain) + : mConversationManager(conversationManager), + mConvHandle(convHandle), + mPartHandle(partHandle), + mInputGain(inputGain), + mOutputGain(outputGain) {} + virtual void executeCommand() + { + Participant* participant = mConversationManager->getParticipant(mPartHandle); + Conversation* conversation = mConversationManager->getConversation(mConvHandle); + if(participant && conversation) + { + conversation->modifyParticipantContribution(participant, mInputGain, mOutputGain); + } + else + { + if(!participant) + { + WarningLog(<< "ModifyParticipantContributionCmd: invalid participant handle."); + } + if(!conversation) + { + WarningLog(<< "ModifyParticipantContributionCmd: invalid conversation handle."); + } + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " ModifyParticipantContributionCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ConversationHandle mConvHandle; + ParticipantHandle mPartHandle; + unsigned int mInputGain; + unsigned int mOutputGain; +}; + +class OutputBridgeMixWeightsCmd : public resip::DumCommand +{ + public: + OutputBridgeMixWeightsCmd(ConversationManager* conversationManager) + : mConversationManager(conversationManager) {} + virtual void executeCommand() + { + assert(mConversationManager->getBridgeMixer()!=0); + mConversationManager->getBridgeMixer()->outputBridgeMixWeights(); + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " OutputBridgeMixWeightsCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; +}; + +class AlertParticipantCmd : public resip::DumCommand +{ + public: + AlertParticipantCmd(ConversationManager* conversationManager, + ParticipantHandle partHandle, + bool earlyFlag) + : mConversationManager(conversationManager), + mPartHandle(partHandle), + mEarlyFlag(earlyFlag) {} + virtual void executeCommand() + { + RemoteParticipant* remoteParticipant = dynamic_cast<RemoteParticipant*>(mConversationManager->getParticipant(mPartHandle)); + if(remoteParticipant) + { + if(mConversationManager->getMediaInterfaceMode() == ConversationManager::sipXConversationMediaInterfaceMode && mEarlyFlag) + { + // Need to ensure, that the remote paticipant is added to a conversation before doing an opertation that requires + // media (ie. EarlyMediaFlag set to true). + if(remoteParticipant->getConversations().size() == 0) + { + WarningLog(<< "AlertParticipantCmd: remote participants must to added to a conversation before alert with early flag can be used when in sipXConversationMediaInterfaceMode."); + return; + } + } + remoteParticipant->alert(mEarlyFlag); + } + else + { + WarningLog(<< "AlertParticipantCmd: invalid remote participant handle."); + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " AlertParticipantCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ParticipantHandle mPartHandle; + bool mEarlyFlag; +}; + +class AnswerParticipantCmd : public resip::DumCommand +{ + public: + AnswerParticipantCmd(ConversationManager* conversationManager, + ParticipantHandle partHandle) + : mConversationManager(conversationManager), + mPartHandle(partHandle) {} + virtual void executeCommand() + { + RemoteParticipant* remoteParticipant = dynamic_cast<RemoteParticipant*>(mConversationManager->getParticipant(mPartHandle)); + if(remoteParticipant) + { + if(mConversationManager->getMediaInterfaceMode() == ConversationManager::sipXConversationMediaInterfaceMode) + { + // Need to ensure, that the remote paticipant is added to a conversation before accepting the call + if(remoteParticipant->getConversations().size() == 0) + { + WarningLog(<< "AnswerParticipantCmd: remote participant must to added to a conversation before calling accept in sipXConversationMediaInterfaceMode."); + return; + } + } + remoteParticipant->accept(); + } + else + { + WarningLog(<< "AnswerParticipantCmd: invalid remote participant handle."); + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " AnswerParticipantCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ParticipantHandle mPartHandle; +}; + +class RejectParticipantCmd : public resip::DumCommand +{ + public: + RejectParticipantCmd(ConversationManager* conversationManager, + ParticipantHandle partHandle, + unsigned int rejectCode) + : mConversationManager(conversationManager), + mPartHandle(partHandle), + mRejectCode(rejectCode) {} + virtual void executeCommand() + { + RemoteParticipant* remoteParticipant = dynamic_cast<RemoteParticipant*>(mConversationManager->getParticipant(mPartHandle)); + if(remoteParticipant) + { + remoteParticipant->reject(mRejectCode); + } + else + { + WarningLog(<< "RejectParticipantCmd: invalid remote participant handle."); + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " RejectParticipantCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ParticipantHandle mPartHandle; + unsigned int mRejectCode; +}; + +class RedirectParticipantCmd : public resip::DumCommand +{ + public: + RedirectParticipantCmd(ConversationManager* conversationManager, + ParticipantHandle partHandle, + const resip::NameAddr& destination) + : mConversationManager(conversationManager), + mPartHandle(partHandle), + mDestination(destination) {} + virtual void executeCommand() + { + RemoteParticipant* remoteParticipant = dynamic_cast<RemoteParticipant*>(mConversationManager->getParticipant(mPartHandle)); + if(remoteParticipant) + { + remoteParticipant->redirect(mDestination); + } + else + { + WarningLog(<< "RedirectParticipantCmd: invalid remote participant handle."); + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " RedirectParticipantCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ParticipantHandle mPartHandle; + resip::NameAddr mDestination; +}; + +class RedirectToParticipantCmd : public resip::DumCommand +{ + public: + RedirectToParticipantCmd(ConversationManager* conversationManager, + ParticipantHandle partHandle, + ParticipantHandle destPartHandle) + : mConversationManager(conversationManager), + mPartHandle(partHandle), + mDestPartHandle(destPartHandle) {} + virtual void executeCommand() + { + RemoteParticipant* remoteParticipant = dynamic_cast<RemoteParticipant*>(mConversationManager->getParticipant(mPartHandle)); + RemoteParticipant* destRemoteParticipant = dynamic_cast<RemoteParticipant*>(mConversationManager->getParticipant(mDestPartHandle)); + if(remoteParticipant && destRemoteParticipant) + { + remoteParticipant->redirectToParticipant(destRemoteParticipant->getInviteSessionHandle()); + } + else + { + if(!remoteParticipant) + { + WarningLog(<< "RedirectToParticipantCmd: invalid remote participant handle."); + } + if(!destRemoteParticipant) + { + WarningLog(<< "RedirectToParticipantCmd: invalid destination remote participant handle."); + } + } + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " RedirectToParticipantCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + ConversationManager* mConversationManager; + ParticipantHandle mPartHandle; + ParticipantHandle mDestPartHandle; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/ConversationParticipantAssignment.cxx b/src/libs/resiprocate/resip/recon/ConversationParticipantAssignment.cxx new file mode 100644 index 00000000..cef0243c --- /dev/null +++ b/src/libs/resiprocate/resip/recon/ConversationParticipantAssignment.cxx @@ -0,0 +1,86 @@ +#include "ConversationParticipantAssignment.hxx" +#include "Participant.hxx" +#include "ReconSubsystem.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> + +using namespace recon; +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +ConversationParticipantAssignment::ConversationParticipantAssignment(Participant* participant, + unsigned int inputGain, + unsigned int outputGain) : + mParticipant(participant), + mInputGain(inputGain), + mOutputGain(outputGain) +{ +} + +Participant* +ConversationParticipantAssignment::getParticipant() +{ + return mParticipant; +} + +void +ConversationParticipantAssignment::setInputGain(unsigned int inputGain) +{ + mInputGain = inputGain; +} + +unsigned int +ConversationParticipantAssignment::getInputGain() +{ + return mInputGain; +} + + +void +ConversationParticipantAssignment::setOutputGain(unsigned int outputGain) +{ + mOutputGain = outputGain; +} + +unsigned int +ConversationParticipantAssignment::getOutputGain() +{ + return mOutputGain; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/ConversationParticipantAssignment.hxx b/src/libs/resiprocate/resip/recon/ConversationParticipantAssignment.hxx new file mode 100644 index 00000000..5dd783af --- /dev/null +++ b/src/libs/resiprocate/resip/recon/ConversationParticipantAssignment.hxx @@ -0,0 +1,71 @@ +#if !defined(ConversationParticipantAssignment_hxx) +#define ConversationParticipantAssignment_hxx + +namespace recon +{ +class Participant; + +/** + This class is used by a conversation to track assigned participants. + It also stores the participants contribution gain settings applied + to the owning conversation. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class ConversationParticipantAssignment +{ +public: + ConversationParticipantAssignment(Participant* participant=0, unsigned int inputGain=100, unsigned int outputGain=100); + + Participant* getParticipant(); + void setInputGain(unsigned int inputGain); + unsigned int getInputGain(); + + void setOutputGain(unsigned int outputGain); + unsigned int getOutputGain(); + +private: + Participant* mParticipant; + unsigned int mInputGain; + unsigned int mOutputGain; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/ConversationProfile.cxx b/src/libs/resiprocate/resip/recon/ConversationProfile.cxx new file mode 100644 index 00000000..e29c83bc --- /dev/null +++ b/src/libs/resiprocate/resip/recon/ConversationProfile.cxx @@ -0,0 +1,151 @@ +#include <resip/stack/Tuple.hxx> +#include <resip/stack/SipMessage.hxx> +#include <resip/stack/ExtensionParameter.hxx> + +#include "ReconSubsystem.hxx" +#include "ConversationProfile.hxx" + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +static const resip::ExtensionParameter p_answerafter("answer-after"); +static const resip::ExtensionParameter p_required("required"); + +ConversationProfile::ConversationProfile() : + mHandle(0), + mAllowAutoAnswer(false), + mAllowPriorityAutoAnswer(false), + mChallengeAutoAnswerRequests(false), + mChallengeOODReferRequests(true), + mSecureMediaMode(Srtp), + mSecureMediaRequired(false), + mDefaultSecureMediaCryptoSuite(SRTP_AES_CM_128_HMAC_SHA1_80), + mNatTraversalMode(NoNatTraversal), + mNatTraversalServerPort(0) +{ +} + +ConversationProfile::ConversationProfile(SharedPtr<Profile> baseProfile) : + UserProfile(baseProfile), + mHandle(0), + mAllowAutoAnswer(false), + mAllowPriorityAutoAnswer(false), + mChallengeAutoAnswerRequests(false), + mChallengeOODReferRequests(true), + mSecureMediaMode(Srtp), + mSecureMediaRequired(false), + mDefaultSecureMediaCryptoSuite(SRTP_AES_CM_128_HMAC_SHA1_80), + mNatTraversalMode(NoNatTraversal), + mNatTraversalServerPort(0) +{ +} + +ConversationProfileHandle +ConversationProfile::getHandle() +{ + return mHandle; +} + +void +ConversationProfile::setHandle(ConversationProfileHandle handle) +{ + assert(mHandle==0); + mHandle = handle; +} + +SdpContents& +ConversationProfile::sessionCaps() +{ + return mSessionCaps; +} + +const SdpContents +ConversationProfile::sessionCaps() const +{ + return mSessionCaps; +} + +bool +ConversationProfile::shouldAutoAnswer(const SipMessage& inviteRequest, bool *required) +{ + assert(inviteRequest.method() == INVITE); + bool shouldAutoAnswer = false; + bool autoAnswerRequired = false; + if(inviteRequest.exists(h_PrivAnswerMode) && inviteRequest.header(h_PrivAnswerMode).value() == "Auto") + { + if(allowPriorityAutoAnswer()) + { + shouldAutoAnswer = true; + } + if(inviteRequest.header(h_PrivAnswerMode).exists(p_required)) + { + autoAnswerRequired = true; + } + } + else if(inviteRequest.exists(h_AnswerMode) && inviteRequest.header(h_AnswerMode).value() == "Auto") + { + if(allowAutoAnswer()) + { + shouldAutoAnswer = true; + } + if(inviteRequest.header(h_AnswerMode).exists(p_required)) + { + autoAnswerRequired = true; + } + } + else if(allowAutoAnswer() && inviteRequest.exists(h_CallInfos)) + { + // Iterate through Call-Info headers and look for answer-after=0 parameter + for(GenericUris::const_iterator i = inviteRequest.header(h_CallInfos).begin(); i != inviteRequest.header(h_CallInfos).end(); i++) + { + if(i->exists(p_answerafter) && i->param(p_answerafter) == "0") + { + shouldAutoAnswer = true; + } + } + } + + if(required) + { + *required = autoAnswerRequired; + } + return shouldAutoAnswer; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/ConversationProfile.hxx b/src/libs/resiprocate/resip/recon/ConversationProfile.hxx new file mode 100644 index 00000000..e95dd635 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/ConversationProfile.hxx @@ -0,0 +1,295 @@ +#if !defined(ConversationProfile_hxx) +#define ConversationProfile_hxx + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <resip/dum/UserProfile.hxx> +#include <resip/stack/SdpContents.hxx> + +namespace recon +{ + +typedef unsigned int ConversationProfileHandle; + +/** + This class extends the resip UserProfile to include Conversation + Manager specific settings. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class ConversationProfile : public resip::UserProfile +{ +public: + + ConversationProfile(); + + enum NatTraversalMode + { + NoNatTraversal, + StunBindDiscovery, + TurnUdpAllocation, + TurnTcpAllocation, +#ifdef USE_SSL + TurnTlsAllocation +#endif + }; + + enum SecureMediaMode + { + NoSecureMedia, // Will accept secure media offers, but will not offer secure media in calls placed + Srtp, // SRTP with keying outside of media stream - ie. SDES key negotiation via SDP +#ifdef USE_SSL + SrtpDtls // SRTP with DTLS key negotiation +#endif + }; + + enum SecureMediaCryptoSuite + { + SRTP_AES_CM_128_HMAC_SHA1_32, + SRTP_AES_CM_128_HMAC_SHA1_80 + }; + + /** + Constructor + + @param baseProfile if any UserProfile settings are not set on this + class, then the setting will "fall through" to + the base profile + */ + ConversationProfile(resip::SharedPtr<resip::Profile> baseProfile); + + /** + Get the conversation profile handle. Returns 0 if called before adding + the profile to the ConversationManager. + + @return ConversationProfileHandle + */ + virtual ConversationProfileHandle getHandle(); + + /** + Get/Set the session capabilities. Session capabilites are expressed + as a SessionDesriptionProtocol body. Typically this is populated as you + would expect an SDP offer to look like that is generated by this application. + + This is used to generate SDP offers and form valid SDP answers. + + @return SdpContents representing the session capabilities + */ + virtual resip::SdpContents& sessionCaps(); + virtual const resip::SdpContents sessionCaps() const; + + /** + Get/Set wether auto answers are allowed, if an autoanswer indication + is found in a new inbound call request. + + @return bool True if auto answer is enabled + */ + virtual bool& allowAutoAnswer() { return mAllowAutoAnswer; } + virtual const bool allowAutoAnswer() const { return mAllowAutoAnswer; } + + /** + Get/Set wether priority auto answers are allowed, if a priority + autoanswer indication is found in a new inbound call request. + + @note Priority Auto Answers are indicated using the PrivAnswerMode + SIP header + + @return bool True if priority auto answer is enabled + */ + virtual bool& allowPriorityAutoAnswer() { return mAllowPriorityAutoAnswer; } + virtual const bool allowPriorityAutoAnswer() const { return mAllowPriorityAutoAnswer; } + + /** + Checks an Invite message for auto-answer headers against the current allow + settings. + + @param inviteRequest SIP Invite message to check + @param required Will return true if the auto-answer is "required" + */ + virtual bool shouldAutoAnswer(const resip::SipMessage& inviteRequest, bool *required = 0); + + /** + Get/Set wether auto answer requests should be digest challenged + or not. + + @note Requests will be challenged using the digest credentials + set on this profile + + @return bool True if auto answer requests should be challenged + */ + virtual bool& challengeAutoAnswerRequests() { return mChallengeAutoAnswerRequests; } + virtual const bool challengeAutoAnswerRequests() const { return mChallengeAutoAnswerRequests; } + + /** + Get/Set wether out of dialog REFER requests should be digest + challenged or not. + + @note Requests will be challenged using the digest credentials + set on this profile + + @return bool True if OOD REFER requests should be challenged + */ + virtual bool& challengeOODReferRequests() { return mChallengeOODReferRequests; } + virtual const bool challengeOODReferRequests() const { return mChallengeOODReferRequests; } + + /** + Get/Set the secure media mode that will be used for sending/receiving media packets. + NoSecureMedia - don't use any secure media strategies - RTP packets are sent + unencrypted via the specified transport. + Srtp - use SRTP with keying outside of media stream - ie. SDES key negotiation via SDP (default) + SrtpDtls - use SRTP with DTLS key negotiation + + @note If TurnTlsAllocation NatTraversalMode is used, then media will be secured from + this UA to the TURN the turn server, even if NoSecureMedia is used. + + @return SecureMediaMode + */ + virtual SecureMediaMode& secureMediaMode() { return mSecureMediaMode; } + virtual const SecureMediaMode secureMediaMode() const { return mSecureMediaMode; } + + /** + Get/Set the wether Secure Media is required (default is false). + - if required then SAVP transport protocol is signalled in SDP offers + - if not required then AVP transport portocol is signalled in SDP offers + and encryption=optional attribute is added + + @return true if secure media is required + */ + virtual bool& secureMediaRequired() { return mSecureMediaRequired; } + virtual const bool secureMediaRequired() const { return mSecureMediaRequired; } + + + /** + Get/Set the secure media default crypto suite. The default crypto suite is used when + forming SDP offers (SDES only - does not apply to DTLS-SRTP). + SRTP_AES_CM_128_HMAC_SHA1_32 - Counter Mode AES 128 bit encryption with + 32bit authenication code + SRTP_AES_CM_128_HMAC_SHA1_80 - Counter Mode AES 128 bit encryption with + 80bit authenication code (default) + + @return SecureMediaMode + */ + virtual SecureMediaCryptoSuite& secureMediaDefaultCryptoSuite() { return mDefaultSecureMediaCryptoSuite; } + virtual const SecureMediaCryptoSuite secureMediaDefaultCryptoSuite() const { return mDefaultSecureMediaCryptoSuite; } + + /** + Get/Set the NAT traversal mode that will be used for sending/receiving media packets. + NoNatTraversal - don't use any NAT traversal strategies - local address and port + are used in SDP negotiations + StunBindDiscovery - use Binding discovery on a STUN server, to discover and use + "public" address and port in SDP negotiations + TurnUdpAllocation - Use a TURN server as a media relay. Communicate to the TURN + server over UDP and Allocate a UDP relay address and port to + use in SDP negotiations + TurnTcpAllocation - Use a TURN server as a media relay. Communicate to the TURN + server over TCP and Allocate a UDP relay address and port to + use in SDP negotiations + TurnTlsAllocation - Use a TURN server as a media relay. Communicate to the TURN + server over TLS and Allocate a UDP relay address and port to + use in SDP negotiations + + @return NatTraversalMode + */ + virtual NatTraversalMode& natTraversalMode() { return mNatTraversalMode; } + virtual const NatTraversalMode natTraversalMode() const { return mNatTraversalMode; } + + /** + Get/Set the NAT traversal server hostname that will be used for if natTranversalMode + is anything other than NoNatTraversal. The server can be specified as an IP address + or a A-Records DNS resolvable hostname. SRV resolution is not yet supported. + + @return The server to use for NAT traversal + */ + virtual resip::Data& natTraversalServerHostname() { return mNatTraversalServerHostname; } + virtual const resip::Data natTraversalServerHostname() const { return mNatTraversalServerHostname; } + + /** + Get/Set the NAT traversal server port that will be used for if natTranversalMode + is anything other than NoNatTraversal. + + @return The server port to use for NAT traversal + */ + virtual unsigned short& natTraversalServerPort() { return mNatTraversalServerPort; } + virtual const unsigned short natTraversalServerPort() const { return mNatTraversalServerPort; } + + /** + Get/Set the STUN username that will be used for if natTranversalMode + is anything other than NoNatTraversal. The stun username/password is used for + both STUN and TURN server authentication. + + @return The STUN username + */ + virtual resip::Data& stunUsername() { return mStunUsername; } + virtual const resip::Data stunUsername() const { return mStunUsername; } + + /** + Get/Set the STUN password that will be used for if natTranversalMode + is anything other than NoNatTraversal. The stun username/password is used for + both STUN and TURN server authentication. + + @return The STUN password + */ + virtual resip::Data& stunPassword() { return mStunPassword; } + virtual const resip::Data stunPassword() const { return mStunPassword; } + +private: + friend class UserAgent; + void setHandle(ConversationProfileHandle handle); + + ConversationProfileHandle mHandle; + resip::SdpContents mSessionCaps; + bool mAllowAutoAnswer; + bool mAllowPriorityAutoAnswer; + bool mChallengeAutoAnswerRequests; + bool mChallengeOODReferRequests; + SecureMediaMode mSecureMediaMode; + bool mSecureMediaRequired; + SecureMediaCryptoSuite mDefaultSecureMediaCryptoSuite; + NatTraversalMode mNatTraversalMode; + resip::Data mNatTraversalServerHostname; + unsigned short mNatTraversalServerPort; + resip::Data mStunUsername; + resip::Data mStunPassword; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/DefaultDialogSet.cxx b/src/libs/resiprocate/resip/recon/DefaultDialogSet.cxx new file mode 100644 index 00000000..b4dc4f13 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/DefaultDialogSet.cxx @@ -0,0 +1,64 @@ +#include "ConversationManager.hxx" +#include "DefaultDialogSet.hxx" +#include "UserAgent.hxx" +#include "ReconSubsystem.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <resip/dum/DialogUsageManager.hxx> +#include <resip/dum/ClientInviteSession.hxx> +#include <resip/dum/ServerInviteSession.hxx> +#include <resip/dum/ClientSubscription.hxx> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +DefaultDialogSet::DefaultDialogSet(ConversationManager& conversationManager) +: AppDialogSet(conversationManager.getUserAgent()->getDialogUsageManager()), + mConversationManager(conversationManager) +{ +} + +SharedPtr<UserProfile> +DefaultDialogSet::selectUASUserProfile(const SipMessage& msg) +{ + return mConversationManager.getUserAgent()->getIncomingConversationProfile(msg); +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/DefaultDialogSet.hxx b/src/libs/resiprocate/resip/recon/DefaultDialogSet.hxx new file mode 100644 index 00000000..bcb9dd4b --- /dev/null +++ b/src/libs/resiprocate/resip/recon/DefaultDialogSet.hxx @@ -0,0 +1,75 @@ +#if !defined(DefaultDialogSet_hxx) +#define DefaultDialogSet_hxx + +#include <resip/dum/AppDialogSet.hxx> +#include <resip/dum/InviteSessionHandler.hxx> +#include <resip/dum/DialogSetHandler.hxx> +#include <resip/dum/SubscriptionHandler.hxx> + +namespace resip +{ +class DialogUsageManager; +class SipMessage; +} + +namespace recon +{ +class ConversationManager; + +/** + This class is used by non-Invite DialogSets. Invite DialogSets + are managed by RemoteParticipantDialogSet + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class DefaultDialogSet : public resip::AppDialogSet +{ + public: + DefaultDialogSet(ConversationManager& conversationManager); + + protected: + resip::SharedPtr<resip::UserProfile> selectUASUserProfile(const resip::SipMessage&); + + private: + ConversationManager &mConversationManager; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/DtmfEvent.cxx b/src/libs/resiprocate/resip/recon/DtmfEvent.cxx new file mode 100644 index 00000000..3b39bf46 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/DtmfEvent.cxx @@ -0,0 +1,80 @@ +#include "RemoteParticipant.hxx" +#include "DtmfEvent.hxx" + +#include <rutil/Logger.hxx> + +using namespace recon; +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +DtmfEvent::DtmfEvent(ConversationManager& conversationManager, ConversationHandle conversationHandle, int connectionId, int dtmf, int duration, bool up) : + mConversationManager(conversationManager), + mConversationHandle(conversationHandle), + mConnectionId(connectionId), + mDtmfTone(dtmf), + mDuration(duration), + mUp(up) +{ +} + +void +DtmfEvent::executeCommand() +{ + mConversationManager.notifyDtmfEvent(mConversationHandle, mConnectionId, mDtmfTone, mDuration, mUp); +} + +resip::Message* +DtmfEvent::clone() const +{ + assert(0); + return 0; +} + +EncodeStream& +DtmfEvent::encode(EncodeStream& strm) const +{ + strm << " DtmfEvent: conversationHandle=" << mConversationHandle << ", connectionId=" << mConnectionId << ", tone=" << mDtmfTone << " duration=" << mDuration << " up=" << mUp; + return strm; +} + +EncodeStream& +DtmfEvent::encodeBrief(EncodeStream& strm) const +{ + return encode(strm); +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/DtmfEvent.hxx b/src/libs/resiprocate/resip/recon/DtmfEvent.hxx new file mode 100644 index 00000000..5baf93fb --- /dev/null +++ b/src/libs/resiprocate/resip/recon/DtmfEvent.hxx @@ -0,0 +1,74 @@ +#if !defined(DtmfEvent_hxx) +#define DtmfEvent_hxx + +#include <resip/dum/DumCommand.hxx> + +namespace recon +{ + +class Message; + +/** + This class represents the data passed in a DTMF event. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class DtmfEvent : public resip::DumCommand +{ + public: + DtmfEvent(ConversationManager& conversationManager, ConversationHandle conversationHandle, int connectionId, int dtmf, int duration, bool up); + virtual void executeCommand(); + + Message* clone() const; + EncodeStream& encode(EncodeStream& strm) const; + EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + ConversationManager& mConversationManager; + ConversationHandle mConversationHandle; + int mConnectionId; + int mDtmfTone; + int mDuration; + bool mUp; +}; + + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/FlowManagerSipXSocket.cxx b/src/libs/resiprocate/resip/recon/FlowManagerSipXSocket.cxx new file mode 100644 index 00000000..5fcc3fca --- /dev/null +++ b/src/libs/resiprocate/resip/recon/FlowManagerSipXSocket.cxx @@ -0,0 +1,191 @@ +#include <asio.hpp> +#include <boost/function.hpp> +#include <rutil/Data.hxx> + +// SYSTEM INCLUDES +#include <assert.h> +#include <stdio.h> +#ifndef _WIN32 +#include <netinet/in.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#endif + +// APPLICATION INCLUDES +#include "Flow.hxx" +#include "FlowManagerSipXSocket.hxx" + +using namespace std; +using namespace recon; + +// Constructor +FlowManagerSipXSocket::FlowManagerSipXSocket(Flow* flow, int tos) + : OsSocket(), + mFlow(flow) +{ +#ifndef WIN32 + setsockopt (flow->getSocketDescriptor(), IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)); +#else + // TODO:: Implement QoS request under Windows. The following works under NT 4.0 and Windows 9x only (http://support.microsoft.com/kb/248611) + setsockopt (flow->getSocketDescriptor(), IPPROTO_IP, 3 /* IP_TOS */, (char *)&tos, sizeof(int)); +#endif +} + + +// Destructor +FlowManagerSipXSocket::~FlowManagerSipXSocket() +{ +} + +OsSocket* FlowManagerSipXSocket::getSocket() +{ + assert(false); + return 0; +} + +int FlowManagerSipXSocket::getSocketDescriptor() const +{ + assert(mFlow); + return mFlow->getSelectSocketDescriptor(); +} + +int FlowManagerSipXSocket::read(char* buffer, int bufferLength) +{ + //cout << "read: bufferlen=" << bufferLength << endl; + assert(mFlow); + unsigned int len = bufferLength; + if(mFlow->receive(buffer, len, 0)) + { + //cout << "read: done: len=0" << endl; + return 0; + } + + //cout << "read: done: len=" << len << endl; + return len; +} + +int FlowManagerSipXSocket::read(char* buffer, int bufferLength, + UtlString* ipAddress, int* port) +{ + asio::ip::address receivedAddress; + unsigned short receivedPort=0; + + //cout << "read(get address): bufferlen=" << bufferLength << endl; // ********** + assert(mFlow); + + unsigned int len = bufferLength; + if(mFlow->receive(buffer, len, 0, &receivedAddress, &receivedPort)) + { + //cout << "read(get address): done, len=0" << endl; + return 0; + } + + if (ipAddress) + { + *ipAddress = receivedAddress.to_string().c_str(); + } + + if (port) + { + *port = (int)receivedPort ; + } + //cout << "read(get address): done, len=" << len << endl; + + return len; +} + +int FlowManagerSipXSocket::read(char* buffer, int bufferLength, + struct in_addr* ipAddress, int* port) +{ + int iRC ; + int iReceivedPort ; + UtlString receivedIp ; + + iRC = read(buffer, bufferLength, &receivedIp, &iReceivedPort) ; + if (ipAddress) + ipAddress->s_addr = inet_addr(receivedIp) ; + + if (port) + *port = iReceivedPort ; + + return iRC ; +} + + +int FlowManagerSipXSocket::read(char* buffer, int bufferLength, long waitMilliseconds) +{ + //cout << "read: bufferlen=" << bufferLength << ", waitMilliseconds=" << waitMilliseconds << "ms" << endl; + assert(mFlow); + unsigned int len = bufferLength; + if(!mFlow->receive(buffer, len, waitMilliseconds)) + { + return len; + } + else + { + return 0; + } +} + +int FlowManagerSipXSocket::write(const char* buffer, int bufferLength) +{ + //cout << "write: bufferlen=" << bufferLength << endl; // ********* + assert(mFlow); + mFlow->send((char *)buffer, bufferLength); + return 0; +} + +int FlowManagerSipXSocket::write(const char* buffer, + int bufferLength, + const char* ipAddress, + int port) +{ + //cout << "write: bufferlen=" << bufferLength << ", address=" << ipAddress << ", port=" << port << endl; + assert(mFlow); + mFlow->sendTo(asio::ip::address::from_string(ipAddress), port, (char*)buffer, bufferLength); + return 0; +} + +int FlowManagerSipXSocket::write(const char* buffer, int bufferLength, + long waitMilliseconds) +{ + //cout << "write: bufferlen=" << bufferLength << ", waitMilliseconds=" << waitMilliseconds << endl; + assert(0); + mFlow->send((char*)buffer, bufferLength); // !SLG! We don't have a timed out send??? Not used by sipX anyway + return 0; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/FlowManagerSipXSocket.hxx b/src/libs/resiprocate/resip/recon/FlowManagerSipXSocket.hxx new file mode 100644 index 00000000..a31074a3 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/FlowManagerSipXSocket.hxx @@ -0,0 +1,174 @@ + +#ifndef _FlowManagerSipXSocket_hxx_ +#define _FlowManagerSipXSocket_hxx_ + +#include "os/OsSocket.h" +#include "FlowManager.hxx" + +using namespace flowmanager; + +namespace recon +{ + +class FlowManagerSipXSocket : public OsSocket +{ +/* //////////////////////////// PUBLIC //////////////////////////////////// */ +public: + + FlowManagerSipXSocket(Flow* flow, int tos); + virtual ~FlowManagerSipXSocket(); + +/* ============================ MANIPULATORS ============================== */ + + virtual OsSocket* getSocket(); + + virtual int read(char* buffer, int bufferLength) ; + virtual int read(char* buffer, int bufferLength, + UtlString* ipAddress, int* port); + virtual int read(char* buffer, int bufferLength, + struct in_addr* ipAddress, int* port); + virtual int read(char* buffer, int bufferLength, long waitMilliseconds); + + + virtual int write(const char* buffer, int bufferLength); + virtual int write(const char* buffer, int bufferLength, + const char* ipAddress, int port); + virtual int write(const char* buffer, int bufferLength, + long waitMilliseconds); + + virtual void close() { return; } + //: Closes the socket + + virtual void makeNonblocking() { return; } + virtual void makeBlocking() { return; } + //: Make the connect and all subsequent operations blocking + // By default the sockets are blocking. + +/* ============================ ACCESSORS ================================= */ + + virtual OsSocket::IpProtocolSocketType getIpProtocol() const { return OsSocket::CUSTOM; } + //:Return the protocol type of this socket + + virtual UtlBoolean reconnect() { return TRUE; } + //:Set up the connection again, assuming the connection failed + + virtual int getSocketDescriptor() const; + //:Return the socket descriptor + // Warning: Use of this method risks the creation of platform-dependent + // code. + + virtual void getLocalHostIp(UtlString* localHostAddress) const { *localHostAddress = "FlowManagerHost"; } + //:Return this host's ip address + // Returns the ip address for this host on which this socket is communicating + // On multi-homed machines, this is the address to the NIC over which the + // socket communicates. The format is of the form: xx.x.xxx.x + + virtual const UtlString& getLocalIp() const { static UtlString ipAddr="0.0.0.0"; return ipAddr; } + //:Return this socket's Local Ip Address + + virtual int getLocalHostPort() const { return 0; } + //:Return the local port number + // Returns the port to which this socket is bound on this host. + + virtual void getRemoteHostName(UtlString* remoteHostName) const { *remoteHostName = "FlowManagerRemoteHost"; } + //:Return remote host name + // Returns a string containing the name of the host on which the socket + // on the other end of this socket is bound. This may be the local + // name, a fully qualified domain name or anything in between. + + + virtual void getRemoteHostIp(struct in_addr* remoteHostAddress, + int* remotePort = NULL) { printf("getRemoteHostIp\n"); return; } + //:Return remote host ip address + // Returns the ip address for the host on which the socket on the + // other end of this socket is bound. + + virtual void getRemoteHostIp(UtlString* remoteHostAddress, + int* remotePort = NULL) { printf("getRemoteHostIp\n"); return; } + //:Return remote host ip address + // Returns the ip address for the host on which the socket on the + // other end of this socket is bound. The format is of the form: + // xx.x.xxx.x + + virtual int getRemoteHostPort() const { return 0; } + //:Return the remote port number + // Returns the port to which the socket on the other end of this socket + // is bound. + + +/* ============================ INQUIRY =================================== */ + + virtual UtlBoolean isOk() const { return TRUE; } + //:Returns TRUE if this socket's descriptor is not the invalid descriptor + + virtual UtlBoolean isConnected() const { return TRUE; } + //:Returns TRUE if this socket is connected + + virtual UtlBoolean isReadyToReadEx(long waitMilliseconds, UtlBoolean &rSocketError) const { return TRUE; } + //:Poll if there are bytes to read + // Returns TRUE if socket is read to read. + // Returns FALSE if wait expires or socket error. + // rSocketError returns TRUE is socket error occurred. + + virtual UtlBoolean isReadyToRead(long waitMilliseconds = 0) const { return TRUE; } + //:Poll if there are bytes to read + // Returns TRUE if socket is ready to read. + // Returns FALSE if wait expires or socket error. + + virtual UtlBoolean isReadyToWrite(long waitMilliseconds = 0) const { return TRUE; } + //:Poll if socket is able to write without blocking + + +/* //////////////////////////// PROTECTED ///////////////////////////////// */ +protected: + + +/* //////////////////////////// PRIVATE /////////////////////////////////// */ +private: + Flow* mFlow; +}; + +} +/* ============================ INLINE METHODS ============================ */ + + +/* ///////////////////////// HELPER CLASSES /////////////////////////////// */ + + + +#endif // _FlowManagerSipXSocket_h_ + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/HandleTypes.hxx b/src/libs/resiprocate/resip/recon/HandleTypes.hxx new file mode 100644 index 00000000..a0033127 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/HandleTypes.hxx @@ -0,0 +1,48 @@ +#if !defined(HandleTypes_hxx) +#define HandleTypes_hxx + +namespace recon +{ + +typedef unsigned int ConversationHandle; +typedef unsigned int ParticipantHandle; +typedef unsigned int SubscriptionHandle; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/LocalParticipant.cxx b/src/libs/resiprocate/resip/recon/LocalParticipant.cxx new file mode 100644 index 00000000..53242721 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/LocalParticipant.cxx @@ -0,0 +1,103 @@ +#include "BridgeMixer.hxx" +#include "ConversationManager.hxx" +#include "Conversation.hxx" +#include "UserAgent.hxx" +#include "ReconSubsystem.hxx" +#include "LocalParticipant.hxx" +#include <CpTopologyGraphInterface.h> + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +LocalParticipant::LocalParticipant(ParticipantHandle partHandle, + ConversationManager& conversationManager) +: Participant(partHandle, conversationManager), + mLocalPortOnBridge(-1) +{ + InfoLog(<< "LocalParticipant created, handle=" << mHandle); +} + +LocalParticipant::~LocalParticipant() +{ + // unregister from Conversations + // Note: ideally this functionality would exist in Participant Base class - but dynamic_cast required in unregisterParticipant will not work + ConversationMap::iterator it; + for(it = mConversations.begin(); it != mConversations.end(); it++) + { + it->second->unregisterParticipant(this); + } + mConversations.clear(); + InfoLog(<< "LocalParticipant destroyed, handle=" << mHandle); +} + +int +LocalParticipant::getConnectionPortOnBridge() +{ + if(mLocalPortOnBridge == -1) + { + assert(getMediaInterface() != 0); + ((CpTopologyGraphInterface*)getMediaInterface()->getInterface())->getResourceInputPortOnBridge(VIRTUAL_NAME_LOCAL_STREAM_OUTPUT,0,mLocalPortOnBridge); + InfoLog(<< "LocalParticipant getConnectionPortOnBridge, handle=" << mHandle << ", localPortOnBridge=" << mLocalPortOnBridge); + } + return mLocalPortOnBridge; +} + +void +LocalParticipant::addToConversation(Conversation *conversation, unsigned int inputGain, unsigned int outputGain) +{ + Participant::addToConversation(conversation, inputGain, outputGain); + + if(mConversationManager.getMediaInterfaceMode() == ConversationManager::sipXConversationMediaInterfaceMode) + { + // The Local participant is in a new Conversation, give that conversation focus + assert(getMediaInterface() != 0); + getMediaInterface()->getInterface()->giveFocus(); + } +} + +void +LocalParticipant::destroyParticipant() +{ + delete this; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/LocalParticipant.hxx b/src/libs/resiprocate/resip/recon/LocalParticipant.hxx new file mode 100644 index 00000000..fc90147f --- /dev/null +++ b/src/libs/resiprocate/resip/recon/LocalParticipant.hxx @@ -0,0 +1,74 @@ +#if !defined(LocalParticipant_hxx) +#define LocalParticipant_hxx + +#include "ConversationManager.hxx" +#include "Participant.hxx" + +namespace recon +{ +class ConversationManager; + +/** + This class represents a local participant. + A local participant is a representation of the local source (speaker) + and sink (microphone). The local participant is generally only + created once and is added to conversations in which the local speaker + and/or microphone should be involved. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class LocalParticipant : public Participant +{ + public: + LocalParticipant(ParticipantHandle partHandle, + ConversationManager& conversationManager); + virtual ~LocalParticipant(); + + virtual int getConnectionPortOnBridge(); + virtual void addToConversation(Conversation *conversation, unsigned int inputGain = 100, unsigned int outputGain = 100); + virtual void destroyParticipant(); + + protected: + private: + int mLocalPortOnBridge; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/ActiveCallInfo.hxx b/src/libs/resiprocate/resip/recon/MOHParkServer/ActiveCallInfo.hxx new file mode 100644 index 00000000..bdbfb653 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/ActiveCallInfo.hxx @@ -0,0 +1,69 @@ +#if !defined(ActiveCallInfo_hxx) +#define ActiveCallInfo_hxx + +#include <list> +#include <resip/stack/Uri.hxx> +#include <rutil/Data.hxx> + +namespace mohparkserver +{ + +class ActiveCallInfo +{ +public: + ActiveCallInfo(const resip::Uri& heldUri, + const resip::Uri& invokingUri, + const resip::Data& holdType, + unsigned int participantId, + unsigned int conversationId) : + mHeldUri(heldUri), + mInvokingUri(invokingUri), + mHoldType(holdType), + mParticipantId(participantId), + mConversationId(conversationId) {} + resip::Uri mHeldUri; + resip::Uri mInvokingUri; + resip::Data mHoldType; + unsigned int mParticipantId; + unsigned int mConversationId; +}; +typedef std::list<ActiveCallInfo> CallInfoList; + +} + +#endif + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/AppSubsystem.cxx b/src/libs/resiprocate/resip/recon/MOHParkServer/AppSubsystem.cxx new file mode 100644 index 00000000..fa6a02ba --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/AppSubsystem.cxx @@ -0,0 +1,38 @@ +#include "AppSubsystem.hxx" + +AppSubsystem AppSubsystem::MOHPARKSERVER("MOHPARKSERVER"); + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/AppSubsystem.hxx b/src/libs/resiprocate/resip/recon/MOHParkServer/AppSubsystem.hxx new file mode 100644 index 00000000..c43d1db0 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/AppSubsystem.hxx @@ -0,0 +1,61 @@ +#if !defined(AppSubsystem_hxx) +#define AppSubsystem_hxx + +#include <iostream> +#include <rutil/Subsystem.hxx> + +/** + This class is used in the logging subsystem to identify + logging messages generated from the MOHPark server. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class AppSubsystem : public resip::Subsystem +{ + public: + // Add new systems below + static AppSubsystem MOHPARKSERVER; + + private: + explicit AppSubsystem(const char* rhs) : resip::Subsystem(rhs) {}; + explicit AppSubsystem(const resip::Data& rhs); + AppSubsystem& operator=(const resip::Data& rhs); +}; + +#endif + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/ConfigParser.cxx b/src/libs/resiprocate/resip/recon/MOHParkServer/ConfigParser.cxx new file mode 100644 index 00000000..c9f174bd --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/ConfigParser.cxx @@ -0,0 +1,428 @@ +#include "ConfigParser.hxx" + +#include "AppSubsystem.hxx" + +#include <iostream> +#include <fstream> +#include <iterator> + +#include <rutil/DnsUtil.hxx> +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/WinLeakCheck.hxx> +#include <resip/stack/Tuple.hxx> + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM AppSubsystem::MOHPARKSERVER + +namespace mohparkserver +{ + +ConfigParser::ConfigParser(int argc, char** argv) : + // Defaults + mMOHUri("sip:moh@server.com"), + mMOHRegistrationTime(3600), + mMOHFilenameUrl("file:music.wav;repeat"), + mParkUri("sip:park@server.com"), + mParkRegistrationTime(3600), + mParkMOHFilenameUrl("file:music.wav;repeat"), + mParkOrbitRangeStart(6000), + mParkNumOrbits(10), + mParkOrbitRegistrationTime(3600), + mMaxParkTime(600), // 600 seconds = 10 mins + mUdpPort(0), + mTcpPort(0), + mTlsPort(0), + mTlsDomain(DnsUtil::getLocalHostName()), + mKeepAlives(true), + mMediaPortRangeStart(50000), + mMediaPortRangeSize(100), + mHttpPort(5082), + mLogLevel("INFO"), + mLogFilename("mohparkserver.log"), + mLogFileMaxBytes(5000000), // about 5Mb size + mSocketFunc(0) +{ + //mAddress = DnsUtil::getLocalIpAddress(); + + // Parse config file first + parseConfigFile("mohparkserver.config"); + + // Parse command line options + // Note: command line overrides config file setting + parseCommandLine(argc, argv); +} + +ConfigParser::ConfigParser() : + // Defaults + mMOHUri("sip:moh@server.com"), + mMOHRegistrationTime(3600), + mMOHFilenameUrl("file:music.wav;repeat"), + mParkUri("sip:park@server.com"), + mParkRegistrationTime(3600), + mParkMOHFilenameUrl("file:music.wav;repeat"), + mParkOrbitRangeStart(6000), + mParkNumOrbits(10), + mParkOrbitRegistrationTime(3600), + mMaxParkTime(600), // 600 seconds = 10 mins + mUdpPort(0), + mTcpPort(0), + mTlsPort(0), + mTlsDomain(DnsUtil::getLocalHostName()), + mKeepAlives(true), + mMediaPortRangeStart(50000), + mMediaPortRangeSize(100), + mHttpPort(5082), + mLogLevel("INFO"), + mLogFilename("mohparkserver.log"), + mLogFileMaxBytes(5000000) // about 5Mb size +{ +} + +ConfigParser::~ConfigParser() +{ +} + +void +ConfigParser::parseCommandLine(int argc, char** argv) +{ + // Loop through command line arguments and process them + for(int i = 1; i < argc; i++) + { + Data commandName(argv[i]); + + // Process all commandNames that don't take values + if(isEqualNoCase(commandName, "-?") || + isEqualNoCase(commandName, "--?") || + isEqualNoCase(commandName, "--help") || + isEqualNoCase(commandName, "/?")) + { + cout << "Command line options are:" << endl; + cout << " -a <IP Address> - bind SIP transports to this IP address" << endl; + cout << " -d <DNS servers> - comma seperated list of DNS servers, overrides OS detected list" << endl; + cout << " -up <port num> - local port number to use for UDP SIP messaging" << endl; + cout << " -tp <port num> - local port number to use for TCP SIP messaging" << endl; + cout << " -sp <port num> - local port number to use for TLS SIP messaging" << endl; + cout << " -td <domain name> - domain name to use for TLS server connections" << endl; + cout << " -nk - no keepalives, set this to disable sending of keepalives" << endl; + cout << " -op <SIP URI> - URI of a proxy server to use a SIP outbound proxy" << endl; + cout << " -l <NONE|ERR|WARNING|INFO|DEBUG|STACK> - logging level" << endl; + cout << endl; + cout << "Sample Command line:" << endl; + cout << "MOHParkServer -a 192.168.1.100 -l DEBUG" << endl; + exit(0); + } + else if(isEqualNoCase(commandName, "-nk")) + { + mKeepAlives = false; + } + else if(commandName.at(0) == '-') + { + commandName = commandName.substr(1); // Remove - + + // Process commands that have values + Data commandValue(i+1 < argc ? argv[i+1] : Data::Empty); + if(commandValue.empty() || commandValue.at(0) == '-') + { + cerr << "Invalid command line parameters!" << endl; + exit(-1); + } + i++; // increment argument + + //cout << "Command Line Name='" << commandName << "' value='" << commandValue << "'" << endl; + if(!processOption(commandName.lowercase(), commandValue)) + { + cerr << "Invalid command line parameters!" << endl; + exit(-1); + } + } + else + { + cerr << "Invalid command line parameters!" << endl; + exit(-1); + } + } +} + +void +ConfigParser::parseConfigFile(const Data& filename) +{ + ifstream configFile(filename.c_str()); + + string sline; + while(getline(configFile, sline)) + { + Data line(sline); + Data name; + Data value; + ParseBuffer pb(line); + + pb.skipWhitespace(); + const char * anchor = pb.position(); + if(pb.eof() || *anchor == '#') continue; // if line is a comment or blank then skip it + // Look for = + pb.skipToOneOf("= \t"); + if(!pb.eof()) + { + pb.data(name,anchor); + if(*pb.position()!='=') + { + pb.skipToChar('='); + } + pb.skipChar('='); + pb.skipWhitespace(); + anchor = pb.position(); + if(!pb.eof()) + { + pb.skipToEnd(); + pb.data(value, anchor); + } + //cout << "Config file Name='" << name << "' value='" << value << "'" << endl; + processOption(name.lowercase(), value); + } + } +} + +bool +ConfigParser::processOption(const Data& name, const Data& value) +{ + bool result = true; + if(name == "mohuri") + { + result = assignNameAddr("MOH Uri", value, mMOHUri); + } + else if(name == "mohpassword") + { + mMOHPassword = value; + } + else if(name == "mohregistrationtime") + { + mMOHRegistrationTime = value.convertUnsignedLong(); + } + else if(name == "mohfilename") + { + Uri url("file:music.wav;repeat"); + Data urlData; + if(value.find("http://") != Data::npos || + value.find("file:") != Data::npos) + { + // URL was specified - add repeat parameter + urlData = value + ";repeat"; + } + else + { + urlData = "file:" + value + ";repeat"; + } + try + { + Uri temp(urlData); + url = temp; + } + catch(BaseException& e) + { + cerr << "Invalid MOHFilename format=" << value << ": " << e << endl; + cerr << "Using " << url << " instead." << endl; + } + mMOHFilenameUrl = url; + } + else if(name == "parkuri") + { + result = assignNameAddr("Park Uri", value, mParkUri); + } + else if(name == "parkpassword") + { + mParkPassword = value; + } + else if(name == "parkregistrationtime") + { + mParkRegistrationTime = value.convertUnsignedLong(); + } + else if(name == "parkmohfilename") + { + Uri url("file:music.wav;repeat"); + Data urlData; + if(value.find("http://") != Data::npos || + value.find("file:") != Data::npos) + { + // URL was specified - add repeat parameter + urlData = value + ";repeat"; + } + else + { + urlData = "file:" + value + ";repeat"; + } + try + { + Uri temp(urlData); + url = temp; + } + catch(BaseException& e) + { + cerr << "Invalid Park MOHFilename format=" << value << ": " << e << endl; + cerr << "Using " << url << " instead." << endl; + } + mParkMOHFilenameUrl = url; + } + else if(name == "parkorbitrangestart") + { + mParkOrbitRangeStart = value.convertUnsignedLong(); + } + else if(name == "parknumorbits") + { + mParkNumOrbits = value.convertUnsignedLong(); + } + else if(name == "parkorbitregistrationtime") + { + mParkOrbitRegistrationTime = value.convertUnsignedLong(); + } + else if(name == "parkorbitpassword") + { + mParkOrbitPassword = value; + } + else if(name == "maxparktime") + { + mMaxParkTime = value.convertUnsignedLong(); + } + else if(name == "a" || name == "ipaddress") + { + if(!value.empty()) + { + mAddress = value; + } + } + else if(name == "d" || name == "dnsservers") + { + mDnsServers = value; + } + else if(name == "up" || name == "udpport") + { + mUdpPort = (unsigned short)value.convertUnsignedLong(); + } + else if(name == "tp" || name == "tcpport") + { + mTcpPort = (unsigned short)value.convertUnsignedLong(); + } + else if(name == "sp" || name == "tlsport") + { + mTlsPort = (unsigned short)value.convertUnsignedLong(); + } + else if(name == "td" || name == "tlsdomain") + { + mTlsDomain = value; + } + else if(name == "keepalives") + { + if(value == "1" || value == "true" || value == "on" || value == "enable") + { + mKeepAlives = true; + } + else if(value == "0" || value == "false" || value == "off" || value == "disable") + { + mKeepAlives = false; + } + } + else if(name == "op" || name == "outboundproxy") + { + result = assignNameAddr("outbound proxy", value, mOutboundProxy); + } + else if(name == "mediaportrangestart") + { + mMediaPortRangeStart = (unsigned short)value.convertUnsignedLong(); + } + else if(name == "mediaportrangesize") + { + mMediaPortRangeSize = (unsigned short)value.convertUnsignedLong(); + } + else if(name == "httpport") + { + mHttpPort = (unsigned short)value.convertUnsignedLong(); + } + else if(name == "sipxlogfilename") + { + mSipXLogFilename = value; + } + else if(name == "l" || name == "loglevel") + { + mLogLevel = value; + } + else if(name == "logfilename") + { + mLogFilename = value; + } + else if(name == "logfilemaxbytes") + { + mLogFileMaxBytes = value.convertUnsignedLong(); + } + else + { + result = false; + } + return result; +} + +bool +ConfigParser::assignNameAddr(const Data& settingName, const Data& settingValue, NameAddr& nameAddr) +{ + try + { + if(!settingValue.empty()) + { + NameAddr tempNameAddr(settingValue); + nameAddr = tempNameAddr; + } + } + catch(resip::BaseException& e) + { + // Try adding sip: to address to see if it will be valid + try + { + NameAddr tempNameAddr(Data("sip:" + settingValue)); + nameAddr = tempNameAddr; + } + catch(resip::BaseException&) + { + cerr << "Invalid " << settingName << " NameAddr format=" << settingValue << ": " << e << endl; + return false; + } + } + return true; +} + +} + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/ConfigParser.hxx b/src/libs/resiprocate/resip/recon/MOHParkServer/ConfigParser.hxx new file mode 100644 index 00000000..6c0d2e1e --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/ConfigParser.hxx @@ -0,0 +1,103 @@ +#if !defined(ConfigParser_hxx) +#define ConfigParser_hxx + +#include <list> +#include <rutil/Data.hxx> +#include <rutil/Socket.hxx> +#include <resip/stack/NameAddr.hxx> + +namespace mohparkserver +{ + +class ConfigParser +{ +public: + ConfigParser(int argc, char** argv); // Use this constructor to parse command line arguments and read configuration file from disk + ConfigParser(); // If you use this constructor you must manually set all configuration values + virtual ~ConfigParser(); + + void parseCommandLine(int argc, char** argv); + void parseConfigFile(const resip::Data& filename); + bool processOption(const resip::Data& name, const resip::Data& value); + bool assignNameAddr(const resip::Data& settingName, const resip::Data& settingValue, resip::NameAddr& nameAddr); + + // MOH Settings + resip::NameAddr mMOHUri; + resip::Data mMOHPassword; + unsigned long mMOHRegistrationTime; + resip::Uri mMOHFilenameUrl; + + // Park Settings + resip::NameAddr mParkUri; + resip::Data mParkPassword; + unsigned long mParkRegistrationTime; + resip::Uri mParkMOHFilenameUrl; + unsigned long mParkOrbitRangeStart; + unsigned long mParkNumOrbits; + unsigned long mParkOrbitRegistrationTime; + resip::Data mParkOrbitPassword; + unsigned long mMaxParkTime; + + // SIP Settings + resip::Data mAddress; + resip::Data mDnsServers; + unsigned short mUdpPort; + unsigned short mTcpPort; + unsigned short mTlsPort; + resip::Data mTlsDomain; + resip::NameAddr mOutboundProxy; + bool mKeepAlives; + + // Media Settings + unsigned short mMediaPortRangeStart; + unsigned short mMediaPortRangeSize; + resip::Data mSipXLogFilename; + + // General Settings + unsigned short mHttpPort; + resip::Data mLogLevel; + resip::Data mLogFilename; + unsigned int mLogFileMaxBytes; + + // Store pointer to after socket creation fn - can be used for QOS + resip::AfterSocketCreationFuncPtr mSocketFunc; +}; + +} + +#endif + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/HttpBase.cxx b/src/libs/resiprocate/resip/recon/MOHParkServer/HttpBase.cxx new file mode 100644 index 00000000..5d3c0f3e --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/HttpBase.cxx @@ -0,0 +1,267 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <cassert> + +#include <rutil/Data.hxx> +#include <rutil/Socket.hxx> +#include <resip/stack/Symbols.hxx> +#include <rutil/TransportType.hxx> +#include <rutil/Logger.hxx> +#include <resip/stack/Tuple.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/ParseBuffer.hxx> +#include <resip/stack/Transport.hxx> + +#include "AppSubsystem.hxx" +#include "HttpBase.hxx" +#include "HttpConnection.hxx" +#include "WebAdmin.hxx" +#include "rutil/WinLeakCheck.hxx" + + +using namespace resip; +using namespace mohparkserver; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM AppSubsystem::MOHPARKSERVER + + +HttpBase::~HttpBase() +{ +#if defined(WIN32) + closesocket(mFd); +#else + close(mFd); +#endif + mFd=0; + for( int i=0; i<MaxConnections; i++) + { + if ( mConnection[i] ) + { + delete mConnection[i] ; mConnection[i]=0; + } + } +} + + +HttpBase::HttpBase( int port, IpVersion ipVer, const Data& realm ): + mRealm(realm), + nextConnection(0), + mTuple(Data::Empty,port,ipVer,TCP,Data::Empty) +{ + sane = true; + + for ( int i=0 ; i<MaxConnections; i++) + { + mConnection[i]=0; + } + +#ifdef USE_IPV6 + mFd = ::socket(ipVer == V4 ? PF_INET : PF_INET6, SOCK_STREAM, 0); +#else + mFd = ::socket(PF_INET, SOCK_STREAM, 0); +#endif + + if ( mFd == INVALID_SOCKET ) + { + int e = getErrno(); + ErrLog (<< "Failed to create socket: " << strerror(e)); + sane = false; + return; + } + + DebugLog (<< "Creating fd=" << (int)mFd + << (ipVer == V4 ? " V4/" : " V6/") ); + + int on = 1; +#if !defined(WIN32) + if ( ::setsockopt ( mFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) ) +#else + if ( ::setsockopt ( mFd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) ) +#endif + { + int e = getErrno(); + ErrLog (<< "Couldn't set sockoptions SO_REUSEPORT | SO_REUSEADDR: " << strerror(e)); + sane = false; + return; + } + + DebugLog (<< "Binding to " << Tuple::inet_ntop(mTuple)); + + if ( ::bind( mFd, &mTuple.getMutableSockaddr(), mTuple.length()) == SOCKET_ERROR ) + { + int e = getErrno(); + if ( e == EADDRINUSE ) + { + ErrLog (<< mTuple << " already in use "); + } + else + { + ErrLog (<< "Could not bind to " << mTuple); + } + sane = false; + return; + } + + bool ok = makeSocketNonBlocking(mFd); + if ( !ok ) + { + ErrLog (<< "Could not make HTTP socket non-blocking " << port ); + sane = false; + return; + } + + // do the listen, seting the maximum queue size for compeletly established + // sockets -- on linux, tcp_max_syn_backlog should be used for the incomplete + // queue size(see man listen) + int e = listen(mFd,5 ); + + if (e != 0 ) + { + int e = getErrno(); + InfoLog (<< "Failed listen " << strerror(e)); + sane = false; + return; + } +} + + +void +HttpBase::buildFdSet(FdSet& fdset) +{ + fdset.setRead( mFd ); + + for( int i=0; i<MaxConnections; i++) + { + if ( mConnection[i] ) + { + mConnection[i]->buildFdSet(fdset); + } + } +} + + +void +HttpBase::process(FdSet& fdset) +{ + if (fdset.readyToRead(mFd)) + { + Tuple tuple(mTuple); + struct sockaddr& peer = tuple.getMutableSockaddr(); + socklen_t peerLen = tuple.length(); + Socket sock = accept( mFd, &peer, &peerLen); + if ( sock == SOCKET_ERROR ) + { + int e = getErrno(); + switch (e) + { + case EWOULDBLOCK: + // !jf! this can not be ready in some cases + return; + default: + ErrLog(<< "Some error reading from socket: " << e); + // .bwc. This is almost certainly a bad assert that a nefarious + // endpoint could hit. + // assert(0); // Transport::error(e); + } + return; + } + makeSocketNonBlocking(sock); + + int c = nextConnection; + nextConnection = ( nextConnection+1 ) % MaxConnections; + + if ( mConnection[c] ) + { + delete mConnection[c]; mConnection[c] = 0; + } + + mConnection[c] = new HttpConnection(*this,sock); + + DebugLog (<< "Received TCP connection as connection=" << c << " fd=" << (int)sock); + } + + for( int i=0; i<MaxConnections; i++) + { + if ( mConnection[i] ) + { + bool ok = mConnection[i]->process(fdset); + if ( !ok ) + { + delete mConnection[i]; mConnection[i]=0; + } + } + } +} + + +void HttpBase::setPage( const Data& page, int pageNumber, int response, const Mime& type ) +{ + for ( int i=0 ; i<MaxConnections; i++) + { + if ( mConnection[i] ) + { + if ( mConnection[i]->mPageNumber == pageNumber ) + { + mConnection[i]->setPage( page,response,type ); + } + } + } +} + +bool HttpBase::isSane() +{ + return sane; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/HttpBase.hxx b/src/libs/resiprocate/resip/recon/MOHParkServer/HttpBase.hxx new file mode 100644 index 00000000..b3614f29 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/HttpBase.hxx @@ -0,0 +1,104 @@ +#if !defined(MOHPARK_HTTPBASE_HXX) +#define MOHPARK_HTTPBASE_HXX + +#include <rutil/Data.hxx> +#include <rutil/Socket.hxx> +#include <rutil/TransportType.hxx> +#include <resip/stack/Tuple.hxx> +#include <resip/stack/Mime.hxx> + +namespace mohparkserver +{ +class HttpConnection; + +class HttpBase +{ + friend class HttpConnection; + + public: + HttpBase( int port, resip::IpVersion version, const resip::Data& realm ); + virtual ~HttpBase(); + + void buildFdSet(resip::FdSet& fdset); + void process(resip::FdSet& fdset); + + bool isSane(); + + protected: + virtual void buildPage( const resip::Data& uri, + int pageNumber, + const resip::Data& user, + const resip::Data& password )=0; + void setPage( const resip::Data& page, + int pageNumber, + int response=200, + const resip::Mime& pType = resip::Mime("text","html") ); + + const resip::Data mRealm; + + private: + static const int MaxConnections = 30; + + resip::Socket mFd; + int nextConnection; + resip::Tuple mTuple; + + bool sane; + + HttpConnection* mConnection[MaxConnections]; + +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/HttpConnection.cxx b/src/libs/resiprocate/resip/recon/MOHParkServer/HttpConnection.cxx new file mode 100644 index 00000000..0054353d --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/HttpConnection.cxx @@ -0,0 +1,419 @@ +#include <cassert> + +#include <rutil/Data.hxx> +#include <rutil/Socket.hxx> +#include <resip/stack/Symbols.hxx> +#include <rutil/TransportType.hxx> +#include <rutil/Logger.hxx> +#include <resip/stack/Tuple.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/ParseBuffer.hxx> + +#include "AppSubsystem.hxx" +#include "HttpBase.hxx" +#include "HttpConnection.hxx" + +using namespace resip; +using namespace mohparkserver; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM AppSubsystem::MOHPARKSERVER + +int HttpConnection::nextPageNumber=1; + + +HttpConnection::HttpConnection( HttpBase& base, Socket pSock ): + mHttpBase( base ), + mPageNumber(nextPageNumber++), + mSock(pSock), + mParsedRequest(false) +{ + assert( mSock > 0 ); +} + + +HttpConnection::~HttpConnection() +{ + assert( mSock > 0 ); +#ifdef WIN32 + closesocket(mSock); mSock=0; +#else + close(mSock); mSock=0; +#endif +} + + +void +HttpConnection::buildFdSet(FdSet& fdset) +{ + if ( !mTxBuffer.empty() ) + { + fdset.setWrite(mSock); + } + fdset.setRead(mSock); +} + + +bool +HttpConnection::process(FdSet& fdset) +{ + if ( fdset.hasException(mSock) ) + { + int errNum = 0; + int errNumSize = sizeof(errNum); + getsockopt(mSock,SOL_SOCKET,SO_ERROR,(char *)&errNum,(socklen_t *)&errNumSize); + InfoLog (<< "Exception reading from socket " + << (int)mSock << " code: " << errNum << "; closing connection"); + return false; + } + + if ( fdset.readyToRead( mSock ) ) + { + bool ok = processSomeReads(); + if ( !ok ) + { + return false; + } + } + if ( (!mTxBuffer.empty()) && fdset.readyToWrite( mSock ) ) + { + bool ok = processSomeWrites(); + if ( !ok ) + { + return false; + } + } + + return true; +} + + +void +HttpConnection::setPage(const Data& pPage,int response,const Mime& pType) +{ + Data page(pPage); + + switch (response) + { + case 401: + { + mTxBuffer += "HTTP/1.0 401 Unauthorized"; mTxBuffer += Symbols::CRLF; + + page = ("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">" + "<html><head>" + "<title>401 Unauthorized</title>" + "</head><body>" + "<h1>Unauthorized</h1>" + "</body></html>" ); + } + break; + + case 404: + { + mTxBuffer += "HTTP/1.0 404 Not Found"; mTxBuffer += Symbols::CRLF; + + page = ("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">" + "<html><head>" + "<title>404 Not Found</title>" + "</head><body>" + "<h1>Unauthorized</h1>" + "</body></html>" ); + } + break; + + case 301: + { + mTxBuffer += "HTTP/1.0 301 Moved Permanently"; mTxBuffer += Symbols::CRLF; + mTxBuffer += "Location: http:/activecalls.html"; mTxBuffer += Symbols::CRLF; + + page = ("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">" + "<html><head>" + "<title>301 Moved Permanently</title>" + "</head><body>" + "<h1>Moved</h1>" + "</body></html>" ); + } + break; + + case 200: + { + mTxBuffer += "HTTP/1.0 200 OK" ; mTxBuffer += Symbols::CRLF; + } + break; + + default: + { + assert(0); + + Data resp; + { + DataStream s(resp); + s << response; + s.flush(); + } + + mTxBuffer += "HTTP/1.0 "; + mTxBuffer += resp; + mTxBuffer += "OK" ; mTxBuffer += Symbols::CRLF; + } + break; + } + + Data len; + { + DataStream s(len); + s << page.size(); + s.flush(); + } + + mTxBuffer += "WWW-Authenticate: Basic realm=\""; + if ( mHttpBase.mRealm.empty() ) + { + mTxBuffer += resip::DnsUtil::getLocalHostName(); + } + else + { + mTxBuffer += mHttpBase.mRealm; + } + mTxBuffer += "\" "; + mTxBuffer += Symbols::CRLF; + + mTxBuffer += "Server: Console RFSS " ; +// mTxBuffer += Data(VersionUtils::instance().displayVersion()); + mTxBuffer += Symbols::CRLF; + mTxBuffer += "Mime-version: 1.0 " ; mTxBuffer += Symbols::CRLF; + mTxBuffer += "Pragma: no-cache " ; mTxBuffer += Symbols::CRLF; + mTxBuffer += "Content-Length: "; mTxBuffer += len; mTxBuffer += Symbols::CRLF; + + mTxBuffer += "Content-Type: " ; + mTxBuffer += pType.type() ; + mTxBuffer +="/" ; + mTxBuffer += pType.subType() ; mTxBuffer += Symbols::CRLF; + + mTxBuffer += Symbols::CRLF; + + mTxBuffer += page; +} + + +bool +HttpConnection::processSomeReads() +{ + const int bufSize = 8000; + char buf[bufSize]; + + +#if defined(WIN32) + int bytesRead = ::recv(mSock, buf, bufSize, 0); +#else + int bytesRead = ::read(mSock, buf, bufSize); +#endif + + if (bytesRead == INVALID_SOCKET) + { + int e = getErrno(); + switch (e) + { + case EAGAIN: + InfoLog (<< "No data ready to read"); + return true; + case EINTR: + InfoLog (<< "The call was interrupted by a signal before any data was read."); + break; + case EIO: + InfoLog (<< "I/O error"); + break; + case EBADF: + InfoLog (<< "fd is not a valid file descriptor or is not open for reading."); + break; + case EINVAL: + InfoLog (<< "fd is attached to an object which is unsuitable for reading."); + break; + case EFAULT: + InfoLog (<< "buf is outside your accessible address space."); + break; + default: + InfoLog (<< "Some other error"); + break; + } + InfoLog (<< "Failed read on " << (int)mSock << " " << strerror(e)); + return false; + } + else if (bytesRead == 0) + { + InfoLog (<< "Connection closed by remote " ); + return false; + } + + //DebugLog (<< "HttpConnection::processSomeReads() " + // << " read=" << bytesRead); + + mRxBuffer += Data( buf, bytesRead ); + + tryParse(); + + return true; +} + + +void +HttpConnection::tryParse() +{ + //DebugLog (<< "parse " << mRxBuffer ); + + ParseBuffer pb(mRxBuffer); + + pb.skipToChar(Symbols::SPACE[0]); + const char* start = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + + if (pb.eof()) + { + // parse failed - just return + return; + } + + Data uri; + pb.data( uri, start ); + + DebugLog (<< "parse found URI " << uri ); + mParsedRequest = true; + + + Data user; + Data password; + + try + { + pb.skipToChars( "Authorization" ); + if ( !pb.eof() ) + { + if ( pb.eof() ) DebugLog( << "Did not find Authorization header" ); + pb.skipToChars( "Basic" ); pb.skipN(6); + if ( pb.eof() ) DebugLog( << "Did not find Authorization basic " ); + pb.skipWhitespace(); + if ( pb.eof() ) DebugLog( << "Something weird in Auhtorization header " ); + if ( !pb.eof() ) + { + const char* a = pb.position(); + pb.skipNonWhitespace(); + Data buf = pb.data(a); + + DebugLog (<< "parse found basic base64 auth data of " << buf ); + Data auth = buf.base64decode(); + + //DebugLog (<< "parse found basic auth data of " << auth ); + + ParseBuffer p(auth); + const char* a1 = p.position(); + p.skipToChar(':'); + user = p.data(a1); + const char* a2 = p.skipChar(':'); + p.skipToEnd(); + password = p.data(a2); + + //DebugLog (<< "parse found basic auth data with user=" << user + // << " password=" << password ); + } + } + } + catch ( ... ) + { + ErrLog (<< "Some problem finding Authorization header in HTTP request" ); + } + + mHttpBase.buildPage(uri,mPageNumber,user,password); +} + + +bool +HttpConnection::processSomeWrites() +{ + if ( mTxBuffer.empty() ) + { + return true; + } + + //DebugLog (<< "Writing " << mTxBuffer ); + +#if defined(WIN32) + int bytesWritten = ::send( mSock, mTxBuffer.data(), mTxBuffer.size(), 0); +#else + int bytesWritten = ::write(mSock, mTxBuffer.data(), mTxBuffer.size() ); +#endif + + if (bytesWritten == INVALID_SOCKET) + { + int e = getErrno(); + InfoLog (<< "HttpConnection failed write on " << mSock << " " << strerror(e)); + + return false; + } + + if (bytesWritten == (int)mTxBuffer.size() ) + { + DebugLog (<< "Wrote it all" ); + mTxBuffer = Data::Empty; + + return false; // return false causes connection to close and clean up + } + else + { + Data rest = mTxBuffer.substr(bytesWritten); + mTxBuffer = rest; + DebugLog( << "Wrote " << bytesWritten << " bytes - still need to do " << mTxBuffer ); + } + + return true; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/HttpConnection.hxx b/src/libs/resiprocate/resip/recon/MOHParkServer/HttpConnection.hxx new file mode 100644 index 00000000..d8710e51 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/HttpConnection.hxx @@ -0,0 +1,98 @@ +#if !defined(MOHPARK_HTTPCONNECTION_HXX) +#define MOHPARK_HTTPCONNECTION_HXX + +#include <rutil/Data.hxx> +#include <rutil/Socket.hxx> +#include <rutil/TransportType.hxx> +#include <resip/stack/Tuple.hxx> +#include <resip/stack/Mime.hxx> + +#include <repro/UserStore.hxx> +#include "HttpBase.hxx" + +namespace mohparkserver +{ + +class HttpConnection +{ + friend class HttpBase; + + public: + HttpConnection( HttpBase& webAdmin, resip::Socket pSock ); + ~HttpConnection(); + + void buildFdSet(resip::FdSet& fdset); + bool process(resip::FdSet& fdset); + + void setPage(const resip::Data& page, + int response, + const resip::Mime& pType ); + + private: + bool processSomeReads(); + bool processSomeWrites(); + void tryParse(); + + HttpBase& mHttpBase; + const int mPageNumber; + static int nextPageNumber; + + resip::Socket mSock; + resip::Data mRxBuffer; + resip::Data mTxBuffer; + bool mParsedRequest; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/MOHManager.cxx b/src/libs/resiprocate/resip/recon/MOHParkServer/MOHManager.cxx new file mode 100644 index 00000000..1bc92acb --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/MOHManager.cxx @@ -0,0 +1,278 @@ +#include "AppSubsystem.hxx" +#include "MOHManager.hxx" +#include "Server.hxx" +#include "../UserAgent.hxx" + +#include <resip/stack/ExtensionParameter.hxx> +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/WinLeakCheck.hxx> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM AppSubsystem::MOHPARKSERVER + +static const resip::ExtensionParameter p_automaton("automaton"); +static const resip::ExtensionParameter p_byeless("+sip.byeless"); +static const resip::ExtensionParameter p_rendering("+sip.rendering"); + +namespace mohparkserver +{ + +MOHManager::MOHManager(Server& server) : + mServer(server), + mConversationProfileHandle(0), + mMusicFilenameChanged(false) +{ +} + +MOHManager::~MOHManager() +{ +} + +void +MOHManager::startup() +{ + // Initialize settings + initializeSettings(mServer.mConfig.mMOHFilenameUrl); + + // Setup ConversationProfile + initializeConversationProfile(mServer.mConfig.mMOHUri, mServer.mConfig.mMOHPassword, mServer.mConfig.mMOHRegistrationTime, mServer.mConfig.mOutboundProxy); + + // Create an initial conversation and start music + ConversationHandle convHandle = mServer.createConversation(true /* broadcast only*/); + mServer.createMediaResourceParticipant(convHandle, mServer.mConfig.mMOHFilenameUrl); // Play Music + mConversations[convHandle]; + mMusicFilenameChanged = false; +} + +void +MOHManager::initializeConversationProfile(const NameAddr& uri, const Data& password, unsigned long registrationTime, const resip::NameAddr& outboundProxy) +{ + if(mConversationProfileHandle) + { + mServer.mMyUserAgent->destroyConversationProfile(mConversationProfileHandle); + mConversationProfileHandle = 0; + } + + // Setup ConversationProfile + SharedPtr<ConversationProfile> mohConversationProfile = SharedPtr<ConversationProfile>(new ConversationProfile(mServer.mUserAgentMasterProfile)); + mohConversationProfile->setDefaultRegistrationTime(registrationTime); + mohConversationProfile->setDefaultRegistrationRetryTime(120); // 2 mins + mohConversationProfile->setDefaultFrom(uri); + mohConversationProfile->setDigestCredential(uri.uri().host(), uri.uri().user(), password); + if(!outboundProxy.uri().host().empty()) + { + mohConversationProfile->setOutboundProxy(outboundProxy.uri()); + } + mohConversationProfile->challengeOODReferRequests() = false; + mohConversationProfile->setExtraHeadersInReferNotifySipFragEnabled(true); // Enable dialog identifying headers in SipFrag bodies of Refer Notifies - required for a music on hold server + NameAddr capabilities; + capabilities.param(p_automaton); + capabilities.param(p_byeless); + capabilities.param(p_rendering) = "\"no\""; + mohConversationProfile->setUserAgentCapabilities(capabilities); + mohConversationProfile->natTraversalMode() = ConversationProfile::NoNatTraversal; + mohConversationProfile->secureMediaMode() = ConversationProfile::NoSecureMedia; + mServer.buildSessionCapabilities(mohConversationProfile->sessionCaps()); + mConversationProfileHandle = mServer.mMyUserAgent->addConversationProfile(mohConversationProfile); +} + +void +MOHManager::initializeSettings(const resip::Uri& musicFilename) +{ + Lock lock(mMutex); + mMusicFilename = musicFilename; + // If there is a single conversation with no participants, then there are no + // current parties on hold - re-create the conversation with new music + if(mConversations.size() == 1 && mConversations.begin()->second.size() == 0) + { + mServer.destroyConversation(mConversations.begin()->first); + mConversations.clear(); + + // re-create an initial conversation and start music + ConversationHandle convHandle = mServer.createConversation(true /* broadcast only*/); + mServer.createMediaResourceParticipant(convHandle, mMusicFilename); // Play Music + mConversations[convHandle]; + } + else + { + mMusicFilenameChanged = true; + } +} + +void +MOHManager::shutdown(bool shuttingDownServer) +{ + Lock lock(mMutex); + // Destroy all conversations + ConversationMap::iterator it = mConversations.begin(); + for(; it != mConversations.end(); it++) + { + // Clean up participant memory + ParticipantMap::iterator partIt = it->second.begin(); + for(;partIt!= it->second.end(); partIt++) + { + delete partIt->second; + } + it->second.clear(); + + mServer.destroyConversation(it->first); + } + mConversations.clear(); + + // If shutting down server, then we shouldn't remove the conversation profiles here + // shutting down the ConversationManager will take care of this. We need to be sure + // we don't remove all conversation profiles when we are still processing SipMessages, + // since recon requires at least one to be present for inbound processing. + if(mConversationProfileHandle && !shuttingDownServer) + { + mServer.mMyUserAgent->destroyConversationProfile(mConversationProfileHandle); + mConversationProfileHandle = 0; + } +} + +bool +MOHManager::isMyProfile(recon::ConversationProfile& profile) +{ + Lock lock(mMutex); + return profile.getHandle() == mConversationProfileHandle; +} + +void +MOHManager::addParticipant(ParticipantHandle participantHandle, const Uri& heldUri, const Uri& holdingUri) +{ + Lock lock(mMutex); + ConversationHandle conversationToUse = 0; + // Check if we have an existing conversation with room to add this party + ConversationMap::iterator it = mConversations.begin(); + for(; it != mConversations.end(); it++) + { + if(it->second.size() < DEFAULT_BRIDGE_MAX_IN_OUTPUTS-3) + { + // Found an existing conversation with room - add the participant here + conversationToUse = it->first; + break; + } + } + + // No conversation found that we can use - create a new one + if(!conversationToUse) + { + conversationToUse = mServer.createConversation(true /* broadcast only*/); + InfoLog(<< "MOHManager::addParticipant created new conversation for music on hold, id=" << conversationToUse); + + // Play Music + mServer.createMediaResourceParticipant(conversationToUse, mMusicFilename); + } + + assert(conversationToUse); + + mServer.addParticipant(conversationToUse, participantHandle); + mServer.modifyParticipantContribution(conversationToUse, participantHandle, 100, 0 /* Mute participant */); + mServer.answerParticipant(participantHandle); + mConversations[conversationToUse].insert(std::make_pair(participantHandle, new ParticipantMOHInfo(participantHandle, heldUri, holdingUri))); +} + +bool +MOHManager::removeParticipant(ParticipantHandle participantHandle) +{ + Lock lock(mMutex); + // Find Conversation that participant is in + ConversationMap::iterator it = mConversations.begin(); + for(; it != mConversations.end(); it++) + { + ParticipantMap::iterator partIt = it->second.find(participantHandle); + if(partIt != it->second.end()) + { + InfoLog(<< "MOHManager::removeParticipant found in conversation id=" << it->first << ", size=" << it->second.size()); + + // Found! Remove from conversation + delete partIt->second; + it->second.erase(partIt); + + // Check if conversation is now empty, and it's not the last conversation + if(it->second.size() == 0) + { + if(mConversations.size() > 1) + { + // Destroy conversation (and containing media participant) + mServer.destroyConversation(it->first); + + // Remove Conversation from Map + mConversations.erase(it); + + InfoLog(<< "MOHManager::removeParticipant last participant in conversation, destroying conversation, num conversations now=" << mConversations.size()); + } + else if(mConversations.size() == 1 && mMusicFilenameChanged) // If the initial conversation is empty, and the music filename setting changed, then restart it + { + mServer.destroyConversation(mConversations.begin()->first); + mConversations.clear(); + + // re-create an initial conversation and start music + ConversationHandle convHandle = mServer.createConversation(true /* broadcast only*/); + mServer.createMediaResourceParticipant(convHandle, mMusicFilename); // Play Music + mConversations[convHandle]; + mMusicFilenameChanged = false; + } + } + return true; + } + } + return false; +} + +void +MOHManager::getActiveCallsInfo(CallInfoList& callInfos) +{ + Lock lock(mMutex); + // Find Conversation that participant is in + ConversationMap::iterator it = mConversations.begin(); + for(; it != mConversations.end(); it++) + { + ParticipantMap::iterator partIt = it->second.begin(); + for(; partIt != it->second.end(); partIt++) + { + callInfos.push_back(ActiveCallInfo(partIt->second->mHeldUri, partIt->second->mHoldingUri, "MOH", partIt->first, it->first)); + } + } +} + +} + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/MOHManager.hxx b/src/libs/resiprocate/resip/recon/MOHParkServer/MOHManager.hxx new file mode 100644 index 00000000..c6d3b4cb --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/MOHManager.hxx @@ -0,0 +1,90 @@ +#if !defined(MOHManager_hxx) +#define MOHManager_hxx + +#include <map> +#include <set> +#include "ActiveCallInfo.hxx" +#include "../UserAgent.hxx" +#include "../HandleTypes.hxx" + +namespace mohparkserver +{ +class Server; + +class ParticipantMOHInfo +{ +public: + ParticipantMOHInfo(recon::ParticipantHandle participantHandle, const resip::Uri& heldUri, const resip::Uri& holdingUri) : + mParticipantHandle(participantHandle), mHeldUri(heldUri), mHoldingUri(holdingUri) {} + recon::ParticipantHandle mParticipantHandle; + resip::Uri mHeldUri; + resip::Uri mHoldingUri; +}; + +class MOHManager +{ +public: + MOHManager(Server& server); + virtual ~MOHManager(); + + void startup(); + void initializeConversationProfile(const resip::NameAddr& uri, const resip::Data& password, unsigned long registrationTime, const resip::NameAddr& outboundProxy); + void initializeSettings(const resip::Uri& musicFilename); + + void shutdown(bool shuttingDownServer); + + bool isMyProfile(recon::ConversationProfile& profile); + void addParticipant(recon::ParticipantHandle participantHandle, const resip::Uri& heldUri, const resip::Uri& holdingUri); + bool removeParticipant(recon::ParticipantHandle participantHandle); + void getActiveCallsInfo(CallInfoList& callInfos); + +private: + resip::Mutex mMutex; + Server& mServer; + volatile recon::ConversationProfileHandle mConversationProfileHandle; + resip::Uri mMusicFilename; + volatile bool mMusicFilenameChanged; + + typedef std::map<recon::ParticipantHandle, ParticipantMOHInfo*> ParticipantMap; + typedef std::map<recon::ConversationHandle, ParticipantMap> ConversationMap; + ConversationMap mConversations; +}; + +} + +#endif + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/MOHParkServer.config b/src/libs/resiprocate/resip/recon/MOHParkServer/MOHParkServer.config new file mode 100644 index 00000000..fdb25818 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/MOHParkServer.config @@ -0,0 +1,145 @@ +######################################################## +# MOH / Park Server configuration file +######################################################## + + +######################################################## +# MOH settings +######################################################## + +# URI that SIP user agents use to communicate with the MOH server. If a display name +# is desired on calls placed by the MOH server then it can be provided here using the +# following format: "{displayName}"<sip:{user}@{domain}> +# Example: "Music-On-Hold"<sip:moh@server.com> +MOHUri = "Music-On-Hold"<sip:moh@blitzzgod.com> + +# Registration Time in seconds - set to 0 to disable registration +MOHRegistrationTime = 3600 + +# The password that is used if registration is enabled (ie. MOHRegistrationTime is +# greater than 0), and the registrar requires a password for the user specified in +# the MOHUri. +MOHPassword = 123 + +# The audio filename to play for music-on-hold. Audio files may be AU, WAV or RAW +# formats. Audiofiles should be 16bit mono, 8khz, PCM to avoid runtime conversion. +MOHFilename = music.wav + + +######################################################## +# Park settings +######################################################## + +# URI that SIP user agents use to communicate with the Park server. If a display name +# is desired on calls placed by the Park server then it can be provided here using the +# following format: "{displayName}"<sip:{user}@{domain}> +# Example: "Parked"<sip:park@server.com> +ParkUri = "Parked"<sip:park@blitzzgod.com> + +# Registration Time in seconds - set to 0 to disable registration +ParkRegistrationTime = 3600 + +# The password that is used if registration is enabled (ie. ParkRegistrationTime is +# greater than 0), and the registrar requires a password for the user specified in +# the ParkUri. +ParkPassword = 123 + +# The audio filename to play for music-on-hold. Audio files may be AU, WAV or RAW +# formats. Audiofiles should be 16bit mono, 8khz, PCM to avoid runtime conversion. +ParkMOHFilename = music.wav + +# A number specifying the starting number of the park orbit range. Orbit numbers +# are treated as integers, thus this number must be 9 digits or less. +ParkOrbitRangeStart = 6000 + +# The number of park orbits to allocate and potentially register. For example, if +# ParkOrbitRangeStart is specified as 6000 and ParkNumOrbits is 10, then the number +# range 6000-6009 will be used for park orbits. +ParkNumOrbits = 10 + +# The registration period, in seconds, to use when registering the orbit retrieval +# identities. Specify this setting as 0 to disable registration of the park orbit +# URIs. +# Note: Park orbit URI’s are formed by taking the park orbit number as the SIP user +# and the domain from the ParkUri setting. For example, if the ParkUri is specified +# as sip:park@server.com and the ParkOrbitRangeStart is 6000, then the first park orbit +# Uri will be: sip:6000@server.com +ParkOrbitRegistrationTime = 3600 + +# The password that is used if orbit registration is enabled (ie. +# ParkOrbitRegistrationTime is greater than 0), and the registrar requires a password +# for the park orbit user. +ParkOrbitPassword = 123 + +# The number of seconds the park server will allow a call to stay parked. If a call is +# not retrieved within this time, it will ring back the party that originally parked the +# call (set to 0 to disable). +MaxParkTime = 600 + + +######################################################## +# SIP settings +######################################################## + +# Local IP Address to bind SIP transports to. If left blank +# MOHParkServer will bind to all adapters. +#IPAddress = 192.168.1.106 +#IPAddress = 2001:5c0:1000:a::6d +IPAddress = + +# Comma separated list of DNS servers, overrides default OS detected list (leave blank for default) +DNSServers = 192.168.1.105 + +# Local port to listen on for SIP messages over UDP +UDPPort = 5072 + +# Local port to listen on for SIP messages over TCP +TCPPort = 5072 + +# Local port to listen on for SIP messages over TLS +TLSPort = 5073 + +# TLS domain name for this server (note: domain cert for this domain must be present) +TLSDomainName = + +# Enable/Disable TCP/UDP CRLFCRLF keepalive packets for SIP endpoints +# 1|true|on|enable to enable, 0|false|off|disable to disable +KeepAlives = enable + +# URI of a proxy server to use a SIP outbound proxy. This setting should not be required if +# proper DNS based SIP routing is operational. +OutboundProxy = + + +######################################################## +# Media settings +######################################################## + +# Specifies the start of the range of UDP port numbers to be used to send RTP traffic. +MediaPortRangeStart = 50000 + +# Specifies the size of the range of UDP port numbers to be used to send RTP traffic. +# Calls will be rejected when the media ports are depleted. A SIP call requires 2 media +# ports for each call (RTP and RTCP). For example: a setting of 800 will limit the server +# to a maximum of 400 calls. +MediaPortRangeSize = 800 + +# Log Filename - leave blank to disable sipXtapi logging +sipXLogFilename = sipXtapi.log + + +######################################################## +# General settings +######################################################## + +# Port number for HTTP Server to run on that shows all active calls +HttpPort = 5082 + +# Logging level: NONE|ERR|WARNING|INFO|DEBUG|STACK +LogLevel = WARNING + +# Log Filename +LogFilename = MOHParkServer.log + +# Log file Max Bytes +LogFileMaxBytes = 5000000 diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/MOHParkServer.cxx b/src/libs/resiprocate/resip/recon/MOHParkServer/MOHParkServer.cxx new file mode 100644 index 00000000..abe1ea47 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/MOHParkServer.cxx @@ -0,0 +1,126 @@ +#include <signal.h> + +#include "AppSubsystem.hxx" +#include "Server.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/BaseException.hxx> +#include <resip/stack/NameAddr.hxx> +#include <rutil/WinLeakCheck.hxx> + +using namespace mohparkserver; +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM AppSubsystem::MOHPARKSERVER + +void sleepSeconds(unsigned int seconds) +{ +#ifdef WIN32 + Sleep(seconds*1000); +#else + sleep(seconds); +#endif +} + +static bool finished = false; + +static void +signalHandler(int signo) +{ + std::cerr << "Shutting down..." << endl; + finished = true; +} + +int +main (int argc, char** argv) +{ +#ifndef _WIN32 + if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR) + { + cerr << "Couldn't install signal handler for SIGPIPE" << endl; + exit(-1); + } +#else +#if defined(_DEBUG) && defined(LEAK_CHECK) + resip::FindMemoryLeaks fml; +#endif +#endif + + if ( signal( SIGINT, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGINT" << endl; + exit( -1 ); + } + + if ( signal( SIGTERM, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGTERM" << endl; + exit( -1 ); + } + + initNetwork(); + + ////////////////////////////////////////////////////////////////////////////// + // Create Server + ////////////////////////////////////////////////////////////////////////////// + { + ConfigParser config(argc, argv); + Server server(config); + + ////////////////////////////////////////////////////////////////////////////// + // Startup and run... + ////////////////////////////////////////////////////////////////////////////// + + server.startup(); + + while(true) + { + server.process(500); + if(finished) break; + } + + server.shutdown(); + } + + InfoLog(<< "MOHParkServer is shutdown."); + sleepSeconds(2); +} + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/MOHParkServer_9_0.vcproj b/src/libs/resiprocate/resip/recon/MOHParkServer/MOHParkServer_9_0.vcproj new file mode 100644 index 00000000..4fcff7cd --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/MOHParkServer_9_0.vcproj @@ -0,0 +1,483 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="MOHParkServer" + ProjectGUID="{74D896AB-C35B-4BB3-9418-D18D509C8D22}" + RootNamespace="MOHParkServer" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-MOHParkServer.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)/MOHParkServer.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\pcre\Debug\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Debug\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Debug\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Debug\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Debug\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Debug\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/MOHParkServer.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/MOHParkServer.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-MOHParkServer.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)\MOHParkServer.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\pcre\Release\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Release\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Release\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Release\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Release\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Release\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/MOHParkServer.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/MOHParkServer.pdb" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-MOHParkServer.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)/MOHParkServer.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\pcre\Debug\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Debug\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Debug\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Debug\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Debug\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Debug\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/MOHParkServer.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/MOHParkServer.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-MOHParkServer.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)\MOHParkServer.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\pcre\Release\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Release\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Release\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Release\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Release\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Release\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/MOHParkServer.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/MOHParkServer.pdb" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath=".\AppSubsystem.cxx" + > + </File> + <File + RelativePath=".\ConfigParser.cxx" + > + </File> + <File + RelativePath=".\HttpBase.cxx" + > + </File> + <File + RelativePath=".\HttpConnection.cxx" + > + </File> + <File + RelativePath=".\MOHManager.cxx" + > + </File> + <File + RelativePath=".\MOHParkServer.cxx" + > + </File> + <File + RelativePath=".\ParkManager.cxx" + > + </File> + <File + RelativePath=".\ParkOrbit.cxx" + > + </File> + <File + RelativePath=".\Server.cxx" + > + </File> + <File + RelativePath=".\WebAdmin.cxx" + > + </File> + <File + RelativePath=".\WebAdminThread.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + <File + RelativePath=".\ActiveCallInfo.hxx" + > + </File> + <File + RelativePath=".\AppSubsystem.hxx" + > + </File> + <File + RelativePath=".\ConfigParser.hxx" + > + </File> + <File + RelativePath=".\HttpBase.hxx" + > + </File> + <File + RelativePath=".\HttpConnection.hxx" + > + </File> + <File + RelativePath=".\MOHManager.hxx" + > + </File> + <File + RelativePath=".\ParkManager.hxx" + > + </File> + <File + RelativePath=".\ParkOrbit.hxx" + > + </File> + <File + RelativePath=".\Server.hxx" + > + </File> + <File + RelativePath=".\WebAdmin.hxx" + > + </File> + <File + RelativePath=".\WebAdminThread.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + > + </Filter> + <File + RelativePath=".\MOHParkServer.config" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/Makefile.am b/src/libs/resiprocate/resip/recon/MOHParkServer/Makefile.am new file mode 100644 index 00000000..725019f0 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/Makefile.am @@ -0,0 +1,46 @@ + +# WARNING +# +# This is not a final version of Makefile.am +# +# it has just been created to ensure the files are part of the +# distribution tarball so that they build on Windows +# + +EXTRA_DIST = ca.pem +EXTRA_DIST += doc +EXTRA_DIST += *.vcproj +EXTRA_DIST += MOHParkServer.config +EXTRA_DIST += music.wav + +LDADD = ../librecon.la +#LDADD += ../../........whatever + +sbin_PROGRAMS = MOHParkServer + +MOHParkServer_SOURCES = \ + AppSubsystem.cxx \ + ConfigParser.cxx \ + HttpBase.cxx \ + HttpConnection.cxx \ + MOHManager.cxx \ + MOHParkServer.cxx \ + ParkManager.cxx \ + ParkOrbit.cxx \ + Server.cxx \ + WebAdmin.cxx \ + WebAdminThread.cxx + +noinst_HEADERS = \ + ActiveCallInfo.hxx \ + AppSubsystem.hxx \ + ConfigParser.hxx \ + HttpBase.hxx \ + HttpConnection.hxx \ + MOHManager.hxx \ + ParkManager.hxx \ + ParkOrbit.hxx \ + Server.hxx \ + WebAdmin.hxx \ + WebAdminThread.hxx + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/ParkManager.cxx b/src/libs/resiprocate/resip/recon/MOHParkServer/ParkManager.cxx new file mode 100644 index 00000000..e500a3b1 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/ParkManager.cxx @@ -0,0 +1,467 @@ +#include "AppSubsystem.hxx" +#include "ParkManager.hxx" +#include "ParkOrbit.hxx" +#include "Server.hxx" +#include "../UserAgent.hxx" + +#include <resip/stack/ExtensionParameter.hxx> +#include <resip/stack/SipMessage.hxx> +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/WinLeakCheck.hxx> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM AppSubsystem::MOHPARKSERVER + +static const resip::ExtensionParameter p_orbit("orbit"); +static const resip::ExtensionParameter p_automaton("automaton"); +static const resip::ExtensionParameter p_byeless("+sip.byeless"); +static const resip::ExtensionParameter p_rendering("+sip.rendering"); + +namespace mohparkserver +{ + +ParkManager::ParkManager(Server& server) : + mServer(server), + mConversationProfileHandle(0), + mOrbitRangeStart(0), + mNumOrbits(0), + mMaxParkTime(0) +{ +} + +ParkManager::~ParkManager() +{ +} + +void +ParkManager::startup() +{ + // Initialize park settings + initializeParkSettings(mServer.mConfig.mMaxParkTime, mServer.mConfig.mParkMOHFilenameUrl); + + // Setup Park ConversationProfile + initializeConversationProfile(mServer.mConfig.mParkUri, mServer.mConfig.mParkPassword, mServer.mConfig.mParkRegistrationTime, mServer.mConfig.mOutboundProxy); + + // Create Orbit Profiles + initializeOrbitConversationProfiles(mServer.mConfig.mParkOrbitRangeStart, mServer.mConfig.mParkNumOrbits, mServer.mConfig.mParkUri, mServer.mConfig.mParkOrbitPassword, mServer.mConfig.mParkOrbitRegistrationTime, mServer.mConfig.mOutboundProxy); +} + +void +ParkManager::initializeConversationProfile(const NameAddr& uri, const Data& password, unsigned long registrationTime, const resip::NameAddr& outboundProxy) +{ + Lock lock(mMutex); + + if(mConversationProfileHandle) + { + mServer.mMyUserAgent->destroyConversationProfile(mConversationProfileHandle); + mConversationProfileHandle = 0; + } + + SharedPtr<ConversationProfile> parkConversationProfile = SharedPtr<ConversationProfile>(new ConversationProfile(mServer.mUserAgentMasterProfile)); + parkConversationProfile->setDefaultRegistrationTime(registrationTime); + parkConversationProfile->setDefaultRegistrationRetryTime(120); // 2 mins + parkConversationProfile->setDefaultFrom(uri); + parkConversationProfile->setDigestCredential(uri.uri().host(), uri.uri().user(), password); + if(!outboundProxy.uri().host().empty()) + { + parkConversationProfile->setOutboundProxy(outboundProxy.uri()); + } + parkConversationProfile->challengeOODReferRequests() = false; + parkConversationProfile->setExtraHeadersInReferNotifySipFragEnabled(true); // Enable dialog identifying headers in SipFrag bodies of Refer Notifies + NameAddr capabilities; + capabilities.param(p_automaton); + capabilities.param(p_byeless); + capabilities.param(p_rendering) = "\"no\""; + parkConversationProfile->setUserAgentCapabilities(capabilities); // Same as above + parkConversationProfile->natTraversalMode() = ConversationProfile::NoNatTraversal; + parkConversationProfile->secureMediaMode() = ConversationProfile::NoSecureMedia; + mServer.buildSessionCapabilities(parkConversationProfile->sessionCaps()); + mConversationProfileHandle = mServer.mMyUserAgent->addConversationProfile(parkConversationProfile); + mParkUri = uri; +} + +void +ParkManager::initializeOrbitConversationProfiles(unsigned long orbitStart, + unsigned long numOrbits, + const NameAddr& uri, + const Data& password, + unsigned long registrationTime, + const resip::NameAddr& outboundProxy) +{ + Lock lock(mMutex); + + // Remove current Profiles (if set) + OrbitProfileMap::iterator itOrbit = mOrbitProfiles.begin(); + for(;itOrbit!=mOrbitProfiles.end();itOrbit++) + { + mServer.mMyUserAgent->destroyConversationProfile(itOrbit->second); + } + mOrbitProfiles.clear(); + + // Store orbit range values + mOrbitRangeStart = orbitStart; + mNumOrbits = numOrbits; + + // Clear free list and rebuild it + mFreeOrbitList.clear(); + + for(unsigned long orbit = mOrbitRangeStart; orbit < mOrbitRangeStart + mNumOrbits; orbit++) + { + SharedPtr<ConversationProfile> orbitConversationProfile = SharedPtr<ConversationProfile>(new ConversationProfile(mServer.mUserAgentMasterProfile)); + Data orbitData(orbit); + orbitConversationProfile->setDefaultRegistrationTime(registrationTime); + orbitConversationProfile->setDefaultRegistrationRetryTime(120); // 2 mins + orbitConversationProfile->setDefaultFrom(uri); + orbitConversationProfile->getDefaultFrom().uri().user() = orbitData; + orbitConversationProfile->setDigestCredential(uri.uri().host(), orbitData, password); + if(!outboundProxy.uri().host().empty()) + { + orbitConversationProfile->setOutboundProxy(outboundProxy.uri()); + } + orbitConversationProfile->challengeOODReferRequests() = false; + orbitConversationProfile->setExtraHeadersInReferNotifySipFragEnabled(true); // Enable dialog identifying headers in SipFrag bodies of Refer Notifies + NameAddr capabilities; + capabilities.param(p_automaton); + capabilities.param(p_byeless); + capabilities.param(p_rendering) = "\"no\""; + orbitConversationProfile->setUserAgentCapabilities(capabilities); // Same as above + orbitConversationProfile->natTraversalMode() = ConversationProfile::NoNatTraversal; + orbitConversationProfile->secureMediaMode() = ConversationProfile::NoSecureMedia; + mServer.buildSessionCapabilities(orbitConversationProfile->sessionCaps()); + mOrbitProfiles[orbit] = mServer.mMyUserAgent->addConversationProfile(orbitConversationProfile); + + // If orbit is free - add to free list + if(mOrbits.find(orbit) == mOrbits.end()) + { + mFreeOrbitList.push_back(orbit); + } + } +} + +void +ParkManager::initializeParkSettings(unsigned long maxParkTime, const resip::Uri& musicFilename) +{ + Lock lock(mMutex); + mMaxParkTime = maxParkTime; + mMusicFilename = musicFilename; +} + +void +ParkManager::shutdown(bool shuttingDownServer) +{ + Lock lock(mMutex); + OrbitMap::iterator it = mOrbits.begin(); + for(;it!=mOrbits.end();it++) + { + // Delete all Orbit objects + delete it->second; + } + mOrbits.clear(); + mOrbitsByParticipant.clear(); + + // If shutting down server, then we shouldn't remove the conversation profiles here + // shutting down the ConversationManager will take care of this. We need to be sure + // we don't remove all conversation profiles when we are still processing SipMessages, + // since recon requires at least one to be present for inbound processing. + if(!shuttingDownServer) + { + // Destroy main Park profile + if(mConversationProfileHandle) + { + mServer.mMyUserAgent->destroyConversationProfile(mConversationProfileHandle); + mConversationProfileHandle = 0; + } + + // Destroy Orbit Profiles + OrbitProfileMap::iterator itOrbit = mOrbitProfiles.begin(); + for(;itOrbit!=mOrbitProfiles.end();itOrbit++) + { + mServer.mMyUserAgent->destroyConversationProfile(itOrbit->second); + } + mOrbitProfiles.clear(); + } +} + +bool +ParkManager::isMyProfile(recon::ConversationProfile& profile) +{ + Lock lock(mMutex); + if(profile.getHandle() == mConversationProfileHandle) + { + return true; + } + else + { + // check orbit profiles + OrbitProfileMap::iterator it = mOrbitProfiles.begin(); + for(;it!=mOrbitProfiles.end();it++) + { + if(profile.getHandle() == it->second) + { + return true; + } + } + } + return false; +} + +ParkOrbit* +ParkManager::getOrbit(unsigned long orbit) +{ + assert((orbit >= mOrbitRangeStart) && + (orbit < (mOrbitRangeStart + mNumOrbits))); + + // Check if Orbit is created or not yet + OrbitMap::iterator it = mOrbits.find(orbit); + ParkOrbit* parkOrbit = 0; + if(it == mOrbits.end()) + { + // Create Orbit + parkOrbit = new ParkOrbit(mServer, orbit, mMaxParkTime, mMusicFilename); + mOrbits[orbit] = parkOrbit; + + // Remove from free list + std::deque<unsigned long>::iterator itFree = mFreeOrbitList.begin(); + for(;itFree!=mFreeOrbitList.end();itFree++) + { + if(orbit == *itFree) + { + mFreeOrbitList.erase(itFree); + break; + } + } + } + else + { + // Use existing + parkOrbit = it->second; + } + return parkOrbit; +} + +ParkOrbit* +ParkManager::getOrbitByParticipant(recon::ParticipantHandle participantHandle) +{ + OrbitsByParticipantMap::iterator it = mOrbitsByParticipant.find(participantHandle); + if(it != mOrbitsByParticipant.end()) + { + return it->second; + } + return 0; +} + +bool +ParkManager::addParticipantToOrbit(ParkOrbit* orbit, recon::ParticipantHandle participantHandle, const resip::Uri& parkedUri, const resip::Uri& parkerUri) +{ + if(orbit->addParticipant(participantHandle, parkedUri, parkerUri)) + { + mOrbitsByParticipant[participantHandle] = orbit; // add participant to orbit index + return true; + } + return false; +} + +void +ParkManager::parkParticipant(ParticipantHandle participantHandle, const SipMessage& msg) +{ + Lock lock(mMutex); + + unsigned long orbit = 0; + assert(msg.method() == REFER); + + // Check if Orbit parameter has been specified on the To header + if(msg.header(h_To).uri().exists(p_orbit)) + { + orbit = msg.header(h_To).uri().param(p_orbit).convertUnsignedLong(); + } + + if((orbit >= mOrbitRangeStart) && + (orbit < (mOrbitRangeStart + mNumOrbits))) + { + // Park call at specified orbit + ParkOrbit* parkOrbit = getOrbit(orbit); + assert(parkOrbit); + addParticipantToOrbit(parkOrbit, participantHandle, msg.header(h_ReferTo).uri().getAorAsUri(), msg.header(h_From).uri()); + } + else + { + // If no orbit was specified, or specified number is bad - select a free orbit, and redirect request to use newly allocated orbit + if(mFreeOrbitList.size() > 0) + { + unsigned long freeorbit = mFreeOrbitList.front(); + // Move free item to end of list, to reduce chance it will be double allocated + mFreeOrbitList.pop_front(); + mFreeOrbitList.push_back(freeorbit); + InfoLog(<< "ParkManager::parkParticipant no valid orbit specified (orbit=" << orbit << ") redirecting to free orbit=" << freeorbit); + NameAddr destination(mParkUri); + destination.uri().param(p_orbit) = Data(freeorbit); + mServer.redirectParticipant(participantHandle, destination); + } + else + { + // No free orbits + WarningLog(<< "ParkManager::parkParticipant no free orbits available, rejecing with 486 busy."); + mServer.rejectParticipant(participantHandle, 486 /* Busy */); + } + } +} + +void +ParkManager::incomingParticipant(ParticipantHandle participantHandle, const SipMessage& msg) +{ + Lock lock(mMutex); + + // Get orbit number, either from To Uri parameter, or To user + unsigned long orbit = 0; + if(msg.header(h_To).uri().exists(p_orbit)) + { + orbit = msg.header(h_To).uri().param(p_orbit).convertUnsignedLong(); + } + else + { + orbit = msg.header(h_To).uri().user().convertUnsignedLong(); + } + if((orbit >= mOrbitRangeStart) && + (orbit < (mOrbitRangeStart + mNumOrbits))) + { + // Check if this is a direct call, or a transferred call. We will allow transferred calls to be parked, as an alternative parking method + if(msg.exists(h_ReferredBy)) + { + // If a Referred-By header is present then this was a transferred call - park it + // Park call at specified orbit + ParkOrbit* parkOrbit = getOrbit(orbit); + assert(parkOrbit); + addParticipantToOrbit(parkOrbit, participantHandle, msg.header(h_From).uri(), msg.header(h_ReferredBy).uri()); + } + else // Direct call - retrieval attempt + { + // Orbit is valid - see if we have a call parked there + OrbitMap::iterator it = mOrbits.find(orbit); + ParticipantHandle participantToRetrieve = 0; + if(it!=mOrbits.end() && (participantToRetrieve = it->second->getNextQueuedParticipant()) != 0) + { + // Answer incoming call and then immediately redirect to parked call + mServer.addParticipant(it->second->getConversationHandle(), participantHandle); + mServer.modifyParticipantContribution(it->second->getConversationHandle(), participantHandle, 0, 0 /* Mute participant */); + mServer.answerParticipant(participantHandle); + mServer.redirectToParticipant(participantHandle, participantToRetrieve); + + InfoLog(<< "ParkManager::incomingParticipant retrieving participant " << participantToRetrieve << " from orbit " << orbit); + } + else + { + WarningLog(<< "ParkManager::incomingParticipant orbit " << orbit << " has no call to retrieve, rejecting with 404."); + mServer.rejectParticipant(participantHandle, 404 /* Not Found */); + } + } + } + else + { + WarningLog(<< "ParkManager::incomingParticipant valid orbit not found in To header (" << msg.header(h_To).uri() << "), rejecting with 404."); + mServer.rejectParticipant(participantHandle, 404 /* Not Found */); + } +} + +bool +ParkManager::removeParticipant(ParticipantHandle participantHandle) +{ + Lock lock(mMutex); + ParkOrbit* orbit = getOrbitByParticipant(participantHandle); + if(orbit) + { + mOrbitsByParticipant.erase(participantHandle); // Remove participant from orbit index + if(orbit->removeParticipant(participantHandle)) + { + if(orbit->getNumParticipants() == 0) + { + // Last participant just left orbit - destroy it + unsigned long orbitNum = orbit->getOrbit(); + if((orbitNum >= mOrbitRangeStart) && + (orbitNum < (mOrbitRangeStart + mNumOrbits))) + { + // Only add back to free list, if in currently configured range + mFreeOrbitList.push_back(orbitNum); + } + delete orbit; + mOrbits.erase(orbitNum); + } + return true; + } + } + return false; +} + +void +ParkManager::getActiveCallsInfo(CallInfoList& callInfos) +{ + Lock lock(mMutex); + + OrbitMap::iterator it = mOrbits.begin(); + for(; it != mOrbits.end(); it++) + { + ParkOrbit::ParticipantQueue::iterator it2 = it->second->mParticipants.begin(); + for(; it2 != it->second->mParticipants.end(); it2++) + { + callInfos.push_back(ActiveCallInfo((*it2)->mParkedUri, + (*it2)->mParkerUri, + Data("Parked at " + Data(it->first)), + (*it2)->mParticipantHandle, + it->second->mConversationHandle)); + } + } +} + +void +ParkManager::onMaxParkTimeout(recon::ParticipantHandle participantHandle) +{ + Lock lock(mMutex); + + // Try to see if participant is still around + ParkOrbit* orbit = getOrbitByParticipant(participantHandle); + if(orbit) + { + orbit->onMaxParkTimeout(participantHandle); + } +} + + +} + +/* ==================================================================== + + Copyright (c) 2011, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/ParkManager.hxx b/src/libs/resiprocate/resip/recon/MOHParkServer/ParkManager.hxx new file mode 100644 index 00000000..a4b2f875 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/ParkManager.hxx @@ -0,0 +1,104 @@ +#if !defined(ParkManager_hxx) +#define ParkManager_hxx + +#include <map> +#include <deque> +#include "ActiveCallInfo.hxx" +#include "../UserAgent.hxx" +#include "../HandleTypes.hxx" + +namespace resip +{ +class SipMessage; +} + +namespace mohparkserver +{ +class Server; +class ParkOrbit; + +class ParkManager +{ +public: + ParkManager(Server& server); + virtual ~ParkManager(); + + void startup(); + void initializeConversationProfile(const resip::NameAddr& uri, const resip::Data& password, unsigned long registrationTime, const resip::NameAddr& outboundProxy); + void initializeOrbitConversationProfiles(unsigned long orbitStart, unsigned long numOrbits, const resip::NameAddr& uri, const resip::Data& password, unsigned long registrationTime, const resip::NameAddr& outboundProxy); + void initializeParkSettings(unsigned long maxParkTime, const resip::Uri& musicFilename); + void shutdown(bool shuttingDownServer); + + bool isMyProfile(recon::ConversationProfile& profile); + void parkParticipant(recon::ParticipantHandle participantHandle, const resip::SipMessage& msg); + void incomingParticipant(recon::ParticipantHandle participantHandle, const resip::SipMessage& msg); + bool removeParticipant(recon::ParticipantHandle participantHandle); + void getActiveCallsInfo(CallInfoList& callInfos); + + void onMaxParkTimeout(recon::ParticipantHandle participantHandle); + +private: + resip::Mutex mMutex; + Server& mServer; + volatile recon::ConversationProfileHandle mConversationProfileHandle; + resip::NameAddr mParkUri; + unsigned long mOrbitRangeStart; + unsigned long mNumOrbits; + unsigned long mMaxParkTime; + resip::Uri mMusicFilename; + std::deque<unsigned long> mFreeOrbitList; + + // Orbit by orbit number + ParkOrbit* getOrbit(unsigned long orbit); + typedef std::map<unsigned long, ParkOrbit*> OrbitMap; + OrbitMap mOrbits; + + // index on orbits for fast access + ParkOrbit* getOrbitByParticipant(recon::ParticipantHandle participantHandle); + typedef std::map<recon::ParticipantHandle, ParkOrbit*> OrbitsByParticipantMap; + OrbitsByParticipantMap mOrbitsByParticipant; + + bool addParticipantToOrbit(ParkOrbit* orbit, recon::ParticipantHandle participantHandle, const resip::Uri& parkedUri, const resip::Uri& parkerUri); + + typedef std::map<unsigned long, recon::ConversationProfileHandle> OrbitProfileMap; + OrbitProfileMap mOrbitProfiles; +}; + +} + +#endif + +/* ==================================================================== + + Copyright (c) 2011, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/ParkOrbit.cxx b/src/libs/resiprocate/resip/recon/MOHParkServer/ParkOrbit.cxx new file mode 100644 index 00000000..f17a9ab3 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/ParkOrbit.cxx @@ -0,0 +1,156 @@ +#include "AppSubsystem.hxx" +#include "ParkOrbit.hxx" +#include "Server.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/WinLeakCheck.hxx> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM AppSubsystem::MOHPARKSERVER +#define ALLOCATIONTIME 32 // The number of seconds to condsider a participant allocated, when a retreival is attempted + // If the call fails to retrieve, it will still be available to be retrieved by + // another attempt after this time expires. +namespace mohparkserver +{ + +ParkOrbit::ParkOrbit(Server& server, unsigned long orbit, unsigned long maxParkTime, const resip::Uri& musicFilename) : + mServer(server), + mOrbit(orbit), + mMaxParkTime(maxParkTime) +{ + // Create an initial conversation and start music + mConversationHandle = mServer.createConversation(true /* broadcast only*/); + + // Play Music + mServer.createMediaResourceParticipant(mConversationHandle, musicFilename); + + InfoLog(<< "ParkOrbit::ParkOrbit created orbit " << mOrbit); +} + +ParkOrbit::~ParkOrbit() +{ + mServer.destroyConversation(mConversationHandle); + InfoLog(<< "ParkOrbit::~ParkOrbit destroyed orbit " << mOrbit); +} + +bool +ParkOrbit::addParticipant(recon::ParticipantHandle participantHandle, const Uri& parkedUri, const Uri& parkerUri) +{ + if(mParticipants.size() < DEFAULT_BRIDGE_MAX_IN_OUTPUTS-3) + { + mServer.addParticipant(mConversationHandle, participantHandle); + mServer.modifyParticipantContribution(mConversationHandle, participantHandle, 100, 0 /* Mute participant */); + mServer.answerParticipant(participantHandle); + + if(mMaxParkTime != 0) + { + mServer.getMyUserAgent()->startApplicationTimer(MAXPARKTIMEOUT, mMaxParkTime*1000, participantHandle); + } + + mParticipants.push_back(new ParticipantOrbitInfo(participantHandle, parkedUri, parkerUri)); + InfoLog(<< "ParkOrbit::addParticipant added participant=" << participantHandle << " to orbit " << mOrbit << " (size=" << mParticipants.size() << "), parkedUri=" << parkedUri << ", parkerUri=" << parkerUri); + return true; + } + else + { + mServer.rejectParticipant(participantHandle, 486); + WarningLog(<< "ParkOrbit::addParticipant cannot add participant=" << participantHandle << " to full orbit " << mOrbit << " (size=" << mParticipants.size() << ")"); + return false; + } +} + +bool +ParkOrbit::removeParticipant(recon::ParticipantHandle participantHandle) +{ + ParticipantQueue::iterator it = mParticipants.begin(); + for(;it!=mParticipants.end();it++) + { + if((*it)->mParticipantHandle == participantHandle) + { + delete *it; + mParticipants.erase(it); + InfoLog(<< "ParkOrbit::removeParticipant removed participant=" << participantHandle << " from orbit " << mOrbit << " (size=" << mParticipants.size() << ")"); + return true; + } + } + return false; +} + +ParticipantHandle +ParkOrbit::getNextQueuedParticipant() +{ + ParticipantHandle participantHandle = 0; + if(!mParticipants.empty()) + { + UInt64 now = resip::Timer::getTimeSecs(); + if(now - mParticipants.front()->mAllocationTime > ALLOCATIONTIME) + { + participantHandle = mParticipants.front()->mParticipantHandle; + mParticipants.front()->mAllocationTime = now; + // Move to back of queue + mParticipants.push_back(mParticipants.front()); + mParticipants.pop_front(); + InfoLog(<< "ParkOrbit::getNextQueuedParticipant removed participant=" << participantHandle << " from orbit " << mOrbit << " (size=" << mParticipants.size() << ")"); + } + } + return participantHandle; +} + +bool +ParkOrbit::onMaxParkTimeout(recon::ParticipantHandle participantHandle) +{ + ParticipantQueue::iterator it = mParticipants.begin(); + for(;it!=mParticipants.end();it++) + { + if((*it)->mParticipantHandle == participantHandle) + { + InfoLog(<< "ParkOrbit::onMaxParkTimeout sending parked call back to " << (*it)->mParkerUri << ", participant=" << participantHandle << " from orbit " << mOrbit << " (size=" << mParticipants.size() << ")"); + mServer.redirectParticipant(participantHandle, NameAddr((*it)->mParkerUri)); + (*it)->mAllocationTime = resip::Timer::getTimeSecs(); // Ensure call can't be retrieved between now and destruction + mServer.destroyParticipant(participantHandle); // Fully blind transfer - don't wait for notifies + return true; + } + } + return false; +} + +} + +/* ==================================================================== + + Copyright (c) 2011, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/ParkOrbit.hxx b/src/libs/resiprocate/resip/recon/MOHParkServer/ParkOrbit.hxx new file mode 100644 index 00000000..eda9f067 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/ParkOrbit.hxx @@ -0,0 +1,86 @@ +#if !defined(ParkOrbit_hxx) +#define ParkOrbit_hxx + +#include <deque> +#include <resip/stack/Uri.hxx> +#include "../HandleTypes.hxx" + +namespace mohparkserver +{ +class Server; + +class ParticipantOrbitInfo +{ +public: + ParticipantOrbitInfo(recon::ParticipantHandle participantHandle, const resip::Uri& parkedUri, const resip::Uri& parkerUri) : + mParticipantHandle(participantHandle), mParkedUri(parkedUri), mParkerUri(parkerUri) {} + recon::ParticipantHandle mParticipantHandle; + UInt64 mAllocationTime; + resip::Uri mParkedUri; + resip::Uri mParkerUri; +}; + +class ParkOrbit +{ +public: + ParkOrbit(Server& server, unsigned long orbit, unsigned long maxParkTime, const resip::Uri& musicFilename); + virtual ~ParkOrbit(); + + bool addParticipant(recon::ParticipantHandle participantHandle, const resip::Uri& parkedUri, const resip::Uri& parkerUri); + bool removeParticipant(recon::ParticipantHandle participantHandle); + + recon::ParticipantHandle getNextQueuedParticipant(); + unsigned long getOrbit() { return mOrbit; } + unsigned long getNumParticipants() { return (unsigned long)mParticipants.size(); } + recon::ConversationHandle getConversationHandle() { return mConversationHandle; } + + bool onMaxParkTimeout(recon::ParticipantHandle participantHandle); + +private: + friend class ParkManager; + Server& mServer; + unsigned long mOrbit; + unsigned long mMaxParkTime; + recon::ConversationHandle mConversationHandle; + typedef std::deque<ParticipantOrbitInfo*> ParticipantQueue; + ParticipantQueue mParticipants; +}; + +} + +#endif + +/* ==================================================================== + + Copyright (c) 2011, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/Server.cxx b/src/libs/resiprocate/resip/recon/MOHParkServer/Server.cxx new file mode 100644 index 00000000..26416ab9 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/Server.cxx @@ -0,0 +1,570 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include <process.h> +#else +#include <spawn.h> +#endif + +#include "Server.hxx" +#include "../UserAgent.hxx" +#include "AppSubsystem.hxx" +#include "WebAdmin.hxx" +#include "WebAdminThread.hxx" + +#include <resip/stack/Tuple.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/ThreadIf.hxx> +#include <rutil/WinLeakCheck.hxx> + +// sipX includes +#include <os/OsSysLog.h> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM AppSubsystem::MOHPARKSERVER + +namespace mohparkserver +{ + +class SdpMessageDecorator : public MessageDecorator +{ +public: + virtual ~SdpMessageDecorator() {} + virtual void decorateMessage(SipMessage &msg, + const Tuple &source, + const Tuple &destination, + const Data& sigcompId) + { + SdpContents* sdp = dynamic_cast<SdpContents*>(msg.getContents()); + if(sdp && sdp->session().media().size() > 0 && sdp->session().connection().getAddress() == "0.0.0.0") + { + // Fill in IP and Port from source + sdp->session().connection().setAddress(Tuple::inet_ntop(source), source.ipVersion() == V6 ? SdpContents::IP6 : SdpContents::IP4); + sdp->session().origin().setAddress(Tuple::inet_ntop(source), source.ipVersion() == V6 ? SdpContents::IP6 : SdpContents::IP4); + DebugLog( << "SdpMessageDecorator: src=" << source << ", dest=" << destination << ", msg=" << endl << msg.brief()); + } + } + virtual void rollbackMessage(SipMessage& msg) {} // Nothing to do + virtual MessageDecorator* clone() const { return new SdpMessageDecorator; } +}; + +class MyUserAgent : public UserAgent +{ +public: + MyUserAgent(Server& server, SharedPtr<UserAgentMasterProfile> profile, resip::AfterSocketCreationFuncPtr socketFunc) : + UserAgent(&server, profile, socketFunc), + mServer(server) {} + + virtual void onApplicationTimer(unsigned int id, unsigned int durationMs, unsigned int seq) + { + if(id == MAXPARKTIMEOUT) + { + mServer.onMaxParkTimeout((ParticipantHandle)seq); + } + else + { + InfoLog(<< "onApplicationTimeout: id=" << id << " dur=" << durationMs << " seq=" << seq); + } + + } + + virtual void onSubscriptionTerminated(SubscriptionHandle handle, unsigned int statusCode) + { + InfoLog(<< "onSubscriptionTerminated: handle=" << handle << " statusCode=" << statusCode); + } + + virtual void onSubscriptionNotify(SubscriptionHandle handle, Data& notifyData) + { + InfoLog(<< "onSubscriptionNotify: handle=" << handle << " data=" << endl << notifyData); + } +private: + Server& mServer; +}; + +class MOHParkServerLogger : public ExternalLogger +{ +public: + virtual ~MOHParkServerLogger() {} + /** return true to also do default logging, false to supress default logging. */ + virtual bool operator()(Log::Level level, + const Subsystem& subsystem, + const Data& appName, + const char* file, + int line, + const Data& message, + const Data& messageWithHeaders) + { + // Log any warnings/errors to the screen and all MOHParkServer logging messages + if(level <= Log::Warning || subsystem.getSubsystem() == AppSubsystem::MOHPARKSERVER.getSubsystem()) + { + resipCout << messageWithHeaders << endl; + } + return true; + } +}; +MOHParkServerLogger g_MOHParkServerLogger; + +Server::Server(ConfigParser& config) : + ConversationManager(false /* local audio? */, ConversationManager::sipXConversationMediaInterfaceMode), + mConfig(config), + mIsV6Avail(false), + mMyUserAgent(0), + mMOHManager(*this), + mParkManager(*this), + mWebAdmin(0), + mWebAdminThread(0) +{ + // Initialize loggers + initializeResipLogging(mConfig.mLogFileMaxBytes, mConfig.mLogLevel, mConfig.mLogFilename); + if(!mConfig.mSipXLogFilename.empty()) + { + //enableConsoleOutput(TRUE); // Allow sipX console output + OsSysLog::initialize(0, "MOHParkServer"); + OsSysLog::setOutputFile(0, mConfig.mSipXLogFilename.c_str()) ; + } + + InfoLog( << "MOHParkServer settings:"); + InfoLog( << " MOH URI = " << mConfig.mMOHUri); + InfoLog( << " MOH Registration Time = " << mConfig.mMOHRegistrationTime); + InfoLog( << " MOH Filename URL = " << mConfig.mMOHFilenameUrl); + InfoLog( << " Park URI = " << mConfig.mParkUri); + InfoLog( << " Park Registration Time = " << mConfig.mParkRegistrationTime); + InfoLog( << " Park MOH Filename URL = " << mConfig.mParkMOHFilenameUrl); + InfoLog( << " Park Orbit Range Start = " << mConfig.mParkOrbitRangeStart); + InfoLog( << " Park Number of Orbits = " << mConfig.mParkNumOrbits); + InfoLog( << " Park Orbit Registration Time = " << mConfig.mParkOrbitRegistrationTime); + InfoLog( << " Local IP Address = " << mConfig.mAddress); + InfoLog( << " Override DNS Servers = " << mConfig.mDnsServers); + InfoLog( << " UDP Port = " << mConfig.mUdpPort); + InfoLog( << " TCP Port = " << mConfig.mTcpPort); + InfoLog( << " TLS Port = " << mConfig.mTlsPort); + InfoLog( << " TLS Domain = " << mConfig.mTlsDomain); + InfoLog( << " Keepalives = " << (mConfig.mKeepAlives ? "enabled" : "disabled")); + InfoLog( << " Outbound Proxy = " << mConfig.mOutboundProxy); + InfoLog( << " Media Port Range Start = " << mConfig.mMediaPortRangeStart); + InfoLog( << " Media Port Range Size = " << mConfig.mMediaPortRangeSize); + InfoLog( << " Log Level = " << mConfig.mLogLevel); + + resip::Data ; + + if(!mConfig.mAddress.empty()) + { + // If address is specified in config file, then just use this address only + Tuple myTuple(mConfig.mAddress, mConfig.mUdpPort, UDP); + if(myTuple.ipVersion() == V6) + { + mIsV6Avail = true; + } + } + else + { + // If address in config is empty - query network interface info + std::list<std::pair<Data,Data> > interfaces = DnsUtil::getInterfaces(); + std::list<std::pair<Data,Data> >::iterator itInt = interfaces.begin(); + for(;itInt != interfaces.end(); itInt++) + { + Tuple myTuple(itInt->second, mConfig.mUdpPort, UDP); + if(myTuple.ipVersion() == V6) + { + mIsV6Avail = true; + } + } + } + + ////////////////////////////////////////////////////////////////////////////// + // Setup UserAgentMasterProfile + ////////////////////////////////////////////////////////////////////////////// + + SharedPtr<UserAgentMasterProfile> profile(new UserAgentMasterProfile); + + // Add transports + try + { + if(mConfig.mUdpPort == (unsigned short)-1 +#ifdef USE_SSL + && mConfig.mTlsPort == (unsigned short)-1 +#endif + && mConfig.mTcpPort == (unsigned short)-1) + { + // Ensure there is at least one transport enabled - if all are disabled, then enable UDP on an OS selected port + mConfig.mUdpPort = 0; + } + if(mConfig.mUdpPort != (unsigned short)-1) + { + profile->addTransport(UDP, mConfig.mUdpPort, V4, mConfig.mAddress); + if(mIsV6Avail) + { + profile->addTransport(UDP, mConfig.mUdpPort, V6, mConfig.mAddress); + } + } + if(mConfig.mTcpPort != (unsigned short)-1) + { + profile->addTransport(TCP, mConfig.mTcpPort, V4, mConfig.mAddress); + if(mIsV6Avail) + { + profile->addTransport(TCP, mConfig.mTcpPort, V6, mConfig.mAddress); + } + } +#ifdef USE_SSL + if(mConfig.mTlsPort != (unsigned short)-1) + { + profile->addTransport(TLS, mConfig.mTlsPort, V4, mConfig.mAddress, mConfig.mTlsDomain); + if(mIsV6Avail) + { + profile->addTransport(TLS, mConfig.mTlsPort, V6, mConfig.mAddress, mConfig.mTlsDomain); + } + } +#endif + } + catch (BaseException& e) + { + std::cerr << "Cannot start a transport, likely a port is already in use" << endl; + InfoLog (<< "Caught: " << e); + exit(-1); + } + + // DNS Servers + ParseBuffer pb(mConfig.mDnsServers); + Data dnsServer; + while(!mConfig.mDnsServers.empty() && !pb.eof()) + { + pb.skipWhitespace(); + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace, ";,"); // allow white space + pb.data(dnsServer, start); + if(DnsUtil::isIpV4Address(dnsServer)) + { + InfoLog( << "Adding DNS Server: " << dnsServer); + profile->addAdditionalDnsServer(dnsServer); + } + else + { + ErrLog( << "Tried to add dns server, but invalid format: " << dnsServer); + } + if(!pb.eof()) + { + pb.skipChar(); + } + } + + // Disable Statisitics Manager + profile->statisticsManagerEnabled() = false; + + if(mConfig.mKeepAlives) + { + profile->setKeepAliveTimeForDatagram(30); + profile->setKeepAliveTimeForStream(180); + } + + // Support Methods, etc. + profile->validateContentEnabled() = false; + profile->validateContentLanguageEnabled() = false; + profile->validateAcceptEnabled() = false; + + profile->clearSupportedLanguages(); + profile->addSupportedLanguage(Token("en")); + + profile->clearSupportedMimeTypes(); + profile->addSupportedMimeType(INVITE, Mime("application", "sdp")); + profile->addSupportedMimeType(INVITE, Mime("multipart", "mixed")); + profile->addSupportedMimeType(INVITE, Mime("multipart", "signed")); + profile->addSupportedMimeType(INVITE, Mime("multipart", "alternative")); + profile->addSupportedMimeType(OPTIONS,Mime("application", "sdp")); + profile->addSupportedMimeType(OPTIONS,Mime("multipart", "mixed")); + profile->addSupportedMimeType(OPTIONS, Mime("multipart", "signed")); + profile->addSupportedMimeType(OPTIONS, Mime("multipart", "alternative")); + profile->addSupportedMimeType(NOTIFY, Mime("message", "sipfrag")); + + profile->clearSupportedMethods(); + profile->addSupportedMethod(INVITE); + profile->addSupportedMethod(ACK); + profile->addSupportedMethod(CANCEL); + profile->addSupportedMethod(OPTIONS); + profile->addSupportedMethod(BYE); + profile->addSupportedMethod(REFER); + profile->addSupportedMethod(NOTIFY); + profile->addSupportedMethod(SUBSCRIBE); + + profile->clearSupportedOptionTags(); + profile->addSupportedOptionTag(Token(Symbols::Replaces)); + profile->addSupportedOptionTag(Token(Symbols::Timer)); + profile->addSupportedOptionTag(Token(Symbols::NoReferSub)); + profile->addSupportedOptionTag(Token(Symbols::AnswerMode)); + profile->addSupportedOptionTag(Token(Symbols::TargetDialog)); + + profile->setUacReliableProvisionalMode(MasterProfile::Never); + + profile->clearSupportedSchemes(); + profile->addSupportedScheme("sip"); +#ifdef USE_SSL + profile->addSupportedScheme("sips"); +#endif + + // Have stack add Allow/Supported/Accept headers to INVITE dialog establishment messages + profile->clearAdvertisedCapabilities(); // Remove Profile Defaults, then add our preferences + profile->addAdvertisedCapability(Headers::Allow); + //profile->addAdvertisedCapability(Headers::AcceptEncoding); // This can be misleading - it might specify what is expected in response + profile->addAdvertisedCapability(Headers::AcceptLanguage); + profile->addAdvertisedCapability(Headers::Supported); + profile->setMethodsParamEnabled(true); + + profile->setUserAgent("MOHParkServer"); + profile->rtpPortRangeMin() = mConfig.mMediaPortRangeStart; + profile->rtpPortRangeMax() = mConfig.mMediaPortRangeStart + mConfig.mMediaPortRangeSize-1; + + // Install Sdp Message Decorator + SharedPtr<MessageDecorator> outboundDecorator(new SdpMessageDecorator); + profile->setOutboundDecorator(outboundDecorator); + + mUserAgentMasterProfile = profile; + + // Create UserAgent + mMyUserAgent = new MyUserAgent(*this, profile, mConfig.mSocketFunc); + + if(mConfig.mHttpPort != 0) + { + // Create WebAdmin + mWebAdmin = new WebAdmin(*this, true /* noWebChallenges */, Data::Empty, Data::Empty, mConfig.mHttpPort, resip::V4); + mWebAdminThread = new WebAdminThread(*mWebAdmin); + assert(mWebAdminThread && mWebAdmin); + mWebAdminThread->run(); + } +} + +Server::~Server() +{ + if(mWebAdminThread) + { + mWebAdminThread->shutdown(); + mWebAdminThread->join(); + delete mWebAdminThread; + mWebAdminThread = 0; + } + if(mWebAdmin) + { + delete mWebAdmin; + mWebAdmin = 0; + } + + shutdown(); + delete mMyUserAgent; +} + +void +Server::initializeResipLogging(unsigned int maxByteCount, const Data& level, const Data& resipFilename) +{ + // Initialize loggers + GenericLogImpl::MaxByteCount = maxByteCount; + Log::initialize("file", level.c_str(), "", resipFilename.c_str(), &g_MOHParkServerLogger); +} + +void +Server::startup() +{ + assert(mMyUserAgent); + mMyUserAgent->startup(); + mMOHManager.startup(); + mParkManager.startup(); +} + +void +Server::process(int timeoutMs) +{ + assert(mMyUserAgent); + mMyUserAgent->process(timeoutMs); +} + +void +Server::shutdown() +{ + mMOHManager.shutdown(true /*shuttingDownServer*/); + mParkManager.shutdown(true /*shuttingDownServer*/); + assert(mMyUserAgent); + mMyUserAgent->shutdown(); + OsSysLog::shutdown(); +} + +void +Server::buildSessionCapabilities(resip::SdpContents& sessionCaps) +{ + unsigned int codecIds[] = { SdpCodec::SDP_CODEC_PCMU /* 0 - pcmu */, + SdpCodec::SDP_CODEC_PCMA /* 8 - pcma */, + SdpCodec::SDP_CODEC_SPEEX /* 96 - speex NB 8,000bps */, + SdpCodec::SDP_CODEC_SPEEX_15 /* 98 - speex NB 15,000bps */, + SdpCodec::SDP_CODEC_SPEEX_24 /* 99 - speex NB 24,600bps */, + SdpCodec::SDP_CODEC_L16_44100_MONO /* PCM 16 bit/sample 44100 samples/sec. */, + SdpCodec::SDP_CODEC_G726_16, + SdpCodec::SDP_CODEC_G726_24, + SdpCodec::SDP_CODEC_G726_32, + SdpCodec::SDP_CODEC_G726_40, + SdpCodec::SDP_CODEC_ILBC /* 108 - iLBC */, + SdpCodec::SDP_CODEC_ILBC_20MS /* 109 - Internet Low Bit Rate Codec, 20ms (RFC3951) */, + SdpCodec::SDP_CODEC_SPEEX_5 /* 97 - speex NB 5,950bps */, + SdpCodec::SDP_CODEC_GSM /* 3 - GSM */, + SdpCodec::SDP_CODEC_TONES /* 110 - telephone-event */}; + unsigned int numCodecIds = sizeof(codecIds) / sizeof(codecIds[0]); + ConversationManager::buildSessionCapabilities(mConfig.mAddress, numCodecIds, codecIds, sessionCaps); +} + +void +Server::getActiveCallsInfo(std::list<ActiveCallInfo>& callInfos) +{ + callInfos.clear(); + mMOHManager.getActiveCallsInfo(callInfos); + mParkManager.getActiveCallsInfo(callInfos); +} + +void +Server::onConversationDestroyed(ConversationHandle convHandle) +{ + InfoLog(<< "onConversationDestroyed: handle=" << convHandle); +} + +void +Server::onParticipantDestroyed(ParticipantHandle partHandle) +{ + InfoLog(<< "onParticipantDestroyed: handle=" << partHandle); + if(!mMOHManager.removeParticipant(partHandle)) + { + mParkManager.removeParticipant(partHandle); + } +} + +void +Server::onDtmfEvent(ParticipantHandle partHandle, int dtmf, int duration, bool up) +{ + InfoLog(<< "onDtmfEvent: handle=" << partHandle << " tone=" << dtmf << " dur=" << duration << " up=" << up); +} + +void +Server::onIncomingParticipant(ParticipantHandle partHandle, const SipMessage& msg, bool autoAnswer, ConversationProfile& conversationProfile) +{ + InfoLog(<< "onIncomingParticipant: handle=" << partHandle << " auto=" << autoAnswer << " msg=" << msg.brief()); + + if(mMOHManager.isMyProfile(conversationProfile)) + { + mMOHManager.addParticipant(partHandle, msg.header(h_From).uri(), msg.header(h_From).uri()); + } + else if(mParkManager.isMyProfile(conversationProfile)) + { + mParkManager.incomingParticipant(partHandle, msg); + } + else + { + rejectParticipant(partHandle, 404); + } +} + +void +Server::onRequestOutgoingParticipant(ParticipantHandle partHandle, const SipMessage& msg, ConversationProfile& conversationProfile) +{ + InfoLog(<< "onRequestOutgoingParticipant: handle=" << partHandle << " msg=" << msg.brief()); + if(mMOHManager.isMyProfile(conversationProfile)) + { + mMOHManager.addParticipant(partHandle, msg.header(h_ReferTo).uri().getAorAsUri(), msg.header(h_From).uri()); + } + else if(mParkManager.isMyProfile(conversationProfile)) + { + mParkManager.parkParticipant(partHandle, msg); + } + else + { + rejectParticipant(partHandle, 404); + } +} + +void +Server::onParticipantTerminated(ParticipantHandle partHandle, unsigned int statusCode) +{ + InfoLog(<< "onParticipantTerminated: handle=" << partHandle); +} + +void +Server::onParticipantProceeding(ParticipantHandle partHandle, const SipMessage& msg) +{ + InfoLog(<< "onParticipantProceeding: handle=" << partHandle << " msg=" << msg.brief()); +} + +void +Server::onRelatedConversation(ConversationHandle relatedConvHandle, ParticipantHandle relatedPartHandle, + ConversationHandle origConvHandle, ParticipantHandle origPartHandle) +{ + InfoLog(<< "onRelatedConversation: relatedConvHandle=" << relatedConvHandle << " relatedPartHandle=" << relatedPartHandle + << " origConvHandle=" << origConvHandle << " origPartHandle=" << origPartHandle); +} + +void +Server::onParticipantAlerting(ParticipantHandle partHandle, const SipMessage& msg) +{ + InfoLog(<< "onParticipantAlerting: handle=" << partHandle << " msg=" << msg.brief()); +} + +void +Server::onParticipantConnected(ParticipantHandle partHandle, const SipMessage& msg) +{ + InfoLog(<< "onParticipantConnected: handle=" << partHandle << " msg=" << msg.brief()); +} + +void +Server::onParticipantRedirectSuccess(ParticipantHandle partHandle) +{ + InfoLog(<< "onParticipantRedirectSuccess: handle=" << partHandle); + destroyParticipant(partHandle); // Transfer is successful - end participant +} + +void +Server::onParticipantRedirectFailure(ParticipantHandle partHandle, unsigned int statusCode) +{ + InfoLog(<< "onParticipantRedirectFailure: handle=" << partHandle << " statusCode=" << statusCode); +} + +void +Server::onMaxParkTimeout(recon::ParticipantHandle participantHandle) +{ + // Pass to ParkManager to see if participant is still around + mParkManager.onMaxParkTimeout(participantHandle); +} + +} + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/Server.hxx b/src/libs/resiprocate/resip/recon/MOHParkServer/Server.hxx new file mode 100644 index 00000000..10c5a95c --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/Server.hxx @@ -0,0 +1,136 @@ +#if !defined(Server_hxx) +#define Server_hxx + +#include "ConfigParser.hxx" +#include "MOHManager.hxx" +#include "ParkManager.hxx" +#include "ActiveCallInfo.hxx" +#include "../UserAgent.hxx" +#include "../HandleTypes.hxx" + +#ifdef WIN32 + #define sleepMs(t) Sleep(t) +#else + #define sleepMs(t) usleep(t*1000) +#endif + +#define MAXPARKTIMEOUT 1 + +namespace mohparkserver +{ +class WebAdminThread; +class WebAdmin; + +class Server : public recon::ConversationManager +{ +public: + Server(ConfigParser& config); + virtual ~Server(); + + // Called in contructor, but can be used to modify logging at runtime + void initializeResipLogging(unsigned int maxByteCount, const resip::Data& level, const resip::Data& resipFilename); + + /** + Starts the recon thread(s). + + @note This should be called before calling process() in a loop + */ + void startup(); + + /** + This should be called in a loop to give process cycles to the server. + + @param timeoutMs Will return after timeoutMs if nothing to do. + Application can do some work, but should call + process again ASAP. + */ + void process(int timeoutMs); // call this in a loop + + /** + Used to initiate a shutdown of the server. This function blocks + until the shutdown is complete. + + @note There should not be an active process request when this + is called. + */ + void shutdown(); + + recon::UserAgent* getMyUserAgent() { return mMyUserAgent; } + MOHManager& getMOHManager() { return mMOHManager; } + ParkManager& getParkManager() { return mParkManager; } + void getActiveCallsInfo(CallInfoList& callInfos); + + // Timer handler + virtual void onMaxParkTimeout(recon::ParticipantHandle participantHandle); + + // Configuration Container + ConfigParser& mConfig; + +protected: + // Conversation Manager Handlers + virtual void onConversationDestroyed(recon::ConversationHandle convHandle); + virtual void onParticipantDestroyed(recon::ParticipantHandle partHandle); + virtual void onDtmfEvent(recon::ParticipantHandle partHandle, int dtmf, int duration, bool up); + virtual void onIncomingParticipant(recon::ParticipantHandle partHandle, const resip::SipMessage& msg, bool autoAnswer, recon::ConversationProfile& conversationProfile); + virtual void onRequestOutgoingParticipant(recon::ParticipantHandle partHandle, const resip::SipMessage& msg, recon::ConversationProfile& conversationProfile); + virtual void onParticipantTerminated(recon::ParticipantHandle partHandle, unsigned int statusCode); + virtual void onParticipantProceeding(recon::ParticipantHandle partHandle, const resip::SipMessage& msg); + virtual void onRelatedConversation(recon::ConversationHandle relatedConvHandle, recon::ParticipantHandle relatedPartHandle, + recon::ConversationHandle origConvHandle, recon::ParticipantHandle origPartHandle); + virtual void onParticipantAlerting(recon::ParticipantHandle partHandle, const resip::SipMessage& msg); + virtual void onParticipantConnected(recon::ParticipantHandle partHandle, const resip::SipMessage& msg); + virtual void onParticipantRedirectSuccess(recon::ParticipantHandle partHandle); + virtual void onParticipantRedirectFailure(recon::ParticipantHandle partHandle, unsigned int statusCode); + +private: + friend class MOHManager; + friend class ParkManager; + void buildSessionCapabilities(resip::SdpContents& sessionCaps); + + bool mIsV6Avail; + recon::UserAgent* mMyUserAgent; + resip::SharedPtr<recon::UserAgentMasterProfile> mUserAgentMasterProfile; + MOHManager mMOHManager; + ParkManager mParkManager; + WebAdmin* mWebAdmin; + WebAdminThread* mWebAdminThread; +}; + +} + +#endif + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/WebAdmin.cxx b/src/libs/resiprocate/resip/recon/MOHParkServer/WebAdmin.cxx new file mode 100644 index 00000000..c5d18bce --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/WebAdmin.cxx @@ -0,0 +1,305 @@ +#include <cassert> +#include <time.h> + +#include <resip/stack/Symbols.hxx> +#include <resip/stack/Tuple.hxx> +#include <rutil/Data.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/Logger.hxx> +#include <rutil/MD5Stream.hxx> +#include <rutil/ParseBuffer.hxx> +#include <rutil/Socket.hxx> +#include <rutil/Timer.hxx> +#include <rutil/TransportType.hxx> + +#include "AppSubsystem.hxx" +#include "HttpBase.hxx" +#include "HttpConnection.hxx" +#include "WebAdmin.hxx" +#include "ActiveCallInfo.hxx" +#include "Server.hxx" + +using namespace resip; +using namespace mohparkserver; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM AppSubsystem::MOHPARKSERVER + + +WebAdmin::RemoveKey::RemoveKey(const Data &key1, const Data &key2) : mKey1(key1), mKey2(key2) +{ +}; + +bool +WebAdmin::RemoveKey::operator<(const RemoveKey& rhs) const +{ + if(mKey1 < rhs.mKey1) + { + return true; + } + else if(mKey1 == rhs.mKey1 && mKey2 < rhs.mKey2) + { + return true; + } + else + { + return false; + } +} + +WebAdmin::WebAdmin( Server& server, + bool noChal, + const Data& realm, // this realm is used for http challenges + const Data& adminPassword, + int port, + IpVersion version ): + HttpBase( port, version, realm ), + mServer(server), + mNoWebChallenges( noChal ) +{ +} + + +void +WebAdmin::buildPage( const Data& uri, + int pageNumber, + const resip::Data& pUser, + const resip::Data& pPassword ) +{ + ParseBuffer pb(uri); + + DebugLog (<< "Parsing URL" << uri ); + + const char* anchor = pb.skipChar('/'); + pb.skipToChar('?'); + Data pageName; + pb.data(pageName,anchor); + + DebugLog (<< " got page name: " << pageName ); + + // if this is not a valid page, redirect it + if (pageName != Data("activecalls.html")) + { + setPage( resip::Data::Empty, pageNumber, 301 ); + return; + } + + // parse any URI tags from form entry + mRemoveSet.clear(); + mHttpParams.clear(); + + if (!pb.eof()) + { + pb.skipChar('?'); + + while ( !pb.eof() ) + { + const char* anchor1 = pb.position(); + pb.skipToChar('='); + Data key; + pb.data(key,anchor1); + + const char* anchor2 = pb.skipChar('='); + pb.skipToChar('&'); + Data value; + pb.data(value,anchor2); + + if ( !pb.eof() ) + { + pb.skipChar('&'); + } + + if ( key.prefix("remove.") ) // special case of parameters to delete one or more records + { + Data tmp = key.substr(7); // the ID is everything after the dot + if (!tmp.empty()) + { + DebugLog (<< " remove key=" << tmp.urlDecoded()); + mRemoveSet.insert(RemoveKey(tmp.urlDecoded(),value.urlDecoded())); // add to the set of records to remove + } + } + else if ( !key.empty() && !value.empty() ) // make sure both exist + { + DebugLog (<< " key=" << key << " value=" << value << " & unencoded form: " << value.urlDecoded() ); + mHttpParams[key] = value.urlDecoded(); // add other parameters to the Map + } + } + + } + + Data page; + DataStream s(page); + buildPageOutlinePre(s); + + if ( pageName == Data("activecalls.html")) + { + buildActiveCallsSubPage(s); + } + else + { + assert(false); + } + buildPageOutlinePost(s); + s.flush(); + + assert( !page.empty() ); + setPage( page, pageNumber,200 ); +} + + +void +WebAdmin::buildActiveCallsSubPage(DataStream& s) +{ + if (!mRemoveSet.empty()) + { + int j = 0; + for (set<RemoveKey>::iterator i = mRemoveSet.begin(); i != mRemoveSet.end(); ++i) + { + Uri aor(i->mKey1); + ContactInstanceRecord rec; + size_t bar1 = i->mKey2.find("|"); + size_t bar2 = i->mKey2.find("|",bar1+1); + + if(bar1==Data::npos || bar2 == Data::npos) + { + InfoLog(<< "Registration removal key was malformed: " << i->mKey2); + continue; + } + + try + { + resip::Data rawNameAddr = i->mKey2.substr(0,bar1).urlDecoded(); + rec.mContact = NameAddr(rawNameAddr); + rec.mInstance = i->mKey2.substr(bar1+1,bar2-bar1-1).urlDecoded(); + rec.mRegId = i->mKey2.substr(bar2+1,Data::npos).convertInt(); + //mRegDb.lockRecord(aor); // TODO + //mRegDb.removeContact(aor, rec); + //mRegDb.unlockRecord(aor); + ++j; + } + catch(resip::ParseBuffer::Exception& e) + { + InfoLog(<< "Registration removal key was malformed: " << e << + " Key was: " << i->mKey2); + } + + } + s << "<p><em>Removed:</em> " << j << " records</p>" << endl; + } + + s << + "<form id=\"showReg\" method=\"get\" action=\"registrations.html\" name=\"showReg\" enctype=\"application/x-www-form-urlencoded\">" << endl << + //"<button name=\"removeAllReg\" value=\"\" type=\"button\">Remove All</button>" << endl << + //"<hr/>" << endl << + + "<table border=\"1\" cellspacing=\"2\" cellpadding=\"0\" align=\"left\">" << endl << + + "<tr>" << endl << + " <td>Held URI</td>" << endl << + " <td>Invoking URI</td>" << endl << + " <td>Hold Type</td>" << endl << + " <td>Participant ID</td>" << endl << + " <td>Conversation ID</td>" << endl << + //" <td><input type=\"submit\" value=\"Remove\"/></td>" << endl << // TODO + "</tr>" << endl; + + CallInfoList callInfos; + mServer.getActiveCallsInfo(callInfos); + for (CallInfoList::iterator it = callInfos.begin(); it != callInfos.end(); ++it ) + { + s << "<tr>" << endl + << " <td>" << it->mHeldUri << "</td>" << endl + << " <td>" << it->mInvokingUri << "</td>" << endl + << " <td>" << it->mHoldType << "</td>" << endl + << " <td>" << it->mParticipantId << "</td>" << endl + << " <td>" << it->mConversationId << "</td>" << endl + //<< " <td><input type=\"checkbox\" name=\"remove." << it->mHeldUri << "\" value=\"" << it->mParticipantId << "\"/></td>" << endl // TODO + << "</tr>" << endl; + } + + s << "</table>" << endl << + "</form>" << endl; +} + +void +WebAdmin::buildPageOutlinePre(DataStream& s) +{ +s << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; +s << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"; +s << "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"; +s << " <head>\n"; +s << " <meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />\n"; +s << " <title>MOHParkServer Active Call List</title>\n"; +s << " </head>\n"; +s << " <style>\n"; +s << "body { bgcolor: white; font-size: 90%; font-family: Arial, Helvetica, sans-serif }\n"; +s << "h1 { font-size: 200%; font-weight: bold }\n"; +s << "h2 { font-size: 100%; font-weight: bold; text-transform: uppercase }\n"; +s << "h3 { font-size: 100%; font-weight: normal }\n"; +s << "h4 { font-size: 100%; font-style: oblique; font-weight: normal } \n"; +s << "hr { line-height: 2px; margin-top: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0; height: 10px }\n"; +s << "div.title { color: white; background-color: #395af6; padding-top: 10px; padding-bottom: 10px; padding-left: 10px }\n"; +s << "div.title h1 { text-transform: uppercase; margin-top: 0; margin-bottom: 0 } \n"; +s << "div.menu { color: black; background-color: #ff8d09; padding: 0 10px 10px; \n"; +s << " width: 9em; float: left; clear: none; overflow: hidden }\n"; +s << "div.menu p { font-weight: bold; text-transform: uppercase; list-style-type: none; \n"; +s << " margin-top: 0; margin-bottom: 0; margin-left: 10px }\n"; +s << "div.menu h2 { margin-top: 10px; margin-bottom: 0 ; text-transform: uppercase; }\n"; +s << "div.main { color: black; background-color: #dae1ed; margin-left: 11em }\n"; +s << "div.space { font-size: 5px; height: 10px }\n"; +s << " </style>\n"; +s << " <body>\n"; +} + + +void +WebAdmin::buildPageOutlinePost(DataStream& s) +{ +s << " </body>\n"; +s << "</html>\n"; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/WebAdmin.hxx b/src/libs/resiprocate/resip/recon/MOHParkServer/WebAdmin.hxx new file mode 100644 index 00000000..81d741f4 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/WebAdmin.hxx @@ -0,0 +1,120 @@ +#if !defined(MOHPARKSERVER_WEBADMIN_HXX) +#define MOHPARKSERVER_WEBADMIN_HXX + +#include <rutil/Data.hxx> +#include <rutil/TransportType.hxx> +#include <resip/stack/Tuple.hxx> + +#include "HttpBase.hxx" + +#include <map> + +namespace resip +{ +class DataStream; +} + + +namespace mohparkserver +{ + +class Server; +typedef std::map<resip::Data, resip::Data> Dictionary; + +class WebAdmin: public HttpBase +{ + public: + WebAdmin( Server& server, + bool noWebChallenges, + const resip::Data& realm, + const resip::Data& adminPassword, + int port=5082, + resip::IpVersion version=resip::V4 ); + + protected: + virtual void buildPage( const resip::Data& uri, + int pageNumber, + const resip::Data& user, + const resip::Data& password); + + private: + resip::Data buildDefaultPage(); + resip::Data buildUserPage(); + + void buildPageOutlinePre(resip::DataStream& s); + void buildPageOutlinePost(resip::DataStream& s); + + void buildActiveCallsSubPage(resip::DataStream& s); + + bool mNoWebChallenges; + + Dictionary mHttpParams; + + // list of the keys of records that should be deleted + class RemoveKey + { + public: + RemoveKey(const resip::Data &key1, const resip::Data &key2); + bool operator<(const RemoveKey& rhs) const; + resip::Data mKey1; + resip::Data mKey2; + }; + std::set<RemoveKey> mRemoveSet; + Server& mServer; +}; + + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/WebAdminThread.cxx b/src/libs/resiprocate/resip/recon/MOHParkServer/WebAdminThread.cxx new file mode 100644 index 00000000..a9ff0b19 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/WebAdminThread.cxx @@ -0,0 +1,92 @@ + +#include <rutil/Socket.hxx> +#include <rutil/Logger.hxx> + +#include "AppSubsystem.hxx" +#include "WebAdmin.hxx" +#include "WebAdminThread.hxx" + +#define RESIPROCATE_SUBSYSTEM AppSubsystem::MOHPARKSERVER + +using namespace resip; +using namespace mohparkserver; +using namespace std; + + +WebAdminThread::WebAdminThread(WebAdmin& web) + : mWeb(web) +{ +} + + +void +WebAdminThread::thread() +{ + while (!isShutdown()) + { + try + { + FdSet fdset; + + mWeb.buildFdSet(fdset); + fdset.selectMilliSeconds( 2*1000 ); + + mWeb.process(fdset); + } + catch (...) + { + ErrLog (<< "Unhandled exception: " ); + } + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/WebAdminThread.hxx b/src/libs/resiprocate/resip/recon/MOHParkServer/WebAdminThread.hxx new file mode 100644 index 00000000..f0bfc902 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/WebAdminThread.hxx @@ -0,0 +1,80 @@ +#ifndef MOHPARK_WebAdminThread__hxx +#define MOHPARK_WebAdminThread__hxx + +#include <rutil/ThreadIf.hxx> +#include <rutil/Socket.hxx> + +namespace mohparkserver +{ + +class WebAdmin; + +class WebAdminThread : public resip::ThreadIf +{ + public: + WebAdminThread(WebAdmin& web); + + virtual void thread(); + + protected: + // virtual void buildFdSet(FdSet& fdset); + // virtual unsigned int getTimeTillNextProcessMS() const; + + private: + WebAdmin& mWeb; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/ca.pem b/src/libs/resiprocate/resip/recon/MOHParkServer/ca.pem new file mode 100644 index 00000000..9629b437 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MOHParkServer/ca.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIB7TCCAVYCCQCxKhAUH1ygCDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJB +VTEMMAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxDTALBgNVBAoTBGFzaW8w +HhcNMDUxMTAyMTk0ODU1WhcNMTUxMTAyMTk0ODU1WjA7MQswCQYDVQQGEwJBVTEM +MAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxDTALBgNVBAoTBGFzaW8wgZ8w +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMkNbM2RjFdm48Wy1nBA3+exfJL5fR6H +guRFu/7MKf6pQZGRqhzxIWYRoYQDx16BggHwqFVVls5hgoQF0fUqoHfE8MLGwr6m +T6rIYBrIAGnH8eMhfwMNy4I0emkoWI+grEXlw54IUSijh8LokLWorElyGuPmxhn3 +IgZkgGe8dCQTAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAdpHw+r3X4NwzKn9nQs3h +mQK2WeH6DVQ1r7fWqEq1Lq10qBdobbjDRE9jpezWdGMThbYtle6/8wHUJeq189PR +XwZWyRvnfcI+pqX832yNRh24Ujwuv3wlx3JOVByybCoJc05N1THaHo0Q7j//8HsX +VS/RFHuq3muy47cV9gbsCIw= +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,EC6C715D9BC7AFF2 + +bBOh4F/Ouq2cpaWYUqCvpVVTAkptsHCkUFZpjqruGMw1pQ6BY2eBzuHHNgOV+8BI +4Md8LcvD9oRmkigXp10I6ELkPpvTqK5S/9iJBlR/XgYjuj2PkdLiT2t4dWrJP9Rq +NdjybhKV0qqB/WiBKoSI/n0mYDxmrrHjmPAXi3BnivyQiUry42hs+Izxlkyt///D +bDzkW/LqiMDwxOu9mCsxdN/iiFgKsPQBxvLbdG3p1GyERrnB85DeewYGF9fzp1Nz +CXWQiPqEkf3arqgKBIjK+TDfmDluL7+nOyhSp0j9Rh1zba8ffmYZNXXLt0ludVdm +8zbwqjbX6u4BZ+pSpnURFBp9um0TlxhpJ5F3q5ZyUa7l4tTlw37V8UkFP8KmBbuc +PDnjbdlD5BtAbR/b/dDSAhU2y7aftcTsZCu22UOLQqWOm6jMk943ZfmG93rCeKNL +qa4OPXsICSNqKivF0Ovyw5U7ODsFj0UTD8/VY+JWLz/bmJdpsBCNlkfQHGtTahfq +QY4mG0K+cWmUiGvcWcU1pjI4e551dR05wNDmyfJMHHVzn2VnCrxKSKGEtJOMcyzi +E42zQkGlYWVJyqDFHfxCe+1GJLJvW2oYGUUY/++XDzvxITT6Lq3wb1MGisoaC1Q7 +523SXpzVIU+FLlWxewrSnZOyTe13lgNK4OVnuRqz/LQExjfwUXtgqQkRp6A8jTmC +6LWEaXQ6kC7QmwX0VQgtNi74ZMMrBsaxywaE+3oEibeJiXbVJCHDo3RufA9AJnpF +HUmTFTnoBr4f8AUxN0Eyb5Yg16pzOBI5o4EzjKzJ4D0= +-----END RSA PRIVATE KEY----- diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/doc/MOHParkServer_User_Documentation.doc b/src/libs/resiprocate/resip/recon/MOHParkServer/doc/MOHParkServer_User_Documentation.doc new file mode 100644 index 00000000..a092e083 Binary files /dev/null and b/src/libs/resiprocate/resip/recon/MOHParkServer/doc/MOHParkServer_User_Documentation.doc differ diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/doc/MOHParkServer_User_Documentation.pdf b/src/libs/resiprocate/resip/recon/MOHParkServer/doc/MOHParkServer_User_Documentation.pdf new file mode 100644 index 00000000..6d80f23d Binary files /dev/null and b/src/libs/resiprocate/resip/recon/MOHParkServer/doc/MOHParkServer_User_Documentation.pdf differ diff --git a/src/libs/resiprocate/resip/recon/MOHParkServer/music.wav b/src/libs/resiprocate/resip/recon/MOHParkServer/music.wav new file mode 100644 index 00000000..56ae56bc Binary files /dev/null and b/src/libs/resiprocate/resip/recon/MOHParkServer/music.wav differ diff --git a/src/libs/resiprocate/resip/recon/Makefile b/src/libs/resiprocate/resip/recon/Makefile new file mode 100644 index 00000000..b8573c3e --- /dev/null +++ b/src/libs/resiprocate/resip/recon/Makefile @@ -0,0 +1,76 @@ +BUILD := ../../build +include $(BUILD)/Makefile.pre + +PACKAGES += ASIO RUTIL ARES OPENSSL SRTP RETURNCLIENT REFLOW SIPX BOOST PTHREAD +TARGET_LIBRARY = librecon +CODE_SUBDIRS = sdp + +SRC += \ + BridgeMixer.cxx \ + Conversation.cxx \ + ConversationManager.cxx \ + ConversationParticipantAssignment.cxx \ + ConversationProfile.cxx \ + DefaultDialogSet.cxx \ + DtmfEvent.cxx \ + FlowManagerSipXSocket.cxx \ + LocalParticipant.cxx \ + MediaEvent.cxx \ + MediaInterface.cxx \ + MediaResourceParticipant.cxx \ + MediaResourceCache.cxx \ + MediaStreamEvent.cxx \ + Participant.cxx \ + ReconSubsystem.cxx \ + RelatedConversationSet.cxx \ + RemoteParticipant.cxx \ + RemoteParticipantDialogSet.cxx \ + UserAgent.cxx \ + UserAgentClientSubscription.cxx \ + UserAgentDialogSetFactory.cxx \ + UserAgentMasterProfile.cxx \ + UserAgentRegistration.cxx \ + UserAgentServerAuthManager.cxx \ + sdp/Sdp.cxx \ + sdp/SdpCandidate.cxx \ + sdp/SdpCandidatePair.cxx \ + sdp/SdpCodec.cxx \ + sdp/SdpHelperResip.cxx \ + sdp/SdpMediaLine.cxx + +include $(BUILD)/Makefile.post + + +#################################################################### +# +# Copyright (c) 2007-2008, Plantronics, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of Plantronics nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#################################################################### diff --git a/src/libs/resiprocate/resip/recon/Makefile.am b/src/libs/resiprocate/resip/recon/Makefile.am new file mode 100644 index 00000000..6d0c5d63 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/Makefile.am @@ -0,0 +1,138 @@ +# $Id$ + +EXTRA_DIST = readme.txt +EXTRA_DIST += *.vcproj +EXTRA_DIST += *.sln +EXTRA_DIST += recon_10_0.vcxproj recon_10_0.vcxproj.filters +EXTRA_DIST += doc + +SUBDIRS = . +SUBDIRS += test +SUBDIRS += MOHParkServer + +#AM_CXXFLAGS = -DUSE_ARES + +lib_LTLIBRARIES = librecon.la +librecon_la_LIBADD = ../../reflow/libreflow.la +librecon_la_LIBADD += ../../reTurn/client/libreTurnClient.la +librecon_la_LIBADD += ../../rutil/librutil.la +librecon_la_LIBADD += @LIBSSL_LIBADD@ -lsrtp +librecon_la_LDFLAGS = @LIBTOOL_VERSION_RELEASE@ -export-dynamic + +librecon_la_SOURCES = BridgeMixer.cxx \ + Conversation.cxx \ + ConversationManager.cxx \ + ConversationParticipantAssignment.cxx \ + ConversationProfile.cxx \ + DefaultDialogSet.cxx \ + DtmfEvent.cxx \ + FlowManagerSipXSocket.cxx \ + LocalParticipant.cxx \ + MediaEvent.cxx \ + MediaInterface.cxx \ + MediaResourceParticipant.cxx \ + MediaResourceCache.cxx \ + MediaStreamEvent.cxx \ + Participant.cxx \ + ReconSubsystem.cxx \ + RelatedConversationSet.cxx \ + RemoteParticipant.cxx \ + RemoteParticipantDialogSet.cxx \ + UserAgent.cxx \ + UserAgentClientSubscription.cxx \ + UserAgentDialogSetFactory.cxx \ + UserAgentMasterProfile.cxx \ + UserAgentRegistration.cxx \ + UserAgentServerAuthManager.cxx \ + sdp/Sdp.cxx \ + sdp/SdpCandidate.cxx \ + sdp/SdpCandidatePair.cxx \ + sdp/SdpCodec.cxx \ + sdp/SdpHelperResip.cxx \ + sdp/SdpMediaLine.cxx + +reconincludedir = $(includedir)/recon +nobase_reconinclude_HEADERS = ReconSubsystem.hxx \ + LocalParticipant.hxx \ + MediaResourceCache.hxx \ + RelatedConversationSet.hxx \ + UserAgentServerAuthManager.hxx \ + ConversationManagerCmds.hxx \ + UserAgentMasterProfile.hxx \ + RemoteParticipantDialogSet.hxx \ + Conversation.hxx \ + UserAgentDialogSetFactory.hxx \ + sdp/SdpMediaLine.hxx \ + sdp/SdpCodec.hxx \ + sdp/SdpHelperResip.hxx \ + sdp/SdpCandidatePair.hxx \ + sdp/SdpCandidate.hxx \ + sdp/Sdp.hxx \ + MediaInterface.hxx \ + UserAgentCmds.hxx \ + UserAgentRegistration.hxx \ + MediaEvent.hxx \ + DefaultDialogSet.hxx \ + Participant.hxx \ + UserAgentClientSubscription.hxx \ + UserAgent.hxx \ + ConversationParticipantAssignment.hxx \ + RemoteParticipant.hxx \ + MediaResourceParticipant.hxx \ + BridgeMixer.hxx \ + HandleTypes.hxx \ + MediaStreamEvent.hxx \ + FlowManagerSipXSocket.hxx \ + ConversationProfile.hxx \ + ConversationManager.hxx \ + DtmfEvent.hxx + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# <http://www.vovida.org/>. +# +############################################################################## diff --git a/src/libs/resiprocate/resip/recon/MediaEvent.cxx b/src/libs/resiprocate/resip/recon/MediaEvent.cxx new file mode 100644 index 00000000..e8d8bea2 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MediaEvent.cxx @@ -0,0 +1,81 @@ +#include "ConversationManager.hxx" +#include "MediaEvent.hxx" + +#include <rutil/Logger.hxx> + +using namespace recon; +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +MediaEvent::MediaEvent(ConversationManager& conversationManager, + ConversationHandle conversationHandle, + int connectionId, + MediaEventType eventType) : + mConversationManager(conversationManager), + mConversationHandle(conversationHandle), + mConnectionId(connectionId), + mEventType(eventType) +{ +} + +void +MediaEvent::executeCommand() +{ + mConversationManager.notifyMediaEvent(mConversationHandle, mConnectionId, mEventType); +} + +resip::Message* +MediaEvent::clone() const +{ + assert(0); + return 0; +} + +EncodeStream& +MediaEvent::encode(EncodeStream& strm) const +{ + strm << " MediaEvent: conversationHandle=" << mConversationHandle << ", connectionId=" << mConnectionId << ", event=" << mEventType; + return strm; +} + +EncodeStream& +MediaEvent::encodeBrief(EncodeStream& strm) const +{ + return encode(strm); +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/MediaEvent.hxx b/src/libs/resiprocate/resip/recon/MediaEvent.hxx new file mode 100644 index 00000000..7097cf69 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MediaEvent.hxx @@ -0,0 +1,79 @@ +#if !defined(MediaEvent_hxx) +#define MediaEvent_hxx + +#include <resip/dum/DumCommand.hxx> +#include "HandleTypes.hxx" + +namespace recon +{ + +class ConversationManager; +class Message; + +/** + This class represents an event that happens to a media participant. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class MediaEvent : public resip::DumCommand +{ + public: + typedef enum + { + PLAY_FINISHED + } MediaEventType; + + MediaEvent(ConversationManager& conversationManager, ConversationHandle conversationHandle, int connectionId, MediaEventType eventType); + virtual void executeCommand(); + + Message* clone() const; + EncodeStream& encode(EncodeStream& strm) const; + EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + ConversationManager& mConversationManager; + ConversationHandle mConversationHandle; // set to 0 if media interface mode is global + int mConnectionId; + MediaEventType mEventType; +}; + + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/MediaInterface.cxx b/src/libs/resiprocate/resip/recon/MediaInterface.cxx new file mode 100644 index 00000000..e0813144 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MediaInterface.cxx @@ -0,0 +1,171 @@ +#include "MediaInterface.hxx" +#include "ConversationManager.hxx" +#include "ReconSubsystem.hxx" +#include "DtmfEvent.hxx" + +#include <mi/MiNotification.h> +#include <mi/MiDtmfNotf.h> +#include <mi/MiRtpStreamActivityNotf.h> +#include <mi/MiIntNotf.h> + +#include <rutil/Logger.hxx> + +using namespace recon; +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +MediaInterface::MediaInterface(ConversationManager& conversationManager, + ConversationHandle ownerConversationHandle, + CpMediaInterface* mediaInterface) : + mConversationManager(conversationManager), + mOwnerConversationHandle(ownerConversationHandle), + mMediaInterface(mediaInterface) +{ +} + +OsStatus +MediaInterface::post(const OsMsg& msg) +{ + if((OsMsg::MsgTypes)msg.getMsgType() == OsMsg::MI_NOTF_MSG) + { + MiNotification* pNotfMsg = (MiNotification*)&msg; + switch((MiNotification::NotfType)pNotfMsg->getType()) + { + case MiNotification::MI_NOTF_PLAY_STARTED: + InfoLog( << "MediaInterface: received MI_NOTF_PLAY_STARTED, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_PLAY_PAUSED: + InfoLog( << "MediaInterface: received MI_NOTF_PLAY_PAUSED, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_PLAY_RESUMED: + InfoLog( << "MediaInterface: received MI_NOTF_PLAY_RESUMED, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_PLAY_STOPPED: + InfoLog( << "MediaInterface: received MI_NOTF_PLAY_STOPPED, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_PLAY_FINISHED: + { + // Queue event to conversation manager thread + MediaEvent* mevent = new MediaEvent(mConversationManager, pNotfMsg->getConnectionId(), mOwnerConversationHandle, MediaEvent::PLAY_FINISHED); + mConversationManager.post(mevent); + InfoLog( << "MediaInterface: received MI_NOTF_PLAY_FINISHED, sourceId=" << pNotfMsg->getSourceId().data() << + ", connectionId=" << pNotfMsg->getConnectionId() << + ", conversationHandle=" << mOwnerConversationHandle); + } + break; + case MiNotification::MI_NOTF_PROGRESS: + InfoLog( << "MediaInterface: received MI_NOTF_PROGRESS, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_RECORD_STARTED: + InfoLog( << "MediaInterface: received MI_NOTF_RECORD_STARTED, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_RECORD_STOPPED: + InfoLog( << "MediaInterface: received MI_NOTF_RECORD_STOPPED, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_RECORD_FINISHED: + InfoLog( << "MediaInterface: received MI_NOTF_RECORD_FINISHED, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_RECORD_ERROR: + InfoLog( << "MediaInterface: received MI_NOTF_RECORD_ERROR, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_DTMF_RECEIVED: + { + MiDtmfNotf* pDtmfNotfMsg = (MiDtmfNotf*)&msg; + + // Get event into dum queue, so that callback is on dum thread + DtmfEvent* devent = new DtmfEvent(mConversationManager, mOwnerConversationHandle, pNotfMsg->getConnectionId(), pDtmfNotfMsg->getKeyCode(), pDtmfNotfMsg->getDuration(), pDtmfNotfMsg->getKeyPressState()==MiDtmfNotf::KEY_UP); + mConversationManager.post(devent); + + InfoLog( << "MediaInterface: received MI_NOTF_DTMF_RECEIVED, sourceId=" << pNotfMsg->getSourceId().data() << + ", connectionId=" << pNotfMsg->getConnectionId() << + ", conversationHandle=" << mOwnerConversationHandle << + ", keyCode=" << pDtmfNotfMsg->getKeyCode() << + ", state=" << pDtmfNotfMsg->getKeyPressState() << + ", duration=" << pDtmfNotfMsg->getDuration()); + } + break; + case MiNotification::MI_NOTF_DELAY_SPEECH_STARTED: + InfoLog( << "MediaInterface: received MI_NOTF_DELAY_SPEECH_STARTED, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_DELAY_NO_DELAY: + InfoLog( << "MediaInterface: received MI_NOTF_DELAY_NO_DELAY, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_DELAY_QUIESCENCE: + InfoLog( << "MediaInterface: received MI_NOTF_DELAY_QUIESCENCE, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_RX_STREAM_ACTIVITY: ///< Value for MiRtpStreamActivityNotf notifications. + { + MiRtpStreamActivityNotf* pRtpStreamActivityNotfMsg = (MiRtpStreamActivityNotf*)&msg; + + InfoLog( << "MediaInterface: received MI_NOTF_RX_STREAM_ACTIVITY, sourceId=" << pNotfMsg->getSourceId().data() << + ", connectionId=" << pNotfMsg->getConnectionId() << + ", state=" << (pRtpStreamActivityNotfMsg->getState() == MiRtpStreamActivityNotf::STREAM_START ? "STREAM_START" : + pRtpStreamActivityNotfMsg->getState() == MiRtpStreamActivityNotf::STREAM_STOP ? "STREAM_STOP" : + pRtpStreamActivityNotfMsg->getState() == MiRtpStreamActivityNotf::STREAM_CHANGE ? "STREAM_CHANGE" : + Data(pRtpStreamActivityNotfMsg->getState()).c_str()) << + ", ssrc=" << pRtpStreamActivityNotfMsg->getSsrc() << + ", address=" << pRtpStreamActivityNotfMsg->getAddress() << + ", port=" << pRtpStreamActivityNotfMsg->getPort()); + } + break; + case MiNotification::MI_NOTF_ENERGY_LEVEL: ///< Audio energy level (MiIntNotf) + { + //MiIntNotf* pIntNotfMsg = (MiIntNotf*)&msg; + //InfoLog( << "MediaInterface: received MI_NOTF_ENERGY_LEVEL, sourceId=" << pNotfMsg->getSourceId().data() << + // ", connectionId=" << pNotfMsg->getConnectionId() << + // ", value=" << pIntNotfMsg->getValue()); + } + break; + case MiNotification::MI_NOTF_VOICE_STARTED: + //InfoLog( << "MediaInterface: received MI_NOTF_VOICE_STARTED, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + case MiNotification::MI_NOTF_VOICE_STOPPED: + //InfoLog( << "MediaInterface: received MI_NOTF_VOICE_STOPPED, sourceId=" << pNotfMsg->getSourceId().data() << ", connectionId=" << pNotfMsg->getConnectionId()); + break; + + default: + InfoLog(<< "MediaInterface: unrecognized MiNotification type = " << pNotfMsg->getType()); + } + } + else + { + InfoLog(<< "MediaInterface: unrecognized message type = " << msg.getMsgType()); + } + return OS_SUCCESS; +} + + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/MediaInterface.hxx b/src/libs/resiprocate/resip/recon/MediaInterface.hxx new file mode 100644 index 00000000..686707f4 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MediaInterface.hxx @@ -0,0 +1,67 @@ +#if !defined(MediaInterface_hxx) +#define MediaInterface_hxx + +#include <os/OsMsgDispatcher.h> +#include <mi/CpMediaInterface.h> +#include "HandleTypes.hxx" + +namespace recon +{ +class ConversationManager; + +// Wrapper class to allow CpMediaIterface to be stored in a SharedPtr. +// Note: CpMediaIterface cannot be directly stored in a SharePtr because +// the destructor is private and the release() call must be used +// to destroy the object. +class MediaInterface : public OsMsgDispatcher +{ +public: + MediaInterface(ConversationManager& conversationManager, ConversationHandle ownerConversationHandle, CpMediaInterface* mediaInterface); + ~MediaInterface() { mMediaInterface->release(); } + CpMediaInterface* getInterface() { return mMediaInterface; } +private: + virtual OsStatus post(const OsMsg& msg); + + ConversationManager& mConversationManager; + ConversationHandle mOwnerConversationHandle; + CpMediaInterface* mMediaInterface; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2010, SIP Spectrum, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SIP Spectrum nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/MediaResourceCache.cxx b/src/libs/resiprocate/resip/recon/MediaResourceCache.cxx new file mode 100644 index 00000000..cd75d6c4 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MediaResourceCache.cxx @@ -0,0 +1,96 @@ +#include "ReconSubsystem.hxx" +#include "MediaResourceCache.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/WinLeakCheck.hxx> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +MediaResourceCache::MediaResourceCache() +{ +} + +MediaResourceCache::~MediaResourceCache() +{ + // Clear memory + CacheMap::iterator it; + for(it = mCacheMap.begin(); it != mCacheMap.end(); it++) + { + delete it->second; + } +} + +void +MediaResourceCache::addToCache(const resip::Data& name, const resip::Data& buffer, int type) +{ + Lock lock(mMutex); + + CacheMap::iterator it = mCacheMap.find(name); + if(it != mCacheMap.end()) + { + // Item already present update it + // SLG - WARNING - if this cached item is currently being played - there WILL be issues - need to fix this, if calling this at runtime is a requirement + it->second->mBuffer = buffer; // copies buffer locally, so that caller can free + it->second->mType = type; + } + else + { + // Add new item + mCacheMap[name] = new CacheItem(buffer, type); + } +} + +bool +MediaResourceCache::getFromCache(const resip::Data& name, resip::Data** buffer, int* type) +{ + Lock lock(mMutex); + + CacheMap::iterator it = mCacheMap.find(name); + if(it != mCacheMap.end()) + { + *buffer = &it->second->mBuffer; + *type = it->second->mType; + return true; + } + return false; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/MediaResourceCache.hxx b/src/libs/resiprocate/resip/recon/MediaResourceCache.hxx new file mode 100644 index 00000000..3d0f5d69 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MediaResourceCache.hxx @@ -0,0 +1,77 @@ +#if !defined(MediaResourceCache_hxx) +#define MediaResourceCache_hxx + +#include <map> +#include <rutil/Mutex.hxx> + +namespace recon +{ + +/** + This class is responsible for caching media resouce buffers. It use a Mutex + for locking, so that additions can happen from other threads. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class MediaResourceCache +{ + public: + MediaResourceCache(); + virtual ~MediaResourceCache(); + void addToCache(const resip::Data& name, const resip::Data& buffer, int type); + bool getFromCache(const resip::Data& name, resip::Data** buffer, int* type); + + private: + class CacheItem + { + public: + CacheItem(const resip::Data& buffer, int type) : + mBuffer(buffer), mType(type) {} + resip::Data mBuffer; + int mType; + }; + + typedef std::map<resip::Data,CacheItem*> CacheMap; + CacheMap mCacheMap; + resip::Mutex mMutex; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/MediaResourceParticipant.cxx b/src/libs/resiprocate/resip/recon/MediaResourceParticipant.cxx new file mode 100644 index 00000000..9be40231 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MediaResourceParticipant.cxx @@ -0,0 +1,545 @@ +#include "BridgeMixer.hxx" +#include "ReconSubsystem.hxx" +#include "MediaResourceParticipant.hxx" +#include "ConversationManager.hxx" +#include "Conversation.hxx" +#include "UserAgent.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <resip/stack/ExtensionParameter.hxx> +#include <rutil/WinLeakCheck.hxx> + +#include "ConversationManagerCmds.hxx" + +// sipX includes +#include <CpTopologyGraphInterface.h> +#include <mp/dtmflib.h> +#include <mp/MprFromFile.h> +#include <mp/MpStreamPlayer.h> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +static const resip::ExtensionParameter p_localonly("local-only"); +static const resip::ExtensionParameter p_remoteonly("remote-only"); +static const resip::ExtensionParameter p_repeat("repeat"); +static const resip::ExtensionParameter p_prefetch("prefetch"); + +// Url schemes +static const Data toneScheme("tone"); +static const Data fileScheme("file"); +static const Data cacheScheme("cache"); +static const Data httpScheme("http"); +static const Data httpsScheme("https"); + +// Special Tones +static const Data dialtoneTone("dialtone"); +static const Data busyTone("busy"); +static const Data ringbackTone("ringback"); +static const Data ringTone("ring"); +static const Data fastbusyTone("fastbusy"); +static const Data backspaceTone("backspace"); +static const Data callwaitingTone("callwaiting"); +static const Data holdingTone("holding"); +static const Data loudfastbusyTone("loudfastbusy"); + +namespace recon +{ + +// Used to delete a resource, from a sipX thread +class MediaResourceParticipantDeleterCmd : public DumCommand +{ + public: + MediaResourceParticipantDeleterCmd(ConversationManager& conversationManager, ParticipantHandle participantHandle) : + mConversationManager(conversationManager), mParticipantHandle(participantHandle) {} + ~MediaResourceParticipantDeleterCmd() {} + + void executeCommand() { Participant* participant = mConversationManager.getParticipant(mParticipantHandle); if(participant) delete participant; } + + Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << "MediaResourceParticipantDeleterCmd: partHandle=" << mParticipantHandle; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + + private: + ConversationManager& mConversationManager; + ParticipantHandle mParticipantHandle; +}; +} + +MediaResourceParticipant::MediaResourceParticipant(ParticipantHandle partHandle, + ConversationManager& conversationManager, + const Uri& mediaUrl) +: Participant(partHandle, conversationManager), + mMediaUrl(mediaUrl), + mStreamPlayer(0), + mToneGenPortOnBridge(-1), + mFromFilePortOnBridge(-1), + mLocalOnly(false), + mRemoteOnly(false), + mRepeat(false), + mPrefetch(false), + mDurationMs(0), + mPlaying(false), + mDestroying(false) +{ + InfoLog(<< "MediaResourceParticipant created, handle=" << mHandle << " url=" << mMediaUrl); + mResourceType = Invalid; // default + try + { + if(isEqualNoCase(mMediaUrl.scheme(), toneScheme)) + { + mResourceType = Tone; + } + else if(isEqualNoCase(mMediaUrl.scheme(), fileScheme)) + { + mResourceType = File; + } + else if(isEqualNoCase(mMediaUrl.scheme(), cacheScheme)) + { + mResourceType = Cache; + } + else if(isEqualNoCase(mMediaUrl.scheme(), httpScheme)) + { + mResourceType = Http; + } + else if(isEqualNoCase(mMediaUrl.scheme(), httpsScheme)) + { + mResourceType = Https; + } + } + catch(BaseException &e) + { + WarningLog(<< "MediaResourceParticipant::MediaResourceParticipant exception: " << e); + } + catch(...) + { + WarningLog(<< "MediaResourceParticipant::MediaResourceParticipant unknown exception"); + } +} + +MediaResourceParticipant::~MediaResourceParticipant() +{ + // Destroy stream player (if created) + if(mStreamPlayer) + { + mStreamPlayer->removeListener(this); + mStreamPlayer->destroy(); + } + + // unregister from Conversations + // Note: ideally this functionality would exist in Participant Base class - but dynamic_cast required in unregisterParticipant will not work + ConversationMap::iterator it; + for(it = mConversations.begin(); it != mConversations.end(); it++) + { + it->second->unregisterParticipant(this); + } + mConversations.clear(); + + InfoLog(<< "MediaResourceParticipant destroyed, handle=" << mHandle << " url=" << mMediaUrl); +} + +void +MediaResourceParticipant::startPlay() +{ + assert(!mPlaying); + try + { + InfoLog(<< "MediaResourceParticipant playing, handle=" << mHandle << " url=" << mMediaUrl); + + // Common processing + if(mMediaUrl.exists(p_localonly)) + { + mLocalOnly = true; + mMediaUrl.remove(p_localonly); + } + if(mMediaUrl.exists(p_remoteonly)) + { + mRemoteOnly = true; + mMediaUrl.remove(p_remoteonly); + } + if(mMediaUrl.exists(p_duration)) + { + mDurationMs = mMediaUrl.param(p_duration); + mMediaUrl.remove(p_duration); + } + if(mMediaUrl.exists(p_repeat)) + { + mRepeat = true; + mMediaUrl.remove(p_repeat); + } + if(mMediaUrl.exists(p_prefetch)) + { + mPrefetch = true; + mMediaUrl.remove(p_prefetch); + } + + switch(mResourceType) + { + case Tone: + { + int toneid; + if(mMediaUrl.host().size() == 1) + { + toneid = mMediaUrl.host().at(0); + } + else + { + if(isEqualNoCase(mMediaUrl.host(), dialtoneTone)) toneid = DTMF_TONE_DIALTONE; + else if(isEqualNoCase(mMediaUrl.host(), busyTone)) toneid = DTMF_TONE_BUSY; + else if(isEqualNoCase(mMediaUrl.host(), ringbackTone)) toneid = DTMF_TONE_RINGBACK; + else if(isEqualNoCase(mMediaUrl.host(), ringTone)) toneid = DTMF_TONE_RINGTONE; + else if(isEqualNoCase(mMediaUrl.host(), fastbusyTone)) toneid = DTMF_TONE_CALLFAILED; + else if(isEqualNoCase(mMediaUrl.host(), backspaceTone)) toneid = DTMF_TONE_BACKSPACE; + else if(isEqualNoCase(mMediaUrl.host(), callwaitingTone)) toneid = DTMF_TONE_CALLWAITING; + else if(isEqualNoCase(mMediaUrl.host(), holdingTone)) toneid = DTMF_TONE_CALLHELD; + else if(isEqualNoCase(mMediaUrl.host(), loudfastbusyTone)) toneid = DTMF_TONE_LOUD_FAST_BUSY; + else + { + WarningLog(<< "MediaResourceParticipant::startPlay invalid tone identifier: " << mMediaUrl.host()); + return; + } + } + + OsStatus status = getMediaInterface()->getInterface()->startTone(toneid, mRemoteOnly ? FALSE : TRUE /* local */, mLocalOnly ? FALSE : TRUE /* remote */); + if(status == OS_SUCCESS) + { + mPlaying = true; + } + else + { + WarningLog(<< "MediaResourceParticipant::startPlay error calling startTone: " << status); + } + } + break; + case File: + { + Data filepath = mMediaUrl.host().urlDecoded(); + if(filepath.size() > 3 && filepath.substr(0, 3) == Data("///")) filepath = filepath.substr(2); + else if(filepath.size() > 2 && filepath.substr(0, 2) == Data("//")) filepath = filepath.substr(1); + + filepath.replace("|", ":"); // For Windows filepath processing - convert | to : + + InfoLog(<< "MediaResourceParticipant playing, handle=" << mHandle << " filepath=" << filepath); + + OsStatus status = getMediaInterface()->getInterface()->playAudio(filepath.c_str(), + mRepeat ? TRUE: FALSE /* repeast? */, + mRemoteOnly ? FALSE : TRUE /* local */, + mLocalOnly ? FALSE : TRUE /* remote */, + FALSE /* mixWithMic */, + 100 /* downScaling */); + if(status == OS_SUCCESS) + { + mPlaying = true; + } + else + { + WarningLog(<< "MediaResourceParticipant::startPlay error calling playAudio: " << status); + } + } + break; + case Cache: + { + InfoLog(<< "MediaResourceParticipant playing, handle=" << mHandle << " cacheKey=" << mMediaUrl.host()); + + Data *buffer; + int type; + if(mConversationManager.mMediaResourceCache.getFromCache(mMediaUrl.host(), &buffer, &type)) + { + OsStatus status = getMediaInterface()->getInterface()->playBuffer((char*)buffer->data(), + buffer->size(), + 8000, /* rate */ + type, + mRepeat ? TRUE: FALSE /* repeast? */, + mRemoteOnly ? FALSE : TRUE /* local */, + mLocalOnly ? FALSE : TRUE /* remote */, + NULL /* OsProtectedEvent */, + FALSE /* mixWithMic */, + 100 /* downScaling */); + if(status == OS_SUCCESS) + { + mPlaying = true; + } + else + { + WarningLog(<< "MediaResourceParticipant::startPlay error calling playAudio: " << status); + } + } + else + { + WarningLog(<< "MediaResourceParticipant::startPlay media not found in cache, key: " << mMediaUrl.host()); + } + } + break; + case Http: + case Https: + { + int flags; + + if(mLocalOnly) + { + flags = STREAM_SOUND_LOCAL; + } + else if(mRemoteOnly) + { + flags = STREAM_SOUND_REMOTE; + } + else + { + flags = STREAM_SOUND_LOCAL | STREAM_SOUND_REMOTE; + } + OsStatus status = getMediaInterface()->getInterface()->createPlayer(&mStreamPlayer, Data::from(mMediaUrl).c_str(), flags); + if(status == OS_SUCCESS) + { + mStreamPlayer->addListener(this); + status = mStreamPlayer->realize(FALSE /* block? */); + if(status != OS_SUCCESS) + { + WarningLog(<< "MediaResourceParticipant::startPlay error calling StreamPlayer::realize: " << status); + } + else + { + mPlaying = true; + } + } + else + { + WarningLog(<< "MediaResourceParticipant::startPlay error calling createPlayer: " << status); + } + } + break; + case Invalid: + WarningLog(<< "MediaResourceParticipant::startPlay invalid resource type: " << mMediaUrl.scheme()); + break; + } + } + catch(BaseException &e) + { + WarningLog(<< "MediaResourceParticipant::startPlay exception: " << e); + } + catch(...) + { + WarningLog(<< "MediaResourceParticipant::startPlay unknown exception"); + } + + if(mPlaying) // If play started successfully + { + if(mDurationMs > 0) + { + // Start timer to destroy media resource participant automatically + DestroyParticipantCmd destroyer(&mConversationManager, mHandle); + mConversationManager.post(destroyer, mDurationMs); + } + } + else + { + delete this; + } +} + +int +MediaResourceParticipant::getConnectionPortOnBridge() +{ + int connectionPort = -1; + switch(mResourceType) + { + case Tone: + if(mToneGenPortOnBridge == -1) + { + assert(getMediaInterface() != 0); + ((CpTopologyGraphInterface*)getMediaInterface()->getInterface())->getResourceInputPortOnBridge(DEFAULT_TONE_GEN_RESOURCE_NAME,0,mToneGenPortOnBridge); + InfoLog(<< "MediaResourceParticipant getConnectionPortOnBridge, handle=" << mHandle << ", mToneGenPortOnBridge=" << mToneGenPortOnBridge); + } + connectionPort = mToneGenPortOnBridge; + break; + case File: + case Cache: + case Http: + case Https: + if(mFromFilePortOnBridge == -1) + { + assert(getMediaInterface() != 0); + ((CpTopologyGraphInterface*)getMediaInterface()->getInterface())->getResourceInputPortOnBridge(DEFAULT_FROM_FILE_RESOURCE_NAME,0,mFromFilePortOnBridge); + InfoLog(<< "MediaResourceParticipant getConnectionPortOnBridge, handle=" << mHandle << ", mFromFilePortOnBridge=" << mFromFilePortOnBridge); + } + connectionPort = mFromFilePortOnBridge; + break; + case Invalid: + WarningLog(<< "MediaResourceParticipant::getConnectionPortOnBridge invalid resource type: " << mResourceType); + break; + } + return connectionPort; +} + +void +MediaResourceParticipant::destroyParticipant() +{ + bool deleteNow = true; + + if(mDestroying) return; + mDestroying = true; + + if(mPlaying) + { + switch(mResourceType) + { + case Tone: + { + OsStatus status = getMediaInterface()->getInterface()->stopTone(); + if(status != OS_SUCCESS) + { + WarningLog(<< "MediaResourceParticipant::destroyParticipant error calling stopTone: " << status); + } + } + break; + case File: + case Cache: + { + OsStatus status = getMediaInterface()->getInterface()->stopAudio(); + if(status != OS_SUCCESS) + { + WarningLog(<< "MediaResourceParticipant::destroyParticipant error calling stopAudio: " << status); + } + } + break; + case Http: + case Https: + { + mRepeat = false; // Required so that player will not just repeat on stopped event + OsStatus status = mStreamPlayer->stop(); + if(status != OS_SUCCESS) + { + WarningLog(<< "MediaResourceParticipant::destroyParticipant error calling StreamPlayer::stop: " << status); + } + else + { + deleteNow = false; // Wait for play finished event to come in + } + } + break; + case Invalid: + WarningLog(<< "MediaResourceParticipant::destroyParticipant invalid resource type: " << mResourceType); + break; + } + } + if(deleteNow) delete this; +} + +void +MediaResourceParticipant::playerRealized(MpPlayerEvent& event) +{ + InfoLog(<< "MediaResourceParticipant::playerRealized: handle=" << mHandle); + if(mPrefetch) + { + OsStatus status = mStreamPlayer->prefetch(FALSE); + if(status != OS_SUCCESS) + { + WarningLog(<< "MediaResourceParticipant::playerRealized error calling StreamPlayer::prefetch: " << status); + MediaResourceParticipantDeleterCmd* cmd = new MediaResourceParticipantDeleterCmd(mConversationManager, mHandle); + mConversationManager.post(cmd); + } + } + else + { + OsStatus status = mStreamPlayer->play(FALSE /*block?*/); + if(status != OS_SUCCESS) + { + WarningLog(<< "MediaResourceParticipant::playerRealized error calling StreamPlayer::play: " << status); + MediaResourceParticipantDeleterCmd* cmd = new MediaResourceParticipantDeleterCmd(mConversationManager, mHandle); + mConversationManager.post(cmd); + } + } +} + +void +MediaResourceParticipant::playerPrefetched(MpPlayerEvent& event) +{ + InfoLog(<< "MediaResourceParticipant::playerPrefetched: handle=" << mHandle); + OsStatus status = mStreamPlayer->play(FALSE/*block?*/); + if(status != OS_SUCCESS) + { + WarningLog(<< "MediaResourceParticipant::playerPrefetched error calling StreamPlayer::play: " << status); + MediaResourceParticipantDeleterCmd* cmd = new MediaResourceParticipantDeleterCmd(mConversationManager, mHandle); + mConversationManager.post(cmd); + } +} + +void +MediaResourceParticipant::playerPlaying(MpPlayerEvent& event) +{ + InfoLog(<< "MediaResourceParticipant::playerPlaying: handle=" << mHandle); +} + +void +MediaResourceParticipant::playerPaused(MpPlayerEvent& event) +{ + InfoLog(<< "MediaResourceParticipant::playerPaused: handle=" << mHandle); +} + +void +MediaResourceParticipant::playerStopped(MpPlayerEvent& event) +{ + InfoLog(<< "MediaResourceParticipant::playerStopped: handle=" << mHandle); + // We get this event when playing is completed + if(mRepeat) + { + OsStatus status = mStreamPlayer->rewind(FALSE/*block?*/); // Generate playerPrefetched event + if(status != OS_SUCCESS) + { + WarningLog(<< "MediaResourceParticipant::playerStopped error calling StreamPlayer::rewind: " << status); + MediaResourceParticipantDeleterCmd* cmd = new MediaResourceParticipantDeleterCmd(mConversationManager, mHandle); + mConversationManager.post(cmd); + } + } + else + { + MediaResourceParticipantDeleterCmd* cmd = new MediaResourceParticipantDeleterCmd(mConversationManager, mHandle); + mConversationManager.post(cmd); + } +} + +void +MediaResourceParticipant::playerFailed(MpPlayerEvent& event) +{ + InfoLog(<< "MediaResourceParticipant::playerFailed: handle=" << mHandle); + MediaResourceParticipantDeleterCmd* cmd = new MediaResourceParticipantDeleterCmd(mConversationManager, mHandle); + mConversationManager.post(cmd); +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/MediaResourceParticipant.hxx b/src/libs/resiprocate/resip/recon/MediaResourceParticipant.hxx new file mode 100644 index 00000000..3710f458 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MediaResourceParticipant.hxx @@ -0,0 +1,115 @@ +#if !defined(MediaResourceParticipant_hxx) +#define MediaResourceParticipant_hxx + +#include <resip/stack/Uri.hxx> + +#include "ConversationManager.hxx" +#include "Participant.hxx" + +// sipX includes +#include "mp/MpPlayerListener.h" + +class MpStreamPlayer; +class MpPlayerEvent; + +namespace recon +{ +class ConversationManager; + +/** + This class represents a media resource participant. + A media resource participant is a representation of the a playing + audio file or tone. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class MediaResourceParticipant : public Participant, public MpPlayerListener +{ +public: + typedef enum + { + Invalid, + Tone, + File, + Cache, + Http, + Https + } ResourceType; + + MediaResourceParticipant(ParticipantHandle partHandle, + ConversationManager& conversationManager, + const resip::Uri& mediaUrl); + virtual ~MediaResourceParticipant(); + + virtual void startPlay(); + virtual int getConnectionPortOnBridge(); + virtual ResourceType getResourceType() { return mResourceType; } + virtual void destroyParticipant(); + + // For Stream Player callbacks + virtual void playerRealized(MpPlayerEvent& event); + virtual void playerPrefetched(MpPlayerEvent& event); + virtual void playerPlaying(MpPlayerEvent& event); + virtual void playerPaused(MpPlayerEvent& event); + virtual void playerStopped(MpPlayerEvent& event); + virtual void playerFailed(MpPlayerEvent& event); + +protected: + +private: + resip::Uri mMediaUrl; + ResourceType mResourceType; + MpStreamPlayer* mStreamPlayer; + int mToneGenPortOnBridge; + int mFromFilePortOnBridge; + + // Play settings + bool mLocalOnly; + bool mRemoteOnly; + bool mRepeat; + bool mPrefetch; + unsigned int mDurationMs; + + bool mPlaying; + bool mDestroying; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/MediaStreamEvent.cxx b/src/libs/resiprocate/resip/recon/MediaStreamEvent.cxx new file mode 100644 index 00000000..9b26ce3f --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MediaStreamEvent.cxx @@ -0,0 +1,114 @@ +#include "MediaStreamEvent.hxx" + +#include "RemoteParticipantDialogSet.hxx" + +#include <rutil/Logger.hxx> + +using namespace recon; +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +MediaStreamReadyEvent::MediaStreamReadyEvent(RemoteParticipantDialogSet& remoteParticipantDialogSet, + const reTurn::StunTuple& rtpTuple, + const reTurn::StunTuple& rtcpTuple) : + mRemoteParticipantDialogSet(remoteParticipantDialogSet), + mRtpTuple(rtpTuple), + mRtcpTuple(rtcpTuple) +{ +} + +void +MediaStreamReadyEvent::executeCommand() +{ + mRemoteParticipantDialogSet.processMediaStreamReadyEvent(mRtpTuple, mRtcpTuple); +} + +resip::Message* +MediaStreamReadyEvent::clone() const +{ + assert(0); + return 0; +} + +EncodeStream& +MediaStreamReadyEvent::encode(EncodeStream& strm) const +{ + strm << "MediaStreamReadyEvent: rtpTuple: " << mRtpTuple << " rtcpTuple=" << mRtcpTuple; + return strm; +} + +EncodeStream& +MediaStreamReadyEvent::encodeBrief(EncodeStream& strm) const +{ + return encode(strm); +} + + +MediaStreamErrorEvent::MediaStreamErrorEvent(RemoteParticipantDialogSet& remoteParticipantDialogSet, + unsigned int errorCode) : + mRemoteParticipantDialogSet(remoteParticipantDialogSet), + mErrorCode(errorCode) +{ +} + +void +MediaStreamErrorEvent::executeCommand() +{ + mRemoteParticipantDialogSet.processMediaStreamErrorEvent(mErrorCode); +} + +resip::Message* +MediaStreamErrorEvent::clone() const +{ + assert(0); + return 0; +} + +EncodeStream& +MediaStreamErrorEvent::encode(EncodeStream& strm) const +{ + strm << "MediaStreamErrorEvent: errorCode: " << mErrorCode; + return strm; +} + +EncodeStream& +MediaStreamErrorEvent::encodeBrief(EncodeStream& strm) const +{ + return encode(strm); +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/MediaStreamEvent.hxx b/src/libs/resiprocate/resip/recon/MediaStreamEvent.hxx new file mode 100644 index 00000000..171d76b6 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/MediaStreamEvent.hxx @@ -0,0 +1,88 @@ +#if !defined(MediaStreamEvent_hxx) +#define MediaStreamEvent_hxx + +#include "ConversationManager.hxx" + +#include <resip/dum/DumCommand.hxx> +#include <StunTuple.hxx> + +namespace recon +{ + +class RemoteParticipantDialogSet; +class Message; + +/** + This class represents events from the Media stream. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class MediaStreamReadyEvent : public resip::DumCommand +{ + public: + MediaStreamReadyEvent(RemoteParticipantDialogSet& remoteParticipantDialogSet, const reTurn::StunTuple& rtpTuple, const reTurn::StunTuple& rtcpTuple); + virtual void executeCommand(); + + Message* clone() const; + EncodeStream& encode(EncodeStream& strm) const; + EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + RemoteParticipantDialogSet& mRemoteParticipantDialogSet; + reTurn::StunTuple mRtpTuple; + reTurn::StunTuple mRtcpTuple; +}; + +class MediaStreamErrorEvent : public resip::DumCommand +{ + public: + MediaStreamErrorEvent(RemoteParticipantDialogSet& remoteParticipantDialogSet, unsigned int errorCode); + virtual void executeCommand(); + + Message* clone() const; + EncodeStream& encode(EncodeStream& strm) const; + EncodeStream& encodeBrief(EncodeStream& strm) const; + + private: + RemoteParticipantDialogSet& mRemoteParticipantDialogSet; + unsigned int mErrorCode; +}; +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/Participant.cxx b/src/libs/resiprocate/resip/recon/Participant.cxx new file mode 100644 index 00000000..8c61aa2c --- /dev/null +++ b/src/libs/resiprocate/resip/recon/Participant.cxx @@ -0,0 +1,212 @@ +#include "ConversationManager.hxx" +#include "ReconSubsystem.hxx" +#include "Participant.hxx" +#include "Conversation.hxx" +#include "UserAgent.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +Participant::Participant(ParticipantHandle partHandle, + ConversationManager& conversationManager) +: mHandle(partHandle), + mConversationManager(conversationManager) +{ + mConversationManager.registerParticipant(this); + //InfoLog(<< "Participant created, handle=" << mHandle); +} + +Participant::Participant(ConversationManager& conversationManager) +: mHandle(0), + mConversationManager(conversationManager) +{ + setHandle(mConversationManager.getNewParticipantHandle()); + //InfoLog(<< "Participant created, handle=" << mHandle); +} + +Participant::~Participant() +{ + // Note: We cannot call Conversation::unregisterParticipant here, since dynamic_cast in the fn will not work - + // thus unregister must be implemented in sub-classes destructors (see ~LocalParticipant and ~RemoteParticipant) + //InfoLog(<< "Participant destroyed, handle=" << mHandle); + if(mHandle != 0) mConversationManager.onParticipantDestroyed(mHandle); + setHandle(0); // unregister from Conversation Manager +} + +void +Participant::setHandle(ParticipantHandle partHandle) +{ + if(mHandle == partHandle) return; // already set + + // unregister old handle if set + if(mHandle) + { + mConversationManager.unregisterParticipant(this); + } + mHandle = partHandle; + if(mHandle) + { + mConversationManager.registerParticipant(this); + } +} + +void +Participant::addToConversation(Conversation* conversation, unsigned int inputGain, unsigned int outputGain) +{ + assert(conversation); + if(mConversations.find(conversation->getHandle()) != mConversations.end()) return; // already present + + mConversations[conversation->getHandle()] = conversation; + conversation->registerParticipant(this, inputGain, outputGain); +} + +void +Participant::removeFromConversation(Conversation *conversation) +{ + assert(conversation); + //InfoLog(<< "Participant handle=" << mHandle << " removed from conversation=" << conversation->getHandle()); + mConversations.erase(conversation->getHandle()); // Note: this must come before next line - since unregisterParticipant may end up destroying conversation + conversation->unregisterParticipant(this); +} + +void +Participant::copyConversationsToParticipant(Participant* destParticipant) +{ + ConversationMap::iterator it; + for(it = mConversations.begin(); it != mConversations.end(); it++) + { + destParticipant->addToConversation(it->second); // Will over-write our entry in the conversations participant map + } +} + +void +Participant::replaceWithParticipant(Participant* replacingParticipant) +{ + replacingParticipant->setHandle(mHandle); // Set handle on replacing participant + copyConversationsToParticipant(replacingParticipant); // Will over-write our entry in the conversations participant map + Conversation* firstAssociatedConversation=0; + if(mConversations.size() > 0) + { + // If we are running in sipXConversationMediaInterfaceMode, then the call to applyBridgeMixWeights below must be + // passed a conversation pointer, since this participant will not be able to find the appropriate + // BridgeMixer after it's conversation list is cleared. + firstAssociatedConversation = mConversations.begin()->second; + } + mConversations.clear(); // Clear so that we won't remove replaced reference from Conversation + mHandle = 0; // Set to 0 so that we won't remove replaced reference from ConversationManager + assert(mConversationManager.getMediaInterfaceMode() == ConversationManager::sipXGlobalMediaInterfaceMode || // We are either running in sipXGlobalMediaInterfaceMode + firstAssociatedConversation != 0); // or we are running in sipXConversationMediaInterfaceMode and must have belonged to a conversation + applyBridgeMixWeights(firstAssociatedConversation); // Ensure we remove ourselves from the bridge port matrix +} + +SharedPtr<MediaInterface> +Participant::getMediaInterface() +{ + switch(mConversationManager.getMediaInterfaceMode()) + { + case ConversationManager::sipXGlobalMediaInterfaceMode: + assert(mConversationManager.getMediaInterface() != 0); + return mConversationManager.getMediaInterface(); + case ConversationManager::sipXConversationMediaInterfaceMode: + assert(mConversations.size() == 1); + assert(mConversations.begin()->second->getMediaInterface() != 0); + return mConversations.begin()->second->getMediaInterface(); + default: + assert(false); + return SharedPtr<MediaInterface>((MediaInterface*)0); + } +} + +void +Participant::applyBridgeMixWeights() +{ + BridgeMixer* mixer=0; + switch(mConversationManager.getMediaInterfaceMode()) + { + case ConversationManager::sipXGlobalMediaInterfaceMode: + assert(mConversationManager.getBridgeMixer() != 0); + mixer = mConversationManager.getBridgeMixer(); + break; + case ConversationManager::sipXConversationMediaInterfaceMode: + assert(mConversations.size() == 1); + assert(mConversations.begin()->second->getBridgeMixer() != 0); + mixer = mConversations.begin()->second->getBridgeMixer(); + break; + default: + break; + } + assert(mixer); + if(mixer) + { + mixer->calculateMixWeightsForParticipant(this); + } +} + +// Special version of this call used only when a participant +// is removed from a conversation. Required when sipXConversationMediaInterfaceMode +// is used, in order to get a pointer to the bridge mixer +// for a participant (ie. LocalParticipant) that has no currently +// assigned conversations. +void +Participant::applyBridgeMixWeights(Conversation* removedConversation) +{ + BridgeMixer* mixer=0; + switch(mConversationManager.getMediaInterfaceMode()) + { + case ConversationManager::sipXGlobalMediaInterfaceMode: + assert(mConversationManager.getBridgeMixer() != 0); + mixer = mConversationManager.getBridgeMixer(); + break; + case ConversationManager::sipXConversationMediaInterfaceMode: + assert(removedConversation->getBridgeMixer() != 0); + mixer = removedConversation->getBridgeMixer(); + break; + default: + break; + } + assert(mixer); + if(mixer) + { + mixer->calculateMixWeightsForParticipant(this); + } +} + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/Participant.hxx b/src/libs/resiprocate/resip/recon/Participant.hxx new file mode 100644 index 00000000..446c11be --- /dev/null +++ b/src/libs/resiprocate/resip/recon/Participant.hxx @@ -0,0 +1,93 @@ +#if !defined(Participant_hxx) +#define Participant_hxx + +#include "ConversationManager.hxx" +#include <map> + +namespace recon +{ +class ConversationManager; + +/** + This is the base class for a RemoteParticipant, LocalParticipant and a + MediaResourceParticipant. It implements the common functionality of all + participants, such as managing which Conversations that are participant + belongs to. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class Participant +{ + public: + + typedef std::map<ConversationHandle,Conversation*> ConversationMap; + + Participant(ParticipantHandle partHandle, + ConversationManager& conversationManager); + + Participant(ConversationManager& conversationManager); + + virtual ~Participant(); + + virtual ParticipantHandle getParticipantHandle() { return mHandle; } + virtual void addToConversation(Conversation *conversation, unsigned int inputGain = 100, unsigned int outputGain = 100); + virtual void removeFromConversation(Conversation *conversation); + virtual void copyConversationsToParticipant(Participant* destParticipant); + virtual unsigned int getNumConversations() { return (unsigned int)mConversations.size(); } + const ConversationMap& getConversations() { return mConversations; } + + virtual void setHandle(ParticipantHandle partHandle); + virtual void replaceWithParticipant(Participant* replacingParticipant); + + virtual int getConnectionPortOnBridge() = 0; + virtual resip::SharedPtr<MediaInterface> getMediaInterface(); + virtual void applyBridgeMixWeights(); + virtual void applyBridgeMixWeights(Conversation* removedConversation); + + virtual void destroyParticipant() = 0; + + protected: + ParticipantHandle mHandle; + ConversationManager &mConversationManager; + ConversationMap mConversations; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/ReconSubsystem.cxx b/src/libs/resiprocate/resip/recon/ReconSubsystem.cxx new file mode 100644 index 00000000..9609be11 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/ReconSubsystem.cxx @@ -0,0 +1,39 @@ +#include "ReconSubsystem.hxx" + +ReconSubsystem ReconSubsystem::RECON("USERAGENT"); + + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/ReconSubsystem.hxx b/src/libs/resiprocate/resip/recon/ReconSubsystem.hxx new file mode 100644 index 00000000..793e9ad8 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/ReconSubsystem.hxx @@ -0,0 +1,61 @@ +#if !defined(ReconSubsystem_hxx) +#define ReconSubsystem_hxx + +#include <iostream> +#include <rutil/Subsystem.hxx> + +/** + This class is used in the logging subsystem to identify + logging messages generated from the UserAgent library. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class ReconSubsystem : public resip::Subsystem +{ + public: + // Add new systems below + static ReconSubsystem RECON; + + private: + explicit ReconSubsystem(const char* rhs) : resip::Subsystem(rhs) {}; + explicit ReconSubsystem(const resip::Data& rhs); + ReconSubsystem& operator=(const resip::Data& rhs); +}; + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/RelatedConversationSet.cxx b/src/libs/resiprocate/resip/recon/RelatedConversationSet.cxx new file mode 100644 index 00000000..5b1180cc --- /dev/null +++ b/src/libs/resiprocate/resip/recon/RelatedConversationSet.cxx @@ -0,0 +1,83 @@ +#include "Conversation.hxx" +#include "ReconSubsystem.hxx" +#include "RelatedConversationSet.hxx" +#include "Participant.hxx" +#include "LocalParticipant.hxx" +#include "RemoteParticipant.hxx" +#include "UserAgent.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> + +using namespace recon; +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +RelatedConversationSet::RelatedConversationSet(ConversationManager& conversationManager, + ConversationHandle initialConversationHandle, + Conversation* initialConversation) +: mConversationManager(conversationManager), + mInitialConversationHandle(initialConversationHandle) +{ + mRelatedConversationMap[initialConversationHandle] = initialConversation; + + //InfoLog(<< "RelatedConversationSet created, initialConversationHandle=" << mInitialConversationHandle); +} + +RelatedConversationSet::~RelatedConversationSet() +{ + //InfoLog(<< "RelatedConversationSet destroyed, initialConversationHandle=" << mInitialConversationHandle); +} + +void +RelatedConversationSet::addRelatedConversation(ConversationHandle relatedConversationHandle, Conversation* relatedConversation) +{ + mRelatedConversationMap[relatedConversationHandle] = relatedConversation; +} + +void +RelatedConversationSet::removeConversation(ConversationHandle conversationHandle) +{ + mRelatedConversationMap.erase(conversationHandle); + if(mRelatedConversationMap.size() == 0) + { + // No more conversations - destroy self + delete this; + } +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/RelatedConversationSet.hxx b/src/libs/resiprocate/resip/recon/RelatedConversationSet.hxx new file mode 100644 index 00000000..9f2d28cf --- /dev/null +++ b/src/libs/resiprocate/resip/recon/RelatedConversationSet.hxx @@ -0,0 +1,74 @@ +#if !defined(RelatedConversationSet_hxx) +#define RelatedConversationSet_hxx + +#include "ConversationManager.hxx" + +namespace recon +{ +class RemoteParticpant; + +/** + This is used to keep a mapping between all related conversations. + It is currently not used for much, but may prove useful in the + future. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class RelatedConversationSet +{ +public: + // Note: This class is really not used for much right now + RelatedConversationSet(ConversationManager& conversationManager, + ConversationHandle initialConversationHandle, + Conversation* initialConversation); + ~RelatedConversationSet(); + + void addRelatedConversation(ConversationHandle relatedConversationHandle, Conversation* relatedConversation); + void removeConversation(ConversationHandle conversationHandle); + +private: + ConversationManager& mConversationManager; + ConversationHandle mInitialConversationHandle; // only for logging + typedef std::map<ConversationHandle, Conversation *> RelatedConversationMap; + RelatedConversationMap mRelatedConversationMap; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/RemoteParticipant.cxx b/src/libs/resiprocate/resip/recon/RemoteParticipant.cxx new file mode 100644 index 00000000..c9161633 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/RemoteParticipant.cxx @@ -0,0 +1,2466 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ConversationManager.hxx" + +#include "sdp/SdpHelperResip.hxx" +#include "sdp/Sdp.hxx" + +#include <sdp/SdpCodec.h> // sipX SdpCodec + +#include "RemoteParticipant.hxx" +#include "Conversation.hxx" +#include "UserAgent.hxx" +#include "DtmfEvent.hxx" +#include "ReconSubsystem.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/Random.hxx> +#include <resip/stack/SipFrag.hxx> +#include <resip/stack/ExtensionHeader.hxx> +#include <resip/dum/DialogUsageManager.hxx> +#include <resip/dum/ClientInviteSession.hxx> +#include <resip/dum/ServerInviteSession.hxx> +#include <resip/dum/ClientSubscription.hxx> +#include <resip/dum/ServerOutOfDialogReq.hxx> +#include <resip/dum/ServerSubscription.hxx> + +#include <rutil/WinLeakCheck.hxx> + +using namespace recon; +using namespace sdpcontainer; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +// UAC +RemoteParticipant::RemoteParticipant(ParticipantHandle partHandle, + ConversationManager& conversationManager, + DialogUsageManager& dum, + RemoteParticipantDialogSet& remoteParticipantDialogSet) +: Participant(partHandle, conversationManager), + AppDialog(dum), + mDum(dum), + mDialogSet(remoteParticipantDialogSet), + mDialogId(Data::Empty, Data::Empty, Data::Empty), + mState(Connecting), + mOfferRequired(false), + mLocalHold(true), + mRemoteHold(false), + mLocalSdp(0), + mRemoteSdp(0) +{ + InfoLog(<< "RemoteParticipant created (UAC), handle=" << mHandle); +} + +// UAS - or forked leg +RemoteParticipant::RemoteParticipant(ConversationManager& conversationManager, + DialogUsageManager& dum, + RemoteParticipantDialogSet& remoteParticipantDialogSet) +: Participant(conversationManager), + AppDialog(dum), + mDum(dum), + mDialogSet(remoteParticipantDialogSet), + mDialogId(Data::Empty, Data::Empty, Data::Empty), + mState(Connecting), + mOfferRequired(false), + mLocalHold(true), + mLocalSdp(0), + mRemoteSdp(0) +{ + InfoLog(<< "RemoteParticipant created (UAS or forked leg), handle=" << mHandle); +} + +RemoteParticipant::~RemoteParticipant() +{ + if(!mDialogId.getCallId().empty()) + { + mDialogSet.removeDialog(mDialogId); + } + // unregister from Conversations + // Note: ideally this functionality would exist in Participant Base class - but dynamic_cast required in unregisterParticipant will not work + ConversationMap::iterator it; + for(it = mConversations.begin(); it != mConversations.end(); it++) + { + it->second->unregisterParticipant(this); + } + mConversations.clear(); + + // Delete Sdp memory + if(mLocalSdp) delete mLocalSdp; + if(mRemoteSdp) delete mRemoteSdp; + + InfoLog(<< "RemoteParticipant destroyed, handle=" << mHandle); +} + +unsigned int +RemoteParticipant::getLocalRTPPort() +{ + return mDialogSet.getLocalRTPPort(); +} + +//static const resip::ExtensionHeader h_AlertInfo("Alert-Info"); + +void +RemoteParticipant::initiateRemoteCall(const NameAddr& destination) +{ + SdpContents offer; + SharedPtr<ConversationProfile> profile = mConversationManager.getUserAgent()->getDefaultOutgoingConversationProfile(); + buildSdpOffer(mLocalHold, offer); + SharedPtr<SipMessage> invitemsg = mDum.makeInviteSession( + destination, + profile, + &offer, + &mDialogSet); + + mDialogSet.sendInvite(invitemsg); + + // Clear any pending hold/unhold requests since our offer/answer here will handle it + if(mPendingRequest.mType == Hold || + mPendingRequest.mType == Unhold) + { + mPendingRequest.mType = None; + } + + // Adjust RTP streams + adjustRTPStreams(true); + + // Special case of this call - since call in addToConversation will not work, since we didn't know our bridge port at that time + applyBridgeMixWeights(); +} + +int +RemoteParticipant::getConnectionPortOnBridge() +{ + if(mDialogSet.getActiveRemoteParticipantHandle() == mHandle) + { + return mDialogSet.getConnectionPortOnBridge(); + } + else + { + // If this is not active fork leg, then we don't want to effect the bridge mixer. + // Note: All forked endpoints/participants have the same connection port on the bridge + return -1; + } +} + +int +RemoteParticipant::getMediaConnectionId() +{ + return mDialogSet.getMediaConnectionId(); +} + +void +RemoteParticipant::destroyParticipant() +{ + try + { + if(mState != Terminating) + { + stateTransition(Terminating); + if(mInviteSessionHandle.isValid()) + { + mInviteSessionHandle->end(); + } + else + { + mDialogSet.end(); + } + } + } + catch(BaseException &e) + { + WarningLog(<< "RemoteParticipant::destroyParticipant exception: " << e); + } + catch(...) + { + WarningLog(<< "RemoteParticipant::destroyParticipant unknown exception"); + } +} + +void +RemoteParticipant::addToConversation(Conversation* conversation, unsigned int inputGain, unsigned int outputGain) +{ + Participant::addToConversation(conversation, inputGain, outputGain); + if(mLocalHold && !conversation->shouldHold()) // If we are on hold and we now shouldn't be, then unhold + { + unhold(); + } +} + +void +RemoteParticipant::removeFromConversation(Conversation *conversation) +{ + Participant::removeFromConversation(conversation); + checkHoldCondition(); +} + +void +RemoteParticipant::checkHoldCondition() +{ + // Return to Offer a hold sdp if we are not in any conversations, or all the conversations we are in have conditions such that a hold is required + bool shouldHold = true; + ConversationMap::iterator it; + for(it = mConversations.begin(); it != mConversations.end(); it++) + { + if(!it->second->shouldHold()) + { + shouldHold = false; + break; + } + } + if(mLocalHold != shouldHold) + { + if(shouldHold) + { + hold(); + } + else + { + unhold(); + } + } +} + +void +RemoteParticipant::stateTransition(State state) +{ + Data stateName; + + switch(state) + { + case Connecting: + stateName = "Connecting"; break; + case Accepted: + stateName = "Accepted"; break; + case Connected: + stateName = "Connected"; break; + case Redirecting: + stateName = "Redirecting"; break; + case Holding: + stateName = "Holding"; break; + case Unholding: + stateName = "Unholding"; break; + case Replacing: + stateName = "Replacing"; break; + case PendingOODRefer: + stateName = "PendingOODRefer"; break; + case Terminating: + stateName = "Terminating"; break; + default: + stateName = "Unknown: " + Data(state); break; + } + InfoLog( << "RemoteParticipant::stateTransition of handle=" << mHandle << " to state=" << stateName ); + mState = state; + + if(mState == Connected && mPendingRequest.mType != None) + { + PendingRequestType type = mPendingRequest.mType; + mPendingRequest.mType = None; + switch(type) + { + case Hold: + hold(); + break; + case Unhold: + unhold(); + break; + case Redirect: + redirect(mPendingRequest.mDestination); + break; + case RedirectTo: + redirectToParticipant(mPendingRequest.mDestInviteSessionHandle); + break; + case None: + break; + } + } +} + +void +RemoteParticipant::accept() +{ + try + { + // Accept SIP call if required + if(mState == Connecting && mInviteSessionHandle.isValid()) + { + ServerInviteSession* sis = dynamic_cast<ServerInviteSession*>(mInviteSessionHandle.get()); + if(sis && !sis->isAccepted()) + { + if(getLocalRTPPort() == 0) + { + WarningLog(<< "RemoteParticipant::accept cannot accept call, since no free RTP ports, rejecting instead."); + sis->reject(480); // Temporarily Unavailable - no free RTP ports + return; + } + // Clear any pending hold/unhold requests since our offer/answer here will handle it + if(mPendingRequest.mType == Hold || + mPendingRequest.mType == Unhold) + { + mPendingRequest.mType = None; + } + if(mOfferRequired) + { + provideOffer(true /* postOfferAccept */); + } + else if(mPendingOffer.get() != 0) + { + provideAnswer(*mPendingOffer.get(), true /* postAnswerAccept */, false /* postAnswerAlert */); + } + else + { + // It is possible to get here if the app calls alert with early true. There is special logic in + // RemoteParticipantDialogSet::accept to handle the case then an alert call followed immediately by + // accept. In this case the answer from the alert will be queued waiting on the flow to be ready, and + // we need to ensure the accept call is also delayed until the answer completes. + mDialogSet.accept(mInviteSessionHandle); + } + stateTransition(Accepted); + } + } + // Accept Pending OOD Refer if required + else if(mState == PendingOODRefer) + { + acceptPendingOODRefer(); + } + else + { + WarningLog(<< "RemoteParticipant::accept called in invalid state: " << mState); + } + } + catch(BaseException &e) + { + WarningLog(<< "RemoteParticipant::accept exception: " << e); + } + catch(...) + { + WarningLog(<< "RemoteParticipant::accept unknown exception"); + } +} + +void +RemoteParticipant::alert(bool earlyFlag) +{ + try + { + if(mState == Connecting && mInviteSessionHandle.isValid()) + { + ServerInviteSession* sis = dynamic_cast<ServerInviteSession*>(mInviteSessionHandle.get()); + if(sis && !sis->isAccepted()) + { + if(earlyFlag && mPendingOffer.get() != 0) + { + if(getLocalRTPPort() == 0) + { + WarningLog(<< "RemoteParticipant::alert cannot alert call with early media, since no free RTP ports, rejecting instead."); + sis->reject(480); // Temporarily Unavailable - no free RTP ports + return; + } + + provideAnswer(*mPendingOffer.get(), false /* postAnswerAccept */, true /* postAnswerAlert */); + mPendingOffer.release(); + } + else + { + sis->provisional(180, earlyFlag); + } + } + } + else + { + WarningLog(<< "RemoteParticipant::alert called in invalid state: " << mState); + } + } + catch(BaseException &e) + { + WarningLog(<< "RemoteParticipant::alert exception: " << e); + } + catch(...) + { + WarningLog(<< "RemoteParticipant::alert unknown exception"); + } +} + +void +RemoteParticipant::reject(unsigned int rejectCode) +{ + try + { + // Reject UAS Invite Session if required + if(mState == Connecting && mInviteSessionHandle.isValid()) + { + ServerInviteSession* sis = dynamic_cast<ServerInviteSession*>(mInviteSessionHandle.get()); + if(sis && !sis->isAccepted()) + { + sis->reject(rejectCode); + } + } + // Reject Pending OOD Refer request if required + else if(mState == PendingOODRefer) + { + rejectPendingOODRefer(rejectCode); + } + else + { + WarningLog(<< "RemoteParticipant::reject called in invalid state: " << mState); + } + } + catch(BaseException &e) + { + WarningLog(<< "RemoteParticipant::reject exception: " << e); + } + catch(...) + { + WarningLog(<< "RemoteParticipant::reject unknown exception"); + } +} + +void +RemoteParticipant::redirect(NameAddr& destination) +{ + try + { + if(mPendingRequest.mType == None) + { + if((mState == Connecting || mState == Accepted || mState == Connected) && mInviteSessionHandle.isValid()) + { + ServerInviteSession* sis = dynamic_cast<ServerInviteSession*>(mInviteSessionHandle.get()); + // If this is a UAS session and we haven't sent a final response yet - then redirect via 302 response + if(sis && !sis->isAccepted() && mState == Connecting) + { + NameAddrs destinations; + destinations.push_back(destination); + mConversationManager.onParticipantRedirectSuccess(mHandle); + sis->redirect(destinations); + } + else if(mInviteSessionHandle->isConnected()) // redirect via blind transfer + { + mInviteSessionHandle->refer(NameAddr(destination.uri()) /* remove tags */, true /* refersub */); + stateTransition(Redirecting); + } + else + { + mPendingRequest.mType = Redirect; + mPendingRequest.mDestination = destination; + } + } + else if(mState == PendingOODRefer) + { + redirectPendingOODRefer(destination); + } + else + { + mPendingRequest.mType = Redirect; + mPendingRequest.mDestination = destination; + } + } + else + { + WarningLog(<< "RemoteParticipant::redirect error: request pending"); + mConversationManager.onParticipantRedirectFailure(mHandle, 406 /* Not Acceptable */); + } + } + catch(BaseException &e) + { + WarningLog(<< "RemoteParticipant::redirect exception: " << e); + } + catch(...) + { + WarningLog(<< "RemoteParticipant::redirect unknown exception"); + } +} + +void +RemoteParticipant::redirectToParticipant(InviteSessionHandle& destParticipantInviteSessionHandle) +{ + try + { + if(destParticipantInviteSessionHandle.isValid()) + { + if(mPendingRequest.mType == None) + { + if((mState == Connecting || mState == Accepted || mState == Connected) && mInviteSessionHandle.isValid()) + { + ServerInviteSession* sis = dynamic_cast<ServerInviteSession*>(mInviteSessionHandle.get()); + // If this is a UAS session and we haven't sent a final response yet - then redirect via 302 response + if(sis && !sis->isAccepted() && mState == Connecting) + { + NameAddrs destinations; + destinations.push_back(NameAddr(destParticipantInviteSessionHandle->peerAddr().uri())); // ensure we don't get to or from tag by only using the inner uri() + mConversationManager.onParticipantRedirectSuccess(mHandle); + sis->redirect(destinations); + } + else if(mInviteSessionHandle->isConnected()) // redirect via attended transfer (with replaces) + { + mInviteSessionHandle->refer(NameAddr(destParticipantInviteSessionHandle->peerAddr().uri()) /* remove tags */, destParticipantInviteSessionHandle /* session to replace) */, true /* refersub */); + stateTransition(Redirecting); + } + else + { + mPendingRequest.mType = RedirectTo; + mPendingRequest.mDestInviteSessionHandle = destParticipantInviteSessionHandle; + } + } + else + { + mPendingRequest.mType = RedirectTo; + mPendingRequest.mDestInviteSessionHandle = destParticipantInviteSessionHandle; + } + } + else + { + WarningLog(<< "RemoteParticipant::redirectToParticipant error: request pending"); + mConversationManager.onParticipantRedirectFailure(mHandle, 406 /* Not Acceptable */); + } + } + else + { + WarningLog(<< "RemoteParticipant::redirectToParticipant error: destParticipant has no valid InviteSession"); + mConversationManager.onParticipantRedirectFailure(mHandle, 406 /* Not Acceptable */); + } + } + catch(BaseException &e) + { + WarningLog(<< "RemoteParticipant::redirectToParticipant exception: " << e); + } + catch(...) + { + WarningLog(<< "RemoteParticipant::redirectToParticipant unknown exception"); + } +} + +void +RemoteParticipant::hold() +{ + mLocalHold=true; + + InfoLog(<< "RemoteParticipant::hold request: handle=" << mHandle); + + try + { + if(mPendingRequest.mType == None) + { + if(mState == Connected && mInviteSessionHandle.isValid()) + { + provideOffer(false /* postOfferAccept */); + stateTransition(Holding); + } + else + { + mPendingRequest.mType = Hold; + } + } + else if(mPendingRequest.mType == Unhold) + { + mPendingRequest.mType = None; // Unhold pending, so move to do nothing + return; + } + else if(mPendingRequest.mType == Hold) + { + return; // Hold already pending + } + else + { + WarningLog(<< "RemoteParticipant::hold error: request already pending"); + } + } + catch(BaseException &e) + { + WarningLog(<< "RemoteParticipant::hold exception: " << e); + } + catch(...) + { + WarningLog(<< "RemoteParticipant::hold unknown exception"); + } +} + +void +RemoteParticipant::unhold() +{ + mLocalHold=false; + + InfoLog(<< "RemoteParticipant::unhold request: handle=" << mHandle); + + try + { + if(mPendingRequest.mType == None) + { + if(mState == Connected && mInviteSessionHandle.isValid()) + { + provideOffer(false /* postOfferAccept */); + stateTransition(Unholding); + } + else + { + mPendingRequest.mType = Unhold; + } + } + else if(mPendingRequest.mType == Hold) + { + mPendingRequest.mType = None; // Hold pending, so move do nothing + return; + } + else if(mPendingRequest.mType == Unhold) + { + return; // Unhold already pending + } + else + { + WarningLog(<< "RemoteParticipant::unhold error: request already pending"); + } + } + catch(BaseException &e) + { + WarningLog(<< "RemoteParticipant::unhold exception: " << e); + } + catch(...) + { + WarningLog(<< "RemoteParticipant::unhold unknown exception"); + } +} + +void +RemoteParticipant::setPendingOODReferInfo(ServerOutOfDialogReqHandle ood, const SipMessage& referMsg) +{ + stateTransition(PendingOODRefer); + mPendingOODReferMsg = referMsg; + mPendingOODReferNoSubHandle = ood; +} + +void +RemoteParticipant::setPendingOODReferInfo(ServerSubscriptionHandle ss, const SipMessage& referMsg) +{ + stateTransition(PendingOODRefer); + mPendingOODReferMsg = referMsg; + mPendingOODReferSubHandle = ss; +} + +void +RemoteParticipant::acceptPendingOODRefer() +{ + if(mState == PendingOODRefer) + { + SharedPtr<UserProfile> profile; + bool accepted = false; + if(mPendingOODReferNoSubHandle.isValid()) + { + mPendingOODReferNoSubHandle->send(mPendingOODReferNoSubHandle->accept(202)); // Accept OOD Refer + profile = mPendingOODReferNoSubHandle->getUserProfile(); + accepted = true; + } + else if(mPendingOODReferSubHandle.isValid()) + { + mPendingOODReferSubHandle->send(mPendingOODReferSubHandle->accept(202)); // Accept OOD Refer + profile = mPendingOODReferSubHandle->getUserProfile(); + accepted = true; + } + if(accepted) + { + // Create offer + SdpContents offer; + buildSdpOffer(mLocalHold, offer); + + // Build the Invite + SharedPtr<SipMessage> invitemsg = mDum.makeInviteSessionFromRefer(mPendingOODReferMsg, + profile, + mPendingOODReferSubHandle, // Note will be invalid if refer no-sub, which is fine + &offer, + DialogUsageManager::None, //EncryptionLevel + 0, //Aleternative Contents + &mDialogSet); + mDialogSet.sendInvite(invitemsg); + + adjustRTPStreams(true); + + stateTransition(Connecting); + } + else + { + WarningLog(<< "acceptPendingOODRefer - no valid handles"); + mConversationManager.onParticipantTerminated(mHandle, 500); + delete this; + } + } +} + +void +RemoteParticipant::rejectPendingOODRefer(unsigned int statusCode) +{ + if(mState == PendingOODRefer) + { + if(mPendingOODReferNoSubHandle.isValid()) + { + mPendingOODReferNoSubHandle->send(mPendingOODReferNoSubHandle->reject(statusCode)); + mConversationManager.onParticipantTerminated(mHandle, statusCode); + } + else if(mPendingOODReferSubHandle.isValid()) + { + mPendingOODReferSubHandle->send(mPendingOODReferSubHandle->reject(statusCode)); + mConversationManager.onParticipantTerminated(mHandle, statusCode); + } + else + { + WarningLog(<< "rejectPendingOODRefer - no valid handles"); + mConversationManager.onParticipantTerminated(mHandle, 500); + } + mDialogSet.destroy(); // Will also cause "this" to be deleted + } +} + +void +RemoteParticipant::redirectPendingOODRefer(resip::NameAddr& destination) +{ + if(mState == PendingOODRefer) + { + if(mPendingOODReferNoSubHandle.isValid()) + { + SharedPtr<SipMessage> redirect = mPendingOODReferNoSubHandle->reject(302 /* Moved Temporarily */); + redirect->header(h_Contacts).clear(); + redirect->header(h_Contacts).push_back(destination); + mPendingOODReferNoSubHandle->send(redirect); + mConversationManager.onParticipantTerminated(mHandle, 302 /* Moved Temporarily */); + } + else if(mPendingOODReferSubHandle.isValid()) + { + SharedPtr<SipMessage> redirect = mPendingOODReferSubHandle->reject(302 /* Moved Temporarily */); + redirect->header(h_Contacts).clear(); + redirect->header(h_Contacts).push_back(destination); + mPendingOODReferSubHandle->send(redirect); + mConversationManager.onParticipantTerminated(mHandle, 302 /* Moved Temporarily */); + } + else + { + WarningLog(<< "rejectPendingOODRefer - no valid handles"); + mConversationManager.onParticipantTerminated(mHandle, 500); + } + mDialogSet.destroy(); // Will also cause "this" to be deleted + } +} + +void +RemoteParticipant::processReferNotify(const SipMessage& notify) +{ + unsigned int code = 400; // Bad Request - default if for some reason a valid sipfrag is not present + + SipFrag* frag = dynamic_cast<SipFrag*>(notify.getContents()); + if (frag) + { + // Get StatusCode from SipFrag + if (frag->message().isResponse()) + { + code = frag->message().header(h_StatusLine).statusCode(); + } + } + + // Check if success or failure response code was in SipFrag + if(code >= 200 && code < 300) + { + if(mState == Redirecting) + { + if (mHandle) mConversationManager.onParticipantRedirectSuccess(mHandle); + stateTransition(Connected); + } + } + else if(code >= 300) + { + if(mState == Redirecting) + { + if (mHandle) mConversationManager.onParticipantRedirectFailure(mHandle, code); + stateTransition(Connected); + } + } +} + +void +RemoteParticipant::provideOffer(bool postOfferAccept) +{ + std::auto_ptr<SdpContents> offer(new SdpContents); + assert(mInviteSessionHandle.isValid()); + + buildSdpOffer(mLocalHold, *offer); + + mDialogSet.provideOffer(offer, mInviteSessionHandle, postOfferAccept); + mOfferRequired = false; +} + +bool +RemoteParticipant::provideAnswer(const SdpContents& offer, bool postAnswerAccept, bool postAnswerAlert) +{ + auto_ptr<SdpContents> answer(new SdpContents); + assert(mInviteSessionHandle.isValid()); + bool answerOk = buildSdpAnswer(offer, *answer); + + if(answerOk) + { + mDialogSet.provideAnswer(answer, mInviteSessionHandle, postAnswerAccept, postAnswerAlert); + } + else + { + mInviteSessionHandle->reject(488); + } + + return answerOk; +} + +void +RemoteParticipant::buildSdpOffer(bool holdSdp, SdpContents& offer) +{ + SdpContents::Session::Medium *audioMedium = 0; + ConversationProfile *profile = dynamic_cast<ConversationProfile*>(mDialogSet.getUserProfile().get()); + if(!profile) // This can happen for UAC calls + { + profile = mConversationManager.getUserAgent()->getDefaultOutgoingConversationProfile().get(); + } + + // If we already have a local sdp for this sesion, then use this to form the next offer - doing so will ensure + // that we do not switch codecs or payload id's mid session. + if(mInviteSessionHandle.isValid() && mInviteSessionHandle->getLocalSdp().session().media().size() != 0) + { + offer = mInviteSessionHandle->getLocalSdp(); + + // Set sessionid and version for this sdp + UInt64 currentTime = Timer::getTimeMicroSec(); + offer.session().origin().getSessionId() = currentTime; + offer.session().origin().getVersion() = currentTime; + + // Find the audio medium + for (std::list<SdpContents::Session::Medium>::iterator mediaIt = offer.session().media().begin(); + mediaIt != offer.session().media().end(); mediaIt++) + { + if(mediaIt->name() == "audio" && + (mediaIt->protocol() == Symbols::RTP_AVP || + mediaIt->protocol() == Symbols::RTP_SAVP || + mediaIt->protocol() == Symbols::UDP_TLS_RTP_SAVP)) + { + audioMedium = &(*mediaIt); + break; + } + } + assert(audioMedium); + + // Add any codecs from our capabilities that may not be in current local sdp - since endpoint may have changed and may now be capable + // of handling codecs that it previously could not (common when endpoint is a B2BUA). + + SdpContents& sessionCaps = dynamic_cast<ConversationProfile*>(mDialogSet.getUserProfile().get())->sessionCaps(); + int highPayloadId = 96; // Note: static payload id's are in range of 0-96 + // Iterate through codecs in session caps and check if already in offer + for (std::list<SdpContents::Session::Codec>::iterator codecsIt = sessionCaps.session().media().front().codecs().begin(); + codecsIt != sessionCaps.session().media().front().codecs().end(); codecsIt++) + { + bool found=false; + bool payloadIdCollision=false; + for (std::list<SdpContents::Session::Codec>::iterator codecsIt2 = audioMedium->codecs().begin(); + codecsIt2 != audioMedium->codecs().end(); codecsIt2++) + { + if(isEqualNoCase(codecsIt->getName(), codecsIt2->getName()) && + codecsIt->getRate() == codecsIt2->getRate()) + { + found = true; + } + else if(codecsIt->payloadType() == codecsIt2->payloadType()) + { + payloadIdCollision = true; + } + // Keep track of highest payload id in offer - used if we need to resolve a payload id conflict + if(codecsIt2->payloadType() > highPayloadId) + { + highPayloadId = codecsIt2->payloadType(); + } + } + if(!found) + { + if(payloadIdCollision) + { + highPayloadId++; + codecsIt->payloadType() = highPayloadId; + } + else if(codecsIt->payloadType() > highPayloadId) + { + highPayloadId = codecsIt->payloadType(); + } + audioMedium->addCodec(*codecsIt); + } + } + } + else + { + // Build base offer + mConversationManager.buildSdpOffer(profile, offer); + + // Assumes there is only 1 media stream in session caps and it the audio one + audioMedium = &offer.session().media().front(); + assert(audioMedium); + + // Set the local RTP Port + audioMedium->port() = mDialogSet.getLocalRTPPort(); + } + + // Add Crypto attributes (if required) - assumes there is only 1 media stream + audioMedium->clearAttribute("crypto"); + audioMedium->clearAttribute("encryption"); + audioMedium->clearAttribute("tcap"); + audioMedium->clearAttribute("pcfg"); + offer.session().clearAttribute("fingerprint"); + offer.session().clearAttribute("setup"); + if(mDialogSet.getSecureMediaMode() == ConversationProfile::Srtp) + { + // Note: We could add the crypto attribute to the "SDP Capabilties Negotiation" + // potential configuration if secure media is not required - but other implementations + // should ignore them any way if just plain RTP is used. It is thought the + // current implementation will increase interopability. (ie. SNOM Phones) + + Data crypto; + + switch(mDialogSet.getSrtpCryptoSuite()) + { + case flowmanager::MediaStream::SRTP_AES_CM_128_HMAC_SHA1_32: + crypto = "1 AES_CM_128_HMAC_SHA1_32 inline:" + mDialogSet.getLocalSrtpSessionKey().base64encode(); + audioMedium->addAttribute("crypto", crypto); + crypto = "2 AES_CM_128_HMAC_SHA1_80 inline:" + mDialogSet.getLocalSrtpSessionKey().base64encode(); + audioMedium->addAttribute("crypto", crypto); + break; + default: + crypto = "1 AES_CM_128_HMAC_SHA1_80 inline:" + mDialogSet.getLocalSrtpSessionKey().base64encode(); + audioMedium->addAttribute("crypto", crypto); + crypto = "2 AES_CM_128_HMAC_SHA1_32 inline:" + mDialogSet.getLocalSrtpSessionKey().base64encode(); + audioMedium->addAttribute("crypto", crypto); + break; + } + if(mDialogSet.getSecureMediaRequired()) + { + audioMedium->protocol() = Symbols::RTP_SAVP; + } + else + { + audioMedium->protocol() = Symbols::RTP_AVP; + audioMedium->addAttribute("encryption", "optional"); // Used by SNOM phones? + audioMedium->addAttribute("tcap", "1 RTP/SAVP"); // draft-ietf-mmusic-sdp-capability-negotiation-08 + audioMedium->addAttribute("pcfg", "1 t=1"); + } + } +#ifdef USE_SSL + else if(mDialogSet.getSecureMediaMode() == ConversationProfile::SrtpDtls) + { + if(mConversationManager.getFlowManager().getDtlsFactory()) + { + // Note: We could add the fingerprint and setup attributes to the "SDP Capabilties Negotiation" + // potential configuration if secure media is not required - but other implementations + // should ignore them any way if just plain RTP is used. It is thought the + // current implementation will increase interopability. + + // Add fingerprint attribute + char fingerprint[100]; + mConversationManager.getFlowManager().getDtlsFactory()->getMyCertFingerprint(fingerprint); + offer.session().addAttribute("fingerprint", "SHA-1 " + Data(fingerprint)); + //offer.session().addAttribute("acap", "1 fingerprint:SHA-1 " + Data(fingerprint)); + + // Add setup attribute + offer.session().addAttribute("setup", "actpass"); + + if(mDialogSet.getSecureMediaRequired()) + { + audioMedium->protocol() = Symbols::UDP_TLS_RTP_SAVP; + } + else + { + audioMedium->protocol() = Symbols::RTP_AVP; + audioMedium->addAttribute("tcap", "1 UDP/TLS/RTP/SAVP"); // draft-ietf-mmusic-sdp-capability-negotiation-08 + audioMedium->addAttribute("pcfg", "1 t=1"); + //audioMedium->addAttribute("pcfg", "1 t=1 a=1"); + } + } + } +#endif + + audioMedium->clearAttribute("sendrecv"); + audioMedium->clearAttribute("sendonly"); + audioMedium->clearAttribute("recvonly"); + audioMedium->clearAttribute("inactive"); + + if(holdSdp) + { + if(mRemoteHold) + { + audioMedium->addAttribute("inactive"); + } + else + { + audioMedium->addAttribute("sendonly"); + } + } + else + { + if(mRemoteHold) + { + audioMedium->addAttribute("recvonly"); + } + else + { + audioMedium->addAttribute("sendrecv"); + } + } + setProposedSdp(offer); +} + +bool +RemoteParticipant::answerMediaLine(SdpContents::Session::Medium& mediaSessionCaps, const SdpMediaLine& sdpMediaLine, SdpContents& answer, bool potential) +{ + SdpMediaLine::SdpTransportProtocolType protocolType = sdpMediaLine.getTransportProtocolType(); + bool valid = false; + + // If this is a valid audio medium then process it + if(sdpMediaLine.getMediaType() == SdpMediaLine::MEDIA_TYPE_AUDIO && + (protocolType == SdpMediaLine::PROTOCOL_TYPE_RTP_AVP || + protocolType == SdpMediaLine::PROTOCOL_TYPE_RTP_SAVP || + protocolType == SdpMediaLine::PROTOCOL_TYPE_UDP_TLS_RTP_SAVP) && + sdpMediaLine.getConnections().size() != 0 && + sdpMediaLine.getConnections().front().getPort() != 0) + { + SdpContents::Session::Medium medium("audio", getLocalRTPPort(), 1, + protocolType == SdpMediaLine::PROTOCOL_TYPE_RTP_SAVP ? Symbols::RTP_SAVP : + (protocolType == SdpMediaLine::PROTOCOL_TYPE_UDP_TLS_RTP_SAVP ? Symbols::UDP_TLS_RTP_SAVP : + Symbols::RTP_AVP)); + + // Check secure media properties and requirements + bool secureMediaRequired = mDialogSet.getSecureMediaRequired() || protocolType != SdpMediaLine::PROTOCOL_TYPE_RTP_AVP; + + if(mDialogSet.getSecureMediaMode() == ConversationProfile::Srtp || + protocolType == SdpMediaLine::PROTOCOL_TYPE_RTP_SAVP) // allow accepting of SAVP profiles, even if SRTP is not enabled as a SecureMedia mode + { + bool supportedCryptoSuite = false; + SdpMediaLine::CryptoList::const_iterator itCrypto = sdpMediaLine.getCryptos().begin(); + for(; !supportedCryptoSuite && itCrypto!=sdpMediaLine.getCryptos().end(); itCrypto++) + { + Data cryptoKeyB64(itCrypto->getCryptoKeyParams().front().getKeyValue()); + Data cryptoKey = cryptoKeyB64.base64decode(); + + if(cryptoKey.size() == SRTP_MASTER_KEY_LEN) + { + switch(itCrypto->getSuite()) + { + case SdpMediaLine::CRYPTO_SUITE_TYPE_AES_CM_128_HMAC_SHA1_80: + medium.addAttribute("crypto", Data(itCrypto->getTag()) + " AES_CM_128_HMAC_SHA1_80 inline:" + mDialogSet.getLocalSrtpSessionKey().base64encode()); + supportedCryptoSuite = true; + break; + case SdpMediaLine::CRYPTO_SUITE_TYPE_AES_CM_128_HMAC_SHA1_32: + medium.addAttribute("crypto", Data(itCrypto->getTag()) + " AES_CM_128_HMAC_SHA1_32 inline:" + mDialogSet.getLocalSrtpSessionKey().base64encode()); + supportedCryptoSuite = true; + break; + default: + break; + } + } + else + { + InfoLog(<< "SDES crypto key found in SDP, but is not of correct length after base 64 decode: " << cryptoKey.size()); + } + } + if(!supportedCryptoSuite && secureMediaRequired) + { + InfoLog(<< "Secure media stream is required, but there is no supported crypto attributes in the offer - skipping this stream..."); + return false; + } + } +#ifdef USE_SSL + else if(mConversationManager.getFlowManager().getDtlsFactory() && + (mDialogSet.getSecureMediaMode() == ConversationProfile::SrtpDtls || + protocolType == SdpMediaLine::PROTOCOL_TYPE_UDP_TLS_RTP_SAVP)) // allow accepting of DTLS SAVP profiles, even if DTLS-SRTP is not enabled as a SecureMedia mode + { + bool supportedFingerprint = false; + + // We will only process Dtls-Srtp if fingerprint is in SHA-1 format + if(sdpMediaLine.getFingerPrintHashFunction() == SdpMediaLine::FINGERPRINT_HASH_FUNC_SHA_1) + { + answer.session().clearAttribute("fingerprint"); // ensure we don't add these twice + answer.session().clearAttribute("setup"); // ensure we don't add these twice + + // Add fingerprint attribute to answer + char fingerprint[100]; + mConversationManager.getFlowManager().getDtlsFactory()->getMyCertFingerprint(fingerprint); + answer.session().addAttribute("fingerprint", "SHA-1 " + Data(fingerprint)); + + // Add setup attribute + if(sdpMediaLine.getTcpSetupAttribute() == SdpMediaLine::TCP_SETUP_ATTRIBUTE_ACTIVE) + { + answer.session().addAttribute("setup", "passive"); + } + else + { + answer.session().addAttribute("setup", "active"); + } + + supportedFingerprint = true; + } + if(!supportedFingerprint && secureMediaRequired) + { + InfoLog(<< "Secure media stream is required, but there is no supported fingerprint attributes in the offer - skipping this stream..."); + return false; + } + } +#endif + + if(potential && !sdpMediaLine.getPotentialMediaViewString().empty()) + { + medium.addAttribute("acfg", sdpMediaLine.getPotentialMediaViewString()); + } + + // Iterate through codecs and look for supported codecs - tag found ones by storing their payload id + SdpMediaLine::CodecList::const_iterator itCodec = sdpMediaLine.getCodecs().begin(); + for(; itCodec != sdpMediaLine.getCodecs().end(); itCodec++) + { + std::list<SdpContents::Session::Codec>::iterator bestCapsCodecMatchIt = mediaSessionCaps.codecs().end(); + bool modeInOffer = itCodec->getFormatParameters().prefix("mode="); + + // Loop through allowed codec list and see if codec is supported locally + for (std::list<SdpContents::Session::Codec>::iterator capsCodecsIt = mediaSessionCaps.codecs().begin(); + capsCodecsIt != mediaSessionCaps.codecs().end(); capsCodecsIt++) + { + if(isEqualNoCase(capsCodecsIt->getName(), itCodec->getMimeSubtype()) && + (unsigned int)capsCodecsIt->getRate() == itCodec->getRate()) + { + bool modeInCaps = capsCodecsIt->parameters().prefix("mode="); + if(!modeInOffer && !modeInCaps) + { + // If mode is not specified in either - then we have a match + bestCapsCodecMatchIt = capsCodecsIt; + break; + } + else if(modeInOffer && modeInCaps) + { + if(isEqualNoCase(capsCodecsIt->parameters(), itCodec->getFormatParameters())) + { + bestCapsCodecMatchIt = capsCodecsIt; + break; + } + // If mode is specified in both, and doesn't match - then we have no match + } + else + { + // Mode is specified on either offer or caps - this match is a potential candidate + // As a rule - use first match of this kind only + if(bestCapsCodecMatchIt == mediaSessionCaps.codecs().end()) + { + bestCapsCodecMatchIt = capsCodecsIt; + } + } + } + } + + if(bestCapsCodecMatchIt != mediaSessionCaps.codecs().end()) + { + SdpContents::Session::Codec codec(*bestCapsCodecMatchIt); + codec.payloadType() = itCodec->getPayloadType(); // honour offered payload id - just to be nice :) + medium.addCodec(codec); + if(!valid && !isEqualNoCase(bestCapsCodecMatchIt->getName(), "telephone-event")) + { + // Consider offer valid if we see any matching codec other than telephone-event + valid = true; + } + } + } + + if(valid) + { + // copy ptime attribute from session caps (if exists) + if(mediaSessionCaps.exists("ptime")) + { + medium.addAttribute("ptime", mediaSessionCaps.getValues("ptime").front()); + } + + // Check requested direction + unsigned int remoteRtpPort = sdpMediaLine.getConnections().front().getPort(); + if(sdpMediaLine.getDirection() == SdpMediaLine::DIRECTION_TYPE_INACTIVE || + (mLocalHold && (sdpMediaLine.getDirection() == SdpMediaLine::DIRECTION_TYPE_SENDONLY || remoteRtpPort == 0))) // If remote inactive or both sides are holding + { + medium.addAttribute("inactive"); + } + else if(sdpMediaLine.getDirection() == SdpMediaLine::DIRECTION_TYPE_SENDONLY || remoteRtpPort == 0 /* old RFC 2543 hold */) + { + medium.addAttribute("recvonly"); + } + else if(sdpMediaLine.getDirection() == SdpMediaLine::DIRECTION_TYPE_RECVONLY || mLocalHold) + { + medium.addAttribute("sendonly"); + } + else + { + // Note: sendrecv is the default in SDP + medium.addAttribute("sendrecv"); + } + answer.session().addMedium(medium); + } + } + return valid; +} + +bool +RemoteParticipant::buildSdpAnswer(const SdpContents& offer, SdpContents& answer) +{ + // Note: this implementation has minimal support for draft-ietf-mmusic-sdp-capabilities-negotiation + // for responding "best-effort" / optional SRTP (Dtls-SRTP) offers + + bool valid = false; + Sdp* remoteSdp = SdpHelperResip::createSdpFromResipSdp(offer); + + try + { + // copy over session capabilities + answer = dynamic_cast<ConversationProfile*>(mDialogSet.getUserProfile().get())->sessionCaps(); + + // Set sessionid and version for this answer + UInt64 currentTime = Timer::getTimeMicroSec(); + answer.session().origin().getSessionId() = currentTime; + answer.session().origin().getVersion() = currentTime; + + // Set local port in answer + // for now we only allow 1 audio media + assert(answer.session().media().size() == 1); + SdpContents::Session::Medium& mediaSessionCaps = dynamic_cast<ConversationProfile*>(mDialogSet.getUserProfile().get())->sessionCaps().session().media().front(); + assert(mediaSessionCaps.name() == "audio"); + assert(mediaSessionCaps.codecs().size() > 0); + + // Copy t= field from sdp (RFC3264) + assert(answer.session().getTimes().size() > 0); + if(offer.session().getTimes().size() >= 1) + { + answer.session().getTimes().clear(); + answer.session().addTime(offer.session().getTimes().front()); + } + + // Clear out m= lines in answer then populate below + answer.session().media().clear(); + + // Loop through each offered m= line and provide a response + Sdp::MediaLineList::const_iterator itMediaLine = remoteSdp->getMediaLines().begin(); + for(; itMediaLine != remoteSdp->getMediaLines().end(); itMediaLine++) + { + bool mediaLineValid = false; + + // We only process one media stream - so if we already have a valid - just reject the rest + if(valid) + { + SdpContents::Session::Medium rejmedium((*itMediaLine)->getMediaTypeString(), 0, 1, // Reject medium by specifying port 0 (RFC3264) + (*itMediaLine)->getTransportProtocolTypeString()); + if((*itMediaLine)->getCodecs().size() > 0) + { + rejmedium.addCodec(SdpContents::Session::Codec((*itMediaLine)->getCodecs().front().getMimeSubtype(), + (*itMediaLine)->getCodecs().front().getRate(), + (*itMediaLine)->getCodecs().front().getFormatParameters())); + rejmedium.codecs().front().payloadType() = (*itMediaLine)->getCodecs().front().getPayloadType(); + } + answer.session().addMedium(rejmedium); + continue; + } + + // Give preference to potential configuration first - if there are any + SdpMediaLine::SdpMediaLineList::const_iterator itPotentialMediaLine = (*itMediaLine)->getPotentialMediaViews().begin(); + for(; itPotentialMediaLine != (*itMediaLine)->getPotentialMediaViews().end(); itPotentialMediaLine++) + { + mediaLineValid = answerMediaLine(mediaSessionCaps, *itPotentialMediaLine, answer, true); + if(mediaLineValid) + { + // We have a valid potential media - line - copy over normal media line to make + // further processing easier + *(*itMediaLine) = *itPotentialMediaLine; + valid = true; + break; + } + } + if(!mediaLineValid) + { + // Process SDP normally + mediaLineValid = answerMediaLine(mediaSessionCaps, *(*itMediaLine), answer, false); + if(!mediaLineValid) + { + SdpContents::Session::Medium rejmedium((*itMediaLine)->getMediaTypeString(), 0, 1, // Reject medium by specifying port 0 (RFC3264) + (*itMediaLine)->getTransportProtocolTypeString()); + if((*itMediaLine)->getCodecs().size() > 0) + { + rejmedium.addCodec(SdpContents::Session::Codec((*itMediaLine)->getCodecs().front().getMimeSubtype(), + (*itMediaLine)->getCodecs().front().getRate(), + (*itMediaLine)->getCodecs().front().getFormatParameters())); + rejmedium.codecs().front().payloadType() = (*itMediaLine)->getCodecs().front().getPayloadType(); + } + answer.session().addMedium(rejmedium); + } + else + { + valid = true; + } + } + } // end loop through m= offers + } + catch(BaseException &e) + { + WarningLog( << "buildSdpAnswer: exception parsing SDP offer: " << e.getMessage()); + valid = false; + } + catch(...) + { + WarningLog( << "buildSdpAnswer: unknown exception parsing SDP offer"); + valid = false; + } + + //InfoLog( << "SDPOffer: " << offer); + //InfoLog( << "SDPAnswer: " << answer); + if(valid) + { + setLocalSdp(answer); + setRemoteSdp(offer, remoteSdp); + } + else + { + delete remoteSdp; + } + return valid; +} + +#ifdef OLD_CODE +// Note: This old code used to serve 2 purposes - +// 1 - that we do not change payload id's mid session +// 2 - that we do not add codecs or media streams that have previously rejected +// Purpose 2 is not correct. RFC3264 states we need purpose 1, but you are allowed to add new codecs mid-session +// +// Decision to comment out this code and implement purpose 1 elsewhere - leaving this code here for reference (for now) +// as it may be useful for something in the future. +bool +RemoteParticipant::formMidDialogSdpOfferOrAnswer(const SdpContents& localSdp, const SdpContents& remoteSdp, SdpContents& newSdp, bool offer) +{ + bool valid = false; + + try + { + // start with current localSdp + newSdp = localSdp; + + // Clear all m= lines are rebuild + newSdp.session().media().clear(); + + // Set sessionid and version for this sdp + UInt64 currentTime = Timer::getTimeMicroSec(); + newSdp.session().origin().getSessionId() = currentTime; + newSdp.session().origin().getVersion() = currentTime; + + // Loop through each m= line in local Sdp and remove or disable if not in remote + for (std::list<SdpContents::Session::Medium>::const_iterator localMediaIt = localSdp.session().media().begin(); + localMediaIt != localSdp.session().media().end(); localMediaIt++) + { + for (std::list<SdpContents::Session::Medium>::const_iterator remoteMediaIt = remoteSdp.session().media().begin(); + remoteMediaIt != remoteSdp.session().media().end(); remoteMediaIt++) + { + if(localMediaIt->name() == remoteMediaIt->name() && localMediaIt->protocol() == remoteMediaIt->protocol()) + { + // Found an m= line match, proceed to process codecs + SdpContents::Session::Medium medium(localMediaIt->name(), localMediaIt->port(), localMediaIt->multicast(), localMediaIt->protocol()); + + // Iterate through local codecs and look for remote supported codecs + for (std::list<SdpContents::Session::Codec>::const_iterator localCodecsIt = localMediaIt->codecs().begin(); + localCodecsIt != localMediaIt->codecs().end(); localCodecsIt++) + { + // Loop through remote supported codec list and see if codec is supported + for (std::list<SdpContents::Session::Codec>::const_iterator remoteCodecsIt = remoteMediaIt->codecs().begin(); + remoteCodecsIt != remoteMediaIt->codecs().end(); remoteCodecsIt++) + { + if(isEqualNoCase(localCodecsIt->getName(), remoteCodecsIt->getName()) && + localCodecsIt->getRate() == remoteCodecsIt->getRate()) + { + // matching supported codec found - add to newSdp + medium.addCodec(*localCodecsIt); + if(!valid && !isEqualNoCase(localCodecsIt->getName(), "telephone-event")) + { + // Consider valid if we see any matching codec other than telephone-event + valid = true; + } + break; + } + } + } + + // copy ptime attribute from session caps (if exists) + if(localMediaIt->exists("ptime")) + { + medium.addAttribute("ptime", localMediaIt->getValues("ptime").front()); + } + + if(offer) + { + if(mLocalHold) + { + if(remoteMediaIt->exists("inactive") || + remoteMediaIt->exists("sendonly") || + remoteMediaIt->port() == 0) // If remote inactive or both sides are holding + { + medium.addAttribute("inactive"); + } + else + { + medium.addAttribute("sendonly"); + } + } + else + { + if(remoteMediaIt->exists("inactive") || remoteMediaIt->exists("sendonly") || remoteMediaIt->port() == 0 /* old RFC 2543 hold */) + { + medium.addAttribute("recvonly"); + } + else + { + medium.addAttribute("sendrecv"); + } + } + } + else // This is an sdp answer + { + // Check requested direction + if(remoteMediaIt->exists("inactive") || + (mLocalHold && (remoteMediaIt->exists("sendonly") || remoteMediaIt->port() == 0))) // If remote inactive or both sides are holding + { + medium.addAttribute("inactive"); + } + else if(remoteMediaIt->exists("sendonly") || remoteMediaIt->port() == 0 /* old RFC 2543 hold */) + { + medium.addAttribute("recvonly"); + } + else if(remoteMediaIt->exists("recvonly") || mLocalHold) + { + medium.addAttribute("sendonly"); + } + else + { + // Note: sendrecv is the default in SDP + medium.addAttribute("sendrecv"); + } + } + + newSdp.session().addMedium(medium); + break; + } + } + } + } + catch(BaseException &e) + { + WarningLog( << "formMidDialogSdpOfferOrAnswer: exception: " << e.getMessage()); + valid = false; + } + catch(...) + { + WarningLog( << "formMidDialogSdpOfferOrAnswer: unknown exception"); + valid = false; + } + + return valid; +} +#endif + +void +RemoteParticipant::destroyConversations() +{ + ConversationMap temp = mConversations; // Copy since we may end up being destroyed + ConversationMap::iterator it; + for(it = temp.begin(); it != temp.end(); it++) + { + it->second->destroy(); + } +} + +void +RemoteParticipant::setProposedSdp(const resip::SdpContents& sdp) +{ + mDialogSet.setProposedSdp(mHandle, sdp); +} + +void +RemoteParticipant::setLocalSdp(const resip::SdpContents& sdp) +{ + if(mLocalSdp) delete mLocalSdp; + mLocalSdp = 0; + InfoLog(<< "setLocalSdp: handle=" << mHandle << ", localSdp=" << sdp); + mLocalSdp = SdpHelperResip::createSdpFromResipSdp(sdp); +} + +void +RemoteParticipant::setRemoteSdp(const resip::SdpContents& sdp, bool answer) +{ + if(mRemoteSdp) delete mRemoteSdp; + mRemoteSdp = 0; + InfoLog(<< "setRemoteSdp: handle=" << mHandle << ", remoteSdp=" << sdp); + mRemoteSdp = SdpHelperResip::createSdpFromResipSdp(sdp); + if(answer && mDialogSet.getProposedSdp()) + { + if(mLocalSdp) delete mLocalSdp; + mLocalSdp = new sdpcontainer::Sdp(*mDialogSet.getProposedSdp()); // copied + } +} + +void +RemoteParticipant::setRemoteSdp(const resip::SdpContents& sdp, Sdp* remoteSdp) // Note: sdp only passed for logging purposes +{ + if(mRemoteSdp) delete mRemoteSdp; + InfoLog(<< "setRemoteSdp: handle=" << mHandle << ", remoteSdp=" << sdp); + mRemoteSdp = remoteSdp; +} + +void +RemoteParticipant::adjustRTPStreams(bool sendingOffer) +{ + //if(mHandle) mConversationManager.onParticipantMediaUpdate(mHandle, localSdp, remoteSdp); + int mediaDirection = SdpMediaLine::DIRECTION_TYPE_INACTIVE; + Data remoteIPAddress; + unsigned int remoteRtpPort=0; + unsigned int remoteRtcpPort=0; + Sdp *localSdp = sendingOffer ? mDialogSet.getProposedSdp() : mLocalSdp; + Sdp *remoteSdp = sendingOffer ? 0 : mRemoteSdp; + const SdpMediaLine::CodecList* localCodecs; + const SdpMediaLine::CodecList* remoteCodecs; + bool supportedCryptoSuite = false; + bool supportedFingerprint = false; + + assert(localSdp); + + /* + InfoLog(<< "adjustRTPStreams: handle=" << mHandle << ", localSdp=" << localSdp); + if(remoteSdp) + { + InfoLog(<< "adjustRTPStreams: handle=" << mHandle << ", remoteSdp=" << *remoteSdp); + }*/ + + int localMediaDirection = SdpMediaLine::DIRECTION_TYPE_INACTIVE; + + Sdp::MediaLineList::const_iterator itMediaLine = localSdp->getMediaLines().begin(); + for(; itMediaLine != localSdp->getMediaLines().end(); itMediaLine++) + { + DebugLog(<< "adjustRTPStreams: handle=" << mHandle << + ", found media line in local sdp, mediaType=" << SdpMediaLine::SdpMediaTypeString[(*itMediaLine)->getMediaType()] << + ", transportType=" << SdpMediaLine::SdpTransportProtocolTypeString[(*itMediaLine)->getTransportProtocolType()] << + ", numConnections=" << (*itMediaLine)->getConnections().size() << + ", port=" << ((*itMediaLine)->getConnections().size() > 0 ? (*itMediaLine)->getConnections().front().getPort() : 0)); + if((*itMediaLine)->getMediaType() == SdpMediaLine::MEDIA_TYPE_AUDIO && + ((*itMediaLine)->getTransportProtocolType() == SdpMediaLine::PROTOCOL_TYPE_RTP_AVP || + (*itMediaLine)->getTransportProtocolType() == SdpMediaLine::PROTOCOL_TYPE_RTP_SAVP || + (*itMediaLine)->getTransportProtocolType() == SdpMediaLine::PROTOCOL_TYPE_UDP_TLS_RTP_SAVP) && + (*itMediaLine)->getConnections().size() != 0 && + (*itMediaLine)->getConnections().front().getPort() != 0) + { + //InfoLog(<< "adjustRTPStreams: handle=" << mHandle << ", found audio media line in local sdp"); + localMediaDirection = (*itMediaLine)->getDirection(); + localCodecs = &(*itMediaLine)->getCodecs(); + break; + } + } + + if(remoteSdp) + { + int remoteMediaDirection = SdpMediaLine::DIRECTION_TYPE_INACTIVE; + + Sdp::MediaLineList::const_iterator itRemMediaLine = remoteSdp->getMediaLines().begin(); + for(; itRemMediaLine != remoteSdp->getMediaLines().end(); itRemMediaLine++) + { + //InfoLog(<< "adjustRTPStreams: handle=" << mHandle << ", found media line in remote sdp"); + if((*itRemMediaLine)->getMediaType() == SdpMediaLine::MEDIA_TYPE_AUDIO && + ((*itRemMediaLine)->getTransportProtocolType() == SdpMediaLine::PROTOCOL_TYPE_RTP_AVP || + (*itRemMediaLine)->getTransportProtocolType() == SdpMediaLine::PROTOCOL_TYPE_RTP_SAVP || + (*itRemMediaLine)->getTransportProtocolType() == SdpMediaLine::PROTOCOL_TYPE_UDP_TLS_RTP_SAVP) && + (*itRemMediaLine)->getConnections().size() != 0 && + (*itRemMediaLine)->getConnections().front().getPort() != 0) + { + //InfoLog(<< "adjustRTPStreams: handle=" << mHandle << ", found audio media line in remote sdp"); + remoteMediaDirection = (*itRemMediaLine)->getDirection(); + remoteRtpPort = (*itRemMediaLine)->getConnections().front().getPort(); + remoteRtcpPort = (*itRemMediaLine)->getRtcpConnections().front().getPort(); + remoteIPAddress = (*itRemMediaLine)->getConnections().front().getAddress(); + remoteCodecs = &(*itRemMediaLine)->getCodecs(); + + // Process Crypto settings (if required) - createSRTPSession using remote key + // Note: Top crypto in remote sdp will always be the correct suite/key + if(mDialogSet.getSecureMediaMode() == ConversationProfile::Srtp || + (*itRemMediaLine)->getTransportProtocolType() == SdpMediaLine::PROTOCOL_TYPE_RTP_SAVP) + { + SdpMediaLine::CryptoList::const_iterator itCrypto = (*itRemMediaLine)->getCryptos().begin(); + for(; itCrypto != (*itRemMediaLine)->getCryptos().end(); itCrypto++) + { + Data cryptoKeyB64(itCrypto->getCryptoKeyParams().front().getKeyValue()); + Data cryptoKey = cryptoKeyB64.base64decode(); + + if(cryptoKey.size() == SRTP_MASTER_KEY_LEN) + { + switch(itCrypto->getSuite()) + { + case SdpMediaLine::CRYPTO_SUITE_TYPE_AES_CM_128_HMAC_SHA1_80: + mDialogSet.createSRTPSession(flowmanager::MediaStream::SRTP_AES_CM_128_HMAC_SHA1_80, cryptoKey.data(), cryptoKey.size()); + supportedCryptoSuite = true; + break; + case SdpMediaLine::CRYPTO_SUITE_TYPE_AES_CM_128_HMAC_SHA1_32: + mDialogSet.createSRTPSession(flowmanager::MediaStream::SRTP_AES_CM_128_HMAC_SHA1_32, cryptoKey.data(), cryptoKey.size()); + supportedCryptoSuite = true; + break; + default: + break; + } + } + else + { + InfoLog(<< "SDES crypto key found in SDP, but is not of correct length after base 64 decode: " << cryptoKey.size()); + } + if(supportedCryptoSuite) + { + break; + } + } + } + // Process Fingerprint and setup settings (if required) + else if((*itRemMediaLine)->getTransportProtocolType() == SdpMediaLine::PROTOCOL_TYPE_UDP_TLS_RTP_SAVP) + { + // We will only process Dtls-Srtp if fingerprint is in SHA-1 format + if((*itRemMediaLine)->getFingerPrintHashFunction() == SdpMediaLine::FINGERPRINT_HASH_FUNC_SHA_1) + { + if(!(*itRemMediaLine)->getFingerPrint().empty()) + { + InfoLog(<< "Fingerprint retrieved from remote SDP: " << (*itRemMediaLine)->getFingerPrint()); + // ensure we only accept media streams with this fingerprint + mDialogSet.setRemoteSDPFingerprint((*itRemMediaLine)->getFingerPrint()); + + // If remote setup value is not active then we must be the Dtls client - ensure client DtlsSocket is create + if((*itRemMediaLine)->getTcpSetupAttribute() != SdpMediaLine::TCP_SETUP_ATTRIBUTE_ACTIVE) + { + // If we are the active end, then kick start the DTLS handshake + mDialogSet.startDtlsClient(remoteIPAddress.c_str(), remoteRtpPort, remoteRtcpPort); + } + + supportedFingerprint = true; + } + } + else if((*itRemMediaLine)->getFingerPrintHashFunction() != SdpMediaLine::FINGERPRINT_HASH_FUNC_NONE) + { + InfoLog(<< "Fingerprint found, but is not using SHA-1 hash."); + } + } + + break; + } + } + + if(remoteMediaDirection == SdpMediaLine::DIRECTION_TYPE_INACTIVE || + remoteMediaDirection == SdpMediaLine::DIRECTION_TYPE_SENDONLY) + { + mRemoteHold = true; + } + else + { + mRemoteHold = false; + } + + // Check if any conversations are broadcast only - if so, then we need to send media to parties on hold + bool broadcastOnly = false; + ConversationMap::iterator it; + for(it = mConversations.begin(); it != mConversations.end(); it++) + { + if(it->second->broadcastOnly()) + { + broadcastOnly = true; + break; + } + } + + // Aggregate local and remote direction attributes to determine overall media direction + if((mLocalHold && !broadcastOnly) || + localMediaDirection == SdpMediaLine::DIRECTION_TYPE_INACTIVE || + remoteMediaDirection == SdpMediaLine::DIRECTION_TYPE_INACTIVE) + { + mediaDirection = SdpMediaLine::DIRECTION_TYPE_INACTIVE; + } + else if(localMediaDirection == SdpMediaLine::DIRECTION_TYPE_SENDONLY) + { + mediaDirection = SdpMediaLine::DIRECTION_TYPE_SENDONLY; + } + else if(localMediaDirection == SdpMediaLine::DIRECTION_TYPE_RECVONLY) + { + mediaDirection = SdpMediaLine::DIRECTION_TYPE_RECVONLY; + } + else if(remoteMediaDirection == SdpMediaLine::DIRECTION_TYPE_SENDONLY) + { + mediaDirection = SdpMediaLine::DIRECTION_TYPE_RECVONLY; + } + else if(remoteMediaDirection == SdpMediaLine::DIRECTION_TYPE_SENDONLY) + { + mediaDirection = SdpMediaLine::DIRECTION_TYPE_RECVONLY; + } + else + { + mediaDirection = SdpMediaLine::DIRECTION_TYPE_SENDRECV; + } + } + else + { + // No remote SDP info - so put direction into receive only mode (unless inactive) + if(mLocalHold || + localMediaDirection == SdpMediaLine::DIRECTION_TYPE_INACTIVE || + localMediaDirection == SdpMediaLine::DIRECTION_TYPE_SENDONLY) + { + mediaDirection = SdpMediaLine::DIRECTION_TYPE_INACTIVE; + } + else + { + mediaDirection = SdpMediaLine::DIRECTION_TYPE_RECVONLY; + } + } + + if(remoteSdp && mDialogSet.getSecureMediaRequired() && !supportedCryptoSuite && !supportedFingerprint) + { + InfoLog(<< "Secure media is required and no valid support found in remote sdp - ending call."); + destroyParticipant(); + return; + } + + InfoLog(<< "adjustRTPStreams: handle=" << mHandle << ", mediaDirection=" << SdpMediaLine::SdpDirectionTypeString[mediaDirection] << ", remoteIp=" << remoteIPAddress << ", remotePort=" << remoteRtpPort); + + if(!remoteIPAddress.empty() && remoteRtpPort != 0) + { + mDialogSet.setActiveDestination(remoteIPAddress.c_str(), remoteRtpPort, remoteRtcpPort); + } + + if((mediaDirection == SdpMediaLine::DIRECTION_TYPE_SENDRECV || + mediaDirection == SdpMediaLine::DIRECTION_TYPE_SENDONLY) && + !remoteIPAddress.empty() && remoteRtpPort != 0 && + remoteCodecs && localCodecs) + { + // Calculate intersection of local and remote codecs, and pass remote codecs that exist locally to RTP send fn + int numCodecs=0; + ::SdpCodec** codecs = new ::SdpCodec*[remoteCodecs->size()]; + SdpMediaLine::CodecList::const_iterator itRemoteCodec = remoteCodecs->begin(); + for(; itRemoteCodec != remoteCodecs->end(); itRemoteCodec++) + { + bool modeInRemote = itRemoteCodec->getFormatParameters().prefix("mode="); + SdpMediaLine::CodecList::const_iterator bestCapsCodecMatchIt = localCodecs->end(); + SdpMediaLine::CodecList::const_iterator itLocalCodec = localCodecs->begin(); + for(; itLocalCodec != localCodecs->end(); itLocalCodec++) + { + if(isEqualNoCase(itRemoteCodec->getMimeSubtype(), itLocalCodec->getMimeSubtype()) && + itRemoteCodec->getRate() == itLocalCodec->getRate()) + { + bool modeInLocal = itLocalCodec->getFormatParameters().prefix("mode="); + if(!modeInLocal && !modeInRemote) + { + // If mode is not specified in either - then we have a match + bestCapsCodecMatchIt = itLocalCodec; + break; + } + else if(modeInLocal && modeInRemote) + { + if(isEqualNoCase(itRemoteCodec->getFormatParameters(), itLocalCodec->getFormatParameters())) + { + bestCapsCodecMatchIt = itLocalCodec; + break; + } + // If mode is specified in both, and doesn't match - then we have no match + } + else + { + // Mode is specified on either offer or caps - this match is a potential candidate + // As a rule - use first match of this kind only + if(bestCapsCodecMatchIt == localCodecs->end()) + { + bestCapsCodecMatchIt = itLocalCodec; + } + } + } + } + if(bestCapsCodecMatchIt != localCodecs->end()) + { + codecs[numCodecs++] = new ::SdpCodec(itRemoteCodec->getPayloadType(), + itRemoteCodec->getMimeType().c_str(), + itRemoteCodec->getMimeSubtype().c_str(), + itRemoteCodec->getRate(), + itRemoteCodec->getPacketTime(), + itRemoteCodec->getNumChannels(), + itRemoteCodec->getFormatParameters().c_str()); + + UtlString codecString; + codecs[numCodecs-1]->toString(codecString); + + InfoLog(<< "adjustRTPStreams: handle=" << mHandle << ", sending to destination address " << remoteIPAddress << ":" << + remoteRtpPort << " (RTCP on " << remoteRtcpPort << "): " << codecString.data()); + } + } + + if(numCodecs > 0) + { + getMediaInterface()->getInterface()->startRtpSend(mDialogSet.getMediaConnectionId(), numCodecs, codecs); + } + else + { + WarningLog(<< "adjustRTPStreams: handle=" << mHandle << ", something went wrong during SDP negotiations, no common codec found."); + } + for(int i = 0; i < numCodecs; i++) + { + delete codecs[i]; + } + delete [] codecs; + } + else + { + if(getMediaInterface()->getInterface()->isSendingRtpAudio(mDialogSet.getMediaConnectionId())) + { + getMediaInterface()->getInterface()->stopRtpSend(mDialogSet.getMediaConnectionId()); + } + InfoLog(<< "adjustRTPStreams: handle=" << mHandle << ", stop sending."); + } + + if(mediaDirection == SdpMediaLine::DIRECTION_TYPE_SENDRECV || + mediaDirection == SdpMediaLine::DIRECTION_TYPE_RECVONLY) + { + if(!getMediaInterface()->getInterface()->isReceivingRtpAudio(mDialogSet.getMediaConnectionId())) + { + // !SLG! - we could make this better, no need to recalculate this every time + // We are always willing to receive any of our locally supported codecs + int numCodecs=0; + ::SdpCodec** codecs = new ::SdpCodec*[localCodecs->size()]; + SdpMediaLine::CodecList::const_iterator itLocalCodec = localCodecs->begin(); + for(; itLocalCodec != localCodecs->end(); itLocalCodec++) + { + codecs[numCodecs++] = new ::SdpCodec(itLocalCodec->getPayloadType(), + itLocalCodec->getMimeType().c_str(), + itLocalCodec->getMimeSubtype().c_str(), + itLocalCodec->getRate(), + itLocalCodec->getPacketTime(), + itLocalCodec->getNumChannels(), + itLocalCodec->getFormatParameters().c_str()); + UtlString codecString; + codecs[numCodecs-1]->toString(codecString); + InfoLog(<< "adjustRTPStreams: handle=" << mHandle << ", receving: " << codecString.data()); + } + + getMediaInterface()->getInterface()->startRtpReceive(mDialogSet.getMediaConnectionId(), numCodecs, codecs); + for(int i = 0; i < numCodecs; i++) + { + delete codecs[i]; + } + delete [] codecs; + } + InfoLog(<< "adjustRTPStreams: handle=" << mHandle << ", receiving..."); + } + else + { + // Never stop receiving - keep reading buffers and let mixing matrix handle supression of audio output + //if(getMediaInterface()->getInterface()->isReceivingRtpAudio(mDialogSet.getMediaConnectionId())) + //{ + // getMediaInterface()->getInterface()->stopRtpReceive(mDialogSet.getMediaConnectionId()); + //} + InfoLog(<< "adjustRTPStreams: handle=" << mHandle << ", stop receiving (mLocalHold=" << mLocalHold << ")."); + } +} + +void +RemoteParticipant::replaceWithParticipant(RemoteParticipant* replacingParticipant) +{ + // Copy our local hold setting to the replacing participant to replace us + replacingParticipant->mLocalHold = mLocalHold; + + // We are about to adjust the participant handle of the replacing participant to ours + // ensure that the mapping is also adjusted in the replacing participants dialog set + if(replacingParticipant->mHandle == replacingParticipant->mDialogSet.getActiveRemoteParticipantHandle()) + { + replacingParticipant->mDialogSet.setActiveRemoteParticipantHandle(mHandle); + } + + Participant::replaceWithParticipant(replacingParticipant); +} + +void +RemoteParticipant::onDtmfEvent(int dtmf, int duration, bool up) +{ + if(mHandle) mConversationManager.onDtmfEvent(mHandle, dtmf, duration, up); +} + +void +RemoteParticipant::onNewSession(ClientInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg) +{ + InfoLog(<< "onNewSession(Client): handle=" << mHandle << ", " << msg.brief()); + mInviteSessionHandle = h->getSessionHandle(); + mDialogId = getDialogId(); +} + +void +RemoteParticipant::onNewSession(ServerInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg) +{ + InfoLog(<< "onNewSession(Server): handle=" << mHandle << ", " << msg.brief()); + + mInviteSessionHandle = h->getSessionHandle(); + mDialogId = getDialogId(); + + // First check if this INVITE is to replace an existing session + if(msg.exists(h_Replaces)) + { + pair<InviteSessionHandle, int> presult; + presult = mDum.findInviteSession(msg.header(h_Replaces)); + if(!(presult.first == InviteSessionHandle::NotValid())) + { + RemoteParticipant* participantToReplace = dynamic_cast<RemoteParticipant *>(presult.first->getAppDialog().get()); + InfoLog(<< "onNewSession(Server): handle=" << mHandle << ", to replace handle=" << participantToReplace->getParticipantHandle() << ", " << msg.brief()); + + // Assume Participant Handle of old call + participantToReplace->replaceWithParticipant(this); // adjust conversation mappings + + // Session to replace was found - end old session and flag to auto-answer this session after SDP offer-answer is complete + participantToReplace->destroyParticipant(); + stateTransition(Replacing); + return; + } + } + + // Check for Auto-Answer indication - support draft-ietf-answer-mode-01 + // and Answer-After parameter of Call-Info header + ConversationProfile* profile = dynamic_cast<ConversationProfile*>(h->getUserProfile().get()); + assert(profile); + bool autoAnswerRequired; + bool autoAnswer = profile->shouldAutoAnswer(msg, &autoAnswerRequired); + if(!autoAnswer && autoAnswerRequired) // If we can't autoAnswer but it was required, we must reject the call + { + WarningCategory warning; + warning.hostname() = DnsUtil::getLocalHostName(); + warning.code() = 399; /* Misc. */ + warning.text() = "automatic answer forbidden"; + setHandle(0); // Don't generate any callbacks for this rejected invite + h->reject(403 /* Forbidden */, &warning); + return; + } + + // notify of new participant + if(mHandle) mConversationManager.onIncomingParticipant(mHandle, msg, autoAnswer, *profile); +} + +void +RemoteParticipant::onFailure(ClientInviteSessionHandle h, const SipMessage& msg) +{ + stateTransition(Terminating); + InfoLog(<< "onFailure: handle=" << mHandle << ", " << msg.brief()); + // If ForkSelectMode is automatic, then ensure we destory any conversations, except the original + if(mDialogSet.getForkSelectMode() == ConversationManager::ForkSelectAutomatic && + mHandle != mDialogSet.getActiveRemoteParticipantHandle()) + { + destroyConversations(); + } +} + +void +RemoteParticipant::onEarlyMedia(ClientInviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) +{ + InfoLog(<< "onEarlyMedia: handle=" << mHandle << ", " << msg.brief()); + if(!mDialogSet.isStaleFork(getDialogId())) + { + setRemoteSdp(sdp, true); + adjustRTPStreams(); + } +} + +void +RemoteParticipant::onProvisional(ClientInviteSessionHandle h, const SipMessage& msg) +{ + InfoLog(<< "onProvisional: handle=" << mHandle << ", " << msg.brief()); + assert(msg.header(h_StatusLine).responseCode() != 100); + + if(!mDialogSet.isStaleFork(getDialogId())) + { + if(mHandle) mConversationManager.onParticipantAlerting(mHandle, msg); + } +} + +void +RemoteParticipant::onConnected(ClientInviteSessionHandle h, const SipMessage& msg) +{ + InfoLog(<< "onConnected(Client): handle=" << mHandle << ", " << msg.brief()); + + // Check if this is the first leg in a potentially forked call to send a 200 + if(!mDialogSet.isUACConnected()) + { + if(mHandle) mConversationManager.onParticipantConnected(mHandle, msg); + + mDialogSet.setUACConnected(getDialogId(), mHandle); + stateTransition(Connected); + } + else + { + // We already have a 200 response - send a BYE to this leg + h->end(); + } +} + +void +RemoteParticipant::onConnected(InviteSessionHandle, const SipMessage& msg) +{ + InfoLog(<< "onConnected: handle=" << mHandle << ", " << msg.brief()); + stateTransition(Connected); +} + +void +RemoteParticipant::onConnectedConfirmed(InviteSessionHandle, const SipMessage& msg) +{ + InfoLog(<< "onConnectedConfirmed: handle=" << mHandle << ", " << msg.brief()); + stateTransition(Connected); +} + +void +RemoteParticipant::onStaleCallTimeout(ClientInviteSessionHandle) +{ + WarningLog(<< "onStaleCallTimeout: handle=" << mHandle); +} + +void +RemoteParticipant::onTerminated(InviteSessionHandle h, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg) +{ + stateTransition(Terminating); + switch(reason) + { + case InviteSessionHandler::RemoteBye: + InfoLog(<< "onTerminated: handle=" << mHandle << ", received a BYE from peer"); + break; + case InviteSessionHandler::RemoteCancel: + InfoLog(<< "onTerminated: handle=" << mHandle << ", received a CANCEL from peer"); + break; + case InviteSessionHandler::Rejected: + InfoLog(<< "onTerminated: handle=" << mHandle << ", received a rejection from peer"); + break; + case InviteSessionHandler::LocalBye: + InfoLog(<< "onTerminated: handle=" << mHandle << ", ended locally via BYE"); + break; + case InviteSessionHandler::LocalCancel: + InfoLog(<< "onTerminated: handle=" << mHandle << ", ended locally via CANCEL"); + break; + case InviteSessionHandler::Replaced: + InfoLog(<< "onTerminated: handle=" << mHandle << ", ended due to being replaced"); + break; + case InviteSessionHandler::Referred: + InfoLog(<< "onTerminated: handle=" << mHandle << ", ended due to being reffered"); + break; + case InviteSessionHandler::Error: + InfoLog(<< "onTerminated: handle=" << mHandle << ", ended due to an error"); + break; + case InviteSessionHandler::Timeout: + InfoLog(<< "onTerminated: handle=" << mHandle << ", ended due to a timeout"); + break; + default: + assert(false); + break; + } + unsigned int statusCode = 0; + if(msg) + { + if(msg->isResponse()) + { + statusCode = msg->header(h_StatusLine).responseCode(); + } + } + + // If this is a referred call and the refer is still around - then switch back to referrer (ie. failed transfer recovery) + if(mHandle && mReferringAppDialog.isValid()) + { + RemoteParticipant* participant = (RemoteParticipant*)mReferringAppDialog.get(); + + replaceWithParticipant(participant); // adjust conversation mappings + if(participant->getParticipantHandle()) + { + participant->adjustRTPStreams(); + return; + } + } + + // Ensure terminating party is from answered fork before generating event + if(!mDialogSet.isStaleFork(getDialogId())) + { + if(mHandle) mConversationManager.onParticipantTerminated(mHandle, statusCode); + } +} + +void +RemoteParticipant::onRedirected(ClientInviteSessionHandle, const SipMessage& msg) +{ + InfoLog(<< "onRedirected: handle=" << mHandle << ", " << msg.brief()); +} + +void +RemoteParticipant::onAnswer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) +{ + InfoLog(<< "onAnswer: handle=" << mHandle << ", " << msg.brief()); + + // Ensure answering party is from answered fork before generating event + if(!mDialogSet.isStaleFork(getDialogId())) + { + setRemoteSdp(sdp, true); + adjustRTPStreams(); + } + stateTransition(Connected); // This is valid until PRACK is implemented +} + +void +RemoteParticipant::onOffer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& offer) +{ + InfoLog(<< "onOffer: handle=" << mHandle << ", " << msg.brief()); + if(mState == Connecting && mInviteSessionHandle.isValid()) + { + ServerInviteSession* sis = dynamic_cast<ServerInviteSession*>(mInviteSessionHandle.get()); + if(sis && !sis->isAccepted()) + { + // Don't set answer now - store offer and set when needed - so that sendHoldSdp() can be calculated at the right instant + // we need to allow time for app to add to a conversation before alerting(with early flag) or answering + mPendingOffer = std::auto_ptr<SdpContents>(static_cast<SdpContents*>(offer.clone())); + return; + } + } + + if(getLocalRTPPort() == 0) + { + WarningLog(<< "RemoteParticipant::onOffer cannot continue due to no free RTP ports, rejecting offer."); + h->reject(480); // Temporarily Unavailable + } + else + { + if(provideAnswer(offer, mState==Replacing /* postAnswerAccept */, false /* postAnswerAlert */)) + { + if(mState == Replacing) + { + stateTransition(Connecting); + } + } + } +} + +void +RemoteParticipant::onOfferRequired(InviteSessionHandle h, const SipMessage& msg) +{ + InfoLog(<< "onOfferRequired: handle=" << mHandle << ", " << msg.brief()); + // We are being asked to provide SDP to the remote end - we should no longer be considering that + // remote end wants us to be on hold + mRemoteHold = false; + + if(mState == Connecting && !h->isAccepted()) + { + // If we haven't accepted yet - delay providing the offer until accept is called (this allows time + // for a localParticipant to be added before generating the offer) + mOfferRequired = true; + } + else + { + if(getLocalRTPPort() == 0) + { + WarningLog(<< "RemoteParticipant::onOfferRequired cannot continue due to no free RTP ports, rejecting offer request."); + h->reject(480); // Temporarily Unavailable + } + else + { + provideOffer(mState == Replacing /* postOfferAccept */); + if(mState == Replacing) + { + stateTransition(Connecting); + } + } + } +} + +void +RemoteParticipant::onOfferRejected(InviteSessionHandle, const SipMessage* msg) +{ + if(msg) + { + InfoLog(<< "onOfferRejected: handle=" << mHandle << ", " << msg->brief()); + } + else + { + InfoLog(<< "onOfferRejected: handle=" << mHandle); + } +} + +void +RemoteParticipant::onOfferRequestRejected(InviteSessionHandle h, const SipMessage& msg) +{ + InfoLog(<< "onOfferRequestRejected: handle=" << mHandle << ", " << msg.brief()); + assert(0); // We never send a request for an offer (ie. Invite with no SDP) +} + +void +RemoteParticipant::onRemoteSdpChanged(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp) +{ + InfoLog(<< "onRemoteSdpChanged: handle=" << mHandle << ", " << msg.brief()); + setRemoteSdp(sdp); + adjustRTPStreams(); +} + +void +RemoteParticipant::onInfo(InviteSessionHandle, const SipMessage& msg) +{ + InfoLog(<< "onInfo: handle=" << mHandle << ", " << msg.brief()); + //assert(0); +} + +void +RemoteParticipant::onInfoSuccess(InviteSessionHandle, const SipMessage& msg) +{ + InfoLog(<< "onInfoSuccess: handle=" << mHandle << ", " << msg.brief()); + assert(0); // We never send an info request +} + +void +RemoteParticipant::onInfoFailure(InviteSessionHandle, const SipMessage& msg) +{ + InfoLog(<< "onInfoFailure: handle=" << mHandle << ", " << msg.brief()); + assert(0); // We never send an info request +} + +void +RemoteParticipant::onRefer(InviteSessionHandle is, ServerSubscriptionHandle ss, const SipMessage& msg) +{ + InfoLog(<< "onRefer: handle=" << mHandle << ", " << msg.brief()); + + try + { + // Accept the Refer + ss->send(ss->accept(202 /* Refer Accepted */)); + + // Figure out hold SDP before removing ourselves from the conversation + bool holdSdp = mLocalHold; + + // Create new Participant - but use same participant handle + RemoteParticipantDialogSet* participantDialogSet = new RemoteParticipantDialogSet(mConversationManager, mDialogSet.getForkSelectMode()); + RemoteParticipant *participant = participantDialogSet->createUACOriginalRemoteParticipant(mHandle); // This will replace old participant in ConversationManager map + participant->mReferringAppDialog = getHandle(); + + replaceWithParticipant(participant); // adjust conversation mappings + + // Create offer + SdpContents offer; + participant->buildSdpOffer(holdSdp, offer); + + // Build the Invite + SharedPtr<SipMessage> NewInviteMsg = mDum.makeInviteSessionFromRefer(msg, ss->getHandle(), &offer, participantDialogSet); + participantDialogSet->sendInvite(NewInviteMsg); + + // Set RTP stack to listen + participant->adjustRTPStreams(true); + } + catch(BaseException &e) + { + WarningLog(<< "onRefer exception: " << e); + } + catch(...) + { + WarningLog(<< "onRefer unknown exception"); + } +} + +void +RemoteParticipant::doReferNoSub(const SipMessage& msg) +{ + // Figure out hold SDP before removing ourselves from the conversation + bool holdSdp = mLocalHold; + + // Create new Participant - but use same participant handle + RemoteParticipantDialogSet* participantDialogSet = new RemoteParticipantDialogSet(mConversationManager, mDialogSet.getForkSelectMode()); + RemoteParticipant *participant = participantDialogSet->createUACOriginalRemoteParticipant(mHandle); // This will replace old participant in ConversationManager map + participant->mReferringAppDialog = getHandle(); + + replaceWithParticipant(participant); // adjust conversation mappings + + // Create offer + SdpContents offer; + participant->buildSdpOffer(holdSdp, offer); + + // Build the Invite + SharedPtr<SipMessage> NewInviteMsg = mDum.makeInviteSessionFromRefer(msg, mDialogSet.getUserProfile(), &offer, participantDialogSet); + participantDialogSet->sendInvite(NewInviteMsg); + + // Set RTP stack to listen + participant->adjustRTPStreams(true); +} + +void +RemoteParticipant::onReferNoSub(InviteSessionHandle is, const SipMessage& msg) +{ + InfoLog(<< "onReferNoSub: handle=" << mHandle << ", " << msg.brief()); + + try + { + // Accept the Refer + is->acceptReferNoSub(202 /* Refer Accepted */); + + doReferNoSub(msg); + } + catch(BaseException &e) + { + WarningLog(<< "onReferNoSub exception: " << e); + } + catch(...) + { + WarningLog(<< "onReferNoSub unknown exception"); + } +} + +void +RemoteParticipant::onReferAccepted(InviteSessionHandle, ClientSubscriptionHandle, const SipMessage& msg) +{ + InfoLog(<< "onReferAccepted: handle=" << mHandle << ", " << msg.brief()); +} + +void +RemoteParticipant::onReferRejected(InviteSessionHandle, const SipMessage& msg) +{ + InfoLog(<< "onReferRejected: handle=" << mHandle << ", " << msg.brief()); + if(msg.isResponse() && mState == Redirecting) + { + if(mHandle) mConversationManager.onParticipantRedirectFailure(mHandle, msg.header(h_StatusLine).responseCode()); + stateTransition(Connected); + } +} + +void +RemoteParticipant::onMessage(InviteSessionHandle, const SipMessage& msg) +{ + InfoLog(<< "onMessage: handle=" << mHandle << ", " << msg.brief()); +} + +void +RemoteParticipant::onMessageSuccess(InviteSessionHandle, const SipMessage& msg) +{ + InfoLog(<< "onMessageSuccess: handle=" << mHandle << ", " << msg.brief()); +} + +void +RemoteParticipant::onMessageFailure(InviteSessionHandle, const SipMessage& msg) +{ + InfoLog(<< "onMessageFailure: handle=" << mHandle << ", " << msg.brief()); +} + +void +RemoteParticipant::onForkDestroyed(ClientInviteSessionHandle) +{ + InfoLog(<< "onForkDestroyed: handle=" << mHandle); +} + + +//////////////////////////////////////////////////////////////////////////////// +// ClientSubscriptionHandler /////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void +RemoteParticipant::onUpdatePending(ClientSubscriptionHandle h, const SipMessage& notify, bool outOfOrder) +{ + InfoLog(<< "onUpdatePending(ClientSub): handle=" << mHandle << ", " << notify.brief()); + if (notify.exists(h_Event) && notify.header(h_Event).value() == "refer") + { + h->acceptUpdate(); + processReferNotify(notify); + } + else + { + h->rejectUpdate(400, Data("Only notifies for refers are allowed.")); + } +} + +void +RemoteParticipant::onUpdateActive(ClientSubscriptionHandle h, const SipMessage& notify, bool outOfOrder) +{ + InfoLog(<< "onUpdateActive(ClientSub): handle=" << mHandle << ", " << notify.brief()); + if (notify.exists(h_Event) && notify.header(h_Event).value() == "refer") + { + h->acceptUpdate(); + processReferNotify(notify); + } + else + { + h->rejectUpdate(400, Data("Only notifies for refers are allowed.")); + } +} + +void +RemoteParticipant::onUpdateExtension(ClientSubscriptionHandle h, const SipMessage& notify, bool outOfOrder) +{ + InfoLog(<< "onUpdateExtension(ClientSub): handle=" << mHandle << ", " << notify.brief()); + if (notify.exists(h_Event) && notify.header(h_Event).value() == "refer") + { + h->acceptUpdate(); + processReferNotify(notify); + } + else + { + h->rejectUpdate(400, Data("Only notifies for refers are allowed.")); + } +} + +void +RemoteParticipant::onTerminated(ClientSubscriptionHandle h, const SipMessage* notify) +{ + if(notify) + { + InfoLog(<< "onTerminated(ClientSub): handle=" << mHandle << ", " << notify->brief()); + if (notify->isRequest() && notify->exists(h_Event) && notify->header(h_Event).value() == "refer") + { + // Note: Final notify is sometimes only passed in the onTerminated callback + processReferNotify(*notify); + } + else if(notify->isResponse() && mState == Redirecting) + { + if(mHandle) mConversationManager.onParticipantRedirectFailure(mHandle, notify->header(h_StatusLine).responseCode()); + stateTransition(Connected); + } + } + else + { + // Timed out waiting for notify + InfoLog(<< "onTerminated(ClientSub): handle=" << mHandle); + if(mState == Redirecting) + { + if(mHandle) mConversationManager.onParticipantRedirectFailure(mHandle, 408); + stateTransition(Connected); + } + } +} + +void +RemoteParticipant::onNewSubscription(ClientSubscriptionHandle h, const SipMessage& notify) +{ + InfoLog(<< "onNewSubscription(ClientSub): handle=" << mHandle << ", " << notify.brief()); +} + +int +RemoteParticipant::onRequestRetry(ClientSubscriptionHandle h, int retryMinimum, const SipMessage& notify) +{ + InfoLog(<< "onRequestRetry(ClientSub): handle=" << mHandle << ", " << notify.brief()); + return -1; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/RemoteParticipant.hxx b/src/libs/resiprocate/resip/recon/RemoteParticipant.hxx new file mode 100644 index 00000000..0238ccda --- /dev/null +++ b/src/libs/resiprocate/resip/recon/RemoteParticipant.hxx @@ -0,0 +1,228 @@ +#if !defined(RemoteParticipant_hxx) +#define RemoteParticipant_hxx + +#include "ConversationManager.hxx" +#include "Participant.hxx" +#include "RemoteParticipantDialogSet.hxx" + +#include <resip/dum/AppDialogSet.hxx> +#include <resip/dum/AppDialog.hxx> +#include <resip/dum/InviteSessionHandler.hxx> +#include <resip/dum/DialogSetHandler.hxx> +#include <resip/dum/SubscriptionHandler.hxx> + +namespace resip +{ +class DialogUsageManager; +class SipMessage; +} + +namespace sdpcontainer +{ +class Sdp; +class SdpMediaLine; +} + +namespace recon +{ +class ConversationManager; + +/** + This class represent a remote participant. A remote participant is a + participant with a network connection to a remote entity. This + implementation is for a SIP / RTP connections. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class RemoteParticipant : public Participant, public resip::AppDialog +{ +public: + RemoteParticipant(ParticipantHandle partHandle, // UAC + ConversationManager& conversationManager, + resip::DialogUsageManager& dum, + RemoteParticipantDialogSet& remoteParticipantDialogSet); + + RemoteParticipant(ConversationManager& conversationManager, // UAS or forked leg + resip::DialogUsageManager& dum, + RemoteParticipantDialogSet& remoteParticipantDialogSet); + + virtual ~RemoteParticipant(); + + virtual resip::InviteSessionHandle& getInviteSessionHandle() { return mInviteSessionHandle; } + virtual unsigned int getLocalRTPPort(); + void buildSdpOffer(bool holdSdp, resip::SdpContents& offer); + virtual bool isHolding() { return mLocalHold; } + + virtual void initiateRemoteCall(const resip::NameAddr& destination); + virtual int getConnectionPortOnBridge(); + virtual int getMediaConnectionId(); + virtual void destroyParticipant(); + virtual void addToConversation(Conversation *conversation, unsigned int inputGain = 100, unsigned int outputGain = 100); + virtual void removeFromConversation(Conversation *conversation); + virtual void accept(); + virtual void alert(bool earlyFlag); + virtual void reject(unsigned int rejectCode); + virtual void redirect(resip::NameAddr& destination); + virtual void redirectToParticipant(resip::InviteSessionHandle& destParticipantInviteSessionHandle); + virtual void checkHoldCondition(); + + virtual void setPendingOODReferInfo(resip::ServerOutOfDialogReqHandle ood, const resip::SipMessage& referMsg); // OOD-Refer (no Sub) + virtual void setPendingOODReferInfo(resip::ServerSubscriptionHandle ss, const resip::SipMessage& referMsg); // OOD-Refer (with Sub) + virtual void acceptPendingOODRefer(); + virtual void rejectPendingOODRefer(unsigned int statusCode); + virtual void redirectPendingOODRefer(resip::NameAddr& destination); + virtual void processReferNotify(const resip::SipMessage& notify); + + // Called by RemoteParticipantDialogSet when Related Conversations should be destroyed + virtual void destroyConversations(); + virtual void adjustRTPStreams(bool sendingOffer=false); + + // DTMF Handler + virtual void onDtmfEvent(int dtmf, int duration, bool up); + + // Invite Session Handler ///////////////////////////////////////////////////// + virtual void onNewSession(resip::ClientInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg); + virtual void onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg); + virtual void onFailure(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg); + virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&); + virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage& msg); + virtual void onConnected(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg); + virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onConnectedConfirmed(resip::InviteSessionHandle, const resip::SipMessage &msg); + virtual void onStaleCallTimeout(resip::ClientInviteSessionHandle); + virtual void onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* msg); + virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg); + virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&); + virtual void onOffer(resip::InviteSessionHandle handle, const resip::SipMessage& msg, const resip::SdpContents& offer); + virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg); + virtual void onOfferRequestRejected(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onRemoteSdpChanged(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents& sdp); + virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg); + virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg); + virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void doReferNoSub(const resip::SipMessage& msg); + virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg); + virtual void onForkDestroyed(resip::ClientInviteSessionHandle); + + // ClientSubscriptionHandler /////////////////////////////////////////////////// + virtual void onUpdatePending(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder); + virtual void onUpdateActive(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder); + virtual void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder); + virtual void onTerminated(resip::ClientSubscriptionHandle h, const resip::SipMessage* notify); + virtual void onNewSubscription(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify); + virtual int onRequestRetry(resip::ClientSubscriptionHandle h, int retryMinimum, const resip::SipMessage& notify); + +private: + void hold(); + void unhold(); + void provideOffer(bool postOfferAccept); + bool provideAnswer(const resip::SdpContents& offer, bool postAnswerAccept, bool postAnswerAlert); + bool answerMediaLine(resip::SdpContents::Session::Medium& mediaSessionCaps, const sdpcontainer::SdpMediaLine& sdpMediaLine, resip::SdpContents& answer, bool potential); + bool buildSdpAnswer(const resip::SdpContents& offer, resip::SdpContents& answer); + bool formMidDialogSdpOfferOrAnswer(const resip::SdpContents& localSdp, const resip::SdpContents& remoteSdp, resip::SdpContents& newSdp, bool offer); + void setProposedSdp(const resip::SdpContents& sdp); + void setLocalSdp(const resip::SdpContents& sdp); + void setRemoteSdp(const resip::SdpContents& sdp, bool answer=false); + void setRemoteSdp(const resip::SdpContents& sdp, sdpcontainer::Sdp* remoteSdp); + virtual void replaceWithParticipant(RemoteParticipant* replacingParticipant); + + resip::DialogUsageManager &mDum; + resip::InviteSessionHandle mInviteSessionHandle; + RemoteParticipantDialogSet& mDialogSet; + resip::DialogId mDialogId; + + typedef enum + { + Connecting=1, + Accepted, + Connected, + Redirecting, + Holding, + Unholding, + Replacing, + PendingOODRefer, + Terminating + } State; + State mState; + bool mOfferRequired; + bool mLocalHold; + bool mRemoteHold; + void stateTransition(State state); + + resip::AppDialogHandle mReferringAppDialog; + + resip::SipMessage mPendingOODReferMsg; + resip::ServerOutOfDialogReqHandle mPendingOODReferNoSubHandle; + resip::ServerSubscriptionHandle mPendingOODReferSubHandle; + + typedef enum + { + None = 0, + Hold, + Unhold, + Redirect, + RedirectTo + } PendingRequestType; + class PendingRequest + { + public: + PendingRequest() : mType(None) {} + PendingRequestType mType; + resip::NameAddr mDestination; + resip::InviteSessionHandle mDestInviteSessionHandle; + }; + PendingRequest mPendingRequest; + std::auto_ptr<resip::SdpContents> mPendingOffer; + + sdpcontainer::Sdp* mLocalSdp; + sdpcontainer::Sdp* mRemoteSdp; + + ConversationMap mRelatedConversations; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/RemoteParticipantDialogSet.cxx b/src/libs/resiprocate/resip/recon/RemoteParticipantDialogSet.cxx new file mode 100644 index 00000000..34282259 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/RemoteParticipantDialogSet.cxx @@ -0,0 +1,787 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// sipX includes +#include <CpTopologyGraphInterface.h> + +#include "ConversationManager.hxx" +#include "ReconSubsystem.hxx" +#include "RemoteParticipantDialogSet.hxx" +#include "RemoteParticipant.hxx" +#include "Conversation.hxx" +#include "UserAgent.hxx" +#include "MediaStreamEvent.hxx" +#include "FlowManagerSipXSocket.hxx" + +// Flowmanager Includes +#include "FlowManager.hxx" +#include "Flow.hxx" +#include "MediaStream.hxx" + +#include "sdp/SdpHelperResip.hxx" +#include "sdp/Sdp.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/Random.hxx> +#include <rutil/DnsUtil.hxx> +#include <resip/stack/SipFrag.hxx> +#include <resip/dum/DialogUsageManager.hxx> +#include <resip/dum/ServerInviteSession.hxx> + +//#define DISABLE_FLOWMANAGER_IF_NO_NAT_TRAVERSAL +#include <rutil/WinLeakCheck.hxx> + +#ifdef WIN32 + #define sleepMs(t) Sleep(t) +#else + #define sleepMs(t) usleep(t*1000) +#endif + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +RemoteParticipantDialogSet::RemoteParticipantDialogSet(ConversationManager& conversationManager, + ConversationManager::ParticipantForkSelectMode forkSelectMode) : + AppDialogSet(conversationManager.getUserAgent()->getDialogUsageManager()), + mConversationManager(conversationManager), + mUACOriginalRemoteParticipant(0), + mNumDialogs(0), + mLocalRTPPort(0), + mAllocateLocalRTPPortFailed(false), + mForkSelectMode(forkSelectMode), + mUACConnectedDialogId(Data::Empty, Data::Empty, Data::Empty), + mActiveRemoteParticipantHandle(0), + mNatTraversalMode(flowmanager::MediaStream::NoNatTraversal), + mMediaStream(0), + mRtpSocket(0), + mRtcpSocket(0), + mProposedSdp(0), + mSecureMediaMode(ConversationProfile::NoSecureMedia), + mSecureMediaRequired(false), + mMediaConnectionId(0), + mConnectionPortOnBridge(-1) +{ + + InfoLog(<< "RemoteParticipantDialogSet created."); +} + +RemoteParticipantDialogSet::~RemoteParticipantDialogSet() +{ + freeMediaResources(); + + // If we have no dialogs and mUACOriginalRemoteParticipant is set, then we have not passed + // ownership of mUACOriginalRemoteParticipant to DUM - so we need to delete the participant + if(mNumDialogs == 0 && mUACOriginalRemoteParticipant) + { + delete mUACOriginalRemoteParticipant; + } + + // Delete Sdp memory + if(mProposedSdp) delete mProposedSdp; + + InfoLog(<< "RemoteParticipantDialogSet destroyed. mActiveRemoteParticipantHandle=" << mActiveRemoteParticipantHandle); +} + +SharedPtr<UserProfile> +RemoteParticipantDialogSet::selectUASUserProfile(const SipMessage& msg) +{ + return mConversationManager.getUserAgent()->getIncomingConversationProfile(msg); +} + +unsigned int +RemoteParticipantDialogSet::getLocalRTPPort() +{ + if(mLocalRTPPort == 0 && !mAllocateLocalRTPPortFailed) + { + bool isUAC = false; + mLocalRTPPort = mConversationManager.allocateRTPPort(); + if(mLocalRTPPort == 0) + { + WarningLog(<< "Could not allocate a free RTP port for RemoteParticipantDialogSet!"); + mAllocateLocalRTPPortFailed = true; + return 0; + } + else + { + InfoLog(<< "Port allocated: " << mLocalRTPPort); + } + + // UAS Dialogs should have a user profile at this point - for UAC to get default outgoing + ConversationProfile* profile = dynamic_cast<ConversationProfile*>(getUserProfile().get()); + if(!profile) + { + profile = mConversationManager.getUserAgent()->getDefaultOutgoingConversationProfile().get(); + isUAC = true; + } + + OsStatus ret; + // Create localBinding Tuple - note: transport may be changed depending on NAT traversal mode + StunTuple localBinding(StunTuple::UDP, asio::ip::address::from_string(profile->sessionCaps().session().connection().getAddress().c_str()), mLocalRTPPort); + + switch(profile->natTraversalMode()) + { + case ConversationProfile::StunBindDiscovery: + // Use straight UDP with Stun Binding discovery + mNatTraversalMode = MediaStream::StunBindDiscovery; + break; + case ConversationProfile::TurnUdpAllocation: + // Use Udp turn media relay + mNatTraversalMode = MediaStream::TurnAllocation; + break; + case ConversationProfile::TurnTcpAllocation: + // Use Tcp turn media relay + localBinding.setTransportType(StunTuple::TCP); + mNatTraversalMode = MediaStream::TurnAllocation; + break; +#ifdef USE_SSL + case ConversationProfile::TurnTlsAllocation: + // Use TLS turn media relay + localBinding.setTransportType(StunTuple::TLS); + mNatTraversalMode = MediaStream::TurnAllocation; + break; +#endif + case ConversationProfile::NoNatTraversal: + default: + // Use straight UDP + mNatTraversalMode = MediaStream::NoNatTraversal; + break; + } + +#ifdef USE_SSL + if(profile->secureMediaMode() == ConversationProfile::SrtpDtls && + mNatTraversalMode == MediaStream::TurnAllocation) + { + WarningLog(<< "You cannot use SrtpDtls and a Turn allocation at the same time - disabling SrtpDtls!"); + mSecureMediaMode = ConversationProfile::NoSecureMedia; + } + else +#endif + { + mSecureMediaMode = profile->secureMediaMode(); + mSecureMediaRequired = profile->secureMediaRequired(); + } + + // Set other Srtp properties + mLocalSrtpSessionKey = Random::getCryptoRandom(SRTP_MASTER_KEY_LEN); + mSecureMediaRequired = profile->secureMediaRequired(); + + switch(profile->secureMediaDefaultCryptoSuite()) + { + case ConversationProfile::SRTP_AES_CM_128_HMAC_SHA1_32: + mSrtpCryptoSuite = flowmanager::MediaStream::SRTP_AES_CM_128_HMAC_SHA1_32; + break; + default: + mSrtpCryptoSuite = flowmanager::MediaStream::SRTP_AES_CM_128_HMAC_SHA1_80; + break; + } + +#ifdef DISABLE_FLOWMANAGER_IF_NO_NAT_TRAVERSAL + if(mNatTraversalMode != MediaStream::NoNatTraversal) + { +#endif + mMediaStream = mConversationManager.getFlowManager().createMediaStream( + *this, + localBinding, + true /* rtcp? */, + mNatTraversalMode, + profile->natTraversalServerHostname().c_str(), + profile->natTraversalServerPort(), + profile->stunUsername().c_str(), + profile->stunPassword().c_str()); + + // New Remote Participant - create media Interface connection + mRtpSocket = new FlowManagerSipXSocket(mMediaStream->getRtpFlow(), mConversationManager.mSipXTOSValue); + mRtcpSocket = new FlowManagerSipXSocket(mMediaStream->getRtcpFlow(), mConversationManager.mSipXTOSValue); + + ret = ((CpTopologyGraphInterface*)getMediaInterface()->getInterface())->createConnection(mMediaConnectionId,mRtpSocket,mRtcpSocket,false); +#ifdef DISABLE_FLOWMANAGER_IF_NO_NAT_TRAVERSAL + } + else + { + ret = getMediaInterface()->getInterface()->createConnection(mMediaConnectionId, + profile->sessionCaps().session().connection().getAddress().c_str(), + mLocalRTPPort); + mRtpTuple = localBinding; // Just treat media stream as immediately ready using the localBinding in the SDP + } +#endif + + if(ret == OS_SUCCESS) + { + // Get the capabilities so that we can ensure there are codecs loaded + UtlString rtpHostAddress; + int rtpAudioPort; + int rtcpAudioPort; + int rtpVideoPort; + int rtcpVideoPort; + SdpCodecList supportedCodecs; + SdpSrtpParameters srtpParameters; + int bandWidth = 0; + int videoBandwidth; + int videoFramerate; + + ret = getMediaInterface()->getInterface()->getCapabilities( + mMediaConnectionId, + rtpHostAddress, + rtpAudioPort, + rtcpAudioPort, + rtpVideoPort, + rtcpVideoPort, + supportedCodecs, + srtpParameters, + bandWidth, + videoBandwidth, + videoFramerate); + + if(ret == OS_SUCCESS) + { + if(supportedCodecs.getCodecCount() == 0) + { + ErrLog( << "No supported codecs!!!!!"); + } + } + else + { + ErrLog( << "Error getting connection capabilities, ret=" << ret); + } + } + else + { + ErrLog( << "Error creating connection, ret=" << ret); + } + + //InfoLog(<< "About to get Connection Port on Bridge for MediaConnectionId: " << mMediaConnectionId); + ret = ((CpTopologyGraphInterface*)getMediaInterface()->getInterface())->getConnectionPortOnBridge(mMediaConnectionId, 0, mConnectionPortOnBridge); + InfoLog( << "RTP Port allocated=" << mLocalRTPPort << " (sipXmediaConnectionId=" << mMediaConnectionId << ", BridgePort=" << mConnectionPortOnBridge << ", ret=" << ret << ")"); + } + + return mLocalRTPPort; +} + +void +RemoteParticipantDialogSet::processMediaStreamReadyEvent(const StunTuple& rtpTuple, const StunTuple& rtcpTuple) +{ + InfoLog( << "processMediaStreamReadyEvent: rtpTuple=" << rtpTuple << " rtcpTuple=" << rtcpTuple); + mRtpTuple = rtpTuple; + mRtcpTuple = rtcpTuple; // Check if we had operations pending on the media stream being ready + + if(mPendingInvite.get() != 0) + { + // Pending Invite Request + doSendInvite(mPendingInvite); + mPendingInvite.reset(); + } + + if(mPendingOfferAnswer.mSdp.get() != 0) + { + // Pending Offer or Answer + doProvideOfferAnswer(mPendingOfferAnswer.mOffer, + mPendingOfferAnswer.mSdp, + mPendingOfferAnswer.mInviteSessionHandle, + mPendingOfferAnswer.mPostOfferAnswerAccept, + mPendingOfferAnswer.mPostAnswerAlert); + assert(mPendingOfferAnswer.mSdp.get() == 0); + } +} + +void +RemoteParticipantDialogSet::processMediaStreamErrorEvent(unsigned int errorCode) +{ + InfoLog( << "processMediaStreamErrorEvent, error=" << errorCode); + + // Note: in the case of an initial invite we must issue the invite in order for dum to cleanup state + // properly - this is not ideal, since it may cause endpoint phone device to ring a little + // before receiving the cancel + if(mPendingInvite.get() != 0) + { + // Pending Invite Request - Falling back to using local address/port - but then end() immediate + doSendInvite(mPendingInvite); + mPendingInvite.reset(); + } + + // End call + if(mNumDialogs > 0) + { + std::map<DialogId, RemoteParticipant*>::iterator it; + for(it = mDialogs.begin(); it != mDialogs.end(); it++) + { + it->second->destroyParticipant(); + } + } + else + { + end(); + } +} + +void +RemoteParticipantDialogSet::onMediaStreamReady(const StunTuple& rtpTuple, const StunTuple& rtcpTuple) +{ + // Get event into dum queue, so that callback is on dum thread + MediaStreamReadyEvent* event = new MediaStreamReadyEvent(*this, rtpTuple, rtcpTuple); + mDum.post(event); +} + +void +RemoteParticipantDialogSet::onMediaStreamError(unsigned int errorCode) +{ + // Get event into dum queue, so that callback is on dum thread + MediaStreamErrorEvent* event = new MediaStreamErrorEvent(*this, errorCode); + mDum.post(event); +} + +void +RemoteParticipantDialogSet::sendInvite(SharedPtr<SipMessage> invite) +{ + if(mRtpTuple.getTransportType() != reTurn::StunTuple::None) + { + doSendInvite(invite); + } + else + { + // Wait until media stream is ready + mPendingInvite = invite; + } +} + +void +RemoteParticipantDialogSet::doSendInvite(SharedPtr<SipMessage> invite) +{ + // Fix up address and port in SDP if we have remote info + // Note: the only time we don't is if there was an error preparing the media stream + if(mRtpTuple.getTransportType() != reTurn::StunTuple::None) + { + SdpContents* sdp = dynamic_cast<SdpContents*>(invite->getContents()); + if (sdp) + { + sdp->session().media().front().port() = mRtpTuple.getPort(); + sdp->session().connection() = SdpContents::Session::Connection(mRtpTuple.getAddress().is_v4() ? SdpContents::IP4 : SdpContents::IP6, mRtpTuple.getAddress().to_string().c_str()); // c= + } + } + + // Send the invite + mDum.send(invite); +} + +void +RemoteParticipantDialogSet::provideOffer(std::auto_ptr<resip::SdpContents> offer, resip::InviteSessionHandle& inviteSessionHandle, bool postOfferAccept) +{ + if(mRtpTuple.getTransportType() != reTurn::StunTuple::None) + { + doProvideOfferAnswer(true /* offer */, offer, inviteSessionHandle, postOfferAccept, false); + } + else + { + assert(mPendingOfferAnswer.mSdp.get() == 0); + mPendingOfferAnswer.mOffer = true; + mPendingOfferAnswer.mSdp = offer; + mPendingOfferAnswer.mInviteSessionHandle = inviteSessionHandle; + mPendingOfferAnswer.mPostOfferAnswerAccept = postOfferAccept; + mPendingOfferAnswer.mPostAnswerAlert = false; + } +} + +void +RemoteParticipantDialogSet::provideAnswer(std::auto_ptr<resip::SdpContents> answer, resip::InviteSessionHandle& inviteSessionHandle, bool postAnswerAccept, bool postAnswerAlert) +{ + if(mRtpTuple.getTransportType() != reTurn::StunTuple::None) + { + doProvideOfferAnswer(false /* offer */, answer, inviteSessionHandle, postAnswerAccept, postAnswerAlert); + } + else + { + assert(mPendingOfferAnswer.mSdp.get() == 0); + mPendingOfferAnswer.mOffer = false; + mPendingOfferAnswer.mSdp = answer; + mPendingOfferAnswer.mInviteSessionHandle = inviteSessionHandle; + mPendingOfferAnswer.mPostOfferAnswerAccept = postAnswerAccept; + mPendingOfferAnswer.mPostAnswerAlert = postAnswerAlert; + } +} + +void +RemoteParticipantDialogSet::doProvideOfferAnswer(bool offer, std::auto_ptr<resip::SdpContents> sdp, resip::InviteSessionHandle& inviteSessionHandle, bool postOfferAnswerAccept, bool postAnswerAlert) +{ + if(inviteSessionHandle.isValid() && !inviteSessionHandle->isTerminated()) + { + // Fix up address and port in SDP if we have remote info + // Note: the only time we don't is if there was an error preparing the media stream + if(mRtpTuple.getTransportType() != reTurn::StunTuple::None) + { + sdp->session().media().front().port() = mRtpTuple.getPort(); + sdp->session().connection() = SdpContents::Session::Connection(mRtpTuple.getAddress().is_v4() ? SdpContents::IP4 : SdpContents::IP6, mRtpTuple.getAddress().to_string().c_str()); // c= + } + + if(offer) + { + inviteSessionHandle->provideOffer(*sdp); + } + else + { + inviteSessionHandle->provideAnswer(*sdp); + } + + // Adjust RTP Streams + dynamic_cast<RemoteParticipant*>(inviteSessionHandle->getAppDialog().get())->adjustRTPStreams(offer); + + // Do Post Answer Operations + ServerInviteSession* sis = dynamic_cast<ServerInviteSession*>(inviteSessionHandle.get()); + if(sis) + { + if(postAnswerAlert) + { + sis->provisional(180,true); + } + if(postOfferAnswerAccept) + { + sis->accept(); + } + } + } +} + +void +RemoteParticipantDialogSet::accept(resip::InviteSessionHandle& inviteSessionHandle) +{ + // If we have a pending answer, then just flag to accept when complete + if(mPendingOfferAnswer.mSdp.get() != 0 && + !mPendingOfferAnswer.mOffer) + { + mPendingOfferAnswer.mPostOfferAnswerAccept = true; + } + else if(inviteSessionHandle.isValid()) + { + ServerInviteSession* sis = dynamic_cast<ServerInviteSession*>(inviteSessionHandle.get()); + if(sis) + { + sis->accept(); + } + } +} + +SharedPtr<MediaInterface> +RemoteParticipantDialogSet::getMediaInterface() +{ + if(!mMediaInterface) + { + // Get the media interface from the active participant + if(mUACOriginalRemoteParticipant) + { + mMediaInterface = mUACOriginalRemoteParticipant->getMediaInterface(); + } + else if(mDialogs.size() > 0) + { + // All participants in the set will have the same media interface - query from first + assert(mDialogs.begin()->second); + mMediaInterface = mDialogs.begin()->second->getMediaInterface(); + } + } + assert(mMediaInterface); + return mMediaInterface; +} + +int +RemoteParticipantDialogSet::getConnectionPortOnBridge() +{ + if(mConnectionPortOnBridge==-1) + { + getLocalRTPPort(); // This call will create a MediaConnection if not already created at this point + } + return mConnectionPortOnBridge; +} + +void +RemoteParticipantDialogSet::freeMediaResources() +{ + if(mMediaConnectionId) + { + getMediaInterface()->getInterface()->deleteConnection(mMediaConnectionId); + mMediaConnectionId = 0; + } + + // Delete custom sockets - Note: Must be done before MediaStream is deleted + if(mRtpSocket) + { + delete mRtpSocket; + mRtpSocket = 0; + } + if(mRtcpSocket) + { + delete mRtcpSocket; + mRtcpSocket = 0; + } + + // Delete Media Stream + if(mMediaStream) + { + delete mMediaStream; + mMediaStream = 0; + } + + // Add the RTP port back to the pool + if(mLocalRTPPort) + { + mConversationManager.freeRTPPort(mLocalRTPPort); + mLocalRTPPort = 0; + } +} + +void +RemoteParticipantDialogSet::setActiveDestination(const char* address, unsigned short rtpPort, unsigned short rtcpPort) +{ +#ifdef DISABLE_FLOWMANAGER_IF_NO_NAT_TRAVERSAL + if(mNatTraversalMode != MediaStream::NoNatTraversal) + { +#endif + if(mMediaStream && mMediaStream->getRtpFlow()) + { + mMediaStream->getRtpFlow()->setActiveDestination(address, rtpPort); + } + if(mMediaStream && mMediaStream->getRtcpFlow()) + { + mMediaStream->getRtcpFlow()->setActiveDestination(address, rtcpPort); + } +#ifdef DISABLE_FLOWMANAGER_IF_NO_NAT_TRAVERSAL + } + else + { + getMediaInterface()->getInterface()->setConnectionDestination(mMediaConnectionId, + address, + rtpPort, /* audio rtp port */ + rtcpPort, /* audio rtcp port */ + -1 /* video rtp port */, + -1 /* video rtcp port */); + } +#endif +} + +void +RemoteParticipantDialogSet::startDtlsClient(const char* address, unsigned short rtpPort, unsigned short rtcpPort) +{ +#ifdef USE_SSL + if(mMediaStream && mMediaStream->getRtpFlow()) + { + mMediaStream->getRtpFlow()->startDtlsClient(address, rtpPort); + } + if(mMediaStream && mMediaStream->getRtcpFlow()) + { + mMediaStream->getRtcpFlow()->startDtlsClient(address, rtcpPort); + } +#endif +} + +void +RemoteParticipantDialogSet::setRemoteSDPFingerprint(const resip::Data& fingerprint) +{ + if(mMediaStream && mMediaStream->getRtpFlow()) + { + mMediaStream->getRtpFlow()->setRemoteSDPFingerprint(fingerprint); + } + if(mMediaStream && mMediaStream->getRtcpFlow()) + { + mMediaStream->getRtcpFlow()->setRemoteSDPFingerprint(fingerprint); + } +} + +bool +RemoteParticipantDialogSet::createSRTPSession(MediaStream::SrtpCryptoSuite cryptoSuite, const char* remoteKey, unsigned int remoteKeyLen) +{ + if(mMediaStream) + { + mSrtpCryptoSuite = cryptoSuite; // update cypto suite to negotiated value + mMediaStream->createOutboundSRTPSession(cryptoSuite, mLocalSrtpSessionKey.data(), mLocalSrtpSessionKey.size()); + return mMediaStream->createInboundSRTPSession(cryptoSuite, remoteKey, remoteKeyLen); + } + return false; +} + +RemoteParticipant* +RemoteParticipantDialogSet::createUACOriginalRemoteParticipant(ParticipantHandle handle) +{ + assert(!mUACOriginalRemoteParticipant); + RemoteParticipant *participant = new RemoteParticipant(handle, mConversationManager, mDum, *this); + mUACOriginalRemoteParticipant = participant; + mActiveRemoteParticipantHandle = participant->getParticipantHandle(); // Store this since it may not be safe to access mUACOriginalRemoteParticipant pointer after corresponding Dialog has been created + return participant; +} + +AppDialog* +RemoteParticipantDialogSet::createAppDialog(const SipMessage& msg) +{ + mNumDialogs++; + + if(mUACOriginalRemoteParticipant) // UAC DialogSet + { + // Need to either return participant already created, or create a new one. + if(mNumDialogs > 1) + { + // forking occured and we now have multiple dialogs in this dialog set + RemoteParticipant* participant = new RemoteParticipant(mConversationManager, mDum, *this); + + InfoLog(<< "Forking occurred for original UAC participant handle=" << mUACOriginalRemoteParticipant->getParticipantHandle() << + " this is leg number " << mNumDialogs << " new handle=" << participant->getParticipantHandle()); + + // Create Related Conversations for each conversation UACOriginalRemoteParticipant was in when first Dialog is created + std::list<ConversationHandle>::iterator it; + for(it = mUACOriginalConversationHandles.begin(); it != mUACOriginalConversationHandles.end(); it++) + { + Conversation* conversation = mConversationManager.getConversation(*it); + if(conversation) + { + conversation->createRelatedConversation(participant, mActiveRemoteParticipantHandle); + } + } + + mDialogs[DialogId(msg)] = participant; + return participant; + } + else + { + // Get Conversations from Remote Participant and store - used later for creating related conversations + const Participant::ConversationMap& conversations = mUACOriginalRemoteParticipant->getConversations(); + Participant::ConversationMap::const_iterator it; + for(it = conversations.begin(); it != conversations.end(); it++) + { + mUACOriginalConversationHandles.push_back(it->second->getHandle()); + } + + mDialogs[DialogId(msg)] = mUACOriginalRemoteParticipant; + return mUACOriginalRemoteParticipant; + } + } + else + { + RemoteParticipant *participant = new RemoteParticipant(mConversationManager, mDum, *this); + mActiveRemoteParticipantHandle = participant->getParticipantHandle(); + mDialogs[DialogId(msg)] = participant; // Note: !slg! DialogId is not quite right here, since there is no To Tag on the INVITE + return participant; + } +} + +void +RemoteParticipantDialogSet::setProposedSdp(ParticipantHandle handle, const resip::SdpContents& sdp) +{ + if(mProposedSdp) delete mProposedSdp; + mProposedSdp = 0; + InfoLog(<< "setProposedSdp: handle=" << handle << ", proposedSdp=" << sdp); + mProposedSdp = SdpHelperResip::createSdpFromResipSdp(sdp); +} + +void +RemoteParticipantDialogSet::setUACConnected(const DialogId& dialogId, ParticipantHandle partHandle) +{ + assert(mUACConnectedDialogId.getCallId().empty()); + mUACConnectedDialogId = dialogId; + mActiveRemoteParticipantHandle = partHandle; + if(mForkSelectMode == ConversationManager::ForkSelectAutomatic) + { + std::map<DialogId, RemoteParticipant*>::iterator it; + for(it = mDialogs.begin(); it != mDialogs.end(); it++) + { + if(it->first != dialogId) + { + InfoLog(<< "Connected to forked leg " << dialogId << " - stale dialog " << it->first << " and related conversation(s) will be ended."); + it->second->destroyConversations(); + } + } + } +} + +bool +RemoteParticipantDialogSet::isUACConnected() +{ + return !mUACConnectedDialogId.getCallId().empty(); +} + +bool +RemoteParticipantDialogSet::isStaleFork(const DialogId& dialogId) +{ + return (!mUACConnectedDialogId.getCallId().empty() && dialogId != mUACConnectedDialogId); +} + +void +RemoteParticipantDialogSet::removeDialog(const DialogId& dialogId) +{ + std::map<DialogId, RemoteParticipant*>::iterator it = mDialogs.find(dialogId); + if(it != mDialogs.end()) + { + if(it->second == mUACOriginalRemoteParticipant) mUACOriginalRemoteParticipant = 0; + mDialogs.erase(it); + } + + // If we have no more dialogs and we never went connected - make sure we cancel the Invite transaction + if(mDialogs.size() == 0 && !isUACConnected()) + { + end(); + } +} + +ConversationManager::ParticipantForkSelectMode +RemoteParticipantDialogSet::getForkSelectMode() +{ + return mForkSelectMode; +} + +//////////////////////////////////////////////////////////////////////////////// +// DialogSetHandler /////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void +RemoteParticipantDialogSet::onTrying(AppDialogSetHandle, const SipMessage& msg) +{ + if(!isUACConnected() && mUACOriginalRemoteParticipant) + { + InfoLog(<< "onTrying: handle=" << mUACOriginalRemoteParticipant->getParticipantHandle() << ", " << msg.brief()); + //mConversationManager.onParticipantProceeding(mHandle, msg); + } +} + +void +RemoteParticipantDialogSet::onNonDialogCreatingProvisional(AppDialogSetHandle, const SipMessage& msg) +{ + assert(msg.header(h_StatusLine).responseCode() != 100); + // It possible to get a provisional from another fork after receiving a 200 - if so, don't generate an event + if(!isUACConnected() && mUACOriginalRemoteParticipant) + { + InfoLog(<< "onNonDialogCreatingProvisional: handle=" << mUACOriginalRemoteParticipant->getParticipantHandle() << ", " << msg.brief()); + if(mUACOriginalRemoteParticipant->getParticipantHandle()) mConversationManager.onParticipantAlerting(mUACOriginalRemoteParticipant->getParticipantHandle(), msg); + } +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/RemoteParticipantDialogSet.hxx b/src/libs/resiprocate/resip/recon/RemoteParticipantDialogSet.hxx new file mode 100644 index 00000000..2474a68d --- /dev/null +++ b/src/libs/resiprocate/resip/recon/RemoteParticipantDialogSet.hxx @@ -0,0 +1,188 @@ +#if !defined(RemoteParticipantDialogSet_hxx) +#define RemoteParticipantDialogSet_hxx + +#include <map> +#include <list> +#include <resip/dum/AppDialogSet.hxx> +#include <resip/dum/AppDialog.hxx> +#include <resip/dum/InviteSessionHandler.hxx> +#include <resip/dum/DialogSetHandler.hxx> +#include <resip/dum/SubscriptionHandler.hxx> + +// FlowManager Includes +#include "MediaStream.hxx" + +#include "ConversationManager.hxx" +#include "ConversationProfile.hxx" +#include "Participant.hxx" + +namespace sdpcontainer +{ +class Sdp; +} + +namespace resip +{ +class DialogUsageManager; +class SipMessage; +} + +namespace recon +{ +class ConversationManager; +class RemoteParticipant; +class FlowManagerSipXSocket; + +/** + This class is used by Invite DialogSets. Non-Invite DialogSets + are managed by DefaultDialogSet. This class contains logic + to handle forking and RTP connections. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class RemoteParticipantDialogSet : public resip::AppDialogSet, private flowmanager::MediaStreamHandler +{ +public: + RemoteParticipantDialogSet(ConversationManager& conversationManager, + ConversationManager::ParticipantForkSelectMode forkSelectMode = ConversationManager::ForkSelectAutomatic); + + virtual ~RemoteParticipantDialogSet(); + + virtual RemoteParticipant* createUACOriginalRemoteParticipant(ParticipantHandle handle); + virtual resip::AppDialog* createAppDialog(const resip::SipMessage& msg); + virtual unsigned int getLocalRTPPort(); + + virtual void setProposedSdp(ParticipantHandle handle, const resip::SdpContents& sdp); + virtual sdpcontainer::Sdp* getProposedSdp() { return mProposedSdp; } + virtual void setUACConnected(const resip::DialogId& dialogId, ParticipantHandle partHandle); + virtual bool isUACConnected(); + virtual bool isStaleFork(const resip::DialogId& dialogId); + + virtual void removeDialog(const resip::DialogId& dialogId); + virtual ConversationManager::ParticipantForkSelectMode getForkSelectMode(); + virtual ParticipantHandle getActiveRemoteParticipantHandle() { return mActiveRemoteParticipantHandle; } + virtual void setActiveRemoteParticipantHandle(ParticipantHandle handle) { mActiveRemoteParticipantHandle = handle; } + + // DialogSetHandler + virtual void onTrying(resip::AppDialogSetHandle, const resip::SipMessage& msg); + virtual void onNonDialogCreatingProvisional(resip::AppDialogSetHandle, const resip::SipMessage& msg); + + // sipX Media Stuff + virtual int getMediaConnectionId() { return mMediaConnectionId; } + virtual int getConnectionPortOnBridge(); + virtual void freeMediaResources(); + + void setActiveDestination(const char* address, unsigned short rtpPort, unsigned short rtcpPort); + void startDtlsClient(const char* address, unsigned short rtpPort, unsigned short rtcpPort); + void setRemoteSDPFingerprint(const resip::Data& fingerprint); + bool createSRTPSession(flowmanager::MediaStream::SrtpCryptoSuite cryptoSuite, const char* remoteKey, unsigned int remoteKeyLen); + + // Media Stream Processing + void processMediaStreamReadyEvent(const StunTuple& remoteRtpTuple, const StunTuple& remoteRtcpTuple); + void processMediaStreamErrorEvent(unsigned int errorCode); + + void sendInvite(resip::SharedPtr<resip::SipMessage> invite); + void provideOffer(std::auto_ptr<resip::SdpContents> offer, resip::InviteSessionHandle& inviteSessionHandle, bool postOfferAccept); + void provideAnswer(std::auto_ptr<resip::SdpContents> answer, resip::InviteSessionHandle& inviteSessionHandle, bool postAnswerAccept, bool postAnswerAlert); + void accept(resip::InviteSessionHandle& inviteSessionHandle); + ConversationProfile::SecureMediaMode getSecureMediaMode() { return mSecureMediaMode; } + flowmanager::MediaStream::SrtpCryptoSuite getSrtpCryptoSuite() { return mSrtpCryptoSuite; } + bool getSecureMediaRequired() { return mSecureMediaRequired; } + + const resip::Data& getLocalSrtpSessionKey() { return mLocalSrtpSessionKey; } + +protected: + virtual resip::SharedPtr<resip::UserProfile> selectUASUserProfile(const resip::SipMessage&); + +private: + ConversationManager& mConversationManager; + RemoteParticipant* mUACOriginalRemoteParticipant; + std::list<ConversationHandle> mUACOriginalConversationHandles; + unsigned int mNumDialogs; + unsigned int mLocalRTPPort; + bool mAllocateLocalRTPPortFailed; + ConversationManager::ParticipantForkSelectMode mForkSelectMode; + resip::DialogId mUACConnectedDialogId; + ParticipantHandle mActiveRemoteParticipantHandle; + std::map<resip::DialogId, RemoteParticipant*> mDialogs; + + // Media Stream stuff + flowmanager::MediaStream::NatTraversalMode mNatTraversalMode; + flowmanager::MediaStream* mMediaStream; + reTurn::StunTuple mRtpTuple; + reTurn::StunTuple mRtcpTuple; + FlowManagerSipXSocket* mRtpSocket; + FlowManagerSipXSocket* mRtcpSocket; + + // SDP Negotiations that may need to be delayed due to FlowManager binding/allocation + resip::SharedPtr<resip::SipMessage> mPendingInvite; + void doSendInvite(resip::SharedPtr<resip::SipMessage> invite); + class PendingOfferAnswer + { + public: + PendingOfferAnswer() {} + bool mOffer; + std::auto_ptr<resip::SdpContents> mSdp; + resip::InviteSessionHandle mInviteSessionHandle; + bool mPostOfferAnswerAccept; + bool mPostAnswerAlert; + }; + PendingOfferAnswer mPendingOfferAnswer; + void doProvideOfferAnswer(bool offer, std::auto_ptr<resip::SdpContents> sdp, resip::InviteSessionHandle& inviteSessionHandle, bool postOfferAnswerAccept, bool postAnswerAlert); + sdpcontainer::Sdp* mProposedSdp; // stored here vs RemoteParticipant, since each forked leg needs access to the original offer + + // Secure Media + resip::Data mLocalSrtpSessionKey; + ConversationProfile::SecureMediaMode mSecureMediaMode; + bool mSecureMediaRequired; + flowmanager::MediaStream::SrtpCryptoSuite mSrtpCryptoSuite; + + // sipX media stuff + virtual resip::SharedPtr<MediaInterface> getMediaInterface(); + resip::SharedPtr<MediaInterface> mMediaInterface; + int mMediaConnectionId; + int mConnectionPortOnBridge; + + virtual void onMediaStreamReady(const StunTuple& remoteRtpTuple, const StunTuple& remoteRtcpTuple); + virtual void onMediaStreamError(unsigned int errorCode); +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgent.cxx b/src/libs/resiprocate/resip/recon/UserAgent.cxx new file mode 100644 index 00000000..0c179ea3 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgent.cxx @@ -0,0 +1,630 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "UserAgent.hxx" +#include "UserAgentDialogSetFactory.hxx" +#include "UserAgentCmds.hxx" +#include "UserAgentServerAuthManager.hxx" +#include "UserAgentClientSubscription.hxx" +#include "UserAgentRegistration.hxx" +#include "ReconSubsystem.hxx" + +#include "FlowManagerSubsystem.hxx" + +#include <ReTurnSubsystem.hxx> + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <resip/dum/ClientAuthManager.hxx> +#include <resip/dum/ClientSubscription.hxx> +#include <resip/dum/ServerSubscription.hxx> +#include <resip/dum/ClientRegistration.hxx> +#include <resip/dum/KeepAliveManager.hxx> +#include <resip/dum/AppDialogSet.hxx> +#if defined(USE_SSL) +#include <resip/stack/ssl/Security.hxx> +#endif +#include <rutil/WinLeakCheck.hxx> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +UserAgent::UserAgent(ConversationManager* conversationManager, SharedPtr<UserAgentMasterProfile> profile, AfterSocketCreationFuncPtr socketFunc) : + mCurrentSubscriptionHandle(1), + mCurrentConversationProfileHandle(1), + mDefaultOutgoingConversationProfileHandle(0), + mConversationManager(conversationManager), + mProfile(profile), +#if defined(USE_SSL) + mSecurity(new Security(profile->certPath())), +#else + mSecurity(0), +#endif + mStack(mSecurity, profile->getAdditionalDnsServers(), &mSelectInterruptor, false /* stateless */, socketFunc), + mDum(mStack), + mStackThread(mStack, mSelectInterruptor), + mDumShutdown(false) +{ + assert(mConversationManager); + mConversationManager->setUserAgent(this); + + addTransports(); + + // Set Enum Suffixes + mStack.setEnumSuffixes(profile->getEnumSuffixes()); + + // Enable/Disable Statistics Manager + mStack.statisticsManagerEnabled() = profile->statisticsManagerEnabled(); + + // Install Handlers + mDum.setMasterProfile(mProfile); + mDum.setClientRegistrationHandler(this); + mDum.setClientAuthManager(std::auto_ptr<ClientAuthManager>(new ClientAuthManager)); + mDum.setKeepAliveManager(std::auto_ptr<KeepAliveManager>(new KeepAliveManager)); + mDum.setRedirectHandler(mConversationManager); + mDum.setInviteSessionHandler(mConversationManager); + mDum.setDialogSetHandler(mConversationManager); + mDum.addOutOfDialogHandler(OPTIONS, mConversationManager); + mDum.addOutOfDialogHandler(REFER, mConversationManager); + mDum.addClientSubscriptionHandler("refer", mConversationManager); + mDum.addServerSubscriptionHandler("refer", mConversationManager); + + //mDum.addClientSubscriptionHandler(Symbols::Presence, this); + //mDum.addClientPublicationHandler(Symbols::Presence, this); + //mDum.addOutOfDialogHandler(NOTIFY, this); + //mDum.addServerSubscriptionHandler("message-summary", this); + + // Set AppDialogSetFactory + auto_ptr<AppDialogSetFactory> dsf(new UserAgentDialogSetFactory(*mConversationManager)); + mDum.setAppDialogSetFactory(dsf); + + // Set UserAgentServerAuthManager + SharedPtr<ServerAuthManager> uasAuth( new UserAgentServerAuthManager(*this)); + mDum.setServerAuthManager(uasAuth); +} + +UserAgent::~UserAgent() +{ + shutdown(); +} + +void +UserAgent::startup() +{ + mStackThread.run(); +} + +SubscriptionHandle +UserAgent::getNewSubscriptionHandle() +{ + Lock lock(mSubscriptionHandleMutex); + return mCurrentSubscriptionHandle++; +} + +void +UserAgent::registerSubscription(UserAgentClientSubscription *subscription) +{ + mSubscriptions[subscription->getSubscriptionHandle()] = subscription; +} + +void +UserAgent::unregisterSubscription(UserAgentClientSubscription *subscription) +{ + mSubscriptions.erase(subscription->getSubscriptionHandle()); +} + +ConversationProfileHandle +UserAgent::getNewConversationProfileHandle() +{ + Lock lock(mConversationProfileHandleMutex); + return mCurrentConversationProfileHandle++; +} + +void +UserAgent::registerRegistration(UserAgentRegistration *registration) +{ + mRegistrations[registration->getConversationProfileHandle()] = registration; +} + +void +UserAgent::unregisterRegistration(UserAgentRegistration *registration) +{ + mRegistrations.erase(registration->getConversationProfileHandle()); +} + +void +UserAgent::process(int timeoutMs) +{ + mDum.process(timeoutMs); +} + +void +UserAgent::shutdown() +{ + UserAgentShutdownCmd* cmd = new UserAgentShutdownCmd(this); + mDum.post(cmd); + + // Wait for Dum to shutdown + while(!mDumShutdown) + { + process(100); + } + + mStackThread.shutdown(); + mStackThread.join(); +} + +void +UserAgent::logDnsCache() +{ + mStack.logDnsCache(); +} + +void +UserAgent::clearDnsCache() +{ + mStack.clearDnsCache(); +} + +void +UserAgent::post(ApplicationMessage& message, unsigned int ms) +{ + if(ms > 0) + { + mStack.postMS(message, ms, &mDum); + } + else + { + mDum.post(&message); + } +} + +void +UserAgent::setLogLevel(Log::Level level, LoggingSubsystem subsystem) +{ + switch(subsystem) + { + case SubsystemAll: + Log::setLevel(level); + break; + case SubsystemContents: + Log::setLevel(level, Subsystem::CONTENTS); + break; + case SubsystemDns: + Log::setLevel(level, Subsystem::DNS); + break; + case SubsystemDum: + Log::setLevel(level, Subsystem::DUM); + break; + case SubsystemSdp: + Log::setLevel(level, Subsystem::SDP); + break; + case SubsystemSip: + Log::setLevel(level, Subsystem::SIP); + break; + case SubsystemTransaction: + Log::setLevel(level, Subsystem::TRANSACTION); + break; + case SubsystemTransport: + Log::setLevel(level, Subsystem::TRANSPORT); + break; + case SubsystemStats: + Log::setLevel(level, Subsystem::STATS); + break; + case SubsystemRecon: + Log::setLevel(level, ReconSubsystem::RECON); + break; + case SubsystemFlowManager: + Log::setLevel(level, FlowManagerSubsystem::FLOWMANAGER); + break; + case SubsystemReTurn: + Log::setLevel(level, ReTurnSubsystem::RETURN); + break; + } +} + +ConversationProfileHandle +UserAgent::addConversationProfile(SharedPtr<ConversationProfile> conversationProfile, bool defaultOutgoing) +{ + ConversationProfileHandle handle = getNewConversationProfileHandle(); + AddConversationProfileCmd* cmd = new AddConversationProfileCmd(this, handle, conversationProfile, defaultOutgoing); + mDum.post(cmd); + return handle; +} + +void +UserAgent::setDefaultOutgoingConversationProfile(ConversationProfileHandle handle) +{ + SetDefaultOutgoingConversationProfileCmd* cmd = new SetDefaultOutgoingConversationProfileCmd(this, handle); + mDum.post(cmd); +} + +void +UserAgent::destroyConversationProfile(ConversationProfileHandle handle) +{ + DestroyConversationProfileCmd* cmd = new DestroyConversationProfileCmd(this, handle); + mDum.post(cmd); +} + +SubscriptionHandle +UserAgent::createSubscription(const Data& eventType, const NameAddr& target, unsigned int subscriptionTime, const Mime& mimeType) +{ + SubscriptionHandle handle = getNewSubscriptionHandle(); + CreateSubscriptionCmd* cmd = new CreateSubscriptionCmd(this, handle, eventType, target, subscriptionTime, mimeType); + mDum.post(cmd); + return handle; +} + +void +UserAgent::destroySubscription(SubscriptionHandle handle) +{ + DestroySubscriptionCmd* cmd = new DestroySubscriptionCmd(this, handle); + mDum.post(cmd); +} + + +SharedPtr<ConversationProfile> +UserAgent::getDefaultOutgoingConversationProfile() +{ + if(mDefaultOutgoingConversationProfileHandle != 0) + { + return mConversationProfiles[mDefaultOutgoingConversationProfileHandle]; + } + else + { + assert(false); + ErrLog( << "getDefaultOutgoingConversationProfile: something is wrong - no profiles to return"); + return SharedPtr<ConversationProfile>((ConversationProfile*)0); + } +} + +SharedPtr<ConversationProfile> +UserAgent::getIncomingConversationProfile(const SipMessage& msg) +{ + assert(msg.isRequest()); + + // Examine the sip message, and select the most appropriate conversation profile + + // Check if request uri matches registration contact + const Uri& requestUri = msg.header(h_RequestLine).uri(); + RegistrationMap::iterator regIt; + for(regIt = mRegistrations.begin(); regIt != mRegistrations.end(); regIt++) + { + const NameAddrs& contacts = regIt->second->getContactAddresses(); + NameAddrs::const_iterator naIt; + for(naIt = contacts.begin(); naIt != contacts.end(); naIt++) + { + InfoLog( << "getIncomingConversationProfile: comparing requestUri=" << requestUri << " to contactUri=" << (*naIt).uri()); + if((*naIt).uri() == requestUri) + { + ConversationProfileMap::iterator conIt = mConversationProfiles.find(regIt->first); + if(conIt != mConversationProfiles.end()) + { + return conIt->second; + } + } + } + } + + // Check if To header matches default from + Data toAor = msg.header(h_To).uri().getAor(); + ConversationProfileMap::iterator conIt; + for(conIt = mConversationProfiles.begin(); conIt != mConversationProfiles.end(); conIt++) + { + InfoLog( << "getIncomingConversationProfile: comparing toAor=" << toAor << " to defaultFromAor=" << conIt->second->getDefaultFrom().uri().getAor()); + if(isEqualNoCase(toAor, conIt->second->getDefaultFrom().uri().getAor())) + { + return conIt->second; + } + } + + // If can't find any matches, then return the default outgoing profile + InfoLog( << "getIncomingConversationProfile: no matching profile found, falling back to default outgoing profile"); + return getDefaultOutgoingConversationProfile(); +} + +SharedPtr<UserAgentMasterProfile> +UserAgent::getUserAgentMasterProfile() +{ + return mProfile; +} + +DialogUsageManager& +UserAgent::getDialogUsageManager() +{ + return mDum; +} + +ConversationManager* +UserAgent::getConversationManager() +{ + return mConversationManager; +} + +void +UserAgent::onDumCanBeDeleted() +{ + mDumShutdown = true; +} + +void +UserAgent::addTransports() +{ + const std::vector<UserAgentMasterProfile::TransportInfo>& transports = mProfile->getTransports(); + std::vector<UserAgentMasterProfile::TransportInfo>::const_iterator i; + for(i = transports.begin(); i != transports.end(); i++) + { + try + { + switch((*i).mProtocol) + { +#ifdef USE_SSL + case TLS: +#ifdef USE_DTLS + case DTLS: +#endif + mDum.addTransport((*i).mProtocol, (*i).mPort, (*i).mIPVersion, (*i).mIPInterface, (*i).mSipDomainname, Data::Empty, (*i).mSslType); + break; +#endif + case UDP: + case TCP: + mDum.addTransport((*i).mProtocol, (*i).mPort, (*i).mIPVersion, (*i).mIPInterface); + break; + default: + WarningLog (<< "Failed to add " << Tuple::toData((*i).mProtocol) << " transport - unsupported type"); + } + } + catch (BaseException& e) + { + WarningLog (<< "Caught: " << e); + WarningLog (<< "Failed to add " << Tuple::toData((*i).mProtocol) << " transport on " << (*i).mPort); + } + } +} + +void +UserAgent::startApplicationTimer(unsigned int timerId, unsigned int durationMs, unsigned int seqNumber) +{ + UserAgentTimeout t(*this, timerId, durationMs, seqNumber); + post(t, durationMs); +} + +void +UserAgent::onApplicationTimer(unsigned int timerId, unsigned int durationMs, unsigned int seqNumber) +{ + // Default implementation is to do nothing - application should override this +} + +void +UserAgent::onSubscriptionTerminated(SubscriptionHandle handle, unsigned int statusCode) +{ + // Default implementation is to do nothing - application should override this +} + +void +UserAgent::onSubscriptionNotify(SubscriptionHandle handle, const Data& notifyData) +{ + // Default implementation is to do nothing - application should override this +} + +void +UserAgent::shutdownImpl() +{ + mDum.shutdown(this); + + // End all subscriptions + SubscriptionMap tempSubs = mSubscriptions; // Create copy for safety, since ending Subscriptions can immediately remove themselves from map + SubscriptionMap::iterator i; + for(i = tempSubs.begin(); i != tempSubs.end(); i++) + { + i->second->end(); + } + + // Unregister all registrations + RegistrationMap tempRegs = mRegistrations; // Create copy for safety, since ending can immediately remove themselves from map + RegistrationMap::iterator j; + for(j = tempRegs.begin(); j != tempRegs.end(); j++) + { + j->second->end(); + } + + mConversationManager->shutdown(); +} + +void +UserAgent::addConversationProfileImpl(ConversationProfileHandle handle, SharedPtr<ConversationProfile> conversationProfile, bool defaultOutgoing) +{ + // Store new profile + mConversationProfiles[handle] = conversationProfile; + conversationProfile->setHandle(handle); + +#ifdef USE_SSL + // If this is the first profile ever set - then use the aor defined in it as the aor used in + // the DTLS certificate for the DtlsFactory - TODO - improve this sometime so that we can change the aor in + // the cert at runtime to equal the aor in the default conversation profile + if(!mDefaultOutgoingConversationProfileHandle) + { + mConversationManager->getFlowManager().initializeDtlsFactory(conversationProfile->getDefaultFrom().uri().getAor().c_str()); + } +#endif + + // Set the default outgoing if requested to do so, or we don't have one yet + if(defaultOutgoing || mDefaultOutgoingConversationProfileHandle == 0) + { + setDefaultOutgoingConversationProfileImpl(handle); + } + + // Register new profile + if(conversationProfile->getDefaultRegistrationTime() != 0) + { + UserAgentRegistration *registration = new UserAgentRegistration(*this, mDum, handle); + mDum.send(mDum.makeRegistration(conversationProfile->getDefaultFrom(), conversationProfile, registration)); + } +} + +void +UserAgent::setDefaultOutgoingConversationProfileImpl(ConversationProfileHandle handle) +{ + mDefaultOutgoingConversationProfileHandle = handle; +} + +void +UserAgent::destroyConversationProfileImpl(ConversationProfileHandle handle) +{ + // Remove matching registration if found + RegistrationMap::iterator it = mRegistrations.find(handle); + if(it != mRegistrations.end()) + { + it->second->end(); + } + + // Remove from ConversationProfile map + mConversationProfiles.erase(handle); + + // If this Conversation Profile was the default - select the first item in the map as the new default + if(handle == mDefaultOutgoingConversationProfileHandle) + { + ConversationProfileMap::iterator it = mConversationProfiles.begin(); + if(it != mConversationProfiles.end()) + { + setDefaultOutgoingConversationProfileImpl(it->first); + } + else + { + setDefaultOutgoingConversationProfileImpl(0); + } + } +} + +void +UserAgent::createSubscriptionImpl(SubscriptionHandle handle, const Data& eventType, const NameAddr& target, unsigned int subscriptionTime, const Mime& mimeType) +{ + // Ensure we have a client subscription handler for this event type + if(!mDum.getClientSubscriptionHandler(eventType)) + { + mDum.addClientSubscriptionHandler(eventType, this); + } + // Ensure that the request Mime type is supported in the dum profile + if(!mProfile->isMimeTypeSupported(NOTIFY, mimeType)) + { + mProfile->addSupportedMimeType(NOTIFY, mimeType); + } + + UserAgentClientSubscription *subscription = new UserAgentClientSubscription(*this, mDum, handle); + mDum.send(mDum.makeSubscription(target, getDefaultOutgoingConversationProfile(), eventType, subscriptionTime, subscription)); +} + +void +UserAgent::destroySubscriptionImpl(SubscriptionHandle handle) +{ + SubscriptionMap::iterator it = mSubscriptions.find(handle); + if(it != mSubscriptions.end()) + { + it->second->end(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Registration Handler //////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void +UserAgent::onSuccess(ClientRegistrationHandle h, const SipMessage& msg) +{ + dynamic_cast<UserAgentRegistration *>(h->getAppDialogSet().get())->onSuccess(h, msg); +} + +void +UserAgent::onFailure(ClientRegistrationHandle h, const SipMessage& msg) +{ + dynamic_cast<UserAgentRegistration *>(h->getAppDialogSet().get())->onFailure(h, msg); +} + +void +UserAgent::onRemoved(ClientRegistrationHandle h, const SipMessage&msg) +{ + dynamic_cast<UserAgentRegistration *>(h->getAppDialogSet().get())->onRemoved(h, msg); +} + +int +UserAgent::onRequestRetry(ClientRegistrationHandle h, int retryMinimum, const SipMessage& msg) +{ + return dynamic_cast<UserAgentRegistration *>(h->getAppDialogSet().get())->onRequestRetry(h, retryMinimum, msg); +} + +//////////////////////////////////////////////////////////////////////////////// +// ClientSubscriptionHandler /////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void +UserAgent::onUpdatePending(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) +{ + dynamic_cast<UserAgentClientSubscription *>(h->getAppDialogSet().get())->onUpdatePending(h, msg, outOfOrder); +} + +void +UserAgent::onUpdateActive(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) +{ + dynamic_cast<UserAgentClientSubscription *>(h->getAppDialogSet().get())->onUpdateActive(h, msg, outOfOrder); +} + +void +UserAgent::onUpdateExtension(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) +{ + dynamic_cast<UserAgentClientSubscription *>(h->getAppDialogSet().get())->onUpdateExtension(h, msg, outOfOrder); +} + +void +UserAgent::onTerminated(ClientSubscriptionHandle h, const SipMessage* msg) +{ + dynamic_cast<UserAgentClientSubscription *>(h->getAppDialogSet().get())->onTerminated(h, msg); +} + +void +UserAgent::onNewSubscription(ClientSubscriptionHandle h, const SipMessage& msg) +{ + dynamic_cast<UserAgentClientSubscription *>(h->getAppDialogSet().get())->onNewSubscription(h, msg); +} + +int +UserAgent::onRequestRetry(ClientSubscriptionHandle h, int retryMinimum, const SipMessage& msg) +{ + return dynamic_cast<UserAgentClientSubscription *>(h->getAppDialogSet().get())->onRequestRetry(h, retryMinimum, msg); +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgent.hxx b/src/libs/resiprocate/resip/recon/UserAgent.hxx new file mode 100644 index 00000000..3d08d9db --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgent.hxx @@ -0,0 +1,389 @@ +#if !defined(UserAgent_hxx) +#define UserAgent_hxx + +#include "ConversationManager.hxx" +#include "ConversationProfile.hxx" +#include "UserAgentMasterProfile.hxx" +#include "HandleTypes.hxx" + +#include <resip/stack/InterruptableStackThread.hxx> +#include <resip/dum/MasterProfile.hxx> +#include <resip/dum/RegistrationHandler.hxx> +#include <resip/dum/SubscriptionHandler.hxx> +#include <resip/dum/DumShutdownHandler.hxx> +#include <resip/dum/DialogUsageManager.hxx> +#include <rutil/SelectInterruptor.hxx> +#include <rutil/Log.hxx> +#include <rutil/SharedPtr.hxx> +#include <rutil/Mutex.hxx> + +#ifdef WIN32 + #define sleepMs(t) Sleep(t) +#else + #define sleepMs(t) usleep(t*1000) +#endif + +namespace recon +{ + +class UserAgentShutdownCmd; +class SetActiveConversationProfileCmd; +class UserAgentClientSubscription; +class UserAgentRegistration; + +/** + This class is one of two main classes of concern to an application + using the UserAgent library. This class should be subclassed by + the application and the UserAgent handlers should be implemented + by it. + + This class is responsible for handling tasks that are not directly + related to managing the Conversations themselves. All conversation + management is done via the ConversationManager class. + + This class handles tasks such as: + - Startup, Process Loop, and shutdown handling + - Handling user agent settings (UserAgentMasterProfile) + - Handling and dispatching Application Timers + - Management of Conversation Profiles and Registrations + - Management of Subscriptions + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class UserAgent : public resip::ClientRegistrationHandler, + public resip::ClientSubscriptionHandler, + public resip::DumShutdownHandler +{ +public: + + /** + Constructor + + @param conversationManager Application subclassed Conversation + Manager + @param masterProfile Object containing useragent settings + @param socketFunc A pointer to a function that will be called after a socket + in the DNS or SIP transport layers of the stack has been + created. This callback can be used to control low level + socket options, such as Quality-of-Service/DSCP. + Note: For SIP TCP sockets there is one call for the listen + socket, and one (or two) calls for each connection created + afterwards. For each inbound TCP connection the first + callback is called immediately before the socket is connected, + and if configured it is called again after the connect call + has completed and before the first data is sent out. + On some OS's you cannot set QOS until the socket is successfully + connected. To enable this behavior call: + Connection::setEnablePostConnectSocketFuncCall(); + */ + UserAgent(ConversationManager* conversationManager, resip::SharedPtr<UserAgentMasterProfile> masterProfile, resip::AfterSocketCreationFuncPtr socketFunc=0); + virtual ~UserAgent(); + + /** + Starts the SIP stack thread. + + @note This should be called before calling process() in a loop + + @warning Ensure you have added at least one Conversation Profile + with defaultOutgoing set to true before calling this. + */ + void startup(); + + /** + This should be called in a loop to give process cycles to the UserAgent. + + @param timeoutMs Will return after timeoutMs if nothing to do. + Application can do some work, but should call + process again ASAP. + */ + void process(int timeoutMs); // call this in a loop + + /** + Used to initiate a shutdown of the useragent. This function blocks + until the shutdown is complete. + + @note There should not be an active process request when this + is called. + */ + void shutdown(); + + /** + Used to initiate a snapshot of the existing DNS entries in the + cache to the logging subsystem. + */ + void logDnsCache(); + + /** + Used to clear the existing DNS entries in the cache. + */ + void clearDnsCache(); + + /** + Retrieves the ConversationManager passed in the constructor. + + @return Pointer to the conversation manager + */ + ConversationManager* getConversationManager(); + + // Utility Methods //////////////////////////////////////////////////////////// + typedef enum + { + SubsystemAll, + SubsystemContents, + SubsystemDns, + SubsystemDum, + SubsystemSdp, + SubsystemSip, + SubsystemTransaction, + SubsystemTransport, + SubsystemStats, + SubsystemRecon, + SubsystemFlowManager, + SubsystemReTurn + } LoggingSubsystem; + + /** + Static method that sets the logging level for a particular subsystem, + or all subsystems. + + @param level Logging level to set + @param subsystem Subsystem to set level on + + @note: Use UserAgent::SubsystemAll to set the logging level on all + subsystems + */ + static void setLogLevel(resip::Log::Level level, LoggingSubsystem subsystem=SubsystemAll); + + /** + Adds a Conversation Profile to be managed, by the user agent. SIP Registration + is performed, if required. + + @param conversationProfile Profile to add + @param defaultOutgoing Set to true to set this profile as the default + profile to use for outbound calls. + */ + ConversationProfileHandle addConversationProfile(resip::SharedPtr<ConversationProfile> conversationProfile, bool defaultOutgoing=true); // thread safe + + /** + Sets an existing Conversation Profile to the default profile to + use for outbound calls. + + @param handle ConversationProfile handle to use + */ + void setDefaultOutgoingConversationProfile(ConversationProfileHandle handle); + + /** + Destroys an existing Conversation Profile. SIP un-registration is + performed, if required. + + @param handle ConversationProfile handle to use + + @note If this ConversationProfile is currently the default outbound + profile, then the next profile in the list will become the default + */ + void destroyConversationProfile(ConversationProfileHandle handle); + + /** + Used by an application to start a timer that is managed by the + useragent. When the timer expires the onApplicationTimer callback + will be called. + + Applications should override this UserAgent class and callback in + order to use application timers. + + @param timerId Id representing the timers purpose + @param durationMs the duration of the timer in ms + @param seqNumber Can be used by the application to differentiate + "active" from "non-active" timers, since timers + cannot be stopped + */ + virtual void startApplicationTimer(unsigned int timerId, unsigned int durationMs, unsigned int seqNumber); + + /** + Requests that the user agent create and manage an event subscription. + When an subscribed event is received the onSubscriptionNotify callback + is used. If the subscription is terminated by the server, the application + or due to network failure the onSubscriptionTerminated callback is used. + + Applications should override this UserAgent class and callbacks in order + to use subscriptions. + + @param eventType Event type we are subscribing to + @param target A URI representing the location of the subscription server + @param subscriptionTime Requested time that the subscription should stay active, + before sending a refresh request is required. + @param mimeType The mime type of event body expected + */ + SubscriptionHandle createSubscription(const resip::Data& eventType, const resip::NameAddr& target, unsigned int subscriptionTime, const resip::Mime& mimeType); // thread safe + + /** + Destroys an existing subscriptions. Unsubscribe request is sent, + if required. + + @param handle Subscription handle to destroy + */ + void destroySubscription(SubscriptionHandle handle); + + //////////////////////////////////////////////////////////////////// + // UserAgent Handlers ////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// + + /** + Callback used when an application timer expires. + + @note An application should override this method if it uses + startApplicaitonTimer. + + @param timerId Id representing the timers purpose + @param durationMs the duration of the timer in ms + @param seqNumber Can be used by the application to differentiate + "active" from "non-active" timers, since timers + cannot be stopped + */ + virtual void onApplicationTimer(unsigned int timerId, unsigned int durationMs, unsigned int seqNumber); + + /** + Callback used when a subscription has received an event notification + from the server. + + @note An application should override this method if it uses + createSubscription. + + @param handle Subscription handle that event applies to + @param notifyData Data representation of the event received + */ + virtual void onSubscriptionNotify(SubscriptionHandle handle, const resip::Data& notifyData); + + /** + Callback used when a subscription is terminated. + + @note An application should override this method if it uses + createSubscription. + + @param handle Subscription handle that terminated + @param statusCode The status code that caused termination. If + application terminated, then statusCode will be 0. + */ + virtual void onSubscriptionTerminated(SubscriptionHandle handle, unsigned int statusCode); + +protected: + // Shutdown Handler //////////////////////////////////////////////////////////// + void onDumCanBeDeleted(); + + // Registration Handler //////////////////////////////////////////////////////// + virtual void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response); + virtual void onFailure(resip::ClientRegistrationHandle h, const resip::SipMessage& response); + virtual void onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response); + virtual int onRequestRetry(resip::ClientRegistrationHandle h, int retryMinimum, const resip::SipMessage& msg); + + // ClientSubscriptionHandler /////////////////////////////////////////////////// + virtual void onUpdatePending(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder); + virtual void onUpdateActive(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder); + virtual void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder); + virtual void onTerminated(resip::ClientSubscriptionHandle h, const resip::SipMessage* notify); + virtual void onNewSubscription(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify); + virtual int onRequestRetry(resip::ClientSubscriptionHandle h, int retryMinimum, const resip::SipMessage& notify); + +private: + friend class ConversationManager; + friend class UserAgentShutdownCmd; + friend class AddConversationProfileCmd; + friend class SetDefaultOutgoingConversationProfileCmd; + friend class DestroyConversationProfileCmd; + friend class CreateSubscriptionCmd; + friend class DestroySubscriptionCmd; + friend class MediaResourceParticipant; + + // Note: In general the following fns are not thread safe and must be called from dum process + // loop only + friend class UserAgentServerAuthManager; + friend class RemoteParticipant; + friend class DefaultDialogSet; + friend class RemoteParticipantDialogSet; + resip::SharedPtr<ConversationProfile> getDefaultOutgoingConversationProfile(); + resip::SharedPtr<ConversationProfile> getIncomingConversationProfile(const resip::SipMessage& msg); // returns the most appropriate conversation profile for the message + resip::SharedPtr<UserAgentMasterProfile> getUserAgentMasterProfile(); + resip::DialogUsageManager& getDialogUsageManager(); + + void addTransports(); + void post(resip::ApplicationMessage& message, unsigned int ms=0); + void shutdownImpl(); + void addConversationProfileImpl(ConversationProfileHandle handle, resip::SharedPtr<ConversationProfile> conversationProfile, bool defaultOutgoing=true); + void setDefaultOutgoingConversationProfileImpl(ConversationProfileHandle handle); + void destroyConversationProfileImpl(ConversationProfileHandle handle); + void createSubscriptionImpl(SubscriptionHandle handle, const resip::Data& eventType, const resip::NameAddr& target, unsigned int subscriptionTime, const resip::Mime& mimeType); + void destroySubscriptionImpl(SubscriptionHandle handle); + + // Subscription storage + friend class UserAgentClientSubscription; + typedef std::map<SubscriptionHandle, UserAgentClientSubscription *> SubscriptionMap; + SubscriptionMap mSubscriptions; + resip::Mutex mSubscriptionHandleMutex; + SubscriptionHandle mCurrentSubscriptionHandle; + SubscriptionHandle getNewSubscriptionHandle(); // thread safe + void registerSubscription(UserAgentClientSubscription *); + void unregisterSubscription(UserAgentClientSubscription *); + + // Conversation Profile Storage + typedef std::map<ConversationProfileHandle, resip::SharedPtr<ConversationProfile> > ConversationProfileMap; + ConversationProfileMap mConversationProfiles; + resip::Mutex mConversationProfileHandleMutex; + ConversationProfileHandle mCurrentConversationProfileHandle; + ConversationProfileHandle mDefaultOutgoingConversationProfileHandle; + ConversationProfileHandle getNewConversationProfileHandle(); // thread safe + + friend class UserAgentRegistration; + typedef std::map<ConversationProfileHandle, UserAgentRegistration*> RegistrationMap; + RegistrationMap mRegistrations; + void registerRegistration(UserAgentRegistration *); + void unregisterRegistration(UserAgentRegistration *); + + ConversationManager* mConversationManager; + resip::SharedPtr<UserAgentMasterProfile> mProfile; + resip::Security* mSecurity; + resip::SelectInterruptor mSelectInterruptor; + resip::SipStack mStack; + resip::DialogUsageManager mDum; + resip::InterruptableStackThread mStackThread; + volatile bool mDumShutdown; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgentClientSubscription.cxx b/src/libs/resiprocate/resip/recon/UserAgentClientSubscription.cxx new file mode 100644 index 00000000..52f594f7 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgentClientSubscription.cxx @@ -0,0 +1,183 @@ +#include "UserAgent.hxx" +#include "ReconSubsystem.hxx" +#include "UserAgentClientSubscription.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <resip/dum/DialogUsageManager.hxx> +#include <resip/dum/ClientSubscription.hxx> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +UserAgentClientSubscription::UserAgentClientSubscription(UserAgent& userAgent, DialogUsageManager& dum, unsigned int handle) +: AppDialogSet(dum), + mUserAgent(userAgent), + mDum(dum), + mSubscriptionHandle(handle), + mLastNotifyHash(0), + mEnded(false) +{ + mUserAgent.registerSubscription(this); +} + +UserAgentClientSubscription::~UserAgentClientSubscription() +{ + mUserAgent.unregisterSubscription(this); +} + +SubscriptionHandle +UserAgentClientSubscription::getSubscriptionHandle() +{ + return mSubscriptionHandle; +} + +void +UserAgentClientSubscription::end() +{ + if(!mEnded) + { + mEnded = true; + AppDialogSet::end(); + } +} + +void +UserAgentClientSubscription::notifyReceived(const Data& notifyData) +{ + size_t hash = notifyData.hash(); + if(hash != mLastNotifyHash) // only call callback if body changed from last time + { + mLastNotifyHash = hash; + mUserAgent.onSubscriptionNotify(mSubscriptionHandle, notifyData); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// ClientSubscriptionHandler /////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void +UserAgentClientSubscription::onUpdatePending(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) +{ + InfoLog(<< "onUpdatePending(ClientSubscriptionHandle): handle=" << mSubscriptionHandle << ", " << msg.brief()); + h->acceptUpdate(); + if(mEnded) + { + h->end(); + } + else if(msg.getContents()) + { + const Data& bodyData = msg.getContents()->getBodyData(); + notifyReceived(bodyData); + } +} + +void +UserAgentClientSubscription::onUpdateActive(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) +{ + InfoLog(<< "onUpdateActive(ClientSubscriptionHandle): handle=" << mSubscriptionHandle << ", " << msg.brief()); + h->acceptUpdate(); + if(mEnded) + { + h->end(); + } + else if(msg.getContents()) + { + const Data& bodyData = msg.getContents()->getBodyData(); + notifyReceived(bodyData); + } +} + +void +UserAgentClientSubscription::onUpdateExtension(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder) +{ + InfoLog(<< "onUpdateExtension(ClientSubscriptionHandle): handle=" << mSubscriptionHandle << ", " << msg.brief()); + h->acceptUpdate(); + if(mEnded) + { + h->end(); + } + else if(msg.getContents()) + { + const Data& bodyData = msg.getContents()->getBodyData(); + notifyReceived(bodyData); + } +} + +void +UserAgentClientSubscription::onTerminated(ClientSubscriptionHandle h, const SipMessage* msg) +{ + unsigned int statusCode = 0; + if(msg) + { + InfoLog(<< "onTerminated(ClientSubscriptionHandle): handle=" << mSubscriptionHandle << ", " << msg->brief()); + if(msg->isResponse()) + { + statusCode = msg->header(h_StatusLine).responseCode(); + } + else + { + if(msg->getContents()) + { + notifyReceived(msg->getContents()->getBodyData()); + } + } + } + else + { + InfoLog(<< "onTerminated(ClientSubscriptionHandle): handle=" << mSubscriptionHandle); + statusCode = 408; // timedout waiting for notify after subscribe + } + mUserAgent.onSubscriptionTerminated(mSubscriptionHandle, statusCode); +} + +void +UserAgentClientSubscription::onNewSubscription(ClientSubscriptionHandle h, const SipMessage& msg) +{ + InfoLog(<< "onNewSubscription(ClientSubscriptionHandle): handle=" << mSubscriptionHandle << ", " << msg.brief()); + // Note: The notify here, will also be passed in an onUpdateXXXX callback, so no need to do anything with this callback +} + +int +UserAgentClientSubscription::onRequestRetry(ClientSubscriptionHandle h, int retryMinimum, const SipMessage& msg) +{ + return min(retryMinimum, mUserAgent.getUserAgentMasterProfile()->subscriptionRetryInterval()); +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgentClientSubscription.hxx b/src/libs/resiprocate/resip/recon/UserAgentClientSubscription.hxx new file mode 100644 index 00000000..1e2cd5eb --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgentClientSubscription.hxx @@ -0,0 +1,91 @@ +#if !defined(UserAgentClientSubscription_hxx) +#define UserAgentClientSubscription_hxx + +#include <resip/dum/AppDialogSet.hxx> +#include <resip/dum/InviteSessionHandler.hxx> +#include <resip/dum/DialogSetHandler.hxx> +#include <resip/dum/SubscriptionHandler.hxx> + +#include "UserAgent.hxx" + +namespace resip +{ +class DialogUsageManager; +class SipMessage; +} + +namespace recon +{ +class UserAgent; + +/** + This class is used to manage active client subscriptions. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class UserAgentClientSubscription : public resip::AppDialogSet +{ + public: + UserAgentClientSubscription(UserAgent& userAgent, resip::DialogUsageManager& dum, unsigned int handle); + virtual ~UserAgentClientSubscription(); + + SubscriptionHandle getSubscriptionHandle(); + virtual void end(); + + // ClientSubscriptionHandler /////////////////////////////////////////////////// + virtual void onUpdatePending(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder); + virtual void onUpdateActive(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder); + virtual void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder); + virtual void onTerminated(resip::ClientSubscriptionHandle h, const resip::SipMessage* notify); + virtual void onNewSubscription(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify); + virtual int onRequestRetry(resip::ClientSubscriptionHandle h, int retryMinimum, const resip::SipMessage& notify); + + private: + void notifyReceived(const resip::Data& notifyData); + + UserAgent &mUserAgent; + resip::DialogUsageManager &mDum; + SubscriptionHandle mSubscriptionHandle; + size_t mLastNotifyHash; + bool mEnded; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgentCmds.hxx b/src/libs/resiprocate/resip/recon/UserAgentCmds.hxx new file mode 100644 index 00000000..cd1414bc --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgentCmds.hxx @@ -0,0 +1,212 @@ +#if !defined(ConversationManagerCmds_hxx) +#define ConversationManagerCmds_hxx + +#include <resip/dum/DumCommand.hxx> + +#include "UserAgent.hxx" + +namespace recon +{ + +/** + The classes defined here are used to pass commands from the + application thread to the UserAgent thread (process loop). + This ensures thread safety of the UserAgent methods that are + available to an application. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class UserAgentShutdownCmd : public resip::DumCommand +{ + public: + UserAgentShutdownCmd(UserAgent* userAgent) + : mUserAgent(userAgent) {} + virtual void executeCommand() + { + mUserAgent->shutdownImpl(); + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " UserAgentShutdownCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + UserAgent* mUserAgent; +}; + +class AddConversationProfileCmd : public resip::DumCommand +{ + public: + AddConversationProfileCmd(UserAgent* userAgent, + ConversationProfileHandle handle, + resip::SharedPtr<ConversationProfile> conversationProfile, + bool defaultOutgoing) + : mUserAgent(userAgent), + mHandle(handle), + mConversationProfile(conversationProfile), + mDefaultOutgoing(defaultOutgoing) {} + virtual void executeCommand() + { + mUserAgent->addConversationProfileImpl(mHandle, mConversationProfile, mDefaultOutgoing); + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " AddConversationProfileCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + UserAgent* mUserAgent; + ConversationProfileHandle mHandle; + resip::SharedPtr<ConversationProfile> mConversationProfile; + bool mDefaultOutgoing; +}; + +class SetDefaultOutgoingConversationProfileCmd : public resip::DumCommand +{ + public: + SetDefaultOutgoingConversationProfileCmd(UserAgent* userAgent, + ConversationProfileHandle handle) + : mUserAgent(userAgent), + mHandle(handle) {} + virtual void executeCommand() + { + mUserAgent->setDefaultOutgoingConversationProfileImpl(mHandle); + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " SetDefaultOutgoingConversationProfileCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + UserAgent* mUserAgent; + ConversationProfileHandle mHandle; +}; + +class DestroyConversationProfileCmd : public resip::DumCommand +{ + public: + DestroyConversationProfileCmd(UserAgent* userAgent, + ConversationProfileHandle handle) + : mUserAgent(userAgent), + mHandle(handle) {} + virtual void executeCommand() + { + mUserAgent->destroyConversationProfileImpl(mHandle); + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " DestroyConversationProfileCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + UserAgent* mUserAgent; + ConversationProfileHandle mHandle; +}; + +class UserAgentTimeout : public resip::DumCommand +{ + public: + UserAgentTimeout(UserAgent& userAgent, unsigned int timerId, unsigned int duration, unsigned int seqNumber) : + mUserAgent(userAgent), mTimerId(timerId), mDuration(duration), mSeqNumber(seqNumber) {} + UserAgentTimeout(const UserAgentTimeout& rhs) : + mUserAgent(rhs.mUserAgent), mTimerId(rhs.mTimerId), mDuration(rhs.mDuration), mSeqNumber(rhs.mSeqNumber) {} + ~UserAgentTimeout() {} + + void executeCommand() { mUserAgent.onApplicationTimer(mTimerId, mDuration, mSeqNumber); } + + resip::Message* clone() const { return new UserAgentTimeout(*this); } + EncodeStream& encode(EncodeStream& strm) const { strm << "UserAgentTimeout: id=" << mTimerId << ", duration=" << mDuration << ", seq=" << mSeqNumber; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + + unsigned int id() const { return mTimerId; } + unsigned int seqNumber() const { return mSeqNumber; } + unsigned int duration() const { return mDuration; } + + private: + UserAgent& mUserAgent; + unsigned int mTimerId; + unsigned int mDuration; + unsigned int mSeqNumber; +}; + +class CreateSubscriptionCmd : public resip::DumCommand +{ + public: + CreateSubscriptionCmd(UserAgent* userAgent, + SubscriptionHandle handle, + const resip::Data& eventType, + const resip::NameAddr& target, + unsigned int subscriptionTime, + const resip::Mime& mimeType) + : mUserAgent(userAgent), + mHandle(handle), + mEventType(eventType), + mTarget(target), + mSubscriptionTime(subscriptionTime), + mMimeType(mimeType) {} + virtual void executeCommand() + { + mUserAgent->createSubscriptionImpl(mHandle, mEventType, mTarget, mSubscriptionTime, mMimeType); + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " CreateSubscriptionCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + UserAgent* mUserAgent; + SubscriptionHandle mHandle; + resip::Data mEventType; + resip::NameAddr mTarget; + unsigned int mSubscriptionTime; + resip::Mime mMimeType; +}; + +class DestroySubscriptionCmd : public resip::DumCommand +{ + public: + DestroySubscriptionCmd(UserAgent* userAgent, + SubscriptionHandle handle) + : mUserAgent(userAgent), + mHandle(handle) {} + virtual void executeCommand() + { + mUserAgent->destroySubscriptionImpl(mHandle); + } + resip::Message* clone() const { assert(0); return 0; } + EncodeStream& encode(EncodeStream& strm) const { strm << " DestroySubscriptionCmd: "; return strm; } + EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); } + private: + UserAgent* mUserAgent; + SubscriptionHandle mHandle; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgentDialogSetFactory.cxx b/src/libs/resiprocate/resip/recon/UserAgentDialogSetFactory.cxx new file mode 100644 index 00000000..ab127ff7 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgentDialogSetFactory.cxx @@ -0,0 +1,73 @@ +#include "ConversationManager.hxx" +#include "ReconSubsystem.hxx" +#include "UserAgentDialogSetFactory.hxx" +#include "RemoteParticipant.hxx" +#include "DefaultDialogSet.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <resip/stack/SipMessage.hxx> +#include <resip/dum/AppDialogSet.hxx> +#include <rutil/WinLeakCheck.hxx> + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +using namespace recon; +using namespace resip; +using namespace std; + + +UserAgentDialogSetFactory::UserAgentDialogSetFactory(ConversationManager& conversationManager) : + mConversationManager(conversationManager) +{ +} + +AppDialogSet* +UserAgentDialogSetFactory::createAppDialogSet(DialogUsageManager& dum, + const SipMessage& msg) +{ + switch(msg.method()) + { + case INVITE: + return new RemoteParticipantDialogSet(mConversationManager); + break; + default: + return new DefaultDialogSet(mConversationManager); + break; + } +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgentDialogSetFactory.hxx b/src/libs/resiprocate/resip/recon/UserAgentDialogSetFactory.hxx new file mode 100644 index 00000000..d8ca23ee --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgentDialogSetFactory.hxx @@ -0,0 +1,70 @@ +#if !defined(UserAgentDialogSetFactory_hxx) +#define UserAgentDialogSetFactory_hxx + +#include <resip/dum/AppDialogSetFactory.hxx> + +namespace resip +{ + class AppDialogSet; + class DialogUsageManager; + class SipMessage; +} + +namespace recon +{ + class ConversationManager; + +/** + This class is used to manage the creation of RemoteParticipant + objects. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class UserAgentDialogSetFactory : public resip::AppDialogSetFactory +{ +public: + UserAgentDialogSetFactory(ConversationManager& conversationManager); + resip::AppDialogSet* createAppDialogSet(resip::DialogUsageManager&, + const resip::SipMessage&); +private: + ConversationManager& mConversationManager; +}; + +} +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgentMasterProfile.cxx b/src/libs/resiprocate/resip/recon/UserAgentMasterProfile.cxx new file mode 100644 index 00000000..148edf24 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgentMasterProfile.cxx @@ -0,0 +1,169 @@ +#include <resip/stack/Tuple.hxx> + +#include "ReconSubsystem.hxx" +#include "UserAgentMasterProfile.hxx" + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +UserAgentMasterProfile::UserAgentMasterProfile() +: mStatisticsManagerEnabled(false), + mRTPPortRangeMin(16384), + mRTPPortRangeMax(17385), + mSubscriptionRetryInterval(60) +{ +#ifdef WIN32 + mCertPath = "."; +#else + mCertPath = getenv("HOME"); + mCertPath += "/.sipCerts/"; +#endif +} + +void +UserAgentMasterProfile::addTransport( TransportType protocol, + int port, + IpVersion version, + const Data& ipInterface, + const Data& sipDomainname, + SecurityTypes::SSLType sslType) +{ + TransportInfo info; + + info.mProtocol = protocol; + info.mPort = port; + info.mIPVersion = version; + info.mIPInterface = ipInterface; + info.mSipDomainname = sipDomainname; + info.mSslType = sslType; + + mTransports.push_back(info); +} + +const std::vector<UserAgentMasterProfile::TransportInfo>& +UserAgentMasterProfile::getTransports() const +{ + return mTransports; +} + +void +UserAgentMasterProfile::addEnumSuffix( const Data& enumSuffix) +{ + mEnumSuffixes.push_back(enumSuffix); +} + +const std::vector<Data>& +UserAgentMasterProfile::getEnumSuffixes() const +{ + return mEnumSuffixes; +} + +void +UserAgentMasterProfile::addAdditionalDnsServer( const Data& dnsServerIPAddress) +{ + mAdditionalDnsServers.push_back(Tuple(dnsServerIPAddress, 0, UNKNOWN_TRANSPORT).toGenericIPAddress()); +} + +const DnsStub::NameserverList& +UserAgentMasterProfile::getAdditionalDnsServers() const +{ + return mAdditionalDnsServers; +} + +Data& +UserAgentMasterProfile::certPath() +{ + return mCertPath; +} + +const Data +UserAgentMasterProfile::certPath() const +{ + return mCertPath; +} + +bool& +UserAgentMasterProfile::statisticsManagerEnabled() +{ + return mStatisticsManagerEnabled; +} + +const bool +UserAgentMasterProfile::statisticsManagerEnabled() const +{ + return mStatisticsManagerEnabled; +} + +unsigned short& +UserAgentMasterProfile::rtpPortRangeMin() +{ + return mRTPPortRangeMin; +} + +const unsigned short +UserAgentMasterProfile::rtpPortRangeMin() const +{ + return mRTPPortRangeMin; +} + +unsigned short& +UserAgentMasterProfile::rtpPortRangeMax() +{ + return mRTPPortRangeMax; +} + +const unsigned short +UserAgentMasterProfile::rtpPortRangeMax() const +{ + return mRTPPortRangeMax; +} + +int& +UserAgentMasterProfile::subscriptionRetryInterval() +{ + return mSubscriptionRetryInterval; +} + +const int +UserAgentMasterProfile::subscriptionRetryInterval() const +{ + return mSubscriptionRetryInterval; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgentMasterProfile.hxx b/src/libs/resiprocate/resip/recon/UserAgentMasterProfile.hxx new file mode 100644 index 00000000..779485fd --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgentMasterProfile.hxx @@ -0,0 +1,200 @@ +#if !defined(UserAgentMasterProfile_hxx) +#define UserAgentMasterProfile_hxx + +#include <rutil/TransportType.hxx> +#include <rutil/dns/DnsStub.hxx> +#include <resip/stack/SecurityTypes.hxx> +#include <resip/dum/MasterProfile.hxx> +#include <vector> + +namespace recon +{ + +/** + This class extends the resip MasterProfile to include UserAgent + specific settings. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class UserAgentMasterProfile : public resip::MasterProfile +{ +public: + UserAgentMasterProfile(); + + class TransportInfo + { + public: + resip::TransportType mProtocol; + int mPort; + resip::IpVersion mIPVersion; + resip::Data mIPInterface; + resip::Data mSipDomainname; + resip::SecurityTypes::SSLType mSslType; + }; + + /** + Adds a network transport to use for send/receiving SIP messages. + + @note This MUST be called before the UserAgent is created + + @param protocol Transport type: UDP,TCP or TLS + @param port UDP or TCP port to listen on + @param version IP Version: V4 or V6 + @param ipInterface IP Interface to bind to - empty string + binds to all interfaces + @param sipDomainname TLS Domain name - only used if protocol + is TLS + @param sslType SSLv23 vs TLSv1 - only use if protocol is TLS + */ + void addTransport( resip::TransportType protocol, + int port, + resip::IpVersion version=resip::V4, + const resip::Data& ipInterface = resip::Data::Empty, + const resip::Data& sipDomainname = resip::Data::Empty, // TLS only + resip::SecurityTypes::SSLType sslType = resip::SecurityTypes::TLSv1 ); + + /** + Gets a vector of the transports previously added. + + @return Reference to a vector of TransportInfo's + */ + const std::vector<TransportInfo>& getTransports() const; + + /** + Adds a domain suffix used in ENUM DNS queries. + For example: e164.arpa + + @note This MUST be called before the UserAgent is created + + @param enumSuffix ENUM Domain suffix to add + */ + void addEnumSuffix(const resip::Data& enumSuffix); + + /** + Gets a vector of the ENUM domain suffixes previously added. + + @return Reference to a vector of ENUM domain suffixes + */ + const std::vector<resip::Data>& getEnumSuffixes() const; + + /** + Adds an additional DNS server to ones that are attempted + to be discovered by the SIP stack. + + @note This MUST be called before the UserAgent is created + + @param dnsServerIPAddress IP Address of DNS server to add + */ + void addAdditionalDnsServer(const resip::Data& dnsServerIPAddress); + + /** + Gets a vector of the DNS Servers previously added. + + @note This does not include DNS servers detected by the stack + + @return Reference to a vector of DNS server IP Addresses + */ + const resip::DnsStub::NameserverList& getAdditionalDnsServers() const; + + /** + Get/Set the location where the SIP stack will look for X509 + certificates + + @note This MUST be called before the UserAgent is created + + @return Data cert path location + */ + virtual resip::Data& certPath(); + virtual const resip::Data certPath() const; + + /** + Get/Set wether SIP message statistics are send to logging subsystem + + @return bool Set to true to enable statistics + */ + virtual bool& statisticsManagerEnabled(); + virtual const bool statisticsManagerEnabled() const; + + /** + Get/Set the starting port number in the range of valid port + numbers to be used for RTP traffic. + + @note This MUST be called before the UserAgent is created + + @return unsigned short range min + */ + virtual unsigned short& rtpPortRangeMin(); + virtual const unsigned short rtpPortRangeMin() const; + + /** + Get/Set the ending port number in the range of valid port + numbers to be used for RTP traffic. + + @note This MUST be called before the UserAgent is created + + @return unsigned short range max + */ + virtual unsigned short& rtpPortRangeMax(); + virtual const unsigned short rtpPortRangeMax() const; + + /** + Get/Set the interval at which subscriptions are retried if + they fail (if one is not suggested in the failure). + + @note This MUST be called before the UserAgent is created + + @return int subscription retry interval in seconds + */ + virtual int& subscriptionRetryInterval(); + virtual const int subscriptionRetryInterval() const; + +private: + resip::Data mCertPath; + bool mStatisticsManagerEnabled; + std::vector<TransportInfo> mTransports; + std::vector<resip::Data> mEnumSuffixes; + resip::DnsStub::NameserverList mAdditionalDnsServers; + unsigned short mRTPPortRangeMin; + unsigned short mRTPPortRangeMax; + int mSubscriptionRetryInterval; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgentRegistration.cxx b/src/libs/resiprocate/resip/recon/UserAgentRegistration.cxx new file mode 100644 index 00000000..f8626ff6 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgentRegistration.cxx @@ -0,0 +1,165 @@ +#include "UserAgent.hxx" +#include "ReconSubsystem.hxx" +#include "UserAgentRegistration.hxx" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <resip/dum/DialogUsageManager.hxx> +#include <resip/dum/ClientRegistration.hxx> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +UserAgentRegistration::UserAgentRegistration(UserAgent& userAgent, DialogUsageManager& dum, unsigned int handle) +: AppDialogSet(dum), + mUserAgent(userAgent), + mDum(dum), + mConversationProfileHandle(handle), + mEnded(false) +{ + mUserAgent.registerRegistration(this); +} + +UserAgentRegistration::~UserAgentRegistration() +{ + mUserAgent.unregisterRegistration(this); +} + +ConversationProfileHandle +UserAgentRegistration::getConversationProfileHandle() +{ + return mConversationProfileHandle; +} + +void +UserAgentRegistration::end() +{ + if(!mEnded) + { + mEnded = true; + if(mRegistrationHandle.isValid()) + { + try + { + // If ended - then just shutdown registration - likely due to shutdown + mRegistrationHandle->end(); + } + catch(BaseException&) + { + // If end() call is nested - it will throw - catch here so that processing continues normally + } + } + } +} + +const NameAddrs& +UserAgentRegistration::getContactAddresses() +{ + static NameAddrs empty; + if(mRegistrationHandle.isValid()) + { + return mRegistrationHandle->allContacts(); // .slg. note: myContacts is not sufficient, since they do not contain the stack populated transport address + } + else + { + return empty; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Registration Handler //////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void +UserAgentRegistration::onSuccess(ClientRegistrationHandle h, const SipMessage& msg) +{ + InfoLog(<< "onSuccess(ClientRegistrationHandle): " << msg.brief()); + if(!mEnded) + { + mRegistrationHandle = h; + } + else + { + try + { + // If ended - then just shutdown registration - likely due to shutdown + h->end(); + } + catch(BaseException&) + { + // If end() call is nested - it will throw - catch here so that processing continues normally + } + } +} + +void +UserAgentRegistration::onFailure(ClientRegistrationHandle h, const SipMessage& msg) +{ + InfoLog(<< "onFailure(ClientRegistrationHandle): " << msg.brief()); + if(!mEnded) + { + mRegistrationHandle = h; + } + else + { + try + { + // If we don't have a handle - then just shutdown registration - likely due to shutdown + h->end(); + } + catch(BaseException&) + { + // If end() call is nested - it will throw - catch here so that processing continues normally + } + } +} + +void +UserAgentRegistration::onRemoved(ClientRegistrationHandle h, const SipMessage&msg) +{ + InfoLog(<< "onRemoved(ClientRegistrationHandle): " << msg.brief()); +} + +int +UserAgentRegistration::onRequestRetry(ClientRegistrationHandle h, int retryMinimum, const SipMessage& msg) +{ + InfoLog(<< "onRequestRetry(ClientRegistrationHandle): " << msg.brief()); + return -1; // Let Profile retry setting take effect +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgentRegistration.hxx b/src/libs/resiprocate/resip/recon/UserAgentRegistration.hxx new file mode 100644 index 00000000..4406ba85 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgentRegistration.hxx @@ -0,0 +1,89 @@ +#if !defined(UserAgentRegistration_hxx) +#define UserAgentRegistration_hxx + +#include <resip/dum/AppDialogSet.hxx> +#include <resip/dum/InviteSessionHandler.hxx> +#include <resip/dum/DialogSetHandler.hxx> +#include <resip/dum/SubscriptionHandler.hxx> + +#include "UserAgent.hxx" + +namespace resip +{ +class DialogUsageManager; +class SipMessage; +} + +namespace recon +{ +class UserAgent; + +/** + This class is used to manage active SIP registrations. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class UserAgentRegistration : public resip::AppDialogSet +{ + public: + UserAgentRegistration(UserAgent& userAgent, resip::DialogUsageManager& dum, unsigned int handle); + virtual ~UserAgentRegistration(); + + ConversationProfileHandle getConversationProfileHandle(); + virtual void end(); + + const resip::NameAddrs& getContactAddresses(); + + // Registration Handler //////////////////////////////////////////////////////// + virtual void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response); + virtual void onFailure(resip::ClientRegistrationHandle h, const resip::SipMessage& response); + virtual void onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response); + virtual int onRequestRetry(resip::ClientRegistrationHandle h, int retryMinimum, const resip::SipMessage& msg); + + private: + UserAgent &mUserAgent; + resip::DialogUsageManager &mDum; + ConversationProfileHandle mConversationProfileHandle; + bool mEnded; + resip::ClientRegistrationHandle mRegistrationHandle; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgentServerAuthManager.cxx b/src/libs/resiprocate/resip/recon/UserAgentServerAuthManager.cxx new file mode 100644 index 00000000..d5333c82 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgentServerAuthManager.cxx @@ -0,0 +1,149 @@ +#include <cassert> + +#include "UserAgent.hxx" +#include "UserAgentServerAuthManager.hxx" + +#include <resip/dum/DialogUsageManager.hxx> +#include <resip/dum/ServerAuthManager.hxx> +#include <resip/dum/UserAuthInfo.hxx> +#include <resip/dum/UserProfile.hxx> +#include <rutil/MD5Stream.hxx> +#include <rutil/WinLeakCheck.hxx> + +#define RESIPROCATE_SUBSYSTEM Subsystem::RECON + +using namespace recon; +using namespace resip; + +UserAgentServerAuthManager::UserAgentServerAuthManager(UserAgent& userAgent) : + ServerAuthManager(userAgent.getDialogUsageManager(), userAgent.getDialogUsageManager().dumIncomingTarget()), + mUserAgent(userAgent) +{ +} + +UserAgentServerAuthManager::~UserAgentServerAuthManager() +{ +} + +bool +UserAgentServerAuthManager::useAuthInt() const +{ + return true; +} + +bool +UserAgentServerAuthManager::proxyAuthenticationMode() const +{ + return false; // Challenge with 401 +} + +const Data& +UserAgentServerAuthManager::getChallengeRealm(const SipMessage& msg) +{ + return mUserAgent.getIncomingConversationProfile(msg)->getDefaultFrom().uri().host(); +} + +bool +UserAgentServerAuthManager::isMyRealm(const Data& realm) +{ + return true; // .slg. this means we will try to find credentials for any authorization headers + // could improve this by looking through all active conversation profiles to see if realm exists +} + +bool +UserAgentServerAuthManager::authorizedForThisIdentity(const resip::Data &user, + const resip::Data &realm, + resip::Uri &fromUri) +{ + return true; // We don't care who the request came from +} + +ServerAuthManager::AsyncBool +UserAgentServerAuthManager::requiresChallenge(const SipMessage& msg) +{ + assert(msg.isRequest()); + ConversationProfile* profile = mUserAgent.getIncomingConversationProfile(msg).get(); + + // We want to challenge OOD Refer requests and Invite Requests with Auto-Answer indications + switch(msg.method()) + { + case REFER: + if(profile->challengeOODReferRequests() && !msg.header(h_To).exists(p_tag)) + { + // Don't challenge OOD Refer requests have a valid TargetDialog header + if(!msg.exists(h_TargetDialog) || mUserAgent.getDialogUsageManager().findInviteSession(msg.header(h_TargetDialog)).first == InviteSessionHandle::NotValid()) + { + return True; + } + } + break; + + case INVITE: + if(profile->challengeAutoAnswerRequests() && profile->shouldAutoAnswer(msg)) + { + return True; + } + break; + default: + break; + } + + // Default to not challenge + return False; +} + +void +UserAgentServerAuthManager::requestCredential(const Data& user, + const Data& realm, + const SipMessage& msg, + const Auth& auth, + const Data& transactionId ) +{ + const UserProfile::DigestCredential& digestCredential = + mUserAgent.getIncomingConversationProfile(msg)->getDigestCredential(realm); + + MD5Stream a1; + a1 << digestCredential.user + << Symbols::COLON + << digestCredential.realm + << Symbols::COLON + << digestCredential.password; + a1.flush(); + UserAuthInfo* userAuthInfo = new UserAuthInfo(user,realm,a1.getHex(),transactionId); + mUserAgent.getDialogUsageManager().post( userAuthInfo ); +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/UserAgentServerAuthManager.hxx b/src/libs/resiprocate/resip/recon/UserAgentServerAuthManager.hxx new file mode 100644 index 00000000..0667c03d --- /dev/null +++ b/src/libs/resiprocate/resip/recon/UserAgentServerAuthManager.hxx @@ -0,0 +1,91 @@ +#if !defined(UserAgentServerAuthManager_hxx) +#define UserAgentServerAuthManager_hxx + +#include <map> + +#include <resip/stack/Auth.hxx> +#include <resip/stack/Message.hxx> +#include <resip/dum/UserProfile.hxx> +#include <resip/dum/ServerAuthManager.hxx> + +namespace recon +{ +class UserAgent; + +/** + This class is used to provide server digest authentication + capabilities. It uses the profile settings in order to determine + if a SIP request should be challenged or not, and challenges + appropriately. + + It is used to challenge auto-answer requests and OOD refer + requests. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class UserAgentServerAuthManager: public resip::ServerAuthManager +{ + public: + UserAgentServerAuthManager(UserAgent& userAgent); + ~UserAgentServerAuthManager(); + + protected: + // this call back should async cause a post of UserAuthInfo + virtual void requestCredential(const resip::Data& user, + const resip::Data& realm, + const resip::SipMessage& msg, + const resip::Auth& auth, + const resip::Data& transactionId ); + + virtual bool useAuthInt() const; + virtual bool proxyAuthenticationMode() const; + virtual const resip::Data& getChallengeRealm(const resip::SipMessage& msg); + virtual bool isMyRealm(const resip::Data& realm); + virtual bool authorizedForThisIdentity(const resip::Data &user, + const resip::Data &realm, + resip::Uri &fromUri); + virtual AsyncBool requiresChallenge(const resip::SipMessage& msg); + + private: + UserAgent& mUserAgent; +}; + +} + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/doc/ConvManSequence.pdf b/src/libs/resiprocate/resip/recon/doc/ConvManSequence.pdf new file mode 100644 index 00000000..50339614 Binary files /dev/null and b/src/libs/resiprocate/resip/recon/doc/ConvManSequence.pdf differ diff --git a/src/libs/resiprocate/resip/recon/doc/ConvManSequence.png b/src/libs/resiprocate/resip/recon/doc/ConvManSequence.png new file mode 100644 index 00000000..0837213e Binary files /dev/null and b/src/libs/resiprocate/resip/recon/doc/ConvManSequence.png differ diff --git a/src/libs/resiprocate/resip/recon/doc/ConvManSequence.vsd b/src/libs/resiprocate/resip/recon/doc/ConvManSequence.vsd new file mode 100644 index 00000000..8d645385 Binary files /dev/null and b/src/libs/resiprocate/resip/recon/doc/ConvManSequence.vsd differ diff --git a/src/libs/resiprocate/resip/recon/doc/Conversation Manager API.doc b/src/libs/resiprocate/resip/recon/doc/Conversation Manager API.doc new file mode 100644 index 00000000..f99c901f Binary files /dev/null and b/src/libs/resiprocate/resip/recon/doc/Conversation Manager API.doc differ diff --git a/src/libs/resiprocate/resip/recon/doc/Conversation_Manager_API.doc b/src/libs/resiprocate/resip/recon/doc/Conversation_Manager_API.doc new file mode 100644 index 00000000..f99c901f Binary files /dev/null and b/src/libs/resiprocate/resip/recon/doc/Conversation_Manager_API.doc differ diff --git a/src/libs/resiprocate/resip/recon/readme.txt b/src/libs/resiprocate/resip/recon/readme.txt new file mode 100644 index 00000000..558ab4f8 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/readme.txt @@ -0,0 +1,307 @@ +Backgound Information on Conversation Manager +--------------------------------------------- + +The Conversation Manager is a VoIP API that allows conversations and participants +to be created. Participants can then be placed into conversations. In general +all participants belonging to the same conversation can be heard and hear each +other. A participants contribution level to a particular conversation can be +modified such that they appear quiter or louder to other participants. + +There are three types of participants: +1. Local participant - this participant type consists of the default local speaker and + microphone of the computer that is running the testUA console. Local + participants are always only explicitly destroyed. +2. Media participant - this participant type consists of an audio file, audio stream, + or tone played out. Media participants are destroyed when the file or tone output is + complete. +3. Remote Participant - this participant type uses audio from an external source. The + current implementation uses SIP to create/connect to remote participants. Remote + participants are destroyed by the API user, or a "hangup" signal from the + remote party. + +A typical phone conversation consists of 3 components: 1 conversation, 1 local participant +and 1 remote participant. + + +Some Existing Limitations with sipX media Integration +----------------------------------------------------- +1. In order get bridge mixer capabilities across all conversations, one sipX media + interface was used for all conversations created. This has the following limitations: + + a. The sipX compiled default is to allow 10 connections per media interface. Thus there + is currently a limit of 7 remote participants in recon. + + Note: When Bridge In/Outputs are set to 10, 3 of the bridge connections are used for + the local speaker/mic, the file player and the tone player, so their are 7 left + for remote participants. + + The compile time flag: DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10 + can be used to change this maximum - it must be defined for both the recon and the + sipXmediaLib projects. + + b. The default topology media interface has one tone player and one file player, thus + only one media participant of each type can exist at a time. For example, if you + create a media participant that is playing a file, and before it is finished, you + create a second media participant that is playing a file, then the output from the + second media participant will override the first and both media participants will + be destroyed when the second file has completed playing. + +2. The newer Topology Graph interface is used in recon to get Bridge Mixing support. The + following is a list of features that have either been deprecated or are not yet + implemented in this interface. + + a. Streaming media from an http URL has been deperecated - thus http URLs are not + supported in the createMediaParticipant interface. + + b. When playing media tones and files, the local-only and remote-only flags have not + yet been implemented, and will not currently work. + + + +SRTP Implementation Notes +------------------------- + +http://tools.ietf.org/html/draft-ietf-sip-dtls-srtp-framework +http://www.faqs.org/rfcs/rfc3711.html +http://tools.ietf.org/id/draft-ietf-mmusic-sdescriptions-12.txt + +SDES Implementation Notes: +- default offer crypto suite is AES_CM_128_HMAC_SHA1_80 +- secure media required setting: + enabled: then SAVP transport protocol is signalled in SDP offers, + disabled: then AVP transport portocol is signalled in SDP offers and encryption=optional attribute is added +- No f8 crypto suite - libsrtp limitation +- no MKI implementation +- no custom master key lifetime implementation +- no master key lifetime, re-keying when expired +- no Key Derivation Rate (KDR) implementation - libsrtp limitation +- no support for SDES SRTP Session parameters: Unencrypted/Unauthenticated, FEC_ORDER, FEC_KEY, WSH + +DTLS Implementation Notes: +1. Only SHA-1 fingerprint is supported (not SHA-224, SHA-256, SHA-384, SHA-512, MD5 or MD2) +2. Passive side must do a STUN connectivity check - text in draft is inconsistent +3. Does not currently require that Identity header be present/validated. + + + +Setting up build environment: +----------------------------- +1. Go to directory where you want to create build env. +2. svn checkout https://svn.resiprocate.org/rep/resiprocate/main resip +3. svn checkout https://scm.sipfoundry.org/rep/sipX/main sipXtapi +4. cd resip/contrib +5. svn checkout https://svn.resiprocate.org/rep/resiprocate/contrib/dtls-srtp/openssl openssl + +Note: sipXtapi SVN repository has recently changed locations from: + https://scm.sipfoundry.org/rep/sipX/branches/sipXtapi to + https://scm.sipfoundry.org/rep/sipX/main. If you are migrating a local + check out use the following command, or TortoiseSVN, to update your local + copy to the new location: + svn switch https://scm.sipfoundry.org/rep/sipX/main + +Note: Ensure you use at least SVN revision 11413 of sipXtapi. + +/resip/ <- https://svn.resiprocate.org/rep/resiprocate/main +/resip/contrib/openssl <- https://svn.resiprocate.org/rep/resiprocate/contrib/dtls-srtp/openssl +/resip/contrib/boost_1_34_1 <- BOOST 1.34.1 (required in this location for Windows builds only) +/sipXtapi <- https://scm.sipfoundry.org/rep/sipX/branches/sipXtapi + + +Building dtls-srtp version of OpenSSL on Windows +------------------------------------------------ +recon currently uses a branch of OpenSSL that contains modification to do dtls-srtp. + +/resip/contrib/openssl <- https://svn.resiprocate.org/rep/resiprocate/contrib/dtls-srtp/openssl + +You will need ActiveState Perl, available from http://www.activestate.com/ActivePerl - there +is a free version available for download. + +To build openSSL for windows using VS2003: +1. Use VS2003 Command Prompt window - Note: 0.9.8g will not build + Crypto ASM fns with VS2003 MASM - we will build openssl with no ASM +2. From openssl root run: perl Configure VC-WIN32 enable-tlsext +3. Run: perl util\mkfiles.pl >MINFO +4. Run: perl util\mk1mf.pl no-asm debug VC-WIN32 > d32.mak +5. Run: perl util\mk1mf.pl no-asm VC-WIN32 > 32.mak +6. Run: nmake -f d32.mak +7. Run: nmake -f 32.mak + +To build openSSL for windows using VS2005: +1. Use VS2005 Command Prompt window +2. From openssl root run: perl Configure VC-WIN32 enable-tlsext +3. Run: ms\do_masm +4. Run: perl util\mkfiles.pl >MINFO +5. Run: perl util\mk1mf.pl debug VC-WIN32 > d32.mak +6. Run: perl util\mk1mf.pl VC-WIN32 > 32.mak +7. Run: nmake -f d32.mak +8. Run: nmake -f 32.mak + + +Building recon on Windows +------------------------- +1. Ensure the build environment is setup as indicated above. +2. Use the recon_7_1.sln Visual Studio 2003 or recon_8_0.sln Visual Studio 2005 + solution file +3. Open the sipXmediaAdapterLib project settings and enable the following defines: + DISABLE_DEFAULT_PHONE_MEDIA_INTERFACE_FACTORY + ENABLE_TOPOLOGY_FLOWGRAPH_INTERFACE_FACTORY + by removing the 'xx' characters from the Preprocessor defines. + You should do this for both Debug and Release project settings. +4. Open the sipXmediaAdapterLib and sipXmediaLib project settings and add the + following define: DISABLE_STREAM_PLAYER to the Preprocessor defines. + You should do this for both Debug and Release project settings. +5. Provide an include path to pcre for the sipXmediaLib projects by doing one + of the following: + - Modify your base Visual Studio settings for include paths - add an include + path to \resip\contrib\pcre + - Modify the Additional Include Directories settings of the sipXmediaAdapterLib, + sipXmedaLib and sipXportLib projects to include: ";..\..\resip\contrib\pcre" +6. Build solution. + + +Running on Windows +------------------ +A note on testUA executable requirements: +By default you will be able to run testUA from the VS debugger, but if you decide +to run testUA.exe on another machine you will need the following: +- codec_*.dll from sipXtapi/sipXmediaLib/bin directory +- ca.pem file in working directory - contains acceptable root certificate authority (CA) + certificates for TURN over TLS +- VS 2003/2005 - C-runtime libaries present on the destination system + + + + +Building sipXtapi on Generic Linux +---------------------------------- +Note: sipXtackLib is no longer required with the addition of the DISABLE_STREAM_PLAYER define +1. Go to sipXtapi root +2. To build sipXportLib: + cd sipXtapi/sipXportLib + autoreconf -fi + ./configure --prefix=/tmp/stage + make +3. To build sipXsdpLib: + cd sipXtapi/sipXsdpLib + autoreconf -fi + ./configure --prefix=/tmp/stage + make +4. To build sipXmediaLib: + cd sipXtapi/sipXmediaLib + autoreconf -fi + ./configure --prefix=/tmp/stage --enable-local-audio --disable-stream-player + make +5. To build sipXmediaAdapterLib: + cd sipXtapi/sipXmediaAdapterLib + autoreconf -fi + ./configure --prefix=/tmp/stage --enable-topology-graph --disable-stream-player + make + + +Building recon on Generic Linux +------------------------------- +1. Ensure the build environment is setup as indicated above. +2. Build sipXtapi as described above first. +3. If you don't need to cross compile openssl - proceed to step 4, otherwise: + Go to resip/contrib/openssl + ./Configure {place-target-platform-here} --openssldir=/usr enable-tlsext + make depend + make +4. Go to resip/ +5. ./configure + - answer 'yes' to prompt to build reCon - Conversation Manager + - make sure you enter the path to the dtls-srtp version of OpenSSL when it asks + (ie: ....resip/contrib/openssl) +6. make + + +Running testua on Generic Linux +------------------------------- +1. Go to resip/resip/recon/test +2. To run testUA ensure the codec plugins are in the same directory as the executable: + cp ../../../../sipXtapi/sipXmediaLib/bin/*.so ./ +3. ca.pem file in working directory - contains acceptable root certificate authority + (CA) certificates for TURN over TLS +4. ./testUA + + + +TODO List +--------- +In order for recon to appeal to the widest audience possible, some changes +should be made in order to provide a better layer between the underlying +media stack (currently sipXtapi) and the Conversation Manager. The following +task is required: + +Provide a media access API/thin layer so that sipX API's are not accessed directly +from different areas in recon source code. Currently sipX API's are accessed +in the following locations: + + ConversationManager.cxx - contains main sipXmediaFactory and sipXmediaInterface - the interface into sipX library + - createMediaInterface + - setVolume + - setMicrophoneGain + - muteMicrophone + - enableEchoCancel + - enableAutoGainControl + - enableNoiseReduction + + BridgeMixer.cxx - API's to control the sipX bridge mixing matrix + - setMixWeightsForOutput + - setMixWeightsForInput + + MediaResourceParticipant.cxx - API's to play tones, files, media + - start/stopTone + - start/stopAudio + - playBuffer + - createPlayer (deprecated in latest sipX) + + RemoteParticipantDialogSet - API's to create local socket/connection + - create/deleteConnection + - getCapabilities + - getConnectionPortOnBridge + + RemoteParticipant.cxx - API's to start/stop RTP + - setConnectionDestination + - start/stopRtpSend + - start/stopRtpReceive + - isReceivingRtpAudio + - isSendingRtpAudio + + +License +------- + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/recon_10_0.sln b/src/libs/resiprocate/resip/recon/recon_10_0.sln new file mode 100644 index 00000000..491d3669 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/recon_10_0.sln @@ -0,0 +1,151 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recon", "recon_10_0.vcxproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\..\rutil\dns\ares\ares_10_0.vcxproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\..\rutil\rutil_10_0.vcxproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resiprocate", "..\stack\resiprocate_10_0.vcxproj", "{2A8BE839-6466-4001-B224-8F1C3168D04A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dum", "..\dum\dum_10_0.vcxproj", "{31B0654F-E08E-405F-909F-80F86CB14B9D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reflow", "..\..\reflow\reflow_10_0.vcxproj", "{D2AB531B-86AC-43DD-A330-9809B4F1BB53}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcre", "..\..\contrib\pcre\pcre_10_0.vcxproj", "{B933F895-8EFB-4FDD-A46D-09B8C00D1D26}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnClient", "..\..\reTurn\client\reTurnClient_10_0.vcxproj", "{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXportLib-msvc8", "..\..\..\sipXtapi\sipXportLib\sipXportLib-msvc8.vcxproj", "{14631055-9D3F-47E5-B6A7-16BFC0CC8091}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXsdpLib-msvc8", "..\..\..\sipXtapi\sipXsdpLib\sipXsdpLib-msvc8.vcxproj", "{E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXmediaAdapterLib-msvc8", "..\..\..\sipXtapi\sipXmediaAdapterLib\sipXmediaAdapterLib-msvc8.vcxproj", "{9501C518-8693-42F3-86A4-39B14983EC6C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXmediaLib-msvc8", "..\..\..\sipXtapi\sipXmediaLib\sipXmediaLib-msvc8.vcxproj", "{0EC8287A-481E-45DC-8F95-BAD940AE1038}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeex", "..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\win32\VS2003\libspeex\libspeex.vcxproj", "{E972C52F-9E85-4D65-B19C-031E511E9DB4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgpcmapcmu-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgpcmapcmu\plgpcmapcmu-msvc8.vcxproj", "{A9C94D26-C90D-4860-8195-56929E893757}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgtones-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgtones\plgtones-msvc8.vcxproj", "{F3BCA14E-F24D-4570-833E-8C20C4C393F7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgspeex-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgspeex\plgspeex-msvc8.vcxproj", "{4F7FDA11-42A4-4556-A631-15AA785CD1C1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testUA", "test\testUA_10_0.vcxproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unitTests", "test\unitTests_10_0.vcxproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libSRTP", "..\..\contrib\srtp\srtp10.vcxproj", "{EEF031CB-FED8-451E-A471-91EC8D4F6750}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgilbc-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgilbc\plgilbc-msvc8.vcxproj", "{6442C7DE-E500-4BA2-B821-98092F1EDCAF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libilbc-msvc8", "..\..\..\sipXtapi\sipXmediaLib\contrib\libilbc\VS2005\libilbc-msvc8.vcxproj", "{214007F3-D6E8-4B07-AC00-9FB673FF539E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgl16-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgl16\plgl16-msvc8.vcxproj", "{82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeexdsp", "..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\win32\VS2003\libspeexdsp\libspeexdsp.vcxproj", "{03207781-0D1C-4DB3-A71D-45C608F28DBD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Release|Win32.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.Build.0 = SSL-Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.Build.0 = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.ActiveCfg = SSL-Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.Build.0 = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug|Win32.Build.0 = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release|Win32.ActiveCfg = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release|Win32.Build.0 = SSL-Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug|Win32.ActiveCfg = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug|Win32.Build.0 = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release|Win32.ActiveCfg = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release|Win32.Build.0 = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug|Win32.ActiveCfg = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug|Win32.Build.0 = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release|Win32.ActiveCfg = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.Build.0 = Release|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Debug|Win32.ActiveCfg = Debug|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Debug|Win32.Build.0 = Debug|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Release|Win32.ActiveCfg = Release|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Release|Win32.Build.0 = Release|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Debug|Win32.Build.0 = Debug|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Release|Win32.ActiveCfg = Release|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Release|Win32.Build.0 = Release|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.Debug|Win32.ActiveCfg = Debug|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.Debug|Win32.Build.0 = Debug|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.Release|Win32.ActiveCfg = Release|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.Release|Win32.Build.0 = Release|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Debug|Win32.ActiveCfg = Debug|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Debug|Win32.Build.0 = Debug|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Release|Win32.ActiveCfg = Release|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Release|Win32.Build.0 = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.ActiveCfg = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.Build.0 = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.ActiveCfg = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.Build.0 = Release|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Debug|Win32.ActiveCfg = Debug|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Debug|Win32.Build.0 = Debug|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Release|Win32.ActiveCfg = Release|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Release|Win32.Build.0 = Release|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.Debug|Win32.ActiveCfg = Debug|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.Debug|Win32.Build.0 = Debug|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.Release|Win32.ActiveCfg = Release|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.Release|Win32.Build.0 = Release|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Debug|Win32.ActiveCfg = Debug|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Debug|Win32.Build.0 = Debug|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Release|Win32.ActiveCfg = Release|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Release|Win32.Build.0 = Release|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug|Win32.ActiveCfg = Debug|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug|Win32.Build.0 = Debug|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release|Win32.ActiveCfg = Release|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release|Win32.Build.0 = Release|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Debug|Win32.ActiveCfg = Debug|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Debug|Win32.Build.0 = Debug|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Release|Win32.ActiveCfg = Release|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Release|Win32.Build.0 = Release|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Debug|Win32.ActiveCfg = Debug|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Debug|Win32.Build.0 = Debug|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Release|Win32.ActiveCfg = Release|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Release|Win32.Build.0 = Release|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.Debug|Win32.ActiveCfg = Debug|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.Debug|Win32.Build.0 = Debug|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.Release|Win32.ActiveCfg = Release|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.Release|Win32.Build.0 = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug|Win32.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug|Win32.Build.0 = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release|Win32.ActiveCfg = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/resip/recon/recon_10_0.vcxproj b/src/libs/resiprocate/resip/recon/recon_10_0.vcxproj new file mode 100644 index 00000000..e4759fb1 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/recon_10_0.vcxproj @@ -0,0 +1,169 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>recon</ProjectName> + <ProjectGuid>{16CD976A-5D3B-4329-88BA-A32560CDFCC7}</ProjectGuid> + <RootNamespace>recon</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/interface;$(ProjectDir)/../../../sipXtapi/sipXPortLib/include;$(ProjectDir)/../../../sipXtapi/sipXtackLib/include;$(ProjectDir)/../../../sipXtapi/sipXsdpLib/include;$(ProjectDir)/../../../sipXtapi/sipXMediaLib/include;$(ProjectDir)/../../reTurn;$(ProjectDir)/../../contrib/pcre;$(ProjectDir)/../../contrib/asio;$(ProjectDir)/../../contrib/boost_1_34_1;$(ProjectDir)/../../contrib/openssl/include;$(ProjectDir)/../../contrib/srtp/include;$(ProjectDir)/../../contrib/srtp/crypto/include;$(ProjectDir)/../../reflow;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <ProgramDataBaseFileName>$(IntDir)vc70.pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <OmitFramePointers>true</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)/../../;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/interface;$(ProjectDir)/../../../sipXtapi/sipXPortLib/include;$(ProjectDir)/../../../sipXtapi/sipXtackLib/include;$(ProjectDir)/../../../sipXtapi/sipXsdpLib/include;$(ProjectDir)/../../../sipXtapi/sipXMediaLib/include;$(ProjectDir)/../../reTurn;$(ProjectDir)/../../contrib/pcre;$(ProjectDir)/../../contrib/asio;$(ProjectDir)/../../contrib/boost_1_34_1;$(ProjectDir)/../../contrib/openssl/inc32;$(ProjectDir)/../../contrib/srtp/include;$(ProjectDir)/../../contrib/srtp/crypto/include;$(ProjectDir)/../../reflow;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="BridgeMixer.cxx" /> + <ClCompile Include="Conversation.cxx" /> + <ClCompile Include="ConversationManager.cxx" /> + <ClCompile Include="ConversationParticipantAssignment.cxx" /> + <ClCompile Include="ConversationProfile.cxx" /> + <ClCompile Include="DefaultDialogSet.cxx" /> + <ClCompile Include="DtmfEvent.cxx" /> + <ClCompile Include="FlowManagerSipXSocket.cxx" /> + <ClCompile Include="LocalParticipant.cxx" /> + <ClCompile Include="MediaEvent.cxx" /> + <ClCompile Include="MediaInterface.cxx" /> + <ClCompile Include="MediaResourceCache.cxx" /> + <ClCompile Include="MediaResourceParticipant.cxx" /> + <ClCompile Include="MediaStreamEvent.cxx" /> + <ClCompile Include="Participant.cxx" /> + <ClCompile Include="ReconSubsystem.cxx" /> + <ClCompile Include="RelatedConversationSet.cxx" /> + <ClCompile Include="RemoteParticipant.cxx" /> + <ClCompile Include="RemoteParticipantDialogSet.cxx" /> + <ClCompile Include="sdp\Sdp.cxx" /> + <ClCompile Include="sdp\SdpCandidate.cxx" /> + <ClCompile Include="sdp\SdpCandidatePair.cxx" /> + <ClCompile Include="sdp\SdpCodec.cxx" /> + <ClCompile Include="sdp\SdpHelperResip.cxx" /> + <ClCompile Include="sdp\SdpMediaLine.cxx" /> + <ClCompile Include="UserAgent.cxx" /> + <ClCompile Include="UserAgentClientSubscription.cxx" /> + <ClCompile Include="UserAgentDialogSetFactory.cxx" /> + <ClCompile Include="UserAgentMasterProfile.cxx" /> + <ClCompile Include="UserAgentRegistration.cxx" /> + <ClCompile Include="UserAgentServerAuthManager.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="BridgeMixer.hxx" /> + <ClInclude Include="Conversation.hxx" /> + <ClInclude Include="ConversationManager.hxx" /> + <ClInclude Include="ConversationManagerCmds.hxx" /> + <ClInclude Include="ConversationParticipantAssignment.hxx" /> + <ClInclude Include="ConversationProfile.hxx" /> + <ClInclude Include="DefaultDialogSet.hxx" /> + <ClInclude Include="DtmfEvent.hxx" /> + <ClInclude Include="FlowManagerSipXSocket.hxx" /> + <ClInclude Include="LocalParticipant.hxx" /> + <ClInclude Include="MediaEvent.hxx" /> + <ClInclude Include="MediaInterface.hxx" /> + <ClInclude Include="MediaResourceCache.hxx" /> + <ClInclude Include="MediaResourceParticipant.hxx" /> + <ClInclude Include="MediaStreamEvent.hxx" /> + <ClInclude Include="Participant.hxx" /> + <ClInclude Include="ReconSubsystem.hxx" /> + <ClInclude Include="RelatedConversationSet.hxx" /> + <ClInclude Include="RemoteParticipant.hxx" /> + <ClInclude Include="RemoteParticipantDialogSet.hxx" /> + <ClInclude Include="sdp\Sdp.hxx" /> + <ClInclude Include="sdp\SdpCandidate.hxx" /> + <ClInclude Include="sdp\SdpCandidatePair.hxx" /> + <ClInclude Include="sdp\SdpCodec.hxx" /> + <ClInclude Include="sdp\SdpHelperResip.hxx" /> + <ClInclude Include="sdp\SdpMediaLine.hxx" /> + <ClInclude Include="UserAgent.hxx" /> + <ClInclude Include="UserAgentClientSubscription.hxx" /> + <ClInclude Include="UserAgentCmds.hxx" /> + <ClInclude Include="UserAgentDialogSetFactory.hxx" /> + <ClInclude Include="UserAgentMasterProfile.hxx" /> + <ClInclude Include="UserAgentRegistration.hxx" /> + <ClInclude Include="UserAgentServerAuthManager.hxx" /> + </ItemGroup> + <ItemGroup> + <None Include="ReadMe.txt" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/recon/recon_10_0.vcxproj.filters b/src/libs/resiprocate/resip/recon/recon_10_0.vcxproj.filters new file mode 100644 index 00000000..5b80bfd4 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/recon_10_0.vcxproj.filters @@ -0,0 +1,216 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{86dda9af-dda8-4b07-a492-595d70986645}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{8f4ecd48-d090-47b4-9531-6a04ad5a76d9}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{052df6a8-c475-427b-bcde-dab55cf61a9a}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="BridgeMixer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Conversation.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ConversationManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ConversationParticipantAssignment.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ConversationProfile.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DefaultDialogSet.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DtmfEvent.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="FlowManagerSipXSocket.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="LocalParticipant.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MediaEvent.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MediaResourceCache.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MediaResourceParticipant.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MediaStreamEvent.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Participant.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ReconSubsystem.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RelatedConversationSet.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RemoteParticipant.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RemoteParticipantDialogSet.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="sdp\Sdp.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="sdp\SdpCandidate.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="sdp\SdpCandidatePair.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="sdp\SdpCodec.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="sdp\SdpHelperResip.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="sdp\SdpMediaLine.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UserAgent.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UserAgentClientSubscription.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UserAgentDialogSetFactory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UserAgentMasterProfile.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UserAgentRegistration.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UserAgentServerAuthManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MediaInterface.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="BridgeMixer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Conversation.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConversationManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConversationManagerCmds.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConversationParticipantAssignment.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConversationProfile.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DefaultDialogSet.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DtmfEvent.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="FlowManagerSipXSocket.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="LocalParticipant.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MediaEvent.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MediaResourceCache.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MediaResourceParticipant.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MediaStreamEvent.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Participant.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ReconSubsystem.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RelatedConversationSet.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RemoteParticipant.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RemoteParticipantDialogSet.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="sdp\Sdp.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="sdp\SdpCandidate.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="sdp\SdpCandidatePair.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="sdp\SdpCodec.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="sdp\SdpHelperResip.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="sdp\SdpMediaLine.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserAgent.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserAgentClientSubscription.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserAgentCmds.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserAgentDialogSetFactory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserAgentMasterProfile.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserAgentRegistration.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UserAgentServerAuthManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MediaInterface.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="ReadMe.txt" /> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/recon/recon_7_1.sln b/src/libs/resiprocate/resip/recon/recon_7_1.sln new file mode 100644 index 00000000..dcc92fc6 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/recon_7_1.sln @@ -0,0 +1,243 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recon", "recon_7_1.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC7}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\..\contrib\ares\ares_7_1.vcproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\..\rutil\rutil_7_1.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resiprocate", "..\stack\resiprocate_7_1.vcproj", "{2A8BE839-6466-4001-B224-8F1C3168D04A}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dum", "..\dum\dum_7_1.vcproj", "{31B0654F-E08E-405F-909F-80F86CB14B9D}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reflow", "..\..\reflow\reflow_7_1.vcproj", "{D2AB531B-86AC-43DD-A330-9809B4F1BB53}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcre", "..\..\contrib\pcre\pcre_7_1.vcproj", "{B933F895-8EFB-4FDD-A46D-09B8C00D1D26}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnClient", "..\..\reTurn\client\reTurnClient_7_1.vcproj", "{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXportLib", "..\..\..\sipXtapi\sipXportLib\sipXportLib.vcproj", "{14631055-9D3F-47E5-B6A7-16BFC0CC8091}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXsdpLib", "..\..\..\sipXtapi\sipXsdpLib\sipXsdpLib.vcproj", "{E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXmediaAdapterLib", "..\..\..\sipXtapi\sipXmediaAdapterLib\sipXmediaAdapterLib.vcproj", "{0E229E54-9234-44DC-8B74-8C6BA553D3C5}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXmediaLib", "..\..\..\sipXtapi\sipXmediaLib\sipXmediaLib.vcproj", "{0EC8287A-481E-45DC-8F95-BAD940AE1038}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeex", "..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\win32\VS2003\libspeex\libspeex.vcproj", "{E972C52F-9E85-4D65-B19C-031E511E9DB4}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgpcmapcmu", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgpcmapcmu\plgpcmapcmu.vcproj", "{A9C94D26-C90D-4860-8195-56929E893757}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgtones", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgtones\plgtones.vcproj", "{50E09C77-6077-4149-8B80-996217363A2F}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgspeex", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgspeex\plgspeex.vcproj", "{4F7FDA11-42A4-4556-A631-15AA785CD1C1}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testUA", "test\testUA_7_1.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC8}" + ProjectSection(ProjectDependencies) = postProject + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9} = {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9} + {4F7FDA11-42A4-4556-A631-15AA785CD1C1} = {4F7FDA11-42A4-4556-A631-15AA785CD1C1} + {D2AB531B-86AC-43DD-A330-9809B4F1BB53} = {D2AB531B-86AC-43DD-A330-9809B4F1BB53} + {A9C94D26-C90D-4860-8195-56929E893710} = {A9C94D26-C90D-4860-8195-56929E893710} + {A9C94D26-C90D-4860-8195-56929E893757} = {A9C94D26-C90D-4860-8195-56929E893757} + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {0E229E54-9234-44DC-8B74-8C6BA553D3C5} = {0E229E54-9234-44DC-8B74-8C6BA553D3C5} + {14631055-9D3F-47E5-B6A7-16BFC0CC8091} = {14631055-9D3F-47E5-B6A7-16BFC0CC8091} + {16CD976A-5D3B-4329-88BA-A32560CDFCC7} = {16CD976A-5D3B-4329-88BA-A32560CDFCC7} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {50E09C77-6077-4149-8B80-996217363A2F} = {50E09C77-6077-4149-8B80-996217363A2F} + {0EC8287A-481E-45DC-8F95-BAD940AE1038} = {0EC8287A-481E-45DC-8F95-BAD940AE1038} + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} = {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} = {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} + {6442C7DE-E500-4BA2-B821-98092F1EDCAF} = {6442C7DE-E500-4BA2-B821-98092F1EDCAF} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unitTests", "test\unitTests_7_1.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC9}" + ProjectSection(ProjectDependencies) = postProject + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9} = {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9} + {4F7FDA11-42A4-4556-A631-15AA785CD1C1} = {4F7FDA11-42A4-4556-A631-15AA785CD1C1} + {D2AB531B-86AC-43DD-A330-9809B4F1BB53} = {D2AB531B-86AC-43DD-A330-9809B4F1BB53} + {A9C94D26-C90D-4860-8195-56929E893757} = {A9C94D26-C90D-4860-8195-56929E893757} + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {0E229E54-9234-44DC-8B74-8C6BA553D3C5} = {0E229E54-9234-44DC-8B74-8C6BA553D3C5} + {14631055-9D3F-47E5-B6A7-16BFC0CC8091} = {14631055-9D3F-47E5-B6A7-16BFC0CC8091} + {16CD976A-5D3B-4329-88BA-A32560CDFCC7} = {16CD976A-5D3B-4329-88BA-A32560CDFCC7} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {50E09C77-6077-4149-8B80-996217363A2F} = {50E09C77-6077-4149-8B80-996217363A2F} + {0EC8287A-481E-45DC-8F95-BAD940AE1038} = {0EC8287A-481E-45DC-8F95-BAD940AE1038} + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} = {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} = {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} + {6442C7DE-E500-4BA2-B821-98092F1EDCAF} = {6442C7DE-E500-4BA2-B821-98092F1EDCAF} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libSRTP", "..\..\contrib\srtp\srtp7.vcproj", "{7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libilbc", "..\..\..\sipXtapi\sipXmediaLib\contrib\libilbc\VS2003\libilbc.vcproj", "{214007F3-D6E8-4B07-AC00-9FB673FF539E}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgilbc", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgilbc\plgilbc.vcproj", "{6442C7DE-E500-4BA2-B821-98092F1EDCAF}" + ProjectSection(ProjectDependencies) = postProject + {214007F3-D6E8-4B07-AC00-9FB673FF539E} = {214007F3-D6E8-4B07-AC00-9FB673FF539E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgl16", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgl16\plgl16.vcproj", "{A9C94D26-C90D-4860-8195-56929E893710}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeexdsp", "..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\win32\VS2003\libspeexdsp\libspeexdsp.vcproj", "{03207781-0D1C-4DB3-A71D-45C608F28DBD}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Debug.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Debug.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Release.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Release.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release.Build.0 = SSL-Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug.ActiveCfg = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug.Build.0 = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release.ActiveCfg = SSL-Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release.Build.0 = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug.ActiveCfg = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug.Build.0 = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release.ActiveCfg = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release.Build.0 = SSL-Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug.ActiveCfg = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug.Build.0 = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release.ActiveCfg = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release.Build.0 = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug.ActiveCfg = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug.Build.0 = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release.ActiveCfg = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release.Build.0 = Release|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Debug.ActiveCfg = Debug|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Debug.Build.0 = Debug|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Release.ActiveCfg = Release|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Release.Build.0 = Release|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Debug.ActiveCfg = Debug|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Debug.Build.0 = Debug|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Release.ActiveCfg = Release|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Release.Build.0 = Release|Win32 + {0E229E54-9234-44DC-8B74-8C6BA553D3C5}.Debug.ActiveCfg = Debug|Win32 + {0E229E54-9234-44DC-8B74-8C6BA553D3C5}.Debug.Build.0 = Debug|Win32 + {0E229E54-9234-44DC-8B74-8C6BA553D3C5}.Release.ActiveCfg = Release|Win32 + {0E229E54-9234-44DC-8B74-8C6BA553D3C5}.Release.Build.0 = Release|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Debug.ActiveCfg = Debug|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Debug.Build.0 = Debug|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Release.ActiveCfg = Release|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Release.Build.0 = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug.ActiveCfg = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug.Build.0 = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release.ActiveCfg = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release.Build.0 = Release|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Debug.ActiveCfg = Debug|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Debug.Build.0 = Debug|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Release.ActiveCfg = Release|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Release.Build.0 = Release|Win32 + {50E09C77-6077-4149-8B80-996217363A2F}.Debug.ActiveCfg = Debug|Win32 + {50E09C77-6077-4149-8B80-996217363A2F}.Debug.Build.0 = Debug|Win32 + {50E09C77-6077-4149-8B80-996217363A2F}.Release.ActiveCfg = Release|Win32 + {50E09C77-6077-4149-8B80-996217363A2F}.Release.Build.0 = Release|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Debug.ActiveCfg = Debug|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Debug.Build.0 = Debug|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Release.ActiveCfg = Release|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Release.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Debug.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Debug.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Release.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Release.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Debug.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Debug.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Release.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Release.Build.0 = Release|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Debug.ActiveCfg = Debug|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Debug.Build.0 = Debug|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Release.ActiveCfg = Release|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Release.Build.0 = Release|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Debug.ActiveCfg = Debug|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Debug.Build.0 = Debug|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Release.ActiveCfg = Release|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Release.Build.0 = Release|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Debug.ActiveCfg = Debug|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Debug.Build.0 = Debug|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Release.ActiveCfg = Release|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Release.Build.0 = Release|Win32 + {A9C94D26-C90D-4860-8195-56929E893710}.Debug.ActiveCfg = Debug|Win32 + {A9C94D26-C90D-4860-8195-56929E893710}.Debug.Build.0 = Debug|Win32 + {A9C94D26-C90D-4860-8195-56929E893710}.Release.ActiveCfg = Release|Win32 + {A9C94D26-C90D-4860-8195-56929E893710}.Release.Build.0 = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug.Build.0 = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release.ActiveCfg = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/resip/recon/recon_7_1.vcproj b/src/libs/resiprocate/resip/recon/recon_7_1.vcproj new file mode 100644 index 00000000..54708747 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/recon_7_1.vcproj @@ -0,0 +1,320 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="recon" + ProjectGUID="{16CD976A-5D3B-4329-88BA-A32560CDFCC7}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../reTurn&quot;;&quot;$(ProjectDir)/../../contrib/asio&quot;;&quot;$(ProjectDir)/../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;ASIO_ENABLE_CANCELIO" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="TRUE" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)/vc70.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/librecon.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="TRUE" + OptimizeForProcessor="2" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../reTurn&quot;;&quot;$(ProjectDir)/../../contrib/asio&quot;;&quot;$(ProjectDir)/../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;ASIO_ENABLE_CANCELIO" + StringPooling="TRUE" + RuntimeLibrary="2" + BufferSecurityCheck="FALSE" + EnableFunctionLevelLinking="TRUE" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/librecon.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"> + <File + RelativePath=".\BridgeMixer.cxx"> + </File> + <File + RelativePath=".\Conversation.cxx"> + </File> + <File + RelativePath=".\ConversationManager.cxx"> + </File> + <File + RelativePath=".\ConversationParticipantAssignment.cxx"> + </File> + <File + RelativePath=".\ConversationProfile.cxx"> + </File> + <File + RelativePath=".\DefaultDialogSet.cxx"> + </File> + <File + RelativePath=".\DtmfEvent.cxx"> + </File> + <File + RelativePath=".\FlowManagerSipXSocket.cxx"> + </File> + <File + RelativePath=".\LocalParticipant.cxx"> + </File> + <File + RelativePath=".\MediaEvent.cxx"> + </File> + <File + RelativePath=".\MediaInterface.cxx"> + </File> + <File + RelativePath=".\MediaResourceCache.cxx"> + </File> + <File + RelativePath=".\MediaResourceParticipant.cxx"> + </File> + <File + RelativePath=".\MediaStreamEvent.cxx"> + </File> + <File + RelativePath=".\Participant.cxx"> + </File> + <File + RelativePath=".\ReconSubsystem.cxx"> + </File> + <File + RelativePath=".\RelatedConversationSet.cxx"> + </File> + <File + RelativePath=".\RemoteParticipant.cxx"> + </File> + <File + RelativePath=".\RemoteParticipantDialogSet.cxx"> + </File> + <File + RelativePath=".\sdp\Sdp.cxx"> + </File> + <File + RelativePath=".\sdp\SdpCandidate.cxx"> + </File> + <File + RelativePath=".\sdp\SdpCandidatePair.cxx"> + </File> + <File + RelativePath=".\sdp\SdpCodec.cxx"> + </File> + <File + RelativePath=".\sdp\SdpHelperResip.cxx"> + </File> + <File + RelativePath=".\sdp\SdpMediaLine.cxx"> + </File> + <File + RelativePath=".\UserAgent.cxx"> + </File> + <File + RelativePath=".\UserAgentClientSubscription.cxx"> + </File> + <File + RelativePath=".\UserAgentDialogSetFactory.cxx"> + </File> + <File + RelativePath=".\UserAgentMasterProfile.cxx"> + </File> + <File + RelativePath=".\UserAgentRegistration.cxx"> + </File> + <File + RelativePath=".\UserAgentServerAuthManager.cxx"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc"> + <File + RelativePath=".\BridgeMixer.hxx"> + </File> + <File + RelativePath=".\Conversation.hxx"> + </File> + <File + RelativePath=".\ConversationManager.hxx"> + </File> + <File + RelativePath=".\ConversationManagerCmds.hxx"> + </File> + <File + RelativePath=".\ConversationParticipantAssignment.hxx"> + </File> + <File + RelativePath=".\ConversationProfile.hxx"> + </File> + <File + RelativePath=".\DefaultDialogSet.hxx"> + </File> + <File + RelativePath=".\DtmfEvent.hxx"> + </File> + <File + RelativePath=".\FlowManagerSipXSocket.hxx"> + </File> + <File + RelativePath=".\LocalParticipant.hxx"> + </File> + <File + RelativePath=".\MediaEvent.hxx"> + </File> + <File + RelativePath=".\MediaResourceCache.hxx"> + </File> + <File + RelativePath=".\MediaResourceParticipant.hxx"> + </File> + <File + RelativePath=".\MediaStreamEvent.hxx"> + </File> + <File + RelativePath=".\Participant.hxx"> + </File> + <File + RelativePath=".\ReconSubsystem.hxx"> + </File> + <File + RelativePath=".\RelatedConversationSet.hxx"> + </File> + <File + RelativePath=".\RemoteParticipant.hxx"> + </File> + <File + RelativePath=".\RemoteParticipantDialogSet.hxx"> + </File> + <File + RelativePath=".\sdp\Sdp.hxx"> + </File> + <File + RelativePath=".\sdp\SdpCandidate.hxx"> + </File> + <File + RelativePath=".\sdp\SdpCandidatePair.hxx"> + </File> + <File + RelativePath=".\sdp\SdpCodec.hxx"> + </File> + <File + RelativePath=".\SdpHelperResip.hxx"> + </File> + <File + RelativePath=".\sdp\SdpHelperResip.hxx"> + </File> + <File + RelativePath=".\sdp\SdpMediaLine.hxx"> + </File> + <File + RelativePath=".\UserAgent.hxx"> + </File> + <File + RelativePath=".\UserAgentClientSubscription.hxx"> + </File> + <File + RelativePath=".\UserAgentCmds.hxx"> + </File> + <File + RelativePath=".\UserAgentDialogSetFactory.hxx"> + </File> + <File + RelativePath=".\UserAgentMasterProfile.hxx"> + </File> + <File + RelativePath=".\UserAgentRegistration.hxx"> + </File> + <File + RelativePath=".\UserAgentServerAuthManager.hxx"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"> + </Filter> + <File + RelativePath="ReadMe.txt"> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/recon/recon_8_0.sln b/src/libs/resiprocate/resip/recon/recon_8_0.sln new file mode 100644 index 00000000..562822ae --- /dev/null +++ b/src/libs/resiprocate/resip/recon/recon_8_0.sln @@ -0,0 +1,293 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recon", "recon_8_0.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC7}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\..\rutil\dns\ares\ares_8_0.vcproj", "{CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\..\rutil\rutil_8_0.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resiprocate", "..\stack\resiprocate_8_0.vcproj", "{2A8BE839-6466-4001-B224-8F1C3168D04A}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dum", "..\dum\dum_8_0.vcproj", "{31B0654F-E08E-405F-909F-80F86CB14B9D}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reflow", "..\..\reflow\reflow_8_0.vcproj", "{D2AB531B-86AC-43DD-A330-9809B4F1BB53}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcre", "..\..\contrib\pcre\pcre_8_0.vcproj", "{B933F895-8EFB-4FDD-A46D-09B8C00D1D26}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnClient", "..\..\reTurn\client\reTurnClient_8_0.vcproj", "{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXportLib-msvc8", "..\..\..\sipXtapi\sipXportLib\sipXportLib-msvc8.vcproj", "{14631055-9D3F-47E5-B6A7-16BFC0CC8091}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXsdpLib-msvc8", "..\..\..\sipXtapi\sipXsdpLib\sipXsdpLib-msvc8.vcproj", "{E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXmediaAdapterLib-msvc8", "..\..\..\sipXtapi\sipXmediaAdapterLib\sipXmediaAdapterLib-msvc8.vcproj", "{9501C518-8693-42F3-86A4-39B14983EC6C}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXmediaLib-msvc8", "..\..\..\sipXtapi\sipXmediaLib\sipXmediaLib-msvc8.vcproj", "{0EC8287A-481E-45DC-8F95-BAD940AE1038}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeex", "..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\win32\VS2003\libspeex\libspeex.vcproj", "{E972C52F-9E85-4D65-B19C-031E511E9DB4}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgpcmapcmu-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgpcmapcmu\plgpcmapcmu-msvc8.vcproj", "{A9C94D26-C90D-4860-8195-56929E893757}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgtones-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgtones\plgtones-msvc8.vcproj", "{F3BCA14E-F24D-4570-833E-8C20C4C393F7}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgspeex-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgspeex\plgspeex-msvc8.vcproj", "{4F7FDA11-42A4-4556-A631-15AA785CD1C1}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testUA", "test\testUA_8_0.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC8}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {4F7FDA11-42A4-4556-A631-15AA785CD1C1} = {4F7FDA11-42A4-4556-A631-15AA785CD1C1} + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + {6442C7DE-E500-4BA2-B821-98092F1EDCAF} = {6442C7DE-E500-4BA2-B821-98092F1EDCAF} + {9501C518-8693-42F3-86A4-39B14983EC6C} = {9501C518-8693-42F3-86A4-39B14983EC6C} + {D2AB531B-86AC-43DD-A330-9809B4F1BB53} = {D2AB531B-86AC-43DD-A330-9809B4F1BB53} + {A9C94D26-C90D-4860-8195-56929E893757} = {A9C94D26-C90D-4860-8195-56929E893757} + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {F3BCA14E-F24D-4570-833E-8C20C4C393F7} = {F3BCA14E-F24D-4570-833E-8C20C4C393F7} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {14631055-9D3F-47E5-B6A7-16BFC0CC8091} = {14631055-9D3F-47E5-B6A7-16BFC0CC8091} + {16CD976A-5D3B-4329-88BA-A32560CDFCC7} = {16CD976A-5D3B-4329-88BA-A32560CDFCC7} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {0EC8287A-481E-45DC-8F95-BAD940AE1038} = {0EC8287A-481E-45DC-8F95-BAD940AE1038} + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} = {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} + {EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750} + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} = {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE} = {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unitTests", "test\unitTests_8_0.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC9}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {4F7FDA11-42A4-4556-A631-15AA785CD1C1} = {4F7FDA11-42A4-4556-A631-15AA785CD1C1} + {9501C518-8693-42F3-86A4-39B14983EC6C} = {9501C518-8693-42F3-86A4-39B14983EC6C} + {D2AB531B-86AC-43DD-A330-9809B4F1BB53} = {D2AB531B-86AC-43DD-A330-9809B4F1BB53} + {A9C94D26-C90D-4860-8195-56929E893757} = {A9C94D26-C90D-4860-8195-56929E893757} + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {F3BCA14E-F24D-4570-833E-8C20C4C393F7} = {F3BCA14E-F24D-4570-833E-8C20C4C393F7} + {31B0654F-E08E-405F-909F-80F86CB14B9D} = {31B0654F-E08E-405F-909F-80F86CB14B9D} + {14631055-9D3F-47E5-B6A7-16BFC0CC8091} = {14631055-9D3F-47E5-B6A7-16BFC0CC8091} + {16CD976A-5D3B-4329-88BA-A32560CDFCC7} = {16CD976A-5D3B-4329-88BA-A32560CDFCC7} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {0EC8287A-481E-45DC-8F95-BAD940AE1038} = {0EC8287A-481E-45DC-8F95-BAD940AE1038} + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} = {B933F895-8EFB-4FDD-A46D-09B8C00D1D26} + {EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750} + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} = {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} = {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + {6442C7DE-E500-4BA2-B821-98092F1EDCAF} = {6442C7DE-E500-4BA2-B821-98092F1EDCAF} + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libSRTP", "..\..\contrib\srtp\srtp.vcproj", "{EEF031CB-FED8-451E-A471-91EC8D4F6750}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgilbc-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgilbc\plgilbc-msvc8.vcproj", "{6442C7DE-E500-4BA2-B821-98092F1EDCAF}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {214007F3-D6E8-4B07-AC00-9FB673FF539E} = {214007F3-D6E8-4B07-AC00-9FB673FF539E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libilbc-msvc8", "..\..\..\sipXtapi\sipXmediaLib\contrib\libilbc\VS2005\libilbc-msvc8.vcproj", "{214007F3-D6E8-4B07-AC00-9FB673FF539E}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgl16-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgl16\plgl16-msvc8.vcproj", "{82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeexdsp", "..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\win32\VS2003\libspeexdsp\libspeexdsp.vcproj", "{03207781-0D1C-4DB3-A71D-45C608F28DBD}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Release|Win32.Build.0 = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Debug|Win32.Build.0 = Debug|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.ActiveCfg = Release|Win32 + {CE7CF5E0-CAD1-49D6-95D1-143DED7B226E}.Release|Win32.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.Build.0 = SSL-Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.Build.0 = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.ActiveCfg = SSL-Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.Build.0 = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Debug|Win32.Build.0 = SSL-Debug|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release|Win32.ActiveCfg = SSL-Release|Win32 + {31B0654F-E08E-405F-909F-80F86CB14B9D}.Release|Win32.Build.0 = SSL-Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug|Win32.ActiveCfg = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug|Win32.Build.0 = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release|Win32.ActiveCfg = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release|Win32.Build.0 = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug|Win32.ActiveCfg = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Debug|Win32.Build.0 = Debug|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release|Win32.ActiveCfg = Release|Win32 + {B933F895-8EFB-4FDD-A46D-09B8C00D1D26}.Release|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.Build.0 = Release|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Debug|Win32.ActiveCfg = Debug|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Debug|Win32.Build.0 = Debug|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Release|Win32.ActiveCfg = Release|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Release|Win32.Build.0 = Release|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Debug|Win32.Build.0 = Debug|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Release|Win32.ActiveCfg = Release|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Release|Win32.Build.0 = Release|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.Debug|Win32.ActiveCfg = Debug|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.Debug|Win32.Build.0 = Debug|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.Release|Win32.ActiveCfg = Release|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.Release|Win32.Build.0 = Release|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Debug|Win32.ActiveCfg = Debug|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Debug|Win32.Build.0 = Debug|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Release|Win32.ActiveCfg = Release|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Release|Win32.Build.0 = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.ActiveCfg = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.Build.0 = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.ActiveCfg = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.Build.0 = Release|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Debug|Win32.ActiveCfg = Debug|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Debug|Win32.Build.0 = Debug|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Release|Win32.ActiveCfg = Release|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Release|Win32.Build.0 = Release|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.Debug|Win32.ActiveCfg = Debug|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.Debug|Win32.Build.0 = Debug|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.Release|Win32.ActiveCfg = Release|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.Release|Win32.Build.0 = Release|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Debug|Win32.ActiveCfg = Debug|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Debug|Win32.Build.0 = Debug|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Release|Win32.ActiveCfg = Release|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Release|Win32.Build.0 = Release|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug|Win32.ActiveCfg = Debug|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug|Win32.Build.0 = Debug|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release|Win32.ActiveCfg = Release|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release|Win32.Build.0 = Release|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Debug|Win32.ActiveCfg = Debug|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Debug|Win32.Build.0 = Debug|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Release|Win32.ActiveCfg = Release|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Release|Win32.Build.0 = Release|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Debug|Win32.ActiveCfg = Debug|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Debug|Win32.Build.0 = Debug|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Release|Win32.ActiveCfg = Release|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Release|Win32.Build.0 = Release|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.Debug|Win32.ActiveCfg = Debug|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.Debug|Win32.Build.0 = Debug|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.Release|Win32.ActiveCfg = Release|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.Release|Win32.Build.0 = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug|Win32.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug|Win32.Build.0 = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release|Win32.ActiveCfg = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/resip/recon/recon_8_0.vcproj b/src/libs/resiprocate/resip/recon/recon_8_0.vcproj new file mode 100644 index 00000000..b660bebe --- /dev/null +++ b/src/libs/resiprocate/resip/recon/recon_8_0.vcproj @@ -0,0 +1,434 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="recon" + ProjectGUID="{16CD976A-5D3B-4329-88BA-A32560CDFCC7}" + RootNamespace="recon" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../reTurn&quot;;&quot;$(ProjectDir)/../../contrib/pcre&quot;;&quot;$(ProjectDir)/../../contrib/asio&quot;;&quot;$(ProjectDir)/../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)/vc70.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/librecon.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../reTurn&quot;;&quot;$(ProjectDir)/../../contrib/pcre&quot;;&quot;$(ProjectDir)/../../contrib/asio&quot;;&quot;$(ProjectDir)/../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/librecon.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath=".\BridgeMixer.cxx" + > + </File> + <File + RelativePath=".\Conversation.cxx" + > + </File> + <File + RelativePath=".\ConversationManager.cxx" + > + </File> + <File + RelativePath=".\ConversationParticipantAssignment.cxx" + > + </File> + <File + RelativePath=".\ConversationProfile.cxx" + > + </File> + <File + RelativePath=".\DefaultDialogSet.cxx" + > + </File> + <File + RelativePath=".\DtmfEvent.cxx" + > + </File> + <File + RelativePath=".\FlowManagerSipXSocket.cxx" + > + </File> + <File + RelativePath=".\LocalParticipant.cxx" + > + </File> + <File + RelativePath=".\MediaEvent.cxx" + > + </File> + <File + RelativePath=".\MediaInterface.cxx" + > + </File> + <File + RelativePath=".\MediaResourceCache.cxx" + > + </File> + <File + RelativePath=".\MediaResourceParticipant.cxx" + > + </File> + <File + RelativePath=".\MediaStreamEvent.cxx" + > + </File> + <File + RelativePath=".\Participant.cxx" + > + </File> + <File + RelativePath=".\ReconSubsystem.cxx" + > + </File> + <File + RelativePath=".\RelatedConversationSet.cxx" + > + </File> + <File + RelativePath=".\RemoteParticipant.cxx" + > + </File> + <File + RelativePath=".\RemoteParticipantDialogSet.cxx" + > + </File> + <File + RelativePath=".\sdp\Sdp.cxx" + > + </File> + <File + RelativePath=".\sdp\SdpCandidate.cxx" + > + </File> + <File + RelativePath=".\sdp\SdpCandidatePair.cxx" + > + </File> + <File + RelativePath=".\sdp\SdpCodec.cxx" + > + </File> + <File + RelativePath=".\sdp\SdpHelperResip.cxx" + > + </File> + <File + RelativePath=".\sdp\SdpMediaLine.cxx" + > + </File> + <File + RelativePath=".\UserAgent.cxx" + > + </File> + <File + RelativePath=".\UserAgentClientSubscription.cxx" + > + </File> + <File + RelativePath=".\UserAgentDialogSetFactory.cxx" + > + </File> + <File + RelativePath=".\UserAgentMasterProfile.cxx" + > + </File> + <File + RelativePath=".\UserAgentRegistration.cxx" + > + </File> + <File + RelativePath=".\UserAgentServerAuthManager.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + <File + RelativePath=".\BridgeMixer.hxx" + > + </File> + <File + RelativePath=".\Conversation.hxx" + > + </File> + <File + RelativePath=".\ConversationManager.hxx" + > + </File> + <File + RelativePath=".\ConversationManagerCmds.hxx" + > + </File> + <File + RelativePath=".\ConversationParticipantAssignment.hxx" + > + </File> + <File + RelativePath=".\ConversationProfile.hxx" + > + </File> + <File + RelativePath=".\DefaultDialogSet.hxx" + > + </File> + <File + RelativePath=".\DtmfEvent.hxx" + > + </File> + <File + RelativePath=".\FlowManagerSipXSocket.hxx" + > + </File> + <File + RelativePath=".\LocalParticipant.hxx" + > + </File> + <File + RelativePath=".\MediaEvent.hxx" + > + </File> + <File + RelativePath=".\MediaResourceCache.hxx" + > + </File> + <File + RelativePath=".\MediaResourceParticipant.hxx" + > + </File> + <File + RelativePath=".\MediaStreamEvent.hxx" + > + </File> + <File + RelativePath=".\Participant.hxx" + > + </File> + <File + RelativePath=".\ReconSubsystem.hxx" + > + </File> + <File + RelativePath=".\RelatedConversationSet.hxx" + > + </File> + <File + RelativePath=".\RemoteParticipant.hxx" + > + </File> + <File + RelativePath=".\RemoteParticipantDialogSet.hxx" + > + </File> + <File + RelativePath=".\sdp\Sdp.hxx" + > + </File> + <File + RelativePath=".\sdp\SdpCandidate.hxx" + > + </File> + <File + RelativePath=".\sdp\SdpCandidatePair.hxx" + > + </File> + <File + RelativePath=".\sdp\SdpCodec.hxx" + > + </File> + <File + RelativePath=".\sdp\SdpHelperResip.hxx" + > + </File> + <File + RelativePath=".\sdp\SdpMediaLine.hxx" + > + </File> + <File + RelativePath=".\UserAgent.hxx" + > + </File> + <File + RelativePath=".\UserAgentClientSubscription.hxx" + > + </File> + <File + RelativePath=".\UserAgentCmds.hxx" + > + </File> + <File + RelativePath=".\UserAgentDialogSetFactory.hxx" + > + </File> + <File + RelativePath=".\UserAgentMasterProfile.hxx" + > + </File> + <File + RelativePath=".\UserAgentRegistration.hxx" + > + </File> + <File + RelativePath=".\UserAgentServerAuthManager.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + > + </Filter> + <File + RelativePath="ReadMe.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/recon/recon_9_0.sln b/src/libs/resiprocate/resip/recon/recon_9_0.sln new file mode 100644 index 00000000..206292eb --- /dev/null +++ b/src/libs/resiprocate/resip/recon/recon_9_0.sln @@ -0,0 +1,328 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recon", "recon_9_0.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\..\rutil\dns\ares\ares_9_0.vcproj", "{96CD935E-1951-43B8-AF75-F1C06B3778C1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\..\rutil\rutil_9_0.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resiprocate", "..\stack\resiprocate_9_0.vcproj", "{2A8BE839-6466-4001-B224-8F1C3168D04A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dum", "..\dum\dum_9_0.vcproj", "{12720B4D-F4FC-4502-8FA9-589BF5166216}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reflow", "..\..\reflow\reflow_9_0.vcproj", "{D2AB531B-86AC-43DD-A330-9809B4F1BB53}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcre", "..\..\contrib\pcre\pcre_9_0.vcproj", "{38594885-CF9C-4C5F-B3F0-E4969D7E3F58}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reTurnClient", "..\..\reTurn\client\reTurnClient_9_0.vcproj", "{67B5906C-5C9D-4D09-AC7E-AF71D72175F8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXportLib-msvc8", "..\..\..\sipXtapi\sipXportLib\sipXportLib-msvc8.vcproj", "{14631055-9D3F-47E5-B6A7-16BFC0CC8091}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXsdpLib-msvc8", "..\..\..\sipXtapi\sipXsdpLib\sipXsdpLib-msvc8.vcproj", "{E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXmediaAdapterLib-msvc8", "..\..\..\sipXtapi\sipXmediaAdapterLib\sipXmediaAdapterLib-msvc8.vcproj", "{9501C518-8693-42F3-86A4-39B14983EC6C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sipXmediaLib-msvc8", "..\..\..\sipXtapi\sipXmediaLib\sipXmediaLib-msvc8.vcproj", "{0EC8287A-481E-45DC-8F95-BAD940AE1038}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeex", "..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\win32\VS2003\libspeex\libspeex.vcproj", "{E972C52F-9E85-4D65-B19C-031E511E9DB4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgpcmapcmu-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgpcmapcmu\plgpcmapcmu-msvc8.vcproj", "{A9C94D26-C90D-4860-8195-56929E893757}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgtones-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgtones\plgtones-msvc8.vcproj", "{F3BCA14E-F24D-4570-833E-8C20C4C393F7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgspeex-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgspeex\plgspeex-msvc8.vcproj", "{4F7FDA11-42A4-4556-A631-15AA785CD1C1}" + ProjectSection(ProjectDependencies) = postProject + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testUA", "test\testUA_9_0.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC8}" + ProjectSection(ProjectDependencies) = postProject + {4F7FDA11-42A4-4556-A631-15AA785CD1C1} = {4F7FDA11-42A4-4556-A631-15AA785CD1C1} + {9501C518-8693-42F3-86A4-39B14983EC6C} = {9501C518-8693-42F3-86A4-39B14983EC6C} + {D2AB531B-86AC-43DD-A330-9809B4F1BB53} = {D2AB531B-86AC-43DD-A330-9809B4F1BB53} + {A9C94D26-C90D-4860-8195-56929E893757} = {A9C94D26-C90D-4860-8195-56929E893757} + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {F3BCA14E-F24D-4570-833E-8C20C4C393F7} = {F3BCA14E-F24D-4570-833E-8C20C4C393F7} + {12720B4D-F4FC-4502-8FA9-589BF5166216} = {12720B4D-F4FC-4502-8FA9-589BF5166216} + {14631055-9D3F-47E5-B6A7-16BFC0CC8091} = {14631055-9D3F-47E5-B6A7-16BFC0CC8091} + {16CD976A-5D3B-4329-88BA-A32560CDFCC7} = {16CD976A-5D3B-4329-88BA-A32560CDFCC7} + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE} = {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {0EC8287A-481E-45DC-8F95-BAD940AE1038} = {0EC8287A-481E-45DC-8F95-BAD940AE1038} + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + {38594885-CF9C-4C5F-B3F0-E4969D7E3F58} = {38594885-CF9C-4C5F-B3F0-E4969D7E3F58} + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} = {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} + {EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750} + {6442C7DE-E500-4BA2-B821-98092F1EDCAF} = {6442C7DE-E500-4BA2-B821-98092F1EDCAF} + {96CD935E-1951-43B8-AF75-F1C06B3778C1} = {96CD935E-1951-43B8-AF75-F1C06B3778C1} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unitTests", "test\unitTests_9_0.vcproj", "{16CD976A-5D3B-4329-88BA-A32560CDFCC9}" + ProjectSection(ProjectDependencies) = postProject + {4F7FDA11-42A4-4556-A631-15AA785CD1C1} = {4F7FDA11-42A4-4556-A631-15AA785CD1C1} + {9501C518-8693-42F3-86A4-39B14983EC6C} = {9501C518-8693-42F3-86A4-39B14983EC6C} + {D2AB531B-86AC-43DD-A330-9809B4F1BB53} = {D2AB531B-86AC-43DD-A330-9809B4F1BB53} + {A9C94D26-C90D-4860-8195-56929E893757} = {A9C94D26-C90D-4860-8195-56929E893757} + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {F3BCA14E-F24D-4570-833E-8C20C4C393F7} = {F3BCA14E-F24D-4570-833E-8C20C4C393F7} + {12720B4D-F4FC-4502-8FA9-589BF5166216} = {12720B4D-F4FC-4502-8FA9-589BF5166216} + {14631055-9D3F-47E5-B6A7-16BFC0CC8091} = {14631055-9D3F-47E5-B6A7-16BFC0CC8091} + {16CD976A-5D3B-4329-88BA-A32560CDFCC7} = {16CD976A-5D3B-4329-88BA-A32560CDFCC7} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {0EC8287A-481E-45DC-8F95-BAD940AE1038} = {0EC8287A-481E-45DC-8F95-BAD940AE1038} + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + {38594885-CF9C-4C5F-B3F0-E4969D7E3F58} = {38594885-CF9C-4C5F-B3F0-E4969D7E3F58} + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} = {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} + {EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750} + {6442C7DE-E500-4BA2-B821-98092F1EDCAF} = {6442C7DE-E500-4BA2-B821-98092F1EDCAF} + {96CD935E-1951-43B8-AF75-F1C06B3778C1} = {96CD935E-1951-43B8-AF75-F1C06B3778C1} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libSRTP", "..\..\contrib\srtp\srtp9.vcproj", "{EEF031CB-FED8-451E-A471-91EC8D4F6750}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgilbc-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgilbc\plgilbc-msvc8.vcproj", "{6442C7DE-E500-4BA2-B821-98092F1EDCAF}" + ProjectSection(ProjectDependencies) = postProject + {214007F3-D6E8-4B07-AC00-9FB673FF539E} = {214007F3-D6E8-4B07-AC00-9FB673FF539E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libilbc-msvc8", "..\..\..\sipXtapi\sipXmediaLib\contrib\libilbc\VS2005\libilbc-msvc8.vcproj", "{214007F3-D6E8-4B07-AC00-9FB673FF539E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plgl16-msvc8", "..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgl16\plgl16-msvc8.vcproj", "{82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeexdsp", "..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\win32\VS2003\libspeexdsp\libspeexdsp.vcproj", "{03207781-0D1C-4DB3-A71D-45C608F28DBD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MOHParkServer", "MOHParkServer\MOHParkServer_9_0.vcproj", "{74D896AB-C35B-4BB3-9418-D18D509C8D22}" + ProjectSection(ProjectDependencies) = postProject + {4F7FDA11-42A4-4556-A631-15AA785CD1C1} = {4F7FDA11-42A4-4556-A631-15AA785CD1C1} + {9501C518-8693-42F3-86A4-39B14983EC6C} = {9501C518-8693-42F3-86A4-39B14983EC6C} + {D2AB531B-86AC-43DD-A330-9809B4F1BB53} = {D2AB531B-86AC-43DD-A330-9809B4F1BB53} + {A9C94D26-C90D-4860-8195-56929E893757} = {A9C94D26-C90D-4860-8195-56929E893757} + {E972C52F-9E85-4D65-B19C-031E511E9DB4} = {E972C52F-9E85-4D65-B19C-031E511E9DB4} + {2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A} + {F3BCA14E-F24D-4570-833E-8C20C4C393F7} = {F3BCA14E-F24D-4570-833E-8C20C4C393F7} + {12720B4D-F4FC-4502-8FA9-589BF5166216} = {12720B4D-F4FC-4502-8FA9-589BF5166216} + {14631055-9D3F-47E5-B6A7-16BFC0CC8091} = {14631055-9D3F-47E5-B6A7-16BFC0CC8091} + {16CD976A-5D3B-4329-88BA-A32560CDFCC7} = {16CD976A-5D3B-4329-88BA-A32560CDFCC7} + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE} = {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE} + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} = {67B5906C-5C9D-4D09-AC7E-AF71D72175F8} + {0EC8287A-481E-45DC-8F95-BAD940AE1038} = {0EC8287A-481E-45DC-8F95-BAD940AE1038} + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + {38594885-CF9C-4C5F-B3F0-E4969D7E3F58} = {38594885-CF9C-4C5F-B3F0-E4969D7E3F58} + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} = {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6} + {EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750} + {6442C7DE-E500-4BA2-B821-98092F1EDCAF} = {6442C7DE-E500-4BA2-B821-98092F1EDCAF} + {96CD935E-1951-43B8-AF75-F1C06B3778C1} = {96CD935E-1951-43B8-AF75-F1C06B3778C1} + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + {214007F3-D6E8-4B07-AC00-9FB673FF539E} = {214007F3-D6E8-4B07-AC00-9FB673FF539E} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + SSL-Debug|Win32 = SSL-Debug|Win32 + SSL-Release|Win32 = SSL-Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC7}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.Debug|Win32.ActiveCfg = Debug|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.Debug|Win32.Build.0 = Debug|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.Release|Win32.ActiveCfg = Release|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.Release|Win32.Build.0 = Release|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {96CD935E-1951-43B8-AF75-F1C06B3778C1}.SSL-Release|Win32.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.Build.0 = Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.ActiveCfg = Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.Build.0 = Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.ActiveCfg = Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.Build.0 = Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {2A8BE839-6466-4001-B224-8F1C3168D04A}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {12720B4D-F4FC-4502-8FA9-589BF5166216}.Debug|Win32.ActiveCfg = Debug|Win32 + {12720B4D-F4FC-4502-8FA9-589BF5166216}.Debug|Win32.Build.0 = Debug|Win32 + {12720B4D-F4FC-4502-8FA9-589BF5166216}.Release|Win32.ActiveCfg = Release|Win32 + {12720B4D-F4FC-4502-8FA9-589BF5166216}.Release|Win32.Build.0 = Release|Win32 + {12720B4D-F4FC-4502-8FA9-589BF5166216}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {12720B4D-F4FC-4502-8FA9-589BF5166216}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {12720B4D-F4FC-4502-8FA9-589BF5166216}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {12720B4D-F4FC-4502-8FA9-589BF5166216}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug|Win32.ActiveCfg = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Debug|Win32.Build.0 = Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release|Win32.ActiveCfg = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.Release|Win32.Build.0 = Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {D2AB531B-86AC-43DD-A330-9809B4F1BB53}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.Debug|Win32.ActiveCfg = Debug|Win32 + {38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.Debug|Win32.Build.0 = Debug|Win32 + {38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.Release|Win32.ActiveCfg = Release|Win32 + {38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.Release|Win32.Build.0 = Release|Win32 + {38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.SSL-Release|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Debug|Win32.Build.0 = Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.ActiveCfg = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.Release|Win32.Build.0 = Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {67B5906C-5C9D-4D09-AC7E-AF71D72175F8}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Debug|Win32.ActiveCfg = Debug|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Debug|Win32.Build.0 = Debug|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Release|Win32.ActiveCfg = Release|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.Release|Win32.Build.0 = Release|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {14631055-9D3F-47E5-B6A7-16BFC0CC8091}.SSL-Release|Win32.Build.0 = Release|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Debug|Win32.Build.0 = Debug|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Release|Win32.ActiveCfg = Release|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.Release|Win32.Build.0 = Release|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {E1D81EA9-4AC3-4CF5-B600-090FD822B1F6}.SSL-Release|Win32.Build.0 = Release|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.Debug|Win32.ActiveCfg = Debug|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.Debug|Win32.Build.0 = Debug|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.Release|Win32.ActiveCfg = Release|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.Release|Win32.Build.0 = Release|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {9501C518-8693-42F3-86A4-39B14983EC6C}.SSL-Release|Win32.Build.0 = Release|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Debug|Win32.ActiveCfg = Debug|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Debug|Win32.Build.0 = Debug|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Release|Win32.ActiveCfg = Release|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.Release|Win32.Build.0 = Release|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {0EC8287A-481E-45DC-8F95-BAD940AE1038}.SSL-Release|Win32.Build.0 = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.ActiveCfg = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.Build.0 = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.ActiveCfg = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.Build.0 = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.SSL-Release|Win32.Build.0 = Release|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Debug|Win32.ActiveCfg = Debug|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Debug|Win32.Build.0 = Debug|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Release|Win32.ActiveCfg = Release|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.Release|Win32.Build.0 = Release|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {A9C94D26-C90D-4860-8195-56929E893757}.SSL-Release|Win32.Build.0 = Release|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.Debug|Win32.ActiveCfg = Debug|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.Debug|Win32.Build.0 = Debug|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.Release|Win32.ActiveCfg = Release|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.Release|Win32.Build.0 = Release|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {F3BCA14E-F24D-4570-833E-8C20C4C393F7}.SSL-Release|Win32.Build.0 = Release|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Debug|Win32.ActiveCfg = Debug|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Debug|Win32.Build.0 = Debug|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Release|Win32.ActiveCfg = Release|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.Release|Win32.Build.0 = Release|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {4F7FDA11-42A4-4556-A631-15AA785CD1C1}.SSL-Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC8}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Debug|Win32.ActiveCfg = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Debug|Win32.Build.0 = Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Release|Win32.ActiveCfg = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.Release|Win32.Build.0 = Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {16CD976A-5D3B-4329-88BA-A32560CDFCC9}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug|Win32.ActiveCfg = Debug|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug|Win32.Build.0 = Debug|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release|Win32.ActiveCfg = Release|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release|Win32.Build.0 = Release|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {EEF031CB-FED8-451E-A471-91EC8D4F6750}.SSL-Release|Win32.Build.0 = Release|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Debug|Win32.ActiveCfg = Debug|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Debug|Win32.Build.0 = Debug|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Release|Win32.ActiveCfg = Release|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.Release|Win32.Build.0 = Release|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {6442C7DE-E500-4BA2-B821-98092F1EDCAF}.SSL-Release|Win32.Build.0 = Release|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Debug|Win32.ActiveCfg = Debug|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Debug|Win32.Build.0 = Debug|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Release|Win32.ActiveCfg = Release|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.Release|Win32.Build.0 = Release|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {214007F3-D6E8-4B07-AC00-9FB673FF539E}.SSL-Release|Win32.Build.0 = Release|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.Debug|Win32.ActiveCfg = Debug|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.Debug|Win32.Build.0 = Debug|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.Release|Win32.ActiveCfg = Release|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.Release|Win32.Build.0 = Release|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {82A7C86A-5F71-47C3-A74D-54C48C6CD5EE}.SSL-Release|Win32.Build.0 = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug|Win32.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug|Win32.Build.0 = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release|Win32.ActiveCfg = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release|Win32.Build.0 = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.SSL-Debug|Win32.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.SSL-Debug|Win32.Build.0 = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.SSL-Release|Win32.ActiveCfg = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.SSL-Release|Win32.Build.0 = Release|Win32 + {74D896AB-C35B-4BB3-9418-D18D509C8D22}.Debug|Win32.ActiveCfg = Debug|Win32 + {74D896AB-C35B-4BB3-9418-D18D509C8D22}.Debug|Win32.Build.0 = Debug|Win32 + {74D896AB-C35B-4BB3-9418-D18D509C8D22}.Release|Win32.ActiveCfg = Release|Win32 + {74D896AB-C35B-4BB3-9418-D18D509C8D22}.Release|Win32.Build.0 = Release|Win32 + {74D896AB-C35B-4BB3-9418-D18D509C8D22}.SSL-Debug|Win32.ActiveCfg = SSL-Debug|Win32 + {74D896AB-C35B-4BB3-9418-D18D509C8D22}.SSL-Debug|Win32.Build.0 = SSL-Debug|Win32 + {74D896AB-C35B-4BB3-9418-D18D509C8D22}.SSL-Release|Win32.ActiveCfg = SSL-Release|Win32 + {74D896AB-C35B-4BB3-9418-D18D509C8D22}.SSL-Release|Win32.Build.0 = SSL-Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/resiprocate/resip/recon/recon_9_0.vcproj b/src/libs/resiprocate/resip/recon/recon_9_0.vcproj new file mode 100644 index 00000000..4f57e51a --- /dev/null +++ b/src/libs/resiprocate/resip/recon/recon_9_0.vcproj @@ -0,0 +1,585 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="recon" + ProjectGUID="{16CD976A-5D3B-4329-88BA-A32560CDFCC7}" + RootNamespace="recon" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../reTurn&quot;;&quot;$(ProjectDir)/../../contrib/pcre&quot;;&quot;$(ProjectDir)/../../contrib/asio&quot;;&quot;$(ProjectDir)/../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)/vc70.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/librecon.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../reTurn&quot;;&quot;$(ProjectDir)/../../contrib/pcre&quot;;&quot;$(ProjectDir)/../../contrib/asio&quot;;&quot;$(ProjectDir)/../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/librecon.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../reTurn&quot;;&quot;$(ProjectDir)/../../contrib/pcre&quot;;&quot;$(ProjectDir)/../../contrib/asio&quot;;&quot;$(ProjectDir)/../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)/vc70.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/librecon.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../../&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../reTurn&quot;;&quot;$(ProjectDir)/../../contrib/pcre&quot;;&quot;$(ProjectDir)/../../contrib/asio&quot;;&quot;$(ProjectDir)/../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/librecon.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath=".\BridgeMixer.cxx" + > + </File> + <File + RelativePath=".\Conversation.cxx" + > + </File> + <File + RelativePath=".\ConversationManager.cxx" + > + </File> + <File + RelativePath=".\ConversationParticipantAssignment.cxx" + > + </File> + <File + RelativePath=".\ConversationProfile.cxx" + > + </File> + <File + RelativePath=".\DefaultDialogSet.cxx" + > + </File> + <File + RelativePath=".\DtmfEvent.cxx" + > + </File> + <File + RelativePath=".\FlowManagerSipXSocket.cxx" + > + </File> + <File + RelativePath=".\LocalParticipant.cxx" + > + </File> + <File + RelativePath=".\MediaEvent.cxx" + > + </File> + <File + RelativePath=".\MediaInterface.cxx" + > + </File> + <File + RelativePath=".\MediaResourceCache.cxx" + > + </File> + <File + RelativePath=".\MediaResourceParticipant.cxx" + > + </File> + <File + RelativePath=".\MediaStreamEvent.cxx" + > + </File> + <File + RelativePath=".\Participant.cxx" + > + </File> + <File + RelativePath=".\ReconSubsystem.cxx" + > + </File> + <File + RelativePath=".\RelatedConversationSet.cxx" + > + </File> + <File + RelativePath=".\RemoteParticipant.cxx" + > + </File> + <File + RelativePath=".\RemoteParticipantDialogSet.cxx" + > + </File> + <File + RelativePath=".\sdp\Sdp.cxx" + > + </File> + <File + RelativePath=".\sdp\SdpCandidate.cxx" + > + </File> + <File + RelativePath=".\sdp\SdpCandidatePair.cxx" + > + </File> + <File + RelativePath=".\sdp\SdpCodec.cxx" + > + </File> + <File + RelativePath=".\sdp\SdpHelperResip.cxx" + > + </File> + <File + RelativePath=".\sdp\SdpMediaLine.cxx" + > + </File> + <File + RelativePath=".\UserAgent.cxx" + > + </File> + <File + RelativePath=".\UserAgentClientSubscription.cxx" + > + </File> + <File + RelativePath=".\UserAgentDialogSetFactory.cxx" + > + </File> + <File + RelativePath=".\UserAgentMasterProfile.cxx" + > + </File> + <File + RelativePath=".\UserAgentRegistration.cxx" + > + </File> + <File + RelativePath=".\UserAgentServerAuthManager.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + <File + RelativePath=".\BridgeMixer.hxx" + > + </File> + <File + RelativePath=".\Conversation.hxx" + > + </File> + <File + RelativePath=".\ConversationManager.hxx" + > + </File> + <File + RelativePath=".\ConversationManagerCmds.hxx" + > + </File> + <File + RelativePath=".\ConversationParticipantAssignment.hxx" + > + </File> + <File + RelativePath=".\ConversationProfile.hxx" + > + </File> + <File + RelativePath=".\DefaultDialogSet.hxx" + > + </File> + <File + RelativePath=".\DtmfEvent.hxx" + > + </File> + <File + RelativePath=".\FlowManagerSipXSocket.hxx" + > + </File> + <File + RelativePath=".\HandleTypes.hxx" + > + </File> + <File + RelativePath=".\LocalParticipant.hxx" + > + </File> + <File + RelativePath=".\MediaEvent.hxx" + > + </File> + <File + RelativePath=".\MediaInterface.hxx" + > + </File> + <File + RelativePath=".\MediaResourceCache.hxx" + > + </File> + <File + RelativePath=".\MediaResourceParticipant.hxx" + > + </File> + <File + RelativePath=".\MediaStreamEvent.hxx" + > + </File> + <File + RelativePath=".\Participant.hxx" + > + </File> + <File + RelativePath=".\ReconSubsystem.hxx" + > + </File> + <File + RelativePath=".\RelatedConversationSet.hxx" + > + </File> + <File + RelativePath=".\RemoteParticipant.hxx" + > + </File> + <File + RelativePath=".\RemoteParticipantDialogSet.hxx" + > + </File> + <File + RelativePath=".\sdp\Sdp.hxx" + > + </File> + <File + RelativePath=".\sdp\SdpCandidate.hxx" + > + </File> + <File + RelativePath=".\sdp\SdpCandidatePair.hxx" + > + </File> + <File + RelativePath=".\sdp\SdpCodec.hxx" + > + </File> + <File + RelativePath=".\sdp\SdpHelperResip.hxx" + > + </File> + <File + RelativePath=".\sdp\SdpMediaLine.hxx" + > + </File> + <File + RelativePath=".\UserAgent.hxx" + > + </File> + <File + RelativePath=".\UserAgentClientSubscription.hxx" + > + </File> + <File + RelativePath=".\UserAgentCmds.hxx" + > + </File> + <File + RelativePath=".\UserAgentDialogSetFactory.hxx" + > + </File> + <File + RelativePath=".\UserAgentMasterProfile.hxx" + > + </File> + <File + RelativePath=".\UserAgentRegistration.hxx" + > + </File> + <File + RelativePath=".\UserAgentServerAuthManager.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + > + </Filter> + <File + RelativePath="ReadMe.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/recon/sdp/Sdp.cxx b/src/libs/resiprocate/resip/recon/sdp/Sdp.cxx new file mode 100644 index 00000000..079c2b2b --- /dev/null +++ b/src/libs/resiprocate/resip/recon/sdp/Sdp.cxx @@ -0,0 +1,416 @@ +#include "Sdp.hxx" +#include "SdpMediaLine.hxx" + +#include <rutil/Data.hxx> + +using namespace sdpcontainer; + +const char* Sdp::SdpNetTypeString[] = +{ + "NONE", + "IN" +}; + +const char* Sdp::SdpAddressTypeString[] = +{ + "NONE", + "IP4", + "IP6" +}; + +const char* Sdp::SdpBandwidthTypeString[] = +{ + "NONE", + "CT", + "AS", + "TIAS", + "RS", + "RR" +}; + +const char* Sdp::SdpConferenceTypeString[] = +{ + "NONE", + "BROADCAST", + "MODERATED", + "TEST", + "H332" +}; + +const char* Sdp::SdpGroupSemanticsString[] = +{ + "NONE", + "LS", + "FID", + "SRF", + "ANAT" +}; + + +// Constructor +Sdp::Sdp() +{ + mSdpVersion = 1; + mOriginatorSessionId = 0; + mOriginatorSessionVersion = 0; + mOriginatorNetType = NET_TYPE_NONE; + mOriginatorAddressType = ADDRESS_TYPE_NONE; + mConferenceType = CONFERENCE_TYPE_NONE; + mIcePassiveOnlyMode = false; + mMaximumPacketRate = 0; +} + +// Copy constructor +Sdp::Sdp(const Sdp& rhs) +{ + operator=(rhs); +} + +// Destructor +Sdp::~Sdp() +{ + clearMediaLines(); +} + +// Assignment operator +Sdp& +Sdp::operator=(const Sdp& rhs) +{ + if (this == &rhs) // handle the assignment to self case + return *this; + + // Assign values + mSdpVersion = rhs.mSdpVersion; + mOriginatorUserName = rhs.mOriginatorUserName; + mOriginatorSessionId = rhs.mOriginatorSessionId; + mOriginatorSessionVersion = rhs.mOriginatorSessionVersion; + mOriginatorNetType = rhs.mOriginatorNetType; + mOriginatorAddressType = rhs.mOriginatorAddressType; + mOriginatorUnicastAddress = rhs.mOriginatorUnicastAddress; + mSessionName = rhs.mSessionName; + mSessionInformation = rhs.mSessionInformation; + mSessionUri = rhs.mSessionUri; + mEmailAddresses = rhs.mEmailAddresses; + mPhoneNumbers = rhs.mPhoneNumbers; + mBandwidths = rhs.mBandwidths; + mTimes = rhs.mTimes; + mTimeZones = rhs.mTimeZones; + mCategory = rhs.mCategory; + mKeywords = rhs.mKeywords; + mToolNameAndVersion = rhs.mToolNameAndVersion; + mConferenceType = rhs.mConferenceType; + mCharSet = rhs.mCharSet; + mIcePassiveOnlyMode = rhs.mIcePassiveOnlyMode; + mGroups = rhs.mGroups; + mSessionLanguage = rhs.mSessionLanguage; + mDescriptionLanguage = rhs.mDescriptionLanguage; + mMaximumPacketRate = rhs.mMaximumPacketRate; + mFoundationIds = rhs.mFoundationIds; + + // Copy over media lines - deep copy of pointers + clearMediaLines(); + MediaLineList::const_iterator it = rhs.mMediaLines.begin(); + for(;it != rhs.mMediaLines.end(); it++) + { + SdpMediaLine* mediaLineCopy = new SdpMediaLine(*(*it)); + addMediaLine(mediaLineCopy); + } + + return *this; +} + +Sdp::SdpAddressType +Sdp::getAddressTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("IP4", dataType)) + { + return ADDRESS_TYPE_IP4; + } + else if(resip::isEqualNoCase("IP6", dataType)) + { + return ADDRESS_TYPE_IP6; + } + else + { + return ADDRESS_TYPE_NONE; + } +} + +Sdp::SdpBandwidthType +Sdp::SdpBandwidth::getTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("CT", dataType)) + { + return BANDWIDTH_TYPE_CT; + } + else if(resip::isEqualNoCase("AS", dataType)) + { + return BANDWIDTH_TYPE_AS; + } + else if(resip::isEqualNoCase("TIAS", dataType)) + { + return BANDWIDTH_TYPE_TIAS; + } + else if(resip::isEqualNoCase("RS", dataType)) + { + return BANDWIDTH_TYPE_RS; + } + else if(resip::isEqualNoCase("RR", dataType)) + { + return BANDWIDTH_TYPE_RR; + } + else + { + return BANDWIDTH_TYPE_NONE; + } +} + +Sdp::SdpConferenceType +Sdp::getConferenceTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("broadcast", dataType)) + { + return CONFERENCE_TYPE_BROADCAST; + } + else if(resip::isEqualNoCase("moderated", dataType)) + { + return CONFERENCE_TYPE_MODERATED; + } + else if(resip::isEqualNoCase("test", dataType)) + { + return CONFERENCE_TYPE_TEST; + } + else if(resip::isEqualNoCase("H332", dataType)) + { + return CONFERENCE_TYPE_H332; + } + else + { + return CONFERENCE_TYPE_NONE; + } +} + +Sdp::SdpGroupSemantics +Sdp::SdpGroup::getSemanticsFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("LS", dataType)) + { + return GROUP_SEMANTICS_LS; + } + else if(resip::isEqualNoCase("FID", dataType)) + { + return GROUP_SEMANTICS_FID; + } + else if(resip::isEqualNoCase("SRF", dataType)) + { + return GROUP_SEMANTICS_SRF; + } + else if(resip::isEqualNoCase("ANAT", dataType)) + { + return GROUP_SEMANTICS_ANAT; + } + else + { + return GROUP_SEMANTICS_NONE; + } +} + +void +Sdp::setOriginatorInfo(const char* userName, + UInt64 sessionId, + UInt64 sessionVersion, + SdpNetType netType, + SdpAddressType addressType, + const char* unicastAddress) +{ + mOriginatorUserName = userName; + mOriginatorSessionId = sessionId; + mOriginatorSessionVersion = sessionVersion; + mOriginatorNetType = netType; + mOriginatorAddressType = addressType; + mOriginatorUnicastAddress = unicastAddress; +} + +void +Sdp::addMediaLine(SdpMediaLine* mediaLine) +{ + mMediaLines.push_back(mediaLine); +} + +void +Sdp::clearMediaLines() +{ + MediaLineList::iterator it = mMediaLines.begin(); + for(;it != mMediaLines.end(); it++) + { + delete *it; + } + mMediaLines.clear(); +} + +const Sdp::MediaLineList& +Sdp::getMediaLines() const +{ + return mMediaLines; +} + +resip::Data +Sdp::getLocalFoundationId(SdpCandidate::SdpCandidateType candidateType, + const char * baseAddress, + const char * stunAddress) +{ + SdpFoundation sdpFoundation(candidateType, baseAddress, stunAddress); + + std::map<resip::Data, SdpFoundation>::iterator it; + for(it = mFoundationIds.begin(); it != mFoundationIds.end(); it++) + { + if(it->second == sdpFoundation) + { + return it->first; + } + } + + // Not found - insert + char foundationId[15]; + sprintf(foundationId, "%d", mFoundationIds.size() + 1); + mFoundationIds[foundationId] = sdpFoundation; + + return foundationId; +} + +EncodeStream& +sdpcontainer::operator<<( EncodeStream& strm, const Sdp& sdp) +{ + strm << "Sdp:" << std::endl + << "SdpVersion: " << sdp.mSdpVersion << std::endl + << "OrigUserName: '" << sdp.mOriginatorUserName << "'" << std::endl + << "OrigSessionId: " << sdp.mOriginatorSessionId << std::endl + << "OrigSessionVersion: " << sdp.mOriginatorSessionVersion << std::endl + << "OrigNetType: " << Sdp::SdpNetTypeString[sdp.mOriginatorNetType] << std::endl + << "OrigAddressType: " << Sdp::SdpAddressTypeString[sdp.mOriginatorAddressType] << std::endl + << "OrigUnicastAddr: '" << sdp.mOriginatorUnicastAddress << "'" << std::endl + << "SessionName: '" << sdp.mSessionName << "'" << std::endl + << "SessionInformation: '" << sdp.mSessionInformation << "'" << std::endl + << "SessionUri: '" << sdp.mSessionUri << "'" << std::endl; + + Sdp::EmailAddressList::const_iterator itEmail = sdp.mEmailAddresses.begin(); + for(;itEmail != sdp.mEmailAddresses.end(); itEmail++) + { + strm << "EmailAddress: '" << *itEmail << "'" << std::endl; + } + + Sdp::PhoneNumberList::const_iterator itPhone = sdp.mPhoneNumbers.begin(); + for(;itPhone != sdp.mPhoneNumbers.end(); itPhone++) + { + strm << "PhoneNumber: '" << *itPhone << "'" << std::endl; + } + + Sdp::BandwidthList::const_iterator itBandwidth = sdp.mBandwidths.begin(); + for(;itBandwidth != sdp.mBandwidths.end(); itBandwidth++) + { + strm << "Bandwidth: type=" << Sdp::SdpBandwidthTypeString[itBandwidth->getType()] + << ", bandwidth=" << itBandwidth->getBandwidth() << std::endl; + } + + Sdp::TimeList::const_iterator itTime = sdp.mTimes.begin(); + for(;itTime != sdp.mTimes.end(); itTime++) + { + strm << "Time: start=" << itTime->getStartTime() + << ", stop=" << itTime->getStopTime() << std::endl; + + Sdp::SdpTime::RepeatsList::const_iterator itRepeat = itTime->getRepeats().begin(); + for(;itRepeat!=itTime->getRepeats().end(); itRepeat++) + { + strm << "TimeRepeat: interval=" << itRepeat->getRepeatInterval() + << ", duration=" << itRepeat->getActiveDuration(); + + Sdp::SdpTime::SdpTimeRepeat::OffsetsList::const_iterator itOffset = itRepeat->getOffsetsFromStartTime().begin(); + for(;itOffset!=itRepeat->getOffsetsFromStartTime().end(); itOffset++) + { + strm << ", offset=" << *itOffset; + } + strm << std::endl; + } + } + + Sdp::TimeZoneList::const_iterator itTimeZone = sdp.mTimeZones.begin(); + for(;itTimeZone != sdp.mTimeZones.end(); itTimeZone++) + { + strm << "TimeZone: adjustment time=" << itTimeZone->getAdjustmentTime() + << ", offset=" << itTimeZone->getOffset() << std::endl; + } + + strm << "Category: '" << sdp.mCategory << "'" << std::endl + << "Keywords: '" << sdp.mKeywords << "'" << std::endl + << "ToolNameAndVersion: '" << sdp.mToolNameAndVersion << "'" << std::endl + << "ConferenceType: " << Sdp::SdpConferenceTypeString[sdp.mConferenceType] << std::endl + << "CharSet: '" << sdp.mCharSet << "'" << std::endl + << "IcePassiveOnlyMode: " << sdp.mIcePassiveOnlyMode << std::endl; + + Sdp::GroupList::const_iterator itGroup = sdp.mGroups.begin(); + for(;itGroup != sdp.mGroups.end(); itGroup++) + { + strm << "Group: semantics=" << Sdp::SdpGroupSemanticsString[itGroup->getSemantics()]; + Sdp::SdpGroup::TagsList::const_iterator itTag = itGroup->getIdentificationTags().begin(); + for(;itTag!=itGroup->getIdentificationTags().end(); itTag++) + { + strm << ", idTag=" << *itTag; + } + strm << std::endl; + } + + strm << "SessionLanguage: '" << sdp.mSessionLanguage << "'" << std::endl + << "DescriptionLanguage: '" << sdp.mDescriptionLanguage << "'" << std::endl + << "MaximumPacketRate: " << sdp.mMaximumPacketRate << std::endl; + + Sdp::MediaLineList::const_iterator itMediaLine = sdp.mMediaLines.begin(); + for(;itMediaLine!=sdp.mMediaLines.end();itMediaLine++) + { + strm << std::endl << *(*itMediaLine); + } + + return strm; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/sdp/Sdp.hxx b/src/libs/resiprocate/resip/recon/sdp/Sdp.hxx new file mode 100644 index 00000000..d53b36bf --- /dev/null +++ b/src/libs/resiprocate/resip/recon/sdp/Sdp.hxx @@ -0,0 +1,402 @@ +#if !defined(Sdp_hxx) +#define Sdp_hxx + +#include <iostream> +#include <list> +#include <map> + +#include "rutil/compat.hxx" +#include "rutil/HashMap.hxx" +#include "rutil/Data.hxx" + +#include "SdpCandidate.hxx" + +namespace sdpcontainer +{ + +class SdpMediaLine; + +// Container for SDP specification +// This class holds the information related to an SDP. +class Sdp +{ +public: + + typedef enum + { + NET_TYPE_NONE, + NET_TYPE_IN // "IN" - Internet - RFC4566 + } SdpNetType; + static const char* SdpNetTypeString[]; + + typedef enum + { + ADDRESS_TYPE_NONE, + ADDRESS_TYPE_IP4, // "IP4" - RFC4566 + ADDRESS_TYPE_IP6 // "IP6" - RFC4566 + } SdpAddressType; + static const char* SdpAddressTypeString[]; + + typedef enum + { + BANDWIDTH_TYPE_NONE, + BANDWIDTH_TYPE_CT, // "CT" - Conference Total - RFC4566 + BANDWIDTH_TYPE_AS, // "AS" - Application Specific - RFC4566 + BANDWIDTH_TYPE_TIAS, // "TIAS" - Transport Independent Application Specific - RFC3890, + BANDWIDTH_TYPE_RS, // "RS" - RTCP bandwidth on active senders - RFC3556 + BANDWIDTH_TYPE_RR // "RR" - RTCP bandwidth allocated to other participants - RFC3556 + } SdpBandwidthType; + static const char* SdpBandwidthTypeString[]; + + class SdpBandwidth + { + public: + SdpBandwidth(SdpBandwidthType type, unsigned int bandwidth) : mType(type), mBandwidth(bandwidth) {} + SdpBandwidth(const SdpBandwidth& rhs) : mType(rhs.mType), mBandwidth(rhs.mBandwidth) {} + + // Accessors + void setType(SdpBandwidthType type) { mType = type; } + SdpBandwidthType getType() const { return mType; } + static SdpBandwidthType getTypeFromString(const char * type); + + void setBandwidth(unsigned int bandwidth) { mBandwidth = bandwidth; } + unsigned int getBandwidth() const { return mBandwidth; } + + private: + SdpBandwidthType mType; + unsigned int mBandwidth; + }; + + class SdpTime + { + public: + class SdpTimeRepeat + { + public: + SdpTimeRepeat(unsigned int repeatInterval, unsigned int activeDuration) : + mRepeatInterval(repeatInterval), mActiveDuration(activeDuration) {} + SdpTimeRepeat(const SdpTimeRepeat& rhs) : + mRepeatInterval(rhs.mRepeatInterval), mActiveDuration(rhs.mActiveDuration), mOffsetsFromStartTime(rhs.mOffsetsFromStartTime) {} + + typedef std::list<unsigned int> OffsetsList; + + void setRepeatInterval(unsigned int repeatInterval) { mRepeatInterval = repeatInterval; } + unsigned int getRepeatInterval() const { return mRepeatInterval; } + + void setActiveDuration(unsigned int activeDuration) { mActiveDuration = activeDuration; } + unsigned int getActiveDuration() const { return mActiveDuration; } + + void addOffsetFromStartTime(unsigned int offset) { mOffsetsFromStartTime.push_back(offset); } + void clearOffsetsFromStartTime() { mOffsetsFromStartTime.clear(); } + const OffsetsList& getOffsetsFromStartTime() const { return mOffsetsFromStartTime; } + + private: + unsigned int mRepeatInterval; + unsigned int mActiveDuration; + OffsetsList mOffsetsFromStartTime; + }; + + SdpTime(UInt64 startTime, UInt64 stopTime) : mStartTime(startTime), mStopTime(stopTime) {} + SdpTime(const SdpTime& rhs) : mStartTime(rhs.mStartTime), mStopTime(rhs.mStopTime), mRepeats(rhs.mRepeats) {} + + typedef std::list<SdpTimeRepeat> RepeatsList; + + void setStartTime(UInt64 startTime) { mStartTime = startTime; } + UInt64 getStartTime() const { return mStartTime; } + + void setStopTime(UInt64 stopTime) { mStopTime = stopTime; } + UInt64 getStopTime() const { return mStopTime; } + + void addRepeat(const SdpTimeRepeat& sdpTimeRepeat) { mRepeats.push_back(sdpTimeRepeat); } + void clearRepeats() { mRepeats.clear(); } + const RepeatsList& getRepeats() const { return mRepeats; } + + private: + UInt64 mStartTime; + UInt64 mStopTime; + RepeatsList mRepeats; + }; + + class SdpTimeZone + { + public: + SdpTimeZone(int adjustmentTime, int offset) : mAdjustmentTime(adjustmentTime), mOffset(offset) {} + SdpTimeZone(const SdpTimeZone& rhs) : mAdjustmentTime(rhs.mAdjustmentTime), mOffset(rhs.mOffset) {} + + void setAdjustmentTime(int adjustmentTime) { mAdjustmentTime = adjustmentTime; } + int getAdjustmentTime() const { return mAdjustmentTime; } + + void setOffset(int offset) { mOffset = offset; } + int getOffset() const { return mOffset; } + + private: + int mAdjustmentTime; + int mOffset; + }; + + typedef enum + { + CONFERENCE_TYPE_NONE, + CONFERENCE_TYPE_BROADCAST, // "broadcast" - RFC4566 + CONFERENCE_TYPE_MODERATED, // "moderated" - RFC4566 + CONFERENCE_TYPE_TEST, // "test" - RFC4566 + CONFERENCE_TYPE_H332 // "H332" - RFC4566 + } SdpConferenceType; + static const char* SdpConferenceTypeString[]; + + typedef enum + { + GROUP_SEMANTICS_NONE, + GROUP_SEMANTICS_LS, // "LS" - Lip Sync - RFC3388 + GROUP_SEMANTICS_FID, // "FID" - Flow Identifier - RFC3388 + GROUP_SEMANTICS_SRF, // "SRF" - Single Reservation Flow - RFC3524 + GROUP_SEMANTICS_ANAT // "ANAT" - Alternative Network Address Types - RFC4091 + } SdpGroupSemantics; + static const char* SdpGroupSemanticsString[]; + + class SdpGroup + { + public: + SdpGroup(SdpGroupSemantics semantics) : mSemantics(semantics) {} + SdpGroup(const SdpGroup& rhs) : mSemantics(rhs.mSemantics), mIdentificationTags(rhs.mIdentificationTags) {} + + typedef std::list<resip::Data> TagsList; + + void setSemantics(SdpGroupSemantics semantics) { mSemantics = semantics; } + SdpGroupSemantics getSemantics() const { return mSemantics; } + static SdpGroupSemantics getSemanticsFromString(const char * type); + + void addIdentificationTag(const char * identificationTag) { mIdentificationTags.push_back(identificationTag); } + void clearIdentificationTags() { mIdentificationTags.clear(); } + const TagsList& getIdentificationTags() const { return mIdentificationTags; } + + private: + SdpGroupSemantics mSemantics; + TagsList mIdentificationTags; + }; + + class SdpFoundation + { + public: + SdpFoundation() : mCandidateType(SdpCandidate::CANDIDATE_TYPE_NONE) {} + SdpFoundation(SdpCandidate::SdpCandidateType candidateType, const char * baseAddress, const char * stunAddress) : + mCandidateType(candidateType), mBaseAddress(baseAddress), mStunAddress(stunAddress) {} + SdpFoundation(const SdpFoundation& rhs) : + mCandidateType(rhs.mCandidateType), mBaseAddress(rhs.mBaseAddress), mStunAddress(rhs.mStunAddress) {} + + bool operator==(const SdpFoundation& rhs) { return mCandidateType == rhs.mCandidateType && + mBaseAddress == rhs.mBaseAddress && + mStunAddress == rhs.mStunAddress; } + private: + SdpCandidate::SdpCandidateType mCandidateType; + resip::Data mBaseAddress; + resip::Data mStunAddress; + }; + + Sdp(); + Sdp(const Sdp& rSdp); + virtual ~Sdp(); + + Sdp& operator=(const Sdp& rhs); + + void setSdpVersion(unsigned int sdpVersion) { mSdpVersion = sdpVersion; } + + void setOriginatorInfo(const char* userName, UInt64 sessionId, UInt64 sessionVersion, SdpNetType netType, SdpAddressType addressType, const char* unicastAddress); + void setOriginatorUserName(const char* originatorUserName) { mOriginatorUserName = originatorUserName; } + void setOriginatorSessionId(UInt64 originatorSessionId) { mOriginatorSessionId = originatorSessionId; } + void setOriginatorSessionVersion(UInt64 originatorSessionVersion) { mOriginatorSessionVersion = originatorSessionVersion; } + void setOriginatorNetType(SdpNetType originatorNetType) { mOriginatorNetType = originatorNetType; } + void setOriginatorAddressType(SdpAddressType originatorAddressType) { mOriginatorAddressType = originatorAddressType; } + void setOriginatorUnicastAddress(const char* originatorUnicastAddress) { mOriginatorUnicastAddress = originatorUnicastAddress; } + + void setSessionName(const char * sessionName) { mSessionName = sessionName; } + void setSessionInformation(const char * sessionInformation) { mSessionInformation = sessionInformation; } + void setSessionUri(const char * sessionUri) { mSessionUri = sessionUri; } + + void addEmailAddress(const char * emailAddress) { mEmailAddresses.push_back(emailAddress); } + void clearEmailAddresses() { mEmailAddresses.clear(); } + + void addPhoneNumber(const char * phoneNumber) { mPhoneNumbers.push_back(phoneNumber); } + void clearPhoneNumbers() { mPhoneNumbers.clear(); } + + void addBandwidth(SdpBandwidthType type, unsigned int bandwidth) { addBandwidth(SdpBandwidth(type, bandwidth)); } + void addBandwidth(const SdpBandwidth& sdpBandwidth) { mBandwidths.push_back(sdpBandwidth); } + void clearBandwidths() { mBandwidths.clear(); } + + void addTime(UInt64 startTime, UInt64 stopTime) { addTime(SdpTime(startTime, stopTime)); } + void addTime(const SdpTime& time) { mTimes.push_back(time); } + void clearTimes() { mTimes.clear(); } + + void addTimeZone(int adjustmentTime, int offset) { addTimeZone(SdpTimeZone(adjustmentTime, offset)); } + void addTimeZone(const SdpTimeZone& timeZone) { mTimeZones.push_back(timeZone); } + void clearTimeZones() { mTimeZones.clear(); } + + void setCategory(const char * category) { mCategory = category; } + void setKeywords(const char * keywords) { mKeywords = keywords; } + void setToolNameAndVersion(const char * toolNameAndVersion) { mToolNameAndVersion = toolNameAndVersion; } + void setConferenceType(SdpConferenceType conferenceType) { mConferenceType = conferenceType; } + void setCharSet(const char * charSet) { mCharSet = charSet; } + void setIcePassiveOnlyMode(bool icePassiveOnlyMode) { mIcePassiveOnlyMode = icePassiveOnlyMode; } + + void addGroup(const SdpGroup& group) { mGroups.push_back(group); } + void clearGroups() { mGroups.clear(); } + + void setSessionLanguage(const char * sessionLanguage) { mSessionLanguage = sessionLanguage; } + void setDescriptionLanguage(const char * descriptionLanguage) { mDescriptionLanguage = descriptionLanguage; } + void setMaximumPacketRate(double maximumPacketRate) { mMaximumPacketRate = maximumPacketRate; } + + void addMediaLine(SdpMediaLine* mediaLine); + void clearMediaLines(); + + void toString(resip::Data& sdpString) const; + + static SdpAddressType getAddressTypeFromString(const char * type); + + unsigned int getSdpVersion() const { return mSdpVersion; } + + const resip::Data& getOriginatorUserName() const { return mOriginatorUserName; } + UInt64 getOriginatorSessionId() const { return mOriginatorSessionId; } + UInt64 getOriginatorSessionVersion() const { return mOriginatorSessionVersion; } + SdpNetType getOriginatorNetType() const { return mOriginatorNetType; } + SdpAddressType getOriginatorAddressType() const { return mOriginatorAddressType; } + const resip::Data& getOriginatorUnicastAddress() const { return mOriginatorUnicastAddress; } + + const resip::Data& getSessionName() const { return mSessionName; } + const resip::Data& getSessionInformation() const { return mSessionInformation; } + const resip::Data& getSessionUri() const { return mSessionUri; } + + typedef std::list<resip::Data> EmailAddressList; + typedef std::list<resip::Data> PhoneNumberList; + typedef std::list<SdpBandwidth> BandwidthList; + typedef std::list<SdpTime> TimeList; + typedef std::list<SdpTimeZone> TimeZoneList; + typedef std::list<SdpGroup> GroupList; + typedef std::list<SdpMediaLine*> MediaLineList; + + const EmailAddressList& getEmailAddresses() const { return mEmailAddresses; } + const PhoneNumberList& getPhoneNumbers() const { return mPhoneNumbers; } + const BandwidthList& getBandwidths() const { return mBandwidths; } + const TimeList& getTimes() const { return mTimes; } + const TimeZoneList& getTimeZones() const { return mTimeZones; } + + const resip::Data& getCategory() const { return mCategory; } + const resip::Data& getKeywords() const { return mKeywords; } + const resip::Data& getToolNameAndVersion() const { return mToolNameAndVersion; } + SdpConferenceType getConferenceType() const { return mConferenceType; } + static SdpConferenceType getConferenceTypeFromString(const char * type); + const resip::Data& getCharSet() const { return mCharSet; } + bool isIcePassiveOnlyMode() const { return mIcePassiveOnlyMode; } + + const GroupList& getGroups() const { return mGroups; } + + const resip::Data& getSessionLanguage() const { return mSessionLanguage; } + const resip::Data& getDescriptionLanguage() const { return mDescriptionLanguage; } + double getMaximumPacketRate() const { return mMaximumPacketRate; } + + const MediaLineList& getMediaLines() const; + + resip::Data getLocalFoundationId(SdpCandidate::SdpCandidateType candidateType, const char * baseAddress, const char * stunAddress=0); + +private: + // v= + unsigned int mSdpVersion; + + // o= + resip::Data mOriginatorUserName; + UInt64 mOriginatorSessionId; + UInt64 mOriginatorSessionVersion; + SdpNetType mOriginatorNetType; + SdpAddressType mOriginatorAddressType; + resip::Data mOriginatorUnicastAddress; + + // s= + resip::Data mSessionName; + + // i= + resip::Data mSessionInformation; + + // u= + resip::Data mSessionUri; + + // e= + EmailAddressList mEmailAddresses; + + // p= + PhoneNumberList mPhoneNumbers; + + // c= is only stored in sdpMediaLine + + // b= + BandwidthList mBandwidths; + + // t=, r= + TimeList mTimes; + + // z= + TimeZoneList mTimeZones; + + // k= is only stored in sdpMediaLine + + // a= session level only attributes + resip::Data mCategory; // a=cat:<category> - RFC4566 + resip::Data mKeywords; // a=keywds:<keywords> - RFC4566 + resip::Data mToolNameAndVersion; // a=tool:<name and version of tool> - RFC4566 + SdpConferenceType mConferenceType; // a=type:<conference type> - RFC4566 + resip::Data mCharSet; // a=charset:<character set> - RFC4566 + bool mIcePassiveOnlyMode; // a=ice-passive - ietf-draft-mmusic-ice-12 + GroupList mGroups; // a=group:<semantics> <id-tag> ... - RFC3388 + + // a= attributes that have meaning when not associated to a particular media line + resip::Data mSessionLanguage; // a=lang:<language tag> - RFC4566 + resip::Data mDescriptionLanguage; // a=sdplang:<language tag> - RFC4566 + double mMaximumPacketRate; // a=maxprate:<packetrate> in packets/s - RFC3890 + + // Media Lines + MediaLineList mMediaLines; + + // Foundation Id + std::map<resip::Data, SdpFoundation> mFoundationIds; + + friend EncodeStream& operator<<(EncodeStream& strm, const Sdp& ); +}; + +EncodeStream& operator<<(EncodeStream& strm, const Sdp& ); + +} // namespace + +#endif + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/sdp/SdpCandidate.cxx b/src/libs/resiprocate/resip/recon/sdp/SdpCandidate.cxx new file mode 100644 index 00000000..206bebd3 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/sdp/SdpCandidate.cxx @@ -0,0 +1,280 @@ +#include "SdpCandidate.hxx" + +using namespace sdpcontainer; + +const char* SdpCandidate::SdpCandidateTransportTypeString[] = +{ + "NONE", + "UDP", + "TCP-SO", + "TCP-ACT", + "TCP-PASS", + "TLS-SO", + "TLS-ACT", + "TLS-PASS" +}; + +const char* SdpCandidate::SdpCandidateTypeString[] = +{ + "NONE", + "HOST", + "SRFLX", + "PRFLX", + "RELAY" +}; + +// Constructor +SdpCandidate::SdpCandidate(const char * foundation, + unsigned int id, + SdpCandidateTransportType transport, + UInt64 priority, + const char * connectionAddress, + unsigned int port, + SdpCandidateType candidateType, + const char * relatedAddress, + unsigned int relatedPort, + bool inUse) : + mFoundation(foundation), + mId(id), + mTransport(transport), + mPriority(priority), + mConnectionAddress(connectionAddress), + mPort(port), + mCandidateType(candidateType), + mRelatedAddress(relatedAddress), + mRelatedPort(relatedPort), + mInUse(inUse) +{ +} + +// Copy constructor +SdpCandidate::SdpCandidate(const SdpCandidate& rhs) +{ + operator=(rhs); +} + +// Destructor +SdpCandidate::~SdpCandidate() +{ +} + +SdpCandidate& +SdpCandidate::operator=(const SdpCandidate& rhs) +{ + if (this == &rhs) // handle the assignment to self case + return *this; + + // Assign values + mFoundation = rhs.mFoundation; + mId = rhs.mId; + mTransport = rhs.mTransport; + mPriority = rhs.mPriority; + mConnectionAddress = rhs.mConnectionAddress; + mPort = rhs.mPort; + mCandidateType = rhs.mCandidateType; + mRelatedAddress = rhs.mRelatedAddress; + mRelatedPort = rhs.mRelatedPort; + mInUse = rhs.mInUse; + mExtensionAttributes = rhs.mExtensionAttributes; + + return *this; +} + +bool +SdpCandidate::operator==(const SdpCandidate& rhs) const +{ + return mFoundation == rhs.mFoundation && + mId == rhs.mId && + mTransport == rhs.mTransport && + mPriority == rhs.mPriority && + mConnectionAddress == rhs.mConnectionAddress && + mPort == rhs.mPort && + mCandidateType == rhs.mCandidateType && + mRelatedAddress == rhs.mRelatedAddress && + mRelatedPort == rhs.mRelatedPort && + mExtensionAttributes == rhs.mExtensionAttributes && + mInUse == rhs.mInUse; +} + +bool +SdpCandidate::operator!=(const SdpCandidate& rhs) const +{ + return !operator==(rhs); +} + +bool +SdpCandidate::operator<(const SdpCandidate& rhs) const +{ + if(mPriority != rhs.mPriority) + { + return mPriority > rhs.mPriority; // We want to order a list of these from highest priority to lowest - so condition is reversed + } + + // Priority should be unique, so we shouldn't get here, but implementation is included for completeness + if(mFoundation != rhs.mFoundation) + { + return mFoundation < rhs.mFoundation; + } + + if(mId != rhs.mId) + { + return mId < rhs.mId; + } + + if(mTransport != rhs.mTransport) + { + return mTransport < rhs.mTransport; + } + + if(mConnectionAddress != rhs.mConnectionAddress) + { + return mConnectionAddress < rhs.mConnectionAddress; + } + + if(mPort != rhs.mPort) + { + return mPort < rhs.mPort; + } + + if(mCandidateType != rhs.mCandidateType) + { + return mCandidateType < rhs.mCandidateType; + } + + if(mRelatedAddress != rhs.mRelatedAddress) + { + return mRelatedAddress < rhs.mRelatedAddress; + } + + if(mRelatedPort != rhs.mRelatedPort) + { + return mRelatedPort < rhs.mRelatedPort; + } + + return false; // equal +} + +SdpCandidate::SdpCandidateTransportType +SdpCandidate::getCandidateTransportTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("udp", dataType)) + { + return CANDIDATE_TRANSPORT_TYPE_UDP; + } + else if(resip::isEqualNoCase("tcp-so", dataType)) + { + return CANDIDATE_TRANSPORT_TYPE_TCP_SO; + } + else if(resip::isEqualNoCase("tcp-act", dataType)) + { + return CANDIDATE_TRANSPORT_TYPE_TCP_ACT; + } + else if(resip::isEqualNoCase("tcp-pass", dataType)) + { + return CANDIDATE_TRANSPORT_TYPE_TCP_PASS; + } + else if(resip::isEqualNoCase("tls-so", dataType)) + { + return CANDIDATE_TRANSPORT_TYPE_TLS_SO; + } + else if(resip::isEqualNoCase("tls-act", dataType)) + { + return CANDIDATE_TRANSPORT_TYPE_TLS_ACT; + } + else if(resip::isEqualNoCase("tls-pass", dataType)) + { + return CANDIDATE_TRANSPORT_TYPE_TLS_PASS; + } + else + { + return CANDIDATE_TRANSPORT_TYPE_NONE; + } +} + +SdpCandidate::SdpCandidateType +SdpCandidate::getCandidateTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("host", dataType)) + { + return CANDIDATE_TYPE_HOST; + } + else if(resip::isEqualNoCase("srflx", dataType)) + { + return CANDIDATE_TYPE_SRFLX; + } + else if(resip::isEqualNoCase("prflx", dataType)) + { + return CANDIDATE_TYPE_PRFLX; + } + else if(resip::isEqualNoCase("relay", dataType)) + { + return CANDIDATE_TYPE_RELAY; + } + else + { + return CANDIDATE_TYPE_NONE; + } +} + +EncodeStream& +sdpcontainer::operator<<( EncodeStream& strm, const SdpCandidate& sdpCandidate) +{ + strm << "SdpCandidate: foundation=" << sdpCandidate.mFoundation + << ", id=" << sdpCandidate.mId + << ", transport=" << SdpCandidate::SdpCandidateTransportTypeString[sdpCandidate.mTransport] + << ", priority=" << sdpCandidate.mPriority + << ", addr=" << sdpCandidate.mConnectionAddress + << ", port=" << sdpCandidate.mPort + << ", type=" << SdpCandidate::SdpCandidateTypeString[sdpCandidate.mCandidateType] + << ", relatedAddr=" << sdpCandidate.mRelatedAddress + << ", relatedPort=" << sdpCandidate.mRelatedPort + << ", "; + + SdpCandidate::SdpCandidateExtensionAttributeList::const_iterator it = sdpCandidate.mExtensionAttributes.begin(); + for(;it != sdpCandidate.mExtensionAttributes.end(); it++) + { + strm << it->getName() << "=" << it->getValue() << ", "; + } + + strm << "inUse=" << sdpCandidate.mInUse << std::endl; + return strm; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/sdp/SdpCandidate.hxx b/src/libs/resiprocate/resip/recon/sdp/SdpCandidate.hxx new file mode 100644 index 00000000..ff53fff0 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/sdp/SdpCandidate.hxx @@ -0,0 +1,166 @@ +#if !defined(SdpCandidate_hxx) +#define SdpCandidate_hxx + +#include "rutil/compat.hxx" +#include "rutil/Data.hxx" +#include <list> + +namespace sdpcontainer +{ + +class SdpCandidate +{ +public: + + typedef enum + { + CANDIDATE_TRANSPORT_TYPE_NONE, + CANDIDATE_TRANSPORT_TYPE_UDP, // "udp" - draft-ietf-mmusic-ice-12 + CANDIDATE_TRANSPORT_TYPE_TCP_SO, // "tcp-so" - TCP simultaneous-open - draft-ietf-mmusic-ice-tcp-02 + CANDIDATE_TRANSPORT_TYPE_TCP_ACT, // "tcp-act" - TCP active - draft-ietf-mmusic-ice-tcp-02 + CANDIDATE_TRANSPORT_TYPE_TCP_PASS, // "tcp-pass" - TCP passive - draft-ietf-mmusic-ice-tcp-02 + CANDIDATE_TRANSPORT_TYPE_TLS_SO, // "tls-so" - TCP simultaneous-open - draft-ietf-mmusic-ice-tcp-02 + CANDIDATE_TRANSPORT_TYPE_TLS_ACT, // "tls-act" - TCP active - draft-ietf-mmusic-ice-tcp-02 + CANDIDATE_TRANSPORT_TYPE_TLS_PASS // "tls-pass" - TCP passive - draft-ietf-mmusic-ice-tcp-02 + } SdpCandidateTransportType; + static const char* SdpCandidateTransportTypeString[]; + + typedef enum + { + CANDIDATE_TYPE_NONE, + CANDIDATE_TYPE_HOST, // "host" - draft-ietf-mmusic-ice-12 + CANDIDATE_TYPE_SRFLX, // "srflx" - server reflexive - draft-ietf-mmusic-ice-12 + CANDIDATE_TYPE_PRFLX, // "prflx" - peer reflexive - draft-ietf-mmusic-ice-12 + CANDIDATE_TYPE_RELAY, // "relay" - draft-ietf-mmusic-ice-12 + } SdpCandidateType; + static const char* SdpCandidateTypeString[]; + + class SdpCandidateExtensionAttribute + { + public: + SdpCandidateExtensionAttribute(const char * name, const char * value) : mName(name), mValue(value) {} + SdpCandidateExtensionAttribute(const SdpCandidateExtensionAttribute& rhs) : mName(rhs.mName), mValue(rhs.mValue) {} + + bool operator==(const SdpCandidateExtensionAttribute& rhs) const { return mName == rhs.mName && mValue == rhs.mValue; } + + void setName(const char * name) { mName = name; } + const resip::Data& getName() const { return mName; } + + void setValue(const char * value) { mValue = value; } + const resip::Data& getValue() const { return mValue; } + + private: + resip::Data mName; + resip::Data mValue; + }; + + SdpCandidate(const char * foundation = 0, + unsigned int id = 0, + SdpCandidateTransportType transport = CANDIDATE_TRANSPORT_TYPE_NONE, + UInt64 priority = 0, + const char * connectionAddress = 0, + unsigned int port = 0, + SdpCandidateType candidateType = CANDIDATE_TYPE_NONE, + const char * relatedAddress = 0, + unsigned int relatedPort = 0, + bool inUse = false); + + SdpCandidate(const SdpCandidate& rSdpCandidate); + + virtual ~SdpCandidate(); + + typedef std::list<SdpCandidateExtensionAttribute> SdpCandidateExtensionAttributeList; + + SdpCandidate& operator=(const SdpCandidate& rhs); + bool operator<(const SdpCandidate& rhs) const; + bool operator==(const SdpCandidate& rhs) const; + bool operator!=(const SdpCandidate& rhs) const; + + void setFoundation(const char * foundation) { mFoundation = foundation; } + void setId(unsigned int id) { mId = id; } + void setTransport(SdpCandidateTransportType transport) { mTransport = transport; } + void setPriority(UInt64 priority) { mPriority = priority; } + void setConnectionAddress(const char * connectionAddress) { mConnectionAddress = connectionAddress; } + void setPort(unsigned int port) { mPort = port; } + void setCandidateType(SdpCandidateType candidateType) { mCandidateType = candidateType; } + void setRelatedAddress(const char * relatedAddress) { mRelatedAddress = relatedAddress; } + void setRelatedPort(unsigned int relatedPort) { mRelatedPort = relatedPort; } + + void addExtensionAttribute(const char * name, const char * value) { addExtensionAttribute(SdpCandidateExtensionAttribute(name, value)); } + void addExtensionAttribute(const SdpCandidateExtensionAttribute& sdpCandidateExtensionAttribute) { mExtensionAttributes.push_back(sdpCandidateExtensionAttribute); } + void clearExtensionAttributes() { mExtensionAttributes.clear(); } + + void setInUse(bool inUse) { mInUse = inUse; } + + void toString(resip::Data& sdpCandidateString) const; + + const resip::Data& getFoundation() const { return mFoundation; } + unsigned int getId() const { return mId; } + SdpCandidateTransportType getTransport() const { return mTransport; } + static SdpCandidateTransportType getCandidateTransportTypeFromString(const char * type); + UInt64 getPriority() const { return mPriority; } + const resip::Data& getConnectionAddress() const { return mConnectionAddress; } + unsigned int getPort() const { return mPort; } + SdpCandidateType getCandidateType() const { return mCandidateType; } + static SdpCandidateType getCandidateTypeFromString(const char * type); + const resip::Data& getRelatedAddress() const { return mRelatedAddress; } + unsigned int getRelatedPort() const { return mRelatedPort; } + const SdpCandidateExtensionAttributeList& getExtensionAttributes() const { return mExtensionAttributes; } + bool isInUse() const { return mInUse; } + +private: + resip::Data mFoundation; + unsigned int mId; + SdpCandidateTransportType mTransport; + UInt64 mPriority; + resip::Data mConnectionAddress; + unsigned int mPort; + SdpCandidateType mCandidateType; + resip::Data mRelatedAddress; + unsigned int mRelatedPort; + SdpCandidateExtensionAttributeList mExtensionAttributes; + + bool mInUse; + + friend EncodeStream& operator<<(EncodeStream& strm, const SdpCandidate& ); +}; + +EncodeStream& operator<< ( EncodeStream& strm, const SdpCandidate& ); + +} // namespace + +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/sdp/SdpCandidatePair.cxx b/src/libs/resiprocate/resip/recon/sdp/SdpCandidatePair.cxx new file mode 100644 index 00000000..81655de7 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/sdp/SdpCandidatePair.cxx @@ -0,0 +1,192 @@ +#include "SdpCandidatePair.hxx" + +using namespace sdpcontainer; + +const char* SdpCandidatePair::SdpCandidatePairCheckStateString[] = +{ + "FROZEN", + "WAITING", + "INPROGRESS", + "SUCCEEDED", + "FAILED" +}; + +const char* SdpCandidatePair::SdpCandidatePairOffererTypeString[] = +{ + "LOCAL", + "REMOTE" +}; + +// Constructor +SdpCandidatePair::SdpCandidatePair(const SdpCandidate& localCandidate, + const SdpCandidate& remoteCandidate, + SdpCandidatePairOffererType offerer) +: mLocalCandidate(localCandidate) +, mRemoteCandidate(remoteCandidate) +, mOfferer(offerer) +{ + resetPriority(); + mCheckState = CHECK_STATE_FROZEN; +} + +// Copy constructor +SdpCandidatePair::SdpCandidatePair(const SdpCandidatePair& rhs) +{ + operator=(rhs); +} + +// Destructor +SdpCandidatePair::~SdpCandidatePair() +{ +} + +// Assignment operator +SdpCandidatePair& +SdpCandidatePair::operator=(const SdpCandidatePair& rhs) +{ + if (this == &rhs) // handle the assignment to self case + return *this; + + // Assign values + mLocalCandidate = rhs.mLocalCandidate; + mRemoteCandidate = rhs.mRemoteCandidate; + mOfferer = rhs.mOfferer; + mPriority = rhs.mPriority; + mCheckState = rhs.mCheckState; + + return *this; +} + +bool SdpCandidatePair::setCheckState(const SdpCandidatePairCheckState checkState) +{ + bool stateChangeSuccess=false; + switch(mCheckState) + { + case CHECK_STATE_FROZEN: + switch(checkState) + { + case CHECK_STATE_WAITING: + case CHECK_STATE_INPROGRESS: + mCheckState = checkState; + stateChangeSuccess = true; + break; + default: + assert(false); + } + break; + case CHECK_STATE_WAITING: + switch(checkState) + { + case CHECK_STATE_INPROGRESS: + mCheckState = checkState; + stateChangeSuccess = true; + break; + default: + assert(false); + } + break; + case CHECK_STATE_INPROGRESS: + switch(checkState) + { + case CHECK_STATE_SUCCEEDED: + case CHECK_STATE_FAILED: + mCheckState = checkState; + stateChangeSuccess = true; + break; + default: + assert(false); + } + break; + case CHECK_STATE_SUCCEEDED: + case CHECK_STATE_FAILED: + default: + assert(false); + break; + } + return stateChangeSuccess; +} + +bool SdpCandidatePair::operator<(const SdpCandidatePair& rhs) const +{ + if(mPriority != rhs.mPriority) + { + return mPriority > rhs.mPriority; // We want to order a list of these from highest priority to lowest - so condition is reversed + } + + if(mCheckState != rhs.mCheckState) + { + return mCheckState < rhs.mCheckState; + } + + if(mLocalCandidate != rhs.mLocalCandidate) + { + return mLocalCandidate < rhs.mLocalCandidate; + } + + if(mRemoteCandidate != rhs.mRemoteCandidate) + { + return mRemoteCandidate < rhs.mRemoteCandidate; + } + + return false; // equal +} + +#define sdpMin(a,b) (a < b ? a : a > b ? b : a) +#define sdpMax(a,b) (a > b ? a : a < b ? b : a) +void SdpCandidatePair::resetPriority() +{ + UInt64 offererPriority = mOfferer == OFFERER_LOCAL ? mLocalCandidate.getPriority() : mRemoteCandidate.getPriority(); + UInt64 answererPriority = mOfferer == OFFERER_LOCAL ? mRemoteCandidate.getPriority() : mLocalCandidate.getPriority(); + mPriority = (sdpMin(offererPriority, answererPriority)<<32) + + (sdpMax(offererPriority, answererPriority)<<1) + + (offererPriority > answererPriority ? 1 : 0); +} + +EncodeStream& +sdpcontainer::operator<<( EncodeStream& strm, const SdpCandidatePair& sdpCandidatePair) +{ + strm << "SdpCandidatePair:" << std::endl + << " Priority: " << sdpCandidatePair.mPriority << std::endl + << " State: " << SdpCandidatePair::SdpCandidatePairCheckStateString[sdpCandidatePair.mCheckState] << std::endl + << " Offerer: " << SdpCandidatePair::SdpCandidatePairOffererTypeString[sdpCandidatePair.mOfferer] << std::endl + << " " << sdpCandidatePair.mLocalCandidate + << " " << sdpCandidatePair.mRemoteCandidate; + + return strm; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/sdp/SdpCandidatePair.hxx b/src/libs/resiprocate/resip/recon/sdp/SdpCandidatePair.hxx new file mode 100644 index 00000000..fd3a27c0 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/sdp/SdpCandidatePair.hxx @@ -0,0 +1,106 @@ +#if !defined(SdpCandidatePair_hxx) +#define SdpCandidatePair_hxx + +#include "SdpCandidate.hxx" + +namespace sdpcontainer +{ + +class SdpCandidatePair +{ +public: + + typedef enum + { + CHECK_STATE_FROZEN, + CHECK_STATE_WAITING, + CHECK_STATE_INPROGRESS, + CHECK_STATE_SUCCEEDED, + CHECK_STATE_FAILED + } SdpCandidatePairCheckState; + static const char* SdpCandidatePairCheckStateString[]; + + typedef enum + { + OFFERER_LOCAL, + OFFERER_REMOTE + } SdpCandidatePairOffererType; + static const char* SdpCandidatePairOffererTypeString[]; + + SdpCandidatePair(const SdpCandidate& localCandidate, + const SdpCandidate& remoteCandidate, + SdpCandidatePairOffererType offerer); + + SdpCandidatePair(const SdpCandidatePair& rSdpCandidatePair); + + virtual + ~SdpCandidatePair(); + + SdpCandidatePair& operator=(const SdpCandidatePair& rhs); + bool operator<(const SdpCandidatePair& rhs) const; + + void setLocalCandidate(const SdpCandidate& localCandidate) { mLocalCandidate = localCandidate; resetPriority(); } + void setRemoteCandidate(const SdpCandidate& remoteCandidate) { mRemoteCandidate = remoteCandidate; resetPriority(); } + void setOfferer(const SdpCandidatePairOffererType offerer) { mOfferer = offerer; resetPriority(); } + bool setCheckState(const SdpCandidatePairCheckState checkState); + + void toString(resip::Data& sdpCandidateString) const; + + const SdpCandidate& getLocalCandidate() const { return mLocalCandidate; } + const SdpCandidate& getRemoteCandidate() const { return mRemoteCandidate; } + SdpCandidatePairOffererType getOfferer() const { return mOfferer; } + UInt64 getPriority() const { return mPriority; } + SdpCandidatePairCheckState getCheckState() const { return mCheckState; } + +private: + void resetPriority(); + + SdpCandidate mLocalCandidate; + SdpCandidate mRemoteCandidate; + SdpCandidatePairOffererType mOfferer; + UInt64 mPriority; + SdpCandidatePairCheckState mCheckState; + + friend EncodeStream& operator<<(EncodeStream& strm, const SdpCandidatePair& ); +}; + +EncodeStream& operator<< ( EncodeStream& strm, const SdpCandidatePair& ); + +} // namespace + +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/sdp/SdpCodec.cxx b/src/libs/resiprocate/resip/recon/sdp/SdpCodec.cxx new file mode 100644 index 00000000..de1f36fd --- /dev/null +++ b/src/libs/resiprocate/resip/recon/sdp/SdpCodec.cxx @@ -0,0 +1,94 @@ +#include "SdpCodec.hxx" + +using namespace sdpcontainer; + +SdpCodec::SdpCodec(unsigned int payloadType, + const char* mimeType, + const char* mimeSubtype, + unsigned int rate, + unsigned int packetTime, + unsigned int numChannels, + const char* formatParameters) : + mPayloadType(payloadType), + mMimeType(mimeType), + mMimeSubtype(mimeSubtype), + mRate(rate), + mPacketTime(packetTime), + mNumChannels(numChannels), + mFormatParameters(formatParameters) +{ +} + +SdpCodec::SdpCodec(const SdpCodec& rSdpCodec) +{ + operator=(rSdpCodec); +} + +SdpCodec::~SdpCodec() +{ +} + +SdpCodec& +SdpCodec::operator=(const SdpCodec& rhs) +{ + if (this == &rhs) + return *this; + + mPayloadType = rhs.mPayloadType; + mMimeType = rhs.mMimeType; + mMimeSubtype = rhs.mMimeSubtype; + mRate = rhs.mRate; + mPacketTime = rhs.mPacketTime; + mNumChannels = rhs.mNumChannels; + mFormatParameters = rhs.mFormatParameters; + + return *this; +} + +EncodeStream& +sdpcontainer::operator<<( EncodeStream& strm, const SdpCodec& sdpCodec) +{ + strm << "SdpCodec: payloadId=" << sdpCodec.mPayloadType + << ", mime=" << sdpCodec.mMimeType << "/" << sdpCodec.mMimeSubtype + << ", rate=" << sdpCodec.mRate + << ", packetTime=" << sdpCodec.mPacketTime + << ", numCh=" << sdpCodec.mNumChannels + << ", fmtParam=" << sdpCodec.mFormatParameters << std::endl; + return strm; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ + diff --git a/src/libs/resiprocate/resip/recon/sdp/SdpCodec.hxx b/src/libs/resiprocate/resip/recon/sdp/SdpCodec.hxx new file mode 100644 index 00000000..0738f124 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/sdp/SdpCodec.hxx @@ -0,0 +1,96 @@ +#if !defined(SdpCodec_hxx) +#define SdpCodec_hxx + +#include "rutil/compat.hxx" +#include "rutil/Data.hxx" + +namespace sdpcontainer +{ + +class SdpCodec +{ +public: + + SdpCodec(unsigned int payloadType, + const char* mimeType, + const char* mimeSubType, + unsigned int rate, + unsigned int packetTime, + unsigned int numChannels, + const char* formatParameters); + + SdpCodec(const SdpCodec& rSdpCodec); + + virtual ~SdpCodec(); + + SdpCodec& operator=(const SdpCodec& rhs); + + void setPayloadType(unsigned int payloadType) { mPayloadType = payloadType; } + void setMimeType(const resip::Data& mimeType) { mMimeType = mimeType; } + void setMimeSubtype(const resip::Data& mimeSubtype) { mMimeSubtype = mimeSubtype; } + void setRate(unsigned int rate) { mRate = rate; } + void setNumChannels(unsigned int numChannels) { mNumChannels = numChannels; } + void setPacketTime(unsigned int packetTime) { mPacketTime = packetTime; } + void setFormatParameters(const resip::Data& formatParameters) { mFormatParameters = formatParameters; } + + unsigned int getPayloadType() const { return mPayloadType; } + const resip::Data& getMimeType() const { return mMimeType; } + const resip::Data& getMimeSubtype() const { return mMimeSubtype; } + unsigned int getRate() const { return mRate; } + unsigned int getNumChannels() const { return mNumChannels; } + unsigned int getPacketTime() const { return mPacketTime; } + const resip::Data& getFormatParameters() const { return mFormatParameters; } + + void toString(resip::Data& sdpCodecString) const; + +private: + unsigned int mPayloadType; + resip::Data mMimeType; + resip::Data mMimeSubtype; + unsigned int mRate; + unsigned int mPacketTime; // ptime + unsigned int mNumChannels; + resip::Data mFormatParameters; + + friend EncodeStream& operator<<(EncodeStream& strm, const SdpCodec& ); +}; + +EncodeStream& operator<<(EncodeStream& strm, const SdpCodec& ); + +} // namespace + +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/sdp/SdpHelperResip.cxx b/src/libs/resiprocate/resip/recon/sdp/SdpHelperResip.cxx new file mode 100644 index 00000000..9784469b --- /dev/null +++ b/src/libs/resiprocate/resip/recon/sdp/SdpHelperResip.cxx @@ -0,0 +1,1419 @@ +#include <map> +#include <utility> + +#include "SdpHelperResip.hxx" +#include "Sdp.hxx" +#include "SdpMediaLine.hxx" +#include "SdpCodec.hxx" +#include "SdpCandidate.hxx" + +#include <rutil/WinLeakCheck.hxx> + +using namespace resip; +using namespace sdpcontainer; + +Sdp::SdpAddressType SdpHelperResip::convertResipAddressType(resip::SdpContents::AddrType resipAddrType) +{ + return resipAddrType == SdpContents::IP4 ? Sdp::ADDRESS_TYPE_IP4 : Sdp::ADDRESS_TYPE_IP6; +} + +SdpMediaLine::SdpEncryptionMethod SdpHelperResip::convertResipEncryptionMethod(resip::SdpContents::Session::Encryption::KeyType resipMethod) +{ + switch(resipMethod) + { + case SdpContents::Session::Encryption::Prompt: + return SdpMediaLine::ENCRYPTION_METHOD_PROMPT; + case SdpContents::Session::Encryption::Clear: + return SdpMediaLine::ENCRYPTION_METHOD_CLEAR; + case SdpContents::Session::Encryption::Base64: + return SdpMediaLine::ENCRYPTION_METHOD_BASE64; + case SdpContents::Session::Encryption::UriKey: + return SdpMediaLine::ENCRYPTION_METHOD_URI; + default: + return SdpMediaLine::ENCRYPTION_METHOD_NONE; + } +} + +Sdp* SdpHelperResip::createSdpFromResipSdp(const resip::SdpContents& resipSdp) +{ + bool rtcpEnabled = true; + Sdp* sdp = new Sdp(); + const SdpContents::Session* resipSession = &resipSdp.session(); + + sdp->setSdpVersion(resipSession->version()); // v= + + sdp->setOriginatorInfo(resipSession->origin().user().c_str(), // o= + resipSession->origin().getSessionId(), + resipSession->origin().getVersion(), + Sdp::NET_TYPE_IN, + convertResipAddressType(resipSession->origin().getAddressType()), + resipSession->origin().getAddress().c_str()); + + sdp->setSessionName(resipSession->name().c_str()); // s= + sdp->setSessionInformation(resipSession->information().c_str()); // i= + if(!resipSession->uri().host().empty()) + { + sdp->setSessionUri(Data::from(resipSession->uri()).c_str()); // u= + } + + // Populate email addresses, e= + { + const std::list<SdpContents::Session::Email>& emails = resipSession->getEmails(); + std::list<SdpContents::Session::Email>::const_iterator it; + for(it = emails.begin(); it != emails.end(); it++) + { + if(it->getFreeText().empty()) + { + sdp->addEmailAddress(it->getAddress().c_str()); + } + else + { + sdp->addEmailAddress(Data(it->getAddress() + Data(" (") + it->getFreeText() + Data(")")).c_str()); + } + } + } + + // Populate phone numbers, p= + { + const std::list<SdpContents::Session::Phone>& phones = resipSession->getPhones(); + std::list<SdpContents::Session::Phone>::const_iterator it; + for(it = phones.begin(); it != phones.end(); it++) + { + if(it->getFreeText().empty()) + { + sdp->addPhoneNumber(it->getNumber().c_str()); + } + else + { + sdp->addPhoneNumber(Data(it->getNumber() + Data(" (") + it->getFreeText() + Data(")")).c_str()); + } + } + } + + // Populate bandwidths, b= + { + const std::list<SdpContents::Session::Bandwidth>& bandwidths = resipSession->bandwidths(); + std::list<SdpContents::Session::Bandwidth>::const_iterator it; + bool RRSetToZero=false; + bool RSSetToZero=false; + for(it = bandwidths.begin(); it != bandwidths.end(); it++) + { + Sdp::SdpBandwidthType type = Sdp::SdpBandwidth::getTypeFromString(it->modifier().c_str()); + if(type != Sdp::BANDWIDTH_TYPE_NONE) + { + sdp->addBandwidth(type, it->kbPerSecond()); + if(type == Sdp::BANDWIDTH_TYPE_RR && it->kbPerSecond() == 0) + { + RRSetToZero = true; + } + else if(type == Sdp::BANDWIDTH_TYPE_RS && it->kbPerSecond() == 0) + { + RSSetToZero = true; + } + } + } + // Rtcp if considered disabled if RR and RS are both set to 0 + if(RRSetToZero && RSSetToZero) + { + rtcpEnabled = false; + } + } + + // Populate Times, t=, r= + { + const std::list<SdpContents::Session::Time>& times = resipSession->getTimes(); + std::list<SdpContents::Session::Time>::const_iterator it; + for(it = times.begin(); it != times.end(); it++) + { + Sdp::SdpTime *sdpTime = new Sdp::SdpTime(it->getStart(), it->getStop()); + + // Add repeats + const std::list<SdpContents::Session::Time::Repeat>& repeats = it->getRepeats(); + std::list<SdpContents::Session::Time::Repeat>::const_iterator it2; + for(it2 = repeats.begin(); it2 != repeats.end(); it2++) + { + Sdp::SdpTime::SdpTimeRepeat* sdpTimeRepeat = new Sdp::SdpTime::SdpTimeRepeat(it2->getInterval(), it2->getDuration()); + + // Add offsets + const std::list<int>& offsets = it2->getOffsets(); + std::list<int>::const_iterator it3; + for(it3 = offsets.begin(); it3 != offsets.end(); it3++) + { + sdpTimeRepeat->addOffsetFromStartTime(*it3); + } + sdpTime->addRepeat(*sdpTimeRepeat); + } + sdp->addTime(*sdpTime); + delete sdpTime; + } + } + + // Populate Timezones, z= + { + const std::list<SdpContents::Session::Timezones::Adjustment> &adjustments = resipSession->getTimezones().getAdjustments(); + std::list<SdpContents::Session::Timezones::Adjustment>::const_iterator it; + for(it = adjustments.begin(); it != adjustments.end(); it++) + { + sdp->addTimeZone(it->time, it->offset); + } + } + + // Look for any session level attributes + if(resipSession->exists("cat")) + { + sdp->setCategory(resipSession->getValues("cat").front().c_str()); + } + if(resipSession->exists("keywds")) + { + sdp->setKeywords(resipSession->getValues("keywds").front().c_str()); + } + if(resipSession->exists("tool")) + { + sdp->setToolNameAndVersion(resipSession->getValues("tool").front().c_str()); + } + if(resipSession->exists("type")) + { + sdp->setConferenceType(Sdp::getConferenceTypeFromString(resipSession->getValues("type").front().c_str())); + } + if(resipSession->exists("charset")) + { + sdp->setCharSet(resipSession->getValues("charset").front().c_str()); + } + if(resipSession->exists("ice-passive")) + { + sdp->setIcePassiveOnlyMode(true); + } + if(resipSession->exists("group")) + { + const std::list<Data>& values = resipSession->getValues("group"); + std::list<Data>::const_iterator it; + for(it = values.begin(); it != values.end(); it++) + { + Data token; + ParseBuffer pb(*it); + const char* anchor = pb.position(); + pb.skipToChar(Symbols::SPACE[0]); + if(!pb.eof()) + { + pb.data(token, anchor); + + Sdp::SdpGroupSemantics semantics = Sdp::SdpGroup::getSemanticsFromString(token.c_str()); + if(semantics != Sdp::GROUP_SEMANTICS_NONE) + { + Sdp::SdpGroup* sdpGroup = new Sdp::SdpGroup(semantics); + while(!pb.eof()) + { + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + sdpGroup->addIdentificationTag(token.c_str()); + } + sdp->addGroup(*sdpGroup); + } + } + } + } + if(resipSession->exists("lang")) + { + sdp->setSessionLanguage(resipSession->getValues("lang").front().c_str()); + } + if(resipSession->exists("sdplang")) + { + sdp->setDescriptionLanguage(resipSession->getValues("sdplang").front().c_str()); + } + if(resipSession->exists("maxprate")) + { +#ifndef RESIP_FIXED_POINT + sdp->setMaximumPacketRate(resipSession->getValues("maxprate").front().convertDouble()); +#else +// !slg! TODO +#endif + } + + // Iterate through the m= lines + const std::list<SdpContents::Session::Medium>& medias = resipSession->media(); + std::list<SdpContents::Session::Medium>::const_iterator it; + for(it = medias.begin(); it != medias.end(); it++) + { + const SdpContents::Session::Medium& resipMedia = *it; + SdpMediaLine* mediaLine = parseMediaLine(resipMedia, *resipSession, rtcpEnabled); + + // Parse out the SDP Capabilities Negotiation Potential Configurations + if(resipMedia.exists("pcfg")) + { + Data acceptedConfigurationLine; + std::list<SdpMediaLine::SdpTransportProtocolCapabilities> tcapList; + if(resipMedia.exists("tcap")) + { + const std::list<Data>& tcaps = resipMedia.getValues("tcap"); + std::list<Data>::const_iterator it2; + for(it2 = tcaps.begin(); it2 != tcaps.end(); it2++) + { + SdpHelperResip::parseTransportCapabilitiesLine(*it2, tcapList); + } + } + std::map<unsigned int, std::pair<Data, Data> > acapList; + if(resipMedia.exists("acap")) + { + const std::list<Data>& acaps = resipMedia.getValues("acap"); + std::list<Data>::const_iterator it2; + for(it2 = acaps.begin(); it2 != acaps.end(); it2++) + { + ParseBuffer pb(*it2); + unsigned int acapId = pb.uInt32(); + Data name; + Data value; + pb.skipToChar(Symbols::SPACE[0]); + const char * anchor = pb.skipWhitespace(); + if(!pb.eof()) + { + pb.skipToChar(Symbols::COLON[0]); + pb.data(name, anchor); + if(!pb.eof()) + { + anchor = pb.skipChar(); + pb.skipToEnd(); + pb.data(value, anchor); + } + } + acapList[acapId] = std::make_pair(name, value); + } + } + + std::list<SdpMediaLine::SdpPotentialConfiguration> pcfgList; + SdpHelperResip::parsePotentialConfigurationLine(resipMedia.getValues("pcfg").front(), pcfgList); + std::list<SdpMediaLine::SdpPotentialConfiguration>::iterator pcfgIt = pcfgList.begin(); + for(;pcfgIt != pcfgList.end(); pcfgIt++) + { + SdpMediaLine::SdpTransportProtocolType potentialTransportType; + if(pcfgIt->getTransportId() != 0) + { + // Find corresponding transport capability + std::list<SdpMediaLine::SdpTransportProtocolCapabilities>::iterator tcapIt = tcapList.begin(); + for(;tcapIt != tcapList.end(); tcapIt++) + { + if(tcapIt->getId() == pcfgIt->getTransportId()) + { + potentialTransportType = tcapIt->getType(); + acceptedConfigurationLine = Data(pcfgIt->getId()) + " t=" + Data(pcfgIt->getTransportId()); + break; + } + } + } + else + { + potentialTransportType = SdpMediaLine::getTransportProtocolTypeFromString(resipMedia.protocol().c_str()); + acceptedConfigurationLine = Data(pcfgIt->getId()); + } + if(potentialTransportType == SdpMediaLine::PROTOCOL_TYPE_NONE) continue; + + SdpContents::Session potentialSession(*resipSession); // create a session copy that we can modify + + // Find the corresponding medium entry in the copy + SdpContents::Session::Medium* potentialMedium; + std::list<SdpContents::Session::Medium>& potentialMedias = potentialSession.media(); + std::list<SdpContents::Session::Medium>::iterator potMedIt; + for(potMedIt = potentialMedias.begin(); potMedIt != potentialMedias.end(); potMedIt++) + { + if(potMedIt->protocol() == resipMedia.protocol() && + potMedIt->port() == (unsigned int)resipMedia.port() && + potMedIt->name() == resipMedia.name()) + { + potentialMedium = &(*potMedIt); + break; + } + } + assert(potentialMedium); + + potentialMedium->protocol() = SdpMediaLine::SdpTransportProtocolTypeString[potentialTransportType]; + + if(!pcfgIt->getAttributeIds().empty() || pcfgIt->getDeleteSessionAttributes() || pcfgIt->getDeleteMediaAttributes()) + { + acceptedConfigurationLine += " a="; + if(pcfgIt->getDeleteSessionAttributes() && pcfgIt->getDeleteMediaAttributes()) + { + acceptedConfigurationLine += "-ms:"; + // TODO - need way to clear all session and media level attributes + } + else if(pcfgIt->getDeleteSessionAttributes()) + { + acceptedConfigurationLine += "-s:"; + // TODO - need way to clear all session attributes + } + else if(pcfgIt->getDeleteMediaAttributes()) + { + acceptedConfigurationLine += "-m:"; + // TODO - need way to clear all media attributes + } + } + bool optional=false; + bool first=true; + SdpMediaLine::SdpPotentialConfiguration::ConfigIdList::const_iterator attribIt = pcfgIt->getAttributeIds().begin(); + for(;attribIt != pcfgIt->getAttributeIds().end(); attribIt++) + { + const SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem* configIdItem = &(*attribIt); + + // Find attribute in map + std::map<unsigned int, std::pair<Data, Data> >::iterator acapListIt = acapList.find(configIdItem->getId()); + if(acapListIt == acapList.end()) continue; + potentialMedium->addAttribute(acapListIt->second.first, acapListIt->second.second); + + if(!first) + { + acceptedConfigurationLine += ","; + } + // Note: this code assumes all optional attributes are last (as specified by draft) + if(configIdItem->getOptional()) + { + if(!optional) + { + acceptedConfigurationLine += "["; + optional = true; + } + } + acceptedConfigurationLine += Data(configIdItem->getId()); + first = false; + } + if(optional) + { + acceptedConfigurationLine += "]"; + } + SdpMediaLine* potentialSdpMediaLine = parseMediaLine(*potentialMedium, potentialSession, rtcpEnabled); + potentialSdpMediaLine->setPotentialMediaViewString(acceptedConfigurationLine.c_str()); + mediaLine->addPotentialMediaView(*potentialSdpMediaLine); + delete potentialSdpMediaLine; + } + } + + // Add the media line to the sdp + sdp->addMediaLine(mediaLine); + } + + return sdp; +} + +SdpMediaLine* +SdpHelperResip::parseMediaLine(const SdpContents::Session::Medium& resipMedia, const SdpContents::Session& resipSession, bool sessionRtcpEnabled) +{ + bool rtcpEnabledForMedia = sessionRtcpEnabled; // Default to Session setting + SdpMediaLine* mediaLine = new SdpMediaLine(); + + mediaLine->setMediaType(resipMedia.name()); + mediaLine->setTransportProtocolType(resipMedia.protocol()); + + // Get PTime for media line to assign to codecs + unsigned int ptime=20; // default !slg! this default should be dependant on codec type - ie. G723 should be 30, etc. + if(resipMedia.exists("ptime")) + { + ptime = resipMedia.getValues("ptime").front().convertInt(); + mediaLine->setPacketTime(ptime); + } + + // Iterate Through Codecs + { + const std::list<SdpContents::Session::Codec>& codecs = resipMedia.codecs(); + std::list<SdpContents::Session::Codec>::const_iterator it2; + for(it2 = codecs.begin(); it2 != codecs.end(); it2++) + { + const SdpContents::Session::Codec& resipCodec = *it2; + + SdpCodec* codec = new SdpCodec(resipCodec.payloadType(), + resipMedia.name().c_str(), + resipCodec.getName().c_str(), + resipCodec.getRate(), + ptime * 1000, + resipCodec.encodingParameters().empty() ? 1 : resipCodec.encodingParameters().convertInt() /* Num Channels */, + resipCodec.parameters().c_str()); + mediaLine->addCodec(*codec); + delete codec; + } + } + + mediaLine->setTitle(resipMedia.information().c_str()); // i= + + // Iterrate through bandwidths, b= + // Note: this is done before connections so that we can see if RTCP is disabled or not + { + const std::list<SdpContents::Session::Bandwidth>& bandwidths = resipMedia.bandwidths(); + std::list<SdpContents::Session::Bandwidth>::const_iterator it; + bool RRSetToZero=false; + bool RSSetToZero=false; + for(it = bandwidths.begin(); it != bandwidths.end(); it++) + { + Sdp::SdpBandwidthType type = Sdp::SdpBandwidth::getTypeFromString(it->modifier().c_str()); + if(type != Sdp::BANDWIDTH_TYPE_NONE) + { + mediaLine->addBandwidth(type, it->kbPerSecond()); + if(type == Sdp::BANDWIDTH_TYPE_RR) + { + if(it->kbPerSecond() == 0) + { + RRSetToZero = true; + } + else + { + // Explicit settings in the media override session bandwidth settings that may have disabled rtcp + rtcpEnabledForMedia = true; + } + } + else if(type == Sdp::BANDWIDTH_TYPE_RS) + { + if(it->kbPerSecond() == 0) + { + RSSetToZero = true; + } + else + { + // Explicit settings in the media override session bandwidth settings that may have disabled rtcp + rtcpEnabledForMedia = true; + } + } + } + } + // Rtcp if considered disabled if RR and RS are both set to 0 + if(RRSetToZero && RSSetToZero) + { + rtcpEnabledForMedia = false; + } + } + + // Iterate Through Connections, c= + { + unsigned int numPorts = resipMedia.multicast() != 0 ? resipMedia.multicast() : 1; // Protect against some user error for local sdp builds where user may accidently specify 0 for multicast + unsigned int i=0; + + // If the number of ports specified on the m= line matches the number of multicast addresses, then pair them up 1-1 + // if there are multiple addresses and multiple ports but the numbers don't match create num addresses * num ports connections + // If their is only one port specified, the use it with each connection + // If there is only one address and multiple ports then add addtional connections for each port + const std::list<SdpContents::Session::Connection>& connections = resipMedia.getConnections(); + std::list<SdpContents::Session::Connection>::const_iterator it2; + if(connections.size() == numPorts) // if there is a 1-1 mapping between numAddresses and numPorts, then pair them up + { + for(it2 = connections.begin(); it2 != connections.end(); it2++, i++) + { + const SdpContents::Session::Connection& resipConnection = *it2; + + mediaLine->addConnection(Sdp::NET_TYPE_IN, + convertResipAddressType(resipConnection.getAddressType()), + resipConnection.getAddress().c_str(), + resipMedia.port() + (i*2), + resipConnection.ttl()); + } + } + else + { + for(it2 = connections.begin(); it2 != connections.end(); it2++) + { + const SdpContents::Session::Connection& resipConnection = *it2; + + for(i = 0; i < numPorts; i++) + { + mediaLine->addConnection(Sdp::NET_TYPE_IN, + convertResipAddressType(resipConnection.getAddressType()), + resipConnection.getAddress().c_str(), + resipMedia.port() + (i*2), + resipConnection.ttl()); + } + } + } + } + + // Add Rtcp connections (if enabled) - if attributes are present use them, otherwise use default rule + { + if(rtcpEnabledForMedia) // Set when iterrating through bandwidth settings + { + // Note: RFC3605 rtcp-attribute does not support multicast streams - see section 3.2 of RFC + if(mediaLine->getConnections().size() == 1 && resipMedia.exists("rtcp")) + { + unsigned int ipv4ttl = 0; + Sdp::SdpAddressType addrType = Sdp::ADDRESS_TYPE_NONE; + + ParseBuffer pb(resipMedia.getValues("rtcp").front()); + Data address; + unsigned int port = pb.uInt32(); + pb.skipToChar(Symbols::SPACE[0]); + if(!pb.eof()) + { + const char* anchor = pb.skipWhitespace(); + if(!pb.eof()) + { + pb.skipChar('I'); + pb.skipChar('N'); + + anchor = pb.skipChar(Symbols::SPACE[0]); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(address, anchor); // use address as temp storage + addrType = Sdp::getAddressTypeFromString(address.c_str()); + anchor = pb.skipChar(Symbols::SPACE[0]); + pb.skipToOneOf(Symbols::SPACE, Symbols::SLASH); + pb.data(address, anchor); + if(addrType == Sdp::ADDRESS_TYPE_IP4 && !pb.eof() && *pb.position() == Symbols::SLASH[0]) + { + pb.skipChar(); + ipv4ttl = pb.integer(); + } + } + } + if(address.empty()) // If connection address was not specified here - use the c= line + { + SdpMediaLine::SdpConnection *connection = (SdpMediaLine::SdpConnection*)&mediaLine->getConnections().front(); + mediaLine->addRtcpConnection(connection->getNetType(), + connection->getAddressType(), + connection->getAddress().data(), + port, + connection->getMulticastIpV4Ttl()); + } + else + { + mediaLine->addRtcpConnection(Sdp::NET_TYPE_IN, addrType, address.c_str(), port, ipv4ttl); + } + } + else // default rule is that rtcp is sent on all connections, by adding 1 to the port + { + // Iterrate through each connection and add a corresponding RTCP connection + SdpMediaLine::ConnectionList::const_iterator it2 = mediaLine->getConnections().begin(); + for(;it2 != mediaLine->getConnections().end(); it2++) + { + mediaLine->addRtcpConnection(it2->getNetType(), + it2->getAddressType(), + it2->getAddress().data(), + it2->getPort() + 1, + it2->getMulticastIpV4Ttl()); + } + } + } + } + + // k= + if(resipMedia.getEncryption().getMethod() != SdpContents::Session::Encryption::NoEncryption) + { + mediaLine->setEncryptionKey(convertResipEncryptionMethod(resipMedia.getEncryption().getMethod()), resipMedia.getEncryption().getKey().c_str()); + } + else if(resipSession.getEncryption().getMethod() != SdpContents::Session::Encryption::NoEncryption) // check if set at session level + { + mediaLine->setEncryptionKey(convertResipEncryptionMethod(resipSession.getEncryption().getMethod()), resipSession.getEncryption().getKey().c_str()); + } + + // Set direction, a=sendrecv, a=sendonly, a=recvonly, a=inactive + SdpMediaLine::SdpDirectionType direction = SdpMediaLine::DIRECTION_TYPE_SENDRECV; // default + if(resipMedia.exists("sendrecv")) + { + direction = SdpMediaLine::DIRECTION_TYPE_SENDRECV; + } + else if(resipMedia.exists("sendonly")) + { + direction = SdpMediaLine::DIRECTION_TYPE_SENDONLY; + } + else if(resipMedia.exists("recvonly")) + { + direction = SdpMediaLine::DIRECTION_TYPE_RECVONLY; + } + else if(resipMedia.exists("inactive")) + { + direction = SdpMediaLine::DIRECTION_TYPE_INACTIVE; + } + mediaLine->setDirection(direction); + + // Note ptime is set above + if(resipMedia.exists("maxptime")) + { + mediaLine->setMaxPacketTime(resipMedia.getValues("maxptime").front().convertUnsignedLong()); + } + + if(resipMedia.exists("orient")) + { + mediaLine->setOrientation(SdpMediaLine::getOrientationTypeFromString(resipMedia.getValues("orient").front().c_str())); + } + + if(resipMedia.exists("sdplang")) + { + mediaLine->setDescriptionLanguage(resipMedia.getValues("sdplang").front().c_str()); + } + + if(resipMedia.exists("lang")) + { + mediaLine->setLanguage(resipMedia.getValues("lang").front().c_str()); + } + + if(resipMedia.exists("framerate")) + { + mediaLine->setFrameRate(resipMedia.getValues("framerate").front().convertUnsignedLong()); + } + + if(resipMedia.exists("quality")) + { + mediaLine->setQuality(resipMedia.getValues("quality").front().convertUnsignedLong()); + } + + if(resipMedia.exists("setup")) + { + mediaLine->setTcpSetupAttribute(SdpMediaLine::getTcpSetupAttributeFromString(resipMedia.getValues("setup").front().c_str())); + } + + if(resipMedia.exists("connection")) + { + mediaLine->setTcpConnectionAttribute(SdpMediaLine::getTcpConnectionAttributeFromString(resipMedia.getValues("connection").front().c_str())); + } + + if(resipMedia.exists("crypto")) + { + const std::list<Data>& cryptos = resipMedia.getValues("crypto"); + std::list<Data>::const_iterator it2; + for(it2 = cryptos.begin(); it2 != cryptos.end(); it2++) + { + SdpMediaLine::SdpCrypto *crypto = parseCryptoLine(*it2); + if(crypto) + { + mediaLine->addCryptoSettings(*crypto); + delete crypto; + } + } + } + + if(resipMedia.exists("fingerprint")) + { + Data fingerprintLine = resipMedia.getValues("fingerprint").front(); + if(!fingerprintLine.empty()) + { + SdpMediaLine::SdpFingerPrintHashFuncType hashType; + resip::Data fingerPrint; + if(parseFingerPrintLine(fingerprintLine, hashType, fingerPrint)) + { + mediaLine->setFingerPrint(hashType, fingerPrint.c_str()); + } + } + } + + if(resipMedia.exists("key-mgmt")) + { + Data keymgmt = resipMedia.getValues("key-mgmt").front(); + if(!keymgmt.empty()) + { + ParseBuffer pb(keymgmt); + Data token; + SdpMediaLine::SdpKeyManagementProtocolType keyMgmtType; + const char * anchor = pb.position(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + keyMgmtType = SdpMediaLine::getKeyManagementProtocolTypeFromString(token.c_str()); + if(keyMgmtType != SdpMediaLine::KEYMANAGEMENT_PROTOCOL_NONE) + { + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + mediaLine->setKeyManagementProtocol(keyMgmtType, token.c_str()); + } + } + } + + if(resipMedia.exists("curr")) + { + const std::list<Data>& preconds = resipMedia.getValues("curr"); + std::list<Data>::const_iterator it2; + for(it2 = preconds.begin(); it2 != preconds.end(); it2++) + { + ParseBuffer pb(*it2); + Data token; + SdpMediaLine::SdpPreConditionType type; + SdpMediaLine::SdpPreConditionStatusType status; + SdpMediaLine::SdpPreConditionDirectionType direction; + const char * anchor = pb.position(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + type = SdpMediaLine::getPreConditionTypeFromString(token.c_str()); + if(type != SdpMediaLine::PRECONDITION_TYPE_NONE) + { + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + status = SdpMediaLine::getPreConditionStatusTypeFromString(token.c_str()); + if(status != SdpMediaLine::PRECONDITION_STATUS_NONE) + { + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + direction = SdpMediaLine::getPreConditionDirectionTypeFromString(token.c_str()); + mediaLine->addPreConditionCurrentStatus(type, status, direction); + } + } + } + } + + if(resipMedia.exists("conf")) + { + const std::list<Data>& preconds = resipMedia.getValues("conf"); + std::list<Data>::const_iterator it2; + for(it2 = preconds.begin(); it2 != preconds.end(); it2++) + { + ParseBuffer pb(*it2); + Data token; + SdpMediaLine::SdpPreConditionType type; + SdpMediaLine::SdpPreConditionStatusType status; + SdpMediaLine::SdpPreConditionDirectionType direction; + const char * anchor = pb.position(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + type = SdpMediaLine::getPreConditionTypeFromString(token.c_str()); + if(type != SdpMediaLine::PRECONDITION_TYPE_NONE) + { + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + status = SdpMediaLine::getPreConditionStatusTypeFromString(token.c_str()); + if(status != SdpMediaLine::PRECONDITION_STATUS_NONE) + { + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + direction = SdpMediaLine::getPreConditionDirectionTypeFromString(token.c_str()); + mediaLine->addPreConditionConfirmStatus(type, status, direction); + } + } + } + } + + if(resipMedia.exists("des")) + { + const std::list<Data>& preconds = resipMedia.getValues("des"); + std::list<Data>::const_iterator it2; + for(it2 = preconds.begin(); it2 != preconds.end(); it2++) + { + ParseBuffer pb(*it2); + Data token; + SdpMediaLine::SdpPreConditionType type; + SdpMediaLine::SdpPreConditionStrengthType strength; + SdpMediaLine::SdpPreConditionStatusType status; + SdpMediaLine::SdpPreConditionDirectionType direction; + const char * anchor = pb.position(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + type = SdpMediaLine::getPreConditionTypeFromString(token.c_str()); + if(type != SdpMediaLine::PRECONDITION_TYPE_NONE) + { + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + strength = SdpMediaLine::getPreConditionStrengthTypeFromString(token.c_str()); + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + status = SdpMediaLine::getPreConditionStatusTypeFromString(token.c_str()); + if(status != SdpMediaLine::PRECONDITION_STATUS_NONE) + { + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + direction = SdpMediaLine::getPreConditionDirectionTypeFromString(token.c_str()); + mediaLine->addPreConditionDesiredStatus(type, strength, status, direction); + } + } + } + } + + +#ifndef RESIP_FIXED_POINT + if(resipMedia.exists("maxprate")) + { + mediaLine->setMaximumPacketRate(resipMedia.getValues("maxprate").front().convertDouble()); + } +#else + // !slg! TODO +#endif + + if(resipMedia.exists("label")) + { + mediaLine->setLabel(resipMedia.getValues("label").front().c_str()); + } + + if(resipMedia.exists("mid")) + { + mediaLine->setIdentificationTag(resipMedia.getValues("mid").front().c_str()); + } + + if(resipMedia.exists("ice-ufrag")) + { + mediaLine->setIceUserFrag(resipMedia.getValues("ice-ufrag").front().c_str()); + } + + if(resipMedia.exists("ice-pwd")) + { + mediaLine->setIcePassword(resipMedia.getValues("ice-pwd").front().c_str()); + } + + if(resipMedia.exists("remote-candidates")) + { + // multiple remote candidates are allowed on one line - we will also accept multiple remote-candidate attributes + const std::list<Data>& preconds = resipMedia.getValues("remote-candidates"); + std::list<Data>::const_iterator it2; + for(it2 = preconds.begin(); it2 != preconds.end(); it2++) + { + ParseBuffer pb(*it2); + Data token; + unsigned int componentId; + unsigned int port; + const char * anchor; + + while(!pb.eof()) + { + componentId = pb.uInt32(); + pb.skipToChar(Symbols::SPACE[0]); + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + pb.skipWhitespace(); + port = pb.uInt32(); + pb.skipToChar(Symbols::SPACE[0]); + pb.skipWhitespace(); + mediaLine->addRemoteCandidate(componentId, token.c_str(), port); + } + } + } + + if(resipMedia.exists("candidate")) + { + const std::list<Data>& preconds = resipMedia.getValues("candidate"); + std::list<Data>::const_iterator it2; + for(it2 = preconds.begin(); it2 != preconds.end(); it2++) + { + ParseBuffer pb(*it2); + Data foundation; + unsigned int componentId; + Data token; + SdpCandidate::SdpCandidateTransportType transport; + UInt64 priority; + Data address; + unsigned int port; + SdpCandidate::SdpCandidateType candidateType = SdpCandidate::CANDIDATE_TYPE_NONE; + Data relatedAddress; + unsigned int relatedPort = 0; + + const char * anchor = pb.position(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(foundation, anchor); + pb.skipWhitespace(); + componentId = pb.uInt32(); + pb.skipToChar(Symbols::SPACE[0]); + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + transport = SdpCandidate::getCandidateTransportTypeFromString(token.c_str()); + if(transport != SdpCandidate::CANDIDATE_TRANSPORT_TYPE_NONE) + { + pb.skipWhitespace(); + priority = pb.uInt64(); + pb.skipToChar(Symbols::SPACE[0]); + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(address, anchor); + pb.skipWhitespace(); + port = pb.uInt32(); + pb.skipToChar(Symbols::SPACE[0]); + anchor = pb.skipWhitespace(); + if(!pb.eof()) + { + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + if(token == "typ") + { + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + candidateType = SdpCandidate::getCandidateTypeFromString(token.c_str()); + anchor = pb.skipWhitespace(); + if(!pb.eof()) + { + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + } + } + + if(!pb.eof() && token == "raddr") + { + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(relatedAddress, anchor); + anchor = pb.skipWhitespace(); + if(!pb.eof()) + { + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + } + } + + if(!pb.eof() && token == "rport") + { + pb.skipWhitespace(); + relatedPort = pb.uInt32(); + pb.skipToChar(Symbols::SPACE[0]); + anchor = pb.skipWhitespace(); + if(!pb.eof()) + { + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + } + } + + SdpCandidate* candidate = new SdpCandidate(foundation.c_str(), componentId, transport, priority, address.c_str(), port, candidateType, relatedAddress.c_str(), relatedPort); + while(!pb.eof()) + { + Data extAttribValue; + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(extAttribValue, anchor); + anchor = pb.skipWhitespace(); + candidate->addExtensionAttribute(token.c_str(), extAttribValue.c_str()); + if(!pb.eof()) + { + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + } + } + mediaLine->addCandidate(*candidate); + delete candidate; + } + } + } + } + + return mediaLine; +} + +SdpMediaLine::SdpCrypto* SdpHelperResip::parseCryptoLine(const Data& cryptoLine) +{ + SdpMediaLine::SdpCrypto *crypto = 0; + + ParseBuffer pb(cryptoLine); + unsigned int tag = pb.uInt32(); + Data token; + SdpMediaLine::SdpCryptoSuiteType suite; + + pb.skipToChar(Symbols::SPACE[0]); + const char * anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + suite = SdpMediaLine::getCryptoSuiteTypeFromString(token.c_str()); + if(suite != SdpMediaLine::CRYPTO_SUITE_TYPE_NONE) + { + crypto = new SdpMediaLine::SdpCrypto; + crypto->setTag(tag); + crypto->setSuite(suite); + anchor = pb.skipWhitespace(); + + // Loop through KeyParams + while(true) + { + SdpMediaLine::SdpCryptoKeyMethod method; + Data keyValue; + unsigned int lifetime = 0; + unsigned int mkiValue = 0; + unsigned int mkiLength = 0; + + parseCryptoParams(pb, method, keyValue, lifetime, mkiValue, mkiLength); + crypto->addCryptoKeyParam(method, keyValue.c_str(), lifetime, mkiValue, mkiLength); + + if(pb.eof() || *pb.position() != ';') break; + anchor = pb.skipChar(); + } + while(!pb.eof()) + { + anchor = pb.skipWhitespace(); + pb.skipToOneOf(" ="); + pb.data(token, anchor); + if(token == "KDR") + { + pb.skipChar(); + crypto->setSrtpKdr(pb.uInt32()); + } + else if(token == "UNENCRYPTED_SRTP") + { + crypto->setEncryptedSrtp(false); + } + else if(token == "UNENCRYPTED_SRTCP") + { + crypto->setEncryptedSrtcp(false); + } + else if(token == "UNAUTHENTICATED_SRTP") + { + crypto->setAuthenticatedSrtp(false); + } + else if(token == "FEC_ORDER") + { + anchor = pb.skipChar(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + crypto->setSrtpFecOrder(SdpMediaLine::SdpCrypto::getSrtpFecOrderFromString(token.c_str())); + } + else if(token == "FEC_KEY") + { + anchor = pb.skipChar(); + SdpMediaLine::SdpCryptoKeyMethod method; + Data keyValue; + unsigned int lifetime = 0; + unsigned int mkiValue = 0; + unsigned int mkiLength = 0; + + parseCryptoParams(pb, method, keyValue, lifetime, mkiValue, mkiLength); + crypto->setSrtpFecKey(method, keyValue.c_str(), lifetime, mkiValue, mkiLength); + } + else if(token == "WSH") + { + pb.skipChar(); + crypto->setSrtpWsh(pb.uInt32()); + } + else + { + if(!pb.eof() && *pb.position() == '=') + { + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + } + crypto->addGenericSessionParam(token.c_str()); + } + } + } + return crypto; +} + +bool SdpHelperResip::parseFingerPrintLine(const resip::Data& fingerprintLine, SdpMediaLine::SdpFingerPrintHashFuncType& hashType, resip::Data& fingerPrint) +{ + ParseBuffer pb(fingerprintLine); + const char * anchor = pb.position(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(fingerPrint, anchor); // just used fingerprint data temporarily + hashType = SdpMediaLine::getFingerPrintHashFuncTypeFromString(fingerPrint.c_str()); + if(hashType != SdpMediaLine::FINGERPRINT_HASH_FUNC_NONE) + { + anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(fingerPrint, anchor); + return true; + } + return false; +} + +bool SdpHelperResip::parseTransportCapabilitiesLine(const resip::Data& tcapLine, std::list<SdpMediaLine::SdpTransportProtocolCapabilities>& tcapList) +{ + ParseBuffer pb(tcapLine); + unsigned int baseTcapId = pb.uInt32(); + Data token; + bool ok = false; + pb.skipToChar(Symbols::SPACE[0]); + while(true) + { + const char * anchor = pb.skipWhitespace(); + if(pb.eof()) break; + pb.skipToChar(Symbols::SPACE[0]); + pb.data(token, anchor); + tcapList.push_back(SdpMediaLine::SdpTransportProtocolCapabilities(baseTcapId, SdpMediaLine::getTransportProtocolTypeFromString(token.c_str()))); + baseTcapId++; + ok = true; + } + return ok; +} + +bool SdpHelperResip::parsePotentialConfigurationLine(const resip::Data& pcfgLine, std::list<SdpMediaLine::SdpPotentialConfiguration>& pcfgList) +{ + std::list<std::list<SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem> > attributeLists; + std::list<unsigned int> transportList; + bool deleteMediaAttributes = false; + bool deleteSessionAttributes = false; + + ParseBuffer pb(pcfgLine); + unsigned int pcfgId = pb.uInt32(); + Data token; + bool ok = false; + bool attributesFirst = false; + pb.skipToChar(Symbols::SPACE[0]); + + while(!pb.eof()) + { + const char * anchor = pb.skipWhitespace(); + bool optionalOn = false; + pb.skipToChar(Symbols::EQUALS[0]); + if(!pb.eof()) + { + pb.data(token, anchor); + if(token == "a") + { + std::list<SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem> attributeList; + if(transportList.empty()) + { + attributesFirst = true; + } + pb.skipChar(); // skip = + if(pb.eof()) break; + if(*pb.position() == '-') + { + // We have "delete" attributes + anchor = pb.skipChar(); + pb.skipToChar(Symbols::COLON[0]); + pb.data(token, anchor); + if(token == "m") + { + deleteMediaAttributes = true; + } + else if(token == "s") + { + deleteSessionAttributes = true; + } + else if(token == "ms") + { + deleteMediaAttributes = true; + deleteSessionAttributes = true; + } + if(!pb.eof()) pb.skipChar(); + } + while(!pb.eof()) + { + anchor = pb.position(); + pb.skipToOneOf(" ,|[]"); + if(pb.eof() || *pb.position() == ',' || *pb.position() == ' ') + { + pb.data(token, anchor); + attributeList.push_back(SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem(token.convertUnsignedLong(), optionalOn)); + if(!pb.eof()) pb.skipChar(); + } + else if(*pb.position() == '|') + { + attributeLists.push_back(attributeList); + attributeList.clear(); // Start a new list + pb.skipChar(); + } + else if(*pb.position() == '[') + { + optionalOn = true; + pb.skipChar(); + } + else if(*pb.position() == ']') + { + pb.data(token, anchor); + attributeList.push_back(SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem(token.convertUnsignedLong(), optionalOn)); + optionalOn = false; + pb.skipChar(); + } + if(pb.eof() || *pb.position() == ' ') + { + attributeLists.push_back(attributeList); + break; + } + } + } + else if(token == "t") + { + anchor = pb.skipChar(); + while(!pb.eof()) + { + pb.skipToOneOf(" |"); + pb.data(token, anchor); + transportList.push_back(token.convertUnsignedLong()); + if(pb.eof() || *pb.position() == ' ') break; + anchor = pb.skipChar(); + } + } + else + { + // Mostly like an extension list - we do not support this yet - so just skip it + pb.skipToChar(Symbols::SPACE[0]); + } + } + } + + // Ok we've parse everything now - build all of the potential configs + if(attributesFirst) + { + // iterate through each attribute, then each transport + std::list<std::list<SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem> >::iterator listsIt = attributeLists.begin(); + for(;listsIt != attributeLists.end(); listsIt++) + { + if(transportList.empty()) + { + SdpMediaLine::SdpPotentialConfiguration potentialConfiguration(pcfgId, deleteMediaAttributes, deleteSessionAttributes, 0 /* no transportId */); + std::list<SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem>::iterator attributesIt = listsIt->begin(); + for(;attributesIt != listsIt->end(); attributesIt++) + { + potentialConfiguration.addAttributeId(SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem(*attributesIt)); + } + pcfgList.push_back(potentialConfiguration); + } + else + { + std::list<unsigned int>::iterator transportsIt = transportList.begin(); + for(;transportsIt != transportList.end(); transportsIt++) + { + SdpMediaLine::SdpPotentialConfiguration potentialConfiguration(pcfgId, deleteMediaAttributes, deleteSessionAttributes, *transportsIt); + std::list<SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem>::iterator attributesIt = listsIt->begin(); + for(;attributesIt != listsIt->end(); attributesIt++) + { + potentialConfiguration.addAttributeId(SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem(*attributesIt)); + } + pcfgList.push_back(potentialConfiguration); + } + } + } + } + else // transports were listed first - build list in different order + { + std::list<unsigned int>::iterator transportsIt = transportList.begin(); + for(;transportsIt != transportList.end(); transportsIt++) + { + if(attributeLists.empty()) + { + pcfgList.push_back(SdpMediaLine::SdpPotentialConfiguration(pcfgId, deleteMediaAttributes, deleteSessionAttributes, *transportsIt)); + } + else + { + // iterate through each attribute list + std::list<std::list<SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem> >::iterator listsIt = attributeLists.begin(); + for(;listsIt != attributeLists.end(); listsIt++) + { + SdpMediaLine::SdpPotentialConfiguration potentialConfiguration(pcfgId, deleteMediaAttributes, deleteSessionAttributes, *transportsIt); + std::list<SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem>::iterator attributesIt = listsIt->begin(); + for(;attributesIt != listsIt->end(); attributesIt++) + { + potentialConfiguration.addAttributeId(SdpMediaLine::SdpPotentialConfiguration::ConfigIdItem(*attributesIt)); + } + pcfgList.push_back(potentialConfiguration); + } + } + } + } + return ok; +} + +using namespace std; +void testSDPCapabilityNegotiationParsing(void) +{ + std::list<SdpMediaLine::SdpTransportProtocolCapabilities> tcapList; + std::list<SdpMediaLine::SdpPotentialConfiguration> pcfgList; + Data tcap("1 UDP/TLS/RTP/AVP RTP/AVP"); + Data pcfg("1 a=-m:1,2,3,[4,5]|[6,7] x=blah t=1|2 y=foo"); + SdpHelperResip::parseTransportCapabilitiesLine(tcap, tcapList); + SdpHelperResip::parsePotentialConfigurationLine(pcfg, pcfgList); + + cout << "Transport List: " << tcap << endl; + std::list<SdpMediaLine::SdpTransportProtocolCapabilities>::iterator it = tcapList.begin(); + for(;it != tcapList.end(); it++) + { + cout << " Tranpsort Id=" << it->getId() << " protocolType=" << it->getType() << endl; + } + + cout << "Potential Configuration List: " << pcfg << endl; + std::list<SdpMediaLine::SdpPotentialConfiguration>::iterator it2 = pcfgList.begin(); + for(;it2 != pcfgList.end(); it2++) + { + cout << " Config Id=" << it2->getId() << " deleteMediaAttr=" << it2->getDeleteMediaAttributes() << " deleteSessionAttr=" << it2->getDeleteSessionAttributes() << " transportId=" << it2->getTransportId() << endl; + SdpMediaLine::SdpPotentialConfiguration::ConfigIdList::const_iterator it3 = it2->getAttributeIds().begin(); + for(;it3 != it2->getAttributeIds().end(); it3++) + { + cout << " AttributeId=" << it3->getId() << " optional=" << it3->getOptional() << endl; + } + } + + return; +} + +void SdpHelperResip::parseCryptoParams(ParseBuffer& pb, + SdpMediaLine::SdpCryptoKeyMethod& keyMethod, + Data& keyValue, + unsigned int& srtpLifetime, + unsigned int& srtpMkiValue, + unsigned int& srtpMkiLength) +{ + const char * anchor = pb.position(); + Data token; + pb.skipToChar(Symbols::COLON[0]); + pb.data(token, anchor); + keyMethod = SdpMediaLine::getCryptoKeyMethodFromString(token.c_str()); + if(keyMethod == SdpMediaLine::CRYPTO_KEY_METHOD_INLINE) + { + anchor = pb.skipChar(); + pb.skipToOneOf("|;", Symbols::SPACE); + pb.data(keyValue, anchor); + if(!pb.eof() && *pb.position() == '|') + { + pb.skipChar(); + unsigned int base = pb.uInt32(); + pb.skipToOneOf("^|:;", Symbols::SPACE); + if(*pb.position() == '^') + { + pb.skipChar(); + unsigned int exponent = pb.uInt32(); + srtpLifetime = base; + while(0 != --exponent) srtpLifetime *= base; + pb.skipToOneOf("|;", Symbols::SPACE); + if(!pb.eof() && *pb.position() == '|') + { + pb.skipChar(); + base = pb.uInt32(); + pb.skipToOneOf(":;", Symbols::SPACE); + } + } + else if(*pb.position() != ':') + { + srtpLifetime = base; + if(!pb.eof()) + { + if(*pb.position() == '|') + { + pb.skipChar(); + base = pb.uInt32(); + } + pb.skipToOneOf(":;", Symbols::SPACE); + } + } + if(!pb.eof() && *pb.position() == ':') + { + srtpMkiValue = base; + pb.skipChar(); + srtpMkiLength = pb.uInt32(); + pb.skipToOneOf(";", Symbols::SPACE); + } + } + } + else + { + anchor = pb.skipChar(); + pb.skipToChar(Symbols::SPACE[0]); + pb.data(keyValue, anchor); + if(!pb.eof()) + { + pb.skipToOneOf(";", Symbols::SPACE); + } + } +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/sdp/SdpHelperResip.hxx b/src/libs/resiprocate/resip/recon/sdp/SdpHelperResip.hxx new file mode 100644 index 00000000..be3089c9 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/sdp/SdpHelperResip.hxx @@ -0,0 +1,81 @@ +#if !defined(SdpHelperResip_hxx) +#define SdpHelperResip_hxx + +#include "Sdp.hxx" +#include "SdpMediaLine.hxx" +#include <resip/stack/SdpContents.hxx> + +using namespace sdpcontainer; + +namespace resip +{ + class ParseBuffer; + class Data; +} + +/** + This class is used to form a sipX representation of SDP from + a resiprocate representation. + + Author: Scott Godin (sgodin AT SipSpectrum DOT com) +*/ + +class SdpHelperResip +{ +public: + static Sdp::SdpAddressType convertResipAddressType(resip::SdpContents::AddrType resipAddrType); + static SdpMediaLine::SdpEncryptionMethod convertResipEncryptionMethod(resip::SdpContents::Session::Encryption::KeyType resipMethod); + static Sdp* createSdpFromResipSdp(const resip::SdpContents& resipSdp); + + static SdpMediaLine::SdpCrypto* parseCryptoLine(const resip::Data& cryptoLine); + static bool parseFingerPrintLine(const resip::Data& fingerprintLine, SdpMediaLine::SdpFingerPrintHashFuncType& hashType, resip::Data& fingerPrint); + static bool parseTransportCapabilitiesLine(const resip::Data& tcapLine, std::list<SdpMediaLine::SdpTransportProtocolCapabilities>& tcapList); + static bool parsePotentialConfigurationLine(const resip::Data& pcfgLine, std::list<SdpMediaLine::SdpPotentialConfiguration>& pcfgList); + +private: + static SdpMediaLine* parseMediaLine(const resip::SdpContents::Session::Medium& resipMedia, const resip::SdpContents::Session& resipSession, bool sessionRtcpEnabled); + static void parseCryptoParams(resip::ParseBuffer& pb, + SdpMediaLine::SdpCryptoKeyMethod& keyMethod, + resip::Data& keyValue, + unsigned int& srtpLifetime, + unsigned int& srtpMkiValue, + unsigned int& srtpMkiLength); + +}; + +#endif // _SdpHelperResip_hxx_ + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/sdp/SdpMediaLine.cxx b/src/libs/resiprocate/resip/recon/sdp/SdpMediaLine.cxx new file mode 100644 index 00000000..ce0c509e --- /dev/null +++ b/src/libs/resiprocate/resip/recon/sdp/SdpMediaLine.cxx @@ -0,0 +1,863 @@ +#include "SdpMediaLine.hxx" + +using namespace sdpcontainer; + +const char* SdpMediaLine::SdpMediaTypeString[] = +{ + "NONE", + "UNKNOWN", + "AUDIO", + "VIDEO", + "TEXT", + "APPLICATION", + "MESSAGE" +}; + +const char* SdpMediaLine::SdpTransportProtocolTypeString[] = +{ + "NONE", + "UNKNOWN", + "UDP", + "RTP/AVP", + "RTP/SAVP", + "RTP/SAVPF", + "TCP", + "TCP/RTP/AVP", + "TCP/TLS", + "UDP/TLS", + "DCCP/TLS", + "DCCP/TLS/RTP/SAVP", + "UDP/TLS/RTP/SAVP", + "TCP/TLS/RTP/SAVP" +}; + +const char* SdpMediaLine::SdpEncryptionMethodString[] = +{ + "NONE", + "CLEAR", + "BASE64", + "URI", + "PROMPT" +}; + +const char* SdpMediaLine::SdpDirectionTypeString[] = +{ + "NONE", + "SENDRECV", + "SENDONLY", + "RECVONLY", + "INACTIVE" +}; + +const char* SdpMediaLine::SdpOrientationTypeString[] = +{ + "NONE", + "PORTRAIT", + "LANDSCAPE", + "SEASCAPE" +}; + +const char* SdpMediaLine::SdpTcpSetupAttributeString[] = +{ + "NONE", + "ACTIVE", + "PASSIVE", + "ACTPASS", + "HOLDCONN" +}; + +const char* SdpMediaLine::SdpTcpConnectionAttributeString[] = +{ + "NONE", + "NEW", + "EXISTING" +}; + +const char* SdpMediaLine::SdpCryptoSuiteTypeString[] = +{ + "NONE", + "AES_CM_128_HMAC_SHA1_80", + "AES_CM_128_HMAC_SHA1_32", + "F8_128_HMAC_SHA1_80" +}; + +const char* SdpMediaLine::SdpCryptoKeyMethodString[] = +{ + "NONE", + "INLINE" +}; + +const char* SdpMediaLine::SdpCryptoSrtpFecOrderTypeString[] = +{ + "NONE", + "FEC_SRTP", + "SRTP_FEC" +}; + +const char* SdpMediaLine::SdpFingerPrintHashFuncTypeString[] = +{ + "NONE", + "SHA-1", + "SHA-224", + "SHA-256", + "SHA-384", + "SHA-512", + "MD5", + "MD2" +}; + +const char* SdpMediaLine::SdpKeyManagementProtocolTypeString[] = +{ + "NONE", + "MIKEY" +}; + +const char* SdpMediaLine::SdpPreConditionTypeString[] = +{ + "NONE", + "QOS", +}; + +const char* SdpMediaLine::SdpPreConditionStrengthTypeString[] = +{ + "MANDATORY", + "OPTIONAL", + "NONE", + "FAILURE", + "UNKNOWN" +}; + +const char* SdpMediaLine::SdpPreConditionStatusTypeString[] = +{ + "NONE", + "E2E", + "LOCAL", + "REMOTE" +}; + +const char* SdpMediaLine::SdpPreConditionDirectionTypeString[] = +{ + "NONE", + "SEND", + "RECV", + "SENDRECV" +}; + +SdpMediaLine::SdpCrypto::SdpCrypto(const SdpMediaLine::SdpCrypto& rhs) +{ + operator=(rhs); +} + +SdpMediaLine::SdpCrypto& +SdpMediaLine::SdpCrypto::operator=(const SdpMediaLine::SdpCrypto& rhs) +{ + if (this == &rhs) // handle the assignment to self case + return *this; + + // Assign values + mTag = rhs.mTag; + mSuite = rhs.mSuite; + mCryptoKeyParams = rhs.mCryptoKeyParams; + mSrtpKdr = rhs.mSrtpKdr; + mEncryptedSrtp = rhs.mEncryptedSrtp; + mEncryptedSrtcp = rhs.mEncryptedSrtcp; + mAuthenticatedSrtp = rhs.mAuthenticatedSrtp; + mSrtpFecOrder = rhs.mSrtpFecOrder; + mSrtpFecKey = rhs.mSrtpFecKey; + mSrtpWsh = rhs.mSrtpWsh; + mGenericSessionParams = rhs.mGenericSessionParams; + + return *this; +} + + +// Constructor +SdpMediaLine::SdpMediaLine() : + mMediaType(SdpMediaLine::MEDIA_TYPE_NONE), + mTransportProtocolType(SdpMediaLine::PROTOCOL_TYPE_NONE), + mEncryptionMethod(SdpMediaLine::ENCRYPTION_METHOD_NONE), + mDirection(SdpMediaLine::DIRECTION_TYPE_NONE), + mPacketTime(0), + mMaxPacketTime(0), + mOrientation(SdpMediaLine::ORIENTATION_TYPE_NONE), + mFrameRate(0), + mQuality(0), + mTcpSetupAttribute(SdpMediaLine::TCP_SETUP_ATTRIBUTE_NONE), + mTcpConnectionAttribute(SdpMediaLine::TCP_CONNECTION_ATTRIBUTE_NONE), + mFingerPrintHashFunction(SdpMediaLine::FINGERPRINT_HASH_FUNC_NONE), + mKeyManagementProtocol(SdpMediaLine::KEYMANAGEMENT_PROTOCOL_NONE), + mMaximumPacketRate(0), + mRtpCandidatePresent(false), + mRtcpCandidatePresent(false) +{ +} + +// Copy constructor +SdpMediaLine::SdpMediaLine(const SdpMediaLine& rhs) +{ + operator=(rhs); +} + +// Destructor +SdpMediaLine::~SdpMediaLine() +{ + clearCandidates(); + clearCandidatePairs(); +} + +// Assignment operator +SdpMediaLine& +SdpMediaLine::operator=(const SdpMediaLine& rhs) +{ + if (this == &rhs) // handle the assignment to self case + return *this; + + // Assign values + mMediaType = rhs.mMediaType; + mMediaTypeString = rhs.mMediaTypeString; + mTransportProtocolType = rhs.mTransportProtocolType; + mTransportProtocolTypeString = rhs.mTransportProtocolTypeString; + mCodecs = rhs.mCodecs; + mTitle = rhs.mTitle; + mConnections = rhs.mConnections; + mRtcpConnections = rhs.mRtcpConnections; + mBandwidths = rhs.mBandwidths; + mEncryptionMethod = rhs.mEncryptionMethod; + mEncryptionKey = rhs.mEncryptionKey; + mDirection = rhs.mDirection; + mPacketTime = rhs.mPacketTime; + mMaxPacketTime = rhs.mMaxPacketTime; + mOrientation = rhs.mOrientation; + mDescriptionLanguage = rhs.mDescriptionLanguage; + mLanguage = rhs.mLanguage; + mFrameRate = rhs.mFrameRate; + mQuality = rhs.mQuality; + mTcpSetupAttribute = rhs.mTcpSetupAttribute; + mTcpConnectionAttribute = rhs.mTcpConnectionAttribute; + mCryptos = rhs.mCryptos; + mFingerPrintHashFunction = rhs.mFingerPrintHashFunction; + mFingerPrint = rhs.mFingerPrint; + mKeyManagementProtocol = rhs.mKeyManagementProtocol; + mKeyManagementData = rhs.mKeyManagementData; + mPreConditionCurrentStatus = rhs.mPreConditionCurrentStatus; + mPreConditionConfirmStatus = rhs.mPreConditionConfirmStatus; + mPreConditionDesiredStatus = rhs.mPreConditionDesiredStatus; + mMaximumPacketRate = rhs.mMaximumPacketRate; + mLabel = rhs.mLabel; + mIdentificationTag = rhs.mIdentificationTag; + mIceUserFrag = rhs.mIceUserFrag; + mIcePassword = rhs.mIcePassword; + mRemoteCandidates = rhs.mRemoteCandidates; + mCandidates = rhs.mCandidates; + mRtpCandidatePresent = rhs.mRtpCandidatePresent; + mRtcpCandidatePresent = rhs.mRtcpCandidatePresent; + mCandidatePairs = rhs.mCandidatePairs; + + return *this; +} + +void +SdpMediaLine::addCandidate(SdpCandidate& candidate) +{ + // Check if Candidate is in use (appears on m/c line or rtcp attributes) + // First check m/c line(s) + ConnectionList::iterator it = mConnections.begin(); + for(;it != mConnections.end(); it++) + { + if(candidate.getPort() == it->getPort() && + candidate.getConnectionAddress() == it->getAddress()) + { + mRtpCandidatePresent = true; + candidate.setInUse(true); + break; + } + } + + // Next check Rtcp Info + if(isRtcpEnabled()) + { + it = mRtcpConnections.begin(); + for(;it != mRtcpConnections.end(); it++) + { + if(candidate.getPort() == it->getPort() && + candidate.getConnectionAddress() == it->getAddress()) + { + mRtcpCandidatePresent = true; + candidate.setInUse(true); + break; + } + } + } + + mCandidates.insert(candidate); +} + +void +SdpMediaLine::addCandidate(const char * foundation, unsigned int id, SdpCandidate::SdpCandidateTransportType transport, + UInt64 priority, const char * connectionAddress, unsigned int port, + SdpCandidate::SdpCandidateType candidateType, const char * relatedAddress, + unsigned int relatedPort) +{ + SdpCandidate t(foundation, id, transport, priority, connectionAddress, port, candidateType, relatedAddress, relatedPort); + addCandidate(t); +} + +SdpMediaLine::SdpMediaType +SdpMediaLine::getMediaTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("audio", dataType)) + { + return MEDIA_TYPE_AUDIO; + } + else if(resip::isEqualNoCase("video", dataType)) + { + return MEDIA_TYPE_VIDEO; + } + else if(resip::isEqualNoCase("text", dataType)) + { + return MEDIA_TYPE_TEXT; + } + else if(resip::isEqualNoCase("application", dataType)) + { + return MEDIA_TYPE_APPLICATION; + } + else if(resip::isEqualNoCase("message", dataType)) + { + return MEDIA_TYPE_MESSAGE; + } + else + { + return MEDIA_TYPE_UNKNOWN; + } +} + +SdpMediaLine::SdpTransportProtocolType +SdpMediaLine::getTransportProtocolTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("udp", dataType)) + { + return PROTOCOL_TYPE_UDP; + } + else if(resip::isEqualNoCase("RTP/AVP", dataType)) + { + return PROTOCOL_TYPE_RTP_AVP; + } + else if(resip::isEqualNoCase("RTP/SAVP", dataType)) + { + return PROTOCOL_TYPE_RTP_SAVP; + } + else if(resip::isEqualNoCase("RTP/SAVPF", dataType)) + { + return PROTOCOL_TYPE_RTP_SAVPF; + } + else if(resip::isEqualNoCase("TCP", dataType)) + { + return PROTOCOL_TYPE_TCP; + } + else if(resip::isEqualNoCase("TCP/RTP/AVP", dataType)) + { + return PROTOCOL_TYPE_TCP_RTP_AVP; + } + else if(resip::isEqualNoCase("TCP/TLS", dataType)) + { + return PROTOCOL_TYPE_TCP_TLS; + } + else if(resip::isEqualNoCase("UDP/TLS", dataType)) + { + return PROTOCOL_TYPE_UDP_TLS; + } + else if(resip::isEqualNoCase("DCCP/TLS", dataType)) + { + return PROTOCOL_TYPE_DCCP_TLS; + } + else if(resip::isEqualNoCase("DCCP/TLS/RTP/SAVP", dataType)) + { + return PROTOCOL_TYPE_DCCP_TLS_RTP_SAVP; + } + else if(resip::isEqualNoCase("UDP/TLS/RTP/SAVP", dataType)) + { + return PROTOCOL_TYPE_UDP_TLS_RTP_SAVP; + } + else if(resip::isEqualNoCase("TCP/TLS/RTP/SAVP", dataType)) + { + return PROTOCOL_TYPE_TCP_TLS_RTP_SAVP; + } + else + { + return PROTOCOL_TYPE_UNKNOWN; + } +} + +SdpMediaLine::SdpOrientationType +SdpMediaLine::getOrientationTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("portrait", dataType)) + { + return ORIENTATION_TYPE_PORTRAIT; + } + else if(resip::isEqualNoCase("landscape", dataType)) + { + return ORIENTATION_TYPE_LANDSCAPE; + } + else if(resip::isEqualNoCase("seascape", dataType)) + { + return ORIENTATION_TYPE_SEASCAPE; + } + else + { + return ORIENTATION_TYPE_NONE; + } +} + +SdpMediaLine::SdpTcpSetupAttribute +SdpMediaLine::getTcpSetupAttributeFromString(const char * attrib) +{ + resip::Data dataType(attrib); + + if(resip::isEqualNoCase("active", dataType)) + { + return TCP_SETUP_ATTRIBUTE_ACTIVE; + } + else if(resip::isEqualNoCase("passive", dataType)) + { + return TCP_SETUP_ATTRIBUTE_PASSIVE; + } + else if(resip::isEqualNoCase("actpass", dataType)) + { + return TCP_SETUP_ATTRIBUTE_ACTPASS; + } + else if(resip::isEqualNoCase("holdconn", dataType)) + { + return TCP_SETUP_ATTRIBUTE_HOLDCONN; + } + else + { + return TCP_SETUP_ATTRIBUTE_NONE; + } +} + +SdpMediaLine::SdpTcpConnectionAttribute +SdpMediaLine::getTcpConnectionAttributeFromString(const char * attrib) +{ + resip::Data dataType(attrib); + + if(resip::isEqualNoCase("new", dataType)) + { + return TCP_CONNECTION_ATTRIBUTE_NEW; + } + else if(resip::isEqualNoCase("existing", dataType)) + { + return TCP_CONNECTION_ATTRIBUTE_EXISTING; + } + else + { + return TCP_CONNECTION_ATTRIBUTE_NONE; + } +} + +SdpMediaLine::SdpCryptoSuiteType +SdpMediaLine::getCryptoSuiteTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("AES_CM_128_HMAC_SHA1_80", dataType)) + { + return CRYPTO_SUITE_TYPE_AES_CM_128_HMAC_SHA1_80; + } + else if(resip::isEqualNoCase("AES_CM_128_HMAC_SHA1_32", dataType)) + { + return CRYPTO_SUITE_TYPE_AES_CM_128_HMAC_SHA1_32; + } + else if(resip::isEqualNoCase("F8_128_HMAC_SHA1_80", dataType)) + { + return CRYPTO_SUITE_TYPE_F8_128_HMAC_SHA1_80; + } + else + { + return CRYPTO_SUITE_TYPE_NONE; + } +} + +SdpMediaLine::SdpCryptoKeyMethod +SdpMediaLine::getCryptoKeyMethodFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("inline", dataType)) + { + return CRYPTO_KEY_METHOD_INLINE; + } + else + { + return CRYPTO_KEY_METHOD_NONE; + } +} + +SdpMediaLine::SdpCryptoSrtpFecOrderType +SdpMediaLine::SdpCrypto::getSrtpFecOrderFromString(const char * order) +{ + resip::Data dataType(order); + + if(resip::isEqualNoCase("FEC_SRTP", dataType)) + { + return CRYPTO_SRTP_FEC_ORDER_FEC_SRTP; + } + else if(resip::isEqualNoCase("SRTP_FEC", dataType)) + { + return CRYPTO_SRTP_FEC_ORDER_SRTP_FEC; + } + else + { + return CRYPTO_SRTP_FEC_ORDER_NONE; + } +} + +SdpMediaLine::SdpFingerPrintHashFuncType +SdpMediaLine::getFingerPrintHashFuncTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("sha-1", dataType)) + { + return FINGERPRINT_HASH_FUNC_SHA_1; + } + else if(resip::isEqualNoCase("sha-224", dataType)) + { + return FINGERPRINT_HASH_FUNC_SHA_224; + } + else if(resip::isEqualNoCase("sha-256", dataType)) + { + return FINGERPRINT_HASH_FUNC_SHA_256; + } + else if(resip::isEqualNoCase("sha-384", dataType)) + { + return FINGERPRINT_HASH_FUNC_SHA_384; + } + else if(resip::isEqualNoCase("sha-512", dataType)) + { + return FINGERPRINT_HASH_FUNC_SHA_512; + } + else if(resip::isEqualNoCase("md5", dataType)) + { + return FINGERPRINT_HASH_FUNC_MD5; + } + else if(resip::isEqualNoCase("md2", dataType)) + { + return FINGERPRINT_HASH_FUNC_MD2; + } + else + { + return FINGERPRINT_HASH_FUNC_NONE; + } +} + +SdpMediaLine::SdpKeyManagementProtocolType +SdpMediaLine::getKeyManagementProtocolTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("mikey", dataType)) + { + return KEYMANAGEMENT_PROTOCOL_MIKEY; + } + else + { + return KEYMANAGEMENT_PROTOCOL_NONE; + } +} + +SdpMediaLine::SdpPreConditionType +SdpMediaLine::getPreConditionTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("qos", dataType)) + { + return PRECONDITION_TYPE_QOS; + } + else + { + return PRECONDITION_TYPE_NONE; + } +} + +SdpMediaLine::SdpPreConditionStatusType +SdpMediaLine::getPreConditionStatusTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("e2e", dataType)) + { + return PRECONDITION_STATUS_E2E; + } + else if(resip::isEqualNoCase("local", dataType)) + { + return PRECONDITION_STATUS_LOCAL; + } + else if(resip::isEqualNoCase("remote", dataType)) + { + return PRECONDITION_STATUS_REMOTE; + } + else + { + return PRECONDITION_STATUS_NONE; + } +} + +SdpMediaLine::SdpPreConditionDirectionType +SdpMediaLine::getPreConditionDirectionTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("send", dataType)) + { + return PRECONDITION_DIRECTION_SEND; + } + else if(resip::isEqualNoCase("recv", dataType)) + { + return PRECONDITION_DIRECTION_RECV; + } + else if(resip::isEqualNoCase("sendrecv", dataType)) + { + return PRECONDITION_DIRECTION_SENDRECV; + } + else + { + return PRECONDITION_DIRECTION_NONE; + } +} + +SdpMediaLine::SdpPreConditionStrengthType +SdpMediaLine::getPreConditionStrengthTypeFromString(const char * type) +{ + resip::Data dataType(type); + + if(resip::isEqualNoCase("mandatory", dataType)) + { + return PRECONDITION_STRENGTH_MANDATORY; + } + else if(resip::isEqualNoCase("optional", dataType)) + { + return PRECONDITION_STRENGTH_OPTIONAL; + } + else if(resip::isEqualNoCase("none", dataType)) + { + return PRECONDITION_STRENGTH_NONE; + } + else if(resip::isEqualNoCase("failure", dataType)) + { + return PRECONDITION_STRENGTH_FAILURE; + } + else if(resip::isEqualNoCase("unknown", dataType)) + { + return PRECONDITION_STRENGTH_UNKNWOWN; + } + else + { + return PRECONDITION_STRENGTH_NONE; + } +} + +EncodeStream& +sdpcontainer::operator<<( EncodeStream& strm, const SdpMediaLine& sdpMediaLine) +{ + strm << "MediaLine:" << std::endl + << "Type: " << sdpMediaLine.mMediaTypeString << std::endl + << "TransportProtocol: " << sdpMediaLine.mTransportProtocolTypeString << std::endl; + + SdpMediaLine::CodecList::const_iterator itCodec = sdpMediaLine.mCodecs.begin(); + for(;itCodec != sdpMediaLine.mCodecs.end(); itCodec++) + { + strm << *itCodec; + } + + strm << "Title: '" << sdpMediaLine.mTitle << "'" << std::endl; + + SdpMediaLine::ConnectionList::const_iterator itConnection = sdpMediaLine.mConnections.begin(); + for(;itConnection != sdpMediaLine.mConnections.end(); itConnection++) + { + strm << "Connection: netType=" << Sdp::SdpNetTypeString[itConnection->getNetType()] + << ", addrType=" << Sdp::SdpAddressTypeString[itConnection->getAddressType()] + << ", addr=" << itConnection->getAddress() + << ", port=" << itConnection->getPort() + << ", ttl=" << itConnection->getMulticastIpV4Ttl() << std::endl; + } + + SdpMediaLine::ConnectionList::const_iterator itRtcpConnection = sdpMediaLine.mRtcpConnections.begin(); + for(;itRtcpConnection != sdpMediaLine.mRtcpConnections.end(); itRtcpConnection++) + { + strm << "RTCP Connection: netType=" << Sdp::SdpNetTypeString[itRtcpConnection->getNetType()] + << ", addrType=" << Sdp::SdpAddressTypeString[itRtcpConnection->getAddressType()] + << ", addr=" << itRtcpConnection->getAddress() + << ", port=" << itRtcpConnection->getPort() + << ", ttl=" << itRtcpConnection->getMulticastIpV4Ttl() << std::endl; + } + + Sdp::BandwidthList::const_iterator itBandwidth = sdpMediaLine.mBandwidths.begin(); + for(;itBandwidth != sdpMediaLine.mBandwidths.end(); itBandwidth++) + { + strm << "Bandwidth: type=" << Sdp::SdpBandwidthTypeString[itBandwidth->getType()] + << ", bandwidth=" << itBandwidth->getBandwidth() << std::endl; + } + + strm << "Encryption Key: method=" << SdpMediaLine::SdpEncryptionMethodString[sdpMediaLine.mEncryptionMethod] + << ", data='" << sdpMediaLine.mEncryptionKey << "'" << std::endl + << "Direction: " << SdpMediaLine::SdpDirectionTypeString[sdpMediaLine.mDirection] << std::endl + << "PacketTime: " << sdpMediaLine.mPacketTime << std::endl + << "MaxPacketTime: " << sdpMediaLine.mMaxPacketTime << std::endl + << "Orientation: " << SdpMediaLine::SdpOrientationTypeString[sdpMediaLine.mOrientation] << std::endl + << "DescriptionLanguage: '" << sdpMediaLine.mDescriptionLanguage << "'" << std::endl + << "Language: '" << sdpMediaLine.mLanguage << "'" << std::endl + << "FrameRate: " << sdpMediaLine.mFrameRate << std::endl + << "Quality: " << sdpMediaLine.mQuality << std::endl + << "TcpSetupAttrib: " << SdpMediaLine::SdpTcpSetupAttributeString[sdpMediaLine.mTcpSetupAttribute] << std::endl + << "TcpConnectionAttrib: " << SdpMediaLine::SdpTcpConnectionAttributeString[sdpMediaLine.mTcpConnectionAttribute] << std::endl; + + SdpMediaLine::CryptoList::const_iterator itCrypto = sdpMediaLine.mCryptos.begin(); + for(;itCrypto != sdpMediaLine.mCryptos.end(); itCrypto++) + { + strm << "Crypto: tag=" << itCrypto->getTag() + << ", suite=" << SdpMediaLine::SdpCryptoSuiteTypeString[itCrypto->getSuite()]; + + SdpMediaLine::SdpCrypto::CryptoKeyParamList::const_iterator itKeyParam = itCrypto->getCryptoKeyParams().begin(); + for(;itKeyParam!=itCrypto->getCryptoKeyParams().end(); itKeyParam++) + { + strm << std::endl << " Key Param: method=" << SdpMediaLine::SdpCryptoKeyMethodString[itKeyParam->getKeyMethod()] + << ", key=" << itKeyParam->getKeyValue() + << ", srtpLifetime=" << itKeyParam->getSrtpLifetime() + << ", srtpMkiValue=" << itKeyParam->getSrtpMkiValue() + << ", srtpMkiLength=" << itKeyParam->getSrtpMkiLength(); + } + + strm << std::endl << " kdr=" << itCrypto->getSrtpKdr() + << ", encryptSrtp=" << itCrypto->getEncryptedSrtp() + << ", encryptSrtcp=" << itCrypto->getEncryptedSrtcp() + << ", authSrtp=" << itCrypto->getAuthenticatedSrtp() + << ", fecOrder=" << SdpMediaLine::SdpCryptoSrtpFecOrderTypeString[itCrypto->getSrtpFecOrder()] + << ", wsh=" << itCrypto->getSrtpWsh(); + if(itCrypto->getSrtpFecKey().getKeyMethod() != SdpMediaLine::CRYPTO_KEY_METHOD_NONE) + { + strm << std::endl << " fecKeyMethod=" << SdpMediaLine::SdpCryptoKeyMethodString[itCrypto->getSrtpFecKey().getKeyMethod()] + << ", fecKey=" << itCrypto->getSrtpFecKey().getKeyValue() + << ", fecLifetime=" << itCrypto->getSrtpFecKey().getSrtpLifetime() + << ", fecMkiValue=" << itCrypto->getSrtpFecKey().getSrtpMkiValue() + << ", fecMkiLength=" << itCrypto->getSrtpFecKey().getSrtpMkiLength(); + } + + SdpMediaLine::SdpCrypto::GenericSessionParamList::const_iterator itSessParam = itCrypto->getGenericSessionParams().begin(); + for(;itSessParam!=itCrypto->getGenericSessionParams().end(); itSessParam++) + { + strm << std::endl << " sessParam=" << *itSessParam; + } + strm << std::endl; + } + + strm << "FingerPrint: type=" << SdpMediaLine::SdpFingerPrintHashFuncTypeString[sdpMediaLine.mFingerPrintHashFunction] + << ", '" << sdpMediaLine.mFingerPrint << "'" << std::endl + << "KeyManagement: type=" << SdpMediaLine::SdpKeyManagementProtocolTypeString[sdpMediaLine.mKeyManagementProtocol] + << ", '" << sdpMediaLine.mKeyManagementData << "'" << std::endl; + + SdpMediaLine::SdpPreConditionList::const_iterator itCurrentStatus = sdpMediaLine.mPreConditionCurrentStatus.begin(); + for(;itCurrentStatus != sdpMediaLine.mPreConditionCurrentStatus.end(); itCurrentStatus++) + { + strm << "PreConditionCurrentStatus: type=" << SdpMediaLine::SdpPreConditionTypeString[itCurrentStatus->getType()] + << ", status=" << SdpMediaLine::SdpPreConditionStatusTypeString[itCurrentStatus->getStatus()] + << ", direction=" << SdpMediaLine::SdpPreConditionDirectionTypeString[itCurrentStatus->getDirection()] << std::endl; + } + + SdpMediaLine::SdpPreConditionList::const_iterator itConfirmStatus = sdpMediaLine.mPreConditionConfirmStatus.begin(); + for(;itConfirmStatus != sdpMediaLine.mPreConditionConfirmStatus.end(); itConfirmStatus++) + { + strm << "PreConditionConfirmStatus: type=" << SdpMediaLine::SdpPreConditionTypeString[itConfirmStatus->getType()] + << ", status=" << SdpMediaLine::SdpPreConditionStatusTypeString[itConfirmStatus->getStatus()] + << ", direction=" << SdpMediaLine::SdpPreConditionDirectionTypeString[itConfirmStatus->getDirection()] << std::endl; + } + + SdpMediaLine::SdpPreConditionDesiredStatusList::const_iterator itDesiredStatus = sdpMediaLine.mPreConditionDesiredStatus.begin(); + for(;itDesiredStatus != sdpMediaLine.mPreConditionDesiredStatus.end(); itDesiredStatus++) + { + strm << "PreConditionDesiredStatus: type=" << SdpMediaLine::SdpPreConditionTypeString[itDesiredStatus->getType()] + << ", strength=" << SdpMediaLine::SdpPreConditionStrengthTypeString[itDesiredStatus->getStrength()] + << ", status=" << SdpMediaLine::SdpPreConditionStatusTypeString[itDesiredStatus->getStatus()] + << ", direction=" << SdpMediaLine::SdpPreConditionDirectionTypeString[itDesiredStatus->getDirection()] << std::endl; + } + + strm << "MaximumPacketRate: " << sdpMediaLine.mMaximumPacketRate << std::endl + << "Label: '" << sdpMediaLine.mLabel << "'" << std::endl + << "IdentificationTag: '" << sdpMediaLine.mIdentificationTag << "'" << std::endl + << "IceUserFrag: '" << sdpMediaLine.mIceUserFrag << "'" << std::endl + << "IcePassword: '" << sdpMediaLine.mIcePassword << "'" << std::endl; + + SdpMediaLine::SdpRemoteCandidateList::const_iterator itRemoteCandidate = sdpMediaLine.mRemoteCandidates.begin(); + for(;itRemoteCandidate != sdpMediaLine.mRemoteCandidates.end(); itRemoteCandidate++) + { + strm << "Remote Candidate: componentId=" << itRemoteCandidate->getComponentId() + << ", addr=" << itRemoteCandidate->getConnectionAddress() + << ", port=" << itRemoteCandidate->getPort() << std::endl; + } + + strm << "IceSupported: " << sdpMediaLine.isIceSupported() << std::endl; + + SdpMediaLine::SdpCandidateList::const_iterator itCandidate = sdpMediaLine.mCandidates.begin(); + for(;itCandidate != sdpMediaLine.mCandidates.end(); itCandidate++) + { + strm << *itCandidate; + } + + SdpMediaLine::SdpCandidatePairList::const_iterator itCandidatePair = sdpMediaLine.mCandidatePairs.begin(); + for(;itCandidatePair != sdpMediaLine.mCandidatePairs.end(); itCandidatePair++) + { + strm << *itCandidatePair; + } + + SdpMediaLine::SdpMediaLineList::const_iterator itPotentialMediaLine = sdpMediaLine.mPotentialMediaViews.begin(); + for(;itPotentialMediaLine!=sdpMediaLine.mPotentialMediaViews.end();itPotentialMediaLine++) + { + strm << "PotentialMediaView:" << std::endl << *itPotentialMediaLine; + } + + strm << "PotentialMediaViewString: '" << sdpMediaLine.mPotentialMediaViewString << "'" << std::endl; + + return strm; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/sdp/SdpMediaLine.hxx b/src/libs/resiprocate/resip/recon/sdp/SdpMediaLine.hxx new file mode 100644 index 00000000..011a19cd --- /dev/null +++ b/src/libs/resiprocate/resip/recon/sdp/SdpMediaLine.hxx @@ -0,0 +1,715 @@ +#if !defined(SdpMediaLine_hxx) +#define SdpMediaLine_hxx + +#include "Sdp.hxx" +#include "SdpCodec.hxx" +#include "SdpCandidate.hxx" +#include "SdpCandidatePair.hxx" +#include <set> + +namespace sdpcontainer +{ + +class SdpMediaLine +{ +public: + + typedef enum + { + MEDIA_TYPE_NONE, + MEDIA_TYPE_UNKNOWN, + MEDIA_TYPE_AUDIO, // "audio" - RFC4566 + MEDIA_TYPE_VIDEO, // "video" - RFC4566 + MEDIA_TYPE_TEXT, // "text" - RFC4566 + MEDIA_TYPE_APPLICATION, // "application" - RFC4566 + MEDIA_TYPE_MESSAGE // "message" - RFC4566 + } SdpMediaType; + static const char* SdpMediaTypeString[]; + + typedef enum + { + PROTOCOL_TYPE_NONE, + PROTOCOL_TYPE_UNKNOWN, + PROTOCOL_TYPE_UDP, // "udp" - RFC4566 + PROTOCOL_TYPE_RTP_AVP, // "RTP/AVP" - RFC4566 + PROTOCOL_TYPE_RTP_SAVP, // "RTP/SAVP" - RFC4566 + PROTOCOL_TYPE_RTP_SAVPF, // "RTP/SAVPF" - RFC3711 + PROTOCOL_TYPE_TCP, // "TCP" - RFC4145 + PROTOCOL_TYPE_TCP_RTP_AVP, // "TCP/RTP/AVP" - RFC4571 + PROTOCOL_TYPE_TCP_TLS, // "TCP/TLS" - RFC4572 + PROTOCOL_TYPE_UDP_TLS, // "UDP/TLS" - draft-fischl-mmusic-sdp-dtls-04 + PROTOCOL_TYPE_DCCP_TLS, // "DCCP/TLS" - draft-fischl-mmusic-sdp-dtls-04 + PROTOCOL_TYPE_DCCP_TLS_RTP_SAVP, // "DCCP/TLS/RTP/SAVP" - draft-fischl-mmusic-sdp-dtls-04 + PROTOCOL_TYPE_UDP_TLS_RTP_SAVP, // "UDP/TLS/RTP/SAVP" - draft-fischl-mmusic-sdp-dtls-04 + PROTOCOL_TYPE_TCP_TLS_RTP_SAVP // "TCP/TLS/RTP/SAVP" - draft-fischl-mmusic-sdp-dtls-04 + } SdpTransportProtocolType; + static const char* SdpTransportProtocolTypeString[]; + + class SdpConnection + { + public: + SdpConnection(Sdp::SdpNetType netType = Sdp::NET_TYPE_NONE, + Sdp::SdpAddressType addressType = Sdp::ADDRESS_TYPE_NONE, + const char * address = 0, + unsigned int port = 0, + unsigned int multicastIpV4Ttl=0) : + mNetType(netType), mAddressType(addressType), mAddress(address), mPort(port), mMulticastIpV4Ttl(multicastIpV4Ttl) {} + SdpConnection(const SdpConnection& rhs) : + mNetType(rhs.mNetType), mAddressType(rhs.mAddressType), mAddress(rhs.mAddress), mPort(rhs.mPort), mMulticastIpV4Ttl(rhs.mMulticastIpV4Ttl) {} + + void setNetType(Sdp::SdpNetType netType) { mNetType = netType; } + Sdp::SdpNetType getNetType() const { return mNetType; } + + void setAddressType(Sdp::SdpAddressType addressType) { mAddressType = addressType; } + Sdp::SdpAddressType getAddressType() const { return mAddressType; } + + void setAddress(const char * address) { mAddress = address; } + const resip::Data& getAddress() const { return mAddress; } + + void setPort(unsigned int port) { mPort = port; } + unsigned int getPort() const { return mPort; } + + void setMulticastIpV4Ttl(unsigned int multicastIpV4Ttl) { mMulticastIpV4Ttl = multicastIpV4Ttl; } + unsigned int getMulticastIpV4Ttl() const { return mMulticastIpV4Ttl; } + + private: + Sdp::SdpNetType mNetType; + Sdp::SdpAddressType mAddressType; + resip::Data mAddress; + unsigned int mPort; + unsigned int mMulticastIpV4Ttl; + }; + + typedef enum + { + ENCRYPTION_METHOD_NONE, + ENCRYPTION_METHOD_CLEAR, // "clear" - RFC4566 + ENCRYPTION_METHOD_BASE64, // "base64" - RFC4566 + ENCRYPTION_METHOD_URI, // "uri" - RFC4566 + ENCRYPTION_METHOD_PROMPT // "prompt" - RFC4566 + } SdpEncryptionMethod; + static const char* SdpEncryptionMethodString[]; + + typedef enum + { + DIRECTION_TYPE_NONE, + DIRECTION_TYPE_SENDRECV, // "sendrecv" - RFC4566 + DIRECTION_TYPE_SENDONLY, // "sendonly" - RFC4566 + DIRECTION_TYPE_RECVONLY, // "recvonly" - RFC4566 + DIRECTION_TYPE_INACTIVE // "inactive" - RFC4566 + } SdpDirectionType; + static const char* SdpDirectionTypeString[]; + + typedef enum + { + ORIENTATION_TYPE_NONE, + ORIENTATION_TYPE_PORTRAIT, // "portrait" - RFC 4566 + ORIENTATION_TYPE_LANDSCAPE,// "landscape" - RFC 4566 + ORIENTATION_TYPE_SEASCAPE // "seascape" - RFC 4566 + } SdpOrientationType; + static const char* SdpOrientationTypeString[]; + + typedef enum + { + TCP_SETUP_ATTRIBUTE_NONE, + TCP_SETUP_ATTRIBUTE_ACTIVE, // "active" - RFC4145 + TCP_SETUP_ATTRIBUTE_PASSIVE, // "passive" - RFC4145 + TCP_SETUP_ATTRIBUTE_ACTPASS, // "actpass" - RFC4145 + TCP_SETUP_ATTRIBUTE_HOLDCONN // "holdconn" - RFC4145 + } SdpTcpSetupAttribute; + static const char* SdpTcpSetupAttributeString[]; + + typedef enum + { + TCP_CONNECTION_ATTRIBUTE_NONE, + TCP_CONNECTION_ATTRIBUTE_NEW, // "new" - RFC4145 + TCP_CONNECTION_ATTRIBUTE_EXISTING // "existing" - RFC4145 + } SdpTcpConnectionAttribute; + static const char* SdpTcpConnectionAttributeString[]; + + typedef enum + { + CRYPTO_SUITE_TYPE_NONE, + CRYPTO_SUITE_TYPE_AES_CM_128_HMAC_SHA1_80, // "AES_CM_128_HMAC_SHA1_80" - RFC4568 + CRYPTO_SUITE_TYPE_AES_CM_128_HMAC_SHA1_32, // "AES_CM_128_HMAC_SHA1_32" - RFC4568 + CRYPTO_SUITE_TYPE_F8_128_HMAC_SHA1_80 // "F8_128_HMAC_SHA1_80" - RFC4568 + } SdpCryptoSuiteType; + static const char* SdpCryptoSuiteTypeString[]; + + typedef enum + { + CRYPTO_KEY_METHOD_NONE, + CRYPTO_KEY_METHOD_INLINE // "inline" - RFC4568 + } SdpCryptoKeyMethod; + static const char* SdpCryptoKeyMethodString[]; + + typedef enum + { + CRYPTO_SRTP_FEC_ORDER_NONE, + CRYPTO_SRTP_FEC_ORDER_FEC_SRTP, // "FEC_SRTP" - RFC 4568 + CRYPTO_SRTP_FEC_ORDER_SRTP_FEC // "SRTP_FEC" - RFC 2568 + } SdpCryptoSrtpFecOrderType; + static const char* SdpCryptoSrtpFecOrderTypeString[]; + + class SdpCrypto + { + public: + class SdpCryptoKeyParam + { + public: + SdpCryptoKeyParam(SdpCryptoKeyMethod keyMethod=SdpMediaLine::CRYPTO_KEY_METHOD_NONE, const char * keyValue=0, unsigned int srtpLifetime=0, unsigned int srtpMkiValue=0, unsigned int srtpMkiLength=0) : + mKeyMethod(keyMethod), mKeyValue(keyValue), mSrtpLifetime(srtpLifetime), mSrtpMkiValue(srtpMkiValue), mSrtpMkiLength(srtpMkiLength) {} + SdpCryptoKeyParam(const SdpCryptoKeyParam& rhs) : + mKeyMethod(rhs.mKeyMethod), mKeyValue(rhs.mKeyValue), mSrtpLifetime(rhs.mSrtpLifetime), mSrtpMkiValue(rhs.mSrtpMkiValue), mSrtpMkiLength(rhs.mSrtpMkiLength) {} + + void setKeyMethod(SdpCryptoKeyMethod keyMethod) { mKeyMethod = keyMethod; } + SdpCryptoKeyMethod getKeyMethod() const { return mKeyMethod; } + + void setKeyValue(const char * keyValue) { mKeyValue = keyValue; } + const resip::Data& getKeyValue() const { return mKeyValue; } + + void setSrtpLifetime(unsigned int srtpLifetime) { mSrtpLifetime = srtpLifetime; } + unsigned int getSrtpLifetime() const { return mSrtpLifetime; } + + void setSrtpMkiValue(unsigned int srtpMkiValue) { mSrtpMkiValue = srtpMkiValue; } + unsigned int getSrtpMkiValue() const { return mSrtpMkiValue; } + + void setSrtpMkiLength(unsigned int srtpMkiLength) { mSrtpMkiLength = srtpMkiLength; } + unsigned int getSrtpMkiLength() const { return mSrtpMkiLength; } + + private: + SdpCryptoKeyMethod mKeyMethod; + resip::Data mKeyValue; // srtp key-salt or generic key-info + unsigned int mSrtpLifetime; + unsigned int mSrtpMkiValue; + unsigned int mSrtpMkiLength; + }; + + SdpCrypto() : mTag(0), mSuite(SdpMediaLine::CRYPTO_SUITE_TYPE_NONE), mSrtpKdr(0), mEncryptedSrtp(1), mEncryptedSrtcp(1), + mAuthenticatedSrtp(1), mSrtpFecOrder(SdpMediaLine::CRYPTO_SRTP_FEC_ORDER_FEC_SRTP), mSrtpWsh(0) {} + SdpCrypto(const SdpCrypto& rSdpCandidatePair); + ~SdpCrypto() { } + + typedef std::list<SdpCryptoKeyParam> CryptoKeyParamList; + typedef std::list<resip::Data> GenericSessionParamList; + + SdpCrypto& operator=(const SdpCrypto& rhs); + + void setTag(unsigned int tag) { mTag = tag; } + unsigned int getTag() const { return mTag; } + + void setSuite(SdpCryptoSuiteType suite) { mSuite = suite; } + SdpCryptoSuiteType getSuite() const { return mSuite; } + + void addCryptoKeyParam(SdpCryptoKeyMethod keyMethod, const char * keyValue, unsigned int srtpLifetime=0, unsigned int srtpMkiValue=0, unsigned int srtpMkiLength=0) + { addCryptoKeyParam(SdpCryptoKeyParam(keyMethod, keyValue, srtpLifetime, srtpMkiValue, srtpMkiLength)); } + void addCryptoKeyParam(const SdpCryptoKeyParam& keyParam) { mCryptoKeyParams.push_back(keyParam); } + void clearCryptoKeyParams() { mCryptoKeyParams.clear(); } + const CryptoKeyParamList& getCryptoKeyParams() const { return mCryptoKeyParams; } + + void setSrtpKdr(unsigned int srtpKdr) { mSrtpKdr = srtpKdr; } + unsigned int getSrtpKdr() const { return mSrtpKdr; } + + void setEncryptedSrtp(bool encryptedSrtp) { mEncryptedSrtp = encryptedSrtp; } + bool getEncryptedSrtp() const { return mEncryptedSrtp; } + + void setEncryptedSrtcp(bool encryptedSrtcp) { mEncryptedSrtcp = encryptedSrtcp; } + bool getEncryptedSrtcp() const { return mEncryptedSrtcp; } + + void setAuthenticatedSrtp(bool authenticatedSrtp) { mAuthenticatedSrtp = authenticatedSrtp; } + bool getAuthenticatedSrtp() const { return mAuthenticatedSrtp; } + + void setSrtpFecOrder(SdpCryptoSrtpFecOrderType srtpFecOrder) { mSrtpFecOrder = srtpFecOrder; } + SdpCryptoSrtpFecOrderType getSrtpFecOrder() const { return mSrtpFecOrder; } + static SdpCryptoSrtpFecOrderType getSrtpFecOrderFromString(const char * order); + + void setSrtpFecKey(SdpCryptoKeyMethod keyMethod, const char * keyValue, unsigned int srtpLifetime=0, unsigned int srtpMkiValue=0, unsigned int srtpMkiLength=0) + { mSrtpFecKey.setKeyMethod(keyMethod); mSrtpFecKey.setKeyValue(keyValue); mSrtpFecKey.setSrtpLifetime(srtpLifetime); + mSrtpFecKey.setSrtpMkiValue(srtpMkiValue); mSrtpFecKey.setSrtpMkiLength(srtpMkiLength); } + const SdpCryptoKeyParam& getSrtpFecKey() const { return mSrtpFecKey; } + + void setSrtpWsh(unsigned int srtpWsh) { mSrtpWsh = srtpWsh; } + unsigned int getSrtpWsh() const { return mSrtpWsh; } + + void addGenericSessionParam(const char * sessionParam) { mGenericSessionParams.push_back(sessionParam); } + void clearGenericSessionParams() { mGenericSessionParams.clear(); } + const GenericSessionParamList& getGenericSessionParams() const { return mGenericSessionParams; } + + private: + unsigned int mTag; + SdpCryptoSuiteType mSuite; + CryptoKeyParamList mCryptoKeyParams; + unsigned int mSrtpKdr; + bool mEncryptedSrtp; + bool mEncryptedSrtcp; + bool mAuthenticatedSrtp; + SdpCryptoSrtpFecOrderType mSrtpFecOrder; + SdpCryptoKeyParam mSrtpFecKey; + unsigned int mSrtpWsh; + GenericSessionParamList mGenericSessionParams; + }; + + typedef enum + { + FINGERPRINT_HASH_FUNC_NONE, + FINGERPRINT_HASH_FUNC_SHA_1, // "sha-1" - RFC4572 + FINGERPRINT_HASH_FUNC_SHA_224, // "sha-224" - RFC4572 + FINGERPRINT_HASH_FUNC_SHA_256, // "sha-256" - RFC4572 + FINGERPRINT_HASH_FUNC_SHA_384, // "sha-384" - RFC4572 + FINGERPRINT_HASH_FUNC_SHA_512, // "sha-512" - RFC4572 + FINGERPRINT_HASH_FUNC_MD5, // "md5" - RFC4572 + FINGERPRINT_HASH_FUNC_MD2 // "md2" - RFC4572 + } SdpFingerPrintHashFuncType; + static const char* SdpFingerPrintHashFuncTypeString[]; + + typedef enum + { + KEYMANAGEMENT_PROTOCOL_NONE, + KEYMANAGEMENT_PROTOCOL_MIKEY // 'mikey' - RFC4567 + } SdpKeyManagementProtocolType; + static const char* SdpKeyManagementProtocolTypeString[]; + + typedef enum + { + PRECONDITION_TYPE_NONE, + PRECONDITION_TYPE_QOS // "qos" - RFC3312 + } SdpPreConditionType; + static const char* SdpPreConditionTypeString[]; + + typedef enum + { + PRECONDITION_STRENGTH_MANDATORY, // "mandatory" - RFC3312 + PRECONDITION_STRENGTH_OPTIONAL, // "optional" - RFC3312 + PRECONDITION_STRENGTH_NONE, // "none" - RFC3312 + PRECONDITION_STRENGTH_FAILURE, // "failure" - RFC3312 + PRECONDITION_STRENGTH_UNKNWOWN // "unknown" - RFC3312 + } SdpPreConditionStrengthType; + static const char* SdpPreConditionStrengthTypeString[]; + + typedef enum + { + PRECONDITION_STATUS_NONE, + PRECONDITION_STATUS_E2E, // "e2e" - RFC3312 + PRECONDITION_STATUS_LOCAL, // "local" - RFC3312 + PRECONDITION_STATUS_REMOTE, // "remote" - RFC3312 + } SdpPreConditionStatusType; + static const char* SdpPreConditionStatusTypeString[]; + + typedef enum + { + PRECONDITION_DIRECTION_NONE, // "none" - RFC3312 + PRECONDITION_DIRECTION_SEND, // "send" - RFC3312 + PRECONDITION_DIRECTION_RECV, // "recv" - RFC3312 + PRECONDITION_DIRECTION_SENDRECV, // "sendrecv" - RFC3312 + } SdpPreConditionDirectionType; + static const char* SdpPreConditionDirectionTypeString[]; + + class SdpPreCondition + { + public: + SdpPreCondition(SdpPreConditionType type, SdpPreConditionStatusType status, SdpPreConditionDirectionType direction) : + mType(type), mStatus(status), mDirection(direction) {} + SdpPreCondition(const SdpPreCondition& rhs) : + mType(rhs.mType), mStatus(rhs.mStatus), mDirection(rhs.mDirection) {} + + void setType(SdpPreConditionType type) { mType = type; } + SdpPreConditionType getType() const { return mType; } + + void setStatus(SdpPreConditionStatusType status) { mStatus = status; } + SdpPreConditionStatusType getStatus() const { return mStatus; } + + void setDirection(SdpPreConditionDirectionType direction) { mDirection = direction; } + SdpPreConditionDirectionType getDirection() const { return mDirection; } + + private: + SdpPreConditionType mType; + SdpPreConditionStatusType mStatus; + SdpPreConditionDirectionType mDirection; + }; + + class SdpPreConditionDesiredStatus : public SdpPreCondition + { + public: + SdpPreConditionDesiredStatus(SdpPreConditionType type, SdpPreConditionStrengthType strength, SdpPreConditionStatusType status, SdpPreConditionDirectionType direction) : + SdpPreCondition(type, status, direction), mStrength(strength) {} + SdpPreConditionDesiredStatus(const SdpPreConditionDesiredStatus& rhs) : + SdpPreCondition(rhs), mStrength(rhs.mStrength) {} + + void setStrength(SdpPreConditionStrengthType strength) { mStrength = strength; } + SdpPreConditionStrengthType getStrength() const { return mStrength; } + + private: + SdpPreConditionStrengthType mStrength; + }; + + class SdpRemoteCandidate + { + public: + SdpRemoteCandidate(unsigned int componentId, const char * connectionAddress, unsigned int port) : + mComponentId(componentId), mConnectionAddress(connectionAddress), mPort(port) {} + SdpRemoteCandidate(const SdpRemoteCandidate& rhs) : + mComponentId(rhs.mComponentId), mConnectionAddress(rhs.mConnectionAddress), mPort(rhs.mPort) {} + + void setComponentId(unsigned int componentId) { mComponentId = componentId; } + unsigned int getComponentId() const { return mComponentId; } + + void setConnectionAddress(const char * connectionAddress) { mConnectionAddress = connectionAddress; } + const resip::Data& getConnectionAddress() const { return mConnectionAddress; } + + void setPort(unsigned int port) { mPort = port; } + unsigned int getPort() const { return mPort; } + + private: + unsigned int mComponentId; + resip::Data mConnectionAddress; + unsigned int mPort; + }; + + class SdpTransportProtocolCapabilities + { + public: + SdpTransportProtocolCapabilities(unsigned int id, SdpTransportProtocolType type) : + mId(id), mType(type) {} + SdpTransportProtocolCapabilities(const SdpTransportProtocolCapabilities& rhs) : + mId(rhs.mId), mType(rhs.mType) {} + void setId(unsigned int id) { mId = id; } + const unsigned int getId() const { return mId; } + + void setType(SdpTransportProtocolType type) { mType = type; } + SdpTransportProtocolType getType() const { return mType; } + + private: + unsigned int mId; + SdpTransportProtocolType mType; + }; + + class SdpPotentialConfiguration + { + public: + class ConfigIdItem + { + public: + ConfigIdItem(unsigned id, bool optional=false) : mId(id), mOptional(optional) {} + ConfigIdItem(const ConfigIdItem& rhs) : mId(rhs.mId), mOptional(rhs.mOptional) {} + + void setId(unsigned int id) { mId = id; } + const unsigned int getId() const { return mId; } + + void setOptional(bool optional) { mOptional = optional; } + const bool getOptional() const { return mOptional; } + + private: + unsigned int mId; + bool mOptional; + }; + + SdpPotentialConfiguration(unsigned int id, bool deleteMediaAttributes, bool deleteSessionAttributes, unsigned int transportId) : + mId(id), mDeleteMediaAttributes(deleteMediaAttributes), mDeleteSessionAttributes(deleteSessionAttributes), mTransportId(transportId) {} + SdpPotentialConfiguration(const SdpPotentialConfiguration& rhs) : + mId(rhs.mId), mDeleteMediaAttributes(rhs.mDeleteMediaAttributes), mDeleteSessionAttributes(rhs.mDeleteSessionAttributes), + mTransportId(rhs.mTransportId), mAttributeIdList(rhs.mAttributeIdList) {} + + typedef std::list<ConfigIdItem> ConfigIdList; + + void setId(unsigned int id) { mId = id; } + const unsigned int getId() const { return mId; } + + void setDeleteMediaAttributes(bool deleteMediaAttributes) { mDeleteMediaAttributes = deleteMediaAttributes; } + const bool getDeleteMediaAttributes() const { return mDeleteMediaAttributes; } + + void setDeleteSessionAttributes(bool deleteSessionAttributes) { mDeleteSessionAttributes = deleteSessionAttributes; } + const bool getDeleteSessionAttributes() const { return mDeleteSessionAttributes; } + + void setTransportId(unsigned int transportId) { mTransportId = transportId; } + const unsigned int getTransportId() const { return mTransportId; } + + void addAttributeId(unsigned int id, bool optional) { addAttributeId(ConfigIdItem(id, optional)); } + void addAttributeId(const ConfigIdItem& configIdItem) { mAttributeIdList.push_back(configIdItem); } + void clearAttributeIds() { mAttributeIdList.clear(); } + const ConfigIdList& getAttributeIds() const { return mAttributeIdList; } + + private: + unsigned int mId; + bool mDeleteMediaAttributes; + bool mDeleteSessionAttributes; + unsigned int mTransportId; + ConfigIdList mAttributeIdList; + }; + + SdpMediaLine(); + SdpMediaLine(const SdpMediaLine& rSdpMediaLine); + virtual ~SdpMediaLine(); + + SdpMediaLine& operator=(const SdpMediaLine& rhs); + + void setMediaType(SdpMediaType mediaType) { mMediaType = mediaType; mMediaTypeString = SdpMediaLine::SdpMediaTypeString[mediaType];} + void setMediaType(const resip::Data& mediaTypeString) { mMediaType = getMediaTypeFromString(mediaTypeString.c_str()); mMediaTypeString = mediaTypeString;} + void setTransportProtocolType(SdpTransportProtocolType transportProtocolType) { mTransportProtocolType = transportProtocolType; mTransportProtocolTypeString = SdpMediaLine::SdpTransportProtocolTypeString[transportProtocolType]; } + void setTransportProtocolType(const resip::Data& transportProtocolTypeString) { mTransportProtocolType = getTransportProtocolTypeFromString(transportProtocolTypeString.c_str()); mTransportProtocolTypeString = transportProtocolTypeString; } + + void addCodec(const SdpCodec& codec) { mCodecs.push_back(codec); } + void clearCodecs() { mCodecs.clear(); } + + void setTitle(const char * title) { mTitle = title; } + + void addConnection(Sdp::SdpNetType netType, Sdp::SdpAddressType addressType, const char * address, unsigned int port, unsigned int multicastIpV4Ttl=0) + { addConnection(SdpConnection(netType, addressType, address, port, multicastIpV4Ttl)); } + void addConnection(const SdpConnection& connection) { mConnections.push_back(connection); } + void clearConnections() { mConnections.clear(); } + + void addRtcpConnection(Sdp::SdpNetType netType, Sdp::SdpAddressType addressType, const char * address, unsigned int port, unsigned int multicastIpV4Ttl=0) + { addRtcpConnection(SdpConnection(netType, addressType, address, port, multicastIpV4Ttl)); } + void addRtcpConnection(const SdpConnection& connection) { mRtcpConnections.push_back(connection); } + void clearRtcpConnections() { mRtcpConnections.clear(); } + + void addBandwidth(Sdp::SdpBandwidthType type, unsigned int bandwidth) { addBandwidth(Sdp::SdpBandwidth(type, bandwidth)); } + void addBandwidth(const Sdp::SdpBandwidth& sdpBandwidth) { mBandwidths.push_back(sdpBandwidth); } + void clearBandwidths() { mBandwidths.clear(); } + + void setEncryptionKey(SdpEncryptionMethod method, const char * key) { mEncryptionMethod = method; mEncryptionKey = key; } + void setDirection(SdpDirectionType direction) { mDirection = direction; } + void setPacketTime(unsigned int packetTime) { mPacketTime = packetTime; } + void setMaxPacketTime(unsigned int maxPacketTime) { mMaxPacketTime = maxPacketTime; } + void setOrientation(SdpOrientationType orientation) { mOrientation = orientation; } + void setDescriptionLanguage(const char * descriptionLanguage) { mDescriptionLanguage = descriptionLanguage; } + void setLanguage(const char * language) { mLanguage = language; } + void setFrameRate(unsigned int frameRate) { mFrameRate = frameRate; } + void setQuality(unsigned int quality) { mQuality = quality; } + + void setTcpSetupAttribute(SdpTcpSetupAttribute tcpSetupAttribute) { mTcpSetupAttribute = tcpSetupAttribute; } + void setTcpConnectionAttribute(SdpTcpConnectionAttribute tcpConnectionAttribute) { mTcpConnectionAttribute = tcpConnectionAttribute; } + +// void addCryptoSettings(unsigned int tag, SdpCryptoSuiteType suite, SdpCryptoKeyMethod keyMethod, const char * keyValue) { addCryptoSettings(new SdpCrypto(tag, suite, keyMethod, keyValue)); } + void addCryptoSettings(const SdpCrypto& crypto) { mCryptos.push_back(crypto); } + void clearCryptoSettings() { mCryptos.clear(); } + + void setFingerPrint(SdpFingerPrintHashFuncType fingerPrintHashFunction, const char * fingerPrint) { mFingerPrintHashFunction = fingerPrintHashFunction; mFingerPrint = fingerPrint; } + void setKeyManagementProtocol(SdpKeyManagementProtocolType protocol, const char* data) { mKeyManagementProtocol = protocol; mKeyManagementData = data; } + + void addPreConditionCurrentStatus(SdpPreConditionType type, SdpPreConditionStatusType status, SdpPreConditionDirectionType direction) + { addPreConditionCurrentStatus(SdpPreCondition(type, status, direction)); } + void addPreConditionCurrentStatus(const SdpPreCondition& preCondition) { mPreConditionCurrentStatus.push_back(preCondition); } + void clearPreConditionCurrentStatus() { mPreConditionCurrentStatus.clear(); } + + void addPreConditionConfirmStatus(SdpPreConditionType type, SdpPreConditionStatusType status, SdpPreConditionDirectionType direction) + { addPreConditionConfirmStatus(SdpPreCondition(type, status, direction)); } + void addPreConditionConfirmStatus(const SdpPreCondition& preCondition) { mPreConditionConfirmStatus.push_back(preCondition); } + void clearPreConditionConfirmStatus() { mPreConditionConfirmStatus.clear(); } + + void addPreConditionDesiredStatus(SdpPreConditionType type, SdpPreConditionStrengthType strength, SdpPreConditionStatusType status, SdpPreConditionDirectionType direction) + { addPreConditionDesiredStatus(SdpPreConditionDesiredStatus(type, strength, status, direction)); } + void addPreConditionDesiredStatus(const SdpPreConditionDesiredStatus& preConditionDesiredStatus) { mPreConditionDesiredStatus.push_back(preConditionDesiredStatus); } + void clearPreConditionDesiredStatus() { mPreConditionDesiredStatus.clear(); } + + void setMaximumPacketRate(double maximumPacketRate) { mMaximumPacketRate = maximumPacketRate; } + void setLabel(const char * label) { mLabel = label; } + void setIdentificationTag(const char * identificationTag) { mIdentificationTag = identificationTag; } + + void setIceUserFrag(const char * iceUserFrag) { mIceUserFrag = iceUserFrag; } + void setIcePassword(const char * icePassword) { mIcePassword = icePassword; } + + void addRemoteCandidate(unsigned int componentId, const char * connectionAddress, unsigned int port) { addRemoteCandidate(SdpRemoteCandidate(componentId, connectionAddress, port)); } + void addRemoteCandidate(const SdpRemoteCandidate& remoteCandidate) { mRemoteCandidates.push_back(remoteCandidate); } + void clearRemoteCandidates() { mRemoteCandidates.clear(); } + + // Note: Candidates should be added after m/c line and rtcp information is set, so that the in-use candidate + // can be properly tagged and CandidatePresents flag can be properly set + void addCandidate(SdpCandidate& candidate); + void addCandidate(const char * foundation, unsigned int id, SdpCandidate::SdpCandidateTransportType transport, + UInt64 priority, const char * connectionAddress, unsigned int port, + SdpCandidate::SdpCandidateType candidateType, const char * relatedAddress = 0, + unsigned int relatedPort = 0); + void clearCandidates() { mCandidates.clear(); mRtpCandidatePresent = false; mRtcpCandidatePresent = false; } + + void addCandidatePair(const SdpCandidate& localCandidate, const SdpCandidate& remoteCandidate, SdpCandidatePair::SdpCandidatePairOffererType offerer) + { addCandidatePair(SdpCandidatePair(localCandidate, remoteCandidate, offerer)); } + void addCandidatePair(const SdpCandidatePair& sdpCandidatePair) { mCandidatePairs.insert(sdpCandidatePair); } + void clearCandidatePairs() { mCandidatePairs.clear(); } + + void addPotentialMediaView(const SdpMediaLine& potentialMediaView) { mPotentialMediaViews.push_back(potentialMediaView); } + void clearPotentialMediaViews() { mPotentialMediaViews.clear(); } + + void setPotentialMediaViewString(const char *potentialMediaViewString) { mPotentialMediaViewString = potentialMediaViewString; } + + void toString(resip::Data& sdpMediaLineString) const; + + typedef std::list<SdpCodec> CodecList; + typedef std::list<SdpConnection> ConnectionList; + typedef std::list<SdpCrypto> CryptoList; + typedef std::list<SdpPreCondition> SdpPreConditionList; + typedef std::list<SdpPreConditionDesiredStatus> SdpPreConditionDesiredStatusList; + typedef std::list<SdpRemoteCandidate> SdpRemoteCandidateList; + typedef std::set<SdpCandidate> SdpCandidateList; + typedef std::set<SdpCandidatePair> SdpCandidatePairList; + typedef std::list<SdpMediaLine> SdpMediaLineList; + + const SdpMediaType getMediaType() const { return mMediaType; } + const resip::Data& getMediaTypeString() const { return mMediaTypeString; } + static SdpMediaType getMediaTypeFromString(const char * type); + const SdpTransportProtocolType getTransportProtocolType() const { return mTransportProtocolType; } + const resip::Data& getTransportProtocolTypeString() const { return mTransportProtocolTypeString; } + static SdpTransportProtocolType getTransportProtocolTypeFromString(const char * type); + const CodecList& getCodecs() const { return mCodecs; } + const resip::Data& getTitle() const { return mTitle; } + const ConnectionList& getConnections() const { return mConnections; } + const ConnectionList& getRtcpConnections() const { return mRtcpConnections; } + const Sdp::BandwidthList& getBandwidths() const { return mBandwidths; } + SdpEncryptionMethod getEncryptionMethod() const { return mEncryptionMethod; } + const resip::Data& getEncryptionKey() const { return mEncryptionKey; } + SdpDirectionType getDirection() const { return mDirection; } + unsigned int getPacketTime() const { return mPacketTime; } + unsigned int getMaxPacketTime() const { return mMaxPacketTime; } + SdpOrientationType getOrientation() const { return mOrientation; } + static SdpOrientationType getOrientationTypeFromString(const char * type); + const resip::Data& getDescriptionLanguage() const { return mDescriptionLanguage; } + const resip::Data& getLanguage() const { return mLanguage; } + unsigned int getFrameRate() const { return mFrameRate; } + unsigned int getQuality() const { return mQuality; } + SdpTcpSetupAttribute getTcpSetupAttribute() const { return mTcpSetupAttribute; } + static SdpTcpSetupAttribute getTcpSetupAttributeFromString(const char * attrib); + SdpTcpConnectionAttribute getTcpConnectionAttribute() const { return mTcpConnectionAttribute; } + static SdpTcpConnectionAttribute getTcpConnectionAttributeFromString(const char * attrib); + const CryptoList& getCryptos() const { return mCryptos; } + static SdpCryptoSuiteType getCryptoSuiteTypeFromString(const char * type); + static SdpCryptoKeyMethod getCryptoKeyMethodFromString(const char * type); + SdpFingerPrintHashFuncType getFingerPrintHashFunction() const { return mFingerPrintHashFunction; } + static SdpFingerPrintHashFuncType getFingerPrintHashFuncTypeFromString(const char * type); + const resip::Data& getFingerPrint() const { return mFingerPrint; } + SdpKeyManagementProtocolType getKeyManagementProtocol() const { return mKeyManagementProtocol; } + static SdpKeyManagementProtocolType getKeyManagementProtocolTypeFromString(const char * type); + const resip::Data& getKeyManagementData() const { return mKeyManagementData; } + const SdpPreConditionList& getPreConditionCurrentStatus() const { return mPreConditionCurrentStatus; } + const SdpPreConditionList& getPreConditionConfirmStatus() const { return mPreConditionConfirmStatus; } + const SdpPreConditionDesiredStatusList& getPreConditionDesiredStatus() const { return mPreConditionDesiredStatus; } + static SdpPreConditionType getPreConditionTypeFromString(const char * type); + static SdpPreConditionStatusType getPreConditionStatusTypeFromString(const char * type); + static SdpPreConditionDirectionType getPreConditionDirectionTypeFromString(const char * type); + static SdpPreConditionStrengthType getPreConditionStrengthTypeFromString(const char * type); + double getMaximumPacketRate() const { return mMaximumPacketRate; } + const resip::Data& getLabel() const { return mLabel; } + const resip::Data& getIdentificationTag() const { return mIdentificationTag; } + const resip::Data& getIceUserFrag() const { return mIceUserFrag; } + const resip::Data& getIcePassword() const { return mIcePassword; } + const SdpRemoteCandidateList& getRemoteCandidates() const { return mRemoteCandidates; } + const SdpCandidateList& getCandidates() const { return mCandidates; } + + const bool isRtcpEnabled() const { return mRtcpConnections.size() > 0; } + const bool isRtpCandidatePresent() const { return mRtpCandidatePresent; } + const bool isRtcpCandidatePresent() const { return mRtcpCandidatePresent; } + const bool isIceSupported() const { return mRtpCandidatePresent && (!isRtcpEnabled() || mRtcpCandidatePresent); } + + // TODO: In g++ std::set members are const and cannot be modified, need to update to a new STL type + const SdpCandidatePairList& getCandidatePairs() const { return mCandidatePairs; } + SdpCandidatePairList& getCandidatePairs() { return mCandidatePairs; } // non-const version for manipulation + + const SdpMediaLineList& getPotentialMediaViews() const { return mPotentialMediaViews; } + const resip::Data& getPotentialMediaViewString() const { return mPotentialMediaViewString; } + +private: + // m= Note: port is stored in each connection + SdpMediaType mMediaType; + resip::Data mMediaTypeString; + SdpTransportProtocolType mTransportProtocolType; + resip::Data mTransportProtocolTypeString; + CodecList mCodecs; + + // i= + resip::Data mTitle; + + // c= + ConnectionList mConnections; // includes port from m- line + ConnectionList mRtcpConnections; // a=rtcp <port> [<nettype> <addrtype> <connection addr>] - RFC3605 + + // b= + Sdp::BandwidthList mBandwidths; + + // k= + SdpEncryptionMethod mEncryptionMethod; + resip::Data mEncryptionKey; + + // a= media level attributes (including defaults copied from session level attributes) + SdpDirectionType mDirection; // a=sendrecv, a=sendonly, a=recvonly, a=inactive - RFC4566 + unsigned int mPacketTime; // a=ptime:<packet time> in ms - RFC4566 + unsigned int mMaxPacketTime; // a=maxptime:<maximum packet time> in ms - RFC4566 + SdpOrientationType mOrientation; // a=orient:<orientation> - RFC4566 + resip::Data mDescriptionLanguage; // a=sdplang:<language tag> - RFC4566 + resip::Data mLanguage; // a=lang:<language tag> - RFC4566 + unsigned int mFrameRate; // a=framerate:<frame rate> in video frames/sec - RFC4566 + unsigned int mQuality; // a=quality:<quality> 0-10 for vidoe (0 is worst, 10 is best) - RFC4566 + + SdpTcpSetupAttribute mTcpSetupAttribute;// a=setup:<setup attribute> - RFC4145 + SdpTcpConnectionAttribute mTcpConnectionAttribute; // a=connection:<conn attribute> - RFC4145 + + CryptoList mCryptos; // a=crypto:<tag> <crypto-suite> <key method>:<keyvalud> [<session-params>] - RFC4568 + + SdpFingerPrintHashFuncType mFingerPrintHashFunction; // a=fingerprint:<hash func> <fingerprint> - RFC4572 + resip::Data mFingerPrint; + + SdpKeyManagementProtocolType mKeyManagementProtocol; // a=key-mgmt:<protocol id> <key mgmt data> - RFC4567 + resip::Data mKeyManagementData; + + SdpPreConditionList mPreConditionCurrentStatus; // a=curr:<pre cond type> <status type> <direction tag> - RFC3312 + SdpPreConditionList mPreConditionConfirmStatus; // a=conf:<pre cond type> <status type> <direction tag> - RFC3312 - are multiple allowed? + SdpPreConditionDesiredStatusList mPreConditionDesiredStatus; // a=des:<pre cond type> <strength tag> <status type> <direction tag> - RFC3312 + + double mMaximumPacketRate; // a=maxprate:<packetrate> in packets/s - RFC3890 + resip::Data mLabel; // a=label:<label> - RFC4574 + resip::Data mIdentificationTag; // a=mid:<id tag> - RFC3388 + + // Ice settings + resip::Data mIceUserFrag; // a=ice-ufrag:<ufrag> (min 4 characters) - draft-ietf-mmusic-ice-12 + resip::Data mIcePassword; // a=ice-pwd:<password> (min 22 characters) - draft-ietf-mmusic-ice-12 + SdpRemoteCandidateList mRemoteCandidates; // a=remote-candidates:<component id> <connection address> <port> ... - draft-ietf-mmusic-ice-12 + SdpCandidateList mCandidates; // a=candidate:<foundation> <component id> <transport> <qvalue> <connection address> + // <port> [<candidate type>] [<relay addr>] [<relay port>] + // [<ext attrib name> <ext attrib value>] - draft-ietf-mmusic-ice-12 + bool mRtpCandidatePresent; + bool mRtcpCandidatePresent; + SdpCandidatePairList mCandidatePairs; + + // SDP Capabilities Negotiation + SdpMediaLineList mPotentialMediaViews; // List of Potential Media Configurations + resip::Data mPotentialMediaViewString; // string that would be used in a=acfg attribute of an answer using this potential view + + friend EncodeStream& operator<<(EncodeStream& strm, const SdpMediaLine& ); +}; + +EncodeStream& operator<<(EncodeStream& strm, const SdpMediaLine& ); + +} // namespace + +#endif + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/test/Makefile.am b/src/libs/resiprocate/resip/recon/test/Makefile.am new file mode 100644 index 00000000..57dd8d6e --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/Makefile.am @@ -0,0 +1,58 @@ + +EXTRA_DIST = ca.pem +EXTRA_DIST += *.vcxproj *.vcxproj.filters +EXTRA_DIST += *.vcproj +EXTRA_DIST += testua_readme.txt + +LDADD = ../librecon.la +LDADD += $(LIBSSL_LIBADD) -lpthread + +TESTS = \ + testUA \ + sdpTests \ + unitTests + +check_PROGRAMS = \ + testUA \ + sdpTests \ + unitTests + +testUA_SOURCES = testUA.cxx +sdpTests_SOURCES = sdpTests.cxx +unitTests_SOURCES = unitTests.cxx + + + +#################################################################### +# +# Copyright (c) 2007-2008, Plantronics, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of Plantronics nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#################################################################### diff --git a/src/libs/resiprocate/resip/recon/test/ca.pem b/src/libs/resiprocate/resip/recon/test/ca.pem new file mode 100644 index 00000000..9629b437 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/ca.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIB7TCCAVYCCQCxKhAUH1ygCDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJB +VTEMMAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxDTALBgNVBAoTBGFzaW8w +HhcNMDUxMTAyMTk0ODU1WhcNMTUxMTAyMTk0ODU1WjA7MQswCQYDVQQGEwJBVTEM +MAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxDTALBgNVBAoTBGFzaW8wgZ8w +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMkNbM2RjFdm48Wy1nBA3+exfJL5fR6H +guRFu/7MKf6pQZGRqhzxIWYRoYQDx16BggHwqFVVls5hgoQF0fUqoHfE8MLGwr6m +T6rIYBrIAGnH8eMhfwMNy4I0emkoWI+grEXlw54IUSijh8LokLWorElyGuPmxhn3 +IgZkgGe8dCQTAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAdpHw+r3X4NwzKn9nQs3h +mQK2WeH6DVQ1r7fWqEq1Lq10qBdobbjDRE9jpezWdGMThbYtle6/8wHUJeq189PR +XwZWyRvnfcI+pqX832yNRh24Ujwuv3wlx3JOVByybCoJc05N1THaHo0Q7j//8HsX +VS/RFHuq3muy47cV9gbsCIw= +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,EC6C715D9BC7AFF2 + +bBOh4F/Ouq2cpaWYUqCvpVVTAkptsHCkUFZpjqruGMw1pQ6BY2eBzuHHNgOV+8BI +4Md8LcvD9oRmkigXp10I6ELkPpvTqK5S/9iJBlR/XgYjuj2PkdLiT2t4dWrJP9Rq +NdjybhKV0qqB/WiBKoSI/n0mYDxmrrHjmPAXi3BnivyQiUry42hs+Izxlkyt///D +bDzkW/LqiMDwxOu9mCsxdN/iiFgKsPQBxvLbdG3p1GyERrnB85DeewYGF9fzp1Nz +CXWQiPqEkf3arqgKBIjK+TDfmDluL7+nOyhSp0j9Rh1zba8ffmYZNXXLt0ludVdm +8zbwqjbX6u4BZ+pSpnURFBp9um0TlxhpJ5F3q5ZyUa7l4tTlw37V8UkFP8KmBbuc +PDnjbdlD5BtAbR/b/dDSAhU2y7aftcTsZCu22UOLQqWOm6jMk943ZfmG93rCeKNL +qa4OPXsICSNqKivF0Ovyw5U7ODsFj0UTD8/VY+JWLz/bmJdpsBCNlkfQHGtTahfq +QY4mG0K+cWmUiGvcWcU1pjI4e551dR05wNDmyfJMHHVzn2VnCrxKSKGEtJOMcyzi +E42zQkGlYWVJyqDFHfxCe+1GJLJvW2oYGUUY/++XDzvxITT6Lq3wb1MGisoaC1Q7 +523SXpzVIU+FLlWxewrSnZOyTe13lgNK4OVnuRqz/LQExjfwUXtgqQkRp6A8jTmC +6LWEaXQ6kC7QmwX0VQgtNi74ZMMrBsaxywaE+3oEibeJiXbVJCHDo3RufA9AJnpF +HUmTFTnoBr4f8AUxN0Eyb5Yg16pzOBI5o4EzjKzJ4D0= +-----END RSA PRIVATE KEY----- diff --git a/src/libs/resiprocate/resip/recon/test/playback_prompt.h b/src/libs/resiprocate/resip/recon/test/playback_prompt.h new file mode 100644 index 00000000..fa7976cc --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/playback_prompt.h @@ -0,0 +1,2015 @@ +// +// Copyright (C) 2004-2006 SIPfoundry Inc. +// Licensed by SIPfoundry under the LGPL license. +// +// Copyright (C) 2005-2006 SIPez LLC. +// Licensed to SIPfoundry under a Contributor Agreement. +// +// $$ +////////////////////////////////////////////////////////////////////////////// +#ifndef _playback_prompt_h_ +#define _playback_prompt_h_ +unsigned char playback_prompt[23978]= +{ + 0xD6,0xFF,0xD0,0xFF,0xD7,0xFF,0xCA,0xFF,0xD2,0xFF,0xE0,0xFF, + 0xC6,0xFF,0xCB,0xFF,0xD3,0xFF,0xD0,0xFF,0xD1,0xFF,0xCD,0xFF, + 0xD2,0xFF,0xD7,0xFF,0xD9,0xFF,0xD6,0xFF,0xCC,0xFF,0xCF,0xFF, + 0xD2,0xFF,0xD6,0xFF,0xD6,0xFF,0xD7,0xFF,0xD5,0xFF,0xD5,0xFF, + 0xD8,0xFF,0xE5,0xFF,0xD3,0xFF,0xE8,0xFF,0xDB,0xFF,0xDF,0xFF, + 0xDF,0xFF,0xE1,0xFF,0xE9,0xFF,0xE9,0xFF,0xEA,0xFF,0xE3,0xFF, + 0xF3,0xFF,0xF2,0xFF,0xF1,0xFF,0xF0,0xFF,0xF1,0xFF,0xF0,0xFF, + 0xE9,0xFF,0xF1,0xFF,0xFC,0xFF,0xED,0xFF,0xFF,0xFF,0xF2,0xFF, + 0xF7,0xFF,0xE6,0xFF,0xED,0xFF,0xEF,0xFF,0xE6,0xFF,0xEC,0xFF, + 0xF8,0xFF,0xED,0xFF,0xE8,0xFF,0xFC,0xFF,0xEE,0xFF,0xF4,0xFF, + 0xE0,0xFF,0xE8,0xFF,0xEB,0xFF,0xDF,0xFF,0xE9,0xFF,0xF4,0xFF, + 0xE9,0xFF,0xE1,0xFF,0xF1,0xFF,0xEB,0xFF,0xD8,0xFF,0xEC,0xFF, + 0xEF,0xFF,0xE2,0xFF,0xE2,0xFF,0xDF,0xFF,0xF0,0xFF,0xE0,0xFF, + 0xE4,0xFF,0xE0,0xFF,0xF5,0xFF,0xF6,0xFF,0xE9,0xFF,0xEE,0xFF, + 0xEC,0xFF,0xE4,0xFF,0xEA,0xFF,0xF5,0xFF,0xEE,0xFF,0xE6,0xFF, + 0xE9,0xFF,0xE7,0xFF,0xEA,0xFF,0xE3,0xFF,0xDD,0xFF,0xF1,0xFF, + 0xEA,0xFF,0xE7,0xFF,0xD0,0xFF,0xF2,0xFF,0xE6,0xFF,0xCB,0xFF, + 0xD9,0xFF,0xE8,0xFF,0xD8,0xFF,0xE9,0xFF,0xE3,0xFF,0xEB,0xFF, + 0xDF,0xFF,0xE2,0xFF,0xE7,0xFF,0xE2,0xFF,0xE9,0xFF,0xEA,0xFF, + 0xE5,0xFF,0xF1,0xFF,0xE0,0xFF,0xEC,0xFF,0xEC,0xFF,0xDE,0xFF, + 0xE5,0xFF,0xEE,0xFF,0xE5,0xFF,0xE7,0xFF,0xDA,0xFF,0xF4,0xFF, + 0xEF,0xFF,0xEF,0xFF,0xE9,0xFF,0xF3,0xFF,0xF0,0xFF,0xE9,0xFF, + 0xE8,0xFF,0xE7,0xFF,0xEA,0xFF,0xE6,0xFF,0xDF,0xFF,0xE7,0xFF, + 0xDF,0xFF,0xEB,0xFF,0xE9,0xFF,0xEC,0xFF,0xE1,0xFF,0xE4,0xFF, + 0xE6,0xFF,0xE3,0xFF,0xE5,0xFF,0xE2,0xFF,0xEB,0xFF,0xE0,0xFF, + 0xEF,0xFF,0xE3,0xFF,0xEA,0xFF,0xDC,0xFF,0xF5,0xFF,0xDF,0xFF, + 0xE6,0xFF,0xEF,0xFF,0xED,0xFF,0xE8,0xFF,0xED,0xFF,0xEE,0xFF, + 0xFB,0xFF,0x2D,0x00,0x05,0x00,0x9E,0xFF,0xDC,0xFF,0x0B,0x00, + 0xE9,0xFF,0xE1,0xFF,0x0B,0x00,0xEE,0xFF,0xE6,0xFF,0xF1,0xFF, + 0xFB,0xFF,0xED,0xFF,0x01,0x00,0xDD,0xFF,0xFE,0xFF,0xEE,0xFF, + 0x06,0x00,0xF4,0xFF,0xFA,0xFF,0xFD,0xFF,0xF8,0xFF,0xF6,0xFF, + 0xEC,0xFF,0xEA,0xFF,0x00,0x00,0xEE,0xFF,0xF8,0xFF,0xF0,0xFF, + 0xEC,0xFF,0xEF,0xFF,0xF0,0xFF,0xE7,0xFF,0xF0,0xFF,0xE4,0xFF, + 0xF3,0xFF,0xE7,0xFF,0xDE,0xFF,0xDE,0xFF,0xEE,0xFF,0xE6,0xFF, + 0xDC,0xFF,0xE9,0xFF,0xD9,0xFF,0xDC,0xFF,0xDD,0xFF,0xE8,0xFF, + 0xE1,0xFF,0xE1,0xFF,0xDA,0xFF,0xE3,0xFF,0xDB,0xFF,0xE1,0xFF, + 0xD5,0xFF,0xE0,0xFF,0xD5,0xFF,0xD8,0xFF,0xD5,0xFF,0xCF,0xFF, + 0xCB,0xFF,0xE0,0xFF,0xD5,0xFF,0xD1,0xFF,0xCD,0xFF,0xCE,0xFF, + 0xD2,0xFF,0xCB,0xFF,0xCA,0xFF,0xD3,0xFF,0xCA,0xFF,0xCF,0xFF, + 0xC8,0xFF,0xC5,0xFF,0xBE,0xFF,0xC6,0xFF,0xC0,0xFF,0xCD,0xFF, + 0xCB,0xFF,0xBB,0xFF,0xCF,0xFF,0xC0,0xFF,0xD2,0xFF,0xC8,0xFF, + 0xCC,0xFF,0xCB,0xFF,0xBC,0xFF,0xC6,0xFF,0xCB,0xFF,0xC8,0xFF, + 0xD4,0xFF,0xC0,0xFF,0xC8,0xFF,0xC7,0xFF,0xCE,0xFF,0xCF,0xFF, + 0xDA,0xFF,0xC9,0xFF,0xCE,0xFF,0xC8,0xFF,0xCD,0xFF,0xC9,0xFF, + 0xD3,0xFF,0xD1,0xFF,0xCC,0xFF,0xD9,0xFF,0xC6,0xFF,0xCE,0xFF, + 0xC7,0xFF,0xCC,0xFF,0xD0,0xFF,0xCC,0xFF,0xD1,0xFF,0xC7,0xFF, + 0xCC,0xFF,0xC5,0xFF,0xC7,0xFF,0xC9,0xFF,0xC6,0xFF,0xC9,0xFF, + 0xCC,0xFF,0xC3,0xFF,0xD4,0xFF,0xD4,0xFF,0xDB,0xFF,0xD8,0xFF, + 0xE3,0xFF,0xD3,0xFF,0xE2,0xFF,0xDE,0xFF,0xE3,0xFF,0xDB,0xFF, + 0xDE,0xFF,0xDC,0xFF,0xDD,0xFF,0xDC,0xFF,0xE3,0xFF,0xF1,0xFF, + 0xDB,0xFF,0xDC,0xFF,0xE6,0xFF,0xDF,0xFF,0xDF,0xFF,0xDD,0xFF, + 0xD8,0xFF,0xE4,0xFF,0xEC,0xFF,0xD9,0xFF,0xE3,0xFF,0xD5,0xFF, + 0xE7,0xFF,0xDD,0xFF,0xD8,0xFF,0xDB,0xFF,0xDB,0xFF,0xDF,0xFF, + 0xDE,0xFF,0xD4,0xFF,0xE1,0xFF,0xD7,0xFF,0xE3,0xFF,0xCD,0xFF, + 0xDD,0xFF,0xDC,0xFF,0xE4,0xFF,0xDD,0xFF,0xD5,0xFF,0xDE,0xFF, + 0xDF,0xFF,0xDF,0xFF,0xE7,0xFF,0xDA,0xFF,0xEE,0xFF,0xD6,0xFF, + 0xE1,0xFF,0xDE,0xFF,0xDA,0xFF,0xD8,0xFF,0xDD,0xFF,0xD3,0xFF, + 0xD4,0xFF,0xD7,0xFF,0xE0,0xFF,0xDB,0xFF,0xD8,0xFF,0xCA,0xFF, + 0xD2,0xFF,0xDF,0xFF,0xDD,0xFF,0xD3,0xFF,0xD6,0xFF,0xD7,0xFF, + 0xCD,0xFF,0xD5,0xFF,0xD0,0xFF,0xCB,0xFF,0xD8,0xFF,0xCF,0xFF, + 0xD5,0xFF,0xD2,0xFF,0xCF,0xFF,0xCC,0xFF,0xC6,0xFF,0xCE,0xFF, + 0xC4,0xFF,0xDF,0xFF,0xC9,0xFF,0xC8,0xFF,0xC8,0xFF,0xD7,0xFF, + 0xD5,0xFF,0xCC,0xFF,0xD2,0xFF,0xCF,0xFF,0xC9,0xFF,0xD3,0xFF, + 0xDE,0xFF,0xD8,0xFF,0xCE,0xFF,0xDA,0xFF,0xD8,0xFF,0xD2,0xFF, + 0xDD,0xFF,0xD8,0xFF,0xD7,0xFF,0xE1,0xFF,0xE0,0xFF,0xD6,0xFF, + 0xE0,0xFF,0xDF,0xFF,0xE2,0xFF,0xE7,0xFF,0xE8,0xFF,0xE4,0xFF, + 0xDC,0xFF,0xDA,0xFF,0xDF,0xFF,0xD7,0xFF,0xE7,0xFF,0xE0,0xFF, + 0xD9,0xFF,0xE1,0xFF,0xE3,0xFF,0xE0,0xFF,0xD7,0xFF,0xE3,0xFF, + 0xD0,0xFF,0xDB,0xFF,0xE2,0xFF,0xDA,0xFF,0xE9,0xFF,0xE2,0xFF, + 0xD1,0xFF,0xEB,0xFF,0xDE,0xFF,0xF4,0xFF,0xF2,0xFF,0xE6,0xFF, + 0xF4,0xFF,0xEA,0xFF,0xE7,0xFF,0xF8,0xFF,0xFD,0xFF,0xF4,0xFF, + 0xEE,0xFF,0x08,0x00,0xEB,0xFF,0x03,0x00,0xF4,0xFF,0xF6,0xFF, + 0xED,0xFF,0xFC,0xFF,0xF2,0xFF,0xF5,0xFF,0xEB,0xFF,0xF3,0xFF, + 0xF1,0xFF,0xFB,0xFF,0xEE,0xFF,0xFC,0xFF,0xF0,0xFF,0xE8,0xFF, + 0xF8,0xFF,0xE0,0xFF,0xE9,0xFF,0xF1,0xFF,0xE5,0xFF,0xF7,0xFF, + 0xF7,0xFF,0xF0,0xFF,0xE3,0xFF,0xF7,0xFF,0xEA,0xFF,0xF6,0xFF, + 0xEA,0xFF,0xF0,0xFF,0xDF,0xFF,0xE9,0xFF,0xF4,0xFF,0xE9,0xFF, + 0xE6,0xFF,0xE8,0xFF,0xDE,0xFF,0xDB,0xFF,0xDA,0xFF,0xF4,0xFF, + 0xE6,0xFF,0xE5,0xFF,0xD6,0xFF,0xD4,0xFF,0xED,0xFF,0xE9,0xFF, + 0xEA,0xFF,0xD7,0xFF,0xC4,0xFF,0xDF,0xFF,0xD3,0xFF,0x02,0x00, + 0xEB,0xFF,0xDC,0xFF,0xE0,0xFF,0xE8,0xFF,0xE0,0xFF,0xD4,0xFF, + 0xD2,0xFF,0xD2,0xFF,0xD7,0xFF,0xE5,0xFF,0xDF,0xFF,0xC9,0xFF, + 0xDD,0xFF,0xE1,0xFF,0xCA,0xFF,0xCC,0xFF,0xDD,0xFF,0xD4,0xFF, + 0xD6,0xFF,0xC9,0xFF,0xDD,0xFF,0xDA,0xFF,0xD7,0xFF,0xEA,0xFF, + 0xD8,0xFF,0xCD,0xFF,0xDC,0xFF,0xBF,0xFF,0xD3,0xFF,0xD9,0xFF, + 0xE1,0xFF,0xD8,0xFF,0xD7,0xFF,0xE9,0xFF,0xD8,0xFF,0xDB,0xFF, + 0xDD,0xFF,0xE8,0xFF,0xDF,0xFF,0xD2,0xFF,0xEF,0xFF,0xD7,0xFF, + 0xEF,0xFF,0xE6,0xFF,0xE2,0xFF,0xDF,0xFF,0xDC,0xFF,0xF3,0xFF, + 0xDC,0xFF,0xDD,0xFF,0xDB,0xFF,0xDB,0xFF,0xEB,0xFF,0xE6,0xFF, + 0xE0,0xFF,0xD8,0xFF,0xDC,0xFF,0xE2,0xFF,0xE8,0xFF,0xDD,0xFF, + 0xD5,0xFF,0xEA,0xFF,0xF3,0xFF,0xEA,0xFF,0xE9,0xFF,0xE9,0xFF, + 0xF0,0xFF,0xF3,0xFF,0xEA,0xFF,0xF5,0xFF,0xF9,0xFF,0xF7,0xFF, + 0xFC,0xFF,0xFF,0xFF,0x02,0x00,0xF8,0xFF,0x06,0x00,0xFC,0xFF, + 0xF2,0xFF,0x0C,0x00,0x05,0x00,0xFD,0xFF,0x03,0x00,0xFE,0xFF, + 0xFD,0xFF,0x09,0x00,0x0C,0x00,0xFB,0xFF,0xFF,0xFF,0x01,0x00, + 0x00,0x00,0x02,0x00,0xF7,0xFF,0xFB,0xFF,0x08,0x00,0xFB,0xFF, + 0xF5,0xFF,0xFF,0xFF,0x03,0x00,0xF4,0xFF,0x0D,0x00,0xFA,0xFF, + 0xEA,0xFF,0xFE,0xFF,0xF8,0xFF,0xF5,0xFF,0xF8,0xFF,0xF4,0xFF, + 0xFA,0xFF,0xF9,0xFF,0xF2,0xFF,0xEA,0xFF,0xF3,0xFF,0xF5,0xFF, + 0xEF,0xFF,0xEC,0xFF,0xEA,0xFF,0x22,0x00,0x23,0x01,0xB9,0xFF, + 0x29,0xFF,0x4C,0x00,0xEC,0x00,0x7A,0xFF,0x89,0xFF,0x38,0x00, + 0xFA,0xFF,0x6F,0xFF,0x13,0x00,0x38,0x00,0xBF,0xFF,0x87,0xFF, + 0x0B,0x00,0xFA,0xFF,0xBA,0xFF,0xF9,0xFF,0x04,0x00,0xCF,0xFF, + 0xA6,0xFF,0xFB,0xFF,0xFF,0xFF,0xE3,0xFF,0xD3,0xFF,0x02,0x00, + 0xCA,0xFF,0xC6,0xFF,0xEC,0xFF,0xEE,0xFF,0xD0,0xFF,0xCC,0xFF, + 0xC3,0xFF,0xC3,0xFF,0xD6,0xFF,0xD6,0xFF,0xCA,0xFF,0xAA,0xFF, + 0xB5,0xFF,0xC2,0xFF,0xB9,0xFF,0xBE,0xFF,0xB7,0xFF,0xCA,0xFF, + 0x99,0xFF,0xBC,0xFF,0xD6,0xFF,0xC3,0xFF,0xC3,0xFF,0xC3,0xFF, + 0xC5,0xFF,0xB4,0xFF,0xD6,0xFF,0xD6,0xFF,0xBD,0xFF,0xC4,0xFF, + 0xC4,0xFF,0xC1,0xFF,0xC2,0xFF,0xD3,0xFF,0xC4,0xFF,0xC8,0xFF, + 0xC7,0xFF,0xCF,0xFF,0xD2,0xFF,0xCD,0xFF,0xD2,0xFF,0xCC,0xFF, + 0xCA,0xFF,0xC5,0xFF,0xC8,0xFF,0xCD,0xFF,0xB7,0xFF,0xC5,0xFF, + 0xBC,0xFF,0xBE,0xFF,0xC4,0xFF,0xBB,0xFF,0xC8,0xFF,0xC0,0xFF, + 0xD4,0xFF,0xC6,0xFF,0xCA,0xFF,0xD1,0xFF,0xD1,0xFF,0xC3,0xFF, + 0xD8,0xFF,0xE3,0xFF,0xD9,0xFF,0xD4,0xFF,0xD1,0xFF,0xDC,0xFF, + 0xE1,0xFF,0xCD,0xFF,0xEE,0xFF,0xD7,0xFF,0xE2,0xFF,0xD3,0xFF, + 0xD3,0xFF,0xD0,0xFF,0xD4,0xFF,0xCE,0xFF,0xC0,0xFF,0xC4,0xFF, + 0xD7,0xFF,0xCF,0xFF,0xBD,0xFF,0xD4,0xFF,0xDA,0xFF,0xCB,0xFF, + 0xD7,0xFF,0xD0,0xFF,0xBB,0xFF,0xC7,0xFF,0xD5,0xFF,0xD5,0xFF, + 0xBF,0xFF,0xD1,0xFF,0xC3,0xFF,0xBE,0xFF,0xDD,0xFF,0xCC,0xFF, + 0xD0,0xFF,0xB7,0xFF,0xD5,0xFF,0xD5,0xFF,0xBB,0xFF,0xCC,0xFF, + 0xCF,0xFF,0xC6,0xFF,0xC6,0xFF,0xCA,0xFF,0xB9,0xFF,0xD2,0xFF, + 0xC4,0xFF,0xC7,0xFF,0xBD,0xFF,0xCF,0xFF,0xD2,0xFF,0xB7,0xFF, + 0xC5,0xFF,0xC4,0xFF,0xC2,0xFF,0xB1,0xFF,0xCC,0xFF,0xBF,0xFF, + 0xC6,0xFF,0xA8,0xFF,0xD9,0xFF,0xC3,0xFF,0xC6,0xFF,0xC2,0xFF, + 0xCD,0xFF,0xB7,0xFF,0xC1,0xFF,0xC3,0xFF,0xD0,0xFF,0xA2,0xFF, + 0xC4,0xFF,0xB4,0xFF,0xD0,0xFF,0xA4,0xFF,0xC5,0xFF,0xC6,0xFF, + 0xC5,0xFF,0xB5,0xFF,0xD6,0xFF,0xC0,0xFF,0xC8,0xFF,0xCF,0xFF, + 0xD2,0xFF,0xBF,0xFF,0xD2,0xFF,0xD1,0xFF,0xE1,0xFF,0xCE,0xFF, + 0xD1,0xFF,0xDE,0xFF,0xE6,0xFF,0xE0,0xFF,0xE1,0xFF,0xCC,0xFF, + 0xDF,0xFF,0xD4,0xFF,0xDD,0xFF,0xD7,0xFF,0xE3,0xFF,0xF1,0xFF, + 0xDB,0xFF,0xE6,0xFF,0xF4,0xFF,0xF5,0xFF,0xEA,0xFF,0xEE,0xFF, + 0xEB,0xFF,0xE7,0xFF,0xF1,0xFF,0xF9,0xFF,0xF1,0xFF,0xF7,0xFF, + 0xF7,0xFF,0xE7,0xFF,0xED,0xFF,0x00,0x00,0xDF,0xFF,0xE5,0xFF, + 0xFE,0xFF,0xFF,0xFF,0xE3,0xFF,0xF4,0xFF,0x02,0x00,0xDF,0xFF, + 0x01,0x00,0x0D,0x00,0xE9,0xFF,0xF3,0xFF,0x12,0x00,0xFA,0xFF, + 0xEC,0xFF,0xFD,0xFF,0x17,0x00,0xF7,0xFF,0xFA,0xFF,0x05,0x00, + 0xFD,0xFF,0x0B,0x00,0x06,0x00,0x02,0x00,0xF5,0xFF,0xF3,0xFF, + 0x09,0x00,0xF8,0xFF,0x0A,0x00,0x01,0x00,0x07,0x00,0x06,0x00, + 0xF1,0xFF,0x05,0x00,0x05,0x00,0xFA,0xFF,0xEF,0xFF,0xF1,0xFF, + 0xF5,0xFF,0xF5,0xFF,0xED,0xFF,0xFA,0xFF,0xE6,0xFF,0x05,0x00, + 0xE3,0xFF,0xE4,0xFF,0xF7,0xFF,0xF1,0xFF,0xEB,0xFF,0xFE,0xFF, + 0xD4,0xFF,0xEB,0xFF,0x03,0x00,0xEC,0xFF,0xDB,0xFF,0xF1,0xFF, + 0xF3,0xFF,0xE1,0xFF,0xE5,0xFF,0xEC,0xFF,0xE2,0xFF,0xE0,0xFF, + 0xE3,0xFF,0xD3,0xFF,0xD6,0xFF,0xE7,0xFF,0xED,0xFF,0xC8,0xFF, + 0xE6,0xFF,0xEF,0xFF,0xD1,0xFF,0xE5,0xFF,0xED,0xFF,0xD4,0xFF, + 0xEA,0xFF,0xE4,0xFF,0xE0,0xFF,0xD5,0xFF,0xEB,0xFF,0xCC,0xFF, + 0xE4,0xFF,0xDD,0xFF,0xCB,0xFF,0xC8,0xFF,0xDE,0xFF,0xBA,0xFF, + 0xC6,0xFF,0xD2,0xFF,0xC1,0xFF,0xC4,0xFF,0xCE,0xFF,0xC9,0xFF, + 0xD6,0xFF,0xCE,0xFF,0xCC,0xFF,0xD3,0xFF,0xDE,0xFF,0xCE,0xFF, + 0xD0,0xFF,0xE0,0xFF,0xD7,0xFF,0xD7,0xFF,0xD7,0xFF,0xDA,0xFF, + 0xDC,0xFF,0xD6,0xFF,0xCA,0xFF,0xD9,0xFF,0xDA,0xFF,0xCB,0xFF, + 0xCE,0xFF,0xD5,0xFF,0xDE,0xFF,0xBF,0xFF,0xD6,0xFF,0xDE,0xFF, + 0xE2,0xFF,0xD8,0xFF,0xD2,0xFF,0xDE,0xFF,0xD3,0xFF,0xD3,0xFF, + 0xD8,0xFF,0xD4,0xFF,0xE6,0xFF,0xD0,0xFF,0xCB,0xFF,0xD3,0xFF, + 0xDD,0xFF,0xD5,0xFF,0xEC,0xFF,0xD8,0xFF,0xD8,0xFF,0xD7,0xFF, + 0xF0,0xFF,0xDF,0xFF,0xE1,0xFF,0xDF,0xFF,0xE4,0xFF,0xE5,0xFF, + 0xF0,0xFF,0xF6,0xFF,0xFD,0xFF,0xEE,0xFF,0xF7,0xFF,0xFB,0xFF, + 0xEC,0xFF,0xED,0xFF,0x07,0x00,0xE7,0xFF,0x05,0x00,0xFD,0xFF, + 0x02,0x00,0xF0,0xFF,0x0E,0x00,0xF5,0xFF,0xF9,0xFF,0x05,0x00, + 0x0A,0x00,0xEC,0xFF,0xFC,0xFF,0x00,0x00,0xF4,0xFF,0xF6,0xFF, + 0x03,0x00,0xDD,0xFF,0x05,0x00,0xF0,0xFF,0xE9,0xFF,0xF2,0xFF, + 0x08,0x00,0xEB,0xFF,0xEF,0xFF,0xE7,0xFF,0xFA,0xFF,0xEA,0xFF, + 0x00,0x00,0xE7,0xFF,0xF6,0xFF,0xE6,0xFF,0xEA,0xFF,0xDF,0xFF, + 0x09,0x00,0xD9,0xFF,0xE9,0xFF,0xEB,0xFF,0xEB,0xFF,0xDE,0xFF, + 0xF0,0xFF,0xEC,0xFF,0xD6,0xFF,0xD9,0xFF,0xEC,0xFF,0xCA,0xFF, + 0xE6,0xFF,0xF0,0xFF,0xE9,0xFF,0xCE,0xFF,0xDC,0xFF,0xEA,0xFF, + 0xD9,0xFF,0xDA,0xFF,0xDA,0xFF,0xC4,0xFF,0xD1,0xFF,0xDD,0xFF, + 0xD8,0xFF,0xD0,0xFF,0xD6,0xFF,0xCF,0xFF,0xD1,0xFF,0xD0,0xFF, + 0xD6,0xFF,0xCC,0xFF,0xC0,0xFF,0xCD,0xFF,0xC0,0xFF,0xC4,0xFF, + 0xC7,0xFF,0xDE,0xFF,0xC4,0xFF,0xC8,0xFF,0xDA,0xFF,0xC1,0xFF, + 0xDA,0xFF,0xDC,0xFF,0xCC,0xFF,0xCC,0xFF,0xC8,0xFF,0xD3,0xFF, + 0xD5,0xFF,0xD3,0xFF,0xD4,0xFF,0xCD,0xFF,0xC6,0xFF,0xD3,0xFF, + 0xD4,0xFF,0xCE,0xFF,0xD6,0xFF,0xEB,0xFF,0xCE,0xFF,0xDC,0xFF, + 0xEB,0xFF,0xCC,0xFF,0xE1,0xFF,0xDF,0xFF,0xE2,0xFF,0xDB,0xFF, + 0xE0,0xFF,0xD2,0xFF,0xE8,0xFF,0xD9,0xFF,0xD9,0xFF,0xE2,0xFF, + 0xE2,0xFF,0xD7,0xFF,0xE4,0xFF,0xD4,0xFF,0xE0,0xFF,0xE3,0xFF, + 0xE9,0xFF,0xD8,0xFF,0xEB,0xFF,0xE6,0xFF,0xE8,0xFF,0xEF,0xFF, + 0xD8,0xFF,0xEC,0xFF,0xEF,0xFF,0xEC,0xFF,0xE6,0xFF,0xEC,0xFF, + 0xF2,0xFF,0xF1,0xFF,0xE9,0xFF,0xF4,0xFF,0xE6,0xFF,0xF6,0xFF, + 0xEC,0xFF,0xF4,0xFF,0xF2,0xFF,0xF8,0xFF,0xE2,0xFF,0xF3,0xFF, + 0xF3,0xFF,0xEB,0xFF,0xEB,0xFF,0xF7,0xFF,0xEE,0xFF,0xF5,0xFF, + 0xE7,0xFF,0xF1,0xFF,0xE6,0xFF,0xF4,0xFF,0xE0,0xFF,0xE9,0xFF, + 0xEB,0xFF,0xDB,0xFF,0xF1,0xFF,0xF3,0xFF,0xE4,0xFF,0xE8,0xFF, + 0xF6,0xFF,0xE2,0xFF,0xE0,0xFF,0xF8,0xFF,0xF3,0xFF,0xE6,0xFF, + 0xEC,0xFF,0xE3,0xFF,0xED,0xFF,0xE5,0xFF,0xF1,0xFF,0xDE,0xFF, + 0xF6,0xFF,0xE4,0xFF,0xDF,0xFF,0xE4,0xFF,0xDF,0xFF,0xE8,0xFF, + 0xD1,0xFF,0xE5,0xFF,0xE0,0xFF,0xD3,0xFF,0xE9,0xFF,0xDF,0xFF, + 0xE5,0xFF,0xD8,0xFF,0xE0,0xFF,0xE8,0xFF,0xDA,0xFF,0xD4,0xFF, + 0xCC,0xFF,0xD0,0xFF,0xE2,0xFF,0xCC,0xFF,0xDA,0xFF,0xCC,0xFF, + 0xC6,0xFF,0xD0,0xFF,0xCF,0xFF,0xD7,0xFF,0xCC,0xFF,0xCE,0xFF, + 0xCA,0xFF,0xCB,0xFF,0xD8,0xFF,0xCD,0xFF,0xD0,0xFF,0xBE,0xFF, + 0xD1,0xFF,0xBE,0xFF,0xCC,0xFF,0xD3,0xFF,0xC1,0xFF,0xC7,0xFF, + 0xD0,0xFF,0xBD,0xFF,0xD2,0xFF,0xD5,0xFF,0xD0,0xFF,0xC4,0xFF, + 0xDE,0xFF,0xCF,0xFF,0xD6,0xFF,0xDC,0xFF,0xCF,0xFF,0xCF,0xFF, + 0xDA,0xFF,0xD0,0xFF,0xE4,0xFF,0xCF,0xFF,0xC6,0xFF,0xEA,0xFF, + 0xDB,0xFF,0xD5,0xFF,0xE6,0xFF,0xDD,0xFF,0xD9,0xFF,0xDD,0xFF, + 0xD3,0xFF,0xD5,0xFF,0xCF,0xFF,0xDC,0xFF,0xD5,0xFF,0xD3,0xFF, + 0xD2,0xFF,0xCE,0xFF,0xDA,0xFF,0xDF,0xFF,0xCB,0xFF,0xDB,0xFF, + 0xD4,0xFF,0xDE,0xFF,0xD8,0xFF,0xDD,0xFF,0xCA,0xFF,0xE4,0xFF, + 0xE7,0xFF,0xF1,0xFF,0xDE,0xFF,0xEC,0xFF,0xE6,0xFF,0xF1,0xFF, + 0xF6,0xFF,0xDE,0xFF,0xE1,0xFF,0xEF,0xFF,0xF5,0xFF,0xEB,0xFF, + 0xF9,0xFF,0xEB,0xFF,0xE1,0xFF,0xF3,0xFF,0x03,0x00,0xEA,0xFF, + 0xF8,0xFF,0xEC,0xFF,0xE2,0xFF,0xF3,0xFF,0xF6,0xFF,0xE2,0xFF, + 0xDF,0xFF,0xFB,0xFF,0xF2,0xFF,0xE9,0xFF,0xEF,0xFF,0xEF,0xFF, + 0xE7,0xFF,0xF3,0xFF,0xF7,0xFF,0xEB,0xFF,0xEB,0xFF,0xF2,0xFF, + 0xDE,0xFF,0xEC,0xFF,0xD7,0xFF,0xFD,0xFF,0xD8,0xFF,0xDE,0xFF, + 0xE3,0xFF,0xDD,0xFF,0xE9,0xFF,0xF0,0xFF,0xE7,0xFF,0xD9,0xFF, + 0xDD,0xFF,0xE6,0xFF,0xE0,0xFF,0xEF,0xFF,0xE2,0xFF,0xCA,0xFF, + 0xE7,0xFF,0xDE,0xFF,0xDE,0xFF,0xD0,0xFF,0xE5,0xFF,0xE3,0xFF, + 0xCF,0xFF,0xE2,0xFF,0xDB,0xFF,0xD7,0xFF,0xD3,0xFF,0xDD,0xFF, + 0xCF,0xFF,0xDF,0xFF,0xC5,0xFF,0xD7,0xFF,0xE2,0xFF,0xCD,0xFF, + 0xCA,0xFF,0xE9,0xFF,0xD0,0xFF,0xC9,0xFF,0xE0,0xFF,0xD0,0xFF, + 0xD9,0xFF,0xD4,0xFF,0xCF,0xFF,0xBF,0xFF,0xCA,0xFF,0xC4,0xFF, + 0xD3,0xFF,0xBC,0xFF,0xD0,0xFF,0xC9,0xFF,0xDC,0xFF,0xCA,0xFF, + 0xE2,0xFF,0xC8,0xFF,0xDF,0xFF,0xD6,0xFF,0xD7,0xFF,0xD6,0xFF, + 0xD8,0xFF,0xCB,0xFF,0xD9,0xFF,0xE1,0xFF,0xDE,0xFF,0xCD,0xFF, + 0xD1,0xFF,0xE6,0xFF,0xD4,0xFF,0xE4,0xFF,0xD7,0xFF,0xDA,0xFF, + 0xD1,0xFF,0xDA,0xFF,0xCF,0xFF,0xD1,0xFF,0xDB,0xFF,0xE3,0xFF, + 0xE4,0xFF,0xDA,0xFF,0xDE,0xFF,0xE0,0xFF,0xE7,0xFF,0xDE,0xFF, + 0xE3,0xFF,0xE2,0xFF,0xE1,0xFF,0xE3,0xFF,0xE1,0xFF,0xE6,0xFF, + 0xDF,0xFF,0xE9,0xFF,0xEE,0xFF,0xFA,0xFF,0xF2,0xFF,0xF0,0xFF, + 0xE3,0xFF,0x06,0x00,0xF1,0xFF,0xEE,0xFF,0xF9,0xFF,0xDA,0xFF, + 0xEE,0xFF,0xFC,0xFF,0xF2,0xFF,0xF4,0xFF,0xF9,0xFF,0xEB,0xFF, + 0xFB,0xFF,0xF8,0xFF,0xF9,0xFF,0xF8,0xFF,0xF2,0xFF,0xF7,0xFF, + 0xF1,0xFF,0xF8,0xFF,0xF0,0xFF,0xE5,0xFF,0xF2,0xFF,0xFD,0xFF, + 0xEF,0xFF,0xEC,0xFF,0xE8,0xFF,0xEA,0xFF,0xF6,0xFF,0x04,0x00, + 0xD8,0xFF,0xF5,0xFF,0xEA,0xFF,0xE5,0xFF,0xE5,0xFF,0xF1,0xFF, + 0xDE,0xFF,0xDE,0xFF,0xF1,0xFF,0xD4,0xFF,0xED,0xFF,0xE2,0xFF, + 0xE2,0xFF,0xF1,0xFF,0xE1,0xFF,0xE3,0xFF,0xDE,0xFF,0xC7,0xFF, + 0xE5,0xFF,0xE4,0xFF,0xD9,0xFF,0xE0,0xFF,0xD6,0xFF,0xD5,0xFF, + 0xCB,0xFF,0xDF,0xFF,0xDD,0xFF,0xD9,0xFF,0xC8,0xFF,0xE6,0xFF, + 0xD7,0xFF,0xCC,0xFF,0xD2,0xFF,0xD7,0xFF,0xE2,0xFF,0xCA,0xFF, + 0xC6,0xFF,0xCF,0xFF,0xD3,0xFF,0xCB,0xFF,0xD0,0xFF,0xCB,0xFF, + 0xCE,0xFF,0xC5,0xFF,0xCE,0xFF,0xBE,0xFF,0xCB,0xFF,0xB7,0xFF, + 0xBF,0xFF,0xCB,0xFF,0xBB,0xFF,0xC6,0xFF,0xCA,0xFF,0xB7,0xFF, + 0xC2,0xFF,0xCD,0xFF,0xC2,0xFF,0xB9,0xFF,0xBB,0xFF,0xC6,0xFF, + 0xC0,0xFF,0xD0,0xFF,0xC4,0xFF,0xBE,0xFF,0xC6,0xFF,0xC3,0xFF, + 0xC1,0xFF,0xD3,0xFF,0xCC,0xFF,0xBD,0xFF,0xCC,0xFF,0xCE,0xFF, + 0xC9,0xFF,0xC9,0xFF,0xD3,0xFF,0xC3,0xFF,0xDB,0xFF,0xCD,0xFF, + 0xC6,0xFF,0xDC,0xFF,0xD4,0xFF,0xC4,0xFF,0xCB,0xFF,0xDA,0xFF, + 0xBF,0xFF,0xD3,0xFF,0xCC,0xFF,0xC8,0xFF,0xD4,0xFF,0xD9,0xFF, + 0xC0,0xFF,0xD8,0xFF,0xD7,0xFF,0xD1,0xFF,0xDA,0xFF,0xE3,0xFF, + 0xC9,0xFF,0xEC,0xFF,0xEC,0xFF,0xBF,0xFF,0xE7,0xFF,0xE9,0xFF, + 0xF3,0xFF,0xD7,0xFF,0xF3,0xFF,0xF2,0xFF,0xEF,0xFF,0xF3,0xFF, + 0xEA,0xFF,0xE1,0xFF,0xEE,0xFF,0xF2,0xFF,0xDD,0xFF,0x03,0x00, + 0xED,0xFF,0xEE,0xFF,0xEE,0xFF,0xF7,0xFF,0xDD,0xFF,0xFD,0xFF, + 0xE4,0xFF,0xF9,0xFF,0xF0,0xFF,0xF0,0xFF,0xFB,0xFF,0xEE,0xFF, + 0xF1,0xFF,0xF5,0xFF,0xFE,0xFF,0xF3,0xFF,0xED,0xFF,0xF5,0xFF, + 0xF2,0xFF,0xF7,0xFF,0xF1,0xFF,0xF5,0xFF,0xF5,0xFF,0xF7,0xFF, + 0xE8,0xFF,0xED,0xFF,0xF3,0xFF,0xEC,0xFF,0xF3,0xFF,0xF2,0xFF, + 0xE4,0xFF,0xF1,0xFF,0xE1,0xFF,0xF5,0xFF,0xF4,0xFF,0xE6,0xFF, + 0xE6,0xFF,0xE6,0xFF,0xE5,0xFF,0xEF,0xFF,0xE4,0xFF,0xF3,0xFF, + 0xC8,0xFF,0xE4,0xFF,0xEE,0xFF,0xDD,0xFF,0xEB,0xFF,0xD4,0xFF, + 0xE2,0xFF,0xEA,0xFF,0xED,0xFF,0xD0,0xFF,0xF1,0xFF,0xE4,0xFF, + 0xD5,0xFF,0xE3,0xFF,0xE1,0xFF,0xE4,0xFF,0xD0,0xFF,0xDF,0xFF, + 0xDD,0xFF,0xC7,0xFF,0xD3,0xFF,0xDA,0xFF,0xCA,0xFF,0xDD,0xFF, + 0xD7,0xFF,0xC1,0xFF,0xDF,0xFF,0xCD,0xFF,0xCF,0xFF,0xD3,0xFF, + 0xD7,0xFF,0xD3,0xFF,0xDE,0xFF,0xE4,0xFF,0xDE,0xFF,0xD3,0xFF, + 0xE5,0xFF,0xE6,0xFF,0xD2,0xFF,0xE5,0xFF,0xDC,0xFF,0xD8,0xFF, + 0xE6,0xFF,0xDB,0xFF,0xCE,0xFF,0xE7,0xFF,0xD6,0xFF,0xDA,0xFF, + 0xEA,0xFF,0xE2,0xFF,0xD3,0xFF,0xE1,0xFF,0xEF,0xFF,0xEF,0xFF, + 0xEA,0xFF,0xE7,0xFF,0xE4,0xFF,0xD0,0xFF,0xF2,0xFF,0xE1,0xFF, + 0xD1,0xFF,0xE6,0xFF,0xE5,0xFF,0xD6,0xFF,0xE2,0xFF,0xE6,0xFF, + 0xE1,0xFF,0xE8,0xFF,0xF6,0xFF,0xFD,0xFF,0xEF,0xFF,0xEC,0xFF, + 0xEB,0xFF,0xEF,0xFF,0xF9,0xFF,0xEF,0xFF,0xF3,0xFF,0x03,0x00, + 0xEA,0xFF,0xFE,0xFF,0x09,0x00,0xF5,0xFF,0x12,0x00,0x08,0x00, + 0xF8,0xFF,0x02,0x00,0x0B,0x00,0x07,0x00,0x16,0x00,0x03,0x00, + 0xEF,0xFF,0x11,0x00,0x12,0x00,0xFF,0xFF,0x0E,0x00,0x01,0x00, + 0x04,0x00,0x0B,0x00,0x03,0x00,0xF7,0xFF,0x19,0x00,0x12,0x00, + 0xFF,0xFF,0x06,0x00,0x04,0x00,0x08,0x00,0x13,0x00,0xF5,0xFF, + 0xFF,0xFF,0x0B,0x00,0xF9,0xFF,0xEE,0xFF,0xF1,0xFF,0xE4,0xFF, + 0xF5,0xFF,0xF9,0xFF,0xE7,0xFF,0xF9,0xFF,0xF5,0xFF,0xE4,0xFF, + 0xFE,0xFF,0xF6,0xFF,0xEE,0xFF,0xF8,0xFF,0xF1,0xFF,0xEC,0xFF, + 0xF3,0xFF,0xF1,0xFF,0xEC,0xFF,0xE7,0xFF,0xEB,0xFF,0xEB,0xFF, + 0xF9,0xFF,0xE5,0xFF,0xEA,0xFF,0xE0,0xFF,0xE7,0xFF,0xE1,0xFF, + 0xE9,0xFF,0xE9,0xFF,0xD6,0xFF,0xDE,0xFF,0xEE,0xFF,0xE3,0xFF, + 0xDF,0xFF,0xEA,0xFF,0xD9,0xFF,0xE7,0xFF,0xDF,0xFF,0xF5,0xFF, + 0xE7,0xFF,0xE4,0xFF,0xE4,0xFF,0xE4,0xFF,0xDA,0xFF,0xE4,0xFF, + 0xE4,0xFF,0xCA,0xFF,0xD2,0xFF,0xCB,0xFF,0xDF,0xFF,0xD7,0xFF, + 0xD1,0xFF,0xE1,0xFF,0xCC,0xFF,0xD8,0xFF,0xD6,0xFF,0xDF,0xFF, + 0xC7,0xFF,0xD9,0xFF,0xD4,0xFF,0xDD,0xFF,0xD6,0xFF,0xE0,0xFF, + 0xCC,0xFF,0xD0,0xFF,0xCE,0xFF,0xDE,0xFF,0xD6,0xFF,0xEB,0xFF, + 0xD5,0xFF,0xD5,0xFF,0xEB,0xFF,0xE7,0xFF,0xCB,0xFF,0xDC,0xFF, + 0xDC,0xFF,0xC0,0xFF,0xDE,0xFF,0xE4,0xFF,0xD3,0xFF,0xEC,0xFF, + 0xDB,0xFF,0xDA,0xFF,0xE3,0xFF,0xD0,0xFF,0xC7,0xFF,0xED,0xFF, + 0xCE,0xFF,0xD3,0xFF,0xE5,0xFF,0xCA,0xFF,0xE0,0xFF,0xE1,0xFF, + 0xD8,0xFF,0xE6,0xFF,0xEE,0xFF,0xE2,0xFF,0xE7,0xFF,0xE7,0xFF, + 0xE8,0xFF,0xF4,0xFF,0xF5,0xFF,0xE6,0xFF,0xDE,0xFF,0xE7,0xFF, + 0xEE,0xFF,0xF6,0xFF,0xF1,0xFF,0xF1,0xFF,0xEA,0xFF,0xF2,0xFF, + 0xEE,0xFF,0xE7,0xFF,0xDF,0xFF,0xED,0xFF,0xEE,0xFF,0xED,0xFF, + 0xE5,0xFF,0xE6,0xFF,0xE6,0xFF,0xF4,0xFF,0xEA,0xFF,0xEB,0xFF, + 0xE2,0xFF,0xD4,0xFF,0xE1,0xFF,0xEB,0xFF,0xE7,0xFF,0xE1,0xFF, + 0xE2,0xFF,0xD2,0xFF,0xDF,0xFF,0xEA,0xFF,0xE5,0xFF,0xE2,0xFF, + 0xD6,0xFF,0xE2,0xFF,0xEC,0xFF,0xD8,0xFF,0xDD,0xFF,0xD9,0xFF, + 0xD1,0xFF,0xD8,0xFF,0xD5,0xFF,0xC5,0xFF,0xE0,0xFF,0xC9,0xFF, + 0xD2,0xFF,0xDC,0xFF,0xCC,0xFF,0xC0,0xFF,0xD6,0xFF,0xC6,0xFF, + 0xC1,0xFF,0xCE,0xFF,0xD4,0xFF,0xD1,0xFF,0xD0,0xFF,0xCC,0xFF, + 0xC9,0xFF,0xD9,0xFF,0xCB,0xFF,0xDE,0xFF,0xC6,0xFF,0xCB,0xFF, + 0xC9,0xFF,0xD2,0xFF,0xC5,0xFF,0xD3,0xFF,0xCE,0xFF,0xBF,0xFF, + 0xC5,0xFF,0xC6,0xFF,0xBF,0xFF,0xC2,0xFF,0xB5,0xFF,0xB9,0xFF, + 0xC0,0xFF,0xB8,0xFF,0xCB,0xFF,0xBC,0xFF,0xC2,0xFF,0xCD,0xFF, + 0xC1,0xFF,0xB7,0xFF,0xD3,0xFF,0xC4,0xFF,0xBD,0xFF,0xCE,0xFF, + 0xC9,0xFF,0xC8,0xFF,0xC7,0xFF,0xC4,0xFF,0xC1,0xFF,0xCB,0xFF, + 0xC4,0xFF,0xCE,0xFF,0xBE,0xFF,0xC8,0xFF,0xC9,0xFF,0xD0,0xFF, + 0xC8,0xFF,0xCF,0xFF,0xC6,0xFF,0xCF,0xFF,0xD2,0xFF,0xD0,0xFF, + 0xD3,0xFF,0xCD,0xFF,0xD8,0xFF,0xD9,0xFF,0xC9,0xFF,0xCB,0xFF, + 0xD0,0xFF,0xD2,0xFF,0xDE,0xFF,0xD7,0xFF,0xD2,0xFF,0xD3,0xFF, + 0xDA,0xFF,0xD7,0xFF,0xDF,0xFF,0xDA,0xFF,0xE1,0xFF,0xD4,0xFF, + 0xDE,0xFF,0xEB,0xFF,0xF0,0xFF,0xEC,0xFF,0xF6,0xFF,0xE6,0xFF, + 0xE8,0xFF,0xE5,0xFF,0xF0,0xFF,0xF8,0xFF,0xE2,0xFF,0xEF,0xFF, + 0xF3,0xFF,0xEC,0xFF,0xE9,0xFF,0xF5,0xFF,0xEC,0xFF,0xEC,0xFF, + 0xF5,0xFF,0xFA,0xFF,0xFB,0xFF,0xF1,0xFF,0xF8,0xFF,0xF3,0xFF, + 0xEA,0xFF,0xF6,0xFF,0xFE,0xFF,0xF3,0xFF,0xF1,0xFF,0xF4,0xFF, + 0xFC,0xFF,0xEB,0xFF,0xF0,0xFF,0xE7,0xFF,0xE5,0xFF,0xF1,0xFF, + 0xE5,0xFF,0xE2,0xFF,0xF1,0xFF,0xEA,0xFF,0xE6,0xFF,0xEF,0xFF, + 0xEC,0xFF,0xED,0xFF,0xEF,0xFF,0xE6,0xFF,0xDF,0xFF,0xFB,0xFF, + 0xDD,0xFF,0xD9,0xFF,0xF1,0xFF,0xCF,0xFF,0xDF,0xFF,0xE9,0xFF, + 0xE1,0xFF,0xD4,0xFF,0xD6,0xFF,0xD8,0xFF,0xDD,0xFF,0xD2,0xFF, + 0xD4,0xFF,0xD1,0xFF,0xCC,0xFF,0xD9,0xFF,0xD1,0xFF,0xDE,0xFF, + 0xDE,0xFF,0xD5,0xFF,0xDF,0xFF,0xE2,0xFF,0xD5,0xFF,0xCC,0xFF, + 0xCD,0xFF,0xDA,0xFF,0xDA,0xFF,0xC2,0xFF,0xC8,0xFF,0xCC,0xFF, + 0xCC,0xFF,0xD4,0xFF,0xC3,0xFF,0xC2,0xFF,0xD0,0xFF,0xC5,0xFF, + 0xCC,0xFF,0xCE,0xFF,0xC4,0xFF,0xD5,0xFF,0xD7,0xFF,0xDC,0xFF, + 0xDA,0xFF,0xD9,0xFF,0xDC,0xFF,0xDA,0xFF,0xD3,0xFF,0xE7,0xFF, + 0xD2,0xFF,0xC9,0xFF,0xD0,0xFF,0xDC,0xFF,0xDC,0xFF,0xDD,0xFF, + 0xD3,0xFF,0xD2,0xFF,0xE1,0xFF,0xDD,0xFF,0xDC,0xFF,0xDC,0xFF, + 0xD8,0xFF,0xD7,0xFF,0xE1,0xFF,0xDD,0xFF,0xE3,0xFF,0xE6,0xFF, + 0xE4,0xFF,0xE7,0xFF,0xE8,0xFF,0xE3,0xFF,0xE3,0xFF,0xE9,0xFF, + 0xED,0xFF,0xE5,0xFF,0xDD,0xFF,0xE2,0xFF,0xE4,0xFF,0xE6,0xFF, + 0xF7,0xFF,0xEC,0xFF,0xE2,0xFF,0xFD,0xFF,0xEB,0xFF,0xF1,0xFF, + 0xFD,0xFF,0xF0,0xFF,0xFD,0xFF,0x04,0x00,0xE7,0xFF,0x00,0x00, + 0xF7,0xFF,0xFC,0xFF,0xF3,0xFF,0xF8,0xFF,0xFE,0xFF,0xF8,0xFF, + 0xF8,0xFF,0xFB,0xFF,0xFC,0xFF,0xFC,0xFF,0xFE,0xFF,0xF5,0xFF, + 0xEE,0xFF,0xF1,0xFF,0xF8,0xFF,0xEC,0xFF,0xFA,0xFF,0xF1,0xFF, + 0xF6,0xFF,0xF5,0xFF,0xE9,0xFF,0xEB,0xFF,0xF2,0xFF,0xEE,0xFF, + 0xE7,0xFF,0xF2,0xFF,0xF0,0xFF,0xDC,0xFF,0xF3,0xFF,0xE3,0xFF, + 0xE0,0xFF,0xEA,0xFF,0xE0,0xFF,0xE5,0xFF,0xE6,0xFF,0xEE,0xFF, + 0xF7,0xFF,0xEA,0xFF,0xE7,0xFF,0xE6,0xFF,0xEE,0xFF,0xE5,0xFF, + 0xD4,0xFF,0xE1,0xFF,0xE8,0xFF,0xDC,0xFF,0xDD,0xFF,0xD2,0xFF, + 0xC6,0xFF,0xE2,0xFF,0xDF,0xFF,0xD3,0xFF,0xD7,0xFF,0xCA,0xFF, + 0xC8,0xFF,0xDA,0xFF,0xCD,0xFF,0xCC,0xFF,0xE3,0xFF,0xD6,0xFF, + 0xD9,0xFF,0xD9,0xFF,0xD7,0xFF,0xDA,0xFF,0xD8,0xFF,0xD8,0xFF, + 0xD1,0xFF,0xD0,0xFF,0xC9,0xFF,0xD2,0xFF,0xD3,0xFF,0xD0,0xFF, + 0xD3,0xFF,0xCD,0xFF,0xC7,0xFF,0xD0,0xFF,0xD9,0xFF,0xDB,0xFF, + 0xD0,0xFF,0xCB,0xFF,0xD4,0xFF,0xE2,0xFF,0xD4,0xFF,0xD4,0xFF, + 0xD0,0xFF,0xD0,0xFF,0xE4,0xFF,0xEC,0xFF,0xCB,0xFF,0xDF,0xFF, + 0xDB,0xFF,0xDC,0xFF,0xE0,0xFF,0xCC,0xFF,0xDC,0xFF,0xDA,0xFF, + 0xD7,0xFF,0xD0,0xFF,0xE3,0xFF,0xD5,0xFF,0xD6,0xFF,0xD9,0xFF, + 0xD1,0xFF,0xD5,0xFF,0xDB,0xFF,0xCF,0xFF,0xE2,0xFF,0xD4,0xFF, + 0xD3,0xFF,0xD0,0xFF,0xE6,0xFF,0xE1,0xFF,0xDB,0xFF,0xE4,0xFF, + 0xE1,0xFF,0xE6,0xFF,0xEB,0xFF,0xE0,0xFF,0xF0,0xFF,0xE5,0xFF, + 0xE7,0xFF,0xEF,0xFF,0xEE,0xFF,0xEB,0xFF,0xE1,0xFF,0xE3,0xFF, + 0xF7,0xFF,0xE9,0xFF,0xE5,0xFF,0xEE,0xFF,0xF5,0xFF,0xEA,0xFF, + 0xF8,0xFF,0xED,0xFF,0xED,0xFF,0xFC,0xFF,0xEF,0xFF,0xF5,0xFF, + 0xF5,0xFF,0xEB,0xFF,0xFA,0xFF,0xF6,0xFF,0xEF,0xFF,0xFE,0xFF, + 0xEE,0xFF,0xF5,0xFF,0xF4,0xFF,0xE0,0xFF,0xF0,0xFF,0xF8,0xFF, + 0xE0,0xFF,0xF1,0xFF,0xEB,0xFF,0xEB,0xFF,0xE4,0xFF,0xEE,0xFF, + 0xF6,0xFF,0xFD,0xFF,0xF0,0xFF,0xEF,0xFF,0xF9,0xFF,0xF0,0xFF, + 0xE8,0xFF,0xEB,0xFF,0xEA,0xFF,0xEC,0xFF,0xEB,0xFF,0xF3,0xFF, + 0xF2,0xFF,0xE0,0xFF,0xE3,0xFF,0xF5,0xFF,0xED,0xFF,0xE6,0xFF, + 0xE8,0xFF,0xDB,0xFF,0xE7,0xFF,0xED,0xFF,0xE0,0xFF,0xDB,0xFF, + 0xE9,0xFF,0xE8,0xFF,0xE8,0xFF,0xE5,0xFF,0xDD,0xFF,0xE0,0xFF, + 0xE5,0xFF,0xDF,0xFF,0xDE,0xFF,0xEF,0xFF,0xD9,0xFF,0xDF,0xFF, + 0xDA,0xFF,0xD7,0xFF,0xE5,0xFF,0xDA,0xFF,0xD6,0xFF,0xD1,0xFF, + 0xD0,0xFF,0xCF,0xFF,0xD6,0xFF,0xC6,0xFF,0xC5,0xFF,0xD6,0xFF, + 0xCC,0xFF,0xC1,0xFF,0xC8,0xFF,0xC7,0xFF,0xCB,0xFF,0xBE,0xFF, + 0xC3,0xFF,0xC7,0xFF,0xCE,0xFF,0xD1,0xFF,0xD3,0xFF,0xC5,0xFF, + 0xD0,0xFF,0xD0,0xFF,0xD4,0xFF,0xD4,0xFF,0xC9,0xFF,0xD0,0xFF, + 0xDA,0xFF,0xD1,0xFF,0xCB,0xFF,0xCC,0xFF,0xD8,0xFF,0xDC,0xFF, + 0xD5,0xFF,0xC2,0xFF,0xD1,0xFF,0xD5,0xFF,0xD0,0xFF,0xE5,0xFF, + 0xCC,0xFF,0xD1,0xFF,0xDB,0xFF,0xDC,0xFF,0xD4,0xFF,0xD6,0xFF, + 0xD2,0xFF,0xD9,0xFF,0xE2,0xFF,0xDA,0xFF,0xD2,0xFF,0xE5,0xFF, + 0xD5,0xFF,0xDD,0xFF,0xEB,0xFF,0xE0,0xFF,0xEE,0xFF,0xDB,0xFF, + 0xE7,0xFF,0xF4,0xFF,0xE5,0xFF,0xEF,0xFF,0xE7,0xFF,0xEB,0xFF, + 0xF4,0xFF,0xFA,0xFF,0xF3,0xFF,0xF6,0xFF,0xF2,0xFF,0xF9,0xFF, + 0xFC,0xFF,0xFE,0xFF,0x04,0x00,0xFD,0xFF,0x02,0x00,0x08,0x00, + 0xF8,0xFF,0xF6,0xFF,0x05,0x00,0xFE,0xFF,0x05,0x00,0x03,0x00, + 0xFD,0xFF,0xFD,0xFF,0xF9,0xFF,0xEE,0xFF,0x04,0x00,0xFF,0xFF, + 0xF2,0xFF,0x05,0x00,0xF5,0xFF,0xF2,0xFF,0xEA,0xFF,0x05,0x00, + 0xF6,0xFF,0xF7,0xFF,0xEA,0xFF,0xEC,0xFF,0xF1,0xFF,0xFA,0xFF, + 0xF2,0xFF,0xFA,0xFF,0xFB,0xFF,0xEF,0xFF,0xF6,0xFF,0xEC,0xFF, + 0xEC,0xFF,0xF2,0xFF,0xD5,0xFF,0x00,0x00,0xF8,0xFF,0xDD,0xFF, + 0xF2,0xFF,0xEC,0xFF,0xEC,0xFF,0xF7,0xFF,0xE7,0xFF,0xD9,0xFF, + 0xDE,0xFF,0xDF,0xFF,0xE6,0xFF,0xD4,0xFF,0xE6,0xFF,0xD1,0xFF, + 0xE2,0xFF,0xD7,0xFF,0xD0,0xFF,0xE2,0xFF,0xDC,0xFF,0xC7,0xFF, + 0xDD,0xFF,0xDC,0xFF,0xD8,0xFF,0xD5,0xFF,0xCA,0xFF,0xBD,0xFF, + 0xCC,0xFF,0xDC,0xFF,0xD6,0xFF,0xC4,0xFF,0xC8,0xFF,0xC8,0xFF, + 0xC9,0xFF,0xD5,0xFF,0xD4,0xFF,0xBD,0xFF,0xCB,0xFF,0xCC,0xFF, + 0xD3,0xFF,0xCF,0xFF,0xD1,0xFF,0xCA,0xFF,0xC4,0xFF,0xCC,0xFF, + 0xDA,0xFF,0xC5,0xFF,0xBF,0xFF,0xCC,0xFF,0xBE,0xFF,0xD9,0xFF, + 0xD8,0xFF,0xCA,0xFF,0xCB,0xFF,0xCB,0xFF,0xCF,0xFF,0xCF,0xFF, + 0xCB,0xFF,0xCF,0xFF,0xD0,0xFF,0xCF,0xFF,0xD1,0xFF,0xD4,0xFF, + 0xD4,0xFF,0xCC,0xFF,0xD2,0xFF,0xD5,0xFF,0xDB,0xFF,0xD8,0xFF, + 0xD0,0xFF,0xDB,0xFF,0xE3,0xFF,0xC4,0xFF,0xCD,0xFF,0xD2,0xFF, + 0xD5,0xFF,0xE4,0xFF,0xC5,0xFF,0xCD,0xFF,0xEC,0xFF,0xE6,0xFF, + 0xE7,0xFF,0xF8,0xFF,0xD6,0xFF,0xED,0xFF,0xEA,0xFF,0xEA,0xFF, + 0xE7,0xFF,0xE8,0xFF,0xEE,0xFF,0xE2,0xFF,0xE4,0xFF,0xEA,0xFF, + 0xE5,0xFF,0xED,0xFF,0xE5,0xFF,0xE2,0xFF,0xE1,0xFF,0xED,0xFF, + 0xEF,0xFF,0xE8,0xFF,0xE8,0xFF,0xE2,0xFF,0xDE,0xFF,0xE6,0xFF, + 0xEA,0xFF,0xDE,0xFF,0xE3,0xFF,0xE8,0xFF,0xE3,0xFF,0xE0,0xFF, + 0xE9,0xFF,0xEA,0xFF,0xE7,0xFF,0xE3,0xFF,0xE3,0xFF,0xEC,0xFF, + 0xE4,0xFF,0xDE,0xFF,0xD3,0xFF,0xEA,0xFF,0xDB,0xFF,0xCA,0xFF, + 0xD8,0xFF,0xDB,0xFF,0xCE,0xFF,0xD5,0xFF,0xD3,0xFF,0xDC,0xFF, + 0xE7,0xFF,0xD4,0xFF,0xE0,0xFF,0xD7,0xFF,0xD7,0xFF,0xD4,0xFF, + 0xD6,0xFF,0xD8,0xFF,0xD5,0xFF,0xE0,0xFF,0xD8,0xFF,0xCD,0xFF, + 0xDF,0xFF,0xD9,0xFF,0xD1,0xFF,0xCF,0xFF,0xD1,0xFF,0xD1,0xFF, + 0xD9,0xFF,0xD4,0xFF,0xD5,0xFF,0xD1,0xFF,0xD4,0xFF,0xCA,0xFF, + 0xCC,0xFF,0xC8,0xFF,0xC2,0xFF,0xBB,0xFF,0xBF,0xFF,0xC7,0xFF, + 0xC7,0xFF,0xCF,0xFF,0xC4,0xFF,0xBC,0xFF,0xCE,0xFF,0xC0,0xFF, + 0xD6,0xFF,0xC9,0xFF,0xBD,0xFF,0xC0,0xFF,0xBF,0xFF,0xC9,0xFF, + 0xD1,0xFF,0xC4,0xFF,0xCF,0xFF,0xC3,0xFF,0xBF,0xFF,0xD3,0xFF, + 0xCB,0xFF,0xCC,0xFF,0xD7,0xFF,0xCD,0xFF,0xBE,0xFF,0xDA,0xFF, + 0xCB,0xFF,0xD7,0xFF,0xD8,0xFF,0xB9,0xFF,0xCD,0xFF,0xD4,0xFF, + 0xCE,0xFF,0xD7,0xFF,0xC8,0xFF,0xD0,0xFF,0xD7,0xFF,0xCD,0xFF, + 0xD7,0xFF,0xD5,0xFF,0xCC,0xFF,0xCD,0xFF,0xCC,0xFF,0xD4,0xFF, + 0xD5,0xFF,0xCC,0xFF,0xD5,0xFF,0xD1,0xFF,0xC9,0xFF,0xE4,0xFF, + 0xD8,0xFF,0xDF,0xFF,0xD0,0xFF,0xE0,0xFF,0xF5,0xFF,0xEA,0xFF, + 0xEA,0xFF,0xE5,0xFF,0xE7,0xFF,0x01,0x00,0xF9,0xFF,0xEC,0xFF, + 0xEA,0xFF,0xE3,0xFF,0xF0,0xFF,0xFC,0xFF,0xF1,0xFF,0xDF,0xFF, + 0xE9,0xFF,0xF5,0xFF,0xF1,0xFF,0xF1,0xFF,0xEF,0xFF,0xEE,0xFF, + 0x03,0x00,0xEC,0xFF,0xEC,0xFF,0x00,0x00,0xF5,0xFF,0xF1,0xFF, + 0xEE,0xFF,0xEA,0xFF,0xE9,0xFF,0xEF,0xFF,0xE9,0xFF,0xE3,0xFF, + 0xE4,0xFF,0xE8,0xFF,0xE4,0xFF,0xDE,0xFF,0xDB,0xFF,0xE3,0xFF, + 0xE4,0xFF,0xDC,0xFF,0xEC,0xFF,0xEB,0xFF,0xE7,0xFF,0xE2,0xFF, + 0xE9,0xFF,0xE3,0xFF,0xE5,0xFF,0xE0,0xFF,0xE4,0xFF,0xE3,0xFF, + 0xE2,0xFF,0xE2,0xFF,0xD9,0xFF,0xE1,0xFF,0xD9,0xFF,0xE4,0xFF, + 0xDF,0xFF,0xDC,0xFF,0xE0,0xFF,0xE5,0xFF,0xD9,0xFF,0xE0,0xFF, + 0xE7,0xFF,0xE0,0xFF,0xE5,0xFF,0xD6,0xFF,0xD7,0xFF,0xE5,0xFF, + 0xD9,0xFF,0xD6,0xFF,0xD3,0xFF,0xCD,0xFF,0xD8,0xFF,0xCE,0xFF, + 0xCD,0xFF,0xCC,0xFF,0xC7,0xFF,0xC5,0xFF,0xC7,0xFF,0xC7,0xFF, + 0xC6,0xFF,0xCD,0xFF,0xC7,0xFF,0xCD,0xFF,0xC5,0xFF,0xCE,0xFF, + 0xC5,0xFF,0xD9,0xFF,0xCC,0xFF,0xC3,0xFF,0xD1,0xFF,0xC1,0xFF, + 0xBC,0xFF,0xD2,0xFF,0xD6,0xFF,0xD5,0xFF,0xCA,0xFF,0xC4,0xFF, + 0xC2,0xFF,0xC8,0xFF,0xD1,0xFF,0xD3,0xFF,0xC4,0xFF,0xDB,0xFF, + 0xD6,0xFF,0xE0,0xFF,0xD8,0xFF,0xDA,0xFF,0xD9,0xFF,0xDA,0xFF, + 0xD8,0xFF,0xD4,0xFF,0xD1,0xFF,0xD7,0xFF,0xD7,0xFF,0xD6,0xFF, + 0xD6,0xFF,0xD0,0xFF,0xCF,0xFF,0xD3,0xFF,0xDC,0xFF,0xD5,0xFF, + 0xDA,0xFF,0xDF,0xFF,0xDB,0xFF,0xDF,0xFF,0xD5,0xFF,0xDC,0xFF, + 0xE7,0xFF,0xDD,0xFF,0xE9,0xFF,0xD8,0xFF,0xD7,0xFF,0xE2,0xFF, + 0xDA,0xFF,0xF2,0xFF,0xE9,0xFF,0xE8,0xFF,0xEF,0xFF,0xEB,0xFF, + 0xFB,0xFF,0xF9,0xFF,0xF6,0xFF,0xEA,0xFF,0xF0,0xFF,0xF6,0xFF, + 0xF6,0xFF,0xF5,0xFF,0xF2,0xFF,0xFA,0xFF,0xFC,0xFF,0xED,0xFF, + 0xF1,0xFF,0xF3,0xFF,0xEF,0xFF,0xF9,0xFF,0xF2,0xFF,0xF4,0xFF, + 0xFD,0xFF,0xED,0xFF,0xE1,0xFF,0xEE,0xFF,0xFB,0xFF,0xF6,0xFF, + 0xF5,0xFF,0xEF,0xFF,0xE5,0xFF,0xF0,0xFF,0xEC,0xFF,0xED,0xFF, + 0xE7,0xFF,0xDC,0xFF,0xF2,0xFF,0xE8,0xFF,0xEB,0xFF,0xEA,0xFF, + 0xE7,0xFF,0xEC,0xFF,0xE8,0xFF,0xEC,0xFF,0xE9,0xFF,0xD9,0xFF, + 0xE0,0xFF,0xEB,0xFF,0xE2,0xFF,0xEA,0xFF,0xEA,0xFF,0xE1,0xFF, + 0xDC,0xFF,0xDB,0xFF,0xE9,0xFF,0xDE,0xFF,0xE1,0xFF,0xDB,0xFF, + 0xC9,0xFF,0xDE,0xFF,0xDE,0xFF,0xE0,0xFF,0xE3,0xFF,0xD9,0xFF, + 0xD3,0xFF,0xDF,0xFF,0xCD,0xFF,0xDF,0xFF,0xDD,0xFF,0xCD,0xFF, + 0xE4,0xFF,0xD1,0xFF,0xD1,0xFF,0xD8,0xFF,0xCF,0xFF,0xD4,0xFF, + 0xD9,0xFF,0xD9,0xFF,0xD8,0xFF,0xDC,0xFF,0xCD,0xFF,0xD0,0xFF, + 0xDC,0xFF,0xD8,0xFF,0xD7,0xFF,0xD6,0xFF,0xD2,0xFF,0xE2,0xFF, + 0xD5,0xFF,0xDD,0xFF,0xD4,0xFF,0xDB,0xFF,0xDC,0xFF,0xE2,0xFF, + 0xE6,0xFF,0xE3,0xFF,0xE5,0xFF,0xD6,0xFF,0xE9,0xFF,0xEB,0xFF, + 0xE4,0xFF,0xE2,0xFF,0xE6,0xFF,0xE9,0xFF,0xEA,0xFF,0xE9,0xFF, + 0xD9,0xFF,0xE6,0xFF,0xE1,0xFF,0xE8,0xFF,0xD8,0xFF,0xEC,0xFF, + 0xDA,0xFF,0xED,0xFF,0xEC,0xFF,0xEA,0xFF,0xE8,0xFF,0xE4,0xFF, + 0xE6,0xFF,0xE3,0xFF,0xDF,0xFF,0xEF,0xFF,0xDF,0xFF,0xE0,0xFF, + 0xE2,0xFF,0xE8,0xFF,0xF8,0xFF,0xF1,0xFF,0xE7,0xFF,0xF0,0xFF, + 0xE5,0xFF,0xFC,0xFF,0xF8,0xFF,0xEE,0xFF,0xE7,0xFF,0x00,0x00, + 0xFF,0xFF,0xF9,0xFF,0xF6,0xFF,0xE5,0xFF,0x02,0x00,0xFE,0xFF, + 0xEB,0xFF,0xF5,0xFF,0xF0,0xFF,0xE8,0xFF,0x00,0x00,0xF5,0xFF, + 0xF3,0xFF,0xF4,0xFF,0xEF,0xFF,0xF7,0xFF,0xF5,0xFF,0xF0,0xFF, + 0xFC,0xFF,0xFB,0xFF,0xF2,0xFF,0xF0,0xFF,0xFA,0xFF,0xFD,0xFF, + 0xF2,0xFF,0xF2,0xFF,0xE9,0xFF,0xE8,0xFF,0xF1,0xFF,0xE7,0xFF, + 0xE0,0xFF,0xE6,0xFF,0xE7,0xFF,0xEA,0xFF,0xEB,0xFF,0xEA,0xFF, + 0xE4,0xFF,0xE0,0xFF,0xE9,0xFF,0xE3,0xFF,0xE0,0xFF,0xED,0xFF, + 0xE2,0xFF,0xE3,0xFF,0xEE,0xFF,0xE7,0xFF,0xED,0xFF,0xE7,0xFF, + 0xD5,0xFF,0xDC,0xFF,0xD8,0xFF,0xD4,0xFF,0xDE,0xFF,0xD7,0xFF, + 0xD4,0xFF,0xD4,0xFF,0xD7,0xFF,0xD9,0xFF,0xD5,0xFF,0xD8,0xFF, + 0xDF,0xFF,0xDB,0xFF,0xD9,0xFF,0xD5,0xFF,0xD2,0xFF,0xC5,0xFF, + 0xD2,0xFF,0xCE,0xFF,0xD0,0xFF,0xCB,0xFF,0xCE,0xFF,0xCF,0xFF, + 0xBF,0xFF,0xD1,0xFF,0xC7,0xFF,0xD3,0xFF,0xCB,0xFF,0xD0,0xFF, + 0xCE,0xFF,0xCD,0xFF,0xD5,0xFF,0xD9,0xFF,0xC6,0xFF,0xD1,0xFF, + 0xDD,0xFF,0xD3,0xFF,0xE3,0xFF,0xD1,0xFF,0xDE,0xFF,0xD7,0xFF, + 0xD6,0xFF,0xDC,0xFF,0xCF,0xFF,0xD2,0xFF,0xDC,0xFF,0xD7,0xFF, + 0xDD,0xFF,0xCE,0xFF,0xCD,0xFF,0xDD,0xFF,0xD5,0xFF,0xD0,0xFF, + 0xD4,0xFF,0xCE,0xFF,0xD2,0xFF,0xD7,0xFF,0xD6,0xFF,0xD2,0xFF, + 0xDD,0xFF,0xCE,0xFF,0xD2,0xFF,0xD0,0xFF,0xC6,0xFF,0xCF,0xFF, + 0xD0,0xFF,0xCB,0xFF,0xD3,0xFF,0xD4,0xFF,0xD0,0xFF,0xD6,0xFF, + 0xDF,0xFF,0xED,0xFF,0xE3,0xFF,0xE4,0xFF,0xE5,0xFF,0xF2,0xFF, + 0xE7,0xFF,0xEE,0xFF,0xEC,0xFF,0xF0,0xFF,0xF3,0xFF,0xEC,0xFF, + 0xF2,0xFF,0xF7,0xFF,0xF1,0xFF,0xEC,0xFF,0xF4,0xFF,0xF0,0xFF, + 0xF1,0xFF,0xED,0xFF,0xE9,0xFF,0xF2,0xFF,0xEF,0xFF,0xFC,0xFF, + 0xF0,0xFF,0xEA,0xFF,0xF2,0xFF,0xEC,0xFF,0xED,0xFF,0xF0,0xFF, + 0xE9,0xFF,0xF7,0xFF,0xE8,0xFF,0xE7,0xFF,0xEB,0xFF,0xE8,0xFF, + 0xE5,0xFF,0xEE,0xFF,0xE2,0xFF,0xE3,0xFF,0xDB,0xFF,0xE1,0xFF, + 0xE5,0xFF,0xED,0xFF,0xE0,0xFF,0xE1,0xFF,0xE0,0xFF,0xE0,0xFF, + 0xDD,0xFF,0xED,0xFF,0xDA,0xFF,0xD5,0xFF,0xDC,0xFF,0xDC,0xFF, + 0xDE,0xFF,0xDA,0xFF,0xD1,0xFF,0xE5,0xFF,0xD3,0xFF,0xD1,0xFF, + 0xDF,0xFF,0xD4,0xFF,0xD4,0xFF,0xCD,0xFF,0xD0,0xFF,0xD4,0xFF, + 0xD8,0xFF,0xDD,0xFF,0xE3,0xFF,0xD7,0xFF,0xDC,0xFF,0xE3,0xFF, + 0xC1,0xFF,0xDD,0xFF,0xDF,0xFF,0xC6,0xFF,0xC7,0xFF,0xC7,0xFF, + 0xC8,0xFF,0xD8,0xFF,0xBE,0xFF,0xC6,0xFF,0xC4,0xFF,0xC4,0xFF, + 0xCD,0xFF,0xC2,0xFF,0xCA,0xFF,0xCA,0xFF,0xD0,0xFF,0xD0,0xFF, + 0xD6,0xFF,0xD5,0xFF,0xD7,0xFF,0xD5,0xFF,0xCB,0xFF,0xD8,0xFF, + 0xD1,0xFF,0xD1,0xFF,0xDC,0xFF,0xD5,0xFF,0xDB,0xFF,0xD1,0xFF, + 0xC7,0xFF,0xE0,0xFF,0xE3,0xFF,0xD7,0xFF,0xDB,0xFF,0xDC,0xFF, + 0xDA,0xFF,0xE1,0xFF,0xD9,0xFF,0xD1,0xFF,0xDF,0xFF,0xDB,0xFF, + 0xE3,0xFF,0xE4,0xFF,0xDB,0xFF,0xE3,0xFF,0xE7,0xFF,0xD3,0xFF, + 0xEB,0xFF,0xD3,0xFF,0xEC,0xFF,0xF7,0xFF,0xDF,0xFF,0xF3,0xFF, + 0xF1,0xFF,0xE1,0xFF,0xE9,0xFF,0xEA,0xFF,0xF2,0xFF,0xF0,0xFF, + 0xF4,0xFF,0xF1,0xFF,0xEA,0xFF,0xEC,0xFF,0xFB,0xFF,0x01,0x00, + 0xF0,0xFF,0xFD,0xFF,0xEC,0xFF,0xF8,0xFF,0xFA,0xFF,0xF4,0xFF, + 0xFA,0xFF,0xF8,0xFF,0xFC,0xFF,0x03,0x00,0xF9,0xFF,0xFC,0xFF, + 0xF6,0xFF,0x04,0x00,0x06,0x00,0x0A,0x00,0xF7,0xFF,0xF7,0xFF, + 0xEE,0xFF,0xF4,0xFF,0xF4,0xFF,0x09,0x00,0xF6,0xFF,0xEE,0xFF, + 0xF4,0xFF,0xDE,0xFF,0xEF,0xFF,0xF3,0xFF,0xDF,0xFF,0xF2,0xFF, + 0xEC,0xFF,0xD4,0xFF,0xEE,0xFF,0xF4,0xFF,0xDD,0xFF,0xEC,0xFF, + 0xEB,0xFF,0xF3,0xFF,0xF7,0xFF,0xE7,0xFF,0xE0,0xFF,0xE1,0xFF, + 0xE8,0xFF,0xEB,0xFF,0xE3,0xFF,0xDE,0xFF,0xDF,0xFF,0xE7,0xFF, + 0xE7,0xFF,0xE5,0xFF,0xDF,0xFF,0xEF,0xFF,0xE0,0xFF,0xEE,0xFF, + 0xE7,0xFF,0xE4,0xFF,0xD6,0xFF,0xE1,0xFF,0xD6,0xFF,0xD8,0xFF, + 0xDC,0xFF,0xDC,0xFF,0xE5,0xFF,0xCC,0xFF,0xD4,0xFF,0xCE,0xFF, + 0xDD,0xFF,0xD6,0xFF,0xC9,0xFF,0xCC,0xFF,0xC2,0xFF,0xC1,0xFF, + 0xCB,0xFF,0xBC,0xFF,0xC1,0xFF,0xD5,0xFF,0xCF,0xFF,0xD7,0xFF, + 0xCD,0xFF,0xD6,0xFF,0xD3,0xFF,0xDC,0xFF,0xE5,0xFF,0xDD,0xFF, + 0xD1,0xFF,0xCA,0xFF,0xCD,0xFF,0xD7,0xFF,0xCB,0xFF,0xCF,0xFF, + 0xD5,0xFF,0xCC,0xFF,0xCD,0xFF,0xD6,0xFF,0xD7,0xFF,0xD3,0xFF, + 0xCC,0xFF,0xC0,0xFF,0xD8,0xFF,0xCF,0xFF,0xCB,0xFF,0xDD,0xFF, + 0xC9,0xFF,0xCA,0xFF,0xD9,0xFF,0xC9,0xFF,0xDA,0xFF,0xCA,0xFF, + 0xD0,0xFF,0xD0,0xFF,0xD3,0xFF,0xDE,0xFF,0xD7,0xFF,0xD7,0xFF, + 0xDE,0xFF,0xD4,0xFF,0xD3,0xFF,0xCA,0xFF,0xCF,0xFF,0xE0,0xFF, + 0xDF,0xFF,0xD6,0xFF,0xDA,0xFF,0xE0,0xFF,0xCD,0xFF,0xE1,0xFF, + 0xDF,0xFF,0xD6,0xFF,0xE4,0xFF,0xDF,0xFF,0xE5,0xFF,0xE6,0xFF, + 0xD6,0xFF,0xE9,0xFF,0xE2,0xFF,0xDD,0xFF,0xDE,0xFF,0xEA,0xFF, + 0xED,0xFF,0xF3,0xFF,0xEE,0xFF,0xF5,0xFF,0xED,0xFF,0xF8,0xFF, + 0xFC,0xFF,0xED,0xFF,0xEF,0xFF,0xE6,0xFF,0xEE,0xFF,0xE4,0xFF, + 0xF1,0xFF,0xF1,0xFF,0xF0,0xFF,0xEA,0xFF,0xE9,0xFF,0xEB,0xFF, + 0xD9,0xFF,0xE6,0xFF,0xE1,0xFF,0xE7,0xFF,0xEA,0xFF,0xDA,0xFF, + 0xEA,0xFF,0xF5,0xFF,0xE7,0xFF,0xE8,0xFF,0xE4,0xFF,0xE5,0xFF, + 0xE1,0xFF,0xE9,0xFF,0xD4,0xFF,0xE9,0xFF,0xDA,0xFF,0xCD,0xFF, + 0xE1,0xFF,0xDC,0xFF,0xD9,0xFF,0xE2,0xFF,0xD6,0xFF,0xD8,0xFF, + 0xE3,0xFF,0xE0,0xFF,0xE6,0xFF,0xEB,0xFF,0xD7,0xFF,0xF5,0xFF, + 0xD8,0xFF,0xE6,0xFF,0xE2,0xFF,0xC8,0xFF,0xE3,0xFF,0xDB,0xFF, + 0xDE,0xFF,0xE0,0xFF,0xD8,0xFF,0xD8,0xFF,0xDA,0xFF,0xCE,0xFF, + 0xD2,0xFF,0xC7,0xFF,0xCE,0xFF,0xD6,0xFF,0xDB,0xFF,0xC6,0xFF, + 0xCE,0xFF,0xDB,0xFF,0xC1,0xFF,0xD6,0xFF,0xD4,0xFF,0xC2,0xFF, + 0xCB,0xFF,0xD3,0xFF,0xC8,0xFF,0xCD,0xFF,0xD1,0xFF,0xC0,0xFF, + 0xD4,0xFF,0xCD,0xFF,0xDA,0xFF,0xCE,0xFF,0xCA,0xFF,0xD8,0xFF, + 0xDE,0xFF,0xCD,0xFF,0xDA,0xFF,0xDC,0xFF,0xDE,0xFF,0xCE,0xFF, + 0xCF,0xFF,0xDC,0xFF,0xD1,0xFF,0xC9,0xFF,0xD2,0xFF,0xC1,0xFF, + 0xC8,0xFF,0xCD,0xFF,0xCD,0xFF,0xD2,0xFF,0xCE,0xFF,0xD6,0xFF, + 0xCB,0xFF,0xCD,0xFF,0xDE,0xFF,0xD4,0xFF,0xC4,0xFF,0xD5,0xFF, + 0xD7,0xFF,0xD1,0xFF,0xDD,0xFF,0xD5,0xFF,0xD9,0xFF,0xE3,0xFF, + 0xDC,0xFF,0xD8,0xFF,0xE8,0xFF,0xE6,0xFF,0xEB,0xFF,0xEB,0xFF, + 0xE6,0xFF,0xF6,0xFF,0xF6,0xFF,0xF8,0xFF,0xEF,0xFF,0xE0,0xFF, + 0xE9,0xFF,0x04,0x00,0xEB,0xFF,0xF9,0xFF,0xFB,0xFF,0xF5,0xFF, + 0xFE,0xFF,0xE6,0xFF,0xE1,0xFF,0x00,0x00,0xF0,0xFF,0xF5,0xFF, + 0xFB,0xFF,0xE6,0xFF,0xFC,0xFF,0x08,0x00,0xFA,0xFF,0xF7,0xFF, + 0xF6,0xFF,0x0A,0x00,0x07,0x00,0xF2,0xFF,0xEA,0xFF,0xFD,0xFF, + 0xEB,0xFF,0x02,0x00,0xE1,0xFF,0xF0,0xFF,0xED,0xFF,0xF0,0xFF, + 0xFA,0xFF,0xDA,0xFF,0xDF,0xFF,0xE4,0xFF,0xDD,0xFF,0xE6,0xFF, + 0xEF,0xFF,0xE0,0xFF,0xE5,0xFF,0xD7,0xFF,0xE8,0xFF,0xE1,0xFF, + 0xE4,0xFF,0xEA,0xFF,0xEF,0xFF,0xE2,0xFF,0xE2,0xFF,0xE4,0xFF, + 0xE1,0xFF,0xEB,0xFF,0xE1,0xFF,0xD4,0xFF,0xEC,0xFF,0xD9,0xFF, + 0xCF,0xFF,0xDC,0xFF,0xD8,0xFF,0xDD,0xFF,0xDE,0xFF,0xCD,0xFF, + 0xE4,0xFF,0xCF,0xFF,0xD0,0xFF,0xE1,0xFF,0xDB,0xFF,0xD1,0xFF, + 0xE0,0xFF,0xD7,0xFF,0xF3,0xFF,0xCE,0xFF,0xC5,0xFF,0xDC,0xFF, + 0xCD,0xFF,0xD3,0xFF,0xDE,0xFF,0xB6,0xFF,0xC7,0xFF,0xCD,0xFF, + 0xC5,0xFF,0xCA,0xFF,0xC0,0xFF,0xD1,0xFF,0xDF,0xFF,0xD5,0xFF, + 0xD8,0xFF,0xD6,0xFF,0xCD,0xFF,0xDD,0xFF,0xDF,0xFF,0xD2,0xFF, + 0xD4,0xFF,0xD1,0xFF,0xD1,0xFF,0xD2,0xFF,0xE3,0xFF,0xE2,0xFF, + 0xD6,0xFF,0xE5,0xFF,0xE1,0xFF,0xEA,0xFF,0xE4,0xFF,0xF3,0xFF, + 0xE2,0xFF,0xD9,0xFF,0xE6,0xFF,0xF7,0xFF,0xE1,0xFF,0xE8,0xFF, + 0xDE,0xFF,0xE1,0xFF,0xE4,0xFF,0xF1,0xFF,0xE9,0xFF,0xE0,0xFF, + 0xE8,0xFF,0xE8,0xFF,0xEF,0xFF,0xF8,0xFF,0xE4,0xFF,0xED,0xFF, + 0xF5,0xFF,0xE8,0xFF,0xEF,0xFF,0xF0,0xFF,0xF7,0xFF,0xF3,0xFF, + 0xF6,0xFF,0x05,0x00,0xF9,0xFF,0xF9,0xFF,0xFF,0xFF,0x00,0x00, + 0xFE,0xFF,0x01,0x00,0xFB,0xFF,0x01,0x00,0xFC,0xFF,0xFC,0xFF, + 0x04,0x00,0xF3,0xFF,0xF1,0xFF,0xF5,0xFF,0xF2,0xFF,0xF6,0xFF, + 0xFC,0xFF,0xEA,0xFF,0xFA,0xFF,0xF7,0xFF,0xF0,0xFF,0xF8,0xFF, + 0xEE,0xFF,0xF3,0xFF,0xF4,0xFF,0xED,0xFF,0xEB,0xFF,0xF5,0xFF, + 0xE7,0xFF,0xED,0xFF,0xEE,0xFF,0xE7,0xFF,0xE7,0xFF,0xE9,0xFF, + 0xE7,0xFF,0xED,0xFF,0xFA,0xFF,0xF9,0xFF,0x00,0x00,0xE5,0xFF, + 0xE1,0xFF,0xEA,0xFF,0xEA,0xFF,0xEC,0xFF,0xF0,0xFF,0xE3,0xFF, + 0xD0,0xFF,0xE3,0xFF,0xED,0xFF,0xDB,0xFF,0xE0,0xFF,0xDE,0xFF, + 0xDE,0xFF,0xE7,0xFF,0xD4,0xFF,0xD8,0xFF,0xCE,0xFF,0xD2,0xFF, + 0xD5,0xFF,0xDC,0xFF,0xE3,0xFF,0xE2,0xFF,0xDD,0xFF,0xCB,0xFF, + 0xDA,0xFF,0xE0,0xFF,0xDB,0xFF,0xCF,0xFF,0xC6,0xFF,0xD1,0xFF, + 0xD7,0xFF,0xD0,0xFF,0xD6,0xFF,0xCF,0xFF,0xCD,0xFF,0xD4,0xFF, + 0xCF,0xFF,0xD2,0xFF,0xD7,0xFF,0xD2,0xFF,0xD9,0xFF,0xDF,0xFF, + 0xDB,0xFF,0xD9,0xFF,0xD3,0xFF,0xCA,0xFF,0xCB,0xFF,0xD2,0xFF, + 0xDD,0xFF,0xD8,0xFF,0xD2,0xFF,0xD5,0xFF,0xD6,0xFF,0xDA,0xFF, + 0xE3,0xFF,0xDA,0xFF,0xDC,0xFF,0xD6,0xFF,0xD0,0xFF,0xD7,0xFF, + 0xDB,0xFF,0xDA,0xFF,0xDE,0xFF,0xD6,0xFF,0xD9,0xFF,0xDE,0xFF, + 0xE0,0xFF,0xDD,0xFF,0xCC,0xFF,0xC9,0xFF,0xD7,0xFF,0xDF,0xFF, + 0xD2,0xFF,0xEB,0xFF,0xD2,0xFF,0xDE,0xFF,0xD8,0xFF,0xC9,0xFF, + 0xD8,0xFF,0xDF,0xFF,0xDD,0xFF,0xE3,0xFF,0xDF,0xFF,0xE7,0xFF, + 0xE9,0xFF,0xE7,0xFF,0xEB,0xFF,0xE5,0xFF,0xFA,0xFF,0xE9,0xFF, + 0xED,0xFF,0xE9,0xFF,0xE6,0xFF,0xF9,0xFF,0xF5,0xFF,0xF6,0xFF, + 0xEE,0xFF,0xE9,0xFF,0xF5,0xFF,0xED,0xFF,0xF1,0xFF,0xEC,0xFF, + 0xE5,0xFF,0xE4,0xFF,0xF0,0xFF,0xEA,0xFF,0xE9,0xFF,0xEB,0xFF, + 0xE3,0xFF,0xEE,0xFF,0xE0,0xFF,0xDF,0xFF,0xDB,0xFF,0xE5,0xFF, + 0xE5,0xFF,0xE2,0xFF,0xDE,0xFF,0xD9,0xFF,0xD9,0xFF,0xEC,0xFF, + 0xE1,0xFF,0xD9,0xFF,0xD8,0xFF,0xE1,0xFF,0xE6,0xFF,0xEA,0xFF, + 0xE9,0xFF,0xE0,0xFF,0xDB,0xFF,0xD3,0xFF,0xD8,0xFF,0xD5,0xFF, + 0xD2,0xFF,0xDD,0xFF,0xD5,0xFF,0xDF,0xFF,0xE2,0xFF,0xD7,0xFF, + 0xD6,0xFF,0xD1,0xFF,0xD2,0xFF,0xDF,0xFF,0xD5,0xFF,0xD9,0xFF, + 0xD8,0xFF,0xD7,0xFF,0xE1,0xFF,0xDA,0xFF,0xD4,0xFF,0xD9,0xFF, + 0xD4,0xFF,0xC2,0xFF,0xD6,0xFF,0xCD,0xFF,0xD1,0xFF,0xCD,0xFF, + 0xCC,0xFF,0xC5,0xFF,0xC2,0xFF,0xD1,0xFF,0xD0,0xFF,0xC4,0xFF, + 0xCB,0xFF,0xCA,0xFF,0xCD,0xFF,0xCA,0xFF,0xC7,0xFF,0xC8,0xFF, + 0xD4,0xFF,0xCD,0xFF,0xD5,0xFF,0xD8,0xFF,0xD4,0xFF,0xC9,0xFF, + 0xD3,0xFF,0xCF,0xFF,0xCA,0xFF,0xCF,0xFF,0xCE,0xFF,0xC9,0xFF, + 0xD2,0xFF,0xDA,0xFF,0xD5,0xFF,0xD0,0xFF,0xC8,0xFF,0xD5,0xFF, + 0xD7,0xFF,0xDD,0xFF,0xDD,0xFF,0xCF,0xFF,0xCC,0xFF,0xCF,0xFF, + 0xD1,0xFF,0xCE,0xFF,0xD8,0xFF,0xD0,0xFF,0xD5,0xFF,0xCE,0xFF, + 0xDA,0xFF,0xD8,0xFF,0xDA,0xFF,0xD7,0xFF,0xD1,0xFF,0xDA,0xFF, + 0xD7,0xFF,0xDF,0xFF,0xE4,0xFF,0xD6,0xFF,0xD8,0xFF,0xDE,0xFF, + 0xDD,0xFF,0xE5,0xFF,0xDA,0xFF,0xD7,0xFF,0xEB,0xFF,0xE7,0xFF, + 0xE9,0xFF,0xE8,0xFF,0xDE,0xFF,0xE9,0xFF,0xE7,0xFF,0xE8,0xFF, + 0xE7,0xFF,0xEF,0xFF,0xEA,0xFF,0xF7,0xFF,0xFB,0xFF,0xF0,0xFF, + 0xF9,0xFF,0xFF,0xFF,0xFD,0xFF,0xF3,0xFF,0xF4,0xFF,0xF9,0xFF, + 0xF9,0xFF,0xFD,0xFF,0xFE,0xFF,0xF7,0xFF,0xFF,0xFF,0xF0,0xFF, + 0xF5,0xFF,0xFB,0xFF,0xF2,0xFF,0xF5,0xFF,0xED,0xFF,0xED,0xFF, + 0xF6,0xFF,0xF9,0xFF,0xFA,0xFF,0xF7,0xFF,0xF5,0xFF,0xF1,0xFF, + 0xFA,0xFF,0xF8,0xFF,0xED,0xFF,0xEF,0xFF,0xE8,0xFF,0xF0,0xFF, + 0xE9,0xFF,0xEA,0xFF,0xE4,0xFF,0xE4,0xFF,0xE6,0xFF,0xE3,0xFF, + 0xE9,0xFF,0xDF,0xFF,0xE0,0xFF,0xDF,0xFF,0xE2,0xFF,0xE6,0xFF, + 0xE4,0xFF,0xE9,0xFF,0xE3,0xFF,0xE1,0xFF,0xEC,0xFF,0xE6,0xFF, + 0xE6,0xFF,0xE5,0xFF,0xE2,0xFF,0xDD,0xFF,0xD9,0xFF,0xDD,0xFF, + 0xE5,0xFF,0xDF,0xFF,0xDC,0xFF,0xD8,0xFF,0xD2,0xFF,0xD9,0xFF, + 0xD2,0xFF,0xD4,0xFF,0xCC,0xFF,0xC8,0xFF,0xCD,0xFF,0xD6,0xFF, + 0xD8,0xFF,0xCB,0xFF,0xCD,0xFF,0xCC,0xFF,0xD9,0xFF,0xD4,0xFF, + 0xC5,0xFF,0xD4,0xFF,0xD0,0xFF,0xD4,0xFF,0xD0,0xFF,0xCD,0xFF, + 0xCB,0xFF,0xCE,0xFF,0xD0,0xFF,0xDC,0xFF,0xD5,0xFF,0xD9,0xFF, + 0xD5,0xFF,0xD8,0xFF,0xD4,0xFF,0xDB,0xFF,0xD4,0xFF,0xDC,0xFF, + 0xE0,0xFF,0xDC,0xFF,0xE0,0xFF,0xDF,0xFF,0xDE,0xFF,0xE1,0xFF, + 0xDC,0xFF,0xDB,0xFF,0xD9,0xFF,0xDE,0xFF,0xDD,0xFF,0xD7,0xFF, + 0xE0,0xFF,0xE1,0xFF,0xD5,0xFF,0xD8,0xFF,0xDB,0xFF,0xE3,0xFF, + 0xDF,0xFF,0xD9,0xFF,0xD5,0xFF,0xD4,0xFF,0xD3,0xFF,0xCE,0xFF, + 0xD4,0xFF,0xDA,0xFF,0xD5,0xFF,0xDF,0xFF,0xD8,0xFF,0xDB,0xFF, + 0xE2,0xFF,0xE0,0xFF,0xE6,0xFF,0xE5,0xFF,0xE0,0xFF,0xE1,0xFF, + 0xE8,0xFF,0xE0,0xFF,0xED,0xFF,0xEA,0xFF,0xEA,0xFF,0xE6,0xFF, + 0xE8,0xFF,0xE8,0xFF,0xE1,0xFF,0xE2,0xFF,0xE3,0xFF,0xE1,0xFF, + 0xE4,0xFF,0xDC,0xFF,0xDD,0xFF,0xDC,0xFF,0xDD,0xFF,0xD7,0xFF, + 0xDD,0xFF,0xDA,0xFF,0xE5,0xFF,0xE1,0xFF,0xE1,0xFF,0xDB,0xFF, + 0xE9,0xFF,0xE6,0xFF,0xE5,0xFF,0xE2,0xFF,0xDF,0xFF,0xDB,0xFF, + 0xE3,0xFF,0xE0,0xFF,0xD7,0xFF,0xD4,0xFF,0xD1,0xFF,0xD8,0xFF, + 0xDB,0xFF,0xD9,0xFF,0xD5,0xFF,0xD3,0xFF,0xD1,0xFF,0xDA,0xFF, + 0xD8,0xFF,0xDC,0xFF,0xD9,0xFF,0xD9,0xFF,0xD6,0xFF,0xDF,0xFF, + 0xD8,0xFF,0xD4,0xFF,0xD2,0xFF,0xD5,0xFF,0xD9,0xFF,0xDE,0xFF, + 0xDA,0xFF,0xDC,0xFF,0xCF,0xFF,0xD1,0xFF,0xD4,0xFF,0xD8,0xFF, + 0xD1,0xFF,0xD7,0xFF,0xD6,0xFF,0xD8,0xFF,0xD0,0xFF,0xD3,0xFF, + 0xD2,0xFF,0xD4,0xFF,0xCC,0xFF,0xD5,0xFF,0xD3,0xFF,0xD5,0xFF, + 0xD3,0xFF,0xDB,0xFF,0xD8,0xFF,0xD6,0xFF,0xCF,0xFF,0xD0,0xFF, + 0xD4,0xFF,0xDE,0xFF,0xD5,0xFF,0xD8,0xFF,0xD0,0xFF,0xD9,0xFF, + 0xDA,0xFF,0xDC,0xFF,0xE0,0xFF,0xD9,0xFF,0xD3,0xFF,0xDD,0xFF, + 0xE7,0xFF,0xE5,0xFF,0xDF,0xFF,0xDE,0xFF,0xDB,0xFF,0xDF,0xFF, + 0xDE,0xFF,0xDA,0xFF,0xDD,0xFF,0xE3,0xFF,0xE4,0xFF,0xEB,0xFF, + 0xE5,0xFF,0xE2,0xFF,0xE4,0xFF,0xDF,0xFF,0xE0,0xFF,0xE1,0xFF, + 0xE5,0xFF,0xDB,0xFF,0xDC,0xFF,0xD9,0xFF,0xDB,0xFF,0xDB,0xFF, + 0xE1,0xFF,0xDB,0xFF,0xD9,0xFF,0xDB,0xFF,0xE2,0xFF,0xE5,0xFF, + 0xE3,0xFF,0xE2,0xFF,0xE9,0xFF,0xDF,0xFF,0xE7,0xFF,0xEF,0xFF, + 0xEE,0xFF,0xF1,0xFF,0xF1,0xFF,0xF0,0xFF,0xF5,0xFF,0xF3,0xFF, + 0xF3,0xFF,0xF1,0xFF,0xF3,0xFF,0xF5,0xFF,0xF7,0xFF,0xF8,0xFF, + 0xFD,0xFF,0xF3,0xFF,0xF6,0xFF,0xF9,0xFF,0xFC,0xFF,0xFF,0xFF, + 0xFB,0xFF,0xFF,0xFF,0x02,0x00,0x04,0x00,0xFE,0xFF,0xFE,0xFF, + 0xFD,0xFF,0xFA,0xFF,0xF6,0xFF,0xF7,0xFF,0xFD,0xFF,0x03,0x00, + 0xF9,0xFF,0xF7,0xFF,0xF3,0xFF,0xF4,0xFF,0xF3,0xFF,0xF4,0xFF, + 0xF5,0xFF,0xED,0xFF,0xEE,0xFF,0xEF,0xFF,0xF9,0xFF,0xEF,0xFF, + 0xF1,0xFF,0xEF,0xFF,0xEC,0xFF,0xEC,0xFF,0xEB,0xFF,0xEE,0xFF, + 0xEF,0xFF,0xE7,0xFF,0xE0,0xFF,0xE7,0xFF,0xDB,0xFF,0xE1,0xFF, + 0xDE,0xFF,0xE1,0xFF,0xD7,0xFF,0xD7,0xFF,0xD9,0xFF,0xD5,0xFF, + 0xD3,0xFF,0xDD,0xFF,0xD9,0xFF,0xD9,0xFF,0xD7,0xFF,0xD7,0xFF, + 0xD6,0xFF,0xDB,0xFF,0xDA,0xFF,0xDC,0xFF,0xDB,0xFF,0xD4,0xFF, + 0xD5,0xFF,0xD1,0xFF,0xD6,0xFF,0xDA,0xFF,0xD2,0xFF,0xD1,0xFF, + 0xD1,0xFF,0xCF,0xFF,0xD3,0xFF,0xD9,0xFF,0xD7,0xFF,0xD8,0xFF, + 0xD5,0xFF,0xD4,0xFF,0xD4,0xFF,0xD7,0xFF,0xD2,0xFF,0xCE,0xFF, + 0xD6,0xFF,0xD1,0xFF,0xD7,0xFF,0xD6,0xFF,0xD5,0xFF,0xD6,0xFF, + 0xD1,0xFF,0xD7,0xFF,0xD5,0xFF,0xD3,0xFF,0xD8,0xFF,0xD9,0xFF, + 0xDD,0xFF,0xD9,0xFF,0xE1,0xFF,0xDD,0xFF,0xDB,0xFF,0xDA,0xFF, + 0xE0,0xFF,0xDB,0xFF,0xDA,0xFF,0xE4,0xFF,0xDF,0xFF,0xDA,0xFF, + 0xD8,0xFF,0xDC,0xFF,0xE9,0xFF,0xE1,0xFF,0xDE,0xFF,0xE1,0xFF, + 0xDC,0xFF,0xDC,0xFF,0xE4,0xFF,0xE6,0xFF,0xF1,0xFF,0xED,0xFF, + 0xE6,0xFF,0xEA,0xFF,0xE5,0xFF,0xED,0xFF,0xEE,0xFF,0xF0,0xFF, + 0xF4,0xFF,0xF3,0xFF,0xF2,0xFF,0xEB,0xFF,0xEE,0xFF,0xF2,0xFF, + 0xF5,0xFF,0xFC,0xFF,0xF5,0xFF,0xF6,0xFF,0xF0,0xFF,0xFF,0xFF, + 0xF4,0xFF,0xFA,0xFF,0xFB,0xFF,0xF7,0xFF,0xF9,0xFF,0xF4,0xFF, + 0xF2,0xFF,0xF3,0xFF,0xF4,0xFF,0xF5,0xFF,0xF1,0xFF,0xED,0xFF, + 0xED,0xFF,0xEE,0xFF,0xEE,0xFF,0xE4,0xFF,0xE3,0xFF,0xEA,0xFF, + 0xE8,0xFF,0xEC,0xFF,0xEA,0xFF,0xE8,0xFF,0xE8,0xFF,0xE5,0xFF, + 0xE0,0xFF,0xE2,0xFF,0xE0,0xFF,0xE1,0xFF,0xDE,0xFF,0xDD,0xFF, + 0xDB,0xFF,0xD3,0xFF,0xD3,0xFF,0xD9,0xFF,0xD7,0xFF,0xDB,0xFF, + 0xD8,0xFF,0xD9,0xFF,0xD7,0xFF,0xD3,0xFF,0xD7,0xFF,0xD9,0xFF, + 0xD6,0xFF,0xD2,0xFF,0xD3,0xFF,0xCF,0xFF,0xCF,0xFF,0xCC,0xFF, + 0xD2,0xFF,0xD5,0xFF,0xD3,0xFF,0xD1,0xFF,0xDD,0xFF,0xD2,0xFF, + 0xD7,0xFF,0xD8,0xFF,0xD6,0xFF,0xD5,0xFF,0xC8,0xFF,0xD2,0xFF, + 0xD1,0xFF,0xCA,0xFF,0xCB,0xFF,0xCA,0xFF,0xCC,0xFF,0xC3,0xFF, + 0xC6,0xFF,0xC9,0xFF,0xCA,0xFF,0xCE,0xFF,0xD1,0xFF,0xCB,0xFF, + 0xD1,0xFF,0xCD,0xFF,0xD2,0xFF,0xD2,0xFF,0xD3,0xFF,0xD7,0xFF, + 0xDF,0xFF,0xD9,0xFF,0xDD,0xFF,0xD9,0xFF,0xDB,0xFF,0xE1,0xFF, + 0xE5,0xFF,0xDD,0xFF,0xDE,0xFF,0xE0,0xFF,0xDF,0xFF,0xDD,0xFF, + 0xDE,0xFF,0xE2,0xFF,0xDD,0xFF,0xE1,0xFF,0xE1,0xFF,0xE2,0xFF, + 0xDF,0xFF,0xDB,0xFF,0xE0,0xFF,0xDB,0xFF,0xD8,0xFF,0xD9,0xFF, + 0xE1,0xFF,0xE0,0xFF,0xE4,0xFF,0xE4,0xFF,0xE5,0xFF,0xE2,0xFF, + 0xE4,0xFF,0xE5,0xFF,0xE9,0xFF,0xE7,0xFF,0xE7,0xFF,0xE5,0xFF, + 0xE8,0xFF,0xE7,0xFF,0xE3,0xFF,0xEC,0xFF,0xEE,0xFF,0xF1,0xFF, + 0xEF,0xFF,0xF6,0xFF,0xEE,0xFF,0xF5,0xFF,0xF2,0xFF,0xF5,0xFF, + 0xF0,0xFF,0xF6,0xFF,0xF2,0xFF,0xFC,0xFF,0xF8,0xFF,0xF7,0xFF, + 0xF9,0xFF,0xF1,0xFF,0xF4,0xFF,0xEF,0xFF,0xF1,0xFF,0xF3,0xFF, + 0xF4,0xFF,0xF6,0xFF,0xF3,0xFF,0xF2,0xFF,0xEE,0xFF,0xF5,0xFF, + 0xEE,0xFF,0xEE,0xFF,0xF5,0xFF,0xF4,0xFF,0xEE,0xFF,0xEC,0xFF, + 0xE7,0xFF,0xEC,0xFF,0xEB,0xFF,0xE1,0xFF,0xE7,0xFF,0xE2,0xFF, + 0xDF,0xFF,0xE2,0xFF,0xDD,0xFF,0xE8,0xFF,0xE0,0xFF,0xE3,0xFF, + 0xE7,0xFF,0xE2,0xFF,0xDF,0xFF,0xE6,0xFF,0xE3,0xFF,0xE0,0xFF, + 0xE9,0xFF,0xE7,0xFF,0xE2,0xFF,0xE2,0xFF,0xE0,0xFF,0xE2,0xFF, + 0xDF,0xFF,0xDF,0xFF,0xE4,0xFF,0xDD,0xFF,0xE2,0xFF,0xDA,0xFF, + 0xD8,0xFF,0xDD,0xFF,0xDA,0xFF,0xDB,0xFF,0xDE,0xFF,0xDD,0xFF, + 0xDC,0xFF,0xD8,0xFF,0xD3,0xFF,0xD2,0xFF,0xD2,0xFF,0xD1,0xFF, + 0xD3,0xFF,0xCE,0xFF,0xCF,0xFF,0xCB,0xFF,0xCA,0xFF,0xC9,0xFF, + 0xC8,0xFF,0xC7,0xFF,0xC3,0xFF,0xBF,0xFF,0xC3,0xFF,0xC1,0xFF, + 0xC0,0xFF,0xC0,0xFF,0xBE,0xFF,0xBC,0xFF,0xBC,0xFF,0xBF,0xFF, + 0xBF,0xFF,0xC4,0xFF,0xC2,0xFF,0xC0,0xFF,0xBF,0xFF,0xBE,0xFF, + 0xBB,0xFF,0xC1,0xFF,0xC2,0xFF,0xBF,0xFF,0xC2,0xFF,0xBE,0xFF, + 0xBC,0xFF,0xC1,0xFF,0xC4,0xFF,0xBD,0xFF,0xC1,0xFF,0xBB,0xFF, + 0xBD,0xFF,0xC3,0xFF,0xBF,0xFF,0xC8,0xFF,0xC2,0xFF,0xC1,0xFF, + 0xBD,0xFF,0xBD,0xFF,0xC2,0xFF,0xC1,0xFF,0xBB,0xFF,0xC0,0xFF, + 0xC0,0xFF,0xC3,0xFF,0xC0,0xFF,0xC5,0xFF,0xCA,0xFF,0xCD,0xFF, + 0xCA,0xFF,0xCC,0xFF,0xCD,0xFF,0xD9,0xFF,0xDE,0xFF,0x04,0x00, + 0x10,0x00,0x58,0x00,0x0E,0x00,0x9F,0xFF,0xBE,0xFF,0xEB,0xFF, + 0x0D,0x00,0xD7,0xFF,0xEE,0xFF,0xB0,0xFF,0xE9,0xFF,0xF5,0xFF, + 0x0D,0x00,0xDE,0xFF,0xF1,0xFF,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xF1,0xFF,0xF1,0xFF,0xE6,0xFF,0xF3,0xFF,0xF2,0xFF,0xDE,0xFF, + 0xEB,0xFF,0xE2,0xFF,0xEB,0xFF,0xED,0xFF,0xE5,0xFF,0xE6,0xFF, + 0xE1,0xFF,0xE1,0xFF,0xDE,0xFF,0xE7,0xFF,0xE9,0xFF,0xDA,0xFF, + 0xE1,0xFF,0xDD,0xFF,0xDE,0xFF,0xE1,0xFF,0xDC,0xFF,0xE2,0xFF, + 0xE0,0xFF,0xDF,0xFF,0xDD,0xFF,0xDD,0xFF,0xDE,0xFF,0xDD,0xFF, + 0xE1,0xFF,0xDE,0xFF,0xE2,0xFF,0xDE,0xFF,0xDB,0xFF,0xD7,0xFF, + 0xE2,0xFF,0xD8,0xFF,0xDA,0xFF,0xDC,0xFF,0xD3,0xFF,0xDB,0xFF, + 0xDA,0xFF,0xDB,0xFF,0xDC,0xFF,0xDB,0xFF,0xDA,0xFF,0xD9,0xFF, + 0xDB,0xFF,0xD8,0xFF,0xD5,0xFF,0xD6,0xFF,0xD9,0xFF,0xD2,0xFF, + 0xCC,0xFF,0xD0,0xFF,0xCF,0xFF,0xD2,0xFF,0xD2,0xFF,0xD2,0xFF, + 0xD0,0xFF,0xCE,0xFF,0xD2,0xFF,0xD9,0xFF,0xD6,0xFF,0xDD,0xFF, + 0xD9,0xFF,0xD9,0xFF,0xDC,0xFF,0xDD,0xFF,0xE1,0xFF,0xE2,0xFF, + 0xE4,0xFF,0xDE,0xFF,0xDD,0xFF,0xDD,0xFF,0xDD,0xFF,0xE2,0xFF, + 0xE6,0xFF,0xE7,0xFF,0xE7,0xFF,0xE1,0xFF,0xE3,0xFF,0xE6,0xFF, + 0xE7,0xFF,0xE9,0xFF,0xE5,0xFF,0xE7,0xFF,0xE6,0xFF,0xF3,0xFF, + 0xED,0xFF,0xEE,0xFF,0xED,0xFF,0xF2,0xFF,0xEC,0xFF,0xF1,0xFF, + 0xF0,0xFF,0xF0,0xFF,0xF2,0xFF,0xF1,0xFF,0xF1,0xFF,0xF7,0xFF, + 0xF4,0xFF,0xF3,0xFF,0xF7,0xFF,0xF8,0xFF,0xF8,0xFF,0xF9,0xFF, + 0xF2,0xFF,0xFA,0xFF,0xFB,0xFF,0x02,0x00,0x02,0x00,0x04,0x00, + 0x00,0x00,0x06,0x00,0x04,0x00,0x09,0x00,0x01,0x00,0x02,0x00, + 0x0A,0x00,0x07,0x00,0x04,0x00,0x03,0x00,0x08,0x00,0x0A,0x00, + 0x05,0x00,0x03,0x00,0x03,0x00,0xFD,0xFF,0x02,0x00,0x01,0x00, + 0xF8,0xFF,0xF9,0xFF,0xFA,0xFF,0xF5,0xFF,0xF9,0xFF,0xF7,0xFF, + 0xF5,0xFF,0xED,0xFF,0xF1,0xFF,0xF0,0xFF,0xF2,0xFF,0xE8,0xFF, + 0xF5,0xFF,0xEC,0xFF,0xEF,0xFF,0xE9,0xFF,0xE8,0xFF,0xE2,0xFF, + 0xE7,0xFF,0xE6,0xFF,0xE5,0xFF,0xEA,0xFF,0xE1,0xFF,0xE3,0xFF, + 0xE2,0xFF,0xE2,0xFF,0xE2,0xFF,0xDD,0xFF,0xE2,0xFF,0xDB,0xFF, + 0xDC,0xFF,0xD6,0xFF,0xD9,0xFF,0xD7,0xFF,0xD5,0xFF,0xDA,0xFF, + 0xDB,0xFF,0xD9,0xFF,0xD4,0xFF,0xDB,0xFF,0xDE,0xFF,0xDD,0xFF, + 0xE1,0xFF,0xDD,0xFF,0xD5,0xFF,0xD9,0xFF,0xD6,0xFF,0xD2,0xFF, + 0xD4,0xFF,0xD6,0xFF,0xD2,0xFF,0xD6,0xFF,0xCA,0xFF,0xC7,0xFF, + 0xCB,0xFF,0xC9,0xFF,0xCE,0xFF,0xC6,0xFF,0xC7,0xFF,0xC9,0xFF, + 0xD8,0xFF,0xD2,0xFF,0xD1,0xFF,0xCC,0xFF,0xD0,0xFF,0xCE,0xFF, + 0xD3,0xFF,0xD1,0xFF,0xC3,0xFF,0xCD,0xFF,0xCE,0xFF,0xCA,0xFF, + 0xCA,0xFF,0xCA,0xFF,0xCB,0xFF,0xD4,0xFF,0xCC,0xFF,0xD0,0xFF, + 0xCD,0xFF,0xCB,0xFF,0xC7,0xFF,0xD0,0xFF,0xD0,0xFF,0xCD,0xFF, + 0xCE,0xFF,0xC9,0xFF,0xC3,0xFF,0xC9,0xFF,0xC5,0xFF,0xC5,0xFF, + 0xCA,0xFF,0xCF,0xFF,0xCD,0xFF,0xCC,0xFF,0xD4,0xFF,0xD5,0xFF, + 0xD0,0xFF,0xCD,0xFF,0xCD,0xFF,0xCA,0xFF,0xCF,0xFF,0xD8,0xFF, + 0xD5,0xFF,0xD6,0xFF,0xDA,0xFF,0xDE,0xFF,0xDC,0xFF,0xE6,0xFF, + 0xE3,0xFF,0xE6,0xFF,0xE7,0xFF,0xE7,0xFF,0xDE,0xFF,0xDE,0xFF, + 0xE5,0xFF,0xE3,0xFF,0xE5,0xFF,0xE8,0xFF,0xE9,0xFF,0xE5,0xFF, + 0xE3,0xFF,0xE9,0xFF,0xED,0xFF,0xEC,0xFF,0xF4,0xFF,0xEB,0xFF, + 0xEF,0xFF,0xEC,0xFF,0xEE,0xFF,0xF1,0xFF,0xF3,0xFF,0xED,0xFF, + 0xF2,0xFF,0xEC,0xFF,0xEC,0xFF,0xEE,0xFF,0xF1,0xFF,0xF4,0xFF, + 0xF1,0xFF,0xEF,0xFF,0xF2,0xFF,0xE9,0xFF,0xFC,0xFF,0xF3,0xFF, + 0xF3,0xFF,0xF4,0xFF,0xEC,0xFF,0xEE,0xFF,0xEB,0xFF,0xEE,0xFF, + 0xEF,0xFF,0xF1,0xFF,0xEC,0xFF,0xEA,0xFF,0xEC,0xFF,0xF0,0xFF, + 0xF0,0xFF,0xF1,0xFF,0xF2,0xFF,0xEB,0xFF,0xF2,0xFF,0xED,0xFF, + 0xEA,0xFF,0xF2,0xFF,0xF0,0xFF,0xE7,0xFF,0xEB,0xFF,0xEA,0xFF, + 0xEB,0xFF,0xE7,0xFF,0xEB,0xFF,0xE8,0xFF,0xE2,0xFF,0xE5,0xFF, + 0xE6,0xFF,0xDF,0xFF,0xE1,0xFF,0xDC,0xFF,0xE4,0xFF,0xE3,0xFF, + 0xD8,0xFF,0xDA,0xFF,0xDA,0xFF,0xDD,0xFF,0xDC,0xFF,0xDA,0xFF, + 0xD8,0xFF,0xDA,0xFF,0xDB,0xFF,0xD9,0xFF,0xDA,0xFF,0xD9,0xFF, + 0xD7,0xFF,0xD6,0xFF,0xD5,0xFF,0xD2,0xFF,0xD2,0xFF,0xD7,0xFF, + 0xD9,0xFF,0xD8,0xFF,0xD8,0xFF,0xD8,0xFF,0xDB,0xFF,0xDB,0xFF, + 0xDE,0xFF,0xDD,0xFF,0xDE,0xFF,0xDE,0xFF,0xD8,0xFF,0xDE,0xFF, + 0xDD,0xFF,0xDA,0xFF,0xDB,0xFF,0xDB,0xFF,0xD6,0xFF,0xD8,0xFF, + 0xD8,0xFF,0xD7,0xFF,0xD6,0xFF,0xD5,0xFF,0xD0,0xFF,0xCE,0xFF, + 0xD3,0xFF,0xD6,0xFF,0xD5,0xFF,0xD6,0xFF,0xD6,0xFF,0xD0,0xFF, + 0xD3,0xFF,0xCE,0xFF,0xD2,0xFF,0xD4,0xFF,0xD4,0xFF,0xD7,0xFF, + 0xD1,0xFF,0xD4,0xFF,0xD4,0xFF,0xD9,0xFF,0xDB,0xFF,0xD9,0xFF, + 0xDE,0xFF,0xDD,0xFF,0xDD,0xFF,0xE1,0xFF,0xE3,0xFF,0xE7,0xFF, + 0xE5,0xFF,0xDB,0xFF,0xE4,0xFF,0xE9,0xFF,0xE6,0xFF,0xE2,0xFF, + 0xE4,0xFF,0xE0,0xFF,0xE4,0xFF,0xDA,0xFF,0xDA,0xFF,0xD9,0xFF, + 0xDC,0xFF,0xE2,0xFF,0xDF,0xFF,0xD9,0xFF,0xD6,0xFF,0xD5,0xFF, + 0xD7,0xFF,0xD6,0xFF,0xD5,0xFF,0xD2,0xFF,0xD2,0xFF,0xD1,0xFF, + 0xCB,0xFF,0xCD,0xFF,0xC8,0xFF,0xD3,0xFF,0xCD,0xFF,0xCC,0xFF, + 0xC7,0xFF,0xCC,0xFF,0xCC,0xFF,0xC7,0xFF,0xCD,0xFF,0xCD,0xFF, + 0xCF,0xFF,0xC6,0xFF,0xC6,0xFF,0xC6,0xFF,0xCC,0xFF,0xCA,0xFF, + 0xCC,0xFF,0xC8,0xFF,0xC7,0xFF,0xC9,0xFF,0xC3,0xFF,0xC1,0xFF, + 0xC5,0xFF,0xC0,0xFF,0xC1,0xFF,0xC2,0xFF,0xB8,0xFF,0xBD,0xFF, + 0xBC,0xFF,0xC4,0xFF,0xBD,0xFF,0xC6,0xFF,0xC2,0xFF,0xBA,0xFF, + 0xC0,0xFF,0xC2,0xFF,0xC4,0xFF,0xB2,0xFF,0xBC,0xFF,0xBC,0xFF, + 0xB9,0xFF,0xBE,0xFF,0xBD,0xFF,0xBF,0xFF,0xBB,0xFF,0xBC,0xFF, + 0xC5,0xFF,0xC3,0xFF,0xC8,0xFF,0xC4,0xFF,0xCA,0xFF,0xC5,0xFF, + 0xC0,0xFF,0xCE,0xFF,0xC8,0xFF,0xC4,0xFF,0xD0,0xFF,0xCA,0xFF, + 0xCF,0xFF,0xCD,0xFF,0xCB,0xFF,0xCF,0xFF,0xCE,0xFF,0xCE,0xFF, + 0xCE,0xFF,0xCD,0xFF,0xD0,0xFF,0xD0,0xFF,0xCB,0xFF,0xCC,0xFF, + 0xC7,0xFF,0xCE,0xFF,0xC1,0xFF,0xCE,0xFF,0xC9,0xFF,0xCA,0xFF, + 0xC9,0xFF,0xD0,0xFF,0xD5,0xFF,0xCF,0xFF,0xD4,0xFF,0xD6,0xFF, + 0xCF,0xFF,0xD5,0xFF,0xCF,0xFF,0xD7,0xFF,0xCD,0xFF,0xCF,0xFF, + 0xDB,0xFF,0xCC,0xFF,0xE4,0xFF,0xD2,0xFF,0xE3,0xFF,0xE5,0xFF, + 0xDC,0xFF,0xE5,0xFF,0xE4,0xFF,0xDC,0xFF,0xEE,0xFF,0xE3,0xFF, + 0xEF,0xFF,0xE9,0xFF,0xF4,0xFF,0xF4,0xFF,0xF9,0xFF,0xF4,0xFF, + 0xF3,0xFF,0xEB,0xFF,0xFB,0xFF,0xF2,0xFF,0xF9,0xFF,0xF5,0xFF, + 0xF7,0xFF,0xF4,0xFF,0xF9,0xFF,0xF3,0xFF,0xF2,0xFF,0xEB,0xFF, + 0xF3,0xFF,0xEF,0xFF,0xEE,0xFF,0xF1,0xFF,0xF6,0xFF,0xF2,0xFF, + 0xED,0xFF,0xEE,0xFF,0xEA,0xFF,0xEA,0xFF,0xE6,0xFF,0xE4,0xFF, + 0xE2,0xFF,0xE8,0xFF,0xE3,0xFF,0xDD,0xFF,0xDD,0xFF,0xDB,0xFF, + 0xDB,0xFF,0xDB,0xFF,0xDC,0xFF,0xD7,0xFF,0xD4,0xFF,0xD8,0xFF, + 0xD7,0xFF,0xDC,0xFF,0xD9,0xFF,0xDB,0xFF,0xD4,0xFF,0xD5,0xFF, + 0xD4,0xFF,0xD2,0xFF,0xD0,0xFF,0xD0,0xFF,0xCE,0xFF,0xC9,0xFF, + 0xCD,0xFF,0xD2,0xFF,0xD2,0xFF,0xD0,0xFF,0xDC,0xFF,0xD2,0xFF, + 0xD5,0xFF,0xD9,0xFF,0xD6,0xFF,0xD4,0xFF,0xD7,0xFF,0xDB,0xFF, + 0xD0,0xFF,0xCB,0xFF,0xC2,0xFF,0xCB,0xFF,0xC9,0xFF,0xCD,0xFF, + 0xC8,0xFF,0xC5,0xFF,0xBF,0xFF,0xBE,0xFF,0xC3,0xFF,0xC5,0xFF, + 0xC9,0xFF,0xC2,0xFF,0xC2,0xFF,0xC4,0xFF,0xC6,0xFF,0xBF,0xFF, + 0xC3,0xFF,0xC5,0xFF,0xC5,0xFF,0xC6,0xFF,0xC5,0xFF,0xB9,0xFF, + 0xC4,0xFF,0xC7,0xFF,0xCB,0xFF,0xC9,0xFF,0xD3,0xFF,0xCE,0xFF, + 0xD1,0xFF,0xDA,0xFF,0xD6,0xFF,0xCC,0xFF,0xCE,0xFF,0xC9,0xFF, + 0xCF,0xFF,0xCE,0xFF,0xD3,0xFF,0xDB,0xFF,0xDA,0xFF,0xD2,0xFF, + 0xD3,0xFF,0xD3,0xFF,0xD1,0xFF,0xCD,0xFF,0xD6,0xFF,0xD7,0xFF, + 0xD5,0xFF,0xCF,0xFF,0xCF,0xFF,0xCC,0xFF,0xD8,0xFF,0xD5,0xFF, + 0xD4,0xFF,0xD6,0xFF,0xDC,0xFF,0xE3,0xFF,0xE5,0xFF,0xEC,0xFF, + 0xEB,0xFF,0xEB,0xFF,0xEA,0xFF,0xEA,0xFF,0xF0,0xFF,0xEB,0xFF, + 0xF1,0xFF,0xF2,0xFF,0xF4,0xFF,0xF0,0xFF,0xF3,0xFF,0xF3,0xFF, + 0xF1,0xFF,0xF0,0xFF,0xF2,0xFF,0xF0,0xFF,0xF1,0xFF,0xF0,0xFF, + 0xF6,0xFF,0xF9,0xFF,0xF5,0xFF,0xF2,0xFF,0xEE,0xFF,0xF1,0xFF, + 0xEE,0xFF,0xF1,0xFF,0xF6,0xFF,0xF5,0xFF,0xF5,0xFF,0xF5,0xFF, + 0xEE,0xFF,0xF4,0xFF,0xF1,0xFF,0xF8,0xFF,0xF9,0xFF,0xF6,0xFF, + 0xF2,0xFF,0xF2,0xFF,0xEC,0xFF,0xF7,0xFF,0xF3,0xFF,0xF4,0xFF, + 0xF3,0xFF,0xF3,0xFF,0xF2,0xFF,0xF6,0xFF,0xF4,0xFF,0xF6,0xFF, + 0xF8,0xFF,0xF4,0xFF,0xF4,0xFF,0xF3,0xFF,0xF4,0xFF,0xFA,0xFF, + 0xFA,0xFF,0xF8,0xFF,0xFB,0xFF,0xF6,0xFF,0xF7,0xFF,0xFE,0xFF, + 0x08,0x00,0xFA,0xFF,0xFB,0xFF,0x01,0x00,0xF7,0xFF,0x00,0x00, + 0xFF,0xFF,0x04,0x00,0x03,0x00,0x01,0x00,0x03,0x00,0xF8,0xFF, + 0xFB,0xFF,0xF8,0xFF,0xFC,0xFF,0xF9,0xFF,0xF6,0xFF,0xFA,0xFF, + 0xF7,0xFF,0xF2,0xFF,0xFA,0xFF,0xFA,0xFF,0xFC,0xFF,0xF9,0xFF, + 0xF8,0xFF,0xF6,0xFF,0xFB,0xFF,0xF6,0xFF,0xF8,0xFF,0x02,0x00, + 0x00,0x00,0xF8,0xFF,0xFE,0xFF,0xFB,0xFF,0xF9,0xFF,0xFA,0xFF, + 0xFF,0xFF,0xFC,0xFF,0x00,0x00,0xFE,0xFF,0xFF,0xFF,0xFE,0xFF, + 0x04,0x00,0xF9,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x04,0x00, + 0x06,0x00,0x01,0x00,0x07,0x00,0x06,0x00,0x02,0x00,0xFD,0xFF, + 0x02,0x00,0xFC,0xFF,0xF9,0xFF,0xFA,0xFF,0xF9,0xFF,0xFC,0xFF, + 0xFB,0xFF,0x00,0x00,0xFC,0xFF,0xFC,0xFF,0x04,0x00,0x0A,0x00, + 0x03,0x00,0x07,0x00,0x14,0x00,0x11,0x00,0x11,0x00,0x0E,0x00, + 0x0C,0x00,0x0F,0x00,0x0D,0x00,0x13,0x00,0x12,0x00,0x12,0x00, + 0x12,0x00,0x12,0x00,0x10,0x00,0x17,0x00,0x10,0x00,0x12,0x00, + 0x0F,0x00,0x0B,0x00,0x0A,0x00,0x0B,0x00,0x0D,0x00,0x10,0x00, + 0x14,0x00,0x13,0x00,0x0E,0x00,0x10,0x00,0x15,0x00,0x0A,0x00, + 0x0A,0x00,0x05,0x00,0x06,0x00,0x0C,0x00,0x04,0x00,0x05,0x00, + 0x0B,0x00,0x06,0x00,0x03,0x00,0xFB,0xFF,0xF9,0xFF,0xFA,0xFF, + 0xFA,0xFF,0xFC,0xFF,0xF7,0xFF,0x00,0x00,0xF5,0xFF,0xF4,0xFF, + 0xF1,0xFF,0xEC,0xFF,0xEF,0xFF,0xE9,0xFF,0xF0,0xFF,0xEF,0xFF, + 0xEE,0xFF,0xEF,0xFF,0xEE,0xFF,0xF5,0xFF,0xF2,0xFF,0xF7,0xFF, + 0xF4,0xFF,0xF2,0xFF,0xEB,0xFF,0xE8,0xFF,0xEB,0xFF,0xEA,0xFF, + 0xEA,0xFF,0xE5,0xFF,0xE5,0xFF,0xE6,0xFF,0xE5,0xFF,0xE4,0xFF, + 0xE6,0xFF,0xE8,0xFF,0xE1,0xFF,0xE4,0xFF,0xE3,0xFF,0xE1,0xFF, + 0xE1,0xFF,0xDC,0xFF,0xE3,0xFF,0xD3,0xFF,0xD6,0xFF,0xD8,0xFF, + 0xE6,0xFF,0xE3,0xFF,0xE1,0xFF,0xDB,0xFF,0xDB,0xFF,0xD6,0xFF, + 0xD9,0xFF,0xD3,0xFF,0xD4,0xFF,0xD6,0xFF,0xD0,0xFF,0xD2,0xFF, + 0xD3,0xFF,0xCE,0xFF,0xD5,0xFF,0xD4,0xFF,0xD6,0xFF,0xDF,0xFF, + 0xD9,0xFF,0xDA,0xFF,0xE2,0xFF,0xEA,0xFF,0xEB,0xFF,0xE5,0xFF, + 0xE4,0xFF,0xE7,0xFF,0xE9,0xFF,0xED,0xFF,0xE6,0xFF,0xEC,0xFF, + 0xE5,0xFF,0xE9,0xFF,0xF0,0xFF,0xF0,0xFF,0xEA,0xFF,0xED,0xFF, + 0xF0,0xFF,0xF0,0xFF,0xF5,0xFF,0xF3,0xFF,0xF4,0xFF,0xFA,0xFF, + 0xF0,0xFF,0xF0,0xFF,0xF2,0xFF,0xF7,0xFF,0xF7,0xFF,0xFC,0xFF, + 0xFB,0xFF,0xF4,0xFF,0xF1,0xFF,0xFB,0xFF,0xF8,0xFF,0xFA,0xFF, + 0xF7,0xFF,0xFA,0xFF,0xF7,0xFF,0xEF,0xFF,0xF2,0xFF,0xF6,0xFF, + 0xF4,0xFF,0xF7,0xFF,0xF8,0xFF,0xFA,0xFF,0xF6,0xFF,0xEF,0xFF, + 0xEC,0xFF,0xEE,0xFF,0xE9,0xFF,0xED,0xFF,0xED,0xFF,0xEC,0xFF, + 0xE7,0xFF,0xE8,0xFF,0xEF,0xFF,0xEA,0xFF,0xE3,0xFF,0xEA,0xFF, + 0xED,0xFF,0xED,0xFF,0xEE,0xFF,0xEA,0xFF,0xEC,0xFF,0xEC,0xFF, + 0xE4,0xFF,0xE0,0xFF,0xD5,0xFF,0xDB,0xFF,0xD6,0xFF,0xDB,0xFF, + 0xD5,0xFF,0xD0,0xFF,0xD2,0xFF,0xCB,0xFF,0xC8,0xFF,0xC3,0xFF, + 0xBF,0xFF,0xBE,0xFF,0xBD,0xFF,0xB1,0xFF,0xAE,0xFF,0xAD,0xFF, + 0xAB,0xFF,0xAF,0xFF,0xA5,0xFF,0xA0,0xFF,0xA3,0xFF,0xAC,0xFF, + 0xA8,0xFF,0xA2,0xFF,0xA5,0xFF,0xA8,0xFF,0xA3,0xFF,0xA6,0xFF, + 0xA2,0xFF,0xA2,0xFF,0xAB,0xFF,0xAA,0xFF,0xAE,0xFF,0xAD,0xFF, + 0xB0,0xFF,0xAC,0xFF,0xB1,0xFF,0xB7,0xFF,0xBF,0xFF,0xB7,0xFF, + 0xBD,0xFF,0xBA,0xFF,0xBF,0xFF,0xC4,0xFF,0xC8,0xFF,0xD3,0xFF, + 0xD8,0xFF,0xD3,0xFF,0xD8,0xFF,0xE0,0xFF,0xE4,0xFF,0xE7,0xFF, + 0xE1,0xFF,0xE3,0xFF,0xD8,0xFF,0xD3,0xFF,0xD9,0xFF,0xCD,0xFF, + 0xD7,0xFF,0xC9,0xFF,0xBE,0xFF,0xBC,0xFF,0xAA,0xFF,0xA5,0xFF, + 0x9C,0xFF,0x94,0xFF,0x8C,0xFF,0x89,0xFF,0x85,0xFF,0x80,0xFF, + 0x7F,0xFF,0x7E,0xFF,0x84,0xFF,0x83,0xFF,0x82,0xFF,0x82,0xFF, + 0x82,0xFF,0x87,0xFF,0x82,0xFF,0x9B,0xFF,0x99,0xFF,0xA4,0xFF, + 0xA2,0xFF,0xB3,0xFF,0xBA,0xFF,0xBD,0xFF,0xCA,0xFF,0xCE,0xFF, + 0xD7,0xFF,0xD6,0xFF,0xE9,0xFF,0x00,0x00,0x05,0x00,0x1A,0x00, + 0x2C,0x00,0x3E,0x00,0x44,0x00,0x52,0x00,0x6F,0x00,0x7E,0x00, + 0x88,0x00,0x9B,0x00,0xB2,0x00,0xAA,0x00,0x97,0x00,0x87,0x00, + 0x91,0x00,0x64,0x00,0x54,0x00,0x0C,0x00,0xBF,0xFF,0x81,0xFF, + 0x58,0xFF,0x1E,0xFF,0xDC,0xFE,0x9D,0xFE,0xA0,0xFE,0x8B,0xFE, + 0x72,0xFE,0x80,0xFE,0x94,0xFE,0x94,0xFE,0xBC,0xFE,0xFA,0xFE, + 0x38,0xFF,0x54,0xFF,0x92,0xFF,0xC4,0xFF,0xE1,0xFF,0xE9,0xFF, + 0xF1,0xFF,0xF7,0xFF,0xFA,0xFF,0xF7,0xFF,0x04,0x00,0x0D,0x00, + 0x23,0x00,0x2E,0x00,0x3E,0x00,0x51,0x00,0x6F,0x00,0x88,0x00, + 0xAF,0x00,0xE5,0x00,0x21,0x01,0x57,0x01,0xA0,0x01,0xD4,0x01, + 0xF9,0x01,0x02,0x02,0xB1,0x01,0xE1,0x00,0x5A,0x00,0xE9,0xFF, + 0x6B,0xFF,0x06,0xFF,0x04,0xFF,0x04,0xFF,0xA1,0xFE,0x5B,0xFE, + 0x3C,0xFE,0xD3,0xFD,0xCA,0xFD,0x23,0xFE,0xBD,0xFE,0x1B,0xFF, + 0x67,0xFF,0xF7,0xFF,0x0A,0x00,0xD1,0xFF,0xEC,0xFF,0x02,0x00, + 0xFF,0xFF,0x19,0x00,0x43,0x00,0x4B,0x00,0xD0,0xFF,0x87,0xFF, + 0x69,0xFF,0x13,0xFF,0xF3,0xFE,0x2B,0xFF,0x5A,0xFF,0x64,0xFF, + 0x5E,0xFF,0x69,0xFF,0x55,0xFF,0x31,0xFF,0x70,0xFF,0xC0,0xFF, + 0xE5,0xFF,0x04,0x00,0x22,0x00,0x09,0x00,0xD8,0xFF,0xD7,0xFF, + 0xF2,0xFF,0x19,0x00,0x33,0x00,0x78,0x00,0x93,0x00,0x8A,0x00, + 0x96,0x00,0xB5,0x00,0xDE,0x00,0x2B,0x01,0x7E,0x01,0xA3,0x01, + 0xA1,0x01,0x6A,0x01,0x39,0x01,0x19,0x01,0xBB,0x00,0x4C,0x00, + 0x04,0x00,0xD0,0xFF,0x5B,0xFF,0xE7,0xFE,0xC0,0xFE,0x93,0xFE, + 0x61,0xFE,0x52,0xFE,0x5C,0xFE,0x60,0xFE,0x74,0xFE,0xB7,0xFE, + 0x16,0xFF,0x3D,0xFF,0x87,0xFF,0xE4,0xFF,0x0E,0x00,0x13,0x00, + 0x23,0x00,0x48,0x00,0x47,0x00,0x3A,0x00,0x40,0x00,0x3A,0x00, + 0x1B,0x00,0x15,0x00,0x22,0x00,0x37,0x00,0x3F,0x00,0x6F,0x00, + 0x94,0x00,0xB3,0x00,0xE8,0x00,0x4C,0x01,0x98,0x01,0x00,0x02, + 0x7F,0x02,0x09,0x03,0x28,0x03,0x2D,0x03,0xC1,0x02,0x66,0x01, + 0xE8,0x00,0xB3,0x00,0x44,0x00,0xC6,0xFF,0x5E,0xFF,0xCF,0xFE, + 0xFB,0xFD,0x0E,0xFD,0x35,0xFD,0x96,0xFD,0xC6,0xFD,0xE7,0xFD, + 0xF6,0xFD,0x32,0xFE,0x54,0xFE,0x09,0xFF,0xD8,0xFF,0x58,0x00, + 0x60,0x00,0x5F,0x00,0x4B,0x00,0x23,0x00,0x2C,0x00,0x6E,0x00, + 0x39,0x00,0xC4,0xFF,0x3A,0xFF,0xF7,0xFE,0xE3,0xFE,0xDF,0xFE, + 0xE7,0xFE,0xED,0xFE,0x95,0xFE,0x7A,0xFE,0xC6,0xFE,0x32,0xFF, + 0x7F,0xFF,0x86,0xFF,0x97,0xFF,0xA7,0xFF,0xA3,0xFF,0xE9,0xFF, + 0x52,0x00,0x65,0x00,0x63,0x00,0x67,0x00,0xA3,0x00,0x05,0x01, + 0x84,0x01,0xEE,0x01,0x70,0x02,0xCB,0x02,0x00,0x03,0x6D,0x02, + 0xA8,0x00,0x0A,0x01,0x2E,0x01,0xF4,0x00,0x0D,0x00,0x1C,0xFF, + 0xC8,0xFE,0x2D,0xFE,0xB4,0xFD,0x6B,0xFE,0xCF,0xFD,0x22,0xFD, + 0x2F,0xFD,0xDA,0xFD,0x4B,0xFE,0x56,0xFE,0xCD,0xFE,0x49,0xFF, + 0x28,0xFF,0x89,0xFF,0xED,0xFF,0x6F,0x00,0x10,0x00,0xC1,0xFF, + 0xE2,0xFF,0xDD,0xFF,0xB5,0xFF,0xB1,0xFF,0x99,0xFF,0x36,0xFF, + 0xC6,0xFE,0x1D,0xFF,0x5A,0xFF,0x2B,0xFF,0x01,0xFF,0x2E,0xFF, + 0x66,0xFF,0xA7,0xFF,0xED,0xFF,0x63,0x00,0x63,0x00,0x6C,0x00, + 0xFF,0x00,0xA8,0x01,0xF7,0x01,0x37,0x02,0xBC,0x02,0x99,0x03, + 0xDF,0x03,0xD8,0x03,0xDF,0x01,0xFD,0x00,0xA1,0x02,0xFF,0x01, + 0x87,0x00,0xD7,0xFE,0xCE,0xFE,0x2E,0xFF,0x00,0xFE,0xC0,0xFD, + 0x6D,0xFD,0xBB,0xFC,0xDA,0xFC,0x9D,0xFD,0x87,0xFE,0x4B,0xFE, + 0x6F,0xFD,0x4C,0xFF,0x58,0x00,0x40,0x00,0x5B,0x00,0x26,0x00, + 0xF1,0x00,0xD5,0x00,0xAC,0x00,0x25,0x01,0xDF,0xFF,0x7C,0xFF, + 0xF0,0xFF,0xD2,0xFF,0x24,0xFF,0x41,0xFE,0x5A,0xFE,0xEF,0xFE, + 0x60,0xFE,0x7A,0xFE,0x88,0xFE,0xAB,0xFE,0xFA,0xFE,0x5E,0xFF, + 0xED,0xFF,0xA7,0xFF,0xA6,0xFF,0xBC,0x00,0xFF,0x00,0x1D,0x01, + 0x15,0x01,0xED,0x01,0xA6,0x02,0xE2,0x02,0xAB,0x03,0xF3,0x03, + 0xCF,0x03,0x43,0x03,0xB5,0x00,0xF5,0x02,0x6E,0x03,0x3D,0x00, + 0xA4,0xFE,0x08,0xFF,0x24,0x00,0xB7,0xFE,0xD8,0xFB,0x53,0xFD, + 0x8D,0xFD,0xFA,0xFC,0xDB,0xFC,0xEC,0xFC,0x86,0xFD,0x2C,0xFD, + 0x9A,0xFE,0x2F,0x00,0x10,0xFF,0xE9,0xFE,0x19,0x00,0xB0,0x01, + 0x70,0x01,0x35,0xFF,0x77,0x00,0x26,0x01,0x59,0x00,0xCE,0xFF, + 0x2F,0xFF,0x8E,0xFF,0xBE,0xFE,0xAD,0xFE,0x0D,0xFF,0xC7,0xFD, + 0x2F,0xFE,0xD8,0xFE,0x28,0xFF,0x7A,0xFE,0x2B,0xFE,0x81,0xFF, + 0x72,0x00,0x73,0xFF,0xFE,0xFF,0xB6,0x00,0x9E,0x01,0x8F,0x01, + 0x16,0x02,0x50,0x03,0xE6,0x03,0x08,0x04,0x95,0x04,0x1D,0x04, + 0x01,0x01,0x20,0x03,0xB9,0x03,0x74,0x01,0x79,0xFE,0x47,0xFF, + 0x72,0x01,0x3F,0xFF,0xE8,0xFA,0x1C,0xFD,0x8F,0xFE,0x2A,0xFD, + 0x3A,0xFB,0x15,0xFC,0x46,0xFE,0x36,0xFD,0x53,0xFD,0xBF,0xFE, + 0x45,0xFF,0xF0,0xFF,0x6D,0x00,0x52,0x01,0x5E,0x00,0x3E,0x00, + 0xC0,0x01,0xF8,0x01,0xCB,0xFF,0xA5,0xFF,0xB7,0x00,0x25,0x01, + 0x68,0xFE,0x1B,0xFE,0x63,0xFF,0x1F,0xFF,0xBC,0xFD,0xAA,0xFD, + 0x59,0xFE,0xAD,0xFE,0x13,0xFE,0xF8,0xFE,0x3B,0xFF,0x1F,0xFF, + 0xDA,0xFF,0x8F,0x00,0x9D,0x00,0x70,0x00,0x90,0x01,0xA0,0x02, + 0x68,0x02,0xA5,0x02,0x31,0x04,0xA9,0x04,0xBC,0x04,0x39,0x04, + 0x16,0x00,0x42,0x04,0xBC,0x03,0x0D,0x00,0xA0,0xFE,0xB7,0xFF, + 0x0C,0x02,0xC9,0xFE,0x98,0xF9,0x56,0xFE,0xCB,0xFE,0x5E,0xFC, + 0xD4,0xFA,0x10,0xFC,0x1B,0xFF,0x6A,0xFD,0x5E,0xFC,0x1C,0xFF, + 0x20,0xFF,0xC5,0xFF,0x17,0x00,0x93,0x00,0xB0,0x00,0x52,0x00, + 0xF1,0x01,0x25,0x01,0x63,0xFF,0x2B,0x00,0xB7,0x00,0xEE,0xFF, + 0xB5,0xFD,0x00,0xFE,0xDD,0xFF,0x17,0xFE,0x1C,0xFD,0xC1,0xFD, + 0x82,0xFE,0x5A,0xFE,0x55,0xFD,0x19,0xFF,0xA4,0xFF,0xEC,0xFE, + 0xCB,0xFF,0x64,0x00,0xD1,0x00,0x31,0x01,0xBB,0x01,0x1D,0x03, + 0xEC,0x02,0xB0,0x03,0x1F,0x05,0x2D,0x05,0x45,0x04,0x7D,0xFF, + 0xB0,0x05,0xCA,0x03,0x6B,0xFE,0x3C,0xFE,0xF0,0x00,0xF0,0x01, + 0xDA,0xFC,0xB6,0xF8,0x9E,0xFF,0x1D,0xFE,0x45,0xFA,0x2D,0xFA, + 0xB7,0xFC,0xE5,0xFE,0x0B,0xFC,0xCE,0xFB,0xA8,0xFF,0x23,0xFF, + 0x33,0xFF,0x33,0x00,0xB9,0x00,0x2E,0x01,0xB1,0x00,0x15,0x02, + 0x23,0x01,0x6F,0xFF,0x5C,0x01,0xE8,0x00,0x3B,0xFF,0xC3,0xFD, + 0x15,0xFF,0xEB,0xFF,0x04,0xFD,0x75,0xFC,0x9B,0xFE,0x4E,0xFE, + 0x31,0xFD,0xD3,0xFC,0x66,0xFF,0xC8,0xFF,0x32,0xFE,0x9D,0xFF, + 0xD4,0x00,0xFC,0x00,0x1C,0x01,0x84,0x01,0x3F,0x03,0x3F,0x03, + 0x8F,0x03,0x8A,0x05,0x4A,0x05,0xB0,0x04,0x8C,0x00,0xAE,0x03, + 0x41,0x06,0x8A,0x00,0xCE,0xFD,0x12,0x00,0x3A,0x02,0xBB,0xFF, + 0xF3,0xF8,0x27,0xFD,0xA1,0xFF,0x31,0xFC,0x5E,0xFA,0x67,0xFB, + 0xEB,0xFE,0xC8,0xFC,0xB0,0xFB,0x05,0xFF,0x5B,0xFF,0x07,0x00, + 0x7B,0x00,0xD6,0x00,0xB7,0x01,0x58,0x01,0x7A,0x01,0x41,0x02, + 0x36,0x00,0xDF,0x00,0xDC,0x00,0xEF,0xFF,0xBA,0xFE,0x43,0xFE, + 0x02,0xFF,0x7D,0xFE,0xB9,0xFC,0xAA,0xFD,0x31,0xFE,0x24,0xFE, + 0x6D,0xFD,0x2A,0xFE,0x95,0xFF,0x68,0xFF,0x62,0xFF,0x80,0x00, + 0x08,0x01,0x98,0x01,0xBD,0x01,0xE0,0x02,0xA6,0x03,0xA9,0x03, + 0x13,0x05,0x02,0x06,0xA1,0x05,0x63,0x00,0x02,0x02,0x87,0x07, + 0xCF,0xFF,0x29,0xFD,0x12,0xFE,0x83,0x02,0x44,0xFF,0x4C,0xF9, + 0x84,0xFA,0xB7,0xFF,0xAC,0xFC,0xD1,0xFA,0xFC,0xF9,0xFF,0xFD, + 0x86,0xFE,0x74,0xFC,0x7F,0xFE,0x14,0xFF,0x34,0x00,0x04,0x01, + 0x30,0x01,0x92,0x01,0x07,0x01,0xF4,0x00,0x52,0x03,0xDD,0x01, + 0x4A,0xFF,0x0C,0x00,0x78,0x00,0x88,0x00,0x48,0xFD,0x62,0xFD, + 0x4B,0xFF,0x35,0xFE,0xB6,0xFC,0x0D,0xFD,0x4E,0xFE,0xDB,0xFE, + 0x83,0xFD,0xD8,0xFE,0x01,0x00,0xE4,0xFF,0x7D,0x00,0x31,0x01, + 0x24,0x02,0x2A,0x02,0x59,0x02,0x67,0x04,0x93,0x04,0x0D,0x05, + 0x14,0x06,0xD9,0x05,0x21,0x01,0x0A,0x02,0x1C,0x06,0xBE,0x02, + 0x96,0xFE,0xA7,0xFC,0x09,0x00,0xC8,0x01,0x23,0xFB,0xDD,0xF9, + 0x82,0xFC,0x57,0xFE,0xCE,0xFC,0x52,0xFA,0x9A,0xFB,0x14,0xFF, + 0x14,0xFE,0x7F,0xFF,0x95,0xFF,0x1F,0x00,0x20,0x01,0x34,0x02, + 0x32,0x03,0x57,0x02,0xA2,0x00,0xA3,0x02,0xBE,0x02,0xCD,0x00, + 0x2E,0xFF,0x22,0xFF,0x19,0x00,0x9A,0xFE,0x26,0xFD,0xE4,0xFD, + 0xDB,0xFD,0x86,0xFD,0x66,0xFD,0x13,0xFE,0xD7,0xFE,0x58,0xFE, + 0x19,0xFF,0xD1,0x00,0xD5,0x00,0xE7,0x00,0x45,0x01,0x1A,0x03, + 0x50,0x03,0xF5,0x02,0xB7,0x03,0x3D,0x05,0x65,0x06,0xBA,0x06, + 0x68,0x04,0x14,0xFF,0x56,0x04,0x61,0x05,0x87,0x01,0x24,0xFD, + 0xD9,0xFC,0x77,0x00,0x3D,0x00,0x7C,0xFB,0xD9,0xFA,0x08,0xFC, + 0x41,0xFD,0x95,0xFD,0x1B,0xFC,0xF0,0xFD,0x73,0xFD,0xD5,0xFE, + 0x29,0x01,0xFB,0x00,0x13,0x01,0x42,0x00,0xEC,0x01,0xD6,0x03, + 0xCC,0x02,0xBC,0x00,0x61,0x00,0xBA,0x00,0xFA,0x00,0x8F,0xFF, + 0x83,0xFE,0x17,0xFE,0x74,0xFD,0xE7,0xFD,0x21,0xFE,0xCE,0xFD, + 0x59,0xFD,0x4E,0xFD,0xDC,0xFE,0xD6,0xFF,0x7D,0xFF,0x8B,0xFF, + 0x3F,0x00,0x94,0x01,0xE8,0x01,0x93,0x01,0x4E,0x02,0xEB,0x02, + 0x68,0x03,0xF1,0x03,0xCE,0x04,0x4A,0x06,0x05,0x06,0xC1,0x00, + 0x40,0x00,0x33,0x04,0xBA,0x02,0x57,0x01,0xB1,0xFB,0x17,0xFE, + 0x43,0x00,0x73,0xFE,0xD3,0xFC,0x4A,0xFC,0xA1,0xFC,0xAB,0xFD, + 0xEB,0xFC,0x50,0xFE,0x56,0xFF,0xCB,0xFD,0xE3,0xFE,0x62,0x00, + 0x96,0x02,0x9D,0x02,0x49,0x00,0xD4,0x00,0x16,0x02,0x08,0x02, + 0x25,0x01,0x84,0xFF,0x3A,0xFF,0x79,0xFF,0x81,0xFE,0x23,0xFF, + 0x8E,0xFE,0x08,0xFE,0x98,0xFD,0xDC,0xFD,0x75,0xFF,0xB0,0xFF, + 0xA6,0xFE,0x09,0xFF,0xFB,0xFF,0x72,0x00,0xD0,0x00,0x90,0x00, + 0x67,0x01,0x34,0x01,0x5B,0x01,0x56,0x02,0xF8,0x02,0x5E,0x03, + 0xBF,0x03,0x8D,0x04,0x27,0x04,0x24,0x00,0x04,0x00,0x46,0x02, + 0xE7,0x01,0xE7,0x00,0x5D,0xFE,0x5C,0xFE,0xE2,0xFE,0x0C,0xFE, + 0xE6,0xFD,0xCB,0xFD,0x8E,0xFD,0xCE,0xFD,0x01,0xFD,0xEA,0xFD, + 0xE3,0xFF,0x3A,0xFF,0x7B,0xFF,0x59,0xFF,0x58,0x00,0x51,0x01, + 0xC4,0x00,0x87,0x00,0xC9,0x00,0x44,0x00,0x06,0x00,0x9D,0xFF, + 0x47,0xFF,0xBD,0xFF,0x26,0xFF,0xE0,0xFE,0xF2,0xFE,0x46,0xFF, + 0x5E,0xFF,0xE9,0xFE,0x11,0xFF,0x92,0xFF,0x7A,0xFF,0x77,0xFF, + 0x99,0xFF,0xFA,0xFF,0x65,0x00,0xFD,0xFF,0x53,0x00,0xD0,0x00, + 0xE0,0x00,0x0B,0x01,0x6E,0x01,0x42,0x02,0x2D,0x03,0x5A,0x03, + 0x36,0x02,0x6A,0x00,0xEE,0x00,0x3C,0x01,0xA8,0x01,0xEE,0x00, + 0x6B,0xFF,0x5B,0xFF,0xFA,0xFE,0x3B,0xFE,0x2A,0xFE,0x75,0xFE, + 0xBE,0xFE,0x6A,0xFE,0x2E,0xFD,0x7E,0xFD,0xDF,0xFE,0x34,0xFF, + 0x0E,0xFF,0xF4,0xFE,0x54,0xFF,0xC5,0xFF,0x75,0xFF,0x83,0xFF, + 0xFF,0xFF,0xF9,0xFF,0x56,0xFF,0xB0,0xFE,0xF5,0xFE,0xAA,0xFF, + 0x5D,0xFF,0x35,0xFF,0x40,0xFF,0x90,0xFF,0x6C,0xFF,0xE2,0xFE, + 0xD3,0xFE,0x7B,0xFF,0x8A,0xFF,0x2C,0xFF,0x09,0xFF,0x43,0xFF, + 0xB0,0xFF,0x8C,0xFF,0x75,0xFF,0x94,0xFF,0xD0,0xFF,0x92,0x00, + 0x80,0x00,0xFB,0x00,0xD1,0x01,0x59,0x02,0x74,0x02,0xE2,0x00, + 0x41,0x00,0xE3,0x00,0x09,0x01,0x1C,0x01,0x4C,0x00,0xF3,0xFF, + 0x90,0xFF,0x30,0xFF,0x5D,0xFE,0x8F,0xFE,0xEC,0xFE,0x24,0xFF, + 0x79,0xFE,0xB7,0xFD,0x70,0xFE,0xCC,0xFE,0x1E,0xFF,0x01,0xFF, + 0xFF,0xFE,0x46,0xFF,0x65,0xFF,0xE2,0xFE,0x35,0xFF,0x80,0xFF, + 0x97,0xFF,0x4D,0xFF,0xDB,0xFE,0x36,0xFF,0xAD,0xFF,0x90,0xFF, + 0x78,0xFF,0x7F,0xFF,0x9B,0xFF,0x80,0xFF,0xFB,0xFE,0x0E,0xFF, + 0x3D,0xFF,0x50,0xFF,0x33,0xFF,0x23,0xFF,0x51,0xFF,0x86,0xFF, + 0x6B,0xFF,0xB5,0xFF,0xD6,0xFF,0x2A,0x00,0x91,0x00,0xB4,0x00, + 0x2E,0x01,0xEB,0x01,0x0B,0x02,0xC9,0x00,0x4B,0x00,0x66,0x00, + 0xE8,0x00,0x21,0x01,0x97,0x00,0x0A,0x00,0xEC,0xFF,0x64,0xFF, + 0xF5,0xFE,0xB2,0xFE,0xDF,0xFE,0x61,0xFF,0x3A,0xFF,0x43,0xFE, + 0x36,0xFE,0xAB,0xFE,0x10,0xFF,0x32,0xFF,0xF1,0xFE,0x1A,0xFF, + 0x61,0xFF,0x41,0xFF,0x02,0xFF,0xF6,0xFE,0x30,0xFF,0x44,0xFF, + 0x02,0xFF,0x23,0xFF,0x6E,0xFF,0xAF,0xFF,0x8E,0xFF,0x59,0xFF, + 0x87,0xFF,0x9B,0xFF,0x21,0xFF,0x11,0xFF,0x8C,0xFF,0x68,0xFF, + 0x66,0xFF,0x83,0xFF,0x5F,0xFF,0x66,0xFF,0xE2,0xFF,0xC9,0xFF, + 0x0F,0x00,0x35,0x00,0x99,0x00,0x50,0x01,0xE5,0x01,0x15,0x02, + 0x6E,0x01,0x46,0x00,0x1A,0x00,0x4D,0x00,0x0F,0x01,0xE3,0x00, + 0x0D,0x00,0xCC,0xFF,0x8F,0xFF,0x33,0xFF,0xF1,0xFE,0xDB,0xFE, + 0x2B,0xFF,0x8C,0xFF,0xC4,0xFE,0x6F,0xFE,0x6E,0xFE,0x12,0xFF, + 0x68,0xFF,0x4F,0xFF,0x2D,0xFF,0x67,0xFF,0x86,0xFF,0x4D,0xFF, + 0x25,0xFF,0x05,0xFF,0x65,0xFF,0x8D,0xFF,0x63,0xFF,0x6D,0xFF, + 0xA0,0xFF,0xB2,0xFF,0xE8,0xFF,0x76,0xFF,0x77,0xFF,0xD3,0xFF, + 0xC3,0xFF,0x8E,0xFF,0x78,0xFF,0xE2,0xFF,0x3D,0x00,0xDB,0xFF, + 0xE8,0xFF,0x69,0x00,0x49,0x00,0xA8,0x00,0xDE,0x00,0x7C,0x01, + 0xFA,0x01,0x40,0x02,0xD8,0x01,0x79,0x00,0x11,0x00,0x27,0x00, + 0xDF,0x00,0x0E,0x01,0x71,0x00,0xB2,0xFF,0x85,0xFF,0x4C,0xFF, + 0xF9,0xFE,0xEA,0xFE,0x38,0xFF,0xC1,0xFF,0x5E,0xFF,0x02,0xFF, + 0x92,0xFE,0xE8,0xFE,0x97,0xFF,0xF5,0xFF,0xE3,0xFF,0x74,0xFF, + 0x47,0xFF,0x44,0xFF,0x42,0xFF,0xE7,0xFE,0x1C,0xFF,0x6A,0xFF, + 0xBD,0xFF,0xA0,0xFF,0x62,0xFF,0x7D,0xFF,0x06,0x00,0xE7,0xFF, + 0xAC,0xFF,0xC7,0xFF,0x8D,0xFF,0x0F,0x00,0x3D,0x00,0xEF,0xFF, + 0x34,0x00,0xBC,0x00,0x89,0x00,0x95,0x00,0xC0,0x00,0x4B,0x01, + 0xFD,0x01,0x46,0x02,0x8D,0x02,0xA3,0x01,0x32,0x00,0xF8,0xFF, + 0xBD,0xFF,0x62,0x00,0xD9,0x00,0xE8,0xFF,0x7F,0xFF,0x10,0xFF, + 0xAB,0xFE,0xC8,0xFE,0xD7,0xFE,0x0A,0xFF,0xC8,0xFF,0x79,0xFF, + 0x30,0xFF,0x02,0xFF,0xE3,0xFE,0xC1,0xFF,0x71,0x00,0x34,0x00, + 0x9B,0xFF,0x1E,0xFF,0xB2,0xFE,0xC1,0xFE,0xE2,0xFE,0x7C,0xFF, + 0x99,0xFF,0xD8,0xFF,0x6D,0xFF,0xEE,0xFE,0xD0,0xFE,0xB3,0xFF, + 0xEE,0xFF,0x93,0xFF,0x0C,0x00,0x48,0x00,0x87,0x00,0x9B,0x00, + 0x71,0x00,0xD1,0x00,0x25,0x01,0x60,0x01,0x7F,0x01,0xD4,0x01, + 0x44,0x02,0x39,0x03,0x8C,0x02,0x08,0x01,0x8F,0xFF,0x31,0xFF, + 0x08,0x00,0x88,0x00,0x17,0x00,0x79,0xFF,0xF7,0xFE,0x7F,0xFE, + 0x3F,0xFE,0x4B,0xFE,0xD1,0xFE,0xE6,0xFF,0x84,0x00,0xA3,0xFF, + 0xC8,0xFE,0xB7,0xFE,0xAB,0xFF,0xE5,0x00,0x23,0x00,0xB0,0xFF, + 0xEB,0xFE,0x4C,0xFE,0xD8,0xFE,0xF3,0xFE,0xEB,0xFE,0x84,0xFF, + 0x7B,0xFF,0x5F,0xFF,0x4C,0xFF,0x10,0xFF,0xBA,0xFF,0x8F,0x00, + 0x9F,0x00,0x86,0x00,0x48,0x00,0xE0,0x00,0x1E,0x01,0x08,0x01, + 0x83,0x01,0xC5,0x01,0x04,0x02,0x91,0x02,0xE4,0x02,0x84,0x03, + 0x2B,0x02,0xD8,0xFF,0xD3,0xFE,0xEF,0xFE,0xD5,0xFF,0x55,0x00, + 0x9B,0xFF,0xEC,0xFE,0xDA,0xFE,0x44,0xFE,0xF8,0xFD,0x0D,0xFE, + 0xAA,0xFE,0x5E,0x00,0x4F,0x00,0x95,0xFF,0xFE,0xFE,0xD1,0xFE, + 0xF0,0xFF,0x42,0x00,0xD1,0xFF,0x41,0xFF,0xF7,0xFE,0xA8,0xFE, + 0xA4,0xFE,0x60,0xFE,0x0F,0xFF,0xA0,0xFF,0xC5,0xFF,0x2A,0xFF, + 0xE7,0xFE,0x3C,0xFF,0x94,0x00,0xFF,0x00,0xEE,0x00,0x15,0x01, + 0x13,0x01,0x3D,0x01,0x1D,0x01,0xA2,0x01,0xAE,0x02,0x59,0x03, + 0xE5,0x03,0xF0,0x03,0xB6,0x00,0x77,0xFE,0x16,0xFE,0xC3,0xFE, + 0x5A,0x00,0x54,0x00,0xB0,0xFE,0x15,0xFE,0x69,0xFD,0x1C,0xFD, + 0x5F,0xFD,0x14,0xFE,0xE9,0xFF,0xE0,0x00,0xFF,0xFF,0xC7,0xFE, + 0x31,0xFE,0x71,0xFE,0xBE,0xFF,0x35,0x00,0xC9,0xFF,0x73,0xFF, + 0xCC,0xFE,0xE9,0xFD,0xB7,0xFD,0xFE,0xFD,0x33,0xFF,0xC1,0xFF, + 0x14,0xFF,0xD5,0xFE,0xD3,0xFE,0x9E,0xFF,0x64,0x00,0xF0,0x00, + 0x64,0x01,0xF4,0x01,0x96,0x01,0x6C,0x01,0xBF,0x01,0xA1,0x02, + 0x19,0x04,0x1B,0x05,0x5C,0x04,0xA5,0x00,0x51,0xFE,0xB8,0xFD, + 0x92,0xFE,0xE0,0xFF,0x59,0xFF,0x32,0xFF,0x6C,0xFE,0x6B,0xFD, + 0x53,0xFC,0x78,0xFC,0xD9,0xFD,0x6B,0x00,0x27,0x01,0xC8,0xFF, + 0xC3,0xFE,0xC2,0xFD,0xA1,0xFE,0xEE,0xFF,0x7B,0x00,0xF0,0x00, + 0xA4,0x00,0x3B,0xFF,0x3C,0xFE,0x7C,0xFD,0x10,0xFE,0xCE,0xFF, + 0x2C,0x00,0x21,0x00,0x8E,0xFF,0x37,0xFF,0x96,0xFF,0x40,0x00, + 0x39,0x01,0x36,0x02,0x81,0x02,0x37,0x02,0x03,0x02,0x10,0x02, + 0x6E,0x03,0xB4,0x04,0xFA,0x03,0xCC,0x00,0xEE,0xFE,0x97,0xFE, + 0x06,0xFF,0xAA,0xFF,0xDF,0xFE,0x00,0xFF,0x12,0xFF,0x07,0xFE, + 0xEA,0xFC,0x9C,0xFC,0x89,0xFD,0x02,0x00,0x9C,0x00,0xD0,0xFF, + 0xA2,0xFE,0x1F,0xFE,0x62,0xFF,0x0F,0x00,0x8F,0x00,0xEF,0x00, + 0xD0,0x00,0xB7,0xFF,0x08,0xFF,0x2B,0xFE,0xE7,0xFE,0x64,0x00, + 0x9B,0x00,0x75,0x00,0xEF,0xFF,0x96,0xFF,0xE4,0xFF,0x39,0x00, + 0xFF,0x00,0x01,0x02,0x45,0x02,0x21,0x02,0xF4,0x01,0xC8,0x01, + 0x35,0x02,0x16,0x03,0x56,0x01,0x22,0x00,0xD5,0xFF,0x69,0xFF, + 0xCE,0xFF,0xFA,0xFE,0x61,0xFE,0xFA,0xFE,0xE7,0xFE,0x30,0xFE, + 0x49,0xFE,0x22,0xFE,0x57,0xFF,0x45,0x00,0xC8,0xFF,0x19,0xFF, + 0xE4,0xFE,0x62,0xFF,0xCF,0xFF,0x0E,0x00,0x05,0x00,0x51,0x00, + 0xC7,0xFF,0x4F,0xFF,0xF8,0xFE,0x18,0xFF,0x27,0x00,0x92,0x00, + 0x71,0x00,0x62,0x00,0x39,0x00,0x24,0x00,0x3F,0x00,0x6F,0x00, + 0x06,0x01,0x54,0x01,0x26,0x01,0xD4,0x00,0xA6,0x00,0xC2,0x00, + 0x47,0x01,0x9B,0x01,0x58,0x01,0xD4,0x00,0x14,0x00,0xAE,0xFF, + 0xBE,0xFF,0xF7,0xFF,0x04,0x00,0x2A,0x00,0xDE,0xFF,0x6E,0xFF, + 0xC3,0xFE,0x8A,0xFE,0xE2,0xFE,0x49,0xFF,0xA3,0xFF,0x33,0xFF, + 0xE1,0xFE,0xAE,0xFE,0xCE,0xFE,0x2C,0xFF,0x8D,0xFF,0xF5,0xFF, + 0x03,0x00,0xD0,0xFF,0x6A,0xFF,0x5B,0xFF,0x8E,0xFF,0x14,0x00, + 0x75,0x00,0x8A,0x00,0x7D,0x00,0x27,0x00,0xEB,0xFF,0xD3,0xFF, + 0xF3,0xFF,0x58,0x00,0x92,0x00,0x72,0x00,0x3E,0x00,0xF6,0xFF, + 0xC7,0xFF,0xDB,0xFF,0xFB,0xFF,0x30,0x00,0x54,0x00,0x2E,0x00, + 0xFD,0xFF,0xBE,0xFF,0xB9,0xFF,0xD5,0xFF,0xFC,0xFF,0x07,0x00, + 0xF8,0xFF,0xD1,0xFF,0xA3,0xFF,0x77,0xFF,0x6D,0xFF,0x71,0xFF, + 0x85,0xFF,0x81,0xFF,0x52,0xFF,0x30,0xFF,0x12,0xFF,0x14,0xFF, + 0x37,0xFF,0x47,0xFF,0x68,0xFF,0x77,0xFF,0x77,0xFF,0x8B,0xFF, + 0x8C,0xFF,0x9C,0xFF,0xBD,0xFF,0xD8,0xFF,0xFB,0xFF,0x04,0x00, + 0xEF,0xFF,0xE6,0xFF,0xD9,0xFF,0xDA,0xFF,0xE5,0xFF,0xD9,0xFF, + 0xD2,0xFF,0xD0,0xFF,0xB1,0xFF,0x8C,0xFF,0x75,0xFF,0x6F,0xFF, + 0x7D,0xFF,0x7C,0xFF,0x75,0xFF,0x76,0xFF,0x63,0xFF,0x56,0xFF, + 0x62,0xFF,0x6F,0xFF,0x7B,0xFF,0x90,0xFF,0x8F,0xFF,0x80,0xFF, + 0x81,0xFF,0x7E,0xFF,0x96,0xFF,0x96,0xFF,0x94,0xFF,0x99,0xFF, + 0x7F,0xFF,0x67,0xFF,0x61,0xFF,0x66,0xFF,0x74,0xFF,0x6D,0xFF, + 0x6C,0xFF,0x68,0xFF,0x58,0xFF,0x56,0xFF,0x5E,0xFF,0x61,0xFF, + 0x68,0xFF,0x77,0xFF,0x71,0xFF,0x66,0xFF,0x64,0xFF,0x65,0xFF, + 0x77,0xFF,0x83,0xFF,0x82,0xFF,0x7A,0xFF,0x70,0xFF,0x64,0xFF, + 0x5B,0xFF,0x5A,0xFF,0x61,0xFF,0x75,0xFF,0x6A,0xFF,0x62,0xFF, + 0x5F,0xFF,0x64,0xFF,0x65,0xFF,0x7B,0xFF,0x95,0xFF,0x9B,0xFF, + 0x93,0xFF,0x8F,0xFF,0x93,0xFF,0x95,0xFF,0xA3,0xFF,0xA4,0xFF, + 0xAA,0xFF,0xA0,0xFF,0x93,0xFF,0x8A,0xFF,0x90,0xFF,0x89,0xFF, + 0x9B,0xFF,0x9A,0xFF,0x93,0xFF,0x96,0xFF,0x96,0xFF,0x8E,0xFF, + 0xA5,0xFF,0xA7,0xFF,0xB3,0xFF,0xC4,0xFF,0xB1,0xFF,0xC1,0xFF, + 0xD0,0xFF,0xE0,0xFF,0xD7,0xFF,0xCD,0xFF,0xE1,0xFF,0xF0,0xFF, + 0xE2,0xFF,0xE5,0xFF,0xDD,0xFF,0xE7,0xFF,0xEA,0xFF,0xED,0xFF, + 0xE3,0xFF,0xD5,0xFF,0xE7,0xFF,0xE2,0xFF,0xE2,0xFF,0xE9,0xFF, + 0xEF,0xFF,0x0A,0x00,0x03,0x00,0x10,0x00,0x0D,0x00,0x0D,0x00, + 0x0D,0x00,0x0F,0x00,0x10,0x00,0x0B,0x00,0x0F,0x00,0x05,0x00, + 0x03,0x00,0x06,0x00,0x01,0x00,0x07,0x00,0xF3,0xFF,0xFD,0xFF, + 0xF8,0xFF,0xFC,0xFF,0x03,0x00,0x0A,0x00,0x11,0x00,0x1E,0x00, + 0x1E,0x00,0x21,0x00,0x1F,0x00,0x17,0x00,0x1B,0x00,0x1D,0x00, + 0x1C,0x00,0x14,0x00,0x11,0x00,0x0B,0x00,0x0C,0x00,0x09,0x00, + 0x03,0x00,0xFF,0xFF,0x08,0x00,0x0C,0x00,0x06,0x00,0x0B,0x00, + 0x16,0x00,0x16,0x00,0x25,0x00,0x1E,0x00,0x2A,0x00,0x30,0x00, + 0x32,0x00,0x29,0x00,0x2C,0x00,0x29,0x00,0x22,0x00,0x23,0x00, + 0x1E,0x00,0x15,0x00,0x17,0x00,0x18,0x00,0x0B,0x00,0x09,0x00, + 0x17,0x00,0x17,0x00,0x1A,0x00,0x1F,0x00,0x25,0x00,0x2D,0x00, + 0x34,0x00,0x39,0x00,0x3C,0x00,0x35,0x00,0x3C,0x00,0x42,0x00, + 0x39,0x00,0x32,0x00,0x32,0x00,0x33,0x00,0x30,0x00,0x2D,0x00, + 0x29,0x00,0x16,0x00,0x18,0x00,0x27,0x00,0x21,0x00,0x25,0x00, + 0x2A,0x00,0x33,0x00,0x34,0x00,0x2E,0x00,0x32,0x00,0x42,0x00, + 0x45,0x00,0x38,0x00,0x30,0x00,0x35,0x00,0x27,0x00,0x31,0x00, + 0x35,0x00,0x2A,0x00,0x25,0x00,0x20,0x00,0x22,0x00,0x17,0x00, + 0x1D,0x00,0x1D,0x00,0x20,0x00,0x23,0x00,0x1E,0x00,0x28,0x00, + 0x23,0x00,0x2A,0x00,0x3D,0x00,0x39,0x00,0x40,0x00,0x43,0x00, + 0x36,0x00,0x33,0x00,0x36,0x00,0x3E,0x00,0x36,0x00,0x2B,0x00, + 0x31,0x00,0x28,0x00,0x1F,0x00,0x22,0x00,0x1F,0x00,0x1D,0x00, + 0x1D,0x00,0x23,0x00,0x25,0x00,0x1F,0x00,0x19,0x00,0x23,0x00, + 0x1E,0x00,0x1B,0x00,0x1B,0x00,0x1B,0x00,0x09,0x00,0x10,0x00, + 0x09,0x00,0xF7,0xFF,0xED,0xFF,0xF9,0xFF,0xF7,0xFF,0xEC,0xFF, + 0xEB,0xFF,0xE7,0xFF,0xEB,0xFF,0xE7,0xFF,0xEA,0xFF,0xF6,0xFF, + 0xEB,0xFF,0xF2,0xFF,0xF8,0xFF,0xF4,0xFF,0xF3,0xFF,0xF8,0xFF, + 0xF4,0xFF,0xEF,0xFF,0xF2,0xFF,0xE3,0xFF,0xE0,0xFF,0xDE,0xFF, + 0xE6,0xFF,0xD4,0xFF,0xD1,0xFF,0xCB,0xFF,0xCE,0xFF,0xC8,0xFF, + 0xCD,0xFF,0xD4,0xFF,0xE2,0xFF,0xD1,0xFF,0xD2,0xFF,0xDC,0xFF, + 0xE3,0xFF,0xDA,0xFF,0xD2,0xFF,0xD2,0xFF,0xD6,0xFF,0xCA,0xFF, + 0xC9,0xFF,0xBD,0xFF,0xBB,0xFF,0xBA,0xFF,0xC1,0xFF,0xB7,0xFF, + 0xB2,0xFF,0xB4,0xFF,0xB7,0xFF,0xA9,0xFF,0xAF,0xFF,0xB6,0xFF, + 0xB9,0xFF,0xB0,0xFF,0xB0,0xFF,0xB2,0xFF,0xC1,0xFF,0xBB,0xFF, + 0xBE,0xFF,0xB5,0xFF,0xB0,0xFF,0xB7,0xFF,0xAE,0xFF,0xA5,0xFF, + 0xA9,0xFF,0xA4,0xFF,0xA4,0xFF,0xA2,0xFF,0xA4,0xFF,0xA3,0xFF, + 0xAB,0xFF,0xB7,0xFF,0xC0,0xFF,0xB8,0xFF,0xBB,0xFF,0xB8,0xFF, + 0xC0,0xFF,0xB8,0xFF,0xB9,0xFF,0x9D,0xFF,0xB2,0xFF,0x8D,0xFF, + 0xA2,0xFF,0x79,0xFF,0x93,0xFF,0x77,0xFF,0x91,0xFF,0x7F,0xFF, + 0x7F,0xFF,0x86,0xFF,0x7C,0xFF,0x81,0xFF,0x7F,0xFF,0x88,0xFF, + 0x76,0xFF,0x83,0xFF,0x90,0xFF,0x92,0xFF,0x9D,0xFF,0xA2,0xFF, + 0xA6,0xFF,0xAA,0xFF,0xA6,0xFF,0xAE,0xFF,0xA7,0xFF,0xA2,0xFF, + 0x9F,0xFF,0xAB,0xFF,0xA5,0xFF,0x9B,0xFF,0x9E,0xFF,0x9D,0xFF, + 0xA4,0xFF,0xA7,0xFF,0xB4,0xFF,0xAE,0xFF,0xBC,0xFF,0xC7,0xFF, + 0xBA,0xFF,0xBE,0xFF,0xC7,0xFF,0xBF,0xFF,0xBD,0xFF,0xBD,0xFF, + 0xB4,0xFF,0xB7,0xFF,0xB7,0xFF,0xBB,0xFF,0xC4,0xFF,0xBD,0xFF, + 0xB9,0xFF,0xB3,0xFF,0xBC,0xFF,0xBB,0xFF,0xC9,0xFF,0xC8,0xFF, + 0xC5,0xFF,0xCB,0xFF,0xD9,0xFF,0xD0,0xFF,0xD3,0xFF,0xD2,0xFF, + 0xD6,0xFF,0xD6,0xFF,0xD7,0xFF,0xD7,0xFF,0xD0,0xFF,0xCF,0xFF, + 0xD2,0xFF,0xD0,0xFF,0xD5,0xFF,0xCD,0xFF,0xCD,0xFF,0xCC,0xFF, + 0xD7,0xFF,0xD5,0xFF,0xD5,0xFF,0xD2,0xFF,0xD6,0xFF,0xDD,0xFF, + 0xDF,0xFF,0xD6,0xFF,0xDE,0xFF,0xE4,0xFF,0xD1,0xFF,0xD9,0xFF, + 0xE3,0xFF,0xD7,0xFF,0xDA,0xFF,0xD2,0xFF,0xD5,0xFF,0xD8,0xFF, + 0xCC,0xFF,0xC6,0xFF,0xD2,0xFF,0xD0,0xFF,0xCF,0xFF,0xD5,0xFF, + 0xD7,0xFF,0xD6,0xFF,0xD6,0xFF,0xE6,0xFF,0xDD,0xFF,0xD1,0xFF, + 0xD5,0xFF,0xD8,0xFF,0xD9,0xFF,0xCE,0xFF,0xD2,0xFF,0xD1,0xFF, + 0xCD,0xFF,0xD5,0xFF,0xD4,0xFF,0xC6,0xFF,0xB7,0xFF,0xCD,0xFF, + 0xD2,0xFF,0xD7,0xFF,0xD8,0xFF,0xDC,0xFF,0xDF,0xFF,0xE1,0xFF, + 0xE7,0xFF,0xEC,0xFF,0xDE,0xFF,0xE2,0xFF,0xDD,0xFF,0xDE,0xFF, + 0xDE,0xFF,0xE3,0xFF,0xDD,0xFF,0xD7,0xFF,0xD8,0xFF,0xE0,0xFF, + 0xD9,0xFF,0xD1,0xFF,0xD7,0xFF,0xE9,0xFF,0xDD,0xFF,0xE0,0xFF, + 0xE2,0xFF,0xE6,0xFF,0xE2,0xFF,0xE0,0xFF,0xED,0xFF,0xED,0xFF, + 0xE6,0xFF,0xE8,0xFF,0xEA,0xFF,0xEB,0xFF,0xE6,0xFF,0xE8,0xFF, + 0xDE,0xFF,0xD8,0xFF,0xD7,0xFF,0xD3,0xFF,0xD0,0xFF,0xB7,0xFF, + 0xC5,0xFF,0x79,0xFF,0xFA,0xFE,0x06,0xFF,0x7B,0xFF,0x3B,0x00, + 0xC1,0x00,0x00,0x01,0xE6,0x00,0x5B,0x00,0xB3,0xFF,0x7C,0xFF, + 0x97,0xFF,0x0D,0x00,0x58,0x00,0x87,0x00,0x61,0x00,0x04,0x00, + 0x9C,0xFF,0x2D,0xFF,0x74,0xFF,0xA7,0xFF,0x2E,0x00,0x39,0x00, + 0x40,0x00,0x00,0x00,0xC3,0xFF,0x84,0xFF,0x99,0xFF,0xD6,0xFF, + 0x36,0x00,0x76,0x00,0x75,0x00,0x46,0x00,0x00,0x00,0xD7,0xFF, + 0xB1,0xFF,0xEA,0xFF,0xFE,0xFF,0x34,0x00,0x2B,0x00,0x1D,0x00, + 0x15,0x00,0xBD,0xFF,0xEA,0xFF,0x95,0xFF,0xC2,0xFF,0x30,0x00, + 0x1E,0x00,0x25,0x00,0xD5,0xFF,0xCF,0xFF,0xA0,0xFF,0xDB,0xFF, + 0x09,0x00,0xFE,0xFF,0x22,0x00,0x01,0x00,0x1E,0x00,0x1C,0x00, + 0xEC,0xFF,0x04,0x00,0xF5,0xFF,0x31,0x00,0x62,0x00,0x69,0x00, + 0x3F,0x00,0x08,0x00,0xC2,0xFF,0xC1,0xFF,0xDA,0xFF,0xD9,0xFF, + 0x76,0x00,0x4A,0x00,0x47,0x00,0xD1,0xFF,0xA2,0xFF,0xC8,0xFF, + 0xB5,0xFF,0x0D,0x00,0x33,0x00,0x6C,0x00,0x30,0x00,0x1D,0x00, + 0xD3,0xFF,0xEA,0xFF,0xC9,0xFF,0x07,0x00,0x5E,0x00,0x48,0x00, + 0x53,0x00,0xA4,0xFF,0x41,0xFF,0xD9,0xFE,0x07,0xFF,0x97,0xFF, + 0x3B,0x00,0xFF,0x00,0x1A,0x01,0xAC,0x00,0x2C,0x00,0xEF,0xFF, + 0x91,0xFF,0x8E,0xFF,0xD5,0xFF,0x65,0x00,0x82,0xFF,0x5F,0xFF, + 0xBC,0xFE,0x3C,0xFF,0x9A,0xFF,0xD7,0x00,0x7B,0x01,0xFB,0x01, + 0xA3,0x01,0xA5,0x00,0x9A,0xFF,0x7A,0xFE,0x29,0xFF,0x91,0xFF, + 0xEE,0x00,0x8B,0x01,0x5E,0x02,0xB0,0x02,0xA0,0xFE,0x52,0xFC, + 0xDE,0xFA,0x47,0xFC,0xF8,0xFD,0xAA,0x01,0xC8,0x02,0x5C,0x03, + 0xA8,0x01,0xDD,0xFF,0xAD,0xFD,0x1B,0xFD,0x9B,0xFD,0x07,0x00, + 0x80,0x01,0x54,0x02,0x55,0x01,0x5C,0x00,0x6E,0xFE,0xBF,0xFD, + 0xA7,0xFD,0xCB,0xFE,0x18,0x00,0x41,0x01,0xD6,0x01,0xDA,0x01, + 0xC3,0xFF,0x00,0x00,0x20,0xFE,0x48,0xFE,0x86,0xFD,0x74,0xFE, + 0x63,0xFF,0x57,0x01,0x63,0x01,0xEE,0x01,0xC6,0x00,0x34,0x00, + 0xE3,0xFE,0x6D,0xFF,0x75,0xFE,0xF0,0xFF,0x73,0x00,0xA5,0x01, + 0xCA,0x00,0xDD,0x00,0x94,0xFF,0x6D,0xFF,0x78,0xFE,0x0B,0xFF, + 0xB9,0xFF,0x9B,0x00,0x80,0x00,0xD1,0x00,0xF4,0xFF,0x29,0xFF, + 0x97,0xFE,0xE6,0xFE,0x49,0xFF,0xF0,0xFF,0x47,0x00,0x8C,0x00, + 0x6D,0x00,0xB5,0xFF,0x5B,0xFF,0x10,0xFF,0x42,0xFF,0x95,0xFF, + 0x0E,0x00,0x76,0x00,0xA0,0x00,0x1A,0x00,0xDB,0xFF,0x7E,0xFF, + 0x50,0xFF,0x74,0xFF,0xDB,0xFF,0x11,0x00,0x70,0x00,0x44,0x00, + 0x4A,0x00,0xC2,0xFF,0xAD,0xFF,0x2A,0xFF,0x96,0xFF,0x83,0xFF, + 0xF5,0xFF,0xF7,0xFF,0x32,0x00,0x38,0x00,0x50,0x00,0x08,0x00, + 0x23,0x00,0xC1,0xFF,0xFB,0xFF,0xAE,0xFF,0x07,0x00,0xBA,0xFF, + 0x27,0x00,0xFD,0xFF,0x08,0x00,0xD3,0xFF,0xD1,0xFF,0xD7,0xFF, + 0x11,0x00,0xFB,0xFF,0x3B,0x00,0xF5,0xFF,0xEF,0xFF,0xD4,0xFF, + 0xDF,0xFF,0xA1,0xFF,0xCD,0xFF,0xD5,0xFF,0x28,0x00,0x48,0x00, + 0x1B,0x00,0x00,0x00,0xF9,0xFF,0x05,0x00,0xCC,0xFF,0xED,0xFF, + 0xDF,0xFF,0x3F,0x00,0x2C,0x00,0x6A,0x00,0x3D,0x00,0x23,0x00, + 0xFE,0xFF,0x09,0x00,0x06,0x00,0x42,0x00,0x8A,0x00,0xAA,0x00, + 0xA7,0x00,0x75,0x00,0x4C,0x00,0xFC,0xFF,0xF7,0xFF,0xD7,0xFF, + 0x0F,0x00,0x2A,0x00,0xA7,0x00,0xCA,0x00,0xC9,0x00,0xAE,0x00, + 0x7D,0x00,0x63,0x00,0x2E,0x00,0xF6,0xFF,0xEC,0xFF,0xFC,0xFF, + 0x2D,0x00,0x79,0x00,0x77,0x00,0x9F,0x00,0xA1,0x00,0x31,0x00, + 0xED,0xFF,0xD3,0xFF,0xDE,0xFF,0x10,0x00,0x78,0x00,0xBF,0x00, + 0xF6,0x00,0xC2,0x00,0x82,0x00,0x1C,0x00,0xB1,0xFF,0xBB,0xFF, + 0xC2,0xFF,0x57,0x00,0x87,0x00,0xDC,0x00,0x98,0x00,0x5C,0x00, + 0xE8,0xFF,0x50,0xFF,0x0E,0xFF,0x6A,0xFF,0xB4,0xFF,0x3A,0x00, + 0xDC,0x00,0xC0,0x00,0x79,0x00,0xA2,0xFF,0x3F,0xFF,0x04,0xFF, + 0x3E,0xFF,0x9C,0xFF,0x22,0x00,0x47,0x00,0x36,0x00,0x15,0x00, + 0xB1,0xFF,0xB6,0xFF,0x67,0xFF,0xAA,0xFF,0xB4,0xFF,0x0A,0x00, + 0x01,0x00,0x2F,0x00,0x1E,0x00,0xB8,0xFF,0xA5,0xFF,0x49,0xFF, + 0x7D,0xFF,0x47,0xFF,0x6B,0xFF,0x38,0xFF,0x90,0xFF,0x89,0xFF, + 0xDE,0xFF,0xE2,0xFF,0x55,0x00,0xF0,0xFF,0x1C,0x00,0x56,0xFF, + 0x35,0xFF,0x19,0xFF,0x48,0xFF,0x5A,0xFF,0xAB,0xFF,0xDE,0xFF, + 0xB8,0xFF,0xB2,0xFF,0x5D,0xFF,0x27,0xFF,0x30,0xFF,0x5F,0xFF, + 0x81,0xFF,0xD1,0xFF,0xFA,0xFF,0x30,0x00,0x3E,0x00,0x19,0x00, + 0xDF,0xFF,0x64,0xFF,0x3E,0xFF,0x10,0xFF,0x4D,0xFF,0x82,0xFF, + 0xFC,0xFF,0x2C,0x00,0xEA,0xFF,0xF1,0xFF,0xB0,0xFF,0xA7,0xFF, + 0xF1,0xFF,0xBA,0xFF,0x71,0xFF,0x72,0xFF,0x88,0xFF,0x73,0xFF, + 0x9C,0xFF,0x9C,0xFF,0x95,0xFF,0x80,0xFF,0x86,0xFF,0x72,0xFF, + 0x59,0xFF,0x7F,0xFF,0xF7,0xFF,0xE6,0xFF,0x00,0x00,0xF9,0xFF, + 0xED,0xFF,0xE7,0xFF,0xD3,0xFF,0xD0,0xFF,0xBA,0xFF,0xAD,0xFF, + 0x71,0xFF,0xA9,0xFF,0xC8,0xFF,0xFA,0xFF,0xF9,0xFF,0xF6,0xFF, + 0x1B,0x00,0x0B,0x00,0xFD,0xFF,0x0E,0x00,0xF0,0xFF,0x06,0x00, + 0x12,0x00,0x37,0x00,0x37,0x00,0x38,0x00,0x2B,0x00,0x24,0x00, + 0x0B,0x00,0xA2,0xFF,0xA3,0xFF,0xB0,0xFF,0xDA,0xFF,0x1C,0x00, + 0x28,0x00,0x33,0x00,0x24,0x00,0x4E,0x00,0x2E,0x00,0xED,0xFF, + 0x17,0x00,0x1F,0x00,0xD3,0xFF,0xC2,0xFF,0x92,0xFF,0xC9,0xFF, + 0xD4,0xFF,0xE4,0xFF,0xE9,0xFF,0xC0,0xFF,0xDA,0xFF,0xD4,0xFF, + 0xE6,0xFF,0xB6,0xFF,0x90,0xFF,0xA3,0xFF,0x6E,0xFF,0x98,0xFF, + 0xC1,0xFF,0xF3,0xFF,0xF0,0xFF,0xB6,0xFF,0x9D,0xFF,0x66,0xFF, + 0x40,0xFF,0x78,0xFF,0x74,0xFF,0x87,0xFF,0x8F,0xFF,0xCA,0xFF, + 0xF7,0xFF,0xA8,0xFF,0xD2,0xFF,0x8B,0xFF,0x9C,0xFF,0xAC,0xFF, + 0xBA,0xFF,0xFF,0xFF,0xFC,0xFF,0xBA,0xFF,0x77,0xFF,0x90,0xFF, + 0x60,0xFF,0xB4,0xFF,0xB5,0xFF,0xE4,0xFF,0xBF,0xFF,0xE4,0xFF, + 0xDC,0xFF,0x8A,0xFF,0x3E,0xFF,0x6D,0xFF,0xD9,0xFF,0xD1,0xFF, + 0x15,0x00,0x20,0x00,0x18,0x00,0xBC,0xFF,0x91,0xFF,0x81,0xFF, + 0x9B,0xFF,0x7C,0xFF,0x7C,0xFF,0xB3,0xFF,0xF5,0xFF,0xE7,0xFF, + 0x0E,0x00,0x03,0x00,0x08,0x00,0xDC,0xFF,0xBA,0xFF,0x9F,0xFF, + 0xAA,0xFF,0xC3,0xFF,0xEB,0xFF,0x24,0x00,0xF4,0xFF,0xF5,0xFF, + 0xF9,0xFF,0xE8,0xFF,0x15,0x00,0x14,0x00,0x0A,0x00,0x23,0x00, + 0x25,0x00,0xC1,0xFF,0xA0,0xFF,0xAE,0xFF,0xA8,0xFF,0xE2,0xFF, + 0xC9,0xFF,0x18,0x00,0x39,0x00,0xF1,0xFF,0xF0,0xFF,0xC0,0xFF, + 0xB8,0xFF,0xC8,0xFF,0xDA,0xFF,0xE3,0xFF,0xC8,0xFF,0x13,0x00, + 0x45,0x00,0x62,0x00,0x30,0x00,0x3D,0x00,0x11,0x00,0xF1,0xFF, + 0xF2,0xFF,0xF2,0xFF,0x19,0x00,0x13,0x00,0x07,0x00,0xFE,0xFF, + 0xBC,0xFF,0xC2,0xFF,0xEC,0xFF,0xD1,0xFF,0xE4,0xFF,0xE3,0xFF, + 0xE4,0xFF,0x0A,0x00,0x19,0x00,0x32,0x00,0x0B,0x00,0xFE,0xFF, + 0xC8,0xFF,0xEB,0xFF,0x31,0x00,0x1B,0x00,0x28,0x00,0x1B,0x00, + 0xF9,0xFF,0xE0,0xFF,0xE2,0xFF,0xD7,0xFF,0xB4,0xFF,0xCE,0xFF, + 0xDD,0xFF,0x0F,0x00,0x26,0x00,0x2A,0x00,0x0D,0x00,0x0D,0x00, + 0xE6,0xFF,0xD1,0xFF,0xB1,0xFF,0xA0,0xFF,0x9D,0xFF,0xCA,0xFF, + 0xDA,0xFF,0xF5,0xFF,0x0A,0x00,0xD4,0xFF,0xD9,0xFF,0xC8,0xFF, + 0xBB,0xFF,0xD4,0xFF,0xD5,0xFF,0xF5,0xFF,0xE4,0xFF,0xFC,0xFF, + 0x1A,0x00,0x03,0x00,0x00,0x00,0xEF,0xFF,0xD8,0xFF,0xD4,0xFF, + 0xB9,0xFF,0xE5,0xFF,0x06,0x00,0x11,0x00,0x05,0x00,0xF0,0xFF, + 0xF0,0xFF,0xD3,0xFF,0xBA,0xFF,0x98,0xFF,0xB4,0xFF,0xF1,0xFF, + 0x02,0x00,0x2F,0x00,0x1C,0x00,0x0E,0x00,0x1C,0x00,0xE9,0xFF, + 0xEE,0xFF,0xE0,0xFF,0xF9,0xFF,0xFF,0xFF,0x37,0x00,0x1D,0x00, + 0x0B,0x00,0x02,0x00,0xCF,0xFF,0x87,0xFF,0x62,0xFF,0x65,0xFF, + 0x6B,0xFF,0x57,0xFF,0x5F,0xFF,0x5F,0xFF,0x64,0xFF,0x68,0xFF, + 0x73,0xFF,0x70,0xFF,0x7A,0xFF,0x7B,0xFF,0x86,0xFF,0x80,0xFF, + 0x80,0xFF,0x89,0xFF,0xB4,0xFF,0xAF,0xFF,0xD8,0xFF,0xED,0xFF, + 0x03,0x00,0x08,0x00,0x10,0x00,0x09,0x00,0x15,0x00,0x28,0x00, + 0x0C,0x00,0x30,0x00,0x4E,0x00,0x70,0x00,0xA8,0x00,0xCE,0x00, + 0xDA,0x00,0xE9,0x00,0x01,0x01,0x56,0x01,0x63,0x01,0xB6,0x01, + 0x0E,0x02,0x31,0x02,0xD6,0x01,0xD4,0x00,0x6C,0x00,0x09,0xFF, + 0xED,0xFD,0xA7,0xFD,0x93,0xFD,0x30,0xFE,0xA1,0xFE,0x6E,0xFF, + 0xBC,0xFF,0xCF,0xFF,0x93,0xFF,0x2E,0xFF,0x0D,0xFF,0xF2,0xFE, + 0x49,0xFF,0xC8,0xFF,0x17,0x00,0x5A,0x00,0x80,0x00,0x0A,0x00, + 0x6D,0xFF,0x94,0xFE,0xF5,0xFD,0xCA,0xFD,0xC3,0xFD,0x5E,0xFE, + 0x1B,0xFF,0xDF,0xFF,0x2B,0x00,0x7D,0x00,0x63,0x00,0x09,0x00, + 0xCE,0xFF,0x9C,0xFF,0x8F,0xFF,0x9E,0xFF,0xD3,0xFF,0x04,0x00, + 0x00,0x00,0xF8,0xFF,0xEB,0xFF,0xEE,0xFF,0xDF,0xFF,0xDF,0xFF, + 0x31,0x00,0x87,0x00,0xEF,0x00,0x6D,0x01,0xC5,0x01,0xF8,0x01, + 0x15,0x02,0x40,0x02,0x48,0x02,0x3D,0x02,0x11,0x02,0x60,0x01, + 0x14,0x00,0x56,0xFF,0x15,0xFE,0x7F,0xFD,0x41,0xFD,0x5D,0xFD, + 0x39,0xFE,0xC8,0xFE,0xA8,0xFF,0xF6,0xFF,0x17,0x00,0xDC,0xFF, + 0x93,0xFF,0x9A,0xFF,0xB5,0xFF,0xCE,0xFF,0x1C,0x00,0x8D,0x00, + 0xB6,0x00,0x9D,0x00,0x3C,0x00,0xA9,0xFF,0x34,0xFF,0xBE,0xFE, + 0xA6,0xFE,0xD4,0xFE,0x19,0xFF,0x62,0xFF,0x92,0xFF,0x7E,0xFF, + 0x2D,0xFF,0xC4,0xFE,0x9B,0xFE,0xD3,0xFE,0x16,0xFF,0x59,0xFF, + 0xB3,0xFF,0xE4,0xFF,0xD8,0xFF,0xB1,0xFF,0x76,0xFF,0x80,0xFF, + 0x9F,0xFF,0xF4,0xFF,0x5D,0x00,0xDF,0x00,0x12,0x01,0x53,0x01, + 0x8B,0x01,0x8A,0x01,0x86,0x01,0x92,0x01,0xAB,0x01,0xC0,0x01, + 0xFF,0x01,0xD1,0x01,0xB3,0x01,0x7C,0x01,0x2A,0x01,0xF8,0x00, + 0x5F,0x00,0x78,0xFF,0x08,0xFF,0x7C,0xFE,0x28,0xFE,0xEC,0xFD, + 0x56,0xFE,0xC6,0xFE,0x4B,0xFF,0xD6,0xFF,0x2C,0x00,0x5B,0x00, + 0x3C,0x00,0x1F,0x00,0x1B,0x00,0x41,0x00,0x23,0x00,0x40,0x00, + 0x62,0x00,0x6B,0x00,0x32,0x00,0xC5,0xFF,0x77,0xFF,0x45,0xFF, + 0xFF,0xFE,0x07,0xFF,0x46,0xFF,0x93,0xFF,0xE1,0xFF,0x36,0x00, + 0x52,0x00,0x43,0x00,0xC9,0xFF,0x1B,0xFF,0xAC,0xFE,0x70,0xFE, + 0x30,0xFE,0x3B,0xFE,0x77,0xFE,0xD4,0xFE,0xF8,0xFE,0x11,0xFF, + 0x29,0xFF,0x2E,0xFF,0x45,0xFF,0x6B,0xFF,0xD1,0xFF,0x31,0x00, + 0x79,0x00,0xB7,0x00,0xE9,0x00,0xF5,0x00,0xEA,0x00,0xD3,0x00, + 0xF3,0x00,0x22,0x01,0x4A,0x01,0xAF,0x01,0x12,0x02,0xE3,0x01, + 0xAF,0x01,0x68,0x01,0xDB,0x00,0x1A,0x00,0x69,0xFF,0xB0,0xFE, + 0x32,0xFE,0xDD,0xFD,0xD8,0xFD,0x1E,0xFE,0x98,0xFE,0x19,0xFF, + 0x46,0xFF,0x8C,0xFF,0xB7,0xFF,0xED,0xFF,0xDF,0xFF,0x01,0x00, + 0x2C,0x00,0x4E,0x00,0x47,0x00,0x2E,0x00,0xE8,0xFF,0x82,0xFF, + 0x12,0xFF,0xC3,0xFE,0xB5,0xFE,0xA3,0xFE,0xEC,0xFE,0x1A,0xFF, + 0x99,0xFF,0xE3,0xFF,0x0A,0x00,0x16,0x00,0x03,0x00,0xF6,0xFF, + 0xD5,0xFF,0xCB,0xFF,0x91,0xFF,0x39,0xFF,0xE2,0xFE,0x92,0xFE, + 0x1C,0xFE,0xC8,0xFD,0xBA,0xFD,0xF6,0xFD,0x75,0xFE,0x13,0xFF, + 0x8A,0xFF,0xD1,0xFF,0xEF,0xFF,0xE2,0xFF,0xAD,0xFF,0x90,0xFF, + 0x9C,0xFF,0xC9,0xFF,0xF6,0xFF,0x31,0x00,0x36,0x00,0x37,0x00, + 0x2A,0x00,0x32,0x00,0x49,0x00,0xBB,0x00,0x43,0x01,0xDC,0x01, + 0x30,0x02,0x68,0x02,0x4C,0x02,0xFF,0x01,0x8E,0x01,0xBE,0x00, + 0x9B,0xFF,0x5E,0xFE,0xE1,0xFD,0x74,0xFD,0x6B,0xFD,0xB8,0xFD, + 0x1F,0xFE,0xEE,0xFE,0x8D,0xFF,0x02,0x00,0x15,0x00,0x54,0x00, + 0x6B,0x00,0x9D,0x00,0x97,0x00,0xCF,0x00,0xAD,0x00,0x64,0x00, + 0xFE,0xFF,0x64,0xFF,0xE1,0xFE,0x61,0xFE,0x59,0xFE,0x60,0xFE, + 0xE8,0xFE,0x6E,0xFF,0xFA,0xFF,0x2D,0x00,0x6F,0x00,0x7B,0x00, + 0x63,0x00,0x4E,0x00,0x2B,0x00,0x1A,0x00,0xFD,0xFF,0xDA,0xFF, + 0x4E,0xFF,0xB8,0xFE,0xF0,0xFD,0x9B,0xFD,0x5A,0xFD,0x86,0xFD, + 0x44,0xFE,0xD3,0xFE,0xA3,0xFF,0x2F,0x00,0x62,0x00,0x48,0x00, + 0xF5,0xFF,0x9E,0xFF,0x7C,0xFF,0x86,0xFF,0xC4,0xFF,0xF8,0xFF, + 0x19,0x00,0x15,0x00,0xF2,0xFF,0xDB,0xFF,0xF7,0xFF,0x49,0x00, + 0xE2,0x00,0x9E,0x01,0x3B,0x02,0x84,0x02,0x0C,0x03,0x6A,0x03, + 0x72,0x03,0x37,0x01,0x81,0xFF,0x8C,0xFD,0xAA,0xFC,0x46,0xFC, + 0x66,0xFC,0x1E,0xFD,0x23,0xFF,0x37,0x00,0xA2,0x00,0xCE,0xFF, + 0xBC,0xFF,0x14,0x00,0x09,0x00,0xC0,0x00,0xDD,0x00,0xF2,0x01, + 0xC3,0x01,0x41,0x01,0xA4,0xFF,0x22,0xFE,0xB0,0xFD,0x8D,0xFD, + 0xD9,0xFD,0x96,0xFE,0x5C,0xFF,0x7D,0x00,0xDA,0x00,0x74,0x00, + 0x4B,0x00,0x01,0x00,0x5B,0x00,0x7A,0x00,0xB6,0x00,0xF7,0x00, + 0xE6,0x00,0x57,0x00,0x79,0xFF,0x61,0xFE,0xC0,0xFD,0x92,0xFD, + 0x99,0xFD,0xD0,0xFD,0x88,0xFE,0x5B,0xFF,0xD3,0xFF,0xF4,0xFF, + 0x21,0x00,0x57,0x00,0x79,0x00,0x55,0x00,0x1C,0x00,0xE4,0xFF, + 0xBB,0xFF,0x8D,0xFF,0x3F,0xFF,0x49,0xFF,0xA0,0xFF,0x0C,0x00, + 0x68,0x00,0x94,0x00,0xF6,0x00,0x65,0x01,0xCE,0x01,0xF8,0x01, + 0x20,0x02,0x76,0x02,0xAA,0x02,0xAD,0x02,0x11,0x02,0x77,0x01, + 0xB7,0x00,0x14,0x00,0xAB,0xFE,0x97,0xFD,0x46,0xFD,0xA7,0xFD, + 0x93,0xFE,0x65,0xFF,0x33,0x00,0xCE,0x00,0x2D,0x01,0x21,0x01, + 0xD3,0x00,0xBB,0x00,0xED,0x00,0x2C,0x01,0x01,0x01,0x48,0x00, + 0xDA,0xFF,0x33,0xFF,0xBA,0xFE,0x75,0xFE,0x7B,0xFE,0x11,0xFF, + 0xF5,0xFF,0xA9,0x00,0xD7,0x00,0xDA,0x00,0xC0,0x00,0xC2,0x00, + 0xB6,0x00,0x9E,0x00,0x8A,0x00,0x77,0x00,0x51,0x00,0xD5,0xFF, + 0x19,0xFF,0x8D,0xFE,0x82,0xFE,0x9C,0xFE,0x00,0xFF,0xE1,0xFE, + 0x03,0xFF,0xFC,0xFE,0x48,0xFF,0x87,0xFF,0xB3,0xFF,0x11,0x00, + 0x56,0x00,0x68,0x00,0xF6,0xFF,0xA6,0xFF,0x1A,0xFF,0xEB,0xFE, + 0x0B,0xFF,0x51,0xFF,0xBB,0xFF,0x39,0x00,0x87,0x00,0xB1,0x00, + 0x98,0x00,0xAB,0x00,0x02,0x01,0x5C,0x01,0xEC,0x01,0x0F,0x02, + 0x1C,0x02,0xF9,0x01,0xAF,0x01,0x41,0x01,0x7F,0x00,0xFD,0xFF, + 0x0E,0xFF,0x2D,0xFE,0xC6,0xFD,0xB8,0xFD,0x28,0xFE,0xF8,0xFE, + 0xC1,0xFF,0x3C,0x00,0x96,0x00,0xA6,0x00,0xA9,0x00,0xAF,0x00, + 0x9F,0x00,0x89,0x00,0x43,0x00,0xE6,0xFF,0x86,0xFF,0xFF,0xFE, + 0xA3,0xFE,0x98,0xFE,0xCD,0xFE,0x42,0xFF,0xBF,0xFF,0x2B,0x00, + 0x52,0x00,0x7C,0x00,0x7B,0x00,0x76,0x00,0x76,0x00,0x6C,0x00, + 0x47,0x00,0xFD,0xFF,0xAD,0xFF,0x35,0xFF,0xD3,0xFE,0xA1,0xFE, + 0xA7,0xFE,0xDD,0xFE,0x46,0xFF,0xA7,0xFF,0xCE,0xFF,0xC9,0xFF, + 0x83,0xFF,0x11,0xFF,0xD0,0xFE,0xB4,0xFE,0x1C,0xFF,0x84,0xFF, + 0x9B,0xFF,0x9F,0xFF,0x6C,0xFF,0x35,0xFF,0x08,0xFF,0xFF,0xFE, + 0x37,0xFF,0xAA,0xFF,0x11,0x00,0x1E,0x00,0x10,0x00,0xF6,0xFF, + 0x1A,0x00,0x49,0x00,0x89,0x00,0xD5,0x00,0x18,0x01,0x39,0x01, + 0x31,0x01,0x06,0x01,0xCB,0x00,0xD3,0x00,0x16,0x01,0x24,0x01, + 0xBA,0x00,0x15,0x00,0x1E,0xFF,0x07,0xFE,0xA5,0xFD,0xB8,0xFD, + 0x9D,0xFE,0x9E,0xFF,0x3D,0x00,0x76,0x00,0x29,0x00,0xE9,0xFF, + 0xB5,0xFF,0xE2,0xFF,0x22,0x00,0x67,0x00,0x3A,0x00,0xF3,0xFF, + 0x1A,0xFF,0x79,0xFE,0x4F,0xFE,0x8E,0xFE,0x3A,0xFF,0xF5,0xFF, + 0x3E,0x00,0x31,0x00,0x0E,0x00,0xD2,0xFF,0xCD,0xFF,0x06,0x00, + 0x44,0x00,0x64,0x00,0x36,0x00,0x91,0xFF,0x14,0xFF,0x8D,0xFE, + 0x74,0xFE,0xD0,0xFE,0x24,0xFF,0x9B,0xFF,0xDC,0xFF,0xCB,0xFF, + 0xA7,0xFF,0x8D,0xFF,0xA2,0xFF,0x66,0xFF,0xF6,0xFE,0x6C,0xFE, + 0x4A,0xFE,0x97,0xFE,0xC2,0xFE,0x23,0xFF,0x61,0xFF,0xAA,0xFF, + 0xB0,0xFF,0x8E,0xFF,0x60,0xFF,0x59,0xFF,0x83,0xFF,0xF2,0xFF, + 0x26,0x00,0x1D,0x00,0x0F,0x00,0x1C,0x00,0x4C,0x00,0x82,0x00, + 0xD0,0x00,0x08,0x01,0x47,0x01,0x3B,0x01,0xF6,0x00,0xCB,0x00, + 0xB1,0x00,0xB1,0x00,0x7C,0x00,0x27,0x00,0x30,0xFF,0x8A,0xFE, + 0x9F,0xFE,0xFF,0xFE,0x87,0xFF,0xF4,0xFF,0x03,0x00,0x03,0x00, + 0xD6,0xFF,0xD2,0xFF,0xE2,0xFF,0x07,0x00,0x4F,0x00,0x4C,0x00, + 0xEE,0xFF,0x80,0xFF,0x06,0xFF,0x06,0xFF,0x74,0xFF,0xCA,0xFF, + 0x18,0x00,0x1B,0x00,0xFF,0xFF,0xE4,0xFF,0xEA,0xFF,0x04,0x00, + 0x47,0x00,0x72,0x00,0x6C,0x00,0x24,0x00,0xA0,0xFF,0x44,0xFF, + 0x41,0xFF,0x7D,0xFF,0xD5,0xFF,0xF0,0xFF,0xF2,0xFF,0xD1,0xFF, + 0xC0,0xFF,0xD2,0xFF,0xE6,0xFF,0x6B,0xFF,0xE5,0xFE,0x79,0xFE, + 0xB8,0xFE,0x30,0xFF,0x97,0xFF,0xBB,0xFF,0xCD,0xFF,0xDD,0xFF, + 0xEC,0xFF,0xBA,0xFF,0xBA,0xFF,0xBD,0xFF,0x09,0x00,0x28,0x00, + 0x0D,0x00,0xCF,0xFF,0xE9,0xFF,0x60,0x00,0xB2,0x00,0xE7,0x00, + 0xDB,0x00,0xF0,0x00,0x1D,0x01,0x5B,0x01,0x6E,0x01,0x66,0x01, + 0x95,0x01,0xC3,0x01,0xA6,0x01,0xF1,0x00,0xBE,0xFF,0xF3,0xFE, + 0xDA,0xFD,0xFC,0xFD,0xA9,0xFE,0x63,0xFF,0xED,0xFF,0x32,0x00, + 0x01,0x00,0xEF,0xFF,0x2A,0x00,0xC3,0x00,0x45,0x01,0x40,0x01, + 0x92,0x00,0x96,0xFF,0xCB,0xFE,0xA1,0xFE,0xE7,0xFE,0x8D,0xFF, + 0xFD,0xFF,0xF4,0xFF,0xB8,0xFF,0x8B,0xFF,0xEA,0xFF,0x52,0x00, + 0xF6,0x00,0x2E,0x01,0xDE,0x00,0x5A,0x00,0xAF,0xFF,0x4B,0xFF, + 0x66,0xFF,0x8C,0xFF,0xB4,0xFF,0x8B,0xFF,0x3A,0xFF,0x18,0xFF, + 0x45,0xFF,0xC8,0xFF,0x62,0x00,0x94,0x00,0x7B,0x00,0xDD,0xFF, + 0x04,0xFF,0x1D,0xFE,0xF7,0xFD,0x87,0xFE,0xA6,0xFF,0xE9,0xFF, + 0xB6,0xFF,0x41,0xFF,0x76,0xFF,0xF7,0xFF,0x55,0x00,0x5C,0x00, + 0x2D,0x00,0xD2,0xFF,0xB2,0xFF,0x91,0xFF,0xDF,0xFF,0x6E,0x00, + 0xE5,0x00,0x13,0x01,0xC9,0x00,0x81,0x00,0xBD,0x00,0x65,0x01, + 0x00,0x02,0xF9,0x01,0xDD,0x01,0xC5,0x01,0x00,0x02,0xB2,0x01, + 0xA5,0x00,0x84,0xFD,0xD7,0xFC,0xC1,0xFD,0x06,0x00,0x37,0x00, + 0xE3,0xFF,0x02,0xFF,0x80,0xFF,0x5A,0x00,0xAA,0x01,0x9A,0x01, + 0x87,0x01,0x0F,0x01,0xAA,0x00,0x1D,0xFF,0x85,0xFE,0xC9,0xFE, + 0x18,0x00,0xA4,0x00,0x98,0xFF,0x97,0xFE,0x9D,0xFE,0x0B,0x00, + 0xDE,0x01,0x08,0x02,0x66,0x01,0x85,0x00,0x70,0x00,0x7A,0x00, + 0x90,0x00,0x3E,0x00,0x40,0x00,0xF6,0xFF,0x8D,0xFF,0xAB,0xFE, + 0xC5,0xFE,0x6B,0xFF,0xAD,0x00,0xE4,0x00,0x2F,0x00,0x92,0xFF, + 0xE4,0xFF,0xBB,0x00,0xCC,0x00,0x23,0xFF,0x1F,0xFE,0xD6,0xFD, + 0x09,0xFF,0x07,0x00,0xF1,0xFF,0x87,0xFF,0xA1,0xFF,0x0F,0x00, + 0x4A,0x00,0x12,0x00,0x39,0x00,0x9B,0x00,0xB2,0x00,0x1B,0x00, + 0x77,0xFF,0xEE,0xFF,0xAA,0x00,0x48,0x01,0xE4,0x00,0x1B,0x00, + 0x42,0x00,0x43,0x01,0xF8,0x01,0xCB,0x01,0x82,0x01,0x8A,0x01, + 0x40,0x02,0x94,0x02,0x07,0x02,0xEA,0xFD,0xED,0xFC,0x54,0xFD, + 0x7B,0xFF,0xA4,0x00,0x10,0xFF,0xD1,0xFD,0xCD,0xFE,0xDA,0xFF, + 0xD6,0x01,0x1F,0x01,0x28,0x01,0xD8,0x00,0x60,0x00,0xA9,0xFF, + 0xEB,0xFE,0x57,0xFF,0x55,0x00,0xD7,0xFF,0x5C,0xFE,0x77,0xFD, + 0x2D,0xFE,0x85,0x00,0x3F,0x01,0xCD,0x00,0x5F,0xFF,0x7B,0xFF, + 0xDA,0x00,0x4F,0x01,0xFA,0x00,0x14,0x00,0x71,0xFF,0x6B,0xFF, + 0x05,0xFF,0xC6,0xFE,0x1A,0xFF,0x6A,0xFF,0x7D,0xFF,0xD4,0xFE, + 0x87,0xFE,0x2C,0xFF,0x6A,0x00,0xE5,0x00,0xF7,0xFF,0x4B,0xFE, + 0x64,0xFD,0x9D,0xFE,0xD8,0xFF,0x3D,0x00,0x09,0xFF,0x01,0xFE, + 0x8E,0xFE,0xD9,0xFF,0x61,0x00,0xF6,0xFF,0x3C,0xFF,0x5B,0xFF, + 0x66,0xFF,0xD6,0xFF,0x55,0x00,0x6B,0x00,0x7B,0x00,0x0D,0x00, + 0xBF,0xFF,0x60,0x00,0xDC,0x00,0x78,0x01,0x1C,0x01,0x58,0x00, + 0x7B,0x00,0x63,0x01,0x89,0x02,0xE5,0x02,0x2F,0x02,0x4A,0xFE, + 0x55,0xFC,0x1A,0xFE,0xE0,0xFF,0x9B,0x01,0x77,0xFE,0x1E,0xFC, + 0xCF,0xFC,0xF4,0xFF,0x64,0x02,0x6C,0x01,0xC0,0xFF,0x3C,0xFF, + 0x46,0x00,0xFE,0x00,0xFC,0x00,0x53,0x00,0xE5,0xFF,0x2B,0xFF, + 0x3B,0xFE,0x79,0xFE,0xAD,0xFF,0x83,0x00,0xA8,0xFF,0x79,0xFE, + 0x2F,0xFE,0x60,0x00,0xE6,0x01,0xBC,0x01,0xFB,0xFF,0xF2,0xFE, + 0x34,0x00,0xFF,0x00,0xF7,0x00,0xB0,0xFF,0xA1,0xFE,0xB1,0xFE, + 0x47,0xFF,0x4E,0xFF,0x5A,0xFF,0x51,0xFF,0x1D,0xFF,0x29,0xFF, + 0x5D,0xFF,0xE7,0xFF,0x4D,0x00,0x96,0xFE,0x2A,0xFE,0xC4,0xFE, + 0xF9,0xFF,0x85,0x00,0x02,0xFF,0x54,0xFE,0xDB,0xFE,0x02,0x00, + 0x4C,0x00,0x4A,0xFF,0xB0,0xFE,0x83,0xFF,0x50,0x00,0x49,0x00, + 0x49,0x00,0x23,0x00,0x8E,0x00,0xBC,0x00,0x81,0x00,0xBC,0x00, + 0x6C,0x01,0x4C,0x01,0x09,0x01,0xB2,0x00,0x25,0x01,0x63,0x02, + 0xBC,0x02,0xD9,0x01,0x5C,0xFE,0xE8,0xFC,0xEE,0xFE,0x56,0x01, + 0x8D,0x00,0x4D,0xFD,0xDF,0xFB,0x2C,0xFE,0x83,0x01,0x00,0x01, + 0x77,0xFF,0x59,0xFE,0x78,0xFF,0xCB,0x01,0xE4,0x01,0x55,0x00, + 0x12,0x00,0x13,0x00,0x3A,0x00,0x43,0x00,0x1F,0x00,0x2B,0x00, + 0xBA,0xFF,0xE5,0xFE,0xA7,0xFE,0x19,0x00,0xA9,0x00,0x55,0x00, + 0x22,0xFF,0xF4,0xFE,0xB4,0x00,0x7C,0x01,0xE2,0x00,0xA4,0xFF, + 0x9E,0xFF,0x25,0x00,0xED,0x00,0x5A,0x00,0x58,0xFF,0x47,0xFF, + 0x88,0xFF,0xA3,0xFF,0x98,0xFF,0x83,0xFF,0x3A,0xFF,0x04,0xFE, + 0x39,0xFE,0x91,0xFF,0x8D,0x00,0xBD,0xFF,0x78,0xFE,0x82,0xFE, + 0x47,0x00,0x61,0x01,0xF3,0xFF,0xFF,0xFE,0x46,0xFF,0xB3,0x00, + 0x39,0x01,0x1F,0x00,0x75,0xFF,0xF4,0xFF,0xFD,0x00,0x00,0x01, + 0xB4,0x00,0x9C,0x00,0xE9,0x00,0x41,0x01,0x36,0x01,0x29,0x01, + 0xB7,0x01,0x10,0x02,0xF4,0x01,0x97,0x01,0x45,0x00,0x3C,0xFF, + 0x1E,0x00,0x54,0x01,0xFC,0xFF,0xA1,0xFE,0x5A,0xFE,0x11,0xFF, + 0x2D,0x00,0xC1,0xFF,0xBE,0xFE,0x93,0xFE,0xAF,0xFF,0xF2,0xFF, + 0xEB,0xFF,0xE2,0xFF,0xD2,0xFF,0x0E,0x00,0x47,0x00,0x4B,0x00, + 0x7A,0x00,0xA3,0x00,0x41,0x00,0xC3,0xFF,0x24,0x00,0x75,0x00, + 0x37,0x00,0xEE,0xFF,0xA3,0xFF,0xE3,0xFF,0x41,0x00,0x23,0x00, + 0x9F,0xFF,0xA1,0xFF,0xD8,0xFF,0xCD,0xFF,0xA6,0xFF,0x92,0xFF, + 0x8A,0xFF,0x85,0xFF,0x74,0xFF,0x45,0xFF,0x6E,0xFF,0x8A,0xFF, + 0x5B,0xFF,0x3D,0xFF,0x75,0xFF,0x8A,0xFF,0x8C,0xFF,0x6C,0xFF, + 0x69,0xFF,0x7F,0xFF,0xB5,0xFF,0x9D,0xFF,0x87,0xFF,0xA0,0xFF, + 0xC8,0xFF,0xC9,0xFF,0xCF,0xFF,0xD4,0xFF,0xE8,0xFF,0xF6,0xFF, + 0x06,0x00,0x32,0x00,0x50,0x00,0x62,0x00,0x50,0x00,0x5B,0x00, + 0x86,0x00,0xC2,0x00,0xBB,0x00,0xB4,0x00,0xB9,0x00,0x96,0x00, + 0x5E,0x00,0xA4,0x00,0xD8,0x00,0x98,0x00,0x27,0x00,0x28,0x00, + 0x42,0x00,0x1B,0x00,0xD2,0xFF,0xA0,0xFF,0x85,0xFF,0x60,0xFF, + 0x28,0xFF,0x05,0xFF,0x0D,0xFF,0x06,0xFF,0xDB,0xFE,0xD5,0xFE, + 0xF3,0xFE,0x1A,0xFF,0x25,0xFF,0x33,0xFF,0x4C,0xFF,0x6B,0xFF, + 0x8A,0xFF,0xCB,0xFF,0xEC,0xFF,0x03,0x00,0x15,0x00,0x16,0x00, + 0x3F,0x00,0x61,0x00,0x5C,0x00,0x49,0x00,0x3F,0x00,0x3E,0x00, + 0x32,0x00,0x18,0x00,0xFE,0xFF,0xE5,0xFF,0xAC,0xFF,0x7F,0xFF, + 0x77,0xFF,0x68,0xFF,0x35,0xFF,0x07,0xFF,0x0A,0xFF,0x09,0xFF, + 0xED,0xFE,0xEA,0xFE,0xE3,0xFE,0xE9,0xFE,0xFE,0xFE,0x1B,0xFF, + 0x43,0xFF,0x5C,0xFF,0x87,0xFF,0xBE,0xFF,0xFA,0xFF,0x20,0x00, + 0x52,0x00,0x7C,0x00,0x9E,0x00,0xB7,0x00,0xE3,0x00,0x02,0x01, + 0x15,0x01,0x1A,0x01,0x1F,0x01,0x41,0x01,0x2E,0x01,0xE7,0x00, + 0xC6,0x00,0xE2,0x00,0xBB,0x00,0x58,0x00,0x3C,0x00,0x3F,0x00, + 0xEB,0xFF,0x9D,0xFF,0x91,0xFF,0x5B,0xFF,0x07,0xFF,0xEF,0xFE, + 0xEC,0xFE,0xBA,0xFE,0xA9,0xFE,0xD1,0xFE,0xCA,0xFE,0xBE,0xFE, + 0xF4,0xFE,0x24,0xFF,0x32,0xFF,0x46,0xFF,0x71,0xFF,0x8C,0xFF, + 0xAE,0xFF,0xF1,0xFF,0x0F,0x00,0x1A,0x00,0x3C,0x00,0x52,0x00, + 0x54,0x00,0x67,0x00,0x68,0x00,0x40,0x00,0x2D,0x00,0x21,0x00, + 0x00,0x00,0xD6,0xFF,0xBB,0xFF,0x82,0xFF,0x43,0xFF,0x2F,0xFF, + 0x15,0xFF,0xDE,0xFE,0xC2,0xFE,0xB9,0xFE,0x9A,0xFE,0x82,0xFE, + 0x98,0xFE,0x9F,0xFE,0x89,0xFE,0x9A,0xFE,0xB7,0xFE,0xD4,0xFE, + 0x07,0xFF,0x37,0xFF,0x41,0xFF,0x5E,0xFF,0xB7,0xFF,0xF2,0xFF, + 0x0B,0x00,0x2C,0x00,0x4F,0x00,0x67,0x00,0x87,0x00,0x9D,0x00, + 0xA1,0x00,0xB5,0x00,0xBD,0x00,0xAD,0x00,0xAA,0x00,0xAC,0x00, + 0x6C,0x00,0x4F,0x00,0x63,0x00,0x3F,0x00,0xFF,0xFF,0xF3,0xFF, + 0xCD,0xFF,0x7F,0xFF,0x6A,0xFF,0x64,0xFF,0x15,0xFF,0xD7,0xFE, + 0xF5,0xFE,0xC8,0xFE,0xA5,0xFE,0xC1,0xFE,0xE4,0xFE,0xC3,0xFE, + 0xD9,0xFE,0x23,0xFF,0x23,0xFF,0x49,0xFF,0x7F,0xFF,0xA6,0xFF, + 0x95,0xFF,0xD3,0xFF,0xFB,0xFF,0x03,0x00,0x19,0x00,0x47,0x00, + 0x3D,0x00,0x3A,0x00,0x62,0x00,0x5C,0x00,0x3E,0x00,0x37,0x00, + 0x41,0x00,0xFA,0xFF,0xF5,0xFF,0xD8,0xFF,0x99,0xFF,0x7B,0xFF, + 0x77,0xFF,0x5A,0xFF,0x23,0xFF,0x12,0xFF,0x03,0xFF,0xE8,0xFE, + 0xF2,0xFE,0xEE,0xFE,0xE9,0xFE,0xEA,0xFE,0x0D,0xFF,0x1D,0xFF, + 0x33,0xFF,0x5B,0xFF,0x8B,0xFF,0xA2,0xFF,0xCC,0xFF,0xFB,0xFF, + 0x28,0x00,0x3B,0x00,0x75,0x00,0x86,0x00,0x8D,0x00,0xC7,0x00, + 0xD2,0x00,0xC4,0x00,0xC1,0x00,0xE9,0x00,0xE2,0x00,0xDD,0x00, + 0x1C,0x01,0x95,0x00,0x7E,0xFF,0xA3,0x00,0x5B,0x01,0x7B,0xFF, + 0xA9,0x00,0xA5,0x00,0x15,0xFF,0xC2,0xFF,0x53,0x00,0xF7,0xFF, + 0xC3,0xFE,0x71,0xFF,0x74,0xFF,0xDE,0xFE,0x8C,0xFF,0xB5,0xFF, + 0xF2,0xFE,0xF8,0xFE,0xF0,0xFF,0xE2,0xFF,0x18,0xFF,0x3F,0x00, + 0xE3,0xFF,0x85,0xFF,0x47,0x00,0x72,0x00,0x22,0x00,0xA4,0xFF, + 0xB9,0x00,0x2A,0x00,0x00,0x00,0xAF,0x00,0x32,0x00,0x05,0x00, + 0x0B,0x00,0xA9,0x00,0xF7,0xFF,0xAC,0xFF,0x31,0x00,0x9F,0xFF, + 0x79,0xFF,0x9A,0xFF,0x97,0xFF,0x1C,0xFF,0x36,0xFF,0xCD,0xFF, + 0x3A,0xFF,0x53,0xFF,0xAE,0xFF,0x67,0xFF,0x69,0xFF,0xA6,0xFF, + 0xCA,0xFF,0x36,0xFF,0xDC,0xFF,0xC2,0xFF,0x7D,0xFD,0xF8,0x00, + 0xF9,0xFE,0xB8,0xFE,0xB7,0x00,0xDC,0xFF,0xFB,0x00,0x8B,0x01, + 0xF1,0x00,0xB5,0x00,0x27,0x02,0x8D,0x01,0xC0,0x01,0x7C,0x01, + 0x6B,0x01,0xA9,0x01,0x6A,0x01,0xB1,0x02,0xBF,0xFF,0x42,0xFD, + 0x31,0x01,0x12,0x00,0x09,0xFE,0x09,0x00,0x01,0xFE,0x7B,0xFE, + 0xDC,0xFF,0x3F,0x00,0xFE,0xFE,0x44,0xFE,0x5A,0x01,0x89,0x00, + 0x57,0x00,0xE6,0x00,0x88,0xFF,0x15,0x00,0x53,0x01,0x22,0x01, + 0x52,0xFF,0xE6,0xFF,0x4F,0x00,0xCA,0xFF,0x34,0x00,0xF1,0xFF, + 0xEC,0xFE,0x8B,0xFF,0xB5,0x00,0x1C,0x00,0x90,0xFF,0xE3,0xFF, + 0x26,0x00,0x39,0x00,0xC7,0x00,0x10,0x00,0x3A,0xFF,0x02,0xFF, + 0x9C,0xFF,0xA2,0xFF,0x35,0xFE,0x03,0xFF,0x7E,0xFE,0xFF,0xFE, + 0x87,0xFF,0xD1,0xFE,0xC3,0xFE,0x60,0xFF,0x53,0x00,0xD6,0xFF, + 0xA6,0xFF,0xBA,0xFF,0x96,0xFF,0x4F,0x00,0x62,0x00,0x8D,0xFF, + 0x6C,0xFF,0x0A,0x00,0x37,0x00,0x02,0x00,0xF7,0xFF,0x05,0x00, + 0x54,0x00,0x0B,0x01,0x15,0x01,0x87,0x00,0x0A,0x01,0x78,0x01, + 0xC8,0x01,0x83,0x01,0x84,0x01,0x60,0x01,0x9C,0x00,0x8E,0xFF, + 0x72,0xFE,0xD4,0x00,0xC4,0xFD,0xBD,0xFE,0x5A,0xFE,0xEA,0xFD, + 0x1E,0xFF,0x62,0xFF,0x8D,0xFF,0xF0,0xFE,0x17,0x00,0xDC,0x00, + 0x15,0x00,0xA5,0x00,0x74,0x00,0x09,0x00,0x94,0x00,0x43,0x00, + 0x88,0xFF,0x24,0xFF,0x8B,0xFF,0x76,0xFF,0xF4,0xFE,0x55,0xFF, + 0x13,0xFF,0x70,0xFF,0x08,0x00,0xEC,0xFF,0xEB,0xFF,0x34,0x00, + 0x73,0x00,0x5A,0x00,0x5D,0x00,0x1A,0x00,0xB9,0xFF,0xE0,0xFF, + 0x9C,0xFF,0x1C,0xFE,0x3C,0xFF,0x30,0xFE,0x3C,0xFE,0xAB,0xFE, + 0x94,0xFE,0x15,0xFF,0x37,0xFF,0xD0,0xFF,0x92,0xFF,0xC1,0xFF, + 0x67,0x00,0xE9,0xFF,0x0A,0x00,0x05,0x00,0xA5,0xFF,0xCC,0xFF, + 0xC0,0xFF,0xDB,0xFF,0x85,0xFF,0x02,0x00,0x22,0x00,0x19,0x00, + 0xB6,0x00,0xA5,0x00,0xDC,0x00,0x84,0x01,0x7D,0x01,0xAD,0x01, + 0xE6,0x01,0x02,0x02,0x25,0x02,0xC4,0x01,0x12,0x01,0x98,0xFE, + 0x06,0xFF,0xE8,0x00,0x0A,0xFD,0x17,0xFF,0x9F,0xFD,0x66,0xFE, + 0x64,0xFF,0xB4,0xFF,0x3B,0xFF,0x0D,0xFF,0xB8,0x01,0x98,0x01, + 0x28,0x00,0x4E,0x01,0x60,0x00,0x73,0x00,0x37,0x01,0xAC,0x00, + 0x53,0xFF,0xEB,0xFE,0xD7,0xFF,0x6A,0xFF,0xE6,0xFE,0x20,0xFF, + 0x74,0xFE,0x03,0xFF,0x4F,0x00,0xD3,0xFF,0x9E,0xFF,0x0B,0x00, + 0xC4,0x00,0x7F,0x00,0xAC,0x00,0xED,0xFF,0x8D,0xFF,0x2D,0x00, + 0xD4,0xFF,0xB7,0xFE,0x68,0xFD,0xD7,0xFE,0x2A,0xFE,0x0D,0xFE, + 0xE3,0xFE,0x17,0xFE,0x23,0xFF,0x0B,0x00,0xD1,0xFF,0x50,0xFF, + 0xB8,0xFF,0x82,0x00,0x28,0x00,0x1C,0x00,0xBB,0xFF,0x33,0xFF, + 0xDB,0xFF,0x22,0x00,0x69,0xFF,0x49,0xFF,0xB2,0xFF,0x28,0x00, + 0x7E,0x00,0x98,0x00,0x9A,0x00,0xA6,0x00,0xA1,0x01,0xDF,0x01, + 0x70,0x01,0xA4,0x01,0xE0,0x01,0xAF,0x01,0xF1,0x00,0x5F,0x00, + 0x48,0xFD,0x19,0x01,0x8E,0xFD,0xD9,0xFD,0x00,0xFE,0x7B,0xFD, + 0xF3,0xFE,0x42,0xFF,0x88,0xFF,0xDC,0xFE,0x19,0x00,0x81,0x01, + 0x85,0x00,0x0F,0x01,0x64,0x00,0xEF,0xFF,0xD2,0x00,0x77,0x00, + 0x7C,0xFF,0xB6,0xFE,0x3B,0xFF,0x5A,0xFF,0xD9,0xFE,0x0C,0xFF, + 0xCB,0xFE,0xFB,0xFE,0x3C,0x00,0x07,0x00,0xE7,0xFF,0x18,0x00, + 0xBD,0x00,0xDA,0x00,0x95,0x00,0x69,0x00,0xB4,0xFF,0xD7,0xFF, + 0x09,0x00,0xFF,0xFE,0x7F,0xFE,0xBC,0xFC,0x83,0xFE,0xC6,0xFE, + 0x7D,0xFD,0x0B,0xFF,0xA1,0xFE,0x14,0x00,0x5A,0x00,0x10,0x00, + 0xB4,0xFF,0x0D,0x00,0x7D,0x01,0x16,0x00,0xD4,0xFF,0x19,0x00, + 0xA5,0xFF,0xBA,0x00,0x5F,0x00,0xF7,0xFF,0xDE,0xFF,0x11,0x01, + 0x52,0x01,0xD1,0x00,0x03,0x01,0xA2,0x01,0xE7,0x01,0x87,0x02, + 0xF1,0x02,0xB2,0x01,0x6D,0x01,0x5D,0x01,0xFC,0xFE,0x67,0x01, + 0xCF,0xFF,0xB2,0xFD,0xDE,0xFE,0x3E,0xFE,0x09,0xFF,0xAE,0xFE, + 0x7A,0xFF,0x09,0xFF,0x38,0x00,0x74,0x01,0x84,0x00,0xE2,0x00, + 0x58,0x01,0xD4,0x00,0x32,0x01,0xA9,0x00,0x42,0x00,0x8E,0xFF, + 0xD7,0xFF,0xDA,0xFF,0xC9,0xFE,0xFE,0xFE,0x39,0xFF,0x1B,0xFF, + 0xE7,0xFF,0xD4,0xFF,0xF5,0xFF,0x2F,0x00,0xDF,0x00,0xEF,0x00, + 0x7F,0x00,0xC1,0x00,0x70,0xFF,0x84,0xFF,0x04,0x00,0xAD,0xFE, + 0xBE,0xFE,0x7D,0xFE,0xDE,0xFE,0x99,0xFE,0xFD,0xFE,0x1B,0xFF, + 0xEE,0xFE,0x12,0x00,0x0A,0x00,0xD5,0xFF,0x0D,0x00,0x30,0x00, + 0x6D,0x00,0x5C,0x00,0x4E,0x00,0xE2,0xFF,0x10,0x00,0x64,0x00, + 0xFF,0xFF,0xF5,0xFF,0x4E,0x00,0x51,0x00,0xF6,0x00,0x21,0x01, + 0xED,0x00,0xB8,0x01,0xE6,0x01,0x5B,0x02,0x84,0x02,0x27,0x02, + 0xEF,0x00,0xA1,0xFE,0x12,0x01,0x48,0xFF,0x98,0xFD,0xE6,0xFE, + 0xB4,0xFD,0xA7,0xFE,0x03,0xFF,0x47,0xFF,0x3F,0xFE,0x80,0xFF, + 0x06,0x01,0x94,0x00,0x72,0x00,0xCD,0x00,0x58,0x00,0x0F,0x01, + 0x34,0x01,0x35,0x00,0x4B,0xFF,0x80,0xFF,0xD8,0xFF,0xE8,0xFE, + 0x08,0xFF,0xA2,0xFE,0x84,0xFE,0x91,0xFF,0x9B,0xFF,0x55,0xFF, + 0x68,0xFF,0x4F,0x00,0x79,0x00,0x4F,0x00,0x59,0xFF,0x40,0x00, + 0x1F,0xFF,0x4A,0xFF,0x64,0xFF,0x1E,0xFE,0xA4,0xFE,0xBA,0xFE, + 0xCD,0xFE,0x5C,0xFE,0xBE,0xFE,0x0A,0xFF,0x47,0xFF,0xF3,0xFF, + 0xB6,0xFF,0x74,0xFF,0x17,0x00,0x55,0x00,0x35,0x00,0x16,0x00, + 0x1B,0x00,0x20,0x00,0x2B,0x00,0x5C,0x00,0x28,0x00,0x47,0x00, + 0xD7,0x00,0x16,0x01,0x34,0x01,0x9F,0x01,0x95,0x01,0x12,0x02, + 0x35,0x02,0xD2,0xFF,0x99,0xFE,0x90,0x01,0xA1,0xFE,0xB2,0xFE, + 0x3D,0xFE,0x8E,0xFD,0x42,0xFE,0xDE,0xFE,0x0B,0xFF,0x98,0xFD, + 0xF7,0xFE,0x83,0x00,0xBD,0xFF,0xCC,0x00,0x86,0x00,0xD1,0xFF, + 0xE0,0x00,0x17,0x01,0x76,0x00,0x10,0xFF,0xEA,0xFF,0x48,0xFF, + 0xF4,0xFE,0x56,0xFF,0x5F,0xFE,0x46,0xFE,0x21,0xFF,0x78,0xFF, + 0xFF,0xFE,0x37,0xFF,0x49,0xFF,0xC7,0xFE,0x51,0x00,0x2E,0xFF, + 0x1E,0xFF,0xFA,0xFE,0x57,0xFF,0x3B,0xFF,0x09,0xFF,0x10,0xFF, + 0x58,0xFE,0x29,0xFF,0x4E,0xFF,0xFF,0xFE,0xF4,0xFE,0x42,0xFF, + 0x8F,0xFF,0xD8,0xFF,0x0F,0x00,0xDF,0xFF,0x11,0x00,0x89,0x00, + 0xA9,0x00,0x8F,0x00,0xB2,0x00,0xB1,0x00,0x07,0x01,0x5F,0x01, + 0x6E,0x01,0x53,0x01,0x3D,0x01,0xC2,0x01,0x06,0x01,0x73,0xFF, + 0xED,0xFE,0x84,0x00,0x31,0xFE,0x19,0xFF,0x92,0xFE,0xF0,0xFD, + 0xF3,0xFE,0x28,0xFF,0x83,0xFF,0x67,0xFE,0x13,0x00,0xB8,0xFF, + 0x04,0x00,0xCA,0x00,0x22,0x00,0x01,0x00,0x91,0x00,0xFA,0x00, + 0x2C,0x00,0xFD,0xFF,0x07,0x00,0x98,0xFF,0xA6,0xFF,0xD2,0xFF, + 0x24,0xFF,0xDB,0xFE,0x66,0xFF,0x8E,0xFE,0x72,0xFE,0xA8,0xFF, + 0xC2,0xFE,0x32,0xFF,0x9E,0xFF,0x95,0xFF,0x79,0xFF,0xC7,0xFF, + 0x09,0x00,0x2E,0xFF,0xE0,0xFF,0xD8,0xFF,0x70,0xFF,0xB5,0xFF, + 0xEC,0xFF,0xB8,0xFF,0xCB,0xFF,0x76,0x00,0x50,0x00,0x72,0x00, + 0xC0,0x00,0xFB,0x00,0xEC,0x00,0x67,0x01,0x7D,0x01,0x55,0x01, + 0xBE,0x01,0xD9,0x01,0x93,0x01,0xCC,0x01,0x5F,0x01,0x4D,0xFF, + 0x20,0x01,0xEA,0x00,0x0F,0xFF,0x2A,0x00,0xB1,0xFE,0xF7,0xFE, + 0x1F,0xFF,0xAE,0xFF,0x18,0xFF,0x84,0xFE,0xE4,0xFF,0x50,0xFF, + 0xE0,0xFF,0x3C,0x00,0xEF,0xFF,0xE2,0xFF,0x42,0x00,0xA8,0x00, + 0x2D,0x00,0x64,0x00,0x5A,0x00,0x1D,0x00,0x30,0x00,0x5D,0x00, + 0x02,0x00,0xA2,0xFF,0xD2,0xFF,0xB5,0xFF,0xAF,0xFF,0xF4,0xFF, + 0xCF,0xFF,0xA4,0xFF,0xCA,0xFF,0xBF,0xFF,0x92,0xFF,0x89,0xFF, + 0x6E,0xFF,0x52,0xFF,0x62,0xFF,0x6D,0xFF,0x71,0xFF,0x89,0xFF, + 0xAE,0xFF,0xB7,0xFF,0xEA,0xFF,0xFF,0xFF,0x18,0x00,0x3B,0x00, + 0x4C,0x00,0x79,0x00,0x80,0x00,0x96,0x00,0xA3,0x00,0xB2,0x00, + 0xBF,0x00,0xBA,0x00,0xD0,0x00,0xB5,0x00,0xA4,0x00,0xA8,0x00, + 0x95,0x00,0x7B,0x00,0x7D,0x00,0x53,0x00,0x3A,0x00,0x0F,0x00, + 0xF2,0xFF,0xC7,0xFF,0x9E,0xFF,0x7A,0xFF,0x4D,0xFF,0x39,0xFF, + 0x21,0xFF,0x16,0xFF,0x11,0xFF,0x14,0xFF,0x19,0xFF,0x2A,0xFF, + 0x45,0xFF,0x47,0xFF,0x65,0xFF,0x7C,0xFF,0x8F,0xFF,0xB2,0xFF, + 0xC9,0xFF,0xDD,0xFF,0xE9,0xFF,0xF5,0xFF,0x03,0x00,0x03,0x00, + 0x14,0x00,0x01,0x00,0xF9,0xFF,0xF9,0xFF,0xE6,0xFF,0xE6,0xFF, + 0xD2,0xFF,0xC6,0xFF,0xC7,0xFF,0xC3,0xFF,0xBB,0xFF,0xAF,0xFF, + 0xBC,0xFF,0xCA,0xFF,0xD5,0xFF,0xE7,0xFF,0xFB,0xFF,0x0A,0x00, + 0x35,0x00,0x5D,0x00,0x63,0x00,0x70,0x00,0x99,0x00,0x9E,0x00, + 0xA7,0x00,0xB2,0x00,0x9A,0x00,0x84,0x00,0x6F,0x00,0x4D,0x00, + 0x23,0x00,0xF9,0xFF,0xD5,0xFF,0x9D,0xFF,0x89,0xFF,0x6C,0xFF, + 0x4D,0xFF,0x30,0xFF,0x32,0xFF,0x32,0xFF,0x26,0xFF,0x32,0xFF, + 0x42,0xFF,0x4F,0xFF,0x6A,0xFF,0x82,0xFF,0x95,0xFF,0xB7,0xFF, + 0xD0,0xFF,0xEE,0xFF,0xEF,0xFF,0x09,0x00,0x18,0x00,0x17,0x00, + 0x22,0x00,0x20,0x00,0x1A,0x00,0x1A,0x00,0x0F,0x00,0x01,0x00, + 0xE8,0xFF,0xF1,0xFF,0xD6,0xFF,0xD5,0xFF,0xD1,0xFF,0xD0,0xFF, + 0xDD,0xFF,0xE1,0xFF,0xEA,0xFF,0xF5,0xFF,0x1D,0x00,0x2D,0x00, + 0x42,0x00,0x66,0x00,0x6C,0x00,0x79,0x00,0xA4,0x00,0xAD,0x00, + 0xAF,0x00,0xAC,0x00,0xA1,0x00,0x82,0x00,0x6C,0x00,0x55,0x00, + 0x22,0x00,0x07,0x00,0xE4,0xFF,0xC2,0xFF,0x9E,0xFF,0x87,0xFF, + 0x70,0xFF,0x56,0xFF,0x5A,0xFF,0x44,0xFF,0x4F,0xFF,0x4F,0xFF, + 0x55,0xFF,0x5E,0xFF,0x71,0xFF,0x87,0xFF,0x95,0xFF,0xB4,0xFF, + 0xC5,0xFF,0xDB,0xFF,0xE9,0xFF,0x02,0x00,0x11,0x00,0x21,0x00, + 0x2C,0x00,0x2C,0x00,0x34,0x00,0x36,0x00,0x2B,0x00,0x28,0x00, + 0x33,0x00,0x1B,0x00,0x17,0x00,0x1B,0x00,0x17,0x00,0x1E,0x00, + 0x21,0x00,0x29,0x00,0x32,0x00,0x50,0x00,0x5D,0x00,0x64,0x00, + 0x7B,0x00,0x82,0x00,0x94,0x00,0xA3,0x00,0x9A,0x00,0x9C,0x00, + 0x8D,0x00,0x86,0x00,0x65,0x00,0x53,0x00,0x3C,0x00,0x18,0x00, + 0xF5,0xFF,0xCF,0xFF,0xB4,0xFF,0xB0,0xFF,0x8C,0xFF,0x80,0xFF, + 0x72,0xFF,0x6B,0xFF,0x72,0xFF,0x74,0xFF,0x7D,0xFF,0x88,0xFF, + 0x95,0xFF,0xAA,0xFF,0xB0,0xFF,0xC0,0xFF,0xD3,0xFF,0xF0,0xFF, + 0x04,0x00,0x06,0x00,0x1F,0x00,0x21,0x00,0x34,0x00,0x33,0x00, + 0x39,0x00,0x40,0x00,0x2F,0x00,0x33,0x00,0x2F,0x00,0x2C,0x00, + 0x2A,0x00,0x2A,0x00,0x28,0x00,0x2D,0x00,0x37,0x00,0x39,0x00, + 0x41,0x00,0x58,0x00,0x61,0x00,0x6C,0x00,0x6C,0x00,0x76,0x00, + 0x78,0x00,0x80,0x00,0x78,0x00,0x61,0x00,0x52,0x00,0x36,0x00, + 0x24,0x00,0x05,0x00,0xE4,0xFF,0xC5,0xFF,0xB0,0xFF,0x93,0xFF, + 0x82,0xFF,0x67,0xFF,0x65,0xFF,0x52,0xFF,0x4D,0xFF,0x3E,0xFF, + 0x47,0xFF,0x4A,0xFF,0x5A,0xFF,0x6D,0xFF,0x6F,0xFF,0x80,0xFF, + 0x92,0xFF,0xA2,0xFF,0xAB,0xFF,0xB9,0xFF,0xC8,0xFF,0xD1,0xFF, + 0xE4,0xFF,0xEA,0xFF,0xF0,0xFF,0xFA,0xFF,0xFD,0xFF,0x0A,0x00, + 0x07,0x00,0x04,0x00,0x08,0x00,0x05,0x00,0x05,0x00,0x07,0x00, + 0x15,0x00,0x1C,0x00,0x22,0x00,0x1E,0x00,0x28,0x00,0x2A,0x00, + 0x2E,0x00,0x35,0x00,0x35,0x00,0x34,0x00,0x2B,0x00,0x17,0x00, + 0x00,0x00,0xF3,0xFF,0xDA,0xFF,0xBB,0xFF,0xAB,0xFF,0x8F,0xFF, + 0x7D,0xFF,0x61,0xFF,0x4C,0xFF,0x43,0xFF,0x3D,0xFF,0x36,0xFF, + 0x27,0xFF,0x2A,0xFF,0x32,0xFF,0x3E,0xFF,0x46,0xFF,0x54,0xFF, + 0x64,0xFF,0x6F,0xFF,0x7C,0xFF,0x86,0xFF,0x97,0xFF,0xAC,0xFF, + 0xC2,0xFF,0xCB,0xFF,0xD9,0xFF,0xDD,0xFF,0xED,0xFF,0xF6,0xFF, + 0xFD,0xFF,0x00,0x00,0x07,0x00,0x13,0x00,0x11,0x00,0x11,0x00, + 0x15,0x00,0x1A,0x00,0x29,0x00,0x2E,0x00,0x32,0x00,0x2F,0x00, + 0x34,0x00,0x44,0x00,0x47,0x00,0x41,0x00,0x3F,0x00,0x30,0x00, + 0x21,0x00,0x08,0x00,0x01,0x00,0xDC,0xFF,0xC8,0xFF,0xB4,0xFF, + 0xA0,0xFF,0x83,0xFF,0x76,0xFF,0x68,0xFF,0x5B,0xFF,0x55,0xFF, + 0x49,0xFF,0x49,0xFF,0x51,0xFF,0x51,0xFF,0x53,0xFF,0x5C,0xFF, + 0x62,0xFF,0x69,0xFF,0x7C,0xFF,0x89,0xFF,0x91,0xFF,0xA0,0xFF, + 0xB8,0xFF,0xC1,0xFF,0xE2,0xFF,0xE2,0xFF,0xF2,0xFF,0x01,0x00, + 0x11,0x00,0x15,0x00,0x1F,0x00,0x2D,0x00,0x31,0x00,0x27,0x00, + 0x3B,0x00,0x44,0x00,0x3F,0x00,0x42,0x00,0x4E,0x00,0x3C,0x00, + 0x4E,0x00,0x49,0x00,0x2D,0x00,0x2A,0x00,0x17,0x00,0x07,0x00, + 0xF5,0xFF,0xE4,0xFF,0xBA,0xFF,0xA2,0xFF,0x8E,0xFF,0x77,0xFF, + 0x66,0xFF,0x57,0xFF,0x3B,0xFF,0x28,0xFF,0x1B,0xFF,0x20,0xFF, + 0x44,0xFF,0x2B,0xFF,0x03,0xFF,0x45,0xFF,0x43,0xFF,0x2F,0xFF, + 0x6C,0xFF,0x5C,0xFF,0x4A,0xFF,0x84,0xFF,0x93,0xFF,0x8C,0xFF, + 0xB2,0xFF,0xCA,0xFF,0xAE,0xFF,0xDE,0xFF,0xF4,0xFF,0xE9,0xFF, + 0x03,0x00,0x1B,0x00,0x0E,0x00,0x10,0x00,0x33,0x00,0x38,0x00, + 0x31,0x00,0x31,0x00,0x18,0x00,0x06,0x00,0x2B,0x00,0x52,0x00, + 0x11,0x00,0x0D,0x00,0x16,0x00,0xE6,0xFF,0xDC,0xFF,0xE1,0xFF, + 0xB5,0xFF,0x97,0xFF,0x91,0xFF,0x6D,0xFF,0x5E,0xFF,0x6A,0xFF, + 0x5C,0xFF,0x34,0xFF,0x13,0xFF,0x20,0xFF,0x5E,0xFF,0x2F,0xFF, + 0x1C,0xFF,0x3E,0xFF,0x35,0xFF,0x4B,0xFF,0x95,0xFF,0x6E,0xFF, + 0x44,0xFF,0xAE,0xFF,0xA0,0xFF,0x96,0xFF,0xDC,0xFF,0xD5,0xFF, + 0xCA,0xFF,0x07,0x00,0x28,0x00,0x06,0x00,0x3B,0x00,0x52,0x00, + 0x4B,0x00,0x62,0x00,0x84,0x00,0x7C,0x00,0x72,0x00,0x6A,0x00, + 0x02,0x00,0xDF,0xFF,0x61,0x00,0x7D,0x00,0x24,0x00,0x4F,0x00, + 0x45,0x00,0x05,0x00,0x31,0x00,0xF4,0xFF,0xAC,0xFF,0xB5,0xFF, + 0xBE,0xFF,0x8C,0xFF,0x91,0xFF,0x85,0xFF,0x4D,0xFF,0x22,0xFF, + 0x27,0xFF,0xA5,0xFF,0xAA,0xFF,0xB9,0xFF,0xB3,0xFF,0x42,0xFF, + 0x57,0xFF,0xB3,0xFF,0x79,0xFF,0x2A,0xFF,0xB3,0xFF,0xD1,0xFF, + 0xDF,0xFF,0xEC,0xFF,0xCC,0xFF,0xB0,0xFF,0xF6,0xFF,0x4E,0x00, + 0x25,0x00,0x25,0x00,0x43,0x00,0x5C,0x00,0x67,0x00,0xA6,0x00, + 0x95,0x00,0x73,0x00,0x93,0x00,0x70,0x00,0xF4,0xFF,0xED,0xFF, + 0xEA,0xFF,0xB8,0xFF,0x0A,0x00,0x26,0x00,0xE8,0xFF,0xF0,0xFF, + 0x21,0x00,0xE6,0xFF,0x99,0xFF,0xA1,0xFF,0x74,0xFF,0x55,0xFF, + 0x75,0xFF,0x77,0xFF,0xD1,0xFE,0x98,0xFE,0x8E,0xFF,0x1F,0xFF, + 0x13,0xFF,0xA2,0xFF,0x70,0xFF,0x3F,0xFF,0x1C,0x00,0xE1,0xFF, + 0xD1,0xFE,0xA0,0xFF,0x34,0xFE,0x0D,0xFE,0xE4,0xFF,0xFC,0xFE, + 0xCD,0xFE,0xAB,0xFF,0xBB,0xFF,0x6C,0x00,0x72,0x00,0x11,0x00, + 0x18,0x01,0xD2,0x00,0x96,0x01,0xB6,0x01,0x03,0x01,0x15,0x01, + 0x17,0x01,0x09,0x00,0x7A,0x00,0x2F,0x00,0x31,0xFF,0x86,0xFF, + 0x32,0xFF,0xE1,0xFE,0x04,0xFF,0xCF,0xFE,0xAF,0xFE,0xD6,0xFE, + 0xEA,0xFE,0x5F,0xFF,0x29,0xFF,0x06,0xFF,0x3E,0xFF,0xAF,0xFE, + 0x37,0xFF,0xDF,0xFF,0xC4,0xFE,0x4E,0xFF,0x77,0xFF,0xFA,0xFE, + 0x8C,0xFF,0x79,0xFF,0x0D,0xFF,0x66,0xFF,0xC6,0xFF,0xF2,0xFF, + 0xF1,0xFF,0xE9,0xFF,0x40,0x00,0x45,0x00,0x96,0x00,0xD9,0x00, + 0x80,0x00,0xBA,0x00,0x03,0x01,0xDD,0x00,0x07,0x01,0xF3,0x00, + 0xA4,0x00,0x8F,0x00,0x53,0x00,0x18,0x00,0xFD,0xFF,0xCE,0xFF, + 0xA6,0xFF,0x82,0xFF,0x6E,0xFF,0x8F,0xFF,0x75,0xFF,0x6B,0xFF, + 0x80,0xFF,0x87,0xFF,0x8E,0xFF,0x68,0xFF,0x23,0xFF,0x99,0xFF, + 0xB9,0xFF,0x4A,0xFF,0xC5,0xFF,0x96,0xFF,0x6B,0xFF,0xDE,0xFF, + 0xA9,0xFF,0x78,0xFF,0xD2,0xFF,0xE2,0xFF,0x1E,0x00,0x1F,0x00, + 0x30,0x00,0x59,0x00,0x72,0x00,0xD6,0x00,0xD7,0x00,0xB3,0x00, + 0xF7,0x00,0x17,0x01,0x0F,0x01,0x54,0x01,0x12,0x01,0xE6,0x00, + 0xD6,0x00,0xA9,0x00,0x4E,0x00,0x0D,0x00,0xEF,0xFF,0xB4,0xFF, + 0x94,0xFF,0x8B,0xFF,0x85,0xFF,0x51,0xFF,0x70,0xFF,0x76,0xFF, + 0x52,0xFF,0x63,0xFF,0x6E,0xFF,0x54,0xFF,0x7E,0xFF,0x9A,0xFF, + 0x90,0xFF,0x97,0xFF,0xA7,0xFF,0xA1,0xFF,0xA9,0xFF,0xAD,0xFF, + 0xB0,0xFF,0xB6,0xFF,0xDB,0xFF,0x01,0x00,0x02,0x00,0x28,0x00, + 0x5B,0x00,0x79,0x00,0x9D,0x00,0xBD,0x00,0xC2,0x00,0xC9,0x00, + 0xF2,0x00,0x01,0x01,0xDA,0x00,0xD4,0x00,0xB3,0x00,0x91,0x00, + 0x65,0x00,0x33,0x00,0xB8,0xFF,0x9F,0xFF,0x8A,0xFF,0x5D,0xFF, + 0x2D,0xFF,0x2C,0xFF,0x2C,0xFF,0x32,0xFF,0x56,0xFF,0x51,0xFF, + 0x4C,0xFF,0x6E,0xFF,0x6D,0xFF,0x78,0xFF,0x88,0xFF,0x78,0xFF, + 0x87,0xFF,0x8E,0xFF,0xA2,0xFF,0x9F,0xFF,0xA2,0xFF,0xAF,0xFF, + 0xCC,0xFF,0xE3,0xFF,0x00,0x00,0x14,0x00,0x3C,0x00,0x70,0x00, + 0x8A,0x00,0xA8,0x00,0xB0,0x00,0xB6,0x00,0xC4,0x00,0xC8,0x00, + 0xBF,0x00,0xB8,0x00,0xA5,0x00,0x66,0x00,0x5F,0x00,0x14,0x00, + 0xB2,0xFF,0x9F,0xFF,0x86,0xFF,0x32,0xFF,0x39,0xFF,0x42,0xFF, + 0x25,0xFF,0x2D,0xFF,0x4C,0xFF,0x41,0xFF,0x4A,0xFF,0x5C,0xFF, + 0x60,0xFF,0x78,0xFF,0x84,0xFF,0x84,0xFF,0x8C,0xFF,0x90,0xFF, + 0xA1,0xFF,0xB2,0xFF,0xB6,0xFF,0xCB,0xFF,0xD2,0xFF,0xED,0xFF, + 0x28,0x00,0x32,0x00,0x42,0x00,0x73,0x00,0x9A,0x00,0xB2,0x00, + 0xB9,0x00,0xAF,0x00,0x90,0x00,0xA2,0x00,0xB6,0x00,0x8F,0x00, + 0x84,0x00,0x5C,0x00,0x16,0x00,0x16,0x00,0xEC,0xFF,0xB9,0xFF, + 0x86,0xFF,0x64,0xFF,0x68,0xFF,0x61,0xFF,0x45,0xFF,0x50,0xFF, + 0x33,0xFF,0x33,0xFF,0x69,0xFF,0x46,0xFF,0x57,0xFF,0x5F,0xFF, + 0x56,0xFF,0x7B,0xFF,0x8C,0xFF,0x80,0xFF,0x84,0xFF,0x92,0xFF, + 0xB0,0xFF,0xC2,0xFF,0xC0,0xFF,0xE8,0xFF,0xF9,0xFF,0x10,0x00, + 0x3D,0x00,0x47,0x00,0x67,0x00,0x73,0x00,0x74,0x00,0x78,0x00, + 0x6F,0x00,0x76,0x00,0x65,0x00,0x6A,0x00,0x6F,0x00,0x36,0x00, + 0x28,0x00,0x27,0x00,0xED,0xFF,0xCB,0xFF,0xCE,0xFF,0x9C,0xFF, + 0x7B,0xFF,0x75,0xFF,0x75,0xFF,0x62,0xFF,0x5F,0xFF,0x67,0xFF, + 0x45,0xFF,0x41,0xFF,0x72,0xFF,0x41,0xFF,0x40,0xFF,0x66,0xFF, + 0x5B,0xFF,0x73,0xFF,0x8F,0xFF,0x7B,0xFF,0x81,0xFF,0xA2,0xFF, + 0xC0,0xFF,0xC8,0xFF,0xDD,0xFF,0x0E,0x00,0x06,0x00,0x15,0x00, + 0x4D,0x00,0x3B,0x00,0x4B,0x00,0x5F,0x00,0x58,0x00,0x59,0x00, + 0x53,0x00,0x45,0x00,0x4A,0x00,0x4B,0x00,0x3D,0x00,0x47,0x00, + 0x27,0x00,0x08,0x00,0xF6,0xFF,0xF4,0xFF,0xDE,0xFF,0xCF,0xFF, + 0xA8,0xFF,0x9E,0xFF,0xA9,0xFF,0x9C,0xFF,0x8C,0xFF,0x85,0xFF, + 0x71,0xFF,0x6A,0xFF,0x75,0xFF,0x75,0xFF,0x7A,0xFF,0x71,0xFF, + 0x94,0xFF,0xA5,0xFF,0xAF,0xFF,0xB1,0xFF,0xBD,0xFF,0xC4,0xFF, + 0xE3,0xFF,0xF6,0xFF,0xFA,0xFF,0x0A,0x00,0x09,0x00,0x18,0x00, + 0x36,0x00,0x3D,0x00,0x33,0x00,0x38,0x00,0x44,0x00,0x4F,0x00, + 0x44,0x00,0x40,0x00,0x31,0x00,0x42,0x00,0x46,0x00,0x35,0x00, + 0x1E,0x00,0x19,0x00,0x1F,0x00,0x11,0x00,0xF7,0xFF,0xF1,0xFF, + 0xDF,0xFF,0xD7,0xFF,0xCA,0xFF,0xBF,0xFF,0xB0,0xFF,0xB1,0xFF, + 0xAE,0xFF,0xA2,0xFF,0x92,0xFF,0x93,0xFF,0xB1,0xFF,0x97,0xFF, + 0x9B,0xFF,0xB0,0xFF,0x9F,0xFF,0xA9,0xFF,0xB4,0xFF,0xB3,0xFF, + 0xC2,0xFF,0xCD,0xFF,0xD6,0xFF,0xE8,0xFF,0xF6,0xFF,0xF7,0xFF, + 0xFB,0xFF,0x0A,0x00,0x18,0x00,0x15,0x00,0x15,0x00,0x21,0x00, + 0x2D,0x00,0x20,0x00,0x24,0x00,0x20,0x00,0x16,0x00,0x06,0x00, + 0x0F,0x00,0x15,0x00,0x03,0x00,0xF7,0xFF,0xE8,0xFF,0xDE,0xFF, + 0xE4,0xFF,0xE8,0xFF,0xDC,0xFF,0xD3,0xFF,0xCD,0xFF,0xCE,0xFF, + 0xCC,0xFF,0xB8,0xFF,0xB4,0xFF,0xB3,0xFF,0xB4,0xFF,0xB6,0xFF, + 0xBF,0xFF,0xAF,0xFF,0xA6,0xFF,0x9E,0xFF,0xB7,0xFF,0xBB,0xFF, + 0xBA,0xFF,0xC5,0xFF,0xBA,0xFF,0xC3,0xFF,0xE2,0xFF,0xD8,0xFF, + 0xE0,0xFF,0xE6,0xFF,0xEB,0xFF,0xF1,0xFF,0xF5,0xFF,0xF5,0xFF, + 0xF8,0xFF,0xF6,0xFF,0xFD,0xFF,0x02,0x00,0xF8,0xFF,0xF5,0xFF, + 0xFA,0xFF,0xF4,0xFF,0xEC,0xFF,0xFD,0xFF,0x02,0x00,0xF8,0xFF, + 0xED,0xFF,0xEF,0xFF,0xEA,0xFF,0xF3,0xFF,0xEB,0xFF,0xE8,0xFF, + 0xE4,0xFF,0xE5,0xFF,0xEB,0xFF,0xE6,0xFF,0xE0,0xFF,0xE6,0xFF, + 0xDE,0xFF,0xEC,0xFF,0xED,0xFF,0xE7,0xFF,0xDF,0xFF,0xD8,0xFF, + 0xEC,0xFF,0xF1,0xFF,0xEF,0xFF,0xF4,0xFF,0xE7,0xFF,0xE8,0xFF, + 0xF7,0xFF,0xE9,0xFF,0xEE,0xFF,0xED,0xFF,0xEB,0xFF,0xF8,0xFF, + 0xFB,0xFF,0xF7,0xFF,0xF8,0xFF,0xE2,0xFF,0xF4,0xFF,0xF4,0xFF, + 0xFB,0xFF,0xFD,0xFF,0xEC,0xFF,0xF4,0xFF,0x06,0x00,0xEE,0xFF, + 0xF9,0xFF,0xF4,0xFF,0xE0,0xFF,0xF6,0xFF,0xFC,0xFF,0xEF,0xFF, + 0xF0,0xFF,0xEA,0xFF,0xF0,0xFF,0xEC,0xFF,0xFC,0xFF,0xF7,0xFF, + 0xEF,0xFF,0xF9,0xFF,0xF4,0xFF,0xFC,0xFF,0xF6,0xFF,0xEC,0xFF, + 0xF2,0xFF,0xF4,0xFF,0xEF,0xFF,0xEF,0xFF,0xE9,0xFF,0xED,0xFF, + 0xE7,0xFF,0xE4,0xFF,0xE7,0xFF,0xE6,0xFF,0xEE,0xFF,0xF6,0xFF, + 0xEB,0xFF,0xF0,0xFF,0xF6,0xFF,0xE4,0xFF,0xEC,0xFF,0xED,0xFF, + 0xF3,0xFF,0xEE,0xFF,0xE7,0xFF,0xE4,0xFF,0xEE,0xFF,0xED,0xFF, + 0xE7,0xFF,0xE0,0xFF,0xE0,0xFF,0xDF,0xFF,0xDD,0xFF,0xD5,0xFF, + 0xD9,0xFF,0xD3,0xFF,0xD4,0xFF,0xD3,0xFF,0xD0,0xFF,0xCC,0xFF, + 0xD3,0xFF,0xD7,0xFF,0xDA,0xFF,0xD9,0xFF,0xE7,0xFF,0xE7,0xFF, + 0xED,0xFF,0xEE,0xFF,0xE1,0xFF,0xE9,0xFF,0xE9,0xFF,0xE3,0xFF, + 0xF5,0xFF,0xF3,0xFF,0xEA,0xFF,0xF6,0xFF,0xF3,0xFF,0xE6,0xFF, + 0xEA,0xFF,0xE4,0xFF,0xEC,0xFF,0xF3,0xFF,0xFA,0xFF,0xE4,0xFF, + 0xE5,0xFF,0xEF,0xFF,0xE9,0xFF,0xE6,0xFF,0xE4,0xFF,0xD7,0xFF, + 0xE3,0xFF,0xF3,0xFF,0xE2,0xFF,0xEB,0xFF,0xE2,0xFF,0xE3,0xFF, + 0xEE,0xFF,0xE5,0xFF,0xE8,0xFF,0xE1,0xFF,0xE7,0xFF,0xEB,0xFF, + 0xE1,0xFF,0xEF,0xFF,0xE7,0xFF,0xE3,0xFF,0xE6,0xFF,0xE4,0xFF, + 0xEC,0xFF,0xF1,0xFF,0xF5,0xFF,0xF1,0xFF,0xF3,0xFF,0xEE,0xFF, + 0xEF,0xFF,0xF1,0xFF,0xED,0xFF,0xED,0xFF,0xF0,0xFF,0xF5,0xFF, + 0xF1,0xFF,0xF4,0xFF,0xF2,0xFF,0xE3,0xFF,0xF4,0xFF,0xF1,0xFF, + 0xED,0xFF,0xF2,0xFF,0xE6,0xFF,0xEC,0xFF,0xF0,0xFF,0xE8,0xFF, + 0xF3,0xFF,0xE9,0xFF,0xE8,0xFF,0xEE,0xFF,0xF4,0xFF,0xEF,0xFF, + 0xE8,0xFF,0xE5,0xFF,0xDB,0xFF,0xE5,0xFF,0xED,0xFF,0xEC,0xFF, + 0xDB,0xFF,0xD2,0xFF,0xCF,0xFF,0xD6,0xFF,0xD8,0xFF,0xD4,0xFF, + 0xD6,0xFF,0xCF,0xFF,0xCD,0xFF,0xDA,0xFF,0xD2,0xFF,0xCE,0xFF, + 0xC9,0xFF,0xCD,0xFF,0xD4,0xFF,0xCC,0xFF,0xCD,0xFF,0xCB,0xFF, + 0xC5,0xFF,0xCB,0xFF,0xD5,0xFF,0xCE,0xFF,0xC9,0xFF,0xBD,0xFF, + 0xCF,0xFF,0xD7,0xFF,0xDA,0xFF,0xD9,0xFF,0xCF,0xFF,0xD3,0xFF, + 0xDC,0xFF,0xD2,0xFF,0xD8,0xFF,0xCF,0xFF,0xBF,0xFF,0xCC,0xFF, + 0xC6,0xFF,0xC4,0xFF,0xC5,0xFF,0xBE,0xFF,0xC6,0xFF,0xBF,0xFF, + 0xC5,0xFF,0xB8,0xFF,0xB2,0xFF,0xC6,0xFF,0xCC,0xFF,0xD4,0xFF, + 0xD5,0xFF,0xC7,0xFF,0xD5,0xFF,0xCC,0xFF,0xCD,0xFF,0xD7,0xFF, + 0xDB,0xFF,0xD9,0xFF,0xD6,0xFF,0xD3,0xFF,0xD9,0xFF,0xDD,0xFF, + 0xE2,0xFF,0xDF,0xFF,0xD7,0xFF,0xE9,0xFF,0xEA,0xFF,0xE8,0xFF, + 0xE6,0xFF,0xE2,0xFF,0xE4,0xFF,0xDF,0xFF,0xDE,0xFF,0xDF,0xFF, + 0xDC,0xFF,0xE0,0xFF,0xE1,0xFF,0xE9,0xFF,0xE2,0xFF,0xDE,0xFF, + 0xE2,0xFF,0xDE,0xFF,0xE4,0xFF,0xF0,0xFF,0xE9,0xFF,0xE7,0xFF, + 0xE5,0xFF,0xE7,0xFF,0xE6,0xFF,0xE5,0xFF,0xF2,0xFF,0xF0,0xFF, + 0xEF,0xFF,0xF1,0xFF,0xF4,0xFF,0xFB,0xFF,0xF8,0xFF,0x00,0x00, + 0xFB,0xFF,0xFE,0xFF,0x04,0x00,0xFE,0xFF,0xFC,0xFF,0xF7,0xFF, + 0xF7,0xFF,0xFF,0xFF,0xF8,0xFF,0xF8,0xFF,0xF3,0xFF,0x04,0x00, + 0x11,0x00,0x0A,0x00,0x0E,0x00,0x04,0x00,0x0A,0x00,0x10,0x00, + 0x0D,0x00,0x07,0x00,0x06,0x00,0x0A,0x00,0x0C,0x00,0x0C,0x00, + 0x03,0x00,0x01,0x00,0xFF,0xFF,0x00,0x00,0x02,0x00,0xFA,0xFF, + 0xF7,0xFF,0xFC,0xFF,0x00,0x00,0xFF,0xFF,0xF5,0xFF,0xF1,0xFF, + 0x00,0x00,0xFC,0xFF,0xF9,0xFF,0xFD,0xFF,0xFB,0xFF,0xFD,0xFF, + 0x07,0x00,0xF5,0xFF,0xF3,0xFF,0xF3,0xFF,0xEA,0xFF,0xF7,0xFF, + 0xE7,0xFF,0xF0,0xFF,0xEF,0xFF,0xF5,0xFF,0xF1,0xFF,0xF1,0xFF, + 0xEF,0xFF,0xE6,0xFF,0xE6,0xFF,0xF7,0xFF,0xEE,0xFF,0xF0,0xFF, + 0xEF,0xFF,0xE2,0xFF,0xE9,0xFF,0xDE,0xFF,0xDD,0xFF,0xDD,0xFF, + 0xD9,0xFF,0xDA,0xFF,0xD2,0xFF,0xDE,0xFF,0xD0,0xFF,0xCE,0xFF, + 0xD6,0xFF,0xCD,0xFF,0xD1,0xFF,0xDA,0xFF,0xD5,0xFF,0xD7,0xFF, + 0xD3,0xFF,0xD2,0xFF,0xCF,0xFF,0xD8,0xFF,0xD5,0xFF,0xD1,0xFF, + 0xCC,0xFF,0xCE,0xFF,0xD4,0xFF,0xD6,0xFF,0xD1,0xFF,0xCA,0xFF, + 0xC9,0xFF,0xCE,0xFF,0xD1,0xFF,0xD4,0xFF,0xD3,0xFF,0xD1,0xFF, + 0xD6,0xFF,0xD3,0xFF,0xD6,0xFF,0xCD,0xFF,0xC9,0xFF,0xD3,0xFF, + 0xD5,0xFF,0xCD,0xFF,0xC9,0xFF,0xCB,0xFF,0xC9,0xFF,0xC1,0xFF, + 0xC4,0xFF,0xC3,0xFF,0xBF,0xFF,0xC4,0xFF,0xC9,0xFF,0xCC,0xFF, + 0xCC,0xFF,0xC3,0xFF,0xBC,0xFF,0xC6,0xFF,0xC6,0xFF,0xCB,0xFF, + 0xD2,0xFF,0xD4,0xFF,0xD3,0xFF,0xD2,0xFF,0xD3,0xFF,0xD7,0xFF, + 0xCC,0xFF,0xD6,0xFF,0xD4,0xFF,0xCB,0xFF,0xD3,0xFF,0xCF,0xFF, + 0xD9,0xFF,0xCC,0xFF,0xCD,0xFF,0xD0,0xFF,0xD0,0xFF,0xC8,0xFF, + 0xCA,0xFF,0xD1,0xFF,0xCF,0xFF,0xD3,0xFF,0xC8,0xFF,0xC4,0xFF, + 0xC9,0xFF,0xCB,0xFF,0xCF,0xFF,0xCD,0xFF,0xCD,0xFF,0xCB,0xFF, + 0xC4,0xFF,0xCD,0xFF,0xCC,0xFF,0xD1,0xFF,0xD0,0xFF,0xC9,0xFF, + 0xCB,0xFF,0xC2,0xFF,0xC2,0xFF,0xBD,0xFF,0xCD,0xFF,0xCB,0xFF, + 0xD0,0xFF,0xCD,0xFF,0xC1,0xFF,0xC3,0xFF,0xBD,0xFF,0xC3,0xFF, + 0xBC,0xFF,0xBC,0xFF,0xBC,0xFF,0xBC,0xFF,0xBA,0xFF,0xC0,0xFF, + 0xBA,0xFF,0xB2,0xFF,0xB4,0xFF,0xB7,0xFF,0xB7,0xFF,0xBB,0xFF, + 0xC3,0xFF,0xBF,0xFF,0xBE,0xFF,0xC2,0xFF,0xBB,0xFF,0xC7,0xFF, + 0xC8,0xFF,0xC3,0xFF,0xC2,0xFF,0xC7,0xFF,0xC6,0xFF,0xC7,0xFF, + 0xC6,0xFF,0xC3,0xFF,0xBF,0xFF,0xC5,0xFF,0xC3,0xFF,0xCD,0xFF, + 0xC7,0xFF,0xC0,0xFF,0xC5,0xFF,0xC5,0xFF,0xB9,0xFF,0xC5,0xFF, + 0xC0,0xFF,0xBC,0xFF,0xBC,0xFF,0xC1,0xFF,0xBF,0xFF,0xC2,0xFF, + 0xC1,0xFF,0xC2,0xFF,0xBD,0xFF,0xC3,0xFF,0xC4,0xFF,0xC9,0xFF, + 0xCB,0xFF,0xCA,0xFF,0xC8,0xFF,0xD0,0xFF,0xC8,0xFF,0xC6,0xFF, + 0xC9,0xFF,0xD1,0xFF,0xD4,0xFF,0xD1,0xFF,0xD5,0xFF,0xDA,0xFF, + 0xD8,0xFF,0xD3,0xFF,0xD0,0xFF,0xD3,0xFF,0xD8,0xFF,0xDA,0xFF, + 0xDB,0xFF,0xDE,0xFF,0xDF,0xFF,0xE1,0xFF,0xEB,0xFF,0xE4,0xFF, + 0xDF,0xFF,0xDF,0xFF,0xE2,0xFF,0xDE,0xFF,0xEB,0xFF,0xE8,0xFF, + 0xE7,0xFF,0xE0,0xFF,0xE3,0xFF,0xE6,0xFF,0xEB,0xFF,0xE9,0xFF, + 0xED,0xFF,0xED,0xFF,0xEC,0xFF,0xEE,0xFF,0xF1,0xFF,0xED,0xFF, + 0xF1,0xFF,0xF1,0xFF,0xF5,0xFF,0xF4,0xFF,0xF7,0xFF,0xFE,0xFF, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFB,0xFF,0xFF,0xFF, + 0x02,0x00,0x00,0x00,0x02,0x00,0xFD,0xFF,0xF7,0xFF,0xF8,0xFF, + 0xF9,0xFF,0xFD,0xFF,0xF6,0xFF,0xEF,0xFF,0xF1,0xFF,0xEF,0xFF, + 0xF7,0xFF,0xF9,0xFF,0xFB,0xFF,0xFB,0xFF,0xF9,0xFF,0xF2,0xFF, + 0xF0,0xFF,0xEF,0xFF,0xF3,0xFF,0xF0,0xFF,0xEF,0xFF,0xEC,0xFF, + 0xEB,0xFF,0xE7,0xFF,0xE7,0xFF,0xE4,0xFF,0xE0,0xFF,0xE5,0xFF, + 0xE7,0xFF,0xED,0xFF,0xE3,0xFF,0xDC,0xFF,0xDF,0xFF,0xE4,0xFF, + 0xD8,0xFF,0xDA,0xFF,0xDB,0xFF,0xDD,0xFF,0xDD,0xFF,0xE5,0xFF, + 0xDA,0xFF,0xE2,0xFF,0xDE,0xFF,0xE0,0xFF,0xDA,0xFF,0xD6,0xFF, + 0xDA,0xFF,0xDC,0xFF,0xE0,0xFF,0xDF,0xFF,0xDD,0xFF,0xDC,0xFF, + 0xE1,0xFF,0xDD,0xFF,0xE0,0xFF,0xDE,0xFF,0xDC,0xFF,0xDD,0xFF, + 0xDA,0xFF,0xDC,0xFF,0xCE,0xFF,0xD1,0xFF,0xD4,0xFF,0xD2,0xFF, + 0xD3,0xFF,0xCA,0xFF,0xCC,0xFF,0xC8,0xFF,0xCF,0xFF,0xD1,0xFF, + 0xCF,0xFF,0xCA,0xFF,0xD1,0xFF,0xC9,0xFF,0xCF,0xFF,0xCE,0xFF, + 0xCE,0xFF,0xD6,0xFF,0xD0,0xFF,0xD3,0xFF,0xD6,0xFF,0xD2,0xFF, + 0xD0,0xFF,0xCA,0xFF,0xCF,0xFF,0xD0,0xFF,0xCE,0xFF,0xD0,0xFF, + 0xD4,0xFF,0xC8,0xFF,0xCF,0xFF,0xC9,0xFF,0xCE,0xFF,0xCE,0xFF, + 0xD1,0xFF,0xD5,0xFF,0xD9,0xFF,0xD7,0xFF,0xD6,0xFF,0xDF,0xFF, + 0xDE,0xFF,0xE6,0xFF,0xE8,0xFF,0xE2,0xFF,0xE4,0xFF,0xE2,0xFF, + 0xE5,0xFF,0xE4,0xFF,0xE8,0xFF,0xEE,0xFF,0xEA,0xFF,0xEC,0xFF, + 0xE6,0xFF,0xEC,0xFF,0xEB,0xFF,0xF1,0xFF,0xEC,0xFF,0xED,0xFF, + 0xEE,0xFF,0xF1,0xFF,0xF5,0xFF,0xF7,0xFF,0xF6,0xFF,0xF9,0xFF, + 0xFD,0xFF,0xFD,0xFF,0x03,0x00,0x03,0x00,0x06,0x00,0x02,0x00, + 0x05,0x00,0x06,0x00,0xF7,0xFF,0x26,0x00,0xCF,0xFF,0xFA,0xFF, + 0x34,0x00,0xC1,0xFF,0x3F,0x00,0x01,0x00,0xEA,0xFF,0x35,0x00, + 0xCE,0xFF,0x03,0x00,0x10,0x00,0xF5,0xFF,0x07,0x00,0xFB,0xFF, + 0x01,0x00,0xF7,0xFF,0xFC,0xFF,0xF1,0xFF,0xF0,0xFF,0x03,0x00, + 0xE8,0xFF,0xFE,0xFF,0xFF,0xFF,0xEE,0xFF,0x07,0x00,0xEA,0xFF, + 0xEE,0xFF,0xF6,0xFF,0xE5,0xFF,0xFC,0xFF,0xF1,0xFF,0xEE,0xFF, + 0xF4,0xFF,0xF1,0xFF,0xF4,0xFF,0xEC,0xFF,0xF1,0xFF,0xEA,0xFF, + 0xEB,0xFF,0xED,0xFF,0xE8,0xFF,0xEA,0xFF,0xEE,0xFF,0xEA,0xFF, + 0xEE,0xFF,0xE8,0xFF,0xE8,0xFF,0xF2,0xFF,0xE3,0xFF,0xE4,0xFF, + 0xE3,0xFF,0xE8,0xFF,0xE6,0xFF,0xE3,0xFF,0xE1,0xFF,0xDD,0xFF, + 0xE1,0xFF,0xD5,0xFF,0xD8,0xFF,0xDE,0xFF,0xDA,0xFF,0xDF,0xFF, + 0xDC,0xFF,0xDD,0xFF,0xDE,0xFF,0xD6,0xFF,0xDB,0xFF,0xDF,0xFF, + 0xE4,0xFF,0xE0,0xFF,0xDF,0xFF,0xE0,0xFF,0xDC,0xFF,0xDD,0xFF, + 0xDE,0xFF,0xE1,0xFF,0xE8,0xFF,0xDE,0xFF,0xE2,0xFF,0xE7,0xFF, + 0xE3,0xFF,0xE5,0xFF,0xE3,0xFF,0xE5,0xFF,0xE9,0xFF,0xE4,0xFF, + 0xEE,0xFF,0xE5,0xFF,0xE5,0xFF,0xDF,0xFF,0xE2,0xFF,0xE9,0xFF, + 0xE4,0xFF,0xE0,0xFF,0xE1,0xFF,0xE1,0xFF,0xE3,0xFF,0xDE,0xFF, + 0xDC,0xFF,0xDD,0xFF,0xDC,0xFF,0xDA,0xFF,0xD9,0xFF,0xD7,0xFF, + 0xD5,0xFF,0xD5,0xFF,0xD1,0xFF,0xCF,0xFF,0xD4,0xFF,0xD8,0xFF, + 0xDA,0xFF,0xD9,0xFF,0xDA,0xFF,0xD8,0xFF,0xD8,0xFF,0xD5,0xFF, + 0xD6,0xFF,0xD4,0xFF,0xD9,0xFF,0xDE,0xFF,0xD5,0xFF,0xDC,0xFF, + 0xD6,0xFF,0xDD,0xFF,0xD4,0xFF,0xD5,0xFF,0xDB,0xFF,0xD0,0xFF, + 0xD3,0xFF,0xDF,0xFF,0xDB,0xFF,0xD6,0xFF,0xD2,0xFF,0xCF,0xFF, + 0xCC,0xFF,0xC9,0xFF,0xD3,0xFF,0xD5,0xFF,0xCF,0xFF,0xCE,0xFF, + 0xC3,0xFF,0xC9,0xFF,0xC1,0xFF,0xC3,0xFF,0xC4,0xFF,0xBE,0xFF, + 0xBB,0xFF,0xBB,0xFF,0xBE,0xFF,0xBD,0xFF,0xB9,0xFF,0xB3,0xFF, + 0xB1,0xFF,0xAC,0xFF,0xAB,0xFF,0xB9,0xFF,0xB6,0xFF,0xBA,0xFF, + 0xB8,0xFF,0xB2,0xFF,0xB6,0xFF,0xB2,0xFF,0xB2,0xFF,0xAE,0xFF, + 0xB4,0xFF,0xB2,0xFF,0xAD,0xFF,0xB0,0xFF,0xAC,0xFF,0xAE,0xFF, + 0xAB,0xFF,0xA8,0xFF,0xA7,0xFF,0xAA,0xFF,0xA3,0xFF,0xAC,0xFF, + 0xA7,0xFF,0xAC,0xFF,0xB3,0xFF,0xAE,0xFF,0xA9,0xFF,0xA4,0xFF, + 0xA1,0xFF,0xA2,0xFF,0x9C,0xFF,0x99,0xFF,0xA6,0xFF,0xA0,0xFF, + 0xA5,0xFF,0x9C,0xFF,0x9D,0xFF,0xA0,0xFF,0x9B,0xFF,0x9C,0xFF, + 0x9C,0xFF,0x9F,0xFF,0xA5,0xFF,0x9E,0xFF,0xA0,0xFF,0xA2,0xFF, + 0xA2,0xFF,0x9D,0xFF,0xA2,0xFF,0xA3,0xFF,0xA3,0xFF,0xA6,0xFF, + 0xA3,0xFF,0xA5,0xFF,0xA0,0xFF,0xA9,0xFF,0xAB,0xFF,0xAD,0xFF, + 0xB4,0xFF,0xB0,0xFF,0xB0,0xFF,0xB1,0xFF,0xB8,0xFF,0xC1,0xFF, + 0xBC,0xFF,0xBC,0xFF,0xC3,0xFF,0xC8,0xFF,0xC8,0xFF,0xC4,0xFF, + 0xC0,0xFF,0xC9,0xFF,0xC4,0xFF,0xC3,0xFF,0xC3,0xFF,0xC0,0xFF, + 0xC8,0xFF,0xCA,0xFF,0xC9,0xFF,0xCE,0xFF,0xC9,0xFF,0xC4,0xFF, + 0xC2,0xFF,0xCF,0xFF,0xCA,0xFF,0xD1,0xFF,0xD7,0xFF,0xDE,0xFF, + 0xD6,0xFF,0xD9,0xFF,0xDC,0xFF,0xE0,0xFF,0xDF,0xFF,0xE7,0xFF, + 0xDD,0xFF,0xE6,0xFF,0xE6,0xFF,0xEC,0xFF,0xE9,0xFF,0xE9,0xFF, + 0xF3,0xFF,0xEC,0xFF,0xEB,0xFF,0xF2,0xFF,0xF3,0xFF,0xF5,0xFF, + 0xF7,0xFF,0xFA,0xFF,0xFF,0xFF,0xF3,0xFF,0xF5,0xFF,0xFA,0xFF, + 0xF8,0xFF,0xFA,0xFF,0x00,0x00,0xF9,0xFF,0xFD,0xFF,0xFA,0xFF, + 0xF7,0xFF,0xFC,0xFF,0xF9,0xFF,0xF5,0xFF,0xF8,0xFF,0xED,0xFF, + 0xFA,0xFF,0xF5,0xFF,0xFA,0xFF,0xFA,0xFF,0xF4,0xFF,0xF9,0xFF, + 0xF5,0xFF,0xF7,0xFF,0xFD,0xFF,0xF3,0xFF,0xF6,0xFF,0xF8,0xFF, + 0xF8,0xFF,0xF6,0xFF,0xF1,0xFF,0xED,0xFF,0xF6,0xFF,0xF7,0xFF, + 0xFF,0xFF,0xF9,0xFF,0xF7,0xFF,0xF7,0xFF,0xFC,0xFF,0xF9,0xFF, + 0xFD,0xFF,0xFA,0xFF,0xF6,0xFF,0xF7,0xFF,0xF8,0xFF,0xF0,0xFF, + 0xF0,0xFF,0xF5,0xFF,0xF7,0xFF,0xFB,0xFF,0xF7,0xFF,0xF6,0xFF, + 0xF8,0xFF +}; + +#endif //_playback_prompt_h_ diff --git a/src/libs/resiprocate/resip/recon/test/record_prompt.h b/src/libs/resiprocate/resip/recon/test/record_prompt.h new file mode 100644 index 00000000..5687d9f8 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/record_prompt.h @@ -0,0 +1,3679 @@ +// +// Copyright (C) 2004-2006 SIPfoundry Inc. +// Licensed by SIPfoundry under the LGPL license. +// +// Copyright (C) 2005-2006 SIPez LLC. +// Licensed to SIPfoundry under a Contributor Agreement. +// +// $$ +////////////////////////////////////////////////////////////////////////////// +#ifndef _record_prompt_h_ +#define _record_prompt_h_ + +unsigned char record_prompt[43940]= +{ + 0xEA,0xFF,0xF1,0xFF,0xF8,0xFF,0xF2,0xFF,0xE4,0xFF,0xF2,0xFF, + 0xF9,0xFF,0xF0,0xFF,0xE0,0xFF,0xE3,0xFF,0xF0,0xFF,0xE8,0xFF, + 0xEA,0xFF,0xF1,0xFF,0xE1,0xFF,0xFF,0xFF,0xF0,0xFF,0xDB,0xFF, + 0xF0,0xFF,0xF1,0xFF,0xE8,0xFF,0xD8,0xFF,0xED,0xFF,0xD0,0xFF, + 0xD2,0xFF,0xE5,0xFF,0xD3,0xFF,0xE5,0xFF,0xD7,0xFF,0xD7,0xFF, + 0xD7,0xFF,0xD2,0xFF,0xD4,0xFF,0xDF,0xFF,0xE1,0xFF,0xC7,0xFF, + 0xD4,0xFF,0xD4,0xFF,0xD8,0xFF,0xDC,0xFF,0xE5,0xFF,0xD0,0xFF, + 0xCA,0xFF,0xD1,0xFF,0xCE,0xFF,0xCF,0xFF,0xC4,0xFF,0xC3,0xFF, + 0xC6,0xFF,0xCF,0xFF,0xD9,0xFF,0xC8,0xFF,0xC5,0xFF,0xC6,0xFF, + 0xCC,0xFF,0xD2,0xFF,0xC5,0xFF,0xD0,0xFF,0xD2,0xFF,0xD2,0xFF, + 0xD6,0xFF,0xD5,0xFF,0xCE,0xFF,0xD4,0xFF,0xCD,0xFF,0xC9,0xFF, + 0xDC,0xFF,0xCF,0xFF,0xD7,0xFF,0xD6,0xFF,0xD5,0xFF,0xD9,0xFF, + 0xDD,0xFF,0xE3,0xFF,0xD3,0xFF,0xCE,0xFF,0xDC,0xFF,0xE6,0xFF, + 0xE7,0xFF,0xDA,0xFF,0xD9,0xFF,0xD2,0xFF,0xD3,0xFF,0xD7,0xFF, + 0xD4,0xFF,0xD3,0xFF,0xDE,0xFF,0xD2,0xFF,0xDD,0xFF,0xE2,0xFF, + 0xD3,0xFF,0xCF,0xFF,0xD7,0xFF,0xE1,0xFF,0xE7,0xFF,0xDD,0xFF, + 0xCE,0xFF,0xD9,0xFF,0xDD,0xFF,0xDE,0xFF,0xEA,0xFF,0xE4,0xFF, + 0xE4,0xFF,0xF3,0xFF,0xE5,0xFF,0xE8,0xFF,0xEA,0xFF,0xF6,0xFF, + 0xDD,0xFF,0xE4,0xFF,0xF3,0xFF,0xEB,0xFF,0xF8,0xFF,0xE9,0xFF, + 0xEA,0xFF,0xF5,0xFF,0xF9,0xFF,0xFB,0xFF,0xFC,0xFF,0xEB,0xFF, + 0xF1,0xFF,0xF8,0xFF,0xFE,0xFF,0xED,0xFF,0xEA,0xFF,0x02,0x00, + 0xF4,0xFF,0xEA,0xFF,0xFC,0xFF,0xFA,0xFF,0xF7,0xFF,0xEF,0xFF, + 0xE9,0xFF,0xE7,0xFF,0xFB,0xFF,0xF1,0xFF,0xF1,0xFF,0xE3,0xFF, + 0xE6,0xFF,0xF7,0xFF,0xEE,0xFF,0xE4,0xFF,0xEE,0xFF,0xE2,0xFF, + 0xE8,0xFF,0xDC,0xFF,0xE9,0xFF,0xE7,0xFF,0xE4,0xFF,0xE1,0xFF, + 0xE3,0xFF,0xEB,0xFF,0xE4,0xFF,0xE1,0xFF,0xE0,0xFF,0xE0,0xFF, + 0xDE,0xFF,0xE3,0xFF,0xDB,0xFF,0xDF,0xFF,0xF0,0xFF,0xF4,0xFF, + 0xEB,0xFF,0xE6,0xFF,0xE5,0xFF,0xE6,0xFF,0xF2,0xFF,0xE6,0xFF, + 0xE5,0xFF,0xE0,0xFF,0xDA,0xFF,0xDA,0xFF,0xD6,0xFF,0xD9,0xFF, + 0xD8,0xFF,0xD6,0xFF,0xD2,0xFF,0xD1,0xFF,0xD0,0xFF,0xCC,0xFF, + 0xC8,0xFF,0xD3,0xFF,0xD1,0xFF,0xD2,0xFF,0xD2,0xFF,0xCE,0xFF, + 0xD2,0xFF,0xD5,0xFF,0xD9,0xFF,0xD4,0xFF,0xD1,0xFF,0xCC,0xFF, + 0xCD,0xFF,0xCD,0xFF,0xD1,0xFF,0xCD,0xFF,0xD0,0xFF,0xCC,0xFF, + 0xD5,0xFF,0xCA,0xFF,0xCA,0xFF,0xD6,0xFF,0xD0,0xFF,0xCC,0xFF, + 0xC9,0xFF,0xCB,0xFF,0xD2,0xFF,0xC8,0xFF,0xCE,0xFF,0xC8,0xFF, + 0xBE,0xFF,0xD3,0xFF,0xCC,0xFF,0xCB,0xFF,0xC7,0xFF,0xD3,0xFF, + 0xCD,0xFF,0xD5,0xFF,0xC8,0xFF,0xCC,0xFF,0xCF,0xFF,0xD1,0xFF, + 0xD4,0xFF,0xD6,0xFF,0xC7,0xFF,0xD8,0xFF,0xDC,0xFF,0xD4,0xFF, + 0xDB,0xFF,0xDF,0xFF,0xDB,0xFF,0xE2,0xFF,0xE4,0xFF,0xDF,0xFF, + 0xE1,0xFF,0xDF,0xFF,0xDF,0xFF,0xDE,0xFF,0xD6,0xFF,0xE5,0xFF, + 0xE8,0xFF,0xE5,0xFF,0xE4,0xFF,0xE0,0xFF,0xEA,0xFF,0xE6,0xFF, + 0xE5,0xFF,0xF2,0xFF,0xF0,0xFF,0xF1,0xFF,0xF4,0xFF,0xFB,0xFF, + 0xF2,0xFF,0xEA,0xFF,0xED,0xFF,0xF1,0xFF,0xF5,0xFF,0xF1,0xFF, + 0xF5,0xFF,0xFD,0xFF,0xF5,0xFF,0xEC,0xFF,0xF2,0xFF,0xF4,0xFF, + 0xF0,0xFF,0xF2,0xFF,0xED,0xFF,0xFA,0xFF,0xF0,0xFF,0xEB,0xFF, + 0xEC,0xFF,0xE8,0xFF,0xE7,0xFF,0xE2,0xFF,0xE9,0xFF,0xE8,0xFF, + 0xE6,0xFF,0xE3,0xFF,0xDD,0xFF,0xDE,0xFF,0xE4,0xFF,0xDD,0xFF, + 0xE3,0xFF,0xD9,0xFF,0xDB,0xFF,0xE1,0xFF,0xDC,0xFF,0xDE,0xFF, + 0xDB,0xFF,0xDD,0xFF,0xDF,0xFF,0xDF,0xFF,0xDC,0xFF,0xD5,0xFF, + 0xD2,0xFF,0xD2,0xFF,0xE2,0xFF,0xD6,0xFF,0xD3,0xFF,0xD3,0xFF, + 0xD6,0xFF,0xD4,0xFF,0xD4,0xFF,0xCC,0xFF,0xC6,0xFF,0xC6,0xFF, + 0xCB,0xFF,0xC9,0xFF,0xC6,0xFF,0xC7,0xFF,0xD0,0xFF,0xD3,0xFF, + 0xCD,0xFF,0xC4,0xFF,0xC3,0xFF,0xD2,0xFF,0xD1,0xFF,0xD1,0xFF, + 0xC6,0xFF,0xC0,0xFF,0xC4,0xFF,0xCE,0xFF,0xC9,0xFF,0xD0,0xFF, + 0xCC,0xFF,0xD6,0xFF,0xD3,0xFF,0xD5,0xFF,0xD4,0xFF,0xDC,0xFF, + 0xDC,0xFF,0xD6,0xFF,0xD9,0xFF,0xDD,0xFF,0xDE,0xFF,0xDD,0xFF, + 0xD8,0xFF,0xE6,0xFF,0xE4,0xFF,0xE4,0xFF,0xDB,0xFF,0xD7,0xFF, + 0xDE,0xFF,0xE6,0xFF,0xE1,0xFF,0xE2,0xFF,0xE0,0xFF,0xEE,0xFF, + 0xEA,0xFF,0xE1,0xFF,0xE3,0xFF,0xE8,0xFF,0xE6,0xFF,0xE6,0xFF, + 0xE5,0xFF,0xEC,0xFF,0xE2,0xFF,0xE2,0xFF,0xED,0xFF,0xF0,0xFF, + 0xF5,0xFF,0xF9,0xFF,0xEE,0xFF,0xEE,0xFF,0xF8,0xFF,0xFA,0xFF, + 0xF8,0xFF,0xF2,0xFF,0xF9,0xFF,0x03,0x00,0x00,0x00,0xFA,0xFF, + 0xFE,0xFF,0xF9,0xFF,0xFC,0xFF,0xF1,0xFF,0xFA,0xFF,0xF9,0xFF, + 0xF6,0xFF,0xFC,0xFF,0xF9,0xFF,0xF3,0xFF,0xF7,0xFF,0xEE,0xFF, + 0xF2,0xFF,0xF4,0xFF,0xEB,0xFF,0xEF,0xFF,0xEF,0xFF,0xE9,0xFF, + 0xEF,0xFF,0xF0,0xFF,0xF6,0xFF,0xEB,0xFF,0xE5,0xFF,0xE6,0xFF, + 0xE4,0xFF,0xDC,0xFF,0xE8,0xFF,0xE7,0xFF,0xE3,0xFF,0xE2,0xFF, + 0xDD,0xFF,0xE5,0xFF,0xDF,0xFF,0xDA,0xFF,0xD9,0xFF,0xD6,0xFF, + 0xD6,0xFF,0xD9,0xFF,0xD9,0xFF,0xD7,0xFF,0xD8,0xFF,0xDC,0xFF, + 0xD7,0xFF,0xD1,0xFF,0xD6,0xFF,0xD1,0xFF,0xD9,0xFF,0xD2,0xFF, + 0xDB,0xFF,0xD2,0xFF,0xD0,0xFF,0xCC,0xFF,0xCD,0xFF,0xD1,0xFF, + 0xD5,0xFF,0xD5,0xFF,0xD7,0xFF,0xD3,0xFF,0xC5,0xFF,0xD0,0xFF, + 0xCF,0xFF,0xCE,0xFF,0xC8,0xFF,0xCB,0xFF,0xCA,0xFF,0xCD,0xFF, + 0xD2,0xFF,0xD0,0xFF,0xCB,0xFF,0xD2,0xFF,0xD0,0xFF,0xD1,0xFF, + 0xC9,0xFF,0xCC,0xFF,0xD1,0xFF,0xCC,0xFF,0xCD,0xFF,0xCC,0xFF, + 0xC8,0xFF,0xCB,0xFF,0xC1,0xFF,0xCC,0xFF,0xD2,0xFF,0xCA,0xFF, + 0xCA,0xFF,0xCE,0xFF,0xD0,0xFF,0xD6,0xFF,0xCE,0xFF,0xCF,0xFF, + 0xCA,0xFF,0xCB,0xFF,0xD1,0xFF,0xC8,0xFF,0xC7,0xFF,0xCA,0xFF, + 0xCA,0xFF,0xD3,0xFF,0xD4,0xFF,0xD3,0xFF,0xC7,0xFF,0xCF,0xFF, + 0xD4,0xFF,0xDB,0xFF,0xD2,0xFF,0xCD,0xFF,0xD5,0xFF,0xD6,0xFF, + 0xD8,0xFF,0xD9,0xFF,0xDD,0xFF,0xE6,0xFF,0xDF,0xFF,0xD8,0xFF, + 0xDB,0xFF,0xE2,0xFF,0xE7,0xFF,0xE9,0xFF,0xE2,0xFF,0xE5,0xFF, + 0xE4,0xFF,0xF0,0xFF,0xF4,0xFF,0xE8,0xFF,0xF8,0xFF,0xF9,0xFF, + 0xF2,0xFF,0xF8,0xFF,0xFA,0xFF,0xFE,0xFF,0xFD,0xFF,0xF7,0xFF, + 0xFB,0xFF,0xF9,0xFF,0xFB,0xFF,0xFA,0xFF,0x03,0x00,0xFB,0xFF, + 0x00,0x00,0xF8,0xFF,0xFB,0xFF,0xFC,0xFF,0xF7,0xFF,0xFF,0xFF, + 0xFD,0xFF,0xF6,0xFF,0xFA,0xFF,0xEE,0xFF,0xF4,0xFF,0xF9,0xFF, + 0xED,0xFF,0xF5,0xFF,0xF4,0xFF,0xF6,0xFF,0xFC,0xFF,0xEF,0xFF, + 0xEC,0xFF,0xEF,0xFF,0xEA,0xFF,0xEA,0xFF,0xE3,0xFF,0xED,0xFF, + 0xEC,0xFF,0xE8,0xFF,0xF2,0xFF,0xE8,0xFF,0xE9,0xFF,0xE6,0xFF, + 0xE3,0xFF,0xE5,0xFF,0xE3,0xFF,0xDD,0xFF,0xD8,0xFF,0xE2,0xFF, + 0xDD,0xFF,0xD8,0xFF,0xD8,0xFF,0xE0,0xFF,0xDE,0xFF,0xDD,0xFF, + 0xD7,0xFF,0xD8,0xFF,0xDA,0xFF,0xD1,0xFF,0xD1,0xFF,0xD5,0xFF, + 0xD1,0xFF,0xDA,0xFF,0xD5,0xFF,0xD9,0xFF,0xD4,0xFF,0xD2,0xFF, + 0xD0,0xFF,0xCB,0xFF,0xC7,0xFF,0xC9,0xFF,0xC2,0xFF,0xC2,0xFF, + 0xC2,0xFF,0xC2,0xFF,0xBD,0xFF,0xC1,0xFF,0xC0,0xFF,0xC3,0xFF, + 0xC8,0xFF,0xC5,0xFF,0xD1,0xFF,0xC5,0xFF,0xC1,0xFF,0xCA,0xFF, + 0xC4,0xFF,0xD2,0xFF,0xC5,0xFF,0xC1,0xFF,0xC6,0xFF,0xC8,0xFF, + 0xCA,0xFF,0xC7,0xFF,0xC4,0xFF,0xCA,0xFF,0xCD,0xFF,0xC7,0xFF, + 0xC8,0xFF,0xC9,0xFF,0xD4,0xFF,0xD1,0xFF,0xD0,0xFF,0xD4,0xFF, + 0xD2,0xFF,0xD2,0xFF,0xE5,0xFF,0xDF,0xFF,0xD4,0xFF,0xDB,0xFF, + 0xE4,0xFF,0xE0,0xFF,0xE2,0xFF,0xE5,0xFF,0xE4,0xFF,0xE7,0xFF, + 0xE2,0xFF,0xDD,0xFF,0xE4,0xFF,0xDF,0xFF,0xE1,0xFF,0xE4,0xFF, + 0xE7,0xFF,0xE2,0xFF,0xEB,0xFF,0xE8,0xFF,0xE5,0xFF,0xF0,0xFF, + 0xEF,0xFF,0xF7,0xFF,0xF3,0xFF,0xEB,0xFF,0xF2,0xFF,0xF0,0xFF, + 0xFB,0xFF,0xF2,0xFF,0xF9,0xFF,0xFD,0xFF,0xF9,0xFF,0xFA,0xFF, + 0xFD,0xFF,0xFD,0xFF,0x05,0x00,0xFC,0xFF,0xFB,0xFF,0x02,0x00, + 0xFF,0xFF,0x09,0x00,0x0C,0x00,0x01,0x00,0xFD,0xFF,0xFA,0xFF, + 0xFD,0xFF,0x00,0x00,0xF8,0xFF,0xF6,0xFF,0xFA,0xFF,0xFC,0xFF, + 0xEF,0xFF,0xF3,0xFF,0xF2,0xFF,0xF1,0xFF,0xF0,0xFF,0xF8,0xFF, + 0xF5,0xFF,0xEC,0xFF,0xEE,0xFF,0xF0,0xFF,0xFA,0xFF,0xF1,0xFF, + 0xF1,0xFF,0xEF,0xFF,0xF6,0xFF,0xED,0xFF,0xEB,0xFF,0xED,0xFF, + 0xE8,0xFF,0xF1,0xFF,0xE7,0xFF,0xED,0xFF,0xEC,0xFF,0xE8,0xFF, + 0xE7,0xFF,0xE3,0xFF,0xE4,0xFF,0xE2,0xFF,0xE1,0xFF,0xDF,0xFF, + 0xE5,0xFF,0xE6,0xFF,0xEA,0xFF,0xE0,0xFF,0xE2,0xFF,0xE4,0xFF, + 0xE7,0xFF,0xE5,0xFF,0xEB,0xFF,0xE8,0xFF,0xE2,0xFF,0xDF,0xFF, + 0xDC,0xFF,0xD7,0xFF,0xDC,0xFF,0xD4,0xFF,0xD3,0xFF,0xD7,0xFF, + 0xCF,0xFF,0xCD,0xFF,0xD3,0xFF,0xD5,0xFF,0xD1,0xFF,0xD4,0xFF, + 0xD9,0xFF,0xDC,0xFF,0xD6,0xFF,0xDC,0xFF,0xD8,0xFF,0xDD,0xFF, + 0xDE,0xFF,0xD4,0xFF,0xD6,0xFF,0xD4,0xFF,0xD9,0xFF,0xDB,0xFF, + 0xD9,0xFF,0xDC,0xFF,0xDD,0xFF,0xDB,0xFF,0xE0,0xFF,0xE1,0xFF, + 0xE8,0xFF,0xDF,0xFF,0xE1,0xFF,0xE1,0xFF,0xDC,0xFF,0xDF,0xFF, + 0xE2,0xFF,0xE1,0xFF,0xDE,0xFF,0xE1,0xFF,0xDF,0xFF,0xDF,0xFF, + 0xDC,0xFF,0xDC,0xFF,0xDB,0xFF,0xD8,0xFF,0xD9,0xFF,0xD5,0xFF, + 0xD9,0xFF,0xDC,0xFF,0xE2,0xFF,0xDD,0xFF,0xDB,0xFF,0xDF,0xFF, + 0xDA,0xFF,0xDC,0xFF,0xE1,0xFF,0xE7,0xFF,0xE4,0xFF,0xE2,0xFF, + 0xE2,0xFF,0xE6,0xFF,0xEB,0xFF,0xE8,0xFF,0xE8,0xFF,0xEE,0xFF, + 0xEE,0xFF,0xEE,0xFF,0xED,0xFF,0xF7,0xFF,0xFE,0xFF,0x02,0x00, + 0xF9,0xFF,0xFD,0xFF,0xFC,0xFF,0xF6,0xFF,0xF4,0xFF,0xFB,0xFF, + 0xF5,0xFF,0xF8,0xFF,0xF4,0xFF,0xEB,0xFF,0xE6,0xFF,0xED,0xFF, + 0xEB,0xFF,0xF1,0xFF,0xEC,0xFF,0xF1,0xFF,0xE6,0xFF,0xE8,0xFF, + 0xE6,0xFF,0xF0,0xFF,0xF1,0xFF,0xEB,0xFF,0xF0,0xFF,0xE3,0xFF, + 0xE4,0xFF,0xE3,0xFF,0xE2,0xFF,0xE9,0xFF,0xE6,0xFF,0xE7,0xFF, + 0xE6,0xFF,0xE5,0xFF,0xE3,0xFF,0xE5,0xFF,0xE5,0xFF,0xDB,0xFF, + 0xD9,0xFF,0xDF,0xFF,0xE0,0xFF,0xD9,0xFF,0xE7,0xFF,0xE0,0xFF, + 0xE0,0xFF,0xDE,0xFF,0xD5,0xFF,0xDE,0xFF,0xD7,0xFF,0xDA,0xFF, + 0xDA,0xFF,0xDA,0xFF,0xD6,0xFF,0xCE,0xFF,0xD2,0xFF,0xD7,0xFF, + 0xD7,0xFF,0xD0,0xFF,0xCB,0xFF,0xCB,0xFF,0xCA,0xFF,0xC8,0xFF, + 0xC5,0xFF,0xC9,0xFF,0xC4,0xFF,0xC4,0xFF,0xC8,0xFF,0xC7,0xFF, + 0xC5,0xFF,0xC3,0xFF,0xC7,0xFF,0xC4,0xFF,0xC6,0xFF,0xC6,0xFF, + 0xC3,0xFF,0xC5,0xFF,0xC7,0xFF,0xC8,0xFF,0xC3,0xFF,0xC6,0xFF, + 0xC4,0xFF,0xC4,0xFF,0xC9,0xFF,0xC2,0xFF,0xC7,0xFF,0xC4,0xFF, + 0xC6,0xFF,0xC1,0xFF,0xC5,0xFF,0xC4,0xFF,0xCA,0xFF,0xC5,0xFF, + 0xC9,0xFF,0xC3,0xFF,0xCB,0xFF,0xC8,0xFF,0xCD,0xFF,0xCA,0xFF, + 0xC6,0xFF,0xC6,0xFF,0xC8,0xFF,0xCD,0xFF,0xD1,0xFF,0xCE,0xFF, + 0xCE,0xFF,0xCE,0xFF,0xD2,0xFF,0xCC,0xFF,0xCF,0xFF,0xD5,0xFF, + 0xD8,0xFF,0xD5,0xFF,0xD8,0xFF,0xD2,0xFF,0xD5,0xFF,0xD7,0xFF, + 0xDB,0xFF,0xDA,0xFF,0xDD,0xFF,0xDF,0xFF,0xE1,0xFF,0xDC,0xFF, + 0xE2,0xFF,0xE9,0xFF,0xE8,0xFF,0xEB,0xFF,0xED,0xFF,0xEB,0xFF, + 0xE9,0xFF,0xEC,0xFF,0xEC,0xFF,0xF0,0xFF,0xF5,0xFF,0xF0,0xFF, + 0xF2,0xFF,0xF7,0xFF,0xF3,0xFF,0xF8,0xFF,0xF4,0xFF,0xEB,0xFF, + 0xF1,0xFF,0xEA,0xFF,0xEF,0xFF,0xED,0xFF,0xF0,0xFF,0xEC,0xFF, + 0xEC,0xFF,0xEC,0xFF,0xEE,0xFF,0xE8,0xFF,0xEA,0xFF,0xF2,0xFF, + 0xED,0xFF,0xE9,0xFF,0xEA,0xFF,0xE7,0xFF,0xE4,0xFF,0xE5,0xFF, + 0xE0,0xFF,0xE2,0xFF,0xDE,0xFF,0xDE,0xFF,0xDF,0xFF,0xDD,0xFF, + 0xDC,0xFF,0xDF,0xFF,0xDB,0xFF,0xE5,0xFF,0xE1,0xFF,0xE2,0xFF, + 0xE1,0xFF,0xE1,0xFF,0xE3,0xFF,0xDA,0xFF,0xD5,0xFF,0xD8,0xFF, + 0xD6,0xFF,0xDD,0xFF,0xD8,0xFF,0xDB,0xFF,0xD5,0xFF,0xD9,0xFF, + 0xD3,0xFF,0xD5,0xFF,0xD4,0xFF,0xD5,0xFF,0xD5,0xFF,0xD0,0xFF, + 0xCF,0xFF,0xCF,0xFF,0xCE,0xFF,0xCB,0xFF,0xC6,0xFF,0xC5,0xFF, + 0xC5,0xFF,0xC3,0xFF,0xC3,0xFF,0xC4,0xFF,0xC7,0xFF,0xC8,0xFF, + 0xBE,0xFF,0xC6,0xFF,0xC3,0xFF,0xC7,0xFF,0xC8,0xFF,0xCB,0xFF, + 0xCF,0xFF,0xD2,0xFF,0xCF,0xFF,0xCC,0xFF,0xCE,0xFF,0xD6,0xFF, + 0xD3,0xFF,0xD6,0xFF,0xD5,0xFF,0xD5,0xFF,0xD8,0xFF,0xD4,0xFF, + 0xD0,0xFF,0xD4,0xFF,0xD8,0xFF,0xE0,0xFF,0xDE,0xFF,0xD9,0xFF, + 0xDC,0xFF,0xD7,0xFF,0xDB,0xFF,0xDC,0xFF,0xDA,0xFF,0xDC,0xFF, + 0xDA,0xFF,0xD6,0xFF,0xD7,0xFF,0xDA,0xFF,0xDA,0xFF,0xD7,0xFF, + 0xD7,0xFF,0xE1,0xFF,0xD9,0xFF,0xDB,0xFF,0xDA,0xFF,0xD9,0xFF, + 0xD3,0xFF,0xDC,0xFF,0xD7,0xFF,0xDF,0xFF,0xE1,0xFF,0xE2,0xFF, + 0xDF,0xFF,0xE5,0xFF,0xE1,0xFF,0xE8,0xFF,0xEF,0xFF,0xF5,0xFF, + 0xE8,0xFF,0xEE,0xFF,0xF0,0xFF,0xEE,0xFF,0xEF,0xFF,0xEC,0xFF, + 0xEA,0xFF,0xEE,0xFF,0xE5,0xFF,0xE5,0xFF,0xE9,0xFF,0xED,0xFF, + 0xE9,0xFF,0xEB,0xFF,0xE9,0xFF,0xE8,0xFF,0xE3,0xFF,0xE3,0xFF, + 0xE6,0xFF,0xEC,0xFF,0xEB,0xFF,0xEA,0xFF,0xE6,0xFF,0xEF,0xFF, + 0xE9,0xFF,0xE8,0xFF,0xE0,0xFF,0xEA,0xFF,0xEC,0xFF,0xE2,0xFF, + 0xE3,0xFF,0xE3,0xFF,0xE8,0xFF,0xEA,0xFF,0xE7,0xFF,0xE9,0xFF, + 0xE0,0xFF,0xDE,0xFF,0xE9,0xFF,0xE0,0xFF,0xED,0xFF,0xE3,0xFF, + 0xE6,0xFF,0xE3,0xFF,0xDE,0xFF,0xE2,0xFF,0xE4,0xFF,0xDF,0xFF, + 0xE3,0xFF,0xDD,0xFF,0xD4,0xFF,0xD9,0xFF,0xD4,0xFF,0xD4,0xFF, + 0xD6,0xFF,0xD4,0xFF,0xD2,0xFF,0xD4,0xFF,0xD4,0xFF,0xD3,0xFF, + 0xD8,0xFF,0xD4,0xFF,0xD3,0xFF,0xCE,0xFF,0xD1,0xFF,0xCD,0xFF, + 0xCE,0xFF,0xD0,0xFF,0xCF,0xFF,0xC9,0xFF,0xCD,0xFF,0xCD,0xFF, + 0xCC,0xFF,0xCA,0xFF,0xC5,0xFF,0xC5,0xFF,0xC4,0xFF,0xC3,0xFF, + 0xC1,0xFF,0xC6,0xFF,0xC8,0xFF,0xD0,0xFF,0xCB,0xFF,0xC5,0xFF, + 0xCC,0xFF,0xCC,0xFF,0xD8,0xFF,0xD6,0xFF,0xD7,0xFF,0xD5,0xFF, + 0xD8,0xFF,0xD8,0xFF,0xDF,0xFF,0xE0,0xFF,0xD7,0xFF,0xD8,0xFF, + 0xDE,0xFF,0xE3,0xFF,0xDA,0xFF,0xE0,0xFF,0xDD,0xFF,0xE2,0xFF, + 0xE1,0xFF,0xDE,0xFF,0xDC,0xFF,0xDD,0xFF,0xD8,0xFF,0xE1,0xFF, + 0xE1,0xFF,0xDE,0xFF,0xDB,0xFF,0xDA,0xFF,0xD7,0xFF,0xD9,0xFF, + 0xD8,0xFF,0xE0,0xFF,0xE0,0xFF,0xDE,0xFF,0xD6,0xFF,0xD8,0xFF, + 0xDC,0xFF,0xDF,0xFF,0xE5,0xFF,0xE3,0xFF,0xDE,0xFF,0xE4,0xFF, + 0xE8,0xFF,0xEE,0xFF,0xE8,0xFF,0xF2,0xFF,0xEE,0xFF,0xEE,0xFF, + 0xEE,0xFF,0xEE,0xFF,0xF3,0xFF,0xFB,0xFF,0xFA,0xFF,0xF5,0xFF, + 0xF6,0xFF,0xFA,0xFF,0xF4,0xFF,0xEF,0xFF,0xF5,0xFF,0xF9,0xFF, + 0xF3,0xFF,0xEF,0xFF,0xEB,0xFF,0xEE,0xFF,0xF9,0xFF,0xF3,0xFF, + 0xF1,0xFF,0xF1,0xFF,0xF1,0xFF,0xEF,0xFF,0xF5,0xFF,0xEB,0xFF, + 0xEF,0xFF,0xEC,0xFF,0xE7,0xFF,0xEE,0xFF,0xEA,0xFF,0xED,0xFF, + 0xED,0xFF,0xEF,0xFF,0xEC,0xFF,0xE9,0xFF,0xE7,0xFF,0xE9,0xFF, + 0xE8,0xFF,0xED,0xFF,0xF1,0xFF,0xE7,0xFF,0xEE,0xFF,0xEB,0xFF, + 0xEB,0xFF,0xE8,0xFF,0xE4,0xFF,0xE5,0xFF,0xE6,0xFF,0xE4,0xFF, + 0xE6,0xFF,0xE1,0xFF,0xE7,0xFF,0xE1,0xFF,0xE2,0xFF,0xE3,0xFF, + 0xE7,0xFF,0xDD,0xFF,0xDC,0xFF,0xF3,0xFF,0xEA,0xFF,0xE4,0xFF, + 0xE8,0xFF,0xE1,0xFF,0xE6,0xFF,0xDF,0xFF,0xE2,0xFF,0xDF,0xFF, + 0xE3,0xFF,0xE0,0xFF,0xE0,0xFF,0xE1,0xFF,0xDC,0xFF,0xE3,0xFF, + 0xE0,0xFF,0xDA,0xFF,0xE2,0xFF,0xD9,0xFF,0xDB,0xFF,0xE6,0xFF, + 0xE5,0xFF,0xE5,0xFF,0xE4,0xFF,0xE0,0xFF,0xE0,0xFF,0xE1,0xFF, + 0xDE,0xFF,0xDB,0xFF,0xDB,0xFF,0xDB,0xFF,0xDA,0xFF,0xDC,0xFF, + 0xD7,0xFF,0xE1,0xFF,0xE2,0xFF,0xDA,0xFF,0xDC,0xFF,0xDF,0xFF, + 0xDD,0xFF,0xE1,0xFF,0xEB,0xFF,0xE7,0xFF,0xE7,0xFF,0xE2,0xFF, + 0xE9,0xFF,0xE5,0xFF,0xEA,0xFF,0xE9,0xFF,0xE5,0xFF,0xE4,0xFF, + 0xE4,0xFF,0xE7,0xFF,0xEC,0xFF,0xEC,0xFF,0xE6,0xFF,0xEA,0xFF, + 0xEB,0xFF,0xE8,0xFF,0xEA,0xFF,0xE4,0xFF,0xE6,0xFF,0xEB,0xFF, + 0xEF,0xFF,0xEC,0xFF,0xEB,0xFF,0xF0,0xFF,0xF2,0xFF,0xF8,0xFF, + 0xF7,0xFF,0xF0,0xFF,0xF3,0xFF,0xF9,0xFF,0xF6,0xFF,0xFA,0xFF, + 0xFC,0xFF,0xF9,0xFF,0x01,0x00,0xFC,0xFF,0x01,0x00,0x00,0x00, + 0x05,0x00,0x0C,0x00,0x0C,0x00,0x07,0x00,0x0B,0x00,0x04,0x00, + 0x02,0x00,0x02,0x00,0x08,0x00,0xFE,0xFF,0xFC,0xFF,0xFC,0xFF, + 0xF9,0xFF,0xFB,0xFF,0x00,0x00,0x00,0x00,0xFB,0xFF,0xF6,0xFF, + 0xFB,0xFF,0xF9,0xFF,0xFE,0xFF,0xF3,0xFF,0xF2,0xFF,0xF7,0xFF, + 0xEC,0xFF,0xEE,0xFF,0xEF,0xFF,0xF0,0xFF,0xFA,0xFF,0xEF,0xFF, + 0xF0,0xFF,0xE8,0xFF,0xE9,0xFF,0xE8,0xFF,0xDD,0xFF,0xE7,0xFF, + 0xEA,0xFF,0xDE,0xFF,0xE5,0xFF,0xDD,0xFF,0xE5,0xFF,0xE6,0xFF, + 0xE9,0xFF,0xE8,0xFF,0xE5,0xFF,0xE5,0xFF,0xE0,0xFF,0xE0,0xFF, + 0xE9,0xFF,0xE3,0xFF,0xDF,0xFF,0xE3,0xFF,0xDE,0xFF,0xDC,0xFF, + 0xDF,0xFF,0xE0,0xFF,0xDF,0xFF,0xDF,0xFF,0xDF,0xFF,0xD7,0xFF, + 0xD5,0xFF,0xD8,0xFF,0xD6,0xFF,0xE7,0xFF,0xDC,0xFF,0xDC,0xFF, + 0xDC,0xFF,0xDA,0xFF,0xD4,0xFF,0xD6,0xFF,0xD6,0xFF,0xD5,0xFF, + 0xD4,0xFF,0xCF,0xFF,0xCF,0xFF,0xDA,0xFF,0xDE,0xFF,0xE3,0xFF, + 0xD4,0xFF,0xD8,0xFF,0xD4,0xFF,0xDA,0xFF,0xE1,0xFF,0xD7,0xFF, + 0xE3,0xFF,0xDC,0xFF,0xDD,0xFF,0xDA,0xFF,0xDA,0xFF,0xDF,0xFF, + 0xE4,0xFF,0xDC,0xFF,0xE0,0xFF,0xE4,0xFF,0xDE,0xFF,0xD8,0xFF, + 0xDC,0xFF,0xDB,0xFF,0xE0,0xFF,0xD7,0xFF,0xDB,0xFF,0xDD,0xFF, + 0xDA,0xFF,0xDC,0xFF,0xE6,0xFF,0xDC,0xFF,0xDD,0xFF,0xDE,0xFF, + 0xDE,0xFF,0xDD,0xFF,0xDE,0xFF,0xE3,0xFF,0xDE,0xFF,0xE1,0xFF, + 0xE4,0xFF,0xE5,0xFF,0xE7,0xFF,0xE9,0xFF,0xE8,0xFF,0xE7,0xFF, + 0xE1,0xFF,0xE6,0xFF,0xE9,0xFF,0xE6,0xFF,0xEA,0xFF,0xF0,0xFF, + 0xE9,0xFF,0xE9,0xFF,0xEF,0xFF,0xEC,0xFF,0xF2,0xFF,0xF5,0xFF, + 0xED,0xFF,0xF0,0xFF,0xEE,0xFF,0xEB,0xFF,0xEB,0xFF,0xEC,0xFF, + 0xEA,0xFF,0xE9,0xFF,0xEA,0xFF,0xE5,0xFF,0xE9,0xFF,0xE4,0xFF, + 0xEA,0xFF,0xE7,0xFF,0xF0,0xFF,0xEB,0xFF,0xE7,0xFF,0xE8,0xFF, + 0xE7,0xFF,0xE9,0xFF,0xE3,0xFF,0xE4,0xFF,0xE2,0xFF,0xDF,0xFF, + 0xDC,0xFF,0xE1,0xFF,0xE1,0xFF,0xDF,0xFF,0xDE,0xFF,0xDC,0xFF, + 0xDB,0xFF,0xDD,0xFF,0xE0,0xFF,0xDD,0xFF,0xD8,0xFF,0xD9,0xFF, + 0xDA,0xFF,0xD0,0xFF,0xD8,0xFF,0xD9,0xFF,0xDA,0xFF,0xDE,0xFF, + 0xD8,0xFF,0xDA,0xFF,0xD7,0xFF,0xD8,0xFF,0xD9,0xFF,0xD8,0xFF, + 0xD5,0xFF,0xD9,0xFF,0xD3,0xFF,0xD7,0xFF,0xD3,0xFF,0xDA,0xFF, + 0xD8,0xFF,0xD9,0xFF,0xD6,0xFF,0xD6,0xFF,0xD1,0xFF,0xD3,0xFF, + 0xD1,0xFF,0xD4,0xFF,0xCF,0xFF,0xCD,0xFF,0xCB,0xFF,0xCC,0xFF, + 0xCA,0xFF,0xCA,0xFF,0xCD,0xFF,0xCB,0xFF,0xCE,0xFF,0xD3,0xFF, + 0xCC,0xFF,0xCE,0xFF,0xCE,0xFF,0xCC,0xFF,0xCE,0xFF,0xD1,0xFF, + 0xD0,0xFF,0xD0,0xFF,0xD6,0xFF,0xD8,0xFF,0xD9,0xFF,0xD8,0xFF, + 0xDE,0xFF,0xDB,0xFF,0xD6,0xFF,0xD8,0xFF,0xDE,0xFF,0xD7,0xFF, + 0xE3,0xFF,0xDC,0xFF,0xE0,0xFF,0xDE,0xFF,0xDB,0xFF,0xD6,0xFF, + 0xDD,0xFF,0xDB,0xFF,0xDD,0xFF,0xDB,0xFF,0xE2,0xFF,0xE3,0xFF, + 0xE3,0xFF,0xD6,0xFF,0xDC,0xFF,0xE1,0xFF,0xDF,0xFF,0xDB,0xFF, + 0xDC,0xFF,0xD8,0xFF,0xDE,0xFF,0xDC,0xFF,0xDE,0xFF,0xE4,0xFF, + 0xE4,0xFF,0xE3,0xFF,0xE4,0xFF,0xEA,0xFF,0xED,0xFF,0xF1,0xFF, + 0xF3,0xFF,0xF2,0xFF,0xF2,0xFF,0xF7,0xFF,0xF7,0xFF,0xF1,0xFF, + 0xF5,0xFF,0xF6,0xFF,0xFB,0xFF,0xF0,0xFF,0xF5,0xFF,0xF5,0xFF, + 0xF4,0xFF,0xF9,0xFF,0xF8,0xFF,0xFB,0xFF,0xF9,0xFF,0xF5,0xFF, + 0xF3,0xFF,0xF7,0xFF,0xF3,0xFF,0xF6,0xFF,0xF6,0xFF,0xF7,0xFF, + 0xF7,0xFF,0xF1,0xFF,0xEA,0xFF,0xF2,0xFF,0xF1,0xFF,0xF4,0xFF, + 0xF0,0xFF,0xF4,0xFF,0xEA,0xFF,0xEA,0xFF,0xED,0xFF,0xEE,0xFF, + 0xED,0xFF,0xE6,0xFF,0xE2,0xFF,0xEA,0xFF,0xE3,0xFF,0xE4,0xFF, + 0xDD,0xFF,0xE1,0xFF,0xD8,0xFF,0xD9,0xFF,0xD8,0xFF,0xE0,0xFF, + 0xE1,0xFF,0xDB,0xFF,0xD9,0xFF,0xDB,0xFF,0xD6,0xFF,0xD3,0xFF, + 0xD0,0xFF,0xD8,0xFF,0xD3,0xFF,0xD5,0xFF,0xD2,0xFF,0xCE,0xFF, + 0xD3,0xFF,0xD6,0xFF,0xD7,0xFF,0xD5,0xFF,0xD4,0xFF,0xCD,0xFF, + 0xCB,0xFF,0xCF,0xFF,0xD0,0xFF,0xCC,0xFF,0xCC,0xFF,0xCA,0xFF, + 0xC2,0xFF,0xBF,0xFF,0xC0,0xFF,0xC5,0xFF,0xC4,0xFF,0xC3,0xFF, + 0xC2,0xFF,0xC4,0xFF,0xBF,0xFF,0xC7,0xFF,0xC6,0xFF,0xCD,0xFF, + 0xC8,0xFF,0xCA,0xFF,0xC8,0xFF,0xC0,0xFF,0xC0,0xFF,0xC1,0xFF, + 0xCC,0xFF,0xC5,0xFF,0xC7,0xFF,0xC2,0xFF,0xC7,0xFF,0xC4,0xFF, + 0xC7,0xFF,0xCA,0xFF,0xCB,0xFF,0xC6,0xFF,0xC8,0xFF,0xCB,0xFF, + 0xCC,0xFF,0xCE,0xFF,0xCF,0xFF,0xCD,0xFF,0xD2,0xFF,0xCA,0xFF, + 0xCC,0xFF,0xCB,0xFF,0xCB,0xFF,0xC8,0xFF,0xBF,0xFF,0xC5,0xFF, + 0xC5,0xFF,0xC1,0xFF,0xC7,0xFF,0xC8,0xFF,0xCA,0xFF,0xC6,0xFF, + 0xC6,0xFF,0xCA,0xFF,0xCC,0xFF,0xD0,0xFF,0xD3,0xFF,0xD7,0xFF, + 0xD8,0xFF,0xD8,0xFF,0xDB,0xFF,0xDB,0xFF,0xD9,0xFF,0xE1,0xFF, + 0xE0,0xFF,0xDF,0xFF,0xDA,0xFF,0xDE,0xFF,0xE8,0xFF,0xE6,0xFF, + 0xE6,0xFF,0xDC,0xFF,0xE3,0xFF,0xE3,0xFF,0xE5,0xFF,0xE2,0xFF, + 0xDF,0xFF,0xE2,0xFF,0xE3,0xFF,0xE9,0xFF,0xE7,0xFF,0xE2,0xFF, + 0xDF,0xFF,0xE2,0xFF,0xE1,0xFF,0xE6,0xFF,0xDF,0xFF,0xE4,0xFF, + 0xE0,0xFF,0xE2,0xFF,0xE4,0xFF,0xE7,0xFF,0xE7,0xFF,0xE2,0xFF, + 0xE4,0xFF,0xE2,0xFF,0xDF,0xFF,0xE5,0xFF,0xE8,0xFF,0xE5,0xFF, + 0xE1,0xFF,0xDF,0xFF,0xE3,0xFF,0xE9,0xFF,0xE0,0xFF,0xE4,0xFF, + 0xE5,0xFF,0xE3,0xFF,0xDB,0xFF,0xE0,0xFF,0xE5,0xFF,0xE0,0xFF, + 0xE1,0xFF,0xD6,0xFF,0xDA,0xFF,0xDB,0xFF,0xD5,0xFF,0xDE,0xFF, + 0xD9,0xFF,0xD7,0xFF,0xD5,0xFF,0xD4,0xFF,0xD3,0xFF,0xD1,0xFF, + 0xDD,0xFF,0xD3,0xFF,0xD3,0xFF,0xD5,0xFF,0xD5,0xFF,0xD3,0xFF, + 0xD3,0xFF,0xCC,0xFF,0xC9,0xFF,0xCF,0xFF,0xCA,0xFF,0xC8,0xFF, + 0xD3,0xFF,0xD5,0xFF,0xD4,0xFF,0xCD,0xFF,0xCE,0xFF,0xCD,0xFF, + 0xCE,0xFF,0xCF,0xFF,0xCC,0xFF,0xD0,0xFF,0xD0,0xFF,0xD0,0xFF, + 0xCD,0xFF,0xCC,0xFF,0xCF,0xFF,0xCA,0xFF,0xD0,0xFF,0xCF,0xFF, + 0xD3,0xFF,0xD4,0xFF,0xD4,0xFF,0xD9,0xFF,0xD4,0xFF,0xD2,0xFF, + 0xD4,0xFF,0xD6,0xFF,0xD5,0xFF,0xD7,0xFF,0xDE,0xFF,0xDE,0xFF, + 0xE0,0xFF,0xDD,0xFF,0xDF,0xFF,0xE1,0xFF,0xE5,0xFF,0xDE,0xFF, + 0xDF,0xFF,0xDE,0xFF,0xDB,0xFF,0xDF,0xFF,0xE1,0xFF,0xE0,0xFF, + 0xE4,0xFF,0xE6,0xFF,0xE6,0xFF,0xE2,0xFF,0xE2,0xFF,0xDE,0xFF, + 0xE3,0xFF,0xE8,0xFF,0xE4,0xFF,0xED,0xFF,0xE9,0xFF,0xEC,0xFF, + 0xED,0xFF,0xED,0xFF,0xEB,0xFF,0xE8,0xFF,0xEF,0xFF,0xF1,0xFF, + 0xF4,0xFF,0xF1,0xFF,0xEC,0xFF,0xF0,0xFF,0xF5,0xFF,0xF3,0xFF, + 0xF0,0xFF,0xF3,0xFF,0xF5,0xFF,0xF4,0xFF,0xF9,0xFF,0xF6,0xFF, + 0xED,0xFF,0xF0,0xFF,0xED,0xFF,0xF4,0xFF,0xF3,0xFF,0xF0,0xFF, + 0xF2,0xFF,0xF0,0xFF,0xF1,0xFF,0xF8,0xFF,0xF0,0xFF,0xF4,0xFF, + 0xF6,0xFF,0xF5,0xFF,0xF6,0xFF,0xEC,0xFF,0xEF,0xFF,0xF0,0xFF, + 0xF2,0xFF,0xEF,0xFF,0xEE,0xFF,0xEB,0xFF,0xEE,0xFF,0xE9,0xFF, + 0xEE,0xFF,0xE9,0xFF,0xE5,0xFF,0xDD,0xFF,0xE1,0xFF,0xE3,0xFF, + 0xDC,0xFF,0xDA,0xFF,0xD9,0xFF,0xDA,0xFF,0xDD,0xFF,0xD9,0xFF, + 0xDB,0xFF,0xDA,0xFF,0xDA,0xFF,0xE2,0xFF,0xE0,0xFF,0xD9,0xFF, + 0xDA,0xFF,0xD3,0xFF,0xDB,0xFF,0xD6,0xFF,0xD5,0xFF,0xD3,0xFF, + 0xD4,0xFF,0xD4,0xFF,0xD5,0xFF,0xCB,0xFF,0xCF,0xFF,0xCE,0xFF, + 0xC9,0xFF,0xCD,0xFF,0xC8,0xFF,0xC7,0xFF,0xD0,0xFF,0xCA,0xFF, + 0xCC,0xFF,0xC5,0xFF,0xC8,0xFF,0xC4,0xFF,0xCA,0xFF,0xCA,0xFF, + 0xCF,0xFF,0xC6,0xFF,0xC9,0xFF,0xC3,0xFF,0xCA,0xFF,0xD0,0xFF, + 0xD1,0xFF,0xCF,0xFF,0xD2,0xFF,0xD2,0xFF,0xD1,0xFF,0xD2,0xFF, + 0xD0,0xFF,0xD4,0xFF,0xD9,0xFF,0xD5,0xFF,0xD7,0xFF,0xDB,0xFF, + 0xDC,0xFF,0xE0,0xFF,0xE0,0xFF,0xE2,0xFF,0xDA,0xFF,0xDA,0xFF, + 0xDC,0xFF,0xDE,0xFF,0xE0,0xFF,0xE6,0xFF,0xDB,0xFF,0xE2,0xFF, + 0xDB,0xFF,0xDD,0xFF,0xE0,0xFF,0xDF,0xFF,0xD9,0xFF,0xE8,0xFF, + 0xDF,0xFF,0xD9,0xFF,0xD8,0xFF,0xE0,0xFF,0xDF,0xFF,0xE2,0xFF, + 0xE0,0xFF,0xE2,0xFF,0xDF,0xFF,0xE3,0xFF,0xE5,0xFF,0xEC,0xFF, + 0xEA,0xFF,0xEE,0xFF,0xED,0xFF,0xE8,0xFF,0xEC,0xFF,0xEE,0xFF, + 0xF0,0xFF,0xED,0xFF,0xF1,0xFF,0xF1,0xFF,0xF0,0xFF,0xF1,0xFF, + 0xF2,0xFF,0xF1,0xFF,0xF0,0xFF,0xF4,0xFF,0xEE,0xFF,0xEF,0xFF, + 0xEA,0xFF,0xEA,0xFF,0xF2,0xFF,0xEA,0xFF,0xED,0xFF,0xED,0xFF, + 0xEF,0xFF,0xF1,0xFF,0xF0,0xFF,0xF4,0xFF,0xFA,0xFF,0xFB,0xFF, + 0xF3,0xFF,0xF4,0xFF,0xEE,0xFF,0xF3,0xFF,0xF2,0xFF,0xED,0xFF, + 0xE9,0xFF,0xE8,0xFF,0xE2,0xFF,0xE6,0xFF,0xE9,0xFF,0xF0,0xFF, + 0xED,0xFF,0xE6,0xFF,0xE5,0xFF,0xE6,0xFF,0xED,0xFF,0xE6,0xFF, + 0xE4,0xFF,0xEE,0xFF,0xEB,0xFF,0xE3,0xFF,0xEC,0xFF,0xEC,0xFF, + 0xE8,0xFF,0xE9,0xFF,0xE6,0xFF,0xE2,0xFF,0xE2,0xFF,0xDE,0xFF, + 0xDE,0xFF,0xDD,0xFF,0xDC,0xFF,0xDB,0xFF,0xD8,0xFF,0xD2,0xFF, + 0xDA,0xFF,0xDB,0xFF,0xD4,0xFF,0xDA,0xFF,0xDD,0xFF,0xD7,0xFF, + 0xD2,0xFF,0xD5,0xFF,0xD7,0xFF,0xD8,0xFF,0xD6,0xFF,0xD6,0xFF, + 0xD3,0xFF,0xD3,0xFF,0xDB,0xFF,0xD7,0xFF,0xD9,0xFF,0xD9,0xFF, + 0xD9,0xFF,0xDF,0xFF,0xD7,0xFF,0xDF,0xFF,0xE1,0xFF,0xDD,0xFF, + 0xDC,0xFF,0xD7,0xFF,0xD9,0xFF,0xDC,0xFF,0xD4,0xFF,0xD5,0xFF, + 0xD8,0xFF,0xD6,0xFF,0xD6,0xFF,0xD8,0xFF,0xD3,0xFF,0xDA,0xFF, + 0xD8,0xFF,0xD9,0xFF,0xDF,0xFF,0xDF,0xFF,0xDC,0xFF,0xE6,0xFF, + 0xE5,0xFF,0xE1,0xFF,0xE1,0xFF,0xE3,0xFF,0xDD,0xFF,0xE0,0xFF, + 0xE3,0xFF,0xE5,0xFF,0xE4,0xFF,0xE3,0xFF,0xE6,0xFF,0xE2,0xFF, + 0xE0,0xFF,0xE1,0xFF,0xE4,0xFF,0xE7,0xFF,0xE6,0xFF,0xE3,0xFF, + 0xE1,0xFF,0xE2,0xFF,0xE6,0xFF,0xE9,0xFF,0xE8,0xFF,0xF1,0xFF, + 0xEA,0xFF,0xEE,0xFF,0xF3,0xFF,0xF2,0xFF,0xF9,0xFF,0xF4,0xFF, + 0xF3,0xFF,0xF2,0xFF,0xF5,0xFF,0xF6,0xFF,0xFA,0xFF,0xF4,0xFF, + 0xF0,0xFF,0xF8,0xFF,0xF1,0xFF,0xF6,0xFF,0xF3,0xFF,0xF4,0xFF, + 0xF0,0xFF,0xF2,0xFF,0xED,0xFF,0xF0,0xFF,0xED,0xFF,0xE8,0xFF, + 0xF3,0xFF,0xF0,0xFF,0xEF,0xFF,0xEA,0xFF,0xE9,0xFF,0xEA,0xFF, + 0xEB,0xFF,0xE7,0xFF,0xE7,0xFF,0xDE,0xFF,0xDB,0xFF,0xDC,0xFF, + 0xE1,0xFF,0xDE,0xFF,0xDD,0xFF,0xD9,0xFF,0xDF,0xFF,0xDD,0xFF, + 0xD6,0xFF,0xDB,0xFF,0xDD,0xFF,0xDC,0xFF,0xD5,0xFF,0xD5,0xFF, + 0xD5,0xFF,0xD4,0xFF,0xD5,0xFF,0xD5,0xFF,0xD2,0xFF,0xD1,0xFF, + 0xD5,0xFF,0xD5,0xFF,0xD0,0xFF,0xD6,0xFF,0xD6,0xFF,0xD5,0xFF, + 0xD4,0xFF,0xD1,0xFF,0xD0,0xFF,0xD0,0xFF,0xCE,0xFF,0xCD,0xFF, + 0xD2,0xFF,0xCE,0xFF,0xC9,0xFF,0xC6,0xFF,0xCC,0xFF,0xCC,0xFF, + 0xCB,0xFF,0xCA,0xFF,0xCB,0xFF,0xC6,0xFF,0xC6,0xFF,0xC5,0xFF, + 0xC6,0xFF,0xC3,0xFF,0xBE,0xFF,0xC5,0xFF,0xC7,0xFF,0xBF,0xFF, + 0xBF,0xFF,0xC3,0xFF,0xC1,0xFF,0xB9,0xFF,0xBA,0xFF,0xC5,0xFF, + 0xC8,0xFF,0xCF,0xFF,0xD2,0xFF,0xD2,0xFF,0xC4,0xFF,0xC6,0xFF, + 0xCE,0xFF,0xDB,0xFF,0xCB,0xFF,0xD0,0xFF,0xCC,0xFF,0xBD,0xFF, + 0xD8,0xFF,0xE3,0xFF,0xCB,0xFF,0xC8,0xFF,0xDC,0xFF,0xCD,0xFF, + 0xDA,0xFF,0xE0,0xFF,0xCE,0xFF,0xE1,0xFF,0xDF,0xFF,0xD8,0xFF, + 0xD7,0xFF,0xD3,0xFF,0xD1,0xFF,0xD8,0xFF,0xD8,0xFF,0xD5,0xFF, + 0xD3,0xFF,0xD1,0xFF,0xDF,0xFF,0xE2,0xFF,0xD8,0xFF,0xDF,0xFF, + 0xE2,0xFF,0xDB,0xFF,0xE4,0xFF,0xE4,0xFF,0xE7,0xFF,0xE3,0xFF, + 0xE2,0xFF,0xE1,0xFF,0xE9,0xFF,0xDE,0xFF,0xE4,0xFF,0xEE,0xFF, + 0xF2,0xFF,0xF1,0xFF,0xF3,0xFF,0xED,0xFF,0xEE,0xFF,0xE7,0xFF, + 0xE8,0xFF,0xF1,0xFF,0xF1,0xFF,0xF0,0xFF,0xF0,0xFF,0xEC,0xFF, + 0xEA,0xFF,0xEB,0xFF,0xF4,0xFF,0xEC,0xFF,0xEF,0xFF,0xEF,0xFF, + 0xE9,0xFF,0xE7,0xFF,0xED,0xFF,0xF1,0xFF,0xF6,0xFF,0xF7,0xFF, + 0xED,0xFF,0xE5,0xFF,0xF1,0xFF,0xEE,0xFF,0xE7,0xFF,0xEE,0xFF, + 0xEA,0xFF,0xE7,0xFF,0xE8,0xFF,0xE9,0xFF,0xE8,0xFF,0xEC,0xFF, + 0xF1,0xFF,0xEC,0xFF,0xE5,0xFF,0xDC,0xFF,0xE1,0xFF,0xE1,0xFF, + 0xE6,0xFF,0xDE,0xFF,0xE3,0xFF,0xE2,0xFF,0xDD,0xFF,0xE0,0xFF, + 0xDC,0xFF,0xE0,0xFF,0xDB,0xFF,0xDD,0xFF,0xDA,0xFF,0xDA,0xFF, + 0xDA,0xFF,0xD9,0xFF,0xDC,0xFF,0xDB,0xFF,0xD1,0xFF,0xD9,0xFF, + 0xD6,0xFF,0xDA,0xFF,0xD3,0xFF,0xD9,0xFF,0xD3,0xFF,0xCF,0xFF, + 0xCE,0xFF,0xCC,0xFF,0xD1,0xFF,0xD2,0xFF,0xD4,0xFF,0xD1,0xFF, + 0xCF,0xFF,0xCF,0xFF,0xD1,0xFF,0xDB,0xFF,0xDB,0xFF,0xDA,0xFF, + 0xD4,0xFF,0xCF,0xFF,0xCD,0xFF,0xCA,0xFF,0xCE,0xFF,0xD6,0xFF, + 0xD8,0xFF,0xD7,0xFF,0xD3,0xFF,0xD7,0xFF,0xCF,0xFF,0xDA,0xFF, + 0xD8,0xFF,0xD8,0xFF,0xD9,0xFF,0xD9,0xFF,0xD7,0xFF,0xDC,0xFF, + 0xDD,0xFF,0xDA,0xFF,0xD3,0xFF,0xCF,0xFF,0xCE,0xFF,0xCE,0xFF, + 0xD4,0xFF,0xCF,0xFF,0xD2,0xFF,0xD5,0xFF,0xD3,0xFF,0xD0,0xFF, + 0xD3,0xFF,0xDA,0xFF,0xDB,0xFF,0xD8,0xFF,0xDD,0xFF,0xDB,0xFF, + 0xE2,0xFF,0xDD,0xFF,0xDF,0xFF,0xE1,0xFF,0xE3,0xFF,0xE5,0xFF, + 0xE4,0xFF,0xDF,0xFF,0xE2,0xFF,0xE4,0xFF,0xEB,0xFF,0xEA,0xFF, + 0xEB,0xFF,0xF2,0xFF,0xF5,0xFF,0xF4,0xFF,0xF5,0xFF,0xF0,0xFF, + 0xF3,0xFF,0xF0,0xFF,0xF1,0xFF,0xF7,0xFF,0xFB,0xFF,0xF8,0xFF, + 0xF7,0xFF,0xF5,0xFF,0xF6,0xFF,0xEE,0xFF,0xF9,0xFF,0xF4,0xFF, + 0xF6,0xFF,0xF0,0xFF,0xEF,0xFF,0xF6,0xFF,0xF4,0xFF,0xF5,0xFF, + 0xF5,0xFF,0xF1,0xFF,0xF4,0xFF,0xEE,0xFF,0xF0,0xFF,0xEE,0xFF, + 0xF0,0xFF,0xF3,0xFF,0xF3,0xFF,0xF2,0xFF,0xE6,0xFF,0xE6,0xFF, + 0xEB,0xFF,0xE8,0xFF,0xE5,0xFF,0xE2,0xFF,0xDB,0xFF,0xE6,0xFF, + 0xE4,0xFF,0xDB,0xFF,0xDD,0xFF,0xE0,0xFF,0xDE,0xFF,0xDD,0xFF, + 0xDA,0xFF,0xE5,0xFF,0xE5,0xFF,0xE7,0xFF,0xE5,0xFF,0xE6,0xFF, + 0xE4,0xFF,0xE0,0xFF,0xE1,0xFF,0xDF,0xFF,0xDE,0xFF,0xDA,0xFF, + 0xD9,0xFF,0xDB,0xFF,0xDC,0xFF,0xE0,0xFF,0xD7,0xFF,0xDD,0xFF, + 0xD6,0xFF,0xDC,0xFF,0xDB,0xFF,0xDC,0xFF,0xD5,0xFF,0xDA,0xFF, + 0xDA,0xFF,0xD8,0xFF,0xD5,0xFF,0xD4,0xFF,0xD2,0xFF,0xD5,0xFF, + 0xD4,0xFF,0xDC,0xFF,0xD9,0xFF,0xD0,0xFF,0xD2,0xFF,0xD3,0xFF, + 0xD4,0xFF,0xD8,0xFF,0xD8,0xFF,0xDD,0xFF,0xDD,0xFF,0xE0,0xFF, + 0xDD,0xFF,0xDC,0xFF,0xE0,0xFF,0xE2,0xFF,0xDF,0xFF,0xDB,0xFF, + 0xDD,0xFF,0xD9,0xFF,0xE0,0xFF,0xE0,0xFF,0xD8,0xFF,0xDC,0xFF, + 0xE0,0xFF,0xE3,0xFF,0xE7,0xFF,0xE6,0xFF,0xE4,0xFF,0xDF,0xFF, + 0xE6,0xFF,0xDC,0xFF,0xE1,0xFF,0xDC,0xFF,0xDD,0xFF,0xE0,0xFF, + 0xDE,0xFF,0xE5,0xFF,0xE4,0xFF,0xE2,0xFF,0xE1,0xFF,0xE4,0xFF, + 0xED,0xFF,0xE7,0xFF,0xE9,0xFF,0xE9,0xFF,0xEC,0xFF,0xF0,0xFF, + 0xEF,0xFF,0xEE,0xFF,0xF6,0xFF,0xEF,0xFF,0xF4,0xFF,0xF3,0xFF, + 0xF8,0xFF,0xFB,0xFF,0xF8,0xFF,0xF7,0xFF,0xFC,0xFF,0xFF,0xFF, + 0xFF,0xFF,0x02,0x00,0x0C,0x00,0x02,0x00,0x01,0x00,0x01,0x00, + 0xFC,0xFF,0xFC,0xFF,0xFD,0xFF,0xFE,0xFF,0xFB,0xFF,0xF7,0xFF, + 0xF2,0xFF,0xF2,0xFF,0xF8,0xFF,0xF3,0xFF,0xEE,0xFF,0xEF,0xFF, + 0xF2,0xFF,0xF6,0xFF,0xF3,0xFF,0xF5,0xFF,0xF4,0xFF,0xF4,0xFF, + 0xF2,0xFF,0xE8,0xFF,0xE0,0xFF,0xDF,0xFF,0xE3,0xFF,0xEB,0xFF, + 0xE1,0xFF,0xE3,0xFF,0xE6,0xFF,0xE0,0xFF,0xE0,0xFF,0xE4,0xFF, + 0xE3,0xFF,0xDE,0xFF,0xDD,0xFF,0xE1,0xFF,0xDF,0xFF,0xE1,0xFF, + 0xE0,0xFF,0xE4,0xFF,0xE4,0xFF,0xE3,0xFF,0xDC,0xFF,0xD8,0xFF, + 0xDB,0xFF,0xD8,0xFF,0xD8,0xFF,0xD9,0xFF,0xDB,0xFF,0xD7,0xFF, + 0xD2,0xFF,0xD9,0xFF,0xD7,0xFF,0xD7,0xFF,0xD3,0xFF,0xD2,0xFF, + 0xD9,0xFF,0xCF,0xFF,0xD2,0xFF,0xD6,0xFF,0xD3,0xFF,0xCF,0xFF, + 0xD2,0xFF,0xD1,0xFF,0xCD,0xFF,0xCB,0xFF,0xCF,0xFF,0xD2,0xFF, + 0xCD,0xFF,0xC8,0xFF,0xC9,0xFF,0xC8,0xFF,0xCE,0xFF,0xCD,0xFF, + 0xCA,0xFF,0xD0,0xFF,0xD1,0xFF,0xC6,0xFF,0xCC,0xFF,0xD9,0xFF, + 0xD6,0xFF,0xD3,0xFF,0xCF,0xFF,0xD1,0xFF,0xD3,0xFF,0xC9,0xFF, + 0xC9,0xFF,0xD0,0xFF,0xD6,0xFF,0xD7,0xFF,0xCE,0xFF,0xCF,0xFF, + 0xCD,0xFF,0xD2,0xFF,0xD5,0xFF,0xD0,0xFF,0xCB,0xFF,0xD5,0xFF, + 0xD7,0xFF,0xD7,0xFF,0xD6,0xFF,0xD2,0xFF,0xD3,0xFF,0xDB,0xFF, + 0xD8,0xFF,0xCE,0xFF,0xC8,0xFF,0xCE,0xFF,0xD8,0xFF,0xD9,0xFF, + 0xD2,0xFF,0xD9,0xFF,0xDD,0xFF,0xDC,0xFF,0xE6,0xFF,0xE7,0xFF, + 0xE5,0xFF,0xE5,0xFF,0xE7,0xFF,0xE8,0xFF,0xE8,0xFF,0xEE,0xFF, + 0xF3,0xFF,0xF4,0xFF,0xF2,0xFF,0xF2,0xFF,0xF4,0xFF,0xF3,0xFF, + 0xEF,0xFF,0xF1,0xFF,0xEC,0xFF,0xED,0xFF,0xEC,0xFF,0xF1,0xFF, + 0xF3,0xFF,0xF9,0xFF,0xF3,0xFF,0xEB,0xFF,0xF3,0xFF,0xED,0xFF, + 0xED,0xFF,0xF2,0xFF,0xEF,0xFF,0xE9,0xFF,0xED,0xFF,0xEE,0xFF, + 0xEB,0xFF,0xEB,0xFF,0xEB,0xFF,0xEA,0xFF,0xE8,0xFF,0xE7,0xFF, + 0xE3,0xFF,0xE7,0xFF,0xDE,0xFF,0xEA,0xFF,0xE9,0xFF,0xE9,0xFF, + 0xE2,0xFF,0xE2,0xFF,0xE8,0xFF,0xE4,0xFF,0xEA,0xFF,0xE7,0xFF, + 0xE1,0xFF,0xDF,0xFF,0xE2,0xFF,0xDA,0xFF,0xDB,0xFF,0xE1,0xFF, + 0xE1,0xFF,0xDB,0xFF,0xD9,0xFF,0xD3,0xFF,0xD6,0xFF,0xD0,0xFF, + 0xD9,0xFF,0xD8,0xFF,0xD2,0xFF,0xD9,0xFF,0xDA,0xFF,0xD8,0xFF, + 0xDB,0xFF,0xD3,0xFF,0xD6,0xFF,0xD1,0xFF,0xD0,0xFF,0xCD,0xFF, + 0xC9,0xFF,0xCD,0xFF,0xCB,0xFF,0xC9,0xFF,0xD3,0xFF,0xCE,0xFF, + 0xCE,0xFF,0xCB,0xFF,0xC8,0xFF,0xC8,0xFF,0xD1,0xFF,0xC9,0xFF, + 0xCF,0xFF,0xCA,0xFF,0xCF,0xFF,0xCF,0xFF,0xD0,0xFF,0xCE,0xFF, + 0xC8,0xFF,0xC9,0xFF,0xD5,0xFF,0xCD,0xFF,0xCD,0xFF,0xCD,0xFF, + 0xD0,0xFF,0xD3,0xFF,0xCE,0xFF,0xCD,0xFF,0xD1,0xFF,0xD0,0xFF, + 0xCF,0xFF,0xCA,0xFF,0xCB,0xFF,0xD2,0xFF,0xD5,0xFF,0xD3,0xFF, + 0xD5,0xFF,0xD4,0xFF,0xD1,0xFF,0xD4,0xFF,0xDD,0xFF,0xDA,0xFF, + 0xD4,0xFF,0xD7,0xFF,0xD9,0xFF,0xD5,0xFF,0xD7,0xFF,0xCF,0xFF, + 0xD1,0xFF,0xD7,0xFF,0xDC,0xFF,0xDC,0xFF,0xD8,0xFF,0xE9,0xFF, + 0xE9,0xFF,0xEA,0xFF,0xE6,0xFF,0xE4,0xFF,0xEA,0xFF,0xF1,0xFF, + 0xEA,0xFF,0xF4,0xFF,0xEF,0xFF,0xF1,0xFF,0xF0,0xFF,0xF2,0xFF, + 0xEC,0xFF,0xEE,0xFF,0xF4,0xFF,0xFA,0xFF,0xF0,0xFF,0xF4,0xFF, + 0xEF,0xFF,0xF0,0xFF,0xF8,0xFF,0xF5,0xFF,0xEE,0xFF,0xF0,0xFF, + 0xF7,0xFF,0xF5,0xFF,0xF8,0xFF,0xF9,0xFF,0xFA,0xFF,0xFC,0xFF, + 0xFA,0xFF,0xF2,0xFF,0xF0,0xFF,0xF2,0xFF,0xEE,0xFF,0xF5,0xFF, + 0xF7,0xFF,0xF2,0xFF,0xF6,0xFF,0xF3,0xFF,0xF6,0xFF,0xF0,0xFF, + 0xF4,0xFF,0xEF,0xFF,0xF2,0xFF,0xED,0xFF,0xF0,0xFF,0xEC,0xFF, + 0xED,0xFF,0xE9,0xFF,0xED,0xFF,0xEB,0xFF,0xEB,0xFF,0xE2,0xFF, + 0xE3,0xFF,0xEA,0xFF,0xEA,0xFF,0xE3,0xFF,0xE7,0xFF,0xE3,0xFF, + 0xE9,0xFF,0xE8,0xFF,0xE3,0xFF,0xE7,0xFF,0xE5,0xFF,0xE3,0xFF, + 0xE7,0xFF,0xDE,0xFF,0xDE,0xFF,0xE8,0xFF,0xE3,0xFF,0xE2,0xFF, + 0xD9,0xFF,0xDA,0xFF,0xDE,0xFF,0xE0,0xFF,0xDF,0xFF,0xDD,0xFF, + 0xDE,0xFF,0xDA,0xFF,0xDE,0xFF,0xD9,0xFF,0xD9,0xFF,0xDE,0xFF, + 0xE2,0xFF,0xDD,0xFF,0xE3,0xFF,0xD9,0xFF,0xDD,0xFF,0xE5,0xFF, + 0xE3,0xFF,0xE5,0xFF,0xE0,0xFF,0xDD,0xFF,0xE0,0xFF,0xDB,0xFF, + 0xE1,0xFF,0xDB,0xFF,0xDA,0xFF,0xE0,0xFF,0xDA,0xFF,0xE1,0xFF, + 0xE5,0xFF,0xE0,0xFF,0xE3,0xFF,0xE7,0xFF,0xE2,0xFF,0xE7,0xFF, + 0xE3,0xFF,0xE3,0xFF,0xDF,0xFF,0xDF,0xFF,0xE1,0xFF,0xD9,0xFF, + 0xD5,0xFF,0xDB,0xFF,0xDD,0xFF,0xE2,0xFF,0xDC,0xFF,0xDD,0xFF, + 0xD8,0xFF,0xD7,0xFF,0xD3,0xFF,0xE1,0xFF,0xDA,0xFF,0xE0,0xFF, + 0xDD,0xFF,0xE2,0xFF,0xE1,0xFF,0xE3,0xFF,0xE5,0xFF,0xE4,0xFF, + 0xE6,0xFF,0xEA,0xFF,0xE7,0xFF,0xEA,0xFF,0xF2,0xFF,0xEC,0xFF, + 0xF6,0xFF,0xF0,0xFF,0xEE,0xFF,0xF1,0xFF,0xED,0xFF,0xEE,0xFF, + 0xFA,0xFF,0xF8,0xFF,0xFE,0xFF,0xFA,0xFF,0xFE,0xFF,0x04,0x00, + 0x01,0x00,0xFC,0xFF,0xFA,0xFF,0xF6,0xFF,0xF4,0xFF,0xED,0xFF, + 0xF1,0xFF,0xF0,0xFF,0xEC,0xFF,0xF4,0xFF,0xF5,0xFF,0xEE,0xFF, + 0xE6,0xFF,0xE9,0xFF,0xEB,0xFF,0xEE,0xFF,0xEC,0xFF,0xE8,0xFF, + 0xE4,0xFF,0xEA,0xFF,0xEB,0xFF,0xED,0xFF,0xE9,0xFF,0xE7,0xFF, + 0xE5,0xFF,0xE5,0xFF,0xE7,0xFF,0xE3,0xFF,0xE8,0xFF,0xE4,0xFF, + 0xF0,0xFF,0xE8,0xFF,0xE2,0xFF,0xE3,0xFF,0xE6,0xFF,0xE6,0xFF, + 0xEA,0xFF,0xE5,0xFF,0xE5,0xFF,0xE0,0xFF,0xE5,0xFF,0xE8,0xFF, + 0xE5,0xFF,0xE6,0xFF,0xE2,0xFF,0xE6,0xFF,0xE4,0xFF,0xE2,0xFF, + 0xE0,0xFF,0xE5,0xFF,0xE0,0xFF,0xEB,0xFF,0xDD,0xFF,0xDA,0xFF, + 0xD8,0xFF,0xD7,0xFF,0xDE,0xFF,0xDA,0xFF,0xD5,0xFF,0xDA,0xFF, + 0xD5,0xFF,0xD5,0xFF,0xD6,0xFF,0xD5,0xFF,0xD5,0xFF,0xD4,0xFF, + 0xD4,0xFF,0xD5,0xFF,0xD9,0xFF,0xD2,0xFF,0xD0,0xFF,0xD0,0xFF, + 0xD5,0xFF,0xD3,0xFF,0xD6,0xFF,0xDC,0xFF,0xD9,0xFF,0xDD,0xFF, + 0xD6,0xFF,0xDD,0xFF,0xE3,0xFF,0xDB,0xFF,0xE0,0xFF,0xDD,0xFF, + 0xDB,0xFF,0xDB,0xFF,0xE2,0xFF,0xDB,0xFF,0xDE,0xFF,0xE0,0xFF, + 0xE2,0xFF,0xE3,0xFF,0xE2,0xFF,0xDC,0xFF,0xE2,0xFF,0xDD,0xFF, + 0xDF,0xFF,0xE0,0xFF,0xDD,0xFF,0xDF,0xFF,0xDF,0xFF,0xDF,0xFF, + 0xDD,0xFF,0xE5,0xFF,0xDE,0xFF,0xDA,0xFF,0xE5,0xFF,0xE2,0xFF, + 0xE0,0xFF,0xE7,0xFF,0xE3,0xFF,0xE8,0xFF,0xE3,0xFF,0xE7,0xFF, + 0xEF,0xFF,0xEA,0xFF,0xEE,0xFF,0xF6,0xFF,0xEB,0xFF,0xED,0xFF, + 0xEF,0xFF,0xE7,0xFF,0xF0,0xFF,0xEB,0xFF,0xEE,0xFF,0xEA,0xFF, + 0xF0,0xFF,0xEC,0xFF,0xEA,0xFF,0xEE,0xFF,0xF7,0xFF,0xF0,0xFF, + 0xEC,0xFF,0xE7,0xFF,0xEF,0xFF,0xED,0xFF,0xEC,0xFF,0xE6,0xFF, + 0xEB,0xFF,0xE5,0xFF,0xEB,0xFF,0xE7,0xFF,0xEA,0xFF,0xE9,0xFF, + 0xEB,0xFF,0xEC,0xFF,0xE9,0xFF,0xE7,0xFF,0xE6,0xFF,0xEC,0xFF, + 0xEC,0xFF,0xE5,0xFF,0xE4,0xFF,0xDF,0xFF,0xDC,0xFF,0xDC,0xFF, + 0xDD,0xFF,0xD8,0xFF,0xE0,0xFF,0xE1,0xFF,0xE0,0xFF,0xE1,0xFF, + 0xE4,0xFF,0xE2,0xFF,0xDE,0xFF,0xE5,0xFF,0xE7,0xFF,0xDC,0xFF, + 0xE1,0xFF,0xE2,0xFF,0xE4,0xFF,0xDE,0xFF,0xE3,0xFF,0xE0,0xFF, + 0xD8,0xFF,0xE0,0xFF,0xDC,0xFF,0xE3,0xFF,0xE1,0xFF,0xE0,0xFF, + 0xDB,0xFF,0xDB,0xFF,0xD9,0xFF,0xD5,0xFF,0xDC,0xFF,0xDB,0xFF, + 0xD4,0xFF,0xD6,0xFF,0xDC,0xFF,0xD2,0xFF,0xD5,0xFF,0xD8,0xFF, + 0xD6,0xFF,0xD6,0xFF,0xD0,0xFF,0xCE,0xFF,0xD1,0xFF,0xDC,0xFF, + 0xD9,0xFF,0xDA,0xFF,0xD8,0xFF,0xD7,0xFF,0xD6,0xFF,0xD7,0xFF, + 0xE4,0xFF,0xE2,0xFF,0xDF,0xFF,0xE5,0xFF,0xE4,0xFF,0xE7,0xFF, + 0xE9,0xFF,0xEE,0xFF,0xE9,0xFF,0xEE,0xFF,0xEB,0xFF,0xEB,0xFF, + 0xE7,0xFF,0xEC,0xFF,0xF2,0xFF,0xEC,0xFF,0xEA,0xFF,0xEA,0xFF, + 0xEA,0xFF,0xE6,0xFF,0xE6,0xFF,0xEF,0xFF,0xF2,0xFF,0xEE,0xFF, + 0xEB,0xFF,0xEC,0xFF,0xE8,0xFF,0xE8,0xFF,0xEC,0xFF,0xED,0xFF, + 0xEB,0xFF,0xE4,0xFF,0xE4,0xFF,0xEA,0xFF,0xE2,0xFF,0xF1,0xFF, + 0xF2,0xFF,0xF6,0xFF,0xEE,0xFF,0xEF,0xFF,0xF6,0xFF,0xF6,0xFF, + 0xF8,0xFF,0xF5,0xFF,0xF2,0xFF,0xF1,0xFF,0xFB,0xFF,0xFA,0xFF, + 0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x05,0x00,0xFE,0xFF, + 0x00,0x00,0x00,0x00,0xFB,0xFF,0xF4,0xFF,0xF5,0xFF,0xF4,0xFF, + 0xF0,0xFF,0xF2,0xFF,0xF2,0xFF,0xF0,0xFF,0xED,0xFF,0xE6,0xFF, + 0xEA,0xFF,0xF4,0xFF,0xF3,0xFF,0xF1,0xFF,0xF1,0xFF,0xEE,0xFF, + 0xEF,0xFF,0xEB,0xFF,0xEC,0xFF,0xF5,0xFF,0xF7,0xFF,0xFD,0xFF, + 0xF7,0xFF,0xF4,0xFF,0xED,0xFF,0xEE,0xFF,0xED,0xFF,0xED,0xFF, + 0xF4,0xFF,0xEF,0xFF,0xF0,0xFF,0xF3,0xFF,0xF2,0xFF,0xEA,0xFF, + 0xE2,0xFF,0xDA,0xFF,0xDE,0xFF,0xD8,0xFF,0xD0,0xFF,0xD1,0xFF, + 0xCC,0xFF,0xD5,0xFF,0xD2,0xFF,0xD2,0xFF,0xC7,0xFF,0xC0,0xFF, + 0xC5,0xFF,0xD0,0xFF,0xCB,0xFF,0xC8,0xFF,0xC0,0xFF,0xCA,0xFF, + 0xD9,0xFF,0xD6,0xFF,0xD4,0xFF,0xDC,0xFF,0xDF,0xFF,0xE5,0xFF, + 0xE8,0xFF,0xE2,0xFF,0xDE,0xFF,0xE2,0xFF,0xE0,0xFF,0xE1,0xFF, + 0xD5,0xFF,0xD2,0xFF,0xCD,0xFF,0xD4,0xFF,0xE4,0xFF,0xE3,0xFF, + 0xD1,0xFF,0xC9,0xFF,0xCD,0xFF,0xCC,0xFF,0xD3,0xFF,0xC5,0xFF, + 0xCA,0xFF,0xC9,0xFF,0xD3,0xFF,0xD1,0xFF,0xCD,0xFF,0xC9,0xFF, + 0xC8,0xFF,0xC9,0xFF,0xD2,0xFF,0xC7,0xFF,0xC1,0xFF,0xC1,0xFF, + 0xD0,0xFF,0xD5,0xFF,0xD5,0xFF,0xD1,0xFF,0xC9,0xFF,0xD3,0xFF, + 0xDB,0xFF,0xDC,0xFF,0xD8,0xFF,0xCF,0xFF,0xD3,0xFF,0xDC,0xFF, + 0xE0,0xFF,0xD5,0xFF,0xD1,0xFF,0xD1,0xFF,0xD5,0xFF,0xD5,0xFF, + 0xD4,0xFF,0xCB,0xFF,0xC9,0xFF,0xCD,0xFF,0xD8,0xFF,0xD8,0xFF, + 0xD7,0xFF,0xD2,0xFF,0xE3,0xFF,0xE9,0xFF,0xE7,0xFF,0xDD,0xFF, + 0xDD,0xFF,0xD9,0xFF,0xE0,0xFF,0xE4,0xFF,0xDD,0xFF,0xE7,0xFF, + 0xE5,0xFF,0xE4,0xFF,0xEB,0xFF,0xE8,0xFF,0xE5,0xFF,0xDE,0xFF, + 0xE4,0xFF,0xE2,0xFF,0xE0,0xFF,0xDA,0xFF,0xDF,0xFF,0xE3,0xFF, + 0xDE,0xFF,0xE0,0xFF,0xDC,0xFF,0xDE,0xFF,0xDF,0xFF,0xDD,0xFF, + 0xDA,0xFF,0xDC,0xFF,0xDC,0xFF,0xDB,0xFF,0xDE,0xFF,0xDA,0xFF, + 0xD6,0xFF,0xD7,0xFF,0xD5,0xFF,0xD7,0xFF,0xD5,0xFF,0xDC,0xFF, + 0xD3,0xFF,0xDD,0xFF,0xD3,0xFF,0xD1,0xFF,0xD9,0xFF,0xCF,0xFF, + 0xCE,0xFF,0xCF,0xFF,0xD1,0xFF,0xD0,0xFF,0xCD,0xFF,0xCD,0xFF, + 0xC9,0xFF,0xCC,0xFF,0xCA,0xFF,0xD1,0xFF,0xCE,0xFF,0xCD,0xFF, + 0xCB,0xFF,0xCA,0xFF,0xCB,0xFF,0xCF,0xFF,0xCF,0xFF,0xCF,0xFF, + 0xCC,0xFF,0xC9,0xFF,0xCD,0xFF,0xCC,0xFF,0xCF,0xFF,0xCC,0xFF, + 0xCB,0xFF,0xD0,0xFF,0xCC,0xFF,0xCC,0xFF,0xCA,0xFF,0xC4,0xFF, + 0xC6,0xFF,0xC3,0xFF,0xBF,0xFF,0xBA,0xFF,0xBA,0xFF,0xB8,0xFF, + 0xCA,0xFF,0xC3,0xFF,0xC0,0xFF,0xC5,0xFF,0xBD,0xFF,0xC3,0xFF, + 0xC3,0xFF,0xC7,0xFF,0xC9,0xFF,0xC1,0xFF,0xC3,0xFF,0xC7,0xFF, + 0xC6,0xFF,0xC3,0xFF,0xCA,0xFF,0xC5,0xFF,0xCA,0xFF,0xC6,0xFF, + 0xBF,0xFF,0xC3,0xFF,0xC9,0xFF,0xCA,0xFF,0xCD,0xFF,0xCC,0xFF, + 0xCD,0xFF,0xC7,0xFF,0xD0,0xFF,0xD2,0xFF,0xD3,0xFF,0xD4,0xFF, + 0xD1,0xFF,0xD3,0xFF,0xD1,0xFF,0xCE,0xFF,0xD3,0xFF,0xD0,0xFF, + 0xD8,0xFF,0xD8,0xFF,0xDC,0xFF,0xD6,0xFF,0xD7,0xFF,0xDC,0xFF, + 0xD9,0xFF,0xDE,0xFF,0xDF,0xFF,0xD8,0xFF,0xDC,0xFF,0xE1,0xFF, + 0xE4,0xFF,0xEA,0xFF,0xE5,0xFF,0xE7,0xFF,0xE1,0xFF,0xE3,0xFF, + 0xEA,0xFF,0xED,0xFF,0xEF,0xFF,0xEE,0xFF,0xEE,0xFF,0xEE,0xFF, + 0xF0,0xFF,0xED,0xFF,0x01,0x00,0xFB,0xFF,0xF7,0xFF,0xF6,0xFF, + 0xF6,0xFF,0xF3,0xFF,0xEF,0xFF,0xF2,0xFF,0xF2,0xFF,0xEA,0xFF, + 0xEC,0xFF,0xED,0xFF,0xEA,0xFF,0xF0,0xFF,0xED,0xFF,0xE9,0xFF, + 0xEA,0xFF,0xE9,0xFF,0xE6,0xFF,0xF4,0xFF,0xEB,0xFF,0xED,0xFF, + 0xE9,0xFF,0xE7,0xFF,0xE7,0xFF,0xE5,0xFF,0xE9,0xFF,0xEB,0xFF, + 0xE1,0xFF,0xE7,0xFF,0xE8,0xFF,0xE4,0xFF,0xDF,0xFF,0xDD,0xFF, + 0xDD,0xFF,0xE6,0xFF,0xDC,0xFF,0xDA,0xFF,0xD6,0xFF,0xDA,0xFF, + 0xE3,0xFF,0xEB,0xFF,0xE1,0xFF,0xE1,0xFF,0xE1,0xFF,0xD8,0xFF, + 0xD6,0xFF,0xDB,0xFF,0xD5,0xFF,0xDD,0xFF,0xD6,0xFF,0xD8,0xFF, + 0xD7,0xFF,0xD0,0xFF,0xD7,0xFF,0xD6,0xFF,0xD6,0xFF,0xC9,0xFF, + 0xCB,0xFF,0xCC,0xFF,0xC9,0xFF,0xCC,0xFF,0xCC,0xFF,0xCA,0xFF, + 0xD0,0xFF,0xCB,0xFF,0xC9,0xFF,0xC7,0xFF,0xD0,0xFF,0xCD,0xFF, + 0xCE,0xFF,0xD2,0xFF,0xD2,0xFF,0xC8,0xFF,0xCF,0xFF,0xCC,0xFF, + 0xD7,0xFF,0xD4,0xFF,0xCB,0xFF,0xCA,0xFF,0xD0,0xFF,0xD9,0xFF, + 0xDA,0xFF,0xD9,0xFF,0xD8,0xFF,0xDA,0xFF,0xDA,0xFF,0xD9,0xFF, + 0xDC,0xFF,0xDF,0xFF,0xDF,0xFF,0xD7,0xFF,0xDE,0xFF,0xDA,0xFF, + 0xD9,0xFF,0xD8,0xFF,0xD8,0xFF,0xD9,0xFF,0xCE,0xFF,0xCE,0xFF, + 0xD5,0xFF,0xD6,0xFF,0xD9,0xFF,0xD3,0xFF,0xD9,0xFF,0xD7,0xFF, + 0xD3,0xFF,0xDD,0xFF,0xD9,0xFF,0xD9,0xFF,0xD3,0xFF,0xD6,0xFF, + 0xDE,0xFF,0xD8,0xFF,0xDD,0xFF,0xE0,0xFF,0xE9,0xFF,0xE4,0xFF, + 0xE3,0xFF,0xDF,0xFF,0xDD,0xFF,0xE1,0xFF,0xE0,0xFF,0xE7,0xFF, + 0xDE,0xFF,0xDE,0xFF,0xE4,0xFF,0xF2,0xFF,0xE7,0xFF,0xEF,0xFF, + 0xF3,0xFF,0xF2,0xFF,0xF3,0xFF,0xEE,0xFF,0xED,0xFF,0xEA,0xFF, + 0xE6,0xFF,0xE9,0xFF,0xF2,0xFF,0xE8,0xFF,0xE2,0xFF,0xE5,0xFF, + 0xE3,0xFF,0xE9,0xFF,0xE8,0xFF,0xE5,0xFF,0xE7,0xFF,0xEE,0xFF, + 0xDF,0xFF,0xDA,0xFF,0xE1,0xFF,0xEB,0xFF,0xE4,0xFF,0xE0,0xFF, + 0xE4,0xFF,0xE5,0xFF,0xE7,0xFF,0xDF,0xFF,0xE5,0xFF,0xDF,0xFF, + 0xDE,0xFF,0xE4,0xFF,0xE4,0xFF,0xE0,0xFF,0xD8,0xFF,0xDF,0xFF, + 0xDD,0xFF,0xDD,0xFF,0xDB,0xFF,0xC6,0xFF,0xD0,0xFF,0xDE,0xFF, + 0xE3,0xFF,0xDD,0xFF,0xC8,0xFF,0xCB,0xFF,0xD5,0xFF,0xD7,0xFF, + 0xDE,0xFF,0xCC,0xFF,0xC5,0xFF,0xCB,0xFF,0xCF,0xFF,0xD5,0xFF, + 0xCD,0xFF,0xC8,0xFF,0xCF,0xFF,0xCE,0xFF,0xD4,0xFF,0xCE,0xFF, + 0xD2,0xFF,0xC8,0xFF,0xCD,0xFF,0xCA,0xFF,0xCA,0xFF,0xC8,0xFF, + 0xC9,0xFF,0xBE,0xFF,0xBB,0xFF,0xC0,0xFF,0xC1,0xFF,0xBE,0xFF, + 0xC5,0xFF,0xB9,0xFF,0xC3,0xFF,0xDB,0xFF,0xD5,0xFF,0xC4,0xFF, + 0xC9,0xFF,0xC7,0xFF,0xC0,0xFF,0xC0,0xFF,0xB9,0xFF,0xBA,0xFF, + 0xCB,0xFF,0xD4,0xFF,0xD0,0xFF,0xC1,0xFF,0xC7,0xFF,0xD0,0xFF, + 0xC2,0xFF,0xC4,0xFF,0xC3,0xFF,0xBE,0xFF,0xC9,0xFF,0xD7,0xFF, + 0xC9,0xFF,0xD2,0xFF,0xCC,0xFF,0xC5,0xFF,0xD6,0xFF,0xCE,0xFF, + 0xBF,0xFF,0xBA,0xFF,0xB9,0xFF,0xC4,0xFF,0xCA,0xFF,0xC3,0xFF, + 0xDD,0xFF,0xCC,0xFF,0xC8,0xFF,0xCE,0xFF,0xB6,0xFF,0xC7,0xFF, + 0xD0,0xFF,0xDB,0xFF,0xD5,0xFF,0xBF,0xFF,0xCA,0xFF,0xDD,0xFF, + 0xF3,0xFF,0xF6,0xFF,0xE8,0xFF,0xDB,0xFF,0xD7,0xFF,0xE9,0xFF, + 0xD7,0xFF,0xD2,0xFF,0xCF,0xFF,0xED,0xFF,0xFC,0xFF,0xEB,0xFF, + 0xE4,0xFF,0xDF,0xFF,0xD3,0xFF,0xEB,0xFF,0xD8,0xFF,0xE3,0xFF, + 0xDB,0xFF,0xE5,0xFF,0xF3,0xFF,0xF3,0xFF,0xF5,0xFF,0xDC,0xFF, + 0xD2,0xFF,0xF8,0xFF,0xF5,0xFF,0xF3,0xFF,0xE6,0xFF,0xDC,0xFF, + 0xE6,0xFF,0xE7,0xFF,0xE6,0xFF,0xE0,0xFF,0xE6,0xFF,0xEA,0xFF, + 0xD6,0xFF,0xC8,0xFF,0xCE,0xFF,0xE5,0xFF,0xEF,0xFF,0xE0,0xFF, + 0xCB,0xFF,0xD4,0xFF,0xDC,0xFF,0xE3,0xFF,0xDD,0xFF,0xCB,0xFF, + 0xCB,0xFF,0xD4,0xFF,0xFF,0xFF,0xF7,0xFF,0xDD,0xFF,0xD3,0xFF, + 0xD7,0xFF,0xCD,0xFF,0xC5,0xFF,0xCD,0xFF,0xC8,0xFF,0xD7,0xFF, + 0xE8,0xFF,0xC9,0xFF,0xCF,0xFF,0xE2,0xFF,0xF2,0xFF,0xC8,0xFF, + 0xC4,0xFF,0xCE,0xFF,0xBC,0xFF,0xCD,0xFF,0xE0,0xFF,0xDD,0xFF, + 0xC4,0xFF,0xD5,0xFF,0xEC,0xFF,0xCD,0xFF,0xBC,0xFF,0xDA,0xFF, + 0xCA,0xFF,0xAC,0xFF,0xA9,0xFF,0xB9,0xFF,0xBE,0xFF,0xEE,0xFF, + 0xF6,0xFF,0xBE,0xFF,0xAE,0xFF,0xC9,0xFF,0xD6,0xFF,0xD5,0xFF, + 0xD7,0xFF,0xB6,0xFF,0xB9,0xFF,0xE0,0xFF,0xDB,0xFF,0xE1,0xFF, + 0xD7,0xFF,0xC9,0xFF,0xC4,0xFF,0xCC,0xFF,0xDD,0xFF,0xC3,0xFF, + 0xDF,0xFF,0xF0,0xFF,0xD1,0xFF,0xDF,0xFF,0xDB,0xFF,0xD4,0xFF, + 0xD0,0xFF,0xD9,0xFF,0xE2,0xFF,0xC9,0xFF,0xE2,0xFF,0xF3,0xFF, + 0xD4,0xFF,0xD8,0xFF,0xEC,0xFF,0xD1,0xFF,0xC4,0xFF,0xED,0xFF, + 0xD2,0xFF,0xCB,0xFF,0xCF,0xFF,0xE2,0xFF,0xEB,0xFF,0xE5,0xFF, + 0xEC,0xFF,0xD5,0xFF,0xDB,0xFF,0xF9,0xFF,0xEF,0xFF,0xF4,0xFF, + 0xFA,0xFF,0xF6,0xFF,0xF1,0xFF,0x00,0x00,0xFC,0xFF,0xEB,0xFF, + 0xEE,0xFF,0xF6,0xFF,0xF3,0xFF,0xED,0xFF,0xF2,0xFF,0xED,0xFF, + 0xEE,0xFF,0x08,0x00,0x07,0x00,0xF8,0xFF,0xF9,0xFF,0xF0,0xFF, + 0xE0,0xFF,0xFC,0xFF,0xFA,0xFF,0xF2,0xFF,0xEE,0xFF,0xEF,0xFF, + 0xF9,0xFF,0xF0,0xFF,0xF5,0xFF,0x02,0x00,0xEC,0xFF,0xF8,0xFF, + 0xFB,0xFF,0xF8,0xFF,0xF0,0xFF,0xEA,0xFF,0xEB,0xFF,0xD6,0xFF, + 0xF6,0xFF,0xE5,0xFF,0xE1,0xFF,0xF4,0xFF,0xE8,0xFF,0xE7,0xFF, + 0xEC,0xFF,0xF0,0xFF,0xE6,0xFF,0xDD,0xFF,0xD4,0xFF,0xD5,0xFF, + 0xEA,0xFF,0xE8,0xFF,0xF6,0xFF,0xF1,0xFF,0xEE,0xFF,0xCD,0xFF, + 0xD2,0xFF,0x00,0x00,0xE2,0xFF,0xE0,0xFF,0xC3,0xFF,0xCA,0xFF, + 0x03,0x00,0x08,0x00,0xE2,0xFF,0xC5,0xFF,0xE9,0xFF,0xEB,0xFF, + 0xF7,0xFF,0xF1,0xFF,0xDC,0xFF,0xD1,0xFF,0xEB,0xFF,0x0A,0x00, + 0xCD,0xFF,0xC7,0xFF,0xE3,0xFF,0xE9,0xFF,0xF4,0xFF,0xBE,0xFF, + 0x96,0xFF,0xA9,0xFF,0xD6,0xFF,0xFD,0xFF,0xD0,0xFF,0xBD,0xFF, + 0x9D,0xFF,0xC8,0xFF,0x0E,0x00,0xF3,0xFF,0xB7,0xFF,0x89,0xFF, + 0xC1,0xFF,0xF0,0xFF,0xFA,0xFF,0xCB,0xFF,0x9E,0xFF,0xB9,0xFF, + 0xC1,0xFF,0xE0,0xFF,0xBE,0xFF,0xA8,0xFF,0xBB,0xFF,0xD4,0xFF, + 0xF1,0xFF,0xEE,0xFF,0xBD,0xFF,0xAC,0xFF,0xD4,0xFF,0x03,0x00, + 0xF3,0xFF,0xD6,0xFF,0xCC,0xFF,0xE1,0xFF,0xEA,0xFF,0xF1,0xFF, + 0xDB,0xFF,0xC5,0xFF,0xDD,0xFF,0xEF,0xFF,0xED,0xFF,0x0B,0x00, + 0xE7,0xFF,0xB5,0xFF,0xF0,0xFF,0xE1,0xFF,0x05,0x00,0x0C,0x00, + 0xE3,0xFF,0xCD,0xFF,0xF1,0xFF,0x13,0x00,0xFB,0xFF,0xDA,0xFF, + 0xE4,0xFF,0xE4,0xFF,0xD8,0xFF,0xEE,0xFF,0xDA,0xFF,0xD2,0xFF, + 0x0D,0x00,0xF3,0xFF,0xF3,0xFF,0xE2,0xFF,0xE1,0xFF,0xD1,0xFF, + 0xC4,0xFF,0xF3,0xFF,0xD9,0xFF,0xDF,0xFF,0xEC,0xFF,0xDB,0xFF, + 0x14,0x00,0xDD,0xFF,0xCB,0xFF,0xC4,0xFF,0xCA,0xFF,0xEF,0xFF, + 0xF8,0xFF,0x08,0x00,0xE1,0xFF,0xF1,0xFF,0x0B,0x00,0xFE,0xFF, + 0x0C,0x00,0x0A,0x00,0xDA,0xFF,0xCD,0xFF,0x16,0x00,0x28,0x00, + 0x0F,0x00,0x2C,0x00,0x2B,0x00,0x46,0x00,0x6F,0x00,0x58,0x00, + 0x20,0x00,0xFF,0xFF,0x2E,0x00,0xFF,0xFF,0xF0,0xFF,0x09,0x00, + 0xD9,0xFF,0xF1,0xFF,0x19,0x00,0x1D,0x00,0xF3,0xFF,0xCD,0xFF, + 0xBB,0xFF,0xA9,0xFF,0x7F,0xFF,0x70,0xFF,0x71,0xFF,0x80,0xFF, + 0xB1,0xFF,0xAF,0xFF,0xA6,0xFF,0x9E,0xFF,0xA3,0xFF,0x90,0xFF, + 0x6E,0xFF,0x7B,0xFF,0x64,0xFF,0x7A,0xFF,0x98,0xFF,0x9B,0xFF, + 0xB7,0xFF,0xCD,0xFF,0xC0,0xFF,0xAD,0xFF,0xC3,0xFF,0xB4,0xFF, + 0x94,0xFF,0xDA,0xFF,0x28,0x00,0x28,0x00,0x2F,0x00,0x51,0x00, + 0x59,0x00,0x9A,0x00,0xC0,0x00,0x9C,0x00,0xA3,0x00,0xF9,0x00, + 0x09,0x01,0x39,0x01,0x9B,0x01,0xAC,0x00,0x21,0xFF,0xE1,0xFD, + 0x82,0xFE,0xD3,0xFF,0x0E,0x00,0x11,0x00,0x24,0x00,0x04,0x00, + 0x22,0x01,0xF3,0x00,0x1C,0x00,0x9A,0xFE,0x7B,0xFE,0x04,0xFF, + 0x6B,0xFF,0xEE,0xFF,0x86,0xFF,0x86,0xFF,0x3F,0x00,0xEF,0x00, + 0xA9,0x00,0xDE,0xFF,0x22,0xFF,0x9E,0xFE,0x62,0xFE,0x3C,0xFF, + 0x7E,0xFF,0x91,0xFF,0x01,0x00,0x56,0x00,0xA0,0x00,0xEF,0xFF, + 0x94,0xFF,0xD0,0xFE,0xBF,0xFE,0x45,0xFF,0x99,0xFF,0xCA,0xFF, + 0xD0,0xFF,0x27,0x00,0x36,0x00,0x8E,0x00,0x6D,0x00,0x99,0xFF, + 0x83,0xFF,0xE7,0xFF,0x29,0x00,0x2E,0x00,0x44,0x00,0x4E,0x00, + 0x79,0x00,0x09,0x01,0x23,0x01,0xA1,0x00,0x83,0x00,0xDF,0x00, + 0x8C,0x00,0x35,0x01,0x7A,0x01,0xD1,0x00,0x65,0x00,0x73,0xFF, + 0x2C,0xFE,0x26,0xFF,0xEB,0xFF,0xFA,0xFF,0xCD,0xFF,0x54,0x00, + 0x78,0x00,0x75,0x00,0xAC,0x00,0xEE,0xFF,0xBE,0xFE,0x06,0xFF, + 0x6B,0xFF,0x6B,0xFF,0x85,0xFF,0x41,0xFF,0x0C,0xFF,0x62,0xFF, + 0x1B,0x00,0xC2,0xFF,0x27,0xFF,0x27,0xFF,0x2A,0xFF,0x9F,0xFF, + 0xA9,0xFF,0xA2,0xFF,0x36,0xFF,0x94,0xFF,0x25,0x00,0x0D,0x00, + 0xBF,0xFF,0x6C,0xFF,0x85,0xFF,0xBF,0xFF,0x09,0x00,0xFE,0xFF, + 0x07,0x00,0x1A,0x00,0x46,0x00,0x9B,0x00,0xA5,0x00,0x7A,0x00, + 0xDB,0x00,0x15,0x01,0x86,0x01,0xBA,0x01,0x19,0x02,0x68,0x02, + 0xD5,0x00,0x23,0x00,0xB5,0xFB,0x77,0xFD,0x7E,0xFF,0x9F,0xFF, + 0x23,0x00,0x36,0x00,0xAF,0x00,0xFF,0x00,0xD2,0x01,0xB8,0x00, + 0x8D,0xFD,0xE4,0xFD,0x3F,0xFE,0x00,0xFF,0x86,0xFF,0xA3,0xFF, + 0x8D,0xFF,0x38,0x00,0xD4,0x01,0x3E,0x01,0x05,0x00,0xDD,0xFE, + 0x31,0xFE,0x9A,0xFD,0x0D,0xFE,0x86,0xFF,0x4B,0xFF,0xAA,0xFF, + 0xEE,0x00,0xFB,0x00,0x16,0x00,0x4B,0xFF,0x80,0xFE,0x07,0xFE, + 0x8B,0xFE,0x86,0xFF,0x43,0xFF,0x91,0xFF,0x70,0x00,0x83,0x00, + 0x9B,0x00,0x25,0x00,0xA5,0xFF,0x2F,0xFF,0xAA,0xFF,0x3F,0x00, + 0x2F,0x00,0x9D,0x00,0xBF,0x00,0x75,0x01,0x35,0x02,0x7A,0x02, + 0xB6,0x02,0x9D,0x02,0x93,0x02,0x8A,0x01,0x60,0xFE,0x4F,0xF8, + 0xBF,0xFE,0xEB,0xFE,0xB4,0x00,0x8B,0x00,0xFE,0x00,0x2C,0x01, + 0xAF,0x01,0x94,0x03,0x53,0x00,0x5A,0xFC,0xE9,0xFD,0xEA,0xFD, + 0x07,0xFF,0x76,0xFF,0x24,0x00,0x55,0xFF,0xD8,0x00,0x2E,0x03, + 0x83,0x01,0xD8,0xFF,0xE1,0xFE,0xAB,0xFD,0xCE,0xFD,0xC2,0xFD, + 0x12,0xFF,0x44,0xFF,0x9C,0xFF,0xD2,0x01,0x21,0x01,0x4A,0x00, + 0x35,0xFF,0xD5,0xFD,0x17,0xFE,0x1F,0xFE,0x6F,0xFF,0xDB,0xFE, + 0x9C,0xFF,0xA8,0x00,0x86,0x00,0xAA,0x00,0xFC,0xFF,0xA2,0xFF, + 0x17,0xFF,0xC8,0xFF,0x26,0x00,0x16,0x00,0xBF,0x00,0x76,0x01, + 0x21,0x02,0x6D,0x01,0x8C,0x02,0x78,0x03,0x88,0x02,0xC0,0x02, + 0xFB,0x01,0x33,0xFD,0x52,0xF5,0xD1,0xFF,0x70,0xFE,0x0D,0x00, + 0xDB,0x00,0xF4,0x00,0x1A,0x01,0xED,0x01,0x0F,0x05,0xE6,0xFF, + 0x15,0xFB,0x02,0xFE,0x52,0xFD,0xDE,0xFE,0x1A,0xFF,0x05,0x00, + 0x93,0xFE,0x10,0x01,0x35,0x04,0x72,0x01,0x27,0xFF,0xDC,0xFE, + 0x2D,0xFD,0x76,0xFE,0xFC,0xFD,0xA1,0xFD,0x46,0xFE,0x0C,0x00, + 0x90,0x02,0xBD,0x00,0xA6,0x00,0x33,0xFF,0x6A,0xFD,0xD9,0xFE, + 0xFE,0xFD,0x4C,0xFE,0x3F,0xFE,0xE4,0xFF,0xD4,0x00,0x62,0x00, + 0xE3,0x00,0xA1,0xFF,0x87,0xFF,0x9F,0xFF,0xD5,0xFF,0x91,0xFF, + 0x80,0xFF,0xEB,0x00,0x81,0x01,0xE0,0x01,0x28,0x02,0x0E,0x02, + 0xCE,0x02,0x0B,0x03,0x6C,0x03,0xED,0x00,0x67,0x01,0xD5,0xFA, + 0xF2,0xF6,0xD6,0x00,0x95,0xFE,0xB6,0x00,0x79,0x00,0xBF,0x01, + 0x5D,0x01,0x1B,0x02,0x22,0x04,0x78,0xFE,0x8C,0xFB,0xD7,0xFD, + 0x72,0xFD,0x42,0xFF,0x4A,0xFF,0x5F,0x00,0x47,0xFF,0xC8,0x01, + 0x21,0x04,0xB1,0x00,0x3B,0xFF,0x34,0xFE,0x56,0xFD,0x2D,0xFD, + 0x24,0xFE,0xA6,0xFD,0xB8,0xFE,0x7C,0x01,0xFF,0x01,0xB4,0x01, + 0x79,0xFF,0x02,0xFF,0x8F,0xFD,0x1E,0xFE,0x8D,0xFE,0x2C,0xFE, + 0xE0,0xFE,0xF3,0xFF,0x29,0x01,0x7E,0x00,0x7A,0x00,0x0C,0x00, + 0x41,0xFF,0xBF,0xFF,0x06,0x00,0xD8,0xFF,0x8F,0x00,0x90,0x01, + 0xC4,0x01,0x2C,0x02,0xA2,0x02,0x99,0x02,0x99,0x02,0xA5,0x02, + 0x94,0x01,0x3B,0x01,0x82,0xFD,0x4C,0xF7,0x61,0xFE,0x2C,0xFF, + 0xC0,0x00,0x1A,0x01,0x1C,0x01,0x2C,0x01,0x55,0x01,0xB1,0x03, + 0x51,0x00,0x9D,0xFB,0x33,0xFD,0x5C,0xFD,0xF2,0xFE,0x33,0xFF, + 0x68,0x00,0x74,0xFF,0xBD,0x00,0xB8,0x03,0xC2,0x01,0x5F,0xFF, + 0x96,0xFE,0x86,0xFC,0x46,0xFC,0x26,0xFF,0x05,0xFE,0xFF,0xFD, + 0x78,0x00,0xDB,0x01,0x9F,0x01,0xFC,0xFF,0x1E,0xFF,0xBB,0xFC, + 0x40,0xFD,0xD1,0xFE,0x92,0xFE,0xBF,0xFE,0x7B,0xFF,0xE4,0x00, + 0x8B,0x00,0xCD,0x00,0xEC,0xFF,0xF0,0xFE,0x6E,0xFF,0x71,0x00, + 0x61,0x00,0xF3,0x00,0x79,0x01,0x10,0x02,0x39,0x02,0xBB,0x02, + 0xBD,0x02,0xB9,0x01,0x7A,0x02,0x0F,0x01,0xF2,0xFF,0x02,0xFC, + 0x6D,0xFA,0x46,0xFF,0x3A,0xFF,0xD3,0x00,0x47,0x01,0xEB,0x00, + 0x58,0x01,0x2D,0x01,0xFC,0x01,0x72,0xFD,0x64,0xFC,0x84,0xFD, + 0x81,0xFD,0x7A,0xFF,0x78,0xFF,0x3F,0x00,0xF7,0xFF,0x01,0x02, + 0xD9,0x02,0xCB,0x00,0x58,0xFF,0xA3,0xFD,0xE6,0xFB,0x2A,0xFD, + 0xCB,0xFE,0x0B,0xFE,0xA8,0xFE,0xB8,0x00,0x93,0x01,0xA0,0x00, + 0x56,0x00,0x8E,0xFE,0x1A,0xFD,0x3C,0xFE,0xB9,0xFE,0xC0,0xFE, + 0x36,0xFF,0x79,0x00,0xCA,0x00,0xFB,0x00,0xEF,0x00,0xCA,0xFF, + 0x7E,0xFF,0xF6,0xFF,0xB9,0x00,0x70,0x00,0x59,0x00,0xD1,0x01, + 0x65,0x02,0x47,0x02,0x46,0x03,0xBD,0x02,0xD6,0x01,0xDA,0x01, + 0xEF,0x01,0x01,0x01,0xB5,0xFC,0x00,0xFA,0x54,0xFF,0x0F,0x00, + 0x89,0x00,0xD6,0x01,0x6D,0x00,0xF1,0x00,0x62,0x01,0x67,0x02, + 0x77,0xFE,0x99,0xFC,0x8D,0xFD,0x95,0xFD,0x68,0xFF,0x9A,0xFF, + 0xF6,0xFF,0x94,0xFF,0x80,0x01,0x93,0x02,0x0A,0x01,0x9F,0xFF, + 0x5B,0xFE,0x47,0xFD,0xED,0xFC,0x47,0xFE,0x98,0xFE,0x50,0xFE, + 0x6E,0xFF,0xAD,0x00,0x99,0x00,0xD8,0xFF,0xDC,0xFE,0xD1,0xFD, + 0xCA,0xFD,0xBC,0xFE,0xF1,0xFE,0xA7,0xFE,0x66,0xFF,0x2C,0x00, + 0xB4,0x00,0xB0,0x00,0x3D,0x00,0xA8,0xFF,0xCB,0xFF,0x74,0x00, + 0xF4,0x00,0x28,0x01,0x21,0x01,0xBC,0x01,0x76,0x02,0x60,0x02, + 0x81,0x02,0xF6,0x01,0x4B,0x01,0x6D,0x01,0x9C,0x01,0x8A,0xFA, + 0xC5,0xFA,0x22,0xFD,0xE3,0xFF,0xB2,0x01,0x7A,0x01,0xA6,0x01, + 0x03,0x00,0x43,0x02,0x10,0x01,0x84,0xFE,0xC4,0xFC,0x71,0xFC, + 0x0D,0xFE,0x8C,0xFE,0xEC,0x00,0x95,0xFF,0xB9,0xFF,0xD2,0x01, + 0xB6,0x01,0x4B,0x01,0x67,0xFF,0x2B,0xFE,0xA0,0xFD,0xD2,0xFD, + 0x51,0xFE,0x63,0xFD,0xFC,0xFE,0x7B,0xFF,0x3B,0x00,0x39,0x00, + 0x43,0xFF,0xF1,0xFE,0xF7,0xFD,0x87,0xFE,0x23,0xFE,0xEF,0xFD, + 0xD0,0xFE,0x79,0xFF,0x06,0x00,0x10,0x00,0x5C,0x00,0x1B,0x00, + 0x12,0x00,0x76,0x00,0x5E,0x00,0xA1,0x00,0x2C,0x01,0x49,0x01, + 0xD2,0x01,0x94,0x01,0x60,0x02,0xA8,0x02,0xEF,0x01,0x7B,0x02, + 0xAD,0x01,0xCA,0x01,0x9C,0x00,0xD9,0xF9,0x01,0xFD,0x8B,0xFF, + 0x17,0x00,0x38,0x00,0x53,0x00,0x36,0x01,0xC7,0xFF,0x98,0x02, + 0xB7,0x00,0x67,0xFD,0x8F,0xFD,0xF3,0xFD,0xFF,0xFE,0x86,0xFE, + 0x16,0x00,0xA9,0xFF,0xC2,0xFF,0x17,0x02,0x9B,0x01,0x95,0x00, + 0x7F,0xFF,0x3E,0xFF,0xD4,0xFE,0xB4,0xFE,0xEA,0xFE,0x91,0xFD, + 0x1B,0xFC,0x34,0xFF,0x6C,0x00,0xD9,0xFE,0x30,0xFF,0x6F,0xFF, + 0x3D,0xFF,0x56,0xFF,0xFA,0xFE,0xF1,0xFD,0x8D,0xFD,0xC7,0xFF, + 0x0C,0x00,0xF6,0xFF,0x3E,0x00,0x75,0x00,0xAE,0x00,0x0E,0x01, + 0x30,0x01,0x1A,0x00,0x7F,0x00,0xA6,0x01,0x68,0x01,0x2E,0x01, + 0x9E,0x01,0x01,0x02,0xE8,0x02,0x94,0x01,0xED,0x01,0xB1,0x01, + 0xA3,0x01,0xEB,0xFF,0xAA,0xFB,0x56,0xFD,0x28,0xFF,0x18,0x00, + 0x23,0x01,0x79,0x00,0xCA,0x00,0x58,0x00,0xA2,0x01,0xCD,0x00, + 0x4F,0xFE,0x81,0xFE,0xE5,0xFE,0x12,0xFF,0x8E,0xFF,0x2C,0x00, + 0xBB,0xFF,0x8C,0x00,0x5F,0x01,0x13,0x01,0x15,0x00,0xA1,0xFF, + 0x64,0xFF,0xFC,0xFE,0x9C,0xFE,0xEF,0xFD,0x28,0xFE,0x86,0xFF, + 0x38,0x00,0xF0,0xFF,0xAD,0xFF,0xE8,0xFF,0x89,0xFF,0x41,0xFF, + 0x25,0xFF,0xC2,0xFE,0x0E,0xFF,0xE8,0xFF,0x46,0x00,0x2D,0x00, + 0x3E,0x00,0xBF,0x00,0xD7,0x00,0xCE,0x00,0xD4,0x00,0xCB,0x00, + 0xC7,0x00,0x5D,0x01,0x77,0x01,0x60,0x01,0x8D,0x01,0xE8,0x01, + 0xB5,0x02,0x9E,0x02,0x55,0x03,0x1E,0x03,0xFC,0x01,0x50,0x01, + 0x75,0xFC,0xA3,0xFC,0x2E,0xFF,0x2E,0x00,0x7A,0x00,0x5D,0x00, + 0xB5,0x01,0xA5,0x00,0x7A,0x01,0x44,0x01,0xED,0xFE,0x5C,0xFE, + 0xFD,0xFE,0xE9,0xFF,0x46,0xFF,0xF4,0xFF,0x36,0x00,0xBD,0xFF, + 0xB0,0x00,0xF5,0x00,0x26,0x00,0x4B,0xFF,0x5C,0xFF,0x3B,0xFF, + 0x48,0xFE,0xC2,0xFE,0x6F,0xFF,0x8F,0xFF,0xA5,0xFF,0xB3,0xFF, + 0xF6,0xFF,0x7F,0xFF,0x9B,0xFF,0x52,0xFF,0xDB,0xFE,0x45,0xFF, + 0xF1,0xFF,0x0E,0x00,0x0E,0x00,0x2D,0x00,0x1C,0x00,0x54,0x00, + 0x9A,0x00,0x81,0x00,0x4E,0x00,0x71,0x00,0xE0,0x00,0x29,0x01, + 0x18,0x01,0x2F,0x01,0x3F,0x01,0xCF,0x00,0x11,0x01,0xB4,0x01, + 0xD2,0x01,0x58,0x02,0x9F,0x02,0x30,0x03,0xA5,0x01,0xF8,0xFD, + 0x18,0xFF,0xCC,0xFF,0x53,0xFF,0x22,0xFF,0x07,0x00,0xC5,0xFF, + 0xC3,0xFF,0x19,0x01,0x18,0x00,0x87,0xFE,0xA1,0xFE,0x8B,0xFF, + 0xF7,0xFE,0xD3,0xFE,0x63,0xFF,0x56,0xFF,0x50,0xFF,0x0F,0x00, + 0xE2,0xFF,0xD9,0xFE,0x01,0xFE,0x04,0xFF,0x11,0xFF,0x06,0xFF, + 0x33,0xFF,0x08,0xFF,0xDF,0xFE,0x30,0xFF,0xBA,0xFF,0x02,0xFF, + 0xC6,0xFE,0x15,0xFF,0x57,0xFF,0x95,0xFF,0xF1,0xFF,0x25,0x00, + 0xE2,0xFF,0x2F,0x00,0x63,0x00,0xFB,0xFF,0xD4,0xFF,0x5B,0x00, + 0x8C,0x00,0x76,0x00,0x8C,0x00,0xA5,0x00,0xBC,0x00,0xBB,0x00, + 0x3D,0x01,0xEF,0x00,0x80,0x00,0x27,0x01,0x81,0x01,0x8F,0x01, + 0xD1,0x01,0x07,0x02,0x62,0x01,0xE3,0xFE,0xA1,0xFF,0x8F,0x00, + 0x20,0x00,0xD3,0xFF,0x60,0xFF,0x6C,0xFF,0x5A,0xFF,0xF5,0xFF, + 0xC4,0xFF,0xA5,0xFE,0xCD,0xFE,0x73,0xFF,0x87,0xFF,0x3F,0xFF, + 0x53,0xFF,0x25,0xFF,0xD8,0xFE,0x51,0xFF,0x3B,0xFF,0xE0,0xFE, + 0xA3,0xFE,0x5C,0xFF,0x74,0xFF,0xFE,0xFE,0x23,0xFF,0x3D,0xFF, + 0x75,0xFF,0x6C,0xFF,0xCE,0xFF,0x6B,0xFF,0x4F,0xFF,0xEC,0xFF, + 0x09,0x00,0xFA,0xFF,0xAE,0xFF,0x1A,0x00,0x24,0x00,0x19,0x00, + 0x6A,0x00,0x22,0x00,0x1D,0x00,0x57,0x00,0xA5,0x00,0x75,0x00, + 0x4B,0x00,0x8C,0x00,0x7F,0x00,0xDD,0x00,0xC0,0x00,0xD8,0x00, + 0xBF,0x00,0x87,0x00,0xA2,0x00,0x44,0x01,0x7E,0x01,0x2E,0x01, + 0x86,0x00,0x6C,0x00,0xA4,0x00,0x7E,0x00,0x46,0x00,0x0C,0x00, + 0xC2,0xFF,0xD5,0xFF,0xB5,0xFF,0x0F,0x00,0x63,0xFF,0x49,0xFF, + 0x35,0xFF,0x4B,0xFF,0x50,0xFF,0x0E,0xFF,0x4B,0xFF,0xEC,0xFE, + 0x1F,0xFF,0x1F,0xFF,0xCD,0xFE,0xC5,0xFE,0xBA,0xFE,0x17,0xFF, + 0x23,0xFF,0x1F,0xFF,0x29,0xFF,0x2F,0xFF,0x58,0xFF,0x76,0xFF, + 0x63,0xFF,0x34,0xFF,0x4F,0xFF,0xB7,0xFF,0xED,0xFF,0xD5,0xFF, + 0xDE,0xFF,0xF4,0xFF,0xDE,0xFF,0xF5,0xFF,0x0D,0x00,0xFF,0xFF, + 0xD7,0xFF,0x0C,0x00,0x40,0x00,0x72,0x00,0x29,0x00,0x28,0x00, + 0x38,0x00,0xEA,0xFF,0x27,0x00,0x3A,0x00,0x30,0x00,0x39,0x00, + 0x62,0x00,0x58,0x00,0x3B,0x00,0x7E,0x00,0x4F,0x00,0x22,0x00, + 0x3E,0x00,0x45,0x00,0x37,0x00,0x27,0x00,0x46,0x00,0x0F,0x00, + 0xED,0xFF,0x08,0x00,0x0C,0x00,0xBF,0xFF,0x87,0xFF,0xAA,0xFF, + 0x7D,0xFF,0x6A,0xFF,0x91,0xFF,0x7A,0xFF,0x73,0xFF,0x52,0xFF, + 0x4B,0xFF,0x14,0xFF,0xCA,0xFE,0x0E,0xFF,0x28,0xFF,0x21,0xFF, + 0x73,0xFF,0x6F,0xFF,0x87,0xFF,0x55,0xFF,0x4F,0xFF,0x73,0xFF, + 0x67,0xFF,0x85,0xFF,0xB0,0xFF,0xA6,0xFF,0xD3,0xFF,0xE6,0xFF, + 0xEF,0xFF,0xE6,0xFF,0xCD,0xFF,0xBE,0xFF,0xDD,0xFF,0x8B,0xFF, + 0xF2,0xFF,0xB2,0xFF,0xA8,0xFF,0x00,0x00,0xCB,0xFF,0xE8,0xFF, + 0x9C,0xFF,0xDC,0xFF,0xB9,0xFF,0xCB,0xFF,0x9F,0xFF,0xFC,0xFF, + 0xC5,0xFF,0xCE,0xFF,0xE3,0xFF,0xB1,0xFF,0xC0,0xFF,0xD9,0xFF, + 0xF7,0xFF,0xE8,0xFF,0xE0,0xFF,0x8B,0xFF,0xC8,0xFF,0xE6,0xFF, + 0xB0,0xFF,0xB5,0xFF,0xC7,0xFF,0xB7,0xFF,0x9A,0xFF,0x97,0xFF, + 0x95,0xFF,0x7B,0xFF,0x41,0xFF,0x7A,0xFF,0x92,0xFF,0x79,0xFF, + 0x7B,0xFF,0x42,0xFF,0x53,0xFF,0x36,0xFF,0x87,0xFF,0x69,0xFF, + 0xA7,0xFF,0x7C,0xFF,0x58,0xFF,0x72,0xFF,0x3B,0xFF,0x5F,0xFF, + 0x28,0xFF,0x51,0xFF,0x6D,0xFF,0x76,0xFF,0x76,0xFF,0x66,0xFF, + 0x8F,0xFF,0x8E,0xFF,0x9A,0xFF,0x8D,0xFF,0x78,0xFF,0xB7,0xFF, + 0x87,0xFF,0x59,0xFF,0xA5,0xFF,0xB5,0xFF,0x6D,0xFF,0x78,0xFF, + 0xB3,0xFF,0x89,0xFF,0x85,0xFF,0xD0,0xFF,0x8F,0xFF,0xA5,0xFF, + 0x14,0x00,0x01,0x00,0xD3,0xFF,0x49,0xFF,0xC8,0xFF,0x3F,0x00, + 0xA4,0xFF,0x27,0x00,0x46,0xFF,0x75,0xFF,0x81,0xFF,0xD4,0xFF, + 0xED,0xFF,0x6A,0xFF,0xB7,0xFF,0xC7,0xFF,0x2B,0x00,0xED,0xFE, + 0xED,0xFF,0x24,0xFF,0xCA,0xFF,0x6D,0xFF,0xC0,0xFF,0x20,0x00, + 0x22,0xFF,0x5B,0xFF,0x3F,0x00,0x79,0xFF,0x4C,0xFF,0x5D,0x00, + 0x76,0x00,0x43,0xFF,0xEB,0xFF,0xBE,0xFF,0xDB,0xFF,0xD8,0xFF, + 0x0D,0x00,0x1D,0x00,0x7A,0xFF,0x03,0x00,0xC4,0xFF,0x9A,0x00, + 0x54,0xFF,0x85,0xFF,0xE1,0xFF,0xB5,0x00,0xA3,0xFF,0xEB,0xFF, + 0x6C,0x00,0x77,0xFF,0x22,0xFF,0x84,0x00,0x2A,0x00,0xB4,0xFF, + 0xF1,0xFF,0x2F,0x00,0x37,0x00,0x8D,0xFF,0xB6,0xFF,0xD7,0xFF, + 0xB0,0xFF,0x5C,0xFF,0xD5,0xFF,0x68,0x00,0xE5,0xFF,0x50,0xFF, + 0x0D,0x00,0x08,0x00,0xA5,0xFF,0xBA,0xFF,0xED,0xFF,0xD5,0xFF, + 0xA0,0xFF,0x8E,0xFF,0xBC,0xFF,0xC1,0xFF,0xA1,0xFF,0xD1,0xFF, + 0xBA,0xFF,0xB5,0xFF,0xD5,0xFF,0xAD,0xFF,0xAE,0xFF,0xA6,0xFF, + 0xCD,0xFF,0xA1,0xFF,0xAB,0xFF,0xAD,0xFF,0xBF,0xFF,0xCB,0xFF, + 0x96,0xFF,0xC7,0xFF,0xBB,0xFF,0xB4,0xFF,0xC6,0xFF,0xC5,0xFF, + 0xBB,0xFF,0xDF,0xFF,0xC4,0xFF,0xC0,0xFF,0xDB,0xFF,0xE0,0xFF, + 0xD2,0xFF,0xC1,0xFF,0xD1,0xFF,0xC8,0xFF,0xCD,0xFF,0xCF,0xFF, + 0xD0,0xFF,0xC8,0xFF,0xC7,0xFF,0xCC,0xFF,0xC4,0xFF,0xC3,0xFF, + 0xC9,0xFF,0xC8,0xFF,0xCA,0xFF,0xC4,0xFF,0xC0,0xFF,0xC5,0xFF, + 0xAB,0xFF,0xA8,0xFF,0xB9,0xFF,0xB3,0xFF,0xB0,0xFF,0xB1,0xFF, + 0xA7,0xFF,0xB6,0xFF,0xBC,0xFF,0xBB,0xFF,0xB4,0xFF,0xB4,0xFF, + 0xB4,0xFF,0xB7,0xFF,0xBD,0xFF,0xC8,0xFF,0xD1,0xFF,0xC8,0xFF, + 0xBF,0xFF,0xBC,0xFF,0xBB,0xFF,0xB5,0xFF,0xB7,0xFF,0xB9,0xFF, + 0xA3,0xFF,0xA9,0xFF,0x9C,0xFF,0x96,0xFF,0xB1,0xFF,0xA3,0xFF, + 0xB5,0xFF,0xA2,0xFF,0xA6,0xFF,0x9E,0xFF,0xA2,0xFF,0xB7,0xFF, + 0xA3,0xFF,0x9C,0xFF,0xAC,0xFF,0xB2,0xFF,0xB1,0xFF,0xA9,0xFF, + 0xB8,0xFF,0xA5,0xFF,0xC8,0xFF,0xD0,0xFF,0xC1,0xFF,0xB2,0xFF, + 0xC6,0xFF,0xC7,0xFF,0xD9,0xFF,0xCC,0xFF,0xC0,0xFF,0xCD,0xFF, + 0xE4,0xFF,0xE2,0xFF,0xD7,0xFF,0xDE,0xFF,0xCF,0xFF,0xD8,0xFF, + 0xC2,0xFF,0xC7,0xFF,0xDF,0xFF,0xE8,0xFF,0xC7,0xFF,0xC6,0xFF, + 0xEC,0xFF,0xFD,0xFF,0xCA,0xFF,0xD3,0xFF,0xE1,0xFF,0xFE,0xFF, + 0xED,0xFF,0xDF,0xFF,0xE2,0xFF,0x0D,0x00,0xF7,0xFF,0xFA,0xFF, + 0x1A,0x00,0xF4,0xFF,0xEF,0xFF,0x05,0x00,0x13,0x00,0xFB,0xFF, + 0xEF,0xFF,0x04,0x00,0x1F,0x00,0xF6,0xFF,0x04,0x00,0x11,0x00, + 0xFE,0xFF,0x13,0x00,0x0B,0x00,0xEF,0xFF,0x00,0x00,0x05,0x00, + 0x09,0x00,0x01,0x00,0x05,0x00,0x03,0x00,0x05,0x00,0x13,0x00, + 0x0E,0x00,0x0D,0x00,0x11,0x00,0xEF,0xFF,0x14,0x00,0x20,0x00, + 0xFD,0xFF,0xE1,0xFF,0x24,0x00,0x17,0x00,0x0E,0x00,0x30,0x00, + 0x06,0x00,0x0B,0x00,0x2B,0x00,0x31,0x00,0x1C,0x00,0x1B,0x00, + 0x24,0x00,0x13,0x00,0x25,0x00,0x1F,0x00,0x20,0x00,0x15,0x00, + 0x2C,0x00,0x2F,0x00,0xFF,0xFF,0xF5,0xFF,0x2C,0x00,0x25,0x00, + 0x09,0x00,0xFC,0xFF,0x0D,0x00,0x12,0x00,0x22,0x00,0x05,0x00, + 0x19,0x00,0x14,0x00,0x08,0x00,0x22,0x00,0x07,0x00,0x1C,0x00, + 0x1C,0x00,0x11,0x00,0x0F,0x00,0x0C,0x00,0x13,0x00,0x08,0x00, + 0x26,0x00,0x1C,0x00,0x24,0x00,0xF6,0xFF,0x29,0x00,0x4F,0x00, + 0x0D,0x00,0xDA,0xFF,0x36,0x00,0x33,0x00,0x19,0x00,0x03,0x00, + 0x2A,0x00,0x1A,0x00,0x68,0x00,0x14,0x00,0xD0,0xFF,0x59,0x00, + 0x47,0x00,0xE2,0xFF,0xE3,0xFF,0xE7,0xFF,0x47,0x00,0x69,0x00, + 0xFF,0xFF,0x29,0x00,0x4D,0x00,0xFC,0xFF,0xE2,0xFF,0x39,0x00, + 0x38,0x00,0xF7,0xFF,0x21,0x00,0x1E,0x00,0x3E,0x00,0x29,0x00, + 0xF9,0xFF,0x5B,0x00,0xF3,0xFF,0x25,0x00,0x48,0x00,0x06,0x00, + 0x25,0x00,0x3E,0x00,0x0B,0x00,0x5C,0x00,0x18,0x00,0x01,0x00, + 0x02,0x00,0x24,0x00,0x5A,0x00,0x4A,0x00,0xE7,0xFF,0x3B,0x00, + 0x26,0x00,0xDA,0xFF,0x19,0x00,0x1F,0x00,0xDA,0xFF,0x72,0x00, + 0x28,0x00,0x03,0x00,0xC3,0xFF,0x52,0x00,0x25,0x00,0xEC,0xFF, + 0xF5,0xFF,0x03,0x00,0xCE,0xFE,0xA6,0xFE,0x13,0x01,0xD3,0xFF, + 0x60,0xFF,0x2B,0x00,0x0E,0x00,0xB5,0x00,0x4A,0x00,0xE9,0xFF, + 0x4D,0x00,0xC0,0x00,0xA1,0xFF,0x70,0xFF,0x16,0x01,0x50,0xFF, + 0xE7,0xFE,0x6B,0x00,0xBD,0xFF,0xC2,0xFF,0xF3,0xFF,0x45,0x00, + 0x00,0x00,0xD8,0xFF,0x1F,0x00,0x1C,0x00,0xCA,0xFF,0x03,0x00, + 0x82,0xFF,0x60,0x00,0x6C,0xFF,0xC9,0xFF,0xFF,0x00,0x7B,0xFF, + 0x87,0xFF,0x90,0x00,0xA4,0xFF,0xB8,0xFF,0x45,0x00,0xC2,0xFF, + 0x9E,0xFF,0x22,0x00,0x4F,0x00,0xFA,0xFF,0xA4,0xFF,0x75,0xFF, + 0x2B,0x00,0xEB,0xFF,0x3C,0xFF,0xD0,0xFF,0x72,0xFF,0x5A,0xFF, + 0x40,0xFF,0xD8,0xFF,0x63,0xFF,0xA5,0xFF,0x79,0xFF,0x6C,0x00, + 0x25,0xFF,0xB5,0xFF,0x04,0x00,0x93,0xFF,0xB9,0xFF,0x37,0x00, + 0x25,0x00,0x20,0x00,0xDC,0xFE,0xB6,0xFF,0xB2,0xFF,0x2B,0xFF, + 0xB8,0xFF,0xCD,0xFF,0xD3,0xFF,0xA6,0xFF,0xCD,0xFF,0x88,0xFF, + 0x49,0x00,0x2D,0xFF,0x8B,0xFF,0x2B,0x00,0x89,0xFE,0x06,0x00, + 0x54,0x00,0x2E,0xFF,0xD3,0xFF,0x52,0xFF,0xB5,0xFF,0x54,0x00, + 0x34,0xFF,0x70,0x00,0x11,0x00,0xCF,0xFF,0x15,0x00,0xD7,0xFF, + 0x50,0xFF,0xC6,0xFF,0x54,0xFF,0xF4,0xFF,0xF0,0xFF,0x7D,0xFF, + 0x6E,0x00,0x89,0xFF,0x7C,0xFF,0x44,0x00,0x85,0xFF,0x95,0xFF, + 0x23,0x00,0xBC,0xFF,0x57,0x00,0xC2,0xFF,0x02,0x00,0x4E,0x00, + 0x21,0xFF,0x6B,0x00,0xEA,0xFF,0x8A,0xFF,0x27,0x00,0xD1,0xFF, + 0x49,0x00,0xCA,0xFF,0xEB,0xFF,0x28,0x00,0x8E,0xFF,0xF1,0xFF, + 0x06,0x00,0xB0,0xFF,0x0F,0x00,0xEB,0xFF,0x0E,0x00,0xB5,0xFF, + 0x0E,0x00,0xF6,0xFF,0x92,0xFF,0x9C,0xFF,0xA3,0xFF,0x8E,0xFF, + 0xB9,0xFF,0x9C,0xFF,0x00,0x00,0xAB,0xFF,0x6D,0xFF,0xC9,0xFF, + 0x59,0xFF,0xC0,0xFF,0xD9,0xFF,0xB6,0xFF,0xB1,0xFF,0x64,0xFF, + 0xF3,0xFF,0x90,0xFF,0xF4,0xFF,0xC1,0xFF,0xB8,0xFF,0xD4,0xFF, + 0xE1,0xFF,0x0F,0x00,0x01,0x00,0xE9,0xFF,0x44,0x00,0x37,0x00, + 0x2A,0x00,0xA8,0x00,0x8D,0x00,0x9B,0x00,0xE5,0x00,0x11,0x01, + 0x5E,0x01,0x50,0x01,0xAD,0x01,0x67,0x01,0xA9,0x00,0x81,0xFF, + 0x85,0xFF,0x36,0xFF,0xFC,0xFE,0xC7,0xFE,0x9C,0xFE,0xF6,0xFD, + 0xF6,0xFD,0x2C,0xFE,0x07,0xFE,0xDC,0xFD,0x11,0xFE,0x67,0xFE, + 0x6D,0xFE,0xB5,0xFE,0x0B,0xFF,0x39,0xFF,0x0F,0xFF,0x6E,0xFF, + 0x6F,0xFF,0x55,0xFF,0x82,0xFF,0xDC,0xFF,0x02,0x00,0x6F,0x00, + 0x96,0x00,0x91,0x00,0xEC,0x00,0x42,0x01,0xA3,0x01,0xA7,0x01, + 0x2D,0x02,0x9A,0x02,0xB0,0x03,0xC3,0x03,0x47,0x03,0x20,0x00, + 0x18,0x00,0x04,0x00,0x6A,0xFE,0xD8,0xFE,0xFC,0xFE,0x7A,0xFE, + 0x0A,0xFD,0x19,0xFD,0x44,0xFE,0x87,0xFE,0x90,0xFF,0x28,0xFF, + 0x6B,0xFF,0x4F,0xFF,0x6B,0x00,0x1A,0x01,0xB3,0x00,0xF2,0x00, + 0x88,0x00,0x12,0x00,0xC2,0xFE,0xA6,0xFF,0x39,0xFE,0x29,0xFE, + 0x1D,0xFE,0x0D,0xFE,0x9F,0xFD,0x48,0xFE,0xD2,0xFE,0x3A,0xFF, + 0x33,0xFF,0xA5,0xFF,0xFA,0xFF,0x82,0x00,0xC9,0x00,0x85,0x01, + 0x24,0x01,0x03,0x01,0x66,0x01,0x9B,0x01,0xD0,0x01,0x54,0x02, + 0xF7,0x02,0xBB,0x03,0xAB,0x03,0x35,0x02,0x0F,0xFF,0x73,0xFF, + 0x7C,0xFF,0x67,0x00,0x69,0xFF,0x65,0xFF,0xE8,0xFD,0x75,0xFD, + 0x3F,0xFF,0x9A,0xFE,0x3E,0xFF,0x3E,0xFF,0xD6,0x00,0x9E,0xFE, + 0x4A,0x00,0x66,0x00,0x1A,0x01,0xAF,0x00,0x3D,0x01,0xB9,0xFF, + 0xCA,0xFE,0x65,0xFF,0x34,0xFF,0x60,0xFE,0xF2,0xFD,0x27,0xFE, + 0xA9,0xFD,0x57,0xFE,0x25,0xFF,0x3C,0xFF,0x4A,0xFF,0xEA,0xFF, + 0x07,0x00,0xF6,0xFF,0x15,0x01,0xD8,0x01,0x2D,0x01,0x41,0x01, + 0x9D,0x01,0xDC,0x01,0xF9,0x01,0x0B,0x03,0xE1,0x03,0x75,0x03, + 0x56,0x03,0xF5,0xFE,0x27,0x00,0x13,0x00,0xD6,0x00,0xC1,0xFE, + 0xF2,0xFF,0x91,0xFE,0x1D,0xFE,0xA8,0xFD,0x5A,0xFE,0x4D,0xFF, + 0x7D,0xFF,0xAC,0x00,0x7F,0xFE,0x5C,0xFF,0x06,0x00,0x12,0x01, + 0xD2,0x00,0x96,0x00,0xF8,0xFF,0x5B,0xFF,0xB1,0xFF,0x57,0xFF, + 0x52,0xFE,0x62,0xFE,0xB4,0xFD,0xA4,0xFD,0xA9,0xFD,0xBE,0xFE, + 0x76,0xFE,0x27,0xFF,0xEA,0xFE,0xB1,0xFF,0x95,0xFF,0x87,0x00, + 0x9F,0x00,0xA4,0x00,0x95,0x00,0xA5,0x00,0x15,0x01,0x17,0x01, + 0xA8,0x01,0x1B,0x02,0x0B,0x03,0x74,0x02,0xB8,0x02,0x9A,0xFE, + 0x92,0x00,0x55,0x00,0x20,0xFF,0xA9,0xFE,0x70,0x00,0xF3,0xFE, + 0xD5,0xFE,0x6F,0xFE,0x7E,0xFE,0x50,0xFF,0xD9,0xFE,0x85,0xFF, + 0x23,0xFE,0x2B,0xFF,0xC8,0xFE,0x93,0xFF,0xCF,0xFF,0x1D,0x00, + 0x71,0xFF,0x74,0xFF,0xB7,0xFF,0x8F,0xFF,0x4C,0xFF,0x3A,0xFF, + 0x5F,0xFF,0xD5,0xFE,0xED,0xFE,0xB8,0xFF,0x74,0xFF,0x79,0xFF, + 0x4E,0xFF,0x9C,0xFF,0x2E,0xFF,0x6D,0xFF,0x61,0xFF,0x89,0xFF, + 0x97,0xFF,0x9C,0xFF,0xD9,0xFF,0xE1,0xFF,0x43,0x00,0x71,0x00, + 0x04,0x01,0xFE,0x00,0x13,0x01,0x19,0x01,0x04,0x01,0xCD,0x00, + 0x33,0x01,0x57,0x01,0xFF,0x00,0x22,0x01,0xD3,0x00,0x8C,0x00, + 0x62,0x00,0x13,0x00,0x14,0x00,0x82,0xFF,0x93,0xFF,0xF3,0xFE, + 0xD6,0xFE,0x94,0xFE,0xAF,0xFE,0x92,0xFE,0x83,0xFE,0x8C,0xFE, + 0x5F,0xFE,0x56,0xFE,0x61,0xFE,0x9B,0xFE,0x92,0xFE,0xD5,0xFE, + 0xD1,0xFE,0xED,0xFE,0xFC,0xFE,0x3C,0xFF,0x53,0xFF,0x67,0xFF, + 0x9B,0xFF,0x9E,0xFF,0xB7,0xFF,0xE3,0xFF,0x07,0x00,0x1C,0x00, + 0x35,0x00,0x5A,0x00,0x5E,0x00,0x91,0x00,0xC1,0x00,0xFF,0x00, + 0x22,0x01,0xDD,0x00,0x04,0x01,0xD7,0x00,0xE4,0x00,0xEE,0x00, + 0x21,0x01,0xE2,0x00,0x8C,0x00,0x66,0x00,0x26,0x00,0x0B,0x00, + 0xD6,0xFF,0xB7,0xFF,0x37,0xFF,0x00,0xFF,0xDA,0xFE,0xB1,0xFE, + 0x9B,0xFE,0x7C,0xFE,0xA3,0xFE,0x7D,0xFE,0x80,0xFE,0x7F,0xFE, + 0x9A,0xFE,0xB3,0xFE,0xD7,0xFE,0xFE,0xFE,0xEE,0xFE,0x1F,0xFF, + 0x38,0xFF,0x78,0xFF,0x85,0xFF,0xAD,0xFF,0xA9,0xFF,0xB0,0xFF, + 0xD2,0xFF,0xE2,0xFF,0x03,0x00,0x00,0x00,0x17,0x00,0x18,0x00, + 0x3D,0x00,0x5F,0x00,0x83,0x00,0xBB,0x00,0xFA,0x00,0x29,0x01, + 0xE6,0x00,0x04,0x01,0x0A,0x01,0x45,0x01,0x34,0x01,0x53,0x01, + 0x33,0x01,0xDE,0x00,0xCF,0x00,0xB3,0x00,0x98,0x00,0x32,0x00, + 0x39,0x00,0xE3,0xFF,0x8F,0xFF,0x5B,0xFF,0x48,0xFF,0x35,0xFF, + 0xF5,0xFE,0x09,0xFF,0xF0,0xFE,0xCC,0xFE,0xC8,0xFE,0xF3,0xFE, + 0x14,0xFF,0x04,0xFF,0x30,0xFF,0x36,0xFF,0x5F,0xFF,0x86,0xFF, + 0xD6,0xFF,0xCB,0xFF,0xEE,0xFF,0xF3,0xFF,0xF9,0xFF,0x0C,0x00, + 0x16,0x00,0x2B,0x00,0x17,0x00,0x2A,0x00,0x1E,0x00,0x31,0x00, + 0x41,0x00,0x72,0x00,0x9A,0x00,0xB6,0x00,0xFA,0x00,0x18,0x01, + 0xDE,0x00,0x11,0x01,0x31,0x01,0x32,0x01,0x4C,0x01,0x5F,0x01, + 0x46,0x01,0xF5,0x00,0xF8,0x00,0xE8,0x00,0xAF,0x00,0x67,0x00, + 0x49,0x00,0x0E,0x00,0xA3,0xFF,0x81,0xFF,0x55,0xFF,0x33,0xFF, + 0x03,0xFF,0x08,0xFF,0xD9,0xFE,0xCE,0xFE,0xDD,0xFE,0xF4,0xFE, + 0x04,0xFF,0xFE,0xFE,0x23,0xFF,0x0C,0xFF,0x44,0xFF,0x6B,0xFF, + 0x95,0xFF,0xB1,0xFF,0xB8,0xFF,0xBD,0xFF,0xC5,0xFF,0xEF,0xFF, + 0xEC,0xFF,0x02,0x00,0xEF,0xFF,0x02,0x00,0xF1,0xFF,0x07,0x00, + 0x15,0x00,0x26,0x00,0x46,0x00,0x5A,0x00,0x86,0x00,0xAE,0x00, + 0xFD,0x00,0xBE,0x00,0x01,0x01,0xE7,0x00,0xF6,0x00,0x16,0x01, + 0x38,0x01,0x39,0x01,0xDD,0x00,0xE1,0x00,0xAE,0x00,0x9D,0x00, + 0x66,0x00,0x56,0x00,0xD8,0xFF,0x8F,0xFF,0x75,0xFF,0x3B,0xFF, + 0x21,0xFF,0xF1,0xFE,0x12,0xFF,0xD3,0xFE,0xC1,0xFE,0xCD,0xFE, + 0xD6,0xFE,0xF7,0xFE,0xF4,0xFE,0x15,0xFF,0xF1,0xFE,0x26,0xFF, + 0x41,0xFF,0x75,0xFF,0x91,0xFF,0xA1,0xFF,0x99,0xFF,0x97,0xFF, + 0xC9,0xFF,0xC5,0xFF,0xE7,0xFF,0xD5,0xFF,0xE7,0xFF,0xCB,0xFF, + 0xF1,0xFF,0x07,0x00,0x0D,0x00,0x37,0x00,0x57,0x00,0x89,0x00, + 0x9B,0x00,0xFE,0x00,0x17,0x01,0x1A,0x01,0x16,0x01,0x17,0x01, + 0x43,0x01,0x17,0x01,0x45,0x01,0x0D,0x01,0xEA,0x00,0xB4,0x00, + 0x98,0x00,0x84,0x00,0x11,0x00,0xFF,0xFF,0x8B,0xFF,0x62,0xFF, + 0x0C,0xFF,0xFA,0xFE,0xDE,0xFE,0xCA,0xFE,0xCE,0xFE,0x9C,0xFE, + 0xC1,0xFE,0xA9,0xFE,0xF0,0xFE,0xD6,0xFE,0x11,0xFF,0xF4,0xFE, + 0xF0,0xFE,0x1F,0xFF,0x51,0xFF,0x89,0xFF,0x89,0xFF,0xBC,0xFF, + 0x7C,0xFF,0x93,0xFF,0xA2,0xFF,0xC6,0xFF,0xB0,0xFF,0x90,0xFF, + 0xAF,0xFF,0x94,0xFF,0xBC,0xFF,0xAD,0xFF,0xE1,0xFF,0xE2,0xFF, + 0x04,0x00,0x23,0x00,0x4F,0x00,0xA8,0x00,0xFD,0x00,0x15,0x01, + 0xC6,0x00,0x03,0x01,0xCB,0x00,0x21,0x01,0xFA,0x00,0x03,0x01, + 0x70,0x00,0x7C,0x00,0xA2,0x00,0x28,0x00,0x49,0x00,0xF5,0xFF, + 0xEC,0xFF,0x21,0xFF,0x2D,0xFF,0xD3,0xFE,0xCA,0xFE,0xC7,0xFE, + 0xE2,0xFE,0xB9,0xFE,0x62,0xFE,0xD2,0xFE,0xBB,0xFE,0xE0,0xFE, + 0xEB,0xFE,0x43,0xFF,0xD7,0xFE,0xED,0xFE,0x1C,0xFF,0x5A,0xFF, + 0x86,0xFF,0x61,0xFF,0x9D,0xFF,0x5D,0xFF,0x91,0xFF,0x74,0xFF, + 0xA0,0xFF,0x7A,0xFF,0x75,0xFF,0x6B,0xFF,0x4C,0xFF,0xA8,0xFF, + 0xA2,0xFF,0xB1,0xFF,0x97,0xFF,0xC1,0xFF,0xF0,0xFF,0x2E,0x00, + 0xAC,0x00,0xBB,0x00,0x1E,0x01,0x43,0x01,0xA5,0x00,0x24,0x01, + 0x71,0x01,0xAF,0x01,0x28,0x01,0x45,0x01,0xAA,0x00,0x3F,0x00, + 0x5E,0x00,0x36,0x00,0x43,0x00,0xA1,0xFF,0xC8,0xFF,0xF3,0xFE, + 0xD3,0xFE,0xA5,0xFE,0xF4,0xFE,0xEB,0xFE,0xB4,0xFE,0xBE,0xFE, + 0xAE,0xFE,0x22,0xFF,0x28,0xFF,0x7F,0xFF,0x38,0xFF,0x6D,0xFF, + 0x6C,0xFF,0x7B,0xFF,0xC6,0xFF,0x71,0xFF,0xC7,0xFF,0xCC,0xFF, + 0x05,0x00,0xAF,0xFF,0xDC,0xFF,0xD9,0xFF,0xB2,0xFF,0xBC,0xFF, + 0x8B,0xFF,0x87,0xFF,0x8E,0xFF,0xDA,0xFF,0x7D,0xFF,0xAE,0xFF, + 0xD7,0xFF,0x9F,0xFF,0xF3,0xFF,0x38,0x00,0x57,0x00,0xAE,0x00, + 0x0F,0x01,0x1D,0x01,0xD8,0x01,0xDE,0x01,0xB1,0x00,0x92,0x01, + 0xA3,0x01,0x19,0x02,0x2F,0x01,0x65,0x01,0xB2,0x00,0x7B,0x00, + 0x42,0x00,0xD8,0xFF,0xDF,0xFF,0x21,0xFF,0x52,0xFF,0x4F,0xFE, + 0xAA,0xFE,0x75,0xFE,0xD4,0xFE,0xEA,0xFE,0xDD,0xFE,0x00,0xFF, + 0xCC,0xFE,0xAC,0xFF,0x66,0xFF,0xB1,0xFF,0x90,0xFF,0xE1,0xFF, + 0xAD,0xFF,0xBF,0xFF,0xBB,0xFF,0x82,0xFF,0xC9,0xFF,0x81,0xFF, + 0xF2,0xFF,0x4B,0xFE,0xF7,0xFF,0x7A,0xFF,0xDC,0xFE,0xFF,0xFE, + 0x06,0xFF,0x16,0xFF,0x2F,0xFF,0x68,0xFF,0x1E,0xFF,0x55,0xFF, + 0x05,0x00,0xB1,0xFF,0xF7,0xFF,0x3F,0x00,0x87,0x00,0xAF,0x00, + 0xCE,0x00,0x1B,0x02,0xBD,0x02,0x9B,0x02,0x06,0x03,0xDF,0xFF, + 0x6E,0x01,0x8D,0x01,0x03,0x01,0xCF,0xFF,0xBF,0xFF,0xD4,0xFF, + 0x00,0xFE,0x1C,0xFF,0x4B,0xFE,0x8C,0xFE,0xBE,0xFD,0x9E,0xFE, + 0xB1,0xFD,0x61,0xFE,0x64,0xFF,0x3F,0xFF,0xFB,0xFE,0x5D,0xFF, + 0x31,0x00,0xDE,0xFF,0x64,0x00,0x71,0x00,0xEF,0xFF,0xE6,0xFF, + 0x55,0x00,0x90,0xFF,0xF8,0xFE,0x41,0xFF,0x3C,0xFE,0xA1,0xFE, + 0x32,0xFF,0x2A,0xFF,0xC4,0xFE,0xEA,0xFE,0xBD,0xFF,0x1F,0xFF, + 0xDF,0xFF,0xC9,0xFF,0xA9,0xFF,0x71,0xFF,0x02,0x00,0x62,0x00, + 0xC6,0xFF,0xA5,0x00,0x16,0x00,0xB0,0x00,0x59,0x00,0x12,0x01, + 0xF8,0x00,0x33,0x01,0xE9,0x01,0x06,0x02,0x99,0x02,0x3E,0x02, + 0x03,0x01,0xB4,0x00,0xB5,0x01,0x2D,0x01,0xF0,0x00,0x60,0x00, + 0x14,0x00,0x45,0xFF,0x55,0xFF,0xE8,0xFF,0x37,0xFF,0xFE,0xFE, + 0x20,0xFF,0x50,0xFF,0x38,0xFF,0xAF,0xFF,0xA0,0xFF,0x24,0xFF, + 0x70,0xFF,0xC0,0xFF,0xF9,0xFF,0xA5,0xFF,0xC2,0xFF,0xDE,0xFF, + 0xDA,0xFF,0x12,0x00,0x30,0x00,0x35,0x00,0x16,0x00,0x2B,0x00, + 0x32,0x00,0x12,0x00,0x2E,0x00,0x0F,0x00,0xEF,0xFF,0xE5,0xFF, + 0xDC,0xFF,0xD8,0xFF,0xA4,0xFF,0x9C,0xFF,0x8A,0xFF,0x81,0xFF, + 0x76,0xFF,0x7D,0xFF,0x8A,0xFF,0x84,0xFF,0x98,0xFF,0xB8,0xFF, + 0xDF,0xFF,0x04,0x00,0x3B,0x00,0x5E,0x00,0x8B,0x00,0xC8,0x00, + 0xF2,0x00,0x0E,0x01,0x53,0x01,0x78,0x01,0x88,0x01,0x8C,0x01, + 0x6E,0x01,0x90,0x01,0x95,0x01,0x82,0x01,0x62,0x01,0x33,0x01, + 0x0B,0x01,0xDC,0x00,0xB3,0x00,0x83,0x00,0x52,0x00,0x09,0x00, + 0xC9,0xFF,0x90,0xFF,0x67,0xFF,0x3C,0xFF,0x23,0xFF,0x0B,0xFF, + 0x03,0xFF,0xF4,0xFE,0xF8,0xFE,0x07,0xFF,0x1D,0xFF,0x32,0xFF, + 0x4F,0xFF,0x60,0xFF,0x76,0xFF,0x96,0xFF,0xB6,0xFF,0xD5,0xFF, + 0xDE,0xFF,0xF3,0xFF,0xF5,0xFF,0xF9,0xFF,0xFA,0xFF,0xFB,0xFF, + 0xE8,0xFF,0xCC,0xFF,0xBB,0xFF,0xA6,0xFF,0x84,0xFF,0x66,0xFF, + 0x42,0xFF,0x40,0xFF,0x22,0xFF,0x1B,0xFF,0x0F,0xFF,0x10,0xFF, + 0x1D,0xFF,0x2C,0xFF,0x42,0xFF,0x59,0xFF,0x7F,0xFF,0xB1,0xFF, + 0xE0,0xFF,0x00,0x00,0x2B,0x00,0x53,0x00,0x63,0x00,0x74,0x00, + 0x8A,0x00,0x8E,0x00,0x88,0x00,0x7C,0x00,0x68,0x00,0x44,0x00, + 0x1E,0x00,0x03,0x00,0xCF,0xFF,0x9A,0xFF,0x60,0xFF,0x30,0xFF, + 0x12,0xFF,0xDB,0xFE,0xBE,0xFE,0x9A,0xFE,0x8A,0xFE,0x79,0xFE, + 0x7D,0xFE,0x85,0xFE,0x87,0xFE,0x9E,0xFE,0xB7,0xFE,0xD6,0xFE, + 0xF0,0xFE,0x20,0xFF,0x3F,0xFF,0x6B,0xFF,0x75,0xFF,0x8D,0xFF, + 0xAF,0xFF,0xC8,0xFF,0xD2,0xFF,0xD1,0xFF,0xDD,0xFF,0xC6,0xFF, + 0xB9,0xFF,0xA5,0xFF,0x96,0xFF,0x74,0xFF,0x62,0xFF,0x44,0xFF, + 0x27,0xFF,0x26,0xFF,0x18,0xFF,0x05,0xFF,0x0C,0xFF,0x09,0xFF, + 0x1A,0xFF,0x32,0xFF,0x48,0xFF,0x62,0xFF,0x87,0xFF,0x9C,0xFF, + 0xD3,0xFF,0xF9,0xFF,0x20,0x00,0x3E,0x00,0x5B,0x00,0x8A,0x00, + 0x9E,0x00,0xAF,0x00,0xC1,0x00,0xCC,0x00,0xC1,0x00,0xBD,0x00, + 0xAB,0x00,0x98,0x00,0x73,0x00,0x59,0x00,0x2B,0x00,0xFD,0xFF, + 0xCE,0xFF,0xB6,0xFF,0x8C,0xFF,0x69,0xFF,0x4E,0xFF,0x40,0xFF, + 0x37,0xFF,0x31,0xFF,0x30,0xFF,0x39,0xFF,0x43,0xFF,0x50,0xFF, + 0x61,0xFF,0x7F,0xFF,0xA8,0xFF,0xBD,0xFF,0xD5,0xFF,0xE1,0xFF, + 0xF5,0xFF,0xFA,0xFF,0x1D,0x00,0x48,0x00,0x48,0x00,0x1D,0x00, + 0x2C,0x00,0x1E,0x00,0x56,0x00,0x1D,0x00,0xFE,0xFF,0xD6,0xFF, + 0x0A,0x00,0xB2,0xFF,0xB6,0xFF,0xA8,0xFF,0xA0,0xFF,0x7F,0xFF, + 0x77,0xFF,0x87,0xFF,0x8C,0xFF,0x98,0xFF,0xAD,0xFF,0xBB,0xFF, + 0xC4,0xFF,0xE5,0xFF,0xFB,0xFF,0x1A,0x00,0x25,0x00,0x4B,0x00, + 0x71,0x00,0x8B,0x00,0xB7,0x00,0xCF,0x00,0xDB,0x00,0xCD,0x00, + 0xFE,0x00,0xE2,0x00,0xD0,0x00,0xB0,0x00,0xCA,0x00,0xA6,0x00, + 0x93,0x00,0x6F,0x00,0x4F,0x00,0x35,0x00,0x19,0x00,0xFA,0xFF, + 0xD9,0xFF,0xC9,0xFF,0xBA,0xFF,0xA6,0xFF,0x9B,0xFF,0x8C,0xFF, + 0x8B,0xFF,0x89,0xFF,0x90,0xFF,0x97,0xFF,0xA1,0xFF,0xA7,0xFF, + 0xAF,0xFF,0xBA,0xFF,0xD1,0xFF,0xE7,0xFF,0xF6,0xFF,0xEF,0xFF, + 0x02,0x00,0x11,0x00,0x09,0x00,0x08,0x00,0x06,0x00,0x05,0x00, + 0xF7,0xFF,0xDD,0xFF,0xD3,0xFF,0xCC,0xFF,0xC1,0xFF,0xB8,0xFF, + 0xB6,0xFF,0xAD,0xFF,0x9F,0xFF,0xAF,0xFF,0xA1,0xFF,0xB6,0xFF, + 0xBB,0xFF,0xC8,0xFF,0xD5,0xFF,0xE0,0xFF,0xFD,0xFF,0x0B,0x00, + 0x19,0x00,0x36,0x00,0x43,0x00,0x5A,0x00,0x65,0x00,0x61,0x00, + 0x5E,0x00,0x69,0x00,0x6E,0x00,0x62,0x00,0x4E,0x00,0x41,0x00, + 0x27,0x00,0x18,0x00,0xFA,0xFF,0xDD,0xFF,0xC0,0xFF,0xB9,0xFF, + 0x96,0xFF,0x7F,0xFF,0x70,0xFF,0x65,0xFF,0x55,0xFF,0x54,0xFF, + 0x56,0xFF,0x58,0xFF,0x61,0xFF,0x5E,0xFF,0x6F,0xFF,0x80,0xFF, + 0x89,0xFF,0x96,0xFF,0xA7,0xFF,0xB1,0xFF,0xC2,0xFF,0xCD,0xFF, + 0xD8,0xFF,0xE0,0xFF,0xE1,0xFF,0xE7,0xFF,0xE6,0xFF,0xE4,0xFF, + 0xF2,0xFF,0xEA,0xFF,0xD9,0xFF,0xD3,0xFF,0xC9,0xFF,0xC6,0xFF, + 0xC1,0xFF,0xBF,0xFF,0xC3,0xFF,0xC8,0xFF,0xC5,0xFF,0xC4,0xFF, + 0xD2,0xFF,0xDB,0xFF,0xE7,0xFF,0xFA,0xFF,0x05,0x00,0x12,0x00, + 0x22,0x00,0x36,0x00,0x39,0x00,0x52,0x00,0x61,0x00,0x62,0x00, + 0x6B,0x00,0x6F,0x00,0x6B,0x00,0x68,0x00,0x68,0x00,0x4D,0x00, + 0x41,0x00,0x2F,0x00,0x28,0x00,0x20,0x00,0x02,0x00,0xE6,0xFF, + 0xD3,0xFF,0xCF,0xFF,0xC3,0xFF,0xAB,0xFF,0xA6,0xFF,0x9C,0xFF, + 0x97,0xFF,0x91,0xFF,0x98,0xFF,0x97,0xFF,0xA5,0xFF,0xB1,0xFF, + 0xC4,0xFF,0xCD,0xFF,0xD6,0xFF,0xE2,0xFF,0xEE,0xFF,0xFD,0xFF, + 0x0C,0x00,0x13,0x00,0x25,0x00,0x29,0x00,0x32,0x00,0x3F,0x00, + 0x46,0x00,0x3B,0x00,0x49,0x00,0x3E,0x00,0x43,0x00,0x47,0x00, + 0x47,0x00,0x43,0x00,0x48,0x00,0x43,0x00,0x3F,0x00,0x40,0x00, + 0x3C,0x00,0x3F,0x00,0x42,0x00,0x4A,0x00,0x41,0x00,0x3B,0x00, + 0x41,0x00,0x3E,0x00,0x31,0x00,0x27,0x00,0x30,0x00,0x1C,0x00, + 0x0E,0x00,0x02,0x00,0xED,0xFF,0xDF,0xFF,0xD1,0xFF,0xB8,0xFF, + 0xB0,0xFF,0x9E,0xFF,0x89,0xFF,0x7B,0xFF,0x75,0xFF,0x7C,0xFF, + 0x77,0xFF,0x73,0xFF,0x76,0xFF,0x79,0xFF,0x85,0xFF,0x89,0xFF, + 0x90,0xFF,0x9D,0xFF,0xA9,0xFF,0xAF,0xFF,0xB6,0xFF,0xBC,0xFF, + 0xBA,0xFF,0xC0,0xFF,0xC6,0xFF,0xC5,0xFF,0xC7,0xFF,0xBF,0xFF, + 0xBD,0xFF,0xBC,0xFF,0xBD,0xFF,0xBB,0xFF,0xB4,0xFF,0xB2,0xFF, + 0xAD,0xFF,0xA8,0xFF,0xB2,0xFF,0xB3,0xFF,0xBA,0xFF,0xBE,0xFF, + 0xC3,0xFF,0xC6,0xFF,0xCA,0xFF,0xD4,0xFF,0xE0,0xFF,0xE9,0xFF, + 0xF6,0xFF,0xF8,0xFF,0xFB,0xFF,0xF7,0xFF,0xF8,0xFF,0x01,0x00, + 0xF8,0xFF,0xFB,0xFF,0xF2,0xFF,0xEA,0xFF,0xE4,0xFF,0xE1,0xFF, + 0xDD,0xFF,0xD1,0xFF,0xBC,0xFF,0xB5,0xFF,0xAD,0xFF,0xAC,0xFF, + 0xA2,0xFF,0xA1,0xFF,0xA2,0xFF,0x9D,0xFF,0x9A,0xFF,0x9D,0xFF, + 0xA8,0xFF,0xAB,0xFF,0xB4,0xFF,0xB7,0xFF,0xC0,0xFF,0xCA,0xFF, + 0xD5,0xFF,0xE4,0xFF,0xEA,0xFF,0xF6,0xFF,0xFC,0xFF,0x02,0x00, + 0x0C,0x00,0x12,0x00,0x17,0x00,0x1F,0x00,0x2A,0x00,0x29,0x00, + 0x31,0x00,0x2B,0x00,0x32,0x00,0x34,0x00,0x3E,0x00,0x47,0x00, + 0x40,0x00,0x46,0x00,0x3F,0x00,0x41,0x00,0x45,0x00,0x46,0x00, + 0x41,0x00,0x3B,0x00,0x3B,0x00,0x2F,0x00,0x2A,0x00,0x24,0x00, + 0x1B,0x00,0x12,0x00,0x05,0x00,0x01,0x00,0xF1,0xFF,0xE8,0xFF, + 0xD7,0xFF,0xC9,0xFF,0xC6,0xFF,0xB2,0xFF,0xAC,0xFF,0xAD,0xFF, + 0xA5,0xFF,0xA8,0xFF,0xA4,0xFF,0xA0,0xFF,0x99,0xFF,0x9F,0xFF, + 0xA6,0xFF,0xAC,0xFF,0xB5,0xFF,0xB3,0xFF,0xB9,0xFF,0xC0,0xFF, + 0xC3,0xFF,0xCA,0xFF,0xCE,0xFF,0xD8,0xFF,0xD7,0xFF,0xE6,0xFF, + 0xDB,0xFF,0xE6,0xFF,0xE2,0xFF,0xE9,0xFF,0xF1,0xFF,0xED,0xFF, + 0xEC,0xFF,0xF1,0xFF,0xED,0xFF,0xF1,0xFF,0xF4,0xFF,0xF9,0xFF, + 0xF7,0xFF,0xF4,0xFF,0xF2,0xFF,0xEB,0xFF,0xEE,0xFF,0xF1,0xFF, + 0xF6,0xFF,0xED,0xFF,0xF4,0xFF,0xE8,0xFF,0xDF,0xFF,0xD9,0xFF, + 0xD2,0xFF,0xCE,0xFF,0xC0,0xFF,0xB3,0xFF,0xAA,0xFF,0xA2,0xFF, + 0x9D,0xFF,0x89,0xFF,0x82,0xFF,0x75,0xFF,0x6D,0xFF,0x68,0xFF, + 0x6A,0xFF,0x60,0xFF,0x60,0xFF,0x66,0xFF,0x64,0xFF,0x65,0xFF, + 0x6F,0xFF,0x79,0xFF,0x86,0xFF,0x94,0xFF,0x9A,0xFF,0xAB,0xFF, + 0xB5,0xFF,0xBB,0xFF,0xCC,0xFF,0xD1,0xFF,0xDE,0xFF,0xE4,0xFF, + 0xE5,0xFF,0xED,0xFF,0xF3,0xFF,0xF5,0xFF,0xFD,0xFF,0xFE,0xFF, + 0xFC,0xFF,0xFD,0xFF,0xFA,0xFF,0x00,0x00,0x01,0x00,0x02,0x00, + 0x06,0x00,0x05,0x00,0x0E,0x00,0x09,0x00,0x0B,0x00,0x07,0x00, + 0x06,0x00,0x05,0x00,0x01,0x00,0xFB,0xFF,0xF0,0xFF,0xE5,0xFF, + 0xDB,0xFF,0xCE,0xFF,0xC0,0xFF,0xB7,0xFF,0xAA,0xFF,0xA6,0xFF, + 0x93,0xFF,0x87,0xFF,0x83,0xFF,0x78,0xFF,0x6E,0xFF,0x70,0xFF, + 0x6F,0xFF,0x79,0xFF,0x7F,0xFF,0x86,0xFF,0x8F,0xFF,0x99,0xFF, + 0xA2,0xFF,0xB7,0xFF,0xC5,0xFF,0xC9,0xFF,0xD3,0xFF,0xE7,0xFF, + 0xED,0xFF,0x00,0x00,0x0A,0x00,0x0D,0x00,0x13,0x00,0x1A,0x00, + 0x1B,0x00,0x1A,0x00,0x1B,0x00,0x1F,0x00,0x1D,0x00,0x26,0x00, + 0x27,0x00,0x28,0x00,0x1E,0x00,0x26,0x00,0x29,0x00,0x28,0x00, + 0x20,0x00,0x20,0x00,0x18,0x00,0x0E,0x00,0x09,0x00,0xFF,0xFF, + 0xFA,0xFF,0xF0,0xFF,0xDB,0xFF,0xCF,0xFF,0xBF,0xFF,0xB6,0xFF, + 0xA4,0xFF,0x93,0xFF,0x80,0xFF,0x74,0xFF,0x67,0xFF,0x5C,0xFF, + 0x54,0xFF,0x5E,0xFF,0x60,0xFF,0x5D,0xFF,0x5A,0xFF,0x5E,0xFF, + 0x6F,0xFF,0x7B,0xFF,0x83,0xFF,0x97,0xFF,0xA5,0xFF,0xAF,0xFF, + 0xC2,0xFF,0xD1,0xFF,0xE2,0xFF,0xEE,0xFF,0xF5,0xFF,0xFD,0xFF, + 0x0C,0x00,0xF5,0xFF,0xF4,0xFF,0x17,0x00,0x2E,0x00,0x13,0x00, + 0x29,0x00,0x74,0xFF,0x0B,0xFF,0x2B,0x00,0xA0,0x00,0xCE,0xFF, + 0xA4,0xFF,0x43,0x00,0xA4,0x00,0x84,0x00,0x28,0x00,0x88,0x00, + 0x52,0x00,0x65,0x00,0x3A,0x00,0x24,0x00,0xFA,0xFF,0xE1,0xFF, + 0x1E,0x00,0xD0,0xFF,0x90,0xFF,0x95,0xFF,0xAF,0xFF,0xA0,0xFF, + 0x3F,0xFF,0x88,0xFF,0xB2,0xFF,0x73,0xFF,0x5B,0xFF,0x68,0xFF, + 0x97,0xFF,0x89,0xFF,0x52,0xFF,0xCC,0xFE,0x9E,0xFE,0x98,0xFF, + 0xE9,0xFE,0x42,0xFE,0x82,0xFE,0x40,0xFF,0xED,0xFE,0xD9,0xFD, + 0x80,0xFE,0x34,0xFF,0x9F,0xFE,0xAD,0xFE,0x7F,0xFF,0xB6,0xFF, + 0x65,0xFF,0xF2,0xFF,0x5F,0x00,0x2E,0x00,0xA5,0x00,0x02,0x01, + 0x3E,0x01,0x4C,0x01,0xFD,0x01,0x94,0x02,0xC6,0x01,0xEA,0x00, + 0x62,0x00,0x54,0x03,0x58,0xFF,0x0C,0xFE,0xC3,0xFF,0xFF,0x00, + 0x6A,0xFD,0xFB,0xFB,0xD5,0xFE,0xCE,0xFE,0xF8,0xFB,0x95,0xFC, + 0x5B,0xFE,0x3B,0xFE,0xDD,0xFC,0xF9,0xFD,0x60,0xFF,0xDD,0xFE, + 0xDC,0xFF,0xB7,0xFF,0x6D,0x00,0xC9,0x00,0x28,0x01,0xC3,0x00, + 0xAA,0x00,0xFF,0x01,0xBA,0x00,0x29,0x00,0xBE,0x00,0x11,0x01, + 0x3D,0xFF,0x8F,0xFD,0x8B,0xFF,0xEF,0xFF,0xB3,0xFC,0xD7,0xFD, + 0x6F,0xFF,0xF3,0xFE,0xA4,0xFC,0x0A,0xFF,0x3A,0x00,0x9C,0xFE, + 0xBC,0xFE,0x73,0x00,0x64,0x01,0xA3,0x00,0x3E,0x01,0x75,0x02, + 0xC6,0x02,0x4C,0x03,0x17,0x03,0x5C,0x04,0x46,0x05,0x73,0x05, + 0x8C,0x04,0x3D,0x01,0x6C,0x03,0xBC,0x07,0xBC,0xFD,0xDA,0x01, + 0x8F,0x03,0xE4,0x01,0xEA,0xFB,0x70,0x00,0xE2,0x02,0x56,0xFC, + 0x5A,0xFD,0xF8,0xFE,0x0E,0xFF,0x75,0xFD,0x42,0xFE,0xE7,0xFF, + 0xBA,0xFF,0x9C,0x00,0xE4,0xFF,0xA4,0x01,0x74,0x03,0xBD,0x01, + 0xD6,0x01,0xB3,0x03,0x09,0x04,0xDA,0x01,0xDA,0x01,0x4F,0x04, + 0x72,0x01,0xF3,0x00,0xFF,0x00,0x50,0x01,0xF9,0xFD,0x25,0xFF, + 0xC6,0xFF,0x36,0xFD,0xB2,0xFE,0x82,0xFE,0xD3,0xFD,0x0C,0xFE, + 0x20,0xFF,0x89,0xFE,0x62,0xFE,0x65,0x00,0x52,0xFF,0x00,0x00, + 0xB3,0x01,0x86,0x01,0xD9,0x01,0x45,0x03,0xBD,0x03,0xFD,0x02, + 0xA9,0x04,0xE6,0x04,0xFC,0x04,0x20,0x05,0x1F,0x03,0x70,0x02, + 0x86,0x07,0xC2,0xFF,0xA1,0xFF,0xE2,0x02,0xF8,0x00,0x58,0xFC, + 0xBD,0xFE,0x12,0x00,0x31,0xFC,0x09,0xFC,0xF9,0xFD,0xCE,0xFC, + 0xAF,0xFD,0x3C,0xFC,0x01,0xFE,0xE8,0xFE,0x3A,0xFF,0x26,0xFE, + 0x5A,0x00,0x30,0x02,0x5C,0xFF,0x25,0x01,0x9A,0x02,0xC7,0x01, + 0xAA,0x00,0xB4,0x01,0xEB,0x01,0x44,0x00,0x66,0x00,0x9E,0xFF, + 0x11,0x00,0xB5,0xFE,0xA4,0xFC,0x84,0xFC,0x61,0xFF,0xF1,0xFA, + 0x66,0xFB,0x4C,0xFE,0x8E,0xFC,0xCB,0xFA,0x88,0xFD,0x20,0xFE, + 0x43,0xFC,0xA2,0xFD,0xB0,0xFE,0xDD,0xFE,0x2C,0xFF,0x41,0xFF, + 0x0F,0x01,0x86,0x01,0x8A,0x00,0x86,0x01,0x01,0x03,0x8B,0x02, + 0xEA,0x01,0x45,0x04,0x1F,0x03,0x36,0x02,0x31,0x00,0x92,0x03, + 0x57,0x00,0xA6,0xFB,0x18,0x02,0xA3,0xFE,0x60,0xFD,0x5E,0xFC, + 0xCB,0xFD,0xB8,0xFC,0x3E,0xFB,0xA0,0xFC,0xAB,0xFA,0xF8,0xFD, + 0x25,0xFA,0x34,0xFD,0x48,0xFE,0xB7,0xFD,0x8B,0xFD,0x8B,0xFF, + 0xEF,0x00,0xEE,0xFE,0x05,0x01,0xE9,0x00,0x79,0x01,0xFF,0x00, + 0xB1,0x00,0x7C,0x01,0x2C,0x01,0x0D,0x00,0x8F,0xFF,0x5F,0x00, + 0x70,0xFF,0xEA,0xFD,0xAC,0xFE,0x68,0xFD,0x9F,0xFC,0xD4,0xFC, + 0xA4,0xFC,0x83,0xFC,0xA8,0xFC,0x9A,0xFC,0xDD,0xFC,0x7E,0xFD, + 0x2A,0xFD,0x0C,0xFE,0x95,0xFE,0xC4,0xFE,0xF5,0xFE,0xDE,0xFF, + 0xFE,0xFF,0x83,0x00,0x26,0x01,0xF1,0x00,0x76,0x01,0xB3,0x01, + 0xB8,0x01,0x59,0x02,0x7C,0x02,0x1D,0x03,0xFF,0x02,0x07,0x03, + 0x81,0x00,0x43,0x02,0xEE,0x03,0x70,0xFB,0xD6,0x02,0x6A,0xFF, + 0xB9,0xFE,0xB9,0xFD,0x2F,0xFF,0x3B,0xFE,0x57,0xFD,0x73,0xFD, + 0xF4,0xFB,0xD1,0xFF,0x1A,0xFB,0x24,0xFC,0xA8,0xFF,0x29,0xFE, + 0x1D,0xFE,0x7E,0xFF,0xB3,0x00,0xD3,0xFF,0x20,0x01,0x33,0x01, + 0xCE,0x01,0x96,0x01,0xE1,0x00,0x50,0x02,0xC1,0x01,0x80,0x00, + 0xAA,0x00,0x18,0x01,0x4B,0x00,0x23,0xFF,0x90,0xFF,0x1E,0xFF, + 0xB1,0xFE,0x05,0xFD,0xEA,0xFD,0xEB,0xFD,0x59,0xFC,0x18,0xFD, + 0x3F,0xFE,0x5F,0xFD,0x14,0xFD,0xD1,0xFE,0xA9,0xFE,0xA2,0xFE, + 0xE9,0xFE,0xE2,0xFF,0x5D,0x00,0xB9,0xFF,0x80,0x00,0x6B,0x01, + 0x0B,0x01,0xF9,0x00,0xD1,0x01,0xDC,0x01,0x96,0x01,0x08,0x02, + 0x7C,0x02,0xAF,0x02,0xD3,0x02,0x2A,0x03,0x8C,0x03,0x50,0xFF, + 0x6A,0x04,0xE7,0x00,0x63,0xFB,0x50,0x04,0x24,0xFE,0x65,0xFF, + 0xF1,0xFE,0x1B,0xFF,0x70,0xFE,0x32,0xFE,0xE8,0xFC,0xDA,0xFC, + 0x0B,0x00,0xED,0xFA,0xF9,0xFF,0x24,0xFF,0x6C,0xFE,0xF6,0xFE, + 0x10,0x00,0x83,0x00,0x3C,0x00,0x2D,0x01,0x39,0x01,0xA4,0x02, + 0x79,0x00,0xE7,0x01,0xF4,0x01,0x3F,0x01,0xE5,0x00,0xEF,0x00, + 0xD9,0x00,0x1C,0x00,0xAD,0xFF,0x73,0xFF,0xA9,0xFF,0xE2,0xFE, + 0x15,0xFE,0xFA,0xFE,0x08,0xFE,0x4D,0xFD,0x14,0xFE,0x15,0xFE, + 0xD4,0xFD,0xD1,0xFD,0x9D,0xFE,0x0F,0xFF,0x0C,0xFF,0x3C,0xFF, + 0x02,0x00,0x3C,0x00,0xEA,0xFF,0xD8,0x00,0xD5,0x00,0xB6,0x00, + 0xD4,0x00,0x89,0x01,0x3D,0x01,0x08,0x01,0x86,0x01,0xA8,0x01, + 0x9B,0x01,0xBD,0x01,0x6E,0x02,0xB9,0x02,0x98,0x02,0x22,0x03, + 0xD2,0xFF,0x5C,0x04,0x5C,0x06,0xC2,0xFB,0x64,0x04,0x8D,0xFE, + 0xC1,0xFF,0xDF,0xFE,0xAE,0xFF,0x4B,0xFF,0x59,0xFE,0xF6,0xFD, + 0xEE,0xFD,0xD5,0xFF,0x9F,0xFB,0x5F,0xFF,0x16,0xFF,0x9B,0xFE, + 0x00,0xFF,0x10,0x00,0xA8,0x00,0x47,0x00,0x18,0x01,0x2A,0x01, + 0xA3,0x02,0x4F,0x00,0x43,0x02,0xAC,0x02,0x17,0x01,0x00,0x01, + 0x0C,0x01,0x01,0x01,0x2D,0x00,0xB6,0xFF,0xA3,0xFF,0xD1,0xFF, + 0xB5,0xFE,0x86,0xFE,0x26,0xFF,0x02,0xFE,0x19,0xFE,0x94,0xFD, + 0xD7,0xFE,0xCE,0xFD,0xDC,0xFD,0x06,0xFF,0xC7,0xFE,0xDF,0xFE, + 0x33,0xFF,0xEA,0xFF,0x4A,0xFF,0x94,0xFF,0x34,0x00,0x46,0x00, + 0x2A,0x00,0x04,0x00,0xCB,0x00,0x80,0x00,0x7B,0x00,0xD0,0x00, + 0xF4,0x00,0xCC,0x00,0xCE,0x00,0x77,0x01,0x7F,0x01,0x99,0x01, + 0xF9,0x01,0x82,0x02,0x25,0x03,0x0E,0x01,0xE7,0x00,0xA9,0x06, + 0x03,0xFC,0x3D,0x03,0x56,0x00,0x17,0x00,0x1E,0xFF,0xF2,0xFE, + 0xFA,0xFE,0x72,0xFE,0x3F,0xFD,0xA9,0xFC,0xAB,0x00,0x2F,0xFB, + 0x9F,0xFC,0x4A,0xFF,0x29,0xFE,0x7D,0xFE,0x0A,0xFF,0x2F,0x00, + 0x5A,0x00,0xFC,0xFF,0x87,0x00,0x15,0x02,0xBB,0x00,0xC1,0x00, + 0x24,0x02,0x2F,0x01,0x90,0x00,0x55,0x00,0xAF,0x00,0x44,0x00, + 0x14,0xFF,0x26,0xFF,0x8A,0xFF,0xD7,0xFE,0xC7,0xFD,0xD5,0xFE, + 0x50,0xFE,0xE3,0xFD,0x20,0xFE,0x6A,0xFD,0x6A,0xFF,0x2B,0xFD, + 0x14,0xFE,0x76,0xFF,0xDC,0xFE,0x67,0xFE,0x6B,0xFF,0xA7,0xFF, + 0xDA,0xFE,0x8F,0xFF,0x9E,0xFF,0x2A,0x00,0x34,0xFF,0x72,0xFF, + 0x6E,0x00,0xC1,0xFF,0xC8,0xFF,0x4B,0x00,0x8D,0x00,0x3B,0x00, + 0x9F,0x00,0x12,0x01,0x2B,0x01,0x14,0x01,0xAC,0x01,0x3E,0x02, + 0x8D,0x02,0xA6,0x02,0x4A,0xFE,0x44,0x05,0x6D,0x04,0xB0,0xFB, + 0xC5,0x03,0xFF,0xFE,0x76,0xFF,0xCC,0xFE,0xDF,0xFE,0x4A,0xFF, + 0x08,0xFE,0x62,0xFD,0x7C,0xFE,0x0C,0xFF,0x13,0xFB,0xD2,0xFF, + 0xE6,0xFE,0x94,0xFE,0xE7,0xFE,0xB0,0xFF,0xFC,0x00,0x24,0x00, + 0x55,0x00,0x28,0x01,0x9B,0x02,0xC0,0xFF,0x24,0x01,0xEE,0x01, + 0xC3,0x00,0x80,0x00,0x45,0x00,0xB4,0x00,0xAA,0xFF,0x0C,0xFF, + 0x2C,0xFF,0x98,0xFF,0x20,0xFE,0x69,0xFE,0x18,0xFF,0x72,0xFE, + 0x4D,0xFE,0x99,0xFE,0x4C,0xFF,0x87,0xFE,0x19,0xFF,0x45,0xFF, + 0x16,0xFF,0x47,0xFF,0x21,0xFF,0xAA,0xFF,0x71,0xFF,0xA9,0xFF, + 0xF5,0xFF,0x22,0x00,0x86,0xFF,0x69,0xFF,0x2E,0x00,0xAD,0xFF, + 0xC9,0xFF,0xC4,0xFF,0x26,0x00,0xCE,0xFF,0x0B,0x00,0xC7,0x00, + 0x69,0x00,0x14,0x01,0xCE,0x00,0x65,0x01,0xA8,0x01,0xE4,0x01, + 0xB9,0x02,0xCF,0x02,0x54,0xFF,0x6E,0x03,0x84,0x01,0xE6,0xFB, + 0xA9,0x03,0xFC,0xFE,0x2A,0xFF,0x44,0xFF,0xAE,0xFE,0x5A,0xFF, + 0x20,0xFE,0x29,0xFD,0x70,0xFD,0x28,0x00,0xB0,0xFB,0xDF,0xFF, + 0x91,0xFF,0xA4,0xFE,0x88,0xFF,0xE6,0xFF,0xCE,0x00,0x9A,0x00, + 0xD6,0x00,0x3B,0x01,0xB0,0x02,0x62,0x00,0x54,0x01,0xB1,0x01, + 0xFD,0x00,0x94,0x00,0x2B,0x00,0x8A,0x00,0x06,0x00,0x2E,0xFF, + 0x1A,0xFF,0x86,0xFF,0xF4,0xFE,0x1F,0xFE,0x36,0xFF,0xB4,0xFE, + 0xA1,0xFE,0xE6,0xFE,0x7E,0xFF,0x65,0xFF,0xDE,0xFE,0xB0,0xFF, + 0x53,0x00,0x9E,0xFE,0x30,0x00,0x02,0x00,0xD1,0xFF,0xD5,0xFF, + 0xDE,0xFF,0x51,0x00,0xE2,0xFF,0x6C,0xFF,0xCD,0xFF,0x65,0x00, + 0x26,0xFF,0xE4,0xFF,0x3C,0x00,0xE2,0xFF,0xF3,0xFF,0x53,0x00, + 0xA8,0x00,0x9C,0x00,0xEB,0x00,0x44,0x01,0xA5,0x01,0x8E,0x01, + 0xCA,0x01,0xCB,0x02,0xB6,0x02,0x13,0x01,0x65,0x01,0xE6,0x05, + 0x97,0xFB,0x07,0x03,0xAA,0x00,0x73,0xFF,0x27,0xFF,0x4D,0xFF, + 0xA1,0xFF,0x98,0xFE,0xA6,0xFE,0xA6,0xFC,0x4A,0x01,0xA7,0xFC, + 0xE1,0xFE,0x6A,0x00,0x3D,0xFF,0x10,0xFF,0xF6,0xFF,0x32,0x01, + 0x68,0x00,0xDF,0x00,0x7E,0x00,0xC9,0x02,0xA5,0x01,0x15,0x00, + 0xED,0x01,0x0B,0x01,0x47,0x00,0x0F,0x00,0xA1,0x00,0xB9,0xFF, + 0x42,0xFF,0x25,0xFF,0x6A,0xFF,0x23,0xFF,0x3D,0xFE,0xCE,0xFE, + 0x58,0xFF,0xAB,0xFE,0xA1,0xFE,0x62,0xFF,0xC1,0xFF,0x3C,0xFF, + 0xA6,0xFF,0x1C,0x00,0xF8,0xFF,0xE1,0x00,0x6A,0xFF,0x2B,0x00, + 0x7E,0x00,0x07,0xFF,0x5C,0xFF,0x27,0x00,0x79,0xFF,0xF2,0xFE, + 0xEB,0xFF,0x31,0xFF,0x38,0xFF,0x4C,0xFF,0x45,0xFF,0xB5,0xFF, + 0x62,0xFF,0x53,0xFF,0x23,0x00,0x49,0x00,0x9C,0xFF,0x95,0x00, + 0xDA,0x00,0x85,0x00,0xFA,0x00,0x68,0x01,0x77,0x01,0xE5,0x01, + 0x6A,0x02,0x41,0x00,0x9A,0x00,0xF5,0x06,0xD1,0xFC,0x0C,0x01, + 0x91,0x01,0x1C,0x00,0xD4,0xFD,0x50,0xFF,0xDE,0xFF,0x6F,0xFD, + 0xE3,0xFE,0xC1,0xFC,0xE5,0xFF,0x86,0xFF,0xA0,0xFC,0x5E,0xFF, + 0x1F,0x00,0x9A,0xFE,0xAA,0xFE,0x42,0x01,0x5E,0x00,0xB5,0xFF, + 0x40,0x01,0xF3,0x00,0x1E,0x01,0x33,0x00,0x48,0x00,0x61,0x01, + 0x40,0x00,0x70,0xFF,0x34,0xFF,0xE7,0x00,0xD6,0xFE,0x8A,0xFE, + 0x89,0xFF,0x5B,0xFF,0x73,0xFE,0x70,0xFE,0x52,0xFF,0x14,0xFF, + 0xCB,0xFE,0x0F,0xFF,0xAA,0xFF,0xD4,0xFF,0x33,0xFF,0xB9,0xFF, + 0x57,0x00,0xE8,0xFF,0x39,0xFF,0x43,0x00,0x49,0x00,0x66,0xFF, + 0x56,0xFF,0x00,0x00,0xA8,0xFF,0x1A,0xFF,0x30,0xFF,0x7C,0xFF, + 0x42,0xFF,0x11,0xFF,0x1E,0xFF,0xA1,0xFF,0x7C,0xFF,0x59,0xFF, + 0xB8,0xFF,0x3B,0x00,0xE2,0xFF,0xD7,0xFF,0x81,0x00,0xA3,0x00, + 0x6C,0x00,0x6C,0x00,0xF1,0x00,0xFC,0x00,0x1B,0x01,0x0D,0x01, + 0x01,0x02,0xEC,0x01,0x1F,0xFE,0x4E,0x00,0x43,0x03,0xC7,0xFD, + 0x55,0xFF,0x1D,0x01,0xCE,0x00,0x1E,0xFD,0xB6,0xFE,0xDD,0x01, + 0x08,0xFE,0xBA,0xFD,0x1B,0xFF,0x54,0x00,0x71,0xFE,0x1D,0xFE, + 0xFB,0xFF,0xF7,0xFF,0xA0,0xFF,0xAA,0xFF,0x13,0x00,0xE5,0x00, + 0xD2,0x00,0x3E,0x00,0x69,0x00,0x3D,0x01,0x85,0x01,0xA9,0xFF, + 0x59,0x00,0xD0,0x00,0xC0,0x00,0x58,0xFF,0x77,0xFF,0x65,0x00, + 0xB6,0xFF,0xFD,0xFE,0x33,0xFF,0xA2,0xFF,0x76,0xFF,0xFD,0xFE, + 0x51,0xFF,0x5D,0xFF,0x69,0xFF,0xCD,0xFF,0x8D,0xFF,0xCA,0xFF, + 0x9F,0xFF,0xBA,0xFF,0x1D,0x00,0x95,0xFF,0xBA,0xFF,0xFA,0xFF, + 0x23,0x00,0x02,0x00,0xB8,0xFF,0x26,0x00,0x17,0x00,0x12,0x00, + 0x0C,0x00,0x1B,0x00,0x31,0x00,0x25,0x00,0x58,0x00,0x56,0x00, + 0x48,0x00,0x6A,0x00,0x7C,0x00,0x74,0x00,0x71,0x00,0x7A,0x00, + 0x81,0x00,0x68,0x00,0x87,0x00,0x90,0x00,0x8C,0x00,0x99,0x00, + 0x84,0x00,0x5D,0x00,0x77,0x00,0x54,0x00,0x82,0x00,0x46,0x00, + 0x42,0x00,0x57,0x00,0x39,0x00,0x28,0x00,0x26,0x00,0xFC,0xFF, + 0x0D,0x00,0xFC,0xFF,0xD9,0xFF,0xE0,0xFF,0xE0,0xFF,0xBE,0xFF, + 0xCF,0xFF,0xD3,0xFF,0xC7,0xFF,0xCE,0xFF,0xDB,0xFF,0xEF,0xFF, + 0xE8,0xFF,0xF3,0xFF,0xF8,0xFF,0x0A,0x00,0x04,0x00,0x10,0x00, + 0x15,0x00,0x25,0x00,0x1F,0x00,0x20,0x00,0x27,0x00,0x0A,0x00, + 0x01,0x00,0x11,0x00,0xFB,0xFF,0xDC,0xFF,0xE2,0xFF,0xCF,0xFF, + 0xD6,0xFF,0xA9,0xFF,0xAB,0xFF,0xB6,0xFF,0x8F,0xFF,0x7B,0xFF, + 0x95,0xFF,0x83,0xFF,0x76,0xFF,0x82,0xFF,0x71,0xFF,0x77,0xFF, + 0x75,0xFF,0x6D,0xFF,0x75,0xFF,0x83,0xFF,0x66,0xFF,0x73,0xFF, + 0x81,0xFF,0x5C,0xFF,0x64,0xFF,0x6C,0xFF,0x67,0xFF,0x66,0xFF, + 0x5C,0xFF,0x5A,0xFF,0x56,0xFF,0x5A,0xFF,0x42,0xFF,0x48,0xFF, + 0x4C,0xFF,0x48,0xFF,0x2E,0xFF,0x48,0xFF,0x33,0xFF,0x28,0xFF, + 0x47,0xFF,0x27,0xFF,0x2A,0xFF,0x2E,0xFF,0x1F,0xFF,0x24,0xFF, + 0x1B,0xFF,0x1E,0xFF,0x18,0xFF,0x05,0xFF,0x22,0xFF,0x0E,0xFF, + 0x1B,0xFF,0x19,0xFF,0x18,0xFF,0x1B,0xFF,0x19,0xFF,0x1E,0xFF, + 0x22,0xFF,0x20,0xFF,0x23,0xFF,0x2D,0xFF,0x2A,0xFF,0x1C,0xFF, + 0x37,0xFF,0x30,0xFF,0x25,0xFF,0x37,0xFF,0x38,0xFF,0x37,0xFF, + 0x31,0xFF,0x3E,0xFF,0x41,0xFF,0x46,0xFF,0x3C,0xFF,0x49,0xFF, + 0x4E,0xFF,0x49,0xFF,0x48,0xFF,0x57,0xFF,0x65,0xFF,0x58,0xFF, + 0x62,0xFF,0x70,0xFF,0x70,0xFF,0x61,0xFF,0x73,0xFF,0x7C,0xFF, + 0x65,0xFF,0x7B,0xFF,0x6E,0xFF,0x87,0xFF,0x8A,0xFF,0x79,0xFF, + 0x93,0xFF,0x9E,0xFF,0x9A,0xFF,0x84,0xFF,0xAB,0xFF,0xAC,0xFF, + 0x9B,0xFF,0xB7,0xFF,0xB6,0xFF,0xC2,0xFF,0xB3,0xFF,0xCE,0xFF, + 0xD9,0xFF,0xD1,0xFF,0xDB,0xFF,0xE2,0xFF,0xEF,0xFF,0xDD,0xFF, + 0xE6,0xFF,0xF9,0xFF,0xFC,0xFF,0xE8,0xFF,0xFB,0xFF,0x10,0x00, + 0x01,0x00,0xFA,0xFF,0x19,0x00,0x1C,0x00,0x08,0x00,0x0F,0x00, + 0x1A,0x00,0x21,0x00,0x18,0x00,0x19,0x00,0x24,0x00,0x2F,0x00, + 0x21,0x00,0x22,0x00,0x37,0x00,0x29,0x00,0x2E,0x00,0x34,0x00, + 0x34,0x00,0x2D,0x00,0x38,0x00,0x31,0x00,0x36,0x00,0x30,0x00, + 0x38,0x00,0x34,0x00,0x36,0x00,0x31,0x00,0x2A,0x00,0x43,0x00, + 0x2E,0x00,0x40,0x00,0x47,0x00,0x3F,0x00,0x39,0x00,0x3B,0x00, + 0x4E,0x00,0x44,0x00,0x4B,0x00,0x46,0x00,0x57,0x00,0x59,0x00, + 0x4B,0x00,0x58,0x00,0x56,0x00,0x59,0x00,0x4B,0x00,0x58,0x00, + 0x5D,0x00,0x4D,0x00,0x56,0x00,0x50,0x00,0x50,0x00,0x51,0x00, + 0x51,0x00,0x53,0x00,0x53,0x00,0x55,0x00,0x4D,0x00,0x51,0x00, + 0x4C,0x00,0x4F,0x00,0x55,0x00,0x4C,0x00,0x54,0x00,0x51,0x00, + 0x4B,0x00,0x3E,0x00,0x51,0x00,0x4E,0x00,0x45,0x00,0x4F,0x00, + 0x50,0x00,0x48,0x00,0x48,0x00,0x46,0x00,0x55,0x00,0x4F,0x00, + 0x41,0x00,0x53,0x00,0x3E,0x00,0x41,0x00,0x4E,0x00,0x4B,0x00, + 0x4D,0x00,0x4E,0x00,0x43,0x00,0x4C,0x00,0x42,0x00,0x46,0x00, + 0x4E,0x00,0x46,0x00,0x45,0x00,0x42,0x00,0x3D,0x00,0x37,0x00, + 0x38,0x00,0x3C,0x00,0x3D,0x00,0x3B,0x00,0x38,0x00,0x38,0x00, + 0x34,0x00,0x3A,0x00,0x3B,0x00,0x41,0x00,0x39,0x00,0x2F,0x00, + 0x36,0x00,0x31,0x00,0x2D,0x00,0x32,0x00,0x2A,0x00,0x31,0x00, + 0x30,0x00,0x24,0x00,0x28,0x00,0x31,0x00,0x29,0x00,0x25,0x00, + 0x2A,0x00,0x24,0x00,0x27,0x00,0x2E,0x00,0x2C,0x00,0x2D,0x00, + 0x36,0x00,0x2B,0x00,0x2E,0x00,0x31,0x00,0x28,0x00,0x2F,0x00, + 0x27,0x00,0x2C,0x00,0x25,0x00,0x1A,0x00,0x1F,0x00,0x1A,0x00, + 0x28,0x00,0x13,0x00,0x21,0x00,0x0F,0x00,0x0A,0x00,0x0D,0x00, + 0x11,0x00,0x15,0x00,0x10,0x00,0x04,0x00,0x0A,0x00,0x03,0x00, + 0x06,0x00,0xFE,0xFF,0x04,0x00,0xFF,0xFF,0xFA,0xFF,0xFB,0xFF, + 0xF5,0xFF,0xEF,0xFF,0xF6,0xFF,0xEA,0xFF,0xFB,0xFF,0xE0,0xFF, + 0xE8,0xFF,0xEA,0xFF,0xE7,0xFF,0xE7,0xFF,0xE5,0xFF,0xEC,0xFF, + 0xE1,0xFF,0xEA,0xFF,0xE8,0xFF,0xEE,0xFF,0xE9,0xFF,0xE5,0xFF, + 0xEB,0xFF,0xE4,0xFF,0xE5,0xFF,0xD7,0xFF,0xE8,0xFF,0xE4,0xFF, + 0xDC,0xFF,0xDE,0xFF,0xDE,0xFF,0xD9,0xFF,0xD1,0xFF,0xE0,0xFF, + 0xDD,0xFF,0xDC,0xFF,0xE2,0xFF,0xD7,0xFF,0xDB,0xFF,0xC6,0xFF, + 0xD3,0xFF,0xCE,0xFF,0xC6,0xFF,0xCB,0xFF,0xCE,0xFF,0xCF,0xFF, + 0xC4,0xFF,0xD1,0xFF,0xC8,0xFF,0xD4,0xFF,0xD2,0xFF,0xCB,0xFF, + 0xCB,0xFF,0xD5,0xFF,0xCF,0xFF,0xD1,0xFF,0xD2,0xFF,0xD4,0xFF, + 0xCA,0xFF,0xD5,0xFF,0xCB,0xFF,0xDE,0xFF,0xCF,0xFF,0xD7,0xFF, + 0xDC,0xFF,0xD8,0xFF,0xD1,0xFF,0xD1,0xFF,0xDD,0xFF,0xDB,0xFF, + 0xD5,0xFF,0xD7,0xFF,0xD5,0xFF,0xD2,0xFF,0xDC,0xFF,0xDC,0xFF, + 0xD8,0xFF,0xDB,0xFF,0xE0,0xFF,0xDF,0xFF,0xDB,0xFF,0xDB,0xFF, + 0xE6,0xFF,0xE1,0xFF,0xE4,0xFF,0xDD,0xFF,0xDC,0xFF,0xDD,0xFF, + 0xDD,0xFF,0xDB,0xFF,0xD6,0xFF,0xE2,0xFF,0xDC,0xFF,0xDB,0xFF, + 0xDE,0xFF,0xE2,0xFF,0xD8,0xFF,0xDE,0xFF,0xE0,0xFF,0xE3,0xFF, + 0xD7,0xFF,0xDC,0xFF,0xE3,0xFF,0xE7,0xFF,0xE4,0xFF,0xE3,0xFF, + 0xF2,0xFF,0xE6,0xFF,0xEF,0xFF,0xEC,0xFF,0xF0,0xFF,0xEB,0xFF, + 0xEF,0xFF,0xE9,0xFF,0xEF,0xFF,0xEC,0xFF,0xEA,0xFF,0xF3,0xFF, + 0xF1,0xFF,0xE8,0xFF,0xED,0xFF,0xEB,0xFF,0xF1,0xFF,0xDC,0xFF, + 0xE5,0xFF,0xE9,0xFF,0xE3,0xFF,0xDB,0xFF,0xEC,0xFF,0xE5,0xFF, + 0xE2,0xFF,0xD9,0xFF,0xDF,0xFF,0xE0,0xFF,0xD4,0xFF,0xD6,0xFF, + 0xD7,0xFF,0xD0,0xFF,0xCE,0xFF,0xD2,0xFF,0xD8,0xFF,0xD2,0xFF, + 0xCC,0xFF,0xD0,0xFF,0xDA,0xFF,0xC9,0xFF,0xC8,0xFF,0xDA,0xFF, + 0xD1,0xFF,0xD2,0xFF,0xC8,0xFF,0xD2,0xFF,0xCB,0xFF,0xBE,0xFF, + 0xC9,0xFF,0xC5,0xFF,0xC5,0xFF,0xBD,0xFF,0xC8,0xFF,0xBC,0xFF, + 0xB6,0xFF,0xBD,0xFF,0xC1,0xFF,0xC8,0xFF,0xB8,0xFF,0xB6,0xFF, + 0xBA,0xFF,0xB6,0xFF,0xAA,0xFF,0xB9,0xFF,0xB7,0xFF,0xAC,0xFF, + 0xAA,0xFF,0xAA,0xFF,0xAA,0xFF,0xAB,0xFF,0xA1,0xFF,0xAA,0xFF, + 0xA2,0xFF,0x96,0xFF,0x91,0xFF,0x96,0xFF,0x91,0xFF,0x8F,0xFF, + 0x98,0xFF,0x92,0xFF,0x89,0xFF,0x85,0xFF,0x8A,0xFF,0x82,0xFF, + 0x8B,0xFF,0x85,0xFF,0x8A,0xFF,0x86,0xFF,0x78,0xFF,0x85,0xFF, + 0x82,0xFF,0x7C,0xFF,0x7D,0xFF,0x86,0xFF,0x82,0xFF,0x77,0xFF, + 0x81,0xFF,0x7F,0xFF,0x85,0xFF,0x82,0xFF,0x7F,0xFF,0x85,0xFF, + 0x7B,0xFF,0x82,0xFF,0x7B,0xFF,0x82,0xFF,0x87,0xFF,0x7D,0xFF, + 0x7D,0xFF,0x77,0xFF,0x79,0xFF,0x84,0xFF,0x7C,0xFF,0x81,0xFF, + 0x7D,0xFF,0x7C,0xFF,0x83,0xFF,0x87,0xFF,0x8A,0xFF,0x89,0xFF, + 0x91,0xFF,0x88,0xFF,0x99,0xFF,0x94,0xFF,0x8D,0xFF,0x98,0xFF, + 0x96,0xFF,0x95,0xFF,0x99,0xFF,0x9C,0xFF,0x96,0xFF,0x9F,0xFF, + 0x9A,0xFF,0x97,0xFF,0x9A,0xFF,0x8F,0xFF,0x97,0xFF,0xA4,0xFF, + 0x93,0xFF,0x92,0xFF,0x9F,0xFF,0x95,0xFF,0x97,0xFF,0x98,0xFF, + 0x9D,0xFF,0x9A,0xFF,0x9A,0xFF,0x99,0xFF,0x9F,0xFF,0x9A,0xFF, + 0x97,0xFF,0x9A,0xFF,0x9D,0xFF,0xA1,0xFF,0x9C,0xFF,0x9E,0xFF, + 0xA0,0xFF,0x98,0xFF,0x9E,0xFF,0xA0,0xFF,0x9F,0xFF,0x9F,0xFF, + 0x98,0xFF,0x99,0xFF,0x93,0xFF,0x9C,0xFF,0x95,0xFF,0x9D,0xFF, + 0x9D,0xFF,0x9F,0xFF,0x92,0xFF,0x95,0xFF,0x92,0xFF,0x98,0xFF, + 0x9C,0xFF,0x9B,0xFF,0x98,0xFF,0x90,0xFF,0x95,0xFF,0x96,0xFF, + 0x98,0xFF,0x96,0xFF,0x9A,0xFF,0x8D,0xFF,0x93,0xFF,0xAA,0xFF, + 0x95,0xFF,0xB1,0xFF,0x9F,0xFF,0xA5,0xFF,0xB2,0xFF,0x9A,0xFF, + 0xA7,0xFF,0xA7,0xFF,0xAC,0xFF,0xAC,0xFF,0xA8,0xFF,0xA4,0xFF, + 0xA7,0xFF,0xA8,0xFF,0xAC,0xFF,0xA7,0xFF,0xA6,0xFF,0xA0,0xFF, + 0xA3,0xFF,0xA9,0xFF,0xAB,0xFF,0xAA,0xFF,0xAC,0xFF,0xAF,0xFF, + 0xB6,0xFF,0xAA,0xFF,0xAB,0xFF,0xB5,0xFF,0xB4,0xFF,0xB3,0xFF, + 0xB9,0xFF,0xB4,0xFF,0xB8,0xFF,0xAF,0xFF,0xB8,0xFF,0xB7,0xFF, + 0xC1,0xFF,0xC8,0xFF,0xC5,0xFF,0xE4,0xFF,0xB6,0xFF,0xCC,0xFF, + 0xB2,0xFF,0xC6,0xFF,0xB5,0xFF,0xB4,0xFF,0xBC,0xFF,0xA7,0xFF, + 0xB7,0xFF,0xAF,0xFF,0xBE,0xFF,0xB6,0xFF,0xB9,0xFF,0xC0,0xFF, + 0xC9,0xFF,0xC8,0xFF,0xCB,0xFF,0xCD,0xFF,0xCE,0xFF,0xC8,0xFF, + 0xD7,0xFF,0xD9,0xFF,0xE1,0xFF,0xE2,0xFF,0xEC,0xFF,0xE8,0xFF, + 0xEF,0xFF,0xE7,0xFF,0xEA,0xFF,0xEE,0xFF,0xEE,0xFF,0xF5,0xFF, + 0xF2,0xFF,0xFC,0xFF,0xEF,0xFF,0xF6,0xFF,0x00,0x00,0xDB,0xFF, + 0xEF,0xFF,0xE8,0xFF,0xF2,0xFF,0xF0,0xFF,0x02,0x00,0x01,0x00, + 0xF9,0xFF,0xF6,0xFF,0xFE,0xFF,0xFB,0xFF,0xF1,0xFF,0xF2,0xFF, + 0xF1,0xFF,0xFD,0xFF,0xF9,0xFF,0xF6,0xFF,0x01,0x00,0xF9,0xFF, + 0x06,0x00,0x03,0x00,0xFD,0xFF,0x0A,0x00,0x10,0x00,0x13,0x00, + 0x15,0x00,0x0E,0x00,0x14,0x00,0x0F,0x00,0x10,0x00,0x0D,0x00, + 0x12,0x00,0x19,0x00,0x14,0x00,0x1B,0x00,0x13,0x00,0x1D,0x00, + 0x18,0x00,0x12,0x00,0x22,0x00,0x20,0x00,0x21,0x00,0x20,0x00, + 0x21,0x00,0x20,0x00,0x24,0x00,0x25,0x00,0x24,0x00,0x24,0x00, + 0x25,0x00,0x23,0x00,0x23,0x00,0x2C,0x00,0x27,0x00,0x31,0x00, + 0x28,0x00,0x2E,0x00,0x31,0x00,0x35,0x00,0x35,0x00,0x2E,0x00, + 0x30,0x00,0x35,0x00,0x2E,0x00,0x2B,0x00,0x36,0x00,0x31,0x00, + 0x38,0x00,0x33,0x00,0x33,0x00,0x33,0x00,0x35,0x00,0x3C,0x00, + 0x39,0x00,0x3A,0x00,0x3C,0x00,0x37,0x00,0x31,0x00,0x40,0x00, + 0x3A,0x00,0x34,0x00,0x36,0x00,0x38,0x00,0x41,0x00,0x44,0x00, + 0x40,0x00,0x48,0x00,0x4E,0x00,0x52,0x00,0x53,0x00,0x4C,0x00, + 0x4A,0x00,0x4C,0x00,0x55,0x00,0x4C,0x00,0x54,0x00,0x50,0x00, + 0x4E,0x00,0x4E,0x00,0x51,0x00,0x4F,0x00,0x4C,0x00,0x51,0x00, + 0x4D,0x00,0x4C,0x00,0x52,0x00,0x58,0x00,0x4D,0x00,0x57,0x00, + 0x52,0x00,0x4D,0x00,0x4E,0x00,0x49,0x00,0x56,0x00,0x57,0x00, + 0x59,0x00,0x5B,0x00,0x5D,0x00,0x5C,0x00,0x5E,0x00,0x60,0x00, + 0x61,0x00,0x61,0x00,0x65,0x00,0x69,0x00,0x6A,0x00,0x67,0x00, + 0x6F,0x00,0x78,0x00,0x69,0x00,0x67,0x00,0x6D,0x00,0x70,0x00, + 0x67,0x00,0x6A,0x00,0x6C,0x00,0x6D,0x00,0x6A,0x00,0x65,0x00, + 0x62,0x00,0x65,0x00,0x62,0x00,0x5B,0x00,0x57,0x00,0x58,0x00, + 0x55,0x00,0x58,0x00,0x5B,0x00,0x54,0x00,0x5D,0x00,0x51,0x00, + 0x53,0x00,0x4D,0x00,0x49,0x00,0x4C,0x00,0x4A,0x00,0x4B,0x00, + 0x44,0x00,0x39,0x00,0x3A,0x00,0x37,0x00,0x32,0x00,0x32,0x00, + 0x32,0x00,0x2D,0x00,0x28,0x00,0x29,0x00,0x26,0x00,0x23,0x00, + 0x1F,0x00,0x17,0x00,0x15,0x00,0x0E,0x00,0x09,0x00,0x06,0x00, + 0x06,0x00,0x01,0x00,0x03,0x00,0xFC,0xFF,0xFF,0xFF,0xF5,0xFF, + 0xF5,0xFF,0xEE,0xFF,0xEA,0xFF,0xE9,0xFF,0xE4,0xFF,0xE1,0xFF, + 0xDF,0xFF,0xE0,0xFF,0xE1,0xFF,0xD7,0xFF,0xD4,0xFF,0xD6,0xFF, + 0xD2,0xFF,0xCB,0xFF,0xC1,0xFF,0xC0,0xFF,0xBF,0xFF,0xB7,0xFF, + 0xB5,0xFF,0xB1,0xFF,0xAB,0xFF,0xA6,0xFF,0xB7,0xFF,0xA8,0xFF, + 0xAD,0xFF,0xA4,0xFF,0xA5,0xFF,0xA6,0xFF,0xA5,0xFF,0x9C,0xFF, + 0x9D,0xFF,0xA7,0xFF,0xA2,0xFF,0x92,0xFF,0xB0,0xFF,0x12,0xFD, + 0x2F,0x00,0x0B,0xFF,0xE1,0xFF,0x37,0x00,0xB2,0xFE,0xFF,0xFE, + 0xBE,0xFF,0x52,0xFF,0xC2,0xFF,0x88,0xFF,0xD4,0xFF,0xB7,0xFF, + 0xB2,0xFF,0xE0,0xFF,0xA1,0xFF,0x93,0xFF,0xD6,0xFF,0x0D,0xFF, + 0xB9,0xFF,0x3C,0xFF,0xFF,0xFF,0x08,0x00,0x76,0xFF,0xD1,0xFF, + 0x52,0xFF,0x5E,0xFF,0xC0,0xFF,0xAC,0xFF,0x02,0x00,0xEC,0xFF, + 0x97,0xFF,0x90,0xFF,0x4C,0xFF,0x7F,0xFF,0x76,0xFF,0xA4,0xFF, + 0xC5,0xFF,0xD5,0xFF,0x89,0xFF,0xB5,0xFF,0x92,0xFF,0xF3,0xFF, + 0x07,0x00,0x26,0x00,0x22,0x00,0xF4,0xFF,0x04,0x00,0xB3,0xFF, + 0xEF,0xFF,0xBD,0xFF,0xCC,0xFF,0xCA,0xFF,0xB1,0xFF,0xA0,0xFF, + 0xA5,0xFF,0xCE,0xFF,0x8E,0xFF,0xB1,0xFF,0xB7,0xFF,0xCC,0xFF, + 0xAF,0xFF,0x94,0xFF,0x9F,0xFF,0x8B,0xFF,0x7C,0xFF,0x80,0xFF, + 0x9D,0xFF,0x4C,0xFF,0x63,0xFF,0x7B,0xFF,0x81,0xFF,0x6D,0xFF, + 0x7E,0xFF,0x6D,0xFF,0x79,0xFF,0x60,0xFF,0x65,0xFF,0xC9,0xFF, + 0x61,0xFF,0x7E,0xFF,0x85,0xFF,0xC5,0xFF,0xBB,0xFF,0x32,0xFF, + 0x81,0xFF,0xA5,0xFF,0xDF,0xFF,0xB2,0xFF,0xD2,0xFF,0x7F,0xFF, + 0xA6,0xFF,0xB9,0xFF,0xA4,0xFF,0x22,0x00,0xB2,0xFF,0x38,0x00, + 0xB9,0xFF,0x1D,0x00,0x7F,0xFF,0xF0,0xFF,0xA0,0xFF,0x19,0x00, + 0x89,0xFF,0xF2,0xFF,0xBD,0xFF,0xE1,0xFF,0xB9,0xFF,0x8E,0x00, + 0xDF,0xFF,0xC2,0xFF,0x08,0x00,0x61,0x00,0xEC,0xFF,0x97,0x00, + 0x38,0x00,0x5A,0x00,0x06,0x00,0x02,0x00,0x25,0x00,0x2A,0x00, + 0x25,0x00,0x30,0x00,0x20,0x00,0x00,0x00,0x37,0x00,0x1F,0x00, + 0xE4,0xFF,0x52,0x00,0x12,0x00,0xB0,0x00,0x5D,0x00,0x2D,0x00, + 0x7A,0x00,0x5C,0x00,0x01,0x00,0x69,0x00,0x7F,0x00,0x54,0x00, + 0x62,0x00,0x1B,0x00,0x4F,0x00,0x25,0x00,0x6E,0x00,0x2C,0x00, + 0x53,0x00,0x73,0x00,0x3C,0x00,0x4C,0x00,0x0D,0x00,0x4C,0x00, + 0x32,0x00,0x25,0x00,0x9A,0x00,0x1C,0x00,0x3B,0x00,0x0B,0x00, + 0x02,0x00,0x1F,0x00,0x4C,0x00,0xD8,0xFF,0x56,0x00,0xF8,0xFF, + 0x3D,0x00,0xFC,0xFF,0xFB,0xFF,0x36,0x00,0xDC,0xFF,0xF2,0xFF, + 0x4E,0x00,0x3F,0x00,0x24,0x00,0x0C,0x00,0xF3,0xFF,0xF4,0xFF, + 0x1B,0x00,0xD4,0xFF,0x0F,0x00,0xD0,0xFF,0xCF,0xFF,0xE2,0xFF, + 0xA7,0xFF,0xF5,0xFF,0xA8,0xFF,0xE0,0xFF,0xFE,0xFF,0xDC,0xFF, + 0xC0,0xFF,0xB5,0xFF,0xB5,0xFF,0xB6,0xFF,0x9D,0xFF,0xF2,0xFF, + 0xC0,0xFF,0xA5,0xFF,0x7D,0xFF,0x97,0xFF,0x5B,0xFF,0x61,0xFF, + 0x7E,0xFF,0xAB,0xFF,0x60,0xFF,0xE3,0xFF,0x61,0xFF,0x75,0xFF, + 0x70,0xFF,0x8B,0xFF,0xD1,0xFF,0x78,0xFF,0x93,0xFF,0x41,0xFF, + 0x91,0xFF,0x3A,0xFF,0x9F,0xFF,0x5C,0xFF,0x87,0xFF,0x49,0xFF, + 0x45,0xFF,0x51,0xFF,0x4A,0xFF,0x89,0xFF,0x59,0xFF,0x94,0xFF, + 0xBA,0xFF,0x6D,0xFF,0x8E,0xFF,0x1B,0xFF,0x73,0xFF,0x37,0xFF, + 0x91,0xFF,0x77,0xFF,0xC2,0xFF,0x27,0xFF,0x94,0xFF,0x03,0xFF, + 0x5B,0xFF,0x0B,0xFF,0xC4,0xFF,0x39,0xFF,0xA0,0xFF,0x20,0xFF, + 0x5F,0xFF,0x17,0xFF,0x69,0xFF,0x6B,0xFF,0xA5,0xFF,0x73,0xFF, + 0x6B,0xFF,0x86,0xFF,0x88,0xFF,0xB8,0xFF,0x7D,0xFF,0x94,0xFF, + 0x72,0xFF,0xC8,0xFF,0x7A,0xFF,0xA6,0xFF,0xAC,0xFF,0x83,0xFF, + 0xDC,0xFF,0x8B,0xFF,0xE4,0xFF,0xA0,0xFF,0xCC,0xFF,0xA7,0xFF, + 0xD3,0xFF,0x75,0xFF,0xF8,0xFF,0xE4,0xFF,0xD3,0xFF,0x9E,0xFF, + 0x24,0x00,0xF1,0xFF,0x0D,0x00,0xCD,0xFF,0xEC,0xFF,0xE7,0xFF, + 0xCF,0xFF,0x37,0x00,0x11,0x00,0x0B,0x00,0xE9,0xFF,0xE3,0xFF, + 0xDC,0xFF,0xCF,0xFF,0xF4,0xFF,0x0E,0x00,0x33,0x00,0xEF,0xFF, + 0x40,0x00,0x00,0x00,0x2C,0x00,0x00,0x00,0x34,0x00,0x2F,0x00, + 0x3E,0x00,0x2D,0x00,0x0F,0x00,0x15,0x00,0x1F,0x00,0x03,0x00, + 0x1B,0x00,0x48,0x00,0x1B,0x00,0x2E,0x00,0x02,0x00,0x46,0x00, + 0x39,0x00,0x4A,0x00,0x29,0x00,0x12,0x00,0x2D,0x00,0x55,0x00, + 0x5D,0x00,0x6B,0x00,0x5F,0x00,0x15,0x00,0x28,0x00,0x22,0x00, + 0x4C,0x00,0x51,0x00,0x58,0x00,0x65,0x00,0x62,0x00,0x40,0x00, + 0x5D,0x00,0x48,0x00,0x1C,0x00,0x77,0x00,0x63,0x00,0x83,0x00, + 0x4D,0x00,0x21,0x00,0x10,0x00,0x21,0x00,0x4A,0x00,0x69,0x00, + 0x6E,0x00,0x45,0x00,0x4C,0x00,0x8C,0x00,0xFB,0xFF,0xF8,0xFF, + 0x4B,0x00,0x5E,0x00,0x5F,0x00,0xF9,0xFF,0x17,0x00,0x53,0x00, + 0xF0,0xFF,0xDF,0xFF,0xEC,0xFF,0x38,0x00,0xF6,0xFF,0x46,0x00, + 0x17,0x00,0x22,0x00,0xD2,0xFF,0x0E,0x00,0x04,0x00,0x4A,0x00, + 0x22,0x00,0x39,0x00,0xFD,0xFF,0x08,0x00,0xCC,0xFF,0x07,0x00, + 0x16,0x00,0x28,0x00,0xF6,0xFF,0xDB,0xFF,0xC2,0xFF,0xC0,0xFF, + 0xEB,0xFF,0xF0,0xFF,0x17,0x00,0x20,0x00,0xC3,0xFF,0x94,0xFF, + 0x8A,0xFF,0xC7,0xFF,0xFA,0xFF,0xF7,0xFF,0xE8,0xFF,0xBA,0xFF, + 0xA1,0xFF,0x9E,0xFF,0xC2,0xFF,0x0C,0x00,0x3B,0x00,0x04,0x00, + 0xD9,0xFF,0xA8,0xFF,0xC1,0xFF,0xFD,0xFF,0x04,0x00,0x26,0x00, + 0x0C,0x00,0xAF,0xFF,0x8E,0xFF,0x93,0xFF,0xDE,0xFF,0xFD,0xFF, + 0x0B,0x00,0xF4,0xFF,0xD1,0xFF,0xA0,0xFF,0xA3,0xFF,0xC5,0xFF, + 0x06,0x00,0x1C,0x00,0xE2,0xFF,0xB8,0xFF,0xA9,0xFF,0xBD,0xFF, + 0xF3,0xFF,0xFC,0xFF,0x07,0x00,0xDC,0xFF,0xB0,0xFF,0x96,0xFF, + 0xA2,0xFF,0xCB,0xFF,0xFE,0xFF,0xFA,0xFF,0xC7,0xFF,0xA0,0xFF, + 0x82,0xFF,0x99,0xFF,0xCE,0xFF,0xE8,0xFF,0xDD,0xFF,0xCD,0xFF, + 0xA0,0xFF,0x98,0xFF,0xBF,0xFF,0xDB,0xFF,0xE2,0xFF,0xD4,0xFF, + 0xB4,0xFF,0xA3,0xFF,0x9F,0xFF,0xB5,0xFF,0xE2,0xFF,0xDC,0xFF, + 0xCA,0xFF,0xA9,0xFF,0xA2,0xFF,0xA5,0xFF,0xC9,0xFF,0xD1,0xFF, + 0xDA,0xFF,0xC3,0xFF,0xB6,0xFF,0xB6,0xFF,0xB9,0xFF,0xD0,0xFF, + 0xDE,0xFF,0xCE,0xFF,0xCB,0xFF,0xBD,0xFF,0xC5,0xFF,0xD1,0xFF, + 0xCC,0xFF,0xCA,0xFF,0xBC,0xFF,0xA5,0xFF,0xA2,0xFF,0xC2,0xFF, + 0xC8,0xFF,0xC8,0xFF,0xA4,0xFF,0x95,0xFF,0x97,0xFF,0xB2,0xFF, + 0xC4,0xFF,0xCB,0xFF,0xA7,0xFF,0x89,0xFF,0x97,0xFF,0xA7,0xFF, + 0xB9,0xFF,0xBA,0xFF,0xA4,0xFF,0x8A,0xFF,0x76,0xFF,0x68,0xFF, + 0x80,0xFF,0x9B,0xFF,0x8E,0xFF,0x63,0xFF,0x67,0xFF,0x69,0xFF, + 0x8A,0xFF,0x93,0xFF,0x7F,0xFF,0x71,0xFF,0x6C,0xFF,0x6C,0xFF, + 0x73,0xFF,0x88,0xFF,0x73,0xFF,0x6A,0xFF,0x5F,0xFF,0x71,0xFF, + 0x70,0xFF,0x73,0xFF,0x84,0xFF,0x68,0xFF,0x75,0xFF,0x84,0xFF, + 0xA7,0xFF,0xBA,0xFF,0xC7,0xFF,0xCB,0xFF,0xD8,0xFF,0xE9,0xFF, + 0x0A,0x00,0x0E,0x00,0x10,0x00,0x1C,0x00,0x34,0x00,0x33,0x00, + 0x41,0x00,0x66,0x00,0x78,0x00,0x7A,0x00,0x66,0x00,0x59,0x00, + 0x57,0x00,0x52,0x00,0x34,0x00,0xD9,0xFF,0xB3,0xFF,0x71,0xFF, + 0x30,0xFF,0x03,0xFF,0xB0,0xFE,0x6A,0xFE,0x8C,0xFE,0x64,0xFE, + 0x49,0xFE,0x36,0xFE,0x46,0xFE,0x27,0xFE,0x7A,0xFE,0xA3,0xFE, + 0xD1,0xFE,0xE0,0xFE,0x1B,0xFF,0x26,0xFF,0x46,0xFF,0x69,0xFF, + 0x69,0xFF,0x61,0xFF,0x77,0xFF,0x92,0xFF,0x91,0xFF,0xAA,0xFF, + 0xA1,0xFF,0xB2,0xFF,0xC7,0xFF,0xF1,0xFF,0x01,0x00,0x1E,0x00, + 0x45,0x00,0x6E,0x00,0x9C,0x00,0xEE,0x00,0x33,0x01,0x8A,0x01, + 0x0F,0x02,0x69,0x02,0xCF,0x02,0xB6,0x02,0xAF,0x00,0x69,0x00, + 0x73,0x01,0xE8,0x00,0xCF,0xFF,0x15,0xFF,0xCA,0xFE,0xEA,0xFD, + 0xDF,0xFE,0xA1,0xFE,0x29,0xFE,0x7F,0xFD,0x5E,0xFE,0x7A,0xFE, + 0xEE,0xFE,0x64,0xFF,0x73,0xFF,0xAF,0xFF,0x82,0x00,0x79,0x01, + 0xFB,0x00,0x02,0x01,0xCC,0x00,0x0D,0x01,0xFB,0x00,0x5A,0x01, + 0x69,0x00,0xE0,0xFF,0xD0,0xFF,0x8B,0xFF,0x11,0xFF,0x6C,0xFE, + 0x74,0xFE,0x58,0xFE,0x9C,0xFE,0xA3,0xFE,0xC5,0xFE,0x67,0xFE, + 0xEA,0xFE,0x1C,0xFF,0x4B,0xFF,0x60,0xFF,0x8A,0xFF,0x90,0xFF, + 0xF8,0xFF,0x5D,0x00,0x3C,0x00,0x5D,0x00,0x74,0x00,0xBC,0x00, + 0xC4,0x00,0x0D,0x01,0x33,0x01,0xA1,0x01,0xF3,0x01,0x68,0x02, + 0xD1,0x02,0x04,0x03,0x5E,0x03,0xE1,0x02,0xEB,0x00,0xA2,0x02, + 0x76,0x01,0xD2,0x00,0x32,0xFF,0x4E,0x00,0x8F,0xFE,0x5E,0xFF, + 0xA4,0xFE,0x07,0xFE,0x21,0xFD,0x4D,0xFE,0xDB,0xFE,0x4E,0xFE, + 0xB3,0xFE,0x37,0xFF,0x2E,0x00,0x6D,0x00,0xA7,0x01,0xD5,0x00, + 0x1C,0x01,0xC3,0x01,0x22,0x02,0x93,0x01,0x53,0x01,0x38,0x01, + 0xC9,0x00,0xC0,0x00,0x5C,0x00,0xBC,0xFF,0x05,0xFF,0x58,0xFF, + 0x35,0xFF,0xB5,0xFE,0x6C,0xFE,0x6E,0xFE,0x8D,0xFE,0xA0,0xFE, + 0xDD,0xFE,0xCE,0xFE,0x00,0xFF,0x74,0xFF,0xA9,0xFF,0x5B,0xFF, + 0xA9,0xFF,0xFC,0xFF,0x35,0x00,0x57,0x00,0x7F,0x00,0x8E,0x00, + 0xC0,0x00,0x30,0x01,0x18,0x01,0x3B,0x01,0x93,0x01,0x34,0x02, + 0x53,0x02,0xD5,0x02,0xF4,0x02,0x12,0x03,0xB3,0x02,0xA6,0x00, + 0xD9,0x02,0xDB,0x00,0x9B,0x00,0xEF,0xFE,0x6C,0x00,0x91,0xFE, + 0xFB,0xFE,0x4B,0xFE,0xD0,0xFD,0x9E,0xFD,0x41,0xFE,0xBA,0xFE, + 0xB7,0xFD,0xB1,0xFE,0x72,0xFF,0xEF,0xFF,0xF2,0xFF,0xA3,0x00, + 0xEC,0x00,0xFE,0x00,0x91,0x01,0x2F,0x01,0x4C,0x01,0x13,0x01, + 0x54,0x01,0x6F,0x00,0x34,0x00,0xFC,0xFF,0xBE,0xFF,0x5F,0xFF, + 0x09,0xFF,0x90,0xFE,0x54,0xFE,0x7D,0xFE,0xC1,0xFD,0x10,0xFE, + 0x22,0xFE,0x57,0xFE,0x42,0xFE,0x87,0xFE,0x8B,0xFE,0xC5,0xFE, + 0x29,0xFF,0x45,0xFF,0x1E,0xFF,0x6F,0xFF,0xEB,0xFF,0xFB,0xFF, + 0x05,0x00,0x44,0x00,0x5B,0x00,0x81,0x00,0xBA,0x00,0xE1,0x00, + 0xF8,0x00,0x77,0x01,0xFC,0x01,0xD9,0x01,0x5F,0x02,0x70,0x02, + 0x43,0x01,0x30,0x00,0x68,0x02,0x6A,0x00,0x36,0xFF,0xD6,0xFE, + 0x0C,0x00,0x71,0xFE,0x27,0xFE,0x9E,0xFD,0xCE,0xFD,0x58,0xFD, + 0xD6,0xFD,0xB1,0xFD,0x9A,0xFD,0xE5,0xFE,0x06,0xFF,0x0C,0xFF, + 0x46,0xFF,0x79,0x00,0xBA,0x00,0x82,0x00,0xAB,0x00,0x01,0x01, + 0x33,0x01,0xCE,0x00,0xA6,0x00,0x59,0x00,0x45,0x00,0x00,0x00, + 0x8B,0xFF,0x08,0xFF,0xE6,0xFE,0xFA,0xFE,0xD9,0xFD,0x25,0xFE, + 0x46,0xFE,0x08,0xFE,0x05,0xFE,0x37,0xFE,0x63,0xFE,0x22,0xFE, + 0x8D,0xFE,0x9B,0xFE,0xED,0xFE,0x0E,0xFF,0x62,0xFF,0x45,0xFF, + 0x98,0xFF,0xFC,0xFF,0x16,0x00,0x3C,0x00,0x40,0x00,0xA4,0x00, + 0xA2,0x00,0xE9,0x00,0x10,0x01,0x69,0x01,0xBD,0x01,0xDE,0x01, + 0x0F,0x02,0x5A,0x02,0x46,0x02,0x11,0x00,0xE9,0x01,0x5F,0x02, + 0xB0,0xFF,0x3C,0xFF,0x37,0x00,0x5A,0x00,0xEA,0xFD,0x4A,0xFE, + 0x69,0xFE,0x61,0xFE,0xE1,0xFD,0xF9,0xFD,0x48,0xFE,0x55,0xFE, + 0x01,0xFF,0x05,0xFF,0x6E,0xFF,0x0F,0x00,0x93,0x00,0x77,0x00, + 0xAA,0x00,0x41,0x01,0x77,0x01,0xF3,0x00,0xFC,0x00,0x42,0x01, + 0xFD,0x00,0x51,0x00,0x51,0x00,0x0E,0x00,0xAD,0xFF,0x75,0xFF, + 0xF9,0xFE,0x84,0xFE,0x09,0xFF,0x1D,0xFE,0xF0,0xFD,0x05,0xFE, + 0x78,0xFE,0x54,0xFE,0x49,0xFE,0xBA,0xFE,0xE2,0xFE,0x01,0xFF, + 0x3C,0xFF,0xAB,0xFF,0xCE,0xFF,0xEC,0xFF,0x49,0x00,0x6B,0x00, + 0xB1,0x00,0xE6,0x00,0xFD,0x00,0x1F,0x01,0x3A,0x01,0x93,0x01, + 0xBA,0x01,0xFD,0x01,0x1C,0x02,0x48,0x02,0x86,0x02,0xA4,0x01, + 0x21,0x00,0x0F,0x02,0x6E,0x01,0x78,0xFF,0xB2,0xFF,0xD6,0x00, + 0x96,0xFF,0xAE,0xFD,0x29,0xFF,0x0A,0xFF,0x3D,0xFE,0xD5,0xFD, + 0x70,0xFE,0xB3,0xFE,0x52,0xFE,0xF4,0xFE,0x28,0xFF,0x98,0xFF, + 0x0C,0x00,0x5A,0x00,0x77,0x00,0xD3,0x00,0x75,0x01,0x11,0x01, + 0x16,0x01,0x5C,0x01,0x74,0x01,0xB2,0x00,0x8E,0x00,0xCC,0x00, + 0x5A,0x00,0xAE,0xFF,0xA4,0xFF,0xA8,0xFF,0x7F,0xFE,0x57,0xFE, + 0xC8,0xFE,0xC8,0xFD,0xF2,0xFD,0x60,0xFE,0xB2,0xFE,0x05,0xFE, + 0xB2,0xFE,0xF1,0xFE,0xFD,0xFE,0x2A,0xFF,0x87,0xFF,0xC8,0xFF, + 0xFC,0xFF,0xA3,0x00,0x8D,0x00,0xA9,0x00,0x07,0x01,0x2F,0x01, + 0x3A,0x01,0x52,0x01,0xC6,0x01,0xD4,0x01,0xEF,0x01,0x0C,0x02, + 0x4C,0x02,0x65,0x02,0x09,0x02,0x24,0x00,0x4D,0x02,0x34,0x01, + 0x44,0xFF,0xB8,0xFF,0xF1,0x00,0x77,0xFF,0xA5,0xFD,0x39,0xFF, + 0x1B,0xFF,0x30,0xFE,0x9F,0xFD,0x88,0xFE,0xC1,0xFE,0x78,0xFE, + 0xC3,0xFE,0x14,0xFF,0xCC,0xFF,0xFD,0xFF,0x0C,0x00,0x64,0x00, + 0x14,0x01,0x49,0x01,0xE3,0x00,0x33,0x01,0x60,0x01,0x4E,0x01, + 0xBA,0x00,0xCA,0x00,0xCA,0x00,0x4D,0x00,0xE3,0xFF,0xC8,0xFF, + 0xBC,0xFF,0xF7,0xFE,0xFA,0xFD,0xB2,0xFE,0xA1,0xFE,0xE3,0xFD, + 0x67,0xFE,0x8A,0xFE,0x79,0xFE,0x06,0xFE,0x10,0xFF,0xF5,0xFE, + 0xFD,0xFE,0x33,0xFF,0xB5,0xFF,0xD8,0xFF,0x32,0x00,0x79,0x00, + 0x85,0x00,0xC3,0x00,0x13,0x01,0x00,0x01,0x24,0x01,0x70,0x01, + 0x9D,0x01,0x7E,0x01,0xD3,0x01,0xFE,0x01,0x1C,0x02,0x01,0x02, + 0x19,0x01,0xF9,0x00,0x8B,0x02,0x30,0x00,0x51,0xFF,0x06,0x00, + 0xE4,0x00,0x35,0xFE,0x38,0xFE,0x2E,0xFF,0x95,0xFE,0x9E,0xFD, + 0x10,0xFE,0x9B,0xFE,0x20,0xFE,0x52,0xFE,0xC6,0xFE,0xE7,0xFE, + 0x90,0xFF,0xC1,0xFF,0xEF,0xFF,0x41,0x00,0x0C,0x01,0xAC,0x00, + 0x9B,0x00,0x17,0x01,0x23,0x01,0xA2,0x00,0x79,0x00,0x9F,0x00, + 0x29,0x00,0xD6,0xFF,0xB0,0xFF,0x69,0xFF,0x39,0xFF,0xF2,0xFE, + 0xAD,0xFD,0xA6,0xFE,0xBF,0xFE,0x80,0xFD,0xBE,0xFD,0xBC,0xFE, + 0x15,0xFE,0x80,0xFD,0xB5,0xFE,0xEB,0xFE,0xD0,0xFE,0xFE,0xFE, + 0xB9,0xFF,0xAD,0xFF,0x0F,0x00,0x61,0x00,0x51,0x00,0xC8,0x00, + 0x12,0x01,0xD7,0x00,0xCF,0x00,0x62,0x01,0x67,0x01,0x21,0x01, + 0xA2,0x01,0xB6,0x01,0x93,0x01,0xC1,0x01,0x91,0x01,0xD6,0xFF, + 0xD3,0x01,0x3E,0x01,0xAA,0xFF,0x64,0xFF,0xAE,0x00,0x9A,0xFF, + 0xCC,0xFD,0xFE,0xFE,0xB8,0xFE,0x3B,0xFE,0xC3,0xFD,0x93,0xFE, + 0x0A,0xFE,0x85,0xFE,0xE9,0xFE,0xDD,0xFE,0x69,0xFF,0x17,0x00, + 0xF8,0xFF,0xC9,0xFF,0xF3,0x00,0xBC,0x00,0x50,0x00,0x9D,0x00, + 0x07,0x01,0x7B,0x00,0x20,0x00,0x82,0x00,0x1A,0x00,0xCB,0xFF, + 0x96,0xFF,0x78,0xFF,0x23,0xFF,0x2D,0xFF,0x18,0xFE,0x28,0xFE, + 0x19,0xFF,0x02,0xFE,0xB0,0xFD,0x44,0xFE,0xFF,0xFE,0xDC,0xFD, + 0x90,0xFE,0x01,0xFF,0x40,0xFF,0x0F,0xFF,0xA2,0xFF,0xAD,0xFF, + 0x09,0x00,0x67,0x00,0x46,0x00,0x42,0x00,0xD8,0x00,0xB6,0x00, + 0x5B,0x00,0xB6,0x00,0x0B,0x01,0xA1,0x00,0x07,0x01,0x20,0x01, + 0x26,0x01,0x12,0x01,0x71,0x01,0x53,0x01,0x93,0xFF,0x29,0x01, + 0xC7,0x00,0xD7,0xFF,0x84,0xFF,0x72,0x00,0x6D,0xFF,0xBB,0xFE, + 0x2D,0xFF,0xC6,0xFE,0xB6,0xFE,0x6E,0xFE,0xAB,0xFE,0x09,0xFE, + 0x18,0xFF,0xF8,0xFE,0xB1,0xFE,0xD6,0xFE,0xF1,0xFF,0xE3,0xFF, + 0x71,0xFF,0xF9,0xFF,0x36,0x00,0x1F,0x00,0x1B,0x00,0x41,0x00, + 0x12,0x00,0x17,0x00,0x3E,0x00,0xAC,0xFF,0xAE,0xFF,0x67,0xFF, + 0x9E,0xFF,0x34,0xFF,0xE8,0xFE,0xFF,0xFE,0xE4,0xFE,0x25,0xFF, + 0xB8,0xFE,0x18,0xFF,0xF5,0xFE,0x26,0xFF,0xFA,0xFE,0x5A,0xFF, + 0x56,0xFF,0xA9,0xFF,0xA1,0xFF,0xE8,0xFF,0xDD,0xFF,0x6C,0x00, + 0xB9,0xFF,0x80,0x00,0xD3,0xFF,0xCE,0x00,0x04,0x00,0x81,0x00, + 0xF6,0xFF,0xE6,0x00,0x10,0x00,0xC4,0x00,0x08,0x00,0xF0,0x00, + 0x67,0x00,0x92,0x00,0x30,0x00,0x97,0x00,0xEF,0x00,0x96,0x00, + 0x17,0x00,0xB5,0x00,0x72,0x00,0x93,0x00,0xED,0xFF,0x69,0x00, + 0xE6,0xFF,0xF3,0xFF,0xE7,0xFF,0x82,0xFF,0x9B,0xFF,0xAA,0xFF, + 0x95,0xFF,0x44,0xFF,0xC3,0xFF,0xB5,0xFF,0xA7,0xFF,0x97,0xFF, + 0xDC,0xFF,0xD3,0xFF,0xE3,0xFF,0x28,0x00,0x8D,0xFF,0xF6,0xFF, + 0x1B,0x00,0x41,0x00,0x91,0xFF,0xE3,0xFF,0xDA,0xFF,0xD6,0xFF, + 0xA2,0xFF,0xA8,0xFF,0x2B,0xFF,0x1A,0x00,0x09,0x00,0xF4,0xFF, + 0x3B,0xFF,0x45,0x00,0x99,0xFF,0x31,0x00,0x3A,0xFF,0xC2,0x00, + 0x6E,0xFF,0x82,0x00,0xB6,0xFF,0x13,0x00,0x0F,0xFF,0x47,0x01, + 0xA9,0xFF,0xB1,0x00,0x21,0xFF,0x60,0x00,0x95,0x00,0x05,0x00, + 0x2F,0x00,0x0D,0x00,0xD1,0x00,0xFE,0xFF,0xA4,0xFF,0x9F,0x00, + 0xC3,0xFF,0xE7,0x00,0xFF,0xFE,0x1A,0x01,0x2C,0xFF,0x97,0x00, + 0xE8,0xFF,0xDF,0xFF,0x72,0x00,0x70,0x00,0x6A,0x00,0xBD,0xFF, + 0x2B,0x00,0xD9,0xFF,0x64,0x00,0xA4,0xFF,0x4E,0x00,0x8E,0xFF, + 0xAD,0xFF,0xC3,0xFF,0x36,0x00,0x3D,0xFF,0xF9,0xFF,0xFA,0xFF, + 0xB1,0xFF,0xA7,0xFF,0xEB,0xFF,0xBD,0xFF,0x3E,0xFF,0x34,0xFF, + 0xDE,0xFF,0x8F,0xFF,0xE7,0xFF,0x52,0xFF,0xD7,0xFF,0x5B,0xFF, + 0xC1,0xFF,0x47,0x00,0xD4,0xFE,0x01,0x00,0x8C,0xFF,0x2E,0x00, + 0x56,0xFF,0x55,0xFF,0x72,0x00,0x5C,0xFF,0x7C,0x00,0xB6,0xFF, + 0xD4,0x00,0x4C,0xFF,0xC6,0x00,0x6D,0x00,0x10,0xFF,0x11,0x01, + 0x8E,0xFF,0xCA,0x00,0x09,0xFF,0x2A,0x01,0x8C,0xFF,0x19,0x00, + 0xD0,0xFF,0x97,0xFF,0x0F,0x00,0x05,0x00,0xD1,0x00,0xB6,0xFF, + 0xFD,0x00,0xD4,0xFF,0x2F,0x00,0x08,0x00,0x1D,0x00,0xD0,0xFF, + 0x92,0xFF,0xFD,0xFF,0xB8,0xFF,0x05,0x00,0x0D,0x00,0x12,0x00, + 0xDD,0xFE,0xDF,0x00,0x92,0xFE,0x9D,0xFF,0x0A,0x00,0x45,0xFE, + 0x63,0x01,0xB8,0xFE,0x56,0x00,0x70,0xFF,0x5E,0x00,0x74,0x00, + 0xBB,0xFE,0x41,0xFF,0x52,0x00,0x18,0xFF,0x5A,0xFE,0x06,0x00, + 0x1C,0x00,0x90,0x00,0xE7,0xFE,0x47,0xFF,0x2D,0x00,0x77,0xFF, + 0x9C,0x00,0x67,0xFE,0x01,0x00,0xAC,0xFF,0x67,0xFF,0xF0,0x00, + 0x3D,0xFF,0x99,0x00,0x5D,0xFE,0xA8,0xFF,0x99,0xFE,0xCA,0x00, + 0xC4,0xFF,0x62,0xFF,0xE9,0xFF,0x0E,0xFF,0x15,0x00,0x45,0xFF, + 0x27,0xFF,0x7F,0x00,0x57,0x00,0x3D,0x00,0x05,0x01,0x99,0xFF, + 0x3B,0xFF,0x24,0xFF,0xFC,0xFF,0x42,0xFF,0xCA,0xFE,0xE8,0xFE, + 0xBB,0xFE,0xFB,0xFF,0xE1,0xFE,0xCD,0xFE,0xF0,0x00,0x91,0xFF, + 0xD7,0x00,0xC0,0x00,0x64,0x00,0x8D,0xFF,0x68,0xFF,0x1E,0x01, + 0xF4,0xFD,0x35,0x00,0x4C,0xFF,0x39,0x00,0x3B,0xFE,0xA5,0x00, + 0x12,0xFE,0x58,0xFF,0x46,0x00,0xA5,0xFE,0xAB,0x01,0xE0,0xFF, + 0x81,0xFF,0x88,0xFD,0x2A,0x01,0xBB,0xFE,0xE1,0x00,0x92,0xFE, + 0xC1,0x02,0x46,0x00,0x69,0x00,0xA4,0xFF,0xF5,0xFE,0x65,0xFF, + 0x2E,0x00,0x7E,0x00,0xB7,0xFF,0x27,0xFF,0xE3,0x01,0xBB,0x00, + 0xF7,0xFF,0x36,0xFF,0x06,0xFF,0xCA,0x00,0x26,0x00,0xBA,0x00, + 0x18,0xFF,0xEC,0xFF,0x7F,0x00,0xA5,0xFF,0x63,0x01,0xFD,0xFF, + 0x0B,0x00,0x89,0x00,0x94,0x00,0x53,0xFF,0xAF,0x00,0x1D,0xFF, + 0x67,0x00,0xF3,0xFF,0xFF,0xFE,0x88,0xFF,0xE5,0xFE,0x60,0xFF, + 0x36,0xFF,0x0C,0x00,0x3B,0x00,0x86,0x00,0x4D,0xFF,0xD5,0x00, + 0x65,0xFE,0x9F,0x00,0x0A,0x00,0x4B,0x00,0xE0,0xFF,0x54,0xFF, + 0xF9,0xFE,0x76,0xFF,0xEC,0xFE,0x85,0xFF,0x4D,0xFE,0x3F,0x01, + 0x9F,0xFF,0xD6,0xFF,0x3D,0x00,0xB5,0x01,0x75,0x00,0x86,0x00, + 0xBB,0xFF,0x20,0x00,0x14,0xFE,0x82,0xFF,0x89,0xFE,0xA1,0x00, + 0x71,0xFF,0xFD,0xFF,0x7C,0xFF,0x12,0x00,0xCD,0x00,0x92,0xFE, + 0x88,0xFF,0x5E,0x01,0x3C,0xFF,0x0A,0x00,0x5A,0x00,0x59,0x00, + 0xB8,0xFF,0x71,0x00,0x07,0x00,0x25,0x00,0x99,0x00,0x95,0xFF, + 0xF1,0xFE,0xA4,0x00,0x8D,0x00,0x2A,0x00,0x2B,0x02,0xD8,0xFD, + 0x48,0x01,0xBC,0xFE,0x78,0x00,0xB5,0xFE,0x7A,0x00,0xF7,0xFF, + 0x78,0xFF,0xDA,0x00,0x61,0xFF,0xF9,0x00,0x8A,0xFF,0x39,0x00, + 0x2D,0xFE,0x92,0x00,0x28,0x00,0x5D,0xFE,0xBB,0xFD,0x5C,0xFF, + 0xCE,0x00,0x09,0x01,0xA0,0x00,0x6F,0xFF,0xCA,0xFE,0x1D,0xFF, + 0x81,0x01,0xC6,0xFE,0xE2,0xFE,0x78,0x00,0xEA,0x01,0x3E,0xFF, + 0xF2,0xFE,0xD9,0xFF,0x4E,0x00,0xAC,0xFF,0x48,0xFE,0x81,0x00, + 0x94,0x00,0x72,0x00,0x2F,0x00,0x45,0xFF,0x3B,0x00,0xE3,0xFF, + 0x54,0x00,0x2B,0x01,0xDA,0xFF,0x9B,0x01,0x72,0xFF,0xAB,0x01, + 0xA8,0xFF,0x45,0x02,0x72,0xFE,0x36,0x01,0x36,0xFF,0xCA,0xFE, + 0x45,0x00,0x8D,0xFF,0x49,0x01,0x98,0xFF,0xF0,0x01,0x7F,0xFE, + 0xE0,0xFE,0x1A,0xFF,0x7F,0x01,0x43,0xFD,0xD8,0xFE,0xF4,0xFC, + 0x90,0x00,0xD0,0xFF,0xAD,0x00,0xAE,0x00,0x3E,0xFD,0xD9,0xFF, + 0x1C,0xFF,0xF3,0xFF,0x77,0xFE,0x95,0xFF,0x9E,0xFE,0x1B,0x01, + 0xEF,0xFE,0xD0,0xFF,0x09,0x00,0x21,0xFF,0x79,0x00,0x36,0x00, + 0xA5,0x02,0x55,0xFF,0xB9,0x00,0xDE,0x01,0x4D,0x00,0x47,0x00, + 0xD0,0xFF,0x4E,0x02,0xBF,0x00,0xFF,0xFE,0x35,0x00,0x95,0xFE, + 0xDB,0x01,0x2A,0x00,0x66,0x00,0x25,0xFF,0x50,0x00,0x25,0xFF, + 0x75,0x00,0x86,0xFF,0x7E,0xFE,0xBD,0x00,0xEB,0xFD,0x8B,0x00, + 0xC2,0xFF,0x41,0x02,0xC2,0x00,0x87,0xFE,0x0C,0xFF,0x18,0x01, + 0x50,0x00,0xD1,0xFF,0xE8,0xFC,0x32,0x00,0x38,0x00,0xA6,0x01, + 0xA6,0xFE,0x96,0xFD,0x22,0xFF,0xA8,0x00,0x7C,0xFF,0x31,0xFE, + 0xD2,0xFF,0x3D,0xFF,0xF1,0x02,0xF0,0xFE,0x36,0x00,0x17,0x00, + 0xB2,0xFF,0xF0,0xFF,0xD6,0xFE,0x16,0xFE,0xE9,0xFF,0x47,0xFF, + 0x45,0x00,0xE2,0xFD,0x22,0x01,0xFD,0xFE,0xF3,0x00,0x9F,0xFD, + 0xE6,0xFF,0xB9,0xFD,0xE9,0xFF,0x34,0x00,0x26,0xFF,0xD7,0xFF, + 0xE2,0xFE,0x49,0xFF,0xC5,0xFF,0xAB,0x01,0x1C,0xFD,0x15,0x01, + 0x26,0xFF,0x02,0x01,0x48,0xFE,0x92,0xFF,0xE9,0xFF,0x77,0xFF, + 0x20,0x01,0xC4,0xFD,0x10,0x01,0x26,0xFD,0x1A,0x01,0x90,0xFD, + 0x7F,0x01,0xA6,0xFF,0x27,0xFF,0x3D,0xFF,0xEB,0xFD,0x09,0x02, + 0x89,0xFF,0xB5,0x00,0xB9,0xFE,0xC6,0xFE,0xB7,0xFF,0x01,0x00, + 0xC0,0xFE,0x6E,0x00,0x0B,0x00,0x6F,0xFE,0xF8,0xFE,0xAF,0x00, + 0x5A,0xFF,0xD3,0xFF,0x66,0xFD,0xC9,0x02,0xD0,0xFE,0x12,0x01, + 0x6A,0xFF,0xAF,0xFF,0x48,0x00,0xC7,0xFF,0xB4,0xFF,0x29,0x00, + 0xF6,0xFF,0x16,0xFF,0x1D,0xFF,0xEA,0xFF,0x24,0x00,0xDC,0xFF, + 0x9D,0x00,0x4D,0xFF,0x3F,0x00,0xD1,0xFE,0x47,0x00,0x91,0xFF, + 0x2F,0xFF,0xA3,0xFF,0x39,0x00,0x32,0xFE,0x38,0x00,0x54,0xFE, + 0x8F,0xFF,0x53,0x00,0x5F,0x00,0xE9,0xFF,0x37,0xFE,0x53,0xFF, + 0xE7,0x00,0x9F,0xFF,0x5A,0x00,0xCB,0xFE,0x81,0x00,0x27,0x00, + 0xC5,0x01,0xCC,0xFE,0x41,0xFF,0x11,0x01,0x68,0x00,0x2D,0xFF, + 0xF9,0xFE,0xD0,0x00,0xA2,0xFE,0xD4,0xFF,0x91,0xFF,0xCE,0x00, + 0x7E,0x00,0x8D,0xFE,0x80,0x00,0x81,0xFF,0x5E,0x00,0xCA,0xFF, + 0x4D,0x00,0xE3,0xFF,0x18,0x00,0x66,0xFF,0x58,0x00,0xAF,0xFE, + 0xA4,0x00,0x63,0xFF,0x50,0xFF,0xB7,0x00,0x60,0xFD,0x81,0x01, + 0x1A,0xFF,0xDF,0x00,0x65,0xFE,0x4F,0x01,0x07,0xFE,0x3A,0xFF, + 0x2D,0x00,0x59,0xFF,0xB2,0x00,0x8A,0xFD,0x5E,0x00,0x42,0xFE, + 0x52,0x01,0x1A,0x01,0x00,0xFE,0xBA,0xFF,0x2D,0xFF,0x26,0x01, + 0x48,0xFE,0x16,0x00,0x8C,0xFF,0x26,0xFE,0xC1,0x01,0x2F,0xFE, + 0x1D,0x01,0x6E,0xFF,0x41,0xFF,0xA4,0x00,0xF4,0xFE,0x27,0x01, + 0xCF,0xFD,0xCB,0x00,0xE0,0xFE,0x1F,0x00,0x86,0x01,0x6E,0xFD, + 0xB9,0x02,0x81,0xFC,0x14,0x00,0x49,0xFF,0x07,0x00,0x3C,0x00, + 0xE8,0xFC,0xE6,0x02,0x3D,0xFD,0x5F,0x01,0x0A,0x01,0x02,0xFD, + 0x58,0x02,0xFA,0xFC,0xEE,0x02,0x76,0xFD,0x15,0x01,0x2E,0xFF, + 0xB3,0xFE,0x86,0x01,0x38,0xFE,0x75,0x01,0x4A,0x00,0xD9,0xFE, + 0xBE,0x00,0x31,0xFF,0xCB,0xFF,0x02,0x00,0x06,0x00,0x17,0x00, + 0x2A,0x00,0x85,0xFF,0x67,0xFF,0xB7,0xFF,0x6F,0x01,0x94,0xFF, + 0x9E,0xFF,0x79,0xFF,0x9D,0xFF,0x71,0x00,0x2F,0xFF,0x3E,0x01, + 0x68,0xFF,0xA0,0xFF,0xE4,0xFF,0x61,0xFF,0x42,0x00,0x1C,0x00, + 0x23,0x00,0xFB,0xFF,0x08,0xFF,0x41,0x00,0xC5,0xFF,0x1B,0x00, + 0x96,0xFF,0xD7,0xFF,0xE0,0xFF,0x71,0x00,0xB2,0xFF,0x4D,0x00, + 0x15,0x00,0x28,0x00,0x29,0x00,0xD4,0xFF,0x6F,0x00,0x3F,0x00, + 0x8B,0x00,0x84,0x00,0xD5,0xFF,0xB4,0x00,0x0B,0x00,0x43,0x00, + 0x2E,0x00,0xFF,0xFF,0x1C,0x00,0xED,0xFF,0xBF,0xFF,0xA7,0xFF, + 0x83,0xFF,0x75,0xFF,0x92,0xFF,0x5D,0xFF,0x99,0xFF,0x5F,0xFF, + 0x85,0xFF,0xA2,0xFF,0x8E,0xFF,0xC1,0xFF,0xAC,0xFF,0xBB,0xFF, + 0xD3,0xFF,0xF1,0xFF,0xDD,0xFF,0xCF,0xFF,0x0A,0x00,0xD2,0xFF, + 0xD6,0xFF,0xE9,0xFF,0xBA,0xFF,0xBD,0xFF,0xB9,0xFF,0xD2,0xFF, + 0xBF,0xFF,0xAF,0xFF,0xAB,0xFF,0x84,0xFF,0xAB,0xFF,0x97,0xFF, + 0xA0,0xFF,0xA9,0xFF,0xBD,0xFF,0xAB,0xFF,0xB8,0xFF,0xC5,0xFF, + 0xBD,0xFF,0xCA,0xFF,0xE5,0xFF,0xCC,0xFF,0xF6,0xFF,0xEE,0xFF, + 0xFD,0xFF,0xF1,0xFF,0xF2,0xFF,0xFF,0xFF,0xF0,0xFF,0xD4,0xFF, + 0xCC,0xFF,0xE2,0xFF,0xB5,0xFF,0xDD,0xFF,0xBF,0xFF,0xAA,0xFF, + 0xB1,0xFF,0xA8,0xFF,0x9E,0xFF,0x98,0xFF,0x9E,0xFF,0x90,0xFF, + 0x99,0xFF,0x80,0xFF,0x9C,0xFF,0x9B,0xFF,0xAB,0xFF,0xA4,0xFF, + 0xA3,0xFF,0xB1,0xFF,0xB3,0xFF,0xBD,0xFF,0xC9,0xFF,0xC3,0xFF, + 0xBF,0xFF,0xCC,0xFF,0xC1,0xFF,0xD9,0xFF,0xB4,0xFF,0xC0,0xFF, + 0xBC,0xFF,0xC3,0xFF,0xC6,0xFF,0xBE,0xFF,0xB9,0xFF,0xB8,0xFF, + 0xB4,0xFF,0xCF,0xFF,0xBA,0xFF,0x96,0xFF,0xBA,0xFF,0xB4,0xFF, + 0xBD,0xFF,0xBE,0xFF,0xB3,0xFF,0xC3,0xFF,0xB3,0xFF,0xC2,0xFF, + 0xBE,0xFF,0xC9,0xFF,0xC5,0xFF,0xD7,0xFF,0xCC,0xFF,0xC4,0xFF, + 0xDA,0xFF,0xC9,0xFF,0xEF,0xFF,0xC3,0xFF,0xEC,0xFF,0xD3,0xFF, + 0xDB,0xFF,0xFB,0xFF,0xDF,0xFF,0xF2,0xFF,0xEB,0xFF,0xEC,0xFF, + 0x00,0x00,0xEB,0xFF,0x09,0x00,0xE3,0xFF,0x04,0x00,0xF4,0xFF, + 0xEA,0xFF,0x08,0x00,0xD9,0xFF,0x14,0x00,0xEF,0xFF,0x01,0x00, + 0x17,0x00,0x00,0x00,0x27,0x00,0xFC,0xFF,0x1F,0x00,0x17,0x00, + 0x2B,0x00,0x32,0x00,0x0F,0x00,0x22,0x00,0x10,0x00,0x1F,0x00, + 0x0E,0x00,0x25,0x00,0x12,0x00,0x0E,0x00,0x22,0x00,0x10,0x00, + 0x30,0x00,0x1D,0x00,0x23,0x00,0x21,0x00,0x14,0x00,0x23,0x00, + 0x0D,0x00,0x23,0x00,0x16,0x00,0x28,0x00,0x1B,0x00,0x26,0x00, + 0x1A,0x00,0x29,0x00,0x23,0x00,0x2C,0x00,0x1E,0x00,0x1E,0x00, + 0x18,0x00,0x16,0x00,0x1B,0x00,0x1B,0x00,0x13,0x00,0x19,0x00, + 0x07,0x00,0x17,0x00,0x19,0x00,0x0B,0x00,0x26,0x00,0x12,0x00, + 0x17,0x00,0x11,0x00,0x0B,0x00,0x13,0x00,0x02,0x00,0x15,0x00, + 0x0A,0x00,0x02,0x00,0x08,0x00,0xFC,0xFF,0x0D,0x00,0xFA,0xFF, + 0x10,0x00,0xFD,0xFF,0xF6,0xFF,0x00,0x00,0xF5,0xFF,0xF9,0xFF, + 0xFD,0xFF,0xEE,0xFF,0xFA,0xFF,0xF2,0xFF,0xEE,0xFF,0xEE,0xFF, + 0xEA,0xFF,0xF7,0xFF,0xE8,0xFF,0xF4,0xFF,0xE5,0xFF,0xE4,0xFF, + 0xE8,0xFF,0xDC,0xFF,0xE8,0xFF,0xDE,0xFF,0xEE,0xFF,0xD7,0xFF, + 0xE7,0xFF,0xDC,0xFF,0xE2,0xFF,0xE7,0xFF,0xDC,0xFF,0xE1,0xFF, + 0xD3,0xFF,0xD8,0xFF,0xD7,0xFF,0xE3,0xFF,0xD3,0xFF,0xD5,0xFF, + 0xCF,0xFF,0xD4,0xFF,0xC8,0xFF,0xCF,0xFF,0xCF,0xFF,0xC8,0xFF, + 0xCE,0xFF,0xCC,0xFF,0xC3,0xFF,0xCD,0xFF,0xD0,0xFF,0xD9,0xFF, + 0xD9,0xFF,0xCE,0xFF,0xD5,0xFF,0xC5,0xFF,0xD9,0xFF,0xD6,0xFF, + 0xD7,0xFF,0xD9,0xFF,0xD6,0xFF,0xE2,0xFF,0xD5,0xFF,0xD1,0xFF, + 0xE2,0xFF,0xD4,0xFF,0xE1,0xFF,0xD4,0xFF,0xD7,0xFF,0xC9,0xFF, + 0xCB,0xFF,0xD1,0xFF,0xD1,0xFF,0xE2,0xFF,0xD5,0xFF,0xDC,0xFF, + 0xD3,0xFF,0xE2,0xFF,0xE4,0xFF,0xD8,0xFF,0xE9,0xFF,0xD8,0xFF, + 0xE7,0xFF,0xD8,0xFF,0xD1,0xFF,0xE1,0xFF,0xCC,0xFF,0xE1,0xFF, + 0xCD,0xFF,0xD5,0xFF,0xCF,0xFF,0xC9,0xFF,0xE8,0xFF,0xC7,0xFF, + 0xE8,0xFF,0xD0,0xFF,0xCD,0xFF,0xD3,0xFF,0xD0,0xFF,0xDD,0xFF, + 0xC7,0xFF,0xDB,0xFF,0xC7,0xFF,0xD2,0xFF,0xCF,0xFF,0xC3,0xFF, + 0xDB,0xFF,0xC6,0xFF,0xD4,0xFF,0xCA,0xFF,0xCB,0xFF,0xD2,0xFF, + 0xC5,0xFF,0xD8,0xFF,0xC7,0xFF,0xDA,0xFF,0xCC,0xFF,0xD3,0xFF, + 0xD0,0xFF,0xCC,0xFF,0xD3,0xFF,0xCF,0xFF,0xC9,0xFF,0xD3,0xFF, + 0xBE,0xFF,0xD6,0xFF,0xC1,0xFF,0xD4,0xFF,0xC7,0xFF,0xC9,0xFF, + 0xCF,0xFF,0xC9,0xFF,0xCD,0xFF,0xCC,0xFF,0xCF,0xFF,0xCF,0xFF, + 0xD0,0xFF,0xD8,0xFF,0xD9,0xFF,0xE0,0xFF,0xE7,0xFF,0xD7,0xFF, + 0xE6,0xFF,0xDC,0xFF,0xE8,0xFF,0xE4,0xFF,0xE5,0xFF,0xE4,0xFF, + 0xE8,0xFF,0xE2,0xFF,0xE9,0xFF,0xDC,0xFF,0xE2,0xFF,0xE7,0xFF, + 0xE5,0xFF,0xEE,0xFF,0xE2,0xFF,0xE7,0xFF,0xE5,0xFF,0xEE,0xFF, + 0xEA,0xFF,0xEF,0xFF,0xE7,0xFF,0xEE,0xFF,0xED,0xFF,0xEB,0xFF, + 0xE8,0xFF,0xE4,0xFF,0xEF,0xFF,0xEC,0xFF,0xE9,0xFF,0xEB,0xFF, + 0xEE,0xFF,0xED,0xFF,0xF2,0xFF,0xEF,0xFF,0xF9,0xFF,0xED,0xFF, + 0xFB,0xFF,0xEE,0xFF,0x00,0x00,0x02,0x00,0xFC,0xFF,0x09,0x00, + 0xF8,0xFF,0x0B,0x00,0x00,0x00,0x0A,0x00,0x03,0x00,0x01,0x00, + 0x04,0x00,0xFD,0xFF,0x09,0x00,0x03,0x00,0x06,0x00,0x0A,0x00, + 0xF9,0xFF,0x0E,0x00,0x01,0x00,0x08,0x00,0x04,0x00,0x06,0x00, + 0x09,0x00,0xFD,0xFF,0x08,0x00,0x01,0x00,0x01,0x00,0x03,0x00, + 0x05,0x00,0x00,0x00,0x05,0x00,0xF4,0xFF,0xF9,0xFF,0xFC,0xFF, + 0xFC,0xFF,0x04,0x00,0xEF,0xFF,0xFC,0xFF,0xFE,0xFF,0xFB,0xFF, + 0xF4,0xFF,0xF7,0xFF,0xF9,0xFF,0xF2,0xFF,0xF6,0xFF,0xEF,0xFF, + 0xF4,0xFF,0xF4,0xFF,0xF1,0xFF,0xF7,0xFF,0xEF,0xFF,0xED,0xFF, + 0xEF,0xFF,0xF0,0xFF,0xEE,0xFF,0xEF,0xFF,0xEF,0xFF,0xEA,0xFF, + 0xED,0xFF,0xED,0xFF,0xEF,0xFF,0xE8,0xFF,0xED,0xFF,0xEC,0xFF, + 0xF6,0xFF,0xEC,0xFF,0xEE,0xFF,0xE7,0xFF,0xEB,0xFF,0xE9,0xFF, + 0xE4,0xFF,0xE9,0xFF,0xDB,0xFF,0xD7,0xFF,0xDB,0xFF,0xDF,0xFF, + 0xDC,0xFF,0xDA,0xFF,0xD3,0xFF,0xD1,0xFF,0xD1,0xFF,0xCD,0xFF, + 0xCE,0xFF,0xCE,0xFF,0xC8,0xFF,0xD1,0xFF,0xC9,0xFF,0xCC,0xFF, + 0xCA,0xFF,0xD4,0xFF,0xCD,0xFF,0xCD,0xFF,0xCB,0xFF,0xC7,0xFF, + 0xD4,0xFF,0xD0,0xFF,0xD8,0xFF,0xD5,0xFF,0xD9,0xFF,0xCE,0xFF, + 0xD4,0xFF,0xD5,0xFF,0xD1,0xFF,0xDB,0xFF,0xCD,0xFF,0xD9,0xFF, + 0xD9,0xFF,0xD6,0xFF,0xD8,0xFF,0xD4,0xFF,0xD9,0xFF,0xD8,0xFF, + 0xD7,0xFF,0xCE,0xFF,0xD4,0xFF,0xD5,0xFF,0xD3,0xFF,0xD6,0xFF, + 0xD0,0xFF,0xD3,0xFF,0xC9,0xFF,0xCC,0xFF,0xC5,0xFF,0xC7,0xFF, + 0xC6,0xFF,0xBE,0xFF,0xC1,0xFF,0xC9,0xFF,0xC7,0xFF,0xCC,0xFF, + 0xD2,0xFF,0xD0,0xFF,0xDD,0xFF,0xD1,0xFF,0xD5,0xFF,0xCD,0xFF, + 0xDB,0xFF,0xD6,0xFF,0xCF,0xFF,0xD9,0xFF,0xD4,0xFF,0xDD,0xFF, + 0xDF,0xFF,0xDB,0xFF,0xE0,0xFF,0xDE,0xFF,0xD7,0xFF,0xDE,0xFF, + 0xDB,0xFF,0xDF,0xFF,0xD8,0xFF,0xE0,0xFF,0xD4,0xFF,0xDB,0xFF, + 0xDD,0xFF,0xD7,0xFF,0xD8,0xFF,0xD5,0xFF,0xE3,0xFF,0xDC,0xFF, + 0xDF,0xFF,0xD5,0xFF,0xD7,0xFF,0xE4,0xFF,0xD3,0xFF,0xDE,0xFF, + 0xD5,0xFF,0xD7,0xFF,0xD9,0xFF,0xD6,0xFF,0xDD,0xFF,0xDA,0xFF, + 0xDF,0xFF,0xD6,0xFF,0xD3,0xFF,0xD3,0xFF,0xCF,0xFF,0xD9,0xFF, + 0xCF,0xFF,0xD6,0xFF,0xC9,0xFF,0xCF,0xFF,0xC9,0xFF,0xCB,0xFF, + 0xCC,0xFF,0xCA,0xFF,0xC0,0xFF,0xC5,0xFF,0xCC,0xFF,0xCA,0xFF, + 0xC9,0xFF,0xC0,0xFF,0xC9,0xFF,0xBF,0xFF,0xC2,0xFF,0xBB,0xFF, + 0x97,0xFF,0xE8,0xFF,0xFF,0xFF,0xBF,0xFE,0x8E,0xFF,0x70,0xFF, + 0x90,0xFF,0xA5,0xFF,0xC1,0xFF,0xE8,0xFF,0xBE,0xFF,0xE4,0xFF, + 0x87,0xFF,0xE5,0xFF,0xE8,0xFF,0xDD,0xFF,0xF8,0xFF,0xD6,0xFF, + 0xD8,0xFF,0x04,0x00,0xB5,0xFF,0x62,0xFE,0x40,0x00,0xBA,0xFF, + 0x49,0xFF,0x06,0xFF,0xC7,0xFF,0xD2,0xFF,0x63,0xFF,0xBB,0xFF, + 0x62,0xFF,0x73,0xFF,0x0C,0x00,0xA0,0xFF,0xC2,0xFF,0x72,0xFF, + 0xE5,0xFF,0x14,0x00,0x5D,0xFF,0xB6,0xFF,0xCE,0xFF,0xCD,0xFF, + 0xC0,0xFF,0x94,0xFF,0xF5,0xFF,0xA0,0xFF,0xBB,0xFF,0x99,0xFF, + 0x47,0xFF,0xC0,0xFF,0x61,0xFF,0x87,0xFF,0x49,0xFF,0x27,0xFF, + 0x82,0xFF,0x09,0xFF,0x15,0xFF,0x59,0xFF,0x0F,0xFF,0x4C,0xFF, + 0x1A,0xFF,0x2F,0xFF,0x19,0xFF,0x02,0xFF,0x3A,0xFF,0x07,0xFF, + 0x30,0xFF,0x08,0xFF,0x09,0xFF,0x5E,0xFF,0x1D,0xFF,0x3B,0xFF, + 0x45,0xFF,0x36,0xFF,0x7F,0xFF,0x3C,0xFF,0x58,0xFF,0x6F,0xFF, + 0x89,0xFF,0x86,0xFF,0x7E,0xFF,0x9A,0xFF,0xBC,0xFF,0xD5,0xFF, + 0xDC,0xFF,0xCF,0xFF,0x37,0x00,0x12,0x00,0x53,0x00,0x62,0x00, + 0x7B,0x00,0xC0,0x00,0x89,0x00,0xE5,0x00,0x39,0x01,0x5C,0x01, + 0x6D,0x01,0xBF,0x01,0xB1,0x01,0x4C,0x00,0x36,0x01,0xE2,0x01, + 0xF6,0xFF,0x59,0xFF,0x24,0x00,0x5D,0x00,0x09,0xFF,0x93,0xFE, + 0xAB,0xFF,0x17,0xFF,0xB1,0xFE,0xCC,0xFE,0x37,0xFF,0x45,0xFF, + 0x8D,0xFF,0xB5,0xFF,0xAB,0xFF,0x17,0x00,0x0C,0x01,0x4B,0x00, + 0x45,0x00,0x21,0x01,0xDA,0x00,0xF4,0xFF,0x0C,0x00,0x93,0x00, + 0xFC,0xFF,0x7F,0xFF,0x9E,0xFF,0xC9,0xFF,0x82,0xFF,0x9A,0xFF, + 0xA1,0xFF,0xCB,0xFF,0x15,0x00,0x59,0x00,0x22,0x00,0xAA,0x00, + 0x22,0x01,0x25,0x01,0xF8,0x00,0x8D,0x01,0xE5,0x01,0x95,0x01, + 0xD8,0x01,0x26,0x02,0x44,0x02,0x7C,0x02,0x1D,0x03,0x5C,0x03, + 0xD1,0x03,0xF7,0x03,0x7F,0x02,0xC4,0x00,0xD3,0x04,0x04,0x02, + 0xA6,0xFE,0x6E,0x00,0x39,0x02,0x0D,0x00,0x22,0xFD,0x8F,0x00, + 0x03,0xFF,0xAC,0xFD,0x47,0xFE,0x29,0xFF,0x29,0xFF,0x47,0xFF, + 0x84,0xFF,0xD5,0xFF,0x72,0x00,0x50,0x02,0x7B,0x00,0x27,0x01, + 0x71,0x02,0x7F,0x02,0xE1,0x00,0xE6,0x00,0xAB,0x02,0x84,0x01, + 0x0D,0x00,0xCE,0x00,0x83,0x00,0xF3,0xFF,0x89,0xFF,0x85,0xFF, + 0x16,0xFE,0x50,0xFE,0xA9,0xFF,0x82,0xFD,0x2C,0xFE,0xE7,0xFE, + 0x7B,0xFF,0x15,0xFE,0x15,0xFF,0x2F,0x00,0x28,0xFF,0x4C,0xFF, + 0x2F,0x00,0x4C,0x00,0x2F,0x00,0x85,0x00,0xDD,0x00,0xE1,0x00, + 0x42,0x01,0x81,0x01,0xAB,0x00,0x25,0x02,0x2E,0x02,0xB1,0x01, + 0x62,0x02,0x9C,0x03,0x3D,0x03,0xF9,0x02,0x40,0x03,0x20,0x00, + 0x04,0x04,0x94,0x01,0xFA,0xFD,0x5F,0xFF,0x4D,0x01,0x26,0xFE, + 0xB5,0xFB,0x64,0xFF,0x64,0xFF,0x34,0xFB,0x47,0xFD,0x26,0xFE, + 0x3C,0xFE,0x55,0xFD,0x7A,0xFE,0x34,0xFF,0x38,0xFF,0xFC,0x00, + 0x32,0xFF,0x41,0x01,0x8C,0x01,0x4D,0x01,0x1D,0x00,0x6B,0x01, + 0xBF,0x01,0x03,0x00,0x57,0xFF,0x58,0x00,0x11,0xFF,0x91,0xFE, + 0x37,0xFE,0x98,0xFE,0x06,0xFE,0x8E,0xFC,0x79,0xFD,0x8B,0xFD, + 0xA9,0xFD,0xA1,0xFC,0xE1,0xFD,0x11,0xFE,0xB6,0xFD,0xA3,0xFD, + 0x7B,0xFE,0x2A,0xFF,0xB3,0xFE,0x4D,0xFE,0x29,0xFF,0x9F,0xFF, + 0x65,0xFF,0x5C,0xFF,0xFF,0xFF,0xA4,0x00,0xDF,0xFF,0x45,0x00, + 0xB6,0x00,0x4A,0x01,0x17,0x01,0x48,0x01,0xF1,0x01,0x51,0x02, + 0x2E,0x03,0xF3,0x02,0xB5,0xFF,0xE2,0x00,0xB4,0x03,0x95,0xFC, + 0x95,0xFD,0x17,0x01,0x6B,0xFE,0xBC,0xFA,0x66,0xFC,0xE2,0xFF, + 0xA3,0xFA,0xCA,0xFC,0x48,0xFD,0x9F,0xFD,0xEC,0xFC,0xE4,0xFD, + 0x7C,0xFE,0x6E,0xFF,0xA0,0x00,0x44,0xFF,0x8F,0xFF,0xAD,0x02, + 0xFE,0x00,0x0F,0x00,0x13,0x01,0xFE,0x01,0xCA,0xFF,0x2C,0xFF, + 0xE0,0x00,0x55,0xFF,0x8F,0xFE,0x78,0xFE,0xAC,0xFE,0x43,0xFE, + 0xB4,0xFD,0xCB,0xFD,0x09,0xFE,0xCD,0xFD,0x04,0xFE,0x8A,0xFD, + 0x9C,0xFD,0x66,0xFE,0x44,0xFE,0x36,0xFE,0x21,0xFF,0x7A,0xFF, + 0x7A,0xFE,0x05,0xFF,0x99,0xFF,0x77,0xFF,0x20,0xFF,0xC4,0xFF, + 0x2A,0x00,0x06,0x00,0x26,0x00,0x93,0x00,0x1D,0x01,0x2C,0x01, + 0x28,0x01,0xD2,0x01,0x85,0x02,0xA9,0x02,0x65,0x02,0x77,0x03, + 0x6E,0x03,0x39,0x03,0xA1,0xFE,0x53,0x05,0xC8,0xFF,0xE6,0xFC, + 0xEA,0xFF,0x0A,0x01,0x93,0xFC,0x66,0xFB,0xF6,0xFE,0xF3,0xFD, + 0x7F,0xFB,0x39,0xFE,0xAE,0xFD,0xA9,0xFE,0x09,0xFE,0xF6,0xFE, + 0xF6,0xFF,0xAE,0x00,0xE6,0x00,0xE3,0xFF,0xAF,0x02,0xE4,0x01, + 0xB1,0x00,0x6A,0x01,0xAD,0x02,0xE7,0x00,0x85,0xFF,0x17,0x01, + 0xCB,0x00,0xCB,0xFE,0xB7,0xFE,0x0A,0xFF,0x14,0xFF,0x27,0xFE, + 0x28,0xFE,0x9B,0xFE,0xE7,0xFE,0x5B,0xFE,0x75,0xFD,0x77,0x00, + 0x7C,0xFE,0x4C,0xFD,0x30,0xFF,0xBB,0xFF,0xAB,0xFE,0x71,0xFE, + 0x80,0x00,0xAD,0xFE,0xAD,0xFE,0xA6,0xFF,0xFA,0xFF,0x94,0xFF, + 0x69,0xFF,0x15,0x00,0x42,0x00,0x88,0x00,0xB5,0x00,0xDF,0x00, + 0xD3,0x01,0x30,0x01,0xD5,0x01,0x82,0x02,0xAD,0x02,0xBE,0x02, + 0x05,0x03,0x92,0x03,0x12,0x01,0x2A,0x00,0x5E,0x04,0x6C,0xFE, + 0xE4,0xFD,0x89,0x00,0x23,0xFF,0x64,0xFC,0x6A,0xFD,0x48,0x00, + 0x77,0xFB,0x5E,0xFC,0x19,0xFE,0xA8,0xFE,0xA8,0xFD,0x53,0xFE, + 0xB6,0xFF,0xF3,0xFF,0xCD,0x00,0xB8,0x00,0x20,0x01,0xC1,0x02, + 0x1E,0x01,0x29,0x01,0xCA,0x01,0xFD,0x01,0xCE,0xFF,0x21,0x00, + 0x2B,0x01,0x41,0xFF,0xE7,0xFE,0x1D,0xFF,0x89,0xFF,0x0D,0xFE, + 0x7E,0xFE,0xBB,0xFE,0xB6,0xFE,0xAF,0xFE,0xBF,0xFE,0x69,0xFE, + 0xF9,0xFE,0x3E,0x00,0x13,0xFE,0x21,0xFF,0x32,0x00,0x5D,0xFF, + 0xC8,0xFE,0x36,0x00,0x51,0x00,0x6B,0xFE,0x97,0xFF,0xFA,0xFF, + 0xB3,0xFF,0xB8,0xFF,0x64,0x00,0x76,0x00,0x4B,0x00,0xC7,0x00, + 0xF6,0x00,0x6C,0x01,0xB6,0x01,0x56,0x01,0x2D,0x02,0x9F,0x02, + 0x8A,0x02,0xB9,0x02,0x7A,0x03,0x2F,0x03,0xB5,0x00,0x0C,0x01, + 0x9C,0x04,0x66,0xFD,0x8E,0xFF,0x46,0x01,0xB5,0xFF,0x97,0xFB, + 0xB7,0xFF,0xD9,0x00,0xDF,0xFB,0xE4,0xFD,0x15,0xFF,0x47,0xFF, + 0x41,0xFD,0xBD,0xFF,0x31,0x00,0xD3,0xFF,0x7B,0x00,0xA9,0x00, + 0x1F,0x02,0x07,0x02,0x26,0x01,0x7E,0x01,0x65,0x02,0xED,0x01, + 0xF9,0xFF,0x71,0x01,0xDF,0x00,0x9A,0xFF,0x38,0xFF,0xF6,0xFF, + 0x28,0xFF,0x03,0xFE,0xF7,0xFE,0x1F,0xFF,0x91,0xFE,0x59,0xFE, + 0x2F,0xFF,0x65,0xFF,0x26,0xFE,0x16,0xFF,0x39,0x00,0x86,0xFE, + 0xE5,0xFE,0xDF,0xFF,0xAD,0xFF,0xF7,0xFE,0x05,0x00,0xD3,0xFF, + 0x0F,0xFF,0x8E,0xFF,0xC4,0xFF,0x89,0xFF,0x89,0xFF,0x2D,0x00, + 0x0D,0x00,0x14,0x00,0x6A,0x00,0xA1,0x00,0xCF,0x00,0xCC,0x00, + 0x12,0x01,0x5B,0x01,0xBA,0x01,0xD3,0x01,0x24,0x02,0x7D,0x02, + 0x8C,0x02,0x96,0x01,0xB7,0xFF,0x25,0x03,0x1D,0x00,0x8C,0xFE, + 0xEC,0xFF,0x48,0x01,0x56,0xFD,0x6E,0xFD,0x35,0x00,0x65,0xFE, + 0x11,0xFC,0xC1,0xFE,0x60,0xFF,0xB2,0xFD,0x55,0xFD,0x82,0x00, + 0x05,0xFF,0x03,0xFF,0x33,0x00,0x59,0x01,0x92,0x00,0x60,0x00, + 0xBF,0x01,0x38,0x01,0x58,0x01,0x93,0x00,0x45,0x01,0xC3,0x00, + 0x33,0x00,0xB3,0xFF,0xD8,0xFF,0xDB,0xFF,0x8D,0xFE,0xD6,0xFE, + 0x38,0xFF,0xBF,0xFE,0x36,0xFE,0xB3,0xFE,0x37,0xFF,0x64,0xFE, + 0xBF,0xFE,0x6B,0xFF,0xD4,0xFE,0xAE,0xFE,0x5D,0xFF,0xD8,0xFF, + 0xF8,0xFE,0x86,0xFF,0xDE,0xFF,0xA8,0xFF,0x76,0xFF,0xEC,0xFF, + 0x14,0x00,0xC5,0xFF,0x08,0x00,0x18,0x00,0x59,0x00,0x3F,0x00, + 0x5D,0x00,0x8F,0x00,0xB5,0x00,0xC7,0x00,0xCC,0x00,0x32,0x01, + 0x52,0x01,0x7A,0x01,0x9A,0x01,0x21,0x02,0xD9,0x01,0x0F,0x02, + 0x92,0x01,0xB7,0x00,0xAC,0x02,0xAC,0xFF,0x13,0x00,0x87,0x00, + 0xA2,0x00,0xC7,0xFD,0xC9,0xFE,0x3F,0x00,0xD8,0xFD,0x0A,0xFE, + 0xE0,0xFE,0x8A,0xFF,0x2A,0xFD,0x67,0xFF,0xFA,0xFF,0x1A,0xFF, + 0xE8,0xFE,0xE1,0x00,0xF3,0x00,0xA5,0xFF,0x04,0x01,0x75,0x01, + 0xEB,0x00,0x9D,0x00,0xA4,0x01,0x29,0x01,0x97,0x00,0xE2,0x00, + 0xDB,0x00,0x52,0x00,0xD4,0xFF,0x28,0x00,0xBC,0xFF,0x6B,0xFF, + 0x27,0xFF,0x43,0xFF,0x23,0xFF,0xF1,0xFE,0x0C,0xFF,0xF1,0xFE, + 0xB0,0xFE,0x48,0xFF,0xF8,0xFE,0xD5,0xFE,0x46,0xFF,0xBC,0xFF, + 0x16,0xFF,0x61,0xFF,0x08,0x00,0xD2,0xFF,0x8C,0xFF,0x0F,0x00, + 0x60,0x00,0xCC,0xFF,0x15,0x00,0x7A,0x00,0x48,0x00,0xF3,0xFF, + 0x80,0x00,0x93,0x00,0x0F,0x00,0x5B,0x00,0x8F,0x00,0x56,0x00, + 0x47,0x00,0xAE,0x00,0xB3,0x00,0x7B,0x00,0xE2,0x00,0x24,0x01, + 0x15,0x01,0xC5,0x00,0x6B,0x00,0x19,0x01,0xB2,0x00,0xE7,0xFF, + 0xE8,0xFF,0xFB,0x00,0xCA,0xFF,0xFE,0xFE,0x07,0x00,0xF9,0xFF, + 0x90,0xFE,0xB8,0xFE,0xE7,0xFF,0xD5,0xFE,0x02,0xFE,0x65,0xFF, + 0x7D,0xFF,0x81,0xFE,0xC3,0xFE,0x21,0x00,0x77,0xFF,0xF0,0xFE, + 0x04,0x00,0x6C,0x00,0xA1,0xFF,0xC0,0xFF,0xC5,0x00,0x14,0x00, + 0xBF,0xFF,0x4A,0x00,0x93,0x00,0x95,0xFF,0xF1,0xFF,0x2B,0x00, + 0xBE,0xFF,0x1A,0xFF,0xB8,0xFF,0x9A,0xFF,0xFE,0xFE,0xFD,0xFE, + 0x54,0xFF,0x1D,0xFF,0x97,0xFE,0x13,0xFF,0x0A,0xFF,0xD8,0xFE, + 0xD9,0xFE,0x4E,0xFF,0x3B,0xFF,0x0C,0xFF,0x56,0xFF,0x79,0xFF, + 0x52,0xFF,0x5F,0xFF,0x90,0xFF,0x97,0xFF,0x78,0xFF,0x87,0xFF, + 0xAA,0xFF,0x85,0xFF,0x8D,0xFF,0x8E,0xFF,0xAC,0xFF,0x72,0xFF, + 0x92,0xFF,0x8D,0xFF,0xA3,0xFF,0x6D,0xFF,0x9A,0xFF,0x8D,0xFF, + 0xA0,0xFF,0x81,0xFF,0xBB,0xFF,0x9E,0xFF,0x96,0xFF,0xA6,0xFF, + 0xCC,0xFF,0xC2,0xFF,0xB5,0xFF,0xF1,0xFF,0xF2,0xFF,0xCC,0xFF, + 0xE0,0xFF,0x08,0x00,0xE6,0xFF,0xDC,0xFF,0xFF,0xFF,0xF2,0xFF, + 0xD9,0xFF,0xBE,0xFF,0xE3,0xFF,0xCE,0xFF,0xB9,0xFF,0xC7,0xFF, + 0xCE,0xFF,0xAB,0xFF,0xA5,0xFF,0x91,0xFF,0xAA,0xFF,0x72,0xFF, + 0x9E,0xFF,0x79,0xFF,0x74,0xFF,0x79,0xFF,0x72,0xFF,0x76,0xFF, + 0x74,0xFF,0x77,0xFF,0x75,0xFF,0x80,0xFF,0x8A,0xFF,0x9C,0xFF, + 0x92,0xFF,0xAE,0xFF,0xBE,0xFF,0xCA,0xFF,0xA8,0xFF,0xCE,0xFF, + 0xD7,0xFF,0xD5,0xFF,0xBF,0xFF,0xD8,0xFF,0xDD,0xFF,0xDA,0xFF, + 0xC8,0xFF,0xDB,0xFF,0xD1,0xFF,0xC7,0xFF,0xC4,0xFF,0xDC,0xFF, + 0xB5,0xFF,0xB2,0xFF,0xCC,0xFF,0xCC,0xFF,0xB4,0xFF,0xC4,0xFF, + 0xD7,0xFF,0xBF,0xFF,0xC3,0xFF,0xCD,0xFF,0xE9,0xFF,0xDD,0xFF, + 0xDA,0xFF,0xE7,0xFF,0xE9,0xFF,0xED,0xFF,0xD9,0xFF,0xF6,0xFF, + 0xF1,0xFF,0xF2,0xFF,0xDA,0xFF,0x00,0x00,0xE8,0xFF,0xF5,0xFF, + 0xE2,0xFF,0xEE,0xFF,0xD5,0xFF,0xE2,0xFF,0xCD,0xFF,0xD8,0xFF, + 0xCC,0xFF,0xD7,0xFF,0xCB,0xFF,0xD6,0xFF,0xD5,0xFF,0xC0,0xFF, + 0xD5,0xFF,0xD7,0xFF,0xE0,0xFF,0xD5,0xFF,0xE8,0xFF,0xE4,0xFF, + 0xE7,0xFF,0xE6,0xFF,0xEC,0xFF,0xF4,0xFF,0xEB,0xFF,0xE2,0xFF, + 0xF6,0xFF,0xE6,0xFF,0xF2,0xFF,0xF7,0xFF,0x00,0x00,0x01,0x00, + 0xFB,0xFF,0xEE,0xFF,0xEC,0xFF,0x08,0x00,0xF0,0xFF,0xEE,0xFF, + 0xEF,0xFF,0xF7,0xFF,0xEC,0xFF,0xF7,0xFF,0xED,0xFF,0xEF,0xFF, + 0xEF,0xFF,0xF9,0xFF,0xE3,0xFF,0xDA,0xFF,0xF6,0xFF,0xF1,0xFF, + 0xE3,0xFF,0xDD,0xFF,0xF1,0xFF,0xF0,0xFF,0xE8,0xFF,0xD5,0xFF, + 0xF7,0xFF,0xEE,0xFF,0xE8,0xFF,0xD5,0xFF,0xF3,0xFF,0xE6,0xFF, + 0xF9,0xFF,0xD4,0xFF,0x09,0x00,0xD6,0xFF,0xF3,0xFF,0xE6,0xFF, + 0xF6,0xFF,0xE4,0xFF,0xE1,0xFF,0xF1,0xFF,0xF1,0xFF,0xEE,0xFF, + 0xE2,0xFF,0xF6,0xFF,0xF7,0xFF,0xE4,0xFF,0xE9,0xFF,0xF7,0xFF, + 0xED,0xFF,0xDF,0xFF,0xE6,0xFF,0xFA,0xFF,0xE2,0xFF,0xF9,0xFF, + 0xFB,0xFF,0xE9,0xFF,0xE0,0xFF,0xF9,0xFF,0xFF,0xFF,0xF5,0xFF, + 0xE7,0xFF,0xFC,0xFF,0xEC,0xFF,0xEE,0xFF,0xE6,0xFF,0x00,0x00, + 0xF2,0xFF,0xE2,0xFF,0xF6,0xFF,0xF3,0xFF,0xF3,0xFF,0xEB,0xFF, + 0xEF,0xFF,0xE9,0xFF,0x01,0x00,0xEC,0xFF,0xF9,0xFF,0xEC,0xFF, + 0x0F,0x00,0xDC,0xFF,0x02,0x00,0xDF,0xFF,0xFE,0xFF,0xE6,0xFF, + 0x07,0x00,0xCD,0xFF,0x17,0x00,0xDD,0xFF,0xFC,0xFF,0xEC,0xFF, + 0x0C,0x00,0xE5,0xFF,0xFB,0xFF,0xF4,0xFF,0x17,0x00,0xEE,0xFF, + 0x1F,0x00,0xE6,0xFF,0x1C,0x00,0xFF,0xFF,0x19,0x00,0xF5,0xFF, + 0x1E,0x00,0x14,0x00,0x18,0x00,0xFD,0xFF,0x1E,0x00,0x1A,0x00, + 0x29,0x00,0x16,0x00,0x13,0x00,0x28,0x00,0x22,0x00,0x0E,0x00, + 0x1D,0x00,0x31,0x00,0x2D,0x00,0x0F,0x00,0x25,0x00,0x2C,0x00, + 0x2D,0x00,0x22,0x00,0x2E,0x00,0x2B,0x00,0x3D,0x00,0x2A,0x00, + 0x26,0x00,0x32,0x00,0x2E,0x00,0x30,0x00,0x19,0x00,0x2D,0x00, + 0x20,0x00,0x35,0x00,0x24,0x00,0x26,0x00,0x17,0x00,0x2D,0x00, + 0x2E,0x00,0x12,0x00,0x24,0x00,0x39,0x00,0x30,0x00,0x24,0x00, + 0x25,0x00,0x37,0x00,0x25,0x00,0x1E,0x00,0x28,0x00,0x1C,0x00, + 0x2F,0x00,0x13,0x00,0x37,0x00,0x14,0x00,0x2B,0x00,0x21,0x00, + 0x47,0x00,0x0E,0x00,0x1F,0x00,0x2D,0x00,0x45,0x00,0x29,0x00, + 0x1D,0x00,0x28,0x00,0x21,0x00,0x30,0x00,0x2E,0x00,0x34,0x00, + 0x16,0x00,0x29,0x00,0x22,0x00,0x16,0x00,0x09,0x00,0x37,0x00, + 0x13,0x00,0x1E,0x00,0x05,0x00,0x25,0x00,0x03,0x00,0x0D,0x00, + 0xFB,0xFF,0x14,0x00,0x17,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00, + 0x00,0x00,0x19,0x00,0x1B,0x00,0x12,0x00,0x07,0x00,0xFD,0xFF, + 0x06,0x00,0x21,0x00,0x13,0x00,0xFD,0xFF,0xFC,0xFF,0xFE,0xFF, + 0x04,0x00,0x02,0x00,0x34,0x00,0x21,0x00,0x10,0x00,0xE2,0xFF, + 0x0B,0x00,0x2D,0x00,0x16,0x00,0xEA,0xFF,0x12,0x00,0x55,0x00, + 0x2B,0x00,0xFF,0xFF,0x26,0x00,0x36,0x00,0x10,0x00,0x23,0x00, + 0x46,0x00,0x31,0x00,0x06,0x00,0x20,0x00,0x07,0x00,0x40,0x00, + 0xEB,0xFF,0x21,0x00,0x10,0x00,0xF9,0xFF,0xFD,0xFF,0xF8,0xFF, + 0x14,0x00,0x08,0x00,0xFC,0xFF,0xFD,0xFF,0x0C,0x00,0xFF,0xFF, + 0x06,0x00,0x1C,0x00,0x19,0x00,0x19,0x00,0x25,0x00,0x25,0x00, + 0x18,0x00,0x1D,0x00,0x15,0x00,0x28,0x00,0x1E,0x00,0x29,0x00, + 0xFA,0xFF,0x22,0x00,0x3E,0x00,0x1D,0x00,0x0F,0x00,0x18,0x00, + 0x15,0x00,0xEE,0xFF,0x2F,0x00,0x13,0x00,0x0F,0x00,0x06,0x00, + 0xEC,0xFF,0x09,0x00,0xF1,0xFF,0x05,0x00,0xF9,0xFF,0x16,0x00, + 0xD0,0xFF,0xEB,0xFF,0xCA,0xFF,0xF3,0xFF,0xD5,0xFF,0xF2,0xFF, + 0xF2,0xFF,0xC1,0xFF,0xE8,0xFF,0xD7,0xFF,0xCF,0xFF,0xBC,0xFF, + 0xE6,0xFF,0xBE,0xFF,0xD5,0xFF,0xBC,0xFF,0xC0,0xFF,0xB1,0xFF, + 0xC9,0xFF,0xC9,0xFF,0xB4,0xFF,0xBC,0xFF,0xA8,0xFF,0xBE,0xFF, + 0x8C,0xFF,0xAC,0xFF,0xA2,0xFF,0x9A,0xFF,0x99,0xFF,0x8D,0xFF, + 0x90,0xFF,0x88,0xFF,0x83,0xFF,0x69,0xFF,0x8E,0xFF,0x74,0xFF, + 0x78,0xFF,0x79,0xFF,0x8E,0xFF,0x83,0xFF,0x61,0xFF,0x7E,0xFF, + 0x62,0xFF,0x74,0xFF,0x53,0xFF,0x7A,0xFF,0x7C,0xFF,0x53,0xFF, + 0x5F,0xFF,0x6B,0xFF,0x3C,0xFF,0x4E,0xFF,0x24,0xFF,0x91,0xFF, + 0x6C,0xFF,0x6C,0xFF,0x5A,0xFF,0x70,0xFF,0x69,0xFF,0x82,0xFF, + 0x5C,0xFF,0x87,0xFF,0x5A,0xFF,0x5F,0xFF,0x8C,0xFF,0x55,0xFF, + 0x8D,0xFF,0x80,0xFF,0x7A,0xFF,0x5E,0xFF,0x64,0xFF,0x59,0xFF, + 0x62,0xFF,0x88,0xFF,0x65,0xFF,0x9B,0xFF,0x8D,0xFF,0x85,0xFF, + 0x76,0xFF,0x39,0xFF,0x70,0xFF,0xAF,0xFF,0xAB,0xFF,0x87,0xFF, + 0xAD,0xFF,0x49,0xFF,0x9A,0xFF,0x80,0xFF,0xA8,0xFF,0x60,0xFF, + 0x8F,0xFF,0x92,0xFF,0xAA,0xFF,0x68,0xFF,0x8E,0xFF,0x77,0xFF, + 0x19,0xFF,0xAB,0xFF,0x49,0xFF,0xAF,0xFF,0x72,0xFF,0xC7,0xFF, + 0x88,0xFF,0x52,0xFF,0x88,0xFF,0xED,0xFF,0xBE,0xFF,0xBE,0xFF, + 0xAC,0xFF,0xB6,0xFF,0xD3,0xFF,0xD7,0xFF,0xDC,0xFF,0x5E,0xFF, + 0xE9,0xFF,0xAA,0xFF,0x09,0x00,0xAA,0xFF,0x0D,0x00,0x30,0x00, + 0xB4,0xFF,0xD5,0xFF,0xC7,0xFF,0xE4,0xFF,0xE5,0xFF,0xE5,0xFF, + 0xB3,0xFF,0xEA,0xFF,0x21,0x00,0xAC,0xFF,0x23,0x00,0xB9,0xFF, + 0xDE,0xFF,0xC5,0xFF,0xD0,0xFF,0xFF,0xFF,0xDF,0xFF,0x1E,0x00, + 0xA6,0xFF,0xFC,0xFF,0x05,0x00,0xFF,0xFF,0xB9,0xFF,0xAF,0xFF, + 0xB3,0xFF,0x86,0xFF,0x00,0x00,0x3F,0x00,0xE5,0xFF,0x33,0x00, + 0x9C,0xFF,0xF7,0xFF,0xFC,0xFF,0x1D,0x00,0xD8,0xFF,0xBC,0xFF, + 0xD8,0xFF,0x15,0x00,0xF1,0xFF,0xC4,0xFF,0x0E,0x00,0x67,0xFF, + 0x06,0x00,0xE1,0xFF,0xC2,0xFF,0x07,0x00,0xAD,0xFF,0x0C,0x00, + 0x03,0x00,0xE1,0xFF,0x87,0xFF,0xE7,0xFF,0xB3,0xFF,0xEF,0xFF, + 0x71,0xFF,0x58,0x00,0xB8,0xFF,0xE5,0xFF,0x92,0x00,0xDB,0xFF, + 0xB1,0xFF,0xD8,0xFF,0x25,0x00,0xDB,0xFF,0xD8,0xFF,0xF8,0xFF, + 0x00,0x00,0x13,0x00,0x98,0xFF,0xBC,0xFF,0x0B,0x00,0x00,0x00, + 0xED,0xFF,0x0C,0x00,0x0F,0x00,0xFE,0xFF,0xC7,0xFF,0x54,0x00, + 0x81,0xFF,0xCE,0xFF,0xE3,0xFF,0x05,0x00,0xD1,0xFF,0xCB,0xFF, + 0xCA,0xFF,0x4B,0x00,0xD1,0xFF,0x09,0x00,0xD7,0xFF,0x97,0xFF, + 0x3A,0x00,0x01,0x00,0xD8,0xFF,0xE3,0xFF,0xE7,0xFF,0xF1,0xFF, + 0xC8,0xFF,0xE9,0xFF,0xFD,0xFF,0xB4,0xFF,0x94,0xFF,0xCF,0xFF, + 0xEC,0xFF,0xC3,0xFF,0xF9,0xFF,0xB9,0xFF,0xCC,0xFF,0x0F,0x00, + 0xFE,0xFF,0xC8,0xFF,0xFD,0xFF,0x0B,0x00,0x01,0x00,0xEB,0xFF, + 0xF0,0xFF,0xAE,0xFF,0xF9,0xFF,0x1B,0x00,0x19,0x00,0x2E,0x00, + 0x19,0x00,0xDF,0xFF,0xE1,0xFF,0x20,0x00,0x06,0x00,0xEE,0xFF, + 0x22,0x00,0x1A,0x00,0x2F,0x00,0xBB,0xFF,0x3A,0x00,0xE8,0xFF, + 0xDF,0xFF,0x26,0x00,0x29,0x00,0x37,0x00,0x1C,0x00,0xE1,0xFF, + 0x18,0x00,0x0F,0x00,0xF8,0xFF,0x66,0x00,0xC3,0xFF,0xD6,0xFF, + 0x25,0x00,0x08,0x00,0x1C,0x00,0x10,0x00,0xDE,0xFF,0xEE,0xFF, + 0x5D,0x00,0x04,0x00,0x4B,0x00,0x6F,0x00,0x91,0xFF,0x57,0xFF, + 0x72,0xFF,0xB9,0xFF,0x10,0x00,0xF7,0xFF,0xCD,0xFF,0x25,0x00, + 0x36,0x00,0xC7,0xFF,0xA7,0xFF,0xB7,0xFF,0x44,0x00,0x0F,0x00, + 0xE2,0xFF,0xEE,0xFF,0x96,0xFF,0xED,0xFF,0xB7,0xFF,0xDB,0xFF, + 0xD2,0xFF,0x2C,0x00,0x15,0x00,0xCE,0xFF,0x47,0x00,0xFF,0xFF, + 0xA9,0xFF,0xCD,0xFF,0xFD,0xFF,0xAE,0xFF,0xEC,0xFF,0x36,0x00, + 0xBF,0xFF,0x91,0xFF,0x50,0xFF,0x3B,0xFF,0x90,0xFF,0x0A,0x00, + 0x35,0x00,0x60,0xFF,0xC0,0xFF,0xDA,0xFF,0xDD,0xFF,0x11,0x00, + 0xB3,0xFF,0x04,0x00,0x1B,0x00,0xED,0xFF,0xD4,0xFF,0x77,0xFF, + 0x72,0xFF,0x93,0xFF,0xA1,0xFF,0xAC,0xFF,0x3C,0x00,0x34,0x00, + 0xFB,0xFF,0x39,0x00,0xC3,0xFF,0x9A,0xFF,0xC2,0xFF,0xEC,0xFF, + 0xA7,0xFF,0xE6,0xFF,0x0E,0x00,0x36,0x00,0xFF,0xFF,0xBA,0xFF, + 0xC6,0xFF,0xC1,0xFF,0xC9,0xFF,0x04,0x00,0x1C,0x00,0x58,0x00, + 0xD5,0xFF,0x67,0xFF,0x13,0x00,0x50,0x00,0xE8,0xFF,0x9F,0xFF, + 0x39,0x00,0x1E,0x00,0x7D,0xFF,0x9E,0xFF,0xAC,0x00,0x1A,0x00, + 0xB5,0xFF,0x2A,0x00,0x1B,0x00,0xD0,0xFF,0xD4,0xFF,0xFE,0xFF, + 0xE2,0xFF,0xE3,0xFF,0x07,0x00,0xEE,0xFF,0x14,0x00,0x29,0x00, + 0xFF,0xFF,0xBC,0xFF,0x0F,0x00,0xF2,0xFF,0x9A,0xFF,0x5B,0x00, + 0x3F,0x00,0xC2,0xFF,0x9F,0xFF,0x11,0x00,0x61,0x00,0x59,0x00, + 0xD3,0xFF,0x02,0x00,0xE4,0xFF,0xD3,0xFF,0xD7,0xFF,0x04,0x00, + 0x6B,0x00,0x00,0x00,0xD3,0xFF,0xFF,0xFF,0xFB,0xFF,0x37,0x00, + 0xC8,0xFF,0xCE,0xFF,0xCF,0xFF,0x4F,0x00,0x19,0x00,0xD5,0xFF, + 0xDB,0xFF,0xF3,0xFF,0xD7,0xFF,0x96,0xFF,0xCB,0xFF,0x6B,0xFF, + 0xBD,0xFF,0x11,0x00,0xF9,0xFF,0xCB,0xFF,0xFC,0xFF,0x9A,0xFF, + 0xBE,0xFF,0xCE,0xFF,0xFD,0xFF,0xF5,0xFF,0x41,0x00,0x67,0x00, + 0xCF,0xFF,0x5F,0xFF,0x64,0x00,0xCC,0xFF,0x59,0x00,0xA8,0xFF, + 0x56,0x00,0xB6,0xFF,0xF3,0xFF,0xC8,0xFF,0xED,0xFF,0xFB,0xFF, + 0x14,0x00,0xCD,0xFF,0xE9,0xFF,0xD5,0xFF,0x2D,0x00,0xC0,0xFF, + 0xBA,0xFF,0xAB,0xFF,0xB0,0xFF,0xFF,0xFF,0xD1,0xFF,0xBE,0xFF, + 0xA5,0xFF,0x44,0x00,0x90,0xFF,0x9F,0xFF,0x1F,0x00,0xD7,0xFF, + 0x14,0x00,0x09,0x00,0xBD,0xFF,0xB1,0xFF,0xB6,0x00,0xFB,0xFF, + 0xB6,0xFF,0x40,0x00,0xC8,0xFF,0xDF,0xFF,0x81,0xFF,0xFE,0xFF, + 0xEA,0xFF,0x48,0x00,0x54,0x00,0xF9,0xFF,0xF7,0xFF,0xCE,0xFF, + 0x65,0x00,0x87,0x00,0xD9,0xFF,0x95,0xFF,0xF0,0xFF,0x69,0x00, + 0x12,0x00,0x91,0xFF,0x7E,0x00,0xF6,0xFF,0xF4,0xFF,0x88,0x00, + 0x8B,0xFF,0x4C,0x00,0x6F,0x00,0x19,0x00,0x3F,0x00,0x3A,0x00, + 0x17,0x00,0xF6,0xFF,0x12,0x00,0x85,0x00,0x04,0x00,0x38,0x00, + 0xB7,0xFF,0x36,0x00,0x58,0x00,0x5C,0x00,0x67,0x00,0x0B,0x00, + 0x58,0x00,0x71,0x00,0x66,0x00,0x3D,0x00,0x56,0x00,0x6B,0x00, + 0x7A,0x00,0x51,0x00,0x69,0x00,0x70,0x00,0x7F,0x00,0x61,0x00, + 0x54,0x00,0x45,0x00,0x56,0x00,0x53,0x00,0x4A,0x00,0x3D,0x00, + 0x28,0x00,0x28,0x00,0x67,0x00,0x75,0x00,0x62,0x00,0x03,0x00, + 0x36,0x00,0x65,0x00,0x75,0x00,0x5A,0x00,0x14,0x00,0x09,0x00, + 0x1E,0x00,0x18,0x00,0x3C,0x00,0x2A,0x00,0x1A,0x00,0x0B,0x00, + 0x00,0x00,0x28,0x00,0x2C,0x00,0x1D,0x00,0xF5,0xFF,0xF8,0xFF, + 0x08,0x00,0x2D,0x00,0x06,0x00,0xFC,0xFF,0xF7,0xFF,0x03,0x00, + 0x08,0x00,0x07,0x00,0x00,0x00,0x25,0x00,0x31,0x00,0x1B,0x00, + 0xFE,0xFF,0x11,0x00,0x23,0x00,0x26,0x00,0x14,0x00,0x0A,0x00, + 0x18,0x00,0x0B,0x00,0x20,0x00,0x24,0x00,0x06,0x00,0x00,0x00, + 0x01,0x00,0xF9,0xFF,0xE3,0xFF,0xE4,0xFF,0xC6,0xFF,0xBA,0xFF, + 0xA6,0xFF,0xA0,0xFF,0x73,0xFF,0x66,0xFF,0x3F,0xFF,0x3B,0xFF, + 0x38,0xFF,0x2C,0xFF,0x1E,0xFF,0x32,0xFF,0x40,0xFF,0x39,0xFF, + 0x39,0xFF,0x5A,0xFF,0x72,0xFF,0x86,0xFF,0x81,0xFF,0x9E,0xFF, + 0xBA,0xFF,0xE3,0xFF,0x04,0x00,0x26,0x00,0x1C,0x00,0x26,0x00, + 0x26,0x00,0x5F,0x00,0x71,0x00,0x3C,0x00,0x50,0x00,0x8F,0x00, + 0xCF,0x00,0xE2,0x00,0xFA,0x00,0x2A,0x01,0x79,0x01,0x88,0x01, + 0x86,0x01,0xC0,0x00,0xE8,0xFE,0xFC,0xFE,0x85,0xFF,0x05,0x00, + 0xBD,0xFE,0x77,0xFD,0xCE,0xFD,0x64,0xFF,0x8E,0xFF,0xBE,0xFE, + 0x23,0xFE,0xFA,0xFE,0x26,0x00,0x20,0x00,0xB5,0xFF,0xA1,0xFF, + 0xE4,0xFF,0x58,0x00,0x03,0x00,0xFE,0xFF,0xD3,0xFF,0x84,0xFF, + 0x4E,0xFF,0x53,0xFF,0x9E,0xFF,0x9D,0xFF,0xF2,0xFE,0xF7,0xFE, + 0x66,0xFF,0x05,0x00,0xDE,0xFF,0x7C,0xFF,0x6D,0xFF,0xF8,0xFF, + 0x19,0x00,0xB7,0xFF,0x33,0xFF,0x25,0xFF,0x30,0xFF,0xD2,0xFE, + 0x4C,0xFE,0x92,0xFE,0xF2,0xFE,0xE0,0xFE,0x93,0xFE,0xB1,0xFE, + 0x72,0xFF,0x93,0xFF,0x55,0xFF,0x4A,0xFF,0xC6,0xFF,0x1B,0x00, + 0x04,0x00,0x9E,0xFF,0xDB,0xFF,0x29,0x00,0x33,0x00,0xFE,0xFF, + 0x07,0x00,0x67,0x00,0x95,0x00,0x8F,0x00,0xDF,0x00,0x4C,0x01, + 0x7F,0x01,0xA9,0x01,0xAD,0x01,0xE4,0x01,0x5D,0x01,0x01,0xFF, + 0x26,0xFF,0x3E,0x00,0x51,0x00,0xBB,0xFE,0x06,0xFD,0xEB,0xFD, + 0xAB,0xFF,0x78,0xFF,0x20,0xFE,0xC7,0xFD,0xB4,0xFE,0x75,0x00, + 0x1F,0x00,0x06,0xFF,0x52,0xFF,0x27,0x00,0xBE,0x00,0x42,0x00, + 0xBC,0xFF,0xBB,0xFF,0xDA,0xFF,0x6F,0xFF,0x64,0xFF,0x76,0xFF, + 0x20,0xFF,0xDD,0xFE,0xCA,0xFE,0x32,0xFF,0xBD,0xFF,0x3A,0xFF, + 0x05,0xFF,0x53,0xFF,0xF4,0xFF,0x11,0x00,0x54,0xFF,0x25,0xFF, + 0xAC,0xFF,0xF0,0xFF,0x76,0xFF,0x1E,0xFF,0xB5,0xFE,0x01,0xFF, + 0x78,0xFE,0x61,0xFE,0xA1,0xFE,0xF0,0xFE,0xA5,0xFE,0x97,0xFE, + 0x1E,0xFF,0xD9,0xFF,0xA2,0xFF,0x25,0xFF,0x14,0xFF,0x1A,0x00, + 0x3E,0x00,0xD3,0xFF,0x5A,0xFF,0xB6,0xFF,0x6C,0x00,0x68,0x00, + 0xAD,0xFF,0xB2,0xFF,0x55,0x00,0x84,0x00,0x6B,0x00,0x41,0x00, + 0xA4,0x00,0x00,0x01,0x22,0x01,0x36,0x01,0x8F,0x01,0x75,0x01, + 0x5F,0x00,0x44,0xFF,0x5A,0x00,0x18,0x01,0x2D,0x00,0x51,0xFE, + 0x6C,0xFE,0x2C,0x00,0x8A,0x00,0xCE,0xFE,0x9B,0xFD,0x15,0xFF, + 0x59,0x00,0x18,0x00,0xEF,0xFE,0xE2,0xFE,0x61,0x00,0xFA,0x00, + 0x5A,0x00,0xC7,0xFF,0x3F,0x00,0xA3,0x00,0x97,0x00,0x25,0x00, + 0xFD,0xFF,0x1E,0x00,0x12,0x00,0xCC,0xFF,0xE2,0xFF,0x01,0x00, + 0xB9,0xFF,0x7A,0xFF,0xAD,0xFF,0xFD,0xFF,0xEB,0xFF,0x90,0xFF, + 0x7A,0xFF,0xF9,0xFF,0x28,0x00,0xD2,0xFF,0x7D,0xFF,0x99,0xFF, + 0xC3,0xFF,0xAC,0xFF,0x67,0xFF,0x70,0xFF,0x9C,0xFF,0xBA,0xFF, + 0x90,0xFF,0xAB,0xFF,0xDA,0xFF,0xF0,0xFF,0xD0,0xFF,0xCA,0xFF, + 0xEB,0xFF,0x13,0x00,0xEE,0xFF,0xD7,0xFF,0xF7,0xFF,0x31,0x00, + 0x1F,0x00,0x0B,0x00,0x1A,0x00,0x3D,0x00,0x4D,0x00,0x47,0x00, + 0x4F,0x00,0x41,0x00,0x69,0x00,0x8C,0x00,0x80,0x00,0x7C,0x00, + 0x7A,0x00,0xC5,0x00,0xD8,0x00,0xB7,0x00,0x9F,0x00,0x79,0x00, + 0x84,0x00,0xA4,0x00,0x9D,0x00,0x32,0x00,0x03,0x00,0x0F,0x00, + 0x21,0x00,0xF5,0xFF,0x91,0xFF,0x6F,0xFF,0x8C,0xFF,0xA1,0xFF, + 0x70,0xFF,0x4D,0xFF,0x57,0xFF,0x84,0xFF,0x9F,0xFF,0x94,0xFF, + 0x87,0xFF,0x92,0xFF,0xC9,0xFF,0xDD,0xFF,0xE3,0xFF,0xED,0xFF, + 0xF6,0xFF,0xFD,0xFF,0x15,0x00,0x23,0x00,0x11,0x00,0x0D,0x00, + 0x0F,0x00,0x0B,0x00,0x09,0x00,0xEF,0xFF,0xE2,0xFF,0xDF,0xFF, + 0xCF,0xFF,0xBB,0xFF,0xA5,0xFF,0x93,0xFF,0x8C,0xFF,0x89,0xFF, + 0x85,0xFF,0x77,0xFF,0x71,0xFF,0x76,0xFF,0x75,0xFF,0x73,0xFF, + 0x85,0xFF,0x87,0xFF,0x89,0xFF,0x98,0xFF,0x9F,0xFF,0xA6,0xFF, + 0xB3,0xFF,0xB0,0xFF,0xBE,0xFF,0xC9,0xFF,0xC2,0xFF,0xC7,0xFF, + 0xD7,0xFF,0xE6,0xFF,0xE3,0xFF,0xE8,0xFF,0xEE,0xFF,0xF8,0xFF, + 0xFD,0xFF,0xF7,0xFF,0x02,0x00,0x0A,0x00,0x11,0x00,0x08,0x00, + 0x04,0x00,0x11,0x00,0x0E,0x00,0x0C,0x00,0x07,0x00,0x08,0x00, + 0x0E,0x00,0x0C,0x00,0x03,0x00,0x06,0x00,0x10,0x00,0x17,0x00, + 0x1B,0x00,0x1C,0x00,0x2F,0x00,0x31,0x00,0x31,0x00,0x3E,0x00, + 0x36,0x00,0x2F,0x00,0x36,0x00,0x1D,0x00,0x1E,0x00,0x19,0x00, + 0x07,0x00,0xF1,0xFF,0xDF,0xFF,0xDB,0xFF,0xD0,0xFF,0xC0,0xFF, + 0xB4,0xFF,0xB0,0xFF,0xA5,0xFF,0xA0,0xFF,0x93,0xFF,0x90,0xFF, + 0x94,0xFF,0x96,0xFF,0x9A,0xFF,0x9A,0xFF,0x9E,0xFF,0x9F,0xFF, + 0xA6,0xFF,0xAF,0xFF,0xBA,0xFF,0xC2,0xFF,0xC1,0xFF,0xC9,0xFF, + 0xD0,0xFF,0xD9,0xFF,0xDB,0xFF,0xD5,0xFF,0xDE,0xFF,0xDE,0xFF, + 0xD7,0xFF,0xCC,0xFF,0xC8,0xFF,0xC2,0xFF,0xBE,0xFF,0xB9,0xFF, + 0xAC,0xFF,0xA9,0xFF,0xA6,0xFF,0xAA,0xFF,0xA1,0xFF,0x9E,0xFF, + 0xA4,0xFF,0xAA,0xFF,0xAE,0xFF,0xB6,0xFF,0xB1,0xFF,0xBE,0xFF, + 0xC1,0xFF,0xBF,0xFF,0xD3,0xFF,0xD4,0xFF,0xCA,0xFF,0xCB,0xFF, + 0xCF,0xFF,0xD5,0xFF,0xD1,0xFF,0xC6,0xFF,0xCF,0xFF,0xD6,0xFF, + 0xD3,0xFF,0xC9,0xFF,0xC3,0xFF,0xC6,0xFF,0xC3,0xFF,0xC8,0xFF, + 0xBD,0xFF,0xBD,0xFF,0xBA,0xFF,0xB8,0xFF,0xAE,0xFF,0xAF,0xFF, + 0xB0,0xFF,0xB6,0xFF,0xB4,0xFF,0xB6,0xFF,0xB9,0xFF,0xC1,0xFF, + 0xC1,0xFF,0xC7,0xFF,0xCB,0xFF,0xD1,0xFF,0xD6,0xFF,0xCE,0xFF, + 0xCC,0xFF,0xD0,0xFF,0xD8,0xFF,0xD6,0xFF,0xD0,0xFF,0xCE,0xFF, + 0xD7,0xFF,0xD3,0xFF,0xD3,0xFF,0xCD,0xFF,0xD0,0xFF,0xC9,0xFF, + 0xD0,0xFF,0xD3,0xFF,0xD7,0xFF,0xDF,0xFF,0xD6,0xFF,0xDE,0xFF, + 0xE1,0xFF,0xE2,0xFF,0xE3,0xFF,0xE0,0xFF,0xE3,0xFF,0xDF,0xFF, + 0xE7,0xFF,0xE6,0xFF,0xE4,0xFF,0xE4,0xFF,0xE9,0xFF,0xE3,0xFF, + 0xDB,0xFF,0xDD,0xFF,0xE7,0xFF,0xE7,0xFF,0xE3,0xFF,0xE6,0xFF, + 0xEB,0xFF,0xEC,0xFF,0xF3,0xFF,0xF1,0xFF,0xE2,0xFF,0xE2,0xFF, + 0xE7,0xFF,0xED,0xFF,0xEB,0xFF,0xE9,0xFF,0xEB,0xFF,0xE9,0xFF, + 0xE8,0xFF,0xE1,0xFF,0xE9,0xFF,0xE7,0xFF,0xE9,0xFF,0xE8,0xFF, + 0xE6,0xFF,0xE3,0xFF,0xE0,0xFF,0xE3,0xFF,0xEA,0xFF,0xE8,0xFF, + 0xEC,0xFF,0xE8,0xFF,0xE7,0xFF,0xEA,0xFF,0xED,0xFF,0xEC,0xFF, + 0xEF,0xFF,0xED,0xFF,0xE9,0xFF,0xE9,0xFF,0xDF,0xFF,0xE7,0xFF, + 0xE5,0xFF,0xE6,0xFF,0xE6,0xFF,0xDF,0xFF,0xE0,0xFF,0xDB,0xFF, + 0xDD,0xFF,0xDC,0xFF,0xDC,0xFF,0xDF,0xFF,0xDD,0xFF,0xDE,0xFF, + 0xD7,0xFF,0xDC,0xFF,0xDF,0xFF,0xE0,0xFF,0xDD,0xFF,0xD3,0xFF, + 0xD6,0xFF,0xD9,0xFF,0xE1,0xFF,0xE4,0xFF,0xE3,0xFF,0xE3,0xFF, + 0xE8,0xFF,0xE5,0xFF,0xE5,0xFF,0xE5,0xFF,0xE8,0xFF,0xEA,0xFF, + 0xE5,0xFF,0xEA,0xFF,0xDC,0xFF,0xE2,0xFF,0xE9,0xFF,0xEA,0xFF, + 0xE2,0xFF,0xDD,0xFF,0xDC,0xFF,0xE4,0xFF,0xE9,0xFF,0xE3,0xFF, + 0xD7,0xFF,0xDD,0xFF,0xE0,0xFF,0xE2,0xFF,0xE7,0xFF,0xE5,0xFF, + 0xE3,0xFF,0xEA,0xFF,0xEB,0xFF,0xEB,0xFF,0xE6,0xFF,0xED,0xFF, + 0xED,0xFF,0xEF,0xFF,0xED,0xFF,0xEE,0xFF,0xF0,0xFF,0xF1,0xFF, + 0xF1,0xFF,0xF2,0xFF,0xF8,0xFF,0xF1,0xFF,0xF5,0xFF,0xFC,0xFF, + 0xFC,0xFF,0x02,0x00,0x04,0x00,0x08,0x00,0x01,0x00,0x01,0x00, + 0x02,0x00,0x03,0x00,0x08,0x00,0x0D,0x00,0x08,0x00,0x0E,0x00, + 0x0A,0x00,0x02,0x00,0x05,0x00,0x08,0x00,0x0C,0x00,0x0D,0x00, + 0x0D,0x00,0x0F,0x00,0x07,0x00,0x0A,0x00,0x0B,0x00,0x14,0x00, + 0x0A,0x00,0x08,0x00,0x04,0x00,0x0D,0x00,0x0B,0x00,0x05,0x00, + 0x07,0x00,0x0F,0x00,0x0B,0x00,0x08,0x00,0x05,0x00,0x07,0x00, + 0x07,0x00,0x04,0x00,0x01,0x00,0xF9,0xFF,0xFD,0xFF,0xFE,0xFF, + 0x02,0x00,0xFB,0xFF,0xFB,0xFF,0xFD,0xFF,0xEF,0xFF,0xF1,0xFF, + 0xF0,0xFF,0xF1,0xFF,0xF1,0xFF,0xF6,0xFF,0xEE,0xFF,0xEB,0xFF, + 0xEC,0xFF,0xE9,0xFF,0xEC,0xFF,0xEF,0xFF,0xF1,0xFF,0xE5,0xFF, + 0xE6,0xFF,0xE4,0xFF,0xE5,0xFF,0xDF,0xFF,0xE2,0xFF,0xE0,0xFF, + 0xDC,0xFF,0xDA,0xFF,0xDA,0xFF,0xD1,0xFF,0xD8,0xFF,0xD8,0xFF, + 0xD1,0xFF,0xCE,0xFF,0xC8,0xFF,0xCF,0xFF,0xCC,0xFF,0xB7,0xFF, + 0x4F,0xFF,0x6C,0xFF,0x99,0xFF,0x7B,0xFF,0x0A,0xFF,0xB5,0xFC, + 0xDC,0x00,0x35,0xFF,0xCC,0xFE,0x50,0x00,0x28,0xFF,0x19,0x00, + 0xEF,0xFF,0xA7,0xFF,0xDD,0xFF,0xFA,0xFF,0xEB,0xFF,0x6E,0xFF, + 0xD1,0xFF,0x91,0xFF,0xD1,0xFF,0x91,0xFF,0x86,0xFF,0xC7,0xFF, + 0xBB,0xFF,0x96,0xFF,0xF5,0xFF,0x79,0xFF,0x5B,0x00,0x92,0xFF, + 0x67,0x00,0x9C,0xFF,0xE2,0xFF,0x6E,0x00,0x25,0x00,0xBC,0x00, + 0x08,0xFE,0x6E,0x00,0xA2,0xFE,0x7E,0xFF,0xC0,0x00,0xC1,0xFF, + 0x8A,0xFF,0x8F,0x00,0xCE,0xFF,0x64,0x00,0xDB,0xFF,0x6F,0x00, + 0xC7,0xFF,0x46,0x00,0x0D,0xFF,0x24,0x00,0x05,0x00,0x03,0xFF, + 0xF5,0xFF,0x16,0xFF,0xE1,0xFF,0xB0,0xFF,0x30,0xFF,0x1C,0x00, + 0x28,0xFF,0x44,0x00,0x7F,0xFF,0x0B,0x00,0x96,0x00,0x8F,0xFF, + 0x40,0x00,0xDF,0xFF,0x57,0x00,0xE3,0xFF,0x42,0x00,0xC1,0xFF, + 0x4E,0x00,0xC1,0xFF,0xC6,0x00,0xC6,0xFF,0x2B,0x00,0x22,0x00, + 0xCE,0xFF,0xC3,0xFF,0x88,0x00,0xCB,0xFF,0xC5,0xFF,0x92,0xFF, + 0xC4,0xFF,0x55,0xFE,0x10,0x00,0xFE,0xFE,0xF1,0xFF,0xAC,0xFF, + 0xFA,0xFF,0x6D,0xFF,0x2F,0x00,0x8A,0xFF,0x1F,0x00,0xB5,0x00, + 0x7A,0xFF,0xC6,0xFF,0x34,0x00,0xE8,0xFF,0x3A,0x00,0x24,0x00, + 0x34,0x00,0x5A,0xFF,0xA0,0x00,0xA0,0xFF,0x31,0x00,0xAD,0xFF, + 0x57,0x00,0x50,0x00,0x44,0x00,0xDE,0xFF,0xB3,0xFF,0x19,0x00, + 0x34,0x00,0x0D,0x00,0xBD,0xFF,0x01,0x00,0x06,0x00,0xCF,0xFF, + 0x18,0x00,0xFF,0xFF,0x99,0xFF,0x65,0x00,0xCD,0xFF,0x07,0x00, + 0xD3,0xFF,0x1C,0x00,0xE0,0xFF,0x05,0x00,0xF0,0xFF,0xCC,0xFF, + 0x4B,0x00,0xF2,0xFF,0xC1,0xFF,0x03,0x00,0xEE,0xFF,0x1C,0x00, + 0xFA,0xFF,0xFF,0xFF,0xEE,0xFF,0x3C,0x00,0x42,0x00,0x3B,0x00, + 0x9C,0xFF,0x44,0x00,0x25,0x00,0xC3,0xFF,0x74,0x00,0xD5,0xFF, + 0x50,0x00,0x47,0x00,0xDD,0xFF,0x20,0x00,0x33,0x00,0x04,0x00, + 0x3B,0x00,0x18,0x00,0x12,0x00,0x5B,0x00,0x45,0x00,0x16,0x00, + 0x3B,0x00,0x7B,0x00,0x30,0x00,0x1D,0x00,0x4F,0x00,0x2A,0x00, + 0x93,0x00,0x17,0x00,0xF8,0xFF,0x50,0x00,0x16,0x00,0x35,0x00, + 0xF8,0xFF,0x6E,0x00,0x0D,0x00,0x5B,0x00,0x09,0x00,0x09,0x00, + 0x69,0x00,0x27,0x00,0x52,0x00,0x0A,0x00,0x3D,0x00,0x09,0x00, + 0x4C,0x00,0xC5,0xFF,0x08,0x00,0x53,0x00,0x34,0x00,0x3E,0x00, + 0x01,0x00,0x21,0x00,0x72,0x00,0x7D,0x00,0x0C,0x00,0xFF,0xFF, + 0x6D,0x00,0x84,0x00,0x4F,0x00,0x04,0x00,0x02,0x00,0x81,0x00, + 0x53,0x00,0xD2,0xFF,0xF9,0xFF,0x0D,0x00,0x89,0x00,0x27,0x00, + 0xEF,0xFF,0xE3,0xFF,0x7F,0x00,0x34,0x00,0xDB,0xFF,0xC6,0xFF, + 0x1E,0x00,0x4E,0x00,0x01,0x00,0xCD,0xFF,0xCF,0xFF,0x28,0x00, + 0xF3,0xFF,0xDD,0xFF,0xCB,0xFF,0x2B,0x00,0xD2,0xFF,0xE0,0xFF, + 0xAF,0xFF,0xF7,0xFF,0xF8,0xFF,0xE7,0xFF,0xCE,0xFF,0xD7,0xFF, + 0x1B,0x00,0xEE,0xFF,0xDF,0xFF,0x9D,0xFF,0x07,0x00,0xF6,0xFF, + 0xDB,0xFF,0xC4,0xFF,0xA9,0xFF,0x17,0x00,0xE5,0xFF,0xB2,0xFF, + 0x90,0xFF,0xFF,0xFF,0xDE,0xFF,0xCB,0xFF,0x93,0xFF,0xE6,0xFF, + 0x05,0x00,0xE6,0xFF,0x96,0xFF,0xAE,0xFF,0xD9,0xFF,0xE0,0xFF, + 0xAD,0xFF,0x7A,0xFF,0xAC,0xFF,0xE1,0xFF,0xB9,0xFF,0x9B,0xFF, + 0x7C,0xFF,0xA7,0xFF,0xD5,0xFF,0xC4,0xFF,0x8A,0xFF,0xAC,0xFF, + 0xF9,0xFF,0xED,0xFF,0xB7,0xFF,0x90,0xFF,0xAA,0xFF,0xD5,0xFF, + 0xC3,0xFF,0x86,0xFF,0x9E,0xFF,0xEF,0xFF,0xDC,0xFF,0xC7,0xFF, + 0xC1,0xFF,0xCD,0xFF,0xD1,0xFF,0xE4,0xFF,0xAE,0xFF,0xC4,0xFF, + 0xD4,0xFF,0x12,0x00,0xC5,0xFF,0xC8,0xFF,0xE4,0xFF,0xE2,0xFF, + 0xCC,0xFF,0xCB,0xFF,0xB0,0xFF,0xFD,0xFF,0x25,0x00,0xD2,0xFF, + 0xDF,0xFF,0xF8,0xFF,0xF1,0xFF,0xDA,0xFF,0xBF,0xFF,0xB0,0xFF, + 0xFC,0xFF,0x0D,0x00,0xD9,0xFF,0xD4,0xFF,0xB4,0xFF,0x13,0x00, + 0xD3,0xFF,0xB8,0xFF,0xC3,0xFF,0xEB,0xFF,0xDB,0xFF,0xD8,0xFF, + 0xB9,0xFF,0xAE,0xFF,0xFE,0xFF,0xC3,0xFF,0xE2,0xFF,0xD3,0xFF, + 0xD4,0xFF,0xF7,0xFF,0xFA,0xFF,0xDB,0xFF,0xD3,0xFF,0x07,0x00, + 0xF5,0xFF,0xF2,0xFF,0xF0,0xFF,0xD0,0xFF,0xF4,0xFF,0x03,0x00, + 0xEF,0xFF,0xF3,0xFF,0xF7,0xFF,0xE8,0xFF,0xDA,0xFF,0xD3,0xFF, + 0xCA,0xFF,0xDA,0xFF,0xD9,0xFF,0xB6,0xFF,0xE0,0xFF,0x02,0x00, + 0xF8,0xFF,0xEA,0xFF,0x11,0x00,0xD9,0xFF,0xFD,0xFF,0xC7,0xFF, + 0xB7,0xFF,0xBC,0xFF,0xB9,0xFF,0xB2,0xFF,0xE0,0xFF,0xC5,0xFF, + 0xC7,0xFF,0xE0,0xFF,0xF0,0xFF,0xC6,0xFF,0xD6,0xFF,0xDA,0xFF, + 0xCE,0xFF,0xED,0xFF,0xA0,0xFF,0xC1,0xFF,0xE5,0xFF,0xCB,0xFF, + 0xA5,0xFF,0xC6,0xFF,0xB2,0xFF,0xD9,0xFF,0xBB,0xFF,0x9F,0xFF, + 0xCC,0xFF,0xCD,0xFF,0xB5,0xFF,0xF3,0xFF,0xA9,0xFF,0xAF,0xFF, + 0xBB,0xFF,0xB5,0xFF,0xA3,0xFF,0x9D,0xFF,0x7E,0xFF,0xA6,0xFF, + 0xDC,0xFF,0xC4,0xFF,0xBD,0xFF,0xBB,0xFF,0xCC,0xFF,0xB1,0xFF, + 0xCF,0xFF,0x5B,0xFF,0x7F,0xFF,0xB5,0xFF,0x9D,0xFF,0xD1,0xFF, + 0xBB,0xFF,0xA6,0xFF,0xB6,0xFF,0xB7,0xFF,0xBD,0xFF,0xA3,0xFF, + 0xAE,0xFF,0x94,0xFF,0xD2,0xFF,0x98,0xFF,0x96,0xFF,0xBC,0xFF, + 0x98,0xFF,0xA5,0xFF,0x9F,0xFF,0x73,0xFF,0x70,0xFF,0xBF,0xFF, + 0x81,0xFF,0xBD,0xFF,0xD4,0xFF,0xC1,0xFF,0xA6,0xFF,0xDC,0xFF, + 0xA5,0xFF,0x7B,0xFF,0xBB,0xFF,0x70,0xFF,0xA5,0xFF,0xA3,0xFF, + 0xB6,0xFF,0xC3,0xFF,0xA0,0xFF,0x7D,0xFF,0x7E,0xFF,0x9B,0xFF, + 0xA0,0xFF,0xBC,0xFF,0xAD,0xFF,0xB4,0xFF,0xDC,0xFF,0x89,0xFF, + 0xA4,0xFF,0x80,0xFF,0xA0,0xFF,0xF4,0xFF,0xCC,0xFF,0xBD,0xFF, + 0xB0,0xFF,0xE4,0xFF,0xE7,0xFF,0xB3,0xFF,0xB1,0xFF,0xCD,0xFF, + 0x29,0x00,0x10,0x00,0xB7,0xFF,0xD0,0xFF,0xA8,0xFF,0xF5,0xFF, + 0xDC,0xFF,0x55,0xFF,0x83,0xFF,0xFE,0xFF,0xF2,0xFF,0x04,0x00, + 0xC3,0xFF,0xB4,0xFF,0xEB,0xFF,0xD6,0xFF,0x64,0xFF,0x9B,0xFF, + 0x71,0xFF,0xCD,0xFF,0x03,0x00,0x7E,0xFF,0xAB,0xFF,0xDA,0xFF, + 0xAE,0xFF,0xB9,0xFF,0x8D,0xFF,0x61,0xFF,0xEC,0xFF,0xD0,0xFF, + 0xBC,0xFF,0xB4,0xFF,0xA3,0xFF,0xDE,0xFF,0x0B,0x00,0xE0,0xFF, + 0x7F,0xFF,0x01,0x00,0xCA,0xFF,0xE2,0xFF,0xE6,0xFF,0xB9,0xFF, + 0xE9,0xFF,0x35,0x00,0xD2,0xFF,0xE3,0xFF,0x19,0x00,0xBC,0xFF, + 0x34,0x00,0xD0,0xFF,0xB6,0xFF,0x0F,0x00,0x73,0x00,0x08,0x00, + 0x5A,0x00,0x65,0x00,0x23,0x00,0x8E,0x00,0x6B,0xFF,0x51,0xFF, + 0x55,0x00,0xDA,0xFF,0x7C,0x00,0xB2,0xFF,0x7F,0xFF,0x31,0x00, + 0x41,0x00,0x9B,0xFF,0x86,0xFF,0x8B,0xFF,0x28,0x00,0x8C,0x00, + 0x05,0x00,0xBA,0xFF,0x08,0x00,0xFE,0xFF,0xA2,0xFF,0x3D,0xFF, + 0xB4,0xFE,0xC2,0xFF,0x1F,0x00,0xB6,0xFF,0xB1,0xFF,0x79,0xFF, + 0xBA,0xFF,0x20,0x00,0x82,0xFF,0x2C,0xFF,0x68,0xFF,0xE7,0xFF, + 0xF3,0xFF,0xF2,0xFF,0x90,0xFF,0xDC,0xFF,0x4B,0x00,0xFC,0xFF, + 0xFE,0xFF,0xDF,0xFF,0x5A,0x00,0xBB,0x00,0xAF,0x00,0x28,0x00, + 0x5C,0x00,0x0A,0x00,0x86,0x00,0xB1,0x00,0x8E,0xFF,0x87,0x00, + 0x26,0x00,0x41,0x00,0xD4,0x00,0x55,0x00,0xD3,0x00,0x08,0x01, + 0xAE,0x00,0xEB,0x00,0xD1,0x00,0x63,0x00,0xA6,0x01,0xA4,0x01, + 0x38,0x01,0xB1,0x01,0x52,0x01,0x16,0x01,0x03,0x01,0xE3,0xFF, + 0x7F,0x00,0x90,0x00,0xF4,0xFF,0xFB,0xFF,0xD2,0xFF,0xC2,0xFF, + 0x57,0x00,0xE2,0xFF,0x1E,0xFF,0x7C,0xFF,0x3B,0xFF,0x9A,0xFF, + 0x7E,0xFF,0xFC,0xFE,0x3C,0xFF,0xA5,0xFF,0x1B,0xFF,0x60,0xFF, + 0xD5,0xFE,0xC3,0xFE,0xC2,0xFE,0xD3,0xFE,0x3D,0xFF,0x62,0xFF, + 0x5F,0xFF,0x43,0xFF,0x82,0xFF,0x76,0xFF,0x5F,0xFF,0x3D,0xFF, + 0x67,0xFF,0x90,0xFF,0xCE,0xFF,0x08,0x00,0xBD,0xFF,0x1F,0x00, + 0x3C,0x00,0x50,0x00,0x4D,0x00,0x29,0x00,0xFD,0xFF,0x2F,0x00, + 0xEA,0xFF,0x4E,0x00,0xCD,0x00,0xA7,0x00,0x0A,0x01,0x9C,0x00, + 0x24,0x01,0x11,0x01,0xB6,0x01,0xCB,0x01,0x0F,0x02,0x02,0x03, + 0x0F,0x01,0xE9,0xFE,0xBE,0x00,0x59,0xFE,0x56,0x00,0xFB,0xFE, + 0x3A,0xFE,0x43,0x00,0x2F,0x00,0x88,0xFF,0x46,0xFF,0x1F,0xFF, + 0xA3,0xFE,0x31,0x00,0xF6,0xFE,0x4B,0xFE,0x19,0xFF,0x3A,0xFF, + 0xD9,0xFF,0xCC,0xFF,0x56,0xFE,0xDD,0xFE,0x5C,0xFF,0x42,0xFF, + 0x35,0xFF,0x3B,0xFF,0x3B,0xFF,0x17,0x00,0x26,0x00,0x90,0xFF, + 0x81,0xFF,0x5E,0xFF,0x31,0xFF,0xF4,0xFE,0x7E,0xFE,0xEE,0xFD, + 0x20,0xFF,0xD2,0xFE,0x49,0xFF,0xD3,0xFE,0xBB,0xFE,0x17,0xFF, + 0x44,0xFF,0xD3,0xFE,0x62,0xFE,0xE1,0xFE,0xFE,0xFE,0x5F,0xFF, + 0x41,0xFF,0xF7,0xFE,0x64,0xFF,0xC6,0xFF,0xC7,0xFF,0xA1,0xFF, + 0x6A,0xFF,0xCB,0xFF,0x51,0x00,0x93,0x00,0x41,0x00,0x1C,0x00, + 0x51,0x00,0x24,0x01,0xEC,0x00,0xAE,0x00,0xA3,0x00,0x8F,0x01, + 0x1F,0x02,0x98,0x02,0xA7,0x02,0xC6,0x00,0x7D,0x00,0xD5,0xFE, + 0x10,0x00,0xF2,0xFE,0x31,0xFF,0xFF,0xFE,0x07,0x00,0x5C,0x00, + 0xEC,0xFF,0x93,0xFF,0xAF,0xFE,0x9E,0xFF,0x6A,0xFF,0xAE,0xFF, + 0x3A,0xFF,0x11,0xFF,0xCF,0xFF,0x2E,0x00,0x02,0x00,0x7A,0xFF, + 0x60,0xFF,0x83,0xFF,0xCE,0xFF,0xCB,0xFF,0x76,0xFF,0xD5,0xFF, + 0x5E,0x00,0xB0,0x00,0x15,0x00,0x08,0x00,0x09,0xFF,0x60,0xFF, + 0x7E,0xFF,0x6F,0xFE,0x34,0xFF,0xF2,0xFE,0x4B,0xFF,0xC3,0xFF, + 0x8D,0xFF,0x42,0xFF,0xBC,0xFF,0x77,0xFF,0x4A,0xFF,0xBA,0xFF, + 0x41,0xFF,0xE4,0xFF,0x5C,0x00,0x46,0x00,0x68,0x00,0xC2,0x00, + 0x91,0x00,0x2E,0x01,0xD5,0x00,0x99,0x00,0x40,0x01,0x78,0x01, + 0x58,0x01,0xC8,0x01,0x2D,0x02,0x82,0x02,0x50,0x03,0x7B,0x03, + 0x3A,0x03,0x52,0xFC,0x8B,0x00,0x07,0xFE,0xA8,0x00,0x38,0xFF, + 0xE3,0xFE,0xA4,0xFF,0x0F,0x01,0xEB,0x00,0xED,0xFE,0x4D,0x00, + 0xB2,0xFD,0xEB,0x00,0xAC,0x00,0x07,0xFF,0x41,0xFF,0x7B,0xFF, + 0x2C,0x00,0x7B,0x00,0xD1,0xFF,0x84,0xFE,0x5D,0xFF,0xBA,0xFF, + 0xB4,0xFF,0x18,0x00,0x32,0xFF,0xF0,0xFF,0x17,0x01,0xB9,0x00, + 0x10,0x00,0xDE,0xFF,0x6D,0xFF,0xF0,0xFF,0x7C,0xFF,0xAF,0xFE, + 0x7B,0xFE,0x62,0xFE,0x90,0xFF,0xA7,0xFF,0x56,0xFF,0xFB,0xFE, + 0x51,0xFF,0x9D,0xFF,0x2A,0xFF,0xC7,0xFE,0x29,0xFE,0xAB,0xFE, + 0x6C,0xFF,0x8B,0xFF,0x8B,0xFF,0x6E,0xFF,0xC0,0xFF,0x37,0x00, + 0x2E,0x00,0xDC,0xFF,0xF8,0xFF,0x1E,0x00,0xA4,0x00,0xEB,0x00, + 0xAA,0x00,0xFF,0x00,0x86,0x01,0x21,0x02,0x70,0x02,0x18,0x02, + 0x89,0x02,0x95,0x01,0x40,0xFC,0x3C,0x00,0x7D,0xFD,0xCB,0xFF, + 0x1F,0xFF,0x55,0xFE,0x42,0x00,0xEB,0x00,0x11,0x00,0xE6,0xFE, + 0xC3,0xFE,0xF8,0xFD,0xB7,0xFF,0xA0,0xFF,0x24,0xFE,0xD5,0xFE, + 0x0D,0xFF,0x6E,0xFF,0x01,0x00,0xB1,0xFE,0xF5,0xFD,0xF3,0xFE, + 0x37,0xFF,0x51,0xFF,0xA3,0xFF,0xE1,0xFE,0x4B,0xFF,0x7D,0x00, + 0x34,0x00,0x7D,0xFF,0x30,0xFF,0xBF,0xFE,0xE7,0xFE,0x62,0xFF, + 0xAB,0xFE,0x21,0xFE,0x70,0xFE,0x31,0xFE,0xC4,0xFE,0x01,0xFF, + 0x48,0xFE,0x53,0xFE,0xC2,0xFE,0x8A,0xFE,0x99,0xFE,0x4A,0xFE, + 0xF0,0xFD,0x7E,0xFE,0x0B,0xFF,0xDC,0xFE,0xE5,0xFE,0x24,0xFF, + 0x60,0xFF,0xAE,0xFF,0x74,0xFF,0x74,0xFF,0x90,0xFF,0xBB,0xFF, + 0xE9,0xFF,0x70,0x00,0x41,0x00,0x8F,0x00,0x4B,0x01,0xD6,0x01, + 0x05,0x02,0xD0,0x01,0xA2,0x01,0xA2,0x01,0x9D,0xFC,0x40,0xFE, + 0x2C,0xFE,0xC3,0xFF,0x0F,0xFF,0x86,0xFF,0x92,0xFE,0x02,0x00, + 0x3A,0x00,0xC6,0xFE,0xAC,0xFF,0xB0,0xFD,0x36,0xFF,0xBE,0xFF, + 0xB1,0xFF,0xCA,0xFE,0x65,0xFF,0x45,0xFF,0x9A,0xFF,0x0B,0x00, + 0xD1,0xFE,0xEE,0xFE,0x37,0xFF,0x89,0xFF,0xE4,0xFF,0xD5,0xFF, + 0xA1,0xFF,0x14,0x00,0xC2,0x00,0x32,0x00,0x0E,0x00,0xAC,0xFF, + 0x4E,0xFF,0xB1,0xFF,0xC2,0xFF,0x69,0xFF,0x56,0xFF,0xBB,0xFE, + 0x5C,0xFF,0x32,0xFF,0xC8,0xFF,0x2F,0xFF,0x3F,0xFF,0x38,0xFF, + 0x78,0xFF,0xA1,0xFF,0x1E,0xFF,0x07,0xFF,0x46,0xFF,0xBF,0xFF, + 0xC1,0xFF,0xF1,0xFF,0xBE,0xFF,0xEF,0xFF,0x29,0x00,0x5D,0x00, + 0x60,0x00,0x7E,0x00,0x8E,0x00,0xDC,0x00,0x1C,0x01,0x60,0x01, + 0x71,0x01,0xB2,0x01,0xFF,0x01,0x94,0x02,0x95,0x02,0xB7,0x02, + 0x98,0x02,0xB8,0x02,0xA1,0xFE,0xEC,0xFE,0xC4,0xFF,0xA4,0x00, + 0xF9,0xFF,0x82,0x00,0x96,0xFF,0xE9,0x00,0x44,0x01,0x52,0x00, + 0xD7,0x00,0x67,0xFF,0x13,0x00,0x7A,0x00,0x1C,0x01,0xEB,0xFF, + 0x5D,0x00,0x46,0x00,0x77,0x00,0xFE,0x00,0x7C,0x00,0x12,0x00, + 0x12,0x00,0x96,0x00,0xDB,0x00,0x3C,0x01,0xE5,0x00,0xD7,0x00, + 0x57,0x01,0x43,0x01,0x28,0x01,0xF3,0x00,0x4C,0x00,0x52,0x00, + 0x98,0x00,0x9B,0x00,0x5E,0x00,0x73,0x00,0xAA,0xFF,0x2C,0x00, + 0x33,0x00,0x24,0x00,0xE8,0xFF,0xDC,0xFF,0xC3,0xFF,0x35,0x00, + 0x5F,0x00,0xDA,0xFF,0x1A,0x00,0x15,0x00,0x28,0x00,0x7B,0x00, + 0x7F,0x00,0x1F,0x00,0x71,0x00,0x87,0x00,0x9B,0x00,0xBF,0x00, + 0xD3,0x00,0xC6,0x00,0x3D,0x01,0x57,0x01,0x5F,0x01,0x89,0x01, + 0x87,0x01,0xCA,0x01,0x35,0x02,0x14,0x02,0x23,0x02,0x3B,0x02, + 0x78,0x02,0x5D,0x02,0xB0,0xFF,0x28,0x00,0x28,0xFF,0x68,0x00, + 0xFA,0xFF,0x4B,0x00,0x3A,0xFF,0x33,0x00,0x41,0x00,0x79,0x00, + 0x41,0x00,0xAF,0xFF,0xC0,0xFF,0x64,0x00,0x57,0x00,0xFB,0xFF, + 0x22,0x00,0xAA,0xFF,0x07,0x00,0x1A,0x00,0x48,0x00,0xDA,0xFF, + 0xF9,0xFF,0xE6,0xFF,0x2E,0x00,0x5D,0x00,0x66,0x00,0x65,0x00, + 0x70,0x00,0x46,0x00,0x58,0x00,0x42,0x00,0x22,0x00,0x0A,0x00, + 0x08,0x00,0xF3,0xFF,0xF5,0xFF,0x02,0x00,0xBE,0xFF,0x96,0xFF, + 0x8D,0xFF,0x6A,0xFF,0x9D,0xFF,0x59,0xFF,0x6B,0xFF,0x5E,0xFF, + 0x72,0xFF,0x73,0xFF,0xAE,0xFF,0x98,0xFF,0x8C,0xFF,0x9B,0xFF, + 0xB1,0xFF,0x93,0xFF,0xBD,0xFF,0xA8,0xFF,0x9E,0xFF,0xC1,0xFF, + 0xE2,0xFF,0xE3,0xFF,0xF7,0xFF,0x1B,0x00,0x1B,0x00,0x51,0x00, + 0x2B,0x00,0x4A,0x00,0x68,0x00,0x6A,0x00,0x75,0x00,0xA6,0x00, + 0xCA,0x00,0xEA,0x00,0x1F,0x01,0x10,0x01,0xA0,0x00,0x63,0x00, + 0x3F,0x00,0x7E,0x00,0x4D,0x00,0xE6,0xFF,0xD2,0xFF,0xB4,0xFF, + 0x20,0xFF,0x7A,0xFF,0x5D,0xFF,0xDC,0xFE,0x2B,0xFF,0x29,0xFF, + 0xF8,0xFE,0xFC,0xFE,0x28,0xFF,0xE2,0xFE,0x2E,0xFF,0x25,0xFF, + 0x3D,0xFF,0x5D,0xFF,0x6B,0xFF,0x52,0xFF,0x82,0xFF,0x81,0xFF, + 0x87,0xFF,0x91,0xFF,0xAF,0xFF,0x6B,0xFF,0x8F,0xFF,0x9D,0xFF, + 0x79,0xFF,0xA1,0xFF,0xB2,0xFF,0xA5,0xFF,0x95,0xFF,0xA7,0xFF, + 0x69,0xFF,0x52,0xFF,0x61,0xFF,0x35,0xFF,0xF0,0xFE,0x10,0xFF, + 0xF2,0xFE,0xC0,0xFE,0xDE,0xFE,0xEF,0xFE,0xDA,0xFE,0x08,0xFF, + 0x0E,0xFF,0x0F,0xFF,0x27,0xFF,0x3D,0xFF,0x41,0xFF,0x6C,0xFF, + 0x78,0xFF,0x92,0xFF,0xB5,0xFF,0xD0,0xFF,0xD6,0xFF,0x09,0x00, + 0x1B,0x00,0x3B,0x00,0x48,0x00,0x68,0x00,0x6C,0x00,0x9D,0x00, + 0xBA,0x00,0xCD,0x00,0xE8,0x00,0xC1,0x00,0x73,0x00,0x84,0x00, + 0x97,0x00,0xF4,0xFF,0xFC,0xFF,0xEF,0xFF,0x61,0xFF,0x48,0xFF, + 0x4D,0xFF,0xF1,0xFE,0xE0,0xFE,0x10,0xFF,0xD8,0xFE,0xD4,0xFE, + 0x0A,0xFF,0xEB,0xFE,0xFF,0xFE,0x1F,0xFF,0x2F,0xFF,0x58,0xFF, + 0x7E,0xFF,0x6F,0xFF,0x7F,0xFF,0xB2,0xFF,0xA3,0xFF,0xB5,0xFF, + 0xDB,0xFF,0xBD,0xFF,0xB4,0xFF,0xD1,0xFF,0xC4,0xFF,0xC3,0xFF, + 0xDD,0xFF,0xE2,0xFF,0xD0,0xFF,0xDE,0xFF,0xD6,0xFF,0xBB,0xFF, + 0xB7,0xFF,0x7F,0xFF,0x54,0xFF,0x49,0xFF,0x15,0xFF,0x0C,0xFF, + 0x08,0xFF,0xEB,0xFE,0xEB,0xFE,0x0E,0xFF,0x04,0xFF,0x1F,0xFF, + 0x39,0xFF,0x46,0xFF,0x4B,0xFF,0x74,0xFF,0x7D,0xFF,0x8D,0xFF, + 0xB2,0xFF,0xC3,0xFF,0xD0,0xFF,0x05,0x00,0x04,0x00,0x2D,0x00, + 0x3B,0x00,0x46,0x00,0x60,0x00,0x8E,0x00,0x83,0x00,0xAA,0x00, + 0xCC,0x00,0xD4,0x00,0xE8,0x00,0xE6,0x00,0x8B,0x00,0x90,0x00, + 0xA8,0x00,0x26,0x00,0xDF,0xFF,0xE8,0xFF,0xA6,0xFF,0x22,0xFF, + 0x4F,0xFF,0x0F,0xFF,0xC8,0xFE,0x02,0xFF,0x06,0xFF,0xD2,0xFE, + 0x07,0xFF,0x03,0xFF,0xF1,0xFE,0x2C,0xFF,0x42,0xFF,0x45,0xFF, + 0x7E,0xFF,0x80,0xFF,0x93,0xFF,0xA9,0xFF,0xC2,0xFF,0xB9,0xFF, + 0xDF,0xFF,0xD6,0xFF,0xB4,0xFF,0xD4,0xFF,0xD3,0xFF,0xBD,0xFF, + 0xD7,0xFF,0xEC,0xFF,0xD0,0xFF,0xDB,0xFF,0xE3,0xFF,0xB1,0xFF, + 0x9D,0xFF,0x87,0xFF,0x5B,0xFF,0x55,0xFF,0x24,0xFF,0x18,0xFF, + 0x07,0xFF,0x05,0xFF,0x05,0xFF,0x13,0xFF,0x15,0xFF,0x2A,0xFF, + 0x3A,0xFF,0x4E,0xFF,0x56,0xFF,0x6C,0xFF,0x8F,0xFF,0xA1,0xFF, + 0xB2,0xFF,0xD7,0xFF,0xF0,0xFF,0x10,0x00,0x25,0x00,0x3B,0x00, + 0x63,0x00,0x87,0x00,0x95,0x00,0xA3,0x00,0xB6,0x00,0xD1,0x00, + 0xDE,0x00,0xFC,0x00,0x01,0x01,0x04,0x01,0xE9,0x00,0xA2,0x00, + 0xAD,0x00,0x85,0x00,0x1F,0x00,0x06,0x00,0xEB,0xFF,0x6F,0xFF, + 0x5E,0xFF,0x6C,0xFF,0x20,0xFF,0x17,0xFF,0x38,0xFF,0x2D,0xFF, + 0x18,0xFF,0x3F,0xFF,0x43,0xFF,0x47,0xFF,0x7A,0xFF,0x7D,0xFF, + 0x91,0xFF,0xC5,0xFF,0xC9,0xFF,0xE5,0xFF,0x07,0x00,0x02,0x00, + 0x11,0x00,0x32,0x00,0x17,0x00,0x19,0x00,0x27,0x00,0x27,0x00, + 0x15,0x00,0x23,0x00,0x27,0x00,0x14,0x00,0x23,0x00,0x17,0x00, + 0xE5,0xFF,0xE8,0xFF,0xC5,0xFF,0x9E,0xFF,0x89,0xFF,0x75,0xFF, + 0x50,0xFF,0x50,0xFF,0x50,0xFF,0x3A,0xFF,0x55,0xFF,0x61,0xFF, + 0x69,0xFF,0x75,0xFF,0x91,0xFF,0x98,0xFF,0xAE,0xFF,0xC0,0xFF, + 0xDB,0xFF,0xE8,0xFF,0x0D,0x00,0x26,0x00,0x45,0x00,0x67,0x00, + 0x6F,0x00,0x87,0x00,0xB2,0x00,0xBD,0x00,0xCB,0x00,0xD7,0x00, + 0xE1,0x00,0xEC,0x00,0xF7,0x00,0x06,0x01,0x06,0x01,0xD3,0x00, + 0xAC,0x00,0xAE,0x00,0x7A,0x00,0x12,0x00,0x16,0x00,0xEC,0xFF, + 0x88,0xFF,0x70,0xFF,0x71,0xFF,0x24,0xFF,0x20,0xFF,0x34,0xFF, + 0x25,0xFF,0x0C,0xFF,0x38,0xFF,0x31,0xFF,0x3B,0xFF,0x6E,0xFF, + 0x8B,0xFF,0xA4,0xFF,0xBD,0xFF,0xC1,0xFF,0xD9,0xFF,0xFF,0xFF, + 0xF8,0xFF,0x06,0x00,0x1A,0x00,0x02,0x00,0x0B,0x00,0x02,0x00, + 0x00,0x00,0xF0,0xFF,0xFD,0xFF,0xFC,0xFF,0xE8,0xFF,0xEE,0xFF, + 0xDE,0xFF,0xC3,0xFF,0xBC,0xFF,0xAA,0xFF,0x7C,0xFF,0x7E,0xFF, + 0x57,0xFF,0x3E,0xFF,0x4A,0xFF,0x3C,0xFF,0x29,0xFF,0x43,0xFF, + 0x3E,0xFF,0x49,0xFF,0x5B,0xFF,0x7A,0xFF,0x83,0xFF,0xA8,0xFF, + 0xD0,0xFF,0xD3,0xFF,0xFB,0xFF,0x1C,0x00,0x29,0x00,0x4E,0x00, + 0x65,0x00,0x71,0x00,0x8E,0x00,0xA7,0x00,0x9F,0x00,0xB7,0x00, + 0xCC,0x00,0xD0,0x00,0xE9,0x00,0xFD,0x00,0xF5,0x00,0xFD,0x00, + 0xF5,0x00,0xC7,0x00,0xBA,0x00,0xB6,0x00,0x5D,0x00,0x3A,0x00, + 0x33,0x00,0xE5,0xFF,0xA8,0xFF,0xAB,0xFF,0x88,0xFF,0x52,0xFF, + 0x6C,0xFF,0x6C,0xFF,0x56,0xFF,0x72,0xFF,0x7C,0xFF,0x76,0xFF, + 0x9B,0xFF,0xB2,0xFF,0xBE,0xFF,0xF4,0xFF,0x01,0x00,0xFF,0xFF, + 0x24,0x00,0x2E,0x00,0x30,0x00,0x39,0x00,0x42,0x00,0x37,0x00, + 0x31,0x00,0x3D,0x00,0x29,0x00,0x2A,0x00,0x2F,0x00,0x22,0x00, + 0x19,0x00,0x18,0x00,0xED,0xFF,0xDE,0xFF,0xDB,0xFF,0xBB,0xFF, + 0xA6,0xFF,0x9B,0xFF,0x77,0xFF,0x6C,0xFF,0x6C,0xFF,0x66,0xFF, + 0x6F,0xFF,0x73,0xFF,0x78,0xFF,0x8B,0xFF,0xB0,0xFF,0xB7,0xFF, + 0xD6,0xFF,0xE1,0xFF,0xFA,0xFF,0x15,0x00,0x33,0x00,0x38,0x00, + 0x4D,0x00,0x70,0x00,0x7C,0x00,0x7F,0x00,0x91,0x00,0x99,0x00, + 0xA7,0x00,0xAF,0x00,0xAF,0x00,0xB8,0x00,0xC8,0x00,0xD0,0x00, + 0xC4,0x00,0xCF,0x00,0xCD,0x00,0xB2,0x00,0x9E,0x00,0x96,0x00, + 0x6B,0x00,0x37,0x00,0x32,0x00,0x0A,0x00,0xCE,0xFF,0xBD,0xFF, + 0xA2,0xFF,0x74,0xFF,0x65,0xFF,0x68,0xFF,0x54,0xFF,0x50,0xFF, + 0x55,0xFF,0x5A,0xFF,0x63,0xFF,0x73,0xFF,0x8D,0xFF,0xA3,0xFF, + 0xB2,0xFF,0xCD,0xFF,0xCC,0xFF,0xE4,0xFF,0xEE,0xFF,0xFD,0xFF, + 0x06,0x00,0xFC,0xFF,0xF6,0xFF,0xF9,0xFF,0xEF,0xFF,0xE4,0xFF, + 0xE6,0xFF,0xDE,0xFF,0xD4,0xFF,0xCE,0xFF,0xC6,0xFF,0xB8,0xFF, + 0xA9,0xFF,0xA6,0xFF,0x91,0xFF,0x81,0xFF,0x84,0xFF,0x73,0xFF, + 0x64,0xFF,0x6B,0xFF,0x69,0xFF,0x6F,0xFF,0x78,0xFF,0x8B,0xFF, + 0x91,0xFF,0xB0,0xFF,0xC8,0xFF,0xD3,0xFF,0xEA,0xFF,0xFF,0xFF, + 0x01,0x00,0x11,0x00,0x25,0x00,0x26,0x00,0x41,0x00,0x4A,0x00, + 0x53,0x00,0x5B,0x00,0x4D,0x00,0x55,0x00,0x53,0x00,0x51,0x00, + 0x4E,0x00,0x4E,0x00,0x4A,0x00,0x49,0x00,0x44,0x00,0x42,0x00, + 0x42,0x00,0x43,0x00,0x2D,0x00,0x32,0x00,0x33,0x00,0x1A,0x00, + 0x15,0x00,0x0D,0x00,0xF4,0xFF,0xED,0xFF,0xE8,0xFF,0xC3,0xFF, + 0xBF,0xFF,0xB7,0xFF,0xAF,0xFF,0xA6,0xFF,0x9C,0xFF,0xA3,0xFF, + 0x97,0xFF,0x8A,0xFF,0x97,0xFF,0x87,0xFF,0x8A,0xFF,0x8E,0xFF, + 0x86,0xFF,0x92,0xFF,0x94,0xFF,0xA0,0xFF,0x9B,0xFF,0xA9,0xFF, + 0xA7,0xFF,0xB2,0xFF,0xA8,0xFF,0xAB,0xFF,0xB5,0xFF,0xAC,0xFF, + 0xAE,0xFF,0xAC,0xFF,0xA4,0xFF,0xA8,0xFF,0xA7,0xFF,0xAD,0xFF, + 0xA7,0xFF,0xA7,0xFF,0xA8,0xFF,0xBB,0xFF,0xB3,0xFF,0xC1,0xFF, + 0xC3,0xFF,0xC9,0xFF,0xCF,0xFF,0xD8,0xFF,0xDB,0xFF,0xDC,0xFF, + 0xD4,0xFF,0xD9,0xFF,0xE3,0xFF,0xDA,0xFF,0xDF,0xFF,0xD9,0xFF, + 0xD6,0xFF,0xDC,0xFF,0xE1,0xFF,0xCF,0xFF,0xC4,0xFF,0xC5,0xFF, + 0xC5,0xFF,0xC6,0xFF,0xC5,0xFF,0xC3,0xFF,0xC3,0xFF,0xBD,0xFF, + 0xC3,0xFF,0xC1,0xFF,0xB9,0xFF,0xB9,0xFF,0xBC,0xFF,0xBC,0xFF, + 0xBD,0xFF,0xB9,0xFF,0xAD,0xFF,0xB8,0xFF,0xA9,0xFF,0xFC,0xFE, + 0x49,0xFF,0xA1,0xFF,0xC6,0xFF,0xEC,0xFF,0xB9,0xFF,0x31,0x00, + 0xCC,0xFF,0x04,0x00,0x92,0xFF,0xD7,0xFF,0xDF,0xFF,0x53,0x00, + 0xB1,0xFF,0x49,0x00,0x3A,0xFE,0xFC,0xFE,0x81,0xFF,0x4E,0x01, + 0x7E,0xFE,0x0A,0x00,0xFC,0xFE,0xBF,0xFF,0xC1,0xFF,0x0B,0x00, + 0xAC,0x00,0xA2,0xFE,0xCF,0xFD,0xB9,0x00,0x7E,0x00,0x0E,0x00, + 0xE1,0xFF,0xD5,0xFF,0xA6,0xFE,0xE1,0xFF,0x33,0xFF,0x11,0x00, + 0xF5,0xFE,0x78,0x00,0x16,0xFE,0x78,0x01,0xA8,0xFE,0xE9,0xFF, + 0xDA,0xFE,0x4B,0xFE,0xA0,0x00,0x58,0x00,0xAB,0xFE,0x86,0xFF, + 0x62,0xFE,0x08,0x00,0x5E,0xFF,0xEE,0xFF,0xD5,0xFD,0x68,0x00, + 0xB2,0xFF,0xD8,0xFC,0x66,0x00,0xD5,0x00,0x33,0x00,0x30,0xFE, + 0x46,0xFF,0xFD,0xFD,0x55,0x03,0xDF,0xFE,0xAA,0x00,0x13,0xFE, + 0x50,0x01,0x62,0xFE,0xF4,0x00,0xB2,0xFE,0x7F,0x01,0x2E,0xFD, + 0x00,0x01,0x3F,0xFD,0xD0,0x00,0x42,0xFF,0x55,0x02,0x6C,0xFE, + 0x38,0x02,0x4B,0xFE,0x85,0x02,0x74,0xFF,0xE5,0x00,0x82,0xFF, + 0x90,0xFD,0x88,0x00,0xE2,0xFD,0xEC,0x00,0x1B,0x00,0x28,0x00, + 0x9A,0xFE,0x93,0x00,0x7E,0xFF,0x93,0xFF,0x92,0x01,0xFC,0x01, + 0x33,0x01,0x3E,0xFE,0x92,0xFE,0x2E,0x01,0xDB,0xFD,0xB3,0x01, + 0x19,0xFC,0x2E,0x01,0x2C,0xFE,0x84,0x01,0xA1,0xFF,0xF8,0xFF, + 0x7B,0x01,0x32,0xFE,0x4E,0x00,0xBC,0xFF,0xA3,0x00,0xB5,0xFF, + 0xF4,0xFE,0x23,0xFF,0xB7,0x00,0xFD,0xFE,0x1A,0x01,0xDC,0xFE, + 0xF5,0xFE,0x5B,0xFD,0x7C,0x01,0x9C,0xFF,0xD9,0x02,0x28,0xFD, + 0x0B,0x03,0x48,0xFE,0xD2,0x00,0x02,0x01,0xAB,0xFF,0x96,0xFC, + 0xFB,0xFE,0xC1,0xFD,0xF8,0x01,0x0C,0xFE,0x46,0x00,0x61,0xFC, + 0xBF,0x02,0x66,0xFF,0x60,0x02,0x9B,0xFE,0xCB,0x00,0xF3,0xFD, + 0xD1,0x00,0xA8,0x00,0x72,0x01,0x83,0x02,0xB8,0xFC,0x0B,0xFF, + 0x43,0x01,0x7F,0x01,0x47,0xFF,0x59,0x00,0x47,0xFE,0xBD,0xFE, + 0x00,0xFE,0x31,0xFE,0xC3,0x01,0x30,0xFF,0x85,0xFF,0x8A,0x04, + 0x77,0xFF,0xE3,0x01,0x14,0xFB,0xF1,0xFE,0x9F,0x00,0x0F,0x02, + 0x48,0x02,0xD6,0xFF,0x3E,0x00,0x99,0xFF,0x30,0x00,0x9B,0x01, + 0xFE,0x00,0xC7,0x00,0x64,0x00,0xFC,0xFE,0x9A,0x04,0x88,0xFD, + 0x95,0x00,0xCB,0xFD,0x8F,0x01,0x2A,0xFE,0xF8,0x01,0x70,0xFF, + 0x07,0xFD,0xCA,0x01,0x06,0xFE,0x37,0x01,0x08,0x00,0x30,0x02, + 0x36,0x02,0x7F,0xFF,0x79,0xFF,0xC7,0xFE,0x01,0x01,0xFF,0x00, + 0xE6,0x00,0xC6,0xFF,0x67,0xFE,0x52,0x00,0x85,0x00,0xBA,0xFE, + 0x77,0x03,0x67,0xFF,0x42,0x00,0xFA,0x00,0x73,0xFE,0x22,0xFC, + 0x57,0xFE,0x4B,0xFC,0xBD,0x03,0xBF,0xFF,0x4F,0x00,0x43,0xFD, + 0x2E,0x00,0xAA,0xFD,0x43,0x02,0x72,0xFF,0x41,0x02,0x02,0xFD, + 0x1E,0x01,0xE1,0xFF,0x44,0x00,0x3A,0x02,0xF5,0xFE,0x85,0xFF, + 0x3B,0xFD,0x92,0xFF,0x42,0x01,0x80,0x01,0x30,0xFC,0x26,0xFC, + 0x2F,0xFE,0x28,0x01,0xA0,0x00,0x8D,0x02,0xC7,0xFC,0x14,0x02, + 0x90,0xFC,0x7E,0x02,0x20,0x03,0x38,0x02,0xDE,0xFA,0xBA,0x02, + 0x24,0x00,0xFC,0x00,0x10,0x01,0xC5,0xFF,0x66,0xFC,0x8A,0xFE, + 0x16,0x03,0xCE,0xFD,0x62,0x00,0xEA,0xFB,0xBE,0xFE,0x65,0xFE, + 0x20,0x03,0x4F,0x01,0x5E,0xFF,0x7D,0x01,0x4F,0x02,0x41,0x00, + 0x4C,0x03,0x54,0xFC,0x62,0x01,0xD0,0x02,0x4D,0x00,0xBE,0xFC, + 0x4D,0xF9,0x9D,0xFC,0x18,0xFD,0x80,0x03,0x32,0x00,0x6C,0x00, + 0x24,0x04,0xB1,0x00,0xC1,0xFF,0xC8,0xFF,0xD7,0x00,0xA9,0xFF, + 0xDF,0xFD,0x93,0xFD,0x45,0x00,0x1B,0x00,0xFD,0xFF,0xE2,0xFD, + 0x3B,0x01,0xE8,0x01,0x9D,0xFE,0x4A,0xFB,0xE4,0xFB,0x89,0xFD, + 0x8D,0x03,0x9B,0x01,0xF4,0x00,0xD1,0xFF,0xC7,0x00,0xF2,0x02, + 0x30,0x01,0x6F,0x00,0x20,0xFD,0x23,0xFD,0xDF,0xFE,0xBF,0xFF, + 0xC8,0x01,0x5E,0xFD,0x4C,0xFF,0x65,0xFE,0x25,0x02,0x75,0x02, + 0xC6,0xFF,0xDC,0xFF,0xB3,0xFD,0x2E,0x01,0x2C,0x00,0xF5,0x01, + 0xB1,0xFE,0x15,0xFC,0x4D,0xFB,0x90,0xFC,0xDE,0xFA,0x67,0x05, + 0x1A,0x03,0x08,0x02,0xEE,0xFF,0xC9,0xFF,0x0E,0xFF,0x62,0x03, + 0xF1,0x00,0xF7,0xFF,0xE9,0x01,0x41,0x02,0x7E,0x03,0x42,0xFB, + 0xF5,0xFC,0xC8,0xFC,0x62,0x00,0x0E,0x00,0x81,0xFF,0xB5,0xFC, + 0x5B,0xFD,0x47,0x03,0xB6,0x02,0xBC,0x02,0x2A,0x00,0xF4,0xFD, + 0xFB,0xFD,0x5E,0xFB,0xAB,0xFF,0xAC,0x01,0x5F,0x03,0x21,0xFD, + 0xA3,0xFF,0x63,0xFF,0xB0,0x01,0x8E,0x02,0x4B,0x01,0x61,0xFF, + 0xED,0xFD,0xA0,0xFD,0x9C,0xFD,0xB2,0xFF,0x5E,0xFF,0xB0,0xFF, + 0xE9,0x00,0x9C,0xFE,0xEB,0x00,0xF9,0xFE,0x47,0x01,0x68,0x00, + 0x9A,0xFF,0x6F,0xFC,0x45,0x01,0x07,0x01,0xA3,0xFF,0x8D,0xFD, + 0x96,0xFF,0x4E,0x01,0xCD,0xFD,0x18,0x03,0xB8,0xFF,0x87,0xFF, + 0x14,0x00,0xE7,0xFF,0xAE,0xFF,0x0B,0xFF,0x84,0xFF,0xAB,0xFD, + 0x81,0xFF,0xD2,0xFE,0xFD,0x00,0x8F,0x02,0x69,0x02,0x03,0x00, + 0x1E,0x00,0x66,0x03,0xEA,0x01,0x97,0x02,0xD8,0xFB,0xFB,0xFD, + 0x90,0xFD,0xFA,0xFE,0x7E,0x00,0xA5,0x01,0x31,0x01,0xEA,0x00, + 0xF7,0xFF,0xD0,0xFE,0x34,0xFE,0xE1,0xFF,0x97,0xFF,0xCA,0xFF, + 0x99,0xFE,0xBC,0xFF,0x35,0xFE,0xA7,0x01,0x08,0xFE,0x65,0xFE, + 0x63,0x00,0xFF,0xFF,0xE6,0xFF,0x86,0xFF,0xBB,0x02,0xDA,0xFC, + 0xC2,0xFF,0xBE,0xFB,0x9A,0x00,0xA1,0xFF,0x06,0x01,0xFE,0xFE, + 0x3D,0x00,0x6C,0xFF,0x21,0x01,0x0B,0xFF,0xED,0xFD,0xCD,0xFE, + 0x00,0x00,0x9B,0xFF,0x17,0xFF,0xDB,0x02,0xB0,0xFD,0x94,0x01, + 0xD7,0xFD,0xE1,0x02,0x45,0xFE,0xBA,0x01,0xED,0xFD,0x53,0x01, + 0x90,0xFD,0x60,0x01,0x03,0xFF,0x38,0xFF,0x26,0xFF,0xD5,0x00, + 0x57,0xFF,0x19,0xFE,0x35,0x00,0x96,0xFF,0x7D,0x01,0xA8,0xFC, + 0x62,0x01,0xFB,0xFE,0x0E,0x01,0x43,0xFF,0xF5,0xFE,0x83,0xFE, + 0xCE,0x01,0x94,0xFC,0x95,0x02,0x7E,0xFE,0x95,0x01,0xA4,0xFC, + 0xA8,0x03,0x91,0xFE,0x7B,0x02,0x10,0x01,0x4E,0x00,0xA1,0xFE, + 0xC7,0x00,0x49,0xFF,0xEF,0xFF,0x76,0xFD,0xD0,0x00,0x87,0xFE, + 0x60,0xFF,0xF2,0xFE,0x44,0x00,0x7C,0x01,0x20,0xFE,0xF4,0xFF, + 0x56,0xFF,0xDF,0x02,0xD0,0xFD,0x29,0x01,0x2E,0xFE,0x45,0xFF, + 0xBC,0x00,0xEE,0xFF,0x11,0x00,0x6F,0x00,0xE4,0xFE,0x22,0x00, + 0xF2,0xFE,0x55,0x00,0x0F,0x00,0xDB,0x00,0x26,0xFF,0xE6,0xFE, + 0x73,0x01,0x22,0xFF,0x5A,0x01,0xA3,0xFF,0xAF,0xFF,0x2E,0xFF, + 0xD1,0xFF,0x0C,0x01,0x35,0xFD,0x60,0x02,0x35,0xFE,0x24,0x01, + 0xE9,0xFF,0x4F,0xFE,0x52,0x00,0x4D,0xFE,0xA3,0x00,0x3A,0xFE, + 0x9C,0x01,0xBE,0xFF,0xDB,0x00,0xA7,0xFE,0x87,0x01,0x20,0x00, + 0xBF,0xFF,0xCD,0xFE,0xEE,0xFF,0x03,0xFF,0xAF,0xFF,0xEA,0xFE, + 0x8A,0x00,0x3A,0x00,0xA2,0xFF,0x53,0x00,0xF8,0xFF,0x55,0x00, + 0x37,0xFF,0x1E,0x00,0xCB,0xFF,0x2E,0x00,0x3E,0xFF,0x97,0x00, + 0xCC,0xFF,0x21,0x01,0x77,0xFF,0xCC,0xFF,0x92,0x00,0x88,0x00, + 0x5A,0xFF,0xC5,0xFF,0x95,0xFF,0x42,0x00,0x5E,0x00,0x1B,0xFF, + 0xA1,0x00,0x25,0x00,0x1B,0x00,0xE2,0xFF,0x4D,0x01,0xDE,0xFE, + 0x3C,0x00,0xA3,0xFE,0xE3,0xFE,0x16,0x01,0x37,0x00,0xB1,0x00, + 0x11,0x00,0xD0,0xFF,0xD4,0xFF,0xBC,0xFF,0x3E,0xFF,0x60,0x00, + 0x13,0x00,0xAA,0xFF,0xF7,0x00,0x00,0xFF,0xA5,0x00,0x01,0xFF, + 0xBA,0x01,0x85,0xFE,0x50,0x00,0x19,0xFE,0xAC,0x00,0xC9,0xFF, + 0xB7,0x00,0xF4,0xFF,0x81,0x00,0x5E,0x00,0x4D,0x00,0x24,0x00, + 0xF9,0xFF,0x48,0xFF,0xD4,0x00,0x84,0xFF,0x36,0xFF,0xB8,0x00, + 0x2D,0xFF,0x50,0x00,0xD8,0xFE,0x83,0x00,0xB3,0xFF,0x7F,0x00, + 0x6E,0x00,0x75,0x00,0x01,0x00,0xED,0xFF,0x01,0xFF,0x39,0x00, + 0x6B,0xFF,0xA7,0xFF,0x54,0xFF,0xB3,0xFF,0x39,0x00,0x69,0xFF, + 0x9E,0x01,0xFF,0xFE,0x25,0x01,0xBB,0xFE,0x48,0x00,0x15,0x00, + 0x5C,0xFF,0x99,0xFF,0xFF,0xFF,0x06,0xFF,0x5C,0x00,0x6E,0xFF, + 0x43,0x00,0xD1,0xFF,0x64,0xFF,0x31,0x00,0x1D,0xFF,0x80,0x00, + 0xE6,0xFE,0xC4,0x00,0xFB,0xFE,0xB2,0x00,0x0B,0xFF,0x41,0x00, + 0x8D,0xFF,0x7C,0x00,0x1E,0xFF,0x3C,0x00,0x63,0xFF,0xD7,0xFF, + 0x4E,0x00,0xA8,0xFF,0x20,0x00,0x63,0xFF,0x9E,0x00,0xA5,0xFF, + 0xC4,0x00,0xDD,0xFF,0x97,0x00,0xB6,0xFF,0x34,0x00,0x5E,0xFF, + 0xC4,0xFF,0xC5,0xFF,0x36,0x00,0xBD,0xFF,0xCC,0xFF,0xC2,0xFF, + 0xBE,0xFF,0x8D,0xFF,0xCA,0xFF,0xC2,0xFF,0x1A,0x00,0x61,0x00, + 0x74,0xFF,0xD4,0xFF,0x5E,0xFF,0x32,0x00,0xD9,0xFE,0xE3,0xFF, + 0xB6,0xFF,0xCD,0xFF,0xB2,0xFF,0x1C,0x00,0xA3,0xFF,0xFC,0xFF, + 0x0C,0x00,0xF9,0xFF,0xAA,0xFF,0xFD,0xFF,0x32,0x00,0xD5,0xFF, + 0xD8,0xFF,0x7B,0xFF,0xE3,0xFF,0x13,0x00,0xCA,0xFF,0xD6,0xFF, + 0xD9,0xFF,0xE9,0xFF,0xC4,0xFF,0x18,0x00,0xE8,0xFF,0xBB,0xFF, + 0xED,0xFF,0xD9,0xFF,0x98,0xFF,0xED,0xFF,0xA4,0xFF,0xE2,0xFF, + 0x9E,0xFF,0x0A,0x00,0x91,0xFF,0x0B,0x00,0xBF,0xFF,0xE8,0xFF, + 0xD1,0xFF,0xE1,0xFF,0xF1,0xFF,0xF6,0xFF,0xDB,0xFF,0xB5,0xFF, + 0xE8,0xFF,0xB4,0xFF,0x09,0x00,0xAF,0xFF,0x05,0x00,0xD2,0xFF, + 0xFB,0xFF,0xDA,0xFF,0xD3,0xFF,0x96,0xFF,0xEC,0xFF,0xF3,0xFF, + 0xC0,0xFF,0xED,0xFF,0xD5,0xFF,0x00,0x00,0xD7,0xFF,0xF1,0xFF, + 0xEA,0xFF,0xD7,0xFF,0xDF,0xFF,0xBE,0xFF,0xB7,0xFF,0xC5,0xFF, + 0xED,0xFF,0xB4,0xFF,0xF0,0xFF,0xC3,0xFF,0x0E,0x00,0xC0,0xFF, + 0x0C,0x00,0xBD,0xFF,0xDC,0xFF,0xD9,0xFF,0xD6,0xFF,0xBF,0xFF, + 0xCE,0xFF,0xE2,0xFF,0xAD,0xFF,0xCB,0xFF,0x91,0xFF,0xEF,0xFF, + 0xE5,0xFF,0xD6,0xFF,0xAE,0xFF,0xD7,0xFF,0xC9,0xFF,0xD7,0xFF, + 0xDF,0xFF,0xC4,0xFF,0xAD,0xFF,0xEE,0xFF,0xD3,0xFF,0xD4,0xFF, + 0xC5,0xFF,0xC0,0xFF,0xEC,0xFF,0xE6,0xFF,0x19,0x00,0xF8,0xFF, + 0x01,0x00,0xF5,0xFF,0x14,0x00,0xE9,0xFF,0xEC,0xFF,0xC4,0xFF, + 0xB9,0xFF,0xE4,0xFF,0x02,0x00,0xD7,0xFF,0xD6,0xFF,0xFE,0xFF, + 0xDA,0xFF,0x12,0x00,0xF4,0xFF,0xD4,0xFF,0xC2,0xFF,0xF0,0xFF, + 0xBF,0xFF,0xE0,0xFF,0xE2,0xFF,0xE7,0xFF,0xCC,0xFF,0xC6,0xFF, + 0xB6,0xFF,0xA2,0xFF,0xBA,0xFF,0x84,0xFF,0x87,0xFF,0x8D,0xFF, + 0x70,0xFF,0x58,0xFF,0x7C,0xFF,0x66,0xFF,0x73,0xFF,0x7E,0xFF, + 0x8A,0xFF,0x89,0xFF,0xB5,0xFF,0xDC,0xFF,0xC9,0xFF,0xE7,0xFF, + 0xFF,0xFF,0x1A,0x00,0x15,0x00,0x49,0x00,0x36,0x00,0x40,0x00, + 0x44,0x00,0x59,0x00,0x3A,0x00,0x5D,0x00,0x80,0x00,0x8C,0x00, + 0xAA,0x00,0xAF,0x00,0xCA,0x00,0x19,0x01,0x31,0x01,0x3F,0x01, + 0x3F,0x01,0x76,0x01,0xFD,0x00,0x16,0x00,0x75,0xFE,0xE2,0xFE, + 0xCC,0xFE,0xF6,0xFE,0xFC,0xFE,0x19,0xFF,0x35,0xFF,0x8D,0xFF, + 0x5E,0x00,0x26,0x00,0x0A,0x00,0x06,0x00,0xB8,0xFF,0xC3,0xFF, + 0xA6,0xFF,0x7F,0xFF,0xCD,0xFE,0x18,0xFF,0x2A,0xFF,0x78,0xFF, + 0xB7,0xFF,0xB2,0xFF,0x86,0xFF,0xB5,0xFF,0x29,0x00,0xF3,0xFF, + 0xFD,0xFF,0xB6,0xFF,0x81,0xFF,0x72,0xFF,0x72,0xFF,0x55,0xFF, + 0x2D,0xFF,0x43,0xFF,0x47,0xFF,0x5E,0xFF,0x31,0xFE,0x49,0xFF, + 0x42,0xFE,0xD0,0xFE,0x57,0xFF,0xAE,0xFF,0x59,0xFF,0x19,0xFF, + 0x44,0xFF,0xE0,0xFE,0x5B,0xFF,0x3D,0xFF,0xED,0xFE,0x39,0xFF, + 0x92,0xFF,0xA9,0xFF,0xC4,0xFF,0x66,0x00,0x55,0x00,0x57,0x00, + 0x84,0x00,0x9F,0x00,0xB5,0x00,0xFB,0x00,0x14,0x01,0xE7,0x00, + 0x67,0x01,0x6E,0x01,0x78,0x01,0x36,0x01,0x5E,0x00,0xF9,0xFE, + 0x7B,0xFD,0xE8,0xFE,0x8D,0xFE,0xEA,0xFE,0x53,0xFF,0x6E,0xFF, + 0xA2,0xFF,0x07,0x01,0xF0,0x00,0x12,0x00,0x0A,0x00,0x70,0xFF, + 0x35,0xFF,0x48,0xFF,0x62,0xFF,0x8B,0xFE,0x6D,0xFE,0x2B,0xFF, + 0x98,0xFF,0x17,0x00,0x51,0x00,0x22,0x00,0xE1,0xFF,0x35,0x00, + 0x68,0x00,0xC2,0xFF,0x96,0xFF,0x4F,0xFF,0x17,0xFF,0x38,0xFF, + 0x9D,0xFF,0x80,0xFF,0x78,0xFF,0xC4,0xFF,0xE6,0xFF,0x12,0x00, + 0x30,0x00,0x0A,0x00,0xA2,0xFF,0xA2,0xFF,0xBF,0xFF,0x8F,0xFF, + 0x8E,0xFF,0x85,0xFF,0x6A,0xFF,0x68,0xFF,0x66,0xFF,0xBC,0xFE, + 0xF6,0xFE,0x5E,0xFF,0x66,0xFF,0xB3,0xFF,0xAB,0xFF,0xD1,0xFF, + 0xA3,0xFF,0xD6,0xFF,0xA9,0xFF,0x4C,0xFF,0x67,0xFF,0x71,0xFF, + 0x9E,0xFF,0xB0,0xFF,0x04,0x00,0xE1,0xFF,0x2B,0x00,0x65,0x00, + 0x3F,0x00,0x21,0x00,0x38,0x00,0x31,0x00,0x2C,0x00,0x73,0x00, + 0xA8,0x00,0xC9,0x00,0xF6,0x00,0x25,0x01,0x1C,0x01,0x24,0x01, + 0x70,0x01,0x83,0x01,0x0F,0x01,0x60,0x00,0x6F,0xFC,0xDB,0xFE, + 0x72,0xFE,0x60,0xFF,0xCD,0xFF,0x2A,0x00,0xE2,0xFF,0xC9,0x00, + 0xD6,0x01,0xFB,0x00,0x09,0x00,0x66,0xFF,0xFF,0xFE,0xE5,0xFE, + 0x4E,0xFF,0x16,0xFF,0x82,0xFE,0x11,0xFF,0x5B,0x00,0x83,0x00, + 0xEA,0x00,0xB6,0x00,0x2D,0x00,0xC8,0xFF,0x3E,0x00,0xE6,0xFF, + 0x31,0xFF,0x0E,0xFF,0x0D,0xFF,0x23,0xFF,0xD1,0xFF,0x3B,0x00, + 0x16,0x00,0xFE,0xFF,0x57,0x00,0x4F,0x00,0x2A,0x00,0x13,0x00, + 0x8F,0xFF,0x2B,0xFF,0x2F,0xFF,0x7A,0xFF,0xFA,0xFE,0x46,0xFE, + 0x05,0xFF,0x7C,0xFF,0xC3,0xFF,0x7D,0x00,0x04,0x00,0xBE,0xFF, + 0xDA,0xFF,0x1A,0x00,0x96,0xFF,0x32,0xFF,0x55,0xFF,0x35,0xFF, + 0x88,0xFF,0xDC,0xFF,0x20,0x00,0x07,0x00,0x54,0x00,0x7C,0x00, + 0x50,0x00,0x49,0x00,0x27,0x00,0x0B,0x00,0x0E,0x00,0x6E,0x00, + 0x97,0x00,0x99,0x00,0x11,0x01,0x5C,0x01,0x3C,0x01,0x5E,0x01, + 0x4D,0x01,0x16,0x01,0xDF,0x00,0xA1,0x00,0x75,0x00,0x51,0xFE, + 0x12,0xFE,0x91,0xFF,0x95,0xFF,0x45,0x00,0xC6,0x00,0xAF,0x00, + 0x7E,0x00,0x12,0x01,0x7D,0x01,0xE4,0xFF,0x91,0xFF,0x3D,0xFF, + 0x08,0xFF,0x43,0xFF,0xBD,0xFF,0xD6,0xFF,0xB6,0xFF,0xBC,0x00, + 0x31,0x01,0x0B,0x01,0xF1,0x00,0x75,0x00,0xFC,0xFF,0xAC,0xFF, + 0xDD,0xFF,0x97,0xFF,0x38,0xFF,0x7F,0xFF,0xD6,0xFF,0x43,0x00, + 0x9C,0x00,0xC9,0x00,0x68,0x00,0x47,0x00,0x44,0x00,0x20,0x00, + 0xB8,0xFF,0x82,0xFF,0x5F,0xFF,0x64,0xFF,0xB9,0xFF,0x0E,0x00, + 0x17,0x00,0x27,0x00,0xF1,0xFF,0x75,0xFE,0x84,0xFF,0x20,0xFF, + 0x8D,0xFF,0xB8,0xFF,0xCF,0xFF,0x96,0xFF,0xBC,0xFF,0x72,0x00, + 0xB5,0xFF,0x54,0xFF,0x6A,0xFF,0xAF,0xFF,0xF4,0xFF,0x0B,0x00, + 0x02,0x00,0xF2,0xFF,0x17,0x00,0x8B,0x00,0x74,0x00,0x01,0x00, + 0x07,0x00,0x31,0x00,0x65,0x00,0xAF,0x00,0xFE,0x00,0xE8,0x00, + 0xC8,0x00,0xEC,0x00,0xC8,0x00,0xAB,0x00,0x6D,0x00,0xFC,0xFF, + 0xCD,0xFF,0x6C,0x00,0x5B,0x00,0x17,0xFE,0xC6,0xFE,0xB0,0xFF, + 0x15,0x00,0x2B,0x00,0x46,0x00,0xDC,0xFF,0xA9,0xFF,0x8C,0x00, + 0x92,0x00,0x14,0xFF,0x0F,0xFF,0x3F,0xFF,0x59,0xFF,0x84,0xFF, + 0xF1,0xFF,0xCD,0xFF,0x81,0xFF,0x5B,0x00,0xB6,0x00,0x38,0x00, + 0xE3,0xFF,0xB3,0xFF,0x87,0xFF,0x78,0xFF,0xBE,0xFF,0x95,0xFF, + 0x48,0xFF,0x92,0xFF,0x1C,0x00,0x2A,0x00,0x1D,0x00,0x20,0x00, + 0xDD,0xFF,0xAD,0xFF,0xC7,0xFF,0xDA,0xFF,0x69,0xFF,0x60,0xFF, + 0x89,0xFF,0xA2,0xFF,0xDD,0xFF,0x08,0x00,0xE6,0xFF,0xD6,0xFF, + 0x23,0xFE,0xBD,0xFE,0x82,0xFF,0xAF,0xFF,0x78,0xFF,0x6F,0xFF, + 0x8A,0xFF,0xF3,0xFF,0x1D,0x00,0x4D,0x00,0x0D,0xFF,0x0C,0xFF, + 0xB9,0xFF,0xE8,0xFF,0x9E,0xFF,0xC4,0xFF,0xEA,0xFF,0xD8,0xFF, + 0x80,0x00,0xB1,0x00,0xF7,0xFF,0xB3,0xFF,0x1F,0x00,0x36,0x00, + 0x48,0x00,0x3D,0x00,0x8A,0x00,0x6D,0x00,0xCE,0x00,0x1B,0x01, + 0xD3,0x00,0x6A,0x00,0x6E,0x00,0xA3,0x00,0x23,0x00,0xE2,0xFF, + 0x22,0x00,0x3F,0x00,0x30,0x00,0x2F,0x00,0x75,0xFF,0x1B,0xFF, + 0x02,0x00,0x4B,0x00,0xE7,0xFF,0xA8,0xFF,0xD1,0xFF,0x12,0x00, + 0xF5,0xFF,0x5A,0x00,0x90,0xFF,0x69,0xFF,0x9A,0xFF,0x17,0x00, + 0xDB,0xFF,0x90,0xFF,0xA7,0xFF,0xE9,0xFF,0x12,0x00,0x46,0x00, + 0x0C,0x00,0xBF,0xFF,0xBB,0xFF,0x0A,0x00,0x0A,0x00,0xBC,0xFF, + 0xB7,0xFF,0xBB,0xFF,0xD3,0xFF,0x01,0x00,0x0A,0x00,0xC6,0xFF, + 0xC4,0xFF,0xF6,0xFF,0x15,0x00,0xC1,0xFF,0xB9,0xFF,0xB1,0xFF, + 0xC7,0xFF,0xD4,0xFF,0xEF,0xFF,0x6C,0xFF,0x7E,0xFE,0x10,0x00, + 0x2B,0x00,0x5B,0xFF,0x4E,0xFF,0xDE,0xFF,0x4E,0x00,0xC8,0xFF, + 0xBE,0xFF,0x3F,0xFF,0x1D,0xFF,0xB2,0xFF,0x25,0x00,0xE6,0xFF, + 0x85,0xFF,0xB6,0xFF,0x7B,0x00,0x52,0x00,0x48,0x00,0x1B,0x00, + 0xFF,0xFF,0x46,0x00,0xAC,0x00,0x9F,0x00,0x4E,0x00,0x92,0x00, + 0x24,0x01,0x27,0x01,0xDA,0x00,0x7F,0x00,0x89,0x00,0x9D,0x00, + 0xBA,0x00,0x63,0x00,0xF8,0xFF,0x14,0x00,0x82,0x00,0xC3,0x00, + 0x87,0x00,0x3A,0x00,0x8E,0xFF,0xA8,0xFF,0x56,0x00,0x00,0x00, + 0x9E,0xFF,0x59,0xFF,0x3F,0x00,0x7E,0x00,0x09,0x00,0x14,0x00, + 0xE0,0xFF,0x10,0x00,0x3A,0x00,0x46,0x00,0xD8,0xFF,0x94,0xFF, + 0xEA,0xFF,0x69,0x00,0x1D,0x00,0xE1,0xFF,0xE4,0xFF,0x44,0x00, + 0x28,0x00,0x0E,0x00,0x05,0x00,0xE3,0xFF,0x0A,0x00,0x2D,0x00, + 0x18,0x00,0xD8,0xFF,0xCF,0xFF,0x10,0x00,0x19,0x00,0xE9,0xFF, + 0xD9,0xFF,0xED,0xFF,0x0B,0x00,0xFF,0xFF,0xF9,0xFF,0xED,0xFF, + 0xE8,0xFF,0x03,0x00,0x03,0x00,0xD8,0xFF,0x51,0xFF,0x72,0xFF, + 0xBB,0xFF,0xAA,0xFF,0x64,0xFF,0x89,0xFF,0xDE,0xFF,0xB4,0xFF, + 0x82,0xFF,0xCF,0xFF,0xCC,0xFF,0xC2,0xFF,0xAA,0xFF,0xC1,0xFF, + 0x88,0xFF,0x84,0xFF,0xE6,0xFF,0xFF,0xFF,0xA7,0xFF,0xA2,0xFF, + 0xE7,0xFF,0x06,0x00,0xCD,0xFF,0xBD,0xFF,0xD6,0xFF,0xE0,0xFF, + 0xE6,0xFF,0xEA,0xFF,0xDC,0xFF,0xD2,0xFF,0xE1,0xFF,0xFC,0xFF, + 0xF7,0xFF,0xF8,0xFF,0x07,0x00,0x0E,0x00,0x1A,0x00,0x0C,0x00, + 0x12,0x00,0x42,0x00,0x3A,0x00,0x08,0x00,0x1B,0x00,0x40,0x00, + 0x08,0x00,0xD7,0xFF,0xD2,0xFF,0xFA,0xFF,0xE8,0xFF,0xBE,0xFF, + 0xA2,0xFF,0xB3,0xFF,0xBA,0xFF,0x7F,0xFF,0x71,0xFF,0x8A,0xFF, + 0x72,0xFF,0x66,0xFF,0x83,0xFF,0xA4,0xFF,0x77,0xFF,0x68,0xFF, + 0x8D,0xFF,0xAA,0xFF,0x7D,0xFF,0x66,0xFF,0x7B,0xFF,0x92,0xFF, + 0x8A,0xFF,0x6C,0xFF,0x7A,0xFF,0x99,0xFF,0xA4,0xFF,0x92,0xFF, + 0x90,0xFF,0x98,0xFF,0x94,0xFF,0xA6,0xFF,0x9A,0xFF,0x85,0xFF, + 0x94,0xFF,0x8C,0xFF,0xA2,0xFF,0x8F,0xFF,0x7B,0xFF,0x2E,0xFF, + 0xDF,0xFE,0x91,0xFF,0x88,0xFF,0x16,0xFF,0xBE,0xFE,0x77,0xFF, + 0x18,0x00,0x3A,0xFF,0x09,0xFF,0x45,0xFF,0xF1,0xFF,0x60,0xFF, + 0x25,0xFF,0xA4,0xFF,0xFE,0xFF,0xD9,0xFF,0x8A,0xFF,0xC6,0xFF, + 0x1C,0x00,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0x1A,0x00,0x2B,0x00, + 0x48,0x00,0x35,0x00,0x2B,0x00,0x54,0x00,0x6F,0x00,0x5F,0x00, + 0x4A,0x00,0x58,0x00,0x7B,0x00,0x54,0x00,0x48,0x00,0x32,0x00, + 0x52,0x00,0x31,0x00,0x32,0x00,0x22,0x00,0x11,0x00,0x19,0x00, + 0x25,0x00,0x0C,0x00,0xF4,0xFF,0x09,0x00,0x29,0x00,0xF9,0xFF, + 0xDB,0xFF,0xF1,0xFF,0x1B,0x00,0x0A,0x00,0xDE,0xFF,0xFD,0xFF, + 0x0F,0x00,0x13,0x00,0xF0,0xFF,0xF4,0xFF,0x16,0x00,0x23,0x00, + 0xEE,0xFF,0xFC,0xFF,0x09,0x00,0x18,0x00,0xF5,0xFF,0xF6,0xFF, + 0x1F,0x00,0x1A,0x00,0xF3,0xFF,0xED,0xFF,0x07,0x00,0x08,0x00, + 0xE7,0xFF,0xE8,0xFF,0x00,0x00,0xF9,0xFF,0xD2,0xFF,0xE4,0xFF, + 0xF8,0xFF,0xF7,0xFF,0xE2,0xFF,0xEB,0xFF,0xED,0xFF,0xE6,0xFF, + 0xCE,0xFF,0xD6,0xFF,0xD7,0xFF,0xDE,0xFF,0xD6,0xFF,0xDB,0xFF, + 0xDE,0xFF,0xD9,0xFF,0xE1,0xFF,0xDF,0xFF,0xE1,0xFF,0xE7,0xFF, + 0xE1,0xFF,0xE1,0xFF,0xE4,0xFF,0xDC,0xFF,0xE6,0xFF,0xE2,0xFF, + 0xDC,0xFF,0xDC,0xFF,0xDF,0xFF,0xDF,0xFF,0xDE,0xFF,0xDC,0xFF, + 0xE6,0xFF,0xE5,0xFF,0xE7,0xFF,0xE3,0xFF,0xE3,0xFF,0xE4,0xFF, + 0xDE,0xFF,0xD6,0xFF,0xE7,0xFF,0xE8,0xFF,0xE0,0xFF,0xDC,0xFF, + 0xE1,0xFF,0xE8,0xFF,0xD7,0xFF,0xD7,0xFF,0xD7,0xFF,0xDC,0xFF, + 0xD6,0xFF,0xDA,0xFF,0xD9,0xFF,0xE1,0xFF,0xDF,0xFF,0xE2,0xFF, + 0xDC,0xFF,0xE9,0xFF,0xE8,0xFF,0xED,0xFF,0xE6,0xFF,0xED,0xFF, + 0xE3,0xFF,0xEB,0xFF,0xE7,0xFF,0xF5,0xFF,0xE9,0xFF,0xE3,0xFF, + 0xF2,0xFF,0xF3,0xFF,0xEC,0xFF,0xE5,0xFF,0xF3,0xFF,0xEE,0xFF, + 0xF3,0xFF,0xEC,0xFF,0xF4,0xFF,0xF0,0xFF,0xF3,0xFF,0xF0,0xFF, + 0xF1,0xFF,0xEC,0xFF,0xEF,0xFF,0xE7,0xFF,0xEE,0xFF,0xE8,0xFF, + 0xF0,0xFF,0xED,0xFF,0xEC,0xFF,0xE3,0xFF,0xE2,0xFF,0xE4,0xFF, + 0xDC,0xFF,0xDE,0xFF,0xDB,0xFF,0xDF,0xFF,0xE6,0xFF,0xE6,0xFF, + 0xE6,0xFF,0xDF,0xFF,0xE1,0xFF,0xD6,0xFF,0xD6,0xFF,0xE0,0xFF, + 0xD4,0xFF,0xD2,0xFF,0xC9,0xFF,0xCE,0xFF,0xC7,0xFF,0xC1,0xFF, + 0xC5,0xFF,0xC5,0xFF,0xBE,0xFF,0xB3,0xFF,0xB8,0xFF,0xBA,0xFF, + 0xB6,0xFF,0xB2,0xFF,0xAE,0xFF,0xB8,0xFF,0xB8,0xFF,0xB6,0xFF, + 0xAF,0xFF,0xAE,0xFF,0xB2,0xFF,0xAF,0xFF,0xB4,0xFF,0xB2,0xFF, + 0xA1,0xFF,0xAB,0xFF,0xA9,0xFF,0xA8,0xFF,0x9D,0xFF,0xA5,0xFF, + 0x9C,0xFF,0x9F,0xFF,0x9A,0xFF,0x9E,0xFF,0xA0,0xFF,0x99,0xFF, + 0xA4,0xFF,0x9C,0xFF,0x97,0xFF,0x95,0xFF,0x99,0xFF,0x97,0xFF, + 0x9D,0xFF,0x9D,0xFF,0x9D,0xFF,0x8E,0xFF,0x98,0xFF,0x98,0xFF, + 0x9C,0xFF,0x99,0xFF,0x96,0xFF,0x90,0xFF,0x97,0xFF,0x97,0xFF, + 0x99,0xFF,0x9A,0xFF,0x9A,0xFF,0x98,0xFF,0x91,0xFF,0x9C,0xFF, + 0xA1,0xFF,0xA1,0xFF,0x9F,0xFF,0xA1,0xFF,0x9F,0xFF,0xA6,0xFF, + 0x9F,0xFF,0xA9,0xFF,0xA8,0xFF,0xAE,0xFF,0xAE,0xFF,0xAB,0xFF, + 0xAD,0xFF,0xB3,0xFF,0xB4,0xFF,0xAC,0xFF,0xAF,0xFF,0xB6,0xFF, + 0xAC,0xFF,0xAE,0xFF,0xAF,0xFF,0xB4,0xFF,0xB9,0xFF,0xB6,0xFF, + 0xB5,0xFF,0xB6,0xFF,0xB4,0xFF,0xB2,0xFF,0xB7,0xFF,0xBB,0xFF, + 0xBA,0xFF,0xB5,0xFF,0xC0,0xFF,0xBD,0xFF,0xBE,0xFF,0xC2,0xFF, + 0xCA,0xFF,0xC8,0xFF,0xCE,0xFF,0xCC,0xFF,0xD4,0xFF,0xD6,0xFF, + 0xDA,0xFF,0xDC,0xFF,0xDC,0xFF,0xE5,0xFF,0xE7,0xFF,0xEB,0xFF, + 0xEB,0xFF,0xF6,0xFF,0xEB,0xFF,0xE8,0xFF,0xE6,0xFF,0xE6,0xFF, + 0xE7,0xFF,0xE8,0xFF,0xEA,0xFF,0xF3,0xFF,0xF6,0xFF,0xF2,0xFF, + 0xEF,0xFF,0xEC,0xFF,0xED,0xFF,0xF5,0xFF,0xFB,0xFF,0xF3,0xFF, + 0xF4,0xFF,0xF6,0xFF,0xF9,0xFF,0xF2,0xFF,0xF8,0xFF,0xF3,0xFF, + 0xF6,0xFF,0xF7,0xFF,0xF2,0xFF,0xF1,0xFF,0xF2,0xFF,0xF2,0xFF, + 0xF8,0xFF,0xF6,0xFF,0xF0,0xFF,0xEC,0xFF,0xE8,0xFF,0xE8,0xFF, + 0xE8,0xFF,0xE9,0xFF,0xF5,0xFF,0xF3,0xFF,0xF0,0xFF,0xEB,0xFF, + 0xEF,0xFF,0xEF,0xFF,0xF7,0xFF,0xEF,0xFF,0xEE,0xFF,0xEE,0xFF, + 0xEC,0xFF,0xF5,0xFF,0xF0,0xFF,0xE4,0xFF,0xE2,0xFF,0xED,0xFF, + 0xEE,0xFF,0xEC,0xFF,0xEC,0xFF,0xF3,0xFF,0xEE,0xFF,0xEA,0xFF, + 0xE8,0xFF,0xF0,0xFF,0xEA,0xFF,0xE3,0xFF,0xE6,0xFF,0xEB,0xFF, + 0xE8,0xFF,0xEA,0xFF,0xE6,0xFF,0xE7,0xFF,0xE2,0xFF,0xEC,0xFF, + 0xE7,0xFF,0xE4,0xFF,0xE4,0xFF,0xE3,0xFF,0xE3,0xFF,0xEB,0xFF, + 0xE5,0xFF,0xE1,0xFF,0xE3,0xFF,0xE3,0xFF,0xEB,0xFF,0xE3,0xFF, + 0xEF,0xFF,0xEC,0xFF,0xE4,0xFF,0xE5,0xFF,0xE7,0xFF,0xE9,0xFF, + 0xDF,0xFF,0xDF,0xFF,0xE5,0xFF,0xD9,0xFF,0xDE,0xFF,0xDC,0xFF, + 0xE2,0xFF,0xE0,0xFF,0xE6,0xFF,0xE4,0xFF,0xD8,0xFF,0xD0,0xFF, + 0xE7,0xFF,0xEE,0xFF,0xE1,0xFF,0xDD,0xFF,0xDD,0xFF,0xE0,0xFF, + 0xCE,0xFF,0xDA,0xFF,0xE3,0xFF,0xE4,0xFF,0xD2,0xFF,0xDD,0xFF, + 0xE5,0xFF,0xD2,0xFF,0xDB,0xFF,0xDB,0xFF,0xEC,0xFF,0xE0,0xFF, + 0xDB,0xFF,0xE2,0xFF,0xEB,0xFF,0xEB,0xFF,0xE3,0xFF,0xEF,0xFF, + 0xE0,0xFF,0xEF,0xFF,0xE4,0xFF,0xF3,0xFF,0xEB,0xFF,0xEC,0xFF, + 0xE6,0xFF,0xE9,0xFF,0xFA,0xFF,0xE8,0xFF,0xF8,0xFF,0xE3,0xFF, + 0xF5,0xFF,0xF0,0xFF,0xEF,0xFF,0xE9,0xFF,0xEB,0xFF,0xF4,0xFF, + 0xEA,0xFF,0xF5,0xFF,0xEE,0xFF,0xF1,0xFF,0xE9,0xFF,0xF3,0xFF, + 0xEA,0xFF,0xDC,0xFF,0xDA,0xFF,0xBA,0xFF,0x3B,0xFF,0x61,0x00, + 0xD2,0xFF,0x98,0xFF,0xA1,0xFF,0x75,0x00,0xF6,0xFF,0xBF,0xFF, + 0xCB,0xFF,0x5A,0x00,0xE1,0xFF,0xB9,0xFF,0x21,0x00,0xED,0xFF, + 0xE0,0xFF,0xA1,0xFF,0x1A,0x00,0xBD,0xFF,0xBA,0xFF,0xD6,0xFF, + 0x05,0x00,0xB6,0xFF,0xB8,0xFF,0xF4,0xFF,0xD8,0xFF,0xBD,0xFF, + 0xCD,0xFF,0xF0,0xFF,0xD8,0xFF,0xB6,0xFF,0xE4,0xFF,0xF8,0xFF, + 0xD8,0xFF,0xB1,0xFF,0xE7,0xFF,0xF4,0xFF,0xC1,0xFF,0xCC,0xFF, + 0xE8,0xFF,0xE8,0xFF,0xAD,0xFF,0xD1,0xFF,0xDE,0xFF,0xE1,0xFF, + 0xBA,0xFF,0xCA,0xFF,0xDD,0xFF,0xD0,0xFF,0xB7,0xFF,0xCB,0xFF, + 0xDE,0xFF,0xC7,0xFF,0xD0,0xFF,0xCB,0xFF,0xD5,0xFF,0xD7,0xFF, + 0xCA,0xFF,0xDB,0xFF,0xD8,0xFF,0xD8,0xFF,0xD8,0xFF,0xDD,0xFF, + 0xCF,0xFF,0xE1,0xFF,0xE2,0xFF,0xE4,0xFF,0xDC,0xFF,0xEA,0xFF, + 0xE8,0xFF,0xDE,0xFF,0xE9,0xFF,0xF6,0xFF,0xEE,0xFF,0xEA,0xFF, + 0xEB,0xFF,0xE4,0xFF,0xDB,0xFF,0xF2,0xFF,0xEF,0xFF,0xEA,0xFF, + 0xE4,0xFF,0xF2,0xFF,0xE6,0xFF,0xE7,0xFF,0xEB,0xFF,0xE7,0xFF, + 0xEA,0xFF,0xEA,0xFF,0xF8,0xFF,0xAC,0xFF,0x05,0x00,0xFF,0xFF, + 0xEF,0xFF,0xE2,0xFF,0x19,0x00,0x01,0x00,0xFC,0xFF,0x09,0x00, + 0x0C,0x00,0x1A,0x00,0xFB,0xFF,0x20,0x00,0x14,0x00,0x23,0x00, + 0x04,0x00,0x21,0x00,0x15,0x00,0x22,0x00,0x20,0x00,0x1B,0x00, + 0x19,0x00,0x1B,0x00,0x2A,0x00,0x27,0x00,0x19,0x00,0x2D,0x00, + 0x21,0x00,0x1E,0x00,0x19,0x00,0x38,0x00,0x16,0x00,0x1C,0x00, + 0x20,0x00,0x26,0x00,0x1A,0x00,0x13,0x00,0x29,0x00,0x25,0x00, + 0x19,0x00,0x16,0x00,0x1E,0x00,0x25,0x00,0x13,0x00,0x0F,0x00, + 0x16,0x00,0x29,0x00,0x10,0x00,0x03,0x00,0x0A,0x00,0x2B,0x00, + 0x12,0x00,0x15,0x00,0x18,0x00,0x1D,0x00,0x11,0x00,0x0E,0x00, + 0x12,0x00,0x0E,0x00,0x11,0x00,0x13,0x00,0x0A,0x00,0x07,0x00, + 0x11,0x00,0x27,0x00,0x24,0x00,0x11,0x00,0x0C,0x00,0x10,0x00, + 0x0F,0x00,0x05,0x00,0x01,0x00,0x11,0x00,0x13,0x00,0x00,0x00, + 0xB8,0xFF,0xEF,0xFF,0xE3,0xFF,0xDA,0xFF,0x9C,0xFF,0xDE,0xFF, + 0x02,0x00,0xCF,0xFF,0x9C,0xFF,0xC6,0xFF,0xF3,0xFF,0xF0,0xFF, + 0xDB,0xFF,0xD2,0xFF,0xE7,0xFF,0x05,0x00,0xFE,0xFF,0xE5,0xFF, + 0xEE,0xFF,0x04,0x00,0x1E,0x00,0x0B,0x00,0xF8,0xFF,0x07,0x00, + 0x2A,0x00,0x28,0x00,0x16,0x00,0x18,0x00,0x25,0x00,0x39,0x00, + 0x2E,0x00,0x24,0x00,0x29,0x00,0x24,0x00,0x2A,0x00,0x27,0x00, + 0x2A,0x00,0x20,0x00,0x2A,0x00,0x38,0x00,0x3C,0x00,0x31,0x00, + 0x2C,0x00,0x41,0x00,0x57,0x00,0x3E,0x00,0x3E,0x00,0x4E,0x00, + 0x4D,0x00,0x28,0x00,0x2B,0x00,0x26,0x00,0x28,0x00,0x1B,0x00, + 0x0E,0x00,0xF7,0xFF,0xFB,0xFF,0x0E,0x00,0xF9,0xFF,0xDB,0xFF, + 0xE0,0xFF,0xFE,0xFF,0xFA,0xFF,0xE2,0xFF,0xD9,0xFF,0xE9,0xFF, + 0xFD,0xFF,0xD9,0xFF,0xC6,0xFF,0xBB,0xFF,0xCF,0xFF,0xC5,0xFF, + 0xC9,0xFF,0xC0,0xFF,0xB6,0xFF,0xCB,0xFF,0xC9,0xFF,0xC0,0xFF, + 0xB8,0xFF,0xBB,0xFF,0xC0,0xFF,0xBE,0xFF,0xC2,0xFF,0xB4,0xFF, + 0xB1,0xFF,0xC7,0xFF,0xD0,0xFF,0xD3,0xFF,0xCF,0xFF,0xD9,0xFF, + 0xD6,0xFF,0xE3,0xFF,0xE6,0xFF,0xF8,0xFF,0x03,0x00,0x13,0x00, + 0x13,0x00,0x1E,0x00,0x21,0x00,0x33,0x00,0x20,0x00,0x32,0x00, + 0x37,0x00,0x49,0x00,0x57,0x00,0x42,0x00,0x44,0x00,0x55,0x00, + 0x3F,0x00,0x2E,0x00,0xF6,0xFF,0xE6,0xFF,0xAC,0xFF,0xAE,0xFF, + 0xBB,0xFF,0xA4,0xFF,0x85,0xFF,0x8A,0xFF,0xAE,0xFF,0x95,0xFF, + 0x75,0xFF,0x67,0xFF,0x81,0xFF,0x7A,0xFF,0x82,0xFF,0x84,0xFF, + 0x8C,0xFF,0x90,0xFF,0x9B,0xFF,0x9E,0xFF,0x97,0xFF,0x83,0xFF, + 0x8C,0xFF,0x9E,0xFF,0xA9,0xFF,0x95,0xFF,0xA9,0xFF,0xB0,0xFF, + 0xB9,0xFF,0xB3,0xFF,0xB4,0xFF,0x9C,0xFF,0xA0,0xFF,0x98,0xFF, + 0x97,0xFF,0x97,0xFF,0x8E,0xFF,0x92,0xFF,0x9E,0xFF,0x9A,0xFF, + 0x97,0xFF,0x89,0xFF,0x93,0xFF,0x94,0xFF,0x9B,0xFF,0x92,0xFF, + 0x92,0xFF,0x91,0xFF,0xA1,0xFF,0xA2,0xFF,0xA7,0xFF,0xAB,0xFF, + 0xA1,0xFF,0xA7,0xFF,0x9F,0xFF,0xA8,0xFF,0xA8,0xFF,0xA4,0xFF, + 0xAE,0xFF,0xAC,0xFF,0xA6,0xFF,0xB2,0xFF,0xA9,0xFF,0xAE,0xFF, + 0xA7,0xFF,0xAF,0xFF,0xB7,0xFF,0xB5,0xFF,0xAE,0xFF,0xB1,0xFF, + 0xB3,0xFF,0xB2,0xFF,0xB8,0xFF,0xB5,0xFF,0xB6,0xFF,0xB4,0xFF, + 0xB4,0xFF,0xBC,0xFF,0xB9,0xFF,0xBA,0xFF,0xBA,0xFF,0xC2,0xFF, + 0xC6,0xFF,0xC4,0xFF,0xC6,0xFF,0xCD,0xFF,0xCE,0xFF,0xD3,0xFF, + 0xD0,0xFF,0xD2,0xFF,0xD4,0xFF,0xDA,0xFF,0xDB,0xFF,0xD9,0xFF, + 0xD6,0xFF,0xDD,0xFF,0xE3,0xFF,0xE2,0xFF,0xDB,0xFF,0xDB,0xFF, + 0xDF,0xFF,0xD9,0xFF,0xBD,0xFF,0x8B,0xFF,0xA3,0xFF,0xBD,0xFF, + 0xCF,0xFF,0xAA,0xFF,0xC0,0xFF,0xAA,0xFF,0xB7,0xFF,0xAA,0xFF, + 0xCD,0xFF,0xBA,0xFF,0xC0,0xFF,0xCC,0xFF,0xD1,0xFF,0xCE,0xFF, + 0xE0,0xFF,0xEB,0xFF,0xDF,0xFF,0xDD,0xFF,0xE3,0xFF,0xEB,0xFF, + 0xEE,0xFF,0xF4,0xFF,0xED,0xFF,0xF5,0xFF,0xF2,0xFF,0xF3,0xFF, + 0xF2,0xFF,0xEE,0xFF,0xF3,0xFF,0xEC,0xFF,0xF0,0xFF,0xE7,0xFF, + 0xDC,0xFF,0xE9,0xFF,0xF0,0xFF,0xEA,0xFF,0xEA,0xFF,0xDA,0xFF, + 0xE0,0xFF,0xDA,0xFF,0xE7,0xFF,0xE6,0xFF,0xE3,0xFF,0xE6,0xFF, + 0xE5,0xFF,0xE6,0xFF,0xE9,0xFF,0xE8,0xFF,0xEF,0xFF,0xED,0xFF, + 0xD6,0xFF,0xD5,0xFF,0xD1,0xFF,0xCE,0xFF,0xC5,0xFF,0xC4,0xFF, + 0xC4,0xFF,0xBD,0xFF,0xAE,0xFF,0xB7,0xFF,0xA6,0xFF,0xAB,0xFF, + 0xB0,0xFF,0xA4,0xFF,0x99,0xFF,0xA0,0xFF,0xA7,0xFF,0xA6,0xFF, + 0xA8,0xFF,0xA9,0xFF,0xA6,0xFF,0xA4,0xFF,0xA6,0xFF,0xB0,0xFF, + 0xA9,0xFF,0xAC,0xFF,0xB2,0xFF,0xB4,0xFF,0xB8,0xFF,0xB4,0xFF, + 0xB3,0xFF,0xB4,0xFF,0xBD,0xFF,0xBE,0xFF,0xB9,0xFF,0xBC,0xFF, + 0xC1,0xFF,0xC8,0xFF,0xC4,0xFF,0xC7,0xFF,0xC6,0xFF,0xCC,0xFF, + 0xCE,0xFF,0xD0,0xFF,0xC8,0xFF,0xD8,0xFF,0xDE,0xFF,0xDF,0xFF, + 0xE3,0xFF,0xDE,0xFF,0xDF,0xFF,0xE6,0xFF,0xE1,0xFF,0xED,0xFF, + 0xEA,0xFF,0xE9,0xFF,0xE7,0xFF,0xE8,0xFF,0xE7,0xFF,0xE9,0xFF, + 0xEA,0xFF,0xD3,0xFF,0xC0,0xFF,0xBE,0xFF,0xA9,0xFF,0xA1,0xFF, + 0x92,0xFF,0x86,0xFF,0x81,0xFF,0x76,0xFF,0x71,0xFF,0x77,0xFF, + 0x76,0xFF,0x75,0xFF,0x7D,0xFF,0x86,0xFF,0x80,0xFF,0x87,0xFF, + 0x95,0xFF,0xA4,0xFF,0xAB,0xFF,0xB5,0xFF,0xC0,0xFF,0xC9,0xFF, + 0xCE,0xFF,0xDD,0xFF,0xE4,0xFF,0xE7,0xFF,0xE7,0xFF,0xE7,0xFF, + 0xE8,0xFF,0xE9,0xFF,0xED,0xFF,0xF1,0xFF,0xFC,0xFF,0x04,0x00, + 0xFC,0xFF,0x00,0x00,0x06,0x00,0x08,0x00,0x11,0x00,0x15,0x00, + 0x19,0x00,0x1D,0x00,0x24,0x00,0x1D,0x00,0x26,0x00,0x30,0x00, + 0x34,0x00,0x29,0x00,0x30,0x00,0x27,0x00,0x21,0x00,0x26,0x00, + 0x2D,0x00,0x11,0x00,0xF1,0xFF,0xE8,0xFF,0xEE,0xFF,0xD9,0xFF, + 0xC0,0xFF,0xC6,0xFF,0xCB,0xFF,0xA3,0xFF,0xB4,0xFF,0xC4,0xFF, + 0xB1,0xFF,0xAF,0xFF,0xC7,0xFF,0xC0,0xFF,0xB8,0xFF,0xCC,0xFF, + 0xCF,0xFF,0xCB,0xFF,0xDF,0xFF,0xE6,0xFF,0xDE,0xFF,0xE3,0xFF, + 0xEF,0xFF,0xEE,0xFF,0xFC,0xFF,0xFA,0xFF,0xEE,0xFF,0xF2,0xFF, + 0xEC,0xFF,0xF0,0xFF,0xF2,0xFF,0xF7,0xFF,0xF9,0xFF,0xF5,0xFF, + 0xF4,0xFF,0xEC,0xFF,0xE7,0xFF,0xE8,0xFF,0xE3,0xFF,0xE9,0xFF, + 0xE1,0xFF,0xE1,0xFF,0xDA,0xFF,0xDF,0xFF,0xE4,0xFF,0xF0,0xFF, + 0xE9,0xFF,0xF5,0xFF,0xEF,0xFF,0xF2,0xFF,0xF5,0xFF,0xF7,0xFF, + 0xFA,0xFF,0xFE,0xFF,0xFE,0xFF,0xFC,0xFF,0xF6,0xFF,0xFF,0xFF, + 0xFD,0xFF,0x04,0x00,0xFE,0xFF,0x08,0x00,0x03,0x00,0x01,0x00, + 0xF9,0xFF,0xDC,0xFF,0xD8,0xFF,0xF8,0xFF,0xEF,0xFF,0xDA,0xFF, + 0xE7,0xFF,0xF0,0xFF,0xCE,0xFF,0x05,0x00,0x0F,0x00,0xFC,0xFF, + 0xFD,0xFF,0x21,0x00,0x0E,0x00,0x15,0x00,0x32,0x00,0x39,0x00, + 0x2E,0x00,0x36,0x00,0x3A,0x00,0x34,0x00,0x4A,0x00,0x4F,0x00, + 0x48,0x00,0x4D,0x00,0x47,0x00,0x40,0x00,0x42,0x00,0x43,0x00, + 0x44,0x00,0x49,0x00,0x4C,0x00,0x3C,0x00,0x35,0x00,0x36,0x00, + 0x31,0x00,0x2C,0x00,0x30,0x00,0x27,0x00,0x17,0x00,0x1E,0x00, + 0x14,0x00,0x12,0x00,0x1A,0x00,0x20,0x00,0x13,0x00,0x15,0x00, + 0x15,0x00,0x16,0x00,0x1B,0x00,0x12,0x00,0x1C,0x00,0x0F,0x00, + 0x0B,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0xF8,0xFF,0xFA,0xFF, + 0xF4,0xFF,0xF2,0xFF,0xF0,0xFF,0xF0,0xFF,0xE9,0xFF,0xEB,0xFF, + 0xE7,0xFF,0xE0,0xFF,0xE0,0xFF,0xD7,0xFF,0xDE,0xFF,0xE0,0xFF, + 0xDA,0xFF,0xD8,0xFF,0xD7,0xFF,0xCE,0xFF,0xD3,0xFF,0xD1,0xFF, + 0xCD,0xFF,0xCB,0xFF,0xCB,0xFF,0xC6,0xFF,0xC9,0xFF,0xC4,0xFF, + 0xC5,0xFF,0xC8,0xFF,0xBC,0xFF,0xC3,0xFF,0xBF,0xFF,0xBA,0xFF, + 0xB9,0xFF,0xC5,0xFF,0xBB,0xFF,0xBD,0xFF,0xBB,0xFF,0xBF,0xFF, + 0xC4,0xFF,0xC4,0xFF,0xC4,0xFF,0xC3,0xFF,0xBE,0xFF,0xC5,0xFF, + 0xC6,0xFF,0xCB,0xFF,0xCB,0xFF,0xCD,0xFF,0xCD,0xFF,0xCD,0xFF, + 0xCC,0xFF,0xCC,0xFF,0xD4,0xFF,0xD3,0xFF,0xDA,0xFF,0xD7,0xFF, + 0xD7,0xFF,0xD2,0xFF,0xD6,0xFF,0xD5,0xFF,0xD7,0xFF,0xD8,0xFF, + 0xD2,0xFF,0xD0,0xFF,0xC7,0xFF,0xCB,0xFF,0xCD,0xFF,0xC4,0xFF, + 0xC5,0xFF,0xC2,0xFF,0xBA,0xFF,0xB3,0xFF,0xB6,0xFF,0xAE,0xFF, + 0xBE,0xFF,0xC4,0xFF,0xC0,0xFF,0xBD,0xFF,0xC9,0xFF,0xC8,0xFF, + 0xCF,0xFF,0xCD,0xFF,0xD3,0xFF,0xCB,0xFF,0xD4,0xFF,0xDA,0xFF, + 0xDA,0xFF,0xE8,0xFF,0xEC,0xFF,0xE5,0xFF,0xE9,0xFF,0xE7,0xFF, + 0xED,0xFF,0xF2,0xFF,0xF5,0xFF,0xFD,0xFF,0xF9,0xFF,0xF8,0xFF, + 0xFA,0xFF,0xFF,0xFF,0x05,0x00,0x03,0x00,0x01,0x00,0x03,0x00, + 0x09,0x00,0xFB,0xFF,0x01,0x00,0x06,0x00,0x0C,0x00,0x03,0x00, + 0x03,0x00,0x02,0x00,0x08,0x00,0x07,0x00,0x05,0x00,0x08,0x00, + 0x01,0x00,0x00,0x00,0xF8,0xFF,0xFC,0xFF,0xFF,0xFF,0x00,0x00, + 0xFA,0xFF,0xF7,0xFF,0xF6,0xFF,0xF4,0xFF,0xEE,0xFF,0xEE,0xFF, + 0xE1,0xFF,0xEA,0xFF,0xDD,0xFF,0xC9,0xFF,0xBB,0xFF,0xBF,0xFF, + 0xBD,0xFF,0xB8,0xFF,0xBF,0xFF,0xC1,0xFF,0xB4,0xFF,0xB6,0xFF, + 0xB3,0xFF,0xB1,0xFF,0xB8,0xFF,0xC0,0xFF,0xB8,0xFF,0xBD,0xFF, + 0xBE,0xFF,0xC0,0xFF,0xC9,0xFF,0xCE,0xFF,0xD2,0xFF,0xCE,0xFF, + 0xCD,0xFF,0xD2,0xFF,0xD6,0xFF,0xD8,0xFF,0xD8,0xFF,0xDA,0xFF, + 0xDC,0xFF,0xDE,0xFF,0xDA,0xFF,0xDE,0xFF,0xDE,0xFF,0xE6,0xFF, + 0xE0,0xFF,0xDF,0xFF,0xDB,0xFF,0xDC,0xFF,0xD8,0xFF,0xDE,0xFF, + 0xDF,0xFF,0xE0,0xFF,0xDC,0xFF,0xDF,0xFF,0xD9,0xFF,0xDA,0xFF, + 0xE4,0xFF,0xEA,0xFF,0xE3,0xFF,0xDC,0xFF,0xE1,0xFF,0xDD,0xFF, + 0xDD,0xFF,0xD8,0xFF,0xE1,0xFF,0xD7,0xFF,0xDA,0xFF,0xD1,0xFF, + 0xCE,0xFF,0xC8,0xFF,0xC6,0xFF,0xC8,0xFF,0xBD,0xFF,0xB6,0xFF, + 0xBA,0xFF,0xB2,0xFF,0xA6,0xFF,0xA6,0xFF,0xA1,0xFF,0x9E,0xFF, + 0x9C,0xFF,0x99,0xFF,0x9D,0xFF,0xA2,0xFF,0x9C,0xFF,0x9D,0xFF, + 0xA2,0xFF,0xA4,0xFF,0xA8,0xFF,0xAF,0xFF,0xB8,0xFF,0xBF,0xFF, + 0xC1,0xFF,0xC7,0xFF,0xD0,0xFF,0xD0,0xFF,0xE4,0xFF,0xE3,0xFF, + 0xE6,0xFF,0xEB,0xFF,0xF4,0xFF,0xEA,0xFF,0xF0,0xFF,0xF1,0xFF, + 0xF8,0xFF,0xF9,0xFF,0xFF,0xFF,0x01,0x00,0xFB,0xFF,0xF1,0xFF, + 0xE8,0xFF,0xFD,0xFF,0xF6,0xFF,0xF1,0xFF,0xEF,0xFF,0x01,0x00, + 0xFA,0xFF,0xF7,0xFF,0xF7,0xFF,0xF5,0xFF,0xEE,0xFF,0xE6,0xFF, + 0xF4,0xFF,0xED,0xFF,0xE8,0xFF,0xF8,0xFF,0xEF,0xFF,0xEB,0xFF, + 0xE7,0xFF,0xE4,0xFF,0xE2,0xFF,0xE6,0xFF,0xE3,0xFF,0xE7,0xFF, + 0xE8,0xFF,0xE0,0xFF,0xDD,0xFF,0xDD,0xFF,0xDD,0xFF,0xE9,0xFF, + 0xDA,0xFF,0xDA,0xFF,0xE3,0xFF,0xE2,0xFF,0xDC,0xFF,0xD8,0xFF, + 0xD7,0xFF,0xD1,0xFF,0xCD,0xFF,0xC9,0xFF,0xC4,0xFF,0xC2,0xFF, + 0xC3,0xFF,0xC4,0xFF,0xC3,0xFF,0xCD,0xFF,0xCD,0xFF,0xCA,0xFF, + 0xCB,0xFF,0xCC,0xFF,0xD1,0xFF,0xD7,0xFF,0xDB,0xFF,0xDD,0xFF, + 0xDE,0xFF,0xDC,0xFF,0xDB,0xFF,0xDC,0xFF,0xD8,0xFF,0xD9,0xFF, + 0xDE,0xFF,0xD7,0xFF,0xDB,0xFF,0xDB,0xFF,0xD8,0xFF,0xDA,0xFF, + 0xD9,0xFF,0xDC,0xFF,0xDD,0xFF,0xD9,0xFF,0xD6,0xFF,0xDA,0xFF, + 0xDB,0xFF,0xD8,0xFF,0xD9,0xFF,0xDA,0xFF,0xD8,0xFF,0xD4,0xFF, + 0xD9,0xFF,0xDE,0xFF,0xDF,0xFF,0xE1,0xFF,0xE3,0xFF,0xE5,0xFF, + 0xDD,0xFF,0xDF,0xFF,0xE3,0xFF,0xE4,0xFF,0xE2,0xFF,0xE3,0xFF, + 0xE8,0xFF,0xE5,0xFF,0xE3,0xFF,0xEC,0xFF,0x9C,0xFF,0x75,0xFF, + 0x9A,0x00,0x38,0xFF,0x6B,0x00,0x96,0xFF,0x05,0x00,0xE9,0xFF, + 0x03,0x00,0xE9,0xFF,0xD1,0xFF,0xFB,0xFF,0xE1,0xFF,0x0C,0x00, + 0xF7,0xFF,0xF1,0xFF,0xE5,0xFF,0xDC,0xFF,0xEC,0xFF,0xE2,0xFF, + 0xF7,0xFF,0xE9,0xFF,0xF6,0xFF,0xED,0xFF,0xEB,0xFF,0xDB,0xFF, + 0xE9,0xFF,0xE2,0xFF,0xFE,0xFF,0xF0,0xFF,0xF0,0xFF,0xED,0xFF, + 0xFB,0xFF,0xF3,0xFF,0x06,0x00,0xE0,0xFF,0x00,0x00,0x06,0x00, + 0xE7,0xFF,0x02,0x00,0xFB,0xFF,0xF1,0xFF,0x1A,0x00,0xDC,0xFF, + 0xF2,0xFF,0xCC,0xFF,0x2F,0x00,0xF4,0xFF,0xC2,0xFF,0xE0,0xFF, + 0xEB,0xFF,0xD8,0xFF,0xF5,0xFF,0xC2,0xFF,0xDB,0xFF,0x09,0x00, + 0x13,0x00,0xFE,0xFF,0x08,0x00,0xDF,0xFF,0xFA,0xFF,0xBD,0xFF, + 0x03,0x00,0x8F,0xFF,0xBC,0xFF,0x92,0xFF,0xF2,0xFF,0xFA,0xFF, + 0x26,0x00,0x96,0xFF,0x1B,0x00,0xB6,0xFF,0x02,0x00,0xD2,0xFF, + 0xD0,0xFF,0xF0,0xFF,0xCB,0xFF,0xE9,0xFF,0xD3,0xFF,0xAB,0xFF, + 0xD3,0xFF,0xA4,0xFF,0x08,0x00,0x7F,0xFF,0xEF,0xFF,0x96,0xFF, + 0x05,0x00,0x89,0xFF,0xB5,0xFF,0xFD,0xFF,0xC4,0xFF,0xCC,0xFF, + 0xF2,0xFF,0xB8,0xFF,0x0A,0x00,0x6D,0xFF,0x49,0x00,0x98,0xFF, + 0x02,0x00,0xE0,0xFF,0xC4,0xFF,0xBB,0xFF,0xF5,0xFF,0xA9,0xFF, + 0xC9,0xFF,0x8D,0xFF,0xDE,0xFF,0xCC,0xFF,0xE9,0xFF,0x23,0x00, + 0x84,0xFF,0x08,0x00,0x99,0xFF,0x1F,0x00,0x85,0xFF,0x4F,0x00, + 0xCD,0xFF,0xD1,0xFF,0x25,0x00,0x85,0xFF,0x37,0x00,0x6B,0xFF, + 0x48,0x00,0xD6,0xFF,0x3F,0x00,0xC8,0xFF,0xE6,0xFF,0xC6,0xFF, + 0x0C,0x00,0x04,0x00,0xB9,0xFF,0xA5,0xFF,0x23,0x00,0xC0,0xFF, + 0xD9,0xFF,0xDD,0xFF,0x0E,0x00,0xC1,0xFF,0x0B,0x00,0x9D,0xFF, + 0x30,0x00,0xD5,0xFF,0xAD,0xFF,0x1C,0x00,0x81,0xFF,0x88,0x00, + 0x53,0xFF,0x0D,0x00,0xC0,0xFF,0x5D,0x00,0xC9,0xFF,0x1D,0x00, + 0x2C,0x00,0x1E,0x00,0xA0,0xFF,0x11,0x00,0xE2,0xFF,0xEF,0xFF, + 0x10,0x00,0xE3,0xFF,0x37,0x00,0xF3,0xFF,0xF0,0xFF,0x0F,0x00, + 0xFE,0xFF,0x92,0x00,0xB7,0xFF,0x5E,0x00,0x98,0xFF,0x48,0x00, + 0x48,0x00,0xAC,0xFF,0x52,0x00,0x25,0x00,0x02,0x00,0xDF,0xFF, + 0xEB,0xFF,0x15,0x00,0x03,0x00,0x08,0x00,0x10,0x00,0x18,0x00, + 0x70,0x00,0x84,0xFF,0xE1,0xFF,0xF4,0xFF,0x20,0x00,0xBA,0xFF, + 0xFE,0xFF,0xCE,0xFF,0x45,0x00,0x18,0x00,0x8F,0x00,0xE4,0xFF, + 0x0C,0x00,0xC5,0xFF,0xCC,0xFF,0x49,0x00,0xF3,0xFF,0x1D,0x00, + 0xDA,0xFF,0xBF,0xFF,0x4E,0x00,0x2F,0x00,0x7B,0xFF,0x27,0x00, + 0xE5,0xFF,0xB9,0x00,0x40,0xFF,0x4A,0x00,0x7A,0xFF,0xDD,0x00, + 0x64,0xFF,0x59,0x00,0x38,0xFF,0x91,0x00,0x63,0xFF,0x91,0x00, + 0x6C,0xFF,0xF2,0xFF,0x46,0x00,0x17,0x00,0xEE,0xFF,0x4B,0xFF, + 0x63,0x00,0x7B,0xFF,0x47,0x00,0x40,0xFF,0x7A,0x00,0x17,0xFF, + 0xD2,0x00,0x57,0xFF,0x18,0x00,0xFE,0xFF,0xCA,0xFF,0xE4,0xFF, + 0x0C,0xFF,0x05,0x01,0xD0,0xFF,0x28,0x00,0x29,0xFF,0x5C,0x00, + 0x38,0xFF,0xEE,0x00,0x7A,0xFF,0x3E,0x00,0xD7,0xFF,0x5C,0x00, + 0x93,0x00,0xBB,0xFF,0x59,0x00,0xEA,0xFF,0xA4,0x00,0x05,0xFF, + 0x64,0x01,0xB5,0xFE,0x68,0x00,0x89,0xFF,0xB2,0x00,0x52,0xFF, + 0x75,0xFF,0xC3,0x00,0x62,0xFF,0x7C,0x00,0x9F,0xFE,0x23,0x01, + 0xB0,0xFE,0xF6,0x00,0xE5,0xFF,0x4D,0x00,0xC4,0xFF,0x40,0x00, + 0xFE,0xFF,0xE9,0xFE,0xC2,0x00,0xFD,0xFE,0x1F,0x01,0xFD,0xFE, + 0x1C,0x01,0x2C,0xFF,0x6C,0x01,0xC1,0xFF,0x6B,0x00,0xFB,0xFF, + 0x53,0x00,0xC9,0x00,0x22,0xFF,0x78,0x00,0x4B,0xFF,0x69,0x00, + 0x87,0xFF,0xA3,0x00,0xC9,0xFF,0x40,0x00,0xE3,0xFF,0x1A,0x00, + 0x23,0x00,0x77,0xFF,0x35,0x01,0xBF,0xFF,0xDA,0x00,0x5F,0xFF, + 0x7C,0x00,0x86,0xFF,0x99,0x00,0xBC,0xFF,0x31,0x00,0x90,0xFF, + 0x40,0x00,0x38,0xFF,0xDB,0x00,0x16,0x00,0x85,0x00,0x9E,0xFF, + 0x19,0x00,0xFF,0xFF,0xFA,0xFF,0x2F,0x00,0xBC,0xFF,0x2A,0x00, + 0xF9,0xFF,0xB7,0xFF,0xC7,0x00,0x54,0xFF,0xE1,0x00,0xA0,0xFF, + 0xCE,0x00,0xA3,0xFF,0xA3,0x00,0x22,0x00,0x05,0x00,0x01,0x00, + 0x3A,0xFF,0xC0,0x00,0x86,0xFF,0x5E,0x00,0xA0,0xFF,0x07,0x00, + 0x29,0x00,0xC4,0xFF,0xCC,0x00,0x4E,0xFF,0x56,0x00,0x18,0x00, + 0xC7,0xFF,0xFB,0xFF,0x65,0xFF,0x0E,0x00,0xAF,0xFF,0x05,0x00, + 0xE3,0xFF,0xB7,0xFF,0x1A,0x00,0x90,0xFF,0xA9,0x00,0xA4,0xFF, + 0x5F,0x00,0xD9,0xFE,0xE9,0x00,0xEA,0xFF,0x5C,0x00,0x85,0xFF, + 0x35,0x00,0x2C,0x00,0x89,0xFF,0x29,0x00,0xD0,0xFF,0xAE,0x00, + 0x00,0xFF,0x91,0x00,0x09,0xFF,0x0C,0x01,0x6D,0xFE,0x72,0x00, + 0x15,0xFF,0x0B,0x01,0x93,0xFE,0xAA,0x00,0xC4,0xFE,0x6A,0x00, + 0xC3,0xFE,0xD3,0x00,0x8B,0xFE,0xDF,0xFF,0xAB,0xFF,0x06,0x00, + 0x32,0xFF,0x47,0xFF,0x13,0x00,0x33,0xFF,0xD1,0xFF,0xB9,0xFF, + 0x79,0x00,0x33,0xFF,0xFE,0xFF,0x03,0xFF,0x4C,0x00,0xBD,0xFE, + 0x23,0x00,0x3E,0xFF,0xB7,0xFF,0xCE,0xFF,0x1F,0xFF,0x1B,0x00, + 0xEF,0xFE,0x16,0x00,0xDE,0xFE,0x14,0x00,0xA2,0xFF,0x42,0xFF, + 0xD7,0xFF,0x0F,0xFF,0x72,0x00,0x1A,0xFF,0x87,0x00,0x80,0xFE, + 0x52,0x00,0xD4,0xFE,0x37,0x00,0xD2,0xFE,0x76,0xFF,0xDF,0xFF, + 0x00,0xFF,0xD5,0xFF,0xD8,0xFE,0xC3,0x00,0xC9,0xFE,0xBF,0x00, + 0x0F,0xFF,0x12,0x00,0x7C,0xFE,0x68,0x00,0x37,0xFE,0xFA,0xFF, + 0x56,0xFF,0x6D,0xFF,0x2C,0xFF,0x69,0xFE,0x4B,0x00,0xA6,0xFE, + 0xCD,0xFF,0xA3,0xFE,0xF3,0x00,0xFF,0xFD,0xFE,0x00,0x4E,0xFE, + 0x08,0x00,0xC0,0xFE,0x67,0x00,0x54,0x00,0x87,0xFE,0xBE,0xFF, + 0xDD,0xFE,0xAB,0x00,0x25,0xFE,0xD9,0x00,0x1D,0xFE,0xA7,0xFF, + 0x1F,0xFF,0x91,0xFF,0xD0,0xFE,0x2A,0xFE,0x22,0x00,0x1F,0xFE, + 0xC1,0x00,0x31,0xFE,0x52,0x00,0xF4,0xFD,0xB5,0x00,0x77,0xFF, + 0x29,0xFF,0xBC,0xFF,0x1A,0xFF,0x18,0x00,0xD7,0xFD,0xD6,0x00, + 0xD1,0xFD,0xD2,0x00,0xA6,0xFE,0x23,0x00,0xCB,0xFE,0x08,0x00, + 0x4C,0x00,0x61,0xFE,0x4D,0x00,0x18,0xFE,0xC3,0x00,0x0F,0xFE, + 0x5D,0x00,0x56,0xFE,0xA8,0xFE,0xD8,0xFF,0x43,0xFE,0x49,0x00, + 0xCB,0xFD,0x0D,0x01,0xA7,0xFD,0x24,0x01,0xDB,0xFE,0x39,0x00, + 0xD4,0xFE,0xC8,0xFF,0xA1,0x00,0x3D,0xFE,0x8A,0x00,0x88,0xFE, + 0x5E,0x00,0x6C,0xFE,0xCF,0xFF,0x89,0xFE,0x2F,0xFF,0x5C,0x00, + 0x8A,0xFE,0xC5,0xFF,0xFE,0xFE,0x8D,0x00,0x78,0xFE,0x20,0x00, + 0xA4,0xFE,0xEB,0xFF,0x96,0xFF,0x70,0xFF,0x4B,0xFF,0x13,0xFF, + 0x97,0xFF,0xF1,0xFE,0xAC,0xFF,0x5D,0xFF,0xA9,0xFF,0x08,0xFF, + 0xB8,0xFF,0x45,0x00,0x08,0xFF,0x39,0x00,0x6A,0xFE,0x88,0x00, + 0xB3,0xFE,0x46,0x00,0xCE,0xFE,0xE7,0xFE,0x55,0x00,0xEE,0xFE, + 0x94,0x00,0xCE,0xFE,0x47,0x00,0x1A,0xFF,0x3C,0x00,0x6C,0x00, + 0x33,0xFF,0x8E,0x00,0x48,0xFF,0x15,0x00,0xCE,0xFE,0xE0,0x00, + 0x01,0xFF,0xAF,0x00,0xE0,0xFF,0xB0,0xFF,0x4E,0x00,0x53,0xFF, + 0x6F,0x00,0x08,0xFF,0x88,0x00,0x0D,0xFF,0xC9,0xFF,0x14,0x00, + 0xFC,0xFF,0x36,0x00,0x95,0xFE,0xB6,0x00,0xD3,0xFE,0xC5,0x00, + 0xA1,0xFF,0x75,0x00,0x89,0xFF,0x48,0x00,0x7D,0x00,0x96,0xFF, + 0x44,0x00,0x19,0xFF,0x8A,0x00,0x68,0xFF,0xB3,0x00,0x5E,0xFF, + 0x4F,0xFF,0x59,0x00,0xAC,0xFF,0xC5,0x00,0xED,0xFE,0x2D,0x01, + 0x9A,0xFE,0x50,0x01,0x07,0xFF,0xB0,0xFF,0x71,0x00,0x18,0xFF, + 0x25,0x01,0x91,0xFE,0x57,0x01,0x7E,0xFE,0x19,0x01,0x51,0x00, + 0x27,0x00,0x41,0x00,0xA7,0xFF,0x40,0x01,0xC7,0xFE,0x68,0x01, + 0x18,0xFF,0x2F,0x00,0x68,0x00,0xCF,0xFF,0x60,0x00,0xEB,0xFE, + 0x0B,0x01,0x15,0xFF,0x04,0x01,0x4F,0x00,0x04,0x00,0x01,0x01, + 0x8A,0xFF,0x94,0x01,0xB2,0xFE,0x8F,0x01,0xA6,0xFE,0x42,0x00, + 0x77,0x00,0x04,0x00,0x03,0x01,0x42,0xFE,0xBC,0x01,0xB3,0xFE, + 0xB6,0x01,0x74,0xFE,0x3D,0x00,0x85,0x00,0x0E,0x00,0xD1,0x00, + 0x85,0xFE,0xA9,0x01,0xD3,0xFE,0x98,0x01,0x6D,0x00,0xE2,0xFF, + 0xF5,0x00,0x8F,0xFF,0xB2,0x01,0xE0,0xFE,0x86,0x01,0x51,0xFF, + 0xEE,0xFF,0xE7,0x00,0xBF,0xFF,0x45,0x01,0x32,0xFF,0x47,0x01, + 0x9C,0xFF,0xE5,0x00,0x0A,0x01,0x92,0xFF,0xE0,0x00,0x4F,0xFF, + 0xF7,0x00,0xC0,0xFF,0x04,0x01,0x77,0xFF,0x3D,0x00,0x77,0x00, + 0x02,0x00,0xDE,0x00,0xE8,0xFF,0x07,0x01,0xD9,0xFF,0x04,0x01, + 0xD0,0xFF,0x90,0xFF,0x74,0x01,0x76,0xFF,0xA7,0x01,0x1C,0xFF, + 0x37,0x01,0xDB,0xFF,0xFC,0x00,0x74,0x01,0xE6,0xFE,0xEF,0x01, + 0x92,0xFE,0x34,0x01,0xD9,0xFF,0x14,0x00,0x86,0x00,0x6C,0xFE, + 0x0D,0x02,0xA8,0xFE,0x89,0x01,0x51,0x00,0xD9,0xFF,0x13,0x01, + 0x99,0xFF,0x99,0x01,0x1E,0xFF,0x18,0x01,0x88,0xFF,0x97,0xFF, + 0xF9,0x00,0x2F,0xFF,0x4E,0x01,0xED,0xFF,0x15,0x00,0xA1,0x00, + 0x78,0xFF,0x15,0x01,0x44,0xFF,0x11,0x01,0x89,0xFF,0x85,0x00, + 0x00,0x01,0x01,0xFF,0x3D,0x01,0x40,0xFF,0x57,0x00,0x73,0x00, + 0x86,0xFF,0xDF,0x00,0xAD,0xFE,0x40,0x01,0x26,0xFF,0xD3,0x00, + 0xBB,0x00,0xFE,0xFE,0x49,0x01,0x48,0xFF,0x42,0x00,0x0A,0x00, + 0x95,0xFF,0x9D,0x00,0x5C,0xFF,0xA0,0x00,0xBA,0xFF,0x0C,0x00, + 0xA8,0x00,0x41,0xFF,0xA5,0x00,0x7E,0xFF,0x6F,0xFF,0x87,0x00, + 0x38,0xFF,0xC6,0x00,0x07,0x00,0xBE,0xFF,0xDE,0x00,0x09,0xFF, + 0xE7,0x00,0x3E,0xFF,0x3E,0x00,0xDE,0xFF,0xC3,0xFF,0xC2,0x00, + 0x37,0xFF,0x22,0x00,0xE5,0xFF,0x6D,0xFF,0x3C,0x00,0xEF,0xFF, + 0xD0,0xFF,0x90,0x00,0x81,0xFF,0x46,0x00,0x0B,0x00,0x42,0xFF, + 0x77,0x00,0x4D,0xFF,0x76,0x00,0xFD,0xFF,0x99,0xFF,0x26,0x00, + 0x75,0xFF,0x48,0x00,0xA8,0xFF,0x98,0xFF,0xEF,0xFF,0xDA,0xFF, + 0x9F,0xFF,0xE9,0xFF,0x6C,0xFF,0xD4,0xFF,0xED,0xFF,0xC8,0xFF, + 0x34,0x00,0x57,0xFF,0x3C,0x00,0xBF,0xFF,0xC0,0xFF,0xAB,0xFF, + 0xEB,0xFF,0x93,0xFF,0x4B,0x00,0x8A,0xFF,0xED,0xFF,0xE8,0xFF, + 0xD8,0xFF,0x17,0x00,0x7A,0xFF,0x4A,0x00,0xDF,0xFF,0xDF,0xFF, + 0x08,0x00,0xB1,0xFF,0x0F,0x00,0xF5,0xFF,0xFF,0xFF,0xD7,0xFF, + 0x32,0x00,0xA8,0xFF,0xF3,0xFF,0x00,0x00,0xDF,0xFF,0x28,0x00, + 0xCF,0xFF,0x36,0x00,0xC1,0xFF,0xEE,0xFF,0x00,0x00,0xFD,0xFF, + 0xEB,0xFF,0xDE,0xFF,0xC1,0xFF,0x28,0x00,0xC4,0xFF,0x3B,0x00, + 0x96,0xFF,0x2F,0x00,0xB4,0xFF,0x1F,0x00,0xBA,0xFF,0xCF,0xFF, + 0x1D,0x00,0xB2,0xFF,0x30,0x00,0x91,0xFF,0x13,0x00,0xB2,0xFF, + 0x0D,0x00,0x12,0x00,0xB0,0xFF,0x29,0x00,0x92,0xFF,0x0B,0x00, + 0xBA,0xFF,0x14,0x00,0xBE,0xFF,0xB6,0xFF,0xF6,0xFF,0x9C,0xFF, + 0x08,0x00,0xBA,0xFF,0xEC,0xFF,0xD2,0xFF,0xD0,0xFF,0xEF,0xFF, + 0xBB,0xFF,0xED,0xFF,0xBB,0xFF,0xFA,0xFF,0xC1,0xFF,0xE2,0xFF, + 0xC2,0xFF,0xEE,0xFF,0xC8,0xFF,0xF3,0xFF,0xB9,0xFF,0xDE,0xFF, + 0xCE,0xFF,0xCB,0xFF,0xEF,0xFF,0xC9,0xFF,0xCF,0xFF,0xCA,0xFF, + 0xCC,0xFF,0xC4,0xFF,0xBC,0xFF,0xBA,0xFF,0xD9,0xFF,0x93,0xFF, + 0xD1,0xFF,0xA6,0xFF,0xB7,0xFF,0xBB,0xFF,0xBF,0xFF,0xC0,0xFF, + 0xA1,0xFF,0xC0,0xFF,0xB3,0xFF,0xB8,0xFF,0xBE,0xFF,0xB4,0xFF, + 0xB9,0xFF,0xAB,0xFF,0xBA,0xFF,0xA3,0xFF,0xBA,0xFF,0xC9,0xFF, + 0xB4,0xFF,0xB5,0xFF,0xAF,0xFF,0xBB,0xFF,0xA5,0xFF,0xE3,0xFF, + 0xC5,0xFF,0xC5,0xFF,0xC5,0xFF,0xA7,0xFF,0xC7,0xFF,0x9D,0xFF, + 0xEB,0xFF,0xAE,0xFF,0xE6,0xFF,0xC5,0xFF,0xB7,0xFF,0xC8,0xFF, + 0xB8,0xFF,0xE3,0xFF,0xB6,0xFF,0xE0,0xFF,0xA7,0xFF,0xCB,0xFF, + 0xB3,0xFF,0xD4,0xFF,0xBE,0xFF,0xB3,0xFF,0xE4,0xFF,0xAE,0xFF, + 0xEF,0xFF,0xC1,0xFF,0xDE,0xFF,0xD0,0xFF,0xE4,0xFF,0xE4,0xFF, + 0xBE,0xFF,0xE3,0xFF,0xC1,0xFF,0xE6,0xFF,0xCA,0xFF,0xE4,0xFF, + 0xE0,0xFF,0xC5,0xFF,0xFE,0xFF,0xC2,0xFF,0x07,0x00,0xF3,0xFF, + 0xDE,0xFF,0xF4,0xFF,0xCC,0xFF,0xFD,0xFF,0xCF,0xFF,0xF1,0xFF, + 0xDD,0xFF,0xE4,0xFF,0xF1,0xFF,0xD3,0xFF,0xE2,0xFF,0xE5,0xFF, + 0xD8,0xFF,0xF1,0xFF,0xD8,0xFF,0xE1,0xFF,0xE9,0xFF,0xC8,0xFF, + 0xFB,0xFF,0xCE,0xFF,0xE3,0xFF,0xEA,0xFF,0xCE,0xFF,0xE2,0xFF, + 0xC6,0xFF,0xE1,0xFF,0xD8,0xFF,0xDF,0xFF,0xF1,0xFF,0xD1,0xFF, + 0xE1,0xFF,0xDA,0xFF,0xD2,0xFF,0xDD,0xFF,0xE1,0xFF,0xE1,0xFF, + 0xF1,0xFF,0xDB,0xFF,0xF1,0xFF,0xE2,0xFF,0xDE,0xFF,0xF0,0xFF, + 0xDC,0xFF,0xE2,0xFF,0xD6,0xFF,0xD5,0xFF,0xF1,0xFF,0xE3,0xFF, + 0xE5,0xFF,0xED,0xFF,0xD5,0xFF,0xD9,0xFF,0xC4,0xFF,0xE4,0xFF, + 0xE2,0xFF,0xD6,0xFF,0xD1,0xFF,0xDB,0xFF,0xC5,0xFF,0xD5,0xFF, + 0xCA,0xFF,0xCB,0xFF,0xD6,0xFF,0xCE,0xFF,0xD0,0xFF,0xBC,0xFF, + 0xC9,0xFF,0xD4,0xFF,0xD6,0xFF,0xD4,0xFF,0xD7,0xFF,0xCB,0xFF, + 0xD0,0xFF,0xC9,0xFF,0xD4,0xFF,0xD9,0xFF,0xD7,0xFF,0xD7,0xFF, + 0xD6,0xFF,0xD1,0xFF,0xD7,0xFF,0xDB,0xFF,0xD4,0xFF,0xDF,0xFF, + 0xCC,0xFF,0xD7,0xFF,0xD8,0xFF,0xD9,0xFF,0xDA,0xFF,0xE0,0xFF, + 0xDA,0xFF,0xD1,0xFF,0xCE,0xFF,0xD0,0xFF,0xD7,0xFF,0xD9,0xFF, + 0xD3,0xFF,0xD3,0xFF,0xD4,0xFF,0xD0,0xFF,0xD6,0xFF,0xDB,0xFF, + 0xD2,0xFF,0xE1,0xFF,0xC5,0xFF,0xD6,0xFF,0xDA,0xFF,0xC9,0xFF, + 0xE7,0xFF,0xD9,0xFF,0xE0,0xFF,0xCD,0xFF,0xD5,0xFF,0xE3,0xFF, + 0xE2,0xFF,0xF3,0xFF,0xE8,0xFF,0xE6,0xFF,0xE8,0xFF,0xE4,0xFF, + 0xF1,0xFF,0xF1,0xFF,0xEE,0xFF,0xE8,0xFF,0xDE,0xFF,0xDA,0xFF, + 0xE5,0xFF,0xF2,0xFF,0xF5,0xFF,0xF2,0xFF,0xDC,0xFF,0xE0,0xFF, + 0xDA,0xFF,0xE3,0xFF,0xE6,0xFF,0xF5,0xFF,0xE3,0xFF,0xE4,0xFF, + 0xE3,0xFF,0xE6,0xFF,0xE3,0xFF,0xE4,0xFF,0xDD,0xFF,0xE6,0xFF, + 0xD2,0xFF,0xD8,0xFF,0xDF,0xFF,0xD6,0xFF,0xF0,0xFF,0xE2,0xFF, + 0xDC,0xFF,0xDE,0xFF,0xCF,0xFF,0xE1,0xFF,0xD5,0xFF,0xDF,0xFF, + 0xDA,0xFF,0xD6,0xFF,0xCF,0xFF,0xD3,0xFF,0xC9,0xFF,0xDC,0xFF, + 0xCE,0xFF,0xD0,0xFF,0xCB,0xFF,0xCA,0xFF,0xD0,0xFF,0xCB,0xFF, + 0xD9,0xFF,0xD6,0xFF,0xCE,0xFF,0xCF,0xFF,0xC8,0xFF,0xBF,0xFF, + 0xD6,0xFF,0xC9,0xFF,0xD6,0xFF,0xD5,0xFF,0xC5,0xFF,0xD4,0xFF, + 0xC5,0xFF,0xDD,0xFF,0xDA,0xFF,0xD4,0xFF,0xD8,0xFF,0xBF,0xFF, + 0xD5,0xFF,0xCE,0xFF,0xD0,0xFF,0xD1,0xFF,0xC7,0xFF,0xCD,0xFF, + 0xD1,0xFF,0xCA,0xFF,0xCA,0xFF,0xD3,0xFF,0xCD,0xFF,0xCC,0xFF, + 0xCD,0xFF,0xC9,0xFF,0xD5,0xFF,0xD1,0xFF,0xDC,0xFF,0xD1,0xFF, + 0xE3,0xFF,0xCD,0xFF,0xDA,0xFF,0xD7,0xFF,0xE1,0xFF,0xE3,0xFF, + 0xD1,0xFF,0xE9,0xFF,0xC7,0xFF,0xD3,0xFF,0xD9,0xFF,0xCA,0xFF, + 0xE0,0xFF,0xDD,0xFF,0xE6,0xFF,0xE9,0xFF,0xE8,0xFF,0xE6,0xFF, + 0xE8,0xFF,0xE8,0xFF,0xEE,0xFF,0xEA,0xFF,0xF1,0xFF,0xEF,0xFF, + 0xEE,0xFF,0xF5,0xFF,0xF2,0xFF,0xF3,0xFF,0xFF,0xFF,0xF8,0xFF, + 0xF3,0xFF,0x01,0x00,0xF3,0xFF,0x03,0x00,0xF9,0xFF,0xFA,0xFF, + 0xF8,0xFF,0xF6,0xFF,0xF9,0xFF,0x00,0x00,0x04,0x00,0x0D,0x00, + 0xFE,0xFF,0x0E,0x00,0x06,0x00,0x0D,0x00,0x13,0x00,0xFE,0xFF, + 0x0D,0x00,0x01,0x00,0xFC,0xFF,0x10,0x00,0x0D,0x00,0x13,0x00, + 0x15,0x00,0x14,0x00,0x1B,0x00,0x16,0x00,0x0D,0x00,0x18,0x00, + 0x11,0x00,0x23,0x00,0x11,0x00,0x0E,0x00,0x16,0x00,0x0D,0x00, + 0x16,0x00,0x0E,0x00,0x11,0x00,0x15,0x00,0x0C,0x00,0x0D,0x00, + 0x12,0x00,0x0C,0x00,0x13,0x00,0x0C,0x00,0x16,0x00,0x16,0x00, + 0x19,0x00,0x14,0x00,0x19,0x00,0x17,0x00,0x17,0x00,0x17,0x00, + 0x0C,0x00,0x1C,0x00,0x0C,0x00,0x10,0x00,0x0E,0x00,0x00,0x00, + 0x09,0x00,0x03,0x00,0x0B,0x00,0x0E,0x00,0x02,0x00,0x05,0x00, + 0x0A,0x00,0xFD,0xFF,0x02,0x00,0x06,0x00,0xFB,0xFF,0x04,0x00, + 0xF9,0xFF,0xF8,0xFF,0xFE,0xFF,0xF5,0xFF,0xFF,0xFF,0xF9,0xFF, + 0xFC,0xFF,0xF0,0xFF,0xF0,0xFF,0xF3,0xFF,0xF7,0xFF,0xF1,0xFF, + 0xF1,0xFF,0xF0,0xFF,0xEE,0xFF,0xE6,0xFF,0xDB,0xFF,0xE7,0xFF, + 0xED,0xFF,0xED,0xFF,0xEC,0xFF,0xE2,0xFF,0xE9,0xFF,0xDF,0xFF, + 0xE0,0xFF,0xE7,0xFF,0xE6,0xFF,0xE5,0xFF,0xDE,0xFF,0xDC,0xFF, + 0xE1,0xFF,0xDB,0xFF,0xDB,0xFF,0xD8,0xFF,0xD0,0xFF,0xCF,0xFF, + 0xD5,0xFF,0xD8,0xFF,0xD9,0xFF,0xD1,0xFF,0xD1,0xFF,0xCF,0xFF, + 0xCE,0xFF,0xCC,0xFF,0xCB,0xFF,0xD4,0xFF,0xCC,0xFF,0xD4,0xFF, + 0xCC,0xFF,0xC4,0xFF,0xBC,0xFF,0xBF,0xFF,0xBD,0xFF,0xC8,0xFF, + 0xC4,0xFF,0xBF,0xFF,0xC3,0xFF,0xBE,0xFF,0xC6,0xFF,0xC0,0xFF, + 0xC2,0xFF,0xC2,0xFF,0xBF,0xFF,0xBF,0xFF,0xC0,0xFF,0xCC,0xFF, + 0xCA,0xFF,0xCA,0xFF,0xC5,0xFF,0xC6,0xFF,0xC9,0xFF,0xC7,0xFF, + 0xCB,0xFF,0xC8,0xFF,0xCC,0xFF,0xCD,0xFF,0xC9,0xFF,0xC8,0xFF, + 0xC9,0xFF,0xCC,0xFF,0xC9,0xFF,0xCC,0xFF,0xC9,0xFF,0xCD,0xFF, + 0xC5,0xFF,0xC7,0xFF,0xD1,0xFF,0xC7,0xFF,0xCB,0xFF,0xC9,0xFF, + 0xC3,0xFF,0xBE,0xFF,0xC1,0xFF,0xC1,0xFF,0xC5,0xFF,0xC5,0xFF, + 0xBE,0xFF,0xC3,0xFF,0xC2,0xFF,0xBE,0xFF,0xBB,0xFF,0xCA,0xFF, + 0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xB3,0xFF,0xC7,0xFF,0xBE,0xFF, + 0xC5,0xFF,0xC5,0xFF,0xBD,0xFF,0xB5,0xFF,0xB4,0xFF,0xB3,0xFF, + 0xB7,0xFF,0xBB,0xFF,0xC0,0xFF,0xB6,0xFF,0xBB,0xFF,0xBE,0xFF, + 0xBA,0xFF,0xB7,0xFF,0xBA,0xFF,0xB5,0xFF,0xBE,0xFF,0xB4,0xFF, + 0xBA,0xFF,0xBA,0xFF,0xBB,0xFF,0xB5,0xFF,0xB5,0xFF,0xB2,0xFF, + 0xB7,0xFF,0xBC,0xFF,0xB3,0xFF,0xBA,0xFF,0xB4,0xFF,0xB9,0xFF, + 0xAC,0xFF,0xAF,0xFF,0xBB,0xFF,0xB9,0xFF,0xB0,0xFF,0xB5,0xFF, + 0xA8,0xFF,0xAD,0xFF,0xB0,0xFF,0xAE,0xFF,0xB0,0xFF,0xAC,0xFF, + 0xB4,0xFF,0xAD,0xFF,0xB2,0xFF,0xAD,0xFF,0xBD,0xFF,0xB5,0xFF, + 0xC3,0xFF,0xB5,0xFF,0xBA,0xFF,0xBF,0xFF,0xB0,0xFF,0xBF,0xFF, + 0xBE,0xFF,0xC3,0xFF,0xC6,0xFF,0xC4,0xFF,0xC3,0xFF,0xC1,0xFF, + 0xC3,0xFF,0xC2,0xFF,0xCB,0xFF,0xD1,0xFF,0xD4,0xFF,0xD0,0xFF, + 0xCD,0xFF,0xD6,0xFF,0xD4,0xFF,0xD8,0xFF,0xDA,0xFF,0xD0,0xFF, + 0xDD,0xFF,0xD4,0xFF,0xD8,0xFF,0xDC,0xFF,0xDA,0xFF,0xE2,0xFF, + 0xD7,0xFF,0xDC,0xFF,0xDA,0xFF,0xDA,0xFF,0xD8,0xFF,0xE9,0xFF, + 0xDA,0xFF,0xE0,0xFF,0xE2,0xFF,0xEA,0xFF,0xE8,0xFF,0xEE,0xFF, + 0xF3,0xFF,0xF5,0xFF,0xF8,0xFF,0xF6,0xFF,0xFE,0xFF,0xFF,0xFF, + 0x01,0x00,0x04,0x00,0x06,0x00,0x02,0x00,0xFD,0xFF,0x00,0x00, + 0x01,0x00,0x0D,0x00,0xFE,0xFF,0xFD,0xFF,0x08,0x00,0x01,0x00, + 0x05,0x00,0x04,0x00,0x07,0x00,0x04,0x00,0x06,0x00,0x0D,0x00, + 0x05,0x00,0x07,0x00,0x0C,0x00,0x09,0x00,0x0C,0x00,0x0C,0x00, + 0x15,0x00,0x0F,0x00,0x0D,0x00,0x0D,0x00,0x10,0x00,0x0E,0x00, + 0x06,0x00,0x0B,0x00,0x08,0x00,0x10,0x00,0x00,0x00,0x05,0x00, + 0x01,0x00,0x06,0x00,0xFF,0xFF,0x00,0x00,0x07,0x00,0x08,0x00, + 0xFF,0xFF,0x02,0x00,0x0A,0x00,0x00,0x00,0x04,0x00,0x02,0x00, + 0xFB,0xFF,0x05,0x00,0xFF,0xFF,0x03,0x00,0x03,0x00,0x00,0x00, + 0xF6,0xFF,0xF9,0xFF,0xFB,0xFF,0xFA,0xFF,0xF6,0xFF,0xF3,0xFF, + 0xFA,0xFF,0xF1,0xFF,0xEC,0xFF,0xF1,0xFF,0xF3,0xFF,0xEB,0xFF, + 0xF2,0xFF,0xF3,0xFF,0xF0,0xFF,0xF5,0xFF,0xE1,0xFF,0xEB,0xFF, + 0xEC,0xFF,0xE9,0xFF,0xEA,0xFF,0xE9,0xFF,0xDE,0xFF,0xEB,0xFF, + 0xE3,0xFF,0xE6,0xFF,0xE1,0xFF,0xEC,0xFF,0xDF,0xFF,0xEF,0xFF, + 0xE1,0xFF,0xE9,0xFF,0xE7,0xFF,0xEC,0xFF,0xE4,0xFF,0xE7,0xFF, + 0xDD,0xFF,0xE8,0xFF,0xE3,0xFF,0xEA,0xFF,0xE9,0xFF,0xDB,0xFF, + 0xE3,0xFF,0xD9,0xFF,0xDB,0xFF,0xD5,0xFF,0xE3,0xFF,0xD7,0xFF, + 0xDE,0xFF,0xDB,0xFF,0xDD,0xFF,0xE1,0xFF,0xE2,0xFF,0xE1,0xFF, + 0xE7,0xFF,0xEB,0xFF,0xE4,0xFF,0xE6,0xFF,0xE0,0xFF,0xE8,0xFF, + 0xE6,0xFF,0xDF,0xFF,0xDD,0xFF,0xE1,0xFF,0xD6,0xFF,0xDB,0xFF, + 0xD9,0xFF,0xDC,0xFF,0xE0,0xFF,0xDB,0xFF,0xDC,0xFF,0xE0,0xFF, + 0xE1,0xFF,0xE6,0xFF,0xEE,0xFF,0xE8,0xFF,0xE9,0xFF,0xE9,0xFF, + 0xEF,0xFF,0xF3,0xFF,0xEB,0xFF,0xF0,0xFF,0xEC,0xFF,0xEA,0xFF, + 0xE9,0xFF,0xEB,0xFF,0xF0,0xFF,0xF1,0xFF,0xEA,0xFF,0xF1,0xFF, + 0xF0,0xFF,0xE2,0xFF,0xEB,0xFF,0xE2,0xFF,0xF0,0xFF,0xE9,0xFF, + 0xE4,0xFF,0xE4,0xFF,0xEA,0xFF,0xEA,0xFF,0xE6,0xFF,0xED,0xFF, + 0xE1,0xFF,0xE7,0xFF,0xDE,0xFF,0xE1,0xFF,0xD5,0xFF,0xDF,0xFF, + 0xDA,0xFF,0xDB,0xFF,0xD7,0xFF,0xD2,0xFF,0xD0,0xFF,0xCB,0xFF, + 0xD6,0xFF,0xD3,0xFF,0xCF,0xFF,0xD0,0xFF,0xCF,0xFF,0xD2,0xFF, + 0xCA,0xFF,0xD8,0xFF,0xCF,0xFF,0xD0,0xFF,0xC9,0xFF,0xC3,0xFF, + 0xC7,0xFF,0xC5,0xFF,0xC6,0xFF,0xCB,0xFF,0xBE,0xFF,0xC0,0xFF, + 0xBD,0xFF,0xBD,0xFF,0xBF,0xFF,0xC9,0xFF,0xC3,0xFF,0xC5,0xFF, + 0xC6,0xFF,0xBA,0xFF,0xC3,0xFF,0xC2,0xFF,0xC6,0xFF,0xBF,0xFF, + 0xC4,0xFF,0xBE,0xFF,0xBF,0xFF,0xBA,0xFF,0xB9,0xFF,0xB9,0xFF, + 0xB8,0xFF,0xAF,0xFF,0xB7,0xFF,0xB6,0xFF,0xAF,0xFF,0xB7,0xFF, + 0xBF,0xFF,0xBB,0xFF,0xB4,0xFF,0xBC,0xFF,0xBA,0xFF,0xBD,0xFF, + 0xC4,0xFF,0xC1,0xFF,0xC9,0xFF,0xC2,0xFF,0xC3,0xFF,0xC1,0xFF, + 0xC2,0xFF,0xC2,0xFF,0xC8,0xFF,0xC5,0xFF,0xCC,0xFF,0xC4,0xFF, + 0xCC,0xFF,0xC6,0xFF,0xCB,0xFF,0xCF,0xFF,0xCB,0xFF,0xD2,0xFF, + 0xCE,0xFF,0xD6,0xFF,0xD1,0xFF,0xD2,0xFF,0xD3,0xFF,0xD0,0xFF, + 0xD3,0xFF,0xC9,0xFF,0xD5,0xFF,0xD1,0xFF,0xD3,0xFF,0xD7,0xFF, + 0xDD,0xFF,0xD5,0xFF,0xD8,0xFF,0xDA,0xFF,0xE1,0xFF,0xE3,0xFF, + 0xDE,0xFF,0xE6,0xFF,0xE0,0xFF,0xE4,0xFF,0xEC,0xFF,0xEC,0xFF, + 0xEE,0xFF,0xF2,0xFF,0xF3,0xFF,0xF3,0xFF,0xF7,0xFF,0xF6,0xFF, + 0xF5,0xFF,0xF9,0xFF,0xF3,0xFF,0xF9,0xFF,0xED,0xFF,0xF7,0xFF, + 0xF4,0xFF,0xFF,0xFF,0xF4,0xFF,0xF6,0xFF,0xF7,0xFF,0xF5,0xFF, + 0xFD,0xFF,0xF4,0xFF,0xFD,0xFF,0xF0,0xFF,0xF2,0xFF,0xF3,0xFF, + 0xE9,0xFF,0xF2,0xFF,0xE5,0xFF,0xEF,0xFF,0xEA,0xFF,0xEE,0xFF, + 0xED,0xFF,0xED,0xFF,0xE7,0xFF,0xE9,0xFF,0xEF,0xFF,0xEE,0xFF, + 0xE9,0xFF,0xE3,0xFF,0xE3,0xFF,0xE8,0xFF,0xEA,0xFF,0xE7,0xFF, + 0xE5,0xFF,0xE3,0xFF,0xE4,0xFF,0xE7,0xFF,0xE5,0xFF,0xE4,0xFF, + 0xD4,0xFF,0xE4,0xFF,0xD7,0xFF,0xE2,0xFF,0xD4,0xFF,0xD6,0xFF, + 0xD9,0xFF,0xD7,0xFF,0xDA,0xFF,0xD6,0xFF,0xCF,0xFF,0xD8,0xFF, + 0xD7,0xFF,0xD6,0xFF,0xD7,0xFF,0xD2,0xFF,0xDA,0xFF,0xCF,0xFF, + 0xD6,0xFF,0xD2,0xFF,0xD7,0xFF,0xD0,0xFF,0xCB,0xFF,0xCD,0xFF, + 0xBF,0xFF,0xC2,0xFF,0xC4,0xFF,0xC5,0xFF,0xC6,0xFF,0xC9,0xFF, + 0xC3,0xFF,0xBF,0xFF,0xC9,0xFF,0xC0,0xFF,0xCB,0xFF,0xC2,0xFF, + 0xC5,0xFF,0xC4,0xFF,0xC3,0xFF,0xC1,0xFF,0xC5,0xFF,0xC9,0xFF, + 0xBE,0xFF,0xC0,0xFF,0xC9,0xFF,0xC7,0xFF,0xC8,0xFF,0xCA,0xFF, + 0xCB,0xFF,0xBF,0xFF,0xC9,0xFF,0xBD,0xFF,0xCD,0xFF,0xCD,0xFF, + 0xD0,0xFF,0xD1,0xFF,0xCD,0xFF,0xCC,0xFF,0xC5,0xFF,0xCB,0xFF, + 0xCC,0xFF,0xD2,0xFF,0xC3,0xFF,0xCB,0xFF,0xC5,0xFF,0xC5,0xFF, + 0xCA,0xFF,0xC5,0xFF,0xC5,0xFF,0xC4,0xFF,0xC0,0xFF,0xC3,0xFF, + 0xBD,0xFF,0xC2,0xFF,0xC1,0xFF,0xC0,0xFF,0xC9,0xFF,0xC4,0xFF, + 0xC5,0xFF,0xC8,0xFF,0xC9,0xFF,0xD1,0xFF,0xCA,0xFF,0xD0,0xFF, + 0xCE,0xFF,0xD2,0xFF,0xDA,0xFF,0xDE,0xFF,0xD9,0xFF,0xDD,0xFF, + 0xDB,0xFF,0xE4,0xFF,0xE6,0xFF,0xDB,0xFF,0xE4,0xFF,0xDD,0xFF, + 0xDF,0xFF,0xE0,0xFF,0xE4,0xFF,0xE3,0xFF,0xDF,0xFF,0xE4,0xFF, + 0xE5,0xFF,0xE3,0xFF,0xDF,0xFF,0xDB,0xFF,0xD2,0xFF,0xE6,0xFF, + 0xE2,0xFF,0xE2,0xFF,0xE3,0xFF,0xE1,0xFF,0xD9,0xFF,0xE6,0xFF, + 0xE9,0xFF,0xE2,0xFF,0xDE,0xFF,0xD8,0xFF,0xD9,0xFF,0xD8,0xFF, + 0xD9,0xFF,0xDA,0xFF,0xD8,0xFF,0xE1,0xFF,0xDA,0xFF,0xD8,0xFF, + 0xD6,0xFF,0xD3,0xFF,0xDF,0xFF,0xD7,0xFF,0xDB,0xFF,0xD8,0xFF, + 0xDB,0xFF,0xD8,0xFF,0xD7,0xFF,0xDD,0xFF,0xDD,0xFF,0xD8,0xFF, + 0xD9,0xFF,0xD6,0xFF,0xD7,0xFF,0xD3,0xFF,0xD8,0xFF,0xD5,0xFF, + 0xD9,0xFF,0xCC,0xFF,0xD8,0xFF,0xD5,0xFF,0xDC,0xFF,0xE2,0xFF, + 0xD6,0xFF,0xD9,0xFF,0xE4,0xFF,0xDA,0xFF,0xD7,0xFF,0xDC,0xFF, + 0xDC,0xFF,0xDF,0xFF,0xD9,0xFF,0xDD,0xFF,0xE1,0xFF,0xDB,0xFF, + 0xE5,0xFF,0xDD,0xFF,0xE5,0xFF,0xDB,0xFF,0xE0,0xFF,0xE2,0xFF, + 0xE6,0xFF,0xDF,0xFF,0xE3,0xFF,0xDD,0xFF,0xE3,0xFF,0xDD,0xFF, + 0xE6,0xFF,0xDF,0xFF,0xEF,0xFF,0xE9,0xFF,0xEE,0xFF,0xE7,0xFF, + 0xEC,0xFF,0xEA,0xFF,0xEA,0xFF,0xEE,0xFF,0xF2,0xFF,0xF4,0xFF, + 0xF1,0xFF,0xF1,0xFF,0xF0,0xFF,0xEE,0xFF,0xED,0xFF,0xF0,0xFF, + 0xED,0xFF,0xE5,0xFF,0xE6,0xFF,0xE4,0xFF,0xE9,0xFF,0xE8,0xFF, + 0xEA,0xFF,0xE6,0xFF,0xEA,0xFF,0xE9,0xFF,0xEA,0xFF,0xEB,0xFF, + 0xED,0xFF,0xEC,0xFF,0xEE,0xFF,0xEF,0xFF,0xED,0xFF,0xF4,0xFF, + 0xF5,0xFF,0xF7,0xFF,0xFB,0xFF,0xF4,0xFF,0xF7,0xFF,0xF6,0xFF, + 0xFB,0xFF,0x02,0x00,0x03,0x00,0x01,0x00,0x05,0x00,0x01,0x00, + 0x05,0x00,0xFF,0xFF,0x05,0x00,0x01,0x00,0x00,0x00,0xFB,0xFF, + 0xFE,0xFF,0xFC,0xFF,0xFF,0xFF,0x00,0x00,0xFB,0xFF,0x06,0x00, + 0xF9,0xFF,0xFC,0xFF,0xFF,0xFF,0xFE,0xFF,0xFC,0xFF,0xFF,0xFF, + 0xFD,0xFF,0xF7,0xFF,0xF7,0xFF,0xF4,0xFF,0xFA,0xFF,0xF8,0xFF, + 0xEB,0xFF,0xF0,0xFF,0xEE,0xFF,0xED,0xFF,0xEC,0xFF,0xE8,0xFF, + 0xE9,0xFF,0xE6,0xFF,0xE6,0xFF,0xE3,0xFF,0xDE,0xFF,0xE8,0xFF, + 0xE2,0xFF,0xE1,0xFF,0xDE,0xFF,0xE4,0xFF,0xDE,0xFF,0xDE,0xFF, + 0xDC,0xFF,0xDB,0xFF,0xD5,0xFF,0xD1,0xFF,0xD6,0xFF,0xD0,0xFF, + 0xD2,0xFF,0xCA,0xFF,0xD8,0xFF,0xCE,0xFF,0xCA,0xFF,0xCB,0xFF, + 0xCC,0xFF,0xC4,0xFF,0xD0,0xFF,0xCF,0xFF,0xD1,0xFF,0xD1,0xFF, + 0xCB,0xFF,0xCE,0xFF,0xD1,0xFF,0xD1,0xFF,0xCB,0xFF,0xCA,0xFF, + 0xCB,0xFF,0xC1,0xFF,0xBD,0xFF,0xC3,0xFF,0xC1,0xFF,0xBD,0xFF, + 0xBA,0xFF,0xC0,0xFF,0xBD,0xFF,0xBF,0xFF,0xBD,0xFF,0xC2,0xFF, + 0xC3,0xFF,0xC5,0xFF,0xC6,0xFF,0xC8,0xFF,0xC9,0xFF,0xC3,0xFF, + 0xC5,0xFF,0xCD,0xFF,0xBD,0xFF,0xBD,0xFF,0xB9,0xFF,0xC1,0xFF, + 0xB2,0xFF,0xBB,0xFF,0xBE,0xFF,0xBF,0xFF,0xC5,0xFF,0xBE,0xFF, + 0xCB,0xFF,0xD0,0xFF,0xD5,0xFF,0xD4,0xFF,0xDE,0xFF,0xD3,0xFF, + 0xD4,0xFF,0xD8,0xFF,0xD5,0xFF,0xD3,0xFF,0xD2,0xFF,0xCE,0xFF, + 0xC9,0xFF,0xCE,0xFF,0xCE,0xFF,0xCF,0xFF,0xD2,0xFF,0xD7,0xFF, + 0xD7,0xFF,0xDA,0xFF,0xE0,0xFF,0xE7,0xFF,0xE3,0xFF,0xE9,0xFF, + 0xE8,0xFF,0xED,0xFF,0xEA,0xFF,0xEB,0xFF,0xEC,0xFF,0xEB,0xFF, + 0xEB,0xFF,0xEC,0xFF,0xE7,0xFF,0xE4,0xFF,0xEF,0xFF,0xEF,0xFF, + 0xF4,0xFF,0xF7,0xFF,0x01,0x00,0x01,0x00,0xFF,0xFF,0xF3,0xFF, + 0x0E,0x00,0xF4,0xFF,0xE7,0xFF,0xF5,0xFF,0xF8,0xFF,0xE0,0xFF, + 0xE6,0xFF,0xEF,0xFF,0xE6,0xFF,0xEE,0xFF,0xE9,0xFF,0xEE,0xFF, + 0xF7,0xFF,0xFB,0xFF,0xF3,0xFF,0x01,0x00,0x07,0x00,0xF9,0xFF, + 0x00,0x00,0xF8,0xFF,0xFF,0xFF,0xF0,0xFF,0xF1,0xFF,0xD8,0xFF, + 0xE0,0xFF,0xE0,0xFF,0xDF,0xFF,0xDE,0xFF,0xE5,0xFF,0xE5,0xFF, + 0xE7,0xFF,0xED,0xFF,0xF2,0xFF,0x00,0x00,0xF9,0xFF,0xF8,0xFF, + 0xF9,0xFF,0xFC,0xFF,0xEC,0xFF,0xEC,0xFF,0xF3,0xFF,0xE2,0xFF, + 0xDE,0xFF,0xD9,0xFF,0xE1,0xFF,0xD3,0xFF,0xDB,0xFF,0xDA,0xFF, + 0xED,0xFF,0xEC,0xFF,0xEC,0xFF,0xE5,0xFF,0xEB,0xFF,0xEC,0xFF, + 0xF0,0xFF,0xEF,0xFF,0xF0,0xFF,0xE8,0xFF,0xD6,0xFF,0xD2,0xFF, + 0xF0,0xFF,0xCB,0xFF,0xBE,0xFF,0xCB,0xFF,0xCD,0xFF,0xB9,0xFF, + 0xD0,0xFF,0xCC,0xFF,0xD5,0xFF,0xF1,0xFF,0xE3,0xFF,0xE3,0xFF, + 0xF6,0xFF,0xF9,0xFF,0xE2,0xFF,0xFA,0xFF,0xF2,0xFF,0xF4,0xFF, + 0xE0,0xFF,0xE0,0xFF,0xE0,0xFF,0xE2,0xFF,0xD3,0xFF,0xCB,0xFF, + 0xDE,0xFF,0xD6,0xFF,0xD2,0xFF,0xE6,0xFF,0xEA,0xFF,0xF9,0xFF, + 0xFF,0xFF,0xFB,0xFF,0xFB,0xFF,0x09,0x00,0xF6,0xFF,0x00,0x00, + 0xF5,0xFF,0xFA,0xFF,0xE3,0xFF,0xDC,0xFF,0xCD,0xFF,0xCD,0xFF, + 0xD2,0xFF,0xCA,0xFF,0xCE,0xFF,0xD2,0xFF,0xD5,0xFF,0xD6,0xFF, + 0xEC,0xFF,0xE9,0xFF,0xF3,0xFF,0xF4,0xFF,0xFA,0xFF,0xF9,0xFF, + 0x0C,0x00,0xEF,0xFF,0xEE,0xFF,0x15,0x00,0xEF,0xFF,0xD0,0xFF, + 0xE9,0xFF,0xE9,0xFF,0xD2,0xFF,0xEA,0xFF,0xDB,0xFF,0xCF,0xFF, + 0x00,0x00,0xF2,0xFF,0xF4,0xFF,0xFD,0xFF,0x1E,0x00,0x01,0x00, + 0x1C,0x00,0x0C,0x00,0x04,0x00,0x01,0x00,0xFD,0xFF,0xF1,0xFF, + 0xE1,0xFF,0xE4,0xFF,0xD9,0xFF,0xE4,0xFF,0xDE,0xFF,0xEB,0xFF, + 0xFC,0xFF,0x06,0x00,0x12,0x00,0x04,0x00,0x13,0x00,0x16,0x00, + 0x12,0x00,0x04,0x00,0x09,0x00,0xFB,0xFF,0xF1,0xFF,0xE7,0xFF, + 0xE9,0xFF,0xE5,0xFF,0xE2,0xFF,0xE2,0xFF,0xDC,0xFF,0xE8,0xFF, + 0xE0,0xFF,0xE1,0xFF,0xE5,0xFF,0xFA,0xFF,0xF1,0xFF,0xEE,0xFF, + 0xF1,0xFF,0xFD,0xFF,0xE9,0xFF,0xD9,0xFF,0x0C,0x00,0xCF,0xFF, + 0xC1,0xFF,0xD9,0xFF,0xE3,0xFF,0xCB,0xFF,0xEA,0xFF,0xC7,0xFF, + 0xCE,0xFF,0xF2,0xFF,0xF6,0xFF,0xDF,0xFF,0xE1,0xFF,0x02,0x00, + 0xEA,0xFF,0xF5,0xFF,0xE5,0xFF,0xD8,0xFF,0xD3,0xFF,0xE0,0xFF, + 0xCB,0xFF,0xAC,0xFF,0xBB,0xFF,0xC4,0xFF,0xCB,0xFF,0xD0,0xFF, + 0xD1,0xFF,0xCF,0xFF,0x05,0x00,0xFA,0xFF,0xD6,0xFF,0xE8,0xFF, + 0xF7,0xFF,0xEB,0xFF,0xDB,0xFF,0xDB,0xFF,0xBB,0xFF,0xD7,0xFF, + 0xC8,0xFF,0xBE,0xFF,0xC4,0xFF,0xDB,0xFF,0xDC,0xFF,0xD7,0xFF, + 0xEF,0xFF,0xE1,0xFF,0xE3,0xFF,0xF6,0xFF,0xEB,0xFF,0xC7,0xFF, + 0xDD,0xFF,0xE9,0xFF,0xC2,0xFF,0xB5,0xFF,0xDF,0xFF,0xA8,0xFF, + 0xB5,0xFF,0xCD,0xFF,0xBF,0xFF,0xBD,0xFF,0xDF,0xFF,0xD1,0xFF, + 0xAB,0xFF,0xE1,0xFF,0xE8,0xFF,0xD5,0xFF,0xE6,0xFF,0xEB,0xFF, + 0xE2,0xFF,0xE4,0xFF,0xF5,0xFF,0xC9,0xFF,0xCA,0xFF,0xDA,0xFF, + 0xE2,0xFF,0xC1,0xFF,0xC1,0xFF,0xE2,0xFF,0xEA,0xFF,0xF2,0xFF, + 0xF1,0xFF,0xEC,0xFF,0xFC,0xFF,0x17,0x00,0x00,0x00,0xE4,0xFF, + 0x04,0x00,0xF2,0xFF,0xEF,0xFF,0xF8,0xFF,0xE2,0xFF,0xDF,0xFF, + 0xE3,0xFF,0xFC,0xFF,0xF3,0xFF,0xF1,0xFF,0xFB,0xFF,0xF9,0xFF, + 0x14,0x00,0x06,0x00,0xE2,0xFF,0xF4,0xFF,0x0A,0x00,0xED,0xFF, + 0xDC,0xFF,0xCA,0xFF,0xCB,0xFF,0xF4,0xFF,0xE9,0xFF,0xAB,0xFF, + 0xBA,0xFF,0xED,0xFF,0xD6,0xFF,0xDE,0xFF,0xD2,0xFF,0xD6,0xFF, + 0xDB,0xFF,0xF2,0xFF,0xDE,0xFF,0xCB,0xFF,0xDC,0xFF,0xD7,0xFF, + 0xE3,0xFF,0xD2,0xFF,0xC2,0xFF,0xC7,0xFF,0xC4,0xFF,0xCF,0xFF, + 0xC5,0xFF,0xC0,0xFF,0xC3,0xFF,0xE8,0xFF,0xE2,0xFF,0xE4,0xFF, + 0xE9,0xFF,0xE1,0xFF,0xE0,0xFF,0xF5,0xFF,0xEA,0xFF,0xC1,0xFF, + 0xD9,0xFF,0xD2,0xFF,0xCD,0xFF,0xC2,0xFF,0xD0,0xFF,0xB7,0xFF, + 0xC1,0xFF,0xDE,0xFF,0xD5,0xFF,0xD2,0xFF,0xE0,0xFF,0xE2,0xFF, + 0xD5,0xFF,0xDC,0xFF,0xD2,0xFF,0xD1,0xFF,0xD8,0xFF,0xD5,0xFF, + 0xAF,0xFF,0xB6,0xFF,0xD6,0xFF,0xAD,0xFF,0xB1,0xFF,0xC1,0xFF, + 0xB5,0xFF,0xD1,0xFF,0xE2,0xFF,0xCB,0xFF,0xCD,0xFF,0xDE,0xFF, + 0xE1,0xFF,0xCF,0xFF,0xDF,0xFF,0xD0,0xFF,0xBE,0xFF,0xD0,0xFF, + 0xD2,0xFF,0xCE,0xFF,0xC3,0xFF,0xC6,0xFF,0xCC,0xFF,0xC9,0xFF, + 0xD2,0xFF,0xCA,0xFF,0xD7,0xFF,0xDF,0xFF,0xEC,0xFF,0xE9,0xFF, + 0xF4,0xFF,0xED,0xFF,0xF1,0xFF,0xF6,0xFF,0xE0,0xFF,0xD4,0xFF, + 0xDB,0xFF,0xEE,0xFF,0xD4,0xFF,0xDA,0xFF,0xCF,0xFF,0xD6,0xFF, + 0xDF,0xFF,0xE5,0xFF,0xE6,0xFF,0xE2,0xFF,0xFA,0xFF,0xF8,0xFF, + 0xF5,0xFF,0xEC,0xFF,0xF9,0xFF,0xF8,0xFF,0x01,0x00,0xEB,0xFF, + 0xDA,0xFF,0x00,0x00,0xEA,0xFF,0xD6,0xFF,0xE4,0xFF,0xF3,0xFF, + 0xEF,0xFF,0xE9,0xFF,0xF8,0xFF,0xE9,0xFF,0xF0,0xFF,0x08,0x00, + 0xF1,0xFF,0xF4,0xFF,0xFF,0xFF,0xF2,0xFF,0xDC,0xFF,0xF8,0xFF, + 0xFA,0xFF,0xE5,0xFF,0xEB,0xFF,0xD8,0xFF,0xD9,0xFF,0xE6,0xFF, + 0xF4,0xFF,0xDD,0xFF,0xDB,0xFF,0xF7,0xFF,0xF2,0xFF,0xE6,0xFF, + 0xE4,0xFF,0xE8,0xFF,0xE8,0xFF,0xE8,0xFF,0xDF,0xFF,0xCE,0xFF, + 0xD0,0xFF,0xE0,0xFF,0xCC,0xFF,0xE0,0xFF,0xE6,0xFF,0xE0,0xFF, + 0xDF,0xFF,0xEF,0xFF,0xE6,0xFF,0xE9,0xFF,0xE4,0xFF,0xE2,0xFF, + 0xE2,0xFF,0xD6,0xFF,0xCF,0xFF,0xCF,0xFF,0xD4,0xFF,0xD6,0xFF, + 0xC9,0xFF,0xC9,0xFF,0xCD,0xFF,0xD6,0xFF,0xC7,0xFF,0xDA,0xFF, + 0xDC,0xFF,0xD2,0xFF,0xE5,0xFF,0xD8,0xFF,0xD4,0xFF,0xCD,0xFF, + 0xE0,0xFF,0xD4,0xFF,0xD0,0xFF,0xDC,0xFF,0xD9,0xFF,0xD1,0xFF, + 0xDE,0xFF,0xDB,0xFF,0xCA,0xFF,0xE0,0xFF,0xDF,0xFF,0xE1,0xFF, + 0xE2,0xFF,0xE1,0xFF,0xF2,0xFF,0xEB,0xFF,0xE8,0xFF,0xD4,0xFF, + 0xD8,0xFF,0xDB,0xFF,0xC3,0xFF,0xDE,0xFF,0xCE,0xFF,0xD2,0xFF, + 0xC9,0xFF,0xDA,0xFF,0xD0,0xFF,0xD6,0xFF,0xED,0xFF,0xDE,0xFF, + 0xDC,0xFF,0xDE,0xFF,0xE7,0xFF,0xE1,0xFF,0xEB,0xFF,0xDE,0xFF, + 0xCC,0xFF,0xC3,0xFF,0xBE,0xFF,0xD1,0xFF,0xCD,0xFF,0xD3,0xFF, + 0xD2,0xFF,0xCA,0xFF,0xCB,0xFF,0xE0,0xFF,0xD5,0xFF,0xD4,0xFF, + 0xD5,0xFF,0xDD,0xFF,0xE0,0xFF,0xCE,0xFF,0xCF,0xFF,0xD2,0xFF, + 0xDA,0xFF,0xD0,0xFF,0xC5,0xFF,0xD9,0xFF,0xD7,0xFF,0xE6,0xFF, + 0xF2,0xFF,0xF1,0xFF,0xF0,0xFF,0xFE,0xFF,0x03,0x00,0x04,0x00, + 0x02,0x00,0x09,0x00,0x02,0x00,0xFE,0xFF,0xF2,0xFF,0xF3,0xFF, + 0xE8,0xFF,0xEB,0xFF,0xEF,0xFF,0xEF,0xFF,0xED,0xFF,0xF7,0xFF, + 0x02,0x00,0xFA,0xFF,0x09,0x00,0x08,0x00,0xFF,0xFF,0xFF,0xFF, + 0x03,0x00,0x00,0x00,0xF7,0xFF,0xFC,0xFF,0xF3,0xFF,0xF6,0xFF, + 0xE1,0xFF,0xE4,0xFF,0xE4,0xFF,0xDD,0xFF,0xE5,0xFF,0xEC,0xFF, + 0xE9,0xFF,0xEE,0xFF,0xEF,0xFF,0xF3,0xFF,0xE8,0xFF,0xF6,0xFF, + 0xFE,0xFF,0x02,0x00,0xF3,0xFF,0xE4,0xFF,0xE1,0xFF,0xE4,0xFF, + 0xDC,0xFF,0xD7,0xFF,0xD1,0xFF,0xDC,0xFF,0xD9,0xFF,0xE0,0xFF, + 0xD7,0xFF,0xDF,0xFF,0xEB,0xFF,0xE8,0xFF,0xEA,0xFF,0xEC,0xFF, + 0xF1,0xFF,0xFA,0xFF,0xEC,0xFF,0xF0,0xFF,0xE4,0xFF,0xE3,0xFF, + 0xD9,0xFF,0xE3,0xFF,0xD9,0xFF,0xCE,0xFF,0xD6,0xFF,0xDE,0xFF, + 0xE0,0xFF,0xDE,0xFF,0xE5,0xFF,0xE6,0xFF,0xE0,0xFF,0xE6,0xFF, + 0xD5,0xFF,0xD0,0xFF,0xD1,0xFF,0xCF,0xFF,0xCC,0xFF,0xC6,0xFF, + 0xCB,0xFF,0xBF,0xFF,0xCC,0xFF,0xCE,0xFF,0xC7,0xFF,0xCE,0xFF, + 0xD1,0xFF,0xD2,0xFF,0xCE,0xFF,0xD4,0xFF,0xD6,0xFF,0xCE,0xFF, + 0xD2,0xFF,0xD1,0xFF,0xC2,0xFF,0xC4,0xFF,0xC7,0xFF,0xC4,0xFF, + 0xC2,0xFF,0xC5,0xFF,0xC1,0xFF,0xC5,0xFF,0xC6,0xFF,0xC7,0xFF, + 0xCD,0xFF,0xC7,0xFF,0xC3,0xFF,0xC5,0xFF,0xD4,0xFF,0xD4,0xFF, + 0xD5,0xFF,0xD3,0xFF,0xDB,0xFF,0xD3,0xFF,0xC8,0xFF,0xC9,0xFF, + 0xC6,0xFF,0xD5,0xFF,0xD4,0xFF,0xD9,0xFF,0xDF,0xFF,0xE8,0xFF, + 0xEB,0xFF,0xEC,0xFF,0xEE,0xFF,0xEC,0xFF,0xF7,0xFF,0xEE,0xFF, + 0xED,0xFF,0xE9,0xFF,0xE4,0xFF,0xDF,0xFF,0xE4,0xFF,0xED,0xFF, + 0xE0,0xFF,0xE9,0xFF,0xE0,0xFF,0xE2,0xFF,0xDD,0xFF,0xED,0xFF, + 0xF2,0xFF,0xF2,0xFF,0xF1,0xFF,0xEF,0xFF,0xE8,0xFF,0xEB,0xFF, + 0xEC,0xFF,0xEE,0xFF,0xEA,0xFF,0xEF,0xFF,0xED,0xFF,0xF0,0xFF, + 0xE8,0xFF,0xEC,0xFF,0xE8,0xFF,0xE7,0xFF,0xE5,0xFF,0xE3,0xFF, + 0xEB,0xFF,0xED,0xFF,0xF3,0xFF,0xF2,0xFF,0xEE,0xFF,0xF1,0xFF, + 0xE8,0xFF,0xF1,0xFF,0xEA,0xFF,0xE7,0xFF,0xE0,0xFF,0xE2,0xFF, + 0xE5,0xFF,0xE1,0xFF,0xDD,0xFF,0xDD,0xFF,0xE5,0xFF,0xDF,0xFF, + 0xEC,0xFF,0xEC,0xFF,0xDE,0xFF,0xE6,0xFF,0xE9,0xFF,0xE4,0xFF, + 0xE5,0xFF,0xE4,0xFF,0xDF,0xFF,0xDE,0xFF,0xDF,0xFF,0xD4,0xFF, + 0xDE,0xFF,0xE3,0xFF,0xD9,0xFF,0xCF,0xFF,0xD9,0xFF,0xD2,0xFF, + 0xCC,0xFF,0xCA,0xFF,0xCD,0xFF,0xCB,0xFF,0xCE,0xFF,0xCC,0xFF, + 0xCF,0xFF,0xD2,0xFF,0xCF,0xFF,0xD1,0xFF,0xD4,0xFF,0xD3,0xFF, + 0xCF,0xFF,0xCC,0xFF,0xD4,0xFF,0xD4,0xFF,0xD0,0xFF,0xD8,0xFF, + 0xD0,0xFF,0xCA,0xFF,0xD4,0xFF,0xD5,0xFF,0xDA,0xFF,0xD5,0xFF, + 0xDB,0xFF,0xD6,0xFF,0xDE,0xFF,0xE7,0xFF,0xE0,0xFF,0xE9,0xFF, + 0xE3,0xFF,0xE2,0xFF,0xE4,0xFF,0xE6,0xFF,0xE7,0xFF,0xE9,0xFF, + 0xE4,0xFF,0xDE,0xFF,0xE2,0xFF,0xDD,0xFF,0xD5,0xFF,0xDA,0xFF, + 0xDA,0xFF,0xDA,0xFF,0xD9,0xFF,0xDE,0xFF,0xD2,0xFF,0xDE,0xFF, + 0xE0,0xFF,0xE2,0xFF,0xD6,0xFF,0xDA,0xFF,0xD6,0xFF,0xE5,0xFF, + 0xE3,0xFF,0xE8,0xFF,0xE8,0xFF,0xE5,0xFF,0xEA,0xFF,0xE4,0xFF, + 0xDC,0xFF,0xE3,0xFF,0xE8,0xFF,0xE8,0xFF,0xDF,0xFF,0xDE,0xFF, + 0xDE,0xFF,0xE6,0xFF,0xDE,0xFF,0xEA,0xFF,0xE3,0xFF,0xE9,0xFF, + 0xE3,0xFF,0xE2,0xFF,0xF2,0xFF,0xF2,0xFF,0xF1,0xFF,0xFA,0xFF, + 0xF7,0xFF,0xF5,0xFF,0xF1,0xFF,0xF8,0xFF,0xF6,0xFF,0xF7,0xFF, + 0xF2,0xFF,0xE9,0xFF,0xEA,0xFF,0xEB,0xFF,0xEB,0xFF,0xE0,0xFF, + 0xE5,0xFF,0xE7,0xFF,0xDF,0xFF,0xE0,0xFF,0xDE,0xFF,0xE4,0xFF, + 0xE9,0xFF,0xE7,0xFF,0xE6,0xFF,0xE3,0xFF,0xE4,0xFF,0xE0,0xFF, + 0xE4,0xFF,0xE0,0xFF,0xEC,0xFF,0xE8,0xFF,0xE8,0xFF,0xE1,0xFF, + 0xE3,0xFF,0xDD,0xFF,0xE3,0xFF,0xE7,0xFF,0xD8,0xFF,0xD9,0xFF, + 0xD9,0xFF,0xDC,0xFF,0xED,0xFF,0xE1,0xFF,0xE0,0xFF,0xDF,0xFF, + 0xE1,0xFF,0xD4,0xFF,0xD7,0xFF,0xDB,0xFF,0xDF,0xFF,0xDE,0xFF, + 0xDF,0xFF,0xDF,0xFF,0xDB,0xFF,0xDB,0xFF,0xDA,0xFF,0xD7,0xFF, + 0xD1,0xFF,0xD3,0xFF,0xD6,0xFF,0xD6,0xFF,0xDD,0xFF,0xD9,0xFF, + 0xDC,0xFF,0xD7,0xFF,0xD3,0xFF,0xD6,0xFF,0xCC,0xFF,0xCB,0xFF, + 0xCF,0xFF,0xD3,0xFF,0xD1,0xFF,0xD7,0xFF,0xD6,0xFF,0xD1,0xFF, + 0xD7,0xFF,0xD4,0xFF,0xD7,0xFF,0xD4,0xFF,0xD6,0xFF,0xD9,0xFF, + 0xDA,0xFF,0xDE,0xFF,0xD8,0xFF,0xD6,0xFF,0xD2,0xFF,0xD5,0xFF, + 0xCC,0xFF,0xD1,0xFF,0xD5,0xFF,0xD0,0xFF,0xCE,0xFF,0xCD,0xFF, + 0xD4,0xFF,0xCF,0xFF,0xD6,0xFF,0xD4,0xFF,0xD5,0xFF,0xDF,0xFF, + 0xD8,0xFF,0xD9,0xFF,0xDF,0xFF,0xDD,0xFF,0xD6,0xFF,0xD9,0xFF, + 0xD4,0xFF,0xCD,0xFF,0xCE,0xFF,0xD7,0xFF,0xD2,0xFF,0xCF,0xFF, + 0xD2,0xFF,0xD7,0xFF,0xD8,0xFF,0xE7,0xFF,0xE2,0xFF,0xE3,0xFF, + 0xE0,0xFF,0xE1,0xFF,0xE0,0xFF,0xDD,0xFF,0xDB,0xFF,0xE0,0xFF, + 0xE3,0xFF,0xE0,0xFF,0xE5,0xFF,0xE9,0xFF,0xEF,0xFF,0xF2,0xFF, + 0xEB,0xFF,0xE6,0xFF,0xEC,0xFF,0xED,0xFF,0xEA,0xFF,0xE9,0xFF, + 0xE6,0xFF,0xE7,0xFF,0xEC,0xFF,0xEE,0xFF,0xEB,0xFF,0xE4,0xFF, + 0xE9,0xFF,0xEB,0xFF,0xEF,0xFF,0xEC,0xFF,0xED,0xFF,0xF2,0xFF, + 0xEF,0xFF,0xF2,0xFF,0xF7,0xFF,0xF4,0xFF,0xF2,0xFF,0xF2,0xFF, + 0xEF,0xFF,0xED,0xFF,0xF5,0xFF,0xFB,0xFF,0xFA,0xFF,0xF9,0xFF, + 0xF9,0xFF,0xEA,0xFF,0xF2,0xFF,0xEA,0xFF,0xEE,0xFF,0xF3,0xFF, + 0xF6,0xFF,0xFB,0xFF,0xF0,0xFF,0xEA,0xFF,0xED,0xFF,0xED,0xFF, + 0xED,0xFF,0xE8,0xFF,0xEC,0xFF,0xDF,0xFF,0xEC,0xFF,0xEA,0xFF, + 0xED,0xFF,0xE4,0xFF,0xE8,0xFF,0xE6,0xFF,0xE2,0xFF,0xE8,0xFF, + 0xDB,0xFF,0xDF,0xFF,0xEC,0xFF,0xE4,0xFF,0xE3,0xFF,0xD9,0xFF, + 0xDA,0xFF,0xDB,0xFF,0xDB,0xFF,0xDD,0xFF,0xD6,0xFF,0xD5,0xFF, + 0xD2,0xFF,0xD5,0xFF,0xD5,0xFF,0xD5,0xFF,0xD4,0xFF,0xD1,0xFF, + 0xD3,0xFF,0xCD,0xFF,0xCD,0xFF,0xD2,0xFF,0xD7,0xFF,0xD9,0xFF, + 0xDC,0xFF,0xE2,0xFF,0xDE,0xFF,0xDB,0xFF,0xD8,0xFF,0xDB,0xFF, + 0xDA,0xFF,0xD7,0xFF,0xCF,0xFF,0xD0,0xFF,0xCF,0xFF,0xD4,0xFF, + 0xD5,0xFF,0xD0,0xFF,0xDC,0xFF,0xD2,0xFF,0xD1,0xFF,0xD0,0xFF, + 0xD9,0xFF,0xDF,0xFF,0xD9,0xFF,0xD4,0xFF,0xD2,0xFF,0xD3,0xFF, + 0xD5,0xFF,0xD2,0xFF,0xD3,0xFF,0xD0,0xFF,0xD3,0xFF,0xD1,0xFF, + 0xCB,0xFF,0xC8,0xFF,0xD4,0xFF,0xD8,0xFF,0xCC,0xFF,0xCD,0xFF, + 0xD2,0xFF,0xD6,0xFF,0xD7,0xFF,0xDB,0xFF,0xD7,0xFF,0xDC,0xFF, + 0xD9,0xFF,0xE2,0xFF,0xE3,0xFF,0xE5,0xFF,0xE6,0xFF,0xF3,0xFF, + 0xF4,0xFF,0xE4,0xFF,0xE6,0xFF,0xEF,0xFF,0xE7,0xFF,0xE6,0xFF, + 0xE8,0xFF,0xE7,0xFF,0xDE,0xFF,0xE4,0xFF,0xE6,0xFF,0xDC,0xFF, + 0xE4,0xFF,0xDE,0xFF,0xD9,0xFF,0xD2,0xFF,0xDB,0xFF,0xD5,0xFF, + 0xD6,0xFF,0xD9,0xFF,0xDD,0xFF,0xDA,0xFF,0xD7,0xFF,0xD9,0xFF, + 0xD5,0xFF,0xD6,0xFF,0xD9,0xFF,0xCF,0xFF,0xCD,0xFF,0xCA,0xFF, + 0xCE,0xFF,0xCB,0xFF,0xCA,0xFF,0xD4,0xFF,0xC5,0xFF,0xC8,0xFF, + 0xC8,0xFF,0xC5,0xFF,0xC2,0xFF,0xC9,0xFF,0xCF,0xFF,0xC6,0xFF, + 0xC4,0xFF,0xBB,0xFF,0xBC,0xFF,0xBF,0xFF,0xBF,0xFF,0xBE,0xFF, + 0xC0,0xFF,0xC3,0xFF,0xCA,0xFF,0xD0,0xFF,0xD1,0xFF,0xD0,0xFF, + 0xCF,0xFF,0xD1,0xFF,0xCA,0xFF,0xC8,0xFF,0xC8,0xFF,0xC6,0xFF, + 0xC7,0xFF,0xCB,0xFF,0xC4,0xFF,0xC5,0xFF,0xC7,0xFF,0xC3,0xFF, + 0xC1,0xFF,0xC3,0xFF,0xBB,0xFF,0xBA,0xFF,0xB2,0xFF,0xB4,0xFF, + 0xB9,0xFF,0xC1,0xFF,0xC4,0xFF,0xBB,0xFF,0xBD,0xFF,0xC0,0xFF, + 0xC3,0xFF,0xBF,0xFF,0xBC,0xFF,0xC4,0xFF,0xBD,0xFF,0xC8,0xFF, + 0xC6,0xFF,0xC3,0xFF,0xCA,0xFF,0xCA,0xFF,0xCE,0xFF,0xD0,0xFF, + 0xC3,0xFF,0xD2,0xFF,0xD0,0xFF,0xD6,0xFF,0xD3,0xFF,0xD0,0xFF, + 0xD1,0xFF,0xD3,0xFF,0xD4,0xFF,0xD4,0xFF,0xD6,0xFF,0xD4,0xFF, + 0xD6,0xFF,0xD4,0xFF,0xD3,0xFF,0xD7,0xFF,0xD4,0xFF,0xD6,0xFF, + 0xE6,0xFF,0xE6,0xFF,0xE5,0xFF,0xE8,0xFF,0xE8,0xFF,0xE6,0xFF, + 0xE2,0xFF,0xE5,0xFF,0xEF,0xFF,0xEB,0xFF,0xEF,0xFF,0xEB,0xFF, + 0xF2,0xFF,0xF0,0xFF,0xF0,0xFF,0xF0,0xFF,0xF0,0xFF,0xF1,0xFF, + 0xF4,0xFF,0xFC,0xFF,0x00,0x00,0xFD,0xFF,0x07,0x00,0xFF,0xFF, + 0x01,0x00,0x00,0x00,0x01,0x00,0xFF,0xFF,0x04,0x00,0x04,0x00, + 0xFF,0xFF,0xFF,0xFF,0x01,0x00,0xFB,0xFF,0x01,0x00,0xFD,0xFF, + 0xFF,0xFF,0xFA,0xFF,0xFB,0xFF,0xFC,0xFF,0x03,0x00,0x09,0x00, + 0x07,0x00,0x07,0x00,0x00,0x00,0x03,0x00,0x05,0x00,0x01,0x00, + 0x00,0x00,0x05,0x00,0xFE,0xFF,0x00,0x00,0xF9,0xFF,0xF9,0xFF, + 0x03,0x00,0xFB,0xFF,0xF6,0xFF,0xFA,0xFF,0xFE,0xFF,0xFA,0xFF, + 0xF9,0xFF,0xFD,0xFF,0xFD,0xFF,0xF5,0xFF,0xF4,0xFF,0xF2,0xFF, + 0xF7,0xFF,0xF3,0xFF,0xF7,0xFF,0xFD,0xFF,0x06,0x00,0xFF,0xFF, + 0xFC,0xFF,0x02,0x00,0xF7,0xFF,0xF9,0xFF,0xF9,0xFF,0xFA,0xFF, + 0xFB,0xFF,0xFB,0xFF,0xF6,0xFF,0xF2,0xFF,0xE9,0xFF,0xEB,0xFF, + 0xE7,0xFF,0xF3,0xFF,0xED,0xFF,0xF1,0xFF,0xEC,0xFF,0xED,0xFF, + 0xE9,0xFF,0xED,0xFF,0xE6,0xFF,0xE9,0xFF,0xE9,0xFF,0xEE,0xFF, + 0xEE,0xFF,0xEC,0xFF,0xE8,0xFF,0xEF,0xFF,0xF1,0xFF,0xEE,0xFF, + 0xEC,0xFF,0xED,0xFF,0xF3,0xFF,0xEF,0xFF,0xEC,0xFF,0xEB,0xFF, + 0xEA,0xFF,0xEA,0xFF,0xE8,0xFF,0xE4,0xFF,0xE3,0xFF,0xE8,0xFF, + 0xE6,0xFF,0xED,0xFF,0xE8,0xFF,0xDF,0xFF,0xDE,0xFF,0xE7,0xFF, + 0xEA,0xFF,0xE5,0xFF,0xDD,0xFF,0xD9,0xFF,0xD6,0xFF,0xDA,0xFF, + 0xDA,0xFF,0xDE,0xFF,0xD5,0xFF,0xD9,0xFF,0xE0,0xFF,0xE0,0xFF, + 0xDF,0xFF,0xE6,0xFF,0xF0,0xFF,0xED,0xFF,0xE7,0xFF,0xEC,0xFF, + 0xE4,0xFF,0xE6,0xFF,0xE2,0xFF,0xE3,0xFF,0xE5,0xFF,0xE7,0xFF, + 0xE1,0xFF,0xE4,0xFF,0xE8,0xFF,0xE6,0xFF,0xEA,0xFF,0xE6,0xFF, + 0xEB,0xFF,0xF0,0xFF,0xF0,0xFF,0xEE,0xFF,0xF4,0xFF,0xF5,0xFF, + 0xFD,0xFF,0xF9,0xFF,0xF6,0xFF,0xF1,0xFF,0xF3,0xFF,0xF4,0xFF, + 0xFE,0xFF,0xFE,0xFF,0xFD,0xFF,0xF9,0xFF,0xFA,0xFF,0xFB,0xFF, + 0xF7,0xFF,0xF6,0xFF,0xEE,0xFF,0xF1,0xFF,0xE9,0xFF,0xF5,0xFF, + 0xF4,0xFF,0xFD,0xFF,0xF3,0xFF,0xF3,0xFF,0xF5,0xFF,0xF2,0xFF, + 0xF5,0xFF,0xF2,0xFF,0xF1,0xFF,0xF2,0xFF,0xF2,0xFF,0xEF,0xFF, + 0xEE,0xFF,0xEF,0xFF,0xEB,0xFF,0xE2,0xFF,0xD6,0xFF,0xD5,0xFF, + 0xD5,0xFF,0xDC,0xFF,0xD8,0xFF,0xE8,0xFF,0xE7,0xFF,0xE2,0xFF, + 0xE0,0xFF,0xE1,0xFF,0xE6,0xFF,0xE3,0xFF,0xE8,0xFF,0xEF,0xFF, + 0xEC,0xFF,0xE5,0xFF,0xDB,0xFF,0xD9,0xFF,0xD8,0xFF,0xDC,0xFF, + 0xDC,0xFF,0xD5,0xFF,0xD6,0xFF,0xD7,0xFF,0xCE,0xFF,0xD4,0xFF, + 0xDD,0xFF,0xDE,0xFF,0xDA,0xFF,0xDD,0xFF,0xD8,0xFF,0xCF,0xFF, + 0xCB,0xFF,0xCC,0xFF,0xCA,0xFF,0xC8,0xFF,0xCF,0xFF,0xCB,0xFF, + 0xC8,0xFF,0xCE,0xFF,0xD7,0xFF,0xD1,0xFF,0xD2,0xFF,0xCD,0xFF, + 0xD3,0xFF,0xD1,0xFF,0xDB,0xFF,0xE4,0xFF,0xE0,0xFF,0xE9,0xFF, + 0xE9,0xFF,0xE3,0xFF,0xDE,0xFF,0xDC,0xFF,0xE4,0xFF,0xDD,0xFF, + 0xE0,0xFF,0xD9,0xFF,0xE1,0xFF,0xDC,0xFF,0xE6,0xFF,0xDE,0xFF, + 0xE3,0xFF,0xDF,0xFF,0xD6,0xFF,0xCF,0xFF,0xCF,0xFF,0xD6,0xFF, + 0xD4,0xFF,0xD0,0xFF,0xD6,0xFF,0xD8,0xFF,0xD7,0xFF,0xD6,0xFF, + 0xDD,0xFF,0xD8,0xFF,0xD2,0xFF,0xD5,0xFF,0xDC,0xFF,0xDB,0xFF, + 0xDB,0xFF,0xE5,0xFF,0xED,0xFF,0xEF,0xFF,0xEA,0xFF,0xDC,0xFF, + 0xDC,0xFF,0xE5,0xFF,0xE1,0xFF,0xE7,0xFF,0xE3,0xFF,0xEA,0xFF, + 0xEE,0xFF,0xD4,0xFF,0xE0,0xFF,0x97,0xFF,0x02,0x00,0xF2,0xFF, + 0xB3,0xFF,0x21,0x00,0x30,0x00,0x7E,0xFF,0xB4,0xFF,0xE5,0xFF, + 0xE3,0xFF,0xA3,0xFF,0x9F,0xFF,0xDF,0xFF,0xDC,0xFF,0xBE,0xFF, + 0xFD,0xFF,0x1A,0x00,0xE1,0xFF,0xE9,0xFF,0xC3,0xFF,0xF1,0xFF, + 0xDD,0xFF,0xE2,0xFF,0xE2,0xFF,0x08,0x00,0xE0,0xFF,0xD0,0xFF, + 0xEB,0xFF,0xD9,0xFF,0xE2,0xFF,0xBF,0xFF,0xC2,0xFF,0xEE,0xFF, + 0xCB,0xFF,0xEC,0xFF,0xCF,0xFF,0xCE,0xFF,0xC3,0xFF,0xC4,0xFF, + 0xAE,0xFF,0xC6,0xFF,0xD0,0xFF,0xBF,0xFF,0xBB,0xFF,0xCB,0xFF, + 0xC4,0xFF,0xC7,0xFF,0xB1,0xFF,0xBF,0xFF,0xC4,0xFF,0xB4,0xFF, + 0xC4,0xFF,0xBD,0xFF,0xD4,0xFF,0xC2,0xFF,0xDA,0xFF,0xDC,0xFF, + 0xDD,0xFF,0xC4,0xFF,0xC7,0xFF,0xBD,0xFF,0xC6,0xFF,0xC8,0xFF, + 0xC0,0xFF,0xC8,0xFF,0xC2,0xFF,0xC2,0xFF,0xC7,0xFF,0xB8,0xFF, + 0xB2,0xFF,0xB3,0xFF,0xAB,0xFF,0xB3,0xFF,0xC1,0xFF,0xCB,0xFF, + 0xBF,0xFF,0xC2,0xFF,0xC9,0xFF,0xC2,0xFF,0xBA,0xFF,0xB8,0xFF, + 0xB8,0xFF,0xC6,0xFF,0xCA,0xFF,0xC3,0xFF,0xC7,0xFF,0xD2,0xFF, + 0xC0,0xFF,0xD4,0xFF,0xD3,0xFF,0xD0,0xFF,0xC8,0xFF,0xCE,0xFF, + 0xCE,0xFF,0xC8,0xFF,0xD8,0xFF,0xD7,0xFF,0xD2,0xFF,0xD7,0xFF, + 0xD6,0xFF,0xDA,0xFF,0xD5,0xFF,0xD0,0xFF,0xDE,0xFF,0xDE,0xFF, + 0xDD,0xFF,0xD5,0xFF,0xE2,0xFF,0xD8,0xFF,0xDE,0xFF,0xD7,0xFF, + 0xDC,0xFF,0xDA,0xFF,0xD5,0xFF,0xDA,0xFF,0xCD,0xFF,0xCB,0xFF, + 0xCE,0xFF,0xDE,0xFF,0xE9,0xFF,0xF3,0xFF,0xE8,0xFF,0xED,0xFF, + 0xED,0xFF,0xF8,0xFF,0xF5,0xFF,0xF9,0xFF,0xFB,0xFF,0x03,0x00, + 0x05,0x00,0xFC,0xFF,0xF7,0xFF,0xF6,0xFF,0xF5,0xFF,0xE9,0xFF, + 0xF9,0xFF,0xFB,0xFF,0xF6,0xFF,0xF5,0xFF,0xEB,0xFF,0xEB,0xFF, + 0xED,0xFF,0xEE,0xFF,0xF2,0xFF,0xFC,0xFF,0xE7,0xFF,0xF2,0xFF, + 0xF0,0xFF,0xF5,0xFF,0xEC,0xFF,0xE5,0xFF,0xF5,0xFF,0xE5,0xFF, + 0xE6,0xFF,0xF0,0xFF,0xED,0xFF,0xEE,0xFF,0xF1,0xFF,0xE5,0xFF, + 0xEF,0xFF,0xF0,0xFF,0xEA,0xFF,0xF3,0xFF,0xF1,0xFF,0xEE,0xFF, + 0xEC,0xFF,0xE3,0xFF,0xE7,0xFF,0xED,0xFF,0xEC,0xFF,0xDA,0xFF, + 0xF8,0xFF,0xF6,0xFF,0xE1,0xFF,0xEC,0xFF +}; + +#endif //_record_prompt_h_ diff --git a/src/libs/resiprocate/resip/recon/test/sdpTests.cxx b/src/libs/resiprocate/resip/recon/test/sdpTests.cxx new file mode 100644 index 00000000..b8d5fa4d --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/sdpTests.cxx @@ -0,0 +1,594 @@ +#include <iostream> + +#include <sdp/SdpCodec.hxx> +#include <sdp/Sdp.hxx> +#include <sdp/SdpMediaLine.hxx> +#include <sdp/SdpHelperResip.hxx> + +#include <rutil/ParseBuffer.hxx> +#include <resip/stack/Symbols.hxx> +#include <resip/stack/SdpContents.hxx> +#include <resip/stack/HeaderFieldValue.hxx> + +#ifdef WIN32 +#define UINT64_C(val) val##ui64 +#elif __GNUC__ +#define UINT64_C(val) val##ULL +#else +#error Unknown compiler for 64-bit integer constants. +#endif + +using namespace resip; +using namespace sdpcontainer; +using namespace std; + +#ifdef WIN32 +int sdpTests() +#else +int main(int argc, char* argv[]) +#endif +{ + { // Test get/set interfaces + Sdp sdp; + sdp.setSdpVersion(1); + sdp.setOriginatorUserName("Test"); + sdp.setOriginatorSessionId(8888); + sdp.setOriginatorSessionVersion(9999); + sdp.setOriginatorNetType(Sdp::NET_TYPE_IN); + sdp.setOriginatorAddressType(Sdp::ADDRESS_TYPE_IP4); + sdp.setOriginatorUnicastAddress("127.0.0.1"); + sdp.setSessionName("SdpTestSession"); + sdp.setSessionInformation("sample session information"); + sdp.setSessionUri("http://www.sessionuri.com"); + assert(sdp.getSdpVersion() == 1); + assert(sdp.getOriginatorUserName() == "Test"); + assert(sdp.getOriginatorSessionId() == 8888); + assert(sdp.getOriginatorSessionVersion() == 9999); + assert(sdp.getOriginatorNetType() == Sdp::NET_TYPE_IN); + assert(sdp.getOriginatorAddressType() == Sdp::ADDRESS_TYPE_IP4); + assert(sdp.getOriginatorUnicastAddress() == "127.0.0.1"); + assert(sdp.getSessionName() == "SdpTestSession"); + assert(sdp.getSessionInformation() == "sample session information"); + assert(sdp.getSessionUri() == "http://www.sessionuri.com"); + + sdp.addEmailAddress("me@here.com"); + sdp.addEmailAddress("you@there.com"); + assert(sdp.getEmailAddresses().size() == 2); + + sdp.addPhoneNumber("555-555-5555"); + sdp.addPhoneNumber("123-123-1234"); + assert(sdp.getPhoneNumbers().size() == 2); + + sdp.addBandwidth(Sdp::BANDWIDTH_TYPE_CT, 1000); + assert(sdp.getBandwidths().size() == 1); + sdp.clearBandwidths(); + assert(sdp.getBandwidths().size() == 0); + sdp.addBandwidth(Sdp::BANDWIDTH_TYPE_AS, 5000); + sdp.addBandwidth(Sdp::BANDWIDTH_TYPE_CT, 100); + assert(sdp.getBandwidths().size() == 2); + assert(sdp.getBandwidths().front().getType() == Sdp::BANDWIDTH_TYPE_AS); + assert(sdp.getBandwidths().front().getBandwidth() == 5000); + assert(sdp.getBandwidths().back().getType() == Sdp::BANDWIDTH_TYPE_CT); + assert(sdp.getBandwidths().back().getBandwidth() == 100); + + Sdp::SdpTime* sdpTime = new Sdp::SdpTime(100, 200); + Sdp::SdpTime::SdpTimeRepeat* repeat = new Sdp::SdpTime::SdpTimeRepeat(8, 800); + sdpTime->addRepeat(*repeat); + repeat = new Sdp::SdpTime::SdpTimeRepeat(9, 900); + repeat->addOffsetFromStartTime(20); + repeat->addOffsetFromStartTime(21); + sdpTime->addRepeat(*repeat); + sdp.addTime(*sdpTime); + sdp.addTime(300, 400); + assert(sdp.getTimes().size() == 2); + assert(sdp.getTimes().front().getStartTime() == 100); + assert(sdp.getTimes().front().getStopTime() == 200); + assert(sdp.getTimes().front().getRepeats().size() == 2); + assert(sdp.getTimes().front().getRepeats().front().getRepeatInterval() == 8); + assert(sdp.getTimes().front().getRepeats().front().getActiveDuration() == 800); + assert(sdp.getTimes().front().getRepeats().back().getRepeatInterval() == 9); + assert(sdp.getTimes().front().getRepeats().back().getActiveDuration() == 900); + assert(sdp.getTimes().front().getRepeats().back().getOffsetsFromStartTime().size() == 2); + assert(sdp.getTimes().front().getRepeats().back().getOffsetsFromStartTime().front() == 20); + assert(sdp.getTimes().front().getRepeats().back().getOffsetsFromStartTime().back() == 21); + assert(sdp.getTimes().back().getStartTime() == 300); + assert(sdp.getTimes().back().getStopTime() == 400); + sdp.addTimeZone(500, 600); + sdp.addTimeZone(700, 800); + assert(sdp.getTimeZones().size() == 2); + assert(sdp.getTimeZones().front().getAdjustmentTime() == 500); + assert(sdp.getTimeZones().front().getOffset() == 600); + assert(sdp.getTimeZones().back().getAdjustmentTime() == 700); + assert(sdp.getTimeZones().back().getOffset() == 800); + + sdp.setCategory("sample sdp category"); + sdp.setKeywords("sdp session description protocol"); + sdp.setToolNameAndVersion("sipX session description 1.0"); + sdp.setConferenceType(Sdp::CONFERENCE_TYPE_BROADCAST); + sdp.setCharSet("UTF-8"); + sdp.setIcePassiveOnlyMode(true); + assert(sdp.getCategory() == "sample sdp category"); + assert(sdp.getKeywords() == "sdp session description protocol"); + assert(sdp.getToolNameAndVersion() == "sipX session description 1.0"); + assert(sdp.getConferenceType() == Sdp::CONFERENCE_TYPE_BROADCAST); + assert(sdp.getCharSet() == "UTF-8"); + assert(sdp.isIcePassiveOnlyMode() == true); + + Sdp::SdpGroup* group = new Sdp::SdpGroup(Sdp::GROUP_SEMANTICS_LS); + group->addIdentificationTag("media1"); + group->addIdentificationTag("media2"); + sdp.addGroup(*group); + group = new Sdp::SdpGroup(Sdp::GROUP_SEMANTICS_FID); + group->addIdentificationTag("fid1"); + sdp.addGroup(*group); + assert(sdp.getGroups().size() == 2); + assert(sdp.getGroups().front().getSemantics() == Sdp::GROUP_SEMANTICS_LS); + assert(sdp.getGroups().front().getIdentificationTags().size() == 2); + assert(sdp.getGroups().front().getIdentificationTags().front() == "media1"); + assert(sdp.getGroups().front().getIdentificationTags().back() == "media2"); + assert(sdp.getGroups().back().getSemantics() == Sdp::GROUP_SEMANTICS_FID); + assert(sdp.getGroups().back().getIdentificationTags().size() == 1); + assert(sdp.getGroups().back().getIdentificationTags().front() == "fid1"); + + sdp.setSessionLanguage("EN-US"); + sdp.setDescriptionLanguage("FR-CN"); + sdp.setMaximumPacketRate(1.5); + assert(sdp.getSessionLanguage() == "EN-US"); + assert(sdp.getDescriptionLanguage() == "FR-CN"); + assert(sdp.getMaximumPacketRate() == 1.5); + + // Test Copy constructor + Sdp sdp2(sdp); + assert(sdp2.getSdpVersion() == 1); + assert(sdp2.getOriginatorUserName() == "Test"); + assert(sdp2.getOriginatorSessionId() == 8888); + assert(sdp2.getOriginatorSessionVersion() == 9999); + assert(sdp2.getOriginatorNetType() == Sdp::NET_TYPE_IN); + assert(sdp2.getOriginatorAddressType() == Sdp::ADDRESS_TYPE_IP4); + assert(sdp2.getOriginatorUnicastAddress() == "127.0.0.1"); + assert(sdp2.getSessionName() == "SdpTestSession"); + assert(sdp2.getSessionInformation() == "sample session information"); + assert(sdp2.getSessionUri() == "http://www.sessionuri.com"); + assert(sdp2.getEmailAddresses().size() == 2); + assert(sdp2.getBandwidths().size() == 2); + assert(sdp2.getPhoneNumbers().size() == 2); + assert(sdp2.getBandwidths().front().getType() == Sdp::BANDWIDTH_TYPE_AS); + assert(sdp2.getBandwidths().front().getBandwidth() == 5000); + assert(sdp2.getBandwidths().back().getType() == Sdp::BANDWIDTH_TYPE_CT); + assert(sdp2.getBandwidths().back().getBandwidth() == 100); + assert(sdp2.getTimes().size() == 2); + assert(sdp2.getTimes().front().getStartTime() == 100); + assert(sdp2.getTimes().front().getStopTime() == 200); + assert(sdp2.getTimes().front().getRepeats().size() == 2); + assert(sdp2.getTimes().front().getRepeats().front().getRepeatInterval() == 8); + assert(sdp2.getTimes().front().getRepeats().front().getActiveDuration() == 800); + assert(sdp2.getTimes().front().getRepeats().back().getRepeatInterval() == 9); + assert(sdp2.getTimes().front().getRepeats().back().getActiveDuration() == 900); + assert(sdp2.getTimes().front().getRepeats().back().getOffsetsFromStartTime().size() == 2); + assert(sdp2.getTimes().front().getRepeats().back().getOffsetsFromStartTime().front() == 20); + assert(sdp2.getTimes().front().getRepeats().back().getOffsetsFromStartTime().back() == 21); + assert(sdp2.getTimes().back().getStartTime() == 300); + assert(sdp2.getTimes().back().getStopTime() == 400); + assert(sdp2.getTimeZones().size() == 2); + assert(sdp2.getTimeZones().front().getAdjustmentTime() == 500); + assert(sdp2.getTimeZones().front().getOffset() == 600); + assert(sdp2.getTimeZones().back().getAdjustmentTime() == 700); + assert(sdp2.getTimeZones().back().getOffset() == 800); + assert(sdp2.getGroups().size() == 2); + assert(sdp2.getGroups().front().getSemantics() == Sdp::GROUP_SEMANTICS_LS); + assert(sdp2.getGroups().front().getIdentificationTags().size() == 2); + assert(sdp2.getGroups().front().getIdentificationTags().front() == "media1"); + assert(sdp2.getGroups().front().getIdentificationTags().back() == "media2"); + assert(sdp2.getGroups().back().getSemantics() == Sdp::GROUP_SEMANTICS_FID); + assert(sdp2.getGroups().back().getIdentificationTags().size() == 1); + assert(sdp2.getGroups().back().getIdentificationTags().front() == "fid1"); + assert(sdp2.getSessionLanguage() == "EN-US"); + assert(sdp2.getDescriptionLanguage() == "FR-CN"); + assert(sdp2.getMaximumPacketRate() == 1.5); + + SdpMediaLine* mediaLine = new SdpMediaLine(); + mediaLine->setMediaType(SdpMediaLine::MEDIA_TYPE_AUDIO); + mediaLine->setTransportProtocolType(SdpMediaLine::PROTOCOL_TYPE_RTP_AVP); + mediaLine->setTitle("G729a Audio Codec"); + mediaLine->addConnection(Sdp::NET_TYPE_IN, Sdp::ADDRESS_TYPE_IP4, "127.0.0.1", 6000, 90); + mediaLine->addRtcpConnection(Sdp::NET_TYPE_IN, Sdp::ADDRESS_TYPE_IP4, "127.0.0.1", 6001); + mediaLine->addBandwidth(Sdp::BANDWIDTH_TYPE_CT, 10); + mediaLine->setEncryptionKey(SdpMediaLine::ENCRYPTION_METHOD_BASE64, "0123456789ABCD"); + mediaLine->setDirection(SdpMediaLine::DIRECTION_TYPE_SENDRECV); + mediaLine->setPacketTime(20); + mediaLine->setMaxPacketTime(60); + mediaLine->setOrientation(SdpMediaLine::ORIENTATION_TYPE_LANDSCAPE); + mediaLine->setDescriptionLanguage("English"); + mediaLine->setLanguage("EN"); + mediaLine->setFrameRate(256); + mediaLine->setQuality(10); + mediaLine->setTcpConnectionAttribute(SdpMediaLine::TCP_CONNECTION_ATTRIBUTE_NEW); + mediaLine->setTcpSetupAttribute(SdpMediaLine::TCP_SETUP_ATTRIBUTE_ACTPASS); + assert(mediaLine->getMediaType() == SdpMediaLine::MEDIA_TYPE_AUDIO); + assert(mediaLine->getTransportProtocolType() == SdpMediaLine::PROTOCOL_TYPE_RTP_AVP); + assert(mediaLine->getTitle() == "G729a Audio Codec"); + assert(mediaLine->getConnections().size() == 1); + assert(mediaLine->getConnections().front().getNetType() == Sdp::NET_TYPE_IN); + assert(mediaLine->getConnections().front().getAddressType() == Sdp::ADDRESS_TYPE_IP4); + assert(mediaLine->getConnections().front().getAddress() == "127.0.0.1"); + assert(mediaLine->getConnections().front().getPort() == 6000); + assert(mediaLine->getConnections().front().getMulticastIpV4Ttl() == 90); + assert(mediaLine->getRtcpConnections().size() == 1); + assert(mediaLine->getRtcpConnections().front().getNetType() == Sdp::NET_TYPE_IN); + assert(mediaLine->getRtcpConnections().front().getAddressType() == Sdp::ADDRESS_TYPE_IP4); + assert(mediaLine->getRtcpConnections().front().getAddress() == "127.0.0.1"); + assert(mediaLine->getRtcpConnections().front().getPort() == 6001); + assert(mediaLine->getRtcpConnections().front().getMulticastIpV4Ttl() == 0); + assert(mediaLine->getBandwidths().size() == 1); + assert(mediaLine->getEncryptionKey() == "0123456789ABCD"); + assert(mediaLine->getEncryptionMethod() == SdpMediaLine::ENCRYPTION_METHOD_BASE64); + assert(mediaLine->getDirection() == SdpMediaLine::DIRECTION_TYPE_SENDRECV); + assert(mediaLine->getPacketTime() == 20); + assert(mediaLine->getMaxPacketTime() == 60); + assert(mediaLine->getOrientation() == SdpMediaLine::ORIENTATION_TYPE_LANDSCAPE); + assert(mediaLine->getDescriptionLanguage() == "English"); + assert(mediaLine->getLanguage() == "EN"); + assert(mediaLine->getFrameRate() == 256); + assert(mediaLine->getQuality() == 10); + assert(mediaLine->getTcpConnectionAttribute() == SdpMediaLine::TCP_CONNECTION_ATTRIBUTE_NEW); + assert(mediaLine->getTcpSetupAttribute() == SdpMediaLine::TCP_SETUP_ATTRIBUTE_ACTPASS); + + SdpMediaLine::SdpCrypto *crypto = new SdpMediaLine::SdpCrypto; + crypto->setTag(1); + crypto->setSuite(SdpMediaLine::CRYPTO_SUITE_TYPE_AES_CM_128_HMAC_SHA1_32); + crypto->setSrtpFecOrder(SdpMediaLine::CRYPTO_SRTP_FEC_ORDER_SRTP_FEC); + crypto->setSrtpFecKey(SdpMediaLine::CRYPTO_KEY_METHOD_INLINE, "FECKEY", 200000, 2, 8); + crypto->setAuthenticatedSrtp(true); + crypto->setEncryptedSrtcp(true); + crypto->setEncryptedSrtp(true); + crypto->setSrtpKdr(64); + crypto->setSrtpWsh(32); + crypto->addCryptoKeyParam(SdpMediaLine::CRYPTO_KEY_METHOD_INLINE, "CyrptoKey", 10000, 1, 5); + mediaLine->addCryptoSettings(*crypto); + crypto = new SdpMediaLine::SdpCrypto; + crypto->setTag(2); + crypto->setSuite(SdpMediaLine::CRYPTO_SUITE_TYPE_F8_128_HMAC_SHA1_80); + crypto->addCryptoKeyParam(SdpMediaLine::CRYPTO_KEY_METHOD_INLINE, "CryptoKey2"); + crypto->addGenericSessionParam("param1"); + crypto->addGenericSessionParam("param2"); + assert(crypto->getGenericSessionParams().size() == 2); + assert(crypto->getTag() == 2); + assert(crypto->getSuite() == SdpMediaLine::CRYPTO_SUITE_TYPE_F8_128_HMAC_SHA1_80); + assert(crypto->getCryptoKeyParams().size() == 1); + assert(crypto->getCryptoKeyParams().front().getKeyMethod() == SdpMediaLine::CRYPTO_KEY_METHOD_INLINE); + assert(crypto->getCryptoKeyParams().front().getKeyValue() == "CryptoKey2"); + assert(crypto->getGenericSessionParams().size() == 2); + mediaLine->addCryptoSettings(*crypto); + assert(mediaLine->getCryptos().size() == 2); + + mediaLine->setFingerPrint(SdpMediaLine::FINGERPRINT_HASH_FUNC_MD5, "this-is-a-finger-print"); + mediaLine->setKeyManagementProtocol(SdpMediaLine::KEYMANAGEMENT_PROTOCOL_MIKEY, "this-is-some-key-management-data"); + mediaLine->addPreConditionCurrentStatus(SdpMediaLine::PRECONDITION_TYPE_QOS, SdpMediaLine::PRECONDITION_STATUS_E2E, SdpMediaLine::PRECONDITION_DIRECTION_SENDRECV); + mediaLine->addPreConditionCurrentStatus(SdpMediaLine::PRECONDITION_TYPE_QOS, SdpMediaLine::PRECONDITION_STATUS_REMOTE, SdpMediaLine::PRECONDITION_DIRECTION_RECV); + mediaLine->addPreConditionConfirmStatus(SdpMediaLine::PRECONDITION_TYPE_QOS, SdpMediaLine::PRECONDITION_STATUS_E2E, SdpMediaLine::PRECONDITION_DIRECTION_SENDRECV); + mediaLine->addPreConditionConfirmStatus(SdpMediaLine::PRECONDITION_TYPE_QOS, SdpMediaLine::PRECONDITION_STATUS_REMOTE, SdpMediaLine::PRECONDITION_DIRECTION_RECV); + mediaLine->addPreConditionDesiredStatus(SdpMediaLine::PRECONDITION_TYPE_QOS, SdpMediaLine::PRECONDITION_STRENGTH_MANDATORY, SdpMediaLine::PRECONDITION_STATUS_E2E, SdpMediaLine::PRECONDITION_DIRECTION_SENDRECV); + mediaLine->addPreConditionDesiredStatus(SdpMediaLine::PRECONDITION_TYPE_QOS, SdpMediaLine::PRECONDITION_STRENGTH_OPTIONAL, SdpMediaLine::PRECONDITION_STATUS_REMOTE, SdpMediaLine::PRECONDITION_DIRECTION_RECV); + assert(mediaLine->getFingerPrint() == "this-is-a-finger-print"); + assert(mediaLine->getFingerPrintHashFunction() == SdpMediaLine::FINGERPRINT_HASH_FUNC_MD5); + assert(mediaLine->getPreConditionCurrentStatus().size() == 2); + assert(mediaLine->getPreConditionCurrentStatus().front().getType() == SdpMediaLine::PRECONDITION_TYPE_QOS); + assert(mediaLine->getPreConditionCurrentStatus().front().getStatus() == SdpMediaLine::PRECONDITION_STATUS_E2E); + assert(mediaLine->getPreConditionCurrentStatus().back().getDirection() == SdpMediaLine::PRECONDITION_DIRECTION_RECV); + assert(mediaLine->getPreConditionConfirmStatus().size() == 2); + assert(mediaLine->getPreConditionConfirmStatus().front().getType() == SdpMediaLine::PRECONDITION_TYPE_QOS); + assert(mediaLine->getPreConditionConfirmStatus().back().getStatus() == SdpMediaLine::PRECONDITION_STATUS_REMOTE); + assert(mediaLine->getPreConditionConfirmStatus().front().getDirection() == SdpMediaLine::PRECONDITION_DIRECTION_SENDRECV); + assert(mediaLine->getPreConditionDesiredStatus().size() == 2); + assert(mediaLine->getPreConditionDesiredStatus().front().getStrength() == SdpMediaLine::PRECONDITION_STRENGTH_MANDATORY); + assert(mediaLine->getPreConditionDesiredStatus().back().getStatus() == SdpMediaLine::PRECONDITION_STATUS_REMOTE); + assert(mediaLine->getPreConditionDesiredStatus().front().getDirection() == SdpMediaLine::PRECONDITION_DIRECTION_SENDRECV); + + mediaLine->setMaximumPacketRate(20); + mediaLine->setLabel("G711 Label"); + mediaLine->setIdentificationTag("item1"); + mediaLine->setIceUserFrag("ICEUSER"); + mediaLine->setIcePassword("ICEPASSWORD"); + mediaLine->addRemoteCandidate(1, "127.0.0.1", 5060); + mediaLine->addRemoteCandidate(2, "127.0.0.2", 5061); + assert(mediaLine->getMaximumPacketRate() == 20); + assert(mediaLine->getLabel() == "G711 Label"); + assert(mediaLine->getIdentificationTag() == "item1"); + assert(mediaLine->getIceUserFrag() == "ICEUSER"); + assert(mediaLine->getIcePassword() == "ICEPASSWORD"); + assert(mediaLine->getRemoteCandidates().size() == 2); + assert(mediaLine->getRemoteCandidates().front().getComponentId() == 1); + assert(mediaLine->getRemoteCandidates().front().getConnectionAddress() == "127.0.0.1"); + assert(mediaLine->getRemoteCandidates().front().getPort() == 5060); + + mediaLine->addCandidate("id1", 1, SdpCandidate::CANDIDATE_TRANSPORT_TYPE_UDP, 100, "127.0.0.1", 6000, SdpCandidate::CANDIDATE_TYPE_HOST); + mediaLine->addCandidate("id1", 2, SdpCandidate::CANDIDATE_TRANSPORT_TYPE_UDP, 50, "127.0.0.1", 6000, SdpCandidate::CANDIDATE_TYPE_SRFLX); + mediaLine->addCandidate("id2", 1, SdpCandidate::CANDIDATE_TRANSPORT_TYPE_UDP, 101, "192.168.1.2", 5060, SdpCandidate::CANDIDATE_TYPE_RELAY, "127.0.0.3", 5080); + mediaLine->addCandidate("id2", 1, SdpCandidate::CANDIDATE_TRANSPORT_TYPE_UDP, 100, "127.0.0.1", 6001, SdpCandidate::CANDIDATE_TYPE_HOST); + assert(mediaLine->getCandidates().size() == 4); + // Note: this list is ordered + SdpMediaLine::SdpCandidateList::const_iterator it = mediaLine->getCandidates().begin(); + assert(it->getPriority() == 101); + assert(it->getFoundation() == "id2"); + assert(it->getId() == 1); + assert(it->getTransport() == SdpCandidate::CANDIDATE_TRANSPORT_TYPE_UDP); + assert(it->getConnectionAddress() == "192.168.1.2"); + assert(it->getPort() == 5060); + assert(it->getCandidateType() == SdpCandidate::CANDIDATE_TYPE_RELAY); + assert(it->getRelatedAddress() == "127.0.0.3"); + assert(it->getRelatedPort() == 5080); + assert(it->getExtensionAttributes().size() == 0); + assert(it->isInUse() == false); + it++; + assert(it->getPriority() == 100); + assert(it->getFoundation() == "id1"); + assert(it->getRelatedAddress() == ""); + assert(it->getRelatedPort() == 0); + assert(it->isInUse() == true); + it++; + assert(it->getPriority() == 100); + assert(it->getFoundation() == "id2"); + assert(it->isInUse() == true); + it++; + assert(it->getPriority() == 50); + assert(it->getFoundation() == "id1"); + assert(it->isInUse() == true); + + assert(mediaLine->isIceSupported() == true); + + sdp.addMediaLine(mediaLine); + assert(sdp.getMediaLines().size() == 1); + + mediaLine = new SdpMediaLine(); + SdpCodec* codec = new SdpCodec(19, "audio", "G729", 8000, 20, 1, "annexb=no"); + assert(codec->getPayloadType() == 19); + assert(codec->getMimeType() == "audio"); + assert(codec->getMimeSubtype() == "G729"); + assert(codec->getRate() == 8000); + assert(codec->getPacketTime() == 20); + assert(codec->getNumChannels() == 1); + assert(codec->getFormatParameters() == "annexb=no"); + mediaLine->addCodec(*codec); + assert(mediaLine->getCodecs().size() == 1); + + SdpCandidate* sdpLocalCandidate = new SdpCandidate("f1", 1, SdpCandidate::CANDIDATE_TRANSPORT_TYPE_UDP, 100, "192.168.1.1", 6000, SdpCandidate::CANDIDATE_TYPE_HOST); + SdpCandidate* sdpRemoteCandidate = new SdpCandidate("a1", 1, SdpCandidate::CANDIDATE_TRANSPORT_TYPE_UDP, 55, "192.168.1.1", 2345, SdpCandidate::CANDIDATE_TYPE_HOST); + mediaLine->addCandidate(*sdpLocalCandidate); + assert(mediaLine->getCandidates().size() == 1); + mediaLine->addCandidatePair(*sdpLocalCandidate, *sdpRemoteCandidate, SdpCandidatePair::OFFERER_REMOTE); + assert(mediaLine->getCandidatePairs().size() == 1); + delete sdpRemoteCandidate; + sdpLocalCandidate = new SdpCandidate("f1", 2, SdpCandidate::CANDIDATE_TRANSPORT_TYPE_UDP, 101, "192.168.1.1", 6001, SdpCandidate::CANDIDATE_TYPE_HOST); + sdpRemoteCandidate = new SdpCandidate("a1", 2, SdpCandidate::CANDIDATE_TRANSPORT_TYPE_UDP, 56, "192.168.1.1", 2346, SdpCandidate::CANDIDATE_TYPE_HOST); + mediaLine->addCandidate(*sdpLocalCandidate); + assert(mediaLine->getCandidates().size() == 2); + mediaLine->addCandidatePair(*sdpLocalCandidate, *sdpRemoteCandidate, SdpCandidatePair::OFFERER_LOCAL); + assert(mediaLine->getCandidatePairs().size() == 2); + SdpMediaLine::SdpCandidatePairList& candidatePairs = mediaLine->getCandidatePairs(); + SdpMediaLine::SdpCandidatePairList::iterator it2 = candidatePairs.begin(); + assert(it2->getPriority() == UINT64_C(240518168779)); + assert(it2->getLocalCandidate().getPort() == 6001); + assert(it2->getRemoteCandidate().getPort() == 2346); + assert(it2->getOfferer() == SdpCandidatePair::OFFERER_LOCAL); + assert(it2->getCheckState() == SdpCandidatePair::CHECK_STATE_FROZEN); + // Note: TODO - In g++ std:set members are inmutable, and cannot be modified - will need to change to another type + //it2->setCheckState(SdpCandidatePair::CHECK_STATE_WAITING); + //assert(it2->getCheckState() == SdpCandidatePair::CHECK_STATE_WAITING); + it2++; + assert(it2->getPriority() == UINT64_C(236223201480)); + + delete sdpRemoteCandidate; + + sdp.addMediaLine(mediaLine); + assert(sdp.getMediaLines().size() == 2); + + // Ensure string builder does not crash + resipCout << sdp << std::endl; + + // Test FoundationId interface + assert(sdp.getLocalFoundationId(SdpCandidate::CANDIDATE_TYPE_HOST, "127.0.0.1") == "1"); + assert(sdp.getLocalFoundationId(SdpCandidate::CANDIDATE_TYPE_HOST, "127.0.0.1") == "1"); + assert(sdp.getLocalFoundationId(SdpCandidate::CANDIDATE_TYPE_HOST, "127.0.0.2") == "2"); + assert(sdp.getLocalFoundationId(SdpCandidate::CANDIDATE_TYPE_HOST, "127.0.0.2", "192.168.1.1") == "3"); + assert(sdp.getLocalFoundationId(SdpCandidate::CANDIDATE_TYPE_HOST, "127.0.0.2") == "2"); + assert(sdp.getLocalFoundationId(SdpCandidate::CANDIDATE_TYPE_HOST, "127.0.0.2", "192.168.1.1") == "3"); + } + + { + // Test helpers + char txt[] = "v=0\r\n" + "o=- 333525334858460 333525334858460 IN IP4 192.168.0.156\r\n" + "s=test123\r\n" + "e=unknown@invalid.net\r\n" + "p=+972 683 1000\r\n" + "c=IN IP4 127.0.0.1\r\n" + "b=RR:0\r\n" + "b=RS:0\r\n" + "b=CT:10000\r\n" + "t=4058038202 0\r\n" + "k=base64:base64key\r\n" + "a=tool:ResipParserTester\r\n" + "a=inactive\r\n" + "m=audio 41466/6 RTP/AVP 0 101\r\n" + "i=Audio Stream\r\n" + "c=IN IP4 192.168.0.156/100/3\r\n" + "c=IN IP6 FF15::101/3\r\n" + "k=clear:base64clearkey\r\n" + "a=fmtp:101 0-11\r\n" + "a=ptime:20\r\n" + "a=fmtp:0 annexb=no\r\n" + "a=maxptime:40\r\n" + "a=setup:active\r\n" + "a=sendrecv\r\n" + "a=rtpmap:101 telephone-event/8000\r\n" + "a=crypto:1 F8_128_HMAC_SHA1_80 inline:MTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5QUJjZGVm|2^20|1:4;inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20|2:4 FEC_ORDER=FEC_SRTP\r\n" + "m=video 21234 RTP/AVP 140\r\n" + "b=RR:1\r\n" + "b=RS:0\r\n" + "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2:18;inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|21|3:4 KDR=23 FEC_ORDER=SRTP_FEC UNENCRYPTED_SRTP\r\n" + "a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20 FEC_KEY=inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20|2:4 WSH=60\r\n" + "a=fingerprint:sha-1 0123456789\r\n" + "a=key-mgmt:mikey thisissomebase64data\r\n" + "a=curr:qos e2e sendrecv\r\n" + "a=curr:qos local send\r\n" + "a=des:qos mandatory e2e sendrecv\r\n" + "a=des:qos optional local send\r\n" + "a=conf:qos e2e none\r\n" + "a=conf:qos remote recv\r\n" + "a=remote-candidates:1 192.168.0.1 5060 2 192.168.0.1 5061\r\n" + "a=remote-candidates:3 192.168.0.2 5063\r\n" + "a=candidate:foundation1 1 udp 100000 127.0.0.1 21234 typ host raddr 127.0.0.8 rport 6667 name value name2 value2\r\n" + "a=candidate:foundation2 2 udp 100001 192.168.0.1 6667 raddr 127.0.0.9 rport 6668 name value name2 value2\r\n" + "a=candidate:foundation3 3 udp 100002 192.168.0.2 6668 raddr 127.0.0.9 name value name2 value2\r\n" + "a=candidate:foundation3 3 udp 100002 123.123.123.124 127 name value name2 value2\r\n" + "a=candidate:foundation3 3 udp 100002 192.168.0.2 6668 typ relay\r\n" + "a=rtcp:127 IN IP4 123.123.123.124/60\r\n" + "a=rtpmap:140 vp71/144000\r\n" + "a=fmtp:140 CIF=1 QCIF=2 SQCIF\r\n"; + + Sdp* convSdp; + + { // Test resip helper + HeaderFieldValue hfv(txt, sizeof(txt)); + Mime type("application", "sdp"); + SdpContents resipSdp(hfv, type); + + convSdp = SdpHelperResip::createSdpFromResipSdp(resipSdp); + if(convSdp) + { + // Ensure string builder does not crash + resipCout << "\n\nResip Sdp Helper Test:" << endl << *convSdp << endl; + + // Perform some random assertions + assert(convSdp->getLocalFoundationId(SdpCandidate::CANDIDATE_TYPE_HOST, "127.0.0.1") == "1"); + assert(convSdp->getOriginatorUnicastAddress() == "192.168.0.156"); + assert(convSdp->getSessionName() == "test123"); + assert(convSdp->getEmailAddresses().size() == 1); + assert(convSdp->getPhoneNumbers().size() == 1); + assert(convSdp->getBandwidths().size() == 3); + assert(convSdp->getTimes().size() == 1); + assert(convSdp->getToolNameAndVersion() == "ResipParserTester"); + assert(convSdp->getMediaLines().size() == 2); + assert(convSdp->getMediaLines().front()->getMediaType() == SdpMediaLine::MEDIA_TYPE_AUDIO); + assert(convSdp->getMediaLines().back()->getMediaType() == SdpMediaLine::MEDIA_TYPE_VIDEO); + assert(convSdp->getMediaLines().front()->getTransportProtocolType() == SdpMediaLine::PROTOCOL_TYPE_RTP_AVP); + assert(convSdp->getMediaLines().front()->getCodecs().size() == 2); + assert(convSdp->getMediaLines().back()->getCodecs().size() == 1); + assert(convSdp->getMediaLines().front()->getCodecs().front().getPayloadType() == 0); + assert(convSdp->getMediaLines().front()->getCodecs().back().getPayloadType() == 101); + assert(convSdp->getMediaLines().back()->getCodecs().front().getPayloadType() == 140); + assert(convSdp->getMediaLines().front()->getCodecs().back().getFormatParameters() == "0-11"); + assert(convSdp->getMediaLines().front()->getConnections().size() == 6); + assert(convSdp->getMediaLines().back()->getConnections().size() == 1); + assert(convSdp->getMediaLines().front()->getRtcpConnections().size() == 0); + assert(convSdp->getMediaLines().back()->getRtcpConnections().size() == 1); + assert(convSdp->getMediaLines().front()->getConnections().front().getAddress() == "192.168.0.156"); + assert(convSdp->getMediaLines().front()->getConnections().front().getPort() == 41466); + assert(convSdp->getMediaLines().back()->getRtcpConnections().front().getPort() == 127); + assert(convSdp->getMediaLines().front()->getBandwidths().size() == 0); + assert(convSdp->getMediaLines().back()->getBandwidths().size() == 2); + assert(convSdp->getMediaLines().front()->getEncryptionKey() == "base64clearkey"); + assert(convSdp->getMediaLines().front()->getDirection() == SdpMediaLine::DIRECTION_TYPE_SENDRECV); + assert(convSdp->getMediaLines().back()->getDirection() == SdpMediaLine::DIRECTION_TYPE_INACTIVE); + assert(convSdp->getMediaLines().front()->getPacketTime() == 20); + assert(convSdp->getMediaLines().front()->getTcpConnectionAttribute() == SdpMediaLine::TCP_CONNECTION_ATTRIBUTE_NONE); + assert(convSdp->getMediaLines().front()->getTcpSetupAttribute() == SdpMediaLine::TCP_SETUP_ATTRIBUTE_ACTIVE); + assert(convSdp->getMediaLines().front()->getCryptos().size() == 1); + assert(convSdp->getMediaLines().back()->getCryptos().size() == 2); + assert(convSdp->getMediaLines().front()->getCandidates().size() == 0); + assert(convSdp->getMediaLines().back()->getCandidates().size() == 5); + assert(convSdp->getMediaLines().back()->getRemoteCandidates().size() == 3); + assert(convSdp->getMediaLines().back()->getPreConditionCurrentStatus().size() == 2); + assert(convSdp->getMediaLines().back()->getPreConditionConfirmStatus().size() == 2); + assert(convSdp->getMediaLines().back()->getPreConditionDesiredStatus().size() == 2); + + // Copy test + Sdp copySdp(*convSdp); + + // Ensure string builder does not crash + resipCout << copySdp << endl; + + // Perform some random assertions on copy + assert(copySdp.getLocalFoundationId(SdpCandidate::CANDIDATE_TYPE_HOST, "127.0.0.2") == "2"); + assert(copySdp.getOriginatorUnicastAddress() == "192.168.0.156"); + assert(copySdp.getSessionName() == "test123"); + assert(copySdp.getEmailAddresses().size() == 1); + assert(copySdp.getPhoneNumbers().size() == 1); + assert(copySdp.getBandwidths().size() == 3); + assert(copySdp.getTimes().size() == 1); + assert(copySdp.getToolNameAndVersion() == "ResipParserTester"); + assert(copySdp.getMediaLines().size() == 2); + assert(copySdp.getMediaLines().front()->getMediaType() == SdpMediaLine::MEDIA_TYPE_AUDIO); + assert(copySdp.getMediaLines().back()->getMediaType() == SdpMediaLine::MEDIA_TYPE_VIDEO); + assert(copySdp.getMediaLines().front()->getTransportProtocolType() == SdpMediaLine::PROTOCOL_TYPE_RTP_AVP); + assert(copySdp.getMediaLines().front()->getCodecs().size() == 2); + assert(copySdp.getMediaLines().back()->getCodecs().size() == 1); + assert(copySdp.getMediaLines().front()->getCodecs().front().getPayloadType() == 0); + assert(copySdp.getMediaLines().front()->getCodecs().back().getPayloadType() == 101); + assert(copySdp.getMediaLines().back()->getCodecs().front().getPayloadType() == 140); + assert(copySdp.getMediaLines().front()->getCodecs().back().getFormatParameters() == "0-11"); + assert(copySdp.getMediaLines().front()->getConnections().size() == 6); + assert(copySdp.getMediaLines().back()->getConnections().size() == 1); + assert(copySdp.getMediaLines().front()->getRtcpConnections().size() == 0); + assert(copySdp.getMediaLines().back()->getRtcpConnections().size() == 1); + assert(copySdp.getMediaLines().front()->getConnections().front().getAddress() == "192.168.0.156"); + assert(copySdp.getMediaLines().front()->getConnections().front().getPort() == 41466); + assert(copySdp.getMediaLines().back()->getRtcpConnections().front().getPort() == 127); + assert(copySdp.getMediaLines().front()->getBandwidths().size() == 0); + assert(copySdp.getMediaLines().back()->getBandwidths().size() == 2); + assert(copySdp.getMediaLines().front()->getEncryptionKey() == "base64clearkey"); + assert(copySdp.getMediaLines().front()->getDirection() == SdpMediaLine::DIRECTION_TYPE_SENDRECV); + assert(copySdp.getMediaLines().back()->getDirection() == SdpMediaLine::DIRECTION_TYPE_INACTIVE); + assert(copySdp.getMediaLines().front()->getPacketTime() == 20); + assert(copySdp.getMediaLines().front()->getTcpConnectionAttribute() == SdpMediaLine::TCP_CONNECTION_ATTRIBUTE_NONE); + assert(copySdp.getMediaLines().front()->getTcpSetupAttribute() == SdpMediaLine::TCP_SETUP_ATTRIBUTE_ACTIVE); + assert(copySdp.getMediaLines().front()->getCryptos().size() == 1); + assert(copySdp.getMediaLines().back()->getCryptos().size() == 2); + assert(copySdp.getMediaLines().front()->getCandidates().size() == 0); + assert(copySdp.getMediaLines().back()->getCandidates().size() == 5); + assert(copySdp.getMediaLines().back()->getRemoteCandidates().size() == 3); + assert(copySdp.getMediaLines().back()->getPreConditionCurrentStatus().size() == 2); + assert(copySdp.getMediaLines().back()->getPreConditionConfirmStatus().size() == 2); + assert(copySdp.getMediaLines().back()->getPreConditionDesiredStatus().size() == 2); + delete convSdp; + } + } + } + + return 0; +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/test/testUA.cxx b/src/libs/resiprocate/resip/recon/test/testUA.cxx new file mode 100644 index 00000000..d1c426b2 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/testUA.cxx @@ -0,0 +1,1566 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> +#ifdef WIN32 +#include <conio.h> +#else +/** + Linux (POSIX) implementation of _kbhit(). + Morgan McGuire, morgan@cs.brown.edu + */ +#include <stdio.h> +#include <sys/select.h> +#include <termios.h> +#ifndef __GNUC__ + #include <stropts.h> +#endif +#include <sys/ioctl.h> + +int _kbhit() { + static const int STDIN = 0; + static bool initialized = false; + + if (! initialized) { + // Use termios to turn off line buffering + termios term; + tcgetattr(STDIN, &term); + term.c_lflag &= ~ICANON; + tcsetattr(STDIN, TCSANOW, &term); + setbuf(stdin, NULL); + initialized = true; + } + + int bytesWaiting; + ioctl(STDIN, FIONREAD, &bytesWaiting); + return bytesWaiting; +} +#endif + +#include "../UserAgent.hxx" +#include "../ReconSubsystem.hxx" + +#include <os/OsSysLog.h> + +// Test Prompts for cache testing +#include "playback_prompt.h" +#include "record_prompt.h" + +#include <rutil/Log.hxx> +#include <rutil/Logger.hxx> +#include <rutil/DnsUtil.hxx> +#include <rutil/BaseException.hxx> +#include <rutil/WinLeakCheck.hxx> + +using namespace recon; +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +void sleepSeconds(unsigned int seconds) +{ +#ifdef WIN32 + Sleep(seconds*1000); +#else + sleep(seconds); +#endif +} + +static bool finished = false; +NameAddr uri("sip:noreg@127.0.0.1"); +bool autoAnswerEnabled = false; // If enabled then testUA will automatically answer incoming calls by adding to lowest numbered conversation +SharedPtr<ConversationProfile> conversationProfile; + +static void +signalHandler(int signo) +{ + std::cerr << "Shutting down" << endl; + finished = true; +} + +class MyUserAgent : public UserAgent +{ +public: + MyUserAgent(ConversationManager* conversationManager, SharedPtr<UserAgentMasterProfile> profile) : + UserAgent(conversationManager, profile) {} + + virtual void onApplicationTimer(unsigned int id, unsigned int durationMs, unsigned int seq) + { + InfoLog(<< "onApplicationTimeout: id=" << id << " dur=" << durationMs << " seq=" << seq); + } + + virtual void onSubscriptionTerminated(SubscriptionHandle handle, unsigned int statusCode) + { + InfoLog(<< "onSubscriptionTerminated: handle=" << handle << " statusCode=" << statusCode); + } + + virtual void onSubscriptionNotify(SubscriptionHandle handle, Data& notifyData) + { + InfoLog(<< "onSubscriptionNotify: handle=" << handle << " data=" << endl << notifyData); + } +}; + +class MyConversationManager : public ConversationManager +{ +public: + + MyConversationManager(bool localAudioEnabled) + : ConversationManager(localAudioEnabled), + mLocalAudioEnabled(localAudioEnabled) + { + }; + + virtual void startup() + { + if(mLocalAudioEnabled) + { + // Create initial local participant and conversation + addParticipant(createConversation(), createLocalParticipant()); + resip::Uri uri("tone:dialtone;duration=1000"); + createMediaResourceParticipant(mConversationHandles.front(), uri); + } + else + { + // If no local audio - just create a starter conversation + createConversation(); + } + + // Load 2 items into cache for testing + { + resip::Data buffer(Data::Share, (const char*)playback_prompt, sizeof(playback_prompt)); + resip::Data name("playback"); + addBufferToMediaResourceCache(name, buffer, 0); + } + { + resip::Data buffer(Data::Share, (const char *)record_prompt, sizeof(record_prompt)); + resip::Data name("record"); + addBufferToMediaResourceCache(name, buffer, 0); + } + } + + + virtual ConversationHandle createConversation() + { + ConversationHandle convHandle = ConversationManager::createConversation(); + mConversationHandles.push_back(convHandle); + return convHandle; + } + + virtual ParticipantHandle createRemoteParticipant(ConversationHandle convHandle, NameAddr& destination, ParticipantForkSelectMode forkSelectMode = ForkSelectAutomatic) + { + ParticipantHandle partHandle = ConversationManager::createRemoteParticipant(convHandle, destination, forkSelectMode); + mRemoteParticipantHandles.push_back(partHandle); + return partHandle; + } + + virtual ParticipantHandle createMediaResourceParticipant(ConversationHandle convHandle, const Uri& mediaUrl) + { + ParticipantHandle partHandle = ConversationManager::createMediaResourceParticipant(convHandle, mediaUrl); + mMediaParticipantHandles.push_back(partHandle); + return partHandle; + } + + virtual ParticipantHandle createLocalParticipant() + { + ParticipantHandle partHandle = ConversationManager::createLocalParticipant(); + mLocalParticipantHandles.push_back(partHandle); + return partHandle; + } + + virtual void onConversationDestroyed(ConversationHandle convHandle) + { + InfoLog(<< "onConversationDestroyed: handle=" << convHandle); + mConversationHandles.remove(convHandle); + } + + virtual void onParticipantDestroyed(ParticipantHandle partHandle) + { + InfoLog(<< "onParticipantDestroyed: handle=" << partHandle); + // Remove from whatever list it is in + mRemoteParticipantHandles.remove(partHandle); + mLocalParticipantHandles.remove(partHandle); + mMediaParticipantHandles.remove(partHandle); + } + + virtual void onDtmfEvent(ParticipantHandle partHandle, int dtmf, int duration, bool up) + { + InfoLog(<< "onDtmfEvent: handle=" << partHandle << " tone=" << dtmf << " dur=" << duration << " up=" << up); + } + + virtual void onIncomingParticipant(ParticipantHandle partHandle, const SipMessage& msg, bool autoAnswer, ConversationProfile& conversationProfile) + { + InfoLog(<< "onIncomingParticipant: handle=" << partHandle << "auto=" << autoAnswer << " msg=" << msg.brief()); + mRemoteParticipantHandles.push_back(partHandle); + if(autoAnswerEnabled) + { + // If there are no conversations, then create one + if(mConversationHandles.empty()) + { + ConversationHandle convHandle = createConversation(); + // ensure a local participant is in the conversation - create one if one doesn't exist + if(mLocalParticipantHandles.empty()) + { + createLocalParticipant(); + } + addParticipant(convHandle, mLocalParticipantHandles.front()); + } + addParticipant(mConversationHandles.front(), partHandle); + answerParticipant(partHandle); + } + } + + virtual void onRequestOutgoingParticipant(ParticipantHandle partHandle, const SipMessage& msg, ConversationProfile& conversationProfile) + { + InfoLog(<< "onRequestOutgoingParticipant: handle=" << partHandle << " msg=" << msg.brief()); + /* + if(mConvHandles.empty()) + { + ConversationHandle convHandle = createConversation(); + addParticipant(convHandle, partHandle); + }*/ + } + + virtual void onParticipantTerminated(ParticipantHandle partHandle, unsigned int statusCode) + { + InfoLog(<< "onParticipantTerminated: handle=" << partHandle); + } + + virtual void onParticipantProceeding(ParticipantHandle partHandle, const SipMessage& msg) + { + InfoLog(<< "onParticipantProceeding: handle=" << partHandle << " msg=" << msg.brief()); + } + + virtual void onRelatedConversation(ConversationHandle relatedConvHandle, ParticipantHandle relatedPartHandle, + ConversationHandle origConvHandle, ParticipantHandle origPartHandle) + { + InfoLog(<< "onRelatedConversation: relatedConvHandle=" << relatedConvHandle << " relatedPartHandle=" << relatedPartHandle + << " origConvHandle=" << origConvHandle << " origPartHandle=" << origPartHandle); + mConversationHandles.push_back(relatedConvHandle); + mRemoteParticipantHandles.push_back(relatedPartHandle); + } + + virtual void onParticipantAlerting(ParticipantHandle partHandle, const SipMessage& msg) + { + InfoLog(<< "onParticipantAlerting: handle=" << partHandle << " msg=" << msg.brief()); + } + + virtual void onParticipantConnected(ParticipantHandle partHandle, const SipMessage& msg) + { + InfoLog(<< "onParticipantConnected: handle=" << partHandle << " msg=" << msg.brief()); + } + + virtual void onParticipantRedirectSuccess(ParticipantHandle partHandle) + { + InfoLog(<< "onParticipantRedirectSuccess: handle=" << partHandle); + } + + virtual void onParticipantRedirectFailure(ParticipantHandle partHandle, unsigned int statusCode) + { + InfoLog(<< "onParticipantRedirectFailure: handle=" << partHandle << " statusCode=" << statusCode); + } + + void displayInfo() + { + Data output; + + if(!mConversationHandles.empty()) + { + output = "Active conversation handles: "; + std::list<ConversationHandle>::iterator it; + for(it = mConversationHandles.begin(); it != mConversationHandles.end(); it++) + { + output += Data(*it) + " "; + } + InfoLog(<< output); + } + if(!mLocalParticipantHandles.empty()) + { + output = "Local Participant handles: "; + std::list<ParticipantHandle>::iterator it; + for(it = mLocalParticipantHandles.begin(); it != mLocalParticipantHandles.end(); it++) + { + output += Data(*it) + " "; + } + InfoLog(<< output); + } + if(!mRemoteParticipantHandles.empty()) + { + output = "Remote Participant handles: "; + std::list<ParticipantHandle>::iterator it; + for(it = mRemoteParticipantHandles.begin(); it != mRemoteParticipantHandles.end(); it++) + { + output += Data(*it) + " "; + } + InfoLog(<< output); + } + if(!mMediaParticipantHandles.empty()) + { + output = "Media Participant handles: "; + std::list<ParticipantHandle>::iterator it; + for(it = mMediaParticipantHandles.begin(); it != mMediaParticipantHandles.end(); it++) + { + output += Data(*it) + " "; + } + InfoLog(<< output); + } + } + + std::list<ConversationHandle> mConversationHandles; + std::list<ParticipantHandle> mLocalParticipantHandles; + std::list<ParticipantHandle> mRemoteParticipantHandles; + std::list<ParticipantHandle> mMediaParticipantHandles; + bool mLocalAudioEnabled; +}; + +void processCommandLine(Data& commandline, MyConversationManager& myConversationManager, MyUserAgent& myUserAgent) +{ + Data command; +#define MAX_ARGS 5 + Data arg[MAX_ARGS]; + ParseBuffer pb(commandline); + pb.skipWhitespace(); + if(pb.eof()) return; + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace); + pb.data(command, start); + + // Get arguments (up to MAX_ARGS) + int currentArg = 0; + while(!pb.eof() && currentArg < MAX_ARGS) + { + pb.skipWhitespace(); + if(!pb.eof()) + { + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace); + pb.data(arg[currentArg++], start); + } + } + + // Process commands + if(isEqualNoCase(command, "quit") || isEqualNoCase(command, "q") || isEqualNoCase(command, "exit")) + { + finished=true; + return; + } + if(isEqualNoCase(command, "createconv") || isEqualNoCase(command, "cc")) + { + myConversationManager.createConversation(); + return; + } + if(isEqualNoCase(command, "destroyconv") || isEqualNoCase(command, "dc")) + { + unsigned long handle = arg[0].convertUnsignedLong(); + if(handle != 0) + { + myConversationManager.destroyConversation(handle); + } + else + { + InfoLog( << "Invalid command format: <'destroyconv'|'dc'> <convHandle>"); + } + return; + } + if(isEqualNoCase(command, "joinconv") || isEqualNoCase(command, "jc")) + { + unsigned long handleSrc = arg[0].convertUnsignedLong(); + unsigned long handleDest = arg[1].convertUnsignedLong(); + if(handleSrc != 0 && handleDest != 0) + { + myConversationManager.joinConversation(handleSrc, handleDest); + } + else + { + InfoLog( << "Invalid command format: <'joinconv'|'jc'> <sourceConvHandle> <destConvHandle>"); + } + return; + } + if(isEqualNoCase(command, "createlocal") || isEqualNoCase(command, "clp")) + { + myConversationManager.createLocalParticipant(); + return; + } + if(isEqualNoCase(command, "createremote") || isEqualNoCase(command, "crp")) + { + unsigned long handle = arg[0].convertUnsignedLong(); + ConversationManager::ParticipantForkSelectMode mode = ConversationManager::ForkSelectAutomatic; + if(handle != 0 && !arg[1].empty()) + { + if(!arg[2].empty() && isEqualNoCase(arg[2], "manual")) + { + mode = ConversationManager::ForkSelectManual; + } + try + { + NameAddr dest(arg[1]); + myConversationManager.createRemoteParticipant(handle, dest, mode); + } + catch(...) + { + NameAddr dest(uri); + dest.uri().user() = arg[1]; + myConversationManager.createRemoteParticipant(handle, dest, mode); + } + } + else + { + InfoLog( << "Invalid command format: <'createremote'|'crp'> <convHandle> <destURI> [<'manual'>] (last arg is fork select mode, 'auto' is default)."); + } + return; + } + if(isEqualNoCase(command, "createmedia") || isEqualNoCase(command, "cmp")) + { + unsigned long handle = arg[0].convertUnsignedLong(); + unsigned long duration = arg[2].convertUnsignedLong(); + if(handle != 0 && !arg[1].empty()) + { + try + { + Uri url(arg[1]); + if(duration != 0) + { + url.param(p_duration) = duration; + } + myConversationManager.createMediaResourceParticipant(handle, url); + } + catch(resip::BaseException& e) + { + InfoLog( << "Invalid url format: <'createmedia'|'cmp'> <convHandle> <mediaURL> [<durationMs>]: " << e); + } + catch(...) + { + InfoLog( << "Invalid url format: <'createmedia'|'cmp'> <convHandle> <mediaURL> [<durationMs>]"); + } + } + else + { + //myConversationManager.createMediaResourceParticipant(1, Uri("http://www.sillyhumor.com/answer/helloo.wav")); + InfoLog( << "Invalid command format: <'createmedia'|'cmp'> <convHandle> <mediaURL> [<durationMs>]"); + } + return; + } + if(isEqualNoCase(command, "destroypart") || isEqualNoCase(command, "dp")) + { + unsigned long handle = arg[0].convertUnsignedLong(); + if(handle != 0) + { + myConversationManager.destroyParticipant(handle); + } + else + { + InfoLog( << "Invalid command format: <'destroypart'|'dp'> <parthandle>"); + } + return; + } + if(isEqualNoCase(command, "addpart") || isEqualNoCase(command, "ap")) + { + unsigned long convHandle = arg[0].convertUnsignedLong(); + unsigned long partHandle = arg[1].convertUnsignedLong(); + if(convHandle != 0 && partHandle != 0) + { + myConversationManager.addParticipant(convHandle, partHandle); + } + else + { + InfoLog( << "Invalid command format: <'addpart'|'ap'> <convHandle> <partHandle>"); + } + return; + } + if(isEqualNoCase(command, "remotepart") || isEqualNoCase(command, "rp")) + { + unsigned long convHandle = arg[0].convertUnsignedLong(); + unsigned long partHandle = arg[1].convertUnsignedLong(); + if(convHandle != 0 && partHandle != 0) + { + myConversationManager.removeParticipant(convHandle, partHandle); + } + else + { + InfoLog( << "Invalid command format: <'removepart'|'rp'> <convHandle> <partHandle>"); + } + return; + } + if(isEqualNoCase(command, "movepart") || isEqualNoCase(command, "mp")) + { + unsigned long partHandle = arg[0].convertUnsignedLong(); + unsigned long srcConvHandle = arg[1].convertUnsignedLong(); + unsigned long dstConvHandle = arg[2].convertUnsignedLong(); + if(partHandle != 0 && srcConvHandle != 0 && dstConvHandle != 0) + { + myConversationManager.moveParticipant(partHandle, srcConvHandle, dstConvHandle); + } + else + { + InfoLog( << "Invalid command format: <'movepart'|'mp'> <partHandle> <srcConvHandle> <dstConvHandle>"); + } + return; + } + if(isEqualNoCase(command, "partcontrib") || isEqualNoCase(command, "pc")) + { + unsigned long convHandle = arg[0].convertUnsignedLong(); + unsigned long partHandle = arg[1].convertUnsignedLong(); + if(partHandle != 0 && convHandle != 0) + { + myConversationManager.modifyParticipantContribution(convHandle, partHandle, arg[2].convertUnsignedLong(), arg[3].convertUnsignedLong()); + } + else + { + InfoLog( << "Invalid command format: <'partcontrib'|'pc'> <convHandle> <partHandle> <inputGain> <outputGain> (gain in percentage)"); + } + return; + } + if(isEqualNoCase(command, "bridgematrix") || isEqualNoCase(command, "bm")) + { + myConversationManager.outputBridgeMatrix(); + return; + } + if(isEqualNoCase(command, "alert") || isEqualNoCase(command, "al")) + { + unsigned long partHandle = arg[0].convertUnsignedLong(); + bool early = true; + if(partHandle != 0) + { + if(!arg[1].empty() && isEqualNoCase(arg[1], "noearly")) + { + early = false; + } + myConversationManager.alertParticipant(partHandle, early); + } + else + { + InfoLog( << "Invalid command format: <'alert'|'al'> <partHandle> [<'noearly'>] (last arg is early flag, enabled by default)"); + } + return; + } + if(isEqualNoCase(command, "answer") || isEqualNoCase(command, "an")) + { + unsigned long partHandle = arg[0].convertUnsignedLong(); + if(partHandle != 0) + { + myConversationManager.answerParticipant(partHandle); + } + else + { + InfoLog( << "Invalid command format: <'answer'|'an'> <partHandle>"); + } + return; + } + if(isEqualNoCase(command, "reject") || isEqualNoCase(command, "rj")) + { + unsigned long partHandle = arg[0].convertUnsignedLong(); + unsigned long status = arg[1].convertUnsignedLong(); + if(partHandle != 0) + { + if(status == 0) status = 486; + myConversationManager.rejectParticipant(partHandle, status); + } + else + { + InfoLog( << "Invalid command format: <'reject'|'rj'> <partHandle> [<statusCode>] (default status code is 486)"); + } + return; + } + if(isEqualNoCase(command, "redirect") || isEqualNoCase(command, "rd")) + { + unsigned long partHandle = arg[0].convertUnsignedLong(); + if(partHandle != 0 && !arg[1].empty()) + { + try + { + NameAddr dest(arg[1]); + myConversationManager.redirectParticipant(partHandle, dest); + } + catch(...) + { + NameAddr dest(uri); + dest.uri().user() = arg[1]; + myConversationManager.redirectParticipant(partHandle, dest); + } + } + else + { + InfoLog( << "Invalid command format: <'redirect'|'rd'> <partHandle> <destURI>"); + } + return; + } + if(isEqualNoCase(command, "redirectTo") || isEqualNoCase(command, "rt")) + { + unsigned long partHandle = arg[0].convertUnsignedLong(); + unsigned long destPartHandle = arg[1].convertUnsignedLong(); + if(partHandle != 0 && destPartHandle != 0) + { + myConversationManager.redirectToParticipant(partHandle, destPartHandle); + } + else + { + InfoLog( << "Invalid command format: <'redirectTo'|'rt'> <partHandle> <destPartHandle>"); + } + return; + } + if(isEqualNoCase(command, "volume") || isEqualNoCase(command, "sv")) + { + unsigned long volume = arg[0].convertUnsignedLong(); + myConversationManager.setSpeakerVolume(volume); + InfoLog( << "Speaker volume set to " << volume); + return; + } + if(isEqualNoCase(command, "gain") || isEqualNoCase(command, "sg")) + { + unsigned long gain = arg[0].convertUnsignedLong(); + myConversationManager.setMicrophoneGain(gain); + InfoLog( << "Microphone gain set to " << gain); + return; + } + if(isEqualNoCase(command, "mute") || isEqualNoCase(command, "mm")) + { + bool enable = arg[0].convertUnsignedLong() != 0; + myConversationManager.muteMicrophone(enable); + InfoLog( << "Microphone mute " << (enable ? "enabled" : "disabled")); + return; + } + if(isEqualNoCase(command, "echocanel") || isEqualNoCase(command, "aec")) + { + bool enable = arg[0].convertUnsignedLong() != 0; + myConversationManager.enableEchoCancel(enable); + InfoLog( << "Echo cancellation " << (enable ? "enabled" : "disabled")); + return; + } + if(isEqualNoCase(command, "autogain") || isEqualNoCase(command, "agc")) + { + bool enable = arg[0].convertUnsignedLong() != 0; + myConversationManager.enableAutoGainControl(enable); + InfoLog( << "Automatic gain control " << (enable ? "enabled" : "disabled")); + return; + } + if(isEqualNoCase(command, "noisereduction") || isEqualNoCase(command, "nr")) + { + bool enable = arg[0].convertUnsignedLong() != 0; + myConversationManager.enableNoiseReduction(enable); + return; + } + if(isEqualNoCase(command, "subscribe") || isEqualNoCase(command, "cs")) + { + unsigned int subTime = arg[2].convertUnsignedLong(); + if(!arg[0].empty() && !arg[1].empty() && subTime != 0 && !arg[3].empty() && !arg[4].empty()) + { + try + { + NameAddr dest(arg[1]); + Mime mime(arg[3], arg[4]); + myUserAgent.createSubscription(arg[0], dest, subTime, mime); + } + catch(...) + { + NameAddr dest(uri); + Mime mime(arg[3], arg[4]); + dest.uri().user() = arg[1]; + myUserAgent.createSubscription(arg[0], dest, subTime, mime); + } + } + else + { + InfoLog( << "Invalid command format: <'subscribe'|'cs'> <eventType> <targetUri> <subTime> <mimeType> <mimeSubType>"); + } + return; + } + if(isEqualNoCase(command, "destsub") || isEqualNoCase(command, "ds")) + { + unsigned int subHandle = arg[0].convertUnsignedLong(); + + if(subHandle > 0) + { + myUserAgent.destroySubscription(subHandle); + } + else + { + InfoLog( << "Invalid command format: <'destsub'|'ds'> <subHandle>"); + } + return; + } + if(isEqualNoCase(command, "autoans") || isEqualNoCase(command, "aa")) + { + bool enable = arg[0].convertUnsignedLong() != 0; + autoAnswerEnabled = enable; + InfoLog( << "Autoanswer " << (enable ? "enabled" : "disabled")); + return; + } + if(isEqualNoCase(command, "setcodecs") || isEqualNoCase(command, "sc")) + { + Data codecId; + std::list<unsigned int> idList; + ParseBuffer pb(arg[0]); + pb.skipWhitespace(); + while(!pb.eof()) + { + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace, ","); // white space or "," + pb.data(codecId, start); + idList.push_back(codecId.convertUnsignedLong()); + if(!pb.eof()) + { + pb.skipChar(','); + } + } + unsigned int numCodecIds = idList.size(); + if(numCodecIds > 0) + { + unsigned int* codecIdArray = new unsigned int[numCodecIds]; + unsigned int index = 0; + std::list<unsigned int>::iterator it = idList.begin(); + for(;it != idList.end(); it++) + { + codecIdArray[index++] = (*it); + } + Data ipAddress(conversationProfile->sessionCaps().session().connection().getAddress()); + // Note: Technically modifying the conversation profile at runtime like this is not + // thread safe. But it should be fine for this test consoles purposes. + myConversationManager.buildSessionCapabilities(ipAddress, numCodecIds, codecIdArray, conversationProfile->sessionCaps()); + delete [] codecIdArray; + } + return; + } + if(isEqualNoCase(command, "securemedia") || isEqualNoCase(command, "sm")) + { + ConversationProfile::SecureMediaMode secureMediaMode = ConversationProfile::NoSecureMedia; + bool secureMediaRequired = false; + if(isEqualNoCase(arg[0], "Srtp")) + { + secureMediaMode = ConversationProfile::Srtp; + } + else if(isEqualNoCase(arg[0], "SrtpReq")) + { + secureMediaMode = ConversationProfile::Srtp; + secureMediaRequired = true; + } +#ifdef USE_SSL + else if(isEqualNoCase(arg[0], "SrtpDtls")) + { + secureMediaMode = ConversationProfile::SrtpDtls; + } + else if(isEqualNoCase(arg[0], "SrtpDtlsReq")) + { + secureMediaMode = ConversationProfile::SrtpDtls; + secureMediaRequired = true; + } +#endif + else + { + arg[0] = "None"; // for display output only + } + // Note: Technically modifying the conversation profile at runtime like this is not + // thread safe. But it should be fine for this test consoles purposes. + conversationProfile->secureMediaMode() = secureMediaMode; + conversationProfile->secureMediaRequired() = secureMediaRequired; + InfoLog( << "Secure media mode set to: " << arg[0]); + return; + } + if(isEqualNoCase(command, "natmode") || isEqualNoCase(command, "nm")) + { + ConversationProfile::NatTraversalMode natTraversalMode = ConversationProfile::NoNatTraversal; + if(isEqualNoCase(arg[0], "Bind")) + { + natTraversalMode = ConversationProfile::StunBindDiscovery; + } + else if(isEqualNoCase(arg[0], "UdpAlloc")) + { + natTraversalMode = ConversationProfile::TurnUdpAllocation; + } + else if(isEqualNoCase(arg[0], "TcpAlloc")) + { + natTraversalMode = ConversationProfile::TurnTcpAllocation; + } +#ifdef USE_SSL + else if(isEqualNoCase(arg[0], "TlsAlloc")) + { + natTraversalMode = ConversationProfile::TurnTlsAllocation; + } +#endif + else + { + arg[0] = "None"; // for display output only + } + // Note: Technically modifying the conversation profile at runtime like this is not + // thread safe. But it should be fine for this test consoles purposes. + conversationProfile->natTraversalMode() = natTraversalMode; + InfoLog( << "NAT traversal mode set to: " << arg[0]); + return; + } + if(isEqualNoCase(command, "natserver") || isEqualNoCase(command, "ns")) + { + Data natTraversalServerHostname; + unsigned short natTraversalServerPort = 8777; + // Read server and port + ParseBuffer pb(arg[0]); + pb.skipWhitespace(); + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace, ":"); // white space or ":" + pb.data(natTraversalServerHostname, start); + if(!pb.eof()) + { + pb.skipChar(':'); + start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace); // white space + Data port; + pb.data(port, start); + natTraversalServerPort = port.convertUnsignedLong(); + } + // Note: Technically modifying the conversation profile at runtime like this is not + // thread safe. But it should be fine for this test consoles purposes. + conversationProfile->natTraversalServerHostname() = natTraversalServerHostname; + conversationProfile->natTraversalServerPort() = natTraversalServerPort; + InfoLog( << "NAT traversal STUN/TURN server set to: " << natTraversalServerHostname << ":" << natTraversalServerPort); + return; + } + if(isEqualNoCase(command, "natuser") || isEqualNoCase(command, "nu")) + { + // Note: Technically modifying the conversation profile at runtime like this is not + // thread safe. But it should be fine for this test consoles purposes. + conversationProfile->stunUsername() = arg[0]; + InfoLog( << "STUN/TURN user set to: " << arg[0]); + return; + } + if(isEqualNoCase(command, "natpwd") || isEqualNoCase(command, "np")) + { + // Note: Technically modifying the conversation profile at runtime like this is not + // thread safe. But it should be fine for this test consoles purposes. + conversationProfile->stunPassword() = arg[0]; + InfoLog( << "STUN/TURN password set to: " << arg[0]); + return; + } + if(isEqualNoCase(command, "starttimer") || isEqualNoCase(command, "st")) + { + unsigned int timerId = arg[0].convertUnsignedLong(); + unsigned int durationMs = arg[1].convertUnsignedLong(); + unsigned int seqNumber = arg[2].convertUnsignedLong(); + + if(durationMs > 0) + { + myUserAgent.startApplicationTimer(timerId, durationMs, seqNumber); + InfoLog( << "Application Timer started for " << durationMs << "ms"); + } + else + { + InfoLog( << "Invalid command format: <'starttimer'|'st'> <timerId> <durationMs> <seqNo>"); + } + return; + } + if(isEqualNoCase(command, "info") || isEqualNoCase(command, "i")) + { + myConversationManager.displayInfo(); + return; + } + if(isEqualNoCase(command, "dns") || isEqualNoCase(command, "ld")) + { + InfoLog( << "DNS cache (at WARNING log level):"); + myUserAgent.logDnsCache(); + return; + } + if(isEqualNoCase(command, "cleardns") || isEqualNoCase(command, "cd")) + { + myUserAgent.clearDnsCache(); + InfoLog( << "DNS cache has been cleared."); + return; + } + +#ifdef USE_SSL + Data setSecureMediaMode(" setSecureMediaMode <'securemedia'|'sm'> <'None'|'Srtp'|'SrtpReq'|'SrtpDtls'|'SrtpDtlsReq'>"); + Data setNATTraversalMode(" setNATTraversalMode <'natmode'|'nm'> <'None'|'Bind'|'UdpAlloc'|'TcpAlloc'|'TlsAlloc'>" ); +#else + Data setSecureMediaMode(" setSecureMediaMode <'securemedia'|'sm'> <'None'|'Srtp'|'SrtpReq'>"); + Data setNATTraversalMode(" setNATTraversalMode <'natmode'|'nm'> <'None'|'Bind'|'UdpAlloc'|'TcpAlloc'>" ); +#endif + + InfoLog( << "Possible commands are: " << endl + << " createConversation: <'createconv'|'cc'>" << endl + << " destroyConversation: <'destroyconv'|'dc'> <convHandle>" << endl + << " joinConversation: <'joinconv'|'jc'> <sourceConvHandle> <destConvHandle>" << endl + << endl + << " createLocalParticipant: <'createlocal'|'clp'>" << endl + << " createRemoteParticipant: <'createremote'|'crp'> <convHandle> <destURI> [<'manual'>] (last arg is fork select mode, 'auto' is default)" << endl + << " createMediaResourceParticipant: <'createmedia'|'cmp'> <convHandle> <mediaURL> [<durationMs>]" << endl + << " destroyParticipant: <'destroypart'|'dp'> <parthandle>" << endl + << endl + << " addPartcipant: <'addpart'|'ap'> <convHandle> <partHandle>" << endl + << " removePartcipant: <'removepart'|'rp'> <convHandle> <partHandle>" << endl + << " moveParticipant: <'movepart'|'mp'> <partHandle> <srcConvHandle> <dstConvHandle>" << endl + << " modifyParticipantContribution: <'partcontrib'|'pc'> <convHandle> <partHandle> <inputGain> <outputGain> (gain in percentage)" << endl + << " outputBridgeMatrix: <'bridgematrix'|'bm'>" << endl + << " alertPartcipant: <'alert'|'al'> <partHandle> [<'noearly'>] (last arg is early flag, enabled by default)" << endl + << " answerParticipant: <'answer'|'an'> <partHandle>" << endl + << " rejectParticipant: <'reject'|'rj'> <partHandle> [<statusCode>] (default status code is 486)" << endl + << " redirectPartcipant: <'redirect'|'rd'> <partHandle> <destURI>" << endl + << " redirectToPartcipant: <'redirectTo'|'rt'> <partHandle> <destPartHandle>" << endl + << endl + << " setSpeakerVolume: <'volume'|'sv'> <volume>" << endl + << " setMicrophoneGain: <'gain'|'sg'> <gain>" << endl + << " muteMicrophone: <'mute'|'mm'> <'0'|'1'> (1 to enable/mute)" << endl + << " enableEchoCancel: <'echocancel'|'aec'> <'0'|'1'> (1 to enable)" << endl + << " enableAutoGainControl: <'autogain'|'agc'> <'0'|'1'> (1 to enable)" << endl + << " enableNoiseReduction: <'noisereduction'|'nr'> <'0'|'1'> (1 to enable)" << endl + << endl + << " createSubscription: <'subscribe'|'cs'> <eventType> <targetUri> <subTime> <mimeType> <mimeSubType>" << endl + << " destroySubscription: <'destsub'|'ds'> <subHandle>" << endl + << endl + << " setAutoAnswer <'autoans'|'aa'> <'0'|'1'> (1 to enable (default))" << endl + << " setCodecs <'setcodecs'|'sc'> <codecId>[,<codecId>]+ (comma separated list)" << endl + << setSecureMediaMode << endl + << setNATTraversalMode << endl + << " setNATTraversalServer <'natserver'|'ns'> <server:port>" << endl + << " setNATUsername <'natuser'|'nu'> <username>" << endl + << " setNATPassword <'natpwd'|'np'> <password>" << endl + << " startApplicationTimer: <'starttimer'|'st'> <timerId> <durationMs> <seqNo>" << endl + << " displayInfo: <'info'|'i'>" << endl + << " logDnsCache: <'dns'|'ld'>" << endl + << " clearDnsCache: <'cleardns'|'cd'>" << endl + << " exitProgram: <'exit'|'quit'|'q'>"); +} + +#define KBD_BUFFER_SIZE 256 +void processKeyboard(char input, MyConversationManager& myConversationManager, MyUserAgent& myUserAgent) +{ + static char buffer[KBD_BUFFER_SIZE]; + static int bufferpos = 0; + + if(input == 13 || input == 10) // enter + { + Data db(buffer,bufferpos); +#ifdef WIN32 + cout << endl; +#endif + processCommandLine(db, myConversationManager, myUserAgent); + bufferpos = 0; + } + else if(input == 8 || input == 127) // backspace + { + if(bufferpos > 0) + { +#ifdef WIN32 + cout << input << ' ' << input; +#else + // note: This is bit of a hack and may not be portable to all linux terminal types + cout << "\b\b\b \b\b\b"; + fflush(stdout); +#endif + bufferpos--; + } + } + else + { + if(bufferpos == KBD_BUFFER_SIZE) + { + cout << endl; + bufferpos = 0; + } + else + { +#ifdef WIN32 + cout << input; +#endif + buffer[bufferpos++] = (char)input; + } + } +} + +int +main (int argc, char** argv) +{ +#ifndef _WIN32 + if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR) + { + cerr << "Couldn't install signal handler for SIGPIPE" << endl; + exit(-1); + } +#endif + +#if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK) + resip::FindMemoryLeaks fml; + { +#endif + + if ( signal( SIGINT, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGINT" << endl; + exit( -1 ); + } + + if ( signal( SIGTERM, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGTERM" << endl; + exit( -1 ); + } + + // Defaults + bool registrationDisabled = false; + bool keepAlivesDisabled = false; + Data password; + Data dnsServers; + Data address = DnsUtil::getLocalIpAddress(); + ConversationProfile::SecureMediaMode secureMediaMode = ConversationProfile::NoSecureMedia; + bool secureMediaRequired = false; + ConversationProfile::NatTraversalMode natTraversalMode = ConversationProfile::NoNatTraversal; + Data natTraversalServerHostname; + unsigned short natTraversalServerPort = 8777; + Data stunUsername; + Data stunPassword; + bool localAudioEnabled = true; + unsigned short sipPort = 5062; + unsigned short tlsPort = 5063; + unsigned short mediaPortStart = 17384; + Data tlsDomain = DnsUtil::getLocalHostName(); + NameAddr outboundProxy; + Data logLevel("INFO"); + unsigned int codecIds[] = { SdpCodec::SDP_CODEC_PCMU /* 0 - pcmu */, + SdpCodec::SDP_CODEC_PCMA /* 8 - pcma */, + SdpCodec::SDP_CODEC_SPEEX /* 96 - speex NB 8,000bps */, + SdpCodec::SDP_CODEC_SPEEX_15 /* 98 - speex NB 15,000bps */, + SdpCodec::SDP_CODEC_SPEEX_24 /* 99 - speex NB 24,600bps */, + SdpCodec::SDP_CODEC_L16_44100_MONO /* PCM 16 bit/sample 44100 samples/sec. */, + SdpCodec::SDP_CODEC_ILBC /* 108 - iLBC */, + SdpCodec::SDP_CODEC_ILBC_20MS /* 109 - Internet Low Bit Rate Codec, 20ms (RFC3951) */, + SdpCodec::SDP_CODEC_SPEEX_5 /* 97 - speex NB 5,950bps */, + SdpCodec::SDP_CODEC_GSM /* 3 - GSM */, + SdpCodec::SDP_CODEC_TONES /* 110 - telephone-event */}; + unsigned int numCodecIds = sizeof(codecIds) / sizeof(codecIds[0]); + + // Loop through command line arguments and process them + for(int i = 1; i < argc; i++) + { + Data commandName(argv[i]); + + // Process all commandNames that don't take values + if(isEqualNoCase(commandName, "-?") || + isEqualNoCase(commandName, "--?") || + isEqualNoCase(commandName, "--help") || + isEqualNoCase(commandName, "/?")) + { + cout << "Command line options are:" << endl; + cout << " -aa - enable autoanswer" << endl; + cout << " -a <IP Address> - bind SIP transports to this IP address" << endl; + cout << " -u <SIP URI> - URI of this SIP user" << endl; + cout << " -p <password> - SIP password of this this SIP user" << endl; + cout << " -nr - no registration, set this to disable registration with SIP Proxy" << endl; + cout << " -d <DNS servers> - comma seperated list of DNS servers, overrides OS detected list" << endl; + cout << " -sp <port num> - local port number to use for SIP messaging (UDP/TCP)" << endl; + cout << " -mp <port num> - local port number to start allocating from for RTP media" << endl; +#ifdef USE_SSL + cout << " -tp <port num> - local port number to use for TLS SIP messaging" << endl; + cout << " -td <domain name> - domain name to use for TLS server connections" << endl; +#endif + cout << " -nk - no keepalives, set this to disable sending of keepalives" << endl; + cout << " -op <SIP URI> - URI of a proxy server to use a SIP outbound proxy" << endl; +#ifdef USE_SSL + cout << " -sm <Srtp|SrtpReq|SrtpDtls|SrtpDtlsReq> - sets the secure media mode" << endl; + cout << " -nm <Bind|UdpAlloc|TcpAlloc|TlsAlloc> - sets the NAT traversal mode" << endl; +#else + cout << " -sm <Srtp|SrtpReq> - sets the secure media mode" << endl; + cout << " -nm <Bind|UdpAlloc|TcpAlloc> - sets the NAT traversal mode" << endl; +#endif + cout << " -ns <server:port> - set the hostname and port of the NAT STUN/TURN server" << endl; + cout << " -nu <username> - sets the STUN/TURN username to use for NAT server" << endl; + cout << " -np <password> - sets the STUN/TURN password to use for NAT server" << endl; + cout << " -nl - no local audio support - removed local sound hardware requirement" << endl; + cout << " -l <NONE|CRIT|ERR|WARNING|INFO|DEBUG|STACK> - logging level" << endl; + cout << endl; + cout << "Sample Command line:" << endl; + cout << "testUA -a 192.168.1.100 -u sip:1000@myproxy.com -p 123 -aa" << endl; + return 0; + } + else if(isEqualNoCase(commandName, "-nr")) + { + registrationDisabled = true; + } + else if(isEqualNoCase(commandName, "-aa")) + { + autoAnswerEnabled = true; + } + else if(isEqualNoCase(commandName, "-nk")) + { + keepAlivesDisabled = true; + } + else if(isEqualNoCase(commandName, "-nl")) + { + localAudioEnabled = false; + } + else + { + // Process commands that have values + Data commandValue(i+1 < argc ? argv[i+1] : Data::Empty); + if(commandValue.empty() || commandValue.at(0) == '-') + { + cerr << "Invalid command line parameters!" << endl; + exit(-1); + } + i++; // increment argument + + if(isEqualNoCase(commandName, "-a")) + { + address = commandValue; + } + else if(isEqualNoCase(commandName, "-u")) + { + try + { + NameAddr tempuri(commandValue); + uri = tempuri; + } + catch(resip::BaseException& e) + { + cerr << "Invalid uri format: " << e << endl; + exit(-1); + } + } + else if(isEqualNoCase(commandName, "-p")) + { + password = commandValue; + } + else if(isEqualNoCase(commandName, "-d")) + { + dnsServers = commandValue; + } + else if(isEqualNoCase(commandName, "-sm")) + { + if(isEqualNoCase(commandValue, "Srtp")) + { + secureMediaMode = ConversationProfile::Srtp; + } + else if(isEqualNoCase(commandValue, "SrtpReq")) + { + secureMediaMode = ConversationProfile::Srtp; + secureMediaRequired = true; + } +#ifdef USE_SSL + else if(isEqualNoCase(commandValue, "SrtpDtls")) + { + secureMediaMode = ConversationProfile::SrtpDtls; + } + else if(isEqualNoCase(commandValue, "SrtpDtlsReq")) + { + secureMediaMode = ConversationProfile::SrtpDtls; + secureMediaRequired = true; + } +#endif + else + { + cerr << "Invalid Secure Media Mode: " << commandValue << endl; + exit(-1); + } + } + else if(isEqualNoCase(commandName, "-nm")) + { + if(isEqualNoCase(commandValue, "Bind")) + { + natTraversalMode = ConversationProfile::StunBindDiscovery; + } + else if(isEqualNoCase(commandValue, "UdpAlloc")) + { + natTraversalMode = ConversationProfile::TurnUdpAllocation; + } + else if(isEqualNoCase(commandValue, "TcpAlloc")) + { + natTraversalMode = ConversationProfile::TurnTcpAllocation; + } +#ifdef USE_SSL + else if(isEqualNoCase(commandValue, "TlsAlloc")) + { + natTraversalMode = ConversationProfile::TurnTlsAllocation; + } +#endif + else + { + cerr << "Invalid NAT Traversal Mode: " << commandValue << endl; + exit(-1); + } + } + else if(isEqualNoCase(commandName, "-ns")) + { + // Read server and port + Data natServerAndPort = commandValue; + ParseBuffer pb(natServerAndPort); + pb.skipWhitespace(); + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace, ":"); // white space or ":" + Data hostname; + pb.data(hostname, start); + natTraversalServerHostname = hostname; + if(!pb.eof()) + { + pb.skipChar(':'); + start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace); // white space + Data port; + pb.data(port, start); + natTraversalServerPort = port.convertUnsignedLong(); + } + } + else if(isEqualNoCase(commandName, "-nu")) + { + stunUsername = commandValue; + } + else if(isEqualNoCase(commandName, "-np")) + { + stunPassword = commandValue; + } + else if(isEqualNoCase(commandName, "-sp")) + { + sipPort = (unsigned short)commandValue.convertUnsignedLong(); + } + else if(isEqualNoCase(commandName, "-mp")) + { + mediaPortStart = (unsigned short)commandValue.convertUnsignedLong(); + } + else if(isEqualNoCase(commandName, "-tp")) + { + tlsPort = (unsigned short)commandValue.convertUnsignedLong(); + } + else if(isEqualNoCase(commandName, "-td")) + { + tlsDomain = commandValue; + } + else if(isEqualNoCase(commandName, "-op")) + { + try + { + NameAddr tempuri(commandValue); + outboundProxy = tempuri; + } + catch(resip::BaseException& e) + { + cerr << "Invalid outbound proxy uri format: " << e << endl; + exit(-1); + } + } + else if(isEqualNoCase(commandName, "-l")) + { + logLevel = commandValue; + } + else + { + cerr << "Invalid command line parameters!" << endl; + exit(-1); + } + } + } + + //enableConsoleOutput(TRUE); // Allow sipX console output + OsSysLog::initialize(0, "testUA"); + OsSysLog::setOutputFile(0, "sipXtapilog.txt") ; + Log::initialize("Cout", logLevel, "testUA"); + //UserAgent::setLogLevel(Log::Warning, UserAgent::SubsystemAll); + //UserAgent::setLogLevel(Log::Info, UserAgent::SubsystemRecon); + + initNetwork(); + + InfoLog( << "testUA settings:"); + InfoLog( << " No Keepalives = " << (keepAlivesDisabled ? "true" : "false")); + InfoLog( << " Autoanswer = " << (autoAnswerEnabled ? "true" : "false")); + InfoLog( << " Do not register = " << (registrationDisabled ? "true" : "false")); + InfoLog( << " Local IP Address = " << address); + InfoLog( << " SIP URI = " << uri); + InfoLog( << " SIP Password = " << password); + InfoLog( << " Override DNS Servers = " << dnsServers); + InfoLog( << " Secure Media Mode = " << secureMediaMode); + InfoLog( << " NAT Traversal Mode = " << natTraversalMode); + InfoLog( << " NAT Server = " << natTraversalServerHostname << ":" << natTraversalServerPort); + InfoLog( << " STUN/TURN user = " << stunUsername); + InfoLog( << " STUN/TURN password = " << stunPassword); + InfoLog( << " SIP Port = " << sipPort); + InfoLog( << " Media Port Range Start = " << mediaPortStart); +#ifdef USE_SSL + InfoLog( << " TLS Port = " << tlsPort); + InfoLog( << " TLS Domain = " << tlsDomain); +#endif + InfoLog( << " Outbound Proxy = " << outboundProxy); + InfoLog( << " Local Audio Enabled = " << (localAudioEnabled ? "true" : "false")); + InfoLog( << " Log Level = " << logLevel); + + InfoLog( << "type help or '?' for list of accepted commands." << endl); + + ////////////////////////////////////////////////////////////////////////////// + // Setup UserAgentMasterProfile + ////////////////////////////////////////////////////////////////////////////// + + SharedPtr<UserAgentMasterProfile> profile(new UserAgentMasterProfile); + + // Add transports + profile->addTransport(UDP, sipPort, V4, address); + profile->addTransport(TCP, sipPort, V4, address); +#ifdef USE_SSL + profile->addTransport(TLS, tlsPort, V4, address, tlsDomain); +#endif + + // The following settings are used to avoid a kernel panic seen on an ARM embedded platform. + // The kernel panic happens when either binding a udp socket to port 0 (OS selected), + // or calling connect without first binding to a specific port. There is code in the + // resip transport selector that uses a utility UDP socket in order to determine + // which interface should be used to route to a particular destination. This code calls + // connect with no bind. By setting a fixed transport interface here that + // code will not be used. + // The following line can be safely removed for other platforms + //profile->setFixedTransportInterface(address); + + // Settings + profile->setDefaultRegistrationTime(3600); + profile->setDefaultFrom(uri); + profile->setDigestCredential(uri.uri().host(), uri.uri().user(), password); + + // DNS Servers + ParseBuffer pb(dnsServers); + Data dnsServer; + while(!dnsServers.empty() && !pb.eof()) + { + pb.skipWhitespace(); + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace, ";,"); // allow white space + pb.data(dnsServer, start); + if(DnsUtil::isIpV4Address(dnsServer)) + { + InfoLog( << "Adding DNS Server: " << dnsServer); + profile->addAdditionalDnsServer(dnsServer); + } + else + { + ErrLog( << "Tried to add dns server, but invalid format: " << dnsServer); + } + if(!pb.eof()) + { + pb.skipChar(); + } + } + + // Disable Statisitics Manager + profile->statisticsManagerEnabled() = false; + + // Add ENUM Suffixes from setting string - use code similar to dns server + //profile->addEnumSuffix(enumSuffix); + + if(!keepAlivesDisabled) + { + profile->setKeepAliveTimeForDatagram(30); + profile->setKeepAliveTimeForStream(180); + } + + // Support Methods, etc. + profile->validateContentEnabled() = false; + profile->validateContentLanguageEnabled() = false; + profile->validateAcceptEnabled() = false; + + profile->clearSupportedLanguages(); + profile->addSupportedLanguage(Token("en")); + + profile->clearSupportedMimeTypes(); + profile->addSupportedMimeType(INVITE, Mime("application", "sdp")); + profile->addSupportedMimeType(INVITE, Mime("multipart", "mixed")); + profile->addSupportedMimeType(INVITE, Mime("multipart", "signed")); + profile->addSupportedMimeType(INVITE, Mime("multipart", "alternative")); + profile->addSupportedMimeType(OPTIONS,Mime("application", "sdp")); + profile->addSupportedMimeType(OPTIONS,Mime("multipart", "mixed")); + profile->addSupportedMimeType(OPTIONS, Mime("multipart", "signed")); + profile->addSupportedMimeType(OPTIONS, Mime("multipart", "alternative")); + profile->addSupportedMimeType(PRACK, Mime("application", "sdp")); + profile->addSupportedMimeType(PRACK, Mime("multipart", "mixed")); + profile->addSupportedMimeType(PRACK, Mime("multipart", "signed")); + profile->addSupportedMimeType(PRACK, Mime("multipart", "alternative")); + profile->addSupportedMimeType(UPDATE, Mime("application", "sdp")); + profile->addSupportedMimeType(UPDATE, Mime("multipart", "mixed")); + profile->addSupportedMimeType(UPDATE, Mime("multipart", "signed")); + profile->addSupportedMimeType(UPDATE, Mime("multipart", "alternative")); + profile->addSupportedMimeType(NOTIFY, Mime("message", "sipfrag")); + + profile->clearSupportedMethods(); + profile->addSupportedMethod(INVITE); + profile->addSupportedMethod(ACK); + profile->addSupportedMethod(CANCEL); + profile->addSupportedMethod(OPTIONS); + profile->addSupportedMethod(BYE); + profile->addSupportedMethod(REFER); + profile->addSupportedMethod(NOTIFY); + profile->addSupportedMethod(SUBSCRIBE); + profile->addSupportedMethod(UPDATE); + profile->addSupportedMethod(PRACK); + //profile->addSupportedMethod(INFO); + //profile->addSupportedMethod(MESSAGE); + + profile->clearSupportedOptionTags(); + profile->addSupportedOptionTag(Token(Symbols::Replaces)); + profile->addSupportedOptionTag(Token(Symbols::Timer)); + profile->addSupportedOptionTag(Token(Symbols::NoReferSub)); + profile->addSupportedOptionTag(Token(Symbols::AnswerMode)); + profile->addSupportedOptionTag(Token(Symbols::TargetDialog)); + //profile->addSupportedOptionTag(Token(Symbols::C100rel)); // Automatically added by calling setUacReliableProvisionalMode + + profile->setUacReliableProvisionalMode(MasterProfile::Supported); + + profile->clearSupportedSchemes(); + profile->addSupportedScheme("sip"); +#ifdef USE_SSL + profile->addSupportedScheme("sips"); +#endif + + // Have stack add Allow/Supported/Accept headers to INVITE dialog establishment messages + profile->clearAdvertisedCapabilities(); // Remove Profile Defaults, then add our preferences + profile->addAdvertisedCapability(Headers::Allow); + //profile->addAdvertisedCapability(Headers::AcceptEncoding); // This can be misleading - it might specify what is expected in response + profile->addAdvertisedCapability(Headers::AcceptLanguage); + profile->addAdvertisedCapability(Headers::Supported); + profile->setMethodsParamEnabled(true); + + //profile->setOverrideHostAndPort(mContact); + if(!outboundProxy.uri().host().empty()) + { + profile->setOutboundProxy(outboundProxy.uri()); + } + + profile->setUserAgent("ConversationManager/TestUA"); + profile->rtpPortRangeMin() = mediaPortStart; + profile->rtpPortRangeMax() = mediaPortStart + 101; // Allows 100 media streams + + ////////////////////////////////////////////////////////////////////////////// + // Setup ConversationProfile + ////////////////////////////////////////////////////////////////////////////// + + conversationProfile = SharedPtr<ConversationProfile>(new ConversationProfile(profile)); + if(uri.uri().user() != "noreg" && !registrationDisabled) + { + conversationProfile->setDefaultRegistrationTime(3600); + } + else + { + conversationProfile->setDefaultRegistrationTime(0); + } + conversationProfile->setDefaultRegistrationRetryTime(120); // 2 mins + conversationProfile->setDefaultFrom(uri); + conversationProfile->setDigestCredential(uri.uri().host(), uri.uri().user(), password); + +#if 0 // Now auto-built + + // Create Session Capabilities and assign to coversation Profile + // Note: port, sessionId and version will be replaced in actual offer/answer int port = 16384; + // Build s=, o=, t=, and c= lines + SdpContents::Session::Origin origin("-", 0 /* sessionId */, 0 /* version */, SdpContents::IP4, address); // o= + SdpContents::Session session(0, origin, "-" /* s= */); + session.connection() = SdpContents::Session::Connection(SdpContents::IP4, address); // c= + session.addTime(SdpContents::Session::Time(0, 0)); + + // Build Codecs and media offering + SdpContents::Session::Medium medium("audio", port, 1, "RTP/AVP"); + SdpContents::Session::Codec g711ucodec("PCMU", 8000); + g711ucodec.payloadType() = 0; /* RFC3551 */ ; + medium.addCodec(g711ucodec); + SdpContents::Session::Codec g711acodec("PCMA", 8000); + g711acodec.payloadType() = 8; /* RFC3551 */ ; + medium.addCodec(g711acodec); + SdpContents::Session::Codec speexCodec("SPEEX", 8000); + speexCodec.payloadType() = 110; + speexCodec.parameters() = Data("mode=3"); + medium.addCodec(speexCodec); + SdpContents::Session::Codec gsmCodec("GSM", 8000); + gsmCodec.payloadType() = 3; /* RFC3551 */ ; + medium.addCodec(gsmCodec); + medium.addAttribute("ptime", Data(20)); // 20 ms of speech per frame (note G711 has 10ms samples, so this is 2 samples per frame) + medium.addAttribute("sendrecv"); + + SdpContents::Session::Codec toneCodec("telephone-event", 8000); + toneCodec.payloadType() = 102; + toneCodec.parameters() = Data("0-15"); + medium.addCodec(toneCodec); + session.addMedium(medium); + + conversationProfile->sessionCaps().session() = session; +#endif + + // Setup NatTraversal Settings + conversationProfile->natTraversalMode() = natTraversalMode; + conversationProfile->natTraversalServerHostname() = natTraversalServerHostname; + conversationProfile->natTraversalServerPort() = natTraversalServerPort; + conversationProfile->stunUsername() = stunUsername; + conversationProfile->stunPassword() = stunPassword; + + // Secure Media Settings + conversationProfile->secureMediaMode() = secureMediaMode; + conversationProfile->secureMediaRequired() = secureMediaRequired; + conversationProfile->secureMediaDefaultCryptoSuite() = ConversationProfile::SRTP_AES_CM_128_HMAC_SHA1_80; + + ////////////////////////////////////////////////////////////////////////////// + // Create ConverationManager and UserAgent + ////////////////////////////////////////////////////////////////////////////// + { + MyConversationManager myConversationManager(localAudioEnabled); + MyUserAgent ua(&myConversationManager, profile); + myConversationManager.buildSessionCapabilities(address, numCodecIds, codecIds, conversationProfile->sessionCaps()); + ua.addConversationProfile(conversationProfile); + + ////////////////////////////////////////////////////////////////////////////// + // Startup and run... + ////////////////////////////////////////////////////////////////////////////// + + ua.startup(); + myConversationManager.startup(); + + //ua.createSubscription("message-summary", uri, 120, Mime("application", "simple-message-summary")); // thread safe + + int input; + while(true) + { + ua.process(50); + while(_kbhit() != 0) + { +#ifdef WIN32 + input = _getch(); + processKeyboard(input, myConversationManager, ua); +#else + input = fgetc(stdin); + fflush(stdin); + //cout << "input: " << input << endl; + processKeyboard(input, myConversationManager, ua); +#endif + } + if(finished) break; + } + + ua.shutdown(); + } + InfoLog(<< "testUA is shutdown."); + OsSysLog::shutdown(); + sleepSeconds(2); + +#if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK) +} // end FML scope +#endif +} + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/test/testUA_10_0.vcxproj b/src/libs/resiprocate/resip/recon/test/testUA_10_0.vcxproj new file mode 100644 index 00000000..94abfb32 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/testUA_10_0.vcxproj @@ -0,0 +1,207 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>testUA</ProjectName> + <ProjectGuid>{16CD976A-5D3B-4329-88BA-A32560CDFCC8}</ProjectGuid> + <RootNamespace>testUA</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)/../../contrib\pcre;$(IncludePath)</IncludePath> + <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)/../../contrib\pcre;$(IncludePath)</IncludePath> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <BuildLog> + <Path>$(IntDir)BuildLog-testUA.htm</Path> + </BuildLog> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../;$(ProjectDir)/../../../;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include;$(ProjectDir)/../../../reTurn;$(ProjectDir)/../../../contrib/asio;$(ProjectDir)/../../../contrib/boost_1_34_1;$(ProjectDir)/../../../contrib/openssl/include;$(ProjectDir)/../../../contrib/srtp/include;$(ProjectDir)/../../../contrib/srtp/crypto/include;$(ProjectDir)/../../../reflow;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <ProgramDataBaseFileName>$(IntDir)testUA.pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalOptions>/FIXED:NO %(AdditionalOptions)</AdditionalOptions> + <AdditionalDependencies>Ws2_32.lib;Dnsapi.lib;iphlpapi.lib;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib;$(ProjectDir)..\..\..\contrib\pcre\Debug\pcre.lib;$(ProjectDir)..\..\..\contrib\srtp\Debug\libSRTP.lib;winmm.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Debug\sipxportlib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Debug\sipxsdplib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Debug\sipxmedialib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Debug\sipxmediaadapterlib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)testUA.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)testUA.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <BuildLog> + <Path>$(IntDir)BuildLog-testUA.htm</Path> + </BuildLog> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <OmitFramePointers>true</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)/../;$(ProjectDir)/../../../;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include;$(ProjectDir)/../../../reTurn;$(ProjectDir)/../../../contrib/asio;$(ProjectDir)/../../../contrib/boost_1_34_1;$(ProjectDir)/../../../contrib/openssl/inc32;$(ProjectDir)/../../../contrib/srtp/include;$(ProjectDir)/../../../contrib/srtp/crypto/include;$(ProjectDir)/../../../reflow;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <ProgramDataBaseFileName>$(IntDir)testUA.pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalOptions>/FIXED:NO %(AdditionalOptions)</AdditionalOptions> + <AdditionalDependencies>Ws2_32.lib;Dnsapi.lib;iphlpapi.lib;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib;$(ProjectDir)..\..\..\contrib\pcre\Release\pcre.lib;$(ProjectDir)..\..\..\contrib\srtp\Release\libSRTP.lib;winmm.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Release\sipxportlib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Release\sipxsdplib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Release\sipxmedialib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Release\sipxmediaadapterlib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)testUA.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)testUA.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="testUA.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="playback_prompt.hxx" /> + <ClInclude Include="record_prompt.hxx" /> + </ItemGroup> + <ItemGroup> + <None Include="testua_readme.txt" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\win32\VS2003\libspeexdsp\libspeexdsp.vcxproj"> + <Project>{03207781-0d1c-4db3-a71d-45c608f28dbd}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\win32\VS2003\libspeex\libspeex.vcxproj"> + <Project>{e972c52f-9e85-4d65-b19c-031e511e9db4}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgilbc\plgilbc-msvc8.vcxproj"> + <Project>{6442c7de-e500-4ba2-b821-98092f1edcaf}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgl16\plgl16-msvc8.vcxproj"> + <Project>{82a7c86a-5f71-47c3-a74d-54c48c6cd5ee}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgpcmapcmu\plgpcmapcmu-msvc8.vcxproj"> + <Project>{a9c94d26-c90d-4860-8195-56929e893757}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgspeex\plgspeex-msvc8.vcxproj"> + <Project>{4f7fda11-42a4-4556-a631-15aa785cd1c1}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgtones\plgtones-msvc8.vcxproj"> + <Project>{f3bca14e-f24d-4570-833e-8c20c4c393f7}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\contrib\pcre\pcre_10_0.vcxproj"> + <Project>{b933f895-8efb-4fdd-a46d-09b8c00d1d26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\contrib\srtp\srtp10.vcxproj"> + <Project>{eef031cb-fed8-451e-a471-91ec8d4f6750}</Project> + <Private>true</Private> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies> + <LinkLibraryDependencies>true</LinkLibraryDependencies> + <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs> + </ProjectReference> + <ProjectReference Include="..\..\..\reflow\reflow_10_0.vcxproj"> + <Project>{d2ab531b-86ac-43dd-a330-9809b4f1bb53}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\reTurn\client\reTurnClient_10_0.vcxproj"> + <Project>{67b5906c-5c9d-4d09-ac7e-af71d72175f8}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\rutil\rutil_10_0.vcxproj"> + <Project>{3d0e5ceb-93dc-4fdb-918b-d08fa369e106}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\dum\dum_10_0.vcxproj"> + <Project>{31b0654f-e08e-405f-909f-80f86cb14b9d}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\stack\resiprocate_10_0.vcxproj"> + <Project>{2a8be839-6466-4001-b224-8f1c3168d04a}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\recon_10_0.vcxproj"> + <Project>{16cd976a-5d3b-4329-88ba-a32560cdfcc7}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/recon/test/testUA_10_0.vcxproj.filters b/src/libs/resiprocate/resip/recon/test/testUA_10_0.vcxproj.filters new file mode 100644 index 00000000..fae16d1e --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/testUA_10_0.vcxproj.filters @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{c8e86bbb-b736-45e4-956f-b70785595cca}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{a0541208-c98e-42cc-a8d0-5e39b0717417}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{bc83dc52-6802-41fe-ade2-9f97deb9151b}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="testUA.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="playback_prompt.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="record_prompt.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="testua_readme.txt" /> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/recon/test/testUA_8_0.vcproj b/src/libs/resiprocate/resip/recon/test/testUA_8_0.vcproj new file mode 100644 index 00000000..6a0de99a --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/testUA_8_0.vcproj @@ -0,0 +1,233 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="testUA" + ProjectGUID="{16CD976A-5D3B-4329-88BA-A32560CDFCC8}" + RootNamespace="testUA" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-testUA.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)/testUA.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\pcre\Debug\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Debug\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Debug\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Debug\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Debug\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Debug\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/testUA.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/testUA.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-testUA.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)\testUA.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\pcre\Release\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Release\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Release\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Release\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Release\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Release\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/testUA.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/testUA.pdb" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath=".\testUA.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + <File + RelativePath=".\playback_prompt.hxx" + > + </File> + <File + RelativePath=".\record_prompt.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + > + </Filter> + <File + RelativePath=".\testua_readme.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/recon/test/testUA_9_0.vcproj b/src/libs/resiprocate/resip/recon/test/testUA_9_0.vcproj new file mode 100644 index 00000000..155cd5da --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/testUA_9_0.vcproj @@ -0,0 +1,407 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="testUA" + ProjectGUID="{16CD976A-5D3B-4329-88BA-A32560CDFCC8}" + RootNamespace="testUA" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-testUA.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)/testUA.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\pcre\Debug\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Debug\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Debug\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Debug\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Debug\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Debug\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/testUA.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/testUA.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-testUA.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)\testUA.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\pcre\Release\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Release\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Release\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Release\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Release\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Release\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/testUA.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/testUA.pdb" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-testUA.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)/testUA.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\pcre\Debug\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Debug\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Debug\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Debug\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Debug\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Debug\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/testUA.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/testUA.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-testUA.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)\testUA.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\pcre\Release\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Release\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Release\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Release\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Release\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Release\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/testUA.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/testUA.pdb" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath=".\testUA.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + <File + RelativePath=".\playback_prompt.hxx" + > + </File> + <File + RelativePath=".\record_prompt.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + > + </Filter> + <File + RelativePath=".\testua_readme.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/recon/test/testua_readme.txt b/src/libs/resiprocate/resip/recon/test/testua_readme.txt new file mode 100644 index 00000000..b9e22e97 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/testua_readme.txt @@ -0,0 +1,325 @@ +User Agent Tester (testUA) Instructions +======================================= + +Author: Scott Godin (s g o d i n a t s i p s p e c t r u m d o t c o m) + +TestUA is a test console for the recon (Conversation Manager) API. + + +Backgound Information on Conversation Manager +--------------------------------------------- + +The Conversation Manager is a VoIP API that allows conversations and participants +to be created. Participants can then be placed into conversations. In general +all participants belonging to the same conversation can be heard and hear each +other. A participants contribution level to a particular conversation can be +modified such that they appear quiter or louder to other participants. + +There are three types of participants: +1. Local participant - this participant type consists of the default local speaker and + microphone of the computer that is running the testUA console. Local + participants are always only explicitly destroyed. +2. Media participant - this participant type consists of an audio file, audio stream, + or tone played out. Media participants are destroyed when the file or tone output is + complete. +3. Remote Participant - this participant type uses audio from an external source. The + current implementation uses SIP to create/connect to remote participants. Remote + participants are destroyed by the API user, or a "hangup" signal from the + remote party. + +A typical phone conversation consists of 3 components: 1 conversation, 1 local participant +and 1 remote participant. + + + +Startup Command Line Parameters +------------------------------- +Command line options are: + -?, --?, --help, /? - display command line options + + -aa - enable autoanswer + + Enabling autoanswer will cause testUA to automatically answer any inbound SIP calls + and place them in the lowest numbered conversation currently created. + + -a <IP Address> - bind SIP transports to this IP address + + In general the IP address to bind to is queried from the host OS. This switch allows + specification of the IP address for OS's that cannot be queried, or for machines that + have mulitple NICs. + + -u <SIP URI> - URI of this SIP user + + This option is used to specify the SIP URI for this instance of testUA. testUA uses + this setting (-ip is not specified) in order to find the regisration server. If + nothing is specified, then the default of sip:noreg@<ipaddress> will be used. + + -p <password> - SIP password of this this SIP user + + Use this switch in cases where the proxy digest challenges sip messaging. + + -nr - no registration, set this to disable registration with SIP Proxy + + By default, if a SIP uri is specified, testUA will attempt to register with it. Use + this switch to disable this. + + -d <DNS servers> - comma seperated list of DNS servers, overrides OS detected list + + By default, testUA will query the OS for a list of DNS servers. Use this option in + cases where the OS does not return any, or the correct values. + + -sp <port num> - local port number to use for SIP messaging (UDP/TCP) + + By default, testUA will use port 5062 for SIP messaging, use this switch to specify + something different. + + -mp <port num> - local port number to start allocating from for RTP media + + By default, testUA will use media ports starting at 17384, use this switch to specify + something different. + + -tp <port num> - local port number to use for TLS SIP messaging + + By default, testUA will listen for TLS connections on port 5063, use this switch to + specify something different. Note SIP certificiates must be present in executable + directory for windows hosts and ~/.sipCerts directory on linux hosts. + + -td <domain name> - domain name to use for TLS server connections + + By default, testUA will query the OS for a local hostname for TLS, use this switch + to override the OS queried result. + + -nk - no keepalives, set this to disable sending of keepalives + + By default, testUA will enable UDP CRLF keepalives every 30 seconds and TCP keepalives + every 180 seconds. Use this switch to disable CRLF keepalives. + + -op <SIP URI> - URI of a proxy server to use a SIP outbound proxy + + By default testUA does not use an outbound proxy. Use this switch to route all + outbound, out-of-dialog requests through a fixed proxy despite the destination URI. + + -sm <Srtp|SrtpReq|SrtpDtls|SrtpDtlsReq> - sets the secure media mode + + By default, no secure media is offered in outbound SIP requests. Use this option to + change that behaviour. Note: Inbound secure media is always accepted. + Srtp - use SRTP with keying outside of media stream (SDES key negotiation) + via SDP. RTP/AVP profile is used, and transport capability of RTP/SAVP is + listed, in order to implement best-effort SRTP. Note: The crypo attribute + is provided outside of the SDP capability, as this is required by SNOM for + optional SRTP offers. + SrtpReq - use SRTP with keying outside of media stream (SDES key negotiation) + via SDP. RTP/SAVP profile is used to indicate that SRTP is mandatory. + SrtpDtls - use SRTP with DTLS key negotiation. RTP/AVP is use as a default, and a + transport capability of UDP/TLS/RTP/SAVP is listed, in order to impelement + best-effort DTLS-SRTP. + SrtpDtlsReq - use SRTP with DTLS key negotiation. UDP/TLS/RTP/SAVP profile is used to + indicate that Dtls-Srtp use is mandatory. + + -nm <Bind|UdpAlloc|TcpAlloc|TlsAlloc> - sets the NAT traversal mode + + By default, no NAT traversal strategies are used. Use this switch to specify one: + Bind - use Binding discovery on a STUN server, to discover and use "public" address + and port in SDP negotiations + UdpAlloc - Use a TURN server as a media relay. Communicate to the TURN + server over UDP and Allocate a UDP relay address and port to + use in SDP negotiations + TcpAlloc - Use a TURN server as a media relay. Communicate to the TURN + server over TCP and Allocate a UDP relay address and port to + use in SDP negotiations + TlsAlloc - Use a TURN server as a media relay. Communicate to the TURN + server over TLS and Allocate a UDP relay address and port to + use in SDP negotiations + + -ns <server:port> - set the hostname and port of the NAT STUN/TURN server + + If -nm switch is used then you MUST specify the STUN/TURN server name/address and port. + + -nu <username> - sets the STUN/TURN username to use for NAT server + + Use this option if the STUN/TURN server requires authentication. + + -np <password> - sets the STUN/TURN password to use for NAT server + + Use this option if the STUN/TURN server requires authentication. + + -nl - disables local audio support - removes requirement for local audio hardware. + Note: if local audio support is disabled, then local participants cannot + be created. + + -l <NONE|CRIT|ERR|WARNING|INFO|DEBUG|STACK> - logging level + + By default the logging level is INFO, use this switch to change it. + + +Sample Command line: + testUA -a 192.168.1.100 -u sip:1000@myproxy.com -p 123 -aa + + + +Console Command Reference +------------------------- +Once the console is started, testUA will automatically register with a proxy server, +if required. + +When starting testUA, one Conversation (Handle=1) and one local participant (Handle=1) is +automatically created for convienience. + +The console then accepts the following commands: +createConversation: <'createconv'|'cc'> + Create a new empty conversation. + +destroyConversation: <'destroyconv'|'dc'> <convHandle> + Destroys conversation and ends all participants that solely belong to this conversation. + +joinConversation: <'joinconv'|'jc'> <sourceConvHandle> <destConvHandle> + Add all participants from source conversation to destination conversation + and destroys source conversation. + +createLocalParticipant: <'createlocal'|'cl'> + Creates a new local participant. + +createRemoteParticipant: <'createremote'|'crp'> <convHandle> <destURI> [<'manual'>] + (last arg is fork select mode, 'auto' is default) + Creates a new remote participant (outbound SIP call) in conversation specified. + Dest URI must be provided. When ForkSelectMode is set to auto the conversation + manager will automatically dispose of any related conversations that were created, + due to forking. + +createMediaResourceParticipant: <'createmedia'|'cmp'> <convHandle> <mediaURL> [<durationMs>] + Creates a new media resource participant in the specified conversation. Media is played + from a source specified by the url and may be a local audio file, audio file fetched via + HTTP or tones. The URL can contain parameters that specify properties of the media + playback, such as number of repeats. + Media Urls are of the following format: + "tone"|"file":<tone|filepath>[;duration=<duration>][;local-only] + [;remote-only][;repeat][;prefetch] + Tones can be any DTMF digit 0-9,*,#,A-D or a special tone: + dialtone, busy, fastbusy, ringback, ring, backspace, callwaiting, holding, or + loudfastbusy + Note: 'repeat' option only makes sense for file and http URLs + Note2: 'prefetch' option only makes sense for http URLs + Note3: audio files may be AU, WAV or RAW formats. Audiofiles should be 16bit mono, + 8khz, PCM to avoid runtime conversion. + +destroyParticipant: <'destroypart'|'dp'> <parthandle> + Ends connections to the participant and removes it from all active conversations. + +addPartcipant: <'addpart'|'ap'> <convHandle> <partHandle> + Adds a participant to an existing conversation. + +removePartcipant: <'removepart'|'rp'> <convHandle> <partHandle> + Removes a participant from a conversation. If the participant no longer exists in + any conversation, then they are destroyed (local participants exempt). For a remote + participant this means the call will be released. + +moveParticipant: <'movepart'|'mp'> <partHandle> <srcConvHandle> <dstConvHandle> + Removes participant from src conversation and adds them to the dst conversation. + +modifyParticipantContribution: <'partcontrib'|'pc'> <convHandle> <partHandle> <inputGain> + <outputGain> (gain in percentage) + Sets a participants input and output gain towards the specified conversation. + +outputBridgeMatrix: <'bridgematrix'|'bm'> + Outputs the sipX mixing bridge matrix for debugging purposes. + +alertPartcipant: <'alert'|'al'> <partHandle> [<'noearly'>] + (last arg is early flag, enabled by default) + Sends a 180 response to the far end. If noearly is enabled then SDP is not sent in the + response. + +answerParticipant: <'answer'|'an'> <partHandle> + Sends a 200 response to the far end. + +rejectParticipant: <'reject'|'rj'> <partHandle> [<statusCode>] + Sends the specied response code to the far end. (default status code is 486) + +redirectPartcipant: <'redirect'|'rd'> <partHandle> <destURI> + If unanswered - sends a 302 response to the far end with the destURI in the + contact header. Otherwise sends a REFER request to the far end. + +redirectToPartcipant: <'redirectTo'|'rt'> <partHandle> <destPartHandle> + Sends a REFER request to the far end with a 'replaces' header corresponding to the + partHandle specified. + +setSpeakerVolume: <'volume'|'sv'> <volume> +setMicrophoneGain: <'gain'|'sg'> <gain> +muteMicrophone: <'mute'|'mm'> <'0'|'1'> (1 to enable/mute) +enableEchoCancel: <'echocancel'|'aec'> <'0'|'1'> (1 to enable) +enableAutoGainControl: <'autogain'|'agc'> <'0'|'1'> (1 to enable) +enableNoiseReduction: <'noisereduction'|'nr'> <'0'|'1'> (1 to enable) + +createSubscription: <'subscribe'|'cs'> <eventType> <targetUri> <subTime> + <mimeType> <mimeSubType> + Creates a SIP subscription to the targetURI of the corresponding eventType. + Expected mimeType and subType must be specified. + +destroySubscription: <'destsub'|'ds'> <subHandle> + Unsubscribes an existing subscription. + +setAutoAnswer <'autoans'|'aa'> <'0'|'1'> (1 to enable (default) + Enable this to have testUA automatically answer incoming calls and add to the + lowest numbered created conversation. + +setCodecs <'setcodecs'|'sc'> <codecId>[,<codecId>]+ (comma separated list) + Changes the default codec list/order. Note a codec plugin must have been + present at startup time, in order to use that codec. Unknown id's are + ignored. Default is: 0,8,96,98,99,108,97,3,109 + Acceptable sipX codec Ids are: + 0 - G.711 mu-law + 3 - GSM codec + 8 - G.711 a-law + 96 - Speex NB, 8,000bps + 97 - Speex NB, 5,950bps + 98 - Speex NB, 15,000bps + 99 - Speex NB, 24,600bps + 108 - Internet Low Bit Rate Codec - iLBC (RFC3951) + 109 - AVT/DTMF Tones, RFC 2833 + +setSecureMediaMode <'securemedia'|'sm'> <'None'|'Srtp'|'SrtpReq'|'SrtpDtls'|'SrtpDtlsReq'> + Allows changing the secure media mode at runtime. Controls what is present + for secure media in our SDP offers. Note: Inbound secure media is always accepted. + Srtp - use SRTP with keying outside of media stream (SDES key negotiation) + via SDP. RTP/AVP profile is used, and transport capability of RTP/SAVP is + listed, in order to implement best-effort SRTP. Note: The crypo attribute + is provided outside of the SDP capability, as this is required by SNOM for + optional SRTP offers. + SrtpReq - use SRTP with keying outside of media stream (SDES key negotiation) + via SDP. RTP/SAVP profile is used to indicate that SRTP is mandatory. + SrtpDtls - use SRTP with DTLS key negotiation. RTP/AVP is use as a default, and a + transport capability of UDP/TLS/RTP/SAVP is listed, in order to impelement + best-effort DTLS-SRTP. + SrtpDtlsReq - use SRTP with DTLS key negotiation. UDP/TLS/RTP/SAVP profile is used to + indicate that Dtls-Srtp use is mandatory. + +setNATTraversalMode <'natmode'|'nm'> <'None'|'Bind'|'UdpAlloc'|'TcpAlloc'|'TlsAlloc'> + Allows changing the NAT traversal mode at runtime. + Bind - use Binding discovery on a STUN server, to discover and use "public" address + and port in SDP negotiations + UdpAlloc - Use a TURN server as a media relay. Communicate to the TURN + server over UDP and Allocate a UDP relay address and port to + use in SDP negotiations + TcpAlloc - Use a TURN server as a media relay. Communicate to the TURN + server over TCP and Allocate a UDP relay address and port to + use in SDP negotiations + TlsAlloc - Use a TURN server as a media relay. Communicate to the TURN + server over TLS and Allocate a UDP relay address and port to + use in SDP negotiations + +setNATTraversalServer <'natserver'|'ns'> <server:port> + Allows changing the STUN/TURN server hostname and port at runtime. + +setNATUsername <'natuser'|'nu'> <username> + Allows changing the STUN/TURN username at runtime. + +setNATPassword <'natpwd'|'np'> <password> + Allows chaning the STUN/TURN password at runtime. + +startApplicationTimer: <'starttimer'|'st'> <timerId> <durationMs> <seqNo> + Test interface for application time API. + +displayInfo: <'info'|'i'> + Display information about all of the currently created conversation handles, and + participant handles. + +exitProgram: <'exit'|'quit'|'q'> diff --git a/src/libs/resiprocate/resip/recon/test/unitTests.cxx b/src/libs/resiprocate/resip/recon/test/unitTests.cxx new file mode 100644 index 00000000..bf092802 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/unitTests.cxx @@ -0,0 +1,849 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "UserAgent.hxx" +#include "ReconSubsystem.hxx" + +#include <signal.h> +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" +#include "rutil/DnsUtil.hxx" +#include <rutil/WinLeakCheck.hxx> + +#ifdef WIN32 +extern int sdpTests(void); +#endif + +/////////////////////////////////////////////////////////////////////////// +// SCENARIOS UNDER TEST +// +// Scenario 1: Simple call: Alice -> Bob +// +// Alice Bob Callback Sequence +// -------------------------- ------------------------ ------------------ +// createConversation +// createLocalParticipant +// addParticipant +// createRemoteParticipant +// <-onIncomingCall 1 +// alertParticpant +// <-onParticipantAlerting 2 +// createConversation +// addParticipant +// answerParticipant +// <-onParticpantConnected 3 +// destroyConversation +// <-onParticipantTerminated 4 +// <-onParticipantTerminated 5 +// +// +// Scenario 2: Call Rejection: Bob -> Alice +// +// Alice Bob Callback Sequence +// -------------------------- ------------------------ ------------------ +// createConversation +// createRemoteParticipant +// <-onIncomingCall 1 +// rejectParticpant +// <-onParticipantTerminated 2 +// <-onParticipantTerminated 3 +// +// +// Scenario 3: Call Redirection: Bob -> Alice +// +// Alice Bob Callback Sequence +// -------------------------- ------------------------ ------------------ +// createConversation +// createRemoteParticipant +// <-onIncomingCall 1 +// redirectParticpant +// <-onParticipantTerminated 2 +// <-onIncomingCall 3 +// rejectParticpant +// <-onParticipantTerminated 4 +// <-onParticipantTerminated 5 +// +// +// Scenario 4: Call Hold/Transfer: Bob -> Alice +// +// Alice Bob Callback Sequence +// -------------------------- ------------------------ ------------------ +// createConversation +// createLocalPartcipant +// addPartcipant +// createRemoteParticipant +// <-onIncomingCall 1 +// createConversation +// addParticipant +// alertParticpant(early) +// <-onParticipantAlerting 2 +// answerParticipant +// <-onParticpantConnected 3 +// removeParticipant(local/hold) +// redirectParticipant to bad dest +// call failure (408) +// <-onParticipantRedirectFailure 4 +// destroyParticipant +// <-onParticipantTerminated 5 +// <-onParticipantTerminated 6 +// +/////////////////////////////////////////////////////////////////////////// + +using namespace recon; +using namespace resip; +using namespace std; + +unsigned int SCENARIO = 1; +unsigned int LAST_SCENARIO = 4; +unsigned int CALLBACK_SEQUENCE = 1; + +NameAddr aliceUri("sip:alice@127.0.0.1:32543"); +NameAddr bobUri("sip:bob@127.0.0.1:32544"); + +//#define LOG_LEVEL resip::Log::Info +#define LOG_LEVEL resip::Log::Warning +#define MARKER cout << "**** SCENARIO " << SCENARIO << " CALLBACK_SEQUENCE " << CALLBACK_SEQUENCE-1 << " passed! ****" << endl + +#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON + +void sleepSeconds(unsigned int seconds) +{ +#ifdef WIN32 + Sleep(seconds*1000); +#else + sleep(seconds); +#endif +} + +static bool finished = false; + +static void +signalHandler(int signo) +{ + std::cerr << "Shutting down" << endl; + finished = true; +} + +/////////////////////////////////////////////////////////////////////////////// +// ALICE +/////////////////////////////////////////////////////////////////////////////// +class AliceConversationManager : public ConversationManager +{ +public: + AliceConversationManager(ConversationManager::MediaInterfaceMode mode) : ConversationManager(true, mode) + { + mLogPrefix = "Alice: "; + }; + + virtual ConversationHandle createConversation() + { + ConversationHandle convHandle = ConversationManager::createConversation(); + mConvHandles.push_back(convHandle); + return convHandle; + } + + virtual void startup() + { + ConversationHandle convHandle = createConversation(); + mLocalParticipant = createLocalParticipant(); + addParticipant(convHandle, mLocalParticipant); + createRemoteParticipant(convHandle, bobUri, ConversationManager::ForkSelectAutomatic); + } + + virtual void onConversationDestroyed(ConversationHandle convHandle) + { + InfoLog(<< mLogPrefix << "onConversationDestroyed: handle=" << convHandle); + } + + virtual void onParticipantDestroyed(ParticipantHandle partHandle) + { + InfoLog(<< mLogPrefix << "onParticipantDestroyed: handle=" << partHandle); + } + + virtual void onApplicationTimer(unsigned int id, unsigned int durationMs, unsigned int seq) + { + InfoLog(<< mLogPrefix << "onApplicationTimeout: id=" << id << " dur=" << durationMs << " seq=" << seq); + } + + virtual void onIncomingParticipant(ParticipantHandle partHandle, const SipMessage& msg, bool autoAnswer, ConversationProfile& conversationProfile) + { + InfoLog(<< mLogPrefix << "onIncomingParticipant: handle=" << partHandle << " msg=" << msg.brief()); + switch(SCENARIO) + { + case 2: + assert(CALLBACK_SEQUENCE++ == 1); + assert(partHandle == 3); + assert(autoAnswer == false); + MARKER; + rejectParticipant(partHandle, 486); + break; + case 3: + assert(CALLBACK_SEQUENCE == 1 || CALLBACK_SEQUENCE == 3); + CALLBACK_SEQUENCE++; + if(CALLBACK_SEQUENCE-1 == 1) + { + assert(partHandle == 4); + assert(autoAnswer == false); + MARKER; + redirectParticipant(partHandle, aliceUri); + } + else + { + assert(partHandle == 5); + assert(autoAnswer == false); + MARKER; + rejectParticipant(partHandle, 404); + } + break; + case 4: + assert(CALLBACK_SEQUENCE++ == 1); + assert(partHandle == 6); + assert(autoAnswer == false); + MARKER; + { + ConversationHandle convHandle = createConversation(); + addParticipant(convHandle, partHandle); + } + alertParticipant(partHandle, true); + answerParticipant(partHandle); + break; + default: + assert(false); + break; + } + } + + virtual void onRequestOutgoingParticipant(ParticipantHandle partHandle, const SipMessage& msg, ConversationProfile& conversationProfile) + { + InfoLog(<< mLogPrefix << "onRequestOutgoingParticipant: handle=" << partHandle << " msg=" << msg.brief()); + } + + virtual void onParticipantTerminated(ParticipantHandle partHandle, unsigned int statusCode) + { + InfoLog(<< mLogPrefix << "onParticipantTerminated: handle=" << partHandle << " status=" << statusCode); + + switch(SCENARIO) + { + case 1: + assert(CALLBACK_SEQUENCE++ == 4); + assert(partHandle == 2); // Note: LocalParticipant is part handle 1, remote is 2 + assert(statusCode == 0); + MARKER; + break; + case 2: + assert(CALLBACK_SEQUENCE++ == 2); + assert(partHandle == 3); + assert(statusCode == 0); + MARKER; + break; + case 3: + assert(CALLBACK_SEQUENCE == 2 || CALLBACK_SEQUENCE == 4); + CALLBACK_SEQUENCE++; + if(CALLBACK_SEQUENCE-1 == 2) + { + assert(partHandle == 4); + assert(statusCode == 0); + MARKER; + } + else + { + assert(partHandle == 5); + assert(statusCode == 0); + MARKER; + } + break; + case 4: + assert(CALLBACK_SEQUENCE++ == 6); + assert(partHandle == 6); + assert(statusCode == 0); + MARKER; + break; + default: + assert(false); + break; + } + + // Destroy all conversations + std::list<ConversationHandle>::iterator it; + for(it = mConvHandles.begin(); it != mConvHandles.end(); it++) + { + destroyConversation(*it); + } + mConvHandles.clear(); + } + + virtual void onParticipantProceeding(ParticipantHandle partHandle, const SipMessage& msg) + { + InfoLog(<< mLogPrefix << "onParticipantProceeding: handle=" << partHandle << " msg=" << msg.brief()); + } + + virtual void onRelatedConversation(ConversationHandle relatedConvHandle, ParticipantHandle relatedPartHandle, + ConversationHandle origConvHandle, ParticipantHandle origPartHandle) + { + InfoLog(<< mLogPrefix << "onRelatedConversation: relatedConvHandle=" << relatedConvHandle << " relatedPartHandle=" << relatedPartHandle + << " origConvHandle=" << origConvHandle << " origPartHandle=" << origPartHandle); + mConvHandles.push_back(relatedConvHandle); + } + + virtual void onParticipantAlerting(ParticipantHandle partHandle, const SipMessage& msg) + { + InfoLog(<< mLogPrefix << "onParticipantAlerting: handle=" << partHandle << " msg=" << msg.brief()); + switch(SCENARIO) + { + case 1: + assert(CALLBACK_SEQUENCE++ == 2); + assert(partHandle == 2); // Note: LocalParticipant is part handle 1, remote is 2 + MARKER; + break; + default: + assert(false); + break; + } + } + + virtual void onParticipantConnected(ParticipantHandle partHandle, const SipMessage& msg) + { + InfoLog(<< mLogPrefix << "onParticipantConnected: handle=" << partHandle << " msg=" << msg.brief()); + switch(SCENARIO) + { + case 1: + assert(CALLBACK_SEQUENCE++ == 3); + assert(partHandle == 2); // Note: LocalParticipant is part handle 1, remote is 2 + MARKER; + { + // Destroy all conversations + std::list<ConversationHandle>::iterator it; + for(it = mConvHandles.begin(); it != mConvHandles.end(); it++) + { + destroyConversation(*it); + } + mConvHandles.clear(); + } + break; + default: + assert(false); + break; + } + } + + virtual void onParticipantRedirectSuccess(ParticipantHandle partHandle) + { + InfoLog(<< mLogPrefix << "onParticipantRedirectSuccess: handle=" << partHandle); + } + + virtual void onParticipantRedirectFailure(ParticipantHandle partHandle, unsigned int statusCode) + { + InfoLog(<< mLogPrefix << "onParticipantRedirectFailure: handle=" << partHandle << " statusCode=" << statusCode); + } + + virtual void onDtmfEvent(ParticipantHandle partHandle, int dtmf, int duration, bool up) {} + +private: + std::list<ConversationHandle> mConvHandles; + ParticipantHandle mLocalParticipant; + Data mLogPrefix; +}; + +/////////////////////////////////////////////////////////////////////////////// +// BOB +/////////////////////////////////////////////////////////////////////////////// +class BobConversationManager : public ConversationManager +{ +public: + BobConversationManager(ConversationManager::MediaInterfaceMode mode) : ConversationManager(true, mode) + { + mLogPrefix = "Bob: "; + }; + + virtual ConversationHandle createConversation() + { + ConversationHandle convHandle = ConversationManager::createConversation(); + mConvHandles.push_back(convHandle); + return convHandle; + } + + virtual void startup() + { + } + + virtual void onConversationDestroyed(ConversationHandle convHandle) + { + InfoLog(<< mLogPrefix << "onConversationDestroyed: handle=" << convHandle); + } + + virtual void onParticipantDestroyed(ParticipantHandle partHandle) + { + InfoLog(<< mLogPrefix << "onParticipantDestroyed: handle=" << partHandle); + } + + virtual void onApplicationTimer(unsigned int id, unsigned int durationMs, unsigned int seq) + { + InfoLog(<< mLogPrefix << "onApplicationTimeout: id=" << id << " dur=" << durationMs << " seq=" << seq); + + if(SCENARIO == LAST_SCENARIO) + { + // End Test + finished = true; + } + else + { + // Kick off next scenario + cout << endl; + SCENARIO++; + CALLBACK_SEQUENCE = 1; + switch(SCENARIO) + { + case 2: + case 3: + { + ConversationHandle convHandle = createConversation(); + createRemoteParticipant(convHandle, aliceUri, ConversationManager::ForkSelectAutomatic); + } + break; + case 4: + { + ConversationHandle convHandle = createConversation(); + mLocalParticipant = createLocalParticipant(); + addParticipant(convHandle, mLocalParticipant); + createRemoteParticipant(convHandle, aliceUri, ConversationManager::ForkSelectAutomatic); + } + break; + default: + assert(false); + break; + } + } + } + + virtual void onIncomingParticipant(ParticipantHandle partHandle, const SipMessage& msg, bool autoAnswer, ConversationProfile& conversationProfile) + { + InfoLog(<< mLogPrefix << "onIncomingParticipant: handle=" << partHandle << " msg=" << msg.brief()); + switch(SCENARIO) + { + case 1: + assert(CALLBACK_SEQUENCE++ == 1); + assert(partHandle == 1); // Note: Bob has no local participant + assert(autoAnswer == false); + MARKER; + alertParticipant(partHandle, false); + { + ConversationHandle convHandle = createConversation(); + addParticipant(convHandle, partHandle); + } + answerParticipant(partHandle); + break; + default: + assert(false); + break; + } + } + + virtual void onRequestOutgoingParticipant(ParticipantHandle partHandle, const SipMessage& msg, ConversationProfile& conversationProfile) + { + InfoLog(<< mLogPrefix << "onRequestOutgoingParticipant: handle=" << partHandle << " msg=" << msg.brief()); + if(mConvHandles.empty()) + { + ConversationHandle convHandle = createConversation(); + addParticipant(convHandle, partHandle); + } + } + + virtual void onParticipantTerminated(ParticipantHandle partHandle, unsigned int statusCode) + { + InfoLog(<< mLogPrefix << "onParticipantTerminated: handle=" << partHandle << " status=" << statusCode); + + switch(SCENARIO) + { + case 1: + assert(CALLBACK_SEQUENCE++ == 5); + assert(partHandle == 1); // Note: Bob has no local participant + assert(statusCode == 0); + MARKER; + + // Next Scenario + getUserAgent()->startApplicationTimer(0, 500, 0); + break; + case 2: + assert(CALLBACK_SEQUENCE++ == 3); + assert(partHandle == 2); + assert(statusCode == 486); + MARKER; + + // End Test + getUserAgent()->startApplicationTimer(0, 500, 0); + break; + case 3: + assert(CALLBACK_SEQUENCE++ == 5); + assert(partHandle == 3); + assert(statusCode == 404); + MARKER; + + // End Test + getUserAgent()->startApplicationTimer(0, 500, 0); + break; + case 4: + assert(CALLBACK_SEQUENCE++ == 5); + assert(partHandle == 5); + assert(statusCode == 0); + MARKER; + + // End Test + getUserAgent()->startApplicationTimer(0, 500, 0); + break; + default: + assert(false); + break; + } + + // Destroy all conversations + std::list<ConversationHandle>::iterator it; + for(it = mConvHandles.begin(); it != mConvHandles.end(); it++) + { + destroyConversation(*it); + } + mConvHandles.clear(); + } + + virtual void onParticipantProceeding(ParticipantHandle partHandle, const SipMessage& msg) + { + InfoLog(<< mLogPrefix << "onParticipantProceeding: handle=" << partHandle << " msg=" << msg.brief()); + } + + virtual void onRelatedConversation(ConversationHandle relatedConvHandle, ParticipantHandle relatedPartHandle, + ConversationHandle origConvHandle, ParticipantHandle origPartHandle) + { + InfoLog(<< mLogPrefix << "onRelatedConversation: relatedConvHandle=" << relatedConvHandle << " relatedPartHandle=" << relatedPartHandle + << " origConvHandle=" << origConvHandle << " origPartHandle=" << origPartHandle); + mConvHandles.push_back(relatedConvHandle); + } + + virtual void onParticipantAlerting(ParticipantHandle partHandle, const SipMessage& msg) + { + InfoLog(<< mLogPrefix << "onParticipantAlerting: handle=" << partHandle << " msg=" << msg.brief()); + switch(SCENARIO) + { + case 4: + assert(CALLBACK_SEQUENCE++ == 2); + assert(partHandle == 5); + MARKER; + break; + default: + assert(false); + break; + } + } + + virtual void onParticipantConnected(ParticipantHandle partHandle, const SipMessage& msg) + { + InfoLog(<< mLogPrefix << "onParticipantConnected: handle=" << partHandle << " msg=" << msg.brief()); + switch(SCENARIO) + { + case 4: + assert(CALLBACK_SEQUENCE++ == 3); + assert(partHandle == 5); + MARKER; + removeParticipant(mConvHandles.front(), mLocalParticipant); // hold + { + NameAddr badAddress("sip:badAddress@127.0.0.1:33333"); + redirectParticipant(partHandle, badAddress); + } + break; + default: + assert(false); + break; + } + } + + virtual void onParticipantRedirectSuccess(ParticipantHandle partHandle) + { + InfoLog(<< mLogPrefix << "onParticipantRedirectSuccess: handle=" << partHandle); + } + + virtual void onParticipantRedirectFailure(ParticipantHandle partHandle, unsigned int statusCode) + { + InfoLog(<< mLogPrefix << "onParticipantRedirectFailure: handle=" << partHandle << " statusCode=" << statusCode); + switch(SCENARIO) + { + case 4: + assert(CALLBACK_SEQUENCE++ == 4); + assert(partHandle == 5); + MARKER; + destroyParticipant(partHandle); + break; + default: + assert(false); + break; + } + } + + virtual void onDtmfEvent(ParticipantHandle partHandle, int dtmf, int duration, bool up) {} + +private: + std::list<ConversationHandle> mConvHandles; + ParticipantHandle mLocalParticipant; + Data mLogPrefix; +}; + + +class MyUserAgent : public UserAgent +{ +public: + MyUserAgent(ConversationManager* conversationManager, SharedPtr<UserAgentMasterProfile> profile) : + UserAgent(conversationManager, profile) {} + + virtual void onApplicationTimer(unsigned int id, unsigned int durationMs, unsigned int seq) + { + //InfoLog(<< "onApplicationTimeout: id=" << id << " dur=" << durationMs << " seq=" << seq); + BobConversationManager* bcm = dynamic_cast<BobConversationManager*>(getConversationManager()); + if(bcm) + { + bcm->onApplicationTimer(id, durationMs, seq); + } + else + { + AliceConversationManager* acm = dynamic_cast<AliceConversationManager*>(getConversationManager()); + if(acm) + { + acm->onApplicationTimer(id, durationMs, seq); + } + } + } + + virtual void onSubscriptionTerminated(SubscriptionHandle handle, unsigned int statusCode) + { + InfoLog(<< "onSubscriptionTerminated: handle=" << handle << " statusCode=" << statusCode); + } + + virtual void onSubscriptionNotify(SubscriptionHandle handle, Data& notifyData) + { + InfoLog(<< "onSubscriptionNotify: handle=" << handle << " data=" << endl << notifyData); + } +}; + + +SharedPtr<UserAgentMasterProfile> createUserAgentMasterProfile() +{ + SharedPtr<UserAgentMasterProfile> profile(new UserAgentMasterProfile); + + // Settings + profile->statisticsManagerEnabled() = false; + profile->validateContentEnabled() = false; + profile->validateContentLanguageEnabled() = false; + profile->validateAcceptEnabled() = false; + profile->clearSupportedLanguages(); + profile->addSupportedLanguage(Token("en")); + profile->clearSupportedMimeTypes(); + profile->addSupportedMimeType(INVITE, Mime("application", "sdp")); + profile->addSupportedMimeType(OPTIONS,Mime("application", "sdp")); + profile->addSupportedMimeType(UPDATE, Mime("application", "sdp")); + profile->addSupportedMimeType(NOTIFY, Mime("message", "sipfrag")); + profile->clearSupportedMethods(); + profile->addSupportedMethod(INVITE); + profile->addSupportedMethod(ACK); + profile->addSupportedMethod(CANCEL); + profile->addSupportedMethod(OPTIONS); + profile->addSupportedMethod(BYE); + profile->addSupportedMethod(REFER); + profile->addSupportedMethod(NOTIFY); + profile->addSupportedMethod(SUBSCRIBE); + profile->addSupportedMethod(UPDATE); + profile->clearSupportedOptionTags(); + profile->addSupportedOptionTag(Token(Symbols::Replaces)); + profile->addSupportedOptionTag(Token(Symbols::Timer)); + profile->addSupportedOptionTag(Token(Symbols::NoReferSub)); + profile->addSupportedOptionTag(Token(Symbols::AnswerMode)); + profile->addSupportedOptionTag(Token(Symbols::TargetDialog)); + //profile->addSupportedOptionTag(Token(Symbols::C100rel)); + profile->clearSupportedSchemes(); + profile->addSupportedScheme("sip"); +#ifdef USE_SSL + profile->addSupportedScheme("sips"); +#endif + + // Have stack add Allow/Supported/Accept headers to INVITE dialog establishment messages + profile->clearAdvertisedCapabilities(); // Remove Profile Defaults, then add our preferences + profile->addAdvertisedCapability(Headers::Allow); + //profile->addAdvertisedCapability(Headers::AcceptEncoding); // This can be misleading - it might specify what is expected in response + profile->addAdvertisedCapability(Headers::AcceptLanguage); + profile->addAdvertisedCapability(Headers::Supported); + profile->setMethodsParamEnabled(true); + + return profile; +} + +SharedPtr<ConversationProfile> createConversationProfile(SharedPtr<UserAgentMasterProfile> profile, int port) +{ + SharedPtr<ConversationProfile> conversationProfile(new ConversationProfile(profile)); + conversationProfile->setDefaultRegistrationTime(0); + + // Create Session Capabilities and assign to coversation Profile + Data address("127.0.0.1"); + // Build s=, o=, t=, and c= lines + SdpContents::Session::Origin origin("-", 0 /* sessionId */, 0 /* version */, SdpContents::IP4, address); // o= Note: sessionId and version will be replace in actual offer/answer + SdpContents::Session session(0, origin, "-" /* s= */); + session.connection() = SdpContents::Session::Connection(SdpContents::IP4, address); // c= + session.addTime(SdpContents::Session::Time(0, 0)); + // Build Codecs and media offering + SdpContents::Session::Medium medium("audio", port, 0, "RTP/AVP"); + SdpContents::Session::Codec g711ucodec("PCMU", 8000); + g711ucodec.payloadType() = 0; /* RFC3551 */ ; + medium.addCodec(g711ucodec); + medium.addAttribute("ptime", Data(20)); // 20 ms of speech per frame (note G711 has 10ms samples, so this is 2 samples per frame) + medium.addAttribute("sendrecv"); + session.addMedium(medium); + + SdpContents sessionCaps; + sessionCaps.session() = session; + conversationProfile->sessionCaps() = sessionCaps; + + return conversationProfile; +} + +void executeConversationTest(ConversationManager::MediaInterfaceMode mode) +{ + ////////////////////////////////////////////////////////////////////////////// + // Setup UserAgentMasterProfiles + ////////////////////////////////////////////////////////////////////////////// + SharedPtr<UserAgentMasterProfile> profileAlice = createUserAgentMasterProfile(); + profileAlice->addTransport(UDP, aliceUri.uri().port(), V4); + SharedPtr<ConversationProfile> conversationProfileAlice = createConversationProfile(profileAlice, 16384); + conversationProfileAlice->setDefaultFrom(aliceUri); + conversationProfileAlice->setUserAgent("Test-Alice"); + + SharedPtr<UserAgentMasterProfile> profileBob = createUserAgentMasterProfile(); + profileBob->addTransport(UDP, bobUri.uri().port(), V4); + SharedPtr<ConversationProfile> conversationProfileBob = createConversationProfile(profileBob, 16385); + conversationProfileBob->setDefaultFrom(bobUri); + conversationProfileBob->setUserAgent("Test-Bob"); + + InfoLog(<< "Tests for sipXGlobalMediaInterfaceMode"); + + ////////////////////////////////////////////////////////////////////////////// + // Create ConverationManagers and UserAgents + ////////////////////////////////////////////////////////////////////////////// + + { + AliceConversationManager aliceConversationManager(mode); + MyUserAgent aliceUa(&aliceConversationManager, profileAlice); + aliceUa.addConversationProfile(conversationProfileAlice); + + BobConversationManager bobConversationManager(mode); + MyUserAgent bobUa(&bobConversationManager, profileBob); + bobUa.addConversationProfile(conversationProfileBob); + + ////////////////////////////////////////////////////////////////////////////// + // Startup and run... + ////////////////////////////////////////////////////////////////////////////// + + aliceUa.startup(); + aliceConversationManager.startup(); + + bobUa.startup(); + bobConversationManager.startup(); + + while(true) + { + aliceUa.process(50); + bobUa.process(50); + if(finished) break; + } + + aliceUa.shutdown(); + bobUa.shutdown(); + } +} + +int +main (int argc, char** argv) +{ +#ifndef _WIN32 + if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR) + { + cerr << "Couldn't install signal handler for SIGPIPE" << endl; + exit(-1); + } +#endif + +#if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK) + resip::FindMemoryLeaks fml; + { +#endif + + if ( signal( SIGINT, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGINT" << endl; + exit( -1 ); + } + + if ( signal( SIGTERM, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGTERM" << endl; + exit( -1 ); + } + +#ifdef WIN32 + // Run SdpTests + sdpTests(); +#endif + + Log::initialize(Log::Cout, LOG_LEVEL, argv[0]); + //Log::initialize(Log::Cout, resip::Log::Debug, argv[0]); + initNetwork(); + + cout << "Tests for sipXConversationMediaInterfaceMode" << endl; + executeConversationTest(ConversationManager::sipXConversationMediaInterfaceMode); + + // Reset counters, etc. + SCENARIO = 1; + LAST_SCENARIO = 4; + CALLBACK_SEQUENCE = 1; + finished = false; + + cout << "Tests for sipXGlobalMediaInterfaceMode" << endl; + executeConversationTest(ConversationManager::sipXGlobalMediaInterfaceMode); + + InfoLog(<< "unitTests is shutdown."); + //sleepSeconds(10); + +#if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK) + } // End FML scope +#endif + +} + + + +/* ==================================================================== + + Copyright (c) 2007-2008, Plantronics, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Plantronics nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ==================================================================== */ diff --git a/src/libs/resiprocate/resip/recon/test/unitTests_10_0.vcxproj b/src/libs/resiprocate/resip/recon/test/unitTests_10_0.vcxproj new file mode 100644 index 00000000..308bb078 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/unitTests_10_0.vcxproj @@ -0,0 +1,195 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>unitTests</ProjectName> + <ProjectGuid>{16CD976A-5D3B-4329-88BA-A32560CDFCC9}</ProjectGuid> + <RootNamespace>unitTests</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <BuildLog> + <Path>$(IntDir)BuildLog-unitTests.htm</Path> + </BuildLog> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../;$(ProjectDir)/../../../;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include;$(ProjectDir)/../../../reTurn;$(ProjectDir)/../../../contrib/asio;$(ProjectDir)/../../../contrib/boost_1_34_1;$(ProjectDir)/../../../contrib/openssl/inc32;$(ProjectDir)/../../../contrib/srtp/include;$(ProjectDir)/../../../contrib/srtp/crypto/include;$(ProjectDir)/../../../reflow;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <ProgramDataBaseFileName>$(IntDir)unitTests.pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalOptions>/FIXED:NO %(AdditionalOptions)</AdditionalOptions> + <AdditionalDependencies>Ws2_32.lib;Dnsapi.lib;iphlpapi.lib;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib;$(ProjectDir)..\..\..\contrib\pcre\Debug\pcre.lib;$(ProjectDir)..\..\..\contrib\srtp\Debug\libSRTP.lib;winmm.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Debug\sipxportlib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Debug\sipxsdplib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Debug\sipxmedialib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Debug\sipxmediaadapterlib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)unitTests.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)unitTests.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <BuildLog> + <Path>$(IntDir)BuildLog-unitTests.htm</Path> + </BuildLog> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <OmitFramePointers>true</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)/../;$(ProjectDir)/../../../;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include;$(ProjectDir)/../../../reTurn;$(ProjectDir)/../../../contrib/asio;$(ProjectDir)/../../../contrib/boost_1_34_1;$(ProjectDir)/../../../contrib/openssl/inc32;$(ProjectDir)/../../../contrib/srtp/include;$(ProjectDir)/../../../contrib/srtp/crypto/include;$(ProjectDir)/../../../reflow;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <ProgramDataBaseFileName>$(IntDir)unitTests.pdb</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalOptions>/FIXED:NO %(AdditionalOptions)</AdditionalOptions> + <AdditionalDependencies>Ws2_32.lib;Dnsapi.lib;iphlpapi.lib;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib;$(ProjectDir)..\..\..\contrib\pcre\Release\pcre.lib;$(ProjectDir)..\..\..\contrib\srtp\Release\libSRTP.lib;winmm.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Release\sipxportlib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Release\sipxsdplib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Release\sipxmedialib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Release\sipxmediaadapterlib.lib;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)unitTests.exe</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)unitTests.pdb</ProgramDatabaseFile> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="sdpTests.cxx" /> + <ClCompile Include="unitTests.cxx" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\win32\VS2003\libspeexdsp\libspeexdsp.vcxproj"> + <Project>{03207781-0d1c-4db3-a71d-45c608f28dbd}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\win32\VS2003\libspeex\libspeex.vcxproj"> + <Project>{e972c52f-9e85-4d65-b19c-031e511e9db4}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgilbc\plgilbc-msvc8.vcxproj"> + <Project>{6442c7de-e500-4ba2-b821-98092f1edcaf}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgpcmapcmu\plgpcmapcmu-msvc8.vcxproj"> + <Project>{a9c94d26-c90d-4860-8195-56929e893757}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgspeex\plgspeex-msvc8.vcxproj"> + <Project>{4f7fda11-42a4-4556-a631-15aa785cd1c1}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\..\sipXtapi\sipXmediaLib\src\mp\codecs\plgtones\plgtones-msvc8.vcxproj"> + <Project>{f3bca14e-f24d-4570-833e-8c20c4c393f7}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\contrib\pcre\pcre_10_0.vcxproj"> + <Project>{b933f895-8efb-4fdd-a46d-09b8c00d1d26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\contrib\srtp\srtp10.vcxproj"> + <Project>{eef031cb-fed8-451e-a471-91ec8d4f6750}</Project> + <Private>true</Private> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies> + <LinkLibraryDependencies>true</LinkLibraryDependencies> + <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs> + </ProjectReference> + <ProjectReference Include="..\..\..\reflow\reflow_10_0.vcxproj"> + <Project>{d2ab531b-86ac-43dd-a330-9809b4f1bb53}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\reTurn\client\reTurnClient_10_0.vcxproj"> + <Project>{67b5906c-5c9d-4d09-ac7e-af71d72175f8}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\rutil\rutil_10_0.vcxproj"> + <Project>{3d0e5ceb-93dc-4fdb-918b-d08fa369e106}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\dum\dum_10_0.vcxproj"> + <Project>{31b0654f-e08e-405f-909f-80f86cb14b9d}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\stack\resiprocate_10_0.vcxproj"> + <Project>{2a8be839-6466-4001-b224-8f1c3168d04a}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\recon_10_0.vcxproj"> + <Project>{16cd976a-5d3b-4329-88ba-a32560cdfcc7}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/recon/test/unitTests_10_0.vcxproj.filters b/src/libs/resiprocate/resip/recon/test/unitTests_10_0.vcxproj.filters new file mode 100644 index 00000000..403a7fa8 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/unitTests_10_0.vcxproj.filters @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{248cc270-c04e-4985-baf7-3dabd74bd58d}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{a591bcb6-7f2a-4ba6-8825-c471272a16b2}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{e22a1cdc-2bc6-4d50-9363-e57db1f19f4f}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="sdpTests.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="unitTests.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/recon/test/unitTests_8_0.vcproj b/src/libs/resiprocate/resip/recon/test/unitTests_8_0.vcproj new file mode 100644 index 00000000..bba37fe7 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/unitTests_8_0.vcproj @@ -0,0 +1,225 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="unitTests" + ProjectGUID="{16CD976A-5D3B-4329-88BA-A32560CDFCC9}" + RootNamespace="unitTests" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-unitTests.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)/unitTests.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\pcre\Debug\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Debug\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Debug\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Debug\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Debug\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Debug\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/unitTests.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/unitTests.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-unitTests.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)\unitTests.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\pcre\Release\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Release\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Release\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Release\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Release\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Release\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/unitTests.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/unitTests.pdb" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath=".\sdpTests.cxx" + > + </File> + <File + RelativePath=".\unitTests.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/recon/test/unitTests_9_0.vcproj b/src/libs/resiprocate/resip/recon/test/unitTests_9_0.vcproj new file mode 100644 index 00000000..81f0d2a2 --- /dev/null +++ b/src/libs/resiprocate/resip/recon/test/unitTests_9_0.vcproj @@ -0,0 +1,399 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="unitTests" + ProjectGUID="{16CD976A-5D3B-4329-88BA-A32560CDFCC9}" + RootNamespace="unitTests" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-unitTests.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)/unitTests.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\pcre\Debug\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Debug\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Debug\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Debug\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Debug\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Debug\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/unitTests.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/unitTests.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-unitTests.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)\unitTests.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\pcre\Release\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Release\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Release\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Release\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Release\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Release\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/unitTests.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/unitTests.pdb" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-unitTests.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;_DEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;LEAK_CHECK;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)/unitTests.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32.dbg\ssleay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\pcre\Debug\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Debug\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Debug\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Debug\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Debug\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Debug\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/unitTests.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/unitTests.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + BuildLogFile="$(IntDir)\BuildLog-unitTests.htm" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)/../&quot;;&quot;$(ProjectDir)/../../../&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/sipXmediaMediaProcessing/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaAdapterLib/interface&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXPortLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXtackLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXsdpLib/include&quot;;&quot;$(ProjectDir)/../../../../sipXtapi/sipXMediaLib/include&quot;;&quot;$(ProjectDir)/../../../reTurn&quot;;&quot;$(ProjectDir)/../../../contrib/asio&quot;;&quot;$(ProjectDir)/../../../contrib/boost_1_34_1&quot;;&quot;$(ProjectDir)/../../../contrib/openssl/inc32&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/include&quot;;&quot;$(ProjectDir)/../../../contrib/srtp/crypto/include&quot;;&quot;$(ProjectDir)/../../../reflow&quot;" + PreprocessorDefinitions="WIN32;_WIN32_WINNT=0x0501;NDEBUG;_CONSOLE;USE_IPV6;USE_ARES;DEFAULT_BRIDGE_MAX_IN_OUTPUTS=10;BOOST_ALL_NO_LIB;USE_SSL;_CRT_SECURE_NO_WARNINGS;ASIO_ENABLE_CANCELIO" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + ProgramDataBaseFileName="$(IntDir)\unitTests.pdb" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/FIXED:NO" + AdditionalDependencies="Ws2_32.lib Dnsapi.lib iphlpapi.lib &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\libeay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\openssl\out32\ssleay32.lib&quot; &quot;$(ProjectDir)..\..\..\contrib\pcre\Release\pcre.lib&quot; $(ProjectDir)..\..\..\contrib\srtp\Release\libSRTP.lib winmm.lib &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXportLib\Release\sipxportlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXsdpLib\Release\sipxsdplib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\Release\sipxmedialib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaAdapterLib\Release\sipxmediaadapterlib.lib&quot; &quot;$(ProjectDir)..\..\..\..\sipXtapi\sipXmediaLib\contrib\libspeex\lib\libspeex.lib&quot;" + OutputFile="$(OutDir)/unitTests.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/unitTests.pdb" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath=".\sdpTests.cxx" + > + </File> + <File + RelativePath=".\unitTests.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/sip.mcp.xml b/src/libs/resiprocate/resip/sip.mcp.xml new file mode 100644 index 00000000..2d0d00e9 --- /dev/null +++ b/src/libs/resiprocate/resip/sip.mcp.xml @@ -0,0 +1,12818 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<?codewarrior exportversion="1.0.1" ideversion="5.0" ?> + +<!DOCTYPE PROJECT [ +<!ELEMENT PROJECT (TARGETLIST, TARGETORDER, GROUPLIST, DESIGNLIST?)> +<!ELEMENT TARGETLIST (TARGET+)> +<!ELEMENT TARGET (NAME, SETTINGLIST, FILELIST?, LINKORDER?, SEGMENTLIST?, OVERLAYGROUPLIST?, SUBTARGETLIST?, SUBPROJECTLIST?, FRAMEWORKLIST?, PACKAGEACTIONSLIST?)> +<!ELEMENT NAME (#PCDATA)> +<!ELEMENT USERSOURCETREETYPE (#PCDATA)> +<!ELEMENT PATH (#PCDATA)> +<!ELEMENT FILELIST (FILE*)> +<!ELEMENT FILE (PATHTYPE, PATHROOT?, ACCESSPATH?, PATH, PATHFORMAT?, ROOTFILEREF?, FILEKIND?, FILEFLAGS?)> +<!ELEMENT PATHTYPE (#PCDATA)> +<!ELEMENT PATHROOT (#PCDATA)> +<!ELEMENT ACCESSPATH (#PCDATA)> +<!ELEMENT PATHFORMAT (#PCDATA)> +<!ELEMENT ROOTFILEREF (PATHTYPE, PATHROOT?, ACCESSPATH?, PATH, PATHFORMAT?)> +<!ELEMENT FILEKIND (#PCDATA)> +<!ELEMENT FILEFLAGS (#PCDATA)> +<!ELEMENT FILEREF (TARGETNAME?, PATHTYPE, PATHROOT?, ACCESSPATH?, PATH, PATHFORMAT?)> +<!ELEMENT TARGETNAME (#PCDATA)> +<!ELEMENT SETTINGLIST ((SETTING|PANELDATA)+)> +<!ELEMENT SETTING (NAME?, (VALUE|(SETTING+)))> +<!ELEMENT PANELDATA (NAME, VALUE)> +<!ELEMENT VALUE (#PCDATA)> +<!ELEMENT LINKORDER (FILEREF*)> +<!ELEMENT SEGMENTLIST (SEGMENT+)> +<!ELEMENT SEGMENT (NAME, ATTRIBUTES?, FILEREF*)> +<!ELEMENT ATTRIBUTES (#PCDATA)> +<!ELEMENT OVERLAYGROUPLIST (OVERLAYGROUP+)> +<!ELEMENT OVERLAYGROUP (NAME, BASEADDRESS, OVERLAY*)> +<!ELEMENT BASEADDRESS (#PCDATA)> +<!ELEMENT OVERLAY (NAME, FILEREF*)> +<!ELEMENT SUBTARGETLIST (SUBTARGET+)> +<!ELEMENT SUBTARGET (TARGETNAME, ATTRIBUTES?, FILEREF?)> +<!ELEMENT SUBPROJECTLIST (SUBPROJECT+)> +<!ELEMENT SUBPROJECT (FILEREF, SUBPROJECTTARGETLIST)> +<!ELEMENT SUBPROJECTTARGETLIST (SUBPROJECTTARGET*)> +<!ELEMENT SUBPROJECTTARGET (TARGETNAME, ATTRIBUTES?, FILEREF?)> +<!ELEMENT FRAMEWORKLIST (FRAMEWORK+)> +<!ELEMENT FRAMEWORK (FILEREF, DYNAMICLIBRARY?, VERSION?)> +<!ELEMENT PACKAGEACTIONSLIST (PACKAGEACTION+)> +<!ELEMENT PACKAGEACTION (#PCDATA)> +<!ELEMENT LIBRARYFILE (FILEREF)> +<!ELEMENT VERSION (#PCDATA)> +<!ELEMENT TARGETORDER (ORDEREDTARGET|ORDEREDDESIGN)*> +<!ELEMENT ORDEREDTARGET (NAME)> +<!ELEMENT ORDEREDDESIGN (NAME, ORDEREDTARGET+)> +<!ELEMENT GROUPLIST (GROUP|FILEREF)*> +<!ELEMENT GROUP (NAME, (GROUP|FILEREF)*)> +<!ELEMENT DESIGNLIST (DESIGN+)> +<!ELEMENT DESIGN (NAME, DESIGNDATA)> +<!ELEMENT DESIGNDATA (#PCDATA)> +]> + +<PROJECT> + <TARGETLIST> + <TARGET> + <NAME>AresDebug</NAME> + <SETTINGLIST> + + <!-- Settings for "Source Trees" panel --> + <SETTING><NAME>UserSourceTrees</NAME> + <SETTING> + <SETTING><NAME>Name</NAME><VALUE>SDKCurrent</VALUE></SETTING> + <SETTING><NAME>Kind</NAME><VALUE>AbsolutePath</VALUE></SETTING> + <SETTING><NAME>Path</NAME> + <SETTING><NAME>Path</NAME><VALUE>/Developer/SDKs/MacOSX10.2.8.sdk</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE></VALUE></SETTING> + </SETTING> + </SETTING> + </SETTING> + + <!-- Settings for "Access Paths" panel --> + <SETTING><NAME>AlwaysSearchUserPaths</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>InterpretDOSAndUnixPaths</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>RequireFrameworkStyleIncludes</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>SourceRelativeIncludes</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>UserSearchPaths</NAME> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>contrib/ares</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + </SETTING> + <SETTING><NAME>SystemSearchPaths</NAME> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>usr/include</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>SDKCurrent</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>MacOS X Support</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>CodeWarrior</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + </SETTING> + + <!-- Settings for "Debugger Runtime" panel --> + <SETTING><NAME>MWRuntimeSettings_WorkingDirectory</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWRuntimeSettings_CommandLine</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWRuntimeSettings_HostApplication</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWRuntimeSettings_EnvVars</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Target Settings" panel --> + <SETTING><NAME>Linker</NAME><VALUE>MacOS X PPC Linker</VALUE></SETTING> + <SETTING><NAME>PreLinker</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PostLinker</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Targetname</NAME><VALUE>AresDebug</VALUE></SETTING> + <SETTING><NAME>OutputDirectory</NAME> + <SETTING><NAME>Path</NAME><VALUE>Output</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>SaveEntriesUsingRelativePaths</NAME><VALUE>true</VALUE></SETTING> + + <!-- Settings for "File Mappings" panel --> + <SETTING><NAME>FileMappings</NAME> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>APPL</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>Appl</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MDYL</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MLIB</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MMLB</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MPLF</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MWCD</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>RSRC</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.arr</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.axp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.c</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.c++</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cpp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.exp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.h</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.h++</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.hpp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.lcf</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.m</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.mm</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pch</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pch++</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pchm</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pchmm</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.plc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Property List Compiler</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>Property List</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.ploc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Property List Compiler</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>Property List</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.r</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.wke</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>docu</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>rsrc</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.a</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.doc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.dylib</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.gif</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.icns</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.jpg</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.lib</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.nib</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.plist</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.ppob</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.rsrc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.strings</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.tiff</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + </SETTING> + + <!-- Settings for "Build Extras" panel --> + <SETTING><NAME>CacheModDates</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>DumpBrowserInfo</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>CacheSubprojects</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>UseThirdPartyDebugger</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>BrowserGenerator</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>DebuggerAppPath</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>DebuggerCmdLineArgs</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>DebuggerWorkingDir</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CodeCompletionPrefixFileName</NAME><VALUE>MacHeadersMach-O.c</VALUE></SETTING> + <SETTING><NAME>CodeCompletionMacroFileName</NAME><VALUE>MacOSX_MSL_C++_Macros.h</VALUE></SETTING> + + <!-- Settings for "Debugger Target" panel --> + <SETTING><NAME>ConsoleEncoding</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>LogSystemMessages</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>AutoTargetDLLsPopUp</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>StopAtWatchpoints</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PauseWhileRunning</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PauseInterval</NAME><VALUE>5</VALUE></SETTING> + <SETTING><NAME>PauseUIFlags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>AltExePath</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>StopAtTempBPOnLaunch</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>CacheSymbolics</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>TempBPFunctionName</NAME><VALUE>main</VALUE></SETTING> + <SETTING><NAME>TempBPType</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "Remote Debug" panel --> + <SETTING><NAME>Enabled</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ConnectionName</NAME><VALUE>Shiny</VALUE></SETTING> + <SETTING><NAME>DownloadPath</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>LaunchRemoteApp</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>RemoteAppPath</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>CoreID</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>JTAGClockSpeed</NAME><VALUE>8000</VALUE></SETTING> + <SETTING><NAME>IsMultiCore</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>OSDownload</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>UseGlobalOSDownload</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>OSDownloadConnectionName</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>OSDownloadPath</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>AltDownload</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>AltDownloadConnectionName</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Auto-target" panel --> + <SETTING><NAME>OtherExecutables</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Analyzer Connections" panel --> + <SETTING><NAME>AnalyzerConnectionName</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Custom Keywords" panel --> + <SETTING><NAME>CustomColor1</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CustomColor2</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CustomColor3</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CustomColor4</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + + <!-- Settings for "C/C++ Compiler" panel --> + <SETTING><NAME>MWFrontEnd_C_cplusplus</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_checkprotos</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_arm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_trigraphs</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_onlystdkeywords</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_enumsalwaysint</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_ansistrict</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_wchar_type</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_enableexceptions</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_dontreusestrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_poolstrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_dontinline</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_useRTTI</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_unsignedchars</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_autoinline</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_booltruefalse</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_inlinelevel</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_ecplusplus</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_defer_codegen</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_templateparser</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_c99</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_bottomupinline</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_gcc_extensions</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_instance_manager</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "C/C++ Preprocessor" panel --> + <SETTING><NAME>C_CPP_Preprocessor_EmitFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_EmitLine</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_EmitFullPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_KeepComments</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_PCHUsesPrefixText</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_EmitPragmas</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_KeepWhiteSpace</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_MultiByteEncoding</NAME><VALUE>encASCII_Unicode</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_PrefixText</NAME><VALUE>#include &lt;MacHeadersMach-O.h&gt; + +// set up TARGET_OS_MAC +#include &lt;TargetConditionals.h&gt;</VALUE></SETTING> + + <!-- Settings for "C/C++ Warnings" panel --> + <SETTING><NAME>MWWarning_C_warn_illpragma</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_emptydecl</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_possunwant</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_unusedvar</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_unusedarg</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_extracomma</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_pedantic</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warningerrors</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_hidevirtual</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_implicitconv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_notinlined</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_structclass</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_missingreturn</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_no_side_effect</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_resultnotused</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_padding</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_impl_i2f_conv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_impl_f2i_conv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_impl_s2u_conv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_illtokenpasting</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_filenamecaps</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_filenamecapssystem</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_undefmacro</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_ptrintconv</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "MacOS Merge Panel" panel --> + <SETTING><NAME>MWMerge_MacOS_projectType</NAME><VALUE>Application</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_outputName</NAME><VALUE>Merge Out</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_outputCreator</NAME><VALUE>????</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_outputType</NAME><VALUE>APPL</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_suppressWarning</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_copyFragments</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_copyResources</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_flattenResource</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_flatFileName</NAME><VALUE>a.rsrc</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_flatFileOutputPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWMerge_MacOS_skipResources</NAME> + <SETTING><VALUE>DLGX</VALUE></SETTING> + <SETTING><VALUE>ckid</VALUE></SETTING> + <SETTING><VALUE>Proj</VALUE></SETTING> + <SETTING><VALUE>WSPC</VALUE></SETTING> + </SETTING> + + <!-- Settings for "Output Flags" panel --> + <SETTING><NAME>FileLocked</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourcesMapIsReadOnly</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PrinterDriverIsMultiFinderCompatible</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Invisible</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasBundle</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>NameLocked</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Stationery</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasCustomIcon</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Shared</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasBeenInited</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Label</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Comments</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>HasCustomBadge</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasRoutingInfo</NAME><VALUE>true</VALUE></SETTING> + + <!-- Settings for "PPC CodeGen" panel --> + <SETTING><NAME>MWCodeGen_PPC_structalignment</NAME><VALUE>PPC_mw</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_tracebacktables</NAME><VALUE>Inline</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_processor</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_function_align</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_tocdata</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_largetoc</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_profiler</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_vectortocdata</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_poolconst</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_peephole</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_readonlystrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_linkerpoolsstrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_volatileasm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_schedule</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_altivec</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_altivec_move_block</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_strictIEEEfp</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_fpcontract</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_genfsel</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_orderedfpcmp</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC CodeGen Mach-O" panel --> + <SETTING><NAME>MWCodeGen_MachO_structalignment</NAME><VALUE>PPC_mw</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_profiler_enum</NAME><VALUE>Off</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_processor</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_function_align</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_common</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_boolisint</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_peephole</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_readonlystrings</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_linkerpoolsstrings</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_volatileasm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_schedule</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_altivec</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_vecmove</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_fp_ieee_strict</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_fpcontract</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_genfsel</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_fp_cmps_ordered</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC Disassembler" panel --> + <SETTING><NAME>MWDisassembler_PPC_showcode</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_extended</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_mix</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_nohex</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_showdata</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_showexceptions</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_showsym</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_shownames</NAME><VALUE>1</VALUE></SETTING> + + <!-- Settings for "PPC Global Optimizer" panel --> + <SETTING><NAME>GlobalOptimizer_PPC_optimizationlevel</NAME><VALUE>Level0</VALUE></SETTING> + <SETTING><NAME>GlobalOptimizer_PPC_optfor</NAME><VALUE>Speed</VALUE></SETTING> + + <!-- Settings for "PPC Linker" panel --> + <SETTING><NAME>MWLinker_PPC_linksym</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_symfullpath</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_linkmap</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_nolinkwarnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_dontdeadstripinitcode</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_permitmultdefs</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_linkmode</NAME><VALUE>Fast</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_code_folding</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_initname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_mainname</NAME><VALUE>__start</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_termname</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "PPC Mac OS X Linker" panel --> + <SETTING><NAME>MWLinker_MacOSX_linksym</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_symfullpath</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_nolinkwarnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_linkmap</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_dontdeadstripinitcode</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_permitmultdefs</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_use_objectivec_semantics</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_strip_debug_symbols</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_prebind_all_twolevel_modules</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_data_before_text_segment</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_report_msl_overloads</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_objects_follow_linkorder</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_linkmode</NAME><VALUE>Fast</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_exports</NAME><VALUE>ReferencedGlobals</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_sortcode</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_mainname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_initname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_code_folding</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_stabsgen</NAME><VALUE>None</VALUE></SETTING> + + <!-- Settings for "PPC Mac OS X Project" panel --> + <SETTING><NAME>MWProject_MacOSX_type</NAME><VALUE>Library</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_outfile</NAME><VALUE>aresdebug.lib</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_filecreator</NAME><VALUE>CWIE</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_filetype</NAME><VALUE>MLIB</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_vmaddress</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_usedefaultvmaddr</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flatrsrc</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flatrsrcfilename</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flatrsrcoutputdir</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWProject_MacOSX_installpath</NAME><VALUE>./</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_dont_prebind</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flat_namespace</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_frameworkversion</NAME><VALUE>A</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_currentversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flat_oldimpversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_AddrMode</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC PEF" panel --> + <SETTING><NAME>MWPEF_exports</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWPEF_libfolder</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_sortcode</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWPEF_expandbss</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_sharedata</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_olddefversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_oldimpversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_currentversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_fragmentname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWPEF_collapsereloads</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC Project" panel --> + <SETTING><NAME>MWProject_PPC_type</NAME><VALUE>Application</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_outfile</NAME><VALUE>Std C Console PPC</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_filecreator</NAME><VALUE>????</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_filetype</NAME><VALUE>APPL</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_size</NAME><VALUE>384</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_minsize</NAME><VALUE>384</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_stacksize</NAME><VALUE>64</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_flags</NAME><VALUE>22720</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_symfilename</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcheader</NAME><VALUE>Native</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrctype</NAME><VALUE>????</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcflags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcstore</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcmerge</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_flatrsrc</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_flatrsrcoutputdir</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWProject_PPC_flatrsrcfilename</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "PPCAsm Panel" panel --> + <SETTING><NAME>MWAssembler_PPC_auxheader</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_symmode</NAME><VALUE>Mac</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_dialect</NAME><VALUE>PPC</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_prefixfile</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_typecheck</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_warnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_casesensitive</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "Property List" panel --> + <SETTING><NAME>PList_OutputType</NAME><VALUE>File</VALUE></SETTING> + <SETTING><NAME>PList_OutputEncoding</NAME><VALUE>UTF-8</VALUE></SETTING> + <SETTING><NAME>PList_PListVersion</NAME><VALUE>1.0</VALUE></SETTING> + <SETTING><NAME>PList_Prefix</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PList_FileFilename</NAME><VALUE>Info.plist</VALUE></SETTING> + <SETTING><NAME>PList_FileDirectory</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>PList_ResourceType</NAME><VALUE>plst</VALUE></SETTING> + <SETTING><NAME>PList_ResourceID</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>PList_ResourceName</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Rez Compiler" panel --> + <SETTING><NAME>MWRez_Language_maxwidth</NAME><VALUE>80</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_script</NAME><VALUE>Roman</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_alignment</NAME><VALUE>Align1</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_filtermode</NAME><VALUE>FilterSkip</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_suppresswarnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_escapecontrolchars</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_prefixname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWRez_Language_filteredtypes</NAME><VALUE>'CODE' 'DATA' 'PICT'</VALUE></SETTING> + + <!-- Settings for "WinRC Compiler" panel --> + <SETTING><NAME>MWWinRC_prefixname</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "x86 CodeGen" panel --> + <SETTING><NAME>MWCodeGen_X86_processor</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_alignment</NAME><VALUE>bytes8</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_exceptions</NAME><VALUE>ZeroOverhead</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_name_mangling</NAME><VALUE>MWWin32</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_use_extinst</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_mmx</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_3dnow</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_use_mmx_3dnow_convention</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_cmov</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_sse</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_sse2</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_intrinsics</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_optimizeasm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_disableopts</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_profile</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_runtime</NAME><VALUE>Custom</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_readonlystrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_vectorize</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_relaxieee</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "x86 COFF" panel --> + <SETTING><NAME>MWLinker_X86_subsysmajorid</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_subsysminorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_opsysmajorid</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_opsysminorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_usrmajorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_usrminorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_maxstacksize</NAME><VALUE>1024</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_minstacksize</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_size</NAME><VALUE>1024</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_minsize</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_coff_flags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_dll_flags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_baseaddress</NAME><VALUE>4194304</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_filealign</NAME><VALUE>4096</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_sectionalign</NAME><VALUE>4096</VALUE></SETTING> + + <!-- Settings for "x86 Disassembler" panel --> + <SETTING><NAME>PDisasmX86_showHeaders</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSectHeaders</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSymTab</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showCode</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showData</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showDebug</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showExceptions</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showRaw</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showAllRaw</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSource</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showRelocation</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showHex</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showComments</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSymDefs</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_unmangle</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_verbose</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_resolveRelocs</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_resolveLocals</NAME><VALUE>false</VALUE></SETTING> + + <!-- Settings for "x86 Exceptions Panel" panel --> + <SETTING><NAME>MWDebugger_X86_Exceptions</NAME> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + </SETTING> + + <!-- Settings for "x86 Global Optimizer" panel --> + <SETTING><NAME>GlobalOptimizer_X86_optimizationlevel</NAME><VALUE>Level0</VALUE></SETTING> + <SETTING><NAME>GlobalOptimizer_X86_optfor</NAME><VALUE>Speed</VALUE></SETTING> + + <!-- Settings for "x86 Linker" panel --> + <SETTING><NAME>MWLinker_X86_entrypointusage</NAME><VALUE>Default</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_entrypoint</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_subsystem</NAME><VALUE>WinGUI</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_commandfile</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_generatemap</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linksym</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linkCV</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_symfullpath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linkdebug</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_checksum</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_zero_init_bss</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_mergedata</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_usedefaultlibs</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_adddefaultlibs</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_nowarnings</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_verbose</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linkformem</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_codefolding</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_debuginline</NAME><VALUE>false</VALUE></SETTING> + + <!-- Settings for "x86 Project" panel --> + <SETTING><NAME>MWProject_X86_type</NAME><VALUE>Application</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_outfile</NAME><VALUE>noname.exe</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_importlib</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_X86_setimportlibdir</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_dontgenerateimportlib</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_oldformatlib</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_replaceobjextension</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_copyallfiles</NAME><VALUE>false</VALUE></SETTING> + </SETTINGLIST> + <FILELIST> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__close_sockets.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__get_hostent.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__read_line.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_destroy.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_expand_name.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_fds.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_errmem.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_hostent.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_string.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_gethostbyaddr.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_gethostbyname.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_init.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_local.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_mkquery.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_parse_a_reply.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_parse_ptr_reply.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_process.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_query.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_search.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_send.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_strerror.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_timeout.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + </FILELIST> + <LINKORDER> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__close_sockets.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__get_hostent.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__read_line.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_destroy.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_expand_name.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_fds.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_errmem.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_hostent.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_string.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_gethostbyaddr.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_gethostbyname.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_init.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_local.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_mkquery.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_parse_a_reply.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_parse_ptr_reply.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_process.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_query.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_search.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_send.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_strerror.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_timeout.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + </LINKORDER> + </TARGET> + <TARGET> + <NAME>ResiprocateDebug</NAME> + <SETTINGLIST> + + <!-- Settings for "Source Trees" panel --> + <SETTING><NAME>UserSourceTrees</NAME> + <SETTING> + <SETTING><NAME>Name</NAME><VALUE>SDKCurrent</VALUE></SETTING> + <SETTING><NAME>Kind</NAME><VALUE>AbsolutePath</VALUE></SETTING> + <SETTING><NAME>Path</NAME> + <SETTING><NAME>Path</NAME><VALUE>/Developer/SDKs/MacOSX10.2.8.sdk</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE></VALUE></SETTING> + </SETTING> + </SETTING> + </SETTING> + + <!-- Settings for "Access Paths" panel --> + <SETTING><NAME>AlwaysSearchUserPaths</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>InterpretDOSAndUnixPaths</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>RequireFrameworkStyleIncludes</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>SourceRelativeIncludes</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>UserSearchPaths</NAME> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + </SETTING> + <SETTING><NAME>SystemSearchPaths</NAME> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>../../../Works/Library/OpenSSL/openssl-0.9.7g/inc32</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>usr/include</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>SDKCurrent</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>MSL/MSL_C++</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>CodeWarrior</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>MSL/MSL_C</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>CodeWarrior</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>MacOS X Support</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>CodeWarrior</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>System/Library/Frameworks</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>SDKCurrent</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + </SETTING> + + <!-- Settings for "Debugger Runtime" panel --> + <SETTING><NAME>MWRuntimeSettings_WorkingDirectory</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWRuntimeSettings_CommandLine</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWRuntimeSettings_HostApplication</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWRuntimeSettings_EnvVars</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Target Settings" panel --> + <SETTING><NAME>Linker</NAME><VALUE>MacOS X PPC Linker</VALUE></SETTING> + <SETTING><NAME>PreLinker</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PostLinker</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Targetname</NAME><VALUE>ResiprocateDebug</VALUE></SETTING> + <SETTING><NAME>OutputDirectory</NAME> + <SETTING><NAME>Path</NAME><VALUE>Output</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>SaveEntriesUsingRelativePaths</NAME><VALUE>true</VALUE></SETTING> + + <!-- Settings for "File Mappings" panel --> + <SETTING><NAME>FileMappings</NAME> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>APPL</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>Appl</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MDYL</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MLIB</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MMLB</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MPLF</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MWCD</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>RSRC</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.arr</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.axp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.c</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.c++</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cpp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cxx</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.exp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.h</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.h++</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.hpp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.hxx</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.lcf</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.m</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.mm</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pch</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pch++</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pchm</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pchmm</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.plc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Property List Compiler</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>Property List</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.ploc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Property List Compiler</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>Property List</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.r</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.wke</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>docu</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>rsrc</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.a</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.doc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.dylib</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.gif</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.icns</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.jpg</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.lib</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.nib</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.plist</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.ppob</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.rsrc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.strings</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.tiff</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + </SETTING> + + <!-- Settings for "Build Extras" panel --> + <SETTING><NAME>CacheModDates</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>DumpBrowserInfo</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>CacheSubprojects</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>UseThirdPartyDebugger</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>BrowserGenerator</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>DebuggerAppPath</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>DebuggerCmdLineArgs</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>DebuggerWorkingDir</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CodeCompletionPrefixFileName</NAME><VALUE>MacHeadersMach-O.c</VALUE></SETTING> + <SETTING><NAME>CodeCompletionMacroFileName</NAME><VALUE>MacOSX_MSL_C++_Macros.h</VALUE></SETTING> + + <!-- Settings for "Debugger Target" panel --> + <SETTING><NAME>ConsoleEncoding</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>LogSystemMessages</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>AutoTargetDLLsPopUp</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>StopAtWatchpoints</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PauseWhileRunning</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PauseInterval</NAME><VALUE>5</VALUE></SETTING> + <SETTING><NAME>PauseUIFlags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>AltExePath</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>StopAtTempBPOnLaunch</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>CacheSymbolics</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>TempBPFunctionName</NAME><VALUE>main</VALUE></SETTING> + <SETTING><NAME>TempBPType</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "Remote Debug" panel --> + <SETTING><NAME>Enabled</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ConnectionName</NAME><VALUE>Shiny</VALUE></SETTING> + <SETTING><NAME>DownloadPath</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>LaunchRemoteApp</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>RemoteAppPath</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>CoreID</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>JTAGClockSpeed</NAME><VALUE>8000</VALUE></SETTING> + <SETTING><NAME>IsMultiCore</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>OSDownload</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>UseGlobalOSDownload</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>OSDownloadConnectionName</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>OSDownloadPath</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>AltDownload</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>AltDownloadConnectionName</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Auto-target" panel --> + <SETTING><NAME>OtherExecutables</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Analyzer Connections" panel --> + <SETTING><NAME>AnalyzerConnectionName</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Custom Keywords" panel --> + <SETTING><NAME>CustomColor1</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CustomColor2</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CustomColor3</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CustomColor4</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + + <!-- Settings for "C/C++ Compiler" panel --> + <SETTING><NAME>MWFrontEnd_C_cplusplus</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_checkprotos</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_arm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_trigraphs</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_onlystdkeywords</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_enumsalwaysint</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_ansistrict</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_wchar_type</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_enableexceptions</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_dontreusestrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_poolstrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_dontinline</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_useRTTI</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_unsignedchars</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_autoinline</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_booltruefalse</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_inlinelevel</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_ecplusplus</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_defer_codegen</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_templateparser</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_c99</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_bottomupinline</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_gcc_extensions</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_instance_manager</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "C/C++ Preprocessor" panel --> + <SETTING><NAME>C_CPP_Preprocessor_EmitFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_EmitLine</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_EmitFullPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_KeepComments</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_PCHUsesPrefixText</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_EmitPragmas</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_KeepWhiteSpace</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_MultiByteEncoding</NAME><VALUE>encASCII_Unicode</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_PrefixText</NAME><VALUE>#include &lt;MacHeadersMach-O.h&gt; + +// set up TARGET_OS_MAC +#include &lt;TargetConditionals.h&gt; + +// voodoo magic +#define USE_ARES 1 +#define USE_IPV6 1 +#define USE_SSL 1 +#define VONAGE_FIX 1 + +// Darwin defines assert() to use printf, oddly enough +#include &lt;stdio.h&gt; + +// trying to get rid of tolower() link conflict +#include &lt;ctype.h&gt; +</VALUE></SETTING> + + <!-- Settings for "C/C++ Warnings" panel --> + <SETTING><NAME>MWWarning_C_warn_illpragma</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_emptydecl</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_possunwant</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_unusedvar</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_unusedarg</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_extracomma</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_pedantic</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warningerrors</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_hidevirtual</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_implicitconv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_notinlined</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_structclass</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_missingreturn</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_no_side_effect</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_resultnotused</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_padding</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_impl_i2f_conv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_impl_f2i_conv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_impl_s2u_conv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_illtokenpasting</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_filenamecaps</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_filenamecapssystem</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_undefmacro</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_ptrintconv</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "MacOS Merge Panel" panel --> + <SETTING><NAME>MWMerge_MacOS_projectType</NAME><VALUE>Application</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_outputName</NAME><VALUE>Merge Out</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_outputCreator</NAME><VALUE>????</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_outputType</NAME><VALUE>APPL</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_suppressWarning</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_copyFragments</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_copyResources</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_flattenResource</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_flatFileName</NAME><VALUE>a.rsrc</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_flatFileOutputPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWMerge_MacOS_skipResources</NAME> + <SETTING><VALUE>DLGX</VALUE></SETTING> + <SETTING><VALUE>ckid</VALUE></SETTING> + <SETTING><VALUE>Proj</VALUE></SETTING> + <SETTING><VALUE>WSPC</VALUE></SETTING> + </SETTING> + + <!-- Settings for "Output Flags" panel --> + <SETTING><NAME>FileLocked</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourcesMapIsReadOnly</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PrinterDriverIsMultiFinderCompatible</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Invisible</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasBundle</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>NameLocked</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Stationery</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasCustomIcon</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Shared</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasBeenInited</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Label</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Comments</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>HasCustomBadge</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasRoutingInfo</NAME><VALUE>false</VALUE></SETTING> + + <!-- Settings for "PPC CodeGen" panel --> + <SETTING><NAME>MWCodeGen_PPC_structalignment</NAME><VALUE>PPC_mw</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_tracebacktables</NAME><VALUE>Inline</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_processor</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_function_align</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_tocdata</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_largetoc</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_profiler</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_vectortocdata</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_poolconst</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_peephole</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_readonlystrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_linkerpoolsstrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_volatileasm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_schedule</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_altivec</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_altivec_move_block</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_strictIEEEfp</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_fpcontract</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_genfsel</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_orderedfpcmp</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC CodeGen Mach-O" panel --> + <SETTING><NAME>MWCodeGen_MachO_structalignment</NAME><VALUE>PPC_mw</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_profiler_enum</NAME><VALUE>Off</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_processor</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_function_align</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_common</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_boolisint</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_peephole</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_readonlystrings</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_linkerpoolsstrings</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_volatileasm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_schedule</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_altivec</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_vecmove</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_fp_ieee_strict</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_fpcontract</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_genfsel</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_fp_cmps_ordered</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC Disassembler" panel --> + <SETTING><NAME>MWDisassembler_PPC_showcode</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_extended</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_mix</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_nohex</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_showdata</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_showexceptions</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_showsym</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_shownames</NAME><VALUE>1</VALUE></SETTING> + + <!-- Settings for "PPC Global Optimizer" panel --> + <SETTING><NAME>GlobalOptimizer_PPC_optimizationlevel</NAME><VALUE>Level0</VALUE></SETTING> + <SETTING><NAME>GlobalOptimizer_PPC_optfor</NAME><VALUE>Speed</VALUE></SETTING> + + <!-- Settings for "PPC Linker" panel --> + <SETTING><NAME>MWLinker_PPC_linksym</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_symfullpath</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_linkmap</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_nolinkwarnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_dontdeadstripinitcode</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_permitmultdefs</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_linkmode</NAME><VALUE>Fast</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_code_folding</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_initname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_mainname</NAME><VALUE>__start</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_termname</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "PPC Mac OS X Linker" panel --> + <SETTING><NAME>MWLinker_MacOSX_linksym</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_symfullpath</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_nolinkwarnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_linkmap</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_dontdeadstripinitcode</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_permitmultdefs</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_use_objectivec_semantics</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_strip_debug_symbols</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_prebind_all_twolevel_modules</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_data_before_text_segment</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_report_msl_overloads</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_objects_follow_linkorder</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_linkmode</NAME><VALUE>Fast</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_exports</NAME><VALUE>ReferencedGlobals</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_sortcode</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_mainname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_initname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_code_folding</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_stabsgen</NAME><VALUE>None</VALUE></SETTING> + + <!-- Settings for "PPC Mac OS X Project" panel --> + <SETTING><NAME>MWProject_MacOSX_type</NAME><VALUE>Library</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_outfile</NAME><VALUE>resiprocatedebug.lib</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_filecreator</NAME><VALUE>CWIE</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_filetype</NAME><VALUE>MLIB</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_vmaddress</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_usedefaultvmaddr</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flatrsrc</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flatrsrcfilename</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flatrsrcoutputdir</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWProject_MacOSX_installpath</NAME><VALUE>./</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_dont_prebind</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flat_namespace</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_frameworkversion</NAME><VALUE>A</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_currentversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flat_oldimpversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_AddrMode</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC PEF" panel --> + <SETTING><NAME>MWPEF_exports</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWPEF_libfolder</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_sortcode</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWPEF_expandbss</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_sharedata</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_olddefversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_oldimpversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_currentversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_fragmentname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWPEF_collapsereloads</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC Project" panel --> + <SETTING><NAME>MWProject_PPC_type</NAME><VALUE>Application</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_outfile</NAME><VALUE>Std C Console PPC</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_filecreator</NAME><VALUE>????</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_filetype</NAME><VALUE>APPL</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_size</NAME><VALUE>384</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_minsize</NAME><VALUE>384</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_stacksize</NAME><VALUE>64</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_flags</NAME><VALUE>22720</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_symfilename</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcheader</NAME><VALUE>Native</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrctype</NAME><VALUE>????</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcflags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcstore</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcmerge</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_flatrsrc</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_flatrsrcoutputdir</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWProject_PPC_flatrsrcfilename</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "PPCAsm Panel" panel --> + <SETTING><NAME>MWAssembler_PPC_auxheader</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_symmode</NAME><VALUE>Mac</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_dialect</NAME><VALUE>PPC</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_prefixfile</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_typecheck</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_warnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_casesensitive</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "Property List" panel --> + <SETTING><NAME>PList_OutputType</NAME><VALUE>File</VALUE></SETTING> + <SETTING><NAME>PList_OutputEncoding</NAME><VALUE>UTF-8</VALUE></SETTING> + <SETTING><NAME>PList_PListVersion</NAME><VALUE>1.0</VALUE></SETTING> + <SETTING><NAME>PList_Prefix</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PList_FileFilename</NAME><VALUE>Info.plist</VALUE></SETTING> + <SETTING><NAME>PList_FileDirectory</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>PList_ResourceType</NAME><VALUE>plst</VALUE></SETTING> + <SETTING><NAME>PList_ResourceID</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>PList_ResourceName</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Rez Compiler" panel --> + <SETTING><NAME>MWRez_Language_maxwidth</NAME><VALUE>80</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_script</NAME><VALUE>Roman</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_alignment</NAME><VALUE>Align1</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_filtermode</NAME><VALUE>FilterSkip</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_suppresswarnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_escapecontrolchars</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_prefixname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWRez_Language_filteredtypes</NAME><VALUE>'CODE' 'DATA' 'PICT'</VALUE></SETTING> + + <!-- Settings for "WinRC Compiler" panel --> + <SETTING><NAME>MWWinRC_prefixname</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "x86 CodeGen" panel --> + <SETTING><NAME>MWCodeGen_X86_processor</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_alignment</NAME><VALUE>bytes8</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_exceptions</NAME><VALUE>ZeroOverhead</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_name_mangling</NAME><VALUE>MWWin32</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_use_extinst</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_mmx</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_3dnow</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_use_mmx_3dnow_convention</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_cmov</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_sse</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_sse2</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_intrinsics</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_optimizeasm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_disableopts</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_profile</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_runtime</NAME><VALUE>Custom</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_readonlystrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_vectorize</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_relaxieee</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "x86 COFF" panel --> + <SETTING><NAME>MWLinker_X86_subsysmajorid</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_subsysminorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_opsysmajorid</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_opsysminorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_usrmajorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_usrminorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_maxstacksize</NAME><VALUE>1024</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_minstacksize</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_size</NAME><VALUE>1024</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_minsize</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_coff_flags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_dll_flags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_baseaddress</NAME><VALUE>4194304</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_filealign</NAME><VALUE>4096</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_sectionalign</NAME><VALUE>4096</VALUE></SETTING> + + <!-- Settings for "x86 Disassembler" panel --> + <SETTING><NAME>PDisasmX86_showHeaders</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSectHeaders</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSymTab</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showCode</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showData</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showDebug</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showExceptions</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showRaw</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showAllRaw</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSource</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showRelocation</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showHex</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showComments</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSymDefs</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_unmangle</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_verbose</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_resolveRelocs</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_resolveLocals</NAME><VALUE>false</VALUE></SETTING> + + <!-- Settings for "x86 Exceptions Panel" panel --> + <SETTING><NAME>MWDebugger_X86_Exceptions</NAME> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + </SETTING> + + <!-- Settings for "x86 Global Optimizer" panel --> + <SETTING><NAME>GlobalOptimizer_X86_optimizationlevel</NAME><VALUE>Level0</VALUE></SETTING> + <SETTING><NAME>GlobalOptimizer_X86_optfor</NAME><VALUE>Speed</VALUE></SETTING> + + <!-- Settings for "x86 Linker" panel --> + <SETTING><NAME>MWLinker_X86_entrypointusage</NAME><VALUE>Default</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_entrypoint</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_subsystem</NAME><VALUE>WinGUI</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_commandfile</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_generatemap</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linksym</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linkCV</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_symfullpath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linkdebug</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_checksum</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_zero_init_bss</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_mergedata</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_usedefaultlibs</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_adddefaultlibs</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_nowarnings</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_verbose</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linkformem</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_codefolding</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_debuginline</NAME><VALUE>false</VALUE></SETTING> + + <!-- Settings for "x86 Project" panel --> + <SETTING><NAME>MWProject_X86_type</NAME><VALUE>Application</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_outfile</NAME><VALUE>noname.exe</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_importlib</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_X86_setimportlibdir</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_dontgenerateimportlib</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_oldformatlib</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_replaceobjextension</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_copyallfiles</NAME><VALUE>false</VALUE></SETTING> + </SETTINGLIST> + <FILELIST> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialog.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialogSet.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialogSetFactory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientAuthManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientInviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientOutOfDialogReq.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientPagerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientPublication.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientRegistration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DefaultServerReferHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DestroyUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Dialog.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogSet.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogSetId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogUsageManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DumProcessHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DumTimeout.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Handled.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/HandleException.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/HandleManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSessionCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSessionHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/MergedRequestKey.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/KeepAliveManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/KeepAliveTimeout.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/MasterProfile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/NetworkAssociation.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/NonDialogUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/OutOfDialogReqCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/PagerMessageCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Profile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/PublicationCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/RedirectManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/RegistrationCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerAuthManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerInviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerOutOfDialogReq.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerPagerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerPublication.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerRegistration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionState.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UInt64Hash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UserAuthInfo.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UserProfile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/AbstractFifo.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/BaseException.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Coders.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Condition.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/CountStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Data.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/DataStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/DnsUtil.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Lock.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Log.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Logger.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/MD5Stream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Mutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/ParseBuffer.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Random.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/RecursiveMutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/RWMutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Socket.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Subsystem.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SysLogBuf.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SysLogStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/ThreadIf.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Timer.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Tuple.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/vmd5.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ApiCheck.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/AresDns.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Auth.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/BranchParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CallId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Connection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ConnectionBase.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ConnectionManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Contents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CpimContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CSeqCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DataParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DateCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DnsInterface.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DnsResult.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Embedded.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExistsParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExpiresCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExternalBodyContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/FloatParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/GenericContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/GenericUri.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderFieldValue.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderFieldValueList.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Headers.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Helper.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/IntegerCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/IntegerParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/InternalTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/KeepAliveMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/LazyParser.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Message.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MessageWaitingContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MethodHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MethodTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Mime.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MsgHeaderScanner.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartAlternativeContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartMixedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartRelatedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartSignedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/NameAddr.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/OctetContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Parameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParameterHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParameterTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParserCategories.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParserCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParseUtil.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Pkcs7Contents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/PlainContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/QopParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/QuotedDataParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RAckCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Registration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RequestLine.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RportParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SdpContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Security.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SecurityAttributes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipFrag.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipStack.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StackThread.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatelessHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatisticsManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatisticsMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatusLine.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StringCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Symbols.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpBaseTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpConnection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TimerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TimerQueue.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Token.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionController.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionMap.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionState.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionUser.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionUserMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Transport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransportMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransportSelector.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TuSelector.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/UdpTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/UnknownParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Uri.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Via.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/WarningCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MacSecurity.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExternalDnsFactory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/FileSystem.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MessageFilterRule.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TlsTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TlsConnection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SHA1Stream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/external/HttpGetMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/external/HttpProvider.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsAAAARecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsCnameRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsHostRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsNaptrRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsSrvRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsStub.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/QueryTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRCache.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRList.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RROverlay.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRVip.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS>Debug</FILEFLAGS> + </FILE> + </FILELIST> + <LINKORDER> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialog.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialogSet.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialogSetFactory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientAuthManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientInviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientOutOfDialogReq.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientPagerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientPublication.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientRegistration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DefaultServerReferHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DestroyUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Dialog.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogSet.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogSetId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogUsageManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DumProcessHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DumTimeout.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Handled.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/HandleException.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/HandleManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSessionCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSessionHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/MergedRequestKey.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/KeepAliveManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/KeepAliveTimeout.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/MasterProfile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/NetworkAssociation.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/NonDialogUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/OutOfDialogReqCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/PagerMessageCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Profile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/PublicationCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/RedirectManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/RegistrationCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerAuthManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerInviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerOutOfDialogReq.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerPagerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerPublication.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerRegistration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionState.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UInt64Hash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UserAuthInfo.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UserProfile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/AbstractFifo.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/BaseException.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Coders.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Condition.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/CountStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Data.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/DataStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/DnsUtil.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Lock.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Log.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Logger.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/MD5Stream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Mutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/ParseBuffer.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Random.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/RecursiveMutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/RWMutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Socket.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Subsystem.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SysLogBuf.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SysLogStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/ThreadIf.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Timer.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Tuple.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/vmd5.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ApiCheck.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/AresDns.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Auth.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/BranchParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CallId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Connection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ConnectionBase.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ConnectionManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Contents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CpimContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CSeqCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DataParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DateCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DnsInterface.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DnsResult.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Embedded.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExistsParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExpiresCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExternalBodyContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/FloatParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/GenericContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/GenericUri.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderFieldValue.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderFieldValueList.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Headers.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Helper.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/IntegerCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/IntegerParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/InternalTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/KeepAliveMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/LazyParser.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Message.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MessageWaitingContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MethodHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MethodTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Mime.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MsgHeaderScanner.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartAlternativeContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartMixedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartRelatedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartSignedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/NameAddr.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/OctetContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Parameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParameterHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParameterTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParserCategories.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParserCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParseUtil.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Pkcs7Contents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/PlainContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/QopParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/QuotedDataParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RAckCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Registration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RequestLine.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RportParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SdpContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Security.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SecurityAttributes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipFrag.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipStack.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StackThread.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatelessHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatisticsManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatisticsMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatusLine.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StringCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Symbols.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpBaseTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpConnection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TimerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TimerQueue.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Token.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionController.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionMap.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionState.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionUser.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionUserMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Transport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransportMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransportSelector.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TuSelector.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/UdpTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/UnknownParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Uri.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Via.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/WarningCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MacSecurity.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExternalDnsFactory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/FileSystem.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MessageFilterRule.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TlsTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TlsConnection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SHA1Stream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/external/HttpGetMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/external/HttpProvider.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsAAAARecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsCnameRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsHostRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsNaptrRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsSrvRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsStub.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/QueryTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRCache.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRList.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RROverlay.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRVip.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + </LINKORDER> + </TARGET> + <TARGET> + <NAME>AresRelease</NAME> + <SETTINGLIST> + + <!-- Settings for "Source Trees" panel --> + <SETTING><NAME>UserSourceTrees</NAME> + <SETTING> + <SETTING><NAME>Name</NAME><VALUE>SDKCurrent</VALUE></SETTING> + <SETTING><NAME>Kind</NAME><VALUE>AbsolutePath</VALUE></SETTING> + <SETTING><NAME>Path</NAME> + <SETTING><NAME>Path</NAME><VALUE>/Developer/SDKs/MacOSX10.2.8.sdk</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE></VALUE></SETTING> + </SETTING> + </SETTING> + </SETTING> + + <!-- Settings for "Access Paths" panel --> + <SETTING><NAME>AlwaysSearchUserPaths</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>InterpretDOSAndUnixPaths</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>RequireFrameworkStyleIncludes</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>SourceRelativeIncludes</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>UserSearchPaths</NAME> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>contrib/ares</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + </SETTING> + <SETTING><NAME>SystemSearchPaths</NAME> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>usr/include</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>SDKCurrent</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>MacOS X Support</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>CodeWarrior</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + </SETTING> + + <!-- Settings for "Debugger Runtime" panel --> + <SETTING><NAME>MWRuntimeSettings_WorkingDirectory</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWRuntimeSettings_CommandLine</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWRuntimeSettings_HostApplication</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWRuntimeSettings_EnvVars</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Target Settings" panel --> + <SETTING><NAME>Linker</NAME><VALUE>MacOS X PPC Linker</VALUE></SETTING> + <SETTING><NAME>PreLinker</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PostLinker</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Targetname</NAME><VALUE>AresRelease</VALUE></SETTING> + <SETTING><NAME>OutputDirectory</NAME> + <SETTING><NAME>Path</NAME><VALUE>Output</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>SaveEntriesUsingRelativePaths</NAME><VALUE>true</VALUE></SETTING> + + <!-- Settings for "File Mappings" panel --> + <SETTING><NAME>FileMappings</NAME> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>APPL</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>Appl</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MDYL</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MLIB</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MMLB</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MPLF</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MWCD</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>RSRC</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.arr</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.axp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.c</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.c++</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cpp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.exp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.h</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.h++</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.hpp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.lcf</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.m</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.mm</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pch</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pch++</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pchm</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pchmm</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.plc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Property List Compiler</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>Property List</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.ploc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Property List Compiler</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>Property List</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.r</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.wke</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>docu</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>rsrc</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.a</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.doc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.dylib</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.gif</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.icns</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.jpg</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.lib</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.nib</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.plist</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.ppob</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.rsrc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.strings</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.tiff</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + </SETTING> + + <!-- Settings for "Build Extras" panel --> + <SETTING><NAME>CacheModDates</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>DumpBrowserInfo</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>CacheSubprojects</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>UseThirdPartyDebugger</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>BrowserGenerator</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>DebuggerAppPath</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>DebuggerCmdLineArgs</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>DebuggerWorkingDir</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CodeCompletionPrefixFileName</NAME><VALUE>MacHeadersMach-O.c</VALUE></SETTING> + <SETTING><NAME>CodeCompletionMacroFileName</NAME><VALUE>MacOSX_MSL_C++_Macros.h</VALUE></SETTING> + + <!-- Settings for "Debugger Target" panel --> + <SETTING><NAME>ConsoleEncoding</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>LogSystemMessages</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>AutoTargetDLLsPopUp</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>StopAtWatchpoints</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PauseWhileRunning</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PauseInterval</NAME><VALUE>5</VALUE></SETTING> + <SETTING><NAME>PauseUIFlags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>AltExePath</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>StopAtTempBPOnLaunch</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>CacheSymbolics</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>TempBPFunctionName</NAME><VALUE>main</VALUE></SETTING> + <SETTING><NAME>TempBPType</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "Remote Debug" panel --> + <SETTING><NAME>Enabled</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ConnectionName</NAME><VALUE>Shiny</VALUE></SETTING> + <SETTING><NAME>DownloadPath</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>LaunchRemoteApp</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>RemoteAppPath</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>CoreID</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>JTAGClockSpeed</NAME><VALUE>8000</VALUE></SETTING> + <SETTING><NAME>IsMultiCore</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>OSDownload</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>UseGlobalOSDownload</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>OSDownloadConnectionName</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>OSDownloadPath</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>AltDownload</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>AltDownloadConnectionName</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Auto-target" panel --> + <SETTING><NAME>OtherExecutables</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Analyzer Connections" panel --> + <SETTING><NAME>AnalyzerConnectionName</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Custom Keywords" panel --> + <SETTING><NAME>CustomColor1</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CustomColor2</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CustomColor3</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CustomColor4</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + + <!-- Settings for "C/C++ Compiler" panel --> + <SETTING><NAME>MWFrontEnd_C_cplusplus</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_checkprotos</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_arm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_trigraphs</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_onlystdkeywords</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_enumsalwaysint</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_ansistrict</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_wchar_type</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_enableexceptions</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_dontreusestrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_poolstrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_dontinline</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_useRTTI</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_unsignedchars</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_autoinline</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_booltruefalse</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_inlinelevel</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_ecplusplus</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_defer_codegen</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_templateparser</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_c99</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_bottomupinline</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_gcc_extensions</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_instance_manager</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "C/C++ Preprocessor" panel --> + <SETTING><NAME>C_CPP_Preprocessor_EmitFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_EmitLine</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_EmitFullPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_KeepComments</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_PCHUsesPrefixText</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_EmitPragmas</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_KeepWhiteSpace</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_MultiByteEncoding</NAME><VALUE>encASCII_Unicode</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_PrefixText</NAME><VALUE>#include &lt;MacHeadersMach-O.h&gt; + +// set up TARGET_OS_MAC +#include &lt;TargetConditionals.h&gt;</VALUE></SETTING> + + <!-- Settings for "C/C++ Warnings" panel --> + <SETTING><NAME>MWWarning_C_warn_illpragma</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_emptydecl</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_possunwant</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_unusedvar</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_unusedarg</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_extracomma</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_pedantic</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warningerrors</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_hidevirtual</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_implicitconv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_notinlined</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_structclass</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_missingreturn</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_no_side_effect</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_resultnotused</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_padding</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_impl_i2f_conv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_impl_f2i_conv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_impl_s2u_conv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_illtokenpasting</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_filenamecaps</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_filenamecapssystem</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_undefmacro</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_ptrintconv</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "MacOS Merge Panel" panel --> + <SETTING><NAME>MWMerge_MacOS_projectType</NAME><VALUE>Application</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_outputName</NAME><VALUE>Merge Out</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_outputCreator</NAME><VALUE>????</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_outputType</NAME><VALUE>APPL</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_suppressWarning</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_copyFragments</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_copyResources</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_flattenResource</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_flatFileName</NAME><VALUE>a.rsrc</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_flatFileOutputPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWMerge_MacOS_skipResources</NAME> + <SETTING><VALUE>DLGX</VALUE></SETTING> + <SETTING><VALUE>ckid</VALUE></SETTING> + <SETTING><VALUE>Proj</VALUE></SETTING> + <SETTING><VALUE>WSPC</VALUE></SETTING> + </SETTING> + + <!-- Settings for "Output Flags" panel --> + <SETTING><NAME>FileLocked</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourcesMapIsReadOnly</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PrinterDriverIsMultiFinderCompatible</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Invisible</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasBundle</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>NameLocked</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Stationery</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasCustomIcon</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Shared</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasBeenInited</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Label</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Comments</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>HasCustomBadge</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasRoutingInfo</NAME><VALUE>true</VALUE></SETTING> + + <!-- Settings for "PPC CodeGen" panel --> + <SETTING><NAME>MWCodeGen_PPC_structalignment</NAME><VALUE>PPC_mw</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_tracebacktables</NAME><VALUE>Inline</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_processor</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_function_align</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_tocdata</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_largetoc</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_profiler</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_vectortocdata</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_poolconst</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_peephole</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_readonlystrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_linkerpoolsstrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_volatileasm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_schedule</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_altivec</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_altivec_move_block</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_strictIEEEfp</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_fpcontract</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_genfsel</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_orderedfpcmp</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC CodeGen Mach-O" panel --> + <SETTING><NAME>MWCodeGen_MachO_structalignment</NAME><VALUE>PPC_mw</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_profiler_enum</NAME><VALUE>Off</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_processor</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_function_align</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_common</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_boolisint</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_peephole</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_readonlystrings</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_linkerpoolsstrings</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_volatileasm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_schedule</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_altivec</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_vecmove</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_fp_ieee_strict</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_fpcontract</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_genfsel</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_fp_cmps_ordered</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC Disassembler" panel --> + <SETTING><NAME>MWDisassembler_PPC_showcode</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_extended</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_mix</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_nohex</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_showdata</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_showexceptions</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_showsym</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_shownames</NAME><VALUE>1</VALUE></SETTING> + + <!-- Settings for "PPC Global Optimizer" panel --> + <SETTING><NAME>GlobalOptimizer_PPC_optimizationlevel</NAME><VALUE>Level4</VALUE></SETTING> + <SETTING><NAME>GlobalOptimizer_PPC_optfor</NAME><VALUE>Speed</VALUE></SETTING> + + <!-- Settings for "PPC Linker" panel --> + <SETTING><NAME>MWLinker_PPC_linksym</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_symfullpath</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_linkmap</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_nolinkwarnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_dontdeadstripinitcode</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_permitmultdefs</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_linkmode</NAME><VALUE>Fast</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_code_folding</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_initname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_mainname</NAME><VALUE>__start</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_termname</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "PPC Mac OS X Linker" panel --> + <SETTING><NAME>MWLinker_MacOSX_linksym</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_symfullpath</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_nolinkwarnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_linkmap</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_dontdeadstripinitcode</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_permitmultdefs</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_use_objectivec_semantics</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_strip_debug_symbols</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_prebind_all_twolevel_modules</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_data_before_text_segment</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_report_msl_overloads</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_objects_follow_linkorder</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_linkmode</NAME><VALUE>Fast</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_exports</NAME><VALUE>ReferencedGlobals</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_sortcode</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_mainname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_initname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_code_folding</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_stabsgen</NAME><VALUE>None</VALUE></SETTING> + + <!-- Settings for "PPC Mac OS X Project" panel --> + <SETTING><NAME>MWProject_MacOSX_type</NAME><VALUE>Library</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_outfile</NAME><VALUE>ares.lib</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_filecreator</NAME><VALUE>CWIE</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_filetype</NAME><VALUE>MLIB</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_vmaddress</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_usedefaultvmaddr</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flatrsrc</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flatrsrcfilename</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flatrsrcoutputdir</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWProject_MacOSX_installpath</NAME><VALUE>./</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_dont_prebind</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flat_namespace</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_frameworkversion</NAME><VALUE>A</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_currentversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flat_oldimpversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_AddrMode</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC PEF" panel --> + <SETTING><NAME>MWPEF_exports</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWPEF_libfolder</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_sortcode</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWPEF_expandbss</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_sharedata</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_olddefversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_oldimpversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_currentversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_fragmentname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWPEF_collapsereloads</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC Project" panel --> + <SETTING><NAME>MWProject_PPC_type</NAME><VALUE>Application</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_outfile</NAME><VALUE>Std C Console PPC</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_filecreator</NAME><VALUE>????</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_filetype</NAME><VALUE>APPL</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_size</NAME><VALUE>384</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_minsize</NAME><VALUE>384</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_stacksize</NAME><VALUE>64</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_flags</NAME><VALUE>22720</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_symfilename</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcheader</NAME><VALUE>Native</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrctype</NAME><VALUE>????</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcflags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcstore</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcmerge</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_flatrsrc</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_flatrsrcoutputdir</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWProject_PPC_flatrsrcfilename</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "PPCAsm Panel" panel --> + <SETTING><NAME>MWAssembler_PPC_auxheader</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_symmode</NAME><VALUE>Mac</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_dialect</NAME><VALUE>PPC</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_prefixfile</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_typecheck</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_warnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_casesensitive</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "Property List" panel --> + <SETTING><NAME>PList_OutputType</NAME><VALUE>File</VALUE></SETTING> + <SETTING><NAME>PList_OutputEncoding</NAME><VALUE>UTF-8</VALUE></SETTING> + <SETTING><NAME>PList_PListVersion</NAME><VALUE>1.0</VALUE></SETTING> + <SETTING><NAME>PList_Prefix</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PList_FileFilename</NAME><VALUE>Info.plist</VALUE></SETTING> + <SETTING><NAME>PList_FileDirectory</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>PList_ResourceType</NAME><VALUE>plst</VALUE></SETTING> + <SETTING><NAME>PList_ResourceID</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>PList_ResourceName</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Rez Compiler" panel --> + <SETTING><NAME>MWRez_Language_maxwidth</NAME><VALUE>80</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_script</NAME><VALUE>Roman</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_alignment</NAME><VALUE>Align1</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_filtermode</NAME><VALUE>FilterSkip</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_suppresswarnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_escapecontrolchars</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_prefixname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWRez_Language_filteredtypes</NAME><VALUE>'CODE' 'DATA' 'PICT'</VALUE></SETTING> + + <!-- Settings for "WinRC Compiler" panel --> + <SETTING><NAME>MWWinRC_prefixname</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "x86 CodeGen" panel --> + <SETTING><NAME>MWCodeGen_X86_processor</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_alignment</NAME><VALUE>bytes8</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_exceptions</NAME><VALUE>ZeroOverhead</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_name_mangling</NAME><VALUE>MWWin32</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_use_extinst</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_mmx</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_3dnow</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_use_mmx_3dnow_convention</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_cmov</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_sse</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_sse2</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_intrinsics</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_optimizeasm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_disableopts</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_profile</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_runtime</NAME><VALUE>Custom</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_readonlystrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_vectorize</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_relaxieee</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "x86 COFF" panel --> + <SETTING><NAME>MWLinker_X86_subsysmajorid</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_subsysminorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_opsysmajorid</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_opsysminorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_usrmajorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_usrminorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_maxstacksize</NAME><VALUE>1024</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_minstacksize</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_size</NAME><VALUE>1024</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_minsize</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_coff_flags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_dll_flags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_baseaddress</NAME><VALUE>4194304</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_filealign</NAME><VALUE>4096</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_sectionalign</NAME><VALUE>4096</VALUE></SETTING> + + <!-- Settings for "x86 Disassembler" panel --> + <SETTING><NAME>PDisasmX86_showHeaders</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSectHeaders</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSymTab</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showCode</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showData</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showDebug</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showExceptions</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showRaw</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showAllRaw</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSource</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showRelocation</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showHex</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showComments</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSymDefs</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_unmangle</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_verbose</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_resolveRelocs</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_resolveLocals</NAME><VALUE>false</VALUE></SETTING> + + <!-- Settings for "x86 Exceptions Panel" panel --> + <SETTING><NAME>MWDebugger_X86_Exceptions</NAME> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + </SETTING> + + <!-- Settings for "x86 Global Optimizer" panel --> + <SETTING><NAME>GlobalOptimizer_X86_optimizationlevel</NAME><VALUE>Level0</VALUE></SETTING> + <SETTING><NAME>GlobalOptimizer_X86_optfor</NAME><VALUE>Speed</VALUE></SETTING> + + <!-- Settings for "x86 Linker" panel --> + <SETTING><NAME>MWLinker_X86_entrypointusage</NAME><VALUE>Default</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_entrypoint</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_subsystem</NAME><VALUE>WinGUI</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_commandfile</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_generatemap</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linksym</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linkCV</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_symfullpath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linkdebug</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_checksum</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_zero_init_bss</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_mergedata</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_usedefaultlibs</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_adddefaultlibs</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_nowarnings</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_verbose</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linkformem</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_codefolding</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_debuginline</NAME><VALUE>false</VALUE></SETTING> + + <!-- Settings for "x86 Project" panel --> + <SETTING><NAME>MWProject_X86_type</NAME><VALUE>Application</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_outfile</NAME><VALUE>noname.exe</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_importlib</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_X86_setimportlibdir</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_dontgenerateimportlib</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_oldformatlib</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_replaceobjextension</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_copyallfiles</NAME><VALUE>false</VALUE></SETTING> + </SETTINGLIST> + <FILELIST> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__close_sockets.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__get_hostent.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__read_line.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_destroy.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_expand_name.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_fds.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_errmem.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_hostent.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_string.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_gethostbyaddr.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_gethostbyname.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_init.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_local.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_mkquery.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_parse_a_reply.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_parse_ptr_reply.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_process.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_query.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_search.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_send.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_strerror.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_timeout.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + </FILELIST> + <LINKORDER> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__close_sockets.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__get_hostent.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__read_line.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_destroy.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_expand_name.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_fds.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_errmem.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_hostent.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_string.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_gethostbyaddr.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_gethostbyname.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_init.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_local.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_mkquery.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_parse_a_reply.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_parse_ptr_reply.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_process.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_query.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_search.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_send.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_strerror.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_timeout.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + </LINKORDER> + </TARGET> + <TARGET> + <NAME>ResiprocateRelease</NAME> + <SETTINGLIST> + + <!-- Settings for "Source Trees" panel --> + <SETTING><NAME>UserSourceTrees</NAME> + <SETTING> + <SETTING><NAME>Name</NAME><VALUE>SDKCurrent</VALUE></SETTING> + <SETTING><NAME>Kind</NAME><VALUE>AbsolutePath</VALUE></SETTING> + <SETTING><NAME>Path</NAME> + <SETTING><NAME>Path</NAME><VALUE>/Developer/SDKs/MacOSX10.2.8.sdk</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE></VALUE></SETTING> + </SETTING> + </SETTING> + </SETTING> + + <!-- Settings for "Access Paths" panel --> + <SETTING><NAME>AlwaysSearchUserPaths</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>InterpretDOSAndUnixPaths</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>RequireFrameworkStyleIncludes</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>SourceRelativeIncludes</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>UserSearchPaths</NAME> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + </SETTING> + <SETTING><NAME>SystemSearchPaths</NAME> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>../../../Works/Library/OpenSSL/openssl-0.9.7g/inc32</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>usr/include</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>SDKCurrent</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>MSL/MSL_C++</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>CodeWarrior</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>MSL/MSL_C</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>CodeWarrior</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>MacOS X Support</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>CodeWarrior</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>SearchPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>System/Library/Frameworks</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>SDKCurrent</VALUE></SETTING> + </SETTING> + <SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>FrameworkPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING> + </SETTING> + </SETTING> + + <!-- Settings for "Debugger Runtime" panel --> + <SETTING><NAME>MWRuntimeSettings_WorkingDirectory</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWRuntimeSettings_CommandLine</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWRuntimeSettings_HostApplication</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWRuntimeSettings_EnvVars</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Target Settings" panel --> + <SETTING><NAME>Linker</NAME><VALUE>MacOS X PPC Linker</VALUE></SETTING> + <SETTING><NAME>PreLinker</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PostLinker</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Targetname</NAME><VALUE>ResiprocateRelease</VALUE></SETTING> + <SETTING><NAME>OutputDirectory</NAME> + <SETTING><NAME>Path</NAME><VALUE>Output</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>SaveEntriesUsingRelativePaths</NAME><VALUE>true</VALUE></SETTING> + + <!-- Settings for "File Mappings" panel --> + <SETTING><NAME>FileMappings</NAME> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>APPL</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>Appl</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MDYL</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MLIB</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MMLB</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MPLF</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>MWCD</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>RSRC</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.arr</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.axp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.c</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.c++</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cpp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.cxx</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.exp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.h</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.h++</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.hpp</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.hxx</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.lcf</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.m</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.mm</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pch</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pch++</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pchm</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.pchmm</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MW C/C++ PPC Mac OS X</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.plc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Property List Compiler</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>Property List</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.ploc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Property List Compiler</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>Property List</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.r</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>TEXT</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.wke</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>docu</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileType</NAME><VALUE>rsrc</VALUE></SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.a</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.doc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.dylib</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.gif</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.icns</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.jpg</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.lib</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>MachO Importer</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE>C/C++</VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.nib</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.plist</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.ppob</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.rsrc</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Rez</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>false</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.strings</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + <SETTING> + <SETTING><NAME>FileExtension</NAME><VALUE>.tiff</VALUE></SETTING> + <SETTING><NAME>Compiler</NAME><VALUE>Copy To Package</VALUE></SETTING> + <SETTING><NAME>EditLanguage</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>Precompile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Launchable</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>ResourceFile</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>IgnoredByMake</NAME><VALUE>true</VALUE></SETTING> + </SETTING> + </SETTING> + + <!-- Settings for "Build Extras" panel --> + <SETTING><NAME>CacheModDates</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>DumpBrowserInfo</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>CacheSubprojects</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>UseThirdPartyDebugger</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>BrowserGenerator</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>DebuggerAppPath</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>DebuggerCmdLineArgs</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>DebuggerWorkingDir</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CodeCompletionPrefixFileName</NAME><VALUE>MacHeadersMach-O.c</VALUE></SETTING> + <SETTING><NAME>CodeCompletionMacroFileName</NAME><VALUE>MacOSX_MSL_C++_Macros.h</VALUE></SETTING> + + <!-- Settings for "Debugger Target" panel --> + <SETTING><NAME>ConsoleEncoding</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>LogSystemMessages</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>AutoTargetDLLsPopUp</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>StopAtWatchpoints</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PauseWhileRunning</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PauseInterval</NAME><VALUE>5</VALUE></SETTING> + <SETTING><NAME>PauseUIFlags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>AltExePath</NAME> + <SETTING><NAME>Path</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>Unix</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Absolute</VALUE></SETTING> + </SETTING> + <SETTING><NAME>StopAtTempBPOnLaunch</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>CacheSymbolics</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>TempBPFunctionName</NAME><VALUE>main</VALUE></SETTING> + <SETTING><NAME>TempBPType</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "Remote Debug" panel --> + <SETTING><NAME>Enabled</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ConnectionName</NAME><VALUE>Shiny</VALUE></SETTING> + <SETTING><NAME>DownloadPath</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>LaunchRemoteApp</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>RemoteAppPath</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>CoreID</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>JTAGClockSpeed</NAME><VALUE>8000</VALUE></SETTING> + <SETTING><NAME>IsMultiCore</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>OSDownload</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>UseGlobalOSDownload</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>OSDownloadConnectionName</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>OSDownloadPath</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>AltDownload</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>AltDownloadConnectionName</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Auto-target" panel --> + <SETTING><NAME>OtherExecutables</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Analyzer Connections" panel --> + <SETTING><NAME>AnalyzerConnectionName</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Custom Keywords" panel --> + <SETTING><NAME>CustomColor1</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CustomColor2</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CustomColor3</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + <SETTING><NAME>CustomColor4</NAME> + <SETTING><NAME>Red</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Green</NAME><VALUE>32767</VALUE></SETTING> + <SETTING><NAME>Blue</NAME><VALUE>0</VALUE></SETTING> + </SETTING> + + <!-- Settings for "C/C++ Compiler" panel --> + <SETTING><NAME>MWFrontEnd_C_cplusplus</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_checkprotos</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_arm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_trigraphs</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_onlystdkeywords</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_enumsalwaysint</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_ansistrict</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_wchar_type</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_enableexceptions</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_dontreusestrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_poolstrings</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_dontinline</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_useRTTI</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_unsignedchars</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_autoinline</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_booltruefalse</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_inlinelevel</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_ecplusplus</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_defer_codegen</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_templateparser</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_c99</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_bottomupinline</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_gcc_extensions</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWFrontEnd_C_instance_manager</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "C/C++ Preprocessor" panel --> + <SETTING><NAME>C_CPP_Preprocessor_EmitFile</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_EmitLine</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_EmitFullPath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_KeepComments</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_PCHUsesPrefixText</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_EmitPragmas</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_KeepWhiteSpace</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_MultiByteEncoding</NAME><VALUE>encASCII_Unicode</VALUE></SETTING> + <SETTING><NAME>C_CPP_Preprocessor_PrefixText</NAME><VALUE>#include &lt;MacHeadersMach-O.h&gt; + +// set up TARGET_OS_MAC +#include &lt;TargetConditionals.h&gt; + +// voodoo magic +#define USE_ARES 1 +#define USE_IPV6 1 +#define USE_SSL 1 +#define VONAGE_FIX 1 + +// Darwin defines assert() to use printf, oddly enough +#include &lt;stdio.h&gt; + +// trying to get rid of tolower() link conflict +#include &lt;ctype.h&gt; +</VALUE></SETTING> + + <!-- Settings for "C/C++ Warnings" panel --> + <SETTING><NAME>MWWarning_C_warn_illpragma</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_emptydecl</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_possunwant</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_unusedvar</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_unusedarg</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_extracomma</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_pedantic</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warningerrors</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_hidevirtual</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_implicitconv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_notinlined</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_structclass</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_missingreturn</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_no_side_effect</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_resultnotused</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_padding</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_impl_i2f_conv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_impl_f2i_conv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_impl_s2u_conv</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_illtokenpasting</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_filenamecaps</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_filenamecapssystem</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_undefmacro</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWWarning_C_warn_ptrintconv</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "MacOS Merge Panel" panel --> + <SETTING><NAME>MWMerge_MacOS_projectType</NAME><VALUE>Application</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_outputName</NAME><VALUE>Merge Out</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_outputCreator</NAME><VALUE>????</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_outputType</NAME><VALUE>APPL</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_suppressWarning</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_copyFragments</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_copyResources</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_flattenResource</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_flatFileName</NAME><VALUE>a.rsrc</VALUE></SETTING> + <SETTING><NAME>MWMerge_MacOS_flatFileOutputPath</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWMerge_MacOS_skipResources</NAME> + <SETTING><VALUE>DLGX</VALUE></SETTING> + <SETTING><VALUE>ckid</VALUE></SETTING> + <SETTING><VALUE>Proj</VALUE></SETTING> + <SETTING><VALUE>WSPC</VALUE></SETTING> + </SETTING> + + <!-- Settings for "Output Flags" panel --> + <SETTING><NAME>FileLocked</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>ResourcesMapIsReadOnly</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PrinterDriverIsMultiFinderCompatible</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Invisible</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasBundle</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>NameLocked</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Stationery</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasCustomIcon</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Shared</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasBeenInited</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>Label</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>Comments</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>HasCustomBadge</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>HasRoutingInfo</NAME><VALUE>false</VALUE></SETTING> + + <!-- Settings for "PPC CodeGen" panel --> + <SETTING><NAME>MWCodeGen_PPC_structalignment</NAME><VALUE>PPC_mw</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_tracebacktables</NAME><VALUE>Inline</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_processor</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_function_align</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_tocdata</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_largetoc</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_profiler</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_vectortocdata</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_poolconst</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_peephole</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_readonlystrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_linkerpoolsstrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_volatileasm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_schedule</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_altivec</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_altivec_move_block</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_strictIEEEfp</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_fpcontract</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_genfsel</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_PPC_orderedfpcmp</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC CodeGen Mach-O" panel --> + <SETTING><NAME>MWCodeGen_MachO_structalignment</NAME><VALUE>PPC_mw</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_profiler_enum</NAME><VALUE>Off</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_processor</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_function_align</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_common</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_boolisint</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_peephole</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_readonlystrings</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_linkerpoolsstrings</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_volatileasm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_schedule</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_altivec</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_vecmove</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_fp_ieee_strict</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_fpcontract</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_genfsel</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_MachO_fp_cmps_ordered</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC Disassembler" panel --> + <SETTING><NAME>MWDisassembler_PPC_showcode</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_extended</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_mix</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_nohex</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_showdata</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_showexceptions</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_showsym</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWDisassembler_PPC_shownames</NAME><VALUE>1</VALUE></SETTING> + + <!-- Settings for "PPC Global Optimizer" panel --> + <SETTING><NAME>GlobalOptimizer_PPC_optimizationlevel</NAME><VALUE>Level4</VALUE></SETTING> + <SETTING><NAME>GlobalOptimizer_PPC_optfor</NAME><VALUE>Speed</VALUE></SETTING> + + <!-- Settings for "PPC Linker" panel --> + <SETTING><NAME>MWLinker_PPC_linksym</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_symfullpath</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_linkmap</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_nolinkwarnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_dontdeadstripinitcode</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_permitmultdefs</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_linkmode</NAME><VALUE>Fast</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_code_folding</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_initname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_mainname</NAME><VALUE>__start</VALUE></SETTING> + <SETTING><NAME>MWLinker_PPC_termname</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "PPC Mac OS X Linker" panel --> + <SETTING><NAME>MWLinker_MacOSX_linksym</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_symfullpath</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_nolinkwarnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_linkmap</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_dontdeadstripinitcode</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_permitmultdefs</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_use_objectivec_semantics</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_strip_debug_symbols</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_prebind_all_twolevel_modules</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_data_before_text_segment</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_report_msl_overloads</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_objects_follow_linkorder</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_linkmode</NAME><VALUE>Fast</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_exports</NAME><VALUE>ReferencedGlobals</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_sortcode</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_mainname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_initname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_code_folding</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_MacOSX_stabsgen</NAME><VALUE>None</VALUE></SETTING> + + <!-- Settings for "PPC Mac OS X Project" panel --> + <SETTING><NAME>MWProject_MacOSX_type</NAME><VALUE>Library</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_outfile</NAME><VALUE>resiprocate.lib</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_filecreator</NAME><VALUE>CWIE</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_filetype</NAME><VALUE>MLIB</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_vmaddress</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_usedefaultvmaddr</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flatrsrc</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flatrsrcfilename</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flatrsrcoutputdir</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWProject_MacOSX_installpath</NAME><VALUE>./</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_dont_prebind</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flat_namespace</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_frameworkversion</NAME><VALUE>A</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_currentversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_flat_oldimpversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_MacOSX_AddrMode</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC PEF" panel --> + <SETTING><NAME>MWPEF_exports</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWPEF_libfolder</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_sortcode</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWPEF_expandbss</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_sharedata</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_olddefversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_oldimpversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_currentversion</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWPEF_fragmentname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWPEF_collapsereloads</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "PPC Project" panel --> + <SETTING><NAME>MWProject_PPC_type</NAME><VALUE>Application</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_outfile</NAME><VALUE>Std C Console PPC</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_filecreator</NAME><VALUE>????</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_filetype</NAME><VALUE>APPL</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_size</NAME><VALUE>384</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_minsize</NAME><VALUE>384</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_stacksize</NAME><VALUE>64</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_flags</NAME><VALUE>22720</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_symfilename</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcheader</NAME><VALUE>Native</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrctype</NAME><VALUE>????</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcflags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcstore</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_rsrcmerge</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_flatrsrc</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_PPC_flatrsrcoutputdir</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>MWProject_PPC_flatrsrcfilename</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "PPCAsm Panel" panel --> + <SETTING><NAME>MWAssembler_PPC_auxheader</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_symmode</NAME><VALUE>Mac</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_dialect</NAME><VALUE>PPC</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_prefixfile</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_typecheck</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_warnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWAssembler_PPC_casesensitive</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "Property List" panel --> + <SETTING><NAME>PList_OutputType</NAME><VALUE>File</VALUE></SETTING> + <SETTING><NAME>PList_OutputEncoding</NAME><VALUE>UTF-8</VALUE></SETTING> + <SETTING><NAME>PList_PListVersion</NAME><VALUE>1.0</VALUE></SETTING> + <SETTING><NAME>PList_Prefix</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>PList_FileFilename</NAME><VALUE>Info.plist</VALUE></SETTING> + <SETTING><NAME>PList_FileDirectory</NAME> + <SETTING><NAME>Path</NAME><VALUE>:</VALUE></SETTING> + <SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING> + <SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING> + </SETTING> + <SETTING><NAME>PList_ResourceType</NAME><VALUE>plst</VALUE></SETTING> + <SETTING><NAME>PList_ResourceID</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>PList_ResourceName</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "Rez Compiler" panel --> + <SETTING><NAME>MWRez_Language_maxwidth</NAME><VALUE>80</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_script</NAME><VALUE>Roman</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_alignment</NAME><VALUE>Align1</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_filtermode</NAME><VALUE>FilterSkip</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_suppresswarnings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_escapecontrolchars</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWRez_Language_prefixname</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWRez_Language_filteredtypes</NAME><VALUE>'CODE' 'DATA' 'PICT'</VALUE></SETTING> + + <!-- Settings for "WinRC Compiler" panel --> + <SETTING><NAME>MWWinRC_prefixname</NAME><VALUE></VALUE></SETTING> + + <!-- Settings for "x86 CodeGen" panel --> + <SETTING><NAME>MWCodeGen_X86_processor</NAME><VALUE>Generic</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_alignment</NAME><VALUE>bytes8</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_exceptions</NAME><VALUE>ZeroOverhead</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_name_mangling</NAME><VALUE>MWWin32</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_use_extinst</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_mmx</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_3dnow</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_use_mmx_3dnow_convention</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_cmov</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_sse</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_extinst_sse2</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_intrinsics</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_optimizeasm</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_disableopts</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_profile</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_runtime</NAME><VALUE>Custom</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_readonlystrings</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_vectorize</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCodeGen_X86_relaxieee</NAME><VALUE>0</VALUE></SETTING> + + <!-- Settings for "x86 COFF" panel --> + <SETTING><NAME>MWLinker_X86_subsysmajorid</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_subsysminorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_opsysmajorid</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_opsysminorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_usrmajorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_usrminorid</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_maxstacksize</NAME><VALUE>1024</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_minstacksize</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_size</NAME><VALUE>1024</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_minsize</NAME><VALUE>4</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_coff_flags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_dll_flags</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_baseaddress</NAME><VALUE>4194304</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_filealign</NAME><VALUE>4096</VALUE></SETTING> + <SETTING><NAME>MWCOFF_X86_sectionalign</NAME><VALUE>4096</VALUE></SETTING> + + <!-- Settings for "x86 Disassembler" panel --> + <SETTING><NAME>PDisasmX86_showHeaders</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSectHeaders</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSymTab</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showCode</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showData</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showDebug</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showExceptions</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showRaw</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showAllRaw</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSource</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showRelocation</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showHex</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showComments</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_showSymDefs</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_unmangle</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_verbose</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_resolveRelocs</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>PDisasmX86_resolveLocals</NAME><VALUE>false</VALUE></SETTING> + + <!-- Settings for "x86 Exceptions Panel" panel --> + <SETTING><NAME>MWDebugger_X86_Exceptions</NAME> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + <SETTING><VALUE>0</VALUE></SETTING> + </SETTING> + + <!-- Settings for "x86 Global Optimizer" panel --> + <SETTING><NAME>GlobalOptimizer_X86_optimizationlevel</NAME><VALUE>Level0</VALUE></SETTING> + <SETTING><NAME>GlobalOptimizer_X86_optfor</NAME><VALUE>Speed</VALUE></SETTING> + + <!-- Settings for "x86 Linker" panel --> + <SETTING><NAME>MWLinker_X86_entrypointusage</NAME><VALUE>Default</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_entrypoint</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_subsystem</NAME><VALUE>WinGUI</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_commandfile</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_generatemap</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linksym</NAME><VALUE>0</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linkCV</NAME><VALUE>1</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_symfullpath</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linkdebug</NAME><VALUE>true</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_checksum</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_zero_init_bss</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_mergedata</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_usedefaultlibs</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_adddefaultlibs</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_nowarnings</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_verbose</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_linkformem</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_codefolding</NAME><VALUE>None</VALUE></SETTING> + <SETTING><NAME>MWLinker_X86_debuginline</NAME><VALUE>false</VALUE></SETTING> + + <!-- Settings for "x86 Project" panel --> + <SETTING><NAME>MWProject_X86_type</NAME><VALUE>Application</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_outfile</NAME><VALUE>noname.exe</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_importlib</NAME><VALUE></VALUE></SETTING> + <SETTING><NAME>MWProject_X86_setimportlibdir</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_dontgenerateimportlib</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_oldformatlib</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_replaceobjextension</NAME><VALUE>false</VALUE></SETTING> + <SETTING><NAME>MWProject_X86_copyallfiles</NAME><VALUE>false</VALUE></SETTING> + </SETTINGLIST> + <FILELIST> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialog.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialogSet.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialogSetFactory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientAuthManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientInviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientOutOfDialogReq.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientPagerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientPublication.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientRegistration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DefaultServerReferHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DestroyUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Dialog.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogSet.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogSetId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogUsageManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DumProcessHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DumTimeout.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Handled.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/HandleException.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/HandleManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSessionCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSessionHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/MergedRequestKey.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/KeepAliveManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/KeepAliveTimeout.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/MasterProfile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/NetworkAssociation.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/NonDialogUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/OutOfDialogReqCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/PagerMessageCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Profile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/PublicationCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/RedirectManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/RegistrationCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerAuthManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerInviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerOutOfDialogReq.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerPagerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerPublication.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerRegistration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionState.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UInt64Hash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UserAuthInfo.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UserProfile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/AbstractFifo.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/BaseException.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Coders.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Condition.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/CountStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Data.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/DataStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/DnsUtil.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Lock.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Log.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Logger.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/MD5Stream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Mutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/ParseBuffer.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Random.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/RecursiveMutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/RWMutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Socket.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Subsystem.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SysLogBuf.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SysLogStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/ThreadIf.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Timer.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Tuple.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/vmd5.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ApiCheck.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/AresDns.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Auth.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/BranchParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CallId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Connection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ConnectionBase.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ConnectionManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Contents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CpimContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CSeqCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DataParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DateCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DnsInterface.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DnsResult.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Embedded.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExistsParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExpiresCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExternalBodyContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/FloatParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/GenericContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/GenericUri.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderFieldValue.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderFieldValueList.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Headers.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Helper.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/IntegerCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/IntegerParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/InternalTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/KeepAliveMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/LazyParser.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Message.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MessageWaitingContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MethodHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MethodTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Mime.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MsgHeaderScanner.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartAlternativeContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartMixedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartRelatedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartSignedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/NameAddr.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/OctetContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Parameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParameterHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParameterTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParserCategories.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParserCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParseUtil.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Pkcs7Contents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/PlainContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/QopParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/QuotedDataParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RAckCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Registration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RequestLine.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RportParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SdpContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Security.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SecurityAttributes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipFrag.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipStack.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StackThread.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatelessHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatisticsManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatisticsMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatusLine.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StringCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Symbols.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpBaseTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpConnection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TimerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TimerQueue.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Token.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionController.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionMap.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionState.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionUser.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionUserMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Transport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransportMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransportSelector.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TuSelector.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/UdpTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/UnknownParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Uri.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Via.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/WarningCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MacSecurity.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExternalDnsFactory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/FileSystem.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MessageFilterRule.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TlsTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TlsConnection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SHA1Stream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/external/HttpGetMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/external/HttpProvider.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsAAAARecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsCnameRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsHostRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsNaptrRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsSrvRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsStub.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/QueryTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRCache.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRList.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RROverlay.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + <FILE> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRVip.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + <FILEKIND>Text</FILEKIND> + <FILEFLAGS></FILEFLAGS> + </FILE> + </FILELIST> + <LINKORDER> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialog.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialogSet.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialogSetFactory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientAuthManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientInviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientOutOfDialogReq.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientPagerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientPublication.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientRegistration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DefaultServerReferHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DestroyUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Dialog.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogSet.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogSetId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogUsageManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DumProcessHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DumTimeout.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Handled.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/HandleException.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/HandleManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSessionCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSessionHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/MergedRequestKey.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/KeepAliveManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/KeepAliveTimeout.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/MasterProfile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/NetworkAssociation.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/NonDialogUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/OutOfDialogReqCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/PagerMessageCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Profile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/PublicationCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/RedirectManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/RegistrationCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerAuthManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerInviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerOutOfDialogReq.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerPagerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerPublication.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerRegistration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionState.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UInt64Hash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UserAuthInfo.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UserProfile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/AbstractFifo.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/BaseException.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Coders.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Condition.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/CountStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Data.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/DataStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/DnsUtil.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Lock.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Log.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Logger.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/MD5Stream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Mutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/ParseBuffer.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Random.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/RecursiveMutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/RWMutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Socket.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Subsystem.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SysLogBuf.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SysLogStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/ThreadIf.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Timer.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Tuple.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/vmd5.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ApiCheck.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/AresDns.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Auth.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/BranchParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CallId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Connection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ConnectionBase.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ConnectionManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Contents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CpimContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CSeqCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DataParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DateCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DnsInterface.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DnsResult.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Embedded.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExistsParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExpiresCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExternalBodyContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/FloatParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/GenericContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/GenericUri.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderFieldValue.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderFieldValueList.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Headers.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Helper.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/IntegerCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/IntegerParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/InternalTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/KeepAliveMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/LazyParser.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Message.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MessageWaitingContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MethodHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MethodTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Mime.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MsgHeaderScanner.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartAlternativeContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartMixedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartRelatedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartSignedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/NameAddr.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/OctetContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Parameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParameterHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParameterTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParserCategories.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParserCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParseUtil.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Pkcs7Contents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/PlainContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/QopParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/QuotedDataParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RAckCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Registration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RequestLine.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RportParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SdpContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Security.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SecurityAttributes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipFrag.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipStack.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StackThread.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatelessHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatisticsManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatisticsMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatusLine.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StringCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Symbols.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpBaseTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpConnection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TimerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TimerQueue.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Token.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionController.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionMap.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionState.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionUser.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionUserMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Transport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransportMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransportSelector.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TuSelector.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/UdpTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/UnknownParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Uri.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Via.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/WarningCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MacSecurity.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExternalDnsFactory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/FileSystem.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MessageFilterRule.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TlsTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TlsConnection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SHA1Stream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/external/HttpGetMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/external/HttpProvider.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsAAAARecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsCnameRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsHostRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsNaptrRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsSrvRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsStub.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/QueryTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRCache.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRList.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RROverlay.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRVip.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + </LINKORDER> + </TARGET> + </TARGETLIST> + + <TARGETORDER> + <ORDEREDTARGET><NAME>AresDebug</NAME></ORDEREDTARGET> + <ORDEREDTARGET><NAME>AresRelease</NAME></ORDEREDTARGET> + <ORDEREDTARGET><NAME>ResiprocateDebug</NAME></ORDEREDTARGET> + <ORDEREDTARGET><NAME>ResiprocateRelease</NAME></ORDEREDTARGET> + </TARGETORDER> + + <GROUPLIST> + <GROUP><NAME>Sources</NAME> + <GROUP><NAME>ares</NAME> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__close_sockets.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__get_hostent.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares__read_line.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_destroy.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_expand_name.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_fds.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_errmem.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_hostent.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_free_string.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_gethostbyaddr.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_gethostbyname.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_init.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_local.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_mkquery.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_parse_a_reply.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_parse_ptr_reply.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_process.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_query.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_search.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_send.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_strerror.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>AresDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>contrib/ares</ACCESSPATH> + <PATH>ares_timeout.c</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + </GROUP> + <GROUP><NAME>resiprocate</NAME> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ApiCheck.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/AresDns.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Auth.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/BranchParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CallId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Connection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ConnectionBase.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ConnectionManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Contents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CpimContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/CSeqCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DataParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DateCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DnsInterface.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/DnsResult.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Embedded.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExistsParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExpiresCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExternalBodyContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ExternalDnsFactory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/FloatParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/GenericContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/GenericUri.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderFieldValue.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderFieldValueList.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Headers.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/HeaderTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Helper.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/IntegerCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/IntegerParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/InternalTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/KeepAliveMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/LazyParser.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MacSecurity.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Message.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MessageFilterRule.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MessageWaitingContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MethodHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MethodTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Mime.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MsgHeaderScanner.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartAlternativeContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartMixedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartRelatedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/MultipartSignedContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/NameAddr.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/OctetContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Parameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParameterHash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParameterTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParserCategories.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParserCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/ParseUtil.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Pkcs7Contents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/PlainContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/QopParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/QuotedDataParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RAckCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Registration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RequestLine.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/RportParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SdpContents.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Security.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SecurityAttributes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipFrag.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/SipStack.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StackThread.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatelessHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatisticsManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatisticsMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StatusLine.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/StringCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Symbols.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpBaseTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpConnection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TcpTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TimerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TimerQueue.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TlsConnection.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TlsTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Token.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionController.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionMap.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionState.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionUser.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransactionUserMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Transport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransportMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TransportSelector.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/TuSelector.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/UdpTransport.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/UnknownParameter.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Uri.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/Via.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/WarningCategory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <GROUP><NAME>dns</NAME> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsAAAARecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsCnameRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsHostRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsNaptrRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsSrvRecord.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/DnsStub.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/QueryTypes.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRCache.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRList.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RROverlay.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dns/RRVip.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + </GROUP> + <GROUP><NAME>dum</NAME> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialog.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialogSet.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/AppDialogSetFactory.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/BaseUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientAuthManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientInviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientOutOfDialogReq.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientPagerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientPublication.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientRegistration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ClientSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DefaultServerReferHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DestroyUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Dialog.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogSet.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogSetId.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DialogUsageManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DumProcessHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/DumTimeout.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Handled.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/HandleException.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/HandleManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSessionCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/InviteSessionHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/MergedRequestKey.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/KeepAliveManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/KeepAliveTimeout.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/MasterProfile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/NetworkAssociation.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/NonDialogUsage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/OutOfDialogReqCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/PagerMessageCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/Profile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/PublicationCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/RedirectManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/RegistrationCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerAuthManager.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerInviteSession.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerOutOfDialogReq.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerPagerMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerPublication.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerRegistration.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/ServerSubscription.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionCreator.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionHandler.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/SubscriptionState.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UInt64Hash.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UserAuthInfo.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/dum/UserProfile.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + </GROUP> + <GROUP><NAME>os</NAME> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/AbstractFifo.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/BaseException.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Coders.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Condition.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/CountStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Data.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/DataStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/DnsUtil.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/FileSystem.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Lock.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Log.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Logger.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/MD5Stream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Mutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/ParseBuffer.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Random.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/RecursiveMutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/RWMutex.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SHA1Stream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Socket.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Subsystem.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SysLogBuf.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/SysLogStream.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/ThreadIf.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Timer.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/Tuple.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/os/vmd5.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + </GROUP> + <GROUP><NAME>external</NAME> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/external/HttpGetMessage.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + <FILEREF> + <TARGETNAME>ResiprocateDebug</TARGETNAME> + <PATHTYPE>PathRelative</PATHTYPE> + <PATHROOT>Project</PATHROOT> + <ACCESSPATH>:</ACCESSPATH> + <PATH>resiprocate/external/HttpProvider.cxx</PATH> + <PATHFORMAT>Unix</PATHFORMAT> + </FILEREF> + </GROUP> + </GROUP> + </GROUP> + </GROUPLIST> + +</PROJECT> diff --git a/src/libs/resiprocate/resip/sip.xcode/fluffy.pbxuser b/src/libs/resiprocate/resip/sip.xcode/fluffy.pbxuser new file mode 100644 index 00000000..e91f41bf --- /dev/null +++ b/src/libs/resiprocate/resip/sip.xcode/fluffy.pbxuser @@ -0,0 +1,707 @@ +// !$*UTF8*$! +{ + D61F2E75054CD488003A923B = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {716, 853}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {716, 252}}"; + }; + }; + D61F2E9C054CD49C003A923B = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {768, 2967}}"; + sepNavSelRange = "{2882, 0}"; + sepNavVisRect = "{{0, 1335}, {768, 285}}"; + }; + }; + D62F5DA5057C2D7E0025A74F = { + fRef = D6A7A2C3054CD02C00F1D5A3; + isa = PBXTextBookmark; + name = "ares_free_string.c: 15"; + rLen = 1; + rLoc = 704; + rType = 0; + vrLen = 744; + vrLoc = 0; + }; + D62F5DAC057C2E890025A74F = { + isa = PBXSymbolicBreakpoint; + state = 1; + symbolName = ""; + }; + D62F5DAF057C2ED00025A74F = { + fRef = D6A7A2C3054CD02C00F1D5A3; + isa = PBXTextBookmark; + name = "ares_free_string.c: 15"; + rLen = 1; + rLoc = 704; + rType = 0; + vrLen = 744; + vrLoc = 0; + }; + D6A7A290054CCEE800F1D5A3 = { + activeBuildStyle = D6A7A28E054CCEE800F1D5A3; + activeExecutable = D6A7A45A054CD1EE00F1D5A3; + activeTarget = D6A7A458054CD1EE00F1D5A3; + addToTargets = ( + D6A7A2F4054CD1A000F1D5A3, + ); + breakpoints = ( + D62F5DAC057C2E890025A74F, + ); + codeSenseManager = D6A7A292054CCEE800F1D5A3; + executables = ( + D6A7A45A054CD1EE00F1D5A3, + ); + perUserDictionary = { + PBXConfiguration.PBXFileTableDataSource3.PBXBookmarksDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXBookmarksDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 373.2085, + 358.5991, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXBookmarksDataSource_LocationID, + PBXBookmarksDataSource_NameID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = -1; + PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_LocationID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 457.8799, + 250.2085, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXErrorsWarningsDataSource_TypeID, + PBXErrorsWarningsDataSource_MessageID, + PBXErrorsWarningsDataSource_LocationID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = -1; + PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 22, + 709.7974, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXExecutablesDataSource_ActiveFlagID, + PBXExecutablesDataSource_NameID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = -1; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 478, + 20, + 88, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXSymbolsDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXSymbolsDataSource_SymbolNameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 16, + 224.8008, + 253.0356, + 230.2085, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXSymbolsDataSource_SymbolTypeIconID, + PBXSymbolsDataSource_SymbolNameID, + PBXSymbolsDataSource_SymbolTypeID, + PBXSymbolsDataSource_ReferenceNameID, + ); + }; + PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = -1; + PBXFileTableDataSourceColumnSortingKey = PBXTargetDataSource_PrimaryAttribute; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 408, + 89, + 20, + 89, + 43, + 43, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXTargetDataSource_PrimaryAttribute, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 92024193; + PBXWorkspaceContents = ( + { + PBXProjectWorkspaceModule_StateKey_Rev36 = { + PBXProjectWorkspaceModule_EditorOpen = true; + PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = { + Split0 = { + bookmark = D62F5DAF057C2ED00025A74F; + history = ( + D6CA2C7E057C22E2008107C1, + D62F5DA5057C2D7E0025A74F, + ); + prevStack = ( + D6CA2C83057C22E2008107C1, + ); + }; + SplitCount = 1; + }; + PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {755, 409}}"; + PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 409}, {755, 284}}"; + PBXProjectWorkspaceModule_OldSuperviewFrame = "{{314, 0}, {755, 693}}"; + PBXProjectWorkspaceModule_SGTM = { + PBXBottomSmartGroupGIDs = ( + 1C37FBAC04509CD000000102, + 1C37FAAC04509CD000000102, + 1C08E77C0454961000C914BD, + 1CC0EA4004350EF90044410B, + 1CC0EA4004350EF90041110B, + 1C37FABC05509CD000000102, + 1C37FABC05539CD112110102, + 1C37FABC04509CD000100104, + ); + PBXTopSmartGroupGIDs = ( + ); + }; + }; + }, + ); + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXBuildResultsModule" = { + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXCVSModule" = { + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXClassBrowserModule" = { + OptionsSetName = "Hierarchy, all classes"; + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugBreakpointsModule" = { + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugCLIModule" = { + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugSessionModule" = { + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXNavigatorGroup" = { + Split0 = { + bookmark = D6E8BE70057C26D80044AECA; + history = ( + D6E8BE6F057C26D80044AECA, + ); + }; + SplitCount = 1; + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = { + PBXProjectWorkspaceModule_StateKey_Rev36 = { + PBXProjectWorkspaceModule_EditorOpen = true; + PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = { + Split0 = { + bookmark = D62F5D72057C2B010025A74F; + history = ( + D6CA2C7E057C22E2008107C1, + D6CA2C7F057C22E2008107C1, + D6CA2C80057C22E2008107C1, + D6CA2C81057C22E2008107C1, + D6E8BE91057C29DF0044AECA, + ); + prevStack = ( + D6CA2C83057C22E2008107C1, + D6CA2C84057C22E2008107C1, + D6CA2C85057C22E2008107C1, + D6CA2C86057C22E2008107C1, + ); + }; + SplitCount = 1; + }; + PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {755, 409}}"; + PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 409}, {755, 284}}"; + PBXProjectWorkspaceModule_OldSuperviewFrame = "{{314, 0}, {755, 693}}"; + PBXProjectWorkspaceModule_SGTM = { + PBXBottomSmartGroupGIDs = ( + 1C37FBAC04509CD000000102, + 1C37FAAC04509CD000000102, + 1C08E77C0454961000C914BD, + 1CC0EA4004350EF90044410B, + 1CC0EA4004350EF90041110B, + 1C37FABC05509CD000000102, + 1C37FABC05539CD112110102, + 1C37FABC04509CD000100104, + ); + PBXTopSmartGroupGIDs = ( + ); + }; + }; + }; + PBXWorkspaceGeometries = ( + { + Frame = "{{0, 0}, {1069, 713}}"; + PBXProjectWorkspaceModule_GeometryKey_Rev11 = { + PBXProjectWorkspaceModule_SGTM_Geometry = { + _collapsingFrameDimension = 0; + _indexOfCollapsedView = 0; + _percentageOfCollapsedView = 0; + sizes = ( + "{{0, 0}, {314, 693}}", + "{{314, 0}, {755, 693}}", + ); + }; + }; + WindowFrame = "{{137, 77}, {1069, 775}}"; + }, + ); + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXBuildResultsModule" = { + Frame = "{{0, 0}, {746, 411}}"; + WindowFrame = "{{53, 10}, {746, 489}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXCVSModule" = { + Frame = "{{0, 0}, {482, 296}}"; + WindowFrame = "{{822, 337}, {482, 318}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXClassBrowserModule" = { + ClassesFrame = "{{0, 0}, {408, 92}}"; + ClassesTreeTableConfiguration = ( + PBXClassNameColumnIdentifier, + 208, + PBXClassBookColumnIdentifier, + 22, + ); + Frame = "{{0, 0}, {655, 496}}"; + MembersFrame = "{{0, 92}, {408, 384}}"; + MembersTreeTableConfiguration = ( + PBXMemberTypeIconColumnIdentifier, + 22, + PBXMemberNameColumnIdentifier, + 216, + PBXMemberTypeColumnIdentifier, + 133, + PBXMemberBookColumnIdentifier, + 22, + ); + WindowFrame = "{{377, 294}, {655, 574}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugBreakpointsModule" = { + BreakpointsTreeTableConfiguration = ( + enabledColumn, + 16, + breakpointColumn, + 282.583, + ); + Frame = "{{0, 0}, {208, 494}}"; + WindowFrame = "{{245, 187}, {208, 516}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugCLIModule" = { + Frame = "{{0, 0}, {400, 200}}"; + WindowFrame = "{{50, 850}, {400, 222}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugSessionModule" = { + DebugConsoleDrawerSize = "{100, 120}"; + DebugConsoleVisible = Drawer; + DebugConsoleWindowFrame = "{{200, 200}, {500, 300}}"; + DebugSTDIOWindowFrame = "{{200, 200}, {500, 300}}"; + Frame = "{{0, 0}, {807, 635}}"; + WindowFrame = "{{518, 158}, {807, 713}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXNavigatorGroup" = { + Frame = "{{0, 0}, {750, 480}}"; + WindowFrame = "{{15, 315}, {750, 558}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = { + Frame = "{{0, 0}, {1069, 713}}"; + PBXProjectWorkspaceModule_GeometryKey_Rev11 = { + PBXProjectWorkspaceModule_SGTM_Geometry = { + _collapsingFrameDimension = 0; + _indexOfCollapsedView = 0; + _percentageOfCollapsedView = 0; + sizes = ( + "{{0, 0}, {314, 693}}", + "{{314, 0}, {755, 693}}", + ); + }; + }; + WindowFrame = "{{137, 77}, {1069, 775}}"; + }; + PBXWorkspaceStateSaveDate = 92024193; + }; + perUserProjectItems = { + D62F5DA5057C2D7E0025A74F = D62F5DA5057C2D7E0025A74F; + D62F5DAF057C2ED00025A74F = D62F5DAF057C2ED00025A74F; + D6CA2C7E057C22E2008107C1 = D6CA2C7E057C22E2008107C1; + D6CA2C83057C22E2008107C1 = D6CA2C83057C22E2008107C1; + }; + sourceControlManager = D6A7A291054CCEE800F1D5A3; + userBuildSettings = { + }; + }; + D6A7A291054CCEE800F1D5A3 = { + isa = PBXSourceControlManager; + scmConfiguration = { + }; + scmType = ""; + }; + D6A7A292054CCEE800F1D5A3 = { + indexTemplatePath = ""; + isa = PBXCodeSenseManager; + usesDefaults = 1; + wantsCodeCompletion = 1; + wantsCodeCompletionAutoPopup = 0; + wantsCodeCompletionAutoSuggestions = 0; + wantsCodeCompletionCaseSensitivity = 1; + wantsCodeCompletionOnlyMatchingItems = 1; + wantsCodeCompletionParametersIncluded = 1; + wantsCodeCompletionPlaceholdersInserted = 1; + wantsCodeCompletionTabCompletes = 1; + wantsIndex = 1; + }; + D6A7A29D054CCF0E00F1D5A3 = { + activeExec = 0; + }; + D6A7A2AF054CD01B00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 769}}"; + sepNavSelRange = "{743, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{38, 294}, {750, 558}}"; + }; + }; + D6A7A2B1054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 428}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{61, 273}, {750, 558}}"; + }; + }; + D6A7A2B2054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 727}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{84, 252}, {750, 558}}"; + }; + }; + D6A7A2B3054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 8861}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 3}, {711, 428}}"; + sepNavWindowFrame = "{{107, 231}, {750, 558}}"; + }; + }; + D6A7A2B4054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 3975}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{130, 210}, {750, 558}}"; + }; + }; + D6A7A2B5054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 867}}"; + sepNavSelRange = "{703, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{153, 189}, {750, 558}}"; + }; + }; + D6A7A2B6054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 1455}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{176, 168}, {750, 558}}"; + }; + }; + D6A7A2B7054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 3751}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{291, 63}, {750, 558}}"; + }; + }; + D6A7A2B8054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 1553}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{314, 42}, {750, 558}}"; + }; + }; + D6A7A2B9054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {768, 9547}}"; + sepNavSelRange = "{2270, 0}"; + sepNavVisRect = "{{0, 733}, {768, 285}}"; + sepNavWindowFrame = "{{245, 105}, {750, 558}}"; + }; + }; + D6A7A2BA054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 2239}}"; + sepNavSelRange = "{703, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{337, 21}, {750, 558}}"; + }; + }; + D6A7A2BB054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 2225}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{15, 315}, {750, 558}}"; + }; + }; + D6A7A2BC054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 2407}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{360, -0}, {750, 558}}"; + }; + }; + D6A7A2BE054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {716, 629}}"; + sepNavSelRange = "{704, 1}"; + sepNavVisRect = "{{0, 0}, {716, 252}}"; + sepNavWindowFrame = "{{130, 210}, {750, 558}}"; + }; + }; + D6A7A2BF054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 2253}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{38, 294}, {750, 558}}"; + }; + }; + D6A7A2C0054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 643}}"; + sepNavSelRange = "{703, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{268, 84}, {750, 558}}"; + }; + }; + D6A7A2C1054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 895}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{153, 189}, {750, 558}}"; + }; + }; + D6A7A2C2054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {716, 2365}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {716, 252}}"; + sepNavWindowFrame = "{{176, 168}, {750, 558}}"; + }; + }; + D6A7A2C3054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {716, 335}}"; + sepNavSelRange = "{704, 1}"; + sepNavVisRect = "{{0, 0}, {716, 252}}"; + sepNavWindowFrame = "{{61, 273}, {750, 558}}"; + }; + }; + D6A7A2C4054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 503}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{84, 252}, {750, 558}}"; + }; + }; + D6A7A2C5054CD02C00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 2197}}"; + sepNavSelRange = "{704, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{107, 231}, {750, 558}}"; + }; + }; + D6A7A2DD054CD04B00F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 2869}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 1629}, {711, 428}}"; + }; + }; + D6A7A2F4054CD1A000F1D5A3 = { + activeExec = 0; + }; + D6A7A2F8054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 1483}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{38, 294}, {750, 558}}"; + }; + }; + D6A7A2FA054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 853}}"; + sepNavSelRange = "{141, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + }; + }; + D6A7A304054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {768, 4885}}"; + sepNavSelRange = "{6205, 0}"; + sepNavVisRect = "{{0, 3715}, {768, 285}}"; + }; + }; + D6A7A306054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 9001}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 5231}, {711, 428}}"; + }; + }; + D6A7A311054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {768, 1245}}"; + sepNavSelRange = "{395, 0}"; + sepNavVisRect = "{{0, 145}, {768, 285}}"; + }; + }; + D6A7A31B054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {716, 6635}}"; + sepNavSelRange = "{369, 51}"; + sepNavVisRect = "{{0, 0}, {716, 252}}"; + }; + }; + D6A7A31E054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 3737}}"; + sepNavSelRange = "{134, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{15, 315}, {750, 558}}"; + }; + }; + D6A7A361054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {768, 2323}}"; + sepNavSelRange = "{948, 0}"; + sepNavVisRect = "{{0, 411}, {768, 285}}"; + }; + }; + D6A7A369054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {768, 2393}}"; + sepNavSelRange = "{1836, 0}"; + sepNavVisRect = "{{0, 1195}, {768, 285}}"; + }; + }; + D6A7A36E054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {768, 6831}}"; + sepNavSelRange = "{3416, 0}"; + sepNavVisRect = "{{0, 1643}, {768, 285}}"; + }; + }; + D6A7A386054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 7643}}"; + sepNavSelRange = "{4411, 24}"; + sepNavVisRect = "{{0, 425}, {711, 428}}"; + sepNavWindowFrame = "{{15, 315}, {750, 558}}"; + }; + }; + D6A7A387054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {716, 23813}}"; + sepNavSelRange = "{27910, 53}"; + sepNavVisRect = "{{0, 18725}, {716, 252}}"; + sepNavWindowFrame = "{{38, 294}, {750, 558}}"; + }; + }; + D6A7A394054CD1C100F1D5A3 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 8231}}"; + sepNavSelRange = "{14018, 0}"; + sepNavVisRect = "{{0, 6457}, {711, 428}}"; + sepNavWindowFrame = "{{107, 231}, {750, 558}}"; + }; + }; + D6A7A458054CD1EE00F1D5A3 = { + activeExec = 0; + executables = ( + D6A7A45A054CD1EE00F1D5A3, + ); + }; + D6A7A45A054CD1EE00F1D5A3 = { + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + configStateDict = { + }; + debuggerPlugin = GDBDebugging; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + isa = PBXExecutable; + name = limp; + shlibInfoDictList = ( + ); + sourceDirectories = ( + ); + }; + D6CA2C7E057C22E2008107C1 = { + fRef = D61F2E75054CD488003A923B; + isa = PBXTextBookmark; + name = "AbstractFifo.cxx: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 266; + vrLoc = 0; + }; + D6CA2C83057C22E2008107C1 = { + fRef = D61F2E75054CD488003A923B; + isa = PBXTextBookmark; + name = "AbstractFifo.cxx: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 266; + vrLoc = 0; + }; + D6E8BE64057C26140044AECA = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {768, 12543}}"; + sepNavSelRange = "{21131, 0}"; + sepNavVisRect = "{{0, 11611}, {768, 285}}"; + sepNavWindowFrame = "{{15, 315}, {750, 558}}"; + }; + }; +} diff --git a/src/libs/resiprocate/resip/sip.xcode/project.pbxproj b/src/libs/resiprocate/resip/sip.xcode/project.pbxproj new file mode 100644 index 00000000..ce5238c1 --- /dev/null +++ b/src/libs/resiprocate/resip/sip.xcode/project.pbxproj @@ -0,0 +1,9213 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 39; + objects = { + 3723305A08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Aor.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723305B08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Aor.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723305C08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ApiCheck.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723305D08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ApiCheck.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723305E08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ApiCheckList.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723305F08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ApplicationMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306008561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = AresDns.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306108561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = AresDns.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306208561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Auth.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306308561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Auth.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306408561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = CallId.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306508561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = CallId.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306708561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ConnectionBase.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306808561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ConnectionBase.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306908561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = CpimContents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306A08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = CpimContents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306B08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = CSeqCategory.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306C08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = CSeqCategory.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306D08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = DateCategory.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306E08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = DateCategory.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723306F08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = DeprecatedDialog.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307008561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = DeprecatedDialog.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307108561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = DtlsMessage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307208561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = DtlsMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307308561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = DtlsTransport.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307408561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = DtlsTransport.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307508561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ExpiresCategory.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307608561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ExpiresCategory.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307708561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ExtensionHeader.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307808561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ExtensionHeader.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307908561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ExtensionParameter.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307A08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ExtensionParameter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307B08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ExternalBodyContents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307C08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ExternalBodyContents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307D08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ExternalDnsFactory.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723307E08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ExternalDnsFactory.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308008561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = GenericIPAddress.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308108561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = GenericUri.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308208561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = GenericUri.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308308561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = IntegerCategory.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308408561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = IntegerCategory.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308508561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = InternalTransport.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308608561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = InternalTransport.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308808561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = InterruptableStackThread.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308908561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = KeepAliveMessage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308A08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = KeepAliveMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308B08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = MacSecurity.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308C08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = MacSecurity.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308D08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = makeCert.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308E08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = MessageFilterRule.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723308F08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = MessageFilterRule.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309008561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Mime.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309108561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Mime.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309208561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = MultipartAlternativeContents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309308561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = MultipartAlternativeContents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309408561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = MultipartRelatedContents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309508561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = MultipartRelatedContents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309608561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = NameAddr.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309708561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = NameAddr.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309808561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Pkcs8Contents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309908561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Pkcs8Contents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309A08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = RAckCategory.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309B08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = RAckCategory.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309C08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = RequestLine.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309D08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = RequestLine.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309E08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Rlmi.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723309F08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Rlmi.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330A008561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = SecurityAttributes.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330A108561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = SecurityAttributes.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330A308561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = SecurityOld.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330A408561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = SecurityTypes.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330A508561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = SendData.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330A708561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = StackThread.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330A808561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = StackThread.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330A908561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = StatisticsManager.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330AA08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = StatisticsManager.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330AB08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = StatisticsMessage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330AC08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = StatisticsMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330AD08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = StatusLine.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330AE08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = StatusLine.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330AF08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = StringCategory.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330B008561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = StringCategory.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330B108561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TimeAccumulate.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330B208561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TimeAccumulate.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330B308561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Token.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330B408561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Token.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330B508561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TransactionMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330B608561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TransactionUser.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330B708561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TransactionUser.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330B808561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TransactionUserMessage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330B908561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TransactionUserMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330BA08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TransportMessage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330BB08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TuSelector.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330BC08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TuSelector.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330BD08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Via.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330BE08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Via.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330BF08561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = WarningCategory.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330C008561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = WarningCategory.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330C208561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = WinSecurity.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330C308561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = X509Contents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330C408561F1F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = X509Contents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330EA0856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = AsyncProcessHandler.hxx; + path = os/AsyncProcessHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330EB0856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = FileSystem.cxx; + path = os/FileSystem.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330EC0856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = FileSystem.hxx; + path = os/FileSystem.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330ED0856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = HeapInstanceCounter.cxx; + path = os/HeapInstanceCounter.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330EE0856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = HeapInstanceCounter.hxx; + path = os/HeapInstanceCounter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330EF0856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Id.cxx; + path = os/Id.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330F00856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Id.hxx; + path = os/Id.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330F10856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Poll.cxx; + path = os/Poll.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330F20856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Poll.hxx; + path = os/Poll.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330F30856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = SelectInterruptor.cxx; + path = os/SelectInterruptor.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330F40856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = SelectInterruptor.hxx; + path = os/SelectInterruptor.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330F50856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = SHA1Stream.cxx; + path = os/SHA1Stream.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330F70856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = SHA1Stream.hxx; + path = os/SHA1Stream.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330F90856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = SharedCount.hxx; + path = os/SharedCount.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330FA0856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = SharedPtr.hxx; + path = os/SharedPtr.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330FB0856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = SysLogBuf.cxx; + path = os/SysLogBuf.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330FC0856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = SysLogStream.cxx; + path = os/SysLogStream.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330FD0856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = TimeLimitFifo.hxx; + path = os/TimeLimitFifo.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372330FF0856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = WinCompat.hxx; + path = os/WinCompat.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331000856273F006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = WinLeakCheck.hxx; + path = os/WinLeakCheck.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723310608562887006148AE = { + fileRef = 3723308D08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723310708562888006148AE = { + fileRef = 372330F10856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723310808562889006148AE = { + fileRef = 3723306A08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331090856288A006148AE = { + fileRef = 3723308E08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723310A0856288B006148AE = { + fileRef = 3723308B08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723310B0856288F006148AE = { + fileRef = 372330B808561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723310C0856288F006148AE = { + fileRef = 372330FB0856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723310D08562890006148AE = { + fileRef = 3723308608561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723310E085628A3006148AE = { + fileRef = 372330AC08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723310F085628A4006148AE = { + fileRef = 372330B908561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233110085628A5006148AE = { + fileRef = 372330F90856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233111085628A7006148AE = { + fileRef = 3723306C08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233112085628A8006148AE = { + fileRef = 3723309308561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233113085628A8006148AE = { + fileRef = 3723305D08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233114085628A9006148AE = { + fileRef = 3723306108561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233115085628AC006148AE = { + fileRef = 3723308A08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233116085628AE006148AE = { + fileRef = 372330A508561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233117085628AF006148AE = { + fileRef = 372330C008561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233118085628B2006148AE = { + fileRef = 3723309108561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233119085628B3006148AE = { + fileRef = 3723309B08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723311A085628BB006148AE = { + fileRef = 372330BB08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723311B085628BC006148AE = { + fileRef = 372330AB08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723311C085628BE006148AE = { + fileRef = 3723309408561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723311D085628C0006148AE = { + fileRef = 3723307D08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723311E085628C2006148AE = { + fileRef = 3723306F08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723311F085628C2006148AE = { + fileRef = 3723305A08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233120085628C3006148AE = { + fileRef = 3723308908561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233121085628C4006148AE = { + fileRef = 3723305C08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233122085628C6006148AE = { + fileRef = 3723309A08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233123085628C8006148AE = { + fileRef = 3723307908561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233124085628C9006148AE = { + fileRef = 372330A008561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233125085628CD006148AE = { + fileRef = 372330ED0856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233126085628CE006148AE = { + fileRef = 3723306408561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233127085628D1006148AE = { + fileRef = 372330AD08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233128085628D2006148AE = { + fileRef = 372330BA08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723312A085628D3006148AE = { + fileRef = 372330AF08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723312B085628D4006148AE = { + fileRef = 3723307708561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723312C085628D7006148AE = { + fileRef = 372330A708561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723312D085628D8006148AE = { + fileRef = 3723307B08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723312E085628DD006148AE = { + fileRef = 372330EB0856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723312F085628DE006148AE = { + fileRef = 3723307308561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233130085628DF006148AE = { + fileRef = 372330B108561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233131085628E0006148AE = { + fileRef = 3723307508561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233132085628E0006148AE = { + fileRef = 3723309208561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233133085628E1006148AE = { + fileRef = D61F2E75054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + 37233135085628E4006148AE = { + fileRef = 3723307108561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233136085628E4006148AE = { + fileRef = 372330F50856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233137085628E5006148AE = { + fileRef = 3723306D08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233138085628E6006148AE = { + fileRef = 3723309608561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233139085628E6006148AE = { + fileRef = 3723306208561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723313A085628EA006148AE = { + fileRef = 372330EF0856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723313B085628EB006148AE = { + fileRef = 3723308308561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723313C085628EB006148AE = { + fileRef = 372330A908561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723313D085628EC006148AE = { + fileRef = 3723306008561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723313E085628EC006148AE = { + fileRef = 3723306708561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723313F085628ED006148AE = { + fileRef = 3723306B08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233140085628EE006148AE = { + fileRef = 3723309008561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233142085628F0006148AE = { + fileRef = 3723309E08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233143085628F0006148AE = { + fileRef = 3723309C08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233144085628F1006148AE = { + fileRef = 372330BD08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233145085628F1006148AE = { + fileRef = 3723309808561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233146085628F4006148AE = { + fileRef = 372330FC0856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233147085628F5006148AE = { + fileRef = 3723308508561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233148085628F6006148AE = { + fileRef = 3723308108561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 37233149085628F7006148AE = { + fileRef = 372330C308561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723314A085628F8006148AE = { + fileRef = 372330BF08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723314B085628F9006148AE = { + fileRef = 372330B608561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723314C085628FA006148AE = { + fileRef = 372330B308561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723314D085628FB006148AE = { + fileRef = 372330F30856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723314E085628FC006148AE = { + fileRef = 3723306908561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723314F0856290A006148AE = { + fileRef = 3723307A08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331500856290B006148AE = { + fileRef = 3723309F08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331510856290B006148AE = { + fileRef = 3723307808561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331520856290C006148AE = { + fileRef = 372330B708561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331530856290E006148AE = { + fileRef = 372330A408561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331540856290E006148AE = { + fileRef = 3723308208561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331550856290F006148AE = { + fileRef = 372330EA0856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331560856290F006148AE = { + fileRef = 372330C208561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723315708562910006148AE = { + fileRef = 372330FA0856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723315808562911006148AE = { + fileRef = 3723307208561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723315908562911006148AE = { + fileRef = 3723307E08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723315A08562912006148AE = { + fileRef = 3723307008561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723315B08562915006148AE = { + fileRef = 372330A808561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723315C08562916006148AE = { + fileRef = 3723307408561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723315D08562916006148AE = { + fileRef = 3723308808561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723315E08562917006148AE = { + fileRef = 3723306808561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723315F08562918006148AE = { + fileRef = 372330FD0856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723316008562918006148AE = { + fileRef = 372330A108561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723316108562919006148AE = { + fileRef = 372330B208561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331620856291A006148AE = { + fileRef = 3723309508561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331630856291B006148AE = { + fileRef = 372330F70856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331640856291D006148AE = { + fileRef = 372330A308561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331650856291D006148AE = { + fileRef = 372330FF0856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331660856291E006148AE = { + fileRef = 372330BC08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331670856291F006148AE = { + fileRef = 3723305E08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723316808562920006148AE = { + fileRef = 372330F40856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723316908562921006148AE = { + fileRef = 3723307608561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723316A08562924006148AE = { + fileRef = 372330B408561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723316B08562925006148AE = { + fileRef = 372331000856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723316C08562926006148AE = { + fileRef = 3723308C08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723316D08562927006148AE = { + fileRef = 3723306E08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723316E0856292A006148AE = { + fileRef = 3723305F08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723316F0856292A006148AE = { + fileRef = 3723309908561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331700856292C006148AE = { + fileRef = 3723307C08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331710856292D006148AE = { + fileRef = 3723305B08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331720856292E006148AE = { + fileRef = 372330EC0856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331730856292E006148AE = { + fileRef = 372330B008561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723317408562931006148AE = { + fileRef = 372330BE08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723317508562933006148AE = { + fileRef = 372330F20856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723317608562935006148AE = { + fileRef = 3723308F08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723317708562935006148AE = { + fileRef = 3723306308561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723317808562936006148AE = { + fileRef = 372330F00856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723317908562937006148AE = { + fileRef = 372330B508561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723317A08562938006148AE = { + fileRef = 3723308408561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723317B0856293A006148AE = { + fileRef = 3723308008561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723317C0856293A006148AE = { + fileRef = 3723309D08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723317D0856293B006148AE = { + fileRef = 3723309708561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723317E0856293B006148AE = { + fileRef = 372330C408561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723317F0856293C006148AE = { + fileRef = 372330AA08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331800856293D006148AE = { + fileRef = 3723306508561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331810856293E006148AE = { + fileRef = 372330EE0856273F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331820856293F006148AE = { + fileRef = 372330AE08561F1F006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372331BE08563770006148AE = { + children = ( + 372331BF085637E6006148AE, + 372331C0085637E7006148AE, + 372331C1085637E7006148AE, + 372331C2085637E7006148AE, + 372331C3085637E7006148AE, + 372331C4085637E7006148AE, + 372331C5085637E7006148AE, + 372331C6085637E7006148AE, + 372331C7085637E7006148AE, + 372331C8085637E7006148AE, + 372331C9085637E7006148AE, + 372331CA085637E7006148AE, + 372331CB085637E7006148AE, + 372331CC085637E7006148AE, + 372331CD085637E7006148AE, + 372331CE085637E7006148AE, + 372331CF085637E7006148AE, + 372331D0085637E7006148AE, + 372331D1085637E7006148AE, + 372331D2085637E7006148AE, + 372331D3085637E7006148AE, + 372331D4085637E7006148AE, + 372331D5085637E7006148AE, + 372331D6085637E7006148AE, + 372331D7085637E7006148AE, + 372331D8085637E7006148AE, + 372331D9085637E7006148AE, + 372331DA085637E7006148AE, + 372331DB085637E7006148AE, + 372331DC085637E7006148AE, + 372331DD085637E7006148AE, + 372331DE085637E7006148AE, + 372331DF085637E7006148AE, + 372331E0085637E7006148AE, + 372331E1085637E7006148AE, + 372331E2085637E7006148AE, + 372331E3085637E7006148AE, + 372331E4085637E7006148AE, + 372331E5085637E7006148AE, + 372331E6085637E7006148AE, + 372331E7085637E7006148AE, + 372331E8085637E7006148AE, + 372331E9085637E7006148AE, + 372331EC085637E7006148AE, + 372331ED085637E7006148AE, + 372331EE085637E7006148AE, + 372331EF085637E7006148AE, + 372331F0085637E7006148AE, + 372331F1085637E7006148AE, + 372331F2085637E7006148AE, + 372331F3085637E7006148AE, + 372331F4085637E7006148AE, + 372331F5085637E7006148AE, + 372331F6085637E7006148AE, + 372331F7085637E7006148AE, + 372331F8085637E7006148AE, + 372331F9085637E7006148AE, + 372331FA085637E7006148AE, + 372331FB085637E7006148AE, + 372331FC085637E7006148AE, + 372331FD085637E7006148AE, + 372331FE085637E7006148AE, + 372331FF085637E7006148AE, + 37233200085637E7006148AE, + 37233201085637E7006148AE, + 37233202085637E7006148AE, + 37233203085637E7006148AE, + 37233204085637E7006148AE, + 37233205085637E7006148AE, + 37233206085637E7006148AE, + 37233207085637E7006148AE, + 37233208085637E7006148AE, + 37233209085637E7006148AE, + 3723320A085637E7006148AE, + 3723320B085637E7006148AE, + 3723320C085637E7006148AE, + 3723320D085637E7006148AE, + 3723320E085637E7006148AE, + 3723320F085637E7006148AE, + 37233210085637E7006148AE, + 37233211085637E7006148AE, + 37233212085637E7006148AE, + 37233213085637E7006148AE, + 37233214085637E7006148AE, + 37233215085637E7006148AE, + 37233216085637E7006148AE, + 37233219085637E7006148AE, + 3723321A085637E7006148AE, + 3723321B085637E7006148AE, + 3723321C085637E7006148AE, + 3723321D085637E7006148AE, + 3723321E085637E7006148AE, + 3723321F085637E7006148AE, + 37233220085637E7006148AE, + 37233221085637E7006148AE, + 37233222085637E7006148AE, + 37233223085637E7006148AE, + 37233224085637E7006148AE, + 37233225085637E7006148AE, + 37233226085637E7006148AE, + 37233227085637E7006148AE, + 37233228085637E7006148AE, + 37233229085637E7006148AE, + 3723322A085637E7006148AE, + 3723322B085637E7006148AE, + 3723322C085637E7006148AE, + 3723322D085637E7006148AE, + 3723322E085637E7006148AE, + 3723322F085637E7006148AE, + 37233230085637E7006148AE, + 37233231085637E7006148AE, + 37233232085637E7006148AE, + 37233233085637E7006148AE, + 37233234085637E7006148AE, + 37233235085637E7006148AE, + 37233236085637E7006148AE, + 37233237085637E7006148AE, + 37233238085637E7006148AE, + 37233239085637E7006148AE, + 3723323A085637E7006148AE, + 3723323B085637E7006148AE, + 3723323C085637E7006148AE, + 3723323D085637E7006148AE, + 3723323E085637E7006148AE, + 3723323F085637E7006148AE, + 37233240085637E7006148AE, + 37233241085637E7006148AE, + ); + isa = PBXGroup; + name = Dum; + refType = 4; + sourceTree = "<group>"; + }; + 372331BF085637E6006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = AppDialog.cxx; + path = resiprocate/dum/AppDialog.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331C0085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = AppDialog.hxx; + path = resiprocate/dum/AppDialog.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331C1085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = AppDialogSet.cxx; + path = resiprocate/dum/AppDialogSet.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331C2085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = AppDialogSet.hxx; + path = resiprocate/dum/AppDialogSet.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331C3085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = AppDialogSetFactory.cxx; + path = resiprocate/dum/AppDialogSetFactory.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331C4085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = AppDialogSetFactory.hxx; + path = resiprocate/dum/AppDialogSetFactory.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331C5085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = BaseCreator.cxx; + path = resiprocate/dum/BaseCreator.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331C6085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = BaseCreator.hxx; + path = resiprocate/dum/BaseCreator.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331C7085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = BaseSubscription.cxx; + path = resiprocate/dum/BaseSubscription.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331C8085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = BaseSubscription.hxx; + path = resiprocate/dum/BaseSubscription.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331C9085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = BaseUsage.cxx; + path = resiprocate/dum/BaseUsage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331CA085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = BaseUsage.hxx; + path = resiprocate/dum/BaseUsage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331CB085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ClientAuthManager.cxx; + path = resiprocate/dum/ClientAuthManager.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331CC085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ClientAuthManager.hxx; + path = resiprocate/dum/ClientAuthManager.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331CD085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ClientInviteSession.cxx; + path = resiprocate/dum/ClientInviteSession.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331CE085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ClientInviteSession.hxx; + path = resiprocate/dum/ClientInviteSession.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331CF085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ClientOutOfDialogReq.cxx; + path = resiprocate/dum/ClientOutOfDialogReq.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331D0085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ClientOutOfDialogReq.hxx; + path = resiprocate/dum/ClientOutOfDialogReq.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331D1085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ClientPagerMessage.cxx; + path = resiprocate/dum/ClientPagerMessage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331D2085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ClientPagerMessage.hxx; + path = resiprocate/dum/ClientPagerMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331D3085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ClientPublication.cxx; + path = resiprocate/dum/ClientPublication.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331D4085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ClientPublication.hxx; + path = resiprocate/dum/ClientPublication.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331D5085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ClientRegistration.cxx; + path = resiprocate/dum/ClientRegistration.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331D6085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ClientRegistration.hxx; + path = resiprocate/dum/ClientRegistration.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331D7085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ClientSubscription.cxx; + path = resiprocate/dum/ClientSubscription.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331D8085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ClientSubscription.hxx; + path = resiprocate/dum/ClientSubscription.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331D9085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DefaultServerReferHandler.cxx; + path = resiprocate/dum/DefaultServerReferHandler.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331DA085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DefaultServerReferHandler.hxx; + path = resiprocate/dum/DefaultServerReferHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331DB085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DestroyUsage.cxx; + path = resiprocate/dum/DestroyUsage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331DC085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DestroyUsage.hxx; + path = resiprocate/dum/DestroyUsage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331DD085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Dialog.cxx; + path = resiprocate/dum/Dialog.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331DE085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Dialog.hxx; + path = resiprocate/dum/Dialog.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331DF085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DialogId.cxx; + path = resiprocate/dum/DialogId.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331E0085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DialogId.hxx; + path = resiprocate/dum/DialogId.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331E1085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DialogSet.cxx; + path = resiprocate/dum/DialogSet.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331E2085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DialogSet.hxx; + path = resiprocate/dum/DialogSet.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331E3085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DialogSetHandler.hxx; + path = resiprocate/dum/DialogSetHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331E4085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DialogSetId.cxx; + path = resiprocate/dum/DialogSetId.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331E5085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DialogSetId.hxx; + path = resiprocate/dum/DialogSetId.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331E6085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DialogUsage.cxx; + path = resiprocate/dum/DialogUsage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331E7085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DialogUsage.hxx; + path = resiprocate/dum/DialogUsage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331E8085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DialogUsageManager.cxx; + path = resiprocate/dum/DialogUsageManager.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331E9085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DialogUsageManager.hxx; + path = resiprocate/dum/DialogUsageManager.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331EC085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DumException.hxx; + path = resiprocate/dum/DumException.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331ED085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DumProcessHandler.cxx; + path = resiprocate/dum/DumProcessHandler.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331EE085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DumProcessHandler.hxx; + path = resiprocate/dum/DumProcessHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331EF085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DumShutdownHandler.hxx; + path = resiprocate/dum/DumShutdownHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331F0085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DumThread.cxx; + path = resiprocate/dum/DumThread.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331F1085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DumThread.hxx; + path = resiprocate/dum/DumThread.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331F2085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DumTimeout.cxx; + path = resiprocate/dum/DumTimeout.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331F3085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DumTimeout.hxx; + path = resiprocate/dum/DumTimeout.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331F4085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Handle.cxx; + path = resiprocate/dum/Handle.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331F5085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Handle.hxx; + path = resiprocate/dum/Handle.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331F6085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Handled.cxx; + path = resiprocate/dum/Handled.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331F7085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Handled.hxx; + path = resiprocate/dum/Handled.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331F8085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = HandleException.cxx; + path = resiprocate/dum/HandleException.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331F9085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = HandleException.hxx; + path = resiprocate/dum/HandleException.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331FA085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = HandleManager.cxx; + path = resiprocate/dum/HandleManager.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331FB085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = HandleManager.hxx; + path = resiprocate/dum/HandleManager.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331FC085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Handles.hxx; + path = resiprocate/dum/Handles.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331FD085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = InMemoryRegistrationDatabase.cxx; + path = resiprocate/dum/InMemoryRegistrationDatabase.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331FE085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = InMemoryRegistrationDatabase.hxx; + path = resiprocate/dum/InMemoryRegistrationDatabase.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372331FF085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = InviteSession.cxx; + path = resiprocate/dum/InviteSession.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233200085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = InviteSession.hxx; + path = resiprocate/dum/InviteSession.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233201085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = InviteSessionCreator.cxx; + path = resiprocate/dum/InviteSessionCreator.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233202085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = InviteSessionCreator.hxx; + path = resiprocate/dum/InviteSessionCreator.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233203085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = InviteSessionHandler.cxx; + path = resiprocate/dum/InviteSessionHandler.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233204085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = InviteSessionHandler.hxx; + path = resiprocate/dum/InviteSessionHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233205085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = KeepAliveManager.cxx; + path = resiprocate/dum/KeepAliveManager.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233206085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = KeepAliveManager.hxx; + path = resiprocate/dum/KeepAliveManager.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233207085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = KeepAliveTimeout.cxx; + path = resiprocate/dum/KeepAliveTimeout.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233208085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = KeepAliveTimeout.hxx; + path = resiprocate/dum/KeepAliveTimeout.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233209085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = MasterProfile.cxx; + path = resiprocate/dum/MasterProfile.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723320A085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = MasterProfile.hxx; + path = resiprocate/dum/MasterProfile.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723320B085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = MergedRequestKey.cxx; + path = resiprocate/dum/MergedRequestKey.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723320C085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = MergedRequestKey.hxx; + path = resiprocate/dum/MergedRequestKey.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723320D085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = NetworkAssociation.cxx; + path = resiprocate/dum/NetworkAssociation.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723320E085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = NetworkAssociation.hxx; + path = resiprocate/dum/NetworkAssociation.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723320F085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = NonDialogUsage.cxx; + path = resiprocate/dum/NonDialogUsage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233210085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = NonDialogUsage.hxx; + path = resiprocate/dum/NonDialogUsage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233211085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = OutOfDialogHandler.hxx; + path = resiprocate/dum/OutOfDialogHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233212085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = OutOfDialogReqCreator.cxx; + path = resiprocate/dum/OutOfDialogReqCreator.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233213085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = OutOfDialogReqCreator.hxx; + path = resiprocate/dum/OutOfDialogReqCreator.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233214085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = PagerMessageCreator.cxx; + path = resiprocate/dum/PagerMessageCreator.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233215085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = PagerMessageCreator.hxx; + path = resiprocate/dum/PagerMessageCreator.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233216085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = PagerMessageHandler.hxx; + path = resiprocate/dum/PagerMessageHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233219085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Profile.cxx; + path = resiprocate/dum/Profile.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723321A085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Profile.hxx; + path = resiprocate/dum/Profile.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723321B085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = PublicationCreator.cxx; + path = resiprocate/dum/PublicationCreator.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723321C085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = PublicationCreator.hxx; + path = resiprocate/dum/PublicationCreator.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723321D085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = PublicationHandler.hxx; + path = resiprocate/dum/PublicationHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723321E085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RedirectHandler.hxx; + path = resiprocate/dum/RedirectHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723321F085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = RedirectManager.cxx; + path = resiprocate/dum/RedirectManager.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233220085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RedirectManager.hxx; + path = resiprocate/dum/RedirectManager.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233221085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RefCountedDestroyer.hxx; + path = resiprocate/dum/RefCountedDestroyer.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233222085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = RegistrationCreator.cxx; + path = resiprocate/dum/RegistrationCreator.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233223085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RegistrationCreator.hxx; + path = resiprocate/dum/RegistrationCreator.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233224085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RegistrationHandler.hxx; + path = resiprocate/dum/RegistrationHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233225085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RegistrationPersistenceManager.hxx; + path = resiprocate/dum/RegistrationPersistenceManager.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233226085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ServerAuthManager.cxx; + path = resiprocate/dum/ServerAuthManager.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233227085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ServerAuthManager.hxx; + path = resiprocate/dum/ServerAuthManager.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233228085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ServerInviteSession.cxx; + path = resiprocate/dum/ServerInviteSession.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233229085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ServerInviteSession.hxx; + path = resiprocate/dum/ServerInviteSession.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723322A085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ServerOutOfDialogReq.cxx; + path = resiprocate/dum/ServerOutOfDialogReq.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723322B085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ServerOutOfDialogReq.hxx; + path = resiprocate/dum/ServerOutOfDialogReq.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723322C085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ServerPagerMessage.cxx; + path = resiprocate/dum/ServerPagerMessage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723322D085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ServerPagerMessage.hxx; + path = resiprocate/dum/ServerPagerMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723322E085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ServerPublication.cxx; + path = resiprocate/dum/ServerPublication.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723322F085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ServerPublication.hxx; + path = resiprocate/dum/ServerPublication.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233230085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ServerRegistration.cxx; + path = resiprocate/dum/ServerRegistration.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233231085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ServerRegistration.hxx; + path = resiprocate/dum/ServerRegistration.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233232085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ServerSubscription.cxx; + path = resiprocate/dum/ServerSubscription.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233233085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ServerSubscription.hxx; + path = resiprocate/dum/ServerSubscription.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233234085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = SubscriptionCreator.cxx; + path = resiprocate/dum/SubscriptionCreator.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233235085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = SubscriptionCreator.hxx; + path = resiprocate/dum/SubscriptionCreator.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233236085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = SubscriptionHandler.cxx; + path = resiprocate/dum/SubscriptionHandler.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233237085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = SubscriptionHandler.hxx; + path = resiprocate/dum/SubscriptionHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233238085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = SubscriptionPersistenceManager.hxx; + path = resiprocate/dum/SubscriptionPersistenceManager.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233239085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = SubscriptionState.cxx; + path = resiprocate/dum/SubscriptionState.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723323A085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = SubscriptionState.hxx; + path = resiprocate/dum/SubscriptionState.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723323B085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = UInt64Hash.cxx; + path = resiprocate/dum/UInt64Hash.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723323C085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = UInt64Hash.hxx; + path = resiprocate/dum/UInt64Hash.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723323D085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = UsageUseException.hxx; + path = resiprocate/dum/UsageUseException.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723323E085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = UserAuthInfo.cxx; + path = resiprocate/dum/UserAuthInfo.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3723323F085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = UserAuthInfo.hxx; + path = resiprocate/dum/UserAuthInfo.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233240085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = UserProfile.cxx; + path = resiprocate/dum/UserProfile.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 37233241085637E7006148AE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = UserProfile.hxx; + path = resiprocate/dum/UserProfile.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 372332C50856382C006148AE = { + buildActionMask = 2147483647; + files = ( + 372332D308564635006148AE, + 372332D508564635006148AE, + 372332D708564635006148AE, + 372332D908564635006148AE, + 372332DB08564635006148AE, + 372332DD08564635006148AE, + 372332DF08564635006148AE, + 372332E108564635006148AE, + 372332E308564635006148AE, + 372332E508564635006148AE, + 372332E708564635006148AE, + 372332E908564635006148AE, + 372332EB08564635006148AE, + 372332ED08564635006148AE, + 372332EF08564635006148AE, + 372332F108564635006148AE, + 372332F308564635006148AE, + 372332F508564635006148AE, + 372332F608564635006148AE, + 372332F808564635006148AE, + 372332FA08564635006148AE, + 372332FC08564635006148AE, + 372332FF08564635006148AE, + 3723330108564635006148AE, + 3723330208564635006148AE, + 3723330408564635006148AE, + 3723330608564635006148AE, + 3723330808564635006148AE, + 3723330A08564635006148AE, + 3723330C08564635006148AE, + 3723330E08564635006148AE, + 3723330F08564635006148AE, + 3723331108564635006148AE, + 3723331308564635006148AE, + 3723331508564635006148AE, + 3723331708564635006148AE, + 3723331908564635006148AE, + 3723331B08564635006148AE, + 3723331D08564635006148AE, + 3723331F08564635006148AE, + 3723332108564635006148AE, + 3723332308564635006148AE, + 3723332408564635006148AE, + 3723332608564635006148AE, + 3723332808564635006148AE, + 3723332908564635006148AE, + 3723332D08564635006148AE, + 3723332F08564635006148AE, + 3723333008564635006148AE, + 3723333108564635006148AE, + 3723333308564635006148AE, + 3723333408564635006148AE, + 3723333608564635006148AE, + 3723333708564635006148AE, + 3723333808564635006148AE, + 3723333A08564635006148AE, + 3723333C08564635006148AE, + 3723333E08564635006148AE, + 3723334008564635006148AE, + 3723334208564635006148AE, + 3723334408564635006148AE, + 3723334608564635006148AE, + 3723334808564635006148AE, + 3723334A08564635006148AE, + 3723334B08564635006148AE, + 3723334D08564635006148AE, + 3723334F08564635006148AE, + 3723335008564635006148AE, + 3723335208564635006148AE, + 3723335408564635006148AE, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 372332C60856382C006148AE = { + buildActionMask = 2147483647; + files = ( + 3723334308564635006148AE, + 372332D208564635006148AE, + 372332D408564635006148AE, + 372332D608564635006148AE, + 372332D808564635006148AE, + 372332DA08564635006148AE, + 372332DC08564635006148AE, + 372332DE08564635006148AE, + 372332E008564635006148AE, + 372332E208564635006148AE, + 372332E408564635006148AE, + 372332E608564635006148AE, + 372332E808564635006148AE, + 372332EA08564635006148AE, + 372332EC08564635006148AE, + 372332EE08564635006148AE, + 372332F008564635006148AE, + 372332F208564635006148AE, + 372332F408564635006148AE, + 372332F708564635006148AE, + 372332F908564635006148AE, + 372332FB08564635006148AE, + 3723330008564635006148AE, + 3723330308564635006148AE, + 3723330508564635006148AE, + 3723330708564635006148AE, + 3723330908564635006148AE, + 3723330B08564635006148AE, + 3723330D08564635006148AE, + 3723331008564635006148AE, + 3723331208564635006148AE, + 3723331408564635006148AE, + 3723331608564635006148AE, + 3723331808564635006148AE, + 3723331A08564635006148AE, + 3723331C08564635006148AE, + 3723331E08564635006148AE, + 3723332008564635006148AE, + 3723332208564635006148AE, + 3723332508564635006148AE, + 3723332708564635006148AE, + 3723332C08564635006148AE, + 3723332E08564635006148AE, + 3723333208564635006148AE, + 3723333508564635006148AE, + 3723333908564635006148AE, + 3723333B08564635006148AE, + 3723333D08564635006148AE, + 3723333F08564635006148AE, + 3723334108564635006148AE, + 3723334508564635006148AE, + 3723334708564635006148AE, + 3723334908564635006148AE, + 3723334C08564635006148AE, + 3723334E08564635006148AE, + 3723335108564635006148AE, + 3723335308564635006148AE, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 372332C70856382C006148AE = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 372332C80856382C006148AE = { + buildPhases = ( + 372332C50856382C006148AE, + 372332C60856382C006148AE, + 372332C70856382C006148AE, + ); + buildRules = ( + ); + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = USE_SSL; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = STATIC; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = dum; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + 3767C65508564E20008F581F, + ); + isa = PBXNativeTarget; + name = dum; + productName = dum; + productReference = 372332C90856382C006148AE; + productType = "com.apple.product-type.library.static"; + }; + 372332C90856382C006148AE = { + explicitFileType = archive.ar; + includeInIndex = 0; + isa = PBXFileReference; + path = libdum.a; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 372332D208564635006148AE = { + fileRef = 372331BF085637E6006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332D308564635006148AE = { + fileRef = 372331C0085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332D408564635006148AE = { + fileRef = 372331C1085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332D508564635006148AE = { + fileRef = 372331C2085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332D608564635006148AE = { + fileRef = 372331C3085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332D708564635006148AE = { + fileRef = 372331C4085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332D808564635006148AE = { + fileRef = 372331C5085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332D908564635006148AE = { + fileRef = 372331C6085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332DA08564635006148AE = { + fileRef = 372331C7085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332DB08564635006148AE = { + fileRef = 372331C8085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332DC08564635006148AE = { + fileRef = 372331C9085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332DD08564635006148AE = { + fileRef = 372331CA085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332DE08564635006148AE = { + fileRef = 372331CB085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332DF08564635006148AE = { + fileRef = 372331CC085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332E008564635006148AE = { + fileRef = 372331CD085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332E108564635006148AE = { + fileRef = 372331CE085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332E208564635006148AE = { + fileRef = 372331CF085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332E308564635006148AE = { + fileRef = 372331D0085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332E408564635006148AE = { + fileRef = 372331D1085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332E508564635006148AE = { + fileRef = 372331D2085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332E608564635006148AE = { + fileRef = 372331D3085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332E708564635006148AE = { + fileRef = 372331D4085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332E808564635006148AE = { + fileRef = 372331D5085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332E908564635006148AE = { + fileRef = 372331D6085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332EA08564635006148AE = { + fileRef = 372331D7085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332EB08564635006148AE = { + fileRef = 372331D8085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332EC08564635006148AE = { + fileRef = 372331D9085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332ED08564635006148AE = { + fileRef = 372331DA085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332EE08564635006148AE = { + fileRef = 372331DB085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332EF08564635006148AE = { + fileRef = 372331DC085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332F008564635006148AE = { + fileRef = 372331DD085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332F108564635006148AE = { + fileRef = 372331DE085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332F208564635006148AE = { + fileRef = 372331DF085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332F308564635006148AE = { + fileRef = 372331E0085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332F408564635006148AE = { + fileRef = 372331E1085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332F508564635006148AE = { + fileRef = 372331E2085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332F608564635006148AE = { + fileRef = 372331E3085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332F708564635006148AE = { + fileRef = 372331E4085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332F808564635006148AE = { + fileRef = 372331E5085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332F908564635006148AE = { + fileRef = 372331E6085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332FA08564635006148AE = { + fileRef = 372331E7085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332FB08564635006148AE = { + fileRef = 372331E8085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332FC08564635006148AE = { + fileRef = 372331E9085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 372332FF08564635006148AE = { + fileRef = 372331EC085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330008564635006148AE = { + fileRef = 372331ED085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330108564635006148AE = { + fileRef = 372331EE085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330208564635006148AE = { + fileRef = 372331EF085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330308564635006148AE = { + fileRef = 372331F0085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330408564635006148AE = { + fileRef = 372331F1085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330508564635006148AE = { + fileRef = 372331F2085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330608564635006148AE = { + fileRef = 372331F3085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330708564635006148AE = { + fileRef = 372331F4085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330808564635006148AE = { + fileRef = 372331F5085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330908564635006148AE = { + fileRef = 372331F6085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330A08564635006148AE = { + fileRef = 372331F7085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330B08564635006148AE = { + fileRef = 372331F8085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330C08564635006148AE = { + fileRef = 372331F9085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330D08564635006148AE = { + fileRef = 372331FA085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330E08564635006148AE = { + fileRef = 372331FB085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723330F08564635006148AE = { + fileRef = 372331FC085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331008564635006148AE = { + fileRef = 372331FD085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331108564635006148AE = { + fileRef = 372331FE085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331208564635006148AE = { + fileRef = 372331FF085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331308564635006148AE = { + fileRef = 37233200085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331408564635006148AE = { + fileRef = 37233201085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331508564635006148AE = { + fileRef = 37233202085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331608564635006148AE = { + fileRef = 37233203085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331708564635006148AE = { + fileRef = 37233204085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331808564635006148AE = { + fileRef = 37233205085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331908564635006148AE = { + fileRef = 37233206085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331A08564635006148AE = { + fileRef = 37233207085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331B08564635006148AE = { + fileRef = 37233208085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331C08564635006148AE = { + fileRef = 37233209085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331D08564635006148AE = { + fileRef = 3723320A085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331E08564635006148AE = { + fileRef = 3723320B085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723331F08564635006148AE = { + fileRef = 3723320C085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332008564635006148AE = { + fileRef = 3723320D085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332108564635006148AE = { + fileRef = 3723320E085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332208564635006148AE = { + fileRef = 3723320F085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332308564635006148AE = { + fileRef = 37233210085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332408564635006148AE = { + fileRef = 37233211085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332508564635006148AE = { + fileRef = 37233212085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332608564635006148AE = { + fileRef = 37233213085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332708564635006148AE = { + fileRef = 37233214085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332808564635006148AE = { + fileRef = 37233215085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332908564635006148AE = { + fileRef = 37233216085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332C08564635006148AE = { + fileRef = 37233219085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332D08564635006148AE = { + fileRef = 3723321A085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332E08564635006148AE = { + fileRef = 3723321B085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723332F08564635006148AE = { + fileRef = 3723321C085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333008564635006148AE = { + fileRef = 3723321D085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333108564635006148AE = { + fileRef = 3723321E085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333208564635006148AE = { + fileRef = 3723321F085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333308564635006148AE = { + fileRef = 37233220085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333408564635006148AE = { + fileRef = 37233221085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333508564635006148AE = { + fileRef = 37233222085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333608564635006148AE = { + fileRef = 37233223085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333708564635006148AE = { + fileRef = 37233224085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333808564635006148AE = { + fileRef = 37233225085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333908564635006148AE = { + fileRef = 37233226085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333A08564635006148AE = { + fileRef = 37233227085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333B08564635006148AE = { + fileRef = 37233228085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333C08564635006148AE = { + fileRef = 37233229085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333D08564635006148AE = { + fileRef = 3723322A085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333E08564635006148AE = { + fileRef = 3723322B085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723333F08564635006148AE = { + fileRef = 3723322C085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334008564635006148AE = { + fileRef = 3723322D085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334108564635006148AE = { + fileRef = 3723322E085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334208564635006148AE = { + fileRef = 3723322F085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334308564635006148AE = { + fileRef = 37233230085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334408564635006148AE = { + fileRef = 37233231085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334508564635006148AE = { + fileRef = 37233232085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334608564635006148AE = { + fileRef = 37233233085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334708564635006148AE = { + fileRef = 37233234085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334808564635006148AE = { + fileRef = 37233235085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334908564635006148AE = { + fileRef = 37233236085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334A08564635006148AE = { + fileRef = 37233237085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334B08564635006148AE = { + fileRef = 37233238085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334C08564635006148AE = { + fileRef = 37233239085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334D08564635006148AE = { + fileRef = 3723323A085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334E08564635006148AE = { + fileRef = 3723323B085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723334F08564635006148AE = { + fileRef = 3723323C085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723335008564635006148AE = { + fileRef = 3723323D085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723335108564635006148AE = { + fileRef = 3723323E085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723335208564635006148AE = { + fileRef = 3723323F085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723335308564635006148AE = { + fileRef = 37233240085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3723335408564635006148AE = { + fileRef = 37233241085637E7006148AE; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C63308564CCA008F581F = { + buildActionMask = 2147483647; + files = ( + 3767C64908564D73008F581F, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 3767C63408564CCA008F581F = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 3767C63508564CCA008F581F = { + buildPhases = ( + 3767C63308564CCA008F581F, + 3767C63408564CCA008F581F, + ); + buildRules = ( + ); + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = "USE_SSL USE_IPV6"; + INSTALL_PATH = /usr/local/bin; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = "-ldum -lresiprocate -lares -lssl -lcrypto"; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = testSMIMEMessage; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + 3767C63B08564CDD008F581F, + ); + isa = PBXNativeTarget; + name = testSMIMEMessage; + productName = testSMIMEMessage; + productReference = 3767C63608564CCA008F581F; + productType = "com.apple.product-type.tool"; + }; + 3767C63608564CCA008F581F = { + explicitFileType = "compiled.mach-o.executable"; + includeInIndex = 0; + isa = PBXFileReference; + path = testSMIMEMessage; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 3767C63A08564CDD008F581F = { + containerPortal = D6A7A290054CCEE800F1D5A3; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 372332C80856382C006148AE; + remoteInfo = dum; + }; + 3767C63B08564CDD008F581F = { + isa = PBXTargetDependency; + target = 372332C80856382C006148AE; + targetProxy = 3767C63A08564CDD008F581F; + }; + 3767C63C08564CED008F581F = { + children = ( + 3767C70908565B45008F581F, + 3767C70A08565B45008F581F, + 3767C63D08564D64008F581F, + 3767C63E08564D64008F581F, + 3767C63F08564D64008F581F, + 3767C64008564D64008F581F, + 3767C64208564D64008F581F, + 3767C64108564D64008F581F, + 3767C64308564D64008F581F, + ); + isa = PBXGroup; + name = DumTest; + refType = 4; + sourceTree = "<group>"; + }; + 3767C63D08564D64008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = BasicCall.cxx; + path = resiprocate/dum/test/BasicCall.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C63E08564D64008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = basicMessage.cxx; + path = resiprocate/dum/test/basicMessage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C63F08564D64008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = basicRegister.cxx; + path = resiprocate/dum/test/basicRegister.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C64008564D64008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = CommandLineParser.cxx; + path = resiprocate/dum/test/CommandLineParser.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C64108564D64008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = CommandLineParser.hxx; + path = resiprocate/dum/test/CommandLineParser.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C64208564D64008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = testIdentity.cxx; + path = resiprocate/dum/test/testIdentity.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C64308564D64008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = testSMIMEMessage.cxx; + path = resiprocate/dum/test/testSMIMEMessage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C64908564D73008F581F = { + fileRef = 3767C64308564D64008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C64B08564DFC008F581F = { + buildActionMask = 2147483647; + files = ( + 3767C6F908565A60008F581F, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 3767C64C08564DFC008F581F = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 3767C64D08564DFC008F581F = { + buildPhases = ( + 3767C64B08564DFC008F581F, + 3767C64C08564DFC008F581F, + ); + buildRules = ( + ); + buildSettings = { + INSTALL_PATH = /usr/local/bin; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = "-ldum -lresiprocate -lares -lssl -lcrypto"; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = BasicMessage; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + 3767C65308564E09008F581F, + ); + isa = PBXNativeTarget; + name = BasicMessage; + productName = BasicMessage; + productReference = 3767C64E08564DFC008F581F; + productType = "com.apple.product-type.tool"; + }; + 3767C64E08564DFC008F581F = { + explicitFileType = "compiled.mach-o.executable"; + includeInIndex = 0; + isa = PBXFileReference; + path = BasicMessage; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 3767C65208564E09008F581F = { + containerPortal = D6A7A290054CCEE800F1D5A3; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 372332C80856382C006148AE; + remoteInfo = dum; + }; + 3767C65308564E09008F581F = { + isa = PBXTargetDependency; + target = 372332C80856382C006148AE; + targetProxy = 3767C65208564E09008F581F; + }; + 3767C65408564E20008F581F = { + containerPortal = D6A7A290054CCEE800F1D5A3; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = D6A7A2F4054CD1A000F1D5A3; + remoteInfo = resiprocate; + }; + 3767C65508564E20008F581F = { + isa = PBXTargetDependency; + target = D6A7A2F4054CD1A000F1D5A3; + targetProxy = 3767C65408564E20008F581F; + }; + 3767C691085654B2008F581F = { + children = ( + 3767C692085654DC008F581F, + 3767C693085654DD008F581F, + 3767C694085654DD008F581F, + 3767C695085654DD008F581F, + 3767C696085654DD008F581F, + 3767C697085654DD008F581F, + 3767C698085654DD008F581F, + 3767C699085654DD008F581F, + 3767C69A085654DD008F581F, + 3767C69B085654DD008F581F, + 3767C69C085654DD008F581F, + 3767C69D085654DD008F581F, + 3767C69E085654DD008F581F, + 3767C69F085654DD008F581F, + 3767C6A0085654DD008F581F, + 3767C6A1085654DD008F581F, + 3767C6A2085654DD008F581F, + 3767C6A3085654DD008F581F, + 3767C6A4085654DD008F581F, + 3767C6A5085654DD008F581F, + 3767C6A6085654DD008F581F, + 3767C6A7085654DD008F581F, + 3767C6A8085654DD008F581F, + 3767C6A9085654DD008F581F, + ); + isa = PBXGroup; + name = Dns; + refType = 4; + sourceTree = "<group>"; + }; + 3767C692085654DC008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DnsAAAARecord.cxx; + path = dns/DnsAAAARecord.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C693085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DnsAAAARecord.hxx; + path = dns/DnsAAAARecord.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C694085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DnsCnameRecord.cxx; + path = dns/DnsCnameRecord.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C695085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DnsCnameRecord.hxx; + path = dns/DnsCnameRecord.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C696085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DnsHostRecord.cxx; + path = dns/DnsHostRecord.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C697085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DnsHostRecord.hxx; + path = dns/DnsHostRecord.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C698085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DnsNaptrRecord.cxx; + path = dns/DnsNaptrRecord.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C699085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DnsNaptrRecord.hxx; + path = dns/DnsNaptrRecord.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C69A085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DnsResourceRecord.hxx; + path = dns/DnsResourceRecord.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C69B085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DnsSrvRecord.cxx; + path = dns/DnsSrvRecord.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C69C085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DnsSrvRecord.hxx; + path = dns/DnsSrvRecord.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C69D085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DnsStub.cxx; + path = dns/DnsStub.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C69E085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DnsStub.hxx; + path = dns/DnsStub.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C69F085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = QueryTypes.cxx; + path = dns/QueryTypes.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6A0085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = QueryTypes.hxx; + path = dns/QueryTypes.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6A1085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = RRCache.cxx; + path = dns/RRCache.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6A2085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RRCache.hxx; + path = dns/RRCache.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6A3085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RRFactory.hxx; + path = dns/RRFactory.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6A4085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = RRList.cxx; + path = dns/RRList.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6A5085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RRList.hxx; + path = dns/RRList.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6A6085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = RROverlay.cxx; + path = dns/RROverlay.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6A7085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RROverlay.hxx; + path = dns/RROverlay.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6A8085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = RRVip.cxx; + path = dns/RRVip.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6A9085654DD008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RRVip.hxx; + path = dns/RRVip.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6AA085654DD008F581F = { + fileRef = 3767C692085654DC008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6AB085654DD008F581F = { + fileRef = 3767C693085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6AC085654DD008F581F = { + fileRef = 3767C694085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6AD085654DD008F581F = { + fileRef = 3767C695085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6AE085654DD008F581F = { + fileRef = 3767C696085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6AF085654DD008F581F = { + fileRef = 3767C697085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6B0085654DD008F581F = { + fileRef = 3767C698085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6B1085654DD008F581F = { + fileRef = 3767C699085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6B2085654DD008F581F = { + fileRef = 3767C69A085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6B3085654DD008F581F = { + fileRef = 3767C69B085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6B4085654DD008F581F = { + fileRef = 3767C69C085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6B5085654DD008F581F = { + fileRef = 3767C69D085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6B6085654DD008F581F = { + fileRef = 3767C69E085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6B7085654DD008F581F = { + fileRef = 3767C69F085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6B8085654DD008F581F = { + fileRef = 3767C6A0085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6B9085654DD008F581F = { + fileRef = 3767C6A1085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6BA085654DD008F581F = { + fileRef = 3767C6A2085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6BB085654DD008F581F = { + fileRef = 3767C6A3085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6BC085654DD008F581F = { + fileRef = 3767C6A4085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6BD085654DD008F581F = { + fileRef = 3767C6A5085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6BE085654DD008F581F = { + fileRef = 3767C6A6085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6BF085654DD008F581F = { + fileRef = 3767C6A7085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6C0085654DD008F581F = { + fileRef = 3767C6A8085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6C1085654DD008F581F = { + fileRef = 3767C6A9085654DD008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6C408565582008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_local.c; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6C508565582008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ares_local.h; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6C808565582008F581F = { + fileRef = 3767C6C408565582008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6C908565582008F581F = { + fileRef = 3767C6C508565582008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6CD085655F9008F581F = { + children = ( + 3767C6CE08565616008F581F, + 3767C6CF08565616008F581F, + 3767C6D008565616008F581F, + 3767C6D108565616008F581F, + 3767C6D208565616008F581F, + 3767C6D308565616008F581F, + 3767C6D408565616008F581F, + ); + isa = PBXGroup; + name = External; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6CE08565616008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = AsyncID.hxx; + path = external/AsyncID.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6CF08565616008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ExternalDns.hxx; + path = external/ExternalDns.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6D008565616008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ExternalTimer.hxx; + path = external/ExternalTimer.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6D108565616008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = HttpGetMessage.cxx; + path = external/HttpGetMessage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6D208565616008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = HttpGetMessage.hxx; + path = external/HttpGetMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6D308565616008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = HttpProvider.cxx; + path = external/HttpProvider.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6D408565616008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = HttpProvider.hxx; + path = external/HttpProvider.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C6D508565616008F581F = { + fileRef = 3767C6CE08565616008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6D608565616008F581F = { + fileRef = 3767C6CF08565616008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6D708565616008F581F = { + fileRef = 3767C6D008565616008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6D808565616008F581F = { + fileRef = 3767C6D108565616008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6D908565616008F581F = { + fileRef = 3767C6D208565616008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6DA08565616008F581F = { + fileRef = 3767C6D308565616008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6DB08565616008F581F = { + fileRef = 3767C6D408565616008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6F908565A60008F581F = { + fileRef = 3767C63E08564D64008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C6FA08565A99008F581F = { + buildActionMask = 2147483647; + files = ( + 3767C70B08565B4D008F581F, + 3767C70C08565B4D008F581F, + 3767C70808565AE8008F581F, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 3767C6FB08565A99008F581F = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 3767C6FC08565A99008F581F = { + buildPhases = ( + 3767C6FA08565A99008F581F, + 3767C6FB08565A99008F581F, + ); + buildRules = ( + ); + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = "USE_ARES USE_SSL USE_IPV6 USE_CURL"; + INSTALL_PATH = /usr/local/bin; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = "-ldum -lresiprocate -lares -lcurl -lssl -lcrypto"; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = testIdentity; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + 3767C72A08565D26008F581F, + ); + isa = PBXNativeTarget; + name = testIdentity; + productName = testIdentity; + productReference = 3767C6FD08565A99008F581F; + productType = "com.apple.product-type.tool"; + }; + 3767C6FD08565A99008F581F = { + explicitFileType = "compiled.mach-o.executable"; + includeInIndex = 0; + isa = PBXFileReference; + path = testIdentity; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 3767C70808565AE8008F581F = { + fileRef = 3767C64208564D64008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C70908565B45008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = CurlHttpProvider.cxx; + path = resiprocate/dum/test/curlHttp/CurlHttpProvider.cxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C70A08565B45008F581F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = CurlHttpProvider.hxx; + path = resiprocate/dum/test/curlHttp/CurlHttpProvider.hxx; + refType = 4; + sourceTree = "<group>"; + }; + 3767C70B08565B4D008F581F = { + fileRef = 3767C70908565B45008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C70C08565B4D008F581F = { + fileRef = 3767C70A08565B45008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C71508565BA4008F581F = { + buildActionMask = 2147483647; + files = ( + 3767C71A08565BE0008F581F, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 3767C71608565BA4008F581F = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 3767C71708565BA4008F581F = { + buildPhases = ( + 3767C71508565BA4008F581F, + 3767C71608565BA4008F581F, + ); + buildRules = ( + ); + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = "USE_ARES USE_SSL USE_IPV6"; + INSTALL_PATH = /usr/local/bin; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = "-ldum -lresiprocate -lares -lssl -lcrypto"; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = BasicCall; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + 3767C72C08565D33008F581F, + ); + isa = PBXNativeTarget; + name = BasicCall; + productName = BasicCall; + productReference = 3767C71808565BA4008F581F; + productType = "com.apple.product-type.tool"; + }; + 3767C71808565BA4008F581F = { + explicitFileType = "compiled.mach-o.executable"; + includeInIndex = 0; + isa = PBXFileReference; + path = BasicCall; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 3767C71A08565BE0008F581F = { + fileRef = 3767C63D08564D64008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C72308565C1F008F581F = { + buildActionMask = 2147483647; + files = ( + 3767C72808565C4E008F581F, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 3767C72408565C1F008F581F = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 3767C72508565C1F008F581F = { + buildPhases = ( + 3767C72308565C1F008F581F, + 3767C72408565C1F008F581F, + ); + buildRules = ( + ); + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = "USE_ARES USE_SSL USE_IPV6"; + INSTALL_PATH = /usr/local/bin; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = "-ldum -lresiprocate -lares -lssl -lcrypto"; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = BasicRegister; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + 3767C72E08565D42008F581F, + ); + isa = PBXNativeTarget; + name = BasicRegister; + productName = BasicRegister; + productReference = 3767C72608565C1F008F581F; + productType = "com.apple.product-type.tool"; + }; + 3767C72608565C1F008F581F = { + explicitFileType = "compiled.mach-o.executable"; + includeInIndex = 0; + isa = PBXFileReference; + path = BasicRegister; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 3767C72808565C4E008F581F = { + fileRef = 3767C63F08564D64008F581F; + isa = PBXBuildFile; + settings = { + }; + }; + 3767C72908565D26008F581F = { + containerPortal = D6A7A290054CCEE800F1D5A3; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 372332C80856382C006148AE; + remoteInfo = dum; + }; + 3767C72A08565D26008F581F = { + isa = PBXTargetDependency; + target = 372332C80856382C006148AE; + targetProxy = 3767C72908565D26008F581F; + }; + 3767C72B08565D33008F581F = { + containerPortal = D6A7A290054CCEE800F1D5A3; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 372332C80856382C006148AE; + remoteInfo = dum; + }; + 3767C72C08565D33008F581F = { + isa = PBXTargetDependency; + target = 372332C80856382C006148AE; + targetProxy = 3767C72B08565D33008F581F; + }; + 3767C72D08565D42008F581F = { + containerPortal = D6A7A290054CCEE800F1D5A3; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 372332C80856382C006148AE; + remoteInfo = dum; + }; + 3767C72E08565D42008F581F = { + isa = PBXTargetDependency; + target = 372332C80856382C006148AE; + targetProxy = 3767C72D08565D42008F581F; + }; +//370 +//371 +//372 +//373 +//374 +//D60 +//D61 +//D62 +//D63 +//D64 + D61F2E61054CD45E003A923B = { + children = ( + 372330EA0856273F006148AE, + 372330EB0856273F006148AE, + 372330EC0856273F006148AE, + 372330ED0856273F006148AE, + 372330EE0856273F006148AE, + 372330EF0856273F006148AE, + 372330F00856273F006148AE, + 372330F10856273F006148AE, + 372330F20856273F006148AE, + 372330F30856273F006148AE, + 372330F40856273F006148AE, + 372330F50856273F006148AE, + 372330F70856273F006148AE, + 372330F90856273F006148AE, + 372330FA0856273F006148AE, + 372330FB0856273F006148AE, + 372330FC0856273F006148AE, + 372330FD0856273F006148AE, + 372330FF0856273F006148AE, + 372331000856273F006148AE, + D61F2E90054CD49C003A923B, + D61F2E91054CD49C003A923B, + D61F2E92054CD49C003A923B, + D61F2E93054CD49C003A923B, + D61F2E94054CD49C003A923B, + D61F2E95054CD49C003A923B, + D61F2E96054CD49C003A923B, + D61F2E97054CD49C003A923B, + D61F2E98054CD49C003A923B, + D61F2E99054CD49C003A923B, + D61F2E9A054CD49C003A923B, + D61F2E9B054CD49C003A923B, + D61F2E9C054CD49C003A923B, + D61F2E9D054CD49C003A923B, + D61F2E9E054CD49C003A923B, + D61F2E9F054CD49C003A923B, + D61F2EA0054CD49C003A923B, + D61F2EA1054CD49C003A923B, + D61F2EA2054CD49C003A923B, + D61F2EA3054CD49C003A923B, + D61F2EA4054CD49C003A923B, + D61F2EA5054CD49C003A923B, + D61F2EA6054CD49C003A923B, + D61F2EA7054CD49C003A923B, + D61F2EA8054CD49C003A923B, + D61F2EA9054CD49C003A923B, + D61F2EAA054CD49C003A923B, + D61F2EAB054CD49C003A923B, + D61F2EAC054CD49C003A923B, + D61F2EAD054CD49C003A923B, + D61F2EAE054CD49C003A923B, + D61F2EAF054CD49C003A923B, + D61F2EB0054CD49C003A923B, + D61F2EB1054CD49C003A923B, + D61F2EB2054CD49C003A923B, + D61F2E62054CD488003A923B, + D61F2E63054CD488003A923B, + D61F2E64054CD488003A923B, + D61F2E65054CD488003A923B, + D61F2E66054CD488003A923B, + D61F2E67054CD488003A923B, + D61F2E68054CD488003A923B, + D61F2E69054CD488003A923B, + D61F2E6A054CD488003A923B, + D61F2E6B054CD488003A923B, + D61F2E6C054CD488003A923B, + D61F2E6D054CD488003A923B, + D61F2E6E054CD488003A923B, + D61F2E6F054CD488003A923B, + D61F2E70054CD488003A923B, + D61F2E71054CD488003A923B, + D61F2E72054CD488003A923B, + D61F2E73054CD488003A923B, + D61F2E74054CD488003A923B, + D61F2E75054CD488003A923B, + D61F2E76054CD488003A923B, + D61F2E77054CD488003A923B, + D61F2E78054CD488003A923B, + ); + isa = PBXGroup; + name = Os; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E62054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = BaseException.cxx; + path = os/BaseException.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E63054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = RWMutex.cxx; + path = os/RWMutex.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E64054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Lock.cxx; + path = os/Lock.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E65054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Data.cxx; + path = os/Data.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E66054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Mutex.cxx; + path = os/Mutex.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E67054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DnsUtil.cxx; + path = os/DnsUtil.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E68054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Coders.cxx; + path = os/Coders.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E69054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Timer.cxx; + path = os/Timer.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E6A054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Logger.cxx; + path = os/Logger.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E6B054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ParseBuffer.cxx; + path = os/ParseBuffer.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E6C054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = DataStream.cxx; + path = os/DataStream.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E6D054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Random.cxx; + path = os/Random.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E6E054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = vmd5.cxx; + path = os/vmd5.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E6F054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = RecursiveMutex.cxx; + path = os/RecursiveMutex.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E70054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ThreadIf.cxx; + path = os/ThreadIf.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E71054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Log.cxx; + path = os/Log.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E72054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Socket.cxx; + path = os/Socket.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E73054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Condition.cxx; + path = os/Condition.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E74054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = CountStream.cxx; + path = os/CountStream.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E75054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = AbstractFifo.cxx; + path = os/AbstractFifo.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E76054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Subsystem.cxx; + path = os/Subsystem.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E77054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = MD5Stream.cxx; + path = os/MD5Stream.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E78054CD488003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = Tuple.cxx; + path = os/Tuple.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E79054CD488003A923B = { + fileRef = D61F2E62054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E7A054CD488003A923B = { + fileRef = D61F2E63054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E7B054CD488003A923B = { + fileRef = D61F2E64054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E7C054CD488003A923B = { + fileRef = D61F2E65054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E7D054CD488003A923B = { + fileRef = D61F2E66054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E7E054CD488003A923B = { + fileRef = D61F2E67054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E7F054CD488003A923B = { + fileRef = D61F2E68054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E80054CD488003A923B = { + fileRef = D61F2E69054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E81054CD488003A923B = { + fileRef = D61F2E6A054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E82054CD488003A923B = { + fileRef = D61F2E6B054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E83054CD488003A923B = { + fileRef = D61F2E6C054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E84054CD488003A923B = { + fileRef = D61F2E6D054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E85054CD488003A923B = { + fileRef = D61F2E6E054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E86054CD488003A923B = { + fileRef = D61F2E6F054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E87054CD488003A923B = { + fileRef = D61F2E70054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E88054CD488003A923B = { + fileRef = D61F2E71054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E89054CD488003A923B = { + fileRef = D61F2E72054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E8A054CD488003A923B = { + fileRef = D61F2E73054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E8B054CD488003A923B = { + fileRef = D61F2E74054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E8D054CD488003A923B = { + fileRef = D61F2E76054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E8E054CD488003A923B = { + fileRef = D61F2E77054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E8F054CD488003A923B = { + fileRef = D61F2E78054CD488003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2E90054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Coders.hxx; + path = os/Coders.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E91054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Logger.hxx; + path = os/Logger.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E92054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = SysLogStream.hxx; + path = os/SysLogStream.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E93054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Log.hxx; + path = os/Log.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E94054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Data.hxx; + path = os/Data.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E95054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = compat.hxx; + path = os/compat.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E96054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = vthread.hxx; + path = os/vthread.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E97054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Lock.hxx; + path = os/Lock.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E98054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RWMutex.hxx; + path = os/RWMutex.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E99054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = vmd5.hxx; + path = os/vmd5.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E9A054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Inserter.hxx; + path = os/Inserter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E9B054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DataStream.hxx; + path = os/DataStream.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E9C054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Socket.hxx; + path = os/Socket.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E9D054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = HashMap.hxx; + path = os/HashMap.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E9E054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = CountStream.hxx; + path = os/CountStream.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2E9F054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Fifo.hxx; + path = os/Fifo.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EA0054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Timer.hxx; + path = os/Timer.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EA1054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Subsystem.hxx; + path = os/Subsystem.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EA2054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = AbstractFifo.hxx; + path = os/AbstractFifo.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EA3054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ParseBuffer.hxx; + path = os/ParseBuffer.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EA4054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Mutex.hxx; + path = os/Mutex.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EA5054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = CircularBuffer.hxx; + path = os/CircularBuffer.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EA6054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = BaseException.hxx; + path = os/BaseException.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EA7054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Condition.hxx; + path = os/Condition.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EA8054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Tuple.hxx; + path = os/Tuple.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EA9054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = ThreadIf.hxx; + path = os/ThreadIf.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EAA054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = FiniteFifo.hxx; + path = os/FiniteFifo.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EAB054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Lockable.hxx; + path = os/Lockable.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EAC054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = Random.hxx; + path = os/Random.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EAD054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = IntrusiveListElement.hxx; + path = os/IntrusiveListElement.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EAE054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = TransportType.hxx; + path = os/TransportType.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EAF054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = MD5Stream.hxx; + path = os/MD5Stream.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EB0054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = RecursiveMutex.hxx; + path = os/RecursiveMutex.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EB1054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = SysLogBuf.hxx; + path = os/SysLogBuf.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EB2054CD49C003A923B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + name = DnsUtil.hxx; + path = os/DnsUtil.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D61F2EB3054CD49C003A923B = { + fileRef = D61F2E90054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EB4054CD49C003A923B = { + fileRef = D61F2E91054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EB5054CD49C003A923B = { + fileRef = D61F2E92054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EB6054CD49C003A923B = { + fileRef = D61F2E93054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EB7054CD49C003A923B = { + fileRef = D61F2E94054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EB8054CD49C003A923B = { + fileRef = D61F2E95054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EB9054CD49C003A923B = { + fileRef = D61F2E96054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EBA054CD49C003A923B = { + fileRef = D61F2E97054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EBB054CD49C003A923B = { + fileRef = D61F2E98054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EBC054CD49C003A923B = { + fileRef = D61F2E99054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EBD054CD49C003A923B = { + fileRef = D61F2E9A054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EBE054CD49C003A923B = { + fileRef = D61F2E9B054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EBF054CD49C003A923B = { + fileRef = D61F2E9C054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EC0054CD49C003A923B = { + fileRef = D61F2E9D054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EC1054CD49C003A923B = { + fileRef = D61F2E9E054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EC2054CD49C003A923B = { + fileRef = D61F2E9F054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EC3054CD49C003A923B = { + fileRef = D61F2EA0054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EC4054CD49C003A923B = { + fileRef = D61F2EA1054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EC5054CD49C003A923B = { + fileRef = D61F2EA2054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EC6054CD49C003A923B = { + fileRef = D61F2EA3054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EC7054CD49C003A923B = { + fileRef = D61F2EA4054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EC8054CD49C003A923B = { + fileRef = D61F2EA5054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2EC9054CD49C003A923B = { + fileRef = D61F2EA6054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2ECA054CD49C003A923B = { + fileRef = D61F2EA7054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2ECB054CD49C003A923B = { + fileRef = D61F2EA8054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2ECC054CD49C003A923B = { + fileRef = D61F2EA9054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2ECD054CD49C003A923B = { + fileRef = D61F2EAA054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2ECE054CD49C003A923B = { + fileRef = D61F2EAB054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2ECF054CD49C003A923B = { + fileRef = D61F2EAC054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2ED0054CD49C003A923B = { + fileRef = D61F2EAD054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2ED1054CD49C003A923B = { + fileRef = D61F2EAE054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2ED2054CD49C003A923B = { + fileRef = D61F2EAF054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2ED3054CD49C003A923B = { + fileRef = D61F2EB0054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2ED4054CD49C003A923B = { + fileRef = D61F2EB1054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D61F2ED5054CD49C003A923B = { + fileRef = D61F2EB2054CD49C003A923B; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A28C054CCEE800F1D5A3 = { + children = ( + 3767C63C08564CED008F581F, + 372331BE08563770006148AE, + D6E8BE5F057C25D80044AECA, + D6A7A2EB054CD0EA00F1D5A3, + D6A7A2AC054CCFBD00F1D5A3, + D6A7A29F054CCF0E00F1D5A3, + ); + isa = PBXGroup; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A28E054CCEE800F1D5A3 = { + buildSettings = { + COPY_PHASE_STRIP = NO; + HEADER_SEARCH_PATHS = ./; + LIBRARY_SEARCH_PATHS = ./; + }; + isa = PBXBuildStyle; + name = Development; + }; + D6A7A28F054CCEE800F1D5A3 = { + buildSettings = { + COPY_PHASE_STRIP = YES; + }; + isa = PBXBuildStyle; + name = Deployment; + }; + D6A7A290054CCEE800F1D5A3 = { + buildSettings = { + }; + buildStyles = ( + D6A7A28E054CCEE800F1D5A3, + D6A7A28F054CCEE800F1D5A3, + ); + hasScannedForEncodings = 1; + isa = PBXProject; + mainGroup = D6A7A28C054CCEE800F1D5A3; + productRefGroup = D6A7A29F054CCF0E00F1D5A3; + projectDirPath = ""; + targets = ( + D6A7A29D054CCF0E00F1D5A3, + D6A7A2F4054CD1A000F1D5A3, + D6A7A458054CD1EE00F1D5A3, + 372332C80856382C006148AE, + 3767C63508564CCA008F581F, + 3767C64D08564DFC008F581F, + 3767C6FC08565A99008F581F, + 3767C71708565BA4008F581F, + 3767C72508565C1F008F581F, + ); + }; + D6A7A29B054CCF0E00F1D5A3 = { + buildActionMask = 2147483647; + files = ( + D6A7A2DF054CD04B00F1D5A3, + D6A7A2E0054CD04B00F1D5A3, + D6A7A2E1054CD04B00F1D5A3, + D6A7A2E2054CD04B00F1D5A3, + 3767C6C908565582008F581F, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + D6A7A29C054CCF0E00F1D5A3 = { + buildActionMask = 2147483647; + files = ( + D6A7A2B0054CD01B00F1D5A3, + D6A7A2C6054CD02C00F1D5A3, + D6A7A2C7054CD02C00F1D5A3, + D6A7A2C8054CD02C00F1D5A3, + D6A7A2C9054CD02C00F1D5A3, + D6A7A2CA054CD02C00F1D5A3, + D6A7A2CB054CD02C00F1D5A3, + D6A7A2CC054CD02C00F1D5A3, + D6A7A2CD054CD02C00F1D5A3, + D6A7A2CE054CD02C00F1D5A3, + D6A7A2CF054CD02C00F1D5A3, + D6A7A2D0054CD02C00F1D5A3, + D6A7A2D1054CD02C00F1D5A3, + D6A7A2D2054CD02C00F1D5A3, + D6A7A2D3054CD02C00F1D5A3, + D6A7A2D4054CD02C00F1D5A3, + D6A7A2D5054CD02C00F1D5A3, + D6A7A2D6054CD02C00F1D5A3, + D6A7A2D7054CD02C00F1D5A3, + D6A7A2D8054CD02C00F1D5A3, + D6A7A2D9054CD02C00F1D5A3, + D6A7A2DA054CD02C00F1D5A3, + 3767C6C808565582008F581F, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + D6A7A29D054CCF0E00F1D5A3 = { + buildPhases = ( + D6A7A29B054CCF0E00F1D5A3, + D6A7A29C054CCF0E00F1D5A3, + ); + buildRules = ( + ); + buildSettings = { + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = STATIC; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = ares; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + }; + dependencies = ( + ); + isa = PBXNativeTarget; + name = ares; + productName = ares; + productReference = D6A7A29E054CCF0E00F1D5A3; + productType = "com.apple.product-type.library.static"; + }; + D6A7A29E054CCF0E00F1D5A3 = { + explicitFileType = archive.ar; + includeInIndex = 0; + isa = PBXFileReference; + path = libares.a; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + D6A7A29F054CCF0E00F1D5A3 = { + children = ( + D6A7A29E054CCF0E00F1D5A3, + D6A7A2F5054CD1A000F1D5A3, + D6A7A459054CD1EE00F1D5A3, + 372332C90856382C006148AE, + 3767C63608564CCA008F581F, + 3767C64E08564DFC008F581F, + 3767C6FD08565A99008F581F, + 3767C71808565BA4008F581F, + 3767C72608565C1F008F581F, + ); + isa = PBXGroup; + name = Products; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2AC054CCFBD00F1D5A3 = { + children = ( + 3767C6C408565582008F581F, + 3767C6C508565582008F581F, + D6A7A2DB054CD04B00F1D5A3, + D6A7A2DC054CD04B00F1D5A3, + D6A7A2DD054CD04B00F1D5A3, + D6A7A2DE054CD04B00F1D5A3, + D6A7A2AF054CD01B00F1D5A3, + D6A7A2B1054CD02C00F1D5A3, + D6A7A2B2054CD02C00F1D5A3, + D6A7A2B3054CD02C00F1D5A3, + D6A7A2B4054CD02C00F1D5A3, + D6A7A2B5054CD02C00F1D5A3, + D6A7A2B6054CD02C00F1D5A3, + D6A7A2B7054CD02C00F1D5A3, + D6A7A2B8054CD02C00F1D5A3, + D6A7A2B9054CD02C00F1D5A3, + D6A7A2BA054CD02C00F1D5A3, + D6A7A2BB054CD02C00F1D5A3, + D6A7A2BC054CD02C00F1D5A3, + D6A7A2BD054CD02C00F1D5A3, + D6A7A2BE054CD02C00F1D5A3, + D6A7A2BF054CD02C00F1D5A3, + D6A7A2C0054CD02C00F1D5A3, + D6A7A2C1054CD02C00F1D5A3, + D6A7A2C2054CD02C00F1D5A3, + D6A7A2C3054CD02C00F1D5A3, + D6A7A2C4054CD02C00F1D5A3, + D6A7A2C5054CD02C00F1D5A3, + ); + isa = PBXGroup; + name = Ares; + path = contrib/ares; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2AF054CD01B00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares__close_sockets.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2B0054CD01B00F1D5A3 = { + fileRef = D6A7A2AF054CD01B00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2B1054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_free_errmem.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2B2054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_fds.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2B3054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_init.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2B4054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_gethostbyname.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2B5054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_timeout.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2B6054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_send.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2B7054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_search.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2B8054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_query.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2B9054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_process.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2BA054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_parse_ptr_reply.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2BB054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_mkquery.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2BC054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_parse_a_reply.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2BD054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares__close_sockets.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2BE054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_destroy.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2BF054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_gethostbyaddr.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2C0054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_strerror.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2C1054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares__read_line.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2C2054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares__get_hostent.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2C3054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_free_string.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2C4054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_free_hostent.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2C5054CD02C00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = ares_expand_name.c; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2C6054CD02C00F1D5A3 = { + fileRef = D6A7A2B1054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2C7054CD02C00F1D5A3 = { + fileRef = D6A7A2B2054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2C8054CD02C00F1D5A3 = { + fileRef = D6A7A2B3054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2C9054CD02C00F1D5A3 = { + fileRef = D6A7A2B4054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2CA054CD02C00F1D5A3 = { + fileRef = D6A7A2B5054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2CB054CD02C00F1D5A3 = { + fileRef = D6A7A2B6054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2CC054CD02C00F1D5A3 = { + fileRef = D6A7A2B7054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2CD054CD02C00F1D5A3 = { + fileRef = D6A7A2B8054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2CE054CD02C00F1D5A3 = { + fileRef = D6A7A2B9054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2CF054CD02C00F1D5A3 = { + fileRef = D6A7A2BA054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2D0054CD02C00F1D5A3 = { + fileRef = D6A7A2BB054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2D1054CD02C00F1D5A3 = { + fileRef = D6A7A2BC054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2D2054CD02C00F1D5A3 = { + fileRef = D6A7A2BD054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2D3054CD02C00F1D5A3 = { + fileRef = D6A7A2BE054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2D4054CD02C00F1D5A3 = { + fileRef = D6A7A2BF054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2D5054CD02C00F1D5A3 = { + fileRef = D6A7A2C0054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2D6054CD02C00F1D5A3 = { + fileRef = D6A7A2C1054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2D7054CD02C00F1D5A3 = { + fileRef = D6A7A2C2054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2D8054CD02C00F1D5A3 = { + fileRef = D6A7A2C3054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2D9054CD02C00F1D5A3 = { + fileRef = D6A7A2C4054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2DA054CD02C00F1D5A3 = { + fileRef = D6A7A2C5054CD02C00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2DB054CD04B00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ares_private.h; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2DC054CD04B00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ares_compat.h; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2DD054CD04B00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ares.h; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2DE054CD04B00F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ares_dns.h; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2DF054CD04B00F1D5A3 = { + fileRef = D6A7A2DB054CD04B00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2E0054CD04B00F1D5A3 = { + fileRef = D6A7A2DC054CD04B00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2E1054CD04B00F1D5A3 = { + fileRef = D6A7A2DD054CD04B00F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A2E2054CD04B00F1D5A3 = { + fileRef = D6A7A2DE054CD04B00F1D5A3; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + D6A7A2EB054CD0EA00F1D5A3 = { + children = ( + 3767C6CD085655F9008F581F, + 3767C691085654B2008F581F, + 3723305A08561F1F006148AE, + 3723305B08561F1F006148AE, + 3723305C08561F1F006148AE, + 3723305D08561F1F006148AE, + 3723305E08561F1F006148AE, + 3723305F08561F1F006148AE, + 3723306008561F1F006148AE, + 3723306108561F1F006148AE, + 3723306208561F1F006148AE, + 3723306308561F1F006148AE, + 3723306408561F1F006148AE, + 3723306508561F1F006148AE, + 3723306708561F1F006148AE, + 3723306808561F1F006148AE, + 3723306908561F1F006148AE, + 3723306A08561F1F006148AE, + 3723306B08561F1F006148AE, + 3723306C08561F1F006148AE, + 3723306D08561F1F006148AE, + 3723306E08561F1F006148AE, + 3723306F08561F1F006148AE, + 3723307008561F1F006148AE, + 3723307108561F1F006148AE, + 3723307208561F1F006148AE, + 3723307308561F1F006148AE, + 3723307408561F1F006148AE, + 3723307508561F1F006148AE, + 3723307608561F1F006148AE, + 3723307708561F1F006148AE, + 3723307808561F1F006148AE, + 3723307908561F1F006148AE, + 3723307A08561F1F006148AE, + 3723307B08561F1F006148AE, + 3723307C08561F1F006148AE, + 3723307D08561F1F006148AE, + 3723307E08561F1F006148AE, + 3723308008561F1F006148AE, + 3723308108561F1F006148AE, + 3723308208561F1F006148AE, + 3723308308561F1F006148AE, + 3723308408561F1F006148AE, + 3723308508561F1F006148AE, + 3723308608561F1F006148AE, + 3723308808561F1F006148AE, + 3723308908561F1F006148AE, + 3723308A08561F1F006148AE, + 3723308B08561F1F006148AE, + 3723308C08561F1F006148AE, + 3723308D08561F1F006148AE, + 3723308E08561F1F006148AE, + 3723308F08561F1F006148AE, + 3723309008561F1F006148AE, + 3723309108561F1F006148AE, + 3723309208561F1F006148AE, + 3723309308561F1F006148AE, + 3723309408561F1F006148AE, + 3723309508561F1F006148AE, + 3723309608561F1F006148AE, + 3723309708561F1F006148AE, + 3723309808561F1F006148AE, + 3723309908561F1F006148AE, + 3723309A08561F1F006148AE, + 3723309B08561F1F006148AE, + 3723309C08561F1F006148AE, + 3723309D08561F1F006148AE, + 3723309E08561F1F006148AE, + 3723309F08561F1F006148AE, + 372330A008561F1F006148AE, + 372330A108561F1F006148AE, + 372330A308561F1F006148AE, + 372330A408561F1F006148AE, + 372330A508561F1F006148AE, + 372330A708561F1F006148AE, + 372330A808561F1F006148AE, + 372330A908561F1F006148AE, + 372330AA08561F1F006148AE, + 372330AB08561F1F006148AE, + 372330AC08561F1F006148AE, + 372330AD08561F1F006148AE, + 372330AE08561F1F006148AE, + 372330AF08561F1F006148AE, + 372330B008561F1F006148AE, + 372330B108561F1F006148AE, + 372330B208561F1F006148AE, + 372330B308561F1F006148AE, + 372330B408561F1F006148AE, + 372330B508561F1F006148AE, + 372330B608561F1F006148AE, + 372330B708561F1F006148AE, + 372330B808561F1F006148AE, + 372330B908561F1F006148AE, + 372330BA08561F1F006148AE, + 372330BB08561F1F006148AE, + 372330BC08561F1F006148AE, + 372330BD08561F1F006148AE, + 372330BE08561F1F006148AE, + 372330BF08561F1F006148AE, + 372330C008561F1F006148AE, + 372330C208561F1F006148AE, + 372330C308561F1F006148AE, + 372330C408561F1F006148AE, + D61F2E61054CD45E003A923B, + D6A7A2F8054CD1C100F1D5A3, + D6A7A2FB054CD1C100F1D5A3, + D6A7A2FC054CD1C100F1D5A3, + D6A7A2FD054CD1C100F1D5A3, + D6A7A2FE054CD1C100F1D5A3, + D6A7A2FF054CD1C100F1D5A3, + D6A7A300054CD1C100F1D5A3, + D6A7A301054CD1C100F1D5A3, + D6A7A302054CD1C100F1D5A3, + D6A7A303054CD1C100F1D5A3, + D6A7A304054CD1C100F1D5A3, + D6A7A305054CD1C100F1D5A3, + D6A7A307054CD1C100F1D5A3, + D6A7A308054CD1C100F1D5A3, + D6A7A309054CD1C100F1D5A3, + D6A7A30A054CD1C100F1D5A3, + D6A7A30B054CD1C100F1D5A3, + D6A7A30D054CD1C100F1D5A3, + D6A7A30E054CD1C100F1D5A3, + D6A7A30F054CD1C100F1D5A3, + D6A7A312054CD1C100F1D5A3, + D6A7A314054CD1C100F1D5A3, + D6A7A315054CD1C100F1D5A3, + D6A7A316054CD1C100F1D5A3, + D6A7A318054CD1C100F1D5A3, + D6A7A319054CD1C100F1D5A3, + D6A7A31A054CD1C100F1D5A3, + D6A7A31B054CD1C100F1D5A3, + D6A7A31C054CD1C100F1D5A3, + D6A7A31D054CD1C100F1D5A3, + D6A7A31E054CD1C100F1D5A3, + D6A7A320054CD1C100F1D5A3, + D6A7A321054CD1C100F1D5A3, + D6A7A322054CD1C100F1D5A3, + D6A7A323054CD1C100F1D5A3, + D6A7A327054CD1C100F1D5A3, + D6A7A328054CD1C100F1D5A3, + D6A7A329054CD1C100F1D5A3, + D6A7A32B054CD1C100F1D5A3, + D6A7A32C054CD1C100F1D5A3, + D6A7A32D054CD1C100F1D5A3, + D6A7A32E054CD1C100F1D5A3, + D6A7A32F054CD1C100F1D5A3, + D6A7A330054CD1C100F1D5A3, + D6A7A331054CD1C100F1D5A3, + D6A7A332054CD1C100F1D5A3, + D6A7A333054CD1C100F1D5A3, + D6A7A334054CD1C100F1D5A3, + D6A7A335054CD1C100F1D5A3, + D6A7A336054CD1C100F1D5A3, + D6A7A337054CD1C100F1D5A3, + D6A7A338054CD1C100F1D5A3, + D6A7A339054CD1C100F1D5A3, + D6A7A33A054CD1C100F1D5A3, + D6A7A33B054CD1C100F1D5A3, + D6A7A33C054CD1C100F1D5A3, + D6A7A33D054CD1C100F1D5A3, + D6A7A33E054CD1C100F1D5A3, + D6A7A33F054CD1C100F1D5A3, + D6A7A340054CD1C100F1D5A3, + D6A7A341054CD1C100F1D5A3, + D6A7A342054CD1C100F1D5A3, + D6A7A343054CD1C100F1D5A3, + D6A7A344054CD1C100F1D5A3, + D6A7A345054CD1C100F1D5A3, + D6A7A346054CD1C100F1D5A3, + D6A7A347054CD1C100F1D5A3, + D6A7A348054CD1C100F1D5A3, + D6A7A349054CD1C100F1D5A3, + D6A7A34B054CD1C100F1D5A3, + D6A7A34C054CD1C100F1D5A3, + D6A7A34D054CD1C100F1D5A3, + D6A7A34E054CD1C100F1D5A3, + D6A7A34F054CD1C100F1D5A3, + D6A7A351054CD1C100F1D5A3, + D6A7A352054CD1C100F1D5A3, + D6A7A353054CD1C100F1D5A3, + D6A7A354054CD1C100F1D5A3, + D6A7A355054CD1C100F1D5A3, + D6A7A356054CD1C100F1D5A3, + D6A7A357054CD1C100F1D5A3, + D6A7A358054CD1C100F1D5A3, + D6A7A359054CD1C100F1D5A3, + D6A7A35A054CD1C100F1D5A3, + D6A7A35B054CD1C100F1D5A3, + D6A7A35C054CD1C100F1D5A3, + D6A7A35D054CD1C100F1D5A3, + D6A7A35E054CD1C100F1D5A3, + D6A7A35F054CD1C100F1D5A3, + D6A7A360054CD1C100F1D5A3, + D6A7A361054CD1C100F1D5A3, + D6A7A362054CD1C100F1D5A3, + D6A7A363054CD1C100F1D5A3, + D6A7A364054CD1C100F1D5A3, + D6A7A365054CD1C100F1D5A3, + D6A7A367054CD1C100F1D5A3, + D6A7A368054CD1C100F1D5A3, + D6A7A369054CD1C100F1D5A3, + D6A7A36B054CD1C100F1D5A3, + D6A7A36C054CD1C100F1D5A3, + D6A7A36D054CD1C100F1D5A3, + D6A7A36E054CD1C100F1D5A3, + D6A7A36F054CD1C100F1D5A3, + D6A7A370054CD1C100F1D5A3, + D6A7A371054CD1C100F1D5A3, + D6A7A372054CD1C100F1D5A3, + D6A7A373054CD1C100F1D5A3, + D6A7A375054CD1C100F1D5A3, + D6A7A376054CD1C100F1D5A3, + D6A7A377054CD1C100F1D5A3, + D6A7A378054CD1C100F1D5A3, + D6A7A379054CD1C100F1D5A3, + D6A7A37B054CD1C100F1D5A3, + D6A7A37C054CD1C100F1D5A3, + D6A7A37D054CD1C100F1D5A3, + D6A7A37E054CD1C100F1D5A3, + D6A7A37F054CD1C100F1D5A3, + D6A7A384054CD1C100F1D5A3, + D6A7A385054CD1C100F1D5A3, + D6A7A386054CD1C100F1D5A3, + D6A7A387054CD1C100F1D5A3, + D6A7A388054CD1C100F1D5A3, + D6A7A389054CD1C100F1D5A3, + D6A7A38B054CD1C100F1D5A3, + D6A7A38C054CD1C100F1D5A3, + D6A7A38D054CD1C100F1D5A3, + D6A7A38E054CD1C100F1D5A3, + D6A7A38F054CD1C100F1D5A3, + D6A7A390054CD1C100F1D5A3, + D6A7A395054CD1C100F1D5A3, + D6A7A396054CD1C100F1D5A3, + D6A7A397054CD1C100F1D5A3, + D6A7A398054CD1C100F1D5A3, + D6A7A399054CD1C100F1D5A3, + D6A7A39A054CD1C100F1D5A3, + D6A7A39B054CD1C100F1D5A3, + D6A7A39C054CD1C100F1D5A3, + D6A7A39F054CD1C100F1D5A3, + D6A7A3A0054CD1C100F1D5A3, + D6A7A3A1054CD1C100F1D5A3, + D6A7A3A3054CD1C100F1D5A3, + D6A7A3A4054CD1C100F1D5A3, + ); + isa = PBXGroup; + name = Resiprocate; + path = resiprocate; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2F2054CD1A000F1D5A3 = { + buildActionMask = 2147483647; + files = ( + D6A7A3A5054CD1C100F1D5A3, + D6A7A3A8054CD1C100F1D5A3, + D6A7A3AA054CD1C100F1D5A3, + D6A7A3AB054CD1C100F1D5A3, + D6A7A3AC054CD1C100F1D5A3, + D6A7A3AE054CD1C100F1D5A3, + D6A7A3B0054CD1C100F1D5A3, + D6A7A3B7054CD1C100F1D5A3, + D6A7A3B8054CD1C100F1D5A3, + D6A7A3BA054CD1C100F1D5A3, + D6A7A3BC054CD1C100F1D5A3, + D6A7A3C1054CD1C100F1D5A3, + D6A7A3C2054CD1C100F1D5A3, + D6A7A3C3054CD1C100F1D5A3, + D6A7A3C5054CD1C100F1D5A3, + D6A7A3C9054CD1C100F1D5A3, + D6A7A3CB054CD1C100F1D5A3, + D6A7A3CD054CD1C100F1D5A3, + D6A7A3CE054CD1C100F1D5A3, + D6A7A3D0054CD1C100F1D5A3, + D6A7A3D4054CD1C100F1D5A3, + D6A7A3D5054CD1C100F1D5A3, + D6A7A3D8054CD1C100F1D5A3, + D6A7A3DA054CD1C100F1D5A3, + D6A7A3DC054CD1C100F1D5A3, + D6A7A3DE054CD1C100F1D5A3, + D6A7A3DF054CD1C100F1D5A3, + D6A7A3E1054CD1C100F1D5A3, + D6A7A3E3054CD1C100F1D5A3, + D6A7A3E4054CD1C100F1D5A3, + D6A7A3E5054CD1C100F1D5A3, + D6A7A3E7054CD1C100F1D5A3, + D6A7A3E9054CD1C100F1D5A3, + D6A7A3EB054CD1C100F1D5A3, + D6A7A3ED054CD1C100F1D5A3, + D6A7A3F0054CD1C100F1D5A3, + D6A7A3F2054CD1C100F1D5A3, + D6A7A3F4054CD1C100F1D5A3, + D6A7A3F6054CD1C100F1D5A3, + D6A7A3F8054CD1C100F1D5A3, + D6A7A3FA054CD1C100F1D5A3, + D6A7A3FB054CD1C100F1D5A3, + D6A7A3FF054CD1C100F1D5A3, + D6A7A401054CD1C100F1D5A3, + D6A7A402054CD1C100F1D5A3, + D6A7A404054CD1C100F1D5A3, + D6A7A405054CD1C100F1D5A3, + D6A7A406054CD1C100F1D5A3, + D6A7A408054CD1C100F1D5A3, + D6A7A409054CD1C100F1D5A3, + D6A7A40B054CD1C100F1D5A3, + D6A7A40D054CD1C100F1D5A3, + D6A7A40F054CD1C100F1D5A3, + D6A7A411054CD1C100F1D5A3, + D6A7A414054CD1C100F1D5A3, + D6A7A418054CD1C100F1D5A3, + D6A7A41A054CD1C100F1D5A3, + D6A7A41C054CD1C100F1D5A3, + D6A7A41E054CD1C100F1D5A3, + D6A7A420054CD1C100F1D5A3, + D6A7A422054CD1C100F1D5A3, + D6A7A424054CD1C100F1D5A3, + D6A7A426054CD1C100F1D5A3, + D6A7A428054CD1C100F1D5A3, + D6A7A42A054CD1C100F1D5A3, + D6A7A431054CD1C100F1D5A3, + D6A7A433054CD1C100F1D5A3, + D6A7A435054CD1C100F1D5A3, + D6A7A438054CD1C100F1D5A3, + D6A7A43A054CD1C100F1D5A3, + D6A7A43C054CD1C100F1D5A3, + D6A7A442054CD1C100F1D5A3, + D6A7A444054CD1C100F1D5A3, + D6A7A447054CD1C100F1D5A3, + D6A7A44C054CD1C100F1D5A3, + D6A7A44E054CD1C100F1D5A3, + D6A7A450054CD1C100F1D5A3, + D61F2EB3054CD49C003A923B, + D61F2EB4054CD49C003A923B, + D61F2EB5054CD49C003A923B, + D61F2EB6054CD49C003A923B, + D61F2EB7054CD49C003A923B, + D61F2EB8054CD49C003A923B, + D61F2EB9054CD49C003A923B, + D61F2EBA054CD49C003A923B, + D61F2EBB054CD49C003A923B, + D61F2EBC054CD49C003A923B, + D61F2EBD054CD49C003A923B, + D61F2EBE054CD49C003A923B, + D61F2EBF054CD49C003A923B, + D61F2EC0054CD49C003A923B, + D61F2EC1054CD49C003A923B, + D61F2EC2054CD49C003A923B, + D61F2EC3054CD49C003A923B, + D61F2EC4054CD49C003A923B, + D61F2EC5054CD49C003A923B, + D61F2EC6054CD49C003A923B, + D61F2EC7054CD49C003A923B, + D61F2EC8054CD49C003A923B, + D61F2EC9054CD49C003A923B, + D61F2ECA054CD49C003A923B, + D61F2ECB054CD49C003A923B, + D61F2ECC054CD49C003A923B, + D61F2ECD054CD49C003A923B, + D61F2ECE054CD49C003A923B, + D61F2ECF054CD49C003A923B, + D61F2ED0054CD49C003A923B, + D61F2ED1054CD49C003A923B, + D61F2ED2054CD49C003A923B, + D61F2ED3054CD49C003A923B, + D61F2ED4054CD49C003A923B, + D61F2ED5054CD49C003A923B, + 3723310808562889006148AE, + 3723310D08562890006148AE, + 3723310E085628A3006148AE, + 3723310F085628A4006148AE, + 37233110085628A5006148AE, + 37233111085628A7006148AE, + 37233112085628A8006148AE, + 37233113085628A8006148AE, + 37233114085628A9006148AE, + 37233115085628AC006148AE, + 37233116085628AE006148AE, + 37233117085628AF006148AE, + 37233118085628B2006148AE, + 37233119085628B3006148AE, + 3723314F0856290A006148AE, + 372331500856290B006148AE, + 372331510856290B006148AE, + 372331520856290C006148AE, + 372331530856290E006148AE, + 372331540856290E006148AE, + 372331550856290F006148AE, + 372331560856290F006148AE, + 3723315708562910006148AE, + 3723315808562911006148AE, + 3723315908562911006148AE, + 3723315A08562912006148AE, + 3723315B08562915006148AE, + 3723315C08562916006148AE, + 3723315D08562916006148AE, + 3723315E08562917006148AE, + 3723315F08562918006148AE, + 3723316008562918006148AE, + 3723316108562919006148AE, + 372331620856291A006148AE, + 372331630856291B006148AE, + 372331640856291D006148AE, + 372331650856291D006148AE, + 372331660856291E006148AE, + 372331670856291F006148AE, + 3723316808562920006148AE, + 3723316908562921006148AE, + 3723316A08562924006148AE, + 3723316B08562925006148AE, + 3723316C08562926006148AE, + 3723316D08562927006148AE, + 3723316E0856292A006148AE, + 3723316F0856292A006148AE, + 372331700856292C006148AE, + 372331710856292D006148AE, + 372331720856292E006148AE, + 372331730856292E006148AE, + 3723317408562931006148AE, + 3723317508562933006148AE, + 3723317608562935006148AE, + 3723317708562935006148AE, + 3723317808562936006148AE, + 3723317908562937006148AE, + 3723317A08562938006148AE, + 3723317B0856293A006148AE, + 3723317C0856293A006148AE, + 3723317D0856293B006148AE, + 3723317E0856293B006148AE, + 3723317F0856293C006148AE, + 372331800856293D006148AE, + 372331810856293E006148AE, + 372331820856293F006148AE, + 3767C6AB085654DD008F581F, + 3767C6AD085654DD008F581F, + 3767C6AF085654DD008F581F, + 3767C6B1085654DD008F581F, + 3767C6B2085654DD008F581F, + 3767C6B4085654DD008F581F, + 3767C6B6085654DD008F581F, + 3767C6B8085654DD008F581F, + 3767C6BA085654DD008F581F, + 3767C6BB085654DD008F581F, + 3767C6BD085654DD008F581F, + 3767C6BF085654DD008F581F, + 3767C6C1085654DD008F581F, + 3767C6D508565616008F581F, + 3767C6D608565616008F581F, + 3767C6D708565616008F581F, + 3767C6D908565616008F581F, + 3767C6DB08565616008F581F, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + D6A7A2F3054CD1A000F1D5A3 = { + buildActionMask = 2147483647; + files = ( + D6A7A3A9054CD1C100F1D5A3, + D6A7A3AD054CD1C100F1D5A3, + D6A7A3AF054CD1C100F1D5A3, + D6A7A3B1054CD1C100F1D5A3, + D6A7A3B2054CD1C100F1D5A3, + D6A7A3B4054CD1C100F1D5A3, + D6A7A3B5054CD1C100F1D5A3, + D6A7A3B6054CD1C100F1D5A3, + D6A7A3BB054CD1C100F1D5A3, + D6A7A3BF054CD1C100F1D5A3, + D6A7A3C6054CD1C100F1D5A3, + D6A7A3C7054CD1C100F1D5A3, + D6A7A3C8054CD1C100F1D5A3, + D6A7A3CA054CD1C100F1D5A3, + D6A7A3CF054CD1C100F1D5A3, + D6A7A3D6054CD1C100F1D5A3, + D6A7A3D9054CD1C100F1D5A3, + D6A7A3DB054CD1C100F1D5A3, + D6A7A3DD054CD1C100F1D5A3, + D6A7A3E0054CD1C100F1D5A3, + D6A7A3E2054CD1C100F1D5A3, + D6A7A3E6054CD1C100F1D5A3, + D6A7A3E8054CD1C100F1D5A3, + D6A7A3EA054CD1C100F1D5A3, + D6A7A3EC054CD1C100F1D5A3, + D6A7A3EE054CD1C100F1D5A3, + D6A7A3EF054CD1C100F1D5A3, + D6A7A3F1054CD1C100F1D5A3, + D6A7A3F3054CD1C100F1D5A3, + D6A7A3F5054CD1C100F1D5A3, + D6A7A3F9054CD1C100F1D5A3, + D6A7A3FC054CD1C100F1D5A3, + D6A7A3FE054CD1C100F1D5A3, + D6A7A400054CD1C100F1D5A3, + D6A7A403054CD1C100F1D5A3, + D6A7A407054CD1C100F1D5A3, + D6A7A40A054CD1C100F1D5A3, + D6A7A40C054CD1C100F1D5A3, + D6A7A40E054CD1C100F1D5A3, + D6A7A410054CD1C100F1D5A3, + D6A7A412054CD1C100F1D5A3, + D6A7A415054CD1C100F1D5A3, + D6A7A416054CD1C100F1D5A3, + D6A7A419054CD1C100F1D5A3, + D6A7A41B054CD1C100F1D5A3, + D6A7A41D054CD1C100F1D5A3, + D6A7A41F054CD1C100F1D5A3, + D6A7A423054CD1C100F1D5A3, + D6A7A425054CD1C100F1D5A3, + D6A7A429054CD1C100F1D5A3, + D6A7A42B054CD1C100F1D5A3, + D6A7A42C054CD1C100F1D5A3, + D6A7A432054CD1C100F1D5A3, + D6A7A434054CD1C100F1D5A3, + D6A7A436054CD1C100F1D5A3, + D6A7A439054CD1C100F1D5A3, + D6A7A43B054CD1C100F1D5A3, + D6A7A43D054CD1C100F1D5A3, + D6A7A443054CD1C100F1D5A3, + D6A7A445054CD1C100F1D5A3, + D6A7A446054CD1C100F1D5A3, + D6A7A448054CD1C100F1D5A3, + D6A7A449054CD1C100F1D5A3, + D6A7A44D054CD1C100F1D5A3, + D6A7A451054CD1C100F1D5A3, + D61F2E79054CD488003A923B, + D61F2E7A054CD488003A923B, + D61F2E7B054CD488003A923B, + D61F2E7C054CD488003A923B, + D61F2E7D054CD488003A923B, + D61F2E7E054CD488003A923B, + D61F2E7F054CD488003A923B, + D61F2E80054CD488003A923B, + D61F2E81054CD488003A923B, + D61F2E82054CD488003A923B, + D61F2E83054CD488003A923B, + D61F2E84054CD488003A923B, + D61F2E85054CD488003A923B, + D61F2E86054CD488003A923B, + D61F2E87054CD488003A923B, + D61F2E88054CD488003A923B, + D61F2E89054CD488003A923B, + D61F2E8A054CD488003A923B, + D61F2E8B054CD488003A923B, + D61F2E8D054CD488003A923B, + D61F2E8E054CD488003A923B, + D61F2E8F054CD488003A923B, + 3723310608562887006148AE, + 3723310708562888006148AE, + 372331090856288A006148AE, + 3723310A0856288B006148AE, + 3723310B0856288F006148AE, + 3723310C0856288F006148AE, + 3723311A085628BB006148AE, + 3723311B085628BC006148AE, + 3723311C085628BE006148AE, + 3723311D085628C0006148AE, + 3723311E085628C2006148AE, + 3723311F085628C2006148AE, + 37233120085628C3006148AE, + 37233121085628C4006148AE, + 37233122085628C6006148AE, + 37233123085628C8006148AE, + 37233124085628C9006148AE, + 37233125085628CD006148AE, + 37233126085628CE006148AE, + 37233127085628D1006148AE, + 37233128085628D2006148AE, + 3723312A085628D3006148AE, + 3723312B085628D4006148AE, + 3723312C085628D7006148AE, + 3723312D085628D8006148AE, + 3723312E085628DD006148AE, + 3723312F085628DE006148AE, + 37233130085628DF006148AE, + 37233131085628E0006148AE, + 37233132085628E0006148AE, + 37233133085628E1006148AE, + 37233135085628E4006148AE, + 37233136085628E4006148AE, + 37233137085628E5006148AE, + 37233138085628E6006148AE, + 37233139085628E6006148AE, + 3723313A085628EA006148AE, + 3723313B085628EB006148AE, + 3723313C085628EB006148AE, + 3723313D085628EC006148AE, + 3723313E085628EC006148AE, + 3723313F085628ED006148AE, + 37233140085628EE006148AE, + 37233142085628F0006148AE, + 37233143085628F0006148AE, + 37233144085628F1006148AE, + 37233145085628F1006148AE, + 37233146085628F4006148AE, + 37233147085628F5006148AE, + 37233148085628F6006148AE, + 37233149085628F7006148AE, + 3723314A085628F8006148AE, + 3723314B085628F9006148AE, + 3723314C085628FA006148AE, + 3723314D085628FB006148AE, + 3723314E085628FC006148AE, + 3767C6AA085654DD008F581F, + 3767C6AC085654DD008F581F, + 3767C6AE085654DD008F581F, + 3767C6B0085654DD008F581F, + 3767C6B3085654DD008F581F, + 3767C6B5085654DD008F581F, + 3767C6B7085654DD008F581F, + 3767C6B9085654DD008F581F, + 3767C6BC085654DD008F581F, + 3767C6BE085654DD008F581F, + 3767C6C0085654DD008F581F, + 3767C6D808565616008F581F, + 3767C6DA08565616008F581F, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + D6A7A2F4054CD1A000F1D5A3 = { + buildPhases = ( + D6A7A2F2054CD1A000F1D5A3, + D6A7A2F3054CD1A000F1D5A3, + ); + buildRules = ( + ); + buildSettings = { + GCC_ENABLE_CPP_EXCEPTIONS = YES; + GCC_PREPROCESSOR_DEFINITIONS = "USE_SSL USE_IPV6 USE_ARES"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + HEADER_SEARCH_PATHS = ./; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = STATIC; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = resiprocate; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + D6C18013054CD29700491827, + ); + isa = PBXNativeTarget; + name = resiprocate; + productName = resiprocate; + productReference = D6A7A2F5054CD1A000F1D5A3; + productType = "com.apple.product-type.library.static"; + }; + D6A7A2F5054CD1A000F1D5A3 = { + explicitFileType = archive.ar; + includeInIndex = 0; + isa = PBXFileReference; + path = libresiprocate.a; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + D6A7A2F8054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = LazyParser.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2FB054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = SipMessageExplicit.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2FC054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ParseUtil.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2FD054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ParserContainerBase.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2FE054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ParserContainer.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A2FF054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Subscription.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A300054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Subscription.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A301054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = StatelessHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A302054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = StatelessHandler.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A303054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = SipStack.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A304054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = SipStack.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A305054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = DnsResult.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A307054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ConnectionManager.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A308054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = DataParameter.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A309054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = HeaderHash.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A30A054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = HeaderFieldValueList.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A30B054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = HeaderHash.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A30D054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Embedded.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A30E054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Embedded.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A30F054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ConnectionManager.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A312054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = MethodHash.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A314054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = MessageWaitingContents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A315054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = BranchParameter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A316054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ApplicationSip.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A318054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = SipMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A319054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = SipMessage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A31A054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = FloatParameter.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A31B054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Connection.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A31C054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ExistsParameter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A31D054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ExistsParameter.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A31E054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = DnsResult.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A320054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = DataParameter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A321054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = SipFrag.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A322054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = SipFrag.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A323054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ShutdownMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A327054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = DnsHandler.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A328054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Symbols.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A329054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Symbols.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A32B054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Contents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A32C054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TimerMessage.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A32D054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TcpTransport.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A32E054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TcpTransport.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A32F054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = GenericContents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A330054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = GenericContents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A331054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = DnsInterface.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A332054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ParserCategory.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A333054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ParserCategory.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A334054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ParserCategories.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A335054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ParserCategories.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A336054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ParseException.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A337054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ParameterTypes.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A338054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Parameter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A339054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Parameter.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A33A054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = OctetContents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A33B054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = OctetContents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A33C054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = MultipartSignedContents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A33D054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = MultipartSignedContents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A33E054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = MultipartMixedContents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A33F054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = MultipartMixedContents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A340054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = MsgHeaderScanner.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A341054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = MsgHeaderScanner.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A342054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = LazyParser.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A343054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = IntegerParameter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A344054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = IntegerParameter.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A345054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Helper.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A346054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Helper.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A347054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = HeaderTypes.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A348054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = HeaderFieldValueList.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A349054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = HeaderFieldValue.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A34B054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Connection.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A34C054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ParameterTypes.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A34D054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ParameterTypeEnums.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A34E054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ParameterHash.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A34F054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = ParameterHash.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A351054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = BranchParameter.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A352054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Pidf.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A353054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Pidf.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A354054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = ParseUtil.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A355054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TimerQueue.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A356054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TimerQueue.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A357054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TimerMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A358054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TransportMessage.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A359054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Transport.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A35A054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Transport.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A35B054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TransactionTerminated.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A35C054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TransactionState.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A35D054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TransactionState.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A35E054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TransactionMap.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A35F054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TransactionMap.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A360054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TransactionController.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A361054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TransactionController.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A362054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TlsTransport.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A363054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = HeaderTypes.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A364054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Headers.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A365054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Headers.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A367054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = XMLCursor.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A368054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = XMLCursor.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A369054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = DnsInterface.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A36B054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TuIM.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A36C054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TuIM.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A36D054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TransportSelector.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A36E054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TransportSelector.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A36F054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TcpConnection.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A370054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TcpConnection.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A371054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TcpBaseTransport.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A372054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TcpBaseTransport.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A373054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = FloatParameter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A375054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = MethodTypes.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A376054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = MethodTypes.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A377054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = MethodHash.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A378054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = UnknownParameter.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A379054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = UnknownHeaderType.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A37B054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = UdpTransport.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A37C054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TlsTransport.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A37D054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = TlsConnection.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A37E054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = TlsConnection.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A37F054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = UdpTransport.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A384054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Security.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A385054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Security.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A386054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = SdpContents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A387054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = SdpContents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A388054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = RportParameter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A389054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = RportParameter.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A38B054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Registration.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A38C054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Registration.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A38D054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = QuotedDataParameter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A38E054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = QuotedDataParameter.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A38F054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = QopParameter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A390054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = QopParameter.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A395054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = PlainContents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A396054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = PlainContents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A397054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Pkcs7Contents.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A398054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Pkcs7Contents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A399054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = MessageWaitingContents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A39A054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Message.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A39B054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Message.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A39C054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = HeaderFieldValue.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A39F054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = Uri.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A3A0054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Uri.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A3A1054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = UnknownParameterType.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A3A3054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.h; + path = UnknownParameter.hxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A3A4054CD1C100F1D5A3 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + path = Contents.cxx; + refType = 4; + sourceTree = "<group>"; + }; + D6A7A3A5054CD1C100F1D5A3 = { + fileRef = D6A7A2F8054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3A8054CD1C100F1D5A3 = { + fileRef = D6A7A2FB054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3A9054CD1C100F1D5A3 = { + fileRef = D6A7A2FC054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3AA054CD1C100F1D5A3 = { + fileRef = D6A7A2FD054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3AB054CD1C100F1D5A3 = { + fileRef = D6A7A2FE054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3AC054CD1C100F1D5A3 = { + fileRef = D6A7A2FF054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3AD054CD1C100F1D5A3 = { + fileRef = D6A7A300054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3AE054CD1C100F1D5A3 = { + fileRef = D6A7A301054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3AF054CD1C100F1D5A3 = { + fileRef = D6A7A302054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3B0054CD1C100F1D5A3 = { + fileRef = D6A7A303054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3B1054CD1C100F1D5A3 = { + fileRef = D6A7A304054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3B2054CD1C100F1D5A3 = { + fileRef = D6A7A305054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3B4054CD1C100F1D5A3 = { + fileRef = D6A7A307054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3B5054CD1C100F1D5A3 = { + fileRef = D6A7A308054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3B6054CD1C100F1D5A3 = { + fileRef = D6A7A309054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3B7054CD1C100F1D5A3 = { + fileRef = D6A7A30A054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3B8054CD1C100F1D5A3 = { + fileRef = D6A7A30B054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3BA054CD1C100F1D5A3 = { + fileRef = D6A7A30D054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3BB054CD1C100F1D5A3 = { + fileRef = D6A7A30E054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3BC054CD1C100F1D5A3 = { + fileRef = D6A7A30F054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3BF054CD1C100F1D5A3 = { + fileRef = D6A7A312054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3C1054CD1C100F1D5A3 = { + fileRef = D6A7A314054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3C2054CD1C100F1D5A3 = { + fileRef = D6A7A315054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3C3054CD1C100F1D5A3 = { + fileRef = D6A7A316054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3C5054CD1C100F1D5A3 = { + fileRef = D6A7A318054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3C6054CD1C100F1D5A3 = { + fileRef = D6A7A319054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3C7054CD1C100F1D5A3 = { + fileRef = D6A7A31A054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3C8054CD1C100F1D5A3 = { + fileRef = D6A7A31B054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3C9054CD1C100F1D5A3 = { + fileRef = D6A7A31C054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3CA054CD1C100F1D5A3 = { + fileRef = D6A7A31D054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3CB054CD1C100F1D5A3 = { + fileRef = D6A7A31E054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3CD054CD1C100F1D5A3 = { + fileRef = D6A7A320054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3CE054CD1C100F1D5A3 = { + fileRef = D6A7A321054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3CF054CD1C100F1D5A3 = { + fileRef = D6A7A322054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3D0054CD1C100F1D5A3 = { + fileRef = D6A7A323054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3D4054CD1C100F1D5A3 = { + fileRef = D6A7A327054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3D5054CD1C100F1D5A3 = { + fileRef = D6A7A328054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3D6054CD1C100F1D5A3 = { + fileRef = D6A7A329054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3D8054CD1C100F1D5A3 = { + fileRef = D6A7A32B054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3D9054CD1C100F1D5A3 = { + fileRef = D6A7A32C054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3DA054CD1C100F1D5A3 = { + fileRef = D6A7A32D054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3DB054CD1C100F1D5A3 = { + fileRef = D6A7A32E054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3DC054CD1C100F1D5A3 = { + fileRef = D6A7A32F054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3DD054CD1C100F1D5A3 = { + fileRef = D6A7A330054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3DE054CD1C100F1D5A3 = { + fileRef = D6A7A331054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3DF054CD1C100F1D5A3 = { + fileRef = D6A7A332054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3E0054CD1C100F1D5A3 = { + fileRef = D6A7A333054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3E1054CD1C100F1D5A3 = { + fileRef = D6A7A334054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3E2054CD1C100F1D5A3 = { + fileRef = D6A7A335054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3E3054CD1C100F1D5A3 = { + fileRef = D6A7A336054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3E4054CD1C100F1D5A3 = { + fileRef = D6A7A337054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3E5054CD1C100F1D5A3 = { + fileRef = D6A7A338054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3E6054CD1C100F1D5A3 = { + fileRef = D6A7A339054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3E7054CD1C100F1D5A3 = { + fileRef = D6A7A33A054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3E8054CD1C100F1D5A3 = { + fileRef = D6A7A33B054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3E9054CD1C100F1D5A3 = { + fileRef = D6A7A33C054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3EA054CD1C100F1D5A3 = { + fileRef = D6A7A33D054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3EB054CD1C100F1D5A3 = { + fileRef = D6A7A33E054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3EC054CD1C100F1D5A3 = { + fileRef = D6A7A33F054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3ED054CD1C100F1D5A3 = { + fileRef = D6A7A340054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3EE054CD1C100F1D5A3 = { + fileRef = D6A7A341054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3EF054CD1C100F1D5A3 = { + fileRef = D6A7A342054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3F0054CD1C100F1D5A3 = { + fileRef = D6A7A343054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3F1054CD1C100F1D5A3 = { + fileRef = D6A7A344054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3F2054CD1C100F1D5A3 = { + fileRef = D6A7A345054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3F3054CD1C100F1D5A3 = { + fileRef = D6A7A346054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3F4054CD1C100F1D5A3 = { + fileRef = D6A7A347054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3F5054CD1C100F1D5A3 = { + fileRef = D6A7A348054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3F6054CD1C100F1D5A3 = { + fileRef = D6A7A349054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3F8054CD1C100F1D5A3 = { + fileRef = D6A7A34B054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3F9054CD1C100F1D5A3 = { + fileRef = D6A7A34C054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3FA054CD1C100F1D5A3 = { + fileRef = D6A7A34D054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3FB054CD1C100F1D5A3 = { + fileRef = D6A7A34E054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3FC054CD1C100F1D5A3 = { + fileRef = D6A7A34F054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3FE054CD1C100F1D5A3 = { + fileRef = D6A7A351054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A3FF054CD1C100F1D5A3 = { + fileRef = D6A7A352054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A400054CD1C100F1D5A3 = { + fileRef = D6A7A353054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A401054CD1C100F1D5A3 = { + fileRef = D6A7A354054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A402054CD1C100F1D5A3 = { + fileRef = D6A7A355054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A403054CD1C100F1D5A3 = { + fileRef = D6A7A356054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A404054CD1C100F1D5A3 = { + fileRef = D6A7A357054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A405054CD1C100F1D5A3 = { + fileRef = D6A7A358054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A406054CD1C100F1D5A3 = { + fileRef = D6A7A359054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A407054CD1C100F1D5A3 = { + fileRef = D6A7A35A054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A408054CD1C100F1D5A3 = { + fileRef = D6A7A35B054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A409054CD1C100F1D5A3 = { + fileRef = D6A7A35C054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A40A054CD1C100F1D5A3 = { + fileRef = D6A7A35D054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A40B054CD1C100F1D5A3 = { + fileRef = D6A7A35E054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A40C054CD1C100F1D5A3 = { + fileRef = D6A7A35F054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A40D054CD1C100F1D5A3 = { + fileRef = D6A7A360054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A40E054CD1C100F1D5A3 = { + fileRef = D6A7A361054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A40F054CD1C100F1D5A3 = { + fileRef = D6A7A362054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A410054CD1C100F1D5A3 = { + fileRef = D6A7A363054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A411054CD1C100F1D5A3 = { + fileRef = D6A7A364054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A412054CD1C100F1D5A3 = { + fileRef = D6A7A365054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A414054CD1C100F1D5A3 = { + fileRef = D6A7A367054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A415054CD1C100F1D5A3 = { + fileRef = D6A7A368054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A416054CD1C100F1D5A3 = { + fileRef = D6A7A369054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A418054CD1C100F1D5A3 = { + fileRef = D6A7A36B054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A419054CD1C100F1D5A3 = { + fileRef = D6A7A36C054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A41A054CD1C100F1D5A3 = { + fileRef = D6A7A36D054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A41B054CD1C100F1D5A3 = { + fileRef = D6A7A36E054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A41C054CD1C100F1D5A3 = { + fileRef = D6A7A36F054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A41D054CD1C100F1D5A3 = { + fileRef = D6A7A370054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A41E054CD1C100F1D5A3 = { + fileRef = D6A7A371054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A41F054CD1C100F1D5A3 = { + fileRef = D6A7A372054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A420054CD1C100F1D5A3 = { + fileRef = D6A7A373054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A422054CD1C100F1D5A3 = { + fileRef = D6A7A375054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A423054CD1C100F1D5A3 = { + fileRef = D6A7A376054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A424054CD1C100F1D5A3 = { + fileRef = D6A7A377054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A425054CD1C100F1D5A3 = { + fileRef = D6A7A378054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A426054CD1C100F1D5A3 = { + fileRef = D6A7A379054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A428054CD1C100F1D5A3 = { + fileRef = D6A7A37B054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A429054CD1C100F1D5A3 = { + fileRef = D6A7A37C054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A42A054CD1C100F1D5A3 = { + fileRef = D6A7A37D054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A42B054CD1C100F1D5A3 = { + fileRef = D6A7A37E054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A42C054CD1C100F1D5A3 = { + fileRef = D6A7A37F054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A431054CD1C100F1D5A3 = { + fileRef = D6A7A384054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A432054CD1C100F1D5A3 = { + fileRef = D6A7A385054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A433054CD1C100F1D5A3 = { + fileRef = D6A7A386054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A434054CD1C100F1D5A3 = { + fileRef = D6A7A387054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A435054CD1C100F1D5A3 = { + fileRef = D6A7A388054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A436054CD1C100F1D5A3 = { + fileRef = D6A7A389054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A438054CD1C100F1D5A3 = { + fileRef = D6A7A38B054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A439054CD1C100F1D5A3 = { + fileRef = D6A7A38C054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A43A054CD1C100F1D5A3 = { + fileRef = D6A7A38D054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A43B054CD1C100F1D5A3 = { + fileRef = D6A7A38E054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A43C054CD1C100F1D5A3 = { + fileRef = D6A7A38F054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A43D054CD1C100F1D5A3 = { + fileRef = D6A7A390054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A442054CD1C100F1D5A3 = { + fileRef = D6A7A395054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A443054CD1C100F1D5A3 = { + fileRef = D6A7A396054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A444054CD1C100F1D5A3 = { + fileRef = D6A7A397054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A445054CD1C100F1D5A3 = { + fileRef = D6A7A398054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A446054CD1C100F1D5A3 = { + fileRef = D6A7A399054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A447054CD1C100F1D5A3 = { + fileRef = D6A7A39A054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A448054CD1C100F1D5A3 = { + fileRef = D6A7A39B054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A449054CD1C100F1D5A3 = { + fileRef = D6A7A39C054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A44C054CD1C100F1D5A3 = { + fileRef = D6A7A39F054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A44D054CD1C100F1D5A3 = { + fileRef = D6A7A3A0054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A44E054CD1C100F1D5A3 = { + fileRef = D6A7A3A1054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A450054CD1C100F1D5A3 = { + fileRef = D6A7A3A3054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A451054CD1C100F1D5A3 = { + fileRef = D6A7A3A4054CD1C100F1D5A3; + isa = PBXBuildFile; + settings = { + }; + }; + D6A7A456054CD1EE00F1D5A3 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + D6A7A457054CD1EE00F1D5A3 = { + buildActionMask = 2147483647; + files = ( + D6E8BE66057C26350044AECA, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + D6A7A458054CD1EE00F1D5A3 = { + buildPhases = ( + D6A7A456054CD1EE00F1D5A3, + D6A7A457054CD1EE00F1D5A3, + ); + buildRules = ( + ); + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = "USE_ARES USE_SSL USE_IPV6"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + HEADER_SEARCH_PATHS = ""; + INSTALL_PATH = /usr/local/bin; + LIBRARY_SEARCH_PATHS = ""; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = "-lresiprocate -lares -lssl -lcrypto"; + OTHER_REZFLAGS = ""; + PREBINDING = YES; + PRODUCT_NAME = limp; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + }; + dependencies = ( + D6C18011054CD28C00491827, + ); + isa = PBXNativeTarget; + name = limp; + productName = limp; + productReference = D6A7A459054CD1EE00F1D5A3; + productType = "com.apple.product-type.tool"; + }; + D6A7A459054CD1EE00F1D5A3 = { + explicitFileType = "compiled.mach-o.executable"; + includeInIndex = 0; + isa = PBXFileReference; + path = limp; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + D6C18010054CD28C00491827 = { + containerPortal = D6A7A290054CCEE800F1D5A3; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = D6A7A2F4054CD1A000F1D5A3; + remoteInfo = resiprocate; + }; + D6C18011054CD28C00491827 = { + isa = PBXTargetDependency; + target = D6A7A2F4054CD1A000F1D5A3; + targetProxy = D6C18010054CD28C00491827; + }; + D6C18012054CD29700491827 = { + containerPortal = D6A7A290054CCEE800F1D5A3; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = D6A7A29D054CCF0E00F1D5A3; + remoteInfo = ares; + }; + D6C18013054CD29700491827 = { + isa = PBXTargetDependency; + target = D6A7A29D054CCF0E00F1D5A3; + targetProxy = D6C18012054CD29700491827; + }; + D6E8BE5F057C25D80044AECA = { + children = ( + D6E8BE64057C26140044AECA, + ); + isa = PBXGroup; + name = Limp; + refType = 4; + sourceTree = "<group>"; + }; + D6E8BE64057C26140044AECA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = limpc.cxx; + path = resiprocate/test/limpc.cxx; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + D6E8BE66057C26350044AECA = { + fileRef = D6E8BE64057C26140044AECA; + isa = PBXBuildFile; + settings = { + }; + }; + }; + rootObject = D6A7A290054CCEE800F1D5A3; +} diff --git a/src/libs/resiprocate/resip/sip.xcodeproj/project.pbxproj b/src/libs/resiprocate/resip/sip.xcodeproj/project.pbxproj new file mode 100644 index 00000000..62194df2 --- /dev/null +++ b/src/libs/resiprocate/resip/sip.xcodeproj/project.pbxproj @@ -0,0 +1,2981 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 12396E3708A2F3C800C5ED5E /* DumFeature.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 12396E3608A2F3C800C5ED5E /* DumFeature.cxx */; }; + 12396E6A08A2F91E00C5ED5E /* OutgoingEvent.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 12396E6908A2F91E00C5ED5E /* OutgoingEvent.cxx */; }; + 12396E6C08A2F93400C5ED5E /* TargetCommand.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 12396E6B08A2F93400C5ED5E /* TargetCommand.cxx */; }; + 123B4D4F089871C90049A5B9 /* DumFeatureChain.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 123B4D4E089871C90049A5B9 /* DumFeatureChain.cxx */; }; + 123B4D53089871F70049A5B9 /* IdentityHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 123B4D52089871F70049A5B9 /* IdentityHandler.cxx */; }; + 123B4D55089872040049A5B9 /* EncryptionRequest.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 123B4D54089872040049A5B9 /* EncryptionRequest.cxx */; }; + 123B4D570898721D0049A5B9 /* DumFeatureMessage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 123B4D560898721D0049A5B9 /* DumFeatureMessage.cxx */; }; + 124D78B2086CC36600BCA5A9 /* ares__close_sockets.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D789C086CC36600BCA5A9 /* ares__close_sockets.c */; }; + 124D78B3086CC36600BCA5A9 /* ares__get_hostent.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D789D086CC36600BCA5A9 /* ares__get_hostent.c */; }; + 124D78B4086CC36600BCA5A9 /* ares__read_line.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D789E086CC36600BCA5A9 /* ares__read_line.c */; }; + 124D78B5086CC36600BCA5A9 /* ares_destroy.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D789F086CC36600BCA5A9 /* ares_destroy.c */; }; + 124D78B6086CC36600BCA5A9 /* ares_expand_name.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78A0086CC36600BCA5A9 /* ares_expand_name.c */; }; + 124D78B7086CC36600BCA5A9 /* ares_fds.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78A1086CC36600BCA5A9 /* ares_fds.c */; }; + 124D78B8086CC36600BCA5A9 /* ares_free_errmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78A2086CC36600BCA5A9 /* ares_free_errmem.c */; }; + 124D78B9086CC36600BCA5A9 /* ares_free_hostent.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78A3086CC36600BCA5A9 /* ares_free_hostent.c */; }; + 124D78BA086CC36600BCA5A9 /* ares_free_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78A4086CC36600BCA5A9 /* ares_free_string.c */; }; + 124D78BB086CC36600BCA5A9 /* ares_gethostbyaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78A5086CC36600BCA5A9 /* ares_gethostbyaddr.c */; }; + 124D78BC086CC36600BCA5A9 /* ares_gethostbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78A6086CC36600BCA5A9 /* ares_gethostbyname.c */; }; + 124D78BD086CC36600BCA5A9 /* ares_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78A7086CC36600BCA5A9 /* ares_init.c */; }; + 124D78BE086CC36600BCA5A9 /* ares_local.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78A8086CC36600BCA5A9 /* ares_local.c */; }; + 124D78BF086CC36600BCA5A9 /* ares_mkquery.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78A9086CC36600BCA5A9 /* ares_mkquery.c */; }; + 124D78C0086CC36600BCA5A9 /* ares_parse_a_reply.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78AA086CC36600BCA5A9 /* ares_parse_a_reply.c */; }; + 124D78C1086CC36600BCA5A9 /* ares_parse_ptr_reply.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78AB086CC36600BCA5A9 /* ares_parse_ptr_reply.c */; }; + 124D78C2086CC36600BCA5A9 /* ares_process.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78AC086CC36600BCA5A9 /* ares_process.c */; }; + 124D78C3086CC36600BCA5A9 /* ares_query.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78AD086CC36600BCA5A9 /* ares_query.c */; }; + 124D78C4086CC36600BCA5A9 /* ares_search.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78AE086CC36600BCA5A9 /* ares_search.c */; }; + 124D78C5086CC36600BCA5A9 /* ares_send.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78AF086CC36600BCA5A9 /* ares_send.c */; }; + 124D78C6086CC36600BCA5A9 /* ares_strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78B0086CC36600BCA5A9 /* ares_strerror.c */; }; + 124D78C7086CC36600BCA5A9 /* ares_timeout.c in Sources */ = {isa = PBXBuildFile; fileRef = 124D78B1086CC36600BCA5A9 /* ares_timeout.c */; }; + 124D792A086CC3CE00BCA5A9 /* ApiCheck.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78CA086CC3CE00BCA5A9 /* ApiCheck.cxx */; }; + 124D792B086CC3CE00BCA5A9 /* AresDns.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78CB086CC3CE00BCA5A9 /* AresDns.cxx */; }; + 124D792C086CC3CE00BCA5A9 /* Auth.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78CC086CC3CE00BCA5A9 /* Auth.cxx */; }; + 124D792D086CC3CE00BCA5A9 /* BranchParameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78CD086CC3CE00BCA5A9 /* BranchParameter.cxx */; }; + 124D792E086CC3CE00BCA5A9 /* CallId.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78CE086CC3CE00BCA5A9 /* CallId.cxx */; }; + 124D792F086CC3CE00BCA5A9 /* Connection.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78CF086CC3CE00BCA5A9 /* Connection.cxx */; }; + 124D7930086CC3CE00BCA5A9 /* ConnectionBase.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78D0086CC3CE00BCA5A9 /* ConnectionBase.cxx */; }; + 124D7931086CC3CE00BCA5A9 /* ConnectionManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78D1086CC3CE00BCA5A9 /* ConnectionManager.cxx */; }; + 124D7932086CC3CE00BCA5A9 /* Contents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78D2086CC3CE00BCA5A9 /* Contents.cxx */; }; + 124D7933086CC3CE00BCA5A9 /* CpimContents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78D3086CC3CE00BCA5A9 /* CpimContents.cxx */; }; + 124D7934086CC3CE00BCA5A9 /* CSeqCategory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78D4086CC3CE00BCA5A9 /* CSeqCategory.cxx */; }; + 124D7935086CC3CE00BCA5A9 /* DataParameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78D5086CC3CE00BCA5A9 /* DataParameter.cxx */; }; + 124D7936086CC3CE00BCA5A9 /* DateCategory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78D6086CC3CE00BCA5A9 /* DateCategory.cxx */; }; + 124D7937086CC3CE00BCA5A9 /* DnsInterface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78D7086CC3CE00BCA5A9 /* DnsInterface.cxx */; }; + 124D7938086CC3CE00BCA5A9 /* DnsResult.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78D8086CC3CE00BCA5A9 /* DnsResult.cxx */; }; + 124D7939086CC3CE00BCA5A9 /* Embedded.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78D9086CC3CE00BCA5A9 /* Embedded.cxx */; }; + 124D793A086CC3CE00BCA5A9 /* ExistsParameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78DA086CC3CE00BCA5A9 /* ExistsParameter.cxx */; }; + 124D793B086CC3CE00BCA5A9 /* ExpiresCategory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78DB086CC3CE00BCA5A9 /* ExpiresCategory.cxx */; }; + 124D793C086CC3CE00BCA5A9 /* ExternalBodyContents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78DC086CC3CE00BCA5A9 /* ExternalBodyContents.cxx */; }; + 124D793D086CC3CE00BCA5A9 /* ExternalDnsFactory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78DD086CC3CE00BCA5A9 /* ExternalDnsFactory.cxx */; }; + 124D793E086CC3CE00BCA5A9 /* FloatParameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78DE086CC3CE00BCA5A9 /* FloatParameter.cxx */; }; + 124D793F086CC3CE00BCA5A9 /* GenericContents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78DF086CC3CE00BCA5A9 /* GenericContents.cxx */; }; + 124D7940086CC3CE00BCA5A9 /* GenericUri.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78E0086CC3CE00BCA5A9 /* GenericUri.cxx */; }; + 124D7941086CC3CE00BCA5A9 /* HeaderFieldValue.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78E1086CC3CE00BCA5A9 /* HeaderFieldValue.cxx */; }; + 124D7942086CC3CE00BCA5A9 /* HeaderFieldValueList.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78E2086CC3CE00BCA5A9 /* HeaderFieldValueList.cxx */; }; + 124D7943086CC3CE00BCA5A9 /* HeaderHash.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78E3086CC3CE00BCA5A9 /* HeaderHash.cxx */; }; + 124D7944086CC3CE00BCA5A9 /* Headers.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78E4086CC3CE00BCA5A9 /* Headers.cxx */; }; + 124D7945086CC3CE00BCA5A9 /* HeaderTypes.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78E5086CC3CE00BCA5A9 /* HeaderTypes.cxx */; }; + 124D7946086CC3CE00BCA5A9 /* Helper.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78E6086CC3CE00BCA5A9 /* Helper.cxx */; }; + 124D7947086CC3CE00BCA5A9 /* IntegerCategory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78E7086CC3CE00BCA5A9 /* IntegerCategory.cxx */; }; + 124D7948086CC3CE00BCA5A9 /* IntegerParameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78E8086CC3CE00BCA5A9 /* IntegerParameter.cxx */; }; + 124D7949086CC3CE00BCA5A9 /* InternalTransport.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78E9086CC3CE00BCA5A9 /* InternalTransport.cxx */; }; + 124D794A086CC3CE00BCA5A9 /* KeepAliveMessage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78EA086CC3CE00BCA5A9 /* KeepAliveMessage.cxx */; }; + 124D794B086CC3CE00BCA5A9 /* LazyParser.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78EB086CC3CE00BCA5A9 /* LazyParser.cxx */; }; + 124D794C086CC3CE00BCA5A9 /* MacSecurity.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78EC086CC3CE00BCA5A9 /* MacSecurity.cxx */; }; + 124D794D086CC3CE00BCA5A9 /* Message.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78ED086CC3CE00BCA5A9 /* Message.cxx */; }; + 124D794E086CC3CE00BCA5A9 /* MessageFilterRule.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78EE086CC3CE00BCA5A9 /* MessageFilterRule.cxx */; }; + 124D794F086CC3CE00BCA5A9 /* MessageWaitingContents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78EF086CC3CE00BCA5A9 /* MessageWaitingContents.cxx */; }; + 124D7950086CC3CE00BCA5A9 /* MethodHash.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78F0086CC3CE00BCA5A9 /* MethodHash.cxx */; }; + 124D7951086CC3CE00BCA5A9 /* MethodTypes.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78F1086CC3CE00BCA5A9 /* MethodTypes.cxx */; }; + 124D7952086CC3CE00BCA5A9 /* Mime.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78F2086CC3CE00BCA5A9 /* Mime.cxx */; }; + 124D7953086CC3CE00BCA5A9 /* MsgHeaderScanner.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78F3086CC3CE00BCA5A9 /* MsgHeaderScanner.cxx */; }; + 124D7954086CC3CE00BCA5A9 /* MultipartAlternativeContents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78F4086CC3CE00BCA5A9 /* MultipartAlternativeContents.cxx */; }; + 124D7955086CC3CE00BCA5A9 /* MultipartMixedContents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78F5086CC3CE00BCA5A9 /* MultipartMixedContents.cxx */; }; + 124D7956086CC3CE00BCA5A9 /* MultipartRelatedContents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78F6086CC3CE00BCA5A9 /* MultipartRelatedContents.cxx */; }; + 124D7957086CC3CE00BCA5A9 /* MultipartSignedContents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78F7086CC3CE00BCA5A9 /* MultipartSignedContents.cxx */; }; + 124D7958086CC3CE00BCA5A9 /* NameAddr.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78F8086CC3CE00BCA5A9 /* NameAddr.cxx */; }; + 124D7959086CC3CE00BCA5A9 /* OctetContents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78F9086CC3CE00BCA5A9 /* OctetContents.cxx */; }; + 124D795A086CC3CE00BCA5A9 /* Parameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78FA086CC3CE00BCA5A9 /* Parameter.cxx */; }; + 124D795B086CC3CE00BCA5A9 /* ParameterHash.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78FB086CC3CE00BCA5A9 /* ParameterHash.cxx */; }; + 124D795C086CC3CE00BCA5A9 /* ParameterTypes.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78FC086CC3CE00BCA5A9 /* ParameterTypes.cxx */; }; + 124D795D086CC3CE00BCA5A9 /* ParserCategories.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78FD086CC3CE00BCA5A9 /* ParserCategories.cxx */; }; + 124D795E086CC3CE00BCA5A9 /* ParserCategory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D78FE086CC3CE00BCA5A9 /* ParserCategory.cxx */; }; + 124D7960086CC3CE00BCA5A9 /* Pkcs7Contents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7900086CC3CE00BCA5A9 /* Pkcs7Contents.cxx */; }; + 124D7961086CC3CE00BCA5A9 /* PlainContents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7901086CC3CE00BCA5A9 /* PlainContents.cxx */; }; + 124D7963086CC3CE00BCA5A9 /* QuotedDataParameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7903086CC3CE00BCA5A9 /* QuotedDataParameter.cxx */; }; + 124D7964086CC3CE00BCA5A9 /* RAckCategory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7904086CC3CE00BCA5A9 /* RAckCategory.cxx */; }; + 124D7966086CC3CE00BCA5A9 /* RequestLine.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7906086CC3CE00BCA5A9 /* RequestLine.cxx */; }; + 124D7967086CC3CE00BCA5A9 /* RportParameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7907086CC3CE00BCA5A9 /* RportParameter.cxx */; }; + 124D7968086CC3CE00BCA5A9 /* SdpContents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7908086CC3CE00BCA5A9 /* SdpContents.cxx */; }; + 124D7969086CC3CE00BCA5A9 /* Security.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7909086CC3CE00BCA5A9 /* Security.cxx */; }; + 124D796A086CC3CE00BCA5A9 /* SecurityAttributes.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D790A086CC3CE00BCA5A9 /* SecurityAttributes.cxx */; }; + 124D796B086CC3CE00BCA5A9 /* SipFrag.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D790B086CC3CE00BCA5A9 /* SipFrag.cxx */; }; + 124D796C086CC3CE00BCA5A9 /* SipMessage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D790C086CC3CE00BCA5A9 /* SipMessage.cxx */; }; + 124D796D086CC3CE00BCA5A9 /* SipStack.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D790D086CC3CE00BCA5A9 /* SipStack.cxx */; }; + 124D796E086CC3CE00BCA5A9 /* StackThread.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D790E086CC3CE00BCA5A9 /* StackThread.cxx */; }; + 124D796F086CC3CE00BCA5A9 /* StatelessHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D790F086CC3CE00BCA5A9 /* StatelessHandler.cxx */; }; + 124D7970086CC3CE00BCA5A9 /* StatisticsManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7910086CC3CE00BCA5A9 /* StatisticsManager.cxx */; }; + 124D7971086CC3CE00BCA5A9 /* StatisticsMessage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7911086CC3CE00BCA5A9 /* StatisticsMessage.cxx */; }; + 124D7972086CC3CE00BCA5A9 /* StatusLine.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7912086CC3CE00BCA5A9 /* StatusLine.cxx */; }; + 124D7973086CC3CE00BCA5A9 /* StringCategory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7913086CC3CE00BCA5A9 /* StringCategory.cxx */; }; + 124D7974086CC3CE00BCA5A9 /* Symbols.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7914086CC3CE00BCA5A9 /* Symbols.cxx */; }; + 124D7975086CC3CE00BCA5A9 /* TcpBaseTransport.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7915086CC3CE00BCA5A9 /* TcpBaseTransport.cxx */; }; + 124D7977086CC3CE00BCA5A9 /* TcpTransport.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7917086CC3CE00BCA5A9 /* TcpTransport.cxx */; }; + 124D7978086CC3CE00BCA5A9 /* TimerMessage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7918086CC3CE00BCA5A9 /* TimerMessage.cxx */; }; + 124D7979086CC3CE00BCA5A9 /* TimerQueue.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7919086CC3CE00BCA5A9 /* TimerQueue.cxx */; }; + 124D797B086CC3CE00BCA5A9 /* TlsTransport.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D791B086CC3CE00BCA5A9 /* TlsTransport.cxx */; }; + 124D797C086CC3CE00BCA5A9 /* Token.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D791C086CC3CE00BCA5A9 /* Token.cxx */; }; + 124D797D086CC3CE00BCA5A9 /* TransactionController.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D791D086CC3CE00BCA5A9 /* TransactionController.cxx */; }; + 124D797E086CC3CE00BCA5A9 /* TransactionMap.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D791E086CC3CE00BCA5A9 /* TransactionMap.cxx */; }; + 124D797F086CC3CE00BCA5A9 /* TransactionState.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D791F086CC3CE00BCA5A9 /* TransactionState.cxx */; }; + 124D7980086CC3CE00BCA5A9 /* TransactionUser.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7920086CC3CE00BCA5A9 /* TransactionUser.cxx */; }; + 124D7981086CC3CE00BCA5A9 /* TransactionUserMessage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7921086CC3CE00BCA5A9 /* TransactionUserMessage.cxx */; }; + 124D7982086CC3CE00BCA5A9 /* Transport.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7922086CC3CE00BCA5A9 /* Transport.cxx */; }; + 124D7983086CC3CE00BCA5A9 /* TransportSelector.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7923086CC3CE00BCA5A9 /* TransportSelector.cxx */; }; + 124D7984086CC3CE00BCA5A9 /* TuSelector.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7924086CC3CE00BCA5A9 /* TuSelector.cxx */; }; + 124D7985086CC3CE00BCA5A9 /* UdpTransport.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7925086CC3CE00BCA5A9 /* UdpTransport.cxx */; }; + 124D7986086CC3CE00BCA5A9 /* UnknownParameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7926086CC3CE00BCA5A9 /* UnknownParameter.cxx */; }; + 124D7987086CC3CE00BCA5A9 /* Uri.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7927086CC3CE00BCA5A9 /* Uri.cxx */; }; + 124D7988086CC3CE00BCA5A9 /* Via.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7928086CC3CE00BCA5A9 /* Via.cxx */; }; + 124D7989086CC3CE00BCA5A9 /* WarningCategory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7929086CC3CE00BCA5A9 /* WarningCategory.cxx */; }; + 124D79B2086CC67000BCA5A9 /* DnsAAAARecord.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79A7086CC67000BCA5A9 /* DnsAAAARecord.cxx */; }; + 124D79B3086CC67000BCA5A9 /* DnsCnameRecord.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79A8086CC67000BCA5A9 /* DnsCnameRecord.cxx */; }; + 124D79B4086CC67000BCA5A9 /* DnsHostRecord.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79A9086CC67000BCA5A9 /* DnsHostRecord.cxx */; }; + 124D79B5086CC67000BCA5A9 /* DnsNaptrRecord.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79AA086CC67000BCA5A9 /* DnsNaptrRecord.cxx */; }; + 124D79B6086CC67000BCA5A9 /* DnsSrvRecord.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79AB086CC67000BCA5A9 /* DnsSrvRecord.cxx */; }; + 124D79B7086CC67000BCA5A9 /* DnsStub.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79AC086CC67000BCA5A9 /* DnsStub.cxx */; }; + 124D79B8086CC67000BCA5A9 /* QueryTypes.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79AD086CC67000BCA5A9 /* QueryTypes.cxx */; }; + 124D79B9086CC67000BCA5A9 /* RRCache.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79AE086CC67000BCA5A9 /* RRCache.cxx */; }; + 124D79BA086CC67000BCA5A9 /* RRList.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79AF086CC67000BCA5A9 /* RRList.cxx */; }; + 124D79BB086CC67000BCA5A9 /* RROverlay.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79B0086CC67000BCA5A9 /* RROverlay.cxx */; }; + 124D79BC086CC67000BCA5A9 /* RRVip.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79B1086CC67000BCA5A9 /* RRVip.cxx */; }; + 124D79F3086CC68200BCA5A9 /* AppDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79BD086CC68200BCA5A9 /* AppDialog.cxx */; }; + 124D79F4086CC68200BCA5A9 /* AppDialogSet.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79BE086CC68200BCA5A9 /* AppDialogSet.cxx */; }; + 124D79F5086CC68200BCA5A9 /* AppDialogSetFactory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79BF086CC68200BCA5A9 /* AppDialogSetFactory.cxx */; }; + 124D79F6086CC68200BCA5A9 /* BaseCreator.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79C0086CC68200BCA5A9 /* BaseCreator.cxx */; }; + 124D79F7086CC68200BCA5A9 /* BaseSubscription.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79C1086CC68200BCA5A9 /* BaseSubscription.cxx */; }; + 124D79F8086CC68200BCA5A9 /* BaseUsage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79C2086CC68200BCA5A9 /* BaseUsage.cxx */; }; + 124D79F9086CC68200BCA5A9 /* ClientAuthManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79C3086CC68200BCA5A9 /* ClientAuthManager.cxx */; }; + 124D79FA086CC68200BCA5A9 /* ClientInviteSession.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79C4086CC68200BCA5A9 /* ClientInviteSession.cxx */; }; + 124D79FB086CC68200BCA5A9 /* ClientOutOfDialogReq.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79C5086CC68200BCA5A9 /* ClientOutOfDialogReq.cxx */; }; + 124D79FC086CC68200BCA5A9 /* ClientPagerMessage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79C6086CC68200BCA5A9 /* ClientPagerMessage.cxx */; }; + 124D79FD086CC68200BCA5A9 /* ClientPublication.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79C7086CC68200BCA5A9 /* ClientPublication.cxx */; }; + 124D79FE086CC68200BCA5A9 /* ClientRegistration.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79C8086CC68200BCA5A9 /* ClientRegistration.cxx */; }; + 124D79FF086CC68200BCA5A9 /* ClientSubscription.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79C9086CC68200BCA5A9 /* ClientSubscription.cxx */; }; + 124D7A00086CC68200BCA5A9 /* DefaultServerReferHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79CA086CC68200BCA5A9 /* DefaultServerReferHandler.cxx */; }; + 124D7A01086CC68200BCA5A9 /* DestroyUsage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79CB086CC68200BCA5A9 /* DestroyUsage.cxx */; }; + 124D7A02086CC68200BCA5A9 /* Dialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79CC086CC68200BCA5A9 /* Dialog.cxx */; }; + 124D7A03086CC68200BCA5A9 /* DialogId.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79CD086CC68200BCA5A9 /* DialogId.cxx */; }; + 124D7A04086CC68200BCA5A9 /* DialogSet.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79CE086CC68200BCA5A9 /* DialogSet.cxx */; }; + 124D7A05086CC68200BCA5A9 /* DialogSetId.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79CF086CC68200BCA5A9 /* DialogSetId.cxx */; }; + 124D7A06086CC68200BCA5A9 /* DialogUsage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79D0086CC68200BCA5A9 /* DialogUsage.cxx */; }; + 124D7A07086CC68200BCA5A9 /* DialogUsageManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79D1086CC68200BCA5A9 /* DialogUsageManager.cxx */; }; + 124D7A08086CC68200BCA5A9 /* DumProcessHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79D2086CC68200BCA5A9 /* DumProcessHandler.cxx */; }; + 124D7A09086CC68200BCA5A9 /* DumTimeout.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79D3086CC68200BCA5A9 /* DumTimeout.cxx */; }; + 124D7A0A086CC68200BCA5A9 /* Handled.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79D4086CC68200BCA5A9 /* Handled.cxx */; }; + 124D7A0B086CC68200BCA5A9 /* HandleException.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79D5086CC68200BCA5A9 /* HandleException.cxx */; }; + 124D7A0C086CC68200BCA5A9 /* HandleManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79D6086CC68200BCA5A9 /* HandleManager.cxx */; }; + 124D7A0D086CC68200BCA5A9 /* InviteSession.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79D7086CC68200BCA5A9 /* InviteSession.cxx */; }; + 124D7A0E086CC68200BCA5A9 /* InviteSessionCreator.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79D8086CC68200BCA5A9 /* InviteSessionCreator.cxx */; }; + 124D7A0F086CC68200BCA5A9 /* InviteSessionHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79D9086CC68200BCA5A9 /* InviteSessionHandler.cxx */; }; + 124D7A10086CC68200BCA5A9 /* MergedRequestKey.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79DA086CC68200BCA5A9 /* MergedRequestKey.cxx */; }; + 124D7A11086CC68200BCA5A9 /* KeepAliveManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79DB086CC68200BCA5A9 /* KeepAliveManager.cxx */; }; + 124D7A12086CC68200BCA5A9 /* KeepAliveTimeout.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79DC086CC68200BCA5A9 /* KeepAliveTimeout.cxx */; }; + 124D7A13086CC68200BCA5A9 /* MasterProfile.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79DD086CC68200BCA5A9 /* MasterProfile.cxx */; }; + 124D7A14086CC68200BCA5A9 /* NetworkAssociation.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79DE086CC68200BCA5A9 /* NetworkAssociation.cxx */; }; + 124D7A15086CC68200BCA5A9 /* NonDialogUsage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79DF086CC68200BCA5A9 /* NonDialogUsage.cxx */; }; + 124D7A16086CC68200BCA5A9 /* OutOfDialogReqCreator.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79E0086CC68200BCA5A9 /* OutOfDialogReqCreator.cxx */; }; + 124D7A17086CC68200BCA5A9 /* PagerMessageCreator.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79E1086CC68200BCA5A9 /* PagerMessageCreator.cxx */; }; + 124D7A18086CC68200BCA5A9 /* Profile.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79E2086CC68200BCA5A9 /* Profile.cxx */; }; + 124D7A19086CC68200BCA5A9 /* PublicationCreator.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79E3086CC68200BCA5A9 /* PublicationCreator.cxx */; }; + 124D7A1A086CC68200BCA5A9 /* RedirectManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79E4086CC68200BCA5A9 /* RedirectManager.cxx */; }; + 124D7A1B086CC68200BCA5A9 /* RegistrationCreator.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79E5086CC68200BCA5A9 /* RegistrationCreator.cxx */; }; + 124D7A1C086CC68200BCA5A9 /* ServerAuthManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79E6086CC68200BCA5A9 /* ServerAuthManager.cxx */; }; + 124D7A1D086CC68200BCA5A9 /* ServerInviteSession.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79E7086CC68200BCA5A9 /* ServerInviteSession.cxx */; }; + 124D7A1E086CC68200BCA5A9 /* ServerOutOfDialogReq.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79E8086CC68200BCA5A9 /* ServerOutOfDialogReq.cxx */; }; + 124D7A1F086CC68200BCA5A9 /* ServerPagerMessage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79E9086CC68200BCA5A9 /* ServerPagerMessage.cxx */; }; + 124D7A20086CC68200BCA5A9 /* ServerPublication.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79EA086CC68200BCA5A9 /* ServerPublication.cxx */; }; + 124D7A21086CC68200BCA5A9 /* ServerRegistration.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79EB086CC68200BCA5A9 /* ServerRegistration.cxx */; }; + 124D7A22086CC68200BCA5A9 /* ServerSubscription.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79EC086CC68200BCA5A9 /* ServerSubscription.cxx */; }; + 124D7A23086CC68200BCA5A9 /* SubscriptionCreator.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79ED086CC68200BCA5A9 /* SubscriptionCreator.cxx */; }; + 124D7A24086CC68200BCA5A9 /* SubscriptionHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79EE086CC68200BCA5A9 /* SubscriptionHandler.cxx */; }; + 124D7A25086CC68200BCA5A9 /* SubscriptionState.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79EF086CC68200BCA5A9 /* SubscriptionState.cxx */; }; + 124D7A27086CC68200BCA5A9 /* UserAuthInfo.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79F1086CC68200BCA5A9 /* UserAuthInfo.cxx */; }; + 124D7A28086CC68200BCA5A9 /* UserProfile.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D79F2086CC68200BCA5A9 /* UserProfile.cxx */; }; + 124D7A44086CC69300BCA5A9 /* AbstractFifo.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A29086CC69300BCA5A9 /* AbstractFifo.cxx */; }; + 124D7A45086CC69300BCA5A9 /* BaseException.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A2A086CC69300BCA5A9 /* BaseException.cxx */; }; + 124D7A46086CC69300BCA5A9 /* Coders.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A2B086CC69300BCA5A9 /* Coders.cxx */; }; + 124D7A47086CC69300BCA5A9 /* Condition.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A2C086CC69300BCA5A9 /* Condition.cxx */; }; + 124D7A48086CC69300BCA5A9 /* CountStream.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A2D086CC69300BCA5A9 /* CountStream.cxx */; }; + 124D7A49086CC69300BCA5A9 /* Data.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A2E086CC69300BCA5A9 /* Data.cxx */; }; + 124D7A4A086CC69300BCA5A9 /* DataStream.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A2F086CC69300BCA5A9 /* DataStream.cxx */; }; + 124D7A4B086CC69300BCA5A9 /* DnsUtil.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A30086CC69300BCA5A9 /* DnsUtil.cxx */; }; + 124D7A4C086CC69300BCA5A9 /* FileSystem.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A31086CC69300BCA5A9 /* FileSystem.cxx */; }; + 124D7A4D086CC69300BCA5A9 /* Lock.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A32086CC69300BCA5A9 /* Lock.cxx */; }; + 124D7A4E086CC69300BCA5A9 /* Log.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A33086CC69300BCA5A9 /* Log.cxx */; }; + 124D7A50086CC69300BCA5A9 /* MD5Stream.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A35086CC69300BCA5A9 /* MD5Stream.cxx */; }; + 124D7A51086CC69300BCA5A9 /* Mutex.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A36086CC69300BCA5A9 /* Mutex.cxx */; }; + 124D7A52086CC69300BCA5A9 /* ParseBuffer.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A37086CC69300BCA5A9 /* ParseBuffer.cxx */; }; + 124D7A53086CC69300BCA5A9 /* Random.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A38086CC69300BCA5A9 /* Random.cxx */; }; + 124D7A54086CC69300BCA5A9 /* RecursiveMutex.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A39086CC69300BCA5A9 /* RecursiveMutex.cxx */; }; + 124D7A55086CC69300BCA5A9 /* RWMutex.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A3A086CC69300BCA5A9 /* RWMutex.cxx */; }; + 124D7A57086CC69300BCA5A9 /* Socket.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A3C086CC69300BCA5A9 /* Socket.cxx */; }; + 124D7A58086CC69300BCA5A9 /* Subsystem.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A3D086CC69300BCA5A9 /* Subsystem.cxx */; }; + 124D7A59086CC69300BCA5A9 /* SysLogBuf.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A3E086CC69300BCA5A9 /* SysLogBuf.cxx */; }; + 124D7A5A086CC69300BCA5A9 /* SysLogStream.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A3F086CC69300BCA5A9 /* SysLogStream.cxx */; }; + 124D7A5B086CC69300BCA5A9 /* ThreadIf.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A40086CC69300BCA5A9 /* ThreadIf.cxx */; }; + 124D7A5C086CC69300BCA5A9 /* Timer.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A41086CC69300BCA5A9 /* Timer.cxx */; }; + 124D7A5D086CC69300BCA5A9 /* Tuple.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A42086CC69300BCA5A9 /* Tuple.cxx */; }; + 124D7A5E086CC69300BCA5A9 /* vmd5.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A43086CC69300BCA5A9 /* vmd5.cxx */; }; + 124D7A61086CC77900BCA5A9 /* HttpGetMessage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A5F086CC77900BCA5A9 /* HttpGetMessage.cxx */; }; + 124D7A62086CC77900BCA5A9 /* HttpProvider.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7A60086CC77900BCA5A9 /* HttpProvider.cxx */; }; + 124EC468087217600017C8BB /* TransportFailure.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124EC467087217600017C8BB /* TransportFailure.cxx */; }; + 124EC47D08721CFF0017C8BB /* ExtensionHeader.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124EC47B08721CFF0017C8BB /* ExtensionHeader.cxx */; }; + 124EC47E08721CFF0017C8BB /* ExtensionParameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124EC47C08721CFF0017C8BB /* ExtensionParameter.cxx */; }; + 12BF59350895D59E00F7DD81 /* ParserContainerBase.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 12BF59340895D59E00F7DD81 /* ParserContainerBase.cxx */; }; + 12BF59370895D5BA00F7DD81 /* ContentsFactoryBase.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 12BF59360895D5BA00F7DD81 /* ContentsFactoryBase.cxx */; }; + 12BF59390895D5E600F7DD81 /* EncryptionManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 12BF59380895D5E600F7DD81 /* EncryptionManager.cxx */; }; + 12BF593C0895D5FF00F7DD81 /* DumDecrypted.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 12BF593A0895D5FF00F7DD81 /* DumDecrypted.cxx */; }; + 12BF59580895D7B800F7DD81 /* CertMessage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 12BF59570895D7B800F7DD81 /* CertMessage.cxx */; }; + F80A8D4A12B2CA66002D37E0 /* FdPoll.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F80A8D4812B2CA66002D37E0 /* FdPoll.cxx */; }; + F80A8D4B12B2CA66002D37E0 /* FdPoll.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F80A8D4912B2CA66002D37E0 /* FdPoll.hxx */; }; + F8A057C7124D47D700112774 /* TcpConnection.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D7916086CC3CE00BCA5A9 /* TcpConnection.cxx */; }; + F8A057DB124D52BA00112774 /* AbandonServerTransaction.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8A057D3124D52BA00112774 /* AbandonServerTransaction.hxx */; }; + F8A057DC124D52BA00112774 /* CancelClientInviteTransaction.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8A057D4124D52BA00112774 /* CancelClientInviteTransaction.hxx */; }; + F8A057DD124D52BA00112774 /* ExistsOrDataParameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8A057D5124D52BA00112774 /* ExistsOrDataParameter.cxx */; }; + F8A057DE124D52BA00112774 /* ExistsOrDataParameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8A057D6124D52BA00112774 /* ExistsOrDataParameter.hxx */; }; + F8A057DF124D52BA00112774 /* InteropHelper.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8A057D7124D52BA00112774 /* InteropHelper.cxx */; }; + F8A057E0124D52BA00112774 /* InteropHelper.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8A057D8124D52BA00112774 /* InteropHelper.hxx */; }; + F8A057E1124D52BA00112774 /* PrivacyCategory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8A057D9124D52BA00112774 /* PrivacyCategory.cxx */; }; + F8A057E2124D52BA00112774 /* PrivacyCategory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8A057DA124D52BA00112774 /* PrivacyCategory.hxx */; }; + F8A057EE124D52DE00112774 /* ClientAuthExtension.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8A057E3124D52DE00112774 /* ClientAuthExtension.cxx */; }; + F8A057EF124D52DE00112774 /* ClientAuthExtension.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8A057E4124D52DE00112774 /* ClientAuthExtension.hxx */; }; + F8A057F0124D52DE00112774 /* DialogEventInfo.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8A057E5124D52DE00112774 /* DialogEventInfo.cxx */; }; + F8A057F1124D52DE00112774 /* DialogEventInfo.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8A057E6124D52DE00112774 /* DialogEventInfo.hxx */; }; + F8A057F2124D52DE00112774 /* DialogEventStateManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8A057E7124D52DE00112774 /* DialogEventStateManager.cxx */; }; + F8A057F3124D52DE00112774 /* DialogEventStateManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8A057E8124D52DE00112774 /* DialogEventStateManager.hxx */; }; + F8A057F4124D52DE00112774 /* InMemorySyncRegDb.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8A057E9124D52DE00112774 /* InMemorySyncRegDb.cxx */; }; + F8A057F5124D52DE00112774 /* InMemorySyncRegDb.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8A057EA124D52DE00112774 /* InMemorySyncRegDb.hxx */; }; + F8A057F6124D52DE00112774 /* RADIUSServerAuthManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8A057EB124D52DE00112774 /* RADIUSServerAuthManager.cxx */; }; + F8A057F7124D52DE00112774 /* RADIUSServerAuthManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8A057EC124D52DE00112774 /* RADIUSServerAuthManager.hxx */; }; + F8A057F8124D52DE00112774 /* RegistrationHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8A057ED124D52DE00112774 /* RegistrationHandler.cxx */; }; + F8C76C9D1243CCFF0076CFF8 /* AsyncProcessHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8C76C911243CCFF0076CFF8 /* AsyncProcessHandler.hxx */; }; + F8C76C9E1243CCFF0076CFF8 /* DataException.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8C76C921243CCFF0076CFF8 /* DataException.hxx */; }; + F8C76C9F1243CCFF0076CFF8 /* DigestStream.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8C76C931243CCFF0076CFF8 /* DigestStream.cxx */; }; + F8C76CA01243CCFF0076CFF8 /* DigestStream.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8C76C941243CCFF0076CFF8 /* DigestStream.hxx */; }; + F8C76CA11243CCFF0076CFF8 /* ParseException.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8C76C951243CCFF0076CFF8 /* ParseException.cxx */; }; + F8C76CA21243CCFF0076CFF8 /* ParseException.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8C76C961243CCFF0076CFF8 /* ParseException.hxx */; }; + F8C76CA31243CCFF0076CFF8 /* RADIUSDigestAuthenticator.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8C76C971243CCFF0076CFF8 /* RADIUSDigestAuthenticator.cxx */; }; + F8C76CA41243CCFF0076CFF8 /* RADIUSDigestAuthenticator.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8C76C981243CCFF0076CFF8 /* RADIUSDigestAuthenticator.hxx */; }; + F8C76CA51243CCFF0076CFF8 /* resipfaststreams.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8C76C991243CCFF0076CFF8 /* resipfaststreams.cxx */; }; + F8C76CA61243CCFF0076CFF8 /* resipfaststreams.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8C76C9A1243CCFF0076CFF8 /* resipfaststreams.hxx */; }; + F8C76CA71243CCFF0076CFF8 /* Time.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8C76C9B1243CCFF0076CFF8 /* Time.cxx */; }; + F8C76CA81243CCFF0076CFF8 /* Time.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8C76C9C1243CCFF0076CFF8 /* Time.hxx */; }; + F8C76CAB1243CD2B0076CFF8 /* OpenSSLInit.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8C76CA91243CD2B0076CFF8 /* OpenSSLInit.cxx */; }; + F8C76CAC1243CD2B0076CFF8 /* SHA1Stream.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8C76CAA1243CD2B0076CFF8 /* SHA1Stream.cxx */; }; + F8DB1C920C56B7FD00853E27 /* DialerConfiguration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1C8E0C56B7FD00853E27 /* DialerConfiguration.cpp */; }; + F8DB1C930C56B7FD00853E27 /* DialInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1C8F0C56B7FD00853E27 /* DialInstance.cpp */; }; + F8DB1C940C56B7FD00853E27 /* MyInviteSessionHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1C900C56B7FD00853E27 /* MyInviteSessionHandler.cpp */; }; + F8DB1C950C56B7FD00853E27 /* sipdialer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1C910C56B7FD00853E27 /* sipdialer.cpp */; }; + F8DB1D210C56B9B800853E27 /* AppDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CBA0C56B9B800853E27 /* AppDialog.hxx */; }; + F8DB1D220C56B9B800853E27 /* AppDialogSet.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CBB0C56B9B800853E27 /* AppDialogSet.hxx */; }; + F8DB1D230C56B9B800853E27 /* AppDialogSetFactory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CBC0C56B9B800853E27 /* AppDialogSetFactory.hxx */; }; + F8DB1D240C56B9B800853E27 /* BaseCreator.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CBD0C56B9B800853E27 /* BaseCreator.hxx */; }; + F8DB1D250C56B9B800853E27 /* BaseSubscription.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CBE0C56B9B800853E27 /* BaseSubscription.hxx */; }; + F8DB1D260C56B9B800853E27 /* BaseUsage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CBF0C56B9B800853E27 /* BaseUsage.hxx */; }; + F8DB1D270C56B9B800853E27 /* CertMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CC00C56B9B800853E27 /* CertMessage.hxx */; }; + F8DB1D280C56B9B800853E27 /* ChallengeInfo.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1CC10C56B9B800853E27 /* ChallengeInfo.cxx */; }; + F8DB1D290C56B9B800853E27 /* ChallengeInfo.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CC20C56B9B800853E27 /* ChallengeInfo.hxx */; }; + F8DB1D2A0C56B9B800853E27 /* ClientAuthManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CC30C56B9B800853E27 /* ClientAuthManager.hxx */; }; + F8DB1D2B0C56B9B800853E27 /* ClientInviteSession.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CC40C56B9B800853E27 /* ClientInviteSession.hxx */; }; + F8DB1D2C0C56B9B800853E27 /* ClientOutOfDialogReq.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CC50C56B9B800853E27 /* ClientOutOfDialogReq.hxx */; }; + F8DB1D2D0C56B9B800853E27 /* ClientPagerMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CC60C56B9B800853E27 /* ClientPagerMessage.hxx */; }; + F8DB1D2E0C56B9B800853E27 /* ClientPublication.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CC70C56B9B800853E27 /* ClientPublication.hxx */; }; + F8DB1D2F0C56B9B800853E27 /* ClientRegistration.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CC80C56B9B800853E27 /* ClientRegistration.hxx */; }; + F8DB1D300C56B9B800853E27 /* ClientSubscription.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CC90C56B9B800853E27 /* ClientSubscription.hxx */; }; + F8DB1D310C56B9B800853E27 /* ClientSubscriptionFunctor.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CCA0C56B9B800853E27 /* ClientSubscriptionFunctor.hxx */; }; + F8DB1D320C56B9B800853E27 /* ContactInstanceRecord.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1CCB0C56B9B800853E27 /* ContactInstanceRecord.cxx */; }; + F8DB1D330C56B9B800853E27 /* ContactInstanceRecord.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CCC0C56B9B800853E27 /* ContactInstanceRecord.hxx */; }; + F8DB1D340C56B9B800853E27 /* DefaultServerReferHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CCD0C56B9B800853E27 /* DefaultServerReferHandler.hxx */; }; + F8DB1D350C56B9B800853E27 /* DestroyUsage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CCE0C56B9B800853E27 /* DestroyUsage.hxx */; }; + F8DB1D360C56B9B800853E27 /* Dialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CCF0C56B9B800853E27 /* Dialog.hxx */; }; + F8DB1D370C56B9B800853E27 /* DialogEventHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CD00C56B9B800853E27 /* DialogEventHandler.hxx */; }; + F8DB1D380C56B9B800853E27 /* DialogId.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CD10C56B9B800853E27 /* DialogId.hxx */; }; + F8DB1D390C56B9B800853E27 /* DialogSet.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CD20C56B9B800853E27 /* DialogSet.hxx */; }; + F8DB1D3A0C56B9B800853E27 /* DialogSetHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CD30C56B9B800853E27 /* DialogSetHandler.hxx */; }; + F8DB1D3B0C56B9B800853E27 /* DialogSetId.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CD40C56B9B800853E27 /* DialogSetId.hxx */; }; + F8DB1D3C0C56B9B800853E27 /* DialogUsage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CD50C56B9B800853E27 /* DialogUsage.hxx */; }; + F8DB1D3D0C56B9B800853E27 /* DialogUsageManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CD60C56B9B800853E27 /* DialogUsageManager.hxx */; }; + F8DB1D3E0C56B9B800853E27 /* DumCommand.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CD70C56B9B800853E27 /* DumCommand.hxx */; }; + F8DB1D3F0C56B9B800853E27 /* DumDecrypted.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CD80C56B9B800853E27 /* DumDecrypted.hxx */; }; + F8DB1D400C56B9B800853E27 /* DumException.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CD90C56B9B800853E27 /* DumException.hxx */; }; + F8DB1D410C56B9B800853E27 /* DumFeature.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CDA0C56B9B800853E27 /* DumFeature.hxx */; }; + F8DB1D420C56B9B800853E27 /* DumFeatureChain.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CDB0C56B9B800853E27 /* DumFeatureChain.hxx */; }; + F8DB1D430C56B9B800853E27 /* DumFeatureMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CDC0C56B9B800853E27 /* DumFeatureMessage.hxx */; }; + F8DB1D440C56B9B800853E27 /* DumHelper.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1CDD0C56B9B800853E27 /* DumHelper.cxx */; }; + F8DB1D450C56B9B800853E27 /* DumHelper.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CDE0C56B9B800853E27 /* DumHelper.hxx */; }; + F8DB1D460C56B9B800853E27 /* DumProcessHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CDF0C56B9B800853E27 /* DumProcessHandler.hxx */; }; + F8DB1D470C56B9B800853E27 /* DumShutdownHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CE00C56B9B800853E27 /* DumShutdownHandler.hxx */; }; + F8DB1D480C56B9B800853E27 /* DumThread.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1CE10C56B9B800853E27 /* DumThread.cxx */; }; + F8DB1D490C56B9B800853E27 /* DumThread.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CE20C56B9B800853E27 /* DumThread.hxx */; }; + F8DB1D4A0C56B9B800853E27 /* DumTimeout.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CE30C56B9B800853E27 /* DumTimeout.hxx */; }; + F8DB1D4B0C56B9B800853E27 /* EncryptionManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CE40C56B9B800853E27 /* EncryptionManager.hxx */; }; + F8DB1D4C0C56B9B800853E27 /* EncryptionRequest.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CE50C56B9B800853E27 /* EncryptionRequest.hxx */; }; + F8DB1D4D0C56B9B800853E27 /* EventDispatcher.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CE60C56B9B800853E27 /* EventDispatcher.hxx */; }; + F8DB1D4E0C56B9B800853E27 /* ExternalMessageBase.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CE70C56B9B800853E27 /* ExternalMessageBase.hxx */; }; + F8DB1D4F0C56B9B800853E27 /* ExternalMessageHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CE80C56B9B800853E27 /* ExternalMessageHandler.hxx */; }; + F8DB1D500C56B9B800853E27 /* ExternalTimer.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CE90C56B9B800853E27 /* ExternalTimer.hxx */; }; + F8DB1D510C56B9B800853E27 /* Handle.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1CEA0C56B9B800853E27 /* Handle.cxx */; }; + F8DB1D520C56B9B800853E27 /* Handle.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CEB0C56B9B800853E27 /* Handle.hxx */; }; + F8DB1D530C56B9B800853E27 /* Handled.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CEC0C56B9B800853E27 /* Handled.hxx */; }; + F8DB1D540C56B9B800853E27 /* HandleException.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CED0C56B9B800853E27 /* HandleException.hxx */; }; + F8DB1D550C56B9B800853E27 /* HandleManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CEE0C56B9B800853E27 /* HandleManager.hxx */; }; + F8DB1D560C56B9B800853E27 /* Handles.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CEF0C56B9B800853E27 /* Handles.hxx */; }; + F8DB1D570C56B9B800853E27 /* HttpGetMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CF00C56B9B800853E27 /* HttpGetMessage.hxx */; }; + F8DB1D580C56B9B800853E27 /* HttpProvider.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CF10C56B9B800853E27 /* HttpProvider.hxx */; }; + F8DB1D590C56B9B800853E27 /* IdentityHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CF20C56B9B800853E27 /* IdentityHandler.hxx */; }; + F8DB1D5A0C56B9B800853E27 /* InMemoryRegistrationDatabase.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1CF30C56B9B800853E27 /* InMemoryRegistrationDatabase.cxx */; }; + F8DB1D5B0C56B9B800853E27 /* InMemoryRegistrationDatabase.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CF40C56B9B800853E27 /* InMemoryRegistrationDatabase.hxx */; }; + F8DB1D5C0C56B9B800853E27 /* InviteDialogs.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CF50C56B9B800853E27 /* InviteDialogs.hxx */; }; + F8DB1D5D0C56B9B800853E27 /* InviteSession.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CF60C56B9B800853E27 /* InviteSession.hxx */; }; + F8DB1D5E0C56B9B800853E27 /* InviteSessionCreator.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CF70C56B9B800853E27 /* InviteSessionCreator.hxx */; }; + F8DB1D5F0C56B9B800853E27 /* InviteSessionHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CF80C56B9B800853E27 /* InviteSessionHandler.hxx */; }; + F8DB1D600C56B9B800853E27 /* KeepAliveManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CF90C56B9B800853E27 /* KeepAliveManager.hxx */; }; + F8DB1D610C56B9B800853E27 /* KeepAliveTimeout.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CFA0C56B9B800853E27 /* KeepAliveTimeout.hxx */; }; + F8DB1D620C56B9B800853E27 /* MasterProfile.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CFB0C56B9B800853E27 /* MasterProfile.hxx */; }; + F8DB1D630C56B9B800853E27 /* MergedRequestKey.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CFC0C56B9B800853E27 /* MergedRequestKey.hxx */; }; + F8DB1D640C56B9B800853E27 /* MergedRequestRemovalCommand.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1CFD0C56B9B800853E27 /* MergedRequestRemovalCommand.cxx */; }; + F8DB1D650C56B9B800853E27 /* MergedRequestRemovalCommand.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CFE0C56B9B800853E27 /* MergedRequestRemovalCommand.hxx */; }; + F8DB1D660C56B9B800853E27 /* NetworkAssociation.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1CFF0C56B9B800853E27 /* NetworkAssociation.hxx */; }; + F8DB1D670C56B9B800853E27 /* NonDialogUsage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D000C56B9B800853E27 /* NonDialogUsage.hxx */; }; + F8DB1D680C56B9B800853E27 /* OutgoingEvent.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D010C56B9B800853E27 /* OutgoingEvent.hxx */; }; + F8DB1D690C56B9B800853E27 /* OutOfDialogHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D020C56B9B800853E27 /* OutOfDialogHandler.hxx */; }; + F8DB1D6A0C56B9B800853E27 /* OutOfDialogReqCreator.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D030C56B9B800853E27 /* OutOfDialogReqCreator.hxx */; }; + F8DB1D6B0C56B9B800853E27 /* PagerMessageCreator.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D040C56B9B800853E27 /* PagerMessageCreator.hxx */; }; + F8DB1D6C0C56B9B800853E27 /* PagerMessageHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D050C56B9B800853E27 /* PagerMessageHandler.hxx */; }; + F8DB1D6D0C56B9B800853E27 /* Postable.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D060C56B9B800853E27 /* Postable.hxx */; }; + F8DB1D6E0C56B9B800853E27 /* Profile.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D070C56B9B800853E27 /* Profile.hxx */; }; + F8DB1D6F0C56B9B800853E27 /* PublicationCreator.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D080C56B9B800853E27 /* PublicationCreator.hxx */; }; + F8DB1D700C56B9B800853E27 /* PublicationHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D090C56B9B800853E27 /* PublicationHandler.hxx */; }; + F8DB1D710C56B9B800853E27 /* RedirectHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D0A0C56B9B800853E27 /* RedirectHandler.hxx */; }; + F8DB1D720C56B9B800853E27 /* RedirectManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D0B0C56B9B800853E27 /* RedirectManager.hxx */; }; + F8DB1D730C56B9B800853E27 /* RefCountedDestroyer.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D0C0C56B9B800853E27 /* RefCountedDestroyer.hxx */; }; + F8DB1D740C56B9B800853E27 /* RegistrationCreator.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D0D0C56B9B800853E27 /* RegistrationCreator.hxx */; }; + F8DB1D750C56B9B800853E27 /* RegistrationHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D0E0C56B9B800853E27 /* RegistrationHandler.hxx */; }; + F8DB1D760C56B9B800853E27 /* RegistrationPersistenceManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D0F0C56B9B800853E27 /* RegistrationPersistenceManager.hxx */; }; + F8DB1D770C56B9B800853E27 /* RemoteCertStore.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D100C56B9B800853E27 /* RemoteCertStore.hxx */; }; + F8DB1D780C56B9B800853E27 /* ServerAuthManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D110C56B9B800853E27 /* ServerAuthManager.hxx */; }; + F8DB1D790C56B9B800853E27 /* ServerInviteSession.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D120C56B9B800853E27 /* ServerInviteSession.hxx */; }; + F8DB1D7A0C56B9B800853E27 /* ServerOutOfDialogReq.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D130C56B9B800853E27 /* ServerOutOfDialogReq.hxx */; }; + F8DB1D7B0C56B9B800853E27 /* ServerPagerMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D140C56B9B800853E27 /* ServerPagerMessage.hxx */; }; + F8DB1D7C0C56B9B800853E27 /* ServerPublication.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D150C56B9B800853E27 /* ServerPublication.hxx */; }; + F8DB1D7D0C56B9B800853E27 /* ServerRegistration.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D160C56B9B800853E27 /* ServerRegistration.hxx */; }; + F8DB1D7E0C56B9B800853E27 /* ServerSubscription.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D170C56B9B800853E27 /* ServerSubscription.hxx */; }; + F8DB1D7F0C56B9B800853E27 /* ServerSubscriptionFunctor.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D180C56B9B800853E27 /* ServerSubscriptionFunctor.hxx */; }; + F8DB1D800C56B9B800853E27 /* SubscriptionCreator.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D190C56B9B800853E27 /* SubscriptionCreator.hxx */; }; + F8DB1D810C56B9B800853E27 /* SubscriptionHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D1A0C56B9B800853E27 /* SubscriptionHandler.hxx */; }; + F8DB1D820C56B9B800853E27 /* SubscriptionPersistenceManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D1B0C56B9B800853E27 /* SubscriptionPersistenceManager.hxx */; }; + F8DB1D830C56B9B800853E27 /* SubscriptionState.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D1C0C56B9B800853E27 /* SubscriptionState.hxx */; }; + F8DB1D840C56B9B800853E27 /* TargetCommand.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D1D0C56B9B800853E27 /* TargetCommand.hxx */; }; + F8DB1D850C56B9B800853E27 /* UsageUseException.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D1E0C56B9B800853E27 /* UsageUseException.hxx */; }; + F8DB1D860C56B9B800853E27 /* UserAuthInfo.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D1F0C56B9B800853E27 /* UserAuthInfo.hxx */; }; + F8DB1D870C56B9B800853E27 /* UserProfile.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D200C56B9B800853E27 /* UserProfile.hxx */; }; + F8DB1D8E0C56B9EA00853E27 /* ares_compat.h in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D890C56B9EA00853E27 /* ares_compat.h */; }; + F8DB1D8F0C56B9EA00853E27 /* ares_dns.h in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D8A0C56B9EA00853E27 /* ares_dns.h */; }; + F8DB1D900C56B9EA00853E27 /* ares_local.h in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D8B0C56B9EA00853E27 /* ares_local.h */; }; + F8DB1D910C56B9EA00853E27 /* ares_private.h in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D8C0C56B9EA00853E27 /* ares_private.h */; }; + F8DB1DC30C56CE1500853E27 /* AbstractFifo.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D920C56CE1500853E27 /* AbstractFifo.hxx */; }; + F8DB1DC40C56CE1500853E27 /* AsyncID.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D930C56CE1500853E27 /* AsyncID.hxx */; }; + F8DB1DC50C56CE1500853E27 /* BaseException.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D940C56CE1500853E27 /* BaseException.hxx */; }; + F8DB1DC60C56CE1500853E27 /* CircularBuffer.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D950C56CE1500853E27 /* CircularBuffer.hxx */; }; + F8DB1DC70C56CE1500853E27 /* Coders.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D960C56CE1500853E27 /* Coders.hxx */; }; + F8DB1DC80C56CE1500853E27 /* compat.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D970C56CE1500853E27 /* compat.hxx */; }; + F8DB1DC90C56CE1500853E27 /* Condition.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D980C56CE1500853E27 /* Condition.hxx */; }; + F8DB1DCA0C56CE1500853E27 /* CountStream.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D990C56CE1500853E27 /* CountStream.hxx */; }; + F8DB1DCB0C56CE1500853E27 /* Data.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D9A0C56CE1500853E27 /* Data.hxx */; }; + F8DB1DCC0C56CE1500853E27 /* DataStream.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D9B0C56CE1500853E27 /* DataStream.hxx */; }; + F8DB1DCD0C56CE1500853E27 /* DnsUtil.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D9C0C56CE1500853E27 /* DnsUtil.hxx */; }; + F8DB1DCE0C56CE1500853E27 /* Fifo.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D9D0C56CE1500853E27 /* Fifo.hxx */; }; + F8DB1DCF0C56CE1500853E27 /* FileSystem.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D9E0C56CE1500853E27 /* FileSystem.hxx */; }; + F8DB1DD00C56CE1500853E27 /* FiniteFifo.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1D9F0C56CE1500853E27 /* FiniteFifo.hxx */; }; + F8DB1DD10C56CE1500853E27 /* GenericIPAddress.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DA00C56CE1500853E27 /* GenericIPAddress.hxx */; }; + F8DB1DD20C56CE1500853E27 /* GenericTimerQueue.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DA10C56CE1500853E27 /* GenericTimerQueue.hxx */; }; + F8DB1DD30C56CE1500853E27 /* HashMap.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DA20C56CE1500853E27 /* HashMap.hxx */; }; + F8DB1DD40C56CE1500853E27 /* HeapInstanceCounter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1DA30C56CE1500853E27 /* HeapInstanceCounter.cxx */; }; + F8DB1DD50C56CE1500853E27 /* HeapInstanceCounter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DA40C56CE1500853E27 /* HeapInstanceCounter.hxx */; }; + F8DB1DD60C56CE1500853E27 /* Inserter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DA50C56CE1500853E27 /* Inserter.hxx */; }; + F8DB1DD70C56CE1500853E27 /* IntrusiveListElement.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DA60C56CE1500853E27 /* IntrusiveListElement.hxx */; }; + F8DB1DD80C56CE1500853E27 /* Lock.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DA70C56CE1500853E27 /* Lock.hxx */; }; + F8DB1DD90C56CE1500853E27 /* Lockable.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DA80C56CE1500853E27 /* Lockable.hxx */; }; + F8DB1DDA0C56CE1500853E27 /* Log.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DA90C56CE1500853E27 /* Log.hxx */; }; + F8DB1DDB0C56CE1500853E27 /* Logger.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DAA0C56CE1500853E27 /* Logger.hxx */; }; + F8DB1DDC0C56CE1500853E27 /* MD5Stream.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DAB0C56CE1500853E27 /* MD5Stream.hxx */; }; + F8DB1DDD0C56CE1500853E27 /* Mutex.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DAC0C56CE1500853E27 /* Mutex.hxx */; }; + F8DB1DDF0C56CE1500853E27 /* OpenSSLInit.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DAE0C56CE1500853E27 /* OpenSSLInit.hxx */; }; + F8DB1DE00C56CE1500853E27 /* ParseBuffer.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DAF0C56CE1500853E27 /* ParseBuffer.hxx */; }; + F8DB1DE10C56CE1500853E27 /* Poll.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1DB00C56CE1500853E27 /* Poll.cxx */; }; + F8DB1DE20C56CE1500853E27 /* Poll.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DB10C56CE1500853E27 /* Poll.hxx */; }; + F8DB1DE30C56CE1500853E27 /* Random.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DB20C56CE1500853E27 /* Random.hxx */; }; + F8DB1DE40C56CE1500853E27 /* RecursiveMutex.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DB30C56CE1500853E27 /* RecursiveMutex.hxx */; }; + F8DB1DE50C56CE1500853E27 /* RWMutex.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DB40C56CE1500853E27 /* RWMutex.hxx */; }; + F8DB1DE60C56CE1500853E27 /* SHA1Stream.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DB50C56CE1500853E27 /* SHA1Stream.hxx */; }; + F8DB1DE70C56CE1500853E27 /* SharedCount.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DB60C56CE1500853E27 /* SharedCount.hxx */; }; + F8DB1DE80C56CE1500853E27 /* SharedPtr.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DB70C56CE1500853E27 /* SharedPtr.hxx */; }; + F8DB1DE90C56CE1500853E27 /* Socket.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DB80C56CE1500853E27 /* Socket.hxx */; }; + F8DB1DEA0C56CE1500853E27 /* Subsystem.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DB90C56CE1500853E27 /* Subsystem.hxx */; }; + F8DB1DEB0C56CE1500853E27 /* SysLogBuf.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DBA0C56CE1500853E27 /* SysLogBuf.hxx */; }; + F8DB1DEC0C56CE1500853E27 /* SysLogStream.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DBB0C56CE1500853E27 /* SysLogStream.hxx */; }; + F8DB1DED0C56CE1500853E27 /* ThreadIf.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DBC0C56CE1500853E27 /* ThreadIf.hxx */; }; + F8DB1DEE0C56CE1500853E27 /* TimeLimitFifo.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DBD0C56CE1500853E27 /* TimeLimitFifo.hxx */; }; + F8DB1DEF0C56CE1500853E27 /* Timer.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DBE0C56CE1500853E27 /* Timer.hxx */; }; + F8DB1DF00C56CE1500853E27 /* TransportType.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1DBF0C56CE1500853E27 /* TransportType.cxx */; }; + F8DB1DF10C56CE1500853E27 /* TransportType.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DC00C56CE1500853E27 /* TransportType.hxx */; }; + F8DB1DF20C56CE1500853E27 /* vmd5.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DC10C56CE1500853E27 /* vmd5.hxx */; }; + F8DB1DF30C56CE1500853E27 /* vthread.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DC20C56CE1500853E27 /* vthread.hxx */; }; + F8DB1E080C56CE3C00853E27 /* AresDns.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DF40C56CE3C00853E27 /* AresDns.hxx */; }; + F8DB1E090C56CE3C00853E27 /* DnsAAAARecord.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DF50C56CE3C00853E27 /* DnsAAAARecord.hxx */; }; + F8DB1E0A0C56CE3C00853E27 /* DnsCnameRecord.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DF60C56CE3C00853E27 /* DnsCnameRecord.hxx */; }; + F8DB1E0B0C56CE3C00853E27 /* DnsHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DF70C56CE3C00853E27 /* DnsHandler.hxx */; }; + F8DB1E0C0C56CE3C00853E27 /* DnsHostRecord.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DF80C56CE3C00853E27 /* DnsHostRecord.hxx */; }; + F8DB1E0D0C56CE3C00853E27 /* DnsNaptrRecord.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DF90C56CE3C00853E27 /* DnsNaptrRecord.hxx */; }; + F8DB1E0E0C56CE3C00853E27 /* DnsResourceRecord.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1DFA0C56CE3C00853E27 /* DnsResourceRecord.cxx */; }; + F8DB1E0F0C56CE3C00853E27 /* DnsResourceRecord.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DFB0C56CE3C00853E27 /* DnsResourceRecord.hxx */; }; + F8DB1E100C56CE3C00853E27 /* DnsSrvRecord.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DFC0C56CE3C00853E27 /* DnsSrvRecord.hxx */; }; + F8DB1E110C56CE3C00853E27 /* DnsStub.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DFD0C56CE3C00853E27 /* DnsStub.hxx */; }; + F8DB1E120C56CE3C00853E27 /* ExternalDns.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DFE0C56CE3C00853E27 /* ExternalDns.hxx */; }; + F8DB1E130C56CE3C00853E27 /* ExternalDnsFactory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1DFF0C56CE3C00853E27 /* ExternalDnsFactory.hxx */; }; + F8DB1E140C56CE3C00853E27 /* LocalDns.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E000C56CE3C00853E27 /* LocalDns.cxx */; }; + F8DB1E150C56CE3C00853E27 /* LocalDns.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E010C56CE3C00853E27 /* LocalDns.hxx */; }; + F8DB1E160C56CE3C00853E27 /* QueryTypes.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E020C56CE3C00853E27 /* QueryTypes.hxx */; }; + F8DB1E170C56CE3C00853E27 /* RRCache.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E030C56CE3C00853E27 /* RRCache.hxx */; }; + F8DB1E180C56CE3C00853E27 /* RRFactory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E040C56CE3C00853E27 /* RRFactory.hxx */; }; + F8DB1E190C56CE3C00853E27 /* RRList.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E050C56CE3C00853E27 /* RRList.hxx */; }; + F8DB1E1A0C56CE3C00853E27 /* RROverlay.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E060C56CE3C00853E27 /* RROverlay.hxx */; }; + F8DB1E1B0C56CE3C00853E27 /* RRVip.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E070C56CE3C00853E27 /* RRVip.hxx */; }; + F8DB1ECC0C56CE9800853E27 /* Aor.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E1C0C56CE9800853E27 /* Aor.cxx */; }; + F8DB1ECD0C56CE9800853E27 /* Aor.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E1D0C56CE9800853E27 /* Aor.hxx */; }; + F8DB1ECE0C56CE9800853E27 /* ApiCheck.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E1E0C56CE9800853E27 /* ApiCheck.hxx */; }; + F8DB1ECF0C56CE9800853E27 /* ApiCheckList.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E1F0C56CE9800853E27 /* ApiCheckList.hxx */; }; + F8DB1ED00C56CE9800853E27 /* ApplicationMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E200C56CE9800853E27 /* ApplicationMessage.hxx */; }; + F8DB1ED10C56CE9800853E27 /* ApplicationSip.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E210C56CE9800853E27 /* ApplicationSip.cxx */; }; + F8DB1ED20C56CE9800853E27 /* ApplicationSip.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E220C56CE9800853E27 /* ApplicationSip.hxx */; }; + F8DB1ED40C56CE9800853E27 /* Auth.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E240C56CE9800853E27 /* Auth.hxx */; }; + F8DB1ED50C56CE9800853E27 /* BasicNonceHelper.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E250C56CE9800853E27 /* BasicNonceHelper.cxx */; }; + F8DB1ED60C56CE9800853E27 /* BasicNonceHelper.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E260C56CE9800853E27 /* BasicNonceHelper.hxx */; }; + F8DB1ED70C56CE9800853E27 /* BranchParameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E270C56CE9800853E27 /* BranchParameter.hxx */; }; + F8DB1ED80C56CE9800853E27 /* CallId.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E280C56CE9800853E27 /* CallId.hxx */; }; + F8DB1ED90C56CE9800853E27 /* CancelableTimerQueue.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E290C56CE9800853E27 /* CancelableTimerQueue.hxx */; }; + F8DB1EDA0C56CE9800853E27 /* Compression.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E2A0C56CE9800853E27 /* Compression.cxx */; }; + F8DB1EDB0C56CE9800853E27 /* Compression.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E2B0C56CE9800853E27 /* Compression.hxx */; }; + F8DB1EDC0C56CE9800853E27 /* Connection.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E2C0C56CE9800853E27 /* Connection.hxx */; }; + F8DB1EDD0C56CE9800853E27 /* ConnectionBase.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E2D0C56CE9800853E27 /* ConnectionBase.hxx */; }; + F8DB1EDE0C56CE9800853E27 /* ConnectionManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E2E0C56CE9800853E27 /* ConnectionManager.hxx */; }; + F8DB1EDF0C56CE9800853E27 /* ConnectionTerminated.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E2F0C56CE9800853E27 /* ConnectionTerminated.hxx */; }; + F8DB1EE00C56CE9800853E27 /* Contents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E300C56CE9800853E27 /* Contents.hxx */; }; + F8DB1EE10C56CE9800853E27 /* ContentsFactory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E310C56CE9800853E27 /* ContentsFactory.hxx */; }; + F8DB1EE20C56CE9800853E27 /* ContentsFactoryBase.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E320C56CE9800853E27 /* ContentsFactoryBase.hxx */; }; + F8DB1EE30C56CE9800853E27 /* CpimContents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E330C56CE9800853E27 /* CpimContents.hxx */; }; + F8DB1EE40C56CE9800853E27 /* CSeqCategory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E340C56CE9800853E27 /* CSeqCategory.hxx */; }; + F8DB1EE50C56CE9800853E27 /* DataParameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E350C56CE9800853E27 /* DataParameter.hxx */; }; + F8DB1EE60C56CE9800853E27 /* DateCategory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E360C56CE9800853E27 /* DateCategory.hxx */; }; + F8DB1EE70C56CE9800853E27 /* DeprecatedDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E370C56CE9800853E27 /* DeprecatedDialog.cxx */; }; + F8DB1EE80C56CE9800853E27 /* DeprecatedDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E380C56CE9800853E27 /* DeprecatedDialog.hxx */; }; + F8DB1EE90C56CE9800853E27 /* DnsInterface.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E390C56CE9800853E27 /* DnsInterface.hxx */; }; + F8DB1EEA0C56CE9800853E27 /* DnsResult.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E3A0C56CE9800853E27 /* DnsResult.hxx */; }; + F8DB1EEB0C56CE9800853E27 /* DtlsMessage.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E3B0C56CE9800853E27 /* DtlsMessage.cxx */; }; + F8DB1EEC0C56CE9800853E27 /* DtlsMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E3C0C56CE9800853E27 /* DtlsMessage.hxx */; }; + F8DB1EED0C56CE9800853E27 /* DtlsTransport.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E3D0C56CE9800853E27 /* DtlsTransport.cxx */; }; + F8DB1EEE0C56CE9800853E27 /* DtlsTransport.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E3E0C56CE9800853E27 /* DtlsTransport.hxx */; }; + F8DB1EEF0C56CE9800853E27 /* Embedded.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E3F0C56CE9800853E27 /* Embedded.hxx */; }; + F8DB1EF00C56CE9800853E27 /* ExistsParameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E400C56CE9800853E27 /* ExistsParameter.hxx */; }; + F8DB1EF10C56CE9800853E27 /* ExpiresCategory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E410C56CE9800853E27 /* ExpiresCategory.hxx */; }; + F8DB1EF20C56CE9800853E27 /* ExtensionHeader.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E420C56CE9800853E27 /* ExtensionHeader.hxx */; }; + F8DB1EF30C56CE9800853E27 /* ExtensionParameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E430C56CE9800853E27 /* ExtensionParameter.hxx */; }; + F8DB1EF40C56CE9800853E27 /* ExternalBodyContents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E440C56CE9800853E27 /* ExternalBodyContents.hxx */; }; + F8DB1EF50C56CE9800853E27 /* FloatParameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E450C56CE9800853E27 /* FloatParameter.hxx */; }; + F8DB1EF80C56CE9800853E27 /* GenericContents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E480C56CE9800853E27 /* GenericContents.hxx */; }; + F8DB1EF90C56CE9800853E27 /* GenericUri.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E490C56CE9800853E27 /* GenericUri.hxx */; }; + F8DB1EFA0C56CE9800853E27 /* HeaderFieldValue.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E4A0C56CE9800853E27 /* HeaderFieldValue.hxx */; }; + F8DB1EFB0C56CE9800853E27 /* HeaderFieldValueList.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E4B0C56CE9800853E27 /* HeaderFieldValueList.hxx */; }; + F8DB1EFC0C56CE9800853E27 /* HeaderHash.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E4C0C56CE9800853E27 /* HeaderHash.hxx */; }; + F8DB1EFD0C56CE9800853E27 /* Headers.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E4D0C56CE9800853E27 /* Headers.hxx */; }; + F8DB1EFE0C56CE9800853E27 /* HeaderTypes.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E4E0C56CE9800853E27 /* HeaderTypes.hxx */; }; + F8DB1EFF0C56CE9800853E27 /* Helper.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E4F0C56CE9800853E27 /* Helper.hxx */; }; + F8DB1F000C56CE9800853E27 /* IntegerCategory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E500C56CE9800853E27 /* IntegerCategory.hxx */; }; + F8DB1F010C56CE9800853E27 /* IntegerParameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E510C56CE9800853E27 /* IntegerParameter.hxx */; }; + F8DB1F020C56CE9800853E27 /* InternalTransport.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E520C56CE9800853E27 /* InternalTransport.hxx */; }; + F8DB1F030C56CE9800853E27 /* InterruptableStackThread.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E530C56CE9800853E27 /* InterruptableStackThread.cxx */; }; + F8DB1F040C56CE9800853E27 /* InterruptableStackThread.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E540C56CE9800853E27 /* InterruptableStackThread.hxx */; }; + F8DB1F050C56CE9800853E27 /* InvalidContents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E550C56CE9800853E27 /* InvalidContents.cxx */; }; + F8DB1F060C56CE9800853E27 /* InvalidContents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E560C56CE9800853E27 /* InvalidContents.hxx */; }; + F8DB1F070C56CE9800853E27 /* KeepAliveMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E570C56CE9800853E27 /* KeepAliveMessage.hxx */; }; + F8DB1F080C56CE9800853E27 /* LazyParser.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E580C56CE9800853E27 /* LazyParser.hxx */; }; + F8DB1F090C56CE9800853E27 /* MacSecurity.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E590C56CE9800853E27 /* MacSecurity.hxx */; }; + F8DB1F0A0C56CE9800853E27 /* makeCert.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E5A0C56CE9800853E27 /* makeCert.cxx */; }; + F8DB1F0B0C56CE9800853E27 /* MarkListener.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E5B0C56CE9800853E27 /* MarkListener.hxx */; }; + F8DB1F0C0C56CE9800853E27 /* Message.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E5C0C56CE9800853E27 /* Message.hxx */; }; + F8DB1F0D0C56CE9800853E27 /* MessageDecorator.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E5D0C56CE9800853E27 /* MessageDecorator.hxx */; }; + F8DB1F0E0C56CE9800853E27 /* MessageFilterRule.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E5E0C56CE9800853E27 /* MessageFilterRule.hxx */; }; + F8DB1F0F0C56CE9800853E27 /* MessageWaitingContents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E5F0C56CE9800853E27 /* MessageWaitingContents.hxx */; }; + F8DB1F100C56CE9800853E27 /* MethodHash.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E600C56CE9800853E27 /* MethodHash.hxx */; }; + F8DB1F110C56CE9800853E27 /* MethodTypes.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E610C56CE9800853E27 /* MethodTypes.hxx */; }; + F8DB1F120C56CE9800853E27 /* Mime.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E620C56CE9800853E27 /* Mime.hxx */; }; + F8DB1F130C56CE9800853E27 /* MsgHeaderScanner.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E630C56CE9800853E27 /* MsgHeaderScanner.hxx */; }; + F8DB1F140C56CE9800853E27 /* MultipartAlternativeContents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E640C56CE9800853E27 /* MultipartAlternativeContents.hxx */; }; + F8DB1F150C56CE9800853E27 /* MultipartMixedContents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E650C56CE9800853E27 /* MultipartMixedContents.hxx */; }; + F8DB1F160C56CE9800853E27 /* MultipartRelatedContents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E660C56CE9800853E27 /* MultipartRelatedContents.hxx */; }; + F8DB1F170C56CE9800853E27 /* MultipartSignedContents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E670C56CE9800853E27 /* MultipartSignedContents.hxx */; }; + F8DB1F180C56CE9800853E27 /* NameAddr.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E680C56CE9800853E27 /* NameAddr.hxx */; }; + F8DB1F190C56CE9800853E27 /* NonceHelper.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E690C56CE9800853E27 /* NonceHelper.cxx */; }; + F8DB1F1A0C56CE9800853E27 /* NonceHelper.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E6A0C56CE9800853E27 /* NonceHelper.hxx */; }; + F8DB1F1B0C56CE9800853E27 /* OctetContents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E6B0C56CE9800853E27 /* OctetContents.hxx */; }; + F8DB1F1C0C56CE9800853E27 /* Parameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E6C0C56CE9800853E27 /* Parameter.hxx */; }; + F8DB1F1D0C56CE9800853E27 /* ParameterHash.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E6E0C56CE9800853E27 /* ParameterHash.hxx */; }; + F8DB1F1E0C56CE9800853E27 /* ParameterTypeEnums.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E6F0C56CE9800853E27 /* ParameterTypeEnums.hxx */; }; + F8DB1F1F0C56CE9800853E27 /* ParameterTypes.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E700C56CE9800853E27 /* ParameterTypes.hxx */; }; + F8DB1F210C56CE9800853E27 /* ParserCategories.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E720C56CE9800853E27 /* ParserCategories.hxx */; }; + F8DB1F220C56CE9800853E27 /* ParserCategory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E730C56CE9800853E27 /* ParserCategory.hxx */; }; + F8DB1F230C56CE9800853E27 /* ParserContainer.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E740C56CE9800853E27 /* ParserContainer.hxx */; }; + F8DB1F240C56CE9800853E27 /* ParserContainerBase.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E750C56CE9800853E27 /* ParserContainerBase.hxx */; }; + F8DB1F250C56CE9800853E27 /* Pidf.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E760C56CE9800853E27 /* Pidf.cxx */; }; + F8DB1F260C56CE9800853E27 /* Pidf.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E770C56CE9800853E27 /* Pidf.hxx */; }; + F8DB1F270C56CE9800853E27 /* Pkcs7Contents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E780C56CE9800853E27 /* Pkcs7Contents.hxx */; }; + F8DB1F280C56CE9800853E27 /* Pkcs8Contents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E790C56CE9800853E27 /* Pkcs8Contents.cxx */; }; + F8DB1F290C56CE9800853E27 /* Pkcs8Contents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E7A0C56CE9800853E27 /* Pkcs8Contents.hxx */; }; + F8DB1F2A0C56CE9800853E27 /* PlainContents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E7B0C56CE9800853E27 /* PlainContents.hxx */; }; + F8DB1F2C0C56CE9800853E27 /* QuotedDataParameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E7D0C56CE9800853E27 /* QuotedDataParameter.hxx */; }; + F8DB1F2D0C56CE9800853E27 /* QValue.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E7E0C56CE9800853E27 /* QValue.cxx */; }; + F8DB1F2E0C56CE9800853E27 /* QValue.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E7F0C56CE9800853E27 /* QValue.hxx */; }; + F8DB1F2F0C56CE9800853E27 /* QValueParameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E800C56CE9800853E27 /* QValueParameter.cxx */; }; + F8DB1F300C56CE9800853E27 /* QValueParameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E810C56CE9800853E27 /* QValueParameter.hxx */; }; + F8DB1F310C56CE9800853E27 /* RAckCategory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E820C56CE9800853E27 /* RAckCategory.hxx */; }; + F8DB1F320C56CE9800853E27 /* RequestLine.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E860C56CE9800853E27 /* RequestLine.hxx */; }; + F8DB1F330C56CE9800853E27 /* Rlmi.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E870C56CE9800853E27 /* Rlmi.cxx */; }; + F8DB1F340C56CE9800853E27 /* Rlmi.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E880C56CE9800853E27 /* Rlmi.hxx */; }; + F8DB1F350C56CE9800853E27 /* RportParameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E890C56CE9800853E27 /* RportParameter.hxx */; }; + F8DB1F360C56CE9800853E27 /* SdpContents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E8A0C56CE9800853E27 /* SdpContents.hxx */; }; + F8DB1F370C56CE9800853E27 /* Security.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E8B0C56CE9800853E27 /* Security.hxx */; }; + F8DB1F380C56CE9800853E27 /* SecurityAttributes.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E8C0C56CE9800853E27 /* SecurityAttributes.hxx */; }; + F8DB1F390C56CE9800853E27 /* SecurityTypes.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E8D0C56CE9800853E27 /* SecurityTypes.hxx */; }; + F8DB1F3A0C56CE9800853E27 /* SelectInterruptor.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E8E0C56CE9800853E27 /* SelectInterruptor.cxx */; }; + F8DB1F3B0C56CE9800853E27 /* SelectInterruptor.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E8F0C56CE9800853E27 /* SelectInterruptor.hxx */; }; + F8DB1F3C0C56CE9800853E27 /* SendData.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E900C56CE9800853E27 /* SendData.hxx */; }; + F8DB1F3D0C56CE9800853E27 /* SERNonceHelper.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E910C56CE9800853E27 /* SERNonceHelper.cxx */; }; + F8DB1F3E0C56CE9800853E27 /* SERNonceHelper.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E920C56CE9800853E27 /* SERNonceHelper.hxx */; }; + F8DB1F3F0C56CE9800853E27 /* ShutdownMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E930C56CE9800853E27 /* ShutdownMessage.hxx */; }; + F8DB1F400C56CE9800853E27 /* SipFrag.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E940C56CE9800853E27 /* SipFrag.hxx */; }; + F8DB1F410C56CE9800853E27 /* SipMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E950C56CE9800853E27 /* SipMessage.hxx */; }; + F8DB1F420C56CE9800853E27 /* SipStack.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E960C56CE9800853E27 /* SipStack.hxx */; }; + F8DB1F430C56CE9800853E27 /* StackThread.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E970C56CE9800853E27 /* StackThread.hxx */; }; + F8DB1F440C56CE9800853E27 /* StatelessHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E980C56CE9800853E27 /* StatelessHandler.hxx */; }; + F8DB1F450C56CE9800853E27 /* StatisticsHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1E990C56CE9800853E27 /* StatisticsHandler.cxx */; }; + F8DB1F460C56CE9800853E27 /* StatisticsHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E9A0C56CE9800853E27 /* StatisticsHandler.hxx */; }; + F8DB1F470C56CE9800853E27 /* StatisticsManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E9B0C56CE9800853E27 /* StatisticsManager.hxx */; }; + F8DB1F480C56CE9800853E27 /* StatisticsMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E9C0C56CE9800853E27 /* StatisticsMessage.hxx */; }; + F8DB1F490C56CE9800853E27 /* StatusLine.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E9D0C56CE9800853E27 /* StatusLine.hxx */; }; + F8DB1F4A0C56CE9800853E27 /* StringCategory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E9E0C56CE9800853E27 /* StringCategory.hxx */; }; + F8DB1F4B0C56CE9800853E27 /* Symbols.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1E9F0C56CE9800853E27 /* Symbols.hxx */; }; + F8DB1F4C0C56CE9800853E27 /* TcpBaseTransport.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EA00C56CE9800853E27 /* TcpBaseTransport.hxx */; }; + F8DB1F4D0C56CE9800853E27 /* TcpConnection.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EA10C56CE9800853E27 /* TcpConnection.hxx */; }; + F8DB1F4E0C56CE9800853E27 /* TcpTransport.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EA20C56CE9800853E27 /* TcpTransport.hxx */; }; + F8DB1F4F0C56CE9800853E27 /* TimeAccumulate.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1EA30C56CE9800853E27 /* TimeAccumulate.cxx */; }; + F8DB1F500C56CE9800853E27 /* TimeAccumulate.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EA40C56CE9800853E27 /* TimeAccumulate.hxx */; }; + F8DB1F510C56CE9800853E27 /* TimerMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EA50C56CE9800853E27 /* TimerMessage.hxx */; }; + F8DB1F520C56CE9800853E27 /* TimerQueue.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EA60C56CE9800853E27 /* TimerQueue.hxx */; }; + F8DB1F530C56CE9800853E27 /* TlsConnection.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EA70C56CE9800853E27 /* TlsConnection.hxx */; }; + F8DB1F540C56CE9800853E27 /* TlsTransport.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EA80C56CE9800853E27 /* TlsTransport.hxx */; }; + F8DB1F550C56CE9800853E27 /* Token.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EA90C56CE9800853E27 /* Token.hxx */; }; + F8DB1F560C56CE9800853E27 /* TransactionController.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EAA0C56CE9800853E27 /* TransactionController.hxx */; }; + F8DB1F570C56CE9800853E27 /* TransactionMap.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EAB0C56CE9800853E27 /* TransactionMap.hxx */; }; + F8DB1F580C56CE9800853E27 /* TransactionMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EAC0C56CE9800853E27 /* TransactionMessage.hxx */; }; + F8DB1F590C56CE9800853E27 /* TransactionState.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EAD0C56CE9800853E27 /* TransactionState.hxx */; }; + F8DB1F5A0C56CE9800853E27 /* TransactionTerminated.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EAE0C56CE9800853E27 /* TransactionTerminated.hxx */; }; + F8DB1F5B0C56CE9800853E27 /* TransactionUser.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EAF0C56CE9800853E27 /* TransactionUser.hxx */; }; + F8DB1F5C0C56CE9800853E27 /* TransactionUserMessage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EB00C56CE9800853E27 /* TransactionUserMessage.hxx */; }; + F8DB1F5D0C56CE9800853E27 /* Transport.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EB10C56CE9800853E27 /* Transport.hxx */; }; + F8DB1F5E0C56CE9800853E27 /* TransportFailure.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EB20C56CE9800853E27 /* TransportFailure.hxx */; }; + F8DB1F5F0C56CE9800853E27 /* TransportSelector.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EB30C56CE9800853E27 /* TransportSelector.hxx */; }; + F8DB1F600C56CE9800853E27 /* TuIM.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1EB40C56CE9800853E27 /* TuIM.cxx */; }; + F8DB1F610C56CE9800853E27 /* TuIM.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EB50C56CE9800853E27 /* TuIM.hxx */; }; + F8DB1F620C56CE9800853E27 /* Tuple.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EB60C56CE9800853E27 /* Tuple.hxx */; }; + F8DB1F630C56CE9800853E27 /* TupleMarkManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1EB70C56CE9800853E27 /* TupleMarkManager.cxx */; }; + F8DB1F640C56CE9800853E27 /* TupleMarkManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EB80C56CE9800853E27 /* TupleMarkManager.hxx */; }; + F8DB1F650C56CE9800853E27 /* TuSelector.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EB90C56CE9800853E27 /* TuSelector.hxx */; }; + F8DB1F660C56CE9800853E27 /* UdpTransport.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EBA0C56CE9800853E27 /* UdpTransport.hxx */; }; + F8DB1F670C56CE9800853E27 /* UInt32Category.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1EBB0C56CE9800853E27 /* UInt32Category.cxx */; }; + F8DB1F680C56CE9800853E27 /* UInt32Category.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EBC0C56CE9800853E27 /* UInt32Category.hxx */; }; + F8DB1F690C56CE9800853E27 /* UInt32Parameter.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1EBD0C56CE9800853E27 /* UInt32Parameter.cxx */; }; + F8DB1F6A0C56CE9800853E27 /* UInt32Parameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EBE0C56CE9800853E27 /* UInt32Parameter.hxx */; }; + F8DB1F6B0C56CE9800853E27 /* UnknownHeaderType.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EBF0C56CE9800853E27 /* UnknownHeaderType.hxx */; }; + F8DB1F6C0C56CE9800853E27 /* UnknownParameter.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EC00C56CE9800853E27 /* UnknownParameter.hxx */; }; + F8DB1F6D0C56CE9800853E27 /* UnknownParameterType.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EC10C56CE9800853E27 /* UnknownParameterType.hxx */; }; + F8DB1F6E0C56CE9800853E27 /* Uri.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EC20C56CE9800853E27 /* Uri.hxx */; }; + F8DB1F6F0C56CE9800853E27 /* ValueFifo.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EC30C56CE9800853E27 /* ValueFifo.hxx */; }; + F8DB1F700C56CE9800853E27 /* Via.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EC40C56CE9800853E27 /* Via.hxx */; }; + F8DB1F710C56CE9800853E27 /* WarningCategory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EC50C56CE9800853E27 /* WarningCategory.hxx */; }; + F8DB1F740C56CE9800853E27 /* X509Contents.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1EC80C56CE9800853E27 /* X509Contents.cxx */; }; + F8DB1F750C56CE9800853E27 /* X509Contents.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1EC90C56CE9800853E27 /* X509Contents.hxx */; }; + F8DB1F760C56CE9800853E27 /* XMLCursor.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1ECA0C56CE9800853E27 /* XMLCursor.cxx */; }; + F8DB1F770C56CE9800853E27 /* XMLCursor.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1ECB0C56CE9800853E27 /* XMLCursor.hxx */; }; + F8DB1F7D0C56CEEC00853E27 /* Stun.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1F790C56CEEC00853E27 /* Stun.cxx */; }; + F8DB1F7E0C56CEEC00853E27 /* Stun.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1F7A0C56CEEC00853E27 /* Stun.hxx */; }; + F8DB1F7F0C56CEEC00853E27 /* Udp.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8DB1F7B0C56CEEC00853E27 /* Udp.cxx */; }; + F8DB1F800C56CEEC00853E27 /* Udp.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8DB1F7C0C56CEEC00853E27 /* Udp.hxx */; }; + F8DB1FB40C56D49A00853E27 /* libresiprocate.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 12F79738086CBA1E00AF4EDF /* libresiprocate.a */; }; + F8DB1FB80C56D4B000853E27 /* libares.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AAC06F0554671400DB518D /* libares.a */; }; + F8DB20730C56D75B00853E27 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8DB20720C56D75B00853E27 /* SystemConfiguration.framework */; }; + F8DB20880C56D77100853E27 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8DB20720C56D75B00853E27 /* SystemConfiguration.framework */; }; + F8DB20A00C56DAD700853E27 /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F8DB209C0C56DAC300853E27 /* libcrypto.dylib */; }; + F8DB20A10C56DAD700853E27 /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F8DB209D0C56DAC300853E27 /* libssl.dylib */; }; + F8F4ED4D133D2F000000D69D /* TlsConnection.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 124D791A086CC3CE00BCA5A9 /* TlsConnection.cxx */; }; + F8F4ED77133D36380000D69D /* EnableFlowTimer.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8F4ED72133D36380000D69D /* EnableFlowTimer.hxx */; }; + F8F4ED78133D36380000D69D /* EventStackThread.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8F4ED73133D36380000D69D /* EventStackThread.cxx */; }; + F8F4ED79133D36380000D69D /* EventStackThread.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8F4ED74133D36380000D69D /* EventStackThread.hxx */; }; + F8F4ED7A133D36380000D69D /* KeepAlivePong.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8F4ED75133D36380000D69D /* KeepAlivePong.hxx */; }; + F8F4ED7B133D36380000D69D /* TerminateFlow.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8F4ED76133D36380000D69D /* TerminateFlow.hxx */; }; + F8F4ED7F133D365D0000D69D /* RequestValidationHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = F8F4ED7E133D365D0000D69D /* RequestValidationHandler.hxx */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + F8DB1C960C56B82600853E27 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 12F7972F086CBA1E00AF4EDF; + remoteInfo = resiprocate; + }; + F8DB1C980C56B82F00853E27 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC06E0554671400DB518D; + remoteInfo = ares; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 12396E3608A2F3C800C5ED5E /* DumFeature.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DumFeature.cxx; path = dum/DumFeature.cxx; sourceTree = "<group>"; }; + 12396E6908A2F91E00C5ED5E /* OutgoingEvent.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = OutgoingEvent.cxx; path = dum/OutgoingEvent.cxx; sourceTree = "<group>"; }; + 12396E6B08A2F93400C5ED5E /* TargetCommand.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TargetCommand.cxx; path = dum/TargetCommand.cxx; sourceTree = "<group>"; }; + 123B4D4E089871C90049A5B9 /* DumFeatureChain.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DumFeatureChain.cxx; path = dum/DumFeatureChain.cxx; sourceTree = "<group>"; }; + 123B4D52089871F70049A5B9 /* IdentityHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = IdentityHandler.cxx; path = dum/IdentityHandler.cxx; sourceTree = "<group>"; }; + 123B4D54089872040049A5B9 /* EncryptionRequest.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = EncryptionRequest.cxx; path = dum/EncryptionRequest.cxx; sourceTree = "<group>"; }; + 123B4D560898721D0049A5B9 /* DumFeatureMessage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DumFeatureMessage.cxx; path = dum/DumFeatureMessage.cxx; sourceTree = "<group>"; }; + 124D789C086CC36600BCA5A9 /* ares__close_sockets.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares__close_sockets.c; path = ../contrib/ares/ares__close_sockets.c; sourceTree = SOURCE_ROOT; }; + 124D789D086CC36600BCA5A9 /* ares__get_hostent.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares__get_hostent.c; path = ../contrib/ares/ares__get_hostent.c; sourceTree = SOURCE_ROOT; }; + 124D789E086CC36600BCA5A9 /* ares__read_line.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares__read_line.c; path = ../contrib/ares/ares__read_line.c; sourceTree = SOURCE_ROOT; }; + 124D789F086CC36600BCA5A9 /* ares_destroy.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_destroy.c; path = ../contrib/ares/ares_destroy.c; sourceTree = SOURCE_ROOT; }; + 124D78A0086CC36600BCA5A9 /* ares_expand_name.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_expand_name.c; path = ../contrib/ares/ares_expand_name.c; sourceTree = SOURCE_ROOT; }; + 124D78A1086CC36600BCA5A9 /* ares_fds.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_fds.c; path = ../contrib/ares/ares_fds.c; sourceTree = SOURCE_ROOT; }; + 124D78A2086CC36600BCA5A9 /* ares_free_errmem.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_free_errmem.c; path = ../contrib/ares/ares_free_errmem.c; sourceTree = SOURCE_ROOT; }; + 124D78A3086CC36600BCA5A9 /* ares_free_hostent.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_free_hostent.c; path = ../contrib/ares/ares_free_hostent.c; sourceTree = SOURCE_ROOT; }; + 124D78A4086CC36600BCA5A9 /* ares_free_string.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_free_string.c; path = ../contrib/ares/ares_free_string.c; sourceTree = SOURCE_ROOT; }; + 124D78A5086CC36600BCA5A9 /* ares_gethostbyaddr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_gethostbyaddr.c; path = ../contrib/ares/ares_gethostbyaddr.c; sourceTree = SOURCE_ROOT; }; + 124D78A6086CC36600BCA5A9 /* ares_gethostbyname.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_gethostbyname.c; path = ../contrib/ares/ares_gethostbyname.c; sourceTree = SOURCE_ROOT; }; + 124D78A7086CC36600BCA5A9 /* ares_init.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_init.c; path = ../contrib/ares/ares_init.c; sourceTree = SOURCE_ROOT; }; + 124D78A8086CC36600BCA5A9 /* ares_local.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_local.c; path = ../contrib/ares/ares_local.c; sourceTree = SOURCE_ROOT; }; + 124D78A9086CC36600BCA5A9 /* ares_mkquery.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_mkquery.c; path = ../contrib/ares/ares_mkquery.c; sourceTree = SOURCE_ROOT; }; + 124D78AA086CC36600BCA5A9 /* ares_parse_a_reply.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_parse_a_reply.c; path = ../contrib/ares/ares_parse_a_reply.c; sourceTree = SOURCE_ROOT; }; + 124D78AB086CC36600BCA5A9 /* ares_parse_ptr_reply.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_parse_ptr_reply.c; path = ../contrib/ares/ares_parse_ptr_reply.c; sourceTree = SOURCE_ROOT; }; + 124D78AC086CC36600BCA5A9 /* ares_process.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_process.c; path = ../contrib/ares/ares_process.c; sourceTree = SOURCE_ROOT; }; + 124D78AD086CC36600BCA5A9 /* ares_query.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_query.c; path = ../contrib/ares/ares_query.c; sourceTree = SOURCE_ROOT; }; + 124D78AE086CC36600BCA5A9 /* ares_search.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_search.c; path = ../contrib/ares/ares_search.c; sourceTree = SOURCE_ROOT; }; + 124D78AF086CC36600BCA5A9 /* ares_send.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_send.c; path = ../contrib/ares/ares_send.c; sourceTree = SOURCE_ROOT; }; + 124D78B0086CC36600BCA5A9 /* ares_strerror.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_strerror.c; path = ../contrib/ares/ares_strerror.c; sourceTree = SOURCE_ROOT; }; + 124D78B1086CC36600BCA5A9 /* ares_timeout.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ares_timeout.c; path = ../contrib/ares/ares_timeout.c; sourceTree = SOURCE_ROOT; }; + 124D78CA086CC3CE00BCA5A9 /* ApiCheck.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ApiCheck.cxx; path = stack/ApiCheck.cxx; sourceTree = "<group>"; }; + 124D78CB086CC3CE00BCA5A9 /* AresDns.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AresDns.cxx; path = ../rutil/dns/AresDns.cxx; sourceTree = "<group>"; }; + 124D78CC086CC3CE00BCA5A9 /* Auth.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Auth.cxx; path = stack/Auth.cxx; sourceTree = "<group>"; }; + 124D78CD086CC3CE00BCA5A9 /* BranchParameter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BranchParameter.cxx; path = stack/BranchParameter.cxx; sourceTree = "<group>"; }; + 124D78CE086CC3CE00BCA5A9 /* CallId.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CallId.cxx; path = stack/CallId.cxx; sourceTree = "<group>"; }; + 124D78CF086CC3CE00BCA5A9 /* Connection.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Connection.cxx; path = stack/Connection.cxx; sourceTree = "<group>"; }; + 124D78D0086CC3CE00BCA5A9 /* ConnectionBase.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ConnectionBase.cxx; path = stack/ConnectionBase.cxx; sourceTree = "<group>"; }; + 124D78D1086CC3CE00BCA5A9 /* ConnectionManager.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ConnectionManager.cxx; path = stack/ConnectionManager.cxx; sourceTree = "<group>"; }; + 124D78D2086CC3CE00BCA5A9 /* Contents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Contents.cxx; path = stack/Contents.cxx; sourceTree = "<group>"; }; + 124D78D3086CC3CE00BCA5A9 /* CpimContents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CpimContents.cxx; path = stack/CpimContents.cxx; sourceTree = "<group>"; }; + 124D78D4086CC3CE00BCA5A9 /* CSeqCategory.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CSeqCategory.cxx; path = stack/CSeqCategory.cxx; sourceTree = "<group>"; }; + 124D78D5086CC3CE00BCA5A9 /* DataParameter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DataParameter.cxx; path = stack/DataParameter.cxx; sourceTree = "<group>"; }; + 124D78D6086CC3CE00BCA5A9 /* DateCategory.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DateCategory.cxx; path = stack/DateCategory.cxx; sourceTree = "<group>"; }; + 124D78D7086CC3CE00BCA5A9 /* DnsInterface.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DnsInterface.cxx; path = stack/DnsInterface.cxx; sourceTree = "<group>"; }; + 124D78D8086CC3CE00BCA5A9 /* DnsResult.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DnsResult.cxx; path = stack/DnsResult.cxx; sourceTree = "<group>"; }; + 124D78D9086CC3CE00BCA5A9 /* Embedded.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Embedded.cxx; path = stack/Embedded.cxx; sourceTree = "<group>"; }; + 124D78DA086CC3CE00BCA5A9 /* ExistsParameter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ExistsParameter.cxx; path = stack/ExistsParameter.cxx; sourceTree = "<group>"; }; + 124D78DB086CC3CE00BCA5A9 /* ExpiresCategory.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ExpiresCategory.cxx; path = stack/ExpiresCategory.cxx; sourceTree = "<group>"; }; + 124D78DC086CC3CE00BCA5A9 /* ExternalBodyContents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ExternalBodyContents.cxx; path = stack/ExternalBodyContents.cxx; sourceTree = "<group>"; }; + 124D78DD086CC3CE00BCA5A9 /* ExternalDnsFactory.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ExternalDnsFactory.cxx; path = ../rutil/dns/ExternalDnsFactory.cxx; sourceTree = "<group>"; }; + 124D78DE086CC3CE00BCA5A9 /* FloatParameter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = FloatParameter.cxx; path = stack/FloatParameter.cxx; sourceTree = "<group>"; }; + 124D78DF086CC3CE00BCA5A9 /* GenericContents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = GenericContents.cxx; path = stack/GenericContents.cxx; sourceTree = "<group>"; }; + 124D78E0086CC3CE00BCA5A9 /* GenericUri.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = GenericUri.cxx; path = stack/GenericUri.cxx; sourceTree = "<group>"; }; + 124D78E1086CC3CE00BCA5A9 /* HeaderFieldValue.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = HeaderFieldValue.cxx; path = stack/HeaderFieldValue.cxx; sourceTree = "<group>"; }; + 124D78E2086CC3CE00BCA5A9 /* HeaderFieldValueList.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = HeaderFieldValueList.cxx; path = stack/HeaderFieldValueList.cxx; sourceTree = "<group>"; }; + 124D78E3086CC3CE00BCA5A9 /* HeaderHash.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = HeaderHash.cxx; path = stack/HeaderHash.cxx; sourceTree = "<group>"; }; + 124D78E4086CC3CE00BCA5A9 /* Headers.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Headers.cxx; path = stack/Headers.cxx; sourceTree = "<group>"; }; + 124D78E5086CC3CE00BCA5A9 /* HeaderTypes.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = HeaderTypes.cxx; path = stack/HeaderTypes.cxx; sourceTree = "<group>"; }; + 124D78E6086CC3CE00BCA5A9 /* Helper.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Helper.cxx; path = stack/Helper.cxx; sourceTree = "<group>"; }; + 124D78E7086CC3CE00BCA5A9 /* IntegerCategory.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = IntegerCategory.cxx; path = stack/IntegerCategory.cxx; sourceTree = "<group>"; }; + 124D78E8086CC3CE00BCA5A9 /* IntegerParameter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = IntegerParameter.cxx; path = stack/IntegerParameter.cxx; sourceTree = "<group>"; }; + 124D78E9086CC3CE00BCA5A9 /* InternalTransport.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = InternalTransport.cxx; path = stack/InternalTransport.cxx; sourceTree = "<group>"; }; + 124D78EA086CC3CE00BCA5A9 /* KeepAliveMessage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = KeepAliveMessage.cxx; path = stack/KeepAliveMessage.cxx; sourceTree = "<group>"; }; + 124D78EB086CC3CE00BCA5A9 /* LazyParser.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = LazyParser.cxx; path = stack/LazyParser.cxx; sourceTree = "<group>"; }; + 124D78EC086CC3CE00BCA5A9 /* MacSecurity.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MacSecurity.cxx; path = stack/ssl/MacSecurity.cxx; sourceTree = "<group>"; }; + 124D78ED086CC3CE00BCA5A9 /* Message.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Message.cxx; path = stack/Message.cxx; sourceTree = "<group>"; }; + 124D78EE086CC3CE00BCA5A9 /* MessageFilterRule.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MessageFilterRule.cxx; path = stack/MessageFilterRule.cxx; sourceTree = "<group>"; }; + 124D78EF086CC3CE00BCA5A9 /* MessageWaitingContents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MessageWaitingContents.cxx; path = stack/MessageWaitingContents.cxx; sourceTree = "<group>"; }; + 124D78F0086CC3CE00BCA5A9 /* MethodHash.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MethodHash.cxx; path = stack/MethodHash.cxx; sourceTree = "<group>"; }; + 124D78F1086CC3CE00BCA5A9 /* MethodTypes.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MethodTypes.cxx; path = stack/MethodTypes.cxx; sourceTree = "<group>"; }; + 124D78F2086CC3CE00BCA5A9 /* Mime.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Mime.cxx; path = stack/Mime.cxx; sourceTree = "<group>"; }; + 124D78F3086CC3CE00BCA5A9 /* MsgHeaderScanner.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MsgHeaderScanner.cxx; path = stack/MsgHeaderScanner.cxx; sourceTree = "<group>"; }; + 124D78F4086CC3CE00BCA5A9 /* MultipartAlternativeContents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MultipartAlternativeContents.cxx; path = stack/MultipartAlternativeContents.cxx; sourceTree = "<group>"; }; + 124D78F5086CC3CE00BCA5A9 /* MultipartMixedContents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MultipartMixedContents.cxx; path = stack/MultipartMixedContents.cxx; sourceTree = "<group>"; }; + 124D78F6086CC3CE00BCA5A9 /* MultipartRelatedContents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MultipartRelatedContents.cxx; path = stack/MultipartRelatedContents.cxx; sourceTree = "<group>"; }; + 124D78F7086CC3CE00BCA5A9 /* MultipartSignedContents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MultipartSignedContents.cxx; path = stack/MultipartSignedContents.cxx; sourceTree = "<group>"; }; + 124D78F8086CC3CE00BCA5A9 /* NameAddr.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = NameAddr.cxx; path = stack/NameAddr.cxx; sourceTree = "<group>"; }; + 124D78F9086CC3CE00BCA5A9 /* OctetContents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = OctetContents.cxx; path = stack/OctetContents.cxx; sourceTree = "<group>"; }; + 124D78FA086CC3CE00BCA5A9 /* Parameter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Parameter.cxx; path = stack/Parameter.cxx; sourceTree = "<group>"; }; + 124D78FB086CC3CE00BCA5A9 /* ParameterHash.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParameterHash.cxx; path = stack/ParameterHash.cxx; sourceTree = "<group>"; }; + 124D78FC086CC3CE00BCA5A9 /* ParameterTypes.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParameterTypes.cxx; path = stack/ParameterTypes.cxx; sourceTree = "<group>"; }; + 124D78FD086CC3CE00BCA5A9 /* ParserCategories.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParserCategories.cxx; path = stack/ParserCategories.cxx; sourceTree = "<group>"; }; + 124D78FE086CC3CE00BCA5A9 /* ParserCategory.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParserCategory.cxx; path = stack/ParserCategory.cxx; sourceTree = "<group>"; }; + 124D7900086CC3CE00BCA5A9 /* Pkcs7Contents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Pkcs7Contents.cxx; path = stack/Pkcs7Contents.cxx; sourceTree = "<group>"; }; + 124D7901086CC3CE00BCA5A9 /* PlainContents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PlainContents.cxx; path = stack/PlainContents.cxx; sourceTree = "<group>"; }; + 124D7903086CC3CE00BCA5A9 /* QuotedDataParameter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = QuotedDataParameter.cxx; path = stack/QuotedDataParameter.cxx; sourceTree = "<group>"; }; + 124D7904086CC3CE00BCA5A9 /* RAckCategory.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RAckCategory.cxx; path = stack/RAckCategory.cxx; sourceTree = "<group>"; }; + 124D7906086CC3CE00BCA5A9 /* RequestLine.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RequestLine.cxx; path = stack/RequestLine.cxx; sourceTree = "<group>"; }; + 124D7907086CC3CE00BCA5A9 /* RportParameter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RportParameter.cxx; path = stack/RportParameter.cxx; sourceTree = "<group>"; }; + 124D7908086CC3CE00BCA5A9 /* SdpContents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SdpContents.cxx; path = stack/SdpContents.cxx; sourceTree = "<group>"; }; + 124D7909086CC3CE00BCA5A9 /* Security.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Security.cxx; path = stack/ssl/Security.cxx; sourceTree = "<group>"; }; + 124D790A086CC3CE00BCA5A9 /* SecurityAttributes.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SecurityAttributes.cxx; path = stack/SecurityAttributes.cxx; sourceTree = "<group>"; }; + 124D790B086CC3CE00BCA5A9 /* SipFrag.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SipFrag.cxx; path = stack/SipFrag.cxx; sourceTree = "<group>"; }; + 124D790C086CC3CE00BCA5A9 /* SipMessage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SipMessage.cxx; path = stack/SipMessage.cxx; sourceTree = "<group>"; }; + 124D790D086CC3CE00BCA5A9 /* SipStack.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SipStack.cxx; path = stack/SipStack.cxx; sourceTree = "<group>"; }; + 124D790E086CC3CE00BCA5A9 /* StackThread.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = StackThread.cxx; path = stack/StackThread.cxx; sourceTree = "<group>"; }; + 124D790F086CC3CE00BCA5A9 /* StatelessHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = StatelessHandler.cxx; path = stack/StatelessHandler.cxx; sourceTree = "<group>"; }; + 124D7910086CC3CE00BCA5A9 /* StatisticsManager.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = StatisticsManager.cxx; path = stack/StatisticsManager.cxx; sourceTree = "<group>"; }; + 124D7911086CC3CE00BCA5A9 /* StatisticsMessage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = StatisticsMessage.cxx; path = stack/StatisticsMessage.cxx; sourceTree = "<group>"; }; + 124D7912086CC3CE00BCA5A9 /* StatusLine.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = StatusLine.cxx; path = stack/StatusLine.cxx; sourceTree = "<group>"; }; + 124D7913086CC3CE00BCA5A9 /* StringCategory.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = StringCategory.cxx; path = stack/StringCategory.cxx; sourceTree = "<group>"; }; + 124D7914086CC3CE00BCA5A9 /* Symbols.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Symbols.cxx; path = stack/Symbols.cxx; sourceTree = "<group>"; }; + 124D7915086CC3CE00BCA5A9 /* TcpBaseTransport.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TcpBaseTransport.cxx; path = stack/TcpBaseTransport.cxx; sourceTree = "<group>"; }; + 124D7916086CC3CE00BCA5A9 /* TcpConnection.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TcpConnection.cxx; path = stack/TcpConnection.cxx; sourceTree = "<group>"; }; + 124D7917086CC3CE00BCA5A9 /* TcpTransport.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TcpTransport.cxx; path = stack/TcpTransport.cxx; sourceTree = "<group>"; }; + 124D7918086CC3CE00BCA5A9 /* TimerMessage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TimerMessage.cxx; path = stack/TimerMessage.cxx; sourceTree = "<group>"; }; + 124D7919086CC3CE00BCA5A9 /* TimerQueue.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TimerQueue.cxx; path = stack/TimerQueue.cxx; sourceTree = "<group>"; }; + 124D791A086CC3CE00BCA5A9 /* TlsConnection.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TlsConnection.cxx; path = stack/ssl/TlsConnection.cxx; sourceTree = "<group>"; }; + 124D791B086CC3CE00BCA5A9 /* TlsTransport.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TlsTransport.cxx; path = stack/ssl/TlsTransport.cxx; sourceTree = "<group>"; }; + 124D791C086CC3CE00BCA5A9 /* Token.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Token.cxx; path = stack/Token.cxx; sourceTree = "<group>"; }; + 124D791D086CC3CE00BCA5A9 /* TransactionController.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TransactionController.cxx; path = stack/TransactionController.cxx; sourceTree = "<group>"; }; + 124D791E086CC3CE00BCA5A9 /* TransactionMap.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TransactionMap.cxx; path = stack/TransactionMap.cxx; sourceTree = "<group>"; }; + 124D791F086CC3CE00BCA5A9 /* TransactionState.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TransactionState.cxx; path = stack/TransactionState.cxx; sourceTree = "<group>"; }; + 124D7920086CC3CE00BCA5A9 /* TransactionUser.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TransactionUser.cxx; path = stack/TransactionUser.cxx; sourceTree = "<group>"; }; + 124D7921086CC3CE00BCA5A9 /* TransactionUserMessage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TransactionUserMessage.cxx; path = stack/TransactionUserMessage.cxx; sourceTree = "<group>"; }; + 124D7922086CC3CE00BCA5A9 /* Transport.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Transport.cxx; path = stack/Transport.cxx; sourceTree = "<group>"; }; + 124D7923086CC3CE00BCA5A9 /* TransportSelector.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TransportSelector.cxx; path = stack/TransportSelector.cxx; sourceTree = "<group>"; }; + 124D7924086CC3CE00BCA5A9 /* TuSelector.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TuSelector.cxx; path = stack/TuSelector.cxx; sourceTree = "<group>"; }; + 124D7925086CC3CE00BCA5A9 /* UdpTransport.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UdpTransport.cxx; path = stack/UdpTransport.cxx; sourceTree = "<group>"; }; + 124D7926086CC3CE00BCA5A9 /* UnknownParameter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UnknownParameter.cxx; path = stack/UnknownParameter.cxx; sourceTree = "<group>"; }; + 124D7927086CC3CE00BCA5A9 /* Uri.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Uri.cxx; path = stack/Uri.cxx; sourceTree = "<group>"; }; + 124D7928086CC3CE00BCA5A9 /* Via.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Via.cxx; path = stack/Via.cxx; sourceTree = "<group>"; }; + 124D7929086CC3CE00BCA5A9 /* WarningCategory.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = WarningCategory.cxx; path = stack/WarningCategory.cxx; sourceTree = "<group>"; }; + 124D79A7086CC67000BCA5A9 /* DnsAAAARecord.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DnsAAAARecord.cxx; path = ../rutil/dns/DnsAAAARecord.cxx; sourceTree = SOURCE_ROOT; }; + 124D79A8086CC67000BCA5A9 /* DnsCnameRecord.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DnsCnameRecord.cxx; path = ../rutil/dns/DnsCnameRecord.cxx; sourceTree = SOURCE_ROOT; }; + 124D79A9086CC67000BCA5A9 /* DnsHostRecord.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DnsHostRecord.cxx; path = ../rutil/dns/DnsHostRecord.cxx; sourceTree = SOURCE_ROOT; }; + 124D79AA086CC67000BCA5A9 /* DnsNaptrRecord.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DnsNaptrRecord.cxx; path = ../rutil/dns/DnsNaptrRecord.cxx; sourceTree = SOURCE_ROOT; }; + 124D79AB086CC67000BCA5A9 /* DnsSrvRecord.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DnsSrvRecord.cxx; path = ../rutil/dns/DnsSrvRecord.cxx; sourceTree = SOURCE_ROOT; }; + 124D79AC086CC67000BCA5A9 /* DnsStub.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DnsStub.cxx; path = ../rutil/dns/DnsStub.cxx; sourceTree = SOURCE_ROOT; }; + 124D79AD086CC67000BCA5A9 /* QueryTypes.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = QueryTypes.cxx; path = ../rutil/dns/QueryTypes.cxx; sourceTree = SOURCE_ROOT; }; + 124D79AE086CC67000BCA5A9 /* RRCache.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RRCache.cxx; path = ../rutil/dns/RRCache.cxx; sourceTree = SOURCE_ROOT; }; + 124D79AF086CC67000BCA5A9 /* RRList.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RRList.cxx; path = ../rutil/dns/RRList.cxx; sourceTree = SOURCE_ROOT; }; + 124D79B0086CC67000BCA5A9 /* RROverlay.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RROverlay.cxx; path = ../rutil/dns/RROverlay.cxx; sourceTree = SOURCE_ROOT; }; + 124D79B1086CC67000BCA5A9 /* RRVip.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RRVip.cxx; path = ../rutil/dns/RRVip.cxx; sourceTree = SOURCE_ROOT; }; + 124D79BD086CC68200BCA5A9 /* AppDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AppDialog.cxx; path = dum/AppDialog.cxx; sourceTree = "<group>"; }; + 124D79BE086CC68200BCA5A9 /* AppDialogSet.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AppDialogSet.cxx; path = dum/AppDialogSet.cxx; sourceTree = "<group>"; }; + 124D79BF086CC68200BCA5A9 /* AppDialogSetFactory.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AppDialogSetFactory.cxx; path = dum/AppDialogSetFactory.cxx; sourceTree = "<group>"; }; + 124D79C0086CC68200BCA5A9 /* BaseCreator.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BaseCreator.cxx; path = dum/BaseCreator.cxx; sourceTree = "<group>"; }; + 124D79C1086CC68200BCA5A9 /* BaseSubscription.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BaseSubscription.cxx; path = dum/BaseSubscription.cxx; sourceTree = "<group>"; }; + 124D79C2086CC68200BCA5A9 /* BaseUsage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BaseUsage.cxx; path = dum/BaseUsage.cxx; sourceTree = "<group>"; }; + 124D79C3086CC68200BCA5A9 /* ClientAuthManager.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ClientAuthManager.cxx; path = dum/ClientAuthManager.cxx; sourceTree = "<group>"; }; + 124D79C4086CC68200BCA5A9 /* ClientInviteSession.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ClientInviteSession.cxx; path = dum/ClientInviteSession.cxx; sourceTree = "<group>"; }; + 124D79C5086CC68200BCA5A9 /* ClientOutOfDialogReq.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ClientOutOfDialogReq.cxx; path = dum/ClientOutOfDialogReq.cxx; sourceTree = "<group>"; }; + 124D79C6086CC68200BCA5A9 /* ClientPagerMessage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ClientPagerMessage.cxx; path = dum/ClientPagerMessage.cxx; sourceTree = "<group>"; }; + 124D79C7086CC68200BCA5A9 /* ClientPublication.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ClientPublication.cxx; path = dum/ClientPublication.cxx; sourceTree = "<group>"; }; + 124D79C8086CC68200BCA5A9 /* ClientRegistration.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ClientRegistration.cxx; path = dum/ClientRegistration.cxx; sourceTree = "<group>"; }; + 124D79C9086CC68200BCA5A9 /* ClientSubscription.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ClientSubscription.cxx; path = dum/ClientSubscription.cxx; sourceTree = "<group>"; }; + 124D79CA086CC68200BCA5A9 /* DefaultServerReferHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DefaultServerReferHandler.cxx; path = dum/DefaultServerReferHandler.cxx; sourceTree = "<group>"; }; + 124D79CB086CC68200BCA5A9 /* DestroyUsage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DestroyUsage.cxx; path = dum/DestroyUsage.cxx; sourceTree = "<group>"; }; + 124D79CC086CC68200BCA5A9 /* Dialog.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Dialog.cxx; path = dum/Dialog.cxx; sourceTree = "<group>"; }; + 124D79CD086CC68200BCA5A9 /* DialogId.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DialogId.cxx; path = dum/DialogId.cxx; sourceTree = "<group>"; }; + 124D79CE086CC68200BCA5A9 /* DialogSet.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DialogSet.cxx; path = dum/DialogSet.cxx; sourceTree = "<group>"; }; + 124D79CF086CC68200BCA5A9 /* DialogSetId.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DialogSetId.cxx; path = dum/DialogSetId.cxx; sourceTree = "<group>"; }; + 124D79D0086CC68200BCA5A9 /* DialogUsage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DialogUsage.cxx; path = dum/DialogUsage.cxx; sourceTree = "<group>"; }; + 124D79D1086CC68200BCA5A9 /* DialogUsageManager.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DialogUsageManager.cxx; path = dum/DialogUsageManager.cxx; sourceTree = "<group>"; }; + 124D79D2086CC68200BCA5A9 /* DumProcessHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DumProcessHandler.cxx; path = dum/DumProcessHandler.cxx; sourceTree = "<group>"; }; + 124D79D3086CC68200BCA5A9 /* DumTimeout.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DumTimeout.cxx; path = dum/DumTimeout.cxx; sourceTree = "<group>"; }; + 124D79D4086CC68200BCA5A9 /* Handled.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Handled.cxx; path = dum/Handled.cxx; sourceTree = "<group>"; }; + 124D79D5086CC68200BCA5A9 /* HandleException.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = HandleException.cxx; path = dum/HandleException.cxx; sourceTree = "<group>"; }; + 124D79D6086CC68200BCA5A9 /* HandleManager.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = HandleManager.cxx; path = dum/HandleManager.cxx; sourceTree = "<group>"; }; + 124D79D7086CC68200BCA5A9 /* InviteSession.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = InviteSession.cxx; path = dum/InviteSession.cxx; sourceTree = "<group>"; }; + 124D79D8086CC68200BCA5A9 /* InviteSessionCreator.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = InviteSessionCreator.cxx; path = dum/InviteSessionCreator.cxx; sourceTree = "<group>"; }; + 124D79D9086CC68200BCA5A9 /* InviteSessionHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = InviteSessionHandler.cxx; path = dum/InviteSessionHandler.cxx; sourceTree = "<group>"; }; + 124D79DA086CC68200BCA5A9 /* MergedRequestKey.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MergedRequestKey.cxx; path = dum/MergedRequestKey.cxx; sourceTree = "<group>"; }; + 124D79DB086CC68200BCA5A9 /* KeepAliveManager.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = KeepAliveManager.cxx; path = dum/KeepAliveManager.cxx; sourceTree = "<group>"; }; + 124D79DC086CC68200BCA5A9 /* KeepAliveTimeout.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = KeepAliveTimeout.cxx; path = dum/KeepAliveTimeout.cxx; sourceTree = "<group>"; }; + 124D79DD086CC68200BCA5A9 /* MasterProfile.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MasterProfile.cxx; path = dum/MasterProfile.cxx; sourceTree = "<group>"; }; + 124D79DE086CC68200BCA5A9 /* NetworkAssociation.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkAssociation.cxx; path = dum/NetworkAssociation.cxx; sourceTree = "<group>"; }; + 124D79DF086CC68200BCA5A9 /* NonDialogUsage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = NonDialogUsage.cxx; path = dum/NonDialogUsage.cxx; sourceTree = "<group>"; }; + 124D79E0086CC68200BCA5A9 /* OutOfDialogReqCreator.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = OutOfDialogReqCreator.cxx; path = dum/OutOfDialogReqCreator.cxx; sourceTree = "<group>"; }; + 124D79E1086CC68200BCA5A9 /* PagerMessageCreator.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PagerMessageCreator.cxx; path = dum/PagerMessageCreator.cxx; sourceTree = "<group>"; }; + 124D79E2086CC68200BCA5A9 /* Profile.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Profile.cxx; path = dum/Profile.cxx; sourceTree = "<group>"; }; + 124D79E3086CC68200BCA5A9 /* PublicationCreator.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PublicationCreator.cxx; path = dum/PublicationCreator.cxx; sourceTree = "<group>"; }; + 124D79E4086CC68200BCA5A9 /* RedirectManager.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RedirectManager.cxx; path = dum/RedirectManager.cxx; sourceTree = "<group>"; }; + 124D79E5086CC68200BCA5A9 /* RegistrationCreator.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RegistrationCreator.cxx; path = dum/RegistrationCreator.cxx; sourceTree = "<group>"; }; + 124D79E6086CC68200BCA5A9 /* ServerAuthManager.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ServerAuthManager.cxx; path = dum/ServerAuthManager.cxx; sourceTree = "<group>"; }; + 124D79E7086CC68200BCA5A9 /* ServerInviteSession.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ServerInviteSession.cxx; path = dum/ServerInviteSession.cxx; sourceTree = "<group>"; }; + 124D79E8086CC68200BCA5A9 /* ServerOutOfDialogReq.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ServerOutOfDialogReq.cxx; path = dum/ServerOutOfDialogReq.cxx; sourceTree = "<group>"; }; + 124D79E9086CC68200BCA5A9 /* ServerPagerMessage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ServerPagerMessage.cxx; path = dum/ServerPagerMessage.cxx; sourceTree = "<group>"; }; + 124D79EA086CC68200BCA5A9 /* ServerPublication.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ServerPublication.cxx; path = dum/ServerPublication.cxx; sourceTree = "<group>"; }; + 124D79EB086CC68200BCA5A9 /* ServerRegistration.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ServerRegistration.cxx; path = dum/ServerRegistration.cxx; sourceTree = "<group>"; }; + 124D79EC086CC68200BCA5A9 /* ServerSubscription.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ServerSubscription.cxx; path = dum/ServerSubscription.cxx; sourceTree = "<group>"; }; + 124D79ED086CC68200BCA5A9 /* SubscriptionCreator.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SubscriptionCreator.cxx; path = dum/SubscriptionCreator.cxx; sourceTree = "<group>"; }; + 124D79EE086CC68200BCA5A9 /* SubscriptionHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SubscriptionHandler.cxx; path = dum/SubscriptionHandler.cxx; sourceTree = "<group>"; }; + 124D79EF086CC68200BCA5A9 /* SubscriptionState.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SubscriptionState.cxx; path = dum/SubscriptionState.cxx; sourceTree = "<group>"; }; + 124D79F1086CC68200BCA5A9 /* UserAuthInfo.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UserAuthInfo.cxx; path = dum/UserAuthInfo.cxx; sourceTree = "<group>"; }; + 124D79F2086CC68200BCA5A9 /* UserProfile.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UserProfile.cxx; path = dum/UserProfile.cxx; sourceTree = "<group>"; }; + 124D7A29086CC69300BCA5A9 /* AbstractFifo.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AbstractFifo.cxx; path = ../rutil/AbstractFifo.cxx; sourceTree = "<group>"; }; + 124D7A2A086CC69300BCA5A9 /* BaseException.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BaseException.cxx; path = ../rutil/BaseException.cxx; sourceTree = "<group>"; }; + 124D7A2B086CC69300BCA5A9 /* Coders.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Coders.cxx; path = ../rutil/Coders.cxx; sourceTree = "<group>"; }; + 124D7A2C086CC69300BCA5A9 /* Condition.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Condition.cxx; path = ../rutil/Condition.cxx; sourceTree = "<group>"; }; + 124D7A2D086CC69300BCA5A9 /* CountStream.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CountStream.cxx; path = ../rutil/CountStream.cxx; sourceTree = "<group>"; }; + 124D7A2E086CC69300BCA5A9 /* Data.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Data.cxx; path = ../rutil/Data.cxx; sourceTree = "<group>"; }; + 124D7A2F086CC69300BCA5A9 /* DataStream.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DataStream.cxx; path = ../rutil/DataStream.cxx; sourceTree = "<group>"; }; + 124D7A30086CC69300BCA5A9 /* DnsUtil.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DnsUtil.cxx; path = ../rutil/DnsUtil.cxx; sourceTree = "<group>"; }; + 124D7A31086CC69300BCA5A9 /* FileSystem.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = FileSystem.cxx; path = ../rutil/FileSystem.cxx; sourceTree = "<group>"; }; + 124D7A32086CC69300BCA5A9 /* Lock.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Lock.cxx; path = ../rutil/Lock.cxx; sourceTree = "<group>"; }; + 124D7A33086CC69300BCA5A9 /* Log.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Log.cxx; path = ../rutil/Log.cxx; sourceTree = "<group>"; }; + 124D7A35086CC69300BCA5A9 /* MD5Stream.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MD5Stream.cxx; path = ../rutil/MD5Stream.cxx; sourceTree = "<group>"; }; + 124D7A36086CC69300BCA5A9 /* Mutex.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Mutex.cxx; path = ../rutil/Mutex.cxx; sourceTree = "<group>"; }; + 124D7A37086CC69300BCA5A9 /* ParseBuffer.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseBuffer.cxx; path = ../rutil/ParseBuffer.cxx; sourceTree = "<group>"; }; + 124D7A38086CC69300BCA5A9 /* Random.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Random.cxx; path = ../rutil/Random.cxx; sourceTree = "<group>"; }; + 124D7A39086CC69300BCA5A9 /* RecursiveMutex.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RecursiveMutex.cxx; path = ../rutil/RecursiveMutex.cxx; sourceTree = "<group>"; }; + 124D7A3A086CC69300BCA5A9 /* RWMutex.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RWMutex.cxx; path = ../rutil/RWMutex.cxx; sourceTree = "<group>"; }; + 124D7A3C086CC69300BCA5A9 /* Socket.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Socket.cxx; path = ../rutil/Socket.cxx; sourceTree = "<group>"; }; + 124D7A3D086CC69300BCA5A9 /* Subsystem.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Subsystem.cxx; path = ../rutil/Subsystem.cxx; sourceTree = "<group>"; }; + 124D7A3E086CC69300BCA5A9 /* SysLogBuf.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SysLogBuf.cxx; path = ../rutil/SysLogBuf.cxx; sourceTree = "<group>"; }; + 124D7A3F086CC69300BCA5A9 /* SysLogStream.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SysLogStream.cxx; path = ../rutil/SysLogStream.cxx; sourceTree = "<group>"; }; + 124D7A40086CC69300BCA5A9 /* ThreadIf.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadIf.cxx; path = ../rutil/ThreadIf.cxx; sourceTree = "<group>"; }; + 124D7A41086CC69300BCA5A9 /* Timer.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Timer.cxx; path = ../rutil/Timer.cxx; sourceTree = "<group>"; }; + 124D7A42086CC69300BCA5A9 /* Tuple.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Tuple.cxx; path = stack/Tuple.cxx; sourceTree = "<group>"; }; + 124D7A43086CC69300BCA5A9 /* vmd5.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = vmd5.cxx; path = ../rutil/vmd5.cxx; sourceTree = "<group>"; }; + 124D7A5F086CC77900BCA5A9 /* HttpGetMessage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = HttpGetMessage.cxx; path = dum/HttpGetMessage.cxx; sourceTree = "<group>"; }; + 124D7A60086CC77900BCA5A9 /* HttpProvider.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = HttpProvider.cxx; path = dum/HttpProvider.cxx; sourceTree = "<group>"; }; + 124EC467087217600017C8BB /* TransportFailure.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TransportFailure.cxx; path = stack/TransportFailure.cxx; sourceTree = "<group>"; }; + 124EC47B08721CFF0017C8BB /* ExtensionHeader.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ExtensionHeader.cxx; path = stack/ExtensionHeader.cxx; sourceTree = "<group>"; }; + 124EC47C08721CFF0017C8BB /* ExtensionParameter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ExtensionParameter.cxx; path = stack/ExtensionParameter.cxx; sourceTree = "<group>"; }; + 12BF59340895D59E00F7DD81 /* ParserContainerBase.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParserContainerBase.cxx; path = stack/ParserContainerBase.cxx; sourceTree = "<group>"; }; + 12BF59360895D5BA00F7DD81 /* ContentsFactoryBase.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ContentsFactoryBase.cxx; path = stack/ContentsFactoryBase.cxx; sourceTree = "<group>"; }; + 12BF59380895D5E600F7DD81 /* EncryptionManager.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = EncryptionManager.cxx; path = dum/ssl/EncryptionManager.cxx; sourceTree = "<group>"; }; + 12BF593A0895D5FF00F7DD81 /* DumDecrypted.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DumDecrypted.cxx; path = dum/DumDecrypted.cxx; sourceTree = "<group>"; }; + 12BF59570895D7B800F7DD81 /* CertMessage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CertMessage.cxx; path = dum/CertMessage.cxx; sourceTree = "<group>"; }; + 12F79738086CBA1E00AF4EDF /* libresiprocate.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libresiprocate.a; sourceTree = BUILT_PRODUCTS_DIR; }; + D2AAC06F0554671400DB518D /* libares.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libares.a; sourceTree = BUILT_PRODUCTS_DIR; }; + F80A8D4812B2CA66002D37E0 /* FdPoll.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FdPoll.cxx; path = ../rutil/FdPoll.cxx; sourceTree = SOURCE_ROOT; }; + F80A8D4912B2CA66002D37E0 /* FdPoll.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = FdPoll.hxx; path = ../rutil/FdPoll.hxx; sourceTree = SOURCE_ROOT; }; + F8A057D3124D52BA00112774 /* AbandonServerTransaction.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AbandonServerTransaction.hxx; path = stack/AbandonServerTransaction.hxx; sourceTree = "<group>"; }; + F8A057D4124D52BA00112774 /* CancelClientInviteTransaction.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CancelClientInviteTransaction.hxx; path = stack/CancelClientInviteTransaction.hxx; sourceTree = "<group>"; }; + F8A057D5124D52BA00112774 /* ExistsOrDataParameter.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExistsOrDataParameter.cxx; path = stack/ExistsOrDataParameter.cxx; sourceTree = "<group>"; }; + F8A057D6124D52BA00112774 /* ExistsOrDataParameter.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ExistsOrDataParameter.hxx; path = stack/ExistsOrDataParameter.hxx; sourceTree = "<group>"; }; + F8A057D7124D52BA00112774 /* InteropHelper.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InteropHelper.cxx; path = stack/InteropHelper.cxx; sourceTree = "<group>"; }; + F8A057D8124D52BA00112774 /* InteropHelper.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = InteropHelper.hxx; path = stack/InteropHelper.hxx; sourceTree = "<group>"; }; + F8A057D9124D52BA00112774 /* PrivacyCategory.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PrivacyCategory.cxx; path = stack/PrivacyCategory.cxx; sourceTree = "<group>"; }; + F8A057DA124D52BA00112774 /* PrivacyCategory.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = PrivacyCategory.hxx; path = stack/PrivacyCategory.hxx; sourceTree = "<group>"; }; + F8A057E3124D52DE00112774 /* ClientAuthExtension.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClientAuthExtension.cxx; path = dum/ClientAuthExtension.cxx; sourceTree = "<group>"; }; + F8A057E4124D52DE00112774 /* ClientAuthExtension.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ClientAuthExtension.hxx; path = dum/ClientAuthExtension.hxx; sourceTree = "<group>"; }; + F8A057E5124D52DE00112774 /* DialogEventInfo.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DialogEventInfo.cxx; path = dum/DialogEventInfo.cxx; sourceTree = "<group>"; }; + F8A057E6124D52DE00112774 /* DialogEventInfo.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = DialogEventInfo.hxx; path = dum/DialogEventInfo.hxx; sourceTree = "<group>"; }; + F8A057E7124D52DE00112774 /* DialogEventStateManager.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DialogEventStateManager.cxx; path = dum/DialogEventStateManager.cxx; sourceTree = "<group>"; }; + F8A057E8124D52DE00112774 /* DialogEventStateManager.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = DialogEventStateManager.hxx; path = dum/DialogEventStateManager.hxx; sourceTree = "<group>"; }; + F8A057E9124D52DE00112774 /* InMemorySyncRegDb.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InMemorySyncRegDb.cxx; path = dum/InMemorySyncRegDb.cxx; sourceTree = "<group>"; }; + F8A057EA124D52DE00112774 /* InMemorySyncRegDb.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = InMemorySyncRegDb.hxx; path = dum/InMemorySyncRegDb.hxx; sourceTree = "<group>"; }; + F8A057EB124D52DE00112774 /* RADIUSServerAuthManager.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RADIUSServerAuthManager.cxx; path = dum/RADIUSServerAuthManager.cxx; sourceTree = "<group>"; }; + F8A057EC124D52DE00112774 /* RADIUSServerAuthManager.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = RADIUSServerAuthManager.hxx; path = dum/RADIUSServerAuthManager.hxx; sourceTree = "<group>"; }; + F8A057ED124D52DE00112774 /* RegistrationHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegistrationHandler.cxx; path = dum/RegistrationHandler.cxx; sourceTree = "<group>"; }; + F8C76C911243CCFF0076CFF8 /* AsyncProcessHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AsyncProcessHandler.hxx; path = ../rutil/AsyncProcessHandler.hxx; sourceTree = SOURCE_ROOT; }; + F8C76C921243CCFF0076CFF8 /* DataException.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = DataException.hxx; path = ../rutil/DataException.hxx; sourceTree = SOURCE_ROOT; }; + F8C76C931243CCFF0076CFF8 /* DigestStream.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DigestStream.cxx; path = ../rutil/DigestStream.cxx; sourceTree = SOURCE_ROOT; }; + F8C76C941243CCFF0076CFF8 /* DigestStream.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = DigestStream.hxx; path = ../rutil/DigestStream.hxx; sourceTree = SOURCE_ROOT; }; + F8C76C951243CCFF0076CFF8 /* ParseException.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParseException.cxx; path = ../rutil/ParseException.cxx; sourceTree = SOURCE_ROOT; }; + F8C76C961243CCFF0076CFF8 /* ParseException.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ParseException.hxx; path = ../rutil/ParseException.hxx; sourceTree = SOURCE_ROOT; }; + F8C76C971243CCFF0076CFF8 /* RADIUSDigestAuthenticator.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RADIUSDigestAuthenticator.cxx; path = ../rutil/RADIUSDigestAuthenticator.cxx; sourceTree = SOURCE_ROOT; }; + F8C76C981243CCFF0076CFF8 /* RADIUSDigestAuthenticator.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = RADIUSDigestAuthenticator.hxx; path = ../rutil/RADIUSDigestAuthenticator.hxx; sourceTree = SOURCE_ROOT; }; + F8C76C991243CCFF0076CFF8 /* resipfaststreams.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = resipfaststreams.cxx; path = ../rutil/resipfaststreams.cxx; sourceTree = SOURCE_ROOT; }; + F8C76C9A1243CCFF0076CFF8 /* resipfaststreams.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = resipfaststreams.hxx; path = ../rutil/resipfaststreams.hxx; sourceTree = SOURCE_ROOT; }; + F8C76C9B1243CCFF0076CFF8 /* Time.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Time.cxx; path = ../rutil/Time.cxx; sourceTree = SOURCE_ROOT; }; + F8C76C9C1243CCFF0076CFF8 /* Time.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Time.hxx; path = ../rutil/Time.hxx; sourceTree = SOURCE_ROOT; }; + F8C76CA91243CD2B0076CFF8 /* OpenSSLInit.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenSSLInit.cxx; path = ../rutil/ssl/OpenSSLInit.cxx; sourceTree = SOURCE_ROOT; }; + F8C76CAA1243CD2B0076CFF8 /* SHA1Stream.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SHA1Stream.cxx; path = ../rutil/ssl/SHA1Stream.cxx; sourceTree = SOURCE_ROOT; }; + F8DB1C870C56B7D800853E27 /* SipDialer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SipDialer; sourceTree = BUILT_PRODUCTS_DIR; }; + F8DB1C8E0C56B7FD00853E27 /* DialerConfiguration.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DialerConfiguration.cpp; path = ../apps/sipdial/DialerConfiguration.cpp; sourceTree = SOURCE_ROOT; }; + F8DB1C8F0C56B7FD00853E27 /* DialInstance.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DialInstance.cpp; path = ../apps/sipdial/DialInstance.cpp; sourceTree = SOURCE_ROOT; }; + F8DB1C900C56B7FD00853E27 /* MyInviteSessionHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MyInviteSessionHandler.cpp; path = ../apps/sipdial/MyInviteSessionHandler.cpp; sourceTree = SOURCE_ROOT; }; + F8DB1C910C56B7FD00853E27 /* sipdialer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sipdialer.cpp; path = ../apps/sipdial/sipdialer.cpp; sourceTree = SOURCE_ROOT; }; + F8DB1CBA0C56B9B800853E27 /* AppDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = AppDialog.hxx; path = dum/AppDialog.hxx; sourceTree = "<group>"; }; + F8DB1CBB0C56B9B800853E27 /* AppDialogSet.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = AppDialogSet.hxx; path = dum/AppDialogSet.hxx; sourceTree = "<group>"; }; + F8DB1CBC0C56B9B800853E27 /* AppDialogSetFactory.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = AppDialogSetFactory.hxx; path = dum/AppDialogSetFactory.hxx; sourceTree = "<group>"; }; + F8DB1CBD0C56B9B800853E27 /* BaseCreator.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = BaseCreator.hxx; path = dum/BaseCreator.hxx; sourceTree = "<group>"; }; + F8DB1CBE0C56B9B800853E27 /* BaseSubscription.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = BaseSubscription.hxx; path = dum/BaseSubscription.hxx; sourceTree = "<group>"; }; + F8DB1CBF0C56B9B800853E27 /* BaseUsage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = BaseUsage.hxx; path = dum/BaseUsage.hxx; sourceTree = "<group>"; }; + F8DB1CC00C56B9B800853E27 /* CertMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = CertMessage.hxx; path = dum/CertMessage.hxx; sourceTree = "<group>"; }; + F8DB1CC10C56B9B800853E27 /* ChallengeInfo.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ChallengeInfo.cxx; path = dum/ChallengeInfo.cxx; sourceTree = "<group>"; }; + F8DB1CC20C56B9B800853E27 /* ChallengeInfo.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ChallengeInfo.hxx; path = dum/ChallengeInfo.hxx; sourceTree = "<group>"; }; + F8DB1CC30C56B9B800853E27 /* ClientAuthManager.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ClientAuthManager.hxx; path = dum/ClientAuthManager.hxx; sourceTree = "<group>"; }; + F8DB1CC40C56B9B800853E27 /* ClientInviteSession.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ClientInviteSession.hxx; path = dum/ClientInviteSession.hxx; sourceTree = "<group>"; }; + F8DB1CC50C56B9B800853E27 /* ClientOutOfDialogReq.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ClientOutOfDialogReq.hxx; path = dum/ClientOutOfDialogReq.hxx; sourceTree = "<group>"; }; + F8DB1CC60C56B9B800853E27 /* ClientPagerMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ClientPagerMessage.hxx; path = dum/ClientPagerMessage.hxx; sourceTree = "<group>"; }; + F8DB1CC70C56B9B800853E27 /* ClientPublication.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ClientPublication.hxx; path = dum/ClientPublication.hxx; sourceTree = "<group>"; }; + F8DB1CC80C56B9B800853E27 /* ClientRegistration.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ClientRegistration.hxx; path = dum/ClientRegistration.hxx; sourceTree = "<group>"; }; + F8DB1CC90C56B9B800853E27 /* ClientSubscription.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ClientSubscription.hxx; path = dum/ClientSubscription.hxx; sourceTree = "<group>"; }; + F8DB1CCA0C56B9B800853E27 /* ClientSubscriptionFunctor.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ClientSubscriptionFunctor.hxx; path = dum/ClientSubscriptionFunctor.hxx; sourceTree = "<group>"; }; + F8DB1CCB0C56B9B800853E27 /* ContactInstanceRecord.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ContactInstanceRecord.cxx; path = dum/ContactInstanceRecord.cxx; sourceTree = "<group>"; }; + F8DB1CCC0C56B9B800853E27 /* ContactInstanceRecord.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ContactInstanceRecord.hxx; path = dum/ContactInstanceRecord.hxx; sourceTree = "<group>"; }; + F8DB1CCD0C56B9B800853E27 /* DefaultServerReferHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DefaultServerReferHandler.hxx; path = dum/DefaultServerReferHandler.hxx; sourceTree = "<group>"; }; + F8DB1CCE0C56B9B800853E27 /* DestroyUsage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DestroyUsage.hxx; path = dum/DestroyUsage.hxx; sourceTree = "<group>"; }; + F8DB1CCF0C56B9B800853E27 /* Dialog.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Dialog.hxx; path = dum/Dialog.hxx; sourceTree = "<group>"; }; + F8DB1CD00C56B9B800853E27 /* DialogEventHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DialogEventHandler.hxx; path = dum/DialogEventHandler.hxx; sourceTree = "<group>"; }; + F8DB1CD10C56B9B800853E27 /* DialogId.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DialogId.hxx; path = dum/DialogId.hxx; sourceTree = "<group>"; }; + F8DB1CD20C56B9B800853E27 /* DialogSet.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DialogSet.hxx; path = dum/DialogSet.hxx; sourceTree = "<group>"; }; + F8DB1CD30C56B9B800853E27 /* DialogSetHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DialogSetHandler.hxx; path = dum/DialogSetHandler.hxx; sourceTree = "<group>"; }; + F8DB1CD40C56B9B800853E27 /* DialogSetId.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DialogSetId.hxx; path = dum/DialogSetId.hxx; sourceTree = "<group>"; }; + F8DB1CD50C56B9B800853E27 /* DialogUsage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DialogUsage.hxx; path = dum/DialogUsage.hxx; sourceTree = "<group>"; }; + F8DB1CD60C56B9B800853E27 /* DialogUsageManager.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DialogUsageManager.hxx; path = dum/DialogUsageManager.hxx; sourceTree = "<group>"; }; + F8DB1CD70C56B9B800853E27 /* DumCommand.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DumCommand.hxx; path = dum/DumCommand.hxx; sourceTree = "<group>"; }; + F8DB1CD80C56B9B800853E27 /* DumDecrypted.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DumDecrypted.hxx; path = dum/DumDecrypted.hxx; sourceTree = "<group>"; }; + F8DB1CD90C56B9B800853E27 /* DumException.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DumException.hxx; path = dum/DumException.hxx; sourceTree = "<group>"; }; + F8DB1CDA0C56B9B800853E27 /* DumFeature.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DumFeature.hxx; path = dum/DumFeature.hxx; sourceTree = "<group>"; }; + F8DB1CDB0C56B9B800853E27 /* DumFeatureChain.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DumFeatureChain.hxx; path = dum/DumFeatureChain.hxx; sourceTree = "<group>"; }; + F8DB1CDC0C56B9B800853E27 /* DumFeatureMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DumFeatureMessage.hxx; path = dum/DumFeatureMessage.hxx; sourceTree = "<group>"; }; + F8DB1CDD0C56B9B800853E27 /* DumHelper.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DumHelper.cxx; path = dum/DumHelper.cxx; sourceTree = "<group>"; }; + F8DB1CDE0C56B9B800853E27 /* DumHelper.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DumHelper.hxx; path = dum/DumHelper.hxx; sourceTree = "<group>"; }; + F8DB1CDF0C56B9B800853E27 /* DumProcessHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DumProcessHandler.hxx; path = dum/DumProcessHandler.hxx; sourceTree = "<group>"; }; + F8DB1CE00C56B9B800853E27 /* DumShutdownHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DumShutdownHandler.hxx; path = dum/DumShutdownHandler.hxx; sourceTree = "<group>"; }; + F8DB1CE10C56B9B800853E27 /* DumThread.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DumThread.cxx; path = dum/DumThread.cxx; sourceTree = "<group>"; }; + F8DB1CE20C56B9B800853E27 /* DumThread.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DumThread.hxx; path = dum/DumThread.hxx; sourceTree = "<group>"; }; + F8DB1CE30C56B9B800853E27 /* DumTimeout.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DumTimeout.hxx; path = dum/DumTimeout.hxx; sourceTree = "<group>"; }; + F8DB1CE40C56B9B800853E27 /* EncryptionManager.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = EncryptionManager.hxx; path = dum/ssl/EncryptionManager.hxx; sourceTree = "<group>"; }; + F8DB1CE50C56B9B800853E27 /* EncryptionRequest.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = EncryptionRequest.hxx; path = dum/EncryptionRequest.hxx; sourceTree = "<group>"; }; + F8DB1CE60C56B9B800853E27 /* EventDispatcher.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = EventDispatcher.hxx; path = dum/EventDispatcher.hxx; sourceTree = "<group>"; }; + F8DB1CE70C56B9B800853E27 /* ExternalMessageBase.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ExternalMessageBase.hxx; path = dum/ExternalMessageBase.hxx; sourceTree = "<group>"; }; + F8DB1CE80C56B9B800853E27 /* ExternalMessageHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ExternalMessageHandler.hxx; path = dum/ExternalMessageHandler.hxx; sourceTree = "<group>"; }; + F8DB1CE90C56B9B800853E27 /* ExternalTimer.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ExternalTimer.hxx; path = dum/ExternalTimer.hxx; sourceTree = "<group>"; }; + F8DB1CEA0C56B9B800853E27 /* Handle.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Handle.cxx; path = dum/Handle.cxx; sourceTree = "<group>"; }; + F8DB1CEB0C56B9B800853E27 /* Handle.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Handle.hxx; path = dum/Handle.hxx; sourceTree = "<group>"; }; + F8DB1CEC0C56B9B800853E27 /* Handled.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Handled.hxx; path = dum/Handled.hxx; sourceTree = "<group>"; }; + F8DB1CED0C56B9B800853E27 /* HandleException.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = HandleException.hxx; path = dum/HandleException.hxx; sourceTree = "<group>"; }; + F8DB1CEE0C56B9B800853E27 /* HandleManager.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = HandleManager.hxx; path = dum/HandleManager.hxx; sourceTree = "<group>"; }; + F8DB1CEF0C56B9B800853E27 /* Handles.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Handles.hxx; path = dum/Handles.hxx; sourceTree = "<group>"; }; + F8DB1CF00C56B9B800853E27 /* HttpGetMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = HttpGetMessage.hxx; path = dum/HttpGetMessage.hxx; sourceTree = "<group>"; }; + F8DB1CF10C56B9B800853E27 /* HttpProvider.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = HttpProvider.hxx; path = dum/HttpProvider.hxx; sourceTree = "<group>"; }; + F8DB1CF20C56B9B800853E27 /* IdentityHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = IdentityHandler.hxx; path = dum/IdentityHandler.hxx; sourceTree = "<group>"; }; + F8DB1CF30C56B9B800853E27 /* InMemoryRegistrationDatabase.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = InMemoryRegistrationDatabase.cxx; path = dum/InMemoryRegistrationDatabase.cxx; sourceTree = "<group>"; }; + F8DB1CF40C56B9B800853E27 /* InMemoryRegistrationDatabase.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = InMemoryRegistrationDatabase.hxx; path = dum/InMemoryRegistrationDatabase.hxx; sourceTree = "<group>"; }; + F8DB1CF50C56B9B800853E27 /* InviteDialogs.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = InviteDialogs.hxx; path = dum/InviteDialogs.hxx; sourceTree = "<group>"; }; + F8DB1CF60C56B9B800853E27 /* InviteSession.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = InviteSession.hxx; path = dum/InviteSession.hxx; sourceTree = "<group>"; }; + F8DB1CF70C56B9B800853E27 /* InviteSessionCreator.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = InviteSessionCreator.hxx; path = dum/InviteSessionCreator.hxx; sourceTree = "<group>"; }; + F8DB1CF80C56B9B800853E27 /* InviteSessionHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = InviteSessionHandler.hxx; path = dum/InviteSessionHandler.hxx; sourceTree = "<group>"; }; + F8DB1CF90C56B9B800853E27 /* KeepAliveManager.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = KeepAliveManager.hxx; path = dum/KeepAliveManager.hxx; sourceTree = "<group>"; }; + F8DB1CFA0C56B9B800853E27 /* KeepAliveTimeout.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = KeepAliveTimeout.hxx; path = dum/KeepAliveTimeout.hxx; sourceTree = "<group>"; }; + F8DB1CFB0C56B9B800853E27 /* MasterProfile.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MasterProfile.hxx; path = dum/MasterProfile.hxx; sourceTree = "<group>"; }; + F8DB1CFC0C56B9B800853E27 /* MergedRequestKey.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MergedRequestKey.hxx; path = dum/MergedRequestKey.hxx; sourceTree = "<group>"; }; + F8DB1CFD0C56B9B800853E27 /* MergedRequestRemovalCommand.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MergedRequestRemovalCommand.cxx; path = dum/MergedRequestRemovalCommand.cxx; sourceTree = "<group>"; }; + F8DB1CFE0C56B9B800853E27 /* MergedRequestRemovalCommand.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MergedRequestRemovalCommand.hxx; path = dum/MergedRequestRemovalCommand.hxx; sourceTree = "<group>"; }; + F8DB1CFF0C56B9B800853E27 /* NetworkAssociation.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = NetworkAssociation.hxx; path = dum/NetworkAssociation.hxx; sourceTree = "<group>"; }; + F8DB1D000C56B9B800853E27 /* NonDialogUsage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = NonDialogUsage.hxx; path = dum/NonDialogUsage.hxx; sourceTree = "<group>"; }; + F8DB1D010C56B9B800853E27 /* OutgoingEvent.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = OutgoingEvent.hxx; path = dum/OutgoingEvent.hxx; sourceTree = "<group>"; }; + F8DB1D020C56B9B800853E27 /* OutOfDialogHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = OutOfDialogHandler.hxx; path = dum/OutOfDialogHandler.hxx; sourceTree = "<group>"; }; + F8DB1D030C56B9B800853E27 /* OutOfDialogReqCreator.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = OutOfDialogReqCreator.hxx; path = dum/OutOfDialogReqCreator.hxx; sourceTree = "<group>"; }; + F8DB1D040C56B9B800853E27 /* PagerMessageCreator.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = PagerMessageCreator.hxx; path = dum/PagerMessageCreator.hxx; sourceTree = "<group>"; }; + F8DB1D050C56B9B800853E27 /* PagerMessageHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = PagerMessageHandler.hxx; path = dum/PagerMessageHandler.hxx; sourceTree = "<group>"; }; + F8DB1D060C56B9B800853E27 /* Postable.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Postable.hxx; path = dum/Postable.hxx; sourceTree = "<group>"; }; + F8DB1D070C56B9B800853E27 /* Profile.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Profile.hxx; path = dum/Profile.hxx; sourceTree = "<group>"; }; + F8DB1D080C56B9B800853E27 /* PublicationCreator.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = PublicationCreator.hxx; path = dum/PublicationCreator.hxx; sourceTree = "<group>"; }; + F8DB1D090C56B9B800853E27 /* PublicationHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = PublicationHandler.hxx; path = dum/PublicationHandler.hxx; sourceTree = "<group>"; }; + F8DB1D0A0C56B9B800853E27 /* RedirectHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RedirectHandler.hxx; path = dum/RedirectHandler.hxx; sourceTree = "<group>"; }; + F8DB1D0B0C56B9B800853E27 /* RedirectManager.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RedirectManager.hxx; path = dum/RedirectManager.hxx; sourceTree = "<group>"; }; + F8DB1D0C0C56B9B800853E27 /* RefCountedDestroyer.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RefCountedDestroyer.hxx; path = dum/RefCountedDestroyer.hxx; sourceTree = "<group>"; }; + F8DB1D0D0C56B9B800853E27 /* RegistrationCreator.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RegistrationCreator.hxx; path = dum/RegistrationCreator.hxx; sourceTree = "<group>"; }; + F8DB1D0E0C56B9B800853E27 /* RegistrationHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RegistrationHandler.hxx; path = dum/RegistrationHandler.hxx; sourceTree = "<group>"; }; + F8DB1D0F0C56B9B800853E27 /* RegistrationPersistenceManager.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RegistrationPersistenceManager.hxx; path = dum/RegistrationPersistenceManager.hxx; sourceTree = "<group>"; }; + F8DB1D100C56B9B800853E27 /* RemoteCertStore.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RemoteCertStore.hxx; path = dum/RemoteCertStore.hxx; sourceTree = "<group>"; }; + F8DB1D110C56B9B800853E27 /* ServerAuthManager.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ServerAuthManager.hxx; path = dum/ServerAuthManager.hxx; sourceTree = "<group>"; }; + F8DB1D120C56B9B800853E27 /* ServerInviteSession.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ServerInviteSession.hxx; path = dum/ServerInviteSession.hxx; sourceTree = "<group>"; }; + F8DB1D130C56B9B800853E27 /* ServerOutOfDialogReq.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ServerOutOfDialogReq.hxx; path = dum/ServerOutOfDialogReq.hxx; sourceTree = "<group>"; }; + F8DB1D140C56B9B800853E27 /* ServerPagerMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ServerPagerMessage.hxx; path = dum/ServerPagerMessage.hxx; sourceTree = "<group>"; }; + F8DB1D150C56B9B800853E27 /* ServerPublication.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ServerPublication.hxx; path = dum/ServerPublication.hxx; sourceTree = "<group>"; }; + F8DB1D160C56B9B800853E27 /* ServerRegistration.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ServerRegistration.hxx; path = dum/ServerRegistration.hxx; sourceTree = "<group>"; }; + F8DB1D170C56B9B800853E27 /* ServerSubscription.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ServerSubscription.hxx; path = dum/ServerSubscription.hxx; sourceTree = "<group>"; }; + F8DB1D180C56B9B800853E27 /* ServerSubscriptionFunctor.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ServerSubscriptionFunctor.hxx; path = dum/ServerSubscriptionFunctor.hxx; sourceTree = "<group>"; }; + F8DB1D190C56B9B800853E27 /* SubscriptionCreator.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SubscriptionCreator.hxx; path = dum/SubscriptionCreator.hxx; sourceTree = "<group>"; }; + F8DB1D1A0C56B9B800853E27 /* SubscriptionHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SubscriptionHandler.hxx; path = dum/SubscriptionHandler.hxx; sourceTree = "<group>"; }; + F8DB1D1B0C56B9B800853E27 /* SubscriptionPersistenceManager.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SubscriptionPersistenceManager.hxx; path = dum/SubscriptionPersistenceManager.hxx; sourceTree = "<group>"; }; + F8DB1D1C0C56B9B800853E27 /* SubscriptionState.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SubscriptionState.hxx; path = dum/SubscriptionState.hxx; sourceTree = "<group>"; }; + F8DB1D1D0C56B9B800853E27 /* TargetCommand.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TargetCommand.hxx; path = dum/TargetCommand.hxx; sourceTree = "<group>"; }; + F8DB1D1E0C56B9B800853E27 /* UsageUseException.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = UsageUseException.hxx; path = dum/UsageUseException.hxx; sourceTree = "<group>"; }; + F8DB1D1F0C56B9B800853E27 /* UserAuthInfo.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = UserAuthInfo.hxx; path = dum/UserAuthInfo.hxx; sourceTree = "<group>"; }; + F8DB1D200C56B9B800853E27 /* UserProfile.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = UserProfile.hxx; path = dum/UserProfile.hxx; sourceTree = "<group>"; }; + F8DB1D890C56B9EA00853E27 /* ares_compat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ares_compat.h; path = ../contrib/ares/ares_compat.h; sourceTree = SOURCE_ROOT; }; + F8DB1D8A0C56B9EA00853E27 /* ares_dns.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ares_dns.h; path = ../contrib/ares/ares_dns.h; sourceTree = SOURCE_ROOT; }; + F8DB1D8B0C56B9EA00853E27 /* ares_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ares_local.h; path = ../contrib/ares/ares_local.h; sourceTree = SOURCE_ROOT; }; + F8DB1D8C0C56B9EA00853E27 /* ares_private.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ares_private.h; path = ../contrib/ares/ares_private.h; sourceTree = SOURCE_ROOT; }; + F8DB1D920C56CE1500853E27 /* AbstractFifo.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = AbstractFifo.hxx; path = ../rutil/AbstractFifo.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D930C56CE1500853E27 /* AsyncID.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = AsyncID.hxx; path = ../rutil/AsyncID.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D940C56CE1500853E27 /* BaseException.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = BaseException.hxx; path = ../rutil/BaseException.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D950C56CE1500853E27 /* CircularBuffer.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = CircularBuffer.hxx; path = ../rutil/CircularBuffer.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D960C56CE1500853E27 /* Coders.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Coders.hxx; path = ../rutil/Coders.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D970C56CE1500853E27 /* compat.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = compat.hxx; path = ../rutil/compat.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D980C56CE1500853E27 /* Condition.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Condition.hxx; path = ../rutil/Condition.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D990C56CE1500853E27 /* CountStream.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = CountStream.hxx; path = ../rutil/CountStream.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D9A0C56CE1500853E27 /* Data.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Data.hxx; path = ../rutil/Data.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D9B0C56CE1500853E27 /* DataStream.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DataStream.hxx; path = ../rutil/DataStream.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D9C0C56CE1500853E27 /* DnsUtil.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DnsUtil.hxx; path = ../rutil/DnsUtil.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D9D0C56CE1500853E27 /* Fifo.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Fifo.hxx; path = ../rutil/Fifo.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D9E0C56CE1500853E27 /* FileSystem.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = FileSystem.hxx; path = ../rutil/FileSystem.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1D9F0C56CE1500853E27 /* FiniteFifo.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = FiniteFifo.hxx; path = ../rutil/FiniteFifo.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DA00C56CE1500853E27 /* GenericIPAddress.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = GenericIPAddress.hxx; path = ../rutil/GenericIPAddress.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DA10C56CE1500853E27 /* GenericTimerQueue.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = GenericTimerQueue.hxx; path = ../rutil/GenericTimerQueue.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DA20C56CE1500853E27 /* HashMap.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = HashMap.hxx; path = ../rutil/HashMap.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DA30C56CE1500853E27 /* HeapInstanceCounter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = HeapInstanceCounter.cxx; path = ../rutil/HeapInstanceCounter.cxx; sourceTree = SOURCE_ROOT; }; + F8DB1DA40C56CE1500853E27 /* HeapInstanceCounter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = HeapInstanceCounter.hxx; path = ../rutil/HeapInstanceCounter.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DA50C56CE1500853E27 /* Inserter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Inserter.hxx; path = ../rutil/Inserter.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DA60C56CE1500853E27 /* IntrusiveListElement.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = IntrusiveListElement.hxx; path = ../rutil/IntrusiveListElement.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DA70C56CE1500853E27 /* Lock.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Lock.hxx; path = ../rutil/Lock.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DA80C56CE1500853E27 /* Lockable.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Lockable.hxx; path = ../rutil/Lockable.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DA90C56CE1500853E27 /* Log.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Log.hxx; path = ../rutil/Log.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DAA0C56CE1500853E27 /* Logger.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Logger.hxx; path = ../rutil/Logger.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DAB0C56CE1500853E27 /* MD5Stream.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MD5Stream.hxx; path = ../rutil/MD5Stream.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DAC0C56CE1500853E27 /* Mutex.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Mutex.hxx; path = ../rutil/Mutex.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DAE0C56CE1500853E27 /* OpenSSLInit.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = OpenSSLInit.hxx; path = ../rutil/ssl/OpenSSLInit.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DAF0C56CE1500853E27 /* ParseBuffer.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ParseBuffer.hxx; path = ../rutil/ParseBuffer.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DB00C56CE1500853E27 /* Poll.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Poll.cxx; path = ../rutil/Poll.cxx; sourceTree = SOURCE_ROOT; }; + F8DB1DB10C56CE1500853E27 /* Poll.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Poll.hxx; path = ../rutil/Poll.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DB20C56CE1500853E27 /* Random.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Random.hxx; path = ../rutil/Random.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DB30C56CE1500853E27 /* RecursiveMutex.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RecursiveMutex.hxx; path = ../rutil/RecursiveMutex.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DB40C56CE1500853E27 /* RWMutex.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RWMutex.hxx; path = ../rutil/RWMutex.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DB50C56CE1500853E27 /* SHA1Stream.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SHA1Stream.hxx; path = ../rutil/ssl/SHA1Stream.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DB60C56CE1500853E27 /* SharedCount.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SharedCount.hxx; path = ../rutil/SharedCount.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DB70C56CE1500853E27 /* SharedPtr.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SharedPtr.hxx; path = ../rutil/SharedPtr.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DB80C56CE1500853E27 /* Socket.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Socket.hxx; path = ../rutil/Socket.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DB90C56CE1500853E27 /* Subsystem.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Subsystem.hxx; path = ../rutil/Subsystem.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DBA0C56CE1500853E27 /* SysLogBuf.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SysLogBuf.hxx; path = ../rutil/SysLogBuf.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DBB0C56CE1500853E27 /* SysLogStream.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SysLogStream.hxx; path = ../rutil/SysLogStream.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DBC0C56CE1500853E27 /* ThreadIf.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ThreadIf.hxx; path = ../rutil/ThreadIf.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DBD0C56CE1500853E27 /* TimeLimitFifo.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TimeLimitFifo.hxx; path = ../rutil/TimeLimitFifo.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DBE0C56CE1500853E27 /* Timer.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Timer.hxx; path = ../rutil/Timer.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DBF0C56CE1500853E27 /* TransportType.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TransportType.cxx; path = ../rutil/TransportType.cxx; sourceTree = SOURCE_ROOT; }; + F8DB1DC00C56CE1500853E27 /* TransportType.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TransportType.hxx; path = ../rutil/TransportType.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DC10C56CE1500853E27 /* vmd5.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = vmd5.hxx; path = ../rutil/vmd5.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DC20C56CE1500853E27 /* vthread.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = vthread.hxx; path = ../rutil/vthread.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DF40C56CE3C00853E27 /* AresDns.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = AresDns.hxx; path = ../rutil/dns/AresDns.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DF50C56CE3C00853E27 /* DnsAAAARecord.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DnsAAAARecord.hxx; path = ../rutil/dns/DnsAAAARecord.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DF60C56CE3C00853E27 /* DnsCnameRecord.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DnsCnameRecord.hxx; path = ../rutil/dns/DnsCnameRecord.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DF70C56CE3C00853E27 /* DnsHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DnsHandler.hxx; path = ../rutil/dns/DnsHandler.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DF80C56CE3C00853E27 /* DnsHostRecord.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DnsHostRecord.hxx; path = ../rutil/dns/DnsHostRecord.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DF90C56CE3C00853E27 /* DnsNaptrRecord.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DnsNaptrRecord.hxx; path = ../rutil/dns/DnsNaptrRecord.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DFA0C56CE3C00853E27 /* DnsResourceRecord.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DnsResourceRecord.cxx; path = ../rutil/dns/DnsResourceRecord.cxx; sourceTree = SOURCE_ROOT; }; + F8DB1DFB0C56CE3C00853E27 /* DnsResourceRecord.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DnsResourceRecord.hxx; path = ../rutil/dns/DnsResourceRecord.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DFC0C56CE3C00853E27 /* DnsSrvRecord.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DnsSrvRecord.hxx; path = ../rutil/dns/DnsSrvRecord.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DFD0C56CE3C00853E27 /* DnsStub.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DnsStub.hxx; path = ../rutil/dns/DnsStub.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DFE0C56CE3C00853E27 /* ExternalDns.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ExternalDns.hxx; path = ../rutil/dns/ExternalDns.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1DFF0C56CE3C00853E27 /* ExternalDnsFactory.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ExternalDnsFactory.hxx; path = ../rutil/dns/ExternalDnsFactory.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1E000C56CE3C00853E27 /* LocalDns.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = LocalDns.cxx; path = ../rutil/dns/LocalDns.cxx; sourceTree = SOURCE_ROOT; }; + F8DB1E010C56CE3C00853E27 /* LocalDns.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = LocalDns.hxx; path = ../rutil/dns/LocalDns.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1E020C56CE3C00853E27 /* QueryTypes.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = QueryTypes.hxx; path = ../rutil/dns/QueryTypes.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1E030C56CE3C00853E27 /* RRCache.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RRCache.hxx; path = ../rutil/dns/RRCache.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1E040C56CE3C00853E27 /* RRFactory.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RRFactory.hxx; path = ../rutil/dns/RRFactory.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1E050C56CE3C00853E27 /* RRList.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RRList.hxx; path = ../rutil/dns/RRList.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1E060C56CE3C00853E27 /* RROverlay.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RROverlay.hxx; path = ../rutil/dns/RROverlay.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1E070C56CE3C00853E27 /* RRVip.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RRVip.hxx; path = ../rutil/dns/RRVip.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1E1C0C56CE9800853E27 /* Aor.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Aor.cxx; path = stack/Aor.cxx; sourceTree = "<group>"; }; + F8DB1E1D0C56CE9800853E27 /* Aor.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Aor.hxx; path = stack/Aor.hxx; sourceTree = "<group>"; }; + F8DB1E1E0C56CE9800853E27 /* ApiCheck.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ApiCheck.hxx; path = stack/ApiCheck.hxx; sourceTree = "<group>"; }; + F8DB1E1F0C56CE9800853E27 /* ApiCheckList.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ApiCheckList.hxx; path = stack/ApiCheckList.hxx; sourceTree = "<group>"; }; + F8DB1E200C56CE9800853E27 /* ApplicationMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ApplicationMessage.hxx; path = stack/ApplicationMessage.hxx; sourceTree = "<group>"; }; + F8DB1E210C56CE9800853E27 /* ApplicationSip.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ApplicationSip.cxx; path = stack/ApplicationSip.cxx; sourceTree = "<group>"; }; + F8DB1E220C56CE9800853E27 /* ApplicationSip.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ApplicationSip.hxx; path = stack/ApplicationSip.hxx; sourceTree = "<group>"; }; + F8DB1E240C56CE9800853E27 /* Auth.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Auth.hxx; path = stack/Auth.hxx; sourceTree = "<group>"; }; + F8DB1E250C56CE9800853E27 /* BasicNonceHelper.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BasicNonceHelper.cxx; path = stack/BasicNonceHelper.cxx; sourceTree = "<group>"; }; + F8DB1E260C56CE9800853E27 /* BasicNonceHelper.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = BasicNonceHelper.hxx; path = stack/BasicNonceHelper.hxx; sourceTree = "<group>"; }; + F8DB1E270C56CE9800853E27 /* BranchParameter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = BranchParameter.hxx; path = stack/BranchParameter.hxx; sourceTree = "<group>"; }; + F8DB1E280C56CE9800853E27 /* CallId.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = CallId.hxx; path = stack/CallId.hxx; sourceTree = "<group>"; }; + F8DB1E290C56CE9800853E27 /* CancelableTimerQueue.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = CancelableTimerQueue.hxx; path = stack/CancelableTimerQueue.hxx; sourceTree = "<group>"; }; + F8DB1E2A0C56CE9800853E27 /* Compression.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Compression.cxx; path = stack/Compression.cxx; sourceTree = "<group>"; }; + F8DB1E2B0C56CE9800853E27 /* Compression.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Compression.hxx; path = stack/Compression.hxx; sourceTree = "<group>"; }; + F8DB1E2C0C56CE9800853E27 /* Connection.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Connection.hxx; path = stack/Connection.hxx; sourceTree = "<group>"; }; + F8DB1E2D0C56CE9800853E27 /* ConnectionBase.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ConnectionBase.hxx; path = stack/ConnectionBase.hxx; sourceTree = "<group>"; }; + F8DB1E2E0C56CE9800853E27 /* ConnectionManager.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ConnectionManager.hxx; path = stack/ConnectionManager.hxx; sourceTree = "<group>"; }; + F8DB1E2F0C56CE9800853E27 /* ConnectionTerminated.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ConnectionTerminated.hxx; path = stack/ConnectionTerminated.hxx; sourceTree = "<group>"; }; + F8DB1E300C56CE9800853E27 /* Contents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Contents.hxx; path = stack/Contents.hxx; sourceTree = "<group>"; }; + F8DB1E310C56CE9800853E27 /* ContentsFactory.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ContentsFactory.hxx; path = stack/ContentsFactory.hxx; sourceTree = "<group>"; }; + F8DB1E320C56CE9800853E27 /* ContentsFactoryBase.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ContentsFactoryBase.hxx; path = stack/ContentsFactoryBase.hxx; sourceTree = "<group>"; }; + F8DB1E330C56CE9800853E27 /* CpimContents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = CpimContents.hxx; path = stack/CpimContents.hxx; sourceTree = "<group>"; }; + F8DB1E340C56CE9800853E27 /* CSeqCategory.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = CSeqCategory.hxx; path = stack/CSeqCategory.hxx; sourceTree = "<group>"; }; + F8DB1E350C56CE9800853E27 /* DataParameter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DataParameter.hxx; path = stack/DataParameter.hxx; sourceTree = "<group>"; }; + F8DB1E360C56CE9800853E27 /* DateCategory.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DateCategory.hxx; path = stack/DateCategory.hxx; sourceTree = "<group>"; }; + F8DB1E370C56CE9800853E27 /* DeprecatedDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DeprecatedDialog.cxx; path = stack/DeprecatedDialog.cxx; sourceTree = "<group>"; }; + F8DB1E380C56CE9800853E27 /* DeprecatedDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DeprecatedDialog.hxx; path = stack/DeprecatedDialog.hxx; sourceTree = "<group>"; }; + F8DB1E390C56CE9800853E27 /* DnsInterface.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DnsInterface.hxx; path = stack/DnsInterface.hxx; sourceTree = "<group>"; }; + F8DB1E3A0C56CE9800853E27 /* DnsResult.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DnsResult.hxx; path = stack/DnsResult.hxx; sourceTree = "<group>"; }; + F8DB1E3B0C56CE9800853E27 /* DtlsMessage.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DtlsMessage.cxx; path = stack/DtlsMessage.cxx; sourceTree = "<group>"; }; + F8DB1E3C0C56CE9800853E27 /* DtlsMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DtlsMessage.hxx; path = stack/DtlsMessage.hxx; sourceTree = "<group>"; }; + F8DB1E3D0C56CE9800853E27 /* DtlsTransport.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DtlsTransport.cxx; path = stack/ssl/DtlsTransport.cxx; sourceTree = "<group>"; }; + F8DB1E3E0C56CE9800853E27 /* DtlsTransport.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = DtlsTransport.hxx; path = stack/ssl/DtlsTransport.hxx; sourceTree = "<group>"; }; + F8DB1E3F0C56CE9800853E27 /* Embedded.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Embedded.hxx; path = stack/Embedded.hxx; sourceTree = "<group>"; }; + F8DB1E400C56CE9800853E27 /* ExistsParameter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ExistsParameter.hxx; path = stack/ExistsParameter.hxx; sourceTree = "<group>"; }; + F8DB1E410C56CE9800853E27 /* ExpiresCategory.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ExpiresCategory.hxx; path = stack/ExpiresCategory.hxx; sourceTree = "<group>"; }; + F8DB1E420C56CE9800853E27 /* ExtensionHeader.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ExtensionHeader.hxx; path = stack/ExtensionHeader.hxx; sourceTree = "<group>"; }; + F8DB1E430C56CE9800853E27 /* ExtensionParameter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ExtensionParameter.hxx; path = stack/ExtensionParameter.hxx; sourceTree = "<group>"; }; + F8DB1E440C56CE9800853E27 /* ExternalBodyContents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ExternalBodyContents.hxx; path = stack/ExternalBodyContents.hxx; sourceTree = "<group>"; }; + F8DB1E450C56CE9800853E27 /* FloatParameter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = FloatParameter.hxx; path = stack/FloatParameter.hxx; sourceTree = "<group>"; }; + F8DB1E480C56CE9800853E27 /* GenericContents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = GenericContents.hxx; path = stack/GenericContents.hxx; sourceTree = "<group>"; }; + F8DB1E490C56CE9800853E27 /* GenericUri.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = GenericUri.hxx; path = stack/GenericUri.hxx; sourceTree = "<group>"; }; + F8DB1E4A0C56CE9800853E27 /* HeaderFieldValue.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = HeaderFieldValue.hxx; path = stack/HeaderFieldValue.hxx; sourceTree = "<group>"; }; + F8DB1E4B0C56CE9800853E27 /* HeaderFieldValueList.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = HeaderFieldValueList.hxx; path = stack/HeaderFieldValueList.hxx; sourceTree = "<group>"; }; + F8DB1E4C0C56CE9800853E27 /* HeaderHash.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = HeaderHash.hxx; path = stack/HeaderHash.hxx; sourceTree = "<group>"; }; + F8DB1E4D0C56CE9800853E27 /* Headers.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Headers.hxx; path = stack/Headers.hxx; sourceTree = "<group>"; }; + F8DB1E4E0C56CE9800853E27 /* HeaderTypes.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = HeaderTypes.hxx; path = stack/HeaderTypes.hxx; sourceTree = "<group>"; }; + F8DB1E4F0C56CE9800853E27 /* Helper.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Helper.hxx; path = stack/Helper.hxx; sourceTree = "<group>"; }; + F8DB1E500C56CE9800853E27 /* IntegerCategory.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = IntegerCategory.hxx; path = stack/IntegerCategory.hxx; sourceTree = "<group>"; }; + F8DB1E510C56CE9800853E27 /* IntegerParameter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = IntegerParameter.hxx; path = stack/IntegerParameter.hxx; sourceTree = "<group>"; }; + F8DB1E520C56CE9800853E27 /* InternalTransport.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = InternalTransport.hxx; path = stack/InternalTransport.hxx; sourceTree = "<group>"; }; + F8DB1E530C56CE9800853E27 /* InterruptableStackThread.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = InterruptableStackThread.cxx; path = stack/InterruptableStackThread.cxx; sourceTree = "<group>"; }; + F8DB1E540C56CE9800853E27 /* InterruptableStackThread.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = InterruptableStackThread.hxx; path = stack/InterruptableStackThread.hxx; sourceTree = "<group>"; }; + F8DB1E550C56CE9800853E27 /* InvalidContents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = InvalidContents.cxx; path = stack/InvalidContents.cxx; sourceTree = "<group>"; }; + F8DB1E560C56CE9800853E27 /* InvalidContents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = InvalidContents.hxx; path = stack/InvalidContents.hxx; sourceTree = "<group>"; }; + F8DB1E570C56CE9800853E27 /* KeepAliveMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = KeepAliveMessage.hxx; path = stack/KeepAliveMessage.hxx; sourceTree = "<group>"; }; + F8DB1E580C56CE9800853E27 /* LazyParser.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = LazyParser.hxx; path = stack/LazyParser.hxx; sourceTree = "<group>"; }; + F8DB1E590C56CE9800853E27 /* MacSecurity.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MacSecurity.hxx; path = stack/ssl/MacSecurity.hxx; sourceTree = "<group>"; }; + F8DB1E5A0C56CE9800853E27 /* makeCert.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = makeCert.cxx; path = stack/makeCert.cxx; sourceTree = "<group>"; }; + F8DB1E5B0C56CE9800853E27 /* MarkListener.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MarkListener.hxx; path = stack/MarkListener.hxx; sourceTree = "<group>"; }; + F8DB1E5C0C56CE9800853E27 /* Message.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Message.hxx; path = stack/Message.hxx; sourceTree = "<group>"; }; + F8DB1E5D0C56CE9800853E27 /* MessageDecorator.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MessageDecorator.hxx; path = stack/MessageDecorator.hxx; sourceTree = "<group>"; }; + F8DB1E5E0C56CE9800853E27 /* MessageFilterRule.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MessageFilterRule.hxx; path = stack/MessageFilterRule.hxx; sourceTree = "<group>"; }; + F8DB1E5F0C56CE9800853E27 /* MessageWaitingContents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MessageWaitingContents.hxx; path = stack/MessageWaitingContents.hxx; sourceTree = "<group>"; }; + F8DB1E600C56CE9800853E27 /* MethodHash.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MethodHash.hxx; path = stack/MethodHash.hxx; sourceTree = "<group>"; }; + F8DB1E610C56CE9800853E27 /* MethodTypes.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MethodTypes.hxx; path = stack/MethodTypes.hxx; sourceTree = "<group>"; }; + F8DB1E620C56CE9800853E27 /* Mime.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Mime.hxx; path = stack/Mime.hxx; sourceTree = "<group>"; }; + F8DB1E630C56CE9800853E27 /* MsgHeaderScanner.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MsgHeaderScanner.hxx; path = stack/MsgHeaderScanner.hxx; sourceTree = "<group>"; }; + F8DB1E640C56CE9800853E27 /* MultipartAlternativeContents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MultipartAlternativeContents.hxx; path = stack/MultipartAlternativeContents.hxx; sourceTree = "<group>"; }; + F8DB1E650C56CE9800853E27 /* MultipartMixedContents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MultipartMixedContents.hxx; path = stack/MultipartMixedContents.hxx; sourceTree = "<group>"; }; + F8DB1E660C56CE9800853E27 /* MultipartRelatedContents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MultipartRelatedContents.hxx; path = stack/MultipartRelatedContents.hxx; sourceTree = "<group>"; }; + F8DB1E670C56CE9800853E27 /* MultipartSignedContents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MultipartSignedContents.hxx; path = stack/MultipartSignedContents.hxx; sourceTree = "<group>"; }; + F8DB1E680C56CE9800853E27 /* NameAddr.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = NameAddr.hxx; path = stack/NameAddr.hxx; sourceTree = "<group>"; }; + F8DB1E690C56CE9800853E27 /* NonceHelper.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = NonceHelper.cxx; path = stack/NonceHelper.cxx; sourceTree = "<group>"; }; + F8DB1E6A0C56CE9800853E27 /* NonceHelper.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = NonceHelper.hxx; path = stack/NonceHelper.hxx; sourceTree = "<group>"; }; + F8DB1E6B0C56CE9800853E27 /* OctetContents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = OctetContents.hxx; path = stack/OctetContents.hxx; sourceTree = "<group>"; }; + F8DB1E6C0C56CE9800853E27 /* Parameter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Parameter.hxx; path = stack/Parameter.hxx; sourceTree = "<group>"; }; + F8DB1E6D0C56CE9800853E27 /* ParameterHash.gperf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = ParameterHash.gperf; path = stack/ParameterHash.gperf; sourceTree = "<group>"; }; + F8DB1E6E0C56CE9800853E27 /* ParameterHash.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ParameterHash.hxx; path = stack/ParameterHash.hxx; sourceTree = "<group>"; }; + F8DB1E6F0C56CE9800853E27 /* ParameterTypeEnums.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ParameterTypeEnums.hxx; path = stack/ParameterTypeEnums.hxx; sourceTree = "<group>"; }; + F8DB1E700C56CE9800853E27 /* ParameterTypes.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ParameterTypes.hxx; path = stack/ParameterTypes.hxx; sourceTree = "<group>"; }; + F8DB1E720C56CE9800853E27 /* ParserCategories.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ParserCategories.hxx; path = stack/ParserCategories.hxx; sourceTree = "<group>"; }; + F8DB1E730C56CE9800853E27 /* ParserCategory.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ParserCategory.hxx; path = stack/ParserCategory.hxx; sourceTree = "<group>"; }; + F8DB1E740C56CE9800853E27 /* ParserContainer.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ParserContainer.hxx; path = stack/ParserContainer.hxx; sourceTree = "<group>"; }; + F8DB1E750C56CE9800853E27 /* ParserContainerBase.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ParserContainerBase.hxx; path = stack/ParserContainerBase.hxx; sourceTree = "<group>"; }; + F8DB1E760C56CE9800853E27 /* Pidf.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Pidf.cxx; path = stack/Pidf.cxx; sourceTree = "<group>"; }; + F8DB1E770C56CE9800853E27 /* Pidf.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Pidf.hxx; path = stack/Pidf.hxx; sourceTree = "<group>"; }; + F8DB1E780C56CE9800853E27 /* Pkcs7Contents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Pkcs7Contents.hxx; path = stack/Pkcs7Contents.hxx; sourceTree = "<group>"; }; + F8DB1E790C56CE9800853E27 /* Pkcs8Contents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Pkcs8Contents.cxx; path = stack/Pkcs8Contents.cxx; sourceTree = "<group>"; }; + F8DB1E7A0C56CE9800853E27 /* Pkcs8Contents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Pkcs8Contents.hxx; path = stack/Pkcs8Contents.hxx; sourceTree = "<group>"; }; + F8DB1E7B0C56CE9800853E27 /* PlainContents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = PlainContents.hxx; path = stack/PlainContents.hxx; sourceTree = "<group>"; }; + F8DB1E7D0C56CE9800853E27 /* QuotedDataParameter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = QuotedDataParameter.hxx; path = stack/QuotedDataParameter.hxx; sourceTree = "<group>"; }; + F8DB1E7E0C56CE9800853E27 /* QValue.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = QValue.cxx; path = stack/QValue.cxx; sourceTree = "<group>"; }; + F8DB1E7F0C56CE9800853E27 /* QValue.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = QValue.hxx; path = stack/QValue.hxx; sourceTree = "<group>"; }; + F8DB1E800C56CE9800853E27 /* QValueParameter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = QValueParameter.cxx; path = stack/QValueParameter.cxx; sourceTree = "<group>"; }; + F8DB1E810C56CE9800853E27 /* QValueParameter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = QValueParameter.hxx; path = stack/QValueParameter.hxx; sourceTree = "<group>"; }; + F8DB1E820C56CE9800853E27 /* RAckCategory.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RAckCategory.hxx; path = stack/RAckCategory.hxx; sourceTree = "<group>"; }; + F8DB1E860C56CE9800853E27 /* RequestLine.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RequestLine.hxx; path = stack/RequestLine.hxx; sourceTree = "<group>"; }; + F8DB1E870C56CE9800853E27 /* Rlmi.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Rlmi.cxx; path = stack/Rlmi.cxx; sourceTree = "<group>"; }; + F8DB1E880C56CE9800853E27 /* Rlmi.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Rlmi.hxx; path = stack/Rlmi.hxx; sourceTree = "<group>"; }; + F8DB1E890C56CE9800853E27 /* RportParameter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RportParameter.hxx; path = stack/RportParameter.hxx; sourceTree = "<group>"; }; + F8DB1E8A0C56CE9800853E27 /* SdpContents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SdpContents.hxx; path = stack/SdpContents.hxx; sourceTree = "<group>"; }; + F8DB1E8B0C56CE9800853E27 /* Security.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Security.hxx; path = stack/ssl/Security.hxx; sourceTree = "<group>"; }; + F8DB1E8C0C56CE9800853E27 /* SecurityAttributes.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SecurityAttributes.hxx; path = stack/SecurityAttributes.hxx; sourceTree = "<group>"; }; + F8DB1E8D0C56CE9800853E27 /* SecurityTypes.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SecurityTypes.hxx; path = stack/SecurityTypes.hxx; sourceTree = "<group>"; }; + F8DB1E8E0C56CE9800853E27 /* SelectInterruptor.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SelectInterruptor.cxx; path = stack/SelectInterruptor.cxx; sourceTree = "<group>"; }; + F8DB1E8F0C56CE9800853E27 /* SelectInterruptor.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SelectInterruptor.hxx; path = stack/SelectInterruptor.hxx; sourceTree = "<group>"; }; + F8DB1E900C56CE9800853E27 /* SendData.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SendData.hxx; path = stack/SendData.hxx; sourceTree = "<group>"; }; + F8DB1E910C56CE9800853E27 /* SERNonceHelper.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SERNonceHelper.cxx; path = stack/SERNonceHelper.cxx; sourceTree = "<group>"; }; + F8DB1E920C56CE9800853E27 /* SERNonceHelper.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SERNonceHelper.hxx; path = stack/SERNonceHelper.hxx; sourceTree = "<group>"; }; + F8DB1E930C56CE9800853E27 /* ShutdownMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ShutdownMessage.hxx; path = stack/ShutdownMessage.hxx; sourceTree = "<group>"; }; + F8DB1E940C56CE9800853E27 /* SipFrag.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SipFrag.hxx; path = stack/SipFrag.hxx; sourceTree = "<group>"; }; + F8DB1E950C56CE9800853E27 /* SipMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SipMessage.hxx; path = stack/SipMessage.hxx; sourceTree = "<group>"; }; + F8DB1E960C56CE9800853E27 /* SipStack.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = SipStack.hxx; path = stack/SipStack.hxx; sourceTree = "<group>"; }; + F8DB1E970C56CE9800853E27 /* StackThread.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = StackThread.hxx; path = stack/StackThread.hxx; sourceTree = "<group>"; }; + F8DB1E980C56CE9800853E27 /* StatelessHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = StatelessHandler.hxx; path = stack/StatelessHandler.hxx; sourceTree = "<group>"; }; + F8DB1E990C56CE9800853E27 /* StatisticsHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = StatisticsHandler.cxx; path = stack/StatisticsHandler.cxx; sourceTree = "<group>"; }; + F8DB1E9A0C56CE9800853E27 /* StatisticsHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = StatisticsHandler.hxx; path = stack/StatisticsHandler.hxx; sourceTree = "<group>"; }; + F8DB1E9B0C56CE9800853E27 /* StatisticsManager.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = StatisticsManager.hxx; path = stack/StatisticsManager.hxx; sourceTree = "<group>"; }; + F8DB1E9C0C56CE9800853E27 /* StatisticsMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = StatisticsMessage.hxx; path = stack/StatisticsMessage.hxx; sourceTree = "<group>"; }; + F8DB1E9D0C56CE9800853E27 /* StatusLine.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = StatusLine.hxx; path = stack/StatusLine.hxx; sourceTree = "<group>"; }; + F8DB1E9E0C56CE9800853E27 /* StringCategory.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = StringCategory.hxx; path = stack/StringCategory.hxx; sourceTree = "<group>"; }; + F8DB1E9F0C56CE9800853E27 /* Symbols.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Symbols.hxx; path = stack/Symbols.hxx; sourceTree = "<group>"; }; + F8DB1EA00C56CE9800853E27 /* TcpBaseTransport.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TcpBaseTransport.hxx; path = stack/TcpBaseTransport.hxx; sourceTree = "<group>"; }; + F8DB1EA10C56CE9800853E27 /* TcpConnection.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TcpConnection.hxx; path = stack/TcpConnection.hxx; sourceTree = "<group>"; }; + F8DB1EA20C56CE9800853E27 /* TcpTransport.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TcpTransport.hxx; path = stack/TcpTransport.hxx; sourceTree = "<group>"; }; + F8DB1EA30C56CE9800853E27 /* TimeAccumulate.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TimeAccumulate.cxx; path = stack/TimeAccumulate.cxx; sourceTree = "<group>"; }; + F8DB1EA40C56CE9800853E27 /* TimeAccumulate.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TimeAccumulate.hxx; path = stack/TimeAccumulate.hxx; sourceTree = "<group>"; }; + F8DB1EA50C56CE9800853E27 /* TimerMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TimerMessage.hxx; path = stack/TimerMessage.hxx; sourceTree = "<group>"; }; + F8DB1EA60C56CE9800853E27 /* TimerQueue.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TimerQueue.hxx; path = stack/TimerQueue.hxx; sourceTree = "<group>"; }; + F8DB1EA70C56CE9800853E27 /* TlsConnection.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TlsConnection.hxx; path = stack/ssl/TlsConnection.hxx; sourceTree = "<group>"; }; + F8DB1EA80C56CE9800853E27 /* TlsTransport.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TlsTransport.hxx; path = stack/ssl/TlsTransport.hxx; sourceTree = "<group>"; }; + F8DB1EA90C56CE9800853E27 /* Token.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Token.hxx; path = stack/Token.hxx; sourceTree = "<group>"; }; + F8DB1EAA0C56CE9800853E27 /* TransactionController.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TransactionController.hxx; path = stack/TransactionController.hxx; sourceTree = "<group>"; }; + F8DB1EAB0C56CE9800853E27 /* TransactionMap.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TransactionMap.hxx; path = stack/TransactionMap.hxx; sourceTree = "<group>"; }; + F8DB1EAC0C56CE9800853E27 /* TransactionMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TransactionMessage.hxx; path = stack/TransactionMessage.hxx; sourceTree = "<group>"; }; + F8DB1EAD0C56CE9800853E27 /* TransactionState.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TransactionState.hxx; path = stack/TransactionState.hxx; sourceTree = "<group>"; }; + F8DB1EAE0C56CE9800853E27 /* TransactionTerminated.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TransactionTerminated.hxx; path = stack/TransactionTerminated.hxx; sourceTree = "<group>"; }; + F8DB1EAF0C56CE9800853E27 /* TransactionUser.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TransactionUser.hxx; path = stack/TransactionUser.hxx; sourceTree = "<group>"; }; + F8DB1EB00C56CE9800853E27 /* TransactionUserMessage.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TransactionUserMessage.hxx; path = stack/TransactionUserMessage.hxx; sourceTree = "<group>"; }; + F8DB1EB10C56CE9800853E27 /* Transport.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Transport.hxx; path = stack/Transport.hxx; sourceTree = "<group>"; }; + F8DB1EB20C56CE9800853E27 /* TransportFailure.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TransportFailure.hxx; path = stack/TransportFailure.hxx; sourceTree = "<group>"; }; + F8DB1EB30C56CE9800853E27 /* TransportSelector.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TransportSelector.hxx; path = stack/TransportSelector.hxx; sourceTree = "<group>"; }; + F8DB1EB40C56CE9800853E27 /* TuIM.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TuIM.cxx; path = stack/TuIM.cxx; sourceTree = "<group>"; }; + F8DB1EB50C56CE9800853E27 /* TuIM.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TuIM.hxx; path = stack/TuIM.hxx; sourceTree = "<group>"; }; + F8DB1EB60C56CE9800853E27 /* Tuple.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Tuple.hxx; path = stack/Tuple.hxx; sourceTree = "<group>"; }; + F8DB1EB70C56CE9800853E27 /* TupleMarkManager.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TupleMarkManager.cxx; path = stack/TupleMarkManager.cxx; sourceTree = "<group>"; }; + F8DB1EB80C56CE9800853E27 /* TupleMarkManager.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TupleMarkManager.hxx; path = stack/TupleMarkManager.hxx; sourceTree = "<group>"; }; + F8DB1EB90C56CE9800853E27 /* TuSelector.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = TuSelector.hxx; path = stack/TuSelector.hxx; sourceTree = "<group>"; }; + F8DB1EBA0C56CE9800853E27 /* UdpTransport.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = UdpTransport.hxx; path = stack/UdpTransport.hxx; sourceTree = "<group>"; }; + F8DB1EBB0C56CE9800853E27 /* UInt32Category.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UInt32Category.cxx; path = stack/UInt32Category.cxx; sourceTree = "<group>"; }; + F8DB1EBC0C56CE9800853E27 /* UInt32Category.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = UInt32Category.hxx; path = stack/UInt32Category.hxx; sourceTree = "<group>"; }; + F8DB1EBD0C56CE9800853E27 /* UInt32Parameter.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UInt32Parameter.cxx; path = stack/UInt32Parameter.cxx; sourceTree = "<group>"; }; + F8DB1EBE0C56CE9800853E27 /* UInt32Parameter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = UInt32Parameter.hxx; path = stack/UInt32Parameter.hxx; sourceTree = "<group>"; }; + F8DB1EBF0C56CE9800853E27 /* UnknownHeaderType.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = UnknownHeaderType.hxx; path = stack/UnknownHeaderType.hxx; sourceTree = "<group>"; }; + F8DB1EC00C56CE9800853E27 /* UnknownParameter.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = UnknownParameter.hxx; path = stack/UnknownParameter.hxx; sourceTree = "<group>"; }; + F8DB1EC10C56CE9800853E27 /* UnknownParameterType.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = UnknownParameterType.hxx; path = stack/UnknownParameterType.hxx; sourceTree = "<group>"; }; + F8DB1EC20C56CE9800853E27 /* Uri.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Uri.hxx; path = stack/Uri.hxx; sourceTree = "<group>"; }; + F8DB1EC30C56CE9800853E27 /* ValueFifo.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = ValueFifo.hxx; path = stack/ValueFifo.hxx; sourceTree = "<group>"; }; + F8DB1EC40C56CE9800853E27 /* Via.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Via.hxx; path = stack/Via.hxx; sourceTree = "<group>"; }; + F8DB1EC50C56CE9800853E27 /* WarningCategory.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = WarningCategory.hxx; path = stack/WarningCategory.hxx; sourceTree = "<group>"; }; + F8DB1EC80C56CE9800853E27 /* X509Contents.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = X509Contents.cxx; path = stack/X509Contents.cxx; sourceTree = "<group>"; }; + F8DB1EC90C56CE9800853E27 /* X509Contents.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = X509Contents.hxx; path = stack/X509Contents.hxx; sourceTree = "<group>"; }; + F8DB1ECA0C56CE9800853E27 /* XMLCursor.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = XMLCursor.cxx; path = stack/XMLCursor.cxx; sourceTree = "<group>"; }; + F8DB1ECB0C56CE9800853E27 /* XMLCursor.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = XMLCursor.hxx; path = stack/XMLCursor.hxx; sourceTree = "<group>"; }; + F8DB1F790C56CEEC00853E27 /* Stun.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Stun.cxx; path = ../rutil/stun/Stun.cxx; sourceTree = SOURCE_ROOT; }; + F8DB1F7A0C56CEEC00853E27 /* Stun.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Stun.hxx; path = ../rutil/stun/Stun.hxx; sourceTree = SOURCE_ROOT; }; + F8DB1F7B0C56CEEC00853E27 /* Udp.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Udp.cxx; path = ../rutil/stun/Udp.cxx; sourceTree = SOURCE_ROOT; }; + F8DB1F7C0C56CEEC00853E27 /* Udp.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Udp.hxx; path = ../rutil/stun/Udp.hxx; sourceTree = SOURCE_ROOT; }; + F8DB20720C56D75B00853E27 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = /System/Library/Frameworks/SystemConfiguration.framework; sourceTree = "<absolute>"; }; + F8DB209C0C56DAC300853E27 /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = /usr/lib/libcrypto.dylib; sourceTree = "<absolute>"; }; + F8DB209D0C56DAC300853E27 /* libssl.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libssl.dylib; path = /usr/lib/libssl.dylib; sourceTree = "<absolute>"; }; + F8F4ED72133D36380000D69D /* EnableFlowTimer.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = EnableFlowTimer.hxx; path = stack/EnableFlowTimer.hxx; sourceTree = "<group>"; }; + F8F4ED73133D36380000D69D /* EventStackThread.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = EventStackThread.cxx; path = stack/EventStackThread.cxx; sourceTree = "<group>"; }; + F8F4ED74133D36380000D69D /* EventStackThread.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = EventStackThread.hxx; path = stack/EventStackThread.hxx; sourceTree = "<group>"; }; + F8F4ED75133D36380000D69D /* KeepAlivePong.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = KeepAlivePong.hxx; path = stack/KeepAlivePong.hxx; sourceTree = "<group>"; }; + F8F4ED76133D36380000D69D /* TerminateFlow.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = TerminateFlow.hxx; path = stack/TerminateFlow.hxx; sourceTree = "<group>"; }; + F8F4ED7E133D365D0000D69D /* RequestValidationHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = RequestValidationHandler.hxx; path = dum/RequestValidationHandler.hxx; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 12F79732086CBA1E00AF4EDF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F8DB1FB80C56D4B000853E27 /* libares.a in Frameworks */, + F8DB20730C56D75B00853E27 /* SystemConfiguration.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2AAC06D0554671400DB518D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F8DB1C850C56B7D800853E27 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F8DB20A00C56DAD700853E27 /* libcrypto.dylib in Frameworks */, + F8DB20A10C56DAD700853E27 /* libssl.dylib in Frameworks */, + F8DB20880C56D77100853E27 /* SystemConfiguration.framework in Frameworks */, + F8DB1FB40C56D49A00853E27 /* libresiprocate.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DDFF38A45A11DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + D2AAC06F0554671400DB518D /* libares.a */, + 12F79738086CBA1E00AF4EDF /* libresiprocate.a */, + F8DB1C870C56B7D800853E27 /* SipDialer */, + ); + name = Products; + sourceTree = "<group>"; + }; + 0867D691FE84028FC02AAC07 /* sip */ = { + isa = PBXGroup; + children = ( + F8DB1C890C56B7E200853E27 /* sipdialer */, + 08FB77ACFE841707C02AAC07 /* ares */, + 124D79A3086CC64E00BCA5A9 /* dum */, + F8DB1C440C56B50E00853E27 /* rutil */, + 12F7983E086CBBEC00AF4EDF /* resip */, + 0867D69AFE84028FC02AAC07 /* Libraries */, + 034768DDFF38A45A11DB9C8B /* Products */, + ); + name = sip; + sourceTree = "<group>"; + }; + 0867D69AFE84028FC02AAC07 /* Libraries */ = { + isa = PBXGroup; + children = ( + F8DB209C0C56DAC300853E27 /* libcrypto.dylib */, + F8DB209D0C56DAC300853E27 /* libssl.dylib */, + F8DB20720C56D75B00853E27 /* SystemConfiguration.framework */, + ); + name = Libraries; + sourceTree = "<group>"; + }; + 08FB77ACFE841707C02AAC07 /* ares */ = { + isa = PBXGroup; + children = ( + 124D789C086CC36600BCA5A9 /* ares__close_sockets.c */, + 124D789D086CC36600BCA5A9 /* ares__get_hostent.c */, + 124D789E086CC36600BCA5A9 /* ares__read_line.c */, + F8DB1D890C56B9EA00853E27 /* ares_compat.h */, + 124D789F086CC36600BCA5A9 /* ares_destroy.c */, + F8DB1D8A0C56B9EA00853E27 /* ares_dns.h */, + 124D78A0086CC36600BCA5A9 /* ares_expand_name.c */, + 124D78A1086CC36600BCA5A9 /* ares_fds.c */, + 124D78A2086CC36600BCA5A9 /* ares_free_errmem.c */, + 124D78A3086CC36600BCA5A9 /* ares_free_hostent.c */, + 124D78A4086CC36600BCA5A9 /* ares_free_string.c */, + 124D78A5086CC36600BCA5A9 /* ares_gethostbyaddr.c */, + 124D78A6086CC36600BCA5A9 /* ares_gethostbyname.c */, + 124D78A7086CC36600BCA5A9 /* ares_init.c */, + 124D78A8086CC36600BCA5A9 /* ares_local.c */, + F8DB1D8B0C56B9EA00853E27 /* ares_local.h */, + 124D78A9086CC36600BCA5A9 /* ares_mkquery.c */, + 124D78AA086CC36600BCA5A9 /* ares_parse_a_reply.c */, + 124D78AB086CC36600BCA5A9 /* ares_parse_ptr_reply.c */, + F8DB1D8C0C56B9EA00853E27 /* ares_private.h */, + 124D78AC086CC36600BCA5A9 /* ares_process.c */, + 124D78AD086CC36600BCA5A9 /* ares_query.c */, + 124D78AE086CC36600BCA5A9 /* ares_search.c */, + 124D78AF086CC36600BCA5A9 /* ares_send.c */, + 124D78B0086CC36600BCA5A9 /* ares_strerror.c */, + 124D78B1086CC36600BCA5A9 /* ares_timeout.c */, + ); + name = ares; + sourceTree = "<group>"; + }; + 124D799D086CC62900BCA5A9 /* dns */ = { + isa = PBXGroup; + children = ( + F8DB1DF40C56CE3C00853E27 /* AresDns.hxx */, + F8DB1DF50C56CE3C00853E27 /* DnsAAAARecord.hxx */, + F8DB1DF60C56CE3C00853E27 /* DnsCnameRecord.hxx */, + F8DB1DF70C56CE3C00853E27 /* DnsHandler.hxx */, + F8DB1DF80C56CE3C00853E27 /* DnsHostRecord.hxx */, + F8DB1DF90C56CE3C00853E27 /* DnsNaptrRecord.hxx */, + F8DB1DFA0C56CE3C00853E27 /* DnsResourceRecord.cxx */, + F8DB1DFB0C56CE3C00853E27 /* DnsResourceRecord.hxx */, + F8DB1DFC0C56CE3C00853E27 /* DnsSrvRecord.hxx */, + F8DB1DFD0C56CE3C00853E27 /* DnsStub.hxx */, + F8DB1DFE0C56CE3C00853E27 /* ExternalDns.hxx */, + F8DB1DFF0C56CE3C00853E27 /* ExternalDnsFactory.hxx */, + F8DB1E000C56CE3C00853E27 /* LocalDns.cxx */, + F8DB1E010C56CE3C00853E27 /* LocalDns.hxx */, + F8DB1E020C56CE3C00853E27 /* QueryTypes.hxx */, + F8DB1E030C56CE3C00853E27 /* RRCache.hxx */, + F8DB1E040C56CE3C00853E27 /* RRFactory.hxx */, + F8DB1E050C56CE3C00853E27 /* RRList.hxx */, + F8DB1E060C56CE3C00853E27 /* RROverlay.hxx */, + F8DB1E070C56CE3C00853E27 /* RRVip.hxx */, + 124D78CB086CC3CE00BCA5A9 /* AresDns.cxx */, + 124D78DD086CC3CE00BCA5A9 /* ExternalDnsFactory.cxx */, + 124D79A7086CC67000BCA5A9 /* DnsAAAARecord.cxx */, + 124D79A8086CC67000BCA5A9 /* DnsCnameRecord.cxx */, + 124D79A9086CC67000BCA5A9 /* DnsHostRecord.cxx */, + 124D79AA086CC67000BCA5A9 /* DnsNaptrRecord.cxx */, + 124D79AB086CC67000BCA5A9 /* DnsSrvRecord.cxx */, + 124D79AC086CC67000BCA5A9 /* DnsStub.cxx */, + 124D79AD086CC67000BCA5A9 /* QueryTypes.cxx */, + 124D79AE086CC67000BCA5A9 /* RRCache.cxx */, + 124D79AF086CC67000BCA5A9 /* RRList.cxx */, + 124D79B0086CC67000BCA5A9 /* RROverlay.cxx */, + 124D79B1086CC67000BCA5A9 /* RRVip.cxx */, + ); + name = dns; + sourceTree = "<group>"; + }; + 124D79A3086CC64E00BCA5A9 /* dum */ = { + isa = PBXGroup; + children = ( + 124D79BD086CC68200BCA5A9 /* AppDialog.cxx */, + F8DB1CBA0C56B9B800853E27 /* AppDialog.hxx */, + 124D79BE086CC68200BCA5A9 /* AppDialogSet.cxx */, + F8DB1CBB0C56B9B800853E27 /* AppDialogSet.hxx */, + 124D79BF086CC68200BCA5A9 /* AppDialogSetFactory.cxx */, + F8DB1CBC0C56B9B800853E27 /* AppDialogSetFactory.hxx */, + 124D79C0086CC68200BCA5A9 /* BaseCreator.cxx */, + F8DB1CBD0C56B9B800853E27 /* BaseCreator.hxx */, + 124D79C1086CC68200BCA5A9 /* BaseSubscription.cxx */, + F8DB1CBE0C56B9B800853E27 /* BaseSubscription.hxx */, + 124D79C2086CC68200BCA5A9 /* BaseUsage.cxx */, + F8DB1CBF0C56B9B800853E27 /* BaseUsage.hxx */, + 12BF59570895D7B800F7DD81 /* CertMessage.cxx */, + F8DB1CC00C56B9B800853E27 /* CertMessage.hxx */, + F8DB1CC10C56B9B800853E27 /* ChallengeInfo.cxx */, + F8DB1CC20C56B9B800853E27 /* ChallengeInfo.hxx */, + F8A057E3124D52DE00112774 /* ClientAuthExtension.cxx */, + F8A057E4124D52DE00112774 /* ClientAuthExtension.hxx */, + 124D79C3086CC68200BCA5A9 /* ClientAuthManager.cxx */, + F8DB1CC30C56B9B800853E27 /* ClientAuthManager.hxx */, + 124D79C4086CC68200BCA5A9 /* ClientInviteSession.cxx */, + F8DB1CC40C56B9B800853E27 /* ClientInviteSession.hxx */, + 124D79C5086CC68200BCA5A9 /* ClientOutOfDialogReq.cxx */, + F8DB1CC50C56B9B800853E27 /* ClientOutOfDialogReq.hxx */, + 124D79C6086CC68200BCA5A9 /* ClientPagerMessage.cxx */, + F8DB1CC60C56B9B800853E27 /* ClientPagerMessage.hxx */, + 124D79C7086CC68200BCA5A9 /* ClientPublication.cxx */, + F8DB1CC70C56B9B800853E27 /* ClientPublication.hxx */, + 124D79C8086CC68200BCA5A9 /* ClientRegistration.cxx */, + F8DB1CC80C56B9B800853E27 /* ClientRegistration.hxx */, + 124D79C9086CC68200BCA5A9 /* ClientSubscription.cxx */, + F8DB1CC90C56B9B800853E27 /* ClientSubscription.hxx */, + F8DB1CCA0C56B9B800853E27 /* ClientSubscriptionFunctor.hxx */, + F8DB1CCB0C56B9B800853E27 /* ContactInstanceRecord.cxx */, + F8DB1CCC0C56B9B800853E27 /* ContactInstanceRecord.hxx */, + 124D79CA086CC68200BCA5A9 /* DefaultServerReferHandler.cxx */, + F8DB1CCD0C56B9B800853E27 /* DefaultServerReferHandler.hxx */, + 124D79CB086CC68200BCA5A9 /* DestroyUsage.cxx */, + F8DB1CCE0C56B9B800853E27 /* DestroyUsage.hxx */, + 124D79CC086CC68200BCA5A9 /* Dialog.cxx */, + F8DB1CCF0C56B9B800853E27 /* Dialog.hxx */, + F8DB1CD00C56B9B800853E27 /* DialogEventHandler.hxx */, + F8A057E5124D52DE00112774 /* DialogEventInfo.cxx */, + F8A057E6124D52DE00112774 /* DialogEventInfo.hxx */, + F8A057E7124D52DE00112774 /* DialogEventStateManager.cxx */, + F8A057E8124D52DE00112774 /* DialogEventStateManager.hxx */, + 124D79CD086CC68200BCA5A9 /* DialogId.cxx */, + F8DB1CD10C56B9B800853E27 /* DialogId.hxx */, + 124D79CE086CC68200BCA5A9 /* DialogSet.cxx */, + F8DB1CD20C56B9B800853E27 /* DialogSet.hxx */, + F8DB1CD30C56B9B800853E27 /* DialogSetHandler.hxx */, + 124D79CF086CC68200BCA5A9 /* DialogSetId.cxx */, + F8DB1CD40C56B9B800853E27 /* DialogSetId.hxx */, + 124D79D0086CC68200BCA5A9 /* DialogUsage.cxx */, + F8DB1CD50C56B9B800853E27 /* DialogUsage.hxx */, + 124D79D1086CC68200BCA5A9 /* DialogUsageManager.cxx */, + F8DB1CD60C56B9B800853E27 /* DialogUsageManager.hxx */, + F8DB1CD70C56B9B800853E27 /* DumCommand.hxx */, + 12BF593A0895D5FF00F7DD81 /* DumDecrypted.cxx */, + F8DB1CD80C56B9B800853E27 /* DumDecrypted.hxx */, + F8DB1CD90C56B9B800853E27 /* DumException.hxx */, + 12396E3608A2F3C800C5ED5E /* DumFeature.cxx */, + F8DB1CDA0C56B9B800853E27 /* DumFeature.hxx */, + 123B4D4E089871C90049A5B9 /* DumFeatureChain.cxx */, + F8DB1CDB0C56B9B800853E27 /* DumFeatureChain.hxx */, + 123B4D560898721D0049A5B9 /* DumFeatureMessage.cxx */, + F8DB1CDC0C56B9B800853E27 /* DumFeatureMessage.hxx */, + F8DB1CDD0C56B9B800853E27 /* DumHelper.cxx */, + F8DB1CDE0C56B9B800853E27 /* DumHelper.hxx */, + 124D79D2086CC68200BCA5A9 /* DumProcessHandler.cxx */, + F8DB1CDF0C56B9B800853E27 /* DumProcessHandler.hxx */, + F8DB1CE00C56B9B800853E27 /* DumShutdownHandler.hxx */, + F8DB1CE10C56B9B800853E27 /* DumThread.cxx */, + F8DB1CE20C56B9B800853E27 /* DumThread.hxx */, + 124D79D3086CC68200BCA5A9 /* DumTimeout.cxx */, + F8DB1CE30C56B9B800853E27 /* DumTimeout.hxx */, + 12BF59380895D5E600F7DD81 /* EncryptionManager.cxx */, + F8DB1CE40C56B9B800853E27 /* EncryptionManager.hxx */, + 123B4D54089872040049A5B9 /* EncryptionRequest.cxx */, + F8DB1CE50C56B9B800853E27 /* EncryptionRequest.hxx */, + F8DB1CE60C56B9B800853E27 /* EventDispatcher.hxx */, + F8DB1CE70C56B9B800853E27 /* ExternalMessageBase.hxx */, + F8DB1CE80C56B9B800853E27 /* ExternalMessageHandler.hxx */, + F8DB1CE90C56B9B800853E27 /* ExternalTimer.hxx */, + F8DB1CEA0C56B9B800853E27 /* Handle.cxx */, + F8DB1CEB0C56B9B800853E27 /* Handle.hxx */, + 124D79D4086CC68200BCA5A9 /* Handled.cxx */, + F8DB1CEC0C56B9B800853E27 /* Handled.hxx */, + 124D79D5086CC68200BCA5A9 /* HandleException.cxx */, + F8DB1CED0C56B9B800853E27 /* HandleException.hxx */, + 124D79D6086CC68200BCA5A9 /* HandleManager.cxx */, + F8DB1CEE0C56B9B800853E27 /* HandleManager.hxx */, + F8DB1CEF0C56B9B800853E27 /* Handles.hxx */, + F8DB1CF00C56B9B800853E27 /* HttpGetMessage.hxx */, + F8DB1CF10C56B9B800853E27 /* HttpProvider.hxx */, + 123B4D52089871F70049A5B9 /* IdentityHandler.cxx */, + F8DB1CF20C56B9B800853E27 /* IdentityHandler.hxx */, + F8DB1CF30C56B9B800853E27 /* InMemoryRegistrationDatabase.cxx */, + F8DB1CF40C56B9B800853E27 /* InMemoryRegistrationDatabase.hxx */, + F8A057E9124D52DE00112774 /* InMemorySyncRegDb.cxx */, + F8A057EA124D52DE00112774 /* InMemorySyncRegDb.hxx */, + F8DB1CF50C56B9B800853E27 /* InviteDialogs.hxx */, + 124D79D7086CC68200BCA5A9 /* InviteSession.cxx */, + F8DB1CF60C56B9B800853E27 /* InviteSession.hxx */, + 124D79D8086CC68200BCA5A9 /* InviteSessionCreator.cxx */, + F8DB1CF70C56B9B800853E27 /* InviteSessionCreator.hxx */, + 124D79D9086CC68200BCA5A9 /* InviteSessionHandler.cxx */, + F8DB1CF80C56B9B800853E27 /* InviteSessionHandler.hxx */, + 124D79DB086CC68200BCA5A9 /* KeepAliveManager.cxx */, + F8DB1CF90C56B9B800853E27 /* KeepAliveManager.hxx */, + 124D79DC086CC68200BCA5A9 /* KeepAliveTimeout.cxx */, + F8DB1CFA0C56B9B800853E27 /* KeepAliveTimeout.hxx */, + 124D79DD086CC68200BCA5A9 /* MasterProfile.cxx */, + F8DB1CFB0C56B9B800853E27 /* MasterProfile.hxx */, + 124D79DA086CC68200BCA5A9 /* MergedRequestKey.cxx */, + F8DB1CFC0C56B9B800853E27 /* MergedRequestKey.hxx */, + F8DB1CFD0C56B9B800853E27 /* MergedRequestRemovalCommand.cxx */, + F8DB1CFE0C56B9B800853E27 /* MergedRequestRemovalCommand.hxx */, + 124D79DE086CC68200BCA5A9 /* NetworkAssociation.cxx */, + F8DB1CFF0C56B9B800853E27 /* NetworkAssociation.hxx */, + 124D79DF086CC68200BCA5A9 /* NonDialogUsage.cxx */, + F8DB1D000C56B9B800853E27 /* NonDialogUsage.hxx */, + 12396E6908A2F91E00C5ED5E /* OutgoingEvent.cxx */, + F8DB1D010C56B9B800853E27 /* OutgoingEvent.hxx */, + F8DB1D020C56B9B800853E27 /* OutOfDialogHandler.hxx */, + 124D79E0086CC68200BCA5A9 /* OutOfDialogReqCreator.cxx */, + F8DB1D030C56B9B800853E27 /* OutOfDialogReqCreator.hxx */, + 124D79E1086CC68200BCA5A9 /* PagerMessageCreator.cxx */, + F8DB1D040C56B9B800853E27 /* PagerMessageCreator.hxx */, + F8DB1D050C56B9B800853E27 /* PagerMessageHandler.hxx */, + F8DB1D060C56B9B800853E27 /* Postable.hxx */, + 124D79E2086CC68200BCA5A9 /* Profile.cxx */, + F8DB1D070C56B9B800853E27 /* Profile.hxx */, + 124D79E3086CC68200BCA5A9 /* PublicationCreator.cxx */, + F8DB1D080C56B9B800853E27 /* PublicationCreator.hxx */, + F8DB1D090C56B9B800853E27 /* PublicationHandler.hxx */, + F8A057EB124D52DE00112774 /* RADIUSServerAuthManager.cxx */, + F8A057EC124D52DE00112774 /* RADIUSServerAuthManager.hxx */, + F8DB1D0A0C56B9B800853E27 /* RedirectHandler.hxx */, + 124D79E4086CC68200BCA5A9 /* RedirectManager.cxx */, + F8DB1D0B0C56B9B800853E27 /* RedirectManager.hxx */, + F8DB1D0C0C56B9B800853E27 /* RefCountedDestroyer.hxx */, + 124D79E5086CC68200BCA5A9 /* RegistrationCreator.cxx */, + F8DB1D0D0C56B9B800853E27 /* RegistrationCreator.hxx */, + F8A057ED124D52DE00112774 /* RegistrationHandler.cxx */, + F8DB1D0E0C56B9B800853E27 /* RegistrationHandler.hxx */, + F8DB1D0F0C56B9B800853E27 /* RegistrationPersistenceManager.hxx */, + F8DB1D100C56B9B800853E27 /* RemoteCertStore.hxx */, + F8F4ED7E133D365D0000D69D /* RequestValidationHandler.hxx */, + 124D79E6086CC68200BCA5A9 /* ServerAuthManager.cxx */, + F8DB1D110C56B9B800853E27 /* ServerAuthManager.hxx */, + 124D79E7086CC68200BCA5A9 /* ServerInviteSession.cxx */, + F8DB1D120C56B9B800853E27 /* ServerInviteSession.hxx */, + 124D79E8086CC68200BCA5A9 /* ServerOutOfDialogReq.cxx */, + F8DB1D130C56B9B800853E27 /* ServerOutOfDialogReq.hxx */, + 124D79E9086CC68200BCA5A9 /* ServerPagerMessage.cxx */, + F8DB1D140C56B9B800853E27 /* ServerPagerMessage.hxx */, + 124D79EA086CC68200BCA5A9 /* ServerPublication.cxx */, + F8DB1D150C56B9B800853E27 /* ServerPublication.hxx */, + 124D79EB086CC68200BCA5A9 /* ServerRegistration.cxx */, + F8DB1D160C56B9B800853E27 /* ServerRegistration.hxx */, + 124D79EC086CC68200BCA5A9 /* ServerSubscription.cxx */, + F8DB1D170C56B9B800853E27 /* ServerSubscription.hxx */, + F8DB1D180C56B9B800853E27 /* ServerSubscriptionFunctor.hxx */, + 124D79ED086CC68200BCA5A9 /* SubscriptionCreator.cxx */, + F8DB1D190C56B9B800853E27 /* SubscriptionCreator.hxx */, + 124D79EE086CC68200BCA5A9 /* SubscriptionHandler.cxx */, + F8DB1D1A0C56B9B800853E27 /* SubscriptionHandler.hxx */, + F8DB1D1B0C56B9B800853E27 /* SubscriptionPersistenceManager.hxx */, + 124D79EF086CC68200BCA5A9 /* SubscriptionState.cxx */, + F8DB1D1C0C56B9B800853E27 /* SubscriptionState.hxx */, + 12396E6B08A2F93400C5ED5E /* TargetCommand.cxx */, + F8DB1D1D0C56B9B800853E27 /* TargetCommand.hxx */, + F8DB1D1E0C56B9B800853E27 /* UsageUseException.hxx */, + 124D79F1086CC68200BCA5A9 /* UserAuthInfo.cxx */, + F8DB1D1F0C56B9B800853E27 /* UserAuthInfo.hxx */, + 124D79F2086CC68200BCA5A9 /* UserProfile.cxx */, + F8DB1D200C56B9B800853E27 /* UserProfile.hxx */, + ); + name = dum; + sourceTree = "<group>"; + }; + 12F7983E086CBBEC00AF4EDF /* resip */ = { + isa = PBXGroup; + children = ( + F8A057D3124D52BA00112774 /* AbandonServerTransaction.hxx */, + F8DB1E1C0C56CE9800853E27 /* Aor.cxx */, + F8DB1E1D0C56CE9800853E27 /* Aor.hxx */, + 124D78CA086CC3CE00BCA5A9 /* ApiCheck.cxx */, + F8DB1E1E0C56CE9800853E27 /* ApiCheck.hxx */, + F8DB1E1F0C56CE9800853E27 /* ApiCheckList.hxx */, + F8DB1E200C56CE9800853E27 /* ApplicationMessage.hxx */, + F8DB1E210C56CE9800853E27 /* ApplicationSip.cxx */, + F8DB1E220C56CE9800853E27 /* ApplicationSip.hxx */, + 124D78CC086CC3CE00BCA5A9 /* Auth.cxx */, + F8DB1E240C56CE9800853E27 /* Auth.hxx */, + F8DB1E250C56CE9800853E27 /* BasicNonceHelper.cxx */, + F8DB1E260C56CE9800853E27 /* BasicNonceHelper.hxx */, + 124D78CD086CC3CE00BCA5A9 /* BranchParameter.cxx */, + F8DB1E270C56CE9800853E27 /* BranchParameter.hxx */, + 124D78CE086CC3CE00BCA5A9 /* CallId.cxx */, + F8DB1E280C56CE9800853E27 /* CallId.hxx */, + F8DB1E290C56CE9800853E27 /* CancelableTimerQueue.hxx */, + F8A057D4124D52BA00112774 /* CancelClientInviteTransaction.hxx */, + F8DB1E2A0C56CE9800853E27 /* Compression.cxx */, + F8DB1E2B0C56CE9800853E27 /* Compression.hxx */, + 124D78CF086CC3CE00BCA5A9 /* Connection.cxx */, + F8DB1E2C0C56CE9800853E27 /* Connection.hxx */, + 124D78D0086CC3CE00BCA5A9 /* ConnectionBase.cxx */, + F8DB1E2D0C56CE9800853E27 /* ConnectionBase.hxx */, + 124D78D1086CC3CE00BCA5A9 /* ConnectionManager.cxx */, + F8DB1E2E0C56CE9800853E27 /* ConnectionManager.hxx */, + F8DB1E2F0C56CE9800853E27 /* ConnectionTerminated.hxx */, + 124D78D2086CC3CE00BCA5A9 /* Contents.cxx */, + F8DB1E300C56CE9800853E27 /* Contents.hxx */, + F8DB1E310C56CE9800853E27 /* ContentsFactory.hxx */, + 12BF59360895D5BA00F7DD81 /* ContentsFactoryBase.cxx */, + F8DB1E320C56CE9800853E27 /* ContentsFactoryBase.hxx */, + 124D78D3086CC3CE00BCA5A9 /* CpimContents.cxx */, + F8DB1E330C56CE9800853E27 /* CpimContents.hxx */, + 124D78D4086CC3CE00BCA5A9 /* CSeqCategory.cxx */, + F8DB1E340C56CE9800853E27 /* CSeqCategory.hxx */, + 124D78D5086CC3CE00BCA5A9 /* DataParameter.cxx */, + F8DB1E350C56CE9800853E27 /* DataParameter.hxx */, + 124D78D6086CC3CE00BCA5A9 /* DateCategory.cxx */, + F8DB1E360C56CE9800853E27 /* DateCategory.hxx */, + F8DB1E370C56CE9800853E27 /* DeprecatedDialog.cxx */, + F8DB1E380C56CE9800853E27 /* DeprecatedDialog.hxx */, + 124D78D7086CC3CE00BCA5A9 /* DnsInterface.cxx */, + F8DB1E390C56CE9800853E27 /* DnsInterface.hxx */, + 124D78D8086CC3CE00BCA5A9 /* DnsResult.cxx */, + F8DB1E3A0C56CE9800853E27 /* DnsResult.hxx */, + F8DB1E3B0C56CE9800853E27 /* DtlsMessage.cxx */, + F8DB1E3C0C56CE9800853E27 /* DtlsMessage.hxx */, + F8DB1E3D0C56CE9800853E27 /* DtlsTransport.cxx */, + F8DB1E3E0C56CE9800853E27 /* DtlsTransport.hxx */, + 124D78D9086CC3CE00BCA5A9 /* Embedded.cxx */, + F8DB1E3F0C56CE9800853E27 /* Embedded.hxx */, + F8F4ED72133D36380000D69D /* EnableFlowTimer.hxx */, + F8F4ED73133D36380000D69D /* EventStackThread.cxx */, + F8F4ED74133D36380000D69D /* EventStackThread.hxx */, + F8A057D5124D52BA00112774 /* ExistsOrDataParameter.cxx */, + F8A057D6124D52BA00112774 /* ExistsOrDataParameter.hxx */, + 124D78DA086CC3CE00BCA5A9 /* ExistsParameter.cxx */, + F8DB1E400C56CE9800853E27 /* ExistsParameter.hxx */, + 124D78DB086CC3CE00BCA5A9 /* ExpiresCategory.cxx */, + F8DB1E410C56CE9800853E27 /* ExpiresCategory.hxx */, + 124EC47B08721CFF0017C8BB /* ExtensionHeader.cxx */, + F8DB1E420C56CE9800853E27 /* ExtensionHeader.hxx */, + 124EC47C08721CFF0017C8BB /* ExtensionParameter.cxx */, + F8DB1E430C56CE9800853E27 /* ExtensionParameter.hxx */, + 124D78DC086CC3CE00BCA5A9 /* ExternalBodyContents.cxx */, + F8DB1E440C56CE9800853E27 /* ExternalBodyContents.hxx */, + 124D78DE086CC3CE00BCA5A9 /* FloatParameter.cxx */, + F8DB1E450C56CE9800853E27 /* FloatParameter.hxx */, + 124D78DF086CC3CE00BCA5A9 /* GenericContents.cxx */, + F8DB1E480C56CE9800853E27 /* GenericContents.hxx */, + 124D78E0086CC3CE00BCA5A9 /* GenericUri.cxx */, + F8DB1E490C56CE9800853E27 /* GenericUri.hxx */, + 124D78E1086CC3CE00BCA5A9 /* HeaderFieldValue.cxx */, + F8DB1E4A0C56CE9800853E27 /* HeaderFieldValue.hxx */, + 124D78E2086CC3CE00BCA5A9 /* HeaderFieldValueList.cxx */, + F8DB1E4B0C56CE9800853E27 /* HeaderFieldValueList.hxx */, + 124D78E3086CC3CE00BCA5A9 /* HeaderHash.cxx */, + F8DB1E4C0C56CE9800853E27 /* HeaderHash.hxx */, + 124D78E4086CC3CE00BCA5A9 /* Headers.cxx */, + F8DB1E4D0C56CE9800853E27 /* Headers.hxx */, + 124D78E5086CC3CE00BCA5A9 /* HeaderTypes.cxx */, + F8DB1E4E0C56CE9800853E27 /* HeaderTypes.hxx */, + 124D78E6086CC3CE00BCA5A9 /* Helper.cxx */, + F8DB1E4F0C56CE9800853E27 /* Helper.hxx */, + 124D7A5F086CC77900BCA5A9 /* HttpGetMessage.cxx */, + 124D7A60086CC77900BCA5A9 /* HttpProvider.cxx */, + 124D78E7086CC3CE00BCA5A9 /* IntegerCategory.cxx */, + F8DB1E500C56CE9800853E27 /* IntegerCategory.hxx */, + 124D78E8086CC3CE00BCA5A9 /* IntegerParameter.cxx */, + F8DB1E510C56CE9800853E27 /* IntegerParameter.hxx */, + 124D78E9086CC3CE00BCA5A9 /* InternalTransport.cxx */, + F8DB1E520C56CE9800853E27 /* InternalTransport.hxx */, + F8A057D7124D52BA00112774 /* InteropHelper.cxx */, + F8A057D8124D52BA00112774 /* InteropHelper.hxx */, + F8DB1E530C56CE9800853E27 /* InterruptableStackThread.cxx */, + F8DB1E540C56CE9800853E27 /* InterruptableStackThread.hxx */, + F8DB1E550C56CE9800853E27 /* InvalidContents.cxx */, + F8DB1E560C56CE9800853E27 /* InvalidContents.hxx */, + 124D78EA086CC3CE00BCA5A9 /* KeepAliveMessage.cxx */, + F8DB1E570C56CE9800853E27 /* KeepAliveMessage.hxx */, + F8F4ED75133D36380000D69D /* KeepAlivePong.hxx */, + 124D78EB086CC3CE00BCA5A9 /* LazyParser.cxx */, + F8DB1E580C56CE9800853E27 /* LazyParser.hxx */, + 124D78EC086CC3CE00BCA5A9 /* MacSecurity.cxx */, + F8DB1E590C56CE9800853E27 /* MacSecurity.hxx */, + F8DB1E5A0C56CE9800853E27 /* makeCert.cxx */, + F8DB1E5B0C56CE9800853E27 /* MarkListener.hxx */, + 124D78ED086CC3CE00BCA5A9 /* Message.cxx */, + F8DB1E5C0C56CE9800853E27 /* Message.hxx */, + F8DB1E5D0C56CE9800853E27 /* MessageDecorator.hxx */, + 124D78EE086CC3CE00BCA5A9 /* MessageFilterRule.cxx */, + F8DB1E5E0C56CE9800853E27 /* MessageFilterRule.hxx */, + 124D78EF086CC3CE00BCA5A9 /* MessageWaitingContents.cxx */, + F8DB1E5F0C56CE9800853E27 /* MessageWaitingContents.hxx */, + 124D78F0086CC3CE00BCA5A9 /* MethodHash.cxx */, + F8DB1E600C56CE9800853E27 /* MethodHash.hxx */, + 124D78F1086CC3CE00BCA5A9 /* MethodTypes.cxx */, + F8DB1E610C56CE9800853E27 /* MethodTypes.hxx */, + 124D78F2086CC3CE00BCA5A9 /* Mime.cxx */, + F8DB1E620C56CE9800853E27 /* Mime.hxx */, + 124D78F3086CC3CE00BCA5A9 /* MsgHeaderScanner.cxx */, + F8DB1E630C56CE9800853E27 /* MsgHeaderScanner.hxx */, + 124D78F4086CC3CE00BCA5A9 /* MultipartAlternativeContents.cxx */, + F8DB1E640C56CE9800853E27 /* MultipartAlternativeContents.hxx */, + 124D78F5086CC3CE00BCA5A9 /* MultipartMixedContents.cxx */, + F8DB1E650C56CE9800853E27 /* MultipartMixedContents.hxx */, + 124D78F6086CC3CE00BCA5A9 /* MultipartRelatedContents.cxx */, + F8DB1E660C56CE9800853E27 /* MultipartRelatedContents.hxx */, + 124D78F7086CC3CE00BCA5A9 /* MultipartSignedContents.cxx */, + F8DB1E670C56CE9800853E27 /* MultipartSignedContents.hxx */, + 124D78F8086CC3CE00BCA5A9 /* NameAddr.cxx */, + F8DB1E680C56CE9800853E27 /* NameAddr.hxx */, + F8DB1E690C56CE9800853E27 /* NonceHelper.cxx */, + F8DB1E6A0C56CE9800853E27 /* NonceHelper.hxx */, + 124D78F9086CC3CE00BCA5A9 /* OctetContents.cxx */, + F8DB1E6B0C56CE9800853E27 /* OctetContents.hxx */, + 124D78FA086CC3CE00BCA5A9 /* Parameter.cxx */, + F8DB1E6C0C56CE9800853E27 /* Parameter.hxx */, + 124D78FB086CC3CE00BCA5A9 /* ParameterHash.cxx */, + F8DB1E6D0C56CE9800853E27 /* ParameterHash.gperf */, + F8DB1E6E0C56CE9800853E27 /* ParameterHash.hxx */, + F8DB1E6F0C56CE9800853E27 /* ParameterTypeEnums.hxx */, + 124D78FC086CC3CE00BCA5A9 /* ParameterTypes.cxx */, + F8DB1E700C56CE9800853E27 /* ParameterTypes.hxx */, + 124D78FD086CC3CE00BCA5A9 /* ParserCategories.cxx */, + F8DB1E720C56CE9800853E27 /* ParserCategories.hxx */, + 124D78FE086CC3CE00BCA5A9 /* ParserCategory.cxx */, + F8DB1E730C56CE9800853E27 /* ParserCategory.hxx */, + F8DB1E740C56CE9800853E27 /* ParserContainer.hxx */, + 12BF59340895D59E00F7DD81 /* ParserContainerBase.cxx */, + F8DB1E750C56CE9800853E27 /* ParserContainerBase.hxx */, + F8DB1E760C56CE9800853E27 /* Pidf.cxx */, + F8DB1E770C56CE9800853E27 /* Pidf.hxx */, + 124D7900086CC3CE00BCA5A9 /* Pkcs7Contents.cxx */, + F8DB1E780C56CE9800853E27 /* Pkcs7Contents.hxx */, + F8DB1E790C56CE9800853E27 /* Pkcs8Contents.cxx */, + F8DB1E7A0C56CE9800853E27 /* Pkcs8Contents.hxx */, + 124D7901086CC3CE00BCA5A9 /* PlainContents.cxx */, + F8DB1E7B0C56CE9800853E27 /* PlainContents.hxx */, + F8A057D9124D52BA00112774 /* PrivacyCategory.cxx */, + F8A057DA124D52BA00112774 /* PrivacyCategory.hxx */, + 124D7903086CC3CE00BCA5A9 /* QuotedDataParameter.cxx */, + F8DB1E7D0C56CE9800853E27 /* QuotedDataParameter.hxx */, + F8DB1E7E0C56CE9800853E27 /* QValue.cxx */, + F8DB1E7F0C56CE9800853E27 /* QValue.hxx */, + F8DB1E800C56CE9800853E27 /* QValueParameter.cxx */, + F8DB1E810C56CE9800853E27 /* QValueParameter.hxx */, + 124D7904086CC3CE00BCA5A9 /* RAckCategory.cxx */, + F8DB1E820C56CE9800853E27 /* RAckCategory.hxx */, + 124D7906086CC3CE00BCA5A9 /* RequestLine.cxx */, + F8DB1E860C56CE9800853E27 /* RequestLine.hxx */, + F8DB1E870C56CE9800853E27 /* Rlmi.cxx */, + F8DB1E880C56CE9800853E27 /* Rlmi.hxx */, + 124D7907086CC3CE00BCA5A9 /* RportParameter.cxx */, + F8DB1E890C56CE9800853E27 /* RportParameter.hxx */, + 124D7908086CC3CE00BCA5A9 /* SdpContents.cxx */, + F8DB1E8A0C56CE9800853E27 /* SdpContents.hxx */, + 124D7909086CC3CE00BCA5A9 /* Security.cxx */, + F8DB1E8B0C56CE9800853E27 /* Security.hxx */, + 124D790A086CC3CE00BCA5A9 /* SecurityAttributes.cxx */, + F8DB1E8C0C56CE9800853E27 /* SecurityAttributes.hxx */, + F8DB1E8D0C56CE9800853E27 /* SecurityTypes.hxx */, + F8DB1E8E0C56CE9800853E27 /* SelectInterruptor.cxx */, + F8DB1E8F0C56CE9800853E27 /* SelectInterruptor.hxx */, + F8DB1E900C56CE9800853E27 /* SendData.hxx */, + F8DB1E910C56CE9800853E27 /* SERNonceHelper.cxx */, + F8DB1E920C56CE9800853E27 /* SERNonceHelper.hxx */, + F8DB1E930C56CE9800853E27 /* ShutdownMessage.hxx */, + 124D790B086CC3CE00BCA5A9 /* SipFrag.cxx */, + F8DB1E940C56CE9800853E27 /* SipFrag.hxx */, + 124D790C086CC3CE00BCA5A9 /* SipMessage.cxx */, + F8DB1E950C56CE9800853E27 /* SipMessage.hxx */, + 124D790D086CC3CE00BCA5A9 /* SipStack.cxx */, + F8DB1E960C56CE9800853E27 /* SipStack.hxx */, + 124D790E086CC3CE00BCA5A9 /* StackThread.cxx */, + F8DB1E970C56CE9800853E27 /* StackThread.hxx */, + 124D790F086CC3CE00BCA5A9 /* StatelessHandler.cxx */, + F8DB1E980C56CE9800853E27 /* StatelessHandler.hxx */, + F8DB1E990C56CE9800853E27 /* StatisticsHandler.cxx */, + F8DB1E9A0C56CE9800853E27 /* StatisticsHandler.hxx */, + 124D7910086CC3CE00BCA5A9 /* StatisticsManager.cxx */, + F8DB1E9B0C56CE9800853E27 /* StatisticsManager.hxx */, + 124D7911086CC3CE00BCA5A9 /* StatisticsMessage.cxx */, + F8DB1E9C0C56CE9800853E27 /* StatisticsMessage.hxx */, + 124D7912086CC3CE00BCA5A9 /* StatusLine.cxx */, + F8DB1E9D0C56CE9800853E27 /* StatusLine.hxx */, + 124D7913086CC3CE00BCA5A9 /* StringCategory.cxx */, + F8DB1E9E0C56CE9800853E27 /* StringCategory.hxx */, + 124D7914086CC3CE00BCA5A9 /* Symbols.cxx */, + F8DB1E9F0C56CE9800853E27 /* Symbols.hxx */, + 124D7915086CC3CE00BCA5A9 /* TcpBaseTransport.cxx */, + F8DB1EA00C56CE9800853E27 /* TcpBaseTransport.hxx */, + 124D7916086CC3CE00BCA5A9 /* TcpConnection.cxx */, + F8DB1EA10C56CE9800853E27 /* TcpConnection.hxx */, + 124D7917086CC3CE00BCA5A9 /* TcpTransport.cxx */, + F8DB1EA20C56CE9800853E27 /* TcpTransport.hxx */, + F8F4ED76133D36380000D69D /* TerminateFlow.hxx */, + F8DB1EA30C56CE9800853E27 /* TimeAccumulate.cxx */, + F8DB1EA40C56CE9800853E27 /* TimeAccumulate.hxx */, + 124D7918086CC3CE00BCA5A9 /* TimerMessage.cxx */, + F8DB1EA50C56CE9800853E27 /* TimerMessage.hxx */, + 124D7919086CC3CE00BCA5A9 /* TimerQueue.cxx */, + F8DB1EA60C56CE9800853E27 /* TimerQueue.hxx */, + 124D791A086CC3CE00BCA5A9 /* TlsConnection.cxx */, + F8DB1EA70C56CE9800853E27 /* TlsConnection.hxx */, + 124D791B086CC3CE00BCA5A9 /* TlsTransport.cxx */, + F8DB1EA80C56CE9800853E27 /* TlsTransport.hxx */, + 124D791C086CC3CE00BCA5A9 /* Token.cxx */, + F8DB1EA90C56CE9800853E27 /* Token.hxx */, + 124D791D086CC3CE00BCA5A9 /* TransactionController.cxx */, + F8DB1EAA0C56CE9800853E27 /* TransactionController.hxx */, + 124D791E086CC3CE00BCA5A9 /* TransactionMap.cxx */, + F8DB1EAB0C56CE9800853E27 /* TransactionMap.hxx */, + F8DB1EAC0C56CE9800853E27 /* TransactionMessage.hxx */, + 124D791F086CC3CE00BCA5A9 /* TransactionState.cxx */, + F8DB1EAD0C56CE9800853E27 /* TransactionState.hxx */, + F8DB1EAE0C56CE9800853E27 /* TransactionTerminated.hxx */, + 124D7920086CC3CE00BCA5A9 /* TransactionUser.cxx */, + F8DB1EAF0C56CE9800853E27 /* TransactionUser.hxx */, + 124D7921086CC3CE00BCA5A9 /* TransactionUserMessage.cxx */, + F8DB1EB00C56CE9800853E27 /* TransactionUserMessage.hxx */, + 124D7922086CC3CE00BCA5A9 /* Transport.cxx */, + F8DB1EB10C56CE9800853E27 /* Transport.hxx */, + 124EC467087217600017C8BB /* TransportFailure.cxx */, + F8DB1EB20C56CE9800853E27 /* TransportFailure.hxx */, + 124D7923086CC3CE00BCA5A9 /* TransportSelector.cxx */, + F8DB1EB30C56CE9800853E27 /* TransportSelector.hxx */, + F8DB1EB40C56CE9800853E27 /* TuIM.cxx */, + F8DB1EB50C56CE9800853E27 /* TuIM.hxx */, + F8DB1EB60C56CE9800853E27 /* Tuple.hxx */, + F8DB1EB70C56CE9800853E27 /* TupleMarkManager.cxx */, + F8DB1EB80C56CE9800853E27 /* TupleMarkManager.hxx */, + 124D7924086CC3CE00BCA5A9 /* TuSelector.cxx */, + F8DB1EB90C56CE9800853E27 /* TuSelector.hxx */, + 124D7925086CC3CE00BCA5A9 /* UdpTransport.cxx */, + F8DB1EBA0C56CE9800853E27 /* UdpTransport.hxx */, + F8DB1EBB0C56CE9800853E27 /* UInt32Category.cxx */, + F8DB1EBC0C56CE9800853E27 /* UInt32Category.hxx */, + F8DB1EBD0C56CE9800853E27 /* UInt32Parameter.cxx */, + F8DB1EBE0C56CE9800853E27 /* UInt32Parameter.hxx */, + F8DB1EBF0C56CE9800853E27 /* UnknownHeaderType.hxx */, + 124D7926086CC3CE00BCA5A9 /* UnknownParameter.cxx */, + F8DB1EC00C56CE9800853E27 /* UnknownParameter.hxx */, + F8DB1EC10C56CE9800853E27 /* UnknownParameterType.hxx */, + 124D7927086CC3CE00BCA5A9 /* Uri.cxx */, + F8DB1EC20C56CE9800853E27 /* Uri.hxx */, + F8DB1EC30C56CE9800853E27 /* ValueFifo.hxx */, + 124D7928086CC3CE00BCA5A9 /* Via.cxx */, + F8DB1EC40C56CE9800853E27 /* Via.hxx */, + 124D7929086CC3CE00BCA5A9 /* WarningCategory.cxx */, + F8DB1EC50C56CE9800853E27 /* WarningCategory.hxx */, + F8DB1EC80C56CE9800853E27 /* X509Contents.cxx */, + F8DB1EC90C56CE9800853E27 /* X509Contents.hxx */, + F8DB1ECA0C56CE9800853E27 /* XMLCursor.cxx */, + F8DB1ECB0C56CE9800853E27 /* XMLCursor.hxx */, + ); + name = resip; + sourceTree = "<group>"; + }; + F8DB1C440C56B50E00853E27 /* rutil */ = { + isa = PBXGroup; + children = ( + 124D7A29086CC69300BCA5A9 /* AbstractFifo.cxx */, + F8DB1D920C56CE1500853E27 /* AbstractFifo.hxx */, + F8DB1D930C56CE1500853E27 /* AsyncID.hxx */, + F8C76C911243CCFF0076CFF8 /* AsyncProcessHandler.hxx */, + 124D7A2A086CC69300BCA5A9 /* BaseException.cxx */, + F8DB1D940C56CE1500853E27 /* BaseException.hxx */, + F8DB1D950C56CE1500853E27 /* CircularBuffer.hxx */, + 124D7A2B086CC69300BCA5A9 /* Coders.cxx */, + F8DB1D960C56CE1500853E27 /* Coders.hxx */, + F8DB1D970C56CE1500853E27 /* compat.hxx */, + 124D7A2C086CC69300BCA5A9 /* Condition.cxx */, + F8DB1D980C56CE1500853E27 /* Condition.hxx */, + 124D7A2D086CC69300BCA5A9 /* CountStream.cxx */, + F8DB1D990C56CE1500853E27 /* CountStream.hxx */, + 124D7A2E086CC69300BCA5A9 /* Data.cxx */, + F8DB1D9A0C56CE1500853E27 /* Data.hxx */, + F8C76C921243CCFF0076CFF8 /* DataException.hxx */, + 124D7A2F086CC69300BCA5A9 /* DataStream.cxx */, + F8DB1D9B0C56CE1500853E27 /* DataStream.hxx */, + F8C76C931243CCFF0076CFF8 /* DigestStream.cxx */, + F8C76C941243CCFF0076CFF8 /* DigestStream.hxx */, + 124D799D086CC62900BCA5A9 /* dns */, + 124D7A30086CC69300BCA5A9 /* DnsUtil.cxx */, + F8DB1D9C0C56CE1500853E27 /* DnsUtil.hxx */, + F80A8D4812B2CA66002D37E0 /* FdPoll.cxx */, + F80A8D4912B2CA66002D37E0 /* FdPoll.hxx */, + F8DB1D9D0C56CE1500853E27 /* Fifo.hxx */, + 124D7A31086CC69300BCA5A9 /* FileSystem.cxx */, + F8DB1D9E0C56CE1500853E27 /* FileSystem.hxx */, + F8DB1D9F0C56CE1500853E27 /* FiniteFifo.hxx */, + F8DB1DA00C56CE1500853E27 /* GenericIPAddress.hxx */, + F8DB1DA10C56CE1500853E27 /* GenericTimerQueue.hxx */, + F8DB1DA20C56CE1500853E27 /* HashMap.hxx */, + F8DB1DA30C56CE1500853E27 /* HeapInstanceCounter.cxx */, + F8DB1DA40C56CE1500853E27 /* HeapInstanceCounter.hxx */, + F8DB1DA50C56CE1500853E27 /* Inserter.hxx */, + F8DB1DA60C56CE1500853E27 /* IntrusiveListElement.hxx */, + 124D7A32086CC69300BCA5A9 /* Lock.cxx */, + F8DB1DA70C56CE1500853E27 /* Lock.hxx */, + F8DB1DA80C56CE1500853E27 /* Lockable.hxx */, + 124D7A33086CC69300BCA5A9 /* Log.cxx */, + F8DB1DA90C56CE1500853E27 /* Log.hxx */, + F8DB1DAA0C56CE1500853E27 /* Logger.hxx */, + 124D7A35086CC69300BCA5A9 /* MD5Stream.cxx */, + F8DB1DAB0C56CE1500853E27 /* MD5Stream.hxx */, + 124D7A36086CC69300BCA5A9 /* Mutex.cxx */, + F8DB1DAC0C56CE1500853E27 /* Mutex.hxx */, + F8C76CA91243CD2B0076CFF8 /* OpenSSLInit.cxx */, + F8DB1DAE0C56CE1500853E27 /* OpenSSLInit.hxx */, + 124D7A37086CC69300BCA5A9 /* ParseBuffer.cxx */, + F8DB1DAF0C56CE1500853E27 /* ParseBuffer.hxx */, + F8C76C951243CCFF0076CFF8 /* ParseException.cxx */, + F8C76C961243CCFF0076CFF8 /* ParseException.hxx */, + F8DB1DB00C56CE1500853E27 /* Poll.cxx */, + F8DB1DB10C56CE1500853E27 /* Poll.hxx */, + F8C76C971243CCFF0076CFF8 /* RADIUSDigestAuthenticator.cxx */, + F8C76C981243CCFF0076CFF8 /* RADIUSDigestAuthenticator.hxx */, + 124D7A38086CC69300BCA5A9 /* Random.cxx */, + F8DB1DB20C56CE1500853E27 /* Random.hxx */, + 124D7A39086CC69300BCA5A9 /* RecursiveMutex.cxx */, + F8DB1DB30C56CE1500853E27 /* RecursiveMutex.hxx */, + F8C76C991243CCFF0076CFF8 /* resipfaststreams.cxx */, + F8C76C9A1243CCFF0076CFF8 /* resipfaststreams.hxx */, + 124D7A3A086CC69300BCA5A9 /* RWMutex.cxx */, + F8DB1DB40C56CE1500853E27 /* RWMutex.hxx */, + F8C76CAA1243CD2B0076CFF8 /* SHA1Stream.cxx */, + F8DB1DB50C56CE1500853E27 /* SHA1Stream.hxx */, + F8DB1DB60C56CE1500853E27 /* SharedCount.hxx */, + F8DB1DB70C56CE1500853E27 /* SharedPtr.hxx */, + 124D7A3C086CC69300BCA5A9 /* Socket.cxx */, + F8DB1DB80C56CE1500853E27 /* Socket.hxx */, + F8DB1F780C56CED500853E27 /* stun */, + 124D7A3D086CC69300BCA5A9 /* Subsystem.cxx */, + F8DB1DB90C56CE1500853E27 /* Subsystem.hxx */, + 124D7A3E086CC69300BCA5A9 /* SysLogBuf.cxx */, + F8DB1DBA0C56CE1500853E27 /* SysLogBuf.hxx */, + 124D7A3F086CC69300BCA5A9 /* SysLogStream.cxx */, + F8DB1DBB0C56CE1500853E27 /* SysLogStream.hxx */, + 124D7A40086CC69300BCA5A9 /* ThreadIf.cxx */, + F8DB1DBC0C56CE1500853E27 /* ThreadIf.hxx */, + F8C76C9B1243CCFF0076CFF8 /* Time.cxx */, + F8C76C9C1243CCFF0076CFF8 /* Time.hxx */, + F8DB1DBD0C56CE1500853E27 /* TimeLimitFifo.hxx */, + 124D7A41086CC69300BCA5A9 /* Timer.cxx */, + F8DB1DBE0C56CE1500853E27 /* Timer.hxx */, + F8DB1DBF0C56CE1500853E27 /* TransportType.cxx */, + F8DB1DC00C56CE1500853E27 /* TransportType.hxx */, + 124D7A42086CC69300BCA5A9 /* Tuple.cxx */, + 124D7A43086CC69300BCA5A9 /* vmd5.cxx */, + F8DB1DC10C56CE1500853E27 /* vmd5.hxx */, + F8DB1DC20C56CE1500853E27 /* vthread.hxx */, + ); + name = rutil; + sourceTree = "<group>"; + }; + F8DB1C890C56B7E200853E27 /* sipdialer */ = { + isa = PBXGroup; + children = ( + F8DB1C8E0C56B7FD00853E27 /* DialerConfiguration.cpp */, + F8DB1C8F0C56B7FD00853E27 /* DialInstance.cpp */, + F8DB1C900C56B7FD00853E27 /* MyInviteSessionHandler.cpp */, + F8DB1C910C56B7FD00853E27 /* sipdialer.cpp */, + ); + name = sipdialer; + sourceTree = "<group>"; + }; + F8DB1F780C56CED500853E27 /* stun */ = { + isa = PBXGroup; + children = ( + F8DB1F790C56CEEC00853E27 /* Stun.cxx */, + F8DB1F7A0C56CEEC00853E27 /* Stun.hxx */, + F8DB1F7B0C56CEEC00853E27 /* Udp.cxx */, + F8DB1F7C0C56CEEC00853E27 /* Udp.hxx */, + ); + name = stun; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 12F79730086CBA1E00AF4EDF /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + F8A057DB124D52BA00112774 /* AbandonServerTransaction.hxx in Headers */, + F8DB1DC30C56CE1500853E27 /* AbstractFifo.hxx in Headers */, + F8DB1ECD0C56CE9800853E27 /* Aor.hxx in Headers */, + F8DB1ECE0C56CE9800853E27 /* ApiCheck.hxx in Headers */, + F8DB1ECF0C56CE9800853E27 /* ApiCheckList.hxx in Headers */, + F8DB1D210C56B9B800853E27 /* AppDialog.hxx in Headers */, + F8DB1D220C56B9B800853E27 /* AppDialogSet.hxx in Headers */, + F8DB1D230C56B9B800853E27 /* AppDialogSetFactory.hxx in Headers */, + F8DB1ED00C56CE9800853E27 /* ApplicationMessage.hxx in Headers */, + F8DB1ED20C56CE9800853E27 /* ApplicationSip.hxx in Headers */, + F8DB1E080C56CE3C00853E27 /* AresDns.hxx in Headers */, + F8DB1DC40C56CE1500853E27 /* AsyncID.hxx in Headers */, + F8C76C9D1243CCFF0076CFF8 /* AsyncProcessHandler.hxx in Headers */, + F8DB1ED40C56CE9800853E27 /* Auth.hxx in Headers */, + F8DB1D240C56B9B800853E27 /* BaseCreator.hxx in Headers */, + F8DB1DC50C56CE1500853E27 /* BaseException.hxx in Headers */, + F8DB1D250C56B9B800853E27 /* BaseSubscription.hxx in Headers */, + F8DB1D260C56B9B800853E27 /* BaseUsage.hxx in Headers */, + F8DB1ED60C56CE9800853E27 /* BasicNonceHelper.hxx in Headers */, + F8DB1ED70C56CE9800853E27 /* BranchParameter.hxx in Headers */, + F8DB1ED80C56CE9800853E27 /* CallId.hxx in Headers */, + F8DB1ED90C56CE9800853E27 /* CancelableTimerQueue.hxx in Headers */, + F8A057DC124D52BA00112774 /* CancelClientInviteTransaction.hxx in Headers */, + F8DB1D270C56B9B800853E27 /* CertMessage.hxx in Headers */, + F8DB1D290C56B9B800853E27 /* ChallengeInfo.hxx in Headers */, + F8DB1DC60C56CE1500853E27 /* CircularBuffer.hxx in Headers */, + F8A057EF124D52DE00112774 /* ClientAuthExtension.hxx in Headers */, + F8DB1D2A0C56B9B800853E27 /* ClientAuthManager.hxx in Headers */, + F8DB1D2B0C56B9B800853E27 /* ClientInviteSession.hxx in Headers */, + F8DB1D2C0C56B9B800853E27 /* ClientOutOfDialogReq.hxx in Headers */, + F8DB1D2D0C56B9B800853E27 /* ClientPagerMessage.hxx in Headers */, + F8DB1D2E0C56B9B800853E27 /* ClientPublication.hxx in Headers */, + F8DB1D2F0C56B9B800853E27 /* ClientRegistration.hxx in Headers */, + F8DB1D300C56B9B800853E27 /* ClientSubscription.hxx in Headers */, + F8DB1D310C56B9B800853E27 /* ClientSubscriptionFunctor.hxx in Headers */, + F8DB1DC70C56CE1500853E27 /* Coders.hxx in Headers */, + F8DB1DC80C56CE1500853E27 /* compat.hxx in Headers */, + F8DB1EDB0C56CE9800853E27 /* Compression.hxx in Headers */, + F8DB1DC90C56CE1500853E27 /* Condition.hxx in Headers */, + F8DB1EDC0C56CE9800853E27 /* Connection.hxx in Headers */, + F8DB1EDD0C56CE9800853E27 /* ConnectionBase.hxx in Headers */, + F8DB1EDE0C56CE9800853E27 /* ConnectionManager.hxx in Headers */, + F8DB1EDF0C56CE9800853E27 /* ConnectionTerminated.hxx in Headers */, + F8DB1D330C56B9B800853E27 /* ContactInstanceRecord.hxx in Headers */, + F8DB1EE00C56CE9800853E27 /* Contents.hxx in Headers */, + F8DB1EE10C56CE9800853E27 /* ContentsFactory.hxx in Headers */, + F8DB1EE20C56CE9800853E27 /* ContentsFactoryBase.hxx in Headers */, + F8DB1DCA0C56CE1500853E27 /* CountStream.hxx in Headers */, + F8DB1EE30C56CE9800853E27 /* CpimContents.hxx in Headers */, + F8DB1EE40C56CE9800853E27 /* CSeqCategory.hxx in Headers */, + F8DB1DCB0C56CE1500853E27 /* Data.hxx in Headers */, + F8C76C9E1243CCFF0076CFF8 /* DataException.hxx in Headers */, + F8DB1EE50C56CE9800853E27 /* DataParameter.hxx in Headers */, + F8DB1DCC0C56CE1500853E27 /* DataStream.hxx in Headers */, + F8DB1EE60C56CE9800853E27 /* DateCategory.hxx in Headers */, + F8DB1D340C56B9B800853E27 /* DefaultServerReferHandler.hxx in Headers */, + F8DB1EE80C56CE9800853E27 /* DeprecatedDialog.hxx in Headers */, + F8DB1D350C56B9B800853E27 /* DestroyUsage.hxx in Headers */, + F8DB1D360C56B9B800853E27 /* Dialog.hxx in Headers */, + F8DB1D370C56B9B800853E27 /* DialogEventHandler.hxx in Headers */, + F8A057F1124D52DE00112774 /* DialogEventInfo.hxx in Headers */, + F8A057F3124D52DE00112774 /* DialogEventStateManager.hxx in Headers */, + F8DB1D380C56B9B800853E27 /* DialogId.hxx in Headers */, + F8DB1D390C56B9B800853E27 /* DialogSet.hxx in Headers */, + F8DB1D3A0C56B9B800853E27 /* DialogSetHandler.hxx in Headers */, + F8DB1D3B0C56B9B800853E27 /* DialogSetId.hxx in Headers */, + F8DB1D3C0C56B9B800853E27 /* DialogUsage.hxx in Headers */, + F8DB1D3D0C56B9B800853E27 /* DialogUsageManager.hxx in Headers */, + F8C76CA01243CCFF0076CFF8 /* DigestStream.hxx in Headers */, + F8DB1E090C56CE3C00853E27 /* DnsAAAARecord.hxx in Headers */, + F8DB1E0A0C56CE3C00853E27 /* DnsCnameRecord.hxx in Headers */, + F8DB1E0B0C56CE3C00853E27 /* DnsHandler.hxx in Headers */, + F8DB1E0C0C56CE3C00853E27 /* DnsHostRecord.hxx in Headers */, + F8DB1EE90C56CE9800853E27 /* DnsInterface.hxx in Headers */, + F8DB1E0D0C56CE3C00853E27 /* DnsNaptrRecord.hxx in Headers */, + F8DB1E0F0C56CE3C00853E27 /* DnsResourceRecord.hxx in Headers */, + F8DB1EEA0C56CE9800853E27 /* DnsResult.hxx in Headers */, + F8DB1E100C56CE3C00853E27 /* DnsSrvRecord.hxx in Headers */, + F8DB1E110C56CE3C00853E27 /* DnsStub.hxx in Headers */, + F8DB1DCD0C56CE1500853E27 /* DnsUtil.hxx in Headers */, + F8DB1EEC0C56CE9800853E27 /* DtlsMessage.hxx in Headers */, + F8DB1EEE0C56CE9800853E27 /* DtlsTransport.hxx in Headers */, + F8DB1D3E0C56B9B800853E27 /* DumCommand.hxx in Headers */, + F8DB1D3F0C56B9B800853E27 /* DumDecrypted.hxx in Headers */, + F8DB1D400C56B9B800853E27 /* DumException.hxx in Headers */, + F8DB1D410C56B9B800853E27 /* DumFeature.hxx in Headers */, + F8DB1D420C56B9B800853E27 /* DumFeatureChain.hxx in Headers */, + F8DB1D430C56B9B800853E27 /* DumFeatureMessage.hxx in Headers */, + F8DB1D450C56B9B800853E27 /* DumHelper.hxx in Headers */, + F8DB1D460C56B9B800853E27 /* DumProcessHandler.hxx in Headers */, + F8DB1D470C56B9B800853E27 /* DumShutdownHandler.hxx in Headers */, + F8DB1D490C56B9B800853E27 /* DumThread.hxx in Headers */, + F8DB1D4A0C56B9B800853E27 /* DumTimeout.hxx in Headers */, + F8DB1EEF0C56CE9800853E27 /* Embedded.hxx in Headers */, + F8F4ED77133D36380000D69D /* EnableFlowTimer.hxx in Headers */, + F8DB1D4B0C56B9B800853E27 /* EncryptionManager.hxx in Headers */, + F8DB1D4C0C56B9B800853E27 /* EncryptionRequest.hxx in Headers */, + F8DB1D4D0C56B9B800853E27 /* EventDispatcher.hxx in Headers */, + F8F4ED79133D36380000D69D /* EventStackThread.hxx in Headers */, + F8A057DE124D52BA00112774 /* ExistsOrDataParameter.hxx in Headers */, + F8DB1EF00C56CE9800853E27 /* ExistsParameter.hxx in Headers */, + F8DB1EF10C56CE9800853E27 /* ExpiresCategory.hxx in Headers */, + F8DB1EF20C56CE9800853E27 /* ExtensionHeader.hxx in Headers */, + F8DB1EF30C56CE9800853E27 /* ExtensionParameter.hxx in Headers */, + F8DB1EF40C56CE9800853E27 /* ExternalBodyContents.hxx in Headers */, + F8DB1E120C56CE3C00853E27 /* ExternalDns.hxx in Headers */, + F8DB1E130C56CE3C00853E27 /* ExternalDnsFactory.hxx in Headers */, + F8DB1D4E0C56B9B800853E27 /* ExternalMessageBase.hxx in Headers */, + F8DB1D4F0C56B9B800853E27 /* ExternalMessageHandler.hxx in Headers */, + F8DB1D500C56B9B800853E27 /* ExternalTimer.hxx in Headers */, + F80A8D4B12B2CA66002D37E0 /* FdPoll.hxx in Headers */, + F8DB1DCE0C56CE1500853E27 /* Fifo.hxx in Headers */, + F8DB1DCF0C56CE1500853E27 /* FileSystem.hxx in Headers */, + F8DB1DD00C56CE1500853E27 /* FiniteFifo.hxx in Headers */, + F8DB1EF50C56CE9800853E27 /* FloatParameter.hxx in Headers */, + F8DB1EF80C56CE9800853E27 /* GenericContents.hxx in Headers */, + F8DB1DD10C56CE1500853E27 /* GenericIPAddress.hxx in Headers */, + F8DB1DD20C56CE1500853E27 /* GenericTimerQueue.hxx in Headers */, + F8DB1EF90C56CE9800853E27 /* GenericUri.hxx in Headers */, + F8DB1D520C56B9B800853E27 /* Handle.hxx in Headers */, + F8DB1D530C56B9B800853E27 /* Handled.hxx in Headers */, + F8DB1D540C56B9B800853E27 /* HandleException.hxx in Headers */, + F8DB1D550C56B9B800853E27 /* HandleManager.hxx in Headers */, + F8DB1D560C56B9B800853E27 /* Handles.hxx in Headers */, + F8DB1DD30C56CE1500853E27 /* HashMap.hxx in Headers */, + F8DB1EFA0C56CE9800853E27 /* HeaderFieldValue.hxx in Headers */, + F8DB1EFB0C56CE9800853E27 /* HeaderFieldValueList.hxx in Headers */, + F8DB1EFC0C56CE9800853E27 /* HeaderHash.hxx in Headers */, + F8DB1EFD0C56CE9800853E27 /* Headers.hxx in Headers */, + F8DB1EFE0C56CE9800853E27 /* HeaderTypes.hxx in Headers */, + F8DB1DD50C56CE1500853E27 /* HeapInstanceCounter.hxx in Headers */, + F8DB1EFF0C56CE9800853E27 /* Helper.hxx in Headers */, + F8DB1D570C56B9B800853E27 /* HttpGetMessage.hxx in Headers */, + F8DB1D580C56B9B800853E27 /* HttpProvider.hxx in Headers */, + F8DB1D590C56B9B800853E27 /* IdentityHandler.hxx in Headers */, + F8DB1D5B0C56B9B800853E27 /* InMemoryRegistrationDatabase.hxx in Headers */, + F8A057F5124D52DE00112774 /* InMemorySyncRegDb.hxx in Headers */, + F8DB1DD60C56CE1500853E27 /* Inserter.hxx in Headers */, + F8DB1F000C56CE9800853E27 /* IntegerCategory.hxx in Headers */, + F8DB1F010C56CE9800853E27 /* IntegerParameter.hxx in Headers */, + F8DB1F020C56CE9800853E27 /* InternalTransport.hxx in Headers */, + F8A057E0124D52BA00112774 /* InteropHelper.hxx in Headers */, + F8DB1F040C56CE9800853E27 /* InterruptableStackThread.hxx in Headers */, + F8DB1DD70C56CE1500853E27 /* IntrusiveListElement.hxx in Headers */, + F8DB1F060C56CE9800853E27 /* InvalidContents.hxx in Headers */, + F8DB1D5C0C56B9B800853E27 /* InviteDialogs.hxx in Headers */, + F8DB1D5D0C56B9B800853E27 /* InviteSession.hxx in Headers */, + F8DB1D5E0C56B9B800853E27 /* InviteSessionCreator.hxx in Headers */, + F8DB1D5F0C56B9B800853E27 /* InviteSessionHandler.hxx in Headers */, + F8DB1D600C56B9B800853E27 /* KeepAliveManager.hxx in Headers */, + F8DB1F070C56CE9800853E27 /* KeepAliveMessage.hxx in Headers */, + F8F4ED7A133D36380000D69D /* KeepAlivePong.hxx in Headers */, + F8DB1D610C56B9B800853E27 /* KeepAliveTimeout.hxx in Headers */, + F8DB1F080C56CE9800853E27 /* LazyParser.hxx in Headers */, + F8DB1E150C56CE3C00853E27 /* LocalDns.hxx in Headers */, + F8DB1DD80C56CE1500853E27 /* Lock.hxx in Headers */, + F8DB1DD90C56CE1500853E27 /* Lockable.hxx in Headers */, + F8DB1DDA0C56CE1500853E27 /* Log.hxx in Headers */, + F8DB1DDB0C56CE1500853E27 /* Logger.hxx in Headers */, + F8DB1F090C56CE9800853E27 /* MacSecurity.hxx in Headers */, + F8DB1F0B0C56CE9800853E27 /* MarkListener.hxx in Headers */, + F8DB1D620C56B9B800853E27 /* MasterProfile.hxx in Headers */, + F8DB1DDC0C56CE1500853E27 /* MD5Stream.hxx in Headers */, + F8DB1D630C56B9B800853E27 /* MergedRequestKey.hxx in Headers */, + F8DB1D650C56B9B800853E27 /* MergedRequestRemovalCommand.hxx in Headers */, + F8DB1F0C0C56CE9800853E27 /* Message.hxx in Headers */, + F8DB1F0D0C56CE9800853E27 /* MessageDecorator.hxx in Headers */, + F8DB1F0E0C56CE9800853E27 /* MessageFilterRule.hxx in Headers */, + F8DB1F0F0C56CE9800853E27 /* MessageWaitingContents.hxx in Headers */, + F8DB1F100C56CE9800853E27 /* MethodHash.hxx in Headers */, + F8DB1F110C56CE9800853E27 /* MethodTypes.hxx in Headers */, + F8DB1F120C56CE9800853E27 /* Mime.hxx in Headers */, + F8DB1F130C56CE9800853E27 /* MsgHeaderScanner.hxx in Headers */, + F8DB1F140C56CE9800853E27 /* MultipartAlternativeContents.hxx in Headers */, + F8DB1F150C56CE9800853E27 /* MultipartMixedContents.hxx in Headers */, + F8DB1F160C56CE9800853E27 /* MultipartRelatedContents.hxx in Headers */, + F8DB1F170C56CE9800853E27 /* MultipartSignedContents.hxx in Headers */, + F8DB1DDD0C56CE1500853E27 /* Mutex.hxx in Headers */, + F8DB1F180C56CE9800853E27 /* NameAddr.hxx in Headers */, + F8DB1D660C56B9B800853E27 /* NetworkAssociation.hxx in Headers */, + F8DB1F1A0C56CE9800853E27 /* NonceHelper.hxx in Headers */, + F8DB1D670C56B9B800853E27 /* NonDialogUsage.hxx in Headers */, + F8DB1F1B0C56CE9800853E27 /* OctetContents.hxx in Headers */, + F8DB1DDF0C56CE1500853E27 /* OpenSSLInit.hxx in Headers */, + F8DB1D680C56B9B800853E27 /* OutgoingEvent.hxx in Headers */, + F8DB1D690C56B9B800853E27 /* OutOfDialogHandler.hxx in Headers */, + F8DB1D6A0C56B9B800853E27 /* OutOfDialogReqCreator.hxx in Headers */, + F8DB1D6B0C56B9B800853E27 /* PagerMessageCreator.hxx in Headers */, + F8DB1D6C0C56B9B800853E27 /* PagerMessageHandler.hxx in Headers */, + F8DB1F1C0C56CE9800853E27 /* Parameter.hxx in Headers */, + F8DB1F1D0C56CE9800853E27 /* ParameterHash.hxx in Headers */, + F8DB1F1E0C56CE9800853E27 /* ParameterTypeEnums.hxx in Headers */, + F8DB1F1F0C56CE9800853E27 /* ParameterTypes.hxx in Headers */, + F8DB1DE00C56CE1500853E27 /* ParseBuffer.hxx in Headers */, + F8C76CA21243CCFF0076CFF8 /* ParseException.hxx in Headers */, + F8DB1F210C56CE9800853E27 /* ParserCategories.hxx in Headers */, + F8DB1F220C56CE9800853E27 /* ParserCategory.hxx in Headers */, + F8DB1F230C56CE9800853E27 /* ParserContainer.hxx in Headers */, + F8DB1F240C56CE9800853E27 /* ParserContainerBase.hxx in Headers */, + F8DB1F260C56CE9800853E27 /* Pidf.hxx in Headers */, + F8DB1F270C56CE9800853E27 /* Pkcs7Contents.hxx in Headers */, + F8DB1F290C56CE9800853E27 /* Pkcs8Contents.hxx in Headers */, + F8DB1F2A0C56CE9800853E27 /* PlainContents.hxx in Headers */, + F8DB1DE20C56CE1500853E27 /* Poll.hxx in Headers */, + F8DB1D6D0C56B9B800853E27 /* Postable.hxx in Headers */, + F8A057E2124D52BA00112774 /* PrivacyCategory.hxx in Headers */, + F8DB1D6E0C56B9B800853E27 /* Profile.hxx in Headers */, + F8DB1D6F0C56B9B800853E27 /* PublicationCreator.hxx in Headers */, + F8DB1D700C56B9B800853E27 /* PublicationHandler.hxx in Headers */, + F8DB1E160C56CE3C00853E27 /* QueryTypes.hxx in Headers */, + F8DB1F2C0C56CE9800853E27 /* QuotedDataParameter.hxx in Headers */, + F8DB1F2E0C56CE9800853E27 /* QValue.hxx in Headers */, + F8DB1F300C56CE9800853E27 /* QValueParameter.hxx in Headers */, + F8DB1F310C56CE9800853E27 /* RAckCategory.hxx in Headers */, + F8C76CA41243CCFF0076CFF8 /* RADIUSDigestAuthenticator.hxx in Headers */, + F8A057F7124D52DE00112774 /* RADIUSServerAuthManager.hxx in Headers */, + F8DB1DE30C56CE1500853E27 /* Random.hxx in Headers */, + F8DB1DE40C56CE1500853E27 /* RecursiveMutex.hxx in Headers */, + F8DB1D710C56B9B800853E27 /* RedirectHandler.hxx in Headers */, + F8DB1D720C56B9B800853E27 /* RedirectManager.hxx in Headers */, + F8DB1D730C56B9B800853E27 /* RefCountedDestroyer.hxx in Headers */, + F8DB1D740C56B9B800853E27 /* RegistrationCreator.hxx in Headers */, + F8DB1D750C56B9B800853E27 /* RegistrationHandler.hxx in Headers */, + F8DB1D760C56B9B800853E27 /* RegistrationPersistenceManager.hxx in Headers */, + F8DB1D770C56B9B800853E27 /* RemoteCertStore.hxx in Headers */, + F8DB1F320C56CE9800853E27 /* RequestLine.hxx in Headers */, + F8F4ED7F133D365D0000D69D /* RequestValidationHandler.hxx in Headers */, + F8C76CA61243CCFF0076CFF8 /* resipfaststreams.hxx in Headers */, + F8DB1F340C56CE9800853E27 /* Rlmi.hxx in Headers */, + F8DB1F350C56CE9800853E27 /* RportParameter.hxx in Headers */, + F8DB1E170C56CE3C00853E27 /* RRCache.hxx in Headers */, + F8DB1E180C56CE3C00853E27 /* RRFactory.hxx in Headers */, + F8DB1E190C56CE3C00853E27 /* RRList.hxx in Headers */, + F8DB1E1A0C56CE3C00853E27 /* RROverlay.hxx in Headers */, + F8DB1E1B0C56CE3C00853E27 /* RRVip.hxx in Headers */, + F8DB1DE50C56CE1500853E27 /* RWMutex.hxx in Headers */, + F8DB1F360C56CE9800853E27 /* SdpContents.hxx in Headers */, + F8DB1F370C56CE9800853E27 /* Security.hxx in Headers */, + F8DB1F380C56CE9800853E27 /* SecurityAttributes.hxx in Headers */, + F8DB1F390C56CE9800853E27 /* SecurityTypes.hxx in Headers */, + F8DB1F3B0C56CE9800853E27 /* SelectInterruptor.hxx in Headers */, + F8DB1F3C0C56CE9800853E27 /* SendData.hxx in Headers */, + F8DB1F3E0C56CE9800853E27 /* SERNonceHelper.hxx in Headers */, + F8DB1D780C56B9B800853E27 /* ServerAuthManager.hxx in Headers */, + F8DB1D790C56B9B800853E27 /* ServerInviteSession.hxx in Headers */, + F8DB1D7A0C56B9B800853E27 /* ServerOutOfDialogReq.hxx in Headers */, + F8DB1D7B0C56B9B800853E27 /* ServerPagerMessage.hxx in Headers */, + F8DB1D7C0C56B9B800853E27 /* ServerPublication.hxx in Headers */, + F8DB1D7D0C56B9B800853E27 /* ServerRegistration.hxx in Headers */, + F8DB1D7E0C56B9B800853E27 /* ServerSubscription.hxx in Headers */, + F8DB1D7F0C56B9B800853E27 /* ServerSubscriptionFunctor.hxx in Headers */, + F8DB1DE60C56CE1500853E27 /* SHA1Stream.hxx in Headers */, + F8DB1DE70C56CE1500853E27 /* SharedCount.hxx in Headers */, + F8DB1DE80C56CE1500853E27 /* SharedPtr.hxx in Headers */, + F8DB1F3F0C56CE9800853E27 /* ShutdownMessage.hxx in Headers */, + F8DB1F400C56CE9800853E27 /* SipFrag.hxx in Headers */, + F8DB1F410C56CE9800853E27 /* SipMessage.hxx in Headers */, + F8DB1F420C56CE9800853E27 /* SipStack.hxx in Headers */, + F8DB1DE90C56CE1500853E27 /* Socket.hxx in Headers */, + F8DB1F430C56CE9800853E27 /* StackThread.hxx in Headers */, + F8DB1F440C56CE9800853E27 /* StatelessHandler.hxx in Headers */, + F8DB1F460C56CE9800853E27 /* StatisticsHandler.hxx in Headers */, + F8DB1F470C56CE9800853E27 /* StatisticsManager.hxx in Headers */, + F8DB1F480C56CE9800853E27 /* StatisticsMessage.hxx in Headers */, + F8DB1F490C56CE9800853E27 /* StatusLine.hxx in Headers */, + F8DB1F4A0C56CE9800853E27 /* StringCategory.hxx in Headers */, + F8DB1F7E0C56CEEC00853E27 /* Stun.hxx in Headers */, + F8DB1D800C56B9B800853E27 /* SubscriptionCreator.hxx in Headers */, + F8DB1D810C56B9B800853E27 /* SubscriptionHandler.hxx in Headers */, + F8DB1D820C56B9B800853E27 /* SubscriptionPersistenceManager.hxx in Headers */, + F8DB1D830C56B9B800853E27 /* SubscriptionState.hxx in Headers */, + F8DB1DEA0C56CE1500853E27 /* Subsystem.hxx in Headers */, + F8DB1F4B0C56CE9800853E27 /* Symbols.hxx in Headers */, + F8DB1DEB0C56CE1500853E27 /* SysLogBuf.hxx in Headers */, + F8DB1DEC0C56CE1500853E27 /* SysLogStream.hxx in Headers */, + F8DB1D840C56B9B800853E27 /* TargetCommand.hxx in Headers */, + F8DB1F4C0C56CE9800853E27 /* TcpBaseTransport.hxx in Headers */, + F8DB1F4D0C56CE9800853E27 /* TcpConnection.hxx in Headers */, + F8DB1F4E0C56CE9800853E27 /* TcpTransport.hxx in Headers */, + F8F4ED7B133D36380000D69D /* TerminateFlow.hxx in Headers */, + F8DB1DED0C56CE1500853E27 /* ThreadIf.hxx in Headers */, + F8C76CA81243CCFF0076CFF8 /* Time.hxx in Headers */, + F8DB1F500C56CE9800853E27 /* TimeAccumulate.hxx in Headers */, + F8DB1DEE0C56CE1500853E27 /* TimeLimitFifo.hxx in Headers */, + F8DB1DEF0C56CE1500853E27 /* Timer.hxx in Headers */, + F8DB1F510C56CE9800853E27 /* TimerMessage.hxx in Headers */, + F8DB1F520C56CE9800853E27 /* TimerQueue.hxx in Headers */, + F8DB1F530C56CE9800853E27 /* TlsConnection.hxx in Headers */, + F8DB1F540C56CE9800853E27 /* TlsTransport.hxx in Headers */, + F8DB1F550C56CE9800853E27 /* Token.hxx in Headers */, + F8DB1F560C56CE9800853E27 /* TransactionController.hxx in Headers */, + F8DB1F570C56CE9800853E27 /* TransactionMap.hxx in Headers */, + F8DB1F580C56CE9800853E27 /* TransactionMessage.hxx in Headers */, + F8DB1F590C56CE9800853E27 /* TransactionState.hxx in Headers */, + F8DB1F5A0C56CE9800853E27 /* TransactionTerminated.hxx in Headers */, + F8DB1F5B0C56CE9800853E27 /* TransactionUser.hxx in Headers */, + F8DB1F5C0C56CE9800853E27 /* TransactionUserMessage.hxx in Headers */, + F8DB1F5D0C56CE9800853E27 /* Transport.hxx in Headers */, + F8DB1F5E0C56CE9800853E27 /* TransportFailure.hxx in Headers */, + F8DB1F5F0C56CE9800853E27 /* TransportSelector.hxx in Headers */, + F8DB1DF10C56CE1500853E27 /* TransportType.hxx in Headers */, + F8DB1F610C56CE9800853E27 /* TuIM.hxx in Headers */, + F8DB1F620C56CE9800853E27 /* Tuple.hxx in Headers */, + F8DB1F640C56CE9800853E27 /* TupleMarkManager.hxx in Headers */, + F8DB1F650C56CE9800853E27 /* TuSelector.hxx in Headers */, + F8DB1F800C56CEEC00853E27 /* Udp.hxx in Headers */, + F8DB1F660C56CE9800853E27 /* UdpTransport.hxx in Headers */, + F8DB1F680C56CE9800853E27 /* UInt32Category.hxx in Headers */, + F8DB1F6A0C56CE9800853E27 /* UInt32Parameter.hxx in Headers */, + F8DB1F6B0C56CE9800853E27 /* UnknownHeaderType.hxx in Headers */, + F8DB1F6C0C56CE9800853E27 /* UnknownParameter.hxx in Headers */, + F8DB1F6D0C56CE9800853E27 /* UnknownParameterType.hxx in Headers */, + F8DB1F6E0C56CE9800853E27 /* Uri.hxx in Headers */, + F8DB1D850C56B9B800853E27 /* UsageUseException.hxx in Headers */, + F8DB1D860C56B9B800853E27 /* UserAuthInfo.hxx in Headers */, + F8DB1D870C56B9B800853E27 /* UserProfile.hxx in Headers */, + F8DB1F6F0C56CE9800853E27 /* ValueFifo.hxx in Headers */, + F8DB1F700C56CE9800853E27 /* Via.hxx in Headers */, + F8DB1DF20C56CE1500853E27 /* vmd5.hxx in Headers */, + F8DB1DF30C56CE1500853E27 /* vthread.hxx in Headers */, + F8DB1F710C56CE9800853E27 /* WarningCategory.hxx in Headers */, + F8DB1F750C56CE9800853E27 /* X509Contents.hxx in Headers */, + F8DB1F770C56CE9800853E27 /* XMLCursor.hxx in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2AAC06B0554671400DB518D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + F8DB1D8E0C56B9EA00853E27 /* ares_compat.h in Headers */, + F8DB1D8F0C56B9EA00853E27 /* ares_dns.h in Headers */, + F8DB1D900C56B9EA00853E27 /* ares_local.h in Headers */, + F8DB1D910C56B9EA00853E27 /* ares_private.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 12F7972F086CBA1E00AF4EDF /* resiprocate */ = { + isa = PBXNativeTarget; + buildConfigurationList = 12F79734086CBA1E00AF4EDF /* Build configuration list for PBXNativeTarget "resiprocate" */; + buildPhases = ( + 12F79730086CBA1E00AF4EDF /* Headers */, + 12F79731086CBA1E00AF4EDF /* Sources */, + 12F79732086CBA1E00AF4EDF /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + F8DB1C990C56B82F00853E27 /* PBXTargetDependency */, + ); + name = resiprocate; + productName = sip; + productReference = 12F79738086CBA1E00AF4EDF /* libresiprocate.a */; + productType = "com.apple.product-type.library.static"; + }; + D2AAC06E0554671400DB518D /* ares */ = { + isa = PBXNativeTarget; + buildConfigurationList = 12F7971B086CB6D700AF4EDF /* Build configuration list for PBXNativeTarget "ares" */; + buildPhases = ( + D2AAC06B0554671400DB518D /* Headers */, + D2AAC06C0554671400DB518D /* Sources */, + D2AAC06D0554671400DB518D /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ares; + productName = sip; + productReference = D2AAC06F0554671400DB518D /* libares.a */; + productType = "com.apple.product-type.library.static"; + }; + F8DB1C860C56B7D800853E27 /* SipDialer */ = { + isa = PBXNativeTarget; + buildConfigurationList = F8DB1C8A0C56B7E200853E27 /* Build configuration list for PBXNativeTarget "SipDialer" */; + buildPhases = ( + F8DB1C840C56B7D800853E27 /* Sources */, + F8DB1C850C56B7D800853E27 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + F8DB1C970C56B82600853E27 /* PBXTargetDependency */, + ); + name = SipDialer; + productName = SipDialer; + productReference = F8DB1C870C56B7D800853E27 /* SipDialer */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 12F7971F086CB6D700AF4EDF /* Build configuration list for PBXProject "sip" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 0867D691FE84028FC02AAC07 /* sip */; + productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D2AAC06E0554671400DB518D /* ares */, + 12F7972F086CBA1E00AF4EDF /* resiprocate */, + F8DB1C860C56B7D800853E27 /* SipDialer */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 12F79731086CBA1E00AF4EDF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 124D7A44086CC69300BCA5A9 /* AbstractFifo.cxx in Sources */, + F8DB1ECC0C56CE9800853E27 /* Aor.cxx in Sources */, + 124D792A086CC3CE00BCA5A9 /* ApiCheck.cxx in Sources */, + 124D79F3086CC68200BCA5A9 /* AppDialog.cxx in Sources */, + 124D79F4086CC68200BCA5A9 /* AppDialogSet.cxx in Sources */, + 124D79F5086CC68200BCA5A9 /* AppDialogSetFactory.cxx in Sources */, + F8DB1ED10C56CE9800853E27 /* ApplicationSip.cxx in Sources */, + 124D792B086CC3CE00BCA5A9 /* AresDns.cxx in Sources */, + 124D792C086CC3CE00BCA5A9 /* Auth.cxx in Sources */, + 124D79F6086CC68200BCA5A9 /* BaseCreator.cxx in Sources */, + 124D7A45086CC69300BCA5A9 /* BaseException.cxx in Sources */, + 124D79F7086CC68200BCA5A9 /* BaseSubscription.cxx in Sources */, + 124D79F8086CC68200BCA5A9 /* BaseUsage.cxx in Sources */, + F8DB1ED50C56CE9800853E27 /* BasicNonceHelper.cxx in Sources */, + 124D792D086CC3CE00BCA5A9 /* BranchParameter.cxx in Sources */, + 124D792E086CC3CE00BCA5A9 /* CallId.cxx in Sources */, + 12BF59580895D7B800F7DD81 /* CertMessage.cxx in Sources */, + F8DB1D280C56B9B800853E27 /* ChallengeInfo.cxx in Sources */, + F8A057EE124D52DE00112774 /* ClientAuthExtension.cxx in Sources */, + 124D79F9086CC68200BCA5A9 /* ClientAuthManager.cxx in Sources */, + 124D79FA086CC68200BCA5A9 /* ClientInviteSession.cxx in Sources */, + 124D79FB086CC68200BCA5A9 /* ClientOutOfDialogReq.cxx in Sources */, + 124D79FC086CC68200BCA5A9 /* ClientPagerMessage.cxx in Sources */, + 124D79FD086CC68200BCA5A9 /* ClientPublication.cxx in Sources */, + 124D79FE086CC68200BCA5A9 /* ClientRegistration.cxx in Sources */, + 124D79FF086CC68200BCA5A9 /* ClientSubscription.cxx in Sources */, + 124D7A46086CC69300BCA5A9 /* Coders.cxx in Sources */, + F8DB1EDA0C56CE9800853E27 /* Compression.cxx in Sources */, + 124D7A47086CC69300BCA5A9 /* Condition.cxx in Sources */, + 124D792F086CC3CE00BCA5A9 /* Connection.cxx in Sources */, + 124D7930086CC3CE00BCA5A9 /* ConnectionBase.cxx in Sources */, + 124D7931086CC3CE00BCA5A9 /* ConnectionManager.cxx in Sources */, + F8DB1D320C56B9B800853E27 /* ContactInstanceRecord.cxx in Sources */, + 124D7932086CC3CE00BCA5A9 /* Contents.cxx in Sources */, + 12BF59370895D5BA00F7DD81 /* ContentsFactoryBase.cxx in Sources */, + 124D7A48086CC69300BCA5A9 /* CountStream.cxx in Sources */, + 124D7933086CC3CE00BCA5A9 /* CpimContents.cxx in Sources */, + 124D7934086CC3CE00BCA5A9 /* CSeqCategory.cxx in Sources */, + 124D7A49086CC69300BCA5A9 /* Data.cxx in Sources */, + 124D7935086CC3CE00BCA5A9 /* DataParameter.cxx in Sources */, + 124D7A4A086CC69300BCA5A9 /* DataStream.cxx in Sources */, + 124D7936086CC3CE00BCA5A9 /* DateCategory.cxx in Sources */, + 124D7A00086CC68200BCA5A9 /* DefaultServerReferHandler.cxx in Sources */, + F8DB1EE70C56CE9800853E27 /* DeprecatedDialog.cxx in Sources */, + 124D7A01086CC68200BCA5A9 /* DestroyUsage.cxx in Sources */, + 124D7A02086CC68200BCA5A9 /* Dialog.cxx in Sources */, + F8A057F0124D52DE00112774 /* DialogEventInfo.cxx in Sources */, + F8A057F2124D52DE00112774 /* DialogEventStateManager.cxx in Sources */, + 124D7A03086CC68200BCA5A9 /* DialogId.cxx in Sources */, + 124D7A04086CC68200BCA5A9 /* DialogSet.cxx in Sources */, + 124D7A05086CC68200BCA5A9 /* DialogSetId.cxx in Sources */, + 124D7A06086CC68200BCA5A9 /* DialogUsage.cxx in Sources */, + 124D7A07086CC68200BCA5A9 /* DialogUsageManager.cxx in Sources */, + F8C76C9F1243CCFF0076CFF8 /* DigestStream.cxx in Sources */, + 124D79B2086CC67000BCA5A9 /* DnsAAAARecord.cxx in Sources */, + 124D79B3086CC67000BCA5A9 /* DnsCnameRecord.cxx in Sources */, + 124D79B4086CC67000BCA5A9 /* DnsHostRecord.cxx in Sources */, + 124D7937086CC3CE00BCA5A9 /* DnsInterface.cxx in Sources */, + 124D79B5086CC67000BCA5A9 /* DnsNaptrRecord.cxx in Sources */, + F8DB1E0E0C56CE3C00853E27 /* DnsResourceRecord.cxx in Sources */, + 124D7938086CC3CE00BCA5A9 /* DnsResult.cxx in Sources */, + 124D79B6086CC67000BCA5A9 /* DnsSrvRecord.cxx in Sources */, + 124D79B7086CC67000BCA5A9 /* DnsStub.cxx in Sources */, + 124D7A4B086CC69300BCA5A9 /* DnsUtil.cxx in Sources */, + F8DB1EEB0C56CE9800853E27 /* DtlsMessage.cxx in Sources */, + F8DB1EED0C56CE9800853E27 /* DtlsTransport.cxx in Sources */, + 12BF593C0895D5FF00F7DD81 /* DumDecrypted.cxx in Sources */, + 12396E3708A2F3C800C5ED5E /* DumFeature.cxx in Sources */, + 123B4D4F089871C90049A5B9 /* DumFeatureChain.cxx in Sources */, + 123B4D570898721D0049A5B9 /* DumFeatureMessage.cxx in Sources */, + F8DB1D440C56B9B800853E27 /* DumHelper.cxx in Sources */, + 124D7A08086CC68200BCA5A9 /* DumProcessHandler.cxx in Sources */, + F8DB1D480C56B9B800853E27 /* DumThread.cxx in Sources */, + 124D7A09086CC68200BCA5A9 /* DumTimeout.cxx in Sources */, + 124D7939086CC3CE00BCA5A9 /* Embedded.cxx in Sources */, + 12BF59390895D5E600F7DD81 /* EncryptionManager.cxx in Sources */, + 123B4D55089872040049A5B9 /* EncryptionRequest.cxx in Sources */, + F8F4ED78133D36380000D69D /* EventStackThread.cxx in Sources */, + F8A057DD124D52BA00112774 /* ExistsOrDataParameter.cxx in Sources */, + 124D793A086CC3CE00BCA5A9 /* ExistsParameter.cxx in Sources */, + 124D793B086CC3CE00BCA5A9 /* ExpiresCategory.cxx in Sources */, + 124EC47D08721CFF0017C8BB /* ExtensionHeader.cxx in Sources */, + 124EC47E08721CFF0017C8BB /* ExtensionParameter.cxx in Sources */, + 124D793C086CC3CE00BCA5A9 /* ExternalBodyContents.cxx in Sources */, + 124D793D086CC3CE00BCA5A9 /* ExternalDnsFactory.cxx in Sources */, + F80A8D4A12B2CA66002D37E0 /* FdPoll.cxx in Sources */, + 124D7A4C086CC69300BCA5A9 /* FileSystem.cxx in Sources */, + 124D793E086CC3CE00BCA5A9 /* FloatParameter.cxx in Sources */, + 124D793F086CC3CE00BCA5A9 /* GenericContents.cxx in Sources */, + 124D7940086CC3CE00BCA5A9 /* GenericUri.cxx in Sources */, + F8DB1D510C56B9B800853E27 /* Handle.cxx in Sources */, + 124D7A0A086CC68200BCA5A9 /* Handled.cxx in Sources */, + 124D7A0B086CC68200BCA5A9 /* HandleException.cxx in Sources */, + 124D7A0C086CC68200BCA5A9 /* HandleManager.cxx in Sources */, + 124D7941086CC3CE00BCA5A9 /* HeaderFieldValue.cxx in Sources */, + 124D7942086CC3CE00BCA5A9 /* HeaderFieldValueList.cxx in Sources */, + 124D7943086CC3CE00BCA5A9 /* HeaderHash.cxx in Sources */, + 124D7944086CC3CE00BCA5A9 /* Headers.cxx in Sources */, + 124D7945086CC3CE00BCA5A9 /* HeaderTypes.cxx in Sources */, + F8DB1DD40C56CE1500853E27 /* HeapInstanceCounter.cxx in Sources */, + 124D7946086CC3CE00BCA5A9 /* Helper.cxx in Sources */, + 124D7A61086CC77900BCA5A9 /* HttpGetMessage.cxx in Sources */, + 124D7A62086CC77900BCA5A9 /* HttpProvider.cxx in Sources */, + 123B4D53089871F70049A5B9 /* IdentityHandler.cxx in Sources */, + F8DB1D5A0C56B9B800853E27 /* InMemoryRegistrationDatabase.cxx in Sources */, + F8A057F4124D52DE00112774 /* InMemorySyncRegDb.cxx in Sources */, + 124D7947086CC3CE00BCA5A9 /* IntegerCategory.cxx in Sources */, + 124D7948086CC3CE00BCA5A9 /* IntegerParameter.cxx in Sources */, + 124D7949086CC3CE00BCA5A9 /* InternalTransport.cxx in Sources */, + F8A057DF124D52BA00112774 /* InteropHelper.cxx in Sources */, + F8DB1F030C56CE9800853E27 /* InterruptableStackThread.cxx in Sources */, + F8DB1F050C56CE9800853E27 /* InvalidContents.cxx in Sources */, + 124D7A0D086CC68200BCA5A9 /* InviteSession.cxx in Sources */, + 124D7A0E086CC68200BCA5A9 /* InviteSessionCreator.cxx in Sources */, + 124D7A0F086CC68200BCA5A9 /* InviteSessionHandler.cxx in Sources */, + 124D7A11086CC68200BCA5A9 /* KeepAliveManager.cxx in Sources */, + 124D794A086CC3CE00BCA5A9 /* KeepAliveMessage.cxx in Sources */, + 124D7A12086CC68200BCA5A9 /* KeepAliveTimeout.cxx in Sources */, + 124D794B086CC3CE00BCA5A9 /* LazyParser.cxx in Sources */, + F8DB1E140C56CE3C00853E27 /* LocalDns.cxx in Sources */, + 124D7A4D086CC69300BCA5A9 /* Lock.cxx in Sources */, + 124D7A4E086CC69300BCA5A9 /* Log.cxx in Sources */, + 124D794C086CC3CE00BCA5A9 /* MacSecurity.cxx in Sources */, + F8DB1F0A0C56CE9800853E27 /* makeCert.cxx in Sources */, + 124D7A13086CC68200BCA5A9 /* MasterProfile.cxx in Sources */, + 124D7A50086CC69300BCA5A9 /* MD5Stream.cxx in Sources */, + 124D7A10086CC68200BCA5A9 /* MergedRequestKey.cxx in Sources */, + F8DB1D640C56B9B800853E27 /* MergedRequestRemovalCommand.cxx in Sources */, + 124D794D086CC3CE00BCA5A9 /* Message.cxx in Sources */, + 124D794E086CC3CE00BCA5A9 /* MessageFilterRule.cxx in Sources */, + 124D794F086CC3CE00BCA5A9 /* MessageWaitingContents.cxx in Sources */, + 124D7950086CC3CE00BCA5A9 /* MethodHash.cxx in Sources */, + 124D7951086CC3CE00BCA5A9 /* MethodTypes.cxx in Sources */, + 124D7952086CC3CE00BCA5A9 /* Mime.cxx in Sources */, + 124D7953086CC3CE00BCA5A9 /* MsgHeaderScanner.cxx in Sources */, + 124D7954086CC3CE00BCA5A9 /* MultipartAlternativeContents.cxx in Sources */, + 124D7955086CC3CE00BCA5A9 /* MultipartMixedContents.cxx in Sources */, + 124D7956086CC3CE00BCA5A9 /* MultipartRelatedContents.cxx in Sources */, + 124D7957086CC3CE00BCA5A9 /* MultipartSignedContents.cxx in Sources */, + 124D7A51086CC69300BCA5A9 /* Mutex.cxx in Sources */, + 124D7958086CC3CE00BCA5A9 /* NameAddr.cxx in Sources */, + 124D7A14086CC68200BCA5A9 /* NetworkAssociation.cxx in Sources */, + F8DB1F190C56CE9800853E27 /* NonceHelper.cxx in Sources */, + 124D7A15086CC68200BCA5A9 /* NonDialogUsage.cxx in Sources */, + 124D7959086CC3CE00BCA5A9 /* OctetContents.cxx in Sources */, + F8C76CAB1243CD2B0076CFF8 /* OpenSSLInit.cxx in Sources */, + 12396E6A08A2F91E00C5ED5E /* OutgoingEvent.cxx in Sources */, + 124D7A16086CC68200BCA5A9 /* OutOfDialogReqCreator.cxx in Sources */, + 124D7A17086CC68200BCA5A9 /* PagerMessageCreator.cxx in Sources */, + 124D795A086CC3CE00BCA5A9 /* Parameter.cxx in Sources */, + 124D795B086CC3CE00BCA5A9 /* ParameterHash.cxx in Sources */, + 124D795C086CC3CE00BCA5A9 /* ParameterTypes.cxx in Sources */, + 124D7A52086CC69300BCA5A9 /* ParseBuffer.cxx in Sources */, + F8C76CA11243CCFF0076CFF8 /* ParseException.cxx in Sources */, + 124D795D086CC3CE00BCA5A9 /* ParserCategories.cxx in Sources */, + 124D795E086CC3CE00BCA5A9 /* ParserCategory.cxx in Sources */, + 12BF59350895D59E00F7DD81 /* ParserContainerBase.cxx in Sources */, + F8DB1F250C56CE9800853E27 /* Pidf.cxx in Sources */, + 124D7960086CC3CE00BCA5A9 /* Pkcs7Contents.cxx in Sources */, + F8DB1F280C56CE9800853E27 /* Pkcs8Contents.cxx in Sources */, + 124D7961086CC3CE00BCA5A9 /* PlainContents.cxx in Sources */, + F8DB1DE10C56CE1500853E27 /* Poll.cxx in Sources */, + F8A057E1124D52BA00112774 /* PrivacyCategory.cxx in Sources */, + 124D7A18086CC68200BCA5A9 /* Profile.cxx in Sources */, + 124D7A19086CC68200BCA5A9 /* PublicationCreator.cxx in Sources */, + 124D79B8086CC67000BCA5A9 /* QueryTypes.cxx in Sources */, + 124D7963086CC3CE00BCA5A9 /* QuotedDataParameter.cxx in Sources */, + F8DB1F2D0C56CE9800853E27 /* QValue.cxx in Sources */, + F8DB1F2F0C56CE9800853E27 /* QValueParameter.cxx in Sources */, + 124D7964086CC3CE00BCA5A9 /* RAckCategory.cxx in Sources */, + F8C76CA31243CCFF0076CFF8 /* RADIUSDigestAuthenticator.cxx in Sources */, + F8A057F6124D52DE00112774 /* RADIUSServerAuthManager.cxx in Sources */, + 124D7A53086CC69300BCA5A9 /* Random.cxx in Sources */, + 124D7A54086CC69300BCA5A9 /* RecursiveMutex.cxx in Sources */, + 124D7A1A086CC68200BCA5A9 /* RedirectManager.cxx in Sources */, + 124D7A1B086CC68200BCA5A9 /* RegistrationCreator.cxx in Sources */, + F8A057F8124D52DE00112774 /* RegistrationHandler.cxx in Sources */, + 124D7966086CC3CE00BCA5A9 /* RequestLine.cxx in Sources */, + F8C76CA51243CCFF0076CFF8 /* resipfaststreams.cxx in Sources */, + F8DB1F330C56CE9800853E27 /* Rlmi.cxx in Sources */, + 124D7967086CC3CE00BCA5A9 /* RportParameter.cxx in Sources */, + 124D79B9086CC67000BCA5A9 /* RRCache.cxx in Sources */, + 124D79BA086CC67000BCA5A9 /* RRList.cxx in Sources */, + 124D79BB086CC67000BCA5A9 /* RROverlay.cxx in Sources */, + 124D79BC086CC67000BCA5A9 /* RRVip.cxx in Sources */, + 124D7A55086CC69300BCA5A9 /* RWMutex.cxx in Sources */, + 124D7968086CC3CE00BCA5A9 /* SdpContents.cxx in Sources */, + 124D7969086CC3CE00BCA5A9 /* Security.cxx in Sources */, + 124D796A086CC3CE00BCA5A9 /* SecurityAttributes.cxx in Sources */, + F8DB1F3A0C56CE9800853E27 /* SelectInterruptor.cxx in Sources */, + F8DB1F3D0C56CE9800853E27 /* SERNonceHelper.cxx in Sources */, + 124D7A1C086CC68200BCA5A9 /* ServerAuthManager.cxx in Sources */, + 124D7A1D086CC68200BCA5A9 /* ServerInviteSession.cxx in Sources */, + 124D7A1E086CC68200BCA5A9 /* ServerOutOfDialogReq.cxx in Sources */, + 124D7A1F086CC68200BCA5A9 /* ServerPagerMessage.cxx in Sources */, + 124D7A20086CC68200BCA5A9 /* ServerPublication.cxx in Sources */, + 124D7A21086CC68200BCA5A9 /* ServerRegistration.cxx in Sources */, + 124D7A22086CC68200BCA5A9 /* ServerSubscription.cxx in Sources */, + F8C76CAC1243CD2B0076CFF8 /* SHA1Stream.cxx in Sources */, + 124D796B086CC3CE00BCA5A9 /* SipFrag.cxx in Sources */, + 124D796C086CC3CE00BCA5A9 /* SipMessage.cxx in Sources */, + 124D796D086CC3CE00BCA5A9 /* SipStack.cxx in Sources */, + 124D7A57086CC69300BCA5A9 /* Socket.cxx in Sources */, + 124D796E086CC3CE00BCA5A9 /* StackThread.cxx in Sources */, + 124D796F086CC3CE00BCA5A9 /* StatelessHandler.cxx in Sources */, + F8DB1F450C56CE9800853E27 /* StatisticsHandler.cxx in Sources */, + 124D7970086CC3CE00BCA5A9 /* StatisticsManager.cxx in Sources */, + 124D7971086CC3CE00BCA5A9 /* StatisticsMessage.cxx in Sources */, + 124D7972086CC3CE00BCA5A9 /* StatusLine.cxx in Sources */, + 124D7973086CC3CE00BCA5A9 /* StringCategory.cxx in Sources */, + F8DB1F7D0C56CEEC00853E27 /* Stun.cxx in Sources */, + 124D7A23086CC68200BCA5A9 /* SubscriptionCreator.cxx in Sources */, + 124D7A24086CC68200BCA5A9 /* SubscriptionHandler.cxx in Sources */, + 124D7A25086CC68200BCA5A9 /* SubscriptionState.cxx in Sources */, + 124D7A58086CC69300BCA5A9 /* Subsystem.cxx in Sources */, + 124D7974086CC3CE00BCA5A9 /* Symbols.cxx in Sources */, + 124D7A59086CC69300BCA5A9 /* SysLogBuf.cxx in Sources */, + 124D7A5A086CC69300BCA5A9 /* SysLogStream.cxx in Sources */, + 12396E6C08A2F93400C5ED5E /* TargetCommand.cxx in Sources */, + 124D7975086CC3CE00BCA5A9 /* TcpBaseTransport.cxx in Sources */, + F8A057C7124D47D700112774 /* TcpConnection.cxx in Sources */, + 124D7977086CC3CE00BCA5A9 /* TcpTransport.cxx in Sources */, + 124D7A5B086CC69300BCA5A9 /* ThreadIf.cxx in Sources */, + F8C76CA71243CCFF0076CFF8 /* Time.cxx in Sources */, + F8DB1F4F0C56CE9800853E27 /* TimeAccumulate.cxx in Sources */, + 124D7A5C086CC69300BCA5A9 /* Timer.cxx in Sources */, + 124D7978086CC3CE00BCA5A9 /* TimerMessage.cxx in Sources */, + 124D7979086CC3CE00BCA5A9 /* TimerQueue.cxx in Sources */, + F8F4ED4D133D2F000000D69D /* TlsConnection.cxx in Sources */, + 124D797B086CC3CE00BCA5A9 /* TlsTransport.cxx in Sources */, + 124D797C086CC3CE00BCA5A9 /* Token.cxx in Sources */, + 124D797D086CC3CE00BCA5A9 /* TransactionController.cxx in Sources */, + 124D797E086CC3CE00BCA5A9 /* TransactionMap.cxx in Sources */, + 124D797F086CC3CE00BCA5A9 /* TransactionState.cxx in Sources */, + 124D7980086CC3CE00BCA5A9 /* TransactionUser.cxx in Sources */, + 124D7981086CC3CE00BCA5A9 /* TransactionUserMessage.cxx in Sources */, + 124D7982086CC3CE00BCA5A9 /* Transport.cxx in Sources */, + 124EC468087217600017C8BB /* TransportFailure.cxx in Sources */, + 124D7983086CC3CE00BCA5A9 /* TransportSelector.cxx in Sources */, + F8DB1DF00C56CE1500853E27 /* TransportType.cxx in Sources */, + F8DB1F600C56CE9800853E27 /* TuIM.cxx in Sources */, + 124D7A5D086CC69300BCA5A9 /* Tuple.cxx in Sources */, + F8DB1F630C56CE9800853E27 /* TupleMarkManager.cxx in Sources */, + 124D7984086CC3CE00BCA5A9 /* TuSelector.cxx in Sources */, + F8DB1F7F0C56CEEC00853E27 /* Udp.cxx in Sources */, + 124D7985086CC3CE00BCA5A9 /* UdpTransport.cxx in Sources */, + F8DB1F670C56CE9800853E27 /* UInt32Category.cxx in Sources */, + F8DB1F690C56CE9800853E27 /* UInt32Parameter.cxx in Sources */, + 124D7986086CC3CE00BCA5A9 /* UnknownParameter.cxx in Sources */, + 124D7987086CC3CE00BCA5A9 /* Uri.cxx in Sources */, + 124D7A27086CC68200BCA5A9 /* UserAuthInfo.cxx in Sources */, + 124D7A28086CC68200BCA5A9 /* UserProfile.cxx in Sources */, + 124D7988086CC3CE00BCA5A9 /* Via.cxx in Sources */, + 124D7A5E086CC69300BCA5A9 /* vmd5.cxx in Sources */, + 124D7989086CC3CE00BCA5A9 /* WarningCategory.cxx in Sources */, + F8DB1F740C56CE9800853E27 /* X509Contents.cxx in Sources */, + F8DB1F760C56CE9800853E27 /* XMLCursor.cxx in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2AAC06C0554671400DB518D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 124D78B2086CC36600BCA5A9 /* ares__close_sockets.c in Sources */, + 124D78B3086CC36600BCA5A9 /* ares__get_hostent.c in Sources */, + 124D78B4086CC36600BCA5A9 /* ares__read_line.c in Sources */, + 124D78B5086CC36600BCA5A9 /* ares_destroy.c in Sources */, + 124D78B6086CC36600BCA5A9 /* ares_expand_name.c in Sources */, + 124D78B7086CC36600BCA5A9 /* ares_fds.c in Sources */, + 124D78B8086CC36600BCA5A9 /* ares_free_errmem.c in Sources */, + 124D78B9086CC36600BCA5A9 /* ares_free_hostent.c in Sources */, + 124D78BA086CC36600BCA5A9 /* ares_free_string.c in Sources */, + 124D78BB086CC36600BCA5A9 /* ares_gethostbyaddr.c in Sources */, + 124D78BC086CC36600BCA5A9 /* ares_gethostbyname.c in Sources */, + 124D78BD086CC36600BCA5A9 /* ares_init.c in Sources */, + 124D78BE086CC36600BCA5A9 /* ares_local.c in Sources */, + 124D78BF086CC36600BCA5A9 /* ares_mkquery.c in Sources */, + 124D78C0086CC36600BCA5A9 /* ares_parse_a_reply.c in Sources */, + 124D78C1086CC36600BCA5A9 /* ares_parse_ptr_reply.c in Sources */, + 124D78C2086CC36600BCA5A9 /* ares_process.c in Sources */, + 124D78C3086CC36600BCA5A9 /* ares_query.c in Sources */, + 124D78C4086CC36600BCA5A9 /* ares_search.c in Sources */, + 124D78C5086CC36600BCA5A9 /* ares_send.c in Sources */, + 124D78C6086CC36600BCA5A9 /* ares_strerror.c in Sources */, + 124D78C7086CC36600BCA5A9 /* ares_timeout.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F8DB1C840C56B7D800853E27 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F8DB1C920C56B7FD00853E27 /* DialerConfiguration.cpp in Sources */, + F8DB1C930C56B7FD00853E27 /* DialInstance.cpp in Sources */, + F8DB1C940C56B7FD00853E27 /* MyInviteSessionHandler.cpp in Sources */, + F8DB1C950C56B7FD00853E27 /* sipdialer.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + F8DB1C970C56B82600853E27 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 12F7972F086CBA1E00AF4EDF /* resiprocate */; + targetProxy = F8DB1C960C56B82600853E27 /* PBXContainerItemProxy */; + }; + F8DB1C990C56B82F00853E27 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC06E0554671400DB518D /* ares */; + targetProxy = F8DB1C980C56B82F00853E27 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 12F7971C086CB6D700AF4EDF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_DYNAMIC_NO_PIC = NO; + INSTALL_PATH = /usr/local/lib; + PRODUCT_NAME = ares; + }; + name = Debug; + }; + 12F7971D086CB6D700AF4EDF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INSTALL_PATH = /usr/local/lib; + PRODUCT_NAME = ares; + }; + name = Release; + }; + 12F79720086CB6D700AF4EDF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + COPY_PHASE_STRIP = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "USE_IPV6=1", + "USE_ARES=1", + ); + MACOSX_DEPLOYMENT_TARGET = 10.5; + SDKROOT = macosx10.5; + USER_HEADER_SEARCH_PATHS = "../ ../contrib/ares"; + }; + name = Debug; + }; + 12F79721086CB6D700AF4EDF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_OPTIMIZATION_LEVEL = s; + GCC_PREPROCESSOR_DEFINITIONS = ( + "USE_IPV6=1", + "USE_ARES=1", + ); + MACOSX_DEPLOYMENT_TARGET = 10.5; + SDKROOT = macosx10.5; + USER_HEADER_SEARCH_PATHS = "../ ../contrib/ares"; + }; + name = Release; + }; + 12F79735086CBA1E00AF4EDF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXCLUDED_SOURCE_FILE_NAMES = TlsConnection.cxx; + PRODUCT_NAME = resiprocate; + }; + name = Debug; + }; + 12F79736086CBA1E00AF4EDF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXCLUDED_SOURCE_FILE_NAMES = TlsConnection.cxx; + PRODUCT_NAME = resiprocate; + }; + name = Release; + }; + F8DB1C8B0C56B7E200853E27 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = "$(HOME)/bin"; + PREBINDING = NO; + PRODUCT_NAME = SipDialer; + USER_HEADER_SEARCH_PATHS = "../ ../contrib/ares ../apps/sipdial/include/sipdial"; + ZERO_LINK = YES; + }; + name = Debug; + }; + F8DB1C8C0C56B7E200853E27 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + INSTALL_PATH = "$(HOME)/bin"; + PREBINDING = NO; + PRODUCT_NAME = SipDialer; + USER_HEADER_SEARCH_PATHS = "../ ../contrib/ares ../apps/sipdial/include/sipdial"; + ZERO_LINK = NO; + }; + name = Release; + }; + F8F4ED62133D351F0000D69D /* SSL-Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + COPY_PHASE_STRIP = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "USE_IPV6=1", + "USE_ARES=1", + "USE_SSL=1", + ); + MACOSX_DEPLOYMENT_TARGET = 10.5; + SDKROOT = macosx10.5; + USER_HEADER_SEARCH_PATHS = "../ ../contrib/ares"; + }; + name = "SSL-Debug"; + }; + F8F4ED63133D351F0000D69D /* SSL-Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_DYNAMIC_NO_PIC = NO; + INSTALL_PATH = /usr/local/lib; + PRODUCT_NAME = ares; + }; + name = "SSL-Debug"; + }; + F8F4ED64133D351F0000D69D /* SSL-Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = resiprocate; + }; + name = "SSL-Debug"; + }; + F8F4ED65133D351F0000D69D /* SSL-Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = "$(HOME)/bin"; + PREBINDING = NO; + PRODUCT_NAME = SipDialer; + USER_HEADER_SEARCH_PATHS = "../ ../contrib/ares ../apps/sipdial/include/sipdial"; + ZERO_LINK = YES; + }; + name = "SSL-Debug"; + }; + F8F4ED66133D35220000D69D /* SSL-Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_OPTIMIZATION_LEVEL = s; + GCC_PREPROCESSOR_DEFINITIONS = ( + "USE_IPV6=1", + "USE_ARES=1", + "USE_SSL=1", + ); + MACOSX_DEPLOYMENT_TARGET = 10.5; + SDKROOT = macosx10.5; + USER_HEADER_SEARCH_PATHS = "../ ../contrib/ares"; + }; + name = "SSL-Release"; + }; + F8F4ED67133D35220000D69D /* SSL-Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INSTALL_PATH = /usr/local/lib; + PRODUCT_NAME = ares; + }; + name = "SSL-Release"; + }; + F8F4ED68133D35220000D69D /* SSL-Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = resiprocate; + }; + name = "SSL-Release"; + }; + F8F4ED69133D35220000D69D /* SSL-Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + INSTALL_PATH = "$(HOME)/bin"; + PREBINDING = NO; + PRODUCT_NAME = SipDialer; + USER_HEADER_SEARCH_PATHS = "../ ../contrib/ares ../apps/sipdial/include/sipdial"; + ZERO_LINK = NO; + }; + name = "SSL-Release"; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 12F7971B086CB6D700AF4EDF /* Build configuration list for PBXNativeTarget "ares" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 12F7971C086CB6D700AF4EDF /* Debug */, + 12F7971D086CB6D700AF4EDF /* Release */, + F8F4ED63133D351F0000D69D /* SSL-Debug */, + F8F4ED67133D35220000D69D /* SSL-Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 12F7971F086CB6D700AF4EDF /* Build configuration list for PBXProject "sip" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 12F79720086CB6D700AF4EDF /* Debug */, + 12F79721086CB6D700AF4EDF /* Release */, + F8F4ED62133D351F0000D69D /* SSL-Debug */, + F8F4ED66133D35220000D69D /* SSL-Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 12F79734086CBA1E00AF4EDF /* Build configuration list for PBXNativeTarget "resiprocate" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 12F79735086CBA1E00AF4EDF /* Debug */, + 12F79736086CBA1E00AF4EDF /* Release */, + F8F4ED64133D351F0000D69D /* SSL-Debug */, + F8F4ED68133D35220000D69D /* SSL-Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F8DB1C8A0C56B7E200853E27 /* Build configuration list for PBXNativeTarget "SipDialer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F8DB1C8B0C56B7E200853E27 /* Debug */, + F8DB1C8C0C56B7E200853E27 /* Release */, + F8F4ED65133D351F0000D69D /* SSL-Debug */, + F8F4ED69133D35220000D69D /* SSL-Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/src/libs/resiprocate/resip/sip_MacPrefix.pch b/src/libs/resiprocate/resip/sip_MacPrefix.pch new file mode 100644 index 00000000..97c3122c --- /dev/null +++ b/src/libs/resiprocate/resip/sip_MacPrefix.pch @@ -0,0 +1,25 @@ +// +// Prefix header for all source files of the 'sip' target in the 'sip' project. +// + +// set up TARGET_OS_MAC +#include <TargetConditionals.h> + +// set up MAC_OS_X_VERSION_MIN_REQUIRED +#include <AvailabilityMacros.h> + +// defaults so that we don't have to use config.hxx +#define USE_ARES 1 +#define USE_IPV6 1 +#define USE_SSL 1 +#define VONAGE_FIX 1 + +// Darwin defines assert() to use printf, oddly enough +#include <stdio.h> + +// trying to get rid of tolower() link conflict +#include <ctype.h> + +// For some reason, if we don't have at least one framework then GCC +// starts having problem with having a C pch in a a C++ file. +#include <CoreFoundation/CoreFoundation.h> diff --git a/src/libs/resiprocate/resip/stack/.cvsignore b/src/libs/resiprocate/resip/stack/.cvsignore new file mode 100644 index 00000000..7e143910 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/.cvsignore @@ -0,0 +1,74 @@ +*-raw.cxx +*.d +*.la +*.lo +*~ +dox +.DS_Store +.dependlibs +.deps +.gdb_history +.libs +Debug +English.lproj +ExpandedSipMessage +JF +Makefile.in +Release +SSL-Debug +SSL-Release +UserAgentCore.hxx +a.out +backup +bak +bar +bin.* +build +config.hxx +dumpasn1 +enc64 +foo +foo2 +foo3 +foo4 +fooMsg +gmon.out +headers-hash.c +hotsip_stun1 +hotsip_stun2 +html +j2 +junk +log +log1 +log1.txt +log2 +log2.txt +log3.txt +memprof.sh +new-pp.tgz +obj.* +pp-safe.tgz +pp-todo +save +save2 +sipit14_ntt1 +sipit14_ntt2 +sipit14_ntt3 +sipit14_ntt4 +sipit14_ntt5 +sipit14_ntt6 +sipit14_radvision1 +sipit_ntt7 +stamp-h1 +testSipStack1 +testUdp +tmp +un64 +doxygen +*.stackdump +*.diff +*.tar +*.gz +TAGS +*.tmp diff --git a/src/libs/resiprocate/resip/stack/AbandonServerTransaction.hxx b/src/libs/resiprocate/resip/stack/AbandonServerTransaction.hxx new file mode 100644 index 00000000..f4d133ff --- /dev/null +++ b/src/libs/resiprocate/resip/stack/AbandonServerTransaction.hxx @@ -0,0 +1,46 @@ +#ifndef AbandonServerTransaction_Include_Guard +#define AbandonServerTransaction_Include_Guard + +#include "resip/stack/TransactionMessage.hxx" + +#include "rutil/Data.hxx" +#include "rutil/resipfaststreams.hxx" + +namespace resip +{ +class AbandonServerTransaction : public TransactionMessage +{ + public: + AbandonServerTransaction(const Data& tid) : + mTid(tid) + {} + virtual ~AbandonServerTransaction() {} + +/////////////////// Must implement unless abstract /// + + virtual const Data& getTransactionId() const {return mTid;} + virtual bool isClientTransaction() const {return false;} + virtual EncodeStream& encode(EncodeStream& strm) const + { + return strm << "AbandonServerTransaction: " << mTid; + } + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "AbandonServerTransaction: " << mTid; + } + +/////////////////// May override /// + + virtual Message* clone() const + { + return new AbandonServerTransaction(*this); + } + + protected: + const resip::Data mTid; + +}; // class AbandonServerTransaction + +} // namespace resip + +#endif // include guard diff --git a/src/libs/resiprocate/resip/stack/Aor.cxx b/src/libs/resiprocate/resip/stack/Aor.cxx new file mode 100644 index 00000000..01f350eb --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Aor.cxx @@ -0,0 +1,283 @@ +#include <iostream> + +#include "rutil/ParseBuffer.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/DnsUtil.hxx" +#include "resip/stack/Uri.hxx" +#include "resip/stack/Aor.hxx" + +using namespace resip; + +Aor::Aor() +{ +} + +Aor::Aor(const Data& value) +{ + ParseBuffer pb(value); + + pb.skipWhitespace(); + const char* start = pb.position(); + pb.skipToOneOf(":@"); // make sure the colon precedes + + pb.assertNotEof(); + + pb.data(mScheme, start); + pb.skipChar(Symbols::COLON[0]); + mScheme.lowercase(); + + if (isEqualNoCase(mScheme, Symbols::Tel)) + { + const char* anchor = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace, ";>"); + pb.data(mUser, anchor); + if (!pb.eof() && *pb.position() == Symbols::SEMI_COLON[0]) + { + anchor = pb.skipChar(); + pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::RA_QUOTE); + } + return; + } + + start = pb.position(); + pb.skipToChar(Symbols::AT_SIGN[0]); + if (!pb.eof()) + { + pb.reset(start); + start = pb.position(); + pb.skipToOneOf(":@"); + pb.data(mUser, start); + if (!pb.eof() && *pb.position() == Symbols::COLON[0]) + { + start = pb.skipChar(); + pb.skipToChar(Symbols::AT_SIGN[0]); + } + start = pb.skipChar(); + } + else + { + pb.reset(start); + } + + if (*start == '[') + { + start = pb.skipChar(); + pb.skipToChar(']'); + pb.data(mHost, start); + DnsUtil::canonicalizeIpV6Address(mHost); + pb.skipChar(); + } + else + { + pb.skipToOneOf(ParseBuffer::Whitespace, ":;?>"); + pb.data(mHost, start); + } + + pb.skipToOneOf(ParseBuffer::Whitespace, ":;?>"); + if (!pb.eof() && *pb.position() == ':') + { + start = pb.skipChar(); + mPort = pb.integer(); + pb.skipToOneOf(ParseBuffer::Whitespace, ";?>"); + } + else + { + mPort = 0; + } +} + +Aor::Aor(const Uri& uri) : + mScheme(uri.scheme()), + mUser(uri.user()), + mHost(uri.host()), + mPort(uri.port()) +{ + +} + +Aor::Aor(const Aor& aor) +{ + *this = aor; +} + +Aor& +Aor::operator=(const Aor& aor) +{ + if (this != &aor) + { + mScheme = aor.mScheme; + mUser = aor.mUser; + mHost = aor.mHost; + mPort = aor.mPort; + } + return *this; +} + + +bool +Aor::operator==(const Aor& other) const +{ + return value() == other.value(); +} + +bool +Aor::operator!=(const Aor& other) const +{ + return value() != other.value(); +} + +bool +Aor::operator<(const Aor& other) const +{ + return value() < other.value(); +} + +const Data& +Aor::value() const +{ + if (mOldScheme != mScheme || + mOldUser != mUser || + mOldHost != mHost || + mOldPort != mPort) + { + mOldHost = mHost; + if (DnsUtil::isIpV6Address(mHost)) + { + mCanonicalHost = DnsUtil::canonicalizeIpV6Address(mHost); + } + else + { + mCanonicalHost = mHost; + mCanonicalHost.lowercase(); + } + + mOldScheme = mScheme; + mOldUser = mUser; + mOldPort = mPort; + + mValue.reserve(mUser.size() + mCanonicalHost.size() + 10); + + DataStream strm(mValue); + strm << mScheme; + strm << Symbols::COLON; + strm << mUser; + if (!mCanonicalHost.empty()) + { + strm << Symbols::AT_SIGN; + strm << mCanonicalHost; + + if (mPort != 0) + { + strm << Symbols::COLON; + strm << Data(mPort); + } + } + } + + return mValue; +} + +Data& +Aor::scheme() +{ + return mScheme; +} + +const Data& +Aor::scheme() const +{ + return mScheme; +} + +Data& +Aor::host() +{ + return mHost; +} + +const Data& +Aor::host() const +{ + return mHost; +} + +Data& +Aor::user() +{ + return mUser; +} + +const Data& +Aor::user() const +{ + return mUser; +} + +int& +Aor::port() +{ + return mPort; +} + +int +Aor::port() const +{ + return mPort; +} + +EncodeStream& +Aor::operator<<(EncodeStream& str) const +{ + str << value(); + return str; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Aor.hxx b/src/libs/resiprocate/resip/stack/Aor.hxx new file mode 100644 index 00000000..1d990796 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Aor.hxx @@ -0,0 +1,110 @@ +#if !defined(RESIP_AOR_HXX) +#define RESIP_AOR_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" + +namespace resip +{ + +class Uri; + +class Aor +{ + public: + explicit Aor(const Data& value); + Aor(); + Aor(const Uri& uri); + Aor(const Aor& aor); + Aor& operator=(const Aor& aor); + + bool operator==(const Aor& other) const; + bool operator!=(const Aor& other) const; + bool operator<(const Aor& other) const; + + const Data& value() const; + + Data& scheme(); + const Data& scheme() const; + + Data& host(); + const Data& host() const; + + Data& user(); + const Data& user() const; + + int& port(); + int port() const; + + EncodeStream& operator<<(EncodeStream& str) const; + + private: + mutable Data mValue; + + mutable Data mOldScheme; + mutable Data mOldUser; + mutable Data mOldHost; + mutable int mOldPort; + + // cache for IPV6 host comparison + mutable Data mCanonicalHost; + + Data mScheme; + Data mUser; + Data mHost; + int mPort; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ApiCheck.cxx b/src/libs/resiprocate/resip/stack/ApiCheck.cxx new file mode 100644 index 00000000..f4d234e3 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ApiCheck.cxx @@ -0,0 +1,133 @@ +#include <stdlib.h> +#include <iostream> +#include <iomanip> + +#include "resip/stack/ApiCheck.hxx" +#include "resip/stack/ApiCheckList.hxx" + +namespace resip +{ + +ApiCheck::ApiCheck( ApiEntry * list, int len) +{ + int bad = 0; + + ApiEntry* p = list; + ApiEntry* q = ::anonymous_resipApiSizeList; + int resipListLen = sizeof(::anonymous_resipApiSizeList)/sizeof(*::anonymous_resipApiSizeList); + + if (list == ::anonymous_resipApiSizeList ) + { + return; + } + + if (resipListLen != len) + { + std::cerr << "reSIProcate Type verification list lengths are different." + << std::endl + << "\tEither the library and application are radically out of date" + << std::endl + << "application length: " << len << std::endl + << "reSIProcate length: " << resipListLen << std::endl; + ++bad; + } + + std::cerr << std::setfill(' ') + << std::setw(34) << "Class" << ' ' + << std::setw(8) << "App" << ' ' + << std::setw(8) << "Lib" << ' ' + << std::setw(8) << "Possible Culprit Flags" + << std::endl; + + for(int i = 0 ; i < resipListLen && i < len; ++i) + { + bool oops = false; + if (strcmp(p[i].name, q[i].name)) + { + std::cerr << "!!! Miss match entry for : (app)" + << p[i].name << " vs. (resip)" << q[i].name + << std::endl; + ++bad; + continue; + } + + if (p[i].sz != q[i].sz) + { + ++bad; + oops = true; + } + const char w = oops?'!':' '; + + std::cerr << w << w << w << std::setfill(' ') + << std::setw(30-strlen(p[i].name)) << "resip::" + << p[i].name << ' ' + << std::setw(8) << p[i].sz << ' ' + << std::setw(8) << q[i].sz << ' ' + << (oops?p[i].culprits:"") + << std::endl; + + + } + + if (bad) + { + std::cerr <<"SERIOUS COMPILATION / CONFIGURATION ERRORS -- ABORTING" << std::endl; +#ifndef UNDER_CE + abort(); +#endif + exit(bad); + } + std::cerr << std::endl; +} + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ApiCheck.hxx b/src/libs/resiprocate/resip/stack/ApiCheck.hxx new file mode 100644 index 00000000..a58dbfac --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ApiCheck.hxx @@ -0,0 +1,78 @@ + +// This is intentionally without a namespace. +// To use this intelligently, include it from within +// a reasonable namespace (resip::) in the stack and +// whatever your client namespace is if you want +// a list in your application. + + +#if !defined(RESIP_API_CHECK_HXX) +#define RESIP_API_CHECK_HXX +#if defined(WIN32) +#include <stddef.h> +#else +#include <unistd.h> +#endif +namespace resip +{ +class ApiCheck +{ + public: + typedef struct { const char * name; size_t sz; const char * culprits;} ApiEntry; + ApiCheck(ApiEntry * list, int len); +}; +}; + +#endif + +// end of ApiCheck + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ApiCheckList.hxx b/src/libs/resiprocate/resip/stack/ApiCheckList.hxx new file mode 100644 index 00000000..c9c3c268 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ApiCheckList.hxx @@ -0,0 +1,98 @@ +#if !defined(RESIP_APICHECKLIST_HXX) +#define RESIP_APICHECKLIST_HXX + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include "resip/stack/ApiCheck.hxx" + +// These types were chosen because they represent the exported stuff. + + +#include "rutil/GenericIPAddress.hxx" +#include "resip/stack/Connection.hxx" +#include "resip/stack/DnsResult.hxx" +#include "resip/stack/Headers.hxx" +#include "resip/stack/MsgHeaderScanner.hxx" +#include "resip/stack/Tuple.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/TransportSelector.hxx" +#include "resip/stack/UdpTransport.hxx" + +// Make an entry in the table +#define RESIP_TENT(x,y) { #x, sizeof(resip::x), y } + +static ::resip::ApiCheck::ApiEntry anonymous_resipApiSizeList[] = +{ + // KEEP SORTED ALPHABETICALLY + RESIP_TENT(Connection,"NEW_MSG_HEADER_SCANNER"), + RESIP_TENT(Data,"RESIP_DATA_LOCAL_SIZE (configure)"), + RESIP_TENT(DnsResult,"USE_IPV6"), + RESIP_TENT(Headers,"PARTIAL_TEMPLATE_SPECIALIZATION"), + RESIP_TENT(MsgHeaderScanner,"NEW_MSG_HEADER_SCANNER"), + RESIP_TENT(SipMessage, "PARTIAL_TEMPLATE_SPECIALIZATION"), + RESIP_TENT(TransportSelector,"USE_IPV6"), + RESIP_TENT(Tuple,"USE_IPV6"), + RESIP_TENT(UdpTransport,"NEW_MSG_HEADER_SCANNER"), + RESIP_TENT(GenericIPAddress,"USE_IPV6") +}; + +#undef RESIP_TENT + +static resip::ApiCheck + anonymous_resipApiCheckObj(anonymous_resipApiSizeList, + sizeof(anonymous_resipApiSizeList)/sizeof(*anonymous_resipApiSizeList)); + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ApplicationMessage.hxx b/src/libs/resiprocate/resip/stack/ApplicationMessage.hxx new file mode 100644 index 00000000..d2f2a5f8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ApplicationMessage.hxx @@ -0,0 +1,76 @@ +#ifndef RESIP_ApplicationMessage_hxx +#define RESIP_ApplicationMessage_hxx + +#include "assert.h" +#include "resip/stack/Message.hxx" + +namespace resip +{ + +/** + @ingroup resip_crit + @brief A base-class for messages used by applications. + + One use case for these is timers; you use SipStack::post() or + SipStack::postMs() to get timer events in the form of your subclass of + ApplicationMessage. +*/ +class ApplicationMessage : public Message +{ + public: + ApplicationMessage() {}; + virtual ~ApplicationMessage() {}; + + virtual const Data& getTransactionId() const { assert(0); return Data::Empty; } +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ApplicationSip.cxx b/src/libs/resiprocate/resip/stack/ApplicationSip.cxx new file mode 100644 index 00000000..015ee6d0 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ApplicationSip.cxx @@ -0,0 +1,104 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/ApplicationSip.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +bool +ApplicationSip::init() +{ + static ContentsFactory<ApplicationSip> factory; + (void)factory; + return true; +} + +ApplicationSip::ApplicationSip(const Mime& contentsType) + : SipFrag(contentsType) +{} + +ApplicationSip::ApplicationSip(const HeaderFieldValue& hfv, const Mime& contentsType) + : SipFrag(hfv, contentsType) +{ +} + +ApplicationSip::ApplicationSip(const ApplicationSip& rhs) + : SipFrag(rhs) +{ +} + +ApplicationSip& +ApplicationSip::operator=(const ApplicationSip& rhs) +{ + SipFrag::operator=(rhs); + return *this; +} + +Contents* +ApplicationSip::clone() const +{ + return new ApplicationSip(*this); +} + +const Mime& +ApplicationSip::getStaticType() +{ + static Mime type("application", "sip"); + return type; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ApplicationSip.hxx b/src/libs/resiprocate/resip/stack/ApplicationSip.hxx new file mode 100644 index 00000000..0e7774f9 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ApplicationSip.hxx @@ -0,0 +1,92 @@ +#if !defined(RESIP_APPLICATIONSIP_HXX) +#define RESIP_APPLICATIONSIP_HXX + +#include "resip/stack/SipFrag.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type to represent contents with an Content-Type application/sip. + + @note Applications may need to explicitly mention this type to induce static + registration. Applications that mention only SipFrag may not be able to + determine the content instance for content-type: application/sip + + map content-type application/sip to the same parser as message/sip + some Cisco gateways send NOTIFY with content-type application/sip +*/ +class ApplicationSip : public SipFrag +{ + public: + ApplicationSip(const Mime& contentsType = getStaticType()); + ApplicationSip(const HeaderFieldValue& hfv, const Mime& contentsType); + ApplicationSip(const Data& data, const Mime& contentsType); + ApplicationSip(const ApplicationSip& rhs); + ApplicationSip& operator=(const ApplicationSip& rhs); + + /** @brief duplicate an ApplicationSip object + @return pointer to a new ApplicationSip object + **/ + virtual Contents* clone() const; + static const Mime& getStaticType(); + + static bool init(); +}; + +static bool invokeApplicationSipInit = ApplicationSip::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Auth.cxx b/src/libs/resiprocate/resip/stack/Auth.cxx new file mode 100644 index 00000000..a09e36c2 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Auth.cxx @@ -0,0 +1,369 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Auth.hxx" +#include "resip/stack/UnknownParameter.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// Auth: +//==================== +Auth::Auth() : + ParserCategory() +{} + +Auth::Auth(const HeaderFieldValue& hfv, Headers::Type type, PoolBase* pool) + : ParserCategory(hfv, type, pool) +{} + +Auth::Auth(const Auth& rhs, PoolBase* pool) + : ParserCategory(rhs, pool), + mScheme(rhs.mScheme) +{} + +Auth& +Auth::operator=(const Auth& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mScheme = rhs.mScheme; + } + return *this; +} + +Data& +Auth::scheme() +{ + checkParsed(); + return mScheme; +} + +const Data& +Auth::scheme() const +{ + checkParsed(); + return mScheme; +} + +void +Auth::parse(ParseBuffer& pb) +{ + const char* start; + start = pb.skipWhitespace(); + static const std::bitset<256> schemeDelimiter(Data::toBitset("\r\n\t =")); + pb.skipToOneOf(schemeDelimiter); + + if (!pb.eof() && *pb.position() == Symbols::EQUALS[0]) + { + // Authentication-Info only + // back up, and then parse + pb.reset(start); + parseAuthParameters(pb); + } + else + { + // everything else + pb.data(mScheme, start); + + pb.skipWhitespace(); + parseAuthParameters(pb); + } +} + +EncodeStream& +Auth::encodeParsed(EncodeStream& str) const +{ + if (!mScheme.empty()) + { + str << mScheme << Symbols::SPACE; + } + + encodeAuthParameters(str); + + return str; +} + +ParserCategory* +Auth::clone() const +{ + return new Auth(*this); +} + +ParserCategory* +Auth::clone(void* location) const +{ + return new (location) Auth(*this); +} + +ParserCategory* +Auth::clone(PoolBase* pool) const +{ + return new (pool) Auth(*this, pool); +} + +void +Auth::parseAuthParameters(ParseBuffer& pb) +{ + while (!pb.eof()) + { + const char* keyStart = pb.position(); + static std::bitset<256> paramBegin=Data::toBitset(" \t\r\n="); + static std::bitset<256> terminators=Data::toBitset(" \t\r\n,"); + const char* keyEnd = pb.skipToOneOf(paramBegin); + if((int)(keyEnd-keyStart) != 0) + { + ParameterTypes::Type type = ParameterTypes::getType(keyStart, (unsigned int)(keyEnd - keyStart)); + Parameter* p=createParam(type, pb, terminators, getPool()); + if (!p) + { + mUnknownParameters.push_back(new UnknownParameter(keyStart, + int((keyEnd - keyStart)), pb, + terminators)); + } + else + { + // invoke the particular factory + mParameters.push_back(p); + } + pb.skipWhitespace(); + if (pb.eof() || *pb.position() != Symbols::COMMA[0]) + { + break; + } + pb.skipChar(); + pb.skipWhitespace(); + } + } +} + +EncodeStream& +Auth::encodeAuthParameters(EncodeStream& str) const +{ + bool first = true; + for (ParameterList::const_iterator it = mParameters.begin(); + it != mParameters.end(); it++) + { + if (!first) + { + str << Symbols::COMMA; + } + first = false; + (*it)->encode(str); + } + + for (ParameterList::const_iterator it = mUnknownParameters.begin(); + it != mUnknownParameters.end(); it++) + { + if (!first) + { + str << Symbols::COMMA; + } + first = false; + (*it)->encode(str); + } + return str; +} + +ParameterTypes::Factory Auth::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; + +Parameter* +Auth::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) +{ + if(type==ParameterTypes::qop) + { + DataParameter* qop = 0; + switch(mHeaderType) + { + case Headers::ProxyAuthenticate: + case Headers::WWWAuthenticate: + qop = new (pool) DataParameter(ParameterTypes::qopOptions,pb,terminators); + qop->setQuoted(true); + break; + case Headers::ProxyAuthorization: + case Headers::Authorization: + case Headers::AuthenticationInfo: + default: + qop = new (pool) DataParameter(ParameterTypes::qop,pb,terminators); + qop->setQuoted(false); + } + return qop; + } + + if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) + { + return ParameterFactories[type](type, pb, terminators, pool); + } + return 0; +} + +bool +Auth::exists(const Param<Auth>& paramType) const +{ + checkParsed(); + bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; + return ret; +} + +void +Auth::remove(const Param<Auth>& paramType) +{ + checkParsed(); + removeParameterByEnum(paramType.getTypeNum()); +} + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ +_enum##_Param::DType& \ +Auth::param(const _enum##_Param& paramType) \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + p = new _enum##_Param::Type(paramType.getTypeNum()); \ + mParameters.push_back(p); \ + } \ + return p->value(); \ +} \ +const _enum##_Param::DType& \ +Auth::param(const _enum##_Param& paramType) const \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + InfoLog(<< "Missing parameter " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ + DebugLog(<< *this); \ + throw Exception("Missing parameter", __FILE__, __LINE__); \ + } \ + return p->value(); \ +} + +defineParam(algorithm, "algorithm", DataParameter, "RFC 2617"); +defineParam(cnonce, "cnonce", QuotedDataParameter, "RFC 2617"); +defineParam(domain, "domain", QuotedDataParameter, "RFC 3261"); +defineParam(nc, "nc", DataParameter, "RFC 2617"); +defineParam(nonce, "nonce", QuotedDataParameter, "RFC 2617"); +defineParam(opaque, "opaque", QuotedDataParameter, "RFC 2617"); +defineParam(realm, "realm", QuotedDataParameter, "RFC 2617"); +defineParam(response, "response", QuotedDataParameter, "RFC 3261"); +defineParam(stale, "stale", DataParameter, "RFC 2617"); +defineParam(uri, "uri", QuotedDataParameter, "RFC 3261"); +defineParam(username, "username", QuotedDataParameter, "RFC 3261"); + +DataParameter::Type& +Auth::param(const qop_Param& paramType) +{ + checkParsed(); + DataParameter* p = static_cast<DataParameter*>(getParameterByEnum(paramType.getTypeNum())); + if (!p) + { + p = new DataParameter(ParameterTypes::qop); + p->setQuoted(false); + mParameters.push_back(p); + } + return p->value(); +} +const DataParameter::Type& +Auth::param(const qop_Param& paramType) const +{ + checkParsed(); + DataParameter* p = static_cast<DataParameter*>(getParameterByEnum(paramType.getTypeNum())); + if (!p) + { + InfoLog(<< "Missing parameter " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); + DebugLog(<< *this); + throw Exception("Missing parameter", __FILE__, __LINE__); + } + return p->value(); +} + +DataParameter::Type& +Auth::param(const qopOptions_Param& paramType) +{ + checkParsed(); + DataParameter* p = static_cast<DataParameter*>(getParameterByEnum(paramType.getTypeNum())); + if (!p) + { + p = new DataParameter(ParameterTypes::qopOptions); + p->setQuoted(true); + mParameters.push_back(p); + } + return p->value(); +} +const DataParameter::Type& +Auth::param(const qopOptions_Param& paramType) const +{ + checkParsed(); + DataParameter* p = static_cast<DataParameter*>(getParameterByEnum(paramType.getTypeNum())); + if (!p) + { + InfoLog(<< "Missing parameter " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); + DebugLog(<< *this); + throw Exception("Missing parameter", __FILE__, __LINE__); + } + return p->value(); +} + + +#undef defineParam + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Auth.hxx b/src/libs/resiprocate/resip/stack/Auth.hxx new file mode 100644 index 00000000..1e37ccdf --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Auth.hxx @@ -0,0 +1,131 @@ +#if !defined(RESIP_AUTH_HXX) +#define RESIP_AUTH_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" + +namespace resip +{ + + +/** + @ingroup sip_grammar + @brief Represents the "credentials" and "challenge" elements in the SIP + grammar. +*/ +class Auth : public ParserCategory +{ + public: + enum {commaHandling = NoCommaTokenizing}; + + Auth(); + Auth(const HeaderFieldValue& hfv, Headers::Type type, PoolBase* pool=0); + Auth(const Auth& orig, PoolBase* pool=0); + Auth& operator=(const Auth&); + + virtual void parse(ParseBuffer& pb); + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + + void parseAuthParameters(ParseBuffer& pb); + EncodeStream& encodeAuthParameters(EncodeStream& str) const; + + Data& scheme(); + const Data& scheme() const; + + // Inform the compiler that overloads of these may be found in + // ParserCategory, too. + using ParserCategory::exists; + using ParserCategory::remove; + using ParserCategory::param; + + virtual Parameter* createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool); + bool exists(const Param<Auth>& paramType) const; + void remove(const Param<Auth>& paramType); + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ + _enum##_Param::DType& param(const _enum##_Param& paramType); \ + const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \ + friend class _enum##_Param + + defineParam(algorithm, "algorithm", DataParameter, "RFC 2617"); + defineParam(cnonce, "cnonce", QuotedDataParameter, "RFC 2617"); + defineParam(domain, "domain", QuotedDataParameter, "RFC 3261"); + defineParam(nc, "nc", DataParameter, "RFC 2617"); + defineParam(nonce, "nonce", QuotedDataParameter, "RFC 2617"); + defineParam(opaque, "opaque", QuotedDataParameter, "RFC 2617"); + defineParam(realm, "realm", QuotedDataParameter, "RFC 2617"); + defineParam(response, "response", QuotedDataParameter, "RFC 3261"); + defineParam(stale, "stale", DataParameter, "RFC 2617"); + defineParam(uri, "uri", QuotedDataParameter, "RFC 3261"); + defineParam(username, "username", QuotedDataParameter, "RFC 3261"); + defineParam(qop,"qop",DataParameter, "RFC 3261"); + // Internal use only + defineParam(qopOptions,"qop",DataParameter, "RFC 3261"); + +#undef defineParam + + private: + Data mScheme; + + static ParameterTypes::Factory ParameterFactories[ParameterTypes::MAX_PARAMETER]; +}; + +} + + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/BasicNonceHelper.cxx b/src/libs/resiprocate/resip/stack/BasicNonceHelper.cxx new file mode 100644 index 00000000..0c42bffa --- /dev/null +++ b/src/libs/resiprocate/resip/stack/BasicNonceHelper.cxx @@ -0,0 +1,129 @@ + + +#include "resip/stack/BasicNonceHelper.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Random.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + + +/** + * BasicNonceHelper implements the makeNonce function in the same way + * as the original implementation of makeNonce within Helper.cxx + * + * To operate a farm/cluster of UASs/proxies, you must: + * a) make sure the clocks are sychronized (using ntpd for instance) + * b) use the same privateKey value on every instance of the application + * + * To operate with SER, use the SERNonceHelper instead, as that generates + * the nonce string the same way as SER. You must also observe the same + * conditions above regarding clock and key synchronization. + */ +BasicNonceHelper::BasicNonceHelper() +{ + //privateKey = Data("asdfklsadflkj"); + privateKey = Random::getRandomHex(24); +} + +BasicNonceHelper::~BasicNonceHelper() +{ +} + +void +BasicNonceHelper::setPrivateKey(const Data& pprivateKey) +{ + this->privateKey = pprivateKey; +} + +Data +BasicNonceHelper::makeNonce(const SipMessage& request, const Data& timestamp) +{ + Data nonce(100, Data::Preallocate); + nonce += timestamp; + nonce += Symbols::COLON; + Data noncePrivate(100, Data::Preallocate); + noncePrivate += timestamp; + noncePrivate += Symbols::COLON; + // !jf! don't include the Call-Id since it might not be the same. + // noncePrivate += request.header(h_CallId).value(); + noncePrivate += request.header(h_From).uri().user(); + noncePrivate += privateKey; + nonce += noncePrivate.md5(); + return nonce; +} + +NonceHelper::Nonce +BasicNonceHelper::parseNonce(const Data& nonce) +{ + ParseBuffer pb(nonce.data(), nonce.size()); + if (!pb.eof() && !isdigit(*pb.position())) + { + DebugLog(<< "Invalid nonce; expected timestamp."); + return BasicNonceHelper::Nonce(0); + } + const char* anchor = pb.position(); + pb.skipToChar(Symbols::COLON[0]); + if (pb.eof()) + { + DebugLog(<< "Invalid nonce; expected timestamp terminator."); + return BasicNonceHelper::Nonce(0); + } + Data creationTime; + pb.data(creationTime, anchor); + return BasicNonceHelper::Nonce(creationTime.convertUInt64()); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/stack/BasicNonceHelper.hxx b/src/libs/resiprocate/resip/stack/BasicNonceHelper.hxx new file mode 100644 index 00000000..6f09851a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/BasicNonceHelper.hxx @@ -0,0 +1,94 @@ +#if !defined(RESIP_BASICNONCEHELPER_HXX) +#define RESIP_BASICNONCEHELPER_HXX + +#include "resip/stack/NonceHelper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Data.hxx" + + +namespace resip +{ + +/** + * @brief Implements the makeNonce function in the same way + * as the original implementation of makeNonce within Helper.cxx + * + * To operate a farm/cluster of UASs/proxies, you must: + * -# make sure the clocks are sychronized (using ntpd for instance) + * -# use the same privateKey value on every instance of the application + * + * To operate with SER, use the SERNonceHelper instead, as that generates + * the nonce string the same way as SER. You must also observe the same + * conditions above regarding clock and key synchronization. + */ + +class BasicNonceHelper : public NonceHelper +{ + private: + Data privateKey; + + public: + BasicNonceHelper(); + virtual ~BasicNonceHelper(); + void setPrivateKey(const Data& privateKey); + Data makeNonce(const SipMessage& request, const Data& timestamp); + Nonce parseNonce(const Data& nonce); + + +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/stack/BranchParameter.cxx b/src/libs/resiprocate/resip/stack/BranchParameter.cxx new file mode 100644 index 00000000..7f6802f0 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/BranchParameter.cxx @@ -0,0 +1,346 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <cassert> +#include "resip/stack/BranchParameter.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Random.hxx" +#include "rutil/Coders.hxx" +#include "rutil/ParseException.hxx" + +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +BranchParameter::BranchParameter(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators) + : Parameter(type), + mHasMagicCookie(false), + mIsMyBranch(false), + mTransactionId(), + mTransportSeq(1), + mClientData(), + mInteropMagicCookie(0), + mSigcompCompartment() +{ + try + { + pb.skipWhitespace(); + pb.skipChar(Symbols::EQUALS[0]); + pb.skipWhitespace(); + if(memcmp(pb.position(), Symbols::MagicCookie, 7) == 0) + { + mHasMagicCookie=true; + pb.skipN(7); + } + // !bwc! This no-case comparison is expensive; only do it if the case- + // sensitive comparison fails. + else if(strncasecmp(pb.position(), Symbols::MagicCookie, 7) == 0) + { + mHasMagicCookie=true; + mInteropMagicCookie = new Data(pb.position(), 7); + pb.skipN(7); + } + + const char* start = pb.position(); + static std::bitset<256> delimiter=Data::toBitset("\r\n\t ;=?>"); + + if (mHasMagicCookie && + (pb.end() - start > 8) && + // look for prefix cookie (maybe make this bigger?) + memcmp(start, Symbols::resipCookie, 8) == 0) + { + // ?bwc? Wrap this stuff in try/catch, just in case of false positives? + const char* curr=start; + mIsMyBranch = true; + pb.skipN(8); + + mTransportSeq=pb.uInt32(); + + curr=pb.skipChar('-'); + pb.skipToChar('-'); + Data encoded; + pb.data(encoded, curr); + if(!encoded.empty()) + { + // !bwc! Expensive! Also, Base64 isn't case-insensitive. + mClientData = encoded.base64decode(); + } + + curr=pb.skipChar('-'); + pb.skipToChar('-'); + pb.data(encoded,curr); + if(!encoded.empty()) + { + // !bwc! Expensive! Also, Base64 isn't case-insensitive. + mSigcompCompartment = encoded.base64decode(); + } + + start=pb.skipChar('-'); + } + pb.skipToOneOf(delimiter); + pb.data(mTransactionId, start); + } + catch(resip::ParseException& e) + { + mTransactionId=Random::getRandomHex(8); + throw e; + } +} + +BranchParameter::BranchParameter(ParameterTypes::Type type) + : Parameter(type), + mHasMagicCookie(true), + mIsMyBranch(true), + mTransactionId(Random::getRandomHex(8)), + mTransportSeq(1), + mInteropMagicCookie(0), + mSigcompCompartment() +{ +} + +BranchParameter::BranchParameter(const BranchParameter& other) + : Parameter(other), + mHasMagicCookie(other.mHasMagicCookie), + mIsMyBranch(other.mIsMyBranch), + mTransactionId(other.mTransactionId), + mTransportSeq(other.mTransportSeq), + mClientData(other.mClientData), + mSigcompCompartment(other.mSigcompCompartment) +{ + if (other.mInteropMagicCookie) + { + mInteropMagicCookie = new Data(*other.mInteropMagicCookie); + } + else + { + mInteropMagicCookie = 0; + } +} + +BranchParameter::~BranchParameter() +{ + delete mInteropMagicCookie; +} + +BranchParameter& +BranchParameter::operator=(const BranchParameter& other) +{ + if (this != &other) + { + mHasMagicCookie = other.mHasMagicCookie; + mIsMyBranch = other.mIsMyBranch; + mTransactionId = other.mTransactionId; + mTransportSeq = other.mTransportSeq; + mClientData = other.mClientData; + mSigcompCompartment = other.mSigcompCompartment; + if (other.mInteropMagicCookie) + { + delete mInteropMagicCookie; + mInteropMagicCookie = new Data(*other.mInteropMagicCookie); + } + else + { + delete mInteropMagicCookie; + mInteropMagicCookie = 0; + } + } + return *this; +} + +bool +BranchParameter::operator==(const BranchParameter& other) +{ + if (mIsMyBranch != other.mIsMyBranch || + mHasMagicCookie != other.mHasMagicCookie || + mTransportSeq != other.mTransportSeq || + mTransactionId != other.mTransactionId || + mClientData != other.mClientData || + mSigcompCompartment != other.mSigcompCompartment) + { + return false; + } + return true; +} + +bool +BranchParameter::hasMagicCookie() const +{ + return mHasMagicCookie; +} + +const Data& +BranchParameter::getTransactionId() const +{ + return mTransactionId; +} + +void +BranchParameter::incrementTransportSequence() +{ + assert(mIsMyBranch); + mTransportSeq++; +} + +Data& +BranchParameter::clientData() +{ + return mClientData; +} + +const Data& +BranchParameter::clientData() const +{ + return mClientData; +} + +/** + @todo The encoding here could be more efficient. +*/ +void +BranchParameter::setSigcompCompartment(const Data &id) +{ + if (id.size() == 0) + { + mSigcompCompartment = Data::Empty; + } + + // These will often (but not always) be UUID URNs in angle brackets; + // e.g.: <urn:uuid:fa33c72d-121f-47e8-42e2-1eb6e24aba64> + + // Ideally, we would detect this, strip out everything that isn't + // hex, and convert the hex to raw data. + + mSigcompCompartment = id; +} + +Data +BranchParameter::getSigcompCompartment() const +{ + return mSigcompCompartment; +} + +void +BranchParameter::reset(const Data& transactionId) +{ + mHasMagicCookie = true; + mIsMyBranch = true; + delete mInteropMagicCookie; + mInteropMagicCookie = 0; + + mSigcompCompartment = Data::Empty; + + mTransportSeq = 1; + if (!transactionId.empty()) + { + mTransactionId = transactionId; + } + else + { + mTransactionId = Random::getRandomHex(8); + } +} + +Parameter* +BranchParameter::clone() const +{ + return new BranchParameter(*this); +} + +EncodeStream& +BranchParameter::encode(EncodeStream& stream) const +{ + stream << getName() << Symbols::EQUALS; + if (mHasMagicCookie) + { + if (mInteropMagicCookie) + { + stream << *mInteropMagicCookie; + } + else + { + stream << Symbols::MagicCookie; + } + } + if (mIsMyBranch) + { + stream << Symbols::resipCookie; + stream << mTransportSeq; + stream << Symbols::DASH; + if(!mClientData.empty()) // base64encode() makes copies + { + // !bwc! We should be using hex encoding; branch params are supposed to + // be case-insensitive. + stream << mClientData.base64encode(true/*safe URL*/); + } + stream << Symbols::DASH; + if(!mSigcompCompartment.empty()) // base64encode() makes copies + { + // !bwc! We should be using hex encoding; branch params are supposed to + // be case-insensitive. + stream << mSigcompCompartment.base64encode(true); + } + stream << Symbols::DASH; + } + stream << mTransactionId; + + return stream; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/BranchParameter.hxx b/src/libs/resiprocate/resip/stack/BranchParameter.hxx new file mode 100644 index 00000000..f940fac0 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/BranchParameter.hxx @@ -0,0 +1,141 @@ +#if !defined(RESIP_BRANCHPARAMETER_HXX) +#define RESIP_BRANCHPARAMETER_HXX + +#include <iosfwd> + +#include "resip/stack/Parameter.hxx" +#include "resip/stack/ParameterTypeEnums.hxx" +#include "rutil/Data.hxx" +#include "rutil/PoolBase.hxx" + +namespace resip +{ + +class ParseBuffer; + +// BranchParameter of the form: +// rfc3261cookie-sip2cookie-tid-transportseq-clientdata-sip2cookie +// Notably, the tid MAY contain dashes by the clientdata MUST NOT. +// + +/** + @ingroup sip_grammar + @brief Represents the "via-branch" parameter of the RFC 3261 grammar. +*/ + +class BranchParameter : public Parameter +{ + public: + typedef BranchParameter Type; + + BranchParameter(ParameterTypes::Type, ParseBuffer& pb, const std::bitset<256>& terminators); + explicit BranchParameter(ParameterTypes::Type); + + ~BranchParameter(); + + // contains z9hG4bK + bool hasMagicCookie() const; + + // returns tid + const Data& getTransactionId() const; + + // increments the transport sequence component - not part of tid + void incrementTransportSequence(); + + // pseudo-random tid if none specified, zero sequences either way + void reset(const Data& transactionId = Data::Empty); + + // access the client specific portion of the branch - not part of tid + Data& clientData(); + const Data& clientData() const; + + // access sigcomp id -- we do pre- and post-processing on this, + // so we need "normal" setters and getters + void setSigcompCompartment(const Data &); + Data getSigcompCompartment() const; + + static Parameter* decode(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators, + PoolBase* pool) + { + return new (pool) BranchParameter(type, pb, terminators); + } + + virtual Parameter* clone() const; + virtual EncodeStream& encode(EncodeStream& stream) const; + + BranchParameter(const BranchParameter& other); + BranchParameter& operator=(const BranchParameter& other); + bool operator==(const BranchParameter& other); + + Type& value() {return *this;} + + private: + bool mHasMagicCookie; + bool mIsMyBranch; + Data mTransactionId; + unsigned int mTransportSeq; + Data mClientData; + //magic cookie for interop; if case is different some proxies will treat this as a different tid + const Data* mInteropMagicCookie; + + // If we're compressing, this will hold the compartment ID + // for the host that the request was sent to. + Data mSigcompCompartment; + +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/CSeqCategory.cxx b/src/libs/resiprocate/resip/stack/CSeqCategory.cxx new file mode 100644 index 00000000..bc5333fb --- /dev/null +++ b/src/libs/resiprocate/resip/stack/CSeqCategory.cxx @@ -0,0 +1,222 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/CSeqCategory.hxx" +#include "resip/stack/UnknownParameter.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// CSeqCategory: +//==================== +CSeqCategory::CSeqCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), mMethod(UNKNOWN), mSequence(0) +{} + +CSeqCategory::CSeqCategory() + : ParserCategory(), + mMethod(UNKNOWN), + mUnknownMethodName(getMethodName(UNKNOWN)), + mSequence(0) +{} + +CSeqCategory::CSeqCategory(const CSeqCategory& rhs, PoolBase* pool) + : ParserCategory(rhs, pool), + mMethod(rhs.mMethod), + mUnknownMethodName(rhs.mUnknownMethodName), + mSequence(rhs.mSequence) +{} + +CSeqCategory& +CSeqCategory::operator=(const CSeqCategory& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mMethod = rhs.mMethod; + mUnknownMethodName = rhs.mUnknownMethodName; + mSequence = rhs.mSequence; + } + return *this; +} + +bool +CSeqCategory::operator==(const CSeqCategory& rhs) const +{ + return (mMethod == rhs.mMethod && + (mMethod != UNKNOWN || mUnknownMethodName == rhs.mUnknownMethodName) && + mSequence == rhs.mSequence); +} + +bool +CSeqCategory::operator<(const CSeqCategory& rhs) const +{ + if (mUnknownMethodName < rhs.mUnknownMethodName) + { + return true; + } + else if (mUnknownMethodName > rhs.mUnknownMethodName) + { + return false; + } + + return mSequence < rhs.mSequence; +} + + +ParserCategory* +CSeqCategory::clone() const +{ + return new CSeqCategory(*this); +} + +ParserCategory* +CSeqCategory::clone(void* location) const +{ + return new (location) CSeqCategory(*this); +} + +ParserCategory* +CSeqCategory::clone(PoolBase* pool) const +{ + return new (pool) CSeqCategory(*this, pool); +} + +MethodTypes& +CSeqCategory::method() +{ + checkParsed(); + return mMethod; +} + +MethodTypes +CSeqCategory::method() const +{ + checkParsed(); return mMethod; +} + +Data& +CSeqCategory::unknownMethodName() +{ + checkParsed(); + return mUnknownMethodName; +} + +const Data& +CSeqCategory::unknownMethodName() const +{ + checkParsed(); + return mUnknownMethodName; +} + +unsigned int& +CSeqCategory::sequence() +{ + checkParsed(); + return mSequence; +} + +unsigned int +CSeqCategory::sequence() const +{ + checkParsed(); + return mSequence; +} + +// examples to test: +// "CSeq:15 ACK" // ok +// "CSeq:ACK" // bad +// "CSeq:JOE" // ok +// "CSeq:1 JOE" // ok +// "CSeq:1323333 INVITE" // ok +// "CSeq:1323333 Invite" // ok - not invite +// "CSeq:1323333 InviTe" // ok - not invite +// "CSeq:\t\t \t15\t\t\t \t ACK" // ok +// "CSeq:\t\t \t15\t\t\t \t" // bad +// "CSeq:1xihzihsihtqnognsd INVITE" // not ok, but parses (?) + +void +CSeqCategory::parse(ParseBuffer& pb) +{ + pb.skipWhitespace(); + mSequence = pb.uInt32(); + + const char* anchorPtr = pb.skipWhitespace(); + pb.skipNonWhitespace(); // .dcm. maybe pass an arg that says throw if you + // don't move + mMethod = getMethodType(anchorPtr, int(pb.position() - anchorPtr)); + // for backward compatibility, set the method name even if the method is known + pb.data(mUnknownMethodName, anchorPtr); +} + +EncodeStream& +CSeqCategory::encodeParsed(EncodeStream& str) const +{ + str << mSequence + << Symbols::SPACE + << (mMethod != UNKNOWN ? getMethodName(mMethod) : mUnknownMethodName); + return str; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/CSeqCategory.hxx b/src/libs/resiprocate/resip/stack/CSeqCategory.hxx new file mode 100644 index 00000000..5916fafd --- /dev/null +++ b/src/libs/resiprocate/resip/stack/CSeqCategory.hxx @@ -0,0 +1,105 @@ +#if !defined(RESIP_CSEQ_HXX) +#define RESIP_CSEQ_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/MethodTypes.hxx" + +namespace resip +{ + + +/** + @ingroup sip_grammar + @brief Represents a CSeq header field value (this doesn't have an official + name in the RFC 3261 grammar). +*/ +class CSeqCategory : public ParserCategory +{ + public: + enum {commaHandling = NoCommaTokenizing}; + + CSeqCategory(); + CSeqCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + CSeqCategory(const CSeqCategory& orig, PoolBase* pool=0); + CSeqCategory& operator=(const CSeqCategory&); + + MethodTypes& method(); + MethodTypes method() const; + Data& unknownMethodName(); + const Data& unknownMethodName() const; + unsigned int& sequence(); + unsigned int sequence() const; + + bool operator==(const CSeqCategory& rhs) const; + bool operator<(const CSeqCategory& rhs) const; + + virtual void parse(ParseBuffer& pb); + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + + private: + MethodTypes mMethod; + Data mUnknownMethodName; + unsigned int mSequence; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/CallId.cxx b/src/libs/resiprocate/resip/stack/CallId.cxx new file mode 100644 index 00000000..0978f443 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/CallId.cxx @@ -0,0 +1,219 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/CallId.hxx" +#include "resip/stack/UnknownParameter.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// CallID: +//==================== +CallID::CallID() + : ParserCategory(), + mValue() +{} + +CallID::CallID(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), mValue() +{} + +CallID::CallID(const CallID& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mValue(rhs.mValue) +{} + +CallID& +CallID::operator=(const CallID& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mValue = rhs.mValue; + } + return *this; +} + +bool +CallID::operator==(const CallID& rhs) const +{ + return value() == rhs.value(); +} + +ParserCategory * +CallID::clone() const +{ + return new CallID(*this); +} + +ParserCategory * +CallID::clone(void* location) const +{ + return new (location) CallID(*this); +} + +ParserCategory* +CallID::clone(PoolBase* pool) const +{ + return new (pool) CallID(*this, pool); +} + +Data& +CallID::value() +{ + checkParsed(); + return mValue; +} + +const Data& +CallID::value() const +{ + checkParsed(); + return mValue; +} + +void +CallID::parse(ParseBuffer& pb) +{ + const char* start = pb.skipWhitespace(); + static const std::bitset<256> wsOrSemi(Data::toBitset(ParseBuffer::Whitespace).set(Symbols::SEMI_COLON[0])); + pb.skipToOneOf(wsOrSemi); + pb.data(mValue, start); + + parseParameters(pb); +} + +EncodeStream& +CallID::encodeParsed(EncodeStream& str) const +{ + str << mValue; + encodeParameters(str); + return str; +} + +ParameterTypes::Factory CallID::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; + +Parameter* +CallID::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) +{ + if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) + { + return ParameterFactories[type](type, pb, terminators, pool); + } + return 0; +} + +bool +CallID::exists(const Param<CallID>& paramType) const +{ + checkParsed(); + bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; + return ret; +} + +void +CallID::remove(const Param<CallID>& paramType) +{ + checkParsed(); + removeParameterByEnum(paramType.getTypeNum()); +} + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ +_enum##_Param::DType& \ +CallID::param(const _enum##_Param& paramType) \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + p = new _enum##_Param::Type(paramType.getTypeNum()); \ + mParameters.push_back(p); \ + } \ + return p->value(); \ +} \ + \ +const _enum##_Param::DType& \ +CallID::param(const _enum##_Param& paramType) const \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ + DebugLog(<< *this); \ + throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ + } \ + return p->value(); \ +} + +defineParam(fromTag, "from-tag", DataParameter, "RFC 3891 (not in IANA, apparently)"); +defineParam(toTag, "to-tag", DataParameter, "RFC 3891 (not in IANA, apparently)"); +defineParam(earlyOnly, "early-only", ExistsParameter, "RFC 3891 (not in IANA, apparently)"); + +#undef defineParam + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/CallId.hxx b/src/libs/resiprocate/resip/stack/CallId.hxx new file mode 100644 index 00000000..fddca0b4 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/CallId.hxx @@ -0,0 +1,124 @@ +#if !defined(RESIP_CALLID_HXX) +#define RESIP_CALLID_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/ParserContainer.hxx" + +namespace resip +{ + + +/** + @ingroup sip_grammar + @brief Represents the "callid" element in the SIP grammar. +*/ +class CallID : public ParserCategory +{ + public: + enum {commaHandling = NoCommaTokenizing}; + + CallID(); + CallID(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + CallID(const CallID& orig, + PoolBase* pool=0); + CallID& operator=(const CallID&); + bool operator==(const CallID&) const; + + Data& value(); + const Data& value() const; + + virtual void parse(ParseBuffer& pb); + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + + // Inform the compiler that overloads of these may be found in + // ParserCategory, too. + using ParserCategory::exists; + using ParserCategory::remove; + using ParserCategory::param; + + virtual Parameter* createParam(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators, + PoolBase* pool); + bool exists(const Param<CallID>& paramType) const; + void remove(const Param<CallID>& paramType); + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ + const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \ + _enum##_Param::DType& param(const _enum##_Param& paramType); \ + friend class _enum##_Param + +defineParam(fromTag, "from-tag", DataParameter, "RFC 3891 (not in IANA, apparently)"); +defineParam(toTag, "to-tag", DataParameter, "RFC 3891 (not in IANA, apparently)"); +defineParam(earlyOnly, "early-only", ExistsParameter, "RFC 3891 (not in IANA, apparently)"); + +#undef defineParam + + private: + Data mValue; + + static ParameterTypes::Factory ParameterFactories[ParameterTypes::MAX_PARAMETER]; +}; +typedef ParserContainer<CallID> CallIDs; +typedef CallID CallId; // code convention compatible + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/CancelClientInviteTransaction.hxx b/src/libs/resiprocate/resip/stack/CancelClientInviteTransaction.hxx new file mode 100644 index 00000000..6defbee8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/CancelClientInviteTransaction.hxx @@ -0,0 +1,95 @@ +#ifndef CancelClientInviteTransaction_Include_Guard +#define CancelClientInviteTransaction_Include_Guard + +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/MessageDecorator.hxx" + +#include "rutil/Data.hxx" + +namespace resip +{ +class CancelClientInviteTransaction : public TransactionMessage +{ + public: + explicit CancelClientInviteTransaction(const resip::Data& tid) : mTid(tid) {} + virtual ~CancelClientInviteTransaction(){} + +/////////////////// Must implement unless abstract /// + + virtual const Data& getTransactionId() const {return mTid;} + virtual bool isClientTransaction() const {return true;} + virtual EncodeStream& encode(EncodeStream& strm) const + { + return strm << "CancelClientInviteTransaction: " << mTid; + } + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "CancelClientInviteTransaction: " << mTid; + } + +/////////////////// May override /// + + virtual Message* clone() const + { + return new CancelClientInviteTransaction(*this); + } + + protected: + const resip::Data mTid; +}; // class CancelClientInviteTransaction + +} // namespace resip + +#endif // include guard + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ + diff --git a/src/libs/resiprocate/resip/stack/CancelableTimerQueue.hxx b/src/libs/resiprocate/resip/stack/CancelableTimerQueue.hxx new file mode 100644 index 00000000..8b72d9e5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/CancelableTimerQueue.hxx @@ -0,0 +1,191 @@ +#ifndef resip_CancelableTimerQueue_hxx +#define resip_CancelableTimerQueue_hxx + +#include <map> +#include <limits.h> +#include <iosfwd> + +#include "rutil/Timer.hxx" +#include "rutil/HashMap.hxx" +#include "rutil/Inserter.hxx" + +using namespace std; + +namespace resip +{ + +template<class T> +class CancelableTimerQueue +{ + public: + CancelableTimerQueue() : mNextId(0) {}; + ~CancelableTimerQueue() {}; + + typedef long Id; + private: + typedef std::multimap< UInt64, std::pair<T, Id> > TimerMap; + typedef HashMap<Id, UInt64> IdToTimer; + + public: + Id addRelative(T msg, + unsigned int offset) + { + return addTimer(msg, resip::Timer::getTimeMs() + offset); + } + + //returns true if the id existed + bool cancel(Id id) + { + typename IdToTimer::iterator j = mIdToTimer.find(id); + if (j == mIdToTimer.end()) + { + return false; + } + + for (typename TimerMap::iterator i = mTimerMap.lower_bound(j->second); i != mTimerMap.upper_bound(j->second); i++) + { + if (i->second.second == id) + { + mTimerMap.erase(i); + mIdToTimer.erase(j); + return true; + } + } + //cerr << "mIdToTimer: " << Inserter(mIdToTimer) << endl; + //cerr << "Searching for ID: " << id << endl; + //cerr << "TimerMap state: " << Inserter(mTimerMap) << endl; + assert(mIdToTimer.size() == mTimerMap.size()); + assert(0); + } + + //get the number of milliseconds until the next event, returns -1 if no + //event is available + int getTimeout() const + { + if (mTimerMap.empty()) + { + return -1; + } + else + { + if (mTimerMap.begin()->first - resip::Timer::getTimeMs() < 0) + { + return 0; + } + else + { + return mTimerMap.begin()->first - resip::Timer::getTimeMs(); + } + } + } + + bool available() const + { + return (!mTimerMap.empty() && + mTimerMap.begin()->first <= resip::Timer::getTimeMs()); + } + + T getNext() + { + assert(mIdToTimer.size() == mTimerMap.size()); + + assert(available()); + + typename TimerMap::iterator it = mTimerMap.begin(); + mIdToTimer.erase(it->second.second); + + T msg = it->second.first; + mTimerMap.erase(it); + + assert(mIdToTimer.size() == mTimerMap.size()); + + return msg; + } + + void clear() + { + mTimerMap.clear(); + mIdToTimer.clear(); + } + + bool empty() const + { + return mTimerMap.empty(); + } + + size_t size() const + { + return mTimerMap.size(); + } + + private: + + Id addTimer(T msg, UInt64 expiry) + { + Id id = getNextId(); + mTimerMap.insert(std::make_pair(expiry, std::make_pair(msg, id))); + mIdToTimer[id] = expiry; + assert(mIdToTimer.size() == mTimerMap.size()); + return id; + } + + Id getNextId() + { + mNextId++; + if (mNextId == INT_MAX) + { + mNextId = 1; + } + return mNextId; + } + + Id mNextId; + IdToTimer mIdToTimer; + TimerMap mTimerMap; +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 PurpleComm, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ChangeLog b/src/libs/resiprocate/resip/stack/ChangeLog new file mode 100644 index 00000000..29f5ebd8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ChangeLog @@ -0,0 +1,9506 @@ +2004-01-12 <alan@jasomi.com> + * os/Timer.cxx: + Minor timer cleanup. + + * TransactionState.hxx: + Added mNetSource for explicit tracking of sources. + Fixes for force target support. + + * SipMessage.hxx: renamed ...Target to ...ForceTarget. + + * ParserCategories.hxx (class Via): + Changed default transport to + be empty. + + * Helper.cxx: cleanup of reason phrase code. + (getPortForReply): renamed getSentPort to be in line with use. + (getPortForReply): added notion of symmetric response. + +2003-10-09 12:59 davidb + + * test/testData.cxx: added some tests + +2003-10-09 12:58 davidb + + * test/limpc.cxx: corrected --help text + +2003-10-09 12:58 jason + + * Transport.cxx: added call to Helper::validateMessage to validate + more than just existence of Via header + +2003-10-09 12:58 davidb + + * os/Data.cxx: generalize for any value of LocalAlloc + +2003-10-09 12:57 davidb + + * ParserCategories.hxx: Token constructor against Data + +2003-10-09 12:57 jason + + * test/testDns.cxx: added command line args + +2003-10-09 12:57 davidb + + * ParserCategories.cxx: set the unknownMethodName even if it is + know for backward compatibility + +2003-10-09 12:57 jason + + * Helper.cxx, Helper.hxx: added a validate message check + +2003-10-09 12:56 davidb + + * Headers.hxx, MethodTypes.hxx: added RFCs + +2003-10-09 12:54 jason + + * DnsResult.cxx: fix problem with DnsResult calling handle() when + results are already available + +2003-10-08 01:38 alan + + * test/testMsgHeaderDiagram.cxx: impound + +2003-10-07 16:49 alan + + * Helper.cxx, MsgHeaderScanner.cxx, MsgHeaderScanner.hxx, TODO, + Transport.cxx, Transport.hxx, UdpTransport.cxx, test/Makefile.am, + test/testStack.cxx: Added via-less changes to HEAD Modified Files: + resiprocate/Helper.cxx resiprocate/MsgHeaderScanner.cxx + resiprocate/MsgHeaderScanner.hxx resiprocate/TODO + resiprocate/Transport.cxx resiprocate/Transport.hxx + resiprocate/UdpTransport.cxx resiprocate/test/Makefile.am + resiprocate/test/testStack.cxx + +2003-10-07 16:35 alan + + * Connection.cxx, Connection.hxx, SipMessage.cxx, + TcpBaseTransport.cxx, Transport.cxx, os/Tuple.hxx, + test/Makefile.am, test/testData.cxx, test/testResponses.cxx, + test/testUdp.cxx: Completed via-less malformed message recovery. + Framework for other recoveries in Transport::basicCheck() Modified + Files: configure.ac resiprocate/Connection.cxx + resiprocate/Connection.hxx resiprocate/SipMessage.cxx + resiprocate/TcpBaseTransport.cxx Tag: b-dev-ah-20031006-viafix + resiprocate/Transport.cxx No tag + resiprocate/os/Tuple.hxx resiprocate/test/Makefile.am + resiprocate/test/testData.cxx resiprocate/test/testUdp.cxx Added + Files: resiprocate/test/testResponses.cxx VS: + ------------------------------------------------------------------- + --- + +2003-10-07 11:02 alan + + * test/Makefile.am: autotools minor tweaks + +2003-10-07 08:03 alan + + * MsgHeaderScanner.cxx, MsgHeaderScanner.hxx, TODO, Transport.cxx, + Transport.hxx, UdpTransport.cxx, test/Makefile.am, + test/testStack.cxx: Made MsgHeaderScanner compile cleanly on OS/X. + Made Changes to testStack so bindaddr was used better. Minor + changes to Makefile.am for popts Adding via-less response fixes. + Modified Files: Tag: b-dev-ah-20031006-viafix + resiprocate/MsgHeaderScanner.cxx + resiprocate/MsgHeaderScanner.hxx resiprocate/TODO + resiprocate/Transport.cxx resiprocate/Transport.hxx + resiprocate/UdpTransport.cxx resiprocate/test/Makefile.am + resiprocate/test/testStack.cxx + +2003-10-06 17:57 alan + + * Helper.cxx, Transport.cxx, Transport.hxx, UdpTransport.cxx: + Changes for via-less messages. DO NOT USE. ON BRANCH TO CHECK ON + VARIOUS PLATFORMS AND TO MIGRATE TESTING TO NEW MACHINE. + (alan@jasomi.com) Modified Files: Tag: b-dev-20031006-via-fix + Helper.cxx Transport.cxx Transport.hxx UdpTransport.cxx + +2003-10-06 11:59 davidb + + * os/DnsUtil.cxx, test/testUri.cxx: ::1 is a valid IPV6 address + +2003-10-04 21:47 fluffy + + * test/Makefile: made POP optional - wish this defaulted off so + that stuff compiled by default + +2003-10-04 21:09 fluffy + + * test/: test.vcproj, testIntrusiveList.cxx, testStack.cxx: updated + +2003-10-04 21:08 fluffy + + * Connection.hxx, ConnectionManager.cxx, ConnectionManager.hxx: + Fixed intrusinve lists in windows + +2003-10-04 20:52 fluffy + + * test/testIntrusiveList.cxx: changed to work in windows + +2003-10-04 19:41 jason + + * DnsResult.cxx: [no log message] + +2003-10-04 19:34 fluffy + + * test/: limpc.cxx, test.vcproj: no change + +2003-10-04 19:34 fluffy + + * test/testStack.cxx: took out the || 1 in HAVE_POPT_H #if defs + +2003-10-04 19:32 fluffy + + * UdpTransport.cxx, Transport.cxx, TcpBaseTransport.cxx: don't + print error for EWOULDBLOCK + +2003-10-04 19:09 jason + + * DnsResult.cxx, DnsResult.hxx: fix a memory corruption error in + set<SRV> by changing to vector<SRV> + +2003-10-04 18:29 jason + + * DnsInterface.cxx, DnsInterface.hxx: simplify how supported + transport types work + +2003-10-04 16:47 fluffy + + * os/DnsUtil.cxx: fix endian problem + +2003-10-04 15:50 jason + + * ConnectionManager.cxx: try a different delete + +2003-10-04 15:50 jason + + * os/Tuple.cxx: fix compile issue + +2003-10-04 15:50 jason + + * DnsResult.cxx: remove USE_ARES flag from dns resolver only do + AAAA lookup if USE_IPV6 + +2003-10-04 14:34 fluffy + + * ConnectionManager.cxx, DnsInterface.cxx, DnsInterface.hxx, + DnsResolver.hxx, DnsResult.cxx, TransportSelector.cxx, Uri.cxx: fix + so ares.h is not exported to things that use resiprocate + +2003-10-04 14:33 fluffy + + * os/Tuple.cxx: fix printing of IP addr for windows + +2003-10-04 14:33 fluffy + + * os/Tuple.hxx: inlcude for scoklen_t type + +2003-10-04 14:32 fluffy + + * test/test.vcproj, resiprocate.vcproj: Release and Debug work but + SSL version are broken + +2003-10-04 10:51 jason + + * TcpBaseTransport.cxx, Transport.cxx, UdpTransport.cxx, + os/Socket.cxx: fix shutdown of transports in multithreaded case + +2003-10-03 13:47 jason + + * test/testStack.cxx: support for v6 in test + +2003-10-03 13:47 jason + + * os/Tuple.cxx: fix bug in length() + +2003-10-03 13:46 jason + + * Transport.cxx, TransportSelector.cxx: debug + +2003-10-02 22:08 jason + + * SipStack.cxx, SipStack.hxx, TransactionController.cxx, + TransactionController.hxx, TransportSelector.cxx, + TransportSelector.hxx, os/TransportType.hxx, os/Tuple.hxx: + reorganized how v6 is specified to be more clear + +2003-10-02 20:11 jason + + * UdpTransport.cxx: move errno stuff into base class + +2003-10-02 20:11 jason + + * TransportSelector.cxx, TransportSelector.hxx: return default + transport if no specific ones match based on transport type + +2003-10-02 19:43 davidb + + * test/testUri.cxx: test operator== for reflexivity add tests from + 3261 19.1.4 + +2003-10-02 19:39 davidb + + * test/testTransactionFSM.cxx: use skipToChar when we can + +2003-10-02 19:38 davidb + + * test/testParserCategories.cxx: fixed Uri comparison + +2003-10-02 19:37 davidb + + * test/testParseBuffer.cxx: added tests for skip primitives + +2003-10-02 19:36 davidb + + * test/testMultipartMixedContents.cxx: cosmetic + +2003-10-02 19:36 davidb + + * test/testData.cxx: a few more tests + +2003-10-02 19:35 davidb + + * os/: Data.cxx, Data.hxx: Data has own char buffer[128] for + efficient heap use + +2003-10-02 19:30 davidb + + * Uri.cxx: !nasty bug fixes! added case break added missing + comparison in integer comparison made operator== reflexive list => + vector for efficiency + +2003-10-02 19:28 davidb + + * ParserCategory.hxx: list => vector for efficiency + +2003-10-02 18:53 jason + + * test/testTimer.cxx: fix test + +2003-10-02 18:52 jason + + * os/Data.cxx, DnsResult.cxx, os/Inserter.hxx, + os/RecursiveMutex.cxx, os/Tuple.cxx: fix compat with intel compiler + +2003-10-02 16:28 jason + + * TcpBaseTransport.cxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, TransportSelector.hxx, os/Tuple.cxx, + os/Tuple.hxx: reorganize ipv6 stuff in TransportSelector, + Transports and Tuple change datastructure for storing the + Transports in the TransportSelector to be more efficient + +2003-10-02 16:24 jason + + * DnsInterface.cxx, DnsInterface.hxx, DnsResult.cxx, DnsResult.hxx: + change license to VOCAL + +2003-10-02 16:24 jason + + * Connection.cxx: debug + +2003-10-01 11:07 davidb + + * test/testEmbedded.cxx: rport automatically added in Via -- fix + comparison string + +2003-10-01 10:53 jason + + * test/testTypedef.cxx: compile on linux + +2003-10-01 10:53 jason + + * test/testParserCategories.cxx: make the test pass + +2003-10-01 10:53 jason + + * Connection.cxx, TcpBaseTransport.cxx, os/Socket.hxx, + os/Tuple.cxx, os/Tuple.hxx, os/Socket.cxx: fix the cullen whirlwind + +2003-10-01 08:35 fluffy + + * TransportSelector.cxx, TransportSelector.hxx: fix opening of + socket and errno stuff + +2003-10-01 08:33 fluffy + + * os/Fifo.hxx, os/Socket.cxx, os/Socket.hxx, os/DnsUtil.cxx, + Transport.cxx, Transport.hxx, UdpTransport.cxx, + ParserCategories.cxx, TcpBaseTransport.cxx, TcpConnection.cxx: fix + errno stuff + +2003-10-01 08:33 fluffy + + * test/: limpc.cxx, test.vcproj: compile windows + +2003-09-30 12:31 jason + + * ConnectionManager.cxx, DnsResult.cxx, Headers.hxx, SipStack.cxx, + os/Inserter.hxx, os/IntrusiveListElement.hxx, test/Makefile, + test/testIntrusiveList.cxx, test/testTypedef.cxx: fixes for solaris + +2003-09-29 19:59 jason + + * os/Socket.cxx: for solaris compiler + +2003-09-29 19:38 jason + + * os/DnsUtil.cxx: getdomainname() and int e = + ioctl(s,SIOCGIFCONF,&ifc) are not supported in solaris + +2003-09-29 18:53 fluffy + + * os/IntrusiveListElement.hxx: change to compile windows - had to + move private memeber to protected - no idea why this fixed the + problem + +2003-09-29 18:49 fluffy + + * TransportSelector.cxx, Transport.hxx, os/Tuple.hxx: fix for when + there is no IPV6 + +2003-09-29 18:48 fluffy + + * TransactionController.cxx: fix compiler warning in windows + +2003-09-29 16:07 alan + + * TransportSelector.cxx, os/Tuple.cxx, test/Makefile.am: minor + compilation fixes for Linux + +2003-09-29 15:56 alan + + * Makefile.am: fixed duplicate SUBDIRS + +2003-09-29 15:51 alan + + * Makefile.am, Transport.hxx, TransportSelector.cxx, + TransportSelector.hxx, config.hxx.in, os/Tuple.cxx, os/Tuple.hxx, + test/Makefile.am, test/testStack.cxx, test/testUdp.cxx: + TransportSelector changes. sentPort() to clue for specifics. + Otherwise, will select tightest bound transport. Populates topmost + via with correct IP address. + + Modified Files: + Connection.cxx Connection.hxx ConnectionManager.cxx + DnsResult.cxx DnsResult.hxx Helper.cxx Makefile.am + StatelessHandler.cxx TcpBaseTransport.cxx TcpConnection.cxx + TcpConnection.hxx TcpTransport.cxx TlsConnection.hxx + TransactionState.cxx Transport.cxx Transport.hxx + TransportMessage.hxx TransportSelector.cxx + TransportSelector.hxx UdpTransport.cxx config.hxx.in + resiprocate.vcproj os/DnsUtil.cxx os/DnsUtil.hxx + os/Random.cxx os/Socket.cxx + os/Socket.hxx os/Tuple.cxx os/Tuple.hxx test/Makefile.am + test/testStack.cxx test/testUdp.cxx + +2003-09-29 15:40 alan + + * Transport.hxx, TransportSelector.cxx, TransportSelector.hxx, + os/Tuple.cxx, os/Tuple.hxx, test/Makefile.am, test/testStack.cxx: + transport selector overhaul + +2003-09-29 13:25 davidb + + * Connection.hxx: unse simplified IntrusiveListElement templates + +2003-09-29 13:25 davidb + + * test/Makefile: added testIntrusiveList + +2003-09-29 13:25 davidb + + * test/testIntrusiveList.cxx: [no log message] + +2003-09-29 13:25 davidb + + * os/IntrusiveListElement.hxx: simplified templates, added license + +2003-09-29 13:23 davidb + + * os/ParseBuffer.cxx: output parse errors to Info + +2003-09-29 08:23 alan + + * Makefile.am: re-ordered build + +2003-09-29 07:56 alan + + * Connection.cxx, Connection.hxx, ConnectionManager.cxx, + DnsResult.cxx, DnsResult.hxx, Helper.cxx, StatelessHandler.cxx, + TcpBaseTransport.cxx, TcpConnection.cxx, TcpConnection.hxx, + TcpTransport.cxx, TlsConnection.hxx, TransactionState.cxx, + Transport.cxx, Transport.hxx, TransportMessage.hxx, + TransportSelector.cxx, UdpTransport.cxx, resiprocate.vcproj, + os/DnsUtil.cxx, os/DnsUtil.hxx, os/IntrusiveListElement.hxx, + os/Random.cxx, os/Socket.cxx, os/Socket.hxx, os/Tuple.cxx, + os/Tuple.hxx, test/testStack.cxx: safety check-in before + integrating Jasons changes + +2003-09-28 17:37 jason + + * test/testStack.cxx: allow specification of protocol with -p + +2003-09-28 17:36 jason + + * os/Socket.hxx: fix compile on linux + +2003-09-28 17:36 jason + + * UdpTransport.cxx: [no log message] + +2003-09-28 13:26 fluffy + + * os/DnsUtil.cxx, os/Socket.hxx, os/Tuple.cxx, Connection.hxx, + DnsResult.cxx, DnsResult.hxx, TcpConnection.hxx, TlsConnection.hxx, + resiprocate.vcproj: compiles under windows - added bunch of + USE_IPV6 #ifdefs + +2003-09-28 13:25 fluffy + + * os/IntrusiveListElement.hxx: This needs help before it will work + under windoes - right not it just comiples by commenting stuff out + - it would not run in widnows. Other versiosns should still work + +2003-09-27 17:21 jason + + * Connection.cxx, TcpBaseTransport.cxx, TcpConnection.cxx, + Transport.cxx: fix bug when read returns 0 bytes - means far side + closed + +2003-09-27 14:53 jason + + * os/: Random.cxx, Socket.cxx, Socket.hxx: change to use shutdown + instead of close + +2003-09-27 14:50 jason + + * Connection.cxx, TcpBaseTransport.cxx, TcpConnection.cxx, + TcpTransport.cxx, TransportMessage.hxx: change some debug levels + +2003-09-27 14:45 jason + + * ConnectionManager.cxx: fix memory leak in deleteConnection from + mAddrMap and mIdMap + +2003-09-27 10:27 jason + + * DnsResult.cxx: fixed bug with setting port for numeric ip query + +2003-09-27 10:05 jason + + * os/Tuple.cxx: fixed bug with not converting port from host to + network + +2003-09-27 09:52 jason + + * os/: DnsUtil.cxx, DnsUtil.hxx: added capability to get local ip + address also added capability to find ip address for a named + interface + +2003-09-26 18:49 jason + + * ConnectionManager.cxx, DnsResult.cxx, Helper.cxx, + StatelessHandler.cxx, TcpBaseTransport.cxx, TransactionState.cxx, + Transport.cxx, Transport.hxx, TransportSelector.cxx, + UdpTransport.cxx, os/DnsUtil.cxx, os/DnsUtil.hxx, os/Tuple.cxx, + os/Tuple.hxx: refactored the Tuple required interface changes to + the Tuple store network address in a sockaddr structure to be + generic for v4 and v6 fixed a bug in Tuple::operator< + +2003-09-26 18:44 alan + + * TcpBaseTransport.cxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, UdpTransport.cxx, config.hxx.in, + os/Tuple.cxx, test/testUdp.cxx: Safety check-in so I can work on + the w/e on the Mac. Modified Files: Tag: b-dev-ah-20030925-ts + TcpBaseTransport.cxx Transport.cxx Transport.hxx + TransportSelector.cxx UdpTransport.cxx config.hxx.in + os/Tuple.cxx test/testUdp.cxx + +2003-09-26 09:47 jason + + * TcpBaseTransport.cxx, Transport.cxx, Transport.hxx, + UdpTransport.cxx: added a method Transport::bind to replace the + static so we can store the bound sockaddr in the Transport for use + by TransportSelector + +2003-09-25 19:14 alan + + * Makefile.am, TransportSelector.cxx, TransportSelector.hxx, + test/Makefile.am, test/testStack.cxx: Not ready for prime-time -- + personal integration branch. Modified Files: Tag: + b-dev-ah-20030925-ts configure.ac aclocal.m4 + resiprocate/Makefile.am resiprocate/TransportSelector.cxx + resiprocate/TransportSelector.hxx resiprocate/test/Makefile.am + resiprocate/test/testStack.cxx + +2003-09-25 17:50 jason + + * test/testStack.cxx: combine message creation with sends + +2003-09-25 14:42 jason + + * test/testStack.cxx: use dns + +2003-09-25 14:30 jason + + * test/: Makefile, testStack.cxx: added a new performance test for + the stack + +2003-09-25 14:30 jason + + * TransactionState.cxx: fix some memory issues with delete this + +2003-09-25 10:47 jason + + * test/: testTcp.cxx, testUdp.cxx, Makefile: added command line + args using popt + +2003-09-25 10:47 jason + + * test/testDns.cxx: delete DnsResults + +2003-09-25 10:46 jason + + * os/: Log.cxx, Log.hxx: added Log::initialize that takes char* for + command line arg ease of use + +2003-09-25 10:46 jason + + * DnsInterface.cxx: fix memory leak with ares + +2003-09-25 10:45 jason + + * DnsResult.cxx: change to LOG_DEBUG + +2003-09-24 14:31 alan + + * Connection.cxx, Connection.hxx, ConnectionMap.cxx, + ConnectionMap.hxx: removing obsolete files and references to them + +2003-09-24 13:33 alan + + * test/testTcp.cxx: dummy use for err + +2003-09-24 13:33 alan + + * config.hxx.in: missing USE options + +2003-09-24 11:07 davidb + + * test/testUri.cxx: test IPV6 handling + +2003-09-24 11:06 davidb + + * test/testSipFrag.cxx: added test for tricky end of SipFrag + +2003-09-24 11:05 davidb + + * os/ParseBuffer.cxx: added file name to logging on failure -- how + helpful + +2003-09-24 11:04 davidb + + * os/: DnsUtil.cxx, DnsUtil.hxx: IPV6 mods + +2003-09-24 11:04 davidb + + * os/: AbstractFifo.cxx, AbstractFifo.hxx, FiniteFifo.hxx: + refactored fifo for finite length -- returns false if can't push + (how will this interact with priorty queue?) (do timers ever go + into finite queues?) + +2003-09-24 10:59 davidb + + * Uri.cxx, Uri.hxx: allow IP6 hosts -- includes comparison + +2003-09-24 10:58 davidb + + * SipFrag.cxx: hacked SipFrag to allow MsgHeaderScanner to be + unhappy with how the fragment ends -- probably wrong + +2003-09-23 13:25 jason + + * Connection.cxx, TcpBaseTransport.cxx, TcpConnection.cxx, + Transport.cxx, Transport.hxx: [no log message] + +2003-09-22 00:05 jason + + * Connection.cxx, ConnectionManager.cxx, TcpBaseTransport.cxx, + TcpConnection.cxx: fix some problems with cleanup when delete + TcpTransport and/or Connection + +2003-09-19 17:33 davidb + + * test/testIntrusiveList.cxx: use static makeList + +2003-09-19 17:32 davidb + + * os/IntrusiveListElement.hxx: valiant attempt to synch comments + with code + +2003-09-19 17:32 davidb + + * ConnectionManager.cxx, ConnectionManager.hxx: using a single + Connection for all list heads; fixed iterator validation + +2003-09-19 16:30 davidb + + * test/testTcp.cxx: spelling in output + +2003-09-19 16:29 davidb + + * os/Data.cxx: fixed weird cast bug in hash + +2003-09-19 16:29 davidb + + * Connection.cxx, Connection.hxx, ConnectionManager.cxx, + ConnectionManager.hxx: converted Connection lists (read, write, + least recently used) to intrusive + +2003-09-19 16:28 davidb + + * os/IntrusiveListElement.hxx: rationalized initialization, added + some paranoid asserts + +2003-09-19 14:51 davidb + + * os/IntrusiveListElement.hxx, test/testIntrusiveList.cxx: [no log + message] + +2003-09-18 14:10 davidb + + * ConnectionManager.cxx: [no log message] + +2003-09-18 14:08 jason + + * Makefile: added new files to old build system + +2003-09-18 10:15 davidb + + * Connection.cxx, Connection.hxx, ConnectionManager.cxx, + ConnectionManager.hxx, ConnectionMap.cxx, DnsResult.cxx, + Makefile.am, Security.cxx, Security.hxx, SipStack.cxx, + SipStack.hxx, TcpBaseTransport.cxx, TcpBaseTransport.hxx, + TcpConnection.cxx, TcpConnection.hxx, TcpTransport.cxx, + TcpTransport.hxx, TlsConnection.cxx, TlsConnection.hxx, + TlsTransport.cxx, TlsTransport.hxx, TransactionController.cxx, + TransactionController.hxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx, + os/DnsUtil.cxx, os/DnsUtil.hxx, os/Socket.cxx, os/Tuple.cxx, + os/Tuple.hxx, test/Makefile.am, test/Transceiver.cxx, + test/testTcp.cxx, test/testUdp.cxx: refactored tcp code refactored + tls code full support for tcpv6 with more general use support for + binding to specific interfaces added many new DnsUtil and utilities + in Tuple class + +2003-09-16 08:22 jason + + * MethodHash.cxx: fix cullen's erasure of this file + +2003-09-16 06:55 fluffy + + * os/: RandomHex.cxx, RandomHex.hxx: no longe used + +2003-09-16 06:53 fluffy + + * .cvsignore, os/.cvsignore, test/.cvsignore: ignore goofy stuff + +2003-09-16 06:50 fluffy + + * PreparseDiagnostic.cxx, PreparseInlines.cxx, SdpContents.cxx, + ShutdownMessage.hxx, SipFrag.cxx, StatelessHandler.cxx, + StatelessHandler.hxx, TransactionController.cxx, + TransactionController.hxx, TransactionTerminated.hxx, TuShim.cxx, + UnknownHeaderType.cxx, UnknownParameterType.cxx, XMLCursor.cxx, + XPidf.cxx, X_msMsgsInvite.cxx, libSipImp.cxx, os/Coders.cxx, + os/Coders.hxx, os/CountStream.cxx, os/DataStream.cxx, + os/DnsUtil.hxx, os/MD5Stream.cxx, os/MD5Stream.hxx, os/Tuple.cxx, + os/Tuple.hxx, test/InviteClient.cxx, test/InviteClient.hxx, + test/InviteServer.cxx, test/InviteServer.hxx, test/Register.cxx, + test/Register.hxx, test/Registrar.cxx, test/Registrar.hxx, + test/Resolver.cxx, test/TestSupport.cxx, test/TestSupport.hxx, + test/Transceiver.cxx, test/Transceiver.hxx, test/digcalc.hxx, + test/lg.cxx, test/limpc.cxx, test/md5.cxx, test/md5.hxx, + test/test1.cxx, test/test2.cxx, test/testBlast.cxx, + test/testClient.cxx, test/testCoders.cxx, test/testCountStream.cxx, + test/testData.cxx, test/testDataPerformance.cxx, + test/testDataStream.cxx, test/testDigestAuthentication.cxx, + test/testDns.cxx, test/testDnsResolver.cxx, test/testEmbedded.cxx, + test/testEmptyHeader.cxx, test/testIM.cxx, test/testIM.hxx, + test/testLockStep.cxx, test/testLogger.cxx, + test/testMessageWaiting.cxx, test/testMultipartMixedContents.cxx, + test/testNameAddrParamExclusions.cxx, + test/testNonInviteClientTx.cxx, test/testNonInviteServerTx.cxx, + test/testParseUtil.cxx, test/testPlainContents.cxx, + test/testRandomHex.cxx, test/testSdp.cxx, test/testSelect.cxx, + test/testServer.cxx, test/testSimpleLeak.cxx, + test/testSipStackInvite.cxx, test/testSource.cxx, + test/testSpeed.cxx, test/testTcpTransport.cxx, + test/testThreadIf.cxx, test/testTlsConnection.cxx, + test/testTransactionFSM.cxx, test/testUdp.cxx, test/testUri.cxx, + test/testXMLCursor.cxx, ApplicationSip.cxx, Connection.cxx, + Connection.hxx, ConnectionMap.cxx, Contents.cxx, DnsHandler.hxx, + DnsResolver.cxx, Embedded.cxx, GenericContents.cxx, HeaderHash.cxx, + HeaderHash.hxx, LazyParser.cxx, MessageWaitingContents.cxx, + MethodHash.cxx, MethodHash.hxx, MsgHeaderScanner.cxx, + MsgHeaderScanner.hxx, MultipartMixedContents.cxx, + MultipartSignedContents.cxx, OctetContents.cxx, ParameterHash.cxx, + ParameterHash.hxx, ParseUtil.hxx, Pidf.cxx, Pkcs7Contents.cxx, + PlainContents.cxx: fixed up license text + +2003-09-16 06:48 fluffy + + * os/DnsUtil.cxx: made to compile on mac + +2003-09-15 20:54 davidb + + * UnknownParameter.cxx: should initialize mIsQuoted + +2003-09-15 20:04 fluffy + + * UdpTransport.cxx: update error codes + +2003-09-15 20:04 fluffy + + * test/test.vcproj: no message + +2003-09-15 12:35 alan + + * Transport.cxx: added initialisation of mV4 member. + +2003-09-15 12:00 jason + + * StatelessHandler.cxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, os/DnsUtil.cxx, os/DnsUtil.hxx, + os/Tuple.cxx: [no log message] + +2003-09-14 22:07 alan + + * test/testSource.cxx: sockaddr_t fixes + +2003-09-14 21:08 alan + + * TransportSelector.cxx: initial ipv6 via support + +2003-09-14 19:49 fluffy + + * os/Socket.hxx: add assert + +2003-09-14 19:48 fluffy + + * test/testBlast.cxx: does not work yet + +2003-09-14 19:27 fluffy + + * UdpTransport.cxx, os/DnsUtil.cxx: update + +2003-09-14 19:24 fluffy + + * test/: test.vcproj, limpc.cxx: update + +2003-09-14 16:45 alan + + * TransportSelector.cxx: type repair for Linux + +2003-09-14 16:40 davidb + + * os/Data.cxx: new hash fn + +2003-09-14 16:39 jason + + * SipStack.cxx, SipStack.hxx, TransactionController.cxx, + TransactionController.hxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx: + added multi-threading for transports + +2003-09-14 16:35 jason + + * test/: .cvsignore, Makefile.am: [no log message] + +2003-09-14 16:35 jason + + * test/testUdp.cxx: added a speed test for udp + +2003-09-14 14:05 alan + + * Connection.hxx, MsgHeaderScanner.cxx, MsgHeaderScanner.hxx, + SipFrag.cxx, SipMessage.cxx, TransactionState.cxx, + TransportSelector.cxx, TransportSelector.hxx, test/Makefile.am, + test/testSource.cxx: Added via: setting to TransportSelector.cxx + Fixed includes in MsgScanner Added some flags for configure: + --enable-ipv6 --enable-scanner --with-ares + --with-openssl + + modified Files: configure.ac resiprocate/Connection.hxx + resiprocate/MsgHeaderScanner.cxx + resiprocate/MsgHeaderScanner.hxx resiprocate/SipFrag.cxx + resiprocate/SipMessage.cxx resiprocate/TransactionState.cxx + resiprocate/TransportSelector.cxx + resiprocate/TransportSelector.hxx resiprocate/test/Makefile.am + Added Files: resiprocate/test/testSource.cxx + +2003-09-14 13:42 fluffy + + * test/: Makefile, testSelect.cxx: added testSelect + +2003-09-14 01:42 fluffy + + * Security.cxx: fix error for earlier version of SSL + +2003-09-14 01:39 fluffy + + * Security.cxx: try to stop overwrite of certs + +2003-09-14 01:37 jason + + * TransactionState.cxx: fix bugs + +2003-09-14 01:31 fluffy + + * test/: Makefile, limpc.cxx: [no log message] + +2003-09-14 01:27 jason + + * Makefile, test/Makefile: [no log message] + +2003-09-14 00:54 fluffy + + * os/: DnsUtil.cxx, Tuple.cxx, Tuple.hxx: fixed for windows + +2003-09-14 00:53 fluffy + + * resiprocate.vcproj: added ares - does not link + +2003-09-14 00:22 rjsparks + + * DnsResult.cxx, DnsResult.hxx: Added queries for AAAA records + +2003-09-14 00:21 jason + + * test/testDns.cxx: fix recursive lock error on debug + +2003-09-14 00:10 fluffy + + * DnsResolver.cxx, DnsResult.cxx, TlsTransport.cxx, + TlsTransport.hxx, TransactionState.cxx, Transport.hxx, + UdpTransport.cxx, UdpTransport.hxx: compile under windows + +2003-09-14 00:09 fluffy + + * resiprocate.vcproj: add ares + +2003-09-13 23:30 jason + + * test/: test2.cxx, testClient.cxx, testDnsResolver.cxx, + testLockStep.cxx, testNonInviteClientTx.cxx, + testNonInviteServerTx.cxx, testServer.cxx, testSipStackInvite.cxx, + testSpeed.cxx, testTcpTransport.cxx, testTransactionFSM.cxx: fix + Transport -> Tuple stuff + +2003-09-13 23:25 jason + + * test/Makefile.am: added files + +2003-09-13 23:18 jason + + * os/Tuple.cxx: fix compile + +2003-09-13 22:46 jason + + * Makefile.am: added files + +2003-09-13 22:41 jason + + * test/: Makefile.am, limpc.cxx: [no log message] + +2003-09-13 22:25 jason + + * Connection.cxx, Connection.hxx, ConnectionMap.cxx, + ConnectionMap.hxx, DnsInterface.hxx, DnsResolver.cxx, + DnsResolver.hxx, DnsResult.cxx, DnsResult.hxx, Makefile.am, + SipMessage.hxx, SipStack.cxx, SipStack.hxx, StatelessHandler.cxx, + TcpTransport.cxx, TcpTransport.hxx, TlsTransport.cxx, + TlsTransport.hxx, TransactionController.cxx, + TransactionController.hxx, TransactionState.cxx, + TransactionState.hxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, TransportSelector.hxx, TuIM.cxx, TuIM.hxx, + UdpTransport.cxx, UdpTransport.hxx, libSipImp.cxx, os/DnsUtil.cxx, + os/DnsUtil.hxx, os/Socket.hxx, test/Resolver.cxx, + test/Resolver.hxx, test/Transceiver.cxx, test/test1.cxx, + test/testClient.cxx, test/testServer.cxx: moved Tuple out of + Transport added preliminary ipv6 support + +2003-09-13 22:20 davidb + + * TransactionState.cxx: removed crazy TimerCleanup that causes + strange crash + +2003-09-13 21:58 davidb + + * os/Timer.cxx: fix error on display of timer + +2003-09-13 21:17 fluffy + + * MethodHash.cxx: remvoed std + +2003-09-13 21:15 fluffy + + * ApplicationSip.cxx, BranchParameter.cxx, Connection.cxx, + ConnectionMap.cxx, Contents.cxx, DataParameter.cxx, Dialog.cxx, + Dialog2.cxx, DialogSet.cxx, Embedded.cxx, Executive.cxx, + ExistsParameter.cxx, FloatParameter.cxx, GenericContents.cxx, + HeaderFieldValue.cxx, HeaderFieldValueList.cxx, HeaderHash.cxx, + HeaderTypes.cxx, Headers.cxx, Helper.cxx, IntegerParameter.cxx, + LazyParser.cxx, Message.cxx, MessageWaitingContents.cxx, + MethodTypes.cxx, MsgHeaderScanner.cxx, MultipartMixedContents.cxx, + MultipartSignedContents.cxx, OctetContents.cxx, Parameter.cxx, + ParameterHash.cxx, ParameterTypes.cxx, ParseUtil.cxx, + ParserCategories.cxx, ParserCategory.cxx, Pidf.cxx, + Pkcs7Contents.cxx, PlainContents.cxx, Preparse.cxx, + PreparseDiagnostic.cxx, PreparseInlines.cxx, QopParameter.cxx, + QuotedDataParameter.cxx, Registration.cxx, RportParameter.cxx, + SdpContents.cxx, SendingMessage.cxx, SipFrag.cxx, SipMessage.cxx, + SipMessageExplicit.cxx, SipSession.cxx, StatelessHandler.cxx, + Subscription.cxx, Symbols.cxx, TcpTransport.cxx, TimerMessage.cxx, + TimerQueue.cxx, TlsTransport.cxx, TransactionController.cxx, + TransactionMap.cxx, TransactionState.cxx, Transport.cxx, + TuShim.cxx, UdpTransport.cxx, UnknownHeaderType.cxx, + UnknownParameter.cxx, UnknownParameterType.cxx, Uri.cxx, + XMLCursor.cxx, XPidf.cxx, X_msMsgsInvite.cxx: added the config.h + include in + +2003-09-13 21:12 fluffy + + * MethodHash-raw.cxx: remove std namespace - not used + +2003-09-13 21:03 fluffy + + * DnsResult.hxx: interface is reserve work in windows + +2003-09-13 21:02 fluffy + + * MethodHash.cxx, SipMessage.cxx: fix windows warnings + +2003-09-13 20:42 jason + + * os/: Tuple.cxx, Tuple.hxx: moved out of Transport + +2003-09-13 20:40 davidb + + * Makefile, MethodHash-raw.cxx: fix hash for old build stuff + +2003-09-13 20:33 fluffy + + * Security.cxx, Security.hxx: made path function public instead of + private + +2003-09-13 20:31 fluffy + + * Makefile: removed old gperf generation stuff + +2003-09-13 18:41 davidb + + * test/testParseUtil.cxx: [no log message] + +2003-09-13 18:41 davidb + + * Makefile, MethodHash.cxx, ParseUtil.cxx, ParseUtil.hxx, Uri.cxx, + os/DnsUtil.cxx, os/DnsUtil.hxx, test/Makefile, + test/testParserCategories.cxx, test/testUri.cxx, + ParserCategories.cxx: first pass at IPV6 syntax + +2003-09-13 14:23 rjsparks + + * os/compat.hxx: Added a definition for the DNS AAAA record type + T_AAAA == 28 + +2003-09-13 13:16 jason + + * DnsInterface.hxx, Makefile.am: fix build for ares and new dns + +2003-09-13 12:57 jason + + * DnsResolver.cxx, DnsResolver.hxx, Executive.cxx, Executive.hxx, + Makefile, Security.cxx, Security.hxx, SipStack.cxx, SipStack.hxx, + StatelessHandler.cxx, StatelessHandler.hxx, TcpTransport.cxx, + TimerMessage.cxx, TlsTransport.cxx, TransactionController.cxx, + TransactionController.hxx, TransactionState.cxx, + TransactionState.hxx, TransportSelector.cxx, TransportSelector.hxx, + TuIM.hxx, UdpTransport.cxx, os/Timer.hxx, test/testDns.cxx, + SipMessage.hxx: working new version of dns resolver using a + TransactionController now no ok() methods in Transports callback + for dns results instead of event + +2003-09-13 12:47 jason + + * DnsHandler.hxx, DnsInterface.cxx, DnsInterface.hxx, + DnsResult.cxx, DnsResult.hxx: working new version of dns resolver + +2003-09-13 10:47 davidb + + * SdpContents.cxx, SdpContents.hxx: change int& + +2003-09-11 21:45 fluffy + + * Headers.cxx, ParserCategories.cxx, SdpContents.cxx: fixed compile + warnings on windows + +2003-09-11 21:38 fluffy + + * resiprocate.vcproj, os/DnsUtil.cxx: fixed to compile on windows + again + +2003-09-11 10:17 alan + + * Makefile.am: added RPM stuff to autotools manifests + +2003-09-08 19:04 jason + + * test/Makefile: remove some tests that aren't building at the + moment + +2003-09-08 15:56 davidb + + * test/testUri.cxx: more tests, test missing scheme failure + +2003-09-08 15:56 davidb + + * test/testSipMessage.cxx: slight fix to test + +2003-09-08 15:55 davidb + + * Uri.cxx: complain if give an uri with a @ and no scheme + +2003-09-08 15:54 davidb + + * UdpTransport.cxx: typo in debug + +2003-09-08 15:54 davidb + + * SipMessage.cxx: type agreement in comparison + +2003-09-08 15:53 davidb + + * HeaderTypes.hxx, Headers.cxx, Headers.hxx, MethodTypes.cxx, + MethodTypes.hxx, ParameterTypeEnums.hxx: unified macros in + preparation for auto generating gperf files + +2003-09-08 15:00 jason + + * os/Fifo.hxx: remove reference to Inserter in Fifo + +2003-09-08 14:43 jason + + * os/Inserter.hxx: change inserter to only comment out code under + windows + +2003-09-05 21:38 fluffy + + * os/Fifo.hxx, os/Inserter.hxx, DnsInterface.cxx, DnsResult.hxx, + MethodHash.cxx, StatelessHandler.cxx, TransportSelector.cxx, + Uri.cxx, resiprocate.vcproj: compile under windows + +2003-09-04 11:20 jason + + * test/.cvsignore: allow addition of new tests + +2003-09-04 11:20 jason + + * test/: testDns.cxx, Makefile: simple test code for new Dns + resolver + +2003-09-04 11:19 jason + + * DnsResult.cxx: added code to handle case where SRV or A records + are not in additional section of dns record + +2003-09-03 15:08 jason + + * HeaderHash.cxx, MethodHash.cxx, MethodHash.gperf: added PRACK and + PUBLISH rebuild the gperf stuff + +2003-09-01 22:00 jason + + * DnsResult.cxx: NAPTR processing seems better now. If no NAPTR, + the algorithm to pick from multiple SRV results is not right - need + clarification + +2003-09-01 21:38 jason + + * DnsInterface.cxx, DnsInterface.hxx, DnsResult.cxx, DnsResult.hxx: + closer to implementation of rfc2782, rfc2915 and rfc3263 (still not + ready for public consumption) + +2003-08-31 18:54 jason + + * DnsInterface.cxx, DnsInterface.hxx, DnsResult.cxx: fixed some + bugs, not for public use yet. interface may still change + +2003-08-31 17:40 jason + + * DnsInterface.cxx, DnsInterface.hxx, DnsResult.cxx, DnsResult.hxx: + fix some link errors + +2003-08-31 16:49 jason + + * os/: Subsystem.cxx, Subsystem.hxx: added DNS subsystem sorted + entries + +2003-08-31 16:49 jason + + * os/: DnsUtil.cxx, DnsUtil.hxx: added some calls for isIpAddress + (v4 & v6) v6 not implemented + +2003-08-31 16:48 jason + + * DnsInterface.cxx, DnsInterface.hxx, DnsResult.cxx, DnsResult.hxx: + first cut at a new set of DNS interfaces/implementation complete + rewrite of DnsResolver class + +2003-08-31 16:43 jason + + * ParserCategories.hxx: add rport parameter by default on Via + +2003-08-29 13:33 ryker + + * MethodHash.gperf: Get some s/sip2/resiprocate/ out of my local + tree. + +2003-08-29 13:33 ryker + + * MethodHash.hxx: Make macro guards consistent. + +2003-08-29 13:27 ryker + + * HeaderHash.gperf, HeaderHash.hxx: Get some s/sip2/resiprocate/ + out of my tree. + +2003-08-26 21:58 fluffy + + * Helper.cxx, TuIM.cxx, TuIM.hxx, test/limpc.cxx: fixed bugs with + TCP + +2003-08-26 20:48 fluffy + + * os/vmd5.cxx: fixed endina bug that caused digest auth to fail on + MAC + +2003-08-26 19:45 wensong + + * os/DnsUtil.cxx: [no log message] + +2003-08-26 17:51 jason + + * TcpTransport.cxx: temporary fix to problem with + blocking/non-blocking creation of tcp socket needs more work + +2003-08-26 17:50 jason + + * ConnectionMap.cxx: remove the delete of connection to avoid a + crash in TCP/TLS + +2003-08-26 17:50 jason + + * Helper.cxx: only add record-route to response if 180 -- 2xx + +2003-08-26 17:49 jason + + * TODO: [no log message] + +2003-08-26 17:49 jason + + * TlsTransport.cxx: fix bug related to using an existing connection + with TLS + +2003-08-26 17:49 jason + + * Transport.cxx: added some debug to operator<< + +2003-08-26 17:48 jason + + * TransportSelector.cxx: added a comment + +2003-08-26 17:48 jason + + * os/Fifo.hxx: added asserts + +2003-08-26 15:04 fluffy + + * SipStack.cxx, SipStack.hxx, libSipImp.cxx, test/limpc.cxx: change + order of addTlsTransport + +2003-08-26 15:03 fluffy + + * TransactionState.cxx: fix compile warning + +2003-08-26 14:03 fluffy + + * os/DnsUtil.cxx: fix for MAC + +2003-08-25 20:21 wensong + + * Makefile.am: [no log message] + +2003-08-21 06:28 jason + + * TransactionState.cxx: when reliability message comes back from + transports, set mIsReliable flag in transaction so retransmissions + don't occur on reliable transports + +2003-08-20 13:47 jason + + * MethodTypes.cxx, MethodTypes.hxx: added PRACK and PUBLISH + +2003-08-20 08:56 jason + + * ParserCategories.cxx, ParserCategory.cxx: Unknown parameters call + +2003-08-20 08:16 jason + + * UnknownParameter.cxx, UnknownParameter.hxx: deal with exists + style unknown parameters + +2003-08-20 08:10 jason + + * SipMessage.cxx: fix brie for UNKNOWN method + +2003-08-20 07:07 ryker + + * TcpTransport.cxx: Fix the comment so that I can understand it + better. + +2003-08-19 16:11 jason + + * HeaderFieldValueList.cxx, ParserContainer.hxx: don't allow empty + headers (still requires support for special multi headers that can + be empty) fix bug in multi output on separate lines + +2003-08-19 16:10 jason + + * TransportSelector.cxx: debug output + +2003-08-19 16:10 jason + + * TransactionState.cxx, TransactionState.hxx: fix handling of dns + errors and running out of dns entries - send a 480 to TU + +2003-08-19 16:09 jason + + * TlsTransport.cxx: return when error occurs to avoid seg fault + +2003-08-19 16:08 jason + + * DnsResolver.cxx, DnsResolver.hxx: when dns error occurs, set + final = true + +2003-08-19 09:56 jason + + * test/: testParserCategories.cxx, testSipMessage.cxx: add exists + style unknown parameters + +2003-08-19 08:17 jason + + * TransportSelector.cxx: include TlsTransports in all process + calls. temporary solution + +2003-08-19 08:17 jason + + * TlsTransport.cxx: handle case where 0 bytes received + +2003-08-19 08:17 jason + + * Connection.cxx: stampReceived not called in one case + +2003-08-19 01:30 wensong + + * ChangeLog, Makefile.am, TcpTransport.cxx, TlsTransport.cxx: [no + log message] + +2003-08-18 15:41 jason + + * Headers.cxx, ParserCategories.hxx, ParserCategory.hxx: rename + weird comma enums fix bug in output of multi headers on separate + lines + +2003-08-18 07:48 ryker + + * ExistsParameter.cxx: When we parse "exists" parameters, be + accepting of a right hand side (e.g. ;lr=1 instead of plain ;lr). + In this case, eat the right hand side so we can continue parsing + normally. + +2003-08-16 18:43 jason + + * Transport.cxx: init to -1 + +2003-08-16 18:43 jason + + * TcpTransport.cxx: handle shutting down the TcpTransport if stuff + is still in the fifo. not correct behavior. shut drain the + transport + +2003-08-16 18:42 jason + + * Connection.cxx, Connection.hxx, ConnectionMap.cxx: fixed a bug in + the Connection where it was deleting some dummy Connections + resulting in closing file descriptor 0 + +2003-08-16 18:17 jason + + * SipStack.cxx: [no log message] + +2003-08-15 16:28 davidb + + * Connection.cxx, Connection.hxx, Makefile, MsgHeaderScanner.cxx, + SipFrag.cxx, SipMessage.cxx, SipMessage.hxx, TcpTransport.cxx, + UdpTransport.cxx, UdpTransport.hxx, test/SipTortureTests.cxx, + test/TestSupport.cxx, test/testMultipartMixedContents.cxx, + test/testTcpTransport.cxx: support both Preparser and + MsgHeaderScanner + +2003-08-14 22:05 davidb + + * os/DnsUtil.cxx: include + +2003-08-14 22:05 davidb + + * os/RecursiveMutex.cxx: indent + +2003-08-14 22:03 davidb + + * Transport.cxx: fixed hash function for tuple + +2003-08-14 22:03 davidb + + * Transport.hxx: added warning comment + +2003-08-14 22:03 davidb + + * MsgHeaderScanner.cxx, MsgHeaderScanner.hxx: new style message + scanner (alternative for preparser) + +2003-08-14 22:02 davidb + + * ConnectionMap.cxx: minor change to assertion + +2003-08-14 21:28 wensong + + * Makefile.am: [no log message] + +2003-08-13 22:49 jason + + * Connection.cxx, SipStack.hxx, TcpTransport.cxx, TlsTransport.cxx, + TlsTransport.hxx, Transport.hxx: tweaks to the TLS stuff so that it + sets the tls domainname when a message is received on a TLS + transport + +2003-08-13 22:48 jason + + * TransportSelector.cxx, TransportSelector.hxx: use the only TLS + transport if there is only one and no TLS domainname specified + +2003-08-13 22:47 jason + + * os/: DnsUtil.cxx, DnsUtil.hxx: added getLocalDomainName + +2003-08-13 20:21 wensong + + * test/Makefile.am: [no log message] + +2003-08-13 19:26 jason + + * Connection.cxx, SipMessage.cxx, SipMessage.hxx, SipStack.cxx, + SipStack.hxx, TlsTransport.cxx, TlsTransport.hxx, + TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx, + test/TestSupport.cxx, test/testPreparse.cxx: TLS interface changes + to support one Security object per TlsTransport Change to how + SipMessage is constructed to provide access to the Transport* if it + came from the wire + +2003-08-13 19:18 jason + + * os/: DnsUtil.cxx, DnsUtil.hxx: added an interface to return SRV + records + +2003-08-13 19:17 jason + + * Security.cxx, Security.hxx: make initialize thread-safe + +2003-08-13 19:17 jason + + * DnsResolver.hxx: indentation + +2003-08-13 13:36 davidb + + * test/testSipMessage.cxx: header remove tests + +2003-08-13 13:35 davidb + + * os/MD5Stream.cxx, test/testData.cxx: use Data::Share interface + for overlay + +2003-08-13 13:34 davidb + + * os/: Data.cxx, Data.hxx: depracate bool overlay interface, add + Data::Share interface for overlay + +2003-08-13 13:33 davidb + + * Uri.cxx: share default scheme, avoid temporary Data in + + +2003-08-13 13:33 davidb + + * TransportSelector.cxx: use clear rather than "" assign + +2003-08-13 13:33 davidb + + * Transport.cxx: check Via exists + +2003-08-13 13:32 davidb + + * TimerQueue.cxx: remove Inserter include + +2003-08-13 13:32 davidb + + * SipStack.hxx: comment fix + +2003-08-13 13:32 davidb + + * SipMessage.cxx: check Vias exists + +2003-08-13 13:31 davidb + + * HeaderTypes.hxx: cosmetic + +2003-08-13 13:31 davidb + + * DnsResolver.cxx: avoide temporary Data in + + +2003-08-13 13:06 davidb + + * TransactionMap.cxx: remove include Inserter + +2003-08-13 13:05 davidb + + * Security.cxx: commented out reference to SSL_ERROR_WANT_ACCEPT + +2003-08-13 13:05 davidb + + * SdpContents.hxx: defined getMediumConnectionsm getEncryption + +2003-08-13 13:04 davidb + + * SdpContents.cxx: defined getConnections + +2003-08-13 13:03 davidb + + * Helper.cxx: check header exists + +2003-08-13 12:22 jason + + * Dialog.cxx, Dialog.hxx: added makeRequest + +2003-08-13 11:01 fluffy + + * os/DnsUtil.cxx: compile on Mac OSX + +2003-08-13 10:34 fluffy + + * Security.cxx: better error generation + +2003-08-13 10:33 fluffy + + * TlsTransport.cxx: added output of who peer is + +2003-08-13 10:32 fluffy + + * Contents.cxx: removed second content transfer encoding output + +2003-08-13 09:49 fluffy + + * test/.cvsignore: updated + +2003-08-13 09:49 fluffy + + * os/: Socket.cxx, Socket.hxx: added call no make blocking + +2003-08-13 09:45 fluffy + + * test/Makefile: [no log message] + +2003-08-13 08:38 jason + + * Uri.cxx, ParserCategories.cxx: better debug on parse fail + +2003-08-13 08:38 jason + + * X_msMsgsInvite.cxx: fix bug in parsing of X_msMsgsInvite + +2003-08-12 11:39 jason + + * SipStack.cxx: optimization of isMyDomain + +2003-08-10 03:21 wensong + + * ChangeLog, Makefile.am: [no log message] + +2003-08-09 14:27 jason + + * StatelessHandler.cxx: delete before invalidating iterator (fixed + crash on win32) + +2003-08-09 14:19 jason + + * os/: Log.cxx, Log.hxx, Logger.hxx: added simple file-based + logging + +2003-08-08 19:04 wensong + + * ChangeLog, Makefile.am, config.hxx.in: [no log message] + +2003-08-08 01:33 wensong + + * Makefile.am: [no log message] + +2003-08-08 01:00 wensong + + * ChangeLog, Makefile.am: [no log message] + +2003-08-07 23:15 wensong + + * Makefile.am: [no log message] + +2003-08-07 22:53 wensong + + * ChangeLog, Makefile.am: [no log message] + +2003-08-07 13:50 jason + + * Makefile, os/DnsUtil.cxx, os/DnsUtil.hxx: added simple DnsUtil + class + +2003-08-07 09:20 jason + + * os/HashMap.hxx: define a simple hash function for pointers + +2003-08-07 09:19 jason + + * UdpTransport.cxx: added debug in error case + +2003-08-07 09:18 jason + + * TcpTransport.cxx: reindent + +2003-08-07 09:18 jason + + * SipStack.hxx: make some virtual functions + +2003-08-07 01:17 wensong + + * ChangeLog, TcpTransport.cxx: [no log message] + +2003-08-06 09:25 jason + + * Executive.cxx, Makefile, SipStack.cxx, SipStack.hxx, + StatelessHandler.cxx: added support for stateless proxies + +2003-08-06 09:15 jason + + * SipMessage.hxx: add support for getDestination setDestination + +2003-08-05 08:48 jason + + * TransportSelector.cxx: don't pop the route in the + TransportSelector - this is a TU function + +2003-08-05 08:47 jason + + * GenericContents.cxx: fix assignment + +2003-08-01 01:17 wensong + + * ChangeLog, Makefile.am: [no log message] + +2003-07-28 19:29 jason + + * os/Log.hxx: [no log message] + +2003-07-28 19:29 jason + + * os/Log.cxx: added toType + +2003-07-28 18:55 jason + + * os/.cvsignore: [no log message] + +2003-07-28 18:55 jason + + * UdpTransport.cxx: add debug + +2003-07-28 18:53 jason + + * SipStack.cxx: make it more eficient + +2003-07-28 03:50 jason + + * DnsResolver.cxx: reindent but minor fix for stateless proxy + removed dependency on TransactionState + +2003-07-28 03:45 davidb + + * Contents.cxx, Contents.hxx, GenericContents.cxx, + GenericContents.hxx, Makefile, X_msMsgsInvite.cxx, + X_msMsgsInvite.hxx: generic contents + +2003-07-28 03:43 davidb + + * SdpContents.hxx, SipStack.hxx: [no log message] + +2003-07-28 03:05 wensong + + * Security.hxx: [no log message] + +2003-07-27 21:55 wensong + + * ChangeLog, Security.cxx, Security.hxx: [no log message] + +2003-07-27 19:43 jason + + * StatelessHandler.cxx, StatelessHandler.hxx: for stateless proxies + +2003-07-27 19:35 jason + + * Makefile.am: add support for redhat-9.0 + +2003-07-16 14:04 davidb + + * test/torture-test.txt: fixed some whitespace + +2003-07-16 14:04 davidb + + * test/testSpeed.cxx: don't over ride logging level + +2003-07-16 14:03 davidb + + * test/testParserCategories.cxx: added test for quoted and + non-quoted display name in NameAddr. don't like how it works... + +2003-07-16 14:03 davidb + + * test/testData.cxx: test preallocated append + +2003-07-16 14:01 davidb + + * test/SipTortureTests.cxx: empty header still exists + +2003-07-16 14:01 davidb + + * Uri.cxx: comment + +2003-07-16 14:00 davidb + + * Dialog.cxx: copy Routes only if they exist + +2003-07-16 13:59 davidb + + * os/Data.cxx: removed gratuitous assignments to 0 after delete + +2003-07-14 15:49 davidb + + * test/testSdp.cxx: added test with missing colon in bandwidth (b=) + +2003-07-14 15:48 davidb + + * os/ParseBuffer.cxx: added [CRLF] to escapeAndAnnotate for + readability through syslog + +2003-07-14 15:47 davidb + + * SdpContents.cxx: fail on bad bandwith line rather than scan past + end of line (e.g. missing colon) + +2003-07-14 13:52 davidb + + * TransportSelector.cxx: check for Route existance before checking + if empty + +2003-07-07 20:36 ryker + + * Makefile.am: Fix hash generation when the source directory is not + the build directory. + +2003-07-07 15:27 davidb + + * test/testSipMessage.cxx: comma encoding, cleaned up branch + parameters + +2003-07-07 15:23 davidb + + * test/testDataPerformance.cxx: added characater and char* to test + +2003-07-07 15:22 davidb + + * os/ParseBuffer.cxx, test/testData.cxx: replaced a few asserts + with fails + +2003-07-07 15:22 davidb + + * os/Data.cxx: use append for all operator+= adeed invariant assert + to append + +2003-07-07 15:20 davidb + + * SipMessage.cxx: replaced const access throws with asserts + factored HeaderFieldValueList encode calls + +2003-07-07 15:19 davidb + + * ParserContainer.hxx: comma encoding + +2003-07-07 15:16 davidb + + * ParserCategory.hxx: comma encoding const enforcing + +2003-07-07 15:16 davidb + + * ParserCategory.cxx: const enforcing + +2003-07-07 15:16 davidb + + * ParserCategories.hxx: comma encoding StringCategory constructor + against Data + +2003-07-07 15:15 davidb + + * ParserCategories.cxx: StringCategory constructor against Data + +2003-07-07 15:14 davidb + + * HeaderTypes.hxx, Headers.cxx: added comma encoding + +2003-07-07 15:14 davidb + + * HeaderHash.gperf: shortform of Supported + +2003-07-07 15:14 davidb + + * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx: allow + valueless header encode + +2003-07-05 19:28 ryker + + * test/: testEmbedded.cxx, testEmptyHeader.cxx, testSipMessage.cxx: + Fix some clientData in Via headers. + +2003-07-03 14:10 ryker + + * BranchParameter.cxx, BranchParameter.hxx: Implement a const + version of clientData(). + +2003-07-03 13:11 ryker + + * Makefile.am: Teach the new build system how to generate the gperf + hashes. + +2003-07-03 12:07 ryker + + * os/Data.hxx: Document invariant for Data objects with !mMine. + +2003-07-03 09:25 ryker + + * os/Data.cxx: Fix Data mCapacity tracking in two places. + +2003-06-30 16:28 jason + + * TransactionMap.cxx, SipStack.cxx, DnsResolver.cxx: [no log + message] + +2003-06-30 16:27 jason + + * TransactionState.cxx: don't pass ACK to TU again + +2003-06-30 15:00 ryker + + * TransactionState.cxx: Fix two crashes that could happen during an + extremely coordinated attack on a reSIProcate-based SIP element. + +2003-06-30 09:55 ryker + + * torture.txt: torture.txt does not belong in the sources + directory. It is indirectly already in reSIProcate as + resiprocate/test/SipTortureTests.cxx. + +2003-06-26 18:38 ryker + + * test/.cvsignore: Ignore more. + +2003-06-26 18:08 ryker + + * TransactionState.cxx: Fix a crash that happens when a final + response retransmission is received at the INVITE client + transaction *after* the ACK has been sent. + +2003-06-24 18:02 jason + + * TransactionMap.cxx, TransactionState.cxx, TransactionState.hxx: + ryan's memory leak fixes merged in also fixed a problem with CANCEL + transaction cleanup on stack shutdown + +2003-06-24 18:01 jason + + * ShutdownMessage.hxx, SipStack.cxx, SipStack.hxx: simple shutdown + method (not finished yet, but tested) + +2003-06-24 17:56 davidb + + * test/testParserCategories.cxx: test added user param to set of + parameters that are moved to Uri for NameAddr + +2003-06-24 17:56 davidb + + * ParserCategories.cxx: added user param to set of parameters that + are moved to Uri for NameAddr + +2003-06-24 14:11 ryker + + * test/.cvsignore: Ignore more. + +2003-06-24 12:20 ryker + + * TransactionState.cxx: Respond to the TU with a 481 if a CANCEL is + sent down when no corresponding INVITE transaction is known about. + +2003-06-23 10:35 jason + + * Helper.cxx: remove call-id from nonce + +2003-06-23 10:34 jason + + * ParserCategory.cxx: fix initializer + +2003-06-19 19:48 ryker + + * TransactionState.cxx: Fix a large number of stack leaks. + +2003-06-19 09:40 ryker + + * test/: limpc.cxx, testApplicationSip.cxx, testData.cxx, + testDataPerformance.cxx, testDigestAuthentication.cxx, + testEmbedded.cxx, testEmptyHeader.cxx, testLogger.cxx, + testMessageWaiting.cxx, testMultipartMixedContents.cxx, + testParseBuffer.cxx, testPlainContents.cxx, testRandomHex.cxx, + testSdp.cxx, testServer.cxx, testSipFrag.cxx, testSipMessage.cxx, + testSipMessageMemory.cxx, testTcpTransport.cxx, testTimer.cxx, + testUri.cxx: Make sure tests return 0 on successful completion. + +2003-06-19 09:27 ryker + + * test/Makefile.am: Arrange for all tests to be run. Remove tests + appearing to be bogus (note: revisit these). + +2003-06-19 09:07 ryker + + * test/Makefile.am: Define first test to automagically run as an + example of how to do this. + +2003-06-19 09:07 ryker + + * test/testParserCategories.cxx: Return 0 from this test on + completion. + +2003-06-18 17:20 ryker + + * Makefile.am, test/Makefile.am: Get tests working under autoconf. + +2003-06-18 16:08 ryker + + * test/SipTortureTests.cxx: Make this compile. + +2003-06-18 15:50 ryker + + * UnknownHeaderType.cxx, UnknownHeaderType.hxx: Allow creation from + Data in addition to char*. + +2003-06-18 15:46 ryker + + * UdpTransport.cxx: Change log level of message to be consistent + with the TCP transport. + +2003-06-18 15:42 ryker + + * DnsResolver.cxx, TransactionState.cxx: Plug memory leaks. + +2003-06-18 13:26 ryker + + * test/testParserCategories.cxx: Test clientData which was put back + in the branch. + +2003-06-18 13:26 ryker + + * BranchParameter.cxx, BranchParameter.hxx: Put clientData back in + the branch. + +2003-06-17 18:10 davidb + + * Uri.cxx, test/testUri.cxx: GreaterQ correct + +2003-06-17 17:59 davidb + + * SdpContents.cxx: allow codec parse failure -- discard bad codec + +2003-06-17 17:57 davidb + + * Uri.hxx: GreaterQ + +2003-06-17 17:53 davidb + + * Uri.cxx, test/testSdp.cxx: allow codec parse failures -- discard + codec + +2003-06-17 16:17 davidb + + * os/: Data.cxx, Data.hxx: operator<=, operator>= + +2003-06-12 18:40 alan + + * TlsTransport.cxx: Oops forgot to check in USE_SSL changes here. + +2003-06-12 17:07 alan + + * Security.hxx, SipStack.cxx, SipStack.hxx, TlsTransport.cxx, + TransportSelector.cxx, TuIM.cxx, libSipImp.cxx: Made changes to + USE_SSL defines and added typedefs for types when openssl is not + being used. This preserves object sizes between configurations. + This is a "Good Thing". Right Jason? Modified Files: .cvsignore + resiprocate/Security.hxx resiprocate/SipStack.cxx + resiprocate/SipStack.hxx resiprocate/TlsTransport.cxx + resiprocate/TransportSelector.cxx resiprocate/TuIM.cxx + resiprocate/libSipImp.cxx + +2003-06-11 19:37 jason + + * test/testSpeed.cxx: [no log message] + +2003-06-05 15:12 jason + + * os/: Log.hxx, Logger.hxx: added support for log to cerr + +2003-06-05 13:17 ryker + + * UdpTransport.cxx: Fix some really confusing indentation. + +2003-06-04 10:14 ryker + + * Uri.cxx: An even uglier fix is needed for the Sun Forte compiler. + This one was tested with the checked in testUri unit test and it + compiles and works. + +2003-06-04 09:12 ryker + + * Uri.cxx: Hack in a workaround for the Solaris Forte STL + implementation which does not support a list.sort() function taking + a BinaryPredicate. + +2003-06-04 09:09 ryker + + * test/testUri.cxx: Test order irrelevance of unknown parameters. + +2003-06-03 08:55 ryker + + * os/RecursiveMutex.cxx: Hack to make reSIProcate compile with the + Intel C++ compiler. + +2003-06-03 08:15 ryker + + * os/Fifo.hxx: Squash warning produced by the Intel C++ compiler. + +2003-06-02 20:29 ryker + + * os/compat.hxx: Minor cleanup and temporary hack for Solaris + compilation. + +2003-06-02 20:25 ryker + + * config.hxx.in: Get rid of non-reSIProcate specific stuff. + +2003-06-02 20:24 ryker + + * Makefile.am: Install the library build configuration header. + +2003-06-02 14:14 ryker + + * os/: compat.hxx, vmd5.hxx: Remove Sun-specific conditional code + and replace with autoconf probed results. This might just work on + another non-Sun platform too now. + +2003-06-02 14:13 ryker + + * config.hxx.in: Let autoconf find <sys/int_types.h> if it exists. + +2003-06-02 13:52 ryker + + * os/: BaseException.hxx, CircularBuffer.hxx, Coders.hxx, + Condition.hxx, CountStream.hxx, Data.hxx, DataStream.hxx, Fifo.hxx, + HashMap.hxx, Inserter.hxx, Lock.hxx, Lockable.hxx, Log.hxx, + Logger.hxx, MD5Stream.hxx, Mutex.hxx, ParseBuffer.hxx, RWMutex.hxx, + Random.hxx, RecursiveMutex.hxx, Socket.hxx, Subsystem.hxx, + SysLogBuf.hxx, SysLogStream.hxx, ThreadIf.hxx, Timer.hxx, + compat.hxx, vmd5.hxx, vthread.hxx: Fix include guards to avoid + macro namespace conflicts. Some of these are just style changes to + make things consistent across the project. + +2003-06-02 13:33 ryker + + * Transport.cxx, config.hxx.in: Ascertain the existence of + <sys/sockio.h> at configure-time. This means a platform other than + Solaris that uses this will pick it up too. + +2003-06-02 13:27 ryker + + * OctetContents.hxx, SdpContents.hxx, SendingMessage.hxx, + SipFrag.hxx, SipMessage.hxx, SipSession.hxx, SipStack.hxx, + Subscription.hxx, Symbols.hxx, TcpTransport.hxx, TimerMessage.hxx, + TimerQueue.hxx, TlsTransport.hxx, TransactionMap.hxx, + TransactionState.hxx, TransactionTerminated.hxx, Transport.hxx, + TransportMessage.hxx, TransportSelector.hxx, TuIM.hxx, TuShim.hxx, + TuUa.hxx, UdpTransport.hxx, UnknownHeaderType.hxx, + UnknownParameter.hxx, UnknownParameterType.hxx, Uri.hxx, + XMLCursor.hxx, XPidf.hxx: Fix include guards to avoid macro + namespace conflicts. + +2003-06-02 13:23 ryker + + * DnsResolver.cxx: Fix Sun macro guard so as to compile with the + GNU toolchain too. + +2003-06-02 13:03 ryker + + * Parameter.hxx, ParameterTypeEnums.hxx, ParameterTypes.hxx, + ParseException.hxx, ParserCategories.hxx, ParserCategory.hxx, + ParserContainer.hxx, ParserContainerBase.hxx, Pidf.hxx, + Pkcs7Contents.hxx, PlainContents.hxx, Preparse.hxx, + QopParameter.hxx, QuotedDataParameter.hxx, Registration.hxx, + ReliabilityMessage.hxx, RportParameter.hxx: Fix include guards to + avoid macro namespace conflicts. + +2003-06-02 12:29 ryker + + * Message.hxx, MessageWaitingContents.hxx, MethodTypes.hxx, + MultipartMixedContents.hxx, MultipartSignedContents.hxx: Fix + include guards to avoid macro namespace conflicts. + +2003-06-02 12:23 ryker + + * Executive.hxx, ExistsParameter.hxx, FloatParameter.hxx, + HeaderFieldValue.hxx, HeaderFieldValueList.hxx, HeaderTypes.hxx, + Headers.hxx, Helper.hxx, IntegerParameter.hxx, LazyParser.hxx: Fix + include guards to avoid macro namespace conflicts. + +2003-06-02 12:23 ryker + + * Embedded.hxx: Fix include guards to avoid macro namespace + conflicts. Add license. + +2003-06-02 12:22 ryker + + * DnsResolver.hxx: Add license. + +2003-06-02 12:22 ryker + + * Dialog.hxx: Fix include guards to avoid macro namespace + conflicts. Move license. + +2003-06-02 12:19 ryker + + * ApplicationSip.hxx, BranchParameter.hxx, Connection.hxx, + ConnectionMap.hxx, Contents.hxx, DataParameter.hxx, Dialog2.hxx, + DialogSet.hxx: Fix include guards to avoid macro namespace + conflicts. + +2003-06-02 12:14 ryker + + * Transport.cxx: Make array index const to placate the + Solaris/Forte compiler. + +2003-06-02 12:12 ryker + + * ParserCategory.cxx: Turn a const_iterator into a plain iterator + as the code that followed wasn't really preserving const-ness. + Fixes compile on Solaris/Forte. + +2003-06-02 11:55 ryker + + * SipMessage.hxx: Remove extra trailing semi-colon. Causes a + warning on Solaris/Forte. + +2003-06-02 11:54 ryker + + * ParserCategories.cxx: Quick Solaris portability hack. The right + thing to do, I think, is #if defined(__sun), #define __EXTENSIONS__ + right before #include <time.h>. + +2003-06-02 09:23 ryker + + * os/RecursiveMutex.cxx: Conditionalise linux-isms to fix + portability to Solaris and OpenBSD. + +2003-06-02 09:22 ryker + + * TransportSelector.cxx, TuIM.cxx, libSipImp.cxx, os/Random.cxx, + test/limpc.cxx, test/testTlsConnection.cxx: Pull in build + configuration header. + +2003-06-02 09:22 ryker + + * Transport.cxx: Fix Solaris port by #including necessary headers. + +2003-06-02 09:18 ryker + + * DnsResolver.cxx, DnsResolver.hxx, Security.cxx, Security.hxx, + SipStack.cxx, SipStack.hxx, TlsTransport.cxx: Pull in build + configuration header. + +2003-06-02 09:15 ryker + + * config.hxx.in: Add guard. + +2003-06-02 09:08 ryker + + * .cvsignore: Ignore more. Sort too. + +2003-06-02 09:06 ryker + + * .cvsignore: Ignore more. + +2003-06-02 09:04 ryker + + * Makefile.am, config.hxx.in: Impound autotools-based build system. + +2003-05-23 15:20 fluffy + + * sipstack.vcproj: gone + +2003-05-23 14:20 fluffy + + * Dialog.cxx, Dialog.hxx, TuIM.cxx: fix bug with dialogs and + registration + +2003-05-23 14:20 fluffy + + * os/Coders.cxx: comopile on windows + +2003-05-23 12:23 fluffy + + * resiprocate.vcproj: gone + +2003-05-23 12:12 fluffy + + * .cvsignore: update + +2003-05-23 12:05 fluffy + + * os/Logger.cxx: compile on windows + +2003-05-23 12:05 fluffy + + * sipstack.vcproj: no message + +2003-05-23 11:50 fluffy + + * Security.cxx, TimerMessage.cxx, TlsTransport.cxx, Transport.cxx, + sipstack.vcproj: compile on windows + +2003-05-20 16:36 ryker + + * test/.cvsignore: Tidy up the .cvsignore file and make it catch + all architectures. + +2003-05-18 18:58 fluffy + + * libSipImp.cxx: compile on mac + +2003-05-16 15:23 jason + + * TransactionState.cxx: debug + +2003-05-16 15:23 jason + + * SipMessage.cxx: throw when trying to compute a tid for a response + +2003-05-08 11:04 davidb + + * BranchParameter.cxx, BranchParameter.hxx, DnsResolver.cxx, + ParserCategory.cxx, ParserCategory.hxx, ParserContainer.hxx, + ParserContainerBase.hxx, RportParameter.hxx, SipMessage.cxx, + SipMessage.hxx: const header accessors - throw if header doesn't + exist, return const header + +2003-05-08 10:49 davidb + + * IntegerParameter.hxx, QuotedDataParameter.hxx, + UnknownParameter.hxx: explicit + +2003-05-08 10:48 davidb + + * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx: added + parsedEmpty -- header field value list may be empty but have parsed + elements + +2003-05-08 10:45 davidb + + * DataParameter.hxx, ExistsParameter.hxx, FloatParameter.hxx: + explicit + +2003-05-07 11:38 jason + + * Dialog.cxx: [no log message] + +2003-05-07 11:14 jason + + * test/testSipMessage.cxx: fix case + +2003-05-07 11:13 jason + + * test/InviteClient.cxx: changed interface + +2003-05-07 11:13 jason + + * Registration.cxx, Registration.hxx, SipSession.cxx, + SipSession.hxx: fix copyright + +2003-05-07 11:12 jason + + * Dialog.cxx, Dialog.hxx: remove interface to + createDialogAsUAC(request, response) fix problems referencing tags + which don't exist throw when no contact + +2003-05-07 11:10 jason + + * Dialog2.hxx: indent + +2003-05-04 20:19 fluffy + + * Security.cxx: fixed include for compile + +2003-05-04 18:45 fluffy + + * libSipImp.cxx: [no log message] + +2003-05-04 18:39 fluffy + + * TuIM.cxx, TuIM.hxx: added support for 200 response to a register + +2003-05-04 18:39 fluffy + + * test/Makefile: SSL debug stuff + +2003-05-04 17:25 fluffy + + * Makefile: add libSipImp + +2003-05-04 17:24 fluffy + + * test/limpc.cxx: more updates + +2003-05-04 17:24 fluffy + + * .cvsignore: mac stuff + +2003-05-04 17:21 fluffy + + * libSipImp.cxx, libSipImp.h: first cut - don't work yet + +2003-05-02 17:55 jason + + * Transport.cxx: probably broke mac again + +2003-05-02 17:54 jason + + * TransportSelector.cxx: fixed bug where topmost route wasn't being + popped before sending + +2003-05-01 14:57 fluffy + + * Security.cxx, Security.hxx, SipStack.cxx, test/limpc.cxx: added + SSL options for security + +2003-05-01 14:19 fluffy + + * Makefile: [no log message] + +2003-05-01 14:18 fluffy + + * os/RecursiveMutex.cxx: compile on mac + +2003-05-01 14:18 rohan + + * Makefile: unf*cked the Makefile (sorry) -r + +2003-05-01 14:14 fluffy + + * Security.cxx, Security.hxx, SipStack.cxx, SipStack.hxx, + test/limpc.cxx: added option to make tls server or client + +2003-05-01 13:44 rohan + + * Makefile: comment out RecursiveMutex.cxx from the Makefile as it + will not compile. + +2003-05-01 12:11 fluffy + + * Security.cxx: [no log message] + +2003-05-01 10:43 fluffy + + * ParserCategory.cxx: changed to not add a tag if the tag is empty + +2003-05-01 08:20 fluffy + + * test/.cvsignore: [no log message] + +2003-05-01 08:19 fluffy + + * ParserCategory.cxx: fixed problem with responses that have no tag + +2003-05-01 07:25 fluffy + + * Transport.cxx: compile on MAC - may have broken on linux + +2003-04-30 21:55 jason + + * Transport.cxx, Transport.hxx: added support for finding ip + address for interface + +2003-04-30 21:54 jason + + * Helper.cxx: remove debug + +2003-04-30 21:54 jason + + * Dialog.cxx, Dialog.hxx: store the dialogId including totag and + fromtag + +2003-04-30 19:04 ryker + + * Makefile: Don't add OctetContents.cxx twice. + +2003-04-30 16:57 fluffy + + * Security.cxx, TransportSelector.cxx: updated + +2003-04-30 16:57 fluffy + + * XPidf.cxx, XPidf.hxx: does not work yet + +2003-04-30 13:35 fluffy + + * Security.cxx, TlsTransport.cxx: fixed some TLS stuff + +2003-04-30 13:10 rjsparks + + * Makefile: Added Ryan's OctetContents + +2003-04-30 13:10 rjsparks + + * SipMessage.cxx: repaired literal string that wasn't terminated + +2003-04-30 12:32 ryker + + * SipMessage.cxx: Only extract contents if contents are available + to be extracted. + +2003-04-30 12:32 ryker + + * Makefile: Build OctetContents. + +2003-04-30 11:32 ryker + + * OctetContents.cxx, OctetContents.hxx, SipMessage.cxx: Return + application/octet-stream instead of NULL pointer when we don't have + a Content-Type defined. + +2003-04-30 08:53 alan + + * TcpTransport.cxx, TlsTransport.cxx, os/Data.cxx, os/Data.hxx, + os/compat.hxx: removed vocal2 references, added T_NAPTR and T_SRV + defines if missing + +2003-04-30 08:03 davidb + + * os/: Logger.cxx, Logger.hxx: fix to new recursive mutex + +2003-04-30 08:02 davidb + + * os/: RecursiveMutex.cxx, RecursiveMutex.hxx: [no log message] + +2003-04-30 06:57 fluffy + + * PlainContents.cxx, Security.cxx, TcpTransport.cxx, + TlsTransport.cxx, os/Log.cxx, test/limpc.cxx: updatged debuggging + info + +2003-04-29 13:22 davidb + + * Makefile, os/Logger.cxx, os/Logger.hxx, test/testLogger.cxx: use + recursive mutex for !NO_DEBUG + +2003-04-29 13:15 davidb + + * os/Mutex.hxx: removed VOCAL comment + +2003-04-26 21:09 fluffy + + * os/Timer.cxx: tried to add mac timer stuff - does not work yet + +2003-04-26 17:35 fluffy + + * DnsResolver.cxx: fixed for symbol being char* + +2003-04-26 17:30 fluffy + + * test/limpc.cxx: no real changes + +2003-04-26 17:30 fluffy + + * os/Socket.hxx: Support for mac + +2003-04-26 17:29 fluffy + + * Symbols.cxx, Symbols.hxx: Changed from Data to char* (Again) + because otherwise have static intializaiton order problems + +2003-04-26 17:28 fluffy + + * test/testSpeed.cxx: [no log message] + +2003-04-26 16:52 fluffy + + * test/limpc.cxx: fix ~ bug + +2003-04-26 16:52 fluffy + + * Security.cxx: added more debug + +2003-04-26 12:30 fluffy + + * test/: Makefile, limpc.cxx: added limpc back in + +2003-04-26 10:16 davidb + + * test/testLogger.cxx: test recursive logging + +2003-04-26 10:15 davidb + + * os/: ThreadIf.cxx, ThreadIf.hxx: typedef thread identifier type + +2003-04-26 10:15 davidb + + * os/: Logger.cxx, Logger.hxx: allow recursive DebugLogs; detect + deadlock in other logs when debug on + +2003-04-26 10:13 davidb + + * os/Log.hxx: indent + +2003-04-25 18:03 davidb + + * test/testSipMessage.cxx: add tests for brief() and auto_ptr a + leak or two + +2003-04-25 18:02 davidb + + * Uri.cxx: pre-allocate Data for getAor() + +2003-04-25 18:01 davidb + + * SipMessage.cxx: pre-allocate Data for brief() + +2003-04-25 18:01 davidb + + * Helper.cxx: pre-allocate a few Data + +2003-04-25 18:00 davidb + + * DnsResolver.cxx: pre-allocate a Data + +2003-04-24 15:02 ryker + + * DnsResolver.cxx: #include <memory> for std::auto_ptr. + +2003-04-24 10:43 davidb + + * test/testEmbedded.cxx: passes + +2003-04-24 10:42 davidb + + * Uri.cxx, test/testParserCategories.cxx: canonicalize host in + Uri::getAor() + +2003-04-21 16:03 jason + + * Uri.cxx, test/testParserCategories.cxx: aor for tel uri fixed + parse for tel uri in requri fixed + +2003-04-21 15:44 jason + + * ParserCategories.cxx, Uri.cxx, test/testParserCategories.cxx: + more fixes for tel uri related stuff + +2003-04-21 14:25 jason + + * test/testUri.cxx: added some more tel uri tests + +2003-04-21 14:25 jason + + * Uri.cxx, Uri.hxx: fixed a bug with tel uri parsing, url + comparisons, fromTel fixed again + +2003-04-17 15:20 davidb + + * test/testSipMessage.cxx: corrected empty header tests + +2003-04-17 15:20 davidb + + * SipMessage.cxx: handle empty headers (more or less) gracefully + +2003-04-17 15:18 davidb + + * ParameterTypes.hxx, ParserCategories.hxx: Token is comma + tokenizing + +2003-04-17 13:17 jason + + * TransactionState.cxx: added some debug + +2003-04-17 13:12 alan + + * Preparse.cxx: fixed empty header data handling at end of message + +2003-04-17 13:12 alan + + * test/testSipMessage.cxx: made pretty + +2003-04-17 12:19 jason + + * test/testSipMessage.cxx: added another test + +2003-04-17 09:01 jason + + * TransactionState.cxx: added a log message before asserting + +2003-04-17 08:58 jason + + * test/testSipMessage.cxx: added some tests for Allow-Events - + still fails + +2003-04-17 07:35 jason + + * Headers.hxx, SipMessage.cxx, SipMessage.hxx: fixes for + AllowEvents header + +2003-04-16 21:46 alan + + * doc/static/: Preparse.pdf, Preparse.png, Preparse.ps, + Preparse.svg: updates + +2003-04-16 21:43 alan + + * Preparse.cxx, Preparse.hxx, PreparseDiagnostic.cxx, + test/Makefile, test/testEmptyHeader.cxx: Added new emptyHeader + flag. Added test driver for empty headers. + +2003-04-16 20:34 alan + + * TransactionState.cxx, Preparse.cxx: Updates for empty headers. + Updates for UTF-8 cleanliness. + +2003-04-16 20:32 alan + + * PreparseDiagnostic.cxx: Added new diagnostic support file. + +2003-04-16 14:50 davidb + + * os/: Data.cxx, Data.hxx: prefix is const + +2003-04-14 15:03 ryker + + * Preparse.cxx: Mask off high-ASCII input to the Preparser. + +2003-04-10 10:57 davidb + + * test/testSipMessage.cxx: test for just in time parsing during + comparison of unparsed headers + +2003-04-10 10:56 davidb + + * ParserCategories.cxx: our just in time parser fix was a little + over zealous sufficient to use accessors to ensure parsed + +2003-04-09 20:24 jason + + * ParserCategories.cxx, Uri.cxx, test/testParserCategories.cxx, + test/testUri.cxx: fixed a particularly nasty bug related to just in + time parsing on comparisons + +2003-04-09 13:07 alan + + * doc/static/: Preparse.pdf, Preparse.png, Preparse.svg, + srv-inv-fsm.pdf, srv-inv-fsm.png, srv-inv-fsm.svg, + srv-inv-tree.pdf, srv-inv-tree.png, srv-inv-tree.svg: updates + +2003-04-07 15:41 davidb + + * os/Logger.hxx: pretty + +2003-04-07 15:41 davidb + + * UdpTransport.cxx: indent + +2003-04-07 15:41 davidb + + * SipMessage.cxx: set mContents to 0 after deleting + +2003-04-06 16:50 jason + + * TransactionState.cxx: fix problem with assert(0) when CANCEL + crosses INVITE/200. ignore the timer in this case. changed some + debug + +2003-04-04 20:09 jason + + * TransactionState.cxx: fix retransmissions of invites on client + transaction removed termination event for stateless + +2003-04-04 20:09 jason + + * Helper.cxx: added debug + +2003-04-04 10:48 ryker + + * os/ParseBuffer.cxx: Really fix the parse error printing problem. + +2003-04-04 09:34 ryker + + * os/ParseBuffer.cxx: Fix off by one underflow when formatting + parse error messages. + +2003-04-03 19:23 jason + + * Helper.cxx, Helper.hxx: fix registration methods. this does + change how register works. the way it used to work was always wrong + +2003-04-03 19:22 jason + + * Uri.cxx, Uri.hxx: fixed tel uri conversion to sip: + +2003-04-03 15:58 ryker + + * TransactionState.cxx: If we see a message arrive from the wire + with no Via, drop it. + +2003-04-03 09:56 ryker + + * UdpTransport.cxx: If the preparse machine tells us a message was + fragmented, reset the preparse machine state instead of running off + the rails on the next message. The alternative is to save the + "unpreparsed" bit of the message for concatenation with the next + datagram (not implemented yet). + +2003-04-02 10:58 ryker + + * os/Logger.hxx: cpp knows about #undef, not #undefine. + +2003-04-01 15:00 ryker + + * Helper.cxx: Recover better from being dealt an out of range port + number. + +2003-03-28 18:30 jason + + * DnsResolver.cxx, DnsResolver.hxx, Message.hxx, + ReliabilityMessage.hxx, SipMessage.cxx, SipMessage.hxx, + SipStack.hxx, TimerMessage.cxx, TimerMessage.hxx, + TransactionState.cxx, TransactionState.hxx, + TransactionTerminated.hxx, TransportMessage.hxx: separate client + and server transaction maps to support spirals in a proxy tu - kind + of gross, but necessary + +2003-03-28 13:14 jason + + * ParserCategories.hxx, ParserContainer.hxx, Uri.hxx: [no log + message] + +2003-03-28 12:47 ryker + + * SipMessage.cxx: Permit setContents(0) and interpret that a + "delete contents". + +2003-03-28 12:44 ryker + + * Helper.cxx: Add a default reason phrase for 202 message, + "Accepted". + +2003-03-27 18:47 jason + + * UdpTransport.cxx: close the udp file descriptor on destruction + +2003-03-27 15:53 jason + + * Helper.cxx, Helper.hxx: added fromAor + +2003-03-24 22:33 jason + + * ApplicationSip.cxx, ApplicationSip.hxx, BranchParameter.cxx, + BranchParameter.hxx, Connection.cxx, Connection.hxx, + ConnectionMap.cxx, ConnectionMap.hxx, Contents.cxx, Contents.hxx, + DataParameter.cxx, DataParameter.hxx, Dialog.cxx, Dialog.hxx, + Dialog2.cxx, Dialog2.hxx, DialogSet.cxx, DialogSet.hxx, + DnsResolver.cxx, DnsResolver.hxx, Embedded.cxx, Embedded.hxx, + Executive.cxx, Executive.hxx, ExistsParameter.cxx, + ExistsParameter.hxx, FloatParameter.cxx, FloatParameter.hxx, + HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, HeaderHash.cxx, + HeaderHash.hxx, HeaderTypes.cxx, HeaderTypes.hxx, Headers.cxx, + Headers.hxx, Helper.cxx, Helper.hxx, IntegerParameter.cxx, + IntegerParameter.hxx, LazyParser.cxx, LazyParser.hxx, Message.cxx, + Message.hxx, MessageWaitingContents.cxx, + MessageWaitingContents.hxx, MethodHash.cxx, MethodHash.hxx, + MethodTypes.cxx, MethodTypes.hxx, MultipartMixedContents.cxx, + MultipartMixedContents.hxx, MultipartSignedContents.cxx, + MultipartSignedContents.hxx, Parameter.cxx, Parameter.hxx, + ParameterHash.cxx, ParameterHash.hxx, ParameterTypeEnums.hxx, + ParameterTypes.cxx, ParameterTypes.hxx, ParseException.hxx, + ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, + ParserCategory.hxx, ParserContainer.hxx, ParserContainerBase.hxx, + Pidf.cxx, Pidf.hxx, Pkcs7Contents.cxx, Pkcs7Contents.hxx, + PlainContents.cxx, PlainContents.hxx, Preparse.cxx, Preparse.hxx, + QopParameter.cxx, QopParameter.hxx, QuotedDataParameter.cxx, + QuotedDataParameter.hxx, Registration.cxx, Registration.hxx, + ReliabilityMessage.hxx, RportParameter.cxx, RportParameter.hxx, + SdpContents.cxx, SdpContents.hxx, Security.cxx, Security.hxx, + SendingMessage.cxx, SendingMessage.hxx, SipFrag.cxx, SipFrag.hxx, + SipMessage.cxx, SipMessage.hxx, SipSession.cxx, SipSession.hxx, + SipStack.cxx, SipStack.hxx, Subscription.cxx, Subscription.hxx, + Symbols.cxx, Symbols.hxx, TcpTransport.cxx, TcpTransport.hxx, + TimerMessage.cxx, TimerMessage.hxx, TimerQueue.cxx, TimerQueue.hxx, + TlsTransport.cxx, TlsTransport.hxx, TransactionMap.cxx, + TransactionMap.hxx, TransactionState.cxx, TransactionState.hxx, + TransactionTerminated.hxx, Transport.cxx, Transport.hxx, + TransportMessage.hxx, TransportSelector.cxx, TransportSelector.hxx, + TuIM.cxx, TuIM.hxx, TuShim.hxx, TuUa.hxx, UdpTransport.cxx, + UdpTransport.hxx, UnknownHeaderType.cxx, UnknownHeaderType.hxx, + UnknownParameter.cxx, UnknownParameter.hxx, + UnknownParameterType.cxx, UnknownParameterType.hxx, Uri.cxx, + Uri.hxx, XMLCursor.cxx, XMLCursor.hxx, os/BaseException.cxx, + os/BaseException.hxx, os/CircularBuffer.hxx, os/Coders.cxx, + os/Coders.hxx, os/Condition.cxx, os/Condition.hxx, + os/CountStream.cxx, os/CountStream.hxx, os/Data.cxx, os/Data.hxx, + os/DataStream.cxx, os/DataStream.hxx, os/Fifo.hxx, os/HashMap.hxx, + os/Inserter.hxx, os/Lock.cxx, os/Lock.hxx, os/Lockable.hxx, + os/Log.cxx, os/Log.hxx, os/Logger.cxx, os/Logger.hxx, + os/MD5Stream.cxx, os/MD5Stream.hxx, os/Mutex.cxx, os/Mutex.hxx, + os/ParseBuffer.cxx, os/ParseBuffer.hxx, os/RWMutex.cxx, + os/RWMutex.hxx, os/Random.cxx, os/Random.hxx, os/Socket.cxx, + os/Socket.hxx, os/Subsystem.cxx, os/Subsystem.hxx, + os/SysLogBuf.hxx, os/SysLogStream.hxx, os/ThreadIf.cxx, + os/ThreadIf.hxx, os/Timer.cxx, os/Timer.hxx, os/compat.hxx, + os/vmd5.cxx, os/vmd5.hxx, os/vthread.hxx, test/InviteClient.cxx, + test/InviteClient.hxx, test/InviteServer.cxx, + test/InviteServer.hxx, test/Register.cxx, test/Register.hxx, + test/Registrar.cxx, test/Resolver.cxx, test/Resolver.hxx, + test/SipTortureTests.cxx, test/TestSupport.cxx, + test/TestSupport.hxx, test/Transceiver.cxx, test/Transceiver.hxx, + test/digcalc.hxx, test/lg.cxx, test/limpc.cxx, test/test1.cxx, + test/test2.cxx, test/testApplicationSip.cxx, test/testClient.cxx, + test/testCoders.cxx, test/testCountStream.cxx, test/testData.cxx, + test/testDataPerformance.cxx, test/testDataStream.cxx, + test/testDigestAuthentication.cxx, test/testDnsResolver.cxx, + test/testEmbedded.cxx, test/testHash.cxx, + test/testHeaderFieldValueList.cxx, test/testLockStep.cxx, + test/testLogger.cxx, test/testMessageWaiting.cxx, + test/testMultipartMixedContents.cxx, + test/testNameAddrParamExclusions.cxx, + test/testNonInviteClientTx.cxx, test/testNonInviteServerTx.cxx, + test/testParseBuffer.cxx, test/testParserCategories.cxx, + test/testPlainContents.cxx, test/testPreparse.cxx, + test/testRandomHex.cxx, test/testSdp.cxx, test/testServer.cxx, + test/testSimpleLeak.cxx, test/testSipFrag.cxx, + test/testSipMessage.cxx, test/testSipMessageMemory.cxx, + test/testSipStack1.cxx, test/testSipStackInvite.cxx, + test/testSpeed.cxx, test/testTcpTransport.cxx, + test/testThreadIf.cxx, test/testTimer.cxx, + test/testTlsConnection.cxx, test/testTransactionFSM.cxx, + test/testTypes.cxx, test/testUdp.cxx, test/testUri.cxx, + test/testXMLCursor.cxx, test/testpp.cxx: rename namespace to resip + +2003-03-24 15:37 jason + + * test/Makefile: directory reorg to sip/resiprocate, etc. + +2003-03-24 15:30 jason + + * os/Makefile: directory reorg to sip/resiprocate, etc. + +2003-03-24 15:25 jason + + * ApplicationSip.cxx, ApplicationSip.hxx, BranchParameter.cxx, + BranchParameter.hxx, Connection.cxx, Connection.hxx, + ConnectionMap.cxx, ConnectionMap.hxx, Contents.cxx, Contents.hxx, + DataParameter.cxx, DataParameter.hxx, Dialog.cxx, Dialog.hxx, + Dialog2.cxx, Dialog2.hxx, DialogSet.cxx, DialogSet.hxx, + DnsResolver.cxx, DnsResolver.hxx, Embedded.cxx, Executive.cxx, + Executive.hxx, ExistsParameter.cxx, ExistsParameter.hxx, + FloatParameter.cxx, FloatParameter.hxx, HeaderFieldValue.cxx, + HeaderFieldValue.hxx, HeaderFieldValueList.cxx, HeaderHash.cxx, + HeaderTypes.cxx, HeaderTypes.hxx, Headers.cxx, Headers.hxx, + Helper.cxx, Helper.hxx, IntegerParameter.cxx, IntegerParameter.hxx, + LazyParser.cxx, Makefile, Message.cxx, Message.hxx, + MessageWaitingContents.cxx, MessageWaitingContents.hxx, + MethodHash.cxx, MethodTypes.cxx, MultipartMixedContents.cxx, + MultipartMixedContents.hxx, MultipartSignedContents.cxx, + MultipartSignedContents.hxx, Parameter.cxx, Parameter.hxx, + ParameterHash.cxx, ParameterTypeEnums.hxx, ParameterTypes.cxx, + ParameterTypes.hxx, ParseException.hxx, ParserCategories.cxx, + ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, + ParserContainer.hxx, ParserContainerBase.hxx, Pidf.cxx, Pidf.hxx, + Pkcs7Contents.cxx, Pkcs7Contents.hxx, PlainContents.cxx, + PlainContents.hxx, Preparse.cxx, Preparse.hxx, QopParameter.cxx, + QopParameter.hxx, QuotedDataParameter.cxx, QuotedDataParameter.hxx, + Registration.cxx, Registration.hxx, ReliabilityMessage.hxx, + RportParameter.cxx, RportParameter.hxx, SdpContents.cxx, + SdpContents.hxx, Security.cxx, SendingMessage.cxx, + SendingMessage.hxx, SipFrag.cxx, SipFrag.hxx, SipMessage.cxx, + SipMessage.hxx, SipSession.cxx, SipSession.hxx, SipStack.cxx, + SipStack.hxx, Subscription.cxx, Subscription.hxx, Symbols.cxx, + Symbols.hxx, TcpTransport.cxx, TcpTransport.hxx, TimerMessage.cxx, + TimerMessage.hxx, TimerQueue.cxx, TimerQueue.hxx, TlsTransport.cxx, + TlsTransport.hxx, TransactionMap.cxx, TransactionMap.hxx, + TransactionState.cxx, TransactionState.hxx, Transport.cxx, + Transport.hxx, TransportMessage.hxx, TransportSelector.cxx, + TransportSelector.hxx, TuIM.cxx, TuIM.hxx, TuShim.hxx, TuUa.hxx, + UdpTransport.cxx, UdpTransport.hxx, UnknownHeaderType.cxx, + UnknownHeaderType.hxx, UnknownParameter.cxx, UnknownParameter.hxx, + UnknownParameterType.cxx, UnknownParameterType.hxx, Uri.cxx, + Uri.hxx, XMLCursor.cxx, XMLCursor.hxx, os/BaseException.cxx, + os/BaseException.hxx, os/Coders.cxx, os/Coders.hxx, + os/Condition.cxx, os/CountStream.cxx, os/CountStream.hxx, + os/Data.cxx, os/Data.hxx, os/DataStream.cxx, os/Fifo.hxx, + os/Lock.cxx, os/Lock.hxx, os/Log.cxx, os/Log.hxx, os/Logger.cxx, + os/Logger.hxx, os/MD5Stream.cxx, os/MD5Stream.hxx, os/Mutex.cxx, + os/Mutex.hxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, + os/Random.cxx, os/Random.hxx, os/Socket.cxx, os/Subsystem.cxx, + os/Subsystem.hxx, os/SysLogStream.hxx, os/ThreadIf.cxx, + os/ThreadIf.hxx, os/Timer.cxx, os/Timer.hxx, os/vmd5.cxx, + os/vmd5.hxx, test/InviteClient.cxx, test/InviteClient.hxx, + test/InviteServer.cxx, test/InviteServer.hxx, test/Makefile, + test/Register.cxx, test/Register.hxx, test/Registrar.cxx, + test/Registrar.hxx, test/Resolver.cxx, test/Resolver.hxx, + test/SipTortureTests.cxx, test/TestSupport.cxx, + test/TestSupport.hxx, test/Transceiver.cxx, test/Transceiver.hxx, + test/digcalc.hxx, test/lg.cxx, test/limpc.cxx, test/test1.cxx, + test/test2.cxx, test/testApplicationSip.cxx, test/testClient.cxx, + test/testCoders.cxx, test/testCountStream.cxx, test/testData.cxx, + test/testDataPerformance.cxx, test/testDataStream.cxx, + test/testDigestAuthentication.cxx, test/testDnsResolver.cxx, + test/testEmbedded.cxx, test/testHash.cxx, + test/testHeaderFieldValueList.cxx, test/testLockStep.cxx, + test/testLogger.cxx, test/testMessageWaiting.cxx, + test/testMultipartMixedContents.cxx, + test/testNameAddrParamExclusions.cxx, + test/testNonInviteClientTx.cxx, test/testNonInviteServerTx.cxx, + test/testParseBuffer.cxx, test/testParserCategories.cxx, + test/testPlainContents.cxx, test/testPreparse.cxx, + test/testRandomHex.cxx, test/testSdp.cxx, test/testServer.cxx, + test/testSimpleLeak.cxx, test/testSipFrag.cxx, + test/testSipMessage.cxx, test/testSipMessageMemory.cxx, + test/testSipStack1.cxx, test/testSipStackInvite.cxx, + test/testSpeed.cxx, test/testTcpTransport.cxx, + test/testThreadIf.cxx, test/testTimer.cxx, + test/testTlsConnection.cxx, test/testTransactionFSM.cxx, + test/testTypes.cxx, test/testUdp.cxx, test/testUri.cxx, + test/testXMLCursor.cxx, test/testpp.cxx: directory reorg to + sip/resiprocate, etc. + +2003-03-24 14:42 jason + + * ApplicationSip.cxx, ApplicationSip.hxx, BranchParameter.cxx, + BranchParameter.hxx, Connection.cxx, Connection.hxx, + ConnectionMap.cxx, ConnectionMap.hxx, Contents.cxx, Contents.hxx, + DataParameter.cxx, DataParameter.hxx, Dialog.cxx, Dialog.hxx, + Dialog2.cxx, Dialog2.hxx, DialogSet.cxx, DialogSet.hxx, + DnsResolver.cxx, DnsResolver.hxx, Embedded.cxx, Executive.cxx, + Executive.hxx, ExistsParameter.cxx, ExistsParameter.hxx, + FloatParameter.cxx, FloatParameter.hxx, HeaderFieldValue.cxx, + HeaderFieldValue.hxx, HeaderFieldValueList.cxx, HeaderHash.cxx, + HeaderTypes.cxx, HeaderTypes.hxx, Headers.cxx, Headers.hxx, + Helper.cxx, Helper.hxx, IntegerParameter.cxx, IntegerParameter.hxx, + LazyParser.cxx, Makefile, Message.cxx, Message.hxx, + MessageWaitingContents.cxx, MessageWaitingContents.hxx, + MethodHash.cxx, MethodTypes.cxx, MultipartMixedContents.cxx, + MultipartMixedContents.hxx, MultipartSignedContents.cxx, + MultipartSignedContents.hxx, Parameter.cxx, Parameter.hxx, + ParameterHash.cxx, ParameterTypeEnums.hxx, ParameterTypes.cxx, + ParameterTypes.hxx, ParseException.hxx, ParserCategories.cxx, + ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, + ParserContainer.hxx, ParserContainerBase.hxx, Pidf.cxx, Pidf.hxx, + Pkcs7Contents.cxx, Pkcs7Contents.hxx, PlainContents.cxx, + PlainContents.hxx, Preparse.cxx, Preparse.hxx, QopParameter.cxx, + QopParameter.hxx, QuotedDataParameter.cxx, QuotedDataParameter.hxx, + Registration.cxx, Registration.hxx, ReliabilityMessage.hxx, + RportParameter.cxx, RportParameter.hxx, SdpContents.cxx, + SdpContents.hxx, Security.cxx, SendingMessage.cxx, + SendingMessage.hxx, SipFrag.cxx, SipFrag.hxx, SipMessage.cxx, + SipMessage.hxx, SipSession.cxx, SipSession.hxx, SipStack.cxx, + SipStack.hxx, Subscription.cxx, Subscription.hxx, Symbols.cxx, + Symbols.hxx, TcpTransport.cxx, TcpTransport.hxx, TimerMessage.cxx, + TimerMessage.hxx, TimerQueue.cxx, TimerQueue.hxx, TlsTransport.cxx, + TlsTransport.hxx, TransactionMap.cxx, TransactionMap.hxx, + TransactionState.cxx, TransactionState.hxx, Transport.cxx, + Transport.hxx, TransportMessage.hxx, TransportSelector.cxx, + TransportSelector.hxx, TuIM.cxx, TuIM.hxx, TuShim.hxx, TuUa.hxx, + UdpTransport.cxx, UdpTransport.hxx, UnknownHeaderType.cxx, + UnknownHeaderType.hxx, UnknownParameter.cxx, UnknownParameter.hxx, + UnknownParameterType.cxx, UnknownParameterType.hxx, Uri.cxx, + Uri.hxx, XMLCursor.cxx, XMLCursor.hxx, os/BaseException.cxx, + os/BaseException.hxx, os/Coders.cxx, os/Coders.hxx, + os/Condition.cxx, os/CountStream.cxx, os/CountStream.hxx, + os/Data.cxx, os/Data.hxx, os/DataStream.cxx, os/Fifo.hxx, + os/Lock.cxx, os/Lock.hxx, os/Log.cxx, os/Log.hxx, os/Logger.cxx, + os/Logger.hxx, os/MD5Stream.cxx, os/MD5Stream.hxx, os/Makefile, + os/Mutex.cxx, os/Mutex.hxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, + os/Random.cxx, os/Random.hxx, os/Socket.cxx, os/Subsystem.cxx, + os/Subsystem.hxx, os/SysLogStream.hxx, os/ThreadIf.cxx, + os/ThreadIf.hxx, os/Timer.cxx, os/Timer.hxx, os/vmd5.cxx, + os/vmd5.hxx, test/InviteClient.cxx, test/InviteClient.hxx, + test/InviteServer.cxx, test/InviteServer.hxx, test/Makefile, + test/Register.cxx, test/Register.hxx, test/Registrar.cxx, + test/Registrar.hxx, test/Resolver.cxx, test/Resolver.hxx, + test/SipTortureTests.cxx, test/TestSupport.cxx, + test/TestSupport.hxx, test/Transceiver.cxx, test/Transceiver.hxx, + test/digcalc.hxx, test/lg.cxx, test/limpc.cxx, test/test1.cxx, + test/test2.cxx, test/testApplicationSip.cxx, test/testClient.cxx, + test/testCoders.cxx, test/testCountStream.cxx, test/testData.cxx, + test/testDataPerformance.cxx, test/testDataStream.cxx, + test/testDigestAuthentication.cxx, test/testDnsResolver.cxx, + test/testEmbedded.cxx, test/testHash.cxx, + test/testHeaderFieldValueList.cxx, test/testLockStep.cxx, + test/testLogger.cxx, test/testMessageWaiting.cxx, + test/testMultipartMixedContents.cxx, + test/testNameAddrParamExclusions.cxx, + test/testNonInviteClientTx.cxx, test/testNonInviteServerTx.cxx, + test/testParseBuffer.cxx, test/testParserCategories.cxx, + test/testPlainContents.cxx, test/testPreparse.cxx, + test/testRandomHex.cxx, test/testSdp.cxx, test/testServer.cxx, + test/testSimpleLeak.cxx, test/testSipFrag.cxx, + test/testSipMessage.cxx, test/testSipMessageMemory.cxx, + test/testSipStack1.cxx, test/testSipStackInvite.cxx, + test/testSpeed.cxx, test/testTcpTransport.cxx, + test/testThreadIf.cxx, test/testTimer.cxx, + test/testTlsConnection.cxx, test/testTransactionFSM.cxx, + test/testTypes.cxx, test/testUdp.cxx, test/testUri.cxx, + test/testXMLCursor.cxx, test/testpp.cxx: change from sip2 to + resiprocate + +2003-03-24 14:40 alan + + * doc/static/README: update + +2003-03-24 14:40 alan + + * doc/static/README: added fancy stuff + +2003-03-24 14:35 alan + + * doc/static/README: testing commit list again + +2003-03-24 14:32 alan + + * doc/static/README: test update + +2003-03-22 13:02 jason + + * test/testSipMessage.cxx: [no log message] + +2003-03-22 11:38 jason + + * SipStack.cxx, TimerQueue.cxx, TransactionState.cxx, + Transport.cxx: remove debugs + +2003-03-22 11:33 jason + + * README: [no log message] + +2003-03-17 13:30 davidb + + * Makefile: oops + +2003-03-17 09:54 davidb + + * Contents.cxx, Contents.hxx, LazyParser.cxx, LazyParser.hxx, + ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, + ParserContainer.hxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, + test/testParseBuffer.cxx, test/testParserCategories.cxx, + test/testSipMessage.cxx: pass (header) context into ParserBuffer + for message on throw + +2003-03-17 09:52 davidb + + * os/Log.cxx: indent + +2003-03-17 09:52 davidb + + * test/testLogger.cxx: test detect log recursion -- assert rather + than deadlock (will deadlock on WIN32) + +2003-03-17 09:51 davidb + + * os/: ThreadIf.cxx, ThreadIf.hxx: interface to get current thread + id (not in WIN32) + +2003-03-17 09:50 davidb + + * os/: Logger.cxx, Logger.hxx: detect log recursion -- assert + rather than deadlock (noop in WIN32) + +2003-03-17 09:49 davidb + + * os/: BaseException.cxx, BaseException.hxx: add interface to + extract message + +2003-03-17 09:48 davidb + + * Preparse.cxx: simplified debug switching + +2003-03-17 09:48 davidb + + * Helper.cxx, Helper.hxx: added makeRegister interface account for + badly formed authentication header + +2003-03-17 09:46 davidb + + * DataParameter.cxx: do not allow unassigned data parameter e.g. + ttl;transport=tcp + +2003-03-14 12:04 alan + + * ParserCategory.cxx: Made param static (better performance) + +2003-03-13 12:17 ryker + + * TcpTransport.cxx: Make select(2) on TCP connect(2) signal safe. + +2003-03-13 11:32 ryker + + * DnsResolver.cxx, DnsResolver.hxx: <sigh> That won't work either + as you'd have to mutex lock the ares_channel to avoid bad things if + we go multi-threaded (I didn't know we could but hey). Make + mChannel a non-static member again and find a way to get back to it + from the static DnsResolver member functions. I don't like this + too much but my timetable does not give me the option of rewriting + it from scratch. + +2003-03-13 09:51 ryker + + * DnsResolver.cxx, DnsResolver.hxx: Fix for static ares_channel + being initialised/destroyed in the DnsResolver + constructor/destructor. Change mChannel to a static pointer and + alloc/init it in the DnsResolver constructor only once. No new + static initialisers. + +2003-03-12 22:30 fluffy + + * Security.hxx, sipstack.vcproj: updated + +2003-03-12 21:24 fluffy + + * Security.cxx: compile windows + +2003-03-10 14:24 ryker + + * TcpTransport.cxx: Fix select(2) argument. + +2003-03-10 12:47 ryker + + * DataParameter.cxx: If there is no RHS, just return. Hopefully + whoever picks up the parsing next won't fall over. + +2003-03-10 12:45 ryker + + * TcpTransport.cxx: Make the TCP connect(2) non-blocking and select + for some arbitrary timeout, currently 16*T1. This is still crap + because the whole stack could block for this length of time but + it's better than blocking for a TCP timeout which can be up to + 120s. In the latter (current) case, you never get to try another + transport because 120s > SIP timeout. + +2003-03-10 12:44 ryker + + * TransactionState.cxx, TransactionState.hxx: Fixes to accomodate + updates in DnsResolver. + +2003-03-10 12:43 ryker + + * DnsResolver.cxx, DnsResolver.hxx: Make SRV work a little better + in the face of TCP _and_ UDP transports being available and + restructure a bit to make NAPTR a little easier. + +2003-03-10 12:41 ryker + + * TransportSelector.hxx: Add a findTransport() that takes a + transport type directly in addition to the existing version that + takes a tuple. Make the tuple version forward to this new + findTransport() implementation. Also make DnsResolver a friend. + +2003-03-10 12:38 ryker + + * ParserCategory.cxx: Add Alan's fix for encoding the msgr + parameter in a way MSN can live with. + +2003-03-10 11:26 ryker + + * TransportSelector.cxx: Add a findTransport() that takes a + transport type directly in addition to the existing version that + takes a tuple. Make the tuple version forward to this new + findTransport() implementation. Also make DnsResolver a friend. + +2003-03-10 11:20 ryker + + * PlainContents.cxx, PlainContents.hxx: Add a PlainContents::Empty + static member. + +2003-03-10 11:19 ryker + + * Symbols.hxx: NAPTR-related symbols. + +2003-03-10 10:22 ryker + + * Symbols.cxx: NAPTR-related symbols. + +2003-03-10 10:15 ryker + + * os/Timer.cxx: Check if defined(__PPC__) and select the timer + implementation appropriately. This makes the sip2 stack work on + Linux/PPC. + +2003-03-07 14:50 jason + + * DnsResolver.hxx: turn on ares for linux + +2003-03-07 14:50 jason + + * Dialog.cxx, Dialog.hxx, Dialog2.cxx, Dialog2.hxx, DialogSet.cxx, + DialogSet.hxx, Subscription.cxx, Subscription.hxx, TuShim.hxx, + TuUa.hxx, SipStack.hxx, .cvsignore: [no log message] + +2003-03-06 14:52 davidb + + * ApplicationSip.hxx: added note about static referencing + +2003-03-06 14:49 davidb + + * ApplicationSip.cxx, ApplicationSip.hxx, Makefile, SipFrag.cxx, + SipFrag.hxx, test/Makefile, test/testApplicationSip.cxx: + ApplicationSip (application/sip) preceded SipFrag content-type + +2003-03-05 18:17 davidb + + * Helper.cxx, SipMessage.cxx, SipMessage.hxx: refactored + copyRFC2543TransactionId + +2003-03-05 18:15 davidb + + * BranchParameter.cxx, BranchParameter.hxx: simplified, removed + clientdata + +2003-03-05 18:14 davidb + + * test/: testEmbedded.cxx, testParserCategories.cxx, + testSipMessage.cxx: adjusted for new BranchParameter form + +2003-03-05 18:14 davidb + + * test/testXMLCursor.cxx: added "All OK" output + +2003-03-05 18:12 davidb + + * test/testMessageWaiting.cxx: fixed input strings + +2003-03-05 18:12 davidb + + * test/: test1.cxx, testTcpTransport.cxx: fixed + +2003-03-05 18:11 davidb + + * test/TestSupport.hxx: added SipRawMessage - not used yet + +2003-03-05 18:10 davidb + + * test/SipTortureTests.cxx: remove client data reference + +2003-03-05 18:10 davidb + + * SipStack.hxx: export UnknownParameterType + +2003-03-05 18:09 davidb + + * DataParameter.cxx: upped defaulted parameter access to ErrLog + +2003-03-05 18:07 davidb + + * test/testRandomHex.cxx: correct for change in parameterization by + bytes + +2003-03-05 18:07 davidb + + * test/testParseBuffer.cxx: added boundary condition test for + eof/skipN + +2003-03-05 18:06 davidb + + * os/Random.cxx, os/Random.hxx, test/testDataPerformance.cxx: + parametersized by number of bytes rather than number of digits + +2003-03-05 18:05 davidb + + * os/: ParseBuffer.cxx, ParseBuffer.hxx: skipBackN + +2003-03-03 10:08 davidb + + * HeaderHash.cxx: temporary fix to automated hash bug + +2003-03-03 09:21 jason + + * DataParameter.cxx: added a debug + +2003-02-28 15:41 davidb + + * Transport.cxx: exclude the connection from Transport comparison + and hash + +2003-02-28 15:34 fluffy + + * HeaderHash.cxx, HeaderHash.gperf, Makefile, os/fixupGperf: !rm! + added minor fix for gperf auto making still need to make mktmp + portable infixupGperf + +2003-02-28 13:45 davidb + + * Connection.cxx: deal with preparser state where buffer ends on + Header: + +2003-02-28 13:43 davidb + + * test/testPreparse.cxx: added long message test + +2003-02-28 13:40 davidb + + * Transport.cxx, Transport.hxx: simplified data translation + +2003-02-28 13:37 davidb + + * Headers.hxx: added typedef for Auths + +2003-02-27 01:54 fluffy + + * Helper.cxx, Helper.hxx, TuIM.cxx, test/limpc.cxx: !rm! added 405 + response to TuIM, changed User-Agent header + +2003-02-27 01:28 alan + + * test/Makefile: removed bad test driver from Makefile + +2003-02-26 08:38 ryker + + * DnsResolver.cxx: Remove old comment about memory leak which I + believe is now fixed. See how old comments always become out of + date. + +2003-02-26 06:38 ryker + + * TransactionState.cxx: Fix a memory leak WRT DNS messages. Always + delete the messages after use. + +2003-02-26 06:37 ryker + + * DnsResolver.cxx: Fix a crash if no results are found for an + A/AAAA record lookup. Currently someone can put a pathological + name in a SIP URI and crash the stack. + +2003-02-25 08:33 alan + + * Helper.cxx, Helper.hxx: Added make405 + ------------------------------------------------------------------- + --- + +2003-02-25 08:22 jason + + * SipStack.cxx: [no log message] + +2003-02-25 01:11 jason + + * Helper.cxx: [no log message] + +2003-02-24 21:22 jason + + * Preparse.cxx, .cvsignore: [no log message] + +2003-02-24 21:22 jason + + * Helper.cxx: be more careful about checking for existence of + headers before using them + +2003-02-24 20:40 jason + + * test/testSipMessage.cxx: added test case from radvision interop + at sipit + +2003-02-24 20:40 jason + + * test/TestSupport.cxx: added debug + +2003-02-24 09:50 davidb + + * BranchParameter.cxx: use dot to terminate external tid; allows + internal dashes not a great solution, but gets us past radvision + +2003-02-21 08:32 alan + + * test/: Makefile, SipTortureTests.cxx: updates to + SipTortureTest.cxx + +2003-02-20 15:23 jason + + * BranchParameter.cxx, BranchParameter.hxx: changes to support + spirals + +2003-02-20 15:22 jason + + * TcpTransport.cxx, test/testDigestAuthentication.cxx, + test/testParserCategories.cxx, test/testServer.cxx, + test/testSipMessage.cxx, test/testData.cxx: [no log message] + +2003-02-20 12:33 fluffy + + * Makefile: updated + +2003-02-20 12:33 fluffy + + * test/Makefile: [no log message] + +2003-02-17 14:38 fluffy + + * SdpContents.cxx, SdpContents.hxx: included in windows + +2003-02-17 14:14 davidb + + * SdpContents.cxx, SdpContents.hxx: reordered class declarations + for windows + +2003-02-17 10:38 fluffy + + * XMLCursor.cxx, Security.cxx, Security.hxx: update + +2003-02-16 22:18 fluffy + + * os/.cvsignore, os/util.vcproj, .cvsignore, sipstack.vcproj: + update + +2003-02-16 22:17 jason + + * TransactionState.cxx: fix bug passing message to TU that should + only go to wire + +2003-02-16 19:10 fluffy + + * os/util.vcproj, sipstack.vcproj: made a lib + +2003-02-16 18:34 fluffy + + * os/util.vcproj: no message + +2003-02-16 18:34 fluffy + + * SdpContents.cxx, SdpContents.hxx, TuShim.cxx, XMLCursor.cxx: + remove from windows compile + +2003-02-16 18:11 fluffy + + * SSL.cxx, SSL.hxx: no longer used + +2003-02-16 17:50 fluffy + + * os/util.vcproj: no message + +2003-02-16 15:04 fluffy + + * ParserCategories.cxx: fix to compile in windows + +2003-02-13 19:01 fluffy + + * Dialog2.cxx: [no log message] + +2003-02-13 16:31 fluffy + + * Dialog2.cxx: added a few more member functions. + + -rohan + +2003-02-13 16:30 fluffy + + * TuShim.cxx: wrote a few more methods based on existing + declarations. + + -rohan + +2003-02-13 10:34 davidb + + * test/testData.cxx: added prefix tests + +2003-02-13 10:34 davidb + + * test/testUri.cxx: added tel tests + +2003-02-13 10:34 davidb + + * Symbols.cxx: added = to end of fixed user parameters - don't + match postdfoo + +2003-02-12 15:09 jason + + * Dialog.cxx: truly hideous bug in Dialog::clear() was fixed. was + causing a throw every time clear was called + +2003-02-12 13:24 alan + + * test/testParserCategories.cxx: added verbosity to the test driver + +2003-02-12 12:50 alan + + * ParserCategories.cxx, Uri.cxx, test/testParserCategories.cxx, + test/testUri.cxx: Fixed copy ctor in DateCategory. Fixed encode in + Uri. + +2003-02-12 11:19 jason + + * SipStack.hxx: added Dialog.hxx back in. SipStack.hxx is the only + file that external clients of the stack should have to include + +2003-02-11 21:43 fluffy + + * test/testDnsResolver.cxx: need to #include <sys/types.h> early + otherwise a bunch of stuff doesn't work. -rohan CVS + ------------------------------------------------------------------- + --- + +2003-02-11 15:27 fluffy + + * TuShim.cxx: Fleshed out logic in TuShim::processResponse + +2003-02-11 14:02 alan + + * SdpContents.cxx, SdpContents.hxx: added accessor for Address + +2003-02-11 11:22 alan + + * SipStack.hxx, TuIM.cxx: Moved include to client + +2003-02-11 11:20 jason + + * MessageWaitingContents.cxx, MessageWaitingContents.hxx: fix to + work with 7960 + +2003-02-11 08:49 davidb + + * Symbols.cxx, Symbols.hxx, Uri.cxx, Uri.hxx, os/Data.cxx, + os/Data.hxx, test/testUri.cxx: conversion from tel to sip uri + Uri::fromTel + +2003-02-10 16:09 davidb + + * Symbols.cxx, Symbols.hxx, Uri.cxx, Uri.hxx, os/Data.cxx, + os/Data.hxx, test/testEmbedded.cxx, test/testParserCategories.cxx, + test/testUri.cxx: separate user parameters from user in Uri. + support tel scheme + +2003-02-10 13:52 alan + + * Preparse.cxx: Fixed Preparser Bug on Linux (PPC) platform + +2003-02-10 11:47 davidb + + * Pidf.cxx, Pidf.hxx, Pkcs7Contents.cxx, Pkcs7Contents.hxx, + SdpContents.cxx, SdpContents.hxx, test/testSdp.cxx: made sure rhs + was cleared in all operator= + +2003-02-10 11:46 davidb + + * os/ParseBuffer.cxx, os/ParseBuffer.hxx, test/testParseBuffer.cxx: + added unsignedInteger parser + +2003-02-10 11:45 davidb + + * Uri.cxx: removed try/catch from Uri::Uri(const Data&) + +2003-02-10 09:32 alan + + * FloatParameter.cxx, Helper.cxx, MessageWaitingContents.cxx, + MultipartMixedContents.cxx, ParserCategories.cxx, + RportParameter.cxx, Uri.cxx, XMLCursor.cxx: oops, backing out eof() + removal + +2003-02-10 09:27 alan + + * FloatParameter.cxx, Helper.cxx, MessageWaitingContents.cxx, + MultipartMixedContents.cxx, ParserCategories.cxx, + RportParameter.cxx, Uri.cxx, XMLCursor.cxx: undoing now redundant + eof() checks. + +2003-02-09 00:00 jason + + * test/testParserCategories.cxx: added a test + +2003-02-09 00:00 jason + + * TransactionState.cxx: added an assert + +2003-02-09 00:00 jason + + * SipStack.cxx: debug + +2003-02-08 23:59 jason + + * SipMessage.cxx: add support for updating rfc2543 tid in response + +2003-02-08 23:59 jason + + * ParserCategory.cxx: fix bug in assignment op + +2003-02-08 23:58 jason + + * SdpContents.cxx: [no log message] + +2003-02-07 19:06 jason + + * test/: SipTortureTests.cxx, testSdp.cxx, testSipMessage.cxx: + update for SdpContents interface + +2003-02-07 19:06 jason + + * Connection.cxx, Pkcs7Contents.cxx, SdpContents.hxx, Security.cxx, + SipFrag.cxx, TuIM.cxx, XMLCursor.cxx, os/Log.hxx: force use of + leading << in log macros + +2003-02-07 19:05 jason + + * ParserCategories.cxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, + test/testParseBuffer.cxx: implicitly check for out-of-bounds + dereferncing in ParseBuffer + +2003-02-07 10:55 alan + + * Contents.cxx, DataParameter.cxx: intermediary updates for eof() + +2003-02-07 10:55 alan + + * test/testParserCategories.cxx: updates to test driver for output + +2003-02-06 19:01 jason + + * ParserCategories.cxx: fixed bug in auth parser + +2003-02-06 18:49 jason + + * os/: Data.cxx, Data.hxx: weird order of initialization bug fix + +2003-02-06 18:48 jason + + * SdpContents.cxx, SdpContents.hxx: various changes to interface + +2003-02-06 13:47 alan + + * test/testSpeed.cxx: undo accidental checkin + +2003-02-06 13:46 alan + + * DnsResolver.cxx, FloatParameter.cxx, Helper.cxx, + MessageWaitingContents.cxx, MultipartMixedContents.cxx, + ParserCategories.cxx, RportParameter.cxx, SdpContents.cxx, + TimerQueue.cxx, Uri.cxx, XMLCursor.cxx, test/testSpeed.cxx: + ParseBuffer Fixes and valgrind comments + +2003-02-06 10:54 ryker + + * DnsResolver.cxx: Unbreak in case the ares resolver is not being + used. + +2003-02-05 21:10 jason + + * Symbols.cxx, Symbols.hxx: [no log message] + +2003-02-05 14:56 jason + + * os/HashMap.hxx: support for hash_set + +2003-02-05 11:56 ryker + + * SipStack.cxx: Initialise variable before use. + +2003-02-05 11:22 ryker + + * TransactionState.cxx: Keep better track of the "current" notion + in our DNS resolution list. + +2003-02-05 10:36 alan + + * os/Log.cxx: Fixed unsafe argv[0] manipulation -- was crashing + when relative paths used to execute + +2003-02-05 09:49 ryker + + * DnsResolver.cxx, DnsResolver.hxx, TransactionState.cxx, + TransactionState.hxx: Add SRV lookup support. This also involved a + change to the TransactionState to count the number of outstanding + name lookups although this could easily be moved to another place. + + Modified Files: DnsResolver.cxx DnsResolver.hxx + TransactionState.cxx TransactionState.hxx + +2003-02-05 08:23 ryker + + * Symbols.cxx, Symbols.hxx: Add symbols for _sip, _sips, _udp, and + _tcp for use with SRV lookups. + +2003-02-03 19:34 fluffy + + * Dialog2.cxx, Dialog2.hxx, DialogSet.cxx, DialogSet.hxx, Makefile, + Registration.cxx, Registration.hxx, SipSession.cxx, SipSession.hxx, + Subscription.cxx, Subscription.hxx, TuShim.cxx, TuShim.hxx, + TuUa.hxx: added new TU Shim Related stuff + +2003-02-03 16:40 jason + + * BranchParameter.cxx: remove debug + +2003-02-03 16:39 jason + + * Dialog.cxx, Dialog.hxx: remove via + +2003-02-03 16:39 jason + + * TransactionMap.cxx, TransactionMap.hxx, TransactionState.cxx: + terminate stateless transaction rename Tmap::remove to Tmap::erase + +2003-02-01 09:27 davidb + + * os/: ParseBuffer.cxx, ParseBuffer.hxx: added skipToOneOf + +2003-02-01 09:18 davidb + + * os/: Subsystem.cxx, Subsystem.hxx: added SDP + +2003-01-31 17:14 jason + + * Contents.cxx, Contents.hxx, LazyParser.hxx, + MessageWaitingContents.cxx, MultipartMixedContents.cxx, + MultipartMixedContents.hxx, ParserCategory.cxx, ParserCategory.hxx, + Pkcs7Contents.cxx, SipStack.cxx, SipStack.hxx, TransactionMap.cxx, + TransactionMap.hxx, os/Fifo.hxx: memory leaks + +2003-01-31 15:41 jason + + * ConnectionMap.hxx, TcpTransport.cxx, TlsTransport.cxx, + TransactionMap.hxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, UdpTransport.cxx, os/Data.cxx, os/Data.hxx, + os/HashMap.hxx, os/Inserter.hxx, os/Timer.cxx, os/compat.hxx, + test/testCoders.cxx: intel compiler (icc) compatibility stuff + +2003-01-31 12:58 bko + + * DnsResolver.cxx, os/Data.hxx, os/HashMap.hxx, os/Inserter.hxx, + os/Timer.cxx, os/compat.hxx, test/Resolver.cxx, + test/testCoders.cxx: fixes for FreeBSD / gcc 2.9x compiling + +2003-01-31 12:34 davidb + + * os/ParseBuffer.cxx, os/ParseBuffer.hxx, test/testParseBuffer.cxx: + added skipBackToChar() skipBackChar() bof() // + beginning of file to ParseBuffer Note: skipBackChar() is an inverse + of skipChar -- iterator semantics! this means that pb.position() + will be AT the skipped character + +2003-01-31 12:31 davidb + + * HeaderTypes.hxx, Headers.cxx, IntegerParameter.hxx, + SipMessage.cxx, Uri.cxx, test/testHash.cxx, + test/testParserCategories.cxx, test/testSipMessage.cxx, + test/testTypes.cxx: fixed UNKNOWN = -1 as array index + +2003-01-30 18:15 jason + + * test/: SipTortureTests.cxx, testEmbedded.cxx, .cvsignore: [no log + message] + +2003-01-30 18:14 jason + + * TransactionState.cxx: fix bug with ACK received from wire + +2003-01-30 18:12 jason + + * SipStack.cxx, SipStack.hxx: added interface to specify strict + router + +2003-01-30 18:12 jason + + * SdpContents.cxx, SdpContents.hxx: added empty + +2003-01-30 14:14 bko + + * ParserCategories.cxx: compile fix + +2003-01-28 09:41 jason + + * TransactionState.cxx: ack to 200 from wire doesn't need to create + a transaction, just pass to TU + +2003-01-26 16:13 jason + + * ParserCategories.cxx, ParserCategories.hxx: initialize + DateCategory to current date/time + +2003-01-26 12:54 jason + + * os/Data.cxx, os/Data.hxx, test/testData.cxx: added find and + substr + +2003-01-25 15:39 fluffy + + * os/: Socket.cxx, Socket.hxx, compat.hxx: fixed to compile in + windows. + +2003-01-25 10:32 jason + + * .cvsignore, BranchParameter.cxx, BranchParameter.hxx, Makefile, + SipMessage.cxx, SipMessage.hxx, SipStack.cxx, SipStack.hxx, + TransactionState.cxx, TransactionState.hxx, + TransactionTerminated.hxx, TransportSelector.cxx, + TransportSelector.hxx, os/Timer.cxx, os/Timer.hxx: big overhaul of + Transaction stuff + +2003-01-24 21:51 davidb + + * Headers.hxx, SipMessage.hxx: refined header macros + +2003-01-24 19:56 jason + + * os/: Data.cxx, Data.hxx: put string conversion back in + +2003-01-24 19:44 jason + + * os/Inserter.hxx: solaris compat + +2003-01-24 19:41 jason + + * Executive.cxx: temporary fix for latency problem + +2003-01-24 19:41 jason + + * DataParameter.cxx: added comment + +2003-01-24 19:38 jason + + * Connection.cxx, Connection.hxx, ParameterTypes.cxx, + ParserCategories.cxx, ParserCategory.hxx, TcpTransport.cxx, + Transport.cxx, UdpTransport.cxx, Uri.cxx, test/Resolver.cxx: + solaris compat + +2003-01-24 19:35 jason + + * os/Coders.cxx, os/Condition.cxx, os/Data.cxx, os/Data.hxx, + os/Inserter.hxx, os/Log.cxx, os/Mutex.hxx, os/Socket.cxx, + os/Socket.hxx, os/ThreadIf.cxx, os/compat.hxx, test/testCoders.cxx, + test/testData.cxx, test/testDataStream.cxx: solaris compat + +2003-01-24 12:56 davidb + + * UnknownHeaderType.hxx, UnknownParameterType.hxx: explicit + constructors + +2003-01-24 12:54 davidb + + * ParameterTypes.cxx, ParameterTypes.hxx, ParserCategories.cxx, + ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx: + macroized parameters + +2003-01-23 21:16 fluffy + + * ParserCategory.cxx: updated to compile on windows + +2003-01-23 21:07 fluffy + + * ParserCategory.cxx, ParserCategory.hxx: updated to compile on + windows + +2003-01-23 21:07 fluffy + + * os/HashMap.hxx: updated to compile on windows - may have broken + something but hope not + +2003-01-23 18:48 derekm + + * HeaderHash.cxx, Headers.cxx, MethodHash.cxx, ParserCategory.cxx, + ParserCategory.hxx: gperf compiles under linux-hack + decullinized--use #ifndef WIN32 + +2003-01-23 18:47 jason + + * os/BaseException.hxx, os/.cvsignore, os/Condition.cxx, + os/Data.cxx, os/Data.hxx, os/HashMap.hxx, os/ParseBuffer.cxx, + test/testData.cxx, test/testLogger.cxx, test/testParseBuffer.cxx, + test/testThreadIf.cxx: solaris compat + +2003-01-23 18:45 jason + + * TimerQueue.cxx: debug + +2003-01-23 18:44 jason + + * .cvsignore, TODO, Transport.cxx: [no log message] + +2003-01-23 18:44 jason + + * Connection.cxx, Connection.hxx, Security.hxx, Preparse.hxx, + TlsTransport.cxx, Transport.hxx, TransactionMap.cxx, + TransactionMap.hxx: solaris compat + +2003-01-23 18:43 jason + + * DnsResolver.cxx: fix bug with doing 2 dns lookups + +2003-01-23 18:43 jason + + * Helper.cxx: fix bug with failure and 100 responses having totag + +2003-01-23 18:41 jason + + * Uri.cxx: stuff for scheme in aor (not by default) + +2003-01-23 18:41 jason + + * XMLCursor.cxx, XMLCursor.hxx: solaris compat + +2003-01-22 22:59 davidb + + * XMLCursor.cxx: added url to grammar comment + +2003-01-22 22:58 davidb + + * UnknownHeaderType.cxx, UnknownParameterType.cxx: remove spaces + around token before checking against hash + +2003-01-22 22:58 davidb + + * HeaderHash.cxx, Headers.hxx, MethodHash.cxx, ParserCategory.hxx, + SipMessage.cxx, SipMessage.hxx: ifdeffed nasty template tricks + +2003-01-22 20:41 fluffy + + * Headers.hxx, MethodHash.cxx, ParserCategory.cxx, + ParserCategory.hxx: fixed to compile in windows - not a good fix + +2003-01-22 16:54 jason + + * os/: Logger.cxx, Logger.hxx: fix the syslog logger - never worked + before + +2003-01-22 15:18 jason + + * Symbols.cxx, Symbols.hxx: added dot + +2003-01-22 09:24 alan + + * MethodHash.hxx, ParameterHash.hxx, test/testHash.cxx: link fixes + for namespace + +2003-01-21 17:09 alan + + * .cvsignore, HeaderHash.cxx, HeaderHash.gperf, HeaderHash.hxx, + Headers.cxx, Makefile, MethodHash.cxx, MethodHash.gperf, + MethodHash.hxx, MethodTypes.cxx, ParameterHash.cxx, + ParameterHash.gperf, ParameterHash.hxx, ParameterTypes.cxx, + headers.gperf, methods.gperf, parameters.gperf, os/fixupGperf: + automatic gperf upgrades + +2003-01-21 16:55 davidb + + * Contents.cxx, Contents.hxx, Headers.cxx, Headers.hxx, Helper.cxx, + IntegerParameter.cxx, Makefile, MessageWaitingContents.cxx, + MultipartMixedContents.cxx, MultipartSignedContents.cxx, + ParserCategory.cxx, ParserCategory.hxx, QuotedDataParameter.cxx, + SipFrag.cxx, SipMessage.cxx, SipMessage.hxx, TransactionState.cxx, + UnknownHeaderType.cxx, UnknownHeaderType.hxx, + UnknownParameterType.cxx, UnknownParameterType.hxx, XMLCursor.cxx, + test/Makefile, test/SipTortureTests.cxx, + test/testParserCategories.cxx, test/testSipMessage.cxx, + test/testSipMessageMemory.cxx, test/testUri.cxx, + os/BaseException.hxx, os/Data.cxx, os/Data.hxx, os/ParseBuffer.cxx, + os/ParseBuffer.hxx, os/Subsystem.cxx, os/Subsystem.hxx, + test/testData.cxx: unknown/known header/parameter collision + detection XMLCursor, test reworked template approach to headers + macros for header/parameter declaration/definition + ParseBuffer::skipChar() throws on eof + +2003-01-21 11:23 davidb + + * XMLCursor.cxx, XMLCursor.hxx, test/testXMLCursor.cxx: [no log + message] + +2003-01-20 18:25 davidb + + * XMLCursor.cxx, XMLCursor.hxx: [no log message] + +2003-01-19 18:40 fluffy + + * Security.cxx, Security.hxx: updated to compile in windows + +2003-01-19 18:40 fluffy + + * os/: BaseException.cxx, BaseException.hxx: made non pur virtual - + needed so can catch all types + +2003-01-18 22:56 fluffy + + * Helper.cxx: no change + +2003-01-18 20:59 fluffy + + * MultipartSignedContents.cxx, MultipartSignedContents.hxx, + Security.cxx: ghanced getStatiType to be static + +2003-01-18 20:45 fluffy + + * Contents.hxx, MessageWaitingContents.cxx, + MessageWaitingContents.hxx, MultipartMixedContents.cxx, + MultipartMixedContents.hxx, Pidf.cxx, Pidf.hxx, Pkcs7Contents.cxx, + Pkcs7Contents.hxx, PlainContents.cxx, PlainContents.hxx, + SdpContents.cxx, SdpContents.hxx, SipFrag.cxx, SipFrag.hxx: changed + getStaticType to be (duh) static instead of virtual + +2003-01-18 19:59 fluffy + + * Headers.cxx, MultipartMixedContents.cxx: fixed to compile + +2003-01-18 19:45 derekm + + * Uri.cxx: (david) small efficiency issue with concatenating up + address of record + +2003-01-18 09:47 davidb + + * BranchParameter.hxx, Contents.cxx, Contents.hxx, Dialog.cxx, + DnsResolver.cxx, HeaderFieldValueList.hxx, HeaderTypes.hxx, + Headers.cxx, Headers.hxx, ParameterTypeEnums.hxx, + ParameterTypes.cxx, ParameterTypes.hxx, ParserCategories.hxx, + ParserCategory.cxx, ParserCategory.hxx, RportParameter.hxx, + Security.cxx, SipMessage.cxx, SipMessage.hxx, Symbols.cxx, + Symbols.hxx, Transport.cxx, gperfNotes.txt, headers.gperf, + parameters.gperf, test/Transceiver.cxx, + test/testParserCategories.cxx, test/testSipMessage.cxx: changes to + support easy removal of typed headers macros to support writing + headers and parameters + +2003-01-17 21:15 fluffy + + * TuIM.cxx: fixed typo + +2003-01-17 21:13 fluffy + + * Pkcs7Contents.cxx, Pkcs7Contents.hxx, Security.cxx, Security.hxx, + TuIM.cxx, UdpTransport.cxx: integrated lates Contents changes from + David + +2003-01-17 21:12 fluffy + + * MultipartMixedContents.cxx: fixed bug with missing CRLF before + last boundary + +2003-01-17 19:12 jason + + * Dialog.cxx, Helper.cxx: always create a to tag for a response, + for Dialog, override this value with the stored one. + +2003-01-17 19:09 jason + + * DataParameter.cxx: added an assert for empty parameter. + Ultimately this should be a throw but we want to see it in the + applications for now. + +2003-01-16 15:56 kdc + + * TransactionState.cxx: added a 3261 guard around transaction id + update code + +2003-01-16 14:49 kdc + + * SipMessage.cxx: fixed creation of to tag + +2003-01-16 09:01 ryker + + * DnsResolver.cxx: Add some questions in the comments of Via + lookups. + +2003-01-16 08:45 ryker + + * DnsResolver.cxx: Stub in some information about how NAPTR+SRV + should work. + +2003-01-15 21:11 jason + + * Helper.cxx: removed bogus comment + +2003-01-15 18:08 alan + + * DnsResolver.cxx, TransportSelector.cxx: Transport Updates for + 2543 compat + +2003-01-15 15:23 derekm + + * test/SipTortureTests.cxx: fixed some tests...test10 is still odd + +2003-01-15 12:54 jason + + * os/: Data.cxx, Data.hxx: added unsigned int to Data constructors + +2003-01-14 18:30 davidb + + * ParserCategory.cxx, ParserCategory.hxx, TODO, + test/testParserCategories.cxx: typeless parameter interface + +2003-01-14 13:00 ryker + + * os/ParseBuffer.cxx: Update a !dlb! to parse floats that look like + just "1" instead of "1.0". + +2003-01-13 18:29 davidb + + * Connection.cxx, Contents.cxx, Contents.hxx, + MessageWaitingContents.cxx, MultipartMixedContents.cxx, + MultipartMixedContents.hxx, ParserCategories.cxx, Pidf.cxx, + Pidf.hxx, Pkcs7Contents.cxx, PlainContents.cxx, SipMessage.cxx, + test/testMultipartMixedContents.cxx, test/testPlainContents.cxx: + multipart actually works - fixed Mime::operator< - separated + parseHeader and parse - modified Pidf parser to use Data overlay + +2003-01-12 23:15 fluffy + + * os/ParseBuffer.cxx: [no log message] + +2003-01-12 23:15 fluffy + + * Contents.cxx, Contents.hxx, Makefile, MultipartMixedContents.cxx, + MultipartSignedContents.cxx, MultipartSignedContents.hxx, + Pkcs7Contents.cxx, PlainContents.cxx, PlainContents.hxx, + Security.cxx, Security.hxx, SipMessage.cxx, TuIM.cxx: All the + Content stuff is really confused - half of it thinks that it is a + mim message, half of it thinks it is the body part of a mime + message. It is all somewhate broken in the current state. + +2003-01-12 16:50 fluffy + + * Security.cxx, TuIM.cxx, test/limpc.cxx: few fix up in header + outputs + +2003-01-12 16:50 fluffy + + * Pkcs7Contents.cxx: fixed bug in and made it encode headers + +2003-01-12 16:49 fluffy + + * Contents.cxx: fixed bug in output of header + +2003-01-12 15:00 fluffy + + * MultipartMixedContents.cxx, MultipartMixedContents.hxx, + Security.cxx, Security.hxx, SipMessage.cxx, TuIM.cxx: fixed ugly + bug in multipart - sign security currently broken + +2003-01-12 13:23 davidb + + * Helper.cxx: allow specification of port and transport in register + request + +2003-01-12 12:21 fluffy + + * test/SipTortureTests.cxx: [no log message] + +2003-01-12 11:59 fluffy + + * test/SipTortureTests.cxx: added dump for contents type + +2003-01-12 11:37 davidb + + * SipStack.hxx: remove default port from addAlias + +2003-01-12 11:34 fluffy + + * Security.cxx: updated headers for s/mime encrypt stuff + +2003-01-12 11:09 fluffy + + * Pkcs7Contents.cxx, Readme-Complinace.txt, Security.cxx, + SipMessage.cxx: updated headers for s/mime encrypt stuff + +2003-01-11 22:55 fluffy + + * TuIM.cxx, TuIM.hxx, test/SipTortureTests.cxx, test/limpc.cxx: + fixed up expires in contact header paramter + +2003-01-11 20:52 fluffy + + * Readme-Complinace.txt, test/Transceiver.cxx, test/limpc.cxx, + test/test1.cxx: updated + +2003-01-11 19:39 fluffy + + * SipStack.cxx, SipStack.hxx, Transport.hxx, TransportSelector.cxx: + toying with IP instead of hostnames + +2003-01-11 15:24 fluffy + + * Readme-Complinace.txt: update + +2003-01-11 15:22 fluffy + + * Embedded.cxx, HeaderFieldValueList.cxx: fix includes + +2003-01-11 14:20 jason + + * SipStack.cxx, SipStack.hxx: include port in alias for a my domain + +2003-01-10 17:54 alan + + * os/Coders.cxx, os/Data.cxx, test/testCoders.cxx: Coder update + +2003-01-10 17:53 alan + + * ParserCategories.cxx, Symbols.cxx, Symbols.hxx: Added STAR + support to contacts + +2003-01-10 10:21 ryker + + * TransactionState.cxx: Don't change mMsgToRetransmit from INVITE + to ACK in the failure case of a client INVITE transaction (e.g. + 300-699). This causes problems later with respect to the special + case transaction ID for ACK. Instead recreate the ACK message for + each 300-699 retransmission. Ugly but works. + +2003-01-10 08:17 davidb + + * os/Data.cxx: added asserts where char* could be 0 + +2003-01-09 18:51 derekm + + * test/: Makefile, testClient.cxx, testServer.cxx: [no log message] + +2003-01-09 17:30 derekm + + * TODO: [no log message] + +2003-01-09 17:30 derekm + + * Dialog.cxx: removed spurious comment + +2003-01-09 17:30 derekm + + * Connection.cxx, ConnectionMap.cxx, ConnectionMap.hxx, + SipStack.cxx, SipStack.hxx, TcpTransport.cxx, Transport.cxx, + Transport.hxx: fixed bugs in Connection & Transport More efficient + lookup of connections in ConnectionMap SipStack::getHostName() is + now static + +2003-01-08 19:08 jason + + * SipStack.hxx: [no log message] + +2003-01-08 12:45 davidb + + * test/Makefile: remove limp + +2003-01-08 12:44 davidb + + * DataParameter.cxx: indent + +2003-01-08 12:44 davidb + + * TODO: [no log message] + +2003-01-08 12:43 davidb + + * Embedded.cxx, HeaderFieldValueList.cxx, ParserCategories.cxx, + ParserContainer.hxx, SipMessage.cxx, Uri.cxx, + test/testEmbedded.cxx: fixed embedded multiple headers + +2003-01-07 18:42 davidb + + * HeaderTypes.hxx, ParameterTypeEnums.hxx, gperfNotes.txt, + parametersA.gperf: notes and comments about gperf use + +2003-01-07 17:54 derekm + + * HeaderTypes.hxx, Headers.cxx, Headers.hxx, + ParameterTypeEnums.hxx, ParameterTypes.cxx, ParameterTypes.hxx, + ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, + SipMessage.cxx, SipMessage.hxx, Symbols.cxx, Symbols.hxx, + headers.gperf, parameters.gperf, test/testParserCategories.cxx, + test/testSipMessage.cxx: added rfc 3329 headers, parameters + +2003-01-07 10:20 jason + + * TuIM.hxx: [no log message] + +2003-01-06 22:28 davidb + + * TODO, Headers.hxx: [no log message] + +2003-01-06 22:27 davidb + + * Embedded.cxx, Embedded.hxx, HeaderFieldValueList.cxx, + HeaderFieldValueList.hxx, Makefile, ParserContainer.hxx, + ParserContainerBase.hxx, SipMessage.cxx, SipMessage.hxx, + Symbols.cxx, Symbols.hxx, Uri.cxx, Uri.hxx, test/Makefile, + test/testEmbedded.cxx: Uri embedded headers + +2003-01-06 19:46 fluffy + + * MultipartMixedContents.cxx, TuIM.cxx, TuIM.hxx: fixed inti + problems + +2003-01-06 19:46 fluffy + + * os/Random.cxx: fixid init problem + +2003-01-05 11:01 davidb + + * os/ParseBuffer.cxx: fixed skipToChars, skipLWS + +2003-01-05 10:59 davidb + + * os/Data.hxx, os/DataStream.cxx, os/DataStream.hxx, + test/limpc.cxx: added static Data::from template + +2003-01-05 10:58 davidb + + * Contents.cxx, Contents.hxx, LazyParser.cxx, + MessageWaitingContents.cxx, MultipartMixedContents.cxx, + MultipartMixedContents.hxx, ParserCategories.cxx, + ParserContainer.hxx, Pidf.cxx, PlainContents.cxx, SipMessage.cxx, + Symbols.cxx, Symbols.hxx, test/testMessageWaiting.cxx, + test/testMultipartMixedContents.cxx, test/testParserCategories.cxx, + test/testPlainContents.cxx: dealt with content headers being either + in SipMessage headers or part of multipart body + +2003-01-05 08:57 davidb + + * ParserCategories.cxx: StringCategory::parse fix + +2003-01-04 19:49 fluffy + + * TuIM.cxx, TuIM.hxx, test/SipTortureTests.cxx, test/limpc.cxx: + updated for outbound proxy stuff + +2003-01-04 17:19 jason + + * Helper.cxx, Helper.hxx, TransactionState.cxx: refactor + getSentPort and fix bug when no sent port in via + +2003-01-04 17:10 fluffy + + * UdpTransport.cxx: added assert + +2003-01-04 15:20 jason + + * Transport.cxx: use source port only if rport is present, + otherwise use sentPort from via + +2003-01-04 15:20 jason + + * TransactionState.cxx: change Tuple::operator< to use the + Connection* if it exists + +2003-01-04 13:35 jason + + * TransactionState.cxx: fixed the retransmit bug cullen found + +2003-01-04 07:59 fluffy + + * TransactionState.cxx: turned evil hack ErrLog to InfoLog - please + - need to fix what cuases this + +2003-01-04 07:55 fluffy + + * test/limpc.cxx: updated + +2003-01-04 07:55 fluffy + + * SipStack.cxx, SipStack.hxx, TuIM.cxx, TuIM.hxx: moved the + setOutboundProxy + +2003-01-03 22:08 fluffy + + * SipStack.cxx, SipStack.hxx: add outbound proxy api + +2003-01-03 20:59 fluffy + + * os/Data.cxx, os/ParseBuffer.cxx, os/Socket.cxx, os/Socket.hxx, + TcpTransport.cxx, TuIM.cxx, TuIM.hxx, UdpTransport.cxx, Uri.cxx: + fix bugs to do with error recovery + +2003-01-02 23:31 fluffy + + * os/Data.cxx, os/Data.hxx, os/compat.hxx, TcpTransport.cxx, + TlsTransport.cxx: windows ports for min/max stuff + +2003-01-02 18:25 fluffy + + * Dialog.cxx, DnsResolver.cxx, Helper.cxx, TransportSelector.cxx, + TuIM.cxx, test/limpc.cxx: few formatting changes + +2003-01-02 15:27 derekm + + * test/SipTortureTests.cxx: unknown scheme test had invalid auth + param + +2003-01-02 15:26 derekm + + * test/limpc.cxx: added template method as stopgap to stream + +2003-01-02 15:25 derekm + + * SipStack.hxx: fixed merge + +2003-01-02 15:25 derekm + + * os/Socket.hxx: spelling + +2003-01-02 15:24 derekm + + * test/: Transceiver.cxx, test1.cxx, test2.cxx, + testDnsResolver.cxx, testLockStep.cxx, testSipStack1.cxx, + testSpeed.cxx, testTcpTransport.cxx: selectMilliseconds calls are + now passed milliseconds + +2003-01-02 15:23 derekm + + * Uri.cxx, Uri.hxx: added getOpaque method to retrieve contents of + absolute URI -- non standard schemes no longer result in an + exception + +2003-01-02 15:22 derekm + + * TcpTransport.cxx, TlsTransport.cxx, Transport.cxx, os/compat.hxx: + added min, max to compat + + used where appropriate + +2003-01-02 13:27 jason + + * test/: SipTortureTests.cxx, raw-tests.txt: added some more + torture tests + +2003-01-02 13:27 jason + + * SipStack.hxx: added some interface comments + +2003-01-02 13:26 jason + + * SipStack.cxx, test/testDnsResolver.cxx, test/torture-test.txt: + [no log message] + +2003-01-01 22:57 fluffy + + * Security.cxx: update + +2003-01-01 21:48 fluffy + + * TuIM.cxx, TuIM.hxx: caugh ugly bug with fail loop + +2003-01-01 19:25 fluffy + + * Security.cxx, TuIM.cxx, TuIM.hxx, test/limpc.cxx: turned an + assertion into an error + +2003-01-01 19:02 fluffy + + * Dialog.cxx, LazyParser.cxx, ParserCategories.cxx, SipStack.cxx: + few assertions + +2003-01-01 19:00 fluffy + + * TransactionState.cxx: cullen checked in hack change - is likely + wrong and shoudl be removed + +2003-01-01 18:59 fluffy + + * Security.cxx, Security.hxx, TuIM.cxx, TuIM.hxx, test/limpc.cxx, + test/testIM.cxx: changed some assertions to pass up error instead + +2002-12-31 20:03 fluffy + + * Security.cxx, TlsTransport.cxx, os/Log.hxx, os/Random.cxx: + windows port + +2002-12-31 18:15 fluffy + + * test/: Makefile, limpc.cxx: [no log message] + +2002-12-31 17:18 fluffy + + * Executive.cxx, Security.cxx, Security.hxx, SipStack.cxx, + TcpTransport.cxx, TlsTransport.cxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, TransportSelector.hxx, TuIM.cxx, TuIM.hxx, + UdpTransport.cxx, Uri.cxx, test/limpc.cxx, test/testIM.cxx: general + clean up of bits + +2002-12-31 11:58 fluffy + + * DnsResolver.cxx, Executive.cxx, TcpTransport.cxx, TimerQueue.cxx, + TimerQueue.hxx, TlsTransport.cxx, Transport.cxx, Transport.hxx, + UdpTransport.cxx, UdpTransport.hxx, test/limpc.cxx: fixed nast bug + that cause select to always return + +2002-12-31 10:41 fluffy + + * Executive.cxx, Executive.hxx, SipStack.cxx, SipStack.hxx, + Transport.cxx, TuIM.cxx, TuIM.hxx, os/Log.hxx, os/Socket.hxx, + test/Transceiver.cxx, test/limpc.cxx, test/test1.cxx, + test/test2.cxx, test/testDnsResolver.cxx, test/testIM.cxx, + test/testLockStep.cxx, test/testSipStack1.cxx, test/testSpeed.cxx, + test/testTcpTransport.cxx, test/testSipStack1.cxx: changed time + signatures + +2002-12-30 22:10 fluffy + + * TlsTransport.cxx: [no log message] + +2002-12-30 22:05 fluffy + + * test/: .cvsignore, testIM.cxx: [no log message] + +2002-12-30 22:04 fluffy + + * Connection.cxx, Connection.hxx, ConnectionMap.cxx, + ConnectionMap.hxx, Makefile, Security.cxx, TcpTransport.cxx, + TlsTransport.cxx, TransportSelector.cxx, test/Makefile: refactored + some of the socket code out of the connection class + +2002-12-30 18:50 fluffy + + * DnsResolver.cxx, DnsResolver.hxx, os/Socket.cxx, test/Makefile: + added USE_ARES for ARES stuff + +2002-12-29 19:52 fluffy + + * TlsTransport.cxx: windows fix ups + +2002-12-29 19:27 fluffy + + * Connection.cxx, ConnectionMap.cxx, Security.cxx, Security.hxx, + SipStack.cxx, TcpTransport.cxx: windows fixes + +2002-12-23 16:14 jason + + * DnsMessage.cxx, DnsMessage.hxx, DnsResolver.cxx, DnsResolver.hxx, + Executive.cxx, Executive.hxx, Makefile, TransactionState.cxx, + TransactionState.hxx, test/.cvsignore, test/Makefile, + test/testDnsResolver.cxx, Transport.cxx: moved to using ares lib on + linux for async dns no more support for partial results from dns + queries still uses ares_gethostbyname, needs to support the general + dns result + +2002-12-23 16:13 jason + + * TransportSelector.cxx: [no log message] + +2002-12-23 16:13 jason + + * HeaderTypes.hxx: reordered headers according to rfc + +2002-12-23 15:53 jason + + * os/Socket.hxx: make members public for async dns + +2002-12-23 12:49 fluffy + + * os/Log.hxx: mess with ERR definition + +2002-12-23 12:46 fluffy + + * test/limpc.cxx: no + +2002-12-23 10:04 alan + + * doc/Makefile: added rules for old diagrams + +2002-12-22 14:04 fluffy + + * SipStack.cxx: fixed includes for RH compile + +2002-12-22 13:21 fluffy + + * ConnectionMap.cxx, Pidf.cxx, Uri.cxx, Uri.hxx: few windows fixes + +2002-12-22 12:12 davidb + + * ParserCategories.cxx: added encode parameters to Token::encode, + String::encode + +2002-12-22 07:44 fluffy + + * Connection.cxx, SipFrag.cxx, TcpTransport.cxx, TuIM.cxx, + TuIM.hxx, os/Data.hxx, SipStack.cxx, SipStack.hxx: update to + compile in wind woes + +2002-12-21 22:30 fluffy + + * Dialog.cxx, Pidf.cxx, TuIM.cxx: got resubscriptiongs flowing and + added pidf parse + +2002-12-21 19:15 fluffy + + * Makefile, Pidf.cxx, Pidf.hxx, TuIM.cxx, TuIM.hxx: added PIDF mime + type + +2002-12-21 16:20 fluffy + + * Dialog.cxx, Helper.cxx, TuIM.cxx, TuIM.hxx, UdpTransport.cxx, + os/Timer.cxx, test/testIM.cxx: updates for TuIM sub/notify stuff + +2002-12-21 13:28 fluffy + + * Dialog.cxx, Dialog.hxx, Helper.cxx, Helper.hxx, TuIM.cxx, + TuIM.hxx, os/Timer.cxx, os/Timer.hxx, test/Register.cxx, + test/testIM.cxx, test/testSipMessage.cxx, test/testSpeed.cxx, + test/testTlsConnection.cxx: updating dialog and helper stuff + +2002-12-20 16:36 alan + + * Makefile: added makefile opt + +2002-12-20 16:35 alan + + * test/Makefile: include opts + +2002-12-20 16:19 ryker + + * SipMessage.cxx, SipMessage.hxx, SipStack.cxx, SipStack.hxx: Get + rid of the FixedDest part of SipMessage. It would have been nice + if the author had mentioned this during the list discussion. The + mTarget version is almost the same except it takes Uri types + instead of Data. It is thought that this is better as the rest of + the stack is plugged into it and you may need more than just the + hostname, e.g. the scheme to indicate that the target must be + contacted over TLS. + +2002-12-20 14:32 alan + + * os/Makefile, test/testCoders.cxx: Makefile + +2002-12-20 12:02 jason + + * RportParameter.cxx: output value if set + +2002-12-20 11:03 jason + + * DnsResolver.cxx, os/compat.hxx: moved compatibility stuff into + compat.hxx + +2002-12-20 11:02 jason + + * Helper.cxx: [no log message] + +2002-12-20 11:02 jason + + * Connection.cxx, Transport.cxx, Transport.hxx, UdpTransport.cxx: + refactored received= and rport= code + +2002-12-20 09:53 ryker + + * Helper.cxx, Helper.hxx, SipMessage.cxx, SipMessage.hxx, + TransportSelector.cxx: Implement the notion of a forced target to a + SipMessage with accessor functions. In the TransportSelector this + target is used if it exists, otherwise loose routing rules are + applied. The routes/request-uri rotation magic can be done with + Helper::processStrictRoute(). + +2002-12-20 08:22 kdc + + * TcpTransport.cxx, TlsTransport.cxx, UdpTransport.cxx: changed int + to socklen_t to fix gcc3.2 compile errors + +2002-12-19 23:56 fluffy + + * DnsResolver.cxx, TcpTransport.cxx, TlsTransport.cxx, + UdpTransport.cxx, os/Timer.cxx, os/compat.hxx, test/Resolver.cxx, + test/testTlsConnection.cxx, test/testTransactionFSM.cxx, + os/.cvsignore, test/.cvsignore: compile on mac os 10 + +2002-12-19 10:32 ryker + + * Dialog.cxx: Dialog::makeResponse() was choking with an assert if + the request came with a To: tag already. This happens with + Re-INVITE, for example, so only attempt to generate a To: tag if + there isn't already one present. + +2002-12-18 16:49 alan + + * os/HashMap.hxx: fixed extra defined() test + +2002-12-18 09:21 kdc + + * Dialog.cxx, Dialog.hxx: reverted changes to makeBye + +2002-12-17 16:26 jason + + * Connection.cxx, DnsResolver.cxx, Makefile, ParameterTypes.hxx, + ParserCategory.cxx, RportParameter.cxx, RportParameter.hxx, + UdpTransport.cxx, test/Transceiver.cxx, + test/testParserCategories.cxx: refactored rport param to support + both ;rport and ;rport=value + +2002-12-17 13:45 ryker + + * SdpContents.cxx: Fix parsing of bandwith line of SDP. + +2002-12-17 11:54 ryker + + * os/HashMap.hxx: Correct syntax error. + +2002-12-17 10:06 jason + + * UdpTransport.cxx, test/Makefile: [no log message] + +2002-12-17 10:05 jason + + * os/Data.cxx, os/HashMap.hxx, os/Timer.cxx, Security.cxx, + TuIM.cxx, TuIM.hxx, Uri.hxx: added intel compiler stuff + +2002-12-16 17:46 fluffy + + * test/testIM.cxx: few changes + +2002-12-16 14:51 kdc + + * Dialog.cxx, Dialog.hxx: fixed makeBye + +2002-12-16 12:45 fluffy + + * Security.cxx: fixed compile bug on older versions of OPENSSL + +2002-12-16 12:07 jason + + * TlsTransport.cxx, TlsTransport.hxx: compilation issues + +2002-12-16 12:03 jason + + * ConnectionMap.cxx, ConnectionMap.hxx, TcpTransport.cxx, + TcpTransport.hxx: separate Connection from ConnectionMap + +2002-12-16 12:03 jason + + * TransactionState.cxx, TransactionState.hxx: for Server + transaction, always reply to source (from SipMessage) + +2002-12-16 12:02 jason + + * Transport.cxx, Transport.hxx: added Connection* to Tuple + +2002-12-16 12:01 jason + + * TransportSelector.cxx, TransportSelector.hxx: change constness + (temporary change) + +2002-12-16 12:01 jason + + * test/testLockStep.cxx: [no log message] + +2002-12-16 12:01 jason + + * test/SipTortureTests.cxx: added a torture test(2) + +2002-12-16 12:00 jason + + * SipMessage.cxx: fixes to copy constructor + +2002-12-16 12:00 jason + + * DnsResolver.hxx: added NoLookupRequired + +2002-12-16 11:58 jason + + * Connection.cxx, Connection.hxx, Makefile: separated Connection + from ConnectionMap + +2002-12-16 11:37 derekm + + * ParserCategories.cxx, Uri.cxx, test/testUri.cxx: uri::parse now + parses parameters + +2002-12-16 10:27 derekm + + * SipMessage.cxx, SipMessage.hxx: added create timestamp + +2002-12-15 14:46 fluffy + + * test/testIM.cxx: switched back to UDP + +2002-12-15 14:30 fluffy + + * TlsTransport.cxx: update toc compile - does not work - should be + thrown out once TCP is done + +2002-12-15 14:26 fluffy + + * test/: Makefile, testIM.cxx: updated for TLS + +2002-12-15 14:26 fluffy + + * Makefile, TlsTransport.cxx, TlsTransport.hxx, + TransportSelector.cxx: added Tls transport placeholder class + +2002-12-15 14:25 fluffy + + * DnsResolver.cxx: updatted for sips and tls con + +2002-12-15 14:24 fluffy + + * Security.cxx, Security.hxx: [no log message] + +2002-12-15 12:10 fluffy + + * TcpTransport.cxx: removed one debug message + +2002-12-15 12:09 fluffy + + * test/testIM.cxx: TCP version + +2002-12-15 11:45 fluffy + + * test/: testUri.cxx, Makefile: [no log message] + +2002-12-14 21:06 davidb + + * Contents.cxx, Contents.hxx: added headers to Contents -- closer + to recursive contents + +2002-12-14 21:05 davidb + + * os/ParseBuffer.cxx, os/ParseBuffer.hxx, test/testParseBuffer.cxx: + deal with LWS in ParseBuffer, some tests + +2002-12-14 16:04 fluffy + + * TuIM.cxx, TuIM.hxx: updated buddy stuff + +2002-12-14 15:36 fluffy + + * test/testIM.cxx: add press callback + +2002-12-14 15:36 fluffy + + * MultipartMixedContents.cxx: fixed include to compile + +2002-12-14 15:16 fluffy + + * TuIM.cxx, TuIM.hxx: update API + +2002-12-14 15:16 fluffy + + * os/Socket.hxx: fix compiel warnings + +2002-12-14 12:03 davidb + + * Symbols.cxx, Symbols.hxx: parse symbols as Data, others used in + static init + +2002-12-14 12:03 davidb + + * PlainContents.cxx: don't need pb.reset() + +2002-12-14 11:57 davidb + + * Uri.cxx: use efficient ParseBuffer::data + +2002-12-14 11:55 davidb + + * Contents.cxx, Contents.hxx, MultipartMixedContents.cxx, + MultipartMixedContents.hxx, Security.cxx, Symbols.cxx, Symbols.hxx, + os/Data.hxx, os/Random.cxx, test/Makefile, + test/testMultipartMixedContents.cxx, test/testPlainContents.cxx: + second swipe at MultipartMixedContents -- not there yet + +2002-12-14 11:26 fluffy + + * TimerQueue.cxx, UdpTransport.cxx: update for windows + +2002-12-14 11:26 fluffy + + * test/testIM.cxx: update - sort of works in windows other than bug + that reading from stdin is blocking + +2002-12-14 11:10 fluffy + + * test/testIM.cxx: general messing around + +2002-12-14 10:51 jason + + * TimerQueue.cxx, TimerQueue.hxx, test/Makefile, + test/testTimer.cxx: added TimerQueue::msTillNextTimer() + +2002-12-14 10:43 fluffy + + * DnsResolver.cxx, Executive.cxx, TimerQueue.cxx, TimerQueue.hxx, + TransactionState.cxx, TransportSelector.cxx, TuIM.cxx, + UdpTransport.cxx, test/testIM.cxx, test/testParserCategories.cxx, + test/testSpeed.cxx: general messing around + +2002-12-14 10:43 fluffy + + * os/Socket.cxx: fixed windwos blocking bug + +2002-12-14 09:04 fluffy + + * Symbols.cxx, Symbols.hxx: switch symbols back to char* instead of + Data. This is becuase of initailizor order bug. The headers rely on + symbold being initialized before they are ther is no way to enforce + this Synbols needthere initalizeors to run + +2002-12-14 09:03 fluffy + + * TransactionState.cxx, TransportSelector.cxx: catch weird DNS erro + +2002-12-14 09:03 fluffy + + * Preparse.cxx: make work either symbvol type + +2002-12-14 09:02 fluffy + + * Makefile: add HeaderTypes + +2002-12-14 09:02 fluffy + + * HeaderTypes.cxx: remove duplicat junk + +2002-12-14 09:02 fluffy + + * BranchParameter.cxx: make work either type of symbol + +2002-12-13 18:19 derekm + + * ConnectionMap.cxx, Dialog.cxx, Executive.cxx, SipMessage.cxx, + SipMessage.hxx, UdpTransport.cxx, test/TestSupport.cxx: SipMessage + no longer has a SipMessage(bool) constructor -- this caused + problems because a pointer was convertable to a bool..use + SipMessage::FromWire, SipMessage::NotFromWire(the default) instead + + Fixes to dialog. + +2002-12-13 16:53 derekm + + * ConnectionMap.cxx, DnsResolver.cxx, Executive.cxx, + ReliabilityMessage.hxx, TcpTransport.cxx, TransportMessage.hxx, + UdpTransport.cxx, os/Socket.cxx, os/Socket.hxx: more tcp transport + fixes--snapshot of a work in progress changed Executive::process + loop to only call process once on the transports + + sockets are now made non-blocking after connect, so the connects + are blocking--avoids some book keeping + +2002-12-13 10:47 jason + + * Dialog.cxx: [no log message] + +2002-12-12 22:52 fluffy + + * ConnectionMap.cxx: change *1.5 to *3/2 + +2002-12-12 22:47 fluffy + + * test/: SipTortureTests.cxx, testSpeed.cxx: no message + +2002-12-12 21:52 jason + + * ConnectionMap.cxx, TcpTransport.cxx: [no log message] + +2002-12-12 21:51 jason + + * ParserCategories.hxx: added some explicits + +2002-12-12 19:34 derekm + + * ConnectionMap.cxx, TcpTransport.cxx, TransportSelector.cxx: fixed + a couple of bugs added tcp transportSelector + +2002-12-12 19:12 derekm + + * test/testTcpTransport.cxx: [no log message] + +2002-12-12 19:02 derekm + + * ConnectionMap.cxx, ConnectionMap.hxx, Preparse.cxx, + TcpTransport.cxx, TcpTransport.hxx, Transport.cxx, os/Socket.hxx, + test/testPreparse.cxx, test/testTcpTransport.cxx: tcpTransport is + almost complete various tests& bug fixes removed CritLog from + preParser + +2002-12-12 10:01 fluffy + + * doc/: FifoFlow.pdf, FifoFlow.vsd: no message + +2002-12-11 22:44 jason + + * SipStack.hxx, Security.cxx, Security.hxx, + test/testTlsConnection.cxx: [no log message] + +2002-12-11 22:21 fluffy + + * SSL.cxx, SSL.hxx: removed + +2002-12-11 22:15 fluffy + + * ConnectionMap.cxx: fixed a type + +2002-12-11 19:52 derekm + + * os/Data.hxx: Data::size_type is now size_t + +2002-12-11 19:51 derekm + + * ConnectionMap.cxx, ConnectionMap.hxx, SipFrag.cxx, + TcpTransport.cxx, Transport.hxx, UdpTransport.hxx, test/Makefile, + test/TestSupport.cxx, test/testTcpTransport.cxx: wrote + ConnectionMap::Connection. + + Transport no longer has a preparser--UdpConnection has one, each + ConnectionMap::Connection has one + + tests, fixed some include problems that resulted from the above + +2002-12-11 18:33 jason + + * Helper.cxx: added makeCancel helper + +2002-12-11 14:34 kdc + + * Contents.cxx: fixed copy constructor + +2002-12-11 12:48 derekm + + * ParserCategory.cxx: removed : + + cerr << endl; + +2002-12-11 12:20 jason + + * SipMessage.cxx, SipMessage.hxx, TransactionState.cxx, + TransactionState.hxx: implement support for rfc2543 compatibility + for transactionId - used to match the transaction for requests + coming from 2543 sip elements + +2002-12-11 12:18 jason + + * UdpTransport.cxx: minor reorg of debuglog related to EWOULDBLOCK + +2002-12-11 12:15 jason + + * TODO: [no log message] + +2002-12-10 23:17 jason + + * TransactionMap.cxx: support for adding a second entry that maps + to the same pointer + +2002-12-10 23:16 jason + + * ParserCategory.cxx, ParserCategory.hxx: added + commutativeParameterHash for comparing two lists of parameters + +2002-12-10 23:15 jason + + * os/Data.cxx, os/Data.hxx, test/testData.cxx: added exclusive or + operation for data operator^= + +2002-12-10 19:08 fluffy + + * test/testSpeed.cxx: no message + +2002-12-10 10:53 jason + + * os/: Subsystem.cxx, Subsystem.hxx: added some new subsystems for + debugging purposes + +2002-12-10 10:49 fluffy + + * UdpTransport.cxx: fix bug I put in + +2002-12-10 10:36 jason + + * ConnectionMap.cxx, DnsResolver.cxx, SipMessage.cxx, SipStack.hxx, + TcpTransport.cxx, TimerQueue.cxx, TransactionMap.cxx, + TransactionState.cxx, Transport.cxx, TransportSelector.cxx, + UdpTransport.cxx: added some new subsystems for debugging purposes + +2002-12-09 21:11 fluffy + + * BranchParameter.cxx: changed to use a random number for the + branch + +2002-12-09 21:11 fluffy + + * Preparse.cxx, Preparse.hxx: formatting changes + +2002-12-09 21:11 fluffy + + * UdpTransport.cxx: sort out erros + +2002-12-09 21:11 fluffy + + * os/: Log.cxx, Log.hxx, Logger.hxx: fix to work in windows + +2002-12-09 18:28 jason + + * test/testSipMessage.cxx: added test case with copy of a request + and compare request methods + +2002-12-09 18:27 jason + + * test/testParserCategories.cxx: added test with status line reason + phrase + +2002-12-09 18:27 jason + + * Helper.cxx, SipMessage.cxx, SipMessage.hxx: rework how + transaction id is computed for rfc2543 endpoints added an interface + to set the rfc2543 transactionId in the SipMessage + +2002-12-09 18:25 jason + + * UdpTransport.cxx: removed debugs + +2002-12-09 18:24 jason + + * TransactionState.cxx: fixed problem with cancel state machine + debug changes re-indent + +2002-12-09 18:23 jason + + * SipStack.cxx: fix problem adding alias debug changes + +2002-12-09 18:23 jason + + * ParserCategories.cxx: fixed statusline decoder removed some debug + +2002-12-09 16:32 fluffy + + * test/testSdp.cxx: fixed compile bug + +2002-12-09 13:53 fluffy + + * test/testThreadIf.cxx: fixed compile bug + +2002-12-09 11:28 derekm + + * os/Data.cxx, os/Data.hxx, os/MD5Stream.cxx, os/MD5Stream.hxx, + test/testDigestAuthentication.cxx: md5stream is a real stream + + Data no returns lower case hex from hex(), which is necesary for + md5 to work. If upper case hex is needed somewhere we need two + methods. + +2002-12-08 19:13 jason + + * os/Condition.cxx: minor debug changes + +2002-12-08 19:12 jason + + * os/Log.cxx: fix toLevel + +2002-12-08 19:10 jason + + * os/Subsystem.hxx: allow Subsystem to be subclassed + +2002-12-08 19:06 jason + + * Transport.cxx: remove debug output + +2002-12-08 19:04 jason + + * Security.cxx: fix compilation error on gcc 3.2 (const problem) + +2002-12-08 19:04 jason + + * DnsResolver.cxx: comment out debug output + +2002-12-07 01:22 fluffy + + * Pkcs7Contents.cxx, Pkcs7Contents.hxx: addes suppor for signed + type + +2002-12-07 01:21 fluffy + + * Security.cxx, Security.hxx: upgrade to beta version of openssl + +2002-12-06 23:49 fluffy + + * TransactionMap.cxx, TransactionMap.hxx: fixed member data name + +2002-12-06 23:48 fluffy + + * test/testIM.cxx: switched to just encrypt + +2002-12-06 23:47 fluffy + + * Security.cxx, Security.hxx, TuIM.cxx: added stuff to manage other + people public keys + +2002-12-06 23:46 fluffy + + * ParserCategories.cxx, ParserCategory.cxx, PlainContents.cxx: + fixed MIME and paramter parsing + +2002-12-06 23:46 fluffy + + * Uri.cxx, Uri.hxx: added getAorNoPOrt + +2002-12-06 23:43 fluffy + + * os/Data.cxx: reduce mem realloc on esacped stuff + +2002-12-06 19:24 derekm + + * os/Log.cxx, os/Log.hxx, os/Logger.hxx, os/Makefile, + test/testLogger.cxx, test/testThreadIf.cxx: Logger now has + thread-level "service" level settings. Won't work on windows yet. + + some tests for ThreadIf some 'tests' for logging -- not complete + +2002-12-06 17:21 derekm + + * test/: testDigestAuthentication.cxx, testParserCategories.cxx: + [no log message] + +2002-12-06 17:09 derekm + + * ParserCategories.cxx, ParserCategories.hxx: fixed copy + constructor + +2002-12-06 13:47 fluffy + + * test/testDigestAuthentication.cxx: added incldue for auto_ptr + +2002-12-06 12:49 derekm + + * os/ThreadIf.cxx: [no log message] + +2002-12-05 22:19 davidb + + * ParserCategories.cxx: implemented NameAddr(const Uri&) + +2002-12-05 19:51 jason + + * os/ThreadIf.hxx: allow subclasses of ThreadIf to access member + vars + +2002-12-05 19:50 jason + + * SipStack.hxx, .cvsignore: [no log message] + +2002-12-05 19:50 jason + + * Helper.cxx: added an default implementation of makeCancel + +2002-12-05 19:39 derekm + + * SdpContents.cxx, SdpContents.hxx, SipMessage.cxx, SipMessage.hxx, + test/testSdp.cxx, test/testSipMessage.cxx: sdp interface has + changed to allow assembly--still a work/design in progress. + attributes are now multi, so getValue returns a list<Data> + + new tests, some fixes to encode. + +2002-12-05 19:35 derekm + + * Helper.cxx, Helper.hxx: changed paramter name from + encodedPassword to password, as its not encoded + +2002-12-05 17:33 derekm + + * os/Makefile, os/ThreadIf.cxx, os/ThreadIf.hxx, + test/testThreadIf.cxx: added + + ThreadIf::waitForShutdown(int ms) const + + which causes the thread to sleep for the specified# of ms, but will + wakeup and return true if shutdown is called. Returns false if the + sleep finished w/out shutdown being called. + + shutdown&join are now called in the destructor. it is now ok to + call join multiple times, nothing happens if there isn't an active + thread. + +2002-12-05 08:51 fluffy + + * IntegerParameter.cxx: fixed windows compile warning + +2002-12-04 21:36 davidb + + * Preparse.cxx, Symbols.cxx, Symbols.hxx, os/ParseBuffer.cxx, + os/ParseBuffer.hxx, test/testParseBuffer.cxx: all Symbols now Data + -- impacted ParseBuffer interface + +2002-12-04 21:35 davidb + + * BranchParameter.cxx, Contents.cxx, Contents.hxx, + MessageWaitingContents.cxx, MultipartMixedContents.cxx, + MultipartMixedContents.hxx, Pkcs7Contents.cxx, PlainContents.cxx, + SdpContents.cxx, Security.hxx, SipFrag.cxx, + test/testPlainContents.cxx, test/testSipMessage.cxx: Contents must + be constructed with the leaf Mime contents type + +2002-12-04 20:38 davidb + + * os/: ParseBuffer.cxx, ParseBuffer.hxx: added skipToChars -- scan + for string + +2002-12-04 20:36 davidb + + * SipMessage.cxx: body => contents + +2002-12-04 20:35 davidb + + * Contents.cxx, Contents.hxx, LazyParser.hxx, Makefile, + MessageWaitingContents.cxx, MessageWaitingContents.hxx, + MultipartMixedContents.cxx, MultipartMixedContents.hxx, + Pkcs7Contents.cxx, Pkcs7Contents.hxx, PlainContents.cxx, + PlainContents.hxx, SdpContents.cxx, SdpContents.hxx, Security.cxx, + SipFrag.cxx, SipFrag.hxx: added multipart/mixed changed to + getStaticType() -- getType() returns Mime plus parameters + +2002-12-04 17:02 derekm + + * os/Random.cxx: removed Logs in static initialization + +2002-12-04 12:46 derekm + + * test/: Makefile, digcalc.hxx, md5.cxx, md5.hxx, + testDigestAuthentication.cxx: digest authentication tests--checks + against rfc 2617 implementation + +2002-12-04 12:44 derekm + + * Helper.cxx, Helper.hxx, Makefile, ParserContainer.hxx, + Symbols.cxx, Symbols.hxx, parameters.gperf, os/Data.cxx, + os/Data.hxx, os/MD5Stream.cxx, os/MD5Stream.hxx, os/Makefile: added + digest authentication helpers, only for md5, qop auth or none + supported changed Data::hex to output lowercase const_iterator on + ParserContainer added MD5Stream -- should be used instead of + concatenating Datas + +2002-12-03 15:55 ryker + + * TransactionState.cxx: Reuse the INVITE DNS query results for + CANCEL in the client transaction case. RFC 3261 says that the + CANCEL MUST be sent to an identical destination address, port, and + transport. + +2002-12-03 12:21 ryker + + * TransactionState.cxx: Correct very misleading debugging + statement. + +2002-12-03 11:44 ryker + + * TransactionState.cxx: - Added a bit of debugging, namely warn + about unhandled msgs to transactions. - Made the CANCEL + transaction work. This involved a fair bit of work to reconcile + the overlapping transaction ids for INVITE and CANCEL. I had to + make sure the non-INVITE routines were called for the CANCEL + version of each transaction. + +2002-12-03 09:10 ryker + + * TransactionState.cxx: In the INVITE client transaction, Timer B + only applies in the Calling state. + +2002-12-03 09:02 ryker + + * SipMessage.cxx: Whoops... back out the last change as Derek did + something equivalent already. + +2002-12-03 08:57 ryker + + * SipMessage.cxx: Always print a Content-Length header at the end + of the headers section. + +2002-12-02 17:05 derekm + + * Dialog.cxx, Headers.cxx, Headers.hxx, SipMessage.cxx, + SipMessage.hxx: auth headers are mostly multi + +2002-12-02 15:43 derekm + + * test/Makefile: commented out testTcpTransport + +2002-12-02 15:43 derekm + + * test/testSipMessage.cxx: added construction test; test + Content-Length encoding + +2002-12-02 15:42 derekm + + * os/: Random.cxx, Random.hxx, Timer.cxx: static initialization; + removed DebugLog in static initializers + +2002-12-02 15:41 derekm + + * os/DataStream.cxx: flush on desctruction + +2002-12-02 15:41 derekm + + * os/Data.cxx: using character version of +=, reduced initial size + in escaped + +2002-12-02 15:35 derekm + + * SipMessage.cxx: encode Content-Length even if the header doesn't + exist + +2002-12-02 15:31 derekm + + * BranchParameter.cxx, BranchParameter.hxx, DataParameter.cxx, + DataParameter.hxx, ExistsParameter.cxx, ExistsParameter.hxx, + FloatParameter.cxx, FloatParameter.hxx, IntegerParameter.cxx, + IntegerParameter.hxx, ParameterTypeEnums.hxx, ParserCategories.cxx, + ParserCategories.hxx, ParserCategory.cxx, QopParameter.cxx, + QopParameter.hxx, QuotedDataParameter.cxx, QuotedDataParameter.hxx, + test/testParserCategories.cxx: re-factored terminating characters + in Parameter parsing added auth parameters + +2002-12-02 11:48 kdc + + * SdpContents.hxx: added const to getSession() fixed Bandwith + spelling error + +2002-12-01 12:33 fluffy + + * Security.hxx, TuIM.cxx, test/testIM.cxx: fix to compile on + windows + +2002-11-30 23:06 fluffy + + * test/testIM.cxx: updated + +2002-11-30 22:40 fluffy + + * Security.cxx, Security.hxx, TuIM.cxx, TuIM.hxx, test/testIM.cxx: + refactored security interface + +2002-11-30 21:18 fluffy + + * MessageWaitingContents.cxx: [no log message] + +2002-11-30 21:07 fluffy + + * Contents.cxx, Contents.hxx, MessageWaitingContents.hxx, + Pkcs7Contents.cxx, Pkcs7Contents.hxx, PlainContents.cxx, + PlainContents.hxx, SdpContents.cxx, SdpContents.hxx, Security.cxx, + Security.hxx, SipFrag.cxx, SipFrag.hxx, Symbols.cxx, Symbols.hxx, + TransactionState.cxx, TuIM.cxx, test/testIM.cxx: many changes for + SMIME stuff + +2002-11-30 21:06 fluffy + + * os/Data.cxx: fixed bug zero len stuff + +2002-11-30 15:04 fluffy + + * Security.cxx, os/Data.cxx: few changes + +2002-11-30 12:57 fluffy + + * Pkcs7Contents.cxx, Security.cxx, Security.hxx, test/testIM.cxx: + updated and removed hard coded cert paths + +2002-11-30 12:56 fluffy + + * Contents.hxx, Message.cxx, Transport.cxx, TransportSelector.cxx, + UdpTransport.cxx: made debug prints be escaped data + +2002-11-30 12:56 fluffy + + * os/: Data.cxx, Data.hxx: addec escaped function and fixed but in + constructor + +2002-11-30 10:22 fluffy + + * BranchParameter.cxx, SipMessage.cxx, Symbols.cxx: changed branch + tag creation to reduce odds of transaction id conflict + +2002-11-29 20:42 fluffy + + * Pkcs7Contents.cxx, Security.cxx: changed to do the binary PKCS7 + format instead of SMIME + +2002-11-29 20:30 fluffy + + * Makefile, Pkcs7Contents.cxx, Pkcs7Contents.hxx, Security.cxx, + Security.hxx, TuIM.cxx, test/testIM.cxx: very basic sign and verify + working + +2002-11-29 20:29 fluffy + + * PlainContents.cxx: fixed extra CRLF bug + +2002-11-29 10:36 fluffy + + * LazyParser.cxx, PreparseInlines.cxx, SdpContents.cxx, + SdpContents.hxx, SipStack.cxx, TuIM.cxx, UdpTransport.cxx, + test/testSpeed.cxx: compile and sort of work in windows + +2002-11-29 10:35 fluffy + + * os/: Condition.cxx, Data.cxx, Random.cxx: compile and work in + windows + +2002-11-29 00:56 fluffy + + * test/: Makefile, testSpeed.cxx: added speed test program + +2002-11-29 00:56 fluffy + + * Dialog.cxx, Dialog.hxx: create from just a response instead of + requiring request too + +2002-11-29 00:55 fluffy + + * Executive.cxx: noted bug + +2002-11-29 00:55 fluffy + + * SipMessage.cxx: made breif more useful + +2002-11-29 00:54 fluffy + + * os/Timer.hxx: added code to get cpuSpeed + +2002-11-29 00:54 fluffy + + * os/.cvsignore, test/.cvsignore: ingnore otehr directories + +2002-11-28 15:29 ryker + + * TransactionState.cxx: Don't delete mCancelStateMachine when a + TransactionState is deleted. mCancelStateMachine is another + TransactionState that holds a new CANCEL transaction FSM. I think + this is bad design and we should create an mCancelStateMachine-like + object free of a host TransactionState. + +2002-11-28 13:01 ryker + + * Makefile: Add new file to compile list. + +2002-11-28 12:48 alan + + * test/testSdp.cxx: testSdp -- added reporting + +2002-11-28 09:12 ryker + + * os/Data.hxx: Make isLessThanNoCase() work. + +2002-11-28 08:51 alan + + * Makefile: Added entry for QopParameter + +2002-11-27 19:49 jason + + * ParserContainer.hxx: added stuff for stl algorithms + +2002-11-27 19:49 jason + + * ParserCategories.cxx, ParserCategories.hxx: added operator< for + Token added accessor to wildcard for NameAddr + +2002-11-27 19:39 derekm + + * DataParameter.hxx, ParameterTypeEnums.hxx, ParameterTypes.cxx, + ParameterTypes.hxx, ParserCategories.cxx, QopParameter.cxx, + QopParameter.hxx, QuotedDataParameter.cxx, QuotedDataParameter.hxx, + Symbols.cxx, Symbols.hxx: working on auth parsercategory not + finished...but all of the tests passed. + +2002-11-27 17:19 jason + + * Helper.cxx, Helper.hxx: added interface for authentication added + makeUri from aor + +2002-11-27 17:19 jason + + * SipStack.cxx, SipStack.hxx: added isMyDomain() method + +2002-11-27 17:19 jason + + * UdpTransport.cxx: added comment that inet_ntoa is not reentrant + +2002-11-27 17:19 jason + + * os/: Data.cxx, Data.hxx: added Data::substr method + +2002-11-27 17:09 alan + + * test/SipTortureTests.cxx: Fixed Some test cases. Improved + Reporting. Checked for completion. + +2002-11-27 17:09 alan + + * test/tassert.h: Added better reporting features. + +2002-11-27 17:08 alan + + * Preparse.cxx: Cleaned up debugging. Made it possible to turn + on/off at runtime. + +2002-11-27 17:07 alan + + * ParserCategories.cxx: Removed exception based expires parser -- + changed to logic test + +2002-11-27 16:09 derekm + + * test/testParserCategories.cxx: [no log message] + +2002-11-27 16:09 derekm + + * BranchParameter.cxx: fixed...didn't terminate paramater parse + correctly + +2002-11-27 12:31 alan + + * test/.cvsignore: removed tassert.h + +2002-11-27 11:42 kdc + + * SipMessage.cxx: fixed up some contents stuff + +2002-11-27 11:38 derekm + + * test/testSipMessage.cxx: [no log message] + +2002-11-27 11:37 derekm + + * test/SipTortureTests.cxx: removed false negative from + SipTortureTests + +2002-11-27 11:37 derekm + + * HeaderTypes.hxx, Headers.cxx, Headers.hxx, Symbols.cxx, + Symbols.hxx, headers.gperf: added more headers to the GPerf(most of + the new ones are mapped to unknown) + + added AllowEvent, Event as real headers + +2002-11-26 14:15 derekm + + * ParserCategories.cxx, ParserCategories.hxx: fixed operator < for + Mime fixed accessors for Mime + +2002-11-26 13:46 alan + + * TuIM.cxx: removed ^M s and added a bunch of ^J s. Darned DOS + people :-P :-) + +2002-11-26 13:37 alan + + * test/: TestSupport.cxx, TestSupport.hxx: initial impound + +2002-11-26 13:37 alan + + * test/testPreparse.cxx: ported to new interface changed diagnostic + calls to use TestSupport + +2002-11-26 13:37 alan + + * test/: testNonInviteClientTx.cxx, testSipFrag.cxx, + testSipMessage.cxx, testSipMessageMemory.cxx, + testTransactionFSM.cxx: ported makeMessage to new location + +2002-11-26 13:37 alan + + * test/: testIM.cxx, testSipStackInvite.cxx, testTcpTransport.cxx: + removed unused include + +2002-11-26 13:37 alan + + * test/test2.cxx: increased loop count + +2002-11-26 13:37 alan + + * test/SipTortureTests.cxx: Fixed typos in messages + +2002-11-26 13:37 alan + + * test/Makefile: Added TestSupport + +2002-11-26 13:37 alan + + * SipFrag.cxx, UdpTransport.cxx: updated preparse interface + +2002-11-26 13:37 alan + + * PreparseInlines.cxx: inline Preparse routines + +2002-11-26 13:37 alan + + * Preparse.hxx: cleanup of straggling private types new interface + for process() new routines + +2002-11-26 13:37 alan + + * Preparse.cxx: moved diagnostic output routines to + test/TestSupport removed complex interface and added functions for + status reporting + +2002-11-26 13:37 alan + + * Makefile: added inline switch for Preparse inline functions + +2002-11-26 13:37 alan + + * Helper.cxx, Helper.hxx: removed makeMessage() -- put in + test/TestSupport + +2002-11-26 12:13 davidb + + * Contents.cxx, Contents.hxx, MessageWaitingContents.cxx, + MessageWaitingContents.hxx, PlainContents.cxx, PlainContents.hxx, + SdpContents.cxx, SdpContents.hxx, SipFrag.cxx, SipFrag.hxx, + SipMessage.cxx, test/testMessageWaiting.cxx, + test/testPlainContents.cxx, test/testSdp.cxx: creating Contents + against HFV and now Mime instance (for parameters) + +2002-11-26 10:13 davidb + + * TuIM.cxx, TuIM.hxx, test/testIM.cxx: used PlainContents as + intended + +2002-11-26 10:05 davidb + + * Contents.cxx, Contents.hxx: access Contents via getContents() -- + allows wrappers like signed, encrypted access Contents via + getContents(cinst Mime&) -- null if not given Mime type + +2002-11-26 10:03 davidb + + * test/: Makefile, testPlainContents.cxx: [no log message] + +2002-11-26 10:02 davidb + + * PlainContents.cxx, PlainContents.hxx: fluffed (de-fluffed?) up + PlainContents + +2002-11-25 21:27 fluffy + + * Makefile, PlainContents.cxx, PlainContents.hxx, SipMessage.cxx, + TuIM.cxx, test/Makefile, test/SipTortureTests.cxx, test/testIM.cxx: + Updated to use new Content class for body stuff for TuIM + +2002-11-25 18:28 davidb + + * test/: testSipFrag.cxx, Makefile: [no log message] + +2002-11-25 18:28 davidb + + * LazyParser.cxx, LazyParser.hxx, Makefile, + MessageWaitingContents.cxx, MessageWaitingContents.hxx, + ParserCategories.cxx, ParserCategories.hxx, ParserCategory.hxx, + ParserContainer.hxx, SdpContents.cxx, SdpContents.hxx, SipFrag.cxx, + SipFrag.hxx, SipMessage.cxx, Uri.cxx, Uri.hxx: changed encode to + encodeParsed in subclasses of lazyParser--lazyParser now has a + non-virtual parse + + added sipFrag + +2002-11-25 14:12 ryker + + * os/Data.hxx: Add isLessThanNoCase(). + +2002-11-25 12:15 davidb + + * test/.cvsignore: [no log message] + +2002-11-25 12:14 davidb + + * test/: testMessageWaiting.cxx, testSdp.cxx, testSipMessage.cxx: + modified for Contents added extension header test + +2002-11-25 12:14 davidb + + * Makefile, test/Makefile: commented out IM stuff -- not quite + ready for not-quite-prime time + +2002-11-25 12:13 davidb + + * Helper.cxx: removed Debug + +2002-11-25 12:12 davidb + + * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, + ParserContainer.hxx, ParserContainerBase.hxx, SipMessage.cxx: + generalized encode to unify with extension headers + +2002-11-25 11:54 davidb + + * Helper.cxx: [no log message] + +2002-11-25 11:30 davidb + + * .cvsignore: [no log message] + +2002-11-25 11:30 davidb + + * os/: Makefile, ParseBuffer.cxx, ParseBuffer.hxx: added skipChars + which skips a string + +2002-11-25 11:29 davidb + + * os/: DataStream.cxx, DataStream.hxx: prettified + +2002-11-25 11:29 davidb + + * os/: Data.cxx, Data.hxx: removed string related functions no + allocation on empty copy + +2002-11-25 11:29 davidb + + * os/CountStream.cxx, os/CountStream.hxx, test/testCountStream.cxx: + CountStream--used to efficiently determine Content Size + +2002-11-25 11:28 davidb + + * Symbols.cxx, Symbols.hxx: added LPAREN, RPAREN + +2002-11-25 11:27 davidb + + * IntegerParameter.cxx, os/TODO, test/testData.cxx, + test/testParseBuffer.cxx: [no log message] + +2002-11-25 11:27 davidb + + * Dialog.cxx, Helper.cxx: content length is not exposed to + application + +2002-11-25 11:26 davidb + + * Contents.cxx, Contents.hxx, LazyParser.cxx, LazyParser.hxx, + Makefile, MessageWaitingContents.cxx, MessageWaitingContents.hxx, + ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, + ParserCategory.hxx, SdpContents.cxx, SdpContents.hxx, + SipMessage.cxx, SipMessage.hxx, test/Makefile, + test/testMessageWaiting.cxx, test/testSdp.cxx, + test/testSipMessage.cxx: lazy parser as base for ParserCategory and + Contents. added MessageWaitingContents, SdpContents. + +2002-11-24 16:41 fluffy + + * Makefile, Security.cxx, Security.hxx, SipStack.cxx, SipStack.hxx: + added Security stuff + +2002-11-23 23:48 fluffy + + * Helper.cxx, Makefile, SipStack.hxx, TuIM.cxx, TuIM.hxx, + test/Makefile, test/test2.cxx, test/testIM.cxx, test/testIM.hxx, + test/testSipStack1.cxx: added IM stuff and changed Random stuff + +2002-11-23 23:47 fluffy + + * os/Random.cxx: few trivial changes + +2002-11-23 14:06 fluffy + + * Helper.cxx, Makefile, SipStack.cxx, test/Makefile, + test/Transceiver.cxx, test/testTcpTransport.cxx, os/Data.cxx, + os/Data.hxx, os/Makefile, os/RandomHex.cxx, os/RandomHex.hxx, + test/testDataPerformance.cxx, test/testRandomHex.cxx: fixed Random + Number stuff + +2002-11-23 13:59 fluffy + + * os/: Random.cxx, Random.hxx: [no log message] + +2002-11-23 10:55 fluffy + + * SipStack.hxx, test/testDnsResolver.cxx, + test/testTransactionFSM.cxx: Changed some things from public to + private in the SipStack.hxx and fixed issues cuased by this. + +2002-11-22 16:04 alan + + * SipMessage.cxx: Added encoder call to 2543 tid case. (NULs in tid + were causing problems (also makes it printable) + +2002-11-20 13:16 ryker + + * TransactionState.cxx: In the server non-INVITE transaction also + resent the mMsgToRetransmit if we get a message from the wire in + the Completed state. Also, don't assert(0) in the "stale" + transaction if we get a timer message other than the stale timer. + Just print out the message and continue on. + +2002-11-20 10:45 ryker + + * SipMessage.cxx: Check for mBody == 0. + +2002-11-20 10:05 ryker + + * TransactionState.cxx: Make sure a SIP message is a request before + asking if it's an ACK. + +2002-11-20 09:51 ryker + + * SipMessage.cxx, SipMessage.hxx: Add updateContentLength() to + class SipMessage. This sets a Content-Length header in the message + based on the size of its body including 0 if the body hasn't been + touched yet. + +2002-11-20 08:53 ryker + + * SipMessage.cxx, SipMessage.hxx: Add a temporary getBody() method + so people can continue working before a rich body and MIME + infrastructure is in place. + +2002-11-19 15:30 ryker + + * SipMessage.cxx: Only ask for a From tag if we know it exists. + Also ask for the from tag, not a tag on the From URI. + +2002-11-19 14:50 ryker + + * SipMessage.cxx: For an RFC 2543 transaction id, don't factor in + the branch if no branch exists in the message. My Cisco 7960 load, + for example, will send an INVITE without a branch. This fix + prevents the getTransactionId() function from creating a branch in + the message when none should be there. + +2002-11-19 11:05 davidb + + * test/testSipMessage.cxx: [no log message] + +2002-11-19 11:05 davidb + + * ParserContainer.hxx: fixed leak in pop + +2002-11-19 11:04 davidb + + * ParserCategories.cxx: allow parameters after integer in Expires + +2002-11-18 18:44 derekm + + * os/Log.cxx: string constructor is no longer explicit--made + necessary changes + +2002-11-18 18:44 derekm + + * os/: Data.cxx, Data.hxx: more comparison operators. string + constructor is no longer explicit + +2002-11-18 18:43 derekm + + * test/: testParserCategories.cxx, testSipMessage.cxx, + testData.cxx: [no log message] + +2002-11-18 18:42 derekm + + * Uri.hxx: removed unused member mPortSpecified + +2002-11-18 18:42 derekm + + * Uri.cxx: calls checkparsed in getAor + +2002-11-18 18:42 derekm + + * SipStack.cxx: wrapped win32 warning pragma inside an ifdef + +2002-11-18 18:40 derekm + + * IntegerParameter.cxx: No longer is always 3600 when this is an + expires param. + +2002-11-18 14:04 ryker + + * TransactionState.cxx: Check to see that a dynamic_cast succeeded + before indirecting through the resultant pointer. + +2002-11-18 11:02 ryker + + * TransactionState.cxx: Prevent the stack from sending more than + one 100. We do this by moving to a Trying state on receipt of an + INVITE. If the TU sends a 1xx we move to Proceeding. Likewise if + the timer for sending a 100 expires, the stack sends a 100 and + moves to Proceeding. If the timer fires and the state is already + Proceeding (by virtue of a 1xx from the TU already) then we ignore + the timer. This just makes the code match a server INVITE FSM + diagram I have. + +2002-11-18 10:07 ryker + + * TransactionState.cxx: In the INVITE server transaction the Trying + and Proceeding states collapse into one. For 100 messages, + however, we were only testing against the Trying state and not the + Proceeding state too. + +2002-11-15 18:53 derekm + + * os/Data.cxx: long construcor no longer leaks. + +2002-11-15 18:52 derekm + + * Helper.cxx: ACK is now ACK + +2002-11-15 18:52 derekm + + * Dialog.cxx: CANCEL is no longer INVITE + +2002-11-15 15:24 kdc + + * SipMessage.cxx: fixed bogus logic for via branch + +2002-11-15 10:57 alan + + * doc/.cvsignore: Added dot files + +2002-11-14 22:01 fluffy + + * os/Condition.cxx, os/Data.cxx, DnsResolver.cxx, + ParserCategories.cxx, SipStack.cxx, UdpTransport.cxx, Uri.cxx, + test/SipTortureTests.cxx, test/tassert.h: compile under windows + +2002-11-14 20:10 jason + + * Uri.cxx, Uri.hxx: [no log message] + +2002-11-14 20:06 jason + + * Uri.cxx, Uri.hxx: added interface to make uri from Data + +2002-11-14 20:06 jason + + * SipStack.hxx: [no log message] + +2002-11-14 20:05 jason + + * Helper.hxx: added makeCancel + +2002-11-14 20:00 derekm + + * test/testData.cxx: [no log message] + +2002-11-14 19:57 derekm + + * test/test1.cxx: now actually lockstepped -- stable memory usage. + constructs message correctly. + +2002-11-14 19:56 derekm + + * test/: InviteClient.cxx, InviteClient.hxx, InviteServer.cxx, + InviteServer.hxx, Makefile, Register.cxx, Register.hxx, + Registrar.cxx, Registrar.hxx, Transceiver.cxx, Transceiver.hxx, + lg.cxx: a small 'loadgen' test. + +2002-11-14 19:53 derekm + + * UdpTransport.cxx: fixed leak. the buffer that was being allocated + was not deleted when EWOULDBLOCK was the result of read + +2002-11-14 17:40 fluffy + + * test/test1.cxx: fixed includes to compile in linux + +2002-11-14 17:37 fluffy + + * os/Condition.cxx: fixed includes to compile in linux + +2002-11-14 17:22 davidb + + * FAQ: feel free to contribute... + +2002-11-14 17:22 davidb + + * test/SipTortureTests.cxx: added the next test + +2002-11-14 17:20 davidb + + * Headers.hxx, ParserCategories.cxx, ParserCategories.hxx: added + Expires parser category fixed some problems with IntegerCategory + comment + +2002-11-14 15:11 derekm + + * UdpTransport.cxx: reverted cullens change--his code does not work + on linux + +2002-11-14 13:04 derekm + + * HeaderFieldValue.hxx, ParserCategory.cxx: un-'fixed' + ParserCategory constructor. + + In the ParserCategory constructor thats takes an hfv, the + parsercategory is considered parsed if the hfv has no contents. + This requires that the default constructor of the hfv set mField to + zero. + +2002-11-14 12:17 davidb + + * ParserCategories.cxx, Uri.cxx, Uri.hxx: rewrote the NameAddr and + Uri Data parsers again. + +2002-11-14 12:15 derekm + + * os/: Condition.cxx, Condition.hxx: Added timed wait--only for + linux + +2002-11-14 11:49 fluffy + + * os/Mutex.cxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, + os/Socket.cxx, os/Socket.hxx, SipStack.cxx, TransportSelector.cxx, + test/test2.cxx: few windows fixes + +2002-11-14 10:48 jason + + * Makefile, test/Makefile, test/Resolver.cxx, test/Resolver.hxx, + test/test1.cxx: moved Resolver.?xx into test directory + +2002-11-14 10:22 fluffy + + * TransportSelector.cxx: removed resolver + +2002-11-14 10:13 fluffy + + * Resolver.cxx, Resolver.hxx, SIPSTACK.dsp, SIPSTACK.dsw: no longer + used + +2002-11-14 10:12 fluffy + + * UdpTransport.cxx: compile in windows may have broken received + address tag + +2002-11-14 10:10 fluffy + + * DnsResolver.cxx: compile in windows + +2002-11-14 10:10 fluffy + + * Resolver.cxx, Resolver.hxx: no longer used + +2002-11-14 09:26 jason + + * test/: .cvsignore, Makefile, test1.cxx: [no log message] + +2002-11-13 19:36 davidb + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, ParserCategories.cxx, + ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, + test/testParserCategories.cxx: simplified constructor of NameAddr + from Data + +2002-11-13 17:50 alan + + * doc/: Makefile, fsm-dot.awk, static/Preparse.pdf, + static/Preparse.png, static/Preparse.ps, static/Preparse.svg: PNG + formatted better now + +2002-11-13 17:21 ryker + + * TransactionState.cxx: Validate that a message is indeed a request + before asking if it's an ACK. + +2002-11-13 17:20 alan + + * TransportSelector.cxx: Added check to ensure that the message is + a request before ACK + +2002-11-13 16:43 ryker + + * UdpTransport.cxx: Fix logic in test of preparse status result. + +2002-11-13 15:54 jason + + * os/compat.hxx: fixes for qnx + +2002-11-13 15:31 jason + + * test/testParserCategories.cxx: [no log message] + +2002-11-13 14:40 ryker + + * TransactionState.cxx: More fixing the ACK pseudotransaction. + This involved getting rid of special ACK processing for the + incoming case and actually dispatching to the right machine for the + outgoing case. Furthermore the processAck() logic has been fixed + to enable retries on transport failure and die on transport + success. Although this will enable a TU to complete the 3-way + handshake in the common case, the ACK pseudotransaction can't + really satisfy RFC 3263 as it should due to problems assessing + success or failure in the transport. + +2002-11-13 14:38 davidb + + * test/testSipMessage.cxx: added test for expires="Sat, 01 Dec 2040 + 16:00:00 GMT" => 3600 + +2002-11-13 14:38 davidb + + * ParserCategories.cxx: removed Alan's hack for other Uri types + +2002-11-13 14:37 davidb + + * IntegerParameter.cxx: backward compatible for expires="Sat, 01 + Dec 2040 16:00:00 GMT" + +2002-11-13 14:16 ryker + + * TransportSelector.cxx: In the TransportSelector send() routine we + also (yes this is lame) need to find out if the message is an ACK + and if so add "ACK" to the transaction id. This relates to the + need to have the same branch parameter in the INVITE and ACK but + have different transaction ids for the purpose of dispatching to + the correct code. + +2002-11-13 13:45 alan + + * ConnectionMap.cxx: Removed unused var + +2002-11-13 12:42 davidb + + * os/: Data.cxx, Data.hxx: added clear() added some asserts + +2002-11-13 12:41 davidb + + * os/Logger.hxx: simplified macros to work everywhere + +2002-11-13 12:41 davidb + + * os/: ParseBuffer.cxx, ParseBuffer.hxx: added copy constructor and + operator= + +2002-11-13 10:05 jason + + * test/: .cvsignore, testSipMessageMemory.cxx, torture-test.txt: + [no log message] + +2002-11-13 09:56 jason + + * ParserCategories.cxx, ParserCategories.hxx, TcpTransport.cxx, + TransactionState.cxx, UdpTransport.cxx, os/Logger.hxx, + os/compat.hxx, test/.cvsignore, test/testCoders.cxx, + test/.cvsignore, test/testParserCategories.cxx: fixed to compile on + qnx/neutrino 6.0 with gcc 2.95 + +2002-11-13 09:07 jason + + * test/: Makefile, testNonInviteClientTx.cxx, testTcpTransport.cxx: + get it to compile again + +2002-11-12 15:33 ryker + + * TransportSelector.cxx: In the case of an ACK request we need to + hack the transaction id passed to the DNS resolver to reflect that + it's an ACK. I'm not too happy with this but it does seem to make + the INVITE client transaction work. I think the ACK + pseudotransaction in TransactionState.cxx will never get cleaned up + now, though. + +2002-11-12 14:03 ryker + + * TransactionState.cxx: Improve the handling of DnsMessage events + in processAck(). + +2002-11-12 09:18 ryker + + * os/Data.cxx: Make this compile again by #including <math.h>. + This is needed on my DeadRat 7.3 install with gcc 2.96. + +2002-11-12 00:05 alan + + * Preparse.cxx: Turned off DEBUG + +2002-11-11 23:42 alan + + * ConnectionMap.cxx, ConnectionMap.hxx, Helper.cxx, Preparse.cxx, + Preparse.hxx, UdpTransport.cxx, test/SipTortureTests.cxx, + test/testPreparse.cxx: Preparse Fragment Support. + +2002-11-11 22:42 alan + + * .cvsignore, ChangeLog, ParserCategories.cxx, SipMessage.cxx, + Uri.cxx, test/SipTortureTests.cxx, test/tassert.h, + test/testSipStack1.cxx: Updates to support torture tests. + +2002-11-11 22:42 alan + + * ConnectionMap.cxx: Final fragmentation pre-merge + +2002-11-11 22:41 alan + + * Helper.cxx, Preparse.cxx, Preparse.hxx, UdpTransport.cxx, + test/testPreparse.cxx: Pre-merge fragmentation implementation + +2002-11-11 22:35 alan + + * test/.cvsignore: dded misc + +2002-11-11 21:16 jason + + * os/: Data.cxx, Data.hxx: added some explicit constructors for + double, int, char, unsigned long and convertInt and convertFloat + +2002-11-11 21:16 jason + + * os/: Condition.cxx, Condition.hxx: support broadcast in the + Condition + +2002-11-11 21:15 jason + + * os/: Lock.cxx, Lock.hxx, Mutex.hxx, RWMutex.cxx, RWMutex.hxx, + Makefile: extend Locks to support ReadersWriter + +2002-11-11 21:14 jason + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, ParserCategories.hxx, + ParserCategory.cxx, ParserCategory.hxx: added capability to create + a NameAddr (or other ParserCategories) from an unparsed Data. + +2002-11-11 15:58 ryker + + * test/testTFSM-clientinvite: Flesh out test more. + +2002-11-11 15:32 ryker + + * TransactionState.cxx: - Handle DnsMessage event in the client + invite transaction. - Send a 503 to the TU in case Timer B fires, + killing the same transaction. + +2002-11-11 15:09 jason + + * os/: BaseException.hxx, CircularBuffer.hxx, Coders.hxx, Data.hxx, + Fifo.hxx, Lock.hxx, Lockable.hxx, vmd5.hxx, vthread.hxx: avoid more + vocal1 namespace conflicts + +2002-11-11 14:46 ryker + + * test/: testTFSM-clientinvite, testTFSM-clientnoninvite: Add + testTFSM-clientinvite. + +2002-11-11 14:38 kdc + + * test/Makefile: removed testtransport stuff + +2002-11-11 14:37 kdc + + * Makefile, TestTransport.cxx, TestTransport.hxx, + TransactionState.cxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, TransportSelector.hxx, + test/testTFSM-clientnoninvite, test/testTransactionFSM.cxx: removed + TestTransport stuff fixed resend fixed timer discarding for deleted + transactions added client noninvite test + +2002-11-11 14:05 jason + + * os/: Condition.hxx, Data.hxx, DataStream.hxx, Fifo.hxx, + HashMap.hxx, Inserter.hxx, Lock.hxx, Lockable.hxx, Log.hxx, + Logger.hxx, Mutex.hxx, ParseBuffer.hxx, RandomHex.hxx, Socket.hxx, + Subsystem.hxx, SysLogBuf.hxx, SysLogStream.hxx, ThreadIf.hxx, + Timer.hxx, vmd5.hxx, vthread.hxx: change #ifndef guards to have + Vocal2 prefix to avoid collisions with Vocal1 files + +2002-11-11 13:46 jason + + * Dialog.hxx, ParseException.hxx, SipMessage.hxx, Transport.cxx, + Transport.hxx, TransportSelector.cxx, os/BaseException.cxx, + os/BaseException.hxx, os/Makefile, os/ParseBuffer.hxx, + os/VException.cxx, os/VException.hxx: rename VException to + BaseException + +2002-11-11 11:06 derekm + + * Transport.cxx: toTransport is now case insensitive. + +2002-11-11 10:39 ryker + + * TransactionState.cxx: Initialise mDnsState in the + TransactionState ctor. This fixes a couple of problems (including + a SEGV) that prevented responses from being sent properly. + +2002-11-11 10:35 ryker + + * test/testTransactionFSM.cxx: Add PASS/FAIL on completion plus + complete port to UDP transport. + +2002-11-11 08:58 ryker + + * test/: testTFSM-remoteinvite.dat, testTFSM-remotenoninvite.dat, + testTFSM-serverinvite, testTFSM-servernoninvite: Make names match + RFC. Also change them to specify UDP. + +2002-11-11 08:57 ryker + + * test/testTransactionFSM.cxx: Use UDP transport. + +2002-11-10 20:56 alan + + * ConnectionMap.cxx, Preparse.cxx, Preparse.hxx, UdpTransport.cxx, + test/testPreparse.cxx: Interim fixups + +2002-11-10 12:44 alan + + * ConnectionMap.cxx, UdpTransport.cxx, Helper.cxx: TEMPO W/A + +2002-11-09 23:08 alan + + * test/testPreparse.cxx: More acid tests + +2002-11-09 23:02 alan + + * doc/static/: Preparse.pdf, Preparse.png, Preparse.ps, + Preparse.svg: Updates for leading blanks in headers. + +2002-11-09 23:01 alan + + * Preparse.cxx: Fixed DATA error in early header continuation. + +2002-11-09 21:59 alan + + * Preparse.cxx, Preparse.hxx, test/testPreparse.cxx: Added fixes + for continuations. + +2002-11-09 21:32 alan + + * doc/static/: Preparse.pdf, Preparse.png, Preparse.ps, + Preparse.svg: Updates to PP + +2002-11-09 20:35 alan + + * doc/static/: Preparse.pdf, Preparse.png, Preparse.ps, + Preparse.svg: Preparser State Updates -- typo repair + +2002-11-09 20:32 alan + + * doc/static/: Preparse.pdf, Preparse.png, Preparse.ps, + Preparse.svg: Preparser State Updates + +2002-11-09 19:45 alan + + * Preparse.cxx, Preparse.hxx, test/testPreparse.cxx: Initial revamp + of fragmentation Integration with remainder of stack still + required. + +2002-11-08 18:47 derekm + + * SipMessage.cxx, SipMessage.hxx: added getSource method, which + returns where this message came from as a Transport::Tuple + +2002-11-08 18:46 derekm + + * Resolver.cxx, Resolver.hxx: New constructor--don't need to make a + URI. + +2002-11-08 18:46 derekm + + * ParserCategories.cxx: Fixed CallId operator== + + Always enodes NameAddr with '<' '>' syntax. + +2002-11-08 18:45 derekm + + * Helper.cxx: Now correctly copies Record-Route into responses. + +2002-11-08 18:44 derekm + + * Dialog.cxx: Fixed CSeq for ACK messages. Added max-forwards to + requests. + +2002-11-08 18:44 derekm + + * ConnectionMap.cxx: source is now set in the message upon receipt + +2002-11-08 17:27 derekm + + * os/Fifo.cxx: [no log message] + +2002-11-08 17:06 ryker + + * test/testTFSM-remotenoninvite.dat: More detailed test. + +2002-11-08 16:17 ryker + + * TransactionState.cxx: Yet more guards on the TestTransport. + +2002-11-08 16:01 ryker + + * test/testTFSM-remotenoninvite.dat: Server Non-Invite test. The + TU passes a provisional response to a REGISTER which the stack has + to pass along. + +2002-11-08 16:00 ryker + + * test/testTransactionFSM.cxx: Print the contents of messages if we + don't expect them. + +2002-11-08 15:58 ryker + + * TransactionState.cxx: Fix guard in the other place too. + +2002-11-08 15:38 ryker + + * TransactionState.cxx: Fix use of USETESTTRANSPORT. + +2002-11-08 15:27 ryker + + * DnsResolver.cxx: Revert change Jason made from v1.7 -> v1.8 which + I think breaks name resolution. + +2002-11-08 15:27 kdc + + * test/testSipStackInvite.cxx: updated test + +2002-11-08 15:00 ryker + + * TransactionState.cxx: Fix comment. + +2002-11-08 14:57 ryker + + * TransactionState.cxx: In the Proceeding/Completed state of the + server INVITE transaction we were passing retransmissions of the + INVITE to the TU and not generating a provisional response for each + retransmission. Both problems fixed. + +2002-11-08 14:33 ryker + + * test/testTFSM-remoteinvite.dat: Test file for the server invite + transaction. + +2002-11-08 14:20 kdc + + * test/testSipStackInvite.cxx: updated to new interfaces + +2002-11-08 14:03 ryker + + * Helper.cxx: Change the Helper::makeResponse to invert the + direction of this message. For example, if the original request + came from the transport, then the constructed response should + appear to have come from the TU. + +2002-11-08 13:58 alan + + * Preparse.cxx: Fixed code. + +2002-11-08 13:55 ryker + + * TransactionState.cxx: More DNS message handling. + +2002-11-08 13:54 ryker + + * test/testTransactionFSM.cxx: More fixes. I hate this code. + +2002-11-08 13:53 alan + + * Preparse.cxx, Preparse.hxx: + Stable fixes (no frag support) until frag completed later today. + +2002-11-08 12:34 ryker + + * test/testTransactionFSM.cxx: Allow the stack to run every 100ms + and change the units of time to ms. + +2002-11-08 12:10 ryker + + * SipMessage.hxx: Add setFromExternal() member function to mirror + setFromTU(). + +2002-11-08 11:49 jason + + * Resolver.hxx, Transport.cxx: new resolver constructor Transport + ptr no longer used for comparsion in Transport::Tuple + +2002-11-08 10:46 ryker + + * Makefile, TestTransport.cxx, TestTransport.hxx, + TransactionState.cxx, Transport.cxx, Transport.hxx: Introduce the + USETESTTRANSPORT guard so we can conditionally compile out the test + transport stuff. + +2002-11-08 10:33 ryker + + * test/Makefile: Compile with -DUSETESTTRANSPORT + +2002-11-08 09:53 jason + + * test/: testCoders.cxx, testDataStream.cxx: [no log message] + +2002-11-08 09:53 jason + + * DnsResolver.cxx, Resolver.cxx, TcpTransport.cxx, + UdpTransport.cxx, os/Coders.cxx, os/Data.cxx, os/Data.hxx: added + Data::size_type and made usage consistent in the code + +2002-11-08 09:45 jason + + * os/Makefile, test/testData.cxx, test/testDataStream.cxx: [no log + message] + +2002-11-08 09:45 jason + + * os/Data.cxx: fix various bugs in Data + +2002-11-08 09:42 jason + + * UdpTransport.cxx: stamp received and rport params on incoming + requests + +2002-11-08 09:41 jason + + * TODO, test/.cvsignore, test/Makefile, + test/testNameAddrParamExclusions.cxx, + test/testSipMessageMemory.cxx: [no log message] + +2002-11-08 09:40 jason + + * Resolver.cxx: handle dotted quad case + +2002-11-08 09:40 jason + + * ParserCategory.cxx: fix bug in assignment + +2002-11-08 09:39 jason + + * ParserCategories.cxx, ParserCategories.hxx: added default + constructor for cseq strictly disallow certain things in cseq + +2002-11-08 09:38 jason + + * Helper.cxx: fix tag (not in uri) shorten callid + +2002-11-08 09:38 jason + + * DnsResolver.cxx: changes to dns resolver - don't need to remove + dups + +2002-11-08 09:37 jason + + * Dialog.cxx: various dialog bugs - found in testing + +2002-11-08 09:30 ryker + + * Transport.cxx: Add in case statements for Kevin's TestReliable + and TestUnreliable stuff. This should be conditionally compiled. + +2002-11-08 09:28 ryker + + * TestTransport.cxx: Identify the test transports by their real + names. A long time ago in a galaxy far, far away there were + dependencies on UDP which is why these transports identified + themselves that way. + +2002-11-08 09:27 ryker + + * test/testTransactionFSM.cxx: Assert if Helper::makeMessage fails. + We want to test the transaction FSM, not the Helper function (this + bit me). + +2002-11-08 09:26 ryker + + * TransactionState.cxx, TransactionState.hxx: Handle messages from + the DnsResolver. + +2002-11-08 08:11 ryker + + * test/testTransactionFSM.cxx: Whoops. Increment iterator. + +2002-11-07 16:10 ryker + + * test/testTransactionFSM.cxx: s/cerr/DebugLog/ + +2002-11-07 15:42 ryker + + * Makefile: Don't build Circular.cxx anymore. + +2002-11-07 15:30 ryker + + * test/Makefile: Add testTransactionFSM.cxx + +2002-11-07 15:30 ryker + + * test/testTransactionFSM.cxx: Update this to match how + TestTransport works now. + +2002-11-07 15:27 ryker + + * Circular.cxx, Circular.hxx, TestTransport.cxx, TestTransport.hxx: + Make the test transports use a fifo internally, not a circular + buffer. + +2002-11-07 15:01 alan + + * test/.cvsignore: Added ti ugnire + +2002-11-07 15:01 alan + + * doc/fsm-dot.awk: Updated to make cleaner diagram + +2002-11-07 13:40 jason + + * BranchParameter.cxx, Dialog.cxx, Symbols.cxx: [no log message] + +2002-11-07 12:26 jason + + * SipMessage.cxx: fix output + +2002-11-07 12:26 jason + + * Resolver.cxx: [no log message] + +2002-11-07 12:26 jason + + * Dialog.cxx: set the contact in dialog + +2002-11-07 10:40 derekm + + * ConnectionMap.cxx: fixed one bug...still largely untested + +2002-11-07 10:39 derekm + + * Dialog.cxx: Pot authentication header logic back in. + +2002-11-07 09:49 ryker + + * test/testTransactionFSM.cxx: Fixup. The main thing wrong with + this is detecting messages from the wire properly. + TestTransport.cxx needs to be fixed and then this can be updated to + match the newer, improved interface there. + +2002-11-06 20:07 fluffy + + * DnsResolver.cxx, Transport.cxx: fixed inet_ntop stuff + +2002-11-06 19:07 jason + + * BranchParameter.cxx, BranchParameter.hxx, Circular.cxx, + ConnectionMap.cxx, ConnectionMap.hxx, DataParameter.cxx, + DataParameter.hxx, Dialog.cxx, Dialog.hxx, DnsMessage.cxx, + DnsMessage.hxx, DnsResolver.cxx, DnsResolver.hxx, Executive.cxx, + Executive.hxx, ExistsParameter.cxx, ExistsParameter.hxx, + FloatParameter.cxx, FloatParameter.hxx, HeaderFieldValue.cxx, + HeaderFieldValue.hxx, HeaderFieldValueList.cxx, + HeaderFieldValueList.hxx, HeaderTypes.cxx, HeaderTypes.hxx, + Headers.cxx, Headers.hxx, Helper.cxx, Helper.hxx, + IntegerParameter.cxx, IntegerParameter.hxx, Makefile, Message.cxx, + Message.hxx, MethodTypes.cxx, Parameter.cxx, Parameter.hxx, + ParameterTypeEnums.hxx, ParameterTypes.cxx, ParameterTypes.hxx, + ParseException.hxx, ParserCategories.cxx, ParserCategories.hxx, + ParserCategory.cxx, ParserCategory.hxx, ParserContainer.hxx, + ParserContainerBase.hxx, Preparse.cxx, Preparse.hxx, + ReliabilityMessage.hxx, Resolver.cxx, Resolver.hxx, + SendingMessage.cxx, SendingMessage.hxx, SipMessage.cxx, + SipMessage.hxx, SipStack.cxx, SipStack.hxx, Symbols.cxx, + TcpTransport.cxx, TcpTransport.hxx, TestTransport.cxx, + TestTransport.hxx, TimerMessage.cxx, TimerMessage.hxx, + TimerQueue.cxx, TimerQueue.hxx, TransactionMap.cxx, + TransactionMap.hxx, TransactionState.cxx, TransactionState.hxx, + Transport.cxx, Transport.hxx, TransportMessage.hxx, + TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx, + UdpTransport.hxx, UnknownParameter.cxx, UnknownParameter.hxx, + Uri.cxx, Uri.hxx, test/test1.cxx, test/test2.cxx, + test/testHash.cxx, test/testHeaderFieldValueList.cxx, + test/testNonInviteClientTx.cxx, test/testNonInviteServerTx.cxx, + test/testParserCategories.cxx, test/testPreparse.cxx, + test/testSimpleLeak.cxx, test/testSipMessage.cxx, + test/testSipMessageMemory.cxx, test/testSipStack1.cxx, + test/testSipStackInvite.cxx, test/testTcpTransport.cxx, + test/testTimer.cxx, test/testTransactionFSM.cxx, + test/testTypes.cxx, test/testUdp.cxx, test/testpp.cxx, + os/Coders.cxx, os/Coders.hxx, os/Condition.cxx, os/Data.cxx, + os/Data.hxx, os/DataStream.cxx, os/DataStream.hxx, os/Fifo.cxx, + os/Fifo.hxx, os/Lock.cxx, os/Lock.hxx, os/Lockable.hxx, os/Log.cxx, + os/Log.hxx, os/Logger.cxx, os/Logger.hxx, os/Mutex.cxx, + os/Mutex.hxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, + os/RandomHex.cxx, os/RandomHex.hxx, os/Socket.cxx, os/Socket.hxx, + os/Subsystem.cxx, os/Subsystem.hxx, os/SysLogStream.hxx, + os/ThreadIf.cxx, os/ThreadIf.hxx, os/Timer.cxx, os/Timer.hxx, + os/VException.cxx, os/VException.hxx, os/vmd5.cxx, os/vmd5.hxx, + test/testCoders.cxx, test/testData.cxx, + test/testDataPerformance.cxx, test/testDataStream.cxx, + test/testParseBuffer.cxx, test/testRandomHex.cxx: moved includes to + sip2/ + +2002-11-06 19:00 derekm + + * Uri.cxx: Uri operator< + +2002-11-06 18:57 derekm + + * Makefile: removed test programs + +2002-11-06 18:52 derekm + + * test/testTcpTransport.cxx: Uri operator< + +2002-11-06 18:51 derekm + + * test/SipTortureTests.cxx, test/testDnsResolver.cxx, + SipTortureTests.cxx, test1.cxx, test2.cxx, testDnsResolver.cxx, + testHash.cxx, testHashCasen.cxx, testHeaderFieldValueList.cxx, + testNonInviteClientTx.cxx, testNonInviteServerTx.cxx, + testParserCategories.cxx, testPreparse.cxx, testSimpleLeak.cxx, + testSipMessage.cxx, testSipMessageMemory.cxx, testSipStack1.cxx, + testSipStackInvite.cxx, testTimer.cxx, testTransactionFSM.cxx, + testTypes.cxx, testUdp.cxx, testpp.cxx: [no log message] + +2002-11-06 18:49 derekm + + * test/: Makefile, testTransactionFSM.cxx: brought over changes + from sipstack directory + +2002-11-06 18:44 derekm + + * ParserCategories.cxx, os/Data.cxx, os/Data.hxx: Data operator> + NameAddr operator< Uri operator< + +2002-11-06 18:08 fluffy + + * DnsResolver.cxx: [no log message] + +2002-11-06 18:02 fluffy + + * os/: Log.cxx, ThreadIf.cxx: windows fixes + +2002-11-06 17:28 fluffy + + * DnsResolver.cxx: may have broken this - compiles in windows + +2002-11-06 17:26 fluffy + + * Helper.cxx: fix to compile in windows + +2002-11-06 17:26 fluffy + + * Resolver.cxx, Resolver.hxx: no longer used + +2002-11-06 17:05 fluffy + + * Uri.cxx: fixed problem that caused bug in windows compiler + +2002-11-06 16:12 veer + + * os/Timer.cxx, os/vmd5.hxx, test/testCoders.cxx: Ported on forte + CC 6Update 1 for sparc + +2002-11-06 16:01 bko + + * Makefile, ParserCategories.cxx, ParserCategories.hxx, Uri.cxx, + testParserCategories.cxx: code for warningcategory. at least one + possible bug remains + +2002-11-06 15:49 ryker + + * Helper.cxx, Helper.hxx: Add optional second parameter to + Helper::makeMessage so that you can make a message that is thought + to have arrived from the wire as well as from a TU. Test stuff + needs this to synthesise messages for the transaction state + machines that appear to have arrived from the wire. + +2002-11-06 15:31 veer + + * ConnectionMap.cxx, DnsResolver.cxx, Preparse.hxx, Resolver.cxx, + TransactionState.hxx, Uri.cxx, os/HashMap.hxx, os/vmd5.hxx: Ported + on forte CC 6Update 1 for sparc + +2002-11-06 15:20 alan + + * Preparse.cxx: Fixed traiiling \n problem + +2002-11-06 15:15 alan + + * test/testPreparse.cxx: Added dereks test case + +2002-11-06 13:58 davidb + + * ParserCategories.cxx, ParserCategories.hxx: added + CallId::operator== + +2002-11-06 13:06 alan + + * doc/static/: Preparse.pdf, Preparse.png, Preparse.ps, + Preparse.svg, README, srv-inv-fsm.pdf, srv-inv-fsm.png, + srv-inv-fsm.ps, srv-inv-fsm.svg, srv-inv-tree.pdf, + srv-inv-tree.png, srv-inv-tree.ps, srv-inv-tree.svg: This is a + snapshot of the documentation. Real documentation should be build + from the source. + +2002-11-06 13:04 ryker + + * testTransactionFSM.cxx: Cleanup and port to the new TestTransport + stuff. + +2002-11-06 12:36 ryker + + * TestTransport.cxx: #include <memory> for std::auto_ptr. + +2002-11-06 11:38 derekm + + * test/: Makefile, test1.cxx, test2.cxx, testHash.cxx, + testHashCasen.cxx, testHeaderFieldValueList.cxx, + testNonInviteClientTx.cxx, testNonInviteServerTx.cxx, + testParserCategories.cxx, testPreparse.cxx, testSimpleLeak.cxx, + testSipMessage.cxx, testSipMessageMemory.cxx, testSipStack1.cxx, + testSipStackInvite.cxx, testTcpTransport.cxx, testTimer.cxx, + testTransactionFSM.cxx, testTypes.cxx, testUdp.cxx, testpp.cxx: + moved tests from sipstack directory to test directory + +2002-11-06 10:51 davidb + + * os/CircularBuffer.hxx: stub for CircularBuffer + +2002-11-06 10:23 kdc + + * Makefile: add Circular.cxx + +2002-11-06 10:20 kdc + + * Circular.cxx, Circular.hxx, TestTransport.hxx, circular.hxx: + simplified circular buffer stuff + +2002-11-06 08:19 fluffy + + * Resolver.cxx: fixed to compile in windows + +2002-11-05 22:55 fluffy + + * TcpTransport.cxx: windows compile updates and fiexed nasty bug in + accept + +2002-11-05 22:54 fluffy + + * os/Socket.hxx, os/Timer.cxx, Headers.cxx, SendingMessage.cxx, + TransactionState.cxx, Transport.cxx: windows compile updates + +2002-11-05 22:53 jason + + * Resolver.cxx, Resolver.hxx, test1.cxx: make test1 work again + +2002-11-05 22:15 jason + + * Executive.cxx, Executive.hxx, Preparse.cxx, SipStack.cxx, + SipStack.hxx, TcpTransport.cxx, TcpTransport.hxx, + TestTransport.cxx, TestTransport.hxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx, + UdpTransport.hxx, test2.cxx, testNonInviteClientTx.cxx, + testSipStack1.cxx: added FdSet, also support for read and write + fdsets embedded in FdSet class + +2002-11-05 22:14 jason + + * os/Socket.hxx: added FdSet + +2002-11-05 21:15 jason + + * ReliabilityMessage.hxx, TransportMessage.hxx, DnsMessage.cxx, + Makefile, TransactionState.cxx, Transport.cxx, + TransportSelector.cxx: [no log message] + +2002-11-05 21:11 fluffy + + * convertStringToInt.cxx, convertStringToInt.cxx: not used + +2002-11-05 21:10 fluffy + + * os/HashMap.hxx, os/ParseBuffer.cxx, os/RandomHex.cxx, + DnsMessage.cxx, SSL.cxx, SendingMessage.cxx, SipStack.cxx, + TransactionState.cxx, Transport.cxx, TransportSelector.cxx, + Uri.cxx, testSipStack1.cxx: fixed to compile in windows + +2002-11-05 19:52 jason + + * testDnsResolver.cxx, testPreparse.cxx: make tests compile + +2002-11-05 19:52 jason + + * UdpTransport.cxx: [no log message] + +2002-11-05 19:51 jason + + * SipMessage.cxx, TransactionState.cxx: added debug to destructor + +2002-11-05 19:50 jason + + * Makefile: remove test that no longer works + +2002-11-05 19:20 jason + + * SipTortureTests.cxx: [no log message] + +2002-11-05 18:59 davidb + + * BranchParameter.cxx, BranchParameter.hxx, ConnectionMap.cxx, + ConnectionMap.hxx, DataParameter.cxx, DataParameter.hxx, + Dialog.cxx, Dialog.hxx, DnsMessage.cxx, DnsMessage.hxx, + DnsResolver.cxx, DnsResolver.hxx, Executive.cxx, Executive.hxx, + ExistsParameter.cxx, ExistsParameter.hxx, FloatParameter.cxx, + FloatParameter.hxx, HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, + HeaderTypes.cxx, HeaderTypes.hxx, Headers.cxx, Headers.hxx, + Helper.cxx, Helper.hxx, IntegerParameter.cxx, IntegerParameter.hxx, + Message.cxx, Message.hxx, MethodTypes.cxx, Parameter.cxx, + Parameter.hxx, ParameterTypeEnums.hxx, ParameterTypes.cxx, + ParameterTypes.hxx, ParseException.hxx, ParserCategories.cxx, + ParserCategory.cxx, ParserCategory.hxx, ParserContainer.hxx, + ParserContainerBase.hxx, Preparse.cxx, Preparse.hxx, Resolver.cxx, + Resolver.hxx, SendingMessage.cxx, SendingMessage.hxx, + SipMessage.cxx, SipMessage.hxx, SipStack.cxx, SipStack.hxx, + SipTortureTests.cxx, Symbols.cxx, TcpTransport.cxx, + TcpTransport.hxx, TestTransport.hxx, TimerMessage.cxx, + TimerMessage.hxx, TimerQueue.cxx, TimerQueue.hxx, + TransactionMap.cxx, TransactionMap.hxx, TransactionState.cxx, + TransactionState.hxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx, + UdpTransport.hxx, UnknownParameter.cxx, UnknownParameter.hxx, + Uri.cxx, Uri.hxx, test1.cxx, test2.cxx, testDnsResolver.cxx, + testHash.cxx, testHeaderFieldValueList.cxx, + testNonInviteServerTx.cxx, testParserCategories.cxx, + testPreparse.cxx, testSimpleLeak.cxx, testSipMessage.cxx, + testSipMessageMemory.cxx, testSipStack1.cxx, + testSipStackInvite.cxx, testTimer.cxx, testTransactionFSM.cxx, + testTypes.cxx, testUdp.cxx, testpp.cxx, os/Coders.cxx, + os/Coders.hxx, os/Condition.cxx, os/Data.cxx, os/Data.hxx, + os/DataStream.cxx, os/DataStream.hxx, os/Fifo.cxx, os/Fifo.hxx, + os/Lock.cxx, os/Lock.hxx, os/Log.cxx, os/Log.hxx, os/Logger.cxx, + os/Logger.hxx, os/Mutex.cxx, os/Mutex.hxx, os/ParseBuffer.cxx, + os/ParseBuffer.hxx, os/RandomHex.cxx, os/RandomHex.hxx, + os/Socket.cxx, os/Subsystem.cxx, os/Subsystem.hxx, + os/SysLogStream.hxx, os/ThreadIf.cxx, os/ThreadIf.hxx, + os/Timer.cxx, os/Timer.hxx, os/VException.cxx, os/VException.hxx, + os/vmd5.cxx, os/vmd5.hxx, test/testCoders.cxx, test/testData.cxx, + test/testDataPerformance.cxx, test/testDataStream.cxx, + test/testParseBuffer.cxx, test/testRandomHex.cxx: #include <> to + #include "" + +2002-11-05 18:42 jason + + * testParserCategories.cxx, testSipMessage.cxx: added some tests + +2002-11-05 18:41 jason + + * test2.cxx: doesn't work + +2002-11-05 18:41 jason + + * Transport.cxx, Transport.hxx, TransportSelector.cxx: added an + output operator for Tuple + +2002-11-05 18:40 jason + + * SipMessage.hxx: removed unused + +2002-11-05 18:39 jason + + * BranchParameter.hxx, Helper.cxx, TestTransport.cxx, + TestTransport.hxx, TransactionState.cxx, testNonInviteClientTx.cxx: + [no log message] + +2002-11-05 18:35 jason + + * DataParameter.cxx, FloatParameter.cxx, IntegerParameter.cxx, + SipTortureTests.cxx: skipping whitespace before and after the "=" + +2002-11-05 18:33 derekm + + * os/RandomHex.cxx: better randomness when openssl not + available--will be replaced by Random.hxx soon + +2002-11-05 18:32 derekm + + * test/testRandomHex.cxx: [no log message] + +2002-11-05 18:32 derekm + + * os/: Data.hxx, Logger.hxx, Makefile: added size_t to data fixed + logger to work on linux again added a random tests to the makefile + +2002-11-05 18:31 derekm + + * ConnectionMap.cxx, ConnectionMap.hxx, Makefile, TcpTransport.cxx, + TcpTransport.hxx, UdpTransport.cxx, UdpTransport.hxx: added tcp + transport class -- compiles, untested. added related logic to + connectionmap + +2002-11-05 16:36 veer + + * os/Logger.hxx: more Forte port + +2002-11-05 16:34 alan + + * os/Coders.cxx, os/Coders.hxx, test/testCoders.cxx, + test/testData.cxx: Added base64 coders (Data change) + +2002-11-05 16:33 alan + + * testPreparse.cxx: Blah + +2002-11-05 16:33 alan + + * TODO: Added uchar + +2002-11-05 16:29 veer + + * os/Logger.hxx: More Forte port + +2002-11-05 16:25 alan + + * Preparse.cxx, testPreparse.cxx: Removed EDGE-iness + +2002-11-05 16:13 jason + + * BranchParameter.cxx, BranchParameter.hxx, DataParameter.cxx: + fixed how branch encodes/decodes + +2002-11-05 16:13 jason + + * testParserCategories.cxx: added tests for branch + +2002-11-05 16:12 jason + + * os/ParseBuffer.cxx: fixed bug in skipN + +2002-11-05 16:12 veer + + * HeaderTypes.hxx: forte don't like enum dec. line should not have + , + +2002-11-05 16:12 ryker + + * testTransactionFSM.cxx: A test driver for the transaction state + machine. This allows you to write a test specification in a data + file which this program munches on and performs a test with. See + the comments at the top of the file for instructions on its use. + This is thought to work or be close to working but has not been + used successfully due to volatility in certain parts of the stack. + +2002-11-05 16:06 veer + + * os/Log.hxx: Port to Forte + +2002-11-05 16:04 veer + + * os/Logger.hxx: more Forte support + +2002-11-05 16:00 veer + + * os/Logger.hxx: add Forte support + +2002-11-05 15:55 jason + + * TransactionState.cxx, TransactionState.hxx: fixed bug in dns + state + +2002-11-05 15:54 jason + + * Symbols.cxx, Symbols.hxx: added vocal2 cookie + +2002-11-05 15:54 jason + + * .cvsignore: [no log message] + +2002-11-05 15:53 jason + + * os/: ParseBuffer.cxx, ParseBuffer.hxx: add assertNotEof() + +2002-11-05 14:47 veer + + * SipMessage.cxx, SipMessage.hxx: Add support for backward + compatible RFC2543 transaction Id + +2002-11-05 14:16 kdc + + * TransportSelector.cxx: changed TestReliable to TestUnreliable in + switch() statement + +2002-11-05 14:14 kdc + + * TestTransport.cxx, TestTransport.hxx, testNonInviteClientTx.cxx: + many changes + +2002-11-05 13:38 jason + + * SipMessage.cxx, SipMessage.hxx, TransactionState.cxx, + TransactionState.hxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx: + changes for integration of + TransportSelector/DnsResolver/TransactionState + +2002-11-05 13:38 jason + + * SendingMessage.cxx, SendingMessage.hxx: [no log message] + +2002-11-05 13:36 jason + + * DnsResolver.cxx, DnsResolver.hxx, DnsMessage.cxx, DnsMessage.hxx, + ConnectionMap.cxx: change interface slightly. + +2002-11-05 13:34 jason + + * Dialog.cxx, Helper.cxx, Makefile, ParameterTypes.hxx, + ParserCategories.hxx, ParserCategory.cxx, Symbols.cxx, Symbols.hxx: + change way of creating branch + +2002-11-05 13:34 jason + + * BranchParameter.cxx, BranchParameter.hxx: [no log message] + +2002-11-05 13:25 jason + + * os/Socket.hxx: added some sys includes + +2002-11-05 13:25 jason + + * os/: ParseBuffer.cxx, ParseBuffer.hxx: added some stuff for + advancing pointer + +2002-11-05 12:56 bko + + * testParserCategories.cxx: added test for Mime + +2002-11-05 12:55 bko + + * ParserCategory.cxx: skip whitespace around semi colons in + parseParameters() + +2002-11-05 12:54 bko + + * ParserCategories.cxx, ParserCategories.hxx: implemented Mime + ParserCategory + +2002-11-05 12:05 bko + + * ParserCategories.cxx, testParserCategories.cxx: fixes for Date + parsing + +2002-11-05 11:54 bko + + * Makefile: fix for xyz + +2002-11-05 11:43 davidb + + * Makefile, SipTortureTests.cxx, TestTransport.cxx, + testNonInviteClientTx.cxx, testParserCategories.cxx, + testSipMessage.cxx: got tests compiling with modified Preparsers + +2002-11-05 10:26 alan + + * Helper.cxx, Helper.hxx: Helper for makeMessage + +2002-11-04 23:22 kdc + + * circular.hxx: initial checkin of circular buffer + +2002-11-04 23:10 alan + + * Helper.cxx, Helper.hxx, UdpTransport.cxx: makeMessage helper + +2002-11-04 22:50 davidb + + * ParserCategories.cxx, ParserCategories.hxx: added DateCategory + +2002-11-04 22:49 davidb + + * SipMessage.cxx, SipMessage.hxx: added exists for unknown headers + +2002-11-04 22:49 davidb + + * Symbols.cxx, Symbols.hxx: added ZERO + +2002-11-04 22:49 davidb + + * TODO: [no log message] + +2002-11-04 22:45 davidb + + * os/: ParseBuffer.cxx, ParseBuffer.hxx: added assertEof() for + validation + +2002-11-04 22:44 davidb + + * testSipMessage.cxx: simplified auto_ptr use + +2002-11-04 22:17 alan + + * Makefile, Preparse.cxx, Preparse.hxx, Transport.hxx, + UdpTransport.cxx, UdpTransport.hxx, testPreparse.cxx, + testSipStackInvite.cxx: Preparser Updates + +2002-11-04 21:46 kdc + + * testNonInviteClientTx.cxx: [no log message] + +2002-11-04 21:39 kdc + + * TestTransport.cxx, TestTransport.hxx: initial checkin of + TestTransport stub test harness + +2002-11-04 21:38 kdc + + * Transport.cxx, Transport.hxx, TransportSelector.cxx: added + TestReliable and TestUnreliable transports + +2002-11-04 18:56 derekm + + * Uri.cxx, Uri.hxx, testParserCategories.cxx, os/Data.cxx, + os/Data.hxx, test/testData.cxx: Uri comparison works. added + lowercase, uppercase to data updated tests + +2002-11-04 18:07 veer + + * TransactionState.cxx, TransactionState.hxx: isFromwire is + introduced and stale statemachine is in + +2002-11-04 18:07 bko + + * ParserCategories.cxx, ParserCategories.hxx, SipTortureTests.cxx, + dayofweek.gperf, month.gperf: start implementation of date + +2002-11-04 17:23 bko + + * TODO: update with missing parsers + +2002-11-04 17:12 bko + + * ParameterTypes.hxx, ParserCategories.cxx, ParserCategories.hxx, + ParserCategory.cxx, testParserCategories.cxx: make GenericUri + headers work + +2002-11-04 17:07 davidb + + * Makefile: [no log message] + +2002-11-04 17:06 davidb + + * SipTortureTests.cxx: Sip Torture Tests + +2002-11-04 16:36 veer + + * TransactionState.cxx: added some info on state machine + +2002-11-04 15:59 bko + + * ParserCategories.cxx, testParserCategories.cxx: add a lot more + test cases for auth + +2002-11-04 15:52 veer + + * TransactionState.cxx: added some info on state machine + +2002-11-04 15:42 bko + + * DataParameter.cxx, DataParameter.hxx, ParserCategories.cxx, + ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, + UnknownParameter.cxx, UnknownParameter.hxx, + testParserCategories.cxx: fix unknown parameters as well as first + path at auth parameters + +2002-11-04 15:41 bko + + * os/Data.cxx: fix bug in data + +2002-11-04 14:38 derekm + + * DnsMessage.cxx, DnsResolver.cxx, DnsResolver.hxx: fixed memory + leak in DnsResolver. DnsResolver no longer returns duplicate + elements. + +2002-11-04 13:36 bko + + * testParserCategories.cxx: clean up + +2002-11-04 12:53 bko + + * TODO: update the todo file. + +2002-11-04 12:50 alan + + * os/Coders.cxx, os/Coders.hxx, test/testCoders.cxx, os/Makefile: + Initial Base64 implementation. (contrib'd Alan Hawrylyshen) + +2002-11-04 12:36 derekm + + * os/Data.cxx: fixed operator < + +2002-11-04 12:27 bko + + * DataParameter.cxx, ParserCategories.cxx, + testParserCategories.cxx: fix parsing of parameters terminated by + angle brackets + +2002-11-04 11:46 derekm + + * os/Data.cxx: [no log message] + +2002-11-04 11:34 bko + + * Makefile, testSipMessage.cxx, testSipStack1.cxx: fixes for + compile under gcc < 3 + +2002-11-04 11:07 derekm + + * Makefile: [no log message] + +2002-11-04 10:42 bko + + * Transport.cxx, test2.cxx: fixes for gcc < 3 + +2002-11-04 10:36 bko + + * os/Data.cxx: fixes for gcc < 3 + +2002-11-03 22:36 derekm + + * testDnsResolver.cxx: [no log message] + +2002-11-03 22:33 derekm + + * Makefile, Message.hxx, ParameterTypes.cxx, ParameterTypes.hxx, + ParserCategories.cxx, SipStack.cxx, SipStack.hxx, Symbols.cxx, + Symbols.hxx, os/Data.cxx, os/Data.hxx, DnsMessage.cxx, + DnsMessage.hxx, DnsResolver.cxx, DnsResolver.hxx, os/HashMap.hxx: + [no log message] + +2002-11-03 22:30 jason + + * os/: Timer.cxx, Timer.hxx: add toData + +2002-11-03 22:29 jason + + * testNonInviteClientTx.cxx, testNonInviteServerTx.cxx, Makefile, + testParserCategories.cxx, testSipMessage.cxx, + testSipStackInvite.cxx: [no log message] + +2002-11-03 22:28 jason + + * UdpTransport.cxx, UdpTransport.hxx: added a dummy TcpTransport + +2002-11-03 22:28 jason + + * TransportSelector.cxx, TransportSelector.hxx: support retransmit + move stuff into SipMessage + +2002-11-03 22:28 jason + + * Transport.cxx, Transport.hxx: don't pass in Data*, use Data& + instead + +2002-11-03 22:27 jason + + * TransactionState.cxx: numerous bugs in TransactionState fixed + (for non-invite transaction) + +2002-11-03 22:27 jason + + * TransactionMap.cxx: fix problem erasing TransactionState from + Tmap + +2002-11-03 22:26 jason + + * TimerMessage.cxx, TimerQueue.cxx: debug output for timer type + +2002-11-03 22:26 jason + + * SipMessage.cxx, SipMessage.hxx: store Resolver and encoded + message in SipMessage + +2002-11-03 22:25 jason + + * Resolver.hxx: modified interface to allow creating Resolver with + Via + +2002-11-03 22:25 jason + + * ParserCategories.cxx: ignored grammar and accept no trailing + space + +2002-11-03 22:24 jason + + * Helper.cxx: add response reasons + +2002-11-03 22:23 jason + + * SendingMessage.cxx, SendingMessage.hxx: [no log message] + +2002-11-03 22:22 jason + + * os/ParseBuffer.hxx: removed <string> + +2002-11-03 22:22 jason + + * ConnectionMap.cxx, ConnectionMap.hxx, Makefile, TcpTransport.cxx, + TcpTransport.hxx, Transport.cxx, Transport.hxx, UdpTransport.cxx: + ConnectionMap, enriched Tuple + +2002-11-03 19:17 fluffy + + * TcpTransport.cxx: [no log message] + +2002-11-03 18:57 jason + + * ConnectionMap.cxx, ConnectionMap.hxx, TcpTransport.cxx, + TcpTransport.hxx: [no log message] + +2002-11-03 17:58 dabryan + + * Transport.hxx: [no log message] + +2002-11-03 17:42 alan + + * SSL.cxx, SSL.hxx: Initial SSL support files. + ------------------------------------------------------------------- + --- + +2002-11-02 17:01 derekm + + * Transport.hxx: mem leak + +2002-11-02 17:00 derekm + + * os/.cvsignore, .cvsignore, Dialog.cxx, test1.cxx, + testParserCategories.cxx: [no log message] + +2002-11-02 15:57 jason + + * Preparse.cxx: change from string to data + +2002-11-02 15:31 fluffy + + * doc/: client-invite-state.tif, client-invite-tree.tif, + client-noninvite-state.tif, client-noninvite-tree.tif, + server-invite-state.tif, server-invite-tree.tif, + server-noninvite-state.tif, server-noninvite-tree.tif, + stale-state.tif, stale-tree.tif: initial creation + +2002-11-02 11:31 jason + + * os/: Data.cxx, Data.hxx: moved outline + +2002-11-01 18:51 jason + + * Dialog.cxx, Dialog.hxx: many fixes + +2002-11-01 16:06 jason + + * Symbols.cxx: changed scheme to lowercase + +2002-11-01 15:49 jason + + * Dialog.cxx, Dialog.hxx: support for creating responses in dialog + +2002-11-01 15:34 jason + + * SipStack.cxx: force app to create transport + +2002-11-01 15:34 jason + + * SipMessage.cxx: brief output for sipmessage + +2002-11-01 15:34 jason + + * Helper.cxx: remove setting to tag in response creation + +2002-11-01 14:01 jason + + * test/testData.cxx: [no log message] + +2002-11-01 14:01 jason + + * os/: Data.cxx, Data.hxx: dont allocate for empty Data + +2002-11-01 11:16 jason + + * SipMessage.cxx, SipMessage.hxx, test1.cxx, test2.cxx: [no log + message] + +2002-11-01 11:14 jason + + * TransactionState.cxx: fix bug in isResponse + +2002-11-01 11:12 jason + + * Transport.cxx, Transport.hxx, TransportSelector.cxx, + UdpTransport.cxx, UdpTransport.hxx, SipStack.cxx: [no log message] + +2002-10-31 23:10 fluffy + + * os/RandomHex.cxx, os/ThreadIf.hxx, os/compat.hxx, os/vmd5.cxx, + Resolver.cxx, SipStack.cxx, SipStack.hxx, Transport.cxx, + Transport.hxx, TransportSelector.cxx, TransportSelector.hxx, + UdpTransport.cxx, UdpTransport.hxx, Uri.hxx: fixed to compile under + windows + +2002-10-31 18:03 jason + + * os/ParseBuffer.cxx: fixed reset -- which should actually be + called set + +2002-10-31 18:02 jason + + * testParserCategories.cxx: [no log message] + +2002-10-31 18:02 jason + + * Helper.cxx, Helper.hxx: added makeRegister added reason to + makeresponse + +2002-10-31 17:51 jason + + * os/Timer.hxx: added doc for timers + +2002-10-31 17:50 jason + + * TransactionState.cxx, TransportSelector.cxx, test1.cxx, + test2.cxx, testSipMessage.cxx, testSipStack1.cxx, Makefile: [no log + message] + +2002-10-31 17:50 jason + + * SipStack.cxx, SipStack.hxx: addTransport added to interface + +2002-10-31 17:49 jason + + * SipMessage.hxx: make constructor explicit since it was having bad + effects + +2002-10-31 17:49 jason + + * SipMessage.cxx: return transaction id (branch) + +2002-10-31 17:49 jason + + * Helper.cxx, Helper.hxx: change methods to return SipMessage* + instead of objects + +2002-10-31 15:29 jason + + * Helper.cxx, ParserCategories.hxx: added beginnings of a loadgen + +2002-10-31 13:43 jason + + * TransportSelector.cxx: removed spurious !'s + +2002-10-31 13:07 jason + + * TransportSelector.cxx: fixed use of via's when picking + destination for a response + +2002-10-31 12:52 jason + + * os/: Data.cxx, Makefile: optimization in the Data stream inserter + +2002-10-31 12:51 jason + + * test/testDataPerformance.cxx: [no log message] + +2002-10-30 22:15 jason + + * os/Data.hxx: added compat for qnx + +2002-10-30 20:18 fluffy + + * os/RandomHex.cxx: fixed evil bug when not using OPENSSL and got + to compile + +2002-10-30 17:39 jason + + * Makefile, os/Makefile: changed over to use vocal build stuff + +2002-10-30 17:38 jason + + * SipMessage.cxx, SipMessage.hxx, TransportSelector.cxx: removed + Data encode + +2002-10-30 17:30 jason + + * ParserCategories.hxx, Uri.cxx, testSipMessage.cxx: [no log + message] + +2002-10-30 17:18 jason + + * test1.cxx: [no log message] + +2002-10-30 17:13 jason + + * ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, + ParserCategory.hxx, Uri.cxx, Uri.hxx, os/Data.hxx, os/compat.hxx: + added opeartor== to URI + +2002-10-30 17:08 jason + + * os/: RandomHex.cxx, compat.hxx: use srandom instead of srand + +2002-10-30 17:08 jason + + * os/.cvsignore, os/Data.hxx, test/testData.cxx, os/vmd5.hxx: [no + log message] + +2002-10-30 17:08 jason + + * UdpTransport.cxx, test1.cxx, testPreparse.cxx, + testSipMessage.cxx: for qnx + +2002-10-30 17:07 jason + + * os/DataStream.cxx, os/DataStream.hxx, test/testDataStream.cxx: + got rid of intermediate buffer in DataStream + +2002-10-30 17:04 jason + + * Resolver.cxx, SipMessage.cxx, TransportSelector.cxx: for qnx + +2002-10-30 17:04 jason + + * .cvsignore, HeaderTypes.hxx: [no log message] + +2002-10-30 15:48 jason + + * os/Data.cxx, os/Data.hxx, os/DataStream.cxx, os/DataStream.hxx, + os/Makefile, test/testData.cxx, test/testDataStream.cxx: added + DataStream + +2002-10-30 12:38 jason + + * UdpTransport.cxx, test1.cxx: [no log message] + +2002-10-30 12:30 jason + + * os/Data.cxx: fix bug in md5 + +2002-10-30 12:30 jason + + * os/Data.cxx: fixed a leak -- set mMine incorrectly + +2002-10-30 10:49 jason + + * SipStack.hxx, TransactionState.cxx, TransactionState.hxx, + Transport.cxx, Transport.hxx, TransportSelector.cxx, + UdpTransport.cxx, UdpTransport.hxx: [no log message] + +2002-10-30 10:49 jason + + * SipMessage.cxx, SipMessage.hxx: fix encode + +2002-10-30 10:49 jason + + * Resolver.cxx: fix the resolver + +2002-10-30 10:48 jason + + * ParserCategories.cxx, ParserCategories.hxx: fixed copy + constructor + +2002-10-30 10:47 jason + + * Helper.cxx, Helper.hxx: failure ack, simple changes to other + message creation + +2002-10-30 10:46 jason + + * os/Data.cxx: use memmove when overlap is possible + +2002-10-30 10:45 jason + + * test1.cxx, Dialog.cxx: [no log message] + +2002-10-30 10:44 jason + + * os/Data.hxx: fixed guard + +2002-10-29 18:14 jason + + * HostSpecification.cxx, HostSpecification.hxx: changed name to + Resolver + +2002-10-29 18:14 jason + + * Makefile, Resolver.cxx, Resolver.hxx, Transport.cxx, + Transport.hxx, TransportSelector.cxx, TransportSelector.hxx, + UdpTransport.cxx, UdpTransport.hxx: first cut at TransportSelector + +2002-10-29 17:10 jason + + * Executive.cxx, Executive.hxx: [no log message] + +2002-10-29 17:10 jason + + * Transport.cxx, Transport.hxx, TransportSelector.cxx, + TransportSelector.hxx, UdpTransport.cxx, UdpTransport.hxx: added + code to create transports in the TransportSelector + +2002-10-29 17:10 jason + + * HostSpecification.cxx, HostSpecification.hxx: added getHostName() + +2002-10-25 17:28 alan + + * ParserCategory.cxx, ParserCategory.hxx, SipMessage.cxx, + Transport.hxx, TransportSelector.cxx, testSipStackInvite.cxx: Many + updates and fixes to coerce a message to the TU and get the + provisional message out the wire. + +2002-10-25 17:28 alan + + * TransactionState.cxx: It is really never a good idea to return a + reference to an object on the stack. + +2002-10-25 13:32 alan + + * ParserCategory.cxx: Removed accidental logic flip in ctor. + +2002-10-25 12:43 alan + + * ChangeLog, HostSpecification.cxx, ParserCategories.cxx, + ParserCategory.cxx, ParserCategory.hxx, SipMessage.hxx, + SipStack.cxx, TransactionState.cxx, TransactionState.hxx, + UdpTransport.cxx, doc/design-overview.xml, os/Log.hxx, + os/ParseBuffer.cxx, os/ParseBuffer.hxx: General Bug fixes and clean + up. See ChangeLog + +2002-10-22 16:51 alan + + * Preparse.cxx, Transport.cxx, UdpTransport.cxx, os/Subsystem.cxx, + os/Subsystem.hxx: Added changes that fix Preparse Added Subsystem + APP class Fixed Bug in Transport fd_set generation + +2002-10-22 08:57 jason + + * Symbols.cxx, Symbols.hxx, TimerQueue.cxx, Transport.cxx, + Transport.hxx, UdpTransport.cxx, UdpTransport.hxx, + TransportSelector.cxx, testSipStack1.cxx, HostSpecification.cxx, + HostSpecification.hxx, Helper.cxx, Helper.hxx, Makefile: [no log + message] + +2002-10-22 08:56 jason + + * ParserCategories.hxx: initialize via parameters for protocol and + version + +2002-10-22 08:47 jason + + * os/ThreadIf.cxx: [no log message] + +2002-10-22 08:47 jason + + * os/: ParseBuffer.cxx, ParseBuffer.hxx: add a data method that + makes a copy + +2002-10-22 08:47 jason + + * os/Fifo.hxx: cache fifo size + +2002-10-21 15:49 jason + + * os/vmd5.cxx, os/vmd5.hxx, os/Data.cxx, os/Data.hxx, + test/testData.cxx, os/Makefile: steal md5 stuff from vocal + +2002-10-21 15:46 jason + + * Headers.hxx: added typedefs for ParserContainer<{parser + category}> for multi-categories, e.g. Vias + +2002-10-21 13:28 jason + + * SipMessage.cxx, SipMessage.hxx, SipStack.cxx, + TransportSelector.cxx: [no log message] + +2002-10-21 13:28 jason + + * TransactionState.cxx: added debug + +2002-10-19 10:11 jason + + * os/Data.cxx, test/testData.cxx: corrected tests for + Data::operator< + +2002-10-19 09:23 fluffy + + * os/Timer.cxx: updated CPU speed list + +2002-10-19 09:23 fluffy + + * os/Data.cxx: fixed bogus operator < - did not test + +2002-10-15 14:09 alan + + * .cvsignore: Added local test loop + +2002-10-15 14:06 alan + + * SipMessage.cxx, testSimpleLeak.cxx, testSipMessageMemory.cxx: + Added looping to testSipMessageMemory. Added memory debugging. + +2002-10-15 13:50 jason + + * ParserContainer.hxx: added a destructor, oops + +2002-10-15 13:49 fluffy + + * .cvsignore: [no log message] + +2002-10-15 11:03 jason + + * os/Data.cxx, os/Data.hxx, test/testData.cxx: added operator< hash + uses Data::data() rather than Data::c_str() + +2002-10-15 10:35 alan + + * testSipMessage.cxx, Preparse.cxx, Preparse.hxx: Fixed looping + buffer processing + +2002-10-15 08:53 jason + + * os/: Data.cxx, Data.hxx: minor mods for gcc-2.9x + +2002-10-15 08:46 alan + + * os/: Lock.cxx, Lock.hxx, Lockable.hxx, Mutex.cxx, Mutex.hxx: + Moved Licenses to EOF + +2002-10-13 09:20 jason + + * os/Timer.cxx: changed (unsigned long) cast style to compile + +2002-10-13 09:19 jason + + * SipMessage.cxx, os/compat.hxx: use Data.data() rather than + data.c_str() -- data never copies + +2002-10-12 23:02 jason + + * DataParameter.cxx, HeaderFieldValue.cxx, Headers.cxx, + MethodTypes.cxx, MethodTypes.hxx, Parameter.cxx, + ParameterTypes.cxx, ParserCategories.cxx, ParserCategories.hxx, + ParserCategory.cxx, SipMessage.cxx, Uri.cxx, methods.gperf, + testParserCategories.cxx, testSipMessage.cxx, os/Data.cxx, + os/Data.hxx, os/Makefile, os/ParseBuffer.cxx, os/ParseBuffer.hxx, + test/testData.cxx, test/testParseBuffer.cxx: modified + ParserBuffer::data to cause memory sharing in the Data reference + arg + +2002-10-12 20:46 fluffy + + * os/ParseBuffer.cxx, os/Timer.cxx, Transport.cxx: few windows + updates + +2002-10-12 20:37 fluffy + + * os/Data.cxx, os/Mutex.cxx, Headers.hxx, Helper.cxx, + ParameterTypes.hxx, ParserCategory.cxx, ParserCategory.hxx, + TimerQueue.cxx, UdpTransport.cxx, Transport.cxx: few windows + updates + +2002-10-12 19:26 fluffy + + * os/Data.hxx, os/Inserter.hxx, os/Log.cxx, os/Logger.hxx, + os/compat.hxx, Executive.hxx, HeaderTypes.cxx, Headers.hxx, + Transport.hxx, TransportSelector.hxx: few windows updates + +2002-10-08 11:34 jason + + * SipMessage.cxx: notes for Unknown backward compatibility + +2002-10-08 03:14 jason + + * FloatParameter.cxx, HeaderFieldValueList.cxx, Preparse.cxx, + testSipMessage.cxx: member initializers, turn on testSipMessage + +2002-10-08 03:09 jason + + * TimerQueue.cxx, TimerQueue.hxx, testTimer.cxx, os/Timer.cxx, + os/Timer.hxx: added << to Timer fixed TimerQueue bug, tested + +2002-10-07 12:19 jason + + * HeaderTypes.hxx, ParserCategories.cxx, ParserCategory.cxx, + ParserContainer.hxx, SipMessage.cxx, Uri.cxx, Uri.hxx, + testSipMessage.cxx, os/Data.hxx: fixed some leaks, initializers, + Via parser test copying parts across messages + +2002-10-07 08:47 jason + + * testSipMessage.cxx: added more testing + +2002-10-07 08:28 jason + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderFieldValueList.cxx, ParserCategory.cxx, SipMessage.cxx: + remove back pointer from HeaderFieldValue to ParserCategory -- have + HeaderFieldValueList => ParserContainer => ParserCategory => + HeaderFieldValue + +2002-10-07 08:13 jason + + * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, + HeaderTypes.hxx, ParserCategories.cxx, ParserContainer.hxx, + ParserContainerBase.hxx, SipMessage.cxx, SipMessage.hxx: SipMessage + copy constructor works using HeaderFieldValueList to hold + RequestLine, StatusLine + +2002-10-06 22:39 jason + + * ParserCategories.cxx: [no log message] + +2002-10-06 13:59 jason + + * HeaderFieldValueList.hxx, ParserCategories.hxx, os/Data.cxx, + os/Data.hxx, os/Log.cxx, os/Log.hxx, os/Subsystem.cxx, + os/Subsystem.hxx, os/ThreadIf.cxx: change Data to contain rather + than inherit from string much reduced interface to Data still needs + to get a more efficient implementation + +2002-10-06 12:00 jason + + * testSipMessage.cxx: [no log message] + +2002-10-06 11:45 jason + + * testSipMessage.cxx: added a test case to copy a SipMessage + +2002-10-06 11:36 jason + + * testSipStack1.cxx: added some code to create and send a sip + message + +2002-10-06 11:34 jason + + * Transport.cxx, TransportSelector.cxx, UdpTransport.cxx: add + exception handler + +2002-10-06 11:34 jason + + * ParserCategories.cxx: mods to copy constructor to initialize all + members for NameAddr + +2002-10-06 11:33 jason + + * ParseException.hxx, SipMessage.hxx, Transport.hxx: changed + VException signature + +2002-10-06 11:33 jason + + * Makefile: add openssl back in + +2002-10-06 11:33 jason + + * Helper.cxx, Helper.hxx: add some helpers (remove others) + +2002-10-06 11:32 jason + + * HeaderFieldValue.cxx: remove assert, and replace with InfoLog + +2002-10-06 11:32 jason + + * Dialog.cxx: remove an out of date helper + +2002-10-06 11:31 jason + + * os/: ParseBuffer.hxx, VException.cxx, VException.hxx: change + signature of VException + +2002-10-06 11:31 jason + + * os/RandomHex.cxx: use openssl on non-windows + +2002-10-06 08:39 jason + + * MethodTypes.cxx, MethodTypes.hxx, ParserCategory.hxx, + Symbols.cxx, Symbols.hxx, Uri.cxx, Uri.hxx, testSipMessage.cxx: + ParserCategory created from a fake HeaderFieldValue is parsed fixed + Response method name added DefaultSipScheme fixed Uri::encode + simple tests for creating headers in messages + +2002-10-06 08:07 jason + + * testSipMessage.cxx: added simple header creation test + +2002-10-05 18:11 jason + + * ParserCategories.cxx, ParserCategories.hxx: create lazy Uri in + NameAddr and RequestLine + +2002-10-05 11:11 jason + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, ParserCategories.cxx, + ParserCategories.hxx, ParserCategory.cxx, ParserContainer.hxx: + parser container uses list<T*> added operator= to all parser + categories + +2002-10-04 21:47 fluffy + + * testSipStack1.cxx: fixed license statements + +2002-10-04 21:44 fluffy + + * os/Inserter.hxx, os/Log.cxx, os/Log.hxx, os/Logger.cxx, + os/Logger.hxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, + os/RandomHex.cxx, os/Socket.cxx, os/Socket.hxx, os/Subsystem.cxx, + os/Subsystem.hxx, os/SysLogBuf.hxx, os/SysLogStream.hxx, + os/Timer.cxx, os/Timer.hxx, os/compat.hxx, + test/testParseBuffer.cxx, DataParameter.cxx, DataParameter.hxx, + Dialog.cxx, Dialog.hxx, Executive.cxx, Executive.hxx, + ExistsParameter.cxx, ExistsParameter.hxx, FloatParameter.cxx, + FloatParameter.hxx, HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, + HeaderTypes.cxx, HeaderTypes.hxx, Headers.cxx, Headers.hxx, + Helper.cxx, Helper.hxx, HostSpecification.hxx, + IntegerParameter.cxx, IntegerParameter.hxx, Message.cxx, + Message.hxx, MethodTypes.cxx, MethodTypes.hxx, Parameter.cxx, + Parameter.hxx, ParameterTypeEnums.hxx, ParameterTypes.cxx, + ParameterTypes.hxx, ParseException.hxx, ParserCategories.cxx, + ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, + ParserContainer.hxx, ParserContainerBase.hxx, Preparse.cxx, + Preparse.hxx, SipMessage.cxx, SipMessage.hxx, + SipMessageExplicit.cxx, SipMessageExplicit.hxx, SipStack.cxx, + SipStack.hxx, Symbols.cxx, Symbols.hxx, TimerMessage.cxx, + TimerMessage.hxx, TimerQueue.cxx, TimerQueue.hxx, + TransactionMap.cxx, TransactionMap.hxx, TransactionState.cxx, + TransactionState.hxx, Transport.cxx, Transport.hxx, + TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx, + UdpTransport.hxx, UnknownParameter.cxx, UnknownParameter.hxx, + Uri.cxx, Uri.hxx, convertStringToInt.cxx, supported.hxx, + testHash.cxx, testHashCasen.cxx, testHeaderFieldValueList.cxx, + testParserCategories.cxx, testPreparse.cxx, testSipMessage.cxx, + testSipMessageMemory.cxx, testTypes.cxx, testUdp.cxx, testpp.cxx: + fixed license statements + +2002-10-04 21:30 fluffy + + * SipMessage.cxx, TransactionState.cxx, testSipStack1.cxx: [no log + message] + +2002-10-04 19:22 jason + + * .cvsignore, FloatParameter.cxx, HeaderTypes.hxx, Headers.cxx, + Headers.hxx, IntegerParameter.cxx, Makefile, MethodTypes.hxx, + ParserCategories.cxx, ParserCategories.hxx, ParserContainer.hxx, + ParserContainerBase.hxx, SipMessage.cxx, SipMessage.hxx, Uri.cxx, + testSipMessage.cxx, torture.txt, os/ParseBuffer.cxx, + os/ParseBuffer.hxx, test/testParseBuffer.cxx: ParseBuffer parses + integers and strings fixed some parsed encode bugs -- still some + work to do checked in sip torture test as text + +2002-10-04 18:17 jason + + * DataParameter.cxx, DataParameter.hxx, HeaderFieldValue.hxx, + Parameter.hxx, ParserCategories.hxx, ParserCategory.hxx, + SipMessage.cxx: fix warnings + +2002-10-04 18:12 jason + + * os/: Condition.cxx, ParseBuffer.cxx, ParseBuffer.hxx, + RandomHex.cxx: fix warnings + +2002-10-04 13:54 jason + + * Transport.hxx, TransportSelector.hxx, UdpTransport.cxx: compat + (qnx and others) + +2002-10-04 13:53 jason + + * HeaderTypes.cxx, ParameterTypes.cxx, ParserCategory.cxx: compat + +2002-10-04 13:52 jason + + * Executive.hxx: [no log message] + +2002-10-04 13:52 jason + + * os/Logger.hxx: added in compatibility with older versions of gcc + +2002-10-04 13:52 jason + + * os/: Data.hxx, compat.hxx: added in common stuff for + compatibility between o/s + +2002-10-04 13:49 jason + + * os/Log.cxx: [no log message] + +2002-10-04 13:48 jason + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, + ParserCategory.cxx, ParserCategory.hxx, ParserContainer.hxx, + SipMessage.cxx, SipMessage.hxx, testSipMessage.cxx, + testSipMessageMemory.cxx: more fixes to header memory management, + wrote a few raw and parsed header moving tests + +2002-10-04 10:58 jason + + * HeaderTypes.hxx, Preparse.cxx, os/Logger.hxx: fixed variadic + macros, again, sigh + +2002-10-04 10:24 jason + + * testSipStack1.cxx: [no log message] + +2002-10-04 09:54 alan + + * ChangeLog, Preparse.cxx: Added pre-parse hooks + +2002-10-04 09:48 alan + + * ChangeLog, ParserCategories.cxx, Preparse.cxx, SipMessage.cxx, + SipMessage.hxx, Symbols.cxx, Symbols.hxx, doc/design-overview.xml: + Added pre-parse hooks and const correctness. Added Symbol pkg to + Preparser + +2002-10-03 22:48 fluffy + + * os/Log.cxx: fixed some ^M things + +2002-10-03 22:35 fluffy + + * Executive.cxx, Executive.hxx, Makefile, SipStack.cxx, + SipStack.hxx, Transport.cxx, Transport.hxx, TransportSelector.cxx, + TransportSelector.hxx, UdpTransport.cxx, UdpTransport.hxx, + testSipStack1.cxx: cleaned up use file descriptors for select + +2002-10-03 19:16 jason + + * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, + ParserCategory.cxx, ParserCategory.hxx, ParserContainer.hxx, + ParserContainerBase.hxx, SipMessage.cxx, testSipMessage.cxx: + simplified HeaderFieldValueList/ParserContainer + HeaderFieldValue/ParserContainer memory management, cloning, + assigning fixed encode to be as lazy as possible + +2002-10-03 16:39 jason + + * ParameterTypeEnums.hxx, ParameterTypes.cxx, ParameterTypes.hxx, + ParserCategories.cxx, ParserCategory.cxx, ParserCategory.hxx, + SipMessage.cxx, Symbols.cxx, Symbols.hxx, Uri.cxx, + parameters.gperf, testParserCategories.cxx: move uri parameters + from header to uri fixed uri parser bug more tests + +2002-10-03 12:49 jason + + * HeaderFieldValue.hxx, Makefile, ParameterList.cxx, + ParameterList.hxx, ParserCategory.cxx, SipMessage.cxx, + SipMessage.hxx, testParameterList.cxx, testSipMessage.cxx: removed + ParameterList wrote a strawman setStartLine implmented isRequest, + isResponse fixed StartLine and StatusLine retrieval + +2002-10-03 09:40 jason + + * FloatParameter.cxx, FloatParameter.hxx, HeaderTypes.cxx, + HeaderTypes.hxx, ParameterTypes.cxx, ParameterTypes.hxx, + ParserCategory.cxx, ParserCategory.hxx, SipMessage.cxx, + SipMessage.hxx, headers.gperf: unrolled the classes and methods for + in header/parameter type safety + +2002-10-02 22:13 fluffy + + * os/Log.cxx, Parameter.hxx: no message + +2002-10-02 22:05 fluffy + + * os/: Mutex.hxx, ParseBuffer.hxx, Timer.cxx, ParseBuffer.cxx, + ThreadIf.cxx, ThreadIf.hxx: no message + +2002-10-02 20:56 fluffy + + * os/Data.hxx: small chave to compile in windows + +2002-10-02 17:21 jason + + * HeaderFieldValueList.cxx, SipMessage.cxx, testSipMessage.cxx: + fixed some initializers, got testSipMessage going with Preparse + +2002-10-02 16:08 jason + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, Makefile, + Parameter.cxx, Parameter.hxx, ParseException.hxx, + ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, + ParserCategory.hxx, SipMessage.cxx, SipMessage.hxx, Uri.cxx, + testParserCategories.cxx, os/Data.hxx, os/Makefile, + os/ParseBuffer.cxx, os/ParseBuffer.hxx, os/VException.cxx: + ParameterLists moved to ParserCategory reimplemented ParameterLists + in stl fixed some destructors (leaked) fixed some parsers (missing + some validation), added interface to ParseBuffer added + ParseBuffer::Exception implemented ParseException as VException + implemented isEqualNoCase global function to Data + +2002-10-01 18:43 jason + + * DataParameter.cxx, ExistsParameter.cxx, FloatParameter.cxx, + HeaderFieldValue.cxx, IntegerParameter.cxx, ParserCategories.cxx, + SipMessage.hxx, Symbols.cxx, Symbols.hxx, Uri.cxx, Uri.hxx, + testParserCategories.cxx, testSipMessage.cxx, os/ParseBuffer.cxx, + os/ParseBuffer.hxx: added Uri, NameAddr, RequestLine parsers & + tests. + +2002-10-01 14:42 alan + + * os/RandomHex.cxx: Added stdio.h (needed for sprintf) + +2002-10-01 14:19 jason + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderFieldValueList.hxx, HeaderTypes.cxx, HeaderTypes.hxx, + ParameterList.cxx, ParameterTypes.cxx, ParameterTypes.hxx, + ParserCategories.cxx, ParserCategory.cxx, ParserCategory.hxx, + ParserContainer.hxx, Preparse.cxx, SipMessage.cxx, SipMessage.hxx, + SipStack.hxx, parameters.gperf, testParserCategories.cxx, + os/Data.hxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, + test/testParseBuffer.cxx: fixed gperf hashes -- please ask before + messing with them added Via parser, encode, and a test parameter + encode + +2002-10-01 07:53 fluffy + + * os/Fifo.hxx, os/Logger.hxx, ParameterTypes.cxx, UdpTransport.cxx: + few windows port updates + +2002-09-30 19:22 jason + + * Makefile: [no log message] + +2002-09-30 19:21 jason + + * DataParameter.cxx, ExistsParameter.cxx, HeaderFieldValue.cxx, + HeaderFieldValue.hxx, IntegerParameter.cxx, IntegerParameter.hxx, + MethodTypes.cxx, ParameterList.cxx, ParameterList.hxx, + ParameterTypes.cxx, ParserCategories.cxx, ParserCategory.cxx, + ParserCategory.hxx, testParameterList.cxx: parser work in progress. + gPerf workaround(gperf didn't build a correct hash) less explicit + data constructor parameter parsing/retrieval via parser(untested) + +2002-09-30 16:19 jason + + * MethodTypes.cxx: added definition of strncasecmp + +2002-09-30 14:47 jason + + * Transport.cxx, Transport.hxx, UdpTransport.cxx: fixed SendData + constructor to take address reference + +2002-09-30 14:46 jason + + * DataParameter.cxx, DataParameter.hxx, ExistsParameter.cxx, + ExistsParameter.hxx, FloatParameter.cxx, FloatParameter.hxx, + HeaderFieldValue.cxx, IntegerParameter.cxx, IntegerParameter.hxx, + ParameterTypeEnums.hxx, ParameterTypes.cxx, ParameterTypes.hxx, + SipMessage.cxx, SipMessage.hxx, Symbols.cxx, Symbols.hxx, + UnknownParameter.cxx, UnknownParameter.hxx: addded decode, used + ParseBuffer + +2002-09-30 14:19 jason + + * os/: ParseBuffer.cxx, ParseBuffer.hxx: ++ confusion + +2002-09-30 13:55 jason + + * os/ThreadIf.cxx: #ifdeffed out WIN32 clause + +2002-09-30 13:53 jason + + * os/Makefile, os/ParseBuffer.cxx, os/ParseBuffer.hxx, + test/testParseBuffer.cxx: in-place non-destructive parsing + +2002-09-30 12:22 jason + + * Dialog.cxx, Dialog.hxx, Helper.cxx, Helper.hxx, + ParserCategory.cxx, ParserCategory.hxx, SipMessage.hxx, Uri.hxx: + replaced Url w/ nameAddr. changed to param(p_foo) from [p_foo] + syntax. For safety w/ pointers and to avoid uri()[p_foo] uglyness. + +2002-09-30 11:53 jason + + * TimerQueue.cxx: fixed process--would only haved processed timers + that are now + +2002-09-30 11:49 jason + + * os/Logger.hxx: recorrected the __VA_ARGS macros + +2002-09-29 16:41 fluffy + + * os/Data.hxx, os/Fifo.cxx, os/Log.cxx, os/Logger.hxx, + os/Mutex.cxx, os/RandomHex.cxx, os/Socket.cxx, os/Socket.hxx, + os/SysLogBuf.hxx, os/ThreadIf.cxx, os/ThreadIf.hxx, + os/VException.cxx, HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderTypes.cxx, HeaderTypes.hxx, MethodTypes.cxx, + ParserCategories.cxx, ParserCategory.hxx, Preparse.cxx, + SipMessage.cxx, SipMessage.hxx, SipStack.cxx, TimerQueue.cxx, + Transport.cxx, Transport.hxx, UdpTransport.cxx, testUdp.cxx: + changes for Win32 + +2002-09-29 10:14 jason + + * os/Mutex.hxx: [no log message] + +2002-09-28 17:47 alan + + * doc/: .cvsignore, Makefile, design-overview.xml, design.css, + htmlcss.xsl: Added XML DocBook design doc (initial) + +2002-09-28 10:30 fluffy + + * os/: Condition.cxx, Condition.hxx, Fifo.hxx: cleaned up Fifo + +2002-09-28 10:01 fluffy + + * os/: ThreadIf.cxx, ThreadIf.hxx: added some win32 stuff + +2002-09-28 09:41 fluffy + + * os/: Condition.cxx, Condition.hxx, Fifo.hxx, Makefile, Mutex.cxx, + Mutex.hxx, RandomHex.cxx, ThreadIf.cxx, ThreadIf.hxx, Fifo.cxx, + Fifo.cc: cleaned up thread and lock abstractions + +2002-09-28 08:22 fluffy + + * DataParameter.cxx: fix include + +2002-09-28 08:22 fluffy + + * convertStringToInt.cxx: fix return + +2002-09-27 23:13 jason + + * SipMessage.cxx, SipMessage.hxx, SipMessageExplicit.cxx: hoisted + some code out of the template methods + +2002-09-27 22:35 jason + + * SipMessage.cxx, SipMessage.hxx, SipMessageExplicit.cxx, + SipMessageExplicit.hxx: #if switched method templating/explicit + method declaration and defining + +2002-09-27 22:02 fluffy + + * SIPSTACK.dsp: no message + +2002-09-27 21:59 fluffy + + * Transport.hxx, UdpTransport.cxx: switched file descriptors to + Socket + +2002-09-27 21:47 fluffy + + * SipStack.cxx, SipStack.hxx, testSipStack1.cxx: added the fd_set + stuff to the interface + +2002-09-27 21:44 fluffy + + * os/: Makefile, Socket.cxx, Socket.hxx: added Socket class that is + a file descriptor in unix and a SOCKET in windows + +2002-09-27 18:38 jason + + * Dialog.cxx, HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderTypes.cxx, HeaderTypes.hxx, Helper.cxx, Helper.hxx, + HostSpecification.hxx, Makefile, MethodTypes.hxx, + ParserCategories.cxx, ParserCategories.hxx, ParserCategory.hxx, + SipMessage.cxx, SipMessage.hxx, Symbols.cxx, Symbols.hxx, Uri.cxx, + Uri.hxx: Uri component NameAddr is back NameAddr and RequestLine + have a Uri + +2002-09-27 11:24 jason + + * .cvsignore: [no log message] + +2002-09-27 10:43 jason + + * os/Inserter.hxx: [no log message] + +2002-09-27 06:52 fluffy + + * os/RandomHex.cxx: removed open ssl rand stuff + +2002-09-27 06:48 fluffy + + * Makefile, os/Makefile: [no log message] + +2002-09-26 20:02 alan + + * .cvsignore: Added html subdir + +2002-09-26 19:49 alan + + * .cvsignore, ChangeLog, HeaderTypes.cxx, HeaderTypes.hxx, + Makefile, Symbols.cxx, headers.gperf, testHash.cxx: See changelog. + Fixed up hash routines so they work. :-) + +2002-09-26 19:00 jason + + * os/: Data.cxx, Data.hxx: [no log message] + +2002-09-26 17:24 jason + + * HeaderTypes.cxx, HeaderTypes.hxx: fixed some header + declaration/definition issues -- still need to make crossed + MultiHeader/Header decls not compile + +2002-09-26 17:00 jason + + * DataParameter.cxx, DataParameter.hxx, HeaderFieldValue.cxx, + HeaderFieldValue.hxx, Parameter.hxx, ParserCategories.cxx, + ParserCategory.cxx, ParserCategory.hxx, Symbols.cxx, Symbols.hxx, + UnknownParameter.hxx: parser stuff + +2002-09-26 15:00 alan + + * .cvsignore, HeaderTypes.cxx, HeaderTypes.hxx, Makefile, + testTypes.cxx: Adding testTypes + +2002-09-26 14:58 jason + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, Helper.hxx, + ParserCategory.cxx, ParserCategory.hxx, os/VException.cxx, + os/VException.hxx: [no log message] + +2002-09-26 13:57 jason + + * DataParameter.cxx, DataParameter.hxx, FloatParameter.hxx, + HeaderFieldValue.cxx, HeaderFieldValue.hxx, HeaderTypes.cxx, + HeaderTypes.hxx, IntegerParameter.hxx, Parameter.cxx, + Parameter.hxx, ParameterList.cxx, ParameterTypeEnums.hxx, + ParameterTypes.cxx, ParserCategories.cxx, ParserCategory.cxx, + ParserCategory.hxx, UnknownParameter.cxx, UnknownParameter.hxx, + headers.gperf, parameters.gperf: parser stuff + +2002-09-26 12:46 jason + + * Dialog.cxx, Dialog.hxx, HeaderTypes.cxx, HeaderTypes.hxx, + Makefile, ParserCategories.hxx, ParserContainer.hxx, + SipMessage.cxx, SipMessage.hxx, SipStack.cxx, SipStack.hxx, + Symbols.cxx, Symbols.hxx: [no log message] + +2002-09-26 10:45 jason + + * ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx: [no + log message] + +2002-09-25 20:56 fluffy + + * doc/ClassDiag.vsd: first cut + +2002-09-25 20:36 jason + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, ParseException.hxx, + ParserCategories.cxx, ParserCategory.cxx, ParserCategory.hxx: + parser stuff + +2002-09-25 19:03 jason + + * Helper.hxx, ParserCategories.hxx, os/Data.cxx, os/Data.hxx: [no + log message] + +2002-09-25 18:48 jason + + * testHashCasen.cxx: playing around with hashing functions + +2002-09-25 18:12 jason + + * HeaderFieldValue.cxx, HeaderFieldValueList.cxx, + HeaderFieldValueList.hxx, HeaderTypes.cxx, HeaderTypes.hxx, + Message.cxx, Message.hxx, MethodTypes.cxx, MethodTypes.hxx, + ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, + ParserCategory.hxx, ParserContainer.hxx, ParserContainerBase.hxx, + SipMessage.cxx, SipMessage.hxx, SipStack.cxx, Symbols.cxx, + Symbols.hxx, TimerMessage.cxx, TimerMessage.hxx, + TransactionState.cxx: ParserContainerBase no longer a + ParserCategory Added string names to headers, comma tokenizing in + constructor casts => dynamic_cast + +2002-09-25 17:46 jason + + * os/RandomHex.cxx: [no log message] + +2002-09-25 17:34 jason + + * Makefile, os/Makefile: [no log message] + +2002-09-25 17:30 jason + + * Makefile, os/Makefile, os/Subsystem.cxx, os/Subsystem.hxx: [no + log message] + +2002-09-25 15:50 jason + + * os/: .cvsignore, Inserter.hxx, Makefile, RandomHex.cxx, + RandomHex.hxx: [no log message] + +2002-09-25 15:28 jason + + * Singleton.h, Threads.h: [no log message] + +2002-09-25 15:25 jason + + * Condition.cxx, Condition.hxx, Data.cxx, Data.hxx, + DataParameter.hxx, Dialog.cxx, Executive.cxx, Fifo.cc, Fifo.hxx, + FloatSubComponent.cxx, FloatSubComponent.hxx, HeaderTypes.cxx, + HeaderTypes.hxx, HostSpecification.hxx, IntSubComponent.cxx, + IntSubComponent.hxx, Lock.cxx, Lock.hxx, Lockable.hxx, Log.cxx, + Log.hxx, Logger.cxx, Logger.hxx, Makefile, Message.hxx, + MethodTypes.cxx, Mutex.cxx, Mutex.hxx, Parameter.hxx, + ParameterTypeEnums.hxx, ParameterTypes.hxx, ParserCategories.hxx, + ParserCategory.hxx, ParserContainerBase.hxx, Preparse.cxx, + SipMessage.hxx, SipStack.cxx, SipStack.hxx, StringSubComponent.cxx, + StringSubComponent.hxx, SubComponent.cxx, SubComponent.hxx, + SubComponentList.cxx, SubComponentList.hxx, Subsystem.cxx, + Subsystem.hxx, SysLogBuf.hxx, SysLogStream.hxx, ThreadIf.cxx, + ThreadIf.hxx, Timer.cxx, Timer.hxx, TimerMessage.hxx, + TimerQueue.cxx, TimerQueue.hxx, TransactionMap.cxx, + TransactionMap.hxx, TransactionState.cxx, Transport.hxx, + TransportSelector.hxx, UdpTransport.cxx, UnknownSubComponent.cxx, + UnknownSubComponent.hxx, testHeaderFieldValueList.cxx, testMsg.cxx, + testPreparse.cxx, testSipStack1.cxx, testSubComponentList.cxx, + testUdp.cxx, vthread.hxx: moved util classes into ../util + +2002-09-25 15:24 jason + + * os/: Condition.cxx, Condition.hxx, Data.cxx, Data.hxx, Fifo.cc, + Fifo.hxx, Lock.cxx, Lock.hxx, Lockable.hxx, Log.cxx, Log.hxx, + Logger.cxx, Logger.hxx, Makefile, Mutex.cxx, Mutex.hxx, + Subsystem.cxx, Subsystem.hxx, SysLogBuf.hxx, SysLogStream.hxx, + ThreadIf.cxx, ThreadIf.hxx, Timer.cxx, Timer.hxx, vthread.hxx: + moved util classes into here + +2002-09-25 15:08 jason + + * Dialog.cxx, Dialog.hxx, Helper.hxx, ParameterTypeEnums.hxx, + ParameterTypes.hxx, Symbols.cxx, Symbols.hxx: [no log message] + +2002-09-25 15:02 jason + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, Helper.cxx, Makefile, + ParserCategories.cxx, ParserCategory.cxx, ParserCategory.hxx, + ParserContainer.hxx, SipMessage.cxx: [no log message] + +2002-09-25 13:13 jason + + * ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, + ParserCategory.hxx: << ParserCategory Symbols::DefaultSipVersion + +2002-09-25 13:09 jason + + * Dialog.cxx, Helper.hxx: [no log message] + +2002-09-25 13:05 jason + + * ParserCategories.cxx, ParserCategories.hxx, ParserContainer.hxx, + SipMessage.hxx, Symbols.cxx, Symbols.hxx: RequestLineComponent => + RequestLine StatusLineComponent => StatusLine + +2002-09-25 13:04 jason + + * Helper.hxx: [no log message] + +2002-09-25 13:00 jason + + * Helper.hxx: [no log message] + +2002-09-25 12:50 jason + + * Helper.hxx: [no log message] + +2002-09-25 12:45 jason + + * ParserCategories.cxx, ParserCategories.hxx: collapsed NameAddr, + NameAddrOrAddrSpec, Contact int Url + +2002-09-25 12:40 jason + + * Dialog.cxx, Dialog.hxx, ThreadIf.cxx, ThreadIf.hxx, vthread.hxx, + Makefile: [no log message] + +2002-09-25 12:37 jason + + * ParserCategories.hxx, HeaderTypes.hxx: collapsed NameAddr, + NameAddrOrAddrSpec, Contact int Url + +2002-09-25 12:17 jason + + * HeaderTypes.cxx, HeaderTypes.hxx, TransactionState.cxx: changed + to h_CamelCase convention + +2002-09-25 12:08 jason + + * ExistsParameter.hxx, FloatParameter.hxx, HeaderTypes.cxx, + HeaderTypes.hxx: [no log message] + +2002-09-25 12:03 jason + + * DataParameter.hxx, ExistsParameter.hxx, FloatParameter.hxx, + HeaderFieldValue.hxx, HeaderFieldValueList.cxx, HeaderTypes.cxx, + HeaderTypes.hxx, IntegerParameter.hxx, ParserCategory.hxx, + ParserContainer.hxx, SipMessage.hxx: fix to SipMessage templated + methods + +2002-09-25 11:57 jason + + * SipStack.cxx, SipStack.hxx: changed interface for SipStack::send + +2002-09-25 09:42 jason + + * Dialog.cxx, SipMessage.hxx: [no log message] + +2002-09-25 07:59 jason + + * testParameterList.cxx: [no log message] + +2002-09-25 07:26 alan + + * UdpTransport.cxx, UdpTransport.hxx: Fixed up some compile issues. + Changed type for MaxBufferSize to size_t. Unsigned long was not + appropriate. + +2002-09-24 22:41 jason + + * ExistsParameter.hxx, FloatParameter.hxx, HeaderTypes.cxx, + HeaderTypes.hxx, ParserCategories.hxx, ParserCategory.hxx, + SubComponentList.hxx, TransactionState.cxx: [no log message] + +2002-09-24 22:23 jason + + * Helper.hxx, ParserCategories.hxx: [no log message] + +2002-09-24 21:49 jason + + * Makefile, testSubComponentList.cxx: SubComponent => Parameter + +2002-09-24 21:42 jason + + * DataParameter.cxx, DataParameter.hxx, ExistsParameter.cxx, + ExistsParameter.hxx, FloatParameter.cxx, FloatParameter.hxx, + HeaderFieldValue.cxx, HeaderFieldValue.hxx, HeaderTypes.cxx, + HeaderTypes.hxx, IntegerParameter.cxx, IntegerParameter.hxx, + Makefile, Parameter.cxx, Parameter.hxx, ParameterList.cxx, + ParameterList.hxx, ParameterTypeEnums.hxx, ParameterTypes.cxx, + ParameterTypes.hxx, ParserCategory.hxx, README, SipMessage.cxx, + SipMessage.hxx, SubComponent.hxx, Symbols.cxx, Symbols.hxx, + TransactionState.cxx, UnknownParameter.cxx, UnknownParameter.hxx: + SubComponent => Parameter + +2002-09-24 21:32 fluffy + + * SIPSTACK.dsw: SIPSTACK.dsp + +2002-09-24 21:30 fluffy + + * Condition.cxx, FloatSubComponent.hxx, Log.cxx, Log.hxx, Makefile, + MethodTypes.cxx, Mutex.cxx, Mutex.hxx, ParserCategories.cxx, + ParserCategory.cxx, ParserContainerBase.hxx, SipMessage.hxx, + StringSubComponent.cxx, StringSubComponent.hxx, SysLogBuf.hxx, + Threads.h, Transport.hxx, testHeaderFieldValueList.cxx, + testSipStack1.cxx, vthread.hxx: few changes for win32 + +2002-09-24 21:29 fluffy + + * Data.cxx: [no log message] + +2002-09-24 21:07 jason + + * Helper.hxx, Dialog.cxx, Dialog.hxx, HeaderTypes.hxx, + ParserContainer.hxx, TODO: [no log message] + +2002-09-24 19:16 jason + + * Helper.hxx: [no log message] + +2002-09-24 18:33 jason + + * TransactionState.cxx, UdpTransport.cxx: using get() rather than + [], some interfaces changed in parser categories + +2002-09-24 18:20 jason + + * Dialog.hxx, SipMessage.cxx, SipMessage.hxx, TransactionState.cxx: + [no log message] + +2002-09-24 18:16 jason + + * Helper.hxx: [no log message] + +2002-09-24 18:07 jason + + * HeaderFieldValue.hxx, HeaderFieldValueList.cxx, HeaderTypes.cxx, + ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, + ParserCategory.hxx, ParserContainer.hxx, ParserContainerBase.hxx, + SipMessage.cxx, SipMessage.hxx, TransactionState.cxx: [no log + message] + +2002-09-24 16:08 alan + + * Preparse.cxx, UdpTransport.cxx: Comments / fleshing out error + conditions + +2002-09-23 16:11 jason + + * HeaderTypes.cxx, HeaderTypes.hxx, ParserCategories.hxx: [no log + message] + +2002-09-23 14:34 jason + + * HeaderTypes.hxx: [no log message] + +2002-09-23 10:33 jason + + * HeaderTypes.hxx, Makefile, ParserCategory.cxx, SipMessage.hxx, + TransactionState.cxx, TransactionState.hxx: [no log message] + +2002-09-22 17:37 dabryan + + * TransactionState.cxx: [no log message] + +2002-09-22 17:32 dabryan + + * TransactionState.cxx, TransactionState.hxx: [no log message] + +2002-09-22 17:24 fluffy + + * .cvsignore, Makefile: Removed old graph rules (now in doc subdir) + +2002-09-22 17:21 fluffy + + * dot.awk: Removed DOT stuff from this dir. + +2002-09-22 17:11 fluffy + + * doc/srv-inv-tree.dot: Added CVS header comments + +2002-09-22 17:09 fluffy + + * doc/: Makefile, srv-inv-tree.dot: Initial server INVITE tree + diagram + +2002-09-22 16:14 dabryan + + * TransactionState.cxx, TransactionState.hxx: [no log message] + +2002-09-22 15:56 fluffy + + * TODO: [no log message] + +2002-09-22 15:32 dabryan + + * Timer.cxx, Timer.hxx, TimerMessage.cxx, TimerMessage.hxx, + TimerQueue.cxx, TransactionState.cxx, TransactionState.hxx: [no log + message] + +2002-09-22 15:08 fluffy + + * doc/: .cvsignore, Makefile, fsm-dot.awk: Moved Preparse FSM + diagram into this dir. + +2002-09-22 15:04 fluffy + + * doc/srv-inv-fsm.dot: + Fixed up + +2002-09-22 14:34 fluffy + + * doc/: .cvsignore, Makefile, srv-inv-fsm.dot: + Fixed up + +2002-09-22 14:32 fluffy + + * doc/: Makefile, srv-inv-fsm.dot: Adding FSM Impound + +2002-09-22 11:44 jason + + * HeaderTypes.cxx, HeaderTypes.hxx, ParserCategories.hxx, + ParserCategory.hxx: [no log message] + +2002-09-22 11:26 dabryan + + * SipStack.cxx, testSipStack1.cxx, Executive.cxx: [no log message] + +2002-09-22 11:19 dabryan + + * Executive.cxx, ParserCategories.cxx, SipMessage.cxx, + TransactionState.cxx: [no log message] + +2002-09-22 11:19 fluffy + + * UdpTransport.cxx: Made Single Shot Test Message + +2002-09-22 11:13 fluffy + + * Preparse.cxx, TimerMessage.cxx, UdpTransport.cxx: Added dump ops. + +2002-09-22 11:08 dabryan + + * Makefile, Message.cxx, Message.hxx, SipMessage.cxx, + SipMessage.hxx, TimerMessage.hxx, convertStringToInt.cxx: [no log + message] + +2002-09-22 11:01 dabryan + + * Executive.cxx, Message.hxx, SipMessage.cxx, SipMessage.hxx, + SipStack.cxx, TimerMessage.hxx, TimerQueue.cxx, + TransactionState.cxx, TransactionState.hxx, TransportSelector.cxx, + TransportSelector.hxx, UdpTransport.cxx: [no log message] + +2002-09-22 10:48 fluffy + + * TransactionState.cxx: Added op<< + +2002-09-22 10:41 jason + + * SipMessage.cxx: [no log message] + +2002-09-22 10:41 dabryan + + * .cvsignore, TransactionState.cxx, TransactionState.hxx, + Transport.cxx, Transport.hxx, TransportSelector.cxx, + TransportSelector.hxx, UdpTransport.cxx, testSipStack1.cxx: [no log + message] + +2002-09-22 10:29 jason + + * HeaderFieldValueList.hxx, HeaderTypes.hxx, SipMessage.hxx: [no + log message] + +2002-09-22 10:20 fluffy + + * UdpTransport.cxx: dummy messages + +2002-09-22 10:08 dabryan + + * ParserCategories.cxx: Added bodeis for clone + +2002-09-22 10:02 dabryan + + * ParserCategories.cxx, ParserCategories.hxx: Added destructors + +2002-09-22 10:00 fluffy + + * ParserCategories.cxx, SipMessage.cxx, .cvsignore: [no log + message] + +2002-09-22 09:55 dabryan + + * ParserCategories.hxx: Added a comment. + +2002-09-22 09:53 dabryan + + * ParserCategories.hxx: Added parse method to RequestLine and + StatusLine components, just a dummy assert zero for now. + +2002-09-22 09:11 fluffy + + * Makefile, SipMessage.cxx, TimerMessage.cxx, TimerMessage.hxx: + compiles and links + +2002-09-22 08:00 fluffy + + * Preparse.cxx: [no log message] + +2002-09-22 00:54 jason + + * HeaderTypes.cxx, Makefile, Message.hxx, SipMessage.cxx, + SipMessage.hxx, TransactionState.cxx, TransactionState.hxx, + testSipMessage.cxx: [no log message] + +2002-09-22 00:31 dabryan + + * ParserCategories.cxx, ParserCategories.hxx: Added CSeq and + Integer components to the parser. + +2002-09-22 00:30 fluffy + + * Preparse.cxx: Added COMMA + +2002-09-22 00:25 jason + + * MethodTypes.hxx, ParserCategories.cxx, ParserCategories.hxx: [no + log message] + +2002-09-22 00:22 fluffy + + * Preparse.cxx, Preparse.hxx: FSM State/Edge Complete + +2002-09-22 00:14 fluffy + + * Preparse.cxx: Minor updates for diagnostics. + +2002-09-22 00:03 jason + + * Executive.cxx, Executive.hxx, Makefile, TimerMessage.cxx, + TimerMessage.hxx, TransactionState.cxx, TransportSelector.cxx: [no + log message] + +2002-09-21 23:47 jason + + * Makefile, Message.hxx, MethodTypes.cxx, SipMessage.cxx, + SipMessage.hxx, TimerMessage.hxx, TransactionState.cxx, + TransactionState.hxx, TransportSelector.cxx: [no log message] + +2002-09-21 23:44 fluffy + + * Makefile: Dependancy fixes + +2002-09-21 23:39 fluffy + + * Makefile: Safety checkin + +2002-09-21 23:26 fluffy + + * Makefile: [no log message] + +2002-09-21 22:49 dabryan + + * MethodTypes.cxx, MethodTypes.hxx: [no log message] + +2002-09-21 22:40 dabryan + + * ParserCategories.hxx, SipMessage.hxx: [no log message] + +2002-09-21 22:37 dabryan + + * Makefile, MethodTypes.cxx, MethodTypes.hxx, ParserCategories.cxx, + ParserCategories.hxx, ParserCategory.hxx, SipMessage.hxx, + Symbols.cxx, Symbols.hxx: [no log message] + +2002-09-21 22:30 fluffy + + * Makefile: Moved Transport error + +2002-09-21 22:10 fluffy + + * Makefile, TimerMessage.hxx, TransactionState.cxx, + TransactionState.hxx: [no log message] + +2002-09-21 22:07 fluffy + + * Preparse.cxx: Added Header Transition + +2002-09-21 21:51 jason + + * TransactionState.cxx, TransactionState.hxx: [no log message] + +2002-09-21 21:32 jason + + * SipStack.hxx, TransactionState.cxx: [no log message] + +2002-09-21 21:22 fluffy + + * Preparse.hxx: General Updates + +2002-09-21 21:22 fluffy + + * Preparse.cxx: General Updates. + +2002-09-21 21:20 fluffy + + * UdpTransport.cxx, testUdp.cxx, testSipStack1.cxx: General + Migrations. + +2002-09-21 21:18 dabryan + + * SipMessage.hxx: [no log message] + +2002-09-21 21:15 jason + + * Message.hxx, SipMessage.hxx, Timer.cxx, Timer.hxx, + TimerMessage.hxx, TransactionState.cxx, TransactionState.hxx, + TransportSelector.hxx: [no log message] + +2002-09-21 21:11 fluffy + + * TransactionState.cxx, TransactionState.hxx: [no log message] + +2002-09-21 21:05 dabryan + + * Makefile, MethodTypes.hxx, ParserCategories.cxx, + ParserCategories.hxx, ParserCategory.hxx, ParserContainer.hxx, + SipMessage.hxx, SipMessage.hxx: [no log message] + +2002-09-21 20:55 fluffy + + * Executive.cxx, TransactionState.cxx, TransactionState.hxx: [no + log message] + +2002-09-21 20:26 dabryan + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, ParserCategories.cxx, + ParserCategories.hxx, ParserCategory.hxx, SipMessage.cxx, + SipMessage.hxx: [no log message] + +2002-09-21 20:06 jason + + * Message.hxx, SipMessage.hxx, SipStack.cxx, SipStack.hxx, + TimerMessage.hxx, TransactionState.cxx, TransactionState.hxx: [no + log message] + +2002-09-21 20:02 fluffy + + * Makefile, TransactionState.hxx: [no log message] + +2002-09-21 19:58 fluffy + + * TransactionState.hxx, TransactionState.hxx: [no log message] + +2002-09-21 19:51 fluffy + + * Preparse.cxx, UdpTransport.cxx: Loggin and test + +2002-09-21 19:38 jason + + * Transport.cxx, UdpTransport.cxx: warnings + +2002-09-21 19:37 jason + + * Logger.cxx, Logger.hxx, Makefile: [no log message] + +2002-09-21 19:31 dabryan + + * HeaderFieldValue.hxx, HeaderFieldValueList.hxx, HeaderTypes.hxx, + Makefile, ParserCategories.hxx, SipMessage.hxx, testSipMessage.cxx: + [no log message] + +2002-09-21 19:28 dabryan + + * Executive.cxx, SipStack.cxx, SipStack.hxx, TransactionState.hxx, + TransportSelector.cxx, TransportSelector.hxx: Changes to get stack + to build + +2002-09-21 18:56 fluffy + + * Singleton.h, testUdp.cxx: [no log message] + +2002-09-21 18:30 fluffy + + * UdpTransport.cxx: Added Preparse hooks + +2002-09-21 18:30 dabryan + + * Data.hxx: fix snafu + +2002-09-21 18:19 fluffy + + * SipMessage.cxx: Removed stub addSource(). + +2002-09-21 18:16 fluffy + + * Data.cxx, SipMessage.cxx, SipMessage.hxx: UDP test integration. + +2002-09-21 18:10 dabryan + + * Executive.cxx, SipStack.cxx, SipStack.hxx: More changes to get + things going for the calls from the top level down to the bottom. + +2002-09-21 18:07 jason + + * TransactionMap.cxx, TransactionMap.hxx, TransactionState.hxx, + Makefile, .cvsignore: [no log message] + +2002-09-21 18:06 dabryan + + * HeaderFieldValue.cxx, HeaderFieldValueList.cxx, + HeaderFieldValueList.hxx, ParserCategory.hxx, SipMessage.cxx, + ParserCategory.hxx: [no log message] + +2002-09-21 18:01 fluffy + + * Makefile, Preparse.cxx, UdpTransport.cxx: Minor changes. + +2002-09-21 17:57 dabryan + + * SipStack.cxx, SipStack.hxx, TransportSelector.cxx, + TransportSelector.hxx, testSipStack1.cxx: Added some more code in + the middle between the stack and the lower level stuff. + +2002-09-21 17:56 dabryan + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, SipMessage.cxx, + SipMessage.hxx, Timer.cxx: [no log message] + +2002-09-21 17:34 dabryan + + * HeaderTypes.cxx, HeaderTypes.hxx, Makefile, ParserCategories.hxx, + ParserCategories.cxx, Symbols.cxx: [no log message] + +2002-09-21 17:24 dabryan + + * Makefile: Added logic to build testSipStack1 + +2002-09-21 17:23 jason + + * Makefile, Timer.cxx, Timer.hxx: added timers + +2002-09-21 17:20 dabryan + + * TransactionMap.cxx, TransportSelector.cxx: Added bodies for these + classes, no code yet. + +2002-09-21 17:20 fluffy + + * HeaderFieldValue.cxx: [no log message] + +2002-09-21 17:15 jason + + * Timer.cxx, TimerMessage.hxx, TimerQueue.cxx, TimerQueue.hxx, + Timer.hxx: added timers + +2002-09-21 17:14 fluffy + + * .cvsignore: Added .dot file. + +2002-09-21 17:13 dabryan + + * HeaderTypes.cxx, HeaderTypes.hxx, Logger.hxx, + ParserCategories.hxx, SipMessage.cxx, SipMessage.hxx, + SysLogBuf.hxx, SysLogStream.hxx, Transport.cxx, Transport.hxx: [no + log message] + +2002-09-21 17:02 fluffy + + * .cvsignore: Added cvsignore file. + +2002-09-21 17:02 fluffy + + * HeaderTypes.cxx, SipMessage.cxx, SipMessage.hxx, Transport.hxx, + UdpTransport.cxx: Compiles + +2002-09-21 16:52 fluffy + + * HeaderFieldValue.cxx, HeaderTypes.cxx, HeaderTypes.hxx, + Preparse.cxx, Preparse.hxx, SipMessage.hxx, Threads.h, + UdpTransport.cxx, UdpTransport.hxx, testUdp.cxx: Preparser + integration. + +2002-09-21 16:41 fluffy + + * Makefile: [no log message] + +2002-09-21 16:34 fluffy + + * SipMessage.hxx, Transport.cxx, Transport.hxx, UdpTransport.cxx, + UdpTransport.hxx: [no log message] + +2002-09-21 16:31 dabryan + + * Executive.cxx, Executive.hxx, Fifo.cc, SipStack.cxx, + SipStack.hxx, TransactionMap.hxx, TransportSelector.hxx: Cleaned + up, added more code. + +2002-09-21 16:27 dabryan + + * Message.hxx: [no log message] + +2002-09-21 16:23 fluffy + + * testPreparse.cxx: Added quick (inop) test class + +2002-09-21 16:16 fluffy + + * SipMessage.hxx: Added setSource + +2002-09-21 16:05 dabryan + + * Timer.hxx: Renamed to TimerWheel. + +2002-09-21 16:03 dabryan + + * Message.hxx, SipMessage.cxx, SipMessage.hxx, TimerMessage.hxx, + ParserContainerBase.hxx: [no log message] + +2002-09-21 15:56 fluffy + + * Preparse.cxx, Preparse.hxx: Updates. + +2002-09-21 15:14 dabryan + + * SipMessage.cxx, SipMessage.hxx: [no log message] + +2002-09-21 14:00 dabryan + + * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, + HeaderTypes.cxx, ParserContainer.hxx, SipMessage.cxx, + SipMessage.hxx: [no log message] + +2002-09-21 13:53 dabryan + + * SipMessage.cxx, SipMessage.hxx, SipStack.cxx, SipStack.hxx: Put + body into the SipStack code, added a fixed destination to the + SipMessage class. + +2002-09-21 13:51 dabryan + + * HeaderTypes.hxx: [no log message] + +2002-09-21 13:30 fluffy + + * TransportSelector.hxx: [no log message] + +2002-09-21 13:19 fluffy + + * Executive.cxx, TransactionState.hxx: [no log message] + +2002-09-21 13:15 dabryan + + * Condition.cxx, Condition.hxx, Data.hxx, Fifo.hxx, + FloatSubComponent.hxx, HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, + HeaderTypes.cxx, HeaderTypes.hxx, HostSpecification.hxx, + IntSubComponent.hxx, Lock.cxx, Lock.hxx, Log.cxx, Log.hxx, + Makefile, Mutex.cxx, Mutex.hxx, ParserCategories.hxx, + ParserCategory.hxx, ParserContainer.hxx, Preparse.cxx, + SipMessage.cxx, SipMessage.hxx, StringSubComponent.cxx, + StringSubComponent.hxx, SubComponent.cxx, SubComponent.hxx, + SubComponentList.cxx, SubComponentList.hxx, Subsystem.hxx, + TransactionMap.hxx, Transport.cxx, Transport.hxx, UdpTransport.cxx, + UdpTransport.hxx, UnknownSubComponent.cxx, UnknownSubComponent.hxx, + testHeaderFieldValueList.cxx, testSubComponentList.cxx: [no log + message] + +2002-09-21 13:04 fluffy + + * Makefile, Preparse.cxx, Preparse.hxx: Compilation errors. + +2002-09-21 12:54 fluffy + + * Makefile: Added Preparse tests + +2002-09-21 12:52 jason + + * SipStack.hxx, HeaderFieldValueList.hxx, SubComponentList.hxx: [no + log message] + +2002-09-21 12:51 dabryan + + * Data.hxx, HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, + HeaderTypes.cxx, HeaderTypes.hxx, Log.cxx, Log.hxx, + ParserCategories.hxx, ParserCategory.hxx, ParserContainer.hxx, + SipMessage.cxx, SipMessage.hxx, Symbols.hxx, supported.hxx: [no log + message] + +2002-09-21 12:48 fluffy + + * TransactionState.hxx, TransportSelector.hxx, SipStack.hxx, + TransportSelector.hxx: [no log message] + +2002-09-21 12:48 dabryan + + * testHeaderFieldValueList.cxx: Testing code for the + HeaderFieldValueList object. + +2002-09-21 12:46 jason + + * Transport.cxx, Transport.hxx, UdpTransport.cxx, UdpTransport.hxx: + [no log message] + +2002-09-21 12:34 fluffy + + * dot.awk: Utility awk file for making DOT input file from Preparse + FSM + +2002-09-21 12:30 fluffy + + * Preparse.cxx: Added missing const. + +2002-09-21 12:30 fluffy + + * Preparse.cxx, testpp.cxx: Early Preparse. Integration about to + begin. + +2002-09-21 12:29 fluffy + + * Executive.cxx, Executive.hxx, Timer.hxx: [no log message] + +2002-09-21 12:26 dabryan + + * HeaderFieldValue.cxx, HeaderFieldValueList.cxx: Changes to fix + copy bug in header code + +2002-09-21 12:25 jason + + * .cvsignore, Data.hxx, Makefile: [no log message] + +2002-09-21 12:18 jason + + * Log.cxx, Log.hxx, Logger.hxx, Makefile, Subsystem.cxx, + Subsystem.hxx, SysLogBuf.hxx, SysLogStream.hxx, Data.cxx, Data.hxx: + [no log message] + +2002-09-21 12:03 dabryan + + * HeaderFieldValue.cxx, HeaderFieldValueList.cxx, + testHeaderFieldValueList.cxx: Fixes to allow others to compile. + +2002-09-21 11:50 fluffy + + * Preparse.cxx, Preparse.hxx, testpp.cxx: Improvements, still not + functional. + +2002-09-21 11:27 dabryan + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderFieldValueList.cxx, ParserCategory.hxx, SubComponentList.cxx, + SubComponentList.hxx: Changes for header and subcomponent lists. + +2002-09-21 11:26 dabryan + + * testHeaderFieldValueList.cxx: Added test file for + HeaderFieldValueLists + +2002-09-21 11:06 jason + + * Log.cxx, Log.hxx, Logger.hxx, Singleton.h, Subsystem.cxx, + SysLogBuf.hxx, SysLogStream.hxx, Threads.h, testUdp.cxx: [no log + message] + +2002-09-21 10:30 jason + + * Log.cxx, Log.hxx, Logger.hxx, Subsystem.cxx, Subsystem.hxx: [no + log message] + +2002-09-21 10:07 dabryan + + * FloatSubComponent.cxx, FloatSubComponent.hxx, + HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderFieldValueList.cxx, IntSubComponent.cxx, IntSubComponent.hxx, + StringSubComponent.cxx, StringSubComponent.hxx, SubComponent.cxx, + SubComponent.hxx, SubComponentList.cxx, SubComponentList.hxx: [no + log message] + +2002-09-21 09:48 fluffy + + * Executive.hxx, Makefile: [no log message] + +2002-09-21 09:44 fluffy + + * Executive.hxx, TransactionMap.hxx: [no log message] + +2002-09-21 08:32 fluffy + + * .cvsignore: [no log message] + +2002-09-21 08:28 fluffy + + * SipStack.hxx, testSipStack1.cxx, Makefile: [no log message] + +2002-09-20 23:54 fluffy + + * Preparse.cxx, Preparse.hxx, testpp.cxx: Moved Preparse initial + implementaiton + +2002-09-20 23:49 jason + + * HeaderTypes.cxx, HeaderTypes.hxx, HostSpecification.hxx, + ParserCategory.hxx, SipMessage.cxx, SipMessage.hxx, + HeaderFieldValue.cxx, HeaderFieldValue.hxx, Makefile, + ParseException.hxx, ParserContainer.hxx, UnknownSubComponent.hxx: + [no log message] + +2002-09-20 23:21 fluffy + + * .cvsignore: testSubComponentList + +2002-09-20 22:57 jason + + * Condition.cxx, Condition.hxx, Fifo.cc, Fifo.hxx, Lock.cxx, + Lock.hxx, Lockable.hxx, Mutex.cxx, Mutex.hxx, Transport.cxx, + Transport.hxx, UdpTransport.cxx, UdpTransport.hxx, testUdp.cxx, + vthread.hxx: [no log message] + +2002-09-20 22:55 dabryan + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, ParseException.hxx, + SubComponentList.cxx, SubComponentList.hxx: Added exists, get, a + bit of cleaning, some exceptions + +2002-09-20 22:40 jason + + * FloatSubComponent.cxx, FloatSubComponent.hxx, + IntSubComponent.cxx, IntSubComponent.hxx, ParserContainer.hxx, + UnknownSubComponent.cxx, UnknownSubComponent.hxx: [no log message] + +2002-09-20 22:09 dabryan + + * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx: Moved some + stuff public + +2002-09-20 22:07 jason + + * StringSubComponent.cxx, StringSubComponent.hxx, SubComponent.cxx, + SubComponent.hxx, SubComponentList.cxx, SubComponentList.hxx, + UnknownSubComponent.cxx, UnknownSubComponent.hxx, Makefile: [no log + message] + +2002-09-20 21:23 dabryan + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx, + HeaderFieldValueList.cxx, SubComponentList.cxx: Updates to allow + printing of the underlying data structures. + + Cleaned up the HeaderFieldValue(List) classes to use sub + components. + +2002-09-20 19:48 dabryan + + * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx: Added the + list of headers + +2002-09-20 19:24 jason + + * Parameter.cxx, Parameter.hxx, ParameterList.cxx, + ParameterList.hxx, StringParameter.cxx, StringParameter.hxx, + UnknownParameter.cxx, UnknownParameter.hxx, testParameterList.cxx, + StringSubComponent.cxx, StringSubComponent.hxx, SubComponent.cxx, + SubComponent.hxx, SubComponentList.cxx, SubComponentList.hxx, + UnknownSubComponent.cxx, UnknownSubComponent.hxx, + testSubComponentList.cxx: [no log message] + +2002-09-20 18:13 fluffy + + * Makefile: updated + +2002-09-20 17:57 dabryan + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx: Added code to have + list of Header Field Values to, code to chunk on copy. + +2002-09-20 17:56 jason + + * Makefile, Parameter.cxx, Parameter.hxx, ParameterList.cxx, + ParameterList.hxx, StringParameter.cxx, StringParameter.hxx, + UnknownParameter.cxx, UnknownParameter.hxx, testParameterList.cxx: + [no log message] + +2002-09-20 16:52 jason + + * Parameter.hxx, ParameterList.cxx, ParameterList.hxx, + StringParameter.cxx, StringParameter.hxx, UnknownParameter.cxx, + UnknownParameter.hxx, testParameterList.cxx: [no log message] + +2002-09-20 16:36 jason + + * HeaderFieldValue.cxx, HeaderFieldValue.hxx: [no log message] + +2002-09-20 16:16 fluffy + + * .cvsignore, Makefile, Parameter.cxx, testMsg.cxx: few things + +2002-09-20 15:57 fluffy + + * Makefile: [no log message] + diff --git a/src/libs/resiprocate/resip/stack/Compression.cxx b/src/libs/resiprocate/resip/stack/Compression.cxx new file mode 100644 index 00000000..d3c8a5ab --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Compression.cxx @@ -0,0 +1,130 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rutil/Logger.hxx" +#include "rutil/Random.hxx" +#include "resip/stack/Compression.hxx" + +#ifdef USE_SIGCOMP +#include <osc/StateHandler.h> +#include <osc/Stack.h> +#include <osc/DeflateCompressor.h> +#endif + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +resip::Compression resip::Compression::Disabled(resip::Compression::NONE); + +resip::Compression::Compression(resip::Compression::Algorithm algorithm, + int stateMemorySize, + int cyclesPerBit, + int decompressionMemorySize, + Data sigcompId) + : mAlgorithm(algorithm), mStateHandler(0), mSigcompId(sigcompId) +{ +#ifdef USE_SIGCOMP + if (algorithm != NONE) + { + mStateHandler = new osc::StateHandler(stateMemorySize, + cyclesPerBit, + decompressionMemorySize); + mStateHandler->useSipDictionary(); + + if (sigcompId == Data::Empty) + { + mSigcompId = "<"; + mSigcompId += Random::getVersion4UuidUrn(); + mSigcompId += ">"; + } + } + DebugLog (<< "Set SigcompId to " << mSigcompId); +#else + mAlgorithm = NONE; + DebugLog (<< "COMPRESSION SUPPORT NOT COMPILED IN"); +#endif + DebugLog (<< "Compression configuration object created; algorithm = " + << static_cast<int>(mAlgorithm) ); +} + +resip::Compression::~Compression() +{ +#ifdef USE_SIGCOMP + delete mStateHandler; +#endif +} + +void +resip::Compression::addCompressorsToStack(osc::Stack *stack) +{ +#ifdef USE_SIGCOMP + switch(getAlgorithm()) + { + case DEFLATE: + DebugLog (<< "Adding Deflate Compressor"); + stack->addCompressor(new osc::DeflateCompressor(getStateHandler())); + break; + + default: + WarningLog (<< "Invalid compressor specified! Using deflate Compressor"); + stack->addCompressor(new osc::DeflateCompressor(getStateHandler())); + + case NONE: + DebugLog (<< "Compression disabled: not adding any compressors"); + break; + + } +#else + DebugLog (<< "Compression not compiled in: not adding any compressors"); +#endif +} + +/* ==================================================================== +* The Vovida Software License, Version 1.0 +* +* Copyright (c) 2002-2005 Vovida Networks, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. The names "VOCAL", "Vovida Open Communication Application Library", +* and "Vovida Open Communication Application Library (VOCAL)" must +* not be used to endorse or promote products derived from this +* software without prior written permission. For written +* permission, please contact vocal@vovida.org. +* +* 4. Products derived from this software may not be called "VOCAL", nor +* may "VOCAL" appear in their name, without prior written +* permission of Vovida Networks, Inc. +* +* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +* +* ==================================================================== +* +* This software consists of voluntary contributions made by Vovida +* Networks, Inc. and many individuals on behalf of Vovida Networks, +* Inc. For more information on Vovida Networks, Inc., please see +* <http://www.vovida.org/>. +* +*/ diff --git a/src/libs/resiprocate/resip/stack/Compression.hxx b/src/libs/resiprocate/resip/stack/Compression.hxx new file mode 100644 index 00000000..241008e8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Compression.hxx @@ -0,0 +1,104 @@ +#if !defined(RESIP_COMPRESSION_HXX) +#define RESIP_COMPRESSION_HXX + +namespace osc +{ + class StateHandler; + class Stack; +} + +namespace resip +{ + +class Compression +{ + public: + typedef enum + { + NONE, + DEFLATE + } Algorithm; + + Compression(Algorithm algorithm = DEFLATE, + int stateMemorySize = 8192, + int cyclesPerBit = 64, + int decompressionMemorySize = 8192, + Data sigcompId = Data::Empty); + + ~Compression(); + + bool isEnabled() { return (mAlgorithm != NONE); } + Algorithm getAlgorithm() const { return mAlgorithm; } + osc::StateHandler &getStateHandler(){ return *mStateHandler; } + + void addCompressorsToStack(osc::Stack *); + + const Data &getSigcompId() {return mSigcompId;} + + /// Represents a compression configuration object with + /// compression disabled + static Compression Disabled; + + private: + Algorithm mAlgorithm; + osc::StateHandler *mStateHandler; + + // This is the unique compartment identifier for this + // client or server (or cluster of servers with shared state). + // See draft-ietf-rohc-sigcomp-sip + Data mSigcompId; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Connection.cxx b/src/libs/resiprocate/resip/stack/Connection.cxx new file mode 100644 index 00000000..344fc090 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Connection.cxx @@ -0,0 +1,443 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "rutil/Socket.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/Connection.hxx" +#include "resip/stack/ConnectionManager.hxx" +#include "resip/stack/InteropHelper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/TcpBaseTransport.hxx" +#include "rutil/WinLeakCheck.hxx" + +#ifdef USE_SSL +#include "resip/stack/ssl/Security.hxx" +#endif + +#ifdef USE_SIGCOMP +#include <osc/Stack.h> +#include <osc/SigcompMessage.h> +#endif + +using namespace resip; + +volatile bool Connection::mEnablePostConnectSocketFuncCall = false; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +Connection::Connection(Transport* transport,const Tuple& who, Socket socket, + Compression &compression) + : ConnectionBase(transport,who,compression), + mRequestPostConnectSocketFuncCall(false), + mInWritable(false), + mFlowTimerEnabled(false), + mPollItemHandle(0) +{ + mWho.mFlowKey=(FlowKey)socket; + InfoLog (<< "Connection::Connection: new connection created to who: " << mWho); + + if(mWho.mFlowKey && ConnectionBase::transport()) + { + getConnectionManager().addConnection(this); + } +} + +Connection::~Connection() +{ + if(mWho.mFlowKey && ConnectionBase::transport()) + { + getConnectionManager().removeConnection(this); + // remove first then close, since conn manager may need socket + closeSocket(mWho.mFlowKey); + } +} + +void +Connection::requestWrite(SendData* sendData) +{ + mOutstandingSends.push_back(sendData); + if (isWritable()) + { + ensureWritable(); + } +} + +void +Connection::removeFrontOutstandingSend() +{ + delete mOutstandingSends.front(); + mOutstandingSends.pop_front(); + + if (mOutstandingSends.empty()) + { + assert(mInWritable); + getConnectionManager().removeFromWritable(this); + mInWritable = false; + } +} + +int +Connection::performWrite() +{ + if(transportWrite()) + { + assert(mInWritable); + getConnectionManager().removeFromWritable(this); + mInWritable = false; + return 0; // What does this transportWrite() mean? + } + + assert(!mOutstandingSends.empty()); + switch(mOutstandingSends.front()->command) + { + case SendData::CloseConnection: + // .bwc. Close this connection. + return -1; + break; + case SendData::EnableFlowTimer: + enableFlowTimer(); + removeFrontOutstandingSend(); + return 0; + break; + default: + // do nothing + break; + } + + const Data& sigcompId = mOutstandingSends.front()->sigcompId; + + if(mSendingTransmissionFormat == Unknown) + { + if (sigcompId.size() > 0 && mCompression.isEnabled()) + { + mSendingTransmissionFormat = Compressed; + } + else + { + mSendingTransmissionFormat = Uncompressed; + } + } + + +#ifdef USE_SIGCOMP + // Perform compression here, if appropriate + if (mSendingTransmissionFormat == Compressed + && !(mOutstandingSends.front()->isAlreadyCompressed)) + { + const Data& uncompressed = mOutstandingSends.front()->data; + osc::SigcompMessage *sm = + mSigcompStack->compressMessage(uncompressed.data(), uncompressed.size(), + sigcompId.data(), sigcompId.size(), + true); + DebugLog (<< "Compressed message from " + << uncompressed.size() << " bytes to " + << sm->getStreamLength() << " bytes"); + + SendData *oldSd = mOutstandingSends.front(); + SendData *newSd = new SendData(oldSd->destination, + Data(sm->getStreamMessage(), + sm->getStreamLength()), + oldSd->transactionId, + oldSd->sigcompId, + true); + mOutstandingSends.front() = newSd; + delete oldSd; + delete sm; + } +#endif + + if(mEnablePostConnectSocketFuncCall && mRequestPostConnectSocketFuncCall) + { + // Note: The first time the socket is available for write, is when the TCP connect call is completed + mRequestPostConnectSocketFuncCall = false; + mTransport->callSocketFunc(getSocket()); + } + + const Data& data = mOutstandingSends.front()->data; + + int nBytes = write(data.data() + mSendPos,int(data.size() - mSendPos)); + + //DebugLog (<< "Tried to send " << data.size() - mSendPos << " bytes, sent " << nBytes << " bytes"); + + if (nBytes < 0) + { + //fail(data.transactionId); + InfoLog(<< "Write failed on socket: " << this->getSocket() << ", closing connection"); + return -1; + } + else if (nBytes == 0) + { + return 0; + } + else + { + // Safe because of the conditional above ( < 0 ). + Data::size_type bytesWritten = static_cast<Data::size_type>(nBytes); + mSendPos += bytesWritten; + if (mSendPos == data.size()) + { + mSendPos = 0; + removeFrontOutstandingSend(); + } + return bytesWritten; + } +} + + +bool +Connection::performWrites(unsigned int max) +{ + int res; + // if max==0, we will overflow into UINT_MAX. This is intentional. + while((res=performWrite())>0 && !mOutstandingSends.empty() && --max!=0) + {;} + + if(res<0) + { + if (mTransport) + mTransport->increaseConnectionsDeleted(); + delete this; + return false; + } + return true; +} + +void +Connection::ensureWritable() +{ + if(!mInWritable) + { + assert(!mOutstandingSends.empty()); + getConnectionManager().addToWritable(this); + mInWritable = true; + } +} + +ConnectionManager& +Connection::getConnectionManager() const +{ + TcpBaseTransport* transport = static_cast<TcpBaseTransport*>(ConnectionBase::transport()); + + return transport->getConnectionManager(); +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const resip::Connection& c) +{ + strm << "CONN: " << &c << " " << int(c.getSocket()) << " " << c.mWho; + return strm; +} + +int +Connection::read() +{ + std::pair<char*, size_t> writePair = getWriteBuffer(); + size_t bytesToRead = resipMin(writePair.second, + static_cast<size_t>(Connection::ChunkSize)); + + assert(bytesToRead > 0); + + int bytesRead = read(writePair.first, (int)bytesToRead); + if (bytesRead <= 0) + { + return bytesRead; + } + // mBuffer might have been reallocated inside read() + writePair = getCurrentWriteBuffer(); + + getConnectionManager().touch(this); + +#ifdef USE_SIGCOMP + // If this is the first data we read, determine whether the + // connection is compressed. + if(mReceivingTransmissionFormat == Unknown) + { + if (((writePair.first[0] & 0xf8) == 0xf8) && mCompression.isEnabled()) + { + mReceivingTransmissionFormat = Compressed; + } + else + { + mReceivingTransmissionFormat = Uncompressed; + } + } + + // SigComp compressed messages are handed very differently + // than non-compressed messages: they are guaranteed to + // be framed within SigComp, and each frame contains + // *exactly* one SIP message. Processing looks a lot like + // it does for Datagram-oriented transports. + + if (mReceivingTransmissionFormat == Compressed) + { + decompressNewBytes(bytesRead); + } + else +#endif + { + if(!preparseNewBytes(bytesRead)) + { + // Iffy; only way we have right now to indicate that this connection has + // gone away. + bytesRead=-1; + } + } + return bytesRead; +} + +bool +Connection::performReads(unsigned int max) +{ + int bytesRead; + + // if max==0, we will overflow into UINT_MAX. This is intentional. + while((bytesRead = read())>0 && --max!=0) + { + DebugLog(<< "Connection::performReads() " << " read=" << bytesRead); + } + + if ( bytesRead < 0 ) + { + DebugLog(<< "Closing connection bytesRead=" << bytesRead); + if (mTransport) + mTransport->increaseConnectionsDeleted(); + delete this; + return false; + } + return true; +} + +void +Connection::enableFlowTimer() +{ + if(!mFlowTimerEnabled) + { + mFlowTimerEnabled = true; + + // ensure connection is in a FlowTimer LRU list on the connection manager + getConnectionManager().moveToFlowTimerLru(this); + } +} + +void +Connection::onDoubleCRLF() +{ + // !bwc! TODO might need to make this more efficient. + // !bwc! Need to make this sigcomp-friendly + if(InteropHelper::getOutboundVersion()>=8) + { + DebugLog(<<"Sending response CRLF (aka pong)."); + requestWrite(new SendData(mWho,Symbols::CRLF,Data::Empty,Data::Empty)); + } +} + +void +Connection::onSingleCRLF() +{ + DebugLog(<<"Received response CRLF (aka pong)."); + mTransport->keepAlivePong(mWho); +} + +bool +Connection::hasDataToRead() +{ + return true; +} + +bool +Connection::isGood() +{ + return true; +} + +bool +Connection::isWritable() +{ + return true; +} + +/** + Virtual function of FdPollItemIf, called to process io events +**/ +void +Connection::processPollEvent(FdPollEventMask mask) { + /* The original code in ConnectionManager.cxx didn't check + * for error events unless no writable event. (e.g., writable + * masked error. Why?) + */ + if ( mask & FPEM_Error ) + { + Socket fd = getSocket(); + int errNum = getSocketError(fd); + InfoLog(<< "Exception on socket " << fd << " code: " << errNum << "; closing connection"); + setFailureReason(TransportFailure::ConnectionException, errNum); + if (mTransport) + mTransport->increaseConnectionsDeleted(); + delete this; + return; + } + if ( mask & FPEM_Write ) + { + if(!performWrites()) + { + // Just deleted self + return; + } + } + if ( mask & FPEM_Read ) + { + performReads(); + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/Connection.hxx b/src/libs/resiprocate/resip/stack/Connection.hxx new file mode 100644 index 00000000..d8c7fc2c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Connection.hxx @@ -0,0 +1,186 @@ +#ifndef RESIP_Connection_hxx +#define RESIP_Connection_hxx + +#include <list> + +#include "resip/stack/ConnectionBase.hxx" +//#include "rutil/Fifo.hxx" +#include "rutil/Socket.hxx" +#include "rutil/FdPoll.hxx" +#include "rutil/Timer.hxx" +#include "resip/stack/Transport.hxx" +#include "resip/stack/MsgHeaderScanner.hxx" +#include "rutil/IntrusiveListElement.hxx" + +namespace resip +{ + +class Message; +class TlsConnection; +class ConnectionManager; +class Connection; +class Compression; + +/// three intrusive list types for in-place reference +typedef IntrusiveListElement<Connection*> ConnectionLruList; +typedef IntrusiveListElement1<Connection*> ConnectionReadList; +typedef IntrusiveListElement2<Connection*> ConnectionWriteList; +typedef IntrusiveListElement3<Connection*> FlowTimerLruList; + +/** Connection implements, via sockets, ConnectionBase for managed + connections. Connections are managed for approximate fairness and least + recently used garbage collection. + Connection inherits three different instantiations of intrusive lists. +*/ +class Connection : public ConnectionBase, + public ConnectionLruList, + public ConnectionReadList, + public ConnectionWriteList, + public FlowTimerLruList, + public FdPollItemIf +{ + friend class ConnectionManager; + friend EncodeStream& operator<<(EncodeStream& strm, const resip::Connection& c); + + public: + Connection(Transport* transport,const Tuple& who, Socket socket, Compression &compression); + virtual ~Connection(); + + /*! + @note Right now, Connection is assumed to be a TCP connection. + This means that there is a 1-1 correspondence between + FD and Connection. If this changes down the line (say, if + we use this class to do SCTP connections), we can just remove + this function. + */ + Socket getSocket() const {return mWho.mFlowKey;} + + /// always true -- always add to fdset as read ready + virtual bool hasDataToRead(); + /// has valid connection + virtual bool isGood(); + virtual bool isWritable(); + virtual bool transportWrite(){return false;} + + /// queue data to write and add this to writable list + void requestWrite(SendData* sendData); + + /// send some or all of a queued data; remove from writable if completely written + int performWrite(); + + /** Call performWrite() repeatedly, until either the send queue is + exhausted, the write() call fails (probably because the fd is no + longer ready to write), or a set number of writes has been + performed. + @param max The maximum number of writes to perform. 0 indicates that + there is no limit. + @return false iff this connection has deleted itself. + */ + bool performWrites(unsigned int max=0); + + /// ensure that we are on the writeable list if required + void ensureWritable(); + + /** move data from the connection to the buffer; move this to front of + least recently used list. when the message is complete, + it is delivered via mTransport->pushRxMsgUp() + which generally puts it on a fifo */ + int read(); + + /** Call read() repeatedly, until an error occurs (because the fd is not + ready to read, most likely). + @param max The maximum number of reads to perform. 0 indicates that + there is no limit. + @return false iff this connection has deleted itself. + */ + bool performReads(unsigned int max=0); + + /// Ensures this connection is in the FlowTimer LRU list in the connection manager + void enableFlowTimer(); + bool isFlowTimerEnabled() { return mFlowTimerEnabled; } + + bool mRequestPostConnectSocketFuncCall; + static volatile bool mEnablePostConnectSocketFuncCall; + static void setEnablePostConnectSocketFuncCall(bool enabled = true) { mEnablePostConnectSocketFuncCall = enabled; } + + protected: + /// pure virtual, but need concrete Connection for book-ends of lists + virtual int read(char* /* buffer */, const int /* count */) { return 0; } + /// pure virtual, but need concrete Connection for book-ends of lists + virtual int write(const char* /* buffer */, const int /* count */) { return 0; } + virtual void onDoubleCRLF(); + virtual void onSingleCRLF(); + + /* callback method of FdPollItemIf */ + virtual void processPollEvent(FdPollEventMask mask); + + private: + ConnectionManager& getConnectionManager() const; + void removeFrontOutstandingSend(); + bool mInWritable; + bool mFlowTimerEnabled; + FdPollItemHandle mPollItemHandle; + + /// no default c'tor + Connection(); + + /// no value semantics + Connection(const Connection&); + Connection& operator=(const Connection&); +}; + +EncodeStream& +operator<<(EncodeStream& strm, const resip::Connection& c); + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ConnectionBase.cxx b/src/libs/resiprocate/resip/stack/ConnectionBase.cxx new file mode 100644 index 00000000..2ec53241 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ConnectionBase.cxx @@ -0,0 +1,793 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "rutil/Logger.hxx" +#include "resip/stack/ConnectionBase.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/WinLeakCheck.hxx" + +#ifdef USE_SSL +#include "resip/stack/ssl/Security.hxx" +#include "resip/stack/ssl/TlsConnection.hxx" +#endif + +#ifdef USE_SIGCOMP +#include <osc/Stack.h> +#include <osc/TcpStream.h> +#include <osc/SigcompMessage.h> +#include <osc/StateChanges.h> +#endif + +#include <sstream> +#include "resip/stack/InternalTransport.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +char +ConnectionBase::connectionStates[ConnectionBase::MAX][32] = { "NewMessage", "ReadingHeaders", "PartialBody" }; + + +ConnectionBase::ConnectionBase(Transport* transport, const Tuple& who, Compression &compression) + : mSendPos(0), + mTransport(transport), + mWho(who), + mFailureReason(TransportFailure::None), + mFailureSubCode(0), + mCompression(compression), +// NO: #ifdef USE_SIGCOMP // class def doesn't decl members conditionally + mSigcompStack(0), + mSigcompFramer(0), +// NO: #endif + mSendingTransmissionFormat(Unknown), + mReceivingTransmissionFormat(Unknown), + mMessage(0), + mBuffer(0), + mBufferPos(0), + mBufferSize(0), + mLastUsed(Timer::getTimeMs()), + mConnState(NewMessage), + mTransportLogger(NULL) +{ + DebugLog (<< "ConnectionBase::ConnectionBase, who: " << mWho << " " << this); +#ifdef USE_SIGCOMP + if (mCompression.isEnabled()) + { + DebugLog (<< "Compression enabled for connection: " << this); + mSigcompStack = new osc::Stack(mCompression.getStateHandler()); + mCompression.addCompressorsToStack(mSigcompStack); + } + else + { + DebugLog (<< "Compression disabled for connection: " << this); + } +#else + DebugLog (<< "No compression library available: " << this); +#endif + + // deprecated; stop doing this eventually + mWho.transport=mTransport; + mWho.transportKey=mTransport ? mTransport->getKey() : 0; +} + +ConnectionBase::~ConnectionBase() +{ + if(mTransport) + { + mTransport->flowTerminated(mWho); + } + + while (!mOutstandingSends.empty()) + { + SendData* sendData = mOutstandingSends.front(); + mTransport->fail(sendData->transactionId, + mFailureReason ? mFailureReason : TransportFailure::ConnectionUnknown, + mFailureSubCode); + delete sendData; + mOutstandingSends.pop_front(); + } + delete [] mBuffer; + delete mMessage; +#ifdef USE_SIGCOMP + delete mSigcompStack; +#endif + + DebugLog (<< "ConnectionBase::~ConnectionBase " << this); +} + +void +ConnectionBase::setFailureReason(TransportFailure::FailureReason failReason, int subCode) +{ + if ( failReason > mFailureReason ) + { + mFailureReason = failReason; + mFailureSubCode = subCode; + } +} + +FlowKey +ConnectionBase::getFlowKey() const +{ + return mWho.mFlowKey; +} + +bool +ConnectionBase::preparseNewBytes(int bytesRead) +{ + DebugLog(<< "In State: " << connectionStates[mConnState]); + + start: // If there is an overhang come back here, effectively recursing + + switch(mConnState) + { + case NewMessage: + { + if (strncmp(mBuffer + mBufferPos, Symbols::CRLFCRLF, 4) == 0) + { + DebugLog(<< "Got incoming double-CRLF keepalive (aka ping)."); + mBufferPos += 4; + bytesRead -= 4; + onDoubleCRLF(); + if (bytesRead) + { + goto start; + } + else + { + delete [] mBuffer; + mBuffer = 0; + return true; + } + } + else if (strncmp(mBuffer + mBufferPos, Symbols::CRLF, 2) == 0) + { + //DebugLog(<< "Got incoming CRLF keepalive response (aka pong)."); + mBufferPos += 2; + bytesRead -= 2; + onSingleCRLF(); + if (bytesRead) + { + goto start; + } + else + { + delete [] mBuffer; + mBuffer = 0; + return true; + } + } + + assert(mTransport); + mMessage = new SipMessage(mTransport); + + DebugLog(<< "ConnectionBase::process setting source " << mWho); + mMessage->setSource(mWho); + mMessage->setTlsDomain(mTransport->tlsDomain()); + +#ifdef USE_SSL + // Set TlsPeerName if message is from TlsConnection + TlsConnection *tlsConnection = dynamic_cast<TlsConnection *>(this); + if(tlsConnection) + { + std::list<Data> peerNameList; + tlsConnection->getPeerNames(peerNameList); + mMessage->setTlsPeerNames(peerNameList); + } +#endif + mMsgHeaderScanner.prepareForMessage(mMessage); + // Fall through to the next case. + } + case ReadingHeaders: + { + unsigned int chunkLength = (unsigned int)mBufferPos + bytesRead; + char *unprocessedCharPtr; + MsgHeaderScanner::ScanChunkResult scanChunkResult = + mMsgHeaderScanner.scanChunk(mBuffer, + chunkLength, + &unprocessedCharPtr); + if (scanChunkResult == MsgHeaderScanner::scrError) + { + //.jacob. Not a terribly informative warning. + WarningLog(<< "Discarding preparse!"); + delete [] mBuffer; + mBuffer = 0; + delete mMessage; + mMessage = 0; + mConnState=NewMessage; + return false; + } + + if (mMsgHeaderScanner.getHeaderCount() > 256) + { + WarningLog(<< "Discarding preparse; too many headers"); + delete [] mBuffer; + mBuffer = 0; + delete mMessage; + mMessage = 0; + mConnState=NewMessage; + return false; + } + + unsigned int numUnprocessedChars = + (unsigned int)((mBuffer + chunkLength) - unprocessedCharPtr); + + if(numUnprocessedChars > 2048 && + scanChunkResult == MsgHeaderScanner::scrNextChunk) + { + WarningLog(<< "Discarding preparse; header-field-value (or " + "header name) too long"); + delete [] mBuffer; + mBuffer = 0; + delete mMessage; + mMessage = 0; + mConnState=NewMessage; + return false; + } + + if(numUnprocessedChars==chunkLength) + { + // .bwc. MsgHeaderScanner wasn't able to parse anything useful; + // don't bother mMessage yet, but make more room in mBuffer. + size_t size = numUnprocessedChars*3/2; + if (size < ConnectionBase::ChunkSize) + { + size = ConnectionBase::ChunkSize; + } + char* newBuffer = 0; + try + { + newBuffer=MsgHeaderScanner::allocateBuffer((int)size); + } + catch(std::bad_alloc&) + { + ErrLog(<<"Failed to alloc a buffer during preparse!"); + return false; + } + memcpy(newBuffer, unprocessedCharPtr, numUnprocessedChars); + delete [] mBuffer; + mBuffer = newBuffer; + mBufferPos = numUnprocessedChars; + mBufferSize = size; + mConnState = ReadingHeaders; + return true; + } + + mMessage->addBuffer(mBuffer); + mBuffer=0; + + if (scanChunkResult == MsgHeaderScanner::scrNextChunk) + { + // Message header is incomplete... + if (numUnprocessedChars == 0) + { + // ...but the chunk is completely processed. + //.jacob. I've discarded the "assigned" concept. + //DebugLog(<< "Data assigned, not fragmented, not complete"); + try + { + mBuffer = MsgHeaderScanner::allocateBuffer(ChunkSize); + } + catch(std::bad_alloc&) + { + ErrLog(<<"Failed to alloc a buffer during preparse!"); + return false; + } + mBufferPos = 0; + mBufferSize = ChunkSize; + } + else + { + // ...but some of the chunk must be shifted into the next one. + size_t size = numUnprocessedChars*3/2; + if (size < ConnectionBase::ChunkSize) + { + size = ConnectionBase::ChunkSize; + } + char* newBuffer = 0; + try + { + newBuffer = MsgHeaderScanner::allocateBuffer((int)size); + } + catch(std::bad_alloc&) + { + ErrLog(<<"Failed to alloc a buffer during preparse!"); + return false; + } + memcpy(newBuffer, unprocessedCharPtr, numUnprocessedChars); + mBuffer = newBuffer; + mBufferPos = numUnprocessedChars; + mBufferSize = size; + } + mConnState = ReadingHeaders; + } + else + { + size_t contentLength = 0; + + try + { + // The message header is complete. + contentLength=mMessage->const_header(h_ContentLength).value(); + } + catch(resip::BaseException& e) // Could be SipMessage::Exception or ParseException + { + WarningLog(<<"Malformed Content-Length in connection-based transport" + ". Not much we can do to fix this. " << e); + // .bwc. Bad Content-Length. We are hosed. + delete mMessage; + mMessage = 0; + mBuffer = 0; + // .bwc. mMessage just took ownership of mBuffer, so we don't + // delete it here. We do zero it though, for completeness. + //.jacob. Shouldn't the state also be set here? + return false; + } + + if(contentLength > 10485760 || contentLength < 0) + { + // !bwc! No more than 10M, thanks. We should make this + // configurable. + WarningLog(<<"Absurdly large Content-Length in connection-based " + "transport."); + delete mMessage; + mMessage = 0; + mBuffer = 0; + // .bwc. mMessage just took ownership of mBuffer, so we don't + // delete it here. We do zero it though, for completeness. + //.jacob. Shouldn't the state also be set here? + return false; + } + + if (numUnprocessedChars < contentLength) + { + // The message body is incomplete. + DebugLog(<< "partial body received"); + size_t newSize=resipMin(resipMax((size_t)numUnprocessedChars*3/2, + (size_t)ConnectionBase::ChunkSize), + contentLength); + char* newBuffer = MsgHeaderScanner::allocateBuffer((int)newSize); + memcpy(newBuffer, unprocessedCharPtr, numUnprocessedChars); + mBufferPos = numUnprocessedChars; + mBufferSize = newSize; + mBuffer = newBuffer; + + mConnState = PartialBody; + } + else + { + // Do this stuff BEFORE we kick the message out the door. + // Remember, deleting or passing mMessage on invalidates our + // buffer! + int overHang = numUnprocessedChars - (int)contentLength; + + mConnState = NewMessage; + mBuffer = 0; + if (overHang > 0) + { + // The next message has been partially read. + size_t size = overHang*3/2; + if (size < ConnectionBase::ChunkSize) + { + size = ConnectionBase::ChunkSize; + } + char* newBuffer = MsgHeaderScanner::allocateBuffer((int)size); + memcpy(newBuffer, + unprocessedCharPtr + contentLength, + overHang); + mBuffer = newBuffer; + mBufferPos = 0; + mBufferSize = size; + + DebugLog (<< "Extra bytes after message: " << overHang); + DebugLog (<< Data(mBuffer, overHang)); + + bytesRead = overHang; + } + + // The message body is complete. + mMessage->setBody(unprocessedCharPtr, (UInt32)contentLength); + CongestionManager::RejectionBehavior b=mTransport->getRejectionBehaviorForIncoming(); + if (b==CongestionManager::REJECTING_NON_ESSENTIAL + || (b==CongestionManager::REJECTING_NEW_WORK + && mMessage->isRequest())) + { + UInt32 expectedWait(mTransport->getExpectedWaitForIncoming()); + // .bwc. If this fifo is REJECTING_NEW_WORK, we will drop + // requests but not responses ( ?bwc? is this right for ACK?). + // If we are REJECTING_NON_ESSENTIAL, + // we reject all incoming work, since losing something from the + // wire will not cause instability or leaks (see + // CongestionManager.hxx) + + // .bwc. This handles all appropriate checking for whether + // this is a response or an ACK. + std::auto_ptr<SendData> tryLater(transport()->make503(*mMessage, expectedWait/1000)); + if(tryLater.get()) + { + transport()->send(tryLater); + } + delete mMessage; // dropping message due to congestion + mMessage = 0; + } + else if (!transport()->basicCheck(*mMessage)) + { + delete mMessage; + mMessage = 0; + } + else + { + Transport::stampReceived(mMessage); + DebugLog(<< "##Connection: " << *this << " received: " << *mMessage); + assert( mTransport ); + putMessageToTransportLogger(mMessage); + mTransport->pushRxMsgUp(mMessage); + mMessage = 0; + } + + if (overHang > 0) + { + goto start; + } + } + } + break; + } + case PartialBody: + { + size_t contentLength = 0; + + try + { + contentLength = mMessage->const_header(h_ContentLength).value(); + } + catch(resip::BaseException& e) // Could be SipMessage::Exception or ParseException + { + WarningLog(<<"Malformed Content-Length in connection-based transport" + ". Not much we can do to fix this. " << e); + // .bwc. Bad Content-Length. We are hosed. + delete [] mBuffer; + mBuffer = 0; + delete mMessage; + mMessage = 0; + //.jacob. Shouldn't the state also be set here? + return false; + } + + mBufferPos += bytesRead; + if (mBufferPos == contentLength) + { + mMessage->addBuffer(mBuffer); + mMessage->setBody(mBuffer, (UInt32)contentLength); + mBuffer=0; + // .bwc. basicCheck takes up substantial CPU. Don't bother doing it + // if we're overloaded. + CongestionManager::RejectionBehavior b=mTransport->getRejectionBehaviorForIncoming(); + if (b==CongestionManager::REJECTING_NON_ESSENTIAL + || (b==CongestionManager::REJECTING_NEW_WORK + && mMessage->isRequest())) + { + UInt32 expectedWait(mTransport->getExpectedWaitForIncoming()); + // .bwc. If this fifo is REJECTING_NEW_WORK, we will drop + // requests but not responses ( ?bwc? is this right for ACK?). + // If we are REJECTING_NON_ESSENTIAL, + // we reject all incoming work, since losing something from the + // wire will not cause instability or leaks (see + // CongestionManager.hxx) + + // .bwc. This handles all appropriate checking for whether + // this is a response or an ACK. + std::auto_ptr<SendData> tryLater = transport()->make503(*mMessage, expectedWait/1000); + if(tryLater.get()) + { + transport()->send(tryLater); + } + delete mMessage; // dropping message due to congestion + mMessage = 0; + } + else if (!transport()->basicCheck(*mMessage)) + { + delete mMessage; + mMessage = 0; + } + else + { + DebugLog(<< "##ConnectionBase: " << *this << " received: " << *mMessage); + + Transport::stampReceived(mMessage); + assert( mTransport ); + putMessageToTransportLogger(mMessage); + mTransport->pushRxMsgUp(mMessage); + mMessage = 0; + } + mConnState = NewMessage; + } + else if (mBufferPos == mBufferSize) + { + // .bwc. We've filled our buffer; go ahead and make more room. + size_t newSize = resipMin(mBufferSize*3/2, contentLength); + char* newBuffer = 0; + try + { + newBuffer=new char[newSize]; + } + catch(std::bad_alloc&) + { + ErrLog(<<"Failed to alloc a buffer while receiving body!"); + return false; + } + memcpy(newBuffer, mBuffer, mBufferSize); + mBufferSize=newSize; + delete [] mBuffer; + mBuffer = newBuffer; + } + break; + } + default: + assert(0); + } + return true; +} + +#ifdef USE_SIGCOMP +void +ConnectionBase::decompressNewBytes(int bytesRead) +{ + mConnState = SigComp; + + if (!mSigcompFramer) + { + mSigcompFramer = new osc::TcpStream(); + } + + mSigcompFramer->addData(mBuffer, bytesRead); + size_t bytesUncompressed; + osc::StateChanges *sc = 0; + char *uncompressed = new char[65536]; + while ((bytesUncompressed = mSigcompStack->uncompressMessage( + *mSigcompFramer, uncompressed, 65536, sc)) > 0) + { + DebugLog (<< "Uncompressed Connection-oriented message"); + mMessage = new SipMessage(mWho.transport); + + mMessage->setSource(mWho); + mMessage->setTlsDomain(mWho.transport->tlsDomain()); + + char *sipBuffer = new char[bytesUncompressed]; + memmove(sipBuffer, uncompressed, bytesUncompressed); + mMessage->addBuffer(sipBuffer); + mMsgHeaderScanner.prepareForMessage(mMessage); + char *unprocessedCharPtr; + if (mMsgHeaderScanner.scanChunk(sipBuffer, + bytesUncompressed, + &unprocessedCharPtr) != + MsgHeaderScanner::scrEnd) + { + StackLog(<<"Scanner rejecting compressed message as unparsable"); + StackLog(<< Data(sipBuffer, bytesUncompressed)); + delete mMessage; + mMessage=0; + } + + unsigned int used = unprocessedCharPtr - sipBuffer; + if (mMessage && (used < bytesUncompressed)) + { + mMessage->setBody(sipBuffer+used, bytesUncompressed-used); + } + + if (mMessage && !transport()->basicCheck(*mMessage)) + { + delete mMessage; + mMessage = 0; + } + + if (mMessage) + { + Transport::stampReceived(mMessage); + // If the message made it this far, we should let it store + // SigComp state: extract the compartment ID. + const Via &via = mMessage->const_header(h_Vias).front(); + if (mMessage->isRequest()) + { + // For requests, the compartment ID is read out of the + // top via header field; if not present, we use the + // TCP connection for identification purposes. + if (via.exists(p_sigcompId)) + { + Data compId = via.param(p_sigcompId); + if(!compId.empty()) + { + mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size()); + } + } + else + { + mSigcompStack->provideCompartmentId(sc, this, sizeof(this)); + } + } + else + { + // For responses, the compartment ID is supposed to be + // the same as the compartment ID of the request. We + // *could* dig down into the transaction layer to try to + // figure this out, but that's a royal pain, and a rather + // severe layer violation. In practice, we're going to ferret + // the ID out of the the Via header field, which is where we + // squirreled it away when we sent this request in the first place. + Data compId = via.param(p_branch).getSigcompCompartment(); + if(!compId.empty()) + { + mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size()); + } + } + assert( mTransport ); + mTransport->pushRxMsgUp(mMessage); + mMessage = 0; + sc = 0; + } + else + { + delete sc; + sc = 0; + } + } + delete uncompressed; + + // If there was a decompression failure, let the other side know. + osc::SigcompMessage *nack = mSigcompStack->getNack(); + if (nack) + { + if (mSendingTransmissionFormat == Compressed) + { + // !bwc! We are not telling anyone that we're interested in having our + // FD put in the writable set... + mOutstandingSends.push_back(new SendData( + who(), + Data(nack->getStreamMessage(), nack->getStreamLength()), + Data::Empty, + Data::Empty, + true)); + } + else + { + delete nack; + } + } +} +#endif + +std::pair<char*, size_t> +ConnectionBase::getWriteBuffer() +{ + if (mConnState == NewMessage) + { + if (!mBuffer) + { + DebugLog (<< "Creating buffer for " << *this); + + mBuffer = MsgHeaderScanner::allocateBuffer(ConnectionBase::ChunkSize); + mBufferSize = ConnectionBase::ChunkSize; + } + mBufferPos = 0; + } + return getCurrentWriteBuffer(); +} + +std::pair<char*, size_t> +ConnectionBase::getCurrentWriteBuffer() +{ + return std::make_pair(mBuffer + mBufferPos, mBufferSize - mBufferPos); +} + +char* +ConnectionBase::getWriteBufferForExtraBytes(int extraBytes) +{ + if (extraBytes > 0) + { + char* buffer = MsgHeaderScanner::allocateBuffer((int)mBufferSize + extraBytes); + memcpy(buffer, mBuffer, mBufferSize); + delete [] mBuffer; + mBuffer = buffer; + buffer += mBufferSize; + mBufferSize += extraBytes; + return buffer; + } + else + { + assert(0); + return mBuffer; + } +} + +void +ConnectionBase::setBuffer(char* bytes, int count) +{ + mBuffer = bytes; + mBufferPos = 0; + mBufferSize = count; +} + +Transport* +ConnectionBase::transport() const +{ + assert(this); + return mTransport; +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, + const resip::ConnectionBase& c) + +{ + strm << "CONN_BASE: " << &c << " " << c.mWho; + return strm; +} + +void +ConnectionBase::setTransportLogger(InternalTransport::TransportLogger* logger) +{ + mTransportLogger = logger; +} + +void +ConnectionBase::putMessageToTransportLogger(SipMessage* msg) +{ + if (mTransportLogger) + { + std::ostringstream s; + s << *msg; + mTransportLogger->onSipMessage(InternalTransport::TransportLogger::Flow_Received, s.str().c_str(), s.str().length(), &msg->getSource().getSockaddr(), sizeof(sockaddr_in)); + } +} +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ + diff --git a/src/libs/resiprocate/resip/stack/ConnectionBase.hxx b/src/libs/resiprocate/resip/stack/ConnectionBase.hxx new file mode 100644 index 00000000..427e893d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ConnectionBase.hxx @@ -0,0 +1,175 @@ +#ifndef RESIP_ConnectionBase_hxx +#define RESIP_ConnectionBase_hxx + +#include <deque> +#include <list> + +#include "rutil/Timer.hxx" +// #include "rutil/Fifo.hxx" +#include "resip/stack/Transport.hxx" +#include "resip/stack/MsgHeaderScanner.hxx" +#include "resip/stack/SendData.hxx" +#include "resip/stack/InternalTransport.hxx" + +namespace osc +{ + class Stack; + class TcpStream; +} + +namespace resip +{ + +class TransactionMessage; +class Compression; + +/** + @internal + + @brief Abstracts some of the connection functionality. + + Managed connections (see ConnectionManager) derive from Connection. + Non-managed connections may be derived from ConnectionBase. + + @todo check id connectionId makes sense here +*/ +class ConnectionBase +{ + friend EncodeStream& operator<<(EncodeStream& strm, const resip::ConnectionBase& c); + public: + ConnectionBase(Transport* transport, + const Tuple& who, + Compression &compression = Compression::Disabled); + FlowKey getFlowKey() const; + + /// @todo should be reference + virtual Transport* transport() const; + + Tuple& who() { return mWho; } + const UInt64& whenLastUsed() { return mLastUsed; } + void resetLastUsed() { mLastUsed = Timer::getTimeMs(); } + void setTransportLogger(InternalTransport::TransportLogger* logger); + + enum { ChunkSize = 2048 }; // !jf! what is the optimal size here? + + protected: + enum ConnState + { + NewMessage = 0, + ReadingHeaders, + PartialBody, + SigComp, // This indicates that incoming bytes are compressed. + MAX + }; + + typedef enum + { + Unknown, + Uncompressed, + Compressed + } TransmissionFormat; + + ConnState getCurrentState() const { return mConnState; } + bool preparseNewBytes(int bytesRead); + void decompressNewBytes(int bytesRead); + std::pair<char*, size_t> getWriteBuffer(); + std::pair<char*, size_t> getCurrentWriteBuffer(); + char* getWriteBufferForExtraBytes(int extraBytes); + + // for avoiding copies in external transports--not used in core resip + void setBuffer(char* bytes, int count); + + Data::size_type mSendPos; + std::list<SendData*> mOutstandingSends; // !jacob! intrusive queue? + + void setFailureReason(TransportFailure::FailureReason failReason, int subCode); + + virtual ~ConnectionBase(); + // no value semantics + private: + ConnectionBase(); + ConnectionBase(const Connection&); + ConnectionBase& operator=(const Connection&); + protected: + virtual void onDoubleCRLF(){} + virtual void onSingleCRLF(){} + void putMessageToTransportLogger(SipMessage* msg); + + Transport* mTransport; + Tuple mWho; + TransportFailure::FailureReason mFailureReason; + int mFailureSubCode; + Compression &mCompression; + osc::Stack *mSigcompStack; + osc::TcpStream *mSigcompFramer; + TransmissionFormat mSendingTransmissionFormat; + TransmissionFormat mReceivingTransmissionFormat; + InternalTransport::TransportLogger* mTransportLogger; + + private: + SipMessage* mMessage; + char* mBuffer; + size_t mBufferPos; + size_t mBufferSize; + + static char connectionStates[MAX][32]; + UInt64 mLastUsed; + ConnState mConnState; + MsgHeaderScanner mMsgHeaderScanner; +}; + +EncodeStream& +operator<<(EncodeStream& strm, const resip::ConnectionBase& c); + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ConnectionManager.cxx b/src/libs/resiprocate/resip/stack/ConnectionManager.cxx new file mode 100644 index 00000000..3f97da54 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ConnectionManager.cxx @@ -0,0 +1,438 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/ConnectionManager.hxx" +#include "resip/stack/InteropHelper.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" + +#include <vector> + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +UInt64 ConnectionManager::MinimumGcAge = 1; // in milliseconds +bool ConnectionManager::EnableAgressiveGc = false; + +ConnectionManager::ConnectionManager() : + mHead(0,Tuple(),0,Compression::Disabled), + mWriteHead(ConnectionWriteList::makeList(&mHead)), + mReadHead(ConnectionReadList::makeList(&mHead)), + mLRUHead(ConnectionLruList::makeList(&mHead)), + mFlowTimerLRUHead(FlowTimerLruList::makeList(&mHead)), + mPollGrp(0) +{ + DebugLog(<<"ConnectionManager::ConnectionManager() called "); +} + +ConnectionManager::~ConnectionManager() +{ + closeConnections(); + assert(mReadHead->empty()); + assert(mWriteHead->empty()); + assert(mLRUHead->empty()); + assert(mFlowTimerLRUHead->empty()); +} + +void +ConnectionManager::closeConnections() +{ + while (!mAddrMap.empty()) + { + delete mAddrMap.begin()->second; + } +} + +Connection* +ConnectionManager::findConnection(const Tuple& addr) +{ + if (addr.mFlowKey != 0) + { + IdMap::iterator i = mIdMap.find(addr.mFlowKey); + if (i != mIdMap.end()) + { + if(i->second->who()==addr) + { + DebugLog(<<"Found fd " << addr.mFlowKey); + return i->second; + } + else + { + DebugLog(<<"fd " << addr.mFlowKey + << " exists, but does not match the destination. FD -> " + << i->second->who() << ", tuple -> " << addr); + } + } + else + { + DebugLog(<<"fd " << addr.mFlowKey << " does not exist."); + } + + if(addr.onlyUseExistingConnection) + { + return 0; + } + } + + AddrMap::iterator i = mAddrMap.find(addr); + if (i != mAddrMap.end()) + { + DebugLog(<<"Found connection for tuple "<< addr ); + return i->second; + } + + + DebugLog(<<"Could not find a connection for " << addr); + return 0; +} + +const Connection* +ConnectionManager::findConnection(const Tuple& addr) const +{ + if (addr.mFlowKey != 0) + { + IdMap::const_iterator i = mIdMap.find(addr.mFlowKey); + if (i != mIdMap.end()) + { + if(i->second->who()==addr) + { + DebugLog(<<"Found fd " << addr.mFlowKey); + return i->second; + } + else + { + DebugLog(<<"fd " << addr.mFlowKey + << " exists, but does not match the destination. FD -> " + << i->second->who() << ", tuple -> " << addr); + } + } + else + { + DebugLog(<<"fd " << addr.mFlowKey << " does not exist."); + } + } + + AddrMap::const_iterator i = mAddrMap.find(addr); + if (i != mAddrMap.end()) + { + DebugLog(<<"Found connection for tuple "<< addr ); + return i->second; + } + + + DebugLog(<<"Could not find a connection for " << addr); + return 0; +} + +void +ConnectionManager::buildFdSet(FdSet& fdset) +{ + // If using PollGrp, caller shouldn't call this + assert( mPollGrp==0 ); + + for (ConnectionReadList::iterator i = mReadHead->begin(); + i != mReadHead->end(); ++i) + { + fdset.setRead((*i)->getSocket()); + fdset.setExcept((*i)->getSocket()); + } + + for (ConnectionWriteList::iterator i = mWriteHead->begin(); + i != mWriteHead->end(); ++i) + { + fdset.setWrite((*i)->getSocket()); + fdset.setExcept((*i)->getSocket()); + } +} + +void +ConnectionManager::addToWritable(Connection* conn) +{ + if ( mPollGrp ) + { + mPollGrp->modPollItem(conn->mPollItemHandle, FPEM_Read|FPEM_Write|FPEM_Error); + } + else + { + mWriteHead->push_back(conn); + } +} + +void +ConnectionManager::removeFromWritable(Connection* conn) +{ + if ( mPollGrp ) + { + mPollGrp->modPollItem(conn->mPollItemHandle, FPEM_Read|FPEM_Error); + } + else + { + assert(!mWriteHead->empty()); + conn->ConnectionWriteList::remove(); + } +} + +void +ConnectionManager::addConnection(Connection* connection) +{ + assert(mAddrMap.find(connection->who())==mAddrMap.end()); + + //DebugLog (<< "ConnectionManager::addConnection() " << connection->mWho.mFlowKey << ":" << connection->mSocket); + + + mAddrMap[connection->who()] = connection; + mIdMap[connection->who().mFlowKey] = connection; + + if ( mPollGrp ) + { + connection->mPollItemHandle = mPollGrp->addPollItem( + connection->getSocket(), FPEM_Read|FPEM_Error, connection); + } + else + { + mReadHead->push_back(connection); + } + mLRUHead->push_back(connection); + + // Garbage collect old connections if agressive is enabled + if(EnableAgressiveGc) + { + gc(MinimumGcAge, 0); // cleanup all connections that haven't seen data in last x ms + } + + //DebugLog (<< "count=" << mAddrMap.count(connection->who()) << "who=" << connection->who() << " mAddrMap=" << Inserter(mAddrMap)); + //assert(mAddrMap.begin()->first == connection->who()); + assert(mAddrMap.count(connection->who()) == 1); +} + +void +ConnectionManager::removeConnection(Connection* connection) +{ + //DebugLog (<< "ConnectionManager::removeConnection()"); + + mIdMap.erase(connection->mWho.mFlowKey); + mAddrMap.erase(connection->mWho); + + if ( mPollGrp ) + { + mPollGrp->delPollItem(connection->mPollItemHandle); + } + else + { + assert(!mReadHead->empty()); + connection->ConnectionReadList::remove(); + connection->ConnectionWriteList::remove(); + if(connection->isFlowTimerEnabled()) + { + connection->FlowTimerLruList::remove(); + } + else + { + connection->ConnectionLruList::remove(); + } + } +} + +// release excessively old connections (free up file descriptors) +void +ConnectionManager::gc(UInt64 relThreshold, unsigned int maxToRemove) +{ + UInt64 curTimeMs = Timer::getTimeMs(); + UInt64 threshold = curTimeMs - relThreshold; + DebugLog(<< "recycling connections not used in last " << relThreshold/1000.0 << " seconds"); + + // Look through non-flow-timer connections and close those using the passed in relThreshold + unsigned int numRemoved = 0; + for (ConnectionLruList::iterator i = mLRUHead->begin(); + i != mLRUHead->end() && + (maxToRemove == 0 || numRemoved != maxToRemove);) + { + if ((*i)->whenLastUsed() < threshold) + { + Connection* discard = *i; + InfoLog(<< "recycling connection: " << discard << " " << discard->getSocket()); + // iterate before removing + ++i; + delete discard; + numRemoved++; + } + else + { + break; + } + } + + // Look through flow-timer connections and close those using the configured FlowTimer + // value + the configured grace period as a threshold + if(mFlowTimerLRUHead->begin() != mFlowTimerLRUHead->end()) + { + threshold = curTimeMs - ((InteropHelper::getFlowTimerSeconds() + InteropHelper::getFlowTimerGracePeriodSeconds()) * 1000); + for (FlowTimerLruList::iterator i2 = mFlowTimerLRUHead->begin(); + i2 != mFlowTimerLRUHead->end() && + (maxToRemove == 0 || numRemoved != maxToRemove);) + { + if ((*i2)->whenLastUsed() < threshold) + { + Connection* discard = *i2; + InfoLog(<< "recycling flow-timer enabled connection: " << discard << " " << discard->getSocket()); + // iterate before removing + ++i2; + delete discard; + numRemoved++; + } + else + { + break; + } + } + } +} + +// move to youngest +void +ConnectionManager::touch(Connection* connection) +{ + connection->resetLastUsed(); + if(connection->isFlowTimerEnabled()) + { + connection->FlowTimerLruList::remove(); + mFlowTimerLRUHead->push_back(connection); + } + else + { + connection->ConnectionLruList::remove(); + mLRUHead->push_back(connection); + } +} + +void +ConnectionManager::moveToFlowTimerLru(Connection *connection) +{ + connection->ConnectionLruList::remove(); + mFlowTimerLRUHead->push_back(connection); +} + +void +ConnectionManager::process(FdSet& fdset) +{ + assert( mPollGrp==NULL ); // owner shouldn't call this if polling + + // process the write list + for (ConnectionWriteList::iterator writeIter = mWriteHead->begin(); + writeIter != mWriteHead->end(); ) + { + Connection* currConnection = *writeIter; + + // update iterator to next first so that it can traverse safely + // even if current one is removed from the list later + ++writeIter; + + if (!currConnection) + continue; + + if (fdset.readyToWrite(currConnection->getSocket())) + { + currConnection->performWrites(); + } + else if (fdset.hasException(currConnection->getSocket())) + { + int errNum = 0; + int errNumSize = sizeof(errNum); + getsockopt(currConnection->getSocket(), SOL_SOCKET, SO_ERROR, (char *)&errNum, (socklen_t *)&errNumSize); + InfoLog(<< "Exception writing to socket " << currConnection->getSocket() << " code: " << errNum << "; closing connection"); + delete currConnection; + } + } + + // process the read list + for (ConnectionReadList::iterator readIter = mReadHead->begin(); + readIter != mReadHead->end(); ) + { + Connection* currConnection = *readIter; + + // update iterator to next first so that it can traverse safely + // even if current one is removed from the list later + ++readIter; + + if (!currConnection) + continue; + + if ( fdset.readyToRead(currConnection->getSocket()) || + currConnection->hasDataToRead() ) + { + fdset.clear(currConnection->getSocket()); + currConnection->performReads(); + } + else if (fdset.hasException(currConnection->getSocket())) + { + int errNum = 0; + int errNumSize = sizeof(errNum); + getsockopt(currConnection->getSocket(), SOL_SOCKET, SO_ERROR, (char *)&errNum, (socklen_t *)&errNumSize); + InfoLog(<< "Exception reading from socket " << currConnection->getSocket() << " code: " << errNum << "; closing connection"); + delete currConnection; + } + } +} + +void +ConnectionManager::setPollGrp(FdPollGrp *grp) +{ + // .bwc. We could have all the connections detach and re-attach, but the + // only place we call this when connections exist is when tearing down + // anyway. + closeConnections(); + mPollGrp = grp; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ConnectionManager.hxx b/src/libs/resiprocate/resip/stack/ConnectionManager.hxx new file mode 100644 index 00000000..0815e1e8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ConnectionManager.hxx @@ -0,0 +1,136 @@ +#ifndef RESIP_ConnectionMgr_hxx +#define RESIP_ConnectionMgr_hxx + +#include <map> +#include "rutil/HashMap.hxx" +#include "resip/stack/Connection.hxx" + +namespace resip +{ +class FdPollGrp; + +/** + Collection of Connection per Transport. Maintains round-robin + orders for read and write. Maintains least-recently-used connections list + for garbage collection. + + Maintains mapping from Tuple to Connection. + */ +class ConnectionManager +{ + friend class Connection; + public: + /** connection must have no inbound traffic for greater than this + time (in ms) before it is garbage collected */ + static UInt64 MinimumGcAge; + /** Enable Agressive Connection Garbage Collection to have resip + perform garbage collection on every new connection. If disabled + then garbage collection is only performed if we run out of Fd's */ + static bool EnableAgressiveGc; + + ConnectionManager(); + ~ConnectionManager(); + + /// may return 0 + Connection* findConnection(const Tuple& tuple); + const Connection* findConnection(const Tuple& tuple) const; + + /// populate the fdset againt the read and write lists + void setPollGrp(FdPollGrp *grp); + void buildFdSet(FdSet& fdset); + void process(FdSet& fdset); + + private: + void addToWritable(Connection* conn); // add the specified conn to end + void removeFromWritable(Connection* conn); // remove the current mWriteMark + + typedef std::map<Tuple, Connection*> AddrMap; + typedef std::map<Socket, Connection*> IdMap; + + void addConnection(Connection* connection); + void removeConnection(Connection* connection); + void closeConnections(); + + /// release excessively old connections (free up file descriptors) + /// set maxToRemove to 0 for no-max + void gc(UInt64 threshold, unsigned int maxToRemove); + + /// move to youngest + void touch(Connection* connection); + void moveToFlowTimerLru(Connection *connection); + + AddrMap mAddrMap; + IdMap mIdMap; + + /// all intrusive lists based on the same element type + Connection mHead; + + /// ready to write list + ConnectionWriteList* mWriteHead; + /// ready to read list + ConnectionReadList* mReadHead; + /// least recently used list + ConnectionLruList* mLRUHead; + /// least recently used list for flow timer enabled connections + FlowTimerLruList* mFlowTimerLRUHead; + + /// collection for epoll + FdPollGrp* mPollGrp; + //<<--------------------------------- + + friend class TcpBaseTransport; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ConnectionTerminated.hxx b/src/libs/resiprocate/resip/stack/ConnectionTerminated.hxx new file mode 100644 index 00000000..29262c3b --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ConnectionTerminated.hxx @@ -0,0 +1,92 @@ +#if !defined(RESIP_CONNECTIONTERMINATED_HXX) +#define RESIP_CONNECTIONTERMINATED_HXX + +#include "rutil/HeapInstanceCounter.hxx" +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/Tuple.hxx" + +namespace resip +{ + +class ConnectionTerminated : public TransactionMessage +{ + public: + RESIP_HeapCount(ConnectionTerminated); + + ConnectionTerminated(const Tuple& flow) : + mFlow(flow) + { + } + virtual const Data& getTransactionId() const { assert(0); return Data::Empty; } + virtual bool isClientTransaction() const { assert(0); return false; } + virtual Message* clone() const { return new ConnectionTerminated(mFlow); } + virtual EncodeStream& encode(EncodeStream& strm) const { return encodeBrief(strm); } + virtual EncodeStream& encodeBrief(EncodeStream& str) const + { + return str << "ConnectionTerminated " << mFlow; + } + + FlowKey getFlowKey() const + { + return mFlow.mFlowKey; + } + + const Tuple& getFlow() const + { + return mFlow; + } + + private: + const Tuple mFlow; +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Contents.cxx b/src/libs/resiprocate/resip/stack/Contents.cxx new file mode 100644 index 00000000..9d3069ea --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Contents.cxx @@ -0,0 +1,713 @@ +#include <vector> + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Contents.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/OctetContents.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::CONTENTS + +H_ContentID resip::h_ContentID; +H_ContentDescription resip::h_ContentDescription; + +Contents::Contents(const HeaderFieldValue& headerFieldValue, + const Mime& contentType) + : LazyParser(headerFieldValue), + mType(contentType) +{ + init(); +} + +Contents::Contents(const Mime& contentType) + : mType(contentType) +{ + init(); +} + +Contents::Contents(const Contents& rhs) + : LazyParser(rhs) +{ + init(rhs); +} + +Contents::Contents(const Contents& rhs,HeaderFieldValue::CopyPaddingEnum e) + : LazyParser(rhs,e) +{ + init(rhs); +} + +Contents::Contents(const HeaderFieldValue& headerFieldValue, + HeaderFieldValue::CopyPaddingEnum e, + const Mime& contentsType) + : LazyParser(headerFieldValue,e), + mType(contentsType) +{ + init(); +} + + +Contents::~Contents() +{ + freeMem(); +} + +static const Data errorContextData("Contents"); +const Data& +Contents::errorContext() const +{ + return errorContextData; +} + +Contents& +Contents::operator=(const Contents& rhs) +{ + if (this != &rhs) + { + freeMem(); + LazyParser::operator=(rhs); + init(rhs); + } + + return *this; +} + +void +Contents::init(const Contents& orig) +{ + mBufferList.clear(); + mType = orig.mType; + if (orig.mDisposition) + { + mDisposition = new H_ContentDisposition::Type(*orig.mDisposition); + } + else + { + mDisposition = 0; + } + + if (orig.mTransferEncoding) + { + mTransferEncoding = new H_ContentTransferEncoding::Type(*orig.mTransferEncoding); + } + else + { + mTransferEncoding = 0; + } + + if (orig.mLanguages) + { + mLanguages = new H_ContentLanguages::Type(*orig.mLanguages); + } + else + { + mLanguages = 0; + } + + if (orig.mId) + { + mId = new Token(*orig.mId); + } + else + { + mId = 0; + } + + if (orig.mDescription) + { + mDescription = new StringCategory(*orig.mDescription); + } + else + { + mDescription = 0; + } + + if(orig.mLength) + { + mLength = new StringCategory(*orig.mLength); + } + else + { + mLength = 0; + } + + mVersion = orig.mVersion; + mMinorVersion = orig.mMinorVersion; + +} + +Contents* +Contents::createContents(const Mime& contentType, + const Data& contents) +{ + // !ass! why are we asserting that the Data doesn't own the buffer? + // .dlb. because this method is to be called only within a multipart + // !ass! HFV is an overlay -- then setting c->mIsMine to true ?? dlb Q + // .dlb. we are telling the content that it owns its HFV, not the data that it + // .dlb. owns its memory + // .bwc. So, we are _violating_ _encapsulation_, to make an assertion that the + // Data is an intermediate instead of owning the buffer itself? What do we + // care how this buffer is owned? All we require is that the buffer doesn't + // get dealloced/modified while we're still around. The assertion might mean + // that the Data will not do either of these things, but it affords no + // protection from the actual owner doing so. We are no more protected with + // the assertion, so I am removing it. +// assert(!contents.mMine); + + HeaderFieldValue hfv(contents.data(), (unsigned int)contents.size()); + +// !bwc! This padding stuff is now the responsibility of the Contents class. +// if(contentType.subType()=="sipfrag"||contentType.subType()=="external-body") +// { +// // .bwc. The parser for sipfrag requires padding at the end of the hfv. +// HeaderFieldValue* temp = hfv; +// hfv = new HeaderFieldValue(*temp,HeaderFieldValue::CopyPadding); +// delete temp; +// } + + Contents* c; + if (ContentsFactoryBase::getFactoryMap().find(contentType) != ContentsFactoryBase::getFactoryMap().end()) + { + c = ContentsFactoryBase::getFactoryMap()[contentType]->create(hfv, contentType); + } + else + { + c = new OctetContents(hfv, contentType); + } + return c; +} + +bool +Contents::exists(const HeaderBase& headerType) const +{ + checkParsed(); + switch (headerType.getTypeNum()) + { + case Headers::ContentType : + { + return true; + } + case Headers::ContentDisposition : + { + return mDisposition != 0; + } + case Headers::ContentTransferEncoding : + { + return mTransferEncoding != 0; + } + case Headers::ContentLanguage : + { + return mLanguages != 0; + } + default : return false; + } +} + +bool +Contents::exists(const MIME_Header& type) const +{ + if (&type == &h_ContentID) + { + return mId != 0; + } + + if (&type == &h_ContentDescription) + { + return mDescription != 0; + } + + assert(false); + return false; +} + +void +Contents::remove(const HeaderBase& headerType) +{ + switch (headerType.getTypeNum()) + { + case Headers::ContentDisposition : + { + delete mDisposition; + mDisposition = 0; + break; + } + case Headers::ContentLanguage : + { + delete mLanguages; + mLanguages = 0; + break; + } + case Headers::ContentTransferEncoding : + { + delete mTransferEncoding; + mTransferEncoding = 0; + break; + } + default : + ; + } +} + +void +Contents::remove(const MIME_Header& type) +{ + if (&type == &h_ContentID) + { + delete mId; + mId = 0; + return; + } + + if (&type == &h_ContentDescription) + { + delete mDescription; + mDescription = 0; + return; + } + + assert(false); +} + +const H_ContentType::Type& +Contents::header(const H_ContentType& headerType) const +{ + return mType; +} + +H_ContentType::Type& +Contents::header(const H_ContentType& headerType) +{ + return mType; +} + +const H_ContentDisposition::Type& +Contents::header(const H_ContentDisposition& headerType) const +{ + checkParsed(); + if (mDisposition == 0) + { + ErrLog(<< "You called " + "Contents::header(const H_ContentDisposition& headerType) _const_ " + "without first calling exists(), and the header does not exist. Our" + " behavior in this scenario is to implicitly create the header(using const_cast!); " + "this is probably not what you want, but it is either this or " + "assert/throw an exception. Since this has been the behavior for " + "so long, we are not throwing here, _yet_. You need to fix your " + "code, before we _do_ start throwing. This is why const-correctness" + " should never be made a TODO item </rant>"); + Contents* ncthis = const_cast<Contents*>(this); + ncthis->mDisposition = new H_ContentDisposition::Type; + } + return *mDisposition; +} + +H_ContentDisposition::Type& +Contents::header(const H_ContentDisposition& headerType) +{ + checkParsed(); + if (mDisposition == 0) + { + mDisposition = new H_ContentDisposition::Type; + } + return *mDisposition; +} + +const H_ContentTransferEncoding::Type& +Contents::header(const H_ContentTransferEncoding& headerType) const +{ + checkParsed(); + if (mTransferEncoding == 0) + { + ErrLog(<< "You called " + "Contents::header(const H_ContentTransferEncoding& headerType) _const_ " + "without first calling exists(), and the header does not exist. Our" + " behavior in this scenario is to implicitly create the header(using const_cast!); " + "this is probably not what you want, but it is either this or " + "assert/throw an exception. Since this has been the behavior for " + "so long, we are not throwing here, _yet_. You need to fix your " + "code, before we _do_ start throwing. This is why const-correctness" + " should never be made a TODO item </rant>"); + Contents* ncthis = const_cast<Contents*>(this); + ncthis->mTransferEncoding = new H_ContentTransferEncoding::Type; + } + return *mTransferEncoding; +} + +H_ContentTransferEncoding::Type& +Contents::header(const H_ContentTransferEncoding& headerType) +{ + checkParsed(); + if (mTransferEncoding == 0) + { + mTransferEncoding = new H_ContentTransferEncoding::Type; + } + return *mTransferEncoding; +} + +const H_ContentLanguages::Type& +Contents::header(const H_ContentLanguages& headerType) const +{ + checkParsed(); + if (mLanguages == 0) + { + ErrLog(<< "You called " + "Contents::header(const H_ContentLanguages& headerType) _const_ " + "without first calling exists(), and the header does not exist. Our" + " behavior in this scenario is to implicitly create the header(using const_cast!); " + "this is probably not what you want, but it is either this or " + "assert/throw an exception. Since this has been the behavior for " + "so long, we are not throwing here, _yet_. You need to fix your " + "code, before we _do_ start throwing. This is why const-correctness" + " should never be made a TODO item </rant>"); + Contents* ncthis = const_cast<Contents*>(this); + ncthis->mLanguages = new H_ContentLanguages::Type; + } + return *mLanguages; +} + +H_ContentLanguages::Type& +Contents::header(const H_ContentLanguages& headerType) +{ + checkParsed(); + if (mLanguages == 0) + { + mLanguages = new H_ContentLanguages::Type; + } + return *mLanguages; +} + +const H_ContentDescription::Type& +Contents::header(const H_ContentDescription& headerType) const +{ + checkParsed(); + if (mDescription == 0) + { + ErrLog(<< "You called " + "Contents::header(const H_ContentDescription& headerType) _const_ " + "without first calling exists(), and the header does not exist. Our" + " behavior in this scenario is to implicitly create the header(using const_cast!); " + "this is probably not what you want, but it is either this or " + "assert/throw an exception. Since this has been the behavior for " + "so long, we are not throwing here, _yet_. You need to fix your " + "code, before we _do_ start throwing. This is why const-correctness" + " should never be made a TODO item </rant>"); + Contents* ncthis = const_cast<Contents*>(this); + ncthis->mDescription = new H_ContentDescription::Type; + } + return *mDescription; +} + +H_ContentDescription::Type& +Contents::header(const H_ContentDescription& headerType) +{ + checkParsed(); + if (mDescription == 0) + { + mDescription = new H_ContentDescription::Type; + } + return *mDescription; +} + +const H_ContentID::Type& +Contents::header(const H_ContentID& headerType) const +{ + checkParsed(); + if (mId == 0) + { + ErrLog(<< "You called " + "Contents::header(const H_ContentID& headerType) _const_ " + "without first calling exists(), and the header does not exist. Our" + " behavior in this scenario is to implicitly create the header(using const_cast!); " + "this is probably not what you want, but it is either this or " + "assert/throw an exception. Since this has been the behavior for " + "so long, we are not throwing here, _yet_. You need to fix your " + "code, before we _do_ start throwing. This is why const-correctness" + " should never be made a TODO item </rant>"); + Contents* ncthis = const_cast<Contents*>(this); + ncthis->mId = new H_ContentID::Type; + } + return *mId; +} + +H_ContentID::Type& +Contents::header(const H_ContentID& headerType) +{ + checkParsed(); + if (mId == 0) + { + mId = new H_ContentID::Type; + } + return *mId; +} + +// !dlb! headers except Content-Disposition may contain (comments) +void +Contents::preParseHeaders(ParseBuffer& pb) +{ + const char* start = pb.position(); + Data all( start, pb.end()-start); + + Data headerName; + + try + { + + while (!pb.eof()) + { + const char* anchor = pb.skipWhitespace(); + pb.skipToOneOf(Symbols::COLON, ParseBuffer::Whitespace); + pb.data(headerName, anchor); + + pb.skipWhitespace(); + pb.skipChar(Symbols::COLON[0]); + anchor = pb.skipWhitespace(); + pb.skipToTermCRLF(); + + Headers::Type type = Headers::getType(headerName.data(), (int)headerName.size()); + ParseBuffer subPb(anchor, pb.position() - anchor); + + switch (type) + { + case Headers::ContentType : + { + // already set + break; + } + case Headers::ContentDisposition : + { + mDisposition = new H_ContentDisposition::Type; + mDisposition->parse(subPb); + break; + } + case Headers::ContentTransferEncoding : + { + mTransferEncoding = new H_ContentTransferEncoding::Type; + mTransferEncoding->parse(subPb); + break; + } + // !dlb! not sure this ever happens? + case Headers::ContentLanguage : + { + if (mLanguages == 0) + { + mLanguages = new H_ContentLanguages::Type; + } + + subPb.skipWhitespace(); + while (!subPb.eof() && *subPb.position() != Symbols::COMMA[0]) + { + H_ContentLanguages::Type::value_type tmp; + header(h_ContentLanguages).push_back(tmp); + header(h_ContentLanguages).back().parse(subPb); + subPb.skipLWS(); + } + break; // .kw. added -- this is needed, right? + } + default : + { + if (isEqualNoCase(headerName, "Content-Transfer-Encoding")) + { + mTransferEncoding = new StringCategory(); + mTransferEncoding->parse(subPb); + } + else if (isEqualNoCase(headerName, "Content-Description")) + { + mDescription = new StringCategory(); + mDescription->parse(subPb); + } + else if (isEqualNoCase(headerName, "Content-Id")) + { + mId = new Token(); + mId->parse(subPb); + } + // Some people put this in ... + else if (isEqualNoCase(headerName, "Content-Length")) + { + mLength = new StringCategory(); + mLength->parse(subPb); + } + else if (isEqualNoCase(headerName, "MIME-Version")) + { + subPb.skipWhitespace(); + if (!subPb.eof() && *subPb.position() == Symbols::LPAREN[0]) + { + subPb.skipToEndQuote(Symbols::RPAREN[0]); + subPb.skipChar(Symbols::RPAREN[0]); + } + mVersion = subPb.integer(); + + if (!subPb.eof() && *subPb.position() == Symbols::LPAREN[0]) + { + subPb.skipToEndQuote(Symbols::RPAREN[0]); + subPb.skipChar(Symbols::RPAREN[0]); + } + subPb.skipChar(Symbols::PERIOD[0]); + + if (!subPb.eof() && *subPb.position() == Symbols::LPAREN[0]) + { + subPb.skipToEndQuote(Symbols::RPAREN[0]); + subPb.skipChar(Symbols::RPAREN[0]); + } + + mMinorVersion = subPb.integer(); + } + else + { + // add to application headers someday + std::cerr << "Unknown MIME Content- header: " << headerName << std::endl; + ErrLog(<< "Unknown MIME Content- header: " << headerName); + assert(false); + } + } + } + } + } + catch (ParseException & e ) + { + ErrLog( << "Some problem parsing contents: " << e ); + throw e; + } +} + +EncodeStream& +Contents::encodeHeaders(EncodeStream& str) const +{ + if (mVersion != 1 || mMinorVersion != 0) + { + str << "MIME-Version" << Symbols::COLON[0] << Symbols::SPACE[0] + << mVersion << Symbols::PERIOD[0] << mMinorVersion + << Symbols::CRLF; + } + + str << "Content-Type" << Symbols::COLON[0] << Symbols::SPACE[0] + << mType + << Symbols::CRLF; + + if (exists(h_ContentDisposition)) + { + str << "Content-Disposition" << Symbols::COLON[0] << Symbols::SPACE[0]; + + header(h_ContentDisposition).encode(str); + str << Symbols::CRLF; + } + + if (exists(h_ContentLanguages)) + { + str << "Content-Languages" << Symbols::COLON[0] << Symbols::SPACE[0]; + + size_t count = 0; + size_t size = header(h_ContentLanguages).size(); + + for (H_ContentLanguages::Type::const_iterator + i = header(h_ContentLanguages).begin(); + i != header(h_ContentLanguages).end(); ++i) + { + i->encode(str); + + if (++count < size) + str << Symbols::COMMA << Symbols::SPACE; + } + str << Symbols::CRLF; + } + + if (mTransferEncoding) + { + str << "Content-Transfer-Encoding" << Symbols::COLON[0] << Symbols::SPACE[0] + << *mTransferEncoding + << Symbols::CRLF; + } + + if (mId) + { + str << "Content-Id" << Symbols::COLON[0] << Symbols::SPACE[0] + << *mId + << Symbols::CRLF; + } + + if (mDescription) + { + str << "Content-Description" << Symbols::COLON[0] << Symbols::SPACE[0] + << *mDescription + << Symbols::CRLF; + } + + if (mLength) + { + str << "Content-Length" << Symbols::COLON[0] << Symbols::SPACE[0] + << *mLength + << Symbols::CRLF; + } + + str << Symbols::CRLF; + return str; +} + +Data +Contents::getBodyData() const +{ + checkParsed(); + return Data::from(*this); +} + +void +Contents::addBuffer(char* buf) +{ + mBufferList.push_back(buf); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Contents.hxx b/src/libs/resiprocate/resip/stack/Contents.hxx new file mode 100644 index 00000000..17fb0a66 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Contents.hxx @@ -0,0 +1,416 @@ +#ifndef RESIP_Contents_hxx +#define RESIP_Contents_hxx + +#include <iosfwd> +#include <vector> + +#include "resip/stack/LazyParser.hxx" +#include "resip/stack/Mime.hxx" +#include "resip/stack/StringCategory.hxx" +#include "resip/stack/Headers.hxx" +#include "resip/stack/HeaderFieldValue.hxx" +#include "rutil/Data.hxx" +#include "resip/stack/ContentsFactory.hxx" + +namespace resip +{ + +class Token; +class Contents; +class HeaderFieldValue; +class ParseBuffer; + +/** @brief MIME header identifier base class */ +class MIME_Header +{ +}; + +/** @brief Content-ID MIME header identifier class */ +class H_ContentID : public MIME_Header +{ + public: + typedef Token Type; +}; +extern H_ContentID h_ContentID; + +/** @brief Content-ID MIME header identifier class */ +class H_ContentDescription : public MIME_Header +{ + public: + typedef StringCategory Type; +}; +extern H_ContentDescription h_ContentDescription; + + +/** + @ingroup resip_crit + @ingroup sip_payload + @brief Base class for all SIP body types. Lazily-parsed. +*/ +class Contents : public LazyParser +{ + public: + /// pass Mime instance for parameters + Contents(const HeaderFieldValue& headerFieldValue, const Mime& contentsType); + /** + @brief Create a contents with a given mime type + @param contentsType the mime type of the contents + */ + Contents(const Mime& contentsType); + /** + @brief Copy constructor + @param rhs the Contents to be copied + */ + Contents(const Contents& rhs); + /** + @internal + @todo internal documentation + */ + Contents(const Contents& rhs,HeaderFieldValue::CopyPaddingEnum e); + /** + @internal + @todo internal documentation + */ + Contents(const HeaderFieldValue& headerFieldValue, + HeaderFieldValue::CopyPaddingEnum e, + const Mime& contentsType); + virtual ~Contents(); + /** + @brief Assignment operator + @param rhs Contents object to be copied + @return a reference to a copy of rhs + */ + Contents& operator=(const Contents& rhs); + /** + @brief Preforms preparsing on the headers stored in the ParseBuffer pb + @param pb a ParseBuffer containing the headers to preparse + */ + void preParseHeaders(ParseBuffer& pb); + /** + @brief encodes headers to an output stream + @param str output stream destination for encoded headers + @return a reference to str + */ + EncodeStream& encodeHeaders(EncodeStream& str) const; + + /** + @brief access to wrapped contents (signed, encrypted) + @return a pointer to self + */ + virtual Contents* getContents() {return this;} + + /** + @internal + @todo - unimplemented - decide fate + */ + Contents* getContents(const Mime&); + + virtual Data getBodyData() const; + + /** + @brief returns a copy of a Contents object + */ + virtual Contents* clone() const = 0; + /** + @brief getter for mime type of message + @return the mime type of the message + */ + const Mime& getType() const {return mType;} + /** + @brief factory method to create a Contents object from a mime type and a payload + @param contentType the mime type of the contents + @param contents the contents + @return a instance of a Contents subclass appropriate to the mime type + @note If no registered Contents subclass has been registered with the factory + an instance of OctetContents is returned. + @sa ContentsFactory + @sa ContentsFactoryBase + */ + static Contents* createContents(const Mime& contentType, + const Data& contents); + /** + @brief checks to see if a header is present + @param headerType the header to check for + @return true if that header exists and false otherwise + */ + bool exists(const HeaderBase& headerType) const; + /** + @brief removes a header if it is present + @param headerType the header to remove + */ + void remove(const HeaderBase& headerType); + /** + @brief checks to see if a MIME header exists + @param headerType the MIME header to check for + @return true if the header exists and false otherwise + */ + bool exists(const MIME_Header& headerType) const; + /** + @brief removes a MIME header if it is present + @param headerType the MIME header to remove + */ + void remove(const MIME_Header& headerType); + + // !dlb! break into const and non-const -- throw on const if not exists + // !dlb! requires a nested exception... + + // shared header types + /** + @brief returns the value of the Content-Type header + Throws an Contents::Exception if the header doesn't exist. + + @code + retval = contents.header(Headers::ContentType); + @endcode + + @return the Content-Type header value + */ + const H_ContentType::Type& header(const H_ContentType& headerType) const; + /** + @brief returns the value of the Content-Type header + + @code + retval = contents.header(Headers::ContentType); + @endcode + + @return the Content-Type header value + */ + H_ContentType::Type& header(const H_ContentType& headerType); + + /** + @brief returns the value of the Content-Disposition header + Throws an Contents::Exception if the header doesn't exist. + @code + retval = contents.header(Headers::ContentDisposition); + @endcode + @return the Content-Disposition header value + */ + const H_ContentDisposition::Type& header(const H_ContentDisposition& headerType) const; + /** + @brief returns the value of the Content-Disposition header + @code + retval = contents.header(Headers::ContentDisposition); + @endcode + @return the Content-Disposition header value + */ + H_ContentDisposition::Type& header(const H_ContentDisposition& headerType); + + /** + @brief returns the value of the Content-Transfer-Encoding header + Throws an Contents::Exception if the header doesn't exist. + @code + retval = contents.header(Headers::ContentTransferEncoding); + @endcode + @return the Content-Transfer-Encoding header value + */ + const H_ContentTransferEncoding::Type& header(const H_ContentTransferEncoding& headerType) const; + /** + @brief returns the value of the Content-Transfer-Encoding header + @code + retval = contents.header(Headers::ContentTransferEncoding); + @endcode + @return the Content-Transfer-Encoding header value + */ + H_ContentTransferEncoding::Type& header(const H_ContentTransferEncoding& headerType); + + /** + @brief returns the value of the Content-Languages header + Throws an Contents::Exception if the header doesn't exist. + @code + retval = contents.header(Headers::ContentLanguages); + @endcode + @return the Content-Languages header value + */ + const H_ContentLanguages::Type& header(const H_ContentLanguages& headerType) const; + /** + @brief returns the value of the Content-Languages header + @code + retval = contents.header(Headers::ContentLanguages); + @endcode + @return the Content-Languages header value + */ + H_ContentLanguages::Type& header(const H_ContentLanguages& headerType); + + // MIME specific header types + /** + @brief returns the value of the Content-ID MIME header + Throws an Contents::Exception if the header doesn't exist. + @code + retval = contents.header(Headers::ContentId); + @endcode + @return the Content-Id MIME header value + */ + const H_ContentID::Type& header(const H_ContentID& headerType) const; + /** + @brief returns the value of the Content-ID MIME header + @code + retval = contents.header(Headers::ContentId); + @endcode + @return the Content-Id MIME header value + */ + H_ContentID::Type& header(const H_ContentID& headerType); + + /** + @brief returns the Content-Description MIME header + Throws an Contents::Exception if the header doesn't exist. + @code + retval = contents.header(Headers::ContentDescription) + @endcode + @return the Content-Description MIME header + */ + const H_ContentDescription::Type& header(const H_ContentDescription& headerType) const; + /** + @brief returns the Content-Description MIME header + @code + retval = contents.header(Headers::ContentDescription) + @endcode + @return the Content-Description MIME header + */ + H_ContentDescription::Type& header(const H_ContentDescription& headerType); + + /** + @brief returns the major version of MIME used by the contents + @return MIME major version + */ + int& version() {return mVersion;} + /** + @brief returns the minor version of MIME used by the contents + @return MIME minor version + */ + int& minorVersion() {return mMinorVersion;} + /** + @internal + @todo - is this being used? -- is the buffer list being used as a list? + */ + void addBuffer(char* buf); + + protected: + + /** + @internal + @todo !bwc! Calls freeMem(), then reverts members to a default state + (including setting pointers to 0) + */ + inline void clear() + { + freeMem(); + init(); + } + + /** @internal */ + inline void init() + { + mBufferList.clear(); + mDisposition = 0; + mTransferEncoding = 0; + mLanguages = 0; + mId = 0; + mDescription = 0; + mLength = 0; + mVersion = 1; + mMinorVersion = 0; + } + /** @internal */ + void init(const Contents& orig); + + // !bwc! Just frees up heap-allocated stuff, doesn't set pointers to 0 + // This exists because it is pointless (and inefficient) to revert + // members to a default state while deleting (they're just going to go + // out of scope anyway) The d'tor is the only thing that uses this by + // itself. Everything else should use clear() + /** @internal */ + inline void freeMem() + { + delete mDisposition; + delete mTransferEncoding; + delete mLanguages; + delete mId; + delete mDescription; + delete mLength; + + for (std::vector<char*>::iterator i = mBufferList.begin(); + i != mBufferList.end(); i++) + { + delete [] *i; + } + + } + /** @internal */ + virtual const Data& errorContext() const; + + /** @internal */ + Mime mType; + /** @internal */ + H_ContentDisposition::Type *mDisposition; + /** @internal */ + H_ContentTransferEncoding::Type *mTransferEncoding; + /** @internal */ + H_ContentLanguages::Type *mLanguages; + /** @internal */ + Token *mId; + /** @internal */ + H_ContentDescription::Type *mDescription; + /** @internal */ + StringCategory *mLength; + + /** @internal */ + int mVersion; + /** @internal */ + int mMinorVersion; + + std::vector<char*> mBufferList; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ContentsFactory.hxx b/src/libs/resiprocate/resip/stack/ContentsFactory.hxx new file mode 100644 index 00000000..ff4a793f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ContentsFactory.hxx @@ -0,0 +1,90 @@ +#ifndef RESIP_ContentsFactory +#define RESIP_ContentsFactory + +#include "resip/stack/ContentsFactoryBase.hxx" + +namespace resip +{ + +class Contents; + +/** + @internal +*/ +template<class T> +class ContentsFactory : public ContentsFactoryBase +{ + public: + ContentsFactory() + : ContentsFactoryBase(T::getStaticType()) + {} + + explicit ContentsFactory(const Mime& nonStandardType) + : ContentsFactoryBase(nonStandardType) + {} + + // pass Mime instance for parameters + virtual Contents* create(const HeaderFieldValue& hfv, const Mime& contentType) const + { + return new T(hfv, contentType); + } + + virtual Contents* convert(Contents* c) const + { + return dynamic_cast<T*>(c); + } +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ContentsFactoryBase.cxx b/src/libs/resiprocate/resip/stack/ContentsFactoryBase.cxx new file mode 100644 index 00000000..1d89b814 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ContentsFactoryBase.cxx @@ -0,0 +1,95 @@ +#include <cassert> + +#include "resip/stack/ContentsFactoryBase.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +HashMap<Mime, ContentsFactoryBase*>* ContentsFactoryBase::FactoryMap = 0; + +ContentsFactoryBase::ContentsFactoryBase(const Mime& contentType) + : mContentType(contentType) +{ + // .amr. Due to multiple static initializers, this can be called more than once for a mimetype + // so gracefully handle it + if(ContentsFactoryBase::getFactoryMap().count(contentType) == 0) + ContentsFactoryBase::getFactoryMap()[contentType] = this; +} + +ContentsFactoryBase::~ContentsFactoryBase() +{ + if (ContentsFactoryBase::FactoryMap == 0) + return; + + HashMap<Mime, ContentsFactoryBase*>::iterator i; + i = ContentsFactoryBase::getFactoryMap().find(mContentType); + // .amr. Need to check if iterator is valid since on some STL instances erase(i) will crash if i is invalid. + if (i != ContentsFactoryBase::getFactoryMap().end()) + ContentsFactoryBase::getFactoryMap().erase(i); + if (ContentsFactoryBase::getFactoryMap().size() == 0) + { + delete &ContentsFactoryBase::getFactoryMap(); + ContentsFactoryBase::FactoryMap = 0; + } +} + +HashMap<Mime, ContentsFactoryBase*>& +ContentsFactoryBase::getFactoryMap() +{ + if (ContentsFactoryBase::FactoryMap == 0) + { + ContentsFactoryBase::FactoryMap = new HashMap<Mime, ContentsFactoryBase*>(); + } + return *ContentsFactoryBase::FactoryMap; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ContentsFactoryBase.hxx b/src/libs/resiprocate/resip/stack/ContentsFactoryBase.hxx new file mode 100644 index 00000000..eda4c109 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ContentsFactoryBase.hxx @@ -0,0 +1,84 @@ +#ifndef RESIP_ContentsFactoryBase_hxx +#define RESIP_ContentsFactoryBase_hxx + +#include "resip/stack/Mime.hxx" +#include "rutil/HashMap.hxx" + +namespace resip +{ + +class Contents; +/** + @internal + + @brief Hoist for template mapping from Mime to derived content. +*/ +class ContentsFactoryBase +{ + public: + ContentsFactoryBase(const Mime& contentType); + virtual ~ContentsFactoryBase(); + virtual Contents* create(const HeaderFieldValue& hfv, + const Mime& contentType) const = 0; + virtual Contents* convert(Contents* c) const = 0; + + static HashMap<Mime, ContentsFactoryBase*>& getFactoryMap(); + private: + Mime mContentType; + static HashMap<Mime, ContentsFactoryBase*>* FactoryMap; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/stack/CpimContents.cxx b/src/libs/resiprocate/resip/stack/CpimContents.cxx new file mode 100644 index 00000000..1e2e1884 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/CpimContents.cxx @@ -0,0 +1,152 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/CpimContents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +bool +CpimContents::init() +{ + static ContentsFactory<CpimContents> factory; + (void)factory; + return true; +} + +const CpimContents CpimContents::Empty; + +CpimContents::CpimContents() + : Contents(getStaticType()), + mText() +{} + +CpimContents::CpimContents(const Data& txt) + : Contents(getStaticType()), + mText(txt) +{} + +CpimContents::CpimContents(const HeaderFieldValue& hfv, const Mime& contentsType) + : Contents(hfv, contentsType), + mText() +{ +} + +CpimContents::CpimContents(const Data& txt, const Mime& contentsType) + : Contents(contentsType), + mText(txt) +{ +} + +CpimContents::CpimContents(const CpimContents& rhs) + : Contents(rhs), + mText(rhs.mText) +{ +} + +CpimContents::~CpimContents() +{ +} + +CpimContents& +CpimContents::operator=(const CpimContents& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + mText = rhs.mText; + } + return *this; +} + +Contents* +CpimContents::clone() const +{ + return new CpimContents(*this); +} + +const Mime& +CpimContents::getStaticType() +{ + static Mime type("message","cpim"); + return type; +} + +EncodeStream& +CpimContents::encodeParsed(EncodeStream& str) const +{ + //DebugLog(<< "CpimContents::encodeParsed " << mText); + str << mText; + return str; +} + +void +CpimContents::parse(ParseBuffer& pb) +{ + //DebugLog(<< "CpimContents::parse: " << pb.position()); + + const char* anchor = pb.position(); + pb.skipToEnd(); + pb.data(mText, anchor); + + //DebugLog("CpimContents::parsed <" << mText << ">" ); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/CpimContents.hxx b/src/libs/resiprocate/resip/stack/CpimContents.hxx new file mode 100644 index 00000000..9ec29a88 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/CpimContents.hxx @@ -0,0 +1,101 @@ +#if !defined(RESIP_CPIMCONTENTS_HXX) +#define RESIP_CPIMCONTENTS_HXX + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type for holding CPIM (Common Profile for Instant + Messaging) contents (MIME content-type message/cpim). +*/ +class CpimContents : public Contents +{ + public: + static const CpimContents Empty; + + CpimContents(); + CpimContents(const Data& text); + CpimContents(const HeaderFieldValue& hfv, const Mime& contentType); + CpimContents(const Data& data, const Mime& contentType); + CpimContents(const CpimContents& rhs); + virtual ~CpimContents(); + CpimContents& operator=(const CpimContents& rhs); + + /** @brief duplicate an CpimContents object + @return pointer to a new CpimContents object + **/ + virtual Contents* clone() const; + static const Mime& getStaticType() ; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + + /** @brief Get the CPIM message text. + @return Data containing the CPIM message text. + **/ + Data& text() {checkParsed(); return mText;} + + static bool init(); + private: + Data mText; +}; + +static bool invokeCpimContentsInit = CpimContents::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/DataParameter.cxx b/src/libs/resiprocate/resip/stack/DataParameter.cxx new file mode 100644 index 00000000..ebc855ca --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DataParameter.cxx @@ -0,0 +1,146 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <cassert> +#include "resip/stack/DataParameter.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/ParseException.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +DataParameter::DataParameter(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators) + : Parameter(type), + mValue(), + mQuoted(false) +{ + pb.skipWhitespace(); + pb.skipChar(Symbols::EQUALS[0]); + pb.skipWhitespace(); + if(terminators[(unsigned char)(*pb.position())]) // handle cases such as ;tag= + { + throw ParseException("Empty value in string-type parameter.", + "DataParameter", + __FILE__,__LINE__); + } + + if (*pb.position() == Symbols::DOUBLE_QUOTE[0]) + { + setQuoted(true); + pb.skipChar(); + const char* pos = pb.position(); + pb.skipToEndQuote(); + pb.data(mValue, pos); + pb.skipChar(); + } + else + { + const char* pos = pb.position(); + pb.skipToOneOf(terminators); + pb.data(mValue, pos); + } + + if(!mQuoted && mValue.empty()) + { + // .bwc. We can't let this happen, because we throw if we try to encode + // when we have an empty value. If that behavior stops, this can be + // removed. + /* throw ParseException("DataParameter c'tor parsed empty param!", + "DataParameter", + __FILE__, + __LINE__); */ + } +} + +DataParameter::DataParameter(ParameterTypes::Type type) + : Parameter(type), + mValue(), + mQuoted(false) +{ +} + +Parameter* +DataParameter::clone() const +{ + return new DataParameter(*this); +} + +EncodeStream& +DataParameter::encode(EncodeStream& stream) const +{ + if (mQuoted) + { + return stream << getName() << Symbols::EQUALS + << Symbols::DOUBLE_QUOTE << mValue << Symbols::DOUBLE_QUOTE; + } + else + { + // this will assert if you've accessed a parameter that doesn't exist and + // then the stack has created an empty parameter with no value. Try + // calling exists(p_foo) before calling param(p_foo) + if (mValue.empty()) + { + ErrLog(<< "Accessing defaulted DataParameter: '" << getName() << "'"); + } + assert(!mValue.empty()); // !jf! probably should throw here + return stream << getName() << Symbols::EQUALS << mValue; + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/DataParameter.hxx b/src/libs/resiprocate/resip/stack/DataParameter.hxx new file mode 100644 index 00000000..1363d87e --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DataParameter.hxx @@ -0,0 +1,109 @@ +#if !defined(RESIP_DATAPARAMETER_HXX) +#define RESIP_DATAPARAMETER_HXX + +#include "resip/stack/Parameter.hxx" +#include "resip/stack/ParameterTypeEnums.hxx" +#include "rutil/Data.hxx" +#include "rutil/PoolBase.hxx" +#include <iosfwd> + +namespace resip +{ + +class ParseBuffer; + + +/** + @ingroup sip_grammar + @brief Generically represents miscellaneous parameter data. +*/ +class DataParameter : public Parameter +{ + public: + typedef Data Type; + + DataParameter(ParameterTypes::Type, ParseBuffer& pb, + const std::bitset<256>& terminators); + explicit DataParameter(ParameterTypes::Type); + + bool isQuoted() const { return mQuoted; } + void setQuoted(bool b) { mQuoted = b; }; // this parameter will be enclosed in quotes e.g. "foo" + + static Parameter* decode(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators, + PoolBase* pool) + { + return new (pool) DataParameter(type, pb, terminators); + } + + virtual Parameter* clone() const; + virtual EncodeStream& encode(EncodeStream& stream) const; + + Type& value() {return mValue;} // does not return a quoted string + protected: + DataParameter(const DataParameter& other) + : Parameter(other), + mValue(other.mValue), + mQuoted(other.mQuoted) + { + } + + Type mValue; + bool mQuoted; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/DateCategory.cxx b/src/libs/resiprocate/resip/stack/DateCategory.cxx new file mode 100644 index 00000000..bcab588d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DateCategory.cxx @@ -0,0 +1,663 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <time.h> + +#include "resip/stack/DateCategory.hxx" +#include "resip/stack/Transport.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Socket.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// Date +//==================== + +Data resip::DayOfWeekData[] = +{ + "Sun", + "Mon", + "Tue", + "Wed", + "Thu", + "Fri", + "Sat" +}; + +Data resip::MonthData[] = +{ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" +}; + + +DateCategory::DateCategory() + : ParserCategory(), + mDayOfWeek(Sun), + mDayOfMonth(), + mMonth(Jan), + mYear(0), + mHour(0), + mMin(0), + mSec(0) +{ + time_t now; + time(&now); + if (now == ((time_t)-1)) + { + int e = getErrno(); + DebugLog (<< "Failed to get time: " << strerror(e)); + Transport::error(e); + return; + } + + setDatetime(now); +} + +DateCategory::DateCategory(time_t datetime) + : ParserCategory(), + mDayOfWeek(Sun), + mDayOfMonth(), + mMonth(Jan), + mYear(0), + mHour(0), + mMin(0), + mSec(0) +{ + setDatetime(datetime); +} + +DateCategory::DateCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), + mDayOfWeek(Sun), + mDayOfMonth(), + mMonth(Jan), + mYear(0), + mHour(0), + mMin(0), + mSec(0) +{} + +DateCategory::DateCategory(const DateCategory& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mDayOfWeek(rhs.mDayOfWeek), + mDayOfMonth(rhs.mDayOfMonth), + mMonth(rhs.mMonth), + mYear(rhs.mYear), + mHour(rhs.mHour), + mMin(rhs.mMin), + mSec(rhs.mSec) +{} + +DateCategory& +DateCategory::operator=(const DateCategory& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mDayOfWeek = rhs.mDayOfWeek; + mDayOfMonth = rhs.mDayOfMonth; + mMonth = rhs.mMonth; + mYear = rhs.mYear; + mHour = rhs.mHour; + mMin = rhs.mMin; + mSec = rhs.mSec; + } + return *this; +} + +bool +DateCategory::setDatetime(time_t datetime) +{ + struct tm gmt; +#if defined(WIN32) || defined(__sun) + struct tm *gmtp = gmtime(&datetime); + if (gmtp == 0) + { + int e = getErrno(); + DebugLog (<< "Failed to convert to gmt: " << strerror(e)); + Transport::error(e); + return false; + } + memcpy(&gmt,gmtp,sizeof(gmt)); +#else + if (gmtime_r(&datetime, &gmt) == 0) + { + int e = getErrno(); + DebugLog (<< "Failed to convert to gmt: " << strerror(e)); + Transport::error(e); + return false; + } +#endif + + mDayOfWeek = static_cast<DayOfWeek>(gmt.tm_wday); + mDayOfMonth = gmt.tm_mday; + mMonth = static_cast<Month>(gmt.tm_mon); + mYear = gmt.tm_year + 1900; + mHour = gmt.tm_hour; + mMin = gmt.tm_min; + mSec = gmt.tm_sec; + DebugLog (<< "Set date: day=" << mDayOfWeek + << " month=" << mMonth + << " year=" << mYear + << " " << mHour << ":" << mMin << ":" << mSec); + return true; +} + +/* ANSI-C code produced by gperf version 2.7.2 */ +/* Command-line: gperf -L ANSI-C -t -k '*' dayofweek.gperf */ +/** + @internal +*/ +struct days { char name[32]; DayOfWeek day; }; + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +dayofweek_hash (register const char *str, register unsigned int len) +{ + static unsigned char asso_values[] = + { + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 1, 13, 13, 13, 13, 13, 13, 5, 13, 13, + 13, 13, 13, 2, 0, 13, 13, 7, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 7, 13, 13, + 0, 0, 13, 13, 4, 0, 13, 13, 13, 13, + 0, 0, 13, 13, 0, 13, 0, 0, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13 + }; + register int hval = len; + + switch (hval) + { + default: /*FALLTHRU*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHRU*/ + case 2: + hval += asso_values[(unsigned char)str[1]]; + /*FALLTHRU*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval; +} + +#ifdef __GNUC__ +__inline +#endif +struct days * +in_dayofweek_word_set (register const char *str, register unsigned int len) +{ + static const unsigned int MIN_WORD_LENGTH = 3; + static const unsigned int MAX_WORD_LENGTH = 3; + static const int MAX_HASH_VALUE = 12; + + static struct days wordlist[] = + { + {""}, {""}, {""}, + {"Tue", Tue}, + {"Fri", Fri}, + {"Sun", Sun}, + {""}, + {"Thu", Thu}, + {"Mon", Mon}, + {""}, + {"Wed", Wed}, + {""}, + {"Sat", Sat} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = dayofweek_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &wordlist[key]; + } + } + return 0; +} + +DayOfWeek +DateCategory::DayOfWeekFromData(const Data& dow) +{ + static const unsigned int MIN_WORD_LENGTH = 3; + static const unsigned int MAX_WORD_LENGTH = 3; + static const int MAX_HASH_VALUE = 12; + + register const char *str = dow.data(); + register Data::size_type len = dow.size(); + + static struct days wordlist[] = + { + {""}, {""}, {""}, + {"Tue", Tue}, + {"Fri", Fri}, + {"Sun", Sun}, + {""}, + {"Thu", Thu}, + {"Mon", Mon}, + {""}, + {"Wed", Wed}, + {""}, + {"Sat", Sat} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = dayofweek_hash (str, (unsigned int)len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (*str == *s && !strncmp (str+1, s+1, len-1)) + { + return wordlist[key].day; + } + } + } + return Sun; +} + +/* ANSI-C code produced by gperf version 2.7.2 */ +/* Command-line: gperf -L ANSI-C -t -k '*' month.gperf */ +/** + @internal +*/ +struct months { char name[32]; Month type; }; + +/* maximum key range = 31, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +month_hash (register const char *str, register unsigned int len) +{ + static unsigned char asso_values[] = + { + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 15, 34, 34, 8, 34, + 5, 34, 34, 34, 0, 34, 34, 10, 3, 14, + 34, 34, 34, 9, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 10, 0, 0, + 34, 0, 34, 10, 34, 34, 34, 34, 4, 34, + 0, 0, 0, 34, 0, 34, 0, 0, 0, 34, + 34, 10, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34 + }; + register int hval = len; + + switch (hval) + { + default: /*FALLTHRU*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHRU*/ + case 2: + hval += asso_values[(unsigned char)str[1]]; + /*FALLTHRU*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval; +} + +Month +DateCategory::MonthFromData(const Data& mon) +{ + static const unsigned int MIN_WORD_LENGTH = 3; + static const unsigned int MAX_WORD_LENGTH = 3; + static const int MAX_HASH_VALUE = 33; + + register const char *str = mon.data(); + register Data::size_type len = mon.size(); + + static struct months wordlist[] = + { + {""}, {""}, {""}, + {"Jun", Jun}, + {""}, {""}, + {"Nov", Nov}, + {"Jul", Jul}, + {"Feb", Feb}, + {""}, {""}, + {"Dec", Dec}, + {"Sep", Sep}, + {"Jan", Jan}, + {""}, {""}, {""}, + {"Oct", Oct}, + {"Apr", Apr}, + {""}, {""}, {""}, {""}, + {"Mar", Mar}, + {""}, {""}, {""}, {""}, + {"Aug", Aug}, + {""}, {""}, {""}, {""}, + {"May", May} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = month_hash (str, (unsigned int)len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (*str == *s && !strncmp (str + 1, s + 1, mon.size()-1)) + return wordlist[key].type; + } + } + return Jan; +} + +const DayOfWeek& +DateCategory::dayOfWeek() const +{ + checkParsed(); + return mDayOfWeek; +} + +int& +DateCategory::dayOfMonth() +{ + checkParsed(); + return mDayOfMonth; +} + +int +DateCategory::dayOfMonth() const +{ + checkParsed(); + return mDayOfMonth; +} + +Month& +DateCategory::month() +{ + checkParsed(); + return mMonth; +} + +Month +DateCategory::month() const +{ + checkParsed(); + return mMonth; +} + +int& +DateCategory::year() +{ + checkParsed(); + return mYear; +} + +int +DateCategory::year() const +{ + checkParsed(); + return mYear; +} + +int& +DateCategory::hour() +{ + checkParsed(); + return mHour; +} + +int +DateCategory::hour() const +{ + checkParsed(); + return mHour; +} + +int& +DateCategory::minute() +{ + checkParsed(); + return mMin; +} + +int +DateCategory::minute() const +{ + checkParsed(); + return mMin; +} + +int& +DateCategory::second() +{ + checkParsed(); + return mSec; +} + +int +DateCategory::second() const +{ + checkParsed(); + return mSec; +} + +void +DateCategory::parse(ParseBuffer& pb) +{ + // Mon, 04 Nov 2002 17:34:15 GMT + + const char* anchor = pb.skipWhitespace(); + + pb.skipToChar(Symbols::COMMA[0]); + Data dayOfWeek; + pb.data(dayOfWeek, anchor); + mDayOfWeek = DateCategory::DayOfWeekFromData(dayOfWeek); + + pb.skipChar(Symbols::COMMA[0]); + + pb.skipWhitespace(); + + mDayOfMonth = pb.integer(); + + anchor = pb.skipWhitespace(); + pb.skipNonWhitespace(); + + Data month; + pb.data(month, anchor); + mMonth = DateCategory::MonthFromData(month); + + pb.skipWhitespace(); + mYear = pb.integer(); + + pb.skipWhitespace(); + + mHour = pb.integer(); + pb.skipChar(Symbols::COLON[0]); + mMin = pb.integer(); + pb.skipChar(Symbols::COLON[0]); + mSec = pb.integer(); + + pb.skipWhitespace(); + pb.skipChar('G'); + pb.skipChar('M'); + pb.skipChar('T'); + + pb.skipWhitespace(); + pb.assertEof(); +} + +ParserCategory* +DateCategory::clone() const +{ + return new DateCategory(*this); +} + +ParserCategory* +DateCategory::clone(void* location) const +{ + return new (location) DateCategory(*this); +} + +ParserCategory* +DateCategory::clone(PoolBase* pool) const +{ + return new (pool) DateCategory(*this, pool); +} + +static void pad2(const int x, EncodeStream& str) +{ + if (x < 10) + { + str << Symbols::ZERO[0]; + } + str << x; +} + +EncodeStream& +DateCategory::encodeParsed(EncodeStream& str) const +{ + str << DayOfWeekData[mDayOfWeek] // Mon + << Symbols::COMMA[0] << Symbols::SPACE[0]; + + pad2(mDayOfMonth, str); // 04 + + str << Symbols::SPACE[0] + << MonthData[mMonth] << Symbols::SPACE[0] // Nov + << mYear << Symbols::SPACE[0]; // 2002 + + pad2(mHour, str); + str << Symbols::COLON[0]; + pad2(mMin, str); + str << Symbols::COLON[0]; + pad2(mSec, str); + str << " GMT"; + + return str; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/DateCategory.hxx b/src/libs/resiprocate/resip/stack/DateCategory.hxx new file mode 100644 index 00000000..a31ed049 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DateCategory.hxx @@ -0,0 +1,149 @@ +#if !defined(RESIP_DATE_CATEGORY_HXX) +#define RESIP_DATE_CATEGORY_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" + +namespace resip +{ + +//==================== +// DateCategory: +//==================== + +enum DayOfWeek { + Sun = 0, + Mon, + Tue, + Wed, + Thu, + Fri, + Sat +}; + +extern Data DayOfWeekData[]; +extern Data MonthData[]; + +enum Month { + Jan = 0, + Feb, + Mar, + Apr, + May, + Jun, + Jul, + Aug, + Sep, + Oct, + Nov, + Dec +}; + +/** + @ingroup sip_grammar + @brief Represents the "SIP-date" element in the RFC 3261 grammar. +*/ +class DateCategory : public ParserCategory +{ + public: + enum {commaHandling = NoCommaTokenizing}; + + DateCategory(); + DateCategory(time_t datetime); + DateCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + DateCategory(const DateCategory& orig, + PoolBase* pool=0); + DateCategory& operator=(const DateCategory&); + + virtual bool setDatetime(time_t datetime); + + virtual void parse(ParseBuffer& pb); + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + + static DayOfWeek DayOfWeekFromData(const Data&); + static Month MonthFromData(const Data&); + + const DayOfWeek& dayOfWeek() const; + int& dayOfMonth(); + int dayOfMonth() const; + Month& month(); + Month month() const; + int& year(); + int year() const; + int& hour(); + int hour() const; + int& minute(); + int minute() const; + int& second(); + int second() const; + + private: + enum DayOfWeek mDayOfWeek; + int mDayOfMonth; + enum Month mMonth; + int mYear; + int mHour; + int mMin; + int mSec; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/DeprecatedDialog.cxx b/src/libs/resiprocate/resip/stack/DeprecatedDialog.cxx new file mode 100644 index 00000000..bf27e901 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DeprecatedDialog.cxx @@ -0,0 +1,817 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <iostream> +#include "resip/stack/DeprecatedDialog.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Uri.hxx" +#include "resip/stack/NameAddr.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + + +DeprecatedDialog::DeprecatedDialog(const NameAddr& localContact) + : mContact(localContact), + mCreated(false), + mEarly(false), + mRouteSet(), + mRemoteTarget(), + mRemoteSequence(0), + mRemoteEmpty(true), + mLocalSequence(0), + mLocalEmpty(true), + mCallId(), + mLocalTag(), + mRemoteTag(), + mRemoteUri(), + mLocalUri() +{ + // .kw. members "secure" and "expireyTimeAbsoluteMs" are not initialized! +} + +SipMessage* +DeprecatedDialog::makeResponse(const SipMessage& request, int code) +{ + assert( code >= 100 ); + + if ( (!mCreated) && (code < 300) && (code > 100) ) + { + assert (code > 100); + assert (code < 300); + assert(request.isRequest()); + assert(request.header(h_RequestLine).getMethod() == INVITE || + request.header(h_RequestLine).getMethod() == SUBSCRIBE || + request.header(h_RequestLine).getMethod() == PUBLISH); + + assert (request.header(h_Contacts).size() == 1); + + SipMessage* response = Helper::makeResponse(request, code, mContact); + if (request.exists(h_RecordRoutes)) + { + mRouteSet = request.header(h_RecordRoutes); + } + + if (!request.exists(h_Contacts) && request.header(h_Contacts).size() != 1) + { + InfoLog (<< "Request doesn't have a contact header or more than one contact, so can't create dialog"); + DebugLog (<< request); + throw Exception("Invalid or missing contact header in request", __FILE__,__LINE__); + } + + mRemoteTarget = request.header(h_Contacts).front(); + mRemoteSequence = request.header(h_CSeq).sequence(); + mRemoteEmpty = false; + mLocalSequence = 0; + mLocalEmpty = true; + mCallId = request.header(h_CallId); + response->header(h_To).param(p_tag) = Helper::computeTag(Helper::tagSize); + assert (response->header(h_To).exists(p_tag)); + mLocalTag = response->header(h_To).param(p_tag); // from response + if (request.header(h_From).exists(p_tag)) // 2543 compat + { + mRemoteTag = request.header(h_From).param(p_tag); + } + + mRemoteUri = request.header(h_From); + mLocalUri = request.header(h_To); + + mDialogId = mCallId; + mDialogId.param(p_toTag) = mLocalTag; + mDialogId.param(p_fromTag) = mRemoteTag; + + mEarly = (code < 200); + mCreated = true; + + return response; + } + else + { + SipMessage* response = Helper::makeResponse(request, code, mContact); + if (mCreated) + { + response->header(h_To).param(p_tag) = mLocalTag; + } + //DebugLog(<< "Created response within dialog: " << *response); + return response; + } +} + + +void +DeprecatedDialog::createDialogAsUAC(const SipMessage& msg) +{ + if (!mCreated) + { + if(msg.isResponse()) + { + const SipMessage& response = msg; + + int code = response.header(h_StatusLine).statusCode(); + mEarly = (code > 100 && code < 200); + + if (code >= 200 && code < 300) + { + if (!response.exists(h_Contacts) || response.header(h_Contacts).size() != 1) + { + InfoLog (<< "Response doesn't have a contact header or more than one contact, so can't create dialog"); + DebugLog (<< response); + throw Exception("Invalid or missing contact header in message", __FILE__,__LINE__); + } + } + + // reverse order from response + if (response.exists(h_RecordRoutes)) + { + mRouteSet = response.header(h_RecordRoutes).reverse(); + } + + if (response.exists(h_Contacts) && !response.header(h_Contacts).empty()) + { + mRemoteTarget = response.header(h_Contacts).front(); + } + + mRemoteSequence = 0; + mRemoteEmpty = true; + mLocalSequence = response.header(h_CSeq).sequence(); + mLocalEmpty = false; + mCallId = response.header(h_CallId); + if ( response.header(h_From).exists(p_tag) ) // 2543 compat + { + mLocalTag = response.header(h_From).param(p_tag); + } + if ( response.header(h_To).exists(p_tag) ) // 2543 compat + { + mRemoteTag = response.header(h_To).param(p_tag); + } + mRemoteUri = response.header(h_To); + mLocalUri = response.header(h_From); + + mDialogId = mCallId; + mDialogId.param(p_toTag) = mLocalTag; + mDialogId.param(p_fromTag) = mRemoteTag; + + mCreated = true; + } + else if (msg.isRequest() && msg.header(h_CSeq).method() == NOTIFY) + { + const SipMessage& notify = msg; + if (notify.exists(h_RecordRoutes)) + { + mRouteSet = notify.header(h_RecordRoutes); + } + + if (!notify.exists(h_Contacts) && notify.header(h_Contacts).size() != 1) + { + InfoLog (<< "Notify doesn't have a contact header or more than one contact, so can't create dialog"); + DebugLog (<< notify); + throw Exception("Invalid or missing contact header in notify", __FILE__,__LINE__); + } + + mRemoteTarget = notify.header(h_Contacts).front(); + mRemoteSequence = notify.header(h_CSeq).sequence(); + mRemoteEmpty = false; + mLocalSequence = 0; + mLocalEmpty = true; + mCallId = notify.header(h_CallId); + if (notify.header(h_To).exists(p_tag)) + { + mLocalTag = notify.header(h_To).param(p_tag); + } + if (notify.header(h_From).exists(p_tag)) // 2543 compat + { + mRemoteTag = notify.header(h_From).param(p_tag); + } + + mRemoteUri = notify.header(h_From); + mLocalUri = notify.header(h_To); + + mDialogId = mCallId; + mDialogId.param(p_toTag) = mLocalTag; + mDialogId.param(p_fromTag) = mRemoteTag; + + mCreated = true; + mEarly = false; + } + } + else if (msg.isResponse()) + { + mEarly = (msg.header(h_StatusLine).statusCode() < 200 && + msg.header(h_StatusLine).statusCode() > 100); + + // don't update target for register since contact is not a target + if ( msg.header(h_CSeq).method() != REGISTER ) + { + targetRefreshResponse(msg); + } + } +} + +void +DeprecatedDialog::targetRefreshResponse(const SipMessage& response) +{ + if (response.exists(h_Contacts) && response.header(h_Contacts).size() == 1) + { + mRemoteTarget = response.header(h_Contacts).front(); + } +} + +int +DeprecatedDialog::targetRefreshRequest(const SipMessage& request) +{ + assert (request.header(h_RequestLine).getMethod() != CANCEL); + if (request.header(h_RequestLine).getMethod() != ACK) + { + unsigned long cseq = request.header(h_CSeq).sequence(); + + if (mRemoteEmpty) + { + mRemoteSequence = cseq; + mRemoteEmpty = false; + } + else if (cseq < mRemoteSequence) + { + InfoLog (<< "Got a cseq out of sequence: " << cseq << " < " << mRemoteSequence); + throw Exception("out of order", __FILE__,__LINE__); + } + else + { + mRemoteSequence = cseq; + } + + if (request.exists(h_Contacts) && request.header(h_Contacts).size() == 1) + { + mRemoteTarget = request.header(h_Contacts).front(); + } + else + { + InfoLog (<< "Request doesn't have a contact header or more than one contact, so can't create dialog"); + DebugLog (<< request); + throw Exception("Invalid or missing contact header in message", __FILE__,__LINE__); + } + } + + return 0; +} + +void +DeprecatedDialog::updateRequest(SipMessage& request) +{ + assert (request.isRequest()); + if (mCreated) + { + request.header(h_RequestLine).uri() = mRemoteTarget.uri(); + request.header(h_To) = mRemoteUri; + if ( !mRemoteTag.empty() ) + { + request.header(h_To).param(p_tag) = mRemoteTag; + } + request.header(h_From) = mLocalUri; + if ( !mLocalTag.empty() ) + { + request.header(h_From).param(p_tag) = mLocalTag; + } + request.header(h_CallId) = mCallId; + request.header(h_Routes) = mRouteSet; + request.header(h_Contacts).clear(); + request.header(h_Contacts).push_back(mContact); + copyCSeq(request); + incrementCSeq(request); + + request.header(h_MaxForwards).value() = 70; + + Via via; + via.param(p_branch); // will create the branch + request.header(h_Vias).clear(); + request.header(h_Vias).push_back(via); + + request.clearForceTarget(); + Helper::processStrictRoute(request); + } + else + { + DebugLog (<< "Updating a request when not in a dialog yet"); + } +} + +void +DeprecatedDialog::makeResponse(const SipMessage& request, SipMessage& response, int code) +{ + assert(request.isRequest()); + if ( (!mCreated) && (code < 300) && (code > 100) ) + { + assert(request.header(h_RequestLine).getMethod() == INVITE || + request.header(h_RequestLine).getMethod() == SUBSCRIBE); + assert (request.header(h_Contacts).size() == 1); + + Helper::makeResponse(response, request, code, mContact); + response.header(h_To).param(p_tag) = Helper::computeTag(Helper::tagSize); + + if (request.exists(h_RecordRoutes)) + { + mRouteSet = request.header(h_RecordRoutes); + } + + if (!request.exists(h_Contacts) && request.header(h_Contacts).size() != 1) + { + InfoLog (<< "Request doesn't have a contact header or more than one contact, so can't create dialog"); + DebugLog (<< request); + throw Exception("Invalid or missing contact header in request", __FILE__,__LINE__); + } + + mRemoteTarget = request.header(h_Contacts).front(); + mRemoteSequence = request.header(h_CSeq).sequence(); + mRemoteEmpty = false; + mLocalSequence = 0; + mLocalEmpty = true; + mCallId = request.header(h_CallId); + assert (response.const_header(h_To).exists(p_tag)); + mLocalTag = response.header(h_To).param(p_tag); // from response + if (request.header(h_From).exists(p_tag)) // 2543 compat + { + mRemoteTag = request.header(h_From).param(p_tag); + } + + mRemoteUri = request.header(h_From); + mLocalUri = request.header(h_To); + + mDialogId = mCallId; + mDialogId.param(p_toTag) = mLocalTag; + mDialogId.param(p_fromTag) = mRemoteTag; + + mEarly = (code > 100 && code < 200); + + mCreated = true; + } + else + { + Helper::makeResponse(response, request, code, mContact); + if (mCreated) + { + response.header(h_To).param(p_tag) = mLocalTag; + mEarly = false; + } + } +} + + +SipMessage* +DeprecatedDialog::makeInitialRegister(const NameAddr& registrar, const NameAddr& aor) +{ + SipMessage* msg = Helper::makeRegister( registrar, aor, mContact ); + assert( msg ); + + mRequestUri = msg->const_header(h_RequestLine).uri(); + mLocalEmpty = false; + mLocalSequence = msg->const_header(h_CSeq).sequence(); + mCallId = msg->const_header(h_CallId); + assert(msg->const_header(h_From).exists(p_tag)); + mLocalTag = msg->const_header(h_From).param(p_tag); + mRemoteUri = msg->const_header(h_To); + mLocalUri = msg->const_header(h_From); + mCreated = true; + + mRemoteTarget = mRemoteUri; + + return msg; +} + + +SipMessage* +DeprecatedDialog::makeInitialSubscribe(const NameAddr& target, const NameAddr& from) +{ + SipMessage* msg = Helper::makeSubscribe( target, from, mContact ); + assert( msg ); + + mRequestUri = msg->const_header(h_RequestLine).uri(); + mLocalEmpty = false; + mLocalSequence = msg->const_header(h_CSeq).sequence(); + mCallId = msg->const_header(h_CallId); + assert(msg->const_header(h_From).exists(p_tag)); + mLocalTag = msg->const_header(h_From).param(p_tag); + mRemoteUri = msg->const_header(h_To); + mLocalUri = msg->const_header(h_From); + + return msg; +} + + +SipMessage* +DeprecatedDialog::makeInitialPublish(const NameAddr& target, const NameAddr& from) +{ + SipMessage* msg = Helper::makePublish( target, from, mContact ); + assert( msg ); + + mRequestUri = msg->const_header(h_RequestLine).uri(); + mLocalEmpty = false; + mLocalSequence = msg->const_header(h_CSeq).sequence(); + mCallId = msg->const_header(h_CallId); + assert(msg->const_header(h_From).exists(p_tag)); + mLocalTag = msg->const_header(h_From).param(p_tag); + mRemoteUri = msg->const_header(h_To); + mLocalUri = msg->const_header(h_From); + + return msg; +} + + +SipMessage* +DeprecatedDialog::makeInitialMessage(const NameAddr& target, const NameAddr& from) +{ + SipMessage* msg = Helper::makeMessage( target, from, mContact ); + assert( msg ); + + mRequestUri = msg->const_header(h_RequestLine).uri(); + mLocalEmpty = false; + mLocalSequence = msg->const_header(h_CSeq).sequence(); + mCallId = msg->const_header(h_CallId); + assert(msg->const_header(h_From).exists(p_tag)); + mLocalTag = msg->const_header(h_From).param(p_tag); + mRemoteUri = msg->const_header(h_To); + mLocalUri = msg->const_header(h_From); + + return msg; +} + + +SipMessage* +DeprecatedDialog::makeInitialInvite(const NameAddr& target, const NameAddr& from) +{ + SipMessage* msg = Helper::makeInvite( target, from, mContact ); + assert( msg ); + + mRequestUri = msg->const_header(h_RequestLine).uri(); + mLocalEmpty = false; + mLocalSequence = msg->const_header(h_CSeq).sequence(); + mCallId = msg->const_header(h_CallId); + assert(msg->const_header(h_From).exists(p_tag)); + mLocalTag = msg->const_header(h_From).param(p_tag); + mRemoteUri = msg->const_header(h_To); + mLocalUri = msg->const_header(h_From); + + return msg; +} + + +SipMessage* +DeprecatedDialog::makeInvite() +{ + SipMessage* request = makeRequestInternal(INVITE); + incrementCSeq(*request); + DebugLog(<< "DeprecatedDialog::makeInvite: " << *request); + return request; +} + +SipMessage* +DeprecatedDialog::makeUpdate() +{ + SipMessage* request = makeRequestInternal(UPDATE); + incrementCSeq(*request); + DebugLog(<< "DeprecatedDialog::makeUpdate: " << *request); + return request; +} + +SipMessage* +DeprecatedDialog::makeRegister() +{ + SipMessage* request = makeRequestInternal(REGISTER); + incrementCSeq(*request); + DebugLog(<< "DeprecatedDialog::makeRegister: " << *request); + return request; +} + +SipMessage* +DeprecatedDialog::makeSubscribe() +{ + SipMessage* request = makeRequestInternal(SUBSCRIBE); + incrementCSeq(*request); + DebugLog(<< "DeprecatedDialog::makeSubscribe: " << *request); + return request; +} + +SipMessage* +DeprecatedDialog::makeBye() +{ + SipMessage* request = makeRequestInternal(BYE); + incrementCSeq(*request); + + return request; +} + + +SipMessage* +DeprecatedDialog::makeRefer(const NameAddr& referTo) +{ + SipMessage* request = makeRequestInternal(REFER); + request->header(h_ReferTo) = referTo; + request->header(h_ReferredBy) = mLocalUri; + incrementCSeq(*request); + return request; +} + +SipMessage* +DeprecatedDialog::makeNotify() +{ + SipMessage* request = makeRequestInternal(NOTIFY); + incrementCSeq(*request); + return request; +} + + +SipMessage* +DeprecatedDialog::makeOptions() +{ + SipMessage* request = makeRequestInternal(OPTIONS); + incrementCSeq(*request); + return request; +} + +SipMessage* +DeprecatedDialog::makePublish() +{ + SipMessage* request = makeRequestInternal(PUBLISH); + incrementCSeq(*request); + return request; +} + +SipMessage* +DeprecatedDialog::makeRequest(resip::MethodTypes method) +{ + assert(method != ACK); + assert(method != CANCEL); + + SipMessage* request = makeRequestInternal(method); + incrementCSeq(*request); + return request; +} + +SipMessage* +DeprecatedDialog::makeAck(const SipMessage& original) +{ + SipMessage* request = makeRequestInternal(ACK); + copyCSeq(*request); + + // !dcm! should we copy the authorizations? + // !jf! will this do the right thing if these headers weren't in original + // we should be able to store this stuff in the DeprecatedDialog and not need to pass + // in the original + if (original.exists(h_ProxyAuthorizations)) + { + request->header(h_ProxyAuthorizations) = original.header(h_ProxyAuthorizations); + } + if (original.exists(h_Authorizations)) + { + request->header(h_Authorizations) = original.header(h_Authorizations); + } + request->header(h_CSeq).sequence() = original.header(h_CSeq).sequence(); + return request; +} + +SipMessage* +DeprecatedDialog::makeAck() +{ + SipMessage* request = makeRequestInternal(ACK); + copyCSeq(*request); + return request; +} + +SipMessage* +DeprecatedDialog::makeCancel(const SipMessage& request) +{ + assert (request.header(h_Vias).size() >= 1); + assert (request.header(h_RequestLine).getMethod() == INVITE); + + SipMessage* cancel = new SipMessage; + + cancel->header(h_RequestLine) = request.header(h_RequestLine); + cancel->header(h_RequestLine).method() = CANCEL; + + cancel->header(h_CallId) = request.header(h_CallId); + cancel->header(h_To) = request.header(h_To); + cancel->header(h_From) = request.header(h_From); + cancel->header(h_CSeq) = request.header(h_CSeq); + cancel->header(h_CSeq).method() = CANCEL; + cancel->header(h_Vias).push_back(request.header(h_Vias).front()); + + return cancel; +} + + +CallId +DeprecatedDialog::makeReplaces() +{ + return mDialogId; +} + +void +DeprecatedDialog::clear() +{ + mCreated = false; + mEarly = false; + + mRouteSet.clear(); + mRemoteTarget = NameAddr(); + mRemoteSequence = 0; + mRemoteEmpty = true; + mLocalSequence = 0; + mLocalEmpty = true; + mCallId.value() = Data::Empty; + mLocalTag = Data::Empty; + mRemoteTag = Data::Empty; + mRemoteUri = NameAddr(); + mLocalUri = NameAddr(); +} + +SipMessage* +DeprecatedDialog::makeRequestInternal(MethodTypes method) +{ + SipMessage* request = new SipMessage; + RequestLine rLine(method); + + if (!mCreated) + { + rLine.uri() = mRequestUri; + } + else + { + rLine.uri() = mRemoteTarget.uri(); + } + + request->header(h_RequestLine) = rLine; + request->header(h_To) = mRemoteUri; + if ( !mRemoteTag.empty() ) + { + request->header(h_To).param(p_tag) = mRemoteTag; + } + request->header(h_From) = mLocalUri; + if ( !mLocalTag.empty() ) + { + request->header(h_From).param(p_tag) = mLocalTag; + } + request->header(h_CallId) = mCallId; + request->header(h_Routes) = mRouteSet; + request->header(h_Contacts).push_back(mContact); + request->header(h_CSeq).method() = method; + copyCSeq(*request); + request->header(h_MaxForwards).value() = 70; + + Via via; + via.param(p_branch); // will create the branch + request->header(h_Vias).push_front(via); + + Helper::processStrictRoute(*request); + return request; +} + +void +DeprecatedDialog::copyCSeq(SipMessage& request) +{ + if (mLocalEmpty) + { + mLocalSequence = 1; + mLocalEmpty = false; + } + request.header(h_CSeq).sequence() = mLocalSequence; +} + +void +DeprecatedDialog::incrementCSeq(SipMessage& request) +{ + if (mLocalEmpty) + { + mLocalSequence = 1; + mLocalEmpty = false; + } + //DebugLog ( << "mLocalSequence: " << mLocalSequence); + request.header(h_CSeq).sequence() = ++mLocalSequence; +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const DeprecatedDialog& d) +{ + strm << "DeprecatedDialog: [" << d.dialogId() + << " created=" << d.mCreated + << ",remoteTarget=" << d.mRemoteTarget + << ", routeset=" << Inserter(d.mRouteSet) + << ",remoteSeq=" << d.mRemoteSequence + << ",remote=" << d.mRemoteUri + << ",remoteTag=" << d.mRemoteTag + << ",localSeq=" << d.mLocalSequence + << ",local=" << d.mLocalUri + << ",localTag=" << d.mLocalTag + << "]"; + return strm; +} + +Data +DeprecatedDialog::dialogId(const SipMessage& msg) +{ + CallID id(msg.header(h_CallId)); + if ((msg.isRequest() && msg.isExternal()) || + (msg.isResponse() && !msg.isExternal())) + { + if (msg.header(h_To).exists(p_tag)) + { + id.param(p_toTag) = msg.header(h_To).param(p_tag); + } + if (msg.header(h_From).exists(p_tag)) + { + id.param(p_fromTag) = msg.header(h_From).param(p_tag); + } + } + else + { + if (msg.header(h_From).exists(p_tag)) + { + id.param(p_toTag) = msg.header(h_From).param(p_tag); + } + if (msg.header(h_To).exists(p_tag)) + { + id.param(p_fromTag) = msg.header(h_To).param(p_tag); + } + } + return Data::from(id); +} + + +const Data +DeprecatedDialog::dialogId() const +{ + return Data::from(mDialogId); +} + + +void +DeprecatedDialog::setExpirySeconds( int secondsInFuture ) +{ + expireyTimeAbsoluteMs = Timer::getTimeMs() + 1000*secondsInFuture; +} + + +int +DeprecatedDialog::getExpirySeconds() +{ + // !cj! TODO - may be bugs here when result is negative + UInt64 delta = ( expireyTimeAbsoluteMs - Timer::getTimeMs() )/1000; + + int ret = (int)delta; + return ret; +} + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/DeprecatedDialog.hxx b/src/libs/resiprocate/resip/stack/DeprecatedDialog.hxx new file mode 100644 index 00000000..ef697958 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DeprecatedDialog.hxx @@ -0,0 +1,196 @@ +#if !defined(RESIP_DIALOG_HXX) +#define RESIP_DIALOG_HXX + +#include <iosfwd> +#include "resip/stack/MethodTypes.hxx" +#include "resip/stack/NameAddr.hxx" +#include "resip/stack/Uri.hxx" +#include "resip/stack/CallId.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/Timer.hxx" + +namespace resip +{ + +class SipMessage; +class NameAddr; +class CallID; + +class DeprecatedDialog +{ + public: + class Exception : public BaseException + { + public: + Exception( const resip::Data& msg, + const resip::Data& file, + const int line): BaseException(msg,file,line){} + const char* name() const { return "Dialog::Exception"; } + }; + + // pass in a contact for this location e.g. "sip:local@domain:5060" + DeprecatedDialog(const NameAddr& localContact); + + // If a dialog is not yet created, make a dialog or early dialog as + // follows. Otherwise, just make response from the dialog state + // Used by the UAS to create a dialog or early dialog, will return a 1xx(code) + // UAS should call this upon receiving the invite/subscribe. + // This should not be called twice if the UAS sends back a 180 and a 200, + // it should call it for the 180 and then use Dialog::makeResponse to make + // the 200 + SipMessage* makeResponse(const SipMessage& request, int code=200); + + // This happens when a dialog gets created on a UAC when + // a UAC receives a response that creates a dialog. Also works for NOTIFY + // requests which create a dialog + void createDialogAsUAC(const SipMessage& response); + + // Called when a 2xx response is received in an existing dialog + // Replace the _remoteTarget with uri from Contact header in response + void targetRefreshResponse(const SipMessage& response); + + // Called when a request is received in an existing dialog + // return status code of response to generate - 0 if ok + int targetRefreshRequest(const SipMessage& request); + + // given a template of a request, update the relevant fields based on this + void updateRequest(SipMessage& msg); + + // For UAS, make a response and create the dialog if necessary + void makeResponse(const SipMessage& request, SipMessage& response, int code=200); + + bool isCreated() const { return mCreated; } + bool isEarly() const { return mEarly; } + + static Data dialogId(const SipMessage& msg); + const Data dialogId() const; + const CallID& getCallId() const { return mCallId; } + const NameAddr& getRemoteTarget() const { return mRemoteTarget; } + //const Data& getLocalTag() const { return mLocalTag; } + const Data& getRemoteTag() const { return mRemoteTag; } + + // For creating request which do not form a dialog but whose response + // might create a dialog + SipMessage* makeInitialRegister(const NameAddr& registrar, const NameAddr& from); + SipMessage* makeInitialSubscribe(const NameAddr& target, const NameAddr& from); + SipMessage* makeInitialPublish(const NameAddr& target, const NameAddr& from); + SipMessage* makeInitialInvite(const NameAddr& target, const NameAddr& from); + SipMessage* makeInitialMessage(const NameAddr& target, const NameAddr& from); + + // For creating requests within a dialog + SipMessage* makeInvite(); + SipMessage* makeUpdate(); + SipMessage* makeRegister(); + SipMessage* makeSubscribe(); + SipMessage* makeBye(); + SipMessage* makeRefer(const NameAddr& referTo); + SipMessage* makeNotify(); + SipMessage* makeOptions(); + SipMessage* makePublish(); + SipMessage* makeAck(); + SipMessage* makeAck(const SipMessage& request); + SipMessage* makeCancel(const SipMessage& request); + SipMessage* makeRequest(MethodTypes method); + CallID makeReplaces(); + + // resets to an empty dialog with no state + void clear(); + + // set how many seconds in the futre this dialog will expire + void setExpirySeconds( int secondsInFuture ); + int getExpirySeconds(); // get number Seconds till this expires, it can + // be negative + + + private: + SipMessage* makeRequestInternal(MethodTypes method); + void incrementCSeq(SipMessage& request); + void copyCSeq(SipMessage& request); + + NameAddr mContact; // for this UA + + // Dialog State + bool mCreated; + bool mEarly; + + Uri mRequestUri; + + NameAddrs mRouteSet; + NameAddr mRemoteTarget; + + unsigned long mRemoteSequence; + bool mRemoteEmpty; + unsigned long mLocalSequence; + bool mLocalEmpty; + + CallID mCallId; + Data mLocalTag; + Data mRemoteTag; + CallID mDialogId; + + NameAddr mRemoteUri; + NameAddr mLocalUri; + + bool secure; // indicates the messages in this Dialog must use TLS + + UInt64 expireyTimeAbsoluteMs; + + friend EncodeStream& operator<<(EncodeStream&, const DeprecatedDialog&); +}; + +EncodeStream& +operator<<(EncodeStream& strm, const DeprecatedDialog& d); + +} // namespace Cathay + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/DnsInterface.cxx b/src/libs/resiprocate/resip/stack/DnsInterface.cxx new file mode 100644 index 00000000..ea62b676 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DnsInterface.cxx @@ -0,0 +1,209 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#ifndef WIN32 +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#ifndef __CYGWIN__ +# include <netinet/in.h> +# include <arpa/nameser.h> +# include <resolv.h> +#endif +#endif + +#include "rutil/compat.hxx" +#include "rutil/Logger.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/Socket.hxx" + +#include "rutil/dns/DnsStub.hxx" +#include "rutil/dns/RRVip.hxx" +#include "resip/stack/DnsInterface.hxx" +#include "rutil/dns/DnsHandler.hxx" +#include "resip/stack/DnsResult.hxx" + +//#include "rutil/dns/ExternalDnsFactory.hxx" +#include "rutil/WinLeakCheck.hxx" + + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS + +DnsInterface::DnsInterface(DnsStub& dnsStub) : + mDnsStub(dnsStub) +{ + +#ifdef USE_DNS_VIP + mDnsStub.setResultTransform(&mVip); +#endif +} + +DnsInterface::~DnsInterface() +{ +} + +static Data UdpNAPTRType("SIP+D2U"); +static Data TcpNAPTRType("SIP+D2T"); +static Data TlsNAPTRType("SIPS+D2T"); +static Data DtlsNAPTRType("SIPS+D2U"); +void +DnsInterface::addTransportType(TransportType type, IpVersion version) +{ + mSupportedTransports.push_back(std::make_pair(type, version)); + switch (type) + { + case UDP: + mSupportedNaptrs.insert(UdpNAPTRType); + break; + case TCP: + mSupportedNaptrs.insert(TcpNAPTRType); + break; + case TLS: + mSupportedNaptrs.insert(TlsNAPTRType); + break; + case DTLS: + mSupportedNaptrs.insert(DtlsNAPTRType); + break; + default: + assert(0); + break; + } +} + +bool +DnsInterface::isSupported(const Data& service) +{ + return mSupportedNaptrs.count(service) != 0; +} + + +bool +DnsInterface::isSupported(TransportType t, IpVersion version) +{ + if (t != UNKNOWN_TRANSPORT) + return std::find(mSupportedTransports.begin(), mSupportedTransports.end(), std::make_pair(t, version)) != mSupportedTransports.end(); + else + { + for (TransportMap::size_type i=0; i<mSupportedTransports.size(); i++) + if (mSupportedTransports[i].second == version) + return true; + return false; + } +} + +bool +DnsInterface::isSupportedProtocol(TransportType t) +{ + for (TransportMap::const_iterator i=mSupportedTransports.begin(); i != mSupportedTransports.end(); ++i) + { + if (i->first == t) + { + return true; + } + } + return false; +} + +int DnsInterface::supportedProtocols() +{ + return (int)mSupportedTransports.size(); +} + + +DnsResult* +DnsInterface::createDnsResult(DnsHandler* handler) +{ + DnsResult* result = new DnsResult(*this, mDnsStub, mVip, handler); + return result; +} + +void +DnsInterface::lookup(DnsResult* res, const Uri& uri) +{ + res->lookup(uri, mDnsStub.getEnumSuffixes(), + mDnsStub.getEnumDomains()); +} + +// DnsResult* +// DnsInterface::lookup(const Via& via, DnsHandler* handler) +// { +// assert(0); + +// //DnsResult* result = new DnsResult(*this); +// return NULL; +// } + +//?dcm? -- why is this here? +DnsHandler::~DnsHandler() +{ +} + +/* moved to DnsStub. +void +DnsInterface::lookupRecords(const Data& target, unsigned short type, DnsRawSink* sink) +{ + mDnsProvider->lookup(target.c_str(), type, this, sink); +} + +void +DnsInterface::handleDnsRaw(ExternalDnsRawResult res) +{ + reinterpret_cast<DnsRawSink*>(res.userData)->onDnsRaw(res.errorCode(), res.abuf, res.alen); + mDnsProvider->freeResult(res); +} +*/ + +// Copyright (c) 2003, Jason Fischl +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/stack/DnsInterface.hxx b/src/libs/resiprocate/resip/stack/DnsInterface.hxx new file mode 100644 index 00000000..5713ae23 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DnsInterface.hxx @@ -0,0 +1,153 @@ +#if !defined(RESIP_DNSINTERFACE_HXX) +#define RESIP_DNSINTERFACE_HXX + +#include <set> +#include <vector> + +#include "rutil/TransportType.hxx" +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/dns/DnsStub.hxx" +#include "rutil/dns/RRVip.hxx" +#include "resip/stack/TupleMarkManager.hxx" + +namespace resip +{ +class DnsHandler; +class DnsResultSink; +class DnsResult; +class Uri; +class Via; +//class ExternalDns; +class DnsRawSink; + +class DnsInterface +{ + public: + class Exception : public BaseException + { + public: + Exception(const Data& msg, const Data& file, const int line) : BaseException(msg,file,line){} + const char* name() const { return "DnsInterface::Exception"; } + }; + + // Used to create an asynchronous Dns Interface. Any lookup requests will + // be queued for later processing. It is critical that the consumer of the + // DnsResult be in the same thread that is processing the async results + // since there is no locking on the DnsResult + // Will throw DnsInterface::Exception if the Dns provider fails to initialize + DnsInterface(DnsStub& dnsStub); + + virtual ~DnsInterface(); + + //Data errorMessage(int status); + + // set the supported set of types that a UAC wishes to use + void addTransportType(TransportType type, IpVersion version); + + // return if the client supports the specified service (e.g. SIP+D2T) + bool isSupported(const Data& service); + bool isSupported(TransportType t, IpVersion version); + + // this is used if NAPTR doesn't return anything to decide which SRV + // records to query + bool isSupportedProtocol(TransportType t); + int supportedProtocols(); + + // For each of the following calls, immediately return a DnsResult to the + // caller. If synchronous, the DnsResult is complete and may block for an + // arbitrary amount of time. In the synchronous case, the transactionId is + // not useful. If asynchronous, the DnsResult will be returned immediately + // and is owned by the caller. If queries are outstanding, it is not valid + // for the caller to delete the DnsResult. + // + // First determine a transport. Second, determine a set of ports and ip + // addresses. These can be returned to the client by asking the DnsResult + // for the next result in the form of a Transport:Tuple. The client can + // continue to ask the DnsResult to return more tuples. If the tuples for + // the current transport are exhausted, move on to the next preferred + // transport (if there is one) + + DnsResult* createDnsResult(DnsHandler* handler=0); + void lookup(DnsResult* res, const Uri& uri); + + //DnsResult* lookup(const Uri& url, DnsHandler* handler=0); + //DnsResult* lookup(const Via& via, DnsHandler* handler=0); + + //void lookupRecords(const Data& target, unsigned short type, DnsRawSink* sink); + //virtual void handleDnsRaw(ExternalDnsRawResult); + TupleMarkManager& getMarkManager(){return mMarkManager;} + + protected: + // When complete or partial results are ready, call DnsHandler::process() + // For synchronous DnsInterface, set to 0 + friend class DnsResult; + // DnsHandler* mHandler; // .kw. not used anymore? + std::set<Data> mSupportedNaptrs; + typedef std::vector<std::pair<TransportType, IpVersion> > TransportMap; + TransportMap mSupportedTransports; + //std::set<TransportType> mSupportedTransportTypes; + + //ExternalDns* mDnsProvider; + + DnsStub& mDnsStub; + RRVip mVip; + TupleMarkManager mMarkManager; +}; + +} + +#endif +// Copyright (c) 2003, Jason Fischl +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + + diff --git a/src/libs/resiprocate/resip/stack/DnsResult.cxx b/src/libs/resiprocate/resip/stack/DnsResult.cxx new file mode 100644 index 00000000..594a08e2 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DnsResult.cxx @@ -0,0 +1,1498 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <algorithm> +#include <stack> + +#ifndef WIN32 +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#ifndef __CYGWIN__ +# include <netinet/in.h> +# include <arpa/nameser.h> +# include <resolv.h> +#endif +#include <netdb.h> +#include <netinet/in.h> +#else +#include <Winsock2.h> +#include <svcguid.h> +#ifdef USE_IPV6 +#include <ws2tcpip.h> +#endif +#endif + +#include "rutil/DnsUtil.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Random.hxx" +#include "rutil/compat.hxx" +#include "rutil/Timer.hxx" +#include "rutil/dns/DnsHandler.hxx" +#include "rutil/dns/QueryTypes.hxx" +#include "rutil/dns/DnsStub.hxx" +#include "rutil/dns/DnsNaptrRecord.hxx" +#include "resip/stack/DnsResult.hxx" +#include "resip/stack/DnsInterface.hxx" +#include "resip/stack/TupleMarkManager.hxx" +#include "resip/stack/Tuple.hxx" +#include "resip/stack/Uri.hxx" +#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS + +EnumResult::EnumResult(EnumResultSink& resultSink, int order) + : mResultSink(resultSink), + mOrder(order) +{ +} + +EnumResult::~EnumResult() +{ +} + +void +EnumResult::onDnsResult(const DNSResult<DnsHostRecord>& result) +{ + assert(0); + delete this; +} + +void +EnumResult::onDnsResult(const DNSResult<DnsAAAARecord>& result) +{ + assert(0); + delete this; +} + +void +EnumResult::onDnsResult(const DNSResult<DnsSrvRecord>&) +{ + assert(0); + delete this; +} + +void +EnumResult::onDnsResult(const DNSResult<DnsNaptrRecord>& result) +{ + mResultSink.onEnumResult(result, mOrder); + delete this; +} + +void +EnumResult::onDnsResult(const DNSResult<DnsCnameRecord>&) +{ + assert(0); + delete this; +} + +DnsResult::DnsResult(DnsInterface& interfaceObj, DnsStub& dns, RRVip& vip, DnsHandler* handler) + : mInterface(interfaceObj), + mDns(dns), + mVip(vip), + mHandler(handler), + mSRVCount(0), + mDoingEnum(0), + mSips(false), + mTransport(UNKNOWN_TRANSPORT), + mPort(-1), + mHaveChosenTransport(false), + mType(Pending), + mCumulativeWeight(0), + mHaveReturnedResults(false) +{ +} + +DnsResult::~DnsResult() +{ + //DebugLog (<< "DnsResult::~DnsResult() " << *this); + assert(mType != Pending); +} + +void +DnsResult::transition(Type t) +{ + if((t == Pending || t== Available) && + (mType== Finished || mType == Destroyed) ) + { + assert(0); + } + + mType = t; +} + +void +DnsResult::destroy() +{ + assert(this); + //DebugLog (<< "DnsResult::destroy() " << *this); + + if (mType == Pending) + { + transition(Destroyed); + } + else + { + transition(Finished); + delete this; + } +} + +bool +DnsResult::blacklistLast(UInt64 expiry) +{ + if(mHaveReturnedResults) + { + assert(!mLastReturnedPath.empty()); + assert(mLastReturnedPath.size()<=3); + Item top = mLastReturnedPath.back(); + + mInterface.getMarkManager().mark(mLastResult,expiry,TupleMarkManager::BLACK); + + DebugLog( << "Remove vip " << top.domain << "(" << top.rrType << ")"); + mVip.removeVip(top.domain, top.rrType); + return true; + } + + return false; +} + +bool +DnsResult::greylistLast(UInt64 expiry) +{ + if(mHaveReturnedResults) + { + assert(!mLastReturnedPath.empty()); + assert(mLastReturnedPath.size()<=3); + Item top = mLastReturnedPath.back(); + + mInterface.getMarkManager().mark(mLastResult,expiry,TupleMarkManager::GREY); + + DebugLog( << "Remove vip " << top.domain << "(" << top.rrType << ")"); + mVip.removeVip(top.domain, top.rrType); + return true; + } + + return false; +} + +DnsResult::Type +DnsResult::available() +{ + assert(mType != Destroyed); + if (mType == Available) + { + if (!mResults.empty()) + { + return Available; + } + else + { + primeResults(); + return available(); // recurse + } + } + else + { + return mType; + } +} + +Tuple +DnsResult::next() +{ + assert(available()==Available); + assert(mCurrentPath.size()<=3); + + mLastResult=mResults.front(); + mResults.pop_front(); + + if(!mCurrentPath.empty() && + (mCurrentPath.back().rrType==T_A || mCurrentPath.back().rrType==T_AAAA)) + { + mCurrentPath.pop_back(); + } + + Item AorAAAA; + AorAAAA.domain = mLastResult.getTargetDomain(); + AorAAAA.rrType = mLastResult.isV4() ? T_A : T_AAAA; + AorAAAA.value = Tuple::inet_ntop(mLastResult); + mCurrentPath.push_back(AorAAAA); + + StackLog (<< "Returning next dns entry: " << mLastResult); + mLastReturnedPath=mCurrentPath; + mHaveReturnedResults=true; + return mLastResult; +} + +void +DnsResult::whitelistLast() +{ + std::vector<Item>::iterator i; + for (i=mLastReturnedPath.begin(); i!=mLastReturnedPath.end(); ++i) + { + DebugLog( << "Whitelisting " << i->domain << "(" << i->rrType << "): " << i->value); + mVip.vip(i->domain, i->rrType, i->value); + } +} + +void +DnsResult::lookup(const Uri& uri, const std::vector<Data> &enumSuffixes, + const std::map<Data,Data> &enumDomains) +{ + DebugLog (<< "DnsResult::lookup " << uri); + //int type = this->mType; + if (!enumSuffixes.empty() && uri.isEnumSearchable() && + enumDomains.find(uri.host()) != enumDomains.end()) + { + mInputUri = uri; + int order = 0; + std::vector<Data> enums = uri.getEnumLookups(enumSuffixes); + assert(enums.size() >= 1); + if (!enums.empty()) + { + mDoingEnum = enums.size(); + for(std::vector<Data>::iterator it = enums.begin(); + it != enums.end(); it++) + { + InfoLog (<< "Doing ENUM lookup on " << *it); + mDns.lookup<RR_NAPTR>(*it, Protocol::Enum, + new EnumResult(*this, order++)); + } + return; + } + } + + mDoingEnum = 0; + lookupInternal(uri); +} + +void +DnsResult::lookupInternal(const Uri& uri) +{ + //assert(uri.scheme() == Symbols::Sips || uri.scheme() == Symbols::Sip); + mSips = (uri.scheme() == Symbols::Sips); + mTarget = (!mSips && uri.exists(p_maddr)) ? uri.param(p_maddr) : uri.host(); + mSrvKey = Symbols::UNDERSCORE + uri.scheme().substr(0, uri.scheme().size()) + Symbols::DOT; + bool isNumeric = DnsUtil::isIpAddress(mTarget); + + if (uri.exists(p_transport)) + { + mTransport = Tuple::toTransport(uri.param(p_transport)); + mHaveChosenTransport=true; + + if (isNumeric) // IP address specified + { + mPort = getDefaultPort(mTransport, uri.port()); + Tuple tuple(mTarget, mPort, mTransport, mTarget); + + // ?bwc? If this is greylisted, what can we do? This is the only result + if(!(mInterface.getMarkManager().getMarkType(tuple)==TupleMarkManager::BLACK)) + { + DebugLog (<< "Found immediate result: " << tuple); + mResults.push_back(tuple); + transition(Available); + if (mHandler) mHandler->handle(this); + } + else + { + transition(Available); + if (mHandler) mHandler->handle(this); + } + + } + else if (uri.port() != 0) + { + mPort = uri.port(); + lookupHost(mTarget); // for current target and port + } + else + { + if (mSips) + { + if (mTransport == UDP) + { + mTransport = DTLS; + if (!mInterface.isSupportedProtocol(mTransport)) + { + transition(Finished); + if (mHandler) mHandler->handle(this); + return; + } + if(!mDns.supportedType(T_SRV)) + { + mPort = getDefaultPort(mTransport, uri.port()); + lookupHost(mTarget); // for current target and port + } + else + { + mSRVCount++; + mDns.lookup<RR_SRV>("_sips._udp." + mTarget, Protocol::Sip, this); + StackLog (<< "Doing SRV lookup of _sips._udp." << mTarget); + } + } + else + { + mTransport = TLS; + mHaveChosenTransport=true; + if (!mInterface.isSupportedProtocol(mTransport)) + { + transition(Finished); + if (mHandler) mHandler->handle(this); + return; + } + if(!mDns.supportedType(T_SRV)) + { + mPort = getDefaultPort(mTransport, uri.port()); + lookupHost(mTarget); // for current target and port + } + else + { + mSRVCount++; + mDns.lookup<RR_SRV>("_sips._tcp." + mTarget, Protocol::Sip, this); + StackLog (<< "Doing SRV lookup of _sips._tcp." << mTarget); + } + } + } + else + { + if (!mInterface.isSupportedProtocol(mTransport)) + { + transition(Finished); + if (mHandler) mHandler->handle(this); + return; + } + + if(!mDns.supportedType(T_SRV)) + { + mPort = getDefaultPort(mTransport, uri.port()); + lookupHost(mTarget); // for current target and port + return; + } + + switch(mTransport) + { + case TLS: //deprecated, mean TLS over TCP + mSRVCount++; + mDns.lookup<RR_SRV>("_sips._tcp." + mTarget, Protocol::Sip, this); + StackLog (<< "Doing SRV lookup of _sips._tcp." << mTarget); + break; + case DTLS: //deprecated, mean TLS over TCP + mSRVCount++; + mDns.lookup<RR_SRV>("_sip._dtls." + mTarget, Protocol::Sip, this); + StackLog (<< "Doing SRV lookup of _sip._dtls." << mTarget); + break; + case TCP: + mSRVCount++; + mDns.lookup<RR_SRV>("_sip._tcp." + mTarget, Protocol::Sip, this); + StackLog (<< "Doing SRV lookup of _sip._tcp." << mTarget); + break; + case SCTP: + case DCCP: + case UDP: + default: //fall through to UDP for unimplemented & unknown + mSRVCount++; + mDns.lookup<RR_SRV>("_sip._udp." + mTarget, Protocol::Sip, this); + StackLog (<< "Doing SRV lookup of _sip._udp." << mTarget); + } + } + } + } + else // transport parameter is not specified + { + // if hostname is numeric, a port is specified, or NAPTR queries are not support by the DNS layer - skip NAPTR lookup + if (isNumeric || uri.port() != 0 || !mDns.supportedType(T_NAPTR)) + { + TupleMarkManager::MarkType mark=TupleMarkManager::BLACK; + Tuple tuple; + + if(isNumeric) + { + if(mSips) + { + if((mInterface.isSupported(TLS, V4) || + mInterface.isSupported(TLS, V6))) + { + mTransport=TLS; + mPort = getDefaultPort(mTransport,uri.port()); + tuple=Tuple(mTarget,mPort,mTransport,mTarget); + mark=mInterface.getMarkManager().getMarkType(tuple); + } + } + else + { + if(mark!=TupleMarkManager::OK && (mInterface.isSupported(UDP, V4) || + mInterface.isSupported(UDP, V6))) + { + mTransport=UDP; + mPort = getDefaultPort(mTransport,uri.port()); + tuple=Tuple(mTarget,mPort,mTransport,mTarget); + mark=mInterface.getMarkManager().getMarkType(tuple); + } + + if(mark!=TupleMarkManager::OK && (mInterface.isSupported(TCP, V4) || + mInterface.isSupported(TCP, V6))) + { + mTransport=TCP; + mPort = getDefaultPort(mTransport,uri.port()); + tuple=Tuple(mTarget,mPort,mTransport,mTarget); + mark=mInterface.getMarkManager().getMarkType(tuple); + } + + if(mark!=TupleMarkManager::OK && (mInterface.isSupported(TLS, V4) || + mInterface.isSupported(TLS, V6))) + { + mTransport=TLS; + mPort = getDefaultPort(mTransport,uri.port()); + tuple=Tuple(mTarget,mPort,mTransport,mTarget); + mark=mInterface.getMarkManager().getMarkType(tuple); + } + } + + if(mark==TupleMarkManager::OK || mark==TupleMarkManager::GREY) + { + mHaveChosenTransport=true; + mResults.push_back(tuple); + transition(Available); + DebugLog (<< "Numeric result so return immediately: " << tuple); + } + else + { + // .bwc. Numeric result is blacklisted. Oh well. + assert(mResults.empty()); + transition(Available); + DebugLog(<< "Numeric result, but this result is currently blacklisted: " << tuple); + } + + if (mHandler) mHandler->handle(this); + + } + else // host is not numeric, so we need to make a query + { + mTransport=UNKNOWN_TRANSPORT; + + if(mSips) + { + if(mInterface.isSupported(TLS, V4) || mInterface.isSupported(TLS, V6)) + { + mTransport=TLS; + } + } + else if(mInterface.isSupported(UDP, V4) || mInterface.isSupported(UDP, V6)) + { + mTransport=UDP; + } + else if(mInterface.isSupported(TCP, V4) || mInterface.isSupported(TCP, V6)) + { + mTransport=TCP; + } + else if(mInterface.isSupported(TLS, V4) || mInterface.isSupported(TLS, V6)) + { + mTransport=TLS; + } + + if(mTransport!=UNKNOWN_TRANSPORT) + { + mPort=getDefaultPort(mTransport,uri.port()); + lookupHost(mTarget); + } + else + { + // !bwc! Debatable. + assert(0); + if (mHandler) mHandler->handle(this); + } + } + } + else // do NAPTR + { + mDns.lookup<RR_NAPTR>(mTarget, Protocol::Sip, this); // for current target + } + } +} + +void DnsResult::lookupHost(const Data& target) +{ + if (mInterface.isSupported(mTransport, V6)) + { +#ifdef USE_IPV6 + DebugLog(<< "Doing host (AAAA) lookup: " << target); + mPassHostFromAAAAtoA = target; + mDns.lookup<RR_AAAA>(target, Protocol::Sip, this); +#else + assert(0); + mDns.lookup<RR_A>(target, Protocol::Sip, this); +#endif + } + else if (mInterface.isSupported(mTransport, V4)) + { + mDns.lookup<RR_A>(target, Protocol::Sip, this); + } + else + { + CritLog(<<"Cannot lookup target="<<target + <<" because DnsInterface doesn't support transport="<<mTransport); + assert(0); + } +} + +int +DnsResult::getDefaultPort(TransportType transport, int port) +{ + if (port == 0) + { + switch (transport) + { + case UDP: + return Symbols::DefaultSipPort; + case TCP: + return mSips ? Symbols::DefaultSipsPort : Symbols::DefaultSipPort; + case TLS: + case DTLS: + return Symbols::DefaultSipsPort; + default: + ErrLog( << "Should not get this - unknown transport" ); + return Symbols::DefaultSipPort; // !cj! todo - remove + assert(0); + } + } + else + { + return port; + } + + assert(0); + return 0; +} + +void +DnsResult::primeResults() +{ + StackLog(<< "Priming " << Inserter(mSRVResults)); + //assert(mType != Pending); + //assert(mType != Finished); + assert(mResults.empty()); + + if (!mSRVResults.empty()) + { + SRV next = retrieveSRV(); + StackLog (<< "Primed with SRV=" << next); + transition(Pending); + mPort = next.port; + mTransport = next.transport; + StackLog (<< "No A or AAAA record for " << next.target << " in additional records"); + if (mInterface.isSupported(mTransport, V6) || mInterface.isSupported(mTransport, V4)) + { + Item item; + clearCurrPath(); + // Check if SRV came from a NAPTR look up + std::map<Data, NAPTR>::iterator it = mTopOrderedNAPTRs.find(next.key); + if(it != mTopOrderedNAPTRs.end()) + { + item.domain = (*it).second.key; + item.rrType = T_NAPTR; + item.value = (*it).second.replacement; + mCurrentPath.push_back(item); + } + item.domain = next.key; + item.rrType = T_SRV; + item.value = next.target + ":" + Data(next.port); + mCurrentPath.push_back(item); + lookupHost(next.target); + } + else + { + assert(0); + if (mHandler) mHandler->handle(this); + } + // don't call primeResults since we need to wait for the response to + // AAAA/A query first + } + else if(!mGreylistedTuples.empty()) + { + for(std::vector<Tuple>::iterator i = mGreylistedTuples.begin(); i != mGreylistedTuples.end(); ++i) + { + mResults.push_back(*i); + } + mGreylistedTuples.clear(); + transition(Available); + } + else + { + bool changed = (mType == Pending); + transition(Finished); + if (changed && mHandler) mHandler->handle(this); + } + + // Either we are finished or there are results primed +} + +// implement the selection algorithm from rfc2782 (SRV records) +DnsResult::SRV +DnsResult::retrieveSRV() +{ + // !ah! if mTransport is known -- should we ignore those that don't match?! + assert(!mSRVResults.empty()); + assert(mSRVCount==0); + + const SRV& srv = *mSRVResults.begin(); + int priority = srv.priority; + TransportType transport=UNKNOWN_TRANSPORT; + + if(!mHaveChosenTransport) + { + // .bwc. We have not chosen a transport yet; this happens when we fail + // to find a NAPTR record, and the transport is not specified in the uri. + // In this contingency, we manufacture best-guess SRV queries for each + // transport we support, and try one transport at a time. This + // means we might try more than one transport for the uri in question. + transport = srv.transport; + } + else + { + // .bwc. We chose our transport before we started looking up SRVs. + // All SRVs must match. + + transport=mTransport; + assert(mSRVResults.begin()->transport==transport); + } + + if (mCumulativeWeight == 0) + { + for (std::vector<SRV>::iterator i=mSRVResults.begin(); + i!=mSRVResults.end() + && i->priority == priority + && i->transport == transport; i++) + { + assert(i->weight>=0); + mCumulativeWeight += i->weight; + } + } + + int selected =0; + if(mCumulativeWeight!=0) + { + selected = Random::getRandom() % (mCumulativeWeight); + } + else + { + // .bwc. All of the remaining SRVs (at this priority/type) have a weight + // of 0. The best we can do here is pick arbitrarily. In this case, we + // will end up picking the first. + // (selected will be less than the weight of the first SRV, causing the + // loop below to break on the first iteration) + selected=-1; + } + + StackLog (<< "cumulative weight = " << mCumulativeWeight << " selected=" << selected); + + std::vector<SRV>::iterator i; + int cumulativeWeight=0; + for (i=mSRVResults.begin(); i!=mSRVResults.end(); ++i) + { + cumulativeWeight+=i->weight; + if (cumulativeWeight > selected) + { + break; + } + } + + if (i == mSRVResults.end()) + { + InfoLog (<< "SRV Results problem selected=" << selected << " cum=" << mCumulativeWeight); + } + assert(i != mSRVResults.end()); + SRV next = *i; + mCumulativeWeight -= next.weight; + mSRVResults.erase(i); + + if(!mSRVResults.empty()) + { + int nextPriority=mSRVResults.begin()->priority; + TransportType nextTransport=mSRVResults.begin()->transport; + + // .bwc. If we have finished traversing a priority value/transport type, + // we reset the cumulative weight to 0, to prompt its recalculation. + if(priority!=nextPriority || transport!=nextTransport) + { + mCumulativeWeight=0; + } + } + + StackLog (<< "SRV: " << Inserter(mSRVResults)); + + return next; +} + +DnsResult::NAPTR::NAPTR() : order(0), pref(0) +{ +} + +bool +DnsResult::NAPTR::operator<(const DnsResult::NAPTR& rhs) const +{ + if (key.empty()) // default value + { + return false; + } + else if (rhs.key.empty()) // default value + { + return true; + } + else if (order < rhs.order) + { + return true; + } + else if (order == rhs.order) + { + if (pref < rhs.pref) + { + return true; + } + else if (pref == rhs.pref) + { + return replacement < rhs.replacement; + } + } + return false; +} + +DnsResult::SRV::SRV() : priority(0), weight(0), port(0) +{ + // .kw. member "transport" is not initialized. good default? +} + +bool +DnsResult::SRV::operator<(const DnsResult::SRV& rhs) const +{ + if (naptrpref < rhs.naptrpref) + { + return true; + } + else if(naptrpref == rhs.naptrpref) + { + if (transport < rhs.transport) + { + return true; + } + else if (transport == rhs.transport) + { + if (priority < rhs.priority) + { + return true; + } + else if (priority == rhs.priority) + { + if (weight < rhs.weight) + { + return true; + } + else if (weight == rhs.weight) + { + if (target < rhs.target) + { + return true; + } + } + } + } + } + return false; +} + +void DnsResult::onDnsResult(const DNSResult<DnsHostRecord>& result) +{ + if (!mInterface.isSupported(mTransport, V4) && !mInterface.isSupported(mTransport, V6)) + { + return; + } + StackLog (<< "Received dns result for: " << mTarget); + StackLog (<< "DnsResult::onDnsResult() " << result.status); + + // This function assumes that the A query that caused this callback + // is the _only_ outstanding DNS query that might result in a + // callback into this function + if ( mType == Destroyed ) + { + destroy(); + return; + } + + if (result.status == 0) + { + for (vector<DnsHostRecord>::const_iterator it = result.records.begin(); it != result.records.end(); ++it) + { + in_addr addr; + addr.s_addr = (*it).addr().s_addr; + Tuple tuple(addr, mPort, mTransport, mTarget); + + switch(mInterface.getMarkManager().getMarkType(tuple)) + { + case TupleMarkManager::OK: + StackLog (<< "Adding " << tuple << " to result set"); + mResults.push_back(tuple); + break; + case TupleMarkManager::GREY: + StackLog(<< "Adding greylisted tuple " << tuple); + mGreylistedTuples.push_back(tuple); + break; + case TupleMarkManager::BLACK: + default: + ;// .bwc. Do nothing. + } + + } + + } + else + { + StackLog (<< "Failed async A query: " << result.msg); + } + + if (mSRVCount == 0) + { + bool changed = (mType == Pending); + if (mResults.empty()) + { +#ifdef WIN32_SYNCRONOUS_RESOLUTION_ON_ARES_FAILURE + // Try Windows Name Resolution (not asyncronous) + WSAQUERYSET QuerySet = { 0 }; + GUID guidServiceTypeUDP = SVCID_UDP(mPort); + GUID guidServiceTypeTCP = SVCID_TCP(mPort); + HANDLE hQuery; + QuerySet.dwSize = sizeof(WSAQUERYSET); + QuerySet.lpServiceClassId = mTransport == UDP ? &guidServiceTypeUDP : &guidServiceTypeTCP; + QuerySet.dwNameSpace = NS_ALL; + QuerySet.lpszServiceInstanceName = (char *)mTarget.c_str(); + if(WSALookupServiceBegin(&QuerySet, LUP_RETURN_ADDR, &hQuery) == 0) + { + DWORD dwQuerySize = 256; // Starting size + int iRet = 0; + bool fDone = false; + LPWSAQUERYSET pQueryResult = (LPWSAQUERYSET) new char[dwQuerySize]; + while(iRet == 0 && pQueryResult) + { + iRet = WSALookupServiceNext(hQuery, 0, &dwQuerySize, pQueryResult); + if(pQueryResult && iRet == -1 && GetLastError() == WSAEFAULT) + { + delete [] pQueryResult; + pQueryResult = (LPWSAQUERYSET) new char[dwQuerySize]; // Re-allocate new size + iRet = WSALookupServiceNext(hQuery, 0, &dwQuerySize, pQueryResult); + } + if(pQueryResult && iRet == 0) + { + for(DWORD i = 0; i < pQueryResult->dwNumberOfCsAddrs; i++) + { + SOCKADDR_IN *pSockAddrIn = (SOCKADDR_IN *)pQueryResult->lpcsaBuffer[i].RemoteAddr.lpSockaddr; + Tuple tuple(pSockAddrIn->sin_addr, mPort, mTransport, mTarget); + + if(mInterface.getMarkManager().getMarkType(tuple)!=TupleMarkManager::BLACK) + { + // .bwc. This is the only result we have, so it doesn't + // matter if it is greylisted. + StackLog (<< "Adding (WIN) " << tuple << " to result set"); + mResults.push_back(tuple); + transition(Available); + } + + } + } + } + delete [] pQueryResult; + WSALookupServiceEnd(hQuery); + } + + if(mResults.empty()) + { + if(mSRVResults.empty()) + { + if (mGreylistedTuples.empty()) + { + transition(Finished); + clearCurrPath(); + } + else + { + for(std::vector<Tuple>::iterator i = mGreylistedTuples.begin(); i != mGreylistedTuples.end(); ++i) + { + mResults.push_back(*i); + } + mGreylistedTuples.clear(); + transition(Available); + } + } + else + { + transition(Available); + } + } +#else + // .bwc. If this A query failed, don't give up if there are more SRVs! + if(mSRVResults.empty()) + { + if (mGreylistedTuples.empty()) + { + transition(Finished); + clearCurrPath(); + } + else + { + for(std::vector<Tuple>::iterator i = mGreylistedTuples.begin(); i != mGreylistedTuples.end(); ++i) + { + mResults.push_back(*i); + } + mGreylistedTuples.clear(); + transition(Available); + } + } + else + { + transition(Available); + } +#endif + } + else + { + transition(Available); + } + if (changed && mHandler) mHandler->handle(this); + } +} + +void DnsResult::onDnsResult(const DNSResult<DnsAAAARecord>& result) +{ +#ifdef USE_IPV6 + StackLog (<< "Received AAAA result for: " << mTarget); + if (!mInterface.isSupported(mTransport, V6)) + { + return; + } + StackLog (<< "DnsResult::onDnsResult() " << result.status); + assert(mInterface.isSupported(mTransport, V6)); + + // This function assumes that the AAAA query that caused this callback + // is the _only_ outstanding DNS query that might result in a + // callback into this function + if ( mType == Destroyed ) + { + destroy(); + return; + } + + if (result.status == 0) + { + for (vector<DnsAAAARecord>::const_iterator it = result.records.begin(); it != result.records.end(); ++it) + { + Tuple tuple((*it).v6Address(), mPort, mTransport, mTarget); + + switch(mInterface.getMarkManager().getMarkType(tuple)) + { + case TupleMarkManager::OK: + StackLog (<< "Adding " << tuple << " to result set"); + mResults.push_back(tuple); + break; + case TupleMarkManager::GREY: + StackLog(<< "Adding greylisted tuple " << tuple); + mGreylistedTuples.push_back(tuple); + break; + case TupleMarkManager::BLACK: + default: + ;// .bwc. Do nothing. + } + + } + + } + else + { + StackLog (<< "Failed async AAAA query: " << result.msg); + } + // funnel through to host processing + mDns.lookup<RR_A>(mPassHostFromAAAAtoA, Protocol::Sip, this); +#else + assert(0); +#endif +} + +void DnsResult::onDnsResult(const DNSResult<DnsSrvRecord>& result) +{ + StackLog (<< "Received SRV result for: " << mTarget); + assert(mSRVCount>=0); + mSRVCount--; + StackLog (<< "DnsResult::onDnsResult() " << mSRVCount << " status=" << result.status); + + // There could be multiple SRV queries outstanding, but there will be no + // other DNS queries outstanding that might cause a callback into this + // object. + if (mType == Destroyed && mSRVCount == 0) + { + destroy(); + return; + } + + if (result.status == 0) + { + for (vector<DnsSrvRecord>::const_iterator it = result.records.begin(); it != result.records.end(); ++it) + { + SRV srv; + srv.key = (*it).name(); + srv.priority = (*it).priority(); + srv.weight = (*it).weight(); + srv.port = (*it).port(); + srv.target = (*it).target(); + + // Workaround for dns server bug - domain name can be doubled via dot + Data p1 = srv.target.substr(0, srv.target.size()/2), p2 = srv.target.substr(srv.target.size()/2 + 1); + if (p1 == p2) + { + StackLog (<< "Workaround for SRV result : " << srv.target << " rewrites to " << p1); + srv.target = p1; + } + // fillin srv.naptrpref - if found in NAPTR map, then SRV query was driven from a NAPTR lookup + std::map<Data, NAPTR>::iterator itNaptr = mTopOrderedNAPTRs.find(srv.key); + if(itNaptr != mTopOrderedNAPTRs.end()) + { + srv.naptrpref = itNaptr->second.pref; + } + else + { + srv.naptrpref = 0; + } + if (srv.key.find("_sips._udp") != Data::npos) + { + srv.transport = DTLS; + } + else if (srv.key.find("_sips._tcp") != Data::npos) + { + srv.transport = TLS; + } + else if (srv.key.find("_udp") != Data::npos) + { + srv.transport = UDP; + } + else if (srv.key.find("_dtls") != Data::npos) + { + srv.transport = DTLS; + } + else if (srv.key.find("_tls") != Data::npos) + { + srv.transport = TLS; + } + else if (srv.key.find("_tcp") != Data::npos) + { + srv.transport = TCP; + } + else + { + StackLog (<< "Skipping SRV " << srv.key); + continue; + } + + if(!mHaveChosenTransport || srv.transport==mTransport) + { + // .bwc. If we have not committed to a given transport, or we have + // committed to a given transport which this SRV matches, we will + // add this SRV. We do not add SRVs that do not match a transport + // we have committed to. + mSRVResults.push_back(srv); + } + } + } + else + { + StackLog (<< "SRV lookup failed: " << result.domain << " " << result.status); + } + + // no outstanding queries + if (mSRVCount == 0) + { + if (mSRVResults.empty()) + { + if (mTransport == UNKNOWN_TRANSPORT) + { + if (mSips) + { + mTransport = TLS; + mHaveChosenTransport=true; + mPort = Symbols::DefaultSipsPort; + } + else + { + if (mInterface.isSupported(UDP, V4)) + { + mTransport = UDP; + mHaveChosenTransport=true; + } + else if (mInterface.isSupported(TCP, V4)) + { + mTransport = TCP; + mHaveChosenTransport=true; + } + else + if (mInterface.isSupported(UDP, V6)) + { + mTransport = UDP; + mHaveChosenTransport = true; + } + else + if (mInterface.isSupported(TCP, V6)) + { + mTransport = TCP; + mHaveChosenTransport = true; + } + + /* Yes, there is the possibility that at this point mTransport + is still UNKNOWN_TRANSPORT, but this is likely to fail just as + well as defaulting to UDP when there isn't an interface that + supports UDP. + It doesn't support failover to TCP when there is a UDP failure, + but neither does the original code. + This fixes the case where there is no UDP transport, but + there was no explicit ;transport=tcp on the uri. + (mjf) + */ + mPort = Symbols::DefaultSipPort; + } + } + else + { + mPort = getDefaultPort(mTransport, 0); + } + + StackLog (<< "No SRV records for " << mTarget << ". Trying A records"); + if (mInterface.isSupported(mTransport, V6) || mInterface.isSupported(mTransport, V4)) + { + lookupHost(mTarget); + } + else + { + primeResults(); + } + } + else + { + std::sort(mSRVResults.begin(),mSRVResults.end()); // !jf! uggh + primeResults(); + } + } +} + +static Data enumService1("e2u+sip"); +static Data enumService2("sip+e2u"); +void +DnsResult::onEnumResult(const DNSResult<DnsNaptrRecord>& result, int order) +{ + Lock l(mEnumDestinationsMutex); + assert(mDoingEnum > 0); + + mDoingEnum--; + + StackLog(<< "checking result of ENUM query, remaining queries outstanding = " << mDoingEnum); + + if (result.status == 0) + { + DnsNaptrRecord best; + best.order() = -1; + + for (vector<DnsNaptrRecord>::const_iterator i = result.records.begin(); i != result.records.end(); ++i) + { + InfoLog (<< "service=" << i->service() + << " order=" << i->order() + << " flags=" << i->flags() + << " regexp substitution=" << i->regexp().replacement() + << " replacement=" << i->replacement()); + + if ( (isEqualNoCase(i->service(), enumService1) || + isEqualNoCase(i->service(), enumService2) ) && // only E2U records + //i->flags().find("u") != Data::npos && // must be terminal record + i->replacement().empty() ) + + { + if (best.order() == -1) + { + best = *i; + } + else if (i->order() < best.order()) + { + best = *i; + } + else if (i->order() == best.order() && + i->preference() < best.preference()) + { + best = *i; + } + } + } + + if (best.order() != -1) + { + InfoLog (<< "Found an enum result: " << best.regexp().replacement()); + try + { + Uri rewrite(best.regexp().apply(Data::from(mInputUri))); + InfoLog (<< "Rewrote uri " << mInputUri << " -> " << rewrite); + mEnumDestinations[order] = rewrite; + } + catch (ParseException& e ) + { + ErrLog(<<"Caught exception: "<< e); + // we just don't add anything to mEnumDestinations... + // later, if mEnumDestinations is empty after all ENUM queries, + // it will fall back to mInputUri + } + } + } + + if(mDoingEnum == 0) + { + DebugLog(<< "All ENUM DNS queries done, checking for results..."); + std::map<int,Uri>::iterator it = mEnumDestinations.begin(); + if(it != mEnumDestinations.end()) + { + DebugLog(<< "Using result for suffix " << (it->first + 1)); + mHandler->rewriteRequest(it->second); + lookupInternal(it->second); + } + else + { + DebugLog(<< "No valid ENUM query result, falling back to request URI"); + lookupInternal(mInputUri); + } + } +} + +void +DnsResult::onNaptrResult(const DNSResult<DnsNaptrRecord>& result) +{ + bool bFail = false; + if (result.status == 0) + { + int preferredNAPTROrder=65536; // order is unsigned short - so max is 65535, initialize to one higher + std::list<NAPTR> supportedNAPTRs; + for (vector<DnsNaptrRecord>::const_iterator it = result.records.begin(); it != result.records.end(); ++it) + { + NAPTR naptr; + naptr.key = (*it).name(); + naptr.flags = (*it).flags(); + naptr.order = (*it).order(); + naptr.pref = (*it).preference(); + naptr.regex = (*it).regexp(); + naptr.replacement = (*it).replacement(); + naptr.service = (*it).service(); + + StackLog (<< "Received NAPTR record: " << naptr); + + if ( !mSips || naptr.service.find("SIPS") == 0) + { + if (mInterface.isSupported(naptr.service)) + { + supportedNAPTRs.push_back(naptr); + if(naptr.order < preferredNAPTROrder) + { + preferredNAPTROrder = naptr.order; + } + } + } + } + + // This means that dns / NAPTR is misconfigured for this client + if (supportedNAPTRs.empty()) + { + StackLog (<< "There are no NAPTR records supported by this client so do an SRV lookup instead"); + bFail = true; + } + else + { + // Go through NAPTR's and issue SRV queries for each supported record, that has equal + // ordering to the most preferred order discovered above + transition(Pending); + for (std::list<NAPTR>::const_iterator it = supportedNAPTRs.begin(); it != supportedNAPTRs.end(); ++it) + { + if(preferredNAPTROrder == (*it).order) + { + StackLog (<< "NAPTR record is supported and matches highes priority order. doing SRV query: " << (*it)); + mTopOrderedNAPTRs[(*it).replacement] = (*it); + mSRVCount++; + mDns.lookup<RR_SRV>((*it).replacement, Protocol::Sip, this); + } + } + } + } + else + { + if (result.status > 6) + { + DebugLog (<< "NAPTR lookup failed: " << result.domain << " " << result.msg); + } + else + { + StackLog (<< "NAPTR lookup failed: " << result.domain << " " << result.msg); + } + bFail = true; + } + + if (bFail) + { + if (mSips) + { + if (!mInterface.isSupportedProtocol(TLS)) + { + transition(Finished); + if (mHandler) mHandler->handle(this); + return; + } + + mSRVCount++; + mDns.lookup<RR_SRV>("_sips._tcp." + mTarget, Protocol::Sip, this); + StackLog (<< "Doing SRV lookup of _sips._tcp." << mTarget); + } + else + { + if (mInterface.isSupportedProtocol(TLS)) + { + mDns.lookup<RR_SRV>("_sips._tcp." + mTarget, Protocol::Sip, this); + ++mSRVCount; + StackLog (<< "Doing SRV lookup of _sips._tcp." << mTarget); + } + if (mInterface.isSupportedProtocol(DTLS)) + { + mDns.lookup<RR_SRV>("_sips._udp." + mTarget, Protocol::Sip, this); + ++mSRVCount; + StackLog (<< "Doing SRV lookup of _sips._udp." << mTarget); + } + if (mInterface.isSupportedProtocol(TCP)) + { + mDns.lookup<RR_SRV>("_sip._tcp." + mTarget, Protocol::Sip, this); + ++mSRVCount; + StackLog (<< "Doing SRV lookup of _sip._tcp." << mTarget); + } + if (mInterface.isSupportedProtocol(UDP)) + { + mDns.lookup<RR_SRV>("_sip._udp." + mTarget, Protocol::Sip, this); + ++mSRVCount; + StackLog (<< "Doing SRV lookup of _sip._udp." << mTarget); + } + } + } +} + +void +DnsResult::onDnsResult(const DNSResult<DnsNaptrRecord>& result) +{ + StackLog (<< "Received NAPTR result for: " << mInputUri << " target=" << mTarget); + StackLog (<< "DnsResult::onDnsResult() " << result.status); + + // This function assumes that the NAPTR query that caused this + // callback is the ONLY outstanding query that might cause + // a callback into this object + if (mType == Destroyed) + { + destroy(); + return; + } + + onNaptrResult(result); + +} + +void DnsResult::onDnsResult(const DNSResult<DnsCnameRecord>& result) +{ +} + +void DnsResult::clearCurrPath() +{ + while (!mCurrentPath.empty()) + { + mCurrentPath.pop_back(); + } +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const resip::DnsResult& result) +{ + strm << result.mTarget << " --> " << Inserter(result.mResults); + return strm; +} + + +EncodeStream& +resip::operator<<(EncodeStream& strm, const resip::DnsResult::NAPTR& naptr) +{ + strm << "key=" << naptr.key + << " order=" << naptr.order + << " pref=" << naptr.pref + << " flags=" << naptr.flags + << " service=" << naptr.service + << " regex=" << naptr.regex.regexp() << " -> " << naptr.regex.replacement() + << " replacement=" << naptr.replacement; + return strm; +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const resip::DnsResult::SRV& srv) +{ + strm << "key=" << srv.key + << " t=" << Tuple::toData(srv.transport) + << " p=" << srv.priority + << " w=" << srv.weight + << " port=" << srv.port + << " target=" << srv.target; + return strm; +} + +// Copyright (c) 2003, Jason Fischl +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/DnsResult.hxx b/src/libs/resiprocate/resip/stack/DnsResult.hxx new file mode 100644 index 00000000..3315efdf --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DnsResult.hxx @@ -0,0 +1,386 @@ +#if !defined(RESIP_DNSRESULT_HXX) +#define RESIP_DNSRESULT_HXX + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include <iosfwd> +#include <set> +#include <vector> +#include <deque> +#include <map> +#include <stack> + +#include "resip/stack/Tuple.hxx" +#include "resip/stack/Transport.hxx" +#include "resip/stack/Uri.hxx" +#include "rutil/Condition.hxx" +#include "rutil/HeapInstanceCounter.hxx" +#include "rutil/dns/RRVip.hxx" +#include "rutil/dns/DnsStub.hxx" + +#ifdef WIN32 +#include <Ws2tcpip.h> +#endif + +struct hostent; + +namespace resip +{ +class DnsInterface; +class DnsAAAARecord; +class DnsHandler; + +class EnumResultSink +{ + public: + virtual void onEnumResult(const DNSResult<DnsNaptrRecord>& result, + int order) = 0; +}; + +class EnumResult : public DnsResultSink +{ + public: + EnumResult(EnumResultSink& resultSink, int order); + ~EnumResult(); + + // DnsResultSink + void onDnsResult(const DNSResult<DnsHostRecord>&); + +//#ifdef USE_IPV6 + void onDnsResult(const DNSResult<DnsAAAARecord>&); +//#endif + + void onDnsResult(const DNSResult<DnsSrvRecord>&); + void onDnsResult(const DNSResult<DnsNaptrRecord>&); + void onDnsResult(const DNSResult<DnsCnameRecord>&); + + void onEnumResult(const DNSResult<DnsNaptrRecord>& result); + void onNaptrResult(const DNSResult<DnsNaptrRecord>& result); + + private: + EnumResultSink& mResultSink; + int mOrder; +}; + +class DnsResult : public DnsResultSink, public EnumResultSink +{ + public: + RESIP_HeapCount(DnsResult); + DnsResult(DnsInterface& interfaceObj, DnsStub& dns, RRVip& vip, DnsHandler* handler); + virtual ~DnsResult(); + + typedef enum + { + Available, // A result is available now + Pending, // More results may be pending + Finished, // No more results available and none pending + Destroyed // the associated transaction has been deleted + // (ie, this DnsResult will delete itself as soon as it + // gets a new result) + } Type; + + typedef std::vector<Data> DataVector; + + + /*! Starts a lookup. Has the rules for determining the transport + from a uri as per rfc3263 and then does a NAPTR lookup or an A + lookup depending on the uri. + + @param uri The uri to resolve. + @param enumSuffixes If the uri is enum searchable, this is the list of + enum suffixes (for example "e164.arpa") that will be used in + the attempt to resolve this uri. + @param enumDomains The ENUM possibility is only considered if + the URI domain part is one of these domains + */ + void lookup(const Uri& uri, const std::vector<Data> &enumSuffixes, + const std::map<Data,Data> &enumDomains); + + /*! + Blacklist the last returned result until the specified time (ms) + + @param expiry The absolute expiry, in ms, of this blacklist. + @return true iff the last result could be blacklisted + @note This is a no-op if no results have been returned. + */ + bool blacklistLast(UInt64 expiry); + + /*! + Greylist the last returned result until the specified time (ms) + Greylisting a tuple effectively de-prioritizes it, so it will not be + tried if there are any non-grey or blacklisted tuples left to try. + + @param expiry The absolute expiry, in ms, of this blacklist. + @return true iff the last result could be greylisted + @note This is a no-op if no results have been returned. + */ + bool greylistLast(UInt64 expiry); + + /*! + Tries to load the next tuple. If Available is returned, the tuple may + be accessed using current(). + + @return Available if there is a result ready, Pending if it needs to + follow an SRV (more results might come in later), or Finished + if there are definitively no more results. + @note ALWAYS call this before calling next() + */ + Type available(); + + /*! + Return the next tuple available for this query. + + @return The next Tuple available for this query. + @note ALWAYS call available() and verify the return is Available + before calling this function. + @note This no longer results in the last result being blacklisted. To + blacklist the last result, use blacklistLast(). + */ + Tuple next(); + + /*! + Whitelist the last tuple returned by next(). This means that the path + to this result (NAPTR->SRV->A/AAAA) will be favored by the resolver + from now on. (ie, this NAPTR will be favored above all others that + match, even if the order/preference changes in the DNS, and this + A/AAAA record will be favored above all others that match, even if new + ones are added.) + + @note It can be argued that using this is harmful, since the load- + leveling capabilities of DNS are ignored from here on. + @note This will also re-order SRV records, but the order in which + SRVs arrive is ignored by DnsResult (they are just re-sorted) + */ + void whitelistLast(); + + // return the target of associated query + Data target() const { return mTarget; } + unsigned int getSRVResultsSize() const {return (unsigned int)mSRVResults.size();} + + // Will delete this DnsResult if no pending queries are out there or wait + // until the pending queries get responses and then delete + void destroy(); + + // Used to store a NAPTR result + class NAPTR + { + public: + NAPTR(); + // As defined by RFC3263 + bool operator<(const NAPTR& rhs) const; + + Data key; // NAPTR record key + + int order; + int pref; + Data flags; + Data service; + DnsNaptrRecord::RegExp regex; + Data replacement; + }; + + class SRV + { + public: + SRV(); + // As defined by RFC3263, RFC2782 + bool operator<(const SRV& rhs) const; + + Data key; // SRV record key + + int naptrpref; + TransportType transport; + int priority; + int weight; + int port; + Data target; + }; + + private: + void lookupInternal(const Uri& uri); + + // Given a transport and port from uri, return the default port to use + int getDefaultPort(TransportType transport, int port); + + void lookupHost(const Data& target); + + // compute the cumulative weights for the SRV entries with the lowest + // priority, then randomly pick according to RFC2782 from the entries with + // the lowest priority based on weights. When all entries at the lowest + // priority are chosen, pick the next lowest priority and repeat. After an + // SRV entry is selected, remove it from mSRVResults + SRV retrieveSRV(); + + // Will retrieve the next SRV record and compute the prime the mResults + // with the appropriate Tuples. + void primeResults(); + + private: + DnsInterface& mInterface; + DnsStub& mDns; + RRVip& mVip; + DnsHandler* mHandler; + int mSRVCount; + Uri mInputUri; + int mDoingEnum; + std::map<int,Uri> mEnumDestinations; + resip::Mutex mEnumDestinationsMutex; + + bool mSips; + Data mTarget; + Data mSrvKey; + TransportType mTransport; // current + int mPort; // current + + /*! + @author bwc + This is set to true when the RFC 3263 logic has chosen the transport + it will be using. Incoming SRVs will be filtered according to + mTransport if mHaveChosenTransport is true. It is VITAL that this + boolean not change during the phase where we are acquiring/processing + SRV records, because the state of this boolean denotes whether we + filtered incoming SRVs or not. (If it changes halfway through, some + of the SRVs will have been filtered, but some won't, and this will + break retrieveSRV() ) + */ + bool mHaveChosenTransport; + + /*! + @author bwc + DnsResult::transition is the ONLY function that should ever touch this + (This is because we need to notify mInterface when we are done making + queries, and this is when we transition from either Pending or + Available to either Destroyed or Finished.) + */ + Type mType; + + //Ugly hack + Data mPassHostFromAAAAtoA; + + void transition(Type t); + + // This is where the current pending (ordered) results are stored. As they + // are retrieved by calling next(), they are popped from the front of the list + std::deque<Tuple> mResults; + std::vector<Tuple> mGreylistedTuples; + + // Map of NAPTR records by replacement (ie. SRV lookup key) + std::map<Data, NAPTR> mTopOrderedNAPTRs; + + // used in determining the next SRV record to use as per rfc2782 + int mCumulativeWeight; // for current priority + + // All SRV records sorted in order of preference + std::vector<SRV> mSRVResults; + + friend class DnsInterface; + friend EncodeStream& operator<<(EncodeStream& strm, const DnsResult&); + friend EncodeStream& operator<<(EncodeStream& strm, const DnsResult::SRV&); + friend EncodeStream& operator<<(EncodeStream& strm, const DnsResult::NAPTR&); + + // DnsResultSink + void onDnsResult(const DNSResult<DnsHostRecord>&); + +//#ifdef USE_IPV6 + void onDnsResult(const DNSResult<DnsAAAARecord>&); +//#endif + + void onDnsResult(const DNSResult<DnsSrvRecord>&); + void onDnsResult(const DNSResult<DnsNaptrRecord>&); + void onDnsResult(const DNSResult<DnsCnameRecord>&); + + void onEnumResult(const DNSResult<DnsNaptrRecord>& result, int order); + void onNaptrResult(const DNSResult<DnsNaptrRecord>& result); + + + typedef struct + { + Data domain; + int rrType; + Data value; // stores ip for A/AAAA, target host:port for SRV, and replacement for NAPTR. + } Item; + + /*! + @author bwc + This is a snapshot of mCurrentPath when it was returned last. + (This will be empty if we haven't returned anything) + This is primarily used for whitelisting the last returned result. + */ + std::vector<Item> mLastReturnedPath; + + /*! + @author bwc + The current DNS path we are working on. + (ie NAPTR -> SRV -> A/AAAA) There is at most one of these types + in here at any given time, and they will always be in order. + This exists solely to allow mLastReturnedPath to be defined. + */ + std::vector<Item> mCurrentPath; + + bool mHaveReturnedResults; + + void clearCurrPath(); + + Tuple mLastResult; +}; + +EncodeStream& operator<<(EncodeStream& strm, const DnsResult&); +EncodeStream& operator<<(EncodeStream& strm, const DnsResult::SRV&); +EncodeStream& operator<<(EncodeStream& strm, const DnsResult::NAPTR&); + +} + +#endif +// Copyright (c) 2003, Jason Fischl +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/DnsResultMessage.hxx b/src/libs/resiprocate/resip/stack/DnsResultMessage.hxx new file mode 100644 index 00000000..a86026f5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DnsResultMessage.hxx @@ -0,0 +1,103 @@ +#ifndef DNS_RESULT_MESSAGE_HXX +#define DNS_RESULT_MESSAGE_HXX + +#include "resip/stack/TransactionMessage.hxx" + +namespace resip +{ + +/** + @internal +*/ +class DnsResultMessage : public TransactionMessage +{ + public: + DnsResultMessage(const resip::Data& tid, bool isClient) + : mTid(tid), + mIsClientTransaction(isClient) + {} + + virtual ~DnsResultMessage(){}; + + virtual const Data& getTransactionId() const {return mTid;} + + // indicates this message is associated with a Client Transaction for the + // purpose of determining which TransactionMap to use + virtual bool isClientTransaction() const {return mIsClientTransaction;} + + virtual Message* clone() const {return new DnsResultMessage(*this);} + /// output the entire message to stream + virtual EncodeStream& encode(EncodeStream& strm) const + { + strm << (mIsClientTransaction ? Data("Client ") : Data("Server ") ) + << Data("DnsResultMessage: tid=") << mTid; + return strm; + } + /// output a brief description to stream + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + strm << (mIsClientTransaction ? Data("Client ") : Data("Server ") ) + << Data("DnsResultMessage: tid=") << mTid; + return strm; + } + + private: + DnsResultMessage(); + resip::Data mTid; + bool mIsClientTransaction; +}; +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/Doxyfile b/src/libs/resiprocate/resip/stack/Doxyfile new file mode 100644 index 00000000..f3cbe87f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Doxyfile @@ -0,0 +1,209 @@ +# Doxyfile 1.3.5 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = reSIProcate +PROJECT_NUMBER = +OUTPUT_DIRECTORY = doxygen/ +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = YES +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = YES +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = +FILE_PATTERNS = *.cxx \ + *.hxx \ + *.doc +RECURSIVE = YES +EXCLUDE = test/ +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = YES +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = NO +COLLABORATION_GRAPH = NO +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 0 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/src/libs/resiprocate/resip/stack/DtlsMessage.cxx b/src/libs/resiprocate/resip/stack/DtlsMessage.cxx new file mode 100644 index 00000000..0860614c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DtlsMessage.cxx @@ -0,0 +1,67 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "resip/stack/DtlsMessage.hxx" + +#ifdef USE_DTLS + +using namespace resip ; + +DtlsMessage::DtlsMessage( SSL *ssl ) + : mSsl( ssl ) +{ +} + +#endif /* USE_DTLS */ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/DtlsMessage.hxx b/src/libs/resiprocate/resip/stack/DtlsMessage.hxx new file mode 100644 index 00000000..437b198b --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DtlsMessage.hxx @@ -0,0 +1,90 @@ +#ifndef RESIP_DTLSMESSAGE_HXX +#define RESIP_DTLSMESSAGE_HXX + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#ifdef USE_DTLS + +#include "resip/stack/Message.hxx" + +#include <openssl/ssl.h> + +#if (OPENSSL_VERSION_NUMBER < 0x0090800fL ) +#error DTLS support requires OpenSSL 0.9.8 or later +#endif + +namespace resip +{ + +class DtlsMessage : public Message +{ + public: + RESIP_HeapCount(DtlsMessage); + DtlsMessage(SSL *ssl); + virtual ~DtlsMessage() + {} + virtual Message * clone() const { return new DtlsMessage(mSsl); } + virtual EncodeStream& encode(EncodeStream& strm) const { return strm ; } + virtual EncodeStream& encodeBrief(EncodeStream& str) const { str << mSsl; return str; } + + SSL *getSsl() { return mSsl ; } + + private: + SSL *mSsl ; +} ; + +} + +#endif /* USE_DTLS */ + +#endif /* ! RESIP_DTLSMESSAGE_HXX */ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Embedded.cxx b/src/libs/resiprocate/resip/stack/Embedded.cxx new file mode 100644 index 00000000..c810164c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Embedded.cxx @@ -0,0 +1,194 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + + +#include <cassert> + +#include "resip/stack/Embedded.hxx" +#include "rutil/Data.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +char fromHex(char h1, char h2) +{ + h1 = toupper(h1); + h2 = toupper(h2); + + int i1; + int i2; + + if (isdigit(h1)) + { + i1 = h1 - '0'; + } + else + { + i1 = h1 - 'A' + 10; + } + + if (isdigit(h2)) + { + i2 = h2 - '0'; + } + else + { + i2 = h2 - 'A' + 10; + } + + return i1*16+i2; +} + +char* +Embedded::decode(const Data& in, unsigned int& count) +{ + const char *get = in.data(); + const char *end = get + in.size(); + char *ret = new char[in.size()]; + char *put = ret; + + count = 0; + while (get < end) + { + if (*get == Symbols::PERCENT[0] && get+2 < end) + { + *put = fromHex(*(get+1), *(get+2)); + get += 3; + } + else + { + *put = *get; + get++; + } + count++; + put++; + } + + return ret; +} + +static char hexMap[] = "0123456789ABCDEF"; + +/* + This method encodes the hname and hvalue production of SIP-URI. + + SIP-URI = "sip:" [ userinfo ] hostport + uri-parameters [ headers ] + + headers = "?" header *( "&" header ) + header = hname "=" hvalue + hname = 1*( hnv-unreserved / unreserved / escaped ) + hvalue = *( hnv-unreserved / unreserved / escaped ) + + hnv-unreserved = "[" / "]" / "/" / "?" / ":" / "+" / "$" + + unreserved = alphanum / mark + mark = "-" / "_" / "." / "!" / "~" / "*" / "'" + / "(" / ")" + escaped = "%" HEXDIG HEXDIG + + alphanum = ALPHA / DIGIT + + It is both unsafe and unwise to express what needs to be escaped + and simply not escape everything else, because the omission of an item + in need of escaping will cause mis-parsing on the remote end. + Because escaping unnecessarily causes absolutely no harm, the omission + of a symbol from the list of items positively allowed causes no + damage whatsoever. +*/ + +Data +Embedded::encode(const Data& dat) +{ + Data out((int)((dat.size()*11)/10), Data::Preallocate); + + { + DataStream str(out); + for (Data::size_type i = 0; i < dat.size(); i++) + { + switch (dat[i]) + { + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': case 'a': case 'b': + case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': + case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': + case 'o': case 'p': case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': case '[': case ']': case ',': case '?': + case ':': case '+': case '$': case '-': case '_': case '.': + case '!': case '~': case '*': case '\'': case '(': case ')': + str << dat[i]; + break; + + default: + { + str << Symbols::PERCENT; + + unsigned char temp = dat[i]; + int hi = (temp & 0xf0)>>4; + int low = (temp & 0xf); + + str << hexMap[hi]; + str << hexMap[low]; + } + } + } + } + + return out; +} +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Embedded.hxx b/src/libs/resiprocate/resip/stack/Embedded.hxx new file mode 100644 index 00000000..b0db27fc --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Embedded.hxx @@ -0,0 +1,71 @@ +#if !defined(RESIP_EMBEDDED_HXX) +#define RESIP_EMBEDDED_HXX + +namespace resip +{ + +class Data; + +class Embedded +{ + public: + static char* decode(const Data& input, unsigned int& decodedLength); + static Data encode(const Data& input); + + private: + Embedded(); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/EnableFlowTimer.hxx b/src/libs/resiprocate/resip/stack/EnableFlowTimer.hxx new file mode 100644 index 00000000..185d4aeb --- /dev/null +++ b/src/libs/resiprocate/resip/stack/EnableFlowTimer.hxx @@ -0,0 +1,94 @@ +#ifndef EnableFlowTimer_Include_Guard +#define EnableFlowTimer_Include_Guard + +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/Tuple.hxx" + +namespace resip +{ +class EnableFlowTimer : public TransactionMessage +{ + public: + explicit EnableFlowTimer(const resip::Tuple& flow) : + mFlow(flow) + {} + virtual ~EnableFlowTimer(){} + + virtual const Data& getTransactionId() const {return Data::Empty;} + const Tuple& getFlow() const { return mFlow; } + + virtual bool isClientTransaction() const {return true;} + virtual EncodeStream& encode(EncodeStream& strm) const + { + return strm << "EnableFlowTimer: " << mFlow; + } + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "EnableFlowTimer: " << mFlow; + } + + virtual Message* clone() const + { + return new EnableFlowTimer(*this); + } + + protected: + const resip::Tuple mFlow; + +}; // class EnableFlowTimer + +} // namespace resip + +#endif // include guard + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ + diff --git a/src/libs/resiprocate/resip/stack/EventStackThread.cxx b/src/libs/resiprocate/resip/stack/EventStackThread.cxx new file mode 100644 index 00000000..142a97dc --- /dev/null +++ b/src/libs/resiprocate/resip/stack/EventStackThread.cxx @@ -0,0 +1,219 @@ +#include <climits> + +#include "resip/stack/EventStackThread.hxx" +#include "resip/stack/SipStack.hxx" +//#include "resip/stack/SipMessage.hxx" +//#include "rutil/SelectInterruptor.hxx" +//#include "resip/stack/FdPoll.hxx" + +#include "rutil/Logger.hxx" +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +using namespace resip; + +/**************************************************************** + * + * EventThreadInterruptor + * + ****************************************************************/ + +EventThreadInterruptor::EventThreadInterruptor(FdPollGrp& pollGrp) + : mPollGrp(pollGrp) +{ + mPollItemHandle = mPollGrp.addPollItem(getReadSocket(), FPEM_Read, this); +} + +EventThreadInterruptor::~EventThreadInterruptor() +{ + mPollGrp.delPollItem(mPollItemHandle); +} + +/**************************************************************** + * + * EventStackThread + * + ****************************************************************/ + +EventStackThread::EventStackThread(EventThreadInterruptor& si, + FdPollGrp& pollGrp) + : mIntr(si), mPollGrp(pollGrp) +{ +} + +EventStackThread::EventStackThread(SipStack& stack, EventThreadInterruptor& si, + FdPollGrp& pollGrp) + : mIntr(si), mPollGrp(pollGrp) +{ + addStack(stack); +} + + +EventStackThread::~EventStackThread() +{ + //InfoLog (<< "EventStackThread::~EventStackThread()"); +} + +void +EventStackThread::addStack(SipStack& stack) +{ + mStacks.push_back(&stack); +} + +void +EventStackThread::thread() +{ + while (!isShutdown()) + { + unsigned waitMs = getTimeTillNextProcessMS(); + if ( waitMs > INT_MAX ) + waitMs = INT_MAX; + StackList::iterator it; + for ( it=mStacks.begin(); it!=mStacks.end(); ++it) + { + SipStack *ss = *it; + unsigned wms = ss->getTimeTillNextProcessMS(); + if ( wms < waitMs ) + waitMs = wms; + // NOTE: In theory, we could early-out when waitMs gets to zero + // but I fear the stack may depend upon doing real-work in the query. + } + mPollGrp.waitAndProcess((int)waitMs); + for ( it=mStacks.begin(); it!=mStacks.end(); ++it) + { + SipStack *ss = *it; + ss->processTimers(); + } + afterProcess(); + } + InfoLog (<< "Shutting down stack thread"); +} + +void +EventStackThread::shutdown() +{ + ThreadIf::shutdown(); + mIntr.interrupt(); +} + +unsigned int +EventStackThread::getTimeTillNextProcessMS() const +{ + return 10000; +} + +void +EventStackThread::afterProcess() +{ +} + + +/**************************************************************** + * + * EventStackSimpleMgr + * + * This is a helper class that constructs the thread-related + * classes in the appropriate order, and destructs them when done. + * It is to help save typing in simple applications. + * + ****************************************************************/ + +EventStackSimpleMgr::EventStackSimpleMgr(const char *implName) + : mPollGrp(0), mIntr(0), mThread(0), mStack(0) +{ + mPollGrp = FdPollGrp::create(implName); + mIntr = new EventThreadInterruptor(*mPollGrp); + mThread = new EventStackThread(*mIntr, *mPollGrp); +} + +EventStackSimpleMgr::~EventStackSimpleMgr() +{ + release(); +} + +void +EventStackSimpleMgr::setOptions(SipStackOptions& options) +{ + options.mPollGrp = mPollGrp; + options.mAsyncProcessHandler = mIntr; +} + + +SipStack& +EventStackSimpleMgr::createStack(SipStackOptions& options) +{ + setOptions(options); + mStack = new SipStack(options); + mThread->addStack(*mStack); + return *mStack; +} + +void +EventStackSimpleMgr::release() { + if ( mThread ) + { + delete mThread; mThread = NULL; + } + if ( mStack ) { + // we only delete the stack if we created, not if externally created + delete mStack; mStack = NULL; + } + if ( mIntr ) + { + delete mIntr; mIntr = NULL; + } + if ( mPollGrp ) + { + delete mPollGrp; mPollGrp = NULL; + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/EventStackThread.hxx b/src/libs/resiprocate/resip/stack/EventStackThread.hxx new file mode 100644 index 00000000..be107b3c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/EventStackThread.hxx @@ -0,0 +1,201 @@ +#ifndef RESIP_EventStackThread__hxx +#define RESIP_EventStackThread__hxx + +#include <vector> + +#include "rutil/ThreadIf.hxx" +#include "rutil/FdPoll.hxx" +#include "rutil/SelectInterruptor.hxx" + +namespace resip +{ + +class SipStackOptions; +class SipStack; +class SelectInterruptor; +class EventThreadInterruptor; +class FdPollGrp; + +/** + This class creates a thread in which to run one or more SipStacks. The + thread provides cycles to the stack(s). It provides cycles in 3 ways: + 1. When socket-io is possible, the event-loop will directly invoke + the registered callback. + 2. Prior to waiting for events, getTimeTillNextProcessMS() is called + on all stacks. + 3. After waiting, processTimers() is called on all stacks. + + This implementation improves on StackThread and IntrruptableStackThread, + by using the epoll() based system call (if available) provided + by the FdPoll class. + + Note that this is different than the InterruptableStackThread and + simple StackThread in that it doesn't use the buildFdSet()/process() + flow. + + You must register {si} as an AsyncProcessHandler on the + stacks in order to use this class. The same {si} instance must be + used for all stacks. +**/ +class EventStackThread : public ThreadIf +{ + public: + EventStackThread(EventThreadInterruptor& si, FdPollGrp& pollGrp); + EventStackThread(SipStack& stack, EventThreadInterruptor& si, FdPollGrp& pollGrp); + virtual ~EventStackThread(); + + /* + * If you use the 1st constructor form, use this after creating + * the stack to add it into the list to which the thread is providing + * cycles. Even with only one active stack, this approach can + * be used to solve the cyclic initialization problem. + */ + void addStack(SipStack& stack); + + virtual void thread(); + virtual void shutdown(); + + protected: + /* + * Return time (in milliseconds) until your next timer, or + * ~30sec for infinity. + */ + virtual unsigned int getTimeTillNextProcessMS() const; + + /* + * Called after all socket IO and sip stack timers. Process + * any application timers here. + */ + virtual void afterProcess(); + + private: + typedef std::vector<SipStack*> StackList; + StackList mStacks; + EventThreadInterruptor& mIntr; + FdPollGrp& mPollGrp; +}; + + + +class EventThreadInterruptor : public SelectInterruptor +{ + public: + EventThreadInterruptor(FdPollGrp& pollGrp); + virtual ~EventThreadInterruptor(); + protected: + FdPollGrp& mPollGrp; // used just to remove ourselves + FdPollItemHandle mPollItemHandle; +}; + +/** + Helper class to properly manage event loop for simple applications. + + To use: + { + EventStackSimpleMgr myMgr(implName); + SipStackOptions options; + options.something = something; + SipStack& myStack = myMgr.createStack(options); + // do other init here (like start dum) + myMgr.getThread.run(); + // loop doing stuff with myStack until app finished + myMgr.getThread.shutdown(); + myMgr.getThread.join(); + } + + There is nothing unique about this class; you can inline it all + into your app if want. +**/ +class EventStackSimpleMgr +{ + public: + EventStackSimpleMgr(const char *implName); + ~EventStackSimpleMgr(); + /* + * Configure {options} with our pollGrp and asyncHandler. + * Use this prior to creating your SipStack instance. + */ + void setOptions(SipStackOptions& options); + + /* + * Convenience function to create SipStack instance. Will add + * appropriate options, cerate the stack and add the stack to + * the thread. + */ + SipStack& createStack(SipStackOptions& options); + + + /* + * Thread accessor. + * Use this to invoke addStack(), run(), shutdown(), join(), etc. + */ + EventStackThread& getThread() { assert(mThread); return *mThread; } + + /* + * Call to release all owned resources early. Stack must be + * stopped and thread joined prior to releasing. + */ + void release(); + + protected: + FdPollGrp* mPollGrp; + EventThreadInterruptor* mIntr; + EventStackThread* mThread; + SipStack* mStack; +}; + +} // namespace + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/ExistsOrDataParameter.cxx b/src/libs/resiprocate/resip/stack/ExistsOrDataParameter.cxx new file mode 100644 index 00000000..a567d754 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExistsOrDataParameter.cxx @@ -0,0 +1,72 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <cassert> +#include "rutil/ParseException.hxx" +#include "resip/stack/ExistsOrDataParameter.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +namespace resip +{ + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + + +ExistsOrDataParameter::ExistsOrDataParameter(ParameterTypes::Type type, bool) : + DataParameter(type) +{ +} + +ExistsOrDataParameter::ExistsOrDataParameter(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators) + : DataParameter(type, pb, terminators) +{ +} + +ExistsOrDataParameter::ExistsOrDataParameter(ParameterTypes::Type type) + : DataParameter(type) +{ +} + +Parameter* +ExistsOrDataParameter::decode(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators, + PoolBase* pool) +{ + pb.skipWhitespace(); + if (pb.eof() || terminators[*pb.position()]) + { + return new (pool) ExistsOrDataParameter(type); + } + else + { + return new (pool) ExistsOrDataParameter(type, pb, terminators); + } +} + +Parameter* +ExistsOrDataParameter::clone() const +{ + return new ExistsOrDataParameter(*this); +} + +EncodeStream& +ExistsOrDataParameter::encode(EncodeStream& stream) const +{ + if (mValue.empty()) + { + return stream << getName(); + } + else + { + return DataParameter::encode(stream); + } +} + +} // namespace resip diff --git a/src/libs/resiprocate/resip/stack/ExistsOrDataParameter.hxx b/src/libs/resiprocate/resip/stack/ExistsOrDataParameter.hxx new file mode 100644 index 00000000..544e1381 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExistsOrDataParameter.hxx @@ -0,0 +1,94 @@ +#if !defined(RESIP_ExistsOrDataParameter_HXX) +#define RESIP_ExistsOrDataParameter_HXX + +#include "resip/stack/Parameter.hxx" +#include "resip/stack/ParameterTypeEnums.hxx" +#include "resip/stack/QuotedDataParameter.hxx" +#include "rutil/PoolBase.hxx" +#include <iosfwd> + +namespace resip +{ + +class ParseBuffer; + +class ExistsOrDataParameter : public DataParameter +{ + public: + explicit ExistsOrDataParameter(ParameterTypes::Type); + ExistsOrDataParameter(ParameterTypes::Type, bool); + + ExistsOrDataParameter(ParameterTypes::Type, ParseBuffer& pb, + const std::bitset<256>& terminators); + + virtual EncodeStream& encode(EncodeStream& stream) const; + + static Parameter* decode(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators, + PoolBase* pool); + + virtual Parameter* clone() const; + + protected: + ExistsOrDataParameter(const ExistsOrDataParameter& other) + : DataParameter(other) + {} + + friend class ParserCategory; + friend class Auth; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ExistsParameter.cxx b/src/libs/resiprocate/resip/stack/ExistsParameter.cxx new file mode 100644 index 00000000..7d922b49 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExistsParameter.cxx @@ -0,0 +1,109 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/ExistsParameter.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +ExistsParameter::ExistsParameter(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators) + : Parameter(type), + mValue(true) +{ + // Protect ourselves just in case an exists parameter has a RHS. + pb.skipWhitespace(); + if (!pb.eof() && *pb.position() == Symbols::EQUALS[0]) + { + pb.skipChar(); + if (!pb.eof() && *pb.position() == Symbols::DOUBLE_QUOTE[0]) + { + pb.skipChar(); + pb.skipToEndQuote(); + } + else + { + pb.skipToOneOf(terminators); + } + } +} + +ExistsParameter::ExistsParameter(ParameterTypes::Type type) + : Parameter(type), + mValue(true) +{} + +Parameter* +ExistsParameter::clone() const +{ + return new ExistsParameter(*this); +} + +EncodeStream& +ExistsParameter::encode(EncodeStream& stream) const +{ + if (mValue) + { + stream << getName(); + } + return stream; +} + + + + + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ExistsParameter.hxx b/src/libs/resiprocate/resip/stack/ExistsParameter.hxx new file mode 100644 index 00000000..f8416881 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExistsParameter.hxx @@ -0,0 +1,95 @@ +#if !defined(RESIP_EXISTSPARAMETER_HXX) +#define RESIP_EXISTSPARAMETER_HXX + +#include "resip/stack/Parameter.hxx" +#include "rutil/PoolBase.hxx" +#include <iosfwd> + +namespace resip +{ + +class ParseBuffer; + +/** + @ingroup sip_grammar + + @brief Represents various parameters that are indicated to be in + effect merely by being present, e.g. ";lr" +*/ +class ExistsParameter : public Parameter +{ + public: + typedef bool Type; + + ExistsParameter(ParameterTypes::Type, ParseBuffer& pb, const std::bitset<256>& terminators); + explicit ExistsParameter(ParameterTypes::Type type); + + static Parameter* decode(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators, + PoolBase* pool) + { + return new (pool) ExistsParameter(type, pb, terminators); + } + + virtual Parameter* clone() const; + virtual EncodeStream& encode(EncodeStream& stream) const; + Type& value() {return mValue;} + + private: + Type mValue; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ExpiresCategory.cxx b/src/libs/resiprocate/resip/stack/ExpiresCategory.cxx new file mode 100644 index 00000000..2c1b041d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExpiresCategory.cxx @@ -0,0 +1,210 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/ExpiresCategory.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// Expires: +//==================== +ExpiresCategory:: ExpiresCategory() + : ParserCategory(), + mValue(0) +{} + +ExpiresCategory::ExpiresCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), mValue(0) +{} + +ExpiresCategory::ExpiresCategory(const ExpiresCategory& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mValue(rhs.mValue) +{} + +ExpiresCategory& +ExpiresCategory::operator=(const ExpiresCategory& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mValue = rhs.mValue; + } + return *this; +} + +ParserCategory* ExpiresCategory::clone() const +{ + return new ExpiresCategory(*this); +} + +ParserCategory* ExpiresCategory::clone(void* location) const +{ + return new (location) ExpiresCategory(*this); +} + +ParserCategory* +ExpiresCategory::clone(PoolBase* pool) const +{ + return new (pool) ExpiresCategory(*this, pool); +} + +UInt32& +ExpiresCategory::value() +{ + checkParsed(); + return mValue; +} + +UInt32 +ExpiresCategory::value() const +{ + checkParsed(); + return mValue; +} + +void +ExpiresCategory::parse(ParseBuffer& pb) +{ + pb.skipWhitespace(); + const char *p = pb.position(); + if (!pb.eof() && isdigit(*p)) + { + mValue = pb.uInt32(); + } + else + { + mValue = 3600; + } + pb.skipToChar(Symbols::SEMI_COLON[0]); + parseParameters(pb); +} + +EncodeStream& +ExpiresCategory::encodeParsed(EncodeStream& str) const +{ + str << mValue; + encodeParameters(str); + return str; +} + +ParameterTypes::Factory ExpiresCategory::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; + +Parameter* +ExpiresCategory::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) +{ + if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) + { + return ParameterFactories[type](type, pb, terminators, pool); + } + return 0; +} + +bool +ExpiresCategory::exists(const Param<ExpiresCategory>& paramType) const +{ + checkParsed(); + bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; + return ret; +} + +void +ExpiresCategory::remove(const Param<ExpiresCategory>& paramType) +{ + checkParsed(); + removeParameterByEnum(paramType.getTypeNum()); +} + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ +_enum##_Param::DType& \ +ExpiresCategory::param(const _enum##_Param& paramType) \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + p = new _enum##_Param::Type(paramType.getTypeNum()); \ + mParameters.push_back(p); \ + } \ + return p->value(); \ +} \ + \ +const _enum##_Param::DType& \ +ExpiresCategory::param(const _enum##_Param& paramType) const \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ + DebugLog(<< *this); \ + throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ + } \ + return p->value(); \ +} + +defineParam(refresher, "refresher", DataParameter, "RFC 4028"); + +#undef defineParam + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ExpiresCategory.hxx b/src/libs/resiprocate/resip/stack/ExpiresCategory.hxx new file mode 100644 index 00000000..110da78c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExpiresCategory.hxx @@ -0,0 +1,118 @@ +#if !defined(RESIP_EXPIRES_CATEGORY_HXX) +#define RESIP_EXPIRES_CATEGORY_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" + +namespace resip +{ + +/** + @ingroup sip_grammar + @brief Represents the header field value for an Expires-type header. (Numeric + with no comment) + @todo Seems like this and UInt32Category (numeric _with_ a comment) could be + renamed to something a little more self-explanatory. + +*/ +class ExpiresCategory : public ParserCategory +{ + public: + enum {commaHandling = NoCommaTokenizing}; + + ExpiresCategory(); + ExpiresCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + ExpiresCategory(const ExpiresCategory& orig, + PoolBase* pool=0); + ExpiresCategory& operator=(const ExpiresCategory&); + + virtual void parse(ParseBuffer& pb); + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + + UInt32& value(); + UInt32 value() const; + + // Inform the compiler that overloads of these may be found in + // ParserCategory, too. + using ParserCategory::exists; + using ParserCategory::remove; + using ParserCategory::param; + + virtual Parameter* createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool); + // .bwc, This is an awful lot for one lousy param type. + bool exists(const Param<ExpiresCategory>& paramType) const; + void remove(const Param<ExpiresCategory>& paramType); + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ + const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \ + _enum##_Param::DType& param(const _enum##_Param& paramType); \ + friend class _enum##_Param + +defineParam(refresher, "refresher", DataParameter, "RFC 4028"); + +#undef defineParam + + private: + UInt32 mValue; + + static ParameterTypes::Factory ParameterFactories[ParameterTypes::MAX_PARAMETER]; +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ExtensionHeader.cxx b/src/libs/resiprocate/resip/stack/ExtensionHeader.cxx new file mode 100644 index 00000000..ce5571c8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExtensionHeader.cxx @@ -0,0 +1,103 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "ExtensionHeader.hxx" +#include "HeaderTypes.hxx" +#include "rutil/Logger.hxx" + +#include <cassert> +#include "rutil/ParseBuffer.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +using namespace resip; + +ExtensionHeader::ExtensionHeader(const char* name) + : mName(name) +{ + assert(name); + if (mName.empty()) + { + assert(false); + throw Exception("Empty extension header",__FILE__,__LINE__); + } + assert(Headers::getType(mName.data(), (int)mName.size()) == Headers::UNKNOWN); +} + +ExtensionHeader::ExtensionHeader(const Data& name) + : mName(name) +{ + if (mName.empty()) + { + assert(false); + throw Exception("Empty extension header",__FILE__,__LINE__); + } + assert(Headers::getType(mName.data(), (int)mName.size()) == Headers::UNKNOWN); +} + +const Data& +ExtensionHeader::getName() const +{ + return mName; +} + +ExtensionHeader::Exception::Exception(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) +{} + +const char* +ExtensionHeader::Exception::name() const +{ + return "ExtensionHeader::Exception"; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ExtensionHeader.hxx b/src/libs/resiprocate/resip/stack/ExtensionHeader.hxx new file mode 100644 index 00000000..6c3365e7 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExtensionHeader.hxx @@ -0,0 +1,80 @@ +#ifndef RESIP_ExtensionHeader_hxx +#define RESIP_ExtensionHeader_hxx + +#include "rutil/Data.hxx" +#include "rutil/BaseException.hxx" +namespace resip +{ + +class ExtensionHeader +{ + public: + explicit ExtensionHeader(const char* unknownHeaderName); + explicit ExtensionHeader(const Data& unknownHeaderName); + + const Data& getName() const; + + class Exception : public BaseException + { + public: + Exception(const Data& msg, const Data& file, const int line); + const char* name() const; + }; + + private: + const Data mName; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ExtensionParameter.cxx b/src/libs/resiprocate/resip/stack/ExtensionParameter.cxx new file mode 100644 index 00000000..4a91b9c7 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExtensionParameter.cxx @@ -0,0 +1,73 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "ExtensionParameter.hxx" +#include "ParameterTypeEnums.hxx" + +#include <cassert> +#include <string.h> + +using namespace resip; + +ExtensionParameter::ExtensionParameter(const Data& name) + : mName(name) +{ + assert(!mName.empty()); +} + +const Data& +ExtensionParameter::getName() const +{ + return mName; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ExtensionParameter.hxx b/src/libs/resiprocate/resip/stack/ExtensionParameter.hxx new file mode 100644 index 00000000..7bd83568 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExtensionParameter.hxx @@ -0,0 +1,72 @@ +#ifndef RESIP_ExtensionParameter_hxx +#define RESIP_ExtensionParameter_hxx + +#include "rutil/Data.hxx" + +namespace resip +{ + +class ExtensionParameter +{ + public: + explicit ExtensionParameter(const Data& unknownParameterName); + + const Data& getName() const; + + private: + const Data mName; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ExternalBodyContents.cxx b/src/libs/resiprocate/resip/stack/ExternalBodyContents.cxx new file mode 100644 index 00000000..854062ef --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExternalBodyContents.cxx @@ -0,0 +1,101 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/ExternalBodyContents.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::CONTENTS + +bool +ExternalBodyContents::init() +{ + static ContentsFactory<ExternalBodyContents> factory; + (void)factory; + return true; +} + +ExternalBodyContents::ExternalBodyContents() + : SipFrag(getStaticType()) +{} + +ExternalBodyContents::ExternalBodyContents(const HeaderFieldValue& hfv, const Mime& contentsType) + : SipFrag(hfv, contentsType) +{} + +ExternalBodyContents::ExternalBodyContents(const ExternalBodyContents& rhs) + : SipFrag(rhs) +{} + +ExternalBodyContents& +ExternalBodyContents::operator=(const ExternalBodyContents& rhs) +{ + SipFrag::operator=(rhs); + return *this; +} + +Contents* +ExternalBodyContents::clone() const +{ + return new ExternalBodyContents(*this); +} + +const Mime& +ExternalBodyContents::getStaticType() +{ + static Mime type("message", "external-body"); + return type; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ExternalBodyContents.hxx b/src/libs/resiprocate/resip/stack/ExternalBodyContents.hxx new file mode 100644 index 00000000..e6c0e493 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExternalBodyContents.hxx @@ -0,0 +1,86 @@ +#ifndef RESIP_ExternalBodyContents_hxx +#define RESIP_ExternalBodyContents_hxx + +#include "resip/stack/SipFrag.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type to represent contents with an external body (MIME content-type message/external-body). +*/ +class ExternalBodyContents : public SipFrag +{ + public: + ExternalBodyContents(); + ExternalBodyContents(const HeaderFieldValue& hfv, const Mime& contentType); + ExternalBodyContents(const ExternalBodyContents& rhs); + ExternalBodyContents& operator=(const ExternalBodyContents& rhs); + + /** @brief duplicate an ExternalBodyContents object + @return pointer to a new ExternalBodyContents object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType() ; + + static bool init(); +}; + +static bool invokeExternalBodyContentsInit = ExternalBodyContents::init(); + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/FAQ b/src/libs/resiprocate/resip/stack/FAQ new file mode 100644 index 00000000..32e92a6a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/FAQ @@ -0,0 +1,23 @@ +1. Changing an existing header type: +- modify the Type of the header in Headers.hxx +class Expires_Header : public HeaderBase +{ + public: + typedef ExpiresCategory Type; // this defines the type + virtual Headers::Type getTypeNum() const {return Headers::Expires;} + Expires_Header() + { + Headers::CommaTokenizing[Headers::Expires] = Type::isCommaTokenizing; + Headers::HeaderNames[Headers::Expires] = Symbols::Expires; + } +}; +- define the new derived ParserCategory according to the ParserCategoy interface + +2. Adding a new header. +- determine its type. +- add to HeaderTypes.hxx Type enum. +- create a type class in Headers.hxx +- update the gperf functions in Headers.cxx + - change the hash and in_word_set function names + - make the comparisons case insensitive + - use strcasencmp -- Data not NULL terminated diff --git a/src/libs/resiprocate/resip/stack/FloatParameter.cxx b/src/libs/resiprocate/resip/stack/FloatParameter.cxx new file mode 100644 index 00000000..63d471fe --- /dev/null +++ b/src/libs/resiprocate/resip/stack/FloatParameter.cxx @@ -0,0 +1,101 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/FloatParameter.hxx" +#include "rutil/ParseException.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +FloatParameter::FloatParameter(ParameterTypes::Type type, + ParseBuffer& pb, + const char* terminators) + : Parameter(type), + mValue(0) +{ + pb.skipWhitespace(); + if (!pb.eof() && *pb.position() != '=') + { + throw ParseException("parameter constructor expected '='", "FloatParameter", __FILE__, __LINE__); + } + pb.skipChar(); + pb.skipWhitespace(); + + // .dlb. not zero terminated; no error detection + mValue = pb.floatVal(); +} + +FloatParameter::FloatParameter(ParameterTypes::Type type) + : Parameter(type), + mValue(0.0) +{} + +Parameter* +FloatParameter::clone() const +{ + return new FloatParameter(*this); +} + +EncodeStream& +FloatParameter::encode(ostream& stream) const +{ + return stream << getName() << Symbols::EQUALS << mValue; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/FloatParameter.hxx b/src/libs/resiprocate/resip/stack/FloatParameter.hxx new file mode 100644 index 00000000..ad80222c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/FloatParameter.hxx @@ -0,0 +1,94 @@ +#if !defined(RESIP_FLOATPARAMETER_HXX) +#define RESIP_FLOATPARAMETER_HXX + +#include "resip/stack/Parameter.hxx" +#include "resip/stack/ParameterTypeEnums.hxx" +#include <iosfwd> + +namespace resip +{ + +class ParseBuffer; + +/** + @ingroup sip_grammar + + @brief Generically represents floating point values conveyed by SIP + parameters. +*/ +class FloatParameter : public Parameter +{ + public: + typedef float Type; + + FloatParameter(ParameterTypes::Type, ParseBuffer& pb, const char* terminators); + explicit FloatParameter(ParameterTypes::Type type); + + static Parameter* decode(ParameterTypes::Type type, ParseBuffer& pb, const char* terminators) + { + return new FloatParameter(type, pb, terminators); + } + + virtual Parameter* clone() const; + virtual EncodeStream& encode(std::ostream& stream) const; + + private: + friend class ParserCategory; + Type& value() {return mValue;} + + Type mValue; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/GenericContents.cxx b/src/libs/resiprocate/resip/stack/GenericContents.cxx new file mode 100644 index 00000000..1af751dc --- /dev/null +++ b/src/libs/resiprocate/resip/stack/GenericContents.cxx @@ -0,0 +1,96 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/GenericContents.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +GenericContents::GenericContents() + : PlainContents() +{} + +GenericContents::GenericContents(const Data& text) + : PlainContents(text) +{} + +GenericContents::GenericContents(const HeaderFieldValue& hfv, const Mime& contentType) + : PlainContents(hfv, contentType) +{} + +GenericContents::GenericContents(const Data& data, const Mime& contentType) + : PlainContents(data, contentType) +{} + +GenericContents::GenericContents(const GenericContents& rhs) + : PlainContents(rhs) +{} + +GenericContents::~GenericContents() +{} + +GenericContents& +GenericContents::operator=(const GenericContents& rhs) +{ + if (this != &rhs) + { + this->PlainContents::operator=(rhs); + } + return *this; +} + +Contents* +GenericContents::clone() const +{ + return new GenericContents(*this); +} +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/GenericContents.hxx b/src/libs/resiprocate/resip/stack/GenericContents.hxx new file mode 100644 index 00000000..6014546d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/GenericContents.hxx @@ -0,0 +1,84 @@ +#if !defined(RESIP_GENERICCONTENTS_HXX) +#define RESIP_GENERICCONTENTS_HXX + +#include "resip/stack/PlainContents.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type for holding generic contents. + @note not added to ContentsFactory +*/ +class GenericContents : public PlainContents +{ + public: + GenericContents(); + GenericContents(const Data& text); + GenericContents(const HeaderFieldValue& hfv, const Mime& contentType); + GenericContents(const Data& data, const Mime& contentType); + GenericContents(const GenericContents& rhs); + virtual ~GenericContents(); + GenericContents& operator=(const GenericContents& rhs); + + /** @brief duplicate an GenericContents object + @return pointer to a new GenericContents object + **/ + virtual Contents* clone() const; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/GenericUri.cxx b/src/libs/resiprocate/resip/stack/GenericUri.cxx new file mode 100644 index 00000000..8e1b9e34 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/GenericUri.cxx @@ -0,0 +1,210 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/GenericUri.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + + +//==================== +// GenericUri +//==================== +GenericUri::GenericUri(const GenericUri& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mUri(rhs.mUri) +{} + +GenericUri::GenericUri(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool) +{} + +GenericUri& +GenericUri::operator=(const GenericUri& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mUri = rhs.mUri; + } + return *this; +} + +Data& +GenericUri::uri() +{ + checkParsed(); + return mUri; +} + +const Data& +GenericUri::uri() const +{ + checkParsed(); + return mUri; +} + +void +GenericUri::parse(ParseBuffer& pb) +{ + pb.skipWhitespace(); + const char* anchor = pb.skipChar(Symbols::LA_QUOTE[0]); + + pb.skipToChar(Symbols::RA_QUOTE[0]); + pb.data(mUri, anchor); + pb.skipChar(Symbols::RA_QUOTE[0]); + + pb.skipWhitespace(); + + parseParameters(pb); +} + +ParserCategory* +GenericUri::clone() const +{ + return new GenericUri(*this); +} + +ParserCategory* +GenericUri::clone(void* location) const +{ + return new (location) GenericUri(*this); +} + +ParserCategory* +GenericUri::clone(PoolBase* pool) const +{ + return new (pool) GenericUri(*this, pool); +} + +EncodeStream& +GenericUri::encodeParsed(EncodeStream& str) const +{ + str << Symbols::LA_QUOTE[0] + << mUri + << Symbols::RA_QUOTE[0]; + + encodeParameters(str); + + return str; +} + +ParameterTypes::Factory GenericUri::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; + +Parameter* +GenericUri::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) +{ + if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) + { + return ParameterFactories[type](type, pb, terminators, pool); + } + return 0; +} + +bool +GenericUri::exists(const Param<GenericUri>& paramType) const +{ + checkParsed(); + bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; + return ret; +} + +void +GenericUri::remove(const Param<GenericUri>& paramType) +{ + checkParsed(); + removeParameterByEnum(paramType.getTypeNum()); +} + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ +_enum##_Param::DType& \ +GenericUri::param(const _enum##_Param& paramType) \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + p = new _enum##_Param::Type(paramType.getTypeNum()); \ + mParameters.push_back(p); \ + } \ + return p->value(); \ +} \ + \ +const _enum##_Param::DType& \ +GenericUri::param(const _enum##_Param& paramType) const \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ + DebugLog(<< *this); \ + throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ + } \ + return p->value(); \ +} + +defineParam(purpose, "purpose", DataParameter, "RFC 3261"); + +#undef defineParam + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/GenericUri.hxx b/src/libs/resiprocate/resip/stack/GenericUri.hxx new file mode 100644 index 00000000..7835576f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/GenericUri.hxx @@ -0,0 +1,117 @@ +#if !defined(RESIP_GENERIC_URI_HXX) +#define RESIP_GENERIC_URI_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/ParserContainer.hxx" + +namespace resip +{ + +/** + @ingroup sip_grammar + @brief Represents the "absoluteURI" element in the RFC 3261 grammar. +*/ +class GenericUri : public ParserCategory +{ + public: + enum {commaHandling = CommasAllowedOutputMulti}; + + GenericUri() : ParserCategory() {} + GenericUri(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + GenericUri(const GenericUri& orig, + PoolBase* pool=0); + GenericUri& operator=(const GenericUri&); + + virtual void parse(ParseBuffer& pb); + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + + Data& uri(); + const Data& uri() const; + + // Inform the compiler that overloads of these may be found in + // ParserCategory, too. + using ParserCategory::exists; + using ParserCategory::remove; + using ParserCategory::param; + + virtual Parameter* createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool); + // .bwc, This is an awful lot for one lousy param type. + bool exists(const Param<GenericUri>& paramType) const; + void remove(const Param<GenericUri>& paramType); + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ + const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \ + _enum##_Param::DType& param(const _enum##_Param& paramType); \ + friend class _enum##_Param + +defineParam(purpose, "purpose", DataParameter, "RFC 3261"); + +#undef defineParam + + private: + Data mUri; + + static ParameterTypes::Factory ParameterFactories[ParameterTypes::MAX_PARAMETER]; +}; +typedef ParserContainer<GenericUri> GenericUris; +typedef GenericUri GenericURI; //.dcm. deprecated, should be removed soon +} + + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/HeaderFieldValue.cxx b/src/libs/resiprocate/resip/stack/HeaderFieldValue.cxx new file mode 100644 index 00000000..e12f31fb --- /dev/null +++ b/src/libs/resiprocate/resip/stack/HeaderFieldValue.cxx @@ -0,0 +1,177 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <iostream> + +#include "resip/stack/UnknownParameter.hxx" +#include "resip/stack/ExistsParameter.hxx" +#include "resip/stack/HeaderFieldValue.hxx" +#include "resip/stack/MsgHeaderScanner.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace std; +using namespace resip; + + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +const HeaderFieldValue HeaderFieldValue::Empty; + +HeaderFieldValue::HeaderFieldValue(const char* field, unsigned int fieldLength) + : mField(field), + mFieldLength(fieldLength), + mMine(false) +{} + +HeaderFieldValue::HeaderFieldValue(const HeaderFieldValue& hfv) + : mField(0), + mFieldLength(hfv.mFieldLength), + mMine(true) +{ + if(mFieldLength) + { + char* newField = new char[mFieldLength]; + memcpy(newField, hfv.mField, mFieldLength); + mField=newField; + } +} + +HeaderFieldValue& +HeaderFieldValue::operator=(const HeaderFieldValue& rhs) +{ + if(this!=&rhs) + { + mFieldLength=rhs.mFieldLength; + if(mMine) delete [] mField; + mMine=true; + if(mFieldLength) + { + char* newField = new char[mFieldLength]; + memcpy(newField, rhs.mField, mFieldLength); + mField=newField; + } + else + { + mField=0; + } + } + + return *this; +} + +HeaderFieldValue& +HeaderFieldValue::copyWithPadding(const HeaderFieldValue& rhs) +{ + if(this!=&rhs) + { + mFieldLength=rhs.mFieldLength; + if(mMine) delete [] mField; + mMine=true; + if(mFieldLength) + { + char* newField = MsgHeaderScanner::allocateBuffer(mFieldLength); + memcpy(newField, rhs.mField, mFieldLength); + mField=newField; + } + else + { + mField=0; + } + } + + return *this; +} + +HeaderFieldValue::HeaderFieldValue(const HeaderFieldValue& hfv, CopyPaddingEnum e) + : mField(0), + mFieldLength(hfv.mFieldLength), + mMine(true) +{ + char* newField = MsgHeaderScanner::allocateBuffer(mFieldLength); + memcpy(newField, hfv.mField, mFieldLength); + mField=newField; +} + +HeaderFieldValue::HeaderFieldValue(const HeaderFieldValue& hfv, NoOwnershipEnum n) + : mField(hfv.mField), + mFieldLength(hfv.mFieldLength), + mMine(false) +{ + // ?bwc? assert(!hfv.mMine); ? +} + +HeaderFieldValue::~HeaderFieldValue() +{ + if (mMine) + { + delete[] mField; + } +} + +EncodeStream& +HeaderFieldValue::encode(EncodeStream& str) const +{ + str.write(mField, mFieldLength); + return str; +} + +EncodeStream& resip::operator<<(EncodeStream& stream, HeaderFieldValue& hfv) +{ + hfv.encode(stream); + return stream; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/HeaderFieldValue.hxx b/src/libs/resiprocate/resip/stack/HeaderFieldValue.hxx new file mode 100644 index 00000000..393e3330 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/HeaderFieldValue.hxx @@ -0,0 +1,154 @@ +#if !defined(RESIP_HEADERFIELDVALUE_HXX) +#define RESIP_HEADERFIELDVALUE_HXX + +#include "rutil/ParseException.hxx" +#include "rutil/Data.hxx" +#include "resip/stack/ParameterTypes.hxx" + +#include <iosfwd> + +namespace resip +{ + +class ParserCategory; +class UnknownParameter; +class ParseBuffer; + +/** + @internal +*/ +class HeaderFieldValue +{ + public: + static const HeaderFieldValue Empty; + + enum CopyPaddingEnum + { + CopyPadding + }; + + enum NoOwnershipEnum + { + NoOwnership + }; + + HeaderFieldValue() + : mField(0), //this must be initialized to 0 or ParserCategory will parse + mFieldLength(0), + mMine(false) + {} + HeaderFieldValue(const char* field, unsigned int fieldLength); + HeaderFieldValue(const HeaderFieldValue& hfv); + HeaderFieldValue(const HeaderFieldValue& hfv, CopyPaddingEnum); + HeaderFieldValue(const HeaderFieldValue& hfv, NoOwnershipEnum); + HeaderFieldValue& operator=(const HeaderFieldValue&); + HeaderFieldValue& copyWithPadding(const HeaderFieldValue& rhs); + + ~HeaderFieldValue(); + + EncodeStream& encode(EncodeStream& str) const; + + inline void init(const char* field, size_t length, bool own) + { + if(mMine) + { + delete [] mField; + } + + mField=field; + mFieldLength=(unsigned int)length; + mMine=own; + } + + inline const char* getBuffer() const {return mField;} + inline unsigned int getLength() const {return mFieldLength;} + inline void clear() + { + if (mMine) + { + delete[] mField; + mMine=false; + } + mField=0; + mFieldLength=0; + } + + // const because Data::Share implies read-only access + void toShareData(Data& data) const + { + data.setBuf(Data::Share, mField, mFieldLength); + } + + // not const because Data::Borrow implies read/write access + void toBorrowData(Data& data) + { + data.setBuf(Data::Borrow, mField, mFieldLength); + } + + private: + + const char* mField; + unsigned int mFieldLength; + bool mMine; + + friend EncodeStream& operator<<(EncodeStream&, HeaderFieldValue&); +}; + +EncodeStream& operator<<(EncodeStream& stream, + HeaderFieldValue& hList); + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/HeaderFieldValueList.cxx b/src/libs/resiprocate/resip/stack/HeaderFieldValueList.cxx new file mode 100644 index 00000000..0dd9190a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/HeaderFieldValueList.cxx @@ -0,0 +1,264 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + + +#include <cassert> + +#include "resip/stack/HeaderFieldValue.hxx" +#include "resip/stack/HeaderFieldValueList.hxx" +#include "resip/stack/ParserContainerBase.hxx" +#include "resip/stack/Embedded.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +const HeaderFieldValueList HeaderFieldValueList::Empty; + +HeaderFieldValueList::~HeaderFieldValueList() +{ + freeParserContainer(); +} + +HeaderFieldValueList::HeaderFieldValueList(const HeaderFieldValueList& rhs) + : mHeaders(), + mPool(0), + mParserContainer(0) +{ + if (rhs.mParserContainer) + { + mParserContainer = rhs.mParserContainer->clone(); + } + else if(rhs.mHeaders.size()) + { + mHeaders=rhs.mHeaders; + } +} + +HeaderFieldValueList::HeaderFieldValueList(const HeaderFieldValueList& rhs, PoolBase& pool) + : mHeaders(StlPoolAllocator<HeaderFieldValue, PoolBase>(&pool)), + mPool(&pool), + mParserContainer(0) +{ + if (rhs.mParserContainer) + { + mParserContainer = rhs.mParserContainer->clone(); + } + else if(rhs.mHeaders.size()) + { + mHeaders=rhs.mHeaders; + } +} + +HeaderFieldValueList& +HeaderFieldValueList::operator=(const HeaderFieldValueList& rhs) +{ + if(this!=&rhs) + { + mHeaders.clear(); + + freeParserContainer(); + + if (rhs.mParserContainer != 0) + { + mParserContainer = rhs.mParserContainer->clone(); + } + else + { + mHeaders=rhs.mHeaders; + } + } + + return *this; +} + +EncodeStream& +HeaderFieldValueList::encode(int headerEnum, EncodeStream& str) const +{ + const Data& headerName = Headers::getHeaderName(static_cast<Headers::Type>(headerEnum)); + + if (getParserContainer() != 0) + { + getParserContainer()->encode(headerName, str); + } + else + { + if (!headerName.empty()) + { + str << headerName << Symbols::COLON[0] << Symbols::SPACE[0]; + } + + for (HeaderFieldValueList::const_iterator j = begin(); + j != end(); j++) + { + if (j != begin()) + { + if (Headers::isCommaEncoding(static_cast<Headers::Type>(headerEnum))) + { + str << Symbols::COMMA[0] << Symbols::SPACE[0]; + } + else + { + str << Symbols::CRLF << headerName << Symbols::COLON << Symbols::SPACE; + } + } + j->encode(str); + } + str << Symbols::CRLF; + } + return str; +} + +EncodeStream& +HeaderFieldValueList::encode(const Data& headerName, EncodeStream& str) const +{ + if (getParserContainer() != 0) + { + getParserContainer()->encode(headerName, str); + } + else + { + if (!headerName.empty()) + { + str << headerName << Symbols::COLON << Symbols::SPACE; + } + for (HeaderFieldValueList::const_iterator j = begin(); + j != end(); j++) + { + if (j != begin()) + { + str << Symbols::COMMA[0] << Symbols::SPACE[0]; + } + j->encode(str); + } + str << Symbols::CRLF; + } + return str; +} + +EncodeStream& +HeaderFieldValueList::encodeEmbedded(const Data& headerName, EncodeStream& str) const +{ + assert(!headerName.empty()); + + if (getParserContainer() != 0) + { + getParserContainer()->encodeEmbedded(headerName, str); + } + else + { + bool first = true; + for (HeaderFieldValueList::const_iterator j = begin(); + j != end(); j++) + { + if (first) + { + first = false; + } + else + { + str << Symbols::AMPERSAND; + } + + str << headerName << Symbols::EQUALS; + Data buf; + { + DataStream s(buf); + j->encode(s); + } + str << Embedded::encode(buf); + } + } + return str; +} + +void +HeaderFieldValueList::clear() +{ + freeParserContainer(); + mHeaders.clear(); +} + +bool +HeaderFieldValueList::parsedEmpty() const +{ + if (mParserContainer) + { + return mParserContainer->empty(); + } + else + { + return mHeaders.empty(); + } +} + +void +HeaderFieldValueList::freeParserContainer() +{ + if(mParserContainer) + { + mParserContainer->~ParserContainerBase(); + // The allocator will check whether this belongs to it, and if not, fall + // back to global operator delete. + if(mPool) + { + mPool->deallocate(mParserContainer); + } + else + { + ::operator delete(mParserContainer); + } + mParserContainer=0; + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/HeaderFieldValueList.hxx b/src/libs/resiprocate/resip/stack/HeaderFieldValueList.hxx new file mode 100644 index 00000000..25ba1d0e --- /dev/null +++ b/src/libs/resiprocate/resip/stack/HeaderFieldValueList.hxx @@ -0,0 +1,156 @@ +#if !defined(RESIP_HEADERFIELDVALUELIST_HXX) +#define RESIP_HEADERFIELDVALUELIST_HXX + +#include <iosfwd> +#include <vector> + +#include "rutil/StlPoolAllocator.hxx" +#include "rutil/PoolBase.hxx" + +namespace resip +{ + +class Data; +class ParserContainerBase; +class HeaderFieldValue; + +/** + @internal +*/ +class HeaderFieldValueList +{ + public: + static const HeaderFieldValueList Empty; + + HeaderFieldValueList() + : mHeaders(), + mPool(0), + mParserContainer(0) + {} + + HeaderFieldValueList(PoolBase& pool) + : mHeaders(StlPoolAllocator<HeaderFieldValue, PoolBase>(&pool)), + mPool(&pool), + mParserContainer(0) + {} + + ~HeaderFieldValueList(); + HeaderFieldValueList(const HeaderFieldValueList& rhs); + HeaderFieldValueList(const HeaderFieldValueList& rhs, PoolBase& pool); + HeaderFieldValueList& operator=(const HeaderFieldValueList& rhs); + + inline void setParserContainer(ParserContainerBase* parser) {mParserContainer = parser;} + inline ParserContainerBase* getParserContainer() const {return mParserContainer;} + + EncodeStream& encode(int headerEnum, EncodeStream& str) const; + EncodeStream& encode(const Data& headerName, EncodeStream& str) const; + EncodeStream& encodeEmbedded(const Data& headerName, EncodeStream& str) const; + + bool empty() const {return mHeaders.empty();} + size_t size() const {return mHeaders.size();} + void clear(); + //void push_front(HeaderFieldValue* header) {mHeaders.push_front(header);} + + /** + READ THIS CAREFULLY BEFORE USING THIS FUNCTION + @param own Specifies whether the created HeaderFieldValue will take + ownership of the buffer passed. This will never make a copy + of the buffer; if own==false, the HeaderFieldValue will retain the + same reference that it would if own==true. The only difference is + that if own==false, the buffer will not be deleted when the + HeaderFieldValue goes away/releases its reference, while if + own==true the buffer will be deleted. This means that no matter what + you pass for this param, you must ensure that the buffer is not + deleted during the lifetime of this HeaderFieldValueList. + */ + void push_back(const char* buffer, size_t length, bool own) + { + mHeaders.push_back(HeaderFieldValue::Empty); + mHeaders.back().init(buffer,length,own); + } + + //void pop_front() {mHeaders.pop_front();} + void pop_back() {mHeaders.pop_back();}; + HeaderFieldValue* front() {return &mHeaders.front();} + HeaderFieldValue* back() {return &mHeaders.back();} + const HeaderFieldValue* front() const {return &mHeaders.front();} + const HeaderFieldValue* back() const {return &mHeaders.back();} + + inline void reserve(size_t size) + { + mHeaders.reserve(size); + } + + bool parsedEmpty() const; + private: + typedef std::vector<HeaderFieldValue, StlPoolAllocator<HeaderFieldValue, PoolBase > > ListImpl; + public: + typedef ListImpl::iterator iterator; + typedef ListImpl::const_iterator const_iterator; + + iterator begin() {return mHeaders.begin();} + iterator end() {return mHeaders.end();} + const_iterator begin() const {return mHeaders.begin();} + const_iterator end() const {return mHeaders.end();} + + private: + ListImpl mHeaders; + PoolBase* mPool; + ParserContainerBase* mParserContainer; + + void freeParserContainer(); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/HeaderHash.cxx b/src/libs/resiprocate/resip/stack/HeaderHash.cxx new file mode 100644 index 00000000..8c2dfbbe --- /dev/null +++ b/src/libs/resiprocate/resip/stack/HeaderHash.cxx @@ -0,0 +1,499 @@ +/* C++ code produced by gperf version 3.0.4 */ +/* Command-line: gperf -C -D -E -L C++ -t -k '*' --compare-strncmp --ignore-case -Z HeaderHash HeaderHash.gperf */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>." +#endif + +#line 1 "HeaderHash.gperf" + +#include <string.h> +#include <ctype.h> +#include "resip/stack/HeaderTypes.hxx" + +namespace resip +{ +using namespace std; +#line 10 "HeaderHash.gperf" +struct headers { const char *name; Headers::Type type; }; +/* maximum key range = 430, duplicates = 0 */ + +#ifndef GPERF_DOWNCASE +#define GPERF_DOWNCASE 1 +static unsigned char gperf_downcase[256] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255 + }; +#endif + +#ifndef GPERF_CASE_STRNCMP +#define GPERF_CASE_STRNCMP 1 +static int +gperf_case_strncmp (register const char *s1, register const char *s2, register unsigned int n) +{ + for (; n > 0;) + { + unsigned char c1 = gperf_downcase[(unsigned char)*s1++]; + unsigned char c2 = gperf_downcase[(unsigned char)*s2++]; + if (c1 != 0 && c1 == c2) + { + n--; + continue; + } + return (int)c1 - (int)c2; + } + return 0; +} +#endif + +class HeaderHash +{ +private: + static inline unsigned int hash (const char *str, unsigned int len); +public: + static const struct headers *in_word_set (const char *str, unsigned int len); +}; + +inline unsigned int +HeaderHash::hash (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 0, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 0, 55, 15, 0, 30, + 35, 10, 5, 25, 5, 70, 40, 75, 0, 5, + 0, 25, 10, 50, 0, 10, 45, 0, 60, 20, + 50, 431, 431, 431, 431, 431, 431, 0, 55, 15, + 0, 30, 35, 10, 5, 25, 5, 70, 40, 75, + 0, 5, 0, 25, 10, 50, 0, 10, 45, 0, + 60, 20, 50, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, 431, 431 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[24]]; + /*FALLTHROUGH*/ + case 24: + hval += asso_values[(unsigned char)str[23]]; + /*FALLTHROUGH*/ + case 23: + hval += asso_values[(unsigned char)str[22]]; + /*FALLTHROUGH*/ + case 22: + hval += asso_values[(unsigned char)str[21]]; + /*FALLTHROUGH*/ + case 21: + hval += asso_values[(unsigned char)str[20]]; + /*FALLTHROUGH*/ + case 20: + hval += asso_values[(unsigned char)str[19]]; + /*FALLTHROUGH*/ + case 19: + hval += asso_values[(unsigned char)str[18]]; + /*FALLTHROUGH*/ + case 18: + hval += asso_values[(unsigned char)str[17]]; + /*FALLTHROUGH*/ + case 17: + hval += asso_values[(unsigned char)str[16]]; + /*FALLTHROUGH*/ + case 16: + hval += asso_values[(unsigned char)str[15]]; + /*FALLTHROUGH*/ + case 15: + hval += asso_values[(unsigned char)str[14]]; + /*FALLTHROUGH*/ + case 14: + hval += asso_values[(unsigned char)str[13]]; + /*FALLTHROUGH*/ + case 13: + hval += asso_values[(unsigned char)str[12]]; + /*FALLTHROUGH*/ + case 12: + hval += asso_values[(unsigned char)str[11]]; + /*FALLTHROUGH*/ + case 11: + hval += asso_values[(unsigned char)str[10]]; + /*FALLTHROUGH*/ + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + hval += asso_values[(unsigned char)str[1]]; + /*FALLTHROUGH*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval; +} + +const struct headers * +HeaderHash::in_word_set (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 101, + MIN_WORD_LENGTH = 1, + MAX_WORD_LENGTH = 25, + MIN_HASH_VALUE = 1, + MAX_HASH_VALUE = 430 + }; + + static const struct headers wordlist[] = + { +#line 20 "HeaderHash.gperf" + {"t", Headers::To}, +#line 26 "HeaderHash.gperf" + {"o", Headers::Event}, +#line 36 "HeaderHash.gperf" + {"to", Headers::To}, +#line 92 "HeaderHash.gperf" + {"path", Headers::Path}, +#line 22 "HeaderHash.gperf" + {"r", Headers::ReferTo}, +#line 16 "HeaderHash.gperf" + {"c", Headers::ContentType}, +#line 25 "HeaderHash.gperf" + {"y", Headers::Identity}, +#line 12 "HeaderHash.gperf" + {"i", Headers::CallID}, +#line 14 "HeaderHash.gperf" + {"e", Headers::ContentEncoding}, +#line 52 "HeaderHash.gperf" + {"date", Headers::Date}, +#line 17 "HeaderHash.gperf" + {"f", Headers::From}, +#line 86 "HeaderHash.gperf" + {"join", Headers::Join}, +#line 15 "HeaderHash.gperf" + {"l", Headers::ContentLength}, +#line 29 "HeaderHash.gperf" + {"contact", Headers::Contact}, +#line 21 "HeaderHash.gperf" + {"v", Headers::Via}, +#line 18 "HeaderHash.gperf" + {"s", Headers::Subject}, +#line 76 "HeaderHash.gperf" + {"warning", Headers::Warning}, +#line 23 "HeaderHash.gperf" + {"b", Headers::ReferredBy}, +#line 34 "HeaderHash.gperf" + {"route", Headers::Route}, +#line 24 "HeaderHash.gperf" + {"x", Headers::SessionExpires}, +#line 83 "HeaderHash.gperf" + {"hide", Headers::UNKNOWN}, +#line 38 "HeaderHash.gperf" + {"accept", Headers::Accept}, +#line 19 "HeaderHash.gperf" + {"k", Headers::Supported}, +#line 37 "HeaderHash.gperf" + {"via", Headers::Via}, +#line 13 "HeaderHash.gperf" + {"m", Headers::Contact}, +#line 47 "HeaderHash.gperf" + {"content-id", Headers::ContentId}, +#line 43 "HeaderHash.gperf" + {"allow", Headers::Allow}, +#line 95 "HeaderHash.gperf" + {"rack", Headers::RAck}, +#line 96 "HeaderHash.gperf" + {"reason", Headers::Reason}, +#line 58 "HeaderHash.gperf" + {"priority", Headers::Priority}, +#line 84 "HeaderHash.gperf" + {"identity", Headers::Identity}, +#line 39 "HeaderHash.gperf" + {"accept-contact", Headers::AcceptContact}, +#line 82 "HeaderHash.gperf" + {"event", Headers::Event}, +#line 50 "HeaderHash.gperf" + {"content-type", Headers::ContentType}, +#line 63 "HeaderHash.gperf" + {"reply-to", Headers::ReplyTo}, +#line 70 "HeaderHash.gperf" + {"supported", Headers::Supported}, +#line 81 "HeaderHash.gperf" + {"encryption", Headers::UNKNOWN}, +#line 103 "HeaderHash.gperf" + {"rseq", Headers::RSeq}, +#line 94 "HeaderHash.gperf" + {"privacy", Headers::Privacy}, +#line 68 "HeaderHash.gperf" + {"sip-etag", Headers::SIPETag}, +#line 27 "HeaderHash.gperf" + {"cseq", Headers::CSeq}, +#line 74 "HeaderHash.gperf" + {"unsupported", Headers::Unsupported}, +#line 28 "HeaderHash.gperf" + {"call-id", Headers::CallID}, +#line 97 "HeaderHash.gperf" + {"refer-to",Headers::ReferTo}, +#line 32 "HeaderHash.gperf" + {"from", Headers::From}, +#line 77 "HeaderHash.gperf" + {"www-authenticate",Headers::WWWAuthenticate}, +#line 62 "HeaderHash.gperf" + {"record-route", Headers::RecordRoute}, +#line 100 "HeaderHash.gperf" + {"reject-contact", Headers::RejectContact}, +#line 53 "HeaderHash.gperf" + {"error-info", Headers::ErrorInfo}, +#line 54 "HeaderHash.gperf" + {"in-reply-to", Headers::InReplyTo}, +#line 57 "HeaderHash.gperf" + {"organization", Headers::Organization}, +#line 93 "HeaderHash.gperf" + {"target-dialog", Headers::TargetDialog}, +#line 64 "HeaderHash.gperf" + {"require", Headers::Require}, +#line 79 "HeaderHash.gperf" + {"authorization", Headers::Authorization}, +#line 30 "HeaderHash.gperf" + {"content-length", Headers::ContentLength}, +#line 75 "HeaderHash.gperf" + {"user-agent", Headers::UserAgent}, +#line 48 "HeaderHash.gperf" + {"content-encoding", Headers::ContentEncoding}, +#line 42 "HeaderHash.gperf" + {"alert-info",Headers::AlertInfo}, +#line 65 "HeaderHash.gperf" + {"retry-after", Headers::RetryAfter}, +#line 40 "HeaderHash.gperf" + {"accept-encoding", Headers::AcceptEncoding}, +#line 49 "HeaderHash.gperf" + {"content-language", Headers::ContentLanguage}, +#line 45 "HeaderHash.gperf" + {"call-info", Headers::CallInfo}, +#line 35 "HeaderHash.gperf" + {"subject", Headers::Subject}, +#line 41 "HeaderHash.gperf" + {"accept-language", Headers::AcceptLanguage}, +#line 85 "HeaderHash.gperf" + {"identity-info", Headers::IdentityInfo}, +#line 67 "HeaderHash.gperf" + {"server", Headers::Server}, +#line 99 "HeaderHash.gperf" + {"replaces",Headers::Replaces}, +#line 109 "HeaderHash.gperf" + {"min-se", Headers::MinSE}, +#line 112 "HeaderHash.gperf" + {"history-info", Headers::HistoryInfo}, +#line 89 "HeaderHash.gperf" + {"p-called-party-id", Headers::PCalledPartyId}, +#line 44 "HeaderHash.gperf" + {"authentication-info", Headers::AuthenticationInfo}, +#line 72 "HeaderHash.gperf" + {"answer-mode", Headers::AnswerMode}, +#line 31 "HeaderHash.gperf" + {"expires", Headers::Expires}, +#line 111 "HeaderHash.gperf" + {"remote-party-id", Headers::RemotePartyId}, +#line 59 "HeaderHash.gperf" + {"proxy-authenticate", Headers::ProxyAuthenticate}, +#line 66 "HeaderHash.gperf" + {"flow-timer", Headers::FlowTimer}, +#line 88 "HeaderHash.gperf" + {"p-associated-uri", Headers::PAssociatedUri}, +#line 110 "HeaderHash.gperf" + {"refer-sub", Headers::ReferSub}, +#line 98 "HeaderHash.gperf" + {"referred-by",Headers::ReferredBy}, +#line 69 "HeaderHash.gperf" + {"sip-if-match", Headers::SIPIfMatch}, +#line 61 "HeaderHash.gperf" + {"proxy-require", Headers::ProxyRequire}, +#line 60 "HeaderHash.gperf" + {"proxy-authorization", Headers::ProxyAuthorization}, +#line 80 "HeaderHash.gperf" + {"allow-events", Headers::AllowEvents}, +#line 46 "HeaderHash.gperf" + {"content-disposition", Headers::ContentDisposition}, +#line 33 "HeaderHash.gperf" + {"max-forwards", Headers::MaxForwards}, +#line 71 "HeaderHash.gperf" + {"timestamp", Headers::Timestamp}, +#line 107 "HeaderHash.gperf" + {"service-route", Headers::ServiceRoute}, +#line 91 "HeaderHash.gperf" + {"p-preferred-identity", Headers::PPreferredIdentity}, +#line 104 "HeaderHash.gperf" + {"security-client", Headers::SecurityClient}, +#line 90 "HeaderHash.gperf" + {"p-media-authorization", Headers::PMediaAuthorization}, +#line 87 "HeaderHash.gperf" + {"p-asserted-identity", Headers::PAssertedIdentity}, +#line 51 "HeaderHash.gperf" + {"content-transfer-encoding", Headers::ContentTransferEncoding}, +#line 73 "HeaderHash.gperf" + {"priv-answer-mode", Headers::PrivAnswerMode}, +#line 102 "HeaderHash.gperf" + {"response-key", Headers::UNKNOWN}, +#line 55 "HeaderHash.gperf" + {"min-expires", Headers::MinExpires}, +#line 106 "HeaderHash.gperf" + {"security-verify", Headers::SecurityVerify}, +#line 78 "HeaderHash.gperf" + {"subscription-state",Headers::SubscriptionState}, +#line 105 "HeaderHash.gperf" + {"security-server", Headers::SecurityServer}, +#line 101 "HeaderHash.gperf" + {"request-disposition", Headers::RequestDisposition}, +#line 56 "HeaderHash.gperf" + {"mime-version", Headers::MIMEVersion}, +#line 108 "HeaderHash.gperf" + {"session-expires", Headers::SessionExpires} + }; + + static const signed char lookup[] = + { + -1, 0, -1, -1, -1, -1, 1, 2, -1, 3, + -1, 4, -1, -1, -1, -1, 5, -1, -1, -1, + -1, 6, -1, -1, -1, -1, 7, -1, -1, -1, + -1, 8, -1, -1, 9, -1, 10, -1, -1, 11, + -1, 12, 13, -1, -1, -1, 14, -1, -1, -1, + -1, 15, 16, -1, -1, -1, 17, -1, -1, -1, + 18, 19, -1, -1, 20, -1, 21, -1, -1, -1, + -1, 22, -1, 23, -1, -1, 24, -1, -1, -1, + -1, -1, -1, -1, -1, 25, -1, -1, -1, -1, + 26, -1, -1, -1, -1, -1, -1, -1, -1, 27, + -1, 28, -1, 29, -1, -1, -1, -1, 30, 31, + 32, -1, 33, 34, 35, 36, -1, -1, -1, 37, + -1, -1, 38, 39, 40, -1, 41, 42, 43, 44, + -1, 45, -1, -1, -1, -1, -1, 46, -1, 47, + 48, 49, 50, 51, -1, -1, -1, 52, 53, 54, + 55, 56, -1, -1, -1, 57, 58, -1, -1, -1, + 59, -1, -1, -1, -1, -1, 60, -1, -1, 61, + -1, -1, 62, -1, -1, 63, -1, -1, 64, -1, + -1, 65, -1, 66, -1, -1, 67, -1, -1, -1, + -1, -1, 68, -1, -1, -1, -1, 69, -1, 70, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 71, 72, -1, -1, -1, -1, -1, -1, -1, + 73, -1, -1, -1, -1, -1, -1, -1, 74, -1, + 75, -1, -1, -1, -1, -1, 76, -1, -1, 77, + -1, 78, 79, -1, -1, -1, -1, -1, 80, 81, + -1, -1, 82, -1, 83, -1, -1, 84, -1, -1, + -1, -1, -1, -1, 85, -1, -1, -1, -1, -1, + -1, -1, -1, 86, -1, 87, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 88, 89, -1, -1, 90, + -1, -1, -1, -1, -1, 91, 92, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 93, -1, -1, + -1, -1, -1, -1, -1, -1, 94, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 95, -1, -1, 96, -1, -1, -1, -1, -1, -1, + 97, -1, -1, -1, -1, -1, -1, -1, -1, 98, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 99, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 100 + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int index = lookup[key]; + + if (index >= 0) + { + register const char *s = wordlist[index].name; + + if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strncmp (str, s, len) && s[len] == '\0') + return &wordlist[index]; + } + } + } + return 0; +} +#line 113 "HeaderHash.gperf" + +} diff --git a/src/libs/resiprocate/resip/stack/HeaderHash.gperf b/src/libs/resiprocate/resip/stack/HeaderHash.gperf new file mode 100644 index 00000000..b8c72eb5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/HeaderHash.gperf @@ -0,0 +1,114 @@ +%{ +#include <string.h> +#include <ctype.h> +#include "resip/stack/HeaderTypes.hxx" + +namespace resip +{ +using namespace std; +%} +struct headers { const char *name; Headers::Type type; }; +%% +i, Headers::CallID +m, Headers::Contact +e, Headers::ContentEncoding +l, Headers::ContentLength +c, Headers::ContentType +f, Headers::From +s, Headers::Subject +k, Headers::Supported +t, Headers::To +v, Headers::Via +r, Headers::ReferTo +b, Headers::ReferredBy +x, Headers::SessionExpires +y, Headers::Identity +o, Headers::Event +cseq, Headers::CSeq +call-id, Headers::CallID +contact, Headers::Contact +content-length, Headers::ContentLength +expires, Headers::Expires +from, Headers::From +max-forwards, Headers::MaxForwards +route, Headers::Route +subject, Headers::Subject +to, Headers::To +via, Headers::Via +accept, Headers::Accept +accept-contact, Headers::AcceptContact +accept-encoding, Headers::AcceptEncoding +accept-language, Headers::AcceptLanguage +alert-info,Headers::AlertInfo +allow, Headers::Allow +authentication-info, Headers::AuthenticationInfo +call-info, Headers::CallInfo +content-disposition, Headers::ContentDisposition +content-id, Headers::ContentId +content-encoding, Headers::ContentEncoding +content-language, Headers::ContentLanguage +content-type, Headers::ContentType +content-transfer-encoding, Headers::ContentTransferEncoding +date, Headers::Date +error-info, Headers::ErrorInfo +in-reply-to, Headers::InReplyTo +min-expires, Headers::MinExpires +mime-version, Headers::MIMEVersion +organization, Headers::Organization +priority, Headers::Priority +proxy-authenticate, Headers::ProxyAuthenticate +proxy-authorization, Headers::ProxyAuthorization +proxy-require, Headers::ProxyRequire +record-route, Headers::RecordRoute +reply-to, Headers::ReplyTo +require, Headers::Require +retry-after, Headers::RetryAfter +flow-timer, Headers::FlowTimer +server, Headers::Server +sip-etag, Headers::SIPETag +sip-if-match, Headers::SIPIfMatch +supported, Headers::Supported +timestamp, Headers::Timestamp +answer-mode, Headers::AnswerMode +priv-answer-mode, Headers::PrivAnswerMode +unsupported, Headers::Unsupported +user-agent, Headers::UserAgent +warning, Headers::Warning +www-authenticate,Headers::WWWAuthenticate +subscription-state,Headers::SubscriptionState +authorization, Headers::Authorization +allow-events, Headers::AllowEvents +encryption, Headers::UNKNOWN +event, Headers::Event +hide, Headers::UNKNOWN +identity, Headers::Identity +identity-info, Headers::IdentityInfo +join, Headers::Join +p-asserted-identity, Headers::PAssertedIdentity +p-associated-uri, Headers::PAssociatedUri +p-called-party-id, Headers::PCalledPartyId +p-media-authorization, Headers::PMediaAuthorization +p-preferred-identity, Headers::PPreferredIdentity +path, Headers::Path +target-dialog, Headers::TargetDialog +privacy, Headers::Privacy +rack, Headers::RAck +reason, Headers::Reason +refer-to,Headers::ReferTo +referred-by,Headers::ReferredBy +replaces,Headers::Replaces +reject-contact, Headers::RejectContact +request-disposition, Headers::RequestDisposition +response-key, Headers::UNKNOWN +rseq, Headers::RSeq +security-client, Headers::SecurityClient +security-server, Headers::SecurityServer +security-verify, Headers::SecurityVerify +service-route, Headers::ServiceRoute +session-expires, Headers::SessionExpires +min-se, Headers::MinSE +refer-sub, Headers::ReferSub +remote-party-id, Headers::RemotePartyId +history-info, Headers::HistoryInfo +%% +} diff --git a/src/libs/resiprocate/resip/stack/HeaderHash.hxx b/src/libs/resiprocate/resip/stack/HeaderHash.hxx new file mode 100644 index 00000000..90c10d56 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/HeaderHash.hxx @@ -0,0 +1,69 @@ +#if !defined(RESIP_HEADERHASH_HXX) +#define RESIP_HEADERHASH_HXX +namespace resip +{ + +struct headers { char *name; Headers::Type type; }; +/* maximum key range = 494, duplicates = 0 */ + +class HeaderHash +{ +private: + static inline unsigned int hash (const char *str, unsigned int len); +public: + static const struct headers *in_word_set (const char *str, unsigned int len); +}; +// NOTE the cxx file for this class is AUTO GENERATED. DO NOT EDIT IT. +// This file should match it. BUT THIS FILE IS MANUALLY GENERATED. +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/HeaderTypes.cxx b/src/libs/resiprocate/resip/stack/HeaderTypes.cxx new file mode 100644 index 00000000..1e561d42 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/HeaderTypes.cxx @@ -0,0 +1,61 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "rutil/compat.hxx" +#include "rutil/Data.hxx" +#include "resip/stack/HeaderTypes.hxx" +#include "resip/stack/Headers.hxx" +#include "resip/stack/Symbols.hxx" + +using namespace resip; + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/HeaderTypes.hxx b/src/libs/resiprocate/resip/stack/HeaderTypes.hxx new file mode 100644 index 00000000..dcda54eb --- /dev/null +++ b/src/libs/resiprocate/resip/stack/HeaderTypes.hxx @@ -0,0 +1,208 @@ +#if !defined(RESIP_HEADERTYPES_HXX) +#define RESIP_HEADERTYPES_HXX + +#include "rutil/Data.hxx" + +//**************************************************************************** +// +// !dlb! until automated, must ensure that this set is consistent with +// +// ************ PLEASE RUN testParserCategories AFTER CHANGING *************** +// +// HeaderTypes.hxx +// Headers.hxx +// HeaderHash.gperf +// Headers.cxx +// SipMessage.hxx +// SipMessage.cxx +// +//**************************************************************************** + +// eventually use these macros to automate Headers.hxx, Headers.cxx+gperf +#define UNUSED_defineHeader(_enum, _name, _type, _rfc) SAVE##_enum, _enum = UNKNOWN, RESET##enum = SAVE##_enum-1 +#define UNUSED_defineMultiHeader(_enum, _name, _type, _rfc) SAVE##_enum, _enum = UNKNOWN, RESET##enum = SAVE##_enum-1 +#define defineHeader(_enum, _name, _type, _rfc) _enum +#define defineMultiHeader(_enum, _name, _type, _rfc) _enum + +namespace resip +{ + +/** + Maps from header name to derived ParserCategory. Determines whether the + header is single or multiple valued. + + The Type enum controls the order of output of the headers in the encoded + SipMessage. Put headers that you want to appear early in the message early + in this list. +*/ +class Headers +{ + public: + enum Type + { + UNKNOWN = -1, + defineMultiHeader(Via, "Via", Via, "RFC 3261"), // rjs says must be first + defineHeader(MaxForwards, "Max-Forwards", UInt32Category, "RFC 3261"), + defineMultiHeader(Route, "Route", NameAddr, "RFC 3261"), + defineMultiHeader(RecordRoute, "Record-Route", NameAddr, "RFC 3261"), + defineMultiHeader(Path, "Path", NameAddr, "RFC 3327"), + defineMultiHeader(ServiceRoute, "Service-Route", NameAddr, "RFC 3608"), + defineMultiHeader(ProxyRequire, "Proxy-Require", Token, "RFC 3261"), + defineMultiHeader(ProxyAuthenticate, "Proxy-Authenticate", Auth, "RFC 3261"), + defineHeader(Identity, "Identity", StringCategory, "RFC 4474"), + defineHeader(IdentityInfo, "Identity-Info", GenericUri, "RFC 4474"), + defineMultiHeader(Require, "Require", Token, "RFC 3261"), + defineMultiHeader(Contact, "Contact", NameAddr, "RFC 3261"), + + defineHeader(To, "To", NameAddr, "RFC 3261"), + defineHeader(From, "From", NameAddr, "RFC 3261"), + defineHeader(CallID, "Call-ID", CallId, "RFC 3261"), + defineHeader(CSeq, "CSeq", CSeqCategory, "RFC 3261"), + defineHeader(Subject, "Subject", StringCategory, "RFC 3261"), + defineHeader(Expires, "Expires", ExpiresCategory, "RFC 3261"), + defineHeader(SessionExpires, "Session-Expires", ExpiresCategory, "RFC 4028"), + defineHeader(MinSE, "Min-SE", ExpiresCategory, "RFC 4028"), + defineMultiHeader(Accept, "Accept", Mime, "RFC 3261"), + defineMultiHeader(AcceptEncoding, "Accept-Encoding", Token, "RFC 3261"), + defineMultiHeader(AcceptLanguage, "Accept-Language", Token, "RFC 3261"), + defineMultiHeader(AlertInfo, "Alert-Info", GenericUri, "RFC 3261"), + defineMultiHeader(Allow, "Allow", Token, "RFC 3261"), + defineHeader(AuthenticationInfo, "Authentication-Info", Auth, "RFC 3261"), + defineMultiHeader(CallInfo, "Call-Info", GenericUri, "RFC 3261"), + defineHeader(ContentDisposition, "Content-Disposition", Token, "RFC ?"), + defineHeader(ContentEncoding, "Content-Encoding", Token, "RFC ?"), + defineHeader(ContentId, "Content-ID", Token, "RFC 2045"), + defineMultiHeader(ContentLanguage, "Content-Language", Token, "RFC ?"), +// i really think that Content-Transfer-Encoding should be a Token !rwm + defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC ?"), // !dlb! defineMultiHeader + defineHeader(ContentType, "Content-Type", Mime, "RFC 3261"), + defineHeader(Date, "Date", DateCategory, "RFC 3261"), + defineMultiHeader(ErrorInfo, "Error-Info", GenericUri, "RFC 3261"), + defineHeader(InReplyTo, "In-Reply-To", CallId, "RFC 3261"), + defineHeader(MinExpires, "Min-Expires", UInt32Category, "RFC 3261"), + defineHeader(MIMEVersion, "MIME-Version", Token, "RFC 3261"), + defineHeader(Organization, "Organization", StringCategory, "RFC 3261"), + defineHeader(Priority, "Priority", Token, "RFC 3261"), + defineMultiHeader(ProxyAuthorization, "Proxy-Authorization", Auth, "RFC 3261"), + defineHeader(ReplyTo, "Reply-To", NameAddr, "RFC 3261"), + defineHeader(RetryAfter, "Retry-After", UInt32Category, "RFC 3261"), + defineHeader(FlowTimer, "Flow-Timer", UInt32Category, "RFC 5626"), + defineHeader(Server, "Server", StringCategory, "RFC 3261"), + defineHeader(SIPETag, "SIP-ETag", Token, "RFC 3903"), + defineHeader(SIPIfMatch, "SIP-If-Match", Token, "RFC 3903"), + defineMultiHeader(Supported, "Supported", Token, "RFC 3261"), + defineHeader(Timestamp, "Timestamp", StringCategory, "RFC 3261"), + defineMultiHeader(Unsupported, "Unsupported", Token, "RFC 3261"), + defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261"), + defineMultiHeader(Warning, "Warning", WarningCategory, "RFC 3261"), + defineMultiHeader(WWWAuthenticate, "WWW-Authenticate", Auth, "RFC 3261"), + defineHeader(SubscriptionState, "Subscription-State", Token, "RFC 3265"), + defineHeader(ReferTo, "Refer-To", NameAddr, "RFC 3515"), + defineHeader(ReferredBy, "Referred-By", NameAddr, "RFC 3892"), + defineMultiHeader(Authorization, "Authorization", Auth, "RFC 3261"), + defineHeader(Replaces, "Replaces", CallId, "RFC 3891"), + defineHeader(Event, "Event", Token, "RFC 3265"), + defineMultiHeader(AllowEvents, "Allow-Events", Token, "RFC 3265"), + defineMultiHeader(SecurityClient, "Security-Client", Token, "RFC 3329"), + defineMultiHeader(SecurityServer, "Security-Server", Token, "RFC 3329"), + defineMultiHeader(SecurityVerify, "Security-Verify", Token, "RFC 3329"), + defineHeader(RSeq, "RSeq", UInt32Category, "RFC 3262"), + defineHeader(RAck, "RAck", RAckCategory, "RFC 3262"), + + defineMultiHeader(Reason, "Reason", Token, "RFC 3326"), + defineMultiHeader(Privacy, "Privacy", PrivacyCategory, "RFC 3323"), + defineMultiHeader(RequestDisposition, "Request-Disposition", Token, "RFC 3841"), + defineMultiHeader(PMediaAuthorization, "P-Media-Authorization", Token, "RFC 3313"), + defineHeader(Join, "Join", CallId, "RFC 3911"), + defineHeader(TargetDialog, "Target-Dialog", CallId, "RFC 4538"), + defineMultiHeader(PAssertedIdentity, "P-Asserted-Identity", NameAddr, "RFC 3325"), + defineMultiHeader(PPreferredIdentity, "P-Preferred-Identity", NameAddr, "RFC 3325"), + defineMultiHeader(AcceptContact, "Accept-Contact", NameAddr, "RFC 3841"), + defineMultiHeader(RejectContact, "Reject-Contact", NameAddr, "RFC 3841"), + defineHeader(PCalledPartyId, "P-Called-Party-ID", NameAddr, "RFC 3455"), + defineMultiHeader(PAssociatedUri, "P-Associated-URI", NameAddr, "RFC 3455"), + + defineHeader(ContentLength, "Content-Length", UInt32Category, "RFC 3261"), + defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488"), + defineHeader(AnswerMode, "Answer-Mode", Token, "RFC 5373"), + defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "RFC 5373"), + defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04"), // ?bwc? Not in 3323, should we keep? + defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244"), + + defineMultiHeader(RESIP_DO_NOT_USE, "ShouldNotSeeThis", StringCategory, "N/A"), + MAX_HEADERS, + NONE + }; + + // get enum from header name + static Type getType(const char* name, int len); + static bool isCommaTokenizing(Type type); + static bool isCommaEncoding(Type type); + static const Data& getHeaderName(int); + static bool isMulti(Type type); + + // treat as private + static bool CommaTokenizing[MAX_HEADERS+1]; + static bool CommaEncoding[MAX_HEADERS+1]; + static Data HeaderNames[MAX_HEADERS+1]; + static bool Multi[MAX_HEADERS+1]; +}; + +} + +#undef UNUSED_defineHeader +#undef UNUSED_defineMultiHeader +#undef defineHeader +#undef defineMultiHeader + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Headers.cxx b/src/libs/resiprocate/resip/stack/Headers.cxx new file mode 100644 index 00000000..9568f935 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Headers.cxx @@ -0,0 +1,378 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "rutil/Data.hxx" +#include "resip/stack/Headers.hxx" +#include "resip/stack/Symbols.hxx" +#include "resip/stack/SipMessage.hxx" + +// GPERF generated external routines +#include "resip/stack/HeaderHash.hxx" + +#include <iostream> +using namespace std; + +//int strcasecmp(const char*, const char*); +//int strncasecmp(const char*, const char*, int len); + +using namespace resip; + +Data Headers::HeaderNames[MAX_HEADERS+1]; +bool Headers::CommaTokenizing[] = {false}; +bool Headers::CommaEncoding[] = {false}; +bool Headers::Multi[]={false}; +HeaderBase* HeaderBase::theHeaderInstances[] = {0}; + +bool +Headers::isCommaTokenizing(Type type) +{ + return CommaTokenizing[type+1]; +} + +bool +Headers::isCommaEncoding(Type type) +{ + return CommaEncoding[type+1]; +} + +const Data& +Headers::getHeaderName(int type) +{ + return HeaderNames[type+1]; +} + +bool +Headers::isMulti(Type type) +{ + return Multi[type+1]; +} + +#define defineHeader(_enum, _name, _type, _reference) \ +Headers::Type \ +H_##_enum::getTypeNum() const {return Headers::_enum;} \ + \ +void H_##_enum::merge(SipMessage& target, const SipMessage& embedded) \ +{ \ + if (embedded.exists(*this)) \ + { \ + target.header(*this) = embedded.header(*this); \ + } \ +} \ + \ +H_##_enum::H_##_enum() \ +{ \ + Headers::CommaTokenizing[Headers::_enum+1] = bool(Type::commaHandling & ParserCategory::CommasAllowedOutputMulti); \ + Headers::CommaEncoding[Headers::_enum+1] = bool(Type::commaHandling & 2); \ + Headers::HeaderNames[Headers::_enum+1] = _name; \ + Headers::Multi[Headers::_enum+1] = false; \ + HeaderBase::theHeaderInstances[Headers::_enum+1] = this; \ +} \ + \ +_type& \ +H_##_enum::knownReturn(ParserContainerBase* container) \ +{ \ + return dynamic_cast<ParserContainer<_type>*>(container)->front(); \ +} \ + \ +ParserContainerBase* \ +H_##_enum::makeContainer(HeaderFieldValueList* hfvs) const \ +{ \ + return new ParserContainer<_type>(hfvs,Headers::_enum); \ +} \ + \ +H_##_enum resip::h_##_enum + +#define defineMultiHeader(_enum, _name, _type, _reference) \ + Headers::Type \ +H_##_enum##s::getTypeNum() const {return Headers::_enum;} \ + \ +void H_##_enum##s::merge(SipMessage& target, const SipMessage& embedded) \ +{ \ + if (embedded.exists(*this)) \ + { \ + target.header(*this).append(embedded.header(*this)); \ + } \ +} \ + \ +H_##_enum##s::H_##_enum##s() \ +{ \ + Headers::CommaTokenizing[Headers::_enum+1] = bool(Type::value_type::commaHandling & ParserCategory::CommasAllowedOutputMulti); \ + Headers::CommaEncoding[Headers::_enum+1] = bool(Type::value_type::commaHandling & 2); \ + Headers::HeaderNames[Headers::_enum+1] = _name; \ + Headers::Multi[Headers::_enum+1] = true; \ + HeaderBase::theHeaderInstances[Headers::_enum+1] = this; \ +} \ + \ +ParserContainer<_type>& \ +H_##_enum##s::knownReturn(ParserContainerBase* container) \ +{ \ + return *dynamic_cast<ParserContainer<_type>*>(container); \ +} \ + \ +ParserContainerBase* \ +H_##_enum##s::makeContainer(HeaderFieldValueList* hfvs) const \ +{ \ + return new ParserContainer<_type>(hfvs,Headers::_enum); \ +} \ + \ +H_##_enum##s resip::h_##_enum##s + +//==================== +// Token +//==================== + +defineHeader(ContentDisposition, "Content-Disposition", Token, "RFC 3261"); +defineHeader(ContentEncoding, "Content-Encoding", Token, "RFC 3261"); +defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC ?"); // !dlb! defineMultiHeader +defineHeader(MIMEVersion, "MIME-Version", Token, "RFC 3261"); +defineHeader(Priority, "Priority", Token, "RFC 3261"); +defineHeader(Event, "Event", Token, "RFC 3265"); +defineHeader(SubscriptionState, "Subscription-State", Token, "RFC 3265"); + +defineHeader(SIPETag, "SIP-ETag", Token, "RFC 3903"); +defineHeader(SIPIfMatch, "SIP-If-Match", Token, "RFC 3903"); +defineHeader(ContentId, "Content-ID", Token, "RFC 2045"); + +defineHeader(Identity, "Identity", StringCategory, "RFC 4474"); + +defineMultiHeader(AllowEvents, "Allow-Events", Token, "RFC 3265"); +// explicitly declare to avoid h_AllowEventss, ugh +H_AllowEventss resip::h_AllowEvents; + +defineMultiHeader(AcceptEncoding, "Accept-Encoding", Token, "RFC 3261"); +defineMultiHeader(AcceptLanguage, "Accept-Language", Token, "RFC 3261"); +defineMultiHeader(Allow, "Allow", Token, "RFC 3261"); +defineMultiHeader(ContentLanguage, "Content-Language", Token, "RFC 3261"); +defineMultiHeader(ProxyRequire, "Proxy-Require", Token, "RFC 3261"); +defineMultiHeader(Require, "Require", Token, "RFC 3261"); +defineMultiHeader(Supported, "Supported", Token, "RFC 3261"); +defineMultiHeader(Unsupported, "Unsupported", Token, "RFC 3261"); +defineMultiHeader(SecurityClient, "Security-Client", Token, "RFC 3329"); +defineMultiHeader(SecurityServer, "Security-Server", Token, "RFC 3329"); +defineMultiHeader(SecurityVerify, "Security-Verify", Token, "RFC 3329"); +// explicitly declare to avoid h_SecurityVerifys, ugh +H_SecurityVerifys resip::h_SecurityVerifies; + +defineMultiHeader(RequestDisposition, "Request-Disposition", Token, "RFC 3841"); +defineMultiHeader(Reason, "Reason", Token, "RFC 3326"); +defineMultiHeader(Privacy, "Privacy", PrivacyCategory, "RFC 3323"); +// explicitly declare to avoid h_Privacys +H_Privacys resip::h_Privacies; + +defineMultiHeader(PMediaAuthorization, "P-Media-Authorization", Token, "RFC 3313"); +defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488"); +defineHeader(AnswerMode, "Answer-Mode", Token, "draft-ietf-answermode-01"); +defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "draft-ietf-answermode-01"); + +//==================== +// Mime +//==================== +typedef ParserContainer<Mime> Mimes; + +defineMultiHeader(Accept, "Accept", Mime, "RFC 3261"); +defineHeader(ContentType, "Content-Type", Mime, "RFC 3261"); + +//==================== +// GenericUris: +//==================== +defineHeader(IdentityInfo, "Identity-Info", GenericUri, "RFC 4474"); + +typedef ParserContainer<GenericUri> GenericUris; +defineMultiHeader(CallInfo, "Call-Info", GenericUri, "RFC 3261"); +defineMultiHeader(AlertInfo, "Alert-Info", GenericUri, "RFC 3261"); +defineMultiHeader(ErrorInfo, "Error-Info", GenericUri, "RFC 3261"); + +//==================== +// NameAddr: +//==================== +typedef ParserContainer<NameAddr> NameAddrs; + +defineMultiHeader(RecordRoute, "Record-Route", NameAddr, "RFC 3261"); +defineMultiHeader(Route, "Route", NameAddr, "RFC 3261"); +defineMultiHeader(Contact, "Contact", NameAddr, "RFC 3261"); +defineHeader(From, "From", NameAddr, "RFC 3261"); +defineHeader(To, "To", NameAddr, "RFC 3261"); +defineHeader(ReplyTo, "Reply-To", NameAddr, "RFC 3261"); +defineHeader(ReferTo, "Refer-To", NameAddr, "RFC 3515"); +defineHeader(ReferredBy, "Referred-By", NameAddr, "RFC 3892"); + +defineMultiHeader(Path, "Path", NameAddr, "RFC 3327"); +defineMultiHeader(AcceptContact, "Accept-Contact", NameAddr, "RFC 3841"); +defineMultiHeader(RejectContact, "Reject-Contact", NameAddr, "RFC 3841"); +defineMultiHeader(PPreferredIdentity, "P-Preferred-Identity", NameAddr, "RFC 3325"); +// explicitly declare to avoid h_PPrefferedIdentitys +H_PPreferredIdentitys resip::h_PPreferredIdentities; + +defineMultiHeader(PAssertedIdentity, "P-Asserted-Identity", NameAddr, "RFC 3325"); +// explicitly declare to avoid h_PAssertedIdentitys +H_PAssertedIdentitys resip::h_PAssertedIdentities; + + +defineHeader(PCalledPartyId, "P-Called-Party-ID", NameAddr, "RFC 3455"); +defineMultiHeader(PAssociatedUri, "P-Associated-URI", NameAddr, "RFC 3455"); +defineMultiHeader(ServiceRoute, "Service-Route", NameAddr, "RFC 3608"); +defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04"); // ?bwc? Not in 3323, should we keep? +defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244"); + +//==================== +// String: +//==================== +typedef ParserContainer<StringCategory> StringCategories; + +defineHeader(Organization, "Organization", StringCategory, "RFC 3261"); +defineHeader(Server, "Server", StringCategory, "RFC 3261"); +defineHeader(Subject, "Subject", StringCategory, "RFC 3261"); +defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261"); +defineHeader(Timestamp, "Timestamp", StringCategory, "RFC 3261"); + +//==================== +// Integer: +//==================== + +// !dlb! not clear this needs to be exposed +defineHeader(ContentLength, "Content-Length", UInt32Category, "RFC 3261"); +defineHeader(MaxForwards, "Max-Forwards", UInt32Category, "RFC 3261"); +defineHeader(MinExpires, "Min-Expires", UInt32Category, "RFC 3261"); +defineHeader(RSeq, "RSeq", UInt32Category, "RFC 3262"); + +// !dlb! this one is not quite right -- can have (comment) after field value +// !rwm! WHO CARES!!!! Comments are evil +defineHeader(RetryAfter, "Retry-After", UInt32Category, "RFC 3261"); +defineHeader(FlowTimer, "Flow-Timer", UInt32Category, "RFC 5626"); + +defineHeader(Expires, "Expires", ExpiresCategory, "RFC 3261"); +defineHeader(SessionExpires, "Session-Expires", ExpiresCategory, "RFC 4028"); +defineHeader(MinSE, "Min-SE", ExpiresCategory, "RFC 4028"); + +//==================== +// CallId: +//==================== +defineHeader(CallID, "Call-ID", CallId, "RFC 3261"); +H_CallId resip::h_CallId; // code convention compatible +defineHeader(Replaces, "Replaces", CallId, "RFC 3891"); +defineHeader(InReplyTo, "In-Reply-To", CallId, "RFC 3261"); +defineHeader(Join, "Join", CallId, "RFC 3911"); +defineHeader(TargetDialog, "Target-Dialog", CallId, "RFC 4538"); + + +//==================== +// Auth: +//==================== +defineHeader(AuthenticationInfo, "Authentication-Info", Auth, "RFC 3261"); +defineMultiHeader(Authorization, "Authorization", Auth, "RFC 3261"); +defineMultiHeader(ProxyAuthenticate, "Proxy-Authenticate", Auth, "RFC 3261"); +defineMultiHeader(ProxyAuthorization, "Proxy-Authorization", Auth, "RFC 3261"); +defineMultiHeader(WWWAuthenticate, "WWW-Authenticate", Auth, "RFC 3261"); + +//==================== +// CSeqCategory: +//==================== +defineHeader(CSeq, "CSeq", CSeqCategory, "RFC 3261"); + +//==================== +// DateCategory: +//==================== +defineHeader(Date, "Date", DateCategory, "RFC 3261"); + +//==================== +// WarningCategory: +//==================== +defineMultiHeader(Warning, "Warning", WarningCategory, "RFC 3261"); + +//==================== +// RAckCategory +//==================== +defineHeader(RAck, "RAck", RAckCategory, "RFC 3262"); + +defineMultiHeader(Via, "Via", Via, "RFC 3261"); + +//Enforces string encoding of extension headers +Headers::Type +H_RESIP_DO_NOT_USEs::getTypeNum() const {return Headers::RESIP_DO_NOT_USE;} + +H_RESIP_DO_NOT_USEs::H_RESIP_DO_NOT_USEs() +{ + Headers::CommaTokenizing[Headers::RESIP_DO_NOT_USE+1] = bool(Type::value_type::commaHandling & ParserCategory::CommasAllowedOutputMulti); + Headers::CommaEncoding[Headers::RESIP_DO_NOT_USE+1] = bool(Type::value_type::commaHandling & 2); + Headers::HeaderNames[Headers::RESIP_DO_NOT_USE+1] = "RESIP_DO_NOT_USE"; +} + +ParserContainer<StringCategory>& +H_RESIP_DO_NOT_USEs::knownReturn(ParserContainerBase* container) +{ + return *dynamic_cast<ParserContainer<StringCategory>*>(container); +} + +H_RESIP_DO_NOT_USEs resip::h_RESIP_DO_NOT_USEs; + +void H_RESIP_DO_NOT_USEs::merge(SipMessage& target, const SipMessage& embedded) +{ +} + +ParserContainerBase* +H_RESIP_DO_NOT_USEs::makeContainer(HeaderFieldValueList* hfvs) const +{ + return new ParserContainer<StringCategory>(hfvs,Headers::RESIP_DO_NOT_USE); +} + +RequestLineType resip::h_RequestLine; +StatusLineType resip::h_StatusLine; + +Headers::Type +Headers::getType(const char* name, int len) +{ + const struct headers* p; + p = HeaderHash::in_word_set(name, len); + return p ? Headers::Type(p->type) : Headers::UNKNOWN; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Headers.hxx b/src/libs/resiprocate/resip/stack/Headers.hxx new file mode 100644 index 00000000..227cbae5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Headers.hxx @@ -0,0 +1,358 @@ +#if !defined(RESIP_HEADERS_HXX) +#define RESIP_HEADERS_HXX + +#include "resip/stack/ParserCategories.hxx" +#include "resip/stack/HeaderTypes.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/Data.hxx" +#include "rutil/HeapInstanceCounter.hxx" + +namespace resip +{ +class SipMessage; +class HeaderFieldValueList; + +//#define PARTIAL_TEMPLATE_SPECIALIZATION +#ifdef PARTIAL_TEMPLATE_SPECIALIZATION +template<bool> +class TypeIf +{ + public: + template <class T> + class Resolve + { + public: + typedef T Type; + }; +}; + +class UnusedHeader +{ +}; + +class TypeIf<false> +{ + public: + template <class T> + class Resolve + { + public: + typedef UnusedHeader Type; + }; +}; + +#define UnusedChecking(_enum) \ + typedef TypeIf<Headers::_enum != Headers::UNKNOWN> TypeIfT; \ + typedef TypeIfT::Resolve<Type> Resolver; \ + typedef Resolver::Type UnknownReturn + +#define MultiUnusedChecking(_enum) \ + typedef TypeIf<Headers::_enum != Headers::UNKNOWN> TypeIfT; \ + typedef TypeIfT::Resolve< ParserContainer<Type> > Resolver; \ + typedef Resolver::Type UnknownReturn + +#else + +#define UnusedChecking(_enum) typedef int _dummy +#define MultiUnusedChecking(_enum) typedef int _dummy + +#endif + +class HeaderBase +{ + public: + virtual ~HeaderBase() {} + virtual Headers::Type getTypeNum() const = 0; + virtual void merge(SipMessage&, const SipMessage&)=0; + + static HeaderBase* getInstance(Headers::Type typenum) + { + return theHeaderInstances[typenum+1]; + } + + virtual ParserContainerBase* makeContainer(HeaderFieldValueList* hfvs) const=0; + protected: + static HeaderBase* theHeaderInstances[Headers::MAX_HEADERS+1]; +}; + +#define defineHeader(_enum, _name, _type, _rfc) \ +class H_##_enum : public HeaderBase \ +{ \ + public: \ + RESIP_HeapCount(H_##_enum); \ + enum {Single = true}; \ + typedef _type Type; \ + UnusedChecking(_enum); \ + static Type& knownReturn(ParserContainerBase* container); \ + virtual ParserContainerBase* makeContainer(HeaderFieldValueList* hfvs) const; \ + virtual Headers::Type getTypeNum() const; \ + virtual void merge(SipMessage&, const SipMessage&); \ + H_##_enum(); \ +}; \ +extern H_##_enum h_##_enum + +#define defineMultiHeader(_enum, _name, _type, _rfc) \ +class H_##_enum##s : public HeaderBase \ +{ \ + public: \ + RESIP_HeapCount(H_##_enum##s); \ + enum {Single = false}; \ + typedef ParserContainer<_type> Type; \ + typedef _type ContainedType; \ + MultiUnusedChecking(_enum); \ + static Type& knownReturn(ParserContainerBase* container); \ + virtual ParserContainerBase* makeContainer(HeaderFieldValueList* hfvs) const; \ + virtual Headers::Type getTypeNum() const; \ + virtual void merge(SipMessage&, const SipMessage&); \ + H_##_enum##s(); \ +}; \ +extern H_##_enum##s h_##_enum##s + +//==================== +// Token: +//==================== +typedef ParserContainer<Token> Tokens; + +defineHeader(ContentDisposition, "Content-Disposition", Token, "RFC 3261"); +defineHeader(ContentEncoding, "Content-Encoding", Token, "RFC 3261"); +defineHeader(MIMEVersion, "Mime-Version", Token, "RFC 3261"); +defineHeader(Priority, "Priority", Token, "RFC 3261"); +defineHeader(Event, "Event", Token, "RFC 3265"); +defineHeader(SubscriptionState, "Subscription-State", Token, "RFC 3265"); + +defineHeader(SIPETag, "SIP-ETag", Token, "RFC 3903"); +defineHeader(SIPIfMatch, "SIP-If-Match", Token, "RFC 3903"); +defineHeader(ContentId, "Content-ID", Token, "RFC 2045"); + +defineMultiHeader(AllowEvents, "Allow-Events", Token, "RFC 3265"); + +defineHeader(Identity, "Identity", StringCategory, "RFC 4474"); +// explicitly declare to avoid h_AllowEventss, ugh +extern H_AllowEventss h_AllowEvents; + +defineMultiHeader(AcceptEncoding, "Accept-Encoding", Token, "RFC 3261"); +defineMultiHeader(AcceptLanguage, "Accept-Language", Token, "RFC 3261"); +defineMultiHeader(Allow, "Allow", Token, "RFC 3261"); +defineMultiHeader(ContentLanguage, "Content-Language", Token, "RFC 3261"); +defineMultiHeader(ProxyRequire, "Proxy-Require", Token, "RFC 3261"); +defineMultiHeader(Require, "Require", Token, "RFC 3261"); +defineMultiHeader(Supported, "Supported", Token, "RFC 3261"); +defineMultiHeader(Unsupported, "Unsupported", Token, "RFC 3261"); +defineMultiHeader(SecurityClient, "Security-Client", Token, "RFC 3329"); +defineMultiHeader(SecurityServer, "Security-Server", Token, "RFC 3329"); +defineMultiHeader(SecurityVerify, "Security-Verify", Token, "RFC 3329"); +// explicitly declare to avoid h_SecurityVerifys, ugh +extern H_SecurityVerifys h_SecurityVerifies; + +defineMultiHeader(RequestDisposition, "Request-Disposition", Token, "RFC 3841"); +defineMultiHeader(Reason, "Reason", Token, "RFC 3326"); +defineMultiHeader(Privacy, "Privacy", PrivacyCategory, "RFC 3323"); +// explicitly declare to avoid h_Privacys +extern H_Privacys h_Privacies; + +defineMultiHeader(PMediaAuthorization, "P-Media-Authorization", Token, "RFC 3313"); + +defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488"); +defineHeader(AnswerMode, "Answer-Mode", Token, "draft-ietf-answermode-01"); +defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "draft-ietf-answermode-01"); + +//==================== +// Mime +//==================== +typedef ParserContainer<Mime> Mimes; + +defineMultiHeader(Accept, "Accept", Mime, "RFC 3261"); +defineHeader(ContentType, "Content-Type", Mime, "RFC 3261"); + +//==================== +// GenericUris: +//==================== +typedef ParserContainer<GenericUri> GenericUris; +defineMultiHeader(CallInfo, "Call-Info", GenericUri, "RFC 3261"); +defineMultiHeader(AlertInfo, "Alert-Info", GenericUri, "RFC 3261"); +defineMultiHeader(ErrorInfo, "Error-Info", GenericUri, "RFC 3261"); +defineHeader(IdentityInfo, "Identity-Info", GenericUri, "RFC 4474"); + +//==================== +// NameAddr: +//==================== +typedef ParserContainer<NameAddr> NameAddrs; + +defineMultiHeader(RecordRoute, "Record-Route", NameAddr, "RFC 3261"); +defineMultiHeader(Route, "Route", NameAddr, "RFC 3261"); +defineMultiHeader(Contact, "Contact", NameAddr, "RFC 3261"); +defineHeader(From, "From", NameAddr, "RFC 3261"); +defineHeader(To, "To", NameAddr, "RFC 3261"); +defineHeader(ReplyTo, "Reply-To", NameAddr, "RFC 3261"); +defineHeader(ReferTo, "Refer-To", NameAddr, "RFC 3515"); +defineHeader(ReferredBy, "Referred-By", NameAddr, "RFC 3892"); + +defineMultiHeader(Path, "Path", NameAddr, "RFC 3327"); +defineMultiHeader(AcceptContact, "Accept-Contact", NameAddr, "RFC 3841"); +defineMultiHeader(RejectContact, "Reject-Contact", NameAddr, "RFC 3841"); +defineMultiHeader(PPreferredIdentity, "P-Preferred-Identity", NameAddr, "RFC 3325"); +// explicitly declare to avoid h_PAssertedIdentitys +extern H_PPreferredIdentitys h_PPreferredIdentities; + +defineMultiHeader(PAssertedIdentity, "P-Asserted-Identity", NameAddr, "RFC 3325"); +// explicitly declare to avoid h_PAssertedIdentitys +extern H_PAssertedIdentitys h_PAssertedIdentities; + +defineHeader(PCalledPartyId, "P-Called-Party-ID", NameAddr, "RFC 3455"); +defineMultiHeader(PAssociatedUri, "P-Associated-URI", NameAddr, "RFC 3455"); +defineMultiHeader(ServiceRoute, "Service-Route", NameAddr, "RFC 3608"); +defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04"); // ?bwc? Not in 3323, should we keep? +defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244"); + +//==================== +// StringCategory: +//==================== +typedef ParserContainer<StringCategory> StringCategories; + +defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC ?"); +defineHeader(Organization, "Organization", StringCategory, "RFC 3261"); +defineHeader(Server, "Server", StringCategory, "RFC 3261"); +defineHeader(Subject, "Subject", StringCategory, "RFC 3261"); +defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261"); +defineHeader(Timestamp, "Timestamp", StringCategory, "RFC 3261"); + +//==================== +// ExpiresCategory: +//==================== + +defineHeader(Expires, "Expires", ExpiresCategory, "RFC 3261"); +defineHeader(SessionExpires, "Session-Expires", ExpiresCategory, "RFC 4028"); +defineHeader(MinSE, "Min-SE", ExpiresCategory, "RFC 4028"); + +//==================== +// UInt32Category: +//==================== +typedef ParserContainer<UInt32Category> UInt32Categories; +defineHeader(MaxForwards, "Max-Forwards", UInt32Category, "RFC 3261"); +// !dlb! not clear this needs to be exposed +defineHeader(ContentLength, "Content-Length", UInt32Category, "RFC 3261"); +defineHeader(MinExpires, "Min-Expires", UInt32Category, "RFC 3261"); +defineHeader(RSeq, "RSeq", UInt32Category, "RFC 3261"); + +// !dlb! this one is not quite right -- can have (comment) after field value +defineHeader(RetryAfter, "Retry-After", UInt32Category, "RFC 3261"); +defineHeader(FlowTimer, "Flow-Timer", UInt32Category, "RFC 5626"); + +//==================== +// CallId: +//==================== +defineHeader(CallID, "Call-ID", CallID, "RFC 3261"); +defineHeader(Replaces, "Replaces", CallID, "RFC 3891"); +defineHeader(InReplyTo, "In-Reply-To", CallID, "RFC 3261"); + +typedef H_CallID H_CallId; // code convention compatible +extern H_CallId h_CallId; // code convention compatible + +defineHeader(Join, "Join", CallId, "RFC 3911"); +defineHeader(TargetDialog, "Target-Dialog", CallId, "RFC 4538"); + + +//==================== +// Auth: +//==================== +typedef ParserContainer<Auth> Auths; +defineHeader(AuthenticationInfo, "Authentication-Info", Auth, "RFC 3261"); +defineMultiHeader(Authorization, "Authorization", Auth, "RFC 3261"); +defineMultiHeader(ProxyAuthenticate, "Proxy-Authenticate", Auth, "RFC 3261"); +defineMultiHeader(ProxyAuthorization, "Proxy-Authorization", Auth, "RFC 3261"); +defineMultiHeader(WWWAuthenticate, "Www-Authenticate", Auth, "RFC 3261"); + +//==================== +// CSeqCategory: +//==================== +defineHeader(CSeq, "CSeq", CSeqCategory, "RFC 3261"); + +//==================== +// DateCategory: +//==================== +defineHeader(Date, "Date", DateCategory, "RFC 3261"); + +//==================== +// WarningCategory: +//==================== +defineMultiHeader(Warning, "Warning", WarningCategory, "RFC 3261"); + +//Enforces string encoding of extension headers +defineMultiHeader(RESIP_DO_NOT_USE, "If you see this things are seriously awry", StringCategory, "NA"); + +//==================== +// Via +//==================== +typedef ParserContainer<Via> Vias; +defineMultiHeader(Via, "Via", Via, "RFC 3261"); + +//==================== +// RAckCategory +//==================== +defineHeader(RAck, "RAck", RAckCategory, "RFC 3262"); + +//==================== +// special first line accessors +//==================== +class RequestLineType {}; +extern RequestLineType h_RequestLine; + +class StatusLineType {}; +extern StatusLineType h_StatusLine; + +} + +#undef defineHeader +#undef defineMultiHeader + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Helper.cxx b/src/libs/resiprocate/resip/stack/Helper.cxx new file mode 100644 index 00000000..fb9605a7 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Helper.cxx @@ -0,0 +1,2299 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <string.h> +#include <iomanip> +#include <algorithm> +#include <memory> + +#include "resip/stack/Auth.hxx" +#include "resip/stack/BasicNonceHelper.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/NonceHelper.hxx" +#include "rutil/Coders.hxx" +#include "resip/stack/Uri.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Random.hxx" +#include "rutil/Timer.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/MD5Stream.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/compat.hxx" +#include "rutil/ParseBuffer.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Pkcs7Contents.hxx" +#include "resip/stack/MultipartSignedContents.hxx" +#include "resip/stack/MultipartMixedContents.hxx" +#include "resip/stack/MultipartAlternativeContents.hxx" +#include "rutil/WinLeakCheck.hxx" + +#ifdef USE_SSL +#include "resip/stack/ssl/Security.hxx" +#endif + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +const int Helper::tagSize = 4; + +// !jf! this should be settable by the application in case a group of apps +// (e.g. proxies) want to share the same secret +Helper::NonceHelperPtr Helper::mNonceHelperPtr; + +void Helper::integer2hex(char* _d, unsigned int _s, bool _l) +{ + int i; + unsigned char j; + int k = 0; + char* s; + + _s = htonl(_s); + s = (char*)&_s; + + for (i = 0; i < 4; i++) + { + j = (s[i] >> 4) & 0xf; + if (j <= 9) + { + if(_l || j != 0 || k != 0) + { + _d[k++] = (j + '0'); + } + } + else + { + _d[k++] = (j + 'a' - 10); + } + + j = s[i] & 0xf; + if (j <= 9) + { + if(_l || j != 0 || k != 0) + { + _d[k++] = (j + '0'); + } + } + else + { + _d[k++] = (j + 'a' - 10); + } + } +} + +unsigned int Helper::hex2integer(const char* _s) +{ + unsigned int i, res = 0; + + for(i = 0; i < 8; i++) + { + if ((_s[i] >= '0') && (_s[i] <= '9')) + { + res *= 16; + res += _s[i] - '0'; + } + else if ((_s[i] >= 'a') && (_s[i] <= 'f')) + { + res *= 16; + res += _s[i] - 'a' + 10; + } + else if ((_s[i] >= 'A') && (_s[i] <= 'F')) + { + res *= 16; + res += _s[i] - 'A' + 10; + } + else + { + return res; + } + } + + return res; +} + +SipMessage* +Helper::makeRequest(const NameAddr& target, const NameAddr& from, const NameAddr& contact, MethodTypes method) +{ + std::auto_ptr<SipMessage> request(new SipMessage); + RequestLine rLine(method); + rLine.uri() = target.uri(); + request->header(h_To) = target; + request->header(h_RequestLine) = rLine; + request->header(h_MaxForwards).value() = 70; + request->header(h_CSeq).method() = method; + request->header(h_CSeq).sequence() = 1; + request->header(h_From) = from; + request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); + request->header(h_Contacts).push_back(contact); + request->header(h_CallId).value() = Helper::computeCallId(); + //request->header(h_ContentLength).value() = 0; + + Via via; + request->header(h_Vias).push_back(via); + + return request.release(); +} + +SipMessage* +Helper::makeRequest(const NameAddr& target, const NameAddr& from, MethodTypes method) +{ + NameAddr contact; + return makeRequest(target, from, contact, method); +} + +SipMessage* +Helper::makeRegister(const NameAddr& to, const NameAddr& from) +{ + NameAddr contact; + return makeRegister(to, from, contact); +} + +SipMessage* +Helper::makeRegister(const NameAddr& to, const NameAddr& from, const NameAddr& contact) +{ + std::auto_ptr<SipMessage> request(new SipMessage); + RequestLine rLine(REGISTER); + + rLine.uri().scheme() = to.uri().scheme(); + rLine.uri().host() = to.uri().host(); + rLine.uri().port() = to.uri().port(); + if (to.uri().exists(p_transport)) + { + rLine.uri().param(p_transport) = to.uri().param(p_transport); + } + + request->header(h_To) = to; + request->header(h_RequestLine) = rLine; + request->header(h_MaxForwards).value() = 70; + request->header(h_CSeq).method() = REGISTER; + request->header(h_CSeq).sequence() = 1; + request->header(h_From) = from; + request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); + request->header(h_CallId).value() = Helper::computeCallId(); + assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); + request->header(h_Contacts).push_back( contact ); + + Via via; + request->header(h_Vias).push_back(via); + + return request.release(); +} + +SipMessage* +Helper::makeRegister(const NameAddr& to,const Data& transport) +{ + NameAddr contact; + return makeRegister(to, transport, contact); + +} + +SipMessage* +Helper::makeRegister(const NameAddr& to, const Data& transport, const NameAddr& contact) +{ + std::auto_ptr<SipMessage> request(new SipMessage); + RequestLine rLine(REGISTER); + + rLine.uri().scheme() = to.uri().scheme(); + rLine.uri().host() = to.uri().host(); + rLine.uri().port() = to.uri().port(); + if (!transport.empty()) + { + rLine.uri().param(p_transport) = transport; + } + + request->header(h_To) = to; + request->header(h_RequestLine) = rLine; + request->header(h_MaxForwards).value() = 70; + request->header(h_CSeq).method() = REGISTER; + request->header(h_CSeq).sequence() = 1; + request->header(h_From) = to; + request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); + request->header(h_CallId).value() = Helper::computeCallId(); + assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); + request->header(h_Contacts).push_back( contact ); + + Via via; + request->header(h_Vias).push_back(via); + + return request.release(); +} + + +SipMessage* +Helper::makePublish(const NameAddr& target, const NameAddr& from) +{ + NameAddr contact; + return makePublish(target, from, contact); +} + +SipMessage* +Helper::makePublish(const NameAddr& target, const NameAddr& from, const NameAddr& contact) +{ + std::auto_ptr<SipMessage> request(new SipMessage); + RequestLine rLine(PUBLISH); + rLine.uri() = target.uri(); + + request->header(h_To) = target; + request->header(h_RequestLine) = rLine; + request->header(h_MaxForwards).value() = 70; + request->header(h_CSeq).method() = PUBLISH; + request->header(h_CSeq).sequence() = 1; + request->header(h_From) = from; + request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); + request->header(h_CallId).value() = Helper::computeCallId(); + assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); + request->header(h_Contacts).push_back( contact ); + Via via; + request->header(h_Vias).push_back(via); + + return request.release(); +} + +SipMessage* +Helper::makeMessage(const NameAddr& target, const NameAddr& from) +{ + NameAddr contact; + return makeMessage(target, from, contact); +} + +SipMessage* +Helper::makeMessage(const NameAddr& target, const NameAddr& from, const NameAddr& contact) +{ + std::auto_ptr<SipMessage> request(new SipMessage); + RequestLine rLine(MESSAGE); + rLine.uri() = target.uri(); + + request->header(h_To) = target; + request->header(h_RequestLine) = rLine; + request->header(h_MaxForwards).value() = 70; + request->header(h_CSeq).method() = MESSAGE; + request->header(h_CSeq).sequence() = 1; + request->header(h_From) = from; + request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); + request->header(h_CallId).value() = Helper::computeCallId(); + assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); + request->header(h_Contacts).push_back( contact ); + Via via; + request->header(h_Vias).push_back(via); + + return request.release(); +} + + +SipMessage* +Helper::makeSubscribe(const NameAddr& target, const NameAddr& from) +{ + NameAddr contact; + return makeSubscribe(target, from, contact); +} + +SipMessage* +Helper::makeSubscribe(const NameAddr& target, const NameAddr& from, const NameAddr& contact) +{ + std::auto_ptr<SipMessage> request(new SipMessage); + RequestLine rLine(SUBSCRIBE); + rLine.uri() = target.uri(); + + request->header(h_To) = target; + request->header(h_RequestLine) = rLine; + request->header(h_MaxForwards).value() = 70; + request->header(h_CSeq).method() = SUBSCRIBE; + request->header(h_CSeq).sequence() = 1; + request->header(h_From) = from; + request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); + request->header(h_CallId).value() = Helper::computeCallId(); + assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); + request->header(h_Contacts).push_front( contact ); + Via via; + request->header(h_Vias).push_front(via); + + return request.release(); +} + +int +Helper::jitterValue(int input, int lowerPercentage, int upperPercentage, int minimum) +{ + assert(upperPercentage >= lowerPercentage); + if (input < minimum) + { + return input; + } + else if (lowerPercentage == 100 && upperPercentage == 100) + { + return input; + } + else + { + const int rnd = Random::getRandom() % (upperPercentage-lowerPercentage) + lowerPercentage; + return (input * rnd) / 100; + } +} + +SipMessage* +Helper::makeInvite(const NameAddr& target, const NameAddr& from) +{ + return Helper::makeRequest(target, from, INVITE); +} + +SipMessage* +Helper::makeInvite(const NameAddr& target, const NameAddr& from, const NameAddr& contact) +{ + return Helper::makeRequest(target, from, contact, INVITE); +} + + +void +Helper::makeResponse(SipMessage& response, + const SipMessage& request, + int responseCode, + const NameAddr& myContact, + const Data& reason, + const Data& hostname, + const Data& warning) +{ + makeResponse(response,request, responseCode, reason,hostname, warning); + // in general, this should not create a Contact header since only requests + // that create a dialog (or REGISTER requests) should produce a response with + // a contact(s). + response.header(h_Contacts).clear(); + response.header(h_Contacts).push_back(myContact); +} + + +void +Helper::makeResponse(SipMessage& response, + const SipMessage& request, + int responseCode, + const Data& reason, + const Data& hostname, + const Data& warning) +{ + DebugLog(<< "Helper::makeResponse(" << request.brief() << " code=" << responseCode << " reason=" << reason); + response.header(h_StatusLine).responseCode() = responseCode; + response.header(h_From) = request.header(h_From); + response.header(h_To) = request.header(h_To); + response.header(h_CallId) = request.header(h_CallId); + response.header(h_CSeq) = request.header(h_CSeq); + response.header(h_Vias) = request.header(h_Vias); + + if (!warning.empty()) + { + WarningCategory warn; + warn.code() = 399; + warn.hostname() = hostname; + warn.text() = warning; + response.header(h_Warnings).push_back(warn); + } + + if(responseCode > 100 && + response.const_header(h_To).isWellFormed() && + !response.const_header(h_To).exists(p_tag)) + { + // Only generate a To: tag if one doesn't exist. Think Re-INVITE. + // No totag for failure responses or 100s + // ?bwc? Should we be generating to-tags for failure responses or not? + // The comments say no, but the code says yes. Which is it? + response.header(h_To).param(p_tag) = Helper::computeTag(Helper::tagSize); + } + + // .bwc. This will only throw if the topmost Via is malformed, and that + // should have been caught at the transport level. + response.setRFC2543TransactionId(request.getRFC2543TransactionId()); + + //response.header(h_ContentLength).value() = 0; + + if (responseCode >= 180 && responseCode < 300 && request.exists(h_RecordRoutes)) + { + response.header(h_RecordRoutes) = request.header(h_RecordRoutes); + } + + // .bwc. If CSeq is malformed, basicCheck would have already attempted to + // parse it, meaning we won't throw here (we never try to parse the same + // thing twice, see LazyParser::checkParsed()) + if (responseCode/100 == 2 && + !response.exists(h_Contacts) && + !(response.const_header(h_CSeq).method()==CANCEL) ) + { + // in general, this should not create a Contact header since only requests + // that create a dialog (or REGISTER requests) should produce a response with + // a contact(s). + + NameAddr contact; + response.header(h_Contacts).push_back(contact); + } + + if (request.isExternal()) + { + response.setFromTU(); + } + else + { + response.setFromExternal(); + } + + if (reason.size()) + { + response.header(h_StatusLine).reason() = reason; + } + else + { + getResponseCodeReason(responseCode, response.header(h_StatusLine).reason()); + } +} + +SipMessage* +Helper::makeResponse(const SipMessage& request, + int responseCode, + const NameAddr& myContact, + const Data& reason, + const Data& hostname, + const Data& warning) +{ + // .bwc. Exception safety. Catch/rethrow is dicey because we can't rethrow + // resip::BaseException, since it is abstract. + std::auto_ptr<SipMessage> response(new SipMessage); + + makeResponse(*response, request, responseCode, reason, hostname, warning); + + // in general, this should not create a Contact header since only requests + // that create a dialog (or REGISTER requests) should produce a response with + // a contact(s). + response->header(h_Contacts).clear(); + response->header(h_Contacts).push_back(myContact); + return response.release(); +} + + +SipMessage* +Helper::makeResponse(const SipMessage& request, + int responseCode, + const Data& reason, + const Data& hostname, + const Data& warning) +{ + // .bwc. Exception safety. Catch/rethrow is dicey because we can't rethrow + // resip::BaseException, since it is abstract. + std::auto_ptr<SipMessage> response(new SipMessage); + + makeResponse(*response, request, responseCode, reason, hostname, warning); + return response.release(); +} + +void +Helper::makeRawResponse(Data& raw, + const SipMessage& msg, + int responseCode, + const Data& additionalHeaders, + const Data& body) +{ + raw.reserve(256); + { + DataStream encodeStream(raw); + encodeStream << "SIP/2.0 " << responseCode << " "; + Data reason; + getResponseCodeReason(responseCode, reason); + encodeStream << reason; + msg.encodeSingleHeader(Headers::Via,encodeStream); + msg.encodeSingleHeader(Headers::To,encodeStream); + msg.encodeSingleHeader(Headers::From,encodeStream); + msg.encodeSingleHeader(Headers::CallID,encodeStream); + msg.encodeSingleHeader(Headers::CSeq,encodeStream); + encodeStream << additionalHeaders; + encodeStream << "Content-Length: " << body.size() << "\r\n\r\n"; + } +} + +void +Helper::getResponseCodeReason(int responseCode, Data& reason) +{ + switch (responseCode) + { + case 100: reason = "Trying"; break; + case 180: reason = "Ringing"; break; + case 181: reason = "Call Is Being Forwarded"; break; + case 182: reason = "Queued"; break; + case 183: reason = "Session Progress"; break; + case 200: reason = "OK"; break; + case 202: reason = "Accepted"; break; + case 300: reason = "Multiple Choices"; break; + case 301: reason = "Moved Permanently"; break; + case 302: reason = "Moved Temporarily"; break; + case 305: reason = "Use Proxy"; break; + case 380: reason = "Alternative Service"; break; + case 400: reason = "Bad Request"; break; + case 401: reason = "Unauthorized"; break; + case 402: reason = "Payment Required"; break; + case 403: reason = "Forbidden"; break; + case 404: reason = "Not Found"; break; + case 405: reason = "Method Not Allowed"; break; + case 406: reason = "Not Acceptable"; break; + case 407: reason = "Proxy Authentication Required"; break; + case 408: reason = "Request Timeout"; break; + case 410: reason = "Gone"; break; + case 412: reason = "Precondition Failed"; break; + case 413: reason = "Request Entity Too Large"; break; + case 414: reason = "Request-URI Too Long"; break; + case 415: reason = "Unsupported Media Type"; break; + case 416: reason = "Unsupported URI Scheme"; break; + case 420: reason = "Bad Extension"; break; + case 421: reason = "Extension Required"; break; + case 422: reason = "Session Interval Too Small"; break; + case 423: reason = "Interval Too Brief"; break; + case 430: reason = "Flow failed"; break; + case 439: reason = "First Hop Lacks Outbound Support"; break; + case 480: reason = "Temporarily Unavailable"; break; + case 481: reason = "Call/Transaction Does Not Exist"; break; + case 482: reason = "Loop Detected"; break; + case 483: reason = "Too Many Hops"; break; + case 484: reason = "Address Incomplete"; break; + case 485: reason = "Ambiguous"; break; + case 486: reason = "Busy Here"; break; + case 487: reason = "Request Terminated"; break; + case 488: reason = "Not Acceptable Here"; break; + case 489: reason = "Event Package Not Supported"; break; + case 491: reason = "Request Pending"; break; + case 493: reason = "Undecipherable"; break; + case 500: reason = "Server Internal Error"; break; + case 501: reason = "Not Implemented"; break; + case 502: reason = "Bad Gateway"; break; + case 503: reason = "Service Unavailable"; break; + case 504: reason = "Server Time-out"; break; + case 505: reason = "Version Not Supported"; break; + case 513: reason = "Message Too Large"; break; + case 600: reason = "Busy Everywhere"; break; + case 603: reason = "Decline"; break; + case 604: reason = "Does Not Exist Anywhere"; break; + case 606: reason = "Not Acceptable"; break; + } +} + +SipMessage* +Helper::makeCancel(const SipMessage& request) +{ + assert(request.isRequest()); + assert(request.header(h_RequestLine).getMethod() == INVITE); + std::auto_ptr<SipMessage> cancel(new SipMessage); + + RequestLine rLine(CANCEL, request.header(h_RequestLine).getSipVersion()); + rLine.uri() = request.header(h_RequestLine).uri(); + cancel->header(h_RequestLine) = rLine; + cancel->header(h_MaxForwards).value() = 70; + cancel->header(h_To) = request.header(h_To); + cancel->header(h_From) = request.header(h_From); + cancel->header(h_CallId) = request.header(h_CallId); + if (request.exists(h_ProxyAuthorizations)) + { + cancel->header(h_ProxyAuthorizations) = request.header(h_ProxyAuthorizations); + } + if (request.exists(h_Authorizations)) + { + cancel->header(h_Authorizations) = request.header(h_Authorizations); + } + + if (request.exists(h_Routes)) + { + cancel->header(h_Routes) = request.header(h_Routes); + } + + cancel->header(h_CSeq) = request.header(h_CSeq); + cancel->header(h_CSeq).method() = CANCEL; + cancel->header(h_Vias).push_back(request.header(h_Vias).front()); + + return cancel.release(); +} + + +SipMessage* +Helper::makeFailureAck(const SipMessage& request, const SipMessage& response) +{ + assert (request.header(h_Vias).size() >= 1); + assert (request.header(h_RequestLine).getMethod() == INVITE); + + std::auto_ptr<SipMessage> ack(new SipMessage); + + RequestLine rLine(ACK, request.header(h_RequestLine).getSipVersion()); + rLine.uri() = request.header(h_RequestLine).uri(); + ack->header(h_RequestLine) = rLine; + ack->header(h_MaxForwards).value() = 70; + ack->header(h_CallId) = request.header(h_CallId); + ack->header(h_From) = request.header(h_From); + ack->header(h_To) = response.header(h_To); // to get to-tag + ack->header(h_Vias).push_back(request.header(h_Vias).front()); + ack->header(h_CSeq) = request.header(h_CSeq); + ack->header(h_CSeq).method() = ACK; + if (request.exists(h_Routes)) + { + ack->header(h_Routes) = request.header(h_Routes); + } + + return ack.release(); +} + + +static const Data cookie("z9hG4bK"); // magic cookie per rfc3261 +Data +Helper::computeUniqueBranch() +{ + Data result(16, Data::Preallocate); + result += cookie; + result += Random::getRandomHex(4); + result += "C1"; + result += Random::getRandomHex(2); + return result; +} + + +// It is overwritten by Dmytro; because doing getLocalHostName() during initialization is not best idea. +static Data localhostname = "localhost"; +//DnsUtil::getLocalHostName(); + +Data +Helper::computeCallId() +{ + Data hostAndSalt(localhostname + Random::getRandomHex(16)); +#ifndef USE_SSL // .bwc. None of this is neccessary if we're using openssl +#if defined(__linux__) || defined(__APPLE__) + pid_t pid = getpid(); + hostAndSalt.append((char*)&pid,sizeof(pid)); +#endif +#ifdef __APPLE__ + pthread_t thread = pthread_self(); + hostAndSalt.append((char*)&thread,sizeof(thread)); +#endif +#ifdef WIN32 + DWORD proccessId = ::GetCurrentProcessId(); + DWORD threadId = ::GetCurrentThreadId(); + hostAndSalt.append((char*)&proccessId,sizeof(proccessId)); + hostAndSalt.append((char*)&threadId,sizeof(threadId)); +#endif +#endif // of USE_SSL + return hostAndSalt.md5(Data::BASE64); +} + +Data +Helper::computeTag(int numBytes) +{ + return Random::getRandomHex(numBytes); +} + +void +Helper::setNonceHelper(NonceHelper *nonceHelper) +{ + mNonceHelperPtr.mNonceHelper = nonceHelper; +} + +NonceHelper* +Helper::getNonceHelper() +{ + if (mNonceHelperPtr.mNonceHelper == 0) + { + mNonceHelperPtr.mNonceHelper = new BasicNonceHelper(); + } + return mNonceHelperPtr.mNonceHelper; +} + + +Data +Helper::makeNonce(const SipMessage& request, const Data& timestamp) +{ + return getNonceHelper()->makeNonce(request, timestamp); +} + +static Data noBody = MD5Stream().getHex(); +Data +Helper::makeResponseMD5WithA1(const Data& a1, + const Data& method, const Data& digestUri, const Data& nonce, + const Data& qop, const Data& cnonce, const Data& cnonceCount, + const Contents* entityBody) +{ + MD5Stream a2; + a2 << method + << Symbols::COLON + << digestUri; + + if (qop == Symbols::authInt) + { + if (entityBody) + { + MD5Stream eStream; + eStream << *entityBody; + a2 << Symbols::COLON << eStream.getHex(); + } + else + { + a2 << Symbols::COLON << noBody; + } + } + + MD5Stream r; + r << a1 + << Symbols::COLON + << nonce + << Symbols::COLON; + + if (!qop.empty()) + { + r << cnonceCount + << Symbols::COLON + << cnonce + << Symbols::COLON + << qop + << Symbols::COLON; + } + r << a2.getHex(); + + return r.getHex(); +} + +//RFC 2617 3.2.2.1 +Data +Helper::makeResponseMD5(const Data& username, const Data& password, const Data& realm, + const Data& method, const Data& digestUri, const Data& nonce, + const Data& qop, const Data& cnonce, const Data& cnonceCount, + const Contents *entity) +{ + MD5Stream a1; + a1 << username + << Symbols::COLON + << realm + << Symbols::COLON + << password; + + return makeResponseMD5WithA1(a1.getHex(), method, digestUri, nonce, qop, + cnonce, cnonceCount, entity); +} + +static Data digest("digest"); +std::pair<Helper::AuthResult,Data> +Helper::advancedAuthenticateRequest(const SipMessage& request, + const Data& realm, + const Data& a1, + int expiresDelta, + bool proxyAuthorization) +{ + Data username; + DebugLog(<< "Authenticating: realm=" << realm << " expires=" << expiresDelta); + //DebugLog(<< request); + + const ParserContainer<Auth>* auths = 0; + if(proxyAuthorization) + { + if(request.exists(h_ProxyAuthorizations)) + { + auths = &request.header(h_ProxyAuthorizations); + } + } + else + { + if(request.exists(h_Authorizations)) + { + auths = &request.header(h_Authorizations); + } + } + + if (auths) + { + for (ParserContainer<Auth>::const_iterator i = auths->begin(); i != auths->end(); i++) + { + if (i->exists(p_realm) && + i->exists(p_nonce) && + i->exists(p_response) && + i->param(p_realm) == realm) + { + if(!isEqualNoCase(i->scheme(),digest)) + { + DebugLog(<< "Scheme must be Digest"); + continue; + } + /* ParseBuffer pb(i->param(p_nonce).data(), i->param(p_nonce).size()); + if (!pb.eof() && !isdigit(*pb.position())) + { + DebugLog(<< "Invalid nonce; expected timestamp."); + return make_pair(BadlyFormed,username); + } + const char* anchor = pb.position(); + pb.skipToChar(Symbols::COLON[0]); + + if (pb.eof()) + { + DebugLog(<< "Invalid nonce; expected timestamp terminator."); + return make_pair(BadlyFormed,username); + } + + Data then; + pb.data(then, anchor); + if (expiresDelta > 0) + { + unsigned int now = (unsigned int)(Timer::getTimeMs()/1000); + if ((unsigned int)then.convertUInt64() + expiresDelta < now) + { + DebugLog(<< "Nonce has expired."); + return make_pair(Expired,username); + } + } */ + + NonceHelper::Nonce x_nonce = getNonceHelper()->parseNonce(i->param(p_nonce)); + if(x_nonce.getCreationTime() == 0) + return make_pair(BadlyFormed,username); + + if (expiresDelta > 0) + { + UInt64 now = Timer::getTimeSecs(); + if (x_nonce.getCreationTime() + expiresDelta < now) + { + DebugLog(<< "Nonce has expired."); + return make_pair(Expired,username); + } + } + + Data then(x_nonce.getCreationTime()); + if (i->param(p_nonce) != makeNonce(request, then)) + { + InfoLog(<< "Not my nonce. expected=" << makeNonce(request, then) + << " received=" << i->param(p_nonce) + << " then=" << then); + + return make_pair(BadlyFormed,username); + } + + if (i->exists(p_qop)) + { + if (i->param(p_qop) == Symbols::auth || i->param(p_qop) == Symbols::authInt) + { + if(i->exists(p_uri) && i->exists(p_cnonce) && i->exists(p_nc)) + { + if (i->param(p_response) == makeResponseMD5WithA1(a1, + getMethodName(request.header(h_RequestLine).getMethod()), + i->param(p_uri), + i->param(p_nonce), + i->param(p_qop), + i->param(p_cnonce), + i->param(p_nc), + request.getContents())) + { + if(i->exists(p_username)) + { + username = i->param(p_username); + } + return make_pair(Authenticated,username); + } + else + { + return make_pair(Failed,username); + } + } + } + else + { + InfoLog (<< "Unsupported qop=" << i->param(p_qop)); + return make_pair(Failed,username); + } + } + else if(i->exists(p_uri)) + { + if (i->param(p_response) == makeResponseMD5WithA1(a1, + getMethodName(request.header(h_RequestLine).getMethod()), + i->param(p_uri), + i->param(p_nonce))) + { + if(i->exists(p_username)) + { + username = i->param(p_username); + } + return make_pair(Authenticated,username); + } + else + { + return make_pair(Failed,username); + } + } + } + else + { + return make_pair(BadlyFormed,username); + } + } + return make_pair(BadlyFormed,username); + } + DebugLog (<< "No authentication headers. Failing request."); + return make_pair(Failed,username); +} + +Helper::AuthResult +Helper::authenticateRequest(const SipMessage& request, + const Data& realm, + const Data& password, + int expiresDelta) +{ + DebugLog(<< "Authenticating: realm=" << realm << " expires=" << expiresDelta); + //DebugLog(<< request); + + // !bwc! Somewhat inefficient. Maybe optimize later. + ParserContainer<Auth> auths; + + if(request.exists(h_ProxyAuthorizations)) + { + auths.append(request.header(h_ProxyAuthorizations)); + } + + if(request.exists(h_Authorizations)) + { + auths.append(request.header(h_Authorizations)); + } + + if(auths.empty()) + { + DebugLog (<< "No authentication headers. Failing request."); + return Failed; + } + + // ?bwc? Why is const_iterator& operator=(const iterator& rhs) + // not working properly? + //ParserContainer<Auth>::const_iterator i = auths.begin(); + + ParserContainer<Auth>::iterator i = auths.begin(); + + for (; i != auths.end(); i++) + { + if (i->exists(p_realm) && + i->exists(p_nonce) && + i->exists(p_response) && + i->param(p_realm) == realm) + { + if(!isEqualNoCase(i->scheme(),digest)) + { + DebugLog(<< "Scheme must be Digest"); + continue; + } + /* + ParseBuffer pb(i->param(p_nonce).data(), i->param(p_nonce).size()); + if (!pb.eof() && !isdigit(*pb.position())) + { + DebugLog(<< "Invalid nonce; expected timestamp."); + return BadlyFormed; + } + const char* anchor = pb.position(); + pb.skipToChar(Symbols::COLON[0]); + + if (pb.eof()) + { + DebugLog(<< "Invalid nonce; expected timestamp terminator."); + return BadlyFormed; + } + + Data then; + pb.data(then, anchor); + */ + NonceHelper::Nonce x_nonce = getNonceHelper()->parseNonce(i->param(p_nonce)); + if(x_nonce.getCreationTime() == 0) + return BadlyFormed; + + + + + + if (expiresDelta > 0) + { + UInt64 now = Timer::getTimeSecs(); + if (x_nonce.getCreationTime() + expiresDelta < now) + { + DebugLog(<< "Nonce has expired."); + return Expired; + } + } + + Data then(x_nonce.getCreationTime()); + if (i->param(p_nonce) != makeNonce(request, then)) + { + InfoLog(<< "Not my nonce."); + return Failed; + } + + InfoLog (<< " username=" << (i->param(p_username)) + << " password=" << password + << " realm=" << realm + << " method=" << getMethodName(request.header(h_RequestLine).getMethod()) + << " uri=" << i->param(p_uri) + << " nonce=" << i->param(p_nonce)); + + if (i->exists(p_qop)) + { + if (i->param(p_qop) == Symbols::auth || i->param(p_qop) == Symbols::authInt) + { + if(i->exists(p_uri) && i->exists(p_cnonce) && i->exists(p_nc)) + { + if (i->param(p_response) == makeResponseMD5(i->param(p_username), + password, + realm, + getMethodName(request.header(h_RequestLine).getMethod()), + i->param(p_uri), + i->param(p_nonce), + i->param(p_qop), + i->param(p_cnonce), + i->param(p_nc)), + request.getContents()) + { + return Authenticated; + } + else + { + return Failed; + } + } + } + else + { + InfoLog (<< "Unsupported qop=" << i->param(p_qop)); + return Failed; + } + } + else if(i->exists(p_uri)) + { + + if (i->param(p_response) == makeResponseMD5(i->param(p_username), + password, + realm, + getMethodName(request.header(h_RequestLine).getMethod()), + i->param(p_uri), + i->param(p_nonce))) + { + return Authenticated; + } + else + { + return Failed; + } + } + } + else + { + return BadlyFormed; + } + } + + return BadlyFormed; + +} + +Helper::AuthResult +Helper::authenticateRequestWithA1(const SipMessage& request, + const Data& realm, + const Data& hA1, + int expiresDelta) +{ + DebugLog(<< "Authenticating with HA1: realm=" << realm << " expires=" << expiresDelta); + //DebugLog(<< request); + + // !bwc! Somewhat inefficient. Maybe optimize later. + ParserContainer<Auth> auths; + + if(request.exists(h_ProxyAuthorizations)) + { + auths.append(request.header(h_ProxyAuthorizations)); + } + + if(request.exists(h_Authorizations)) + { + auths.append(request.header(h_Authorizations)); + } + + if(auths.empty()) + { + DebugLog (<< "No authentication headers. Failing request."); + return Failed; + } + + // ?bwc? Why is const_iterator& operator=(const iterator& rhs) + // not working properly? + //ParserContainer<Auth>::const_iterator i = auths.begin(); + + ParserContainer<Auth>::iterator i = auths.begin(); + + for (;i != auths.end(); i++) + { + if (i->exists(p_realm) && + i->exists(p_nonce) && + i->exists(p_response) && + i->param(p_realm) == realm) + { + if(!isEqualNoCase(i->scheme(),digest)) + { + DebugLog(<< "Scheme must be Digest"); + continue; + } + /* + ParseBuffer pb(i->param(p_nonce).data(), i->param(p_nonce).size()); + if (!pb.eof() && !isdigit(*pb.position())) + { + DebugLog(<< "Invalid nonce; expected timestamp."); + return BadlyFormed; + } + const char* anchor = pb.position(); + pb.skipToChar(Symbols::COLON[0]); + + if (pb.eof()) + { + DebugLog(<< "Invalid nonce; expected timestamp terminator."); + return BadlyFormed; + } + + Data then; + pb.data(then, anchor); + */ + + NonceHelper::Nonce x_nonce = getNonceHelper()->parseNonce(i->param(p_nonce)); + if(x_nonce.getCreationTime() == 0) + return BadlyFormed; + + + + if (expiresDelta > 0) + { + UInt64 now = Timer::getTimeSecs(); + if (x_nonce.getCreationTime() + expiresDelta < now) + { + DebugLog(<< "Nonce has expired."); + return Expired; + } + } + + Data then(x_nonce.getCreationTime()); + + if (i->param(p_nonce) != makeNonce(request, then)) + { + InfoLog(<< "Not my nonce."); + return Failed; + } + + InfoLog (<< " username=" << (i->param(p_username)) + << " H(A1)=" << hA1 + << " realm=" << realm + << " method=" << getMethodName(request.header(h_RequestLine).getMethod()) + << " uri=" << i->param(p_uri) + << " nonce=" << i->param(p_nonce)); + + if (i->exists(p_qop)) + { + if (i->param(p_qop) == Symbols::auth || i->param(p_qop) == Symbols::authInt) + { + if(i->exists(p_uri) && i->exists(p_cnonce) && i->exists(p_nc)) + { + if (i->param(p_response) == makeResponseMD5WithA1(hA1, + getMethodName(request.header(h_RequestLine).getMethod()), + i->param(p_uri), + i->param(p_nonce), + i->param(p_qop), + i->param(p_cnonce), + i->param(p_nc), + request.getContents())) + { + return Authenticated; + } + else + { + return Failed; + } + } + } + else + { + InfoLog (<< "Unsupported qop=" << i->param(p_qop)); + return Failed; + } + } + else if(i->exists(p_uri)) + { + if (i->param(p_response) == makeResponseMD5WithA1(hA1, + getMethodName(request.header(h_RequestLine).getMethod()), + i->param(p_uri), + i->param(p_nonce))) + { + return Authenticated; + } + else + { + return Failed; + } + } + } + else + { + return BadlyFormed; + } + } + + return BadlyFormed; + +} + +SipMessage* +Helper::make405(const SipMessage& request, + const int* allowedMethods, + int len ) +{ + SipMessage* resp = Helper::makeResponse(request, 405); + + if (len < 0) + { + int upperBound = static_cast<int>(MAX_METHODS); + + // The UNKNOWN method name is the first in the enum + for (int i = 1 ; i < upperBound; i ++) + { + int last = 0; + + // ENUMS must be contiguous in order for this to work. + assert( i - last <= 1); + Token t; + t.value() = getMethodName(static_cast<resip::MethodTypes>(i)); + resp->header(h_Allows).push_back(t); + last = i; + } + } + else + { + // use user's list + for ( int i = 0 ; i < len ; i++) + { + Token t; + t.value() = getMethodName(static_cast<resip::MethodTypes>(allowedMethods[i])); + resp->header(h_Allows).push_back(t); + } + } + return resp; +} + + +SipMessage* +Helper::makeProxyChallenge(const SipMessage& request, const Data& realm, bool useAuth, bool stale) +{ + return makeChallenge(request,realm,useAuth,stale,true); +} + +SipMessage* +Helper::makeWWWChallenge(const SipMessage& request, const Data& realm, bool useAuth, bool stale) +{ + return makeChallenge(request,realm,useAuth,stale,false); +} + +SipMessage* +Helper::makeChallenge(const SipMessage& request, const Data& realm, bool useAuth, bool stale, bool proxy) +{ + Auth auth; + auth.scheme() = Symbols::Digest; + Data timestamp(Timer::getTimeSecs()); + auth.param(p_nonce) = makeNonce(request, timestamp); + auth.param(p_algorithm) = "MD5"; + auth.param(p_realm) = realm; + if (useAuth) + { + auth.param(p_qopOptions) = "auth,auth-int"; + } + if (stale) + { + auth.param(p_stale) = "true"; + } + SipMessage *response; + if(proxy) + { + response = Helper::makeResponse(request, 407); + response->header(h_ProxyAuthenticates).push_back(auth); + } + else + { + response = Helper::makeResponse(request, 401); + response->header(h_WWWAuthenticates).push_back(auth); + } + return response; +} + +void +Helper::updateNonceCount(unsigned int& nonceCount, Data& nonceCountString) +{ + if (!nonceCountString.empty()) + { + return; + } + nonceCount++; + { + //DataStream s(nonceCountString); + + //s << std::setw(8) << std::setfill('0') << std::hex << nonceCount; + char buf[128]; + *buf = 0; + +#if (defined(_MSC_VER) && _MSC_VER >= 1400) + sprintf_s(buf,128,"%08x",nonceCount); +#else + sprintf(buf,"%08x",nonceCount); +#endif + nonceCountString = buf; + } + DebugLog(<< "nonceCount is now: [" << nonceCountString << "]"); +} + + +Auth +Helper::makeChallengeResponseAuth(const SipMessage& request, + const Data& username, + const Data& password, + const Auth& challenge, + const Data& cnonce, + unsigned int& nonceCount, + Data& nonceCountString) +{ + Auth auth; + Data authQop = qopOption(challenge); + if(!authQop.empty()) + { + updateNonceCount(nonceCount, nonceCountString); + } + makeChallengeResponseAuth(request, username, password, challenge, cnonce, authQop, nonceCountString, auth); + return auth; +} + +void +Helper::makeChallengeResponseAuth(const SipMessage& request, + const Data& username, + const Data& password, + const Auth& challenge, + const Data& cnonce, + const Data& authQop, + const Data& nonceCountString, + Auth& auth) +{ + auth.scheme() = Symbols::Digest; + auth.param(p_username) = username; + assert(challenge.exists(p_realm)); + auth.param(p_realm) = challenge.param(p_realm); + assert(challenge.exists(p_nonce)); + auth.param(p_nonce) = challenge.param(p_nonce); + Data digestUri; + { + DataStream s(digestUri); + //s << request.header(h_RequestLine).uri().host(); // wrong + s << request.header(h_RequestLine).uri(); // right + } + auth.param(p_uri) = digestUri; + + if (!authQop.empty()) + { + auth.param(p_response) = Helper::makeResponseMD5(username, + password, + challenge.param(p_realm), + getMethodName(request.header(h_RequestLine).getMethod()), + digestUri, + challenge.param(p_nonce), + authQop, + cnonce, + nonceCountString, + request.getContents()); + auth.param(p_cnonce) = cnonce; + auth.param(p_nc) = nonceCountString; + auth.param(p_qop) = authQop; + } + else + { + assert(challenge.exists(p_realm)); + auth.param(p_response) = Helper::makeResponseMD5(username, + password, + challenge.param(p_realm), + getMethodName(request.header(h_RequestLine).getMethod()), + digestUri, + challenge.param(p_nonce)); + } + + if (challenge.exists(p_algorithm)) + { + auth.param(p_algorithm) = challenge.param(p_algorithm); + } + else + { + auth.param(p_algorithm) = "MD5"; + } + + if (challenge.exists(p_opaque) && challenge.param(p_opaque).size() > 0) + { + auth.param(p_opaque) = challenge.param(p_opaque); + } +} + +// priority-order list of preferred qop tokens +static Data preferredTokens[] = +{ + "auth-int", + "auth" +}; +static size_t pTokenSize=sizeof(preferredTokens)/sizeof(*preferredTokens); +Data +Helper::qopOption(const Auth& challenge) +{ + bool found = false; + size_t index = pTokenSize; + if (challenge.exists(p_qopOptions) && !challenge.param(p_qopOptions).empty()) + { + ParseBuffer pb(challenge.param(p_qopOptions).data(), challenge.param(p_qopOptions).size()); + do + { + const char* anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::COMMA[0]); + Data q; + pb.data(q, anchor); + if (!pb.eof()) + pb.skipChar(); + for (size_t i=0; i < pTokenSize; i++) + { + if (q == preferredTokens[i]) + { + // found a preferred token; is it higher priority? + if (i < index) + { + found = true; + index = i; + } + } + } + } + while(!pb.eof()); + } + + if (found) + return preferredTokens[index]; + + return Data::Empty; + +} + + +Auth +Helper::makeChallengeResponseAuthWithA1(const SipMessage& request, + const Data& username, + const Data& passwordHashA1, + const Auth& challenge, + const Data& cnonce, + unsigned int& nonceCount, + Data& nonceCountString) +{ + Auth auth; + Data authQop = qopOption(challenge); + if(!authQop.empty()) + { + updateNonceCount(nonceCount, nonceCountString); + } + makeChallengeResponseAuthWithA1(request, username, passwordHashA1, challenge, cnonce, authQop, nonceCountString, auth); + return auth; +} + +void +Helper::makeChallengeResponseAuthWithA1(const SipMessage& request, + const Data& username, + const Data& passwordHashA1, + const Auth& challenge, + const Data& cnonce, + const Data& authQop, + const Data& nonceCountString, + Auth& auth) +{ + auth.scheme() = Symbols::Digest; + auth.param(p_username) = username; + assert(challenge.exists(p_realm)); + auth.param(p_realm) = challenge.param(p_realm); + assert(challenge.exists(p_nonce)); + auth.param(p_nonce) = challenge.param(p_nonce); + Data digestUri; + { + DataStream s(digestUri); + //s << request.const_header(h_RequestLine).uri().host(); // wrong + s << request.const_header(h_RequestLine).uri(); // right + } + auth.param(p_uri) = digestUri; + + if (!authQop.empty()) + { + auth.param(p_response) = Helper::makeResponseMD5WithA1(passwordHashA1, + getMethodName(request.header(h_RequestLine).getMethod()), + digestUri, + challenge.param(p_nonce), + authQop, + cnonce, + nonceCountString, + request.getContents()); + auth.param(p_cnonce) = cnonce; + auth.param(p_nc) = nonceCountString; + auth.param(p_qop) = authQop; + } + else + { + assert(challenge.exists(p_realm)); + auth.param(p_response) = Helper::makeResponseMD5WithA1(passwordHashA1, + getMethodName(request.header(h_RequestLine).getMethod()), + digestUri, + challenge.param(p_nonce)); + } + + if (challenge.exists(p_algorithm)) + { + auth.param(p_algorithm) = challenge.param(p_algorithm); + } + else + { + auth.param(p_algorithm) = "MD5"; + } + + if (challenge.exists(p_opaque) && challenge.param(p_opaque).size() > 0) + { + auth.param(p_opaque) = challenge.param(p_opaque); + } +} + +//.dcm. all the auth stuff should be yanked out of helper and +//architected for algorithm independance +bool +Helper::algorithmAndQopSupported(const Auth& challenge) +{ + if ( !(challenge.exists(p_nonce) && challenge.exists(p_realm))) + { + return false; + } + return ((!challenge.exists(p_algorithm) + || isEqualNoCase(challenge.param(p_algorithm), "MD5")) + && (!challenge.exists(p_qop) + || isEqualNoCase(challenge.param(p_qop), Symbols::auth) + || isEqualNoCase(challenge.param(p_qop), Symbols::authInt))); +} + +SipMessage& +Helper::addAuthorization(SipMessage& request, + const SipMessage& challenge, + const Data& username, + const Data& password, + const Data& cnonce, + unsigned int& nonceCount) +{ + Data nonceCountString = Data::Empty; + + assert(challenge.isResponse()); + assert(challenge.header(h_StatusLine).responseCode() == 401 || + challenge.header(h_StatusLine).responseCode() == 407); + + if (challenge.exists(h_ProxyAuthenticates)) + { + const ParserContainer<Auth>& auths = challenge.header(h_ProxyAuthenticates); + for (ParserContainer<Auth>::const_iterator i = auths.begin(); + i != auths.end(); i++) + { + request.header(h_ProxyAuthorizations).push_back(makeChallengeResponseAuth(request, username, password, *i, + cnonce, nonceCount, nonceCountString)); + } + } + if (challenge.exists(h_WWWAuthenticates)) + { + const ParserContainer<Auth>& auths = challenge.header(h_WWWAuthenticates); + for (ParserContainer<Auth>::const_iterator i = auths.begin(); + i != auths.end(); i++) + { + request.header(h_Authorizations).push_back(makeChallengeResponseAuth(request, username, password, *i, + cnonce, nonceCount, nonceCountString)); + } + } + return request; +} + +Uri +Helper::makeUri(const Data& aor, const Data& scheme) +{ + assert(!aor.prefix("sip:")); + assert(!aor.prefix("sips:")); + + Data tmp(aor.size() + scheme.size() + 1, Data::Preallocate); + tmp += scheme; + tmp += Symbols::COLON; + tmp += aor; + Uri uri(tmp); + return uri; +} + +void +Helper::processStrictRoute(SipMessage& request) +{ + if (request.exists(h_Routes) && + !request.const_header(h_Routes).empty() && + !request.const_header(h_Routes).front().uri().exists(p_lr)) + { + // The next hop is a strict router. Move the next hop into the + // Request-URI and move the ultimate destination to the end of the + // route list. Force the message target to be the next hop router. + request.header(h_Routes).push_back(NameAddr(request.const_header(h_RequestLine).uri())); + request.header(h_RequestLine).uri() = request.const_header(h_Routes).front().uri(); + request.header(h_Routes).pop_front(); // !jf! + assert(!request.hasForceTarget()); + request.setForceTarget(request.const_header(h_RequestLine).uri()); + } +} + +void +Helper::massageRoute(const SipMessage& request, NameAddr& rt) +{ + assert(request.isRequest()); + // .bwc. Let's not record-route with a tel uri or something, shall we? + // If the topmost route header is malformed, we can get along without. + if (!request.empty(h_Routes) && + request.header(h_Routes).front().isWellFormed() && + (request.header(h_Routes).front().uri().scheme() == "sip" || + request.header(h_Routes).front().uri().scheme() == "sips" )) + { + rt.uri().scheme() = request.header(h_Routes).front().uri().scheme(); + } + else if(request.header(h_RequestLine).uri().scheme() == "sip" || + request.header(h_RequestLine).uri().scheme() == "sips") + { + rt.uri().scheme() = request.header(h_RequestLine).uri().scheme(); + } + + rt.uri().param(p_lr); +} + +int +Helper::getPortForReply(SipMessage& request) +{ + assert(request.isRequest()); + int port = 0; + if(request.const_header(h_Vias).front().transport() == Symbols::TCP || + request.const_header(h_Vias).front().transport() == Symbols::TLS) + { + // 18.2.2 - bullet 1 and 2 + port = request.getSource().getPort(); + if(port == 0) // .slg. not sure if it makes sense for sourcePort to be 0 + { + port = request.const_header(h_Vias).front().sentPort(); + } + } + else // unreliable transport 18.2.2 bullets 3 and 4 + { + if (request.const_header(h_Vias).front().exists(p_rport)) + { + port = request.getSource().getPort(); + } + else + { + port = request.const_header(h_Vias).front().sentPort(); + } + } + + // If we haven't got a valid port yet, then use the default + if (port <= 0 || port > 65535) + { + if(request.const_header(h_Vias).front().transport() == Symbols::TLS || + request.const_header(h_Vias).front().transport() == Symbols::DTLS) + { + port = Symbols::DefaultSipsPort; + } + else + { + port = Symbols::DefaultSipPort; + } + } + return port; +} + +Uri +Helper::fromAor(const Data& aor, const Data& scheme) +{ + return makeUri(aor, scheme); +} + +bool +Helper::validateMessage(const SipMessage& message,resip::Data* reason) +{ + if (message.empty(h_To) || + message.empty(h_From) || + message.empty(h_CSeq) || + message.empty(h_CallId) || + message.empty(h_Vias) || + message.empty(h_Vias)) + { + InfoLog(<< "Missing mandatory header fields (To, From, CSeq, Call-Id or Via)"); + DebugLog(<< message); + if(reason) *reason="Missing mandatory header field"; + return false; + } + else + { + if(!message.header(h_CSeq).isWellFormed()) + { + InfoLog(<<"Malformed CSeq header"); + if(reason) *reason="Malformed CSeq header"; + return false; + } + + if(!message.header(h_Vias).front().isWellFormed()) + { + InfoLog(<<"Malformed topmost Via header"); + if(reason) *reason="Malformed topmost Via header"; + return false; + } + + if (message.isRequest()) + { + if(!message.header(h_RequestLine).isWellFormed()) + { + InfoLog(<< "Illegal request line"); + if(reason) *reason="Malformed Request Line"; + return false; + } + + if(message.header(h_RequestLine).method()!=message.header(h_CSeq).method()) + { + InfoLog(<< "Method mismatch btw Request Line and CSeq"); + if(reason) *reason="Method mismatch btw Request Line and CSeq"; + return false; + } + } + else + { + if(!message.header(h_StatusLine).isWellFormed()) + { + InfoLog(<< "Malformed status line"); + if(reason) *reason="Malformed status line"; + return false; + } + } + + return true; + } +} + +#if defined(USE_SSL) +#include <openssl/blowfish.h> + +static const Data sep("[]"); +static const Data pad("\0\0\0\0\0\0\0", 7); +static const Data GRUU("_GRUU"); +static const int saltBytes(16); + +Data +Helper::gruuUserPart(const Data& instanceId, + const Data& aor, + const Data& key) +{ + unsigned char ivec[8]; + + ivec[0] = '\x6E'; + ivec[1] = '\xE7'; + ivec[2] = '\xB0'; + ivec[3] = '\x4A'; + ivec[4] = '\x45'; + ivec[5] = '\x93'; + ivec[6] = '\x7D'; + ivec[7] = '\x51'; + + BF_KEY fish; + BF_set_key(&fish, (int)key.size(), (const unsigned char*)key.data()); + + const Data salt(resip::Random::getRandomHex(saltBytes)); + + const Data token(salt + instanceId + sep + aor + '\0' + + pad.substr(0, (8 - ((salt.size() + + instanceId.size() + + sep.size() + 1 + + aor.size() ) % 8)) + % 8)); + auto_ptr <unsigned char> out(new unsigned char[token.size()]); + BF_cbc_encrypt((const unsigned char*)token.data(), + out.get(), + (long)token.size(), + &fish, + ivec, + BF_ENCRYPT); + + return GRUU + Data(out.get(),token.size()).base64encode(true/*safe URL*/); +} + +std::pair<Data,Data> +Helper::fromGruuUserPart(const Data& gruuUserPart, + const Data& key) +{ + unsigned char ivec[8]; + + ivec[0] = '\x6E'; + ivec[1] = '\xE7'; + ivec[2] = '\xB0'; + ivec[3] = '\x4A'; + ivec[4] = '\x45'; + ivec[5] = '\x93'; + ivec[6] = '\x7D'; + ivec[7] = '\x51'; + + static const std::pair<Data, Data> empty; + + if (gruuUserPart.size() < GRUU.size()) + { + return empty; + } + + const Data gruu = gruuUserPart.substr(GRUU.size()); + + BF_KEY fish; + BF_set_key(&fish, (int)key.size(), (const unsigned char*)key.data()); + + const Data decoded = gruu.base64decode(); + + auto_ptr <unsigned char> out(new unsigned char[gruuUserPart.size()+1]); + BF_cbc_encrypt((const unsigned char*)decoded.data(), + out.get(), + (long)decoded.size(), + &fish, + ivec, + BF_DECRYPT); + const Data pair(out.get(), decoded.size()); + + Data::size_type pos = pair.find(sep); + if (pos == Data::npos) + { + return empty; + } + + return std::make_pair(pair.substr(2*saltBytes, pos), // strip out the salt + pair.substr(pos+sep.size())); +} +#endif +Helper::ContentsSecAttrs::ContentsSecAttrs() + : mContents(0), + mAttributes(0) +{} + +Helper::ContentsSecAttrs::ContentsSecAttrs(std::auto_ptr<Contents> contents, + std::auto_ptr<SecurityAttributes> attributes) + : mContents(contents), + mAttributes(attributes) +{} + +// !!bwc!! Yikes! Destructive copy c'tor! Are we _sure_ this is the +// intended behavior? +Helper::ContentsSecAttrs::ContentsSecAttrs(const ContentsSecAttrs& rhs) + : mContents(rhs.mContents), + mAttributes(rhs.mAttributes) +{} + +Helper::ContentsSecAttrs& +Helper::ContentsSecAttrs::operator=(const ContentsSecAttrs& rhs) +{ + if (&rhs != this) + { + // !!bwc!! Yikes! Destructive assignment operator! Are we _sure_ this is + // the intended behavior? + mContents = rhs.mContents; + mAttributes = rhs.mAttributes; + } + return *this; +} + + +Contents* +extractFromPkcs7Recurse(Contents* tree, + const Data& signerAor, + const Data& receiverAor, + SecurityAttributes* attributes, + Security& security) +{ + Pkcs7Contents* pk; + if ((pk = dynamic_cast<Pkcs7Contents*>(tree))) + { + InfoLog( << "GREG1: " << *pk ); +#if defined(USE_SSL) + Contents* contents = security.decrypt(receiverAor, pk); + if (contents) + { + attributes->setEncrypted(); + } + return contents; +#else + return 0; +#endif + } + MultipartSignedContents* mps; + if ((mps = dynamic_cast<MultipartSignedContents*>(tree))) + { + InfoLog( << "GREG2: " << *mps ); +#if defined(USE_SSL) + Data signer; + SignatureStatus sigStatus; + Contents* b = extractFromPkcs7Recurse(security.checkSignature(mps, + &signer, + &sigStatus), + signerAor, + receiverAor, attributes, security); + attributes->setSigner(signer); + attributes->setSignatureStatus(sigStatus); + return b->clone(); +#else + return mps->parts().front()->clone(); +#endif + } + MultipartAlternativeContents* alt; + if ((alt = dynamic_cast<MultipartAlternativeContents*>(tree))) + { + InfoLog( << "GREG3: " << *alt ); + for (MultipartAlternativeContents::Parts::reverse_iterator i = alt->parts().rbegin(); + i != alt->parts().rend(); ++i) + { + Contents* b = extractFromPkcs7Recurse(*i, signerAor, receiverAor, attributes, security); + if (b) + { + return b; + } + } + } + + MultipartMixedContents* mult; + if ((mult = dynamic_cast<MultipartMixedContents*>(tree))) + { + InfoLog( << "GREG4: " << *mult ); + for (MultipartMixedContents::Parts::iterator i = mult->parts().begin(); + i != mult->parts().end(); ++i) + { + Contents* b = extractFromPkcs7Recurse(*i, signerAor, receiverAor, + attributes, security); + if (b) + { + return b; + } + }; + + return 0; + } + + return tree->clone(); +} + +Helper::ContentsSecAttrs +Helper::extractFromPkcs7(const SipMessage& message, + Security& security) +{ + SecurityAttributes* attr = new SecurityAttributes; + // .dlb. currently flattening SecurityAttributes? + //attr->setIdentity(message.getIdentity()); + attr->setIdentity(message.header(h_From).uri().getAor()); + Contents *b = message.getContents(); + if (b) + { + Data fromAor(message.header(h_From).uri().getAor()); + Data toAor(message.header(h_To).uri().getAor()); + if (message.isRequest()) + { + b = extractFromPkcs7Recurse(b, fromAor, toAor, attr, security); + } + else // its a response + { + b = extractFromPkcs7Recurse(b, toAor, fromAor, attr, security); + } + } + std::auto_ptr<Contents> c(b); + std::auto_ptr<SecurityAttributes> a(attr); + return ContentsSecAttrs(c, a); +} + +Helper::FailureMessageEffect +Helper::determineFailureMessageEffect(const SipMessage& response) +{ + assert(response.isResponse()); + int code = response.header(h_StatusLine).statusCode(); + assert(code >= 400); + + switch(code) + { + case 404: + case 410: + case 416: + case 480: // but maybe not, still not quite decided: + case 481: + case 482: // but maybe not, still not quite decided: + case 484: + case 485: + case 502: + case 604: + return DialogTermination; + case 403: + case 489: //only for only subscription + case 408: //again, maybe not. This seems best. + return UsageTermination; + case 400: + case 401: + case 402: + case 405: //doesn't agree w/ -00 of dialogusage + case 406: + case 412: + case 413: + case 414: + case 415: + case 420: + case 421: + case 423: + + case 429: // but if this the refer creating the Subscription, no sub will be created. + case 486: + case 487: + case 488: + case 491: + case 493: + case 494: + case 500: + case 505: + case 513: + case 603: + case 606: + return TransactionTermination; + case 483: // who knows, gravefully terminate or just destroy dialog + case 501: + return ApplicationDependant; + default: + if (code < 600) + { + if (response.exists(h_RetryAfter)) + + { + return RetryAfter; + } + else + { + return OptionalRetryAfter; + } + } + else + { + if (response.exists(h_RetryAfter)) + { + return RetryAfter; + } + else + { + return ApplicationDependant; + } + } + } +} + +SdpContents* getSdpRecurse(Contents* tree) +{ + if (dynamic_cast<SdpContents*>(tree)) + { + return static_cast<SdpContents*>(tree); + } + + MultipartSignedContents* mps; + if ((mps = dynamic_cast<MultipartSignedContents*>(tree))) + { + try + { + MultipartSignedContents::Parts::const_iterator it = mps->parts().begin(); + Contents* contents = getSdpRecurse(*it); + return static_cast<SdpContents*>(contents); + } + catch (ParseException& e) + { + ErrLog(<< e.name() << endl << e.getMessage()); + } + catch (BaseException& e) + { + ErrLog(<< e.name() << endl << e.getMessage()); + } + + return 0; + } + + MultipartAlternativeContents* alt; + if ((alt = dynamic_cast<MultipartAlternativeContents*>(tree))) + { + try + { + for (MultipartAlternativeContents::Parts::reverse_iterator i = alt->parts().rbegin(); + i != alt->parts().rend(); ++i) + { + Contents* contents = getSdpRecurse(*i); + if (contents) + { + return static_cast<SdpContents*>(contents); + } + } + } + catch (ParseException& e) + { + ErrLog(<< e.name() << endl << e.getMessage()); + } + catch (BaseException& e) + { + ErrLog(<< e.name() << endl << e.getMessage()); + } + + return 0; + } + + MultipartMixedContents* mult; + if ((mult = dynamic_cast<MultipartMixedContents*>(tree))) + { + + try + { + for (MultipartMixedContents::Parts::iterator i = mult->parts().begin(); + i != mult->parts().end(); ++i) + { + Contents* contents = getSdpRecurse(*i); + if (contents) + { + return static_cast<SdpContents*>(contents); + } + } + } + catch (ParseException& e) + { + ErrLog(<< e.name() << endl << e.getMessage()); + } + catch (BaseException& e) + { + ErrLog(<< e.name() << endl << e.getMessage()); + } + + return 0; + } + + return 0; +} + +static std::auto_ptr<SdpContents> emptysdp; +auto_ptr<SdpContents> Helper::getSdp(Contents* tree) +{ + if (tree) + { + SdpContents* sdp = getSdpRecurse(tree); + + if (sdp) + { + DebugLog(<< "Got sdp" << endl); + return auto_ptr<SdpContents>(static_cast<SdpContents*>(sdp->clone())); + } + } + + //DebugLog(<< "No sdp" << endl); + return emptysdp; +} + +bool +Helper::isClientBehindNAT(const SipMessage& request, bool privateToPublicOnly) +{ + assert(request.isRequest()); + assert(!request.header(h_Vias).empty()); + + // If received parameter is on top Via, then the source of the message doesn't match + // the address provided in the via. Assume this is because the sender is behind a NAT. + // The assumption here is that this SipStack instance is the first hop in a public SIP server + // architecture, and that clients are directly connected to this instance. + if(request.header(h_Vias).front().exists(p_received)) + { + if(privateToPublicOnly) + { + if(Tuple(request.header(h_Vias).front().sentHost(), 0, UNKNOWN_TRANSPORT).isPrivateAddress() && + !Tuple(request.header(h_Vias).front().param(p_received), 0, UNKNOWN_TRANSPORT).isPrivateAddress()) + { + return true; + } + else + { + return false; + } + } + return true; + } + return false; +} + + +Tuple +Helper::getClientPublicAddress(const SipMessage& request) +{ + assert(request.isRequest()); + assert(!request.header(h_Vias).empty()); + + // Iterate through Via's starting at the bottom (closest to the client). Return the first + // public address found from received parameter if present, or Via host. + Vias::const_iterator it = request.header(h_Vias).end(); + while(true) + { + it--; + if(it->exists(p_received)) + { + // Check IP from received parameter + Tuple address(it->param(p_received), 0, UNKNOWN_TRANSPORT); + if(!address.isPrivateAddress()) + { + address.setPort(it->exists(p_rport) ? it->param(p_rport).port() : it->sentPort()); + address.setType(Tuple::toTransport(it->transport())); + return address; + } + } + + // Check IP from Via sentHost + Tuple address(it->sentHost(), 0, UNKNOWN_TRANSPORT); + if(!address.isPrivateAddress()) + { + address.setPort(it->exists(p_rport) ? it->param(p_rport).port() : it->sentPort()); + address.setType(Tuple::toTransport(it->transport())); + return address; + } + + if(it == request.header(h_Vias).begin()) break; + } + return Tuple(); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Helper.hxx b/src/libs/resiprocate/resip/stack/Helper.hxx new file mode 100644 index 00000000..2a3c7ac1 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Helper.hxx @@ -0,0 +1,636 @@ +#if !defined(RESIP_HELPER_HXX) +#define RESIP_HELPER_HXX + +#include <time.h> + +#include "resip/stack/NonceHelper.hxx" +#include "resip/stack/Symbols.hxx" +#include "resip/stack/Uri.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/Data.hxx" +#include "resip/stack/Contents.hxx" +#include "resip/stack/SecurityAttributes.hxx" +#include "resip/stack/SdpContents.hxx" + +namespace resip +{ + +class SipMessage; +class NameAddr; +class SecurityAttributes; +class Security; + +class UnsupportedAuthenticationScheme : public BaseException +{ + public: + UnsupportedAuthenticationScheme(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) {} + + const char* name() const { return "UnsupportedAuthenticationScheme"; } +}; + + +/** + @ingroup resip_crit + @brief An aggregation of useful static functions. + + These are mostly involved with + - The manufacture of SIP messages (requests and responses). This is of + particular importance to app-writers. + - Digest auth related functions. +*/ +class Helper +{ + public: + + /// bytes in to-tag& from-tag, should prob. live somewhere else + const static int tagSize; + + /** + Used by Registration, Publication and Subscription refreshes, to + calculate the time at which a refresh should be performed (which + is some time, that is a bit smaller than the Expiration interval). + The recommended calculation from the RFC's is the minimnum of the + Exipiration interval less 5 seconds and nine tenths of the exipiration + interval. + */ + template<typename T> + static T aBitSmallerThan(T secs) + { + return resipMax(T(0), resipMin(T(secs-5), T(9*secs/10))); + } + + /** + Converts an interger in a character string containing the + hexidecimal representation of the integer. Note: The + string buffer provided should be at least 8 characters long. + This function will NOT NULL terminate the string. + + @param _d A pointer to the character buffer to write + the hex string + + @param _s The integer value to convert. + + @param _l Boolean flag to include leading 0 zeros or + not. + */ + static void integer2hex(char* _d, unsigned int _s, bool _l = true); + + /** + Converts a character string containing a hexidecimal value + into an unsigned int. Note: Parsing stops after the first + non-hex character, or after 8 characters have been processed. + + @param _s A pointer to the character buffer to convert. + + @returns The integer value of the coverted hex string. + */ + static unsigned int hex2integer(const char* _s); + + /** + Used to jitter the expires in a SUBSCRIBE or REGISTER expires header + + @param input Value to jitter + + @param lowerPercentage The lower range of the random percentage by which + to jitter the value by. + + @param upperPercentage The upper range of the random percentage by which + to jitter the value by. Must be greater than or equal + to lowerPercentage + + @param minimum Only jitter the input if greater than minimum + */ + static int jitterValue(int input, int lowerPercentage, int upperPercentage, int minimum=0); + + /** + Make an invite request - Empty Contact and Via is added and will be populated + by the stack when sent. + + @param target Ends up in the RequestURI and To header + + @param from Ends up in the From header + */ + static SipMessage* makeInvite(const NameAddr& target, const NameAddr& from); + + /** + Make an invite request using a overridden contact header - Empty Via is added + and will be populated by the stack when sent. + + @param target Ends up in the RequestURI and To header + + @param from Ends up in the From header + + @param contact Ends up in the Contact header. Stack will not change this + when sent. + */ + static SipMessage* makeInvite(const NameAddr& target, const NameAddr& from, const NameAddr& contact); + + /** + Make a response to a provided request. Adds a To tag, Contact and Record-Route + headers appropriately. + + @param response SipMessage populated with the appropriate response + + @param request SipMessage request from which to generate the response + + @param responseCode Response code to use on status line. + + @param reason Optional reason string to use on status line. If not provided + then a default reason string will be added for well defined + response codes. + + @param hostname Optional hostname to use in Warning header. Only used if + warning is also provided. + + @param warning Optional warning text. If present a Warning header is added + and hostname is used in warning header. + */ + static void makeResponse(SipMessage& response, + const SipMessage& request, + int responseCode, + const Data& reason = Data::Empty, + const Data& hostname = Data::Empty, + const Data& warning=Data::Empty); + + /** + Make a response to a provided request with an overridden Contact. + Adds a To tag, Contact and Record-Route headers appropriately. + + @param response SipMessage populated with the appropriate response + + @param request SipMessage request from which to generate the response + + @param responseCode Response code to use on status line. + + @param myContact Contact header to add to response. + + @param reason Optional reason string to use on status line. If not provided + then a default reason string will be added for well defined + response codes. + + @param hostname Optional hostname to use in Warning header. Only used if + warning is also provided. + + @param warning Optional warning text. If present a Warning header is added + and hostname is used in warning header. + */ + static void makeResponse(SipMessage& response, + const SipMessage& request, + int responseCode, + const NameAddr& myContact, + const Data& reason = Data::Empty, + const Data& hostname = Data::Empty, + const Data& warning=Data::Empty); + + /** + Make a new response to a provided request. Adds a To tag, Contact and + Record-Route headers appropriately. Caller owns the returned pointer and + is responsible for deleting it. + + @param request SipMessage request from which to generate the response + + @param responseCode Response code to use on status line. + + @param reason Optional reason string to use on status line. If not provided + then a default reason string will be added for well defined + response codes. + + @param hostname Optional hostname to use in Warning header. Only used if + warning is also provided. + + @param warning Optional warning text. If present a Warning header is added + and hostname is used in warning header + + @returns SipMessage populated with the appropriate response. + Caller must deallocate. + */ + static SipMessage* makeResponse(const SipMessage& request, + int responseCode, + const Data& reason = Data::Empty, + const Data& hostname = Data::Empty, + const Data& warning=Data::Empty); + + /** + Make a new response to a provided request with an overridden Contact. + Adds a To tag, Contact and Record-Route headers appropriately. + Caller owns the returned pointer and is responsible for deleting it. + + @param request SipMessage request from which to generate the response + + @param responseCode Response code to use on status line. + + @param myContact Contact header to add to response. + + @param reason Optional reason string to use on status line. If not provided + then a default reason string will be added for well defined + response codes. + + @param hostname Optional hostname to use in Warning header. Only used if + warning is also provided. + + @param warning Optional warning text. If present a Warning header is added + and hostname is used in warning header. + + @returns SipMessage populated with the appropriate response. + Caller must deallocate. + */ + static SipMessage* makeResponse(const SipMessage& request, + int responseCode, + const NameAddr& myContact, + const Data& reason = Data::Empty, + const Data& hostname = Data::Empty, + const Data& warning=Data::Empty); + + static void makeRawResponse(Data& rawBuffer, + const SipMessage& request, + int responseCode, + const Data& additionalHeaders=Data::Empty, + const Data& body=Data::Empty); + + /** + Make a 405 response to a provided request. Allows header is added + with specified methods, or with all methods the stack knows about. + Caller owns the returned pointer and is responsible for deleting it. + + @param request SipMessage request from which to generate the response + + @param allowedMethods Array of integers representing a list of Method + Types to add to the generated Allows header. + See MethodTypes.hxx. + + @param nMethods Number of methods specified in the allowedMethods + integer array. Specify -1 to have this method fill + in the Allows header automatically with each method + supported by the stack. + + @returns SipMessage populated with the appropriate response. + Caller must deallocate. + */ + static SipMessage* make405(const SipMessage& request, + const int* allowedMethods = 0, + int nMethods = -1); + + /** + Returns the default reason string for a particular response code. + + @param responseCode Response code to get reason for + + @param reason Data where the reason string associated with the + responseCode will be set. + */ + static void getResponseCodeReason(int responseCode, Data& reason); + + /** + Make a new request with a overridden Contact. To, maxforward=70, requestline + created, cseq method set, cseq sequence is 1, from and from tag set, contact + set, CallId created. Caller owns the returned pointer and is responsible for + deleting it. + + @note While contact is only necessary for requests that establish a dialog, + those are the requests most likely created by this method, others will + be generated by the dialog. + + @param target Ends up in the RequestURI and To header + + @param from Ends up in the From header + + @param contact Ends up in the Contact header. Stack will not change this + when sent. + + @param method Type of request to create. Methos is used in the Request Line + and the CSeq. + + @returns SipMessage request created. Caller must deallocate. + */ + static SipMessage* makeRequest(const NameAddr& target, const NameAddr& from, const NameAddr& contact, MethodTypes method); + + /** + Make a new request. To, maxforward=70, requestline created, cseq method set, + cseq sequence is 1, from and from tag set, CallId created. Caller owns the + returned pointer and is responsible for deleting it. + + @note An empty contact header is added. This signals to the stack that it + should be populated by the transports when sent. + + @param target Ends up in the RequestURI and To header + + @param from Ends up in the From header + + @param method Type of request to create. Methos is used in the Request Line + and the CSeq. + + @returns SipMessage request created. Caller must deallocate. + */ + static SipMessage* makeRequest(const NameAddr& target, const NameAddr& from, MethodTypes method); + + /** + Make a new Cancel request for the specified request. Caller owns the + returned pointer and is responsible for deleting it. + + @param request Request for which the Cancel will apply. ie. Invite request. + + @returns Created Cancel request. Caller must deallocate. + */ + static SipMessage* makeCancel(const SipMessage& request); + + /// Create a Register request with an overriden Contact. See makeRequest. + static SipMessage* makeRegister(const NameAddr& to, const NameAddr& from, const NameAddr& contact); + + /// Create a Register request with an empty Contact. See makeRequest. + static SipMessage* makeRegister(const NameAddr& to, const NameAddr& from); + + /// Create a Register request with an overriden Contact, transport is added to Request URI. See makeRequest. + static SipMessage* makeRegister(const NameAddr& to, const Data& transport, const NameAddr& contact); + + /// Create a Register request with an empty Contact, transport is added to Request URI. See makeRequest. + static SipMessage* makeRegister(const NameAddr& to, const Data& transport); + + /// Create a Subscribe request with an overriden Contact. See makeRequest. + static SipMessage* makeSubscribe(const NameAddr& target, const NameAddr& from, const NameAddr& contact); + + /// Create a Subscribe request with an empty Contact. See makeRequest. + static SipMessage* makeSubscribe(const NameAddr& target, const NameAddr& from); + + /// Create a Message request with an overriden Contact. See makeRequest. + static SipMessage* makeMessage(const NameAddr& target, const NameAddr& from, const NameAddr& contact); + + /// Create a Message request with an empty Contact. See makeRequest. + static SipMessage* makeMessage(const NameAddr& target, const NameAddr& from); + + /// Create a Publish request with an overriden Contact. See makeRequest. + static SipMessage* makePublish(const NameAddr& target, const NameAddr& from, const NameAddr& contact); + + /// Create a Publish request with an empty Contact. See makeRequest. + static SipMessage* makePublish(const NameAddr& target, const NameAddr& from); + + /** + This interface should be used by the stack (TransactionState) to create an + AckMsg to a failure response. See RFC3261 section 17.1.1.3. Caller owns the + returned pointer and is responsible for deleting it. + + @note The branch in this ACK needs to be the one from the request. + For TU generated ACK, see Dialog::makeAck(...) + + @param request Request that this ACK applies to. + + @param response Response that we are ACKing - required so that we can get the To tag + into the generated ACK. + + @returns Created Ack request. Caller must deallocate. + */ + static SipMessage* makeFailureAck(const SipMessage& request, const SipMessage& response); + + /** + Creates and returns a unique branch parameter. Generated branch will contain + the RFC3261 magic cookie + 4 randome hex characters + "C1" + 2 random hex characters. + + @deprecated Not used by stack. + */ + static Data computeUniqueBranch(); + static Data computeProxyBranch(const SipMessage& request); + + static Data computeCallId(); + static Data computeTag(int numBytes); + + enum AuthResult {Failed = 1, Authenticated, Expired, BadlyFormed}; + + static AuthResult authenticateRequest(const SipMessage& request, + const Data& realm, + const Data& password, + int expiresDelta = 0); + + static AuthResult authenticateRequestWithA1(const SipMessage& request, + const Data& realm, + const Data& hA1, + int expiresDelta = 0); + + static std::pair<AuthResult,Data> + advancedAuthenticateRequest(const SipMessage& request, + const Data& realm, + const Data& a1, + int expiresDelta = 0, + bool proxyAuthorization = true); + + // create a 407 response with Proxy-Authenticate header filled in + static SipMessage* makeProxyChallenge(const SipMessage& request, + const Data& realm, + bool useAuth = true, + bool stale = false); + + //create a 401 response with WWW-Authenticate header filled in + static SipMessage* makeWWWChallenge(const SipMessage& request, + const Data& realm, + bool useAuth = true, + bool stale = false); + + // create a 401 or 407 response with Proxy-Authenticate or Authenticate header + // filled in + static SipMessage* makeChallenge(const SipMessage& request, + const Data& realm, + bool useAuth = true, + bool stale = false, + bool proxy = false); + + static Data qopOption(const Auth& challenge); + static void updateNonceCount(unsigned int& nonceCount, Data& nonceCountString); + static bool algorithmAndQopSupported(const Auth& challenge); + + + // adds authorization headers in reponse to the 401 or 407--currently + // only supports md5. + static SipMessage& addAuthorization(SipMessage& request, + const SipMessage& challenge, + const Data& username, + const Data& password, + const Data& cnonce, + unsigned int& nonceCount); + + static Auth makeChallengeResponseAuth(const SipMessage& request, + const Data& username, + const Data& password, + const Auth& challenge, + const Data& cnonce, + unsigned int& nonceCount, + Data& nonceCountString); + + static void makeChallengeResponseAuth(const SipMessage& request, + const Data& username, + const Data& password, + const Auth& challenge, + const Data& cnonce, + const Data& authQop, + const Data& nonceCountString, + Auth& auth); + + static Auth makeChallengeResponseAuthWithA1(const SipMessage& request, + const Data& username, + const Data& passwordHashA1, + const Auth& challenge, + const Data& cnonce, + unsigned int& nonceCount, + Data& nonceCountString); + + static void makeChallengeResponseAuthWithA1(const SipMessage& request, + const Data& username, + const Data& passwordHashA1, + const Auth& challenge, + const Data& cnonce, + const Data& authQop, + const Data& nonceCountString, + Auth& auth); + + static Data makeResponseMD5WithA1(const Data& a1, + const Data& method, const Data& digestUri, const Data& nonce, + const Data& qop = Data::Empty, const Data& cnonce = Data::Empty, + const Data& cnonceCount = Data::Empty, const Contents *entityBody = 0); + + static Data makeResponseMD5(const Data& username, const Data& password, const Data& realm, + const Data& method, const Data& digestUri, const Data& nonce, + const Data& qop = Data::Empty, const Data& cnonce = Data::Empty, + const Data& cnonceCount = Data::Empty, const Contents *entityBody = 0); + + /// Note: Helper assumes control of NonceHelper object and will delete when global scope is cleaned up + static void setNonceHelper(NonceHelper *nonceHelper); + static NonceHelper* getNonceHelper(); + static Data makeNonce(const SipMessage& request, const Data& timestamp); + + static Uri makeUri(const Data& aor, const Data& scheme=Symbols::DefaultSipScheme); + + static void processStrictRoute(SipMessage& request); + + // return the port that the response should be sent to using rules from + // RFC 3261 - 18.2.2 + static int getPortForReply(SipMessage& request); + + static void massageRoute(const SipMessage& request, NameAddr& route); + + static Uri fromAor(const Data& aor, const Data& scheme=Symbols::DefaultSipScheme); + + // Do basic checks to validate a received message off the wire + // If the basic check fails, and reason is non-null, reason will be set + // to the reason the check failed. This function does not take ownership + // of reason. + static bool validateMessage(const SipMessage& message,resip::Data* reason=0); + + // GRUU support -- reversibly and opaquely combine instance id and aor + static Data gruuUserPart(const Data& instanceId, + const Data& aor, + const Data& key); + + // GRUU support -- extract instance id and aor from user portion + static std::pair<Data,Data> fromGruuUserPart(const Data& gruuUserPart, + const Data& key); + + struct ContentsSecAttrs + { + ContentsSecAttrs(); + ContentsSecAttrs(std::auto_ptr<Contents> contents, + std::auto_ptr<SecurityAttributes> attributes); + ContentsSecAttrs(const ContentsSecAttrs& rhs); + ContentsSecAttrs& operator=(const ContentsSecAttrs& rhs); + mutable std::auto_ptr<Contents> mContents; + mutable std::auto_ptr<SecurityAttributes> mAttributes; + }; + + static ContentsSecAttrs extractFromPkcs7(const SipMessage& message, Security& security); + + + enum FailureMessageEffect{ DialogTermination, TransactionTermination, UsageTermination, + RetryAfter, OptionalRetryAfter, ApplicationDependant }; + + static FailureMessageEffect determineFailureMessageEffect(const SipMessage& response); + + // Just simply walk the contents tree and return the first SdpContents in + // the tree. + static std::auto_ptr<SdpContents> getSdp(Contents* tree); + + /** Looks at SIP headers and message source for a mismatch to make an + assumption that the sender is behind a NAT device. + + @param request Request message that we use for checking. + + @privateToPublicOnly If enabled then we ensure that the via is private + address and that the source was a public address. + This allows us to ignore cases of private-private NAT'ing + or false detections, when a server behind a load balancer + is sending us requests and using the load balancer address + in the Via, instead of the real of the adapter. + */ + static bool isClientBehindNAT(const SipMessage& request, bool privateToPublicOnly=true); + + /** Look at Via headers, and find the first public IP address closest to the sending + client. + + @param request Request message that we use for checking. + + @note If no public IP's are found, then an empty Tuple is returned. This + can be tested by checking if Tuple::getType() returns UNKNOWN_TRANSPORT. + */ + static Tuple getClientPublicAddress(const SipMessage& request); + + private: + class NonceHelperPtr + { + public: + NonceHelperPtr() : mNonceHelper(0) {} + ~NonceHelperPtr() { delete mNonceHelper; } + NonceHelper *mNonceHelper; + }; + static NonceHelperPtr mNonceHelperPtr; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/IntegerCategory.cxx b/src/libs/resiprocate/resip/stack/IntegerCategory.cxx new file mode 100644 index 00000000..e02df449 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/IntegerCategory.cxx @@ -0,0 +1,179 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/IntegerCategory.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// Integer: +//==================== +IntegerCategory::IntegerCategory() + : ParserCategory(), + mValue(0), + mComment() +{} + +IntegerCategory::IntegerCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), + mValue(0), + mComment() +{} + +IntegerCategory::IntegerCategory(const IntegerCategory& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mValue(rhs.mValue), + mComment(rhs.mComment) +{} + +IntegerCategory& +IntegerCategory::operator=(const IntegerCategory& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mValue = rhs.mValue; + mComment = rhs.mComment; + } + return *this; +} + +ParserCategory* IntegerCategory::clone() const +{ + return new IntegerCategory(*this); +} + +ParserCategory* IntegerCategory::clone(void* location) const +{ + return new (location) IntegerCategory(*this); +} + +ParserCategory* +IntegerCategory::clone(PoolBase* pool) const +{ + return new (pool) IntegerCategory(*this, pool); +} + +int IntegerCategory::value() const +{ + checkParsed(); + return mValue; +} + +const Data& +IntegerCategory::comment() const +{ + checkParsed(); + return mComment; +} + +int& IntegerCategory::value() +{ + checkParsed(); + return mValue; +} + +Data& +IntegerCategory::comment() +{ + checkParsed(); + return mComment; +} + + +void +IntegerCategory::parse(ParseBuffer& pb) +{ + const char* start = pb.skipWhitespace(); + mValue = pb.integer(); + pb.skipToChar('('); + if (!pb.eof()) + { + start = pb.skipChar(); + pb.skipToEndQuote(')'); + pb.data(mComment, start); + pb.skipChar(); + } + else + { + pb.reset(start); + start = pb.skipNonWhitespace(); + } + + parseParameters(pb); +} + +EncodeStream& +IntegerCategory::encodeParsed(EncodeStream& str) const +{ + str << mValue; + + if (!mComment.empty()) + { + str << "(" << mComment << ")"; + } + + encodeParameters(str); + return str; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/IntegerCategory.hxx b/src/libs/resiprocate/resip/stack/IntegerCategory.hxx new file mode 100644 index 00000000..343ff08c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/IntegerCategory.hxx @@ -0,0 +1,96 @@ +#if !defined(RESIP_INTEGER_CATEGORY_HXX) +#define RESIP_INTEGER_CATEGORY_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" + +namespace resip +{ + +/** + @deprecated Use UInt32Category instead. + @brief Represents a numeric-with-comment header field value. +*/ +class IntegerCategory : public ParserCategory +{ + public: + enum {commaHandling = NoCommaTokenizing}; + + IntegerCategory(); + IntegerCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + IntegerCategory(const IntegerCategory& orig, + PoolBase* pool=0); + IntegerCategory& operator=(const IntegerCategory&); + + virtual void parse(ParseBuffer& pb); + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + + int value() const; + int& value(); + Data& comment(); + const Data& comment() const; + + private: + int mValue; + Data mComment; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/IntegerParameter.cxx b/src/libs/resiprocate/resip/stack/IntegerParameter.cxx new file mode 100644 index 00000000..096ea5a4 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/IntegerParameter.cxx @@ -0,0 +1,114 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/IntegerParameter.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +IntegerParameter::IntegerParameter(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators) + : Parameter(type), + mValue(0) +{ + pb.skipWhitespace(); + pb.skipChar(Symbols::EQUALS[0]); + pb.skipWhitespace(); + pb.assertNotEof(); + + // hack to allow expires to have an 2543 style quoted Date + if (type == ParameterTypes::expires) + { + try + { + mValue = pb.integer(); + } + catch (ParseException&) + { + mValue = 3600; + pb.skipToOneOf(ParseBuffer::ParamTerm); + } + + if(mValue < 0) + { + mValue = 3600; + } + } + else + { + mValue = pb.integer(); + } +} + +IntegerParameter::IntegerParameter(ParameterTypes::Type type, int value) + : Parameter(type), + mValue(value) +{} + +Parameter* +IntegerParameter::clone() const +{ + return new IntegerParameter(*this); +} + +EncodeStream& +IntegerParameter::encode(EncodeStream& stream) const +{ + return stream << getName() << Symbols::EQUALS << mValue; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/IntegerParameter.hxx b/src/libs/resiprocate/resip/stack/IntegerParameter.hxx new file mode 100644 index 00000000..de1d1934 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/IntegerParameter.hxx @@ -0,0 +1,99 @@ +#if !defined(RESIP_INTEGERPARAMETER_HXX) +#define RESIP_INTEGERPARAMETER_HXX + +#include "resip/stack/ParameterTypeEnums.hxx" +#include "resip/stack/Parameter.hxx" +#include "rutil/PoolBase.hxx" +#include <iosfwd> + +namespace resip +{ + +class ParseBuffer; + +/** + @ingroup sip_grammar + + @brief Generically represents integer values conveyed by SIP + parameters. +*/ +class IntegerParameter : public Parameter +{ + public: + typedef int Type; + + IntegerParameter(ParameterTypes::Type, ParseBuffer& pb, const std::bitset<256>& terminators); + explicit IntegerParameter(ParameterTypes::Type type, int value = -666999666); + + static Parameter* decode(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators, + PoolBase* pool) + { + return new (pool) IntegerParameter(type, pb, terminators); + } + + virtual EncodeStream& encode(EncodeStream& stream) const; + + virtual Parameter* clone() const; + private: + friend class ParserCategory; + friend class Uri; + Type& value() {return mValue;} + + int mValue; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/InternalTransport.cxx b/src/libs/resiprocate/resip/stack/InternalTransport.cxx new file mode 100644 index 00000000..2b94a706 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/InternalTransport.cxx @@ -0,0 +1,269 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <iostream> + +#if defined(HAVE_SYS_SOCKIO_H) +#include <sys/sockio.h> +#endif + +#include "resip/stack/Helper.hxx" +#include "resip/stack/InternalTransport.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + + +InternalTransport::InternalTransport(Fifo<TransactionMessage>& rxFifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + AfterSocketCreationFuncPtr socketFunc, + Compression &compression, + unsigned transportFlags) : + Transport(rxFifo, portNum, version, interfaceObj, Data::Empty, + socketFunc, compression, transportFlags), + mFd(INVALID_SOCKET), + mInterruptorHandle(0), + mTxFifoOutBuffer(mTxFifo), + mPollGrp(NULL), + mPollItemHandle(NULL), + mTransportLogger(NULL) +{} + +InternalTransport::~InternalTransport() +{ + if (mPollItemHandle && mPollGrp) + mPollGrp->delPollItem(mPollItemHandle); + if (mInterruptorHandle && mPollGrp) + mPollGrp->delPollItem(mInterruptorHandle); + + if (mFd != INVALID_SOCKET) + { + //DebugLog (<< "Closing " << mFd); + closeSocket(mFd); + } + mFd = -2; + if(!mTxFifo.empty()) + { + WarningLog(<< "TX Fifo non-empty in ~InternalTransport! Has " << mTxFifo.size() << " messages."); + } +} + +bool +InternalTransport::isFinished() const +{ + return !mTxFifoOutBuffer.messageAvailable(); +} + +Socket +InternalTransport::socket(TransportType type, IpVersion ipVer) +{ + Socket fd; + switch (type) + { + case UDP: +#ifdef USE_IPV6 + fd = ::socket(ipVer == V4 ? PF_INET : PF_INET6, SOCK_DGRAM, IPPROTO_UDP); +#else + fd = ::socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); +#endif + break; + case TCP: + case TLS: +#ifdef USE_IPV6 + fd = ::socket(ipVer == V4 ? PF_INET : PF_INET6, SOCK_STREAM, 0); +#else + fd = ::socket(PF_INET, SOCK_STREAM, 0); +#endif + break; + default: + InfoLog (<< "Try to create an unsupported socket type: " << Tuple::toData(type)); + assert(0); + throw Transport::Exception("Unsupported transport", __FILE__,__LINE__); + } + + if ( fd == INVALID_SOCKET ) + { + int e = getErrno(); + ErrLog (<< "Failed to create socket: " << strerror(e)); + throw Transport::Exception("Can't create TcpBaseTransport", __FILE__,__LINE__); + } + + DebugLog (<< "Creating fd=" << fd << (ipVer == V4 ? " V4/" : " V6/") << (type == UDP ? "UDP" : "TCP")); + + return fd; +} + +void +InternalTransport::bind() +{ + DebugLog (<< "Binding to " << Tuple::inet_ntop(mTuple)); + + if ( ::bind( mFd, &mTuple.getMutableSockaddr(), mTuple.length()) == SOCKET_ERROR ) + { + int e = getErrno(); + if ( e == EADDRINUSE ) + { + error(e); + ErrLog (<< mTuple << " already in use "); + throw Transport::Exception("port already in use", __FILE__,__LINE__); + } + else + { + error(e); + ErrLog (<< "Could not bind to " << mTuple); + throw Transport::Exception("Could not use port", __FILE__,__LINE__); + } + } + + // If we bound to port 0, then query OS for assigned port number + if(mTuple.getPort() == 0) + { + socklen_t len = mTuple.isV4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6); + if(::getsockname(mFd, &mTuple.getMutableSockaddr(), &len) == SOCKET_ERROR) + { + int e = getErrno(); + ErrLog (<<"getsockname failed, error=" << e); + throw Transport::Exception("Could not query port", __FILE__,__LINE__); + } + } + + bool ok = makeSocketNonBlocking(mFd); + if ( !ok ) + { + ErrLog (<< "Could not make socket non-blocking " << port()); + throw Transport::Exception("Failed making socket non-blocking", __FILE__,__LINE__); + } + + if (mSocketFunc) + { + mSocketFunc(mFd, transport(), __FILE__, __LINE__); + } +} + +unsigned int +InternalTransport::getFifoSize() const +{ + return mTxFifo.size(); +} + +bool +InternalTransport::hasDataToSend() const +{ + return mTxFifoOutBuffer.messageAvailable(); +} + +void +InternalTransport::send(std::auto_ptr<SendData> data) +{ + mTxFifo.add(data.release()); +} + +void +InternalTransport::setTransportLogger(TransportLogger* logger) +{ + mTransportLogger = logger; +} + + +void +InternalTransport::setPollGrp(FdPollGrp *grp) +{ + if(!shareStackProcessAndSelect()) + { + // If this transport does not have its own thread, it does not need to + // register its SelectInterruptor because the TransportSelector will take + // care of interrupting the select()/epoll() loop when necessary. + if(mPollGrp && mInterruptorHandle) + { + mPollGrp->delPollItem(mInterruptorHandle); + mInterruptorHandle=0; + } + + if (grp) + { + mInterruptorHandle = grp->addPollItem(mSelectInterruptor.getReadSocket(), FPEM_Read, &mSelectInterruptor); + } + } + + mPollGrp = grp; +} + +void +InternalTransport::poke() +{ + // !bwc! I have tried installing mSelectInterruptor in mTxFifo, but it + // hampers performance. This seems to be because we get a significant + // performance boost from having multiple messages added to mTxFifo before + // mSelectInterruptor is invoked (this is what the TransactionController + // does; it processes at most 16 TransactionMessages, and then pokes the + // Transports). Once we have buffered producer queues in place, this + // performance concern will be rendered moot, and we'll be able to install + // the interruptor in mTxFifo. + if(mTxFifoOutBuffer.messageAvailable()) + { + // This will interrupt the select statement and cause processing of + // this new outgoing message. + mSelectInterruptor.handleProcessNotification(); + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/InternalTransport.hxx b/src/libs/resiprocate/resip/stack/InternalTransport.hxx new file mode 100644 index 00000000..bbe8a178 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/InternalTransport.hxx @@ -0,0 +1,170 @@ +#if !defined(RESIP_INTERNAL_TRANSPORT_HXX) +#define RESIP_INTERNAL_TRANSPORT_HXX + +#include <exception> + +#include "rutil/BaseException.hxx" +#include "rutil/ConsumerFifoBuffer.hxx" +#include "rutil/Data.hxx" +#include "rutil/Fifo.hxx" +#include "rutil/Socket.hxx" +#include "rutil/FdPoll.hxx" +#include "resip/stack/Message.hxx" +#include "resip/stack/Transport.hxx" +#include "resip/stack/Tuple.hxx" +#include "resip/stack/SendData.hxx" +#include "resip/stack/Compression.hxx" +#include "rutil/SelectInterruptor.hxx" + +namespace resip +{ + +class TransactionMessage; +class SipMessage; +class Connection; +class FdPollGrp; + +/** + @internal +*/ +class InternalTransport : public Transport +{ +friend class ConnectionBase; +public: + class TransportLogger + { + public: + enum + { + Flow_Received, + Flow_Sent + }; + virtual void onSipMessage(int flow, const char* msg, unsigned int length, const sockaddr* addr, unsigned int addrlen) = 0; + }; + +public: + // sendHost what to put in the Via:sent-by + // portNum is the port to receive and/or send on + InternalTransport(Fifo<TransactionMessage>& rxFifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + AfterSocketCreationFuncPtr socketFunc = 0, + Compression &compression = Compression::Disabled, + unsigned transportFlags = 0); + + virtual ~InternalTransport(); + + virtual bool isFinished() const; + virtual bool hasDataToSend() const; + + virtual bool shareStackProcessAndSelect() const + { return !(mTransportFlags & RESIP_TRANSPORT_FLAG_OWNTHREAD); } + + // No-op, even if this Transport is marked as having its own thread. It is the + // responsibility of the app-writer to ensure that a TransportThread is + // created for this Transport, and run it. + virtual void startOwnProcessing() {} + + // shared by UDP, TCP, and TLS + static Socket socket(TransportType type, IpVersion ipVer); + void bind(); + + //used for epoll + virtual void setPollGrp(FdPollGrp *grp); + + // used for statistics + virtual unsigned int getFifoSize() const; + virtual void send(std::auto_ptr<SendData> data); + virtual void poke(); + + // .bwc. This needs to be overridden if this transport runs in its own + // thread to be threadsafe. + virtual void setCongestionManager(CongestionManager* manager) + { + if(mCongestionManager) + { + mCongestionManager->unregisterFifo(&mTxFifo); + } + Transport::setCongestionManager(manager); + if(mCongestionManager) + { + mCongestionManager->registerFifo(&mTxFifo); + } + } + void setTransportLogger(TransportLogger* logger); + protected: + friend class SipStack; + + Socket mFd; // this is a unix file descriptor or a windows SOCKET + + // .bwc. We use this to interrupt the select call when our tx fifo goes + // from empty to non-empty; if the fifo is empty when we build our fd set, + // we will add the read end of this pipe to the fd set, and when a message + // is added, we will write something to the write end. + SelectInterruptor mSelectInterruptor; + FdPollItemHandle mInterruptorHandle; + + Fifo<SendData> mTxFifo; // owned by the transport + ConsumerFifoBuffer<SendData> mTxFifoOutBuffer; + FdPollGrp *mPollGrp; // not owned by transport, just used + // FdPollItemIf *mPollItem; // owned by the transport + FdPollItemHandle mPollItemHandle; // owned by the transport + TransportLogger* mTransportLogger; +}; + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/InteropHelper.cxx b/src/libs/resiprocate/resip/stack/InteropHelper.cxx new file mode 100644 index 00000000..3a8cbf53 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/InteropHelper.cxx @@ -0,0 +1,63 @@ +#include "resip/stack/InteropHelper.hxx" + +namespace resip +{ +int InteropHelper::theOutboundVersion=11; +bool InteropHelper::isOutboundSupported=true; +unsigned int InteropHelper::flowTimerSeconds=0; // 0 = disabled +unsigned int InteropHelper::flowTimerGracePeriodSeconds=30; +bool InteropHelper::useRRTokenHack=false; +InteropHelper::ClientNATDetectionMode InteropHelper::clientNATDetection=InteropHelper::ClientNATDetectionDisabled; +bool InteropHelper::assumeFirstHopSupportsOutbound=false; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/stack/InteropHelper.hxx b/src/libs/resiprocate/resip/stack/InteropHelper.hxx new file mode 100644 index 00000000..edf8224f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/InteropHelper.hxx @@ -0,0 +1,139 @@ +#ifndef INTEROP_HELPER_HXX +#define INTEROP_HELPER_HXX + +namespace resip +{ + +/** + This class is intended to encapsulate what version/s of various drafts are + supported by the stack. This also allows for configurable version support at + runtime. +*/ +class InteropHelper +{ + public: + static int getOutboundVersion() {return theOutboundVersion;} + static void setOutboundVersion(int version) {theOutboundVersion=version;} + static bool getOutboundSupported() {return isOutboundSupported;} + static void setOutboundSupported(bool supported) {isOutboundSupported=supported;} + + // If this value is set, then DUM/repro will populate a Flow-Timer header in a + // successful registration reponse + static unsigned int getFlowTimerSeconds() {return flowTimerSeconds;} + static void setFlowTimerSeconds(unsigned int seconds) {flowTimerSeconds=seconds;} + + // Only relevant if setFlowTimerSeconds is set to value greater than 0. + // Specifies the amount of time beyond the FlowTimer time, before the stack + // will consider any Flow-Timer based connection to be in a bad state. This + // is used by the ConnectionManager garbage collection logic to cleanup + // flow-timer based connections for which we are no-longer receiving keepalives. + static unsigned int getFlowTimerGracePeriodSeconds() {return flowTimerGracePeriodSeconds;} + static void setFlowTimerGracePeriodSeconds(unsigned int seconds) {flowTimerGracePeriodSeconds=seconds;} + + // .bwc. If this is enabled, we will record-route with flow tokens + // whenever possible. This will make things work with endpoints that don't + // use NAT traversal tricks. However, this will break several things: + // 1) Target-refreshes won't work. + // 2) Proxies that do not record-route may be implicitly included in the + // route-set by this proxy, because a flow token may point to them. + // 3) Third-party registrations won't work. + static bool getRRTokenHackEnabled(){return useRRTokenHack;} + static void setRRTokenHackEnabled(bool enabled) {useRRTokenHack=enabled;} + + enum ClientNATDetectionMode + { + ClientNATDetectionDisabled, + ClientNATDetectionEnabled, + ClientNATDetectionPrivateToPublicOnly + }; + + // If this is enabled, and we have clients not explicitly supporting outbound + // that we detect to be behind a NAT device, we will record-route with flow tokens + // whenever possible. However, this will break several things: + // 1) Target-refreshes won't work. + // 2) Proxies that do not record-route may be implicitly included in the + // route-set by this proxy, because a flow token may point to them. + // 3) Third-party registrations won't work. + static InteropHelper::ClientNATDetectionMode getClientNATDetectionMode(){return clientNATDetection;} + static void setClientNATDetectionMode(InteropHelper::ClientNATDetectionMode mode) {clientNATDetection=mode;} + + // There are cases where the first hop in a particular network supports the concept of outbound + // and ensures all messaging for a client is delivered over the same connection used for + // registration. This could be a SBC or other NAT traversal aid router that uses the Path + // header. However such endpoints may not be 100% compliant with outbound RFC and may not + // include a ;ob parameter in the path header. This parameter is required in order for repro + // to have knowledge that the first hop does support outbound, and it will reject registrations + // that appear to be using outboud (ie. instanceId and regId) with a 439 (First Hop Lacks Outbound + // Support). In this case it can be desirable when using repro as the registrar to not reject + // REGISTRATION requests that contain an instanceId and regId with a 439. + // If this setting is enabled, then repro will assume the first hop supports outbound + // and not return this error. + static bool getAssumeFirstHopSupportsOutboundEnabled(){return assumeFirstHopSupportsOutbound;} + static void setAssumeFirstHopSupportsOutboundEnabled(bool enabled) {assumeFirstHopSupportsOutbound=enabled;} + + private: + InteropHelper(); + ~InteropHelper(); + + static int theOutboundVersion; + static bool isOutboundSupported; + static unsigned int flowTimerSeconds; + static unsigned int flowTimerGracePeriodSeconds; + static bool useRRTokenHack; + static ClientNATDetectionMode clientNATDetection; + static bool assumeFirstHopSupportsOutbound; +}; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/stack/InterruptableStackThread.cxx b/src/libs/resiprocate/resip/stack/InterruptableStackThread.cxx new file mode 100644 index 00000000..e75bb167 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/InterruptableStackThread.cxx @@ -0,0 +1,125 @@ +#include "resip/stack/InterruptableStackThread.hxx" +#include "resip/stack/SipStack.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/SelectInterruptor.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +using namespace resip; + +InterruptableStackThread::InterruptableStackThread(SipStack& stack, SelectInterruptor& si) + : mStack(stack), + mSelectInterruptor(si) +{} + +InterruptableStackThread::~InterruptableStackThread() +{ + //InfoLog (<< "InterruptableStackThread::~InterruptableStackThread()"); +} + +void +InterruptableStackThread::thread() +{ + while (!isShutdown()) + { + try + { + FdSet fdset; + mStack.process(fdset); // .dcm. reqd to get send requests queued at transports + mSelectInterruptor.buildFdSet(fdset); + mStack.buildFdSet(fdset); + buildFdSet(fdset); + int ret = fdset.selectMilliSeconds(resipMin(mStack.getTimeTillNextProcessMS(), + getTimeTillNextProcessMS())); + if (ret >= 0) + { + // .dlb. use return value to peak at the message to see if it is a + // shutdown, and call shutdown if it is + // .dcm. how will this interact w/ TuSelector? + mSelectInterruptor.process(fdset); + mStack.process(fdset); + process(fdset); + } + } + catch (BaseException& e) + { + ErrLog (<< "Unhandled exception: " << e); + } + } + InfoLog (<< "Shutting down stack thread"); +} + +void +InterruptableStackThread::shutdown() +{ + ThreadIf::shutdown(); + mSelectInterruptor.interrupt(); +} + +void +InterruptableStackThread::buildFdSet(FdSet& fdset) +{ +} + +unsigned int +InterruptableStackThread::getTimeTillNextProcessMS() const +{ + //.dcm. --- eventually make infinite + return 10000; +} + +void +InterruptableStackThread::process(FdSet& fdset) +{ +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/InterruptableStackThread.hxx b/src/libs/resiprocate/resip/stack/InterruptableStackThread.hxx new file mode 100644 index 00000000..ebd730e9 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/InterruptableStackThread.hxx @@ -0,0 +1,100 @@ +#ifndef RESIP_InterruptableStackThread__hxx +#define RESIP_InterruptableStackThread__hxx + +#include "rutil/ThreadIf.hxx" +#include "rutil/Socket.hxx" + +namespace resip +{ + +class SipStack; +class SelectInterruptor; + +/** + This class is used to create a thread to run the SipStack in. The + thread provides cycles to the SipStack by calling process. Process + is called when select returns a signaled file descriptor. + + This implementation improves on StackThread, by providing a fully + blocking architecture (ie. no need to wake up every 25ms), since + posting to TransactionState will cause the SelectInterruptor to + be invoked. + + You must register SelectInterrupter as an AsyncProcessHandler on the + SipStack in order to use this class. This is done by providing + SelectInterrupter to the constructor of SipStack. This should be + the same SelectInterrupter provided when constructing this class. +*/ +class InterruptableStackThread : public ThreadIf +{ + public: + InterruptableStackThread(SipStack& stack, SelectInterruptor& si); + virtual ~InterruptableStackThread(); + + virtual void thread(); + virtual void shutdown(); + + protected: + virtual void buildFdSet(FdSet& fdset); + virtual unsigned int getTimeTillNextProcessMS() const; + virtual void process(FdSet& fdset); + + private: + SipStack& mStack; + SelectInterruptor& mSelectInterruptor; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/InvalidContents.cxx b/src/libs/resiprocate/resip/stack/InvalidContents.cxx new file mode 100644 index 00000000..c5c7c638 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/InvalidContents.cxx @@ -0,0 +1,140 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/InvalidContents.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +InvalidContents::InvalidContents(const Data& txt, const Mime& originalType) + : Contents(getStaticType()), + mOriginalType(originalType), + mText(txt) +{} + +InvalidContents::InvalidContents(const HeaderFieldValue& hfv, const Mime& contentsType, const Mime& originalType) + : Contents(hfv, contentsType), + mOriginalType(originalType), + mText() +{ +} + +InvalidContents::InvalidContents(const Data& txt, const Mime& contentsType, const Mime& originalType) + : Contents(contentsType), + mOriginalType(originalType), + mText(txt) +{ +} + +InvalidContents::InvalidContents(const InvalidContents& rhs) + : Contents(rhs), + mOriginalType(rhs.mOriginalType), + mText(rhs.mText) +{ +} + +InvalidContents::~InvalidContents() +{ +} + +InvalidContents& +InvalidContents::operator=(const InvalidContents& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + mOriginalType = rhs.mOriginalType; + mText = rhs.mText; + } + return *this; +} + +Contents* +InvalidContents::clone() const +{ + return new InvalidContents(*this); +} + +const Mime& +InvalidContents::getStaticType() +{ + static Mime type("Invalid","Invalid"); + return type; +} + +EncodeStream& +InvalidContents::encodeParsed(EncodeStream& str) const +{ + str << mText; + return str; +} + +void +InvalidContents::parse(ParseBuffer& pb) +{ + const char* anchor = pb.position(); + pb.skipToEnd(); + pb.data(mText, anchor); +} + +const Mime& +InvalidContents::getOriginalType() const +{ + return mOriginalType; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/InvalidContents.hxx b/src/libs/resiprocate/resip/stack/InvalidContents.hxx new file mode 100644 index 00000000..d715cc43 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/InvalidContents.hxx @@ -0,0 +1,105 @@ +#if !defined(RESIP_INVALIDCONTENTS_HXX) +#define RESIP_INVALIDCONTENTS_HXX + +#include "resip/stack/Contents.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type to represent an invalid content type (MIME content-type Invalid/Invalid). +*/ +class InvalidContents : public Contents +{ + public: + InvalidContents(); + InvalidContents(const Data& text, const Mime& originalType); + InvalidContents(const HeaderFieldValue& hfv, const Mime& contentType, const Mime& originalType); + InvalidContents(const Data& data, const Mime& contentType, const Mime& originalType); + InvalidContents(const InvalidContents& rhs); + virtual ~InvalidContents(); + InvalidContents& operator=(const InvalidContents& rhs); + + /** @brief duplicate an InvalidContents object + @return pointer to a new InvalidContents object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType(); + + /** @brief Gets the MIME content-type used in the constructor of InvalidContents. + @return Mime containing the MIME content-type. + **/ + const Mime& getOriginalType() const; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + /** @brief Gets a const reference to the parsed text from invalid contents. + @return Data containing the parsed contents. + **/ + const Data& text() const {checkParsed(); return mText;} + /** @brief Gets the parsed text from invalid contents. + @return Data containing the parsed contents. + **/ + Data& text() {checkParsed(); return mText;} + + private: + Mime mOriginalType; // mime type of original message. + Data mText; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/KeepAliveMessage.cxx b/src/libs/resiprocate/resip/stack/KeepAliveMessage.cxx new file mode 100644 index 00000000..15aebef9 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/KeepAliveMessage.cxx @@ -0,0 +1,97 @@ +#include "resip/stack/KeepAliveMessage.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +KeepAliveMessage::KeepAliveMessage() +{ +} + +KeepAliveMessage::KeepAliveMessage(const KeepAliveMessage& message) + : SipMessage(message) +{ + // .slg. these lines are required in order for transport selector + // to work - we are not actually sending an OPTIONS request. + // see encode() below + header(h_RequestLine).method() = OPTIONS; + Via via; + header(h_Vias).push_back(via); +} + +KeepAliveMessage::~KeepAliveMessage() +{ +} + + +KeepAliveMessage& +KeepAliveMessage::operator=(const KeepAliveMessage& rhs) +{ + if (this != &rhs) + { + SipMessage::operator=(rhs); + } + return *this; +} + +Message* +KeepAliveMessage::clone() const +{ + return new KeepAliveMessage(*this); +} + +EncodeStream& +KeepAliveMessage::encode(EncodeStream& str) const +{ + str << Symbols::CRLFCRLF; + return str; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/KeepAliveMessage.hxx b/src/libs/resiprocate/resip/stack/KeepAliveMessage.hxx new file mode 100644 index 00000000..62e9c26f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/KeepAliveMessage.hxx @@ -0,0 +1,71 @@ +#if !defined(RESIP_KEEPALIVEMESSAGE_HXX) +#define RESIP_KEEPALIVEMESSAGE_HXX + +#include "resip/stack/SipMessage.hxx" + +namespace resip +{ +class KeepAliveMessage : public SipMessage +{ + public: + RESIP_HeapCount(KeepAliveMessage); + KeepAliveMessage(); + KeepAliveMessage(const KeepAliveMessage& message); + virtual Message* clone() const; + KeepAliveMessage& operator=(const KeepAliveMessage& rhs); + virtual ~KeepAliveMessage(); + virtual EncodeStream& encode(EncodeStream& str) const; +}; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/KeepAlivePong.hxx b/src/libs/resiprocate/resip/stack/KeepAlivePong.hxx new file mode 100644 index 00000000..10826b1c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/KeepAlivePong.hxx @@ -0,0 +1,92 @@ +#if !defined(RESIP_KEEPALIVEPONG_HXX) +#define RESIP_KEEPALIVEPONG_HXX + +#include "rutil/HeapInstanceCounter.hxx" +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/Tuple.hxx" + +namespace resip +{ + +class KeepAlivePong : public TransactionMessage +{ + public: + RESIP_HeapCount(KeepAlivePong); + + KeepAlivePong(const Tuple& flow) : + mFlow(flow) + { + } + virtual const Data& getTransactionId() const { assert(0); return Data::Empty; } + virtual bool isClientTransaction() const { assert(0); return false; } + virtual Message* clone() const { return new KeepAlivePong(mFlow); } + virtual EncodeStream& encode(EncodeStream& strm) const { return encodeBrief(strm); } + virtual EncodeStream& encodeBrief(EncodeStream& str) const + { + return str << "KeepAlivePong " << mFlow; + } + + FlowKey getFlowKey() const + { + return mFlow.mFlowKey; + } + + const Tuple& getFlow() const + { + return mFlow; + } + + private: + const Tuple mFlow; +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/LazyParser.cxx b/src/libs/resiprocate/resip/stack/LazyParser.cxx new file mode 100644 index 00000000..42f7ae51 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/LazyParser.cxx @@ -0,0 +1,192 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + + +#include <cassert> + +#include "resip/stack/Headers.hxx" +#include "resip/stack/HeaderFieldValue.hxx" +#include "resip/stack/LazyParser.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +LazyParser::LazyParser(const HeaderFieldValue& headerFieldValue) + : mHeaderField(headerFieldValue, HeaderFieldValue::NoOwnership), + mState(mHeaderField.getBuffer() == 0 ? DIRTY : NOT_PARSED) +{ +} + +LazyParser::LazyParser(const HeaderFieldValue& headerFieldValue, + HeaderFieldValue::CopyPaddingEnum e) + : mHeaderField(headerFieldValue, e), // Causes ownership to be taken. Oh well + mState(mHeaderField.getBuffer() == 0 ? DIRTY : NOT_PARSED) +{} + +LazyParser::LazyParser(const char* buf, int length) : + mHeaderField(buf, length), + mState(buf == 0 ? DIRTY : NOT_PARSED) +{} + +LazyParser::LazyParser() + : mHeaderField(), + mState(DIRTY) +{ +} + +LazyParser::LazyParser(const LazyParser& rhs) + : mHeaderField((rhs.mState==DIRTY ? HeaderFieldValue::Empty : rhs.mHeaderField)), // Pretty cheap when rhs is DIRTY + mState(rhs.mState) +{} + +LazyParser::LazyParser(const LazyParser& rhs,HeaderFieldValue::CopyPaddingEnum e) + : mHeaderField((rhs.mState==DIRTY ? HeaderFieldValue::Empty : rhs.mHeaderField), e), // Pretty cheap when rhs is DIRTY + mState(rhs.mState) +{} + + +LazyParser::~LazyParser() +{ + clear(); +} + +LazyParser& +LazyParser::operator=(const LazyParser& rhs) +{ + assert( &rhs != 0 ); + + if (this != &rhs) + { + clear(); + mState = rhs.mState; + if (rhs.mState!=DIRTY) + { + mHeaderField=rhs.mHeaderField; + } + } + return *this; +} + +void +LazyParser::doParse() const +{ + LazyParser* ncThis = const_cast<LazyParser*>(this); + // .bwc. We assume the worst, and if the parse succeeds, we update. + ncThis->mState = MALFORMED; + ParseBuffer pb(mHeaderField.getBuffer(), mHeaderField.getLength(), errorContext()); + ncThis->parse(pb); + // .bwc. If we get this far without throwing, the parse has succeeded. + ncThis->mState = WELL_FORMED; +} + +bool +LazyParser::isWellFormed() const +{ + try + { + checkParsed(); + } + catch(resip::ParseException&) + { + } + + return (mState!=MALFORMED); +} + +void +LazyParser::clear() +{ + mHeaderField.clear(); +} + +EncodeStream& +LazyParser::encode(EncodeStream& str) const +{ + if (mState == DIRTY) + { + return encodeParsed(str); + } + else + { + mHeaderField.encode(str); + return str; + } +} + +#ifndef RESIP_USE_STL_STREAMS +EncodeStream& +resip::operator<<(EncodeStream&s, const LazyParser& lp) +{ + lp.encode(s); + return s; +} +#endif + +std::ostream& +resip::operator<<(std::ostream &s, const LazyParser& lp) +{ +#ifdef RESIP_USE_STL_STREAMS + lp.encode(s); +#else + //this should only be called for things like cout,cerr, or other streams not supporting + //other stream encoders, aka MD5Stream + Data data; + DataStream stream(data); + + lp.encode(stream); + stream.flush(); + s << data.c_str(); +#endif + return s; +} +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/LazyParser.hxx b/src/libs/resiprocate/resip/stack/LazyParser.hxx new file mode 100644 index 00000000..6cb0e25b --- /dev/null +++ b/src/libs/resiprocate/resip/stack/LazyParser.hxx @@ -0,0 +1,215 @@ +#if !defined(RESIP_LAZYPARSER_HXX) +#define RESIP_LAZYPARSER_HXX + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <iosfwd> +#include "resip/stack/HeaderFieldValue.hxx" +#include "rutil/resipfaststreams.hxx" + +namespace resip +{ + +class ParseBuffer; +class Data; + +/** + @brief The base-class for all lazily-parsed SIP grammar elements. + + Subclasses of this are parse-on-access; the parse will be carried out (if + it hasn't already) the first time one of the members is accessed. Right now, + all header field values and SIP bodies are lazily parsed. + + Application writers are expected to make consistent use of isWellFormed() in + order to determine whether an element is parseable. Using a try/catch block + around accesses will not work as expected, since an exception will only be + thrown the _first_ time an access is made, and it is determined that the + element isn't parseable. + + @ingroup resip_crit + @ingroup sip_parse +*/ +class LazyParser +{ + public: + /** + @internal + */ + explicit LazyParser(const HeaderFieldValue& headerFieldValue); + + /** + @internal + */ + LazyParser(const char* buf, int length); + + /** + @internal + */ + LazyParser(const HeaderFieldValue& headerFieldValue, + HeaderFieldValue::CopyPaddingEnum e); + + /** + @internal + */ + LazyParser(const LazyParser& rhs); + + /** + @internal + */ + LazyParser(const LazyParser& rhs,HeaderFieldValue::CopyPaddingEnum e); + + /** + @internal + */ + LazyParser& operator=(const LazyParser& rhs); + virtual ~LazyParser(); + + /** + @internal + */ + virtual EncodeStream& encodeParsed(EncodeStream& str) const = 0; + + /** + @internal + */ + virtual void parse(ParseBuffer& pb) = 0; + + /** + @brief Encodes this element to a stream, in the fashion it should be + represented on the wire. + @param str The ostream to encode to. + @return A reference to str. + */ + EncodeStream& encode(EncodeStream& str) const; + + /** + @brief Returns true iff a parse has been attempted. + @note This means that this will return true if a parse failed earlier. + */ + bool isParsed() const {return (mState!=NOT_PARSED);} + + /** + @internal + */ + HeaderFieldValue& getHeaderField() { return mHeaderField; } + + // call (internally) before every access + /** + @internal + */ + void checkParsed() const + { + if (mState==NOT_PARSED) + { + doParse(); + } + } + void checkParsed() + { + const LazyParser* constThis = const_cast<const LazyParser*>(this); + constThis->checkParsed(); + mState=DIRTY; + } + void doParse() const; + inline void markDirty() const {mState=DIRTY;} + + /** + @brief Returns true iff this element was parsed successfully, according + to the implementation of parse(). + + App writers are expected to use this extensively, since a failure in + the parse-on-access will throw an exception the _first_ time access is + made, but nothing will happen on subsequent accesses. (Writing a + try/catch block when you try to inspect the members of a subclass will + only work as intended if the subclass hasn't been accessed before.) + */ + bool isWellFormed() const; + protected: + LazyParser(); + + // called in destructor and on assignment + void clear(); + + // context for error messages + virtual const Data& errorContext() const = 0; + + private: + // !dlb! bit of a hack until the dust settles + friend class Contents; + + HeaderFieldValue mHeaderField; + + typedef enum + { + NOT_PARSED, + WELL_FORMED, // Parsed, well-formed, but underlying buffer is still valid + MALFORMED, // Parsed, malformed, underlying buffer is still valid + DIRTY // Well-formed, and underlying buffer is invalid + } ParseState; + mutable ParseState mState; +}; + +#ifndef RESIP_USE_STL_STREAMS +EncodeStream& +operator<<(EncodeStream&, const LazyParser& lp); +#endif + +//need this for MD5Stream +std::ostream& +operator<<(std::ostream&, const LazyParser& lp); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Makefile b/src/libs/resiprocate/resip/stack/Makefile new file mode 100644 index 00000000..24b44672 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Makefile @@ -0,0 +1,157 @@ +############################################################################# +# Makefile for building: resiprocate +# Generated by qmake (2.01a) (Qt 4.7.4) on: ?? 19. ??? 14:08:04 2011 +# Project: resiprocate.pro +# Template: lib +# Command: d:\tools\qtsdk\desktop\qt\4.7.4\msvc2008\bin\qmake.exe -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile resiprocate.pro +############################################################################# + +first: debug +install: debug-install +uninstall: debug-uninstall +MAKEFILE = Makefile +QMAKE = d:\tools\qtsdk\desktop\qt\4.7.4\msvc2008\bin\qmake.exe +DEL_FILE = del +CHK_DIR_EXISTS= if not exist +MKDIR = mkdir +COPY = copy /y +COPY_FILE = $(COPY) +COPY_DIR = xcopy /s /q /y /i +INSTALL_FILE = $(COPY_FILE) +INSTALL_PROGRAM = $(COPY_FILE) +INSTALL_DIR = $(COPY_DIR) +DEL_FILE = del +SYMLINK = +DEL_DIR = rmdir +MOVE = move +CHK_DIR_EXISTS= if not exist +MKDIR = mkdir +SUBTARGETS = \ + debug \ + release + +debug: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug +debug-make_default: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug +debug-make_first: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug first +debug-all: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug all +debug-clean: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug clean +debug-distclean: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug distclean +debug-install: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug install +debug-uninstall: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug uninstall +release: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release +release-make_default: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release +release-make_first: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release first +release-all: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release all +release-clean: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release clean +release-distclean: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release distclean +release-install: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release install +release-uninstall: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release uninstall + +Makefile: resiprocate.pro d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008\qmake.conf d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\qconfig.pri \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\modules\qt_webkit_version.pri \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_functions.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_config.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\exclusive_builds.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_pre.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_pre.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug_and_release.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_post.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_post.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\staticlib.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\static.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\rtti.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\exceptions.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\stl.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_exe.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_dll.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\warn_on.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\thread.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\moc.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\windows.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\resources.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\uic.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\yacc.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\lex.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\incredibuild_xge.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\include_source_dir.prf + $(QMAKE) -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile resiprocate.pro +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\qconfig.pri: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\modules\qt_webkit_version.pri: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_functions.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_config.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\exclusive_builds.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_pre.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_pre.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug_and_release.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_post.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_post.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\staticlib.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\static.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\rtti.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\exceptions.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\stl.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_exe.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_dll.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\warn_on.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\thread.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\moc.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\windows.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\resources.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\uic.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\yacc.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\lex.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\incredibuild_xge.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\include_source_dir.prf: +qmake: qmake_all FORCE + @$(QMAKE) -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile resiprocate.pro + +qmake_all: FORCE + +make_default: debug-make_default release-make_default FORCE +make_first: debug-make_first release-make_first FORCE +all: debug-all release-all FORCE +clean: debug-clean release-clean FORCE + -$(DEL_FILE) ..\..\..\..\Libs\compiled\win\resiprocate.ilk + -$(DEL_FILE) vc*.pdb + -$(DEL_FILE) vc*.idb +distclean: debug-distclean release-distclean FORCE + -$(DEL_FILE) Makefile + -$(DEL_FILE) ..\..\..\..\Libs\compiled\win\resiprocate.pdb + +check: first + +debug-mocclean: $(MAKEFILE).Debug + $(MAKE) -f $(MAKEFILE).Debug mocclean +release-mocclean: $(MAKEFILE).Release + $(MAKE) -f $(MAKEFILE).Release mocclean +mocclean: debug-mocclean release-mocclean + +debug-mocables: $(MAKEFILE).Debug + $(MAKE) -f $(MAKEFILE).Debug mocables +release-mocables: $(MAKEFILE).Release + $(MAKE) -f $(MAKEFILE).Release mocables +mocables: debug-mocables release-mocables +FORCE: + +$(MAKEFILE).Debug: Makefile +$(MAKEFILE).Release: Makefile diff --git a/src/libs/resiprocate/resip/stack/MarkListener.hxx b/src/libs/resiprocate/resip/stack/MarkListener.hxx new file mode 100644 index 00000000..8a60d3a5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MarkListener.hxx @@ -0,0 +1,66 @@ +#ifndef MARK_LISTENER_HXX +#define MARK_LISTENER_HXX + +#include "resip/stack/TupleMarkManager.hxx" + +namespace resip +{ +class MarkListener +{ + public: + virtual ~MarkListener() {} + virtual void onMark(const Tuple& target,UInt64& expiry, TupleMarkManager::MarkType& mark)= 0; +}; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Message.cxx b/src/libs/resiprocate/resip/stack/Message.cxx new file mode 100644 index 00000000..b94aedf5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Message.cxx @@ -0,0 +1,118 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Message.hxx" +#include "rutil/DataStream.hxx" +#include <cassert> + +using namespace resip; + + +Message::Message() : mTu(0) +{} + +Message::Brief +Message::brief() const +{ + return Message::Brief(*this); +} + +Message::Brief::Brief(const Message& source) : + mSource(source) +{ +} + +#ifndef RESIP_USE_STL_STREAMS +std::ostream& +resip::operator<<(std::ostream& strm, + const resip::Message& msg) +{ + Data encoded; + + DataStream encodeStream(encoded); + msg.encode(encodeStream); + encodeStream.flush(); + + strm << encoded.c_str(); + + return strm; +} + +std::ostream& +resip::operator<<(std::ostream& strm, + const resip::Message::Brief& brief) +{ + Data encoded; + + DataStream encodeStream(encoded); + brief.mSource.encodeBrief(encodeStream); + encodeStream.flush(); + + strm << encoded.c_str(); + + return strm; +} +#endif + +EncodeStream& +resip::operator<<(EncodeStream& strm, + const resip::Message& msg) +{ + return msg.encode(strm); +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, + const resip::Message::Brief& brief) +{ + return brief.mSource.encodeBrief(strm); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Message.hxx b/src/libs/resiprocate/resip/stack/Message.hxx new file mode 100644 index 00000000..492b4e4a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Message.hxx @@ -0,0 +1,119 @@ +#ifndef RESIP_Message_hxx +#define RESIP_Message_hxx + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rutil/Data.hxx" +#include <iosfwd> +#include "rutil/resipfaststreams.hxx" + +namespace resip +{ +class TransactionUser; + +/** + @ingroup resip_crit + @brief The base-class used for message-passing. +*/ +class Message +{ + public: + Message(); + virtual ~Message() {} + + /// facet for brief output to streams + class Brief + { + public: + Brief(const Message& src); + const Message& mSource; + }; + + /// return a facet for brief encoding of message + Brief brief() const; + virtual Message* clone() const = 0; + /// output the entire message to stream + virtual EncodeStream& encode(EncodeStream& strm) const = 0; + /// output a brief description to stream + virtual EncodeStream& encodeBrief(EncodeStream& str) const = 0; + + protected: + friend class TuSelector; + friend class TransactionController; + friend class TransactionState; + friend class SipStack; + bool hasTransactionUser() const { return mTu != 0; } + void setTransactionUser(TransactionUser* t) { mTu = t; } + TransactionUser* getTransactionUser() { return mTu; } + TransactionUser* mTu; +}; + +//always need std streams where things are encoded to cout, cerr, MD5Stream, etc... +#ifndef RESIP_USE_STL_STREAMS +EncodeStream& +operator<<(EncodeStream& strm, const Message& msg); + +EncodeStream& +operator<<(EncodeStream& strm, const Message::Brief& brief); +#endif + +std::ostream& +operator<<(std::ostream& strm, const Message& msg); + +std::ostream& +operator<<(std::ostream& strm, const Message::Brief& brief); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/stack/MessageDecorator.hxx b/src/libs/resiprocate/resip/stack/MessageDecorator.hxx new file mode 100644 index 00000000..a38f300e --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MessageDecorator.hxx @@ -0,0 +1,86 @@ +#if !defined(RESIP_MESSAGE_DECORATOR_HXX) +#define RESIP_MESSAGE_DECORATOR_HXX + + +namespace resip +{ +class Data; +class SipMessage; +class Tuple; + +class MessageDecorator +{ + public: + virtual ~MessageDecorator() {;} + virtual void decorateMessage(SipMessage &msg, + const Tuple &source, + const Tuple &destination, + const Data& sigcompId) = 0; + virtual void rollbackMessage(SipMessage& msg) = 0; + virtual MessageDecorator* clone() const = 0; + + /// If this decorator is applied to an INVITE request, and the stack + /// ends up needing to CANCEL it or to generate a failure ACK for it + /// then setting these returns to true will signal the stack to copy + /// this Decorator from the INVITE message to the resulting CANCEL or ACK. + /// Note: This functionality was added so that it is possible to + /// decorate all request messaging on the wire. + /// Note: If the CANCEL or ACK/200 is generated at the DUM layer, then + /// the normal profile decorators will be added to it. + virtual bool copyToStackCancels() const { return false; } + virtual bool copyToStackFailureAcks() const { return false; } +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MessageFilterRule.cxx b/src/libs/resiprocate/resip/stack/MessageFilterRule.cxx new file mode 100644 index 00000000..4376ba13 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MessageFilterRule.cxx @@ -0,0 +1,245 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/MessageFilterRule.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/TransactionUser.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TRANSACTION + +using namespace resip; +using namespace std; + + +MessageFilterRule::MessageFilterRule(SchemeList schemeList, + HostpartTypes hostpartType, + MethodList methodList, + EventList eventList) + : mSchemeList(schemeList), + mHostpartMatches(hostpartType), + mMethodList(methodList), + mEventList(eventList), + mTransactionUser(0) +{ +} + +MessageFilterRule::MessageFilterRule(SchemeList schemeList, + HostpartList hostpartList, + MethodList methodList, + EventList eventList) + : mSchemeList(schemeList), + mHostpartMatches(List), + mHostpartList(hostpartList), + mMethodList(methodList), + mEventList(eventList), + mTransactionUser(0) +{ +} + +bool +MessageFilterRule::matches(const SipMessage &msg) const +{ + DebugLog(<< "Matching rule for: " << std::endl << std::endl << msg); + const Data scheme = msg.header(h_RequestLine).uri().scheme(); + + if (!schemeIsInList(scheme)) + { + DebugLog(<< "Scheme is not in list. Rule does not match."); + return false; + } + + if (msg.header(h_RequestLine).uri().scheme() != Symbols::Tel) + { + // !rwm! Should be hostport, not host + if (!hostIsInList( msg.header(h_RequestLine).uri().host())) + { + DebugLog(<< "Host is not in list. Rule does not match."); + return false; + } + } + + MethodTypes method = msg.header(h_RequestLine).method(); + if (!methodIsInList(method)) + { + DebugLog(<< "Method is not in list. Rule does not match."); + return false; + } + else + { + switch(method) + { + case SUBSCRIBE: + case NOTIFY: + case PUBLISH: + if (!eventIsInList(msg)) + { + DebugLog(<< "Event is not in list. Rule does not match."); + return false; + } + break; + default: + break; + } + } + + return true; +} + +bool +MessageFilterRule::schemeIsInList(const Data& scheme) const +{ + // Emtpy list means "sip or sips" + if (mSchemeList.empty()) + { + return (scheme == Symbols::Sip || scheme == Symbols::Sips || scheme == Symbols::Tel); + } + + // step through mSchemeList looking for supported schemes + for (SchemeList::const_iterator i = mSchemeList.begin(); + i != mSchemeList.end(); i++) + { + if (scheme == *i) + { + return true; + } + + } + return false; +} + +bool +MessageFilterRule::methodIsInList(MethodTypes method) const +{ + // empty list means "match all" + if (mMethodList.empty()) + { + return true; + } + + for (MethodList::const_iterator i = mMethodList.begin(); + i != mMethodList.end(); i++) + { + if (method == *i) + { + return true; + } + + } + return false; +} + +bool +MessageFilterRule::eventIsInList(const SipMessage& msg) const +{ + // empty list means "match all" + if (mEventList.empty()) + { + return true; + } + + if (!msg.exists(h_Event)) + { + return false; + } + + Data event = msg.header(h_Event).value(); + + for (EventList::const_iterator i = mEventList.begin(); + i != mEventList.end(); i++) + { + if (event == *i) + { + return true; + } + + } + return false; +} + +bool +MessageFilterRule::hostIsInList(const Data& hostpart) const +{ + switch(mHostpartMatches) + { + case Any: + return true; + case HostIsMe: + // !abr! Waiting for TU support for this method. + // return (tu.hostIsMe(hostpart)); + return false; + break; + case DomainIsMe: + if(mTransactionUser) + { + return mTransactionUser->isMyDomain(hostpart); + } + return false; + break; + case List: + // walk the list for specific matches + for (HostpartList::const_iterator i = mHostpartList.begin() ; + i != mHostpartList.end() ; ++i) + { + if (isEqualNoCase(*i, hostpart)) + return true; + } + break; + default: + break; + } + return false; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MessageFilterRule.hxx b/src/libs/resiprocate/resip/stack/MessageFilterRule.hxx new file mode 100644 index 00000000..d0736b2e --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MessageFilterRule.hxx @@ -0,0 +1,99 @@ +#if !defined(RESIP_MESSAGE_FILTER_RULE_HXX) +#define RESIP_MESSAGE_FILTER_RULE_HXX + +#include <vector> +#include "resip/stack/SipMessage.hxx" + +namespace resip +{ +class TransactionUser; +class MessageFilterRule +{ + public: + typedef std::vector<Data> SchemeList; + typedef std::vector<Data> HostpartList; + enum HostpartTypes { Any, HostIsMe, DomainIsMe, List }; // Note: HostIsMe is currently not implemented + typedef std::vector<Data> EventList; + typedef std::vector<MethodTypes> MethodList; + + MessageFilterRule(SchemeList schemeList = SchemeList(), + HostpartTypes hostpartType = Any, + MethodList methodList = MethodList(), + EventList eventTypeList = EventList()); + + MessageFilterRule(SchemeList schemeList, + HostpartList hostpartList, + MethodList methodList = MethodList(), + EventList eventList = EventList()); + + bool matches(const SipMessage &) const; + void setTransactionUser(TransactionUser* tu) { mTransactionUser = tu; } + + private: + bool schemeIsInList(const Data &scheme) const; + bool hostIsInList(const Data &hostpart) const; + bool methodIsInList(MethodTypes method) const; + bool eventIsInList(const SipMessage& msg) const; + + SchemeList mSchemeList; + HostpartTypes mHostpartMatches; + HostpartList mHostpartList; + MethodList mMethodList; + EventList mEventList; + TransactionUser* mTransactionUser; +}; + +typedef std::vector<MessageFilterRule> MessageFilterRuleList; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MessageWaitingContents.cxx b/src/libs/resiprocate/resip/stack/MessageWaitingContents.cxx new file mode 100644 index 00000000..ae2a8346 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MessageWaitingContents.cxx @@ -0,0 +1,667 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/MessageWaitingContents.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" +#include <utility> + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::CONTENTS + +bool +MessageWaitingContents::init() +{ + static ContentsFactory<MessageWaitingContents> factory; + (void)factory; + return true; +} + +resip::MessageWaitingContents::AccountHeader resip::mw_account; +const char* MessageHeaders[MW_MAX] = {"voice-message", + "fax-message", + "pager-message", + "multimedia-message", + "text-message", + "none"}; + +MessageWaitingContents::MessageWaitingContents() + : Contents(getStaticType()), + mHasMessages(false), + mAccountUri(0) +{ + for(int i = 0; i < (int)MW_MAX; i++) + { + mHeaders[i] = 0; + } +} + +MessageWaitingContents::MessageWaitingContents(const HeaderFieldValue& hfv, const Mime& contentType) + : Contents(hfv, contentType), + mHasMessages(false), + mAccountUri(0) +{ + for(int i = 0; i < (int)MW_MAX; i++) + { + mHeaders[i] = 0; + } +} + +MessageWaitingContents::MessageWaitingContents(const Data& data, const Mime& contentType) + : Contents(contentType), + mHasMessages(false), + mAccountUri(0) +{ + for(int i = 0; i < (int)MW_MAX; i++) + { + mHeaders[i] = 0; + } + assert(0); +} + +MessageWaitingContents::MessageWaitingContents(const MessageWaitingContents& rhs) + : Contents(rhs), + mHasMessages(rhs.mHasMessages), + mAccountUri(rhs.mAccountUri ? new Uri(*rhs.mAccountUri) : 0), + mExtensions(rhs.mExtensions) +{ + for(int i = 0; i < (int)MW_MAX; i++) + { + if (rhs.mHeaders[i] != 0) + { + mHeaders[i] = new Header(*rhs.mHeaders[i]); + } + else + { + mHeaders[i] = 0; + } + } +} + +MessageWaitingContents::~MessageWaitingContents() +{ + clear(); +} + +void +MessageWaitingContents::clear() +{ + mHasMessages = false; + + delete mAccountUri; + mAccountUri = 0; + + for (int i = 0; i < (int)MW_MAX; i++) + { + delete mHeaders[i]; + } +} + +MessageWaitingContents& +MessageWaitingContents::operator=(const MessageWaitingContents& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + clear(); + + mHasMessages = rhs.mHasMessages; + mAccountUri = rhs.mAccountUri ? new Uri(*rhs.mAccountUri) : 0; + mExtensions = rhs.mExtensions; + + for(int i = 0; i < (int)MW_MAX; i++) + { + if (rhs.mHeaders[i] != 0) + { + mHeaders[i] = new Header(*rhs.mHeaders[i]); + } + else + { + mHeaders[i] = 0; + } + } + } + return *this; +} + +const Mime& +MessageWaitingContents::getStaticType() +{ + static Mime type("application", "simple-message-summary"); + //static Mime type("text", "data"); + return type; +} + +Contents* +MessageWaitingContents::clone() const +{ + return new MessageWaitingContents(*this); +} + +EncodeStream& +MessageWaitingContents::encodeParsed(EncodeStream& s) const +{ + s << "Messages-Waiting" << Symbols::COLON[0] << Symbols::SPACE[0] + << (mHasMessages ? "yes" : "no") << Symbols::CRLF; + + if (exists(mw_account)) + { + s << "Message-Account" << Symbols::COLON[0] << Symbols::SPACE[0]; + header(mw_account).encode(s); + s << Symbols::CRLF; + } + + for(int i = 0; i < (int)MW_MAX; i++) + { + if (mHeaders[i] != 0) + { + s << MessageHeaders[i] << Symbols::COLON[0] << Symbols::SPACE[0] + << mHeaders[i]->mNew << Symbols::SLASH[0] + << mHeaders[i]->mOld; + + if (mHeaders[i]->mHasUrgent) + { + s << Symbols::SPACE[0] << Symbols::LPAREN[0] + << mHeaders[i]->mUrgentNew << Symbols::SLASH[0] + << mHeaders[i]->mUrgentOld << Symbols::RPAREN[0]; + } + + s << Symbols::CRLF; + } + } + + if (!mExtensions.empty()) + { + s << Symbols::CRLF; + for (map<Data, Data>::const_iterator i = mExtensions.begin(); + i != mExtensions.end(); i++) + { + s << i->first << Symbols::COLON[0] << Symbols::SPACE[0] + << i->second << Symbols::CRLF; + } + } + + return s; +} + +inline +bool +isWhite(char c) +{ + switch (c) + { + case ' ' : + case '\t' : + case '\r' : + case '\n' : + return true; + default: + return false; + } +} + +const char* +resip::skipSipLWS(ParseBuffer& pb) +{ + enum {WS, CR, LF, CR1}; + + int state = WS; + + while (!pb.eof()) + { + if (!isWhite(*pb.position())) + { + if (state == LF) + { + pb.reset(pb.position() - 2); + } + return pb.position(); + } + if (!pb.eof()) + { + switch (state) + { + case WS: + if (*pb.position() == Symbols::CR[0]) + { + state = CR; + } + break; + case CR: + if (*pb.position() == Symbols::CR[0]) + { + state = CR; + } + else if (*pb.position() == Symbols::LF[0]) + { + state = LF; + } + else + { + state = WS; + } + break; + case LF: + if (*pb.position() == Symbols::CR[0]) + { + state = CR1; + } + else if (!pb.eof() && *pb.position() == Symbols::LF[0]) + { + state = WS; + } + break; + case CR1: + if (*pb.position() == Symbols::CR[0]) + { + state = CR; + } + else if (*pb.position() == Symbols::LF[0]) + { + pb.reset(pb.position() - 3); + return pb.position(); + } + else + { + state = WS; + } + break; + default: + assert(false); + } + } + pb.skipChar(); + } + + if (state == LF) + { + pb.reset(pb.position() - 2); + } + return pb.position(); +} + +void +MessageWaitingContents::parse(ParseBuffer& pb) +{ + pb.skipChars("Messages-Waiting"); + pb.skipWhitespace(); + pb.skipChar(Symbols::COLON[0]); + const char* anchor = pb.skipWhitespace(); + pb.skipNonWhitespace(); + + Data has; + pb.data(has, anchor); + if (isEqualNoCase(has, "yes")) + { + mHasMessages = true; + } + else if (isEqualNoCase(has, "no")) + { + mHasMessages = false; + } + else + { + pb.fail(__FILE__, __LINE__); + } + + anchor = pb.skipWhitespace(); + if (pb.eof()) + { + return; + } + + Data accountHeader; + pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::COLON); + pb.data(accountHeader, anchor); + static const Data AccountMessage("message-account"); + if (isEqualNoCase(accountHeader, AccountMessage)) + { + pb.skipWhitespace(); + pb.skipChar(Symbols::COLON[0]); + pb.skipWhitespace(); + + mAccountUri = new Uri(); + mAccountUri->parse(pb); + pb.skipChars(Symbols::CRLF); + } + else + { + pb.reset(anchor); + } + + while (!pb.eof() && *pb.position() != Symbols::CR[0]) + { + int ht = -1; + switch (tolower(*pb.position())) + { + case 'v' : + ht = mw_voice; + break; + case 'f' : + ht = mw_fax; + break; + case 'p' : + ht = mw_pager; + break; + case 'm' : + ht = mw_multimedia; + break; + case 't' : + ht = mw_text; + break; + case 'n' : + ht = mw_none; + break; + default : + pb.fail(__FILE__, __LINE__); + } + assert(ht != -1); + + pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::COLON); + pb.skipWhitespace(); + pb.skipChar(Symbols::COLON[0]); + pb.skipWhitespace(); + + unsigned int numNew = pb.integer(); + pb.skipWhitespace(); + pb.skipChar(Symbols::SLASH[0]); + pb.skipWhitespace(); + + unsigned int numOld = pb.integer(); + skipSipLWS(pb); + + if (!pb.eof() && *pb.position() != Symbols::LPAREN[0]) + { + if (mHeaders[ht] != 0) + { + pb.fail(__FILE__, __LINE__); + } + mHeaders[ht] = new Header(numNew, numOld); + } + else + { + pb.skipChar(); + pb.skipWhitespace(); + + unsigned int numUrgentNew = pb.integer(); + pb.skipWhitespace(); + pb.skipChar(Symbols::SLASH[0]); + pb.skipWhitespace(); + + unsigned int numUrgentOld = pb.integer(); + pb.skipWhitespace(); + pb.skipChar(Symbols::RPAREN[0]); + // skip LWS as specified in rfc3261 + skipSipLWS(pb); + + if (mHeaders[ht] != 0) + { + pb.fail(__FILE__, __LINE__); + } + mHeaders[ht] = new Header(numNew, numOld, numUrgentNew, numUrgentOld); + } + + pb.skipChars(Symbols::CRLF); + } + + if (!pb.eof() && *pb.position() == Symbols::CR[0]) + { + pb.skipChars(Symbols::CRLF); + + while (!pb.eof()) + { + anchor = pb.position(); + Data header; + pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::COLON); + pb.data(header, anchor); + + pb.skipWhitespace(); + pb.skipChar(Symbols::COLON[0]); + anchor = pb.skipWhitespace(); + + while (true) + { + // CodeWarrior isn't helpful enough to pick the "obvious" operator definition + // so we add volatile here so CW is completely unconfused what to do. + const volatile char* pos = pb.skipToChar(Symbols::CR[0]); + skipSipLWS(pb); + if (pb.position() == pos) + { + Data content; + pb.data(content, anchor); + mExtensions[header] = content; + + pb.skipChars(Symbols::CRLF); + break; + } + } + } + } +} + +MessageWaitingContents::Header::Header(unsigned int numNew, + unsigned int numOld) + : mNew(numNew), + mOld(numOld), + mHasUrgent(false), + mUrgentNew(0), + mUrgentOld(0) +{} + +MessageWaitingContents::Header::Header(unsigned int numNew, + unsigned int numOld, + unsigned int numUrgentNew, + unsigned int numUrgentOld) + : mNew(numNew), + mOld(numOld), + mHasUrgent(true), + mUrgentNew(numUrgentNew), + mUrgentOld(numUrgentOld) +{} + +MessageWaitingContents::Header& +MessageWaitingContents::header(HeaderType ht) +{ + checkParsed(); + + /* this is a trick to allow a const method to update "this" with an empty + Header in case there wasn't a corresponding header line in the MessageWaiting doc + */ + if (mHeaders[ht] == 0) + { + mHeaders[ht] = new Header(0, 0); + } + return *mHeaders[ht]; +} + +const MessageWaitingContents::Header& +MessageWaitingContents::header(HeaderType ht) const +{ + checkParsed(); + + /* this is a trick to allow a const method to update "this" with an empty + Header in case there wasn't a corresponding header line in the MessageWaiting doc + */ + if (mHeaders[ht] == 0) + { + ErrLog(<< "You called " + "MessageWaitingContents::header(HeaderType ht) _const_ " + "without first calling exists(), and the header does not exist. Our" + " behavior in this scenario is to implicitly create the header(using const_cast!); " + "this is probably not what you want, but it is either this or " + "assert/throw an exception. Since this has been the behavior for " + "so long, we are not throwing here, _yet_. You need to fix your " + "code, before we _do_ start throwing. This is why const-correctness" + " should never be made a TODO item </rant>"); + MessageWaitingContents* ncthis = const_cast<MessageWaitingContents*>(this); + ncthis->mHeaders[ht] = new Header(0, 0); + } + return *mHeaders[ht]; +} + +bool +MessageWaitingContents::exists(HeaderType ht) const +{ + checkParsed(); + return mHeaders[ht] != 0; +} + +void +MessageWaitingContents::remove(HeaderType ht) +{ + checkParsed(); + delete mHeaders[ht]; + mHeaders[ht] = 0; +} + +Uri& +MessageWaitingContents::header(const AccountHeader& ht) +{ + checkParsed(); + + /* this is a trick to allow a const method to update "this" with an empty + Uri in case there wasn't a Message-Account line in the MessageWaiting doc + */ + if (mAccountUri == 0) + { + mAccountUri = new Uri(); + } + return *mAccountUri; +} + +const Uri& +MessageWaitingContents::header(const AccountHeader& ht) const +{ + checkParsed(); + + /* this is a trick to allow a const method to update "this" with an empty + Uri in case there wasn't a Message-Account line in the MessageWaiting doc + */ + if (mAccountUri == 0) + { + ErrLog(<< "You called " + "MessageWaitingContents::header(const AccountHeader& ht) _const_ " + "without first calling exists(), and the header does not exist. Our" + " behavior in this scenario is to implicitly create the header(using const_cast!); " + "this is probably not what you want, but it is either this or " + "assert/throw an exception. Since this has been the behavior for " + "so long, we are not throwing here, _yet_. You need to fix your " + "code, before we _do_ start throwing. This is why const-correctness" + " should never be made a TODO item </rant>"); + MessageWaitingContents* ncthis = const_cast<MessageWaitingContents*>(this); + ncthis->mAccountUri = new Uri(); + } + return *mAccountUri; +} + +bool +MessageWaitingContents::exists(const AccountHeader& ht) const +{ + checkParsed(); + return mAccountUri != 0; +} + +void +MessageWaitingContents::remove(const AccountHeader& ht) +{ + checkParsed(); + delete mAccountUri; + mAccountUri = 0; +} + +Data& +MessageWaitingContents::header(const Data& hn) +{ + checkParsed(); + return mExtensions[hn]; +} + +const Data& +MessageWaitingContents::header(const Data& hn) const +{ + checkParsed(); + std::map<Data, Data>::const_iterator h=mExtensions.find(hn); + if(h==mExtensions.end()) + { + ErrLog(<< "You called " + "MessageWaitingContents::header(const Data& hn) _const_ " + "without first calling exists(), and the header does not exist. Our" + " behavior in this scenario is to implicitly create the header(using const_cast!); " + "this is probably not what you want, but it is either this or " + "assert/throw an exception. Since this has been the behavior for " + "so long, we are not throwing here, _yet_. You need to fix your " + "code, before we _do_ start throwing. This is why const-correctness" + " should never be made a TODO item </rant>"); + MessageWaitingContents* ncthis = const_cast<MessageWaitingContents*>(this); + h=ncthis->mExtensions.insert(std::pair<Data, Data>(hn,Data::Empty)).first; + } + return h->second; +} + +bool +MessageWaitingContents::exists(const Data& hn) const +{ + checkParsed(); + return mExtensions.find(hn) != mExtensions.end(); +} + +void +MessageWaitingContents::remove(const Data& hn) +{ + checkParsed(); + mExtensions.erase(hn); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MessageWaitingContents.hxx b/src/libs/resiprocate/resip/stack/MessageWaitingContents.hxx new file mode 100644 index 00000000..d52e31dd --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MessageWaitingContents.hxx @@ -0,0 +1,282 @@ +#if !defined(RESIP_MESSAGEWAITINGCONTENTS_HXX) +#define RESIP_MESSAGEWAITINGCONTENTS_HXX + +#include <map> + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +const char* skipSipLWS(ParseBuffer& pb); + +/** @brief An enumeration of MessageWaiting header types for use with resip::MessageWaitingContents. + + Also see resip::mw_account to access the special Message-Account header for MessageWaiting. + **/ +typedef enum {mw_voice=0, mw_fax, mw_pager, mw_multimedia, mw_text, mw_none, MW_MAX} HeaderType; + +/** + @ingroup sip_payload + @brief SIP body type for holding MWI contents (MIME content-type application/simple-message-summary). + + See resip/stack/test/testMessageWaiting.cxx for usage examples. +*/ +class MessageWaitingContents : public Contents +{ + public: + MessageWaitingContents(); + MessageWaitingContents(const HeaderFieldValue& hfv, const Mime& contentType); + MessageWaitingContents(const Data& data, const Mime& contentType); + MessageWaitingContents(const MessageWaitingContents& rhs); + virtual ~MessageWaitingContents(); + MessageWaitingContents& operator=(const MessageWaitingContents& rhs); + + /** @brief duplicate an MessageWaitingContents object + @return pointer to a new MessageWaitingContents object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType() ; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + class Header; + + /** @brief Get the header correspoding to ht + @param ht HeaderType used to lookup MessageWaiting header + @return Header corresponding to ht + **/ + Header& header(HeaderType ht); + const Header& header(HeaderType ht) const; + + /** @brief Check if HeaderType is present + @param ht HeaderType used to lookup MessageWaiting header + @return bool true if HeaderType exists + **/ + bool exists(HeaderType ht) const; + + /** @brief Remove the header correspoding to ht + @param ht HeaderType used to remove from MessageWaiting header + **/ + void remove(HeaderType ht); + + /** @brief makes accessing the MessageAccount Uri + operate like accessing the other MessageWaiting headers. + + However, the user of these calls has to treat them differently + since the two header calls return different classes. + + @todo This is an awkward attempt to make accessing the MessageAccount Uri + operate like accessing the other MessageWaiting headers even though + the user of these calls has to treat them differently to being with + since the two header calls return different classes. ugh. .mjf. + **/ + class AccountHeader {}; + + /** @brief Get the Uri for Message-Account line + @param ht AccountHeader used to lookup MessageWaiting header - not really used computationally + @return Uri for Message-Account line + **/ + const Uri& header(const AccountHeader& ht) const; + Uri& header(const AccountHeader& ht); + + /** @brief Check if Message-Account line is present + @note This call only indicates the actual existence of the Message-Account + line in the MessageWaiting doc if header(mw_account) hasn't been called. + After that call the exists(mw_account) call will return true (since a + Uri now exists) whether or not the Uri was built based on the + MessageWaiting doc. + @param ht AccountHeader used to lookup MessageWaiting header - not really used computationally + @return bool true if HeaderType exists + **/ + bool exists(const AccountHeader& ht) const; + + /** @brief Remove the Uri for Message-Account line + @param ht AccountHeader used to lookup MessageWaiting header - not really used computationally + **/ + void remove(const AccountHeader& ht); + + /** @brief Get the value correspoding to optional message header hn in the MessageWaiting doc. + + Used to access optional message headers in the MessageWaiting doc + + @param hn HeaderType used to lookup the optional MessageWaiting header + @return Data corresponding to hn + **/ + const Data& header(const Data& hn) const; + Data& header(const Data& hn); + + /** @brief Check if optional message header hn is present + @param hn HeaderType used to lookup the optional MessageWaiting header + @return bool true if optional message header exists + **/ + bool exists(const Data& hn) const; + + /** @brief Remove the optional message header corresponding to hn + @param hn HeaderType used to lookup the optional MessageWaiting header + **/ + void remove(const Data& hn); + + /** @brief Check to see if there are messages + @return bool true if there are messages + **/ + bool& hasMessages() { checkParsed(); return mHasMessages; } + + /** @brief Provides an interface for reading and modifying MessageWaiting bodies. + **/ + class Header + { + public: + /** @brief Header constructor. + Create a Header using new count and old message counts. + @param numNew new message count + @param numOld old message count + **/ + Header(unsigned int numNew, + unsigned int numOld); + + /** @brief Header constructor with urgent counts. + Create a Header using new/old/urgent new/urgent old message counts. + @param numNew new message count + @param numOld old message count + @param numUrgentNew new urgent message count + @param numUrgentOld old urgent message count + **/ + Header(unsigned int numNew, + unsigned int numOld, + unsigned int numUrgentNew, + unsigned int numUrgentOld); + + /** @brief Return new message count + @return int new message count + **/ + const unsigned int& newCount() const {return mNew;} + + /** @brief Return new message count + @return int new message count + **/ + unsigned int& newCount() {return mNew;} + + /** @brief Return old message count + @return int new message count + **/ + const unsigned int& oldCount() const {return mOld;} + + /** @brief Return old message count + @return int new message count + **/ + unsigned int& oldCount() {return mOld;} + + /** @brief Return bool indicating that there are urgent messages + @note Currently this is only set during construction. Modification of the new and old urgent counts does not update this field. + @return bool true if there are urgent messages + **/ + const bool& urgent() const {return mHasUrgent;} + + /** @brief Return bool indicating that there are urgent messages + @note Currently this is only set during construction. Modification of the new and old urgent counts does not update this field. + @return bool true if there are urgent messages + **/ + bool& urgent() {return mHasUrgent;} + + /** @brief Return new urgent message count + @return int new message count + **/ + const unsigned int& urgentNewCount() const {return mUrgentNew;} + + /** @brief Return new urgent message count + @return int new message count + **/ + unsigned int& urgentNewCount() {return mUrgentNew;} + + /** @brief Return new message count + @return int new message count + **/ + const unsigned int& urgentOldCount() const {return mUrgentOld;} + + /** @brief Return new message count + @return int new message count + **/ + unsigned int& urgentOldCount() {return mUrgentOld;} + + private: + unsigned int mNew; + unsigned int mOld; + bool mHasUrgent; + unsigned int mUrgentNew; + unsigned int mUrgentOld; + + friend class MessageWaitingContents; + }; + + static bool init(); + private: + void clear(); + + bool mHasMessages; + Uri* mAccountUri; + Header* mHeaders[MW_MAX]; + std::map<Data, Data> mExtensions; +}; + +/** @brief Used to access the Message-Account header in MessageWaiting docs. + **/ +extern MessageWaitingContents::AccountHeader mw_account; +static bool invokeMessageWaitingContentsInit = MessageWaitingContents::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MethodHash.cxx b/src/libs/resiprocate/resip/stack/MethodHash.cxx new file mode 100644 index 00000000..3006778a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MethodHash.cxx @@ -0,0 +1,194 @@ +/* C++ code produced by gperf version 3.0.4 */ +/* Command-line: gperf -C -D -E -L C++ -t -k '*' --compare-strncmp -Z MethodHash MethodHash.gperf */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>." +#endif + +#line 1 "MethodHash.gperf" + +#include <string.h> +#include <ctype.h> +#include "resip/stack/MethodTypes.hxx" + +namespace resip +{ +#line 9 "MethodHash.gperf" +struct methods { const char *name; MethodTypes type; }; +/* maximum key range = 31, duplicates = 0 */ + +class MethodHash +{ +private: + static inline unsigned int hash (const char *str, unsigned int len); +public: + static const struct methods *in_word_set (const char *str, unsigned int len); +}; + +inline unsigned int +MethodHash::hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 5, 10, 5, 5, 0, + 0, 15, 0, 0, 35, 0, 0, 0, 0, 0, + 0, 35, 0, 0, 0, 0, 0, 35, 35, 5, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + hval += asso_values[(unsigned char)str[1]]; + /*FALLTHROUGH*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval; +} + +const struct methods * +MethodHash::in_word_set (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 16, + MIN_WORD_LENGTH = 3, + MAX_WORD_LENGTH = 9, + MIN_HASH_VALUE = 4, + MAX_HASH_VALUE = 34 + }; + + static const struct methods wordlist[] = + { +#line 24 "MethodHash.gperf" + {"INFO", INFO}, +#line 19 "MethodHash.gperf" + {"REFER", REFER}, +#line 14 "MethodHash.gperf" + {"INVITE", INVITE}, +#line 16 "MethodHash.gperf" + {"OPTIONS", OPTIONS}, +#line 22 "MethodHash.gperf" + {"RESPONSE", RESPONSE}, +#line 15 "MethodHash.gperf" + {"NOTIFY", NOTIFY}, +#line 25 "MethodHash.gperf" + {"SERVICE", SERVICE}, +#line 11 "MethodHash.gperf" + {"ACK", ACK}, +#line 17 "MethodHash.gperf" + {"PRACK", PRACK}, +#line 26 "MethodHash.gperf" + {"UPDATE", UPDATE}, +#line 18 "MethodHash.gperf" + {"PUBLISH", PUBLISH}, +#line 12 "MethodHash.gperf" + {"BYE", BYE}, +#line 13 "MethodHash.gperf" + {"CANCEL", CANCEL}, +#line 20 "MethodHash.gperf" + {"REGISTER", REGISTER}, +#line 23 "MethodHash.gperf" + {"MESSAGE", MESSAGE}, +#line 21 "MethodHash.gperf" + {"SUBSCRIBE", SUBSCRIBE} + }; + + static const signed char lookup[] = + { + -1, -1, -1, -1, 0, 1, 2, 3, 4, -1, -1, 5, 6, 7, + -1, 8, 9, 10, 11, -1, -1, 12, -1, 13, -1, -1, -1, 14, + -1, -1, -1, -1, -1, -1, 15 + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int index = lookup[key]; + + if (index >= 0) + { + register const char *s = wordlist[index].name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist[index]; + } + } + } + return 0; +} +#line 27 "MethodHash.gperf" + +} diff --git a/src/libs/resiprocate/resip/stack/MethodHash.gperf b/src/libs/resiprocate/resip/stack/MethodHash.gperf new file mode 100644 index 00000000..f665501d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MethodHash.gperf @@ -0,0 +1,28 @@ +%{ +#include <string.h> +#include <ctype.h> +#include "resip/stack/MethodTypes.hxx" + +namespace resip +{ +%} +struct methods { const char *name; MethodTypes type; }; +%% +ACK, ACK +BYE, BYE +CANCEL, CANCEL +INVITE, INVITE +NOTIFY, NOTIFY +OPTIONS, OPTIONS +PRACK, PRACK +PUBLISH, PUBLISH +REFER, REFER +REGISTER, REGISTER +SUBSCRIBE, SUBSCRIBE +RESPONSE, RESPONSE +MESSAGE, MESSAGE +INFO, INFO +SERVICE, SERVICE +UPDATE, UPDATE +%% +} diff --git a/src/libs/resiprocate/resip/stack/MethodHash.hxx b/src/libs/resiprocate/resip/stack/MethodHash.hxx new file mode 100644 index 00000000..15e23bbc --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MethodHash.hxx @@ -0,0 +1,69 @@ +#if !defined(RESIP_METHODSHASH_HXX) +#define RESIP_METHODSHASH_HXX +namespace resip +{ + +struct methods { char *name; MethodTypes type; }; +/* maximum key range = 494, duplicates = 0 */ + +class MethodHash +{ +private: + static inline unsigned int hash (const char *str, unsigned int len); +public: + static const struct methods *in_word_set (const char *str, unsigned int len); +}; +// NOTE the cxx file for this class is AUTO GENERATED. DO NOT EDIT IT. +// This file should match it. BUT THIS FILE IS MANUALLY GENERATED. +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MethodTypes.cxx b/src/libs/resiprocate/resip/stack/MethodTypes.cxx new file mode 100644 index 00000000..0078bad6 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MethodTypes.cxx @@ -0,0 +1,128 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <string.h> +#include <cstdio> +#include <cassert> + +#include "resip/stack/MethodTypes.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/Data.hxx" + +using namespace resip; + +#define defineMethod(_enum, _name, _rfc) _name + +// !dlb! this file will be subsumed by MethodHash.cxx on auto-generate +// move into MethodHash.cxx -- generated from MethodTypes.hxx -- !ah! indeed, yuck! +namespace resip{ + +Data MethodNames[] = +{ + defineMethod(UNKNOWN, "UNKNOWN", "NA"), + defineMethod(ACK, "ACK", "RFC ????"), + defineMethod(BYE, "BYE", "RFC ????"), + defineMethod(CANCEL, "CANCEL", "RFC ????"), + defineMethod(INVITE, "INVITE", "RFC ????"), + defineMethod(NOTIFY, "NOTIFY", "RFC ????"), + defineMethod(OPTIONS, "OPTIONS", "RFC ????"), + defineMethod(REFER, "REFER", "RFC ????"), + defineMethod(REGISTER, "REGISTER", "RFC ????"), + defineMethod(SUBSCRIBE, "SUBSCRIBE", "RFC ????"), + defineMethod(RESPONSE, "RESPONSE", "RFC ????"), + defineMethod(MESSAGE, "MESSAGE", "RFC ????"), + defineMethod(INFO, "INFO", "RFC ????"), + defineMethod(PRACK, "PRACK", "RFC ????"), + defineMethod(PUBLISH, "PUBLISH", "RFC ????"), + defineMethod(SERVICE, "SERVICE", "!RFC"), + defineMethod(UPDATE,"UPDATE", "RFC ????") +}; +} +#include "MethodHash.hxx" + +const Data& +resip::getMethodName(MethodTypes t) +{ + if (t < UNKNOWN || t >= MAX_METHODS) + t=UNKNOWN; + return MethodNames[t]; +} + +MethodTypes +resip::getMethodType(const Data& name) +{ + // note: use data to prevent copying shared data + return getMethodType(name.data(), (int)name.size()); +} + +MethodTypes +resip::getMethodType(const char* name, int len) +{ + const struct methods* m = MethodHash::in_word_set(name, len); + return m ? m->type : UNKNOWN; +} + +// ?dlb? why aren't we using the lib strncasecmp? +int strncasecmp(const char* a, const char* b, int len) +{ + //!ah! whoever implemented this should be shot. + //!ah! should use library based strncasecmp() ! + //!ah! have fixed it up a bit. + for (int i = 0; i < len; i++) + { + int c = tolower(a[i]) - tolower(b[i]); + if (c) return c; + } + return 0; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MethodTypes.hxx b/src/libs/resiprocate/resip/stack/MethodTypes.hxx new file mode 100644 index 00000000..9ca912d9 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MethodTypes.hxx @@ -0,0 +1,103 @@ +#if !defined(RESIP_METHODTYPES_HXX) +#define RESIP_METHODTYPES_HXX + +#define defineMethod(_enum, _name, _rfc) _enum +namespace resip +{ + +class Data; + +#ifdef __BORLANDC__ + #undef MESSAGE +#endif + +typedef enum +{ + defineMethod(UNKNOWN, "UNKNOWN", "NA"), + defineMethod(ACK, "ACK", " RFC 3261"), + defineMethod(BYE, "BYE", "RFC 3261"), + defineMethod(CANCEL, "CANCEL", "RFC 3261"), + defineMethod(INVITE, "INVITE", "RFC 3261"), + defineMethod(NOTIFY, "NOTIFY", "RFC 3265"), + defineMethod(OPTIONS, "OPTIONS", "RFC 3261"), + defineMethod(REFER, "REFER", "RFC 3515"), + defineMethod(REGISTER, "REGISTER", "RFC 3261"), + defineMethod(SUBSCRIBE, "SUBSCRIBE", "RFC 3265"), + defineMethod(RESPONSE, "RESPONSE", "RFC ????"), + defineMethod(MESSAGE, "MESSAGE", "RFC ????"), + //_MESSAGE, + defineMethod(INFO, "INFO", "RFC 2976"), + defineMethod(PRACK, "PRACK", "RFC 3262"), + defineMethod(PUBLISH, "PUBLISH", "RFC draft"), + defineMethod(SERVICE, "SERVICE", "!RFC"), + defineMethod(UPDATE, "UPDATE", "RFC 3311"), + MAX_METHODS +} MethodTypes; + +// extern Data MethodNames[]; // !ah! Do not touch. want a name, call getMethodName() + +MethodTypes +getMethodType(const Data& name); + +MethodTypes +getMethodType(const char* name, int len); + +// TODO -- !dcm! -- fix to return unknown method as a string +const Data& +getMethodName(MethodTypes t); + +} + +#undef defineMethod + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Mime.cxx b/src/libs/resiprocate/resip/stack/Mime.cxx new file mode 100644 index 00000000..2097483d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Mime.cxx @@ -0,0 +1,291 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Mime.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// MIME +//==================== +Mime::Mime() + : ParserCategory(), + mType(), + mSubType() +{} + +Mime::Mime(const Data& type, const Data& subType) + : ParserCategory(), + mType(type), + mSubType(subType) +{} + +Mime::Mime(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), + mType(), + mSubType() +{} + +Mime::Mime(const Mime& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mType(rhs.mType), + mSubType(rhs.mSubType) +{} + +Mime& +Mime::operator=(const Mime& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mType = rhs.mType; + mSubType = rhs.mSubType; + } + return *this; +} + +bool +Mime::operator<(const Mime& rhs) const +{ + if (isLessThanNoCase(type(), rhs.type())) + { + return true; + } + else if (isLessThanNoCase(rhs.type(), type())) + { + return false; + } + return isLessThanNoCase(subType(), rhs.subType()); +} + +bool +Mime::isEqual(const Mime& rhs) const +{ + return (isEqualNoCase(type(), rhs.type()) && + isEqualNoCase(subType(), rhs.subType())); +} + +bool +Mime::operator==(const Mime& rhs) const +{ + return (isEqualNoCase(type(), rhs.type()) && + isEqualNoCase(subType(), rhs.subType())); +} + +bool +Mime::operator!=(const Mime& rhs) const +{ + return !(*this == rhs); +} + +const Data& +Mime::type() const +{ + checkParsed(); + return mType; +} + +const Data& Mime::subType() const +{ + checkParsed(); + return mSubType; +} + +Data& +Mime::type() +{ + checkParsed(); + return mType; +} + +Data& Mime::subType() +{ + checkParsed(); + return mSubType; +} + +void +Mime::parse(ParseBuffer& pb) +{ + const char* anchor = pb.skipWhitespace(); + static std::bitset<256> delimiter1=Data::toBitset("\r\n\t /"); + pb.skipToOneOf(delimiter1); + pb.data(mType, anchor); + + pb.skipWhitespace(); + pb.skipChar(Symbols::SLASH[0]); + + anchor = pb.skipWhitespace(); + static std::bitset<256> delimiter2=Data::toBitset("\r\n\t ;"); + pb.skipToOneOf(delimiter2); + pb.data(mSubType, anchor); + + pb.skipWhitespace(); + parseParameters(pb); +} + +ParserCategory* +Mime::clone() const +{ + return new Mime(*this); +} + +ParserCategory* +Mime::clone(void* location) const +{ + return new (location) Mime(*this); +} + +ParserCategory* +Mime::clone(PoolBase* pool) const +{ + return new (pool) Mime(*this, pool); +} + +EncodeStream& +Mime::encodeParsed(EncodeStream& str) const +{ + str << mType << Symbols::SLASH << mSubType ; + encodeParameters(str); + return str; +} + +ParameterTypes::Factory Mime::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; + +Parameter* +Mime::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) +{ + if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) + { + return ParameterFactories[type](type, pb, terminators, pool); + } + return 0; +} + +bool +Mime::exists(const Param<Mime>& paramType) const +{ + checkParsed(); + bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; + return ret; +} + +void +Mime::remove(const Param<Mime>& paramType) +{ + checkParsed(); + removeParameterByEnum(paramType.getTypeNum()); +} + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ +_enum##_Param::DType& \ +Mime::param(const _enum##_Param& paramType) \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + p = new _enum##_Param::Type(paramType.getTypeNum()); \ + mParameters.push_back(p); \ + } \ + return p->value(); \ +} \ + \ +const _enum##_Param::DType& \ +Mime::param(const _enum##_Param& paramType) const \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ + DebugLog(<< *this); \ + throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ + } \ + return p->value(); \ +} + +defineParam(accessType, "access-type", DataParameter, "RFC 2046"); +defineParam(boundary, "boundary", DataParameter, "RFC 2046"); +defineParam(charset, "charset", DataParameter, "RFC 2045"); +defineParam(directory, "directory", DataParameter, "RFC 2046"); +defineParam(expiration, "expiration", QuotedDataParameter, "RFC 2046"); +defineParam(micalg, "micalg", DataParameter, "RFC 1847"); +defineParam(mode, "mode", DataParameter, "RFC 2046"); +defineParam(name, "name", DataParameter, "RFC 2046"); +defineParam(permission, "permission", DataParameter, "RFC 2046"); +defineParam(protocol, "protocol", QuotedDataParameter, "RFC 1847"); +defineParam(q, "q", QValueParameter, "RFC 3261"); +defineParam(server, "server", DataParameter, "RFC 2046"); +defineParam(site, "site", DataParameter, "RFC 2046"); +defineParam(size, "size", DataParameter, "RFC 2046"); +defineParam(smimeType, "smime-type", DataParameter, "RFC 2633"); +defineParam(url, "url", QuotedDataParameter, "RFC 4483"); + +#undef defineParam + +HashValueImp(resip::Mime, data.type().caseInsensitiveTokenHash() ^ data.subType().caseInsensitiveTokenHash()); + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Mime.hxx b/src/libs/resiprocate/resip/stack/Mime.hxx new file mode 100644 index 00000000..9b05afbd --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Mime.hxx @@ -0,0 +1,146 @@ +#if !defined(RESIP_MIME_HXX) +#define RESIP_MIME_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "rutil/HashMap.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/ParserContainer.hxx" + +namespace resip +{ + +class HeaderFieldValue; + +/** + @ingroup sip_grammar + @brief Represents the "media-type" element in the RFC 3261 grammar. +*/ +class Mime : public ParserCategory +{ + public: + enum {commaHandling = CommasAllowedOutputCommas}; + + Mime(); + Mime(const Data& type, const Data& subType); + Mime(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + Mime(const Mime& orig, + PoolBase* pool=0); + Mime& operator=(const Mime&); + bool operator<(const Mime& rhs) const; + bool isEqual(const Mime& rhs) const; + bool operator==(const Mime& rhs) const; + bool operator!=(const Mime& rhs) const; + + const Data& type() const; + const Data& subType() const; + Data& type(); + Data& subType(); + + virtual void parse(ParseBuffer& pb); + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + + // Inform the compiler that overloads of these may be found in + // ParserCategory, too. + using ParserCategory::exists; + using ParserCategory::remove; + using ParserCategory::param; + + virtual Parameter* createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool); + bool exists(const Param<Mime>& paramType) const; + void remove(const Param<Mime>& paramType); + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ + const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \ + _enum##_Param::DType& param(const _enum##_Param& paramType); \ + friend class _enum##_Param + + defineParam(accessType, "access-type", DataParameter, "RFC 2046"); + defineParam(boundary, "boundary", DataParameter, "RFC 2046"); + defineParam(charset, "charset", DataParameter, "RFC 2045"); + defineParam(directory, "directory", DataParameter, "RFC 2046"); + defineParam(expiration, "expiration", QuotedDataParameter, "RFC 2046"); + defineParam(micalg, "micalg", DataParameter, "RFC 1847"); + defineParam(mode, "mode", DataParameter, "RFC 2046"); + defineParam(name, "name", DataParameter, "RFC 2046"); + defineParam(permission, "permission", DataParameter, "RFC 2046"); + defineParam(protocol, "protocol", QuotedDataParameter, "RFC 1847"); + defineParam(q, "q", QValueParameter, "RFC 3261"); + defineParam(server, "server", DataParameter, "RFC 2046"); + defineParam(site, "site", DataParameter, "RFC 2046"); + defineParam(size, "size", DataParameter, "RFC 2046"); + defineParam(smimeType, "smime-type", DataParameter, "RFC 2633"); + defineParam(url, "url", QuotedDataParameter, "RFC 4483"); + +#undef defineParam + + private: + Data mType; + Data mSubType; + + static ParameterTypes::Factory ParameterFactories[ParameterTypes::MAX_PARAMETER]; +}; +typedef ParserContainer<Mime> Mimes; + +} + + +HashValue(resip::Mime); + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MsgHeaderScanner.cxx b/src/libs/resiprocate/resip/stack/MsgHeaderScanner.cxx new file mode 100644 index 00000000..5f5193c5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MsgHeaderScanner.cxx @@ -0,0 +1,1166 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <ctype.h> +#include <limits.h> +#include <stdio.h> +#include "resip/stack/HeaderTypes.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/MsgHeaderScanner.hxx" +#include "rutil/WinLeakCheck.hxx" + +namespace resip +{ + +/////////////////////////////////////////////////////////////////////////////// +// Any character could be used as the chunk terminating sentinel, as long as +// it would otherwise be character category "other". The null character +// was chosen because it is unlikely to occur naturally -- but it's OK if it +// does. + +enum { chunkTermSentinelChar = '\0' }; + +enum CharCategoryEnum +{ + ccChunkTermSentinel, + ccOther, + ccFieldName, + ccWhitespace, + ccColon, + ccDoubleQuotationMark, + ccLeftAngleBracket, + ccRightAngleBracket, + ccBackslash, + ccComma, + ccCarriageReturn, + ccLineFeed, + numCharCategories +}; +typedef char CharCategory; + +char* +MsgHeaderScanner::allocateBuffer(int size) +{ + return new char[size + MaxNumCharsChunkOverflow]; +} + +struct CharInfo +{ + CharCategory category; + MsgHeaderScanner::TextPropBitMask textPropBitMask; +}; + +static CharInfo charInfoArray[UCHAR_MAX+1]; + +static inline int c2i(unsigned char c) +{ + return static_cast<int>(c); +} + +static void initCharInfoArray() +{ + for(unsigned int charIndex = 0; charIndex <= UCHAR_MAX; ++charIndex) + { + charInfoArray[charIndex].category = ccOther; + charInfoArray[charIndex].textPropBitMask = 0; + } + + for(const char *charPtr = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.!%*_+`'~"; + *charPtr; + ++charPtr) + { + charInfoArray[c2i(*charPtr)].category = ccFieldName; + } + + charInfoArray[c2i(' ')].category = ccWhitespace; + charInfoArray[c2i('\t')].category = ccWhitespace; + charInfoArray[c2i(':')].category = ccColon; + charInfoArray[c2i('"')].category = ccDoubleQuotationMark; + charInfoArray[c2i('<')].category = ccLeftAngleBracket; + charInfoArray[c2i('>')].category = ccRightAngleBracket; + charInfoArray[c2i('\\')].category = ccBackslash; + charInfoArray[c2i(',')].category = ccComma; + charInfoArray[c2i('\r')].category = ccCarriageReturn; + charInfoArray[c2i('\n')].category = ccLineFeed; + // Assert: "chunkTermSentinelChar"'s category is still the default "ccOther". + charInfoArray[c2i(chunkTermSentinelChar)].category = ccChunkTermSentinel; + // Init text property bit masks. + charInfoArray[c2i('\r')].textPropBitMask = + MsgHeaderScanner::tpbmContainsLineBreak; + charInfoArray[c2i('\n')].textPropBitMask = + MsgHeaderScanner::tpbmContainsLineBreak; + charInfoArray[c2i(' ')].textPropBitMask = + MsgHeaderScanner::tpbmContainsWhitespace; + charInfoArray[c2i('\t')].textPropBitMask = + MsgHeaderScanner::tpbmContainsWhitespace; + charInfoArray[c2i('\\')].textPropBitMask = + MsgHeaderScanner::tpbmContainsBackslash; + charInfoArray[c2i('%')].textPropBitMask = + MsgHeaderScanner::tpbmContainsPercent; + charInfoArray[c2i(';')].textPropBitMask = + MsgHeaderScanner::tpbmContainsSemicolon; + charInfoArray[c2i('(')].textPropBitMask = + MsgHeaderScanner::tpbmContainsParen; + charInfoArray[c2i(')')].textPropBitMask = + MsgHeaderScanner::tpbmContainsParen; +} + +/////////////////////////////////////////////////////////////////////////////// +// States marked '1' scan normal values. States marked 'N' scan multi-values. + +enum StateEnum +{ + sMsgStart, + sHalfLineBreakAtMsgStart, + sScanStatusLine, + sHalfLineBreakAfterStatusLine, + sAfterLineBreakAfterStatusLine, + sScanFieldName, + sScanWhitespaceAfter1FieldName, + sScanWhitespaceAfterNFieldName, + sScanWhitespaceOr1Value, + sScanWhitespaceOrNValue, + sHalfLineBreakInWhitespaceBefore1Value, + sHalfLineBreakInWhitespaceBeforeNValue, + sAfterLineBreakInWhitespaceBefore1Value, + sAfterLineBreakInWhitespaceBeforeNValue, + sScan1Value, + sScanNValue, + sHalfLineBreakIn1Value, + sHalfLineBreakInNValue, + sAfterLineBreakIn1Value, + sAfterLineBreakInNValue, + sScanNValueInQuotes, + sAfterEscCharInQuotesInNValue, + sHalfLineBreakInQuotesInNValue, + sAfterLineBreakInQuotesInNValue, + sScanNValueInAngles, + sHalfLineBreakInAnglesInNValue, + sAfterLineBreakInAnglesInNValue, + sHalfLineBreakAfterLineBreak, + numStates +}; + +typedef char State; + +// For each '1' state, the 'N' state is "deltaOfNStateFrom1State" larger. +enum { deltaOfNStateFrom1State = 1 }; + +///// + +enum TransitionActionEnum { + taNone, + taTermStatusLine, // The current character terminates the status + // line. + taTermFieldName, // The current character terminates a field name. + // If the field supports multi-values, shift + // the state machine into multi-value scanning. + taBeyondEmptyValue, // The current character terminates an empty value. + // Implies taStartText. + taTermValueAfterLineBreak, + // The previous two characters are a linebreak + // terminating a value. Implies taStartText. + taTermValue, // The current character terminates a value. + taStartText, // The current character starts a text unit. + // (The status line, a field name, or a value.) + taEndHeader, // The current character mEnds_ the header. + taChunkTermSentinel, // Either the current character terminates the + // current chunk or it is an ordinary character. + taError // The input is erroneous. +}; +typedef char TransitionAction; + + +struct TransitionInfo +{ + TransitionAction action; + State nextState; +}; + +static TransitionInfo stateMachine[numStates][numCharCategories]; + +inline void specTransition(State state, + CharCategory charCategory, + TransitionAction action, + State nextState) +{ + stateMachine[c2i(state)][c2i(charCategory)].action = action; + stateMachine[c2i(state)][c2i(charCategory)].nextState = nextState; +} + +static void specDefaultTransition(State state, + TransitionAction action, + State nextState) +{ + for (int charCategory = 0; + charCategory < numCharCategories; + ++charCategory) + { + specTransition(state, charCategory, action, nextState); + } + specTransition(state, ccCarriageReturn, taError, state); + specTransition(state, ccLineFeed, taError, state); + specTransition(state, ccChunkTermSentinel, taChunkTermSentinel, state); +} + +static void specHalfLineBreakState(State halfLineBreakState, + State afterLineBreakState) +{ + specDefaultTransition(halfLineBreakState, taError, halfLineBreakState); + specTransition(halfLineBreakState, ccLineFeed, taNone, afterLineBreakState); +} + + +// Single-value (1) scanning and multi-value (N) scanning involves several nearly +// identical states. +// "stateDelta" is either 0 or "deltaOfNStateFrom1State". + +static void specXValueStates(int stateDelta) +{ + specDefaultTransition(sScanWhitespaceAfter1FieldName + stateDelta, + taError, + sScanWhitespaceAfter1FieldName + stateDelta); + specTransition(sScanWhitespaceAfter1FieldName + stateDelta, + ccWhitespace, + taNone, + sScanWhitespaceAfter1FieldName + stateDelta); + specTransition(sScanWhitespaceAfter1FieldName + stateDelta, + ccColon, + taNone, + sScanWhitespaceOr1Value + stateDelta); + specDefaultTransition(sScanWhitespaceOr1Value + stateDelta, + taStartText, + sScan1Value + stateDelta); + specTransition(sScanWhitespaceOr1Value + stateDelta, + ccWhitespace, + taNone, + sScanWhitespaceOr1Value + stateDelta); + if (stateDelta == deltaOfNStateFrom1State) + { + specTransition(sScanWhitespaceOr1Value + stateDelta, + ccComma, + taError, + sScanWhitespaceOr1Value + stateDelta); + specTransition(sScanWhitespaceOr1Value + stateDelta, + ccLeftAngleBracket, + taStartText, + sScanNValueInAngles); + specTransition(sScanWhitespaceOr1Value + stateDelta, + ccDoubleQuotationMark, + taStartText, + sScanNValueInQuotes); + } + specTransition(sScanWhitespaceOr1Value + stateDelta, + ccCarriageReturn, + taNone, + sHalfLineBreakInWhitespaceBefore1Value + stateDelta); + specHalfLineBreakState(sHalfLineBreakInWhitespaceBefore1Value + stateDelta, + sAfterLineBreakInWhitespaceBefore1Value + stateDelta); + specDefaultTransition(sAfterLineBreakInWhitespaceBefore1Value + stateDelta, + taError, + sAfterLineBreakInWhitespaceBefore1Value + stateDelta); + specTransition(sAfterLineBreakInWhitespaceBefore1Value + stateDelta, + ccFieldName, + taBeyondEmptyValue, + sScanFieldName); + specTransition(sAfterLineBreakInWhitespaceBefore1Value + stateDelta, + ccWhitespace, + taNone, + sScanWhitespaceOr1Value + stateDelta); + specTransition(sAfterLineBreakInWhitespaceBefore1Value + stateDelta, + ccCarriageReturn, + taBeyondEmptyValue, + sHalfLineBreakAfterLineBreak); + specDefaultTransition(sScan1Value + stateDelta, + taNone, + sScan1Value + stateDelta); + if (stateDelta == deltaOfNStateFrom1State) + { + specTransition(sScan1Value + stateDelta, + ccComma, + taTermValue, + sScanWhitespaceOr1Value + stateDelta); + specTransition(sScan1Value + stateDelta, + ccLeftAngleBracket, + taNone, + sScanNValueInAngles); + specTransition(sScan1Value + stateDelta, + ccDoubleQuotationMark, + taNone, + sScanNValueInQuotes); + } + specTransition(sScan1Value + stateDelta, + ccCarriageReturn, + taNone, + sHalfLineBreakIn1Value + stateDelta); + specHalfLineBreakState(sHalfLineBreakIn1Value + stateDelta, + sAfterLineBreakIn1Value + stateDelta); + specDefaultTransition(sAfterLineBreakIn1Value + stateDelta, + taError, + sAfterLineBreakIn1Value + stateDelta); + specTransition(sAfterLineBreakIn1Value + stateDelta, + ccFieldName, + taTermValueAfterLineBreak, + sScanFieldName); + specTransition(sAfterLineBreakIn1Value + stateDelta, + ccWhitespace, + taNone, + sScan1Value + stateDelta); + specTransition(sAfterLineBreakIn1Value + stateDelta, + ccCarriageReturn, + taTermValueAfterLineBreak, + sHalfLineBreakAfterLineBreak); +} + +static void initStateMachine() +{ + // By convention, error transitions maintain the same state. + specDefaultTransition(sMsgStart, taStartText, sScanStatusLine); + specTransition(sMsgStart, + ccCarriageReturn, + taNone, + sHalfLineBreakAtMsgStart); + specTransition(sMsgStart, ccLineFeed, taError, sMsgStart); + specHalfLineBreakState(sHalfLineBreakAtMsgStart, sMsgStart); + specDefaultTransition(sScanStatusLine, taNone, sScanStatusLine); + specTransition(sScanStatusLine, + ccCarriageReturn, + taTermStatusLine, + sHalfLineBreakAfterStatusLine); + specHalfLineBreakState(sHalfLineBreakAfterStatusLine, + sAfterLineBreakAfterStatusLine); + specDefaultTransition(sAfterLineBreakAfterStatusLine, + taError, + sAfterLineBreakAfterStatusLine); + specTransition(sAfterLineBreakAfterStatusLine, + ccFieldName, + taStartText, + sScanFieldName); + specTransition(sAfterLineBreakAfterStatusLine, + ccWhitespace, + taError, + sAfterLineBreakAfterStatusLine); + specTransition(sAfterLineBreakAfterStatusLine, + ccCarriageReturn, + taNone, + sHalfLineBreakAfterLineBreak); + specDefaultTransition(sScanFieldName, taError, sScanFieldName); + specTransition(sScanFieldName, ccFieldName, taNone, sScanFieldName); + specTransition(sScanFieldName, + ccWhitespace, + taTermFieldName, + sScanWhitespaceAfter1FieldName); + specTransition(sScanFieldName, + ccColon, + taTermFieldName, + sScanWhitespaceOr1Value); + specXValueStates(0); + specXValueStates(deltaOfNStateFrom1State); + specDefaultTransition(sScanNValueInQuotes, taNone, sScanNValueInQuotes); + specTransition(sScanNValueInQuotes, + ccDoubleQuotationMark, + taNone, + sScanNValue); + specTransition(sScanNValueInQuotes, + ccBackslash, + taNone, + sAfterEscCharInQuotesInNValue); + specTransition(sScanNValueInQuotes, + ccCarriageReturn, + taNone, + sHalfLineBreakInQuotesInNValue); + specDefaultTransition(sAfterEscCharInQuotesInNValue, + taNone, + sScanNValueInQuotes); + specHalfLineBreakState(sHalfLineBreakInQuotesInNValue, + sAfterLineBreakInQuotesInNValue); + specDefaultTransition(sAfterLineBreakInQuotesInNValue, + taError, + sAfterLineBreakInQuotesInNValue); + specTransition(sAfterLineBreakInQuotesInNValue, + ccWhitespace, + taNone, + sScanNValueInQuotes); + specDefaultTransition(sScanNValueInAngles, taNone, sScanNValueInAngles); + specTransition(sScanNValueInAngles, + ccRightAngleBracket, + taNone, + sScanNValue); + specTransition(sScanNValueInAngles, + ccCarriageReturn, + taNone, + sHalfLineBreakInAnglesInNValue); + specHalfLineBreakState(sHalfLineBreakInAnglesInNValue, + sAfterLineBreakInAnglesInNValue); + specDefaultTransition(sAfterLineBreakInAnglesInNValue, + taError, + sAfterLineBreakInAnglesInNValue); + specTransition(sAfterLineBreakInAnglesInNValue, + ccWhitespace, + taNone, + sScanNValueInAngles); + specHalfLineBreakState(sHalfLineBreakAfterLineBreak, sMsgStart); + + // Most half-line-break states do nothing when they read a line feed, + // but sHalfLineBreakAfterLineBreak must end the message header scanning. + + specTransition(sHalfLineBreakAfterLineBreak, + ccLineFeed, + taEndHeader, + sMsgStart); // Arbitrary but possibly handy. +} + +// Debug follows +#if defined(RESIP_MSG_HEADER_SCANNER_DEBUG) + +static void printText(const char * text, + unsigned int textLength) +{ + const char *charPtr = text; + for (unsigned int counter = 0; counter < textLength; ++charPtr, ++counter) + { + char c = *charPtr; + switch (c) + { + case '\\': printf("\\\\"); + break; + case '\r': printf("\\r"); + break; + case '\n': printf("\\n"); + break; + case '\t': printf("\\t"); + break; + case '\0': printf("\\0"); + break; + default: putchar(c); + } + } +} + +static const char * +categorySymbol(CharCategory c) +{ + switch(c) + { + case ccChunkTermSentinel: return "TERM"; + case ccOther: return "*"; + case ccFieldName: return "FName"; + case ccWhitespace: return "WS"; + case ccColon: return "\\\":\\\""; + case ccDoubleQuotationMark: return "\\\""; + case ccLeftAngleBracket: return "\\\"<\\\""; + case ccRightAngleBracket: return "\\\">\\\""; + case ccBackslash: return "\\\"\\\\\\\""; + case ccComma: return "\\\",\\\""; + case ccCarriageReturn: return "CR"; + case ccLineFeed: return "LF"; + } + return "??CC??"; +} + +static const char * +categoryName(CharCategory c) +{ + switch(c) + { + case ccChunkTermSentinel: return "ccChunkTermSentinel"; + case ccOther: return "ccOther"; + case ccFieldName: return "ccFieldName"; + case ccWhitespace: return "ccWhitespace"; + case ccColon: return "ccColon"; + case ccDoubleQuotationMark: return "ccDoubleQuotationMark"; + case ccLeftAngleBracket: return "ccLeftAngleBracket"; + case ccRightAngleBracket: return "ccRightAngleBracket"; + case ccBackslash: return "ccBackslash"; + case ccComma: return "ccComma"; + case ccCarriageReturn: return "ccCarriageReturn"; + case ccLineFeed: return "ccLineFeed"; + } + return "UNKNOWNCC"; +} + +static const char * +cleanName(const char * name) +{ + // Remove leading type-noise from name + static char *leaders[] = { + "cc", + "s", + "taChunkTerm", // hack to make ChunkTermSentinel smaller + "ta" + }; + const int nLeaders = sizeof(leaders)/sizeof(*leaders); + int offset = 0; + for(int i = 0 ; i < nLeaders ; i++) + { + unsigned int l = strlen(leaders[i]); + if (strstr(name,leaders[i]) == name && + strlen(name) > l && + isupper(name[l])) + { + offset = l; + break; + } + } + return &name[offset]; +} + +static const char * +stateName(State state) +{ + const char *stateName; + switch (state) + { + case sMsgStart: + stateName = "sMsgStart"; + break; + case sHalfLineBreakAtMsgStart: + stateName = "sHalfLineBreakAtMsgStart"; + break; + case sScanStatusLine: + stateName = "sScanStatusLine"; + break; + case sHalfLineBreakAfterStatusLine: + stateName = "sHalfLineBreakAfterStatusLine"; + break; + case sAfterLineBreakAfterStatusLine: + stateName = "sAfterLineBreakAfterStatusLine"; + break; + case sScanFieldName: + stateName = "sScanFieldName"; + break; + case sScanWhitespaceAfter1FieldName: + stateName = "sScanWhitespaceAfter1FieldName"; + break; + case sScanWhitespaceAfterNFieldName: + stateName = "sScanWhitespaceAfterNFieldName"; + break; + case sScanWhitespaceOr1Value: + stateName = "sScanWhitespaceOr1Value"; + break; + case sScanWhitespaceOrNValue: + stateName = "sScanWhitespaceOrNValue"; + break; + case sHalfLineBreakInWhitespaceBefore1Value: + stateName = "sHalfLineBreakInWhitespaceBefore1Value"; + break; + case sHalfLineBreakInWhitespaceBeforeNValue: + stateName = "sHalfLineBreakInWhitespaceBeforeNValue"; + break; + case sAfterLineBreakInWhitespaceBefore1Value: + stateName = "sAfterLineBreakInWhitespaceBefore1Value"; + break; + case sAfterLineBreakInWhitespaceBeforeNValue: + stateName = "sAfterLineBreakInWhitespaceBeforeNValue"; + break; + case sScan1Value: + stateName = "sScan1Value"; + break; + case sScanNValue: + stateName = "sScanNValue"; + break; + case sHalfLineBreakIn1Value: + stateName = "sHalfLineBreakIn1Value"; + break; + case sHalfLineBreakInNValue: + stateName = "sHalfLineBreakInNValue"; + break; + case sAfterLineBreakIn1Value: + stateName = "sAfterLineBreakIn1Value"; + break; + case sAfterLineBreakInNValue: + stateName = "sAfterLineBreakInNValue"; + break; + case sScanNValueInQuotes: + stateName = "sScanNValueInQuotes"; + break; + case sAfterEscCharInQuotesInNValue: + stateName = "sAfterEscCharInQuotesInNValue"; + break; + case sHalfLineBreakInQuotesInNValue: + stateName = "sHalfLineBreakInQuotesInNValue"; + break; + case sAfterLineBreakInQuotesInNValue: + stateName = "sAfterLineBreakInQuotesInNValue"; + break; + case sScanNValueInAngles: + stateName = "sScanNValueInAngles"; + break; + case sHalfLineBreakInAnglesInNValue: + stateName = "sHalfLineBreakInAnglesInNValue"; + break; + case sAfterLineBreakInAnglesInNValue: + stateName = "sAfterLineBreakInAnglesInNValue"; + break; + case sHalfLineBreakAfterLineBreak: + stateName = "sHalfLineBreakAfterLineBreak"; + break; + default: + stateName = "<unknown>"; + }//switch + return stateName; +} + +static const char * +trActionName(TransitionAction transitionAction) +{ + const char *transitionActionName; + switch (transitionAction) + { + case taNone: + transitionActionName = "taNone"; + break; + case taTermStatusLine: + transitionActionName = "taTermStatusLine"; + break; + case taTermFieldName: + transitionActionName = "taTermFieldName"; + break; + case taBeyondEmptyValue: + transitionActionName = "taBeyondEmptyValue"; + break; + case taTermValueAfterLineBreak: + transitionActionName = "taTermValueAfterLineBreak"; + break; + case taTermValue: + transitionActionName = "taTermValue"; + break; + case taStartText: + transitionActionName = "taStartText"; + break; + case taEndHeader: + transitionActionName = "taEndHeader"; + break; + case taChunkTermSentinel: + transitionActionName = "taChunkTermSentinel"; + break; + case taError: + transitionActionName = "taError"; + break; + default: + transitionActionName = "<unknown>"; + } + return transitionActionName; +} + +static void +printStateTransition(State state, + char character, + TransitionAction transitionAction) +{ + printf(" %s['", cleanName(stateName(state))); + printText(&character, 1); + printf("']: %s\n", cleanName(trActionName(transitionAction))); +} +#if !defined(RESIP_MSG_HEADER_SCANNER_DEBUG) +static const char* stateName(const char*) +{ return "RECOMPILE_WITH_SCANNER_DEBUG"; } +static const char* trActionName(const char*) +{ return stateName(0); } +#endif +/// START OF MEMBER METHODS + + + +int +MsgHeaderScanner::dumpStateMachine(int fd) +{ + FILE *fp = fdopen(fd,"w"); + if (!fp) + { + fprintf(stderr,"MsgHeaderScanner:: unable to open output file\n"); + return -1; + } + // Force instance so things are initialized -- YUCK! + MsgHeaderScanner scanner;(void)scanner; + fprintf(fp,"digraph MsgHeaderScannerFSM {\n"); + fprintf(fp,"\tnode[shape=record\n\t\tfontsize=8\n\t\tfontname=\"Helvetica\"\n\t]\n"); + fprintf(fp,"\tedge [ fontsize=6 fontname=\"Helvetica\"]\n"); + + fprintf(fp,"\tgraph [ ratio=0.8\n\t\tfontsize=6 compound=true ]"); + for(int state = 0 ; state < numStates; ++state) + { + fprintf(fp, + " %s [ label = \"%d|%s\" ]\n", + cleanName(stateName(state)), + state, + cleanName(stateName(state)) + ); + for(int category = 0 ; category < numCharCategories; ++category) + { + // Skip Verbose Error or Empty Transitions + if (stateMachine[state][category].nextState == state && + (stateMachine[state][category].action == taError || + stateMachine[state][category].action == taNone + )) continue; + + fprintf(fp, + " %s -> %s [label=\"%s\\n%s\" ]\n", + cleanName(stateName(state)), + cleanName(stateName(stateMachine[state][category].nextState)), + categorySymbol(category), + cleanName(trActionName(stateMachine[state][category].action))); + } + fprintf(fp,"\n"); + } + fprintf(fp,"}\n"); + + return 0; +} + +#endif //defined(RESIP_MSG_HEADER_SCANNER_DEBUG) + + + +#if defined(RESIP_MSG_HEADER_SCANNER_DEBUG) + +static const char *const multiValuedFieldNameArray[] = { + "allow-events", + "accept-encoding", + "accept-language", + "allow", + "content-language", + "proxy-require", + "require", + "supported", + "subscription-state", + "unsupported", + "security-client", + "security-server", + "security-verify", + "accept", + "call-info", + "alert-info", + "error-info", + "record-route", + "route", + "contact", + "authorization", + "proxy-authenticate", + "proxy-authorization", + "www-authenticate", + "via", + 0 +}; + +extern +void +lookupMsgHeaderFieldInfo( + char * fieldName, //inout + unsigned int *fieldNameLength, //inout + MsgHeaderScanner::TextPropBitMask fieldNameTextPropBitMask, + int *fieldKind, //out + bool *isMultiValueAllowed) //out +{ + *isMultiValueAllowed = false; + const char *const *multiValuedFieldNamePtr = multiValuedFieldNameArray; + for (;;) + { + const char *multiValuedFieldName = *multiValuedFieldNamePtr; + if (!multiValuedFieldName) + { + break; + } + if (strncmp(fieldName, multiValuedFieldName, *fieldNameLength) == 0) + { + *isMultiValueAllowed = true; + break; + } + ++multiValuedFieldNamePtr; + }//for +} + +static +bool +processMsgHeaderStatusLine( + SipMessage * msg, + char * lineText, + unsigned int lineTextLength, + MsgHeaderScanner::TextPropBitMask lineTextPropBitMask) +{ + printf("status line: "); + printText(lineText, lineTextLength); + printf("\n"); + return true; +} + +static +void +processMsgHeaderFieldNameAndValue( + SipMessage * msg, + int fieldKind, + const char * fieldName, + unsigned int fieldNameLength, + char * valueText, + unsigned int valueTextLength, + MsgHeaderScanner::TextPropBitMask valueTextPropBitMask) +{ + printText(fieldName, fieldNameLength); + printf(": [[[["); + printText(valueText, valueTextLength); + printf("]]]]\n"); +} + +#else //!defined(RESIP_MSG_HEADER_SCANNER_DEBUG) } { + + +// Determine a field's kind and whether it allows (comma separated) multi-values. +// "fieldName" is not empty and contains only legal characters. +// The text in "fieldName" may be canonicalized (eg, translating % escapes), +// including shrinking it if necessary. + +inline void +lookupMsgHeaderFieldInfo(char * fieldName, + unsigned int *fieldNameLength, + MsgHeaderScanner::TextPropBitMask fieldNameTextPropBitMask, + int *fieldKind, + bool *isMultiValueAllowed) +{ + //.jacob. Don't ignore fieldNameTextPropBitMask. + *fieldKind = Headers::getType(fieldName, *fieldNameLength); + *isMultiValueAllowed = + Headers::isCommaTokenizing(static_cast<Headers::Type>(*fieldKind)); +} + + +// "lineText" contains no carriage returns and no line feeds. +// Return true on success, false on failure. + +inline bool +processMsgHeaderStatusLine(SipMessage * msg, + char * lineText, + unsigned int lineTextLength, + MsgHeaderScanner::TextPropBitMask lineTextPropBitMask) +{ + //.jacob. Don't ignore valueTextPropBitMask, and don't always return true. + msg->setStartLine(lineText, lineTextLength); + return true; +} + +// This function is called once for a field with one value. (The value could be +// several values, but separated by something other than commas.) +// This function is called once for a field with 0 comma-separated values, with +// an empty value. +// This function is called N times for a field with N comma-separated values, +// but with the same value of "fieldName" each time. +// "fieldName" is not empty and contains only legal characters. +// "valueText" may be empty, has no leading whitespace, may contain trailing +// whitespace, contains carriage returns and line feeds only in correct pairs +// and followed by whitespace, and, if the field is multi-valued, contains +// balanced '<'/'>' and '"' pairs, contains ',' only within '<'/'>' or '"' +// pairs, and respects '\\'s within '"' pairs. +// The text in "valueText" may be canonicalized (eg, translating % escapes), +// including shrinking it if necessary. + +inline void +processMsgHeaderFieldNameAndValue(SipMessage * msg, + int fieldKind, + const char * fieldName, + unsigned int fieldNameLength, + char * valueText, + unsigned int valueTextLength, + MsgHeaderScanner::TextPropBitMask valueTextPropBitMask) +{ + //.jacob. Don't ignore valueTextPropBitMask, particularly for '\r' & '\n'. + msg->addHeader(static_cast<Headers::Type>(fieldKind), + fieldName, + fieldNameLength, + valueText, + valueTextLength); +} + +#endif //!defined(RESIP_MSG_HEADER_SCANNER_DEBUG) } + +bool MsgHeaderScanner::mInitialized = false; + +MsgHeaderScanner::MsgHeaderScanner() +{ + if (!mInitialized) + { + mInitialized = true; + initialize(); + } +} + +void +MsgHeaderScanner::prepareForMessage(SipMessage * msg) +{ + mMsg = msg; + mState = sMsgStart; + mPrevScanChunkNumSavedTextChars = 0; + mNumHeaders=0; +} + +void +MsgHeaderScanner::prepareForFrag(SipMessage * msg, bool hasStartLine) +{ + mMsg = msg; + if (hasStartLine) + { + mState = sMsgStart; + } + else + { + mState = sAfterLineBreakAfterStatusLine; + } + mPrevScanChunkNumSavedTextChars = 0; + mNumHeaders=0; +} + +MsgHeaderScanner::ScanChunkResult +MsgHeaderScanner::scanChunk(char * chunk, + unsigned int chunkLength, + char ** unprocessedCharPtr) +{ + MsgHeaderScanner::ScanChunkResult result; + CharInfo* localCharInfoArray = charInfoArray; + TransitionInfo (*localStateMachine)[numCharCategories] = stateMachine; + State localState = mState; + char *charPtr = chunk + mPrevScanChunkNumSavedTextChars; + char *termCharPtr = chunk + chunkLength; + char saveChunkTermChar = *termCharPtr; + *termCharPtr = chunkTermSentinelChar; + char *textStartCharPtr; + MsgHeaderScanner::TextPropBitMask localTextPropBitMask = mTextPropBitMask; + if (mPrevScanChunkNumSavedTextChars == 0) + { + textStartCharPtr = 0; + } + else + { + textStartCharPtr = chunk; + } + --charPtr; // The loop starts by advancing "charPtr", so pre-adjust it. + for (;;) + { + // BEGIN message header character scan block BEGIN + // The code in this block is executed once per message header character. + // This entire file is designed specifically to minimize this block's size. + ++charPtr; + CharInfo *charInfo = &localCharInfoArray[((unsigned char) (*charPtr))]; + CharCategory charCategory = charInfo->category; + localTextPropBitMask |= charInfo->textPropBitMask; + determineTransitionFromCharCategory: + TransitionInfo *transitionInfo = + &(localStateMachine[(unsigned)localState][(size_t)charCategory]); + TransitionAction transitionAction = transitionInfo->action; +#if defined(RESIP_MSG_HEADER_SCANNER_DEBUG) + printStateTransition(localState, *charPtr, transitionAction); +#endif + localState = transitionInfo->nextState; + if (transitionAction == taNone) continue; + // END message header character scan block END + // The loop remainder is executed about 4-5 times per message header line. + switch (transitionAction) + { + case taTermStatusLine: + if (!processMsgHeaderStatusLine(mMsg, + textStartCharPtr, + (unsigned int)(charPtr - textStartCharPtr), + localTextPropBitMask)) + { + result = MsgHeaderScanner::scrError; + *unprocessedCharPtr = charPtr; + goto endOfFunction; + } + textStartCharPtr = 0; + break; + case taTermFieldName: + { + mFieldNameLength = (unsigned int)(charPtr - textStartCharPtr); + bool isMultiValueAllowed; + lookupMsgHeaderFieldInfo(textStartCharPtr, + &mFieldNameLength, + localTextPropBitMask, + &mFieldKind, + &isMultiValueAllowed); + mFieldName = textStartCharPtr; + textStartCharPtr = 0; + if (isMultiValueAllowed) + { + localState += deltaOfNStateFrom1State; + } + } + break; + case taBeyondEmptyValue: + processMsgHeaderFieldNameAndValue(mMsg, + mFieldKind, + mFieldName, + mFieldNameLength, + 0, + 0, + 0); + ++mNumHeaders; + goto performStartTextAction; + case taTermValueAfterLineBreak: + processMsgHeaderFieldNameAndValue(mMsg, + mFieldKind, + mFieldName, + mFieldNameLength, + textStartCharPtr, + (unsigned int)((charPtr - textStartCharPtr) - 2), + localTextPropBitMask); //^:CRLF + ++mNumHeaders; + goto performStartTextAction; + case taTermValue: + processMsgHeaderFieldNameAndValue(mMsg, + mFieldKind, + mFieldName, + mFieldNameLength, + textStartCharPtr, + (unsigned int)(charPtr - textStartCharPtr), + localTextPropBitMask); + textStartCharPtr = 0; + ++mNumHeaders; + break; + case taStartText: + performStartTextAction: + textStartCharPtr = charPtr; + localTextPropBitMask = 0; + break; + case taEndHeader: + // textStartCharPtr is not 0. Not currently relevant. + result = MsgHeaderScanner::scrEnd; + *unprocessedCharPtr = charPtr + 1; // The current char is processed. + goto endOfFunction; + break; + case taChunkTermSentinel: + if (charPtr == termCharPtr) + { + // The chunk has been consumed. Save some state and request another. + mState = localState; + if (textStartCharPtr == 0) + { + mPrevScanChunkNumSavedTextChars = 0; + } + else + { + mPrevScanChunkNumSavedTextChars = (unsigned int)(termCharPtr - textStartCharPtr); + } + mTextPropBitMask = localTextPropBitMask; + result = MsgHeaderScanner::scrNextChunk; + *unprocessedCharPtr = termCharPtr - mPrevScanChunkNumSavedTextChars; + goto endOfFunction; + } + else + { + // The character is not the sentinel. Treat it like any other. + charCategory = ccOther; + goto determineTransitionFromCharCategory; + } + break; + default: + result = MsgHeaderScanner::scrError; + *unprocessedCharPtr = charPtr; + goto endOfFunction; + }//switch + }//for + endOfFunction: + *termCharPtr = saveChunkTermChar; + return result; +} + +bool +MsgHeaderScanner::initialize() +{ + initCharInfoArray(); + initStateMachine(); + return true; +} + + +} //namespace resip + + + +#if defined(RESIP_MSG_HEADER_SCANNER_DEBUG) && defined(MSG_SCANNER_STANDALONE) + +extern +int +main(unsigned int numArgs, + const char * * argVector) +{ + ::resip::MsgHeaderScanner scanner; + scanner.prepareForMessage(0); + char *text = + "status\r\n" + "bobby: dummy\r\n" + "allow: foo, bar, \"don,\\\"xyz\r\n zy\", buzz\r\n\r\n"; + unsigned int textLength = strlen(text); + char chunk[10000]; + strcpy(chunk, text); + ::resip::MsgHeaderScanner::ScanChunkResult scanChunkResult; + char *unprocessedCharPtr; + scanChunkResult = scanner.scanChunk(chunk, 21, &unprocessedCharPtr); + if (scanChunkResult == ::resip::MsgHeaderScanner::scrNextChunk) + { + printf("Scanning another chunk '."); + ::resip::printText(unprocessedCharPtr, 1); + printf("'\n"); + scanChunkResult = + scanner.scanChunk(unprocessedCharPtr, + (chunk + textLength) - unprocessedCharPtr, + &unprocessedCharPtr); + } + if (scanChunkResult != ::resip::MsgHeaderScanner::scrEnd) + { + printf("Error %d at character %d.\n", + scanChunkResult, + unprocessedCharPtr - chunk); + } + return 0; +} + +#endif //!defined(RESIP_MSG_HEADER_SCANNER_DEBUG) } + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MsgHeaderScanner.hxx b/src/libs/resiprocate/resip/stack/MsgHeaderScanner.hxx new file mode 100644 index 00000000..1f71e30d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MsgHeaderScanner.hxx @@ -0,0 +1,194 @@ +#if !defined(RESIP_MSG_HEADER_SCANNER_HXX) +#define RESIP_MSG_HEADER_SCANNER_HXX +namespace resip +{ + +class SipMessage; + +/////////////////////////////////////////////////////////////////////////////// +// This class scans a message header for its status line (the first non-empty +// line) and then any number of field name/value pairs, terminated by an empty +// line. +// The message header text may be divided into arbitrary chunks. +// A single instance may be used to scan any number of message headers. +// +// Its intended usage pattern is as follows: +// +// MsgHeaderScanner scanner; +// for (;;) { +// SipMessage *msg = ... +// scanner.prepareForMessage(msg); +// MsgHeaderScanner::ScanChunkResult scanChunkResult; +// do { +// (Input the next chunk of the message.) +// scanChunkResult = scanner.scanChunk(...); +// } while (scanChunkResult == MsgHeaderScanner::scrNextChunk); +// ... +// }//for +// +// Note that during the input of each message header chunk this class +// encapsulates the full state of the message header scan, so that input may +// be performed in whatever manner desired (eg without blocking). +// +// In this class, "multi-value" refers to associating multiple values with a +// single field name by separating the individual values with commas. +// +// Some assertions about message headers: +// Only space and tab are whitespace characters. +// A carriage return must always be followed by a line feed. +// A line feed must always be preceded by a carriage return. +// A field name always starts at the beginning of a line. +// A value may contain a line break (a carriage return / line feed pair) +// before any whitespace, but not otherwise. (The scanner allows +// whitespace in a few extra places for simplicity.) +// A ',' within '"' pair or '<'/'>' pair does not separate multi-values. +// A '\\' is used only within a '"' pair, and not to escape a carriage +// return or line feed. +// '<'/'>' pairs do not nest, nor contain '"' pairs. +// '('/')' pair comments cannot be combined with any multi-values. +// A multi-value cannot be empty, except as needed to specify 0 multi-values. + +class MsgHeaderScanner +{ + + public: + enum { MaxNumCharsChunkOverflow = 5 }; + static char* allocateBuffer(int size); + + enum TextPropBitMaskEnum + { + tpbmContainsLineBreak = 1 << 0, // '\r' or '\n', always paired + tpbmContainsWhitespace = 1 << 1, // ' ' or '\t' + tpbmContainsBackslash = 1 << 2, // '\\' + tpbmContainsPercent = 1 << 3, // '%' + tpbmContainsSemicolon = 1 << 4, // ';' + tpbmContainsParen = 1 << 5 // '(' or ')', possibly mismatched + }; + typedef unsigned char TextPropBitMask; + + inline unsigned int getHeaderCount() const { return mNumHeaders;} + + private: + + // Fields: + SipMessage * mMsg; + unsigned int mNumHeaders; + /*State*/int mState; // Type defined in .cxx file. + int mPrevScanChunkNumSavedTextChars; + MsgHeaderScanner::TextPropBitMask mTextPropBitMask; + const char * mFieldName; + unsigned int mFieldNameLength; + int mFieldKind; + /* + "mState" and "mPrevScanChunkNumSavedTextChars" are meaningful only between + input chunks. + "mTextPropBitMask" is meaningful only between input chunks and only when + scanning a field name or value. + "mFieldName", "mFieldNameLength", and "mFieldKind" are meaningful only + between terminating a field name and finding the termination of its value. + */ + + public: + + MsgHeaderScanner(); + + // Destructor: defined implicitly + void prepareForMessage(SipMessage * msg); + // allow proper parsing of message/sipfrag & msg/external + // presence of start line is determined in SipFrag + void prepareForFrag(SipMessage * msg, bool hasStartLine); + + + enum ScanChunkResult { + scrEnd, // Message header scan ended. + scrNextChunk, // Another chunk is needed. + scrError // The message header is in error. + }; + + + // The meaning of "*unprocessedCharPtr" depends on the result: + // scrEnd: The character that terminates the message header. + // scrError: The erroneous character. + // scrNextChunk: The first character of some incomplete text unit. The + // remaining portion of the old chunk must be placed + // in the beginning of the new chunk. + // This method writes a sentinel in the chunk's terminal character. + MsgHeaderScanner::ScanChunkResult scanChunk(char * chunk, + unsigned int chunkLength, + char **unprocessedCharPtr); + + // !ah! DEBUG only, write to fd. + // !ah! for documentation generation + static int dumpStateMachine(int fd); + + private: + + + // Copy constructor: declared but not defined + MsgHeaderScanner(const MsgHeaderScanner & from); + + // Assignment: declared but not defined + MsgHeaderScanner & operator=(const MsgHeaderScanner & from); + + // Automatically called when 1st MsgHeaderScanner constructed. + bool initialize(); + static bool mInitialized; + + +}; + + +/////////////////////////////////////////////////////////////////////////////// + +} // namespace resip + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MultipartAlternativeContents.cxx b/src/libs/resiprocate/resip/stack/MultipartAlternativeContents.cxx new file mode 100644 index 00000000..66480626 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MultipartAlternativeContents.cxx @@ -0,0 +1,101 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/MultipartAlternativeContents.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::CONTENTS + +bool +MultipartAlternativeContents::init() +{ + static ContentsFactory<MultipartAlternativeContents> factory; + (void)factory; + return true; +} + +MultipartAlternativeContents::MultipartAlternativeContents() + : MultipartMixedContents(getStaticType()) +{} + +MultipartAlternativeContents::MultipartAlternativeContents(const HeaderFieldValue& hfv, const Mime& contentsType) + : MultipartMixedContents(hfv, contentsType) +{} + +MultipartAlternativeContents::MultipartAlternativeContents(const MultipartAlternativeContents& rhs) + : MultipartMixedContents(rhs) +{} + +MultipartAlternativeContents& +MultipartAlternativeContents::operator=(const MultipartAlternativeContents& rhs) +{ + MultipartMixedContents::operator=(rhs); + return *this; +} + +Contents* +MultipartAlternativeContents::clone() const +{ + return new MultipartAlternativeContents(*this); +} + +const Mime& +MultipartAlternativeContents::getStaticType() +{ + static Mime type("multipart", "alternative"); + return type; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MultipartAlternativeContents.hxx b/src/libs/resiprocate/resip/stack/MultipartAlternativeContents.hxx new file mode 100644 index 00000000..ba627d47 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MultipartAlternativeContents.hxx @@ -0,0 +1,85 @@ +#ifndef RESIP_MultipartAlternativeContents_hxx +#define RESIP_MultipartAlternativeContents_hxx + +#include "resip/stack/MultipartMixedContents.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type for holding Multipart-Alternative body contents (MIME content-type multipart/alternative). +*/ +class MultipartAlternativeContents : public MultipartMixedContents +{ + public: + MultipartAlternativeContents(); + MultipartAlternativeContents(const HeaderFieldValue& hfv, const Mime& contentType); + MultipartAlternativeContents(const MultipartAlternativeContents& rhs); + MultipartAlternativeContents& operator=(const MultipartAlternativeContents& rhs); + + /** @brief duplicate an MultipartAlternativeContents object + @return pointer to a new MultipartAlternativeContents object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType() ; + + static bool init(); +}; + +static bool invokeMultipartAlternativeContentsInit = MultipartAlternativeContents::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MultipartMixedContents.cxx b/src/libs/resiprocate/resip/stack/MultipartMixedContents.cxx new file mode 100644 index 00000000..afc97982 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MultipartMixedContents.cxx @@ -0,0 +1,310 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/MultipartMixedContents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Random.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::CONTENTS + +bool +MultipartMixedContents::init() +{ + static ContentsFactory<MultipartMixedContents> factory; + (void)factory; + return true; +} + +MultipartMixedContents::MultipartMixedContents() + : Contents(getStaticType()), + mContents() +{ + setBoundary(); +} + +MultipartMixedContents::MultipartMixedContents(const Mime& contentsType) + : Contents(contentsType), + mContents() +{ + if (!mType.exists(p_boundary)) + { + setBoundary(); + } +} + +MultipartMixedContents::MultipartMixedContents(const HeaderFieldValue& hfv, const Mime& contentsType) + : Contents(hfv, contentsType), + mContents() +{ + if (!mType.exists(p_boundary)) + { + setBoundary(); + } +} + +MultipartMixedContents::MultipartMixedContents(const MultipartMixedContents& rhs) + : Contents(rhs), + mContents() +{ + vector<Contents*>::const_iterator j; + + // .bwc. Don't trigger a parse of the original by calling parts() + const vector<Contents*>& list = rhs.mContents; + + for ( j = list.begin(); + j != list.end(); ++j) + { + assert( *j ); + mContents.push_back( (*j)->clone() ); + } +} + +void +MultipartMixedContents::setBoundary() +{ + Data boundaryToken = Random::getRandomHex(8); + mType.param(p_boundary) = boundaryToken; +} + +void +MultipartMixedContents::setBoundary(const Data& boundary) +{ + mType.param(p_boundary) = boundary; +} + +void +MultipartMixedContents::clear() +{ + for (vector<Contents*>::iterator i = mContents.begin(); + i != mContents.end(); ++i) + { + delete *i; + } +} + +MultipartMixedContents::~MultipartMixedContents() +{ + clear(); +} + +MultipartMixedContents& +MultipartMixedContents::operator=(const MultipartMixedContents& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + clear(); + + for (vector<Contents*>::iterator i = mContents.begin(); + i != mContents.end(); ++i) + { + mContents.push_back( (*i)->clone() ); + } + } + return *this; +} + +Contents* +MultipartMixedContents::clone() const +{ + return new MultipartMixedContents(*this); +} + +const Mime& +MultipartMixedContents::getStaticType() +{ + static Mime type("multipart","mixed"); + return type; +} + +EncodeStream& +MultipartMixedContents::encodeParsed(EncodeStream& str) const +{ + const Data& boundaryToken = mType.param(p_boundary); + Data boundary(boundaryToken.size() + 2, Data::Preallocate); + boundary = Symbols::DASHDASH; + boundary += boundaryToken; + boundary.replace("\"", ""); // remove quotes + + assert( mContents.size() > 0 ); + + bool first = true; + for (vector<Contents*>::const_iterator i = mContents.begin(); + i != mContents.end(); ++i) + { + if (!first) + { + str << Symbols::CRLF; + } + else + { + first = false; + } + str << boundary << Symbols::CRLF; + (*i)->encodeHeaders(str); + (*i)->encode(str); + } + + str << Symbols::CRLF << boundary << Symbols::DASHDASH; + return str; +} + +// The boundary delimiter MUST occur at the beginning of a line, i.e., following +// a CRLF, and the initial CRLF is considered to be attached to the boundary +// delimiter line rather than part of the preceding part. +void +MultipartMixedContents::parse(ParseBuffer& pb) +{ + const Data& boundaryToken = mType.param(p_boundary); + + Data boundary(boundaryToken.size() + 4, Data::Preallocate); + boundary += Symbols::CRLF; + boundary += Symbols::DASHDASH; + boundary += boundaryToken; + + Data boundaryNoCRLF(boundaryToken.size() + 2, Data::Preallocate); + boundaryNoCRLF += Symbols::DASHDASH; + boundaryNoCRLF += boundaryToken; + + pb.skipToChars(boundaryNoCRLF); + pb.skipN((int)boundaryNoCRLF.size()); + pb.assertNotEof(); + + do + { + // skip over boundary + + if( pb.eof() || *pb.position() != Symbols::CR[0] ) + { + throw Exception("Invalid line ending, missing CR",__FILE__,__LINE__); + } + pb.skipChar(); + if( pb.eof() || *pb.position() != Symbols::LF[0] ) + { + throw Exception("Invalid line ending, missing LF",__FILE__,__LINE__); + } + pb.skipChar(); + + pb.assertNotEof(); + + const char* headerStart = pb.position(); + + // pull out contents type only + pb.skipToChars("Content-Type"); + if (pb.eof()) + { + pb.reset(headerStart); + pb.skipToChars("CONTENT-TYPE"); + } + pb.assertNotEof(); + + pb.skipToChar(Symbols::COLON[0]); + pb.skipChar(); + pb.assertNotEof(); + + pb.skipWhitespace(); + const char* typeStart = pb.position(); + pb.assertNotEof(); + + // determine contents-type header buffer + pb.skipToTermCRLF(); + pb.assertNotEof(); + + ParseBuffer subPb(typeStart, pb.position() - typeStart); + Mime contentType; + contentType.parse(subPb); + + pb.assertNotEof(); + + // determine body start + pb.reset(typeStart); + const char* bodyStart = pb.skipToChars(Symbols::CRLFCRLF); + pb.assertNotEof(); + bodyStart += 4; + + // determine contents body buffer + pb.skipToChars(boundary); + pb.assertNotEof(); + Data tmp; + pb.data(tmp, bodyStart); + // create contents against body + mContents.push_back(createContents(contentType, tmp)); + // pre-parse headers + ParseBuffer headersPb(headerStart, bodyStart-4-headerStart); + mContents.back()->preParseHeaders(headersPb); + + pb.skipN((int)boundary.size()); + + const char* loc = pb.position(); + pb.skipChar(); + pb.skipChar(); + Data next; + pb.data(next, loc); + + if ( next == Symbols::DASHDASH ) + { + break; + } + pb.reset( loc ); + } + while ( !pb.eof() ); + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MultipartMixedContents.hxx b/src/libs/resiprocate/resip/stack/MultipartMixedContents.hxx new file mode 100644 index 00000000..18350a88 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MultipartMixedContents.hxx @@ -0,0 +1,122 @@ +#if !defined(RESIP_MULTIPARTMIXEDCONTENTS_HXX) +#define RESIP_MULTIPARTMIXEDCONTENTS_HXX + +#include <vector> + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +class Mime; +class ParseBuffer; + +/** + @ingroup sip_payload + @brief SIP body type for holding Multipart-Mixed body contents (MIME content-type multipart/mixed). +*/ +class MultipartMixedContents : public Contents +{ + public: + MultipartMixedContents(); + explicit MultipartMixedContents(const Mime& contentType); + MultipartMixedContents(const HeaderFieldValue& hfv, const Mime& contentType); + MultipartMixedContents(const MultipartMixedContents& rhs); + virtual ~MultipartMixedContents(); + MultipartMixedContents& operator=(const MultipartMixedContents& rhs); + + /** @brief duplicate an MultipartMixedContents object + @return pointer to a new MultipartMixedContents object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType() ; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + typedef std::vector<Contents*> Parts; + Parts& parts() {checkParsed(); return mContents;} + const Parts& parts() const {checkParsed(); return mContents;} + + void setBoundary(const Data& boundary); + + /** + @brief Thrown when there is an error parsing a multi-part mixed contents envelope. + @sa resip::BaseException + */ + class Exception : public BaseException + { + public: + Exception(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) {} + + const char* name() const { return "MultipartMixedContents::Exception"; } + }; + + static bool init(); + + protected: + void clear(); + + private: + void setBoundary(); + std::vector<Contents*> mContents; +}; + +static bool invokeMultipartMixedContentsInit = MultipartMixedContents::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MultipartRelatedContents.cxx b/src/libs/resiprocate/resip/stack/MultipartRelatedContents.cxx new file mode 100644 index 00000000..c47329c5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MultipartRelatedContents.cxx @@ -0,0 +1,101 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/MultipartRelatedContents.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::CONTENTS + +bool +MultipartRelatedContents::init() +{ + static ContentsFactory<MultipartRelatedContents> factory; + (void)factory; + return true; +} + +MultipartRelatedContents::MultipartRelatedContents() + : MultipartMixedContents(getStaticType()) +{} + +MultipartRelatedContents::MultipartRelatedContents(const HeaderFieldValue& hfv, const Mime& contentsType) + : MultipartMixedContents(hfv, contentsType) +{} + +MultipartRelatedContents::MultipartRelatedContents(const MultipartRelatedContents& rhs) + : MultipartMixedContents(rhs) +{} + +MultipartRelatedContents& +MultipartRelatedContents::operator=(const MultipartRelatedContents& rhs) +{ + MultipartMixedContents::operator=(rhs); + return *this; +} + +Contents* +MultipartRelatedContents::clone() const +{ + return new MultipartRelatedContents(*this); +} + +const Mime& +MultipartRelatedContents::getStaticType() +{ + static Mime type("multipart","related"); + return type; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MultipartRelatedContents.hxx b/src/libs/resiprocate/resip/stack/MultipartRelatedContents.hxx new file mode 100644 index 00000000..4a5a274c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MultipartRelatedContents.hxx @@ -0,0 +1,85 @@ +#ifndef RESIP_MultipartRelatedContents_hxx +#define RESIP_MultipartRelatedContents_hxx + +#include "resip/stack/MultipartMixedContents.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type for holding Multipart-Related body contents (MIME content-type multipart/related). +*/ +class MultipartRelatedContents : public MultipartMixedContents +{ + public: + MultipartRelatedContents(); + MultipartRelatedContents(const HeaderFieldValue& hfv, const Mime& contentType); + MultipartRelatedContents(const MultipartRelatedContents& rhs); + MultipartRelatedContents& operator=(const MultipartRelatedContents& rhs); + + /** @brief duplicate an MultipartRelatedContents object + @return pointer to a new MultipartRelatedContents object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType() ; + + static bool init(); +}; + +static bool invokeMultipartRelatedContentsInit = MultipartRelatedContents::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MultipartSignedContents.cxx b/src/libs/resiprocate/resip/stack/MultipartSignedContents.cxx new file mode 100644 index 00000000..4948ab10 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MultipartSignedContents.cxx @@ -0,0 +1,119 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/MultipartSignedContents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Logger.hxx" +//#include "resip/stack/EncodingContext.hxx" +#include "rutil/Random.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::CONTENTS + +bool +MultipartSignedContents::init() +{ + static ContentsFactory<MultipartSignedContents> factory; + (void)factory; + return true; +} + +MultipartSignedContents::MultipartSignedContents() + : MultipartMixedContents(getStaticType()) +{} + +MultipartSignedContents::MultipartSignedContents(const HeaderFieldValue& hfv, const Mime& contentsType) + : MultipartMixedContents(hfv, contentsType) +{ +} + + +MultipartSignedContents::MultipartSignedContents(const MultipartSignedContents& rhs) + : MultipartMixedContents(rhs) +{ +} + + +MultipartSignedContents::~MultipartSignedContents() +{ +} + + +MultipartSignedContents& +MultipartSignedContents::operator=(const MultipartSignedContents& rhs) +{ + if (this != &rhs) + { + MultipartMixedContents::operator=( rhs); + } + return *this; +} + + +Contents* +MultipartSignedContents::clone() const +{ + return new MultipartSignedContents(*this); +} + + +const Mime& +MultipartSignedContents::getStaticType() +{ + static Mime type("multipart","signed"); + return type; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/MultipartSignedContents.hxx b/src/libs/resiprocate/resip/stack/MultipartSignedContents.hxx new file mode 100644 index 00000000..1eb3ed6c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MultipartSignedContents.hxx @@ -0,0 +1,91 @@ +#if !defined(RESIP_MULTIPARTSIGNEDCONTENTS_HXX) +#define RESIP_MULTIPARTSIGNEDCONTENTS_HXX + + +#include "resip/stack/MultipartMixedContents.hxx" + + +namespace resip +{ + +class Mime; +class ParseBuffer; + +/** + @ingroup sip_payload + @brief SIP body type for holding Multipart-Signed body contents (MIME content-type multipart/signed). +*/ +class MultipartSignedContents : public MultipartMixedContents +{ + public: + MultipartSignedContents(); + MultipartSignedContents(const HeaderFieldValue& hfv, const Mime& contentType); + MultipartSignedContents(const MultipartSignedContents& rhs); + virtual ~MultipartSignedContents(); + MultipartSignedContents& operator=(const MultipartSignedContents& rhs); + + /** @brief duplicate an MultipartSignedContents object + @return pointer to a new MultipartSignedContents object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType(); + + static bool init(); +}; + +static bool invokeMultipartSignedContentsInit = MultipartSignedContents::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/NameAddr.cxx b/src/libs/resiprocate/resip/stack/NameAddr.cxx new file mode 100644 index 00000000..8c37f857 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/NameAddr.cxx @@ -0,0 +1,550 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/NameAddr.hxx" +#include "rutil/ParseException.hxx" +#include "resip/stack/UnknownParameter.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// NameAddr: +//==================== +NameAddr::NameAddr() : + ParserCategory(), + mAllContacts(false), + mDisplayName(), + mUnknownUriParametersBuffer(0) +{} + +NameAddr::NameAddr(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), + mAllContacts(false), + mUri(pool), + mDisplayName(), + mUnknownUriParametersBuffer(0) +{} + +NameAddr::NameAddr(const NameAddr& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mAllContacts(rhs.mAllContacts), + mUri(rhs.mUri, pool), + mDisplayName(rhs.mDisplayName), + mUnknownUriParametersBuffer(0) +{} + +static const Data parseContext("NameAddr constructor"); +NameAddr::NameAddr(const Data& unparsed, bool preCacheAor) + : ParserCategory(), + mAllContacts(false), + mDisplayName(), + mUnknownUriParametersBuffer(0) +{ + HeaderFieldValue hfv(unparsed.data(), unparsed.size()); + // must copy because parse creates overlays + NameAddr tmp(hfv, Headers::UNKNOWN); + tmp.checkParsed(); + *this = tmp; + if(preCacheAor) + { + mUri.getAor(); + } +} + +NameAddr::NameAddr(const Uri& uri) + : ParserCategory(), + mAllContacts(false), + mUri(uri), + mDisplayName(), + mUnknownUriParametersBuffer(0) +{} + +NameAddr::~NameAddr() +{ + if(mUnknownUriParametersBuffer) + { + delete mUnknownUriParametersBuffer; + } +} + +NameAddr& +NameAddr::operator=(const NameAddr& rhs) +{ + if (this != &rhs) + { + assert( &rhs != 0 ); + + ParserCategory::operator=(rhs); + mAllContacts = rhs.mAllContacts; + mDisplayName = rhs.mDisplayName; + mUri = rhs.mUri; + } + return *this; +} + +bool +NameAddr::operator==(const NameAddr& other) const +{ + return uri() == other.uri() && displayName() == other.displayName(); +} + +bool +NameAddr::operator<(const NameAddr& rhs) const +{ + return uri() < rhs.uri(); +} + +ParserCategory * +NameAddr::clone() const +{ + return new NameAddr(*this); +} + +ParserCategory * +NameAddr::clone(void* location) const +{ + return new (location) NameAddr(*this); +} + +ParserCategory* +NameAddr::clone(PoolBase* pool) const +{ + return new (pool) NameAddr(*this, pool); +} + +const Uri& +NameAddr::uri() const +{ + checkParsed(); + return mUri; +} + +Uri& +NameAddr::uri() +{ + checkParsed(); + return mUri; +} + +Data& +NameAddr::displayName() +{ + checkParsed(); + return mDisplayName; +} + +const Data& +NameAddr::displayName() const +{ + checkParsed(); + return mDisplayName; +} + +bool +NameAddr::isAllContacts() const +{ + checkParsed(); + return mAllContacts; +} + +void +NameAddr::setAllContacts() +{ + mAllContacts = true; +} + +void +NameAddr::parse(ParseBuffer& pb) +{ + const char* start; + start = pb.skipWhitespace(); + pb.assertNotEof(); + bool laQuote = false; + bool starContact = false; + + if (*pb.position() == Symbols::STAR[0]) + { + pb.skipChar(Symbols::STAR[0]); + pb.skipWhitespace(); + if (pb.eof() || *pb.position() == Symbols::SEMI_COLON[0]) + { + starContact = true; + } + } + + if (starContact) + { + mAllContacts = true; + // now fall through to parse header parameters + } + else + { + pb.reset(start); + if (*pb.position() == Symbols::DOUBLE_QUOTE[0]) + { + start = pb.skipChar(Symbols::DOUBLE_QUOTE[0]); + pb.skipToEndQuote(); + pb.data(mDisplayName, start); + pb.skipChar(Symbols::DOUBLE_QUOTE[0]); + laQuote = true; + pb.skipToChar(Symbols::LA_QUOTE[0]); + if (pb.eof()) + { + throw ParseException("Expected '<'", + "NameAddr", + __FILE__, + __LINE__); + } + else + { + pb.skipChar(Symbols::LA_QUOTE[0]); + } + } + else if (*pb.position() == Symbols::LA_QUOTE[0]) + { + pb.skipChar(Symbols::LA_QUOTE[0]); + laQuote = true; + } + else + { + start = pb.position(); + pb.skipToChar(Symbols::LA_QUOTE[0]); + if (pb.eof()) + { + pb.reset(start); + } + else + { + laQuote = true; + pb.skipBackWhitespace(); + pb.data(mDisplayName, start); + pb.skipToChar(Symbols::LA_QUOTE[0]); + pb.skipChar(Symbols::LA_QUOTE[0]); + } + } + pb.skipWhitespace(); + mUri.parse(pb); + if (laQuote) + { + pb.skipChar(Symbols::RA_QUOTE[0]); + pb.skipWhitespace(); + // now fall through to parse header parameters + } + else + { + if(mUri.mUnknownParameters.size() > 0) + { + assert(!mUnknownUriParametersBuffer); + mUnknownUriParametersBuffer = new Data; + { // Scope stream + oDataStream str(*mUnknownUriParametersBuffer); + // deal with Uri/NameAddr parameter ambiguity + // heuristically assign Uri parameters to the Uri + for (ParameterList::iterator it = mUri.mUnknownParameters.begin(); + it != mUri.mUnknownParameters.end(); ++it) + { + // We're just going to assume all unknown (to Uri) params really + // belong on the header. This is not necessarily the case. + str << ";"; + (*it)->encode(str); + } + } + mUri.clearUnknownParameters(); + ParseBuffer pb2(*mUnknownUriParametersBuffer); + parseParameters(pb2); + } + } + } + parseParameters(pb); +} + +EncodeStream& +NameAddr::encodeParsed(EncodeStream& str) const +{ + //bool displayName = !mDisplayName.empty(); + if (mAllContacts) + { + str << Symbols::STAR; + } + else + { + if (!mDisplayName.empty()) + { +#ifndef HANDLE_EMBEDDED_QUOTES_DNAME + // .dlb. doesn't deal with embedded quotes + str << Symbols::DOUBLE_QUOTE << mDisplayName << Symbols::DOUBLE_QUOTE; +#else + // does nothing if display name is properly quoted + if (mustQuoteDisplayName()) + { + str << Symbols::DOUBLE_QUOTE; + for (unsigned int i=0; i < mDisplayName.size(); i++) + { + char c = mDisplayName[i]; + switch(c) + { + case '"': + case '\\': + str << '\\' << c; + break; + default: + str << c; + } + } + str << Symbols::DOUBLE_QUOTE; + } + else + { + str << mDisplayName; + } +#endif + } + str << Symbols::LA_QUOTE; + mUri.encodeParsed(str); + str << Symbols::RA_QUOTE; + } + + encodeParameters(str); + return str; +} + + +bool +NameAddr::mustQuoteDisplayName() const +{ + if (mDisplayName.empty()) + { + return false; + } + ParseBuffer pb(mDisplayName.data(), mDisplayName.size()); + + //shouldn't really be any leading whitespace + pb.skipWhitespace(); + if (pb.eof()) + { + return false; + } + if ((*pb.position() == '"')) + { + bool escaped = false; + while(!pb.eof()) + { + pb.skipChar(); + if (escaped) + { + escaped = false; + } + else if (*pb.position() == '\\') + { + escaped = true; + } + else if (*pb.position() == '"') + { + break; + } + } + if (*pb.position() == '"') + { + //should only have whitespace left, and really non of that + pb.skipChar(); + if (pb.eof()) + { + return false; + } + pb.skipWhitespace(); + if (pb.eof()) + { + return false; //properly quoted + } + else + { + return true; + } + } + else + { + return true; //imbalanced quotes + } + } + else + { + while (!pb.eof()) + { + const char* start; + start = pb.skipWhitespace(); + pb.skipNonWhitespace(); + const char* end = pb.position(); + for (const char* c = start; c < end; c++) + { + if ( (*c >= 'a' && *c <= 'z') || + (*c >= 'A' && *c <= 'Z') || + (*c >= '0' && *c <= '9')) + { + continue; + } + switch(*c) + { + case '-': + case '.': + case '!': + case '%': + case '*': + case '_': + case '+': + case '`': + case '\'': + case '~': + break; + default: + return true; + } + } + } + } + return false; +} + +ParameterTypes::Factory NameAddr::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; + +Parameter* +NameAddr::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) +{ + if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) + { + return ParameterFactories[type](type, pb, terminators, pool); + } + return 0; +} + +bool +NameAddr::exists(const Param<NameAddr>& paramType) const +{ + checkParsed(); + bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; + return ret; +} + +void +NameAddr::remove(const Param<NameAddr>& paramType) +{ + checkParsed(); + removeParameterByEnum(paramType.getTypeNum()); +} + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ +_enum##_Param::DType& \ +NameAddr::param(const _enum##_Param& paramType) \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + p = new _enum##_Param::Type(paramType.getTypeNum()); \ + mParameters.push_back(p); \ + } \ + return p->value(); \ +} \ + \ +const _enum##_Param::DType& \ +NameAddr::param(const _enum##_Param& paramType) const \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ + DebugLog(<< *this); \ + throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ + } \ + return p->value(); \ +} + +defineParam(data, "data", ExistsParameter, "RFC 3840"); +defineParam(control, "control", ExistsParameter, "RFC 3840"); +defineParam(mobility, "mobility", QuotedDataParameter, "RFC 3840"); // mobile|fixed +defineParam(description, "description", QuotedDataParameter, "RFC 3840"); // <> quoted +defineParam(events, "events", QuotedDataParameter, "RFC 3840"); // list +defineParam(priority, "priority", QuotedDataParameter, "RFC 3840"); // non-urgent|normal|urgent|emergency +defineParam(methods, "methods", QuotedDataParameter, "RFC 3840"); // list +defineParam(schemes, "schemes", QuotedDataParameter, "RFC 3840"); // list +defineParam(application, "application", ExistsParameter, "RFC 3840"); +defineParam(video, "video", ExistsParameter, "RFC 3840"); +defineParam(language, "language", QuotedDataParameter, "RFC 3840"); // list +defineParam(type, "type", QuotedDataParameter, "RFC 3840"); // list +defineParam(isFocus, "isfocus", ExistsParameter, "RFC 3840"); +defineParam(actor, "actor", QuotedDataParameter, "RFC 3840"); // principal|msg-taker|attendant|information +defineParam(text, "text", ExistsOrDataParameter, "RFC 3840"); +defineParam(extensions, "extensions", QuotedDataParameter, "RFC 3840"); //list +defineParam(Instance, "+sip.instance", QuotedDataParameter, "RFC 5626"); // <> quoted +defineParam(regid, "reg-id", UInt32Parameter, "RFC 5626"); +defineParam(pubGruu, "pub-gruu", QuotedDataParameter, "RFC 5627"); +defineParam(tempGruu, "temp-gruu", QuotedDataParameter, "RFC 5627"); +defineParam(expires, "expires", UInt32Parameter, "RFC 3261"); +defineParam(q, "q", QValueParameter, "RFC 3261"); +defineParam(tag, "tag", DataParameter, "RFC 3261"); + +#undef defineParam + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/NameAddr.hxx b/src/libs/resiprocate/resip/stack/NameAddr.hxx new file mode 100644 index 00000000..02910c8f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/NameAddr.hxx @@ -0,0 +1,158 @@ +#if !defined(RESIP_NAME_ADDR_HXX) +#define RESIP_NAME_ADDR_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/ParserContainer.hxx" +#include "resip/stack/Uri.hxx" + +namespace resip +{ + +/** + @ingroup sip_grammar + @brief Represents the "name-addr" and the "addr-spec" elements in the RFC + 3261 grammar. +*/ +class NameAddr : public ParserCategory +{ + public: + enum {commaHandling = CommasAllowedOutputMulti}; + + NameAddr(); + NameAddr(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + explicit NameAddr(const Uri& orig); + explicit NameAddr(const Data& unparsed, bool preCacheAor=false); + + NameAddr(const NameAddr& orig, + PoolBase* pool=0); + NameAddr& operator=(const NameAddr&); + bool operator==(const NameAddr& other) const; + + virtual ~NameAddr(); + + Uri& uri(); + const Uri& uri() const; + Data& displayName(); + const Data& displayName() const; + bool isAllContacts() const; + void setAllContacts(); + + virtual void parse(ParseBuffer& pb); + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + + bool operator<(const NameAddr& other) const; + + bool mustQuoteDisplayName() const; + + // Inform the compiler that overloads of these may be found in + // ParserCategory, too. + using ParserCategory::exists; + using ParserCategory::remove; + using ParserCategory::param; + + virtual Parameter* createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool); + bool exists(const Param<NameAddr>& paramType) const; + void remove(const Param<NameAddr>& paramType); + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ + const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \ + _enum##_Param::DType& param(const _enum##_Param& paramType); \ + friend class _enum##_Param + + defineParam(data, "data", ExistsParameter, "RFC 3840"); + defineParam(control, "control", ExistsParameter, "RFC 3840"); + defineParam(mobility, "mobility", QuotedDataParameter, "RFC 3840"); // mobile|fixed + defineParam(description, "description", QuotedDataParameter, "RFC 3840"); // <> quoted + defineParam(events, "events", QuotedDataParameter, "RFC 3840"); // list + defineParam(priority, "priority", QuotedDataParameter, "RFC 3840"); // non-urgent|normal|urgent|emergency + defineParam(methods, "methods", QuotedDataParameter, "RFC 3840"); // list + defineParam(schemes, "schemes", QuotedDataParameter, "RFC 3840"); // list + defineParam(application, "application", ExistsParameter, "RFC 3840"); + defineParam(video, "video", ExistsParameter, "RFC 3840"); + defineParam(language, "language", QuotedDataParameter, "RFC 3840"); // list + defineParam(type, "type", QuotedDataParameter, "RFC 3840"); // list + defineParam(isFocus, "isfocus", ExistsParameter, "RFC 3840"); + defineParam(actor, "actor", QuotedDataParameter, "RFC 3840"); // principal|msg-taker|attendant|information + defineParam(text, "text", ExistsOrDataParameter, "RFC 3840"); + defineParam(extensions, "extensions", QuotedDataParameter, "RFC 3840"); //list + defineParam(Instance, "+sip.instance", QuotedDataParameter, "RFC 5626"); // <> quoted + defineParam(regid, "reg-id", UInt32Parameter, "RFC 5626"); + defineParam(pubGruu, "pub-gruu", QuotedDataParameter, "RFC 5627"); + defineParam(tempGruu, "temp-gruu", QuotedDataParameter, "RFC 5627"); + defineParam(expires, "expires", UInt32Parameter, "RFC 3261"); + defineParam(q, "q", QValueParameter, "RFC 3261"); + defineParam(tag, "tag", DataParameter, "RFC 3261"); + +#undef defineParam + + protected: + bool mAllContacts; + Uri mUri; + Data mDisplayName; + Data* mUnknownUriParametersBuffer; + + private: + + static ParameterTypes::Factory ParameterFactories[ParameterTypes::MAX_PARAMETER]; +}; +typedef ParserContainer<NameAddr> NameAddrs; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/NonceHelper.cxx b/src/libs/resiprocate/resip/stack/NonceHelper.cxx new file mode 100644 index 00000000..afa6a412 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/NonceHelper.cxx @@ -0,0 +1,54 @@ + +#include "resip/stack/NonceHelper.hxx" + +using namespace resip; + +NonceHelper::Nonce::Nonce(UInt64 creationTime) : creationTime(creationTime) +{ +} + +NonceHelper::Nonce::~Nonce() +{ +} + +NonceHelper::~NonceHelper() +{ +} + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/NonceHelper.hxx b/src/libs/resiprocate/resip/stack/NonceHelper.hxx new file mode 100644 index 00000000..ef11074a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/NonceHelper.hxx @@ -0,0 +1,76 @@ +#if !defined(RESIP_NONCEHELPER_HXX) +#define RESIP_NONCEHELPER_HXX + +#include "resip/stack/SipMessage.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +class NonceHelper +{ + public: + + class Nonce + { + private: + UInt64 creationTime; + + public: + Nonce(UInt64 creationTime); + virtual ~Nonce(); + UInt64 getCreationTime() { return creationTime; }; + }; + + virtual ~NonceHelper()=0; + + // Generate a nonce string + virtual Data makeNonce(const SipMessage& request, const Data& timestamp) = 0; + + // Read a nonce string into a Nonce instance, so that we can inspect + // the un-encrypted time stamp + virtual NonceHelper::Nonce parseNonce(const Data& nonce) = 0; +}; + +} + +#endif + + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/OctetContents.cxx b/src/libs/resiprocate/resip/stack/OctetContents.cxx new file mode 100644 index 00000000..a38e5d45 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/OctetContents.cxx @@ -0,0 +1,152 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/OctetContents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +const OctetContents OctetContents::Empty; + +bool +OctetContents::init() +{ + static ContentsFactory<OctetContents> factory; + (void)factory; + return true; +} + +OctetContents::OctetContents() + : Contents(getStaticType()), + mOctets() +{} + +OctetContents::OctetContents(const Data& octets) + : Contents(getStaticType()), + mOctets(octets) +{} + +OctetContents::OctetContents(const HeaderFieldValue& hfv, const Mime& contentsType) + : Contents(hfv, contentsType), + mOctets() +{ +} + +OctetContents::OctetContents(const Data& octets, const Mime& contentsType) + : Contents(contentsType), + mOctets(octets) +{ +} + +OctetContents::OctetContents(const OctetContents& rhs) + : Contents(rhs), + mOctets(rhs.mOctets) +{ +} + +OctetContents::~OctetContents() +{ +} + +OctetContents& +OctetContents::operator=(const OctetContents& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + mOctets = rhs.mOctets; + } + return *this; +} + +Contents* +OctetContents::clone() const +{ + return new OctetContents(*this); +} + +const Mime& +OctetContents::getStaticType() +{ + static Mime type("application","octet-stream"); + return type; +} + +EncodeStream& +OctetContents::encodeParsed(EncodeStream& str) const +{ + //DebugLog(<< "OctetContents::encodeParsed " << mOctets); + str << mOctets; + return str; +} + +void +OctetContents::parse(ParseBuffer& pb) +{ + //DebugLog(<< "OctetContents::parse: " << pb.position()); + + const char* anchor = pb.position(); + pb.skipToEnd(); + pb.data(mOctets, anchor); + + //DebugLog("OctetContents::parsed <" << mOctets << ">" ); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/OctetContents.hxx b/src/libs/resiprocate/resip/stack/OctetContents.hxx new file mode 100644 index 00000000..4f81863e --- /dev/null +++ b/src/libs/resiprocate/resip/stack/OctetContents.hxx @@ -0,0 +1,100 @@ +#if !defined(RESIP_OCTETCONTENTS_HXX) +#define RESIP_OCTETCONTENTS_HXX + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type for holding Octet contents (MIME content-type application/octet-stream). +*/ +class OctetContents : public Contents +{ + public: + static const OctetContents Empty; + + OctetContents(); + OctetContents(const Data& octets); + OctetContents(const HeaderFieldValue& hfv, const Mime& contentType); + OctetContents(const Data& data, const Mime& contentType); + OctetContents(const OctetContents& rhs); + virtual ~OctetContents(); + OctetContents& operator=(const OctetContents& rhs); + + /** @brief duplicate an OctetContents object + @return pointer to a new OctetContents object + **/ + virtual Contents* clone() const; + + //virtual + static const Mime& getStaticType() ; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + Data& octets() {checkParsed(); return mOctets;} + const Data& octets() const {checkParsed(); return mOctets;} + + static bool init(); + private: + Data mOctets; +}; + +static bool invokeOctetContentsInit = OctetContents::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Parameter.cxx b/src/libs/resiprocate/resip/stack/Parameter.cxx new file mode 100644 index 00000000..09ef006a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Parameter.cxx @@ -0,0 +1,76 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Parameter.hxx" + +using namespace resip; +using namespace std; + +Parameter::Parameter(ParameterTypes::Type type) + : mType(type) +{} + + +ParameterTypes::Type +Parameter::getType() const +{ + return mType; +} + + +const Data& +Parameter::getName() const +{ + return ParameterTypes::ParameterNames[mType]; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Parameter.hxx b/src/libs/resiprocate/resip/stack/Parameter.hxx new file mode 100644 index 00000000..a6db0807 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Parameter.hxx @@ -0,0 +1,89 @@ +#if !defined(RESIP_PARAMETER_HXX) +#define RESIP_PARAMETER_HXX + +#include "rutil/Data.hxx" +#include <iosfwd> +#include "resip/stack/ParameterTypeEnums.hxx" + + +namespace resip +{ + +class Parameter +{ + public: + Parameter(ParameterTypes::Type type); + virtual ~Parameter() {} + + ParameterTypes::Type getType() const; + + virtual const Data& getName() const; + + virtual Parameter* clone() const = 0; + + virtual EncodeStream& encode(EncodeStream& stream) const = 0; + + virtual bool isQuoted() const { return false; } // only on DataParameter + virtual void setQuoted(bool /*b*/) { }; // only on DataParameter + + protected: + Parameter(const Parameter& other) : mType(other.mType) {}; + Parameter& operator=(const Parameter& other); // don't define + + private: + ParameterTypes::Type mType; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ParameterHash.cxx b/src/libs/resiprocate/resip/stack/ParameterHash.cxx new file mode 100644 index 00000000..a0225144 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParameterHash.cxx @@ -0,0 +1,415 @@ +/* C++ code produced by gperf version 3.0.4 */ +/* Command-line: gperf -C -D -E -L C++ -t -k '*' --compare-strncmp --ignore-case -Z ParameterHash ParameterHash.gperf */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>." +#endif + +#line 1 "ParameterHash.gperf" + +#include <string.h> +#include <ctype.h> +#include "resip/stack/ParameterTypes.hxx" +namespace resip { +using namespace std; +#line 8 "ParameterHash.gperf" +struct params { const char *name; ParameterTypes::Type type; }; +/* maximum key range = 266, duplicates = 0 */ + +#ifndef GPERF_DOWNCASE +#define GPERF_DOWNCASE 1 +static unsigned char gperf_downcase[256] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255 + }; +#endif + +#ifndef GPERF_CASE_STRNCMP +#define GPERF_CASE_STRNCMP 1 +static int +gperf_case_strncmp (register const char *s1, register const char *s2, register unsigned int n) +{ + for (; n > 0;) + { + unsigned char c1 = gperf_downcase[(unsigned char)*s1++]; + unsigned char c2 = gperf_downcase[(unsigned char)*s2++]; + if (c1 != 0 && c1 == c2) + { + n--; + continue; + } + return (int)c1 - (int)c2; + } + return 0; +} +#endif + +class ParameterHash +{ +private: + static inline unsigned int hash (const char *str, unsigned int len); +public: + static const struct params *in_word_set (const char *str, unsigned int len); +}; + +inline unsigned int +ParameterHash::hash (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 0, 268, 40, 0, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 0, 25, 0, 15, 0, + 15, 35, 75, 10, 268, 10, 0, 25, 5, 5, + 5, 45, 0, 0, 0, 40, 85, 5, 65, 65, + 40, 268, 268, 268, 268, 268, 268, 0, 25, 0, + 15, 0, 15, 35, 75, 10, 268, 10, 0, 25, + 5, 5, 5, 45, 0, 0, 0, 40, 85, 5, + 65, 65, 40, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[12]]; + /*FALLTHROUGH*/ + case 12: + hval += asso_values[(unsigned char)str[11]]; + /*FALLTHROUGH*/ + case 11: + hval += asso_values[(unsigned char)str[10]]; + /*FALLTHROUGH*/ + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + hval += asso_values[(unsigned char)str[1]]; + /*FALLTHROUGH*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval; +} + +const struct params * +ParameterHash::in_word_set (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 90, + MIN_WORD_LENGTH = 1, + MAX_WORD_LENGTH = 13, + MIN_HASH_VALUE = 2, + MAX_HASH_VALUE = 267 + }; + + static const struct params wordlist[] = + { +#line 40 "ParameterHash.gperf" + {"lr", ParameterTypes::lr}, +#line 38 "ParameterHash.gperf" + {"ttl", ParameterTypes::ttl}, +#line 64 "ParameterHash.gperf" + {"stale", ParameterTypes::stale}, +#line 60 "ParameterHash.gperf" + {"nc", ParameterTypes::nc}, +#line 23 "ParameterHash.gperf" + {"actor", ParameterTypes::actor}, +#line 83 "ParameterHash.gperf" + {"site", ParameterTypes::site}, +#line 54 "ParameterHash.gperf" + {"rport", ParameterTypes::rport}, +#line 71 "ParameterHash.gperf" + {"reason", ParameterTypes::reason}, +#line 10 "ParameterHash.gperf" + {"data", ParameterTypes::data}, +#line 59 "ParameterHash.gperf" + {"nonce", ParameterTypes::nonce}, +#line 56 "ParameterHash.gperf" + {"cnonce", ParameterTypes::cnonce}, +#line 11 "ParameterHash.gperf" + {"control", ParameterTypes::control}, +#line 63 "ParameterHash.gperf" + {"response", ParameterTypes::response}, +#line 34 "ParameterHash.gperf" + {"transport", ParameterTypes::transport}, +#line 58 "ParameterHash.gperf" + {"id", ParameterTypes::id}, +#line 77 "ParameterHash.gperf" + {"protocol", ParameterTypes::protocol}, +#line 52 "ParameterHash.gperf" + {"rinstance", ParameterTypes::rinstance}, +#line 62 "ParameterHash.gperf" + {"realm", ParameterTypes::realm}, +#line 29 "ParameterHash.gperf" + {"ob", ParameterTypes::ob}, +#line 33 "ParameterHash.gperf" + {"name", ParameterTypes::name}, +#line 30 "ParameterHash.gperf" + {"gr", ParameterTypes::gr}, +#line 48 "ParameterHash.gperf" + {"tag", ParameterTypes::tag}, +#line 53 "ParameterHash.gperf" + {"comp", ParameterTypes::comp}, +#line 97 "ParameterHash.gperf" + {"url", ParameterTypes::url}, +#line 35 "ParameterHash.gperf" + {"user", ParameterTypes::user}, +#line 25 "ParameterHash.gperf" + {"cause", ParameterTypes::cause}, +#line 41 "ParameterHash.gperf" + {"q", ParameterTypes::q}, +#line 27 "ParameterHash.gperf" + {"+sip.instance", ParameterTypes::Instance}, +#line 85 "ParameterHash.gperf" + {"mode", ParameterTypes::mode}, +#line 91 "ParameterHash.gperf" + {"model", ParameterTypes::model}, +#line 18 "ParameterHash.gperf" + {"application", ParameterTypes::application}, +#line 69 "ParameterHash.gperf" + {"uri", ParameterTypes::uri}, +#line 81 "ParameterHash.gperf" + {"size", ParameterTypes::size}, +#line 99 "ParameterHash.gperf" + {"addtransport", ParameterTypes::addTransport}, +#line 68 "ParameterHash.gperf" + {"qop", ParameterTypes::qop}, +#line 39 "ParameterHash.gperf" + {"maddr", ParameterTypes::maddr}, +#line 13 "ParameterHash.gperf" + {"description", ParameterTypes::description}, +#line 42 "ParameterHash.gperf" + {"purpose", ParameterTypes::purpose}, +#line 76 "ParameterHash.gperf" + {"filename", ParameterTypes::filename}, +#line 57 "ParameterHash.gperf" + {"domain", ParameterTypes::domain}, +#line 36 "ParameterHash.gperf" + {"ext", ParameterTypes::extension}, +#line 24 "ParameterHash.gperf" + {"text", ParameterTypes::text}, +#line 82 "ParameterHash.gperf" + {"permission", ParameterTypes::permission}, +#line 21 "ParameterHash.gperf" + {"type", ParameterTypes::type}, +#line 78 "ParameterHash.gperf" + {"micalg", ParameterTypes::micalg}, +#line 22 "ParameterHash.gperf" + {"isfocus", ParameterTypes::isFocus}, +#line 65 "ParameterHash.gperf" + {"username", ParameterTypes::username}, +#line 95 "ParameterHash.gperf" + {"app-id", ParameterTypes::appId}, +#line 87 "ParameterHash.gperf" + {"charset", ParameterTypes::charset}, +#line 45 "ParameterHash.gperf" + {"duration", ParameterTypes::duration}, +#line 43 "ParameterHash.gperf" + {"to-tag", ParameterTypes::toTag}, +#line 46 "ParameterHash.gperf" + {"expires", ParameterTypes::expires}, +#line 86 "ParameterHash.gperf" + {"server", ParameterTypes::server}, +#line 72 "ParameterHash.gperf" + {"d-alg", ParameterTypes::dAlg}, +#line 14 "ParameterHash.gperf" + {"events", ParameterTypes::events}, +#line 94 "ParameterHash.gperf" + {"document", ParameterTypes::document}, +#line 67 "ParameterHash.gperf" + {"refresher", ParameterTypes::refresher}, +#line 26 "ParameterHash.gperf" + {"extensions", ParameterTypes::extensions}, +#line 61 "ParameterHash.gperf" + {"opaque", ParameterTypes::opaque}, +#line 51 "ParameterHash.gperf" + {"require", ParameterTypes::require}, +#line 15 "ParameterHash.gperf" + {"priority", ParameterTypes::priority}, +#line 84 "ParameterHash.gperf" + {"directory", ParameterTypes::directory}, +#line 28 "ParameterHash.gperf" + {"reg-id", ParameterTypes::regid}, +#line 17 "ParameterHash.gperf" + {"schemes", ParameterTypes::schemes}, +#line 80 "ParameterHash.gperf" + {"expiration", ParameterTypes::expiration}, +#line 49 "ParameterHash.gperf" + {"branch", ParameterTypes::branch}, +#line 92 "ParameterHash.gperf" + {"version", ParameterTypes::version}, +#line 73 "ParameterHash.gperf" + {"d-qop", ParameterTypes::dQop}, +#line 90 "ParameterHash.gperf" + {"vendor", ParameterTypes::vendor}, +#line 96 "ParameterHash.gperf" + {"network-user", ParameterTypes::networkUser}, +#line 50 "ParameterHash.gperf" + {"received", ParameterTypes::received}, +#line 19 "ParameterHash.gperf" + {"video", ParameterTypes::video}, +#line 88 "ParameterHash.gperf" + {"access-type", ParameterTypes::accessType}, +#line 20 "ParameterHash.gperf" + {"language", ParameterTypes::language}, +#line 37 "ParameterHash.gperf" + {"method", ParameterTypes::method}, +#line 16 "ParameterHash.gperf" + {"methods", ParameterTypes::methods}, +#line 44 "ParameterHash.gperf" + {"from-tag", ParameterTypes::fromTag}, +#line 70 "ParameterHash.gperf" + {"retry-after", ParameterTypes::retryAfter}, +#line 74 "ParameterHash.gperf" + {"d-ver", ParameterTypes::dVer}, +#line 12 "ParameterHash.gperf" + {"mobility", ParameterTypes::mobility}, +#line 47 "ParameterHash.gperf" + {"handling", ParameterTypes::handling}, +#line 98 "ParameterHash.gperf" + {"sigcomp-id", ParameterTypes::sigcompId}, +#line 89 "ParameterHash.gperf" + {"profile-type", ParameterTypes::profileType}, +#line 55 "ParameterHash.gperf" + {"algorithm", ParameterTypes::algorithm}, +#line 79 "ParameterHash.gperf" + {"boundary", ParameterTypes::boundary}, +#line 75 "ParameterHash.gperf" + {"smime-type", ParameterTypes::smimeType}, +#line 66 "ParameterHash.gperf" + {"early-only", ParameterTypes::earlyOnly}, +#line 32 "ParameterHash.gperf" + {"temp-gruu", ParameterTypes::tempGruu}, +#line 31 "ParameterHash.gperf" + {"pub-gruu", ParameterTypes::pubGruu}, +#line 93 "ParameterHash.gperf" + {"effective-by", ParameterTypes::effectiveBy} + }; + + static const signed char lookup[] = + { + -1, -1, 0, 1, -1, 2, -1, 3, -1, -1, 4, -1, -1, -1, + 5, 6, 7, -1, -1, 8, 9, 10, 11, 12, 13, -1, -1, 14, + 15, 16, 17, -1, 18, -1, 19, -1, -1, 20, 21, 22, -1, -1, + -1, 23, 24, 25, 26, -1, 27, 28, 29, 30, -1, 31, 32, -1, + -1, 33, 34, -1, 35, 36, 37, 38, -1, -1, 39, -1, 40, 41, + 42, -1, -1, -1, 43, -1, 44, 45, 46, -1, -1, 47, 48, 49, + -1, -1, 50, 51, -1, -1, -1, 52, -1, -1, -1, 53, 54, -1, + 55, 56, 57, 58, 59, 60, 61, -1, 62, 63, -1, -1, 64, 65, + 66, -1, -1, 67, 68, 69, 70, -1, 71, 72, -1, 73, -1, -1, + 74, 75, 76, -1, -1, 77, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 78, -1, -1, 79, -1, -1, -1, -1, 80, + -1, 81, -1, 82, -1, 83, -1, -1, -1, 84, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 85, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 86, -1, -1, -1, 87, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 89 + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int index = lookup[key]; + + if (index >= 0) + { + register const char *s = wordlist[index].name; + + if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strncmp (str, s, len) && s[len] == '\0') + return &wordlist[index]; + } + } + } + return 0; +} +#line 100 "ParameterHash.gperf" + +} diff --git a/src/libs/resiprocate/resip/stack/ParameterHash.gperf b/src/libs/resiprocate/resip/stack/ParameterHash.gperf new file mode 100644 index 00000000..5012c063 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParameterHash.gperf @@ -0,0 +1,101 @@ +%{ +#include <string.h> +#include <ctype.h> +#include "resip/stack/ParameterTypes.hxx" +namespace resip { +using namespace std; +%} +struct params { const char *name; ParameterTypes::Type type; }; +%% +data, ParameterTypes::data +control, ParameterTypes::control +mobility, ParameterTypes::mobility +description, ParameterTypes::description +events, ParameterTypes::events +priority, ParameterTypes::priority +methods, ParameterTypes::methods +schemes, ParameterTypes::schemes +application, ParameterTypes::application +video, ParameterTypes::video +language, ParameterTypes::language +type, ParameterTypes::type +isfocus, ParameterTypes::isFocus +actor, ParameterTypes::actor +text, ParameterTypes::text +cause, ParameterTypes::cause +extensions, ParameterTypes::extensions ++sip.instance, ParameterTypes::Instance +reg-id, ParameterTypes::regid +ob, ParameterTypes::ob +gr, ParameterTypes::gr +pub-gruu, ParameterTypes::pubGruu +temp-gruu, ParameterTypes::tempGruu +name, ParameterTypes::name +transport, ParameterTypes::transport +user, ParameterTypes::user +ext, ParameterTypes::extension +method, ParameterTypes::method +ttl, ParameterTypes::ttl +maddr, ParameterTypes::maddr +lr, ParameterTypes::lr +q, ParameterTypes::q +purpose, ParameterTypes::purpose +to-tag, ParameterTypes::toTag +from-tag, ParameterTypes::fromTag +duration, ParameterTypes::duration +expires, ParameterTypes::expires +handling, ParameterTypes::handling +tag, ParameterTypes::tag +branch, ParameterTypes::branch +received, ParameterTypes::received +require, ParameterTypes::require +rinstance, ParameterTypes::rinstance +comp, ParameterTypes::comp +rport, ParameterTypes::rport +algorithm, ParameterTypes::algorithm +cnonce, ParameterTypes::cnonce +domain, ParameterTypes::domain +id, ParameterTypes::id +nonce, ParameterTypes::nonce +nc, ParameterTypes::nc +opaque, ParameterTypes::opaque +realm, ParameterTypes::realm +response, ParameterTypes::response +stale, ParameterTypes::stale +username, ParameterTypes::username +early-only, ParameterTypes::earlyOnly +refresher, ParameterTypes::refresher +qop, ParameterTypes::qop +uri, ParameterTypes::uri +retry-after, ParameterTypes::retryAfter +reason, ParameterTypes::reason +d-alg, ParameterTypes::dAlg +d-qop, ParameterTypes::dQop +d-ver, ParameterTypes::dVer +smime-type, ParameterTypes::smimeType +filename, ParameterTypes::filename +protocol, ParameterTypes::protocol +micalg, ParameterTypes::micalg +boundary, ParameterTypes::boundary +expiration, ParameterTypes::expiration +size, ParameterTypes::size +permission, ParameterTypes::permission +site, ParameterTypes::site +directory, ParameterTypes::directory +mode, ParameterTypes::mode +server, ParameterTypes::server +charset, ParameterTypes::charset +access-type, ParameterTypes::accessType +profile-type, ParameterTypes::profileType +vendor, ParameterTypes::vendor +model, ParameterTypes::model +version, ParameterTypes::version +effective-by, ParameterTypes::effectiveBy +document, ParameterTypes::document +app-id, ParameterTypes::appId +network-user, ParameterTypes::networkUser +url, ParameterTypes::url +sigcomp-id, ParameterTypes::sigcompId +addtransport, ParameterTypes::addTransport +%% +} diff --git a/src/libs/resiprocate/resip/stack/ParameterHash.hxx b/src/libs/resiprocate/resip/stack/ParameterHash.hxx new file mode 100644 index 00000000..52d92aa9 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParameterHash.hxx @@ -0,0 +1,68 @@ +#if !defined(PARAMETERHASH_HXX) +#define PARAMETERHASH_HXX +namespace resip +{ +struct params { char *name; ParameterTypes::Type type; }; +/* maximum key range = 494, duplicates = 0 */ + +class ParameterHash +{ +private: + static inline unsigned int hash (const char *str, unsigned int len); +public: + static const struct params *in_word_set (const char *str, unsigned int len); +}; +// NOTE the cxx file for this class is AUTO GENERATED. DO NOT EDIT IT. +// This file should match it. BUT THIS FILE IS MANUALLY GENERATED. +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ParameterTypeEnums.hxx b/src/libs/resiprocate/resip/stack/ParameterTypeEnums.hxx new file mode 100644 index 00000000..794d8b97 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParameterTypeEnums.hxx @@ -0,0 +1,235 @@ +#if !defined(RESIP_PARAMETERTYPEENUMS_HXX) +#define RESIP_PARAMETERTYPEENUMS_HXX + +#include "rutil/Data.hxx" + +/** + @internal + @brief local definition for this file, translates the defineParams to + simply enums using the first parameter passed to the defineParam + @note defineParam is hence defined differently in different header files some + of which use the other parameters that are passed as well. + */ +#define defineParam(_enum, _name, _type, _rfc) _enum +/** + @brief unused as of nov 12th, 2007 + @internal + */ +#define UNUSED_defineParam(_enum, _name, _type, _rfc) SAVE##_enum, _enum = UNKNOWN, RESET##enum = SAVE##_enum-1 + +namespace resip +{ + +class Parameter; +class ParseBuffer; +class PoolBase; + + /** + @ingroup sip_grammar + @brief This is one of the places where new parameter types must be defined. + There must be corresponding entries in ParameterTypes.[ch]xx, + Parameters.gperf and ParserCategory.[ch]xx + @note If you make any changes, run testParserCategories to ensure that + the changes are consistent. + @class ParameterTypes + @internal + @see ParamBase + */ +class ParameterTypes +{ + + public: + // !dlb! until automated, must ensure that this set is consistent with + // gperf in ParameterTypes.cxx, ParameterTypes.hxx, Parameters.gperf + // NOTE: !!Parameters.gperf must have lowercase parameters!! + // Also needs to be in ParserCategory.hxx/cxx + // PLEASE compile and run testParserCategories after changing this file. + enum Type + { + UNKNOWN = -1, + defineParam(data, "data", ExistsParameter, "RFC 3840"), + defineParam(control, "control", ExistsParameter, "RFC 3840"), + defineParam(mobility, "mobility", QuotedDataParameter, "RFC 3840"), // mobile|fixed + defineParam(description, "description", QuotedDataParameter, "RFC 3840"), // <> quoted + defineParam(events, "events", QuotedDataParameter, "RFC 3840"), // list + defineParam(priority, "priority", QuotedDataParameter, "RFC 3840"), // non-urgent|normal|urgent|emergency + defineParam(methods, "methods", QuotedDataParameter, "RFC 3840"), // list + defineParam(schemes, "schemes", QuotedDataParameter, "RFC 3840"), // list + defineParam(application, "application", ExistsParameter, "RFC 3840"), + defineParam(video, "video", ExistsParameter, "RFC 3840"), + defineParam(language, "language", QuotedDataParameter, "RFC 3840"), // list + defineParam(type, "type", QuotedDataParameter, "RFC 3840"), // list + defineParam(isFocus, "isfocus", ExistsParameter, "RFC 3840"), + defineParam(actor, "actor", QuotedDataParameter, "RFC 3840"), // principal|msg-taker|attendant|information + defineParam(text, "text", ExistsOrDataParameter, "RFC 3326/3840"), // using ExistsOrDataParameter so this parameter is compatible with both RFC3840 and RFC3326 + defineParam(cause, "cause", UInt32Parameter, "RFC3326"), + defineParam(extensions, "extensions", QuotedDataParameter, "RFC 3840"), //list + + defineParam(Instance, "+sip.instance", QuotedDataParameter, "RFC 5626"), // <> quoted + defineParam(regid, "reg-id", UInt32Parameter, "RFC 5626"), + defineParam(ob,"ob",ExistsParameter, "RFC 5626"), + + defineParam(pubGruu, "pub-gruu", QuotedDataParameter, "RFC 5627"), + defineParam(tempGruu, "temp-gruu", QuotedDataParameter, "RFC 5627"), + defineParam(gr, "gr", ExistsOrDataParameter, "RFC 5627"), + + defineParam(accessType, "access-type", DataParameter, "RFC 2046"), + defineParam(algorithm, "algorithm", DataParameter, "RFC ????"), + defineParam(boundary, "boundary", DataParameter, "RFC 2046"), + defineParam(branch, "branch", BranchParameter, "RFC ????"), + defineParam(charset, "charset", DataParameter, "RFC 2045"), + defineParam(cnonce, "cnonce", QuotedDataParameter, "RFC ????"), + defineParam(comp, "comp", DataParameter, "RFC ????"), + defineParam(dAlg, "d-alg", DataParameter, "RFC 3329"), + defineParam(dQop, "d-qop", DataParameter, "RFC ????"), + defineParam(dVer, "d-ver", QuotedDataParameter, "RFC ????"), + defineParam(directory, "directory", DataParameter, "RFC 2046"), + defineParam(domain, "domain", QuotedDataParameter, "RFC ????"), + defineParam(duration, "duration", UInt32Parameter, "RFC ????"), + defineParam(expiration, "expiration", QuotedDataParameter, "RFC 2046"), + defineParam(expires, "expires", UInt32Parameter, "RFC ????"), + defineParam(filename, "filename", DataParameter, "RFC ????"), + defineParam(fromTag, "from-tag", DataParameter, "RFC ????"), + defineParam(handling, "handling", DataParameter, "RFC ????"), + defineParam(id, "id", DataParameter, "RFC ????"), + defineParam(lr, "lr", ExistsParameter, "RFC ????"), + defineParam(maddr, "maddr", DataParameter, "RFC ????"), + defineParam(method, "method", DataParameter, "RFC ????"), + defineParam(micalg, "micalg", DataParameter, "RFC 1847"), + defineParam(mode, "mode", DataParameter, "RFC 2046"), + defineParam(name, "name", DataParameter, "RFC 2046"), + defineParam(nc, "nc", DataParameter, "RFC ????"), + defineParam(nonce, "nonce", QuotedDataParameter, "RFC ????"), + defineParam(opaque, "opaque", QuotedDataParameter, "RFC ????"), + defineParam(permission, "permission", DataParameter, "RFC 2046"), + defineParam(protocol, "protocol", QuotedDataParameter, "RFC 1847"), + defineParam(purpose, "purpose", DataParameter, "RFC ????"), + defineParam(q, "q", QValueParameter, "RFC 3261"), + + defineParam(realm, "realm", QuotedDataParameter, "RFC ????"), + defineParam(reason, "reason", DataParameter, "RFC ????"), + defineParam(received, "received", DataParameter, "RFC ????"), + defineParam(require, "require", DataParameter, "RFC 5373"), + defineParam(response, "response", QuotedDataParameter, "RFC ????"), + defineParam(retryAfter, "retry-after", UInt32Parameter, "RFC ????"), + defineParam(rinstance, "rinstance", DataParameter, "Internal"), + defineParam(rport, "rport", RportParameter, "RFC 3851"), + defineParam(server, "server", DataParameter, "RFC 2046"), + defineParam(site, "site", DataParameter, "RFC 2046"), + defineParam(size, "size", DataParameter, "RFC 2046"), + defineParam(smimeType, "smime-type", DataParameter, "RFC 2633"), + defineParam(stale, "stale", DataParameter, "RFC ????"), + defineParam(tag, "tag", DataParameter, "RFC 3261"), + defineParam(toTag, "to-tag", DataParameter, "RFC ????"), + defineParam(transport, "transport", DataParameter, "RFC 3261"), + defineParam(ttl, "ttl", UInt32Parameter, "RFC 3261"), + defineParam(uri, "uri", QuotedDataParameter, "RFC ????"), + defineParam(user, "user", DataParameter, "RFC ????"), + defineParam(extension, "ext", DataParameter, "RFC ????"), + defineParam(username, "username", DataParameter, "RFC ????"), + defineParam(earlyOnly, "early-only", ExistsParameter, "RFC 3891"), + defineParam(refresher, "refresher", DataParameter, "RFC 4028"), + + defineParam(profileType, "profile-type", DataParameter, "draft-ietf-sipping-config-framework"), + defineParam(vendor, "vendor", QuotedDataParameter, "draft-ietf-sipping-config-framework"), + defineParam(model, "model", QuotedDataParameter, "draft-ietf-sipping-config-framework"), + defineParam(version, "version", QuotedDataParameter, "draft-ietf-sipping-config-framework"), + defineParam(effectiveBy, "effective-by", UInt32Parameter, "draft-ietf-sipping-config-framework"), + defineParam(document, "document", DataParameter, "draft-ietf-sipping-config-framework"), + defineParam(appId, "app-id", DataParameter, "draft-ietf-sipping-config-framework"), + defineParam(networkUser, "network-user", DataParameter, "draft-ietf-sipping-config-framework"), + + defineParam(url, "url", QuotedDataParameter, "draft-ietf-sip-content-indirect-mech-05"), + + + defineParam(sigcompId, "sigcomp-id", QuotedDataParameter, "draft-ietf-rohc-sigcomp-sip"), + defineParam(qop, "qop", DataParameter, "RFC 3261"), + defineParam(qopOptions, "qop", DataParameter, "RFC 3261"), + defineParam(addTransport, "addTransport", ExistsParameter, "Internal"), + + MAX_PARAMETER + }; + + /** + @brief does a convert to enum from a pointer into the HFV raw buffer + */ + static Type getType(const char* start, unsigned int length); + + /** + @param ParameterTypes::Type class on which to call decode to get + the Parameter* + @param ParseBuffer buffer to parse + @param terminators The terminator characters to use + @return ParameterTypes::Type.decode() defined in each class type. + */ + typedef Parameter* (*Factory)(ParameterTypes::Type, ParseBuffer&, const std::bitset<256>& terminators, PoolBase* pool); + + /** + @brief static array of Factorys indexed by the 2nd element + in defineParam(...) + */ + static Factory ParameterFactories[MAX_PARAMETER]; + + /** + @brief static array of ParameterNames indexed by the 2nd element + in defineParam(...) + */ + static Data ParameterNames[MAX_PARAMETER]; +}; + +} + +#undef defineParam +#undef UNUSED_defineParam + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ParameterTypes.cxx b/src/libs/resiprocate/resip/stack/ParameterTypes.cxx new file mode 100644 index 00000000..6e7bc57d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParameterTypes.cxx @@ -0,0 +1,210 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/ParameterTypes.hxx" +#include "resip/stack/ParserCategories.hxx" +#include "rutil/compat.hxx" +#include <iostream> + +#define defineParam(_enum, _name, _type, _headertype, _RFC_ref_ignored) \ +ParameterTypes::Type \ +_enum##_Param::getTypeNum() const {return ParameterTypes::_enum;} \ +_enum##_Param::_enum##_Param() \ +{ \ + _headertype::ParameterFactories[ParameterTypes::_enum] = Type::decode; \ + ParameterTypes::ParameterNames[ParameterTypes::_enum] = _name; \ +} \ +_enum##_Param resip::p_##_enum + +#define defineParam2(_enum, _name, _type, _headertype, _headertype2, _RFC_ref_ignored) \ +ParameterTypes::Type \ +_enum##_Param::getTypeNum() const {return ParameterTypes::_enum;} \ +_enum##_Param::_enum##_Param() \ +{ \ + _headertype::ParameterFactories[ParameterTypes::_enum] = Type::decode; \ + _headertype2::ParameterFactories[ParameterTypes::_enum] = Type::decode; \ + ParameterTypes::ParameterNames[ParameterTypes::_enum] = _name; \ +} \ +_enum##_Param resip::p_##_enum + + +#define defineParam3(_enum, _name, _type, _headertype, _headertype2, _headertype3, _RFC_ref_ignored) \ +ParameterTypes::Type \ +_enum##_Param::getTypeNum() const {return ParameterTypes::_enum;} \ +_enum##_Param::_enum##_Param() \ +{ \ + _headertype::ParameterFactories[ParameterTypes::_enum] = Type::decode; \ + _headertype2::ParameterFactories[ParameterTypes::_enum] = Type::decode; \ + _headertype3::ParameterFactories[ParameterTypes::_enum] = Type::decode; \ + ParameterTypes::ParameterNames[ParameterTypes::_enum] = _name; \ +} \ +_enum##_Param resip::p_##_enum + +int strncasecmp(char*,char*,int); + +using namespace std; + +using namespace resip; + +ParameterTypes::Factory ParameterTypes::ParameterFactories[ParameterTypes::MAX_PARAMETER] = {0}; +Data ParameterTypes::ParameterNames[ParameterTypes::MAX_PARAMETER] = {"PARAMETER?"}; + +defineParam(data, "data", ExistsParameter, NameAddr, "RFC 3840"); +defineParam(control, "control", ExistsParameter, NameAddr, "RFC 3840"); +defineParam(mobility, "mobility", QuotedDataParameter, NameAddr, "RFC 3840"); // mobile|fixed +defineParam(description, "description", QuotedDataParameter, NameAddr, "RFC 3840"); // <> quoted +defineParam(events, "events", QuotedDataParameter, NameAddr, "RFC 3840"); // list +defineParam(priority, "priority", QuotedDataParameter, NameAddr, "RFC 3840"); // non-urgent|normal|urgent|emergency +defineParam(methods, "methods", QuotedDataParameter, NameAddr, "RFC 3840"); // list +defineParam(schemes, "schemes", QuotedDataParameter, NameAddr, "RFC 3840"); // list +defineParam(application, "application", ExistsParameter, NameAddr, "RFC 3840"); +defineParam(video, "video", ExistsParameter, NameAddr, "RFC 3840"); +defineParam(language, "language", QuotedDataParameter, NameAddr, "RFC 3840"); // list +defineParam(type, "type", QuotedDataParameter, NameAddr, "RFC 3840"); // list +defineParam(isFocus, "isfocus", ExistsParameter, NameAddr, "RFC 3840"); +defineParam(actor, "actor", QuotedDataParameter, NameAddr, "RFC 3840"); // principal|msg-taker|attendant|information +defineParam2(text, "text", ExistsOrDataParameter, NameAddr, Token, "RFC 3326/3840"); +defineParam(cause, "cause", UInt32Parameter, Token, "RFC3326"); +defineParam(extensions, "extensions", QuotedDataParameter, NameAddr, "RFC 3840"); //list +defineParam(Instance, "+sip.instance", QuotedDataParameter, NameAddr, "RFC 5626"); // <> quoted +defineParam(regid, "reg-id", UInt32Parameter, NameAddr, "RFC 5626"); +defineParam(ob,"ob",ExistsParameter, Uri, "RFC 5626"); +defineParam(pubGruu, "pub-gruu", QuotedDataParameter, NameAddr, "RFC 5627"); +defineParam(tempGruu, "temp-gruu", QuotedDataParameter, NameAddr, "RFC 5627"); +defineParam(gr, "gr", ExistsOrDataParameter, Uri, "RFC 5627"); + +defineParam(accessType, "access-type", DataParameter, Mime, "RFC 2046"); +defineParam(algorithm, "algorithm", DataParameter, Auth, "RFC 2617"); +defineParam(boundary, "boundary", DataParameter, Mime, "RFC 2046"); +defineParam(branch, "branch", BranchParameter, Via, "RFC 3261"); +defineParam(charset, "charset", DataParameter, Mime, "RFC 2045"); +defineParam(cnonce, "cnonce", QuotedDataParameter, Auth, "RFC 2617"); +defineParam2(comp, "comp", DataParameter, Uri, Via, "RFC 3486"); +defineParam(dAlg, "d-alg", DataParameter, Token, "RFC 3329"); +defineParam(dQop, "d-qop", DataParameter, Token, "RFC 3329"); +defineParam(dVer, "d-ver", QuotedDataParameter, Token, "RFC 3329"); +defineParam(directory, "directory", DataParameter, Mime, "RFC 2046"); +defineParam(domain, "domain", QuotedDataParameter, Auth, "RFC 3261"); +defineParam(duration, "duration", UInt32Parameter, Uri, "RFC 4240"); +defineParam(expiration, "expiration", QuotedDataParameter, Mime, "RFC 2046"); +defineParam2(expires, "expires", UInt32Parameter, NameAddr, Token, "RFC 3261"); +defineParam(filename, "filename", DataParameter, Token, "RFC 2183"); +defineParam2(fromTag, "from-tag", DataParameter, Token, CallID, "RFC 4235"); +defineParam(handling, "handling", DataParameter, Token, "RFC 3261"); +defineParam(id, "id", DataParameter, Token, "RFC 3265"); +defineParam(lr, "lr", ExistsParameter, Uri, "RFC 3261"); +defineParam2(maddr, "maddr", DataParameter, Uri, Via, "RFC 3261"); +defineParam(method, "method", DataParameter, Uri, "RFC 3261"); +defineParam(micalg, "micalg", DataParameter, Mime, "RFC 1847"); +defineParam(mode, "mode", DataParameter, Mime, "RFC 2046"); +defineParam(name, "name", DataParameter, Mime, "RFC 2046"); +defineParam(nc, "nc", DataParameter, Auth, "RFC 2617"); +defineParam(nonce, "nonce", QuotedDataParameter, Auth, "RFC 2617"); +defineParam(opaque, "opaque", QuotedDataParameter, Auth, "RFC 2617"); +defineParam(permission, "permission", DataParameter, Mime, "RFC 2046"); +defineParam(protocol, "protocol", QuotedDataParameter, Mime, "RFC 1847"); +defineParam(purpose, "purpose", DataParameter, GenericUri, "RFC 3261"); +defineParam3(q, "q", QValueParameter, NameAddr, Token, Mime, "RFC 3261"); +defineParam(realm, "realm", QuotedDataParameter, Auth, "RFC 2617"); +defineParam(reason, "reason", DataParameter, Token, "RFC 3265"); +defineParam(received, "received", DataParameter, Via, "RFC 3261"); +defineParam(require, "require", DataParameter, Token, "RFC 5373"); +defineParam(response, "response", QuotedDataParameter, Auth, "RFC 3261"); +defineParam(retryAfter, "retry-after", UInt32Parameter, Token, "RFC 3265"); +defineParam(rinstance, "rinstance", DataParameter, Uri, "proprietary (resip)"); +defineParam(rport, "rport", RportParameter, Via, "RFC 3581"); +defineParam(server, "server", DataParameter, Mime, "RFC 2046"); +defineParam(site, "site", DataParameter, Mime, "RFC 2046"); +defineParam(size, "size", DataParameter, Mime, "RFC 2046"); +defineParam(smimeType, "smime-type", DataParameter, Mime, "RFC 2633"); +defineParam(stale, "stale", DataParameter, Auth, "RFC 2617"); +defineParam(tag, "tag", DataParameter, NameAddr, "RFC 3261"); +defineParam2(toTag, "to-tag", DataParameter, Token, CallID, "RFC 4235"); +defineParam(transport, "transport", DataParameter, Uri, "RFC 3261"); +defineParam2(ttl, "ttl", UInt32Parameter, Uri, Via, "RFC 3261"); +defineParam(uri, "uri", QuotedDataParameter, Auth, "RFC 3261"); +defineParam(user, "user", DataParameter, Uri, "RFC 3261, 4967"); +defineParam2(extension, "ext", DataParameter, Uri, Token, "RFC 3966"); // Token is used when ext is a user-parameter +defineParam(username, "username", QuotedDataParameter, Auth, "RFC 3261"); +defineParam(earlyOnly, "early-only", ExistsParameter, CallID, "RFC 3891"); +defineParam(refresher, "refresher", DataParameter, ExpiresCategory, "RFC 4028"); + +defineParam(profileType, "profile-type", DataParameter, Token, "RFC 6080"); +defineParam(vendor, "vendor", QuotedDataParameter, Token, "RFC 6080"); +defineParam(model, "model", QuotedDataParameter, Token, "RFC 6080"); +defineParam(version, "version", QuotedDataParameter, Token, "RFC 6080"); +defineParam(effectiveBy, "effective-by", UInt32Parameter, Token, "RFC 6080"); +defineParam(document, "document", DataParameter, Token, "draft-ietf-sipping-config-framework-07 (removed in 08)"); +defineParam(appId, "app-id", DataParameter, Token, "draft-ietf-sipping-config-framework-05 (renamed to auid in 06, which was then removed in 08)"); +defineParam(networkUser, "network-user", DataParameter, Token, "draft-ietf-sipping-config-framework-11 (removed in 12)"); + +defineParam(url, "url", QuotedDataParameter, Mime, "RFC 4483"); + +defineParam2(sigcompId, "sigcomp-id", QuotedDataParameter, Uri, Via, "RFC 5049"); +defineParam(qop,"qop",DataParameter, Auth, "RFC 3261"); + +// Internal use only +defineParam(qopOptions,"qop",DataParameter, Auth, "RFC 3261"); +defineParam(addTransport, "addTransport", ExistsParameter, Uri, "RESIP INTERNAL"); + +#include "resip/stack/ParameterHash.hxx" + +ParameterTypes::Type +ParameterTypes::getType(const char* pname, unsigned int len) +{ + const struct params* p; + p = ParameterHash::in_word_set(pname, len); + return p ? p->type : ParameterTypes::UNKNOWN; + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ParameterTypes.hxx b/src/libs/resiprocate/resip/stack/ParameterTypes.hxx new file mode 100644 index 00000000..7a7858e1 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParameterTypes.hxx @@ -0,0 +1,243 @@ +#if !defined(RESIP_PARAMETERTYPES_HXX) +#define RESIP_PARAMETERTYPES_HXX + +#include "resip/stack/BranchParameter.hxx" +#include "resip/stack/DataParameter.hxx" +#include "resip/stack/ExistsOrDataParameter.hxx" +#include "resip/stack/QuotedDataParameter.hxx" +#include "resip/stack/IntegerParameter.hxx" +#include "resip/stack/UInt32Parameter.hxx" +#include "resip/stack/QValueParameter.hxx" +#include "resip/stack/ExistsParameter.hxx" +#include "resip/stack/ParameterTypeEnums.hxx" +#include "resip/stack/RportParameter.hxx" +#include "resip/stack/Symbols.hxx" + + +#define defineParam(_enum, _name, _type, _headertype, _RFC_ref_ignored) \ + class _enum##_Param : public Param<_headertype> \ + { \ + public: \ + typedef _type Type; \ + typedef _type::Type DType; \ + virtual ParameterTypes::Type getTypeNum() const; \ + virtual const char* name() const { return _name; } \ + _enum##_Param(); \ + }; \ + extern _enum##_Param p_##_enum + +#define defineParam2(_enum, _name, _type, _headertype, _headertype2, _RFC_ref_ignored) \ + class _enum##_Param : public Param<_headertype>, public Param<_headertype2> \ + { \ + public: \ + typedef _type Type; \ + typedef _type::Type DType; \ + virtual ParameterTypes::Type getTypeNum() const; \ + virtual const char* name() const { return _name; } \ + _enum##_Param(); \ + }; \ + extern _enum##_Param p_##_enum + +// .bwc. So far, I have not discovered any parameter types that are defined for +// more than three ParserCategories. This may change. If so, we just create +// another macro with one more _headertype field. +#define defineParam3(_enum, _name, _type, _headertype, _headertype2, _headertype3, _RFC_ref_ignored) \ + class _enum##_Param : public Param<_headertype>, public Param<_headertype2>, public Param<_headertype3> \ + { \ + public: \ + typedef _type Type; \ + typedef _type::Type DType; \ + virtual ParameterTypes::Type getTypeNum() const; \ + virtual const char* name() const { return _name; } \ + _enum##_Param(); \ + }; \ + extern _enum##_Param p_##_enum + +namespace resip +{ +class ParamBase +{ + public: + virtual ~ParamBase() {} + virtual ParameterTypes::Type getTypeNum() const = 0; + virtual const char* name() const = 0; +}; + +template<class T> +class Param : virtual public ParamBase +{}; + +class Auth; +class CSeqCategory; +class CallID; +class DateCategory; +class ExpiresCategory; +class GenericUri; +class IntegerCategory; +class UInt32Category; +class Mime; +class NameAddr; +class PrivacyCategory; +class RAckCategory; +class RequestLine; +class StatusLine; +class StringCategory; +class Token; +class Uri; +class Via; +class WarningCategory; + +defineParam(data, "data", ExistsParameter, NameAddr, "RFC 3840"); +defineParam(control, "control", ExistsParameter, NameAddr, "RFC 3840"); +defineParam(mobility, "mobility", QuotedDataParameter, NameAddr, "RFC 3840"); // mobile|fixed +defineParam(description, "description", QuotedDataParameter, NameAddr, "RFC 3840"); // <> quoted +defineParam(events, "events", QuotedDataParameter, NameAddr, "RFC 3840"); // list +defineParam(priority, "priority", QuotedDataParameter, NameAddr, "RFC 3840"); // non-urgent|normal|urgent|emergency +defineParam(methods, "methods", QuotedDataParameter, NameAddr, "RFC 3840"); // list +defineParam(schemes, "schemes", QuotedDataParameter, NameAddr, "RFC 3840"); // list +defineParam(application, "application", ExistsParameter, NameAddr, "RFC 3840"); +defineParam(video, "video", ExistsParameter, NameAddr, "RFC 3840"); +defineParam(language, "language", QuotedDataParameter, NameAddr, "RFC 3840"); // list +defineParam(type, "type", QuotedDataParameter, NameAddr, "RFC 3840"); // list +defineParam(isFocus, "isfocus", ExistsParameter, NameAddr, "RFC 3840"); +defineParam(actor, "actor", QuotedDataParameter, NameAddr, "RFC 3840"); // principal|msg-taker|attendant|information +defineParam2(text, "text", ExistsOrDataParameter, NameAddr, Token, "RFC 3326/3840"); +defineParam(cause, "cause", UInt32Parameter, Token, "RFC3326"); +defineParam(extensions, "extensions", QuotedDataParameter, NameAddr, "RFC 3840"); //list +defineParam(Instance, "+sip.instance", QuotedDataParameter, NameAddr, "RFC 5626"); // <> quoted +defineParam(regid, "reg-id", UInt32Parameter, NameAddr, "RFC 5626"); +defineParam(ob,"ob",ExistsParameter, Uri, "RFC 5626"); +defineParam(pubGruu, "pub-gruu", QuotedDataParameter, NameAddr, "RFC 5627"); +defineParam(tempGruu, "temp-gruu", QuotedDataParameter, NameAddr, "RFC 5627"); +defineParam(gr, "gr", ExistsOrDataParameter, Uri, "RFC 5627"); + +defineParam(accessType, "access-type", DataParameter, Mime, "RFC 2046"); +defineParam(algorithm, "algorithm", DataParameter, Auth, "RFC 2617"); +defineParam(boundary, "boundary", DataParameter, Mime, "RFC 2046"); +defineParam(branch, "branch", BranchParameter, Via, "RFC 3261"); +defineParam(charset, "charset", DataParameter, Mime, "RFC 2045"); +defineParam(cnonce, "cnonce", QuotedDataParameter, Auth, "RFC 2617"); +defineParam2(comp, "comp", DataParameter, Uri, Via, "RFC 3486"); +defineParam(dAlg, "d-alg", DataParameter, Token, "RFC 3329"); +defineParam(dQop, "d-qop", DataParameter, Token, "RFC 3329"); +defineParam(dVer, "d-ver", QuotedDataParameter, Token, "RFC 3329"); +defineParam(directory, "directory", DataParameter, Mime, "RFC 2046"); +defineParam(domain, "domain", QuotedDataParameter, Auth, "RFC 3261"); +defineParam2(duration, "duration", UInt32Parameter, Uri, UInt32Category, "RFC 4240"); +defineParam(expiration, "expiration", QuotedDataParameter, Mime, "RFC 2046"); +defineParam2(expires, "expires", UInt32Parameter, NameAddr, Token, "RFC 3261"); +defineParam(filename, "filename", DataParameter, Token, "RFC 2183"); +defineParam2(fromTag, "from-tag", DataParameter, Token, CallID, "RFC 4235"); +defineParam(handling, "handling", DataParameter, Token, "RFC 3261"); +defineParam(id, "id", DataParameter, Token, "RFC 3265"); +defineParam(lr, "lr", ExistsParameter, Uri, "RFC 3261"); +defineParam2(maddr, "maddr", DataParameter, Uri, Via, "RFC 3261"); +defineParam(method, "method", DataParameter, Uri, "RFC 3261"); +defineParam(micalg, "micalg", DataParameter, Mime, "RFC 1847"); +defineParam(mode, "mode", DataParameter, Mime, "RFC 2046"); +defineParam(name, "name", DataParameter, Mime, "RFC 2046"); +defineParam(nc, "nc", DataParameter, Auth, "RFC 2617"); +defineParam(nonce, "nonce", QuotedDataParameter, Auth, "RFC 2617"); +defineParam(opaque, "opaque", QuotedDataParameter, Auth, "RFC 2617"); +defineParam(permission, "permission", DataParameter, Mime, "RFC 2046"); +defineParam(protocol, "protocol", QuotedDataParameter, Mime, "RFC 1847"); +defineParam(purpose, "purpose", DataParameter, GenericUri, "RFC 3261"); +defineParam3(q, "q", QValueParameter, NameAddr, Token, Mime, "RFC 3261"); +defineParam(realm, "realm", QuotedDataParameter, Auth, "RFC 2617"); +defineParam(reason, "reason", DataParameter, Token, "RFC 3265"); +defineParam(received, "received", DataParameter, Via, "RFC 3261"); +defineParam(require, "require", DataParameter, Token, "RFC 5373"); +defineParam(response, "response", QuotedDataParameter, Auth, "RFC 3261"); +defineParam(retryAfter, "retry-after", UInt32Parameter, Token, "RFC 3265"); +defineParam(rinstance, "rinstance", DataParameter, Uri, "proprietary (resip)"); +defineParam(rport, "rport", RportParameter, Via, "RFC 3581"); +defineParam(server, "server", DataParameter, Mime, "RFC 2046"); +defineParam(site, "site", DataParameter, Mime, "RFC 2046"); +defineParam(size, "size", DataParameter, Mime, "RFC 2046"); +defineParam(smimeType, "smime-type", DataParameter, Mime, "RFC 2633"); +defineParam(stale, "stale", DataParameter, Auth, "RFC 2617"); +defineParam(tag, "tag", DataParameter, NameAddr, "RFC 3261"); +defineParam2(toTag, "to-tag", DataParameter, Token, CallID, "RFC 4235"); +defineParam(transport, "transport", DataParameter, Uri, "RFC 3261"); +defineParam2(ttl, "ttl", UInt32Parameter, Uri, Via, "RFC 3261"); +defineParam(uri, "uri", QuotedDataParameter, Auth, "RFC 3261"); +defineParam(user, "user", DataParameter, Uri, "RFC 3261, 4967"); +defineParam2(extension, "ext", DataParameter, Uri, Token, "RFC 3966"); // Token is used when ext is a user-parameter +defineParam(username, "username", QuotedDataParameter, Auth, "RFC 3261"); +defineParam(earlyOnly, "early-only", ExistsParameter, CallID, "RFC 3891"); +defineParam(refresher, "refresher", DataParameter, ExpiresCategory, "RFC 4028"); + +defineParam(profileType, "profile-type", DataParameter, Token, "RFC 6080"); +defineParam(vendor, "vendor", QuotedDataParameter, Token, "RFC 6080"); +defineParam(model, "model", QuotedDataParameter, Token, "RFC 6080"); +defineParam(version, "version", QuotedDataParameter, Token, "RFC 6080"); +defineParam(effectiveBy, "effective-by", UInt32Parameter, Token, "RFC 6080"); +defineParam(document, "document", DataParameter, Token, "draft-ietf-sipping-config-framework-07 (removed in 08)"); +defineParam(appId, "app-id", DataParameter, Token, "draft-ietf-sipping-config-framework-05 (renamed to auid in 06, which was then removed in 08)"); +defineParam(networkUser, "network-user", DataParameter, Token, "draft-ietf-sipping-config-framework-11 (removed in 12)"); + +defineParam(url, "url", QuotedDataParameter, Mime, "RFC 4483"); + +defineParam2(sigcompId, "sigcomp-id", QuotedDataParameter, Uri, Via, "RFC 5049"); +defineParam(qop,"qop",DataParameter, Auth, "RFC 3261"); + +// Internal use only +defineParam(qopOptions,"qop",DataParameter, Auth, "RFC 3261"); +defineParam(addTransport, "addTransport", ExistsParameter, Uri, "RESIP INTERNAL"); + +} + +#undef defineParam +#undef defineParam2 +#undef defineParam3 +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ParserCategories.cxx b/src/libs/resiprocate/resip/stack/ParserCategories.cxx new file mode 100644 index 00000000..b75ad426 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParserCategories.cxx @@ -0,0 +1,58 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + +/* Local Variables: */ +/* c-file-style: "ellemtel" */ +/* End: */ + diff --git a/src/libs/resiprocate/resip/stack/ParserCategories.hxx b/src/libs/resiprocate/resip/stack/ParserCategories.hxx new file mode 100644 index 00000000..71c72ea8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParserCategories.hxx @@ -0,0 +1,75 @@ +#if !defined(RESIP_PARSERCATEGORIES_HXX) +#define RESIP_PARSERCATEGORIES_HXX + +//#warning "DO NOT USE ParserCategories.hxx" + +#include "resip/stack/Auth.hxx" +#include "resip/stack/CSeqCategory.hxx" +#include "resip/stack/CallId.hxx" +#include "resip/stack/DateCategory.hxx" +#include "resip/stack/ExpiresCategory.hxx" +#include "resip/stack/GenericUri.hxx" +#include "resip/stack/IntegerCategory.hxx" +#include "resip/stack/UInt32Category.hxx" +#include "resip/stack/Mime.hxx" +#include "resip/stack/NameAddr.hxx" +#include "resip/stack/PrivacyCategory.hxx" +#include "resip/stack/RAckCategory.hxx" +#include "resip/stack/RequestLine.hxx" +#include "resip/stack/StatusLine.hxx" +#include "resip/stack/StringCategory.hxx" +#include "resip/stack/Token.hxx" +#include "resip/stack/Via.hxx" +#include "resip/stack/WarningCategory.hxx" + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ParserCategory.cxx b/src/libs/resiprocate/resip/stack/ParserCategory.cxx new file mode 100644 index 00000000..c7df4cae --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParserCategory.cxx @@ -0,0 +1,511 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/HeaderFieldValue.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "rutil/ParseBuffer.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/compat.hxx" + +#include "resip/stack/UnknownParameter.hxx" +#include "resip/stack/ExtensionParameter.hxx" + +#include <iostream> +#include <cassert> + +#include "rutil/Logger.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +using namespace resip; +using namespace std; + +const ParserCategory::ParameterTypeSet +ParserCategory::EmptyParameterTypeSet; + +ParserCategory::ParserCategory(const HeaderFieldValue& headerFieldValue, + Headers::Type headerType, + PoolBase* pool) + : LazyParser(headerFieldValue), + mParameters(StlPoolAllocator<Parameter*, PoolBase>(pool)), + mUnknownParameters(StlPoolAllocator<Parameter*, PoolBase>(pool)), + mPool(pool), + mHeaderType(headerType) +{ +} + +ParserCategory::ParserCategory(const char* buf, + int length, + Headers::Type type, + PoolBase* pool): + LazyParser(buf, length), + mParameters(StlPoolAllocator<Parameter*, PoolBase>(pool)), + mUnknownParameters(StlPoolAllocator<Parameter*, PoolBase>(pool)), + mPool(pool), + mHeaderType(type) +{} + +ParserCategory::ParserCategory(PoolBase* pool) + : LazyParser(), + mParameters(StlPoolAllocator<Parameter*, PoolBase>(pool)), + mUnknownParameters(StlPoolAllocator<Parameter*, PoolBase>(pool)), + mPool(pool), + mHeaderType(Headers::NONE) +{ +} + +ParserCategory::ParserCategory(const ParserCategory& rhs, + PoolBase* pool) + : LazyParser(rhs), + mParameters(StlPoolAllocator<Parameter*, PoolBase>(pool)), + mUnknownParameters(StlPoolAllocator<Parameter*, PoolBase>(pool)), + mPool(pool), + mHeaderType(rhs.mHeaderType) +{ + if (isParsed()) + { + copyParametersFrom(rhs); + } +} + +ParserCategory& +ParserCategory::operator=(const ParserCategory& rhs) +{ + if (this != &rhs) + { + clear(); + mHeaderType = rhs.mHeaderType; + LazyParser::operator=(rhs); + if (rhs.isParsed()) + { + copyParametersFrom(rhs); + } + } + return *this; +} + +void +ParserCategory::clear() +{ + //DebugLog(<<"ParserCategory::clear"); + LazyParser::clear(); + + while(!mParameters.empty()) + { + freeParameter(mParameters.back()); + mParameters.pop_back(); + } + + while(!mUnknownParameters.empty()) + { + freeParameter(mUnknownParameters.back()); + mUnknownParameters.pop_back(); + } +} + +void +ParserCategory::copyParametersFrom(const ParserCategory& other) +{ + mParameters.reserve(other.mParameters.size()); + mUnknownParameters.reserve(other.mUnknownParameters.size()); + + for (ParameterList::const_iterator it = other.mParameters.begin(); + it != other.mParameters.end(); it++) + { + mParameters.push_back((*it)->clone()); + } + for (ParameterList::const_iterator it = other.mUnknownParameters.begin(); + it != other.mUnknownParameters.end(); it++) + { + mUnknownParameters.push_back((*it)->clone()); + } +} + +ParserCategory::~ParserCategory() +{ + clear(); +} + +const Data& +ParserCategory::param(const ExtensionParameter& param) const +{ + checkParsed(); + Parameter* p = getParameterByData(param.getName()); + if (!p) + { + InfoLog(<< "Referenced an unknown parameter " << param.getName()); + throw Exception("Missing unknown parameter", __FILE__, __LINE__); + } + return static_cast<UnknownParameter*>(p)->value(); +} + +Data& +ParserCategory::param(const ExtensionParameter& param) +{ + checkParsed(); + Parameter* p = getParameterByData(param.getName()); + if (!p) + { + p = new UnknownParameter(param.getName()); + mUnknownParameters.push_back(p); + } + return static_cast<UnknownParameter*>(p)->value(); +} + +// removing non-present parameter is allowed +void +ParserCategory::remove(const ParamBase& paramType) +{ + checkParsed(); + removeParameterByEnum(paramType.getTypeNum()); +} + +void +ParserCategory::remove(const ExtensionParameter& param) +{ + checkParsed(); + removeParameterByData(param.getName()); +} + +bool +ParserCategory::exists(const ExtensionParameter& param) const +{ + checkParsed(); + return getParameterByData(param.getName()) != NULL; +} + +void +ParserCategory::removeParametersExcept(const ParameterTypeSet& set) +{ + checkParsed(); + for (ParameterList::iterator it = mParameters.begin(); + it != mParameters.end();) + { + if (set.find((*it)->getType()) == set.end()) + { + freeParameter(*it); + it = mParameters.erase(it); + } + else + { + ++it; + } + } +} + +void +ParserCategory::clearUnknownParameters() +{ + for (ParameterList::iterator it = mUnknownParameters.begin(); + it != mUnknownParameters.end(); it++) + { + freeParameter(*it); + } + mUnknownParameters.clear(); +} + +void +ParserCategory::parseParameters(ParseBuffer& pb) +{ + while (!pb.eof() ) + { + const char* start = pb.position(); + pb.skipWhitespace(); + + if ( (!pb.eof() && *pb.position() == Symbols::SEMI_COLON[0]) ) + { + // extract the key + pb.skipChar(); + const char* keyStart = pb.skipWhitespace(); + static std::bitset<256> terminators1=Data::toBitset(" \t\r\n;=?>"); //!dlb! @ here? + const char* keyEnd = pb.skipToOneOf(terminators1); + + if((int)(keyEnd-keyStart) != 0) + { + ParameterTypes::Type type = ParameterTypes::getType(keyStart, (unsigned int)(keyEnd - keyStart)); + static std::bitset<256> terminators2 = Data::toBitset(" \t\r\n;?>"); + Parameter* p; + if (type == ParameterTypes::UNKNOWN || + !(p=createParam(type, pb, terminators2,getPool()))) + { + mUnknownParameters.push_back(new (getPool()) UnknownParameter(keyStart, + int((keyEnd - keyStart)), pb, terminators2)); + } + else + { + // invoke the particular factory + mParameters.push_back(p); + } + } + } + else + { + pb.reset(start); + return; + } + } +} + +Parameter* +ParserCategory::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) +{ + return 0; +} + +static Data up_Msgr("msgr"); + +EncodeStream& +ParserCategory::encodeParameters(EncodeStream& str) const +{ + + for (ParameterList::const_iterator it = mParameters.begin(); + it != mParameters.end(); it++) + { +#if 0 + // !cj! - may be wrong just hacking + // The goal of all this is not to add a tag if the tag is empty + ParameterTypes::Type type = (*it)->getType(); + + if ( type == ParameterTypes::tag ) + { + Parameter* p = (*it); + DataParameter* d = dynamic_cast<DataParameter*>(p); + + Data& data = d->value(); + + if ( !data.empty() ) + { + str << Symbols::SEMI_COLON; + // !ah! this is a TOTAL hack to work around an MSN bug that + // !ah! requires a SPACE after the SEMI following the MIME type. + if (it == mParameters.begin() && getParameterByData(up_Msgr)) + { + str << Symbols::SPACE; + } + + (*it)->encode(str); + } + } + else + { + str << Symbols::SEMI_COLON; + // !ah! this is a TOTAL hack to work around an MSN bug that + // !ah! requires a SPACE after the SEMI following the MIME type. + if (it == mParameters.begin() && getParameterByData(up_Msgr)) + { + str << Symbols::SPACE; + } + + (*it)->encode(str); + } + +#else + str << Symbols::SEMI_COLON; + // !ah! this is a TOTAL hack to work around an MSN bug that + // !ah! requires a SPACE after the SEMI following the MIME type. + if (it == mParameters.begin() && getParameterByData(up_Msgr)) + { + str << Symbols::SPACE; + } + + (*it)->encode(str); +#endif + } + for (ParameterList::const_iterator it = mUnknownParameters.begin(); + it != mUnknownParameters.end(); it++) + { + str << Symbols::SEMI_COLON; + (*it)->encode(str); + } + return str; +} + +EncodeStream& +resip::operator<<(EncodeStream& stream, const ParserCategory& category) +{ + category.checkParsed(); + return category.encode(stream); +} + +Parameter* +ParserCategory::getParameterByEnum(ParameterTypes::Type type) const +{ + for (ParameterList::const_iterator it = mParameters.begin(); + it != mParameters.end(); it++) + { + if ((*it)->getType() == type) + { + return *it; + } + } + return 0; +} + +void +ParserCategory::setParameter(const Parameter* parameter) +{ + assert(parameter); + + for (ParameterList::iterator it = mParameters.begin(); + it != mParameters.end(); it++) + { + if ((*it)->getType() == parameter->getType()) + { + freeParameter(*it); + mParameters.erase(it); + mParameters.push_back(parameter->clone()); + return; + } + } + + // !dlb! kinda hacky -- what is the correct semantics here? + // should be quietly add, quietly do nothing, throw? + mParameters.push_back(parameter->clone()); +} + +void +ParserCategory::removeParameterByEnum(ParameterTypes::Type type) +{ + // remove all instances + for (ParameterList::iterator it = mParameters.begin(); + it != mParameters.end();) + { + if ((*it)->getType() == type) + { + freeParameter(*it); + it = mParameters.erase(it); + } + else + { + ++it; + } + } + } + +Parameter* +ParserCategory::getParameterByData(const Data& data) const +{ + for (ParameterList::const_iterator it = mUnknownParameters.begin(); + it != mUnknownParameters.end(); it++) + { + if (isEqualNoCase((*it)->getName(), data)) + { + return *it; + } + } + return 0; +} + +void +ParserCategory::removeParameterByData(const Data& data) +{ + // remove all instances + for (ParameterList::iterator it = mUnknownParameters.begin(); + it != mUnknownParameters.end();) + { + if ((*it)->getName() == data) + { + freeParameter(*it); + it = mUnknownParameters.erase(it); + } + else + { + ++it; + } + } +} + +Data +ParserCategory::commutativeParameterHash() const +{ + Data buffer; + Data working; + + for (ParameterList::const_iterator i = mParameters.begin(); i != mParameters.end(); ++i) + { + if ((*i)->getType() != ParameterTypes::lr) + { + buffer.clear(); + { + DataStream strm(buffer); + (*i)->encode(strm); + } + working ^= buffer; + } + } + + buffer.clear(); + for (ParameterList::const_iterator i = mUnknownParameters.begin(); i != mUnknownParameters.end(); ++i) + { + UnknownParameter* p = static_cast<UnknownParameter*>(*i); + buffer = p->getName(); + buffer += p->value(); + working ^= buffer; + } + + return working; +} + +const Data& +ParserCategory::errorContext() const +{ + return Headers::getHeaderName(mHeaderType); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + +/* Local Variables: */ +/* c-file-style: "ellemtel" */ +/* End: */ diff --git a/src/libs/resiprocate/resip/stack/ParserCategory.hxx b/src/libs/resiprocate/resip/stack/ParserCategory.hxx new file mode 100644 index 00000000..a3ddd08d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParserCategory.hxx @@ -0,0 +1,361 @@ +#if !defined(RESIP_PARSERCATEGORY_HXX) +#define RESIP_PARSERCATEGORY_HXX + +#include <iosfwd> +#include <vector> +#include <set> +#include "resip/stack/HeaderTypes.hxx" +#include "resip/stack/LazyParser.hxx" +#include "resip/stack/ParameterTypes.hxx" +#include "rutil/Data.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/StlPoolAllocator.hxx" +#include "rutil/PoolBase.hxx" + +#include "rutil/resipfaststreams.hxx" + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ + const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \ + _enum##_Param::DType& param(const _enum##_Param& paramType) + +namespace resip +{ +class UnknownParameter; +class ExtensionParameter; +class Parameter; +class ParseBuffer; + +/** + @brief Base class for all SIP grammar elements that can have parameters. + + The pattern for accessing the parameters in a ParserCategory is very similar + to accessing headers in a SipMessage. Each parameter type has an access token + class (a subclass of ParamBase), and a corresponding ParserCategory::param() + function that takes an instance of that subclass as an argument, and returns + the correct type for that parameter. Common examples of access-token include + p_tag, p_q, p_lr, p_expires, p_branch, etc. + + @code + NameAddr& contact = sip.header(h_Contacts).front(); + if(contact.exists(p_q)) + { + QValueParameter& q = contact.param(p_q); + // do stuff with q + } + + NameAddr& to = sip.header(h_To); + if(to.exists(p_tag)) + { + DataParameter& toTag = to.param(p_tag); + // do stuff with toTag + } + + Via& topVia = sip.header(h_Vias).front(); + if(topVia.exists(p_branch)) + { + BranchParameter& branch = topVia.param(p_branch); + // do stuff with branch + } + @endcode + + Note the calls to ParserCategory::exists() in the code above; calling + ParserCategory::param() when the relevant parameter doesn't exist will either + cause the parameter to be created, or an exception to be thrown (if you're + working with a const reference). + + In some cases, you will need to access parameter-types that are not natively + supported by the stack (ie, don't have an access-token). ExtensionParameter + will allow you to construct an access-token at runtime that will retrieve the + parameter as a raw Data. Here's an example: + + @code + // We need to access the foo parameter on the Request-Uri + RequestLine& rLine = sip.header(h_RequestLine); + static ExtensionParameter p_foo("foo"); + if(rLine.uri().exists(p_foo)) + { + Data& foo = rLine.uri().param(p_foo); + } + @endcode + + @todo Maybe a better name? IHaveParams? ElemWithParams? + @ingroup resip_crit +*/ +class ParserCategory : public LazyParser +{ + public: + enum {UnknownParserCategory = -1}; + + // NoCommaTokenizing: commas do not indicate a new header value + // CommasAllowedOutputMulti: multi headers can be received with commas but + // output them on separate lines. + // CommasAllowedOutputCommas: multi headers can be received with commas + // and will always output with commas when + // parsed. + enum {NoCommaTokenizing = 0, CommasAllowedOutputMulti = 1, CommasAllowedOutputCommas = 3}; + + /** + @internal + @brief Constructor used by SipMessage. Unless you _really_ know what + you're doing, don't touch this. + */ + ParserCategory(const HeaderFieldValue& headerFieldValue, + Headers::Type type, + PoolBase* pool=0); + + /** + @internal + @brief Constructor used by SipMessage. Unless you _really_ know what + you're doing, don't touch this. + */ + ParserCategory(const char* buf, + int length, + Headers::Type type, + PoolBase* pool=0); + + /** + @internal + @brief Copy c'tor. + */ + ParserCategory(const ParserCategory& rhs, + PoolBase* pool=0); + + /** + @internal + @brief Assignment operator. + */ + ParserCategory& operator=(const ParserCategory& rhs); + + virtual ~ParserCategory(); + + virtual ParserCategory* clone() const = 0; + virtual Parameter* createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool); + + // Do a placement new + virtual ParserCategory* clone(void* location) const = 0; + + // Do a pool allocated new + virtual ParserCategory* clone(PoolBase* pool) const = 0; + + /** + @brief Checks for the existence of a natively supported parameter. + @param paramType The accessor token for the parameter. + @return true iff the parameter is present. + */ + inline bool exists(const ParamBase& paramType) const + { + checkParsed(); + return (getParameterByEnum(paramType.getTypeNum()) != NULL); + } + + /** + @brief Removes a natively supported parameter, if the parameter is + present. + @param paramType The accessor token for the parameter. + */ + void remove(const ParamBase& paramType); + + // !dlb! causes compiler error in windows -- change template to const T* + /** + @brief Const accessor for non-natively-supported parameter types. + @throw ParserCategory::Exception if this parameter doesn't exist. + @param param The runtime constructed parameter accessor. + @return The parameter, as a raw Data. + */ + const Data& param(const ExtensionParameter& param) const; + + /** + @brief Accessor for non-natively-supported parameter types. + Will create the parameter if it does not exist. + @param param The runtime constructed parameter accessor. + @return The parameter, as a raw Data. + */ + Data& param(const ExtensionParameter& param); + + /** + @brief Removes a non-natively-supported parameter, if the parameter is + present. + @param param The accessor token for the parameter. + */ + void remove(const ExtensionParameter& param); + + /** + @brief Checks for the existence of a non-natively-supported parameter. + @param param The runtime constructed accessor token. + @return true iff the parameter is present. + */ + bool exists(const ExtensionParameter& param) const; + + typedef std::set<ParameterTypes::Type> ParameterTypeSet; + + static const ParameterTypeSet EmptyParameterTypeSet; + + /** + @brief Removes all known parameters except those that are specified in + set. + @param set The set of parameters to retain, as an enum. + @note This does not remove unknown parameters. + */ + void removeParametersExcept(const ParameterTypeSet& set = EmptyParameterTypeSet); + void clearUnknownParameters(); + + /** + @brief Exception class used by ParserCategory. + */ + class Exception : public BaseException + { + public: + Exception(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) {} + + const char* name() const { return "ParserCategory::Exception"; } + }; + + /** + @internal + @brief Causes this ParserCategory to parse parameters out of pb. + @param pb The ParseBuffer to parse params from. + */ + void parseParameters(ParseBuffer& pb); + + /** + @brief Encodes parameters as they should appear on the wire. + @param str The ostream to encode to. + @return str + */ + EncodeStream& encodeParameters(EncodeStream& str) const; + + // used to compare 2 parameter lists for equality in an order independent way + /** + @internal + @brief An order-sensitive hash over the set of parameters in this + ParserCategory. + @return The hash value as a Data. + */ + Data commutativeParameterHash() const; + + /** + @internal + @brief Typeless parameter get interface. + */ + Parameter* getParameterByEnum(ParameterTypes::Type type) const; + + /** + @internal + @brief Removes a parameter. + @param type The parameter type. + */ + void removeParameterByEnum(ParameterTypes::Type type); + + /** + @internal + @brief Typeless parameter put interface. + */ + void setParameter(const Parameter* parameter); + + /** + @brief Returns the number of known (natively supported) parameters. + */ + int numKnownParams() const {return (int)mParameters.size();}; + + /** + @brief Returns the number of unknown parameters. + */ + int numUnknownParams() const {return (int)mUnknownParameters.size();}; + + protected: + ParserCategory(PoolBase* pool=0); + + Parameter* getParameterByData(const Data& data) const; + void removeParameterByData(const Data& data); + inline PoolBase* getPool() + { + return mPool; + } + + inline void freeParameter(Parameter* p) + { + if(p) + { + p->~Parameter(); + if(mPool) + { + mPool->deallocate(p); + return; + } + ::operator delete(p); + } + } + + virtual const Data& errorContext() const; + + typedef std::vector<Parameter*, StlPoolAllocator<Parameter*, PoolBase> > ParameterList; + ParameterList mParameters; + ParameterList mUnknownParameters; + PoolBase* mPool; + Headers::Type mHeaderType; + private: + void clear(); + void copyParametersFrom(const ParserCategory& other); + friend EncodeStream& operator<<(EncodeStream&, const ParserCategory&); + friend class NameAddr; +}; + +EncodeStream& +operator<<(EncodeStream&, const ParserCategory& category); + +} + +#undef defineParam + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ParserContainer.hxx b/src/libs/resiprocate/resip/stack/ParserContainer.hxx new file mode 100644 index 00000000..2e5c0540 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParserContainer.hxx @@ -0,0 +1,426 @@ +#ifndef RESIP_ParserContainer_hxx +#define RESIP_ParserContainer_hxx + +#include <algorithm> +#include <iterator> + +#include "resip/stack/HeaderFieldValueList.hxx" +#include "resip/stack/ParserContainerBase.hxx" + +namespace resip +{ +using std::ptrdiff_t; +/** + @brief Container class for ParserCategory, used by SipMessage to represent + multi-valued headers (Contact, Via, etc). + + This has an interface that is similar to stl containers, but not as complete. + + @ingroup resip_crit +*/ +template<class T> +class ParserContainer : public ParserContainerBase +{ + public: + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef ptrdiff_t difference_type; + + /** + @brief Default c'tor. + */ + ParserContainer() + : ParserContainerBase(Headers::UNKNOWN) + {} + + ParserContainer(PoolBase& pool) + : ParserContainerBase(Headers::UNKNOWN,pool) + {} + + /** + @internal + @brief Used by SipMessage (using this carries a high risk of blowing + your feet off). + */ + ParserContainer(HeaderFieldValueList* hfvs, + Headers::Type type = Headers::UNKNOWN) + : ParserContainerBase(type) + { + mParsers.reserve(hfvs->size()); + for (HeaderFieldValueList::iterator i = hfvs->begin(); + i != hfvs->end(); i++) + { + // create, store without copying -- + // keeps the HeaderFieldValue from reallocating its buffer + mParsers.push_back(HeaderKit::Empty); + mParsers.back().hfv.init(i->getBuffer(),i->getLength(),false); + } + } + + ParserContainer(HeaderFieldValueList* hfvs, + Headers::Type type, + PoolBase& pool) + : ParserContainerBase(type,pool) + { + mParsers.reserve(hfvs->size()); + for (HeaderFieldValueList::iterator i = hfvs->begin(); + i != hfvs->end(); i++) + { + // create, store without copying -- + // keeps the HeaderFieldValue from reallocating its buffer + mParsers.push_back(HeaderKit::Empty); + mParsers.back().hfv.init(i->getBuffer(),i->getLength(),false); + } + } + + /** + @brief Copy c'tor. + */ + ParserContainer(const ParserContainer& other) + : ParserContainerBase(other) + {} + + /** + @brief Copy c'tor. + */ + ParserContainer(const ParserContainer& other, PoolBase& pool) + : ParserContainerBase(other, pool) + {} + + /** + @brief Assignment operator. + */ + ParserContainer& operator=(const ParserContainer& other) + { + return static_cast<ParserContainer&>(ParserContainerBase::operator=(other)); + } + + /** + @brief Returns the first header field value in this container. + */ + T& front() + { + return ensureInitialized(mParsers.front(),this); + } + + /** + @brief Returns the last header field value in this container. + */ + T& back() + { + return ensureInitialized(mParsers.back(),this); + } + + /** + @brief Returns the first header field value in this container. + */ + const T& front() const + { + return ensureInitialized(mParsers.front(),this); + } + + /** + @brief Returns the last header field value in this container. + */ + const T& back() const + { + return ensureInitialized(mParsers.back(),this); + } + + /** + @brief Inserts a header field value at the front of this container. + */ + void push_front(const T & t) + { + mParsers.insert(mParsers.begin(), HeaderKit::Empty); + mParsers.front().pc=makeParser(t); + } + + /** + @brief Inserts a header field value at the back of this container. + */ + void push_back(const T & t) + { + mParsers.push_back(HeaderKit::Empty); + mParsers.back().pc=makeParser(t); + } + + /** + @brief Returns a copy of this ParserContainer, in reverse order. + @todo !bwc! optimize this (we are copying each ParserContainer twice) + */ + ParserContainer reverse() const + { + ParserContainer tmp(*this); + std::reverse(tmp.mParsers.begin(), tmp.mParsers.end()); + return tmp; + } + + typedef ParserContainerBase::Parsers Parsers; + // .dlb. these can be partially hoisted as well + class const_iterator; + + /** + @brief An iterator class, derived from std::iterator (bidirectional) + */ + class iterator : public std::iterator<std::bidirectional_iterator_tag, T> + { + public: + iterator(typename Parsers::iterator i,ParserContainer* ref) : mIt(i),mRef(ref){} + iterator() : mRef(0) {} + iterator(const iterator& orig) : mIt(orig.mIt), mRef(orig.mRef) {} + + iterator operator++() {iterator it(++mIt,mRef); return it;} + iterator operator++(int) {iterator it(mIt++,mRef); return it;} + iterator operator--() {iterator it(--mIt,mRef); return it;} + iterator operator--(int) {iterator it(mIt--,mRef); return it;} + bool operator!=(const iterator& rhs) { return mIt != rhs.mIt; } + bool operator==(const iterator& rhs) { return mIt == rhs.mIt; } + bool operator!=(const const_iterator& rhs) { return mIt != rhs.mIt; } + bool operator==(const const_iterator& rhs) { return mIt == rhs.mIt; } + iterator& operator=(const iterator& rhs) + { + mIt = rhs.mIt; + mRef = rhs.mRef; + return *this; + } + T& operator*() {return ensureInitialized(*mIt,mRef);} + T* operator->() {return &ensureInitialized(*mIt,mRef);} + private: + typename Parsers::iterator mIt; + ParserContainer* mRef; + friend class const_iterator; + friend class ParserContainer; + }; + + /** + @brief A const_iterator class, derived from std::iterator + (bidirectional) + */ + class const_iterator : public std::iterator<std::bidirectional_iterator_tag, T> + { + public: + const_iterator(Parsers::const_iterator i,const ParserContainer* ref) : mIt(i),mRef(ref){} + const_iterator(const const_iterator& orig) : mIt(orig.mIt), mRef(orig.mRef) {} + const_iterator(const iterator& orig) : mIt(orig.mIt), mRef(orig.mRef) {} + const_iterator() : mRef(0) {} + + const_iterator operator++() {const_iterator it(++mIt,mRef); return it;} + const_iterator operator++(int) {const_iterator it(mIt++,mRef); return it;} + const_iterator operator--() {const_iterator it(--mIt,mRef); return it;} + const_iterator operator--(int) {const_iterator it(mIt--,mRef); return it;} + bool operator!=(const const_iterator& rhs) { return mIt != rhs.mIt; } + bool operator==(const const_iterator& rhs) { return mIt == rhs.mIt; } + bool operator!=(const iterator& rhs) { return mIt != rhs.mIt; } + bool operator==(const iterator& rhs) { return mIt == rhs.mIt; } + const_iterator& operator=(const const_iterator& rhs) + { + mIt = rhs.mIt; + mRef = rhs.mRef; + return *this; + } + const_iterator& operator=(const iterator& rhs) + { + mIt = rhs.mIt; + mRef = rhs.mRef; + return *this; + } + const T& operator*() {return ensureInitialized(*mIt,mRef);} + const T* operator->() {return &ensureInitialized(*mIt,mRef);} + private: + friend class iterator; + typename Parsers::const_iterator mIt; + const ParserContainer* mRef; + }; + + /** + @brief Returns an iterator pointing to the first header field value. + */ + iterator begin() { return iterator(mParsers.begin(),this); } + + /** + @brief Returns an iterator pointing to the last header field value. + */ + iterator end() { return iterator(mParsers.end(),this); } + + /** + @brief Erases the header field value pointed to by i. Invalidates all + existing iterators. + */ + iterator erase(iterator i) + { + freeParser(*i.mIt); + return iterator(mParsers.erase(i.mIt),this); + } + + /** + @brief Finds the first header field value that matches rhs. + */ + bool find(const T& rhs) const + { + for (typename Parsers::const_iterator i = mParsers.begin(); + i != mParsers.end(); ++i) + { + // operator== defined by default, but often not usefully + if (rhs.isEqual(ensureInitialized(*i,this))) + { + return true; + } + } + + return false; + } + + /** + @brief Triggers a parse of all contained header field values. + @throw ParseException if any header field value is malformed. + */ + virtual void parseAll() + { + for (typename Parsers::const_iterator i = mParsers.begin(); + i != mParsers.end(); ++i) + { + ensureInitialized(*i,this).checkParsed(); + } + } + + /** + @brief Returns a const_iterator pointing to the first header field + value. + */ + const_iterator begin() const { return const_iterator(mParsers.begin(),this); } + + /** + @brief Returns a const_iterator pointing to the first header field + value. + */ + const_iterator end() const { return const_iterator(mParsers.end(),this); } + + /** + @brief Clones this container, and all contained header field values. + */ + virtual ParserContainerBase* clone() const + { + return new ParserContainer(*this); + } + + private: + friend class ParserContainer<T>::iterator; + friend class ParserContainer<T>::const_iterator; + + /** + @internal + */ + static T& ensureInitialized(HeaderKit& kit, ParserContainer* ref) + { + if(!kit.pc) + { + if(ref) + { + PoolBase* pool(ref->mPool); + kit.pc=new (pool) T(kit.hfv, ref->mType, pool); + } + else + { + kit.pc=new T(kit.hfv, Headers::NONE); + } + } + return *static_cast<T*>(kit.pc); + } + + static const T& ensureInitialized(const HeaderKit& kit, + const ParserContainer* ref) + { + if(!kit.pc) + { + HeaderKit& nc_kit(const_cast<HeaderKit&>(kit)); + if(ref) + { + ParserContainer* nc_ref(const_cast<ParserContainer*>(ref)); + PoolBase* pool(nc_ref->mPool); + nc_kit.pc=new (pool) T(kit.hfv, ref->mType, pool); + } + else + { + nc_kit.pc=new T(kit.hfv, Headers::NONE); + } + } + return *static_cast<T*>(kit.pc); + } +}; + +template <class T> +EncodeStream& +insert(EncodeStream& s, const resip::ParserContainer<T>& c) +{ + s << "["; + for (typename resip::ParserContainer <T>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << ", "; + } + // recurse + insert(s, *i); + } + s << "]"; + return s; +} + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ParserContainerBase.cxx b/src/libs/resiprocate/resip/stack/ParserContainerBase.cxx new file mode 100644 index 00000000..8b5f4eef --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParserContainerBase.cxx @@ -0,0 +1,224 @@ +#include <cassert> + +#include "resip/stack/ParserContainerBase.hxx" +#include "resip/stack/Embedded.hxx" + +using namespace resip; +using namespace std;; + +const ParserContainerBase::HeaderKit ParserContainerBase::HeaderKit::Empty; + +ParserContainerBase::ParserContainerBase(Headers::Type type) + : mType(type), + mPool(0) +{} + +ParserContainerBase::ParserContainerBase(const ParserContainerBase& rhs) + : mType(rhs.mType), + mParsers(), + mPool(0) +{ + copyParsers(rhs.mParsers); +} + +ParserContainerBase::ParserContainerBase(Headers::Type type, + PoolBase& pool) + : mType(type), + mParsers(StlPoolAllocator<HeaderKit, PoolBase>(&pool)), + mPool(&pool) +{} + +ParserContainerBase::ParserContainerBase(const ParserContainerBase& rhs, + PoolBase& pool) + : mType(rhs.mType), + mParsers(StlPoolAllocator<HeaderKit, PoolBase>(&pool)), + mPool(&pool) +{ + copyParsers(rhs.mParsers); +} + +ParserContainerBase::~ParserContainerBase() +{ + freeParsers(); +} + +ParserContainerBase& +ParserContainerBase::operator=(const ParserContainerBase& rhs) +{ + if (this != &rhs) + { + freeParsers(); + mParsers.clear(); + copyParsers(rhs.mParsers); + } + return *this; +} + +void +ParserContainerBase::pop_front() +{ + assert(!mParsers.empty()); + freeParser(mParsers.front()); + mParsers.erase(mParsers.begin()); +} + +void +ParserContainerBase::pop_back() +{ + assert(!mParsers.empty()); + freeParser(mParsers.back()); + mParsers.pop_back(); +} + +void +ParserContainerBase::append(const ParserContainerBase& source) +{ + copyParsers(source.mParsers); +} + +EncodeStream& +ParserContainerBase::encode(const Data& headerName, + EncodeStream& str) const +{ + // !jf! this is not strictly correct since some headers are allowed to + // be empty: Supported, Accept-Encoding, Allow-Events, Allow, + // Accept,Accept-Language + if (!mParsers.empty()) + { + if (!headerName.empty()) + { + str << headerName << Symbols::COLON[0] << Symbols::SPACE[0]; + } + + for (Parsers::const_iterator i = mParsers.begin(); + i != mParsers.end(); ++i) + { + if (i != mParsers.begin()) + { + if (Headers::isCommaEncoding(mType)) + { + str << Symbols::COMMA[0] << Symbols::SPACE[0]; + } + else + { + str << Symbols::CRLF << headerName << Symbols::COLON[0] << Symbols::SPACE[0]; + } + } + + i->encode(str); + } + + str << Symbols::CRLF; + } + + return str; +} + +EncodeStream& +ParserContainerBase::encodeEmbedded(const Data& headerName, + EncodeStream& str) const +{ + assert(!headerName.empty()); + + if (!mParsers.empty()) + { + + bool first = true; + for (Parsers::const_iterator i = mParsers.begin(); + i != mParsers.end(); ++i) + { + if (first) + { + first = false; + } + else + { + str << Symbols::AMPERSAND; + } + + str << headerName << Symbols::EQUALS; + Data buf; + { + DataStream s(buf); + i->encode(s); + } + str << Embedded::encode(buf); + } + } + return str; +} + +void +ParserContainerBase::copyParsers(const Parsers& parsers) +{ + mParsers.reserve(mParsers.size() + parsers.size()); + for(Parsers::const_iterator p=parsers.begin(); p!=parsers.end(); ++p) + { + mParsers.push_back(*p); + HeaderKit& kit(mParsers.back()); + if(kit.pc) + { + kit.pc = makeParser(*kit.pc); + } + } +} + +void +ParserContainerBase::freeParsers() +{ + for(Parsers::iterator p=mParsers.begin(); p!=mParsers.end(); ++p) + { + freeParser(*p); + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ParserContainerBase.hxx b/src/libs/resiprocate/resip/stack/ParserContainerBase.hxx new file mode 100644 index 00000000..fbaa2158 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ParserContainerBase.hxx @@ -0,0 +1,263 @@ +#ifndef RESIP_ParserContainerBase_hxx +#define RESIP_ParserContainerBase_hxx + +#include "resip/stack/ParserCategory.hxx" +#include <iosfwd> +#include "resip/stack/HeaderTypes.hxx" +#include <vector> + +#include "rutil/StlPoolAllocator.hxx" +#include "rutil/PoolBase.hxx" + +namespace resip +{ + +class HeaderFieldValueList; +class PoolBase; + +/** + @class ParserContainerBase + @brief Abstract Base class implemented in derived class ParserContainer + */ +class ParserContainerBase +{ + public: + typedef size_t size_type; + + /** + @brief constructor; sets the type only + */ + ParserContainerBase(Headers::Type type = Headers::UNKNOWN); + + /** + @brief constructor; sets the type only + */ + ParserContainerBase(Headers::Type type, + PoolBase& pool); + + /** + @brief copy constructor copies the mType and the mParsers from the rhs + @note this is a shallow copy + */ + ParserContainerBase(const ParserContainerBase& rhs); + + ParserContainerBase(const ParserContainerBase& rhs, + PoolBase& pool); + + /** + @brief assignment operator copies the mParsers from the rhs + @note this is a shallow copy + */ + ParserContainerBase& operator=(const ParserContainerBase& rhs); + + /** + @brief virtual destructor - empty in this class + */ + virtual ~ParserContainerBase(); + + /** + @brief clear the mParsers vector + */ + inline void clear() {mParsers.clear();} + + /** + @brief pure virtual function to be implemented in derived classes + with the intention of cloning this object + */ + virtual ParserContainerBase* clone() const = 0; + + /** + @brief return the size of the mParsers vector + */ + inline size_t size() const {return mParsers.size();} + + /** + @brief return true or false indicating whether the mParsers vector is + empty or not + */ + inline bool empty() const {return mParsers.empty();} + + /** + @internal + @brief the actual mechanics of parsing + @todo add support for headers that are allowed to be empty like + Supported, Accept-Encoding, Allow-Events, Allow, Accept, + Accept-Language + */ + EncodeStream& encode(const Data& headerName, EncodeStream& str) const; + + /** + @internal + @brief the actual mechanics of parsing + */ + std::ostream& encode(Headers::Type type,std::ostream& str) const; + + /** + @internal + @brief the actual mechanics of parsing + */ + EncodeStream& encodeEmbedded(const Data& headerName, EncodeStream& str) const; + + /** + @brief if mParsers vector is not empty, erase the first element + */ + void pop_front(); + + /** + @brief if mParsers vector is not empty, erase the first element + */ + void pop_back(); + + /** + @brief append the vector to the mParsers vector held locally + @param rhs is the vector whose elements will be added to the + local mParsers vector + */ + void append(const ParserContainerBase& rhs); + + /** + @brief pure virtual function to be implemented in derived classes + The intention is to provide an ability to parse all elements + in the mParsers vector. + */ + virtual void parseAll()=0; + protected: + const Headers::Type mType; + + /** + @internal + */ + class HeaderKit + { + public: + static const HeaderKit Empty; + + HeaderKit(): pc(0){} + HeaderKit(const HeaderKit& orig) + : pc(orig.pc), + hfv(orig.hfv) + {} + + HeaderKit& operator=(const HeaderKit& rhs) + { + if(this!=&rhs) + { + pc=rhs.pc; + hfv=rhs.hfv; + } + return *this; + } + + ~HeaderKit() + {} + + EncodeStream& encode(EncodeStream& str) const + { + if(pc) + { + pc->encode(str); + } + else + { + hfv.encode(str); + } + return str; + } + + ParserCategory* pc; + HeaderFieldValue hfv; + }; + + typedef std::vector<HeaderKit, StlPoolAllocator<HeaderKit, PoolBase> > Parsers; + /** + @brief the actual list (vector) of parsers on which encoding is done + */ + Parsers mParsers; + PoolBase* mPool; + + /** + @brief copy header kits + */ + void copyParsers(const Parsers& parsers); + + /** + @brief free parser containers + */ + void freeParsers(); + + inline void freeParser(HeaderKit& kit) + { + if(kit.pc) + { + kit.pc->~ParserCategory(); + if(mPool) + { + mPool->deallocate(kit.pc); + } + else + { + ::operator delete(kit.pc); + } + kit.pc=0; + } + } + + inline ParserCategory* makeParser(const ParserCategory& orig) + { + return orig.clone(mPool); + } +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Pidf.cxx b/src/libs/resiprocate/resip/stack/Pidf.cxx new file mode 100644 index 00000000..08b04b9a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Pidf.cxx @@ -0,0 +1,448 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Pidf.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/XMLCursor.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +bool +Pidf::init() +{ + static ContentsFactory<Pidf> factory; + (void)factory; + return true; +} + +const Pidf Pidf::Empty; + +Pidf::Pidf() + : Contents(getStaticType()), + mNote() +{ +} + +Pidf::Pidf(const Data& txt) + : Contents(getStaticType()), + mNote(txt) +{ +} + +Pidf::Pidf(const Mime& contentType) + : Contents(getStaticType()), + mNote() +{ +} + +Pidf::Pidf(const HeaderFieldValue& hfv, const Mime& contentsType) + : Contents(hfv, contentsType), + mNote() +{ +} + +Pidf::Pidf(const Data& txt, const Mime& contentType) + : Contents(contentType), + mNote(txt) +{ +} + +Pidf& +Pidf::operator=(const Pidf& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + mNote = rhs.mNote; + mEntity = rhs.mEntity; + mTuples = rhs.mTuples; + } + return *this; +} + +Pidf::Pidf(const Pidf& rhs) + : Contents(rhs), + mNote(rhs.mNote), + mEntity(rhs.mEntity), + mTuples(rhs.mTuples) +{ +} + +Pidf::Pidf(const Uri& entity) + : Contents(getStaticType()), + mEntity(entity) +{ +} + +Pidf::~Pidf() +{ +} + +void +Pidf::setEntity(const Uri& entity) +{ + checkParsed(); + mEntity = entity; +} + +const Uri& +Pidf::getEntity() const +{ + checkParsed(); + return mEntity; +}; + +std::vector<Pidf::Tuple>& +Pidf::getTuples() +{ + checkParsed(); + return mTuples; +} + +const std::vector<Pidf::Tuple>& +Pidf::getTuples() const +{ + checkParsed(); + return mTuples; +} + +int +Pidf::getNumTuples() const +{ + checkParsed(); + return (int)mTuples.size(); +} + +Contents* +Pidf::clone() const +{ + return new Pidf(*this); +} + +const Mime& +Pidf::getStaticType() +{ + static Mime type("application","pidf+xml"); + return type; +} + +EncodeStream& +Pidf::encodeParsed(EncodeStream& str) const +{ + str << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << Symbols::CRLF; + str << "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"" << Symbols::CRLF; + str << " entity=\"" << mEntity << "\">" << Symbols::CRLF; + for (vector<Tuple>::const_iterator i = mTuples.begin(); i != mTuples.end(); ++i) + { + Data status( (char*)( (i->status) ? "open" : "closed" ) ); + str << " <tuple id=\"" << i->id << "\" "; + + XMLCursor::encode(str, i->attributes); + str << ">" << Symbols::CRLF; + str << " <status><basic>" << status << "</basic></status>" << Symbols::CRLF; + if ( !i->contact.empty() ) + { + str << " <contact priority=\"" << i->contactPriority << "\">" << i->contact << "</contact>" << Symbols::CRLF; + } + if ( !i->timeStamp.empty() ) + { + str << " <timestamp>" << i->timeStamp << "</timestamp>" << Symbols::CRLF; + } + if ( !i->note.empty() ) + { + str << " <note>" << i->note << "</note>" << Symbols::CRLF; + } + str << " </tuple>" << Symbols::CRLF; + } + str << "</presence>" << Symbols::CRLF; + + return str; +} + +void +Pidf::parse(ParseBuffer& pb) +{ +/* + REVISIT WHY THE BELOW WAS REMOVED + REMOVING IT SCREWS UP WHAT GOES OUT IN THE PUBLISH +*/ + DebugLog(<< "Pidf::parse(" << Data(pb.start(), int(pb.end()-pb.start())) << ") "); + + std::string pidf_namespace; + + XMLCursor xml(pb); + + XMLCursor::AttributeMap attr = xml.getAttributes(); + XMLCursor::AttributeMap::const_iterator it = + std::find_if(attr.begin(), attr.end(), XMLCursor::AttributeValueEqual("urn:ietf:params:xml:ns:pidf")); + + if ( it != attr.end() ) { + + std::string key(it->first.data(), it->first.size()); + + size_t pos = key.find(':'); + + if ( pos != string::npos) { + pidf_namespace.assign(key, pos+1, key.size()-pos-1); + pidf_namespace.append(1, ':'); + } + } + + const std::string presence = pidf_namespace + "presence"; + + if (xml.getTag() == presence.c_str()) + { + XMLCursor::AttributeMap::const_iterator i = xml.getAttributes().find("entity"); + if (i != xml.getAttributes().end()) + { + mEntity = Uri(i->second); + } + else + { + DebugLog(<< "no entity!"); + } + + if (xml.firstChild()) + { + do + { + const std::string tuple = pidf_namespace + "tuple"; + if (xml.getTag() == tuple.c_str()) + { + Tuple t; + t.attributes = xml.getAttributes(); + XMLCursor::AttributeMap::const_iterator i = xml.getAttributes().find("id"); + if (i != xml.getAttributes().end()) + { + t.id = i->second; + t.attributes.erase("id"); + } + + // look for status, contacts, notes -- take last of each for now + if (xml.firstChild()) + { + do + { + const std::string status = pidf_namespace + "status"; + const std::string contact = pidf_namespace + "contact"; + const std::string note = pidf_namespace + "note"; + const std::string timestamp = pidf_namespace + "timestamp"; + if (xml.getTag() == status.c_str()) + { + // look for basic + if (xml.firstChild()) + { + do + { + std::string basic = pidf_namespace + "basic"; + if (xml.getTag() == basic.c_str()) + { + if (xml.firstChild()) + { + t.status = (xml.getValue() == "open"); + xml.parent(); + } + } + } while (xml.nextSibling()); + xml.parent(); + } + } + else if (xml.getTag() == contact.c_str()) + { + XMLCursor::AttributeMap::const_iterator i = xml.getAttributes().find("priority"); + if (i != xml.getAttributes().end()) + { + t.contactPriority.setValue(i->second); + } + if (xml.firstChild()) + { + t.contact = xml.getValue(); + xml.parent(); + } + } + else if (xml.getTag() == note.c_str()) + { + if (xml.firstChild()) + { + t.note = xml.getValue(); + xml.parent(); + } + } + else if (xml.getTag() == timestamp.c_str()) + { + if (xml.firstChild()) + { + t.timeStamp = xml.getValue(); + xml.parent(); + } + } + } while (xml.nextSibling()); + xml.parent(); + } + + mTuples.push_back(t); + } + } while (xml.nextSibling()); + xml.parent(); + } + } + else + { + DebugLog(<< "no presence tag!"); + } +/* + REVISIT WHY THE ABOVE WAS REMOVED +*/ + + // THIS HERE IS THE ESSENCE OF WHAT IS USED. + // const char* anchor = pb.position(); + const char* anchor = pb.start(); + pb.skipToEnd(); + pb.data(mNote, anchor); + DebugLog(<< "mNote is : " << mNote ); + // END OF - ESSENCE +} + +void +Pidf::setSimpleId(const Data& id) +{ + checkParsed(); + if (mTuples.empty()) + { + Tuple t; + mTuples.push_back(t); + } + mTuples[0].id = id; +} + +void +Pidf::setSimpleStatus( bool online, const Data& note, const Data& contact ) +{ + checkParsed(); + if (mTuples.empty()) + { + Tuple t; + mTuples.push_back(t); + } + + mTuples[0].status = online; + mTuples[0].contact = contact; + mTuples[0].contactPriority = 1000; // 1.0 + mTuples[0].note = note; + mTuples[0].timeStamp = Data::Empty; +} + +bool +Pidf::getSimpleStatus(Data* note) const +{ + checkParsed(); + + if (!mTuples.empty()) + { + if (note) + { + *note = mTuples[0].note; + } + + return mTuples[0].status; + } + return false; +} + +void +Pidf::merge(const Pidf& other) +{ + vector<Tuple>& tuples = getTuples(); + tuples.reserve(tuples.size() + other.getTuples().size()); + + setEntity(other.mEntity); + + for (vector<Tuple>::const_iterator i = other.getTuples().begin(); + i != other.getTuples().end(); ++i) + { + bool found = false; + for (vector<Tuple>::iterator j = getTuples().begin(); + j != getTuples().end(); ++j) + { + if (i->id == j->id) + { + found = true; + *j = *i; + break; + } + } + if (!found) + { + tuples.push_back(*i); + } + } +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const Pidf::Tuple& tuple) +{ + strm << "Tuple [" + << " status=" << tuple.status + << " id=" << tuple.id + << " contact=" << tuple.contact + << " attributes=" << Inserter(tuple.attributes); + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Pidf.hxx b/src/libs/resiprocate/resip/stack/Pidf.hxx new file mode 100644 index 00000000..003f45ce --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Pidf.hxx @@ -0,0 +1,151 @@ +#if !defined(RESIP_PIDF_HXX) +#define RESIP_PIDF_HXX + +#include <vector> + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" +#include "rutil/HashMap.hxx" +#include "resip/stack/Uri.hxx" +#include "rutil/HeapInstanceCounter.hxx" +#include "resip/stack/QValue.hxx" + +namespace resip +{ + +/** + @deprecated + @brief Deprecated + + SIP body type for holding PIDF contents (MIME content-type application/pidf+xml). +*/ +class Pidf : public Contents +{ + public: + static const Pidf Empty; + +// only for Pidf (not for CpimContents) + RESIP_HeapCount(Pidf); + Pidf(const Mime& contentType); + explicit Pidf(const Uri& entity); +// end of - only for Pidf (not for CpimContents) + Pidf(); + Pidf(const Data& txt); + Pidf(const HeaderFieldValue& hfv, const Mime& contentType); + Pidf(const Data& txt, const Mime& contentType); + Pidf(const Pidf& rhs); + virtual ~Pidf(); + Pidf& operator=(const Pidf& rhs); + + /** @brief duplicate an Pidf object + @return pointer to a new Pidf object + **/ + virtual Contents* clone() const; + static const Mime& getStaticType() ; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + +// only for Pidf (not for CpimContents) + void setSimpleId(const Data& id); + void setEntity(const Uri& entity); + const Uri& getEntity() const; + void setSimpleStatus(bool online, const Data& note = Data::Empty, + const Data& contact = Data::Empty); + bool getSimpleStatus(Data* note=NULL) const; +// end of - only for Pidf (not for CpimContents) + + Data& text() {checkParsed(); return mNote;} + + static bool init(); + + +// only for Pidf (not for CpimContents) + /** @deprecated + @brief Deprecated + */ + class Tuple + { + public: + bool status; + Data id; + Data contact; + QValue contactPriority; + Data note; + Data timeStamp; + HashMap<Data, Data> attributes; + }; + + std::vector<Tuple>& getTuples(); + const std::vector<Tuple>& getTuples() const; + int getNumTuples() const; + + // combine tuples + void merge(const Pidf& other); +// end of - only for Pidf (not for CpimContents) + + private: + Data mNote; // equivalent to mText in Cpim +// only for Pidf (not for CpimContents) + Uri mEntity; + std::vector<Tuple> mTuples; +// end of - only for Pidf (not for CpimContents) +}; + +EncodeStream& operator<<(EncodeStream& strm, const Pidf::Tuple& tuple); +// only for Pidf (not for CpimContents) +static bool invokePidfInit = Pidf::init(); +// end of - only for Pidf (not for CpimContents) + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Pkcs7Contents.cxx b/src/libs/resiprocate/resip/stack/Pkcs7Contents.cxx new file mode 100644 index 00000000..55e0ccd8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Pkcs7Contents.cxx @@ -0,0 +1,209 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Pkcs7Contents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +const Pkcs7Contents Pkcs7Contents::Empty; +const Pkcs7SignedContents Pkcs7SignedContents::Empty; + +bool +Pkcs7Contents::init() +{ + static ContentsFactory<Pkcs7Contents> factory; + (void)factory; + return true; +} + +bool +Pkcs7SignedContents::init() +{ + static ContentsFactory<Pkcs7SignedContents> factory; + (void)factory; + return true; +} + +Pkcs7Contents::Pkcs7Contents() + : Contents(getStaticType()), + mText() +{ +} + +Pkcs7SignedContents::Pkcs7SignedContents() +{ +} + +Pkcs7Contents::Pkcs7Contents(const Data& txt) + : Contents(getStaticType()), + mText(txt) +{ +} + +Pkcs7SignedContents::Pkcs7SignedContents(const Data& txt) + : Pkcs7Contents(txt, getStaticType()) +{ +} + +Pkcs7Contents::Pkcs7Contents(const Data& txt, const Mime& contentsType) + : Contents(contentsType), + mText(txt) +{ +} + +Pkcs7Contents::Pkcs7Contents(const HeaderFieldValue& hfv, const Mime& contentsType) + : Contents(hfv, contentsType), + mText() +{ +} + +Pkcs7SignedContents::Pkcs7SignedContents(const HeaderFieldValue& hfv, const Mime& contentsType) + : Pkcs7Contents(hfv, contentsType) +{ +} + +Pkcs7Contents::Pkcs7Contents(const Pkcs7Contents& rhs) + : Contents(rhs), + mText(rhs.mText) +{ +} + +Pkcs7SignedContents::Pkcs7SignedContents(const Pkcs7SignedContents& rhs) + : Pkcs7Contents(rhs) +{ +} + +Pkcs7Contents::~Pkcs7Contents() +{ +} + +Pkcs7SignedContents::~Pkcs7SignedContents() +{ +} + +Pkcs7Contents& +Pkcs7Contents::operator=(const Pkcs7Contents& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + mText = rhs.mText; + } + return *this; +} + +Contents* +Pkcs7Contents::clone() const +{ + return new Pkcs7Contents(*this); +} + +Contents* +Pkcs7SignedContents::clone() const +{ + return new Pkcs7SignedContents(*this); +} + +const Mime& +Pkcs7Contents::getStaticType() +{ + static Mime type("application","pkcs7-mime"); + return type; +} + +const Mime& +Pkcs7SignedContents::getStaticType() +{ + static Mime type("application","pkcs7-signature"); + return type; +} + + +EncodeStream& +Pkcs7Contents::encodeParsed(EncodeStream& str) const +{ + //DebugLog(<< "Pkcs7Contents::encodeParsed " << mText); + str << mText; + return str; +} + + +void +Pkcs7Contents::parse(ParseBuffer& pb) +{ + const char* anchor = pb.position(); + pb.skipToEnd(); + pb.data(mText, anchor); + + if ( mTransferEncoding ) + { + InfoLog( << "Transfer Encoding is " << mTransferEncoding->value() ); + if ( mTransferEncoding->value() == Data("base64") ) + { + Data bin = mText.base64decode(); + mText = bin; + InfoLog( << "Base64 decoded to " << mText.escaped() ); + } + } + + DebugLog(<< "Pkcs7Contents::parsed <" << mText.escaped() << ">" ); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Pkcs7Contents.hxx b/src/libs/resiprocate/resip/stack/Pkcs7Contents.hxx new file mode 100644 index 00000000..70cbd47f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Pkcs7Contents.hxx @@ -0,0 +1,130 @@ +#if !defined(RESIP_PKCS7CONTENTS_HXX) +#define RESIP_PKCS7CONTENTS_HXX + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type for holding PKCS7 contents (MIME content-type application/pkcs7-mime). +*/ +class Pkcs7Contents : public Contents +{ + public: + static const Pkcs7Contents Empty; + + Pkcs7Contents(); + Pkcs7Contents(const Data& text); + Pkcs7Contents(const HeaderFieldValue& hfv, const Mime& contentType); + Pkcs7Contents(const Data& data, const Mime& contentType); + Pkcs7Contents(const Pkcs7Contents& rhs); + virtual ~Pkcs7Contents(); + Pkcs7Contents& operator=(const Pkcs7Contents& rhs); + + /** @brief duplicate an Pkcs7Contents object + @return pointer to a new Pkcs7Contents object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType() ; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + //Data& text() {checkParsed(); return mText;} + + static bool init(); + + private: + Data mText; +}; + +static bool invokePkcs7ContentsInit = Pkcs7Contents::init(); + +/** + @ingroup sip_payload + @brief SIP body type for holding PKCS7 Signed contents (MIME content-type application/pkcs7-signature). +*/ +class Pkcs7SignedContents : public Pkcs7Contents +{ + public: + static const Pkcs7SignedContents Empty; + + Pkcs7SignedContents(); + Pkcs7SignedContents(const Data& text); + Pkcs7SignedContents(const HeaderFieldValue& hfv, const Mime& contentType); + Pkcs7SignedContents(const Data& data, const Mime& contentType); + Pkcs7SignedContents(const Pkcs7SignedContents& rhs); + + virtual ~Pkcs7SignedContents(); + + Pkcs7SignedContents& operator=(const Pkcs7SignedContents& rhs); + + static const Mime& getStaticType() ; + + /** @brief duplicate an Pkcs7SignedContents object + @return pointer to a new Pkcs7SignedContents object + **/ + virtual Contents* clone() const; + + static bool init(); +}; + +static bool invokePkcs7SignedContentsInit = Pkcs7SignedContents::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Pkcs8Contents.cxx b/src/libs/resiprocate/resip/stack/Pkcs8Contents.cxx new file mode 100644 index 00000000..ac6e05b3 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Pkcs8Contents.cxx @@ -0,0 +1,151 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Pkcs8Contents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +const Pkcs8Contents Pkcs8Contents::Empty; + +static bool invokePkcs8ContentsInit = Pkcs8Contents::init(); + +bool +Pkcs8Contents::init() +{ + static ContentsFactory<Pkcs8Contents> factory; + (void)factory; + return true; +} + +Pkcs8Contents::Pkcs8Contents() + : Contents(getStaticType()), + mText() +{ +} + +Pkcs8Contents::Pkcs8Contents(const Data& txt) + : Contents(getStaticType()), + mText(txt) +{ +} + +Pkcs8Contents::Pkcs8Contents(const Data& txt, const Mime& contentsType) + : Contents(contentsType), + mText(txt) +{ +} + +Pkcs8Contents::Pkcs8Contents(const HeaderFieldValue& hfv, const Mime& contentsType) + : Contents(hfv, contentsType), + mText() +{ +} + +Pkcs8Contents::Pkcs8Contents(const Pkcs8Contents& rhs) + : Contents(rhs), + mText(rhs.mText) +{ +} + +Pkcs8Contents::~Pkcs8Contents() +{ +} + +Pkcs8Contents& +Pkcs8Contents::operator=(const Pkcs8Contents& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + mText = rhs.mText; + } + return *this; +} + +Contents* +Pkcs8Contents::clone() const +{ + return new Pkcs8Contents(*this); +} + +const Mime& +Pkcs8Contents::getStaticType() +{ + static Mime type("application", "pkcs8"); + return type; +} + +EncodeStream& +Pkcs8Contents::encodeParsed(EncodeStream& str) const +{ + //DebugLog(<< "Pkcs8Contents::encodeParsed " << mText); + str << mText; + return str; +} + + +void +Pkcs8Contents::parse(ParseBuffer& pb) +{ + const char* anchor = pb.position(); + pb.skipToEnd(); + pb.data(mText, anchor); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Pkcs8Contents.hxx b/src/libs/resiprocate/resip/stack/Pkcs8Contents.hxx new file mode 100644 index 00000000..c22343c9 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Pkcs8Contents.hxx @@ -0,0 +1,97 @@ +#ifndef RESIP_Pkcs8Contents_hxx +#define RESIP_Pkcs8Contents_hxx + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type for holding PKCS8 contents (MIME content-type application/pkcs8). +*/ +class Pkcs8Contents : public Contents +{ + public: + static const Pkcs8Contents Empty; + + Pkcs8Contents(); + Pkcs8Contents(const Data& text); + Pkcs8Contents(const HeaderFieldValue& hfv, const Mime& contentType); + Pkcs8Contents(const Data& data, const Mime& contentType); + Pkcs8Contents(const Pkcs8Contents& rhs); + virtual ~Pkcs8Contents(); + Pkcs8Contents& operator=(const Pkcs8Contents& rhs); + + /** @brief duplicate an Pkcs8Contents object + @return pointer to a new Pkcs8Contents object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType() ; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + Data& text() {checkParsed(); return mText;} + + static bool init(); + + private: + Data mText; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/PlainContents.cxx b/src/libs/resiprocate/resip/stack/PlainContents.cxx new file mode 100644 index 00000000..8f1d08bf --- /dev/null +++ b/src/libs/resiprocate/resip/stack/PlainContents.cxx @@ -0,0 +1,154 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/PlainContents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +const PlainContents PlainContents::Empty; +static bool invokePlainContentsInit = PlainContents::init(); + + +bool +PlainContents::init() +{ + static ContentsFactory<PlainContents> factory; + (void)factory; + return true; +} + + +PlainContents::PlainContents() + : Contents(getStaticType()), + mText() +{} + +PlainContents::PlainContents(const Data& txt) + : Contents(getStaticType()), + mText(txt) +{} + +PlainContents::PlainContents(const HeaderFieldValue& hfv, const Mime& contentsType) + : Contents(hfv, contentsType), + mText() +{ +} + +PlainContents::PlainContents(const Data& txt, const Mime& contentsType) + : Contents(contentsType), + mText(txt) +{ +} + +PlainContents::PlainContents(const PlainContents& rhs) + : Contents(rhs), + mText(rhs.mText) +{ +} + +PlainContents::~PlainContents() +{ +} + +PlainContents& +PlainContents::operator=(const PlainContents& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + mText = rhs.mText; + } + return *this; +} + +Contents* +PlainContents::clone() const +{ + return new PlainContents(*this); +} + +const Mime& +PlainContents::getStaticType() +{ + static Mime type("text","plain"); + return type; +} + +EncodeStream& +PlainContents::encodeParsed(EncodeStream& str) const +{ + //DebugLog(<< "PlainContents::encodeParsed " << mText); + str << mText; + return str; +} + +void +PlainContents::parse(ParseBuffer& pb) +{ + //DebugLog(<< "PlainContents::parse: " << pb.position()); + + const char* anchor = pb.position(); + pb.skipToEnd(); + pb.data(mText, anchor); + + //DebugLog("PlainContents::parsed <" << mText << ">" ); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/PlainContents.hxx b/src/libs/resiprocate/resip/stack/PlainContents.hxx new file mode 100644 index 00000000..15173a5f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/PlainContents.hxx @@ -0,0 +1,98 @@ +#if !defined(RESIP_PLAINCONTENTS_HXX) +#define RESIP_PLAINCONTENTS_HXX + +#include "resip/stack/Contents.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type for holding plain contents (MIME content-type text/plain). +*/ +class PlainContents : public Contents +{ + public: + static const PlainContents Empty; + + PlainContents(); + PlainContents(const Data& text); + PlainContents(const HeaderFieldValue& hfv, const Mime& contentType); + PlainContents(const Data& data, const Mime& contentType); + PlainContents(const PlainContents& rhs); + virtual ~PlainContents(); + PlainContents& operator=(const PlainContents& rhs); + + /** @brief duplicate an PlainContents object + @return pointer to a new PlainContents object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType() ; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + const Data& text() const {checkParsed(); return mText;} + Data& text() {checkParsed(); return mText;} + + static bool init(); + private: + Data mText; +}; + +static bool invokePlainContentsInit = PlainContents::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/PollStatistics.hxx b/src/libs/resiprocate/resip/stack/PollStatistics.hxx new file mode 100644 index 00000000..9aa12d61 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/PollStatistics.hxx @@ -0,0 +1,85 @@ +#ifndef PollStatistics_Include_Guard +#define PollStatistics_Include_Guard + +#include "resip/stack/TransactionMessage.hxx" + +namespace resip +{ +class PollStatistics : public TransactionMessage +{ + public: + explicit PollStatistics(){} + virtual ~PollStatistics(){} + + virtual const Data& getTransactionId() const {return Data::Empty;} + virtual bool isClientTransaction() const {return true;} + virtual EncodeStream& encode(EncodeStream& strm) const + { + return strm << "PollStatistics"; + } + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "PollStatistics"; + } + + virtual Message* clone() const + { + return new PollStatistics(*this); + } +}; // class PollStatistics + +} // namespace resip + +#endif // include guard + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ + diff --git a/src/libs/resiprocate/resip/stack/PrivacyCategory.cxx b/src/libs/resiprocate/resip/stack/PrivacyCategory.cxx new file mode 100644 index 00000000..7673b281 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/PrivacyCategory.cxx @@ -0,0 +1,174 @@ +#include "resip/stack/PrivacyCategory.hxx" + +#include "rutil/ParseBuffer.hxx" + +namespace resip +{ +PrivacyCategory::PrivacyCategory() + : ParserCategory(), + mValue() +{} + +static const Data parseContext("PrivacyCategory constructor"); +PrivacyCategory::PrivacyCategory(const Data& d) + : ParserCategory(), + mValue() +{ + HeaderFieldValue hfv(d.data(), d.size()); + PrivacyCategory tmp(hfv, Headers::UNKNOWN); + tmp.checkParsed(); + *this = tmp; +} + +PrivacyCategory::PrivacyCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), + mValue() +{} + +PrivacyCategory::PrivacyCategory(const PrivacyCategory& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mValue(rhs.mValue) +{} + +PrivacyCategory& +PrivacyCategory::operator=(const PrivacyCategory& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mValue = rhs.mValue; + } + return *this; +} + +const std::vector<Data>& +PrivacyCategory::value() const +{ + checkParsed(); + return mValue; +} + +std::vector<Data>& +PrivacyCategory::value() +{ + checkParsed(); + return mValue; +} + +void +PrivacyCategory::parse(ParseBuffer& pb) +{ + while(!pb.eof()) + { + pb.skipWhitespace(); + if(!pb.eof()) + { + const char* start=pb.position(); + pb.skipToOneOf(";",ParseBuffer::Whitespace); + if(pb.position()==start) + { + throw ParseException("Empty privacy token!", + "PrivacyCategory::parse()", + __FILE__, __LINE__); + } + mValue.push_back(pb.data(start)); + pb.skipWhitespace(); + } + if(!pb.eof()) + { + pb.skipChar(';'); + } + } +} + +ParserCategory* +PrivacyCategory::clone() const +{ + return new PrivacyCategory(*this); +} + +ParserCategory* +PrivacyCategory::clone(void* location) const +{ + return new (location) PrivacyCategory(*this); +} + +ParserCategory* +PrivacyCategory::clone(PoolBase* pool) const +{ + return new (pool) PrivacyCategory(*this, pool); +} + +EncodeStream& +PrivacyCategory::encodeParsed(EncodeStream& str) const +{ + bool first=true; + for(std::vector<Data>::const_iterator i=mValue.begin(); i!=mValue.end(); ++i) + { + if(first) + { + first=false; + } + else + { + str << ';'; + } + str << *i; + } + return str; +} + +} // of namespace resip + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/PrivacyCategory.hxx b/src/libs/resiprocate/resip/stack/PrivacyCategory.hxx new file mode 100644 index 00000000..e3745173 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/PrivacyCategory.hxx @@ -0,0 +1,96 @@ +#if !defined(RESIP_PRIVACY_CATEGORY_HXX) +#define RESIP_PRIVACY_CATEGORY_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/ParserContainer.hxx" + +namespace resip +{ + + +/** + @ingroup sip_grammar + @brief Represents the "token" element in the RFC 3261 grammar. +*/ +class PrivacyCategory : public ParserCategory +{ + public: + enum {commaHandling = CommasAllowedOutputCommas}; + + PrivacyCategory(); + explicit PrivacyCategory(const Data& d); + PrivacyCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + PrivacyCategory(const PrivacyCategory& orig, + PoolBase* pool=0); + PrivacyCategory& operator=(const PrivacyCategory&); + + const std::vector<Data>& value() const; + std::vector<Data>& value(); + + virtual void parse(ParseBuffer& pb); // remember to call parseParameters() + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + private: + std::vector<Data> mValue; +}; +typedef ParserContainer<PrivacyCategory> PrivacyCategories; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/QValue.cxx b/src/libs/resiprocate/resip/stack/QValue.cxx new file mode 100644 index 00000000..27c9d38c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/QValue.cxx @@ -0,0 +1,96 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/QValue.hxx" +//#include <iostream> + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +const Data& +QValue::getData() const +{ + DataStream strm(mDataValue); + encode(strm); + return mDataValue; +} + +EncodeStream& +QValue::encode(EncodeStream& stream) const +{ + int i = mValue; + + if (i == 1000) + { + return stream << "1.0"; + } + + stream << "0." << (i / 100); + i %= 100; + + if (i) + { + stream << (i / 10); + i %= 10; + + if (i) + { + stream << i; + } + } + + return stream; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/QValue.hxx b/src/libs/resiprocate/resip/stack/QValue.hxx new file mode 100644 index 00000000..911db0d5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/QValue.hxx @@ -0,0 +1,135 @@ +#if !defined(RESIP_QVALUE_HXX) +#define RESIP_QVALUE_HXX + +#include "rutil/Data.hxx" +#include "rutil/ParseBuffer.hxx" + +#ifndef RESIP_FIXED_POINT +#include <math.h> +// Required due to float point inaccuracies and platform dependent issues (ie. rounding) +static int doubleToInt(const double d) { double f = floor(d); double c = ceil(d); return (((c-d) >= (d-f)) ? (int)f :(int)c); } +#endif + +namespace resip +{ + class QValue + { + public: + explicit QValue() : mValue(0) { } + explicit QValue(int val) : mValue(val) { } + explicit QValue(const Data& data) { setValue(data); } + + operator int() const { return mValue; } + + bool operator<(const QValue& rhs) const { return mValue < rhs.mValue; } + bool operator>(const QValue& rhs) const { return mValue > rhs.mValue; } + bool operator<=(const QValue& rhs) const { return mValue <= rhs.mValue; } + bool operator>=(const QValue& rhs) const { return mValue >= rhs.mValue; } + bool operator==(const QValue& rhs) const { return mValue == rhs.mValue; } + bool operator!=(const QValue& rhs) const { return mValue != rhs.mValue; } + + bool operator<(const int rhs) const { return mValue < rhs; } + bool operator>(const int rhs) const { return mValue > rhs; } + bool operator<=(const int rhs) const { return mValue <= rhs; } + bool operator>=(const int rhs) const { return mValue >= rhs; } + bool operator==(const int rhs) const { return mValue == rhs; } + bool operator!=(const int rhs) const { return mValue != rhs; } + + bool operator<(const long rhs) const { return mValue < rhs; } + bool operator>(const long rhs) const { return mValue > rhs; } + bool operator<=(const long rhs) const { return mValue <= rhs; } + bool operator>=(const long rhs) const { return mValue >= rhs; } + bool operator==(const long rhs) const { return mValue == rhs; } + bool operator!=(const long rhs) const { return mValue != rhs; } + + QValue& operator=(const QValue& rhs) { mValue = rhs.mValue; return (*this); } + QValue& operator=(const int rhs) { setValue(rhs); return (*this); } + QValue& operator=(const long rhs) { setValue(rhs); return (*this); } + +#ifndef RESIP_FIXED_POINT + + float floatVal() const { return mValue/float(1000.0); } + + operator float() const { return floatVal(); } + operator double() const { return (double) floatVal(); } + + bool operator<(const float rhs) const { return mValue < doubleToInt(rhs*1000.0); } + bool operator>(const float rhs) const { return mValue > doubleToInt(rhs*1000.0); } + bool operator<=(const float rhs) const { return mValue <= doubleToInt(rhs*1000.0); } + bool operator>=(const float rhs) const { return mValue >= doubleToInt(rhs*1000.0); } + bool operator==(const float rhs) const { return mValue == doubleToInt(rhs*1000.0); } + bool operator!=(const float rhs) const { return mValue != doubleToInt(rhs*1000.0); } + + bool operator<(const double rhs) const { return mValue < doubleToInt(rhs*1000.0); } + bool operator>(const double rhs) const { return mValue > doubleToInt(rhs*1000.0); } + bool operator<=(const double rhs) const { return mValue <= doubleToInt(rhs*1000.0); } + bool operator>=(const double rhs) const { return mValue >= doubleToInt(rhs*1000.0); } + bool operator==(const double rhs) const { return mValue == doubleToInt(rhs*1000.0); } + bool operator!=(const double rhs) const { return mValue != doubleToInt(rhs*1000.0); } + + QValue& operator=(const float rhs) { setValue(doubleToInt(rhs*1000.0)); return (*this); } + QValue& operator=(const double rhs) { setValue(doubleToInt(rhs*1000.0)); return (*this); } +#endif + void setValue(int val) { mValue = (val<0) || (val>1000) ? 1000 : val; } + void setValue(const Data& data) { ParseBuffer pb(data); mValue = pb.qVal(); } + int getValue() const { return mValue; } + const Data& getData() const; + EncodeStream& encode(EncodeStream& stream) const; + + private: + int mValue; + mutable Data mDataValue; + }; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/QValueParameter.cxx b/src/libs/resiprocate/resip/stack/QValueParameter.cxx new file mode 100644 index 00000000..0e936628 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/QValueParameter.cxx @@ -0,0 +1,107 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/QValueParameter.hxx" +#include "rutil/ParseException.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +QValueParameter::QValueParameter(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators) + : Parameter(type), + mValue(0) +{ + pb.skipWhitespace(); + if (!pb.eof() && *pb.position() != '=') + { + throw ParseException("parameter constructor expected '='", + "QValueParameter", __FILE__, __LINE__); + } + pb.skipChar(); + pb.skipWhitespace(); + + // .dlb. not zero terminated; no error detection + mValue.setValue(pb.qVal()); +} + +QValueParameter::QValueParameter(ParameterTypes::Type type) + : Parameter(type), + mValue(0) +{} + +Parameter* +QValueParameter::clone() const +{ + return new QValueParameter(*this); +} + +EncodeStream& +QValueParameter::encode(EncodeStream& stream) const +{ + return stream << getName() << Symbols::EQUALS << mValue; +} + +EncodeStream& +resip::operator<<(EncodeStream& stream, const QValue& qvalue) +{ + return qvalue.encode(stream); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/QValueParameter.hxx b/src/libs/resiprocate/resip/stack/QValueParameter.hxx new file mode 100644 index 00000000..ddbe1ddb --- /dev/null +++ b/src/libs/resiprocate/resip/stack/QValueParameter.hxx @@ -0,0 +1,181 @@ +#if !defined(RESIP_QVALUEPARAMETER_HXX) +#define RESIP_QVALUEPARAMETER_HXX + +#include "rutil/resipfaststreams.hxx" + +#include "resip/stack/Parameter.hxx" +#include "resip/stack/ParameterTypeEnums.hxx" +#include "resip/stack/QValue.hxx" +#include "rutil/PoolBase.hxx" +#include <iosfwd> + +namespace resip +{ + + class ParseBuffer; + +/** + @ingroup sip_grammar + + @brief Represents the "q" parameter value of the RFC 3261 grammar. + + @see Parameter + + First reference to q-values in 3261 reproduced here: + + 8.1.3.4 Processing 3xx Responses + + Upon receipt of a redirection response (for example, a 301 response + status code), clients SHOULD use the URI(s) in the Contact header + field to formulate one or more new requests based on the redirected + request. This process is similar to that of a proxy recursing on a + 3xx class response as detailed in Sections 16.5 and 16.6. A client + starts with an initial target set containing exactly one URI, the + Request-URI of the original request. If a client wishes to formulate + new requests based on a 3xx class response to that request, it places + the URIs to try into the target set. Subject to the restrictions in + this specification, a client can choose which Contact URIs it places + into the target set. As with proxy recursion, a client processing + 3xx class responses MUST NOT add any given URI to the target set more + than once. If the original request had a SIPS URI in the Request- + URI, the client MAY choose to recurse to a non-SIPS URI, but SHOULD + inform the user of the redirection to an insecure URI. + + Any new request may receive 3xx responses themselves containing + the original URI as a contact. Two locations can be configured to + redirect to each other. Placing any given URI in the target set + only once prevents infinite redirection loops. + + As the target set grows, the client MAY generate new requests to the + URIs in any order. A common mechanism is to order the set by the "q" + parameter value from the Contact header field value. Requests to the + URIs MAY be generated serially or in parallel. One approach is to + process groups of decreasing q-values serially and process the URIs + in each q-value group in parallel. Another is to perform only serial + processing in decreasing q-value order, arbitrarily choosing between + contacts of equal q-value. +*/ + class QValueParameter : public Parameter + { + public: + typedef QValue Type; + + /** + @brief constructor + @param type used to initialize Parameter + @param pb input is expected to be in the format " = qvalue" + The blanks before and after the "=" sign are optional in this + implementation. But absence of "=" will throw a ParseException. + @param terminators not used + @see Parameter + @throw ParseException + */ + QValueParameter(ParameterTypes::Type, ParseBuffer& pb, const std::bitset<256>& terminators); + /** + @brief constructor creates object and sets q value to zero + @param type used to initialize Parameter + @throw nothing + */ + explicit QValueParameter(ParameterTypes::Type type); + + /** + @brief creates a QValueParameter object and returns a pointer to it. + @param type used to initialize Parameter + @param pb input is expected to be in the format " = qvalue" + The blanks before and after the "=" sign are optional in this + implementation. But absence of "=" will throw a ParseException. + @param terminators not used + @return a new QValueParameter object that is a copy of this one. + @throw ParseException + */ + static Parameter* decode(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators, + PoolBase* pool) + { + return new (pool) QValueParameter(type, pb, terminators); + } + + /** + @brief creates a new QValueParameter object that is a copy of this one. + @return a new QValueParameter object that is a copy of this one. + */ + virtual Parameter* clone() const; + + /** + @brief returns "q=3" or equivalent in the stream it receives + @param stream ostream to write into + @return ostream with information written into it + */ + virtual EncodeStream& encode(EncodeStream& stream) const; + + Type& value() {return mValue;} + int qval() const {return mValue.getValue();} + + private: + Type mValue; + }; + + /** + @brief calls encode and returns "q=3" or equivalent ostream + @param stream ostream to write into + @param qvalue qvalue + @return ostream with q value divided by 1000 and expressed in decimal to + 3 decimal places + @see QValue + */ + EncodeStream& operator<<(EncodeStream& stream, const QValue& qvalue); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/QuotedDataParameter.cxx b/src/libs/resiprocate/resip/stack/QuotedDataParameter.cxx new file mode 100644 index 00000000..6d77a1f8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/QuotedDataParameter.cxx @@ -0,0 +1,91 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <cassert> +#include "rutil/ParseException.hxx" +#include "resip/stack/QuotedDataParameter.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +QuotedDataParameter::QuotedDataParameter(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators) + : DataParameter(type, pb, terminators) +{ + if (!mQuoted) + { + DebugLog (<< "Fixing unquoted parameter to be quoted: " << mValue); + mQuoted = true; // may want to fail in this case if we are being strict + //pb.fail(__FILE__, __LINE__); + } +} + +QuotedDataParameter::QuotedDataParameter(ParameterTypes::Type type) + : DataParameter(type) +{ + mQuoted = true; +} + +Parameter* +QuotedDataParameter::clone() const +{ + return new QuotedDataParameter(*this); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/QuotedDataParameter.hxx b/src/libs/resiprocate/resip/stack/QuotedDataParameter.hxx new file mode 100644 index 00000000..0c5f3b7c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/QuotedDataParameter.hxx @@ -0,0 +1,98 @@ +#if !defined(RESIP_QUOTEDDATAPARAMETER_HXX) +#define RESIP_QUOTEDDATAPARAMETER_HXX + +#include "resip/stack/Parameter.hxx" +#include "resip/stack/ParameterTypeEnums.hxx" +#include "resip/stack/DataParameter.hxx" +#include "rutil/PoolBase.hxx" +#include <iosfwd> + +namespace resip +{ + +class ParseBuffer; + +/** + @ingroup sip_grammar + + @brief Generically represents miscellaneous parameter data that is + encoded using double quotes. +*/ +class QuotedDataParameter : public DataParameter +{ + public: + QuotedDataParameter(ParameterTypes::Type, ParseBuffer& pb, const std::bitset<256>& terminators); + explicit QuotedDataParameter(ParameterTypes::Type); + + static Parameter* decode(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators, + PoolBase* pool) + { + return new (pool) QuotedDataParameter(type, pb, terminators); + } + + virtual Parameter* clone() const; + + protected: + QuotedDataParameter(const QuotedDataParameter& other) + : DataParameter(other) + {} + + friend class ParserCategory; + friend class Auth; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/RAckCategory.cxx b/src/libs/resiprocate/resip/stack/RAckCategory.cxx new file mode 100644 index 00000000..cbd7d58d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/RAckCategory.cxx @@ -0,0 +1,218 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/RAckCategory.hxx" +#include "resip/stack/UnknownParameter.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// RAckCategory: +//==================== +RAckCategory::RAckCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), + mMethod(UNKNOWN), + mRSequence(0), + mCSequence(0) +{} + +RAckCategory::RAckCategory() + : ParserCategory(), + mMethod(UNKNOWN), + mUnknownMethodName(getMethodName(UNKNOWN)), + mRSequence(0), + mCSequence(0) +{} + +RAckCategory::RAckCategory(const RAckCategory& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mMethod(rhs.mMethod), + mUnknownMethodName(rhs.mUnknownMethodName), + mRSequence(rhs.mRSequence), + mCSequence(rhs.mCSequence) +{} + +RAckCategory& +RAckCategory::operator=(const RAckCategory& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mMethod = rhs.mMethod; + mUnknownMethodName = rhs.mUnknownMethodName; + mRSequence = rhs.mRSequence; + mCSequence = rhs.mCSequence; + } + return *this; +} + +bool +RAckCategory::operator==(const RAckCategory& rhs) const +{ + return (mMethod == rhs.mMethod && + (mMethod != UNKNOWN || mUnknownMethodName == rhs.mUnknownMethodName) && + mRSequence == rhs.mRSequence && + mCSequence == rhs.mCSequence); +} + +ParserCategory* +RAckCategory::clone() const +{ + return new RAckCategory(*this); +} + +ParserCategory* +RAckCategory::clone(void* location) const +{ + return new (location) RAckCategory(*this); +} + +ParserCategory* +RAckCategory::clone(PoolBase* pool) const +{ + return new (pool) RAckCategory(*this, pool); +} + +MethodTypes& +RAckCategory::method() +{ + checkParsed(); + return mMethod; +} + +MethodTypes +RAckCategory::method() const +{ + checkParsed(); return mMethod; +} + +Data& +RAckCategory::unknownMethodName() +{ + checkParsed(); + return mUnknownMethodName; +} + +const Data& +RAckCategory::unknownMethodName() const +{ + checkParsed(); + return mUnknownMethodName; +} + +unsigned int& +RAckCategory::rSequence() +{ + checkParsed(); + return mRSequence; +} + +unsigned int +RAckCategory::rSequence() const +{ + checkParsed(); + return mRSequence; +} + +unsigned int& +RAckCategory::cSequence() +{ + checkParsed(); + return mCSequence; +} + +unsigned int +RAckCategory::cSequence() const +{ + checkParsed(); + return mCSequence; +} + +void +RAckCategory::parse(ParseBuffer& pb) +{ + const char* anchorPtr; + pb.skipWhitespace(); + mRSequence = pb.uInt32(); + + pb.skipWhitespace(); + mCSequence = pb.uInt32(); + + anchorPtr = pb.skipWhitespace(); + pb.skipNonWhitespace(); + + mMethod = getMethodType(anchorPtr, int(pb.position() - anchorPtr)); + // for backward compatibility, set the method name even if the method is known + pb.data(mUnknownMethodName, anchorPtr); +} + +EncodeStream& +RAckCategory::encodeParsed(EncodeStream& str) const +{ + str << mRSequence << Symbols::SPACE + << mCSequence << Symbols::SPACE + << (mMethod != UNKNOWN ? getMethodName(mMethod) : mUnknownMethodName); + return str; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/RAckCategory.hxx b/src/libs/resiprocate/resip/stack/RAckCategory.hxx new file mode 100644 index 00000000..2fb253e6 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/RAckCategory.hxx @@ -0,0 +1,106 @@ +#ifndef RESIP_RAckCategory_hxx +#define RESIP_RAckCategory_hxx + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/MethodTypes.hxx" + +namespace resip +{ + +/** + @ingroup sip_grammar + @brief Represents the RAck header field value defined in the RFC 3262 + grammar. +*/ +class RAckCategory : public ParserCategory +{ + public: + enum {commaHandling = NoCommaTokenizing}; + + RAckCategory(); + RAckCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + RAckCategory(const RAckCategory& orig, + PoolBase* pool=0); + RAckCategory& operator=(const RAckCategory&); + + MethodTypes& method(); + MethodTypes method() const; + Data& unknownMethodName(); + const Data& unknownMethodName() const; + unsigned int& rSequence(); + unsigned int rSequence() const; + unsigned int& cSequence(); + unsigned int cSequence() const; + + bool operator==(const RAckCategory& rhs) const; + + virtual void parse(ParseBuffer& pb); + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + + private: + MethodTypes mMethod; + Data mUnknownMethodName; + unsigned int mRSequence; + unsigned int mCSequence; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/README b/src/libs/resiprocate/resip/stack/README new file mode 100644 index 00000000..14bb57f3 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/README @@ -0,0 +1,190 @@ +September 23, 2002 +head/vocal/sip2/sipstack/README + +SipMessage design goals: +- efficient parsing +- reasonable interface for the application writer +- reasonably easy path to adding new headers, methods, parameter names + +SipMessage design. + +There are two APIs to SipMessage; one from the transport layer 'up' and one from +the application layer 'down'. The transport layers pulls the raw message text +off the wire, parses the text just enough to segment it onto headers and sets +the text of the headers into the SipMessage generically. This minimal header +parse phase is called "pre-parsing". + +The pre-parse phase needs to identify the header for generic storage into the +SipMessage. In addition, the pre-parse phase needs to know if unescaped commas +are delimiters in the header text to be parsed. However, the pre-parse phase +does not require static typing of the header or whether the header can appear +multiple times in the message. + +The pre-parse phase allows unknown headers. + +The application requests a specific header by static type. If the header does +not exists, an empty header of the appropriate type is created. If the header +has not already been parsed, a parser is created and associated with the +header. The parser is not invoked until the application requests a sub-part of +the header. This permits headers to be moved from one message to another without +parsing within the header. + +The parser is statically typed to provide a specific interface to the +application. The specifics of how to parse a message of a given type is +implemented by the parser type. The static header types are available to the +application through global variables named after the headers; e.g. CallId, CSeq, +From, Via. + +The interface from each parser is a set of accessors. Each accessor may return a +reference, allowing the application to set the corresponding value directly, or +it may return a const reference, indicating a read only value. Most parsers also +present an interface to a generic parameter accessor. This generic parameter +accessors allows the application to get or set proprietary parameters. + +The application retrieves unknown headers by the string name of the unknown +header. + +Interface Examples: + +SipMessage *msg; +msg->get(From).getAddressOfRecord(); +Data& aor = msg->get(From)->host(); +msg->get(From).host() = "vovida.org"; +msg->exists(Warning); +msg->exists("Proprietary-Header"); // true if present +msg->get("Proprietary-Header"); // returns ParserContainer<String>& + +for (Vias::iterator i = msg->get(Vias).begin(); + i != msg->get(Vias).end(); i++) +{ + Data& host = i->host(); + int& port = i->port(); +} + +Implementation: + +There is a fixed set of headers. Each header is assigned an enum value. There is +a type associated with each enum value and a distinctly named global variable of +header type. The enum value is used to store and retrieve the headers at +runtime. The header type is used to retrieve the parsed and statically typed +headers at compile time. + +A SipMessage contains an array of pointers to HeaderFieldValueList. This array +is indexed by the header enums. + +The pre-parse phase consists of: +0. determine the boundaries of the header string +1. determine the boundaries of the header name string +2. look up the enum value for the header name +3. look up the comma tokenizing property of the header enum +4. determine the boundaries of each header in the header string +5. for each header in the header string, add the header string boundaries by + enum to the message -- the message stores the header string boundaries in the + as indexed by the header enum + +While processing headers the pre-parse will allocate chunks of memory to hold the +header strings. Each of these buffers is passed opaquely to the message for +deletion when the message is deleted. + +After pre-parsing the message header array contains one HeaderFieldValueList for +each header encountered in the pre-parse. Each HeaderFieldValueList contains +a list of HeaderFieldValue. + +The application requests the contents of a header through a type safe interface; +the returned object is either a particular parser type or a particular parser +container. A parser container is returned if and only if the header is specified +to permit multiple values. + +If the header specifies multiple values, the returned value is iterable. Each +iteration provides access to a header value. In addition, there is an interface +on the returned value to determine the number of header values. + +The returned value in the single header value case, and within the iteration +over the multi header value case provides access to the components of the header +value specfic to the type of header. For example, CSeq provides getMethod() and +sequence. For sequence, the sequence value is an integer returned by reference +and may be directly modified. + +Adding a new header: + +Assume the new header name New-Header + +Symbols.hxx +1. Add New_Header to the static symbol declarations. +Symbols.chxx +1. Add New_Header = "New-Header" to the static symbol definitions. + +HeaderTypes.hxx +1. Add New_Header to the Headers::Type enum. Add this entry anywhere before UNKNOWN. + Headers are output in the same order they appear in the Headers::Type enum. +2. Determine if the header allows multiple values. Use the MultiHeader template + if the new header allows multiple values, use the Header template if the new + header does not allow multiple values. +3. Determine the parser type for the header. This may be StringComponent for + unstructured headers, may be another existing parser type (see + ParserCategories.hxx), or may require a new parser type. +4. Add the declaration of the header type and the header type global variable to + HeaderTypes.hxx +e.g.: +class Header<Headers::New_Header> +{ + public: + typedef StringComponent Type; + Header() + { + Headers::CommaTokenizing[Headers::New_Header] = Type::isCommaTokenizing; + HeaderStrings[Headers::New_Header] = Symbols::New_Header; + } +}; +extern Header<Headers::Content_Disposition> Content_Disposition; +5. Add the mapping from the four character hash to the header enum. This is + error prone. The hash value is platform dependent. + +HeaderTypesSetup.cxx +1. Add a line to the hash id generator. + +HeaderTypes.cxx +1. Add the definition of the new header type global variable. Be sure to use the + same template type as in the declaration. +e.g. +Header<Headers::New_Header> Vocal2:: New_Header>; + +ParserCategories.hxx +(if the new header requires a new parser) + +1. Declare the new parser category as publicly inheriting from + ParserCategory. +2. Determine if commas can be used to include multiple header values in a single + line. +3. Declare virtual ParserCategory* clone(HeaderFieldValue*) const; +4. Declare virtual void parse(); +5. Declare private members as required to store the parsed header value. +6. Declare public methods as required to access the parsed header value. +7. Typedef the container for the parser. Not required if the header value is + never used in a header that allows multiple values. + +e.g. +typedef ParserContainer<NewComponent> NewComponents; + +ParserCategories.cxx +(if the new header requires a new parser) +1. Define clone(), parse() +2. Define accessors. Each accessor must call checkParsed() before processing any + data. + + +(* + It would be nice if getHeaderType(const char *headerName, int len) + was defined my configure/make. The supported.hxx would be replaced + with a configuration file headers.hdr that specified the SIP header name, the + C++ parser category, and whether the header allows multiple values. + + This file could be compiled into the various declarations and definitions. + It is even possible to allow the user to specify additional headers in the + code; have the automatically generated types go into the enum + HeaderTypesBase, and have HeaderTypes inherit; HeaderTypes::Types could + continue where the inherited enum leaves off. +*) + + + diff --git a/src/libs/resiprocate/resip/stack/Readme-Compliance.txt b/src/libs/resiprocate/resip/stack/Readme-Compliance.txt new file mode 100644 index 00000000..2c9209d4 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Readme-Compliance.txt @@ -0,0 +1,90 @@ +WARNING WARNING WARNING + +THIS FILE IS WELL OVER A YEAR OUT OF DATE + +The contents of this file are currently very inaccurate. +If you need to know about a particular RFC before this list +gets updated, please ask on resip-devel. + +------------------------------------------- + +RFC which the stack is in compliance with + +2976 - INFO +no + +3204 - ISUP & QSIG MIME +no + +3261 - sip +all including S/MIME and TLS + +3262 - Reliabilae provisional responses +Not suported + +3263 - SIP Locationt +- partial support only +- currently SRV and NAPTER are not supported + +3264 - Offer/Answer +Yes + +3265 - Events +Yes + +3310 - AKA +Not sure - probably + +3311 - Update +no + +3312 - Preconditions +Maybey - not sure + +3420 - sipfrag +yes + +3323 - Privacy +no + +3325 - Asserted-Identity +no + +3428 - MESSAGE +yes + +3326 - Reason +no + +3327 - Path +no + +3329 - Sec Agree +yes + +draft-ietf-impp-cpim-pidf-07.txt +yes + +http://www.ietf.org/internet-drafts/draft-ietf-sip-callerprefs-07.txt +hmm + +draft-message-waiting +yes + +2311 - S/MIME ver 2 spec +yes + +2045 - MIME part one +yes + +2046 - Mime part two +yes + +2633 - S/MIME ver 3 +yes + +2315 - PKCS#7 +yes + +1847 - Secure Multipart MIME +yes diff --git a/src/libs/resiprocate/resip/stack/RequestLine.cxx b/src/libs/resiprocate/resip/stack/RequestLine.cxx new file mode 100644 index 00000000..0f395094 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/RequestLine.cxx @@ -0,0 +1,222 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/RequestLine.hxx" +#include "resip/stack/UnknownParameter.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// RequestLine: +//==================== +RequestLine::RequestLine() + : StartLine(), + mMethod(UNKNOWN), + mUnknownMethodName(Data::Share,getMethodName(UNKNOWN)), + mSipVersion(Data::Share,Symbols::DefaultSipVersion) +{} + +RequestLine::RequestLine(MethodTypes method, + const Data& sipVersion) + : mMethod(method), + mUnknownMethodName(), + mSipVersion(sipVersion) +{} + +RequestLine::RequestLine(const HeaderFieldValue& hfv) + : StartLine(hfv), + mMethod(UNKNOWN), + mUnknownMethodName(Data::Share,getMethodName(UNKNOWN)), + mSipVersion(Data::Share,Symbols::DefaultSipVersion) +{} + +RequestLine::RequestLine(const char* buf, int len) : + StartLine(buf, len), + mMethod(UNKNOWN), + mUnknownMethodName(Data::Share,getMethodName(UNKNOWN)), + mSipVersion(Data::Share,Symbols::DefaultSipVersion) +{} + +RequestLine::RequestLine(const RequestLine& rhs) + : StartLine(rhs), + mUri(rhs.mUri), + mMethod(rhs.mMethod), + mUnknownMethodName(rhs.mUnknownMethodName), + mSipVersion(rhs.mSipVersion) +{} + +RequestLine& +RequestLine::operator=(const RequestLine& rhs) +{ + if (this != &rhs) + { + StartLine::operator=(rhs); + mUri = rhs.mUri; + mMethod = rhs.mMethod; + mUnknownMethodName = rhs.mUnknownMethodName; + mSipVersion = rhs.mSipVersion; + } + return *this; +} + +RequestLine::~RequestLine() +{} + +StartLine * +RequestLine::clone() const +{ + return new RequestLine(*this); +} + +StartLine * +RequestLine::clone(void* location) const +{ + return new (location) RequestLine(*this); +} + +const Uri& +RequestLine::uri() const +{ + checkParsed(); + return mUri; +} + +Uri& +RequestLine::uri() +{ + checkParsed(); + return mUri; +} + +MethodTypes +RequestLine::getMethod() const +{ + checkParsed(); + return mMethod; +} + +MethodTypes& +RequestLine::method() +{ + checkParsed(); + return mMethod; +} + +MethodTypes +RequestLine::method() const +{ + checkParsed(); + return mMethod; +} + +Data& +RequestLine::unknownMethodName() +{ + checkParsed(); + return mUnknownMethodName; +} + +const Data& +RequestLine::unknownMethodName() const +{ + checkParsed(); + return mUnknownMethodName; +} + +const Data& +RequestLine::getSipVersion() const +{ + checkParsed(); + return mSipVersion; +} + +void +RequestLine::parse(ParseBuffer& pb) +{ + const char* start; + start = pb.skipWhitespace(); + pb.skipNonWhitespace(); + mMethod = getMethodType(start, int(pb.position() - start)); + // for backward compatibility, set the method name even if the method is known + pb.data(mUnknownMethodName, start); + pb.skipWhitespace(); + mUri.parse(pb); + start = pb.skipWhitespace(); + pb.skipNonWhitespace(); + pb.data(mSipVersion, start); +} + +EncodeStream& +RequestLine::encodeParsed(EncodeStream& str) const +{ + str << (mMethod != UNKNOWN ? getMethodName(mMethod) : mUnknownMethodName) << Symbols::SPACE; + mUri.encodeParsed(str); + str << Symbols::SPACE << mSipVersion; + return str; +} + +const Data& +RequestLine::errorContext() const +{ + static const Data reqLine("Request Line"); + return reqLine; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/RequestLine.hxx b/src/libs/resiprocate/resip/stack/RequestLine.hxx new file mode 100644 index 00000000..c173d14c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/RequestLine.hxx @@ -0,0 +1,105 @@ +#if !defined(RESIP_REQUESTLINE_HXX) +#define RESIP_REQUESTLINE_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/StartLine.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "resip/stack/Uri.hxx" + +namespace resip +{ + +/** + @ingroup sip_grammar + @brief Represents the "Request-Line" element in the RFC 3261 grammar. +*/ +class RequestLine : public StartLine +{ + public: + RequestLine(); + RequestLine(MethodTypes method, const Data& sipVersion = Symbols::DefaultSipVersion); + RequestLine(const HeaderFieldValue& hfv); + RequestLine(const char* buf, int len); + RequestLine(const RequestLine&); + RequestLine& operator=(const RequestLine&); + + virtual ~RequestLine(); + + const Uri& uri() const; + Uri& uri(); + + MethodTypes getMethod() const; + MethodTypes& method(); + MethodTypes method() const; + + Data& unknownMethodName(); + const Data& unknownMethodName() const; + const Data& getSipVersion() const; + + virtual void parse(ParseBuffer& pb); + virtual StartLine* clone() const; + virtual StartLine* clone(void* location) const; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual const Data& errorContext() const; + + private: + Uri mUri; + MethodTypes mMethod; + Data mUnknownMethodName; + Data mSipVersion; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Rlmi.cxx b/src/libs/resiprocate/resip/stack/Rlmi.cxx new file mode 100644 index 00000000..5cdefc8a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Rlmi.cxx @@ -0,0 +1,146 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Rlmi.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +bool +Rlmi::init() +{ + static ContentsFactory<Rlmi> factory; + (void)factory; + return true; +} + +Rlmi::Rlmi() + : Contents(getStaticType()) +{} + +Rlmi::Rlmi(const HeaderFieldValue& hfv, const Mime& contentsType) + : Contents(hfv, contentsType) +{ +} + +Rlmi::Rlmi(const Rlmi& rhs) + : Contents(rhs) +{ + mText = rhs.mText; +} + +Rlmi::~Rlmi() +{ +} + +Rlmi& +Rlmi::operator=(const Rlmi& rhs) +{ + if (this != &rhs) + { + mText = rhs.mText; + } + return *this; +} + +Contents* +Rlmi::clone() const +{ + return new Rlmi(*this); +} + +const Mime& +Rlmi::getStaticType() +{ + static Mime type("application","rlmi+xml"); + return type; +} + +EncodeStream& +Rlmi::encodeParsed(EncodeStream& str) const +{ + //DebugLog(<< "Rlmi::encodeParsed " << mText); + str << mText; + + return str; +} + +void +Rlmi::parse(ParseBuffer& pb) +{ + + const char* anchor = pb.position(); + pb.skipToEnd(); + pb.data(mText, anchor); +} + +const Data& +Rlmi::get() +{ + checkParsed(); + return mText; +} + +void +Rlmi::set(const Data& text) +{ + mText = text; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Rlmi.hxx b/src/libs/resiprocate/resip/stack/Rlmi.hxx new file mode 100644 index 00000000..ea002a63 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Rlmi.hxx @@ -0,0 +1,99 @@ +#if !defined(RESIP_RLMI_HXX) +#define RESIP_RLMI_HXX + +#include <vector> + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type for holding RLMI contents (MIME content-type application/rlmi+xml). +*/ +class Rlmi : public Contents +{ + public: + Rlmi(); + Rlmi(const HeaderFieldValue& hfv, const Mime& contentType); + Rlmi(const Rlmi& rhs); + virtual ~Rlmi(); + Rlmi& operator=(const Rlmi& rhs); + + /** @brief duplicate an Rlmi object + @return pointer to a new Rlmi object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType() ; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + // replace these with real interface + const Data& get(); + void set(const Data& text); + + static bool init(); + private: + // replace this with real structure + Data mText; +}; + +static bool invokeRlmiInit = Rlmi::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/RportParameter.cxx b/src/libs/resiprocate/resip/stack/RportParameter.cxx new file mode 100644 index 00000000..89fb59ca --- /dev/null +++ b/src/libs/resiprocate/resip/stack/RportParameter.cxx @@ -0,0 +1,127 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/RportParameter.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/Logger.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::SIP + +RportParameter::RportParameter(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators) + : Parameter(type), + mValue(0), + mHasValue(false) +{ + pb.skipWhitespace(); + if (!pb.eof() && *pb.position() == Symbols::EQUALS[0]) + { + mHasValue = true; + + pb.skipChar(); + pb.skipWhitespace(); + + // Catch the exception gracefully to handle seeing ;rport= + try + { + mValue = pb.integer(); + } + catch(BaseException& e ) + { + ErrLog(<<"Caught exception: "<< e); + mHasValue = false; + } + } +} + +RportParameter::RportParameter(ParameterTypes::Type type, int value) + : Parameter(type), + mValue(value), + mHasValue(true) +{ +} + +RportParameter::RportParameter(ParameterTypes::Type type) + : Parameter(type), + mValue(-1), + mHasValue(false) +{ +} + +Parameter* +RportParameter::clone() const +{ + return new RportParameter(*this); +} + +EncodeStream& +RportParameter::encode(EncodeStream& stream) const +{ + if (mHasValue || mValue > 0) + { + return stream << getName() << Symbols::EQUALS << mValue; + } + else + { + return stream << getName(); + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/RportParameter.hxx b/src/libs/resiprocate/resip/stack/RportParameter.hxx new file mode 100644 index 00000000..1f5eb35d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/RportParameter.hxx @@ -0,0 +1,106 @@ +#if !defined(RESIP_RPORTPARAMETER_HXX) +#define RESIP_RPORTPARAMETER_HXX + +#include <iosfwd> + +#include "resip/stack/ParameterTypeEnums.hxx" +#include "resip/stack/Parameter.hxx" +#include "rutil/PoolBase.hxx" + +namespace resip +{ + +class ParseBuffer; + +/** + @ingroup sip_grammar + + @brief Represents the "response-port" element of the SIP grammar + (as extended in RFC 3581). +*/ +class RportParameter : public Parameter +{ + public: + typedef RportParameter Type; + + RportParameter(ParameterTypes::Type, ParseBuffer& pb, const std::bitset<256>& terminators); + RportParameter(ParameterTypes::Type type, int value); + explicit RportParameter(ParameterTypes::Type type); + + static Parameter* decode(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators, + PoolBase* pool) + { + return new (pool) RportParameter(type, pb, terminators); + } + + int& port() {return mValue;} + int port() const {return mValue;} + + bool hasValue() const { return mHasValue; } + + virtual EncodeStream& encode(EncodeStream& stream) const; + + virtual Parameter* clone() const; + + Type& value() { return *this; } + private: + + int mValue; + bool mHasValue; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/SERNonceHelper.cxx b/src/libs/resiprocate/resip/stack/SERNonceHelper.cxx new file mode 100644 index 00000000..e0a0938f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SERNonceHelper.cxx @@ -0,0 +1,117 @@ + +#include "resip/stack/SERNonceHelper.hxx" +#include "rutil/Random.hxx" +#include "resip/stack/Helper.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + + +/** + * SERNonceHelper implements the makeNonce function in the same way + * as SIP Express Router (SER) - http://www.iptel.org/ser + * + * To operate a farm/cluster of UASs/proxies, you must: + * a) make sure the clocks are sychronized (using ntpd for instance) + * b) use the same privateKey value on every instance of the application + * c) call Helper::setNonceHelper(mySERNonceHelper) to over-ride + * the default implementation of NonceHelper in the reSIProcate stack + * + */ + + +SERNonceHelper::SERNonceHelper(int serOffset) : serOffset(serOffset) +{ + //privateKey = Data("asdfklsadflkj"); + privateKey = Random::getRandomHex(24); +} + +SERNonceHelper::~SERNonceHelper() +{ +} + +void +SERNonceHelper::setPrivateKey(const Data& pprivateKey) +{ + this->privateKey = pprivateKey; +} + +Data +SERNonceHelper::makeNonce(const SipMessage& request, const Data& timestamp) +{ + char buf[8]; + Data md5buf(8, Data::Preallocate); + Data nonce(40, Data::Preallocate); + int ts = timestamp.convertInt() + serOffset; + Helper::integer2hex(buf, ts); + md5buf.append(buf, 8); + nonce.append(buf, 8); + md5buf += privateKey; + nonce += md5buf.md5(); + return nonce; +} + +NonceHelper::Nonce +SERNonceHelper::parseNonce(const Data& nonce) +{ + if(nonce.size() != 40) + { + return SERNonceHelper::Nonce(0); + } + const char *s = nonce.data(); + unsigned int ts = Helper::hex2integer(s) - serOffset; + return SERNonceHelper::Nonce(ts); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/stack/SERNonceHelper.hxx b/src/libs/resiprocate/resip/stack/SERNonceHelper.hxx new file mode 100644 index 00000000..591b4c82 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SERNonceHelper.hxx @@ -0,0 +1,96 @@ +#if !defined(RESIP_BASICNONCEHELPER_HXX) +#define RESIP_BASICNONCEHELPER_HXX + +#include "resip/stack/NonceHelper.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Data.hxx" + +/** + * SERNonceHelper implements the makeNonce function in the same way + * as SIP Express Router (SER) - http://www.iptel.org/ser + * + * To operate a farm/cluster of UASs/proxies, you must: + * a) make sure the clocks are sychronized (using ntpd for instance) + * b) use the same privateKey value on every instance of the application + * c) call Helper::setNonceHelper(mySERNonceHelper) to over-ride + * the default implementation of NonceHelper in the reSIProcate stack + * + */ + +namespace resip +{ + +class SERNonceHelper : public NonceHelper { + + private: + Data privateKey; + // SER puts the expiry time in the nonce, while the reSIProcate stack + // expects to work with the creation time of the nonce. Therefore, + // serOffset should be initialised to the duration for which a SER + // generated nonce is valid, in seconds. + int serOffset; + + public: + SERNonceHelper(int serOffset); + virtual ~SERNonceHelper(); + void setPrivateKey(const Data& privateKey); + Data makeNonce(const SipMessage& request, const Data& timestamp); + Nonce parseNonce(const Data& nonce); + +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Aor.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Aor.obj new file mode 100644 index 00000000..752e4d78 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Aor.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ApiCheck.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ApiCheck.obj new file mode 100644 index 00000000..5054affc Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ApiCheck.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ApplicationSip.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ApplicationSip.obj new file mode 100644 index 00000000..a9d63c61 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ApplicationSip.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Auth.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Auth.obj new file mode 100644 index 00000000..22bfd9ff Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Auth.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/BasicNonceHelper.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/BasicNonceHelper.obj new file mode 100644 index 00000000..86853ec2 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/BasicNonceHelper.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/BranchParameter.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/BranchParameter.obj new file mode 100644 index 00000000..5d21f3d3 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/BranchParameter.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/CSeqCategory.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/CSeqCategory.obj new file mode 100644 index 00000000..5adbd7dc Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/CSeqCategory.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/CallId.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/CallId.obj new file mode 100644 index 00000000..66968184 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/CallId.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Compression.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Compression.obj new file mode 100644 index 00000000..7dda2ef9 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Compression.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Connection.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Connection.obj new file mode 100644 index 00000000..f1b2898d Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Connection.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ConnectionBase.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ConnectionBase.obj new file mode 100644 index 00000000..27db1111 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ConnectionBase.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ConnectionManager.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ConnectionManager.obj new file mode 100644 index 00000000..11e4a76d Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ConnectionManager.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Contents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Contents.obj new file mode 100644 index 00000000..798c8a0a Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Contents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ContentsFactoryBase.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ContentsFactoryBase.obj new file mode 100644 index 00000000..e6278b45 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ContentsFactoryBase.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/CpimContents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/CpimContents.obj new file mode 100644 index 00000000..03bf8cda Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/CpimContents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/DataParameter.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/DataParameter.obj new file mode 100644 index 00000000..f51e22ed Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/DataParameter.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/DateCategory.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/DateCategory.obj new file mode 100644 index 00000000..0a042c2c Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/DateCategory.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/DeprecatedDialog.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/DeprecatedDialog.obj new file mode 100644 index 00000000..5220599e Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/DeprecatedDialog.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/DnsInterface.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/DnsInterface.obj new file mode 100644 index 00000000..f79209d1 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/DnsInterface.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/DnsResult.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/DnsResult.obj new file mode 100644 index 00000000..f45f6c66 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/DnsResult.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/DtlsMessage.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/DtlsMessage.obj new file mode 100644 index 00000000..1c868e7b Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/DtlsMessage.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/DtlsTransport.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/DtlsTransport.obj new file mode 100644 index 00000000..7a0d9ca7 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/DtlsTransport.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Embedded.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Embedded.obj new file mode 100644 index 00000000..41cd2f98 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Embedded.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/EventStackThread.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/EventStackThread.obj new file mode 100644 index 00000000..a0774bc0 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/EventStackThread.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ExistsOrDataParameter.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ExistsOrDataParameter.obj new file mode 100644 index 00000000..69e3e713 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ExistsOrDataParameter.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ExistsParameter.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ExistsParameter.obj new file mode 100644 index 00000000..5a592c7d Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ExistsParameter.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ExpiresCategory.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ExpiresCategory.obj new file mode 100644 index 00000000..42cef78f Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ExpiresCategory.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ExtensionHeader.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ExtensionHeader.obj new file mode 100644 index 00000000..66c98f9b Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ExtensionHeader.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ExtensionParameter.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ExtensionParameter.obj new file mode 100644 index 00000000..ba820772 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ExtensionParameter.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ExternalBodyContents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ExternalBodyContents.obj new file mode 100644 index 00000000..210534c0 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ExternalBodyContents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/GenericContents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/GenericContents.obj new file mode 100644 index 00000000..f73d047c Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/GenericContents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/GenericUri.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/GenericUri.obj new file mode 100644 index 00000000..a2642d40 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/GenericUri.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/HeaderFieldValue.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/HeaderFieldValue.obj new file mode 100644 index 00000000..6783ddac Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/HeaderFieldValue.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/HeaderFieldValueList.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/HeaderFieldValueList.obj new file mode 100644 index 00000000..5e82c1c9 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/HeaderFieldValueList.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/HeaderHash.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/HeaderHash.obj new file mode 100644 index 00000000..a74ccf0e Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/HeaderHash.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/HeaderTypes.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/HeaderTypes.obj new file mode 100644 index 00000000..70fca6d4 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/HeaderTypes.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Headers.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Headers.obj new file mode 100644 index 00000000..6dc701d9 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Headers.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Helper.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Helper.obj new file mode 100644 index 00000000..df35df6e Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Helper.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/IntegerCategory.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/IntegerCategory.obj new file mode 100644 index 00000000..7cc32aa7 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/IntegerCategory.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/IntegerParameter.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/IntegerParameter.obj new file mode 100644 index 00000000..f7abeee0 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/IntegerParameter.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/InternalTransport.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/InternalTransport.obj new file mode 100644 index 00000000..1509228f Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/InternalTransport.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/InteropHelper.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/InteropHelper.obj new file mode 100644 index 00000000..cc363a75 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/InteropHelper.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/InterruptableStackThread.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/InterruptableStackThread.obj new file mode 100644 index 00000000..63bfcfc3 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/InterruptableStackThread.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/InvalidContents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/InvalidContents.obj new file mode 100644 index 00000000..40ac57b8 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/InvalidContents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/KeepAliveMessage.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/KeepAliveMessage.obj new file mode 100644 index 00000000..d58f349d Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/KeepAliveMessage.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/LazyParser.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/LazyParser.obj new file mode 100644 index 00000000..9c3ab6f7 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/LazyParser.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Message.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Message.obj new file mode 100644 index 00000000..72e2b0a7 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Message.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/MessageFilterRule.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/MessageFilterRule.obj new file mode 100644 index 00000000..18985c9b Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/MessageFilterRule.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/MessageWaitingContents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/MessageWaitingContents.obj new file mode 100644 index 00000000..135b0fcd Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/MessageWaitingContents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/MethodHash.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/MethodHash.obj new file mode 100644 index 00000000..d154243e Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/MethodHash.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/MethodTypes.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/MethodTypes.obj new file mode 100644 index 00000000..7cd04ea2 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/MethodTypes.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Mime.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Mime.obj new file mode 100644 index 00000000..a545d1a9 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Mime.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/MsgHeaderScanner.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/MsgHeaderScanner.obj new file mode 100644 index 00000000..3455224c Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/MsgHeaderScanner.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/MultipartAlternativeContents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/MultipartAlternativeContents.obj new file mode 100644 index 00000000..7d4b1777 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/MultipartAlternativeContents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/MultipartMixedContents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/MultipartMixedContents.obj new file mode 100644 index 00000000..1dad10b3 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/MultipartMixedContents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/MultipartRelatedContents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/MultipartRelatedContents.obj new file mode 100644 index 00000000..24b3bff2 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/MultipartRelatedContents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/MultipartSignedContents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/MultipartSignedContents.obj new file mode 100644 index 00000000..38db0e04 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/MultipartSignedContents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/NameAddr.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/NameAddr.obj new file mode 100644 index 00000000..de335d36 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/NameAddr.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/NonceHelper.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/NonceHelper.obj new file mode 100644 index 00000000..2e14f471 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/NonceHelper.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/OctetContents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/OctetContents.obj new file mode 100644 index 00000000..59d2d232 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/OctetContents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Parameter.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Parameter.obj new file mode 100644 index 00000000..1109d1b5 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Parameter.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ParameterHash.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ParameterHash.obj new file mode 100644 index 00000000..ed7d1d8c Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ParameterHash.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ParameterTypes.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ParameterTypes.obj new file mode 100644 index 00000000..3f383a04 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ParameterTypes.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ParserCategories.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ParserCategories.obj new file mode 100644 index 00000000..4501da96 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ParserCategories.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ParserCategory.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ParserCategory.obj new file mode 100644 index 00000000..ceffb4ed Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ParserCategory.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/ParserContainerBase.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/ParserContainerBase.obj new file mode 100644 index 00000000..5b1c6bd1 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/ParserContainerBase.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Pidf.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Pidf.obj new file mode 100644 index 00000000..afb766bf Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Pidf.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Pkcs7Contents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Pkcs7Contents.obj new file mode 100644 index 00000000..bf0aab4a Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Pkcs7Contents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Pkcs8Contents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Pkcs8Contents.obj new file mode 100644 index 00000000..e32728fe Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Pkcs8Contents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/PlainContents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/PlainContents.obj new file mode 100644 index 00000000..169949c6 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/PlainContents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/PrivacyCategory.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/PrivacyCategory.obj new file mode 100644 index 00000000..82dc8b23 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/PrivacyCategory.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/QValue.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/QValue.obj new file mode 100644 index 00000000..eb4e9ed5 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/QValue.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/QValueParameter.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/QValueParameter.obj new file mode 100644 index 00000000..164dacc4 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/QValueParameter.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/QuotedDataParameter.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/QuotedDataParameter.obj new file mode 100644 index 00000000..8f4d026c Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/QuotedDataParameter.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/RAckCategory.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/RAckCategory.obj new file mode 100644 index 00000000..059e3279 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/RAckCategory.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/RequestLine.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/RequestLine.obj new file mode 100644 index 00000000..bae53193 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/RequestLine.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Rlmi.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Rlmi.obj new file mode 100644 index 00000000..202f1a1a Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Rlmi.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/RportParameter.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/RportParameter.obj new file mode 100644 index 00000000..9211c0a6 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/RportParameter.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/SERNonceHelper.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/SERNonceHelper.obj new file mode 100644 index 00000000..0cd56364 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/SERNonceHelper.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/SdpContents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/SdpContents.obj new file mode 100644 index 00000000..21ea7dd3 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/SdpContents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Security.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Security.obj new file mode 100644 index 00000000..f53a7f47 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Security.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/SecurityAttributes.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/SecurityAttributes.obj new file mode 100644 index 00000000..6b6273eb Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/SecurityAttributes.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/SipFrag.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/SipFrag.obj new file mode 100644 index 00000000..cacc3ff2 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/SipFrag.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/SipMessage.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/SipMessage.obj new file mode 100644 index 00000000..72af96c2 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/SipMessage.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/SipStack.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/SipStack.obj new file mode 100644 index 00000000..a9136227 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/SipStack.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/StackThread.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/StackThread.obj new file mode 100644 index 00000000..f10a7f77 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/StackThread.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/StatelessHandler.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/StatelessHandler.obj new file mode 100644 index 00000000..6856003d Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/StatelessHandler.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/StatisticsHandler.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/StatisticsHandler.obj new file mode 100644 index 00000000..6a009747 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/StatisticsHandler.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/StatisticsManager.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/StatisticsManager.obj new file mode 100644 index 00000000..69394ea6 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/StatisticsManager.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/StatisticsMessage.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/StatisticsMessage.obj new file mode 100644 index 00000000..c8354260 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/StatisticsMessage.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/StatusLine.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/StatusLine.obj new file mode 100644 index 00000000..7d7228d8 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/StatusLine.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/StringCategory.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/StringCategory.obj new file mode 100644 index 00000000..86df2676 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/StringCategory.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Symbols.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Symbols.obj new file mode 100644 index 00000000..e3c5fd0b Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Symbols.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TcpBaseTransport.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TcpBaseTransport.obj new file mode 100644 index 00000000..e1056039 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TcpBaseTransport.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TcpConnection.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TcpConnection.obj new file mode 100644 index 00000000..050976a5 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TcpConnection.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TcpTransport.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TcpTransport.obj new file mode 100644 index 00000000..d1dda85a Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TcpTransport.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TimeAccumulate.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TimeAccumulate.obj new file mode 100644 index 00000000..7512d262 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TimeAccumulate.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TimerMessage.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TimerMessage.obj new file mode 100644 index 00000000..2d74a7f9 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TimerMessage.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TimerQueue.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TimerQueue.obj new file mode 100644 index 00000000..be059784 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TimerQueue.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TlsConnection.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TlsConnection.obj new file mode 100644 index 00000000..13d2496f Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TlsConnection.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TlsTransport.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TlsTransport.obj new file mode 100644 index 00000000..42b8f82f Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TlsTransport.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Token.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Token.obj new file mode 100644 index 00000000..2f90077a Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Token.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionController.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionController.obj new file mode 100644 index 00000000..0626a9ef Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionController.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionMap.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionMap.obj new file mode 100644 index 00000000..7a5197b0 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionMap.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionState.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionState.obj new file mode 100644 index 00000000..0f8cba92 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionState.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionUser.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionUser.obj new file mode 100644 index 00000000..ce282714 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionUser.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionUserMessage.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionUserMessage.obj new file mode 100644 index 00000000..7f23406f Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TransactionUserMessage.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Transport.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Transport.obj new file mode 100644 index 00000000..13c10167 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Transport.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TransportFailure.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TransportFailure.obj new file mode 100644 index 00000000..a866abb6 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TransportFailure.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TransportSelector.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TransportSelector.obj new file mode 100644 index 00000000..436aa8dc Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TransportSelector.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TransportThread.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TransportThread.obj new file mode 100644 index 00000000..03e184fe Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TransportThread.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TuIM.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TuIM.obj new file mode 100644 index 00000000..3bbdf265 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TuIM.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TuSelector.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TuSelector.obj new file mode 100644 index 00000000..6bbeac06 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TuSelector.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Tuple.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Tuple.obj new file mode 100644 index 00000000..2ffa546c Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Tuple.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/TupleMarkManager.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/TupleMarkManager.obj new file mode 100644 index 00000000..6a875b64 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/TupleMarkManager.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/UInt32Category.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/UInt32Category.obj new file mode 100644 index 00000000..9f8459f9 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/UInt32Category.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/UInt32Parameter.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/UInt32Parameter.obj new file mode 100644 index 00000000..671fb861 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/UInt32Parameter.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/UdpTransport.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/UdpTransport.obj new file mode 100644 index 00000000..d4ee4fd5 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/UdpTransport.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/UnknownParameter.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/UnknownParameter.obj new file mode 100644 index 00000000..a7ae913e Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/UnknownParameter.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Uri.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Uri.obj new file mode 100644 index 00000000..cdc76924 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Uri.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/Via.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/Via.obj new file mode 100644 index 00000000..6bcf2679 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/Via.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/WarningCategory.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/WarningCategory.obj new file mode 100644 index 00000000..d8f4e6a2 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/WarningCategory.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/WinSecurity.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/WinSecurity.obj new file mode 100644 index 00000000..1a73557e Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/WinSecurity.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/X509Contents.obj b/src/libs/resiprocate/resip/stack/SSL-Debug/X509Contents.obj new file mode 100644 index 00000000..7e653571 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/X509Contents.obj differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.Build.CppClean.log b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.Build.CppClean.log new file mode 100644 index 00000000..88bcce52 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.Build.CppClean.log @@ -0,0 +1,133 @@ +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\vc120.pdb +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\resiprocate.lib +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\aor.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\apicheck.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\applicationsip.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\auth.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\basicnoncehelper.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\branchparameter.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\callid.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\compression.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\connection.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\connectionbase.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\connectionmanager.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\contents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\contentsfactorybase.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\cpimcontents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\cseqcategory.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\dataparameter.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\datecategory.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\deprecateddialog.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\dnsinterface.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\dnsresult.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\dtlsmessage.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\dtlstransport.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\embedded.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\eventstackthread.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\existsordataparameter.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\existsparameter.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\expirescategory.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\extensionheader.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\extensionparameter.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\externalbodycontents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\genericcontents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\genericuri.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\headerfieldvalue.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\headerfieldvaluelist.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\headerhash.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\headers.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\headertypes.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\helper.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\integercategory.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\integerparameter.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\internaltransport.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\interophelper.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\interruptablestackthread.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\invalidcontents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\keepalivemessage.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\lazyparser.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\message.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\messagefilterrule.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\messagewaitingcontents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\methodhash.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\methodtypes.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\mime.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\msgheaderscanner.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\multipartalternativecontents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\multipartmixedcontents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\multipartrelatedcontents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\multipartsignedcontents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\nameaddr.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\noncehelper.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\octetcontents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\parameter.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\parameterhash.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\parametertypes.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\parsercategories.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\parsercategory.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\parsercontainerbase.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\pidf.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\pkcs7contents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\pkcs8contents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\plaincontents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\privacycategory.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\quoteddataparameter.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\qvalue.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\qvalueparameter.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\rackcategory.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\requestline.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\rlmi.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\rportparameter.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\sdpcontents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\security.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\securityattributes.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\sernoncehelper.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\sipfrag.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\sipmessage.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\sipstack.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\stackthread.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\statelesshandler.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\statisticshandler.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\statisticsmanager.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\statisticsmessage.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\statusline.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\stringcategory.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\symbols.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\tcpbasetransport.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\tcpconnection.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\tcptransport.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\timeaccumulate.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\timermessage.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\timerqueue.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\tlsconnection.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\tlstransport.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\token.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\transactioncontroller.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\transactionmap.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\transactionstate.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\transactionuser.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\transactionusermessage.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\transport.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\transportfailure.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\transportselector.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\transportthread.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\tuim.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\tuple.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\tuplemarkmanager.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\tuselector.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\udptransport.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\uint32category.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\uint32parameter.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\unknownparameter.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\uri.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\via.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\warningcategory.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\winsecurity.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\x509contents.obj +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\vc120.idb +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\resiprocate.tlog\cl.command.1.tlog +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\resiprocate.tlog\cl.read.1.tlog +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\resiprocate.tlog\cl.write.1.tlog +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\resiprocate.tlog\lib-link.read.1.tlog +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\resiprocate.tlog\lib-link.write.1.tlog +c:\works\own\rtphone\libs\resiprocate\resip\stack\ssl-debug\resiprocate.tlog\lib.command.1.tlog diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.lib b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.lib new file mode 100644 index 00000000..8475a45e Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.lib differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/CL.read.1.tlog b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/CL.read.1.tlog new file mode 100644 index 00000000..7a93d968 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/CL.read.1.tlog differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/Lib-link.read.1.tlog b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/Lib-link.read.1.tlog new file mode 100644 index 00000000..a5dea751 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/Lib-link.read.1.tlog differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/Lib-link.write.1.tlog b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/Lib-link.write.1.tlog new file mode 100644 index 00000000..bc2ed450 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/Lib-link.write.1.tlog differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/cl.command.1.tlog b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/cl.command.1.tlog new file mode 100644 index 00000000..8a6f2573 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/cl.command.1.tlog differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/cl.write.1.tlog b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/cl.write.1.tlog new file mode 100644 index 00000000..4103c215 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/cl.write.1.tlog differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/lib.command.1.tlog b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/lib.command.1.tlog new file mode 100644 index 00000000..850a6b47 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/lib.command.1.tlog differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/resiprocate.lastbuildstate b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/resiprocate.lastbuildstate new file mode 100644 index 00000000..9849a2df --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate.tlog/resiprocate.lastbuildstate @@ -0,0 +1,2 @@ +#TargetFrameworkVersion=v4.0:PlatformToolSet=v120:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit +SSL-Debug|Win32|C:\works\own\rtphone\| diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate_9_0.log b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate_9_0.log new file mode 100644 index 00000000..50a5126c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SSL-Debug/resiprocate_9_0.log @@ -0,0 +1,263 @@ +Build started 10/22/2015 4:21:14 PM. + 1>Project "C:\works\own\rtphone\Libs\resiprocate\resip\stack\resiprocate_9_0.vcxproj" on node 2 (Rebuild target(s)). + 1>ClCompile: + C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\CL.exe /c /IC:\works\own\rtphone\Libs\resiprocate\resip\stack\../../contrib/ares /IC:\works\own\rtphone\Libs\resiprocate\resip\stack\../ /IC:\works\own\rtphone\Libs\resiprocate\resip\stack\../../ /IC:\works\own\rtphone\Libs\resiprocate\resip\stack\../../../openssl/include /ZI /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D _LIB /D LEAK_CHECK /D USE_SSL /D USE_ARES /D USE_IPV6 /D USE_DTLS /D _VC80_UPGRADE=0x0710 /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /GR /Fo"SSL-Debug\\" /Fd"SSL-Debug\vc120.pdb" /Gd /TP /analyze- /errorReport:prompt /Zm300 /MP Aor.cxx ApiCheck.cxx ApplicationSip.cxx Auth.cxx BasicNonceHelper.cxx BranchParameter.cxx CallId.cxx Compression.cxx Connection.cxx ConnectionBase.cxx ConnectionManager.cxx Contents.cxx ContentsFactoryBase.cxx CpimContents.cxx CSeqCategory.cxx DataParameter.cxx DateCategory.cxx DeprecatedDialog.cxx DnsInterface.cxx DnsResult.cxx DtlsMessage.cxx ssl\DtlsTransport.cxx Embedded.cxx EventStackThread.cxx ExistsOrDataParameter.cxx ExistsParameter.cxx ExpiresCategory.cxx ExtensionHeader.cxx ExtensionParameter.cxx ExternalBodyContents.cxx GenericContents.cxx GenericUri.cxx HeaderFieldValue.cxx HeaderFieldValueList.cxx HeaderHash.cxx Headers.cxx HeaderTypes.cxx Helper.cxx IntegerCategory.cxx IntegerParameter.cxx InternalTransport.cxx InteropHelper.cxx InterruptableStackThread.cxx InvalidContents.cxx KeepAliveMessage.cxx LazyParser.cxx Message.cxx MessageFilterRule.cxx MessageWaitingContents.cxx MethodHash.cxx MethodTypes.cxx Mime.cxx MsgHeaderScanner.cxx MultipartAlternativeContents.cxx MultipartMixedContents.cxx MultipartRelatedContents.cxx MultipartSignedContents.cxx NameAddr.cxx NonceHelper.cxx OctetContents.cxx Parameter.cxx ParameterHash.cxx ParameterTypes.cxx ParserCategories.cxx ParserCategory.cxx ParserContainerBase.cxx Pidf.cxx Pkcs7Contents.cxx Pkcs8Contents.cxx PlainContents.cxx PrivacyCategory.cxx QuotedDataParameter.cxx QValue.cxx QValueParameter.cxx RAckCategory.cxx RequestLine.cxx Rlmi.cxx RportParameter.cxx SdpContents.cxx ssl\Security.cxx SecurityAttributes.cxx SERNonceHelper.cxx SipFrag.cxx SipMessage.cxx SipStack.cxx StackThread.cxx StatelessHandler.cxx StatisticsHandler.cxx StatisticsManager.cxx StatisticsMessage.cxx StatusLine.cxx StringCategory.cxx Symbols.cxx TcpBaseTransport.cxx TcpConnection.cxx TcpTransport.cxx TimeAccumulate.cxx TimerMessage.cxx TimerQueue.cxx ssl\TlsConnection.cxx ssl\TlsTransport.cxx Token.cxx TransactionController.cxx TransactionMap.cxx TransactionState.cxx TransactionUser.cxx TransactionUserMessage.cxx Transport.cxx TransportFailure.cxx TransportSelector.cxx TransportThread.cxx TuIM.cxx Tuple.cxx TupleMarkManager.cxx TuSelector.cxx UdpTransport.cxx UInt32Category.cxx UInt32Parameter.cxx UnknownParameter.cxx Uri.cxx Via.cxx WarningCategory.cxx ssl\WinSecurity.cxx X509Contents.cxx + Aor.cxx + ApiCheck.cxx + ApplicationSip.cxx + Auth.cxx + BasicNonceHelper.cxx + BranchParameter.cxx + CallId.cxx + Compression.cxx + Connection.cxx + ConnectionBase.cxx + ConnectionManager.cxx + Contents.cxx + 1>c:\works\own\rtphone\libs\resiprocate\resip\stack\connectionbase.cxx(406): warning C4244: 'argument' : conversion from 'UInt32' to 'UInt16', possible loss of data + 1>c:\works\own\rtphone\libs\resiprocate\resip\stack\connectionbase.cxx(481): warning C4244: 'argument' : conversion from 'UInt32' to 'UInt16', possible loss of data + ContentsFactoryBase.cxx + CpimContents.cxx + CSeqCategory.cxx + DataParameter.cxx + DateCategory.cxx + DeprecatedDialog.cxx + DnsInterface.cxx + DnsResult.cxx + DtlsMessage.cxx + DtlsTransport.cxx + Embedded.cxx + EventStackThread.cxx + ExistsOrDataParameter.cxx + ExistsParameter.cxx + ExpiresCategory.cxx + ExtensionHeader.cxx + ExtensionParameter.cxx + ExternalBodyContents.cxx + GenericContents.cxx + GenericUri.cxx + HeaderFieldValue.cxx + HeaderFieldValueList.cxx + HeaderHash.cxx + Headers.cxx + HeaderTypes.cxx + Helper.cxx + IntegerCategory.cxx + IntegerParameter.cxx + InternalTransport.cxx + InteropHelper.cxx + InterruptableStackThread.cxx + InvalidContents.cxx + KeepAliveMessage.cxx + LazyParser.cxx + Message.cxx + MessageFilterRule.cxx + MessageWaitingContents.cxx + MethodHash.cxx + MethodTypes.cxx + Mime.cxx + MsgHeaderScanner.cxx + MultipartAlternativeContents.cxx + MultipartMixedContents.cxx + MultipartRelatedContents.cxx + MultipartSignedContents.cxx + NameAddr.cxx + NonceHelper.cxx + OctetContents.cxx + Parameter.cxx + ParameterHash.cxx + ParameterTypes.cxx + ParserCategories.cxx + ParserCategory.cxx + ParserContainerBase.cxx + Pidf.cxx + Pkcs7Contents.cxx + Pkcs8Contents.cxx + PlainContents.cxx + PrivacyCategory.cxx + QuotedDataParameter.cxx + QValue.cxx + QValueParameter.cxx + RAckCategory.cxx + RequestLine.cxx + Rlmi.cxx + RportParameter.cxx + SdpContents.cxx + Security.cxx + SecurityAttributes.cxx + SERNonceHelper.cxx + SipFrag.cxx + SipMessage.cxx + SipStack.cxx + StackThread.cxx + StatelessHandler.cxx + StatisticsHandler.cxx + StatisticsManager.cxx + StatisticsMessage.cxx + StatusLine.cxx + StringCategory.cxx + Symbols.cxx + TcpBaseTransport.cxx + TcpConnection.cxx + TcpTransport.cxx + TimeAccumulate.cxx + TimerMessage.cxx + TimerQueue.cxx + TlsConnection.cxx + TlsTransport.cxx + Token.cxx + TransactionController.cxx + TransactionMap.cxx + TransactionState.cxx + TransactionUser.cxx + TransactionUserMessage.cxx + Transport.cxx + TransportFailure.cxx + TransportSelector.cxx + TransportThread.cxx + TuIM.cxx + Tuple.cxx + TupleMarkManager.cxx + TuSelector.cxx + UdpTransport.cxx + UInt32Category.cxx + 1>c:\works\own\rtphone\libs\resiprocate\resip\stack\udptransport.cxx(643): warning C4244: 'argument' : conversion from 'UInt32' to 'UInt16', possible loss of data + UInt32Parameter.cxx + UnknownParameter.cxx + Uri.cxx + Via.cxx + WarningCategory.cxx + WinSecurity.cxx + X509Contents.cxx + Lib: + C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\Lib.exe /OUT:"SSL-Debug\resiprocate.lib" /NOLOGO "SSL-Debug\Aor.obj" + "SSL-Debug\ApiCheck.obj" + "SSL-Debug\ApplicationSip.obj" + "SSL-Debug\Auth.obj" + "SSL-Debug\BasicNonceHelper.obj" + "SSL-Debug\BranchParameter.obj" + "SSL-Debug\CallId.obj" + "SSL-Debug\Compression.obj" + "SSL-Debug\Connection.obj" + "SSL-Debug\ConnectionBase.obj" + "SSL-Debug\ConnectionManager.obj" + "SSL-Debug\Contents.obj" + "SSL-Debug\ContentsFactoryBase.obj" + "SSL-Debug\CpimContents.obj" + "SSL-Debug\CSeqCategory.obj" + "SSL-Debug\DataParameter.obj" + "SSL-Debug\DateCategory.obj" + "SSL-Debug\DeprecatedDialog.obj" + "SSL-Debug\DnsInterface.obj" + "SSL-Debug\DnsResult.obj" + "SSL-Debug\DtlsMessage.obj" + "SSL-Debug\DtlsTransport.obj" + "SSL-Debug\Embedded.obj" + "SSL-Debug\EventStackThread.obj" + "SSL-Debug\ExistsOrDataParameter.obj" + "SSL-Debug\ExistsParameter.obj" + "SSL-Debug\ExpiresCategory.obj" + "SSL-Debug\ExtensionHeader.obj" + "SSL-Debug\ExtensionParameter.obj" + "SSL-Debug\ExternalBodyContents.obj" + "SSL-Debug\GenericContents.obj" + "SSL-Debug\GenericUri.obj" + "SSL-Debug\HeaderFieldValue.obj" + "SSL-Debug\HeaderFieldValueList.obj" + "SSL-Debug\HeaderHash.obj" + "SSL-Debug\Headers.obj" + "SSL-Debug\HeaderTypes.obj" + "SSL-Debug\Helper.obj" + "SSL-Debug\IntegerCategory.obj" + "SSL-Debug\IntegerParameter.obj" + "SSL-Debug\InternalTransport.obj" + "SSL-Debug\InteropHelper.obj" + "SSL-Debug\InterruptableStackThread.obj" + "SSL-Debug\InvalidContents.obj" + "SSL-Debug\KeepAliveMessage.obj" + "SSL-Debug\LazyParser.obj" + "SSL-Debug\Message.obj" + "SSL-Debug\MessageFilterRule.obj" + "SSL-Debug\MessageWaitingContents.obj" + "SSL-Debug\MethodHash.obj" + "SSL-Debug\MethodTypes.obj" + "SSL-Debug\Mime.obj" + "SSL-Debug\MsgHeaderScanner.obj" + "SSL-Debug\MultipartAlternativeContents.obj" + "SSL-Debug\MultipartMixedContents.obj" + "SSL-Debug\MultipartRelatedContents.obj" + "SSL-Debug\MultipartSignedContents.obj" + "SSL-Debug\NameAddr.obj" + "SSL-Debug\NonceHelper.obj" + "SSL-Debug\OctetContents.obj" + "SSL-Debug\Parameter.obj" + "SSL-Debug\ParameterHash.obj" + "SSL-Debug\ParameterTypes.obj" + "SSL-Debug\ParserCategories.obj" + "SSL-Debug\ParserCategory.obj" + "SSL-Debug\ParserContainerBase.obj" + "SSL-Debug\Pidf.obj" + "SSL-Debug\Pkcs7Contents.obj" + "SSL-Debug\Pkcs8Contents.obj" + "SSL-Debug\PlainContents.obj" + "SSL-Debug\PrivacyCategory.obj" + "SSL-Debug\QuotedDataParameter.obj" + "SSL-Debug\QValue.obj" + "SSL-Debug\QValueParameter.obj" + "SSL-Debug\RAckCategory.obj" + "SSL-Debug\RequestLine.obj" + "SSL-Debug\Rlmi.obj" + "SSL-Debug\RportParameter.obj" + "SSL-Debug\SdpContents.obj" + "SSL-Debug\Security.obj" + "SSL-Debug\SecurityAttributes.obj" + "SSL-Debug\SERNonceHelper.obj" + "SSL-Debug\SipFrag.obj" + "SSL-Debug\SipMessage.obj" + "SSL-Debug\SipStack.obj" + "SSL-Debug\StackThread.obj" + "SSL-Debug\StatelessHandler.obj" + "SSL-Debug\StatisticsHandler.obj" + "SSL-Debug\StatisticsManager.obj" + "SSL-Debug\StatisticsMessage.obj" + "SSL-Debug\StatusLine.obj" + "SSL-Debug\StringCategory.obj" + "SSL-Debug\Symbols.obj" + "SSL-Debug\TcpBaseTransport.obj" + "SSL-Debug\TcpConnection.obj" + "SSL-Debug\TcpTransport.obj" + "SSL-Debug\TimeAccumulate.obj" + "SSL-Debug\TimerMessage.obj" + "SSL-Debug\TimerQueue.obj" + "SSL-Debug\TlsConnection.obj" + "SSL-Debug\TlsTransport.obj" + "SSL-Debug\Token.obj" + "SSL-Debug\TransactionController.obj" + "SSL-Debug\TransactionMap.obj" + "SSL-Debug\TransactionState.obj" + "SSL-Debug\TransactionUser.obj" + "SSL-Debug\TransactionUserMessage.obj" + "SSL-Debug\Transport.obj" + "SSL-Debug\TransportFailure.obj" + "SSL-Debug\TransportSelector.obj" + "SSL-Debug\TransportThread.obj" + "SSL-Debug\TuIM.obj" + "SSL-Debug\Tuple.obj" + "SSL-Debug\TupleMarkManager.obj" + "SSL-Debug\TuSelector.obj" + "SSL-Debug\UdpTransport.obj" + "SSL-Debug\UInt32Category.obj" + "SSL-Debug\UInt32Parameter.obj" + "SSL-Debug\UnknownParameter.obj" + "SSL-Debug\Uri.obj" + "SSL-Debug\Via.obj" + "SSL-Debug\WarningCategory.obj" + "SSL-Debug\WinSecurity.obj" + "SSL-Debug\X509Contents.obj" + 1>HeaderTypes.obj : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library + resiprocate_9_0.vcxproj -> C:\works\own\rtphone\Libs\resiprocate\resip\stack\SSL-Debug\resiprocate.lib + 1>Done Building Project "C:\works\own\rtphone\Libs\resiprocate\resip\stack\resiprocate_9_0.vcxproj" (Rebuild target(s)). + +Build succeeded. + +Time Elapsed 00:05:10.15 diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/vc120.idb b/src/libs/resiprocate/resip/stack/SSL-Debug/vc120.idb new file mode 100644 index 00000000..d3f6f3bb Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/vc120.idb differ diff --git a/src/libs/resiprocate/resip/stack/SSL-Debug/vc120.pdb b/src/libs/resiprocate/resip/stack/SSL-Debug/vc120.pdb new file mode 100644 index 00000000..25f21de3 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/SSL-Debug/vc120.pdb differ diff --git a/src/libs/resiprocate/resip/stack/SdpContents.cxx b/src/libs/resiprocate/resip/stack/SdpContents.cxx new file mode 100644 index 00000000..f2b3d4de --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SdpContents.cxx @@ -0,0 +1,1960 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/SdpContents.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/DataStream.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::SDP + +using namespace resip; +using namespace std; + +const SdpContents SdpContents::Empty; + +bool +SdpContents::init() +{ + static ContentsFactory<SdpContents> factory; + (void)factory; + return true; +} + +const char* NetworkType[] = {"???", "IP4", "IP6"}; + +static const Data rtpmap("rtpmap"); +static const Data fmtp("fmtp"); + +// RFC2327 6. page 9 +// "parsers should be tolerant and accept records terminated with a single +// newline character" +void skipEol(ParseBuffer& pb) +{ + while(!pb.eof() && (*pb.position() == Symbols::SPACE[0] || + *pb.position() == Symbols::TAB[0])) + { + pb.skipChar(); + } + + if (*pb.position() == Symbols::LF[0]) + { + pb.skipChar(); + } + else + { + // allow extra 0x0d bytes. + while(*pb.position() == Symbols::CR[0]) + { + pb.skipChar(); + } + pb.skipChar(Symbols::LF[0]); + } + +} + +AttributeHelper::AttributeHelper(const AttributeHelper& rhs) + : mAttributeList(rhs.mAttributeList), + mAttributes(rhs.mAttributes) +{ +} + +AttributeHelper::AttributeHelper() +{ +} + +AttributeHelper& +AttributeHelper::operator=(const AttributeHelper& rhs) +{ + if (this != &rhs) + { + mAttributeList = rhs.mAttributeList; + mAttributes = rhs.mAttributes; + } + return *this; +} + +bool +AttributeHelper::exists(const Data& key) const +{ + return mAttributes.find(key) != mAttributes.end(); +} + +const list<Data>& +AttributeHelper::getValues(const Data& key) const +{ + if (!exists(key)) + { + static const list<Data> emptyList; + return emptyList; + } + return mAttributes.find(key)->second; +} + +EncodeStream& +AttributeHelper::encode(EncodeStream& s) const +{ + for (std::list<std::pair<Data, Data> >::const_iterator i = mAttributeList.begin(); + i != mAttributeList.end(); ++i) + { + s << "a=" << i->first; + if (!i->second.empty()) + { + s << Symbols::COLON[0] << i->second; + } + s << Symbols::CRLF; + } + return s; +} + +void +AttributeHelper::parse(ParseBuffer& pb) +{ + while (!pb.eof() && *pb.position() == 'a') + { + Data key; + Data value; + + pb.skipChar('a'); + const char* anchor = pb.skipChar(Symbols::EQUALS[0]); + pb.skipToOneOf(Symbols::COLON, Symbols::CRLF); + pb.data(key, anchor); + if (!pb.eof() && *pb.position() == Symbols::COLON[0]) + { + anchor = pb.skipChar(Symbols::COLON[0]); + pb.skipToOneOf(Symbols::CRLF); + pb.data(value, anchor); + } + + if(!pb.eof()) skipEol(pb); + + mAttributeList.push_back(std::make_pair(key, value)); + mAttributes[key].push_back(value); + } +} + +void +AttributeHelper::addAttribute(const Data& key, const Data& value) +{ + mAttributeList.push_back(std::make_pair(key, value)); + mAttributes[key].push_back(value); +} + +void +AttributeHelper::clearAttribute(const Data& key) +{ + for (std::list<std::pair<Data, Data> >::iterator i = mAttributeList.begin(); + i != mAttributeList.end(); ) + { + std::list<std::pair<Data, Data> >::iterator j = i++; + if (j->first == key) + { + mAttributeList.erase(j); + } + } + mAttributes.erase(key); +} + +SdpContents::SdpContents() : Contents(getStaticType()) +{ +} + +SdpContents::SdpContents(const HeaderFieldValue& hfv, const Mime& contentTypes) + : Contents(hfv, contentTypes) +{ +} + +//SdpContents::SdpContents(const SdpContents& rhs) +// : Contents(rhs), +// mSession(rhs.mSession) +//{ +//} + +SdpContents::~SdpContents() +{ +} + + +SdpContents& +SdpContents::operator=(const SdpContents& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + mSession = rhs.mSession; + } + return *this; +} + +Contents* +SdpContents::clone() const +{ + return new SdpContents(*this); +} + +void +SdpContents::parse(ParseBuffer& pb) +{ + mSession.parse(pb); +} + +EncodeStream& +SdpContents::encodeParsed(EncodeStream& s) const +{ + mSession.encode(s); + return s; +} + +const Mime& +SdpContents::getStaticType() +{ + static Mime type("application", "sdp"); + return type; +} + +static Data nullOrigin("0.0.0.0"); + +SdpContents::Session::Origin::Origin() + : mUser(), + mSessionId(0), + mVersion(0), + mAddrType(IP4), + mAddress(nullOrigin) +{} + +SdpContents::Session::Origin::Origin(const Origin& rhs) + : mUser(rhs.mUser), + mSessionId(rhs.mSessionId), + mVersion(rhs.mVersion), + mAddrType(rhs.mAddrType), + mAddress(rhs.mAddress) +{ +} + +SdpContents::Session::Origin& +SdpContents::Session::Origin::operator=(const Origin& rhs) +{ + if (this != &rhs) + { + mUser = rhs.mUser; + mSessionId = rhs.mSessionId; + mVersion = rhs.mVersion; + mAddrType = rhs.mAddrType; + mAddress = rhs.mAddress; + } + return *this; +} + + +SdpContents::Session::Origin::Origin(const Data& user, + const UInt64& sessionId, + const UInt64& version, + AddrType addr, + const Data& address) + : mUser(user), + mSessionId(sessionId), + mVersion(version), + mAddrType(addr), + mAddress(address) +{} + +EncodeStream& +SdpContents::Session::Origin::encode(EncodeStream& s) const +{ + s << "o=" + << mUser << Symbols::SPACE[0] + << mSessionId << Symbols::SPACE[0] + << mVersion << Symbols::SPACE[0] + << "IN " + << NetworkType[mAddrType] << Symbols::SPACE[0] + << mAddress << Symbols::CRLF; + return s; +} + +void +SdpContents::Session::Origin::setAddress(const Data& host, AddrType addr) +{ + mAddress = host; + mAddrType = addr; +} + +void +SdpContents::Session::Origin::parse(ParseBuffer& pb) +{ + pb.skipChar('o'); + const char* anchor = pb.skipChar(Symbols::EQUALS[0]); + + pb.skipToChar(Symbols::SPACE[0]); + pb.data(mUser, anchor); + + anchor = pb.skipChar(Symbols::SPACE[0]); + try + { + mSessionId = pb.uInt64(); + } + catch(ParseException& e) + { + WarningLog(<< "Exception parsing origin sessionid: " << e); + } + pb.skipToChar(Symbols::SPACE[0]); + + anchor = pb.skipChar(Symbols::SPACE[0]); + try + { + mVersion = pb.uInt64(); + } + catch(ParseException& e) + { + WarningLog(<< "Exception parsing origin version: " << e); + } + pb.skipToChar(Symbols::SPACE[0]); + + pb.skipChar(Symbols::SPACE[0]); + pb.skipChar('I'); + pb.skipChar('N'); + + anchor = pb.skipChar(Symbols::SPACE[0]); + pb.skipToChar(Symbols::SPACE[0]); + Data addrType; + pb.data(addrType, anchor); + if (addrType == NetworkType[IP4]) + { + mAddrType = IP4; + } + else if (addrType == NetworkType[IP6]) + { + mAddrType = IP6; + } + else + { + mAddrType = static_cast<AddrType>(0); + } + + anchor = pb.skipChar(Symbols::SPACE[0]); + pb.skipToOneOf(Symbols::CRLF); + pb.data(mAddress, anchor); + + skipEol(pb); +} + +SdpContents::Session::Email::Email(const Data& address, + const Data& freeText) + : mAddress(address), + mFreeText(freeText) +{} + +SdpContents::Session::Email::Email(const Email& rhs) + : mAddress(rhs.mAddress), + mFreeText(rhs.mFreeText) +{} + +SdpContents::Session::Email& +SdpContents::Session::Email::operator=(const Email& rhs) +{ + if (this != &rhs) + { + mAddress = rhs.mAddress; + mFreeText = rhs.mFreeText; + } + return *this; +} + +EncodeStream& +SdpContents::Session::Email::encode(EncodeStream& s) const +{ + s << "e=" << mAddress; + if (!mFreeText.empty()) + { + s << Symbols::SPACE[0]; + s << Symbols::LPAREN[0] << mFreeText << Symbols::RPAREN[0]; + } + s << Symbols::CRLF; + + return s; +} + +// helper to parse email and phone numbers with display name +void parseEorP(ParseBuffer& pb, Data& eOrp, Data& freeText) +{ + // =mjh@isi.edu (Mark Handley) + // =mjh@isi.edu + // =Mark Handley <mjh@isi.edu> + // =<mjh@isi.edu> + + const char* anchor = pb.skipChar(Symbols::EQUALS[0]); + + pb.skipToOneOf("<(\n\r"); // find a left angle bracket "<", a left paren "(", or a CR + switch (*pb.position()) + { + case '\n': // Symbols::CR[0] + case '\r': // Symbols::LF[0] + // mjh@isi.edu + // ^ + pb.data(eOrp, anchor); + break; + + case '<': // Symbols::LA_QUOTE[0] + // Mark Handley <mjh@isi.edu> + // ^ + // <mjh@isi.edu> + // ^ + + pb.data(freeText, anchor); + anchor = pb.skipChar(); + pb.skipToEndQuote(Symbols::RA_QUOTE[0]); + pb.data(eOrp, anchor); + pb.skipChar(Symbols::RA_QUOTE[0]); + break; + + case '(': // Symbols::LPAREN[0] + // mjh@isi.edu (Mark Handley) + // ^ + + pb.data(eOrp, anchor); + anchor = pb.skipChar(); + pb.skipToEndQuote(Symbols::RPAREN[0]); + pb.data(freeText, anchor); + pb.skipChar(Symbols::RPAREN[0]); + break; + default: + assert(0); + } +} + +void +SdpContents::Session::Email::parse(ParseBuffer& pb) +{ + pb.skipChar('e'); + parseEorP(pb, mAddress, mFreeText); + skipEol(pb); +} + +SdpContents::Session::Phone::Phone(const Data& number, + const Data& freeText) + : mNumber(number), + mFreeText(freeText) +{} + +SdpContents::Session::Phone::Phone(const Phone& rhs) + : mNumber(rhs.mNumber), + mFreeText(rhs.mFreeText) +{} + +SdpContents::Session::Phone& +SdpContents::Session::Phone::operator=(const Phone& rhs) +{ + if (this != &rhs) + { + mNumber = rhs.mNumber; + mFreeText = rhs.mFreeText; + } + return *this; +} + +EncodeStream& +SdpContents::Session::Phone::encode(EncodeStream& s) const +{ + s << "p=" << mNumber; + if (!mFreeText.empty()) + { + s << Symbols::SPACE[0]; + s << Symbols::LPAREN[0] << mFreeText << Symbols::RPAREN[0]; + } + s << Symbols::CRLF; + + return s; +} + +void +SdpContents::Session::Phone::parse(ParseBuffer& pb) +{ + pb.skipChar('p'); + parseEorP(pb, mNumber, mFreeText); + skipEol(pb); +} + +SdpContents::Session::Connection::Connection(AddrType addType, + const Data& address, + unsigned long ttl) + : mAddrType(addType), + mAddress(address), + mTTL(ttl) +{} + +SdpContents::Session::Connection::Connection() + : mAddrType(IP4), + mAddress(), + mTTL(0) +{} + +SdpContents::Session::Connection::Connection(const Connection& rhs) + : mAddrType(rhs.mAddrType), + mAddress(rhs.mAddress), + mTTL(rhs.mTTL) +{ +} + +SdpContents::Session::Connection& +SdpContents::Session::Connection::operator=(const Connection& rhs) +{ + if (this != &rhs) + { + mAddrType = rhs.mAddrType; + mAddress = rhs.mAddress; + mTTL = rhs.mTTL; + } + return *this; +} + +EncodeStream& +SdpContents::Session::Connection::encode(EncodeStream& s) const +{ + s << "c=IN " + << NetworkType[mAddrType] << Symbols::SPACE[0] << mAddress; + + if (mTTL) + { + s << Symbols::SLASH[0] << mTTL; + } + s << Symbols::CRLF; + return s; +} + +void +SdpContents::Session::Connection::setAddress(const Data& host, AddrType addr) +{ + mAddress = host; + mAddrType = addr; +} + +void +SdpContents::Session::Connection::parse(ParseBuffer& pb) +{ + pb.skipChar('c'); + pb.skipChar(Symbols::EQUALS[0]); + pb.skipChar('I'); + pb.skipChar('N'); + + const char* anchor = pb.skipChar(Symbols::SPACE[0]); + pb.skipToChar(Symbols::SPACE[0]); + Data addrType; + pb.data(addrType, anchor); + if (addrType == NetworkType[IP4]) + { + mAddrType = IP4; + } + else if (addrType == NetworkType[IP6]) + { + mAddrType = IP6; + } + else + { + mAddrType = static_cast<AddrType>(0); + } + + anchor = pb.skipChar(); + pb.skipToOneOf(Symbols::SLASH, Symbols::CRLF); + pb.data(mAddress, anchor); + + mTTL = 0; + if (mAddrType == IP4 && !pb.eof() && *pb.position() == Symbols::SLASH[0]) + { + pb.skipChar(); + mTTL = pb.integer(); + } + + // multicast dealt with above this parser + if (!pb.eof() && *pb.position() != Symbols::SLASH[0]) + { + skipEol(pb); + } +} + +SdpContents::Session::Bandwidth::Bandwidth(const Data& modifier, + unsigned long kbPerSecond) + : mModifier(modifier), + mKbPerSecond(kbPerSecond) +{} + +SdpContents::Session::Bandwidth::Bandwidth(const Bandwidth& rhs) + : mModifier(rhs.mModifier), + mKbPerSecond(rhs.mKbPerSecond) +{} + +SdpContents::Session::Bandwidth& +SdpContents::Session::Bandwidth::operator=(const Bandwidth& rhs) +{ + if (this != &rhs) + { + mModifier = rhs.mModifier; + mKbPerSecond = rhs.mKbPerSecond; + } + return *this; +} + +EncodeStream& +SdpContents::Session::Bandwidth::encode(EncodeStream& s) const +{ + s << "b=" + << mModifier + << Symbols::COLON[0] << mKbPerSecond + << Symbols::CRLF; + return s; +} + +void +SdpContents::Session::Bandwidth::parse(ParseBuffer& pb) +{ + pb.skipChar('b'); + const char* anchor = pb.skipChar(Symbols::EQUALS[0]); + + pb.skipToOneOf(Symbols::COLON, Symbols::CRLF); + if (*pb.position() == Symbols::COLON[0]) + { + pb.data(mModifier, anchor); + + anchor = pb.skipChar(Symbols::COLON[0]); + mKbPerSecond = pb.integer(); + + skipEol(pb); + } + else + { + pb.fail(__FILE__, __LINE__); + } +} + +SdpContents::Session::Time::Time(unsigned long start, + unsigned long stop) + : mStart(start), + mStop(stop) +{} + +SdpContents::Session::Time::Time(const Time& rhs) + : mStart(rhs.mStart), + mStop(rhs.mStop) +{} + +SdpContents::Session::Time& +SdpContents::Session::Time::operator=(const Time& rhs) +{ + if (this != &rhs) + { + mStart = rhs.mStart; + mStop = rhs.mStop; + mRepeats = rhs.mRepeats; + } + return *this; +} + +EncodeStream& +SdpContents::Session::Time::encode(EncodeStream& s) const +{ + s << "t=" << mStart << Symbols::SPACE[0] + << mStop + << Symbols::CRLF; + + for (list<Repeat>::const_iterator i = mRepeats.begin(); + i != mRepeats.end(); ++i) + { + i->encode(s); + } + return s; +} + +void +SdpContents::Session::Time::parse(ParseBuffer& pb) +{ + pb.skipChar('t'); + pb.skipChar(Symbols::EQUALS[0]); + + mStart = pb.uInt32(); + pb.skipChar(Symbols::SPACE[0]); + mStop = pb.uInt32(); + + skipEol(pb); + + while (!pb.eof() && *pb.position() == 'r') + { + addRepeat(Repeat()); + mRepeats.back().parse(pb); + } +} + +void +SdpContents::Session::Time::addRepeat(const Repeat& repeat) +{ + mRepeats.push_back(repeat); +} + +SdpContents::Session::Time::Repeat::Repeat(unsigned long interval, + unsigned long duration, + list<int> offsets) + : mInterval(interval), + mDuration(duration), + mOffsets(offsets) +{} + +EncodeStream& +SdpContents::Session::Time::Repeat::encode(EncodeStream& s) const +{ + s << "r=" + << mInterval << Symbols::SPACE[0] + << mDuration << 's'; + for (list<int>::const_iterator i = mOffsets.begin(); + i != mOffsets.end(); ++i) + { + s << Symbols::SPACE[0] << *i << 's'; + } + + s << Symbols::CRLF; + return s; +} + +int +parseTypedTime(ParseBuffer& pb) +{ + int v = pb.integer(); + if (!pb.eof()) + { + switch (*pb.position()) + { + case 's' : + pb.skipChar(); + break; + case 'm' : + v *= 60; + pb.skipChar(); + break; + case 'h' : + v *= 3600; + pb.skipChar(); + break; + case 'd' : + v *= 3600*24; + pb.skipChar(); + } + } + return v; +} + +void +SdpContents::Session::Time::Repeat::parse(ParseBuffer& pb) +{ + pb.skipChar('r'); + pb.skipChar(Symbols::EQUALS[0]); + + mInterval = parseTypedTime(pb); + pb.skipChar(Symbols::SPACE[0]); + + mDuration = parseTypedTime(pb); + + while (!pb.eof() && *pb.position() != Symbols::CR[0]) + { + pb.skipChar(Symbols::SPACE[0]); + + mOffsets.push_back(parseTypedTime(pb)); + } + + skipEol(pb); +} + +SdpContents::Session::Timezones::Adjustment::Adjustment(unsigned long _time, + int _offset) + : time(_time), + offset(_offset) +{} + +SdpContents::Session::Timezones::Adjustment::Adjustment(const Adjustment& rhs) + : time(rhs.time), + offset(rhs.offset) +{} + +SdpContents::Session::Timezones::Adjustment& +SdpContents::Session::Timezones::Adjustment::operator=(const Adjustment& rhs) +{ + if (this != &rhs) + { + time = rhs.time; + offset = rhs.offset; + } + return *this; +} + +SdpContents::Session::Timezones::Timezones() + : mAdjustments() +{} + +SdpContents::Session::Timezones::Timezones(const Timezones& rhs) + : mAdjustments(rhs.mAdjustments) +{} + +SdpContents::Session::Timezones& +SdpContents::Session::Timezones::operator=(const Timezones& rhs) +{ + if (this != &rhs) + { + mAdjustments = rhs.mAdjustments; + } + return *this; +} + +EncodeStream& +SdpContents::Session::Timezones::encode(EncodeStream& s) const +{ + if (!mAdjustments.empty()) + { + s << "z="; + bool first = true; + for (list<Adjustment>::const_iterator i = mAdjustments.begin(); + i != mAdjustments.end(); ++i) + { + if (!first) + { + s << Symbols::SPACE[0]; + } + first = false; + s << i->time << Symbols::SPACE[0] + << i->offset << 's'; + } + + s << Symbols::CRLF; + } + return s; +} + +void +SdpContents::Session::Timezones::parse(ParseBuffer& pb) +{ + pb.skipChar('z'); + pb.skipChar(Symbols::EQUALS[0]); + + while (!pb.eof() && *pb.position() != Symbols::CR[0]) + { + Adjustment adj(0, 0); + adj.time = pb.integer(); + pb.skipChar(Symbols::SPACE[0]); + adj.offset = parseTypedTime(pb); + addAdjustment(adj); + + if (!pb.eof() && *pb.position() == Symbols::SPACE[0]) + { + pb.skipChar(); + } + } + + skipEol(pb); +} + +void +SdpContents::Session::Timezones::addAdjustment(const Adjustment& adjust) +{ + mAdjustments.push_back(adjust); +} + +SdpContents::Session::Encryption::Encryption() + : mMethod(NoEncryption), + mKey() +{} + +SdpContents::Session::Encryption::Encryption(const KeyType& method, + const Data& key) + : mMethod(method), + mKey(key) +{} + +SdpContents::Session::Encryption::Encryption(const Encryption& rhs) + : mMethod(rhs.mMethod), + mKey(rhs.mKey) +{} + +SdpContents::Session::Encryption& +SdpContents::Session::Encryption::operator=(const Encryption& rhs) +{ + if (this != &rhs) + { + mMethod = rhs.mMethod; + mKey = rhs.mKey; + } + return *this; +} + +const char* KeyTypes[] = {"????", "prompt", "clear", "base64", "uri"}; + +EncodeStream& +SdpContents::Session::Encryption::encode(EncodeStream& s) const +{ + s << "k=" + << KeyTypes[mMethod]; + if (mMethod != Prompt) + { + s << Symbols::COLON[0] << mKey; + } + s << Symbols::CRLF; + + return s; +} + +void +SdpContents::Session::Encryption::parse(ParseBuffer& pb) +{ + pb.skipChar('k'); + const char* anchor = pb.skipChar(Symbols::EQUALS[0]); + + pb.skipToChar(Symbols::COLON[0]); + if (!pb.eof()) + { + Data p; + pb.data(p, anchor); + if (p == KeyTypes[Clear]) + { + mMethod = Clear; + } + else if (p == KeyTypes[Base64]) + { + mMethod = Base64; + } + else if (p == KeyTypes[UriKey]) + { + mMethod = UriKey; + } + + anchor = pb.skipChar(Symbols::COLON[0]); + pb.skipToOneOf(Symbols::CRLF); + pb.data(mKey, anchor); + } + else + { + pb.reset(anchor); + pb.skipToOneOf(Symbols::CRLF); + + Data p; + pb.data(p, anchor); + if (p == KeyTypes[Prompt]) + { + mMethod = Prompt; + } + } + + skipEol(pb); +} + +SdpContents::Session::Session(int version, + const Origin& origin, + const Data& name) + : mVersion(version), + mOrigin(origin), + mName(name) +{} + +SdpContents::Session::Session(const Session& rhs) +{ + *this = rhs; +} + +SdpContents::Session& +SdpContents::Session::operator=(const Session& rhs) +{ + if (this != &rhs) + { + mVersion = rhs.mVersion; + mOrigin = rhs.mOrigin; + mName = rhs.mName; + mMedia = rhs.mMedia; + mInformation = rhs.mInformation; + mUri = rhs.mUri; + mEmails = rhs.mEmails; + mPhones = rhs.mPhones; + mConnection = rhs.mConnection; + mBandwidths = rhs.mBandwidths; + mTimes = rhs.mTimes; + mTimezones = rhs.mTimezones; + mEncryption = rhs.mEncryption; + mAttributeHelper = rhs.mAttributeHelper; + + for (MediumContainer::iterator i=mMedia.begin(); i != mMedia.end(); ++i) + { + i->setSession(this); + } + } + return *this; +} + +void +SdpContents::Session::parse(ParseBuffer& pb) +{ + pb.skipChar('v'); + pb.skipChar(Symbols::EQUALS[0]); + mVersion = pb.integer(); + skipEol(pb); + + mOrigin.parse(pb); + + pb.skipChar('s'); + const char* anchor = pb.skipChar(Symbols::EQUALS[0]); + pb.skipToOneOf(Symbols::CRLF); + pb.data(mName, anchor); + skipEol(pb); + + if (!pb.eof() && *pb.position() == 'i') + { + pb.skipChar('i'); + const char* anchor = pb.skipChar(Symbols::EQUALS[0]); + pb.skipToOneOf(Symbols::CRLF); + pb.data(mInformation, anchor); + skipEol(pb); + } + + if (!pb.eof() && *pb.position() == 'u') + { + pb.skipChar('u'); + pb.skipChar(Symbols::EQUALS[0]); + mUri.parse(pb); + skipEol(pb); + } + + while (!pb.eof() && *pb.position() == 'e') + { + addEmail(Email()); + mEmails.back().parse(pb); + } + + while (!pb.eof() && *pb.position() == 'p') + { + addPhone(Phone()); + mPhones.back().parse(pb); + } + + if (!pb.eof() && *pb.position() == 'c') + { + mConnection.parse(pb); + } + + while (!pb.eof() && *pb.position() == 'b') + { + addBandwidth(Bandwidth()); + mBandwidths.back().parse(pb); + } + + while (!pb.eof() && *pb.position() == 't') + { + addTime(Time()); + mTimes.back().parse(pb); + } + + if (!pb.eof() && *pb.position() == 'z') + { + mTimezones.parse(pb); + } + + if (!pb.eof() && *pb.position() == 'k') + { + mEncryption.parse(pb); + } + + mAttributeHelper.parse(pb); + + while (!pb.eof() && *pb.position() == 'm') + { + addMedium(Medium()); + mMedia.back().parse(pb); + } +} + +EncodeStream& +SdpContents::Session::encode(EncodeStream& s) const +{ + s << "v=" << mVersion << Symbols::CRLF; + mOrigin.encode(s); + s << "s=" << mName << Symbols::CRLF; + + if (!mInformation.empty()) + { + s << "i=" << mInformation << Symbols::CRLF; + } + + if (!mUri.host().empty()) + { + s << "u="; + mUri.encode(s); + s << Symbols::CRLF; + } + + for (list<Email>::const_iterator i = mEmails.begin(); + i != mEmails.end(); ++i) + { + i->encode(s); + } + + for (list<Phone>::const_iterator i = mPhones.begin(); + i != mPhones.end(); ++i) + { + i->encode(s); + } + + if (!mConnection.getAddress().empty()) + { + mConnection.encode(s); + } + + for (list<Bandwidth>::const_iterator i = mBandwidths.begin(); + i != mBandwidths.end(); ++i) + { + i->encode(s); + } + + if (mTimes.empty()) + { + s << "t=0 0" << Symbols::CRLF; + } + else + { + for (list<Time>::const_iterator i = mTimes.begin(); + i != mTimes.end(); ++i) + { + i->encode(s); + } + } + + mTimezones.encode(s); + + if (mEncryption.getMethod() != Encryption::NoEncryption) + { + mEncryption.encode(s); + } + + mAttributeHelper.encode(s); + + for (MediumContainer::const_iterator i = mMedia.begin(); + i != mMedia.end(); ++i) + { + i->encode(s); + } + + return s; +} + +void +SdpContents::Session::addEmail(const Email& email) +{ + mEmails.push_back(email); +} + +void +SdpContents::Session::addTime(const Time& t) +{ + mTimes.push_back(t); +} + +void +SdpContents::Session::addPhone(const Phone& phone) +{ + mPhones.push_back(phone); +} + +void +SdpContents::Session::addBandwidth(const Bandwidth& bandwidth) +{ + mBandwidths.push_back(bandwidth); +} + +void +SdpContents::Session::addMedium(const Medium& medium) +{ + mMedia.push_back(medium); + mMedia.back().setSession(this); +} + +void +SdpContents::Session::addAttribute(const Data& key, const Data& value) +{ + mAttributeHelper.addAttribute(key, value); + + if (key == rtpmap) + { + for (MediumContainer::iterator i = mMedia.begin(); + i != mMedia.end(); ++i) + { + i->mRtpMapDone = false; + } + } +} + +void +SdpContents::Session::clearAttribute(const Data& key) +{ + mAttributeHelper.clearAttribute(key); + + if (key == rtpmap) + { + for (MediumContainer::iterator i = mMedia.begin(); + i != mMedia.end(); ++i) + { + i->mRtpMapDone = false; + } + } +} + +bool +SdpContents::Session::exists(const Data& key) const +{ + return mAttributeHelper.exists(key); +} + +const list<Data>& +SdpContents::Session::getValues(const Data& key) const +{ + return mAttributeHelper.getValues(key); +} + +SdpContents::Session::Medium::Medium(const Data& name, + unsigned long port, + unsigned long multicast, + const Data& protocol) + : mSession(0), + mName(name), + mPort(port), + mMulticast(multicast), + mProtocol(protocol), + mRtpMapDone(false) +{} + +SdpContents::Session::Medium::Medium() + : mSession(0), + mPort(0), + mMulticast(1), + mRtpMapDone(false) +{} + +SdpContents::Session::Medium::Medium(const Medium& rhs) + : mSession(0), + mName(rhs.mName), + mPort(rhs.mPort), + mMulticast(rhs.mMulticast), + mProtocol(rhs.mProtocol), + mFormats(rhs.mFormats), + mCodecs(rhs.mCodecs), + mTransport(rhs.mTransport), + mInformation(rhs.mInformation), + mConnections(rhs.mConnections), + mBandwidths(rhs.mBandwidths), + mEncryption(rhs.mEncryption), + mAttributeHelper(rhs.mAttributeHelper), + mRtpMapDone(rhs.mRtpMapDone), + mRtpMap(rhs.mRtpMap) +{ +} + + +SdpContents::Session::Medium& +SdpContents::Session::Medium::operator=(const Medium& rhs) +{ + if (this != &rhs) + { + mSession = 0; + mName = rhs.mName; + mPort = rhs.mPort; + mMulticast = rhs.mMulticast; + mProtocol = rhs.mProtocol; + mFormats = rhs.mFormats; + mCodecs = rhs.mCodecs; + mTransport = rhs.mTransport; + mInformation = rhs.mInformation; + mConnections = rhs.mConnections; + mBandwidths = rhs.mBandwidths; + mEncryption = rhs.mEncryption; + mAttributeHelper = rhs.mAttributeHelper; + mRtpMapDone = rhs.mRtpMapDone; + mRtpMap = rhs.mRtpMap; + } + return *this; +} + +void +SdpContents::Session::Medium::setPort(int port) +{ + mPort = port; +} + +void +SdpContents::Session::Medium::setSession(Session* session) +{ + mSession = session; +} + +void +SdpContents::Session::Medium::parse(ParseBuffer& pb) +{ + pb.skipChar('m'); + const char* anchor = pb.skipChar(Symbols::EQUALS[0]); + + pb.skipToChar(Symbols::SPACE[0]); + pb.data(mName, anchor); + pb.skipChar(Symbols::SPACE[0]); + + mPort = pb.integer(); + + if (*pb.position() == Symbols::SLASH[0]) + { + pb.skipChar(); + mMulticast = pb.integer(); + } + + anchor = pb.skipChar(Symbols::SPACE[0]); + pb.skipToOneOf(Symbols::SPACE, Symbols::CRLF); + pb.data(mProtocol, anchor); + + while (*pb.position() != Symbols::CR[0] && + *pb.position() != Symbols::LF[0]) + { + anchor = pb.skipChar(Symbols::SPACE[0]); + pb.skipToOneOf(Symbols::SPACE, Symbols::CRLF); + if(pb.position() != anchor) + { + Data format; + pb.data(format, anchor); + addFormat(format); + } + } + + skipEol(pb); + + if (!pb.eof() && *pb.position() == 'i') + { + pb.skipChar('i'); + anchor = pb.skipChar(Symbols::EQUALS[0]); + pb.skipToOneOf(Symbols::CRLF); + pb.data(mInformation, anchor); + + skipEol(pb); + } + + while (!pb.eof() && *pb.position() == 'c') + { + addConnection(Connection()); + mConnections.back().parse(pb); + if (!pb.eof() && *pb.position() == Symbols::SLASH[0]) + { + // Note: we only get here if there was a /<number of addresses> + // parameter following the connection address. + pb.skipChar(); + int num = pb.integer(); + + Connection& con = mConnections.back(); + const Data& addr = con.getAddress(); + size_t i = addr.size() - 1; + for (; i; i--) + { + if (addr[i] == '.' || addr[i] == ':') // ipv4 or ipv6 + { + break; + } + } + + if (addr[i] == '.') // add a number of ipv4 connections + { + Data before(addr.data(), i+1); + ParseBuffer subpb(addr.data()+i+1, addr.size()-i-1); + int after = subpb.integer(); + + for (int i = 1; i < num; i++) + { + addConnection(con); + mConnections.back().mAddress = before + Data(after+i); + } + } + if (addr[i] == ':') // add a number of ipv6 connections + { + Data before(addr.data(), i+1); + int after = Helper::hex2integer(addr.data()+i+1); + char hexstring[9]; + + for (int i = 1; i < num; i++) + { + addConnection(con); + memset(hexstring, 0, sizeof(hexstring)); + Helper::integer2hex(hexstring, after+i, false /* supress leading zeros */); + mConnections.back().mAddress = before + Data(hexstring); + } + } + + skipEol(pb); + } + } + + while (!pb.eof() && *pb.position() == 'b') + { + addBandwidth(Bandwidth()); + mBandwidths.back().parse(pb); + } + + if (!pb.eof() && *pb.position() == 'k') + { + mEncryption.parse(pb); + } + + mAttributeHelper.parse(pb); +} + +EncodeStream& +SdpContents::Session::Medium::encode(EncodeStream& s) const +{ + s << "m=" + << mName << Symbols::SPACE[0] + << mPort; + if (mMulticast > 1) + { + s << Symbols::SLASH[0] << mMulticast; + } + s << Symbols::SPACE[0] + << mProtocol; + + for (list<Data>::const_iterator i = mFormats.begin(); + i != mFormats.end(); ++i) + { + s << Symbols::SPACE[0] << *i; + } + + if (!mCodecs.empty()) + { + for (CodecContainer::const_iterator i = mCodecs.begin(); + i != mCodecs.end(); ++i) + { + s << Symbols::SPACE[0] << i->payloadType(); + } + } + + s << Symbols::CRLF; + + if (!mInformation.empty()) + { + s << "i=" << mInformation << Symbols::CRLF; + } + + for (list<Connection>::const_iterator i = mConnections.begin(); + i != mConnections.end(); ++i) + { + i->encode(s); + } + + for (list<Bandwidth>::const_iterator i = mBandwidths.begin(); + i != mBandwidths.end(); ++i) + { + i->encode(s); + } + + if (mEncryption.getMethod() != Encryption::NoEncryption) + { + mEncryption.encode(s); + } + + if (!mCodecs.empty()) + { + // add codecs to information and attributes + for (CodecContainer::const_iterator i = mCodecs.begin(); + i != mCodecs.end(); ++i) + { + // If codec is static (defined in RFC 3551) we probably shouldn't + // add attributes for it. But some UAs do include them. + //Codec::CodecMap& staticCodecs = Codec::getStaticCodecs(); + //if (staticCodecs.find(i->payloadType()) != staticCodecs.end()) + //{ + // continue; + //} + + s << "a=rtpmap:" + << i->payloadType() << Symbols::SPACE[0] << *i + << Symbols::CRLF; + if (!i->parameters().empty()) + { + s << "a=fmtp:" + << i->payloadType() << Symbols::SPACE[0] << i->parameters() + << Symbols::CRLF; + } + } + } + + mAttributeHelper.encode(s); + + return s; +} + +void +SdpContents::Session::Medium::addFormat(const Data& format) +{ + mFormats.push_back(format); +} + +void +SdpContents::Session::Medium::setConnection(const Connection& connection) +{ + mConnections.clear(); + addConnection(connection); +} + +void +SdpContents::Session::Medium::addConnection(const Connection& connection) +{ + mConnections.push_back(connection); +} + +void +SdpContents::Session::Medium::setBandwidth(const Bandwidth& bandwidth) +{ + mBandwidths.clear(); + addBandwidth(bandwidth); +} + +void +SdpContents::Session::Medium::addBandwidth(const Bandwidth& bandwidth) +{ + mBandwidths.push_back(bandwidth); +} + +void +SdpContents::Session::Medium::addAttribute(const Data& key, const Data& value) +{ + mAttributeHelper.addAttribute(key, value); + if (key == rtpmap) + { + mRtpMapDone = false; + } +} + +const list<SdpContents::Session::Connection> +SdpContents::Session::Medium::getConnections() const +{ + list<Connection> connections = const_cast<Medium*>(this)->getMediumConnections(); + // If there are connections specified at the medium level, then check if a session level + // connection is present - if so then return it + if (connections.empty() && mSession && !mSession->connection().getAddress().empty()) + { + connections.push_back(mSession->connection()); + } + + return connections; +} + +bool +SdpContents::Session::Medium::exists(const Data& key) const +{ + if (mAttributeHelper.exists(key)) + { + return true; + } + return mSession && mSession->exists(key); +} + +const list<Data>& +SdpContents::Session::Medium::getValues(const Data& key) const +{ + if (mAttributeHelper.exists(key)) + { + return mAttributeHelper.getValues(key); + } + if (!mSession) + { + assert(false); + static list<Data> error; + return error; + } + return mSession->getValues(key); +} + +void +SdpContents::Session::Medium::clearAttribute(const Data& key) +{ + mAttributeHelper.clearAttribute(key); + if (key == rtpmap) + { + mRtpMapDone = false; + } +} + +void +SdpContents::Session::Medium::clearCodecs() +{ + mFormats.clear(); + clearAttribute(rtpmap); + clearAttribute(fmtp); + mCodecs.clear(); +} + +void +SdpContents::Session::Medium::addCodec(const Codec& codec) +{ + codecs(); + mCodecs.push_back(codec); +} + + +const SdpContents::Session::Medium::CodecContainer& +SdpContents::Session::Medium::codecs() const +{ + return const_cast<Medium*>(this)->codecs(); +} + +SdpContents::Session::Medium::CodecContainer& +SdpContents::Session::Medium::codecs() +{ +#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1310) // CJ TODO fix + assert(0); +#else + if (!mRtpMapDone) + { + // prevent recursion + mRtpMapDone = true; + + if (exists(rtpmap)) + { + for (list<Data>::const_iterator i = getValues(rtpmap).begin(); + i != getValues(rtpmap).end(); ++i) + { + //DebugLog(<< "SdpContents::Session::Medium::getCodec(" << *i << ")"); + ParseBuffer pb(i->data(), i->size()); + int format = pb.integer(); + // pass to codec constructor for parsing + // pass this for other codec attributes + try + { + mRtpMap[format].parse(pb, *this, format); + } + catch (ParseException& e) + { + ErrLog(<<"Caught exception: "<< e); + mRtpMap.erase(format); + } + } + } + + for (list<Data>::const_iterator i = mFormats.begin(); + i != mFormats.end(); ++i) + { + int mapKey = i->convertInt(); + RtpMap::const_iterator ri = mRtpMap.find(mapKey); + if (ri != mRtpMap.end()) + { + //DebugLog(<< "SdpContents::Session::Medium::getCodec[](" << ri->second << ")"); + mCodecs.push_back(ri->second); + } + else + { + // !kk! Is it a static format? + Codec::CodecMap& staticCodecs = Codec::getStaticCodecs(); + Codec::CodecMap::const_iterator ri = staticCodecs.find(mapKey); + if (ri != staticCodecs.end()) + { + //DebugLog(<< "Found static codec for format: " << mapKey); + Codec codec(ri->second); + + // Look for format parameters, and assign + codec.assignFormatParameters(*this); + + mCodecs.push_back(codec); + } + } + } + + // don't store twice + mFormats.clear(); + mAttributeHelper.clearAttribute(rtpmap); + mAttributeHelper.clearAttribute(fmtp); // parsed out in codec.parse + } +#endif + + return mCodecs; +} + +static Codec emptyCodec; +const Codec& +SdpContents::Session::Medium::findFirstMatchingCodecs(const CodecContainer& codecList, Codec* pMatchingCodec) const +{ + const CodecContainer& internalCodecList = codecs(); + resip::SdpContents::Session::Medium::CodecContainer::const_iterator sIter; + resip::SdpContents::Session::Medium::CodecContainer::const_iterator sEnd = internalCodecList.end(); + resip::SdpContents::Session::Medium::CodecContainer::const_iterator eIter; + resip::SdpContents::Session::Medium::CodecContainer::const_iterator eEnd = codecList.end(); + for (eIter = codecList.begin(); eIter != eEnd ; ++eIter) + { + for (sIter = internalCodecList.begin(); sIter != sEnd; ++sIter) + { + if (*sIter == *eIter) + { + if (pMatchingCodec) + { + *pMatchingCodec = *eIter; + } + return *sIter; + } + } + } + return emptyCodec; +} + +const Codec& +SdpContents::Session::Medium::findFirstMatchingCodecs(const Medium& medium, Codec* pMatchingCodec) const +{ + if (&medium == this) + { + return codecs().front(); + } + else + { + return findFirstMatchingCodecs(medium.codecs(), pMatchingCodec); + } +} + +int +SdpContents::Session::Medium::findTelephoneEventPayloadType() const +{ + const CodecContainer& codecList = codecs(); + for (CodecContainer::const_iterator i = codecList.begin(); i != codecList.end(); i++) + { + if (i->getName() == SdpContents::Session::Codec::TelephoneEvent.getName()) + { + return i->payloadType(); + } + } + return -1; +} + +Codec::Codec(const Data& name, + unsigned long rate, + const Data& parameters, + const Data& encodingParameters) + : mName(name), + mRate(rate), + mPayloadType(-1), + mParameters(parameters), + mEncodingParameters(encodingParameters) +{ +} + +Codec::Codec(const Codec& rhs) + : mName(rhs.mName), + mRate(rhs.mRate), + mPayloadType(rhs.mPayloadType), + mParameters(rhs.mParameters), + mEncodingParameters(rhs.mEncodingParameters) +{ +} + +Codec::Codec(const Data& name, int payloadType, int rate) + : mName(name), + mRate(rate), + mPayloadType(payloadType) +{ +} + +Codec& +Codec::operator=(const Codec& rhs) +{ + if (this != &rhs) + { + mName = rhs.mName; + mRate = rhs.mRate; + mPayloadType = rhs.mPayloadType; + mParameters = rhs.mParameters; + mEncodingParameters = rhs.mEncodingParameters; + } + return *this; +} + +void +Codec::parse(ParseBuffer& pb, + const SdpContents::Session::Medium& medium, + int payloadType) +{ + const char* anchor = pb.skipWhitespace(); + pb.skipToChar(Symbols::SLASH[0]); + mName = pb.data(anchor); + if(!pb.eof()) + { + pb.skipChar(Symbols::SLASH[0]); + mRate = pb.integer(); + pb.skipToChar(Symbols::SLASH[0]); + } + if(!pb.eof() && *pb.position() == Symbols::SLASH[0]) + { + anchor = pb.skipChar(Symbols::SLASH[0]); + pb.skipToEnd(); + mEncodingParameters = pb.data(anchor); + } + mPayloadType = payloadType; + + assignFormatParameters(medium); +} + +void +Codec::assignFormatParameters(const SdpContents::Session::Medium& medium) +{ + // get parameters if they exist + if (medium.exists(fmtp)) + { + for (list<Data>::const_iterator i = medium.getValues(fmtp).begin(); + i != medium.getValues(fmtp).end(); ++i) + { + try + { + ParseBuffer pb(i->data(), i->size()); + int payload = pb.integer(); + if (payload == mPayloadType) + { + const char* anchor = pb.skipWhitespace(); + pb.skipToEnd(); + mParameters = pb.data(anchor); + break; + } + } + catch (ParseException &pe) + { + InfoLog(<<"Caught exception when parsing a=fmtp: "<< pe); + } + } + } +} + +const Data& +Codec::getName() const +{ + return mName; +} + +int +Codec::getRate() const +{ + return mRate; +} + +Codec::CodecMap& Codec::getStaticCodecs() +{ + if (! sStaticCodecsCreated) + { + // + // Build map of static codecs as defined in RFC 3551 + // + sStaticCodecs = std::auto_ptr<CodecMap>(new CodecMap); + + // Audio codecs + sStaticCodecs->insert(make_pair(0,Codec("PCMU",0,8000))); + sStaticCodecs->insert(make_pair(3,Codec("GSM",3,8000))); + sStaticCodecs->insert(make_pair(4,Codec("G723",4,8000))); + sStaticCodecs->insert(make_pair(5,Codec("DVI4",5,8000))); + sStaticCodecs->insert(make_pair(6,Codec("DVI4",6,16000))); + sStaticCodecs->insert(make_pair(7,Codec("LPC",7,8000))); + sStaticCodecs->insert(make_pair(8,Codec("PCMA",8,8000))); + sStaticCodecs->insert(make_pair(9,Codec("G722",9,8000))); + sStaticCodecs->insert(make_pair(10,Codec("L16-2",10,44100))); + sStaticCodecs->insert(make_pair(11,Codec("L16-1",11,44100))); + sStaticCodecs->insert(make_pair(12,Codec("QCELP",12,8000))); + sStaticCodecs->insert(make_pair(13,Codec("CN",13,8000))); + sStaticCodecs->insert(make_pair(14,Codec("MPA",14,90000))); + sStaticCodecs->insert(make_pair(15,Codec("G728",15,8000))); + sStaticCodecs->insert(make_pair(16,Codec("DVI4",16,11025))); + sStaticCodecs->insert(make_pair(17,Codec("DVI4",17,22050))); + sStaticCodecs->insert(make_pair(18,Codec("G729",18,8000))); + + // Video or audio/video codecs + sStaticCodecs->insert(make_pair(25,Codec("CelB",25,90000))); + sStaticCodecs->insert(make_pair(26,Codec("JPEG",26,90000))); + sStaticCodecs->insert(make_pair(28,Codec("nv",28,90000))); + sStaticCodecs->insert(make_pair(31,Codec("H261",31,90000))); + sStaticCodecs->insert(make_pair(32,Codec("MPV",32,90000))); + sStaticCodecs->insert(make_pair(33,Codec("MP2T",33,90000))); + sStaticCodecs->insert(make_pair(34,Codec("H263",34,90000))); + + sStaticCodecsCreated = true; + } + return *(sStaticCodecs.get()); +} + +bool +resip::operator==(const Codec& lhs, const Codec& rhs) +{ + static Data defaultEncodingParameters(Data("1")); // Default for audio streams (1-Channel) + return (isEqualNoCase(lhs.mName, rhs.mName) && lhs.mRate == rhs.mRate && + (lhs.mEncodingParameters == rhs.mEncodingParameters || + (lhs.mEncodingParameters.empty() && rhs.mEncodingParameters == defaultEncodingParameters) || + (lhs.mEncodingParameters == defaultEncodingParameters && rhs.mEncodingParameters.empty()))); +} + +EncodeStream& +resip::operator<<(EncodeStream& str, const Codec& codec) +{ + str << codec.mName; + str << Symbols::SLASH[0]; + str << codec.mRate; + if(!codec.mEncodingParameters.empty()) + { + str << Symbols::SLASH[0]; + str << codec.mEncodingParameters; + } + return str; +} + +const Codec Codec::ULaw_8000("PCMU", 0, 8000); +const Codec Codec::ALaw_8000("PCMA", 8, 8000); +const Codec Codec::G729_8000("G729", 18, 8000); +const Codec Codec::G723_8000("G723", 4, 8000); +const Codec Codec::GSM_8000("GSM", 3, 8000); + +const Codec Codec::TelephoneEvent("telephone-event", 101, 8000); +const Codec Codec::FrfDialedDigit("frf-dialed-event",102, 8000); +const Codec Codec::CN("CN", 13, 8000); + +bool Codec::sStaticCodecsCreated = false; +std::auto_ptr<Codec::CodecMap> Codec::sStaticCodecs; + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/SdpContents.hxx b/src/libs/resiprocate/resip/stack/SdpContents.hxx new file mode 100644 index 00000000..05daa73d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SdpContents.hxx @@ -0,0 +1,1105 @@ +#if !defined(RESIP_SDPCONTENTS_HXX) +#define RESIP_SDPCONTENTS_HXX + +#include <vector> +#include <list> +#include <iosfwd> +#include <memory> + +#include "resip/stack/Contents.hxx" +#include "resip/stack/Uri.hxx" +#include "rutil/Data.hxx" +#include "rutil/HashMap.hxx" +#include "rutil/HeapInstanceCounter.hxx" + +namespace resip +{ + +class SdpContents; + +class AttributeHelper +{ + public: + RESIP_HeapCount(AttributeHelper); + AttributeHelper(); + AttributeHelper(const AttributeHelper& rhs); + AttributeHelper& operator=(const AttributeHelper& rhs); + + bool exists(const Data& key) const; + const std::list<Data>& getValues(const Data& key) const; + EncodeStream& encode(EncodeStream& s) const; + void parse(ParseBuffer& pb); + void addAttribute(const Data& key, const Data& value = Data::Empty); + void clearAttribute(const Data& key); + private: + std::list<std::pair<Data, Data> > mAttributeList; // used to ensure attribute ordering on encode + HashMap< Data, std::list<Data> > mAttributes; +}; + +/** + @ingroup sip_payload + @brief Provides an interface to process and generate SDP bodies (MIME content-type application/sdp). + * + * This class performs both the parsing and generation of SDP. Most + * interaction with the SDP will be through the Session object, + * accessible through the session() method. + * + **/ +class SdpContents : public Contents +{ + public: + RESIP_HeapCount(SdpContents); + typedef enum {IP4=1, IP6} AddrType; + static const SdpContents Empty; + + class Session; + + /** @brief Provides an interface to read and modify SDP + * bodies. + * + **/ + class Session + { + public: + class Medium; + + /** @brief parameters for a specific codec are stored in this class. + * + **/ + class Codec + { + public: + Codec() : mName(), mRate(0), mPayloadType(-1) {} + + /** @brief full constructor for a Codec. + * + * This constructor allows a rate and optional parameters to be specified. + * + * @param name a string identifying the codec + * @param rate number of samples/sec + * @param parameters optional list of parameters for the codec + * @param encodingParameters optional encoding parameters for the codec + * + **/ + Codec(const Data& name, unsigned long rate, const Data& parameters = Data::Empty, const Data& encodingParameters = Data::Empty); + + /** @brief constructor for a Codec + * + * This constructor allows for payload type and rate parameters to be specified. + * + * @param name a string identifying the codec + * @param payloadType RTP payload type to associate with this codec + * @param rate sample rate of this codec + * + **/ + Codec(const Data& name, int payloadType, int rate=8000); + Codec(const Codec& rhs); + Codec& operator=(const Codec& codec); + + void parse(ParseBuffer& pb, + const SdpContents::Session::Medium& medium, + int payLoadType); + void assignFormatParameters(const SdpContents::Session::Medium& medium); + + /** @brief returns the name of the codec. + * @return name of the codec + **/ + const Data& getName() const; + /** @brief returns the name of the codec. + * @return name of the codec + **/ + int getRate() const; + + /** @brief returns the RTP payload type associated with this codec. + * @return RTP payload type + **/ + int payloadType() const {return mPayloadType;} + /** @brief returns the RTP payload type associated with this codec. + * @return RTP payload type + **/ + int& payloadType() {return mPayloadType;} + + /** @brief returns the parameters associated with this codec + * @return codec parameters + **/ + const Data& parameters() const {return mParameters;} + /** @brief returns the parameters associated with this codec + * @return codec parameters + **/ + Data& parameters() {return mParameters;} + + /** @brief returns the encoding parameters associated with this codec + * @return encoding parameters + **/ + const Data& encodingParameters() const {return mEncodingParameters;} + /** @brief returns the encoding parameters associated with this codec + * @return encoding parameters + **/ + Data& encodingParameters() {return mEncodingParameters;} + + static const Codec ULaw_8000; + static const Codec ALaw_8000; + static const Codec G729_8000; + static const Codec G723_8000; + static const Codec GSM_8000; + static const Codec TelephoneEvent; + static const Codec FrfDialedDigit; + static const Codec CN; + + typedef HashMap<int, Codec> CodecMap; + // "static" payload types as defined in RFC 3551. + // Maps payload type (number) to Codec definition. + static CodecMap& getStaticCodecs(); + + friend bool operator==(const Codec&, const Codec&); + + private: + Data mName; + unsigned long mRate; + int mPayloadType; + Data mParameters; // Format parameters + Data mEncodingParameters; + + static std::auto_ptr<CodecMap> sStaticCodecs; + static bool sStaticCodecsCreated; + friend EncodeStream& operator<<(EncodeStream&, const Codec&); + }; + + /** @brief processes o= lines in SDP + **/ + class Origin + { + public: + /** @brief constructor for origin line + * + * @param user session user + * @param sessionId session ID + * @param version session version + * @param addr session address type (IP4 or IP6) + * @param address IP address of the session + * + **/ + Origin(const Data& user, + const UInt64& sessionId, + const UInt64& version, + AddrType addr, + const Data& address); + Origin(const Origin& rhs); + Origin& operator=(const Origin& rhs); + + void parse(ParseBuffer& pb); + EncodeStream& encode(EncodeStream&) const; + + /** @brief returns the session ID + * @return session ID + **/ + const UInt64& getSessionId() const {return mSessionId;} + /** @brief returns the session ID + * @return session ID + **/ + UInt64& getSessionId() { return mSessionId; } + + /** @brief returns the session version + * @return session version + **/ + const UInt64& getVersion() const {return mVersion;} + /** @brief returns the session version + * @return session version + **/ + UInt64& getVersion() { return mVersion; } + /** @brief returns the user string for the session + * @return user string + **/ + const Data& user() const {return mUser;} + /** @brief returns the user string for the session + * @return user string + **/ + Data& user() {return mUser;} + + /** @brief returns the session address type + * + * @return address type (IP4 or IP6) + **/ + AddrType getAddressType() const {return mAddrType;} + /** @brief returns the session address type + * + * @return address type (IP4 or IP6) + **/ + const Data& getAddress() const {return mAddress;} + + /** @brief set the address for the session + * + * @param host IP address to associate with the session + * @param type type of addressing + **/ + void setAddress(const Data& host, AddrType type = IP4); + + private: + Origin(); + + Data mUser; + UInt64 mSessionId; + UInt64 mVersion; + AddrType mAddrType; + Data mAddress; + + friend class Session; + }; + + /** @brief process e= (email) lines in the SDP + * + **/ + class Email + { + public: + /** @brief constructor + * + * @param address email address + * @param freeText string describing the email address + * + **/ + Email(const Data& address, + const Data& freeText); + + Email(const Email& rhs); + Email& operator=(const Email& rhs); + + void parse(ParseBuffer& pb); + EncodeStream& encode(EncodeStream&) const; + + /** @brief returns the email address + * + * @return email address + **/ + const Data& getAddress() const {return mAddress;} + /** @brief returns the string describing the email address + * + * @return string + **/ + const Data& getFreeText() const {return mFreeText;} + + private: + Email() {} + + Data mAddress; + Data mFreeText; + + friend class Session; + }; + + /** @brief process p= (phone number) lines in the SDP + * + **/ + class Phone + { + public: + /** @brief constructor + * + * @param number phone number + * @param freeText text string describing the phone number + * + **/ + Phone(const Data& number, + const Data& freeText); + Phone(const Phone& rhs); + Phone& operator=(const Phone& rhs); + + void parse(ParseBuffer& pb); + EncodeStream& encode(EncodeStream&) const; + + + /** @brief return the phone number + * + * @return phone number + **/ + const Data& getNumber() const {return mNumber;} + /** @brief return text string describing the phone number + * + * @return text string describing the phone number + **/ + const Data& getFreeText() const {return mFreeText;} + + private: + Phone() {} + + Data mNumber; + Data mFreeText; + + friend class Session; + }; + + /** @brief Process c= (connection) lines in SDP + * + * This line specifies the IP address and address type used in the session + * + **/ + class Connection + { + public: + /** @brief constructor + * + * @param addType address type (IP4 or IP6) + * @param address IP address + * @param ttl time to live + * + **/ + Connection(AddrType addType, + const Data& address, + unsigned long ttl = 0); + Connection(const Connection& rhs); + Connection& operator=(const Connection& rhs); + + void parse(ParseBuffer& pb); + EncodeStream& encode(EncodeStream&) const; + + /** @brief returns the connection address type + * + * @return address type (IP4 or IP6) + **/ + AddrType getAddressType() const {return mAddrType;} + + /** @brief returns the connection address + * + * @return IP address + **/ + const Data& getAddress() const {return mAddress;} + + /** @brief set the address for the connection + * + * @param host IP address to associate with the connection + * @param type type of addressing + **/ + void setAddress(const Data& host, AddrType type = IP4); + unsigned long ttl() const {return mTTL;} + unsigned long& ttl() {return mTTL;} + + private: + Connection(); + + AddrType mAddrType; + Data mAddress; + unsigned long mTTL; + + friend class Session; + friend class Medium; + }; + + /** @brief Process optional b= (bandwidth) lines in SDP + * + **/ + class Bandwidth + { + public: + /** @brief Constructor + * + * @param modifier alphanumeric word giving the meaning of the bandwidth figure + * @param kbPerSecond number of kilobits per second + * + **/ + Bandwidth(const Data& modifier, + unsigned long kbPerSecond); + Bandwidth(const Bandwidth& rhs); + Bandwidth& operator=(const Bandwidth& rhs); + + void parse(ParseBuffer& pb); + EncodeStream& encode(EncodeStream&) const; + + /** @brief returns the modifier string + * + * @return modifier string + **/ + const Data& modifier() const {return mModifier;} + /** @brief returns the modifier string + * + * @return modifier string + **/ + Data modifier() {return mModifier;} + /** @brief returns the number of kilobits/second maximum bandwidth + * + * @return maximum bandwidth in kilobits/second + **/ + unsigned long kbPerSecond() const {return mKbPerSecond;} + /** @brief returns the number of kilobits/second maximum bandwidth + * + * @return maximum bandwidth in kilobits/second + **/ + unsigned long& kbPerSecond() {return mKbPerSecond;} + + private: + Bandwidth() {} + Data mModifier; + unsigned long mKbPerSecond; + + friend class Session; + friend class Medium; + }; + + /** @brief Process t= (start/stop time) lines in SDP + * + **/ + class Time + { + public: + /** @brief Constructor + * + * The times given are the decimal part of an NTP timestamp. To convert these values to UNIX time, + * subtract decimal 2208988800 from the value. + * + * @param start start time + * @param stop stop time + * + **/ + Time(unsigned long start, + unsigned long stop); + Time(const Time& rhs); + Time& operator=(const Time& rhs); + + void parse(ParseBuffer& pb); + EncodeStream& encode(EncodeStream&) const; + + /** @brief Repeat time. Not used for SIP + * + **/ + class Repeat + { + public: + Repeat(unsigned long interval, + unsigned long duration, + std::list<int> offsets); + void parse(ParseBuffer& pb); + EncodeStream& encode(EncodeStream&) const; + + unsigned long getInterval() const {return mInterval;} + unsigned long getDuration() const {return mDuration;} + const std::list<int> getOffsets() const {return mOffsets;} + + private: + Repeat() {} + unsigned long mInterval; + unsigned long mDuration; + std::list<int> mOffsets; + + friend class Time; + }; + + void addRepeat(const Repeat& repeat); + + /** @brief return the start time + * + * @return start time + **/ + unsigned long getStart() const {return mStart;} + /** @brief return the stop time + * + * @return stop time + **/ + unsigned long getStop() const {return mStop;} + const std::list<Repeat>& getRepeats() const {return mRepeats;} + + private: + Time() {} + unsigned long mStart; + unsigned long mStop; + std::list<Repeat> mRepeats; + + friend class Session; + }; + + /** @brief process z= (timezone) lines + * + * Not used in SIP + * + **/ + class Timezones + { + public: + /** @brief specify the time at which a timezone shift will occur and the offset, in seconds + @deprecated Unused + */ + class Adjustment + { + public: + Adjustment(unsigned long time, + int offset); + Adjustment(const Adjustment& rhs); + Adjustment& operator=(const Adjustment& rhs); + + unsigned long time; + int offset; + }; + + Timezones(); + Timezones(const Timezones& rhs); + Timezones& operator=(const Timezones& rhs); + + void parse(ParseBuffer& pb); + EncodeStream& encode(EncodeStream&) const; + + void addAdjustment(const Adjustment& adjusment); + const std::list<Adjustment>& getAdjustments() const {return mAdjustments; } + private: + std::list<Adjustment> mAdjustments; + }; + + /** @brief process k= (encryption key) line + * + **/ + class Encryption + { + public: + typedef enum {NoEncryption = 0, Prompt, Clear, Base64, UriKey} KeyType; + Encryption(const KeyType& method, + const Data& key); + Encryption(const Encryption& rhs); + Encryption& operator=(const Encryption& rhs); + + + void parse(ParseBuffer& pb); + EncodeStream& encode(EncodeStream&) const; + + const KeyType& getMethod() const {return mMethod;} + const KeyType& method() const {return mMethod;} + KeyType& method() {return mMethod;} + const Data& getKey() const {return mKey;} + const Data& key() const {return mKey;} + Data& key() {return mKey;} + + Encryption(); + private: + KeyType mMethod; + Data mKey; + }; + + /** @brief process m= (media announcement) blocks + * + **/ + class Medium + { + public: + Medium(); + Medium(const Medium& rhs); + /** @brief Constructor + * + * @param name media type (audio, video, application, data, etc.) + * @param port UDP port that will receive RTP + * @param multicast a misnomer. If multicast > 1, the next (multicast) + * even ports will convey RTP and the next (multicast) odd ports will + * convey corresponding RTCP + * @param protocol the transport used to convey the media. Usually "RTP/AVP" for SIP. + * + **/ + Medium(const Data& name, + unsigned long port, + unsigned long multicast, + const Data& protocol); + Medium& operator=(const Medium& rhs); + + void parse(ParseBuffer& pb); + EncodeStream& encode(EncodeStream&) const; + + /** @brief add a format identifier to the m= line + * + * This will need to be called for each codec used in the SDP. + * + * @param format format identifier + * + **/ + void addFormat(const Data& format); + /** @brief set the media connection line. Optional if main SDP has c= line. + * + * @param connection connection line to use + **/ + void setConnection(const Connection& connection); + /** @brief add a media connection line. Optional if main SDP has c= line. + * + * @param connection connection line to use + **/ + void addConnection(const Connection& connection); + void setBandwidth(const Bandwidth& bandwidth); + void addBandwidth(const Bandwidth& bandwidth); + /** @brief add a media attribute line + * + * @param key attribute key + * @param value attribute value + * + **/ + void addAttribute(const Data& key, const Data& value = Data::Empty); + + /** @brief return the media type + * + * @return media type + **/ + const Data& name() const {return mName;} + /** @brief return the media type + * + * @return media type + **/ + Data& name() {return mName;} + /** @brief return the base port + * + * @return base port + **/ + int port() const {return mPort;} + /** @brief return the base port + * + * @return base port + **/ + unsigned long& port() {return mPort;} + /** @brief change the base port + * + * @param port new base port + * + **/ + void setPort(int port); + /** @brief get the number of transport port pairs + * + * @return number of transport port pairs + **/ + int multicast() const {return mMulticast;} + /** @brief get the number of transport port pairs + * + * @return number of transport port pairs + **/ + unsigned long& multicast() {return mMulticast;} + /** @brief return the transport protocol + * + * @return transport protocol name + **/ + const Data& protocol() const {return mProtocol;} + /** @brief return the transport protocol + * + * @return transport protocol name + **/ + Data& protocol() {return mProtocol;} + + // preferred codec/format interface + typedef std::list<Codec> CodecContainer; + /** preferred codec/format interface + @note internal storage of formats, rtpmap attributes, and + ftmp attributes are cleared out after codecs() is + called, since they get converted internally as Codec + objects + */ + const CodecContainer& codecs() const; + CodecContainer& codecs(); + + /** @brief remove all codecs from SDP **/ + void clearCodecs(); + /** @brief add a codec to the m= line + * + * @param codec codec to add + * + **/ + void addCodec(const Codec& codec); + + /** @brief return a list of codec formats + * + * These formats correspond to RTP payload type identifiers + * + * @note formats are cleared out and converted in codec + * objects when codecs() is called + * @return list of codec formats + **/ + const std::list<Data>& getFormats() const {return mFormats;} + + /** @brief get optional i= (information) line contents + * + * @return contents + **/ + const Data& information() const {return mInformation;} + /** @brief get optional i= (information) line contents + * + * @return contents + **/ + Data& information() {return mInformation;} + /** @brief get a list of bandwidth lines + * + * @return list of Bandwidth objects + **/ + const std::list<Bandwidth>& bandwidths() const {return mBandwidths;} + std::list<Bandwidth>& bandwidths() {return mBandwidths;} + + /** @brief get a list of Connection objects, including the Session's c= line. + * + * If the media's c= line is empty, use the Session's c= line. + * + * @return list of connections + **/ + const std::list<Connection> getConnections() const; + /** @brief get a list of Connection objects from the m= section. Does not include session c= line. + * + * @return list of connections + **/ + const std::list<Connection>& getMediumConnections() const {return mConnections;} + std::list<Connection>& getMediumConnections() {return mConnections;} + const Encryption& getEncryption() const {return mEncryption;} + const Encryption& encryption() const {return mEncryption;} + Encryption& encryption() {return mEncryption;} + /** @brief tests if an a= key is present in the media section + * + * @param key key to check + * + * @return true if key exists, false otherwise + **/ + bool exists(const Data& key) const; + /** @brief get the attribute values corresponding to the key + * + * @param key key to check + * + * @return list of values for given key + **/ + const std::list<Data>& getValues(const Data& key) const; + /** @brief erase all attributes for a given key + * + * @param key key to clear + * + **/ + void clearAttribute(const Data& key); + + // Search through this mediums codecs to find and return the first match from the passed in list + // Note: The codecList item that matched the codec from the medium is passed back via pMatchingCodec + // if a non-NULL pointer is passed in. The codec returned if from this medium. + const Codec& findFirstMatchingCodecs(const CodecContainer& codecs, Codec* pMatchingCodec = 0) const; + // Search through this mediums codecs to find and return the first match from the passed in medium + // Note: The passed in medium's codec that matched the codec from this medium is passed back + // via pMatchingCodec if a non-NULL pointer is passed in. The codec returned if from this medium. + const Codec& findFirstMatchingCodecs(const Medium& medium, Codec* pMatchingCodec = 0) const; + + /** @brief finds the telephone-event payload type + * + * @return payload type of telephone-event "codec" + **/ + int findTelephoneEventPayloadType() const; + + private: + void setSession(Session* session); + Session* mSession; + + Data mName; + unsigned long mPort; + unsigned long mMulticast; + Data mProtocol; + std::list<Data> mFormats; + CodecContainer mCodecs; + Data mTransport; + Data mInformation; + std::list<Connection> mConnections; + std::list<Bandwidth> mBandwidths; + Encryption mEncryption; + AttributeHelper mAttributeHelper; + + bool mRtpMapDone; + typedef HashMap<int, Codec> RtpMap; + RtpMap mRtpMap; + + friend class Session; + }; + + /** @brief session constructor + * + * Create a new session from origin line, version, and session anme + * + * @param version session version + * @param origin Origin line + * @param name session name + * + **/ + Session(int version, + const Origin& origin, + const Data& name); + + Session() : mVersion(0) {} + Session(const Session& rhs); + Session& operator=(const Session& rhs); + + void parse(ParseBuffer& pb); + EncodeStream& encode(EncodeStream&) const; + + /** @brief return session version + * + * @return session version + **/ + int version() const {return mVersion;} + /** @brief return session version + * + * @return session version + **/ + int& version() {return mVersion;} + /** @brief return session Origin line + * + * @return Origin line + **/ + const Origin& origin() const {return mOrigin;} + /** @brief return session Origin line + * + * @return Origin line + **/ + Origin& origin() {return mOrigin;} + /** @brief return session name + * + * @return name + **/ + const Data& name() const {return mName;} + /** @brief return session name + * + * @return name + **/ + Data& name() {return mName;} + /** @brief return session Information + * + * @return Information line + **/ + const Data& information() const {return mInformation;} + /** @brief return session Information + * + * @return Information line + **/ + Data& information() {return mInformation;} + /** @brief return session Uri + * + * @return Uri line + **/ + const Uri& uri() const {return mUri;} + /** @brief return session Uri + * + * @return Uri line + **/ + Uri& uri() {return mUri;} + /** @brief return session Email list + * + * @return Email list + **/ + const std::list<Email>& getEmails() const {return mEmails;} + /** @brief return session Phone number list + * + * @return Phone number list + **/ + const std::list<Phone>& getPhones() const {return mPhones;} + /** @brief return session Connection + * + * @return Connection line + **/ + const Connection& connection() const {return mConnection;} + /** @brief return session Connection + * + * @return Connection line + **/ + Connection& connection() {return mConnection;} // !dlb! optional? + /** @brief check if a c= line is present for the session + * + * @return true if c= line is present + **/ + bool isConnection() const { return mConnection.mAddress != Data::Empty; } + /** @brief return session Bandwidth lines + * + * @return Bandwidth lines + **/ + const std::list<Bandwidth>& bandwidths() const {return mBandwidths;} + /** @brief return session Bandwidth lines + * + * @return Bandwidth lines + **/ + std::list<Bandwidth>& bandwidths() {return mBandwidths;} + /** @brief return session Time lines + * + * @return Time lines + **/ + const std::list<Time>& getTimes() const {return mTimes;} + /** @brief return session Time lines + * + * @return Time lines + **/ + std::list<Time>& getTimes() {return mTimes;} + const Timezones& getTimezones() const {return mTimezones;} + const Encryption& getEncryption() const {return mEncryption;} + const Encryption& encryption() const {return mEncryption;} + Encryption& encryption() {return mEncryption;} + typedef std::list<Medium> MediumContainer; + /** @brief return session Media lines + * + * @return Media lines + **/ + const MediumContainer& media() const {return mMedia;} + /** @brief return session Media lines + * + * @return Media lines + **/ + MediumContainer& media() {return mMedia;} + + /** @brief add an e= (email) line to session + * + * @param email Email line to add + * + **/ + void addEmail(const Email& email); + /** @brief add a p= (phone number) line to session + * + * @param phone Phone line to add + * + **/ + void addPhone(const Phone& phone); + /** @brief add a b= (Bandwidth) line to session + * + * @param bandwidth Bandwidth line to add + * + **/ + void addBandwidth(const Bandwidth& bandwidth); + /** @brief add a t= (Time) line to session + * + * @param t Time line to add + * + **/ + void addTime(const Time& t); + /** @brief add an m= (Medium) section to session + * + * @param medium Medium section to add + * + **/ + void addMedium(const Medium& medium); + /** @brief remove all Medium sections from session + * + **/ + void clearMedium() { mMedia.clear(); } + /** @brief erase all attributes for a given key + * + * @param key key to clear + * + **/ + void clearAttribute(const Data& key); + /** @brief add a session attribute line + * + * @param key attribute key + * @param value attribute value + * + **/ + void addAttribute(const Data& key, const Data& value = Data::Empty); + /** @brief tests if an a= key is present in the session + * + * @param key key to check + * + * @return true if key exists, false otherwise + **/ + bool exists(const Data& key) const; + /** @brief get the attribute values corresponding to the key + * + * @param key key to check + * + * @return list of values for given key + **/ + const std::list<Data>& getValues(const Data& key) const; + + private: + int mVersion; + Origin mOrigin; + Data mName; + MediumContainer mMedia; + + // applies to all Media where unspecified + Data mInformation; + Uri mUri; + std::list<Email> mEmails; + std::list<Phone> mPhones; + Connection mConnection; + std::list<Bandwidth> mBandwidths; + std::list<Time> mTimes; + Timezones mTimezones; + Encryption mEncryption; + AttributeHelper mAttributeHelper; + + friend class SdpContents; + }; + + SdpContents(); + SdpContents(const HeaderFieldValue& hfv, const Mime& contentTypes); + virtual ~SdpContents(); + + // !nash! there is no need for overriding copy ctor as every members gets copied + //SdpContents(const SdpContents& rhs); + SdpContents& operator=(const SdpContents& rhs); + + /** @brief duplicate an SdpContents object + * + * @return pointer to a new SdpContents object + **/ + virtual Contents* clone() const; + + /** @brief get the parsed SDP + * + * @return parsed SDP object + **/ + Session& session() {checkParsed(); return mSession;} + const Session& session() const {checkParsed(); return mSession;} + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + static const Mime& getStaticType() ; + + static bool init(); + + private: + SdpContents(const Data& data, const Mime& contentTypes); + Session mSession; +}; + +static bool invokeSdpContentsInit = SdpContents::init(); + +typedef SdpContents::Session::Codec Codec; + +bool operator==(const SdpContents::Session::Codec& lhs, + const SdpContents::Session::Codec& rhs); + +EncodeStream& operator<<(EncodeStream& str, const SdpContents::Session::Codec& codec); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/SecurityAttributes.cxx b/src/libs/resiprocate/resip/stack/SecurityAttributes.cxx new file mode 100644 index 00000000..0d09ad36 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SecurityAttributes.cxx @@ -0,0 +1,95 @@ +#include "resip/stack/SecurityAttributes.hxx" + +using namespace resip; + +SecurityAttributes::SecurityAttributes() : + + mIsEncrypted(false), + mSigStatus(SignatureNone), + mStrength(From), + mLevel(None), + mEncryptionPerformed(false) +{} + +SecurityAttributes::~SecurityAttributes() +{}; + +EncodeStream& +resip::operator<<(EncodeStream& strm, const SecurityAttributes& sa) +{ + const char* strengthText[] = + { + "From", "IdentityFailed", "Identity" + }; + + const char* sigstatusText[] = + { + "None", "Bad", "Trusted", "CA Trusted", "Untrusted", "Self-signed" + }; + + const char* encryptionLevelText[] = + { + "None", "Sign", "Encrypt", "SignAndEncrypt" + }; + + strm << "SecurityAttributes: identity=" << sa.mIdentity + << " strength=" << strengthText[sa.mStrength] + << " encrypted=" << Data(sa.mIsEncrypted) + << " status=" << sigstatusText[sa.mSigStatus] + << " signer=" << sa.mSigner + << " encryption level for outgoing message=" << encryptionLevelText[sa.mLevel] + << " encryption performed=" << Data(sa.mEncryptionPerformed); + + return strm; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/SecurityAttributes.hxx b/src/libs/resiprocate/resip/stack/SecurityAttributes.hxx new file mode 100644 index 00000000..2414e34a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SecurityAttributes.hxx @@ -0,0 +1,165 @@ +#ifndef RESIP_SecurityAttributes_hxx +#define RESIP_SecurityAttributes_hxx + +#include <iostream> + +#include "rutil/Data.hxx" + +namespace resip +{ + +enum SignatureStatus +{ + SignatureNone, // there is no signature + SignatureIsBad, + SignatureTrusted, // It is signed with trusted signature + SignatureCATrusted, // signature is new and is signed by a root we trust + SignatureNotTrusted, // signature is new and is not signed by a CA we + SignatureSelfSigned +}; + +class SecurityAttributes +{ + public: + SecurityAttributes(); + ~SecurityAttributes(); + + typedef enum {None, Sign, Encrypt, SignAndEncrypt} OutgoingEncryptionLevel; + + typedef enum {From, FailedIdentity, Identity} IdentityStrength; + + SignatureStatus getSignatureStatus() const + { + return mSigStatus; + } + + bool isEncrypted() const + { + return mIsEncrypted; + } + void setEncrypted() + { + mIsEncrypted = true; + } + + void setSignatureStatus(SignatureStatus status) + { + mSigStatus = status; + } + + void setIdentity(const Data& identity) + { + mIdentity = identity; + } + + const Data& getIdentity() const + { + return mIdentity; + } + + void setIdentityStrength(IdentityStrength strength) + { + mStrength = strength; + } + + IdentityStrength getIdentityStrength() const + { + return mStrength; + } + + void setSigner(const Data& signer) + { + mSigner = signer; + } + + const Data& getSigner() const + { + return mSigner; + } + + OutgoingEncryptionLevel getOutgoingEncryptionLevel() const + { + return mLevel; + } + + void setOutgoingEncryptionLevel(OutgoingEncryptionLevel level) + { + mLevel = level; + } + + bool encryptionPerformed() const + { + return mEncryptionPerformed; + } + + void setEncryptionPerformed(bool performed) + { + mEncryptionPerformed = performed; + } + + friend EncodeStream& operator<<(EncodeStream& strm, const SecurityAttributes& sa); + + private: + bool mIsEncrypted; + SignatureStatus mSigStatus; + Data mSigner; + Data mIdentity; + IdentityStrength mStrength; + OutgoingEncryptionLevel mLevel; // for outgoing messages. + bool mEncryptionPerformed; +}; + + EncodeStream& operator<<(EncodeStream& strm, const SecurityAttributes& sa); +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/SecurityTypes.hxx b/src/libs/resiprocate/resip/stack/SecurityTypes.hxx new file mode 100644 index 00000000..d73ccf78 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SecurityTypes.hxx @@ -0,0 +1,76 @@ +#if !defined(RESIP_SECURITY_TYPES_HXX) +#define RESIP_SECURITY_TYPES_HXX + +namespace resip +{ + +namespace SecurityTypes +{ +typedef enum +{ + SSLv23 = 1, + TLSv1 = 2 +} SSLType; + +typedef enum +{ + None, + Optional, + Mandatory +} TlsClientVerificationMode; + +}; + +}; + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/SelectInterruptor.hxx b/src/libs/resiprocate/resip/stack/SelectInterruptor.hxx new file mode 100644 index 00000000..13206c2e --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SelectInterruptor.hxx @@ -0,0 +1,126 @@ +#ifndef RESIP_SelectInterruptor_HXX +#define RESIP_SelectInterruptor_HXX + +#include "rutil/AsyncProcessHandler.hxx" +#include "rutil/Socket.hxx" + +#if 0 +#if defined(WIN32) +#include <Ws2tcpip.h> +#else +#include <netinet/in.h> +#endif +#endif + +namespace resip +{ + +/** + Used to 'artificially' interrupt a select call +*/ +class SelectInterruptor : public AsyncProcessHandler +{ + public: + SelectInterruptor(); + virtual ~SelectInterruptor(); + + /** + Called by the stack when messages are posted to it. + Calls interrupt. + */ + virtual void handleProcessNotification(); + + /** + cause the 'artificial' fd to signal + */ + void interrupt(); + + /** + Used to add the 'artificial' fd to the fdset that + will be responsible for interrupting a subsequent select + call. + */ + void buildFdSet(FdSet& fdset); + + /** + cleanup signalled fd + */ + void process(FdSet& fdset); + protected: + /* Get fd of read-side, for use within PollInterruptor, + * Declared as Socket for easier cross-platform even though pipe fd + * under linux. + */ + Socket getReadSocket() const { return mReadThing; } + + /* Cleanup the read side of the interruptor + * If fdset is provided, it will only try cleaning up if our pipe + * is ready in fdset. If NULL, it will unconditionally try reading. + * This last feature is for use within PollInterruptor. + */ + void processCleanup(); + private: +#ifndef WIN32 + int mPipe[2]; +#else + Socket mSocket; + sockaddr mWakeupAddr; +#endif + // either mPipe[0] or mSocket + Socket mReadThing; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/SendData.hxx b/src/libs/resiprocate/resip/stack/SendData.hxx new file mode 100644 index 00000000..c4de3db9 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SendData.hxx @@ -0,0 +1,128 @@ +#ifndef RESIP_SendData_HXX +#define RESIP_SendData_HXX + +#include "rutil/Data.hxx" +#include "resip/stack/Tuple.hxx" + +namespace resip +{ + +/** + @internal +*/ +class SendData +{ + public: + enum SendDataCommand + { + NoCommand, + CloseConnection, + EnableFlowTimer + }; + + SendData() : isAlreadyCompressed(false), command(NoCommand) + {} + + SendData(const Tuple& dest, + const Data& pdata, + const Data& tid, + const Data& scid, + bool isCompressed = false): + destination(dest), + data(pdata), + transactionId(tid), + sigcompId(scid), + isAlreadyCompressed(isCompressed), + command(NoCommand) + { + } + + // This interface is only used for stun responses + SendData(const Tuple& dest, char* buffer, int length) : + destination(dest), + data(Data::Take, buffer, length), + transactionId(Data::Empty), + sigcompId(Data::Empty), + isAlreadyCompressed(false), + command(NoCommand) + { + } + + SendData* clone() const + { + return new SendData(*this); + } + + void clear() + { + data.clear(); + } + + bool empty() const + { + return data.empty(); + } + + Tuple destination; + Data data; + Data transactionId; + Data sigcompId; + bool isAlreadyCompressed; + + // .bwc. Used for special commands: ie. to close connections, and enable flow timers + SendDataCommand command; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ShutdownMessage.hxx b/src/libs/resiprocate/resip/stack/ShutdownMessage.hxx new file mode 100644 index 00000000..938119ea --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ShutdownMessage.hxx @@ -0,0 +1,68 @@ +#ifndef RESIP_ShutdownMessage_hxx +#define RESIP_ShutdownMessage_hxx + +#include "resip/stack/ApplicationMessage.hxx" + +namespace resip +{ + +class ShutdownMessage : public ApplicationMessage +{ + public: + ShutdownMessage() {}; + + virtual Message* clone() const { return new ShutdownMessage; } + virtual EncodeStream& encode(EncodeStream& strm) const { return strm << brief(); } + virtual EncodeStream& encodeBrief(EncodeStream& str) const { return str << "Shutdown"; } +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/SipFrag.cxx b/src/libs/resiprocate/resip/stack/SipFrag.cxx new file mode 100644 index 00000000..4235913c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SipFrag.cxx @@ -0,0 +1,301 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/MsgHeaderScanner.hxx" +#include "resip/stack/SipFrag.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +bool +SipFrag::init() +{ + static ContentsFactory<SipFrag> factory; + (void)factory; + return true; +} + +SipFrag::SipFrag(const Mime& contentsType) + : Contents(contentsType), + mMessage(new SipMessage()) +{} + +SipFrag::SipFrag(const HeaderFieldValue& hfv, const Mime& contentsType) + : Contents(hfv, HeaderFieldValue::CopyPadding, contentsType), + mMessage(0) +{ +} + +SipFrag::SipFrag(const SipFrag& rhs) + : Contents(rhs,HeaderFieldValue::CopyPadding), + mMessage(rhs.mMessage ? new SipMessage(*rhs.mMessage) : 0) +{ +} + +SipFrag::~SipFrag() +{ + delete mMessage; +} + +SipFrag& +SipFrag::operator=(const SipFrag& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + delete mMessage; + if (rhs.mMessage) + { + mMessage = new SipMessage(*rhs.mMessage); + } + else + { + mMessage = 0; + } + } + + return *this; +} + +Contents* +SipFrag::clone() const +{ + return new SipFrag(*this); +} + +const Mime& +SipFrag::getStaticType() +{ + static Mime type("message", "sipfrag"); + //static Mime type("application", "sipfrag"); + return type; +} + +SipMessage& +SipFrag::message() +{ + checkParsed(); + return *mMessage; +} + +const SipMessage& +SipFrag::message() const +{ + checkParsed(); + return *mMessage; +} + +EncodeStream& +SipFrag::encodeParsed(EncodeStream& str) const +{ + mMessage->encodeSipFrag(str); + + return str; +} + +bool +SipFrag::hasStartLine(char* buffer, int size) +{ +#if 0 + //!dcm! -- this probably inefficient, but the SIP grammer makes this very + //difficult. Better here than in the MsgHeaderScanner. There's also proabably a + //way to make a header that matches the requestLine check which isn't a + //request line. + + ParseBuffer pbCheck(buffer, size); + pbCheck.skipWhitespace(); //gratuitous? + + //!dcm! -- could extend to SIP/2.0, but nobody should start a hname with SIP/ + if ((pbCheck.end() - pbCheck.position()) > 4 && + strncmp(pbCheck.position(), "SIP/", 4) == 0) + { + return true; + } + else + { + pbCheck.skipToChars(Symbols::CRLF); + if (pbCheck.eof()) + { + //false positive, let MsgHeaderScanner sort the exact error out + return true; + } + + pbCheck.skipBackToChar(Symbols::SPACE[0]); + if (pbCheck.position() == pbCheck.start()) + { + return false; + } + + if ((pbCheck.end() - pbCheck.position()) > 4 && + strncmp(pbCheck.position(), "SIP/", 4) == 0) + { + return true; + } + else + { + return false; + } + } +#else + //!dcm! -- better approach, remove above if this is proven to be correct + ParseBuffer pbCheck(buffer, size); + pbCheck.skipWhitespace(); //gratuitous? + pbCheck.skipToOneOf(" \t:\r\n"); + while(!pbCheck.eof()) + { + switch(*pbCheck.position()) + { + case ':': + return false; + case ' ': + case '\t': + pbCheck.skipChar(); + break; + case '\r': + case '\n': + return false; + default: + return true; + } + } + return true; //false positive, let MsgHeaderScanner sort the exact error out +#endif +} + +void +SipFrag::parse(ParseBuffer& pb) +{ +// DebugLog(<< "SipFrag::parse: " << pb.position()); + + mMessage = new SipMessage(); + + pb.assertNotEof(); + const char *constBuffer = pb.position(); + char *buffer = const_cast<char *>(constBuffer); + + size_t size = pb.end() - pb.position(); + + // !ah! removed size check .. process() cannot process more + // than size bytes of the message. + + + MsgHeaderScanner msgHeaderScanner; + msgHeaderScanner.prepareForFrag(mMessage, hasStartLine(buffer, (int)size)); + enum { sentinelLength = 4 }; // Two carriage return / line feed pairs. + //char saveTermCharArray[sentinelLength]; + static const char* sentinel="\r\n\r\n"; + char *termCharArray = buffer + size; + memcpy(scratchpad,termCharArray,4); + + /*saveTermCharArray[0] = termCharArray[0]; + saveTermCharArray[1] = termCharArray[1]; + saveTermCharArray[2] = termCharArray[2]; + saveTermCharArray[3] = termCharArray[3];*/ + + memcpy(termCharArray,sentinel,4); + /*termCharArray[0] = '\r'; + termCharArray[1] = '\n'; + termCharArray[2] = '\r'; + termCharArray[3] = '\n';*/ + char *scanTermCharPtr; + MsgHeaderScanner::ScanChunkResult scanChunkResult = + msgHeaderScanner.scanChunk(buffer, + (unsigned int)(size + sentinelLength), + &scanTermCharPtr); + + memcpy(termCharArray,scratchpad,4); + /*termCharArray[0] = saveTermCharArray[0]; + termCharArray[1] = saveTermCharArray[1]; + termCharArray[2] = saveTermCharArray[2]; + termCharArray[3] = saveTermCharArray[3];*/ + + // !dlb! not at all clear what to do here + // see: "// tests end of message problem (MsgHeaderScanner?)" + // in test/testSipFrag.cxx + if (false && scanChunkResult != MsgHeaderScanner::scrEnd) + { + CerrLog(<< "not MsgHeaderScanner::scrEnd"); + pb.fail(__FILE__, __LINE__); + } + else + { + size_t used = scanTermCharPtr - buffer; + + // !ah! I think this is broken .. if we are UDP then the + // remainder is the SigFrag, not the Content-Length... ?? + if (mMessage->exists(h_ContentLength)) + { + mMessage->setBody(scanTermCharPtr, + static_cast<int>(size - used)); + } + else + { + // !ah! So the headers weren't complete. Why are we here? + // !dlb! + if (mMessage->exists(h_ContentLength)) + { + pb.reset(buffer + used); + pb.skipChars(Symbols::CRLF); + mMessage->setBody(pb.position(),int(pb.end()-pb.position()) ); + } + } + pb.reset(pb.end()); + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/SipFrag.hxx b/src/libs/resiprocate/resip/stack/SipFrag.hxx new file mode 100644 index 00000000..b8d6c792 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SipFrag.hxx @@ -0,0 +1,106 @@ +#if !defined(RESIP_SIPFRAG_HXX) +#define RESIP_SIPFRAG_HXX + +#include <map> + +#include "resip/stack/Contents.hxx" +#include "resip/stack/Uri.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +class SipMessage; + +// Mostly works -- +// Preparse insists on a start line while SIP frag may not have one. +/** + @ingroup sip_payload + @brief SIP body type for holding SipFrag contents (MIME content-type message/sipfrag). +*/ +class SipFrag : public Contents +{ + public: + SipFrag(const Mime& contentsType = getStaticType()); + SipFrag(const HeaderFieldValue& hfv, const Mime& contentsType); + SipFrag(const Data& data, const Mime& contentsType); + SipFrag(const SipFrag& rhs); + virtual ~SipFrag(); + SipFrag& operator=(const SipFrag& rhs); + + /** @brief duplicate an SipFrag object + @return pointer to a new SipFrag object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType() ; + + SipMessage& message(); + const SipMessage& message() const; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + static bool init(); + + private: + bool hasStartLine(char* buffer, int size); + SipMessage* mMessage; + char scratchpad[4]; +}; + +static bool invokeSipFragInit = SipFrag::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/SipMessage.cxx b/src/libs/resiprocate/resip/stack/SipMessage.cxx new file mode 100644 index 00000000..7f944810 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SipMessage.cxx @@ -0,0 +1,1817 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Contents.hxx" +#include "resip/stack/Embedded.hxx" +#include "resip/stack/OctetContents.hxx" +#include "resip/stack/HeaderFieldValueList.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/ExtensionHeader.hxx" +#include "rutil/Coders.hxx" +#include "rutil/CountStream.hxx" +#include "rutil/Logger.hxx" +#include "rutil/MD5Stream.hxx" +#include "rutil/compat.hxx" +#include "rutil/vmd5.hxx" +#include "rutil/Coders.hxx" +#include "rutil/Random.hxx" +#include "rutil/ParseBuffer.hxx" +#include "resip/stack/MsgHeaderScanner.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +bool SipMessage::checkContentLength=true; + +SipMessage::SipMessage(const Transport* fromWire) + : mIsDecorated(false), + mIsBadAck200(false), + mIsExternal(fromWire != 0), + mHeaders(StlPoolAllocator<HeaderFieldValueList*, PoolBase >(&mPool)), +#ifndef __SUNPRO_CC + mUnknownHeaders(StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase >(&mPool)), +#else + mUnknownHeaders(), +#endif + mTransport(fromWire), + mRFC2543TransactionId(), + mRequest(false), + mResponse(false), + mInvalid(false), + mCreatedTime(Timer::getTimeMicroSec()), + mTlsDomain(Data::Empty) +{ + // !bwc! TODO make this tunable + mHeaders.reserve(16); + clear(); +} + +SipMessage::SipMessage(const SipMessage& from) + : mHeaders(StlPoolAllocator<HeaderFieldValueList*, PoolBase >(&mPool)), +#ifndef __SUNPRO_CC + mUnknownHeaders(StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase >(&mPool)), +#else + mUnknownHeaders(), +#endif + mCreatedTime(Timer::getTimeMicroSec()) +{ + init(from); +} + +Message* +SipMessage::clone() const +{ + return new SipMessage(*this); +} + +SipMessage& +SipMessage::operator=(const SipMessage& rhs) +{ + if (this != &rhs) + { + freeMem(); + init(rhs); + } + return *this; +} + +SipMessage::~SipMessage() +{ + freeMem(); +} + +void +SipMessage::clear(bool leaveResponseStuff) +{ + if(!leaveResponseStuff) + { + memset(mHeaderIndices,0,sizeof(mHeaderIndices)); + mHeaders.clear(); + + // !bwc! The "invalid" 0 index. + mHeaders.push_back(getEmptyHfvl()); + mBufferList.clear(); + } + + mUnknownHeaders.clear(); + + mStartLine = 0; + mContents = 0; + mContentsHfv.clear(); + mForceTarget = 0; + mReason=0; + mOutboundDecorators.clear(); +} + +void +SipMessage::init(const SipMessage& rhs) +{ + clear(); + mIsDecorated = rhs.mIsDecorated; + mIsBadAck200 = rhs.mIsBadAck200; + mIsExternal = rhs.mIsExternal; + mTransport = rhs.mTransport; + mSource = rhs.mSource; + mDestination = rhs.mDestination; + mRFC2543TransactionId = rhs.mRFC2543TransactionId; + mRequest = rhs.mRequest; + mResponse = rhs.mResponse; + mInvalid = rhs.mInvalid; + if(!rhs.mReason) + { + mReason=0; + } + else + { + mReason = new Data(*rhs.mReason); + } + mTlsDomain = rhs.mTlsDomain; + + memcpy(&mHeaderIndices,&rhs.mHeaderIndices,sizeof(mHeaderIndices)); + + // .bwc. Clear out the pesky invalid 0 index. + mHeaders.clear(); + mHeaders.reserve(rhs.mHeaders.size()); + for (TypedHeaders::const_iterator i = rhs.mHeaders.begin(); + i != rhs.mHeaders.end(); i++) + { + mHeaders.push_back(getCopyHfvl(**i)); + } + + for (UnknownHeaders::const_iterator i = rhs.mUnknownHeaders.begin(); + i != rhs.mUnknownHeaders.end(); i++) + { + mUnknownHeaders.push_back(pair<Data, HeaderFieldValueList*>( + i->first, + getCopyHfvl(*i->second))); + } + if (rhs.mStartLine != 0) + { + mStartLine = rhs.mStartLine->clone(mStartLineMem); + } + if (rhs.mContents != 0) + { + mContents = rhs.mContents->clone(); + } + else if (rhs.mContentsHfv.getBuffer() != 0) + { + mContentsHfv.copyWithPadding(rhs.mContentsHfv); + } + else + { + // no body to copy + } + if (rhs.mForceTarget != 0) + { + mForceTarget = new Uri(*rhs.mForceTarget); + } + + if (rhs.mSecurityAttributes.get()) + { + + if (!mSecurityAttributes.get()) + { + SecurityAttributes* attr = new SecurityAttributes(); + mSecurityAttributes.reset(attr); + } + + if (rhs.mSecurityAttributes->isEncrypted()) + { + mSecurityAttributes->setEncrypted(); + } + mSecurityAttributes->setSignatureStatus(rhs.mSecurityAttributes->getSignatureStatus()); + mSecurityAttributes->setIdentity(rhs.mSecurityAttributes->getIdentity()); + mSecurityAttributes->setIdentityStrength(rhs.mSecurityAttributes->getIdentityStrength()); + mSecurityAttributes->setSigner(rhs.mSecurityAttributes->getSigner()); + mSecurityAttributes->setOutgoingEncryptionLevel(rhs.mSecurityAttributes->getOutgoingEncryptionLevel()); + mSecurityAttributes->setEncryptionPerformed(rhs.mSecurityAttributes->encryptionPerformed()); + } + else + { + if (mSecurityAttributes.get()) + { + mSecurityAttributes.reset(); + } + } + + for(std::vector<MessageDecorator*>::const_iterator i=rhs.mOutboundDecorators.begin(); i!=rhs.mOutboundDecorators.end();++i) + { + mOutboundDecorators.push_back((*i)->clone()); + } +} + +void +SipMessage::freeMem(bool leaveResponseStuff) +{ + for (UnknownHeaders::iterator i = mUnknownHeaders.begin(); + i != mUnknownHeaders.end(); i++) + { + freeHfvl(i->second); + } + + if(!leaveResponseStuff) + { + for (TypedHeaders::iterator i = mHeaders.begin(); + i != mHeaders.end(); i++) + { + freeHfvl(*i); + } + mHeaders.clear(); + + for (vector<char*>::iterator i = mBufferList.begin(); + i != mBufferList.end(); i++) + { + delete [] *i; + } + } + + if(mStartLine) + { + mStartLine->~StartLine(); + mStartLine=0; + } + + delete mContents; + delete mForceTarget; + delete mReason; + + for(std::vector<MessageDecorator*>::iterator i=mOutboundDecorators.begin(); + i!=mOutboundDecorators.end();++i) + { + delete *i; + } +} + +SipMessage* +SipMessage::make(const Data& data, bool isExternal) +{ + Transport* external = (Transport*)(0xFFFF); + SipMessage* msg = new SipMessage(isExternal ? external : 0); + + size_t len = data.size(); + char *buffer = new char[len + 5]; + + msg->addBuffer(buffer); + memcpy(buffer,data.data(), len); + MsgHeaderScanner msgHeaderScanner; + msgHeaderScanner.prepareForMessage(msg); + + char *unprocessedCharPtr; + if (msgHeaderScanner.scanChunk(buffer, (unsigned int)len, &unprocessedCharPtr) != MsgHeaderScanner::scrEnd) + { + DebugLog(<<"Scanner rejecting buffer as unparsable / fragmented."); + DebugLog(<< data); + delete msg; + msg = 0; + return 0; + } + + // no pp error + unsigned int used = (unsigned int)(unprocessedCharPtr - buffer); + + if (used < len) + { + // body is present .. add it up. + // NB. The Sip Message uses an overlay (again) + // for the body. It ALSO expects that the body + // will be contiguous (of course). + // it doesn't need a new buffer in UDP b/c there + // will only be one datagram per buffer. (1:1 strict) + + msg->setBody(buffer+used,UInt32(len-used)); + //DebugLog(<<"added " << len-used << " byte body"); + } + + return msg; +} + +void +SipMessage::parseAllHeaders() +{ + for (int i = 0; i < Headers::MAX_HEADERS; i++) + { + ParserContainerBase* pc=0; + if(mHeaderIndices[i]>0) + { + HeaderFieldValueList* hfvl = ensureHeaders((Headers::Type)i); + if(!Headers::isMulti((Headers::Type)i) && hfvl->parsedEmpty()) + { + hfvl->push_back(0,0,false); + } + + if(!(pc=hfvl->getParserContainer())) + { + pc = HeaderBase::getInstance((Headers::Type)i)->makeContainer(hfvl); + hfvl->setParserContainer(pc); + } + + pc->parseAll(); + } + } + + for (UnknownHeaders::iterator i = mUnknownHeaders.begin(); + i != mUnknownHeaders.end(); i++) + { + ParserContainerBase* scs=0; + if(!(scs=i->second->getParserContainer())) + { + scs=makeParserContainer<StringCategory>(i->second,Headers::RESIP_DO_NOT_USE); + i->second->setParserContainer(scs); + } + + scs->parseAll(); + } + + assert(mStartLine); + + mStartLine->checkParsed(); + + getContents(); +} + +const Data& +SipMessage::getTransactionId() const +{ + if (empty(h_Vias)) + { + InfoLog (<< "Bad message with no Vias: " << *this); + throw Exception("No Via in message", __FILE__,__LINE__); + } + + assert(exists(h_Vias) && !header(h_Vias).empty()); + if( exists(h_Vias) && header(h_Vias).front().exists(p_branch) + && header(h_Vias).front().param(p_branch).hasMagicCookie() + && (!header(h_Vias).front().param(p_branch).getTransactionId().empty()) + ) + { + return header(h_Vias).front().param(p_branch).getTransactionId(); + } + else + { + if (mRFC2543TransactionId.empty()) + { + compute2543TransactionHash(); + } + return mRFC2543TransactionId; + } +} + +void +SipMessage::compute2543TransactionHash() const +{ + assert (mRFC2543TransactionId.empty()); + + /* From rfc3261, 17.2.3 + The INVITE request matches a transaction if the Request-URI, To tag, + From tag, Call-ID, CSeq, and top Via header field match those of the + INVITE request which created the transaction. In this case, the + INVITE is a retransmission of the original one that created the + transaction. + + The ACK request matches a transaction if the Request-URI, From tag, + Call-ID, CSeq number (not the method), and top Via header field match + those of the INVITE request which created the transaction, and the To + tag of the ACK matches the To tag of the response sent by the server + transaction. + + Matching is done based on the matching rules defined for each of those + header fields. Inclusion of the tag in the To header field in the ACK + matching process helps disambiguate ACK for 2xx from ACK for other + responses at a proxy, which may have forwarded both responses (This + can occur in unusual conditions. Specifically, when a proxy forked a + request, and then crashes, the responses may be delivered to another + proxy, which might end up forwarding multiple responses upstream). An + ACK request that matches an INVITE transaction matched by a previous + ACK is considered a retransmission of that previous ACK. + + For all other request methods, a request is matched to a transaction + if the Request-URI, To tag, From tag, Call-ID, CSeq (including the + method), and top Via header field match those of the request that + created the transaction. Matching is done based on the matching + */ + + // If it is here and isn't a request, leave the transactionId empty, this + // will cause the Transaction to send it statelessly + + if (isRequest()) + { + MD5Stream strm; + // See section 17.2.3 Matching Requests to Server Transactions in rfc 3261 + +//#define VONAGE_FIX +#ifndef VONAGE_FIX + strm << header(h_RequestLine).uri().scheme(); + strm << header(h_RequestLine).uri().user(); + strm << header(h_RequestLine).uri().host(); + strm << header(h_RequestLine).uri().port(); + strm << header(h_RequestLine).uri().password(); + strm << header(h_RequestLine).uri().commutativeParameterHash(); +#endif + if (!empty(h_Vias)) + { + strm << header(h_Vias).front().protocolName(); + strm << header(h_Vias).front().protocolVersion(); + strm << header(h_Vias).front().transport(); + strm << header(h_Vias).front().sentHost(); + strm << header(h_Vias).front().sentPort(); + strm << header(h_Vias).front().commutativeParameterHash(); + } + + if (header(h_From).exists(p_tag)) + { + strm << header(h_From).param(p_tag); + } + + // Only include the totag for non-invite requests + if (header(h_RequestLine).getMethod() != INVITE && + header(h_RequestLine).getMethod() != ACK && + header(h_RequestLine).getMethod() != CANCEL && + header(h_To).exists(p_tag)) + { + strm << header(h_To).param(p_tag); + } + + strm << header(h_CallID).value(); + + if (header(h_RequestLine).getMethod() == ACK || + header(h_RequestLine).getMethod() == CANCEL) + { + strm << INVITE; + strm << header(h_CSeq).sequence(); + } + else + { + strm << header(h_CSeq).method(); + strm << header(h_CSeq).sequence(); + } + + mRFC2543TransactionId = strm.getHex(); + } + else + { + InfoLog (<< "Trying to compute a transaction id on a 2543 response. Drop the response"); + DebugLog (<< *this); + throw Exception("Drop invalid 2543 response", __FILE__, __LINE__); + } +} + +const Data& +SipMessage::getRFC2543TransactionId() const +{ + if(empty(h_Vias) || + !header(h_Vias).front().exists(p_branch) || + !header(h_Vias).front().param(p_branch).hasMagicCookie() || + header(h_Vias).front().param(p_branch).getTransactionId().empty()) + { + if (mRFC2543TransactionId.empty()) + { + compute2543TransactionHash(); + } + } + return mRFC2543TransactionId; +} + + +Data +SipMessage::getCanonicalIdentityString() const +{ + Data result; + DataStream strm(result); + + // digest-string = addr-spec ":" addr-spec ":" callid ":" 1*DIGIT SP method ":" + // SIP-Date ":" [ addr-spec ] ":" message-body + + strm << header(h_From).uri(); + strm << Symbols::BAR; + + strm << header(h_To).uri(); + strm << Symbols::BAR; + + strm << header(h_CallId).value(); + strm << Symbols::BAR; + + header(h_CSeq).sequence(); // force parsed + header(h_CSeq).encodeParsed( strm ); + strm << Symbols::BAR; + + // if there is no date, it will throw + if ( empty(h_Date) ) + { + WarningLog( << "Computing Identity on message with no Date header" ); + // TODO FIX - should it have a throw here ???? Help ??? + } + header(h_Date).dayOfMonth(); // force it to be parsed + header(h_Date).encodeParsed( strm ); + strm << Symbols::BAR; + + if ( !empty(h_Contacts) ) + { + if ( header(h_Contacts).front().isAllContacts() ) + { + strm << Symbols::STAR; + } + else + { + strm << header(h_Contacts).front().uri(); + } + } + strm << Symbols::BAR; + + // bodies + if (mContents != 0) + { + mContents->encode(strm); + } + else if (mContentsHfv.getBuffer() != 0) + { + mContentsHfv.encode(strm); + } + + strm.flush(); + + DebugLog( << "Indentity Canonical String is: " << result ); + + return result; +} + + +void +SipMessage::setRFC2543TransactionId(const Data& tid) +{ + mRFC2543TransactionId = tid; +} + +resip::MethodTypes +SipMessage::method() const +{ + resip::MethodTypes res=UNKNOWN; + try + { + if(isRequest()) + { + res=header(h_RequestLine).getMethod(); + } + else if(isResponse()) + { + res=header(h_CSeq).method(); + } + else + { + assert(0); + } + } + catch(resip::ParseException&) + { + } + + return res; +} + +const Data& +SipMessage::methodStr() const +{ + if(method()!=UNKNOWN) + { + return getMethodName(method()); + } + else + { + try + { + if(isRequest()) + { + return header(h_RequestLine).unknownMethodName(); + } + else if(isResponse()) + { + return header(h_CSeq).unknownMethodName(); + } + else + { + assert(0); + } + } + catch(resip::ParseException&) + { + } + } + return Data::Empty; +} + +static const Data requestEB("SipReq: "); +static const Data responseEB("SipResp: "); +static const Data tidEB(" tid="); +static const Data contactEB(" contact="); +static const Data cseqEB(" cseq="); +static const Data slashEB(" / "); +static const Data wireEB(" from(wire)"); +static const Data ftuEB(" from(tu)"); +static const Data tlsdEB(" tlsd="); +EncodeStream& +SipMessage::encodeBrief(EncodeStream& str) const +{ + if (isRequest()) + { + str << requestEB; + MethodTypes meth = header(h_RequestLine).getMethod(); + if (meth != UNKNOWN) + { + str << getMethodName(meth); + } + else + { + str << header(h_RequestLine).unknownMethodName(); + } + + str << Symbols::SPACE; + str << header(h_RequestLine).uri().getAor(); + } + else if (isResponse()) + { + str << responseEB; + str << header(h_StatusLine).responseCode(); + } + if (!empty(h_Vias)) + { + str << tidEB; + try + { + str << getTransactionId(); + } + catch(SipMessage::Exception&) + { + str << "BAD-VIA"; + } + } + else + { + str << " NO-VIAS "; + } + + str << cseqEB; + str << header(h_CSeq); + + try + { + if (!empty(h_Contacts)) + { + str << contactEB; + str << header(h_Contacts).front().uri().getAor(); + } + } + catch(resip::ParseException&) + { + str << " MALFORMED CONTACT "; + } + + str << slashEB; + str << header(h_CSeq).sequence(); + str << (mIsExternal ? wireEB : ftuEB); + if (!mTlsDomain.empty()) + { + str << tlsdEB << mTlsDomain; + } + + return str; +} + +bool +SipMessage::isClientTransaction() const +{ + assert(mRequest || mResponse); + return ((mIsExternal && mResponse) || (!mIsExternal && mRequest)); +} + +EncodeStream& +SipMessage::encode(EncodeStream& str) const +{ + return encode(str, false); +} + +EncodeStream& +SipMessage::encodeSipFrag(EncodeStream& str) const +{ + return encode(str, true); +} + +// dynamic_cast &str to DataStream* to avoid CountStream? + +EncodeStream& +SipMessage::encode(EncodeStream& str, bool isSipFrag) const +{ + if (mStartLine != 0) + { + mStartLine->encode(str); + str << "\r\n"; + } + + Data contents; + if (mContents != 0) + { + oDataStream temp(contents); + mContents->encode(temp); + } + else if (mContentsHfv.getBuffer() != 0) + { +#if 0 + // !bwc! This causes an additional copy; sure would be nice to have a way + // to get a data to take on a buffer with Data::Share _after_ construction + contents.append(mContentsHfv.getBuffer(), mContentsHfv.getLength()); +#else + // .kw. Your wish is granted + mContentsHfv.toShareData(contents); +#endif + } + + for (UInt8 i = 0; i < Headers::MAX_HEADERS; i++) + { + if (i != Headers::ContentLength) // !dlb! hack... + { + if (mHeaderIndices[i] > 0) + { + mHeaders[mHeaderIndices[i]]->encode(i, str); + } + } + } + + for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin(); + i != mUnknownHeaders.end(); i++) + { + i->second->encode(i->first, str); + } + + if(!isSipFrag || !contents.empty()) + { + str << "Content-Length: " << contents.size() << "\r\n"; + } + + str << Symbols::CRLF; + + str << contents; + return str; +} + +EncodeStream& +SipMessage::encodeSingleHeader(Headers::Type type, EncodeStream& str) const +{ + if (mHeaderIndices[type] > 0) + { + mHeaders[mHeaderIndices[type]]->encode(type, str); + } + return str; +} + +EncodeStream& +SipMessage::encodeEmbedded(EncodeStream& str) const +{ + bool first = true; + for (UInt8 i = 0; i < Headers::MAX_HEADERS; i++) + { + if (i != Headers::ContentLength) + { + if (mHeaderIndices[i] > 0) + { + if (first) + { + str << Symbols::QUESTION; + first = false; + } + else + { + str << Symbols::AMPERSAND; + } + mHeaders[mHeaderIndices[i]]->encodeEmbedded(Headers::getHeaderName(i), str); + } + } + } + + for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin(); + i != mUnknownHeaders.end(); i++) + { + if (first) + { + str << Symbols::QUESTION; + first = false; + } + else + { + str << Symbols::AMPERSAND; + } + i->second->encodeEmbedded(i->first, str); + } + + if (mContents != 0 || mContentsHfv.getBuffer() != 0) + { + if (first) + { + str << Symbols::QUESTION; + } + else + { + str << Symbols::AMPERSAND; + } + str << "body="; + Data contents; + // !dlb! encode escaped for characters + // .kw. what does that mean? what needs to be escaped? + if(mContents != 0) + { + DataStream s(contents); + mContents->encode(s); + } + else + { + // .kw. Early code did: + // DataStream s(contents); + // mContentsHfv->encode(str); + // str << Embedded::encode(contents); + // .kw. which I think is buggy b/c Hfv was written directly + // to str and skipped the encode step via contents + mContentsHfv.toShareData(contents); + } + str << Embedded::encode(contents); + } + return str; +} + +void +SipMessage::addBuffer(char* buf) +{ + mBufferList.push_back(buf); +} + +void +SipMessage::setStartLine(const char* st, int len) +{ + if(len >= 4 && !strncasecmp(st,"SIP/",4)) + { + // Response + mStartLine = new (mStartLineMem) StatusLine(st, len); + //!dcm! should invoke the statusline parser here once it does limited validation + mResponse = true; + } + else + { + // Request + mStartLine = new (mStartLineMem) RequestLine(st, len); + //!dcm! should invoke the responseline parser here once it does limited validation + mRequest = true; + } + + +// .bwc. This stuff is so needlessly complicated. Much, much simpler, faster, +// and more robust code above. +// ParseBuffer pb(st, len); +// const char* start; +// start = pb.skipWhitespace(); +// pb.skipNonWhitespace(); +// MethodTypes method = getMethodType(start, pb.position() - start); +// if (method == UNKNOWN) //probably a status line +// { +// start = pb.skipChar(Symbols::SPACE[0]); +// pb.skipNonWhitespace(); +// if ((pb.position() - start) == 3) +// { +// mStartLine = new (mStartLineMem) StatusLine(st, len ,Headers::NONE); +// //!dcm! should invoke the statusline parser here once it does limited validation +// mResponse = true; +// } +// } +// if (!mResponse) +// { +// mStartLine = new (mStartLineMem) RequestLine(st, len, Headers::NONE); +// //!dcm! should invoke the responseline parser here once it does limited validation +// mRequest = true; +// } +} + +void +SipMessage::setBody(const char* start, UInt32 len) +{ + if(checkContentLength) + { + if(exists(h_ContentLength)) + { + try + { + const_header(h_ContentLength).checkParsed(); + } + catch(resip::ParseException& e) + { + if(!mReason) + { + mReason=new Data; + } + + if(mInvalid) + { + mReason->append(",",1); + } + + mInvalid=true; + mReason->append("Malformed Content-Length",24); + InfoLog(<< "Malformed Content-Length. Ignoring. " << e); + header(h_ContentLength).value()=len; + } + + UInt32 contentLength=const_header(h_ContentLength).value(); + + if(len > contentLength) + { + InfoLog(<< (len-contentLength) << " extra bytes after body. Ignoring these bytes."); + } + else if(len < contentLength) + { + InfoLog(<< "Content Length (" << contentLength << ") is " + << (contentLength-len) << " bytes larger than body (" << len << ")!" + << " (We are supposed to 400 this) "); + + if(!mReason) + { + mReason=new Data; + } + + if(mInvalid) + { + mReason->append(",",1); + } + + mInvalid=true; + mReason->append("Bad Content-Length (larger than datagram)",41); + header(h_ContentLength).value()=len; + contentLength=len; + + } + + mContentsHfv.init(start,contentLength, false); + } + else + { + InfoLog(<< "Message has a body, but no Content-Length header."); + mContentsHfv.init(start,len, false); + } + } + else + { + mContentsHfv.init(start,len, false); + } +} + +void +SipMessage::setRawBody(const HeaderFieldValue& body) +{ + setContents(0); + mContentsHfv = body; +} + + +void +SipMessage::setContents(auto_ptr<Contents> contents) +{ + Contents* contentsP = contents.release(); + + delete mContents; + mContents = 0; + mContentsHfv.clear(); + + if (contentsP == 0) + { + // The semantics of setContents(0) are to delete message contents + remove(h_ContentType); + remove(h_ContentDisposition); + remove(h_ContentTransferEncoding); + remove(h_ContentLanguages); + return; + } + + mContents = contentsP; + + // copy contents headers into message + if (mContents->exists(h_ContentDisposition)) + { + header(h_ContentDisposition) = mContents->header(h_ContentDisposition); + } + if (mContents->exists(h_ContentTransferEncoding)) + { + header(h_ContentTransferEncoding) = mContents->header(h_ContentTransferEncoding); + } + if (mContents->exists(h_ContentLanguages)) + { + header(h_ContentLanguages) = mContents->header(h_ContentLanguages); + } + if (mContents->exists(h_ContentType)) + { + header(h_ContentType) = mContents->header(h_ContentType); + assert( header(h_ContentType).type() == mContents->getType().type() ); + assert( header(h_ContentType).subType() == mContents->getType().subType() ); + } + else + { + header(h_ContentType) = mContents->getType(); + } +} + +void +SipMessage::setContents(const Contents* contents) +{ + if (contents) + { + setContents(auto_ptr<Contents>(contents->clone())); + } + else + { + setContents(auto_ptr<Contents>(0)); + } +} + +Contents* +SipMessage::getContents() const +{ + if (mContents == 0 && mContentsHfv.getBuffer() != 0) + { + if (empty(h_ContentType) || + !const_header(h_ContentType).isWellFormed()) + { + StackLog(<< "SipMessage::getContents: ContentType header does not exist - implies no contents"); + return 0; + } + DebugLog(<< "SipMessage::getContents: " + << const_header(h_ContentType).type() + << "/" + << const_header(h_ContentType).subType()); + + if ( ContentsFactoryBase::getFactoryMap().find(const_header(h_ContentType)) == ContentsFactoryBase::getFactoryMap().end() ) + { + InfoLog(<< "SipMessage::getContents: got content type (" + << const_header(h_ContentType).type() + << "/" + << const_header(h_ContentType).subType() + << ") that is not known, " + << "returning as opaque application/octet-stream"); + mContents = ContentsFactoryBase::getFactoryMap()[OctetContents::getStaticType()]->create(mContentsHfv, OctetContents::getStaticType()); + } + else + { + mContents = ContentsFactoryBase::getFactoryMap()[const_header(h_ContentType)]->create(mContentsHfv, const_header(h_ContentType)); + } + assert( mContents ); + + // copy contents headers into the contents + if (!empty(h_ContentDisposition)) + { + mContents->header(h_ContentDisposition) = const_header(h_ContentDisposition); + } + if (!empty(h_ContentTransferEncoding)) + { + mContents->header(h_ContentTransferEncoding) = const_header(h_ContentTransferEncoding); + } + if (!empty(h_ContentLanguages)) + { + mContents->header(h_ContentLanguages) = const_header(h_ContentLanguages); + } + if (!empty(h_ContentType)) + { + mContents->header(h_ContentType) = const_header(h_ContentType); + } + // !dlb! Content-Transfer-Encoding? + } + return mContents; +} + +auto_ptr<Contents> +SipMessage::releaseContents() +{ + Contents* c=getContents(); + // .bwc. auto_ptr owns the Contents. No other references allowed! + auto_ptr<Contents> ret(c ? c->clone() : 0); + setContents(std::auto_ptr<Contents>(0)); + + if (ret.get() != 0 && !ret->isWellFormed()) + { + ret.reset(0); + } + + return ret; +} + +// unknown header interface +const StringCategories& +SipMessage::header(const ExtensionHeader& headerName) const +{ + for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin(); + i != mUnknownHeaders.end(); i++) + { + if (isEqualNoCase(i->first, headerName.getName())) + { + HeaderFieldValueList* hfvs = i->second; + if (hfvs->getParserContainer() == 0) + { + SipMessage* nc_this(const_cast<SipMessage*>(this)); + hfvs->setParserContainer(nc_this->makeParserContainer<StringCategory>(hfvs, Headers::RESIP_DO_NOT_USE)); + } + return *dynamic_cast<ParserContainer<StringCategory>*>(hfvs->getParserContainer()); + } + } + // missing extension header + assert(false); + + return *(StringCategories*)0; +} + +StringCategories& +SipMessage::header(const ExtensionHeader& headerName) +{ + for (UnknownHeaders::iterator i = mUnknownHeaders.begin(); + i != mUnknownHeaders.end(); i++) + { + if (isEqualNoCase(i->first, headerName.getName())) + { + HeaderFieldValueList* hfvs = i->second; + if (hfvs->getParserContainer() == 0) + { + hfvs->setParserContainer(makeParserContainer<StringCategory>(hfvs, Headers::RESIP_DO_NOT_USE)); + } + return *dynamic_cast<ParserContainer<StringCategory>*>(hfvs->getParserContainer()); + } + } + + // create the list empty + HeaderFieldValueList* hfvs = getEmptyHfvl(); + hfvs->setParserContainer(makeParserContainer<StringCategory>(hfvs, Headers::RESIP_DO_NOT_USE)); + mUnknownHeaders.push_back(make_pair(headerName.getName(), hfvs)); + return *dynamic_cast<ParserContainer<StringCategory>*>(hfvs->getParserContainer()); +} + +bool +SipMessage::exists(const ExtensionHeader& symbol) const +{ + for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin(); + i != mUnknownHeaders.end(); i++) + { + if (isEqualNoCase(i->first, symbol.getName())) + { + return true; + } + } + return false; +} + +void +SipMessage::remove(const ExtensionHeader& headerName) +{ + for (UnknownHeaders::iterator i = mUnknownHeaders.begin(); + i != mUnknownHeaders.end(); i++) + { + if (isEqualNoCase(i->first, headerName.getName())) + { + freeHfvl(i->second); + mUnknownHeaders.erase(i); + return; + } + } +} + +void +SipMessage::addHeader(Headers::Type header, const char* headerName, int headerLen, + const char* start, int len) +{ + if (header != Headers::UNKNOWN) + { + HeaderFieldValueList* hfvl=0; + if (mHeaderIndices[header] == 0) + { + mHeaderIndices[header] = mHeaders.size(); + mHeaders.push_back(getEmptyHfvl()); + hfvl=mHeaders.back(); + } + else + { + if(mHeaderIndices[header]<0) + { + // Adding to a previously removed header type; there is already an + // empty HeaderFieldValueList in mHeaders for this type, all we + // need to do is flip the sign to re-enable it. + mHeaderIndices[header] *= -1; + } + hfvl=mHeaders[mHeaderIndices[header]]; + } + + if(Headers::isMulti(header)) + { + if (len) + { + hfvl->push_back(start, len, false); + } + } + else + { + if(hfvl->size()==1) + { + if(!mReason) + { + mReason=new Data; + } + + if(mInvalid) + { + mReason->append(",",1); + } + mInvalid=true; + mReason->append("Multiple values in single-value header ",39); + (*mReason)+=Headers::getHeaderName(header); + return; + } + hfvl->push_back(start ? start : Data::Empty.data(), len, false); + } + + } + else + { + assert(headerLen >= 0); + for (UnknownHeaders::iterator i = mUnknownHeaders.begin(); + i != mUnknownHeaders.end(); i++) + { + if (i->first.size() == (unsigned int)headerLen && + strncasecmp(i->first.data(), headerName, headerLen) == 0) + { + // add to end of list + if (len) + { + i->second->push_back(start, len, false); + } + return; + } + } + + // didn't find it, add an entry + HeaderFieldValueList *hfvs = getEmptyHfvl(); + if (len) + { + hfvs->push_back(start, len, false); + } + mUnknownHeaders.push_back(pair<Data, HeaderFieldValueList*>(Data(headerName, headerLen), + hfvs)); + } +} + +RequestLine& +SipMessage::header(const RequestLineType& l) +{ + assert (!isResponse()); + if (mStartLine == 0 ) + { + mStartLine = new (mStartLineMem) RequestLine; + mRequest = true; + } + return *static_cast<RequestLine*>(mStartLine); +} + +const RequestLine& +SipMessage::header(const RequestLineType& l) const +{ + assert (!isResponse()); + if (mStartLine == 0 ) + { + // request line missing + assert(false); + } + return *static_cast<RequestLine*>(mStartLine); +} + +StatusLine& +SipMessage::header(const StatusLineType& l) +{ + assert (!isRequest()); + if (mStartLine == 0 ) + { + mStartLine = new (mStartLineMem) StatusLine; + mResponse = true; + } + return *static_cast<StatusLine*>(mStartLine); +} + +const StatusLine& +SipMessage::header(const StatusLineType& l) const +{ + assert (!isRequest()); + if (mStartLine == 0 ) + { + // status line missing + assert(false); + } + return *static_cast<StatusLine*>(mStartLine); +} + +HeaderFieldValueList* +SipMessage::ensureHeaders(Headers::Type type) +{ + HeaderFieldValueList* hfvl=0; + if(mHeaderIndices[type]!=0) + { + if(mHeaderIndices[type]<0) + { + // Accessing a previously removed header type; there is already an + // empty HeaderFieldValueList in mHeaders for this type, all we + // need to do is flip the sign to re-enable it. + mHeaderIndices[type] *= -1; + } + hfvl = mHeaders[mHeaderIndices[type]]; + } + else + { + // create the list with a new component + mHeaders.push_back(getEmptyHfvl()); + hfvl=mHeaders.back(); + mHeaderIndices[type]=mHeaders.size()-1; + } + + return hfvl; +} + +HeaderFieldValueList* +SipMessage::ensureHeader(Headers::Type type) +{ + HeaderFieldValueList* hfvl=0; + if(mHeaderIndices[type]!=0) + { + if(mHeaderIndices[type]<0) + { + // Accessing a previously removed header type; there is already an + // empty HeaderFieldValueList in mHeaders for this type, all we + // need to do is flip the sign to re-enable it. + mHeaderIndices[type] *= -1; + hfvl = mHeaders[mHeaderIndices[type]]; + hfvl->push_back(0,0,false); + } + hfvl = mHeaders[mHeaderIndices[type]]; + } + else + { + // create the list with a new component + mHeaders.push_back(getEmptyHfvl()); + hfvl=mHeaders.back(); + mHeaderIndices[type]=mHeaders.size()-1; + mHeaders.back()->push_back(0,0,false); + } + + return hfvl; +} + +void +SipMessage::throwHeaderMissing(Headers::Type type) const +{ + // header missing + // assert(false); + InfoLog( << "Missing Header [" << Headers::getHeaderName(type) << "]"); + DebugLog (<< *this); + throw Exception("Missing header " + Headers::getHeaderName(type), __FILE__, __LINE__); +} + +// type safe header accessors +bool +SipMessage::exists(const HeaderBase& headerType) const +{ + return mHeaderIndices[headerType.getTypeNum()] > 0; +}; + +bool +SipMessage::empty(const HeaderBase& headerType) const +{ + return (mHeaderIndices[headerType.getTypeNum()] <= 0) || mHeaders[mHeaderIndices[headerType.getTypeNum()]]->parsedEmpty(); +} + +void +SipMessage::remove(Headers::Type type) +{ + if(mHeaderIndices[type] > 0) + { + // .bwc. The entry in mHeaders still remains after we do this; we retain + // our index (as a negative number, indicating that this header should + // not be encoded), in case this header type needs to be used later. + mHeaders[mHeaderIndices[type]]->clear(); + mHeaderIndices[type] *= -1; + } +}; + +#ifndef PARTIAL_TEMPLATE_SPECIALIZATION + +#undef defineHeader +#define defineHeader(_header, _name, _type, _rfc) \ +const H_##_header::Type& \ +SipMessage::header(const H_##_header& headerType) const \ +{ \ + HeaderFieldValueList* hfvs = ensureHeader(headerType.getTypeNum()); \ + if (hfvs->getParserContainer() == 0) \ + { \ + SipMessage* nc_this(const_cast<SipMessage*>(this)); \ + hfvs->setParserContainer(nc_this->makeParserContainer<H_##_header::Type>(hfvs, headerType.getTypeNum())); \ + } \ + return static_cast<ParserContainer<H_##_header::Type>*>(hfvs->getParserContainer())->front(); \ +} \ + \ +H_##_header::Type& \ +SipMessage::header(const H_##_header& headerType) \ +{ \ + HeaderFieldValueList* hfvs = ensureHeader(headerType.getTypeNum()); \ + if (hfvs->getParserContainer() == 0) \ + { \ + hfvs->setParserContainer(makeParserContainer<H_##_header::Type>(hfvs, headerType.getTypeNum())); \ + } \ + return static_cast<ParserContainer<H_##_header::Type>*>(hfvs->getParserContainer())->front(); \ +} + +#undef defineMultiHeader +#define defineMultiHeader(_header, _name, _type, _rfc) \ +const H_##_header##s::Type& \ +SipMessage::header(const H_##_header##s& headerType) const \ +{ \ + HeaderFieldValueList* hfvs = ensureHeaders(headerType.getTypeNum()); \ + if (hfvs->getParserContainer() == 0) \ + { \ + SipMessage* nc_this(const_cast<SipMessage*>(this)); \ + hfvs->setParserContainer(nc_this->makeParserContainer<H_##_header##s::ContainedType>(hfvs, headerType.getTypeNum())); \ + } \ + return *static_cast<H_##_header##s::Type*>(hfvs->getParserContainer()); \ +} \ + \ +H_##_header##s::Type& \ +SipMessage::header(const H_##_header##s& headerType) \ +{ \ + HeaderFieldValueList* hfvs = ensureHeaders(headerType.getTypeNum()); \ + if (hfvs->getParserContainer() == 0) \ + { \ + hfvs->setParserContainer(makeParserContainer<H_##_header##s::ContainedType>(hfvs, headerType.getTypeNum())); \ + } \ + return *static_cast<H_##_header##s::Type*>(hfvs->getParserContainer()); \ +} + +defineHeader(ContentDisposition, "Content-Disposition", Token, "RFC 3261"); +defineHeader(ContentEncoding, "Content-Encoding", Token, "RFC 3261"); +defineHeader(MIMEVersion, "Mime-Version", Token, "RFC 3261"); +defineHeader(Priority, "Priority", Token, "RFC 3261"); +defineHeader(Event, "Event", Token, "RFC 3265"); +defineHeader(SubscriptionState, "Subscription-State", Token, "RFC 3265"); +defineHeader(SIPETag, "SIP-ETag", Token, "RFC 3903"); +defineHeader(SIPIfMatch, "SIP-If-Match", Token, "RFC 3903"); +defineHeader(ContentId, "Content-ID", Token, "RFC 2045"); +defineMultiHeader(AllowEvents, "Allow-Events", Token, "RFC 3265"); +defineHeader(Identity, "Identity", StringCategory, "RFC 4474"); +defineMultiHeader(AcceptEncoding, "Accept-Encoding", Token, "RFC 3261"); +defineMultiHeader(AcceptLanguage, "Accept-Language", Token, "RFC 3261"); +defineMultiHeader(Allow, "Allow", Token, "RFC 3261"); +defineMultiHeader(ContentLanguage, "Content-Language", Token, "RFC 3261"); +defineMultiHeader(ProxyRequire, "Proxy-Require", Token, "RFC 3261"); +defineMultiHeader(Require, "Require", Token, "RFC 3261"); +defineMultiHeader(Supported, "Supported", Token, "RFC 3261"); +defineMultiHeader(Unsupported, "Unsupported", Token, "RFC 3261"); +defineMultiHeader(SecurityClient, "Security-Client", Token, "RFC 3329"); +defineMultiHeader(SecurityServer, "Security-Server", Token, "RFC 3329"); +defineMultiHeader(SecurityVerify, "Security-Verify", Token, "RFC 3329"); +defineMultiHeader(RequestDisposition, "Request-Disposition", Token, "RFC 3841"); +defineMultiHeader(Reason, "Reason", Token, "RFC 3326"); +defineMultiHeader(Privacy, "Privacy", PrivacyCategory, "RFC 3323"); +defineMultiHeader(PMediaAuthorization, "P-Media-Authorization", Token, "RFC 3313"); +defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488"); +defineHeader(AnswerMode, "Answer-Mode", Token, "draft-ietf-answermode-01"); +defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "draft-ietf-answermode-01"); + +defineMultiHeader(Accept, "Accept", Mime, "RFC 3261"); +defineHeader(ContentType, "Content-Type", Mime, "RFC 3261"); + +defineMultiHeader(CallInfo, "Call-Info", GenericUri, "RFC 3261"); +defineMultiHeader(AlertInfo, "Alert-Info", GenericUri, "RFC 3261"); +defineMultiHeader(ErrorInfo, "Error-Info", GenericUri, "RFC 3261"); +defineHeader(IdentityInfo, "Identity-Info", GenericUri, "RFC 4474"); + +defineMultiHeader(RecordRoute, "Record-Route", NameAddr, "RFC 3261"); +defineMultiHeader(Route, "Route", NameAddr, "RFC 3261"); +defineMultiHeader(Contact, "Contact", NameAddr, "RFC 3261"); +defineHeader(From, "From", NameAddr, "RFC 3261"); +defineHeader(To, "To", NameAddr, "RFC 3261"); +defineHeader(ReplyTo, "Reply-To", NameAddr, "RFC 3261"); +defineHeader(ReferTo, "Refer-To", NameAddr, "RFC 3515"); +defineHeader(ReferredBy, "Referred-By", NameAddr, "RFC 3892"); +defineMultiHeader(Path, "Path", NameAddr, "RFC 3327"); +defineMultiHeader(AcceptContact, "Accept-Contact", NameAddr, "RFC 3841"); +defineMultiHeader(RejectContact, "Reject-Contact", NameAddr, "RFC 3841"); +defineMultiHeader(PAssertedIdentity, "P-Asserted-Identity", NameAddr, "RFC 3325"); +defineMultiHeader(PPreferredIdentity, "P-Preferred-Identity", NameAddr, "RFC 3325"); +defineHeader(PCalledPartyId, "P-Called-Party-ID", NameAddr, "RFC 3455"); +defineMultiHeader(PAssociatedUri, "P-Associated-URI", NameAddr, "RFC 3455"); +defineMultiHeader(ServiceRoute, "Service-Route", NameAddr, "RFC 3608"); + +defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC ?"); +defineHeader(Organization, "Organization", StringCategory, "RFC 3261"); +defineHeader(Server, "Server", StringCategory, "RFC 3261"); +defineHeader(Subject, "Subject", StringCategory, "RFC 3261"); +defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261"); +defineHeader(Timestamp, "Timestamp", StringCategory, "RFC 3261"); + +defineHeader(ContentLength, "Content-Length", UInt32Category, "RFC 3261"); +defineHeader(MaxForwards, "Max-Forwards", UInt32Category, "RFC 3261"); +defineHeader(MinExpires, "Min-Expires", Uint32Category, "RFC 3261"); +defineHeader(RSeq, "RSeq", UInt32Category, "RFC 3261"); + +// !dlb! this one is not quite right -- can have (comment) after field value +defineHeader(RetryAfter, "Retry-After", UInt32Category, "RFC 3261"); +defineHeader(FlowTimer, "Flow-Timer", UInt32Category, "RFC 5626"); + +defineHeader(Expires, "Expires", ExpiresCategory, "RFC 3261"); +defineHeader(SessionExpires, "Session-Expires", ExpiresCategory, "RFC 4028"); +defineHeader(MinSE, "Min-SE", ExpiresCategory, "RFC 4028"); + +defineHeader(CallID, "Call-ID", CallID, "RFC 3261"); +defineHeader(Replaces, "Replaces", CallID, "RFC 3891"); +defineHeader(InReplyTo, "In-Reply-To", CallID, "RFC 3261"); +defineHeader(Join, "Join", CallId, "RFC 3911"); +defineHeader(TargetDialog, "Target-Dialog", CallId, "RFC 4538"); + +defineHeader(AuthenticationInfo, "Authentication-Info", Auth, "RFC 3261"); +defineMultiHeader(Authorization, "Authorization", Auth, "RFC 3261"); +defineMultiHeader(ProxyAuthenticate, "Proxy-Authenticate", Auth, "RFC 3261"); +defineMultiHeader(ProxyAuthorization, "Proxy-Authorization", Auth, "RFC 3261"); +defineMultiHeader(WWWAuthenticate, "Www-Authenticate", Auth, "RFC 3261"); + +defineHeader(CSeq, "CSeq", CSeqCategory, "RFC 3261"); +defineHeader(Date, "Date", DateCategory, "RFC 3261"); +defineMultiHeader(Warning, "Warning", WarningCategory, "RFC 3261"); +defineMultiHeader(Via, "Via", Via, "RFC 3261"); +defineHeader(RAck, "RAck", RAckCategory, "RFC 3262"); +defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04"); // ?bwc? Not in 3323, should we keep? +defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244"); + +#endif + +const HeaderFieldValueList* +SipMessage::getRawHeader(Headers::Type headerType) const +{ + if(mHeaderIndices[headerType]>0) + { + return mHeaders[mHeaderIndices[headerType]]; + } + + return 0; +} + +void +SipMessage::setRawHeader(const HeaderFieldValueList* hfvs, Headers::Type headerType) +{ + HeaderFieldValueList* copy=0; + if (mHeaderIndices[headerType] == 0) + { + mHeaderIndices[headerType]=mHeaders.size(); + copy=getCopyHfvl(*hfvs); + mHeaders.push_back(copy); + } + else + { + if(mHeaderIndices[headerType]<0) + { + // Setting a previously removed header type; there is already an + // empty HeaderFieldValueList in mHeaders for this type, all we + // need to do is flip the sign to re-enable it. + mHeaderIndices[headerType]=-mHeaderIndices[headerType]; + } + copy = mHeaders[mHeaderIndices[headerType]]; + *copy=*hfvs; + } + if(!Headers::isMulti(headerType) && copy->parsedEmpty()) + { + copy->push_back(0,0,false); + } +} + +void +SipMessage::setForceTarget(const Uri& uri) +{ + if (mForceTarget) + { + *mForceTarget = uri; + } + else + { + mForceTarget = new Uri(uri); + } +} + +void +SipMessage::clearForceTarget() +{ + delete mForceTarget; + mForceTarget = 0; +} + +const Uri& +SipMessage::getForceTarget() const +{ + assert(mForceTarget); + return *mForceTarget; +} + +bool +SipMessage::hasForceTarget() const +{ + return (mForceTarget != 0); +} + +SipMessage& +SipMessage::mergeUri(const Uri& source) +{ + header(h_RequestLine).uri() = source; + header(h_RequestLine).uri().removeEmbedded(); + + if (source.exists(p_method)) + { + header(h_RequestLine).method() = getMethodType(source.param(p_method)); + header(h_RequestLine).uri().remove(p_method); + } + + //19.1.5 + //dangerous headers not included in merge: + // From, Call-ID, Cseq, Via, Record Route, Route, Accept, Accept-Encoding, + // Accept-Langauge, Allow, Contact, Organization, Supported, User-Agent + + //from the should-verify section, remove for now, some never seem to make + //sense: + // Content-Encoding, Content-Language, Content-Length, Content-Type, Date, + // Mime-Version, and TimeStamp + + if (source.hasEmbedded()) + { + h_AuthenticationInfo.merge(*this, source.embedded()); + h_ContentTransferEncoding.merge(*this, source.embedded()); + h_Event.merge(*this, source.embedded()); + h_Expires.merge(*this, source.embedded()); + h_SessionExpires.merge(*this, source.embedded()); + h_MinSE.merge(*this, source.embedded()); + h_InReplyTo.merge(*this, source.embedded()); + h_MaxForwards.merge(*this, source.embedded()); + h_MinExpires.merge(*this, source.embedded()); + h_Priority.merge(*this, source.embedded()); + h_ReferTo.merge(*this, source.embedded()); + h_ReferredBy.merge(*this, source.embedded()); + h_Replaces.merge(*this, source.embedded()); + h_ReplyTo.merge(*this, source.embedded()); + h_RetryAfter.merge(*this, source.embedded()); + h_Server.merge(*this, source.embedded()); + h_SIPETag.merge(*this, source.embedded()); + h_SIPIfMatch.merge(*this, source.embedded()); + h_Subject.merge(*this, source.embedded()); + h_SubscriptionState.merge(*this, source.embedded()); + h_To.merge(*this, source.embedded()); + h_Warnings.merge(*this, source.embedded()); + + h_SecurityClients.merge(*this, source.embedded()); + h_SecurityServers.merge(*this, source.embedded()); + h_SecurityVerifys.merge(*this, source.embedded()); + + h_Authorizations.merge(*this, source.embedded()); + h_ProxyAuthenticates.merge(*this, source.embedded()); + h_WWWAuthenticates.merge(*this, source.embedded()); + h_ProxyAuthorizations.merge(*this, source.embedded()); + + h_AlertInfos.merge(*this, source.embedded()); + h_AllowEvents.merge(*this, source.embedded()); + h_CallInfos.merge(*this, source.embedded()); + h_ErrorInfos.merge(*this, source.embedded()); + h_ProxyRequires.merge(*this, source.embedded()); + h_Requires.merge(*this, source.embedded()); + h_Unsupporteds.merge(*this, source.embedded()); + h_AnswerMode.merge(*this, source.embedded()); + h_PrivAnswerMode.merge(*this, source.embedded()); + + h_RSeq.merge(*this, source.embedded()); + h_RAck.merge(*this, source.embedded()); + } + //unknown header merge + return *this; +} + +void +SipMessage::setSecurityAttributes(auto_ptr<SecurityAttributes> sec) +{ + mSecurityAttributes = sec; +} + +void +SipMessage::callOutboundDecorators(const Tuple &src, + const Tuple &dest, + const Data& sigcompId) +{ + if(mIsDecorated) + { + rollbackOutboundDecorators(); + } + + std::vector<MessageDecorator*>::iterator i; + for (i = mOutboundDecorators.begin(); + i != mOutboundDecorators.end(); i++) + { + (*i)->decorateMessage(*this, src, dest, sigcompId); + } + mIsDecorated = true; +} + +void +SipMessage::clearOutboundDecorators() +{ + while(!mOutboundDecorators.empty()) + { + delete mOutboundDecorators.back(); + mOutboundDecorators.pop_back(); + } +} + +void +SipMessage::rollbackOutboundDecorators() +{ + std::vector<MessageDecorator*>::reverse_iterator r; + for(r=mOutboundDecorators.rbegin(); r!=mOutboundDecorators.rend(); ++r) + { + (*r)->rollbackMessage(*this); + } + mIsDecorated = false; +} + +void +SipMessage::copyOutboundDecoratorsToStackCancel(SipMessage& cancel) +{ + std::vector<MessageDecorator*>::iterator i; + for (i = mOutboundDecorators.begin(); + i != mOutboundDecorators.end(); i++) + { + if((*i)->copyToStackCancels()) + { + cancel.addOutboundDecorator(*(new auto_ptr<MessageDecorator>((*i)->clone()))); + } + } +} + +void +SipMessage::copyOutboundDecoratorsToStackFailureAck(SipMessage& ack) +{ + std::vector<MessageDecorator*>::iterator i; + for (i = mOutboundDecorators.begin(); + i != mOutboundDecorators.end(); i++) + { + if((*i)->copyToStackFailureAcks()) + { + ack.addOutboundDecorator(*(new auto_ptr<MessageDecorator>((*i)->clone()))); + } + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/SipMessage.hxx b/src/libs/resiprocate/resip/stack/SipMessage.hxx new file mode 100644 index 00000000..9b38c4db --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SipMessage.hxx @@ -0,0 +1,746 @@ +#if !defined(RESIP_SIPMESSAGE_HXX) +#define RESIP_SIPMESSAGE_HXX + +#include <sys/types.h> + +#include <list> +#include <vector> +#include <utility> +#include <memory> + +#include "resip/stack/Contents.hxx" +#include "resip/stack/Headers.hxx" +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/ParserContainer.hxx" +#include "resip/stack/ParserCategories.hxx" +#include "resip/stack/SecurityAttributes.hxx" +#include "resip/stack/Tuple.hxx" +#include "resip/stack/Uri.hxx" +#include "resip/stack/MessageDecorator.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/Data.hxx" +#include "rutil/DinkyPool.hxx" +#include "rutil/StlPoolAllocator.hxx" +#include "rutil/Timer.hxx" +#include "rutil/HeapInstanceCounter.hxx" + +namespace resip +{ + +class Contents; +class ExtensionHeader; +class SecurityAttributes; +class Transport; + +/** + @ingroup resip_crit + @ingroup message_passing_tu + @brief Represents a SIP message. + + This is the class that your app will spend the most time working with. This + is because, in the UA core/Transaction User architecture, the vast majority + of interaction is carried out through SIP messaging. + + When you get a SipMessage, generally the first thing you want to know is + whether it is a request or a response. This is done by calling + SipMessage::isRequest() or SipMessage::isResponse(). + + Next, it is usually important to determine what the SIP method of the message + is. This is done by calling SipMessage::method() (this is a convenience + function that checks the method of the Request-Line if the message is a + request, or the method of the CSeq if a response). + + At this point, it may become useful to examine the start-line of the message. + + If the message is a request, you can get the Request-Line (represented by a + RequestLine&) by calling SipMessage::header(const RequestLineType&) + @code + RequestLine& rLine = sip.header(h_RequestLine); + @endcode + + If the message is a response, you can get the Status-Line (represented by a StatusLine&) by calling SipMessage::header(const StatusLineType&) + @code + StatusLine& sLine = sip.header(h_StatusLine); + @endcode + + From here, examination of the various headers is in order. The way the + underlying code works is very complicated, but fortunately relatively + painless to use. For each header type, there is a subclass of HeaderBase, and + a SipMessage::header() function that takes a reference to this subclass. On + top of this, there is a static instance of each of these subclasses. Examples + include h_To, h_From, h_CSeq, h_CallId, h_Routes, h_Contacts, h_RecordRoutes, + etc. + + @code + NameAddr& to = sip.header(h_To); + NameAddr& from = sip.header(h_From); + CSeqCategory& cseq = sip.header(h_CSeq); + CallId& callId = sip.header(h_CallId); + ParserContainer<NameAddr>& routes = sip.header(h_Routes); + ParserContainer<NameAddr>& contacts = sip.header(h_Contacts); + ParserContainer<NameAddr>& rRoutes = sip.header(h_RecordRoutes); + @endcode + + Generally speaking, the access token is named in a predictable fashion; all + non-alphanumeric characters are omitted, the first letter of each word is + capitalized, and the name is pluralized if the header is multi-valued (since + this stuff is all macro-generated, sometimes this pluralization isn't quite + right; h_AllowEventss, h_PAssertedIdentitys). + + When accessing a single-value header, you need to check whether it + exists first (unless you want it to be created implicitly). Also, since all + header field values are lazily parsed (see LazyParser), you'll want to make + sure it is well-formed before attempting to access any portion of it. + + @code + if(sip.exists(h_Event)) + { + Token& event = sip.header(h_Event); + if(event.isWellFormed()) + { + // do stuff with event. + } + else + { + // complain bitterly + } + } + @endcode + + When accessing a multi-value header, it is important to keep in mind that + it can be empty, even if it exists (for example, "Supported: " has a meaning + that is distinct from the lack of a Supported header). + + @code + if(sip.exists(h_Contacts)) + { + ParserContainer<NameAddr>& contacts = sip.header(h_Contacts); + if(!contacts.empty()) + { + NameAddr& frontContact = contacts.front(); + if(frontContact.isWellFormed()) + { + // do stuff with frontContact + } + else + { + // complain bitterly + } + } + else + { + // complain bitterly + } + } + @endcode + + In some cases, you will need to access header-types that are not natively + supported by the stack (ie, don't have an access-token). ExtensionHeader will + allow you to construct an access-token at runtime that will retrieve the + header field value as a ParserContainer<StringCategory>. Here's an example: + + @code + // We need to access the FooBar header field value here. + static ExtensionHeader h_FooBar("FooBar"); + if(sip.exists(h_FooBar)) + { + ParserContainer<StringCategory>& fooBars = sip.header(h_FooBar); + } + @endcode + +*/ +class SipMessage : public TransactionMessage +{ + public: + RESIP_HeapCount(SipMessage); +#ifndef __SUNPRO_CC + typedef std::list< std::pair<Data, HeaderFieldValueList*>, StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase > > UnknownHeaders; +#else + typedef std::list< std::pair<Data, HeaderFieldValueList*> > UnknownHeaders; +#endif + + explicit SipMessage(const Transport* fromWire = 0); + /// @todo .dlb. public, allows pass by value to compile. + SipMessage(const SipMessage& message); + + /// @todo .dlb. sure would be nice to have overloaded return value here.. + virtual Message* clone() const; + + SipMessage& operator=(const SipMessage& rhs); + + /// Returns the transaction id from the branch or if 2543, the computed hash. + virtual const Data& getTransactionId() const; + + /** + @brief Calculates an MD5 hash over the Request-URI, To tag (for + non-INVITE transactions), From tag, Call-ID, CSeq (including + the method), and top Via header. The hash is used for + transaction matching. + */ + const Data& getRFC2543TransactionId() const; + void setRFC2543TransactionId(const Data& tid); + + virtual ~SipMessage(); + + /** @brief Construct a SipMessage object from a string containing a SIP request + or response. + + @param buffer a buffer containing a SIP message + @param isExternal true for a message generated externally, false otherwise. + @return constructed SipMessage object + */ + static SipMessage* make(const Data& buffer, bool isExternal = false); + void parseAllHeaders(); + + static bool checkContentLength; + + /** + @brief Base exception for SipMessage related exceptions + */ + class Exception : public BaseException + { + public: + /** + @brief constructor that records an exception message, the file and the line + that the exception occured in. + */ + Exception(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) {} + /** + @brief returns the class name of the exception instance + @return the class name of the instance + */ + const char* name() const { return "SipMessage::Exception"; } + }; + + /// Mark message as internally generated + inline void setFromTU() + { + mIsExternal = false; + } + + /// Mark message as externally generated + inline void setFromExternal() + { + mIsExternal = true; + } + + /** @brief Check if SipMessage came off the wire. + + @return true if the message came from an IP interface, false otherwise. + */ + inline bool isExternal() const + { + return mIsExternal; + } + + /// @brief Check if SipMessage is a client transaction + /// @return true if the message is external and is a response or + /// an internally-generated request. + virtual bool isClientTransaction() const; + + /** @brief Generate a string from the SipMessage object + + @return string representation of a SIP message. + */ + virtual EncodeStream& encode(EncodeStream& str) const; + //sipfrags will not output Content Length if there is no body--introduce + //friendship to hide this? + virtual EncodeStream& encodeSipFrag(EncodeStream& str) const; + EncodeStream& encodeEmbedded(EncodeStream& str) const; + + virtual EncodeStream& encodeBrief(EncodeStream& str) const; + EncodeStream& encodeSingleHeader(Headers::Type type, EncodeStream& str) const; + + /// Returns true if message is a request, false otherwise + inline bool isRequest() const {return mRequest;} + /// Returns true if message is a response, false otherwise + inline bool isResponse() const {return mResponse;} + /// Returns true if message failed to parse, false otherwise + inline bool isInvalid() const{return mInvalid;} + + /// @brief returns the method type of the message + /// @see MethodTypes + resip::MethodTypes method() const; + /// Returns a string containing the SIP method for the message + const Data& methodStr() const; + + /// Returns a string containing the response reason text + const resip::Data* getReason() const{return mReason;} + + /// Returns the RequestLine. This is only valid for request messages. + const RequestLine& + header(const RequestLineType& l) const; + + /// Returns the RequestLine. This is only valid for request messages. + RequestLine& + header(const RequestLineType& l); + + inline const RequestLine& + const_header(const RequestLineType& l) const + { + return header(l); + } + + /// Returns the StatusLine. This is only valid for response messages. + const StatusLine& + header(const StatusLineType& l) const; + + /// Returns the StatusLine. This is only valid for response messages. + StatusLine& + header(const StatusLineType& l); + + inline const StatusLine& + const_header(const StatusLineType& l) const + { + return header(l); + } + + /// Returns true if the given header field is present, false otherwise + bool exists(const HeaderBase& headerType) const; + /// Returns true if the header field is present and non-empty, false otherwise + bool empty(const HeaderBase& headerType) const; + /// @brief Prevents a header field from being present when the message is prepared + /// for sending to a transport. This does not free the memory that was + /// used by the header. + inline void remove(const HeaderBase& headerType) + { + remove(headerType.getTypeNum()); + } + + void remove(Headers::Type type); + +#define defineHeader(_header, _name, _type, _rfc) \ + const H_##_header::Type& header(const H_##_header& headerType) const; \ + H_##_header::Type& header(const H_##_header& headerType); \ + inline const H_##_header::Type& const_header(const H_##_header& headerType) const \ + {\ + return header(headerType);\ + } + + +#define defineMultiHeader(_header, _name, _type, _rfc) \ + const H_##_header##s::Type& header(const H_##_header##s& headerType) const; \ + H_##_header##s::Type& header(const H_##_header##s& headerType); \ + inline const H_##_header##s::Type& const_header(const H_##_header##s& headerType) const \ + {\ + return header(headerType);\ + } + + defineHeader(ContentDisposition, "Content-Disposition", Token, "RFC 3261"); + defineHeader(ContentEncoding, "Content-Encoding", Token, "RFC 3261"); + defineHeader(MIMEVersion, "Mime-Version", Token, "RFC 3261"); + defineHeader(Priority, "Priority", Token, "RFC 3261"); + defineHeader(Event, "Event", Token, "RFC 3265"); + defineHeader(SubscriptionState, "Subscription-State", Token, "RFC 3265"); + defineHeader(SIPETag, "SIP-ETag", Token, "RFC 3903"); + defineHeader(SIPIfMatch, "SIP-If-Match", Token, "RFC 3903"); + defineHeader(ContentId, "Content-ID", Token, "RFC 2045"); + defineMultiHeader(AllowEvents, "Allow-Events", Token, "RFC 3265"); + defineHeader(Identity, "Identity", StringCategory, "RFC 4474"); + defineMultiHeader(AcceptEncoding, "Accept-Encoding", Token, "RFC 3261"); + defineMultiHeader(AcceptLanguage, "Accept-Language", Token, "RFC 3261"); + defineMultiHeader(Allow, "Allow", Token, "RFC 3261"); + defineMultiHeader(ContentLanguage, "Content-Language", Token, "RFC 3261"); + defineMultiHeader(ProxyRequire, "Proxy-Require", Token, "RFC 3261"); + defineMultiHeader(Require, "Require", Token, "RFC 3261"); + defineMultiHeader(Supported, "Supported", Token, "RFC 3261"); + defineMultiHeader(Unsupported, "Unsupported", Token, "RFC 3261"); + defineMultiHeader(SecurityClient, "Security-Client", Token, "RFC 3329"); + defineMultiHeader(SecurityServer, "Security-Server", Token, "RFC 3329"); + defineMultiHeader(SecurityVerify, "Security-Verify", Token, "RFC 3329"); + defineMultiHeader(RequestDisposition, "Request-Disposition", Token, "RFC 3841"); + defineMultiHeader(Reason, "Reason", Token, "RFC 3326"); + defineMultiHeader(Privacy, "Privacy", PrivacyCategory, "RFC 3323"); + defineMultiHeader(PMediaAuthorization, "P-Media-Authorization", Token, "RFC 3313"); + defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488"); + defineHeader(AnswerMode, "Answer-Mode", Token, "draft-ietf-answermode-04"); + defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "draft-ietf-answermode-04"); + + defineMultiHeader(Accept, "Accept", Mime, "RFC 3261"); + defineHeader(ContentType, "Content-Type", Mime, "RFC 3261"); + + defineMultiHeader(CallInfo, "Call-Info", GenericUri, "RFC 3261"); + defineMultiHeader(AlertInfo, "Alert-Info", GenericUri, "RFC 3261"); + defineMultiHeader(ErrorInfo, "Error-Info", GenericUri, "RFC 3261"); + defineHeader(IdentityInfo, "Identity-Info", GenericUri, "RFC 4474"); + + defineMultiHeader(RecordRoute, "Record-Route", NameAddr, "RFC 3261"); + defineMultiHeader(Route, "Route", NameAddr, "RFC 3261"); + defineMultiHeader(Contact, "Contact", NameAddr, "RFC 3261"); + defineHeader(From, "From", NameAddr, "RFC 3261"); + defineHeader(To, "To", NameAddr, "RFC 3261"); + defineHeader(ReplyTo, "Reply-To", NameAddr, "RFC 3261"); + defineHeader(ReferTo, "Refer-To", NameAddr, "RFC 3515"); + defineHeader(ReferredBy, "Referred-By", NameAddr, "RFC 3892"); + defineMultiHeader(Path, "Path", NameAddr, "RFC 3327"); + defineMultiHeader(AcceptContact, "Accept-Contact", NameAddr, "RFC 3841"); + defineMultiHeader(RejectContact, "Reject-Contact", NameAddr, "RFC 3841"); + defineMultiHeader(PAssertedIdentity, "P-Asserted-Identity", NameAddr, "RFC 3325"); + defineMultiHeader(PPreferredIdentity, "P-Preferred-Identity", NameAddr, "RFC 3325"); + defineHeader(PCalledPartyId, "P-Called-Party-ID", NameAddr, "RFC 3455"); + defineMultiHeader(PAssociatedUri, "P-Associated-URI", NameAddr, "RFC 3455"); + defineMultiHeader(ServiceRoute, "Service-Route", NameAddr, "RFC 3608"); + defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04"); // ?bwc? Not in 3323, should we keep? + defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244"); + + defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC 1521"); + defineHeader(Organization, "Organization", StringCategory, "RFC 3261"); + defineHeader(Server, "Server", StringCategory, "RFC 3261"); + defineHeader(Subject, "Subject", StringCategory, "RFC 3261"); + defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261"); + defineHeader(Timestamp, "Timestamp", StringCategory, "RFC 3261"); + + defineHeader(ContentLength, "Content-Length", UInt32Category, "RFC 3261"); + defineHeader(MaxForwards, "Max-Forwards", UInt32Category, "RFC 3261"); + defineHeader(MinExpires, "Min-Expires", UInt32Category, "RFC 3261"); + defineHeader(RSeq, "RSeq", UInt32Category, "RFC 3261"); + +/// @todo !dlb! this one is not quite right -- can have (comment) after field value + defineHeader(RetryAfter, "Retry-After", UInt32Category, "RFC 3261"); + defineHeader(FlowTimer, "Flow-Timer", UInt32Category, "RFC 5626"); + + defineHeader(Expires, "Expires", ExpiresCategory, "RFC 3261"); + defineHeader(SessionExpires, "Session-Expires", ExpiresCategory, "RFC 4028"); + defineHeader(MinSE, "Min-SE", ExpiresCategory, "RFC 4028"); + + defineHeader(CallID, "Call-ID", CallID, "RFC 3261"); + defineHeader(Replaces, "Replaces", CallID, "RFC 3891"); + defineHeader(InReplyTo, "In-Reply-To", CallID, "RFC 3261"); + defineHeader(Join, "Join", CallId, "RFC 3911"); + defineHeader(TargetDialog, "Target-Dialog", CallId, "RFC 4538"); + + defineHeader(AuthenticationInfo, "Authentication-Info", Auth, "RFC 3261"); + defineMultiHeader(Authorization, "Authorization", Auth, "RFC 3261"); + defineMultiHeader(ProxyAuthenticate, "Proxy-Authenticate", Auth, "RFC 3261"); + defineMultiHeader(ProxyAuthorization, "Proxy-Authorization", Auth, "RFC 3261"); + defineMultiHeader(WWWAuthenticate, "Www-Authenticate", Auth, "RFC 3261"); + + defineHeader(CSeq, "CSeq", CSeqCategory, "RFC 3261"); + defineHeader(Date, "Date", DateCategory, "RFC 3261"); + defineMultiHeader(Warning, "Warning", WarningCategory, "RFC 3261"); + defineMultiHeader(Via, "Via", Via, "RFC 3261"); + defineHeader(RAck, "RAck", RAckCategory, "RFC 3262"); + + /// unknown header interface + const StringCategories& header(const ExtensionHeader& symbol) const; + StringCategories& header(const ExtensionHeader& symbol); + bool exists(const ExtensionHeader& symbol) const; + void remove(const ExtensionHeader& symbol); + + /// typeless header interface + const HeaderFieldValueList* getRawHeader(Headers::Type headerType) const; + void setRawHeader(const HeaderFieldValueList* hfvs, Headers::Type headerType); + const UnknownHeaders& getRawUnknownHeaders() const {return mUnknownHeaders;} + /** + Return the raw body string (if it exists). The returned HFV + and its underlying memory is owned by the SipMessage, and may + be released when this SipMessage is manipulated. + + This is a low-level interface; see getContents() for higher level. + **/ + const HeaderFieldValue& getRawBody() const {return mContentsHfv;} + + /** + Remove any existing body/contents, and (if non-empty) + set the body to {body}. It makes full copy of the body + to stored within the SipMessage (since lifetime of + the message is unpredictable). + + This is a low-level interface; see setContents() for higher level. + **/ + void setRawBody(const HeaderFieldValue& body); + + /** @brief Retrieves the body of a SIP message. + * + * In the case of an INVITE request containing SDP, the body would + * be an SdpContents. For a MESSAGE request, the body may be PlainContents, + * CpimContents, or another subclass of Contents. + * + * @return pointer to the contents of the SIP message + **/ + Contents* getContents() const; + /// Removes the contents from the message + std::auto_ptr<Contents> releaseContents(); + + /// @brief Set the contents of the message + /// @param contents to store in the message + void setContents(const Contents* contents); + /// @brief Set the contents of the message + /// @param contents to store in the message + void setContents(std::auto_ptr<Contents> contents); + + /// @internal transport interface + void setStartLine(const char* start, int len); + + void setBody(const char* start, UInt32 len); + + /// Add HeaderFieldValue given enum, header name, pointer start, content length + void addHeader(Headers::Type header, + const char* headerName, int headerLen, + const char* start, int len); + + /// @brief Interface used to determine which Transport was used to receive a + /// particular SipMessage. If the SipMessage was not received from the + /// wire, getReceivedTransport() returns 0. Set in constructor + const Transport* getReceivedTransport() const { return mTransport; } + + // Returns the source tuple that the message was received from + // only makes sense for messages received from the wire + void setSource(const Tuple& tuple) { mSource = tuple; } + /// @brief Returns the source tuple that the message was received from + /// only makes sense for messages received from the wire + const Tuple& getSource() const { return mSource; } + + /// Used by the stateless interface to specify where to send a request/response + void setDestination(const Tuple& tuple) { mDestination = tuple; } + Tuple& getDestination() { return mDestination; } + + void addBuffer(char* buf); + + UInt64 getCreatedTimeMicroSec() {return mCreatedTime;} + + /// deal with a notion of an "out-of-band" forced target for SIP routing + void setForceTarget(const Uri& uri); + void clearForceTarget(); + const Uri& getForceTarget() const; + bool hasForceTarget() const; + + const Data& getTlsDomain() const { return mTlsDomain; } + void setTlsDomain(const Data& domain) { mTlsDomain = domain; } + + const std::list<Data>& getTlsPeerNames() const { return mTlsPeerNames; } + void setTlsPeerNames(const std::list<Data>& tlsPeerNames) { mTlsPeerNames = tlsPeerNames; } + + Data getCanonicalIdentityString() const; + + SipMessage& mergeUri(const Uri& source); + + void setSecurityAttributes(std::auto_ptr<SecurityAttributes>); + const SecurityAttributes* getSecurityAttributes() const { return mSecurityAttributes.get(); } + + /// @brief Call a MessageDecorator to process the message before it is + /// sent to the transport + void addOutboundDecorator(std::auto_ptr<MessageDecorator> md){mOutboundDecorators.push_back(md.release());} + void clearOutboundDecorators(); + void callOutboundDecorators(const Tuple &src, + const Tuple &dest, + const Data& sigcompId); + void rollbackOutboundDecorators(); + void copyOutboundDecoratorsToStackCancel(SipMessage& cancel); + void copyOutboundDecoratorsToStackFailureAck(SipMessage& ack); + bool mIsDecorated; + + bool mIsBadAck200; + + protected: + // !bwc! Removes or zeros all pointers to heap-allocated memory this + // class owns. + void clear(bool leaveResponseStuff=false); + // !bwc! Frees all heap-allocated memory owned. + void freeMem(bool leaveResponseStuff=false); + + // !bwc! Initializes members. Will not free heap-allocated memory. + // Will begin by calling clear(). + void init(const SipMessage& rhs); + + private: + void compute2543TransactionHash() const; + + EncodeStream& + encode(EncodeStream& str, bool isSipFrag) const; + + void copyFrom(const SipMessage& message); + + HeaderFieldValueList* ensureHeaders(Headers::Type type); + inline HeaderFieldValueList* ensureHeaders(Headers::Type type) const // throws if not present + { + if(mHeaderIndices[type]>0) + { + return mHeaders[mHeaderIndices[type]]; + } + throwHeaderMissing(type); + return 0; + } + + HeaderFieldValueList* ensureHeader(Headers::Type type); + inline HeaderFieldValueList* ensureHeader(Headers::Type type) const // throws if not present + { + if(mHeaderIndices[type]>0) + { + return mHeaders[mHeaderIndices[type]]; + } + throwHeaderMissing(type); + return 0; + } + + void throwHeaderMissing(Headers::Type type) const; + + inline HeaderFieldValueList* getEmptyHfvl() + { + void* ptr(mPool.allocate(sizeof(HeaderFieldValueList))); + return new (ptr) HeaderFieldValueList(mPool); + } + + inline HeaderFieldValueList* getCopyHfvl(const HeaderFieldValueList& hfvl) + { + void* ptr(mPool.allocate(sizeof(HeaderFieldValueList))); + return new (ptr) HeaderFieldValueList(hfvl, mPool); + } + + inline void freeHfvl(HeaderFieldValueList* hfvl) + { + if(hfvl) + { + hfvl->~HeaderFieldValueList(); + mPool.deallocate(hfvl); + } + } + + template<class T> + ParserContainer<T>* makeParserContainer() + { + void* ptr(mPool.allocate(sizeof(ParserContainer<T>))); + return new (ptr) ParserContainer<T>(mPool); + } + + template<class T> + ParserContainer<T>* makeParserContainer(HeaderFieldValueList* hfvs, + Headers::Type type = Headers::UNKNOWN) + { + void* ptr(mPool.allocate(sizeof(ParserContainer<T>))); + return new (ptr) ParserContainer<T>(hfvs, type, mPool); + } + + // indicates this message came from the wire, set by the Transport + bool mIsExternal; + + // !bwc! Would be nice to tweak this to automatically make SipMessage 4KB, + // but I don't know how ugly it would be. + DinkyPool<2968> mPool; + + typedef std::vector<HeaderFieldValueList*, + StlPoolAllocator<HeaderFieldValueList*, + PoolBase > > TypedHeaders; + // raw text corresponding to each typed header (not yet parsed) + TypedHeaders mHeaders; + + // !bwc! Indices into mHeaders + short mHeaderIndices[Headers::MAX_HEADERS]; + + // raw text corresponding to each unknown header + UnknownHeaders mUnknownHeaders; + + // !jf! + const Transport* mTransport; + + // For messages received from the wire, this indicates where it came + // from. Can be used to get to the Transport and/or reliable Connection + Tuple mSource; + + // Used by the TU to specify where a message is to go + Tuple mDestination; + + // Raw buffers coming from the Transport. message manages the memory + std::vector<char*> mBufferList; + + // special case for the first line of message + StartLine* mStartLine; + char mStartLineMem[sizeof(RequestLine) > sizeof(StatusLine) ? sizeof(RequestLine) : sizeof(StatusLine)]; + + // raw text for the contents (all of them) + HeaderFieldValue mContentsHfv; + + // lazy parser for the contents + mutable Contents* mContents; + + // cached value of a hash of the transaction id for a message received + // from a 2543 sip element. as per rfc3261 see 17.2.3 + mutable Data mRFC2543TransactionId; + + // is a request or response + bool mRequest; + bool mResponse; + + bool mInvalid; + resip::Data* mReason; + + UInt64 mCreatedTime; + + // used when next element is a strict router OR + // client forces next hop OOB + Uri* mForceTarget; + + // domain associated with this message for tls cert + Data mTlsDomain; + + // peers domain associate with this message (MTLS) + std::list<Data> mTlsPeerNames; + + std::auto_ptr<SecurityAttributes> mSecurityAttributes; + + std::vector<MessageDecorator*> mOutboundDecorators; + + friend class TransportSelector; +}; + +} + +#undef ensureHeaderTypeUseable +#undef ensureSingleHeader +#undef ensureMultiHeader +#undef defineHeader +#undef defineMultiHeader + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/SipStack.cxx b/src/libs/resiprocate/resip/stack/SipStack.cxx new file mode 100644 index 00000000..55bb9f49 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SipStack.cxx @@ -0,0 +1,1054 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#ifndef WIN32 +#include <unistd.h> +#include <netdb.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#endif + +#include "rutil/compat.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Fifo.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Random.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Timer.hxx" +#include "rutil/FdPoll.hxx" + +#include "rutil/dns/DnsThread.hxx" +#include "resip/stack/Message.hxx" +#include "resip/stack/ShutdownMessage.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/ApplicationMessage.hxx" +#include "resip/stack/SipStack.hxx" +#include "rutil/Inserter.hxx" +#include "resip/stack/StatisticsManager.hxx" +#include "rutil/AsyncProcessHandler.hxx" +#include "resip/stack/TcpTransport.hxx" +#include "resip/stack/UdpTransport.hxx" +#include "resip/stack/TransactionUser.hxx" +#include "resip/stack/TransactionUserMessage.hxx" +#include "resip/stack/TransactionControllerThread.hxx" +#include "resip/stack/TransportSelectorThread.hxx" +#include "rutil/WinLeakCheck.hxx" + +#ifdef USE_SSL +#include "resip/stack/ssl/Security.hxx" +#include "resip/stack/ssl/DtlsTransport.hxx" +#include "resip/stack/ssl/TlsTransport.hxx" +#endif + +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) +#endif + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +SipStack::SipStack(const SipStackOptions& options) : + mTUFifo(TransactionController::MaxTUFifoTimeDepthSecs, + TransactionController::MaxTUFifoSize), + mTuSelector(mTUFifo), + mAppTimers(mTuSelector), + mStatsManager(*this) +{ + // WARNING - don't forget to add new member initialization to the init() method + init(options); + mTUFifo.setDescription("SipStack::mTUFifo"); +} + + +SipStack::SipStack(Security* pSecurity, + const DnsStub::NameserverList& additional, + AsyncProcessHandler* handler, + bool stateless, + AfterSocketCreationFuncPtr socketFunc, + Compression *compression, + FdPollGrp *pollGrp) : + mPollGrp(pollGrp?pollGrp:FdPollGrp::create()), + mPollGrpIsMine(!pollGrp), +#ifdef USE_SSL + mSecurity( pSecurity ? pSecurity : new Security()), +#else + mSecurity(0), +#endif + mDnsStub(new DnsStub(additional, socketFunc, handler, mPollGrp)), + mDnsThread(0), + mCompression(compression ? compression : new Compression(Compression::NONE)), + mAsyncProcessHandler(handler ? handler : new SelectInterruptor), + mInterruptorIsMine(!handler), + mTUFifo(TransactionController::MaxTUFifoTimeDepthSecs, + TransactionController::MaxTUFifoSize), + mCongestionManager(0), + mTuSelector(mTUFifo), + mAppTimers(mTuSelector), + mStatsManager(*this), + mTransactionController(new TransactionController(*this, mAsyncProcessHandler)), + mTransactionControllerThread(0), + mTransportSelectorThread(0), + mRunning(false), + mShuttingDown(false), + mStatisticsManagerEnabled(true), + mSocketFunc(socketFunc) +{ + Timer::getTimeMs(); // initalize time offsets + Random::initialize(); + initNetwork(); + if (pSecurity) + { +#ifdef USE_SSL + pSecurity->preload(); +#else + assert(0); +#endif + } + + mTUFifo.setDescription("SipStack::mTUFifo"); + mTransactionController->transportSelector().setPollGrp(mPollGrp); + +#if 0 + // .kw. originally tried to share common init() for the two + // constructors, but too much risk for changing sequencing, + // first prove out new constructor before merging (or obsoleting) + mTUFifo(TransactionController::MaxTUFifoTimeDepthSecs, + TransactionController::MaxTUFifoSize), + mTuSelector(mTUFifo), + mAppTimers(mTuSelector), + mStatsManager(*this) +{ + SipStackOptions options; + options.mSecurity = pSecurity; + options.mExtraNameserverList = &additional; + options.mStateless = stateless; + options.mSocketFunc = socketFunc; + options.mCompression = compression; + options.mPollGrp = pollGrp; + init(options); +#endif +} + +void +SipStack::init(const SipStackOptions& options) +{ + mPollGrpIsMine=false; + if ( options.mPollGrp ) + { + mPollGrp = options.mPollGrp; + } + else + { + mPollGrp = FdPollGrp::create(); + mPollGrpIsMine=true; + } + +#ifdef USE_SSL + mSecurity = options.mSecurity ? options.mSecurity : new Security(); + mSecurity->preload(); +#else + mSecurity = 0; + assert(options.mSecurity==0); +#endif + + if(options.mAsyncProcessHandler) + { + mAsyncProcessHandler = options.mAsyncProcessHandler; + mInterruptorIsMine = false; + } + else + { + mInterruptorIsMine = true; + mAsyncProcessHandler = new SelectInterruptor; + } + + mDnsStub = new DnsStub( + options.mExtraNameserverList + ? *options.mExtraNameserverList : DnsStub::EmptyNameserverList, + options.mSocketFunc, + mAsyncProcessHandler, + mPollGrp); + mDnsThread = 0; + + mCompression = options.mCompression + ? options.mCompression : new Compression(Compression::NONE); + + mCongestionManager = 0; + + // WATCHOUT: the transaction controller constructor will + // grab the security, DnsStub, compression and statsManager + mTransactionController = new TransactionController(*this, mAsyncProcessHandler); + mTransactionController->transportSelector().setPollGrp(mPollGrp); + mTransactionControllerThread = 0; + mTransportSelectorThread = 0; + + mRunning = false; + mShuttingDown = false; + mStatisticsManagerEnabled = true; + mSocketFunc = options.mSocketFunc; + + // .kw. note that stats manager has already called getTimeMs() + Timer::getTimeMs(); // initalize time offsets + Random::initialize(); + initNetwork(); +} + +SipStack::~SipStack() +{ + DebugLog (<< "SipStack::~SipStack()"); + shutdownAndJoinThreads(); + + delete mDnsThread; + mDnsThread=0; + delete mTransactionControllerThread; + mTransactionControllerThread=0; + delete mTransportSelectorThread; + mTransportSelectorThread=0; + + delete mTransactionController; +#ifdef USE_SSL + delete mSecurity; +#endif + delete mCompression; + + delete mDnsStub; + if (mPollGrpIsMine) + { + // delete pollGrp after deleting DNS + delete mPollGrp; + mPollGrp=0; + } + + if(mInterruptorIsMine) + { + delete mAsyncProcessHandler; + mAsyncProcessHandler=0; + } + +} + +void +SipStack::run() +{ + if(mRunning) + { + return; + } + + mRunning=true; + delete mDnsThread; + mDnsThread=new DnsThread(*mDnsStub); + mDnsThread->run(); + + delete mTransactionControllerThread; + mTransactionControllerThread=new TransactionControllerThread(*mTransactionController); + mTransactionControllerThread->run(); + + delete mTransportSelectorThread; + mTransportSelectorThread=new TransportSelectorThread(mTransactionController->transportSelector()); + mTransportSelectorThread->run(); +} + +void +SipStack::shutdown() +{ + InfoLog (<< "Shutting down sip stack " << this); + + { + Lock lock(mShutdownMutex); + assert(!mShuttingDown); + mShuttingDown = true; + } + + mTransactionController->shutdown(); +} + +void +SipStack::shutdownAndJoinThreads() +{ + if(mDnsThread) + { + mDnsThread->shutdown(); + mDnsThread->join(); + } + + if(mTransactionControllerThread) + { + mTransactionControllerThread->shutdown(); + mTransactionControllerThread->join(); + } + + if(mTransportSelectorThread) + { + mTransportSelectorThread->shutdown(); + mTransportSelectorThread->join(); + } + mRunning=false; +} + +Transport* +SipStack::addTransport( TransportType protocol, + int port, + IpVersion version, + StunSetting stun, + const Data& ipInterface, + const Data& sipDomainname, + const Data& privateKeyPassPhrase, + SecurityTypes::SSLType sslType, + unsigned transportFlags, + SecurityTypes::TlsClientVerificationMode cvm, + bool useEmailAsSIP) +{ + assert(!mShuttingDown); + + // If address is specified, ensure it is valid + if(!ipInterface.empty()) + { + if(version == V6) + { + if(!DnsUtil::isIpV6Address(ipInterface)) + { + ErrLog(<< "Failed to create transport, invalid ipInterface specified (IP address required): V6 " + << Tuple::toData(protocol) << " " << port << " on " + << ipInterface.c_str()); + throw Transport::Exception("Invalid ipInterface specified (IP address required)", __FILE__,__LINE__); + } + } + else // V4 + { + if(!DnsUtil::isIpV4Address(ipInterface)) + { + ErrLog(<< "Failed to create transport, invalid ipInterface specified (IP address required): V4 " + << Tuple::toData(protocol) << " " << port << " on " + << ipInterface.c_str()); + throw Transport::Exception("Invalid ipInterface specified (IP address required)", __FILE__,__LINE__); + } + } + } + + InternalTransport* transport=0; + Fifo<TransactionMessage>& stateMacFifo = mTransactionController->transportSelector().stateMacFifo(); + try + { + switch (protocol) + { + case UDP: + transport = new UdpTransport(stateMacFifo, port, version, stun, ipInterface, mSocketFunc, *mCompression, transportFlags); + break; + case TCP: + transport = new TcpTransport(stateMacFifo, port, version, ipInterface, mSocketFunc, *mCompression, transportFlags); + break; + case TLS: +#if defined( USE_SSL ) + transport = new TlsTransport(stateMacFifo, + port, + version, + ipInterface, + *mSecurity, + sipDomainname, + sslType, + mSocketFunc, + *mCompression, + transportFlags, + cvm, + useEmailAsSIP); +#else + CritLog (<< "TLS not supported in this stack. You don't have openssl"); + assert(0); +#endif + break; + case DTLS: +#if defined( USE_DTLS ) + transport = new DtlsTransport(stateMacFifo, + port, + version, // !jf! stun + ipInterface, + *mSecurity, + sipDomainname, + mSocketFunc, + *mCompression); +#else + CritLog (<< "DTLS not supported in this stack."); + assert(0); +#endif + break; + default: + assert(0); + break; + } + } + catch (BaseException& e) + { + ErrLog(<< "Failed to create transport: " + << (version == V4 ? "V4" : "V6") << " " + << Tuple::toData(protocol) << " " << port << " on " + << (ipInterface.empty() ? "ANY" : ipInterface.c_str()) + << ": " << e); + throw; + } + addTransport(std::auto_ptr<Transport>(transport)); + return transport; +} + +void +SipStack::addTransport(std::auto_ptr<Transport> transport) +{ + //.dcm. once addTransport starts throwing, need to back out alias + if (!transport->interfaceName().empty()) + { + addAlias(transport->interfaceName(), transport->port()); + } + else + { + // Using INADDR_ANY, get all IP interfaces + std::list<std::pair<Data, Data> > ipIfs(DnsUtil::getInterfaces()); + if(transport->ipVersion()==V4) + { + ipIfs.push_back(std::make_pair<Data,Data>("lo0","127.0.0.1")); + } + while(!ipIfs.empty()) + { + if(DnsUtil::isIpV4Address(ipIfs.back().second)== + (transport->ipVersion()==V4)) + { + addAlias(ipIfs.back().second, transport->port()); + } + ipIfs.pop_back(); + } + } + mPorts.insert(transport->port()); + mTransactionController->transportSelector().addTransport(transport,true); +} + +Fifo<TransactionMessage>& +SipStack::stateMacFifo() +{ + return mTransactionController->transportSelector().stateMacFifo(); +} + +void +SipStack::addAlias(const Data& domain, int port) +{ + int portToUse = (port == 0) ? Symbols::DefaultSipPort : port; + + //DebugLog (<< "Adding domain alias: " << domain << ":" << portToUse); + assert(!mShuttingDown); + mDomains.insert(domain + ":" + Data(portToUse)); + + + if(mUri.host().empty()) + { + mUri.host()=*mDomains.begin(); + } + +} + +Data +SipStack::getHostname() +{ + // if you change this, please #def old version for windows + char hostName[1024]; + int err = gethostname( hostName, sizeof(hostName) ); + if(err != 0) + { + ErrLog(<< "gethostname failed with return " << err << " Returning " + "\"localhost\""); + assert(0); + return "localhost"; + } + + struct hostent* hostEnt = gethostbyname( hostName ); + if ( !hostEnt ) + { + // this can fail when there is no name server + // !cj! - need to decided what error to return + ErrLog( << "gethostbyname failed - name server is probably down" ); + return "localhost"; + } + assert( hostEnt ); + + struct in_addr* addr = (struct in_addr*) hostEnt->h_addr_list[0]; + assert( addr ); + + // if you change this, please #def old version for windows + char* addrA = inet_ntoa( *addr ); + Data ret(addrA); + + Data retHost( hostEnt->h_name ); + + return retHost; +} + + +Data +SipStack::getHostAddress() +{ + // if you change this, please #def old version for windows + char hostName[1024]; + int err = gethostname( hostName, sizeof(hostName) ); + if(err != 0) + { + ErrLog(<< "gethostname failed with return " << err << " Returning " + "\"127.0.0.1\""); + assert(0); + return "127.0.0.1"; + } + + struct hostent* hostEnt = gethostbyname( hostName ); + if(!hostEnt) + { + ErrLog(<< "gethostbyname failed, returning \"127.0.0.1\""); + assert(0); + return "127.0.0.1"; + } + + struct in_addr* addr = (struct in_addr*) hostEnt->h_addr_list[0]; + if( !addr ) + { + ErrLog(<< "gethostbyname returned a hostent* with an empty h_addr_list," + " returning \"127.0.0.1\""); + assert(0); + return "127.0.0.1"; + } + + // if you change this, please #def old version for windows + char* addrA = inet_ntoa( *addr ); + Data ret(addrA); + + //Data retHost( hostEnt->h_name ); + + return ret; +} + +bool +SipStack::isMyDomain(const Data& domain, int port) const +{ + return (mDomains.count(domain + ":" + + Data(port == 0 ? Symbols::DefaultSipPort : port)) != 0); +} + +bool +SipStack::isMyPort(int port) const +{ + return mPorts.count(port) != 0; +} + +const Uri& +SipStack::getUri() const +{ + if(mUri.host().empty()) + { + CritLog(<< "There are no associated transports"); + throw Exception("No associated transports", __FILE__, __LINE__); + } + + return mUri; +} + +void +SipStack::send(const SipMessage& msg, TransactionUser* tu) +{ + DebugLog (<< "SEND: " << msg.brief()); + //DebugLog (<< msg); + //assert(!mShuttingDown); + + SipMessage* toSend = static_cast<SipMessage*>(msg.clone()); + if (tu) + { + toSend->setTransactionUser(tu); + } + toSend->setFromTU(); + + mTransactionController->send(toSend); +} + +void +SipStack::send(std::auto_ptr<SipMessage> msg, TransactionUser* tu) +{ + DebugLog (<< "SEND: " << msg->brief()); + + if (tu) + { + msg->setTransactionUser(tu); + } + msg->setFromTU(); + + mTransactionController->send(msg.release()); +} + +void +SipStack::sendTo(std::auto_ptr<SipMessage> msg, const Uri& uri, TransactionUser* tu) +{ + if (tu) msg->setTransactionUser(tu); + msg->setForceTarget(uri); + msg->setFromTU(); + + mTransactionController->send(msg.release()); +} + +void +SipStack::sendTo(std::auto_ptr<SipMessage> msg, const Tuple& destination, TransactionUser* tu) +{ + assert(!mShuttingDown); + + if (tu) msg->setTransactionUser(tu); + msg->setDestination(destination); + msg->setFromTU(); + + mTransactionController->send(msg.release()); +} + +// this is only if you want to send to a destination not in the route. You +// probably don't want to use it. +void +SipStack::sendTo(const SipMessage& msg, const Uri& uri, TransactionUser* tu) +{ + //assert(!mShuttingDown); + + SipMessage* toSend = static_cast<SipMessage*>(msg.clone()); + if (tu) toSend->setTransactionUser(tu); + toSend->setForceTarget(uri); + toSend->setFromTU(); + + mTransactionController->send(toSend); +} + +// this is only if you want to send to a destination not in the route. You +// probably don't want to use it. +void +SipStack::sendTo(const SipMessage& msg, const Tuple& destination, TransactionUser* tu) +{ + assert(!mShuttingDown); + + SipMessage* toSend = static_cast<SipMessage*>(msg.clone()); + if (tu) toSend->setTransactionUser(tu); + toSend->setDestination(destination); + toSend->setFromTU(); + + mTransactionController->send(toSend); +} + +void +SipStack::checkAsyncProcessHandler() +{ + if (mAsyncProcessHandler) + { + mAsyncProcessHandler->handleProcessNotification(); + } +} + +void +SipStack::post(std::auto_ptr<ApplicationMessage> message) +{ + assert(!mShuttingDown); + mTuSelector.add(message.release(), TimeLimitFifo<Message>::InternalElement); +} + +void +SipStack::post(const ApplicationMessage& message) +{ + assert(!mShuttingDown); + Message* toPost = message.clone(); + mTuSelector.add(toPost, TimeLimitFifo<Message>::InternalElement); +} + +void +SipStack::post(const ApplicationMessage& message, unsigned int secondsLater, + TransactionUser* tu) +{ + assert(!mShuttingDown); + postMS(message, secondsLater*1000, tu); +} + +void +SipStack::postMS(const ApplicationMessage& message, unsigned int ms, + TransactionUser* tu) +{ + assert(!mShuttingDown); + Message* toPost = message.clone(); + if (tu) toPost->setTransactionUser(tu); + Lock lock(mAppTimerMutex); + mAppTimers.add(ms,toPost); + //.dcm. timer update rather than process cycle...optimize by checking if sooner + //than current timeTillNextProcess? + checkAsyncProcessHandler(); +} + +void +SipStack::post(std::auto_ptr<ApplicationMessage> message, + unsigned int secondsLater, + TransactionUser* tu) +{ + postMS(message, secondsLater*1000, tu); +} + + +void +SipStack::postMS( std::auto_ptr<ApplicationMessage> message, + unsigned int ms, + TransactionUser* tu) +{ + assert(!mShuttingDown); + if (tu) message->setTransactionUser(tu); + Lock lock(mAppTimerMutex); + mAppTimers.add(ms, message.release()); + //.dcm. timer update rather than process cycle...optimize by checking if sooner + //than current timeTillNextProcess? + checkAsyncProcessHandler(); +} + +void +SipStack::abandonServerTransaction(const Data& tid) +{ + mTransactionController->abandonServerTransaction(tid); +} + +void +SipStack::cancelClientInviteTransaction(const Data& tid) +{ + mTransactionController->cancelClientInviteTransaction(tid); +} + +bool +SipStack::hasMessage() const +{ + return mTUFifo.messageAvailable(); +} + +SipMessage* +SipStack::receive() +{ + // Check to see if a message is available and if it is return the + // waiting message. Otherwise, return 0 + if (mTUFifo.messageAvailable()) + { + // we should only ever have SIP messages on the TU Fifo + // unless we've registered for termination messages. + Message* msg = mTUFifo.getNext(); + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + if (sip) + { + DebugLog (<< "RECV: " << sip->brief()); + return sip; + } + else + { + // assert(0); // !CJ! removed the assert - happens 1 minute after + // stack starts up + delete msg; + return 0; + } + } + else + { + return 0; + } +} + +Message* +SipStack::receiveAny() +{ + // Check to see if a message is available and if it is return the + // waiting message. Otherwise, return 0 + if (mTUFifo.messageAvailable()) + { + // application messages can flow through + Message* msg = mTUFifo.getNext(); + SipMessage* sip=dynamic_cast<SipMessage*>(msg); + if (sip) + { + DebugLog (<< "RECV: " << sip->brief()); + } + return msg; + } + else + { + return 0; + } +} + +void +SipStack::setFallbackPostNotify(AsyncProcessHandler *handler) +{ + mTuSelector.setFallbackPostNotify(handler); +} + +/* Called from external epoll (e.g., EventStackThread) */ +void +SipStack::processTimers() +{ + if(!mShuttingDown && mStatisticsManagerEnabled) + { + mStatsManager.process(); + } + + if(!mTransactionControllerThread) + { + mTransactionController->process(); + } + + if(!mDnsThread) + { + mDnsStub->processTimers(); + } + + if(!mTransportSelectorThread) + { + mTransactionController->transportSelector().process(); + } + + mTuSelector.process(); + Lock lock(mAppTimerMutex); + mAppTimers.process(); +} + +/* Called for internal epoll and non-epoll (e.g., StackThread) */ +void +SipStack::process(FdSet& fdset) +{ + if (mPollGrp) + mPollGrp->processFdSet(fdset); + processTimers(); +} + +bool +SipStack::process(unsigned int timeoutMs) +{ + // Go ahead and do this first. Should cut down on how frequently we call + // waitAndProcess() with a timeout of 0, which should improve efficiency + // somewhat. + processTimers(); + bool result = false; + if (mPollGrp) + result = mPollGrp->waitAndProcess(resipMin(timeoutMs, getTimeTillNextProcessMS())); + return result; +} + +/// returns time in milliseconds when process next needs to be called +unsigned int +SipStack::getTimeTillNextProcessMS() +{ + Lock lock(mAppTimerMutex); + + unsigned int dnsNextProcess = (mDnsThread ? + INT_MAX : mDnsStub->getTimeTillNextProcessMS()); + unsigned int tcNextProcess = mTransactionControllerThread ? INT_MAX : + mTransactionController->getTimeTillNextProcessMS(); + unsigned int tsNextProcess = mTransportSelectorThread ? INT_MAX : mTransactionController->transportSelector().getTimeTillNextProcessMS(); + + return resipMin(Timer::getMaxSystemTimeWaitMs(), + resipMin(dnsNextProcess, + resipMin(tcNextProcess, + resipMin(tsNextProcess, + resipMin(mTuSelector.getTimeTillNextProcessMS(), mAppTimers.msTillNextTimer()))))); +} + +void +SipStack::buildFdSet(FdSet& fdset) +{ + if (mPollGrp) + mPollGrp->buildFdSet(fdset); +} + +Security* +SipStack::getSecurity() const +{ + return mSecurity; +} + +void +SipStack::setStatisticsInterval(unsigned long seconds) +{ + mStatsManager.setInterval(seconds); +} + +void +SipStack::zeroOutStatistics() +{ + if(statisticsManagerEnabled()) + { + mTransactionController->zeroOutStatistics(); + } +} + +bool +SipStack::pollStatistics() +{ + if(statisticsManagerEnabled()) + { + mTransactionController->pollStatistics(); + return true; + } + return false; +} + +void +SipStack::registerTransactionUser(TransactionUser& tu) +{ + mTuSelector.registerTransactionUser(tu); +} + +void +SipStack::requestTransactionUserShutdown(TransactionUser& tu) +{ + mTuSelector.requestTransactionUserShutdown(tu); + checkAsyncProcessHandler(); +} + +void +SipStack::unregisterTransactionUser(TransactionUser& tu) +{ + mTuSelector.unregisterTransactionUser(tu); + checkAsyncProcessHandler(); +} + +void +SipStack::registerMarkListener(MarkListener* listener) +{ + mTransactionController->registerMarkListener(listener); +} + +void +SipStack::unregisterMarkListener(MarkListener* listener) +{ + mTransactionController->unregisterMarkListener(listener); +} + +DnsStub& +SipStack::getDnsStub() const +{ + return *mDnsStub; +} + +void +SipStack::setEnumSuffixes(const std::vector<Data>& suffixes) +{ + mDnsStub->setEnumSuffixes(suffixes); +} + +void +SipStack::setEnumDomains(const std::map<Data,Data>& domains) +{ + mDnsStub->setEnumDomains(domains); +} + +void +SipStack::clearDnsCache() +{ + mDnsStub->clearDnsCache(); +} + +void +SipStack::logDnsCache() +{ + mDnsStub->logDnsCache(); +} + +void +SipStack::getDnsCacheDump(std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler) +{ + mDnsStub->getDnsCacheDump(key, handler); +} + +volatile bool& +SipStack::statisticsManagerEnabled() +{ + return mStatisticsManagerEnabled; +} + +const bool +SipStack::statisticsManagerEnabled() const +{ + return mStatisticsManagerEnabled; +} + +EncodeStream& +SipStack::dump(EncodeStream& strm) const +{ + Lock lock(mAppTimerMutex); + strm << "SipStack: " << (this->mSecurity ? "with security " : "without security ") + << std::endl + << "domains: " << Inserter(this->mDomains) + << std::endl + << " TUFifo size=" << this->mTUFifo.size() << std::endl + << " Timers size=" << this->mTransactionController->mTimers.size() << std::endl + << " AppTimers size=" << this->mAppTimers.size() << std::endl + << " ServerTransactionMap size=" << this->mTransactionController->mServerTransactionMap.size() << std::endl + << " ClientTransactionMap size=" << this->mTransactionController->mClientTransactionMap.size() << std::endl + << " Exact Transports=" << Inserter(this->mTransactionController->mTransportSelector.mExactTransports) << std::endl + << " Any Transports=" << Inserter(this->mTransactionController->mTransportSelector.mAnyInterfaceTransports) << std::endl; + return strm; +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, +const SipStack& stack) +{ + return stack.dump(strm); +} + +void +SipStack::terminateFlow(const resip::Tuple& flow) +{ + mTransactionController->terminateFlow(flow); +} + +void +SipStack::enableFlowTimer(const resip::Tuple& flow) +{ + mTransactionController->enableFlowTimer(flow); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/SipStack.hxx b/src/libs/resiprocate/resip/stack/SipStack.hxx new file mode 100644 index 00000000..5dfe9a91 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SipStack.hxx @@ -0,0 +1,1149 @@ +#if !defined(RESIP_SIPSTACK_HXX) +#define RESIP_SIPSTACK_HXX + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <set> +#include <iosfwd> + +#include "rutil/CongestionManager.hxx" +#include "rutil/FdSetIOObserver.hxx" +#include "rutil/TimeLimitFifo.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/TransportType.hxx" +#include "rutil/BaseException.hxx" +#include "resip/stack/TransactionController.hxx" +#include "resip/stack/SecurityTypes.hxx" +#include "resip/stack/StatisticsManager.hxx" +#include "resip/stack/TuSelector.hxx" +#include "rutil/dns/DnsStub.hxx" + +/** + Let external applications know that this version of the stack + supports the (e)poll interfaces. +**/ +#define RESIP_SIPSTACK_HAVE_FDPOLL 1 + +namespace resip +{ + +class ApplicationMessage; +class Data; +class DnsThread; +class Message; +class Security; +class SipMessage; +class StatisticsManager; +class Tuple; +class Uri; +class TransactionControllerThread; +class TransportSelectorThread; +class TransactionUser; +class AsyncProcessHandler; +class Compression; +class FdPollGrp; + +/** + This class holds constructor-time initialization arguments for SipStack. + + Most values are pointers, and default to zero unless otherwise indicated. + + It has public members: + mSecurity + Security Object required by the stack for TLS, DTLS, SMIME and + Identity-draft compliance. If empty the stack will not support + these advanced security features. The compile flag USE_SSL is + also required. The security object will be owned by the SipStack + and deleted in the SipStack destructor. + + mAsyncProcessHandler + AsyncProcessHandler that will be invoked when Messages + are posted to the stack. Posted messages are added + to thread-safe queue, and then processed later within + event loop. For example: SelectInterruptor. + + mStateless + This parameter does not appear to be used. Default false. + + mSocketFunc + A pointer to a function that will be called after a socket in + the DNS or SIP transport layers of the stack has been created. + This callback can be used to control low level socket options, + such as Quality-of-Service/DSCP. Note: For SIP TCP sockets + there is one call for the listen socket, and one (or two) + calls for each connection created afterwards. For each inbound + TCP connection the first callback is called immediately before + the socket is connected, and if configured it is called again + after the connect call has completed and before the first data + is sent out. On some OS's you cannot set QOS until the socket + is successfully connected. To enable this behavior call: + Connection::setEnablePostConnectSocketFuncCall(); + + mCompression + Compression configuration object required for + SigComp. If set to 0, then SigComp compression + will be disabled. The SipStack takes ownership of this object, + and will be deleted in the destructor. + + mPollGrp + Polling group to support file-io callbacks. + See EventStackThread. The SipStack does NOT take ownership; + the application (or a helper such as EventStackSimpleMgr) must + release this object after the SipStack is destructed. +**/ +class SipStackOptions +{ + public: + SipStackOptions() + : mSecurity(0), mExtraNameserverList(0), + mAsyncProcessHandler(0), mStateless(false), + mSocketFunc(0), mCompression(0), mPollGrp(0) + { + } + + Security* mSecurity; + const DnsStub::NameserverList* mExtraNameserverList; + AsyncProcessHandler* mAsyncProcessHandler; + bool mStateless; + AfterSocketCreationFuncPtr mSocketFunc; + Compression *mCompression; + FdPollGrp* mPollGrp; +}; + + + +/** + @brief This is the primary point of interaction between the app-layer and the + stack. + + @details For a SipStack to be usable, transports must be added by calling + the addTransport() method. + + The useful work done by SipStack occurs when + SipStack::process(unsigned int) is called. A separate thread (such + as EventStackThread) can be dedicated to this task, or it can be called + from within a loop in the main thread of the executable. + + Graceful shutdown is accomplished by advising the SipStack to begin + shutdown procedures via the shutdown() method. The SipStack should + continue to be serviced through the process(unsigned int) method until the + Transaction User is informed by receiving a ShutdownMessage that + the requested shutdown is complete. + + @note Previously, buildFdSet(FdSet&), FdSet::select(), and process(FdSet&) + were the canonical way of giving the SipStack cycles. Because of + shortcomings of the fd_set approach, these have been deprecated. + + @ingroup resip_crit + @ingroup resip_config +*/ +class SipStack : public FdSetIOObserver +{ + public: + /** + Constructor. First instantiate SipStackOptions, then set + any values special to your application, then call this constructor. + The {options} instance is not referenced after construction (i.e., + the SipStack doesn't keep a reference to it). However, it does + copy each individual value, and takes ownership of several + of the objects. + **/ + SipStack(const SipStackOptions& options); + + /** + Constructor. This constructor is obsolete. The SipStackOptions-based + constructor should be used instead. + + @param security Security Object required by the stack for TLS, DTLS, SMIME + and Identity-draft compliance. If 0 is passed in + the stack will not support these advanced security + features. The compile flag USE_SSL is also required. + The security object will be owned by the SipStack and + deleted in the SipStack destructor. Default is 0. + + @param handler AsyncProcessHandler that will be invoked when Messages + are posted to the stack. For example: SelectInterruptor. + Default is 0. + + @param stateless This parameter does not appear to be used. + + @param socketFunc A pointer to a function that will be called after a socket + in the DNS or SIP transport layers of the stack has been + created. This callback can be used to control low level + socket options, such as Quality-of-Service/DSCP. + Note: For SIP TCP sockets there is one call for the listen + socket, and one (or two) calls for each connection created + afterwards. For each inbound TCP connection the first + callback is called immediately before the socket is connected, + and if configured it is called again after the connect call + has completed and before the first data is sent out. + On some OS's you cannot set QOS until the socket is successfully + connected. To enable this behavior call: + Connection::setEnablePostConnectSocketFuncCall(); + + @param compression Compression configuration object required for + SigComp. If set to 0, then SigComp compression + will be disabled. + + @param pollGrp Polling group to support file-io callbacks; if one + is not passed, one will be created. Ownership is + not taken. + */ + SipStack(Security* security=0, + const DnsStub::NameserverList& additional = DnsStub::EmptyNameserverList, + AsyncProcessHandler* handler = 0, + bool stateless=false, + AfterSocketCreationFuncPtr socketFunc = 0, + Compression *compression = 0, + FdPollGrp* pollGrp = 0); + + virtual ~SipStack(); + + /** + @brief Causes this SipStack object to create and run threads for carrying + out processing. + + This includes a thread for DNS lookups, a thread for + transaction processing, and a thread for transport processing + (individual Transport objects may be registered as having their own + thread; these are not serviced by the thread spawned by this call). + This function is intended to be used in addition to the normal method/s + of giving the SipStack cycles (eg; EventStackThread, StackThread, etc); + these are still necessary to give the SipStack cycles for handling + application timers, statistics logging, and shutdown logic. + */ + void run(); + + /** + @brief perform orderly shutdown + @details Inform the transaction state machine processor that it should not + create any new transactions and to perform an orderly shutdown. When + the transactions are all terminated, return a ShutdownMessage to the TU. + @note If the SipStack is running in multithreaded mode, this function + DOES NOT shut down the threads. This is what + shutdownAndJoinThreads() is for. (Shutting down threads in this call + would prevent orderly shutdown from working; outstanding + transactions would be dropped on the floor) + */ + void shutdown(); + + /** + @brief Shutdown and join any threads that the SipStack is running. + */ + void shutdownAndJoinThreads(); + + /** + @brief thrown when the stack is unable to function. + @details For instance, the stack cannot process messages because + there are no transports associated with the stack. + */ + class Exception : public BaseException + { + public: + /** + @brief constructor + @param msg The message to be put in the exception + @param file The source code file where the exception got thrown + @param line The line number in the file where the exception + got thrown + @note Used thus in SipStack.cxx: + throw Exception("exception message", __FILE__, __LINE__); + */ + Exception(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) {} + + /** + @brief what gets called instead of the pure virtual in the base + */ + const char* name() const { return "SipStack::Exception"; } + }; + + /** + Used by the application to add in a new built-in transport. The transport is + created and then added to the Transport Selector. + + @throws Transport::Exception If the transport couldn't be added, usually + because the port was already bound. + + @param protocol TCP, UDP, TLS, DTLS, etc. + + @param port Specifies which port to bind to. + + @param version Protocol Version: V4 or V6 + + @param stun Specifies whether STUN is enabled. + + @param ipInterface Specifies which ethernet interface to bind to. If set to + Data::Empty, bind to all interfaces. Binding to all + interfaces can impose a performance penalty, however, so it is + recommended that you bind to specific interfaces when using in + high-throughput deployments. Note: Interfaces + must be identified via IP address. + + @param sipDomainname Only allow messages to + be sent as the specified domain. For default case, + you can pass in domainname = DnsUtil::getLocalDomainName(). + + @param privateKeyPassPhrase Private key pass phrase used to decrypt private key + certificates. Note: For now this parameter is not used + we are loading PKCS7 keys, so a pass phrase is not required. + + @param sslType Version of the TLS specification to use: SSLv23 or TLSv1 + + @param cvm SSL verify mode for the peer (whether we accept and/or + insist on a client certificate from the peer) + + @param useEmailAsSIP If true, we will accept the email address in a client's + subjectAltName as if it were a SIP URI. This is convenient + because many commercial CAs offer email certificates but not + sip: certificates. For reasons of standards compliance, it + is disabled by default. + */ + Transport* addTransport( TransportType protocol, + int port, + IpVersion version=V4, + StunSetting stun=StunDisabled, + const Data& ipInterface = Data::Empty, + const Data& sipDomainname = Data::Empty, // only used + // for TLS + // based stuff + const Data& privateKeyPassPhrase = Data::Empty, + SecurityTypes::SSLType sslType = SecurityTypes::TLSv1, + unsigned transportFlags = 0, + SecurityTypes::TlsClientVerificationMode cvm = SecurityTypes::None, + bool useEmailAsSIP = false); + + /** + Used to plug-in custom transports. Adds the transport to the Transport + Selector. + + @param transport Pointer to an externally created transport. SipStack + assumes ownership. + */ + void addTransport( std::auto_ptr<Transport> transport); + + /** + Returns the fifo that subclasses of Transport should use for the rxFifo + cons. param. + + @returns A fifo of TransactionMessage's + */ + Fifo<TransactionMessage>& stateMacFifo(); + + /** + @brief add an alias for this sip element + + @details Used to add an alias for this sip element. e.g. foobar.com and boo.com + are both handled by this stack. Not threadsafe. Alias is added + to internal list of Domains and can be checked with isMyDomain. + + @param domain Domain name that this stack is responsible for. + + @param port Port for domain that this stack is responsible for. + @ingroup resip_config + */ + void addAlias(const Data& domain, int port); + + /** + Returns true if domain is handled by this stack. Convenience for + Transaction Users. + + @param domain Domain name to check. + + @param port Port number to check. + */ + bool isMyDomain(const Data& domain, int port) const; + + /** + Returns true if port is handled by this stack. Convenience for + Transaction Users. + + @param port Port number to check. + */ + bool isMyPort(int port) const; + + /** + Get one of the names for this host (calls through to gethostbyname) and + is not threadsafe. + */ + static Data getHostname(); + + /** + Get one of the IP address for this host (calls through to gethostbyname) and + is not threadsafe. + */ + static Data getHostAddress(); + + /** + Get one of the domains/ports that are handled by this stack in Uri form. + "sip:" scheme is assumed. + */ + const Uri& getUri() const; + + /** + @brief allows a TU to send a message + @details Interface for the TU to send a message. Makes a copy of the + SipMessage. Caller is responsible for deleting the memory and may do + so as soon as it returns. Loose Routing processing as per RFC3261 must + be done before calling send by the TU. See Helper::processStrictRoute + + @param msg SipMessage to send. + + @param tu TransactionUser to send from. + + @sa TransactionUser + */ + void send(const SipMessage& msg, TransactionUser* tu=0); + + void send(std::auto_ptr<SipMessage> msg, TransactionUser* tu = 0); + + /** @brief this is only if you want to send to a destination not in the route. + @note You probably don't want to use it. */ + void sendTo(std::auto_ptr<SipMessage> msg, const Uri& uri, TransactionUser* tu=0); + /** @brief this is only if you want to send to a destination not in the route. + @note You probably don't want to use it. */ + void sendTo(std::auto_ptr<SipMessage> msg, const Tuple& tuple, TransactionUser* tu=0); + + /** + @brief send a message to a destination not in the route + @details This is only if you want to send to a destination not in the route. + Useful for implementing Outbound Proxy use. Makes a copy of the + SipMessage. Caller is responsible for deleting the memory and may + do so as soon as it returns. + + @param msg SipMessage to send. + + @param uri Destination to send to, specified as a Uri. + + @param tu TransactionUser to send from. + */ + void sendTo(const SipMessage& msg, const Uri& uri, TransactionUser* tu=0); + + /** + @brief send a message to a destination not in the route + @details This is only if you want to send to a destination not in the route. + Useful for implementing Outbound Proxy use. Makes a copy of the + SipMessage. Caller is responsible for deleting the memory and may + do so as soon as it returns. + + @param msg SipMessage to send. + + @param tuple Destination to send to, specified as a Tuple. + + @param tu TransactionUser to send from. + */ + void sendTo(const SipMessage& msg, const Tuple& tuple, + TransactionUser* tu=0); + + /** + @brief force the a message out over an existing connection + + @details This is only if you want to force send to only send over an existing + connection. If there is no connection, then it will try the next tuple. + If there are no more Tuples to try, then a 503 is sent to the TU. Makes + a copy of the SipMessage. Caller is responsible for deleting the memory + and may do so as soon as it returns. + + @param msg SipMessage to send. + + @param tuple Destination to send to, specified as a Tuple. A + connection to this destination must exist. + + @param tu TransactionUser to send from. + */ + void sendOverExistingConnection(const SipMessage& msg, const Tuple& tuple, + TransactionUser* tu=0); + + /** + @brief Makes the message available to the TU at some later time, specified in + seconds. + + @note TransactionUser subclasses can just post to themselves. + + @param message ApplicationMessage to post + + @param secondsLater Number of seconds before message is to be posted. + + @param tu TransactionUser to post to. + */ + void post(std::auto_ptr<ApplicationMessage> message, + unsigned int secondsLater, + TransactionUser* tu=0); + + /** + @brief Makes the message available to the TU at some later time, specified in + milli-seconds. + + @note TransactionUser subclasses can just post to themselves. + + @param message ApplicationMessage to post + + @param ms Number of milli-seconds before message is to be posted. + + @param tu TransactionUser to post to. + */ + void postMS(const std::auto_ptr<ApplicationMessage> message, + unsigned int ms, + TransactionUser* tu=0); + + /** + @brief Makes the message available to the TU later + + @note TranasctionUser subclasses can just post to themselves. + + @param message ApplicationMessage to post + */ + void post(std::auto_ptr<ApplicationMessage> message); + + /** + @brief Makes the message available to the TU later + + @note Makes a copy of the Message. Caller is responsible for deleting + the memory and may do so as soon as it returns. + + @note TranasctionUser subclasses can just post to themselves. + + @param message ApplicationMessage to post + */ + void post(const ApplicationMessage& message); + + /** + @brief Makes the message available to the TU at some later time, specified in + seconds. + + @note Makes a copy of the ApplicationMessage. Caller is responsible + for deleting the memory and may do so as soon as it returns. + + @note TranasctionUser subclasses can just post to themselves. + + @param message ApplicationMessage to post. + + @param secondsLater Number of seconds before message is to be posted. + + @param tu TransactionUser to post to. + */ + void post(const ApplicationMessage& message, unsigned int secondsLater, + TransactionUser* tu=0); + + /** + @brief Makes the message available to the TU at some later time, specified in + milli-seconds. + + @note Makes a copy of the ApplicationMessage. Caller is responsible for deleting + the memory and may do so as soon as it returns. + + @note TranasctionUser subclasses can just post to themselves. + + @param message ApplicationMessage to post + + @param ms Number of milli-seconds before message is to be posted. + + @param tu TransactionUser to post to. + */ + void postMS(const ApplicationMessage& message, unsigned int ms, + TransactionUser* tu=0); + + /** + Tells the stack that the TU has abandoned a server transaction. This + is provided to allow better behavior in cases where an exception is + thrown due to garbage in the request, and the code catching the + exception has no way of telling whether the original request is still + around. This frees the TU of the obligation to respond to the request. + @param tid The transaction identifier for the server transaction. + @note This function is distinct from cancelClientInviteTransaction(). + */ + void abandonServerTransaction(const Data& tid); + + /** + Tells the stack that the TU wishes to CANCEL an INVITE request. This + frees the TU of the obligation to keep state on whether a 1xx has come + in yet before actually sending a CANCEL request, and also the + obligation of forming the CANCEL request itself. This _does_ _not_ free + the TU of the obligation to handle any INVITE/200 that come in (usually + by sending an ACK to the 200, and then a BYE). + @param tid The transaction identifier of the INVITE request sent. + */ + void cancelClientInviteTransaction(const Data& tid); + + /** + @brief does the stack have new messages for the TU? + @return return true if the stack has new messages for the TU. + + @deprecated Since the addition of TransactionUsers, this method is deprecated. + This only looks into the old TuFifo that is not associated with any TransactionUser. + + */ + bool hasMessage() const; + + /** + @brief retrieve a SipMessage off the old TuFifo + + @details Retrieve a SipMessage off the old TuFifo. Caller now owns the memory. Returns + 0 if nothing there. Since the addition of TransactionUsers, this method + is deprecated. This only looks into the old TuFifo that is not associated + with any TransactionUser. + + @note Applications posting non-sip messages must use receive any. If non + SipMessages are on the Fifo, then they are just deleted. + + @deprecated + + @returns pointer to received SipMessage, 0 if nothing there. + */ + SipMessage* receive(); + + /** + @brief retrieve a message off the old TuFifo + + Retrieve a Message off the old TuFifo. Caller now owns the memory. Returns + 0 if nothing there. Since the addition of TransactionUsers, this method + is deprecated. This only looks into the old TuFifo that is not associated + with any TransactionUser. + + @note Applications posting non-sip messages must use receive any. If non + SipMessages are on the Fifo, then they are just deleted. + + @deprecated + + @returns pointer to received Message, 0 if nothing there. May return + TransactionTerminated*, TimerMessage*, SipMessage* or derived + ApplicationMessage* + */ + Message* receiveAny(); + + /* + * Handler is notified when a message is posted to the default + * application receive queue. (Fetching using receive() above). + * This handler is called from SipStack's thread, and can + * be used to "wake-up" the application's thread. + */ + void setFallbackPostNotify(AsyncProcessHandler *handler); + + /** + Build the FD set to use in a select to find out when process(FdSet&) + must be called again. + + @param fdset an empty or partially populated fdset, fd's are added + to the fdset on return + + @note This must be called prior to calling process. + @note select() must also be called on the fdset prior to process. + + @deprecated Because of serious shortcomings in fd_set (most notably + the inability to store FDs whose value exceeds a relatively small + number; ~1000), we are deprecating the FdSet-based process loop. + @see EventStackThread for an alternative, or if you wish to drive + the SipStack yourself, @see process(unsigned int). On platforms that + do not support epoll, fd_set ends up being used anyway since there + is no other choice, but this is hidden from the app. + */ + RESIP_DEPRECATED(virtual void buildFdSet(FdSet& fdset)); + + /** + This allows the executive to give processing time to stack components. + + @note Must call buildFdSet and select before calling this. + @note The transports are serviced, and then timers are serviced. + + @param fdset a populated and 'select'ed fdset + @deprecated Because of serious shortcomings in fd_set (most notably + the inability to store FDs whose value exceeds a relatively small + number; ~1000), we are deprecating the FdSet-based process loop. + @see EventStackThread for an alternative, or if you wish to drive + the SipStack yourself, @see process(unsigned int). On platforms that + do not support epoll, fd_set ends up being used anyway since there + is no other choice, but this is hidden from the app. + */ + RESIP_DEPRECATED(virtual void process(FdSet& fdset)); + + /** + @brief Give processing time to the SipStack components, when operating + in single-threaded mode. + + This call will allow all the components in the SipStack a chance to + perform processing. This includes: + + - Transaction processing (handling of SIP messages and timers) + - DNS processing (includes DNS network IO and 3263 logic) + - Transport processing (network IO for raw SIP traffic) + - Application timers + + To give the SipStack cycles, it is sufficient to simply call this + function repeatedly. + + @param timeoutMs The maximum time, in milliseconds, we will wait for IO + in this call. We will not necessarily wait this long if no IO + occurs; if timers are scheduled to fire before this duration + elapses, our timeout value will be adjusted accordingly. Similarly, + if there is work waiting in fifos when this call is made, no timeout + will be used. Lower values will cause higher CPU utilization when + idle, higher values may result in processing delays of messages from + the TU sent during the call to process(unsigned int) (eg; you call + process(50), then immediately schedule an app timer to fire in 25ms, + or send a SipMessage to the stack, it could be 50ms before either of + these are processed). You can work around these caveats by creating + a SelectInterruptor, adding its FD to the SipStack's FdPollGrp, and + calling SelectInterruptor::interrupt() to cause + process(unsigned int) to be interrupted. The best approach will + vary, based on your performance needs. + + @note If you wish to add an FD that will interrupt this call if it + becomes ready (either because it has IO you are interested in, or + merely to interrupt this call to carry out some unrelated task, see + getPollGrp()) + + @return Whether any work was done as a result of this call. + */ + bool process(unsigned int timeoutMs); + + inline FdPollGrp* getPollGrp() {return mPollGrp;} + + /** + @brief Returns time in milliseconds when process next needs to be + called. + + @return The maximum time in ms that whatever is giving the + SipStack processing cycles should wait before calling either + process(unsigned int) or process(FdSet&). In most circumstances, this + is simply when the next timer (either an app timer, or a SIP + transaction timer) is scheduled to fire. However, in cases where there + is processing work to be done (in the form of messages in a fifo + somewhere), this will return 0. + */ + virtual unsigned int getTimeTillNextProcessMS(); + + /** + @brief Check all timers + + @note If you are driving this SipStack's IO using its FdPollGrp + directly (because you have more than one stack sharing the FdPollGrp, + for example), you need to call this periodically (see impl of + EventStackThread for an example of this). process(unsigned int) does + this for you. + */ + virtual void processTimers(); + + + /** + @brief Sets the interval that determines the time between Statistics messages + @ingroup resip_config + */ + void setStatisticsInterval(unsigned long seconds); + + /** + @brief Resets all of the cumulative statistics counters. + */ + void zeroOutStatistics(); + + /** + @brief Immediately polls for statistics to be logged and sent to + external handlers, instead of waiting for next statistics interval. + Returns false if statistics manager is not enabled. + */ + bool pollStatistics(); + + /** Installs a handler for the stacks internal StatisticsManager. This handler is called before the + * default behavior. + */ + void setExternalStatsHandler(ExternalStatsHandler *handler) + { + mStatsManager.setExternalStatsHandler(handler); + } + + /** @brief output current state of the stack - for debug **/ + EncodeStream& dump(EncodeStream& strm) const; + + /** @brief Returns a pointer to the embedded Security object, 0 if not set **/ + Security* getSecurity() const; + + /** + @brief add a TU to the TU selection chain + + @details Adds a TU to the TU selection chain. Tu's do not call receive or + receiveAny, the SipStack will call postToTu on the appropriate + Tu. Messages not associated with a registered TU go into SipStack::mTuFifo. + */ + void registerTransactionUser(TransactionUser&); + + /** @brief Queue a shutdown request to the specified TU **/ + void requestTransactionUserShutdown(TransactionUser&); + + /** @brief Removes a TU from the TU selection chain **/ + void unregisterTransactionUser(TransactionUser&); + + /** + Register a handler with the DNS Interface for notifications of when a Dns + Resource Record has been blacklisted. + + @param listener Class implementing the onMark() callback + event sink defined in MarkListener + @ingroup resip_config + */ + void registerMarkListener(MarkListener* listener); + + /** + Removed a registered BlacklistListener handler from the DNS Interface + for a particualr Resource Record type and handler pointer. + + @param listener Class implementing the onMark() callback + event sink defined in MarkListener + + @ingroup resip_config + */ + void unregisterMarkListener(MarkListener* listener); + + DnsStub& getDnsStub() const; + + /** + @brief Specify which enum domains will be searched when sending + + @details Specify which enum domains will be searched when sending to URIs that + return true to Uri::isEnumSearchable(). An enum query will be done for + each suffix in parallel. + + @ingroup resip_config + */ + void setEnumSuffixes(const std::vector<Data>& suffixes); + + /** + @brief Specify which domains in the To: Uri will be subject to ENUM + + @details If the Uri hostname/domain is one of these domains, + the user part will be considered for ENUM search + + @ingroup resip_config + */ + void setEnumDomains(const std::map<Data,Data>& domains); + + /** + @brief Clear the DNS Cache + */ + void clearDnsCache(); + + /** + @brief Log the DNS Cache to WarningLog for Debugging + */ + void logDnsCache(); + + /** + @brief Get a string representation of the DNS Cache. + @param key - a pair representing the request key, can be used + by the callback handler to identify the originating + request + @param handler - pointer to a class that implements the handler + method: onDnsCacheRetrieved + */ + void getDnsCacheDump(std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler); + + /** + @todo is this documented correctly? [!] + @brief Enable Statistics Manager + @details Enable Statistics Manager. SIP Statistics will be collected and + dispatched periodically via a StatisticsMessage. + @note By default the Statistics Manager is enabled. + + @ingroup resip_config + */ + volatile bool& statisticsManagerEnabled(); + const bool statisticsManagerEnabled() const; + + /** + Returns whether the stack is fixing corrupted/changed dialog + identifiers (ie, Call-Id and tags) in responses from the wire. + + @return Denotes whether the stack is fixing corrupted/changed dialog + identifiers. + @see getFixBadDialogIdentifiers() + @ingroup resip_config + */ + bool getFixBadDialogIdentifiers() const + { + return mTransactionController->mFixBadDialogIdentifiers; + } + + /** + Specify whether the stack should fix corrupted/changed dialog + identifiers (ie, Call-Id and tags) in responses from the wire. This is + intended to help TransactionUsers that assume responses will come back + with the same dialog identifiers that the request had (excepting of + course the remote tag for dialog-forming requests). + + @param pFixBadDialogIdentifiers Denotes whether the stack should fix + corrupted/changed dialog identifiers. + @note This is enabled by default, and is recommended for + dialog-stateful TransactionUsers. + @ingroup resip_config + */ + void setFixBadDialogIdentifiers(bool pFixBadDialogIdentifiers) + { + mTransactionController->mFixBadDialogIdentifiers = pFixBadDialogIdentifiers; + } + + inline bool getFixBadCSeqNumbers() const + { + return mTransactionController->getFixBadCSeqNumbers(); + } + + inline void setFixBadCSeqNumbers(bool pFixBadCSeqNumbers) + { + mTransactionController->setFixBadCSeqNumbers(pFixBadCSeqNumbers); + } + + /** + @todo should this be fixed to work with other applicable transports? [] + @brief Used to enable/disable content-length checking on datagram-based + transports. + @details Used to enable/disable content-length checking on datagram-based + transports. If disabled, the stack will ignore the + value of the Content-Length header, and assume that the end of the + payload is at the end of the datagram (and not before). If enabled, it + will take the Content-Length seriously, log a warning if the + Content-Length is too short, and reject the message if the + Content-Length is too long. + @param check Denotes whether we should check Content-Length. + @note By default, Content-Length checking is enabled. + @note only works on UDP at this time + @ingroup resip_config + */ + void setContentLengthChecking(bool check) + { + SipMessage::checkContentLength=check; + } + + /** + Sets the CongestionManager used by the stack. + In order to use a congestion-manager, you will need to create one and + pass it to the SipStack, like so: + + @code + MyCongestionManager* mCM = new MyCongestionManager; + mStack.setCongestionManager(mCM); + @endcode + + This will cause the SipStack to register all its fifos with the + congestion manager, and will also call + TransactionUser::setCongestionManager() for every currently registered + TransactionUser. This means that, if you are working with + such a TransactionUser, you must have registered the TransactionUser + with the SipStack before making this call. + + If you are using the SipStack directly by implementing your own + subclass of TransactionUser, you can override + TransactionUser::setCongestionManager() to register additional fifos + (the default implementation registers TransactionUser::mFifo), like so + + @code + MyTransactionUser::setCongestionManager(CongestionManager* cm) + { + TransactionUser::setCongestionManager(cm); + if(mCongestionManager) + { + mCongestionManager->unregisterFifo(&mExtraFifo); + } + mCongestionManager=cm; + if(mCongestionManager) + { + mCongestionManager->registerFifo(&mExtraFifo); + } + } + @endcode + + @param manager The CongestionManager to use. Ownership is not taken. + @ingroup resip_config + */ + void setCongestionManager ( CongestionManager *manager ) + { + mTransactionController->setCongestionManager(manager); + mTuSelector.setCongestionManager(manager); + if(mCongestionManager) + { + mCongestionManager->unregisterFifo(&mTUFifo); + } + mCongestionManager=manager; + if(mCongestionManager) + { + mCongestionManager->registerFifo(&mTUFifo); + } + } + + /** + @brief Accessor for the CongestionManager object the stack is using. + @return The CongestionManager object being used. + @note If no Compression object was set on construction, this will + return null. + @ingroup resip_config + */ + CongestionManager* getCongestionManager() { return mCongestionManager; } + + /** + @brief Accessor for the Compression object the stack is using. + @return The Compression object being used. + @note If no Compression object was set on construction, this will be + initialized to a null-implementation, so this function will be safe + to call. + @ingroup resip_config + */ + Compression &getCompression() { return *mCompression; } + + void terminateFlow(const resip::Tuple& flow); + void enableFlowTimer(const resip::Tuple& flow); + + private: + /// Performs bulk of work of constructor. + // WATCHOUT: can only be called once (just like constructor) + void init(const SipStackOptions& options); + + /** @brief Notify an async process handler - if one has been registered **/ + void checkAsyncProcessHandler(); + + FdPollGrp* mPollGrp; + bool mPollGrpIsMine; + + /** @brief if this object exists, it manages advanced security featues **/ + Security* mSecurity; + + DnsStub* mDnsStub; + DnsThread* mDnsThread; + + /** @brief If this object exists, it manages compression parameters **/ + Compression* mCompression; + + /** + @brief if this object exists, it gets notified when messages are posted + to any of the various fifos in the stack. + @note When running in multithreaded mode, this is only invoked when + either app timers are scheduled, shutdown has been requested, or a + TransactionUser has unregistered. The other fifos in the system are + associated with their own AsyncProcessHandlers, since they are being + processed by different threads. + **/ + AsyncProcessHandler* mAsyncProcessHandler; + bool mInterruptorIsMine; + + /** @brief Disallow copy, by not implementing **/ + SipStack(const SipStack& copy); + + /** @brief Disallow assignment, by not implementing **/ + SipStack& operator=(const SipStack& rhs); + + /** @brief fifo used to communicate between the TU (TransactionUser) and stack + @note since the introduction of multiple TU's this Fifo should no + longer be used by most applications - each TU now owns it's own Fifo. */ + TimeLimitFifo<Message> mTUFifo; + CongestionManager* mCongestionManager; + + /// Responsible for routing messages to the correct TU based on installed rules + TuSelector mTuSelector; + + /** @brief Protection for AppTimerQueue **/ + mutable Mutex mAppTimerMutex; + + /** @details timers associated with the application. When a timer fires, it is + placed in the mTUFifo (if there is not associated TU), or it is placed + on the fifo of the appropriate TU */ + TuSelectorTimerQueue mAppTimers; + + /** @brief Used to Track stack statistics **/ + StatisticsManager mStatsManager; + + /** @brief All aspects of the Transaction State Machine / DNS resolver **/ + TransactionController* mTransactionController; + std::auto_ptr<ProducerFifoBuffer<TransactionMessage> > mStateMacFifoBuffer; + + TransactionControllerThread* mTransactionControllerThread; + TransportSelectorThread* mTransportSelectorThread; + bool mRunning; + /** @brief store all domains that this stack is responsible for. + @note Controlled by addAlias and addTransport interface + and checks can be made with isMyDomain() */ + std::set<Data> mDomains; + + /** store all ports that this stack is lisenting on. Controlled by addTransport + and checks can be made with isMyPort() */ + std::set<int> mPorts; + + Uri mUri; + bool mShuttingDown; + mutable Mutex mShutdownMutex; + volatile bool mStatisticsManagerEnabled; + + AfterSocketCreationFuncPtr mSocketFunc; + + friend class Executive; + friend class StatelessHandler; + friend class StatisticsManager; + friend class TestDnsResolver; + friend class TestFSM; + friend class TransactionState; + friend class TransactionController; + friend class TuSelector; +}; + +EncodeStream& operator<<(EncodeStream& strm, const SipStack& stack); + +inline void +SipStack::sendOverExistingConnection(const SipMessage& msg, const Tuple& tuple, + TransactionUser* tu) +{ + assert(tuple.mFlowKey); + Tuple tup(tuple); + tup.onlyUseExistingConnection = true; + sendTo(msg, tuple, tu); +} + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/StackThread.cxx b/src/libs/resiprocate/resip/stack/StackThread.cxx new file mode 100644 index 00000000..b241e743 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StackThread.cxx @@ -0,0 +1,108 @@ +#include "resip/stack/StackThread.hxx" +#include "resip/stack/SipStack.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +using namespace resip; + +StackThread::StackThread(SipStack& stack) + : mStack(stack) +{} + +StackThread::~StackThread() +{ + //InfoLog (<< "StackThread::~StackThread()"); +} + +void +StackThread::thread() +{ + while (!isShutdown()) + { + try + { + resip::FdSet fdset; + buildFdSet(fdset); + mStack.buildFdSet(fdset); + int ret = fdset.selectMilliSeconds(resipMin(mStack.getTimeTillNextProcessMS(), + getTimeTillNextProcessMS())); + if (ret >= 0) + { + // .dlb. use return value to peek at the message to see if it is a + // shutdown, and call shutdown if it is + beforeProcess(); + mStack.process(fdset); + afterProcess(); + } + } + catch (BaseException& e) + { + ErrLog (<< "Unhandled exception: " << e); + } + } + WarningLog (<< "Shutting down stack thread"); +} + +void +StackThread::buildFdSet(FdSet& fdset) +{} + +unsigned int +StackThread::getTimeTillNextProcessMS() const +{ +// !dcm! moved the 25 ms min logic here +// return INT_MAX; + return 25; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/StackThread.hxx b/src/libs/resiprocate/resip/stack/StackThread.hxx new file mode 100644 index 00000000..87af3252 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StackThread.hxx @@ -0,0 +1,98 @@ +#ifndef RESIP_StackThread__hxx +#define RESIP_StackThread__hxx + +#include "rutil/ThreadIf.hxx" +#include "rutil/Socket.hxx" + +namespace resip +{ + +class SipStack; + +/** + @ingroup resip_crit + @brief This class is used to create a thread to run the SipStack in. + + The thread provides cycles to the SipStack by calling process. Process + is called at least every 25ms, or sooner if select returns a signaled + file descriptor. + + @deprecated This is a deprecated method of giving the SipStack cycles. + The current canonical example is EventStackThread. +*/ +class StackThread : public ThreadIf +{ + public: + // *sigh* doesn't end up yielding a very good warning, but at least you + // get a line number. + RESIP_DEPRECATED(StackThread(SipStack& stack)); + virtual ~StackThread(); + + virtual void thread(); + + protected: + virtual void buildFdSet(FdSet& fdset); + virtual unsigned int getTimeTillNextProcessMS() const; + + virtual void beforeProcess() {}; + virtual void afterProcess() {}; + + + private: + SipStack& mStack; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/StartLine.hxx b/src/libs/resiprocate/resip/stack/StartLine.hxx new file mode 100644 index 00000000..2b82cf4d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StartLine.hxx @@ -0,0 +1,31 @@ +#ifndef StartLine_Include_Guard +#define StartLine_Include_Guard + +#include "resip/stack/LazyParser.hxx" + +namespace resip +{ +class StartLine : public LazyParser +{ + public: + StartLine() {} + explicit StartLine(const HeaderFieldValue& headerFieldValue) : + LazyParser(headerFieldValue) + {} + StartLine(const char* buf, int length) : + LazyParser(buf, length) + {} + virtual ~StartLine(){} + + virtual EncodeStream& encodeParsed(EncodeStream& str) const=0; + virtual void parse(ParseBuffer& pb)=0; + virtual const Data& errorContext() const=0; + virtual StartLine* clone() const=0; + virtual StartLine* clone(void* location) const=0; + + +}; // class StartLine + +} // namespace resip + +#endif // include guard diff --git a/src/libs/resiprocate/resip/stack/StatelessHandler.cxx b/src/libs/resiprocate/resip/stack/StatelessHandler.cxx new file mode 100644 index 00000000..bc700adb --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StatelessHandler.cxx @@ -0,0 +1,197 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#ifndef WIN32 +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#ifndef __CYGWIN__ +# include <netinet/in.h> +# include <arpa/nameser.h> +# include <resolv.h> +#endif +#include <netdb.h> +#include <netinet/in.h> +#else +#include <Winsock2.h> +#include <svcguid.h> +#ifdef USE_IPV6 +#include <ws2tcpip.h> +#endif +#endif + +#include "rutil/Logger.hxx" +#include "rutil/DnsUtil.hxx" + +#include "resip/stack/TransportSelector.hxx" +#include "resip/stack/DnsResult.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/StatelessHandler.hxx" +#include "resip/stack/TransactionController.hxx" +#include "resip/stack/TransportFailure.hxx" +#include "rutil/WinLeakCheck.hxx" + + + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION + +StatelessHandler::StatelessHandler(TransactionController& c) : mController(c) +{ +} + +void +StatelessHandler::process() +{ + Message* msg = mController.mStateMacFifo.getNext(); + assert(msg); + + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + TransportFailure* transport = dynamic_cast<TransportFailure*>(msg); + + if (sip) + { + if (sip->const_header(h_Vias).empty()) + { + InfoLog(<< "TransactionState::process dropping message with no Via: " << sip->brief()); + delete sip; + return; + } + else + { + if (sip->isExternal()) + { + DebugLog (<< "Processing sip from wire: " << msg->brief()); + Via& via = sip->header(h_Vias).front(); + // this is here so that we will reuse the tcp connection + via.param(p_rport).port() = sip->getSource().getPort(); + mController.mTuSelector.add(sip, TimeLimitFifo<Message>::InternalElement); + } + else if (sip->isRequest()) + { + if (sip->getDestination().mFlowKey) + { + DebugLog (<< "Processing request from TU : " << msg->brief()); + mController.mTransportSelector.transmit(sip, sip->getDestination()); // results not used + } + else + { + DebugLog (<< "Processing request from TU : " << msg->brief()); + StatelessMessage* stateless = new StatelessMessage(mController.mTransportSelector, sip); + DnsResult* dnsRes = mController.mTransportSelector.createDnsResult(stateless); + mController.mTransportSelector.dnsResolve(dnsRes, sip); + } + } + else // no dns for sip responses + { + assert(sip->isResponse()); + DebugLog (<< "Processing response from TU: " << msg->brief()); + const Via& via = sip->const_header(h_Vias).front(); + int port = via.sentPort(); + if (sip->hasForceTarget()) + { + assert( /*Unimplemented*/ 0 ); + } + else + { + if (via.exists(p_rport) && via.param(p_rport).hasValue()) + { + port = via.param(p_rport).port(); + } + Tuple destination(via.param(p_received), port, Tuple::toTransport(via.transport())); + mController.mTransportSelector.transmit(sip, destination); // results not used + } + } + } + } + else if (transport) + { + DebugLog (<< "Processing Transport result: " << msg->brief()); + InfoLog (<< "Not yet supported"); + } + else + { + DebugLog (<< "Dropping: " << msg->brief()); + } +} + + +StatelessMessage::StatelessMessage(TransportSelector& selector, SipMessage* msg) : mSelector(selector), mMsg(msg) +{ +} + +void +StatelessMessage::rewriteRequest(const Uri& rewrite) +{ + assert(mMsg->isRequest()); + if (mMsg->const_header(h_RequestLine).uri() != rewrite) + { + InfoLog (<< "Rewriting request-uri to " << rewrite); + mMsg->header(h_RequestLine).uri() = rewrite; + } +} + + +void +StatelessMessage::handle(DnsResult* result) +{ + if (result->available() == DnsResult::Available) + { + Tuple next = result->next(); + mSelector.transmit(mMsg, next); + } + + delete this; + result->destroy(); +} +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/StatelessHandler.hxx b/src/libs/resiprocate/resip/stack/StatelessHandler.hxx new file mode 100644 index 00000000..7133c0d6 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StatelessHandler.hxx @@ -0,0 +1,88 @@ +#if !defined(RESIP_STATELESS_HANDLER_HXX) +#define RESIP_STATELESS_HANDLER_HXX + +#include "rutil/HashMap.hxx" +#include "rutil/dns/DnsHandler.hxx" + +namespace resip +{ + +class TransactionController; +class TransportSelector; + +class StatelessHandler +{ + public: + StatelessHandler(TransactionController& c); + void process(); + + private: + TransactionController& mController; +}; + +class StatelessMessage : public DnsHandler +{ + public: + StatelessMessage(TransportSelector& selector, SipMessage* msg); + ~StatelessMessage() {}; + + void handle(DnsResult* result); + void rewriteRequest(const Uri& rewrite); + + private: + TransportSelector& mSelector; + SipMessage* mMsg; +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/StatisticsHandler.cxx b/src/libs/resiprocate/resip/stack/StatisticsHandler.cxx new file mode 100644 index 00000000..5b9d8d61 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StatisticsHandler.cxx @@ -0,0 +1,9 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif +#include "resip/stack/StatisticsHandler.hxx" + +using namespace resip; + +ExternalStatsHandler::~ExternalStatsHandler() +{} diff --git a/src/libs/resiprocate/resip/stack/StatisticsHandler.hxx b/src/libs/resiprocate/resip/stack/StatisticsHandler.hxx new file mode 100644 index 00000000..1ea3870a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StatisticsHandler.hxx @@ -0,0 +1,77 @@ +#ifndef RESIP_StatisticsHandler_hxx +#define RESIP_StatisticsHandler_hxx + +namespace resip +{ + +class StatisticsMessage; + +/** Interface functor for external stats handling. + * User can catch stats events before the stack automatically handles them and can + * suppress automatic behavior if desired. + * @see resip::StatisticsManager::setExternalStatsHandler + */ +class ExternalStatsHandler { + public: + virtual ~ExternalStatsHandler()=0; + /** . + * @param statsMessage contains the current stats for the stack. + * @return true to continue processing this message and perform default handling, + * false to supress further handling, including default handling. */ + virtual bool operator()(StatisticsMessage &statsMessage) = 0; +}; + +}//namespace resip + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/stack/StatisticsManager.cxx b/src/libs/resiprocate/resip/stack/StatisticsManager.cxx new file mode 100644 index 00000000..a1353f6a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StatisticsManager.cxx @@ -0,0 +1,211 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "rutil/Logger.hxx" +#include "resip/stack/StatisticsManager.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/TransactionController.hxx" +#include "resip/stack/SipStack.hxx" + +using namespace resip; +using std::vector; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION + +StatisticsManager::StatisticsManager(SipStack& stack, unsigned long intervalSecs) + : StatisticsMessage::Payload(), + mStack(stack), + mInterval(intervalSecs*1000), + mNextPoll(Timer::getTimeMs() + mInterval), + mExternalHandler(NULL), + mPublicPayload(NULL) +{} + +StatisticsManager::~StatisticsManager() +{ + if ( mPublicPayload ) + delete mPublicPayload; +} + +void +StatisticsManager::setInterval(unsigned long intervalSecs) +{ + mInterval = intervalSecs * 1000; +} + +void +StatisticsManager::poll() +{ + // get snapshot data now.. + tuFifoSize = mStack.mTransactionController->getTuFifoSize(); + transportFifoSizeSum = mStack.mTransactionController->sumTransportFifoSizes(); + transactionFifoSize = mStack.mTransactionController->getTransactionFifoSize(); + activeTimers = mStack.mTransactionController->getTimerQueueSize(); + activeClientTransactions = mStack.mTransactionController->getNumClientTransactions(); + activeServerTransactions = mStack.mTransactionController->getNumServerTransactions(); + + // .kw. At last check payload was > 146kB, which seems too large + // to alloc on stack. Also, the post'd message has reference + // to the appStats, so not safe queue as ref to stack element. + // Converted to dynamic memory allocation. + if ( mPublicPayload==NULL ) + { + mPublicPayload = new StatisticsMessage::AtomicPayload; + // re-used each time, free'd in destructor + } + mPublicPayload->loadIn(*this); + + bool postToStack = true; + StatisticsMessage msg(*mPublicPayload); + // WATCHOUT: msg contains reference to the payload, and this reference + // is preserved thru clone(). + + if( mExternalHandler ) + { + postToStack = (*mExternalHandler)(msg); + } + + if( postToStack ) + { + // let the app do what it wants with it + mStack.post(msg); + } + + // !bwc! TODO maybe change this? Or is a flexible implementation of + // CongestionManager::logCurrentState() enough? + if(mStack.mCongestionManager) + { + mStack.mCongestionManager->logCurrentState(); + } +} + +void +StatisticsManager::process() +{ + if (Timer::getTimeMs() >= mNextPoll) + { + poll(); + mNextPoll += mInterval; + } +} + +bool +StatisticsManager::sent(SipMessage* msg) +{ + MethodTypes met = msg->method(); + + if (msg->isRequest()) + { + ++requestsSent; + ++requestsSentByMethod[met]; + } + else if (msg->isResponse()) + { + int code = msg->const_header(h_StatusLine).statusCode(); + if (code < 0 || code >= MaxCode) + { + code = 0; + } + + ++responsesSent; + ++responsesSentByMethod[met]; + ++responsesSentByMethodByCode[met][code]; + } + + return false; +} + +bool +StatisticsManager::retransmitted(MethodTypes met, + bool request, + unsigned int code) +{ + if(request) + { + ++requestsRetransmitted; + ++requestsRetransmittedByMethod[met]; + } + else + { + ++responsesRetransmitted; + ++responsesRetransmittedByMethod[met]; + ++responsesRetransmittedByMethodByCode[met][code]; + } + return false; +} + +bool +StatisticsManager::received(SipMessage* msg) +{ + MethodTypes met = msg->header(h_CSeq).method(); + + if (msg->isRequest()) + { + ++requestsReceived; + ++requestsReceivedByMethod[met]; + } + else if (msg->isResponse()) + { + ++responsesReceived; + ++responsesReceivedByMethod[met]; + int code = msg->const_header(h_StatusLine).statusCode(); + if (code < 0 || code >= MaxCode) + { + code = 0; + } + ++responsesReceivedByMethodByCode[met][code]; + } + + return false; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/StatisticsManager.hxx b/src/libs/resiprocate/resip/stack/StatisticsManager.hxx new file mode 100644 index 00000000..07078c95 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StatisticsManager.hxx @@ -0,0 +1,126 @@ +#ifndef RESIP_StatisticsManager_hxx +#define RESIP_StatisticsManager_hxx + +#include "rutil/Timer.hxx" +#include "rutil/Data.hxx" +#include "resip/stack/StatisticsMessage.hxx" +#include "resip/stack/StatisticsHandler.hxx" + +namespace resip +{ +class SipStack; +class SipMessage; +class TransactionController; + +/** + @brief Keeps track of various statistics on the stack's operation, and + periodically issues a StatisticsMessage to the TransactionUser (or, if the + ExternalStatsHandler is set, it will be sent there). +*/ +class StatisticsManager : public StatisticsMessage::Payload +{ + public: + // not implemented + typedef enum + { + TransportFifoSize, + TUFifoSize, + ActiveTimers, + OpenTcpConnections, + ActiveClientTransactions, + ActiveServerTransactions, + PendingDnsQueries, + StatsMemUsed + } Measurement; + + StatisticsManager(SipStack& stack, unsigned long intervalSecs=60); + ~StatisticsManager(); + + void process(); + // not stricly thread-safe; needs to be called through the fifo somehow + void setInterval(unsigned long intvSecs); + + /** + @ingroup resip_config + @brief Allows the application to set the ExternalStatsHandler for this + StatisticsManager. + */ + void setExternalStatsHandler(ExternalStatsHandler *handler) + { + mExternalHandler = handler; + } + + private: + friend class TransactionState; + bool sent(SipMessage* msg); + bool retransmitted(MethodTypes type, bool request, unsigned int code); + bool received(SipMessage* msg); + + void poll(); // force an update + + SipStack& mStack; + UInt64 mInterval; + UInt64 mNextPoll; + + ExternalStatsHandler *mExternalHandler; + // + // When statistics are published, a copy of values are made + // and copied into this member, and then reference to this is + // published thru both ExternalHandler and posted to stack as message. + // This payload is mutex protected. + StatisticsMessage::AtomicPayload *mPublicPayload; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/StatisticsMessage.cxx b/src/libs/resiprocate/resip/stack/StatisticsMessage.cxx new file mode 100644 index 00000000..b9775791 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StatisticsMessage.cxx @@ -0,0 +1,328 @@ +#include "resip/stack/StatisticsMessage.hxx" +#include "rutil/Lock.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +#include <string.h> + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::STATS + +StatisticsMessage::StatisticsMessage(const StatisticsMessage::AtomicPayload& payload) + : ApplicationMessage(), + mPayload(payload) +{} + +StatisticsMessage::StatisticsMessage(const StatisticsMessage& rhs) + : ApplicationMessage(rhs), + mPayload(rhs.mPayload) +{} + +StatisticsMessage::~StatisticsMessage() +{} + +EncodeStream& +StatisticsMessage::encodeBrief(EncodeStream& str) const +{ + return str << "StatisticsMessage"; +} + +EncodeStream& +StatisticsMessage::encode(EncodeStream& strm) const +{ + strm << "StatisticsMessage"; +/* + strm << " ["; + Payload payload; + mPayload.loadOut(payload); + strm << payload << "]"; +*/ + return strm; +} + +unsigned int +StatisticsMessage::Payload::sum2xxIn(MethodTypes method) const +{ + unsigned int ret = 0; + for (int code = 200; code < 300; ++code) + { + ret += responsesReceivedByMethodByCode[method][code]; + } + + return ret; +} + +unsigned int +StatisticsMessage::Payload::sum2xxOut(MethodTypes method) const +{ + unsigned int ret = 0; + for (int code = 200; code < 300; ++code) + { + ret += responsesSentByMethodByCode[method][code]; + } + + return ret; +} + +unsigned int +StatisticsMessage::Payload::sumErrIn(MethodTypes method) const +{ + unsigned int ret = 0; + for (int code = 300; code < MaxCode; ++code) + { + ret += responsesReceivedByMethodByCode[method][code]; + } + + return ret; +} + +unsigned int +StatisticsMessage::Payload::sumErrOut(MethodTypes method) const +{ + unsigned int ret = 0; + for (int code = 300; code < MaxCode; ++code) + { + ret += responsesSentByMethodByCode[method][code]; + } + + return ret; +} + +void +StatisticsMessage::logStats(const resip::Subsystem& subsystem, + const StatisticsMessage::Payload& stats) +{ + WarningLog(<< subsystem + << std::endl + << stats); +} + + +Message* +StatisticsMessage::clone() const +{ + return new StatisticsMessage(*this); +} + +StatisticsMessage::Payload::Payload() +{ + zeroOut(); +} + +void +StatisticsMessage::Payload::zeroOut() +{ + tuFifoSize = 0; + transportFifoSizeSum = 0; + transactionFifoSize = 0; + activeTimers = 0; + openTcpConnections = 0; + activeClientTransactions = 0; + activeServerTransactions = 0; + pendingDnsQueries = 0; + requestsSent = 0; + responsesSent = 0; + requestsRetransmitted = 0; + responsesRetransmitted = 0; + requestsReceived = 0; + responsesReceived = 0; + memset(responsesByCode, 0, sizeof(responsesByCode)); + memset(requestsSentByMethod, 0, sizeof(requestsSentByMethod)); + memset(requestsRetransmittedByMethod, 0, sizeof(requestsRetransmittedByMethod)); + memset(requestsReceivedByMethod, 0, sizeof(requestsReceivedByMethod)); + memset(responsesSentByMethod, 0, sizeof(responsesSentByMethod)); + memset(responsesRetransmittedByMethod, 0, sizeof(responsesRetransmittedByMethod)); + memset(responsesReceivedByMethod, 0, sizeof(responsesReceivedByMethod)); + memset(responsesSentByMethodByCode, 0, sizeof(responsesSentByMethodByCode)); + memset(responsesRetransmittedByMethodByCode, 0, sizeof(responsesRetransmittedByMethodByCode)); + memset(responsesReceivedByMethodByCode, 0, sizeof(responsesReceivedByMethodByCode)); +} + +StatisticsMessage::Payload& +StatisticsMessage::Payload::operator=(const StatisticsMessage::Payload& rhs) +{ + if (&rhs != this) + { + transportFifoSizeSum = rhs.transportFifoSizeSum; + tuFifoSize = rhs.tuFifoSize; + activeTimers = rhs.activeTimers; + transactionFifoSize = rhs.transactionFifoSize; + + openTcpConnections = rhs.openTcpConnections; + activeClientTransactions = rhs.activeClientTransactions; + activeServerTransactions = rhs.activeServerTransactions; + pendingDnsQueries = rhs.pendingDnsQueries; + + requestsSent = rhs.requestsSent; + responsesSent = rhs.responsesSent; + requestsRetransmitted = rhs.requestsRetransmitted; + responsesRetransmitted = rhs.responsesRetransmitted; + requestsReceived = rhs.requestsReceived; + responsesReceived = rhs.responsesReceived; + + memcpy(responsesByCode, rhs.responsesByCode, sizeof(responsesByCode)); + memcpy(requestsSentByMethod, rhs.requestsSentByMethod, sizeof(requestsSentByMethod)); + memcpy(requestsRetransmittedByMethod, rhs.requestsRetransmittedByMethod, sizeof(requestsRetransmittedByMethod)); + memcpy(requestsReceivedByMethod, rhs.requestsReceivedByMethod, sizeof(requestsReceivedByMethod)); + memcpy(responsesSentByMethod, rhs.responsesSentByMethod, sizeof(responsesSentByMethod)); + memcpy(responsesRetransmittedByMethod, rhs.responsesRetransmittedByMethod, sizeof(responsesRetransmittedByMethod)); + memcpy(responsesReceivedByMethod, rhs.responsesReceivedByMethod, sizeof(responsesReceivedByMethod)); + memcpy(responsesSentByMethodByCode, rhs.responsesSentByMethodByCode, sizeof(responsesSentByMethodByCode)); + memcpy(responsesRetransmittedByMethodByCode, rhs.responsesRetransmittedByMethodByCode, sizeof(responsesRetransmittedByMethodByCode)); + memcpy(responsesReceivedByMethodByCode, rhs.responsesReceivedByMethodByCode, sizeof(responsesReceivedByMethodByCode)); + } + + return *this; +} + +void +StatisticsMessage::loadOut(Payload& payload) const +{ + mPayload.loadOut(payload); +} + +StatisticsMessage::AtomicPayload::AtomicPayload() +{} + +void +StatisticsMessage::AtomicPayload::loadIn(const Payload& payload) +{ + Lock lock(mMutex); + Payload::operator=(payload); +} + +void +StatisticsMessage::AtomicPayload::loadOut(Payload& payload) const +{ + Lock lock(mMutex); + payload = (*this); +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const StatisticsMessage::Payload& stats) +{ + unsigned int retriesFinal = 0; + for (int c = 200; c < 300; ++c) + { + retriesFinal += stats.responsesRetransmittedByMethodByCode[INVITE][c]; + } + + unsigned int retriesNonFinal = 0; + for (int c = 100; c < 200; ++c) + { + retriesNonFinal += stats.responsesRetransmittedByMethodByCode[INVITE][c]; + } + + strm << "TU summary: " << stats.tuFifoSize + << " TRANSPORT " << stats.transportFifoSizeSum + << " TRANSACTION " << stats.transactionFifoSize + << " CLIENTTX " << stats.activeClientTransactions + << " SERVERTX " << stats.activeServerTransactions + << " TIMERS " << stats.activeTimers + << std::endl + << "Transaction summary: reqi " << stats.requestsReceived + << " reqo " << stats.requestsSent + << " rspi " << stats.responsesReceived + << " rspo " << stats.responsesSent + << std::endl + << "Details: INVi " << stats.requestsReceivedByMethod[INVITE] << "/S" << stats.sum2xxOut(INVITE) << "/F" << stats.sumErrOut(INVITE) + << " INVo " << stats.requestsSentByMethod[INVITE]-stats.requestsRetransmittedByMethod[INVITE] << "/S" << stats.sum2xxIn(INVITE) << "/F" << stats.sumErrIn(INVITE) + << " ACKi " << stats.requestsReceivedByMethod[ACK] + << " ACKo " << stats.requestsSentByMethod[ACK]-stats.requestsRetransmittedByMethod[ACK] + << " BYEi " << stats.requestsReceivedByMethod[BYE] << "/S" << stats.sum2xxOut(BYE) << "/F" << stats.sumErrOut(BYE) + << " BYEo " << stats.requestsSentByMethod[BYE]-stats.requestsRetransmittedByMethod[BYE] << "/S" << stats.sum2xxIn(BYE) << "/F" << stats.sumErrIn(BYE) + << " CANi " << stats.requestsReceivedByMethod[CANCEL] << "/S" << stats.sum2xxOut(BYE) << "/F" << stats.sumErrOut(BYE) + << " CANo " << stats.requestsSentByMethod[CANCEL]-stats.requestsRetransmittedByMethod[CANCEL] << "/S" << stats.sum2xxIn(CANCEL) << "/F" << stats.sumErrIn(CANCEL) + << " MSGi " << stats.requestsReceivedByMethod[MESSAGE] << "/S" << stats.sum2xxOut(MESSAGE) << "/F" << stats.sumErrOut(MESSAGE) + << " MSGo " << stats.requestsSentByMethod[MESSAGE]-stats.requestsRetransmittedByMethod[MESSAGE] << "/S" << stats.sum2xxIn(MESSAGE) << "/F" << stats.sumErrIn(MESSAGE) + << " OPTi " << stats.requestsReceivedByMethod[OPTIONS] << "/S" << stats.sum2xxOut(OPTIONS) << "/F" << stats.sumErrOut(OPTIONS) + << " OPTo " << stats.requestsSentByMethod[OPTIONS]-stats.requestsRetransmittedByMethod[OPTIONS] << "/S" << stats.sum2xxIn(OPTIONS) << "/F" << stats.sumErrIn(OPTIONS) + << " REGi " << stats.requestsReceivedByMethod[REGISTER] << "/S" << stats.sum2xxOut(REGISTER) << "/F" << stats.sumErrOut(REGISTER) + << " REGo " << stats.requestsSentByMethod[REGISTER]-stats.requestsRetransmittedByMethod[REGISTER] << "/S" << stats.sum2xxIn(REGISTER) << "/F" << stats.sumErrIn(REGISTER) + << " PUBi " << stats.requestsReceivedByMethod[PUBLISH] << "/S" << stats.sum2xxOut(PUBLISH) << "/F" << stats.sumErrOut(PUBLISH) + << " PUBo " << stats.requestsSentByMethod[PUBLISH] << "/S" << stats.sum2xxIn(PUBLISH) << "/F" << stats.sumErrIn(PUBLISH) + << " SUBi " << stats.requestsReceivedByMethod[SUBSCRIBE] << "/S" << stats.sum2xxOut(SUBSCRIBE) << "/F" << stats.sumErrOut(SUBSCRIBE) + << " SUBo " << stats.requestsSentByMethod[SUBSCRIBE] << "/S" << stats.sum2xxIn(SUBSCRIBE) << "/F" << stats.sumErrIn(SUBSCRIBE) + << " NOTi " << stats.requestsReceivedByMethod[NOTIFY] << "/S" << stats.sum2xxOut(NOTIFY) << "/F" << stats.sumErrOut(NOTIFY) + << " NOTo " << stats.requestsSentByMethod[NOTIFY] << "/S" << stats.sum2xxIn(NOTIFY) << "/F" << stats.sumErrIn(NOTIFY) + << " REFi " << stats.requestsReceivedByMethod[REFER] << "/S" << stats.sum2xxOut(REFER) << "/F" << stats.sumErrOut(REFER) + << " REFo " << stats.requestsSentByMethod[REFER] << "/S" << stats.sum2xxIn(REFER) << "/F" << stats.sumErrIn(REFER) + << " INFi " << stats.requestsReceivedByMethod[INFO] << "/S" << stats.sum2xxOut(INFO) << "/F" << stats.sumErrOut(INFO) + << " INFo " << stats.requestsSentByMethod[INFO] << "/S" << stats.sum2xxIn(INFO) << "/F" << stats.sumErrIn(INFO) + << " PRAi " << stats.requestsReceivedByMethod[PRACK] << "/S" << stats.sum2xxOut(PRACK) << "/F" << stats.sumErrOut(PRACK) + << " PRAo " << stats.requestsSentByMethod[PRACK] << "/S" << stats.sum2xxIn(PRACK) << "/F" << stats.sumErrIn(PRACK) + << " SERi " << stats.requestsReceivedByMethod[SERVICE] << "/S" << stats.sum2xxOut(SERVICE) << "/F" << stats.sumErrOut(SERVICE) + << " SERo " << stats.requestsSentByMethod[SERVICE] << "/S" << stats.sum2xxIn(SERVICE) << "/F" << stats.sumErrIn(SERVICE) + << " UPDi " << stats.requestsReceivedByMethod[UPDATE] << "/S" << stats.sum2xxOut(UPDATE) << "/F" << stats.sumErrOut(UPDATE) + << " UPDo " << stats.requestsSentByMethod[UPDATE] << "/S" << stats.sum2xxIn(UPDATE) << "/F" << stats.sumErrIn(UPDATE) + << std::endl + << "Retransmissions: INVx " << stats.requestsRetransmittedByMethod[INVITE] + << " finx " << retriesFinal + << " nonx " << retriesNonFinal + << " BYEx " << stats.requestsRetransmittedByMethod[BYE] + << " CANx " << stats.requestsRetransmittedByMethod[CANCEL] + << " MSGx " << stats.requestsRetransmittedByMethod[MESSAGE] + << " OPTx " << stats.requestsRetransmittedByMethod[OPTIONS] + << " REGx " << stats.requestsRetransmittedByMethod[REGISTER] + << " PUBx " << stats.requestsRetransmittedByMethod[PUBLISH] + << " SUBx " << stats.requestsRetransmittedByMethod[SUBSCRIBE] + << " NOTx " << stats.requestsRetransmittedByMethod[NOTIFY] + << " REFx " << stats.requestsRetransmittedByMethod[REFER] + << " INFx " << stats.requestsRetransmittedByMethod[INFO] + << " PRAx " << stats.requestsRetransmittedByMethod[PRACK] + << " SERx " << stats.requestsRetransmittedByMethod[SERVICE] + << " UPDx " << stats.requestsRetransmittedByMethod[UPDATE]; + strm.flush(); + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/StatisticsMessage.hxx b/src/libs/resiprocate/resip/stack/StatisticsMessage.hxx new file mode 100644 index 00000000..c63c6fa5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StatisticsMessage.hxx @@ -0,0 +1,149 @@ +#ifndef RESIP_StatisticsMessage_hxx +#define RESIP_StatisticsMessage_hxx + +#include <iostream> +#include "resip/stack/ApplicationMessage.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/HeapInstanceCounter.hxx" + +namespace resip +{ +class Subsystem; + +class StatisticsMessage : public ApplicationMessage +{ + public: + RESIP_HeapCount(StatisticsMessage); + class AtomicPayload; + StatisticsMessage(const AtomicPayload& payload); + StatisticsMessage(const StatisticsMessage& rhs); + + virtual ~StatisticsMessage(); + + struct Payload + { + enum {MaxCode = 700}; + + Payload(); + + unsigned int tuFifoSize; + unsigned int transportFifoSizeSum; + unsigned int transactionFifoSize; + unsigned int activeTimers; + unsigned int openTcpConnections; // .dlb. not implemented + unsigned int activeClientTransactions; + unsigned int activeServerTransactions; + unsigned int pendingDnsQueries; // .dlb. not implemented + + unsigned int requestsSent; // includes retransmissions + unsigned int responsesSent; // includes retransmissions + unsigned int requestsRetransmitted; // counts each retransmission + unsigned int responsesRetransmitted; // counts each retransmission + unsigned int requestsReceived; + unsigned int responsesReceived; + + unsigned int responsesByCode[MaxCode]; + + unsigned int requestsSentByMethod[MAX_METHODS]; + unsigned int requestsRetransmittedByMethod[MAX_METHODS]; + unsigned int requestsReceivedByMethod[MAX_METHODS]; + unsigned int responsesSentByMethod[MAX_METHODS]; + unsigned int responsesRetransmittedByMethod[MAX_METHODS]; + unsigned int responsesReceivedByMethod[MAX_METHODS]; + + unsigned int responsesSentByMethodByCode[MAX_METHODS][MaxCode]; + unsigned int responsesRetransmittedByMethodByCode[MAX_METHODS][MaxCode]; + unsigned int responsesReceivedByMethodByCode[MAX_METHODS][MaxCode]; + + unsigned int sum2xxIn(MethodTypes method) const; + unsigned int sumErrIn(MethodTypes method) const; + unsigned int sum2xxOut(MethodTypes method) const; + unsigned int sumErrOut(MethodTypes method) const; + void zeroOut(); + + Payload& operator=(const Payload& payload); + }; + + void loadOut(Payload& payload) const; + static void logStats(const Subsystem& subsystem, const Payload& stats); + + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& str) const; + + Message* clone() const; + + class AtomicPayload : private Payload + { + public: + AtomicPayload(); + void loadIn(const Payload& payload); + void loadOut(Payload& payload) const; + private: + mutable Mutex mMutex; + + // dis-allowed by not implemented + AtomicPayload(const AtomicPayload&); + AtomicPayload& operator=(const AtomicPayload&); + }; + + private: + const AtomicPayload& mPayload; + friend EncodeStream& operator<<(EncodeStream& strm, const StatisticsMessage::Payload& stats); +}; + +EncodeStream& operator<<(EncodeStream& strm, const StatisticsMessage::Payload& stats); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/StatusLine.cxx b/src/libs/resiprocate/resip/stack/StatusLine.cxx new file mode 100644 index 00000000..1c1eba34 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StatusLine.cxx @@ -0,0 +1,200 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/StatusLine.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// StatusLine: +//==================== +StatusLine::StatusLine() + : StartLine(), + mResponseCode(-1), + mSipVersion(Data::Share,Symbols::DefaultSipVersion), + mReason() +{} + +StatusLine::StatusLine(const HeaderFieldValue& hfv) + : StartLine(hfv), + mResponseCode(-1), + mSipVersion(Data::Share,Symbols::DefaultSipVersion), + mReason() +{} + +StatusLine::StatusLine(const char* buf, int length) : + StartLine(buf, length), + mResponseCode(-1), + mSipVersion(Data::Share,Symbols::DefaultSipVersion), + mReason() +{} + +StatusLine::StatusLine(const StatusLine& rhs) + : StartLine(rhs), + mResponseCode(rhs.mResponseCode), + mSipVersion(rhs.mSipVersion), + mReason(rhs.mReason) +{} + +StatusLine& +StatusLine::operator=(const StatusLine& rhs) +{ + if (this != &rhs) + { + StartLine::operator=(rhs); + mResponseCode = rhs.mResponseCode; + mSipVersion = rhs.mSipVersion; + mReason = rhs.mReason; + } + return *this; +} + +StartLine * +StatusLine::clone() const +{ + return new StatusLine(*this); +} + +StartLine * +StatusLine::clone(void* location) const +{ + return new (location) StatusLine(*this); +} + +int& +StatusLine::responseCode() +{ + checkParsed(); + return mResponseCode; +} + +int +StatusLine::responseCode() const +{ + checkParsed(); + return mResponseCode; +} + +int& +StatusLine::statusCode() +{ + checkParsed(); + return mResponseCode; +} + +int +StatusLine::statusCode() const +{ + checkParsed(); + return mResponseCode; +} + +const Data& +StatusLine::getSipVersion() const +{ + checkParsed(); + return mSipVersion; +} + +Data& +StatusLine::reason() +{ + checkParsed(); + return mReason; +} + +const Data& +StatusLine::reason() const +{ + checkParsed(); + return mReason; +} + +void +StatusLine::parse(ParseBuffer& pb) +{ + const char* start = pb.skipWhitespace(); + pb.skipNonWhitespace(); + pb.data(mSipVersion, start); + + start = pb.skipWhitespace(); + mResponseCode = pb.integer(); + start = pb.skipWhitespace(); + pb.skipToEnd(); + pb.data(mReason, start); +} + +EncodeStream& +StatusLine::encodeParsed(EncodeStream& str) const +{ + str << mSipVersion << Symbols::SPACE + << mResponseCode << Symbols::SPACE + << mReason; + return str; +} + +const Data& +StatusLine::errorContext() const +{ + static const Data statLine("Status Line"); + return statLine; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/StatusLine.hxx b/src/libs/resiprocate/resip/stack/StatusLine.hxx new file mode 100644 index 00000000..fb11a2f9 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StatusLine.hxx @@ -0,0 +1,96 @@ +#if !defined(RESIP_STATUSLINE_HXX) +#define RESIP_STATUSLINE_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/StartLine.hxx" + +namespace resip +{ + +/** + @ingroup sip_grammar + @brief Represents the "Status-Line" element in the RFC 3261 grammar. +*/ +class StatusLine : public StartLine +{ + public: + StatusLine(); + StatusLine(const HeaderFieldValue& hfv); + StatusLine(const char* buf, int length); + StatusLine(const StatusLine&); + StatusLine& operator=(const StatusLine&); + + int& responseCode(); + int responseCode() const; + int& statusCode(); + int statusCode() const; + const Data& getSipVersion() const; + Data& reason(); + const Data& reason() const; + + virtual void parse(ParseBuffer& pb); + virtual StartLine* clone() const; + virtual StartLine* clone(void* location) const; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual const Data& errorContext() const; + + private: + int mResponseCode; + Data mSipVersion; + Data mReason; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/StringCategory.cxx b/src/libs/resiprocate/resip/stack/StringCategory.cxx new file mode 100644 index 00000000..1b8107fd --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StringCategory.cxx @@ -0,0 +1,146 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/StringCategory.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// StringCategory +//==================== +StringCategory::StringCategory() : + ParserCategory(), + mValue() +{} + +StringCategory::StringCategory(const Data& value) + : ParserCategory(), + mValue(value) +{} + +StringCategory::StringCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), + mValue() +{} + +StringCategory::StringCategory(const StringCategory& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mValue(rhs.mValue) +{} + +StringCategory& +StringCategory::operator=(const StringCategory& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mValue = rhs.mValue; + } + return *this; +} +ParserCategory* +StringCategory::clone() const +{ + return new StringCategory(*this); +} + +ParserCategory* +StringCategory::clone(void* location) const +{ + return new (location) StringCategory(*this); +} + +ParserCategory* +StringCategory::clone(PoolBase* pool) const +{ + return new (pool) StringCategory(*this, pool); +} + +void +StringCategory::parse(ParseBuffer& pb) +{ + const char* anchor = pb.position(); + pb.skipToEnd(); + pb.data(mValue, anchor); +} + +EncodeStream& +StringCategory::encodeParsed(EncodeStream& str) const +{ + str << mValue; + return str; +} + +const Data& +StringCategory::value() const +{ + checkParsed(); + return mValue; +} + +Data& +StringCategory::value() +{ + checkParsed(); + return mValue; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/StringCategory.hxx b/src/libs/resiprocate/resip/stack/StringCategory.hxx new file mode 100644 index 00000000..f8395b3f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/StringCategory.hxx @@ -0,0 +1,96 @@ +#if !defined(RESIP_STRING_CATEGORY_HXX) +#define RESIP_STRING_CATEGORY_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/ParserContainer.hxx" + +namespace resip +{ + +/** + @ingroup sip_grammar + @brief Represents the "header-value" element in the RFC 3261 grammar (ie, an + unknown header field value). +*/ +class StringCategory : public ParserCategory +{ + public: + enum {commaHandling = NoCommaTokenizing}; + + StringCategory(); + explicit StringCategory(const Data& value); + StringCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + StringCategory(const StringCategory& orig, + PoolBase* pool=0); + StringCategory& operator=(const StringCategory&); + + virtual void parse(ParseBuffer& pb); + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + + const Data& value() const; + Data& value(); + + private: + Data mValue; +}; +typedef ParserContainer<StringCategory> StringCategories; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Symbols.cxx b/src/libs/resiprocate/resip/stack/Symbols.cxx new file mode 100644 index 00000000..5ca1d335 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Symbols.cxx @@ -0,0 +1,176 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Symbols.hxx" + +using namespace resip; + +const char* Symbols::DefaultSipVersion = "SIP/2.0"; +const char* Symbols::DefaultSipScheme = "sip"; + +const char* Symbols::CRLF = "\r\n"; +const char* Symbols::CRLFCRLF = "\r\n\r\n"; +const char* Symbols::CR = "\r"; +const char* Symbols::LF = "\n"; +const char* Symbols::TAB = "\t"; + +const char* Symbols::AT_SIGN = "@"; +const char* Symbols::SPACE = " "; +const char* Symbols::DASH = "-"; +const char* Symbols::BAR = "|"; +const char* Symbols::DASHDASH = "--"; +const char* Symbols::DOT = "."; +const char* Symbols::COLON = ":"; +const char* Symbols::EQUALS = "="; +const char* Symbols::SEMI_OR_EQUAL = ";="; +const char* Symbols::COMMA_OR_EQUAL = ",="; +const char* Symbols::SEMI_COLON = ";"; +const char* Symbols::SLASH = "/"; +const char* Symbols::B_SLASH = "\\"; +const char* Symbols::DOUBLE_QUOTE = "\""; +const char* Symbols::LA_QUOTE = "<"; +const char* Symbols::RA_QUOTE = ">"; +const char* Symbols::COMMA = ","; +const char* Symbols::ZERO = "0"; +const char* Symbols::LPAREN = "("; +const char* Symbols::RPAREN = ")"; +const char* Symbols::LS_BRACKET = "["; +const char* Symbols::RS_BRACKET = "]"; +const char* Symbols::PERIOD = "."; +const char* Symbols::QUESTION = "?"; +const char* Symbols::AMPERSAND = "&"; +const char* Symbols::PERCENT = "%"; +const char* Symbols::STAR ="*"; +const char* Symbols::UNDERSCORE ="_"; + +const char* Symbols::ProtocolName = "SIP"; +const char* Symbols::ProtocolVersion = "2.0"; +const char* Symbols::UDP = "UDP"; +const char* Symbols::TCP = "TCP"; +const char* Symbols::TLS = "TLS"; +const char* Symbols::DTLS = "DTLS"; +const char* Symbols::SCTP = "SCTP"; +const char* Symbols::SRVUDP = "_udp."; +const char* Symbols::SRVTCP = "_tcp."; +const char* Symbols::SRVTLS = "_tls."; +const char* Symbols::SRVSCTP = "_sctp."; + +const char* Symbols::Sip = "sip"; +const char* Symbols::Sips = "sips"; +const char* Symbols::Tel = "tel"; +const char* Symbols::Pres = "pres"; + +const char* Symbols::Phone = "phone"; +const char* Symbols::Isub = "isub="; +const char* Symbols::Postd = "postd="; + +const char* Symbols::auth = "auth"; +const char* Symbols::authInt = "auth-int"; +const char* Symbols::Digest = "Digest"; +const char* Symbols::Basic = "Basic"; + +const char * const Symbols::MagicCookie = "z9hG4bK"; +const char * const Symbols::resipCookie= "-524287-"; + +const int Symbols::DefaultSipPort = 5060; +const int Symbols::SipTlsPort = 5061; +const int Symbols::DefaultSipsPort = 5061; + +const char* Symbols::SrvSip = "_sip"; +const char* Symbols::SrvSips = "_sips"; +const char* Symbols::SrvUdp = "_udp"; +const char* Symbols::SrvTcp = "_tcp"; +const char* Symbols::NaptrSip = "SIP"; +const char* Symbols::NaptrSips = "SIPS"; +const char* Symbols::NaptrUdp = "D2U"; +const char* Symbols::NaptrTcp = "D2T"; + +const char* Symbols::audio = "audio"; +const char* Symbols::RTP_AVP = "RTP/AVP"; +const char* Symbols::RTP_SAVP = "RTP/SAVP"; // used for SRTP +const char* Symbols::UDP_TLS_RTP_SAVP = "UDP/TLS/RTP/SAVP"; // used for DTLS-SRTP + +const char* Symbols::Presence = "presence"; +const char* Symbols::Required = "required"; +const char* Symbols::Optional = "optional"; + +const char* Symbols::C100rel = "100rel"; +const char* Symbols::Replaces = "replaces"; +const char* Symbols::Timer = "timer"; +const char* Symbols::NoReferSub = "norefersub"; +const char* Symbols::AnswerMode = "answermode"; +const char* Symbols::TargetDialog = "tdialog"; +const char* Symbols::Path = "path"; +const char* Symbols::Outbound = "outbound"; +const char* Symbols::Undefined = "UNDEFINED"; + +const char* Symbols::Pending = "pending"; +const char* Symbols::Active = "active"; +const char* Symbols::Terminated = "terminated"; + +const char* Symbols::Certificate = "certificate"; +const char* Symbols::Credential = "credential"; + +const char* Symbols::SipProfile = "sip-profile"; + +const char* Symbols::id = "id"; // from RFC 3323 + +const char* Symbols::Gruu = "gruu"; + + +#if defined(WIN32) +const char *Symbols::pathSep = "\\"; +#else +const char *Symbols::pathSep = "/"; +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Symbols.hxx b/src/libs/resiprocate/resip/stack/Symbols.hxx new file mode 100644 index 00000000..c4fb6597 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Symbols.hxx @@ -0,0 +1,175 @@ +#if !defined(RESIP_SYMBOLS_HXX) +#define RESIP_SYMBOLS_HXX + + +namespace resip +{ + +class Symbols +{ + public: + static const char* DefaultSipVersion; + static const char* DefaultSipScheme; + + static const char* AT_SIGN; + static const char* COLON; + static const char* BAR; + static const char* DASH; + static const char* DASHDASH; + static const char* DOT; + static const char* COMMA_OR_EQUAL; + static const char* CRLF; + static const char* CRLFCRLF; + static const char* CR; + static const char* LF; + static const char* TAB; + static const char* DOUBLE_QUOTE; + static const char* LA_QUOTE; + static const char* RA_QUOTE; + static const char* EQUALS; + static const char* SEMI_COLON; + static const char* SEMI_OR_EQUAL; + static const char* SLASH; + static const char* B_SLASH; + static const char* SPACE; + static const char* COMMA; + static const char* ZERO; + static const char* LPAREN; + static const char* RPAREN; + static const char* LS_BRACKET; + static const char* RS_BRACKET; + static const char* PERIOD; + static const char* QUESTION; + static const char* AMPERSAND; + static const char* PERCENT; + static const char* STAR; + static const char* UNDERSCORE; + + static const char* ProtocolName; + static const char* ProtocolVersion; + static const char* UDP; + static const char* TCP; + static const char* TLS; + static const char* DTLS; + static const char* SCTP; + static const char* SRVUDP; + static const char* SRVTCP; + static const char* SRVTLS; + static const char* SRVSCTP; + + static const char* Sip; + static const char* Sips; + static const char* Tel; + static const char* Pres; + + static const char* Phone; + static const char* Isub; + static const char* Postd; + + static const char* auth; + static const char* authInt; + static const char* Digest; + static const char* Basic; + + static const char * const MagicCookie; + static const char * const resipCookie; + + static const int DefaultSipPort; + static const int SipTlsPort; + static const int DefaultSipsPort; + + static const char* SrvSip; + static const char* SrvSips; + static const char* SrvUdp; + static const char* SrvTcp; + static const char* NaptrSip; + static const char* NaptrSips; + static const char* NaptrUdp; + static const char* NaptrTcp; + + static const char* audio; + static const char* RTP_AVP; + static const char* RTP_SAVP; + static const char* UDP_TLS_RTP_SAVP; + + static const char* Presence; + static const char* Required; + static const char* Optional; + + static const char* C100rel; + static const char* Replaces; + static const char* Timer; + static const char* NoReferSub; + static const char* AnswerMode; + static const char* TargetDialog; + static const char* Path; + static const char* Outbound; + static const char* Undefined; + + static const char* Pending; + static const char* Active; + static const char* Terminated; + + static const char* Certificate; // from draft-ietf-certs + static const char* Credential; // from draft-ietf-certs + static const char* SipProfile; //from draft-ietf-sipping-config-framework + + static const char* pathSep; + static const char* id; + + static const char* Gruu; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TODO b/src/libs/resiprocate/resip/stack/TODO new file mode 100644 index 00000000..3c21bf26 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TODO @@ -0,0 +1,91 @@ +$Id: TODO,v 1.16 2004/04/13 05:07:27 jason Exp $ + +Change the names of all the parser "components" to "integerparser" or +something like that + +Complete the pre parser stuff so that transport can do framented messages + +Change name of HeadersTy + + +need to add quote interface to DataParameter -- particularly, fetching +a parameter should return DataParameter& rather than Data . the +application is responsible for passing in a quoted string if they want +quotes. + +the application will never get back a quoted one when it asks for a +DataParameter. + +there should be a UserData which is used for anything the user might +input. it has the property that the stack will examine the contents +for quotable material, e.g. if you pass in + + Bob Smith + +it will produce either + + Bob%20Smith + +or + + "Bob Smith" + +depending on what's right. + + +Missing classes of headers: + + Date + Warning + (someone should check these after done) + +Make Symbols Data + +Convert Data to unsigned char interface. + +Add correct const semantics to parserCategories +explicity disallow paramaters or declare parameter accessors where they can be used + +If we proper const parameter retrieval we should probably throw if the user +tries to retrieve a parameter that doesn't exist. + +make case sensitive/case insensitive datas + +handle the case where a request gets sent over the wire to the stack with no +via. currently will assert when getTransactionId() is called + +- change StatusLine::responseCode() to StatusLine::statusCode() +- change CSeqCategory to CSeq + +ParameterTypeEnums => ParametersEnum +ParameterTypes => Parameters + +break up ParserCategories + +Socket => FdSet, as FdSet is a class and socket isn't + +Data::data() => Data::buffer() + +Change BaseException::~BaseException to be pure virtual - cullen has changed +this for a windows problem temporarily + + +TcpTransport has a long timeout in it if a tcp rst occurs + +Fix popt on os/x platforms. +Fix (improve) default configure behaviours. + + + +REMOVE the following files from sip/resiprocate +Dialog2.cxx/hxx +Dialog.cxx/hxx +DialogSet.cxx/hxx +Registration.cxx/hxx +SipMessageExplicit.cxx/hxx +SipSession.cxx/hxx +Subscription.cxx/hxx +TuIM.cxx/hxx +TuShim.cxx/hxx +TuUa.hxx +Testing diff --git a/src/libs/resiprocate/resip/stack/TcpBaseTransport.cxx b/src/libs/resiprocate/resip/stack/TcpBaseTransport.cxx new file mode 100644 index 00000000..59a368e3 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TcpBaseTransport.cxx @@ -0,0 +1,413 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <memory> +#include "rutil/Socket.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/TcpBaseTransport.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +using namespace std; +using namespace resip; + + +const size_t TcpBaseTransport::MaxWriteSize = 4096; +const size_t TcpBaseTransport::MaxReadSize = 4096; + +TcpBaseTransport::TcpBaseTransport(Fifo<TransactionMessage>& fifo, + int portNum, IpVersion version, + const Data& pinterface, + AfterSocketCreationFuncPtr socketFunc, + Compression &compression, + unsigned transportFlags) + : InternalTransport(fifo, portNum, version, pinterface, socketFunc, compression, transportFlags) +{ + if ( (mTransportFlags & RESIP_TRANSPORT_FLAG_NOBIND)==0 ) + { + mFd = InternalTransport::socket(TCP, version); + } +} + + +TcpBaseTransport::~TcpBaseTransport() +{ + //DebugLog (<< "Shutting down TCP Transport " << this << " " << mFd << " " << mInterface << ":" << port()); + + // !jf! this is not right. should drain the sends before + while (mTxFifoOutBuffer.messageAvailable()) + { + SendData* data = mTxFifoOutBuffer.getNext(); + InfoLog (<< "Throwing away queued data for " << data->destination); + + fail(data->transactionId, TransportFailure::TransportShutdown); + delete data; + } + DebugLog (<< "Shutting down " << mTuple); + //mSendRoundRobin.clear(); // clear before we delete the connections + if(mPollGrp && mPollItemHandle) + { + mPollGrp->delPollItem(mPollItemHandle); + mPollItemHandle=0; + } +} + +// called from constructor of TcpTransport +void +TcpBaseTransport::init() +{ + if ( (mTransportFlags & RESIP_TRANSPORT_FLAG_NOBIND)!=0 ) + { + return; + } + + //DebugLog (<< "Opening TCP " << mFd << " : " << this); + + int on = 1; +#if !defined(WIN32) + if ( ::setsockopt ( mFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) ) +#else + if ( ::setsockopt ( mFd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) ) +#endif + { + int e = getErrno(); + InfoLog (<< "Couldn't set sockoptions SO_REUSEPORT | SO_REUSEADDR: " << strerror(e)); + error(e); + throw Exception("Failed setsockopt", __FILE__,__LINE__); + } + + bind(); + makeSocketNonBlocking(mFd); + + // do the listen, seting the maximum queue size for compeletly established + // sockets -- on linux, tcp_max_syn_backlog should be used for the incomplete + // queue size(see man listen) + int e = listen(mFd,64 ); + + if (e != 0 ) + { + int e = getErrno(); + InfoLog (<< "Failed listen " << strerror(e)); + error(e); + // !cj! deal with errors + throw Transport::Exception("Address already in use", __FILE__,__LINE__); + } +} + +// ?kw?: when should this be called relative to init() above? merge? +void +TcpBaseTransport::setPollGrp(FdPollGrp *grp) +{ + if(mPollGrp && mPollItemHandle) + { + mPollGrp->delPollItem(mPollItemHandle); + mPollItemHandle=0; + } + + if ( mFd!=INVALID_SOCKET && grp) + { + mPollItemHandle = grp->addPollItem(mFd, FPEM_Read|FPEM_Edge, this); + // above released by InternalTransport destructor + // ?bwc? Is this really a good idea? If the InternalTransport d'tor is + // freeing this, shouldn't InternalTransport::setPollGrp() handle + // creating it? + } + mConnectionManager.setPollGrp(grp); + + InternalTransport::setPollGrp(grp); +} + +void +TcpBaseTransport::buildFdSet( FdSet& fdset) +{ + assert( mPollGrp==NULL ); + mConnectionManager.buildFdSet(fdset); + if ( mFd!=INVALID_SOCKET ) + { + fdset.setRead(mFd); // for the transport itself (accept) + } + if(!shareStackProcessAndSelect()) + { + mSelectInterruptor.buildFdSet(fdset); + } +} + +/** + Returns 1 if created new connection, -1 if "bad" error, + and 0 if nothing to do (EWOULDBLOCK) +**/ +int +TcpBaseTransport::processListen() +{ + if (1) + { + Tuple tuple(mTuple); + struct sockaddr& peer = tuple.getMutableSockaddr(); + socklen_t peerLen = tuple.length(); + Socket sock = accept( mFd, &peer, &peerLen); + if ( sock == SOCKET_ERROR ) + { + int e = getErrno(); + switch (e) + { + case EWOULDBLOCK: + // !jf! this can not be ready in some cases + // !kw! this will happen every epoll cycle + return 0; + default: + Transport::error(e); + } + return -1; + } + makeSocketNonBlocking(sock); + + DebugLog (<< "Received TCP connection from: " << tuple << " as fd=" << sock); + + if (mSocketFunc) + { + mSocketFunc(sock, transport(), __FILE__, __LINE__); + } + + if(!mConnectionManager.findConnection(tuple)) + { + createConnection(tuple, sock, true); + } + else + { + InfoLog(<<"Someone probably sent a reciprocal SYN at us."); + // ?bwc? Can we call this right after calling accept()? + closeSocket(sock); + } + } + return 1; +} + +Connection* +TcpBaseTransport::makeOutgoingConnection(const Tuple &dest, + TransportFailure::FailureReason &failReason, int &failSubCode) +{ + // attempt to open + Socket sock = InternalTransport::socket( TCP, ipVersion()); + // fdset.clear(sock); !kw! removed as part of epoll impl + + if ( sock == INVALID_SOCKET ) // no socket found - try to free one up and try again + { + int err = getErrno(); + InfoLog (<< "Failed to create a socket " << strerror(err)); + error(err); + mConnectionManager.gc(ConnectionManager::MinimumGcAge, 1); // free one up + + sock = InternalTransport::socket( TCP, ipVersion()); + if ( sock == INVALID_SOCKET ) + { + err = getErrno(); + WarningLog( << "Error in finding free filedescriptor to use. " << strerror(err)); + error(err); + failReason = TransportFailure::TransportNoSocket; + failSubCode = err; + return NULL; + } + } + + assert(sock != INVALID_SOCKET); + + DebugLog (<<"Opening new connection to " << dest); + makeSocketNonBlocking(sock); + if (mSocketFunc) + { + mSocketFunc(sock, transport(), __FILE__, __LINE__); + } + const sockaddr& servaddr = dest.getSockaddr(); + int ret = connect( sock, &servaddr, dest.length() ); + + // See Chapter 15.3 of Stevens, Unix Network Programming Vol. 1 2nd Edition + if (ret == SOCKET_ERROR) + { + int err = getErrno(); + + switch (err) + { + case EINPROGRESS: + case EWOULDBLOCK: + break; + default: + { + // !jf! this has failed + InfoLog( << "Error on TCP connect to " << dest << ", err=" << err << ": " << strerror(err)); + error(err); + //fdset.clear(sock); + closeSocket(sock); + failReason = TransportFailure::TransportBadConnect; + failSubCode = err; + return NULL; + } + } + } + + // This will add the connection to the manager + Connection *conn = createConnection(dest, sock, false); + assert(conn); + conn->mRequestPostConnectSocketFuncCall = true; + return conn; +} + +void +TcpBaseTransport::processAllWriteRequests() +{ + while (mTxFifoOutBuffer.messageAvailable()) + { + SendData* data = mTxFifoOutBuffer.getNext(); + DebugLog (<< "Processing write for " << data->destination); + + // this will check by connectionId first, then by address + Connection* conn = mConnectionManager.findConnection(data->destination); + + //DebugLog (<< "TcpBaseTransport::processAllWriteRequests() using " << conn); + + // There is no connection yet, so make a client connection + if (conn == 0 && + !data->destination.onlyUseExistingConnection && + data->command == 0) // SendData commands (ie. close connection and enable flow timers) shouldn't cause new connections to form + { + TransportFailure::FailureReason failCode = TransportFailure::Failure; + int subCode = 0; + if((conn=makeOutgoingConnection(data->destination, failCode, subCode)) == NULL) + { + fail(data->transactionId, failCode, subCode); + delete data; + return; // .kw. WHY? What about messages left in queue? + } + assert(conn->getSocket() != INVALID_SOCKET); + // .kw. why do below? We already have the conn, who uses key? + data->destination.mFlowKey = conn->getSocket(); // !jf! + } + + if (conn == 0) + { + DebugLog (<< "Failed to create/get connection: " << data->destination); + fail(data->transactionId, TransportFailure::TransportNoExistConn, 0); + delete data; + // NOTE: We fail this one but don't give up on others in queue + } + else // have a connection + { + if (mTransportLogger) + { + sockaddr_in addr; + memset(&addr, 0, sizeof addr); + addr = (const sockaddr_in&)data->destination.getSockaddr(); + mTransportLogger->onSipMessage(TransportLogger::Flow_Sent, (const char*)data->data.c_str(), data->data.size(), (const sockaddr*)&addr, sizeof addr); + } + + conn->requestWrite(data); + } + } +} + +void +TcpBaseTransport::process() +{ + mStateMachineFifo.flush(); + + // called within SipStack's thread. There is some risk of + // recursion here if connection starts doing anything fancy. + // For backward-compat when not-epoll, don't handle transmit synchronously + // now, but rather wait for the process() call + if (mPollGrp) + { + processAllWriteRequests(); + } +} + +void +TcpBaseTransport::process(FdSet& fdSet) +{ + assert( mPollGrp==NULL ); + + processAllWriteRequests(); + + // process the connections in ConnectionManager + mConnectionManager.process(fdSet); + + mStateMachineFifo.flush(); + + // process our own listen/accept socket for incoming connections + if (mFd!=INVALID_SOCKET && fdSet.readyToRead(mFd)) + { + processListen(); + } +} + +void +TcpBaseTransport::processPollEvent(FdPollEventMask mask) { + if ( mask & FPEM_Read ) + { + while ( processListen() > 0 ) + ; + } +} + +void +TcpBaseTransport::setRcvBufLen(int buflen) +{ + assert(0); // not implemented yet + // need to store away the length and use when setting up new connections +} + + + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TcpBaseTransport.hxx b/src/libs/resiprocate/resip/stack/TcpBaseTransport.hxx new file mode 100644 index 00000000..7460b36f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TcpBaseTransport.hxx @@ -0,0 +1,127 @@ +#if !defined(RESIP_TCPBASETRANSPORT_HXX) +#define RESIP_TCPBASETRANSPORT_HXX + +#include "resip/stack/InternalTransport.hxx" +#include "resip/stack/ConnectionManager.hxx" +#include "resip/stack/Compression.hxx" + +namespace resip +{ + +class TransactionMessage; + +class TcpBaseTransport : public InternalTransport, public FdPollItemIf +{ + public: + TcpBaseTransport(Fifo<TransactionMessage>& fifo, + int portNum, + IpVersion version, + const Data& interfaceName, + AfterSocketCreationFuncPtr socketFunc, + Compression &compression, + unsigned transportFlags = 0); + virtual ~TcpBaseTransport(); + + + + virtual void processPollEvent(FdPollEventMask mask); + virtual void process(FdSet& fdset); + virtual void buildFdSet( FdSet& fdset); + virtual bool isReliable() const { return true; } + virtual bool isDatagram() const { return false; } + virtual void process(); + virtual void setPollGrp(FdPollGrp *grp); + virtual void setRcvBufLen(int buflen); + + ConnectionManager& getConnectionManager() {return mConnectionManager;} + const ConnectionManager& getConnectionManager() const {return mConnectionManager;} + + protected: + /** Performs constructor activities that depend on virtual + * functions specified by derived classes. Derived classes + should call this in their constructors. */ + virtual void init(); + + /** Makes new Connection using provided socket. */ + virtual Connection* createConnection(const Tuple& who, Socket fd, bool server=false)=0; + + /** Forms a connection if one doesn't exist, moves requests to the + appropriate connection's fifo. + */ + void processAllWriteRequests(); + + /** This doesn't exist anywhere that I can find? !kw! + *void sendFromRoundRobin(FdSet& fdset); + */ + + // return 1 if accepted connection + int processListen(); + + /* Helper to make a new outgoing TCP connection. + * Makes the socket, connects it, etc. + */ + Connection* makeOutgoingConnection(const Tuple &dest, + TransportFailure::FailureReason &failCode, int &subCode); + + static const size_t MaxWriteSize; + static const size_t MaxReadSize; + + private: + static const int MaxBufferSize; + ConnectionManager mConnectionManager; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TcpConnection.cxx b/src/libs/resiprocate/resip/stack/TcpConnection.cxx new file mode 100644 index 00000000..64a712bd --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TcpConnection.cxx @@ -0,0 +1,177 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "rutil/Logger.hxx" +#include "rutil/Socket.hxx" +#include "resip/stack/TcpConnection.hxx" +#include "resip/stack/Tuple.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +TcpConnection::TcpConnection(Transport* transport,const Tuple& who, Socket fd, + Compression &compression) + : Connection(transport,who, fd, compression) +{ + DebugLog (<< "Creating TCP connection " << who << " on " << fd); +} + +int +TcpConnection::read( char* buf, int count ) +{ + assert(buf); + assert(count > 0); + +#if defined(WIN32) + int bytesRead = ::recv(getSocket(), buf, count, 0); +#else + int bytesRead = ::read(getSocket(), buf, count); +#endif + + if (bytesRead == SOCKET_ERROR) + { + int e = getErrno(); + switch (e) + { + case EAGAIN: +#ifdef WIN32 //EWOULDBLOCK is not returned from recv on *nix/*bsd + case EWOULDBLOCK: +#endif + InfoLog (<< "No data ready to read"); + return 0; + case EINTR: + InfoLog (<< "The call was interrupted by a signal before any data was read."); + return 0; + break; + case EIO: + InfoLog (<< "I/O error"); + break; + case EBADF: + InfoLog (<< "fd is not a valid file descriptor or is not open for reading."); + break; + case EINVAL: + InfoLog (<< "fd is attached to an object which is unsuitable for reading."); + break; + case EFAULT: + InfoLog (<< "buf is outside your accessible address space."); + break; + default: + InfoLog (<< "Some other error"); + break; + } + + InfoLog (<< "Failed read on " << getSocket() << " " << strerror(e)); + Transport::error(e); + setFailureReason(TransportFailure::ConnectionException, e+2000); + return -1; + } + else if (bytesRead == 0) + { + InfoLog (<< "Connection closed by remote " << *this); + return -1; + } + + return bytesRead; +} + + +int +TcpConnection::write( const char* buf, const int count ) +{ + //DebugLog (<< "Writing " << buf); // Note: this can end up writing garbage to the logs following the message for non-null terminated buffers + + assert(buf); + assert(count > 0); + +#if defined(WIN32) + int bytesWritten = ::send(getSocket(), buf, count, 0); +#else + int bytesWritten = ::write(getSocket(), buf, count); +#endif + + if (bytesWritten == INVALID_SOCKET) + { + int e = getErrno(); + if (e == EAGAIN || e == EWOULDBLOCK) // Treat EGAIN and EWOULDBLOCK as the same: http://stackoverflow.com/questions/7003234/which-systems-define-eagain-and-ewouldblock-as-different-values + { + // TCP buffers are backed up - we couldn't write anything - but we shouldn't treat this an error - return we wrote 0 bytes + return 0; + } + InfoLog (<< "Failed write on " << getSocket() << " " << strerror(e)); + Transport::error(e); + return -1; + } + + return bytesWritten; +} + +bool +TcpConnection::hasDataToRead() +{ + return false; +} + +bool +TcpConnection::isGood() +{ + return true; +} + +bool +TcpConnection::isWritable() +{ + return true; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TcpConnection.hxx b/src/libs/resiprocate/resip/stack/TcpConnection.hxx new file mode 100644 index 00000000..815a0ead --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TcpConnection.hxx @@ -0,0 +1,80 @@ +#if !defined(TcpConnection_hxx) +#define TcpConnection_hxx + +#include "resip/stack/Connection.hxx" + +namespace resip +{ + +class Tuple; + +class TcpConnection : public Connection +{ + public: + TcpConnection( Transport* transport, const Tuple& who, Socket fd, Compression &compression); + + int read( char* buf, const int count ); + int write( const char* buf, const int count ); + virtual bool hasDataToRead(); // has data that can be read + virtual bool isGood(); // has valid connection + virtual bool isWritable(); + Data peerName(); + + private: + /// No default c'tor + TcpConnection(); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TcpTransport.cxx b/src/libs/resiprocate/resip/stack/TcpTransport.cxx new file mode 100644 index 00000000..8c0dd874 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TcpTransport.cxx @@ -0,0 +1,100 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <memory> +#include "rutil/compat.hxx" +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/TcpTransport.hxx" +#include "resip/stack/TcpConnection.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +using namespace std; +using namespace resip; + +TcpTransport::TcpTransport(Fifo<TransactionMessage>& fifo, int portNum, + IpVersion version, const Data& pinterface, + AfterSocketCreationFuncPtr socketFunc, + Compression &compression, + unsigned transportFlags) + : TcpBaseTransport(fifo, portNum, version, pinterface, socketFunc, compression, transportFlags) +{ + mTuple.setType(transport()); + + init(); + + InfoLog (<< "Creating TCP transport host=" << pinterface + << " port=" << mTuple.getPort() + << " ipv4=" << bool(version==V4) ); + + mTxFifo.setDescription("TcpTransport::mTxFifo"); +} + +TcpTransport::~TcpTransport() +{ +} + +Connection* +TcpTransport::createConnection(const Tuple& who, Socket fd, bool server) +{ + assert(this); + Connection* conn = new TcpConnection(this,who, fd, mCompression); + conn->setTransportLogger(mTransportLogger); + return conn; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TcpTransport.hxx b/src/libs/resiprocate/resip/stack/TcpTransport.hxx new file mode 100644 index 00000000..67748d24 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TcpTransport.hxx @@ -0,0 +1,83 @@ +#if !defined(RESIP_TCPTRANSPORT_HXX) +#define RESIP_TCPTRANSPORT_HXX + +#include "resip/stack/TcpBaseTransport.hxx" +#include "resip/stack/Compression.hxx" + +namespace resip +{ + +class TransactionMessage; + +class TcpTransport : public TcpBaseTransport +{ + public: + TcpTransport(Fifo<TransactionMessage>& fifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + AfterSocketCreationFuncPtr socketFunc=0, + Compression &compression = Compression::Disabled, + unsigned transportFlags = 0); + virtual ~TcpTransport(); + + TransportType transport() const { return TCP; } + + protected: + Connection* createConnection(const Tuple& who, Socket fd, bool server=false); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TerminateFlow.hxx b/src/libs/resiprocate/resip/stack/TerminateFlow.hxx new file mode 100644 index 00000000..2648a3e7 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TerminateFlow.hxx @@ -0,0 +1,94 @@ +#ifndef TerminateFlow_Include_Guard +#define TerminateFlow_Include_Guard + +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/Tuple.hxx" + +namespace resip +{ +class TerminateFlow : public TransactionMessage +{ + public: + explicit TerminateFlow(const resip::Tuple& flow) : + mFlow(flow) + {} + virtual ~TerminateFlow(){} + + virtual const Data& getTransactionId() const {return Data::Empty;} + const Tuple& getFlow() const { return mFlow; } + + virtual bool isClientTransaction() const {return true;} + virtual EncodeStream& encode(EncodeStream& strm) const + { + return strm << "TerminateFlow: " << mFlow; + } + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "TerminateFlow: " << mFlow; + } + + virtual Message* clone() const + { + return new TerminateFlow(*this); + } + + protected: + const resip::Tuple mFlow; + +}; // class TerminateFlow + +} // namespace resip + +#endif // include guard + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ + diff --git a/src/libs/resiprocate/resip/stack/TimeAccumulate.cxx b/src/libs/resiprocate/resip/stack/TimeAccumulate.cxx new file mode 100644 index 00000000..8617a68b --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TimeAccumulate.cxx @@ -0,0 +1,90 @@ +#include "resip/stack/TimeAccumulate.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::STATS + +using namespace resip; + +resip::Mutex TimeAccumulate::mMutex; + +TimeAccumulate::TimeMap TimeAccumulate::mTimes; + +void +TimeAccumulate::dump() +{ + Lock lock(mMutex); + WarningLog(<< "Accumulated times -------------------------:"); + for (TimeMap::const_iterator i = TimeAccumulate::mTimes.begin(); + i != TimeAccumulate::mTimes.end(); i++) + { + if (i->second.totalTime) + { + WarningLog(<< i->first << " = " << i->second.totalTime/1000.0 + << " seconds for " << i->second.count + << " at " << i->second.count / (i->second.totalTime/1000.0) << " per second"); + } + } +} + +void +TimeAccumulate::clear() +{ + Lock lock(mMutex); + + for (TimeMap::iterator i = TimeAccumulate::mTimes.begin(); + i != TimeAccumulate::mTimes.end(); i++) + { + i->second.count = 0; + i->second.totalTime = 0; + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TimeAccumulate.hxx b/src/libs/resiprocate/resip/stack/TimeAccumulate.hxx new file mode 100644 index 00000000..1a9a3966 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TimeAccumulate.hxx @@ -0,0 +1,154 @@ +#ifndef TimeAccumulate_hxx +#define TimeAccumulate_hxx + +#include <map> + +#include "rutil/Data.hxx" +#include "rutil/Lock.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/Timer.hxx" + +namespace resip +{ + +/** + Accumulates time and count by distinct string. + The data is available statically. + Use class::method as the key when possible to avoid collision. +*/ +class TimeAccumulate +{ + private: + struct Accumulator + { + UInt64 totalTime; + size_t count; + }; + + public: +#if 1 + TimeAccumulate(const Data& name) + : mName(name), + mStart(Timer::getTimeMs()) + {} + + ~TimeAccumulate() + { + UInt64 end = Timer::getTimeMs(); + end -= mStart; + Lock lock(TimeAccumulate::mMutex); + + Accumulator& acc = TimeAccumulate::mTimes[mName]; + acc.count += 1; + acc.totalTime += end; + } +#else + TimeAccumulate(const char* chars) + : mName(Data::Empty), + mStart(0) + {} + + TimeAccumulate(const Data& name) + : mName(Data::Empty), + mStart(0) + {} + + ~TimeAccumulate() + { + } +#endif + + static UInt64 getTime(const Data& name) + { + Lock lock(TimeAccumulate::mMutex); + return TimeAccumulate::mTimes[name].totalTime; + } + + static size_t getCount(const Data& name) + { + Lock lock(TimeAccumulate::mMutex); + return TimeAccumulate::mTimes[name].count; + } + + static void dump(); + static void clear(); + + class Guard + { + public: + explicit Guard(UInt64& accumulator) + : mAccumulator(accumulator) + { + mAccumulator -= Timer::getTimeMs(); + } + ~Guard() + { + mAccumulator += Timer::getTimeMs(); + } + + private: + UInt64& mAccumulator; + }; + + private: + typedef std::map<Data, Accumulator> TimeMap; + + const Data mName; + const UInt64 mStart; + + static Mutex mMutex; + static TimeMap mTimes; +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TimerMessage.cxx b/src/libs/resiprocate/resip/stack/TimerMessage.cxx new file mode 100644 index 00000000..be44e29d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TimerMessage.cxx @@ -0,0 +1,134 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <cassert> +#include "resip/stack/TimerMessage.hxx" + +using namespace resip; + +TimerMessage::TimerMessage(Data transactionId, Timer::Type type, unsigned long duration) + : mTransactionId(transactionId), + mType(type), + mDuration(duration) {} + +const Data& +TimerMessage::getTransactionId() const +{ + return mTransactionId; +} + +Timer::Type +TimerMessage::getType() const +{ + return mType; +} + +unsigned long +TimerMessage::getDuration() const +{ + return mDuration; +} + +TimerMessage::~TimerMessage() +{} + +bool +TimerMessage::isClientTransaction() const +{ + switch (mType) + { + case Timer::TimerA: + case Timer::TimerB: + case Timer::TimerD: + case Timer::TimerE1: + case Timer::TimerE2: + case Timer::TimerF: + case Timer::TimerK: + case Timer::TimerStaleClient: + case Timer::TimerCleanUp: + case Timer::TimerStateless: + return true; + + case Timer::TimerG: + case Timer::TimerH: + case Timer::TimerI: + case Timer::TimerJ: + case Timer::TimerStaleServer: + case Timer::TimerTrying: + return false; + + case Timer::TimerC: + assert(0); + break; + + default: + assert(0); + break; + } + assert(0); + return false; +} + + + +EncodeStream& +TimerMessage::encodeBrief(EncodeStream& str) const +{ + return str << "Timer: " << Timer::toData(mType) << " " << mDuration; +} + +EncodeStream& TimerMessage::encode(EncodeStream& strm) const +{ + return strm << "TimerMessage TransactionId[" << mTransactionId << "] " + << " Type[" << Timer::toData(mType) << "]" + << " duration[" << mDuration << "]"; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TimerMessage.hxx b/src/libs/resiprocate/resip/stack/TimerMessage.hxx new file mode 100644 index 00000000..6aedd8de --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TimerMessage.hxx @@ -0,0 +1,86 @@ +#if !defined(RESIP_TIMERMESSAGE_HXX) +#define RESIP_TIMERMESSAGE_HXX + +#include <iosfwd> +#include "resip/stack/TransactionMessage.hxx" +#include "rutil/Timer.hxx" +#include "rutil/Data.hxx" +#include "rutil/HeapInstanceCounter.hxx" + +namespace resip +{ + +class TimerMessage : public TransactionMessage +{ + public: + RESIP_HeapCount(TimerMessage); + TimerMessage(Data transactionId, Timer::Type type, unsigned long duration); + ~TimerMessage(); + + virtual const Data& getTransactionId() const; + Timer::Type getType() const; + unsigned long getDuration() const; + bool isClientTransaction() const; + + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& str) const; + + private: + Data mTransactionId; + Timer::Type mType; + unsigned long mDuration; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TimerQueue.cxx b/src/libs/resiprocate/resip/stack/TimerQueue.cxx new file mode 100644 index 00000000..e8d22ad0 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TimerQueue.cxx @@ -0,0 +1,167 @@ + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <cassert> +#include <limits.h> + +#include "resip/stack/TimerQueue.hxx" +#include "resip/stack/TimerMessage.hxx" +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/TuSelector.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION + +TransactionTimerQueue::TransactionTimerQueue(Fifo<TimerMessage>& fifo) + : mFifo(fifo) +{ +} + +#ifdef USE_DTLS + +DtlsTimerQueue::DtlsTimerQueue( Fifo<DtlsMessage>& fifo ) + : mFifo( fifo ) +{ +} + +#endif + +UInt64 +TransactionTimerQueue::add(Timer::Type type, const Data& transactionId, unsigned long msOffset) +{ + TransactionTimer t(msOffset, type, transactionId); + mTimers.push(t); + DebugLog (<< "Adding timer: " << Timer::toData(type) << " tid=" << transactionId << " ms=" << msOffset); + return mTimers.top().getWhen(); +} + +#ifdef USE_DTLS + +UInt64 +DtlsTimerQueue::add( SSL *ssl, unsigned long msOffset ) +{ + TimerWithPayload t( msOffset, new DtlsMessage( ssl ) ) ; + mTimers.push( t ) ; + return mTimers.top().getWhen(); +} + +#endif + +UInt64 +BaseTimeLimitTimerQueue::add(unsigned int timeMs,Message* payload) +{ + assert(payload); + DebugLog(<< "Adding application timer: " << payload->brief() << " ms=" << timeMs); + mTimers.push(TimerWithPayload(timeMs,payload)); + return mTimers.top().getWhen(); +} + +void +BaseTimeLimitTimerQueue::processTimer(const TimerWithPayload& timer) +{ + assert(timer.getMessage()); + addToFifo(timer.getMessage(), TimeLimitFifo<Message>::InternalElement); +} + +void +TransactionTimerQueue::processTimer(const TransactionTimer& timer) +{ + mFifo.add(new TimerMessage(timer.getTransactionId(), + timer.getType(), + timer.getDuration())); +} + +TimeLimitTimerQueue::TimeLimitTimerQueue(TimeLimitFifo<Message>& fifo) : mFifo(fifo) +{} + +void +TimeLimitTimerQueue::addToFifo(Message*msg, TimeLimitFifo<Message>::DepthUsage d) +{ + mFifo.add(msg, d); +} + +TuSelectorTimerQueue::TuSelectorTimerQueue(TuSelector& sel) : mFifoSelector(sel) +{} + +UInt64 +TuSelectorTimerQueue::add(unsigned int timeMs,Message* payload) +{ + assert(payload); + DebugLog(<< "Adding application timer: " << payload->brief() << " ms=" << timeMs); + mTimers.push(TimerWithPayload(timeMs,payload)); + return mTimers.top().getWhen(); +} + +void +TuSelectorTimerQueue::processTimer(const TimerWithPayload& timer) +{ + mFifoSelector.add(timer.getMessage(), + TimeLimitFifo<Message>::InternalElement); +} + +#ifdef USE_DTLS + +void +DtlsTimerQueue::processTimer(const TimerWithPayload& timer) +{ + mFifo.add( (DtlsMessage *)timer.getMessage() ) ; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TimerQueue.hxx b/src/libs/resiprocate/resip/stack/TimerQueue.hxx new file mode 100644 index 00000000..5a30b44e --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TimerQueue.hxx @@ -0,0 +1,303 @@ +#if !defined(RESIP_TIMERQUEUE_HXX) +#define RESIP_TIMERQUEUE_HXX + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include <queue> +#include <set> +#include <iosfwd> +#if _MSC_VER >= 1700 +# include <functional> +#endif + +#include "resip/stack/TimerMessage.hxx" +#include "resip/stack/DtlsMessage.hxx" +#include "rutil/Fifo.hxx" +#include "rutil/TimeLimitFifo.hxx" +#include "rutil/Timer.hxx" + +// .dlb. +// to do: timer wheel for transaction-bound timers and a heap for +// everything longer. + +namespace resip +{ + +class Message; +class TransactionMessage; +class TuSelector; + +/** + * @internal + * @brief This class takes a fifo as a place to where you can write your stuff. + * When using this in the main loop, call process() on this. + * During Transaction processing, TimerMessages and SIP messages are generated. + * + * @todo !dcm! - refactor, templatize + @todo .dlb. timer wheel for transaction-bound timers and a heap for + everything longer. + */ +template <class T> +class TimerQueue +{ + public: + // This is the logic that runs when a timer goes off. This is the only + // thing subclasses must implement. + virtual void processTimer(const T& timer)=0; + + + + /// @brief deletes the message associated with the timer as well. + virtual ~TimerQueue() + { + //xkd-2004-11-4 + // delete the message associated with the timer + while (!mTimers.empty()) + { + mTimers.pop(); + } + } + + /// @brief provides the time in milliseconds before the next timer will fire + /// @retval milliseconds time until the next timer will fire + /// @retval 0 implies that timers occur in the past + /// @retval INT_MAX implies that there are no timers + /// + unsigned int msTillNextTimer() + { + if (!mTimers.empty()) + { + UInt64 next = mTimers.top().getWhen(); + UInt64 now = Timer::getTimeMs(); + if (now > next) + { + return 0; + } + else + { + UInt64 ret64 = next - now; + if ( ret64 > UInt64(INT_MAX) ) + { + return INT_MAX; + } + else + { + int ret = int(ret64); + return ret; + } + } + } + else + { + return INT_MAX; + } + } + + /// @brief gets the set of timers that have fired, and inserts TimerMsg into the state + /// machine fifo and application messages into the TU fifo + virtual UInt64 process() + { + if (!mTimers.empty()) + { + UInt64 now=Timer::getTimeMs(); + while (!mTimers.empty() && !(mTimers.top().getWhen() > now)) + { + processTimer(mTimers.top()); + mTimers.pop(); + } + + if(!mTimers.empty()) + { + return mTimers.top().getWhen(); + } + } + return 0; + } + + int size() const + { + return (int)mTimers.size(); + } + bool empty() const + { + return mTimers.empty(); + } + + + std::ostream& encode(std::ostream& str) const + { + if(mTimers.size() > 0) + { + return str << "TimerQueue[ size =" << mTimers.size() + << " top=" << mTimers.top() << "]" ; + } + else + { + return str << "TimerQueue[ size = 0 ]"; + } + } + +#ifndef RESIP_USE_STL_STREAMS + EncodeStream& encode(EncodeStream& str) const + { + if(mTimers.size() > 0) + { + return str << "TimerQueue[ size =" << mTimers.size() + << " top=" << mTimers.top() << "]" ; + } + else + { + return str << "TimerQueue[ size = 0 ]"; + } + } +#endif + + protected: + typedef std::vector<T, std::allocator<T> > TimerVector; + std::priority_queue<T, TimerVector, std::greater<T> > mTimers; +}; + +/** + @internal +*/ +class BaseTimeLimitTimerQueue : public TimerQueue<TimerWithPayload> +{ + public: + UInt64 add(unsigned int timeMs,Message* payload); + virtual void processTimer(const TimerWithPayload& timer); + protected: + virtual void addToFifo(Message*, TimeLimitFifo<Message>::DepthUsage)=0; +}; + + +/** + @internal +*/ +class TimeLimitTimerQueue : public BaseTimeLimitTimerQueue +{ + public: + TimeLimitTimerQueue(TimeLimitFifo<Message>& fifo); + protected: + virtual void addToFifo(Message*, TimeLimitFifo<Message>::DepthUsage); + private: + TimeLimitFifo<Message>& mFifo; +}; + + +/** + @internal +*/ +class TuSelectorTimerQueue : public TimerQueue<TimerWithPayload> +{ + public: + TuSelectorTimerQueue(TuSelector& sel); + UInt64 add(unsigned int timeMs,Message* payload); + virtual void processTimer(const TimerWithPayload& timer); + private: + TuSelector& mFifoSelector; +}; + + +/** + @internal +*/ +class TransactionTimerQueue : public TimerQueue<TransactionTimer> +{ + public: + TransactionTimerQueue(Fifo<TimerMessage>& fifo); + UInt64 add(Timer::Type type, const Data& transactionId, unsigned long msOffset); + virtual void processTimer(const TransactionTimer& timer); + private: + Fifo<TimerMessage>& mFifo; +}; + +#ifdef USE_DTLS + +#include <openssl/ssl.h> + +/** + @internal +*/ +class DtlsTimerQueue : public TimerQueue<TimerWithPayload> +{ + public: + DtlsTimerQueue( Fifo<DtlsMessage>& fifo ) ; + UInt64 add( SSL *, unsigned long msOffset ) ; + virtual void processTimer(const TimerWithPayload& timer) ; + + private: + Fifo<DtlsMessage>& mFifo ; +}; + +#endif + +template <class T> +std::ostream& operator<<(std::ostream& str, const TimerQueue<T>& tq) +{ + return tq.encode(str); +} + +#ifndef RESIP_USE_STL_STREAMS +template <class T> +EncodeStream& operator<<(EncodeStream& str, const TimerQueue<T>& tq) +{ + return tq.encode(str); +} +#endif + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Token.cxx b/src/libs/resiprocate/resip/stack/Token.cxx new file mode 100644 index 00000000..f4ca3c51 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Token.cxx @@ -0,0 +1,258 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Token.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + + +//==================== +// Token +//=================== +Token::Token() + : ParserCategory(), + mValue() +{} + +Token::Token(const Data& d) + : ParserCategory(), + mValue(d) +{} + +Token::Token(const HeaderFieldValue& hfv, Headers::Type type, PoolBase* pool) + : ParserCategory(hfv, type, pool), + mValue() +{} + +Token::Token(const Token& rhs, PoolBase* pool) + : ParserCategory(rhs, pool), + mValue(rhs.mValue) +{} + +Token& +Token::operator=(const Token& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mValue = rhs.mValue; + } + return *this; +} + +bool +Token::isEqual(const Token& rhs) const +{ + return (value() == rhs.value()); +} + +bool +Token::operator==(const Token& rhs) const +{ + return (value() == rhs.value()); +} + +bool +Token::operator!=(const Token& rhs) const +{ + return (value() != rhs.value()); +} + +bool +Token::operator<(const Token& rhs) const +{ + return (value() < rhs.value()); +} + +const Data& +Token::value() const +{ + checkParsed(); + return mValue; +} + +Data& +Token::value() +{ + checkParsed(); + return mValue; +} + +void +Token::parse(ParseBuffer& pb) +{ + const char* startMark = pb.skipWhitespace(); + pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::SEMI_COLON); + pb.data(mValue, startMark); + pb.skipToChar(Symbols::SEMI_COLON[0]); + parseParameters(pb); +} + +ParserCategory* +Token::clone() const +{ + return new Token(*this); +} + +ParserCategory* +Token::clone(void* location) const +{ + return new (location) Token(*this); +} + +ParserCategory* +Token::clone(PoolBase* pool) const +{ + return new (pool) Token(*this, pool); +} + +EncodeStream& +Token::encodeParsed(EncodeStream& str) const +{ + str << mValue; + encodeParameters(str); + return str; +} + +ParameterTypes::Factory Token::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; + +Parameter* +Token::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) +{ + if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) + { + return ParameterFactories[type](type, pb, terminators, pool); + } + return 0; +} + +bool +Token::exists(const Param<Token>& paramType) const +{ + checkParsed(); + bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; + return ret; +} + +void +Token::remove(const Param<Token>& paramType) +{ + checkParsed(); + removeParameterByEnum(paramType.getTypeNum()); +} + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ +_enum##_Param::DType& \ +Token::param(const _enum##_Param& paramType) \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + p = new _enum##_Param::Type(paramType.getTypeNum()); \ + mParameters.push_back(p); \ + } \ + return p->value(); \ +} \ + \ +const _enum##_Param::DType& \ +Token::param(const _enum##_Param& paramType) const \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ + DebugLog(<< *this); \ + throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ + } \ + return p->value(); \ +} + +defineParam(text, "text", ExistsOrDataParameter, "RFC 3840"); +defineParam(cause, "cause", UInt32Parameter, "RFC 3326"); +defineParam(dAlg, "d-alg", DataParameter, "RFC 3329"); +defineParam(dQop, "d-qop", DataParameter, "RFC 3329"); +defineParam(dVer, "d-ver", QuotedDataParameter, "RFC 3329"); +defineParam(expires, "expires", UInt32Parameter, "RFC 3261"); +defineParam(filename, "filename", DataParameter, "RFC 2183"); +defineParam(fromTag, "from-tag", DataParameter, "RFC 4235"); +defineParam(handling, "handling", DataParameter, "RFC 3261"); +defineParam(id, "id", DataParameter, "RFC 3265"); +defineParam(q, "q", QValueParameter, "RFC 3261"); +defineParam(reason, "reason", DataParameter, "RFC 3265"); +defineParam(retryAfter, "retry-after", UInt32Parameter, "RFC 3265"); +defineParam(toTag, "to-tag", DataParameter, "RFC 4235"); +defineParam(extension, "ext", DataParameter, "RFC 3966"); // Token is used when ext is a user-parameter +defineParam(profileType, "profile-type", DataParameter, "RFC 6080"); +defineParam(vendor, "vendor", QuotedDataParameter, "RFC 6080"); +defineParam(model, "model", QuotedDataParameter, "RFC 6080"); +defineParam(version, "version", QuotedDataParameter, "RFC 6080"); +defineParam(effectiveBy, "effective-by", UInt32Parameter, "RFC 6080"); +defineParam(document, "document", DataParameter, "draft-ietf-sipping-config-framework-07 (removed in 08)"); +defineParam(appId, "app-id", DataParameter, "draft-ietf-sipping-config-framework-05 (renamed to auid in 06, which was then removed in 08)"); +defineParam(networkUser, "network-user", DataParameter, "draft-ietf-sipping-config-framework-11 (removed in 12)"); +defineParam(require, "require", DataParameter, "RFC 5373"); + +#undef defineParam + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Token.hxx b/src/libs/resiprocate/resip/stack/Token.hxx new file mode 100644 index 00000000..eb996036 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Token.hxx @@ -0,0 +1,149 @@ +#if !defined(RESIP_TOKEN_HXX) +#define RESIP_TOKEN_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/ParserContainer.hxx" + +namespace resip +{ + + +/** + @ingroup sip_grammar + @brief Represents the "token" element in the RFC 3261 grammar. +*/ +class Token : public ParserCategory +{ + public: + enum {commaHandling = CommasAllowedOutputCommas}; + + Token(); + explicit Token(const Data& d); + Token(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + Token(const Token& orig, + PoolBase* pool=0); + Token& operator=(const Token&); + bool isEqual(const Token& rhs) const; + bool operator==(const Token& rhs) const; + bool operator!=(const Token& rhs) const; + bool operator<(const Token& rhs) const; + + /** + Gets the value (ie; no parameters) of this Token as a Data&. + */ + const Data& value() const; + Data& value(); + + virtual void parse(ParseBuffer& pb); // remember to call parseParameters() + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + + // Inform the compiler that overloads of these may be found in + // ParserCategory, too. + using ParserCategory::exists; + using ParserCategory::remove; + using ParserCategory::param; + + virtual Parameter* createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool); + bool exists(const Param<Token>& paramType) const; + void remove(const Param<Token>& paramType); + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ + const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \ + _enum##_Param::DType& param(const _enum##_Param& paramType); \ + friend class _enum##_Param + + defineParam(text, "text", ExistsOrDataParameter, "RFC 3840"); + defineParam(cause, "cause", UInt32Parameter, "RFC 3326"); + defineParam(dAlg, "d-alg", DataParameter, "RFC 3329"); + defineParam(dQop, "d-qop", DataParameter, "RFC 3329"); + defineParam(dVer, "d-ver", QuotedDataParameter, "RFC 3329"); + defineParam(expires, "expires", UInt32Parameter, "RFC 3261"); + defineParam(filename, "filename", DataParameter, "RFC 2183"); + defineParam(fromTag, "from-tag", DataParameter, "RFC 4235"); + defineParam(handling, "handling", DataParameter, "RFC 3261"); + defineParam(id, "id", DataParameter, "RFC 3265"); + defineParam(q, "q", QValueParameter, "RFC 3261"); + defineParam(reason, "reason", DataParameter, "RFC 3265"); + defineParam(retryAfter, "retry-after", UInt32Parameter, "RFC 3265"); + defineParam(toTag, "to-tag", DataParameter, "RFC 4235"); + defineParam(extension, "ext", DataParameter, "RFC 3966"); // Token is used when ext is a user-parameter + defineParam(profileType, "profile-type", DataParameter, "RFC 6080"); + defineParam(vendor, "vendor", QuotedDataParameter, "RFC 6080"); + defineParam(model, "model", QuotedDataParameter, "RFC 6080"); + defineParam(version, "version", QuotedDataParameter, "RFC 6080"); + defineParam(effectiveBy, "effective-by", UInt32Parameter, "RFC 6080"); + defineParam(document, "document", DataParameter, "draft-ietf-sipping-config-framework-07 (removed in 08)"); + defineParam(appId, "app-id", DataParameter, "draft-ietf-sipping-config-framework-05 (renamed to auid in 06, which was then removed in 08)"); + defineParam(networkUser, "network-user", DataParameter, "draft-ietf-sipping-config-framework-11 (removed in 12)"); + defineParam(require, "require", DataParameter, "RFC 5373"); + +#undef defineParam + + private: + Data mValue; + + static ParameterTypes::Factory ParameterFactories[ParameterTypes::MAX_PARAMETER]; +}; +typedef ParserContainer<Token> Tokens; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionController.cxx b/src/libs/resiprocate/resip/stack/TransactionController.cxx new file mode 100644 index 00000000..cf130afb --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionController.cxx @@ -0,0 +1,323 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/AbandonServerTransaction.hxx" +#include "resip/stack/ApplicationMessage.hxx" +#include "resip/stack/CancelClientInviteTransaction.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/TerminateFlow.hxx" +#include "resip/stack/EnableFlowTimer.hxx" +#include "resip/stack/ZeroOutStatistics.hxx" +#include "resip/stack/PollStatistics.hxx" +#include "resip/stack/ShutdownMessage.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/TransactionController.hxx" +#include "resip/stack/TransactionState.hxx" +#ifdef USE_SSL +#include "resip/stack/ssl/Security.hxx" +#endif +#include "rutil/CongestionManager.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/SipStack.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION + +#if defined(WIN32) && !defined (__GNUC__) +#pragma warning( disable : 4355 ) // using this in base member initializer list +#endif + +unsigned int TransactionController::MaxTUFifoSize = 0; +unsigned int TransactionController::MaxTUFifoTimeDepthSecs = 0; + +TransactionController::TransactionController(SipStack& stack, + AsyncProcessHandler* handler) : + mStack(stack), + mDiscardStrayResponses(true), + mFixBadDialogIdentifiers(true), + mFixBadCSeqNumbers(true), + mStateMacFifo(handler), + mStateMacFifoOutBuffer(mStateMacFifo), + mCongestionManager(0), + mTuSelector(stack.mTuSelector), + mTransportSelector(mStateMacFifo, + stack.getSecurity(), + stack.getDnsStub(), + stack.getCompression()), + mTimers(mTimerFifo), + mShuttingDown(false), + mStatsManager(stack.mStatsManager), + mHostname(DnsUtil::getLocalHostName()) +{ + mStateMacFifo.setDescription("TransactionController::mStateMacFifo"); +} + +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( default : 4355 ) +#endif + +TransactionController::~TransactionController() +{ + if(mClientTransactionMap.size()) + { + WarningLog(<< "On shutdown, there are Client TransactionStates remaining!"); + } + + if(mServerTransactionMap.size()) + { + WarningLog(<< "On shutdown, there are Server TransactionStates remaining!"); + } +} + + +bool +TransactionController::isTUOverloaded() const +{ + return !mTuSelector.wouldAccept(TimeLimitFifo<Message>::EnforceTimeDepth); +} + +void +TransactionController::shutdown() +{ + mShuttingDown = true; + mTransportSelector.shutdown(); +} + +void +TransactionController::process(int timeout) +{ + if (mShuttingDown && + //mTimers.empty() && + !mStateMacFifoOutBuffer.messageAvailable() && // !dcm! -- see below + !mStack.mTUFifo.messageAvailable() && + mTransportSelector.isFinished()) +// !dcm! -- why would one wait for the Tu's fifo to be empty before delivering a +// shutdown message? + { + //!dcm! -- send to all? + mTuSelector.add(new ShutdownMessage, TimeLimitFifo<Message>::InternalElement); + } + else + { + unsigned int nextTimer(mTimers.msTillNextTimer()); + timeout=resipMin((int)nextTimer, timeout); + if(timeout==0) + { + // *sigh* + timeout=-1; + } + + // If non-zero is passed for timeout, we understand that the caller is ok + // with us waiting up to that long on this call. A non-zero timeout is + // passed by TransactionControllerThread, for example. This gets us + // something approximating a blocking wait on both the state machine fifo + // and the timer queue. + TransactionMessage* message=mStateMacFifoOutBuffer.getNext(timeout); + + // If we either had timers ready to go at the beginning of this call, or + // the getNext() call above timed out, our timer queue is likely ready to + // be serviced. + if(!message || nextTimer==0) + { + mTimers.process(); + TimerMessage* timer; + while ((timer=mTimerFifo.getNext(-1))) + { + TransactionState::processTimer(*this,timer); + } + } + + if(message) + { + // Only do 16 at a time; don't let the timer queue (or other + // processing) starve. + int runs=16; + while(message) + { + TransactionState::process(*this, message); + if(--runs==0) + { + break; + } + message = mStateMacFifoOutBuffer.getNext(-1); + } + + mTransportSelector.poke(); + } + } +} + +unsigned int +TransactionController::getTimeTillNextProcessMS() +{ + if ( mStateMacFifoOutBuffer.messageAvailable() ) + { + return 0; + } + return mTimers.msTillNextTimer(); +} + +void +TransactionController::send(SipMessage* msg) +{ + if(msg->isRequest() && + msg->method() != ACK && + getRejectionBehavior()!=CongestionManager::NORMAL) + { + // Need to 503 this. + SipMessage* resp(Helper::makeResponse(*msg, 503)); + resp->header(h_RetryAfter).value()=(UInt32)mStateMacFifo.expectedWaitTimeMilliSec()/1000; + resp->setTransactionUser(msg->getTransactionUser()); + mTuSelector.add(resp, TimeLimitFifo<Message>::InternalElement); + delete msg; + return; + } + mStateMacFifo.add(msg); +} + + +unsigned int +TransactionController::getTuFifoSize() const +{ + return mTuSelector.size(); +} + +unsigned int +TransactionController::sumTransportFifoSizes() const +{ + return mTransportSelector.sumTransportFifoSizes(); +} + +unsigned int +TransactionController::getTransactionFifoSize() const +{ + // Should we include the stuff in mStateMacFifoOutBuffer here too? This is + // likely to be called from other threads... + return mStateMacFifo.size(); +} + +unsigned int +TransactionController::getNumClientTransactions() const +{ + return mClientTransactionMap.size(); +} + +unsigned int +TransactionController::getNumServerTransactions() const +{ + return mServerTransactionMap.size(); +} + +unsigned int +TransactionController::getTimerQueueSize() const +{ + return mTimers.size(); +} + +void +TransactionController::zeroOutStatistics() +{ + mStateMacFifo.add(new ZeroOutStatistics()); +} + +void +TransactionController::pollStatistics() +{ + mStateMacFifo.add(new PollStatistics()); +} + +void +TransactionController::registerMarkListener(MarkListener* listener) +{ + mTransportSelector.registerMarkListener(listener); +} + +void TransactionController::unregisterMarkListener(MarkListener* listener) +{ + mTransportSelector.unregisterMarkListener(listener); +} + +void +TransactionController::abandonServerTransaction(const Data& tid) +{ + mStateMacFifo.add(new AbandonServerTransaction(tid)); +} + +void +TransactionController::cancelClientInviteTransaction(const Data& tid) +{ + mStateMacFifo.add(new CancelClientInviteTransaction(tid)); +} + +void +TransactionController::terminateFlow(const resip::Tuple& flow) +{ + mStateMacFifo.add(new TerminateFlow(flow)); +} + +void +TransactionController::enableFlowTimer(const resip::Tuple& flow) +{ + mStateMacFifo.add(new EnableFlowTimer(flow)); +} + +void +TransactionController::setInterruptor(AsyncProcessHandler* handler) +{ + mStateMacFifo.setInterruptor(handler); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionController.hxx b/src/libs/resiprocate/resip/stack/TransactionController.hxx new file mode 100644 index 00000000..fcfba306 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionController.hxx @@ -0,0 +1,218 @@ +#if !defined(RESIP_TRANSACTION_CONTROLLER_HXX) +#define RESIP_TRANSACTION_CONTROLLER_HXX + +#include "resip/stack/TuSelector.hxx" +#include "resip/stack/TransactionMap.hxx" +#include "resip/stack/TransportSelector.hxx" +#include "resip/stack/TimerQueue.hxx" +#include "rutil/CongestionManager.hxx" + +#include "rutil/ConsumerFifoBuffer.hxx" + +namespace resip +{ + +class TransactionMessage; +class TimerMessage; +class ApplicationMessage; +class StatisticsManager; +class SipStack; +class Compression; +class FdPollGrp; + +class TransactionController +{ + public: + // set after starting at your peril + static unsigned int MaxTUFifoSize; + static unsigned int MaxTUFifoTimeDepthSecs; + + TransactionController(SipStack& stack, + AsyncProcessHandler* handler); + ~TransactionController(); + + void process(int timeout=0); + unsigned int getTimeTillNextProcessMS(); + + // graceful shutdown (eventually) + void shutdown(); + + TransportSelector& transportSelector() { return mTransportSelector; } + const TransportSelector& transportSelector() const { return mTransportSelector; } + + bool isTUOverloaded() const; + + void send(SipMessage* msg); + + unsigned int getTuFifoSize() const; + unsigned int sumTransportFifoSizes() const; + unsigned int getTransactionFifoSize() const; + unsigned int getNumClientTransactions() const; + unsigned int getNumServerTransactions() const; + unsigned int getTimerQueueSize() const; + void zeroOutStatistics(); + void pollStatistics(); + + void setCongestionManager( CongestionManager *manager ) + { + mTransportSelector.setCongestionManager(manager); + if(mCongestionManager) + { + mCongestionManager->unregisterFifo(&mStateMacFifo); + } + mCongestionManager=manager; + if(mCongestionManager) + { + mCongestionManager->registerFifo(&mStateMacFifo); + } + } + + CongestionManager::RejectionBehavior getRejectionBehavior() const + { + if(mCongestionManager) + { + return mCongestionManager->getRejectionBehavior(&mStateMacFifo); + } + return CongestionManager::NORMAL; + } + + void registerMarkListener(MarkListener* listener); + void unregisterMarkListener(MarkListener* listener); + + inline bool getFixBadDialogIdentifiers() const + { + return mFixBadDialogIdentifiers; + } + + inline void setFixBadDialogIdentifiers(bool pFixBadDialogIdentifiers) + { + mFixBadDialogIdentifiers = pFixBadDialogIdentifiers; + } + + inline bool getFixBadCSeqNumbers() const { return mFixBadCSeqNumbers;} + inline void setFixBadCSeqNumbers(bool pFixBadCSeqNumbers) + { + mFixBadCSeqNumbers = pFixBadCSeqNumbers; + } + + void abandonServerTransaction(const Data& tid); + void cancelClientInviteTransaction(const Data& tid); + void terminateFlow(const resip::Tuple& flow); + void enableFlowTimer(const resip::Tuple& flow); + + void setInterruptor(AsyncProcessHandler* handler); + private: + TransactionController(const TransactionController& rhs); + TransactionController& operator=(const TransactionController& rhs); + SipStack& mStack; + + // If true, indicate to the Transaction to ignore responses for which + // there is no transaction. + // !jf! Probably should transmit stray responses statelessly. see RFC3261 + bool mDiscardStrayResponses; + + bool mFixBadDialogIdentifiers; + + bool mFixBadCSeqNumbers; + // fifo used to communicate to the transaction state machine within the + // stack. Not for external use by the application. May contain, sip + // messages (requests and responses), timers (used by state machines), + // asynchronous dns responses, transport errors from the underlying + // transports, etc. + Fifo<TransactionMessage> mStateMacFifo; + ConsumerFifoBuffer<TransactionMessage> mStateMacFifoOutBuffer; + CongestionManager* mCongestionManager; + + //This needs to be separate from mStateMacFifo, because timer messages + //need to be processed before other work. (If timers start getting behind + //all kinds of nastiness occurs. We can tolerate some SipMessage traffic + //getting behind, but processing timers late can cripple the entire + //system with state-bloat.) + // !bwc! This thing does not need to be threadsafe; it is both populated + // and consumed from the same thread. + Fifo<TimerMessage> mTimerFifo; + + // from the sipstack (for convenience) + TuSelector& mTuSelector; + + // Used to decide which transport to send a sip message on. + TransportSelector mTransportSelector; + + // stores all of the transactions that are currently active in this stack + TransactionMap mClientTransactionMap; + TransactionMap mServerTransactionMap; + + // timers associated with the transactions. When a timer fires, it is + // placed in the mStateMacFifo + TransactionTimerQueue mTimers; + + bool mShuttingDown; + + StatisticsManager& mStatsManager; + + Data mHostname; + + friend class SipStack; // for debug only + friend class StatelessHandler; + friend class TransactionState; + friend class TransportSelector; + + friend class TestDnsResolver; + friend class TestFSM; +}; + + +} + + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionControllerThread.hxx b/src/libs/resiprocate/resip/stack/TransactionControllerThread.hxx new file mode 100644 index 00000000..a2d1158b --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionControllerThread.hxx @@ -0,0 +1,93 @@ +#ifndef TransactionControllerThread_Include_Guard +#define TransactionControllerThread_Include_Guard + +#include "rutil/ThreadIf.hxx" + +#include "resip/stack/TransactionController.hxx" + +namespace resip +{ +class TransactionControllerThread : public ThreadIf +{ + public: + explicit TransactionControllerThread(TransactionController& controller): + mController(controller) + { + // Unhook the transaction controller from the SipStack's + // AsyncProcessHandler, since the stack thread isn't giving cycles to + // the TransactionController anymore. + mController.setInterruptor(0); + } + virtual ~TransactionControllerThread(){} + + +/////////////////// Must implement unless abstract /// + + virtual void thread() + { + while(!isShutdown()) + { + mController.process(25); + } + } + + protected: + TransactionController& mController; + +}; // class TransactionControllerThread + +} // namespace resip + +#endif // include guard + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionMap.cxx b/src/libs/resiprocate/resip/stack/TransactionMap.cxx new file mode 100644 index 00000000..a6ce89e1 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionMap.cxx @@ -0,0 +1,132 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "rutil/Logger.hxx" +#include "resip/stack/TransactionMap.hxx" +#include "resip/stack/TransactionState.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION + +TransactionMap::~TransactionMap() +{ + //DebugLog (<< "Deleting TransactionMap: " << this << " " << mMap.size() << " entries"); + while (!mMap.empty()) + { + DebugLog (<< mMap.begin()->first << " -> " << mMap.begin()->second << ": " << *mMap.begin()->second); + delete mMap.begin()->second; + } +} + +TransactionState* +TransactionMap::find( const Data& tid ) const +{ + MapConstIterator i = mMap.find(tid); + if (i != mMap.end()) + { + return i->second; + } + else + { + return 0; + } +} + +void +TransactionMap::add(const Data& tid, TransactionState* state ) +{ + MapIterator i = mMap.find(tid); + if (i != mMap.end()) + { + if (i->second != state) + { + // .bwc. ~TransactionState will remove itself from the map. + delete i->second; + //DebugLog (<< "Replacing TMAP[" << tid << "] = " << state << " : " << *state); + mMap[tid] = state; + } + } + else + { + //DebugLog (<< "Inserting TMAP[" << tid << "] = " << state << " : " << *state); + mMap[tid] = state; + } +} + +void +TransactionMap::erase(const Data& tid ) +{ + MapIterator i = mMap.find(tid); + if (i != mMap.end()) + { + // don't delete it here, the TransactionState deletes itself and removes + // itself from the map + //DebugLog (<< "Erasing " << tid << "(" << i->second << ")"); + mMap.erase(i); + } + else + { + InfoLog (<< "Couldn't find " << tid << " to remove"); + assert(0); + } +} + +int +TransactionMap::size() const +{ + return (int)mMap.size(); +} + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionMap.hxx b/src/libs/resiprocate/resip/stack/TransactionMap.hxx new file mode 100644 index 00000000..a047812a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionMap.hxx @@ -0,0 +1,150 @@ +#if !defined(RESIP_TRANSACTIONMAP_HXX) +#define RESIP_TRANSACTIONMAP_HXX + +#include "rutil/Data.hxx" +#include "rutil/HashMap.hxx" + +namespace resip +{ + class TransactionState; + +/** + @internal +*/ +class TransactionMap +{ + public: + ~TransactionMap(); + + TransactionState* find( const Data& transactionId ) const; + void add( const Data& transactionId, TransactionState* state ); + void erase( const Data& transactionId ); + int size() const; + + private: + +#if defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310)) // !slg! not sure if this works on __INTEL_COMPILER + /** + @internal + */ + class BranchCompare + { + public: + enum { bucket_size = 4, min_buckets = 8 }; + + inline size_t operator()(const Data& branch) const + { + return branch.caseInsensitiveTokenHash(); + } + + inline bool operator()(const Data& branch1, const Data& branch2) const + { + return isLessThanNoCase(branch1,branch2); + } + }; +#elif defined(HASH_MAP_NAMESPACE) + /** + @internal + */ + class BranchHasher + { + public: + inline size_t operator()(const Data& branch) const + { + return branch.caseInsensitiveTokenHash(); + } + }; + + /** + @internal + */ + class BranchEqual + { + public: + inline bool operator()(const Data& branch1, const Data& branch2) const + { + return isEqualNoCase(branch1,branch2); + } + }; +#else + /** + @internal + */ + class BranchCompare + { + public: + inline bool operator()(const Data& branch1, const Data& branch2) const + { + return isLessThanNoCase(branch1,branch2); + } + }; +#endif + + // .bwc. If rutil/HashMap.hxx fails to find a hash_map impl for the + // platform we're using, it will #define HashMap to a std::map, which + // takes different template args. We try to compensate for this here. +#if defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310)) + typedef HashMap<Data, TransactionState*, BranchCompare> Map; +#elif defined(HASH_MAP_NAMESPACE) + typedef HashMap<Data, TransactionState*, BranchHasher, BranchEqual> Map; +#else + typedef std::map<Data, TransactionState*, BranchCompare> Map; +#endif + + Map mMap; + typedef Map::iterator MapIterator; + typedef Map::const_iterator MapConstIterator; +}; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionMessage.hxx b/src/libs/resiprocate/resip/stack/TransactionMessage.hxx new file mode 100644 index 00000000..f7796e1f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionMessage.hxx @@ -0,0 +1,78 @@ +#ifndef RESIP_TransactionMessage_hxx +#define RESIP_TransactionMessage_hxx + +#include <cassert> +#include "resip/stack/Message.hxx" +#include "rutil/HeapInstanceCounter.hxx" + +namespace resip +{ + +class TransactionMessage : public Message +{ + public: + RESIP_HeapCount(TransactionMessage); + + virtual const Data& getTransactionId() const=0; + + // indicates this message is associated with a Client Transaction for the + // purpose of determining which TransactionMap to use + virtual bool isClientTransaction() const = 0; + + virtual Message* clone() const {assert(false); return NULL;} +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/resip/stack/TransactionState.cxx b/src/libs/resiprocate/resip/stack/TransactionState.cxx new file mode 100644 index 00000000..868b4a31 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionState.cxx @@ -0,0 +1,2969 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/AbandonServerTransaction.hxx" +#include "resip/stack/CancelClientInviteTransaction.hxx" +#include "resip/stack/TerminateFlow.hxx" +#include "resip/stack/EnableFlowTimer.hxx" +#include "resip/stack/ZeroOutStatistics.hxx" +#include "resip/stack/PollStatistics.hxx" +#include "resip/stack/ConnectionTerminated.hxx" +#include "resip/stack/KeepAlivePong.hxx" +#include "resip/stack/DnsInterface.hxx" +#include "resip/stack/DnsResultMessage.hxx" +#include "resip/stack/DnsResult.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/SendData.hxx" +#include "resip/stack/SipStack.hxx" +#include "resip/stack/StatisticsManager.hxx" +#include "resip/stack/TimerMessage.hxx" +#include "resip/stack/TransactionController.hxx" +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/TransactionState.hxx" +#include "resip/stack/TransactionTerminated.hxx" +#include "resip/stack/TransportFailure.hxx" +#include "resip/stack/TransactionUserMessage.hxx" +#include "resip/stack/TransportFailure.hxx" +#include "resip/stack/TransportSelector.hxx" +#include "resip/stack/TransactionUser.hxx" +#include "resip/stack/TuSelector.hxx" +#include "resip/stack/InteropHelper.hxx" +#include "resip/stack/KeepAliveMessage.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/MD5Stream.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Random.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION + +unsigned long TransactionState::StatelessIdCounter = 0; + +TransactionState::TransactionState(TransactionController& controller, Machine m, + State s, const Data& id, MethodTypes method, const Data& methodText, TransactionUser* tu) : + mController(controller), + mMachine(m), + mState(s), + mIsAbandoned(false), + mIsReliable(true), // !jf! + mNextTransmission(0), + mDnsResult(0), + mId(id), + mMethod(method), + mMethodText(method==UNKNOWN ? new Data(methodText) : 0), + mCurrentMethodType(UNKNOWN), + mCurrentResponseCode(0), + mAckIsValid(false), + mWaitingForDnsResult(false), + mTransactionUser(tu), + mFailureReason(TransportFailure::None), + mFailureSubCode(0) +{ + StackLog (<< "Creating new TransactionState: " << *this); +} + + +TransactionState* +TransactionState::makeCancelTransaction(TransactionState* tr, Machine machine, const Data& tid) +{ + TransactionState* cancel = new TransactionState(tr->mController, + machine, + Trying, + tid, + CANCEL, + Data::Empty, + tr->mTransactionUser); + // !jf! don't set this since it will be set by TransactionState::processReliability() + //cancel->mIsReliable = tr->mIsReliable; + cancel->mResponseTarget = tr->mResponseTarget; + cancel->mTarget = tr->mTarget; + cancel->add(tid); + + // !jf! don't call processServerNonInvite since it will delete + // the sip message which needs to get sent to the TU + cancel->processReliability(tr->mTarget.getType()); + return cancel; +} + +void +TransactionState::handleInternalCancel(SipMessage* cancel, + TransactionState& clientInvite) +{ + TransactionState* state = TransactionState::makeCancelTransaction(&clientInvite, ClientNonInvite, clientInvite.mId+"cancel"); + // Make sure the branch in the CANCEL matches the current + // branch of the INVITE, in case we have done a DNS failover (the transport + // sequences could be different by now) + cancel->header(h_Vias).front().param(p_branch)=clientInvite.mNextTransmission->const_header(h_Vias).front().param(p_branch); + state->processClientNonInvite(cancel); + // for the INVITE in case we never get a 487 + clientInvite.mController.mTimers.add(Timer::TimerCleanUp, clientInvite.mId, 128*Timer::T1); +} + +bool +TransactionState::handleBadRequest(const resip::SipMessage& badReq, TransactionController& controller) +{ + assert(badReq.isRequest() && badReq.method() != ACK); + try + { + SipMessage* error = Helper::makeResponse(badReq,400); + if(badReq.getReason()) + { + error->header(h_StatusLine).reason()+="(" + *(badReq.getReason())+ ")"; + } + Tuple target(badReq.getSource()); + + if(badReq.isExternal()) + { + controller.mTransportSelector.transmit(error,target); + delete error; + return true; + } + else + { + // ?bwc? Should we put together a TransactionState here so we can + // send a 400 to the TU? + // TODO if we send the error to the TU, don't delete the error + delete error; + return false; + } + } + catch(resip::BaseException& e) + { + ErrLog(<< "Exception thrown in TransactionState::handleBadRequest." + " This shouldn't happen. " << e); + return false; + } +} + +TransactionState::~TransactionState() +{ + assert(mState != Bogus); + + if (mDnsResult) + { + mDnsResult->destroy(); + } + + //StackLog (<< "Deleting TransactionState " << mId << " : " << this); + erase(mId); + + delete mNextTransmission; + delete mMethodText; + mNextTransmission = 0; + mMethodText = 0; + + mState = Bogus; +} + +bool +TransactionState::processSipMessageAsNew(SipMessage* sip, TransactionController& controller, const Data& tid) +{ + MethodTypes method=sip->method(); + StackLog (<< "No matching transaction for " << sip->brief()); + TransactionUser* tu = 0; + if (sip->isExternal()) + { + if (controller.mTuSelector.haveTransactionUsers() && sip->isRequest()) + { + tu = controller.mTuSelector.selectTransactionUser(*sip); + if (!tu) + { + //InfoLog (<< "Didn't find a TU for " << sip->brief()); + // !bwc! We really should do something other than a 500 here. + // If none of the TUs liked the request because of the Request- + // Uri scheme, we should be returning a 416, for example. + // ?bwc? Um, should we _really_ be doing this statelessly? + InfoLog( << "No TU found for message: " << sip->brief()); + SipMessage* noMatch = Helper::makeResponse(*sip, 500); + Tuple target(sip->getSource()); + + controller.mTransportSelector.transmit(noMatch, target); + delete noMatch; + return false; + } + else + { + //InfoLog (<< "Found TU for " << sip->brief()); + } + } + } + else + { + tu = sip->getTransactionUser(); + if (!tu) + { + //InfoLog (<< "No TU associated with " << sip->brief()); + } + } + + if (sip->isRequest()) + { + // create a new state object and insert in the TransactionMap + + if (sip->isExternal()) // new sip msg from transport + { + if (method == INVITE) + { + // !rk! This might be needlessly created. Design issue. + TransactionState* state = new TransactionState(controller, + ServerInvite, + Trying, + tid, + INVITE, + Data::Empty, + tu); + + state->mNextTransmission = state->make100(sip); + state->mResponseTarget = sip->getSource(); // UACs source address + // since we don't want to reply to the source port if rport present + state->mResponseTarget.setPort(Helper::getPortForReply(*sip)); + state->mIsReliable = isReliable(state->mResponseTarget.getType()); + state->add(tid); + + if (Timer::T100 == 0) + { + state->sendCurrentToWire(); // will get deleted when this is deleted + state->mState = Proceeding; + } + else + { + //StackLog(<<" adding T100 timer (INV)"); + controller.mTimers.add(Timer::TimerTrying, tid, Timer::T100); + } + state->sendToTU(sip); + return true; + } + else if (method == CANCEL) + { + TransactionState* matchingInvite = + controller.mServerTransactionMap.find(sip->getTransactionId()); + if (matchingInvite == 0) + { + InfoLog (<< "No matching INVITE for incoming (from wire) CANCEL to uas"); + //was TransactionState::sendToTU(tu, controller, Helper::makeResponse(*sip, 481)); + SipMessage* response = Helper::makeResponse(*sip, 481); + Tuple target(sip->getSource()); + controller.mTransportSelector.transmit(response, target); + + delete response; + return false; + } + else + { + assert(matchingInvite); + TransactionState* state = TransactionState::makeCancelTransaction(matchingInvite, ServerNonInvite, tid); + state->startServerNonInviteTimerTrying(*sip,tid); + state->sendToTU(sip); + return true; + } + } + else if (method != ACK) + { + TransactionState* state = new TransactionState(controller, + ServerNonInvite, + Trying, + tid, + method, + sip->methodStr(), + tu); + state->mResponseTarget = sip->getSource(); + // since we don't want to reply to the source port if rport present + state->mResponseTarget.setPort(Helper::getPortForReply(*sip)); + state->add(tid); + state->mIsReliable = isReliable(state->mResponseTarget.getType()); + state->startServerNonInviteTimerTrying(*sip,tid); + state->sendToTU(sip); + return true; + } + + // Incoming ACK just gets passed to the TU + //StackLog(<< "Adding incoming message to TU fifo " << tid); + TransactionState::sendToTU(tu, controller, sip); + } + else // new sip msg from the TU + { + if (method == INVITE) + { + TransactionState* state = new TransactionState(controller, + ClientInvite, + Calling, + tid, + INVITE, + Data::Empty, + tu); + state->add(state->mId); + state->processClientInvite(sip); + } + else if (method == ACK) + { + TransactionState* state = new TransactionState(controller, + Stateless, + Calling, + tid, + ACK, + Data::Empty, + tu); + state->add(state->mId); + state->mController.mTimers.add(Timer::TimerStateless, state->mId, Timer::TS ); + state->processStateless(sip); + } + else if (method == CANCEL) + { + TransactionState* matchingInvite = controller.mClientTransactionMap.find(sip->getTransactionId()); + + if (matchingInvite == 0) + { + InfoLog (<< "No matching INVITE for incoming (from TU) CANCEL to uac"); + TransactionState::sendToTU(tu, controller, Helper::makeResponse(*sip,481)); + return false; + } + else if (matchingInvite->mState == Calling) // CANCEL before 1xx received + { + WarningLog(<< "You can't CANCEL a request until a provisional has been received"); + StackLog (<< *matchingInvite); + StackLog (<< *sip); + + matchingInvite->mIsAbandoned = true; + return false; + } + else if (matchingInvite->mState == Completed) + { + // A final response was already seen for this INVITE transaction + matchingInvite->sendToTU(Helper::makeResponse(*sip, 200)); + return false; + } + else + { + handleInternalCancel(sip, *matchingInvite); + } + } + else + { + TransactionState* state = new TransactionState(controller, + ClientNonInvite, + Trying, + tid, + method, + sip->methodStr(), + tu); + state->add(tid); + state->processClientNonInvite(sip); + } + } + } + else if (sip->isResponse()) // stray response + { + if (controller.mDiscardStrayResponses) + { + InfoLog (<< "discarding stray response: " << sip->brief()); + return false; + } + else + { + StackLog (<< "forwarding stateless response: " << sip->brief()); + TransactionState* state = + new TransactionState(controller, + Stateless, + Calling, + Data(StatelessIdCounter++), + method, + sip->methodStr(), + tu); + state->add(state->mId); + state->mController.mTimers.add(Timer::TimerStateless, state->mId, Timer::TS ); + state->processStateless(sip); + } + } + else // wasn't a request or a response + { + ErrLog (<< "Got a SipMessage that was neither a request nor response!" + << sip->brief()); + return false; + } + + return true; +} + +void +TransactionState::process(TransactionController& controller, + TransactionMessage* message) +{ + { + KeepAliveMessage* keepAlive = dynamic_cast<KeepAliveMessage*>(message); + if (keepAlive) + { + StackLog ( << "Sending keep alive to: " << keepAlive->getDestination()); + controller.mTransportSelector.transmit(keepAlive, keepAlive->getDestination()); + delete keepAlive; + return; + } + + ConnectionTerminated* term = dynamic_cast<ConnectionTerminated*>(message); + if (term) + { + if(term->hasTransactionUser()) + { + controller.mTuSelector.add(term); + } + else + { + // .bwc. This means we are using this message to close a connection. + controller.mTransportSelector.closeConnection(term->getFlow()); + } + delete term; + return; + } + + KeepAlivePong* pong = dynamic_cast<KeepAlivePong*>(message); + if (pong) + { + controller.mTuSelector.add(pong); + delete pong; + return; + } + + TerminateFlow* termFlow = dynamic_cast<TerminateFlow*>(message); + if(termFlow) + { + controller.mTransportSelector.terminateFlow(termFlow->getFlow()); + delete termFlow; + return; + } + + EnableFlowTimer* enableFlowTimer = dynamic_cast<EnableFlowTimer*>(message); + if(enableFlowTimer) + { + controller.mTransportSelector.enableFlowTimer(enableFlowTimer->getFlow()); + delete enableFlowTimer; + return; + } + + ZeroOutStatistics* zeroOutStatistics = dynamic_cast<ZeroOutStatistics*>(message); + if(zeroOutStatistics) + { + controller.mStatsManager.zeroOut(); + delete zeroOutStatistics; + return; + } + + PollStatistics* pollStatistics = dynamic_cast<PollStatistics*>(message); + if(pollStatistics) + { + controller.mStatsManager.poll(); + delete pollStatistics; + return; + } + } + + // .bwc. We can't do anything without a tid here. Check this first. + Data tid; + try + { + tid = message->getTransactionId(); + } + catch(SipMessage::Exception&) + { + // .bwc This is not our error. Do not ErrLog. + DebugLog( << "TransactionState::process dropping message with invalid tid " << message->brief()); + delete message; + return; + } + + SipMessage* sip = dynamic_cast<SipMessage*>(message); + MethodTypes method = UNKNOWN; + + if(sip) + { + method=sip->method(); + // ?bwc? Should this come after checking for error conditions? + if(controller.mStack.statisticsManagerEnabled() && sip->isExternal()) + { + controller.mStatsManager.received(sip); + } + + // .bwc. Check for error conditions we can respond to. + if(sip->isRequest() && method != ACK) + { + // .bwc. If we are going to statelessly send a 503, we should do it + // in the transport, before we do expensive stuff like basicCheck and + // stampReceived. If the TU fifo is backed up, we should send a + // _stateful_ 503 below. (And only if the specific TU that can handle + // this message is backed up; if other TUs are congested, we should let + // it pass.) + /* + if(sip->isExternal() && (controller.isTUOverloaded() || controller.mStateMacFifo.isRejecting())) + { + SipMessage* tryLater = Helper::makeResponse(*sip, 503); + if( controller.mStateMacFifo.isRejecting() ) + tryLater->header(h_RetryAfter).value() = controller.mStateMacFifo.getRetryAfter(); + else + tryLater->header(h_RetryAfter).value() = 32 + (Random::getRandom() % 32); + + //tryLater->header(h_RetryAfter).comment() = "Server busy TRANS"; + Tuple target(sip->getSource()); + delete sip; + controller.mTransportSelector.transmit(tryLater, target); + delete tryLater; + return; + } + */ + + if(sip->isInvalid()) + { + handleBadRequest(*sip,controller); + delete sip; + return; + } + } + +#ifdef PEDANTIC_STACK + try + { + sip->parseAllHeaders(); + } + catch(resip::ParseException& e) + { + if(sip->isRequest() && method!=ACK) + { + handleBadRequest(*sip,controller); + } + + InfoLog(<< "Exception caught by pedantic stack: " << e); + } +#endif + + // This ensures that CANCEL requests form unique transactions + if (method == CANCEL) + { + tid += "cancel"; + } + } + + TransactionState* state = 0; + if (message->isClientTransaction()) + state = controller.mClientTransactionMap.find(tid); + else + state = controller.mServerTransactionMap.find(tid); + + if (state && sip && sip->isExternal()) + { + // Various kinds of response fixup. + if(sip->isResponse() && + state->mNextTransmission) + { + // .bwc. This code (if enabled) ensures that responses have the same + // CallId and tags as the request did (excepting the introduction of a + // remote tag). This is to protect dialog-stateful TUs that don't react + // gracefully when a stupid/malicious endpoint fiddles with the tags + // and/or CallId when it isn't supposed to. (DUM is one such TU) + if(state->mController.getFixBadDialogIdentifiers()) + { + if(sip->const_header(h_CallId).isWellFormed()) + { + if(!(sip->const_header(h_CallId) == + state->mNextTransmission->const_header(h_CallId))) + { + InfoLog(<< "Other end modified our Call-Id... correcting."); + sip->header(h_CallId) = state->mNextTransmission->const_header(h_CallId); + } + } + else + { + InfoLog(<< "Other end corrupted our CallId... correcting."); + sip->header(h_CallId) = state->mNextTransmission->const_header(h_CallId); + } + + const NameAddr& from = state->mNextTransmission->const_header(h_From); + if(sip->const_header(h_From).isWellFormed()) + { + // Overwrite tag. + if(from.exists(p_tag)) + { + if(sip->const_header(h_From).param(p_tag) != from.param(p_tag)) + { + InfoLog(<<"Other end modified our local tag... correcting."); + sip->header(h_From).param(p_tag) = from.param(p_tag); + } + } + else if(sip->const_header(h_From).exists(p_tag)) + { + if(sip->const_header(h_From).exists(p_tag)) + { + InfoLog(<<"Other end added a local tag for us... removing."); + sip->header(h_From).remove(p_tag); + } + } + } + else + { + InfoLog(<<"Other end corrupted our From header... replacing."); + // Whole header is hosed, overwrite. + sip->header(h_From) = from; + } + + const NameAddr& to = state->mNextTransmission->const_header(h_To); + if(sip->const_header(h_To).isWellFormed()) + { + // Overwrite tag. + if(to.exists(p_tag)) + { + if(sip->const_header(h_To).param(p_tag) != to.param(p_tag)) + { + InfoLog(<<"Other end modified the (existing) remote tag... " + "correcting."); + sip->header(h_To).param(p_tag) = to.param(p_tag); + } + } + } + else + { + InfoLog(<<"Other end corrupted our To header... replacing."); + // Whole header is hosed, overwrite. + sip->header(h_To) = to; + } + } + + // .bwc. This code (if enabled) ensures that responses have the same + // CSeq number as the request did. This is to protect TUs that don't + // react gracefully when a stupid/malicious endpoint fiddles with the + // CSeq number. (This is a very cheap check; we already parse the CSeq + // for incoming messages) + if(state->mController.getFixBadCSeqNumbers()) + { + unsigned int old=state->mNextTransmission->const_header(h_CSeq).sequence(); + if(sip->const_header(h_CSeq).sequence()!=old) + { + InfoLog(<<"Other end changed our CSeq number... replacing."); + sip->header(h_CSeq).sequence()=old; + } + + if(state->mNextTransmission->exists(h_RAck)) + { + if(!(sip->const_header(h_RAck)==state->mNextTransmission->const_header(h_RAck))) + { + InfoLog(<<"Other end changed our RAck... replacing."); + sip->header(h_RAck)=state->mNextTransmission->const_header(h_RAck); + } + } + } + } + // .bwc. This code ensures that the transaction state-machine can recover + // from ACK/200 with the same tid as the original INVITE. This problem is + // stupidly common. + if(sip->isRequest() && method == ACK && !state->mAckIsValid) + { + // Must have received an ACK to a 200; + // We will never respond to this, so nothing will need this tid for + // driving transaction state. Additionally, + InfoLog(<<"Someone sent us an ACK/200 with the same tid as the " + "original INVITE. This is bad behavior, and should be " + "corrected in the client."); + sip->mIsBadAck200=true; + // .bwc. This is a new stateless transaction, despite its tid. + state=0; + } + } + + if(state && sip) + { + switch(state->mMethod) + { + case INVITE: + if(method != INVITE && method != ACK) + { + // Maybe respond if a request? + delete sip; + return; + } + break; + case UNKNOWN: + if(!state->mMethodText || *(state->mMethodText) != sip->methodStr()) + { + // Maybe respond if a request? + delete sip; + return; + } + break; + default: + if(state->mMethod != method) + { + // Maybe respond if a request? + delete sip; + return; + } + break; + } + } + + if (state) // found transaction for sip msg + { + StackLog (<< "Found matching transaction for " << message->brief() << " -> " << *state); + + switch (state->mMachine) + { + case ClientNonInvite: + state->processClientNonInvite(message); + break; + case ClientInvite: + // ACK from TU will be Stateless + assert (!sip || !(state->isFromTU(sip) && sip->isRequest() && method == ACK)); + state->processClientInvite(message); + break; + case ServerNonInvite: + state->processServerNonInvite(message); + break; + case ServerInvite: + state->processServerInvite(message); + break; + case Stateless: + state->processStateless(message); + break; + case ClientStale: + state->processClientStale(message); + break; + case ServerStale: + state->processServerStale(message); + break; + default: + CritLog(<<"internal state error"); + assert(0); + return; + } + } + else if (sip) // new transaction + { + try + { + bool processed = processSipMessageAsNew(sip, controller, tid); + if (!processed) + { + delete sip; + } + } + catch(resip::ParseException& e) + { + StackLog ( << "Got badly formatted sip message, error: " << e.what()); + if(sip->isRequest() && sip->method()!=ACK) + { + handleBadRequest(*sip, controller); + } + delete sip; + } + catch(std::exception& err) + { + StackLog ( << "Got error: " << err.what()); + delete sip; + } + } + else // timer or other non-sip msg + { + //StackLog (<< "discarding non-sip message: " << message->brief()); + delete message; + } +} + +void +TransactionState::processTimer(TransactionController& controller, + TimerMessage* message) +{ + Data tid = message->getTransactionId(); + + if(controller.getRejectionBehavior()==CongestionManager::REJECTING_NON_ESSENTIAL) + { + // .bwc. State machine fifo is backed up; we probably should not be + // retransmitting anything right now. If we have a retransmit timer, + // reschedule for later, but don't retransmit. + switch(message->getType()) + { + case Timer::TimerA: // doubling + controller.mTimers.add(Timer::TimerA, + tid, + message->getDuration()*2); + delete message; + return; + case Timer::TimerE1:// doubling, until T2 + case Timer::TimerG: // doubling, until T2 + controller.mTimers.add(message->getType(), + tid, + resipMin(message->getDuration()*2, + Timer::T2)); + delete message; + return; + case Timer::TimerE2:// just reset + controller.mTimers.add(Timer::TimerE2, + tid, + Timer::T2); + delete message; + return; + default: + ; // let it through + } + } + + TransactionState* state = 0; + if (message->isClientTransaction()) state = controller.mClientTransactionMap.find(tid); + else state = controller.mServerTransactionMap.find(tid); + + if (state) // found transaction for timer + { + StackLog (<< "Found matching transaction for " << message->brief() << " -> " << *state); + + switch (state->mMachine) + { + case ClientNonInvite: + state->processClientNonInvite(message); + break; + case ClientInvite: + state->processClientInvite(message); + break; + case ServerNonInvite: + state->processServerNonInvite(message); + break; + case ServerInvite: + state->processServerInvite(message); + break; + case Stateless: + state->processStateless(message); + break; + case ClientStale: + state->processClientStale(message); + break; + case ServerStale: + state->processServerStale(message); + break; + default: + CritLog(<<"internal state error"); + assert(0); + return; + } + } + else + { + delete message; + } + +} + +void +TransactionState::startServerNonInviteTimerTrying(SipMessage& sip, const Data& tid) +{ + unsigned int duration = 3500; + if(Timer::T1 != 500) // optimzed for T1 == 500 + { + // Iteratively calculate how much time before TimerE reaches T2 (RFC4320) - could be improved + duration = Timer::T1; + while(duration*2<Timer::T2) duration = duration * 2; + } + resetNextTransmission(make100(&sip)); // Store for use when timer expires + mController.mTimers.add(Timer::TimerTrying, tid, duration ); // Start trying timer so that we can send 100 to NITs as recommened in RFC4320 +} + +void +TransactionState::processStateless(TransactionMessage* message) +{ + // for ACK messages from the TU, there is no transaction, send it directly + // to the wire // rfc3261 17.1 Client Transaction + SipMessage* sip = dynamic_cast<SipMessage*>(message); + StackLog (<< "TransactionState::processStateless: " << message->brief()); + + // !jf! There is a leak for Stateless transactions associated with ACK to 200 + if (isFromTU(message)) + { + resetNextTransmission(sip); + sendCurrentToWire(); + } + else if(sip && isFromWire(sip)) + { + InfoLog (<< "Received message from wire on a stateless transaction"); + StackLog (<< *sip); + //assert(0); + sendToTU(sip); + } + else if (isTransportError(message)) + { + processTransportFailure(message); + + delete message; + delete this; + } + else if (isTimer(message)) + { + TimerMessage* timer = dynamic_cast<TimerMessage*>(message); + if (timer->getType() == Timer::TimerStateless) + { + delete message; + delete this; + } + else + { + delete timer; + assert(0); + } + } + else if(dynamic_cast<DnsResultMessage*>(message)) + { + handleSync(mDnsResult); + delete message; + } + else if (isAbandonServerTransaction(message)) + { + // ? + delete message; + } + else + { + delete message; + assert(0); + } +} + +void +TransactionState::saveOriginalContactAndVia(const SipMessage& sip) +{ + if(sip.exists(h_Contacts) && sip.const_header(h_Contacts).size() == 1 && + sip.const_header(h_Contacts).front().isWellFormed()) + { + mOriginalContact = std::auto_ptr<NameAddr>(new NameAddr(sip.header(h_Contacts).front())); + } + mOriginalVia = std::auto_ptr<Via>(new Via(sip.header(h_Vias).front())); +} + +void TransactionState::restoreOriginalContactAndVia() +{ + if (mOriginalContact.get()) + { + mNextTransmission->header(h_Contacts).front() = *mOriginalContact; + } + if (mOriginalVia.get()) + { + mOriginalVia->param(p_branch).incrementTransportSequence(); + mNextTransmission->header(h_Vias).front() = *mOriginalVia; + } +} + +void +TransactionState::processClientNonInvite(TransactionMessage* msg) +{ + StackLog (<< "TransactionState::processClientNonInvite: " << msg->brief()); + + if (isRequest(msg) && isFromTU(msg)) + { + //StackLog (<< "received new non-invite request"); + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + resetNextTransmission(sip); + saveOriginalContactAndVia(*sip); + mController.mTimers.add(Timer::TimerF, mId, Timer::TF); + sendCurrentToWire(); + } + else if (isResponse(msg) && isFromWire(msg)) // from the wire + { + //StackLog (<< "received response from wire"); + + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + int code = sip->const_header(h_StatusLine).responseCode(); + if (code >= 100 && code < 200) // 1XX + { + if (mState == Trying || mState == Proceeding) + { + //?slg? if we set the timer in Proceeding, then every 1xx response will cause another TimerE2 to be set and many retransmissions will occur - which is not correct + // Should we restart the E2 timer though? If so, we need to use somekind of timer sequence number so that previous E2 timers get discarded. + if (!mIsReliable && mState == Trying) + { + mController.mTimers.add(Timer::TimerE2, mId, Timer::T2 ); + } + mState = Proceeding; + sendToTU(msg); // don't delete + } + else + { + // ignore + delete msg; + } + } + else if (code >= 200) + { + // don't notify the TU of retransmissions + if (mState == Trying || mState == Proceeding) + { + sendToTU(msg); // don't delete + } + else if (mState == Completed) + { + delete msg; + } + else + { + assert(0); + delete sip; + } + + if (mIsReliable) + { + terminateClientTransaction(mId); + delete this; + } + else if (mState != Completed) // prevent TimerK reproduced + { + mState = Completed; + mController.mTimers.add(Timer::TimerK, mId, Timer::T4 ); + // !bwc! Got final response in NIT. We don't need to do anything + // except quietly absorb retransmissions. Dump all state. + if(mDnsResult) + { + mDnsResult->destroy(); + mDnsResult=0; + mWaitingForDnsResult=false; + } + resetNextTransmission(0); + } + } + else + { + assert(0); + delete sip; + } + } + else if (isTimer(msg)) + { + //StackLog (<< "received timer in client non-invite transaction"); + + TimerMessage* timer = dynamic_cast<TimerMessage*>(msg); + switch (timer->getType()) + { + case Timer::TimerE1: + if (mState == Trying) + { + unsigned long d = timer->getDuration(); + if (d < Timer::T2) d *= 2; + mController.mTimers.add(Timer::TimerE1, mId, d); + StackLog (<< "Transmitting current message"); + sendCurrentToWire(); + delete timer; + } + else + { + // ignore + delete msg; + } + break; + + case Timer::TimerE2: + if (mState == Proceeding) + { + mController.mTimers.add(Timer::TimerE2, mId, Timer::T2); + StackLog (<< "Transmitting current message"); + sendCurrentToWire(); + delete timer; + } + else + { + // ignore + delete msg; + } + break; + + case Timer::TimerF: + if (mState == Trying || mState == Proceeding) + { + // !bwc! We hold onto this until we get a response from the wire + // in client transactions, for this contingency. + assert(mNextTransmission); + if(mWaitingForDnsResult) + { + WarningLog(<< "Transaction timed out while waiting for DNS " + "result uri=" << + mNextTransmission->const_header(h_RequestLine).uri()); + sendToTU(Helper::makeResponse(*mNextTransmission, 503, "DNS Timeout")); + } + else + { + sendToTU(Helper::makeResponse(*mNextTransmission, 408)); + } + terminateClientTransaction(mId); + delete this; + } + + delete msg; + break; + + case Timer::TimerK: + terminateClientTransaction(mId); + delete msg; + delete this; + break; + + default: + //InfoLog (<< "Ignoring timer: " << *msg); + delete msg; + break; + } + } + else if (isTransportError(msg)) + { + processTransportFailure(msg); + delete msg; + } + else if(dynamic_cast<DnsResultMessage*>(msg)) + { + handleSync(mDnsResult); + delete msg; + } + else if (isAbandonServerTransaction(msg)) + { + // ? + delete msg; + } + else + { + //StackLog (<< "TransactionState::processClientNonInvite: message unhandled"); + delete msg; + } +} + +void +TransactionState::processClientInvite(TransactionMessage* msg) +{ + StackLog(<< "TransactionState::processClientInvite: " << msg->brief() << " " << *this); + if (isRequest(msg) && isFromTU(msg)) + { + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + switch (sip->method()) + { + // Received INVITE request from TU="Transaction User", Start Timer B which controls + // transaction timeouts. + case INVITE: + if(mState==Calling && !mNextTransmission && mMsgToRetransmit.empty()) + { + resetNextTransmission(sip); + saveOriginalContactAndVia(*sip); + mController.mTimers.add(Timer::TimerB, mId, Timer::TB ); + sendCurrentToWire(); + } + else + { + WarningLog(<< "TU sent us a duplicate INVITE: fix this!"); + delete sip; + } + break; + + case CANCEL: + assert(0); + delete msg; + break; + + default: + WarningLog(<< "TU sent us an erroneous request inside a Client" + " INVITE transaction: fix this!"); + delete msg; + break; + } + } + else if (isResponse(msg) && isFromWire(msg)) + { + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + int code = sip->const_header(h_StatusLine).responseCode(); + switch (sip->method()) + { + case INVITE: + /* If the client transaction receives a provisional response while in + the "Calling" state, it transitions to the "Proceeding" state. In the + "Proceeding" state, the client transaction SHOULD NOT retransmit the + request any longer (this will be Handled in "else if (isTimer(msg))") + The Retransmissions will be stopped, Not by Cancelling Timers but + by Ignoring the fired Timers depending upon the State which stack is in. + */ + if (code >= 100 && code < 200) // 1XX + { + if (mState == Calling || mState == Proceeding) + { + mState = Proceeding; + if(mIsAbandoned) + { + SipMessage* cancel = Helper::makeCancel(*mNextTransmission); + // Iterate through message decorators on the INVITE and see if any need to be copied to the CANCEL + mNextTransmission->copyOutboundDecoratorsToStackCancel(*cancel); + handleInternalCancel(cancel, *this); + mIsAbandoned=false; + } + // !bwc! We have gotten a response. We don't need to + // retransmit the original INVITE anymore (so we clear mMsgToRetransmit), + // but we do need to retain the full original INVITE until we get a final + // response, in case we need to forge an ACK. + mMsgToRetransmit.clear(); + sendToTU(sip); // don't delete msg + } + else + { + delete msg; + } + } + + /* When in either the "Calling" or "Proceeding" states, reception of a + 2xx response MUST cause the client transaction to enter the + "Terminated" state, and the response MUST be passed up to the TU + State Machine is changed to Stale since, we wanted to ensure that + all 2xx gets to TU + */ + else if (code >= 200 && code < 300) + { + mIsAbandoned=false; + sendToTU(sip); // don't delete msg + //terminateClientTransaction(mId); + mMachine = ClientStale; + // !bwc! We have a final response. We don't need either of + // mMsgToRetransmit or mNextTransmission. We ignore further + // traffic. + resetNextTransmission(0); + if(mDnsResult) + { + mDnsResult->destroy(); + mDnsResult=0; + mWaitingForDnsResult=false; + } + StackLog (<< "Received 2xx on client invite transaction"); + StackLog (<< *this); + mController.mTimers.add(Timer::TimerStaleClient, mId, Timer::TS ); + } + else if (code >= 300) + { + mIsAbandoned=false; + // When in either the "Calling" or "Proceeding" states, reception of a + // response with status code from 300-699 MUST cause the client + // transaction to transition to "Completed". + if (mIsReliable) + { + // Stack MUST pass the received response up to the TU, and the client + // transaction MUST generate an ACK request, even if the transport is + // reliable + SipMessage* ack = Helper::makeFailureAck(*mNextTransmission, *sip); + mNextTransmission->copyOutboundDecoratorsToStackFailureAck(*ack); + resetNextTransmission(ack); + + // want to use the same transport as was selected for Invite + assert(mTarget.getType() != UNKNOWN_TRANSPORT); + sendCurrentToWire(); + sendToTU(sip); // don't delete msg + terminateClientTransaction(mId); + + // !bwc! We only do this because we are assured the ACK + // will make it to the other end; if we are using an + // unreliable transport, we need to stick around to absorb + // retransmissions of the response. + delete this; + } + else + { + if (mState == Calling || mState == Proceeding) + { + // MUST pass the received response up to the TU, and the client + // transaction MUST generate an ACK request, even if the transport is + // reliable, if transport is Unreliable then Fire the Timer D which + // take care of re-Transmission of ACK + mState = Completed; + mController.mTimers.add(Timer::TimerD, mId, Timer::TD ); + SipMessage* ack = Helper::makeFailureAck(*mNextTransmission, *sip); + mNextTransmission->copyOutboundDecoratorsToStackFailureAck(*ack); + resetNextTransmission(ack); + sendCurrentToWire(); + if(mDnsResult) + { + mDnsResult->destroy(); + mDnsResult=0; + mWaitingForDnsResult=false; + } + sendToTU(sip); // don't delete msg + } + else if (mState == Completed) + { + // Any retransmissions of the final response that + // are received while in the "Completed" state MUST + // cause the ACK to be re-passed to the transport + // layer for retransmission. + sendCurrentToWire(); + delete sip; + } + else + { + /* This should never Happen if it happens we should have a plan + what to do here?? for now assert will work + */ + CritLog( << "State invalid"); + // !ah! syslog + assert(0); + delete sip; + } + } + } + else + { + delete sip; + assert(0); + } + break; + + case CANCEL: + assert(0); + delete sip; + break; + + default: + delete msg; + break; + } + } + else if (isTimer(msg)) + { + /* Handle Transaction Timers , Retransmission Timers which were set and Handle + Cancellation of Timers for Re-transmissions here */ + + TimerMessage* timer = dynamic_cast<TimerMessage*>(msg); + StackLog (<< "timer fired: " << *timer); + + switch (timer->getType()) + { + case Timer::TimerA: + if (mState == Calling && !mIsAbandoned) + { + unsigned long d = timer->getDuration()*2; + // TimerA is supposed to double with each retransmit RFC3261 17.1.1 + + mController.mTimers.add(Timer::TimerA, mId, d); + DebugLog (<< "Retransmitting INVITE "); + sendCurrentToWire(); + } + delete msg; + break; + + case Timer::TimerB: + if (mState == Calling) + { + assert(mNextTransmission && mNextTransmission->isRequest() && + mNextTransmission->method()==INVITE); + if(mWaitingForDnsResult) + { + WarningLog(<< "Transaction timed out while waiting for DNS " + "result uri=" << + mNextTransmission->const_header(h_RequestLine).uri()); + sendToTU(Helper::makeResponse(*mNextTransmission, 503, "DNS Timeout")); + } + else + { + sendToTU(Helper::makeResponse(*mNextTransmission, 408)); + } + terminateClientTransaction(mId); + delete this; + } + delete msg; + break; + + case Timer::TimerD: + terminateClientTransaction(mId); + delete msg; + delete this; + break; + + case Timer::TimerCleanUp: + // !ah! Cancelled Invite Cleanup Timer fired. + StackLog (<< "Timer::TimerCleanUp: " << *this << std::endl << *mNextTransmission); + if (mState == Proceeding) + { + assert(mNextTransmission && mNextTransmission->isRequest() && + mNextTransmission->method() == INVITE); + InfoLog(<<"Making 408 for canceled invite that received no response: "<< mNextTransmission->brief()); + if(mWaitingForDnsResult) + { + WarningLog(<< "Transaction timed out while waiting for DNS " + "result uri=" << + mNextTransmission->const_header(h_RequestLine).uri()); + sendToTU(Helper::makeResponse(*mNextTransmission, 503, "DNS Timeout")); + } + else + { + sendToTU(Helper::makeResponse(*mNextTransmission, 408)); + } + terminateClientTransaction(msg->getTransactionId()); + delete this; + } + delete msg; + break; + + default: + delete msg; + break; + } + } + else if (isTransportError(msg)) + { + processTransportFailure(msg); + delete msg; + } + else if (isCancelClientTransaction(msg)) + { + // TU wants to CANCEL this transaction. See if we can... + if(mState==Proceeding) + { + // We can send the CANCEL now. + SipMessage* cancel=Helper::makeCancel(*mNextTransmission); + mNextTransmission->copyOutboundDecoratorsToStackCancel(*cancel); + TransactionState::handleInternalCancel(cancel, *this); + } + else if(mState==Calling) + { + // We can't send the CANCEL yet, remember to. + mIsAbandoned = true; + } + delete msg; + } + else if(dynamic_cast<DnsResultMessage*>(msg)) + { + handleSync(mDnsResult); + delete msg; + } + else + { + //StackLog ( << "TransactionState::processClientInvite: message unhandled"); + delete msg; + } +} + +void +TransactionState::processServerNonInvite(TransactionMessage* msg) +{ + StackLog (<< "TransactionState::processServerNonInvite: " << msg->brief()); + + if (isRequest(msg) && !isInvite(msg) && isFromWire(msg)) // retransmission from the wire + { + if (mState == Trying) + { + // ignore + delete msg; + } + else if (mState == Proceeding || mState == Completed) + { + if(mIsAbandoned) + { + assert(mState == Completed); + mIsAbandoned=false; + // put a 500 in mNextTransmission + SipMessage* req = dynamic_cast<SipMessage*>(msg); + resetNextTransmission(Helper::makeResponse(*req, 500)); + sendCurrentToWire(); + } + else + { + sendCurrentToWire(); + } + delete msg; + } + else + { + CritLog (<< "Fatal error in TransactionState::processServerNonInvite " + << msg->brief() + << " state=" << *this); + assert(0); + delete msg; + return; + } + } + else if (isResponse(msg) && isFromTU(msg)) + { + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + int code = sip->const_header(h_StatusLine).responseCode(); + if (code >= 100 && code < 200) // 1XX + { + if (mState == Trying || mState == Proceeding) + { + resetNextTransmission(sip); + mState = Proceeding; + sendCurrentToWire(); // don't delete msg + } + else + { + // ignore + delete msg; + } + } + else if (code >= 200 && code <= 699) + { + if (mIsReliable) + { + resetNextTransmission(sip); + sendCurrentToWire(); + terminateServerTransaction(mId); + + // !bwc! We can only do this because we are in a reliable + // transport, and do not need to hang around to soak up + // retransmissions. + delete this; + } + else + { + if (mState == Trying || mState == Proceeding) + { + mState = Completed; + mController.mTimers.add(Timer::TimerJ, mId, 64*Timer::T1 ); + resetNextTransmission(sip); + sendCurrentToWire(); + } + else if (mState == Completed) + { + // ignore + delete sip; + } + else + { + CritLog (<< "Fatal error in TransactionState::processServerNonInvite " + << msg->brief() + << " state=" << *this); + assert(0); + delete sip; + return; + } + } + } + else + { + // ignore + delete msg; + } + } + else if (isTimer(msg)) + { + TimerMessage* timer = dynamic_cast<TimerMessage*>(msg); + assert(timer); + switch (timer->getType()) + { + case Timer::TimerJ: + if (mState == Completed) + { + terminateServerTransaction(mId); + delete this; + } + delete msg; + break; + + case Timer::TimerTrying: + if (mState == Trying) + { + // Timer E has reached T2 - send a 100 as recommended by RFC4320 NIT-Problem-Actions + sendCurrentToWire(); + mState = Proceeding; + } + delete msg; + break; + + default: + delete msg; + break; + } + } + else if (isTransportError(msg)) + { + processTransportFailure(msg); + delete msg; + } + else if (isAbandonServerTransaction(msg)) + { + if(mState==Trying || mState==Proceeding) + { + mIsAbandoned = true; + + // !bwc! We could check to see if we have a 100 lying around, and + // convert it into a 500 for immediate transmission, but it is not + // clear that this is a good idea, especially if the TU has abandoned + // this transaction after the remote endpoint has stopped + // retransmitting. Maybe we could use a time-stamp to help here? Would + // it be worth the extra memory footprint? + + if (mIsReliable) + { + // If we haven't sent a 500 yet, we never will (no retransmissions + // to make the response with). + terminateServerTransaction(mId); + delete this; + } + else + { + // If we haven't sent a 500 yet, we'll do so when the next + // retransmission comes in. In the meantime, set up timers for + // transaction termination. + mState = Completed; + mController.mTimers.add(Timer::TimerJ, mId, 64*Timer::T1 ); + } + } + delete msg; + } + else if(dynamic_cast<DnsResultMessage*>(msg)) + { + handleSync(mDnsResult); + delete msg; + } + else + { + //StackLog (<< "TransactionState::processServerNonInvite: message unhandled"); + delete msg; + } +} + + +void +TransactionState::processServerInvite(TransactionMessage* msg) +{ + StackLog (<< "TransactionState::processServerInvite: " << msg->brief()); + if (isRequest(msg) && isFromWire(msg)) + { + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + switch (sip->method()) + { + case INVITE: + // note: handling of initial INVITE message is done in TransactionState:process + if(mIsAbandoned) + { + mIsAbandoned=false; + mAckIsValid=true; + resetNextTransmission(Helper::makeResponse(*sip, 500)); + mState = Completed; + mController.mTimers.add(Timer::TimerH, mId, Timer::TH ); + if (!mIsReliable) + { + mController.mTimers.add(Timer::TimerG, mId, Timer::T1 ); + } + sendCurrentToWire(); + delete msg; + return; + } + + if (mState == Proceeding || mState == Completed) + { + /* + The server transaction has already been constructed so this + message is a retransmission. The server transaction must + respond with a 100 Trying _or_ the last provisional response + passed from the TU for this transaction. + */ + //StackLog (<< "Received invite from wire - forwarding to TU state=" << mState); + + // !bwc! If we have nothing to respond with, make something. + if (mMsgToRetransmit.empty() && !mNextTransmission) + { + resetNextTransmission(make100(sip)); + } + delete sip; + sendCurrentToWire(); + } + else + { + //StackLog (<< "Received invite from wire - ignoring state=" << mState); + delete msg; + } + break; + + case ACK: + /* + If an ACK is received while the server transaction is in the + "Completed" state, the server transaction MUST transition to the + "Confirmed" state. + */ + if (mState == Completed) + { + if (mIsReliable) + { + //StackLog (<< "Received ACK in Completed (reliable) - delete transaction"); + terminateServerTransaction(mId); + delete this; + delete msg; + } + else + { + //StackLog (<< "Received ACK in Completed (unreliable) - confirmed, start Timer I"); + mState = Confirmed; + mController.mTimers.add(Timer::TimerI, mId, Timer::T4 ); + // !bwc! Got an ACK/failure; we can stop retransmitting + // our failure response now. + resetNextTransmission(0); + delete sip; + } + } + else + { + //StackLog (<< "Ignore ACK not in Completed state"); + delete msg; + } + break; + + case CANCEL: + assert(0); + delete sip; + break; + + default: + //StackLog (<< "Received unexpected request. Ignoring message"); + delete msg; + break; + } + } + else if (isResponse(msg, 100, 699) && isFromTU(msg)) + { + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + int code = sip->const_header(h_StatusLine).responseCode(); + switch (sip->method()) + { + case INVITE: + if (code == 100) + { + if (mState == Trying || mState == Proceeding) + { + //StackLog (<< "Received 100 in Trying or Proceeding. Send over wire"); + resetNextTransmission(sip); // may be replacing the 100 + mState = Proceeding; + sendCurrentToWire(); // don't delete msg + } + else + { + //StackLog (<< "Ignoring 100 - not in Trying or Proceeding."); + delete msg; + } + } + else if (code > 100 && code < 200) + { + if (mState == Trying || mState == Proceeding) + { + //StackLog (<< "Received 1xx in Trying or Proceeding. Send over wire"); + resetNextTransmission(sip); // may be replacing the 100 + mState = Proceeding; + sendCurrentToWire(); // don't delete msg + } + else + { + //StackLog (<< "Received 100 when not in Trying State. Ignoring"); + delete msg; + } + } + else if (code >= 200 && code < 300) + { + if (mState == Trying || mState == Proceeding) + { + StackLog (<< "Received 2xx when in Trying or Proceeding State of server invite transaction"); + StackLog (<< *this); + resetNextTransmission(sip); // may be replacing the 100 + sendCurrentToWire(); + + // Keep the StaleServer transaction around, so we can keep the + // source Tuple that the request was received on. + //terminateServerTransaction(mId); + mMachine = ServerStale; + mController.mTimers.add(Timer::TimerStaleServer, mId, Timer::TS ); + } + else + { + //StackLog (<< "Received 2xx when not in Trying or Proceeding State. Ignoring"); + delete msg; + } + } + else if (code >= 300) + { + /* + While in the "Proceeding" state, if the TU passes a response with + status code from 300 to 699 to the server transaction, For unreliable + transports,timer G is set to fire in T1 seconds, and is not set to + fire for reliable transports.when the "Completed" state is entered, + timer H MUST be set to fire in 64*T1 seconds for all transports. + Timer H determines when the server transaction abandons retransmitting + the response + */ + + if (mState == Trying || mState == Proceeding) + { + mAckIsValid=true; + StackLog (<< "Received failed response in Trying or Proceeding. Start Timer H, move to completed." << *this); + resetNextTransmission(sip); + mState = Completed; + mController.mTimers.add(Timer::TimerH, mId, Timer::TH ); + if (!mIsReliable) + { + mController.mTimers.add(Timer::TimerG, mId, Timer::T1 ); + } + sendCurrentToWire(); // don't delete msg + } + else + { + //StackLog (<< "Received Final response when not in Trying or Proceeding State. Ignoring"); + delete msg; + } + } + else + { + //StackLog (<< "Received Invalid response line. Ignoring"); + delete msg; + } + break; + + case CANCEL: + assert(0); + delete sip; + break; + + default: + //StackLog (<< "Received response to non invite or cancel. Ignoring"); + delete msg; + break; + } + } + else if (isTimer(msg)) + { + TimerMessage* timer = dynamic_cast<TimerMessage*>(msg); + switch (timer->getType()) + { + case Timer::TimerG: + if (mState == Completed) + { + StackLog (<< "TimerG fired. retransmit, and re-add TimerG"); + sendCurrentToWire(); + mController.mTimers.add(Timer::TimerG, mId, resipMin(Timer::T2, timer->getDuration()*2) ); // TimerG is supposed to double - up until a max of T2 RFC3261 17.2.1 + } + break; + + /* + If timer H fires while in the "Completed" state, it implies that the + ACK was never received. In this case, the server transaction MUST + transition to the "Terminated" state, and MUST indicate to the TU + that a transaction failure has occurred. WHY we need to inform TU + for Failure cases ACK ? do we really need to do this ??? + + !jf! this used to re-add TimerH if there was an associated CANCEL + transaction. Don't know why. + */ + case Timer::TimerH: + case Timer::TimerI: + if (timer->getType() == Timer::TimerH) + { + InfoLog (<< "No ACK was received on a server transaction (Timer H)"); + } + terminateServerTransaction(mId); + delete this; + break; + + case Timer::TimerTrying: + if (mState == Trying) + { + //StackLog (<< "TimerTrying fired. Send a 100"); + sendCurrentToWire(); // will get deleted when this is deleted + mState = Proceeding; + } + else + { + //StackLog (<< "TimerTrying fired. Not in Trying state. Ignoring"); + } + break; + + default: + CritLog(<<"unexpected timer fired: " << timer->getType()); + assert(0); // programming error if any other timer fires + break; + } + delete timer; + } + else if (isTransportError(msg)) + { + processTransportFailure(msg); + delete msg; + } + else if (isAbandonServerTransaction(msg)) + { + if((mState == Trying || mState == Proceeding) && !mIsAbandoned) + { + // We need to schedule teardown, and 500 the next retransmission. + if(mNextTransmission) + { + mMsgToRetransmit.clear(); + // hey, we had a 1xx laying around! Turn it into a 500 and send. + assert(mNextTransmission->isResponse()); + assert(mNextTransmission->const_header(h_StatusLine).statusCode()/100==1); + mNextTransmission->header(h_StatusLine).statusCode()=500; + mNextTransmission->header(h_StatusLine).reason()="Server Error"; + sendCurrentToWire(); + mAckIsValid=true; + StackLog (<< "Received failed response in Trying or Proceeding. Start Timer H, move to completed." << *this); + mState = Completed; + mController.mTimers.add(Timer::TimerH, mId, Timer::TH ); + if (!mIsReliable) + { + mController.mTimers.add(Timer::TimerG, mId, Timer::T1 ); + } + } + else + { + // !bwc! TODO try to convert mMsgToRetransmit if present. + if(mIsReliable) + { + // We will never see another retransmission of the INVITE. We + // need to bail. + terminateServerTransaction(mId); + delete this; + } + else + { + // We should see a retransmission of the INVITE shortly, or we + // will time out eventually. Be patient... + mIsAbandoned = true; + } + } + } + delete msg; + } + else if(dynamic_cast<DnsResultMessage*>(msg)) + { + handleSync(mDnsResult); + delete msg; + } + else + { + //StackLog (<< "TransactionState::processServerInvite: message unhandled"); + delete msg; + } +} + + +void +TransactionState::processClientStale(TransactionMessage* msg) +{ + StackLog (<< "TransactionState::processClientStale: " << msg->brief()); + + if (isTimer(msg)) + { + TimerMessage* timer = dynamic_cast<TimerMessage*>(msg); + if (timer->getType() == Timer::TimerStaleClient) + { + terminateClientTransaction(mId); + delete this; + delete msg; + } + else + { + delete msg; + } + } + else if (isTransportError(msg)) + { + WarningLog (<< "Got a transport error in Stale Client state"); + StackLog (<< *this); + processTransportFailure(msg); + delete msg; + } + else if(isResponse(msg, 200, 299)) + { + assert(isFromWire(msg)); + sendToTU(msg); + } + else if(dynamic_cast<DnsResultMessage*>(msg)) + { + handleSync(mDnsResult); + delete msg; + } + else if (isAbandonServerTransaction(msg)) + { + // ? + delete msg; + } + else if (isCancelClientTransaction(msg)) + { + // ? + delete msg; + } + else + { + // might have received some other response because a downstream UAS is + // misbehaving. For instance, sending a 487/INVITE after already + // sending a 200/INVITE. It could also be some other message type. + StackLog (<< "Discarding extra message: " << *msg); + delete msg; + } +} + +void +TransactionState::processServerStale(TransactionMessage* msg) +{ + StackLog (<< "TransactionState::processServerStale: " << msg->brief()); + + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + if (isTimer(msg)) + { + TimerMessage* timer = dynamic_cast<TimerMessage*>(msg); + if (timer->getType() == Timer::TimerStaleServer) + { + delete msg; + terminateServerTransaction(mId); + delete this; + } + else + { + delete msg; + } + } + else if (isTransportError(msg)) + { + WarningLog (<< "Got a transport error in Stale Server state"); + StackLog (<< *this); + processTransportFailure(msg); + delete msg; + } + else if (sip && isRequest(sip) && sip->method() == ACK) + { + // .bwc. We should never fall into this block. There is code in process + // that should prevent it. + assert(isFromWire(msg)); + InfoLog (<< "Passing ACK directly to TU: " << sip->brief()); + sendToTU(msg); + } + else if (sip && isRequest(sip) && sip->method() == INVITE) + { + // this can happen when an upstream UAC never received the 200 and + // retransmits the INVITE when using unreliable transport + // Drop the INVITE since the 200 will get retransmitted by the downstream UAS + StackLog (<< "Dropping retransmitted INVITE in stale server transaction" << sip->brief()); + delete msg; + } + else if (isResponse(msg) && isFromTU(msg)) + { + resetNextTransmission(sip); + sendCurrentToWire(); + } + else if(dynamic_cast<DnsResultMessage*>(msg)) + { + handleSync(mDnsResult); + delete msg; + } + else if (isAbandonServerTransaction(msg)) + { + // ? + delete msg; + } + else + { + // .bwc. This can very easily be triggered by a stupid/malicious + // endpoint. This is not an error in our code. Do not ErrLog this. + InfoLog(<<"ServerStale unexpected condition, dropping message."); + if (sip) + { + InfoLog(<<sip->brief()); + } + delete msg; + } +} + + +void +TransactionState::processNoDnsResults() +{ + if(!mNextTransmission || mNextTransmission->method()==ACK) + { + // This is probably an ACK; since we know we will never need to send a + // response to an ACK, we delete mNextTransmission as soon as we + // serialize it. + return; + } + + WarningCategory warning; + SipMessage* response = Helper::makeResponse(*mNextTransmission, 503); + warning.hostname() = mController.mHostname; + warning.code() = 399; + warning.text().reserve(100); + + if(mDnsResult) + { + InfoLog (<< "Ran out of dns entries for " << mDnsResult->target() << ". Send 503"); + assert(mDnsResult->available() == DnsResult::Finished); + oDataStream warnText(warning.text()); + warnText << "No other DNS entries to try (" + << mFailureReason << "," << mFailureSubCode << ")"; + } + else + { + oDataStream warnText(warning.text()); + warnText << "Transport failure (" + << mFailureReason << "," << mFailureSubCode << ")"; + } + + switch(mFailureReason) + { + case TransportFailure::None: + response->header(h_StatusLine).reason() = "No DNS results"; + break; + + case TransportFailure::Failure: + case TransportFailure::TransportNoSocket: + case TransportFailure::TransportBadConnect: + case TransportFailure::ConnectionUnknown: + case TransportFailure::ConnectionException: + response->header(h_StatusLine).reason() = "Transport failure: no transports left to try"; + break; + case TransportFailure::NoTransport: + response->header(h_StatusLine).reason() = "No matching transport found"; + break; + case TransportFailure::NoRoute: + response->header(h_StatusLine).reason() = "No route to host"; + break; + case TransportFailure::CertNameMismatch: + response->header(h_StatusLine).reason() = "Certificate Name Mismatch"; + break; + case TransportFailure::CertValidationFailure: + response->header(h_StatusLine).reason() = "Certificate Validation Failure"; + break; + case TransportFailure::TransportNoExistConn: + if(InteropHelper::getOutboundVersion() >= 5) + { + response->header(h_StatusLine).statusCode() = 430; + } + else + { + response->header(h_StatusLine).statusCode() = 410; + } + response->header(h_StatusLine).reason() = "Flow failed"; + warning.text() = "Flow no longer exists"; + break; + case TransportFailure::TransportShutdown: + response->header(h_StatusLine).reason() = "Transport shutdown: no transports left to try"; + break; + } + + response->header(h_Warnings).push_back(warning); + + sendToTU(response); + terminateClientTransaction(mId); + if (mMachine != Stateless) + { + delete this; + } +} + +void +TransactionState::processTransportFailure(TransactionMessage* msg) +{ + TransportFailure* failure = dynamic_cast<TransportFailure*>(msg); + assert(failure); + assert(mState!=Bogus); + + // Store failure reasons + if (failure->getFailureReason() > mFailureReason) + { + mFailureReason = failure->getFailureReason(); + mFailureSubCode = failure->getFailureSubCode(); + } + + if (mNextTransmission && // Note: If we just transmitted an ACK then mNextTransmission is cleared, so this check is necessary + mNextTransmission->isRequest() && + mNextTransmission->method() == CANCEL && + mState != Completed && + mState != Terminated) + { + WarningLog (<< "Failed to deliver a CANCEL request"); + StackLog (<< *this); + assert(mMethod==CANCEL); + + // In the case of a client-initiated CANCEL, we don't want to + // try other transports in the case of transport error as the + // CANCEL MUST be sent to the same IP/PORT as the orig. INVITE. + //?dcm? insepct failure enum? + SipMessage* response = Helper::makeResponse(*mNextTransmission, 503); + WarningCategory warning; + warning.hostname() = mController.mHostname; + warning.code() = 399; + warning.text() = "Failed to deliver CANCEL using the same transport as the INVITE was used"; + response->header(h_Warnings).push_back(warning); + + sendToTU(response); + return; + } + + if(!mDnsResult) + { + InfoLog(<< "Transport failure on send that did not use DNS."); + processNoDnsResults(); + } + // else If we did DNS resolution, then check if we should try to failover to another DNS entry + else if(mDnsResult) + { + // .bwc. Greylist for 32s + // !bwc! TODO make this duration configurable. + mDnsResult->greylistLast(Timer::getTimeMs()+32000); + + // .bwc. We should only try multiple dns results if we are originating a + // request. Additionally, there are (potential) cases where it would not + // be appropriate to fail over even then. + bool shouldFailover=false; + if(mMachine==ClientNonInvite) + { + if(mState==Completed || mState==Terminated) + { + WarningLog(<<"Got a TransportFailure message in a " << mState << + " ClientNonInvite transaction. How did this happen? Since we have" + " already completed the transaction, we shouldn't try" + " additional DNS results."); + } + else + { + shouldFailover=true; + } + } + else if(mMachine==ClientInvite) + { + if(mState==Completed || mState==Terminated) + { + // .bwc. Perhaps the attempted transmission of the ACK failed here. + // (assuming this transaction got a failure response; not sure what + // might have happened if this is not the case) + // In any case, we should not try sending the INVITE anywhere else. + InfoLog(<<"Got a TransportFailure message in a " << mState << + " ClientInvite transaction. Since we have" + " already completed the transaction, we shouldn't try" + " additional DNS results."); + } + else + { + if(mState==Proceeding) + { + // .bwc. We need to revert our state back to Calling, since we are + // going to be sending the INVITE to a new endpoint entirely. + + // !bwc! + // An interesting consequence occurs if our failover ultimately + // sends to the same instance of a resip stack; we increment the + // transport sequence in our branch parameter, but any resip-based + // stack will ignore this change, and process this "new" request as + // a retransmission! Furthermore, our state will be out of phase + // with the state at the remote endpoint, and if we have sent a + // PRACK, it will know (and stuff will break)! + // TODO What else needs to be done here to safely revert our state? + mState=Calling; + } + shouldFailover=true; + } + } + + if(shouldFailover) + { + InfoLog (<< "Try sending request to a different dns result"); + assert(mMethod!=CANCEL); + + switch (mDnsResult->available()) + { + case DnsResult::Available: + InfoLog(<< "We have another DNS result to try."); + restoreOriginalContactAndVia(); + mTarget = mDnsResult->next(); + mMsgToRetransmit.clear(); + processReliability(mTarget.getType()); + sendCurrentToWire(); + break; + + case DnsResult::Pending: + InfoLog(<< "We have a DNS query pending."); + mWaitingForDnsResult=true; + restoreOriginalContactAndVia(); + mMsgToRetransmit.clear(); + break; + + case DnsResult::Finished: + InfoLog(<< "No DNS results remain."); + processNoDnsResults(); + break; + + case DnsResult::Destroyed: + default: + InfoLog (<< "Bad state: " << *this); + assert(0); + } + } + else + { + InfoLog(<< "Transport failure on send, and failover is disabled."); + processNoDnsResults(); + } + } +} + +// called by DnsResult +void +TransactionState::rewriteRequest(const Uri& rewrite) +{ + // !bwc! TODO We need to address the race-conditions caused by callbacks + // into a class whose thread-safety is accomplished through message-passing. + // This function could very easily be called while other processing is + // taking place due to a message from the state-machine fifo. In the end, I + // imagine that we will need to have the callback place a message onto the + // queue, and move all the code below into a function that handles that + // message. + + assert(mNextTransmission->isRequest()); + if (mNextTransmission->const_header(h_RequestLine).uri() != rewrite) + { + InfoLog (<< "Rewriting request-uri to " << rewrite); + mNextTransmission->header(h_RequestLine).uri() = rewrite; + // !bwc! Changing mNextTransmission invalidates mMsgToRetransmit. + mMsgToRetransmit.clear(); + } +} + +void +TransactionState::handle(DnsResult* result) +{ + // ?bwc? Maybe optmize this to use handleSync() directly when running in + // single-threaded mode? + DnsResultMessage* dns = new DnsResultMessage(mId,isClient()); + mController.mStateMacFifo.add(static_cast<TransactionMessage*>(dns)); +} + +void +TransactionState::handleSync(DnsResult* result) +{ + StackLog (<< *this << " got DNS result: " << *result); + + // .bwc. Were we expecting something from mDnsResult? + if (mWaitingForDnsResult) + { + assert(mDnsResult); + switch (mDnsResult->available()) + { + case DnsResult::Available: + mWaitingForDnsResult=false; + mTarget = mDnsResult->next(); + assert( mTarget.transport==0 ); + // below allows TU to which transport we send on + // (The Via mechanism for setting transport doesn't work for TLS) + mTarget.transport = mNextTransmission->getDestination().transport; + processReliability(mTarget.getType()); + sendCurrentToWire(); + break; + + case DnsResult::Finished: + mWaitingForDnsResult=false; + processNoDnsResults(); + break; + + case DnsResult::Pending: + break; + + case DnsResult::Destroyed: + default: + assert(0); + break; + } + } +} + +void +TransactionState::processReliability(TransportType type) +{ + switch (type) + { + case UDP: + case DCCP: + if (mIsReliable) + { + mIsReliable = false; + StackLog (<< "Unreliable transport: " << *this); + switch (mMachine) + { + case ClientNonInvite: + mController.mTimers.add(Timer::TimerE1, mId, Timer::T1 ); + break; + + case ClientInvite: + mController.mTimers.add(Timer::TimerA, mId, Timer::T1 ); + break; + + default: + break; + } + } + break; + + default: + if (!mIsReliable) + { + mIsReliable = true; + } + break; + } +} + +// !ah! only used one place, so leaving it here instead of making a helper. +// !ah! broken out for clarity -- only used for forceTargets. +// Expects that host portion is IP address notation. + +static const Tuple +simpleTupleForUri(const Uri& uri) +{ + const Data& host = uri.host(); + int port = uri.port(); + + resip::TransportType transport = UNKNOWN_TRANSPORT; + + if (uri.exists(p_transport)) + { + transport = Tuple::toTransport(uri.param(p_transport)); + } + + if (transport == UNKNOWN_TRANSPORT) + { + transport = UDP; + } + if (port == 0) + { + switch(transport) + { + case TLS: + port = Symbols::DefaultSipsPort; + break; + case UDP: + case TCP: + default: + port = Symbols::DefaultSipPort; + break; + // !ah! SCTP? + + } + } + + return Tuple(host,port,transport); +} + +void +TransactionState::sendCurrentToWire() +{ + if(!mMsgToRetransmit.empty()) + { + if(mController.mStack.statisticsManagerEnabled()) + { + mController.mStatsManager.retransmitted(mCurrentMethodType, + isClient(), + mCurrentResponseCode); + } + + mController.mTransportSelector.retransmit(mMsgToRetransmit); + } + else if(mNextTransmission) // initial transmission; need to determine target + { + SipMessage* sip=mNextTransmission; + bool transmitted=false; + + if(isClient()) + { + if(mTarget.getType() != UNKNOWN_TRANSPORT) // mTarget is set, so just send. + { + transmitted=mController.mTransportSelector.transmit( + sip, + mTarget, + mIsReliable ? 0 : &mMsgToRetransmit); + } + else // mTarget isn't set... + { + if (sip->getDestination().mFlowKey) //...but sip->getDestination() will work + { + // ?bwc? Maybe we should be nice to the TU and do DNS in this case? + assert(sip->getDestination().getType() != UNKNOWN_TRANSPORT); + + // .bwc. We have the FlowKey. This completely specifies our + // Transport (and Connection, if applicable). No DNS required. + DebugLog(<< "Sending to tuple: " << sip->getDestination()); + mTarget = sip->getDestination(); + processReliability(mTarget.getType()); + transmitted=mController.mTransportSelector.transmit( + sip, + mTarget, + mIsReliable ? 0 : &mMsgToRetransmit); + } + else // ...so DNS is required... + { + if(mDnsResult == 0) // ... and we haven't started a DNS query yet. + { + StackLog (<< "sendToWire with no dns result: " << *this); + assert(sip->isRequest()); + assert(mMethod!=CANCEL); // .bwc. mTarget should be set in this case. + mDnsResult = mController.mTransportSelector.createDnsResult(this); + mWaitingForDnsResult=true; + mController.mTransportSelector.dnsResolve(mDnsResult, sip); + } + else // ... but our DNS query isn't done yet. + { + // .bwc. While the resolver was attempting to find a target, another + // request came down from the TU. This could be a bug in the TU, or + // could be a retransmission of an ACK/200. Either way, we cannot + // expect to ever be able to send this request (nowhere to store it + // temporarily). + // ?bwc? Higher log-level? + DebugLog(<< "Received a second request from the TU for a transaction" + " that already existed, before the DNS subsystem was done " + "resolving the target for the first request. Either the TU" + " has messed up, or it is retransmitting ACK/200 (the only" + " valid case for this to happen)"); + } + } + } + } + else // server transaction + { + assert(mDnsResult == 0); + assert(sip->exists(h_Vias)); + assert(!sip->const_header(h_Vias).empty()); + + // .bwc. Code that tweaks mResponseTarget based on stuff in the SipMessage. + // ?bwc? Why? + if (sip->hasForceTarget()) + { + // ?bwc? Override the target for a single response? Should we even + // allow this? What about client transactions? Should we overwrite + // mResponseTarget here? I don't think this has been thought out properly. + Tuple target = simpleTupleForUri(sip->getForceTarget()); + StackLog(<<"!ah! response with force target going to : "<<target); + transmitted=mController.mTransportSelector.transmit( + sip, + mTarget, + mIsReliable ? 0 : &mMsgToRetransmit); + } + else + { + if (sip->const_header(h_Vias).front().exists(p_rport) && sip->const_header(h_Vias).front().param(p_rport).hasValue()) + { + // ?bwc? This was not setting the port in mResponseTarget before. Why would + // the rport be different than the port in mResponseTarget? Didn't we + // already set this? Maybe the TU messed with it? If so, why should we pay + // attention to it? Again, this hasn't been thought out. + mResponseTarget.setPort(sip->const_header(h_Vias).front().param(p_rport).port()); + StackLog(<< "rport present in response: " << mResponseTarget.getPort()); + } + + StackLog(<< "tid=" << sip->getTransactionId() << " sending to : " << mResponseTarget); + transmitted=mController.mTransportSelector.transmit( + sip, + mResponseTarget, + mIsReliable ? 0 : &mMsgToRetransmit); + } + } + + // !bwc! If we don't have DNS results yet, or TransportSelector::transmit + // fails, we hang on to the full original SipMessage, in the hope that + // next time it works. + if (transmitted) + { + if(mController.mStack.statisticsManagerEnabled()) + { + mController.mStatsManager.sent(sip); + } + + mCurrentMethodType = sip->method(); + if(sip->isResponse()) + { + mCurrentResponseCode = sip->const_header(h_StatusLine).statusCode(); + } + + // !bwc! If mNextTransmission is a non-ACK request, we need to save the + // initial request in case we need to send a simulated 408 or a 503 to + // the TU (at least, until we get a response back) + if(!mNextTransmission->isRequest() || mNextTransmission->method()==ACK) + { + delete mNextTransmission; + mNextTransmission=0; + } + } + } + else + { + assert(0); + } +} + +void +TransactionState::sendToTU(TransactionMessage* msg) +{ + SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg); + if (sipMsg && sipMsg->isResponse() && mDnsResult) + { + // whitelisting rules. + switch (sipMsg->const_header(h_StatusLine).statusCode()) + { + case 503: + // blacklist last target. + // .bwc. If there is no Retry-After, we do not blacklist + // (see RFC 3261 sec 21.5.4 para 1) + if(sipMsg->exists(resip::h_RetryAfter) && + sipMsg->const_header(resip::h_RetryAfter).isWellFormed()) + { + unsigned int relativeExpiry= sipMsg->const_header(resip::h_RetryAfter).value(); + + if(relativeExpiry!=0) + { + mDnsResult->blacklistLast(resip::Timer::getTimeMs()+relativeExpiry*1000); + } + } + + break; + case 408: + if(sipMsg->getReceivedTransport() == 0 && + (mState == Trying || mState==Calling)) // only greylist if internally generated and we haven't received any responses yet + { + // greylist last target. + // ?bwc? How long do we greylist this for? Probably should make + // this configurable. TODO + mDnsResult->greylistLast(resip::Timer::getTimeMs() + 32000); + } + + break; + default: + // !bwc! Debatable. + mDnsResult->whitelistLast(); + break; + } + } + + CongestionManager::RejectionBehavior behavior=CongestionManager::NORMAL; + behavior=mController.mTuSelector.getRejectionBehavior(mTransactionUser); + + if(behavior!=CongestionManager::NORMAL) + { + if(sipMsg) + { + assert(sipMsg->isExternal()); + if(sipMsg->isRequest()) + { + // .bwc. This could be an initial request, or an ACK/200. + if(sipMsg->method()==ACK) + { + // ACK/200 is a continuation of old work. We only reject if + // we're really hosed. + if(behavior==CongestionManager::REJECTING_NON_ESSENTIAL) + { + delete msg; + return; + } + } + else + { + // .bwc. This is new work. Reject. + SipMessage* response(Helper::makeResponse(*sipMsg, 503)); + delete sipMsg; + + UInt16 retryAfter=mController.mTuSelector.getExpectedWait(mTransactionUser); + response->header(h_RetryAfter).value()=retryAfter; + response->setFromTU(); + if(mMethod==INVITE) + { + processServerInvite(response); + } + else + { + processServerNonInvite(response); + } + return; + } + } + else + { + // .bwc. This could be a response from the wire, or an internally + // generated pseudo-response. This is always a continuation of + // old work. + if(behavior==CongestionManager::REJECTING_NON_ESSENTIAL && + mTransactionUser && + !mTransactionUser->responsesMandatory()) + { + delete sipMsg; + return; + } + } + } + else + { + // .bwc. This is some sort of timer, or other message. If we don't know + // any better, we need to assume this is essential for the safe + // operation of the TU. + } + } + + TransactionState::sendToTU(mTransactionUser, mController, msg); +} + +void +TransactionState::sendToTU(TransactionUser* tu, TransactionController& controller, TransactionMessage* msg) +{ + msg->setTransactionUser(tu); + controller.mTuSelector.add(msg, TimeLimitFifo<Message>::InternalElement); +} + +SipMessage* +TransactionState::make100(SipMessage* request) const +{ + return (Helper::makeResponse(*request, 100)); +} + +void +TransactionState::add(const Data& tid) +{ + if (isClient()) + { + mController.mClientTransactionMap.add(tid, this); + } + else + { + mController.mServerTransactionMap.add(tid, this); + } +} + +void +TransactionState::erase(const Data& tid) +{ + if (isClient()) + { + mController.mClientTransactionMap.erase(tid); + } + else + { + mController.mServerTransactionMap.erase(tid); + } +} + +bool +TransactionState::isRequest(TransactionMessage* msg) const +{ + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + return sip && sip->isRequest(); +} + +bool +TransactionState::isInvite(TransactionMessage* msg) const +{ + if (isRequest(msg)) + { + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + return (sip->method()) == INVITE; + } + return false; +} + +bool +TransactionState::isResponse(TransactionMessage* msg, int lower, int upper) const +{ + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + if (sip && sip->isResponse()) + { + int c = sip->const_header(h_StatusLine).responseCode(); + return (c >= lower && c <= upper); + } + return false; +} + +bool +TransactionState::isTimer(TransactionMessage* msg) const +{ + return dynamic_cast<TimerMessage*>(msg) != 0; +} + +bool +TransactionState::isFromTU(TransactionMessage* msg) const +{ + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + return sip && !sip->isExternal(); +} + +bool +TransactionState::isFromWire(TransactionMessage* msg) const +{ + SipMessage* sip = dynamic_cast<SipMessage*>(msg); + return sip && sip->isExternal(); +} + +bool +TransactionState::isTransportError(TransactionMessage* msg) const +{ + return dynamic_cast<TransportFailure*>(msg) != 0; +} + +bool +TransactionState::isAbandonServerTransaction(TransactionMessage* msg) const +{ + return dynamic_cast<AbandonServerTransaction*>(msg) != 0; +} + +bool +TransactionState::isCancelClientTransaction(TransactionMessage* msg) const +{ + return dynamic_cast<CancelClientInviteTransaction*>(msg) != 0; +} + + +const Data& +TransactionState::tid(SipMessage* sip) const +{ + assert(0); + assert (mMachine != Stateless || (mMachine == Stateless && !mId.empty())); + assert (mMachine == Stateless || (mMachine != Stateless && sip)); + return (mId.empty() && sip) ? sip->getTransactionId() : mId; +} + +void +TransactionState::terminateClientTransaction(const Data& tid) +{ + mState = Terminated; + if (mController.mTuSelector.isTransactionUserStillRegistered(mTransactionUser) && + mTransactionUser->isRegisteredForTransactionTermination()) + { + //StackLog (<< "Terminate client transaction " << tid); + sendToTU(new TransactionTerminated(tid, true, mTransactionUser)); + } +} + +void +TransactionState::terminateServerTransaction(const Data& tid) +{ + mState = Terminated; + if (mController.mTuSelector.isTransactionUserStillRegistered(mTransactionUser) && + mTransactionUser->isRegisteredForTransactionTermination()) + { + //StackLog (<< "Terminate server transaction " << tid); + sendToTU(new TransactionTerminated(tid, false, mTransactionUser)); + } +} + +bool +TransactionState::isClient() const +{ + switch(mMachine) + { + case ClientNonInvite: + case ClientInvite: + case ClientStale: + case Stateless: + return true; + case ServerNonInvite: + case ServerInvite: + case ServerStale: + return false; + default: + assert(0); + } + return false; +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const resip::TransactionState& state) +{ + strm << "tid=" << state.mId << " [ "; + switch (state.mMachine) + { + case TransactionState::ClientNonInvite: + strm << "ClientNonInvite"; + break; + case TransactionState::ClientInvite: + strm << "ClientInvite"; + break; + case TransactionState::ServerNonInvite: + strm << "ServerNonInvite"; + break; + case TransactionState::ServerInvite: + strm << "ServerInvite"; + break; + case TransactionState::Stateless: + strm << "Stateless"; + break; + case TransactionState::ClientStale: + strm << "ClientStale"; + break; + case TransactionState::ServerStale: + strm << "ServerStale"; + break; + } + + strm << "/"; + switch (state.mState) + { + case TransactionState::Calling: + strm << "Calling"; + break; + case TransactionState::Trying: + strm << "Trying"; + break; + case TransactionState::Proceeding: + strm << "Proceeding"; + break; + case TransactionState::Completed: + strm << "Completed"; + break; + case TransactionState::Confirmed: + strm << "Confirmed"; + break; + case TransactionState::Terminated: + strm << "Terminated"; + break; + case TransactionState::Bogus: + strm << "Bogus"; + break; + } + + strm << (state.mIsReliable ? " reliable" : " unreliable"); + strm << " target=" << state.mResponseTarget; + //if (state.mTransactionUser) strm << " tu=" << *state.mTransactionUser; + //else strm << "default TU"; + strm << "]"; + return strm; +} + + +/* Local Variables: */ +/* c-file-style: "ellemtel" */ +/* End: */ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionState.hxx b/src/libs/resiprocate/resip/stack/TransactionState.hxx new file mode 100644 index 00000000..835ccbd0 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionState.hxx @@ -0,0 +1,241 @@ +#if !defined(RESIP_TRANSACTIONSTATE_HXX) +#define RESIP_TRANSACTIONSTATE_HXX + +#include <iosfwd> +#include <memory> +#include "rutil/dns/DnsHandler.hxx" +#include "resip/stack/MethodTypes.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Transport.hxx" +#include "rutil/HeapInstanceCounter.hxx" + +namespace resip +{ + +class DnsResult; +class TransactionMessage; +class TimerMessage; +class SendData; +class TransactionMap; +class TransactionController; +class TransactionUser; +class NameAddr; +class Via; +class MessageDecorator; + +/** + @internal +*/ +class TransactionState : public DnsHandler +{ + public: + RESIP_HeapCount(TransactionState); + static void process(TransactionController& controller, + TransactionMessage* message); + static void processTimer(TransactionController& controller, + TimerMessage* timer); + ~TransactionState(); + + private: + typedef enum + { + ClientNonInvite, + ClientInvite, + ServerNonInvite, + ServerInvite, + ClientStale, + ServerStale, + Stateless // may not be needed + } Machine; + + typedef enum + { + Calling, + Trying, + Proceeding, + Completed, + Confirmed, + Terminated, + Bogus + } State; + + TransactionState(TransactionController& controller, + Machine m, + State s, + const Data& tid, + MethodTypes method, + const Data& methodText, + TransactionUser* tu=0); + + void rewriteRequest(const Uri& rewrite); + void handle(DnsResult*); + void handleSync(DnsResult*); + + void processStateless(TransactionMessage* msg); + void processClientNonInvite(TransactionMessage* msg); + void processClientInvite(TransactionMessage* msg); + void processServerNonInvite(TransactionMessage* msg); + void processServerInvite(TransactionMessage* msg); + void processClientStale(TransactionMessage* msg); + void processServerStale(TransactionMessage* msg); + void processTransportFailure(TransactionMessage* failure); + void processNoDnsResults(); + void processReliability(TransportType type); + + void add(const Data& tid); + void erase(const Data& tid); + + bool isClient() const; + private: + bool isRequest(TransactionMessage* msg) const; + bool isInvite(TransactionMessage* msg) const; + bool isTimer(TransactionMessage* msg) const; + bool isResponse(TransactionMessage* msg, int lower=100, int upper=699) const; + bool isFromTU(TransactionMessage* msg) const; + bool isFromWire(TransactionMessage* msg) const; + bool isTransportError(TransactionMessage* msg) const; + bool isSentReliable(TransactionMessage* msg) const; + bool isSentUnreliable(TransactionMessage* msg) const; + bool isReliabilityIndication(TransactionMessage* msg) const; + bool isSentIndication(TransactionMessage* msg) const; + bool isAbandonServerTransaction(TransactionMessage* msg) const; + bool isCancelClientTransaction(TransactionMessage* msg) const; + void sendToTU(TransactionMessage* msg); + static void sendToTU(TransactionUser* tu, TransactionController& controller, TransactionMessage* msg); + void sendCurrentToWire(); + SipMessage* make100(SipMessage* request) const; + void terminateClientTransaction(const Data& tid); + void terminateServerTransaction(const Data& tid); + const Data& tid(SipMessage* sip) const; + + void startServerNonInviteTimerTrying(SipMessage& sip, const Data& tid); + + static TransactionState* makeCancelTransaction(TransactionState* tran, Machine machine, const Data& tid); + static void handleInternalCancel(SipMessage* cancel, + TransactionState& clientInvite); + /** + Attempts to responds to a malformed non-ACK request. + @param badReq MUST be a non-ACK request. This function will assert + if otherwise. + @return true iff a response was successfully sent. + **/ + static bool handleBadRequest(const resip::SipMessage& badReq,TransactionController& controller); + + void saveOriginalContactAndVia(const SipMessage& msg); + void restoreOriginalContactAndVia(); + void resetNextTransmission(SipMessage* msg) + { + delete mNextTransmission; + mNextTransmission=msg; + mMsgToRetransmit.clear(); + } + + static bool processSipMessageAsNew(resip::SipMessage* sip, + resip::TransactionController& controller, + const resip::Data& tid); + + TransactionController& mController; + + Machine mMachine; + State mState; + bool mIsAbandoned; // TU doesn't care about this transaction anymore. + + // Indicates that the message has been sent with a reliable protocol. Set + // by the TransportSelector + bool mIsReliable; + + // !bwc! sendCurrentToWire() uses these to determine what it should put on + // the wire. If mMsgToRetransmit is non-empty, it goes on the wire + // _regardless_ of what mNextTransmission is. If mMsgToRetransmit is + // empty, but mNextTransmission is non-null, sendCurrentToWire() will try + // to send it. + SipMessage* mNextTransmission; + SendData mMsgToRetransmit; + + // Handle to the dns results queried by the TransportSelector + DnsResult* mDnsResult; + + // current selection from the DnsResult. e.g. it is important to send the + // CANCEL to exactly the same tuple as the original INVITE went to. + Tuple mTarget; + Tuple mResponseTarget; // used to reply to requests + + // used when the DnsResult moves to another transport on failure. Only + // used for outgoing stateful, so auto_ptr for space efficiency. + std::auto_ptr<NameAddr> mOriginalContact; + std::auto_ptr<Via> mOriginalVia; + + const Data mId; + const MethodTypes mMethod; + Data* mMethodText; + + // These two apply to the message we're currently retransmitting. + MethodTypes mCurrentMethodType; + unsigned int mCurrentResponseCode; + + bool mAckIsValid; + bool mWaitingForDnsResult; + TransactionUser* mTransactionUser; + TransportFailure::FailureReason mFailureReason; + int mFailureSubCode; + + static unsigned long StatelessIdCounter; + + friend EncodeStream& operator<<(EncodeStream& strm, const TransactionState& state); + friend class TransactionController; +}; + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionTerminated.hxx b/src/libs/resiprocate/resip/stack/TransactionTerminated.hxx new file mode 100644 index 00000000..f3a48bfc --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionTerminated.hxx @@ -0,0 +1,83 @@ +#if !defined(RESIP_TRANSACTIONTERMINATED_HXX) +#define RESIP_TRANSACTIONTERMINATED_HXX + +#include "TransactionMessage.hxx" +#include "rutil/HeapInstanceCounter.hxx" + +namespace resip +{ +class TransactionUser; + +class TransactionTerminated : public TransactionMessage +{ + public: + RESIP_HeapCount(TransactionTerminated); + + TransactionTerminated(const Data& tid, bool isClient, TransactionUser* ptu) : + mTransactionId(tid), + mIsClient(isClient) + { + setTransactionUser(ptu); + } + virtual const Data& getTransactionId() const { return mTransactionId; } + virtual bool isClientTransaction() const { return mIsClient; } + virtual EncodeStream& encode(EncodeStream& strm) const { return encodeBrief(strm); } + virtual EncodeStream& encodeBrief(EncodeStream& str) const + { + return str << (mIsClient ? "ClientTransactionTerminated " : "ServerTransactionTerminated ") << mTransactionId; + } + + Data mTransactionId; + bool mIsClient; +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionUser.cxx b/src/libs/resiprocate/resip/stack/TransactionUser.cxx new file mode 100644 index 00000000..ce30b49b --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionUser.cxx @@ -0,0 +1,199 @@ +#include "resip/stack/TransactionUser.hxx" +#include "resip/stack/MessageFilterRule.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TRANSACTION + +using namespace resip; + +TransactionUser::TransactionUser(TransactionTermination t, + ConnectionTermination c, + KeepAlivePongs k) : + mFifo(0, 0), + mCongestionManager(0), + mRuleList(), + mDomainList(), + mRegisteredForTransactionTermination(t == RegisterForTransactionTermination), + mRegisteredForConnectionTermination(c == RegisterForConnectionTermination), + mRegisteredForKeepAlivePongs(k == RegisterForKeepAlivePongs) +{ + // This creates a default message filter rule, which + // handles all sip:, sips:, and tel: requests. + mRuleList.push_back(MessageFilterRule()); + + // Set a default Fifo description - should be modified by override class to be + // more desriptive + mFifo.setDescription("TransactionUser::mFifo"); +} + +TransactionUser::TransactionUser(MessageFilterRuleList &mfrl, + TransactionTermination t, + ConnectionTermination c, + KeepAlivePongs k) : + mFifo(0, 0), + mCongestionManager(0), + mRuleList(mfrl), + mDomainList(), + mRegisteredForTransactionTermination(t == RegisterForTransactionTermination), + mRegisteredForConnectionTermination(c == RegisterForConnectionTermination), + mRegisteredForKeepAlivePongs(k == RegisterForKeepAlivePongs) +{ + // Set a default Fifo description - should be modified by override class to be + // more desriptive + mFifo.setDescription("TransactionUser::mFifo"); +} + +TransactionUser::~TransactionUser() +{ +} + +void +TransactionUser::post(Message* msg) +{ + mFifo.add(msg, TimeLimitFifo<Message>::InternalElement); +} + +void +TransactionUser::postToTransactionUser(Message* msg, TimeLimitFifo<Message>::DepthUsage usage) +{ + mFifo.add(msg, usage); + //DebugLog (<< "TransactionUser::postToTransactionUser " << msg->brief() << " &=" << &mFifo << " size=" << mFifo.size()); +} + +unsigned int +TransactionUser::size() const +{ + return mFifo.size(); +} + +bool +TransactionUser::wouldAccept(TimeLimitFifo<Message>::DepthUsage usage) const +{ + return mFifo.wouldAccept(usage); +} + +bool +TransactionUser::isForMe(const SipMessage& msg) const +{ + DebugLog (<< "Checking if " << msg.brief() << " is for me"); + // do this for each MessageFilterRule + for (MessageFilterRuleList::const_iterator i = mRuleList.begin() ; + i != mRuleList.end() ; ++i) + { + DebugLog (<< "Checking rule..."); + if (i->matches(msg)) + { + DebugLog (<< "Match!"); + return true; + } + } + DebugLog (<< "No matching rule found"); + return false; +} + +bool +TransactionUser::isMyDomain(const Data& domain) const +{ + // Domain search should be case insensitive - search in lowercase only + return mDomainList.count(Data(domain).lowercase()) > 0; +} + +void TransactionUser::addDomain(const Data& domain) +{ + // Domain search should be case insensitive - store in lowercase only + mDomainList.insert(Data(domain).lowercase()); +} + +EncodeStream& +TransactionUser::encode(EncodeStream& strm) const +{ + strm << "TU: " << name() << " size=" << mFifo.size(); + return strm; +} + +void +TransactionUser::setMessageFilterRuleList(MessageFilterRuleList &rules) +{ + mRuleList = rules; + MessageFilterRuleList::iterator it = mRuleList.begin(); + for(;it!=mRuleList.end();it++) + { + it->setTransactionUser(this); + } +} + +bool +TransactionUser::isRegisteredForTransactionTermination() const +{ + return mRegisteredForTransactionTermination; +} + +bool +TransactionUser::isRegisteredForConnectionTermination() const +{ + return mRegisteredForConnectionTermination; +} + +bool +TransactionUser::isRegisteredForKeepAlivePongs() const +{ + return mRegisteredForKeepAlivePongs; +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const resip::TransactionUser& tu) +{ + tu.encode(strm); + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionUser.hxx b/src/libs/resiprocate/resip/stack/TransactionUser.hxx new file mode 100644 index 00000000..e40a2bf7 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionUser.hxx @@ -0,0 +1,294 @@ +#if !defined(RESIP_TU_HXX) +#define RESIP_TU_HXX + +#include <iosfwd> +#include <set> +#include "rutil/TimeLimitFifo.hxx" +#include "rutil/Data.hxx" +#include "rutil/CongestionManager.hxx" +#include "resip/stack/Message.hxx" +#include "resip/stack/MessageFilterRule.hxx" + + +namespace resip +{ +class SipMessage; + +/** + @brief The base-class for an RFC 3261 Transaction User. This is the + "app-layer". + + Subclasses of TransactionUser are expected to do the following things: + - Register itself by using SipStack::registerTransactionUser(). + - Regularly pull messages out of mFifo, and process them. + - Particularly, every received SIP request MUST be responded to, or + the stack will leak transactions. + - Before the TransactionUser is destroyed, it should ensure that it has + been unregistered from the stack using + SipStack::unregisterTransactionUser(), and gotten a confirmation in + the form of a TransactionUserMessage. + + There is also a collection of things you can do to customize how the stack + interacts with your TransactionUser: + - If you wish to restrict the types of SIP traffic your TransactionUser + will receive from the stack, you can do so by setting the + MessageFilterRuleList, either in the constructor, or with + setMessageFilterRuleList() (see MessageFilterRule for more) + - If you need more fine-grained control over what SIP messages your + TransactionUser is willing/able to handle, you can override + TransactionUser::isForMe(). + - If you wish your TransactionUser to be notified whenever a + transaction ends, just pass RegisterForTransactionTermination in the + constructor. + - If you wish your TransactionUser to be notified when Connections are + closed, pass RegisterForConnectionTermination in the constructor. + + @ingroup resip_crit +*/ +class TransactionUser +{ + public: + /** + @brief Posts a Message to this TransactionUser's fifo. Ownership of msg + is taken. + @param msg The Message to add to mFifo. (This takes ownership of msg) + */ + void post(Message* msg); + + /** + @brief Returns true iff domain matches one of the domains that this + TransactionUser is responsible for. (added with addDomain). + @param domain The domain name to check. + @return True iff this TransactionUser is responsible for domain. + @note The comparison performed is case-sensitive; make sure you + lower-case everything you put in here. + */ + bool isMyDomain(const Data& domain) const; + + /** + @brief Adds a domain to the set of domains that this TransactionUser is + responsible for. + @note The comparison performed is case-sensitive; make sure you + lower-case everything you put in here. + @todo Make this case-insensitive. + */ + void addDomain(const Data& domain); + + /** + @brief Return the name of this TransactionUser. Used in encode(). + @return The name of this TransactionUser, as a Data. + */ + virtual const Data& name() const=0; + + /** + @brief Encodes the name of this TransactionUser (as specified by + name()), and the current depth of its fifo. + @param strm The ostream to encode to. + @return strm + */ + virtual EncodeStream& encode(EncodeStream& strm) const; + + /** + @brief Sets this TransactionUser's MessageFilterRuleList. + + This tells the stack which SIP messages this TransactionUser is + interested in, and which ones it is not. This allows multiple + TransactionUsers to run on top of the same SipStack. + + @param rules The MessageFilterRuleList to use. + @see MessageFilterRule + */ + void setMessageFilterRuleList(MessageFilterRuleList &rules); + + /** + @internal + @brief Returns true iff this TransactionUser should be notified when + transactions end. + */ + bool isRegisteredForTransactionTermination() const; + + /** + @internal + @brief Returns true iff this TransactionUser should be notified when + connections close. + */ + bool isRegisteredForConnectionTermination() const; + bool isRegisteredForKeepAlivePongs() const; + + inline CongestionManager::RejectionBehavior getRejectionBehavior() const + { + if(mCongestionManager) + { + return mCongestionManager->getRejectionBehavior(&mFifo); + } + return CongestionManager::NORMAL; + } + + virtual void setCongestionManager(CongestionManager* manager) + { + if(mCongestionManager) + { + mCongestionManager->unregisterFifo(&mFifo); + } + mCongestionManager=manager; + if(mCongestionManager) + { + mCongestionManager->registerFifo(&mFifo); + } + } + + virtual UInt16 getExpectedWait() const + { + return (UInt16)mFifo.expectedWaitTimeMilliSec(); + } + + // .bwc. This specifies whether the TU can cope with dropped responses + // (due to congestion). Some TUs may need responses to clean up state, + // while others may rely on TransactionTerminated messages. Those that + // rely on TransactionTerminated messages will be able to return false + // here, meaning that in dire congestion situations, the stack will drop + // responses bound for the TU. + virtual bool responsesMandatory() const {return true;} + + protected: + enum TransactionTermination + { + RegisterForTransactionTermination, + DoNotRegisterForTransactionTermination + }; + + enum ConnectionTermination + { + RegisterForConnectionTermination, + DoNotRegisterForConnectionTermination + }; + + enum KeepAlivePongs + { + RegisterForKeepAlivePongs, + DoNotRegisterForKeepAlivePongs + }; + + /** + @brief Constructor that specifies whether this TransactionUser needs to + hear about the completion of transactions, and the closing of + connections. + @param t Whether or not the TransactionUser should be informed when + transactions end (disabled by default). + @param c Whether or not the TransactionUser should be informed when + connections close (disabled by default). + @note The default MessageFilterRuleList used will accept all SIP + requests with either sip: or sips: in the Request-Uri. + @note This is protected to ensure than no-one constructs the + base-class. (Subclasses call this in their constructor) + */ + TransactionUser(TransactionTermination t=DoNotRegisterForTransactionTermination, + ConnectionTermination c=DoNotRegisterForConnectionTermination, + KeepAlivePongs k=DoNotRegisterForKeepAlivePongs); + + /** + @brief Constructor that specifies the MessageFilterRuleList, whether + this TransactionUser needs to hear about the completion of + transactions, and the closing of connections. + @param rules The MessageFilterRuleList to use. (A copy is made) + @param t Whether or not the TransactionUser should be informed when + transactions end (disabled by default). + @param c Whether or not the TransactionUser should be informed when + connections close (disabled by default). + @note This is protected to ensure than no-one constructs the + base-class. (Subclasses call this in their constructor) + */ + TransactionUser(MessageFilterRuleList &rules, + TransactionTermination t=DoNotRegisterForTransactionTermination, + ConnectionTermination c=DoNotRegisterForConnectionTermination, + KeepAlivePongs k=DoNotRegisterForKeepAlivePongs); + + virtual ~TransactionUser()=0; + + /** + @brief Returns true iff this TransactionUser should process msg. + @param msg The SipMessage we received. + @return True iff this TransactionUser should process msg. + @note By default, this uses the MessageFilterRuleList. It can be + overridden for more flexibility. + */ + virtual bool isForMe(const SipMessage& msg) const; + + /** + @brief This TransactionUser's fifo. All communication with the + TransactionUser goes through here. + */ + TimeLimitFifo<Message> mFifo; + CongestionManager* mCongestionManager; + + private: + void postToTransactionUser(Message* msg, TimeLimitFifo<Message>::DepthUsage usage); + unsigned int size() const; + bool wouldAccept(TimeLimitFifo<Message>::DepthUsage usage) const; + + private: + MessageFilterRuleList mRuleList; + typedef std::set<Data> DomainList; + DomainList mDomainList; + bool mRegisteredForTransactionTermination; + bool mRegisteredForConnectionTermination; + bool mRegisteredForKeepAlivePongs; + friend class TuSelector; +}; + +EncodeStream& +operator<<(EncodeStream& strm, const TransactionUser& tu); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionUserMessage.cxx b/src/libs/resiprocate/resip/stack/TransactionUserMessage.cxx new file mode 100644 index 00000000..9823900e --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionUserMessage.cxx @@ -0,0 +1,85 @@ +#include "resip/stack/TransactionUserMessage.hxx" + +using namespace resip; + +TransactionUserMessage::TransactionUserMessage(Type type, TransactionUser* ptu) : + mType(type) +{ + mTu = ptu; + assert(mTu); +} + +EncodeStream& +TransactionUserMessage::encode(EncodeStream& strm) const +{ + return strm << brief(); +} + +EncodeStream& +TransactionUserMessage::encodeBrief(EncodeStream& str) const +{ + return str << "TransactionUserMessage"; +} + +const Data& +TransactionUserMessage::getTransactionId() const +{ + assert(0); + return Data::Empty; +} + +bool +TransactionUserMessage::isClientTransaction() const +{ + assert(0); + return false; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionUserMessage.hxx b/src/libs/resiprocate/resip/stack/TransactionUserMessage.hxx new file mode 100644 index 00000000..40af748b --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransactionUserMessage.hxx @@ -0,0 +1,84 @@ +#ifndef RESIP_TransactionUserMessage_hxx +#define RESIP_TransactionUserMessage_hxx + +#include "resip/stack/TransactionMessage.hxx" + +namespace resip +{ + +class TransactionUserMessage : public TransactionMessage +{ + public: + typedef enum + { + RequestShutdown, + RemoveTransactionUser, + TransactionUserRemoved + } Type; + + TransactionUserMessage(Type type, TransactionUser* tu); + Type type() const { return mType; } + + virtual const Data& getTransactionId() const; + virtual bool isClientTransaction() const; + + virtual Message* clone() const { return new TransactionUserMessage(mType, mTu); } + virtual EncodeStream& encode(EncodeStream& strm) const; + virtual EncodeStream& encodeBrief(EncodeStream& str) const; + + private: + Type mType; +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Transport.cxx b/src/libs/resiprocate/resip/stack/Transport.cxx new file mode 100644 index 00000000..4a537726 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Transport.cxx @@ -0,0 +1,524 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <iostream> + +#if defined(HAVE_SYS_SOCKIO_H) +#include <sys/sockio.h> +#endif + +#include "rutil/Socket.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" + +#include "resip/stack/ConnectionTerminated.hxx" +#include "resip/stack/KeepAlivePong.hxx" +#include "resip/stack/Transport.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/TransportFailure.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/SendData.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +Transport::Exception::Exception(const Data& msg, const Data& file, const int line) : + BaseException(msg,file,line) +{ +} + +Transport::Transport(Fifo<TransactionMessage>& rxFifo, + const GenericIPAddress& address, + const Data& tlsDomain, + AfterSocketCreationFuncPtr socketFunc, + Compression &compression) : + mTuple(address), + mHasRecordRoute(false), + mKey(0), + mCongestionManager(0), + mStateMachineFifo(rxFifo, 8), + mShuttingDown(false), + mTlsDomain(tlsDomain), + mSocketFunc(socketFunc), + mCompression(compression), + mTransportFlags(0) +{ + mInterface = Tuple::inet_ntop(mTuple); + mConnectionsDeleted = 0; +} + +Transport::Transport(Fifo<TransactionMessage>& rxFifo, + int portNum, + IpVersion version, + const Data& intfc, + const Data& tlsDomain, + AfterSocketCreationFuncPtr socketFunc, + Compression &compression, + unsigned transportFlags) : + mInterface(intfc), + mTuple(intfc, portNum, version), + mHasRecordRoute(false), + mKey(0), + mCongestionManager(0), + mStateMachineFifo(rxFifo,8), + mShuttingDown(false), + mTlsDomain(tlsDomain), + mSocketFunc(socketFunc), + mCompression(compression), + mTransportFlags(transportFlags) +{ + mConnectionsDeleted = 0; +} + +Transport::~Transport() +{ +} + +void +Transport::error(int e) +{ + switch (e) + { + case EAGAIN: + //InfoLog (<< "No data ready to read" << strerror(e)); + break; + case EINTR: + InfoLog (<< "The call was interrupted by a signal before any data was read : " << strerror(e)); + break; + case EIO: + InfoLog (<< "I/O error : " << strerror(e)); + break; + case EBADF: + InfoLog (<< "fd is not a valid file descriptor or is not open for reading : " << strerror(e)); + break; + case EINVAL: + InfoLog (<< "fd is attached to an object which is unsuitable for reading : " << strerror(e)); + break; + case EFAULT: + InfoLog (<< "buf is outside your accessible address space : " << strerror(e)); + break; + +#if defined(WIN32) + case WSAENETDOWN: + InfoLog (<<" The network subsystem has failed. "); + break; + case WSAEFAULT: + InfoLog (<<" The buf or from parameters are not part of the user address space, " + "or the fromlen parameter is too small to accommodate the peer address. "); + break; + case WSAEINTR: + InfoLog (<<" The (blocking) call was canceled through WSACancelBlockingCall. "); + break; + case WSAEINPROGRESS: + InfoLog (<<" A blocking Windows Sockets 1.1 call is in progress, or the " + "service provider is still processing a callback function. "); + break; + case WSAEINVAL: + InfoLog (<<" The socket has not been bound with bind, or an unknown flag was specified, " + "or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, " + "or (for byte stream-style sockets only) len was zero or negative. "); + break; + case WSAEISCONN : + InfoLog (<<"The socket is connected. This function is not permitted with a connected socket, " + "whether the socket is connection-oriented or connectionless. "); + break; + case WSAENETRESET: + InfoLog (<<" The connection has been broken due to the keep-alive activity " + "detecting a failure while the operation was in progress. "); + break; + case WSAENOTSOCK : + InfoLog (<<"The descriptor is not a socket. "); + break; + case WSAEOPNOTSUPP: + InfoLog (<<" MSG_OOB was specified, but the socket is not stream-style such as type " + "SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, " + "or the socket is unidirectional and supports only send operations. "); + break; + case WSAESHUTDOWN: + InfoLog (<<"The socket has been shut down; it is not possible to recvfrom on a socket after " + "shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH. "); + break; + case WSAEMSGSIZE: + InfoLog (<<" The message was too large to fit into the specified buffer and was truncated. "); + break; + case WSAETIMEDOUT: + InfoLog (<<" The connection has been dropped, because of a network failure or because the " + "system on the other end went down without notice. "); + break; + case WSAECONNRESET : + InfoLog (<<"Connection reset "); + break; + + case WSAEWOULDBLOCK: + DebugLog (<<"Would Block "); + break; + + case WSAEHOSTUNREACH: + InfoLog (<<"A socket operation was attempted to an unreachable host "); + break; + case WSANOTINITIALISED: + InfoLog (<<"Either the application has not called WSAStartup or WSAStartup failed. " + "The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks)," + "or WSACleanup has been called too many times. "); + break; + case WSAEACCES: + InfoLog (<<"An attempt was made to access a socket in a way forbidden by its access permissions "); + break; + case WSAENOBUFS: + InfoLog (<<"An operation on a socket could not be performed because the system lacked sufficient " + "buffer space or because a queue was full"); + break; + case WSAENOTCONN: + InfoLog (<<"A request to send or receive data was disallowed because the socket is not connected " + "and (when sending on a datagram socket using sendto) no address was supplied"); + break; + case WSAECONNABORTED: + InfoLog (<<"An established connection was aborted by the software in your host computer, possibly " + "due to a data transmission time-out or protocol error"); + break; + case WSAEADDRNOTAVAIL: + InfoLog (<<"The requested address is not valid in its context. This normally results from an attempt to " + "bind to an address that is not valid for the local computer"); + break; + case WSAEAFNOSUPPORT: + InfoLog (<<"An address incompatible with the requested protocol was used"); + break; + case WSAEDESTADDRREQ: + InfoLog (<<"A required address was omitted from an operation on a socket"); + break; + case WSAENETUNREACH: + InfoLog (<<"A socket operation was attempted to an unreachable network"); + break; + +#endif + + default: + InfoLog (<< "Some other error (" << e << "): " << strerror(e)); + break; + } +} + +void +Transport::flowTerminated(const Tuple& flow) +{ + mStateMachineFifo.add(new ConnectionTerminated(flow)); +} + +void +Transport::keepAlivePong(const Tuple& flow) +{ + mStateMachineFifo.add(new KeepAlivePong(flow)); +} + +void +Transport::fail(const Data& tid, TransportFailure::FailureReason reason, int subCode) +{ + if (!tid.empty()) + { + mStateMachineFifo.add(new TransportFailure(tid, reason, subCode)); + } +} + +std::auto_ptr<SendData> +Transport::makeSendData( const Tuple& dest, const Data& d, const Data& tid, const Data &sigcompId) +{ + assert(dest.getPort() != -1); + std::auto_ptr<SendData> data(new SendData(dest, d, tid, sigcompId)); + return data; +} + +void +Transport::makeFailedResponse(const SipMessage& msg, + int responseCode, + const char * warning) +{ + if (msg.isResponse()) return; + + const Tuple& dest = msg.getSource(); + + std::auto_ptr<SipMessage> errMsg(Helper::makeResponse(msg, + responseCode, + warning ? warning : "Original request had no Vias")); + + // make send data here w/ blank tid and blast it out. + // encode message + Data encoded; + encoded.clear(); + DataStream encodeStream(encoded); + errMsg->encode(encodeStream); + encodeStream.flush(); + assert(!encoded.empty()); + + InfoLog(<<"Sending response directly to " << dest << " : " << errMsg->brief() ); + + // Calculate compartment ID for outbound message + Data remoteSigcompId; + setRemoteSigcompId(*errMsg,remoteSigcompId); + send(std::auto_ptr<SendData>(makeSendData(dest, encoded, Data::Empty, remoteSigcompId))); +} + +std::auto_ptr<SendData> +Transport::make503(SipMessage& msg, UInt16 retryAfter) +{ + std::auto_ptr<SendData> result; + if (msg.isResponse()) return result; + + try + { + if(msg.method()==ACK) + { + return result; + } + } + catch(BaseException&) + { + // .bwc. Parse failed on the start-line. Stop. + return result; + } + + const Tuple& dest = msg.getSource(); + + // Calculate compartment ID for outbound message + Data remoteSigcompId; + setRemoteSigcompId(msg,remoteSigcompId); + + // .bwc. msg is completely unverified. Handle with caution. + result=makeSendData(dest, Data::Empty, Data::Empty, remoteSigcompId); + static const Data retryAfterHeader("Retry-After: "); + Data value(retryAfter); + Helper::makeRawResponse(result->data, msg, 503, retryAfterHeader+value+"\r\n"); + + return result; +} + +std::auto_ptr<SendData> +Transport::make100(SipMessage& msg) +{ + std::auto_ptr<SendData> result; + if (msg.isResponse()) return result; + + try + { + if(msg.method()==ACK) + { + return result; + } + } + catch(BaseException&) + { + // .bwc. Parse failed on the start-line. Stop. + return result; + } + + const Tuple& dest = msg.getSource(); + + // Calculate compartment ID for outbound message + Data remoteSigcompId; + setRemoteSigcompId(msg,remoteSigcompId); + + // .bwc. msg is completely unverified. Handle with caution. + result=makeSendData(dest, Data::Empty, Data::Empty, remoteSigcompId); + Helper::makeRawResponse(result->data, msg, 100); + + return result; +} + +void +Transport::setRemoteSigcompId(SipMessage& msg, Data& remoteSigcompId) +{ + if (mCompression.isEnabled()) + { + try + { + const Via &topVia(msg.const_header(h_Vias).front()); + + if(topVia.exists(p_comp) && topVia.param(p_comp) == "sigcomp") + { + if (topVia.exists(p_sigcompId)) + { + remoteSigcompId = topVia.param(p_sigcompId); + } + else + { + // XXX rohc-sigcomp-sip-03 says "sent-by", + // but this should probably be "received" if present, + // and "sent-by" otherwise. + // XXX Also, the spec is ambiguous about whether + // to include the port in this identifier. + remoteSigcompId = topVia.sentHost(); + } + } + } + catch(BaseException&) + { + // ?bwc? Couldn't grab sigcomp compartment id. We don't even know if + // the initial request was using sigcomp or not. + // What should we do here? + } + } +} + +void +Transport::stampReceived(SipMessage* message) +{ + // set the received= and rport= parameters in the message if necessary !jf! + if (message->isRequest() && message->exists(h_Vias) && !message->const_header(h_Vias).empty()) + { + const Tuple& tuple = message->getSource(); + Data received = Tuple::inet_ntop(tuple); + if(message->const_header(h_Vias).front().sentHost() != received) // only add if received address is different from sent-by in Via + { + message->header(h_Vias).front().param(p_received) = received; + } + //message->header(h_Vias).front().param(p_received) = Tuple::inet_ntop(tuple); + if (message->const_header(h_Vias).front().exists(p_rport)) + { + message->header(h_Vias).front().param(p_rport).port() = tuple.getPort(); + } + } + DebugLog (<< "incoming from: " << message->getSource()); + StackLog (<< endl << endl << *message); +} + + +bool +Transport::basicCheck(const SipMessage& msg) +{ + resip::Data reason; + if (msg.isExternal()) + { + try + { + if (!Helper::validateMessage(msg,&reason)) + { + InfoLog(<<"Message Failed basicCheck :" << msg.brief()); + if (msg.isRequest() && msg.method()!=ACK ) + { + // this is VERY low-level b/c we don't have a transaction... + // here we make a response to warn the offending party. + makeFailedResponse(msg,400,reason.c_str()); + } + return false; + } + else if (mShuttingDown && msg.isRequest() && msg.method() != ACK) + { + InfoLog (<< "Server has been shutdown, reject message with 503"); + // this is VERY low-level b/c we don't have a transaction... + // here we make a response to warn the offending party. + makeFailedResponse(msg, 503, "Server has been shutdown"); + return false; + } + } + catch (BaseException& e) + { + InfoLog (<< "Cannot make failure response to badly constructed message: " << e); + return false; + } + } + return true; +} + +void +Transport::callSocketFunc(Socket sock) +{ + if (mSocketFunc) + { + mSocketFunc(sock, transport(), __FILE__, __LINE__); + } +} + +void +Transport::pushRxMsgUp(TransactionMessage* msg) +{ + mStateMachineFifo.add(msg); +} + + +bool +Transport::operator==(const Transport& rhs) const +{ + return ( ( mTuple.isV4() == rhs.isV4()) && + ( port() == rhs.port()) && + ( memcmp(&boundInterface(),&rhs.boundInterface(),mTuple.length()) == 0) ); +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const resip::Transport& rhs) +{ + strm << "Transport: " << rhs.mTuple; + if (!rhs.mInterface.empty()) strm << " on " << rhs.mInterface; + return strm; +} + +int +Transport::getConnectionsDeleted() const +{ + return mConnectionsDeleted; +} + +void +Transport::resetConnectionsDeleted() +{ + mConnectionsDeleted = 0; +} + +void Transport::increaseConnectionsDeleted() +{ + mConnectionsDeleted++; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/Transport.hxx b/src/libs/resiprocate/resip/stack/Transport.hxx new file mode 100644 index 00000000..149c29e5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Transport.hxx @@ -0,0 +1,445 @@ +#if !defined(RESIP_TRANSPORT_HXX) +#define RESIP_TRANSPORT_HXX + +#include "rutil/BaseException.hxx" +#include "rutil/Data.hxx" +#include "rutil/FdSetIOObserver.hxx" +#include "rutil/ProducerFifoBuffer.hxx" +#include "resip/stack/TransportFailure.hxx" +#include "resip/stack/Tuple.hxx" +#include "resip/stack/NameAddr.hxx" +#include "resip/stack/Compression.hxx" +#include "resip/stack/SendData.hxx" + +namespace resip +{ + +class TransactionMessage; +class SipMessage; +class Connection; +class Compression; +class FdPollGrp; + +/** + * TransportFlags is bit-mask that can be set when creating a transport. + * All flags default to "off" to preserve "traditional" resip behavior. + * Not all Transports support all flags. All options are experimental. + * The flags are: + * NOBIND: + * On transports that support it (TCP/TLS), do not bind a listening + * socket; thus no in-bound connections are possible. This can conserve + * ports and avoid port conflicts in pure-outbound (NAT'd) cases. + * RXALL: + * When receiving from socket, read all possible messages before + * returning to event loop. This allows higher thruput. Without this flag, + * only one message is read at a time, which is slower over-all, but + * is more "even" and balanced. + * TXALL: + * When transmitting to a socket, write all possible messages before + * returning to event loop. This allows higher thruput but burstier. + * KEEP_BUFFER: + * With this flag, Transports will keep receive and transmit buffers + * allocated even when not in use. This increases memory utilization + * but speeds things up. Without this flag, the buffer is released + * when not in used. + * TXNOW: + * When a message to transmit is posted to Transport's transmit queue + * immediately try sending it. This should have less latency + * and less overhead with select/poll stuff, but will have deeper + * call stacks. + * OWNTHREAD: + * Specifies whether this Transport object has its own thread (ie; if + * set, the TransportSelector should not run the select/poll loop for + * this transport, since that is another thread's job) + */ +#define RESIP_TRANSPORT_FLAG_NOBIND (1<<0) +#define RESIP_TRANSPORT_FLAG_RXALL (1<<1) +#define RESIP_TRANSPORT_FLAG_TXALL (1<<2) +#define RESIP_TRANSPORT_FLAG_KEEP_BUFFER (1<<3) +#define RESIP_TRANSPORT_FLAG_TXNOW (1<<4) +#define RESIP_TRANSPORT_FLAG_OWNTHREAD (1<<5) + +/** + @brief The base class for Transport classes. + + A Transport presents layer 4 of the OSI model, the transport layer. + For IP-based protocols, this means that a Transport object has an + IP address (v4 or v6), a transport layer protocol (UDP or TCP/TLS), + and a port number. These are managed through the Transport's Tuple + member. + +*/ +class Transport : public FdSetIOObserver +{ + public: + + + /** + @brief General exception class for Transport. + + This would be thrown if there was an attempt to bind to a port + that is already in use. + */ + class Exception : public BaseException + { + public: + Exception(const Data& msg, const Data& file, const int line); + const char* name() const { return "TransportException"; } + }; + + /** + @param rxFifo the TransactionMessage Fifo that will receive + any ConnectionTerminated or TransportFailure messages. + + @param tlsDomain the domain name of the Transport + + @param socketFunc subclassers can call this function after + the socket is created. This is not currently used by + Transport. + */ + Transport(Fifo<TransactionMessage>& rxFifo, + const GenericIPAddress& address, + const Data& tlsDomain = Data::Empty, // !dcm! where is this used? + AfterSocketCreationFuncPtr socketFunc = 0, + Compression &compression = Compression::Disabled + ); + + /** + @param rxFifo the TransactionMessage Fifo that will receive + any ConnectionTerminated or TransportFailure messages. + + @param interfaceObj a "presentation format" representation + of the IP address of this transport + @see Tuple::inet_ntop() for information about "presentation + format" + + @param portNum is the port to receive and/or send on + + @param tlsDomain the domain name of the Transport + + @todo Note that because of InternalTransport's constructor, + tlsDomain is always set to Data::Empty at construction time, + in practice. + + @param socketFunc subclassers can call this function after + the socket is created. This is not currently used by + Transport. + */ + Transport(Fifo<TransactionMessage>& rxFifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + const Data& tlsDomain = Data::Empty, + AfterSocketCreationFuncPtr socketFunc = 0, + Compression &compression = Compression::Disabled, + unsigned transportFlags = 0 + ); + + virtual ~Transport(); + + /** + @note Subclasses override this method by checking whether + there are unprocessed messages on the TransactionMessage + Fifo (that was passed in to the constructor). + */ + virtual bool isFinished() const=0; + + std::auto_ptr<SendData> makeSendData( const Tuple& tuple, const Data& data, const Data& tid, const Data &sigcompId = Data::Empty); + + /** + @todo !bwc! What we do with a SendData is flexible. It might make a + copy, or send synchronously, or convert to another type, + etc. + + @todo !bch! Should this be protected and not public? + !bwc! TransportSelector uses this directly for retransmissions. + */ + virtual void send(std::auto_ptr<SendData> data)=0; + + /** + Called when a writer is done adding messages to the TxFifo; this is + used to interrupt the select call if the Transport is running in its + own thread. This does nothing if select is not currently blocking, so + don't bother calling this from the same thread that selects on this + Transport's fds. Default impl is a no-op. + */ + virtual void poke(){}; + + /** + If there is work to do, this is the method that does it. If + the socket is readable, it is read. If the socket is + writable and there are outgoing messages to be sent, they are + sent. + + Incoming messages are parsed and dispatched to the relevant + entity. SIP messages will be posted to the + TransactionMessage Fifo. + + @see sendData() + + @param fdset is the FdSet after select() has been called. + @see FdSet::select() + */ + virtual void process(FdSet& fdset) = 0; + + /** + Adds the Transport's socket FD to the appropriate read or + write sets as applicable. + */ + virtual void buildFdSet( FdSet& fdset) =0; + + virtual unsigned int getTimeTillNextProcessMS(){return UINT_MAX;} + + /** + Version of process to be invoked periodically when using callback-based + IO (via FdPollGrp). + */ + virtual void process() = 0; + + virtual void setPollGrp(FdPollGrp *grp) = 0; + + /** + Posts a ConnectionTerminated message to TransactionMessage + Fifo. + */ + void flowTerminated(const Tuple& flow); + void keepAlivePong(const Tuple& flow); + + /** + Posts a TransportFailure to the TransactionMessage Fifo. + */ + void fail(const Data& tid, + TransportFailure::FailureReason reason = TransportFailure::Failure, + int subCode = 0); + + /** + Generates a generic log for the platform specific socket + error number. + + @param e the socket error number + */ + static void error(int e); + + // These methods are used by the TransportSelector + const Data& interfaceName() const { return mInterface; } + + int port() const { return mTuple.getPort(); } + + /// @deprecated use ipVersion() + bool isV4() const { return mTuple.isV4(); } // !dcm! -- deprecate ASAP + + IpVersion ipVersion() const { return mTuple.ipVersion(); } + + /** + @return the domain name that will be used for TLS, to, for + example, find the certificate to present in the TLS + handshake. + */ + const Data& tlsDomain() const { return mTlsDomain; } + const sockaddr& boundInterface() const { return mTuple.getSockaddr(); } + const Tuple& getTuple() const { return mTuple; } + + /// @return This transport's TransportType. + virtual TransportType transport() const =0 ; + virtual bool isReliable() const =0; + virtual bool isDatagram() const =0; + + /** + @return true here if the subclass has a specific contact + value that it wishes the TransportSelector to use. + */ + virtual bool hasSpecificContact() const { return false; } + + /** + Perform basic sanity checks on message. Return false + if there is a problem eg) no Vias. + + @note --SIDE EFFECT-- This will queue a response if it CAN + for a via-less request. Response will go straight into the + TxFifo + */ + bool basicCheck(const SipMessage& msg); + + void makeFailedResponse(const SipMessage& msg, + int responseCode = 400, + const char * warning = 0); + std::auto_ptr<SendData> make503(SipMessage& msg, + UInt16 retryAfter); + + std::auto_ptr<SendData> make100(SipMessage& msg); + void setRemoteSigcompId(SipMessage&msg, Data& id); + // mark the received= and rport parameters if necessary + static void stampReceived(SipMessage* request); + + /** + Returns true if this Transport should be included in the + FdSet processing loop, false if the Transport will provide + its own cycles. If the Transport is going to provide its own + cycles, the startOwnProcessing() and shutdown() will be + called to tell the Transport when to process. + + @retval true will run in the SipStack's processing context + @retval false provides own cycles, just puts messages in rxFifo + */ + virtual bool shareStackProcessAndSelect() const=0; + + /** + transports that returned false to + shareStackProcessAndSelect() shouldn't put messages into the + fifo until this is called + + @todo ?dcm? avoid the received a message but haven't added a + transport to the TransportSelector race, but this might not + be necessary. + */ + virtual void startOwnProcessing()=0; + + /// only applies to transports that shareStackProcessAndSelect + virtual bool hasDataToSend() const = 0; + + /** + This starts shutting-down procedures for this Transport. New + requests may be denied while "mShuttingDown" is true. + + Overriding implementations should chain through to this. + + @todo ?dcm? pure virtual protected method to enforce this? + @see basicCheck() + @see isFinished() + */ + virtual void shutdown() + { + // !jf! should use the fifo to pass this in + mShuttingDown = true; + } + + // also used by the TransportSelector. + // requires that the two transports be + bool operator==(const Transport& rhs) const; + + //# queued messages on this transport + virtual unsigned int getFifoSize() const=0; + + void callSocketFunc(Socket sock); + + virtual void setCongestionManager(CongestionManager* manager) + { + mCongestionManager=manager; + } + + CongestionManager::RejectionBehavior getRejectionBehaviorForIncoming() const + { + if(mCongestionManager) + { + return mCongestionManager->getRejectionBehavior(&mStateMachineFifo.getFifo()); + } + return CongestionManager::NORMAL; + } + + UInt32 getExpectedWaitForIncoming() const + { + return (UInt32)mStateMachineFifo.getFifo().expectedWaitTimeMilliSec()/1000; + } + + // called by Connection to deliver a received message + virtual void pushRxMsgUp(TransactionMessage* msg); + + // set the receive buffer length (SO_RCVBUF) + virtual void setRcvBufLen(int buflen) { }; // make pure? + + // Storing and retrieving transport specific record-route header + virtual void setRecordRoute(const NameAddr& recordRoute) { mRecordRoute = recordRoute; mHasRecordRoute = true; } + virtual bool hasRecordRoute() const { return mHasRecordRoute; } + virtual const NameAddr& getRecordRoute() const { assert(mHasRecordRoute); return mRecordRoute; } + + inline unsigned int getKey() const {return mKey;} + + int getConnectionsDeleted() const; + void resetConnectionsDeleted(); + void increaseConnectionsDeleted(); + + protected: + friend class TransportSelector; + inline void setKey(unsigned int pKey) { mKey = pKey;} + + Data mInterface; + Tuple mTuple; + NameAddr mRecordRoute; + bool mHasRecordRoute; + unsigned int mKey; + + /** Number of connections delete in last processFdSet() call */ + int mConnectionsDeleted; + + CongestionManager* mCongestionManager; + ProducerFifoBuffer<TransactionMessage> mStateMachineFifo; // passed in + bool mShuttingDown; + + void setTlsDomain(const Data& domain) { mTlsDomain = domain; } + private: + static const Data transportNames[MAX_TRANSPORT]; + friend EncodeStream& operator<<(EncodeStream& strm, const Transport& rhs); + + Data mTlsDomain; + protected: + AfterSocketCreationFuncPtr mSocketFunc; + Compression &mCompression; + unsigned mTransportFlags; +}; + +EncodeStream& operator<<(EncodeStream& strm, const Transport& rhs); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TransportFailure.cxx b/src/libs/resiprocate/resip/stack/TransportFailure.cxx new file mode 100644 index 00000000..bd8475cd --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransportFailure.cxx @@ -0,0 +1,83 @@ +#include "TransportFailure.hxx" + +using namespace resip; + +TransportFailure::TransportFailure(const Data& transactionId, FailureReason f, int subCode) + : mTransactionId(transactionId), + mFailureReason(f), mFailureSubCode(subCode) +{ +} + +const Data& +TransportFailure::getTransactionId() const +{ + return mTransactionId; +} + +bool +TransportFailure::isClientTransaction() const +{ + // !jf! not strictly true + return true; +} + +EncodeStream& +TransportFailure::encodeBrief(EncodeStream& str) const +{ + return str << "TransportFailure: " << mTransactionId; +} + +EncodeStream& +TransportFailure::encode(EncodeStream& strm) const +{ + return encodeBrief(strm); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TransportFailure.hxx b/src/libs/resiprocate/resip/stack/TransportFailure.hxx new file mode 100644 index 00000000..1cae5417 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransportFailure.hxx @@ -0,0 +1,103 @@ +#ifndef RESIP_TransportFailure_hxx +#define RESIP_TransportFailure_hxx + +#include <iosfwd> +#include "resip/stack/TransactionMessage.hxx" +#include "rutil/Data.hxx" +#include "rutil/HeapInstanceCounter.hxx" + +namespace resip +{ + +/** This message is used to indicate that the TransportSelector has sent a sip + message using either reliable or unreliable transport +*/ +class TransportFailure : public TransactionMessage +{ + public: + RESIP_HeapCount(TransportFailure); + enum FailureReason + { + None = 0, //invalid + TransportNoExistConn, + Failure, + TransportNoSocket, + TransportBadConnect, + TransportShutdown, + ConnectionUnknown, + ConnectionException, + NoTransport, + NoRoute, + CertNameMismatch, + CertValidationFailure + }; + + TransportFailure(const Data& transactionId, FailureReason f, int subCode=0); + + virtual const Data& getTransactionId() const; + virtual bool isClientTransaction() const; + + FailureReason getFailureReason() const { return mFailureReason; } + int getFailureSubCode() const { return mFailureSubCode; } + + virtual EncodeStream& encodeBrief(EncodeStream& str) const; + virtual EncodeStream& encode(EncodeStream& strm) const; + + private: + Data mTransactionId; + FailureReason mFailureReason; + int mFailureSubCode; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TransportSelector.cxx b/src/libs/resiprocate/resip/stack/TransportSelector.cxx new file mode 100644 index 00000000..58fc9280 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransportSelector.cxx @@ -0,0 +1,1556 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#ifdef WIN32 +#include <winsock2.h> +#include <ws2tcpip.h> +#include <wspiapi.h> // Required for freeaddrinfo implementation in Windows 2000, NT, Me/95/98 +#else +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netdb.h> +#endif + +#include "resip/stack/NameAddr.hxx" +#include "resip/stack/Uri.hxx" + +#include "resip/stack/ExtensionParameter.hxx" +#include "resip/stack/Compression.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/TransactionState.hxx" +#include "resip/stack/TransportFailure.hxx" +#include "resip/stack/TransportSelector.hxx" +#include "resip/stack/InternalTransport.hxx" +#include "resip/stack/TcpBaseTransport.hxx" +#include "resip/stack/TcpTransport.hxx" +#include "resip/stack/UdpTransport.hxx" +#include "resip/stack/Uri.hxx" + +#include "rutil/DataStream.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Socket.hxx" +#include "rutil/FdPoll.hxx" +#include "rutil/WinLeakCheck.hxx" +#include "rutil/dns/DnsStub.hxx" + +#ifdef USE_SIGCOMP +#include <osc/Stack.h> +#include <osc/SigcompMessage.h> +#endif + +#ifdef USE_SSL +#include "resip/stack/ssl/DtlsTransport.hxx" +#include "resip/stack/ssl/Security.hxx" +#include "resip/stack/ssl/TlsTransport.hxx" +#endif + +#ifdef WIN32 +#include "rutil/WinCompat.hxx" +#endif + +#ifdef __MINGW32__ +#define gai_strerror strerror +#endif + +#include <sys/types.h> + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +TransportSelector::TransportSelector(Fifo<TransactionMessage>& fifo, Security* security, DnsStub& dnsStub, Compression &compression) : + mDns(dnsStub), + mStateMacFifo(fifo), + mSecurity(security), + mSocket( INVALID_SOCKET ), + mSocket6( INVALID_SOCKET ), + mCompression(compression), + mSigcompStack (0), + mPollGrp(0), + mAvgBufferSize(1024), + mInterruptorHandle(0) +{ + memset(&mUnspecified.v4Address, 0, sizeof(sockaddr_in)); + mUnspecified.v4Address.sin_family = AF_UNSPEC; + +#ifdef USE_IPV6 + memset(&mUnspecified6.v6Address, 0, sizeof(sockaddr_in6)); + mUnspecified6.v6Address.sin6_family = AF_UNSPEC; +#endif + +#ifdef USE_SIGCOMP + if (mCompression.isEnabled()) + { + DebugLog (<< "Compression enabled for Transport Selector"); + mSigcompStack = new osc::Stack(mCompression.getStateHandler()); + mCompression.addCompressorsToStack(mSigcompStack); + } + else + { + DebugLog (<< "Compression disabled for Transport Selector"); + } +#else + DebugLog (<< "No compression library available"); +#endif +} + +TransportSelector::~TransportSelector() +{ + mExactTransports.clear(); + mAnyInterfaceTransports.clear(); + mAnyPortTransports.clear(); + mAnyPortAnyInterfaceTransports.clear(); + mTlsTransports.clear(); + mSharedProcessTransports.clear(); + mHasOwnProcessTransports.clear(); + mTypeToTransportMap.clear(); + while(!mTransports.empty()) + { + delete mTransports.back(); + mTransports.pop_back(); + } +#ifdef USE_SIGCOMP + delete mSigcompStack; +#endif + + if ( mSocket != INVALID_SOCKET ) + closeSocket( mSocket ); + if ( mSocket6 != INVALID_SOCKET ) + closeSocket( mSocket6 ); + + setPollGrp(0); +} + +void +TransportSelector::shutdown() +{ + //!dcm! repeat shutdown template pattern in all loop over all transport functions, refactor to functor? + for (ExactTupleMap::iterator i=mExactTransports.begin(); i!=mExactTransports.end(); ++i) + { + i->second->shutdown(); + } + for (AnyInterfaceTupleMap::iterator i=mAnyInterfaceTransports.begin(); i!=mAnyInterfaceTransports.end(); ++i) + { + i->second->shutdown(); + } + for (TlsTransportMap::iterator i=mTlsTransports.begin(); i!=mTlsTransports.end(); ++i) + { + i->second->shutdown(); + } +} + +bool +TransportSelector::isFinished() const +{ + for (ExactTupleMap::const_iterator i=mExactTransports.begin(); i!=mExactTransports.end(); ++i) + { + if (!i->second->isFinished()) return false; + } + for (AnyInterfaceTupleMap::const_iterator i=mAnyInterfaceTransports.begin(); i!=mAnyInterfaceTransports.end(); ++i) + { + if (!i->second->isFinished()) return false; + } + for (TlsTransportMap::const_iterator i=mTlsTransports.begin(); i!=mTlsTransports.end(); ++i) + { + if (!i->second->isFinished()) return false; + } + return true; +} + +void +TransportSelector::addTransport(std::auto_ptr<Transport> autoTransport, + bool immediate) +{ + if(immediate) + { + addTransportInternal(autoTransport); + } + else + { + mTransportsToAdd.add(autoTransport.release()); + } +} + +void +TransportSelector::addTransportInternal(std::auto_ptr<Transport> autoTransport) +{ + Transport* transport = autoTransport.release(); + mDns.addTransportType(transport->transport(), transport->ipVersion()); + + // !bwc! This is a multimap from TransportType/IpVersion to Transport*. + // Make _extra_ sure that no garbage goes in here. + if(transport->transport()==TCP) + { + assert(dynamic_cast<TcpTransport*>(transport)); + } +#ifdef USE_SSL + else if(transport->transport()==TLS) + { + assert(dynamic_cast<TlsTransport*>(transport)); + } +#endif + else if(transport->transport()==UDP) + { + assert(dynamic_cast<UdpTransport*>(transport)); + } +#ifdef USE_DTLS +#ifdef USE_SSL + else if(transport->transport()==DTLS) + { + assert(dynamic_cast<DtlsTransport*>(transport)); + } +#endif +#endif + else + { + assert(0); + } + + Tuple tuple(transport->interfaceName(), transport->port(), + transport->ipVersion(), transport->transport()); + mTypeToTransportMap.insert(TypeToTransportMap::value_type(tuple,transport)); + + switch (transport->transport()) + { + case UDP: + case TCP: + { + assert(mExactTransports.find(tuple) == mExactTransports.end() && + mAnyInterfaceTransports.find(tuple) == mAnyInterfaceTransports.end()); + + DebugLog (<< "Adding transport: " << tuple); + + // Store the transport in the ANY interface maps if the tuple specifies ANY + // interface. Store the transport in the specific interface maps if the tuple + // specifies an interface. See TransportSelector::findTransport. + if (transport->interfaceName().empty() || + transport->getTuple().isAnyInterface() || + transport->hasSpecificContact() ) + { + mAnyInterfaceTransports[tuple] = transport; + mAnyPortAnyInterfaceTransports[tuple] = transport; + } + else + { + mExactTransports[tuple] = transport; + mAnyPortTransports[tuple] = transport; + } + } + break; + case TLS: + case DTLS: + { + TlsTransportKey key(transport->tlsDomain(),transport->transport(),transport->ipVersion()); + mTlsTransports[key]=transport; + } + break; + default: + assert(0); + break; + } + + if (transport->shareStackProcessAndSelect()) + { + if ( mPollGrp ) + { + transport->setPollGrp(mPollGrp); + } + mSharedProcessTransports.push_back(transport); + } + else + { + mHasOwnProcessTransports.push_back(transport); + mHasOwnProcessTransports.back()->startOwnProcessing(); + } + + mTransports.push_back(transport); + transport->setKey((unsigned int)mTransports.size()); +} + +void +TransportSelector::setPollGrp(FdPollGrp *grp) +{ + if(mPollGrp && mInterruptorHandle) + { + // unregister our select interruptor + mPollGrp->delPollItem(mInterruptorHandle); + mInterruptorHandle=0; + } + + mPollGrp = grp; + + if(mPollGrp && mSelectInterruptor.get()) + { + mInterruptorHandle = mPollGrp->addPollItem(mSelectInterruptor->getReadSocket(), FPEM_Read, mSelectInterruptor.get()); + } + + for(TransportList::iterator t=mSharedProcessTransports.begin(); + t!=mSharedProcessTransports.end(); ++t) + { + (*t)->setPollGrp(mPollGrp); + } +} + +void +TransportSelector::createSelectInterruptor() +{ + if(!mSelectInterruptor.get()) + { + mSelectInterruptor.reset(new SelectInterruptor); + if(mPollGrp) + { + mInterruptorHandle = mPollGrp->addPollItem(mSelectInterruptor->getReadSocket(), FPEM_Read, mSelectInterruptor.get()); + } + } +} + +void +TransportSelector::buildFdSet(FdSet& fdset) +{ + for(TransportList::iterator it = mSharedProcessTransports.begin(); + it != mSharedProcessTransports.end(); it++) + { + (*it)->buildFdSet(fdset); + } + if(mSelectInterruptor.get()) + { + mSelectInterruptor->buildFdSet(fdset); + } +} + +void +TransportSelector::process(FdSet& fdset) +{ + checkTransportAddQueue(); + + for(TransportList::iterator it = mSharedProcessTransports.begin(); + it != mSharedProcessTransports.end(); it++) + { + try + { + (*it)->process(fdset); + } + catch (BaseException& e) + { + ErrLog (<< "Exception thrown from Transport::process: " << e); + } + } + + if(mSelectInterruptor.get()) + { + mSelectInterruptor->process(fdset); + } +} + +void +TransportSelector::process() +{ + // This function will only be sufficient if these Transports are hooked into + // a FdPollGrp. + checkTransportAddQueue(); + + for(TransportList::iterator it = mSharedProcessTransports.begin(); + it != mSharedProcessTransports.end(); it++) + { + try + { + (*it)->process(); + } + catch (BaseException& e) + { + ErrLog (<< "Exception thrown from Transport::process: " << e); + } + } +} + +void +TransportSelector::checkTransportAddQueue() +{ + std::auto_ptr<Transport> t(mTransportsToAdd.getNext(-1)); + while(t.get()) + { + addTransportInternal(t); + t.reset(mTransportsToAdd.getNext(0)); + } +} + +void +TransportSelector::poke() +{ + for(TransportList::iterator it = mHasOwnProcessTransports.begin(); + it != mHasOwnProcessTransports.end(); it++) + { + try + { + (*it)->poke(); + } + catch (BaseException& e) + { + ErrLog (<< "Exception thrown from Transport::process: " << e); + } + } + + if(mSelectInterruptor.get() && hasDataToSend()) + { + mSelectInterruptor->handleProcessNotification(); + } +} + +bool +TransportSelector::hasDataToSend() const +{ + for(TransportList::const_iterator it = mSharedProcessTransports.begin(); + it != mSharedProcessTransports.end(); it++) + { + if ((*it)->hasDataToSend()) + { + return true; + } + } + return false; +} + +//!jf! the problem here is that DnsResult is returned after looking +//mDns.lookup() but this can result in a synchronous call to handle() which +//assumes that dnsresult has been assigned to the TransactionState +//!dcm! -- now 2-phase to fix this +DnsResult* +TransportSelector::createDnsResult(DnsHandler* handler) +{ + return mDns.createDnsResult(handler); +} + +void +TransportSelector::dnsResolve(DnsResult* result, + SipMessage* msg) +{ + // Picking the target destination: + // - for request, use forced target if set + // otherwise use loose routing behaviour (route or, if none, request-uri) + // - for response, use forced target if set, otherwise look at via + + if (msg->isRequest()) + { + // If this is an ACK we need to fix the tid to reflect that + if (msg->hasForceTarget()) + { + //DebugLog(<< "!ah! RESOLVING request with force target : " << msg->getForceTarget() ); + mDns.lookup(result, msg->getForceTarget()); + } + else if (msg->exists(h_Routes) && !msg->const_header(h_Routes).empty()) + { + // put this into the target, in case the send later fails, so we don't + // lose the target + msg->setForceTarget(msg->const_header(h_Routes).front().uri()); + DebugLog (<< "Looking up dns entries (from route) for " << msg->getForceTarget()); + mDns.lookup(result, msg->getForceTarget()); + } + else + { + DebugLog (<< "Looking up dns entries for " << msg->const_header(h_RequestLine).uri()); + mDns.lookup(result, msg->const_header(h_RequestLine).uri()); + } + } + else if (msg->isResponse()) + { + ErrLog(<<"unimplemented response dns"); + assert(0); + } + else + { + assert(0); + } +} + +bool isDgramTransport (TransportType type) +{ + static const bool unknown_transport = false; + switch(type) + { + case UDP: + case DTLS: + case DCCP: + case SCTP: + return true; + + case TCP: + case TLS: + return false; + + default: + assert(unknown_transport); + return unknown_transport; // !kh! just to make it compile wo/warning. + } +} + +Tuple +TransportSelector::getFirstInterface(bool is_v4, TransportType type) +{ +// !kh! both getaddrinfo() and IPv6 are not supported by cygwin, yet. +#ifdef __CYGWIN__ + assert(0); + return Tuple(); +#else + // !kh! + // 1. Query local hostname. + char hostname[256] = ""; + if(gethostname(hostname, sizeof(hostname)) != 0) + { + int e = getErrno(); + Transport::error( e ); + InfoLog(<< "Can't query local hostname : [" << e << "] " << strerror(e) ); + throw Transport::Exception("Can't query local hostname", __FILE__, __LINE__); + } + InfoLog(<< "Local hostname is [" << hostname << "]"); + + // !kh! + // 2. Resolve address(es) of local hostname for specified transport. + const bool is_dgram = isDgramTransport(type); + addrinfo hint; + memset(&hint, 0, sizeof(hint)); + hint.ai_family = is_v4 ? PF_INET : PF_INET6; + hint.ai_flags = AI_PASSIVE; + hint.ai_socktype = is_dgram ? SOCK_DGRAM : SOCK_STREAM; + + addrinfo* results; + int ret = getaddrinfo( + hostname, + 0, + &hint, + &results); + + if(ret != 0) + { + Transport::error( ret ); // !kh! is this the correct sematics? ret is not errno. + InfoLog(<< "Can't resolve " << hostname << "'s address : [" << ret << "] " << gai_strerror(ret) ); + throw Transport::Exception("Can't resolve hostname", __FILE__,__LINE__); + } + + // !kh! + // 3. Use first address resolved if there are more than one. + // What should I do if there are more than one address? + // i.e. results->ai_next != 0. + Tuple source(*(results->ai_addr), type); + InfoLog(<< "Local address is " << source); + addrinfo* ai = results->ai_next; + for(; ai; ai = ai->ai_next) + { + Tuple addr(*(ai->ai_addr), type); + InfoLog(<<"Additional address " << addr); + } + freeaddrinfo(results); + + return source; +#endif +} + + +/** + Check the msg's top Via header for a source host&port that indicates + a particular Transport. + Do NOT do this for a response, as it would allow malicious downstream + to insert bogus host in via header that we would then use. +**/ +Transport* +TransportSelector::findTransportByVia(SipMessage* msg, const Tuple& target, + Tuple& source) const +{ + assert(msg->exists(h_Vias)); + assert(!msg->const_header(h_Vias).empty()); + const Via& via = msg->const_header(h_Vias).front(); + + if (via.sentHost().empty() && via.transport().empty()) + { + return 0; + } + + // XXX: Is there better way to do below (without the copy)? + source = Tuple(via.sentHost(), via.sentPort(), target.ipVersion(), + via.transport().empty() ? target.getType() : toTransportType(via.transport())); // Transport type is pre-populated in via, lock to it + + if ( target.mFlowKey!=0 && (source.getPort()==0 || source.isAnyInterface()) ) + { + WarningLog(<< "Sending request with incomplete Via header and FlowKey." + <<" This code no smart enough to pick the correct Transport." + <<" Via=" << via); + assert(0); + } + if ( source.isAnyInterface() ) + { + // INADDR_ANY cannot go out on the wire, so remove it from + // via header now. + // transmit() will later use determineSourceInterface() to + // get the actual interface to populate the Contact & Via headers. + // Not sure if we should support this case or just assert. + // .gh. This should be supported, in case only the transport part of the Via is set + msg->header(h_Vias).front().sentHost().clear(); + } + + Transport *trans; + if ( (trans = findTransportBySource(source, msg)) == NULL ) + { + return NULL; + } + if(source.getPort()==0) + { + source.setPort(trans->port()); + } + return trans; +} + +Tuple +TransportSelector::determineSourceInterface(SipMessage* msg, const Tuple& target) const +{ + assert(msg->exists(h_Vias)); + assert(!msg->header(h_Vias).empty()); + const Via& via = msg->header(h_Vias).front(); + + // this case should be handled already for UDP and TCP targets + //assert( (!(msg->isRequest() && !via.sentHost().empty())) || (target.getType() == TLS || target.getType() == DTLS) ); + if (1) + { + Tuple source(target); +#if defined(WIN32) && !defined(NO_IPHLPAPI) + try + { + GenericIPAddress addr = WinCompat::determineSourceInterface(target.toGenericIPAddress()); + source.setSockaddr(addr); + } + catch (WinCompat::Exception& ex) + { + ErrLog (<< "Can't find source interface to use: " << ex); + throw Transport::Exception("Can't find source interface", __FILE__, __LINE__); + } +#else + // !kh! + // The connected UDP technique doesn't work all the time. + // 1. Might not work on all implementaions as stated in UNP vol.1 8.14. + // 2. Might not work under unspecified condition on Windows, + // search "getsockname" in MSDN library. + // 3. We've experienced this issue on our production software. + + // this process will determine which interface the kernel would use to + // send a packet to the target by making a connect call on a udp socket. + Socket tmp = INVALID_SOCKET; + if (target.isV4()) + { + if (mSocket == INVALID_SOCKET) + { + mSocket = InternalTransport::socket(UDP, V4); // may throw + } + tmp = mSocket; + } + else + { + if (mSocket6 == INVALID_SOCKET) + { + mSocket6 = InternalTransport::socket(UDP, V6); // may throw + } + tmp = mSocket6; + } + + int ret = connect(tmp,&target.getSockaddr(), target.length()); + if (ret < 0) + { + int e = getErrno(); + Transport::error( e ); + InfoLog(<< "Unable to route to " << target << " : [" << e << "] " << strerror(e) ); + throw Transport::Exception("Can't find source address for Via", __FILE__,__LINE__); + } + + socklen_t len = source.length(); + ret = getsockname(tmp,&source.getMutableSockaddr(), &len); + if (ret < 0) + { + int e = getErrno(); + Transport::error(e); + InfoLog(<< "Can't determine name of socket " << target << " : " << strerror(e) ); + throw Transport::Exception("Can't find source address for Via", __FILE__,__LINE__); + } + + // !kh! test if connected UDP technique results INADDR_ANY, i.e. 0.0.0.0. + // if it does, assume the first avaiable interface. + if(source.isV4()) + { + long src = (reinterpret_cast<const sockaddr_in*>(&source.getSockaddr())->sin_addr.s_addr); + if(src == INADDR_ANY) + { + InfoLog(<< "Connected UDP failed to determine source address, use first address instaed."); + source = getFirstInterface(true, target.getType()); + } + } + else // IPv6 + { +//should never reach here in WIN32 w/ V6 support +#if defined(USE_IPV6) && !defined(WIN32) + if (source.isAnyInterface()) //!dcm! -- when could this happen? + { + source = getFirstInterface(false, target.getType()); + } +# endif + } + // Unconnect. + // !jf! This is necessary, but I am not sure what we can do if this + // fails. I'm not sure the stack can recover from this error condition. + if (target.isV4()) + { + ret = connect(mSocket, + (struct sockaddr*)&mUnspecified.v4Address, + sizeof(mUnspecified.v4Address)); + } +#ifdef USE_IPV6 + else + { + ret = connect(mSocket6, + (struct sockaddr*)&mUnspecified6.v6Address, + sizeof(mUnspecified6.v6Address)); + } +#else + else + { + assert(0); + } +#endif + + if ( ret<0 ) + { + int e = getErrno(); + //.dcm. OS X 10.5 workaround, we could #ifdef for specific OS X version. + if (!(e ==EAFNOSUPPORT || e == EADDRNOTAVAIL)) + { + ErrLog(<< "Can't disconnect socket : " << strerror(e) ); + Transport::error(e); + throw Transport::Exception("Can't disconnect socket", __FILE__,__LINE__); + } + } +#endif + + // This is the port that the request will get sent out from. By default, + // this value will be 0, since the Helper that creates the request will not + // assign it. In this case, the stack will pick an arbitrary (but appropriate) + // transport. If it is non-zero, it will only match transports that are bound to + // the specified port (and fail if none are available) + + if(msg->isRequest()) + { + source.setPort(via.sentPort()); + } + else + { + source.setPort(0); + } + + DebugLog (<< "Looked up source for destination: " << target + << " -> " << source + << " sent-by=" << via.sentHost() + << " sent-port=" << via.sentPort()); + + return source; + } +} + +// !jf! there may be an extra copy of a tuple here. can probably get rid of it +// but there are some const issues. +bool +TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) +{ + assert(msg); + + if(msg->mIsDecorated) + { + msg->rollbackOutboundDecorators(); + } + + try + { + TransportFailure::FailureReason transportFailureReason = TransportFailure::NoTransport; + + // !ah! You NEED to do this for responses too -- the transport doesn't + // !ah! know it's IP addres(es) in all cases, AND it's function of the dest. + // (imagine a synthetic message...) + + Tuple source; + // .bwc. We need 3 things here: + // 1) A Transport* to call send() on. + // 2) A complete Tuple to pass in this call (target). + // 3) A host, port, and protocol for filling out the topmost via, and + // possibly stuff like Contact, Referred-By, and other headers that + // must specify a hostname that the TU was unable to supply, because + // it didn't know what interface/port the message would be sent on. + // (source) + /* + Our Transport* might be found in target. If so, we can skip this block + of stuff. + Alternatively, we might not have the transport to start with. However, + given a connection id, we will be able to find the Connection we + should use, we can get the Transport we want. If we have no connection + id, but we know we are using TLS or DTLS and have a tls hostname, we + can use the hostname to find the appropriate transport. If all else + fails, we must resort to the connected UDP trick to fill out source, + which in turn is used to look up a matching transport. + + Given the transport, it is always possible to get the port/protocol, + and usually possible to get the host (if it is bound to INADDR_ANY, we + can't tell). However, if we had to fill out source in order to find + the transport in the first place, this is not an issue. + */ + + Data remoteSigcompId; + + Transport* transport=0; + + if (msg->isRequest()) + { + transport = findTransportByVia(msg, target, source); + if (!transport) + { + if ((transport = findTransportByDest(target)) != NULL) + { + source = transport->getTuple(); + } + } + + if(!transport && target.mFlowKey && target.onlyUseExistingConnection) + { + // .bwc. Connection info was specified, and use of this connection + // was mandatory, but connection is no longer around. We fail. + transportFailureReason = TransportFailure::TransportNoExistConn; + } + else if (transport)// .bwc. Here we use transport to find source. + { + assert( source.getType()!=0 ); + + // .bwc. If the transport has an ambiguous interface, we need to + //look a little closer. + if(source.isAnyInterface()) + { + Tuple temp = determineSourceInterface(msg,target); + + // .bwc. determineSourceInterface() can give us a port, if the TU + // put one in the topmost Via. + assert(source.ipVersion()==temp.ipVersion() && + source.getType()==temp.getType()); + source=temp; + + /* determineSourceInterface might return an arbitrary port + here, so use the port specified in transport->port(). + */ + if(source.getPort()==0) + { + source.setPort(transport->port()); + } + } + } + // .bwc. Here we use source to find transport. + else + { + source = determineSourceInterface(msg, target); + transport = findTransportBySource(source, msg); + + // .bwc. determineSourceInterface might give us a port + if(transport && source.getPort()==0) + { + source.setPort(transport->port()); + } + } + + target.transportKey=transport ? transport->getKey() : 0; + + // .bwc. Topmost Via is only filled out in the request case. Also, if + // we don't have a transport at this point, we're going to fail, + // so don't bother doing the work. + if(target.transportKey) + { + Via& topVia(msg->header(h_Vias).front()); + topVia.remove(p_maddr); // !jf! why do this? + + // insert the via + if (topVia.transport().empty()) + { + topVia.transport() = Tuple::toData(source.getType()); + } + if (!topVia.sentHost().size()) + { + topVia.sentHost() = Tuple::inet_ntop(source); + } + if (!topVia.sentPort()) + { + topVia.sentPort() = source.getPort(); + } + + if (mCompression.isEnabled()) + { + // Indicate support for SigComp, if appropriate. + if (!topVia.exists(p_comp)) + { + topVia.param(p_comp) = "sigcomp"; + } + if (!topVia.exists(p_sigcompId)) + { + topVia.param(p_sigcompId) = mCompression.getSigcompId(); + } + + // Figure out remote identifier (from Route header + // field, if present; otherwise, from Request-URI). + // XXX rohc-sip-sigcomp-03 says to use +sip.instance, + // but this is impossible to actually do if you're + // not actually the registrar, and really hard even + // if you are. + Uri destination;// (*reinterpret_cast<Uri*>(0)); // !bwc! What? + + if(msg->exists(h_Routes) && + !msg->const_header(h_Routes).empty()) + { + destination = msg->const_header(h_Routes).front().uri(); + } + else + { + destination = msg->const_header(h_RequestLine).uri(); + } + + if (destination.exists(p_comp) && + destination.param(p_comp) == "sigcomp") + { + if (destination.exists(p_sigcompId)) + { + remoteSigcompId = destination.param(p_sigcompId); + } + else + { + remoteSigcompId = destination.host(); + } + } + // Squirrel the compartment away in the branch so that + // we can figure out (pre-transaction-matching) what + // compartment incoming requests are associated with. + topVia.param(p_branch).setSigcompCompartment(remoteSigcompId); + } + } + + } + else if (msg->isResponse()) + { + // We assume that all stray responses have been discarded, so we always + // know the transport that the corresponding request was received on + // and this has been copied by TransactionState::sendToWire into transport + transport=findTransportByDest(target); + + // !bwc! May eventually remove this once we allow transports to be + // removed while running. + assert(transport); + + source = transport->getTuple(); + + // .bwc. If the transport has an ambiguous interface, we need to + //look a little closer. + if(source.isAnyInterface()) + { + Tuple temp = source; + source = determineSourceInterface(msg,target); + assert(source.ipVersion()==temp.ipVersion() && + source.getType()==temp.getType()); + + /* determineSourceInterface might return an arbitrary port here, + so use the port specified in transport->port(). + */ + if(source.getPort()==0) + { + source.setPort(transport->port()); + } + } + if (mCompression.isEnabled()) + { + // Figure out remote identifier (from Via header field). + Via& topVia(msg->header(h_Vias).front()); + + if(topVia.exists(p_comp) && + topVia.param(p_comp) == "sigcomp") + { + if (topVia.exists(p_sigcompId)) + { + remoteSigcompId = topVia.param(p_sigcompId); + } + else + { + // XXX rohc-sigcomp-sip-03 says "sent-by", + // but this should probably be "received" if present, + // and "sent-by" otherwise. + // XXX Also, the spec is ambiguous about whether + // to include the port in this identifier. + remoteSigcompId = topVia.sentHost(); + } + } + } + } + else + { + assert(0); + } + + // .bwc. At this point, source, transport, and target should be + // _fully_ specified. + + if (transport) + { + // !bwc! TODO This filling in of stuff really should be handled with + // the callOutboundDecorators() callback. (Or, at the very least, + // we should allow this code to be turned off through configuration. + // There are plenty of cases where this stuff is not at all necessary.) + // There is a contact header and it contains exactly one entry + if (msg->exists(h_Contacts) && msg->header(h_Contacts).size()==1) + { + for (NameAddrs::iterator i=msg->header(h_Contacts).begin(); i != msg->header(h_Contacts).end(); i++) + { + const NameAddr& c_contact = *i; + NameAddr& contact = *i; + // No host specified, so use the ip address and port of the + // transport used. Otherwise, leave it as is. + if (c_contact.uri().host().empty()) + { + contact.uri().host() = (transport->hasSpecificContact() ? + transport->interfaceName() : + Tuple::inet_ntop(source) ); + contact.uri().port() = transport->port(); + + if (transport->transport() != UDP && !contact.uri().exists(p_gr)) + { + contact.uri().param(p_transport) = Tuple::toDataLower(transport->transport()); + } + + // Add comp=sigcomp to contact URI + // Also, If no +sip.instance on contact HEADER, + // add sigcomp-id="<urn>" to contact URI. + if (mCompression.isEnabled()) + { + if (!contact.uri().exists(p_comp)) + { + contact.uri().param(p_comp) = "sigcomp"; + } + if (!contact.exists(p_Instance) && + !contact.uri().exists(p_sigcompId)) + { + contact.uri().param(p_sigcompId) + = mCompression.getSigcompId(); + } + } + } + else + { + if (c_contact.uri().exists(p_addTransport)) + { + if (target.getType() != UDP) + { + contact.uri().param(p_transport) = Tuple::toDataLower(target.getType()); + } + contact.uri().remove(p_addTransport); + } + } + + } + } + + // !bwc! TODO make this configurable + // Fix the Referred-By header if no host specified. + // If malformed, leave it alone. + if (msg->exists(h_ReferredBy) + && msg->const_header(h_ReferredBy).isWellFormed()) + { + if (msg->const_header(h_ReferredBy).uri().host().empty()) + { + msg->header(h_ReferredBy).uri().host() = Tuple::inet_ntop(source); + msg->header(h_ReferredBy).uri().port() = transport->port(); + } + } + + // !bwc! TODO make this configurable + // .bwc. Only try fiddling with this is if the Record-Route is well- + // formed. If the topmost Record-Route is malformed, we have no idea + // whether it came from something the TU synthesized or from the wire. + // We shouldn't touch it. Frankly, I take issue with the method we have + // chosen to signal to the stack that we want it to fill out various + // header-field-values. + if (msg->exists(h_RecordRoutes) + && !msg->const_header(h_RecordRoutes).empty() + && msg->const_header(h_RecordRoutes).front().isWellFormed()) + { + const NameAddr& c_rr = msg->const_header(h_RecordRoutes).front(); + NameAddr& rr = msg->header(h_RecordRoutes).front(); + if (c_rr.uri().host().empty()) + { + rr.uri().host() = Tuple::inet_ntop(source); + rr.uri().port() = transport->port(); + if (target.getType() != UDP && !rr.uri().exists(p_transport)) + { + rr.uri().param(p_transport) = Tuple::toDataLower(target.getType()); + } + // Add comp=sigcomp and sigcomp-id="<urn>" to Record-Route + // XXX This isn't quite right -- should be set only + // on routes facing the client. Doing this correctly + // requires double-record-routing + if (mCompression.isEnabled()) + { + if (!rr.uri().exists(p_comp)) + { + rr.uri().param(p_comp) = "sigcomp"; + } + if (!rr.uri().exists(p_sigcompId)) + { + rr.uri().param(p_sigcompId) = mCompression.getSigcompId(); + } + } + } + } + + // !bwc! TODO make this configurable + // See draft-ietf-sip-identity + if (mSecurity && msg->exists(h_Identity) && msg->const_header(h_Identity).value().empty()) + { + DateCategory now; + msg->header(h_Date) = now; +#if defined(USE_SSL) + try + { + const Data& domain = msg->const_header(h_From).uri().host(); + msg->header(h_Identity).value() = mSecurity->computeIdentity( domain, + msg->getCanonicalIdentityString()); + } + catch (Security::Exception& e) + { + InfoLog (<< "Couldn't add identity header: " << e); + msg->remove(h_Identity); + if (msg->exists(h_IdentityInfo)) + { + msg->remove(h_IdentityInfo); + } + } +#endif + } + + target.transportKey=transport->getKey(); + + // !bwc! Deprecated. Stop doing this eventually. + target.transport=transport; + + // Call back anyone who wants to perform outbound decoration + msg->callOutboundDecorators(source, target,remoteSigcompId); + + std::auto_ptr<SendData> send(new SendData(target, + resip::Data::Empty, + msg->getTransactionId(), + remoteSigcompId)); + + send->data.reserve(mAvgBufferSize + mAvgBufferSize/4); + + DataStream str(send->data); + msg->encode(str); + str.flush(); + + // !bwc! Moving average of message size. (Used to intelligently + // predict how much space to reserve in the buffer, to minimize + // dynamic resizing.) + mAvgBufferSize = (255*mAvgBufferSize + send->data.size()+128)/256; + + assert(!send->data.empty()); + DebugLog (<< "Transmitting to " << target + << " tlsDomain=" << msg->getTlsDomain() + << " via " << source + << std::endl << std::endl << send->data.escaped() + << "sigcomp id=" << remoteSigcompId); + + if(sendData) + { + *sendData = *send; + } + + transport->send(send); + return true; + } + else + { + InfoLog (<< "tid=" << msg->getTransactionId() << " failed to find a transport to " << target); + mStateMacFifo.add(new TransportFailure(msg->getTransactionId(), transportFailureReason)); + return false; + } + + } + catch (Transport::Exception& ) + { + InfoLog (<< "tid=" << msg->getTransactionId() << " no route to target: " << target); + mStateMacFifo.add(new TransportFailure(msg->getTransactionId(), TransportFailure::NoRoute)); + return false; + } +} + +void +TransportSelector::retransmit(const SendData& data) +{ + assert(data.destination.transportKey); + Transport* transport = findTransportByDest(data.destination); + + // !jf! The previous call to transmit may have blocked or failed (It seems to + // block in windows when the network is disconnected - don't know why just + // yet. + + // !kh! + // My speculation for blocking is; when network is disconnected, WinSock sets + // a timer (to give up) and tries to defer reporting the error, in hope of + // the network would be recovered. Before the timer fires, applications could + // still select() (or the likes) their socket descriptors and find they are + // writable if there is still room in buffer (per socket). If the send()s or + // sendto()s made during this time period overflows the buffer, it blocks. + // But I somewhat doubt this would be noticed, because block would be brief, + // once the timer fires, the blocked call would return error. + // Note that the block applies to both UDP and TCP sockets. + // Quote from Linux man page: + // When the message does not fit into the send buffer of the socket, send + // normally blocks, unless the socket has been placed in non-blocking I/O + // mode. In non-blocking mode it would return EAGAIN in this case. + // Quote from MSDN library: + // If no buffer space is available within the transport system to hold the + // data to be transmitted, sendto will block unless the socket has been + // placed in a nonblocking mode. + + if(transport) + { + // If this is not true, it means the transport has been removed. + transport->send(std::auto_ptr<SendData>(data.clone())); + } +} + +void +TransportSelector::closeConnection(const Tuple& peer) +{ + Transport* t = findTransportByDest(peer); + if(t) + { + SendData* close=new SendData(peer, + resip::Data::Empty, + resip::Data::Empty, + resip::Data::Empty); + close->command = SendData::CloseConnection; + t->send(std::auto_ptr<SendData>(close)); + } +} + +unsigned int +TransportSelector::sumTransportFifoSizes() const +{ + unsigned int sum = 0; + + for (AnyPortTupleMap::const_iterator i = mAnyPortTransports.begin(); + i != mAnyPortTransports.end(); ++i) + { + sum += i->second->getFifoSize(); + } + + for (AnyPortAnyInterfaceTupleMap::const_iterator i = mAnyPortAnyInterfaceTransports.begin(); + i != mAnyPortAnyInterfaceTransports.end(); ++i) + { + sum += i->second->getFifoSize(); + } + + for (TlsTransportMap::const_iterator i = mTlsTransports.begin(); + i != mTlsTransports.end(); ++i) + { + sum += i->second->getFifoSize(); + } + + return sum; +} + +void +TransportSelector::terminateFlow(const resip::Tuple& flow) +{ + closeConnection(flow); +} + +void +TransportSelector::enableFlowTimer(const resip::Tuple& flow) +{ + Transport* t = findTransportByDest(flow); + if(t) + { + SendData* enableFlowTimer=new SendData(flow, + resip::Data::Empty, + resip::Data::Empty, + resip::Data::Empty); + enableFlowTimer->command = SendData::EnableFlowTimer; + t->send(std::auto_ptr<SendData>(enableFlowTimer)); + } +} + +Transport* +TransportSelector::findTransportByDest(const Tuple& target) +{ + if(target.transportKey) + { + if(target.transportKey <= mTransports.size()) + { + return mTransports[target.transportKey-1]; + } + } + else + { + std::pair<TypeToTransportMap::iterator, TypeToTransportMap::iterator> range(mTypeToTransportMap.equal_range(target)); + + if(range.first != range.second) // At least one match + { + TypeToTransportMap::iterator i=range.first; + ++i; + if(i==range.second) // Exactly one match + { + return range.first->second; + } + return i->second; + } + } + + // .bwc. No luck here. Maybe findTransportBySource will end up working. + return 0; +} + +/** + Search for Transport on any loopback interface matching {search}. + WATCHOUT: This is O(N) walk thru (nearly) all transports. +**/ +Transport* +TransportSelector::findLoopbackTransportBySource(bool ignorePort, Tuple& search) const +{ + //When we are sending to a loopback address, the kernel makes an + //(effectively) arbitrary choice of which loopback address to send + //from. (Since any loopback address can be used to send to any other + //loopback address) This choice may not agree with our idea of what + //address we should be sending from, so we need to just choose the + //loopback address we like, and ignore what the kernel told us to do. + ExactTupleMap::const_iterator i; + for (i=mExactTransports.begin();i != mExactTransports.end();i++) + { + DebugLog(<<"search: " << search << " elem: " << i->first); + if(i->first.ipVersion()==V4) + { + //Compare only the first byte (the 127) + if(i->first.isEqualWithMask(search,8,ignorePort)) + { + search=i->first; + DebugLog(<<"Match!"); + return i->second; + } + } +#ifdef USE_IPV6 + else if(i->first.ipVersion()==V6) + { + //What to do? + } +#endif + else + { + assert(0); + } + } + + return 0; +} // of findLoopbackTransport + +Transport* +TransportSelector::findTransportBySource(Tuple& search, const SipMessage* msg) const +{ + DebugLog(<< "findTransportBySource(" << search << ")"); + + if(msg && + !msg->getTlsDomain().empty() && + (search.getType()==TLS || search.getType()==DTLS)) + { + // We should not be willing to attempt sending on a TLS/DTLS transport + // that does not have the cert we're attempting to use, even if the + // IP/port/proto match. If we have not specified which identity we want + // to use, then proceed with the code below. + return findTlsTransport(msg->getTlsDomain(),search.getType(),search.ipVersion()); + } + + bool ignorePort = (search.getPort() == 0); + DebugLog(<< "should port be ignored: " << ignorePort); + + if (!ignorePort) + { + // 1. search for matching port on a specific interface + { + ExactTupleMap::const_iterator i = mExactTransports.find(search); + if (i != mExactTransports.end()) + { + DebugLog(<< "findTransport (exact) => " << *(i->second)); + return i->second; + } + } + + // 2. search for matching port on any loopback interface + if (search.isLoopback()) + { + Transport *trans=findLoopbackTransportBySource( /*ignorePort*/false, search); + if (trans) + { + return trans; + } + } + + // 3. search for specific port on ANY interface + { + AnyInterfaceTupleMap::const_iterator i = mAnyInterfaceTransports.find(search); + if (i != mAnyInterfaceTransports.end()) + { + DebugLog(<< "findTransport (any interface) => " << *(i->second)); + return i->second; + } + } + } + else + { + // 1. search for ANY port on specific interface + { + AnyPortTupleMap::const_iterator i = mAnyPortTransports.find(search); + if (i != mAnyPortTransports.end()) + { + DebugLog(<< "findTransport (any port, specific interface) => " << *(i->second)); + return i->second; + } + } + + // 2. search for ANY port on any loopback interface + if (search.isLoopback()) + { + Transport *trans = findLoopbackTransportBySource( /*ignorePort*/true, search); + if (trans) + { + return trans; + } + } + + // 3. search for ANY port on ANY interface + { + //CerrLog(<< "Trying AnyPortAnyInterfaceTupleMap " << mAnyPortAnyInterfaceTransports.size()); + AnyPortAnyInterfaceTupleMap::const_iterator i = mAnyPortAnyInterfaceTransports.find(search); + if (i != mAnyPortAnyInterfaceTransports.end()) + { + DebugLog(<< "findTransport (any port, any interface) => " << *(i->second)); + return i->second; + } + } + } + + DebugLog (<< "Exact interface / Specific port: " << Inserter(mExactTransports)); + DebugLog (<< "Any interface / Specific port: " << Inserter(mAnyInterfaceTransports)); + DebugLog (<< "Exact interface / Any port: " << Inserter(mAnyPortTransports)); + DebugLog (<< "Any interface / Any port: " << Inserter(mAnyPortAnyInterfaceTransports)); + + WarningLog(<< "Can't find matching transport " << search); + return 0; +} + + +Transport* +TransportSelector::findTlsTransport(const Data& domainname,resip::TransportType type,resip::IpVersion version) const +{ + assert(type==TLS || type==DTLS); + DebugLog (<< "Searching for " << ((type==TLS) ? "TLS" : "DTLS") << " transport for domain='" + << domainname << "'" << " have " << mTlsTransports.size()); + + if (domainname == Data::Empty) + { + for(TlsTransportMap::const_iterator i=mTlsTransports.begin(); + i!=mTlsTransports.end();++i) + { + if(i->first.mType==type && i->first.mVersion==version) + { + DebugLog(<<"Found a default transport."); + return i->second; + } + } + } + else + { + TlsTransportKey key(domainname,type,version); + + TlsTransportMap::const_iterator i=mTlsTransports.find(key); + + if(i!=mTlsTransports.end()) + { + DebugLog(<< "Found a transport."); + return i->second; + } + } + + DebugLog(<<"No transport found."); + return 0; +} + +unsigned int +TransportSelector::getTimeTillNextProcessMS() +{ + return hasDataToSend() ? 0 : INT_MAX; +} + +void +TransportSelector::registerMarkListener(MarkListener* listener) +{ + mDns.getMarkManager().registerMarkListener(listener); +} + +void TransportSelector::unregisterMarkListener(MarkListener* listener) +{ + mDns.getMarkManager().unregisterMarkListener(listener); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TransportSelector.hxx b/src/libs/resiprocate/resip/stack/TransportSelector.hxx new file mode 100644 index 00000000..6596f4c1 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransportSelector.hxx @@ -0,0 +1,307 @@ +#if !defined(RESIP_TRANSPORTSELECTOR_HXX) +#define RESIP_TRANSPORTSELECTOR_HXX + +#ifndef WIN32 +#include <sys/select.h> +#endif + +#include <map> +#include <vector> + +#include "rutil/Data.hxx" +#include "rutil/Fifo.hxx" +#include "rutil/GenericIPAddress.hxx" +#include "resip/stack/Transport.hxx" +#include "resip/stack/DnsInterface.hxx" +#include "rutil/SelectInterruptor.hxx" + + +#include "resip/stack/SecurityTypes.hxx" +class TestTransportSelector; + +namespace osc +{ + class Stack; +} + +namespace resip +{ + +class DnsHandler; +class Message; +class TransactionMessage; +class SipMessage; +class TransactionController; +class Security; +class Compression; +class FdPollGrp; + +/** + @internal + + TransportSelector has two distinct roles. The first is transmit on the best +outgoing Transport for a given SipMessage based on the target's TransportType +and the hints present in the topmost Via in the SipMessage. The second role +is to hold all Transports added to the SipStack, and if a given Transport returns +true for shareStackProcessAndSelect(), TransportSelector will include the +Transport in the FdSet processing loop. If the Transport returns false for +shareStackProcessAndSelect(), TransportSelector will call startOwnProcessing +on Transport add. + +*/ +class TransportSelector +{ + public: + TransportSelector(Fifo<TransactionMessage>& fifo, Security* security, DnsStub& dnsStub, Compression &compression); + virtual ~TransportSelector(); + /** + @retval true Some transport in the transport list has data to send + @retval false No transport in the transport list has data to send + */ + bool hasDataToSend() const; + + /** + Shuts down all transports. + */ + void shutdown(); + + /// Returns true if all Transports have their buffers cleared, false otherwise. + bool isFinished() const; + + /// Configure a PollGrp to use (instead of buildFdSet/process) + /// Must be called before adding any transports + void setPollGrp(FdPollGrp *pollGrp); + + /// Called when the TransportSelector will be running in a different + // thread than the TransactionController; this will allow the thread to be + // interrupted when poke() is called. + void createSelectInterruptor(); + + /// Calls process on all suitable transports + /// NOTE that TransportSelector no longer handles DNSInterface + /// NOTE not used with pollGrp + void process(FdSet& fdset); + void process(); + /// Builds an FdSet comprised of all FDs from all suitable Transports + void buildFdSet(FdSet& fdset); + + /// Causes transport process loops to be interrupted if there is stuff in + /// their transmit fifos. + void poke(); + void addTransport( std::auto_ptr<Transport> transport, bool immediate); + + DnsResult* createDnsResult(DnsHandler* handler); + + void dnsResolve(DnsResult* result, SipMessage* msg); + + /** + Results in msg->resolve() being called to either + kick off dns resolution or to pick the next tuple and will cause the + message to be encoded and via updated + */ + bool transmit( SipMessage* msg, Tuple& target, SendData* sendData=0 ); + + /// Resend to the same transport as last time + void retransmit(const SendData& msg); + + void closeConnection(const Tuple& peer); + + unsigned int sumTransportFifoSizes() const; + + unsigned int getTimeTillNextProcessMS(); + Fifo<TransactionMessage>& stateMacFifo() { return mStateMacFifo; } + + void registerMarkListener(MarkListener* listener); + void unregisterMarkListener(MarkListener* listener); + void setEnumSuffixes(const std::vector<Data>& suffixes); + + static Tuple getFirstInterface(bool is_v4, TransportType type); + void terminateFlow(const resip::Tuple& flow); + void enableFlowTimer(const resip::Tuple& flow); + + void setCongestionManager(CongestionManager* manager) + { + for(TransportList::iterator i=mSharedProcessTransports.begin(); + i!=mSharedProcessTransports.end();++i) + { + (*i)->setCongestionManager(manager); + } + + for(TransportList::iterator i=mHasOwnProcessTransports.begin(); + i!=mHasOwnProcessTransports.end();++i) + { + (*i)->setCongestionManager(manager); + } + } + + private: + void addTransportInternal( std::auto_ptr<Transport> transport); + void checkTransportAddQueue(); + Connection* findConnection(const Tuple& dest) const; + Transport* findTransportBySource(Tuple& src, const SipMessage* msg) const; + Transport* findLoopbackTransportBySource(bool ignorePort, Tuple& src) const; + Transport* findTransportByDest(const Tuple& dest); + Transport* findTransportByVia(SipMessage* msg, const Tuple& dest, + Tuple& src) const; + Transport* findTlsTransport(const Data& domain,TransportType type,IpVersion ipv) const; + Tuple determineSourceInterface(SipMessage* msg, const Tuple& dest) const; + + DnsInterface mDns; + Fifo<TransactionMessage>& mStateMacFifo; + Security* mSecurity;// for computing identity header + + // specific port and interface + typedef std::map<Tuple, Transport*> ExactTupleMap; + ExactTupleMap mExactTransports; + + // specific port, ANY interface + typedef std::map<Tuple, Transport*, Tuple::AnyInterfaceCompare> AnyInterfaceTupleMap; + AnyInterfaceTupleMap mAnyInterfaceTransports; + + // ANY port, specific interface + typedef std::map<Tuple, Transport*, Tuple::AnyPortCompare> AnyPortTupleMap; + AnyPortTupleMap mAnyPortTransports; + + // ANY port, ANY interface + typedef std::map<Tuple, Transport*, Tuple::AnyPortAnyInterfaceCompare> AnyPortAnyInterfaceTupleMap; + AnyPortAnyInterfaceTupleMap mAnyPortAnyInterfaceTransports; + + std::vector<Transport*> mTransports; // owns all Transports + + /** + @internal + */ + class TlsTransportKey + { + public: + TlsTransportKey(const resip::Data& domain, resip::TransportType type, resip::IpVersion version) + :mDomain(domain), + mType(type), + mVersion(version) + {} + + TlsTransportKey(const TlsTransportKey& orig) + { + mDomain=orig.mDomain; + mType=orig.mType; + mVersion=orig.mVersion; + } + + ~TlsTransportKey(){} + bool operator<(const TlsTransportKey& rhs) const + { + if(mDomain < rhs.mDomain) + { + return true; + } + else if(mDomain == rhs.mDomain) + { + if(mType < rhs.mType) + { + return true; + } + else if(mType == rhs.mType) + { + return mVersion < rhs.mVersion; + } + } + return false; + } + + resip::Data mDomain; + resip::TransportType mType; + resip::IpVersion mVersion; + + private: + TlsTransportKey(); + }; + + typedef std::map<TlsTransportKey, Transport*> TlsTransportMap ; + + TlsTransportMap mTlsTransports; + + typedef std::vector<Transport*> TransportList; + TransportList mSharedProcessTransports; + TransportList mHasOwnProcessTransports; + + typedef std::multimap<Tuple, Transport*, Tuple::AnyPortAnyInterfaceCompare> TypeToTransportMap; + TypeToTransportMap mTypeToTransportMap; + + // fake socket for connect() and route table lookups + mutable Socket mSocket; + mutable Socket mSocket6; + + // An AF_UNSPEC addr_in for rapid unconnect + GenericIPAddress mUnspecified; + GenericIPAddress mUnspecified6; + + /// SigComp configuration object + Compression &mCompression; + osc::Stack *mSigcompStack; + + // epoll support, for sharedprocess transports + FdPollGrp* mPollGrp; + + int mAvgBufferSize; + Fifo<Transport> mTransportsToAdd; + std::auto_ptr<SelectInterruptor> mSelectInterruptor; + FdPollItemHandle mInterruptorHandle; + + friend class TestTransportSelector; + friend class SipStack; // for debug only +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TransportSelectorThread.hxx b/src/libs/resiprocate/resip/stack/TransportSelectorThread.hxx new file mode 100644 index 00000000..29a830d4 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransportSelectorThread.hxx @@ -0,0 +1,109 @@ +#ifndef TransportSelectorThread_Include_Guard +#define TransportSelectorThread_Include_Guard + +#include "rutil/FdPoll.hxx" +#include "rutil/ThreadIf.hxx" + +#include "resip/stack/TransportSelector.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +namespace resip +{ +class TransportSelectorThread : public ThreadIf +{ + public: + explicit TransportSelectorThread(TransportSelector& selector): + mSelector(selector), + mPollGrp(FdPollGrp::create()) + { + mSelector.setPollGrp(mPollGrp.get()); + mSelector.createSelectInterruptor(); + } + virtual ~TransportSelectorThread() + { + mSelector.setPollGrp(0); + } + + +/////////////////// Must implement unless abstract /// + + virtual void thread() + { + while(!isShutdown()) + { + try + { + mSelector.process(); + if (mPollGrp.get()) + mPollGrp->waitAndProcess(25); + } + catch(BaseException& e) + { + ErrLog(<< "Unhandled exception: " << e); + } + } + } + + protected: + TransportSelector& mSelector; + std::auto_ptr<FdPollGrp> mPollGrp; + +}; // class TransportSelectorThread + +} // namespace resip + +#endif // include guard + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TransportThread.cxx b/src/libs/resiprocate/resip/stack/TransportThread.cxx new file mode 100644 index 00000000..4691ba72 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransportThread.cxx @@ -0,0 +1,96 @@ +#include "resip/stack/TransportThread.hxx" + +#include "resip/stack/Transport.hxx" + +#include "rutil/FdPoll.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +namespace resip +{ +TransportThread::TransportThread(Transport& transport) : + mTransport(transport), + mPollGrp(FdPollGrp::create()) +{ + // ?bwc? Allow creator to specify the FdPollGrp? + mTransport.setPollGrp(mPollGrp.get()); +} + +TransportThread::~TransportThread() +{ + mTransport.setPollGrp(0); +} + +void +TransportThread::thread() +{ + while(!isShutdown()) + { + try + { + mTransport.process(); + if (mPollGrp.get()) + mPollGrp->waitAndProcess(25); + } + catch(BaseException& e) + { + ErrLog(<< "Unhandled exception: " << e); + } + } + WarningLog(<< "Shutting down transport thread"); +} + +} // of namespace resip + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TransportThread.hxx b/src/libs/resiprocate/resip/stack/TransportThread.hxx new file mode 100644 index 00000000..8090b812 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TransportThread.hxx @@ -0,0 +1,80 @@ +#ifndef TransportThread_Include_Guard +#define TransportThread_Include_Guard + +#include <memory> +#include "rutil/ThreadIf.hxx" + +namespace resip +{ +class FdPollGrp; +class Transport; +class TransportThread : public ThreadIf +{ + public: + explicit TransportThread(Transport& transport); + virtual ~TransportThread(); + +/////////////////// Must implement unless abstract /// + + virtual void thread() ; + + protected: + Transport& mTransport; + std::auto_ptr<FdPollGrp> mPollGrp; +}; // class TransportThread + +} // namespace resip + +#endif // include guard + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TuIM.cxx b/src/libs/resiprocate/resip/stack/TuIM.cxx new file mode 100644 index 00000000..c5d559bd --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TuIM.cxx @@ -0,0 +1,1501 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +/* TODO list for this file .... + handle 302 in message + handle 302 in subscribe + + sort out how contact is formed + keep track of ourstanding message dialogs + add a publish sending dialogs + send options to register, see if do publish, if so use + + suppport loading destination certificates from server +*/ + +#include <cassert> +#include <memory> + +#include "resip/stack/SipStack.hxx" +#include "resip/stack/DeprecatedDialog.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/TuIM.hxx" +#include "resip/stack/Contents.hxx" +#include "resip/stack/ParserCategories.hxx" +#include "resip/stack/PlainContents.hxx" +#include "resip/stack/CpimContents.hxx" +#include "resip/stack/Pkcs7Contents.hxx" +#include "resip/stack/MultipartSignedContents.hxx" +#include "resip/stack/MultipartMixedContents.hxx" +#include "resip/stack/OctetContents.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/Pidf.hxx" +#include "resip/stack/SipFrag.hxx" +#include "rutil/Data.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Random.hxx" +#include "rutil/Socket.hxx" +#include "rutil/WinLeakCheck.hxx" + +#ifdef USE_SSL +#include "resip/stack/ssl/Security.hxx" +#endif + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +using namespace resip; +using namespace std; + +static int IMMethodList[] = { (int) REGISTER, + (int) MESSAGE, + (int) SUBSCRIBE, + (int) NOTIFY }; +const int IMMethodListSize = sizeof(IMMethodList) / sizeof(*IMMethodList); + + +TuIM::Callback::~Callback() +{ +} + + +TuIM::TuIM(SipStack* stack, + const Uri& aor, + const Uri& contact, + Callback* callback, + const int registrationTimeSeconds, + const int subscriptionTimeSeconds) + : mCallback(callback), + mStack(stack), + mAor(aor), + mContact(contact), + mPidf( new Pidf ), + mRegistrationDialog(NameAddr(contact)), + mNextTimeToRegister(0), + mRegistrationPassword( Data::Empty ), + mLastAuthCSeq(0), + mRegistrationTimeSeconds(registrationTimeSeconds), + mSubscriptionTimeSeconds(subscriptionTimeSeconds), + mDefaultProtocol( UNKNOWN_TRANSPORT ) +{ + assert( mStack ); + assert(mCallback); + assert(mPidf); + + mPidf->setSimpleId( Random::getRandomHex(4) ); + mPidf->setEntity(mAor); + mPidf->setSimpleStatus( true, Data::Empty, mContact.getAor() ); +} + + +bool +TuIM::haveCerts( bool sign, const Data& encryptFor ) +{ +/* assert(0); */ + +#if defined( USE_SSL ) + Security* sec = mStack->getSecurity(); + assert(sec); + + if ( sign ) + { + if ( !sec->hasUserPrivateKey(mAor.getAor()) ) + { + return false; + } + } + if ( !encryptFor.empty() ) + { + if ( !sec->hasUserCert( encryptFor ) ) + { + return false; + } + } +#else + if ( (!encryptFor.empty()) || (sign) ) + { + return false; + } +#endif + return true; +} + + +void +TuIM::sendPage(const Data& text, const Uri& dest, + const bool sign, const Data& encryptFor) +{ + if ( text.empty() ) + { + DebugLog( << "tried to send blank message - dropped " ); + return; + } + DebugLog( << "send to <" << dest << ">" << "\n" << text ); + + NameAddr target; + target.uri() = dest; + + NameAddr from; + from.uri() = mAor; + + NameAddr contact; + contact.uri() = mContact; + + DeprecatedDialog* dialog = new DeprecatedDialog( NameAddr(mContact) ); + + auto_ptr<SipMessage> msg( dialog->makeInitialMessage(NameAddr(target),NameAddr(from)) ); + + Page page; + page.text = text; + page.uri = dest; + page.sign = sign; + page.encryptFor = encryptFor; + page.dialog = dialog; + + mPages.push_back(page); + + Contents* body = ( new PlainContents(text) ); +#if 1 + msg->header(h_ContentTransferEncoding) = StringCategory(Data("binary")); +#endif + +#if defined( USE_SSL ) + if ( !encryptFor.empty() ) + { + Security* sec = mStack->getSecurity(); + assert(sec); + + Contents* old = body; + old->header(h_ContentTransferEncoding) = msg->header(h_ContentTransferEncoding); + body = sec->encrypt( old, encryptFor ); + delete old; + + if ( !body ) + { + mCallback->sendPageFailed( dest, -2 ); + return; + } + +#if 0 + msg->header(h_ContentTransferEncoding) = StringCategory(Data("binary")); +#endif + } + + if ( sign ) + { + Security* sec = mStack->getSecurity(); + assert(sec); + + Contents* old = body; + old->header(h_ContentTransferEncoding) = msg->header(h_ContentTransferEncoding); + body = sec->sign( mAor.getAor(), old ); + delete old; + + if ( !body ) + { + mCallback->sendPageFailed( dest, -1 ); + return; + } + +#if 0 + msg->header(h_ContentTransferEncoding) = StringCategory(Data("binary")); +#endif + } +#endif + + msg->setContents(body); + + if (1) // Compute the identity header. + { + //Security* sec = mStack->getSecurity(); + //assert(sec); + + DateCategory now; + msg->header(h_Date) = now; + + //Data token = msg->getCanonicalIdentityString(); + //Data res = sec->computeIdentity( token ); + + msg->header(h_Identity).value() = Data::Empty; + } + + setOutbound( *msg ); + //ErrLog( "About to send " << *msg ); + + mStack->send( *msg ); + + delete body; +} + + +void +TuIM::processRequest(SipMessage* msg) +{ + if ( msg->header(h_RequestLine).getMethod() == MESSAGE ) + { + processMessageRequest(msg); + return; + } + if ( msg->header(h_RequestLine).getMethod() == SUBSCRIBE ) + { + processSubscribeRequest(msg); + return; + } + if ( msg->header(h_RequestLine).getMethod() == REGISTER ) + { + processRegisterRequest(msg); + return; + } + if ( msg->header(h_RequestLine).getMethod() == NOTIFY ) + { + processNotifyRequest(msg); + return; + } + + InfoLog(<< "Don't support this METHOD, send 405" ); + + SipMessage * resp = Helper::make405( *msg, IMMethodList, IMMethodListSize ); + mStack->send(*resp); + delete resp; +} + + +void +TuIM::processSipFrag(SipMessage* msg) +{ + Contents* contents = msg->getContents(); + if ( !contents ) + { + InfoLog(<< "Received message with no contents" ); + return; + } + + InfoLog(<< "Received message with body contents" ); + + assert( contents ); + Mime mime = contents->getType(); + DebugLog ( << "got body of type " << mime.type() << "/" << mime.subType() ); + + Data signedBy; + +#if defined( USE_SSL ) + SignatureStatus sigStat = SignatureNone; + MultipartSignedContents* mBody = dynamic_cast<MultipartSignedContents*>(contents); + if ( mBody ) + { + Security* sec = mStack->getSecurity(); + assert(sec); + + contents = sec->checkSignature( mBody, &signedBy, &sigStat ); + + if ( !contents ) + { + InfoLog( << "Some problem decoding multipart/signed message"); + return; + } + + InfoLog( << "Signed by " << signedBy << " stat = " << sigStat ); + } +#endif + + if ( contents ) + { + MultipartMixedContents* mixed = dynamic_cast<MultipartMixedContents*>(contents); + if ( mixed ) + { + InfoLog( << "Got a multipart mixed" ); + + contents = NULL; + + MultipartMixedContents::Parts& parts = mixed->parts(); + for( MultipartMixedContents::Parts::const_iterator i = parts.begin(); + i != parts.end(); + ++i) + { + Contents* c = *i; + assert( c ); + InfoLog ( << "mixed has a " << c->getType() ); + + if ( c->getType() == Mime("application","sipfrag") ) + { + InfoLog ( << "mixed has sipfrag " << c->getType() ); + + SipFrag* frag = dynamic_cast<SipFrag*>(c); + if ( frag ) + { + InfoLog( << "Got a sipFrag inside mixed" ); + + SipMessage& m = frag->message(); + + InfoLog( <<"Frag is " << m ); + } + } + } + } + } + + if ( contents ) + { + SipFrag* frag = dynamic_cast<SipFrag*>(contents); + if ( frag ) + { + InfoLog( << "Got a sipFrag" ); + + SipMessage& m = frag->message(); + + InfoLog( <<"Frag is " << m ); + } + else + { + InfoLog ( << "Can not handle type " << contents->getType() ); + + return; + } + } +} + + +void +TuIM::processSubscribeRequest(SipMessage* msg) +{ + assert( msg->header(h_RequestLine).getMethod() == SUBSCRIBE ); + CallId id = msg->header(h_CallId); + + processSipFrag( msg ); + + int expires=mSubscriptionTimeSeconds; + if ( msg->exists(h_Expires) ) + { + expires = msg->header(h_Expires).value(); + } + if (expires > mSubscriptionTimeSeconds ) + { + expires = mSubscriptionTimeSeconds; + } + + DeprecatedDialog* dialog = NULL; + + // see if we already have this subscription + for ( SubscriberIterator i=mSubscribers.begin(); i != mSubscribers.end(); i++) + { + DeprecatedDialog* d = i->dialog; + assert( d ); + + if ( d->getCallId() == id ) + { + // found the subscrition in list of current subscrbtions + dialog = d; + break; + } + } + + if ( !dialog ) + { + // create a new subscriber + DebugLog ( << "Creating new subscrition dialog "); + + Subscriber s; + + s.dialog = new DeprecatedDialog( NameAddr(mContact) ); + dialog = s.dialog; + + Uri from = msg->header(h_From).uri(); + s.aor = from.getAorNoPort(); + + assert( mCallback ); + s.authorized = mCallback->authorizeSubscription( from ); + + mSubscribers.push_back( s ); + } + + assert( dialog ); + dialog->setExpirySeconds( expires ); + + auto_ptr<SipMessage> response( dialog->makeResponse( *msg, 200 )); + + response->header(h_Expires).value() = expires; + response->header(h_Event).value() = Data("presence"); + + mStack->send( *response ); + + sendNotify( dialog ); + +#if 1 + // do symetric subscriptions + // See if this person is our buddy list and if we are not subscribed to them + + UInt64 now = Timer::getTimeMs(); + Uri from = msg->header(h_From).uri(); + + for ( BuddyIterator i=mBuddies.begin(); i != mBuddies.end(); i++) + { + Data buddyAor = i->uri.getAor(); + + if ( ! (i->presDialog->isCreated()) ) + { + if ( from.getAor() == i->uri.getAor() ) + { + if ( from.getAor() != mAor.getAor() ) + { + i->mNextTimeToSubscribe = now; + } + } + } + } +#endif +} + + +void +TuIM::processRegisterRequest(SipMessage* msg) +{ + assert( msg->header(h_RequestLine).getMethod() == REGISTER ); + CallId id = msg->header(h_CallId); + + int expires = msg->header(h_Expires).value(); + if ( expires == 0 ) + { + expires = 3600; + } + + SipMessage* response = Helper::makeResponse( *msg, 200 ); + + // the Contacts from the default Helper are wrong for a Registration + response->remove(h_Contacts); + + if ( msg->exists(h_Contacts) ) + { + ParserContainer<NameAddr> &providedContacts(msg->header(h_Contacts)); + + int multipleContacts = (int)providedContacts.size(); + + DebugLog ( << multipleContacts << " contacts were in received message." ); + + ParserContainer<NameAddr>::iterator i(providedContacts.begin()); + for ( ; i != providedContacts.end() ; ++ i) { + if ( i->isAllContacts() && multipleContacts ) // oops, multiple Contacts and one is "*" + { + delete response; // do I need to do this? + response = Helper::makeResponse( *msg, 400 ); + mStack->send( *response ); + delete response; + return; + } + if ( !i->exists(p_expires) ) // add expires params where they don't exist + { + i->param(p_expires) = expires; + } + response->header(h_Contacts).push_back(*i); // copy each Contact into response + } + } + // else the REGISTER is a query, just send the message with no Contacts + + mStack->send( *response ); + + delete response; +} + + +void +TuIM::processNotifyRequest(SipMessage* msg) +{ + assert( mCallback ); + assert( msg->header(h_RequestLine).getMethod() == NOTIFY ); + + processSipFrag( msg ); + + auto_ptr<SipMessage> response( Helper::makeResponse( *msg, 200 )); + mStack->send( *response ); + + Uri from = msg->header(h_From).uri(); + DebugLog ( << "got notify from " << from ); + + Contents* contents = msg->getContents(); + if ( !contents ) + { + InfoLog(<< "Received NOTIFY message event with no contents" ); + mCallback->presenceUpdate( from, true, Data::Empty ); + return; + } + + Mime mime = contents->getType(); + DebugLog ( << "got NOTIFY event with body of type " << mime.type() << "/" << mime.subType() ); + + Pidf* body = dynamic_cast<Pidf*>(contents); + if ( !body ) + { + InfoLog(<< "Received NOTIFY message event with no PIDF contents" ); + mCallback->presenceUpdate( from, true, Data::Empty ); + return; + } + + Data note; + bool open = body->getSimpleStatus( &note ); + + bool changed = true; + + + // update if found in budy list + for ( BuddyIterator i=mBuddies.begin(); i != mBuddies.end(); i++) + { + Uri u = i->uri; // getBuddyUri(i); + + if ( u.getAor() == from.getAor() ) + { + + if ( (i->status == note) && + (i->online == open) ) + { + changed = false; + } + + i->status = note; + i->online = open; + } + } + + InfoLog(<< "Processed NOTIFY message : Presence changed: " << changed ); + // notify callback + if (changed) + { + assert(mCallback); + mCallback->presenceUpdate( from, open, note ); + } +} + + +void +TuIM::processMessageRequest(SipMessage* msg) +{ + assert( msg ); + assert( msg->header(h_RequestLine).getMethod() == MESSAGE ); + + NameAddr contact; + contact.uri() = mContact; + + SipMessage* response = Helper::makeResponse(*msg, 200, contact, "OK"); + mStack->send( *response ); + delete response; response=0; + + Contents* contents = msg->getContents(); + if ( !contents ) + { + InfoLog(<< "Received Message message with no contents" ); + // .kw. NO: delete msg; msg=0; // our caller owns msg + return; + } + + Mime mime = contents->getType(); + DebugLog ( << "got body of type " << mime.type() << "/" << mime.subType() ); + + Data signedBy; + SignatureStatus sigStat = SignatureNone; + bool encrypted=false; + +#if defined( USE_SSL ) + Uri from = msg->header(h_From).uri(); + signedBy = from.getAorNoPort(); + + InfoLog ( << "assuming signedBy is " << signedBy ); + + MultipartSignedContents* mBody = dynamic_cast<MultipartSignedContents*>(contents); + if ( mBody ) + { + Security* sec = mStack->getSecurity(); + assert(sec); + + contents = sec->checkSignature( mBody, &signedBy, &sigStat ); + + //ErrLog("Signed by " << signedBy << " stat = " << sigStat ); + + if ( !contents ) + { + Uri from = msg->header(h_From).uri(); + InfoLog( << "Some problem decoding multipart/signed message"); + + mCallback->receivePageFailed( from ); + return; + } + } + + Pkcs7SignedContents* sBody = dynamic_cast<Pkcs7SignedContents*>(contents); + if ( sBody ) + { + assert( sBody ); + Security* sec = mStack->getSecurity(); + assert(sec); + + contents = sec->decrypt( mAor.getAor(), sBody ); + + if ( !contents ) + { + Uri from = msg->header(h_From).uri(); + InfoLog( << "Some problem decoding signed SMIME message"); + + mCallback->receivePageFailed( from ); + return; + } + + encrypted=true; + } + + Pkcs7Contents* eBody = dynamic_cast<Pkcs7Contents*>(contents); + if ( eBody ) + { + assert( eBody ); + Security* sec = mStack->getSecurity(); + assert(sec); + + contents = sec->decrypt( mAor.getAor(), eBody ); + + if ( !contents ) + { + Uri from = msg->header(h_From).uri(); + InfoLog( << "Some problem decoding SMIME message"); + + mCallback->receivePageFailed( from ); + return; + } + + encrypted=true; + } + +#endif + + if ( contents ) + { + PlainContents* plain = dynamic_cast<PlainContents*>(contents); + if ( plain ) + { + assert( plain ); + const Data& text = plain->text(); + DebugLog ( << "got message from with text of <" << text << ">" ); + + Uri from = msg->header(h_From).uri(); + DebugLog ( << "got message from " << from ); + + assert( mCallback ); + mCallback->receivedPage( text, from, signedBy, sigStat, encrypted ); + return; + } + + CpimContents* cpim = dynamic_cast<CpimContents*>(contents); + if ( cpim ) + { + assert( cpim ); + const Data& text = cpim->text(); + DebugLog ( << "got CPIM message from with text of <" << text << ">" ); + + // !cj! TODO - should get from out of CPIM message + Uri from = msg->header(h_From).uri(); + DebugLog ( << "got message from " << from ); + + assert( mCallback ); + mCallback->receivedPage( text, from, signedBy, sigStat, encrypted ); + return; + } + + MultipartMixedContents* mixed = dynamic_cast<MultipartMixedContents*>(contents); + if ( mixed ) + { + InfoLog( << "Got a multipart mixed" ); + + contents = NULL; + + MultipartMixedContents::Parts& parts = mixed->parts(); + for( MultipartMixedContents::Parts::const_iterator i = parts.begin(); + i != parts.end(); + ++i) + { + Contents* c = *i; + assert( c ); + InfoLog ( << "mixed has a " << c->getType() ); + + if ( c->getType() == Mime("text","plain") ) + { + InfoLog ( << "mixed has sipfrag " << c->getType() ); + + PlainContents* plainBody = dynamic_cast<PlainContents*>(c); + if ( plainBody ) + { + assert( plainBody ); + const Data& text = plainBody->text(); + DebugLog ( << "got message from with text of <" << text << ">" ); + + Uri from = msg->header(h_From).uri(); + DebugLog ( << "got message from " << from ); + + assert( mCallback ); + mCallback->receivedPage( text, from, signedBy, sigStat, encrypted ); + return; + } + + // !cj! TODO - should deal with CPIM too + } + + } + + return; + } + +#if 1 // !cj! TODO remove + OctetContents* octets = dynamic_cast<OctetContents*>(contents); + if (octets) + { + assert( contents ); + const Data& text = octets->getBodyData(); + DebugLog ( << "got message from with text of <" << text << ">" ); + + Uri from = msg->header(h_From).uri(); + DebugLog ( << "got message from " << from ); + + assert( mCallback ); + mCallback->receivedPage( text, from, signedBy, sigStat, encrypted ); + return; + } +#endif + + // deal with it if no one else has + { + InfoLog ( << "Can not handle type " << contents->getType() ); + Uri from = msg->header(h_From).uri(); + mCallback->receivePageFailed( from ); + return; + } + } +} + + +void +TuIM::processResponse(SipMessage* msg) +{ + assert( msg->exists(h_CallId)); + CallId id = msg->header(h_CallId); + assert( id.value() != Data::Empty ); + + processSipFrag( msg ); + + // see if it is a registraition response + CallId regId = mRegistrationDialog.getCallId(); + + Data v1 = id.value(); + Data v2 = regId.value(); + + InfoLog( << "want id =" << id ); + + if ( id == regId ) + { + InfoLog ( << "matched the reg dialog" + << mRegistrationDialog.getCallId() << " = " << id ); + processRegisterResponse( msg ); + return; + } + + // see if it is a subscribe response + for ( BuddyIterator i=mBuddies.begin(); i != mBuddies.end(); i++) + { + Buddy& buddy = *i; + assert( buddy.presDialog ); + InfoLog( << "check buddy id =" << buddy.presDialog->getCallId() ); + if ( buddy.presDialog->getCallId() == id ) + { + DebugLog ( << "matched the subscribe dialog" ); + processSubscribeResponse( msg, buddy ); + return; + } + } + + // see if it is a publish response + for ( StateAgentIterator i=mStateAgents.begin(); i != mStateAgents.end(); i++) + { + assert( i->dialog ); + InfoLog( << "check publish id =" << i->dialog->getCallId() ); + if ( i->dialog->getCallId() == id ) + { + DebugLog ( << "matched the publish dialog" ); + processPublishResponse( msg, *i ); + return; + } + } + + // see if it is a notify response + for ( SubscriberIterator i=mSubscribers.begin(); i != mSubscribers.end(); i++) + { + DeprecatedDialog* dialog = i->dialog; + assert( dialog ); + InfoLog( << "check subscriber id =" << dialog->getCallId() ); + if ( dialog->getCallId() == id ) + { + DebugLog ( << "matched the notify dialog" ); + processNotifyResponse( msg, *dialog ); + return; + } + } + + // see if it is a page response + for ( PageIterator i=mPages.begin(); i != mPages.end(); i++) + { + assert( i->dialog ); + InfoLog( << "check page id =" << i->dialog->getCallId() ); + if ( i->dialog->getCallId() == id ) + { + DebugLog ( << "matched the MESSAGE dialog" ); + processPageResponse( msg, *i ); + return; + } + } + + int number = msg->header(h_StatusLine).responseCode(); + InfoLog( << "got response that DID NOT MATCH of type " << number ); +} + + +void +TuIM::processRegisterResponse(SipMessage* msg) +{ + int number = msg->header(h_StatusLine).responseCode(); + Uri to = msg->header(h_To).uri(); + InfoLog ( << "register of " << to << " got response " << number ); + unsigned int cSeq = msg->header(h_CSeq).sequence(); + + if ( number<200 ) + { + return; + } + + if ( number >= 200 ) + { + mRegistrationDialog.createDialogAsUAC( *msg ); + } + + if ( ((number == 401) || (number == 407)) && (cSeq != mLastAuthCSeq) ) + { + SipMessage* reg = mRegistrationDialog.makeRegister(); + + const Data cnonce = Data::Empty; + unsigned int nonceCount=0; + + Helper::addAuthorization(*reg,*msg,mAor.user(),mRegistrationPassword,cnonce,nonceCount); + + mLastAuthCSeq = reg->header(h_CSeq).sequence(); + + reg->header(h_Expires).value() = mRegistrationTimeSeconds; + reg->header(h_Contacts).front().param(p_expires) = mRegistrationTimeSeconds; + + mNextTimeToRegister = Timer::getRandomFutureTimeMs( mRegistrationTimeSeconds*1000 ); + + InfoLog( << *reg ); + + setOutbound( *reg ); + + mStack->send( *reg ); + + delete reg; reg=NULL; + + return; + } + + if ( number >= 300 ) + { + assert( mCallback ); + mCallback->registrationFailed( to, number ); + return; + } + + if ( (number>=200) && (number<300) ) + { + int expires = mRegistrationTimeSeconds; + + if ( msg->exists(h_Expires) ) + { + expires = msg->header(h_Expires).value(); + } + + // loop throught the contacts, find me, and extract expire time + resip::ParserContainer<resip::NameAddr>::iterator i = msg->header(h_Contacts).begin(); + while ( i != msg->header(h_Contacts).end() ) + { + try + { + Uri uri = i->uri(); + + if ( uri.getAor() == mContact.getAor() ) + { + int e = i->param(p_expires); + DebugLog(<< "match " << uri.getAor() << " e=" << e ); + + expires = e; + } + } + catch ( exception* ) + { + InfoLog(<< "Bad contact in 2xx to register - skipped" ); + } + + i++; + } + + if ( expires < 15 ) + { + InfoLog(<< "Got very small expiers of " << expires ); + expires = 15; + } + + mNextTimeToRegister = Timer::getRandomFutureTimeMs( expires*1000 ); + + mCallback->registrationWorked( to ); + + return; + } +} + + +void +TuIM::processNotifyResponse(SipMessage* msg, DeprecatedDialog& d ) +{ + int number = msg->header(h_StatusLine).responseCode(); + DebugLog( << "got NOTIFY response of type " << number ); + + if ( number >= 300 ) + { + // TODO + } +} + + +void +TuIM::processPublishResponse(SipMessage* msg, StateAgent& sa ) +{ + int number = msg->header(h_StatusLine).responseCode(); + DebugLog( << "got PUBLISH response of type " << number ); + + if ( number >= 300 ) + { + // TODO + } +} + + +void +TuIM::processPageResponse(SipMessage* msg, Page& page ) +{ + int number = msg->header(h_StatusLine).responseCode(); + DebugLog( << "got MESSAGE response of type " << number ); + + if ( number >= 400 ) + { + Uri dest = msg->header(h_To).uri(); + assert( mCallback ); + mCallback->sendPageFailed( dest,number ); + } + + if ( (number>=300) && (number<400) ) + { + ParserContainer<NameAddr>::iterator dest = msg->header(h_Contacts).begin(); + while ( dest != msg->header(h_Contacts).end() ) + { + DebugLog(<< "Got a 3xx to" << *dest ); + + // send a message to redirected location + Uri uri = dest->uri(); + sendPage( page.text, uri, page.sign, page.encryptFor ); + + dest++; + } + } + + if ( (number>=200) && (number<300) ) + { + // got a final response for notify - can remove this dialog information + CallId id = msg->header(h_CallId); + + for( PageIterator i=mPages.begin(); i != mPages.end(); i++ ) + { + if ( i->dialog->getCallId() == id ) + { + i = mPages.erase( i ); + } + } + } +} + + +void +TuIM::processSubscribeResponse(SipMessage* msg, Buddy& buddy) +{ + int number = msg->header(h_StatusLine).responseCode(); + Uri to = msg->header(h_To).uri(); + InfoLog ( << "subscribe got response " << number << " from " << to ); + + if ( (number>=200) && (number<300) ) + { + int expires = mSubscriptionTimeSeconds; + if ( msg->exists(h_Expires) ) + { + expires = msg->header(h_Expires).value(); + } + if ( expires < 15 ) + { + InfoLog( << "Got very small expiers of " << expires ); + expires = 15; + } + + assert( buddy.presDialog ); + buddy.presDialog->createDialogAsUAC( *msg ); + + buddy.mNextTimeToSubscribe = Timer::getRandomFutureTimeMs( expires*1000 ); + } + + if ( (number>=300) && (number<400) ) + { + ParserContainer<NameAddr>::iterator dest = msg->header(h_Contacts).begin(); + while ( dest != msg->header(h_Contacts).end() ) + { + DebugLog(<< "Got a 3xx to" << *dest ); + Uri uri = dest->uri(); + + addBuddy( uri , buddy.group ); + + buddy.mNextTimeToSubscribe = Timer::getForever(); + + dest++; + } + } + + if ( (number>=400) ) + { + DebugLog( << "Got an error to some subscription" ); + + // take this buddy off line + Uri to = msg->header(h_To).uri(); + assert( mCallback ); + + bool changed = true; + + for ( BuddyIterator i=mBuddies.begin(); i != mBuddies.end(); i++) + { + Uri u = i->uri; // getBuddyUri(i); + + if ( u.getAor() == to.getAor() ) + { + if ( i->online == false ) + { + changed = false; + } + + i->online = false; + } + } + + if ( changed ) + { + mCallback->presenceUpdate( to, false, Data::Empty ); + } + + // try to contact this buddy again later + buddy.mNextTimeToSubscribe = Timer::getRandomFutureTimeMs( mSubscriptionTimeSeconds*1000 ); + } +} + + +void +TuIM::process() +{ + assert( mStack ); + + UInt64 now = Timer::getTimeMs(); + + // check if register needs refresh + if ( now > mNextTimeToRegister ) + { + if ( mRegistrationDialog.isCreated() ) + { + auto_ptr<SipMessage> msg( mRegistrationDialog.makeRegister() ); + msg->header(h_Expires).value() = mRegistrationTimeSeconds; + setOutbound( *msg ); + mStack->send( *msg ); + } + mNextTimeToRegister = Timer::getRandomFutureTimeMs( mRegistrationTimeSeconds*1000 ); + } + + // check if any subscribes need refresh + for ( BuddyIterator i=mBuddies.begin(); i != mBuddies.end(); i++) + { + if ( now > i->mNextTimeToSubscribe ) + { + Buddy& buddy = *i; + + buddy.mNextTimeToSubscribe + = Timer::getRandomFutureTimeMs( mSubscriptionTimeSeconds*1000 ); + + assert( buddy.presDialog ); + if ( buddy.presDialog->isCreated() ) + { + auto_ptr<SipMessage> msg( buddy.presDialog->makeSubscribe() ); + + msg->header(h_Event).value() = Data("presence");; + msg->header(h_Accepts).push_back( Mime( "application","pidf+xml") ); + msg->header(h_Expires).value() = mSubscriptionTimeSeconds; + + setOutbound( *msg ); + + mStack->send( *msg ); + } + else + { + // person was not available last time - try to subscribe now + subscribeBuddy( buddy ); + } + } + } + + // TODO - go and clean out any subscrption to us that have expired + + // check for any messages from the sip stack + SipMessage* msg( mStack->receive() ); + if ( msg ) + { + DebugLog ( << "got message: " << *msg); + + if ( msg->isResponse() ) + { + processResponse( msg ); + } + + if ( msg->isRequest() ) + { + processRequest( msg ); + } + + delete msg; msg=0; + } +} + + +void +TuIM::registerAor( const Uri& uri, const Data& password ) +{ + mRegistrationPassword = password; + + //const NameAddr aorName; + //const NameAddr contactName; + //aorName.uri() = uri; + //contactName.uri() = mContact; + //SipMessage* msg = Helper::makeRegister(aorName,aorName,contactName); + + auto_ptr<SipMessage> msg( mRegistrationDialog.makeInitialRegister(NameAddr(uri),NameAddr(uri)) ); + + msg->header(h_Expires).value() = mRegistrationTimeSeconds; + msg->header(h_Contacts).front().param(p_expires) = mRegistrationTimeSeconds; + + Token t; + t = Token(Data("presence")); + msg->header(h_AllowEvents).push_back( t ); + + mNextTimeToRegister = Timer::getRandomFutureTimeMs( mRegistrationTimeSeconds*1000 ); + + setOutbound( *msg ); + + mStack->send( *msg ); +} + + +int +TuIM::getNumBuddies() const +{ + return int(mBuddies.size()); +} + + +const Uri +TuIM::getBuddyUri(const int index) +{ + assert( index >= 0 ); + assert( index < getNumBuddies() ); + + return mBuddies[index].uri; +} + + +const Data +TuIM::getBuddyGroup(const int index) +{ + assert( index >= 0 ); + assert( index < getNumBuddies() ); + + return mBuddies[index].group; +} + + +bool +TuIM::getBuddyStatus(const int index, Data* status) +{ + assert( index >= 0 ); + assert( index < getNumBuddies() ); + + if (status) + { + *status = mBuddies[index].status; + } + + bool online = mBuddies[index].online; + + return online; +} + + +void +TuIM::subscribeBuddy( Buddy& buddy ) +{ + // subscribe to this budy + auto_ptr<SipMessage> msg( buddy.presDialog->makeInitialSubscribe(NameAddr(buddy.uri),NameAddr(mAor)) ); + + msg->header(h_Event).value() = Data("presence");; + msg->header(h_Accepts).push_back( Mime( "application","pidf+xml") ); + msg->header(h_Expires).value() = mSubscriptionTimeSeconds; + + buddy.mNextTimeToSubscribe = Timer::getRandomFutureTimeMs( mSubscriptionTimeSeconds*1000 ); + + setOutbound( *msg ); + + mStack->send( *msg ); +} + + +void +TuIM::addBuddy( const Uri& uri, const Data& group ) +{ + Buddy buddy; + buddy.uri = uri; + buddy.online = false; + buddy.status = Data::Empty; + buddy.group = group; + buddy.presDialog = new DeprecatedDialog( NameAddr(mContact) ); + assert( buddy.presDialog ); + + subscribeBuddy( buddy ); + + mBuddies.push_back( buddy ); +} + + +void +TuIM::removeBuddy( const Uri& name) +{ + TuIM::BuddyIterator i; + + i = mBuddies.begin(); + while ( i != mBuddies.end() ) + { + Uri u = i->uri; + + if ( u.getAor() == name.getAor() ) + { + // remove this buddy + // !cj! - should unsubscribe + i = mBuddies.erase(i); + } + else + { + i++; + } + } +} + + +void +TuIM::sendNotify(DeprecatedDialog* dialog) +{ + assert( dialog ); + + auto_ptr<SipMessage> msg( dialog->makeNotify() ); + + Pidf* pidf = new Pidf( *mPidf ); + + msg->header(h_Event).value() = "presence"; + + Token state; + state.value() = Data("active"); + state.param(p_expires) = dialog->getExpirySeconds(); + msg->header(h_SubscriptionState) = state; + + msg->setContents( pidf ); + + setOutbound( *msg ); + + mStack->send( *msg ); +} + + +void +TuIM::sendPublish(StateAgent& sa) +{ + assert( sa.dialog ); + + auto_ptr<SipMessage> msg( sa.dialog->makeInitialPublish(NameAddr(sa.uri),NameAddr(mAor)) ); + + Pidf* pidf = new Pidf( *mPidf ); + + msg->header(h_Event).value() = "presence"; + + msg->setContents( pidf ); + + setOutbound( *msg ); + + mStack->send( *msg ); +} + + +void +TuIM::authorizeSubscription( const Data& user ) +{ + // TODO implement this +} + + +void +TuIM::setMyPresence( const bool open, const Data& status, const Data& user ) +{ + // TODO implement the pser user status (when user is not empty) + assert( mPidf ); + mPidf->setSimpleStatus( open, status, mContact.getAor() ); + + for ( SubscriberIterator i=mSubscribers.begin(); i != mSubscribers.end(); i++) + { + DeprecatedDialog* dialog = i->dialog; + assert( dialog ); + + sendNotify(dialog); + } + + for ( StateAgentIterator i=mStateAgents.begin(); i != mStateAgents.end(); i++) + { + sendPublish( *i ); + } +} + + +void +TuIM::setOutboundProxy( const Uri& uri ) +{ + InfoLog( << "Set outbound proxy to " << uri ); + mOutboundProxy = uri; +} + + +void +TuIM::setUAName( const Data& name ) +{ + DebugLog( << "Set User Agent Name to " << name ); + mUAName = name; +} + + +void +TuIM::setOutbound( SipMessage& msg ) +{ + if ( msg.isResponse() ) + { + return; + } + + if ( !mOutboundProxy.host().empty() ) + { + NameAddr proxy( mOutboundProxy ); + msg.header(h_Routes).push_front( proxy ); + } + + if ( !mUAName.empty() ) + { + DebugLog( << "UserAgent name=" << mUAName ); + msg.header(h_UserAgent).value() = mUAName; + } + + if ( mDefaultProtocol != UNKNOWN_TRANSPORT ) + { + if ( ! msg.header(h_RequestLine).uri().exists(p_transport) ) + { + msg.header(h_RequestLine).uri().param(p_transport) = Tuple::toDataLower(mDefaultProtocol); + } + } +} + + +void +TuIM::setDefaultProtocol( TransportType protocol ) +{ + mDefaultProtocol = protocol; +} + + +void +TuIM::addStateAgent( const Uri& uri ) +{ + StateAgent sa; + + sa.dialog = new DeprecatedDialog( NameAddr(mContact) ); + sa.uri = uri; + + mStateAgents.push_back( sa ); + + sendPublish( sa ); +} + + +bool +TuIM::Callback::authorizeSubscription( const Uri& user ) +{ + return true; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provi +ded that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TuIM.hxx b/src/libs/resiprocate/resip/stack/TuIM.hxx new file mode 100644 index 00000000..a0f21c18 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TuIM.hxx @@ -0,0 +1,243 @@ +#if !defined(RESIP_TUIM_HXX) +#define RESIP_TUIM_HXX + +#include <list> + +#include "resip/stack/DeprecatedDialog.hxx" +#include "resip/stack/SecurityTypes.hxx" +#include "resip/stack/Transport.hxx" +#include "resip/stack/SipStack.hxx" +#include "rutil/Timer.hxx" + +namespace resip +{ + +class Pidf; + +class TuIM +{ + private: + class Buddy; + class StateAgent; + class Page; + +public: + class Callback + { + public: + virtual void receivedPage(const Data& msg, + const Uri& from, + const Data& signedBy, + SignatureStatus sigStatus, + bool wasEncryped ) = 0; + virtual void sendPageFailed(const Uri& dest, int respNumber ) =0; + virtual void receivePageFailed(const Uri& sender) =0; + virtual void registrationFailed(const Uri& dest, int respNumber ) =0; + virtual void registrationWorked(const Uri& dest ) =0; + virtual void presenceUpdate(const Uri& user, bool open, const Data& status ) =0; + virtual bool authorizeSubscription( const Uri& user ); // return + // true if + // sub is ok + + virtual ~Callback(); + }; + + TuIM(SipStack* stack, + const Uri& aor, + const Uri& contact, + Callback* callback, + const int registrationTimeSeconds = 1*60*60, + const int subscriptionTimeSeconds = 10*60 ); + + /// + void setOutboundProxy( const Uri& uri ); + void setDefaultProtocol( TransportType protocol ); + void setUAName( const Data& name ); + + bool haveCerts( bool sign, const Data& encryptFor ); + void sendPage(const Data& text, const Uri& dest, + const bool sign=false, const Data& encryptFor = Data::Empty ); + + void process(); + + // Registration management + void registerAor( const Uri& uri, + const Data& password = Data::Empty ); + + // Buddy List management + int getNumBuddies() const; + const Uri getBuddyUri(const int index); + const Data getBuddyGroup(const int index); + bool getBuddyStatus(const int index, Data* status=NULL); + void addBuddy( const Uri& uri, const Data& group ); + void removeBuddy( const Uri& name); + + // Presence management + void setMyPresence( const bool open, + const Data& status = Data::Empty, + const Data& user = Data::Empty ); + void addStateAgent( const Uri& uri ); + void authorizeSubscription( const Data& user ); + + private: + void processSipFrag(SipMessage* msg); + + void processRequest(SipMessage* msg); + void processMessageRequest(SipMessage* msg); + void processSubscribeRequest(SipMessage* msg); + void processRegisterRequest(SipMessage* msg); + void processNotifyRequest(SipMessage* msg); + + void processResponse(SipMessage* msg); + void processRegisterResponse(SipMessage* msg); + void processSubscribeResponse(SipMessage* msg, Buddy& buddy ); + void processNotifyResponse(SipMessage* msg, DeprecatedDialog& d ); + void processPublishResponse(SipMessage* msg, StateAgent& sa ); + void processPageResponse(SipMessage* msg, Page& page ); + + void sendNotify(DeprecatedDialog* dialog); + void sendPublish(StateAgent& dialog); + + void setOutbound( SipMessage& msg ); + + void subscribeBuddy( Buddy& buddy ); + + Callback* mCallback; + SipStack* mStack; + Uri mAor; + Uri mContact; + + class Buddy + { + public: + Uri uri; + Data group; + DeprecatedDialog* presDialog; + UInt64 mNextTimeToSubscribe; + bool online; + Data status; + + Buddy() {}; + Buddy(const Buddy& rhs) + { + uri = rhs.uri; + group = rhs.group; + presDialog = rhs.presDialog; + mNextTimeToSubscribe = rhs.mNextTimeToSubscribe; + online = rhs.online; + status = rhs.status; + }; + }; + + // people I subscribe to + std::vector<Buddy> mBuddies; + typedef std::vector<Buddy>::iterator BuddyIterator; + + class StateAgent + { + public: + Uri uri; + DeprecatedDialog* dialog; + }; + // people I publish to + std::list<StateAgent> mStateAgents; + typedef std::list<StateAgent>::iterator StateAgentIterator; + + // people who subscribe to me + class Subscriber + { + public: + Data aor; + bool authorized; + DeprecatedDialog* dialog; + }; + std::list<Subscriber> mSubscribers; + typedef std::list<Subscriber>::iterator SubscriberIterator; + + class Page + { + public: + Data text; + Uri uri; + bool sign; + Data encryptFor; + DeprecatedDialog* dialog; + }; + // outstanding messages + std::list<Page> mPages; + typedef std::list<Page>::iterator PageIterator; + + // Current pres info + Pidf* mPidf; + + // registration information + DeprecatedDialog mRegistrationDialog; + UInt64 mNextTimeToRegister; + Data mRegistrationPassword; + unsigned int mLastAuthCSeq; // This is the CSeq of the last registration message + // sent that included digest authorization information + + const int mRegistrationTimeSeconds; // this is the default time to request in + // a registration + + const int mSubscriptionTimeSeconds; // this is the default time to request in + // a subscription + + Uri mOutboundProxy; + Data mUAName; + TransportType mDefaultProtocol; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TuSelector.cxx b/src/libs/resiprocate/resip/stack/TuSelector.cxx new file mode 100644 index 00000000..f5b5c657 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TuSelector.cxx @@ -0,0 +1,363 @@ +#include "resip/stack/ConnectionTerminated.hxx" +#include "resip/stack/KeepAlivePong.hxx" +#include "resip/stack/TuSelector.hxx" +#include "resip/stack/TransactionUser.hxx" +#include "resip/stack/TransactionUserMessage.hxx" +#include "resip/stack/SipStack.hxx" + +#include "rutil/TimeLimitFifo.hxx" +#include "rutil/AsyncProcessHandler.hxx" +#include "rutil/WinLeakCheck.hxx" +#include "rutil/Logger.hxx" +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION + +using namespace resip; + +TuSelector::TuSelector(TimeLimitFifo<Message>& fallBackFifo) : + mFallBackFifo(fallBackFifo), + mCongestionManager(0), + mFallbackPostNotify(0), + mTuSelectorMode(false), + mStatsPayload() +{ + mShutdownFifo.setDescription("TuSelector::mShutdownFifo"); +} + +TuSelector::~TuSelector() +{ + //assert(mTuList.empty()); +} + + +void +TuSelector::setFallbackPostNotify(AsyncProcessHandler *handler) +{ + mFallbackPostNotify = handler; +} + +void +TuSelector::process() +{ + if (mShutdownFifo.messageAvailable()) + { + TransactionUserMessage* msg = mShutdownFifo.getNext(); + + switch (msg->type()) + { + case TransactionUserMessage::RequestShutdown: + InfoLog (<< "TransactionUserMessage::RequestShutdown " << *(msg->getTransactionUser())); + markShuttingDown(msg->getTransactionUser()); + break; + case TransactionUserMessage::RemoveTransactionUser: + InfoLog (<< "TransactionUserMessage::RemoveTransactionUser " << *(msg->getTransactionUser())); + remove(msg->getTransactionUser()); + break; + default: + assert(0); + break; + } + delete msg; + } +} + +void +TuSelector::add(Message* msg, TimeLimitFifo<Message>::DepthUsage usage) +{ + if (msg->hasTransactionUser()) + { + if (exists(msg->getTransactionUser())) + { + DebugLog (<< "Send to TU: " << *(msg->getTransactionUser()) << " " << std::endl << std::endl << *msg); + msg->getTransactionUser()->postToTransactionUser(msg, usage); + } + else + { + WarningLog (<< "Send to TU that no longer exists: " << std::endl << std::endl << *msg); + delete msg; + } + } + else + { + StatisticsMessage* stats = dynamic_cast<StatisticsMessage*>(msg); + if (stats) + { + InfoLog(<< "Stats message " ); + stats->loadOut(mStatsPayload); + stats->logStats(RESIPROCATE_SUBSYSTEM, mStatsPayload); + delete msg; + } + else + { + DebugLog(<< "Send to default TU: " << std::endl << std::endl << *msg); + mFallBackFifo.add(msg, usage); + if ( mFallbackPostNotify ) + mFallbackPostNotify->handleProcessNotification(); + } + } +} + +void +TuSelector::add(ConnectionTerminated* term) +{ + InfoLog (<< "Sending " << *term << " to TUs"); + + for(TuList::const_iterator it = mTuList.begin(); it != mTuList.end(); it++) + { + if (!it->shuttingDown && it->tu->isRegisteredForConnectionTermination()) + { + it->tu->post(term->clone()); + } + } +} + +void +TuSelector::add(KeepAlivePong* pong) +{ + //InfoLog (<< "Sending " << *pong << " to TUs"); + + for(TuList::const_iterator it = mTuList.begin(); it != mTuList.end(); it++) + { + if (!it->shuttingDown && it->tu->isRegisteredForKeepAlivePongs()) + { + it->tu->post(pong->clone()); + } + } +} + +bool +TuSelector::wouldAccept(TimeLimitFifo<Message>::DepthUsage usage) const +{ + if (mTuSelectorMode) + { + for(TuList::const_iterator it = mTuList.begin(); it != mTuList.end(); it++) + { + if (!it->shuttingDown && !it->tu->wouldAccept(usage)) + { + return false; + } + } + return true; + } + else + { + return mFallBackFifo.wouldAccept(usage); + } +} + +unsigned int +TuSelector::size() const +{ + if (mTuSelectorMode) + { + unsigned int total=0; + for(TuList::const_iterator it = mTuList.begin(); it != mTuList.end(); it++) + { + total += it->tu->size(); + } + return total; + } + else + { + return mFallBackFifo.size(); + } +} + +void +TuSelector::registerTransactionUser(TransactionUser& tu) +{ + mTuSelectorMode = true; + mTuList.push_back(Item(&tu)); +} + +void +TuSelector::requestTransactionUserShutdown(TransactionUser& tu) +{ + TransactionUserMessage* msg = new TransactionUserMessage(TransactionUserMessage::RequestShutdown, &tu); + mShutdownFifo.add(msg); +} + +void +TuSelector::unregisterTransactionUser(TransactionUser& tu) +{ + TransactionUserMessage* msg = new TransactionUserMessage(TransactionUserMessage::RemoveTransactionUser, &tu); + mShutdownFifo.add(msg); +} + +TransactionUser* +TuSelector::selectTransactionUser(const SipMessage& msg) +{ + for(TuList::iterator it = mTuList.begin(); it != mTuList.end(); it++) + { + if (it->tu->isForMe(msg)) + { + return it->tu; + } + } + return 0; +} + +void +TuSelector::markShuttingDown(TransactionUser* tu) +{ + for(TuList::iterator it = mTuList.begin(); it != mTuList.end(); it++) + { + if (it->tu == tu) + { + it->shuttingDown = true; + return; + } + } + assert(0); +} + +void +TuSelector::remove(TransactionUser* tu) +{ + for(TuList::iterator it = mTuList.begin(); it != mTuList.end(); it++) + { + if (it->tu == tu) + { + TransactionUserMessage* done = new TransactionUserMessage(TransactionUserMessage::TransactionUserRemoved, tu); + tu->post(done); + mTuList.erase(it); + return; + } + } + assert(0); +} + +bool +TuSelector::exists(TransactionUser* tu) +{ + for(TuList::iterator it = mTuList.begin(); it != mTuList.end(); it++) + { + if (it->tu == tu) + { + return true; + } + } + return false; +} + +unsigned int +TuSelector::getTimeTillNextProcessMS() +{ + if(mShutdownFifo.messageAvailable()) // || !mFallBackFifo.messageAvailable()) // .slg. fallback fifo is not really used + { + return 0; + } + else + { + return INT_MAX; + } +} + +bool +TuSelector::isTransactionUserStillRegistered(const TransactionUser* tu) const +{ + if (mTuSelectorMode) + { + for(TuList::const_iterator it = mTuList.begin(); it != mTuList.end(); it++) + { + if (!it->shuttingDown && it->tu == tu) + { + return true; + } + } + } + return false; +} + +void +TuSelector::setCongestionManager(CongestionManager* manager) +{ + for(TuList::iterator i=mTuList.begin(); i!=mTuList.end();++i) + { + i->tu->setCongestionManager(manager); + } + + // Note: We are intentionally not registering the following Fifos + // mFallbackFifo - this is the same fifo as SipStack::TuFifo (passed in + // constructor). + // mShutdownFifo - since it is only used at shutdown time, it doesn need + // congestion management +} + +CongestionManager::RejectionBehavior +TuSelector::getRejectionBehavior(TransactionUser* tu) const +{ + if(!mCongestionManager) + { + return CongestionManager::NORMAL; + } + + if(tu) + { + return tu->getRejectionBehavior(); + } + + return mCongestionManager->getRejectionBehavior(&mFallBackFifo); +} + +unsigned int +TuSelector::getExpectedWait(TransactionUser* tu) const +{ + if(tu) + { + return tu->getExpectedWait(); + } + + return (UInt32)mFallBackFifo.expectedWaitTimeMilliSec(); +} + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TuSelector.hxx b/src/libs/resiprocate/resip/stack/TuSelector.hxx new file mode 100644 index 00000000..8a13d30d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TuSelector.hxx @@ -0,0 +1,124 @@ +#if !defined(RESIP_TuSelector_HXX) +#define RESIP_TuSelector_HXX + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/StatisticsMessage.hxx" +#include "resip/stack/TransactionUserMessage.hxx" +#include "rutil/TimeLimitFifo.hxx" +#include "rutil/Fifo.hxx" + +namespace resip +{ + +class ConnectionTerminated; +class KeepAlivePong; +class Message; +class TransactionUser; +class AsyncProcessHandler; + +class TuSelector +{ + public: + TuSelector(TimeLimitFifo<Message>& fallBackFifo); + ~TuSelector(); + + void add(Message* msg, TimeLimitFifo<Message>::DepthUsage usage); + void add(ConnectionTerminated* term); + void add(KeepAlivePong* pong); + + unsigned int size() const; + bool wouldAccept(TimeLimitFifo<Message>::DepthUsage usage) const; + + TransactionUser* selectTransactionUser(const SipMessage& msg); + bool haveTransactionUsers() const { return mTuSelectorMode; } + void registerTransactionUser(TransactionUser&); + void requestTransactionUserShutdown(TransactionUser&); + void unregisterTransactionUser(TransactionUser&); + void process(); + unsigned int getTimeTillNextProcessMS(); + bool isTransactionUserStillRegistered(const TransactionUser* ) const; + + // Handler is notified when a message is posted + // to the default application receive queue. + void setFallbackPostNotify(AsyncProcessHandler *handler); + + void setCongestionManager(CongestionManager* manager); + CongestionManager::RejectionBehavior getRejectionBehavior(TransactionUser* tu) const; + unsigned int getExpectedWait(TransactionUser* tu) const; + + private: + void remove(TransactionUser* tu); + void markShuttingDown(TransactionUser* tu); + bool exists(TransactionUser* tu); + + private: + struct Item + { + Item(TransactionUser* ptu) : tu(ptu), shuttingDown(false) {} + TransactionUser* tu; + bool shuttingDown; + bool operator==(const Item& rhs) { return tu == rhs.tu; } + }; + + typedef std::vector<Item> TuList; + TuList mTuList; + TimeLimitFifo<Message>& mFallBackFifo; + CongestionManager* mCongestionManager; + AsyncProcessHandler *mFallbackPostNotify; + Fifo<TransactionUserMessage> mShutdownFifo; + bool mTuSelectorMode; + StatisticsMessage::Payload mStatsPayload; +}; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Tuple.cxx b/src/libs/resiprocate/resip/stack/Tuple.cxx new file mode 100644 index 00000000..06876d48 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Tuple.cxx @@ -0,0 +1,1032 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Tuple.hxx" +#include "rutil/compat.hxx" + +#include <iostream> +#include <string.h> +#include <sys/types.h> +#include <cassert> + +#if !defined (WIN32) +#include <arpa/inet.h> +#include <netinet/in.h> +#if defined(__APPLE__) && !defined(s6_addr16) +#define s6_addr16 __u6_addr.__u6_addr16 +#endif +#endif + +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/GenericIPAddress.hxx" +#include "rutil/HashMap.hxx" +#include "rutil/MD5Stream.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/Transport.hxx" + + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DNS + +Tuple::Tuple() : + mFlowKey(0), + transportKey(0), + transport(0), + onlyUseExistingConnection(false), + mTransportType(UNKNOWN_TRANSPORT) +{ + sockaddr_in* addr4 = (sockaddr_in*)&mSockaddr; + memset(addr4, 0, sizeof(sockaddr_in)); + mSockaddr.sa_family = AF_INET; +} + +Tuple::Tuple(const GenericIPAddress& genericAddress, TransportType type, + const Data& targetDomain) : + mFlowKey(0), + transportKey(0), + transport(0), + onlyUseExistingConnection(false), + mTransportType(type), + mTargetDomain(targetDomain) +{ + setSockaddr(genericAddress); +} + + +Tuple::Tuple(const Data& printableAddr, + int port, + IpVersion ipVer, + TransportType type, + const Data& targetDomain) : + mFlowKey(0), + transportKey(0), + transport(0), + onlyUseExistingConnection(false), + mTransportType(type), + mTargetDomain(targetDomain) +{ + if (ipVer == V4) + { + memset(&m_anonv4, 0, sizeof(m_anonv4)); + m_anonv4.sin_family = AF_INET; + m_anonv4.sin_port = htons(port); + + if (printableAddr.empty()) + { + m_anonv4.sin_addr.s_addr = htonl(INADDR_ANY); + } + else + { + DnsUtil::inet_pton( printableAddr, m_anonv4.sin_addr); + } + } + else + { +#ifdef USE_IPV6 + memset(&m_anonv6, 0, sizeof(m_anonv6)); + m_anonv6.sin6_family = AF_INET6; + m_anonv6.sin6_port = htons(port); + if (printableAddr.empty()) + { + m_anonv6.sin6_addr = in6addr_any; + } + else + { + DnsUtil::inet_pton( printableAddr, m_anonv6.sin6_addr); + } +#else + assert(0); +#endif + } +} + +Tuple::Tuple(const Data& printableAddr, + int port, + TransportType ptype, + const Data& targetDomain) : + mFlowKey(0), + transportKey(0), + transport(0), + onlyUseExistingConnection(false), + mTransportType(ptype), + mTargetDomain(targetDomain) +{ + if (DnsUtil::isIpV4Address(printableAddr)) + { + memset(&m_anonv4, 0, sizeof(m_anonv4)); + + DnsUtil::inet_pton( printableAddr, m_anonv4.sin_addr); + m_anonv4.sin_family = AF_INET; + m_anonv4.sin_port = htons(port); + } + else + { +#ifdef USE_IPV6 + memset(&m_anonv6, 0, sizeof(m_anonv6)); + DnsUtil::inet_pton( printableAddr, m_anonv6.sin6_addr); + m_anonv6.sin6_family = AF_INET6; + m_anonv6.sin6_port = htons(port); +#else + assert(0); +#endif + } +} + +Tuple::Tuple(const in_addr& ipv4, + int port, + TransportType ptype, + const Data& targetDomain) + :mFlowKey(0), + transportKey(0), + transport(0), + onlyUseExistingConnection(false), + mTransportType(ptype), + mTargetDomain(targetDomain) +{ + memset(&m_anonv4, 0, sizeof(sockaddr_in)); + m_anonv4.sin_addr = ipv4; + m_anonv4.sin_port = htons(port); + m_anonv4.sin_family = AF_INET; +} + +#ifdef USE_IPV6 +Tuple::Tuple(const in6_addr& ipv6, + int port, + TransportType ptype, + const Data& targetDomaina) + :mFlowKey(0), + transportKey(0), + transport(0), + onlyUseExistingConnection(false), + mTransportType(ptype), + mTargetDomain(targetDomaina) +{ + memset(&m_anonv6, 0, sizeof(sockaddr_in6)); + m_anonv6.sin6_addr = ipv6; + m_anonv6.sin6_port = htons(port); + m_anonv6.sin6_family = AF_INET6; +} +#endif + +Tuple::Tuple(const struct sockaddr& addr, + TransportType ptype, + const Data& targetDomain) : + mFlowKey(0), + transportKey(0), + transport(0), + onlyUseExistingConnection(false), + mSockaddr(addr), + mTransportType(ptype), + mTargetDomain(targetDomain) +{ + if (addr.sa_family == AF_INET) + { + m_anonv4 = (sockaddr_in&)(addr); + } +#ifdef USE_IPV6 + else if (addr.sa_family == AF_INET6) + { + m_anonv6 = (sockaddr_in6&)(addr); + } +#endif + else + { + assert(0); + } +} + +void +Tuple::setSockaddr(const GenericIPAddress& addr) +{ + if (addr.isVersion4()) + { + m_anonv4 = addr.v4Address; + } + else +#ifdef USE_IPV6 + { + m_anonv6 = addr.v6Address; + } +#else + { + assert(0); + } +#endif +} + +void +Tuple::writeBinaryToken(const resip::Tuple& tuple, resip::Data& container, const Data& salt) +{ + // .bwc. Maybe should just write the raw sockaddr into a buffer, and tack + // on the flowid and onlyUseExistingConnection flag. Would require 10 extra + // bytes for V6, and 14 extra bytes for V4. + // V6: sin6_len(1), sin6_flowinfo(4), flowId(4), onlyUseExistingConnection(1) + // V4: sin_family(2 instead of 1), sin_zero(8), flowId(4), onlyUseExistingConnection(1) + UInt32 rawToken[7]; + memset(&rawToken, 0, 28); + + rawToken[0] = tuple.mFlowKey; + + rawToken[1] = tuple.transportKey; + + // 0xXXXX0000 + rawToken[2] += (tuple.getPort() << 16); + + // 0x0000XX00 + rawToken[2] += (tuple.getType() << 8); + + // 0x000000X0 + if(tuple.onlyUseExistingConnection) + { + rawToken[2] += 0x00000010; + } + +#ifdef USE_IPV6 + if(tuple.ipVersion()==V6) + { + // 0x0000000X + rawToken[2] += 0x00000001; + in6_addr address = reinterpret_cast<const sockaddr_in6&>(tuple.getSockaddr()).sin6_addr; + assert(sizeof(address)==16); + memcpy(&rawToken[3],&address,16); + } + else +#endif + { + in_addr address = reinterpret_cast<const sockaddr_in&>(tuple.getSockaddr()).sin_addr; + assert(sizeof(address)==4); + memcpy(&rawToken[3],&address,4); + } + + container.clear(); + container.reserve(((tuple.ipVersion()==V6) ? 28 : 16) + (salt.empty() ? 0 : 32)); + container.append((char*)&rawToken[0],(tuple.ipVersion()==V6) ? 28 : 16); + + if(!salt.empty()) + { + // TODO - potentially use SHA1 HMAC if USE_SSL is defined for stronger encryption + MD5Stream ms; + ms << container << salt; + container += ms.getHex(); + } +} + + +Tuple +Tuple::makeTupleFromBinaryToken(const resip::Data& binaryFlowToken, const Data& salt) +{ + // To check if size is valid, we first need the IP version, so make sure the token is at least + // the size of an IPv4 token + if(binaryFlowToken.size()<16) + { + // !bwc! Should not assert here, since this sort of thing + // can come off the wire easily. + // TODO Throw an exception here? + DebugLog(<<"binary flow token was too small: " << binaryFlowToken.size()); + return Tuple(); + } + + const UInt32* rawToken=reinterpret_cast<const UInt32*>(binaryFlowToken.data()); + + FlowKey mFlowKey=rawToken[0]; + TransportKey transportKey=rawToken[1]; + + IpVersion version = (rawToken[2] & 0x00000001 ? V6 : V4); + + bool isRealFlow = (rawToken[2] & 0x00000010 ? true : false); + + UInt8 temp = (TransportType)((rawToken[2] & 0x00000F00) >> 8); + if(temp >= MAX_TRANSPORT) + { + DebugLog(<<"Garbage transport type in flow token: " << temp ); + return Tuple(); + } + TransportType type = (TransportType)temp; + + UInt16 port= (rawToken[2] >> 16); + + // Now that we have the version we can do a more accurate check on the size + if(!((version==V4 && salt.empty() && binaryFlowToken.size()==16) || + (version==V4 && !salt.empty() && binaryFlowToken.size()==48) || + (version==V6 && salt.empty() && binaryFlowToken.size()==28) || + (version==V6 && !salt.empty() && binaryFlowToken.size()==60))) + { + DebugLog(<<"Binary flow token is the wrong size for its IP version."); + return Tuple(); + } + + // If salt is specified, validate HMAC + if(!salt.empty()) + { + unsigned int tokenSizeLessHMAC = version == V4 ? 16 : 28; + Data flowTokenLessHMAC(Data::Share, binaryFlowToken.data(), tokenSizeLessHMAC); + Data flowTokenHMAC(Data::Share, binaryFlowToken.data()+tokenSizeLessHMAC, 32); + MD5Stream ms; + ms << flowTokenLessHMAC << salt; + if(ms.getHex() != flowTokenHMAC) + { + DebugLog(<<"Binary flow token has invalid HMAC, not our token"); + return Tuple(); + } + } + + if(version==V6) + { +#ifdef USE_IPV6 + in6_addr address; + assert(sizeof(address)==16); + memcpy(&address,&rawToken[3],16); + Tuple result(address,port,type); +#else + Tuple result(resip::Data::Empty, port, type); +#endif + result.mFlowKey=(FlowKey)mFlowKey; + result.transportKey = (TransportKey)transportKey; + result.onlyUseExistingConnection=isRealFlow; + return result; + } + + in_addr address; + assert(sizeof(address)==4); + memcpy(&address,&rawToken[3],4); + Tuple result(address,port,type); + result.mFlowKey=(FlowKey)mFlowKey; + result.transportKey = (TransportKey)transportKey; + result.onlyUseExistingConnection=isRealFlow; + return result; +} + +Data +Tuple::presentationFormat() const +{ +#ifdef USE_IPV6 + if (isV4()) + { + return Tuple::inet_ntop(*this); + } + else if (IN6_IS_ADDR_V4MAPPED(&m_anonv6.sin6_addr)) + { + return DnsUtil::inet_ntop(*(reinterpret_cast<const in_addr*>( + (reinterpret_cast<const unsigned char*>(&m_anonv6.sin6_addr) + 12)))); + } + else + { + return Tuple::inet_ntop(*this); + } +#else + return Tuple::inet_ntop(*this); +#endif + +} + +void +Tuple::setPort(int port) +{ + if (mSockaddr.sa_family == AF_INET) // v4 + { + m_anonv4.sin_port = htons(port); + } + else + { +#ifdef USE_IPV6 + m_anonv6.sin6_port = htons(port); +#else + assert(0); +#endif + } +} + +int +Tuple::getPort() const +{ + if (mSockaddr.sa_family == AF_INET) // v4 + { + return ntohs(m_anonv4.sin_port); + } + else + { +#ifdef USE_IPV6 + return ntohs(m_anonv6.sin6_port); +#else + assert(0); +#endif + } + + return -1; +} + +bool +Tuple::isAnyInterface() const +{ + if (isV4()) + { + return m_anonv4.sin_addr.s_addr == htonl(INADDR_ANY); + } +#if defined (USE_IPV6) + else + { + return memcmp(&m_anonv6.sin6_addr, &in6addr_any, sizeof(in6_addr)) == 0; + } +#else + return false; +#endif +} + +static Tuple loopbackv4("127.0.0.1",0,UNKNOWN_TRANSPORT); +bool +Tuple::isLoopback() const +{ + if(ipVersion()==V4) + { + return isEqualWithMask(loopbackv4,8,true,true); + } + else if (ipVersion()==V6) + { +#ifdef USE_IPV6 +#if defined(__linux__) || defined(__APPLE__) || defined(WIN32) + return IN6_IS_ADDR_LOOPBACK(&(m_anonv6.sin6_addr)) != 0; +#else + return ((*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[0])) == 0) && + (*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[4])) == 0) && + (*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[8])) == 0) && + (*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[12])) == ntohl(1))); +#endif +#endif + } + else + { + assert(0); + } + + return false; +} + +bool +Tuple::isV4() const +{ + return mSockaddr.sa_family == AF_INET; +} + +IpVersion +Tuple::ipVersion() const +{ + return mSockaddr.sa_family == AF_INET ? V4 : V6; +} + +static Tuple v4privateaddrbase1("10.0.0.0",0,UNKNOWN_TRANSPORT); +static Tuple v4privateaddrbase2("172.16.0.0",0,UNKNOWN_TRANSPORT); +static Tuple v4privateaddrbase3("192.168.0.0",0,UNKNOWN_TRANSPORT); + +#ifdef USE_IPV6 +static Tuple v6privateaddrbase("fc00::",0,UNKNOWN_TRANSPORT); +#endif + +bool +Tuple::isPrivateAddress() const +{ + if(ipVersion()==V4) + { + // RFC 1918 + return isEqualWithMask(v4privateaddrbase1,8,true,true) || // 10.0.0.0 - 10.255.255.255 (10/8 prefix) + isEqualWithMask(v4privateaddrbase2,12,true,true) || // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) + isEqualWithMask(v4privateaddrbase3,16,true,true) || // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) + isLoopback(); + } +#ifdef USE_IPV6 + else if (ipVersion()==V6) + { + // RFC 4193 + // ?slg? should we look specifically for ipv4 mapped/compatible address and apply V4 rules to them? + return isEqualWithMask(v6privateaddrbase,7,true,true) || // fc00::/7 + isLoopback(); + } +#endif + else + { + assert(0); + } + + return false; +} + +socklen_t +Tuple::length() const +{ + if (mSockaddr.sa_family == AF_INET) // v4 + { + return sizeof(sockaddr_in); + } +#ifdef USE_IPV6 + else if (mSockaddr.sa_family == AF_INET6) // v6 + { + return sizeof(sockaddr_in6); + } +#endif + + assert(0); + return 0; +} + + +bool Tuple::operator==(const Tuple& rhs) const +{ + if (mSockaddr.sa_family == rhs.mSockaddr.sa_family) + { + if (mSockaddr.sa_family == AF_INET) // v4 + { + return (m_anonv4.sin_port == rhs.m_anonv4.sin_port && + mTransportType == rhs.mTransportType && + memcmp(&m_anonv4.sin_addr, &rhs.m_anonv4.sin_addr, sizeof(in_addr)) == 0); + } + else // v6 + { +#ifdef USE_IPV6 + return (m_anonv6.sin6_port == rhs.m_anonv6.sin6_port && + mTransportType == rhs.mTransportType && + memcmp(&m_anonv6.sin6_addr, &rhs.m_anonv6.sin6_addr, sizeof(in6_addr)) == 0); +#else + assert(0); + return false; +#endif + } + } + else + { + return false; + } + + // !dlb! don't include connection +} + +bool +Tuple::operator<(const Tuple& rhs) const +{ + if (mTransportType < rhs.mTransportType) + { + return true; + } + else if (mTransportType > rhs.mTransportType) + { + return false; + } + else if (mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET) + { + int c=memcmp(&m_anonv4.sin_addr, + &rhs.m_anonv4.sin_addr, + sizeof(in_addr)); + + if (c < 0) + { + return true; + } + else if (c > 0) + { + return false; + } + else if (m_anonv4.sin_port < rhs.m_anonv4.sin_port) + { + return true; + } + else + { + return false; + } + } +#ifdef USE_IPV6 + else if (mSockaddr.sa_family == AF_INET6 && + rhs.mSockaddr.sa_family == AF_INET6) + { + int c = memcmp(&m_anonv6.sin6_addr, + &rhs.m_anonv6.sin6_addr, + sizeof(in6_addr)); + if (c < 0) + { + return true; + } + else if (c > 0) + { + return false; + } + else if (m_anonv6.sin6_port < rhs.m_anonv6.sin6_port) + { + return true; + } + else + { + return false; + } + } + else if (mSockaddr.sa_family == AF_INET6 && + rhs.mSockaddr.sa_family == AF_INET) + { + return true; + } + else if (mSockaddr.sa_family == AF_INET && + rhs.mSockaddr.sa_family == AF_INET6) + { + return false; + } +#endif + else + { + //assert(0); + return false; + } +} + +EncodeStream& +resip::operator<<(EncodeStream& ostrm, const Tuple& tuple) +{ + ostrm << "[ " ; + +#ifdef USE_IPV6 + if (tuple.mSockaddr.sa_family == AF_INET6) + { + ostrm << "V6 " << DnsUtil::inet_ntop(tuple.m_anonv6.sin6_addr) << " port=" << tuple.getPort(); + } + else +#endif + if (tuple.mSockaddr.sa_family == AF_INET) + { + ostrm << "V4 " << Tuple::inet_ntop(tuple) << ":" << tuple.getPort(); + } + else + { + assert(0); + } + + ostrm << " " << Tuple::toData(tuple.mTransportType); + ostrm << " target domain="; + if (tuple.mTargetDomain.empty()) ostrm << "unspecified"; + else ostrm << tuple.mTargetDomain; + + ostrm << " mFlowKey=" << tuple.mFlowKey + << " ]"; + + return ostrm; +} + +size_t +Tuple::hash() const +{ + // !dlb! do not include the connection +#ifdef USE_IPV6 + if (mSockaddr.sa_family == AF_INET6) + { + const sockaddr_in6& in6 = + reinterpret_cast<const sockaddr_in6&>(mSockaddr); + + return size_t(Data(Data::Share, (const char *)&in6.sin6_addr.s6_addr, sizeof(in6.sin6_addr.s6_addr)).hash() + + 5*in6.sin6_port + + 25*mTransportType); + } + else +#endif + { + const sockaddr_in& in4 = + reinterpret_cast<const sockaddr_in&>(mSockaddr); + + return size_t(in4.sin_addr.s_addr + + 5*in4.sin_port + + 25*mTransportType); + } +} + +HashValueImp(resip::Tuple, data.hash()); + +TransportType +Tuple::toTransport(const Data& transportName) +{ + return resip::toTransportType(transportName); // TransportTypes.hxx +}; + +const Data& +Tuple::toData(TransportType type) +{ + return resip::toData(type); // TransportTypes.hxx +} + +const Data& +Tuple::toDataLower(TransportType type) +{ + return resip::toDataLower(type); // TransportTypes.hxx +} + +Data +Tuple::inet_ntop(const Tuple& tuple) +{ +#ifdef USE_IPV6 + if (!tuple.isV4()) + { + const sockaddr_in6& addr = reinterpret_cast<const sockaddr_in6&>(tuple.getSockaddr()); + return DnsUtil::inet_ntop(addr.sin6_addr); + } + else +#endif + { + const sockaddr_in& addr = reinterpret_cast<const sockaddr_in&>(tuple.getSockaddr()); + return DnsUtil::inet_ntop(addr.sin_addr); + } +} + + +bool +Tuple::isEqualWithMask(const Tuple& compare, short mask, bool ignorePort, bool ignoreTransport) const +{ + if(ignoreTransport || getType() == compare.getType()) // check if transport type matches + { + if (mSockaddr.sa_family == compare.getSockaddr().sa_family && mSockaddr.sa_family == AF_INET) // v4 + { + sockaddr_in* addr1 = (sockaddr_in*)&mSockaddr; + sockaddr_in* addr2 = (sockaddr_in*)&compare.getSockaddr(); + + return ((ignorePort || addr1->sin_port == addr2->sin_port) && + (addr1->sin_addr.s_addr & htonl((0xFFFFFFFF << (32 - mask)))) == + (addr2->sin_addr.s_addr & htonl((0xFFFFFFFF << (32 - mask))))); + } +#ifdef USE_IPV6 + else if (mSockaddr.sa_family == compare.getSockaddr().sa_family && mSockaddr.sa_family == AF_INET6) // v6 + { + sockaddr_in6* addr1 = (sockaddr_in6*)&mSockaddr; + sockaddr_in6* addr2 = (sockaddr_in6*)&compare.getSockaddr(); + + if(ignorePort || addr1->sin6_port == addr2->sin6_port) + { + unsigned long mask6part; + unsigned long temp; + bool match=true; + for(int i = 3; i >= 0; i--) + { + if(mask <= 32*i) + { + mask6part = 0; + } + else + { + temp = mask - 32*i; + if(temp >= 32) + { + mask6part = 0xffffffff; + } + else + { + mask6part = 0xffffffff << (32 - temp); + } + } +#ifdef WIN32 + if((*((unsigned long*)&addr1->sin6_addr.u.Word[i*2]) & htonl(mask6part)) != + (*((unsigned long*)&addr2->sin6_addr.u.Word[i*2]) & htonl(mask6part))) +#elif defined(sun) + // sun has no s6_addr16 + if((*((unsigned long*)&addr1->sin6_addr._S6_un._S6_u32[i]) & htonl(mask6part)) != + (*((unsigned long*)&addr2->sin6_addr._S6_un._S6_u32[i]) & htonl(mask6part))) +#elif defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) + // bsd has no s6_addr16 + if((*((unsigned long*)&addr1->sin6_addr.__u6_addr.__u6_addr32[i]) & htonl(mask6part)) != + (*((unsigned long*)&addr2->sin6_addr.__u6_addr.__u6_addr32[i]) & htonl(mask6part))) +#else + if((*((unsigned long*)&addr1->sin6_addr.s6_addr16[i*2]) & htonl(mask6part)) != + (*((unsigned long*)&addr2->sin6_addr.s6_addr16[i*2]) & htonl(mask6part))) +#endif + { + match=false; + break; + } + } + if(match) + { + return true; + } + } + } +#endif + } + return false; +} + + +// special comparitors +bool +Tuple::AnyInterfaceCompare::operator()(const Tuple& lhs, + const Tuple& rhs) const +{ + if (lhs.mTransportType < rhs.mTransportType) + { + return true; + } + else if (lhs.mTransportType > rhs.mTransportType) + { + return false; + } + else if (lhs.mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET) + { + if (lhs.m_anonv4.sin_port < rhs.m_anonv4.sin_port) + { + return true; + } + else + { + return false; + } + } +#ifdef USE_IPV6 + else if (lhs.mSockaddr.sa_family == AF_INET6 && + rhs.mSockaddr.sa_family == AF_INET6) + { + if (lhs.m_anonv6.sin6_port < rhs.m_anonv6.sin6_port) + { + return true; + } + else + { + return false; + } + } + else if (lhs.mSockaddr.sa_family == AF_INET6 && + rhs.mSockaddr.sa_family == AF_INET) + { + return true; + } + else if (lhs.mSockaddr.sa_family == AF_INET && + rhs.mSockaddr.sa_family == AF_INET6) + { + return false; + } +#endif + else + { + return false; + } +}; + +bool +Tuple::AnyPortCompare::operator()(const Tuple& lhs, + const Tuple& rhs) const +{ + if (lhs.mTransportType < rhs.mTransportType) + { + return true; + } + else if (lhs.mTransportType > rhs.mTransportType) + { + return false; + } + else if (lhs.mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET) + { + int c = memcmp(&lhs.m_anonv4.sin_addr, + &rhs.m_anonv4.sin_addr, + sizeof(in_addr)); + + if (c < 0) + { + return true; + } + else if (c > 0) + { + return false; + } + } +#ifdef USE_IPV6 + else if (lhs.mSockaddr.sa_family == AF_INET6 && + rhs.mSockaddr.sa_family == AF_INET6) + { + int c = memcmp(&lhs.m_anonv6.sin6_addr, + &rhs.m_anonv6.sin6_addr, + sizeof(in6_addr)); + if (c < 0) + { + return true; + } + else if (c > 0) + { + return false; + } + } + else if (lhs.mSockaddr.sa_family == AF_INET6 && + rhs.mSockaddr.sa_family == AF_INET) + { + return true; + } + else if (lhs.mSockaddr.sa_family == AF_INET && + rhs.mSockaddr.sa_family == AF_INET6) + { + return false; + } +#endif + + return false; +} + +bool +Tuple::FlowKeyCompare::operator()(const Tuple& lhs, + const Tuple& rhs) const +{ + if (lhs == rhs) + { + return lhs.mFlowKey < rhs.mFlowKey; + } + return lhs < rhs; +}; + +GenericIPAddress +Tuple::toGenericIPAddress() const +{ + if (isV4()) + { + return GenericIPAddress(m_anonv4); + } + else +#ifdef USE_IPV6 + { + return GenericIPAddress(m_anonv6); + } +#else + { + assert(0); + return m_anonv4; //bogus + } +#endif +} + +bool +Tuple::AnyPortAnyInterfaceCompare::operator()(const Tuple& lhs, + const Tuple& rhs) const +{ + if (lhs.mTransportType < rhs.mTransportType) + { + return true; + } + else if (lhs.mTransportType > rhs.mTransportType) + { + return false; + } +#ifdef USE_IPV6 + else if (lhs.mSockaddr.sa_family == AF_INET6 && + rhs.mSockaddr.sa_family == AF_INET) + { + return true; + } + else if (lhs.mSockaddr.sa_family == AF_INET && + rhs.mSockaddr.sa_family == AF_INET6) + { + return false; + } +#endif + else + { + return false; + } +}; + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Tuple.hxx b/src/libs/resiprocate/resip/stack/Tuple.hxx new file mode 100644 index 00000000..d49f3596 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Tuple.hxx @@ -0,0 +1,325 @@ +#if !defined(RESIP_TUPLE_HXX) +#define RESIP_TUPLE_HXX + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include "rutil/Socket.hxx" +#include "rutil/compat.hxx" + +#include "rutil/HashMap.hxx" +#include "rutil/TransportType.hxx" +#include "rutil/HeapInstanceCounter.hxx" +#include "rutil/Data.hxx" + +#if defined(WIN32) +#include <Ws2tcpip.h> +#else +#include <netinet/in.h> +#endif + +namespace resip +{ + +struct GenericIPAddress; +class Transport; + +// WARNING!! +// When you change this structure, make sure to update the hash function, +// operator== and operator< to be consistent with the new structure. For +// instance, the Connection* and Transport* change value in the Tuple over +// its lifetime so they must not be included in the hash or comparisons. + +typedef unsigned long FlowKey; +typedef unsigned long TransportKey; + +/** + @ingroup resip_crit + @brief Represents a network address. + + This includes: + - IP address + - port + - protocol (TransportType) + - TLS hostname (since this is integral to connection establishment) + + Internally the class is aware of the struct + sockaddr/sin_addr/sin6addr binary representation of the address. + The sa_family of struct sockaddr is used to keep track of whether a + Tuple is representing a an IPv4 or IPv6 address. + + Also included are some comparator classes that can be used for + containers of Tuple. + + +*/ +class Tuple +{ + public: + RESIP_HeapCount(Tuple); + + Tuple(); + + explicit Tuple(const GenericIPAddress& genericAddress, + TransportType type=UNKNOWN_TRANSPORT, + const Data& targetDomain = Data::Empty); + + Tuple(const Data& printableAddress, + int port, + IpVersion ipVer, + TransportType type=UNKNOWN_TRANSPORT, + const Data& targetDomain = Data::Empty); + + Tuple(const Data& printableAddress, + int port, + TransportType type, + const Data& targetDomain = Data::Empty); + + Tuple(const in_addr& pipv4, + int pport, + TransportType ptype, + const Data& targetDomain = Data::Empty); + + Tuple(const sockaddr& addr, + TransportType ptype, + const Data& targetDomain = Data::Empty); + +#ifdef IPPROTO_IPV6 + // enable this if the current platform supports IPV6; the USE_IPV6 #define + // will determine if this c'tor is actually implemented. + // ?bwc? Is there a more standard preprocessor macro for this? + // ?bwc? Is there a way we can add something more informative to the + // linker error we'll see if we compiled without USE_IPV6, on a platform + // with IPV6, and someone tries to invoke this c'tor? (ie; "This library + // was built with IPV6 support disabled") + Tuple(const in6_addr& pipv6, + int pport, + TransportType ptype, + const Data& targetDomain = Data::Empty); +#endif + + /// @brief Retrieve a const binary representation of the socket address + /// for this tuple. + const sockaddr& getSockaddr() const { return mSockaddr; } + + /// @brief Retrieve the binary representation of the socket address for + /// this tuple. + sockaddr& getMutableSockaddr() { return mSockaddr; } + + /// @brief Set the internal binary representation of the socket address + /// from the GenericIPAddress. + void setSockaddr(const GenericIPAddress &); + + TransportType getType() const { return mTransportType; } + void setType(TransportType type) { mTransportType = type ;} + void setPort(int port); + int getPort() const; + inline FlowKey getFlowKey() const { return mFlowKey;} + + /// @deprecated use ipVersion() + /// @todo !dcm! -- should deprecate asap + bool isV4() const; + + /// Returns V4 or V6 as appropriate. + IpVersion ipVersion() const; + void setIpVersion(IpVersion version); + + /// @brief TRUE if this address is equal to the "INADDR_ANY" value for + /// this address family. + bool isAnyInterface() const; + socklen_t length() const; // of sockaddr + bool isLoopback() const; + bool isPrivateAddress() const; // Return boolean based on definitions in RFC1918(v4) and RFC4193(v6) + + /// @brief Compares TransportType, the binary address, port, and + /// address family of the Tuple. + bool operator<(const Tuple& rhs) const; + + /// @brief Compares TransportType, the binary address, port, and + /// address family of the Tuple. + bool operator==(const Tuple& rhs) const; + + /// Wrapper around the inet_top() method. + Data presentationFormat() const; + + /// @brief Converts a string representation of transport type, + /// i.e. "UDP" to a TransportType + static TransportType toTransport( const Data& ); + + /// @brief Converts the TransportType to a string representation of the + /// transport type, e.g. "TCP" + static const Data& toData( TransportType ); + + static const Data& toDataLower(TransportType type); + + /// @brief Converts the binary socket address to presentation format, + /// via the DnsUtil::inet_ntop() method. + static Data inet_ntop(const Tuple& tuple); + + // Creates a binary token from the provided Tuple - if salt is provided, then an HMAC is appended + // to the end of the token + static void writeBinaryToken(const Tuple& tuple, Data& container, const Data& salt=Data::Empty); + // Creates a Tuple from the provided binary token - if salt is provided, then an HMAC is checked + static Tuple makeTupleFromBinaryToken(const Data& binaryToken, const Data& salt=Data::Empty); + + GenericIPAddress toGenericIPAddress() const; + + /// This is a (largely) opaque key that subclasses of Transport will use + /// to help record/find flows. For UDP and DTLS, this is just the FD, and + /// the rest of the information about the flow is carried in the Tuple. + /// For TCP and TLS, the FD of the connection is used. + /// For protocols where using the FD would not be appropriate (SCTP), + /// the transport may use whatever method to generate these it likes. + /// (It is highly recommended that these ids are unique across all + /// instances of a transport type) + FlowKey mFlowKey; + TransportKey transportKey; + + // deprecate + Transport* transport; + bool onlyUseExistingConnection; + + /// @brief compares this tuple with the one passed in for family, port + /// and address equality using the passed in address mask (mask + /// is specified by number of bits) + bool isEqualWithMask(const Tuple& tuple, short mask, bool ignorePort=false, bool ignoreTransport=false) const; + + /// @brief A "less than" comparator for Tuple, for use in map + /// containers etc. Comparison is based on transport type, and + /// if those are equal, it is based on port number. + class AnyInterfaceCompare + { + public: + bool operator()(const Tuple& x, + const Tuple& y) const; + }; + friend class AnyInterfaceCompare; + + /// @brief A "less than" comparator for Tuple, for use in map + /// containers etc. Comparison is based on transport type, and + /// if those are equal, it is based on the binary representation + /// of the socket internet address (v4 or v6, whichever is + /// appropriate). + class AnyPortCompare + { + public: + bool operator()(const Tuple& x, + const Tuple& y) const; + }; + friend class AnyPortCompare; + + /// @brief A "less than" comparator for Tuple, for use in map + /// containers etc. Comparison is based only on transport type + class AnyPortAnyInterfaceCompare + { + public: + bool operator()(const Tuple& x, + const Tuple& y) const; + }; + friend class AnyPortAnyInterfaceCompare; + + class FlowKeyCompare + { + public: + bool operator()(const Tuple& x, + const Tuple& y) const; + }; + friend class FlowKeyCompare; + + /// @brief Set the domain name this address tuple intends to represent. + void setTargetDomain(const Data& target) + { + mTargetDomain = target; + } + + /// @brief Get the domain name this address tuple intends to represent. + /// Useful with DnsUtil, for example. + const Data& getTargetDomain() const + { + return mTargetDomain; + } + + /** + @brief Creates a 32-bit hash based on the contents of this Tuple. + */ + size_t hash() const; + +private: + union + { + sockaddr mSockaddr; + sockaddr_in m_anonv4; +#ifdef IPPROTO_IPV6 + // enable this if the current platform supports IPV6 + // ?bwc? Is there a more standard preprocessor macro for this? + sockaddr_in6 m_anonv6; +#endif + char pad[28]; //< this make union same size if v6 is in or out + }; + TransportType mTransportType; + Data mTargetDomain; + + friend EncodeStream& operator<<(EncodeStream& strm, const Tuple& tuple); + friend class DnsResult; +}; + + +EncodeStream& +operator<<(EncodeStream& ostrm, const Tuple& tuple); + +} + +HashValue(resip::Tuple); + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TupleMarkManager.cxx b/src/libs/resiprocate/resip/stack/TupleMarkManager.cxx new file mode 100644 index 00000000..80e23862 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TupleMarkManager.cxx @@ -0,0 +1,165 @@ +#include "resip/stack/TupleMarkManager.hxx" + +#include "resip/stack/MarkListener.hxx" +#include "rutil/Lock.hxx" +#include "rutil/Timer.hxx" + +namespace resip +{ + +TupleMarkManager::MarkType +TupleMarkManager::getMarkType(const Tuple& tuple) +{ + ListEntry entry(tuple,0); + resip::Lock g(mListMutex); + TupleList::iterator i=mList.find(entry); + + if(i!=mList.end()) + { + UInt64 now=Timer::getTimeMs(); + if(i->first.mExpiry > now) + { + return i->second; + } + else + { + mList.erase(i); + // ?bwc? Should we do this? + UInt64 expiry = 0; + MarkType mark = OK; + notifyListeners(tuple,expiry,mark); + } + } + + return OK; +} + +void TupleMarkManager::mark(const Tuple& tuple,UInt64 expiry,MarkType mark) +{ + // .amr. Notify listeners first so they can change the entry if they want + notifyListeners(tuple,expiry,mark); + ListEntry entry(tuple,expiry); + resip::Lock g(mListMutex); + mList[entry]=mark; +} + +void TupleMarkManager::registerMarkListener(MarkListener* listener) +{ + mListeners.insert(listener); +} + +void TupleMarkManager::unregisterMarkListener(MarkListener* listener) +{ + mListeners.erase(listener); +} + +void +TupleMarkManager::notifyListeners(const resip::Tuple& tuple, UInt64& expiry, MarkType& mark) +{ + for(Listeners::iterator i = mListeners.begin(); i!=mListeners.end(); ++i) + { + (*i)->onMark(tuple,expiry,mark); + } +} + +TupleMarkManager::ListEntry::ListEntry(const Tuple& tuple, UInt64 expiry) + : mTuple(tuple), + mExpiry(expiry) +{} + +TupleMarkManager::ListEntry::ListEntry(const TupleMarkManager::ListEntry& orig) + : mTuple(orig.mTuple), + mExpiry(orig.mExpiry) +{} + +TupleMarkManager::ListEntry::~ListEntry() +{} + +bool +TupleMarkManager::ListEntry::operator<(const TupleMarkManager::ListEntry& rhs) const +{ + if(mTuple < rhs.mTuple) + { + return true; + } + else if(rhs.mTuple < mTuple) + { + return false; + } + + return mTuple.getTargetDomain() < rhs.mTuple.getTargetDomain(); +} + +bool +TupleMarkManager::ListEntry::operator>(const TupleMarkManager::ListEntry& rhs) const +{ + if(rhs.mTuple < mTuple) + { + return true; + } + else if(mTuple < rhs.mTuple) + { + return false; + } + + return mTuple.getTargetDomain() > rhs.mTuple.getTargetDomain(); +} + +bool +TupleMarkManager::ListEntry::operator==(const TupleMarkManager::ListEntry& rhs) const +{ + return (mTuple==rhs.mTuple && mTuple.getTargetDomain()==rhs.mTuple.getTargetDomain()); +} + + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/TupleMarkManager.hxx b/src/libs/resiprocate/resip/stack/TupleMarkManager.hxx new file mode 100644 index 00000000..13692a25 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TupleMarkManager.hxx @@ -0,0 +1,115 @@ +#ifndef TUPLE_MARK_MANAGER +#define TUPLE_MARK_MANAGER + +#include "resip/stack/Tuple.hxx" +#include "rutil/Mutex.hxx" +#include <set> +#include <map> + +namespace resip +{ + +class MarkListener; + +class TupleMarkManager +{ + public: + TupleMarkManager(){} + virtual ~TupleMarkManager(){} + + typedef enum + { + OK, + GREY, + BLACK + } + MarkType; + + MarkType getMarkType(const Tuple& tuple); + + void mark(const Tuple& tuple,UInt64 expiry,MarkType mark); + void registerMarkListener(MarkListener*); + void unregisterMarkListener(MarkListener*); + + private: + + class ListEntry + { + public: + ListEntry(const Tuple& tuple, UInt64 expiry); + ListEntry(const ListEntry& orig); + ~ListEntry(); + bool operator<(const ListEntry& rhs) const; + bool operator>(const ListEntry& rhs) const; + bool operator==(const ListEntry& rhs) const; + + Tuple mTuple; + UInt64 mExpiry; + private: + ListEntry(); + }; + + typedef std::map<ListEntry,MarkType> TupleList; + + TupleList mList; + resip::Mutex mListMutex; + + typedef std::set<MarkListener*> Listeners; + Listeners mListeners; + + void notifyListeners(const resip::Tuple& tuple, UInt64& expiry, MarkType& mark); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/UInt32Category.cxx b/src/libs/resiprocate/resip/stack/UInt32Category.cxx new file mode 100644 index 00000000..64efb445 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/UInt32Category.cxx @@ -0,0 +1,240 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/UInt32Category.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// UInt32: +//==================== +UInt32Category::UInt32Category() + : ParserCategory(), + mValue(0), + mComment() +{} + +UInt32Category::UInt32Category(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), + mValue(0), + mComment() +{} + +UInt32Category::UInt32Category(const UInt32Category& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mValue(rhs.mValue), + mComment(rhs.mComment) +{} + +UInt32Category& +UInt32Category::operator=(const UInt32Category& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mValue = rhs.mValue; + mComment = rhs.mComment; + } + return *this; +} + +ParserCategory* UInt32Category::clone() const +{ + return new UInt32Category(*this); +} + +ParserCategory* UInt32Category::clone(void* location) const +{ + return new (location) UInt32Category(*this); +} + +ParserCategory* +UInt32Category::clone(PoolBase* pool) const +{ + return new (pool) UInt32Category(*this, pool); +} + +const UInt32& +UInt32Category::value() const +{ + checkParsed(); + return mValue; +} + +const Data& +UInt32Category::comment() const +{ + checkParsed(); + return mComment; +} + +UInt32& +UInt32Category::value() +{ + checkParsed(); + return mValue; +} + +Data& +UInt32Category::comment() +{ + checkParsed(); + return mComment; +} + +void +UInt32Category::parse(ParseBuffer& pb) +{ + const char* start = pb.skipWhitespace(); + mValue = pb.uInt32(); + pb.skipToChar('('); + if (!pb.eof()) + { + start = pb.skipChar(); + pb.skipToEndQuote(')'); + pb.data(mComment, start); + pb.skipChar(); + } + else + { + pb.reset(start); + start = pb.skipNonWhitespace(); + } + + parseParameters(pb); +} + +EncodeStream& +UInt32Category::encodeParsed(EncodeStream& str) const +{ + str << mValue; + + if (!mComment.empty()) + { + str << "(" << mComment << ")"; + } + + encodeParameters(str); + return str; +} + +ParameterTypes::Factory UInt32Category::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; + +Parameter* +UInt32Category::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) +{ + if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) + { + return ParameterFactories[type](type, pb, terminators, pool); + } + return 0; +} + +bool +UInt32Category::exists(const Param<UInt32Category>& paramType) const +{ + checkParsed(); + bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; + return ret; +} + +void +UInt32Category::remove(const Param<UInt32Category>& paramType) +{ + checkParsed(); + removeParameterByEnum(paramType.getTypeNum()); +} + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ +_enum##_Param::DType& \ +UInt32Category::param(const _enum##_Param& paramType) \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + p = new _enum##_Param::Type(paramType.getTypeNum()); \ + mParameters.push_back(p); \ + } \ + return p->value(); \ +} \ + \ +const _enum##_Param::DType& \ +UInt32Category::param(const _enum##_Param& paramType) const \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ + DebugLog(<< *this); \ + throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ + } \ + return p->value(); \ +} + +defineParam(duration, "duration", UInt32Parameter, "RFC 3261"); + +#undef defineParam + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/UInt32Category.hxx b/src/libs/resiprocate/resip/stack/UInt32Category.hxx new file mode 100644 index 00000000..1b8f730c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/UInt32Category.hxx @@ -0,0 +1,120 @@ +#if !defined(RESIP_UINT32_CATEGORY_HXX) +#define RESIP_UINT32_CATEGORY_HXX + +#include "rutil/resipfaststreams.hxx" + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" + +namespace resip +{ + +/** + @ingroup sip_grammar + @brief Represents a numeric-with-comment header field value. +*/ +class UInt32Category : public ParserCategory +{ + public: + enum {commaHandling = NoCommaTokenizing}; + + UInt32Category(); + UInt32Category(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + UInt32Category(const UInt32Category& orig, + PoolBase* pool=0); + UInt32Category& operator=(const UInt32Category&); + + virtual void parse(ParseBuffer& pb); + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + + const UInt32& value() const; + const Data& comment() const; + UInt32& value(); + Data& comment(); + + // Inform the compiler that overloads of these may be found in + // ParserCategory, too. + using ParserCategory::exists; + using ParserCategory::remove; + using ParserCategory::param; + + virtual Parameter* createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool); + // .bwc, This is an awful lot for one lousy param type. + bool exists(const Param<UInt32Category>& paramType) const; + void remove(const Param<UInt32Category>& paramType); + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ + const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \ + _enum##_Param::DType& param(const _enum##_Param& paramType); \ + friend class _enum##_Param + +defineParam(duration, "duration", UInt32Parameter, "RFC 3261"); + +#undef defineParam + + private: + UInt32 mValue; + Data mComment; + + static ParameterTypes::Factory ParameterFactories[ParameterTypes::MAX_PARAMETER]; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/UInt32Parameter.cxx b/src/libs/resiprocate/resip/stack/UInt32Parameter.cxx new file mode 100644 index 00000000..53ad9eae --- /dev/null +++ b/src/libs/resiprocate/resip/stack/UInt32Parameter.cxx @@ -0,0 +1,110 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/UInt32Parameter.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +UInt32Parameter::UInt32Parameter(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators) + : Parameter(type), + mValue(0) +{ + pb.skipWhitespace(); + pb.skipChar(Symbols::EQUALS[0]); + pb.skipWhitespace(); + + // hack to allow expires to have an 2543 style quoted Date + if (type == ParameterTypes::expires) + { + pb.assertNotEof(); + try + { + mValue = pb.uInt32(); + } + catch (ParseException&) + { + mValue = 3600; + pb.skipToOneOf(ParseBuffer::ParamTerm); + } + + } + else + { + mValue = pb.uInt32(); + } +} + +UInt32Parameter::UInt32Parameter(ParameterTypes::Type type, UInt32 value) + : Parameter(type), + mValue(value) +{} + +Parameter* +UInt32Parameter::clone() const +{ + return new UInt32Parameter(*this); +} + +EncodeStream& +UInt32Parameter::encode(EncodeStream& stream) const +{ + return stream << getName() << Symbols::EQUALS << mValue; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/UInt32Parameter.hxx b/src/libs/resiprocate/resip/stack/UInt32Parameter.hxx new file mode 100644 index 00000000..41bb004c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/UInt32Parameter.hxx @@ -0,0 +1,99 @@ +#if !defined(RESIP_UINT32PARAMETER_HXX) +#define RESIP_UINT32PARAMETER_HXX + +#include "rutil/resipfaststreams.hxx" + +#include "resip/stack/ParameterTypeEnums.hxx" +#include "resip/stack/Parameter.hxx" +#include "rutil/PoolBase.hxx" +#include <iosfwd> + +namespace resip +{ + +class ParseBuffer; + +/** + @ingroup sip_grammar + + @brief Generically represents unsigned 32-bit integer values + conveyed by SIP parameters. +*/ +class UInt32Parameter : public Parameter +{ + public: + typedef UInt32 Type; + + UInt32Parameter(ParameterTypes::Type, ParseBuffer& pb, const std::bitset<256>& terminators); + explicit UInt32Parameter(ParameterTypes::Type type, UInt32 value = 0); + + static Parameter* decode(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators, + PoolBase* pool) + { + return new (pool) UInt32Parameter(type, pb, terminators); + } + + virtual EncodeStream& encode(EncodeStream& stream) const; + + virtual Parameter* clone() const; + Type& value() {return mValue;} + + private: + UInt32 mValue; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/UdpTransport.cxx b/src/libs/resiprocate/resip/stack/UdpTransport.cxx new file mode 100644 index 00000000..2c542dde --- /dev/null +++ b/src/libs/resiprocate/resip/stack/UdpTransport.cxx @@ -0,0 +1,818 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <memory> + +#include "resip/stack/Helper.hxx" +#include "resip/stack/SendData.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/UdpTransport.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Socket.hxx" +#include "rutil/WinLeakCheck.hxx" +#include "rutil/compat.hxx" +#include "rutil/stun/Stun.hxx" + +#ifdef USE_SIGCOMP +#include <osc/Stack.h> +#include <osc/StateChanges.h> +#include <osc/SigcompMessage.h> +#endif + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +using namespace std; +using namespace resip; + +UdpTransport::UdpTransport(Fifo<TransactionMessage>& fifo, + int portNum, + IpVersion version, + StunSetting stun, + const Data& pinterface, + AfterSocketCreationFuncPtr socketFunc, + Compression &compression, + unsigned transportFlags) + : InternalTransport(fifo, portNum, version, pinterface, socketFunc, compression, transportFlags), + mSigcompStack(0), + mRxBuffer(0), + mExternalUnknownDatagramHandler(0), + mInWritable(false) +{ + mPollEventCnt = 0; + mTxTryCnt = mTxMsgCnt = mTxFailCnt = 0; + mRxTryCnt = mRxMsgCnt = mRxKeepaliveCnt = mRxTransactionCnt = 0; + mTuple.setType(transport()); + mFd = InternalTransport::socket(transport(), version); + mTuple.mFlowKey=(FlowKey)mFd; + bind(); // also makes it non-blocking + + InfoLog (<< "Creating UDP transport host=" << pinterface + << " port=" << mTuple.getPort() + << " ipv4=" << bool(version==V4) ); + +#ifdef USE_SIGCOMP + if (mCompression.isEnabled()) + { + DebugLog (<< "Compression enabled for transport: " << *this); + mSigcompStack = new osc::Stack(mCompression.getStateHandler()); + mCompression.addCompressorsToStack(mSigcompStack); + } + else + { + DebugLog (<< "Compression disabled for transport: " << *this); + } +#else + DebugLog (<< "No compression library available: " << *this); +#endif + mTxFifo.setDescription("UdpTransport::mTxFifo"); +} + +UdpTransport::~UdpTransport() +{ + InfoLog(<< "Shutting down " << mTuple + <<" tf="<<mTransportFlags<<" evt="<<(mPollGrp?1:0) + <<" stats:" + <<" poll="<<mPollEventCnt + <<" txtry="<<mTxTryCnt + <<" txmsg="<<mTxMsgCnt + <<" txfail="<<mTxFailCnt + <<" rxtry="<<mRxTryCnt + <<" rxmsg="<<mRxMsgCnt + <<" rxka="<<mRxKeepaliveCnt + <<" rxtr="<<mRxTransactionCnt + ); +#ifdef USE_SIGCOMP + delete mSigcompStack; +#endif + if ( mRxBuffer ) + { + delete[] mRxBuffer; + } + setPollGrp(0); +} + +void +UdpTransport::setPollGrp(FdPollGrp *grp) +{ + if(mPollGrp) + { + mPollGrp->delPollItem(mPollItemHandle); + mPollItemHandle=0; + } + + if(mFd!=INVALID_SOCKET && grp) + { + mPollItemHandle = grp->addPollItem(mFd, FPEM_Read, this); + // above released by InternalTransport destructor + // ?bwc? Is this really a good idea? If the InternalTransport d'tor is + // freeing this, shouldn't InternalTransport::setPollGrp() handle + // creating it? + } + + InternalTransport::setPollGrp(grp); +} + + +/** + * Called after a message is added. Could try writing it now. + */ +void +UdpTransport::process() { + mStateMachineFifo.flush(); + if ( (mTransportFlags & RESIP_TRANSPORT_FLAG_TXNOW)!= 0 ) + { + processTxAll(); + // FALLTHRU to code below in case queue not-empty + // shouldn't ever happen (with current code) + // but in future we may throttle transmits + } + if ( mPollGrp ) + updateEvents(); +} + +void +UdpTransport::updateEvents() +{ + //assert( mPollGrp ); + bool haveMsg = mTxFifoOutBuffer.messageAvailable(); + if ( !mInWritable && haveMsg ) + { + if (mPollGrp) + mPollGrp->modPollItem(mPollItemHandle, FPEM_Read|FPEM_Write); + mInWritable = true; + } + else if ( mInWritable && !haveMsg ) + { + if (mPollGrp) + mPollGrp->modPollItem(mPollItemHandle, FPEM_Read); + mInWritable = false; + } +} + + +void +UdpTransport::processPollEvent(FdPollEventMask mask) +{ + ++mPollEventCnt; + if ( mask & FPEM_Error ) + { + assert(0); + } + if ( mask & FPEM_Write ) + { + processTxAll(); + updateEvents(); // turn-off writability + } + if ( mask & FPEM_Read ) + { + processRxAll(); + } +} + +/** + If we return true, the TransactionController will set the timeout + to zero so that process() is called immediately. We don't want this; + instead, we depend upon the writable-socket callback (fdset or poll). +**/ +bool +UdpTransport::hasDataToSend() const +{ + return false; +} + +void +UdpTransport::buildFdSet( FdSet& fdset ) +{ + fdset.setRead(mFd); + + if (mTxFifoOutBuffer.messageAvailable()) + { + fdset.setWrite(mFd); + } +} + +void +UdpTransport::process(FdSet& fdset) +{ + // pull buffers to send out of TxFifo + // receive datagrams from fd + // preparse and stuff into RxFifo + + if (fdset.readyToWrite(mFd)) + { + processTxAll(); + } + + if ( fdset.readyToRead(mFd) ) + { + processRxAll(); + } + mStateMachineFifo.flush(); +} + +/** + * Added support for TXNOW and TXALL. Generally only makes sense + * to specify one of these. Limited testing shows limited performance + * gain from either of these: the socket-event overhead appears tiny. + */ +void +UdpTransport::processTxAll() +{ + SendData *msg; + ++mTxTryCnt; + while ( (msg=mTxFifoOutBuffer.getNext(RESIP_FIFO_NOWAIT)) != NULL ) + { + processTxOne(msg); + // With UDP we don't need to worry about write blocking (I hope) + if ( (mTransportFlags & RESIP_TRANSPORT_FLAG_TXALL)==0 ) + break; + } +} + +void +UdpTransport::processTxOne(SendData *data) +{ + ++mTxMsgCnt; + assert(data); + std::auto_ptr<SendData> sendData(data); + //DebugLog (<< "Sent: " << sendData->data); + //DebugLog (<< "Sending message on udp."); + assert( sendData->destination.getPort() != 0 ); + + const sockaddr& addr = sendData->destination.getSockaddr(); + int expected; + int count; + +#ifdef USE_SIGCOMP + // If message needs to be compressed, compress it here. + if (mSigcompStack && + sendData->sigcompId.size() > 0 && + !sendData->isAlreadyCompressed ) + { + osc::SigcompMessage *sm = mSigcompStack->compressMessage + (sendData->data.data(), sendData->data.size(), + sendData->sigcompId.data(), sendData->sigcompId.size(), + isReliable()); + + DebugLog (<< "Compressed message from " + << sendData->data.size() << " bytes to " + << sm->getDatagramLength() << " bytes"); + + expected = sm->getDatagramLength(); + + count = sendto(mFd, + sm->getDatagramMessage(), + sm->getDatagramLength(), + 0, // flags + &addr, sendData->destination.length()); + delete sm; + } + else +#endif + { + expected = (int)sendData->data.size(); + count = sendto(mFd, + sendData->data.data(), (int)sendData->data.size(), + 0, // flags + &addr, (int)sendData->destination.length()); + if (mTransportLogger && count != SOCKET_ERROR) + { + mTransportLogger->onSipMessage(TransportLogger::Flow_Sent, sendData->data.data(), + sendData->data.size(), &addr, sendData->destination.length()); + } + + } + + if ( count == SOCKET_ERROR ) + { + int e = getErrno(); + error(e); + InfoLog (<< "Failed (" << e << ") sending to " << sendData->destination); + fail(sendData->transactionId); + ++mTxFailCnt; + } + else + { + if (count != expected) + { + ErrLog (<< "UDPTransport - send buffer full" ); + fail(sendData->transactionId); + } + } +} + +/** + * Add options RXALL (to try receive all readable data) and KEEP_BUFFER. + * While each can be specified independently, generally should do both + * or neither. This is because with RXALL, every read cycle will have + * end with an EAGAIN read followed by buffer free (if no KEEP_BUFFER flag). + * Testing in very limited cases shows marginal (5%) performance improvements. + * Probably "real" traffic (that is bursty) would more impact. + */ +void +UdpTransport::processRxAll() +{ + char *buffer = mRxBuffer; + mRxBuffer = NULL; + ++mRxTryCnt; + for (;;) + { + // TBD: check StateMac capacity + Tuple sender(mTuple); + int len = processRxRecv(buffer, sender); + if ( len <= 0 ) + break; + ++mRxMsgCnt; + if ( processRxParse(buffer, len, sender) ) + { + buffer = NULL; + } + if ( (mTransportFlags & RESIP_TRANSPORT_FLAG_RXALL)==0 ) + break; + } + if ( buffer && (mTransportFlags & RESIP_TRANSPORT_FLAG_KEEP_BUFFER)!=0 ) + { + assert(mRxBuffer==NULL); + mRxBuffer = buffer; + buffer = NULL; + } + if ( buffer ) + delete[] buffer; +} + +/* + * Receive from socket and store results into {buffer}. Updates + * {buffer} with actual buffer (in case allocation required), + * {len} with length of receive data, and {sender} with who + * sent the packet. + * Return length of data read: + * 0 if no data read and no more data to read (EAGAIN) + * >0 if data read and may be more data to read +**/ +int +UdpTransport::processRxRecv(char*& buffer, Tuple& sender) +{ + // !jf! this may have to change - when we read a message that is too big + //should this buffer be allocated on the stack and then copied out, as it + //needs to be deleted every time EWOULDBLOCK is encountered + // .dlb. can we determine the size of the buffer before we allocate? + // something about MSG_PEEK|MSG_TRUNC in Stevens.. + // .dlb. RFC3261 18.1.1 MUST accept 65K datagrams. would have to attempt to + // adjust the UDP buffer as well... + if (buffer==NULL) + { + buffer = MsgHeaderScanner::allocateBuffer(MaxBufferSize); + } + + for (;;) { + // !jf! how do we tell if it discarded bytes + // !ah! we use the len-1 trick :-( + socklen_t slen = sender.length(); + int len = recvfrom( mFd, + buffer, + MaxBufferSize, + 0 /*flags */, + &sender.getMutableSockaddr(), + &slen); + if ( len == SOCKET_ERROR ) + { + int err = getErrno(); + if ( err != EWOULDBLOCK ) + { + error( err ); + } + len = 0; + } + if (len+1 >= MaxBufferSize) + { + InfoLog(<<"Datagram exceeded max length "<<MaxBufferSize); + continue; + } + return len; + } +} + + +/** + * Parse the contents of {buffer} and do something with it. + * Return true iff {buffer} was consumed (absorbed into SipMessage + * to be free'd later). Note return code doesn't indicate + * "success" in parsing the message; rather, it just indicates + * who owns buffer. +**/ +bool +UdpTransport::processRxParse(char *buffer, int len, Tuple& sender) +{ + bool origBufferConsumed = true; + + //handle incoming CRLFCRLF keep-alive packets + if (len == 4 && + strncmp(buffer, Symbols::CRLFCRLF, len) == 0) + { + StackLog(<<"Throwing away incoming firewall keep-alive"); + ++mRxKeepaliveCnt; + return false; + } + + // this must be a STUN response (or garbage) + if (buffer[0] == 1 && buffer[1] == 1 && ipVersion() == V4) + { + resip::Lock lock(myMutex); + StunMessage resp; + memset(&resp, 0, sizeof(StunMessage)); + + if (stunParseMessage(buffer, len, resp, false)) + { + in_addr sin_addr; + // Use XorMappedAddress if present - if not use MappedAddress + if(resp.hasXorMappedAddress) + { + UInt16 id16 = resp.msgHdr.id.octet[0]<<8 + | resp.msgHdr.id.octet[1]; + UInt32 id32 = resp.msgHdr.id.octet[0]<<24 + | resp.msgHdr.id.octet[1]<<16 + | resp.msgHdr.id.octet[2]<<8 + | resp.msgHdr.id.octet[3]; + resp.xorMappedAddress.ipv4.port = resp.xorMappedAddress.ipv4.port^id16; + resp.xorMappedAddress.ipv4.addr = resp.xorMappedAddress.ipv4.addr^id32; + +#if defined(WIN32) + sin_addr.S_un.S_addr = htonl(resp.xorMappedAddress.ipv4.addr); +#else + sin_addr.s_addr = htonl(resp.xorMappedAddress.ipv4.addr); +#endif + mStunMappedAddress = Tuple(sin_addr,resp.xorMappedAddress.ipv4.port, UDP); + mStunSuccess = true; + } + else if(resp.hasMappedAddress) + { +#if defined(WIN32) + sin_addr.S_un.S_addr = htonl(resp.mappedAddress.ipv4.addr); +#else + sin_addr.s_addr = htonl(resp.mappedAddress.ipv4.addr); +#endif + mStunMappedAddress = Tuple(sin_addr,resp.mappedAddress.ipv4.port, UDP); + mStunSuccess = true; + } + } + return false; + } + + // this must be a STUN request (or garbage) + if (buffer[0] == 0 && buffer[1] == 1 && ipVersion() == V4) + { + bool changePort = false; + bool changeIp = false; + + StunAddress4 myAddr; + const sockaddr_in& bi = (const sockaddr_in&)boundInterface(); + myAddr.addr = ntohl(bi.sin_addr.s_addr); + myAddr.port = ntohs(bi.sin_port); + + StunAddress4 from; // packet source + const sockaddr_in& fi = (const sockaddr_in&)sender.getSockaddr(); + from.addr = ntohl(fi.sin_addr.s_addr); + from.port = ntohs(fi.sin_port); + + StunMessage resp; + StunAddress4 dest; + StunAtrString hmacPassword; + hmacPassword.sizeValue = 0; + + StunAddress4 secondary; + secondary.port = 0; + secondary.addr = 0; + + bool ok = stunServerProcessMsg( buffer, len, // input buffer + from, // packet source + secondary, // not used + myAddr, // address to fill into response + myAddr, // not used + &resp, // stun response + &dest, // where to send response + &hmacPassword, // not used + &changePort, // not used + &changeIp, // not used + false ); // logging + + if (ok) + { + DebugLog(<<"Got UDP STUN keepalive. Sending response..."); + char* response = new char[STUN_MAX_MESSAGE_SIZE]; + int rlen = stunEncodeMessage( resp, + response, + STUN_MAX_MESSAGE_SIZE, + hmacPassword, + false ); + SendData* stunResponse = new SendData(sender, response, rlen); + mTxFifo.add(stunResponse); + } + return false; + } + +#ifdef USE_SIGCOMP + osc::StateChanges *sc = 0; +#endif + + // Attempt to decode SigComp message, if appropriate. + if ((buffer[0] & 0xf8) == 0xf8) + { + if (!mCompression.isEnabled()) + { + InfoLog(<< "Discarding unexpected SigComp Message"); + return false; + } +#ifdef USE_SIGCOMP + char* newBuffer = MsgHeaderScanner::allocateBuffer(MaxBufferSize); + size_t uncompressedLength = + mSigcompStack->uncompressMessage(buffer, len, + newBuffer, MaxBufferSize, sc); + + DebugLog (<< "Uncompressed message from " + << len << " bytes to " + << uncompressedLength << " bytes"); + + + osc::SigcompMessage *nack = mSigcompStack->getNack(); + + if (nack) + { + mTxFifo.add(new SendData(tuple, + Data(nack->getDatagramMessage(), + nack->getDatagramLength()), + Data::Empty, + Data::Empty, + true) + ); + delete nack; + } + + // delete[] buffer; NO: let caller do this if needed + origBufferConsumed = false; + buffer = newBuffer; + len = uncompressedLength; +#endif + } + + buffer[len]=0; // null terminate the buffer string just to make debug easier and reduce errors + if (mTransportLogger) + { + mTransportLogger->onSipMessage(TransportLogger::Flow_Received, buffer, len, &sender.getSockaddr(), sender.length()); + } + + //DebugLog ( << "UDP Rcv : " << len << " b" ); + //DebugLog ( << Data(buffer, len).escaped().c_str()); + + SipMessage* message = new SipMessage(this); + + // set the received from information into the received= parameter in the + // via + + // It is presumed that UDP Datagrams are arriving atomically and that + // each one is a unique SIP message + + + // Save all the info where this message came from + sender.transport = this; + sender.transportKey = getKey(); + sender.mFlowKey=mTuple.mFlowKey; + message->setSource(sender); + //DebugLog (<< "Received from: " << sender); + + // Tell the SipMessage about this datagram buffer. + // WATCHOUT: below here buffer is consumed by message + message->addBuffer(buffer); + + mMsgHeaderScanner.prepareForMessage(message); + + char *unprocessedCharPtr; + if (mMsgHeaderScanner.scanChunk(buffer, + len, + &unprocessedCharPtr) != + MsgHeaderScanner::scrEnd) + { + StackLog(<<"Scanner rejecting datagram as unparsable / fragmented from " << sender); + StackLog(<< Data(Data::Borrow, buffer, len)); + if(mExternalUnknownDatagramHandler) + { + auto_ptr<Data> datagram(new Data(buffer,len)); + (*mExternalUnknownDatagramHandler)(this,sender,datagram); + } + + // Idea: consider backing buffer out of message and letting caller reuse it + delete message; + message=0; + return origBufferConsumed; + } + + // no pp error + int used = int(unprocessedCharPtr - buffer); + + if (used < len) + { + // body is present .. add it up. + // NB. The Sip Message uses an overlay (again) + // for the body. It ALSO expects that the body + // will be contiguous (of course). + // it doesn't need a new buffer in UDP b/c there + // will only be one datagram per buffer. (1:1 strict) + + message->setBody(buffer+used,len-used); + //DebugLog(<<"added " << len-used << " byte body"); + } + + // .bwc. basicCheck takes up substantial CPU. Don't bother doing it + // if we're overloaded. + CongestionManager::RejectionBehavior behavior=getRejectionBehaviorForIncoming(); + if (behavior==CongestionManager::REJECTING_NON_ESSENTIAL + || (behavior==CongestionManager::REJECTING_NEW_WORK + && message->isRequest())) + { + // .bwc. If this fifo is REJECTING_NEW_WORK, we will drop + // requests but not responses ( ?bwc? is this right for ACK?). + // If we are REJECTING_NON_ESSENTIAL, + // we reject all incoming work, since losing something from the + // wire will not cause instability or leaks (see + // CongestionManager.hxx) + + // .bwc. This handles all appropriate checking for whether + // this is a response or an ACK. + std::auto_ptr<SendData> tryLater(make503(*message, getExpectedWaitForIncoming()/1000)); + if(tryLater.get()) + { + send(tryLater); + } + delete message; // dropping message due to congestion + message = 0; + return origBufferConsumed; + } + + if (!basicCheck(*message)) + { + delete message; // cannot use it, so, punt on it... + // basicCheck queued any response required + message = 0; + return origBufferConsumed; + } + + stampReceived(message); + +#ifdef USE_SIGCOMP + if (mCompression.isEnabled() && sc) + { + const Via &via = message->header(h_Vias).front(); + if (message->isRequest()) + { + // For requests, the compartment ID is read out of the + // top via header field; if not present, we use the + // TCP connection for identification purposes. + if (via.exists(p_sigcompId)) + { + Data compId = via.param(p_sigcompId); + if(!compId.empty()) + { + // .bwc. Crash was happening here. Why was there an empty sigcomp + // id? + mSigcompStack->provideCompartmentId( + sc, compId.data(), compId.size()); + } + } + else + { + mSigcompStack->provideCompartmentId(sc, this, sizeof(this)); + } + } + else + { + // For responses, the compartment ID is supposed to be + // the same as the compartment ID of the request. We + // *could* dig down into the transaction layer to try to + // figure this out, but that's a royal pain, and a rather + // severe layer violation. In practice, we're going to ferret + // the ID out of the the Via header field, which is where we + // squirreled it away when we sent this request in the first place. + // !bwc! This probably shouldn't be going out over the wire. + Data compId = via.param(p_branch).getSigcompCompartment(); + if(!compId.empty()) + { + mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size()); + } + } + + } +#endif + + mStateMachineFifo.add(message); + ++mRxTransactionCnt; + return origBufferConsumed; +} + + + +bool +UdpTransport::stunSendTest(const Tuple& dest) +{ + bool changePort=false; + bool changeIP=false; + + StunAtrString username; + StunAtrString password; + + username.sizeValue = 0; + password.sizeValue = 0; + + StunMessage req; + memset(&req, 0, sizeof(StunMessage)); + + stunBuildReqSimple(&req, username, changePort , changeIP , 1); + + char* buf = new char[STUN_MAX_MESSAGE_SIZE]; + int len = STUN_MAX_MESSAGE_SIZE; + + int rlen = stunEncodeMessage(req, buf, len, password, false); + + SendData* stunRequest = new SendData(dest, buf, rlen); + mTxFifo.add(stunRequest); + + mStunSuccess = false; + + return true; +} + +bool +UdpTransport::stunResult(Tuple& mappedAddress) +{ + resip::Lock lock(myMutex); + + if (mStunSuccess) + { + mappedAddress = mStunMappedAddress; + } + return mStunSuccess; +} + +void +UdpTransport::setExternalUnknownDatagramHandler(ExternalUnknownDatagramHandler *handler) +{ + mExternalUnknownDatagramHandler = handler; +} + +void +UdpTransport::setRcvBufLen(int buflen) +{ + setSocketRcvBufLen(mFd, buflen); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/UdpTransport.hxx b/src/libs/resiprocate/resip/stack/UdpTransport.hxx new file mode 100644 index 00000000..b2513764 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/UdpTransport.hxx @@ -0,0 +1,177 @@ +#if !defined(RESIP_UDPTRANSPORT_HXX) +#define RESIP_UDPTRANSPORT_HXX + +#include <memory> +#include "resip/stack/InternalTransport.hxx" +#include "resip/stack/MsgHeaderScanner.hxx" +#include "rutil/HeapInstanceCounter.hxx" +#include "resip/stack/Compression.hxx" + +namespace osc { class Stack; } + +namespace resip +{ +class UdpTransport; + +/** Interface functor for external unrecognized datagram handling. + * User can catch datagram messages recevied that are not recognized by + * the stack. + */ +class ExternalUnknownDatagramHandler { +public: + virtual ~ExternalUnknownDatagramHandler(){}; + + /** . + * @param transport contains a pointer to the specific UdpTransport object that + * received the unknown packet. + * @param unknownDatagram contains the actual contents of unknown data received. */ + virtual void operator()(UdpTransport* transport, const Tuple& source, std::auto_ptr<Data> unknownDatagram) = 0; +}; + +/** + @ingroup transports + + @brief A Transport based on UDP. + + @internal Used in test cases, TransportSelector (which is itself + internal), DtlsTransport as a base class and in + SipStack::addTransport(...). Not expected to be used in an API. +*/ +class UdpTransport : public InternalTransport, public FdPollItemIf +{ +public: + RESIP_HeapCount(UdpTransport); + /** + @param fifo the TransactionMessage Fifo that will receive + any ConnectionTerminated or TransportFailure messages. + + @param interfaceObj a "presentation format" representation + of the IP address of this transport + @see Tuple::inet_ntop() for information about "presentation + format" + + @param portNum is the port to receive and/or send on + + @param socketFunc Functor (defined in rutil/Socket.hxx) that is called + when a socket is created; allows app to log fd creation, tweak + sockopts, and so forth. + */ + UdpTransport(Fifo<TransactionMessage>& fifo, + int portNum, + IpVersion version, + StunSetting stun, + const Data& interfaceObj, + AfterSocketCreationFuncPtr socketFunc = 0, + Compression &compression = Compression::Disabled, + unsigned transportFlags = 0); + virtual ~UdpTransport(); + + virtual TransportType transport() const { return UDP; } + virtual bool isReliable() const { return false; } + virtual bool isDatagram() const { return true; } + + virtual void process(FdSet& fdset); + virtual void process(); + virtual bool hasDataToSend() const; + virtual void buildFdSet( FdSet& fdset); + virtual void setPollGrp(FdPollGrp *grp); + virtual void setRcvBufLen(int buflen); + + // FdPollItemIf + // virtual Socket getPollSocket() const; + virtual void processPollEvent(FdPollEventMask mask); + + static const int MaxBufferSize = 8192; + + // STUN client functionality + bool stunSendTest(const Tuple& dest); + bool stunResult(Tuple& mappedAddress); + + /// Installs a handler for the unknown datagrams arriving on the udp transport. + void setExternalUnknownDatagramHandler(ExternalUnknownDatagramHandler *handler); + +protected: + + void processRxAll(); + int processRxRecv(char*& buffer, Tuple& sender); + bool processRxParse(char *buffer, int len, Tuple& sender); + void processTxAll(); + void processTxOne(SendData *data); + void updateEvents(); + + osc::Stack *mSigcompStack; + + // statistics + unsigned mPollEventCnt; + unsigned mTxTryCnt; + unsigned mTxMsgCnt; + unsigned mTxFailCnt; + unsigned mRxTryCnt; + unsigned mRxMsgCnt; + unsigned mRxKeepaliveCnt; + unsigned mRxTransactionCnt; +private: + char* mRxBuffer; + MsgHeaderScanner mMsgHeaderScanner; + mutable resip::Mutex myMutex; + Tuple mStunMappedAddress; + bool mStunSuccess; + ExternalUnknownDatagramHandler* mExternalUnknownDatagramHandler; + bool mInWritable; + bool mInActiveWrite; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/UnknownHeaderType.hxx b/src/libs/resiprocate/resip/stack/UnknownHeaderType.hxx new file mode 100644 index 00000000..c69d4dba --- /dev/null +++ b/src/libs/resiprocate/resip/stack/UnknownHeaderType.hxx @@ -0,0 +1,63 @@ +#if !defined(RESIP_UNKNOWNHEADERTYPE_HXX) +#define RESIP_UNKNOWNHEADERTYPE_HXX + +// !dlb! deprecated -- use ExtensionHeader.hxx + +#include "ExtensionHeader.hxx" + +namespace resip +{ + typedef ExtensionHeader UnknownHeaderType; +}; + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/UnknownParameter.cxx b/src/libs/resiprocate/resip/stack/UnknownParameter.cxx new file mode 100644 index 00000000..3e5ff247 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/UnknownParameter.cxx @@ -0,0 +1,142 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/UnknownParameter.hxx" +#include "rutil/ParseBuffer.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +UnknownParameter::UnknownParameter(const char* startName, + unsigned int nameSize, + ParseBuffer& pb, + const std::bitset<256>& terminators) + : Parameter(ParameterTypes::UNKNOWN), + mName(startName, nameSize), + mValue(), + mIsQuoted(false) +{ + pb.skipWhitespace(); + if (!pb.eof() && *pb.position() == Symbols::EQUALS[0]) + { + pb.skipChar(Symbols::EQUALS[0]); + pb.skipWhitespace(); + if (*pb.position() == Symbols::DOUBLE_QUOTE[0]) + { + setQuoted(true); + pb.skipChar(); + const char* pos = pb.position(); + pb.skipToEndQuote(); + pb.data(mValue, pos); + pb.skipChar(); + } + else + { + const char* pos = pb.position(); + pb.skipToOneOf(terminators); + pb.data(mValue, pos); + } + + } + else + { + // must be a terminator -- exists style + } +} + +UnknownParameter::UnknownParameter(const Data& name) + : Parameter(ParameterTypes::UNKNOWN), + mName(name), + mIsQuoted(false) +{ +} + +const Data& +UnknownParameter::getName() const +{ + return mName; +} + + +Parameter* +UnknownParameter::clone() const +{ + return new UnknownParameter(*this); +} + +EncodeStream& +UnknownParameter::encode(EncodeStream& stream) const +{ + if (mIsQuoted) + { + return stream << getName() << Symbols::EQUALS + << Symbols::DOUBLE_QUOTE << mValue << Symbols::DOUBLE_QUOTE; + } + else if (!mValue.empty()) + { + return stream << getName() << Symbols::EQUALS << mValue; + } + else + { + return stream << getName(); + } +} + +EncodeStream& operator<<(EncodeStream& stream, UnknownParameter& comp) +{ + return stream << comp.getName() << "=" << comp.value(); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/UnknownParameter.hxx b/src/libs/resiprocate/resip/stack/UnknownParameter.hxx new file mode 100644 index 00000000..42440e5d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/UnknownParameter.hxx @@ -0,0 +1,102 @@ +#if !defined(RESIP_UNKNOWNPARAMETER_HXX) +#define RESIP_UNKNOWNPARAMETER_HXX + +#include <iosfwd> +#include "resip/stack/Parameter.hxx" + +namespace resip +{ + +class ParseBuffer; + +/** + @ingroup sip_grammar + + @brief Generically used to represent any parameter that is not + known by the implmentation. +*/ +class UnknownParameter : public Parameter +{ + public: + UnknownParameter(const char* startName, + unsigned int nameSize, + ParseBuffer& pb, + const std::bitset<256>& terminators); + + // empty value indicates exists style (e.g. ;unknown;...) + UnknownParameter(ParameterTypes::Type type, const Data& value); + + // for making a new unknown parameter + explicit UnknownParameter(const Data& name); + EncodeStream& encode(EncodeStream& stream) const; + + Data& value() {return mValue;} + const Data& value() const {return mValue;} + bool hasValue() const {return !mValue.empty() || mIsQuoted;} + bool isQuoted() const { return mIsQuoted; } + void setQuoted(bool b) { mIsQuoted = b; }; // this parameter will be enclosed in quotes e.g. "foo" + + virtual const Data& getName() const; + virtual Parameter* clone() const; + + private: + Data mName; + Data mValue; + bool mIsQuoted; +}; + +} + +EncodeStream& operator<<(EncodeStream& stream, resip::UnknownParameter& comp); + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/UnknownParameterType.hxx b/src/libs/resiprocate/resip/stack/UnknownParameterType.hxx new file mode 100644 index 00000000..d09e3b1b --- /dev/null +++ b/src/libs/resiprocate/resip/stack/UnknownParameterType.hxx @@ -0,0 +1,63 @@ +#if !defined(RESIP_UNKNOWNPARAMETERTYPE_HXX) +#define RESIP_UNKNOWNPARAMETERTYPE_HXX + +// !dlb! deprecated + +#include "resip/stack/ExtensionParameter.hxx" + +namespace resip +{ +typedef ExtensionParameter UnknownParameterType; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Uri.cxx b/src/libs/resiprocate/resip/stack/Uri.cxx new file mode 100644 index 00000000..6b5a7542 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Uri.cxx @@ -0,0 +1,1413 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <set> + +#include "resip/stack/Embedded.hxx" +#include "resip/stack/Helper.hxx" +#include "resip/stack/NameAddr.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Symbols.hxx" +#include "resip/stack/UnknownParameter.hxx" +#include "resip/stack/Uri.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP +#define HANDLE_CHARACTER_ESCAPING //undef for old behaviour + +static bool initAllTables() +{ + Uri::getUserEncodingTable(); + Uri::getPasswordEncodingTable(); + Uri::getLocalNumberTable(); + Uri::getGlobalNumberTable(); + return true; +} + +const bool Uri::tablesMightBeInitialized(initAllTables()); + +Uri::Uri(PoolBase* pool) + : ParserCategory(pool), + mScheme(Data::Share, Symbols::DefaultSipScheme), + mPort(0), + mHostCanonicalized(false) +{ +} + +Uri::Uri(const HeaderFieldValue& hfv, Headers::Type type, PoolBase* pool) : + ParserCategory(hfv, type, pool), + mPort(0), + mHostCanonicalized(false) +{} + + +static const Data parseContext("Uri constructor"); +Uri::Uri(const Data& data) + : ParserCategory(), + mScheme(Symbols::DefaultSipScheme), + mPort(0), + mHostCanonicalized(false) +{ + HeaderFieldValue hfv(data.data(), data.size()); + // must copy because parse creates overlays + Uri tmp(hfv, Headers::UNKNOWN); + tmp.checkParsed(); + *this = tmp; +} + +Uri::Uri(const Uri& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mScheme(rhs.mScheme), + mHost(rhs.mHost), + mUser(rhs.mUser), + mUserParameters(rhs.mUserParameters), + mPort(rhs.mPort), + mPassword(rhs.mPassword), + mHostCanonicalized(rhs.mHostCanonicalized), + mEmbeddedHeadersText(rhs.mEmbeddedHeadersText.get() ? new Data(*rhs.mEmbeddedHeadersText) : 0), + mEmbeddedHeaders(rhs.mEmbeddedHeaders.get() ? new SipMessage(*rhs.mEmbeddedHeaders) : 0) +{} + + +Uri::~Uri() +{} + +// RFC 3261 19.1.6 +#if 0 // deprecated +Uri +Uri::fromTel(const Uri& tel, const Data& host) +{ + assert(tel.scheme() == Symbols::Tel); + + Uri u; + u.scheme() = Symbols::Sip; + u.user() = tel.user(); + u.host() = host; + u.param(p_user) = Symbols::Phone; + + // need to sort the user parameters + if (!tel.userParameters().empty()) + { + DebugLog(<< "Uri::fromTel: " << tel.userParameters()); + Data isub; + Data postd; + + int totalSize = 0; + std::set<Data> userParameters; + + ParseBuffer pb(tel.userParameters().data(), tel.userParameters().size()); + while (true) + { + const char* anchor = pb.position(); + pb.skipToChar(Symbols::SEMI_COLON[0]); + Data param = pb.data(anchor); + // !dlb! not supposed to lowercase extension parameters + param.lowercase(); + totalSize += param.size() + 1; + + if (param.prefix(Symbols::Isub)) + { + isub = param; + } + else if (param.prefix(Symbols::Postd)) + { + postd = param; + } + else + { + userParameters.insert(param); + } + if (pb.eof()) + { + break; + } + else + { + pb.skipChar(); + } + } + + u.userParameters().reserve(totalSize); + if (!isub.empty()) + { + u.userParameters() = isub; + } + if (!postd.empty()) + { + if (!u.userParameters().empty()) + { + u.userParameters() += Symbols::SEMI_COLON[0]; + } + u.userParameters() += postd; + } + + for(std::set<Data>::const_iterator i = userParameters.begin(); + i != userParameters.end(); ++i) + { + DebugLog(<< "Adding param: " << *i); + if (!u.userParameters().empty()) + { + u.userParameters() += Symbols::SEMI_COLON[0]; + } + u.userParameters() += *i; + } + } + + return u; +} +#endif // deprecated + +Uri +Uri::fromTel(const Uri& tel, const Uri& hostUri) +{ + assert(tel.scheme() == Symbols::Tel); + + Uri u(hostUri); + u.scheme() = Symbols::Sip; + u.user() = tel.user(); + u.param(p_user) = Symbols::Phone; + + // need to sort the user parameters + if (!tel.userParameters().empty()) + { + DebugLog(<< "Uri::fromTel: " << tel.userParameters()); + Data isub; + Data postd; + + int totalSize = 0; + std::set<Data> userParameters; + + ParseBuffer pb(tel.userParameters().data(), tel.userParameters().size()); + while (true) + { + const char* anchor = pb.position(); + pb.skipToChar(Symbols::SEMI_COLON[0]); + Data param = pb.data(anchor); + // !dlb! not supposed to lowercase extension parameters + param.lowercase(); + totalSize += (int)param.size() + 1; + + if (param.prefix(Symbols::Isub)) + { + isub = param; + } + else if (param.prefix(Symbols::Postd)) + { + postd = param; + } + else + { + userParameters.insert(param); + } + if (pb.eof()) + { + break; + } + else + { + pb.skipChar(); + } + } + + u.userParameters().reserve(totalSize); + if (!isub.empty()) + { + u.userParameters() = isub; + } + if (!postd.empty()) + { + if (!u.userParameters().empty()) + { + u.userParameters() += Symbols::SEMI_COLON[0]; + } + u.userParameters() += postd; + } + + for(std::set<Data>::const_iterator i = userParameters.begin(); + i != userParameters.end(); ++i) + { + DebugLog(<< "Adding param: " << *i); + if (!u.userParameters().empty()) + { + u.userParameters() += Symbols::SEMI_COLON[0]; + } + u.userParameters() += *i; + } + } + + return u; +} + +bool +Uri::isEnumSearchable() const +{ + checkParsed(); + int digits = 0; + + if(mUser.size() < 4) + { + StackLog(<< "user part of Uri empty or too short for E.164"); + return false; + } + + // E.164 numbers must begin with a + and have at least + // 3 digits + if(mUser[0] != '+') + { + StackLog(<< "user part of Uri does not begin with `+' or too short"); + return false; + } + + // count the digits (skip the leading `+') + for(const char* i=user().begin() + 1; i!= user().end(); i++) + { + if(isdigit(*i)) + digits++; + else + if(*i != '-') + { + StackLog(<< "user part of Uri contains non-digit: " << *i); + return false; // Only digits and '-' permitted + } + } + if(digits > 15) + { + // E.164 only permits 15 digits in a phone number + StackLog(<< "user part of Uri contains more than 15 digits"); + return false; + } + + DebugLog(<< "is in E.164 format for ENUM: " << mUser); + return true; +} + +std::vector<Data> +Uri::getEnumLookups(const std::vector<Data>& suffixes) const +{ + std::vector<Data> results; + Data prefix; + if (isEnumSearchable()) + { + // skip the leading + + for (const char* i=user().end()-1 ; i!= user().begin(); --i) + { + if (isdigit(*i)) + { + prefix += *i; + prefix += Symbols::DOT; + } + } + StackLog(<< "E.164 number reversed for ENUM query: " << prefix); + for (std::vector<Data>::const_iterator j=suffixes.begin(); j != suffixes.end(); ++j) + { + results.push_back(prefix + *j); + } + } + return results; +} + + +bool +Uri::hasEmbedded() const +{ + checkParsed(); + return (mEmbeddedHeadersText.get() && !mEmbeddedHeadersText->empty()) || mEmbeddedHeaders.get() != 0; +} + +void +Uri::removeEmbedded() +{ + checkParsed(); + mEmbeddedHeaders.reset(); + mEmbeddedHeadersText.reset(); +} + + + +Uri& +Uri::operator=(const Uri& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mScheme = rhs.mScheme; + mHost = rhs.mHost; + mHostCanonicalized=rhs.mHostCanonicalized; + mUser = rhs.mUser; + mUserParameters = rhs.mUserParameters; + mPort = rhs.mPort; + mPassword = rhs.mPassword; + if (rhs.mEmbeddedHeaders.get() != 0) + { + mEmbeddedHeaders.reset(new SipMessage(*rhs.mEmbeddedHeaders)); + } + else if(rhs.mEmbeddedHeadersText.get() != 0) + { + if(!mEmbeddedHeadersText.get()) + { + mEmbeddedHeadersText.reset(new Data(*rhs.mEmbeddedHeadersText)); + } + else + { + // !bwc! Data::operator= is smart enough to handle this safely. + *mEmbeddedHeadersText = *rhs.mEmbeddedHeadersText; + } + } + } + return *this; +} + +/** + @class OrderUnknownParameters + @brief used as a comparator for sorting purposes + */ +class OrderUnknownParameters +{ + public: + /** + @brief constructor ; never called explicitly + */ + OrderUnknownParameters() { notUsed=false; }; + + /** + @brief empty destructor + */ + ~OrderUnknownParameters() {}; + + /** + @brief used as a comparator for sorting purposes + This does a straight Data comparison for name and returns true/false + @param p1 pointer to parameter 1 + @param p2 pointer to parameter 2 + @return true if p1->getName() is less than p2->getName() + else return false + */ + bool operator()(const Parameter* p1, const Parameter* p2) const + { + return dynamic_cast<const UnknownParameter*>(p1)->getName() < dynamic_cast<const UnknownParameter*>(p2)->getName(); + } + + private: + bool notUsed; +}; + +bool +Uri::operator==(const Uri& other) const +{ + checkParsed(); + other.checkParsed(); + + // compare hosts + if (DnsUtil::isIpV6Address(mHost) && + DnsUtil::isIpV6Address(other.mHost)) + { + + // compare canonicalized IPV6 addresses + + // update canonicalized if host changed + if (!mHostCanonicalized) + { + mHost = DnsUtil::canonicalizeIpV6Address(mHost); + mHostCanonicalized=true; + } + + // update canonicalized if host changed + if (!other.mHostCanonicalized) + { + other.mHost = DnsUtil::canonicalizeIpV6Address(other.mHost); + other.mHostCanonicalized=true; + } + + if (mHost != other.mHost) + { + return false; + } + } + else + { + if (!isEqualNoCase(mHost, other.mHost)) + { + return false; + } + } + + if (isEqualNoCase(mScheme, other.mScheme) && + ((isEqualNoCase(mScheme, Symbols::Sip) || isEqualNoCase(mScheme, Symbols::Sips)) ? mUser == other.mUser : isEqualNoCase(mUser, other.mUser)) && + isEqualNoCase(mUserParameters,other.mUserParameters) && + mPassword == other.mPassword && + mPort == other.mPort) + { + for (ParameterList::const_iterator it = mParameters.begin(); it != mParameters.end(); ++it) + { + Parameter* otherParam = other.getParameterByEnum((*it)->getType()); + + switch ((*it)->getType()) + { + case ParameterTypes::user: + { + if (!(otherParam && + isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(), + dynamic_cast<DataParameter*>(otherParam)->value()))) + { + return false; + } + } + break; + case ParameterTypes::ttl: + { + if (!(otherParam && + (dynamic_cast<UInt32Parameter*>(*it)->value() == + dynamic_cast<UInt32Parameter*>(otherParam)->value()))) + { + return false; + } + break; + } + case ParameterTypes::method: + { + // this should possibly be case sensitive, but is allowed to be + // case insensitive for robustness. + + if (otherParam) + { + DataParameter* dp1 = dynamic_cast<DataParameter*>(*it); + DataParameter* dp2 = dynamic_cast<DataParameter*>(otherParam); + (void)dp1; + (void)dp2; + // ?bwc? It looks like we're just assuming the dynamic_cast + // will succeed everywhere else; why are we bothering to + // assert()? + assert(dp1); + assert(dp2); + } + if (!(otherParam && + isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(), + dynamic_cast<DataParameter*>(otherParam)->value()))) + { + return false; + } + break; + } + case ParameterTypes::maddr: + { + if (!(otherParam && + isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(), + dynamic_cast<DataParameter*>(otherParam)->value()))) + { + return false; + } + } + break; + case ParameterTypes::transport: + { + if (!(otherParam && + isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(), + dynamic_cast<DataParameter*>(otherParam)->value()))) + { + return false; + } + } + break; + // the parameters that follow don't affect comparison if only present + // in one of the URI's + case ParameterTypes::lr: + break; + default: + break; + //treat as unknown parameter? + } + } + + // now check the other way, sigh + for (ParameterList::const_iterator it = other.mParameters.begin(); it != other.mParameters.end(); ++it) + { + Parameter* param = getParameterByEnum((*it)->getType()); + switch ((*it)->getType()) + { + case ParameterTypes::user: + { + if (!(param && + isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(), + dynamic_cast<DataParameter*>(param)->value()))) + { + return false; + } + } + break; + case ParameterTypes::ttl: + { + if (!(param && + (dynamic_cast<UInt32Parameter*>(*it)->value() == + dynamic_cast<UInt32Parameter*>(param)->value()))) + { + return false; + } + break; + } + case ParameterTypes::method: + { + // this should possilby be case sensitive, but is allowed to be + // case insensitive for robustness. + if (!(param && + isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(), + dynamic_cast<DataParameter*>(param)->value()))) + { + return false; + } + } + break; + case ParameterTypes::maddr: + { + if (!(param && + isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(), + dynamic_cast<DataParameter*>(param)->value()))) + { + return false; + } + } + break; + case ParameterTypes::transport: + { + if (!(param && + isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(), + dynamic_cast<DataParameter*>(param)->value()))) + { + return false; + } + } + break; + // the parameters that follow don't affect comparison if only present + // in one of the URI's + case ParameterTypes::lr: + break; + default: + break; + //treat as unknown parameter? + } + } + } + else + { + return false; + } + + OrderUnknownParameters orderUnknown; + +#if defined(__SUNPRO_CC) || defined(WIN32) || defined(__sun__) + // The Solaris Forte STL implementation does not support the + // notion of a list.sort() function taking a BinaryPredicate. + // The hacky workaround is to load the Parameter pointers into + // an STL set which does support an ordering function. + + typedef std::set<Parameter*, OrderUnknownParameters> ParameterSet; + ParameterSet unA, unB; + + for (ParameterList::const_iterator i = mUnknownParameters.begin(); + i != mUnknownParameters.end(); ++i) + { + unA.insert(*i); + } + for (ParameterList::const_iterator i = other.mUnknownParameters.begin(); + i != other.mUnknownParameters.end(); ++i) + { + unB.insert(*i); + } + + ParameterSet::iterator a = unA.begin(); + ParameterSet::iterator b = unB.begin(); +#else + // .dlb. more efficient to copy to vector for sorting? + // Uri comparison is expensive; consider caching? ugh + ParameterList unA = mUnknownParameters; + ParameterList unB = other.mUnknownParameters; + + sort(unA.begin(), unA.end(), orderUnknown); + sort(unB.begin(), unB.end(), orderUnknown); + + ParameterList::iterator a = unA.begin(); + ParameterList::iterator b = unB.begin(); +#endif + + while(a != unA.end() && b != unB.end()) + { + if (orderUnknown(*a, *b)) + { + ++a; + } + else if (orderUnknown(*b, *a)) + { + ++b; + } + else + { + if (!isEqualNoCase(dynamic_cast<UnknownParameter*>(*a)->value(), + dynamic_cast<UnknownParameter*>(*b)->value())) + { + return false; + } + ++a; + ++b; + } + } + return true; +} + +bool +Uri::operator!=(const Uri& other) const +{ + return !(*this == other); +} + +bool +Uri::operator<(const Uri& other) const +{ + other.checkParsed(); + checkParsed(); + if (mUser < other.mUser) + { + return true; + } + + if (mUser > other.mUser) + { + return false; + } + + if (mUserParameters < other.mUserParameters) + { + return true; + } + + if (mUserParameters > other.mUserParameters) + { + return false; + } + + // !bwc! Canonicalize before we compare! Jeez... + if (!mHostCanonicalized) + { + if(DnsUtil::isIpV6Address(mHost)) + { + mHost = DnsUtil::canonicalizeIpV6Address(mHost); + } + else + { + mHost.lowercase(); + } + mHostCanonicalized=true; + } + + if (!other.mHostCanonicalized) + { + if(DnsUtil::isIpV6Address(other.mHost)) + { + other.mHost = DnsUtil::canonicalizeIpV6Address(other.mHost); + } + else + { + other.mHost.lowercase(); + } + other.mHostCanonicalized=true; + } + + if (mHost < other.mHost) + { + return true; + } + + if (mHost > other.mHost) + { + return false; + } + + return mPort < other.mPort; +} + +bool +Uri::aorEqual(const resip::Uri& rhs) const +{ + checkParsed(); + rhs.checkParsed(); + + if (!mHostCanonicalized) + { + if(DnsUtil::isIpV6Address(mHost)) + { + mHost = DnsUtil::canonicalizeIpV6Address(mHost); + } + else + { + mHost.lowercase(); + } + mHostCanonicalized=true; + } + + if (!rhs.mHostCanonicalized) + { + if(DnsUtil::isIpV6Address(rhs.mHost)) + { + rhs.mHost = DnsUtil::canonicalizeIpV6Address(rhs.mHost); + } + else + { + rhs.mHost.lowercase(); + } + rhs.mHostCanonicalized=true; + } + + return (mUser==rhs.mUser) && (mHost==rhs.mHost) && (mPort==rhs.mPort) && + (isEqualNoCase(mScheme,rhs.mScheme)); +} + +void +Uri::getAorInternal(bool dropScheme, bool addPort, Data& aor) const +{ + checkParsed(); + // canonicalize host + + addPort = addPort && mPort!=0; + + bool hostIsIpV6Address = false; + if(!mHostCanonicalized) + { + if (DnsUtil::isIpV6Address(mHost)) + { + mHost = DnsUtil::canonicalizeIpV6Address(mHost); + hostIsIpV6Address = true; + } + else + { + mHost.lowercase(); + } + } + + // !bwc! Maybe reintroduce caching of aor. (Would use a bool instead of the + // mOldX cruft) + // @:10000 + aor.clear(); + aor.reserve((dropScheme ? 0 : mScheme.size()+1) + + mUser.size() + mHost.size() + 7); + if(!dropScheme) + { + aor += mScheme; + aor += ':'; + } + + if (!mUser.empty()) + { +#ifdef HANDLE_CHARACTER_ESCAPING + { + oDataStream str(aor); + mUser.escapeToStream(str, getUserEncodingTable()); + } +#else + aor += mUser; +#endif + if(!mHost.empty()) + { + aor += Symbols::AT_SIGN; + } + } + + if(hostIsIpV6Address && addPort) + { + aor += Symbols::LS_BRACKET; + aor += mHost; + aor += Symbols::RS_BRACKET; + } + else + { + aor += mHost; + } + + if(addPort) + { + aor += Symbols::COLON; + aor += Data(mPort); + } +} + +Data +Uri::getAOR(bool addPort) const +{ + Data result; + getAorInternal(false, addPort, result); + return result; +} + +bool +Uri::userIsTelephoneSubscriber() const +{ + try + { + ParseBuffer pb(mUser); + pb.assertNotEof(); + const char* anchor=pb.position(); + bool local=false; + if(*pb.position()=='+') + { + // Might be a global phone number + pb.skipChar(); + pb.skipChars(getGlobalNumberTable()); + } + else + { + pb.skipChars(getLocalNumberTable()); + local=true; + } + + Data dialString(pb.data(anchor)); + if(dialString.empty()) + { + pb.fail(__FILE__, __LINE__, "Dial string is empty."); + } + + // ?bwc? More dial-string checking? For instance, +/ (or simply /) is not + // a valid dial-string according to the BNF; the string must contain at + // least one actual digit (or in the local number case, one hex digit or + // '*' or '#'. Interestingly, this means that stuff like ///*/// is + // valid) + + // Dial string looks ok so far; now look for params (there must be a + // phone-context param if this is a local number, otherwise there might + // or might not be one) + if(local || !pb.eof()) + { + // The only thing that can be here is a ';'. If it does, we're going + // to say it is good enough for us. If something in the parameter + // string is malformed, it'll get caught when/if + // getUserAsTelephoneSubscriber() is called. + pb.skipChar(';'); + } + + return true; + } + catch(ParseException& /*e*/) + { + return false; + } +} + +Token +Uri::getUserAsTelephoneSubscriber() const +{ + // !bwc! Ugly. Someday, refactor all this lazy-parser stuff and make it + // possible to control ownership explicitly. + // Set this up as lazy-parsed, to prevent exceptions from being thrown. + HeaderFieldValue temp(mUser.data(), mUser.size()); + Token tempToken(temp, Headers::NONE); + // tempToken does not own the HeaderFieldValue temp, and temp does not own + // its buffer. + + // Here's the voodoo; invoking operator= makes a deep copy of the stuff in + // tempToken, with result owning the memory, and result is in the unparsed + // state. + Token result = tempToken; + return result; +} + +void +Uri::setUserAsTelephoneSubscriber(const Token& telephoneSubscriber) +{ + mUser.clear(); + oDataStream str(mUser); + str << telephoneSubscriber; +} + +Data +Uri::getAorNoPort() const +{ + Data result; + getAorInternal(true, false, result); + return result; +} + +Data +Uri::getAor() const +{ + Data result; + getAorInternal(true, true, result); + return result; +} + +Uri +Uri::getAorAsUri(TransportType transportTypeToRemoveDefaultPort) const +{ + //.dcm. -- tel conversion? + checkParsed(); + Uri ret; + ret.scheme() = mScheme; + ret.user() = mUser; + ret.host() = mHost; + + // Remove any default ports (if required) + if(transportTypeToRemoveDefaultPort == UDP || + transportTypeToRemoveDefaultPort == TCP) + { + if(mPort != Symbols::DefaultSipPort) + { + ret.port() = mPort; + } + } + else if (transportTypeToRemoveDefaultPort == TLS || + transportTypeToRemoveDefaultPort == DTLS) + { + if(mPort != Symbols::DefaultSipsPort) + { + ret.port() = mPort; + } + } + else + { + ret.port() = mPort; + } + + return ret; +} + +void +Uri::parse(ParseBuffer& pb) +{ + pb.skipWhitespace(); + const char* start = pb.position(); + pb.skipToOneOf(":@"); + + pb.assertNotEof(); + + pb.data(mScheme, start); + pb.skipChar(Symbols::COLON[0]); + mScheme.schemeLowercase(); + + if (mScheme==Symbols::Tel) + { + const char* anchor = pb.position(); + static std::bitset<256> delimiter=Data::toBitset("\r\n\t ;>"); + pb.skipToOneOf(delimiter); + pb.data(mUser, anchor); + if (!pb.eof() && *pb.position() == Symbols::SEMI_COLON[0]) + { + anchor = pb.skipChar(); + pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::RA_QUOTE); + pb.data(mUserParameters, anchor); + } + return; + } + + start = pb.position(); + static std::bitset<256> userPortOrPasswordDelim(Data::toBitset("@:\"")); + // stop at double-quote to prevent matching an '@' in a quoted string param. + pb.skipToOneOf(userPortOrPasswordDelim); + if (!pb.eof()) + { + const char* atSign=0; + if (*pb.position() == Symbols::COLON[0]) + { + // Either a password, or a port + const char* afterColon = pb.skipChar(); + pb.skipToOneOf("@\""); + if(!pb.eof() && *pb.position() == Symbols::AT_SIGN[0]) + { + atSign=pb.position(); + // password +#ifdef HANDLE_CHARACTER_ESCAPING + pb.dataUnescaped(mPassword, afterColon); +#else + pb.data(mPassword, afterColon); +#endif + pb.reset(afterColon-1); + } + else + { + // port. No user part. + pb.reset(start); + } + } + else if(*pb.position() == Symbols::AT_SIGN[0]) + { + atSign=pb.position(); + } + else + { + // Only a hostpart + pb.reset(start); + } + + if(atSign) + { +#ifdef HANDLE_CHARACTER_ESCAPING + pb.dataUnescaped(mUser, start); +#else + pb.data(mUser, start); +#endif + pb.reset(atSign); + start = pb.skipChar(); + } + } + else + { + pb.reset(start); + } + + mHostCanonicalized=false; + static std::bitset<256> hostDelimiter(Data::toBitset("\r\n\t :;?>")); + if (*start == '[') + { + start = pb.skipChar(); + pb.skipToChar(']'); + pb.data(mHost, start); + // .bwc. We do not save this canonicalization, since we weren't doing so + // before. This may change soon. + Data canonicalizedHost=DnsUtil::canonicalizeIpV6Address(mHost); + if(canonicalizedHost.empty()) + { + // .bwc. So the V6 addy is garbage. + throw ParseException("Unparsable V6 address (note, this might" + " be unparsable because IPV6 support is not" + " enabled)","Uri",__FILE__, + __LINE__); + } + pb.skipChar(); + pb.skipToOneOf(hostDelimiter); + } + else + { + pb.skipToOneOf(hostDelimiter); + pb.data(mHost, start); + } + + if (!pb.eof() && *pb.position() == ':') + { + start = pb.skipChar(); + mPort = pb.uInt32(); + } + else + { + mPort = 0; + } + + parseParameters(pb); + + if (!pb.eof() && *pb.position() == Symbols::QUESTION[0]) + { + const char* anchor = pb.position(); + pb.skipToOneOf(">;", ParseBuffer::Whitespace); + if(!mEmbeddedHeadersText.get()) mEmbeddedHeadersText.reset(new Data); + pb.data(*mEmbeddedHeadersText, anchor); + } +} + +ParserCategory* +Uri::clone() const +{ + return new Uri(*this); +} + +ParserCategory* +Uri::clone(void* location) const +{ + return new (location) Uri(*this); +} + +ParserCategory* +Uri::clone(PoolBase* pool) const +{ + return new (pool) Uri(*this); +} + +void Uri::setUriUserEncoding(unsigned char c, bool encode) +{ + getUserEncodingTable()[c] = encode; +} + +void Uri::setUriPasswordEncoding(unsigned char c, bool encode) +{ + getPasswordEncodingTable()[c] = encode; +} + +// should not encode user parameters unless its a tel? +EncodeStream& +Uri::encodeParsed(EncodeStream& str) const +{ + str << mScheme << Symbols::COLON; + if (!mUser.empty()) + { +#ifdef HANDLE_CHARACTER_ESCAPING + mUser.escapeToStream(str, getUserEncodingTable()); +#else + str << mUser; +#endif + if (!mUserParameters.empty()) + { + str << Symbols::SEMI_COLON[0] << mUserParameters; + } + if (!mPassword.empty()) + { + str << Symbols::COLON; +#ifdef HANDLE_CHARACTER_ESCAPING + mPassword.escapeToStream(str, getPasswordEncodingTable()); +#else + str << mPassword; +#endif + } + } + if (!mHost.empty()) + { + if (!mUser.empty()) + { + str << Symbols::AT_SIGN; + } + if (DnsUtil::isIpV6Address(mHost)) + { + str << '[' << mHost << ']'; + } + else + { + str << mHost; + } + } + if (mPort != 0) + { + str << Symbols::COLON << mPort; + } + encodeParameters(str); + encodeEmbeddedHeaders(str); + + return str; +} + +SipMessage& +Uri::embedded() +{ + checkParsed(); + if (mEmbeddedHeaders.get() == 0) + { + this->mEmbeddedHeaders.reset(new SipMessage()); + if (mEmbeddedHeadersText.get() && !mEmbeddedHeadersText->empty()) + { + ParseBuffer pb(mEmbeddedHeadersText->data(), mEmbeddedHeadersText->size()); + this->parseEmbeddedHeaders(pb); + } + } + + return *mEmbeddedHeaders; +} + +const SipMessage& +Uri::embedded() const +{ + Uri* ncthis = const_cast<Uri*>(this); + return ncthis->embedded(); +} + +static const Data bodyData("Body"); +void +Uri::parseEmbeddedHeaders(ParseBuffer& pb) +{ + DebugLog(<< "Uri::parseEmbeddedHeaders"); + if (!pb.eof() && *pb.position() == Symbols::QUESTION[0]) + { + pb.skipChar(); + } + + const char* anchor; + Data headerName; + Data headerContents; + + bool first = true; + while (!pb.eof()) + { + if (first) + { + first = false; + } + else + { + pb.skipChar(Symbols::AMPERSAND[0]); + } + + anchor = pb.position(); + pb.skipToChar(Symbols::EQUALS[0]); + pb.data(headerName, anchor); + // .dlb. in theory, need to decode header name + + anchor = pb.skipChar(Symbols::EQUALS[0]); + pb.skipToChar(Symbols::AMPERSAND[0]); + pb.data(headerContents, anchor); + + unsigned int len; + char* decodedContents = Embedded::decode(headerContents, len); + mEmbeddedHeaders->addBuffer(decodedContents); + + if (isEqualNoCase(bodyData, headerName)) + { + mEmbeddedHeaders->setBody(decodedContents, len); + } + else + { + DebugLog(<< "Uri::parseEmbeddedHeaders(" << headerName << ", " << Data(decodedContents, len) << ")"); + mEmbeddedHeaders->addHeader(Headers::getType(headerName.data(), (int)headerName.size()), + headerName.data(), (int)headerName.size(), + decodedContents, len); + } + } +} + +EncodeStream& +Uri::encodeEmbeddedHeaders(EncodeStream& str) const +{ + if (mEmbeddedHeaders.get()) + { + mEmbeddedHeaders->encodeEmbedded(str); + } + else if(mEmbeddedHeadersText.get()) + { + // never decoded + str << *mEmbeddedHeadersText; + } + return str; +} + +Data +Uri::toString() const +{ + Data out; + { + oDataStream dataStream(out); + this->encodeParsed(dataStream); + } + return out; +} + +ParameterTypes::Factory Uri::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; + +Parameter* +Uri::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) +{ + if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) + { + return ParameterFactories[type](type, pb, terminators, pool); + } + return 0; +} + +bool +Uri::exists(const Param<Uri>& paramType) const +{ + checkParsed(); + bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; + return ret; +} + +void +Uri::remove(const Param<Uri>& paramType) +{ + checkParsed(); + removeParameterByEnum(paramType.getTypeNum()); +} + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ +_enum##_Param::DType& \ +Uri::param(const _enum##_Param& paramType) \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + p = new _enum##_Param::Type(paramType.getTypeNum()); \ + mParameters.push_back(p); \ + } \ + return p->value(); \ +} \ + \ +const _enum##_Param::DType& \ +Uri::param(const _enum##_Param& paramType) const \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ + DebugLog(<< *this); \ + throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ + } \ + return p->value(); \ +} + +defineParam(ob,"ob",ExistsParameter,"RFC 5626"); +defineParam(gr, "gr", ExistsOrDataParameter, "RFC 5627"); +defineParam(comp, "comp", DataParameter, "RFC 3486"); +defineParam(duration, "duration", UInt32Parameter, "RFC 4240"); +defineParam(lr, "lr", ExistsParameter, "RFC 3261"); +defineParam(maddr, "maddr", DataParameter, "RFC 3261"); +defineParam(method, "method", DataParameter, "RFC 3261"); +defineParam(transport, "transport", DataParameter, "RFC 3261"); +defineParam(ttl, "ttl", UInt32Parameter, "RFC 3261"); +defineParam(user, "user", DataParameter, "RFC 3261, 4967"); +defineParam(extension, "ext", DataParameter, "RFC 3966"); // Token is used when ext is a user-parameter +defineParam(sigcompId, "sigcomp-id", QuotedDataParameter, "RFC 5049"); +defineParam(rinstance, "rinstance", DataParameter, "proprietary (resip)"); +defineParam(addTransport, "addTransport", ExistsParameter, "RESIP INTERNAL"); + +#undef defineParam + +HashValueImp(resip::Uri, resip::Data::from(data).hash()); + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Uri.hxx b/src/libs/resiprocate/resip/stack/Uri.hxx new file mode 100644 index 00000000..cdcb5fc4 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Uri.hxx @@ -0,0 +1,342 @@ +#if !defined(RESIP_URI_HXX) +#define RESIP_URI_HXX + +#include <bitset> +#include <cassert> + +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/Token.hxx" +#include "rutil/TransportType.hxx" +#include "rutil/HeapInstanceCounter.hxx" + +namespace resip +{ +class SipMessage; + +/** + @ingroup sip_grammar + @brief Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 + grammar. Also can be made to represent other URI types (like tel URIs) +*/ +class Uri : public ParserCategory +{ + public: + RESIP_HeapCount(Uri); + + static const size_t uriEncodingTableSize = 256; + + Uri(PoolBase* pool=0); + Uri(const HeaderFieldValue& hfv, Headers::Type type, PoolBase* pool=0); + Uri(const Uri& orig, + PoolBase* pool=0); + explicit Uri(const Data& data); + + ~Uri(); + + // convert from a tel scheme to sip scheme, adds user=phone param + //static Uri fromTel(const Uri&, const Data& host); // deprecate... + static Uri fromTel(const Uri&, const Uri& hostUri); + + Data& host() {checkParsed(); mHostCanonicalized=false; return mHost;} + const Data& host() const {checkParsed(); return mHost;} + Data& user() {checkParsed(); return mUser;} + const Data& user() const {checkParsed(); return mUser;} + Data& userParameters() {checkParsed(); return mUserParameters;} + const Data& userParameters() const {checkParsed(); return mUserParameters;} + Data& opaque() {checkParsed(); return mHost;} + const Data& opaque() const {checkParsed(); return mHost;} + + // Returns user@host[:port] (no scheme) + Data getAor() const; + // Returns user@host (no scheme or port) + Data getAorNoPort() const; + + // Actually returns the AOR; <scheme>:<user>@<host> + Data getAorNoReally() const + { + return getAOR(false); + } + + // Returns the AOR, optionally adding the port + Data getAOR(bool addPort) const; + + //strips all paramters - if transport type is specified (ie. not UNKNOWN_TRANSPORT), + //and the default port for the transport is on the Aor, then it is removed + Uri getAorAsUri(TransportType transportTypeToRemoveDefaultPort = UNKNOWN_TRANSPORT) const; + + + /** + Returns true if the user appears to fit the BNF for the + 'telephone-subscriber' element in the RFC 3261 (and by extension, RFC + 3966) grammar. This is important because 'telephone-subscriber' can + have parameters, which you could then access easily through the + getUserAsTelephoneSubscriber() and setUserAsTelephoneSubscriber() + calls. + */ + bool userIsTelephoneSubscriber() const; + + /** + Returns the user-part as a 'telephone-subscriber' grammar element (in + other words, this parses the user-part into a dial string and + parameters, with the dial-string accessible with Token::value(), and + the parameters accessible with the various Token::param() and + Token::exists() interfaces). + + For example, suppose the following is in the Request-URI: + + sip:5555551234;phone-context=+86\@example.com;user=dialstring + + The user-part of this SIP URI is "5555551234;phone-context=+86", and it + fits the BNF for the 'telephone-subscriber' grammar element. To access + the 'phone-context' parameter, do something like the following: + + @code + Uri& reqUri(sip.header(h_RequestLine).uri()); + + // !bwc! May add native support for this param later + static ExtensionParameter p_phoneContext("phone-context"); + Data phoneContextValue; + + if(reqUri.isWellFormed()) + { + if(reqUri.exists(p_phoneContext)) + { + // Phone context as URI param + phoneContextValue=reqUri.param(p_phoneContext); + } + else if(reqUri.scheme()=="sip" || reqUri.scheme()=="sips") + { + // Might have phone-context as a user param (only happens + // in a sip or sips URI) + // Technically, this userIsTelephoneSubscriber() check is + // required: + // sip:bob;phone-context=+86@example.com doesn't have a + // phone-context param according to the BNF in 3261. But, + // interop may require you to parse this as if it did have + // such a param. + if(reqUri.userIsTelephoneSubscriber()) + { + Token telSub(reqUri.getUserAsTelephoneSubscriber()); + if(telSub.isWellFormed() && telSub.exists(p_phoneContext)) + { + // Phone context as user param + phoneContextValue=telSub.param(p_phoneContext); + } + } + } + } + @endcode + */ + Token getUserAsTelephoneSubscriber() const; + + /** + Sets the user-part of this URI using the dial-string and parameters + stored in telephoneSubscriber. + @param telephoneSubscriber The user-part, as a 'telephone-subscriber' + grammar element. + */ + void setUserAsTelephoneSubscriber(const Token& telephoneSubscriber); + + + Data& scheme() {checkParsed(); return mScheme;} + const Data& scheme() const {checkParsed(); return mScheme;} + int& port() {checkParsed(); return mPort;} + int port() const {checkParsed(); return mPort;} + Data& password() {checkParsed(); return mPassword;} + const Data& password() const {checkParsed(); return mPassword;} + + Data toString() const; + + /** Returns true if the uri can be converted into a string that can be + used as an enum lookup */ + bool isEnumSearchable() const; + + /** Return a vector of domains to do a NAPTR lookup for enum */ + std::vector<Data> getEnumLookups(const std::vector<Data>& suffixes) const; + + /** Modifies the default URI encoding character sets */ + static void setUriUserEncoding(unsigned char c, bool encode); + static void setUriPasswordEncoding(unsigned char c, bool encode); + + bool hasEmbedded() const; + SipMessage& embedded(); + const SipMessage& embedded() const; + + void removeEmbedded(); + + virtual void parse(ParseBuffer& pb); + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + + // parse the headers into this as SipMessage + void parseEmbeddedHeaders(ParseBuffer& pb); + EncodeStream& encodeEmbeddedHeaders(EncodeStream& str) const; + + Uri& operator=(const Uri& rhs); + bool operator==(const Uri& other) const; + bool operator!=(const Uri& other) const; + bool operator<(const Uri& other) const; + + bool aorEqual(const Uri& rhs) const; + + typedef std::bitset<Uri::uriEncodingTableSize> EncodingTable; + + static EncodingTable& getUserEncodingTable() + { + static EncodingTable userEncodingTable( + Data::toBitset("abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "-_.!~*\\()&=+$,;?/").flip()); + return userEncodingTable; + } + + static EncodingTable& getPasswordEncodingTable() + { + static EncodingTable passwordEncodingTable( + Data::toBitset("abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "-_.!~*\\()&=+$").flip()); + return passwordEncodingTable; + } + + static EncodingTable& getLocalNumberTable() + { + // ?bwc? 'p' and 'w' are allowed in 2806, but have been removed in + // 3966. Should we support these or not? + static EncodingTable localNumberTable( + Data::toBitset("*#-.()0123456789ABCDEFpw")); + return localNumberTable; + } + + static EncodingTable& getGlobalNumberTable() + { + static EncodingTable globalNumberTable( + Data::toBitset("-.()0123456789")); + return globalNumberTable; + } + + // Inform the compiler that overloads of these may be found in + // ParserCategory, too. + using ParserCategory::exists; + using ParserCategory::remove; + using ParserCategory::param; + + virtual Parameter* createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool); + bool exists(const Param<Uri>& paramType) const; + void remove(const Param<Uri>& paramType); + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ + const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \ + _enum##_Param::DType& param(const _enum##_Param& paramType); \ + friend class _enum##_Param + + defineParam(ob,"ob",ExistsParameter,"RFC 5626"); + defineParam(gr, "gr", ExistsOrDataParameter, "RFC 5627"); + defineParam(comp, "comp", DataParameter, "RFC 3486"); + defineParam(duration, "duration", UInt32Parameter, "RFC 4240"); + defineParam(lr, "lr", ExistsParameter, "RFC 3261"); + defineParam(maddr, "maddr", DataParameter, "RFC 3261"); + defineParam(method, "method", DataParameter, "RFC 3261"); + defineParam(transport, "transport", DataParameter, "RFC 3261"); + defineParam(ttl, "ttl", UInt32Parameter, "RFC 3261"); + defineParam(user, "user", DataParameter, "RFC 3261, 4967"); + defineParam(extension, "ext", DataParameter, "RFC 3966"); // Token is used when ext is a user-parameter + defineParam(sigcompId, "sigcomp-id", QuotedDataParameter, "RFC 5049"); + defineParam(rinstance, "rinstance", DataParameter, "proprietary (resip)"); + defineParam(addTransport, "addTransport", ExistsParameter, "RESIP INTERNAL"); + +#undef defineParam + + protected: + Data mScheme; + // .bwc. I don't like this. + mutable Data mHost; + Data mUser; + Data mUserParameters; + int mPort; + Data mPassword; + + void getAorInternal(bool dropScheme, bool addPort, Data& aor) const; + mutable bool mHostCanonicalized; + + private: + std::auto_ptr<Data> mEmbeddedHeadersText; + std::auto_ptr<SipMessage> mEmbeddedHeaders; + + static ParameterTypes::Factory ParameterFactories[ParameterTypes::MAX_PARAMETER]; + + /** + Dummy static initialization variable, for ensuring that the encoding + tables are initialized sometime during static initialization, + preventing the scenario where multiple threads try to runtime init the + same table at the same time. + @note Prior to static initialization of this bool, it could be either + true or false; you should not be using this variable to check + whether the tables are initialized. Just call the getXTable() + accessor function; it will init the table if it is not already. + */ + static const bool tablesMightBeInitialized; + +}; + +} + +#include "rutil/HashMap.hxx" + +HashValue(resip::Uri); + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ValueFifo.hxx b/src/libs/resiprocate/resip/stack/ValueFifo.hxx new file mode 100644 index 00000000..1897ccd4 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ValueFifo.hxx @@ -0,0 +1,236 @@ +#ifndef ValueFifo_hxx +#define ValueFifo_hxx + +#include <cerrno> +#include <iosfwd> +#include <deque> + +#include "rutil/Condition.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/Lock.hxx" +#include "rutil/AbstractFifo.hxx" +#include "resip/stack/CancelableTimerQueue.hxx" + +namespace resip +{ + +/** + @internal + + Distinct from resip::Fifo; by value and has cancellable timers. +*/ +template <class T> +class ValueFifo : public resip::FifoStatsInterface +{ + public: + typedef typename CancelableTimerQueue<T>::Id TimerId; + + ValueFifo(const Data& name) : + myFifoSize(0), + myTimerSize(0) + { + } + + ~ValueFifo() + { + } + + void add(const T& t) + { + resip::Lock lock(myMutex); + myList.push_back(t); + myFifoSize++; + wakeup(); + } + + TimerId addDelayMs(const T& t, int offsetInMs) + { + resip::Lock lock(myMutex); + if (offsetInMs < 0) + { + offsetInMs = 0; + } + + bool doWakeup = false; + if (myTimerQueue.empty() || + offsetInMs < myTimerQueue.getTimeout()) + { + doWakeup = true; + } + + TimerId id = myTimerQueue.addRelative(t, offsetInMs); + myTimerSize++; + + //wakeup if new timer is sooner than next timer that would have + //fired, or no timer set + if (doWakeup) + { + + wakeup(); + } + return id; + } + + bool cancel(TimerId id) + { + resip::Lock lock(myMutex); + if (myTimerQueue.cancel(id)) + { + myTimerSize--; + return true; + } + return false; + } + + T getNext() + { + resip::Lock lock(myMutex); + + while (!messageAvailableNoLock()) + { + if (myTimerQueue.empty()) + { + myCondition.wait(&myMutex); + } + else + { + myCondition.wait(&myMutex, myTimerQueue.getTimeout()); + } + } + + while (myTimerQueue.available()) + { + myList.push_back(myTimerQueue.getNext()); + myFifoSize++; + myTimerSize--; + } + + assert (myFifoSize > 0); + assert (!myList.empty()); + + T firstMessage = myList.front(); + + myList.pop_front(); //dcm -- should do this with a guard to avoid extra copy + myFifoSize--; + return firstMessage; + } + + void clear() + { + resip::Lock lock(myMutex); + myFifoSize = 0; + myTimerSize = 0; + myTimerQueue.clear(); + myList.clear(); + } + + //size includes timer events + unsigned int size() const + { + resip::Lock lock(myMutex); + return myFifoSize + myTimerSize; + } + + bool empty() const + { + return myFifoSize + myTimerSize == 0; + } + + bool messageAvailable() + { + resip::Lock lock(myMutex); + return messageAvailableNoLock(); + } + + virtual size_t getCountDepth() const + { + return size(); + } + + virtual time_t getTimeDepth() const + { + return 0; + } + + virtual time_t expectedWaitTimeMilliSec() const + { + return 0; + } + + virtual time_t averageServiceTimeMicroSec() const + { + return 1; + } + + private: + bool messageAvailableNoLock() + { + return myFifoSize > 0 || myTimerQueue.available(); + } + + void wakeup() + { + myCondition.signal(); + } + + std::deque<T> myList; + + CancelableTimerQueue<T> myTimerQueue; + + unsigned long myFifoSize; + unsigned long myTimerSize; + + mutable resip::Mutex myMutex; + resip::Condition myCondition; + + // no value semantics + ValueFifo(const ValueFifo&); + ValueFifo& operator=(const ValueFifo&); +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 PurpleComm, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + */ + diff --git a/src/libs/resiprocate/resip/stack/Via.cxx b/src/libs/resiprocate/resip/stack/Via.cxx new file mode 100644 index 00000000..00c09fbd --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Via.cxx @@ -0,0 +1,364 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Via.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + + +//==================== +// Via: +//==================== +Via::Via() + : ParserCategory(), + mProtocolName(Data::Share,Symbols::ProtocolName), + mProtocolVersion(Data::Share,Symbols::ProtocolVersion), + mTransport(), + mSentHost(), + mSentPort(0) +{ + // insert a branch in all Vias (default constructor) + this->param(p_branch); + this->param(p_rport); // add the rport parameter by default as per rfc 3581 +} + +Via::Via(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), + mProtocolName(Data::Share,Symbols::ProtocolName), + mProtocolVersion(Data::Share,Symbols::ProtocolVersion), + mTransport(Data::Share,Symbols::UDP), // !jf! + mSentHost(), + mSentPort(-1) +{} + +Via::Via(const Via& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mProtocolName(rhs.mProtocolName), + mProtocolVersion(rhs.mProtocolVersion), + mTransport(rhs.mTransport), + mSentHost(rhs.mSentHost), + mSentPort(rhs.mSentPort) +{ +} + +Via& +Via::operator=(const Via& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mProtocolName = rhs.mProtocolName; + mProtocolVersion = rhs.mProtocolVersion; + mTransport = rhs.mTransport; + mSentHost = rhs.mSentHost; + mSentPort = rhs.mSentPort; + } + return *this; +} + +ParserCategory * +Via::clone() const +{ + return new Via(*this); +} + +ParserCategory * +Via::clone(void* location) const +{ + return new (location) Via(*this); +} + +ParserCategory* +Via::clone(PoolBase* pool) const +{ + return new (pool) Via(*this, pool); +} + +Data& +Via::protocolName() +{ + checkParsed(); + return mProtocolName; +} + +const Data& +Via::protocolName() const +{ + checkParsed(); + return mProtocolName; +} + +Data& +Via::protocolVersion() +{ + checkParsed(); + return mProtocolVersion; +} + +const Data& +Via::protocolVersion() const +{ + checkParsed(); + return mProtocolVersion; +} + +Data& Via:: +transport() +{ + checkParsed(); + return mTransport; +} + +const Data& Via:: +transport() const +{ + checkParsed(); + return mTransport; +} + +Data& +Via::sentHost() +{ + checkParsed(); + return mSentHost; +} + +const Data& + Via::sentHost() const +{ + checkParsed(); + return mSentHost; +} + +int& +Via::sentPort() +{ + checkParsed(); + return mSentPort; +} + +int +Via::sentPort() const +{ + checkParsed(); + return mSentPort; +} + +void +Via::parse(ParseBuffer& pb) +{ + const char* startMark; + startMark = pb.skipWhitespace(); + static std::bitset<256> wos=Data::toBitset("\r\n\t /"); + pb.skipToOneOf(wos); + pb.data(mProtocolName, startMark); + pb.skipToChar('/'); + pb.skipChar(); + startMark = pb.skipWhitespace(); + pb.skipToOneOf(wos); + pb.data(mProtocolVersion, startMark); + + pb.skipToChar('/'); + pb.skipChar(); + startMark = pb.skipWhitespace(); + + // !jf! this should really be skipTokenChar() since for instance, if the + // protocol token is missing it will read the rest of the Via into this field + pb.skipNonWhitespace(); + pb.data(mTransport, startMark); + + startMark = pb.skipWhitespace(); + pb.assertNotEof(); + if (*startMark == '[') + { + startMark = pb.skipChar(); + pb.skipToChar(']'); + pb.data(mSentHost, startMark); + // .bwc. We do not save this canonicalization, since we weren't doing so + // before. This may change soon. + Data canonicalizedHost=DnsUtil::canonicalizeIpV6Address(mSentHost); + if(canonicalizedHost.empty()) + { + // .bwc. So the V6 addy is garbage. + throw ParseException("Unparsable V6 address (note, this might" + " be unparsable because IPV6 support is not" + " enabled)", "Via", + __FILE__, + __LINE__); + } + pb.skipChar(); + } + else + { + // .bwc. If we hit whitespace, we have the host. + static std::bitset<256> delimiter=Data::toBitset(";: \t\r\n"); + pb.skipToOneOf(delimiter); + pb.data(mSentHost, startMark); + } + + pb.skipToOneOf(";:"); + + if (!pb.eof() && *pb.position() == ':') + { + startMark = pb.skipChar(':'); + mSentPort = pb.integer(); + static std::bitset<256> delimiter=Data::toBitset("; \t\r\n"); + pb.skipToOneOf(delimiter); + } + else + { + mSentPort = 0; + } + parseParameters(pb); +} + +EncodeStream& +Via::encodeParsed(EncodeStream& str) const +{ + str << mProtocolName << Symbols::SLASH << mProtocolVersion << Symbols::SLASH << mTransport + << Symbols::SPACE; + + if (DnsUtil::isIpV6Address(mSentHost)) + { + str << '[' << mSentHost << ']'; + } + else + { + str << mSentHost; + } + + if (mSentPort != 0) + { + str << Symbols::COLON << mSentPort; + } + encodeParameters(str); + return str; +} + +ParameterTypes::Factory Via::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; + +Parameter* +Via::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) +{ + if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) + { + return ParameterFactories[type](type, pb, terminators, pool); + } + return 0; +} + +bool +Via::exists(const Param<Via>& paramType) const +{ + checkParsed(); + bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; + return ret; +} + +void +Via::remove(const Param<Via>& paramType) +{ + checkParsed(); + removeParameterByEnum(paramType.getTypeNum()); +} + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ +_enum##_Param::DType& \ +Via::param(const _enum##_Param& paramType) \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + p = new _enum##_Param::Type(paramType.getTypeNum()); \ + mParameters.push_back(p); \ + } \ + return p->value(); \ +} \ + \ +const _enum##_Param::DType& \ +Via::param(const _enum##_Param& paramType) const \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ + DebugLog(<< *this); \ + throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ + } \ + return p->value(); \ +} + +defineParam(branch, "branch", BranchParameter, "RFC 3261"); +defineParam(comp, "comp", DataParameter, "RFC 3486"); +defineParam(received, "received", DataParameter, "RFC 3261"); +defineParam(rport, "rport", RportParameter, "RFC 3581"); +defineParam(ttl, "ttl", UInt32Parameter, "RFC 3261"); +defineParam(sigcompId, "sigcomp-id", QuotedDataParameter, "RFC 5049"); +defineParam(maddr, "maddr", DataParameter, "RFC 3261"); + +#undef defineParam + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/Via.hxx b/src/libs/resiprocate/resip/stack/Via.hxx new file mode 100644 index 00000000..37a3e821 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Via.hxx @@ -0,0 +1,137 @@ +#if !defined(RESIP_VIA_HXX) +#define RESIP_VIA_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/ParserContainer.hxx" + +namespace resip +{ +class PoolBase; + +/** + @ingroup sip_grammar + @brief Represents the "via-parm" element in the RFC 3261 grammar. +*/ +class Via : public ParserCategory +{ + public: + enum {commaHandling = CommasAllowedOutputMulti}; + + Via(); + Via(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + Via(const Via& orig, + PoolBase* pool=0); + Via& operator=(const Via&); + + Data& protocolName(); + const Data& protocolName() const; + Data& protocolVersion(); + const Data& protocolVersion() const; + Data& transport(); + const Data& transport() const; + Data& sentHost(); + const Data& sentHost() const; + int& sentPort(); + int sentPort() const; + + virtual void parse(ParseBuffer& pb); + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + + // Inform the compiler that overloads of these may be found in + // ParserCategory, too. + using ParserCategory::exists; + using ParserCategory::remove; + using ParserCategory::param; + + virtual Parameter* createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool); + bool exists(const Param<Via>& paramType) const; + void remove(const Param<Via>& paramType); + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ + const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \ + _enum##_Param::DType& param(const _enum##_Param& paramType); \ + friend class _enum##_Param + +defineParam(branch, "branch", BranchParameter, "RFC 3261"); +defineParam(comp, "comp", DataParameter, "RFC 3486"); +defineParam(received, "received", DataParameter, "RFC 3261"); +defineParam(rport, "rport", RportParameter, "RFC 3581"); +defineParam(ttl, "ttl", UInt32Parameter, "RFC 3261"); +defineParam(sigcompId, "sigcomp-id", QuotedDataParameter, "RFC 5049"); +defineParam(maddr, "maddr", DataParameter, "RFC 3261"); + +#undef defineParam + + private: + Data mProtocolName; + Data mProtocolVersion; + Data mTransport; + Data mSentHost; + int mSentPort; + + static ParameterTypes::Factory ParameterFactories[ParameterTypes::MAX_PARAMETER]; +}; +typedef ParserContainer<Via> Vias; + + +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/WarningCategory.cxx b/src/libs/resiprocate/resip/stack/WarningCategory.cxx new file mode 100644 index 00000000..b06415e8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WarningCategory.cxx @@ -0,0 +1,191 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/WarningCategory.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//==================== +// WarningCategory +//==================== +WarningCategory::WarningCategory() + : ParserCategory() +{} + +WarningCategory::WarningCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool) +{} + +WarningCategory::WarningCategory(const WarningCategory& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mCode(rhs.mCode), + mHostname(rhs.mHostname), + mText(rhs.mText) +{} + +WarningCategory& +WarningCategory::operator=(const WarningCategory& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mCode = rhs.mCode; + mHostname = rhs.mHostname; + mText = rhs.mText; + } + return *this; +} +void +WarningCategory::parse(ParseBuffer& pb) +{ + pb.skipWhitespace(); + mCode = pb.uInt32(); + + if(mCode >= 1000 || mCode < 100) + { + pb.fail(__FILE__,__LINE__,"Warning code does not have exactly three digits."); + } + + const char* anchor = pb.skipWhitespace(); + pb.skipNonWhitespace(); + pb.data(mHostname, anchor); + + pb.skipWhitespace(); + anchor = pb.skipChar(Symbols::DOUBLE_QUOTE[0]); + pb.skipToEndQuote(Symbols::DOUBLE_QUOTE[0]); + pb.data(mText, anchor); + anchor = pb.skipChar(Symbols::DOUBLE_QUOTE[0]); + pb.skipWhitespace(); + pb.assertEof(); +} + +ParserCategory* +WarningCategory::clone() const +{ + return new WarningCategory(*this); +} + +ParserCategory* +WarningCategory::clone(void* location) const +{ + return new (location) WarningCategory(*this); +} + +ParserCategory* +WarningCategory::clone(PoolBase* pool) const +{ + return new (pool) WarningCategory(*this, pool); +} + +int& +WarningCategory::code() +{ + checkParsed(); + return mCode; +} + +int +WarningCategory::code() const +{ + checkParsed(); + return mCode; +} + +Data& +WarningCategory::hostname() +{ + checkParsed(); + return mHostname; +} + +const Data& +WarningCategory::hostname() const +{ + checkParsed(); + return mHostname; +} + +Data& +WarningCategory::text() +{ + checkParsed(); + return mText; +} + +const Data& +WarningCategory::text() const +{ + checkParsed(); + return mText; +} + +EncodeStream& +WarningCategory::encodeParsed(EncodeStream& str) const +{ + str << mCode << Symbols::SPACE[0]; + str << mHostname << Symbols::SPACE[0]; + str << Symbols::DOUBLE_QUOTE[0] << mText << Symbols::DOUBLE_QUOTE[0]; + + return str; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/WarningCategory.hxx b/src/libs/resiprocate/resip/stack/WarningCategory.hxx new file mode 100644 index 00000000..5a92c13a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WarningCategory.hxx @@ -0,0 +1,102 @@ +#if !defined(RESIP_WARNING_HXX) +#define RESIP_WARNING_HXX + +#include <iosfwd> +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/ParserContainer.hxx" + +namespace resip +{ + + +/** + @ingroup sip_grammar + @brief Represents the "warning-value" element in the RFC 3261 grammar. +*/ +class WarningCategory : public ParserCategory +{ + public: + enum {commaHandling = CommasAllowedOutputCommas}; + + WarningCategory(); + WarningCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool=0); + WarningCategory(const WarningCategory& orig, + PoolBase* pool=0); + WarningCategory& operator=(const WarningCategory&); + + virtual void parse(ParseBuffer& pb); + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + + int& code(); + int code() const; + Data& hostname(); + const Data& hostname() const; + Data& text(); + const Data& text() const; + + private: + int mCode; + Data mHostname; + Data mText; +}; +typedef ParserContainer<WarningCategory> WarningCategories; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/X509Contents.cxx b/src/libs/resiprocate/resip/stack/X509Contents.cxx new file mode 100644 index 00000000..3f3790e5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/X509Contents.cxx @@ -0,0 +1,151 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/X509Contents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +const X509Contents X509Contents::Empty; + +static bool invokeX509ContentsInit = X509Contents::init(); + +bool +X509Contents::init() +{ + static ContentsFactory<X509Contents> factory; + (void)factory; + return true; +} + +X509Contents::X509Contents() + : Contents(getStaticType()), + mText() +{ +} + +X509Contents::X509Contents(const Data& txt) + : Contents(getStaticType()), + mText(txt) +{ +} + +X509Contents::X509Contents(const Data& txt, const Mime& contentsType) + : Contents(contentsType), + mText(txt) +{ +} + +X509Contents::X509Contents(const HeaderFieldValue& hfv, const Mime& contentsType) + : Contents(hfv, contentsType), + mText() +{ +} + +X509Contents::X509Contents(const X509Contents& rhs) + : Contents(rhs), + mText(rhs.mText) +{ +} + +X509Contents::~X509Contents() +{ +} + +X509Contents& +X509Contents::operator=(const X509Contents& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + mText = rhs.mText; + } + return *this; +} + +Contents* +X509Contents::clone() const +{ + return new X509Contents(*this); +} + +const Mime& +X509Contents::getStaticType() +{ + static Mime type("application", "pkix-cert"); + return type; +} + +EncodeStream& +X509Contents::encodeParsed(EncodeStream& str) const +{ + //DebugLog(<< "X509Contents::encodeParsed " << mText); + str << mText; + return str; +} + + +void +X509Contents::parse(ParseBuffer& pb) +{ + const char* anchor = pb.position(); + pb.skipToEnd(); + pb.data(mText, anchor); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/X509Contents.hxx b/src/libs/resiprocate/resip/stack/X509Contents.hxx new file mode 100644 index 00000000..e251c1a1 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/X509Contents.hxx @@ -0,0 +1,99 @@ +#ifndef RESIP_X509Contents_hxx +#define RESIP_X509Contents_hxx + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +/** + @ingroup sip_payload + @brief SIP body type for holding X509 contents (MIME content-type application/pkix-cert). +*/ +class X509Contents : public Contents +{ + public: + static const X509Contents Empty; + + X509Contents(); + X509Contents(const Data& text); + X509Contents(const HeaderFieldValue& hfv, const Mime& contentType); + X509Contents(const Data& data, const Mime& contentType); + X509Contents(const X509Contents& rhs); + virtual ~X509Contents(); + X509Contents& operator=(const X509Contents& rhs); + + /** @brief duplicate an X509Contents object + @return pointer to a new X509Contents object + **/ + virtual Contents* clone() const; + + static const Mime& getStaticType() ; + + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + Data& text() {checkParsed(); return mText;} + + static bool init(); + + private: + Data mText; +}; + +static bool invokeX509ContentsInit = X509Contents::init(); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/XMLCursor.cxx b/src/libs/resiprocate/resip/stack/XMLCursor.cxx new file mode 100644 index 00000000..ba9850b1 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/XMLCursor.cxx @@ -0,0 +1,680 @@ +#if defined(HAVE_CONFIG_H) +#include "resip/stack/config.hxx" +#endif + +#include "resip/stack/XMLCursor.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::CONTENTS + +/** +Whitespace handling: +Are the following XML fragments equivalent? + +Strictly interpreted, the root of the first XML document has one +child while the root of the second XML doucment has three children. +The line breaks and spaces after the <root> and before </root> are +tagless children. + +---> + <root><child>child content</child></root> +<-- + vs. +---> + <root> + <child>child content</child> + </root> +<-- + +Treating whitespace as children is consistent with the spec but not usually +convenient. <!ATTLIST poem xml:space (default|preserve) 'preserve'> is used to +control whitespace handling. Supporting this switch is painful. For now, treat +whitespace as non-significant. +*/ + +static char BANG[] = "!"; +static char HYPHEN[] = "-"; +//http://www.w3.org/TR/1998/REC-xml-19980210 +static const Data COMMENT_START("<!--"); +static const Data COMMENT_END("-->"); + +// An alternative to stripping comments out in preparse +// is to deal with them in the parse; ignore when after non-leaf element +// put a leaf after a comment after a leaf in the first leaf's children +// getValue() needs to copy first leaf and all 'child' leaves to mValue +// +// has the advantage of allowing +// 1. lazier parsing +// 2. embedded wierdnesses like <! > and <? > +XMLCursor::XMLCursor(const ParseBuffer& pb) + : mRoot(0), + mCursor(0), + mAttributesSet(false) +{ + ParseBuffer lPb(pb); + + skipProlog(lPb); + const char* start = lPb.position(); + + lPb.skipToChars(COMMENT_START); + if (!lPb.eof()) + { + StackLog(<< "removing comments"); + lPb.reset(start); + mData.reserve(lPb.end() - lPb.start()); + + const char* anchor = start; + { + DataStream str(mData); + Data temp; + while (true) + { + lPb.skipToChars(COMMENT_START); + if (!lPb.eof()) + { + lPb.data(temp, anchor); + str << temp; + anchor = Node::skipComments(lPb); + } + else + { + lPb.data(temp, anchor); + str << temp; + break; + } + } + } + mRoot = new Node(ParseBuffer(mData.data(), mData.size())); + } + else + { + mRoot = new Node(ParseBuffer(start, pb.end() - start)); + } + mCursor = mRoot; + + if (mRoot->extractTag()) + { + InfoLog(<< "XML: empty element no a legal root"); + mRoot->mPb.fail(__FILE__, __LINE__); + } + + mTag = mRoot->mTag; + decodeName(mRoot->mTag); + + // check for # & and note -- make decode, decodeName do stuff if set + + //<top></top> // no children + ParseBuffer pbtemp(mRoot->mPb); + pbtemp.skipToChar(Symbols::RA_QUOTE[0]); + pbtemp.skipChar(); + if (!WhitespaceSignificant) + { + pbtemp.skipWhitespace(); + } + if (*pbtemp.position() == Symbols::LA_QUOTE[0] && + *(pbtemp.position()+1) == Symbols::SLASH[0]) + { + pbtemp.skipChar(); + pbtemp.skipChar(); + if (strncmp(mRoot->mTag.data(), pbtemp.position(), mRoot->mTag.size()) == 0) + { + // no children ever + mRoot->mPb.reset(mRoot->mPb.end()); + return; + } + } +} + +XMLCursor::~XMLCursor() +{ + delete mRoot; +} + +static const Data QUESTION_RA_QUOTE("?>"); +void +XMLCursor::skipProlog(ParseBuffer& pb) +{ + //'<?xml' VersionInfo '<xml?' EncodingDecl '?>'? '<?xml' SDDecl '?>'? S? '?> + + // !dlb! much more complicated than this.. can contain comments + const char* start = pb.position(); + pb.skipToChars(QUESTION_RA_QUOTE); + if(pb.eof()) + { + // No Prolog + pb.reset(start); + return; + } + pb.skipN(2); + pb.skipWhitespace(); +} + +void +XMLCursor::decode(Data& text) +{ +} + +void +XMLCursor::decodeName(Data& name) +{ +} + +void +XMLCursor::parseNextRootChild() +{ + // no next child to parse? + if (mRoot->mPb.eof()) + { + return; + } + + // next child already parsed? + if (mRoot->mNext != mRoot->mChildren.end()) + { + return; + } + + // skip self tag + if (mRoot->mPb.position() == mRoot->mPb.start()) + { + mRoot->mPb.skipToChar(Symbols::RA_QUOTE[0]); + mRoot->mPb.skipChar(); + } + + if (!WhitespaceSignificant) + { + mRoot->mPb.skipWhitespace(); + } + + // root end tag? + if (*mRoot->mPb.position() == Symbols::LA_QUOTE[0]) + { + ParseBuffer pb(mRoot->mPb.position(), + mRoot->mPb.end() - mRoot->mPb.position()); + pb.skipChar(); + if (!pb.eof() && *pb.position() == Symbols::SLASH[0]) + { + pb.skipChar(); + // CodeWarrior isn't helpful enough to pick the "obvious" operator definition + // so we add volatile here so CW is completely unconfused what to do. + // second note - MSVC 7.0 won't compile the volatile - tried the following to fix + const char* end = pb.position(); + if ( (const char*)pb.end() < end + mTag.size() ) + { + InfoLog(<< "XML: unexpected end"); + pb.fail(__FILE__, __LINE__); + } + + if (strncmp(mTag.data(), pb.position(), mRoot->mTag.size()) == 0) + { + mRoot->mPb.skipToEnd(); + return; + } + } + } + + // leaf? + if (*mRoot->mPb.position() != Symbols::LA_QUOTE[0]) + { + const char* anchor = mRoot->mPb.position(); + mRoot->mPb.skipToChar(Symbols::LA_QUOTE[0]); + Node* leaf = new Node(ParseBuffer(anchor, mRoot->mPb.position() - anchor)); + leaf->mIsLeaf = true; + mRoot->addChild(leaf); + } + else + { + Node* child = new Node(mRoot->mPb); + child->skipToEndTag(); + + // leave the parse buffer after the child + mRoot->mPb.reset(child->mPb.end()); + + mRoot->addChild(child); + } + + // mNext always points at cursored child + mRoot->mNext = mRoot->mChildren.end(); + mRoot->mNext--; +} + +bool +XMLCursor::nextSibling() +{ + if (atRoot()) + { + StackLog(<< "XMLCursor::nextSibling" << *this->mCursor << " <<root>>"); + return false; + } + + StackLog(<< "XMLCursor::nextSibling" << *this->mCursor << " " << *this->mCursor->mParent); + if (mCursor->mParent == mRoot) + { + parseNextRootChild(); + } + + if (mCursor->mParent->mNext != mCursor->mParent->mChildren.end()) + { + mCursor = *((mCursor->mParent->mNext)++); + mAttributesSet = false; + return true; + } + else + { + return false; + } +} + +bool +XMLCursor::firstChild() +{ + if (atRoot() && + mRoot->mChildren.empty()) + { + parseNextRootChild(); + } + + if (mCursor->mChildren.empty()) + { + return false; + } + else + { + // mNext always points after cursored child + mCursor->mNext = mCursor->mChildren.begin(); + mCursor->mNext++; + mCursor = mCursor->mChildren.front(); + mAttributesSet = false; + return true; + } +} + +bool +XMLCursor::parent() +{ + if (atRoot()) + { + return false; + } + + mCursor = mCursor->mParent; + mAttributesSet = false; + return true; +} + +void +XMLCursor::reset() +{ + mCursor = mRoot; + mAttributesSet = false; +} + +bool +XMLCursor::atRoot() const +{ + return mCursor == mRoot; +} + +bool +XMLCursor::atLeaf() const +{ + return mCursor->mIsLeaf; +} + +const Data& +XMLCursor::getTag() const +{ + return mCursor->mTag; +} + +//<foo > +//<foo> +//<foo/> +//<foo attr = 'value' attr="value"> +//<foo attr = 'value' attr="value" > +// +//<foo attr = 'value' attr="value" /> +static const Data RA_QUOTE_SLASH(">/"); +const XMLCursor::AttributeMap& +XMLCursor::getAttributes() const +{ + if (!atLeaf() && + !mAttributesSet) + { + mAttributes.clear(); + mAttributesSet = true; + + ParseBuffer pb(mCursor->mPb); + pb.reset(mCursor->mPb.start()); + + Data attribute; + Data value; + + pb.skipToOneOf(ParseBuffer::Whitespace, RA_QUOTE_SLASH); + + while (!pb.eof() && + *pb.position() != Symbols::RA_QUOTE[0] && + *pb.position() != Symbols::SLASH[0]) + { + attribute.clear(); + value.clear(); + + const char* anchor = pb.skipWhitespace(); + pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::EQUALS); + pb.data(attribute, anchor); + XMLCursor::decodeName(attribute); + + StackLog(<< "attribute: " << attribute); + + pb.skipWhitespace(); + pb.skipToChar(Symbols::EQUALS[0]); + pb.skipChar(); + pb.skipWhitespace(); + if (!pb.eof()) + { + const char quote = *pb.position(); + + StackLog(<< "quote is <" << quote << ">"); + + if (quote != Symbols::DOUBLE_QUOTE[0] && + quote != '\'') + { + InfoLog(<< "XML: badly quoted attribute value"); + pb.fail(__FILE__, __LINE__); + } + anchor = pb.skipChar(); + pb.skipToChar(quote); + pb.data(value, anchor); + XMLCursor::decode(value); + pb.skipChar(); + mAttributes[attribute] = value; + } + pb.skipWhitespace(); + } + } + + return mAttributes; +} + +const Data& +XMLCursor::getValue() const +{ + if (atLeaf()) + { + ParseBuffer pb(mCursor->mPb); + pb.skipToEnd(); + mValue = pb.data(pb.start()); + XMLCursor::decode(mValue); + } + else + { + mValue.clear(); + } + return mValue; +} + +EncodeStream& +XMLCursor::encode(EncodeStream& str, const AttributeMap& attrs) +{ + for(AttributeMap::const_iterator i = attrs.begin(); + i != attrs.end(); ++i) + { + if (i != attrs.begin()) + { + str << " "; + } + // !dlb! some sort of character encoding required here + str << i->first << "=\"" << i->second << "\""; + } + + return str; +} + +XMLCursor::Node::Node(const ParseBuffer& pb) + : mPb(pb.position(), pb.end() - pb.position()), + mParent(0), + mChildren(), + mNext(mChildren.begin()), + mIsLeaf(false) +{ + mPb.assertNotEof(); + StackLog(<< "XMLCursor::Node::Node" << *this); +} + +XMLCursor::Node::~Node() +{ + for (vector<Node*>::iterator i = mChildren.begin(); + i != mChildren.end(); ++i) + { + delete *i; + } +} + +// start: +//<foo > +//^ +// end: +//<foo > +// ^ +static Data SLASH_RA_QUOTE("/>"); +bool +XMLCursor::Node::extractTag() +{ + ParseBuffer pb(mPb); + const char* anchor = pb.skipChar(); + pb.skipToOneOf(ParseBuffer::Whitespace, SLASH_RA_QUOTE); + pb.assertNotEof(); + pb.data(mTag, anchor); + + return !pb.eof() && *pb.position() == Symbols::SLASH[0]; +} + +void +XMLCursor::Node::addChild(Node* child) +{ + mChildren.push_back(child); + child->mParent = this; +} + +//<foo> <bar> </bar> <baz> </baz> </foo> +//^start +// ^child +// ^child +// ^end +// +//<foo> sdfsf sadfsf <bar> asdfdf </bar> sadfsdf </foo> +//^start +// ^child +// ^child sub +// ^child +void +XMLCursor::Node::skipToEndTag() +{ + extractTag(); + StackLog(<< "XMLCursor::Node::skipToEndTag(" << mTag << ")"); + //StackLog(<< "XMLCursor::Node::skipToEndTag(" << Data(mPb.position(), mPb.end() - mPb.position()) << ")"); + + //<foo /> + mPb.skipToChar(Symbols::RA_QUOTE[0]); + if (*(mPb.position()-1) == Symbols::SLASH[0]) + { + mPb.skipChar(); + mPb = ParseBuffer(mPb.start(), mPb.position() - mPb.start()); + return; + } + + //<foo> ...<child> ... </child> </foo> + // ^ + mPb.skipChar(); + //<foo> ...<child> ... </child> </foo> + // ^ + while (true) + { + if (!WhitespaceSignificant) + { + mPb.skipWhitespace(); + } + + // Some text contents ...< + // ^ ^ + if (*mPb.position() != Symbols::LA_QUOTE[0]) + { + const char* anchor = mPb.position(); + mPb.skipToChar(Symbols::LA_QUOTE[0]); + Node* leaf = new Node(ParseBuffer(anchor, mPb.position() - anchor)); + leaf->mIsLeaf = true; + addChild(leaf); + } + + //<... + //^ + mPb.skipChar(); + //<... + // ^ + + // exit condition + //</foo> + if (*mPb.position() == Symbols::SLASH[0]) + { + mPb.skipChar(); + // CodeWarrior isn't helpful enough to pick the "obvious" operator definition + // so we add volatile here so CW is completely unconfused what to do. + // second note - MSVC 7.0 won't compile the volatile - tried the following to fix + const char* end = mPb.position(); + if ( (const char*)mPb.end() < end + mTag.size() ) + { + InfoLog(<< "XML: unexpected end"); + mPb.fail(__FILE__, __LINE__); + } + + if (strncmp(mTag.data(), mPb.position(), mTag.size()) == 0) + { + mPb.skipToChar(Symbols::RA_QUOTE[0]); + mPb.skipChar(); + mPb = ParseBuffer(mPb.start(), mPb.position() - mPb.start()); + return; + } + else + { + InfoLog(<< "Badly formed XML: unexpected endtag"); + mPb.fail(__FILE__, __LINE__); + } + } + + //<child>... + // ^ + if (mPb.position() == mPb.start()) + { + InfoLog(<< "XML: badly formed element"); + mPb.fail(__FILE__, __LINE__); + } + + mPb.reset(mPb.position()-1); + //<child>... + //^ + Node* child = new Node(mPb); + addChild(child); + child->skipToEndTag(); + mPb.reset(child->mPb.end()); + XMLCursor::decodeName(child->mTag); + StackLog(<< mTag << "(" << child->mTag << ")"); + } +} + +//<!-- declarations for <head> & <body> --> +const char* +XMLCursor::Node::skipComments(ParseBuffer& pb) +{ + while (*pb.position() == Symbols::LA_QUOTE[0] && + *(pb.position()+1) == BANG[0] && + *(pb.position()+2) == HYPHEN[0] && + *(pb.position()+3) == HYPHEN[0]) + { + pb.skipToChars(COMMENT_END); + pb.skipChars(COMMENT_END); + pb.skipWhitespace(); + if(pb.eof()) + { + return pb.end(); + } + } + + return pb.position(); +} + +EncodeStream& +resip::operator<<(EncodeStream& str, const XMLCursor::Node& node) +{ + Data::size_type size = node.mPb.end() - node.mPb.start(); + + static const Data::size_type showSize(35); + + str << &node << "[" + << Data(node.mPb.start(), + min(showSize, size)) + << "]" << (size ? "" : "..."); + + return str; +} + +EncodeStream& +resip::operator<<(EncodeStream& str, const XMLCursor& cursor) +{ + str << "XMLCursor " << *cursor.mCursor; + return str; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/XMLCursor.hxx b/src/libs/resiprocate/resip/stack/XMLCursor.hxx new file mode 100644 index 00000000..ac27d647 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/XMLCursor.hxx @@ -0,0 +1,250 @@ +#if !defined(RESIP_XMLCURSOR_HXX) +#define RESIP_XMLCURSOR_HXX + +#include <iosfwd> +#include <vector> + +#include "rutil/ParseBuffer.hxx" +#include "rutil/HashMap.hxx" + +namespace resip +{ + +/* +// XML tree traversal. +// XMLCursor starts at the root. +// The attributes and value of the cursor are those of the root. +// To descend to the first child of the root, call firstChild(). +// To traverse the children of root from root, call firstChild();nextSibling();nextSibling();... +// To descend into the first child of the current element, call firstChild. +// To return to the parent of the current element, call parent. +// The traversal state among the siblings of the parent is maintained. +// +// root +// / \ +// P1 P2 +// / \ / \ +// A1 A2 B1 B2 +// +// atRoot() == true; +// firstChild(); // P1 +// firstChild(); // A1 +// nextSibling(); // A2 +// parent(); // P1 +// nextSibling(); // P2 +// firstChild(); // B1 +// nextSibling(); // B2 +// parent(); // P2 +// nextSibling(); // false, stay at P2 +// parent(); // root +// nextSibling(); // false, stay at root +// parent(); // false, stay at root +// firstChild(); // P1 + +// E.g.: Depth first traversal +// +// void traverse(XMLCursor& c) +// { +// if (c.firstChild()) +// { +// traverse(c); +// c.parent(); +// } +// +// process(c); +// +// if (c.nextSibling()) +// { +// traverse(c); +// } +// } +// +// E.g.: Lexical Order traversal +// +// void +// traverse(XMLCursor& c, int i = 0) +// { +// for (int ii = 0; ii < i; ++ii) +// { +// cerr << " "; +// } + +// cerr << c.getTag(); +// if (c.atLeaf()) +// { +// cerr << "[" << c.getValue() << "]" << endl; +// } +// else +// { +// cerr << endl; +// } + +// if (c.firstChild()) +// { +// traverse(c, i+2); +// c.parent(); +// } + +// if (c.nextSibling()) +// { +// traverse(c, i+2); +// } +// } + +*/ + +class XMLCursor +{ + public: + // !dlb! should be determined by the document + // see http://www.w3.org/TR/1998/REC-xml-19980210#sec-white-space + enum {WhitespaceSignificant = false}; + + XMLCursor(const ParseBuffer& pb); + ~XMLCursor(); + + bool nextSibling(); + bool firstChild(); + bool parent(); + void reset(); + + bool atRoot() const; + bool atLeaf() const; + + const Data& getTag() const; + typedef HashMap<Data, Data> AttributeMap; + const AttributeMap& getAttributes() const; + const Data& getValue() const; + + static EncodeStream& encode(EncodeStream& strm, const AttributeMap& attrs); + class Node; + + class AttributeValueEqual { + Data data_; + public: + AttributeValueEqual(const Data& data) : data_(data) {}; + bool operator()(const std::pair<Data, Data>& data) { return data.second == data_; } + }; + + private: + static void skipProlog(ParseBuffer& pb); + static void decode(Data&); + static void decodeName(Data&); + + void parseNextRootChild(); + + + Node* mRoot; + Node* mCursor; + + //bool isEmpty; + + // store for undecoded root tag + Data mTag; + + // store for copy of input if commented + Data mData; + + // store date for decoding + mutable Data mValue; + // store attributes for reference + mutable AttributeMap mAttributes; + mutable bool mAttributesSet; + +public: + class Node + { + public: + Node(const ParseBuffer& pb); + ~Node(); + + void addChild(Node*); + // return true if <foo/> + bool extractTag(); + void skipToEndTag(); + static const char* skipComments(ParseBuffer& pb); + + ParseBuffer mPb; + Node* mParent; + std::vector<Node*> mChildren; + std::vector<Node*>::const_iterator mNext; + + bool mIsLeaf; + Data mTag; + + private: + Node(const Node&); + Node& operator=(const Node&); + + friend EncodeStream& operator<<(EncodeStream& str, const XMLCursor& cursor); + // friend EncodeStream& operator<<(EncodeStream& str, const XMLCursor::Node& cursor); // this line won't compile in windows + }; + private: + friend EncodeStream& operator<<(EncodeStream&, const XMLCursor&); + friend EncodeStream& operator<<(EncodeStream&, const XMLCursor::Node&); + + // no value semantics + XMLCursor(const XMLCursor&); + XMLCursor& operator=(const XMLCursor&); + friend class Node; +}; + +EncodeStream& +operator<<(EncodeStream& str, const XMLCursor& cursor); + +EncodeStream& +operator<<(EncodeStream& str, const XMLCursor::Node& cursor); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ZeroOutStatistics.hxx b/src/libs/resiprocate/resip/stack/ZeroOutStatistics.hxx new file mode 100644 index 00000000..57bd29e9 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ZeroOutStatistics.hxx @@ -0,0 +1,85 @@ +#ifndef ZeroOutStatistics_Include_Guard +#define ZeroOutStatistics_Include_Guard + +#include "resip/stack/TransactionMessage.hxx" + +namespace resip +{ +class ZeroOutStatistics : public TransactionMessage +{ + public: + explicit ZeroOutStatistics(){} + virtual ~ZeroOutStatistics(){} + + virtual const Data& getTransactionId() const {return Data::Empty;} + virtual bool isClientTransaction() const {return true;} + virtual EncodeStream& encode(EncodeStream& strm) const + { + return strm << "ZeroOutStatistics"; + } + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "ZeroOutStatistics"; + } + + virtual Message* clone() const + { + return new ZeroOutStatistics(*this); + } +}; // class ZeroOutStatistics + +} // namespace resip + +#endif // include guard + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ + diff --git a/src/libs/resiprocate/resip/stack/config.hxx.in b/src/libs/resiprocate/resip/stack/config.hxx.in new file mode 100644 index 00000000..a17c1da1 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/config.hxx.in @@ -0,0 +1,116 @@ +/* resiprocate/config.hxx.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the <netinet/in.h> header file. */ +#undef HAVE_NETINET_IN_H + +/* Has popt.h */ +#undef HAVE_POPT_H + +/* Define if you have POSIX threads libraries and header files. */ +#undef HAVE_PTHREAD + +/* Has socklen_t */ +#undef HAVE_SOCKLEN_T + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <sys/int_types.h> header file. */ +#undef HAVE_SYS_INT_TYPES_H + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the <sys/sockio.h> header file. */ +#undef HAVE_SYS_SOCKIO_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Use NewHeaderScanner instead of Preparser */ +#undef NEW_MSG_HEADER_SCANNER + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to the necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* Data local size */ +#undef RESIP_DATA_LOCAL_SIZE + +/* The major version number of resip */ +#undef RESIP_MAJOR_VERSION + +/* The micro version number of resip */ +#undef RESIP_MICRO_VERSION + +/* The minor version number of resip */ +#undef RESIP_MINOR_VERSION + +/* set when debugging requested in MsgHeaderScanner */ +#undef RESIP_MSG_HEADER_SCANNER_DEBUG + +/* BaseException DebugLog Disposition */ +#undef RESIP_NO_EXCEPTION_DEBUG_LOGS + +/* The version number of resip */ +#undef RESIP_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Select ARES Resolver */ +#undef USE_ARES + +/* Select IPv6 code */ +#undef USE_IPV6 + +/* Use OpenSSL */ +#undef USE_SSL + +/* Version number of package */ +#undef VERSION + +/* Needs BSD socklen_t */ +#undef _BSD_SOCKLEN_T_ diff --git a/src/libs/resiprocate/resip/stack/dayofweek.gperf b/src/libs/resiprocate/resip/stack/dayofweek.gperf new file mode 100644 index 00000000..fdf69c9f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/dayofweek.gperf @@ -0,0 +1,9 @@ +struct days { const char *name; DayOfWeek type; }; +%% +Sun, DayOfWeek::Sun +Mon, DayOfWeek::Mon +Tue, DayOfWeek::Tue +Wed, DayOfWeek::Wed +Thu, DayOfWeek::Thu +Fri, DayOfWeek::Fri +Sat, DayOfWeek::Sat diff --git a/src/libs/resiprocate/resip/stack/doc/.cvsignore b/src/libs/resiprocate/resip/stack/doc/.cvsignore new file mode 100644 index 00000000..e1a49fa0 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/.cvsignore @@ -0,0 +1,6 @@ +Preparse.dot +design-overview.html +out +Preparse.png.dot +Preparse.ps.dot +Preparse.svg.dot diff --git a/src/libs/resiprocate/resip/stack/doc/ClassDiag.vsd b/src/libs/resiprocate/resip/stack/doc/ClassDiag.vsd new file mode 100644 index 00000000..9fb5591a Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ClassDiag.vsd differ diff --git a/src/libs/resiprocate/resip/stack/doc/FifoFlow.pdf b/src/libs/resiprocate/resip/stack/doc/FifoFlow.pdf new file mode 100644 index 00000000..82682b49 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/FifoFlow.pdf differ diff --git a/src/libs/resiprocate/resip/stack/doc/FifoFlow.vsd b/src/libs/resiprocate/resip/stack/doc/FifoFlow.vsd new file mode 100644 index 00000000..2e4d48ba Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/FifoFlow.vsd differ diff --git a/src/libs/resiprocate/resip/stack/doc/Makefile.am b/src/libs/resiprocate/resip/stack/doc/Makefile.am new file mode 100644 index 00000000..27687ba5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/Makefile.am @@ -0,0 +1,102 @@ + +EXTRA_DIST = *.vsd +EXTRA_DIST += *.tif *.jpg *.png *.gif +EXTRA_DIST += *.html *.css +EXTRA_DIST += *.xml *.xsl +EXTRA_DIST += *.pdf +EXTRA_DIST += *.awk +EXTRA_DIST += oxygenProject.xpr +EXTRA_DIST += *.sitx +EXTRA_DIST += *.txt +EXTRA_DIST += *.ai +EXTRA_DIST += *.svg +EXTRA_DIST += *.dot + +SUBDIRS = static + +TO=neato +DOT=dot + +FSMS=srv-inv-fsm srv-inv-tree Preparse +OUTDIR=out + +PSFILES=$(patsubst %, $(OUTDIR)/%.ps, $(FSMS)) +PDFFILES=$(patsubst %, $(OUTDIR)/%.pdf, $(FSMS)) +SVGFILES=$(patsubst %, $(OUTDIR)/%.svg, $(FSMS)) +PNGFILES=$(patsubst %, $(OUTDIR)/%.png, $(FSMS)) + +DOCBOOKTARGETS=design-overview.html +XSLP=xsltproc +XSLPOPT=--xinclude +HTMLSHEET=htmlcss.xsl + +FILES=$(PSFILES) $(PDFFILES) $(SVGFILES) $(PNGFILES) $(DOCBOOKTARGETS) + +.PRECIOUS: Preparse.svg.dot Preparse.ps.dot Preparse.png.dot + +.phony: + +all: $(FILES) + +%.html: $(HTMLSHEET) %.xml + $(XSLP) $(XSLPOPT) -o $@ $^ + +#design-overview.html: $(HTMLSHEET) design-overview.xml +# $(XSLP) $(XSLPOPT) -o $@ $^ + +$(OUTDIR): + -mkdir $@ + +$(OUTDIR)/%.pdf: $(OUTDIR)/%.ps Makefile $(OUTDIR) + ps2pdf13 $< $@ + +#Digraphs +$(OUTDIR)/%.ps: %.ps.dot Makefile $(OUTDIR) + $(DOT) -Tps -o$@ $< + +$(OUTDIR)/%.png: %.png.dot + $(DOT) -Tpng -o$@ $< + +$(OUTDIR)/%.svg: %.svg.dot Makefile $(OUTDIR) + $(DOT) -Tsvg -o$@ $< + +# Graphs +$(OUTDIR)/%.ps: %.neato Makefile $(OUTDIR) + $(NEATO) -Tps -o$@ $< +$(OUTDIR)/%.png: %.neato + $(NEATO) -Tpng -o$@ $< +$(OUTDIR)/%.svg: %.neato Makefile $(OUTDIR) + $(NEATO) -Tsvg -o$@ $< + +# Old style diagrams +%.ps.dot: %.dot + ln -s $(@:.ps.dot=.dot) $@ + +%.png.dot: %.dot + ln -s $(@:.png.dot=.dot) $@ + +%.svg.dot: %.dot + ln -s $(@:.svg.dot=.dot) $@ + +# Code autogen +%.ps.dot: ../%.cxx fsm-dot.awk Makefile + awk --assign output=$(@:.dot=) -f fsm-dot.awk $< > $@ + +%.svg.dot: ../%.cxx fsm-dot.awk Makefile + awk --assign output=$(@:.dot=) -f fsm-dot.awk $< > $@ + + +%.png.dot: ../%.cxx fsm-dot.awk Makefile + awk --assign output=$(@:.dot=) -f fsm-dot.awk $< > $@ + + +clean: + -/bin/rm -f $(FILES) *.ps + +dummy: + cp *.pdf ~/public_html/misc/ + + +test: + -@echo $(FILES) + diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams.pdf b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams.pdf new file mode 100644 index 00000000..f00ce5ea Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams.pdf differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams.sitx b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams.sitx new file mode 100644 index 00000000..1a7d6aa5 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams.sitx differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_1.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_1.png new file mode 100644 index 00000000..7dd43703 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_1.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_10.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_10.png new file mode 100644 index 00000000..c2c5dd21 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_10.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_11.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_11.png new file mode 100644 index 00000000..b0764235 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_11.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_12.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_12.png new file mode 100644 index 00000000..2ce8ba1a Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_12.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_13.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_13.png new file mode 100644 index 00000000..a213b29e Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_13.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_14.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_14.png new file mode 100644 index 00000000..f4abb841 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_14.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_15.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_15.png new file mode 100644 index 00000000..8c9f0356 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_15.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_16.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_16.png new file mode 100644 index 00000000..d107cc9f Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_16.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_17.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_17.png new file mode 100644 index 00000000..58f85997 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_17.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_18.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_18.png new file mode 100644 index 00000000..dc740ebf Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_18.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_19.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_19.png new file mode 100644 index 00000000..b6bc03bd Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_19.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_2.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_2.png new file mode 100644 index 00000000..cf574798 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_2.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_20.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_20.png new file mode 100644 index 00000000..357928eb Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_20.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_21.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_21.png new file mode 100644 index 00000000..7e4fc97d Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_21.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_22.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_22.png new file mode 100644 index 00000000..541f58bc Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_22.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_23.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_23.png new file mode 100644 index 00000000..f3563493 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_23.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_24.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_24.png new file mode 100644 index 00000000..d73e8713 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_24.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_25.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_25.png new file mode 100644 index 00000000..0cdb863d Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_25.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_26.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_26.png new file mode 100644 index 00000000..2fbae575 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_26.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_3.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_3.png new file mode 100644 index 00000000..9ca144e3 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_3.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_4.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_4.png new file mode 100644 index 00000000..fd629c88 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_4.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_5.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_5.png new file mode 100644 index 00000000..ccc3e3ec Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_5.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_6.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_6.png new file mode 100644 index 00000000..ba067ab7 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_6.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_7.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_7.png new file mode 100644 index 00000000..048f3007 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_7.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_8.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_8.png new file mode 100644 index 00000000..46d8b613 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_8.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_9.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_9.png new file mode 100644 index 00000000..8b204d89 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_9.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_Architecture.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_Architecture.png new file mode 100644 index 00000000..d2fdf603 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_Architecture.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_Main_Event_Loop.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_Main_Event_Loop.png new file mode 100644 index 00000000..794665a9 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_Main_Event_Loop.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_Process_Incoming_UDP.png b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_Process_Incoming_UDP.png new file mode 100644 index 00000000..b70106a2 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ReSIP_diagrams_-_Process_Incoming_UDP.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/ResipArchitecture.graffle b/src/libs/resiprocate/resip/stack/doc/ResipArchitecture.graffle new file mode 100644 index 00000000..5584b82b --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/ResipArchitecture.graffle @@ -0,0 +1,2653 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CanvasColor</key> + <dict> + <key>w</key> + <string>1</string> + </dict> + <key>ColumnAlign</key> + <integer>1</integer> + <key>ColumnSpacing</key> + <real>42.519683837890625</real> + <key>GraphDocumentVersion</key> + <integer>4</integer> + <key>GraphicsList</key> + <array> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>Head</key> + <dict> + <key>ID</key> + <integer>111</integer> + </dict> + <key>ID</key> + <integer>159</integer> + <key>Labels</key> + <array> + <dict> + <key>Label</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\fs18 \cf0 add}</string> + </dict> + <key>LabelVisible</key> + <string>YES</string> + <key>Offset</key> + <real>0.0</real> + <key>Position</key> + <real>0.15397000312805176</real> + </dict> + </array> + <key>Points</key> + <array> + <string>{207.036, 269}</string> + <string>{207.136, 195}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>109</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>Head</key> + <dict> + <key>ID</key> + <integer>114</integer> + </dict> + <key>ID</key> + <integer>158</integer> + <key>Labels</key> + <array> + <dict> + <key>FixedWidth</key> + <real>54</real> + <key>Label</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\fs18 \cf0 App Timer}</string> + </dict> + <key>LabelVisible</key> + <string>YES</string> + <key>Offset</key> + <real>0.0</real> + <key>Position</key> + <real>0.51178056001663208</real> + </dict> + </array> + <key>Points</key> + <array> + <string>{223.169, 195}</string> + <string>{282.198, 278}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>111</integer> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{381, 693}, {141, 11}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FitText</key> + <string>YES</string> + <key>Flow</key> + <string>Resize</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>157</integer> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs18 \cf0 MHS: Message Header Scanner}</string> + </dict> + <key>Wrap</key> + <string>NO</string> + </dict> + <dict> + <key>Bounds</key> + <string>{{319, 658}, {30.963, 22}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>9</real> + </dict> + <key>ID</key> + <integer>156</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.8</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>1</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs18 \cf0 MHS}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{239, 658}, {30.963, 22}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>9</real> + </dict> + <key>ID</key> + <integer>155</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.8</string> + <key>r</key> + <string>0.6</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs18 \cf0 MHS}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{146, 658}, {30.963, 22}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>9</real> + </dict> + <key>ID</key> + <integer>154</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.8</string> + <key>r</key> + <string>1</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs18 \cf0 MHS}</string> + </dict> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{385, 112}, {169, 183}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FitText</key> + <string>Vertical</string> + <key>Flow</key> + <string>Resize</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Zapfino</string> + <key>Size</key> + <real>18</real> + </dict> + <key>ID</key> + <integer>152</integer> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fnil\fcharset77 Zapfino;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs36 \cf0 reSIProcate \ +\ + Architecture}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{405, 139}, {128, 128}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>153</integer> + <key>ImageID</key> + <integer>1</integer> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>151</integer> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>148</integer> + <key>Position</key> + <real>0.34582534432411194</real> + </dict> + <key>ID</key> + <integer>150</integer> + <key>Points</key> + <array> + <string>{174.937, 687.217}</string> + <string>{141.475, 722}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>142</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>148</integer> + <key>Position</key> + <real>0.18943937122821808</real> + </dict> + <key>ID</key> + <integer>149</integer> + <key>Points</key> + <array> + <string>{276.964, 688.347}</string> + <string>{257.775, 722}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>143</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>Head</key> + <dict> + <key>ID</key> + <integer>121</integer> + </dict> + <key>ID</key> + <integer>148</integer> + <key>Labels</key> + <array> + <dict> + <key>Label</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\fs18 \cf0 SIP Message}</string> + </dict> + <key>LabelVisible</key> + <string>YES</string> + <key>Offset</key> + <real>0.0</real> + <key>Position</key> + <real>0.83192622661590576</real> + </dict> + </array> + <key>Points</key> + <array> + <string>{364.556, 688.347}</string> + <string>{365, 722}</string> + <string>{54, 722}</string> + <string>{57.7465, 323}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>144</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>144</integer> + </dict> + <key>ID</key> + <integer>147</integer> + <key>Points</key> + <array> + <string>{364.011, 623.59}</string> + <string>{364.172, 649}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>138</integer> + <key>Position</key> + <real>0.52989864349365234</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>143</integer> + </dict> + <key>ID</key> + <integer>146</integer> + <key>Points</key> + <array> + <string>{288, 622.997}</string> + <string>{288.104, 649}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>138</integer> + <key>Position</key> + <real>0.33246758580207825</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>142</integer> + </dict> + <key>ID</key> + <integer>145</integer> + <key>Points</key> + <array> + <string>{194.006, 622.265}</string> + <string>{193.298, 649}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>138</integer> + <key>Position</key> + <real>0.08832656592130661</real> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{344.623, 649}, {39.3467, 39.3467}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>9</real> + </dict> + <key>ID</key> + <integer>144</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.8</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>1</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs18 \cf0 TLS Recv}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{268.509, 649}, {39.3467, 39.3467}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>9</real> + </dict> + <key>ID</key> + <integer>143</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.8</string> + <key>r</key> + <string>0.6</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs18 \cf0 TCP Recv}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{173.103, 649}, {39.3467, 39.3467}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>9</real> + </dict> + <key>ID</key> + <integer>142</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.8</string> + <key>r</key> + <string>1</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs18 \cf0 UDP Recv}</string> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>138</integer> + <key>Position</key> + <real>0.529837965965271</real> + </dict> + <key>ID</key> + <integer>141</integer> + <key>Points</key> + <array> + <string>{364.186, 588.347}</string> + <string>{363.988, 623.59}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>132</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>138</integer> + <key>Position</key> + <real>0.33504462242126465</real> + </dict> + <key>ID</key> + <integer>140</integer> + <key>Points</key> + <array> + <string>{288.476, 588.347}</string> + <string>{288.992, 623.005}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>130</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>138</integer> + <key>Position</key> + <real>0.085729323327541351</real> + </dict> + <key>ID</key> + <integer>139</integer> + <key>Points</key> + <array> + <string>{192.861, 588.347}</string> + <string>{193.006, 622.257}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>128</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>138</integer> + <key>Labels</key> + <array> + <dict> + <key>Label</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\fs24 \cf0 NETWORK}</string> + </dict> + <key>LabelVisible</key> + <string>YES</string> + <key>Offset</key> + <real>0.0</real> + <key>Position</key> + <real>0.78183144330978394</real> + </dict> + </array> + <key>Points</key> + <array> + <string>{160, 622}</string> + <string>{545, 625}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>0</string> + <key>HopLines</key> + <true/> + <key>Pattern</key> + <integer>3</integer> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>2</real> + </dict> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>Head</key> + <dict> + <key>ID</key> + <integer>121</integer> + </dict> + <key>ID</key> + <integer>137</integer> + <key>Labels</key> + <array> + <dict> + <key>Label</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\fs18 \cf0 add}</string> + </dict> + <key>LabelVisible</key> + <string>YES</string> + <key>Offset</key> + <real>0.0</real> + <key>Position</key> + <real>0.6176835298538208</real> + </dict> + </array> + <key>Points</key> + <array> + <string>{58, 199}</string> + <string>{58, 269}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>108</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>132</integer> + </dict> + <key>ID</key> + <integer>136</integer> + <key>Points</key> + <array> + <string>{364.615, 518.231}</string> + <string>{364.42, 549}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>133</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>130</integer> + </dict> + <key>ID</key> + <integer>135</integer> + <key>Points</key> + <array> + <string>{288.501, 518.231}</string> + <string>{288.306, 549}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>131</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>128</integer> + </dict> + <key>ID</key> + <integer>134</integer> + <key>Points</key> + <array> + <string>{193.095, 518.231}</string> + <string>{192.901, 549}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>129</integer> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{345.024, 492}, {39.3467, 26.2311}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>9</real> + </dict> + <key>ID</key> + <integer>133</integer> + <key>Shape</key> + <string>RoundRect</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.8</string> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>90</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>0.8</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>1</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs16 \cf0 Trans FIFO}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{344.623, 549}, {39.3467, 39.3467}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>9</real> + </dict> + <key>ID</key> + <integer>132</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.8</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>1</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs18 \cf0 TLS Trans}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{268.91, 492}, {39.3467, 26.2311}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>8</real> + </dict> + <key>ID</key> + <integer>131</integer> + <key>Shape</key> + <string>RoundRect</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.8</string> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>90</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.8</string> + <key>r</key> + <string>0.6</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs16 \cf0 Trans FIFO}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{268.509, 549}, {39.3467, 39.3467}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>9</real> + </dict> + <key>ID</key> + <integer>130</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.8</string> + <key>r</key> + <string>0.6</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs18 \cf0 TCP Trans}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{173.505, 492}, {39.3467, 26.2311}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>8</real> + </dict> + <key>ID</key> + <integer>129</integer> + <key>Shape</key> + <string>RoundRect</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.8</string> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>90</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.8</string> + <key>r</key> + <string>1</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs16 \cf0 Trans FIFO}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{173.103, 549}, {39.3467, 39.3467}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>9</real> + </dict> + <key>ID</key> + <integer>128</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.8</string> + <key>r</key> + <string>1</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs18 \cf0 UDP Trans}</string> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>133</integer> + </dict> + <key>ID</key> + <integer>127</integer> + <key>Points</key> + <array> + <string>{382, 470}</string> + <string>{371.16, 492}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>123</integer> + <key>Info</key> + <integer>1</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>131</integer> + </dict> + <key>ID</key> + <integer>126</integer> + <key>Points</key> + <array> + <string>{286.449, 470}</string> + <string>{287.786, 492}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>123</integer> + <key>Position</key> + <real>0.53389829397201538</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>129</integer> + </dict> + <key>ID</key> + <integer>125</integer> + <key>Points</key> + <array> + <string>{177, 470}</string> + <string>{187.136, 492}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>123</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>123</integer> + <key>Position</key> + <real>0.47718718647956848</real> + </dict> + <key>ID</key> + <integer>124</integer> + <key>Points</key> + <array> + <string>{273.325, 421}</string> + <string>{274.823, 470}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>0</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>112</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>123</integer> + <key>Points</key> + <array> + <string>{177, 470}</string> + <string>{382, 470}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>0</string> + <key>HopLines</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>Head</key> + <dict> + <key>ID</key> + <integer>109</integer> + </dict> + <key>ID</key> + <integer>122</integer> + <key>Labels</key> + <array> + <dict> + <key>Label</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\fs18 \cf0 Txn\ +Events}</string> + </dict> + <key>LabelVisible</key> + <string>YES</string> + <key>Offset</key> + <real>0.0</real> + <key>Position</key> + <real>0.46341463923454285</real> + </dict> + </array> + <key>Points</key> + <array> + <string>{85, 296}</string> + <string>{167, 296}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>LineType</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>121</integer> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{31, 269}, {54, 54}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>121</integer> + <key>Shape</key> + <string>RoundRect</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.8</string> + <key>r</key> + <string>1</string> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>318</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.8</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs24 \cf0 Txn FIFO}</string> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>Head</key> + <dict> + <key>ID</key> + <integer>112</integer> + </dict> + <key>ID</key> + <integer>120</integer> + <key>Labels</key> + <array> + <dict> + <key>Label</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\fs18 \cf0 SIP Message}</string> + </dict> + <key>LabelVisible</key> + <string>YES</string> + <key>Offset</key> + <real>0.0</real> + <key>Position</key> + <real>0.56025338172912598</real> + </dict> + </array> + <key>Points</key> + <array> + <string>{225.046, 323}</string> + <string>{254.454, 367}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>LineType</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>109</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>Head</key> + <dict> + <key>ID</key> + <integer>121</integer> + </dict> + <key>ID</key> + <integer>119</integer> + <key>Labels</key> + <array> + <dict> + <key>Label</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\fs18 \cf0 response}</string> + </dict> + <key>LabelVisible</key> + <string>YES</string> + <key>Offset</key> + <real>0.0</real> + <key>Position</key> + <real>0.45411491394042969</real> + </dict> + </array> + <key>Points</key> + <array> + <string>{111.025, 358.095}</string> + <string>{79.6705, 321.377}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>LineType</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>110</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>Head</key> + <dict> + <key>ID</key> + <integer>110</integer> + </dict> + <key>ID</key> + <integer>118</integer> + <key>Labels</key> + <array> + <dict> + <key>Label</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\fs18 \cf0 request}</string> + </dict> + <key>LabelVisible</key> + <string>YES</string> + <key>Offset</key> + <real>0.0</real> + <key>Position</key> + <real>0.50982195138931274</real> + </dict> + </array> + <key>Points</key> + <array> + <string>{184.854, 323}</string> + <string>{156.144, 358.002}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>LineType</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>109</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>114</integer> + </dict> + <key>ID</key> + <integer>117</integer> + <key>Points</key> + <array> + <string>{247, 296}</string> + <string>{268, 296}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>LineType</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>109</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>Head</key> + <dict> + <key>ID</key> + <integer>121</integer> + </dict> + <key>ID</key> + <integer>116</integer> + <key>Labels</key> + <array> + <dict> + <key>Label</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\fs18 \cf0 TxnEvent}</string> + </dict> + <key>LabelVisible</key> + <string>YES</string> + <key>Offset</key> + <real>0.0</real> + <key>Position</key> + <real>0.68321812152862549</real> + </dict> + </array> + <key>Points</key> + <array> + <string>{182.844, 192.637}</string> + <string>{82.3002, 275.881}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>LineType</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>111</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>Head</key> + <dict> + <key>ID</key> + <integer>107</integer> + </dict> + <key>ID</key> + <integer>115</integer> + <key>Labels</key> + <array> + <dict> + <key>Label</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\fs18 \cf0 Message}</string> + </dict> + <key>LabelVisible</key> + <string>YES</string> + <key>Offset</key> + <real>0.0</real> + <key>Position</key> + <real>0.47527125477790833</real> + </dict> + </array> + <key>Points</key> + <array> + <string>{295, 278}</string> + <string>{295, 93}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>LineType</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>114</integer> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{268, 278}, {54, 36}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>114</integer> + <key>Shape</key> + <string>RoundRect</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.8</string> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>316</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>1</string> + <key>r</key> + <string>1</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs24 \cf0 TU FIFO}</string> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>Head</key> + <dict> + <key>ID</key> + <integer>108</integer> + </dict> + <key>ID</key> + <integer>113</integer> + <key>Labels</key> + <array> + <dict> + <key>Label</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\fs18 \cf0 SIP Messages}</string> + </dict> + <key>LabelVisible</key> + <string>YES</string> + <key>Offset</key> + <real>0.0</real> + <key>Position</key> + <real>0.4229586124420166</real> + </dict> + </array> + <key>Points</key> + <array> + <string>{234.632, 93}</string> + <string>{85, 159.924}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>LineType</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>107</integer> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{195, 367}, {155, 54}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>112</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.8</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs24 \cf0 Transport Selector}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{178, 150}, {58.3333, 45}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>111</integer> + <key>Shape</key> + <string>RoundRect</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.8</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs20 \cf0 Timer Queue}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{107, 358}, {54, 54}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>110</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>270</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.8</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs24 \cf0 Async DNS}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{167, 269}, {80, 54}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>109</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.8</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs24 \cf0 Transaction FSM}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{31, 145}, {54, 54}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>108</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.8</string> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>316</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>1</string> + <key>r</key> + <string>1</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs24 \cf0 SIP Stack\ +Object}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{162, 39}, {266, 54}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>107</integer> + <key>Shape</key> + <string>RoundedRectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>1</string> + <key>r</key> + <string>1</string> + </dict> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\fs24 \cf0 Application / Dialog Usage Manager}</string> + </dict> + </dict> + </array> + <key>GridInfo</key> + <dict/> + <key>GuidesLocked</key> + <string>NO</string> + <key>GuidesVisible</key> + <string>YES</string> + <key>HPages</key> + <integer>1</integer> + <key>ImageCounter</key> + <integer>2</integer> + <key>Images</key> + <array> + <dict> + <key>Extension</key> + <string>jpg</string> + <key>ID</key> + <integer>1</integer> + <key>RawData</key> + <data> + /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHBwcJCQgK + DBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0 + Hyc5PTgyPC4zNDL/wAALCACAAIABAREA/8QAHAABAQACAwEBAAAA + AAAAAAAAAAUEBwIGCAED/8QAOxAAAQMDAgUCAwYCCgMAAAAAAQAC + AwQFEQYhBxIxQWFRcRMi0SMyYnKBoUTSFCQlM0NSU2ORknOCwf/a + AAgBAQAAPwDf6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI + um6414zRFRanVFKZ6WskeyVzTh0YHLuPXqV2GzXugv8Ab46+2VLK + imeNnNO4OOhHY+FRByAUREXxzuULFfXsjJBY44WNJe4Y/wDDcsWT + U8Uf8NIfOViS62p4+tJL/wBgsSTiJSx/wM3/AGCwpeK1DFkG21Bx + +ILFk4yUEfW1VJ/9x9Fhy8c7dHn+xqs4/GPotc8TuIlLrejt9PTU + VRTGnke5xkcCN8ePC6NpvV950ddGVtoqHNaSPiQkkxyjy3/6vTWg + eKVm1tTtgDhSXVjftKWQ/ex1cw9x46j913rmPMBt58Lki4lxHY+F + iirhqfisilbI+N3K9rDnlPoViVRxkAnGdlIqiSFFqtwRupNSARjC + i1Z2IUWqJI6lRqoNIOWj33UOrwcjHf1UapAwRjO6k1RwWjAwOn0X + CnnmpaiOemnfFNG4PZIxxaWkdCD6r0hwh4p3bUlQ2yXeilrJ425b + XwN2a0Y/vR0Hg9z27rdKxayvprfSy1VZPHBTxDLpJDygBaY1Zxbq + LkHUWng6OmdkPqsYc8fhz0BH6q7wkrYYbFXmqqWRyOqg8mR/zOGF + 3Sauo5G/LWQZ/Mps88Dshs8RP5lHqXtcSGuBOVLqA92Q2NxKk1VP + M/IbBIT+VSZ7fWPHy0dST4jKkVdsuG4bQ1Oc/wCi76KPU2e5HP8A + UKrP/hd9FBudBV0bWuqaWaEPJDTIwgEqBUgc27gXDbDfqticPOEN + 11gIa6uzQWbmz8Vw+ebw1vp5O3uvTentNWvS9rit9ppWU8Td38uO + aR2MZccblRdZ8RrNo2nc2eQVNwcD8KjhcC4+XHo0e/6LzvqbXN51 + nWiW4TctK1xdFSRkiNnp5J9/+FhU+XABxJGcqzTd+UlocBs0kK1T + HJBOTn8RVilAyDj9yrNLkY+Y49FZpR07qzTZON+3oFYpQNlUj6Df + sv0WnOPFHV3ChsdHRU8tRUTVMjWRRMy5xxtjAK/DQHBGloXQ3XU7 + Wz1jcOjpAR8OPvl2Op/XC3MyKNkbWxtDWgAANGAB2GF+i1dxB4P0 + Gq55btbHiju+DzHOY5j5HY+QtA3Cx3LTtwdQ3SmNPMwlpz912Nsh + 3p6dVlU2x7/qrNKD8uxJI2CsU2dhyOBCs0p6dM47lWaXfGHNyrFM + 4bDO/srNKc4xjp3Ks0rugxuqjDhoz6LnnutU8Z7/AHPTUdjudqqD + FPHNJnoQ9uBlpHdUtB8WLTq/4dDVBtBdjsYJDhsh/wBsnqfwncee + q2EOblOSM+pC59RlfOUZzuD4UfUOmLZqe3OpLpTMmxkxvxh0Z9Wn + stFaq4a3TSr31NOySutm/wBswZfGPxgD9xt7dF2rhbpu03mx1lRX + 2+OeRk3IHOedvlB9fVdwk0fYIWgNtsW233nfVYctitkQ+SkYAOnV + YU1LBFnkjAA6LElqp4hhkhAGwCnz325Q55Klwx4CwZdY6giHyXKR + oHQcrdv2WBPxD1XHs27yAD/aj/lUuo4m6waSBepOv+lH/Kupam1b + fdSQww3e4SVMcLnOY1zWgAnbsAuozyOjmbIzaQEEPBOQQtz8OeOc + 9C6G1asL56bZsdaAS+PsOf1Hleg6Ouhr6aGqpJo6illZzMmidlrh + tjH7rKTC4Oja9pa7Ja4YcPVTrfY7dZXVDrfTtgbO/wCI9jNm5xjY + dl+dTtn3Uip6FR6rv7qRU91ErO/uotT0Kj1Xf3USq6n3UWp7+6kV + X3gvzwXMaBn0Hv6L0HwN05rG3uFfUVL6OwyDIoqlh5ps5w5rc5YM + jYnY56Fb4RFwkBI2WHNRSSbhzd/CwZrNO8bPYsGbS9VJuJo9/BWB + Noyvk+7PT/q4/RT5+HtxlG1VS5/MfosCbhddpB8tbRj35/5VgTcH + r1IMi4UG/wCf6KfNwPv0ueW520Z9TJ/Kuia94fXLRNPTT11VSzNq + HOaBCXZyBnuAulUtnrr3dIrfbaWWpq5ThkcYyfc/5R5K9EcO+ClB + p58Vy1B8OtuYAdHD1ihPtjcj16LbzWBuMdlyREXzA9F9wF85R6Jh + Me//ACmPJTHlMe613xO0LcNbutFJRyRwwQyyOnmleSGggYw3O56r + sOktD2XRtB/R7bB9q8fbVLwPiSHyR0HgLsYGBgL6iIiIiIiIiIiI + iIiIiIiIiIiIiIiIiIiIv//Z + </data> + </dict> + </array> + <key>IsPalette</key> + <string>NO</string> + <key>Layers</key> + <array> + <dict> + <key>Lock</key> + <string>NO</string> + <key>Name</key> + <string>Layer 1</string> + <key>Print</key> + <string>YES</string> + <key>View</key> + <string>YES</string> + </dict> + </array> + <key>LayoutInfo</key> + <dict> + <key>ChildOrdering</key> + <integer>0</integer> + </dict> + <key>LinksVisible</key> + <string>NO</string> + <key>MagnetsVisible</key> + <string>NO</string> + <key>Orientation</key> + <integer>2</integer> + <key>PageBreaks</key> + <string>YES</string> + <key>PageSetup</key> + <data> + BAt0eXBlZHN0cmVhbYED6IQBQISEhAtOU1ByaW50SW5mbwGEhAhOU09iamVjdACFkoSE + hBNOU011dGFibGVEaWN0aW9uYXJ5AISEDE5TRGljdGlvbmFyeQCUhAFpFJKEhIQITlNT + dHJpbmcBlIQBKxBOU0pvYkRpc3Bvc2l0aW9uhpKEmZkPTlNQcmludFNwb29sSm9ihpKE + mZkLTlNQYXBlclNpemWGkoSEhAdOU1ZhbHVlAJSEASqEhAx7X05TU2l6ZT1mZn2cgQJk + gQMYhpKEmZkZTlNQcmludFJldmVyc2VPcmllbnRhdGlvboaShISECE5TTnVtYmVyAJ2b + hJeXAIaShJmZFE5TVmVydGljYWxQYWdpbmF0aW9uhpKEoZuilwCGkoSZmRROU1ZlcnRp + Y2FsbHlDZW50ZXJlZIaShKGbopcBhpKEmZkOTlNQTVBhZ2VGb3JtYXSGkoSEhAZOU0Rh + dGEAlJeBHa2EB1s3NTk3Y108P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYt + OCI/Pgo8IURPQ1RZUEUgcGxpc3QgUFVCTElDICItLy9BcHBsZSBDb21wdXRlci8vRFRE + IFBMSVNUIDEuMC8vRU4iICJodHRwOi8vd3d3LmFwcGxlLmNvbS9EVERzL1Byb3BlcnR5 + TGlzdC0xLjAuZHRkIj4KPHBsaXN0IHZlcnNpb249IjEuMCI+CjxkaWN0PgoJPGtleT5j + b20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTUhvcml6b250YWxSZXM8L2tleT4KCTxk + aWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJ + PHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJPGtleT5j + b20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJ + PGRpY3Q+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNSG9yaXpv + bnRhbFJlczwva2V5PgoJCQkJPHJlYWw+NzI8L3JlYWw+CgkJCQk8a2V5PmNvbS5hcHBs + ZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJCQk8c3RyaW5nPmNvbS5hcHBsZS5w + cmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRp + Y2tldC5tb2REYXRlPC9rZXk+CgkJCQk8ZGF0ZT4yMDAzLTAxLTI0VDE2OjI4OjU0Wjwv + ZGF0ZT4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tl + eT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCTwvZGljdD4KCQk8L2FycmF5PgoJ + PC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0 + aW9uPC9rZXk+Cgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3Jl + YXRvcjwva2V5PgoJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3Ry + aW5nPgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4K + CQk8YXJyYXk+CgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZv + cm1hdC5QTU9yaWVudGF0aW9uPC9rZXk+CgkJCQk8aW50ZWdlcj4xPC9pbnRlZ2VyPgoJ + CQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVudDwva2V5PgoJCQkJPHN0 + cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJCQk8a2V5PmNv + bS5hcHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJPGRhdGU+MjAwMy0w + MS0yNFQxNjoyODo1NFo8L2RhdGU+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNr + ZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQk8L2Rp + Y3Q+CgkJPC9hcnJheT4KCTwvZGljdD4KCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VG + b3JtYXQuUE1TY2FsaW5nPC9rZXk+Cgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmlu + dC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5n + bWFuYWdlcjwvc3RyaW5nPgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVt + QXJyYXk8L2tleT4KCQk8YXJyYXk+CgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUu + cHJpbnQuUGFnZUZvcm1hdC5QTVNjYWxpbmc8L2tleT4KCQkJCTxyZWFsPjE8L3JlYWw+ + CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJCQk8 + c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJCTxrZXk+ + Y29tLmFwcGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQk8ZGF0ZT4yMDAz + LTAxLTI0VDE2OjI4OjU0WjwvZGF0ZT4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRp + Y2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCTwv + ZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuUGFn + ZUZvcm1hdC5QTVZlcnRpY2FsUmVzPC9rZXk+Cgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBs + ZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc+Y29tLmFwcGxlLnBy + aW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tl + dC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk+CgkJCTxkaWN0PgoJCQkJPGtleT5jb20u + YXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTVZlcnRpY2FsUmVzPC9rZXk+CgkJCQk8cmVh + bD43MjwvcmVhbD4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jbGllbnQ8 + L2tleT4KCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5n + PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lm1vZERhdGU8L2tleT4KCQkJ + CTxkYXRlPjIwMDMtMDEtMjRUMTY6Mjg6NTRaPC9kYXRlPgoJCQkJPGtleT5jb20uYXBw + bGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI+MDwvaW50 + ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk+Cgk8L2RpY3Q+Cgk8a2V5PmNvbS5hcHBs + ZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxTY2FsaW5nPC9rZXk+Cgk8ZGljdD4K + CQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJp + bmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCTxrZXk+Y29tLmFw + cGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk+CgkJCTxkaWN0 + PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTVZlcnRpY2FsU2Nh + bGluZzwva2V5PgoJCQkJPHJlYWw+MTwvcmVhbD4KCQkJCTxrZXk+Y29tLmFwcGxlLnBy + aW50LnRpY2tldC5jbGllbnQ8L2tleT4KCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50 + aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0 + Lm1vZERhdGU8L2tleT4KCQkJCTxkYXRlPjIwMDMtMDEtMjRUMTY6Mjg6NTRaPC9kYXRl + PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJ + CQkJPGludGVnZXI+MDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk+Cgk8L2Rp + Y3Q+Cgk8a2V5PmNvbS5hcHBsZS5wcmludC5zdWJUaWNrZXQucGFwZXJfaW5mb190aWNr + ZXQ8L2tleT4KCTxkaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQu + UE1BZGp1c3RlZFBhZ2VSZWN0PC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29tLmFwcGxl + LnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Y29tLmFwcGxlLnBy + aW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNr + ZXQuaXRlbUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+ + Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1BZGp1c3RlZFBhZ2VSZWN0PC9rZXk+ + CgkJCQkJPGFycmF5PgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw+CgkJCQkJCTxyZWFsPjAu + MDwvcmVhbD4KCQkJCQkJPHJlYWw+NzM0PC9yZWFsPgoJCQkJCQk8cmVhbD41NzY8L3Jl + YWw+CgkJCQkJPC9hcnJheT4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQu + Y2xpZW50PC9rZXk+CgkJCQkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2Vy + PC9zdHJpbmc+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lm1vZERhdGU8 + L2tleT4KCQkJCQk8ZGF0ZT4yMDA1LTAyLTE4VDE3OjU4OjA1WjwvZGF0ZT4KCQkJCQk8 + a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQkJPGlu + dGVnZXI+MDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q+ + CgkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTUFkanVzdGVkUGFwZXJS + ZWN0PC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5j + cmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwv + c3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9r + ZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50 + LlBhZ2VGb3JtYXQuUE1BZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCQkJCTxhcnJheT4K + CQkJCQkJPHJlYWw+LTE4PC9yZWFsPgoJCQkJCQk8cmVhbD4tMTg8L3JlYWw+CgkJCQkJ + CTxyZWFsPjc3NDwvcmVhbD4KCQkJCQkJPHJlYWw+NTk0PC9yZWFsPgoJCQkJCTwvYXJy + YXk+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVudDwva2V5PgoJ + CQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQkJ + CTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQkJPGRh + dGU+MjAwNS0wMi0xOFQxNzo1ODowNVo8L2RhdGU+CgkJCQkJPGtleT5jb20uYXBwbGUu + cHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVn + ZXI+CgkJCQk8L2RpY3Q+CgkJCTwvYXJyYXk+CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFw + cGxlLnByaW50LlBhcGVySW5mby5QTVBhcGVyTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8 + a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5n + PmNvbS5hcHBsZS5wcmludC5wbS5Qb3N0U2NyaXB0PC9zdHJpbmc+CgkJCTxrZXk+Y29t + LmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJ + PGRpY3Q+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNUGFwZXJO + YW1lPC9rZXk+CgkJCQkJPHN0cmluZz5uYS1sZXR0ZXI8L3N0cmluZz4KCQkJCQk8a2V5 + PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJCQkJPHN0cmluZz5j + b20uYXBwbGUucHJpbnQucG0uUG9zdFNjcmlwdDwvc3RyaW5nPgoJCQkJCTxrZXk+Y29t + LmFwcGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQkJPGRhdGU+MjAwMC0w + Ny0yOFQyMjo1NzowNFo8L2RhdGU+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlj + a2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjE8L2ludGVnZXI+CgkJCQk8 + L2RpY3Q+CgkJCTwvYXJyYXk+CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50 + LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8 + a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5n + PmNvbS5hcHBsZS5wcmludC5wbS5Qb3N0U2NyaXB0PC9zdHJpbmc+CgkJCTxrZXk+Y29t + LmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJ + PGRpY3Q+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1 + c3RlZFBhZ2VSZWN0PC9rZXk+CgkJCQkJPGFycmF5PgoJCQkJCQk8cmVhbD4wLjA8L3Jl + YWw+CgkJCQkJCTxyZWFsPjAuMDwvcmVhbD4KCQkJCQkJPHJlYWw+NzM0PC9yZWFsPgoJ + CQkJCQk8cmVhbD41NzY8L3JlYWw+CgkJCQkJPC9hcnJheT4KCQkJCQk8a2V5PmNvbS5h + cHBsZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJCQkJPHN0cmluZz5jb20uYXBw + bGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJCQkJPGtleT5jb20uYXBwbGUucHJp + bnQudGlja2V0Lm1vZERhdGU8L2tleT4KCQkJCQk8ZGF0ZT4yMDAzLTAxLTI0VDE2OjI4 + OjU0WjwvZGF0ZT4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVG + bGFnPC9rZXk+CgkJCQkJPGludGVnZXI+MDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJ + PC9hcnJheT4KCQk8L2RpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZv + LlBNVW5hZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5h + cHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBs + ZS5wcmludC5wbS5Qb3N0U2NyaXB0PC9zdHJpbmc+CgkJCTxrZXk+Y29tLmFwcGxlLnBy + aW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q+CgkJ + CQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhcGVy + UmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw+LTE4PC9yZWFsPgoJCQkJ + CQk8cmVhbD4tMTg8L3JlYWw+CgkJCQkJCTxyZWFsPjc3NDwvcmVhbD4KCQkJCQkJPHJl + YWw+NTk0PC9yZWFsPgoJCQkJCTwvYXJyYXk+CgkJCQkJPGtleT5jb20uYXBwbGUucHJp + bnQudGlja2V0LmNsaWVudDwva2V5PgoJCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50 + aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tl + dC5tb2REYXRlPC9rZXk+CgkJCQkJPGRhdGU+MjAwMy0wMS0yNFQxNjoyODo1NFo8L2Rh + dGU+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5 + PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCQk8L2RpY3Q+CgkJCTwvYXJyYXk+ + CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhcGVySW5mby5wcGQuUE1Q + YXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlj + a2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUucHJpbnQucG0uUG9z + dFNjcmlwdDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRl + bUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+Y29tLmFw + cGxlLnByaW50LlBhcGVySW5mby5wcGQuUE1QYXBlck5hbWU8L2tleT4KCQkJCQk8c3Ry + aW5nPkxldHRlcjwvc3RyaW5nPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tl + dC5jbGllbnQ8L2tleT4KCQkJCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludC5wbS5Qb3N0 + U2NyaXB0PC9zdHJpbmc+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lm1v + ZERhdGU8L2tleT4KCQkJCQk8ZGF0ZT4yMDAwLTA3LTI4VDIyOjU3OjA0WjwvZGF0ZT4K + CQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJ + CQkJPGludGVnZXI+MTwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8 + L2RpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LkFQSVZlcnNpb248L2tl + eT4KCQk8c3RyaW5nPjAwLjIwPC9zdHJpbmc+CgkJPGtleT5jb20uYXBwbGUucHJpbnQu + dGlja2V0LnByaXZhdGVMb2NrPC9rZXk+CgkJPGZhbHNlLz4KCQk8a2V5PmNvbS5hcHBs + ZS5wcmludC50aWNrZXQudHlwZTwva2V5PgoJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50 + LlBhcGVySW5mb1RpY2tldDwvc3RyaW5nPgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUu + cHJpbnQudGlja2V0LkFQSVZlcnNpb248L2tleT4KCTxzdHJpbmc+MDAuMjA8L3N0cmlu + Zz4KCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5wcml2YXRlTG9jazwva2V5PgoJ + PGZhbHNlLz4KCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC50eXBlPC9rZXk+Cgk8 + c3RyaW5nPmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0VGlja2V0PC9zdHJpbmc+Cjwv + ZGljdD4KPC9wbGlzdD4KhpKEmZkPTlNQcmludEFsbFBhZ2VzhpKgkoSZmQtOU1BhcGVy + TmFtZYaShJmZBkxldHRlcoaShJmZFU5TSG9yaXpvbmFsUGFnaW5hdGlvboaShKGbopcA + hpKEmZkWTlNIb3Jpem9udGFsbHlDZW50ZXJlZIaSppKEmZkJTlNQcmludGVyhpKEhIQJ + TlNQcmludGVyAJSShJmZFGJyb3RoZXItMS5qYXNvbWkuY29thoaShJmZCE5TQ29waWVz + hpKEoZuilwGGkoSZmQ9OU1NjYWxpbmdGYWN0b3KGkoShm4SEAWahAYaShJmZDU5TUmln + aHRNYXJnaW6GkoShm7ihAIaShJmZDk5TQm90dG9tTWFyZ2luhpKEoZu4oQCGkoSZmQxO + U0xlZnRNYXJnaW6GkoShm7ihAIaShJmZC05TVG9wTWFyZ2luhpKEoZu4oQCGkoSZmQpO + U0xhc3RQYWdlhpKEoZuil4J/////hpKEmZkLTlNGaXJzdFBhZ2WGkoShm6KXAYaShJmZ + DU5TT3JpZW50YXRpb26GkoShm6KXAIaGhg== + </data> + <key>ReadOnly</key> + <string>NO</string> + <key>RowAlign</key> + <integer>1</integer> + <key>RowSpacing</key> + <real>36</real> + <key>SheetTitle</key> + <string>Canvas 1</string> + <key>SmartAlignmentGuidesActive</key> + <string>YES</string> + <key>SmartDistanceGuidesActive</key> + <string>YES</string> + <key>UseEntirePage</key> + <true/> + <key>VPages</key> + <integer>1</integer> + <key>WindowInfo</key> + <dict> + <key>CurrentSheet</key> + <string>0</string> + <key>Frame</key> + <string>{{465, 79}, {591, 832}}</string> + <key>ShowRuler</key> + <false/> + <key>ShowStatusBar</key> + <true/> + <key>VisibleRegion</key> + <string>{{0, 0}, {576, 734}}</string> + <key>Zoom</key> + <string>1</string> + </dict> +</dict> +</plist> diff --git a/src/libs/resiprocate/resip/stack/doc/ResipArchitecture.jpg b/src/libs/resiprocate/resip/stack/doc/ResipArchitecture.jpg new file mode 100644 index 00000000..4edcc15d Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ResipArchitecture.jpg differ diff --git a/src/libs/resiprocate/resip/stack/doc/ResipArchitecture.pdf b/src/libs/resiprocate/resip/stack/doc/ResipArchitecture.pdf new file mode 100644 index 00000000..98aacac2 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ResipArchitecture.pdf differ diff --git a/src/libs/resiprocate/resip/stack/doc/ResipArchitecture.png b/src/libs/resiprocate/resip/stack/doc/ResipArchitecture.png new file mode 100644 index 00000000..6cf22a67 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/ResipArchitecture.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/client-invite-state.tif b/src/libs/resiprocate/resip/stack/doc/client-invite-state.tif new file mode 100644 index 00000000..8ab1fa4e Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/client-invite-state.tif differ diff --git a/src/libs/resiprocate/resip/stack/doc/client-invite-tree.tif b/src/libs/resiprocate/resip/stack/doc/client-invite-tree.tif new file mode 100644 index 00000000..e66e1e65 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/client-invite-tree.tif differ diff --git a/src/libs/resiprocate/resip/stack/doc/client-noninvite-state.tif b/src/libs/resiprocate/resip/stack/doc/client-noninvite-state.tif new file mode 100644 index 00000000..33c1bd1f Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/client-noninvite-state.tif differ diff --git a/src/libs/resiprocate/resip/stack/doc/client-noninvite-tree.tif b/src/libs/resiprocate/resip/stack/doc/client-noninvite-tree.tif new file mode 100644 index 00000000..fcf4dd6a Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/client-noninvite-tree.tif differ diff --git a/src/libs/resiprocate/resip/stack/doc/design-overview.xml b/src/libs/resiprocate/resip/stack/doc/design-overview.xml new file mode 100644 index 00000000..f7ed8dbd --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/design-overview.xml @@ -0,0 +1,206 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> + +<!DOCTYPE article PUBLIC '-//OASIS//DTD DocBook XML V4.1.2//EN' +"/usr/share/sgml/docbook/xml-dtd-4.1.2/docbookx.dtd" [ +<!ENTITY jni '<ulink url="http://jasomi.com/">Jasomi Networks Inc.</ulink>'> +<!ENTITY cisco '<ulink url="http://cisco.com/">Cisco Systems Inc.</ulink>'> +<!ENTITY cathay +'<ulink url="http://cathaynetworks.com/">Cathay Networks Inc.</ulink>'> +<!ENTITY vocal 'VOCAL'> +<!ENTITY R3261 '<ulink url="http://www.ietf.org/rfc/rfc3261.txt?number=3261">RFC 3261</ulink>'> +<!ENTITY R3262 '<ulink url="http://www.ietf.org/rfc/rfc3261.txt?number=3262">RFC 3262</ulink>'> +<!ENTITY R3263 '<ulink url="http://www.ietf.org/rfc/rfc3261.txt?number=3263">RFC 3263</ulink>'> +<!ENTITY R3264 '<ulink url="http://www.ietf.org/rfc/rfc3261.txt?number=3264">RFC 3264</ulink>'> +<!ENTITY R3265 '<ulink url="http://www.ietf.org/rfc/rfc3261.txt?number=3265">RFC 3265</ulink>'> +<!ENTITY R2543 '<ulink url="http://www.ietf.org/rfc/rfc2543.txt?number=2543">RFC 2543</ulink>'> +<!ENTITY stack-name "VOCAL SIP2 stack"> +<!ENTITY stack-list '<email>vocal2@cathaynetworks.com</email>'> +]> + +<article> + <articleinfo> + <title>SIP2 Stack Design Document</title> + <pubdate>2002-09-22</pubdate> + <author> + <firstname>David</firstname> + <othername>A.</othername> + <surname>Bryan</surname> + <affiliation> + <orgname>&jni;</orgname> + <email>dbryan@jasomi.com</email> + </affiliation> + </author> + <author> + <firstname>Alan</firstname> + <surname>Hawrylyshen</surname> + <affiliation> + <orgname>&jni;</orgname> + <email>alan@jasomi.com</email> + </affiliation> + </author> + <author> + <firstname>Rohan</firstname> + <surname>Mahy</surname> + <affiliation> + <orgname>&cisco;</orgname> + <email>rohan@cisco.com</email> + </affiliation> + </author> + <author> + <firstname>Cullen</firstname> + <surname>Jennings</surname> + <affiliation> + <orgname>&cisco;</orgname> + <email>fluffy@cisco.com</email> + </affiliation> + </author> + <author> + <firstname>Jason</firstname> + <surname>Fischl</surname> + <affiliation> + <orgname>&cathay;</orgname> + <email>jason@cathaynetworks.com</email> + </affiliation> + </author> + <author> + <firstname>David</firstname> + <surname>Butcher</surname> + <affiliation> + <orgname>&cathay;</orgname> + <email>david.butcher@cathaynetworks.com</email> + </affiliation> + </author> + <author> + <firstname>Derek</firstname> + <surname>MacDonald</surname> + <affiliation> + <orgname>&cathay;</orgname> + <email>Derek.MacDonald@cathaynetworks.com</email> + </affiliation> + </author> + <abstract> + <para> </para> + </abstract> + <revhistory> + <revision> + <revnumber>1.0</revnumber> + <date>2002-09-28</date> + <authorinitials>abh</authorinitials> + <revremark>Initial Porting to DocBook XML format.</revremark> + </revision> + </revhistory> + </articleinfo> + <section id="aboutthisdocument"> + <title>About this Document</title> + + + <section id="feedback"> + <title>Feedback</title> + <para>Comments on this Guide may be directed to the &stack-name; team + mailing list at &stack-list;. + </para> + </section> + + <section id="copyrights"> + <title>Copyrights and Trademarks</title> + <para>Copyright 1999-2002 David Bryan, Cullen Jennings, Alan Hawrylyshen, + Jason Fischl, David Butcher, Derek MacDonald, Rohan Mahy</para> + <para> + <emphasis>License for document goes here.</emphasis> + </para> + </section> + </section> + <section id="information"> + <title>Overall Information / Guiding Principles</title> + <para>The new stack will attempt to be &R3261; compliant in all cases.</para> + <para> + The new stack will attempt as much as possible to delay parsing. Headers + will not be parsed until we need them, and as little of the message will + be parsed as needed to get us to that stage. Headers will simply be + stored as strings until a parse is requested, at which point the actual + contents of that header will be parsed into individual accessible + storage containers. + </para> + </section> + <section> + <title>Design Details</title> + <section> + <title>Preparsing</title> + <para> + The new stack utilizes a pre-parser/parser structure. A preparse pass + splits the message headers out, identifies the message type, and stores + the body, but does not parse the individual components of the + headers. That is left for the later header parser component. This + paradigm is similar to approach taken by Apache. + </para> + </section> + <section> + <title>Receive Section</title> + <para> + Not clear to me what the boundary + between the transport and the pre-parse is ( need to clear that up here + (class breakup). + </para> + <para> + The UDP transport (class name?)UdpTransport receives the data from the + socket, and passes the information to the preprocessor (class + name?).Preparse. This logic is responsible for several early parse + activities. First, this code locates the start line in the message and + decodes it, determining what type of message has been received. The + code looks at each line, and if it finds a CR-LF it assumes that that + line forms a new header. An order oneO(1) algorithm is used to map the + header field name into an enumerated header type for all known header + types. (describe algorithm). The constructors for these HFVs take a + pointer into space owned by the SipMessage class. Unknown header types + are stored as unknown headers, which can be accessed by the string + name of the header later. + </para> + <para> + The body of the headers is passed to the SipMessage class, which adds + it to a list of HeaderFieldValues (HFV). These HeaderFieldValues do + not parse the actual content of the header at the time the message is + received. Instead, they maintain a pointer and a length back into the + message buffers in the SipMessage class that the message was received + into. These HeaderFieldValues are only evaluated at the time the data + within them is requested. + </para> + <para> + When messages are received, it is possible that they will be + fragmented across several messages. Since a header can span a fragment + for the messages, we need to merge the data if the header spans the + boundary of two receives, but want to do minimal copies (we don't want + to coalesce the buffer into a single buffer after all fragments are + received) + </para> + <para> + In this case, the fraction of the message from the start of the + fragmented header to the end of the message is copied into a new buffer, + and the next chunk is read from the transport into that buffer starting + at that point, and when that fragment is parsed, that HFV is generated + with the complete header value in the new message. (see <xref + linkend="transport-chunk"/> below). + </para> + <para> + <figure id="transport-chunk"> + <title>Transport Chunking</title> + <mediaobject> + <imageobject> + <imagedata fileref="chunk-image" format="GIF" align="center"/> + </imageobject> + </mediaobject> + </figure> + </para> + <para> + The actual memory buffer(s) in which the messages live are owned by the + SipMessage class, and do not ownership does not pass to the HFVs. The + SipMessage class needs to keep a list of these headers, and ensure that + they are properly destructed when they are no longer needed. More + information is available on this in the data structures section. + </para> + + + + </section> + </section> +</article> + diff --git a/src/libs/resiprocate/resip/stack/doc/design.css b/src/libs/resiprocate/resip/stack/doc/design.css new file mode 100644 index 00000000..a36e80fe --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/design.css @@ -0,0 +1,29 @@ +BODY, P, DIV, TABLE, TD, TH, INPUT, SELECT, OPTION { + font-family: Trebuchet MS,sans-serif; + font-size: 11px; + background-repeat: repeat-x; + } + +FORM {size: 2px;} +HR {height: 1px; color:#CCCCCC;} + +.background {visibility: hidden; + position: absolute; + top: -600px; + left: -600px; + width: 300px;} + +A {font-family: Trebuchet MS,sans-serif; color: #862612; text-decoration: none;} +A:hover {font-family: Trebuchet MS,sans-serif; color: #957B04 text-decoration: none;} +A:visted {font-family: Trebuchet MS,sans-serif; color: #CC3B12; text-decoration: none;} + +.title {font-family: Trebuchet MS,sans-serif; font-size: 20px; line-height: 17px; text-transform: uppercase;} + +td.sw-tbl { text-align: center; background-color:#ffcc66; } +td.sw-tbl-name, td.sw-tbl-code { font-family: monospace; background-color: #ffcc66;} +th.sw-tbl-release { text-align: center; background-color: #ff9966; font-size: 16pt;} +td.sw-tbl-rel-comments { text-align: center; background-color: #ffddaa; font-size: -1;} +th.sw-tbl-label { background-color: #ffeeaa; font-size: -1; } +td.sw-tbl-dl { background-color: #ffcc66; font-weight: bold; } +th.sw-tbl-section { background-color: #ffaa88; font-weight: bold; } +p.cvs-id { font-size: 8 pt; font-style: italic; font-family: Trebuchet MS,sans-serif; line-height: 9pt;} diff --git a/src/libs/resiprocate/resip/stack/doc/fsm-dot.awk b/src/libs/resiprocate/resip/stack/doc/fsm-dot.awk new file mode 100644 index 00000000..729fa65d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/fsm-dot.awk @@ -0,0 +1,37 @@ +# For making the Preparse FSM diagram +BEGIN { + if ( output == "Preparse.ps" ) + { + doSpecial = 1; + } + printf "digraph pp_fsm {\nsize=\"10,8\"\n"; + if ( doSpecial ) + { + printf "rotate=90\n"; + printf "ratio=0.8\n"; + } + printf "compound=true\nfontsize=18\nfontname=\"Helvetica\"\n"; + printf "node [ fontname=\"Helvetica\" ]\n"; + printf "graph [\nfontsize=8\nfontname=\"Helvetica\"\nlabelfontsize=8\n"; + printf "labelfontname=\"Helvetica\"\n]\n"; + printf "edge\n[\nfontname=\"Helvetica\"\nfontsize=8\n arrowhead=normal\n]\n"; +} + +/^[ ]*AE\(/ { + line = gensub("\/\/.*$","",g); + line = gensub("^[ ]*AE\\(","","g",line); + line = gensub("[\);]","","g",line); + line = gensub("act","","g",line); + + split(line,f,","); + + if (f[3] == "XC") f[3] = "*"; + + if (f[2] != "X") + printf "%s -> %s [ label=\"%s, %s (%s)\"]\n", f[1], f[4], f[3], f[5], f[2]; + else + printf "%s -> %s [ label=\"%s, %s\"]\n", f[1], f[4], f[3], f[5]; +} +END { + print "}"; +}; diff --git a/src/libs/resiprocate/resip/stack/doc/htmlcss.xsl b/src/libs/resiprocate/resip/stack/doc/htmlcss.xsl new file mode 100644 index 00000000..eef4510a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/htmlcss.xsl @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + +<!-- $Revision: 1.1 $ --> + +<!-- + This stylesheet is for converting docs to a single HTML page. + --> + + +<xsl:import href="/usr/share/sgml/docbook/xsl-stylesheets/html/docbook.xsl"/> +<!-- There IS a way to control the chunk output file names ... use it --> + +<xsl:param name="html.stylesheet">design.css</xsl:param> + +<xsl:param name="shade.verbatim" select="1"/> +<xsl:param name="shade.verbatim.style"> + <xsl:attribute name="border">0</xsl:attribute> + <xsl:attribute name="bgcolor">#ffcc80</xsl:attribute> + <xsl:attribute name="width">80%</xsl:attribute> +</xsl:param> + +<xsl:param name="section.autolabel" select="1"/> + +<xsl:param name="formal.title.placement"> + figure after + example after + equation after + table after +</xsl:param> + +<xsl:param name="linenumbering.extension" select="1"/> +<xsl:param name="use.extensions" select="1"/> + +</xsl:stylesheet> +<!-- +Local Variables: *** +mode:XSL *** +End: *** +--> diff --git a/src/libs/resiprocate/resip/stack/doc/oxygenProject.xpr b/src/libs/resiprocate/resip/stack/doc/oxygenProject.xpr new file mode 100644 index 00000000..dcc26d14 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/oxygenProject.xpr @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project> + <meta> + <lastOpenedFiles> + <file focused="true" name="using-dialogUsageManager.xml"/> + </lastOpenedFiles> + </meta> + <projectTree name="oxygenProject.xpr"> + <file name="using-dialogUsageManager.xml"/> + </projectTree> +</project> diff --git a/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo-big.gif b/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo-big.gif new file mode 100644 index 00000000..f4ac105b Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo-big.gif differ diff --git a/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo-small-w.gif b/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo-small-w.gif new file mode 100644 index 00000000..c7104dd1 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo-small-w.gif differ diff --git a/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo-small.gif b/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo-small.gif new file mode 100644 index 00000000..e18e8d2d Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo-small.gif differ diff --git a/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo.ai b/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo.ai new file mode 100644 index 00000000..7ceaa2be --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo.ai @@ -0,0 +1,767 @@ +%PDF-1.4 % +1 0 obj << /Type /Catalog /Pages 2 0 R /Metadata 161 0 R >> endobj 2 0 obj << /Type /Pages /Kids [ 5 0 R ] /Count 1 >> endobj 3 0 obj << /ModDate (D:20040330171904-05'00') /CreationDate (D:20040330164533-05'00') /Producer (Adobe PDF library 5.00) /Creator (Adobe Illustrator 10) >> endobj 5 0 obj << /Type /Page /MediaBox [ 0 0 792 612 ] /Parent 2 0 R /PieceInfo << /Illustrator 61 1 R >> /LastModified (D:20040330171904-05'00') /ArtBox [ 125.30762 135.14844 669.1416 471.87012 ] /Group 153 0 R /TrimBox [ 0 0 792 612 ] /Thumb 154 0 R /Contents 156 0 R /Resources << /Properties << /MC0 97 0 R /MC1 115 0 R >> /ColorSpace << /CS0 111 0 R /CS1 92 0 R /CS2 112 0 R /DefaultRGB 160 0 R >> /Pattern << /P0 129 0 R /P1 137 0 R /P2 145 0 R >> >> >> endobj 6 1 obj << /Length 1144 >> stream +%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 10.0 %%AI8_CreatorVersion: 10.0 %%For: (Jay Batson) (Pingtel Corp.) %%Title: (reSIProcate logo.ai) %%CreationDate: 3/30/04 5:19 PM %%BoundingBox: 125 135 670 472 %%HiResBoundingBox: 125.3076 135.1484 669.1416 471.8701 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 6.0 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %%AI6_ColorSeparationSet: 1 1 (AI6 Default Color Separation Set) %%+ Options: 1 16 0 1 0 1 0 0 0 0 1 1 1 18 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 2 3 4 %%+ PPD: 1 21 0 0 60 45 2 2 1 0 0 1 0 0 0 0 0 0 0 0 0 0 () %AI3_TemplateBox: 396.5 305.5 396.5 305.5 %AI3_TileBox: 31 30 759 582 %AI3_DocumentPreview: None %AI5_ArtSize: 792 612 %AI5_RulerUnits: 0 %AI9_ColorModel: 1 %AI5_ArtFlags: 1 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 5 %AI9_OpenToView: -50 623 1.03 923 667 18 0 1 108 44 0 0 1 1 1 0 %AI5_OpenViewLayers: 77762 %%PageOrigin:31 30 %%AI3_PaperRect:-31 582 761 -30 %%AI3_Margin:31 -30 -31 30 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %%EndComments endstream endobj 61 1 obj << /Private 62 1 R /LastModified (D:20040330171904-05'00') >> endobj 62 1 obj << /CreatorVersion 10 /ContainerVersion 9 /RoundtripVersion 10 /AIMetaData 6 1 R /AIPrivateData1 69 0 R /AIPrivateData2 70 0 R /AIPrivateData3 72 0 R /AIPrivateData4 74 0 R /AIPrivateData5 76 0 R /AIPrivateData6 78 0 R /AIPrivateData7 80 0 R /AIPrivateData8 82 0 R /AIPrivateData9 84 0 R /AIPrivateData10 86 0 R /AIPrivateData11 88 0 R /AIPrivateData12 90 0 R /NumBlock 12 >> endobj 69 0 obj << /Length 8842 >> stream +%%BoundingBox: 125 135 670 472 %%HiResBoundingBox: 125.3076 135.1484 669.1416 471.8701 %AI7_Thumbnail: 128 80 8 %%BeginData: 8410 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD64FF527DFD7EFF27F827FD7DFF27F8F8F8A8FD7BFF27FD04F87D %FD7AFF52FD05F827A8FD78FF27FD06F8277DFD77FF52FD08F852FD76FF27 %FD09F827A8FD74FF52FD0BF87DFD2FFFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8A8A8FFFD1AA87DA8A8A87DA8A8A87DA8A8A87DA87DA87DA87DA87DA87D %A827FD0CF852A8FD2CFFA8FFFD04A87DA87DA8FD047D527D527D527DFD06 %52275227522752FD0A27F827F827F827F827F827F827F827F8F8F827FD17 %F827A8FD2AFFA8FFFD04A87DA87DA8FD047D527D527DFD06522752275227 %52FD0A27F827F827F827F827F827FD24F852FD2AFFA8FFA8FFFD04A87DA8 %7DA8FD047D527D527DFD0652275227522752FD0A27F8272727F827F827F8 %27F827F827F827F827FD1AF827FD28FFA8FFFD06A87DA8FD067D527DFD06 %52275227522752FD0A27F827F827F827F827F827F8F8F827FD23F8A8FD27 %FFA8FFFD06A87DA8FD067D527D527DFD085227522752FD0827F8272727F8 %27F827F827F827F827F8F8F827FD1FF87DFD23FFA8FFA8FFFD04A87DA8FD %067D527D527DFD08522752FD0A27F827F827F827F827F827F8F8F827FD27 %F827A8FD24FFA8FFFD06A87DA8FD067D527D527D527DFD06522752275227 %52FD0A27F827F827F827F827F827F827F827F8F8F827FD1DF8277DFD22FF %A8FFFD04A87DA8FD067D527D527D527DFD0652275227522752FD0627F827 %F827F827F827F827F8F8F827FD2AF827FD22FFA8FFFD04A87DA87DA8FD04 %7D527D527D527DFD0652275227522752FD0A27F827F827F827F827F827F8 %27F827F8F8F827FD22F827A8FD1FFFA8FFFD04A87DA87DA8FD047D527D52 %7DFD0652275227522752FD0A27F827F827F827F827F827FD2FF87DFD1AFF %527DFFFFFFA8FFA8FFFD04A87DA87DA8FD047D527D527DFD065227522752 %2752FD0A27F8272727F827F827F827F827F827F827F827FD24F827FD18FF %7DF8F87DFFFFA8FFFD06A87DA8FD067D527DFD0652275227522752FD0A27 %F827F827F827F827F827F8F8F827FD2AF852FD18FF52F8F8F87DFFFFFFA8 %FFFD06A87DA8FD067D527D527DFD085227522752FD0827F8272727F827F8 %27F827F827F827F8F8F827FD23F827A8FD18FF27FD04F87DA8FFA8FFFD04 %A87DA8FD067D527D527DFD08522752FD0A27F827F827F827F827F827F8F8 %F827FD29F852FD18FFA8FD06F87DFFFFFFA8FFFD06A87DA8FD067D527D52 %7D527DFD0652275227522752FD0A27F827F827F827F827F827F827F827F8 %F8F827FD1DF8A8FD17FFA852FD07F87DFFFFA8FFFD04A87DA8FD067D527D %527D527DFD0652275227522752FD0627F827F827F827F827F827F8F8F827 %FD26F827FD18FFA827FD08F87DFFFFFFA8FFFD04A87DA87DA8FD047D527D %527D527DFD0652275227522752FD0A27F827F827F827F827F827F827F827 %F8F8F827FD1BF8277DFD18FF52FD0AF87DFFFFA8FFFD04A87DA87DA8FD04 %7D527D527DFD0652275227522752FD0A27F827F827F827F827F827FD25F8 %27A8FD18FF27FD0BF87DFFFFFFA8FFA8FFFD04A87DA87DA8FD047D527D52 %7DFD0652275227522752FD0A27F8272727F827F827F827F827F827F827F8 %27FD19F87DFD18FFA8FD0DF87DFFFFA8FFFD06A87DA8FD067D527DFD0652 %275227522752FD0A27F827F827F827F827F827F8F8F827FD1FF8A8FD18FF %7DFD0FF852FD27275227522752275227FD08527D527D52FD087DA87DA87D %27FD0CF852FD18FFA827FD25F827F827F827F827F827F827F8FD08275227 %5227FD08527D527D52FD047DA87DA87DFD04A8FFA8FF27FD0BF87DFD18FF %A827FD19F827F8F8F827F827F827F827F827F827F8272727F8FD08275227 %522752275227FD04527D527D527D52FD067DA87DFD06A8FFA8FFFF52FD09 %F852FD19FF52FD24F827F8F8F827F827F827F827F827F827F8FD08275227 %5227FD08527D527D52FD047DA87DA87DFD04A8FFA8FF27FD08F87DFD19FF %27FD1EF827F8F8F827F827F827F827F827F827F8272727F8FD0827522752 %27FD08527D527D52FD067DA87DFD06A8FFA8FFFF27FD06F827A8FD18FF7D %FD29F827F8F8F827F827F827F827F8FD0C2752275227FD06527D527D52FD %067DA87DFD04A8FFA8FF27FD05F852FD19FF52FD21F827F827F827F827F8 %27F827F827F827F8FD0C2752275227FD08527D527D52FD047DA87DA87DFD %04A8FFA8FFA8FFFF52F8F8F827A8FD18FFA827FD2BF827F8F8F827F827F8 %27F827F8FD08275227522752275227FD04527D527D52FD087DFD06A8FFA8 %FF27F8F852A8FD18FF7DFD26F827F8F8F827F827F827F827F827F827F8FD %0A27522752275227FD06527D527D527D52FD047DA87DA87DFD04A8FFA8FF %FF52F87DFD19FF27FD30F827F827F827F827F827F827F8FD082752275227 %FD08527D527D52FD047DA87DA87DFD04A8FFA8FF27FD1BFF7DFD23F827F8 %F8F827F827F827F827F827F827F8272727F8FD08275227522752275227FD %04527D527D527D52FD067DA87DFD06A8FFA8FFFF5227A8FD1AFFA827FD2A %F827F8F8F827F827F827F827F827F827F8FD082752275227FD08527D527D %52FD047DA87DA87DFD04A8FFA8FF27F8F87DFD1BFF52FD22F827F8F8F827 %F827F827F827F827F827F8272727F8FD082752275227FD08527D527D52FD %067DA87DFD06A8FFA8FFFF27F8F8F852A8FD1AFF7DFD2AF827F8F8F827F8 %27F827F827F8FD0C2752275227FD06527D527D52FD067DA87DFD04A8FFA8 %FF27FD04F827A8FD1BFF52FD1FF827F827F827F827F827F827F827F827F8 %FD0C2752275227FD08527D527D52FD047DA87DA87DFD04A8FFA8FFA8FFFF %52FD06F87DFD1BFF7DFD27F827F8F8F827F827F827F827F8FD0827522752 %2752275227FD04527D527D52FD087DFD06A8FFA8FF27FD07F827FD1BFFA8 %27FD1EF827F8F8F827F827F827F827F827F827F8FD0A27522752275227FD %06527D527D527D52FD047DA87DA87DFD04A8FFA8FFFF52FD09F8A8FD1BFF %52FD26F827F827F827F827F827F827F8FD082752275227FD08527D527D52 %FD047DA87DA87DFD04A8FFA8FF27FD0AF87DFD1BFFA827FD17F827F8F8F8 %27F827F827F827F827F827F8272727F8FD08275227522752275227FD0452 %7D527D527D52FD067DA87DFD06A8FFA8FFFF52FD0BF852A8FD1AFFA852FD %0DF827527DFD0A5227522752275227522752FD1B27522727275227522752 %275227FD0B52FD0DF8277DFD1BFF7DFD0CF87DFFFFFFA8FFFD04A87DA87D %A8FD047D527D527D527DFD0652275227522752FD0A27F827F827F827F827 %F827F827F827F8F8F827FD18F852FD1CFF27FD0AF87DFFFFA8FFFD04A87D %A87DA8FD047D527D527DFD0652275227522752FD0A27F827F827F827F827 %F827FD24F827A8FD1BFF52FD09F87DFFFFFFA8FFA8FFFD04A87DA87DA8FD %047D527D527DFD0652275227522752FD0A27F8272727F827F827F827F827 %F827F827F827FD1BF8A8FD1BFFA827FD07F87DFFFFA8FFFD06A87DA8FD06 %7D527DFD0652275227522752FD0A27F827F827F827F827F827F8F8F827FD %23F852A8FD1AFFA87DFD06F87DFFFFFFA8FFFD06A87DA8FD067D527D527D %FD085227522752FD0827F8272727F827F827F827F827F827F8F8F827FD1F %F827A8FD1BFFA8FD05F87DA8FFA8FFFD04A87DA8FD067D527D527DFD0852 %2752FD0A27F827F827F827F827F827F8F8F827FD28F852FD1CFF27F8F8F8 %7DFFFFFFA8FFFD06A87DA8FD067D527D527D527DFD0652275227522752FD %0A27F827F827F827F827F827F827F827F8F8F827FD1EF827FD1CFF5227F8 %7DFFFFA8FFFD04A87DA8FD067D527D527D527DFD0652275227522752FD06 %27F827F827F827F827F827F8F8F827FD2BF8A8FD1BFFA8277DFFFFFFA8FF %FD04A87DA87DA8FD047D527D527D527DFD0652275227522752FD0A27F827 %F827F827F827F827F827F827F8F8F827FD23F87DFD1CFFA8FFFFA8FFFD04 %A87DA87DA8FD047D527D527DFD0652275227522752FD0A27F827F827F827 %F827F827FD2FF827FD1FFFA8FFA8FFFD04A87DA87DA8FD047D527D527DFD %0652275227522752FD0A27F8272727F827F827F827F827F827F827F827FD %23F8277DFD1EFFA8FFFD06A87DA8FD067D527DFD0652275227522752FD0A %27F827F827F827F827F827F8F8F827FD29F827A8FD20FFA8FFFD06A87DA8 %FD067D527D527DFD085227522752FD0827F8272727F827F827F827F827F8 %27F8F8F827FD23F87DFD1FFFA8FFA8FFFD04A87DA8FD067D527D527DFD08 %522752FD0A27F827F827F827F827F827F8F8F827FD28F827A8FD23FFA8FF %FD06A87DA8FD067D527D527D527DFD0652275227522752FD0A27F827F827 %F827F827F827F827F827F8F8F827FD1CF852FD24FFA8FFFD04A87DA8FD06 %7D527D527D527DFD0652275227522752FD0627F827F827F827F827F827F8 %F8F827FD26F87DFD26FFA8FFFD04A87DA87DA8FD047D527D527D527DFD06 %52275227522752FD0A27F827F827F827F827F827F827F827F8F8F827FD1B %F852FD27FFA8FFFD04A87DA87DA8FD047D527D527DFD0652275227522752 %FD0A27F827F827F827F827F827FD25F87DFD29FFA8FFA8FFFD04A87DA87D %A8FD047D527D527DFD0652275227522752FD0A27F8272727F827F827F827 %F827F827F827F827FD18F827A8FD29FFA8FFFD06A87DA8FD067D527DFD06 %52275227522752FD0A27F827F827F827F827F827F8F8F827FD1EF852FD71 %FF52FD0BF827A8FD72FF27FD0AF852A8FD73FF52FD09F87DFD75FF27FD07 %F827FD77FF27FD06F852FD78FF27FD04F827A8FD79FF52F8F8F852FD7BFF %27F8F8A8FD7CFF5227FD7EFF7DFD1AFFFF %%EndData endstream endobj 70 0 obj << /Filter [ /FlateDecode ] /Length 71 0 R >> stream +Hn0`EL]4a'(P+Y2dj%IQ(pI.əg<yqkwngJjͷͅZy\>?m7Tuz}&)4*.mnX.G-=,ۧL^-Vn)qv6eVj<vr_拳a +F?Xr2йzyu1?ZIm3郒.<{:l3*xj8.:}ڣŠ4jK3Ꞟry՗J\[.?r96dbať7Ut-慁iߔסu麻_cr[Ӹ7<c( :CYw?/r +?gd_Tĝ<^ONcŠsMvZ#t^aRKdxji>tK gs?ˤU[bS+j\fѤg;[vXt?_wU Vl72!7kjjM).ow=n-750w[ze,{~KG.V?3씱Rϔ9~x-`s#R= BfqX]ְ۫c>o/Qò{:yw%}Y6^,N>I+fm*zd'lOGeJk7:>VNUҩ3qs4o!r* +*\P*U 6"@dCAGB5(cƙxL +SԦ1UV[c o6lm)ueλ]JW WƵ4̠˲gʳ"+:k6k1)wJ%T7mPF< xyp*1䡀P:4PUԑm,bb9%T:6"6%*׹aAxR%bPjIo(taXX)qTJU Ej&jIHr$l"0Q<|_#zT/TO%; +$Wm-rKj57AK g 0&&X{�]x"G^z|!C* +`1ш#9{.ILD`ك)F6PbT3E&J�E*fvGP #p8(<� Qf)Aߡ=~T"_GS5<Soh`%4C_a$%*`e{T*R>=Vz+6R€U;BEH%<CV%( Z٘cׁe.B+KYOpڋ=^)Jⵟ1 ȀbdlWS�1i9p"D$ʿ <TEd6*a2,ZdFQ2Dޥ&|xc8~|~;(z>zSpɹ郆�gVc (VD%q j,}B"rB8vȑ.3kLjNl;CnnK>DNtvC!Bxv*ODJjfԆeY|@3ǯЧ џ^CizˌA/`m` +GA*f`PT6 &Rak +qmsXA7 +k0 +(\`>[솮v*[Q2bC=U[iq8mQ($㼅`*jFs0tNh`+$x˭(s@eu|,yxc3H3'Ʉ|\+G3*җD"՜J9"'QEt:#;eA~-�13*2�LgPc;%JV8%Q� E0t_b4)z) y6Ar0tw,O5lRSLçEL9U|^py| T8橖H1ÅQO* +e'/Brw`};X/`9yr[n'fR|WT,#3%s;܈oS> :fvį~J*kqR\ff~VTQvjXm{Qh+B~#Ŷר/Z19d:kX3^+[ W/F|ﲂ/^~xUOv)ӥ+ zŗ5+��эӕJ�9p+D-+WЮ�9"B@l#JpQ#p 4X!0p +?5U-!/Ѝ-YAk1B]ˎN(m HSpJ +(EkG5ZNyaN)ZfUˊѴ*wbd_gaڪ+_%I#G~Az91 � iIeXVlA�4/#hn+<*|=x*"b]q{rVw"܋ԯ5Kc1\?ɤqd.dͥClc`x f&k79grr*oESno#mWjٹ/L*SȲ6,ES"uh*MKwJxY%qpA@k=4CcBS Dt@>-3@0+drB 41%'@zxc[DwA=~=3D0<"yT:0^Eë n |M#~+|{m{حmYے6rvRn<bgOֽF4mIR%FљyOg%fKLʍ2t*O +ĈO<{ܚT#iL?Oh$# +s*Sl4W&|t4UUQ7)ԲeV9v_ZjUb5 IŻ䪦?/3>Eʻ-FoqcoochML3"o2#/fJVѷ=g ÜIQI2I,:PRڋҖt ImjDŽT##dEV];$_"S/Kgo -Pps~BU+�0jot`;BS}oN;Z֟B4+,QwI +ppN[Kґdԇ00}87ZҦ\*UReb%N ]u/>6W*^2`ΥZZdC%SM`I}5ak36َ}v`۵EN/&]B|ag¼OB-4kur0PO|iN0J9&,lO R;Vzrx5V8..MR̥N>vK ܻncLxg Z*` Y`nP4MBc9+,lǰ 5CcGX,EGYhOȞ +'VOS*@=a ':Y5 B|~==~uw{X}vl8ظjT4DflKaL#G.ggxO].?)=)n2E*g[�&7tWl\Ufƒɭ;?b 4KټStۯur6?$i@8" 6I#anqljIYzC/]?;P?ro+@ _X:+ʮ쥌{=sss.mVC>E|, +xVvYV$a,bL'ፐ el'DB#$ax xOyHuTzH^lud?2V834.Eٍs(]ͥ\*$cT.Ca2SZOW,S�Hr CzfT1EQbmBBg\/|?j +VҥI0 d' #8 EDp.A' ݡV+r1qZIfgߺ" b n[o=&ZeBW٧w(Rm~^A{;H79Vt3L Et9p%!L�u>a^^J\NXo +kh2$^魦𾢨JS1S**h:qXXʶkaX䊘B䋖!PN@Ux3/-M_0-7ѤdXmkSdbJDPaTQRMUeMEatf,Nݬa(U?Kwcܘ9i9F!% Rj`!۫7, # +*Fpl I[Gð0J g?'VQQ#)V³+iF($8ax5&sP ;>aA!�Le d b*'xwJ{D鬀VClVr csuÆea$'qejy8;) +&+n2:Pж ))IIJC3chwY\hFʡ¤ 1ת2zX\GӓV6{uuK7tUwtQ~n%wd!8Dtzmeʛ˸aWwkp;h~FE3(Y4C㦁9u=IK�xi(322A@Z'\+\/r yrCt |Ѭ1`h'xa<ծgIzxI׿~v㬻Mg1w6U}]uT.ږ[wox߯]ܭ ĤwU⧽c%$~ޯӲ8i*Kz]]g9aRE4"FU=hil/^_;iM1C I[vPoJKMpWYYY[]'+iD { ycJN;֛Ed!735l)zhQPO)o%_Iba%aDb MeWO,[Ѿul甍 `102;a .G*vD=ԸiJz{6KUFoww +4)qJJc JʦtdGXphlzנ JrYwQ ePNj f^zԙusA/&e}n2F&HܺX꡽mF\q]Oo8ޫ''.ݜZhPkof;iR륻2jr2Fg(-AU +Ƃ|`hiZ(p{9IX0?0-Ƒ15gc-  m1kyE =p3, �HĪ e8J!|*p &`(#5_\Km~u?댉>_/CodGr +~/ؗD1Q1f` YYյts0%eR#_,mr?oYa|J<=/:No`a''~#('QY=΍<)}8_I1[O</~{_2:h6nNuɷ٘2zV2Kn]z\_^|ٸo_Ǘ__~ۗ?>i4^*|*~2`aL ;a*w0sfda>< a<aJ7 +K\v Dm6&AV|%Q6 .C:]z qB̗/hB5f4WbQDZ*W^%gݰYqgK=`_-z8H&gѬ(xZa0[C<FwRClEgTΕF[.*|';巼ڗ$N .jEsm34橣yI-yi>biSOm<x'4Ή~'⍝)4 \;Dd<UD+Gޱu :|:@mW:;c(+rGBX:z`5<;$:,{:& ,&_߀gyx|+.djb'+ RQ[ER4'' Xj 93Q[Qѳ!CoJFhC輬 Yړ pe? H\l VI6`w%FPI:]@B* jɞYnx]&PqLj +Xl'Ѓ 3y�Z_ܯgAwBvUL'˻u*-WB +s$eE;1?f_\p|eN5xBAHM(~S_Պ^/TIJҲA6\BV"RWAyP-F'O/Ck1/Q3U7:Q>AEJMQm9Sdu22L?O!tRahF: {2Eg2F'Q "„43#@ +AR0JN ZTSgn59=;嚞<el$ΕD&IɒRY&]Hrg,`\ex sg<pݭԓz#>5+ɠBQT(&FF'GG'MNI&j#-n@sa 8`e`ju #p3nͦ:7gCESgkֆ=s}Wq뻹ZKY㷊~5SB݆T|owZT,C DgÚ՞Yd`eWΗ +\7I%K|Es1',.-"r` @"A";JFܱ7 XA�="hICnxĪ98p2Wps'WV=U<rT[Tgy&s}|0,o@x SiW k!Mq"OPaԢhk&U>`'E,血NJP} 2a! #@Bd!3''JuB4eHTAgFW;NgGfHӍcj9o$hT4sEUh`RKyeO2%9zR^"m4B' aD01ee2!x"T$ƕr L -lat<3aה]]Wiԙ36yF\'&k5ĚgS$[7 Vz[fFAAg[J nKݎp54ؾ:1Owf1Z|n6ڛ[2= 8+ +5_vE5 !-ѨţhTZ8~q +n`Ё@_{uZQx1(yt^1~sF vtwyܽO9ˀ<deZ5V]n�W7{ S[orxI[zpI2Z|,{9b +NKDt/e XP;4md8݉avgP]F#l93JL72p3 9g7u+iC$uB7덹'C#C}f: SPf +X qe!a&"Lg4 u0 ŠHH +$ ײKv&x& 3Fa"L5r',Q*L[,3 õ+دl`z®!:Έh؂,"!+3ud9L*ӫXWaBը2 ظ6+++|Wf64]^9#BSHD.EB +K^JT)4}9qE+ai=WU\A7dwZV""-91n4ڵDuE`m>p^p3t<b�? }2be6`p\0dZe`>/0CҀ<`P.ep^Ӏyݍ5oxqHp{gzx5wLOm�s=s>ևOI0O_.?|SY^7)xWH_R܄Xex'4 DWWWeWDW$W7&OתPViaYUQUOUKUIEGEEECEAE?E==)iTTJIQI U"H8 OȄPsp7̓Pk[5/[w^.=rV 4H *@ϹQ[*<$ѳR/Uw/C T:9�-!:7/W.c)ieX onR;**(xn4hٕ@jUݲh{Ȫ;n,ѱV6b ԓeH*S#9bcO�|C-[`֞ a`q ppdQ KF`8#l'|&+ڰ,݀=9t#*²&P۰>dj`$ 0a{+ &3 a`3 sE">4L=L5\Lv^0ݖ'�)sI0H�3t֣RotB;~vYmL|݀v<6a%Ma^?PRd;7)Xh<EAnd(oQ<8v}x>;`؋mg=zA6y={)p+Oa!A6ȼ0{w4Ln̟'_S0'bs?&S{o3Q;Gy~o?_>|>׷?~>˿. c] 1HĭmhB#׳o( ]aBaOxBhL0IFJI\PkfT '"+'�>Uג+)f[˝\m7]HFEES=ձr ˡݓp|u~ד|,Q)E:.)R݋oUhڼ#RP7UYꎣ^c[:JXM̮o"+5T:qI^ډigJM*9= ( *9JH*$*B+T%\VBWWBXX9 `<[+KTL\#FڮRMG۸j{U Vt_T~vL͌))pȫVGWp-•j/Duw/PG$+ef +\ՙf?hry1K[k,hMP젤IzE&Uڦ4IJ"I,FI$}Rj$^vy)nue{nnѲs$8w?{mlT<t<}n뱭R47nO +a#,i糢*RJ跲Ƣ}n4b%)pRpj rZ8r/R񶠉WnJQյfuY*ٕ3$90P9DsJ@,<00W}Gˆ'�*¡+It*$:'ytAGA 08aup&FrG.5ҍd:c #'hMtzֲzv+ڙiE,EƢR4dVZ5Uݹrξen? +'+bX9u/46gCg KdV@0sTbQW2պ5By,G5ϢMxQR,Hڈ梩(3P' rP8 m#K!  , I%9jKlȞNZN/ B^#D\]lR$fS/9 bD'JH0W_\ &%2c5_{nƜ=3e H-0A',Kv)߆[0]*ƺXy\%皽(WF+3ٚE#*}bOa>rQnO\Z{Yؤ̲iJўXm-PTo* +5{GUZ᯦[U + cљ8H'Kz<t:5]+z@}湍͡dcijc[+4Wjw5:s%}֠J{ujwVS+dT$&IfInDVY'LoLpI|Q-YjQ"gaͅ{kk$~#$~#$^9B7OrqOz4pwtcvtlC^]]:РК7k2|:>̝;#Q(0Y,_0j.~T%2+#$1QqʑڣUU"Pn�+qc%V6jט#x) .PsC3&_WglUռRȸO 5<ΐ^YkV*.,[L3o݂Uf$$fŲ2M]Rb1__bQ0hEBmd|!2׾Uv2_z桦] Oڥom? o:e�R +z?7dTǽ&]GYi*yxdIPHO4)Mpim˼"syHÇ4q`ΎXՙW SrdR&�4ga|> 8W8k"C։`p[>pG"nYϰ&T]K�xRHлv;TU=G" +7ooTndod.ҽTi_7ntWE}ݑ.gR/7rWiQ ׻vlc4Mm:MuڛlXU:өv56:P?X:<WG5uMi\LCEv\ZM"S,l˟~zHbS=4.RV^:4X3>lZƾS?m>)sȀ4 0n/0 ]/ɳmq6(K 7X7 >t:=D|:_5t~x>{ N8  t9RWnCo$DdCJb:YL/?r$EnqY]vUU8D(O|_snq|o/o/?_K2/ + yFn<䙝lI a7favͪ5jNՔZ3*jɧNX% I,#a0htITRЁQ&1x/^4Hpal_Ef1`g ,WV`%HLh)!E#J -8$K6$Z6�J7h&Io6qh77n.x<cG''? 2} >|yAG-K|G-K|Z|�`  f Qna�U kN[4ůB\05@@Ny рkChX:079Ws=p {`Bz t}^8ח8_ WKKkȊɒɢ-MNWnY sY|+󊆘`G.\Ҕ+]ʵ!ILL$<\?6sGXY!@IĺTR3t +&p0%{.`wo;`ge�U +Qf,~\аaC.\Ƀ8Ђ<zA{(ς֔`ц,xB3;+(T&Q:%'$ˠ7g ߠr$5xBR13æwsGnm*s^Z) JA.\BV"RWAyP-Eo/Gk6/Q3U7:Q>AEJMQ]9Rv22dg!h*!(S+ahDʆhLE v1YfthfBIIr $i &$1%f䘛lINGNkIOvr6g$/IRnf¹ I hDLÌ9J3\w+i3zB˜t4iO͟;J2P0jS-1mGT[MbQOw0 8F tb7I (Թb sv�]Q qG{ywW,UšٷӬ4jN9+?ww,PZ_7Kk#X3!8"3!QM+RKe df|<p=|`A2:/2{DD*90 41KX@BCbU8ЄNj"<RCG!ˁ|1 "E3>Ay<G<(KΛ5P!2Wȯ!&b|{2�p +SyY1s+8B/6As<b'da@leXᡷ Xl<@-h.ylTrG%?`Hx̐9 H[-mʬ&3<)`}#Dk61� ;v>2%hܳЀS;QGfM8$2ZD%Q6w{d]Ku$@NK4Ef1,`e}2u' +.@|`&FnҮz]/w\ڵ]gΖlQI-Ѱqc`m6Oۧ 0QVik5Eךfcڒk4+q}΁+yEٶ&_ڣ#-ǹ=Nqj'Shq| <጗g lq{/u躌[F<O Ӯh5 +mNr,Gyf"%!H�ǥd'ķ`g r 2a-%1|tSݻsrLn7EW[z!_O1 P.ݓSB2'_w7{ՓfRs XFpbvLKح0 $!LE0G 3#08Iw`V#|3ka<rsN`qI1Cdw#I2!v=6`BȹOvjX|p`IC2LDL, H3 eH0;R `MfI ƕt$Ʀ�KaDgazvF`< {dAvro0OjrjѲteH bl5ЁAk ۯKB,Ʈݔ2{D*hf+&c (Ud׳8S?܉ڗbeblTzX~T@wFG%sp<0t_2 +KZ.{VʧVC'3+#AՏ X/˽N +Oh>AJÖF2:#+CӡQ"z!nԳXazg.`?N|:l8FL<t; h/X:C2sj.; 7\@heJ/I˾s^53\ܶk0Sܻ~?|i-׷j�8a`ퟩ,EbY4A~&UO)B2uM"""*"""Kpڑ:*++ + }-* +e5VVU*8ZUjZTTtTTT4TTSa!"SMLQLKU˕J):)*)K$t@(s +W1{`ϯ--=RX5!enN.jη.m/U>כ� Cz7]RQ +s p0%]<Ex S"5?S-%Q7QQ +HAx -RD2GTf6XehÚ.!G @ `'$ص #bk8_.#Gm7LI/ ixmx`n f^DDE%xU$qѣ!J2#D;&!8٩HxyJLHHhxQ%UEF$oFV9Lb!UDrD,g"J<! A-kE`Gvvu(HOBnD逈G<T[Xp_p~=$ZW'B}🆚";}苼i`!=t?`)r?~׹ӿwyva(r0_zw|W,'TPN7|Iz*"0 Cj䬐{vQitןwh|4Rt]Z;ue|vGj,2p^}^jyoZ_O?v`/_Cz߿~_>?=?>0}ST1|LST1|LSqh#0+jȢ8Hj{%>㔮{<hP);&]y,kzAri + ЍE7Uxtc +.)L)fO(㔱Jx%2n_qXD+lU ' l[}iChT$Srf% @x*1x\\=d:k/.{oc@{s?29|Kr>g*-~6)7EV}I3_n(zVR0|{e_XqR +sxs<}l67Y_3n}6<? s9Yt1j-ZmmdkҔ .r~ w^WK  7ULDDmǂ7MDw,q$i 5gsӋ_@6Lq&r4{3cK .7HiLj3zncNxy#؍ؼ` +d>+8 FD%PE"`t VsGH%I"w(gY/1f ĚL{nAa'eQ$"b#2-�5zUv(XMVbHf>]UCYx__F^>i;A5hb.!*,/hOnBgLvAs#X^ҢLl|;&]l4iZiV4X6l&wUGiwml78}Æ I{2 +uc]Z/7gi7Mp* E!*:&'a6&6<~LϪv88o|A9?:qpxt|r]HpBwO(' & _Iѵ؝~?,yz79{2 Ϙ G2\9ȾL :w'Jay]Cow7JY3vާ.=P|~ܝ<zoaG,Б{0h/%zBj6(XT3D"(S+*kZ+vʏju8GuU|wS_hHzrn4\{u)O:M0U8bfbfwtO >Ny7_ThXalaμϢ;,̷CB;^Mtlo+;2fzy[DLDBWZ~g$|-[!C%(DJe3kUO6`QKFUHInk[ue6N,Ӧդ>QO*03l^Ǎ`wĦOAl77}CJ ".d$'PD YldzQ]ثw*ݠUT 7؝^^ML]V7!fFc1 JQ}Eeլar#ϲm!$@t\n斒¢FhXi:5cH4$zH:h{w:훞fI4JEMC6#=]1A;`e;#  -<icE >QM˛q]6_^:MgӒD-=g򗽿>{EELW_p gE7T ^+$ls<^*zYJqx*DK92&bʀbTM^2KNl`ɵhuT{>$t StB$\ҙ-&٬Ag@b{6#:cC4kB >R&0Z.h5 %4E $zLQ FFIQfof@ِE҈Tt.(GVtgF}FMN=jy;}\(`8!" 6>ش`s~ 裳قv 8dJ +'Bd<dIgXE%iIج*mQlYűڗIIG KYG_yEf~)T` =O|^JVȪ.Ċe3ǖ9'}~<zXIY{IsYkyI;h7Y^Q$x ׎t}#]3j./-{XHmfh4B,I ; riY$txiy{Ѽ-Y,qkQv-N0{ɗ^n.> l*<O}0~)^+7{]PIԠ1pdFHGV•X5 m6amឞ0`x5~k8mLra(zMx.!z|RQEyR|LP &0J>e2H �z to6u+X &0h$@ H �bNV +eyS M 0fN;Kw%uZb*bld#7.Q .r(oC9>%'7[7ETD^G)$*NM6K5"Iw:]Eg R5ҙM/nCvF\Sm+#(W^ m^ � endstream endobj 71 0 obj 17701 endobj 72 0 obj << /Filter [ /FlateDecode ] /Length 73 0 R >> stream +HWn6H.IRsS6{?Rl3<㵽-v4]t eYN^Zgqb'Qqoo +{R'#NV$|zU;IoEck:q{R}g )]|o\卮wuMs?p/3݅?Cy~/O qO=?_:I3]ǚS|WFXNxD bx["4U:eQ&Y䦄JEieժ*ʤ(TU/f˺aKZRM -ҋhW�: ad,2X`5&�$ lfxMױw[kW@+(VWJX~,G柙ٱI8uf V hY:- TF62ˎʃc&"wW`hk� ٜp)v-+gPC2TY +W |[+\ڱUlЦ+6-NHglW~/,w› _iPNP 2Ư[ߞk�h] s+`^QT'zUzyUy8^,uE_Q~,-PO* }iMAu*(9cgG&de(II9SH>)r ++(W9c>bϘUQZB)Ţ-dPi'};  ^]r#$=vK؃a[ZlPҭž{{uoX%k-M^ M+yE1}Es3hs ڝfPf%4?MX' fA{̇ '=6@|*4!&j:܄um�K支 ^a|#_; rlEaFE"CSgvWvv.ت j<Gi=cAZ +|3^ҕ˥ILX`&5ʢаEB7jk}MtN"}m5 Ah$Œ=žD<d|r)$tov;gI7 3681gIcn26L^a"hh=[ܵ&>9_/{ g!pp5,玖@Mhc#*lFtvGg֧+VGRbplUb^*qj^m~ VwdYr@ TTUǜ*~pd!:Χ-ιRdRXLdXGEh +v +0*ȓ`b:X\%X^z,P +5,,2,BBqri7 {u�M ذkزE{p0�N0¡y8%oGaQܶU<\�{*uZAYz3J/4|S  <{s Ӝ$cN r/(0͜{Lԓ>F: D| gpCc,SsA}x 2)!9�(Škv0#VE䬑9wM#yC-c-1<6&.iD 4ҸԦW&%ٱI꼴̞ +xa)4Z@ +qnþAMb&Wn{w2i0K vGlMOskͯȽlt&Lm1S[vmȷȏIrNBm #4-^>j=o�@"_WKP Z'z֫ҫΫʫơ.-YlrQMr8,AC#Yc- V  b а;(Iw'L8E?x9 |*4Le[,ڒFUDd[{ZlR^mp p\ t7imҭž{{uoX%k-M^pJ~ڏSNN-`t}]N%($19!je9̙'} hyl8ޙlul+B\Y:kGvpnv1YO}.ݜwa}9f)4/Qtk *ӓaIulal"2>sٔP7]гk ֘31e7ҿp&fg4M{͠]kÙn)cvޣpD@Ùw/g ˹%s`؈ +:(ݨ٧ +ՑTW WV^+Vjqת)^`uG}i%ԘNEYu̩G[,}k=74O1v7)AdG=%'NgcQpv=mյ4�0EoJw;zdLDmn, ;~l?=.A4'! +Ll39t GC'q_<NzZjq/G$>NFÇB1aɡ9O/NJݲ{][x[EZwZ}|;W}b O_k//z~stR?ӵZusMswS.Gc˨ۆ6#/OԻͽK H.jchw}m#+޲N]1#{~BJۋHb,Ys&{-;?֫eGr~/ x/z>>X`=LRR=zf[ zj$ OSZ%HZ@ɀ& Hpm!"voH#�f!+! ^$j*JX5ʶv접pJ#s!U>#+MF, z<n(4 HdzbLLR$%+]U=VDH5AT֏uPR#g7哨z +ۇs59 4>;BCvu;Ffݨ܃iWڠ[ٖK9q&_СԢ:d֤^nN5祮K%jV5(zsYr JlFPp +ހ(z rAΨ[*8CuP21u^/x4n:n&h،@=dG(^+DŽ25 ӋḄ{3Ag] 3 ++FH YMj@0IT"U1+89 Z E&*= B$FC!6/[/muǝvN'de{]1Vdehڈ0äcwŊ7cN#b| =<" �3f1a=&m@K41F0G@ɠ[:Jowu{-lȝw( D,dDѸ!`< 2:|CEӇzpQ}մa,h6NNt!F�®0WCI(^4]lvIx5A:cF? Sw$P?bHJ#:P"'<ba!Bą( @"2Tf0Fg(PkPQjGUIRZLi21mbhZed &T@808'L㔟Q]olAuNd<H~ԐHQ4^a*↶au$C. p雺 e CSg)W]85xܰ% ѨbvƎ*#˪4:4Hs&v+tk]js4`g1�; \Z9\M nb4 ҈[x#�|9գ*pQ)BjBg +Ù!Pa5jfκܪBv,ws*A)jժQS6ߤ?:Rv( +1fR�-ݙDrޑH SP{UUV@ `0 +4VSYUg)U&1۴\SZ^yۘ[ +J4:tg.?o%Jw?FhtFau/J!K*\#@*{S�s~.)bw" r>,[6#qK (i:;#=[8y)p)rV۽<4`f#B=v,[rb4+/e.w<\b7w@ ]\JX aTm`FtP [`6ߘ.-Bz>G>r߹_wp!u +z<{2=2dF#л~磧|?+'-ܬg( &ڳÎ8*zU*P۞5=x<WrOZί-U:}|PenV`o;:c, o7[A{z#X00f�6yW1 +=:[zZ8�({ +vTfL;Q9-Pbe(JL--/Ð>Jn1%^Q{ +U么y0q| V1._G.jR1SO67gX-6pGAW½veh& +ԃg89[3:ebO"JPk(FC8Czl[({<\ɛUaBgM,7aQW+ˊ ȯ{4/} x7\|?2E\.L )g�&14}:Y_x\ebȿz Fy{N?cĄK:\;Gty7iPP~6i?4~w^O߿O{o7O?߾omʂ.Nn ȋ *O#J 貁 Cg9eF84;q0+.Fvң#r�fRl.$Mx5{t] c'G?Wbۋ^)<\CNH(y'lT^]ޠ6.*z o,苁gVMSj}t8+\L咭D5_q%cΒZƔ9-<܅;_9ou?[-I�aiYOYE!!HM@mW9D<fr\J6qȨ|ԔJCKfb*QiE(5윥dG28;Ȏf&\ZfGv%LY+ٜ|H{1C`',CӃ m%!wjKmjil:;5^wiMlEE'` oZZi\ ;C@x(DIS3*H{dU +W;ġi똨lmT&! xo)eYh-V]䈳bv`Z Cy\(xl`y`<¦%]{e++ XiS EX(b2׸7.ZzdD'Ʃ"W>s JL ̍o +*s(<b?vsCSfl^Sf  ʉn zq +_8($zTNq5XkV3'-##!|,M B!23]&fB'恳Q)O Ҁ7 iW-/4ٯq# `_Ha"J_|X{;"d3=^VUUW^̌ [A9Yu^UYmjeZmVdNVؘ2SO*¸r!G=9T.}U@I}Mn*kr9 ƻޒO}po>R-GKxE/L tU=ÇBUBE +0MާoiySɫKë;x`J g$~_̶lO}[&DЊJ:`]<dzxl3[?*.tݫ +mgBDWkR-WY/^ܫ23]m('Kʢ(k} ղEy3n:ծS:ty9v{a7GW_ {5Csq}:0bI~lG:crN.#-.g�F :㱏=i_̳]P)ј=VW,$rO<G2 ;gp>'f O5Uv%%:TrQ\EerAlˌRs\p.yrXu;WkE +CT}WEXVuYhsUV5bNbX/V5cX7VnVX?V5 8AŬdAʲIey,FPreIs[ؽ-9XZr<& +*7 ' |b;!5',b:a<!N7@s8upvh|-Eh|#L`bwavoX`!N0H:>*bIQeOE)\uze+޺a( i~}rEn 32t bBh"jҐU6(%tm5dvwUw J|lwM3fWPiθo>H |h.V+iMv(CASTF%|$ф#TU%uH- :iT[C*nbk`j bC5tXRw"Nצѕ{֐mzN# Xrl۞"=AY\',O1?tyVJTCPLlX״ٶkB(k7{Q*8¼Ug۱X", 1S#-­B< luG ࡬H;'3pǹ;yiNL0x,c0D8d .9 ixGdA=13'۫te-IAmQU 76 788yÙd�2FְeI52Offyrb 0 &blٌWuC/ 00]%7W~뺗ҽg w۸y=_i\.Py<!'r8{ "\zŷ+ÂK9OuJuJo; WJ5/?b_/՟._._J>C~gDerqq nkfX$58l�VڎﲹOxM8`wdXƂ ]28S@x +d:]_ #p;'xWV\$3E! No3%Ad)q"IN$K^{o% &*/Vbr?' 7]M{ e(KU%aYڲU7E3 AOOnϛç;TẃN px>dpouB#Ujw-~D<F0`<]`<sɭ7>ΗymrrE4aڤ}՜=z| |*>Y?zb,N{ 2^l +Wu0nXd8 .O؇Bf$+^"MSk7޺`/OqUxNxo}wP h` ]JB:æ1iwJA7a^ˁ{rEtk d ЉH@I@Mlē,>;0 X{8;=;46z+ AX^ZSMڑ8Z +؁SCZ{A$=W7x~'| A§^#^Ar ĬAٗI4]9g9q9{S +'rA;`sgt9yiڍ%# +mt$i 1H1OADP&bz4'A#v! J8']G_`X0/sPZj %t9ܩH >}W?|/V'VTT- @#"}erXĎCp{;{}Rwji԰Q :.<FTgrA e<8&'n3.41`A.3pPs@Βp-J6Ng |Hx^ UqnY&_]Rf,YPY- ɗk YknXN8o +NYΰ? ?ǗԽ=r ApC>pFӱI#ƶ t_0.2:Ĩ!ExlYnqrLO"C\�8ƨ֡u7tǬ68b'úM)qyAEALh L t2Wmzz=59(΅:l&m2 8 lD߈DL;1݋ᣈΛ(LzfWۊ$~`5y2~26,/ zma}ODf䥧gvf=;KWVFƉ8-ԫl ?/e',V�_Tf<t+`PfwHjb*>ۺ))Ƣö'SL^V^9?3U)NJ +h6R<1-u^Q�RAQ*TK+UY%S-V @x"-m!Fم;/fN!L哵1fIF0cL~*E&PzFfd3nA|1SB (,܏iBᄙ 9rs36Ɇm<ޜ: +9 y NX9ͿrL<$FWJ)є9l2/dEBTdצ+�R`lT0ôu2lT0ga2Fr7Y}MEvEp ,ڪ矗4 zp>jךk6Y'ƖZX?ccsD]Ťrb&#V̶eCRLW&dK6|bH�lVql&NVչms:ҝjSccPL&sɜ53t2{%G%&9 zz%9bfoLF}ovߤi)ʕ1Y-ˑ'uf (`;9f{\ ؋hgأ+ 92 [[s\A#GY(Թb:T QV +C1(;ϊ,ؑrԀrfzdP~w5%;b*&~Tx3|hV6kyE׎<Iy +\?Y(AP9 +bDʱXZQ0GƣHI)YpƒߐPP{Z(&)g1*ɝGH@"*ʻ8 ;2Y<q"DI%$"HDA7P&8_D%䄂m;[D Qa@$ h\C='GdIQȳ# oWdbYQ3Sі\,1y;SR,f*si^-TJZgZ)u&rӚj^7ki� +8AI1 [O}&mp$v8zi>pyisaxuGϧC?=J#y =n$4c#s n AP=u(ψ+V<t7$_#o}3gy-;`U}1.n_׷ҍ[/uX~T%þFZF. 'I2fS +$i+3E$c3xm)-^1J*L)%+{5J\"ܖaiJK1r +2Jb亼xٹ:k?k4UiM +5 IY)dBʷl\hlbASϊSҰ;{UZjv:CWDjExAYu00(AD*,m@;.^U"܁s6, +X=2X&$ sׄ`X&$?ed²Gr +eQ7qYpdU�7U-p,8MNX +7!O>my-/4*)#%+eI̶%bDÔ)'($Ɖ8RXA <hD8 r:„$Z>03dCXDT@u{� i=ݸ0�<徃i j:΁o\P'XD$@T+悚>)dbD +`,@s+b0F�@ .(}v `L(MƉ;ʄD,*`i 4;vE/H pݱ7Vn3Ej6}e4چ=wGFG=mrj!'0Nahlr@1�KD 뎠* x5ǁ.'_I6Ȓ2 g<2Ǣi U턬[#rl@y3,/"y\H> zB1E`(c.f6 hGGiO4SvdB׼ Tit^{o5BHZh]Ug +M?p?~퇷ol?.Շn?>!ګǐ~˜Gd?_/ӿOۿk=7r/ +WGW) ";HrHG&x8Oc pLu#WWpg7yF>*L&/obL.# /3zLFTދ%j|on-ޞ;ɀoh|.&#ÝS|uYFe 2Ʒ~pun͓2oh]ȕʃU׀;ʃzOJpA 22y\qq_*#zD/ { s%úw&[)WdP)ܺ}<SՇ +\ JpIu<ؤ?RRB#Ý%%J�.wKw{~]dT-)ֽuUOƶDuO~ÏMJ{IaA?jK-6ˋtuzs\p]Fȯ3'&Soc%1ÔڄȊt�AWw9xӼW](^}ϓԉ] MH7}tU)jS,_pgW2yY]y`d49KxZ݀E+AWS8#1B;pvctFD�HOip;(C@AM~F';?+i/# `Fi5ج !~v`B +>]eck)!)]Ojd6љhc6I8'N}LlB<�\D-a)`X?8qA Zj3@JޮĈ+CDiBS$9K#7ጊ 11iOGSMr:4Q,+y4pZi%w,0!K!jdfe%vdVL %I+ <J*R!)YMԳQa_Q\n )ɷ&]mݣ<D [T_I=)1`rDfRC?a%VbK/SB1@"،*^&Q1厭$A^}QLb)++>Ŧ&ϕ4I :{IE,΢y֛GEbUN 4|nmO1; b URngQ qnqR8a4N:Q+[ɘ a+ꨙ.3 my `"EJn%nwbTN} n)^bRA!GKv) =fG!ٕ5 ce.L@;x;%fw+&ZDCAe ')"_o_+UniɆ-ܘa]sq3@Bܦyԣ�gI}$jRsW1tusEDpu&دRH;ώϴ0z*O_x\}#h)?W7<x__`WOk?w뫋ǛMsrE~_1|"n8uɵCKm @߮+4}acS,b$PM-[*% -hi +Z*@ 2CK DnDNyl5. V)TY;I%sw�hIJn^�u vfPO)],~OAIh1L-y( uJ#o +l=͘%r]~QezX v+ D7^Ve3cYN1U i)e=zgi΍>gb s)2`JX /jK-SXm:$~D:78kW /SLu[ܴzgO8,XOi__XO}۸[ڽGRqv}zRO'[n`3[f#}4${C .ouOQKR먙\߯SL{3&t_Xv+}t6~Drݣ<e nR7�\&~] &;+zG7zOeW =% :z޾vr)N_ +8vy)(S|JAW +Kj)z>}{ls ; p̾?S ZZS8_6놟=oݝU2v߬v>c­\x| ug=[jl$]ۋQT/Y ڦ~Vѯsi@ g^mveK!tc h/֢y<*8I&be)3иCUPӵ.M~�?m\(9(L.-%CԬN91—&m.!McM3 pBh<tyWwՂA}4R,RZr!,n4q@ܶ1b}lذwyBGPl^_B>7bnX6~6isLD7;,憄< :Yv33TI(Wmc͂O'P/ ٶʉkiFi1](v!| m9 ŽtB\kxTP"v!} msˣ<Au5/7xjxMWjcnlҰOU_k谭[gScz~*v˚HPq3. /%br%1VF\k5Rl(Ra|mvVBFo"]DO 6+r"{R74V:pqS|>hE{n 5n8z~)ˣG?=8);xh\lLPJs_put/52m5~ۅOO@I;xUV#}Kdi??zի7I;t<!xfq;R_BaÖx%IPe8&5З<H(*oGôA_`DⓂ#[SmrggU;(01v*k0y+21vтɁ,K Y@DF }`o3ن2eD_M>.eq9y +\r(kw YCYFm@XǪm℆8) Hn# <h6цc�-|r:`1Ş *"zU0~IJE +lRf`GIZ`Utڨ,%YJLA5qDq+821evtS@DRlL*ޣ%Z Ky+}bಯ> 0 ͬG'dDD-c[U]YVkdocU:]={Q-K/ /ݍkcX">(߮xhR1X9{L[ +=;])9xV tUSVJǑLb%kӃnRD:'i_z +I$`oxw鞭5It )Ƶ?<߿L{.Aשx-l;Xu*^|"^Yw7PeXڼ𑜸K$b+jY*$huT˿QNS6T9N5ϘHw4�dS6E<U麵@Xcnm l%<m? 7S+۲,6$J YB̋cbℒsН/uJ[ݙtԨx(QG{7ꎱKF= ތv&`�AN/X?/|?_B]iZK& +П}u�7Ճ~-mqP{0@ 'E7b){8we\&rXԀv3s$V?E�}nw&0Hbk:O]y=>6zRM /oN&F;5'c~VJbI.uSǫ-CʿoΫ|lC]Rՠi kJvf9yvЋ&ڪ+N_BxZIA^_GgָlA6g^WB5Z#נ7| X1J%OQ}P͑cn+.쵘5rm}e]21ˢtȒ[^\s28TMO&Ia2~Wkox1Mq奓Af67(\}eL2o`Msde.|hOKheLs+C g 4) aw.'#.rɚ`nX>%aUo22Jm w_l5WiC+feE�D EpzyPѝxb3)N>ߞ$65*u=G^+VCKnigOf39�O 6&;Mؐ=vL7�/u +OXFرo^74FHr#2׽݌:]Ϫ[X9~16T..kKK;w,qTwlߐ|8:<V]bη�q6( S�Gq!YXA>566I +C^$C1TB3,7g1VhNwR㋗Op}՗FİԔuZ멒ejOLܿ+wʗwysX`ǣ&q0I5WZRe#GHN:цck-=ط/3 psP-8. 6+PyΪ 飯l7/9\4�t(I'u%Vb48DaX_?wS`!xe[ȱF*G?m}iw,iY9=ʋkNi+GxQ/:lk:>@f}iEe/%| BIROCR|}ŵ|Q׹|]8<M;�=+AI[$S NN\:ۀ[G.OnV}N3/m~^ԧ�uO=LՐ`|(~8ZۓgKNx]!(=tafNP 8LXFZ RQ9ܘtC\ xsuc�墆ih7_}#Pnhpu>_Omv=5aڬ?sO9m6NG\Yh|諮�bسHk,-|n' +=H_m]5x^ΐ],KB~1C$j@O8-I\12 [@ݵ p^>2lKk|�ZK\c{ ^*�?N{N(>Am6 0zY98 Cw'=mbjc q''.!Ii-rBO +mЏ?&�"AÝw)g] ́{K>^?Λٿo +!<Zq-xNsf!-X= ! 6Ǐqwh_,iݗ/6zҳO grjsnC˵ё#{ +j\TCЬڶqB)_lREE$ɵIN`Ȯ�앑W1mE"lacTS=Awt2@^YXJoH\nuGsut{wy/8/LV:-xڢtuFEJ ╯(0v^`v �23,*jd&?mjOw"p)"0퀽CN}aMt'՛R-ɨ!?C1ҳZǯAX>b=?8\i5!C�Lp�(]]81T+E \U=,P_sˠ }12 h*ڒæ2_-^7*bdRZ\v5|m\s@" TJybMTHӵnpd&_np5y 7]O%,+—UDY۝N=,`狷)Հ]㽼M47\-Mhfw<KpUK~8KƑe1 ` !ŦsTal*lAV`ik%DMx[Tc_)F\hrƋgxY_p$wѪϧ֧bS_ |vq +mEKik'KAf[4/E2ggR"'[t;`Mtoty% +Ed±4 ey!bx}JJ< Qe;-4^An1#Q(ϊ�!t~e�_%=gqB5fBt͎Fp7@;\=& +|)ӭD �O endstream endobj 73 0 obj 17754 endobj 74 0 obj << /Filter [ /FlateDecode ] /Length 75 0 R >> stream +HWAn7<A6yHU.jPZd0EoD8 Ƙ%CrѦ^V]kSۋD*ه]6jRg/v )i)ҫ_3vonLOjWx.p^6MKv^-+~[->jciEm#/ymӫ^`̱oծ~-N8!_ x̒nԎ*@2�ҁN^"5UBkˣF62ckYԊ-,fdapaI"i�MXuVD]zSD1:j|W`eUl0 #`a7ԊwOTC78iVp/$} /2hSO5=7qx:Y6Q2P=m֬ -[2E? !QȊB W)%%W(L`wyLWn0.Fjn N:(b9TE93ڎblC²x(.x:pǫܬ:+.a+X.jˎ" WfL͠*=q:l=PP茗=VQ؃IrR[WdF0hQ.HYOy{|~@/_WPК_]p?޽O|yxl_]~'h'wDx=`'60oL%خ>^Vu˓7x}W?%lH3 iQNOlTi,'MJ_vҶi14Â@)'l~t2?OU_?ol/$ X0{3rr fmۥ�,TAz$/KN1 *Gm>% )a_-.Д63+@+*l߻};e+)Q5�1:K7)M90r> +=m_*X `9ʰAx:~Mv^LK=Чer�Vö=b,Gt ۯۊ556Inɑ.90BGT+a!$,=go.gք8�Xp@pk;<$.囬kڠs +ɒq^ cFP& "fI5CʔcQTUr CLWS>cF D~�R�MGqКHz-m|ȗPɝ)-7^sFVa첦# Ln|;3dO| 4ogӓ@,|)MHx/)\sg M#Ϟ;u} g0ZFyWVRC0T5bƣ� ,:%vxϬ-AвLUءO4Xlo<^RSD<[jGz +X#Kmay;?pXnew}AK7WI B9UjOQ-}"53џe pa) ׶ ˬ R1AŽ{,.&h'չw⮵pueU< +[9' p@-WybJZ0=@!Btl/Kߎu9Fv=bwu.@E +Ő37�\1qt])B+ym- C�o{o3gr[:hlD(h:#W$~�rB % FVи;~+{f\=FE L'Ws;,XôݫƻqJ9Fw)Zeta>$>5�-PoEwH j~v`[i -N~sevn6K}�[4MTB#3mYh�^8�McҸ~DW9CE&7e ,(}Fz9m{3Mw*Ns-YQǧ'hsepBX`Y5KLrۀmSØ)WRLkar|>xN4򑤜ю"�z2IwHm[1qP,huz,R�Y0�ƶdJmHBYd3-k\cPfma{.es휏{8*b{rBn۵3B騩lS;4F+c\Z2#۠j>LMYe5AEF<RD>Gt)dA ~6J=B1ra޽#@T4=(E!G>�ȹ-pxR6c|Q뱼HQ $'(k2gr\�޴24a9[IF=g"8=. _ YAG +d_כ]~5Zχ|~e3,ORlS .SV8~@,^evG ?"ze@ &HFﳪV>{Ub)aժUL2M3GM5H}m_{PNP2I;Ddl1&./ȓAҞ_bA2lSJ!#1Q Sֹ +^,i TkߙE` `0} ɠJ$ `CGn*Ť0[eH 8۽B#gN$j0RU{+y-)f_f{V ٨TV b:?XB(ds<> +KcDzA]'z%w3D6buK7Ze-Ȗƶ=if-&ӔpbT s)@nk-H鲊uxV1d;&{a.ȳs"&Zl'伀 `UtnLɗr`cNPNZm mbrQȾQ|6c}l39P>ؔS ##qT@=4`1蘌sgox"8k!W)a'u$X+H8G5Yh˭@zs+ad-:E]} TDL'ZFʞ)̎Z +U`Z3>U>FF.V԰lcck @mU ;|V" +J!h}^%Ka}_; %,{F:,aE3Uń}\!0PbjLƖY#r!\%a%S+XymZX{Ղq-u0\թQk]PPӀAvΒ�\Sz jYв4jU2@s &b2S FAu҆ 8[6p]淤<y/(؆K;3kzBENG]̽Z0BI6V5 75l]~g9:$1D9XJsBm{ɷm`/;Mv`Ĩ9bt*62o Sn4Ok�)SVLa2:4) PzMq91cQ^ՏKq=lW%'.&aĭ zS JԐ>򻾴TTGI_εvQҁk@"wˍolk X̂?v !W&|6ia |wyJ+hg#k!LYO"yvcHL�j} t1^+y^'?.?K Ʃ얕Mc6`ST;g+{RxRr| 45Fnd%sQ('ٳlmHi|zL$L s6g_7a~%d,! k(Jb"9bƒkX� Q0"L|m}BS}͟/^ꇟ^_}0?ͧ/5}'{/on?kT-~s/| /V]k#bY2Z \ $-pũ+{~1TA1WLѴ˯xS^u}SBZL OS#fP i8UaA`+*g#teX6 w u[2!YTZ }p +V$9D-Ơ +cCl;j0JݺjbE>eUz4IYwF7jMd{aFԊw͙MzI}`fGZ*u!D**r[4@  9P_QI {V[q#:3_̉GFxh͎T<btxMtGդ¡(d +|d%n4b&QӜY,VT-h:˃ H9h\|9.mNUgҽ6mW.+<[J!=<搷<,F66a~U.M\s8U^6U6f6kXu%U9椓lC 1:C=tD֔⠻_5H`êhȞQNȢZ�agh6xRGL_Kmh' E8aFmg�fFۆ{9m ;\8ch -Dzl +w)v }”&*4_:|S=Nv\q@"giD`*O5="DE(/9H𪂪lVGUUHbgE0@ 3aJ^jmQ"1o5'Y!a8Aẃsxе&"Y<CS%HPa"hWVYp pZܩo+õo2<$b  U"PQLgBt\ +|)yʌُs(:t%ZϘWj8}1Îm-]xTC١k-dwޥRlv-1HSҫ?ɜDǎZq(Y%Kw#8; Ky`'0?%hΣMc;(Eb ^)Z�k% T̚Dcג׹~]qϡ[/>3Zp -7} +z]J{-X#ׁ<UlQaޥ>J`F't\3g{zӈ找%{=g| +0y *ygXm~>5C /y_9K1zAh2'<P'g]83lZ)_[A^(]HBÀU(9]@l8KQNmYO�($AGyA3@3!^^9 pi6-K4`2!k\y9lCo1j}*Ig|Pliοc[^?Q;q-%T3p\Xs恣lj;vp/D=9k9ι_%-%nsKF>j[#9_pv,~y`3`0,ƘY8¬w{GUfvWWek-`&2222ҋNΉ"އ9�MkacMI Z +4+N3۳2Yk=}+X v-`8[oA B{�2{c|6”ņ!(V\gn 'Snΰk :iC9#b~(s[9 m\e6v݂9+9ʎ,E%6JsVeEX$; qw/xm:E>EyJ Ofj' j8Ve&P :-* +ze*^80qod7 Y$,qGز-U̖T\Y|u}رdG]}F$v wKMz9r9>ƱA>ӹf^'HJ6wf/8<g4\OJU+hXdp9k,0>fpw=,99[QVں +!`/ d%NUϤS39֤[u sb'n uި(Ona% ֺR<'dyxmEJ0b'W EJOo|c'dTvvOiXc$rc{p:eQ ]}ryMj�fTo.'X*V4OM|7o+!TDP$ϋLb@=k=R墳(S̈́qO슑 x˔K|r +9UkieoGGbY]KƫX�>,lQX*X +jO6<m$!ك{eSUZWJFLyH6ZϕW^]q|K*)CO$MF 6�7 =8ۗ۱{q@Qr}KXܛhFDNYVgCԟKowܿTw2^j#pB| +%5B`]<~x~ҏV٣L䇛:'G6uL*uoS\WE@ ]YTRJӾ:pֹ3PG>[ݟ/W?߼??_;r뛹wn?3@7_w {_Y#yGgyFlQ_sZl#dJ2.ٿQ:۬ۘ\r}㬫l,''S(82MQ}!5DZoV_JEm7m9 `r)zq];@ĔČ KijE+PL >n0 +u {c ++ڗ<d}}r[QJS]c;'=Rڴ&x;P + B Hn=aI& +INEл$UoӨ#pup 17,>mv{!Ej},r& fF8\yqփd:)1M^ �ր~c.~63؄;.HIUt9ݱ/C:y) ac +_E+7$B|z,ѱa^5ZGk2!-!J}mXBg,&zv8jp>PP8ze˱Bn Ngۘno~]pf/a{7mc4ྶ<nj5^nSkwӚן'>C$$hs/=(.n 4!3OBaBןAJgnو Ur%aaKyi@Wզ^qS!]PW $y݌= -iuAy w>D>ǍqQWNy)+0 o4 -2Q"^!fb 媏kRSGBr^o^yn͹$m +U5Z G:eaM= ÞÑ*yې(+ȩgm+TB^OiƮĘJM2_7G-[5u}Z:#*)/fRSF F<MOr6KVQ=-|O3SAX>JIrK=Ry>GuX|6;d`SNk-Q|?m:i6+l/f1N $Br4O B T m&(hۨ,T<V2j*6Q0[כ8ڧ2Dީ.BmLeXh6mX2= EO7yeYyKxY)<7x#1+C[fKuSg| TB+׵`y;AR|- U Lpݡ!+f]dx}R2_w̃Jɐ|5HfsͪY RTU)JKWgqٜ^^w*?ڄGsx|A,V%jJ"=X`M(6lV1bZZ75Ҝɫl 葔Ѹ-6 4Uf }BRbʒ UV7Y-ORH2WdwY$`D2yOֈSj MZ7F +`K^5N˛VzðAi HyM>I`PdۛLL?%RV�q,#:e;CU6$VcU_zVk dj7jJ ʵV%J2ԥUW[[YKuO碶.+"r*842u;vڹZhztPbLSг^#R ;xI޳p1 +v@7rX6]O2}HY=kG3T8_ FMdfAJɌY &k-nǢ1^ֺ^ߏzZjkHZ&q= (u+Ԫn-µ*IΰQ;G8{q6x1=d;) +uw@um'=,ZN"E4GBeHS7LL-d!rW٪~1H/ܗGMa`H^-xVUuct;&+3'Noa\TRI +mxrNmO$pwm!FeH}ʻ #+لi;͌rkzSu;K]^(aFfy^i:[u$Xu%ESUV n浉uׯaXx-*q_|n i3T~Z͝ye9iOaJ$Sʙ3=4۾:;mx7g'y6?-/˗AE.CbF,f9Bمe̷*F֓6sX։k)KHtR^]d##rRjP0JghsVc 4bR VW_]6=iH6_4!,("g kHC"~1IRy4*1EyI\N(2[𣫹P&8qMTi 9*Y E!vExU3Y` l8Ƣ%k+hJ]%U:ad(e7`<1ڷyôK'kmvѾbv0M4eP ri _H$uCͱmM̯ 2iG*Ⅹw,W)1;u](IJϼ|-D7 as繯or!jˠBbkJQLRd)GQ\�xՏɈUnpe]0}(&WWHzo\Cf1):.}he(tU-5-gX&mmlx6>aVPIʀAS" +̴�q:r|oD)[̉5*_CGBw0ksOi +:*HxE]…n92`3ۺ}y7.A кbE&%r#܋Z: (okuw0O!]bCu|Ă\ͻ>6繯ښ1,T*qV$@TcH&ƊS{3<=&=P%Bnf jmE,>T(ZP$<sYR) wVܫEPEd! _?bJjl$YFe@ds辇]s^7RLt UbخxW͛Hn&7 '*pSM)i g,v&Ch.G8J&]iYWE RWUiO4'v={v2Lr/أÌ++W5CEi%Kh ^G)0"zYSֳ:Fl%Y#jsTȭ89pKu +s1&=rEȟk70Z6clDmmt)̎s@ym$ͶӴo "_-WOsI<<͍ztV,HJĨ,u&IaWy6n@S> qȐ=՞n5eaQl$vV~K;x`Q:׺.Nc-L_Kf₲2i<%'z⿚ %KysUS HhM6krL8li)^dx@S=N„?e-ja~E`FˁqiUPs63j|j~mJ`+<%D>|'.PyŸ*[Nz0KkS,d"K+HL U*XAOban}~LT뼖Wf>D4W|'D?M:?,��ǭ_|<EE!Vs۝]C>ኘLW�;hތGS&UX ^hA4w)x{~\%n3VE UAFfzq/DPkog۳!of4pyrXJ=@̯8 ~Z_ׯן//,>77?N!]o?azJߝ~;D'DާrS�trY-jܾ̮]Rzej򁩴F#O%M W`r$=A`'*y~HtH)sy~�ݝ\Ky*yѦVѵLTDy^޲Va꾪ؾe_(^:ބգ/7bl1cvU=Ƣ/Ոk9YMkۋA ҋ,HhBcl;G:yA=A1(Ң؏ЕӻU(:$0z/S󜠕 +$ ( Qª�ёoDn]6ux+IIDAɝI]IHI > 3|IWb@BV +Y c@ sHH=N (%l4pȈ>u$I[k%!^WZ�䄌Q2Js Bs"]r6} E%kur3<ߩ4XWY؆51/"!'@-wc>n(s ƞ'JxO2]DDhP Zb]#MѾǁ5٨*'%=岄EzRļ~V5|jT!Y+mHdD{R!Yl $Fɻ(V R+B�ܪg3cC.][|mC΢QR^y@%%+@Ε齒z>DMS_D%ibFڒ)H{cY\!Nr2df5,*@9/aamU?tWKkE9}Xd0 !-[&>Uߕ,3Wuϫ_q@9`8q_Kwu!WUv4WR施�<~*·k +;ZՍIEk(ܪ!ö*͎CDwR_zt[Qc#נrYq|�dml %|J ,2*i4oZ.MNcAܕ[GS.AbmG\2Xh{Y.ԨLtz #8.6zMUv0h +͡捅mqUVI̓FcsEmaL_,^A2(xhCfh&;0sa( +h֮k2[*s#@v *la�T6i]>㢇Bok [C^C!Y`Y 7fL0k]j%Rhx+-C-XX-jၑΗ‹4$CHIa~S9K`v|&%Ju@z][Hg\pseQIdYdᮜpWq 縂 c1!vX3]p/XϹ �"B9h]ȳӄEo[p+~@c +lZ}πg[܀'k(4[aNUTMK=$7.'kʕvvoQ~K=cP~]~f"c·5tU+X$|Hm |D An,D]kG]l}dↁmW:uUhIsL=R]oՄaH$A 'l@);Kp*z}ΚkT>ɾk]=ݙh<PGYydI"uU<o-ܽ^h%~ xDu&:{?L! J�7:bi00i'f[WHKAFL›0i{ y7o6#3_e/<=8_?__ +/+==}}a"߇ +~,?/}^?s_~!h $ ~|C`x|u//y+|H0~`=> a*~#$oz2qk^4̈/c)ȡďU(b#O|Hs͜RMlR98zFunR`Gw Id]P~\6Hu`l.ć<wP6: ZCW +sי"FJy2ku[dx0eP# (b~�\F㝧al眩w(#׮KP ̽6^ƌ.pNd_mX={;\`C3fU]nZQpdz]V@ X(UY<Aoq�A:cke( Sf,g� �ȝZ;Xrk՘Q"ua-hdЉ~V}ʀz/=17FA2ـknB:)܁MJܾiIթ FMW`(YQ +x$7a-sϑ֭s'v^we贮SQݶm&?<2 eZך +m@۳OEX-czbrgUVí쩫e=MCT-aSQ5߳zn{$2=NWDW)Ӕi;Y SS8 9MΌ.e.Qez�}r^Fc@ ޒUF=Wj5C*p *F6&܈uIJg?Ǡ3MEGk;x~hF*btj_DbnN8E9 m*+hSk?*}Rc齡N0 $_-3|n|<G.]gY_Zim)$,*u,JwϫK1Un`%܅D{PQ=0t/gDa(hXڌ'F4o[INAf_S\dCf( ++5j:&yahmk.,IJJ֖P[| x5UfILqk5%,8jM} ,n{@B kԩrp <nJ  li[܃NN鮥"eG<з0qv�gлwo؟9 +܉4�`ec?1$y;+E;ѷKǮ$~1)IR +f8'Ca8IT6Gd&cQb3PL(s k\x==MulQPg{PȈ'WMYljSBPYLFj(׹mI'xt�=PC4=-*e4s `p3B8j>1;-Yv["@<ydRtv{5z j냌yz"s+E7)k.Mk_?s@za`߯IC_qi;Aou٘ LH'S믕֔ *IGrJFV ̬KX�R<cԱW5z29F3nf!LBNJN9LOee@jtqϥ"Z=yfAMYvcGð$Oڷظ.H*{ܙVII�]`CWMX2D�}d=]nMtG)JfTꚴ΄X=1b5z;'2m +x]!}rSǙ6,2%Y=q/7:eL}i0AuCԜ =u7@L d)[s즦CTRV /ˉߣ=}]/X%=\ Q)8m۔8qdV‹Y.TpD;- ޛ v"8O'h.$A\19biv2 lqB?c}}́1Mť=ug^ՒNX2V�u0g`{-Q+Sq|N㫙fOef(6ARY,,hMhs ,V[ι|{n>E&~bSC+ w/T +R-:4rSh!�N*׺{ !!H ؈!'>Mx +>0%c[a ~̫sNlK "{Ϥ ev&hk̕j-U)j81TyZ>H$;54mЗ`sY\~im4NyWFG{4;jX UZ :n 6]Mba-|PH3 CnX5yz;h IU#<ɨ:i" pEdu kPd^̌i-E2 f#߶墓tlu]L]ט[ 5}0VGV2J)Wclx&j \x%eljoMpYoJac񼛖ʥ uyHsǒ:)ZXwOp9_w'w> +-<tp:k 8_ A"7ɍ-*Ivtu,!bbvMsz<Z;h|&dީ[Ϫ<H?GsS:?^noBF$\^v4Ѩ`F!9JbI6,!W?0:HيcʟĠ�O7 +�k!xR1ocmuH�c0bCTOkl=(zÝfv[g +c^K314X.!2 -'o~V.2,lYZ5nFX: +2W'jjb? +uuQB,V~qC>LtPb4any2 + vSltcqYʜ_uUܑV`뻀t0C3lDŽ,jUJ <m*hՙU@+SO�-Zd[ЈVXΪTCU4w/Z£ͮ6D۰H�f<?/)}3hgkk<%88r�.BVXFwKkgt͝`(W'A:duuS}a M],}^Tf=E(Ma١R<;&I,sGwS ؙ̛mj{VGo Q.JUXx,t)BmIl_iw k.k2 3ڠ�&kk8QL˿^Oi-Bw}HX͑fTh%x8=15պ?41I.,o^jp^ƬiQVcW4*&_vûIndoٻiU]T"[pi&\@j}DwJ9`ecv}2>rM{# Lc7 T\ A2 " Atv->7[e0qλAP힇] ,̪RR�b60<Uvpv |ASpXU#$*WB0)[X-9+ zV +r @ڴ6߳AWYvdZ!cw۹{-WTr%ҳ`M'7BaPݴ:\ /uO~zTP�Ϭweٯl|aSkNv iR' ga'aiTzmB�4 ooqٚ* Bp,|E_{%:|/qT==Zs4DeBC o* Rx֨i*�T.,W3b45ŶDZǴm!zG|궞 &,l+E{nS:- znP/j-ڲx éRgGk] +_w֑1۳옷^2vb[bK9%PV\R:ςH0yg%3e7>~m-1Ǹ]5Nz_y'her@J/ysGFRc18Dӄnwutc?=tg(璼 ]zMv.Az2jS+ƃC|_#н)SJZEX^rkCA;P\g3% t`i!xk9XР6}EϳJ�!]ӛ@$0s%scJ%l{,C.8s_'0$}Sv܃ h/ŏ[[g$ Ro?I!8NIV:Yn=.#>w(MmĎc:*j۔QnXJE8;1yۚvή`hrE\@R7 |XS)w`]۸(.J7<]ZXҟk2IE -\zjmGhBx+s&pxHh NM𳾋g N}C)PUNR?bO$!D烄&)&5H۲ΠY-pjlvD 5TKY{;c;oQ_47UzG6aբ\fc$?7# 7aݐay" O-d9q#I(! ^:1vR=3mƻ<;'CWҍ4cl#;hGH5Ix݇Oƪ'GNP6£.m\K[MbVA Nf٤xrFBOLN6I>fN츙5:'nL +QfZF{۬{"7|~=6w a 3wFRibD-*k~_x㠃{PJ$. +3>ޞ*=y: >q:S-s dJFV\qهTS:F|1Ƭ0U(tS/AܥF gG3?}C@ߛ||@GO@pz0xj2}5D)Q鋚%™?m¤b]FX6C;͒ }ަG[r9zVn +d]8-Y6%b yalm;_npnC( +<h'̴Bx-ԥ^!84~C9@DŻfPc -GjZ`̓cXgæQ&Ώml/zympqԱ|AM 1}86q{XSNGu[^[Yf}cӋimLi(uh7"0l,ʣELH`NW +* +ot#;ȩԣ=#}M:QuT<|"?kcyNo erv,Sb$ŞKcq0ƢZgzE0X XXm!SvdC;X12WNWgÄsok:#٣d;( >a>v )ʈ8i-,H )#w^cy?A(up>tHY*ӎE~1~G124&aX{F<H>T&{(E抗!"|ޢՀoNj4JpP1kຣ-i&ic: y0SpUΥUiU뤃7S]| ݒaA +, C1{^vƊ&NU5uج`ϓ >&q}1EM/`)]ށbdƍIj놇k'篛G6(k] "k^B;sY.xaz8y`\fe4][ b0d,nc) 92 +ɂU:W?c`Rv{\CU?n0G?)?΅+%/A+c2`JRj`~hf9U~o1- g=h܁KBFΏr�S ~> endstream endobj 75 0 obj 19224 endobj 76 0 obj << /Filter [ /FlateDecode ] /Length 77 0 R >> stream +HW]d K~T*գ=!CBd!z7 <86&>G%;,ݜVH%Riy.oOOi!G~PE?2hm{"*3}qh%5`(>L86|ҡn\JQes$QzT%%sHRve(~({SFvXZUhO^iT Z̽e[fvrėJP3wޤõO7wTC{g'p6d/=e&^aٌ� Wn{*g +7&g: Ab?,c5EM^KuB\a?u1S-\5H젴 V WM->ʈiC{duZ, cJz<R.N& +UPIucف<BkdXvk*N9ΎH v EBL"\^د<�]{iA( I~Qd7FbҜq䃟�i$)`6U+LE]T"b-!ܢ?B_'Cq_Ž-@t8 pVuS jPNnw hG0R0{{PB rR<Q^F$2`Q6=ޮjt,jZ~LPZ84s'sw<E56v7h\p7.2~XۥDbUAhg Q9&r2*^K.!5<d�f],K7lyPZ|cHs;4uXӸXMAEEAH5p^b9q:ymKס\Ar^JjSUi9=;d)WIYv# }qiJui.|=HAc߫ՊNriW3'SDK +5׸·B*pZTq7Z;b&89(tdޜ\VU4K}Le-kJ UӞץQ9g&4;bIԷKGZmi5K S,)}M�X4={kJN~?<X1W�ns>'=Ql⸞sk)61U _Iw\+%Lu 4Ol nϮԄ^LcvGwvX\)57L ,n`%_(}65{Sb­t +=Tf6`+؅dz" =^yPX'Մ֋Vۄ}u+-y$Eu<8\g�4Caf*. +oz<΋I|'e.ZfE(;ۥCw׷$Kr4KHP~RX[XGw�}n&H{b�ξ)hV綆뜋5Z_1I u.1Yk[�6$- {5wwƞ.FɱcѼ< @kbJU:X.<ukPkmݍ;%_8ᚤ| +kQ{`>t{Z@?w÷Aߖw{x~H??~~;_^Fk~y?~HG7*Q6Ӂ}HDnHA7mzD橗Y`FzxXCn 41Y&ifPt0,<Fh�?,jYNZ Ͽ95ǢעӺHC]B?qT Չ4@?`-,V/) .ayLDe..v[ϓO3<gttR8:;Rn< eͽV[k8˂;tLDlA/ӛ)i,9e|Vl?sAhm'/Ƣ;țy 0OӌG\LDA3O`Tĝ֞Ip<>>$%^,b{:"|I񟰻L]!쎿BX`*26lO[-F,vb#n?8qs4"%R(\tx oO@ 6$GP:O?dRk˪>gu=s/XJÞti� �vԿvPҎl!RυɎ)f^Afk8,6fYNv#mXtfJڹ(z]F= 6.i{R4s77i vi㽯Z!CRfi:-I+IO= M0NDr齪뒹(OO b|$ᒭ7xT13ީR^k‹$z>i$2Wz꧵kcaɋf*Vvhϯca > N1?Վ$INwLHnxuձ :K"AMZk�G~ nQgn~q` o%˛+SAxGz}ǧ-]ձ-MCvz<<mN{*16YϪ~հI>/v(~Z垕M߭ܟ|ztF4,7<P.B.)4|]d6'Y)�4gO09-q*~ϣJenneM^¨YD + +Yї9�x^9m$e30bc +% #;d�c{t1\u8,eBʏ 2[v.rf[nz8,T 9}ƿU]M) z7^׉ʱvXr Qj0k;T<2Q>hM4J}dWfTTU3�|*y͋ԉqNA:b9}X-E/P@GH\0]I - K+8rY+0k]߷AdM>q&}\O~}<BŖOJR&PoٽanaF~Kɵ Jg:-v8@oXfAyosɂQv@~OˆEaTgCm+VЙeCn2uM�k-:T�y/<oce^,2`pSQ^ }㖦�jHaqfLzAq&CB*{\hFƖI$MEƍ}0Υn- A  yeKb_ֺpS¢~]<|S؊quqmwi_בʍvOzUiO)e@cC(sGl~ؤPù4VT<� Z %3O/+\pqnnV9<% k+AC4{B|FR0N~D ROPE,nB`u |PUI49T_Uz?% .gReI◘Uuݼa`jIu+*Pߧ#~]GB6c.C=!/ 业oS/ � sHSJS>1Tt&`LjD5#omX} +֢`ɩo \'>nɸF1E^בg!8W!Sv94aI@k/N@:xZa-miJFo&wGނD-U^~oP5nG,|BO4F56 XRs7t{nK%7,DT!X4zHPag!R0pMxzq=έ +> lMuu[ t/<(C7*0ާ#hMpKx*UL쾯svq}cMyҁؐ2 +`jhkUOM4md=]x%H;v 0p: xvB׵m_ݢkTbgNI,JAXuUځx'͹C"Puy6Ԕ}#x�ueeヒ4D>y?y41mII]G<qGaej59D$~=:rw`Q/#4W`iay9 ΊAc +4a /]~lI&HK BMSɴŗBV,96}Nf9yt-Ѣlۥ*৫#],C>bƺ0b$=�|NmbyF$�s>�/є~;( .U-%� +4|rgq_Z5kOJǢg&C]T  FZVX@'>:y -x9-5eʣ�u(~(]e !5]3dTkٸ {}bCBKAcL\]۽ ~'iWE)mx^י'_ba"^sSb NCf>p& uq:o܆u+Teb1 x٦ÓŵCM\J{(݈_`CDv (jMp-t`a1+Л ̾f;DBY `S#g +b@$y}i `V7 t"_H ?*jX]_?3&5'"Gox(QiMt�PEoS{ģ֤;Е Q�lmy~ITΡ&y;u(ݑ?*/O4bZ݉mːִ|CARkpE q|)'kpXUKm7:^בMɕ�'viڷ/ eJ~.iP$?MdR/DNL8Ҟσ>" + W!l +}쾇+erAXKdtuût;R琺CA8 c$[P)BX Dވj->4 >*kG^@D b%=2ĿwvHT4kEPo +^V=,Yj"O$@~u;<>2uR8r60^u�hL &Nrj65,Y ߴsbw_I3~6)U;jY*8hg^בs_m+vG ?p՗钇 FdGM@0U%oFY]ꐳ7Tߵi*,Zb+#7<|(0vkA|XFmMOåp-=;AZD-) 6L(ޱ'1BS3J6wG1# <9L5>f>5oNM`iDcR$uRjDoOۢ` +y$?fZ4# l/6E̙ J5åjH1 +B>ӑZG%dW"r(fĭܹZ3#(b B(G ZN.Jd\SjͷO0gWxXЀ )Zx{gk,0>Ί tj;rUPcZZޛxc oVZujq8I~@ȁ8yg+:q30vtҧ{ϙG$g=G?v,1=8Meul +=r`>ws v! Yj FriV'h2 MGeXbSFGx@SVCFF 7 ٪25>ոK9u|XxxǒL fUhX^k_ 2&1; w6~%&w.*$CU#r](-Ӊ 6ͻ ho44 LjͰȍdλM]xI!a7m+nqF㦲� Pʈ'OWQf +1tQ ᦔX8-lB)u߾=U 4ˣ Hŀ}[SR[/>j�ˠgJhKw:M٨fX(|߶6XdR,=Q w&As92 ߹V^HGP_R>MngK"] ^=MS^#V?qLJ"dp#|*7iZ{6)�1Tf+WjI'4(f%&0nQ {P^j-|�ґB4pW O+8NXa.pCo~0{CؕpV>PeZ]9�y* +on95T%$w죛ԍKˣy`yn2A2zJvfݨ"tEAʡk?<i<=~ٟƏӗoo?~??y}wY {+3~7_LwvӷPٺh;#!-2: y�z)b^=z{h2(~hJ/lX|[U=: ; ڱ#Fj`0�q&Ƌ5\=jgi@c!=AѼ=0RnXr7M*UקyW۠�6 K8k#@v>А]j +kNjᛸTVL:a?|Gd}~Aއ^45NSMx>Eجl焵g{c$cPFGZl&T+A$44qN딺[0&Y:1 $?0](kKؾ*<{n+AX| ,YX1&0S먀~ zZJ U%! d`6\X@2݀_WNf;;9 4?dad$F5 �K<X*6IbDbQafK8I*ljq L%ݺA1NRza cyGT:JCuhZ p^9qNΗQ ƌWm[f(O UvtϦQmiuޭ̀qY$fuoo(>Z9Ζ>WJ[[X,|sj؇`�l d +To!P% dhTA[gd +rBy?�H>XF4/ij'GD37INٺ`4LmB5RmJdf\HypzXoGD6k?I!`h^g#$M[4\KPVS,Z{+t2WTR+%@k*,2zLEWɩ<RՄ6_dxv}&|ݺ>26ǚIH* �JguWg�p2f0:_\sF̺( Zrd_,L'GL7^oh%o4{`]*j'k-1 sp^h?iKdl}ZM@ye +#n%v:" %�`L`p$YIo^'�QW1S,QifN,:`VVcbMZ҈#BP? d`NEM [ ZDP90{>c١h7F*($e /<}dAneQ: OD &d:w,YM$&2&QVO0:g +R7?~>O�ɷ1aӇO?vw?֫mŮ~~ X&1~!O$  ‚D.p&H}tA3.իw_?]Ƿ<%Ni!΢ari3 r|A}Yͷ*oSw,hmO<4S$ 4`-lt̘n&/_#Tw6Rq}(BNg&U_z hjKQP5Id?[W>8臺9]>mmE,�B}D=fOe0}Q#',KR\Z�Iϭ&.p ϭB':AN~w/b޺4 +<[c^k)YUQ"Msi-l2V9MDQ�Ca^ruڬ +ڷsIN8if>x┘e睮ϔí:SFU4aq~f/dyҞi~{y2|g{Njɓ3r6dSZ+y³7æXy FϘ}B0VFX;u]@/E@>ؼ84 +kL2exb1VF\t/嘱kq-6 +&olO6$tEndZGOi07&YyPmg|t[-Ig0>.ZzOQ(F<v{S84:Yi`i\`+.PvV:}?5l +ylUyoҹJ^U rjQؒ.QWZ4MimZ@qCE /]$h[&X h0-k,|UmS`lD�f WF(mZ7a`*VI꒜u(S,ў.5S�*I}Q26]AQ;;(doNѡ\:7_!3`!uzh^Hxmig<12m;-iL##~J)2?6<wW^Tb-q:os_:$~DJ`"uwb'W%V! efymuFCOeLc cیimP5eQ=Y#{:GA腑L"Hpv8K2t޹Fkr'woOSo ͘l9)ҿcJ.*^PBڞc2uyi!20dVmם20uતS�6yf0.&@i{VݭTˋ!Z}]Y(* y^ KwM$0CLin;JzgP:4rvgLv1ݶ2F:TKt-W/jR5q+W7?t@ϝx7:oۏ?w^?>|xW0-#?埀~:I{Wsr}À_>h\rV#0?|iќ'~:GɃ{2֬3# C-UtE7 T6lonT +Sf4%{n'|`(4CY"lp#5`ӱq!,mՌb7M3AӨBH`0U*EVXrqӃ3a2ʂ&>sT^)A pȃ[xGqPW6,.6wY�پX :|2qUTEp^7<NpL�F>ꈳu +tgq@b m޽hʙ`q'�|ܴf?>cw�YXv0RחR}(gt^`GVPؽ"s,遠*:lQt{m)o?KQ2Zrns, ,s@QPSp^CgWZI*N~-΢ +%N``v1к1xp{ ++ V0[^u3;U#hqչ&q?,{ytySN^Yn: +M~|y;ؙւ4#�|m6WD1xpN;^QR@ԴSX])0~V"_�<YpC85FpD 9(JA7{GZYOvK"4Pxwj!j^Wvg z|^~qUcnO CESԪ9w+K;n{Xz"}jeP^+P9ismC{iH[y7__2+X@z�:Jpp.f365prMC d6'j+wb䓘4԰5@,+<Ӽ4[1rlgO897@[i*AC0MEM 'w9\h%yIoARgr$4y?fs.-귑`sl/2(\JPN dFt^يun5BӀiwtoݩTyjpͰ>=16thխ�@wUN#XlX<8$ߍtz~) ۥXrtg}HQFnz9b:Tyhx3.�$ßHSxtm*-KUk8zDlqk|Bp) ?n3VI+]K_>ÛwثA37,VkJ7Kw$ڰ:"cɯglTؖ%yO`̵)lfbzbmG8.|J˚$!lƪgoM_9F?cUXNB7/읤[q&ʣ)p>|TN}OL5M\k|Rnn:(O2o&AW_Ul�Ε~RLYz`735󫊰u(g>vkץh*'S㔾R CX +;\k閂S1#EiZ:}S{ꓒKe`Boz<@?1>oCbpgpa<؜Z^jk,- +`q Y}ātO2{)d .\CLA!=Z +Ӝ%3)BK, ("n΅(sJTzHmhe pLŅƤ?g>K4ohY3x2tWOtՅY9@UgYޜQ'zӚ^5s Y /sub~ +m-56԰+M2Rn &2UD"b+ӿ) ϓ?p]J}훱$�SIOZ}*#D$�5~_ߗVNK!AfXjw `S+JrɞpQx�j%ێo8RPS/,8릸%cZo=}J5L װ/Ӝe+-bZgv`6_qZj 04* +y?[S'amF0Lk�gnˌ1脒R $07/cawt=+[t@IɖC0]Hր8�$0S_`-I:+%Z<9ig uScK5v1و(#zGja%3"h;|g%Xe(j$3> +f^/�oluKkgV\XJ1R<5 9 ^zGZԞO"6豳D{%P!@=#2T-V#V6)Tqw$O?# +0ԊX46[X;r] gxvXS�<P~9'Bl4rD{WI\[*+S^[#/"E [\uDZ@p)}o؝/p9<X?2�p3 zz 0;*|S)E+ .}u u*r0LAx:V@ 7',NeJ]ڈ>kmH$@ȮaioV'ǺcPt5?Dz2f6Ir]%%ܰb:<Yb 7�ZWwÎ#�dB{zA _C&hGՉO|�֔Gh`+!_0@<M^=ee Q~Vu T=*njzm)"V2R%h +̦0My#u@fVCrl,q0\K=߭ +ܣ &yd`xO +kosF=:T#[*a(3u. l<eĝkov +m.u<@#k=1�J㧶?͢]ZO=A%aaآ>jԃ6#bG�h!|Ŧi PD +QBj�]u\MjkR-,S^ `sx_f Nb +*n407SYwżAf]Z6`Ҽj c'%%PGX6gh#qI<]1&a8彞K`o]ʳފ$0쩶(%R\)m1Rg+!lGCЎ$J洹�l^$9�.yyC,dU&828ZI�yֹjk%UԨ Rvty-מnk-k}V/j +0G{wXdj|֪,%:[\R.>$q!2Z`tn=?Ym/#GJmLiCꮨVo]x׿#T0*8y*}-xryR0�8jY�0Rkεˌ>k W�H5i �+εO`6.>5'4@iPs-brĜOkAr?n]+Big#G VK׳J3G Pg#ڴ@r?.B&oe8A8 +r KEVuT3x8S(W)TD;ۧ5Z,hƀDoSq|C_g~mR**,9q{/q x>;G)V{i.]%ͷ. +;2Oq Ӈ *|-k%-| #IVa<@û2Rj ѝL߷3Pc頓ouOWw~K�8A tQM�Jxl8TPwOvRpM^쫳ҵ.HrE]jJl/ҘMڑ$qU;%51^]PLE.SeEqU1bUP]>QKK ӎF .pWHxa7~fP +$@!*$vh%w<֠Va+xf]:ur6TWIw 6nq [.w z5_,J"GS3#.yԹC4\?QF, LZ�!_~jzDG$FuRa@&اGp|jq}h }?a7`rsKO[nQYqUoh[K pt]6V)7\&,{ dqbxr'hu0CFyTȋ7YHP+-E؊+jt<v}DNbF>D%q#v1{Ζq+r E8ޣG"GVwlCq˂ _{",: [c̏KCmݾ-8r+`^]zNMuɣcÔ1( fTV')&0 +4ЧY9yTj&3 (5tVy Y6~^vXcλpm=%>U3Ǚ뤍!TwKYi)X~' +(Xb$af +k"^�p%ѣ ,-) ɳ"|Tl'Mr1@E5E +C;ςx{6sg 8Ԭbb9?Y|! 5 ~OO5{"%Gx@&^nKao<ؚO(vn z;BP -U0rć +yvKj*)k܅7C7S2S:|edRZt*k)+9t�4w X`gKh`R"~ Ю֥Ȥfr=Y|+ 4* gɍ jlۑDP"|>% �F.`l쎜da) ɖ@[kX +<H V5ґ >O MfW)d5o%f fHZ;eth3L YfAQS 8< 7*CuhTY55Ns,2;/2Ԣ g;Cj6Y>jOOp:$7hV͙|\&.)q~q6^Qh?-g61]>GDGQVr!ƹ4\4vt1 @C Kz,+F5L?S^UZzE%\^yevAg y 5%jqiuiКD4vsxޜKX<ZK7%Y.~CڼZgRtMVLL1 z~_3:Ae]y.5O8 mx׋,dg-Q=h +h> Pۍ .>7~-m~?)Ә~% +j1z4UbHk:ֱ`xpAזSsw}'j-g3$]dbX,~},/xA)%'aa7TT$`aZ1VlfYaa{`5  =iyлQ +>dyR˂ag K>)k,JZvf\ _$܀ l oo+<kim]-v`YL'P"[iul8Z5>|xu[SaU'Dz4#BfxX(Q+j[0x_}5E DlVɝX[Mplԯv^׮=|eл~OfShu-x +>b XoaWgΊ1bX+ڵv wItu/vkU]UL:rYmt:p*G-EqQ}5Ahdl/>lJ~}5g#'8IZx;`ׂޮ Q%xu.WZryv/yUvj5PMS߭l_*]�qg_wZg)v*e G LXoZē_ߛV6,fxl(L|;pdeӻ>ן9ta!91CI�hQx $U;;~ut7W;\2{�E.WwHؿ:�|@Na RX,V]1i8ûʑ=/I-˚z@ggё]߬?j +]l㢅i/M=&$!O-=u}MK� )7X|wfhhc�G6!Ad�_O,EidDI^"O }]}{kFL2M!U8MGL Өp_߆4JcQ>#]b zQ}?lpl^2ì(Jqh9_̍A.}߁G[Xs]>ص[RG˹fˏP H0QmT8:#y.'\Fc5㎺ {i)xl9::o 5Nu]uv7 4Lhqi)RmiBwIZ;8>YGFZ>ۑ![c昞dʼn+cQ{x&jt%6A*o;̍LcQǻgUcxL4t3>**{VmqX{2`Mv +fjg}]5MwAo<^`^&!ePfLЉyϙ"lOTG`I.ܿYb"N՚ VLMSs_>_pLT⠦3R}u. c>ҳ=jQE/QXF  Bpd$yv+jh̑‡qaXRqo  .8W/'57my7 @&ܴgJ:2>�laOPc(̬ XIm_xC^=3UᖱJXXǃ h }z#Hъ-c~v֠WI[[Fi*${Wɽp V;:wzZ x(H M .Nױ8hMY*Z| +MY3wz"GZZQg6Jޣk/&wPa={M*,I[ p >2 +)�JsCBdP|IܘEk5$O�kK۸^|5edb(ӵWx«-{h1jXjqGY$iXEUmF:MU-L(};\>fqPqc(9 p[ +[HLzmTq},֘ɤXi]5_%(UׁoJU.⬽Zn2W7c|[JrW+ON5$ࡇŚa%"F(!`OZl�, |r2w!J=+86诳Kq<7Yc�GaV%T +Om34=Ӈu3bw>u[iIOxx)qM?#+>UtEZV.} xlGL@]s}J߿JWD#5XשCp~'y%7>2KNgGD{NY = Y7eTi۴3@( Jh-YVtk SPtA&FsIFբ{3IUyt[%@;ANmce;>�fR1%fU&an;Dm5!R80T\S2fZR@:rbw|89cRəRx&UDK%8})4._jBޚI{֊C?)�i)~%WfC#Ӱ]>ņ=U)d`;G5MaS>N涡[Umq|&cՄ= T鸆&{h3!{O'Yfq.7ky,) Ck:UbxbQhmLҿ/uIvZ4� P|$(I/Gwx!W~K;�P.F2 + p+F +`=vaK[ . uqۼ? V(.6F(T'{WpP#*—?-ЫLO5w2klMpr&why 7whXTذn|m5EĮ3iVcܔH ;'[cWY!= +#Bj:ȄWjm3"$TJ=9`)*{uFc/_}}y~?~w??~s}?_}O/k(oo~w?ϗvoG讠FUk/\` +[U}rߺؐ_lf(*ƤĠ~|` +1�o7d} �` -‘wa3ۜ C4X KԞۺ"c bˎbNX 9q�9&xij~?k +]xI){6_]b޽l+矬Vm +p,hN^,Y{y=DP<t52tNPy:: J$mB[Ľ NHlZv>,\utr~-J=5Cl" +Fx(Ue팭+@)GFtP5jnAO_ +Uh2C[ eì>ke% +P4a�0Elge4}z]>=vCD-8 Yآm\~o{mn y@6o|#@rwxVBcz2<V X +[4qU7a;Z`M3%!2K;>q-7#;K.똃. K~o}ftiXQmEX_='0W0&J?KuЕt^oC*a;|- +l~W)2:yh`@^U 6z^hKceݎ0ؽ"ՌUAY Y�d3_q0  `AzKIe;VgKPF`KQ$Rej +>#Ff1СJU*L Jjۭ HZ�ɻX+PlIs P%#%ܲUXӔ@spf%!K⤶dT֘Ŵ8 TB]P_B|A㛘uAC:*\2,(׸)`W̲>nʯv~{}>~t߮ןǻLaI?ziv05(?g8OaUxc) e!hueQpQ )PoKS#)u2EZ R8 ee鼲O2ȁUkwLM`kl2YlMneл!p6f4ab)=MUݚu7v5.#;GyDu +/]];qWih8ka.J%y^Y;5:in[,}4vL eI΃7UQ07YXeW NxvVIL54bRq &f Ur=@ bbglhP&fH~[]FkiM'u?ڢsrKw]Jk>چ $8\SA8 $x}#|X9"޸Ne瘃"JuWֺDsrd{``Z0m9kqxgHS�;<ԕzق}J3!9k3.&n1$zgW b2Ж^Cr#nGJ$۪|ЩE8A=lOߗ{� 8 `aT/G8l*LN0�X endstream endobj 77 0 obj 20416 endobj 78 0 obj << /Filter [ /FlateDecode ] /Length 79 0 R >> stream +HW l +$@;DRU.ߪxWhK�]{(RsgA (Í{Dy{wۄ;�?~/߾篿n핫}o_~og7~= c6n{%Z9XnBj&7P88)m +V!kQS ǝe[>u8"BVg +UIc{b\njaja +L9w,3Yx! [k=^״mx�w`2 "f;3q~,[{4][|,Eq@ȯ u�4 +[$l�sd"hc)}u8@R lB]STlSL-Eh O E�xHn?.UH*j`o i�7WAVJ5`�n$mu{T?O*:-;K׻Y]h_J!فTl^݁>qv5ԣ.k^9a&m GaecGĄɌQRk4G?VtSo aYZ"H].+o8ܴZS/6P^Y JLH^R7<@r~` {M>62 :b'̠.0–Ea9fɲEHWr|Lk9z#:y#~Ӑhס5`YfL:g ,'8<�i]:IUuSK'Vc'ۍ"s՚u]=lxJ#Fw>1yO+4}87QezemMuf>F֒B㻐߹@-mu2h= _ hJg) Ip%:[Mc ]ǮTg'w#h1< ݹ k)L6r/V7i>P�.Dq^.>BG�󇥩%Fyv&ԛᷙRG/yjg< + 9խYn.(+؄BD[}^7S1418"-յ ӂ"e`S +K*GG+p#�-]Y^f*� lj=td['s ߱V%+u�B�b*eU#JVaɵ}0`Ȭ˶x}\ĖQhU;O¯4O[Z-Y=eDL5MK6o(*l1*A R%Bu\6K\kWXa'gzY:yW_ "6\>m#+<A:^4ΓgCNgs r +i*b'X L>^{˩f}3'Cц p2Ҕ[ieIIpxe{zPx:�={uTI_goGAbX'X/[P0(~1ugpUE+T]#TѲp +-tDp �2%m-j׎ͩߣnb9,`N L�7WCՔ)*Ž|5~5eZ1%v)+|FʒR:XKT{<%&gju_|dL1udjZnjB֨MVPUBGe)3\0W� naFL˲W5($uu_`kNl0}C3hK j"nS =$#Yk{\~(_3zhzU�c!8=i;%וdҌ^W _1Y:�SkW%Rb(ǶvNG>Xz{X"HWsEB1a@!KTsN"1I%Kn>r)9Sl1 �R ^\Ii•t�t +rn9$!&sK•1^#bb-%O]Jh6E`'R3J�{c!rjt08<y!U8e� svl7|RO_?5=W9C RI!9Ԯ/B܍t>׸$"om~;̰ +݊{Ǖ`cvyu&97*ڃUcLJ>Z񹄆J, +�k̬fo~[Q#݅_],P(ܝ-oul.>aSZW)  15ֹ}q1@sWO^5-dBD۽m]tuB!: hs1&fVUpBzue$\m=YF + Wuj'UoOl^1j^dN%Qh添;T0voqƓT')B7xO0ss rq(FSs@M +x YxMMRb霅gB_CxRD^lMOO0geX<!Ό.QgUjqC祐<011}h9PJ &wHgc]cFZZF�KpJB0+6F]f<Y]SU~#ܯ`PyWmX\7A9,賝`R5 eE!"OmރuUe9NN{ `\|d�$6d%\>Dpvtm5?h%IZO�\n,$pgEc֩oǕoN f}{<1X"Ev kǩ.H-"62(j4<'dӛf;ںvLkE )ӻ/Hk[HBF*նHgˆǗ&< )%!kn,ձ_*`pt} Pƪѷ Nr$[Aqg|S +Jnht>4XAl\ʘ@aٮ"c*1ʉ>=ŵ6`쪙ٽ,Us#g_gp4H}13�]yBTM#x'w}AqNDrr ׼Yq=5O�P�!6 I>4U>UN`w5Q=95пJ>AmTӱKޖ +v8P;fp*6݈uǮ?3&7 zlҹ|~#:-kZ<8oT%=YaDAv>lKVB~)KVSl=.{k/%ͺ0_ɸX.<4Ev2C8iW'p}78jڜ[+ٚ}4ds><# m=}ݠDαpn}](wW\mGP8Q,4ǀױ$zY@6o/Gk' 0tj< 81_x7$Yp'93aYm"mru"@bgnkآ; imo^p_\M%*R3+I.1wL +O +-6] ߗ$/NyU:Ej]ĞeOOst8uװ*㜻U0.Svoz{3vR']3Qݶš `,bJh@K3_Cűba<**IK DT9k !MW#]syō![AzTJWr\Sį6ii8`la<L BȖA]~;N+ʜ@, +,ŎGYVIP#> ]!8d+]i/%ͪt6+).U!I;`)g |{Qu +RHѶo") +}Ȱ= F<fT1buk +*O2 sIJ,4-zRB0(u(VܞN-bYM9 zHI͋\S$ϻ2 6_}߼?~xU.%\~, ..ŏo$5$mz[q uf(n9(謴9iSᾘ7�cCATz 8 -E7W=G$׮\%S3R<UPZ-Q�Grw)6ULBD]bR052V }`[I (^LELI4Ebgl`(`{cSAWd^�N}_5{#*Y+5ѽwL;Z+=b,y=Ic`yI{.)95/y5,AǪ]w͐Pkch BB12·$ +`.9۳a8PɐɎrc!h4v: +L:$4dv$^�א5Te³aWkU!9f&e[87=_J)Dq c9\)Һ|:hlAd`[,vjqXs +0 +9m_ =Z7EMc`}ſ W)iMrh1wZLZi"ۮˡEs�xfUu%{�l_j1^?m)Ufj`A"Hٖ%4ݧ>(BC6ue- v j3 ے9f1T'怰�{PF;ۺ6J{ol_nS< ^@|P +YnIFnRP.b) d4s18ShfJ%b`)^D9PGUd~^¨1(`ӥMJ +8>8@arU=zcs[e+_G8n2mk (}Rʇ=#5YY^A,lJk*n[UPXL"P?>dXũ Ǐi1x yJK1x9V.i‚BTm3S+^V%G (Dguf``Cb +7WUswNq�(5-Fk]~~DZaΝ <!:rxJ0hWH]ᨾ� toщm'�V(vR`>453ApK$e +xZ+9: +TgƜ]K\�>;LJ|cUۈ%,�,+Xl$*�XݿX%1PH�<iAֹ;\Yykg*JIlrf^Y xӳw[zuo",9KƗN4GV{-R"` !~LN |^n֯lSz/h+rOB"K{L0 +(&np9u$OQ~Aoa0m7#csW dJ;4Dm%nB2 &$},4QA +AUrՎ +!vZ ]BBMelzEsqd EW&e_UƳ|Ŷ5GFjUӂi$ݹj'Ѷs)QЫhָl�fĉwPjut6mUBdߚUnN*m_؋8^pvT|讋6FRIbNF [Y`U؜T +W%>YI1gu1Pn@ Q<#0`Rg{Rݱ䋭\tF̨i/O!>iGmM~'"-~%㉘8Fn6ӣ�FĉvӧYΩdx5@5!>xqBA:99eS$|i0n}_IHˆm m垖ڽ2:ϛ"Ԣ² +`cl̰])(DsUs` +>9~ҳ>Ͳ?|em68ArՓbR݃<(mnjr%|[`>hR-/"e$~0fvl:a8ZcF:jɹj;Wo=p݁sl/#bȡ8qg1h-'Pv-2p{T}1NwZZݭS(C1{W>]}Az A9DnOruٳ/>]Onpm8g-`.QC@ +5䀈;溢U$x"kl-CҰ~ wbIs'-|Xۃ˿黧?WxWWo//>{ ?}9𐶧3[?/?ek۟=mo;CW~t>F7�#c3w;tՀ:֦c 310 @g*O׷_xֳ7y{V=2 (H{uyt?QF ;Ukwv<~wy- S#U@t}lmW_y:F4)WU<9fbCطW,sv*d3wa`dt5(&Lj 9ok GT3v$pLpLIX %(Ķ/9y,ftNe+Ŗm<  ЬRBw6PRt1ոj`%6 |KáAV0tO+.E钐 D +tQ<2Me̗>-M# ?8-?<rG�<T-V鶩j9]oFPA'a[[L S5"gn7kڕJMdwzR +mL[9ӽRT5=�XJdo r +w6^ :KPi2h++DžfV*YF`V~Xgk<Ѯ4noP+zb0MĠޑRLxwg4oQ[cJ˯D5kL+-Қ^Z4q~zi1]�&$J+,3Jk(%"1n䐾>P٢<ee$A*m-E=Cgl".s+ DtI߄;sf6}I XT2iTсzzv^c %|E߆{i6Z|tvJZR +jن؟.*MZX`86ۭ)v`^`qoabQ%b4&flL{Vד1%E빔 $%"󨉫8dͺ'h>*x ˏ;2ߋb Pb5NoZJXU w6;cבuyBS0yǚtTKѮ#.&h$qYc1!&֔ vrMbv&]zٴ/0l`X]H*tm߹Gs7(+)P1*TZ~90RmJg=2 W-&M5^bn!L1|cRĎHImqKX_ʲ!Yȣm\EڠCɼҫ@4J+iX:hYl跍lV[Z"Z q0R#"t2=۬Pg빟t.!xjlEf\{UCqذCfgzm"'E2S;]ݿ]HvvZ8|˫>>|x}uPڞxeծ~3 HGM pG qlp>Uս#FA]W~TW<{.wo޿˿O7~ +}!I - +Gp_p}tƃ{ndU/r՜F/XjF[N:,Tx%T &"7Ik=@MR6^HbNVIcurV$(LVT%¯uw. SPEkjc!|ق_YzNxpBhgMYM)!ڊJ(n�X8Wu< d1.FntT\c\r4 KX@SDC6E:H+puQp0ft.w#&1R%tP(UB)L k$`᳆:z,SRp—\7:j*"65=i1{oh$D&w#+_(- _ykU$Qi#}0@@ 2W&-8Bh@(-1þ(qӖk +ˁH�9Xe :u+ TH Q*ŋ>%c0EO)5of便d7Q Kn�vsB1]V~Q{S)u1tŬj<%(ic`BSh]^�7k]1& II8u)Mqk(!u9idc*u +d�OiÏ㢉00kCEAޤ&EdzLxhg t6n{0[g} #XcYPy +;ġ7gM)_>޵g \VKV;m6k:&!7^a(6x`f)U #J΅$dMy]$1 eoG  + +6{_ a>Rb-ǡ'f6о+JX\ + B{r Ei&m'<,FG4}5>h,>Yipŀ x7xb6j\Xo7-{ݍT_߿]C Z#Fp3e!-95V<|UOʽ-wYoy={f1/Ϟ_~VEٔ:Dj&uQ:~~JQ䊳DQ2!jtoimEpOs8m;MAmZRjPdn-X3XJe+":SleZó/g{ 9.ۇkp\|Ĭ 4ml aTdʹmhsWu{] +&ָCҨ7,O`3.9<r+|oJQ˩Vڄ8ژ0'0j+BA$k3Ԗnl}X+V%EA`q g +Vw˂Wppy3nJA) @TνS0w�FzǓW[R%Ty}Ǚ<Q% Q3 ^ȭ00КGg)W"8wG昣܁-Z ^?Xxd] DTnKLxBG({_<4ݒ@2ۭRO t>λP?vqgd醒b9\$&>/w-˅lr $5h7x}H, xyo.kfc bMPn5 bgB킮>khs4ჟAON_3?gw۠ptTv㙃9ݟ{gvf'1n7WG^D坯;Gv'DYT;Z;|vz|ד< UV9��|U'XL>ݞt@1Fc|1/qp>4N_|RuZoy&-O@fq}lxyn˿ts)VB~||3-6>a袒S~j#z"jY]. L\\F>F*ߺ.!~G3C R+u>Zv؄ydD5LѦ(5lk;ٙUpG,sFӋ$236u7J4Q1@PhaݔF|g"^T-fWuD*D(ݕVS𬤳 ̚O Wn2 !Lf |U`U^=Fk�Pɂi_V,1-sD*ϳq6{++Š80b#@9�S:E9XG 3^<p%ݺY _cz<QCu8c1y!)t5" +5S$DEۆ>]Fכ,aw(@l$.|&q}Th߾^GKlZ]{B\ No@(3Z~{J^Nm`ʋײ Ti<w?ŗ<-ՂZE|E7 +lpoJ;=em[G5aళ(!6Q VM+ +Y4nWkI(%ٿ>_÷\?_г?㳑)/_~_|y/׏o{>|_/9* 5\:#7Т<6L|d|fQ <,ѣbb}zbRGT1 +[bP"c@(땁:W=v�j]`- 0't ܄3 yOoH"{XةWn^}÷),rH.mMxWZ#m{\ɶW$ /$y%9gbŴ1-%c7Y&y }ފo_>}lo~K{Y2vИkLCh^#` +b�WP^Z4/6gԴ 0Tg*XTF,eU#o!"X�^JQ]!"�`!iPkVGFd-{4t$g뭥44,X;kAv&_n<n G1G|HPj +5k_YlZ6=1JP)5֎ >%[(B_k@FT5*j 0XR$clv\k<AWu +ڍ2V- [[1IF{ H(i3>ζPM"FӽcڋɢY_];`/bk3ya;[ #4hVMOjOA iRnѥ.6nƵbZP7:hDZp? qc�s3g+bjZh5նº2oUq aWjnljFM߭%C|qxKۣyg;/?E~p㈉ vX1i;V|85a9x~e: ~Ҥ +<O5dX>XԑRÚ�/Lf3ZBFKf4*'S% +m9_! +ryqt_k7't,A.1'}vqǫZb$Ua^1c5,Y1gwXEWN(.tb+zrN[[2BA2r`UǬ[m;S)ݛ(=:u2bҚ&N^J3ص (iY'nj[͚K~_j$QĹ;o`$bqlЪخz/yj#i iohVq'[Al +4^_[WJ̃|:J'2"GmU8j2qM<~猪ɠ;Ҁ;hǻ밤[gm[#K?ʕf>˻HH}΋])8N=PkOC ]]{iY%0VckZ`!Ϋ C)RFRM}^3ͰSZo'KRMHq}~~p+�QON ~k HZ{/5f87uTa=98ށ`l׮uLS@88ʲڤ7 vX Ö艟_N{2mK,$JXv,mbum"hFyzM[+p|h4Wۀ2!-㵦VMJ0s~pg78ZN<Rx4`uK @vs̸ù(V6Y? y ֎f-<{h?Jndk 0]}|hF̽s[ylގHfXTlB\ 5cnjUҖOF9H<7˹I=,b-{z;}1�abݣ[U +gĭsc-(,}{߿uX3hzAװ6iѫ J*-b.YH �gPa!HG-.s{(`WCoL-OJ9bQ{mIW]0>/7ÓHc/3n]cx֪%ͼ)pQjJ|8̰!;▪/R-_ ]J2r + (&p+ 1Vm"�s-iGLe +|g! J'v$m-TkRۅc _2$wCrvmы;?RWKq\4a)M7x2V4h`+Obʘ[nFreXv_T7cl{|ksQN?ܯqi9!hQJ@.IK 8j5gj~kD4T2v"/ѥ։j@bbqWƞöEŞL$b" w(f̴q{A8z{8g>;<xP[ʽUs|ǵ` 50A2~aߢ{w �d)АNIn'oә_d\D|҈8 +c$s&LO X`re Ɓ fӻ/wg +tV^\Wgߛ 4R}[:tB:qu2M/A}; ޾f&Z~_֑úZ{Upb_[dAЯG` ؏"\T )hǢ?:7w}.WcAVJZVXuqVi0=e^T͓_֪w1h%~0@-+{0˸ +R]5d"|2F*~SEo?[XP`y_6bJՋڣ|Z5D㜊{P(0a"16ν'K +;O f/d0~W,,NJWiCzT\9pkv\up &"k�0,N߶%e\9f Cg>)�Ӄ:.U~w~߼xÛ_O?]p'W{G<udSO+|{|_|_һS?jY8_PpRj{asFF`B AO2n/{37222ĉn?g:|ĉ ۅٿjIC=fE]IB+P]Ѻ捶T#zg+7:4I uJceX;�i]xe=P S~rq#іAK_n©.=[w.(OĆXØd6VH$,hg)7]Lht295W\?ќ dM>pI }^8 )B.P +"t擏s >=ݠ6JGDWfG"Z=Eo#wyG$fmO'>_;)T&80XFNK42{]Ee3PL?w-O.ϊ^]'H<v85Zy9 +q ,$P,<.=7XߴrH.aQ>s<]SWZ p,6ip֝kwCw?ӟ!sgsw/˛.} 4bR>63wk=8HCź|6gB*ݺV<6RBhmNg|DB|׿QrKY-ϕۥ˩:f],rˡ/@7]7|FkG}!GP~yIf/z'*>, ],u|RNHH^嗵$2BʼxLy{!ia"ZdeQh6 +cU#BnO| 3toJᎢ*/bÍ܋e XBVv7'Z sT#N +j΀6'֘惓zl6j5I7ͅDUoHԹj}5>)aW16] U!57.?!v6R�OED>K ח>.?> |x  ?QtzO]s~K*ɺ&\uqNXjȯ  0"ߖܽ<u0r4VJ0lIPx +UҎU1Q;>B"[M=Ԡ.g^xw"||7l ~Jyspܕ<誷d +E:98z2ȍc!oZjؔd<O5{p +ʓK$3wM?v]MZŖSDgY 5»_͝t;U[czR97l|8cQE&$]?UπC V;y)2I T xHTx#i<h~5/7b? +)'ePI>TN= \h.b3|r8oNPbߧq'I Jb"P~d ~z9k.zWh PD2 4oӔ9MH8Yf>kNRNr0GH>l'aNH]K$TXRT8-NRT=r*v+ 9pˣv%TԚ$g<vY5JGCp{Jt?HJxDJ yŌa68?+0׃y-H= a|ep+x�NyA8; mdӞjlF5*q[g!c8 P-E'ep/ʸa9BvFd-cfoIc6) +cه6+MJʃIVYTF&oU&&-l봶@52ƽ.5nc27"wx +` s+NmԩJnGRALi۫^tF7|^I邝dQi릙ŪnFKI L$dDqoCWX? <oAF9ͣ1 cmv4gXҸe񊬛An?'esw$yq};OŖF /a7Ŭ Aѱ O Cm&a\ED"b1Ҕ6~ثM̯=:dثx<R&(/*?y.득h]E iXMaBUQp;N_TM2]r*8p"VT7#DnE0-Y2tzYZr 0*SvcoQ K5(42cL11ч_vagǵqiqMkgvJE?뿶ͯ?eg९?W LoivG=ӷ=tƏ`KCqu3^V?V0 R8+-G|۪+ĩ t>(S*yMWLP}R:*ǻ(HNtJ騠)hl^25҄aQ\zߞ}cӇ/Z "_ӷ^uӵ;zPϹcu:�d$"vq}5Jœ_/!@N"Q9{IL$xr`=$>Ft3gg5~=-@*4iaX1hl>.5iQQDPbY=m'tr3ɕ+)ԃzlVMtShmYfLVNC1/N9r,C]L]eoKP-Vx0! ֥@#8nFoS7<^2:Ժ+͎)KdșejQ~b1S5}C״Ci)L]}g`dd!;|[Ej>'l2x0vގdv𫸌xUWeߛd[o0qiUF4F`k~0\/<ʤO)Jk/6т#B8>_`.`m#hÆ6W,)*jm¿ !/RbIvbOJKaފ㸍#g~'[:NwItݝd%5Ozl)mivN->k] +֊ֆEjF't" +ێ7/$3Qv b64E6<p4#4\yRV[jy0 3Bwjb:ANv9m~uPHB5m^݆Uݩtt` |md8M@gZr&fj]| FK^k ajuK lbEACT2jx%l`mb�3h5ՑaNVm"gOMdzQ  +?7Òm+%i^pi^}|%t&p#JawX!ԘGx>{9p|<n:̙u2#F;9Frp䂤0qDzEj62!zdm7u/H߲|єQ0bԼz㶳>17h-1w 37@ogRp!?9 fuBhg?}Ux.ãu&D]x8<}+ B6:EvޔŢRԞ'+-TT<<qW #�1\(V]ãHe&ä &EM/g ~"~inrs"_aBl\M*[eY7ϫ�>:tuRzoxq ,7+-h2Um7i˼W`v_'dfGvTAF/>E ~ aUoKǖ] ήoϲ*%X +.;[|&</.J95Ez7<}[^|a+b Yηo+?]0�gX endstream endobj 79 0 obj 18017 endobj 80 0 obj << /Filter [ /FlateDecode ] /Length 81 0 R >> stream +Hrںş pfhrϝON4M-#X=Bre@mƴlnN[-iﵗ.#ѸZ#s9K=LQl 4^_4[o%K&LtMqNv]ua_y g@B+fr9rdYF:Ɵk*7~Mջ\P YayYH\t1 I׻fpǡD0"dn P;a`XN,ʗPLufD!fDWּH+T.Hܲ_؂KOO|'-}ExX|t=ue'">!M<!-/JXt7ටE=]B5k(ipW}WïC97S ?9E`']iD1sDgT~5+Xׇ`w"\)?~ؙm :th/twJB J}Zq!p'yQ e1h^ɷբqoN7d (|@<(byteHL$`:=/[3]8 9åёAY̰VЪk1"v]wZE5vDrǡmPLP;á+ÀP2ge l^ּSS+i`XN mm)G&Jɩ6)fF` JYm1%DBUC/E':T;g:ؖ&?վIWGUOtc{~.ΰM^Yn>ͳ贸¿j@<h#bɛ Ày OwU^H &?__?Ե -3f=G*yEhM)Kzu%$&`ЕahOI@$.DY n̖$@}rφt|CR<ЈنEezB;Ke^"~{QD5a3yyM=!ԯ9 9Q{v 7[&?hq7Vs*Pn[g"7ťvsJQg%)7~+hf8+%೐b2*" +%0eXHqr~ISeMʽKdauv0@AOti)bgeM+DCV;78h%Rk JNKmXhJqLs?:x]/u _)�[Fe;ΥJN5`.S=+jLd0#:ABJ<|𣌾棟fvCJ[Ld>LKGCR?WF1ID.:s, 46Ѽ)s֚S,}C V&fk\sNTZMVLP-B89+B̠6#,+䬒<AED?7 *IЛqsMGXȕ.VmG {0?99[؛aVΌUڳoؽa2AH&\}c%!SOv |wqz"'rYMʍҟ@Y^ 9$,> Qz.!)^yȫ06" +%0eXHqvISeMʽKdquv0@A`J4e}!|I4^,X+;-y`)1c4.TQwMdÂqX�hn5^йTUɩE`'6\&Z*evh?͉<^&%Te+ugl5*{i~}g'?=asf]^^Y~a iEx6@s/pdg[5u=i-{G=BZ0_O=/6YSFN߸~ܧ'Bm@KyQaphmQ KGP;a`XNC|o!f5VMOHfΚWDOHulP0(A jAγA٠.`h8?9?Ȅ:ٞ +D6O՞E`']\ 0,ykE>Jklm9w;O@ClivSblY$9jk!Z00"jΛͅ)ۍmhumFղ*t;jVc +ilIYIKo+ Q(">k\qN&TMVZֆq*rVY1"ˌŴ0fDeU2g/* ͟Eq_(QO +ɒzjg8te0G"'Ax`~ٶPGD ҁ̗hj`4Y!:ìcpӐ^[oӐN*BR>5zQ! ͡;9v-N:T;g:ٖ&?$%r3jb +d'*{YBZ0_&H=/) M}TMqCdl0>ۋ}cFXOab-^g%}Hw+fE90ϡv5ϙxiJ)Yƚ9Wc15VD96afdtV2c1-LfY!gT~?%�tC0ED5 32 VUhʏNy_WQPED?i"Wj_;mQ {HAH>iJPPvkא!؛8/1`^Hn9̾73Y +<@ٙ +4!ԃi�Yeg=GʻJ4LFDB7WBD/.H="yi_i_i +RIJ')}:Cc%zĨ!!2Njܧ7輄Vò}%7ӡ5<h Q/72'h0Z@L-k +*SPiro 6ُ*)-NB.^AF| +"y9Hy^q=s%xOi&#"LX9鱟9ՔR{ۙJ1t{DWP2|q+7> <1;ݙ,$"2fMpkXi%¦"taWL< !WAW3,`-k?rkD7R}<IQ 4x'+{#a1L8РPG>L)"s6,m %-iuQ*4ӡ =hh0bv̎8!Lc"ir^Jn"CqWyUJaZ(0\Qi6_\aL*>$f4䘫4T\e +xwIMhܧ10^kۢ퀇a]5#0TUYe>bLD)PzDwo˩/@G%Lny-xnc#^Fh552*x-72*7+Q>ӏD^XʡkB~1&u +k,W!oMRw7*}\ip0XFzg)a^yxk(go4LLp&ѸM;]Hԇ}l" +y(r)`3#* :7T~ӥ! &2)Pz]* }o9nRPfI�@sp endstream endobj 81 0 obj 3856 endobj 82 0 obj << /Filter [ /FlateDecode ] /Length 83 0 R >> stream +HWao|#MC'hOvtSelg'`ҢjFpcs{=w: #c= +SYҰEĵC>g>ch}m<=wz G3rB#J猌SL< CՊ//~dž;4\~%G5Gbx�dpԿȣfҺ/I1OM#O,) Nky}}g?*]hM8^(MA<Reƈ0 2 4*"+#"{g K"dE/ +3Ijf/ mV7S€/W5RpЧ[ +;\{?*g倪 L Ǧ > x<P7sE&wҊ-($YOŠq; +Gn-D$R&![DxlQFX4U*S:<þvhϳMDݹܤl8r6M("A6jq**'aXbUX193w*򠪵̩T78 IHS5|| 4<2udWG E{IQH"L sI䮛NP]F")V˘Kl<pRYTJo~U7"f̀e$ƈEO"DX! W5&B?!ȁ,v\#"ׄD+4J@ƟGEX/xH)J'"r3 t$p7!LDGb +KE2tS:iR݁tܠB9gDUG4e.q4ht+v0"пqĉ (ZP; 9f߄Tf:]>iE:` 7ϰ4GwMi(L�ȂK*�<f>W2Unt?[#_|~Q]?8g5C>-# * nC].pH<do[0f f&!!+JkjjJC604*04ɆA04(MA_`<=d( #+;fq%ԅ&'H~O"ƉkO*JPd, {]uMeӛ+S@=<@�ttRʫ7?)إ!Rv- +,*̡qܿN<Dc>j@1BN$ c�ڥ!hӑ2E64 ZPLĚ)<ݶ') x[V3i'wkW'E<{?b́PB7c + FǀAa p LRx-^A.vm^^`ե"§G.HmׁhHg~ڧ4:N` *ltE@ɄsqnXy秚9oF1vzł +upXa%tQjL6i7p)@jsܫyzX|aF'1M[Pfp흗hY*&#28@0d4hjW&`~$q4d( "vwHT}ѶG|?M1ƒ PjY|j�h z %־zt@>V/�>xg PeڡAC+҅whePo.1x ~ L^?V=�KQG. wX>C.G%IښqV8)s1ZVc=F >gT�( K uRNj�b$p7!LDGb +j4E}œu +C+^x58.V1[iAV4I<�QȼVK''HԆAy+\~UwT2jWm�jxJW {ϜrG@D-nr'1MWyIjv)diwa0Y-bYZ2E64 qxiX3'“kJJ 5u 6 CQ:RDpF>8C)Hx%D <1o2LzLЀ0yQ. dcY: ||2 nUJ<Wӈp,HT5,D〸0dDhT5(Tan%Kʯ[X1/-ۯ7+Ne9l>M#ktO~ӆ!.PG/nMw(1Z 9f"•S.4ĢQ͜ + ֖Ƨiy2d u|DW|h6Ӱq4}nZ_Hv-f5<c&K|)BZ[?C&6խVumͮ&Y;{=--_k)],Mg+;mn9ve9Z[7;NNO5v/[jNpb3;ن%xD`m VWMkgkǖ %wurvG*X XmgwLq#+V/ z2:sZe88aձ)nӛۦmx,E4 ZYNqזӲAKEw]qq9(edkma{y<m N%mכ#ut̏Ŵl!E<6/ A+8۠ AWhɖj[8Owo2$9$W?@BHYAH}gW6!|sFV#]a6gشOPmȬ(eƭftSʛ0ӢCusi+,Jfv)IM0/UsKjUJKTn7Z@9U5xUz*phg bۂzXPVdTŮmin�4 w.QvQVH~|w4pjƵxF <6J@)k],vi ++z|Pܠ_yڛÞ`$kM$yʃ;)Wj75+H# XgXO*!Lz 먯ˈ2<(.LN+:#\`J02=j"ߣA{sQ JL�p=5Nn_/0M#Q_W~X:&jy�|>)4{fxJYNO6>F`~bA7)4tVAJk+B3 MC~WZ/*]Ɏ[)H(~:礂57h?}!&4/XxtJ*ژ4Ԇ.\T Pݶ-DYhξ`*C/Zڡ#a-]klm.\G7\TƑ5+C^T)kg{Ij_TܴNpJat4*8?٠k!q<P"S2��#ɑ*^ in@I:i(,F4aСي(HmZEp)Hd/n;ðdYۛ:Jn +Zp}Adi[qmڲ^A +dL {LZ%}3~dV$:RG 8/~9Jڀ{eN'-z$# +@qkq:zE7~//E']>dTKD]=zϺhPY{éKU'@JV϶'*/P[^I%1n *+|3J F@ˍ z{\lIgl"4YU5ҏ[>J>4ZZtT<Ku3ZԽafs=)YȐ6˕. G3 i4O^A'=.i+FTeawνiMJ1)]kAe-| (v{._DlyC{L`iS]|&4iDŽ#H͎ho#盜B7mƘ]F[C,Mjʏѱ= N@j~ +PIYwVūcutvksJ50FuqJ$v +ҀQ;Z'[P(>!= `C+ՠfC$5ŧއw9UHHil-)owç/???"(Q7oǟOO_l7c7/q7/&{:Q hƒױJHiZG:?@5'aH~]ӧP󤦬kk}-^Nj+5 ŻTN_{oc CmHʦ.yO"Х +`XY5`~8UWqc1GҰj-. P sNl`}4Mr쫋@P!`5Yа (]8`j m%-6@vVg7Tx.N\;M}q<a=0oIYI8܌.Vr67)Tj˂_rū�pol쀉Z�{XnK<Fp) tL滰M5Bsdo㛍yyCIDG'yq72^6wg)Aiلӣ mYY\/R=wέn*cm/sLZz堁lؗˬ ˼}۷w_޵Rn>QWW`o�IXNc  +6j57Jx@Ppp[ybB=ܕGEٞ!-|;׋6*ʏ{OnxZ ub(JѥqZTyVk…`Gzdi9Y vj HD Kũr3ZtStYxRm"{zCE4pFlONt\„Z@ٙȝ:Iq,٨&<l.fCb;={jD%@vt#% +A<.s4Nz +EZPV²=y~e<}[7>-R^ j\[һ0$j\h11'^q9jr33zY`6W{Lɺ˥˲�}Kx"7v+> rD=0pp40Nu+E*H Y[cbh]w1ɲs &~o025ix)A'`fهd i\2L%u>`\ qnjϻ `[{}lW TgS?3,{R(_leAO9Q礳@q/f؛ͬ6"f) `:kFQmWp)>ILv&SU-W]oTyA2jݽd<j!R!c 86fT3l qMuS'|4u7)*;5…K2đrD .E(]&5~LG2e$Fթ&l,q9yIiU3; ڸ"| +^o@A9W"i[uLp\vzNM)xG@g E?=}ux;8%>�ß6&)_]Knl6 +և\/[]D]b4&I]D ^?\u˄ϙ#E \j>J{$vIZ*jwQԨ98)1/R +{F3#sN.룎ОN!iٖ(uBޟMGŴny޾,?_\w>_?掯7o髋o/ +H Q fD'dZځblcٽWR!]R-7OuUR>aǫAltV!= +T~WrNN`ѯ*^}r}Oϟq1M_\'^^>pp=TWy]2UxEYxjLAj ={^3]6%>Rn5tItkE._PSbah~C^Djj̣?ݞ8\?LWVۃ9{9{g~'~yΧYm# Z ݪK*\ULh^,gdtJvI&;yԒYQ^&t@lM�Z(Fti|v)2ZHoԇ܆ ,'FM>Cr;%n)* ȄejMV$:�0~:Ls)jގ2=<pEҸo'F3 !žS,(֝& RFR^M%�(~vSb*0qdh O$/|1Ea'2Fkcvig"hK@KU2L)'dyF*LSbhhG[kz&6c7CDl\Җ؆6q;à U!k΅JoW0eFK['+G3R*dtH$etJ(9Z> :lܿZ(J-RK˪1 `V'ؼ]/ s4Vt|fUP߹ƬKbJI 4V{%5x=A?s #>#T`r}g%JF]!' +Џ&0 +Ә} j~@唣m- ӥ7N)+%DXR]3bJS*8U)R〚4Y1h^P#Pb& +j.Lz%P~@#65x=WցJsi_FmV M۸Pg#Gծȼ) s-4֥p&J̭z%g@喣m51,K-eIn[&f )u8:cVan:qZbJkt"i)}]e*|jk ^O$/6B $2|TD8QB +CKܕ.SFW@&:VzuJ@aUͶX +9)hky ^Op :WO)~-*9gB4vv-.ok<,s .YWS"lk>LWj(]02xL4,zJ,:ZJ3 +) VrE`ko nPudeFCgg%ٶ.:ۮ^G`R%|̠:%sa +@;ZZ#U JX1@pV=<'VųhJVq�V 0step+앸BS*hky^9b:{-M̰%ֻ%нu}0n` ZKn}ڒ$)bRiюRF#&G oS&edz 3>{3<N]\k@J6* /H5(ttXYi~vPD#ϓ-IZ[KÔzͲpW")V#0P خ(}fsim=+;Ho%o) "p/4o'8]pIJjm-MS* wXl(40+h( +gQ+1<G`l:$:=f@h-Z:eRFk*[FS͑f|2H7"N$rJ@%tP^B/էar.cΩJ’ (=vruM]Ln屏I7<@XspK$ñE |t\+u�Ɍ,}lI'u-]VDC"0P hG!<v B/iH whC,mIZ9UN0Q۔ς=NmԬiMx$q$MY[U*&VX7Q4%Mhִr]@GR;*i_ Q:M3:FVŐ+QK �*ͶQ W-Z +CVDK^X[2h;z=(|G@gOvO_n>^}r}Oϟ=@&?/btIO?'|=ۿպ ΟBC3gr JE,)4 ۻkzCH29{̬ eoNwshg_On^>^叇'OF%هJKꨟtM銰9<Ip< {gdz92y_p+dLm@;-a:XEpIz%/a�WTSUlΪ> sPEqN}A,.|-';["=RԓU7zA7 +*)\V{# ?=_S9^4ݿȵ]moL|<Gop)`SZ(j#|+E=ݒV(Έi١鿶д̤?ERkXu7h4ςYշ~Oݾ{_yz~F(_~8×hVd3"~;ly$N$1mᗿv#x|qTap79%ݛņAغn̺$},&uWZ4?ͼ{"˜`V^n( +xC;7>CSqtsAMu'nш=Ӄ�|.-pۜ`yu͸@.l&gO}A^]*n5$X{e f2` c ttIW^8%6 ˠd [Fqf i aP2ucԊ)(c/ѤAmHQN*B +)Y42uѻ=lY[ޒ_vph2#dw=hR +k6aA\jױ#. vu8+# {1Eah@;zZ\ǘĒ6+sk6E8qt{L/xovyn {aa>L[[<بiLHoJ'K[Q*1=6~ԇ?*N[A6 =*H~X%f"J>*-+j rJ$(Eج}t6fs 35UI'<j(ܻ9'oɟ1 ػY~)Q_>.g;(AK^9Z>gk=.YS@KViwH|qpqmg˂,8y"si�>rWIB;vT(peV1`V.}dϐ'nLyCfG}P$-Ft{ 9"(>.kA}m( +E֢u.Oc\5B1@|nqKAPS@6)/R5p微උi蹶;;ƕv<E �.T`@D +Fj +d)arfu_~j^ANZ c6[>dwfvӠJEU (=.z}Pm VvZ\(tHlqk0,Ԝ~lf/pFf.. v۩,U^7%CZXnɞ18ڪ0$z3c0=ox6TD>8 wB։Uh *yb/Cc0Άe-: 0�.! endstream endobj 83 0 obj 10155 endobj 84 0 obj << /Filter [ /FlateDecode ] /Length 85 0 R >> stream +HlWݪG}ߍ\US] "E"!o謹c ɜYUDo%kϦT]%so] 5G{оo/o_}$m7>vݷPCظr%l,=.0&3!{rګ0$ox>I;smOj2:=FB{_r^xMKwtLby$_|h+\wھ809 {~hg7ݺw6y'8@<2Wy9;,<.<,40p̲�pO4yQz'<^3S{lj3(C<[;M8xۤt$e=Ӊn^SySf~KtÂl<m<s"zKEH2dea"!m*8OzWKzI5I8]f̺4sAQTWUțuV9 nNGD| WbJؠqZ^~Fϩɷk +n@`e>OY}Ip! 2녹ZpIDOKY-XA ƭ7-6V=qwB|lVe<tssP[>*v"efΌue.YImg=&K^/:jBs '9Kp&NuHԂ5"id)fKW7X:j)aZ՞5_ɇlr^,V>}/^_|y}~W_~~}⻿Do>}/]{kwC^ FuoxE njÏo?/~?[anj47%?{ QoaHH +lqߪfF}pV {Ky_aH<Qgaڗof�QQoVb0<#>b=^rڧJcN-1AbCl98,liSiEǴy8Cф"RKʹ7}Y'Tb[~-B-7W6 +T."Qf~qlhcuTCv }EκdBYLjSA>%yFVKx6ɾe�MZ!ւidc "dM fPBY='fLf $#J4jNA4ه+\]B> #:E߳'[bBI*I+zˏzQkR]7*Q#$1R654@|W@�j?9]/I"I�$<6GVc'+ frHf4[]L{.% |Ѯ>+kk<Lm m욋ʆ)U=_{_%(u>+:'<*%Gi:351uL?tz8yϱr`,ZBޕS%,VG `m!DNlRB$Ȫ8_ DA1Hβ ܎Jp< Lr 1I$̾+ !|P{vs{DuܷGטGL3F>C/{ֻI;ޭ 8Q@R[LԶW},iN{~# @~YY|eM%БQkAi'5;|*mrPME;q +ܟ*eQe JH$Ż J%A+�79iߒ*I{"0VYIqN5 YޢY;B1Vm|McQXMi'$ϚP+V\{zsΎ#Ul_ qNB}ͺz `LO죀P =w7at4 #0$sQٓxx׿W190) !顉s\ѽa;ic8IC|[g3rKWI1:۹ht4(1RP25}h7b_-{Wx)H)67W WK&$ON3}ǤTy -V)GsAYpq)MVi>NlH�ZV8=xJJc2M'i}6V;ShIc釀),x͍J S>*g!$نM)jՅzøBL<a]Clq&Ia(y$@ F<CTƣPZ=@ y:sGv +es}LTV@UIuv*EºQH㺏 hɖ̾F?_c^3pvxB}_#A$Z @asU7f&;F鮂U=syl +S(˶,{jlJ7bv%Lә@!}#7dY::gƨ:iAjdQw^Tǟfũh?*0*j,5}&i =�uI �mi .#hٟr=!TOyRO4Pj1$!JH7tqVY>LX�%Ҷoe0i+vs>oD�-&ɉ w +a؆ZbHHˆGaͬw OII0) 1nĄ[V)Xnk|j?W .jBC8Ѩ +Zv~>ydCFB(ي3Rɟs&gt'+ ;m:7|*Z1qQ)Qv|ÜY�X˒Hc/~U;ᐽ -9ktTp6c #`C,0> h$O KFb?I!k;`1v]*TxWr[½Q>o9 ` @3U. kͲG6+fiDgv8(v>;buYP".+fCz~*|Hyxf́=@ Z`VP>*}NMڽ PP0mtawRks!$6k\*C~pXT X}ܭܨZ%׻[M}+κ(ؔ�O(N[ +ni�@^7ϟS9|d(셱Fl;$ ++sqBzѿPJX c~m"q㘇e)tpǒ bx�{nm E<?s=SyoDJWRS <Zz^z٥R3[<ABM N5ʧÖlYvd p۵bp +o?}O?O_~>˻__?>g;_o_~}o$ong!ۖ |}>~|/~B n]MX֬ҐUiXW"^D]*F8*G|Pr5f^ÞMQ/w5yj$%8#Q@k&I:K%!ȇ \G=T3UEgH nb{/{Eʬv +ZK4M `sae6R`y$l9PĴx 8;-l*EYY'E!Ҕ}Ab5m�0W- +j$~qK"˪�F}kNᣊJ^J*{@(i +'=44,Shd(ao#WmNMSA=At@kHЎme+5lP\U)aveO)Udki/y5YXrkT@^LPɩ%rTT"4 y~b{՛Dgҕy+#5yQ.迖v N[5W}b6׽=h ;pNcP:m,j�vz}Bw/0._{JrSUdyenN&>8vwzeL~)rp\i^bk̚i9b~,UUPd>5hŢrڬ 8ll좃%L0! `V;JLGޑZWdU +QΔÕizQ=wH貕k+KuҤ>oDAH]3xLD)IL5s\ϗ%kg0>4%{S-}w5y\WTK'4T(j`i +3�IHL`Wۍ@XMJ.߉P&$rB)z+fi6kBX_97=aM~ ~~VSVTCzJyhNXqIF1ۨ0"5"FI8�6 +qW8mbUh1/ʥ|Q?-30JU�sk{\Y!\~8kӺRBo`ӓDXK=Lk|-<L +�6:`o6KO/;R]YDam1A <@~E'&dfXXi$]0L1;jmH)?_\i 3'j3vH&Z\L0b>nV|˸S{i}6A!%MF%Q|px|~?7n!y|~ XUnw]2$+E:F9`i ȾsxҘנbv0W)oOwV!::(Fڐ]XǦ';8{{yu ⾗ +Ll8]Ġ"vd6@{UaD@]ٽK@Ŷ TN�8t̽.sf�1 u Yj;%(RH%Fb'\E_vW~ +дH�uIJe{eY83kL@Z85&NT:ugE$ۙsn>Ĉ խlcߏW@jDKsxCa]m@LE~1j7)VR=]1dfUV�מeRL-0#`O?^^AYQ&jWe)},U8?Etβ^`YD0^kP\ih,4\KWMh"jzmtݿ_N k AJ0mTكFU إ- +Z ڃ&8"gM{i'/�Y=֓=~c@t:S묞g88fϮkl,�arZY"4�'-{Np٥Ǖ_`SJ~m�0ti' tX_&f03=% +(?Ϯ1'%MvzyUOd&= ':´-tzɳ-uqLjMQ4ӳGTŤmq 3R}FU #$FUB7 v&>hKL$ρ]LycTvRZ\BT˵Lv~VICLC~ojUiPfXuSt |lP{Oj@yȩaW r4%�GodfIغl [›k4ŘX"w5NRD* Ԅ_ꑏ|,-pvEMOTG]oاO p˲ghU^(ϳ2 jR!AەҜMl6q>)_`Lvil +3- `99J ؃̷T�j hJ0O-0wwwӨƫư +)�DDtz_>E=Ou$k(JiwĐ5_{w1ZYiA2]T{[ߖ] 7`U~E0O} <~7^|.Y6D,tTl 7K~Y+26eHGqT-W{v~S<v25֭}ʻ?5,*�YxU:k^tʱJu`a +ݲ;hUG~I?oiyi̸sػ*NK[u*i̋62A0GKIv>=/FP a(+’FHe1._4ȟ0Qe0u.5ujTg i7֗wSdY^4]CDXDԸ<SL}uFfCp>IlP«H lWk`n痻8'v6ꎤS'S)Ϝg##[*uRT^BLtQHd55V%veC;]CWx\W? i3c$jO1+,ӦHLp:@mcd|fO�3oKaklE1(rA{V~D rm܀VZI[zZޠ/B _U +n ꆕ&8! uЧe"X *^kD9>fؼ/fv/j2Ӯ?qnѺԗuo}+0kNFzAZ[OaDDts�F# g%9QX3'!~>e=ELDc;r$ +|;)pAX +&:O.m~Z9B x; t�@fg�?9HX}6n!3/juN2vh3,AGt!{ÐfZޤ-݌t|n?>$Hl56.J~rmm�oo݀V~w> H$cDQ[WL|ۅc%3 ga퓃dP OmUrs +0{7mF}Uئ6z:|?F.oUཛ'^9B[<O +D7<G{;Q)pՠi b~Xn^}%I)}Ѥ~̖c-:6Tvl8 kI,uQ\ݛRp1;a�#0/2vNVEk 5+jv C*Ըv^X*f&]*#xsK,JmwcgcۗM'ukXt3#+|? uPB%)tzQ'(qtdC=%AȿA-[%jЎB#}K~ gS?wIǺz&9< صꤽͧL|6@_/F9݂ ́ʚv:gەVX׾@(NXC˓\^4ض7pQWlmp1pmz78[ۤ7>|Bm4"0L&(vGaf/pCv\tSj۲Y0 `zy<i #M|l^;A*q]578,K`e;.0/)QE_,[mI 0PL|n+e@(mOz^znȖHJDlJ5 1}Nyq"?cc �N@Hܞ`{r)A@7)17;ZJb!|B? 1Z؛Wmbh[qMrT Դ0BGx#|(2 Eԣ@{Cb^`VR!XU:HYD(-=Apێ)UKԡD~˖NI`N 8v7 #*[`6j Ɋ\Y zQ%Zo P8gO7j +#Ҿ_u(^bPTZA;\+Yԕ%79`SYVC5VO8eT!fFt:%d4S?4UҬ�6R7s!K!-͚gh9Bns4%:{i`i4WS^}g}NOo)a=?x+N.nnh̬]b/ +|=ud{,y�sqϜ "#îNggL+UA}Rj5HKFNJ +a ԵSk?^r!RKŵXO1`Ev� +0`<q:"<ʹ篂))FMyĂ8N�I3l/ r6ieNgYz0c .RW o!~Kvdz:vP~5fEU ijxy.9on/p5q8rO ֞X%0 gJȅ T+ԺƼWS`/k/)7ƺTGC^!XULMWP$Xd3bvsthb(6Y҆`bzj{XV +U?'' QLCEM%Zbh1L1ZX>?޵-SZ^R_m�V񤀌 9g=iwo e/Aꎔ1Fz{� Dx�AUm~�BǛ4n=LLp4dZ?�ԆOKK% f se5tk�coQ(eSs�Hn�ʩu9 j�5wUB$؃B[mzo`-' x?ZIkW]{8U뵻g}=-,`$;) ǠQ=ۭ�l"6j`.+cb7+f#)xSbc[W~_!#-;.g 0xnI P.vH .OAjzvH%h _#=]ϏzÇN`{� Bk{r65ZMh͓�ji0G7|o?>oUsl$KTr;|ir֛k<=g7xP (94lp%_T*ۄ[AK 6ͯ6:ka>zp$>]/XFܮj/?UX'uXJA=HOQpaC<ҷT +eT0Z%fnPj^n:x:R=K�O{9hDzbmS]?pZU0*05j>w;Z. \e~&rH9c5 mU +�F"䕯q�9xW~?/f fId\ϩ U(Sޫ~驴A7mS_1(?WR̳EU~4??"[8&LƑ}}**;/GIXL&]Tc5en |q{p/ͱEɟF[kh>moTLrMpbɔ4=n~ΏZ6jPJX}մ^m`͡�sQ; G3cظ~qJY-LGLO>93rO}]>��J\WZ/5aK 8FIR'#OI:No#9Spn/ >wBW .^)ϲNeWXfOwL9Gzɔܐ2_?Yz(֎ֺt+{O()Go@sn9sQQs.ن'䱻I]1kmrnЭ>voO'˚|Z*<A@f| +;sT=gW5:xR +)lr?WX_`JZ ?u1\0b=!XLqջE:�e/G#ZJˠV"yWK\H'k4/aGR9ҙ{5GF~Jӗ$J| ]++'%ؤ=}G 3mkU7o* @-핫Se}ի(5&(]lc5>jSkC uESiԤ5EY,7OK)>m5QSHf%?eWӣ> %" +@l";4lr' E9ۮ&#"60Cyf + +9UҀtml)^r,ь`LFc ̉ު3튃Xkٗ`BƺWczD<,hr vX3@U-κJrM0!VB!RkoTY=v0iم>[$ [̐{ n7y} ӛ Ʌ 4J^}=\>&n}oj.-o YAՄKH({&Y\m^#kW>K:/LjtQ|w6}PVZk+FOzcK8# I<<ZW=hhx,V2mmqFKvz[QʥFsw\5*<'4V9apXrAj.I# +> (#d &`# Gm| mw bVP�ƸE+r�̮])~ +mϦWm 7`\Z|ׯ-Pke<𠫵tx׃g-y Ɗ$Ek]!Y>V0S/t.d 6uk]d[?=Ȑ7K1DZV0'wY 5U- J@t`�TGqp̢�GR<~Ou.7' xdVL0p 0, fK�&:`"܏4 +g%Fz),l24A߃puKdx'%ˢN"@W.E:})nXfwqr`zl5t3�y0(yi$}ʞL9'a88׎嚺Jb}p(HaGy}]37ASۓwx~}*P|�(w3YCaQsxxaν `jss Ϗ(U3X^ +&70 8hY+W*$7.߯tIo$<w>�kGp^]:AGu0RZE 6Mli=�PIo�.x82e)fl}6ViwQS }T;B:-*v0:Z )"w3fÀs�']->ȹ3ϝmΏs%)`~/i坮dWx5Ix?* _amz5 }~ZR)lSUHKɇϙ}a!s�pNGFv*FtU={9~M&>A4qOIaӷ9.X+tǔ^XY9&)%lKg>6+<q Φ8^;3L&8a�ڋ�ݛ�7عm?{OraʴX~Ovy߇) 3D]J<9%LO K$5QA$o>'|Xb;N%3`U6]kv~J%L&(㸎b[[L5+^*ՠ֪lҡxt[jY +K_)Kz%ŕ7ӛ(GjmT$@ +=_4,7 68:�^ܭ 0bddgQtŷ,v5/<Zt-i y!ECץpk[9xk_?cK:U<0Hzb.^,N\`icH̫cΥ/=%9<UcwE:)_7BUNluάu1a: OB"8z$|S[R12Q:;8/soo?ߟ}巀/|O|çݗ/%KO?_08(ݙa/hF|gI1qd_Fx4TL'`ۻ?}[y]ICQNj͌0'k̀fEf|�/1DR-4#5GZ'�<0v\M +#!@*Պ8hzzT~:TԤk[&]:7.a 'rwԲI~Aj? jߵ6yR?TmLਥ0NN$Y>:.*8S9 d!7SZ?FY~jM;=816z +猠ګdlEv +V!.e$1UԖtVY(7e,iT\[_`|pVjaRעwZ6foΔYk5Jt~Թ1٬VJU Gε*Uc؜TbHW =2v<#գȭe(y1m<j@c5wfĤU'z_w +,c| 8ޓukhq(%޻72<nXHj0jy|A�+;rpVOf۩vМ;mh_jaGNT 'USgzH2Uhi|[4$mR<׾Ի5qԦ~߂h|Ͼ5B0ת4 R`3ǪIykE:/%CZ˜jo}b\z6W( +sĀ|&Y]nǮOw87lW�PdƖcL"Q䷧jCܡY{^_|ok>[ڡ<V,$(#浐|n.h<]܇Ǧg2gwA:۹=^m1hU/WxvQ+}- uo'V-ʼeMVC3qwt +H*Sѹt²- =( 3gԗwhe3ٓ doXU)( O0!-CXKhvlxuW0: bθhbg!Z`Z%�t Y_46� +Zp ɘX|Z̼fE&2h{:Cg7, Ve4&ȸV{=m EqF '{Vb7xE �&ƍ mmyT1n=ޠc7I hPa߳#oqz0Fy5sFLGm8Lp' )zQ5wkOa;fI,1[v{L{d%Fv3A^dV!Qʅs;qƽ!8oֆr(M � +*R1wl*BE#]Vhxe3{:m\ nZvPM[l麂�oc}fa-zgd?z)5AC6E3NQ&H-F,?ھF-"5M=("8TA{lI{$ +rP\AJ8**ЕI[SWaFZx`>Ԇ$at 1'VedC>h(VY0MMUG0ppcrd1(�L6mt<꣭ kSctB](`0_Jn c"`$yҜV +?kB;p :Āzs-cYK7QV~S%`v\D')m0)eBo>ZQmt` <6o~:.ı@u%GE.HGw h }ܮ+.uV>SL#bc!v+6F h%G=L6;n5J2rEDBAR@聠)<dPNNyE~晃cSz@1\l b.̶oajk:t)Iʅnc Zl%`3@x%6Pz7!$*G<<G#bqFzVNgdڔ?݋+eO_gZ9\WY)ݤdB3D'aE]o'kELv12 tn9Bt.ߕtSBE;&;]r(ɚSFhM7C8@U<Cõ?6?6|ӷxs/޾O\>{훇חϾyëϿ}//}O.KMFnnc;֖n7:[QLmSR?ei2tQEDPzkH)CyO㮮ygu +;LU `, 3f~ؖ]F\[!yf$[(*%ibfJ&fP821'FnGMPLI m{U! 'i,X?k"hfBIswHs[ *3n]y*r6yc4zZ,VEf\3B0u MH&ڙ5+fyMw ҩ9Wx^4BCpUdZ/M;KWv߇ձvz)-Wŕۇнa{UL%jj1)55nLYS.S=ΊwYt TW猥Pw1o9:"fr4_ 4G׮+#ܱ4 + c4:#Ì|oWILXGOEElS1|⧲N)4_hL^+umZ)tMfT ]9N{Y|1-+q8 NpyպBFg{%N+hV}lxsǀmj ϖKM˹k_AםyQk,;7݄'bdYDze'jZ_`XmP +;]vXo-۷NC&V�m\LS;x py}TۛrK}h8Wfg.4{`.Qk´yN<t֡P%*?_?T85xzϦPQlMN)֤�Ģsmӵ)G 5%`i�O�WNAȫ6'Iп1O=sWꢊ۰df|bY4 +)OASA+TySE m[`_QEaETE}Q@e�a:+S^Q)lf@{nr&mMaor?&?rp|4.\/sw/VՋOpS>яՏg>:ӥ]_n+xm�m ? Y!1 d0'cz\{3W /CٛO,o?1Ե}<5&{-3">HΗ՜FtZ%&e6r 0ֵM6dV=2_eW>D(\HQ$g);dA,G +o8XvA}3LOOwuɱ(B?/~HPm|Nd0MX^A%u[> BJ\#!bC6п "-|½G:ĆAPZjJWސ+jh׵Ⱦ+o΍dTFJˇ{m9G2>Ãb`?u"`SG7@#}x.JYAAjzH'}"J%([4?W<Wb+B$^cJ@܋tdH٧CR4 \'x+K%)6e8ԓ}D=<k`<'{,@R7�6/Iy3 +k)-( { -Yk\;Y4 |[/@ +hKe\&QhgXD3<f?&V&*TճNÊ9i"(:I^&,u掷JŽ{9Z9q@S;F +ϳ +[ +2-a%Ψ&Qnk)78.Cf`Q3seb8ŠgZ +qD1> .Qd[18R0B-{! + uT(ڛ>"͘S.ˆ(vim> fTvk7MS4?Lk9IsQX%ТV>a"&0PqVhоꑍ"KO "ԗT +3f/7%$PaOJڞV#T4yqFYD׶3J2 r2jI+ *rWMM2]`Fg X-Tr ^E!B/Mh=*'Jž+2]abD\5rRX:2l[౞\W Zf{bm-:k] +0[IL' 4EMD(.@{ӬNO7a�H6FUQu�v +b] LO5E�7[[pg#Wc{3nДE-?/A()zAꠏ"` ڞ`T(ܠG]<A*cIHQ3{YuNS I.}522d ".UQe�v@8VTGn;k)%& +35g]E%+ 0,_ʚ]}Ra?zfCÂ)"s z)g.=Y=S)mw$$% +uY{tQj|1t~NCp-eJeV{An +Տ') +"x%S^븤VM9gTPS`iCI[M{U.)Y9 04jrG]Cds)'~_'ȒjMh!KaUm4cy12P5'T{dY Ud*x_+9j`<nv&hI.;ao禡 ocV�g%IiM`ev1Ia1rgݥ1a(._GWsEvnd|ڽsJ2*rcD//Q~F\ӽw3@�=0}l] NjWki8j\bv,rz8]h>& ޛeDi/%B}K�AP7u:X XL: 3e%t\5FTV`mNQ! tAm쌦"#h^k_q3Vԑ b,Gk̑;#lҶ#�p˴6x .mpWUZs n6~6V}d +`RVjh&)'y/?}/}go~n=^|OK,{o*yToO>;at cJ"xp[gd%jþ @2:L]ANbenu2+ѥz^VQ0lJ4ȬؾI9-֥RDGw_!9}W/}/_~{kVc9Ȧxx3VZ\ +0}Qƻo)I@{ N!5̾J4ՠG6Ep.C2 d F=c~t21X$wroy[//}go߼}ٓ?QEo*~@~AD>ǟo=Xw{=@=،odP<bv]k]pyQR 6B]5d{Qs)k2Ϧ!lJڬI5h*KjB$A&61pIBʮj(s^7Y9!*큋afŨ�jEZlc>?0T4)ԆҀaac R>FPƗcsךx3Y +sކ#ZHj],dHm[nmB1A.+G%A%$W;InڠOJrϳni6_ޠ:kۺ(t +3fv$(G +*0|-f-]K ğ"]fU؛$ =%L@U ^{52}dڬJ7BLULG4y'[:{LJF�7ն#ErD^@ٌț^^-j`@0kf@h}"#"_^,SUy8Tac%mPDk12- _%gn +M2n�99[oINs,@V2l$\9dR`|.$ {3B) +6V7 6l1*>(K³qIr.X؂8lU'B%Hc;gzumࠜuZ {i.*bFd` 00XIv^ g +%԰cUdBi Qs=v)Qw[J CwV&Ɂp`tu0~�NYJ[#iM~=bA0 :f|fl �k %ߓ î/w-O~ķ;OW/|~ŕ!wիۿm>݇0ՃwFWvP_qH$X dĥ2Ʌ@!r4I0'_~혗 /-?2#-Nt?$# *nnoKvo \VEqC6!`J`{ +<}9$\p}(:k3bkGxf$e2La<3m:Wqr=* C0;vrPut=GC8'>XIuf3 &2mn{F 2GXiW=^sᛕ!JJ5E޴UB;L1Jٚ4RkM$Gm57A;Nߗ͵DzD m&Cl1[Bgﶻ=>8~g'<cҁAՙyL-:Nhf� U6Sm +`hN9-Uk;0tn0*,nDd\R S=(<ړXEz 5#x*E'Qidj0:~t0[/`?18U`A%!!YI ԟR<F8?8*$s6='#,.�1ڏP +.lE㾓( +ڵ19JBZhf.IץD4j-<7,}VEF@ݺ o-jgꝢLѭ!�Ҏ|Grr8HB97o51Ι-0mS I eWiNqdQ5(Ø. +;w&m<JIA'ZNOb3h^rVM塓KkOv?ɣIfZoib%TAU~knC6cbִm<͝_H8wjX;*Ƞ>nmPqLhY-ӏ$߂im3�lRt8 HeNr8<Tf% %'@idJJsԣ4"!f$~ȃDUݵ*D�ЃJՍݐ y; ʪ" b3CW~:[ �6!€-ʨe{P2ڹձHL%σIyI'Zs4@VR2П)V<q"Ki>�*-%юJL* %V#xW +JVJJj/ί/^={i-_=~qjw/yyϮ_w_>>{ӶF.B4jRJȱ˅o0FS)q1h&3 +BjCp^*<k;z[ʰZ5 s z r% +6DAet"3xu>lxI[S316*i$i +6tRMIr*Ft<U~a:y,[|rGϓ.ӕnP'[|Dž~ 3t[q:-M[gD鶒AJѭ32t[Zn-? i7$\:ֲ8o\"aa_%Bj2s Jy8niQB)FV<h~R^=Nqs\rZY&wI 5lL%hSDN`&cГ↣BlفTMX>�1[ƷĶZ؉E/4RNPK#ͮfY4%r霬AUs6/C@{\C}`Iv̨a-CYrէo҆neRǤ8~0"0H  ,)F:ϹF2OɈh'NޏMcr&ƭ=`뚻6 N~V}Bq8XhG ^O90ƶ}Ǐ.nRSw, 85 aHM=H7 t',XXH,iP8J~NR#N n 1v1KTAQM{e!&%X@ ,RXM ##9- 7@Z֘@9UB p'Ilɜ&J, +XQPP= +uLpQd84H8:E*9L%(:\@  &6 $$T[sS.ś5jRBXȌ>@AiQ&P2v/pcɓ�0<UOFFrt19h^&EO6jXZFP +Mb{7h@U3edK- _`OM߭TU8$hoq_Gc׷pCa460z+K֐--> hEpJDN _F`0i #:-dm_Y+cH7fL`݇"rͿd٨glU;IR�w0gVuxNV6 �|Y +k;2/3j؊W~v(rguI䉻x XA{ngZ ȆAN;|}n鯉JȌSE"Oj|GENXl~(G1t??t7YHELtC{sbNmGڂ{"H1尳ھ:izEWgۼL%bVF{-|SUE3PMm`]ce 6-xi|,)W]jgM<5QHY=NHق<xȲEbFY?mb<⃑n2Vg&8o" ,/<uJ,Qߑ,ƓKD۶о = U3|9W+F޹gr 2NQLG"$XHF=9gV&�-J\ϳ󽿛<i̦޶AG|0? Z�a4 BѠ3#> # Ii6#1o!}yt@;M#Q53iLAj%,٦4Vt g1%=JPLJw]�#�^ endstream endobj 85 0 obj 22908 endobj 86 0 obj << /Filter [ /FlateDecode ] /Length 87 0 R >> stream +HlM7W= K ~D)WeO7Ht%@/><KZʟ?JFژ={S*SylUlCЦ-=b[ytx4}OG%ׇL*ORg1؈$2ⲻ~of߲�.%u6g2#GS"-ZŸo v{-Elޟ֣uT#_s qyA?e<: ,nq/yEʸeـl?G4műgYIn` 4DMq#RS +uvh&)Bfu&e:[+<o@zUy)"hkMy?@B&�p~ +O:?&%FWv'{6̋6Bjd.ߙS|ԩ'!GL-. ""˶s i)kR(U9(L$y\EOn@y*/i7*le㨘Zg+ua'IA{}7~]/jOuatJ<2v]L[Tl:"]aS˩oT^M-ؚd Z¡C?J!(EY,"RN �e:'aW#%x7YE/DUC"z16 +NqGO #DBDY8!4 +DzBz!cW}A Fu()n^5E+4֖iE.IE_"5(] UIAbit.7EJa+ܻ' +pl@P1Z]!e\7 L6HBChPityaB Θ#-euFuBȕ?uJ 6nş:0Q=,�q@ܟVThS8_mkt˺Zy4cD(܌x3<μP�>zϙzAMS%\Y}/՛f"x}q<evv"Dn1ҳށ|vlVP/}=Dg8)haD0}0q$Da':*Vp2E\J2@WajiR7</P˒ U+,Ra^ET] Tɫ Yi~u8{UּTDO ]2$"hz!QDt̉F b9PW3Ǒ_OTaH;Ra)hBkNӏ(!uE{]1e4C"zdAmUEk,^e2lbNʥQ#k<=*58_21ۼu;zal^gkFOxZ{DGGF<Aq1 5ሓRdr4n]<ex2%}qiÅmm'cm$ǰTbgSvbvQL\<rq$zj;!<rq~ +G46ۓedݕhYKt<wGg"Y*la <Zo�!SeBԾqONI(-^�."}>H<U)fqM0F@d c._D5.pJtX榮cLļN2Dw  b9_gT<8"⻁5ֱUSeƖ;ſ o!t:m5lBdIZ%[78Z9Z"W4xYN=]_6 rmZVQ<a L4w�(4*(4 +oZ&-T Hk` (T0B+>vF\60M<?o}{ZGh[,TØ,ꌑ[JJر@1KEA�vœ!w}Q 簄m, mzzZTa� #ϊAIAy3c gvǺ6™Jk{A4Wrw{H=>4ΎR[>9mr2G."$ \56 'gFu q7s^y994oNӉ"}]֮T;ݝDZ담g4CE+¦SG{뗪Ľ._śہs-i,h&:e%rIiq -L?ݔƇ?( \Z,2L: q`fl(G֊C~l^m¿Z>oEV'k0rJSF治Q.RqAECto+tכ6ڀPKN6.:n=P9gNEg!rp�, tM\4Z25l\|Hh_lQ*Xg $Q z9< sv 0U"=<<6 KrW]tYeF,{8׼~ixbyh 3C<ǣ{ݰ6Fݪp FH'1T|9CL#u`!Bv</WN~#$">ipfC*kBNkOJ!(Ұz%C9 V$$j7MQlcrȩ"":odZEˊ"�ڝ VJ:&g|L(iYg/`4 D ԚK7tXgo,4U f~uB\CYsٕs14"K/]%(Jly}wCwkCT*@M>IMvAsFh\?�3~0R۷~ [Wb] 4)ˋ0܆6PrkN"lU1%![#}5j݅ӕFS[r]mF S`i(=\L<FO?a=ﳋkEz;x_{'BҠ Ӌn@v)XCqՔ$) BI$ܛw#G$Y]5~YN(1y\<1EEl鈴 +7cal20Y%gnF$0$[9=2wԝR):w+a\9Γ4:9P(ߐ6hA0-:yQt޵ yXY̅RF^>q,FS`Q�},PeF3a +y|-ŗhV9|I*z{ڤTՄ`, ?V Rv,cK}r9M#m.KE?G9!A>F!̻6\JP/mU:/I}׮MhC@ R8G}sn?8 ^kD + &DC8 +MՂQtQG3�@:ա4\5k%7H 6|#e}xa<F|ɚϏ^<)T#bl7Gm"#!TB,0UE}ۥ2-H)&QJr3MϨof~.WquvY"I;dCP_ 6W|*g?n3NԕIirv20$ަ=}t2[BFa<-ܬ{gC Q6X #)j|p5X1^ExX"v;cputwW 7k@Fol%~$LI Z`nLTH/3"8ZQ۷~4W�0efJZ83<M襣ƾ1xD Q^ۼqimDNGLv3\w"61}i>#FLŅPq[yɠ=Wi#(Z_P:$J0>ULx�iMγYTdn,HzhY+^Hp_t$5؉2\Iq?\7@bS5#ʓhSf+)ŌVZ TϕM#FNp!ę>$)-F,{4k>{T^[>ڝ4Zは{(#嵦fU\n(_ #|ϩ7F~ gxF G{8jBeaal"7ܬ9`YĺkíOmngmiAJg gyU# _ܺ?n�Їe^nUFߔ4}$w6憆.bu�~Z M\呻,G#nw|vQ ̚FZV<mA fqsebx,l114!Kc/z�g8 I,{y%Iw?7èV՚�dcK. v4k<(6Ec8;$Ms1E,�S8H:WjO A*W& N1#Y` +=H^ȷf9-HA pk6zhӄPWHX~jw#=+ʍP +II9K_j}X"x2CVWϿ6Cmk]0IWd%yTS4e}w(}Qq֙62SB8}FrW(pct>@ч}K,<jmF9SJ9F̍Q [Zz X[Ԏk-OAX_VbGkErc˚3kM6� Qu?rI5ȟG:T9JrVܜ9OC׏ ^ĺu~E[kmBgc R(󵛣#6_0ـ!ʷWE0Ou|Fl#DlIs4qc"eF('N衣>cO[de_o|Ao[B"c5hf׎nbdh<g婭41͆Iԍ+b:&blh@@HDz֫v>a:WKkmqݺ(@ą%@o!9 +(\C gvCcѤQQ1?Q- )L5:ZPyCVGVkY٨KԂ&5,QԦE3 ^`P'R 8 +n4"JI$T㗠Y4Y&eDay7lpqf#֫84;7P a^eoE-3)$2CihU3p!GĒ`&Y^󌉠4^Y48z(I M9MÄ%e"KDc,}B~ )*rUfhjK8t4 RA]`:&tc*X"3*A- rh2rEN:yHYeZ1F`dSف + "HddEe +lo;e ?`R5$DR.E;t@F@*Rcs}RgʈVCD潦 Ji_78o.X-)NA}UTb2c~&TәҚT'e�Bnȴ9Ūd +%4y(ZLT1 +.<ꊇ +[A<b4EQȼ UlCja<7$ƗϑfK;L&<@\ &J%'jDPm,(1|kS{6ǹA'x, 2.ZtdIJFG<)T2)�CZR&2m8leN2 ⳉڦ 'yݑ yf# (zM6W5^43Dk:LB$+))!(̍q�}vy\&01FkMIr-SP:S`$NA0 .qXAvZͰFY>Qq"T(%Skk diLZEK wwawB2S܆ bhTRR1&RM”# +! fG*t6!"1E;pbf`SgPUHe7|b$RXuR&, UzA3R'["Da*ƮQ1tS<ڲ^\HY( jQ񂲳DJxdRUJi_n'U%EѮ�a*$% Q͛)e5oLk,ԥ\(N@+x:&Ԭ5!PsXgMUj1~2:(ըBQSW'c}AX'5gf#)t0\8!/`6v!ehF,Ƴf<6UC7I,SJĄ SM#2IEdR]ZwTG<c<oGf1K G-@`Q>dBRTC+вzC +J> +B'}RkYKfh)}}(r!@pOLW` ޤyZ:)]%ЖDI<6 B!+M|pg߿8rǻۋ/-/xr/?]^}{qg8O?'O?Nrz| [?Hߞ<#DN>QQ^뇢gO XaM]ͶҞi7׎!PܾMA>IvobXh`u:l!dtX)8w /T1fn! )r` v'\&N$Ћ<X0HP}y.7W}:xA>yULS-ݑ=]YUI|y~ypǮY6M:(\hdyeIfQsUAy<s-<$cİ񥪉>ҟYr%g>NEn5Y @h!Hu9jO}ҴY=;zx'Ǐ~s:Fχ_O0^K)d) NsK0z_ٕn_ZYo\sDyHMm!+=ܷ[ #.v[P6hGbYLLV`oŮO%ooS3Ozm +0y{$Jʳ= PDhR" +ž\ȍ=fXW#201K Hn6P^/fmOeYw|mn< /p>&(FK!mXݷ#220:سݟ|c=[;9qmV\T'ٸpa^"+{ +4hW@e6b `Z磊?닲4F?7a-ZeI~EU! )0Q܄q<7]aYp4%m(6dn}߭N#=%Hg�m}8l>>R ew*�ܾDCRq#iJ:@P9B*S@? @+Ǔ5MՆzGA(֮z(3h}VqgCsLQ`XTV(ik-5ʏ,||2WsKOSF\C2+"݃ + b ;W\h*!}x2d]lAf[.I@Z7X,G祾{ &fl8|Fz)^ 45 9&.[Bځ$m�'Bil%#(eudYo�8#b@䉢GF F@S@ϩU"A@`rkjrH (0v0A|u[vX  ZxnL[M +~+(%52@˘>:˔ +S+8j"ztijJV >0PWT۴s@Yl#ШU3kIAqo }@P%đ 4&o +2K bǃpTbwC'RՏ9n^Hkd6Ȃl v|/O;~ k=8FCG[_%(KG^魶#&Sִ ׇ.T*(=)aB+*;aO_|Vq;[{p�?2,RHlcŮ`A &Hڱ.a$V +d4&y b4G2Vr@PzaZb4F)@\eu@փ8`s9C_:Gs".pu{xlOMT1qP ~Iqy~w>4>H{-�8|8 5\AA_󏷿{+ߟNG?\ADO~yC7g!JGM`�V}36ҷ& @ /4KzǏHF-Å! [LDQT0z0j2/hm\Rɲ]+5ET)fr`-X_&0TGZ*bq]u+@j +]kŁmD/DJA>"UPKjiRV˖zyW=`- -$}|?1[ht1bh/+e[cQgw 8R0%m5V*ȶ !$ +Xr`0!l e<M\ FVMjj .۝-a @;2[ܒ,Tf +Łm@&o.8�TKqDw-5jS C^L6rõktᚫ>i{dĦSXK40sMXL1 ?Sx,$*XϡONFU>D_q'!\ ^h8eԶ'f /s 3f=965US,r)۰{(3= ,ˉV@z=w��m3:%I<A҃w<R`=W9HNRV-!&seL*YЙ՛j-bIE؝ m ӾOaR*cOm.~P= &h9Q)1Z)[8(珝LTl!"Q!ZqLbPA CNu3'63.9f[UJjyiF̟DM@ {=0lNcY~&Q< ?fdCa;x!vhjƅ|hDcPvtrJDHu!`$lgHy;j35aWh_KkW밼> Q;S�`tx㨫_:.>Y&ab𞪗&pAj ̾9"LitR]^}|s={)ˮ-Cբ4!ًc 5 }T_-$cpqV%vmK}2uh<� i )+}`{l´=˧a}7/~Ŋ"0r<%l"Ƣ7/!fxV7, sk#pعO `2<N]t +t-oiT;?< {<q7o]ѓ۷=zu^dO?{v?{rݽ ?nbq$wZ3hFo;EY.=1+cB 8P,D;~5ȇg-=!:(<gpq& nr}/4tjLܖIv鿢忲o>VU=ƾ?i #?n%ʎ[�d7P_HlUPSOTu:AO:S7J6g@h`GҶA$'E�c_hnN)/ �IHö8b<C:M wZCo@GZV*[!^́a Y]@Rz7EA{%>bA ),g&նeUV^u\9Xh35n~r,̠cS~WBY2$bM=H1Do>@mwHeNŴL:cq91:J "kA8>nXR'uPVĪ)@9/#Tði Sm9}\ i[lrn@} N*,9Ffy53H Na$s^9M=R7877F%' 0b2ٺآD +'8:΁d>D=ZaMcDe˂I".?:R^2dhnc6i}$903Cqry. ۂ_Jq@}� N: )Z=rM4Jb*'I +fV,G&5+3D4e{iqd|)q˶ө<:꘎_#I`VR L bjۍ8_/$?}ziHA 4 )p`Z >N,PHtWWQ)l_*zqyg"U]}; FórXuv/? ^FJY4T1�:*jֶCQ۾/îtKê;X`!OnϚ&Z`_v[uw5*fϨ,i*SfA{(+J℆=۸'gUgԓ]~=XBYpF("w- ,0q˱.>ΛO{:ߜGooOr~?;+ξ^f|z  :ŭw´}^*-?mE4׺>}�/'E44h6l<=MZٺ> +aP*UY7mAE";ϙ Btspk.n 5/ Y7<wDŴ?^b4|$ ,`$?3ޟUeJn*A�m10GK/5fD7<'npG@!ܹ~d./zp5eC۵XdRwˢqiH�p\ Y#4Ua!- }grbB9+H"݊uc-kUrP;2mg``ɕ' hph:CPAN4\=)P3hU{� +I8RQ(# +z;>;GiɿڥF깔8I4i\%$:l t{g[kfjw:Ax.bw4 (HC|%z@`&ieu4!7`uq}:̢>h}<i61;P`\<!4JCcQ0+fhY߯Rϱ)4u8&6Mk!LnT\3(eķ,\~)2L r l)+j_og( ff5eWS̽8jPLuİ[g@h0.LO(Ps|aw$=[Vh$R^ܜm$&82dI]t i2@O6(}3Q=Ɇ>,Qplk%v;\m] +ײ\�#`->x_ VX0wKSG8W:hّ"8i! rSΒx�(m RijO!lg3S^%B}uϹBZrpnȣ%�z G9{KcXQyPJLg:SPM-rŹ<&e-VJh;.cS_6]U`4bL/FJmad&ܿh ȺQ 'h,m-p$R"n#1qc }\,kR]-X�'j+tt*XY@ 8aa%HILo >,Aqo#r +vi2q.ܑTm'Xӯ$:Q²T +ЫHY<jAUua%F >%e`z?ΟR˗4ڒ gv-POq.[QSAa^K8 lq~ 73YHoqU 﫱1D2!14F>~l$jo¥0 Ō}aB 66GbA۟ .bi V_/besseav;f.pCO3[HPR0LXv`ň0^uy#>ՅwEMW5ݞͅm=m+UvrBH&qad.YADGrG@f> XA<uq9D׭uY&v+[5Llf9͆;mҐ- a %UkM)?FN`4A:1NͩQ|C)�|Z?@eaw ,պBn\U8'o7|), Z2|7B`$-<p`ヰmN랉`y l-xZ%f9z/б886m5YllAXH\1i~om>aS.`ĆÆt/AjD#]fJ,Æ6@p8zytw(J�%;.B^Lfߢ?Xjaks*wCcg|ߵQ0ez<Ѱ.gAAx/<ܢ}Hu3 r:CɐV0fՓOޯ_iZ,:ejSaޞ0 g K?zmN{c$W~[Z]5uX9÷^!}o>>~oxe͋>O:FHYh*y7 cbMLbYts??�vn?k:w�dgiB*ji ƙ%Xr7!2%'i)N-Q3E=X`)2au=U йDU,=\�j2*?7^n.T;ɓҢ$e!87;bH盧gU9j_yMɰ"7g]%2_"Y 49̟r_<Tu,i9 '>Zrkto汖_ji8@n6x=3* l";!NX`+F( TuuϹ!d!|]|g= |MC6٬"k1�f(u{ b'L:Bc.:z8hxL0}H㷧9a&6n0#n+|()$`]3Ydٮ#]H-hAnY9Vf!<S=z+m'8@)韹aGjy��~½cqOp>+I߷~%Ύ@U]n-\`YwCHe?:�hYB볯M;U[ѻV �upԡ~TOCY`Lw(B&TִT[6T0<G0SZq}38i+<L`0uR@0wXMp(#]{z8±]�>Q<o0i%!K`-~Q-f z�Jcܬ{`xrF"X# +%D@gѥ׎bJkM3ܬr ԥ8O WAtq'4-m|x6ht5SϘ V#+Kiңod(aفk#y"?s*TtyBt>/j�hXd}ԷJCpSupK]ڷ�Ѱ+7n@q5Ӕ{՝rwѳB! +AS u?v]3lķgՐ5v<Y5{@8`<S"8=-Bh;L9'u!\Xni Z;jں G51\f/r/+wl1g<,[WG(9\^G F;'TR͸ZHe�fn47A }z,d>I #}{۲w*!H(5|l/}7N!+Rg5!yھ܀>v}X;X�*a[mQ @& +{u8 Խ-ۈA 7gf}&ׄC + Տ5]mnq*k1WxmI\O0 +3HQ|u9yIPx赊s'CeWΡ}C�xt]Bۑo<Lcj2g1p_Wy XtYgpj2RL%%,(֍Hi0,s ly}v9>K/^Vm(/#0GE)9]-dǸ )a'[X+A$W`.�VA\vK9iO[d7#>\StC#- ͼpFNx1D%C7"2]ZWR:l8j-/MSsMt>odԇ5*|oúXǕoE&'C,P;W.02ppi(lE iK @c<yp$]zUp~~d0^Zsg)̒gX4=6t)3vv$u"3xTqܡu޵sm^UVKۆL5~gHRZ쏎 rW$'c5,M ']5ilbHMVE}%lB +%ױrn:'gOl)A"kS, +b~0떠jnrG|EI.sϚO[kx:C{[yߦkPi kwq%񾨶ϙ(1Dgt +"D݋qv,xwi>ʢ^8�zdմo +:b:]NcFoHBWs.z=|3<!St9P{9w[|4 +ՆUTϢ>1'6U2UՖP"D",/-�v;S S*v;ED^kj-e-AZNM_Pcl1<Ѵ4nM1O&m$c3=/o;(8E8Y+ &}zUQs"gn&GN}Ԍ0zJ7t FuM.%S >w?W>('jRW'EC!Rr7^ ] `s\\;n|a :zT |=rqʇ\_$$O.(JrǥX]#N1oDJZڊ>2\/js4_[wߡa x:;>XfFe +L+H.kvq1{tYDKewlp;/%E\<7j#8g~fֲ½1I& ނ hWlvH"ɯ,Z׫2,2V4cnk.a +rQ7QX�M3;}I|>�}/O|ở>|_O~_>|_>c??%�ѝ¦us8Oac(5w=A(E5:^vG Y:{E} \}DmAΖ4Sl!yj]}VUL%kx/UK" +?AD23"#2; 6# Nۻ/k-vS*3b}kːN&] )zkj1s_ߋ{?1.魺z۠:cU1 5ߖ@Ld !1-Vp:$By֣2˜Ka:َg\zD&sɞT>˻TZQkfɟ*V&5e UTiꄻ׻°~=y-.hȼNy@챖oU9CO-<Ms5Gw{A( 䙣Yd@_pF,A)p%{ļj@ #/x-$Osz�D")GmEU־= T/Z UD.N� B\MG$,H¸x៽~׷__o۸%O_Pů_Nkb>zOmާ&c}j>vmԍh#OPhF|`7^쓏]@i0Ծeެ\V7GIEN _['}iW丳qٔ;RDks܇Rf T Sx#zfi/0  (<pW-Z ziяb̚L1#ǂYÖG Sfc3!^ĐUO0! 檡Y˪(#E{at4|P_^*nV50}~Yy..WzbBpD\El̢Oגhc\y<%#C%ڙڶiQV\k? aĬ)WiIVnX?<'K#r 'H]*;,:~0-xl~TN06!u@TKd uRo76h}s"+6ٝ(+x5RԼ:z95nNr>ԯ*~<01ZیYr#d5 +. Q %ڕQ,j&ӼE<XӹEZgtQu]B;]}jG +0NJ>|?~ѹ7< +M^zH48^oN*$#G)pK0JV/R|7NhSH:`1Νc%#QS 024ouT(Z$zE<Aщ�xlJpf>:2<ºu-)HV k0Ey!^5,C<ʻ\A&ҋ2R89P2weyJ'#6PB` .HZѢ'/e17OR h7Cdn +*G2 ׺?ZW K鑯-:"n< Z`<$u$%}DVL,2GϘ-Jtm(ڜb8(0#NL` לd]>�`3]ܧϛm,z[`q6̶ax4ioHϽ @ҥɫ3$0ʨ,)#zrW@8!~83J?(?:ylaoL#[UqTT)HOPweɟ6k{YFI:;|zh h m+6wƳ,Nv@;�@'zy˴`!0/##`:rpz{׹8 +GAUFsBR! fuRyr g(m;6fmK#xT {4cRVhaT8NFH@.Ni/{d;<fG/ͺ8f"Oо.'N-w<"{xFfeB0N#Vp@/* ٌ2I$;hdH#Y7׉ԡac677oLݭG؟RbJ�&(Lw\\01{TeuO*u_Faԡˢ,'[}i>.7E�-[kcЊEl)ѐ9]kLhDF(Xр|گs8r~c!dȸfyY� e!jV+yT++]I3P4>;�O8V=# F:@*D'"/ iuL9ׇqBҩbw76w̓FD d9 eu ]DѸP +8b{߆>sXQ{hKp$cv֣vR -],1=8#&{^"  +GD'-q:ΠLgBLp#~5z)])SQ ӄAkUz{%w*1PMaun63F +G#?`$M3lt#Fwo`6y6`fؿWF`dHm.I XS=óL 4ƒ8NjB9tR_+Q4JE/N=T˽̮P2K-4nd%!U5odrZxrsD2po$,jhx&AƚL)q7`"wܧ}[:at] 퍗+H$rȮt[@rTZ .JuveQ5.G`mBcg8N9[%8]-VG ? HI]NFe+Nf#%"LUرQ~ KL2\)ĵuپ�u$cIR'Y]}ɵ'L-"W!K'cJ6GL? ~P\(i˥ +EI!i3AZW]5Ypł$Q $0A'5Γ4HL$:ЯJ&rLdژh?#0*2`uA5CР"O0k`C<<ZBYK`sI3#& �]9zڝNhKzA16ygR5ƳzPHd5Ohj597 ?_ \DX79ۚKUE@vv X +dlѣHR_]g:zjpQz[zvUI["A&I6R)!Ō]6gY) TGI~{l郲[=`RMm.FrXZ֌)tQrC^@ڎ9-ɯnmf<v'YH @>urw A'أ2㧹 %t#9MqLk--뼔9\ [`5젂َ}lёxFlrj~]`HH`ȱB!ȾVd֋G;9S (x&R[ad*3 (| ε7(>voSJKF#)ɧAńɀ]Qf xU| $ X<\6M^\k!'I[!~4 'bSJGT�=IEIAYjy)%6{ m<2I|a':Ik|Pz^P%f#@ܫOAEV.Dш`]ӆ7*7v`q>*_-8םȷ Ȉk_{k^ 2beeqpR%Ayl=8{ M SB2tl##/}dehFn!lgv�y{*Gԝa9xJ]gAL"m'# i`/Y=1/JՖLּI\G!%fp˾'3١A9p]N[xH$Դwg\mmݚZ<+ʪA#U:hK @'E5zsw5%FYB7�]Sx2x1J#֮&U�rQ]B9 @PUہ>xyjX0S =W?}~?||=}շ?}oo|/cKK\Vx ߞ>ww3_y zZ: +WS{Qe|?w魜ۓ?6$;{OW~Jz?{gՀɸ +ؠWu#rbɺh0^XmrC1)y0(D72tT4.$})V"�gǜ)IrbNk:)cm ݈;ռKʹ H87 xb٭cqv .8gϕX|%+2^A!M;aYEdqepM 0. Uko4RQA~#%D6k+M 1pJh= +Xdؤ(*^T 8~bw:QR'z4? +[ +}rf5)͉޾1s5 H)-Ni;SJ5p jׯ#/Uk$Pr>2ajGۋ*sBb-M #aɕ{YC{TCDIQgYkW邬S|."3 *-;GunU{ S 'O~Q.e  HjUj`- THغ +¼mo@Öt܅-50U^Jy>K˺ȡv\҉v &(B5lm* j6-Ve֔t6v&(i|U"ZuRb7RftQ-[|5/,C\)f^MXYzVjQ�g*n +@S}~`YvNe%íupiJ .aC)<ݞȵ8w2! F[/]k'̙ŨQYk)A{/a χ)`W5E*ϭk8C qoSꩪEap()t>i{ ϯ~ԥQ?FQGzi#n50u:Qh_9@ @4\[/+"GVgǷP: > +Wْ8LJ(ڒnґB` 4cS~Q}Gmn4MijM5jF� 7ŤQ0*0CKLQ+ݡ+g{@saz +ej5UK!Ȏ>"VrYuµ�"!p7"[ K֩ƻb u r^ƥB +)a xJ}{{gPis#PhWV .[C56#xZ?(Y .f0 14%. -6CնGD`_~yHBf]bL=UuzVSvjzeVv,@n* Gh\~cdNԲ8iL.imby+DS3кmD6mؚ}}Dz.;V94Z}*TH%scBIO%ib<KU=Vm )B%`XaQaT^x-%#q<THY&$QToU@mS)ll(ʄq2C*"H*T Gc7jAm#xNVd:WjbΓO%$VVS chXavj(,QU,#N8֥mzpDSF@5SP22z9P}Y2A~^ wp6f!oΟ~~uw7\\vw˛?nWޭ< +nwR $6M5w6O?=Nܗ]ɗdt{j ve;U)L8Jo/bEOy � endstream endobj 87 0 obj 22865 endobj 88 0 obj << /Filter [ /FlateDecode ] /Length 89 0 R >> stream +HW]PS6*r +Z3gfs89YQ ,5 + s1 .TltVlgVۙy۽m/7N/ڋLm׾%BlyON8ysy9EBdXEMQUTQ@5Q- +vYXӰ^c5NNfUARaU^4UEX^U 3D˱ƫ ʊ`7z2ꢤո:"p 8V\Nn<Ge 6}O)wCاڐ$!Yk9VQV%88j%zD?4QWݞ'*ynfn&+8Fs^+ߍ77w#e+qVe+qŲ7ɺQ1m5Uqyf6UK67Z9o$׵ph[[jc|3s9WOebw9^Fs5]伞\|W9=83YK~Vc^ќ[lrζl%UVL6 G +ɱm)0ǜzIMի]5,47۟^(Kcٔڳ_~KrRs6_}|iE s_;/5Ua^\ǟſVe/'+sә#}-vx{VPcȄsb]+S7ge+ ><&_QlnY[^3SIͷﴔ/"/W !ۏ:뱼{RV0̷=K-8~u'=&sř9ge;w͒WRuebsf+wpJi*gɫh~xԵGZ غ9uxnv󟹬j`)Ol;Sa܍6[o7O_{ n[ +U0Kᩱ4ccc~qL@)F')vlԽVZ fCE1:7¡+cʱz?yWhT<(ϵ^r C=j,MX,u0tӡ jb]s6~`0l. ,-F7M C;s硶c eCC'iZ~|ޙ=J:4:K EB%c"f'/^,ggKswz뻗k&;48bbL@\S4iO%oB͔{:<Qg/Zo{SqNG}hy8HƼk.í~oQ.V̖"[ۍah;B!#4w wgnAq?27ܚt\4/;Tvl֊ <]˽ `~8sSf'/V,ڀhc`hrr`cةSGK l9p fJ)ov:θN2֪:~7}OeP#b%UxUBr)TXͮԊvTIYMeZUbQZyJEvV ?("Ub:ñ)]Jf5.FY-E`hJUD +yVGų/$T%dVD!QuN_P J28c:7@sj (n3In"+'(*)*'9R95V9;ja+ `2&*U4Na5B-`J WZ<"'4PUT/ .D^F5EBb{Th4jìUBA=<Cu*9KP Lxұ(ڣ}A-eɠƭh%ùfMd>Yqfl8 Ul)$Sj琦 I2X3Fk{If|&c]2F&sI,d64fvc&I0'&6Ɍ`L)% `Pt"E^2VLXz:B{>l_kQu o0J4qGPUлzPz+RCfa" HDԈsVZlL916GP*<B=�0Bx!Oo[KLQ韐ɭG`CPT Z 9 G 5>Z) 8bj dDOR1Tm`��U,D躠5}* ¡l#] O \awHOD +:`dj[1E +2tn 9 +&qjPS6F )=wE b*YC'՚sS _ߤnbj$%&-3q,,�+hG)ЍD*k󼰔 +$f-Y  CD3h[󼰰 +{ pYr"n |VzuX#cel@Q F<Î 6+,iVXN/銉 ݂˰ol4E7֘Q$R!@dز.)._#Y 5#(&Uni@/;;dz3*`c#_M~9U612)SwQ f i"}01QrL8�ۖcF&-_ +SVO+qԜóSVJi\l)ٌVkK:Nj +MJך <Ҹcsh!])U41mnȱHPՂ~)gnE=)IXKS2MjxkgXM4dh-}2+Hyܒ,?+ۺ.H=w IXttJHB*]+W(r9bWɚ[Ŵ$5/^WEJ+rzGSږS3XTYZ8[V痵RV>1[#{cס*٫v�6 {؜ZZD?k'yulՂ^^$V-"-W�;ωZ/~7`1IC'* `u2'x]9] Rz$2s!=MxS.N7ow.x0: LXp Z.<`~|-̂/d˾w99#GPyH?Q09 Z,X_e՝Y}ma`1L ::Ň)A.O! +^`e/BHson7^a}=765:U 2u!9�..fj x0k]Ǐa@AUOf696b6 +u+}Åy$x3r>H|ZKyXu +XZpcw8h> c�;aaÕbf!3R H͸=>#Q#K>YQ+ |IRylrϞ{"j*l  Yt.4_g;;o`w􊜻s@&HٺFȉIǓR*Uzu]w֭gN$H^͏g ztERXil:2OU1$m]װh)6>؁z(G>~Xdh*w䫚(-U5Gu~{%=7~̣);x={</p˝ g7ށ9 +3]TV˗+̆2PM Id&6Ai%VpE5 +݇Bt}f2S1ljHl +Bj̬}<Q>i<>v +/pIf~߂nIs@4mH0 m+c{15h/bT4|0ja˓51'!gI>z/|px6E0x<dIp|uރ]?H̺% +ktHpȽ30^RbNfR~^;B0~sȨO 8A{uݑi}1+#S "lP!.Rª63o'Sq0)\3ʔ($^2bS&62fPm]×(j؋ngR^ݘ J<:FuLj` +0U?%曋$> L~QUɯV7ŽZxLDۄNif{;lO'L +r_9ck%I-hcS,z܀Suhd`qhj;7yNmgWpR8SWa #}x^�[{&7=2dĂUm\cfZ,σچG0!aO0m}1;%S~<$$$�CO-zOọoʶ`j6ۨ)$nlC!H KXt6ԣFSU :fNv2 9G}Lc**ibâ;Q,udP]cy)Ein:QRd%Q2J*f{'C>_g"_?\yR?$\_Q/Ya<HVw?}j!ǷMOڃ~4p𿿃➚~h=#4o%t0&`TfhnTJՊ;&)Y#,-b粶OKb!̜?0w< 7o7/\l3i7}'DYx*M1 V6DSc3 Uӝh-#3"~4 +i)+&;\/d$Nx BN^\~IEaɴ\G1s^YW4m&K 3U-aTA� :6fKK='8K:Sy}.tF`eX^/ 8v< [nCE6~omMQUuYN~4RdL6i6<1W\kҘ*nչLWf2U7Oe2o^&7 -5$xN` /Cn<(};xمCԾ)<h&k_ں!RgQ*pR +ua"z!y0\) +XZxQd(`V2<�C_E*mI~/lO CƎVv3A--؜fS[Io&."nABd +ӤW~uFGc~E·8Zm?u;pd _\kx'ˉ3۹XV?WA.Hݽw){J{JSHj:cO{{FPPpHתwr˵&ڕ.%U3e4*b?�_&+9g5=-ڊ\ߪW wBsaQC`.gKD:UUXFB(H,Ֆ c=aÜ[&_м_м>WR$Kw iQ(w?z[с@5Er,pܧ8íE0aa#j\@++P:ǷpXPCb +h+ h!�EWjw}n!P}AG}A8vF{4nҸnI  ^N+7G_18gz|mz"Ю?5[r }%uƱm_нv2Y Nnˑι-e }zünE1w}Giو HԠ6F,@qѱ12m/nEQ&%o8=q唦ٛNTQ\ bſsp`[v_^ t1GZ/À178p PЩ7ڮp_kH9ڞ)((bTxf@aP7{mR>1*\WUAt@ lG@ vԾJjItmE,{xHH_V.;Sӷcj^v+EWfB\XI[ +)d4%SDFe$Uu6֬FR9ԑEZZ5 & R㩒 Ft?uGbJC7*oܖAeި`+;ͰRڑ L'դU&v "H24W٣-3Ԥ{ +Ne 1Ī6l@0j530-헪QAch0~8V^t'5}Lu/TFʱ+J & ,$JVahdSI&E5Z915L]ɁRң(͝#3Ƒ .&1S ,CKґ%;$`sF e9 ?kZwpkJU蔿 V%pC~ 4b%ispC#`Co$>-+?lQkX3zhp0dGYQwyȦtkҨ"(xmâ +Qexl4!!c~]j`n�՝~Y{k\1k8/G*"uv!nVHFu( whR|9L%yq $-c(s\X LXHqS2f<a8X(I6ޕVji8Xf~) qDxL2ÏptY_~@/HCwNF7t +<\2I,XLQs45\p%NwIKo9+AzFlDnbbyOAl +%eKd_za(\*XIxI6T\͊rtn}!_z2d)# P MotƠ0>V~Hg4aY I##sf-ఀ1SM3V64 ?/I)+YXLi*Ή {z%#s{ _~uSi1B8@t@R] +l,yWO{0YW!RA"�p^`FxLsw/3Yx]TJ"3S,mM LB #t˫LbInR1ly4|avn f۹ys6,�!]KB6q5)QUb9>h)w7̂\,[=xe0ObIG!r'}jBo%$|tN7_WyGbѣ pOVci^Mh<l>h[_#&`xM- uS*Z}vǵevdT?n E,,4ՙ +/b%[ͩkSi ^nyQQ`hi.5 'i>vqd7m6E(i,EBdH.(IA,)*'h|Ac1|�]j,>Y@O8_4%ved$N+WV2̢;Ƕ +ASK cD,6TX!8_v. &qf +66hdϨfgЗVkyrıi�Fܺ3,ՀphyF~1Ѩ$ LubS!%4aO5UxÔ)c4e,№*ɏ8,J=8<(FJɢ I= h{&NSVˊSoǂ_EnyN߇/C* ׃>$LzM?Ǘ[>Ia̍r4 $,J Hh4m mbP~|~= 5 HK3;7yμ;IT 3A'F*/rykR1Y_wZ>+|hS$e h0ދBx=Od}ӐSq߹eV懱t1gKlbWkbuA)]rLXe:a泦LF0)S9Ivݶ"SN i\*Sf.!B!B!B!B!\^]9VǷ;{h4҆e S:`m[c0xzDh2 ?C^w|tߟ O`b"jN?9уEU$_<1!zXFvŅ~e۶^_miN-жhD"`0 B=;y@L-p87( +Á@0~9[@U�MG endstream endobj 89 0 obj 8664 endobj 90 0 obj << /Filter [ /FlateDecode ] /Length 91 0 R >> stream +H̗ tg 5R X+E+b_RuRQFT-%*.E&qG2"ZDm ZE6 cL5w^2{us7/w׽<c{QIOe@'/ξo{_!''vs֭{}=g~ݡCWT)(@@@b +* &GE}yKfOT 7oy~ïU\`_<N>WZʔA|*T(\0>|]0K_v[r{>_)6wy׊c_E[O. +yWo\>f̘^PZ56X6yd}BNMK둶 v@ 27�&w\]rҥK}w…oϞ={_}cǎU+++Qj/:t{ݳgOff>#~;vؾm۶O?垞y?ٰa#^vmZ?RSS-KIIIN`Iŋ'$$)k…111s̙5k̙3gǎ+W,sX"/bCi4nܘ29s挕g;5u/(/~k%/שSHd¢gȈz>$>x!ҥK݌\ ,?}ӧN=uĉǎ;7iÆ 4hP~@6}^z@_^~ˋ;w {wСu͛7'HڪU+^ _~Z5TJ(J*E-py<ڈn=*y_|ToN<q"}䈣91&8##cΝ۷oߺu+UhW ]jʕ+&%%%&&.Z(>>Y͓;n(>7$x޽{ݻv:=ڵkٲ%j?mVF4hT;+/_\rle˖EvYLDQhQ^Y)S?j+=(2 ,"$_l)$=.`HKKh|+bc), 3f <54ic1bDž0{#~1\/dg"dYf8R^=`ȩ[n5I;ǗҥKrfazF`㑅 4mQ-3mOgݔΝ 端B +cAfEu֓|<n''_5~x3w48rC! >q ͻEۙ<4fÆ QN:І#>QGgOiX +"E"6ܙi5mN@$ 0Sq(wիW�@|  ?%QC~Oܼ VX?C.82..S7~-g2D|OgTPDD|oo۶m6m�B|2/_wGvdɒR<҆TI R� ,>R BC|bXx ˝C!!~/O NMX(,sΝ={ßhOԨQ`Ȑ!$ ?oPGBCC4iBvܱ�W.�5ZYâL:2&}T|~-ϗ >}Z 3ЂggH-[@~C]a[3$)o/?aǂQF[ jTAw(bJ�abAGyϴ/i\/"yѺ| + 7΁Z5Ek"l(7 3y +ޯ`J=_yo{4_|;G P0god%  81mEѡ@T%�_'8]s"t[ �A4_ ?nG?{hJ#_OZ_agϝH?.0Sb-Z@<-vGv.Kl(!LXx&;"64_',.am9ca F(5Ъ߯?gT_nȐ M68m9ZX,SHMQR/@me||HW (:4/[@_.H#?/ ֬YJc,H)ǘ%`,kょB8̋?g + +~?s]~,BX?F>{  |ZQR<P�7p_3|{7-*;?3++:_|4z_ϵo^+X  (y=!o^,ۈE!vwgJIHEArK3Lpfy~<ny攁_Q,||Lo/3Ts12GÏt^OB:IN:Q <)F`օf + b-]5$}}0!IR0DX 4ث 8Ђi5XWe/ ?}O p5/+u_GG�?b. >Q>fuތc< � s>5K5b@fځɑp H/yܵ?f<3oŇ?˭?ߢG-8%EzG¯;rA!o*FАǂ`.mF6ju<WԯOݧ|{i0fQ guOjdggc'YY?!?A8N F/5[kDvZ�&`y tZ0PY4_&Dʿt74K'�s4X2 zLga=.h\$l̟?kFd!- m�C[]1E +4XyOec?yfA5^?/ZqÕJ B1r(YԢMA\ @pѢ2(PZw$'&E@Uysۼ3p{{=rt0o:D{MR\iFy&&& O{QX*4]ZJ͘иPD1ɞ{),1aE[&sd~ۉw6yq޶#y~UW3_]RÕ/ (G"ja�(g ? ܿ�~k.�/MU-yIc8 X*sA {"PmBQ- (O<; В-]D3Xyߧ>re]f^Gp{S!bjɥ|1ډ]>%\<54~*hb-gWل[uJF|9jAvbΙ2W�Hy3y^hSUmUH!5Oc[x⥦ u/iK۹LB +Yѣ*2LŒgG'3܆*\GxfaFkzgnnNORk׮]#t:Q{D&-F%"c1@ ڙ,uiU͹2C8ij jO=>P9d=s'Y $EB|o+.ϲPZJPCY*`Vp319sc8͸'s\A~~H؊#=EљeoL`toT=BI{3C3#-5:Ѫ|J$ X+D;~UK)!̙ _Оc5;Z5;:^yߍ1h6-#cYBaGH\gĘ4#MtP~ GX*-(`Hhsd]_}ڿp"o*FH؟}9_EJ�gyé*ƛħy'OҐ?gB^ ^TH3Lt0 !(Ro1_GjD[UQ8  Ǩ*8d�Qtm* gzzɚ̕0uA'UpܹBR N<_ͅh<S>K">$>  tEPώE7ՙ.)#-[\)yfW y 3O_s +v'GGXp4ȑGoL&̙3$H~K!o|4/G " _Sώ!>N_jiksn~rE酛�+lذA�;g۶m7�B '>0v- tT] ?_?^<}gh!J]>#)0+4X mc.Ώ3vlW\ק3Jqcrқ6فo=#!S!];  �I6-@ؙ(?$H d@8i'>o)Za~"yJx7ΫB3 43BXe3Aȷ=/nsh|X}k`SĈP?dN &A~jJ� ?:Z@E+WD'm|A9M +*2Uv[m03|.�'T +$H o?SH4BG d:~xgbv7e:w8`%(FG&#~9v&2 6Cٖ*C +bOJ@`ǎ$,Sb§Mo b?m@~";/*GS8oO?Ok&! H[` +T8[,r'9D9UA/hu֩p[ם<#̷'$ȿf%-|PCaNRϷY0 B0`nN/g~UJ?@cb?) 0_[j)a8Y<RwY_H,_*Z�~G/ Owh +P< +)-<GtF�G*DO>~Og]dE) J M[FN':g`B +TA�!9 d+n~)eʃEP7nE] `'>T"5ڵ&ϧ?A˵*S� wj)PkltJoj[AT;#,0j^\ĝ?0F_[eG'1W 2x"p |6߹sg�'A"( l࿲o?. oEy. M?AS1 Rwt%6kGbdhC0=5(VXAbN̞'_epb-e0LM#\zd\ յ}Oz#?|'8�'I>hK῎J� !FJ6OkΝӪ,]pAj9?V͟?yel>lot<*FeBQ#ĔG/*q#">AI,7wx1SZ@A%DG"=!߿{Q^ S<�{:GIJ@8Rه|7×-<D@ z@@7rS/YF!4ʕ+H AU]S,QvXha �Fit <$Q7U yV+]h>ms\>ogNn/U#+}h87rrw8aQeE/�uF`h]z]uqL)6Җt0ifd}_pC幦0F +G >{|;EԹQ<pMb oaXP`|�$'UPODiAԔcHs_4|f?{X$ ب蹒QgrrRT2)p@27fzM;P@i +4nI3ŵO=qH  搗(0VPc\;s +!('UN lGORsb<B)}G s5{7!؞vƔ +(GyJU\`ժUiN^Bm109?[l#!QeDrT`-H4v S ւ`dqB ,9J$^PK PB"i% $C[RPfa].=0;;3;;1_$W0AMT%oF?J'z"? +}.(Ǥ=cKؠv7+%�.]DU@GQ0D +@O*  eB@xګ6gbƌh>Oړp^ +`q5TJ +l,{ !ޕvY>X(;~J , >*$1?;^>O[Q]z  orP?` GO'?xḢ:9mX�y򟮇I~(]`ҤIj|.1w[;%�r#N"y;U'(Յ *_+4?Lx(PGO?E1={Z +؄TV|0fe>|WCp2Wa|'OցW@7o RA L^?fϠ~}t+?B<4%?E#_ǎ`φ%¸R �OS{O{I~ XK>j'M @C{=gK"ZU#OPQ{W#BWRQ +_I ~fC|A@Ϧ[?M~n9B `o#Y J@=K+ZM*42edP!pw +R$EҀ@I"BGDiAr)TF4 +aGB2H|/RΈ0>| oӞ͒8O +p^^T*4|;ZRXSJ�1Q`E(K y3.Gjd;F czлZO P 7Rq. W\Ŭq@(S^5cI~Nc& #Q3_S_vO>#~$a6KwF|&$ʾWƷ:ϰ޼yX^*GcӋnR_3yW_~ ׯ_gW1>>ߓ0'O7&N8v1gr=t{cڵk/~[oݺUhjkkY+hti'S#cy:M�LL6mԩHu>g EaPf0d?�eAB0]s +._|s(M$̀2}}>|wݽ{;ˁƍ?aW_WWxb2?i"UUUϟYf;޲22R}+:`xp@ uy[wA?Sp¹?NB=z{{{ߏٻW}vgܲe  nz'׮]jj(hzp)hhXVe($p8L/X`޼y g̙ e3Ã2WȨ3 |J>Z8W5c>|Gπ&0_v̙J~)* P~A^{{mΝ;a 7mD<`+_d K/<  +yԃS#XJ||>C!psSk/d�rF1oT.A-ЕԎB]Зi:P0B9@@;`օ%uASf4 BkسgyR j*jeF3g"C?]tIÞ'�3/ +<mbfe|RC.+(b_&ҭ@t"08$'tcw13IhBypv|W}V5Lq#"TBg_{XI2ã(u!,AF<JѴbJd>OEyMH{/][IH!^_,my6,V{3ש)T8RZJ�E;csUxqۿD@!&ρwL`h4A-a[|bpwaHa^ңt޹sR4e\VNZ8ي]1^l_#22Hٳ, EˣF$2yGUc1dV~VUU?~l0X%,de F}/"eF}}3-r:Ԁat1O=?AM<uMtc:+8j????????Ï /we3楁x 3[+WiiY52=\u>f;͙@ !/DqL1kXx%r]*@y 5]\=ռYW~ѩZ/+\"nM 4o9y# +q] +᯹8ȩm,qzMiul `: ;X('@H::0t.Ic$Ny]*:;3N[.ڞvb<hi_D"0S`*N;5o慣)viu2Nj$ ڢOG#D:>tasg֮uٖKlEÙ}# +&cdP0L.t(Ǭ9֬>cIT0O`ΞBp"td0J;T4v6_,iJVHFj֎l բ`RJODNd@ F"йsX NZ·(A‰h"\Zfl%i~rN`$6O%5m-XRǖR4lcy;׾K1_>;@a/&&L[5јvD_ߡP"lŠ7uׯ=??ە4<uddMBy:d!iHΖ#m"3sCںr k Vjs)nIc y1-]Ɲ9p3ajuS8Oc}n'ԬAPQ.wf k@ȘD>Q&10qJr;]D XN_.�N �Q&ƴ wq@c3 ]< }, a%k!Q# y;P@HyDn߲]^�ٕٗˎGWeU~\o]+rǛ� aH2 endstream endobj 91 0 obj 10081 endobj 92 0 obj /DeviceGray endobj 97 0 obj << /AIType /HiddenLayer /Contents 99 0 R /Resources << /ColorSpace << /CS0 100 0 R >> /XObject << /Im0 102 0 R >> /ProcSet [ /PDF /ImageC ] >> >> endobj 98 0 obj 158 endobj 99 0 obj << /Length 98 0 R >> stream +q 118.93213 30 m 118.93213 582.06787 l 671 582.06787 l 671 30 l 118.93213 30 l h W n q 549.91211 0 0 549.91211 120.00635 31.08154 cm /Im0 Do Q Q /clipEnd MP endstream endobj 100 0 obj /DeviceGray endobj 101 0 obj 10187 endobj 102 0 obj << /Type /XObject /Subtype /Image /Name /X /Width 128 /Height 128 /BitsPerComponent 8 /Intent /Perceptual /ColorSpace /DeviceRGB /Filter /FlateDecode /DecodeParms << /Predictor 15 /Columns 128 /Colors 3 /BitsPerComponent 4 >> /Length 101 0 R >> stream +HW[\^YimVAJtQˁDA,lHYV~J`[` GONlH$K{jggΥ;Wsfvaٍ6)\tw}_W.6W9PUme[@V9PUme[@V9PUme[@V9PUme[@V9PUme[@V9PUme[@p ].>Bv 26Ƌy+*0w%7ˍr}, mlvF+ۦoA쓤潫7BzJ5U :Ia>uJ_w#Uػ##IԥP1p7+옻rYѣr09WKK2d\!z \+0N{w|ܺ%O' ߬FШ}Boߖ3gPyٱ#<qD>4թWj€V>7A5DgaEywr4Ӗqa)֨\\59nCZ + +[mUXw0;y#ySFGȄ$ +>>.R|j12@ Z`BWs K믑n&i6ӑ-۷SO3ȁ:E͆-[ҿ20H-5 ϳvq,rP Ie-'W[&Ro2=gυ^ +]11lFmv=&ɫr76!`}b5MbwAiL^c}|('}sUܡ^ b}r%" SC<2^s؉f((�n%םa84{g*Ca1 CV<|WdΈC` vC�F4fiVbIۥztH#fb$n~y$ƓO�{-1Ϋ1Qp� St+Wf(:3oIH5Λ٭ `sք &I�Lc�45'.0 +-J5 DvemPxM\�j?�,ς(elXr6BOyߒ K~ͩ*!͌bBeLi]*LŠ6Flet_WkaӈۺU{N~01ZK~$T@ 4m&'-uebCefHC�0/F0ԢG!t�xbJ$]f},Mu *i zm8 n'j ӧ1 +EP`r|06=EEnRsnnF*Y[b^3M}FH FA +E i,з>:%]-۠NH #$RQeRp0] "!oܐ7ސdvDH$Gkg`EW[sIRlmAX絨*"L8e�:[nXQ +׫2`'�9` 7N6cxkT"&b¤ T +M0J%9/ICẂm`⃨hn*i[K!Rd9{zM�0k[8p0p]2l/ +)7*0,&\NH s6r6 T*ܚ4�$OT0]+  +Pkcr<X@^8mF[}i\ +ɆmB$&bfZCi!j$Έ,c o&9SDv;(7N3gYXwBc4󘬉Xw:1#uAoף_~zezVZR�X̞m𛜬-PW! o)).ӂy^ɋ:*d%6&I +BtX P",Y; }jFr #Hk-m7l�!H!2_?au|C͘8| Qw8[2윕f XeHأG]pɀL�O7 ) +-޳đb=M,NAgԂ-{XW8}u3A0m)m-$}I992*7gd׮07/<"}t] pZ̅{zUn/x@i6/ߊ=ȑ~Wm�2\$,g!Z0 �pEb`xhV R?z*ڰx? 4ʳjT<qAN_u:Emn6\*֌Rp[ld`k1su呠{Ĺx(3!mp{42BnXp�l)Y.bMc� Y bqс Yyevjƪ @I!+>X>ɓŘ[Խ@NC!W.B@9Ao=F6 +'/vZ1F<`10=AlTjNڹQ03P3OÀE<H$B\p:S{ 0 Qy\�M-(pK5:~뉟 +:6 +-wu~tO{8+"zo6ſu]X- Wj ')J)eƀ~r#L҆nۄ=XG=cp<o 9rDfSoԾRyG>lX˹{;w@>~^^ڔIXOW<9o91{_9Qڍv;XZK�DFnBvzRc2�8 Ǐˉo?�پU Z-Į +>gnLC-Z_J@|V,Dl*4b/5}HҋVتTs3߷sB7[Z-6Ѣ19Y-xv~NU>VJ?֯}l(8̴TVL`}XV}b<Y\@\;,@RVz!#s^{EtƗQ�Q%gp)ꢋҏd^>Ƿih`L@WVrׯjﭟ^zI5<eW 7؆ )�鑬J2g\ 0{кwJ?%c@p`ı ԒO@givZB!A_sjc30DK2+YͩR~VC;+o 4j1`pHޱөg +T4d(X7lϞTy=9* ޮYc7|4 +3ls]f2E9B +3}'ᙆݐc^ +Oq1;pAgHD BɌo+ߩ)?;@rڶ<BnO=n&ב#itɉ!YXb6hϞo͛!#m28GW+KSbd'1 �Z-<s#b�aƳ.*5jzU2w_+0nv@ 5skU͢_| +Ms,d%8ۻWJp|ڑ,2aQumڵr霿huapmڮwޱmۤ]2bWM;*k?R&nVe>03^{ KZ6ܻ/$ y'tmU(2U'. %.38*c2I\x�-RzeMMZAK )z)R6񜇪Q>˫ǶoG~c}О!GQMT$ ڊix50sJYѦ[wϜ32[p*f @' +OA,aūݻ5 0A#.5qprs X1b2C顇ꩣP{5j,7\ xb:rW |I/aZSL`3gSi.DWsN>#(a*d%:,L<%yL](鯫8>Jy�RW_ZkNW|LTY?*1ͺEH9 +mc*nq<P.PMHE/rIMP +-gM=,\fgkDFqH A'2](;c(R�dfVD b_.;UB$jKG82�!xTWFTx~q.ߴH_t9O~jW\ar_"rz}1WVYil3<HLBeOJ6х@'[P6|L'PVa"_|E}LvG c)b2;lll\z <Ӯʮ}l%|V3`? s V۱mbF<eXR^V=>!t'sJZ$3r|,ϋ *GԹeAK">@ѰПTGx!dXpAt# ~`!䏎sv\ئ_OұO%Ȱ <booegH>"82RGɴ7ȁ`00lSh6epe9X"V&�+am$#B`!yϧBA$CF.t>}x;¿qw^ -p/T]w]+viJBB"T9wV9 +HH(=fRT;WӮe!5PxU n2BN\^x@@0ApIH�O ;UY=` JA>==/(FE1n0d5LkDS�"H/(F"=:<Y%BK|H :qeXw{瞳ko5>Hz p{p amb5$emjo-e1>:KM V~P\耇6Cx4Y@|S@7GZf ,S*2.@H=dZ;Yn N`!)5,ԏ�g/'OO_[-v!Ҍ:r' K)7y^ݺUB�71yJ`*s3<lm6ɝb. R}V@_٢+qY�Bݹ3S7o�ɐ;Wz~WK&#a[] +~ 7hɒxv yqկ7!,av`ҖɵvpH>T9P`-?A{sE9^@H]ܨOJRM""xܢ0uY[oU"<4r@ +g?:99sJcv۶vw5:uv;1aV2fF +:J?>ܭdRȣP:JPƶjw +Ew^QB4ϒkGaߖt:@ۗBR*ͮ]w͛Ȕ % K <  i6"Ydff4I'Gǧ{R&ONJj"#8ܷMSj`@ \s;;ݖ %bw axS_VD_5WaH#L-z䑆(AhhBԡ瞟>Xoڤ6AehXq*4̳dTNI�1HG,0ӿO~|}@xP`LD\0ksvr$jmhBt3f:0'vd%b0<>\8p1}Ġ6}0 +MhR6 &X&Xk +Q&}RomLb//RTp.?\"/rs5ל??l�ozj*1i`=avʹWoй�-ɜ:-^H%0<_Yv Wcf{;ߴR^#Kf&R + _i2ˊڤ)v + ]])FR RbNUwsWZԮ^(4l!4]*%zqP�u E[yld؈'‰؝+ <L:r]NKXPigibpi +LS]1f` Y5}AÑ"!f`v,Y^qq*2b.07ڴi34d,yTw];ط +Ci=T94/mD#L_8tLb:J+88:~^�BVG"vN X|y'o�cZ)2NNdr%t'i|EFq&}@i?CQV<- + ,QF}WW6o4LRH J>is9(wgj*zh\|˪IJejZ?X̄ȒWYL IUֿۗbx!)pr?w oU׮ռ@~Ia�swXT )~nB,)X> +n%Iq­ujwȟ U"x곢~KE˂ +E' =¥BTe[-g^/>xCp7CVk(7ߓy$ <8ELnՇsd8OϣGË/{g/] �O}{^H^tΖحƿ駑:q:?Mו`N5yx@0&3u!% ˺9yI.LߝhġL" @uaϱyRªUvtv;f#օ͛o2(&`A2e9p1qγ6'uN_;4 sgÊ}2|}~"MOˆDIvXU/w "MTp6 \*:4q_+rx,8hB[;؟ҸJ{ne)~A+sղIYa7bf`8/p9S`HC G 9hlLG+9M)Q\nb'1 ^V! (k�Z?~*D*6< 1TYaaZ 63`K>i0 1+F@gҗ^?L:2<矤E7w> ~@WH$R|^NPt\_ɰgOغU̓¥CWOV5Q c<- )B5[@XuxDp'i:ӛ#, lڃ,TȊ]93}E?k-JG隩9 Y~PxA;|/`+U@Z\g|[P5EFˢ(f.�U~U.fqǎp}BG+)#9  +j@eDE2ШJW^ xUf2޿ffcC-^͓͞z @ KyˀϓE⥗'SS4e ' +AI<%erZU^i 3c-(KYۖonNzvs20'hY'Çٳ\Ghٷ/_[뷣%h4XU,7 +K�ny8 +SMK? @<!9sh#ƀwn7JgFwr'E2zq52hf*.=-9vŅ rpVgb<Pn?0]<0ۻ7lZ<ܠ7q�;O&`ϓnj #Ћ�Hg-WeUoYVYTs5VX_r3bfAh�иhm'  =8J^IӐ4릷d"D `{< +6mu}1=8gpqk˖cGZwVv H:Qcz/i횄aEZ[1�i +,?H�)b"n.L{i"CAUe=P�'vp}iv_;F\}GjΟ5MjÕ6M�S@9 < +V D4 &w펛6mdZ`a@q" x�϶AݯZuqlTדm0{ߟFP" n9]8ZܲY8-qooJ5Z nBޮ71+7ŧk/>O./;KdfVdmHm hhW I0 +Cy<W~EaԀz21EYw`S &Unv¾nMehZMywxhÛNxWsg",ùBgf:tюZPH9XָbbN0uƵZ!0sy(ZP9Ͽ*g3+:gNNC$p4ec|<<Pع3PwFw({2"\^C,jSs@1iѬte "JȺ@*-ǀ.q +Ryb lCrE>]Li ^pF샢ac|S +0 կ)YӴ_9O*ԟivu!\)<j2h@+\p5M^J",<N̴YDTz|Wh5a G$GL~g~}xukX@!XF̋@*vz{z5`޲4Ҥ jf~DD[3>aF\ ht"+IXb.tW芰H")ϭN:sOsrqt%$*j|p"X[#X O.W S(_@fB/_Q>i`oFwh }_*;/<E/ߐcW8"8dNAjmrȢcVRE " #dIg#!�-P9ljMùQ^k!vԯަUۧ|6Ϝx&@$T +v3%5W2%ZIRM'-J%!C +BtoRw +sqx++<\zZ-oNJZҝNk:�!LoGw$+u)eh CP&Sbza/-/v_ J r9h \C̿r]#$e¡Gf&8RCXw)8>N334=MaϓJGy|":N_w5Q0v4$-/.:|^,. 6~ 2[Kq6p"6W@7Щq5±-O[հr~EP�f#z>']Cd]M1_orgF&nRO^}Ű7x +7t�b|tgrs]5MMGg_ Ӊ~l:_ܹ-/]bAb-' +pBziW;`/p!4aoqKٓFxA^0;m3xv 'kx 'kx 'kx 'kx 'kx 'k`�t endstream endobj 111 0 obj /Pattern endobj 112 0 obj /DeviceRGB endobj 115 0 obj << /AIType /HiddenLayer /Contents 117 0 R /Resources << /ColorSpace << /CS0 118 0 R /CS1 119 0 R /CS2 120 0 R >> /Pattern << /P0 121 0 R >> >> >> endobj 116 0 obj 265 endobj 117 0 obj << /Length 116 0 R >> stream +/Pattern cs /P0 scn 0 i /RelativeColorimetric ri 551.95313 340.51709 m 240.29248 340.51709 l 240.29248 426.41699 l 551.95313 426.41699 l 551.95313 340.51709 l h f 0 0 0 rg 550.23438 468.75879 m 550.23438 300.40625 l 667.20898 383.12842 l 550.23438 468.75879 l h f endstream endobj 118 0 obj /Pattern endobj 119 0 obj /DeviceGray endobj 120 0 obj /DeviceRGB endobj 121 0 obj << /Type /Pattern /PatternType 2 /Shading 122 0 R /Matrix [ 1 0 0 1 0 0 ] >> endobj 122 0 obj << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [ 240.29248 383.4668 551.95313 383.4668 ] /Extend [ true true ] /Function 123 0 R >> endobj 123 0 obj << /FunctionType 3 /Domain [ 0 1 ] /Encode 124 0 R /Functions 125 0 R /Bounds 128 0 R >> endobj 124 0 obj [ 1 0 1 0 ] endobj 125 0 obj [ 126 0 R 127 0 R ] endobj 126 0 obj << /FunctionType 2 /Domain [ 0 1 ] /N 1.64786 /C0 [ 0 0 0 ] /C1 [ 1 1 1 ] >> endobj 127 0 obj << /FunctionType 2 /Domain [ 0 1 ] /N 1 /C0 [ 0 0 0 ] /C1 [ 0 0 0 ] >> endobj 128 0 obj [ 0.9382 ] endobj 129 0 obj << /Type /Pattern /PatternType 2 /Shading 130 0 R /Matrix [ -1 0 0 1 773.50195 0 ] >> endobj 130 0 obj << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [ 221.27832 302.7168 532.93848 302.7168 ] /Extend [ true true ] /Function 131 0 R >> endobj 131 0 obj << /FunctionType 3 /Domain [ 0 1 ] /Encode 132 0 R /Functions 133 0 R /Bounds 134 0 R >> endobj 132 0 obj [ 1 0 1 0 ] endobj 133 0 obj [ 135 0 R 136 0 R ] endobj 134 0 obj [ 0.9382 ] endobj 135 0 obj << /FunctionType 2 /Domain [ 0 1 ] /N 1.64786 /C0 [ 0 0 0 ] /C1 [ 1 1 1 ] >> endobj 136 0 obj << /FunctionType 2 /Domain [ 0 1 ] /N 1 /C0 [ 0 0 0 ] /C1 [ 0 0 0 ] >> endobj 137 0 obj << /Type /Pattern /PatternType 2 /Shading 138 0 R /Matrix [ 1 0 0 1 0 0 ] >> endobj 138 0 obj << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [ 242.2251 218.20898 553.88574 218.20898 ] /Extend [ true true ] /Function 139 0 R >> endobj 139 0 obj << /FunctionType 3 /Domain [ 0 1 ] /Encode 140 0 R /Functions 141 0 R /Bounds 142 0 R >> endobj 140 0 obj [ 1 0 1 0 ] endobj 141 0 obj [ 143 0 R 144 0 R ] endobj 142 0 obj [ 0.9382 ] endobj 143 0 obj << /FunctionType 2 /Domain [ 0 1 ] /N 1.64786 /C0 [ 0 0 0 ] /C1 [ 1 1 1 ] >> endobj 144 0 obj << /FunctionType 2 /Domain [ 0 1 ] /N 1 /C0 [ 0 0 0 ] /C1 [ 0 0 0 ] >> endobj 145 0 obj << /Type /Pattern /PatternType 2 /Shading 146 0 R /Matrix [ 1 0 0 1 0 0 ] >> endobj 146 0 obj << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [ 242.2251 386.57813 553.88574 386.57813 ] /Extend [ true true ] /Function 147 0 R >> endobj 147 0 obj << /FunctionType 3 /Domain [ 0 1 ] /Encode 148 0 R /Functions 149 0 R /Bounds 150 0 R >> endobj 148 0 obj [ 1 0 1 0 ] endobj 149 0 obj [ 151 0 R 152 0 R ] endobj 150 0 obj [ 0.9382 ] endobj 151 0 obj << /FunctionType 2 /Domain [ 0 1 ] /N 1.64786 /C0 [ 0 0 0 ] /C1 [ 1 1 1 ] >> endobj 152 0 obj << /FunctionType 2 /Domain [ 0 1 ] /N 1 /C0 [ 0 0 0 ] /C1 [ 0 0 0 ] >> endobj 153 0 obj << /Type /Group /S /Transparency /I false /K false /CS /DeviceRGB >> endobj 154 0 obj << /Height 80 /Width 128 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter /FlateDecode /Length 155 0 R >> stream +H[HT[ǍJi!Af +Y5"bFtC.FSPO=(C=D/>s:y`aHs~M9:ÞPǵ}HUVVz+g^Q4{lEQNi&cKcoEkڵkVo-*&- +_EݳzvVxZ/?\FFF~˗ϟ? |Ç߿]OO۷o߼y뮮.f٫W^|ŋϟ?{ӧO<xG>|cwΝ;}~S_TM?1H?|ߤ_岶  ΰ&^֭[7n``]rҥKmmm.\8w\ss3gN>P[[{رÇWUU8p`Ϟ=;wܾ}{qqm۶lٲqggg[.--m͚5VZb˗-[tҤ%K,^811qѢE .\`͛0w9s͚5k̙3f̘>}ibccN:eʔɓ'O4r8"_UT"?X HU]]-[?F pE>O򷊿&mPuE/2@ +$O8$(0\XS7"X 4]YוOg%xs$#]ZyF-u ?\.3?kLϑH읗=H 2"'>H8 +!P{0P"J 3㽮xkuN3##8k׮իSԕ+W Uɠ>(Y˩_aAeqx\ff&.yyyEEET"۷СCG=qD]]ɓ'O:tٖ֋/^|իׯ_yf,-jԲ0 ^Q +w1pÁ7I?q)^űajq5ԅrPJJ�R'� rD"_8rg2H#$$V2Kr/)&$ZEGVÏZ?XUD{?zs^2$)pԲQ='%ZpvKBccCZfym R 6YÉ@6ӎ&. 'L.YQdߖދٖ5=ibMA1Mb#( # \K@Y4 Ǐs=x`eeeEER^^k׮2ŷn +377xLә} i?j Tĩeb 6lڴi<tPZZc{{OvK#G(!R-ad(a܂gpEx G+܅~uxC܈'q&ĥ2�dX۠FTp;) $\2BR !;$&2E)#k$ܑ>2H#$$V2kr!eAT`_zCY K@Y'jxqA`AZoPՌ^1CY#+!x(K+QY-�ŭVx o$)S7(jF $# A?S_וI_ ߌ[oDf%]7j%]tu^o$K̨CQk y{NKp(bN)].+£6?YAk"[;+$cEc3j:aFn9j#,?{FeJf\`�HC endstream endobj 155 0 obj 1876 endobj 156 0 obj << /Filter /FlateDecode /Length 157 0 R >> stream +Hn1`,ۍǗe),")ji.ȘDy!4`|Ǥfl~ڰU:+wkWÃ` (NwGJdߊgCsJ _*< e~M(ҙ>A;\.](vy؝aoܔN9@p ()Vebw羨z|F8Ip}g )4~^,o[B\u|j.]-}R1͏ (̊ah: I-G* (Jd̉VZ)9\(S˞*2IRyjp^;MVI;_A; !cN,'J*.  É&g bn3]<{nl 1Rg$EIJbɜEZվK1 +*4?DTe& +)ь995x˼| &"Dv {L:$9>yo&fhɾ,^&(Gy֠cO�vP endstream endobj 157 0 obj 539 endobj 158 0 obj << /N 3 /Filter [ /FlateDecode ] /Length 159 0 R >> stream +HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽�'0 �֠Jb � + �2y.-;!KZ ^i"L0- �@8(r;q7Ly&Qq4j|9 +V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'K�t;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= +x-�[�0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c.� ��R ߁-25 S>ӣVd`rn~Y&+`;A4 A9�=-tl`;~p Gp| [`L`< "A YA+Cb(R,�*T2B- +ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 +N')].uJr + wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 +n3ܣkGݯz=[==<=G</z^^j^ ޡZQB0FX'+t<u-{__ߘ-G,}/Hh 8mW2p[AiAN#8$X?AKHI{!7<qWy(!46-aaaW @@`lYĎH,$((Yh7ъb<b*b<~L&Y&9%uMssNpJP%MI JlN<DHJIڐtCj'KwKgC%Nd |ꙪO=%mLuvx:HoL!ȨC&13#s$/Y=OsbsrnsO1v=ˏϟ\h٢#¼oZ<]TUt}`IÒsKV-Y,+>TB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O�[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-�u`ֲK³8%yhYѹJº;.! +zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km � endstream endobj 159 0 obj 2574 endobj 160 0 obj [ /ICCBased 158 0 R ] endobj 161 0 obj << /Type /Metadata /Subtype /XML /Length 932 >> stream +<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d' bytes='932'?> + +<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' + xmlns:iX='http://ns.adobe.com/iX/1.0/'> + + <rdf:Description about='' + xmlns='http://ns.adobe.com/pdf/1.3/' + xmlns:pdf='http://ns.adobe.com/pdf/1.3/'> + <pdf:CreationDate>2004-03-30T16:45:33-05:00</pdf:CreationDate> + <pdf:ModDate>2004-03-30T17:19:04-05:00</pdf:ModDate> + <pdf:Creator>Adobe Illustrator 10</pdf:Creator> + <pdf:Producer>Adobe PDF library 5.00</pdf:Producer> + </rdf:Description> + + <rdf:Description about='' + xmlns='http://ns.adobe.com/xap/1.0/' + xmlns:xap='http://ns.adobe.com/xap/1.0/'> + <xap:CreateDate>2004-03-30T16:45:33-05:00</xap:CreateDate> + <xap:ModifyDate>2004-03-30T17:19:04-05:00</xap:ModifyDate> + <xap:CreatorTool>Adobe Illustrator 10</xap:CreatorTool> + <xap:MetadataDate>2004-03-30T17:19:04-05:00</xap:MetadataDate> + </rdf:Description> + +</rdf:RDF> +<?xpacket end='r'?> endstream endobj xref 0 162 0000000004 65535 f 0000000016 00000 n 0000000088 00000 n 0000000152 00000 n 0000000007 00002 f 0000000317 00000 n 0000000791 00001 n 0000000008 00001 f 0000000009 00001 f 0000000010 00001 f 0000000011 00001 f 0000000012 00001 f 0000000013 00001 f 0000000014 00001 f 0000000015 00001 f 0000000016 00001 f 0000000017 00001 f 0000000018 00001 f 0000000019 00001 f 0000000020 00001 f 0000000021 00001 f 0000000022 00001 f 0000000023 00001 f 0000000024 00001 f 0000000025 00001 f 0000000026 00001 f 0000000027 00001 f 0000000028 00001 f 0000000029 00001 f 0000000030 00001 f 0000000031 00001 f 0000000032 00001 f 0000000033 00001 f 0000000034 00001 f 0000000035 00001 f 0000000036 00001 f 0000000037 00001 f 0000000038 00001 f 0000000039 00001 f 0000000040 00001 f 0000000041 00001 f 0000000042 00001 f 0000000043 00001 f 0000000044 00001 f 0000000045 00001 f 0000000046 00001 f 0000000047 00001 f 0000000048 00001 f 0000000049 00001 f 0000000050 00001 f 0000000051 00001 f 0000000052 00001 f 0000000053 00001 f 0000000054 00001 f 0000000055 00001 f 0000000056 00001 f 0000000057 00001 f 0000000058 00001 f 0000000059 00001 f 0000000060 00001 f 0000000063 00001 f 0000001988 00001 n 0000002069 00001 n 0000000064 00001 f 0000000065 00001 f 0000000066 00001 f 0000000067 00001 f 0000000068 00001 f 0000000093 00001 f 0000002480 00000 n 0000011376 00000 n 0000029159 00000 n 0000029182 00000 n 0000047018 00000 n 0000047041 00000 n 0000066347 00000 n 0000066370 00000 n 0000086868 00000 n 0000086891 00000 n 0000104990 00000 n 0000105013 00000 n 0000108951 00000 n 0000108973 00000 n 0000119210 00000 n 0000119233 00000 n 0000142223 00000 n 0000142246 00000 n 0000165193 00000 n 0000165216 00000 n 0000173962 00000 n 0000173984 00000 n 0000184147 00000 n 0000184170 00000 n 0000000094 00001 f 0000000095 00001 f 0000000096 00001 f 0000000103 00001 f 0000184199 00000 n 0000184366 00000 n 0000184387 00000 n 0000184601 00000 n 0000184631 00000 n 0000184655 00000 n 0000000104 00001 f 0000000105 00001 f 0000000106 00001 f 0000000107 00001 f 0000000108 00001 f 0000000109 00001 f 0000000110 00001 f 0000000113 00001 f 0000195127 00000 n 0000195154 00000 n 0000000114 00001 f 0000000000 00001 f 0000195183 00000 n 0000195351 00000 n 0000195373 00000 n 0000195696 00000 n 0000195723 00000 n 0000195753 00000 n 0000195782 00000 n 0000195882 00000 n 0000196040 00000 n 0000196153 00000 n 0000196184 00000 n 0000196223 00000 n 0000196324 00000 n 0000196419 00000 n 0000196449 00000 n 0000196558 00000 n 0000196716 00000 n 0000196829 00000 n 0000196860 00000 n 0000196899 00000 n 0000196929 00000 n 0000197030 00000 n 0000197125 00000 n 0000197225 00000 n 0000197384 00000 n 0000197497 00000 n 0000197528 00000 n 0000197567 00000 n 0000197597 00000 n 0000197698 00000 n 0000197793 00000 n 0000197893 00000 n 0000198052 00000 n 0000198165 00000 n 0000198196 00000 n 0000198235 00000 n 0000198265 00000 n 0000198366 00000 n 0000198461 00000 n 0000198554 00000 n 0000200576 00000 n 0000200599 00000 n 0000201218 00000 n 0000201240 00000 n 0000203903 00000 n 0000203926 00000 n 0000203967 00000 n trailer << /Size 162 /Info 3 0 R /Root 1 0 R /ID[<563bc4ea323190329b08c23c27573e10><423157c68c4948db17ce302aba127548>] >> startxref 204984 %%EOF \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo.svg b/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo.svg new file mode 100644 index 00000000..2668585b --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/reSIProcate-logo.svg @@ -0,0 +1,2949 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 10, SVG Export Plug-In . SVG Version: 3.0.0 Build 76) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [ + <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/"> + <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/"> + <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/"> + <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/"> + <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/"> + <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/"> + <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/"> + <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/"> + <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/"> + <!ENTITY ns_svg "http://www.w3.org/2000/svg"> + <!ENTITY ns_xlink "http://www.w3.org/1999/xlink"> +]> +<svg + xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;" i:viewOrigin="118.9321 582.0679" i:rulerOrigin="0 0" i:pageBounds="0 612 792 0" + xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" + width="552.068" height="552.068" viewBox="0 0 552.068 552.068" overflow="visible" enable-background="new 0 0 552.068 552.068" + xml:space="preserve"> + <metadata> + <variableSets xmlns="&ns_vars;"> + <variableSet varSetName="binding1" locked="none"> + <variables></variables> + <v:sampleDataSets xmlns="&ns_custom;" xmlns:v="&ns_vars;"></v:sampleDataSets> + </variableSet> + </variableSets> + <sfw xmlns="&ns_sfw;"> + <slices></slices> + <sliceSourceBounds y="30" x="118.932" width="552.068" height="552.068" bottomLeftOrigin="true"></sliceSourceBounds> + </sfw> + </metadata> + <switch> + <foreignObject requiredExtensions="&ns_ai;" x="0" y="0" width="1" height="1"> + <i:pgfRef xlink:href="#adobe_illustrator_pgf"> + </i:pgfRef> + </foreignObject> + <g i:extraneous="self"> + + <g id="Image_layer" i:layer="yes" i:visible="no" i:editable="no" i:dimmedPercent="50" i:rgbTrio="#4F008000FFFF" display="none"> + <g display="inline"> + <g> + <defs> + <path id="XMLID_1_" d="M0,552.068V0h552.068v552.068H0z"/> + </defs> + <clipPath id="XMLID_2_"> + <use xlink:href="#XMLID_1_" /> + </clipPath> + <g transform="matrix(1 0 0 1 -1.192093e-07 -1.192093e-07)" clip-path="url(#XMLID_2_)"> + + <switch id="XMLID_4_" i:objectNS="&ns_imrep;" i:objectType="replaceable-image" transform="matrix(4.2962 0 0 4.2962 1.0742 1.0742)"> + <foreignObject overflow="visible" requiredExtensions="&ns_imrep;" x="0" y="0" width="128" height="128"> + + <imageReplacement xmlns="&ns_imrep;" x="0" y="0" width="128" height="128" placementMethod="ratio" align="center" valign="middle" refWidth="128" refHeight="128"> + </imageReplacement> + <x:targetRef xlink:href="#XMLID_3_" /> + </foreignObject> + + <image width="128" height="128" id="XMLID_3_" xlink:href="data:;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAHgAA/+4ADkFkb2JlAGTAAAAAAf/b +AIQAEAsLCwwLEAwMEBcPDQ8XGxQQEBQbHxcXFxcXHx4XGhoaGhceHiMlJyUjHi8vMzMvL0BAQEBA +QEBAQEBAQEBAQAERDw8RExEVEhIVFBEUERQaFBYWFBomGhocGhomMCMeHh4eIzArLicnJy4rNTUw +MDU1QEA/QEBAQEBAQEBAQEBA/8AAEQgAgACAAwEiAAIRAQMRAf/EAT8AAAEFAQEBAQEBAAAAAAAA +AAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUD +DDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1Rk +RcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX +5/cRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MV +Y3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14/NGlKSFtJXE1OT0pbXF1eX1VmZ2hpam +tsbW5vYnN0dXZ3eHl6e3x//aAAwDAQACEQMRAD8A9ASSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklK +SSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkli9f8ArA3oj8U2V+pTkOc2wjQsA26j +x5Whg5+Ln47cnEsFtTuCOQY4I7FJTaSTJ0lKSSSSUpMTCRPkhC6uzc1jg5zDDg3WD4FJSnZDWkiD +ohOz62/mlNaeQOJ0VS0kpKTu6qxv+DcUJ/Xam81O+8KhbrIVO2OElOs76y0t/wAC77wgP+t+M2f1 +d+nmFiXHsqVxJSU9G767Yrf+0z/vH9yC/wCv2I2f1Swx5j+5craAZkfPVUboOnmkp1frV9Zaet1Y +9VVL6TU5xcXEEax5eSw+l9Z6h0fJF+E8gGN9ZJ2PHm3+KFbHHOqqW8gRoOP7klPrn1e+tmB1usVz +6Ga0e+h3eOXMPceXP5VuyZ/KvBa7LKntsqeWWMIc1zSWkEcEHxXo/wBTfrZndSeMDNpdfY0S3KrG +gA/0o4Hke57d0lPaoN2RTj1OuveK6maue4wAFl9c+svT+jVkWO9XKIPp47DLj5uPDR8fkvPOq9f6 +h1m7fkvikEmuhshjfDzJ+P3JKek6x9cbcmaOmAtpMh1/DnD+TPAI+avfU6+tmFebrA1xtDiXHUiF +w9cnQ6iZVyry0BjQSElPo778dw0tZPxVayys6B7SfiuOqOuus+ZVyoCQf70lOza4HQGSqlocZAaS +VGmdNdPBXah80lOVbXYZAY4n4KpZjZDuKrCfJpXW1Sfu8lcqASU+dXYuVwKbJn9x39yp24WXr+gs +n+o7+5ett4HwUklPieVj30gG2t1YcSAXAgEqhbE6nUaQP716T/jBpvyKMGihjrbbLXhrGCXExpEA +of1d+olNGzM6sBZeILKARsb3l0cn5wkp5z6t/U3N6vsyMj9WwJ/nCPfZ5Nb/ABOnxXpnTel4fS8Z +uNhVipg1dES50RLjGpVprWtaA0AAAAAaCOwhTSU8t9Y/qXi9Ve7NxD6GdrJ5ZYfMdj5hcBk4GX06 +84+XX6VjSQZ+iY0kO8PDlezx3VLqXSsPqeOacysPiSx3DmHxaeySnyqrT/artQOnckaBX+r/AFXz +elF1tQdkYev6Rur2D+WAPxGnw4Wr9U+l4OZhXW5NDbHtftBJOntB8fFJTj1TxBBCuVfjHddI7ovS +2AAY7dNOXf3oL+n4bfo1AAccpKc2nXgiVdqI0HdRfTU36LYA4Qn3Ws+i6ANAElOnUZiPDurtR7d1 +y9nUMtn0bCI+CA/rfVGfRyHADgQ3T8ElPctOglOvPbPrJ1tugynAD+Sz/wAiqtn1q68NBlu/zWf+ +RSU9D9eOo5nTG4OXh2bLGPfPBDmwJaR3Vn6v/W/C6vtx7oxs7g1OMNef+DJ5/qnX48rz/qvWOpdS +Yxmbe61tZJaCGgAnTsGrIscWvDm6OEEO1kEJKfeNY158U685+rP1+toLMPrJNlOgZk6lzew3+I81 +6DRfXkVsupc2yl7Za9hkEaRCSkySSSSmJaHAg6g6EKtjYGLhGw4zBWLDvc0aCYjQdlbUXAkaJKat +v8VTtWg+hzuCNUB+Da7ghJTlW91TuW0/pVztQ9uvxVezoeS7h7PmT/ckpwLlStXSWfVvLdxZXPxP +9yA/6p5zuLqh8d3/AJFJTy1vf4qldyfiuvf9SuoO4vp1/rf3Ku/6hdTfMZFAnx3/APkUlPF291Tu +5C6L6w/VzL6JXVZkWV2C0kAM3TIE9wFi04WTm5LcbFrdbc8w1jdT8T4D4pKa0EgD5D4+C9A+ofTe +vY5+0WWGjpr9RjWg7rJmHNbMsEjQnnwKufVv6jY3TyzK6nGRliCyvmus/CNSPHhdgGgJKXSSSSUp +JJJJS0JJ0klLQEk6SSloSTpJKWSTpJKec+tXQMrrZxKKHBldb3m2x5JABAiGzqVf6P0Hp/RqPTxW +e9385cY3vPmR+QLUSSUtEJ0kklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJT/9k=" i:knockout="Off"/> + </switch> + </g> + </g> + </g> + </g> + <g id="New_arrow" i:layer="yes" i:visible="no" i:dimmedPercent="50" i:rgbTrio="#FFFFFFFF4F00" display="none"> + <g display="inline"> + <linearGradient id="XMLID_5_" gradientUnits="userSpaceOnUse" x1="121.3604" y1="198.6011" x2="433.021" y2="198.6011"> + <stop offset="0" style="stop-color:#FFFFFF"/> + <stop offset="0.0028" style="stop-color:#FEFEFE"/> + <stop offset="0.1595" style="stop-color:#BCBCBC"/> + <stop offset="0.3135" style="stop-color:#828282"/> + <stop offset="0.4609" style="stop-color:#545454"/> + <stop offset="0.6005" style="stop-color:#2F2F2F"/> + <stop offset="0.7302" style="stop-color:#151515"/> + <stop offset="0.8466" style="stop-color:#060606"/> + <stop offset="0.9382" style="stop-color:#000000"/> + <a:midPointStop offset="0" style="stop-color:#FFFFFF"/> + <a:midPointStop offset="0.3434" style="stop-color:#FFFFFF"/> + <a:midPointStop offset="0.9382" style="stop-color:#000000"/> + </linearGradient> + <path fill="url(#XMLID_5_)" d="M433.021,241.551H121.36v-85.9h311.661V241.551z"/> + <path d="M431.302,113.309v168.353l116.975-82.722L431.302,113.309z"/> + </g> + </g> + <g id="Middle_arrow" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F004F00FFFF"> + <g> + + <linearGradient id="XMLID_6_" gradientUnits="userSpaceOnUse" x1="102.3462" y1="279.3511" x2="414.0063" y2="279.3511" gradientTransform="matrix(-1 0 0 1 535.6377 0)"> + <stop offset="0" style="stop-color:#FFFFFF"/> + <stop offset="0.0028" style="stop-color:#FEFEFE"/> + <stop offset="0.1595" style="stop-color:#BCBCBC"/> + <stop offset="0.3135" style="stop-color:#828282"/> + <stop offset="0.4609" style="stop-color:#545454"/> + <stop offset="0.6005" style="stop-color:#2F2F2F"/> + <stop offset="0.7302" style="stop-color:#151515"/> + <stop offset="0.8466" style="stop-color:#060606"/> + <stop offset="0.9382" style="stop-color:#000000"/> + <a:midPointStop offset="0" style="stop-color:#FFFFFF"/> + <a:midPointStop offset="0.3434" style="stop-color:#FFFFFF"/> + <a:midPointStop offset="0.9382" style="stop-color:#000000"/> + </linearGradient> + <path fill="url(#XMLID_6_)" d="M121.631,322.3h311.66v-85.899h-311.66V322.3z"/> + <path d="M123.35,194.059v168.353L6.375,279.689L123.35,194.059z"/> + </g> + </g> + <g id="Bottom_arrow" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F00FFFF4F00"> + <g> + <linearGradient id="XMLID_7_" gradientUnits="userSpaceOnUse" x1="123.293" y1="363.8589" x2="434.9536" y2="363.8589"> + <stop offset="0" style="stop-color:#FFFFFF"/> + <stop offset="0.0028" style="stop-color:#FEFEFE"/> + <stop offset="0.1595" style="stop-color:#BCBCBC"/> + <stop offset="0.3135" style="stop-color:#828282"/> + <stop offset="0.4609" style="stop-color:#545454"/> + <stop offset="0.6005" style="stop-color:#2F2F2F"/> + <stop offset="0.7302" style="stop-color:#151515"/> + <stop offset="0.8466" style="stop-color:#060606"/> + <stop offset="0.9382" style="stop-color:#000000"/> + <a:midPointStop offset="0" style="stop-color:#FFFFFF"/> + <a:midPointStop offset="0.3434" style="stop-color:#FFFFFF"/> + <a:midPointStop offset="0.9382" style="stop-color:#000000"/> + </linearGradient> + <path fill="url(#XMLID_7_)" d="M434.954,406.808H123.293v-85.899h311.661V406.808z"/> + <path d="M433.235,278.567v168.353l116.975-82.723L433.235,278.567z"/> + </g> + </g> + <g id="Top_arrow" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#FFFFFFFF4F00"> + <g> + <linearGradient id="XMLID_8_" gradientUnits="userSpaceOnUse" x1="123.293" y1="195.4897" x2="434.9536" y2="195.4897"> + <stop offset="0" style="stop-color:#FFFFFF"/> + <stop offset="0.0028" style="stop-color:#FEFEFE"/> + <stop offset="0.1595" style="stop-color:#BCBCBC"/> + <stop offset="0.3135" style="stop-color:#828282"/> + <stop offset="0.4609" style="stop-color:#545454"/> + <stop offset="0.6005" style="stop-color:#2F2F2F"/> + <stop offset="0.7302" style="stop-color:#151515"/> + <stop offset="0.8466" style="stop-color:#060606"/> + <stop offset="0.9382" style="stop-color:#000000"/> + <a:midPointStop offset="0" style="stop-color:#FFFFFF"/> + <a:midPointStop offset="0.3434" style="stop-color:#FFFFFF"/> + <a:midPointStop offset="0.9382" style="stop-color:#000000"/> + </linearGradient> + <path fill="url(#XMLID_8_)" d="M434.954,238.439H123.293V152.54h311.661V238.439z"/> + <path d="M433.235,110.198V278.55l116.975-82.723L433.235,110.198z"/> + </g> + </g> + </g> + </switch> + <i:pgf id="adobe_illustrator_pgf"> + <![CDATA[ + eJzsveuOJbeVLvgEfIc9PxqQMK3s4J3hOWhgX7vdKNuCbHd70DgwylK2uubURSiVxuPz9MN1JRkR +OyszK+WbclOqzM2MYDB4Xetb31r8h//jy19/sf/m3R9uv/A30878wz8c39++/PDu/c92mLv7+evX +P3z/4T1kffbV5zs73Uz1ov3Py+/5wn+/ff/9q3dvfyZ/usC9n/3byz/tDi8/fP/u7ee7z7589fbb +D7evd8d377+7+bxe85tXH17f1qve3/7651++f/f1yw+3u9fvvn138/LV51KFWuap5v9s5//JT/80 +hV38mZ13X/6i/v3w7oe339QyD+/+v/pYF3fWx13K0y5kV//8r6++uv1+ec2Nn3KCC29sKGGX0lx/ +saneYm9Knmy97/Tu6x/e3L79ADW6/f7747vX795//7Pd8U8v3+5+8fLb+peXu//79vXrd3/cHV6/ +/Pp/mdoM8feXV69v6zu/eflhl6AB9j/3v8dbf/t9vafeDr9Ddv79z9/UnF/ffvhQ61ULhtb66l8O +/eNqJqbP/vOr229fYbvXdvifn2OTJyr317ffvaT8WlR9t5o+q3/cnW7/6+UPrz/QA3ftqvrrh8+h +Z//P3a++g4zv8aZUH2P5f0qWUtEMSV9Y+K9dtvw75bqd3wV8zJdfnuARjq5MtV9i/avjO7fv/wyq +CG33m9s3372uHY8d5+d0E3d+ivBv+52vrC1PV9mavctx3sXi6G+tL2//31e3f/zZ7pfv3t5Sh+3f +f/j1q/9deybPbpeso9yvfnh9+/63b199oI7Z/3ym1v7Fu29uX9e30Xsvr19+iy3Y3gX/pQt+8/L9 +t7cf6vh79/qHDzgtysR/+uUPb168/NMtDKlID/jVd7dvf/Pu37F+X8TaUs7v7M3kd3P9JaVMfVG7 +ZCq7ELo+4hLhfrhbis05J5gAX9Zh9qv3r7599fZn2DQ4evzvv3z53e37r26//vCzL2p2bapdTrVn +9e+/qHWnW2re7gu+FQbuv7x/9U0bt9ntCv2DL35Tuv9n+Z/esDbWhw+3b2msn99+c3z3Bnrle5jE +dYC/rWO/znv6m/6Of6mP++E7Y3eHt/SumPkv719+86reX5eO3759+/LN7Te7bzlrF6bPzWZuraPb +Hb4x/2n+h5ngY2tyk5/CFGtKU57KNE/7mg7TcTpN53qBtc76ukBEm2rKttjZ7u3BHu2pprO9uMk5 +540LLrrksis17d3BHd3Jnd3FT95654OPNSWfffGzP/ijP/mzv/hLmIINPoQQQwq5rkgl7MMhHE04 +hXO4QMWiq/eGGGOKuaY57uMhnuI5XuKlVsoln0KCT04lzWmfDjUd0ymd0yVd8pRrtet6mOvDc6gl +pAyfkue8r+mQj/mUzzVdylRswRcovmBVSiy1zJJLKTOmfTnUdCyncjblXC6Q5mm2s8Pk51BTxJTm ++gS8Cz77+YDpiOlU0xnTBdIeG93s7d5h8pgCpogpccIq74umGRN9DpyOksz+hOncpQukw9QlOyS3 +SJ5TgGToxyF2KQ0pd6lspHlMBn/sN9K1z3GVTn0y41dN53uky1Yy29mbl/6zTCyZWjC5YHoFnF7r +CVan2HSxeLFONJpqMtH2hudanWmQapkW5ls33WDgrSec834x6eY6purEMzTzoFL1YU7nHs0+nHt1 +6snks3XyjdOv4ATc4yQ8wjQ0OA8nWB7qXKTZWK/V+TjjyIUZCXMSZqXMS5iZrpuWPDGNzk2anTA/ +2wyFOWpxnnpMMEdpltI8HWcqzNWjqdMV0hkTzNcJ52ybtb6btTRvs85emr80h/c0j81iKi+ms0zo +mqwmN8ztfobXZHSit6nepnteTfs29fvUfYz+tjm7hnS8TzJX/nB6bDIPuPTBE4umlcVJ1fav3O9f +ptvAaFItp9V+Y1p5nlY0qQpOqj3tZ4anlR2mVR3adUuQaXXRSQVTiiZVwklVeF870qSC3c3Am+kG +F3Ba0TZ3v4nlcHLB1Iq06xnc9gpPL1ql2+Tqp9e4BUbdBjNPsYITbG90jnXTi7dEmWIyyWSijVtk +6iZcLdMMM23cM69MtWG69VMO+8/cNeu6/XWZ0pWUzWJOLlO5M63n7Gy2MsfJfK+Pzmdzjykvl3YT +68k+f8EC7ZCcJq8JlwzD8i6sG7lbO65vy0sJWGRg3JndZHQFgfUj4/qxR/npWNcOWD0srx60IReW +gg+4F5950fCwItRpXuecqSPzqCuGhbvq32CtKDg+aZUg+beWh/ttxrkEUtgJlwFY7jxO/QxTH6bY +EaY5TnKoQsTpDNOu7pEwd3HOepyZcDl8YNrVyYatA/MIZgwMcxy2MIZggQaJEmRHeCMSCmFpgakL +HxW/jrVxj7VFjvhq8ApH3N3h6ce9wf0EJDr6nDFdjpcT9sjJYfKYUEA5RUy4ftH+zusDbxuGZb8j +J/mcOV0knSdOTpPvUpBk8EdcpbROOLEul8u5Fn+souG+LlLlkmu3xNqh/uKqKDedL+dzrcixNs2+ +tnGpfQM3x/oQX+tgz1Ot3bnW+FjfYn+aTX3DXBf6iG/va2vY01Rb6Fzf7ljbbY+rZKkNmmrThqOv +TW2h0atweq4tcaydsa+dAkt2ruMkgjjv6yiFvptqL55rqx2xV/e1d0vt5oSLYaiLpqsrah0EdbU9 +1zY+4rq8rwOk4FBJdciE2Rtc5e081T0A9oJT7Vl43L6OsYKjLdVRF3D0ubrN1JGYL3VMQhce65iB +oTXXy+CT6sANpm5fHjcymycY1bWBTrjhHXA9nlHuy3VThBkQcC44lEQnmB21d2CMHHFQ7mFcmzqB +YE6kCJ+AE8vVCWbjBFMN+/mE4/OA2wNsVgU3cdiAY4BPFQDqBg8zti4mBpTYOkxgXNYWx0m9x30O +3hKEW6gUPCeg8ACSOSwGdS1ydRjgcIORDRMDFoy9qdMMmhH2YHhzkKlBCA+Y4H74gFxTFzZSCqoU +c0Zp5ogJ+pP2QFioikF5GZYDbBiLb4uKBlYEJSRn6YNr3nTBRJOCZh9OXVEYDS+WvMlPhVPmlDRF +TkGT75KuzwZ/2FXa2gueJ9bzxHqeWM8T63liPU+sv5WJFXb/8PvDe/OfZrrJAYwCKZeAP6YEJoLJ +se3H7eK0m/1NqaXDPb82//D7B91z+N6AKcKHG1/7sf7GhYyZ9arDiawJ57ffiC2hMy/8/pfv3n75 +/tVbsHOYX35nrL9qfkAD4D/u/uO/X3243X1Vs1++/txs5qJl7FPMDxmHxdL8YJfmhyVo0wM2+2Z6 +qH3rBsODYDQAfFqjqGdkzJPQzkuHyMTO4HAU/EVBTbE0MNhi2MxwUTODgJeJURWCLI9iXlCk0nYI +JYEliEkaBUiaOUGgEIE/RiuCAIqj3YAWT4QMRzhQ9Ki15UBtBZ+CeF/t2R6YW2PdY+8KKBfWOHfr +ZTN084yqdY9vN3RbsG1Gthe9rZC20S7vbUxuMDAJxib4mmBrm/1uuOsJRROTkh1MStL1Ao8JMLbs +e+x3wx0fh45fdv2+7+/Hg6wNYo2DiZD7sodY7+rLsSczg6t9T9p1Xx4+0pcNUBUThR171HRg6mE1 +kWUqj2ZD6dlxRnPfmoXdkKHSASW96NS2nQEiDAYINRyarrOvWA4HE0NttL91XO8uFC/ofiEAno5K +I8NSB6ZfmNMO3criGayDkUhAHYxCAulgBM7+YOrgO7OFmpA52CROCMk5BOQKgnFnBuIIhEMAjsG3 +XIfKETE3B3ibqb16QKDN1e4GiO0wn3DShjpHC+JpF0TSIiJoh8Pp8YJ5RLzqo4L5tli+EspXIjkK +5CKPGxXHSSDvxXEVxjtRXARxFsM7GZwk8L1hAVzEbxS+WfQmwZvE7kRiN8rcJHGTvH1gWZsk7Spn +GxSzJxaxjyxeF5asA0vVE0rUJ5amSZImKZok6AlFZxCej4bl5oISM0nLIClPKCOfUDreo1icUSCu +ovCn9eVmT56KedqePEymU6w+uR+hG829+vFevUidaJ6kF0+o/GAXmvv3IaoyVY35ifTlsjfNPWfl +vXvTPNGc1N40D5mR1JuDjjaQAFG7UjVq829Vm6pq2VxQOQsRftS224HeZuGHRaXrpu5GCX/ESHdW +bbHpeI+8/6OaXKepHd99993t+6qc8S+16ln0MUQVJDn93+r/E/5PqvGFcQfqlTMaY44oiR24h/ZG +YQiBIuIWFKGLKXTeHrtvP2AQgTEIaxbwg4IPHeogmEOPNZwZYzg0dAGhhWQYVwiKKFic0d36Bakh +Qakf9CD0dcN+xmEPAz/iwMdhj0P/bLqRv1+MfdqQ2tBvgz9oF7TBv8fGLaY2qYx+jxBLG//HYUsK +2IBtAoCofRimAE4C09Y0THXZwZbo1orlSrFcJ5Yr/nKBwHYy3foQF+tDvzpA+/jFZr25LBhsmiM2 +zcdWhcWS0I0jGUW1LoZXBVgXeABhS3DjCGIlY6kwQEWDiCCpiWGoE4NPgjoVxZki2Z9HeMl16SN4 +0sMk6Ud+Ngqk2dHjC16VzIYs9KjCUeGDBhs4JRMic9AwUVBYgAdl9CEhD0E8mL8OxjZbjQFMJasx +KERkNIYPGHnPRi3G0FlOrcURdHW2FIuN+KBm4bOaga2af8nWm0zdsNFqjkoXvA2xJjqsZ4n2NMV/ +VPu3wB4FegzjPEG5o4VZo6T1nbHpW7NHbPKizX3Epr60Zjbcxpl5l9S4J+I5YrM6bFJp0IKNeZCG +xFakFuT2M9x4e7aq12bDlhh07TVqklYo2VWMjNrMdAiZNNnYYBdFxcKqrcaWwnYy2lBjMzkcidJG +Qwst2mdsHRhkXePA0MpNgsAG2U5l8a3oz9L9zMO/NUmBicliaUhR/w/4vyRSNgbub59G5p7gQIIK +0QcmM2FGMNbQrmIYT/QoP9ZmZgrWGfcFkiKJNDnIkVgXHGhbKQ4pcPKccK/HPRzXAxzAMASPBsXe +Ay4czUYk4m8gARj6epSAsS4hXkm0rfbJsbxCW8qlk1lObD05gNBJ5pNebAHTB6ztbaeZdedlOQXr +Uq5/5kVqVLJDo7cysKQEPHMnutSwpb1OGZw0NJntleSGJKKiNBt9ElOEhc9YFwWD68JAa+xYjW2F +WKwRWBe/v5IOQ5KBwtwgpu1cmOIsfEwXPGGHgVlWmRFEIWceO4eDAUkcprbvxkrUuTfOS5qr4yTP +IlyOq1bpIPyLrllhWNtxyRKJ7K5VrK1hqxVMxBiHAy91qNep7nbNRSMp6kqYKzFZI+/9KP/1umKb +5b3u38uCpP/zhnmHRn+XAii7zF064R2yX99/LMs0XFEQxR7lzmgbFKT7gIbEE0p1l852gbRAo4R9 +YRczbZ/gb2bunxn/JgTc4xRK6iwzM9UY+uJkiC/IgDgR+QN3jcDiwh2UQd8Gu2VfmoBtgePc8EAv +KCLPuHqzFwcOeSH7n1GhuxBDmeH0aWP2e9NNf05L00Fv1osDSHsYTAduwGjL6F1k0A== + ]]> + <![CDATA[ + RtzAWn+n04MdTH1lYexD84FRXvbSgHC44u5QcCzOCPGK6W9CoDeI6WBct0bpJrJ8I9LNvpMJLSLC +vYBTAFtZCIW8cS5G7dImI2P1uLDKbNlkjtK0zbrmcUXom5UadXTeSmqR0UHXXLfM6LvVNedoj1EJ +UR23evmwkw5NbcDmEwINeBgazy0kw1EuXEqFdXsznVDIovPfupHkPp+1EcWZgQsdlPHQj6Zm5Vsb +VFbOFEYN8jpdGzZ6RobtkRHSPQqLhXFSQEojrjiAljpEHybGTM/I0T0ycgrY6WxQvBHGUTNuOFwn +JgZTz6jQHRlS3aOyV9jakZAwLFQkZ1BHnBhkPaPec2SoVZhJBLgmFUy9CKPKUjqTMAqyqGFRdBRG +Iy62Hr3pkLfEphIxlhxZ3p4RniXQJTVp26NRzwqZaYSdR+B5CT2P4PMIPw8AtNEGm7umUhD6I5yt +EYo+SUsQGr3AowfW1n4BSS9B6U7UMD1pCyWNpZ1hPxiMRnB6CU/nnEyHQDFG/RNB9P8S1pleBlOI +zQ+cMJjFPResYbVZSWChh2sZbbsYZX0dV6DbALsx3hYGxE1RNlI5jh0ZjjBUIcBNHe7cI6iiyzlY ++ARAZYZMXRvXMKEw1qDGB6zpngHChMtwxBq6HgEklVXk2lZHkAd7M0dfw32HiwsqLpj4kTxLZ27e +hoILgCltuR+gy9C1XV+3qdZOMbUeVetxtSWyRn4TBK114Br4icCNBjeBOheR2oeuryAVg6QLIipI +EEC8AfIFsCmACgH0JMC2AAGE58LNBDxMHYTY8JwO0dnCuxTu2gvcJe9i8EXkJQgbbFU/Y52pxh7r +SjUtWEepn9TtcQjUGoCqdcV6Gq2o1Vr2dexr2OrX107qphMWNQiy4mR2FGZ/RHYcjvr/iKREVUX6 +T9XDxXYh8IpALJ1hqANbRsClkVYPQlo1OBF63qrYjYS7ajsghqaIAP97BWWUuEq6tsOVVNbSI6Il +IFDSagpKPNlHLa+nILiT7QN2ocjOk8oZNpukYWEvgLogK6usrbS6ZlxfG1NYWcIGMRVYYRs/OLB+ +XCVv1Y9FQ57RbpS4QzxBWty2dU3Bl6Y9Cnco2J9kd2p7k+xMsi/xrsRbEm1IndHIYBueFBeUnUj2 +IdmFsm4/svn0piLaeGiL5l2H9pywsBM1G5pABQ0oWJqOcagRLBKVpdxWyDNbemg3Wu5E4z40dVaf +unCabhca96G8QTHeIBcvOcVPrFPQ8L5OBm3sT2Z9dnEiWkQICQPBYR+M2hmaKefQBWg4q92hmXQc +I3fiDJg6004x7PQ7OgWeZLFemHl6x8DIxp6kjoF1BBIENWKNa619SffrXaXXUUKQ6hd7BZ719+NA +41yzd+fOWiH2ClROzWDcWZp3FgYetaL1Fh7ZP3AHIZGmY0+uiLD3oU8uTDrmnjadpRXsqkHHPNyi +c5dBZ+TbTxA9aLqx1mflUAB9nsgUhcj0JXi7wcl4xL3IBfFA0ZhuYm0iIHPEUvD2Gen7zsPf6k3w +zQPDA28usT33kffTs4kzkoqDv9cNBq52VNVYN0S4yWb45lwGIkn2N7P1aZf7CnxCIY9ugeQ/rQXq +/fDsNUPHhzvoO/WPWGMbooX3qdID/IjgcgG9i7k5OvDAyFOcuatbkQ+/E5/n2JuD7irQjFpUwn/9 +nKjcmV+w8wh51N0P4Qp99fLV2z+8++PnRn+D+GXCFnqkVtwQBlGISR0+mU7aEE2Y9GDSgkUH3pY1 +QPEFtRcENRYzTCdlnJXFA2quSBkkY4CEkVC+QK4OCl4jCQVEi6rJGhazQKpwKFydmHaSUaTyrJyN +dBOQQRv5RmgmIG44g7riCTWxoipYzWT1S1QvVgcJmiiq61BqoYeOzZmd0z0+5j4XPeTzV1PgeTPV +5jEMSFJLnTbTURMwPeo2ELIFpHjt7XUt3QeRtQ8p8F7pqWrYBMUnEDY/pUASX0bjw8Id5OECjXka +kkoTaczTkFSaSGOehqTSIAKzwDN6NGMDJKBmd53uzPozqykXTS1gxknTUVMLIrcnH1FRtiUVTVlT +0tRsjgoRsBUQdTXj5GM1NQXqoums6aTpqKkFvkMzRvNBnRV/LKr7SVI3oo4fETRpi5lWMds+bQpe +NCGqRFSQy5V0flA6STLt16vp+JBklHhyv/SReEjk+tbSku9yV7ryuUanydupB7qUfngf8mGPIPYY +Ysc8NAP1sCceCoOuTsMFPNpCzCQGSBs4ujcI4CE+ugmPrgFSgUgX/xPwgV5PbDgnszkxP8g3FhbW +rO6SvcvTjPE3YQV17AaLTk+m1nZCwy3YvMnafamThyINgePTqa6KHqMLzbgOnjvXJyC6nOuS5+py +l8j5CYI5XmoHQOMnbPBDbegLNm/ANp2xHWEpg/YLtb0Kopyn2jCEb0IzsKnXrsi1/c9pyINrl3// +tN3sIx/EefoaNK+3MHBUes83IVbQv0UIFn/flu214KOvK+3W+wkuWT3zitlz4sABjd1jrTNs7JaQ +nCPHR2KANZ6POKSfOUrnxEu/E44FuahH3t3ygvxz4GhhSAISDpC6OEtAT+C3BMHvPsHkt7b4mXuZ +/K6Rtzb8d8ynuGP1ZH0CpsWsf2AdcrRTs0F/Yc0/InDY7NVZ7fjeLEKNnMWEvyCTRra89jFHRjdH +MsEWo2b70NnsmwWhD0AyhiChTlJfq34/YhgzcaSzlkKXfJdECrNDmiQZbJw+nTeSBEwbP33IXQ0R +YLh1hStRmDEhaYvmG4Y0knydUdFs4r65cP+cOZAvES1gTLTQqjwNVZS7kt/EvtY45/bdjK2mcqPK +kihZnvtvnJqgJx+cr4Yjn2gGUq0kiXSbuhWh/95ys6wWhsXlpQAt30nEptapLQY4TKqbojtPiL7s +ec4ENvJAF+8VdHFAsMYGJsAlEoMah/sRtBJBWxySvgVrSQi0kDEHVhcyfnl2+znW5UQhFvbzIetN +NLR6IL5CVixye2rgSkFoxaGV6sRLA9i7Pdu6jwqoeEBTDBu2CwrmAqYQlAL2F7Kr827hniT9uMr8 +k37uuduyNX8IqLoVXPV+SWIeaxjWu9NVwvc6SYCL+6ftOK+azP0CwBIX+aNGkodBCuY+ZpKHQArm +42aSh0EK5g7aQQcpDFTreQgUsozGAOPjeGecl8UBAmaFA40o0N0Y0EZvma67Ns8OuIoAXTFrmSsd +tuXYNSvtXyK3NCwoiu3PdI50Z1SOpPu8Wl9zZ3htRtfR4KrGVnNVi12bWcXU2htbJ94bRc7wZgjI +GlRAqQ1I6+wywlZcmMDHWFtiEB/N4vKvxt3ql9/+31GRm4Z/P21ZvP/nRyvQ6s9RS3WDrugXumLQ +9s6iBxlVhkQdatGPD6oWHTWa2kUVI0hOXB9UNwpG8TDCxwQ9A44ZiiInBiwEtrjrI1dcGNxQcQsT +OiiYgVQlmIb8ntVM0tPC9pwO3e+SfzDMyhJmVmcw6H6Tb2tbwWg/APZU/fGkn8dbVhYGEElmOLli +7tpk3xmYZm1NSEkxpXjxXcIRYvghpy4RffvvLsr4T67AB0mtW+sSrNxowXwyWjWxqs3T0apJrTdP +R6smjMU8Ha260f6eKOgNoSzmIUFvlBfX4h+o5Vqow2ZgDvd8ZrLosRsHpaTuHOLSETTwulPnDnbw +wGFA6ayuHifD/h5HPe1nr54f4v1ROEx8XgAqI4TC4InpcZMFVDKCIyMgMiIhHQZiOh/nK77NK8xj +RD1O/CT+GD6/Qc5RKgxYZXa4EMcTcT4J6i3r1A2FXVEI0jKMa4lXinimHPWsiOYRLn4qRc+8SOqx +EhkAC0ZVNaf+K+zDIraHBnlKOnWpC8bfWRwvfTTWzjppjXdD6j+9N3fvtpi6lLtUiFNc2NWyT9e8 +kI9d6hG57hgB02+Zo8gbOvNh6CCiwQ29/yDRV3zY05Byl0qX5i71evGhJTNAcwPIqGcgdG6ifJhN +Syt3cbPwFu88xgdNsS+l7+CtELxrtuwq1yyyty4cQ66sU6tC/dcsbr2rTuv6L9+mJrOQ0iM7fvS+ +eGK1GK09y3jFnAxesjQMCe+4LKT97htty70P3ug4ds9A32M4QaMb8tZ2bAduFyxeshHTNkzI+oxR +J2j/RR45bb57ZuC3uEMn5d2TQcPiPku7rPDHHYKPYsGoO6th9njzPO95407p8825XDheZ4YiC7ve +cDAh0+2aCRFJh/sl7ZYz7pSwT8IuKdGBcIOkLTF3KelvRV1jmnMMH6WySIuPWSlVp0756sXzIwvp +fWGddZnty5NhqoLdTLI4247S0NSO8cOFmsu0SMvCpEgrfqE6Mts7dG9ghrP8Ng0b+nJDYsRziI6y +dTzgvQprrbzsgk1G2qoRrrVxbQqzaBmx9i9T2ExxnQwrc2PKm2mLkzIvk1F9e5m2TkvsrFAkEWzH +AX407cs8LUYL8cueFKMFGelJMdrj0dwHo92ifVEHnD8xncZklhmfmu4u8PjwZB5z02ZiadZ0pLcH +pYXTgrV4hHAJQO8G/ik5HhDnfkKK+U0EOvyG08LD70VC+pwdkMj5B913M00eLnf0wxKnPKapsNNB +99xH3o/PzuRTYInuTzdhrYnLjp4WxPHvHviQm/AphaJqWjg5QZw4pikXuok49F4bJnSPevCd+LyJ +2PkT/X1G7wXsmYLFTBjxE6tPBP2+Ex98Kz2xtjD8PSY8eRqcDrq+t+THYcsUlmFNH37nQ5wJfvP+ +3Xevvn75evfrH95+f/vhc7PKqQVGci6gnkSf3YWQmBWtmcQmzWJiFjGRpUSREwt7alIEMsRnjios +UjhPdAZAaOaE2vqBA3kCMOPJ7VBFxxOf4FLQhSyKCIlCJLtlntgnkxwRJfaT+GV6dEh0GkP1xP6Z +FDd1lpiphR01c+dJSx83OMtyIg9nO4IIzFwUP7stfzu/YGJEzVNDUf+HduuavNFfGRTlEMQjCQSS +VrwQ+T0PaeSQLP/CyWwSTj6aWNq7Im1uSVQfl6Tq+FjKUveVoTakKJGltuSoa7LUplQ1JrPI2PZ9 +WKXeb/JuSWmbIr8Z+1LiHDWJqclMoQtStwpRp9KTxEmL7VBWiT0qLqyj+2pzXm3nl6eV+VT9Vk13 +svhwOPhqetleDKA4Ddugyxb4sgHCdMG5OI2wzBKY2QJoztfgGkrmKoKzna6FBNRklsDP/dKCLbBA +JjaOabp2XNMKDumPeB0v7S2j6xC810Amv2V5bmaOddokCY2WFLN5g9JZidLbH4QE1taEzFOgshFv +wmE0udQzJjQQGp1hsSeihAQ/I6Wpkbon9ZHJeJbFgbWknhghsbkuyO72cpb0rBRvCmUWcXLvkeZ9 +xhkN85k0II7CxTEOad6S2nPEEy8mOEGCNJ5e32lezAuFv6nlfBhK5/2QN9LSQyIbhlbWtzVrhNgg +pg0bhNgf1CBgOruDuFYIfbNN0zVBUwwMzajAhFXTcSZlo8UFR7awfjW/th1c20Q2dw== + ]]> + <![CDATA[ + HInNtZW2YYG8CSFwZC+zBTpcgSfCJpThGZTkZDaRoZrErHQvm+F9TYbmvjbD+5oMzWN42XeZDM01 +m2FvYVnbVlZWlQ17ytqMEszKgrK2nZSV0WRtLtHBbDasJGvzyNossjaIRDGIrM0guA8P0ad6pzE3 +uI51LmRC8R0cyUaHMqYIN9Zw8ylb+ZYtHMtGp7LSOZbVf83gY7b0L5MeEhrO2sVM9hpFYg25Nsgh +18wFP0+NF35kRwhh/ggPaK8xTLrjE0kiLOgjnfkQy3acgehCZ7aw9rpQi5IL+41oQ6gPGVWIThzQ +n0LWZNWGoIdbuKCJwwPJsQftFEs6wzIZDgUkQYCa66JgRc0fMSNmn5iVTXHJXEf2xs41bPY+DIHJ +Wuc4BPfbeZTU1q01F7FgxCPJo5RSMHrnGUmSARlURwwa6/iAqkOtM8Q4hU19xjl04dCbGUOYVvEP +Ym0a3MYpzCYAnbSBFxTa+yOpSncoVVDnrKOeSxV5zz4aDEsMIrfvtuzDgFMG9ddaxh7ecEs1VwJt +LSPLt5D8SwfVIdaWxB5r4V7aWfBFCQBi0T6o491HjoQ3eiK8zPb1ufAiXi8PgV9KHDOFrlQXvs66 +sLQirEwFV20j3iyU004VXWigSz1zqUY2AH44MbJRoPsgQeOhge1wyKWWhRRVc4eqNYYIanrWpXO7 +bJAFowlmg7k6BghqrNU+PFALENQoqjhejA6WeRG+bh3Abh3CbhXEjpCYR3OPtuUI8zT+XU2OMI/n +Hm1Tj8yneniN1KN+s16cRHpanFqwTsu/y/1yxiWO3EOX9gOxpXTEljTQWkLHZemjsap7FwWJO2A5 +Ehqdeon6aQxaug5byj1m+KTptfj3cM4Y7sTmQQdrrftseaSQN3p+Ts8UU54YuWY1kWTlFl/zR6Em +qnclUYibe7263xsVmpo4Jb8dtpy2Vq5ZbvS9MgxB5A0fqqXEfEadusnHjoOyD2KwYXW7ybwi7a4P +I7CD+Br5ZMky4EMHg9v6EJkdEYyeURNYce9PXKADbI8sfp0p2DZIA4ZdyujUBUoRoWxA9v680bDt +8Lvd/G0TVFk6bo3QydZvPUbTfpsUbEEZrL9giwu05fUlv0/rGi6ftvVbjwpto0haw8UTxhdjEQgv +kqj77aje5UG96/NQr/jgmI8e0PtAw7y5f4S5+xnmzbWALI81zJv7x5i7n2He3B2zlcK/tlgZeSOl +jRQ3kqLGRn/1G2nL9GxXaeqTaSTRVdo6V2hrTx6SGWilW3tx/5lXaRVCxHRM1D6tvfe2HP820Hiz +9xup+TL+czMg9UFcthhPS2+IJXqpzWY4RPtdYGbSFBeM6ZE3jailWdCnFb4caNSXgbnUPscusXje +AM6eXD13cGcjWWeFPkfv9cFr3azc1gdctIMntvzV+yryxwxu6v2YQ9lswbFgagIRIjKYttHiPTs8 +ehM4CmDUt2mLY/Hwe8k+T/dJUEA0tsN9YQjZB1EX3c7Hm7oQ+13MN3XpDauHP6qQx/ASYrypktij +uQl8OwVZJMpGQOqEUjaEXsHRDDMURESKUN/Kd49+5P10QCsdrTphFEtmimSicmDTUU/NN7BRdsey +PuSuh3Aifvv27cs3t9/svuWsz8066znk4nPIxb+ZAp9DLn5CDT+qMD368xxy8Tnk4nPIRZmCzyEX +n0MuPodcfA65SJ/nkIv3/awFn+eQi88hF/8uQy7mTRDregDGJYK1wLLMCGV9JADjaZGWoRc55OIA +a13hwd99troc24ghFxcBCIawi6ugi0vXxAFgHFwWl2LhZbCisPhoFsaWZSDFjbCKXRzFdVxFtewR +oadJtMuAioVJP/33Ps2SbzZMhKNgPYRdPNbNkMIu2qrZ0vyZNewiYi8MvCQkdvZhF2c+U4sgl5OE +XSyCuKzDLiLYcuzDLrIry16dWAhmAQsxHCaWTF1DFGPBtSMjGcvVJeOMy8WMnieejwc74TFrBaEV +x0cMHrh1MPCi0RMFJfAiASrH7cCLW37zH0t3GOXuG8nxgSr9E37uveeyJW8+LdL5I+maCwnRfabr +sRzvE9FxI0xjH8vxY3Ea7xWScRl68WoQRgq++GQWRIIXzNNZENshXk8aftHceerjjxV+8fBnCr+4 +3VkPQIOkt8zQXacrfkUFmY2t085y9pr2GvQbkt0M89zOXdf1566lhe/QWpVtoRdRlTXq9laG0IuH +O0+4mxRFcUpk44iLZuCzpZ4HeXf4RTkPV/4N+q/XfzcCMRr1k1n+azf+3cZAh3//4hqOHX42NVDV +QSPv3geEUcehsNB5mpbYezIVZv8iC9goJVjCLFIvIyrFDSUfEn8I4ooDUappRLNBjyCa0H1w6ypx +PTz8YsdBXcAcTmAOw4EA29m7vTdjM5fsuzN5D5s+KoNr4mkwHIhRYcvAcFlYXVa2l78ao0j/Gcwi +pjN+jG6bY1jGPhBjc7cZfWY4QItlEgL1HnxYqfj7hib+Dgt8mBGqk3KbMLxyZ3wOv/gcfvEj4RdH +GtH14IsjW+hoBprQ9dCLI5SyGXiRiD9mAEpGaOR62MURAxmwD9NBHsugi2vEYzvkopDUEFES1t7H +Ay6OJLuRSdfx5YxiOtdZ6VvBFkWRWkVaNERQZzTsorpi7ZOHh1+8RwBG0/kM3j8A4x0hGI36Ei6D +MN4nBONGEEYzehhuhGG8FoTxShhG0xwPHxmGcRGI0Ww5/688/u8TiHEa3fJ7p3tu9+fwi8/hF5/D +Lz6HX3wOv/gcfvE5/OJz+MXn8IvP4Rd/7PCLwcMfLLPnXcSKYnPBXTZmdJqo2ev4iw++9TkA413O +Bju74W5QM3e2ORw8awXPWsGzVvCsFTxrBc9awbNW8KwV/KS1gmc6zTOd5plOc4/PM51m+/NMp3nq +Ap/pNM8F3q/AZzrNM53mmU7zTKd5ptM802n+DHSaZw/CZw/CZw/CZw/CH1+wXV/47EH47EH4ZB6E +z6FZnkOzdGrxc2iW/vNXU+B6+3kOzfIcmoXVh7+r0CzPIVCfQ6D+VRf4HAL1E2r4yRvhUxX4HAL1 +OQTqcwjU5xCof6YQqP/5Z6eN/yWI8X9+8v+fx6nhL+m28ed3U/kEhwO36XHg4IyD2LkcJFXi96qQ +3nV20ci369l2R6AmEuFuyVz92I4+7umyq1s46U7O3Eq8uRc+b+uAxhE9bwvXacf7fMBDUpMctFX3 ++xmxyLq5Gtz4j2ghEpLexAu+bE5kwkPLF6n2d5/ltM1CvOMwJ8PtUh4l61iWdzqJx/ApZD2q2ks9 +Te4R2aeXfpbyT5WA6KhxEYJOqEWNWKvIQigNkYos4nZ/jqcginJyYxbhAw3Vp8bV6oBETqajdgOi +KEgiMbOukahJ4H9SJePqZ7vAMytnJyar7IUV9Wc+761PozvPGscrvADUJcAo57adYbY98tfjfot7 +6wyvBbQSkJn7jKfpCsRbcIzDibp1fJMGfOka8AnYPuZhB5F/nO1jHnYQ+ccRMfPAg8jRbnm3D9KD +X9cMANTDT15fvbK5Nwp4T4qTWXGc7sQCScMRw9Y8pDKkPKQ0pJHwEc3ABgl+/IwcEjuk0T6q6pVZ +6FhrH4JNkn2vdXWpNrXZ1L1G/avTwXrEjxkf1A5yIe2OE6OwZ9w7j9gHB+yHPW6w1BfUG3pCuaEj +ytHR5swdc+QDymfczel48oi7PKG1gteOiC1jtuYqaLs84nabjTZy0apiaK5S0U58lrgw0ZCLRtrb +cIDsas6ecc8cz5BdDOSBrVeFkj3vzaVrQB7QK3h7ZO5Jmw0ot7knzF3uOha4P2fWrCh8d9L4aBGX +nZk41EfdF+8FWt53u33o59ywP7PiK9N2QxtOZp4ySSC9E55VqnLviHcA5zvZjTKTEoWQ6DZoiNRK +2HHiY1mQxhGgt/go4CNTOfJqXF8Z1Yb7Z7t3Gs1SvC8PTO0vOsaTOleo1+82I+OJRZZrl0MrPcyR +5uMInbkfRHd/hM7cD6J7gC8aS8lHlJIvKBuTBwO5LhQWg2la8Vi6m1jxYODTcLM+mlyxbFlz76a9 +J/xpVo17Z/MS7WBJK9sik81DGrfYpdPaYn8e9+6rPNQFE3XBRb2LjeoXEki8g5OKrFTTE1Ov8lKV +mboIVfaMEDwjBM8IwaM+zwjBM0LwjBA8IwTPCMEzQvCMEDwjBM8IwSeJLNcuf0YInhGCZ4TgL4IQ +AJkmMHmh3tsYDp6IDYG4JHUPQmZFvXBNjXjk/X38xymWgnSREHf1r/DrPAE/xgFtBm/J5Waqg2/F +5HnArfjER9Q2+pvZu/RJbyxlPPCt3ePf2n3iW39aD38i/WWT/YLkF6fkl7WPRqfldr4ZF1Zzm6rr +1SUjs8I7A7HwoFrvhbVey94XkXXfrC4Xzd3izHrwpG4WDqcsR6wSJEgwsoM6iJ8JEWIv8N7v26NE +R5/OuduguCc+3Xnw6N4zkLTvXLgP6r597Ny3T+q8fTb0YzvWXrj0eEZzjQmMKZZFhC9pXvJ3ydq0 +gioCklD/DITQFuirB9CWEfOotRputo2aXQzCZo1CTCgiIYj3YxATMKibJGBjEFZhLXkstkeO7+XZ +mz7y9tgLHbAxRoqQ12+Lw6aIzayVlCo+jOK8ko3MsIPL/t12b5GJtiWijU3bqEAkO7bs12233paD +dJvuZKAqAZH8cxx87UDq2aPE8/Tqw1+xV9vCO2Arhu8y0FfvkLYfljzB9RjRNhurXYP3eoDP4UIX +WXIa4e2z+pH5bar/ScDtBu+dWQ1ba10Rob4uWK8GjjoNAXtV1TKqa3kOCzMxKrbt2HXdtYtwMnZl +at5dhcM3RA7U4Dr3rgvHZDhyIJa5c/BKHG/FGw2zsvTx6ry8Fk5enqOlbLl57Q0ibAQrNk8vAtrs +PImn0WNx049EPP7kSEqEI5oFkPjJ/obmEbGU7vQ5NHdHU8Jmvic6eu9XMmXTh/Lx4aHMNS/KxzpR +mhXY9onhoUyLD7UVHmpUSDyR4jP8ANnSkbBbXxaZ6yjnIh97rYs8/NaOGQ5XoAMA3soU8zQHu+FF +cK/rP00EzpsycIag80GEYA6OcxYrKVsGp85a2ttLlxbTgxpLOVyA6QyGjm2kIHOQ1CGSB8keR5Y/ +REpqkpLIIjUZFkia4HTk8Kgom7B8YnFpC/yvYA2Z/y3o9LrHlfFo6AemPljHRSNrTItIGuvAGBQC +AwGVPipRYEt0VDlS7NFikRabtLT6pbPEYlsbbOqADd1jMiTNHXqrtMp1JHyGTrrL3Mq1nQ03chNG +LTazYxNtL/RR2qNDz4kdjM7oitq1sdEmjtq81MDSrgdtWw11om3bWpQs56s2o1Zbt1vfdjhWEfm2 +LPTKOE0Gh2npjNkHbDuyR5xVYJ8wUoTH/yMuk5FbLmPsCGq/2nRmgBCp/Ty3nIj0hb2UZg3dS65Z +Z243xwiYo/ZLW8OSN274uWwvGXstvgpWToJKXE/XTnMYD2IYDL1miPy610CvXZQCyw== + ]]> + <![CDATA[ + EQo0NEEvF+6XUqHZ5DtoVOaaQBKc0fB7YrOvV7PvrGZfh+MkEZWBwn9Y1nYK9u9FY39k1L9OqNWE +Orgl8oetXZAwevKptjBZSIfYdMvIdBKTjhYFkbJEzqKtenSoT2bLp56n0lEFkm3rUNvEO9uQ4Z28 +38v73Xzcz5ciymZghI/t6vcMjkDt18XsWwXsa+3Ut5S21VoorWLpqrX2PLky7ge9MVjaS8Sew8qW +VhvMbJnTrrXYRyxp2GDmo5LQRwJKiChE7bcOcni6R7tFbbc2yFBANCwjrsfZYEbfGmnLlmOD+tO1 +HDWcudpyHw3FMQqRvVW6izwlYSZpYlMASvoc9CeFRT+hfeGMxscJVS93IANAt823QtfFHbWYq4mK +azfL88eb25kbfWTNFl9TowdScYC6xFroGLKo1FIJXCFoBcwgamDiwFA9sFJXSPG8f6L4rXJ+wn2K +uCMArAj4EiTqPnW5syDSFIZIW37QyehTWC+DFFXNDsNW0JLtF71xHl+G+dzm9JiOdyXDvxyeKpkn +KgYH4DjIL3zIgAAVc/2t8BkEqZtEsq1aHMDQhhPpvth6GhXvfKXd+vaZN+pGxyLsCfvYY4CYJ/uY +JyoGW09mvsxvGIXHbqbPuD5QC8K60QLlepz4gUefpyFnUGC0ixZrbdW3EbXPUVuqfQ7Ll93f6ZWf +H5LMwy6/WgySSAFwihxT6IQYEwQTchiQE0IIQSjOCec0zGLP8Tdnjr5p8aisA++MsTiDYYLorKwj +PibjaVmRzaEUCYJi2Z2Y2MTxklEHnpnalCWZjuN0LfmHJPOwy68Wg6FgJzSwJDxA5cgmFSFmgniO +aG1HRR5h2sZCZh6yYTNT1JjBYlHimMBdMOBlAODN4L+mj/97JbmHJPOwy68W8890JM0Bye8Wj7Og +VjyAua/qOiPBdZPWrdY8tuUZxb45sLMa8vqwzSsz3iI+cxed2WyEaF6mj8T3HJN52OVXi8HWSxgh +8IiHhDg28s2sMa5bcL9owVUbGuYjyMAcW3FpEB2DX2/GvTYboa+XqTwkmYddfrWYEdxkKJKic3iM +ByIBLBKhlYlChiQ25c839c179PHxRSDYmShoRiLDfSLbfvI2dCE0IABKH5akj/nxyPspyAgisCmX +gD+AvXBTOIhHreyui5fioebW11tvYhdw5JEF0JtPGRsHEOHZQUGewrBwUzrmUBS3FQLkUXd/GgQ8 +b0LAM0DAniBgCHfinKG21h8QQKb2BDR4rSL+gMVexOduSVtuD1tHas1C39dwXU5dUxDhM52pfdst +pRncEcEb3FL8gDGDHjubzjmlB5knRvAcKsLNTaW5qhRGQveoQh8Zca569Zkh0QsbxScNHyUkMGFJ +yVJLanpE1Cni/wJJJ+AXEgTYAFQ62Gvrs1+kXqJT+c6oeL65+fRbudBItl2KGj2Ce8ysYqz1YZzh +//Oq7xoPIQ8INopQGKhX4WuLsJ10YlRDwZ5JCnvtxUvXixOj2MiNMQxkUzcmlO2KQtrSkSf8/4g9 +ecH/LwJvIzo4MQxV/zWMrngMFxzw38hdGuc0JJFPRTSeB0G5l6mv904vGuwZCd3unZmlqmPrHeoZ +P0yp3tlLZpbQGqlvRpcvsi6gIcfAP4SYKUgeuIcSAkTNxLDsoTOGXMbewdDLjiLntanmMTZnP9ky +yuJ7/H/ZVzLjODaaHNxruok3DVOvTb+4SNJb8aqC8qPxO+7ytLrL20rw9z5K8MU0ZsadxIyzctAc +H7UQlX8m7DMgNlwMVqLJVxSIuzAkf1jL/DWJ2NT8Mg8s4APriwV4xwMzsG2H7DrUHWLREUvYRW2P +XdS9QQHC3rlCK7hGLFhRCxZm+IFe0NniO2t8s8c3i3xogHWHVh/EMj8PYDWB+z3oSnB1D7s24DWy +a4041aA/U+9Ts+1P03vUeJ7lVmHZC5t3T8RXIP+ag/rYzOxnQ742mf1tyOeGPiIq9xziUcGi3rkP +2eM63WNFjTArdsRpsz/EgKAgeIeAi+UA8W/T+gJPo1sD4L2tJWg/LB2btBPMpk+T5/bvW/+kjk0H +PihBmr01eP2YrqWpfdlzh9HzC/s9ke8TJTke5jCkXoGj3rkvEecul76OtmJWc0WMFdIzHXul468c +t3oGOsYseua4aZpoM0TsYJeNyVHodPN1vyxnxbJflr3SJgAcOrTsk6FHtnujacG9Et4riKN6Z0kz +4ICI9GNH0viOpPEdSeMrTsmD70SV5iF3+VgVF+924XEPbbc/TplysX6Z5k9QqKSET1KqYtxSqmpu +z6tRWqYwnhvneYv13JvSW9yAzne6mdFHZuVazI/sxPGRmAqm08y2QikvT2s5CkdowYZWPrRp8n3H +OV6EDVD2j3KPlSEtDGShoxTaS/dbYpldSVWWj+1dn1sh8pX8j2cHm+6wWxG55H86ymLWwxpmNCG1 +IxtEIBOhDAUzQ4ffIjYo/AjL1iiPaJd0sYhs/YEOcqwDHeowU5ji4+JkB/YqkH/Zu6Cd8SAHawUE +0YSIW8R1ySBbfsYTi6YfxYO+PNSH/m4uqNmQ2Hri5DZ1ck2eVPqkWUgGw+4zWMWvsgkG+gVqSnXf +GRnLPWdZWMtFz75tzGXP/qLiJ9rYy0fxFBUKc9GjLhuLWXjMVv1FG5f5qCdZyhmWcJ62HoonR+B1 +R1YqtfmsZ9jJ+ZTtuLqsHGdkOZvFWZSN7HxWwnN/+qTQnsviyEk9btLQeZPSnJdLH+B/M25/55Tb +UjPAtrja2fD5w3ICsfSFpGaLaIcr9p54g18vnVfcHHybk690oqT+pMCDpt6+r6ZOw10tKXcpdSl2 +qT9M0Q+pDg5DDoW92Vu5fSdl9S0Plye8SSh8jRbZiGhCQcNTR3pOw4JT0bEqHJ9xGVjvo6PnKckB +9OjTaXi8HPkgLErUbBLJZdLUAryLayX7RhHQ0jwzZ7TIjL6Z7TcJmXBc/HbsQiucIHRR762psfFX +3pnThkumGCBavIjO6XLtarl1KOgZISF0lNDTP5FrpCv6x47+fSi1u4uk8BBejvI1VowNs6CPbPM/ +lsSN/gzgdgrwcC4tn0zbnU17GfgzA4dGTsLdt08dxaY7qbadVSucQGEFrs+s7YkhtieFLCkhW6SG +LSP9fjTOUxyX5iBsN9K0TptHnuiyZLo1auuzOtS0OyB5TNy4ZmCEbNJdrhxL0J/dmvu1ise9KFR0 +FqqckCpH4BVuv70ehKdH4elheO6uw/DoIDx2Amc38HYUXh+QSpztj2cidbGVkeyLYlPMiNAWHCAM +iKnJOjAGNjPydWbA3OMJdlVbBZT8yOxui7zkjOjkgc+xIzZrwRF6RDTUdafZIaeViGF/VZ5qVv+V +mBBWVywGxxulpLEbB16oHo2xJjemzgvGmRUntId1RmeYj5yWTmSTu0/+vq8ApcKT6TzE/CA2XT8C +TD3EeL1j97ABNaAzE6r+Cakq2OkG9LLdfAPjUvXlu69CnTwGS+r8VPgchgBmUPBKQXfxkkCRD+Vm +ymneBX8Dm1tTyB93Oxl2ySbtouVqkl6PZ1GgAbpuFGGX7Q3oVp0590G30QkSZO9mu3N35AT54tyk +bevtw257CMLw76/evb79sDv/6fZz03+pvaQnNWwEuci47h3xRMoJT6SMuKzBYnbR0ygllh6t9hc+ +qjMYOJYSA4QcH+Mq+2Dn2R+jwF4xOA7KwVItwA3YdLpBpxncoRaETbVAFQOzivljL9OYNo4n2/rw +VmwG3WHUHtbp8PFkFsrGtfTR84p7JWWZHnhm0ZjMp93+6AKFx3ru5BZlYKMsCToLaSuZToNVcjUp +Go6FkoCTEYUSg7LIgVzZGf7AXYHAED2cd5LvcJYs/cQr4Z52X/0fg9fwhkL/06ZC/8/825F/7lkg +akfJw0JBwhMsG3hwvOdVhF4DdSjSqljDIm2LtC/5ULid0mnvkLBxDB5+TqkFvJGztpo03lr40Eni +/Yf5+iSH5yEtj5hen1m9cQy2THWzIGVfkU453ZNJ/TSfp6XHPjnf9sEF0qQ6aA8mJis75nefBuNd +ZoQOVEHyl2vHdwJJwMrJsM1E18txviPlHodog32QPJ9GZ6iqBhsmrfS6cNOG/Sq64JFjo4DFJrG7 +SmwOK1UBR9rhCbV1Go8SMDLy4aBBYj0CVo963BHjsxEm0eIuRozUFgxjue1YuXbCHaHBPL8wEXBM +RGWCluWIOjlB2JruYDpLWxOK4qItCsPgNB00zcPvDQpHdodhEo6g6GXxvaW4kcI6GcbnP5aWLo3r +xGiMWXg7+i5I3aOS+bTbH10gAQCpjkdX1Xo4XRcUbFBKQAnBc3XrDkDoesADdUGTAP0BD9LFtRe8 +CVLPhgc3RVf1qlOdcUDKsVUEooNy4ZhcVxWkE/LbM06hqU6bI84WORkXAhIecU4knAvWID501miE +iSOfWh3vBzczJkTnO5LpYsLTcU98RCOdyYgnLxo+blFOVZz0BMUTDtjDEJuQkkQobFEKuxFo2PrT +xtJ6gNw1SB58DuufTcN+LvDBBSIC8T+InNViUi2jUo0WWr/h7HwY3J0no8Y4OWv94yG/Grdd2Fdd +xC/TsTW3PQWs8ttHL4E8eGPM4o1hFu4YnSvG4HnRhzUYAxtEpQchG8Owr77468/qtd977pMF+ThE +P2hxJ7roE/FiuiAUkuwiuVXacnlhOr9JYUh3OeaQRfsjH8NhMD49UYiLYuSXp0p/qQIFeIQpFdnf +AzxmzjiJPHoeCcGhThomNxA1sXnNtOAAGCbKdESGkcZw78Ogx5CnRkOatGBuLVramruwZi+MkUsw +CmqLgyqhS7KSkPdsd2uRSySqRh8fosUuiaajFjcacU/+3ohfonEjlvFLHJC1+gAmTZNKC6fprBaQ +MlDO+w8qg2bwYm5p7QK9BThc1smo4n13svdNZiNzFRn9Icl82u2PLrA3ijANoxExGhWjJ2P0Ybl6 +NobwMYSRMZsucFnsApfZFrgM5zQqax6h+HMdxMDWBhXNVcHxzIJjRpdJi7j6EbUwEB4dCo+nOgVn +VLRAeLQQc/GMutWMlkYwM0o4axEfKbwOS16u2Q5+dPGgmVMfeVD8tUDI5uPHxItl0yOeItGOWyjp +Fu+4gcF9zOMWUbrFlLZmI/Jxi32Mhq/BNX7LzieMjtPCJn9XYgzWtF8flaQwLdh0z2j1OS7SYWCe +NP7JPGBYiBgYlVKQhtIhWI1+dFLb8Z4NxS0UXwsTQ1Sks9kI5NaRYSnqwjImc1R6wJjKIo2hmJUr +YPiXU5fODFiDLbPXop2m/tNEpM55sdFX1RIrhJNOoxcyePOqFHlKREN28lpw/gGWURFOJDMRjmbe +nI4cuoncvhjogGlIZ1HQ3jxnidhE5xFd8l9zvM4fv0BZJ+UnEidUj5WfoILIT6faL/0MTLlAaMaz +uuwWqrJHfGLqG/r6iULXvFx6cqV6uhgNu7wOupwGuuSh18IWcZebGob8x5kZQD1zVg== + ]]> + <![CDATA[ + uLMtcnBzw1L27CB43smg3ZJAN2TQNX8WDvm4c6eR2C/rNK3TAvS+rMw2DHibjeAa64ARy2AR25Eg +EgXAEht+VEt+UHu+xCxyzMu0EveJARx19eJ0oohGJ/YcOLL5/8CRofZMBJjZn6BwvKPMIHKS5Ud9 +qdFZ0LMfiONoeFbgS1027iLP3MGducqYMY0qs2LIbHNh0oJ10JgHKNIZXuPbOQJWE0O5ypMUi2Gr +mHxkt6wbm1GyZyN8EmshK+tGVHjZCXzHAHXMxGNuHuz7l27XHjfp+ulFDpQqT8rLJUIHOYMIj4OY +uIT8C/+2cTcacwOpbkbR/SXPbSts111hzpjeZh4VG2mL3MYHBpmB2ybsNkYN6TwTCklyUKtHe/NT +9+7CWlnT/BrJ786wZXeHeUvXSX6GWyFutsL1lljGZ1Kin9GArlF3G8VRmzbQ9hXHO4tXPLeFNLzr +fwmCHc3wB7/4/3pRfRryjG6U4yb5EPND82RgjPmq0sM776edc7OhhHzaOTfro1jMp51zsz7mxnz0 +nJs7W+IBbSFNYR7XGtePpjF3tseDW4TIKHe3iWqQJ1HPlEQt1GkhWvYUy0avPDC9kgmWpmM0IMOS +CZZCscy4p9HL9ETLE26dcg5oo1t60x0DOvIu6TBQ5F7ykaD9caByCiiC2NgAfBKo0cNA93rU2IkP +GbsMBLqbTEFIJCzIBCQy9B7D5HaWyXIu3pTgckdAe+CNREGjKNPstDahGxvR5dijbeYA0wECrxTX +sdAeeieR64iX5/TyFnAFT4Bxu2Rvoi9xl8JNFVCH93vorUQkJF5ewNpKNW8CNRPlZuD+0fk6cOxM +6B76qLvhuQuKI53dk6LN10iQ3RUPoez9x3+/+nD7j7vD65df/6/Pzfh1OGNGNKK1G+C+uQFuHB7c +Hx984jhd6Aa4ffQJKDHLo0+a4994YHCvr1jTOfyRskKKyqimLI88uQMNMyvHvv50sH4Zlk2phVNx +jIFHBr8R+DaKeg8xpTcjJLeQneuAncr4X0LXS6D6oki0wsbbB9mIZ2Ha6FMxHd7Rs2ZxfMa2g+eo +pN51ZLYzqxNu7jaLXFNK1S5iNoLujCF3RhD0pPFZrvS7UVlkDCzuBjek3hGpRcde9r3aNTZCY2/E +atX+fnhfro85Hg865r5kG/BH+3LsyfEUFHXUXfblfUxcfV+KnVR71AyBlJYTWaby6Ko7D8aui8aP +d6RG96au3tB1t5GrxY4fo8dj0M7RtHXNsKVB5P/WIb7tYO3Xo8LoCdzH4WCyrdO328riFwZWPnW7 +jsHIsdcPBvzL+IysiAAwhX+64FjDsOt1jB057D45rMwcdV08VQB7PWPM9ViywVA+5KISxEEFJ23A +k6wOeEaURYotkWtPn3as9xW35Ec4Jd99PI0ZLAJ/1rNc7nmai/kUl78FHICAgHmAyx9DIs9HtH/6 +mTzohPSUZ/JAF5qHn8nzE+nLZW+apz1hKVnztCcsATfswScsjTovOWVxDMxU22Gn6p6lkzotxVGx +LsateJaPu39bT5vu0NDudqeqGb//5bu3X75/9fbDq7fffvFFp7L1fzC//A7+4ukvX7788OH2/duq +y+3/9w/vb3df1Su+r6pc/23n3E2kf2Lhf2oNf8BaisPZ7/6EX/+t/vr/1Mw/7sLuF7v//J/T7hvM +/91X9Ucr5418wwJf1G9acvuGF7wY7oNvb7HArwgHiAlwh5nOUMVYpaAio6pO2nmEUDi/29er7U2O +uz/WX8Ikj3oj30L9VmW4nXc3IUzzDjPxifjb13B7/RZnSxmhuydIaXAVfEmlFlIfLnfkJIXhb3CZ +PAczsES5qVUOrvteKqitht+w5L66WttlZTlPbtALpa5YQlfXjRcf2gT/kZvaxUNd8R+tq5/GurbO +1Dvl4foKck/o64HtPI3VbeNEm0yegxnUmlNXXS3u+2HQvZFv0qt40/DWrUGmVVvxTWNN8Jv0q9zU +elwHgzwKM/BuuanVb6ixDgb8Jn2rNdYKL+srt8odYy/gL9K1wzuOrz+0DNZAbmqVG6qr44Eunsbq +tsGmd8rDW/3kpnFkUnNPY427fi+LGrfmlJvaxVLj1glv5Jv0LvbK8OJtbJZVc8nqMNRknOqlGxJ4 +iQ4JeRRm4D9yU7t4qLEOCfwmHaw11gov6yvV1QVi6IhxtvfvOL7+0DJYA7mpVW6org4Jungaq9um +UatJ6ZeIfl0ZB+c44Us3JMa5JI9qzS43tfpJjX9rzrRj1i2W98vNHfT48s27H/7r9ctvwYG5+4I7 +eBUEsh92TXfPXRPufoM/axmwAWJR8pvFXyz/pL3xVySX4OGK7IV+M9OPyUaElCOFHseA3xgY7ncv +19s5PvFNV7w+r1VBa/VfBFnTTszO4HMXv7wB1/A4DnGOT7W1D0KY9WH8lZ4U0k0u3i2+ycPbna0K +jt8bkHERDQCmpxPfM1XJgZxGT7dVirBOGpm/hZts3bybSYxwN6VYL98SxO8rODw4x0KBvg64GxcX +X/xNyV42MMjINwAXwVWAga2+O3szzXXM4r4oeeEGmwAarSy/1SZIMcj1kFXnnp9qz8ab6Ka4+ppu +plClJlwYOWuGePC1k219z/pmy+8QoSAmeoRk5ZspprSrtU8w8cevdS5VmZ6aSLLCTZiCr7UADu3q +a6n3B8eVwqxU5bWEMkBK3q6+xtpsk7QrZc03AMrspAvrd2/riJPvdZAcYdPIN7OrdeMxI1/l6rrA +TFWZ0NL0e/dAzeM61T4Y6ijf+7fSPH5xF29sjH79vWs6yZPWrWUUW9WM1ffWP5IlXViram0dTqvv +3SjQPB4oLt34OcTV936oaR4Nxvqj6mZl9bUbzJInA95BmEq/8b2bMZrHU8qBbS3G1fduRkoWT1np +Xp7P8tXiUGhTv60ehfQ4Byc+1NWDFpEJInbAIhIp+gVG1MTVI9T5UK+kxYO/wLNg/tfmK2DyhJoU +/drVVbJ0xQCLZtj43i8iksfNVp9ZdW+3+t43veZR79ThAtjm6it2Lw0JyaMhkGD4VM1+Xn/vhpHm +4VDDazJECVl+70arZvGADrE2SF2ml9/7SaF5PHFqg1jo8NX3bvJJni4icKRHmdff+1VF8ngh4M6V +dYK/8qIS55spR92X5Gu9ODhblzdP5WaIFFs7Vr6nVHfpWmdc9iTP1T2rPi/GmwIzbPm9lu1s5Hsk +ry7kE5qgpwlW08VXCxFoqcUlr4pGNsDbgZXZx/X3KhnaiZ6ieXV2zBkqMLucl199roKELOGS56sA +VnekWFeLlNzqu5vraiV7keQlCItDtZ9hg1t+r0PQ8yokeVUOSKVO5Ojq5IdNdvk93tQRSPdonr3x +rpZbGyuHZFffc+3+FKWZMcvfzLnspHMDTRH5SkuKrgeyotxXePzXd29v//T1uzd/qLJj+x3k8rlK +LjsbIOROgRFapjozEiBOsbBAaXf779bi20fkSilKin5DmvjwuBddHj8S8xbVGPL6e99i5U6mITaB +AgdFQsZmCIlcF3mSGgMdhePrKgsCXL0QgRuHqE0KVXitnVAXNj9PCasreXVVn+rK84K6ty6dtQfq +1hloNgaUdGN/lWRJYf2ddR20Pjt6p8VDX7BK8E/79x9Or77+8Ord25fv/7T7GWQtv+/fv39Jv7rd +P/387YfdP9Zf/6/dZ7++ff2vLz/UAmre7fufn77HCz/HP3c3fTZ/vvunX394/+rtt6s7Ty8/vOzu +6v/0m5d/eH0LVeE/1f+x9XmAnEhEpt0NBXI88ocaPhOaxpscKg6EnBFsVod/BPmqLmqlyu5vurw6 +j6dih2YMdbJM3Iq1aFiyuqskSwobOiBA5GoaQMuHPq4D/F+8A3iG8lx4/Cyoq2zIM43HgF3AOTC4 +qybygsTGPIdAU4DncKgb4DxcJVlYlLXDnTAFAg/38Yk/5QkAIpZ14wSQvG5oSyN2E8DXts5hmACS +1Q9sbf5uAiwf+rc7AT5x5EOjJICf6pJcpWYyIXAeYEEhzrJdpRKqcuRrY84CUgxXUBkxDdeDjFki +9dfyWX+7o/5T1vsq6rsMeoutgh0t95QF4F50Y/NVzaqKspmar4pliRRIvU7ypLj+3pBu5qoc04I/ +PvUnO9wziNMZh6DPmZpf8jzEkGThpkpdaUKIyALPFffRumfaEofLJA+LS7G/taoH1nEvLZ/6kxz4 +sTaCqyt3HYNVt3VkuuC8OqTzbIf2A0wBRBTCRUlW7i+TPCmuu7XquV7lpsVTf7IjHxbisBj5ktcP +aT/DijIPQ7/2Bd7TXyd5/dCXe3Hse7Y5L577kxz7HiO42mHsS14/qLXxYfBbWvbraK4dW4brJA/K +U2mI78XRP7M4tHju3+7of1I5P9UmivPcC/p1JS9JhruImhmWcDvI9f11kifF9fdm+BsP98VT/3Zn +wNMJ+wAJggzTC/uAB4HDS9+MEcDiPIj2/WWYl50WN/QAAspxEPf7637K80AAmH4iSF4/whV16GaC +gDz9dZLXD3G5t58Jy+f+lKeCYDD9VJC8foxLO3ZTQWCe/jLJ64e4dkE3FZaP/VudCvdFgP/th7ff +vr7dwWO/uwUO3iJjV9vUoq07jvS7+xIJ6H7aSmoZYshvv1leq7L89lafQ+BtoeEzsX8fzViJAS90 +ApzWOHyWdILCWxu8yRt6ZP3tdf2ND2QPXJCY2xJRBQpR+XDUYsHznQX9VkcuPhpaIO0++3z3u/94 +QG/84vabV/XX9y/f3r58u/vNq9fYJVu5APSEurxYcAD0DuxcDrCDiHY/8xii5KLENy2LSxU5qntQ +nyU3vliXJd3KLJGBZcocEOrrmF1EJitSRdT7MOJZgrxY49n11NU3nlocFnAkAmUxKcDNxVMWAzCg +70OfAUSjOSAeOg8HDNDagTfOfodXc14tPk4zZZUiWd0TIecPUiBxcOMUtCJ1b9hlkIXC1UdsVcWl +OvRnxJRmP/Eu70nKxevdmFcfUdUKvdXj4Q/g+t+e0OrWV7m1yrWmg6yI4kZdpVt5AJ9UDbKu4+2x +LmbMy5PX2pWMSFeydsyDRwj4xS9LL3Olw/6w0QJvrrTURoEbj0WTc46cNYtKlqCv8E4/5uETWO3G +e2se1oTztvrnDzheZqIj8UkWShq2dGimo6M6IsgoRBCSTTBBB3LXvumytkbAR0bFojTI+q+N1ntz +vTtgiG5kbbV7n/df3ajnifDGXJ9rwL1YZ23MoC7rv7oO4f5902Vtjb6PjMhFacN7tOnRz5h+evAC +sZG1nFfjVHuI9fbLP71/+ebVN7BF6K+0qM5ArpxvHrdjN+ofloMVlQK7b4xqrymAQoWjNZzcEHZ8 +EG3dVuF/GO3b3D8smxuVaW0R99hWhdftwtdGGDTkDxGJARhprnlm3UEIABDxAvIO64U0w+gtNp9V +89szu6ewo78HMkO9Glk7sCMRv5HdMDDkAE/iq+V3L9KVz/UPJNMEIg9OdJIuNWfnhw== + ]]> + <![CDATA[ + 373F3Y220X53DLMHO3UU+svh/Q/f/7eU89kvb/+44y9VCvjcVJWg/v+7P5ofzNDn22MRR+IXuSqq +uxLmeAOOtPUFv8gpAcbmfZf9YpFtYV8qmM33r3P01rdYn1/V/79dFONh8yn8UAsNipkFcKUXnOlT +Va7BQ5gINsuacBEvDLT2hgLx2RdAkZrynJrg/9nhsP/66x/efPXuw0u4thPqoXB3k+r6Xst2N3WD +tVw9X6tXBwRm138S18QhVYaqneoSRpeCYzhlVmHL7+hCX7VjepM6P8ruyPdPkZ6GYGfecVPMdHsG +zJ4bYq7aL2YiS+rI7ZPCxNlVZEv8KJTcqVJu0udnKSBV9Uuf72wIXMDEdbU3xRbJ9HPkzOQtvxVy +uLQAqmxtrVqAViDzpX4KmTORJomZNgWr94+t/ZQ9WZ+e+TWyDUV70gM1ibrHz3Yn3Zukyq0jXcpc +ZVc1bK6yJz4RXTvnyNcm77iAZL3fbVXg+KQvl3lAeqBAe367OoxicTJ6rNQDJS/q0BA1c/byFpP0 +Zx2doXYuDsgp4I65+bSn7KdYl+HEVc4x8JsAZY8bHypKWUD840q4yHlpkruLr1Lske+OPnH2DPR/ +KTLKW0QvBYxPf8pOSjeubmTdA99w9pQyLwZTmSzXoySZYLN00tW3Q1GZp3hwcq3NshjVKSaZLksr +xnZ/iVwtJNXylUANoQlal13OdDoDauk6SEqRGWBjoqpWfbSuJTIDsuPMWDKPPA/8ZXn+FGKgaT/7 +KDtMrQIoTpQNsgRl1l+5XilV6W6zYZ+y166NR98GZKzrm7RPlCkOVELKtPPsukx5aTfLtbBZcqGA +QrYl4scekdAhMnD8ZHXV8DJysg+yzQKxW9aS6LPV7LGIp1wKqlZbdJ2Bfe4NZwcdAy5GGQNtvM+a +FwEKoJUuBdlmcx1vshJXYYXGJthEZImYXAycWTuEhyAyIKWAGaBK2v6zjNdCij7NA1n0cxUJZG7i +y2y+11P2aUHtCevmYMl/I7mzpVzvuXlK7bHI23XtUCuZpfD93U5Qs6vKzNmJX64Ar1pLdbutxz/h +q2UrZdNWim+Wq3YAAbRIaNDhmicdJE6X/IxmCOkiFrDy1O1mruq39MYZFSrOraoxXzrVEc8dD40D +b1xF/MSNUEUpmd9zlaB0ugS9P+jAmWdaIOBByfHIq+Kf1wLKFHlAx4lHzlwX3plrFYoP3ORz8dyP +M2Cp0mXBZhESQ9FRKptF31w4FiQbna3oaVP2XIQLvALPKiQ63Iqltq4kfrNofZb7o2SiexA/aaaG +hQHmUytAReoo82/Wa8EhKUl/JU8tawl9OfLgCLzjVImTJbmaWTVfkVMTCQnLYfS0I7RMMhirZuJ4 +jFpRDGo7TEiB4lwvDSn9sy7hCRfU7MmrgceUaFu5tvgsO/g0izoD2QDy88ZOMkgGC78uvtzKDk6+ +5VYOttb5yPcH8Ltp8gJluijqAPoocCa4LtC8Kq5oAclNnK1zsNYlW94kp0wKTfbkJUpVzV4KgM2J +F6MZZiNfyptCfVbMgTNnqDcNyknHVN2addGDhuM8a4sMas5qUwKAArm5BLrQ0kJLNUJ3E7o00ATO +kRwAqc9hdkrtZytLGIsIGYSt0GueXGiSZQUiffD9tdhcdLXBocRXB5HCQuRFqEr6qgBEbanFaHnK +mVInqZNxEHWicD/zqhlkdPg5tyt5aFmRlPA3GTAe2oQurQqPjjh5tTRzky8f/5SvVkU76SJYct5I +5uStdKaz3PFWRwO6mdwxGiIpB7RA6qVWllJ93cXTn/LFwJNMBCfvnNdXq/tIP89fmKFyrFm/0EEp +F8dJZ0VRJRoFtc2nPeGrzEjUkCUZFq83ks2KOyMUkAkaWOYOyax9Qu1jct0+ir2EKhSPNcRyuFDd +cmeWN2tmUyDaikVSdJLNqcxybdSmZFkCkCMXrCg9MbYK6OyWLROVehEx4MRDzISXiTLXFMOBdUXl +DgTt+FrVVnKhkQaZYOGnRwGeRQXArqwq2pypuYANUPjaME04fMvcK3PaBmXuFgFu7lKo5blWIXLm +ZEU+CbIIlKowzSL1p0RSS3GAyIk0BKozZE7kPURXgpJLM22uz+KGnWyU3XDuNGLPWnbNtNKuE0s9 +NU9mOqxNRQv1UTE7T+JczUT9g1sleM6sgo+oJ9ZZLWBSpWGO9CjwYbIKVCWqU9VkfOQnRVoCKBtC +Ocqyb+Xath3NllelrIurI+hACghZy51I5YUwCrPMo8LoXmavYboS/iwrWJoVjZp5cU8K6jYtH64M +0q528lELiCp+y8iCAniZgE0+SWYAyzGtjLMgpDW7dpxoJ3Xw8sOqnhJlJhcvmSFm2fqn1ogCZjqa +1DwIRMrljqkjC3UOeoE68nhogqohSAe2Fg6tYsGEIRINTa4CCoqMzWm2hTOLCiQhZZkwMM9E9C2k +h5V+v6lKReDMiZuFBT2ZMW6evYyCSQroOoYVqBIJLqYngcooBWC8BnpdWEDpvZKi+JbWnJqDax21 +tdNMcChmOVhmcVLVm4cAXxmkpRzpEzVvnpxILgB10/39cEe+Fy0YDZ+ONAdxZZHM4GUdhWw3y94a +9NrahyKc5zlzZtM0QaCX+0vysmlwVWveNEnztzIbQmCTrmIzQRttBHGmnWXTcSlJ5mRlK5sFYKrZ +JXKtfCRUb57I/ZfaDyAzykxepvDss2wkE4wwgYQnx2O1ru62LYOwqVCm9iAKmrQ7BF3w4DzEtr2o +cGMJkUb5WHQ/adYZmCxiDGjgTc2u410wB5aD5mbkACDCyvaE/U5ztdveRFdx5LVNmbMAIZmXBXg9 +QUUnK2AnXJlVpXVFtte5lcl67lrCeErxZflubzhX9kNHmwVvx9CplOn45UAhpQWWbXW6dScvJrxZ +2qaJoxCrVdo2iGaGWpy0jlXIdmJjF2TySgbePv5K3/w5RLtipefYuIWGRFk5vUhLbF2kTDD/HLkA +MQCx+Y4zg44H3kB/1K6HeT2LVpanyKAtyFIKz+JuwJlJ8K5UoiwiW1LXDFFoZG1NtLRAngrrrIHC +GmKTyIegKh63q/WEuEUt3AfRuUFMkle2s27G2coaO8tSgqvWnUt8wz8RVuNMxT9xjG89/yn7M6ho +DSum9ie410d5EYYa4VovmU5E46B4GMwlkRcLWGDkWstyPAgATh7mUtRSxxo87UrV1kZcEt6wmhIU +EsPt7YVoL9qlrniGLNaFPN3gylPopFXUXN5gtlfsMRCoRZmC1dY5TmpInkBAEAMe7qpHLMAK/hpo +d6JLwyRIGdqK6EIvwlNV6ZLeLgJMuCH2GORO5GhDpTL6NRft6qAGkRmUI5nPoS3xGVnbJC1l0hhq +HrpE0dy1k97vlDjg53Y/isOUzQJ/zUxRlviYWK4AsU6EJYgsqwXEWVTkQCSFemlg+A2wat5VkxbK +JlC6P4mlGpp1ZlGz5tqi1h9WsSGEjKAKWBStzXMR4AfRIFnckVjHreVmKcCKyiUyZL0yF1kTEZGh +AurMkvsnH0THbwBeZhm8ZurAj6HdHaLgj5mRzpop+3bihai+5lTUVBq09k3hcqQ50e1FNbMQpU1x +shWF+eX+pHs8IjHSqE0skmGV1G4JOL2Tri6T6FUoAEmxYsR2pF9T/4uRFJ7FUEKmnYgeVWbbxkoU +BBP3rxec3WRrHYOlq1hitHqGCAc8LNA0TcUW0l/50iKvC8ECZcWcZyY7zDOstIK4JrJk18w4C040 +QawbmpuJkWkGyY8yZXUUMEqH16qklAkbh8zcYHDoBinAexmGU7KRr3VeMOcoCwFGHpBHgax35FfI +KqSgAsnVUl1Qdr965ayQ/fAKcQG5w/o0OVHv2GADmbirsCTPmj9kS7EASgZeCt2UZcLMlvNEl3ME +ntPtThlejuziL3iFntS8q4spcFrU1kKyOGQ2OWgC2/WRC2h2D9w5pdxkZZFmFQcy86xIzUTPAlIM +Z4GCfOTtBM4Y5buJVnI9c7acibiEFGCFfMSYMOS1fmFmQBWy6uOlB4uPent2YvebCVPCPa7RnKQH +kTC8NI/j85UkMnkrVWXkhYlAmxvnU8oNuYN16luK3HB1RWh4D04sLqIIRIvR2DbLfbpK12t7ZkJC +txXKnr30HguqkNm0bhss52VV2rP3MqQQtlBd1Ge+tpFNcEvmAiZBTtv9GSJaqdW4UO8XckGk3iPN +BTLjrLQjsatAdutpVtDxWiX2saSMmUrxQW1RCsgdmmHp2hmid8p6KzWYOzOugspYgGLNjkC6jK4e +SZDaeZZS0a+bR3WRUQ3liiWYiZRYAGOqQXRjyGzIEzNuOFtXYTZNQaZ1goZEQungUbOyDKK+wUwb +OzdX0mfNiqaEnDlTAGzY5GdeF6wlpmRRvB4yoe/lbaONlAmIUxLRdZ6kAKcUl6C9aJ0a/gKtYpQp +On+g1U4KYDWqipmg4smlYk1H0yRVdVYyjay2NTNlZaTRRnrlpSxQR3QJ420bsgU9DQRpvuCOERt/ +rWyUsdnkdNbra5MIkyoQm0EmR52SUiqI3y84exJ7xSzbSCLQjSVSH6TUoKxfQcshG5mRPOe97Fmp +o/A52AApE4kQdK2LWlm1F4h5B7JtUFiqSA3apitjMOlwZ6icbo+dRBb59ipmJkE62U4NmV5142C1 +sZIwAJWPgVVyKuZ7WYcaJqkM5Y318Sn1uEjjl5oBrP1vODvJduqE74Lv5wQ1RozjxXYZT1tBgX8h +8lOxWsFiRc8joBcrrVPNssAWFfmEUCNTNyJ0Cer6BOU0Wti0nxePf8Kdz1q1LICuPs30bjDnlQiN +atELzpYRC3L53GXrljbJYmYhTp9slJHkkfXjnvJdACTJ3Hg4W+ldeNXAbCRA0vo7M80rUDRXyqxS +LC8paoGDpTLqbiMbpoVlQJfKzFuQV8EStWG6HSTyoow0mqeQ6RQPIJZYxkCyc5AHJXl+6ORF1GEp +EzczXv54AQZtWEYfqJNyfwczzH63zGO9eaMBn7J3MhiOROrXgVaUHeHb3lR0Nje5x4JhR9YgJSFn +jCXaFtYo9ysoMBECVPOaXQaVMbldLOyuSQeF3P94yydFws6k7hRV9amAmj0FMbryMmp7I9Ism3Mh +1hvVoA5ELWBmsy+Ycaw8LDYLeabXclXNTNKCtjADD7Kb2MIG7qpJUNQozqSVCIMOi5SYktxvO+sW +G5cgszEucfmFzMbyccLX5uykyEpEtR4KEHJjE3AwU/ZchUGyq68zi5DINnbIdKxoBrFfQCbaqYrC +YFLArPBcjCRoO9+9F1O2IBM1CrpyavcntRzMrCU6WBiUukAmL8hUky8Ke3R/QMoO3Q69hcuiq9NJ +te/E7RpJN6NXJbeTKpt0VPNJ1H/InlgmB6xBJBxXJZx5wdvPrpBkxVUI1NxzZ4u2jCRCrmjPnRNU +9gBiiPDmyAkIig3qLuS5CRpl1HcToWYHMdOUOEkFivpLWXJRgAfFLIXWJ/DbQkyoJg== + ]]> + <![CDATA[ + UvNEwgJUTieqMlzpglqtaZmi7EaWgQMn+VoMJ1xUV6fMOVldqAWuoKhUujmh3pm9pdDkvOzQllwz +m6SPQBYV4FTQBeBSsF+vVsoGS3ieqjSQPI0Dvzk4PStZnMvv5bW3Aq0FlCl6Fav4VICF2cHLOoq0 +9LKTbIp1lEbubeEgBWL1Us8WMk/Ta3kSVOsozFH2Spdy4kyx/YJ3hZehUbN5zkda4SHol4L0VQqd +JZOFXBV0aBogyFHUfZCLzILBzEUzceDw4+OsBWj7J9bia54wVXh35cwiS47LInzDPPSif4nGDtdO +eTG0XVLMsVYAJKUjLwQlTarpJMarHDu9FFVsaIl0CkgzaQ23DtGAEIfQrUd1dnTbeyFbqjpYzbx3 +WGgagU/YoyzbBI6BUsAkG1JqOBLqEi84V7gmnRodKXrF0AtwpZvcshXhWrZnA1lvkgLEBgaiiZYq +FDuA1FQNjh0VDAfSC86OU9PasxShsB0euMAiD5DsuQIpq3TkrCwGebKO728SCBs2sLJWV0OnAEMd +Cbp6sxsXZGaxoUjXggTUkz6bACJamJ/kwsaVQI1hS356StksKfYSaIl6I9lsMwrC2cDujQI8yIJ4 +rc+T7kpBfEixVCaNBt3t1zV4wtdbratvOFdsFzVXFtUsNjJmykFmM5Crm0d9qyr36ZoY9FKvzEze +8TcW9afrt6W8LwrPrNNH1JU+z/N4vjohRHJbXCuqQV/oLL0+6hsQIqj0xtbxYSJTr/WVp2wbNCMU +QVykbXLoLSIvOLdNYdzMXmwW8YSggocNKIrMyD2HmVnhVrauY7ZCBdYmEmLAcU60TTYXLAt9wuYM +QRVmRy5lbzg7swsnkeheSK56FeWZdteaWaUrkRB5MVgX+4R1To124VHxxSoP3p7sbp/RP1Xt64lW +tZQ6lFcZdpgt2kqeeH8EP0bl17G/fgaHQXZZalJaSqoHBgIWpNTSlkU6zYCybRNUWLWBGjDbvL4i +C18pKh0kkGXiyK8r3K5AJ0BwyzSkluzukFl3QpmOkQ33OTGQyrIaUtuz2JRkV4CAfMw4ChCort0b +ZYEQmB0c8rNCtJ4kp+To4CpqvigyfQLkmoDLqPavZBFs5b2ZBIk09XC4GkAjWFCd7jUkHMCRIOxD +Uq8tpEDFos4QsBYJ+l+zs0iETLvIEYw106JXa2ZhF5ZwI6wNyK0ii5CukIiV4VQYZirVrrHRcWZW +HVq9AuowVV+KwMRZvHSFPMWgD2KTn9yfospXfP9WmUH9qAKp+3J7bQnu+kB+j5DZ++Vkar4BT8ui +2UcABFSkT9x+niznPABoAkbf4TM4VKgA9lplGZf0NzgjxortQgxQ0SniEWhaSwGTqMAiX0VLjpk8 +oq1k4kE2LDMKTAshiIsYOkRwhiN7RKFITm7vXDW8diAYpVqcChrAEQLv6C5EwmEYtHJwIMH7azYq +Fyx2W71d4IZChEa4MKsYi/xYfb7qmZnBndj4Cp42Pn5R5gcy41IKqLNZlBRLMlGgOHZ0KSMjoXQN +IHTqHLISVr3q1KHXM8WkFhCg02GZ9f7a/9xVdF3qwhZExiRC46ezDE53J7UWBKSr0u4UuxKYNoVb +liiZTLDLAassaLwVxA6OHVAfNGQ7cOas3veMx0IBjbQEruVawGRlrXK0EbrOa8ry7U7xaE88JLrd +dXqfc6TgBdthczNPawiXpdwaNN1RARCISdQ2sUtDZtTNkmcaZsqV6IxMBdha7yygK7nnYmbUrma9 +Ew4KmNR4pxw7OPJMEAW0lPKzkqDfXQUaNIZsKHkDX2RYNJOin6ssLtmy3MMpZhr+wvMG6AtQ00RT +t/JiEPsa8DfqcZcFwYEw2UnRBkJDfVTBPqhG7EPjBCr5DnKdkmbISxPyimrkaHXlzFn42c2G7cGv +RsQ6UpjgaDeODOCJsM/yX3OMUhrPdbGy+WZFR9o7xphW/IE8PSCzjTjUA47cLDEKMCKQIbaVLESR +0eCaOYvTHKpIcn9tQNnJGaT2uVvcBVjCTKFdaQQV6EXxlGVnmxdartCWiiBuRdEltbbWPMecHSAo +5W4UiMYnCqoHHoLyk2R0T4RT0f0xtfuLZhdgB8joHJ1teHzrVGR3GSxWox2IExLkRo0FIWYgmOFO +kUiua4A9S9SAJFGacNKpqF2IdQEHok0aaoPY9TBpG2XCK5cjOLKzUwHkmgJLnNOAUFJ/L5PAkSci +3e67SWQLQZ4Yzd/ZrmMpMwRxYbHRtWUzexHc0QpNi7m44nrynJJMmS+ykwVwxFWncsL4Qf1o8cDi +VZWEy2wuVOJXg9k6gngKQJ76EbDnMmYq1VONN3Bc4iw+ewJO1sygrlFTinJ/9ivzE+QKQ56pspAX +4yS+OsSopDKTUH3FhQx2yEZMFcgjgHOgTCt0KaSdWBgfjo4PlA26aVMiDNe9fEqKuhNZAiUBK4KU +BKCASxWpE5Il3O60TJbP4LRorRR2tNzf+U8UHpQzLUfUgLyy1cyG93hdhGr2NAftbhJR8Vqx3Qjm +DLKYcHCFHANim7oTS/vFieAU3stpUEQ447gZIFXBGIwObCbHTGFYFatSW93LhUInwd9AbnPK1k5R +ZLmgkVF4ooDMGmRWljgHvT1b28+fFyw226wBOBwL+VAZ5VUTLxgEd6EosnOeSP5q6UMeygvRR7LQ +WzKPDFRoZHf0LE/BeZNeBOeme8ckkR28OI2CklWVDNERyMkZM9Vojo7Hcr/AUJ6owJSJPpFU2Zml +7EROpbwyCpmplms7iYjVp9wNl0lGQaYa8kbIsSlQ0eziyRE2EoEpqKbdTHwyOPw8eIWfZNOLs/KS +Nf4Z6sRWRgzTuyHTZ2HEKWceskXIaQpcgvjeYamUzbR90KPK1GpQ+NpGvwNVewoiDPA4nAmoLyMs +DMdSelE1PCtlaepk5cKWUYhXqDLhpFphsn1AMt1gAS2IRdc4L3BDcaqCxlngihEZekLUqQ6cLnAi +TN43nK2eAhwZmXLFgQAUYD9rdhU2ZKvjXS0CFKQcNLZUrJ/2tK+yqJ2+SpRF28mESxQFmPvEl7sm +EcziwVWeS9VVn/30sAZeNA3v2yxetdrToYZJBzLvfm8En7NeYScSnyAkmVNnWxnJubNPNw5eyqoK +STwUKrQF2/CSuajAU2KiueNoJrUZwIt4WYBwFRf0cW6mX2VDrgt5wvYvsFGJaRpgBqxgcRSMBHMR +CHrB2UJODRK/KhfmhtC15KJQYKTKmqXhqyA7R8ECcVpCZiCmMWaKC1kJ6gIWSbw+cgUmhXhnlpVy +Ubpmle9oKctJBMXQyX+58UoDhVHA18ot+CAF9YM8uG9i3JBDKGYMoCSwZVDOcfY6hCLBWi84m3ek +SNMG8np2sZDcMZpV5NZSFwXIFRtQbIVajS0QVISDTMd6tEjAEOkrCOesCTAZHOakArFMVoudFCTy +LJdBzLcktAdPQaAynkoi2C9OIioXA1oLSM4Uvzx13nkc3xIyG0qa1L6OUefEjsX6CkSSK75rbpgN +szLTAqniNN9nVYQDhu+US2epEhHbIE/r2bArCPhW+FKOHQN54jkbBbqFAIjey76bhTzUhUAEfsIk +y1Vj44uwCVeqVKexIeBZbUWQbu2i0HFwHXoBp3MIh628vyjngbarF5wtrgpRwUNoK3Vq4gB71K9J +RoCSkaELtFyhrmDDCoA9ifxTH6Vu0K1lYQx4kRfFoJFb5I8gcRdwaCpVCVmSOmJbvGb2ZcEhr8FP +xCcAI8jJ+m4JzKgzDt+bVk/lL0FoKwWaLdkK4Han4UrZVQoepJRH5BlKrVpADemb3EILQOAi0nBz +AxAD1Uoq4JUmxHaJ7JTOHtSBKTsFDeB+jrEA2a0JxXC8vby4hpJpJEDIzbNMrtqFSRctp94LcSc5 +TvuVQPXsu/A5ybIrIq6E6r4xM8BxrYC2NDgrDijZd2GREOOh9blxLsV7IqeOvusEUoRIO1E2I1El +a2ZWInWRsQIcCNVtimv3a0CUwiAZxLPhEH+BfuNMBS+9stIgVpDK0OKqkQs5mAwbTNOEeQDQ/YX2 +NVreJmG1QQwkJ4umNEGZNHoN0Kpo1aobesOAvbpH1my1GHkv+7mliKa8TRN3AOLs2JmtgBMrbcVp +TJRAw533Y15wmZIF0oSV3UmIGisR4wkFLPDfn8TmMMNu8IazkxXXHKSovpCrGaoMEkEtQwgfLyIF +I8MQ64cNhLGz0JXmS8h2XpZf9FrZOiHTqUgwC9sDr6UdNao/J2RGmYl14Y27zRd7wlabJ3W5juRC +gK02W3VoiuLJjZmTFSmGlG3Ii3IhHg5NbwchwWTD9JbYdBBNaJImY3SmNJtuJJsM3Z9vmvmZArNA +noQZCRI1p+5HirwHor/S/c1BPnbqHYRTsiLMUrwW7GBmUkRlhJaoEEDo7AGQnVUYZqMcBHPi5TPS ++k5PalLUrBw/yJ5KWUnT6UblIFxqJNfPuoBIREBsh6KsRCb0QVQnhm6jkl3rlbO2gu3ato2nbkaU +LipDZHABonvosqAvXFcgNh+Esc9DEKZRYn40RAJRz4468/+drxQfjiBnPEBmbTzlS5DcBiFLkhAu +2o4FMVXYTSZKUCIswAq/I0m7zCDNSV1nwcTnSUO1BvKfh0ynBO9I44Qym6Cv4Vsgm2XnqMEqEIkO +PGo5PnRGyEAmghqmRMGkRzGih/ikDs7CRTZKV/NwJxyCXzWz1RSkH9HIktOnN1uZjkJELGTAssyG +CFziynO4u/EsEnlvifKRpM107xOL4npRecoVy2pMuohBDGXBEnMEHFNAyC0sTiyxRrIiXV+xoNhJ +1mNeBWqexCCMijnOjYMeOxL7qlpPpZn/1sx8St9v6Syb89tvhpNs7nXATRgOuMFjSDdPualS4+Y5 +Nx7jss/U72/GnOgQVmmn16wy1NehL0XOtsGq/MqABINnFwU6BinDaIQYS3jIYaZj9/goTj4iydVK +W5Cu4ZC9L9B+wgppYnnoDZsqeB0FBhLtGyCeIhMEiUakkGVYAXFxltu/ZqjCE38uWb0Whji+iFxK +U4gbZKYVViYbX9nFzsCFjYAGwEmZzAUSI4lWeKJKFpHXBb4fWV9fM1AxRdyJ4AwZds/OQWRuPFjG +CXwRMko6yaEd5WvWxZjqXF8KVcAv0M7AoWYA6GWJFQw9Wn8g3XzN9i82lcHhJmwtBoIELiGpIZG+ +ti958wDVDPyC8P6aHSKXiqerUJ4loAUy2SfN64EA0n5HM2RLY5NV0HVdzeGswLBoKY4mvKvYWldj +5es6YfGcVTwiC07OwtPBYK4DbwNPusKjOMGBGw/BG8YW4CZCccaGxN4BLIOfGINcCpHmmTkABgiu +Bh0E8DUD6lLjWcLighzYHiXvpqNLHjSOucw+iiI4MNsWdCvHykeUQQ/atVPtVTLZCvW1QAicHfTa +CAYCelfXCDizdA8ExQZRTkYNRzTtagD8FalscXnR6/IGi16X1130etfcrddBb5+ckA== + ]]> + <![CDATA[ + ncbu4k5/6MqzfEU9naZvDi/mmK7donbn0MZoppKJLdn/P3fvsmvJklyJfUH+w50I6G4ob/v7IY26 +D4dnJKEF9EggslUEAR42QJAF8O8Vy2wtj9gRvi+LmQUNhEIhb1r69nA3Nze3t6Xz6M+TK4t0rofc +a7qdPDTC8+THosexzujgNuRrUICJ+Muq2uXg+ipO+TqWZZatpmwQkPGEBhRBdzhps0OVE4iATDeA +oSKsnG9RuyLsB6+ZsHoOXYQDRXcFzPBQtP873RT2SnwhvLoS3y4UemL6edQkG2+nV5FjhMaZ0Zrh +Wc891JSxLt5s7QcC29CNofJON+c12l64N5dze5G3V/7BHR48Y6FoS3hbEn1DzlvS392RHY7fnsfm +4B5H/Dz48z7sWM6eN2342E+8EouoRZV+5Iv+BX7cFIa87S/Vu/u3vanbW73jAFte8WArN2YT3ct8 +E21GXLHbvaxPDR/rQogLYZC8MFC8ggYmuHPIFZqu+nHPukvnCBz2hQp4o5jLWEgmHJsW/7gwi3jx +kj95yCvNnNzm5EqXA3ycNSnGGYFRiFEMTL5sxYlHC83CvRXpjWTE8G4kc+GDW+b6l/BhUteWDjfb +eLfjv4gP//g3cfjHj8DPPtMXKklXdrsIKi3KPwnvsrmTRqdzBb85JzlP+ZgudJ+evHZ4q8bbvWke +Zne/N3XFl/RVLWec4aZo6cKF5ovQOJXnM8pitS2s29BsqLPf9fn1awstN0H0HHjKVTB81cfRtkuQ +4AXsO5VkJuzn9ShdbuiJ/Oc5/cIb+2QNt0M/OcOO2+z50paFbZndgy/eTv2CoC3R7KhrT4dbkt3R +9g69745ie2iP872f+vUJ2LLbLWPeMfGfeWAvJH2e9wvxrwO/XpP1El1v1PmWvNy+xn1cjqy5j/92 +pXN/3PPpeJQwrps2zhd6lWE8rpro4BSeYPNdIlWVleDye+BxDS2SXsYCjoukWOoFTPIqeVXVjyvu +8HK685qCe+UAufe7EgaDOPH6wlXWmd8P6ydfyBsbex55X+rXkzHueeiW3W4Z84OHPzj7wsyWYLak +9YYMtyS7Je4Nat+dwva8Hkf7PPDzwdo+D7t35Png/LTS3eVrGf3i5ENi1QJLI3i5J1rey5XKS824 +XD/u8H5RNcH1Tj+1bliM42BWDKiFdyosfwIkGq5qri8taySsyOs9H3oF5lmYpZ7dL8qixYVfRoD+ +WG/gqkVfl1FEyRgIXO165tWcOrpbwk10126EoeRlo5tqJihTy0kfAt7JZl607iunkfJX1vmdmH6e +9a9JBHRHg+e1ZagryjQz91dhji07guGEmHKPqBy/bN2zcp1soqKaQdnNw6ovZDOf78MMW5Fgni1D +XukuhhV7IcKtC/FtLhJvbuPSC+HkdCxWnrTtFdmh+O1x5As1J0akvBxxRinl28ljrMrSvx59HFMm +uWkOJHQdIAqfp/VrUgF8U2npUOcVqku8uVy2st6/67W8yP7XGyzrwetdv7EKcIWkzIUTuneK3O+T +/fKTNnOVqIme//TdEpHOsXrM02oc5TCdatFyOPCUvixCpMc7N+Guf+l5JlO64/5kX1tGt2WJW+a5 +ZbMPjnzDPbNLZOQ66EgcSXofgr47Z1CCF6xwRWUUy2IDbV5CYlR/ZEtmG9y+O4ZSV7RaWmW1kOEV +lTZkKbTSqxWrdJYkhbJdVEVD/oILaTHh4X5hoxf5U+bcgWW9DMMLkVu+aWNRU7l5ChzVsVyAEjWP +izxex0K7X9WLuvff2rxhP3fh3VeGXPvLfefp1OoxcS80V7vu6+kTrFe76jrcempoJ83VvEjm9P8V +F8FfaQ75I1U105f/sE5JSS9+Rj6Mp0uS4yStLOelXtDTx3lh2cvHdf31xR0WnOm/yHKg2xrbK7Fo +7XffGzcq9sR5BX5hT7Wc3qHFnwR8ZVCXocij5zmdou/9mH+OQT2wc3cWn4jcIHx/Mrsz3Bz1gyYe +lHK6NHee5q1L+o37eufp3nnEdw7RV2qJL4mqDzfr0yX79NSeF2BLcHvSfFLxz6oPJy4YYvT1KmjX +tkJVjwXofOtKq2oSt6y+RyKHqOmcVerllZaZc/JC9TXoNl4vCEeeDz0onWf2cuvOPMzXMAySzCKk +Dahcsg1f2JgiI678btHWHXG/4gC74+HrfvmJhh1e3xzB7rTaqg93Oda+LFPnTr6bJ6TM2553yHmg +8eOO3JMfIh6uWgpVZVFGFytYugszzCVWiADrxTiHPvXFmvTU06azfc2eDPEd69zx2HfseMe6t0z+ ++SA834mT6LbUvbsGmwvzcxEaNJ5YAMpoK0SDWSJXFhpYZRa8jvWP38TPvIbaeN3X16CcKWfpGb7T +Yl70don0YTub15ig5hkaL+FD7fFUHKrei+JI110ri1f3c/9MhPt+tXcct+Rk9m0ZDDXvy90CAmRI +WG6bVpx967VIvXFhjX0rSpQ6CWC4yxb61I1mtN8lW3g7GQsNUmTRJYSoyjyxizaCPbo4Xq2qkUum +yeuoos5WlCp6I5WflCzuIVNnUNA9umobh/U+ZOtOnFsq3m3j3Y6fiPkDFN5ju/ZBYM94sZ+29g0x +gINK7QWQtY8tTxoC4j1pCaSVrEpAq2eGWF9kXi/ic1r4acsydrk7J/C8Zv2SSX5Cp6uryig4g5D0 +BJ1xXGPdp5eQryA54BId1tdJnnFk+tSL8Nbmq9FG8U7h1ADSZewzVELA+9XjbuX31u3tS2X38hmM +ZbvwhNtx/YqU8NjlLbLusqE97rZo3p7I7ugeh3wLkrnGn20j87YxfPtwv31k4C6GcBO/9nr0l1C3 +XVDcM4DufvRXkt5Sz57ONjT5p2/bd0Jumuebsn193rxU21dt+/49nsrbHb7S+pYJbNnFnrNsmdCW +Xe3uytt7tbuBz9t6P8mrZLB9gveP9eZh/9NfKQi9/mIQOgrwuYxuqQoe+F8ukEvEefV01s/L73aw +85d/7WB0s/9ZdJbp0/HioLQE7Yre5Elp6142qY5lvYOnztP86vQKnB9kNdXrBh0P/oxRSduDGR0t +rqYPraiICGQDJrbi3z3HxZ7n9fp01mO6POR1ddS9PPkot5gldZ3SASyY7ivyeG7SffcKRZdw7hrU +0eglnPsEv9g+zCgocA6rQg2L610sEk9s/5SyALODf/Aazt1WCaoLK7USDb6TsRJmeljLuPB3uIk8 +26eNVQyzF9YPwvNA71rvSwOAG/WSCsueYZ3p0J+U1lmYAGGULFkPzue5N/hVXW8R0WthjIpoqasF +qIU81sFjZxZUL6su03k+LzGjF/D1PTyP7Rr+vo7NHimW/73j++eFxZc9Xl6aoppq/SxTj7ffOwD0 +s7kdgiT9EgEbq5Qs2Kt3IUJCblACB0oBN1POkb7bvSoceK5J2Ba3xhtXdOMElMWC1RsuY0/cnwFy +J45fYi9fTmQ5Vy+Hh9BYVhM6j7ksSn2i6xeEtSd9CfcbWtxR7ZPCP75tj0SE/zy+/UFvdvkOI3vc +3dH8RP4ZIrq/OrtLtruQP8OuFm29BBa3qjaN18Di6o+AAa2inFMx2w0dwLM3Uquq84SorKhcrrYq +9AGsMhaFqboWwMVvZRG3gDe0X8bWssam8yKcRH8NoXvehRvez2tz3q8rDh74+jkF/3mnhffn9d/y +iQdP+fi2PY3Pb29PbnvGm/29w8Vfxmt+/Nv4/Td43U/z83yhiwtPsXscL2D/LjsbG7AIyFJ6Bkxn +ETTWZUeI06phhipYXh4FQVoo5A0gyu0Z/xlsBviKpGvo1wV8ie+8UPcZS3m5B5c9PPb7Kwz5cQHF +kJ93dXupHwzg49sWpeILG/RvD2qzyXcI2aPujuU77q9hqHvWsmNCO4b1M/7nqUoso7mJ74vStTvM +D/3SSiqK4kKajDNa4Xvq2xJWherL5q5RmC9kuGIN4arwvn4g45zktyqVwW1JpdQfS/34OVb4uE5f +e0ycZffuK9ku+b67557PQMT9Nd1d6OdqP34+s6Cv0OXpdfOUoqFeXGh3pubr8NawQAOumQpwZhQH +JyyqIwHpU8Af3CO3fh17FmiBSTne+BNiLsKq6H8lo1NgRMmbwMC0xjrCta7yk2EZV57b/fiFcLz7 +jfjaY1So2yznXHhcxaQuWw97sYFqpNjDedtSaaqG+LiV98V+/BRvCKoN204zNisutGWT0PLzpXKX +KdKrJ6TqT6LC7WQkEPPH6f1jhJcKil0//PlzoVwPklbw5OvnVMHWCmJ42BEzPV92wNjB192uUvBP +8v2khUE1z+MqOLi/FG8u0JvLtruVt93+1HmjxKTzumswkqVxGC1f3LdIHfGeshdHr1V0qXRpn0/l +WCGblYULv7PKSaSrt9OqhKBFL1Rh7lPVXUb4p/eWrNPbWMqC5GIq6uSeEeY1KnSk6PWkgeMa9nIx +yVxwexpvzgiPF0OPaV53+8/VhV5XH4WLt/k89Guc0Dr0Fx92XT07L2NbWpi9hNPfj+snox7v+FlG +vzsmNwh/Ho2f2MMUqBN7WA131sWdaez1zOK1RsHG4PYwzj1tdnaUd5vd5di3BPKkpZ99i8eS9Cys +I45VvJQdR3Cpg4d3j2VzQgFsGX+m6scgG3L1wIQlwItGY2xViU3KxogTjFF5BWx2/RqXUr34H2NY +ogpUn0SpWJcr/a7goBdS18jrnVivwfX+GPDj9Ym5RQKNO4hmR0QzwuyoAJbpJQSxDrGlVfQblcZH +lQPthv5f0V0eqPyiEXWsowg1qDgKi+EdQHUkenOWqGbnsp91gmJ9qOKB6AZsDPY32XDxAt/Od/MO +sahYzatAU1Bh9ZpXudCZVYceRdrbSg5K6slTUX+ylRXgx/rLwKhckmOxAlVfvKwK8amNlWBAzuRm +ZyTr7pXZcLh3zHDLNt+x2C073jLuB5N/8v5XqedJ57sLsb86m0u2vY27m/unf+8DvjmDd8f1PNgt +ATyJxWno8ajrqj4FgL2o8Eas2IkgfykZGbqet+5L5Pngtnu+vGEibxnOjjU92ZhcvbfbqGv3vLm7 +K/6OG2w5x47H7PjRzwiUq4zzSyBbK2pZfwwYDOJBhrKXBm5x9e+D79Cr6sJ3CEu0+CLrEDf2T3Hx +oqmJQbukk091zcAa1INwmQJfYsGsu4NcziOo8gf7T1/80BefYN0qrHJVntrQ6VZceSxepM/cj+5M +e+eqLGqCcAl6OrsIWmwUTawPhP+ktfjhc9XBPf2zO0fu0+e7XMGvxymx8Hn0WyLZ7e8dLvZYe4/h +p+N442HeOaN/2lwc9QpYQIUkwJZVsNeCL6oi5VmGuFH/c0YVnANeIzpgB0fRV4cyV+UAenHQVleX +6xFUiBRAbNoFyK6CxW1cim32IgeAhSGVVR7aNWfLNuyqj316lM8wptP53Ffz7NNNbeE6dw+rReY8 +pX+L4olyP55jnx4wAe+3s/sEkv51wfsp/feLq3xF+zwO7Fdkxscub477K0Z2uNujeQ== + ]]> + <![CDATA[ + fyLbs3ucs47/5tDX8T99/9sggW08wTb0YB+k8PSvvx7+6YrfO+0fDv774ROvN9XvSj87SttR5Z9e +XVWv8WK7d2f7Qj1fs49v2+v5+e39Td5e+Q132DKSLcvZUfu7m7G/Q4/7dj+J+mra3Lyzmwd593Zf +w73+5WcVcrZhPKOuvmjKqKvE7hmMBW/A2USTbQjGCrFHXe6yrGIcOYJLbRISWRsakfW9qmA0jXuI +1qur4LQnd8NCUvr5lrK3L97iAyMrsHO4zRCsQsJrUeu/fnYsQAiof795GLdkRDZpQ+H5ueTc5B1j +UTi+dr3x0dtY9+7rUj4ZG6qhEgw7tsLzxZbXEX0p/Pl6IPynhEzkp3gzUauUQD6KuhRmEUW0Qhtn +V5MUCyMblK9g8QzWOQFMjvncCOrw5pa9XE6tW2ns5JuWCI6YDxdroNTMVfNu1QPn5nyxYUNNqE8X +3MM3nbp9rM8ATt3SSsZ52ezPO4OsB4MX1uIOvwiGT1K0EtSHgmXiuxXCE7CRgqkEflDd9JaYoKuo +dAjk/edBh7wCTQ4SVUubuJqUtC3eUIZf1asveEMyQC83zK+ekK9ndNvtL7zdT+IQzW0JaUtyr9Sp +2KEbQrXJLfK3x/TY5B8gZIO6B5q1sNcz0bo2ZL+9IJvL9DPqZHfhxWM1Ziir3RYzSgbNFi5bhEj2 +3NkN5YCpt+51dw+KU+OqJ23uiPhB7x/7tX7+vKJQV22J4I3Fv6g/jGhfhh1iacFNXR7h+5MFhOHE +l85hQSaCV1zkVT3/BRmZln8r+O7VAvz1pRNc+tVzqb/gcn133o9vKKRjs57dwh97VATZjToUyvQk +pC3FPVb7c07XwdYuqKQiSzIU3Kn3M9Up/TQ39SmLK2SV1+91b9Duw4N9wruidtenZYQPjDcySNJ6 +3ZNpTUimeuvdlvpzrtrn5HJAbRayXfBta9rxjb614/tF2F2Xx8362K/05+80Yj288RwMg6t1YG2r +iVI8iyVBOpB/enQGDlQZ8172Dd1l81CakVf1PiKlTfQizd7wJq6eFMjWDf4uHMc7Rl/z3tb7+Qux +FI9viMo364H8rSYRa+VNj+rr5vsdJ9p89Sbd5z3ZXqgbPX/s1/r5a7EUV+UCh8husC8Lrpf2d7EM +1TxV59i0enXAPKt4kDPX9vGxnw6ieJ1ca96so1wbu2nFbNV+PyVQbnm8MehZ2tSpc1H59j48aPFj +u9yfOigoKL69Tiv6F90V3Eunh9LHspUIuBB1HQstCazNcOpFAHtDPvPLVgU8dC95W9mqyYFmmXT3 +zmp+iMLW8r6b6XNVAvJGjejLOdwGg6FNQljzGjhjMYZXNRTJ3g5+UVnFRC7KbZfA+HKaqLTW47if +5qWzDIrv1NWuxt1GiCwuQ/2Ybgj/OZv1c4Nf397h4h3SXvArrL8q38L6Vk/faPRvtP8/thRc0f6w +P2hdt9P4/Pb25P74jM+F/exjBoqlv2m4zq8ON8VbAZnxLKi2THezWPGsbYex7xxMkTnK+xzQcJx2 +OHV4s+IybstIq6PweblMRWr0FFtpKZkoFPeA0C1Xp46NK/QSQLeg4WmHWdQnwFhrvmcV7pqaJp1v +x1TjnrTO7uV2KHTh9XJcAhqKGuiiP5PbSGAKqypoBbD30US8wHGW6yIZqeFt+217BL+g317Qibp8 +qkB9oH7UTv1UPc5wdtHeZ9hrGeTw/kDlFirLYIzgOKdkeHfy1HaoyeI2OlMgMowJ19MO/g5BN2TK +F31jrZ/f/oANbxn2G+b+fAjwZLie0cNqqIk7QVWYqBWhSZeO50uSFfveV2u9J7sVF76Rn4iHjjEM +aHNNG1hktAhf7+nfmzTC256rEE5soTVkW1z8RjI0jz83vN7THXJybPMvfU9zVIxYpG3YylcadqxJ +q5skdg8MSYSNIg7Jn9Up3j5brzhfyHkcz/YcN2f+pz+6Z1sEb4/iD9jWg8VtmeEbxrllsm/Y8Zub +vuUKG/6xJZx/t9gGRS2r6Jd9ReF0bH0Gh0tYXRVXTAqcVFPeVD7JaEhRqoC8V53uEreoIdi7E796 +UM9efMFVFv/Q2Yb58npnRYa9vt5JLutXM3nKlQ0UlkG9KELk1fheeLXNTt9kp2fMuFn0FVext/13 +U4VhUmxdvUBNGHLPDq0qT2T/XCbG04fxtT/L5drYLWW35je72zlB3rhLXpb181b24U5Md7fhh24p +PgMW+Fp/EizfSV8Nr9HV1xNNUZ6rscVad+5yN9SOS0/Ni6V2Sji4kOYJROonOTAugUuF1pNc9A4y +d97hFb7kYGSQr5WWYPfM+35/wf4H7seKFcNbBH9tHT4K/nl6S964VcJGoH5iVNNusU/PlbVcdlb6 +XO2Hc/knD1GY2Ybf7BjTg4d9bClL7uHNobw5vt1Rb8liT0APYtO6bixPvO3JHrd8dMNy/0rlPFJ6 +KeexreQRt3U8ymoajwozaMHpL3W9QD4XZKqGydlq/gE5f+VlPFDBo82hJ+/4w69MLzEZK+1ZzBN/ +HOxrGZb4Zhz/FVpUYtLBuZKJC1bMheGG5RCwzfVecB9K/u1fJde7KKVF/cN+5n9gxEP1ojAe9J/q +csO0auIBAvEvteDGkuMRHfqvEnx6WJGymV98TMwPnlizBlJVe4Rw46SKBmSrhDX75CI8BULEv1Le +HHNQ9TDr0D/sZz73OCLzMK3sjfbIZkTofZKziuiOkgk8btxce7TUR+NI5jn4h+3E/GCFHdq42pQ5 +lKIXIAdCWZXdG9keJ5PH+o41emWq2HGj/+Ex3z/8tW5QCz97g9RVFVtr3nvaTVj2lzQvzVdf/nL2 +XV31d372qpSDpXb0zc4xXswU5ZCVGgJlcjyYZ3aFqDQWbMiB9Yl8pFsuc4CzaVLcRgEiC1U8NNrf +RwqKQwpY5LEbtL+Zq0q8RVfkgFUP1b3MvxcrRY0JpAzVQnMSPpYZRax4YFtWQQTlD5KKJ4BhC+oN +j4vfu203LYHniQPqItCoI44Cozvaiy+HhHXOBjiFFb8+A0TSHLC3sAz1Ru9YWivxjM30/NVjysUW +YKM4cAJgdr0FQERI453Dho/XR6UAvCyx/T4EJg0deBywy+Bb6iV7AGNLzVdVWy2XQqu+Xz1ndbj9 +5VBXDpmViXmP/Su+C4oXmGaOhzixXK8WvnrADr2LGtoBtDbmNkNjr4B2PHsRLM1OJl6KujlvzWGs +XFDkqludkeMWQ9VyYPWakbbTks94Oi95CDDqYtlQtqDHp6wWA7lymYVEoOYhiOjyszrWf5zJqsMz +fFPIao5yoF53L5xM7y2R47jw4+P7M9v6Y1djKtlH7fcr7gMXJmQ/AEuz9FWhd1XMflaHVKj47emL +Ckue6egEYjSFGwv7rGIfrTCp/f7QNhSHY13r7VvS6A+gN6S3XYGofAKZGrCByjgnFNgzdQKbHVld +LF73r4wC1FYxBpGguZR6BiMNyJYAl8RsOov7tnmRIzdUtdi8UbYCUqGDPQTEsEhegNqt0XcGU+pY +0m3xCepxHc5iwWH4Lain8NX5UuJbqwlfFy+L0wrC/pAUHFDnDhtQ83fUifW1ppeGzjcMmDoPxv3d +mgH0HPnFurpdt99xZH5x1WQDfKP5WTTz6/yZl9lyFGx5x4kqEqGFEC/AP1N9OIici850KGEndnI5 +e6j5n3luTo+FUd1Ojd7NIMOnenzzz3q+s90npCGFvuo2Q5LOCCVBKsufv12hwyIp5V1t5k08juvg +i5XfR2k3PzVk/heP2i2m5QKIrpcwltlYdFnotoVOw5Y/FgO+yXNZvoRCCSlDzkpkSQuHJfkp+Bqq +s/IDNQgjmirSPyCg5zTcIOFLiB6WmdOhkDSPiXgc7Z9vUZmRNJCrTEPHyAQmpubsVofjAEPlCqrs +yiJLuLzTCy0cI50lFbCEqvqKGbG1kI7wMjKvLheE1kLYCOho4clLx/YOlgcF5WCzad2xHOQUCs0r +QTiQIcp46WgszdGDPmxVISoLIYPgq2/geB29ZnD29AfbrAySTwyQfaQmYxr4SlIsY0KnGxNSwRRc +KTzOo7i3EzeayeUJFGPm7UjD4A/+PmUTucAuyQITetuZWQmvZfbbm1D+qvvA0NS5Pa10pAjVzQPQ +jjvfrDTw8a7IW5vYWcIWFXHP9HvGqoE2KGAl1I00nRRsldLJEwHCDLrvmDSb0HkkM1cimcCN8QnG +Ba8QnOj5skkOXTgR6AY3HI5e4RQtQ9bQJf0hBZrQ8F4yVP6YxyQ432yWE+/YDVOnIsP4HBij6bmx +LnOdMXM/ge6Sg08w1NvKvurfQsKyaRMpWmb0dvdES6wu8R//kF2xN7RE1CwZDj20e5+3uWxrcxSP +aY9WqMQ2MF3D+MFZR3Rw9+YtACIB0nEA6cBLhYPMuu8LhhAlWMbE8EZ8lE5IiZv2rcDAQJMpu/Y1 +zp8f3Df6+mON+r7xywNYXPLd7l+ICVaF+oDjaVt4WTpR6h7xzoVlYwepLn4ao+JlUhYh+rSerA4c +dq+1EeDJaH6GanF0CHWs7HYAOx5J+3lAiJhZcnCiCBEDsCkcLaGknGMLI42ZJTD2fP5+dEu4OC5K +JzsPK1cvLanrsf2XRzgo2QkfXGa1TJHnOKBDnNC1OViHm9Vw1WBG+DNvdA1m40nFuaZTbh9mnxXQ +xgZoUlr0ZIUg7MQPDg17oI7/mfhNw0LairUtmaTS48PMpLCEgT/z8qgg7/h93TJaeKO/e3/+9gI+ +Hld7JZ39HCIX477gkLahOfN1twIhzJDMUGy8OVnyTmo+FvUKfnOrOnWINH+vWo9/+gAM9gEZyQPO +TtwV2gkdpcPNi8j0MKumPxS0/B0L6xx4PNp20w58Tq9Huj3T1+dXj+9VC3/RtV+08Bf9/EUL/2kj +wn/7x3/826//53/8FuOLAWEVsP0L7QiHggWWfxzcQQywZgUzlhwi1vDwoBP8+QKu6DWTvRDFZZI3 +4Msk/8hV/pzR4eCTiDk73uSDIaOVtPv4DjCCwY9ba2BrD2BDj8M2iBV28VFIVzxg8EF67oeBraqP +gaHU+Y+hpRjIC2obrEHSM2At+nXxFoAGNQvTJ8ENzMW/laBOGLDCsW2Lqlbparcls3Qb/hKyQg9y +RwC8FxMzcBgHARnYWaQBOQk6kCVosA7MdlwHsBUrXMR5ayIUD6HDMvorODAFTcpzxaTBC6IamHMa +V+avDVuAWdGQ3eq5LTAgG2urGzxA6sgGPhQXW9TxHnUYAB0YQyWwgoca0K6+HwNbERzgzJ6JBjw4 +1HSgtbj0TxXoVAY8xHETWA1coQoaeEJzd2CfGgrXmcOOS+CwgxuO9XOzXBg4AQwgrDXNl4pONpwR +74LvKXlBUQM3Hxlde3NYnEaXEzJ2S79tsCdaCV6T5PgHNEyMvBcAZz/r4bLiJ8HFiWVYNxiCYMky +mJmWHWhhDgY8KLNzsRPxug6tfYrip0tlvgTjpAa059inNeHHgUjm82mxKk0Lu7lB+w== + ]]> + <![CDATA[ + dMoCx8HLfgClzBowQOs2YDj0AP4eQm7j2Ior90lwjBrtzQHsZA5Jazqw+W4hgDoFTX/vNKv1ASyH +UmwmAB8JR4uBSglFMNsUgKMmbeoQGbDsAxxpBvIvHVfUYGaqdNhsw2Gtepiir5MDe11EZRGTBzCx +iIV/PRSHKYPeoGaeMLCV2v0kuB1SsIOreNMxFrK4ARvsK5wWodsOPFjVOe+ogq79l2TrRzm/MTVn +9KWy36J+Hkp2aE5ECQLzkk/p6qIzhZ44LmdeNJgMIn9t1Edg8kPCnc5iH83uTwtw2oe6rlrEDTOw +tSx1oNWbM+DARngpD75F2EJqQ1J8djBvz4kQGE+GENLAyAwY6uVMYPEieAYdn6nDXOrMJPMIMvQP +jQv2JpJSDdxbaWsBg7PWOgUsrXGl5mIVRYdQbWGV+YcGTDUSJjK1e5gdaJqDfm/XyMCFxYHt+hpf +thn0AsHap2lbyeIq1Y8VPLvxXCHD98rFercuA/bKo3LVxWADlgE769L4JkULNjeY5Z047JCbRab4 +CX9ddSUOpXL93Bzafn+sAacBS068ERVmYwKNcdiVyrWsCfypaua0KIlPIJRj/1RqehYjqQJ7W29q +FPnDutX1qYMRk6PkPgXs2J9zKfav9t/zpTqOoY5BRIv5YmwQ9mfl7yMyohf+4GQgnx1VQ2EMdz7d +ohZg3suTTX/wSTEPnj8K4MlcgJi/rsXzpZJcgCIYGhso7EQGvfJRyU6Xx2ahOPq6wgkM3GvQtqI5 +EYZD3d5twAmJ8hWYjLk7rFVdFRxc4DORi+8KQNie/FPmGXBgnNzWwAn/4AS5+uMzjNz4/RNVxQ/7 +vvsfREr5fdG67fRLwmUVB53gDA4sMZCFheh3AHJsFF+ziyGh1cL9nF1Y+BuBQeyC5AKRNYsHhNja +mmCQXx7gnhMZ7vFUOiyJMaFAV4661rEsLt6hBfoCYtHvM9+lg4snsvY7BkguYN7QAU3gqiFNR80x +qpHmZa0x4GiUT0NyOfKA9UDZtjDrwWYtUJQNDIsvh+bkJFuhmmjO2V2+PbY4el4TRLivDVwTJyiL +Cg5gc/Zurwd/n1u5/F5Ss4QVWFuLU4fVoJ8EHmjLDjT/jf8ex1Ep8up1wKvk9yV7VMEWf0JsF4Po +q++SQc1EYhQqoodrMvByQjskrAcJh00MNnSvpEA5kEfgBQzJSTJBOS1YE70GXJTZxDRC4tjWCcuU +mTFw/T4WCffBc5F8T7Hr40ZsBjOz2mbvwsmEIENW3PD6fxGcSZwIvCKyDwbSc6MgSCoGMDppo6bo +1L6mW5uN71tXJQf25i9pZMV4A05OcABHI73Csjz9ziKe1CMyOdp5gXo0cd5IsdUbJOx2dpJBikMK +wYhj0YELJcb8mgv0AQLdenxc0QFsZnHZ3k9CyDWSeVYyjuC5JC6hT52E+Zf583gSQsiBs+bY9Xln +RvZ4tbiOcjHkeV5wOKbFfPsImWPF0V+ANwQIM2DwhYdWkTjwJRrtmZL+IV9P0TM6QjowDQHJfKOJ +jdpZXNBDTBASrUSUy/q9a2fHVyWCwLSonc0cCc4UYW2CSXFnESMu46CsHrMk02DFTAoFq+waQJin +DO7OBifm5qpOcmH5Y92GMCXvJNGXtad1eQc6rgNTcsEU5hoPAfdvwcDnyGq6psO0MoPphjxOQDIE +yrz73WteV05SREYFPQO32aQHRa/pcoC7uwQkMnSHjUYt1oImDLhyGV3iGMmBidp9+p26CZ1MhAXH +9nCjj0QLq9hnYA9PMFOUhXcYcBksssfdGtAccDJbDc7bTfTxSQ/psTksQUl34KAG2zySYy2gToI7 +FJ2rGGPA0jXrDau6Cc2iKfwux0GZDX5APBCuWxeXuwNqsOs+I5ySb9iskbp1WKgJzT1krnKfE6Tc +q6ThFAmEXuYcLZfz9w19c30olHLyo1TJltMJq4WMQ4XVbmBpLcBHFtCEwh0CTuFExqTpLq4vSRez +8hXItIZALpqBG/OavYYZKU7wysrY6BpTleWhZIkHvDbHrM3VcehbsxCoTsUGlknt2HFzKxeAxjmM +/zY3smDWvBj1iOcEpjU4Gkji2AIC43i4bm194kDICbJ1Nbc+fBGaXW5qywCJUw2+Wrh1+GKFpRJ0 +ZJJIcAqgNYem0PT7USffeF5RPJ/I8zdYTEm8JxKz9ims1oHRuB+AVqN5s3pK6uDFppiZClqK5Kbk +T6PZMIrr5QEtDyOBnaSYlpycnc998OfN73N2W8UnoTVMCsVJB3bMEMIUV6eU+liVL3f0hiAaYFE2 ++y+Bsz2lACejUAcus78LJAZMJpKhkHXyZGkDJwSd+ljIf58CtyAXgVVIdaCJioBZfsVuXU41AwUF +ZuAB2Uv0RXAfRSRiqiBgY/KEKQIDZkE1BqzSYwbSVGkib+LYAAYXJ7rXKwCs+bMAmN1h/3lbVtPu +qU4OTGa1MFHZsTVOSzSsL7QaA9xbo4ZtOW8ObDlKMrXYCwNWt8936NSV369yKNin7ILY72sokmaG +fm92JZeRwNM0QelJdtBZshaLG+hcxoItHZg7+WeXNc12ID41c2prAeI9DbYeLtWUEBOLkSWi37v7 +xKa1YmuGwcqnLeoBAFAjI/yaaR3BIKOLLsV98mCT6UEmYli8kAEHLWrRk96dMmKlQabAyPFBuuJr +E393hmaglKpEmSa6KlGfN8OPfi7LJ4Iri75UR5AMb9EIBxBCT+NCY82ZE5yqRXTj0+cCF2KGhkKb +IiZpESE0Av3ADd+XaRE74th2TRKw1vvSYmInsNcWL2eo31dKOIH1I/KYzDnk++GXeyJqMmQpBfH8 +/RL/zYHhwJFJxK0v2Mwi4rLofcIRopGjL6RQlWdneW7UXw6IxWWhJCRe7DpHW5OGyKHsi2JndTAv +Xrjc9XtDs7EaKxa4Y0viV9i1q6dnYJaDR9Q7BeakLZzPz8ytLnAaegAXe4Lmo6WZjrv9HNeBwwmF +h5NnJd80cFiWMTMhAegagL35Yeh0za1JQaDzgmCC5m/jZDCYAUupTdKBvcKbFZwq5sHlcaMh9y6n +FXSWaeJmRPZBkKmBxlAbK/sB2KuD0kXDo+57yK3mtOKcpjAAdkp/t8+fR3eQjGSn4YFjTqYjSc5K +9PQaodPwHby09wKvm5LWRT2ZXRJnfnxNy6hysyF408M7jd+FMElA5lMhsPDFsDgwh0V6RPvvqS5u +GfgOWaFyPRjTXZedHq7nt7UmBM9Pij8KyXVwk/RGQc2AMRDoce0O1EALMfrg74smhcz4uYDuJlwi +mQHdWQ+gC7ubVZ3LPYQ1WSvyjGu5TUaEMPL6nGWQOWsCF13gpc2sJ7ZYeKbD9Gw/vqVFwBO+tJzq +8SIGdm3Xnl7k3AMIfVZaynr5EIovK/ToQbw0Ukdw837S2JJlfbJUfQcG9y4EE2P951ZfP73oEsMS +3mTRCq0XAg8FNYmUz89b3KYIfGqpfXKvvdQoYAkELjVreJaawHmxwogwPj7IUc8BbOY16zn0aSEy +Dz17CDX7QbyOtAQNt4MAmNe6mt6ddJFTUtPLj6wt6VhkP/atSG65xJzHuerA28LXIR2FdN7cWugL +o8J/CpAAei6hARuNLs0Tj3V35XhE87O+ZNXWaIi3ILDtArSyQNefmUdjI2frk54yA8P57MBlyI3u +DzbYkJ9C5az89032Mwu99m8t6+6BuylYK/y9gh9sVVMCQJIAArYqi3GcUZR4Wz83hhT4SN3HQh+/ +CC1FFimaUwYKLfpbAGB1DoKk0UHJbLZMUkAJyZzpQfT6Az60N1q/6BYclhdBGGN4OHR5IP3VAUwH +ltcNQ0sZeQrNZec/j1pUlv/PR2Ya5GhlBDAneX9NqNDvW8z08mQy0H66T+EpdtG2e4xUcc9Pruv3 +SCly8FyqHIN9DOi+J8Pp6PRJiyujqGYmZaosp2OK/u/6u+48Sm2ORi9TorhsI3lfEuLCOGfTh6Z8 +4jhoS+W1sWHyoKHxZmKFJicDTn0+NBrThpdQoLOeFmAAEbNJ/FXn0EjJiMtVX9NcE5ReiBZ7MX1s +HLK+zkK03ElVJFxWVIbnmnwJyuNCmxPOeiKQkhsKhaZIn74t1VdVF4+uHgJB4HLpSRUvXoXb0ZIk +LvTlfKueyMLPJyHQWr1v1q49oayIK43IzxmDm4oy2yUPofrUYJJbclfE536OzzV5mvIs4s6ecys8 +w0TmNYuOx2SRz+0UnBrF2i+BB/T3AGxZ9n722VGPUudNl8/DmB0YuQhLjPng749njqso1TV7fKuJ +TOn73yzgY61Mrxu07JnWyjr3V738vMZGjkXgCoEz6BmycHMtTbEiLxO4N9Ru0BxlLa3zqrRB/8VA +6YW54je0twHvwSAeRnSgyajEQotiDAB3ocylkSa/jMFojQKwa1G0RjvYFSunYCd1JPaF5X12bzCA +SeSfkpgl8ou4/moiKkfmRlzVIZiicqoXGPaf1+Wfg4122rVAtmHXqegNRGXUqklL8kYRBqalr67e +UAY9Y20k4+FbackHjWip7i81oIlja9o2BHYbJoDyIB3AlJsWWyJHHhLSOcGhCUYHF3+braY8BRFP +HnDYnFyU5cWv789IcBd1g/NrrdMjMAAUs2yrAILvKzm9dk9IdOAgCXWzHfBg6DVgi6V1MEnel9j4 +4CBlk64fGAZdUUWr7uHP9XB3ggNltxreA2mRC40m05NInAZb1BKsMasDZTibrq7rvkTSG1zapA38 +zC3Dw6Ml/MLFKKdQlyUFUPq0GIfjHC2slxB78CX0cHF0mb/MgTqZix0dYNmNcGBJQ3MXadDy0YOL +ik6FYclMsOOLkKuUKwxmgB6j8LksPrrV83i2DI4Wa7Q9oNxWnMC/CJYWgNdWEsVz9OeaRn6gcmxb +IjC6Wp0RhFnofI7W4zPkmUVWAt7YL4EtjsrAgSYCFDNxOTBON+4vsJs0UDchtwW9zfy5TPbDyROh +haAYmeyH6Z3NgkWDrPPTXljkDjc3dCIZ1b0Glja1JBdq+D7WI7rt926psGDRIXv9bQF6lBTs7vFI +snVZ0yF5L4yaP/ejP9c0eR19anPNYonG5JekEgt9JD3xrcHDLlZp9sgP/vzkoF7a3VeWc5e8mDTn +6+fP3U1eyuaRjV9kLKFWMlHLNNLu5M6rlmv9uZ9De4Yrp61wViY0AKy4rbzkUYzlqjMTYAwoP3J2 +a/8HJ9Dtzh65S2AV5s2LsV2B9p2XL7iaoe2L0B5c1amugn0SLF2jujL8uZ1D247Lpz3dPP9FcKy+ +7bn8KQ2B0ybwItrFI0sHamBGe26Q5VS7uD1CHqtDS+djEU33Mpj0PS+hyYEjifk1L07vUI8uAYwM +CfEC0TVsFCIwcytGVrZzMXDyyArkjOWq7w/a7Kenr20RQKyjxet6byq9o4B2SiJD8Z0ARkaHDAWY +DuvFqlCF3HgLrAIMAxPI1JE8TWIYCkQGMDEcqCscyMF5xRp4UQ/U0EAmGB9haYIvwA== + ]]> + <![CDATA[ + HhlICXBdzxJDhACM1BrGskChbyMdN+OMlAI4UZSa8u/ax1x8t8pHWlXh/ZueeKffd0ZNn4dQ5RQE +kNExBnRR2s5wtoUCal2wwTnLqVN2tbkuqZ2fPzz01egATnlBToo6l2qDh99JE8ltoRMrdVl/QAG0 +6ayoUZuVFizEi5h7+UlBp+pgGV2IkO516Q2upyC3lZ6+U8BHcl1ZCgkvYcoWrCchJFhUIFK8ZJKC +1hCMI1lCe19akhv1lQymCeYaK42oy0oEoGSNks4p5Q7qCgXAoobLtpA/Kvdp9EeYXwrbUT1FlTgI +jSVLPXJzL4AMM7ljTjcVYmqlZNpDIIO0Ei2dEURdCWFG17TmdE/w+NxP8rm4L82gCM2fi/lair0B +83SLRMuSJJHEGd1XhSZULltFRBQXSZ2Zzk4kYdOfZEVJTBq3EH5qTtmtf42FK/Tr0STdeJQ9Xjaz +jDlsuGR3AFNx8WF6bV29xcmN05ZJSG2myHiF5UuStnI9HGl1VLSA41Eb3H9LmUttbuWzXJ2s/b+g +T0JkYPZYiyxD+0WwJUQBWmhebktoBpBKCi6n39gIQ5UU+zqlJGEsH1a73WYtALDPuni2Y6Y6y/lB +7jLooKL2xI+5TIqsryqWIcGMuq3ePUbU4fdSPwPth0ikiaMRRh80EBAlBD7xQjIsc6kpyQOGvxY4 +0mKpawLgWKkVbq8sky8qYKURX2Ve8ooss++T4CQraiI/BYwPSlJy4WZV4nG8pzlfxEdGmoPFEbOQ +Kd2GCy7hYd4+UvmqK9Qd4FEKwet6mOxDWFpKKe1X6WqFhQacjWZTWUZk68AmbmrFXhzmIhS4VB6n +AmycmTw6S9tOnpsC3uX5Gq+bF5MKDM0y/oKVfhE8GOsPXUCe9OdokgGqp1lynwlWcIB8EZzdhQMx +iJYIlOGWDDRodaqJr2cMHlbo1ybLFg7RrFOASZZ3bzCmXAA2I6Ut9fQzaHOLQQwrGAJLipWfUjDE +c/nyjp+JV9X92V8EjyBVQO8aggZ6UCpEESjIdmfhMx/8+TJlHWTcObQsC63spvDM0oVEc7ZxA4TA +LROXIk1Q/7HRlCaSnSAjZXjFJM/grMwaLAoExpR8v828pgmz8uPMPq4ft1GWzYxBAHXFr9fFSw5g +YDxLcfO2JlDMc/XHGsCyopNhzfdnYr6obMvkNOVNNhOAB00PpC4M2S2D2+KsirMSTurgI4F8hroM +5IyfQhLysvsnxhkh9SNJlzGut76fGS0sK+/McvA0t5ryQ9THmvlv1uddJgKUzjD83B9uWMdoiERS +cVJYsj0QmqAXWefkTJkm9/jFlKhrxRkzb2stssAAU40WLxnMkDhCuR6CnJu27FBdeqQc+UHqCzQb +o0OXKzEgyZI4VpqVBRY0ys8l1JP8U89dY/3hw52IAtoTRGCQsGxNHjRB07cs0xewscyT41zVWJZQ +xkv77+dFsZDjyzKrEmXlsn6vez7OJJphcXOOgb70wOlVylx+80B0wNLSdsyspe+HqCBqvhhYapUJ +bW3pTKJq6/5B6i8iv7X2ZbKOoQihN9ZFnlasUKzC8xFl7E82hIDCh3QwSARjW+dD6qXQHJgnH+0Z +ZKAvVc4SNh75FJSHnTzx3cFlOSQMU8ffvcCAxclND2xAlaum2DuLy/cPpd9X6BtDOq2UauY6e3YG +VpAH2LijKYPPAc2Uv/OSkVFjK8jp6llZmDMEuldTS+fPZ5aJxNNQMTImhtsqRrGw+YEbWBAvqrUH +6t9Wp6npS6XLm+OZ/ACe7smshHH7/mLpZqv95LxKYSgrsALFS7ocvBegzGvVHedamHwpMI+5um+z +6p0Tq8ZqR1+sUiGNxSxKy5TjamHJKzu+KtbfjnVeXLz+c5ih+PzZkyYyCVHGPcUeFlaxJV93r+cB +rCvQwQKvPzhBXWnH6kFhVBl0syTQl9PBgbaKdV2AlXlt5uYPXpbjCeMpePkxA0aGA+Tf6fh/XjYJ +XlmBOMi/SFGGnKxzBNhz5gBM7mhGCTRnjTXLLQjYXIYc6DV2OVAlS0qB929zWKQchFckcs643HQ1 +MyTeIuEYoVdBwZXhcRZdvN3Ax5IFtYXonFyyYBxuR45Lj6uJSeFxZe8YrA0CL8JgouKO0qJ1yW18 +yjG0u8JobV6mvtM7NajkqRiAWgQGp/SMJKUMb5dvRdVZMSfa/6zYzChIGmgUki2q7YtgGSm719v8 +3I/2jlk/UeYGlEZW2134FwdPrqBYWpdossgw11y3KOdT3S1DaVE0n5Xufiz+Ok9JFVmw12+/RU/y +coJO+l2LTB4p4NCqMLpyxpLk1TrCwVUpvxYv+bmd+hdQCcFpMnnJ0mu+CGaaV/WYcLGjGJQqFVbU +9XMOacdR2XHJq+58CapEPGb7GixzpMzxJepZ8egh8X8xv6TyPDZyhRxRent8++NcE8M7sltVfVEI +4pvK5BuKk3+OvmyNtUOYIK29KUOtKDcKcyvJrygpyIBpBTu0ce5PSX6MNeKmb3FKZVVEKCtJEsCy +KmKIg8dLPIKck8/VEzupr0hVpGbKb5fk/rPIcjKqJI+yRZvRRYtSZ0nR5gWmGFsZwJ73AvmNTopU +GbRsQLoOAFRRBVNu9PsYFNpePDELwKq8LJkuUqFsanH1OZ/fN6XSxypWC9CclIrX/B1EEbzcGaTN +uhgAmlGSMfwyfuBr/FZniCd+fv566NeTWTjTlVP92lV5BLNS7MGSqF0EPaLYPB/W4NhdOFl5gLoK +qS7uG8TxDhijU5vCwAErjHNBxQt9p6y0Eq8RBdgMSjA1z4R+PsNkcKliZ3DITcV8mA0LoGKfopcH +/CBFxaJoccU4JDwdKxuWYmzqK/IEueFyZaXhOSK+WqbmoHBsUsysLCZp8OVEwCpcVT/4+7YWkGls +Tcs/HejcIDDMdknf0wKyylzIxoVF5al6HPRYPO/UxzIeMlQnVg9UkfFw2RoV4wyLoEuiqAJBowWA +WdbWAnujrIfVn61YV1in9R4w+dasrXzfpidq+KyxljUB84BsBVljKfIBSMPRcwfcWu5yclgykOxq +Gc50kY2xx8/9aHHZZYiEBazIrlaWYQLgoXQQCLtTti31qHYwExmCqtW5YFybZm4C3j6nk8qKxUZR +W7jqvxY40W52BtPJO2ZtfT85cCaZ4pRzVtwp40MZv/r80MfCRFhSoWWmagUt+QqSR6msF5kG94v9 +GbJt4FiLDOOTTuH4GluL95+BGoxBdKDHSkE2ZrhWKYq6xqRl0tML8BwOZa68wVyXwFq9Bg6ADMLD +vmRiwun4Kwho9MA4U4YKJdP1vD3wopfMQhaZ9DFYGsbYK3OX2WlhPQRB6YNZcs1jipMq/dkwWTz2 +sqgyrEX3uWQ49F9MEtJjPS0At0k4e5xULKy44hStITQmWrIuIvhhFfrU6FVfceXubyY51647kr2U +67pRrv5ask+JjxvF0ZzGXk5VzjMbzhcx1pTGabE2n/vBn+uM0hIWzM+hWfKSC8zGrePIeVU0SaL1 +5ySaPdP768VOMpkHvAddhfSi5xfb2KIQf1bIMuCQ0HGaQOCTCCq6JF97ogHUJ/VknucCTtqUBSC4 +n077Huv18ZIFLzJCpgsedBmVsJLWpcFQGoHC8sQAWCUkZEZ5P7//cR5rV52t5bKF/JCVrSnWD2GB +km5kcXyXyC6/lqhAJ4hlq3YNjCuHdizY68c/1jlK+GRb3HWOK1cyrQi/5+iT2Hy8J5KldJJsj8rm +bbqeJtmtWgSwKAvcWIYkeI37z/3cum5psdd81oBwK1rldRuZrDTJXg2gLJDJtREDmgVpmauS7Bw1 +LjtaGpWZgaXKhHVbwKkHeQanGVAUSGNqRV72k2XLmzK1pOpCFWCB+YZM7nFol02GQn6JKjOIV6N1 +/fr14+eihuslKE/bUz3R5UIoqngxPNKUYDd+FEUkY7fZd1suUb5mYEyEMprVfp74qRiL1NDb9z/W +OepBvSb2wUBIAaqx2L0Dnbat1UWQNbXx8etOOFpZXfMyG9PO0a8nPjaCqOO2gnNpVANQjjLpegBs +1RnxvdoXMdAj2D0si1/ziCKr0amkpee0p+Y7GkMfrRfusmu4qw/gHk4DBuO+rVR9OdXq1znOubsb +ifDREsflugSOt2hHzdLdtm6FOOc5+W0Szp7nksK6e3m+CB6tr6X7g1ACKykZ/ugmAtCD6lgb44Om +A6Y9WOVOt/ziW5NzKgb9+f2P9eRLHUeCo97Bs8w0LP2x1PW2yyiclt6NYNhVn9QCMygzeJgI8rai +oiEQT8syOBFyVuNYOoYBpDL+XNj5gjGlnoFL4qXKZJynQl8U9BemyrkO6/2Q5Bo7lbolb4S5jBUe +O8WPhbpmfV2AFhYoJpl3MIiCrNYjg7HPzHgMDvI6vYJf5/i8tTQLvx3zXYuIH3/8j29t/fuv1i3/ +6daBLyXXM8ISrcuJqqufkFw8Z+4suv6ErGZoVpD8t79jnxlvubO+8gL5/IsganpnWeIHLHsHri+C +m3eSQwwuu+NUL1FmwBrZWYbm3hP4Q13zvID+69iDlsdt1u4yyLmAj794P4+1uwU2lkPQ/7s/2h3N +bdaYEmYTTefNlQw6vHGLxbsEtgcI7MF82TSB2rT3Z7kO7eq/aJN624SmNkX+fXYqf2JC+95g7Q1+ +t2exPbf9Ad+wxU6ucLn+3RZxX2yXxmbXKGCTB1usI2auNnUdz+u7FiJrwFpLf124gD+EEG8Ncx07 +EDM4NKt3lkGPU+t75yvobEn9wPPnt7dHsju7N8e8JYkt8dzR5fgsh/RDfD4wJ4Rm772KYjDHs8iF +e37uAa2+yU/N0SrBnQ3frQuUHSWKKfSQb2gmUGi2xJnXsWiQbq09L7Mi7cYb0NoKmtA83SzM5Q4t +93EoAm8OcHvUb8hiS0JbYnug1w+g9mNnf7dF6RdbjnXv/gEJubM15RWqTjCNvV4M6J0GHNisa+eI +q6yZfSsm32Oy4BdftgWXHbCzP/pl3wT+IOKyt4K5jEXUsDfusUk7e+WZ1ZXfdxXQwaNrqd5wrNPj +yU15+/AXoO3ff/84/XXMD0rZ09Qb+tvS6paq76flx9kh0Z7v4gvmxO83WN4dx5uTCx4lYU2LzbP0 +3ZtUwnZpTdrj8MawSKOI1n66D3fr6uhbtg5RqEKAzs2+KpgS7Fsmfr9ugEAdPTshXcdOK1zNOb3T +jCXBWXupl+8jhdintbUmHbN5pn1XZZQ/op0NmW3pcUe7OKPjCYmPM4pLdXmDjS3a3qIY3hlrvdu6 +91ts7NVmwMAuZogPj+ris35d2LoVI71ChfN0bzdk1eNubyxhYqF5GiouIw095TblWDtC+YvFPy07 +8GWZiPuPcbxu6M3x7ihhTzIb8vrTt8fBcBOSBJ9I2GLrDV79qNARKgqr5NQoo1fKidYSL0DhNUxr +nXwd273d4eusW8Ruj2B3Vs9T/dOStQsai1qXpuaBZsKLBXrfRHYk+CLD+Bwt2dLs3A== + ]]> + <![CDATA[ + BvbOJS5IWD89wFqWvGlWtBMoHvkKdZjF1r/O+Vjtx1Mmvn1hSfybxWxW/djhkl6D8dg8vSW28FG9 +MVye3itXEql10gKw5HHbOYHaebNWZ9ehRSKETRpFf0Ww0tJJgDd8SDbd4u6J5M153GTix8a/JOZU +69kFGw68WBI+o+8H5pQS1rUshHlfhuuHBRQ6st3q69C8erybjVBvJXul2feD9Ko7loSODUJ3mH9z +SNsD3R79A1sPmfiBOOEzDmscCKvrTDrIqXaEhV7SJWRWe07gLju5n3l+DOhNVV7wTOAP4ukQvNNt +bHKf7uus0Q1zXEFs6z2yPIj7eh/HsoT45xHuzvoNWewoaEtqD+w+ROIHRr8oAaBf92/Ww47e4TvY +O6I4sJloVKbVfCOs2luAvJjuKZP2tWwCV+me6eML916W5Tiw4W0nL/smUMdkzvnXsZH9PG1Odsud +EuHs897SxMHe/a/M1eLSUppMIL3s6QVo+/f1P07/POYHpWxp6g39bWl1S9WP83pIxQ/cqXf3E82b +43hzcpBFuv2+ooGOt+yEjuCfqtG7B/ukhqEDxFYstpWB1D/7NUoY8OAT8i/sS6l7e+rL6gnUyece +2m0sfLumxl9nReBXqfcFBBnhbKVVhzxdEsOekuumb0hnR2V7ctyQ7k0kfmxRB7RBxxZxOwxP7zd6 +QNPx2HkLYPSpDN3aU2ZmI9l3hDVkZcy5XnSnDwS49iQVDqZ1+1Kveb7uT0C9VM79r0OzJ5e9zpnW +jl4+nzyi+HWpVjipaVPUCPYHvKWFLdVsKOyUih+7k731iYgdwt7gtnn7vgNc2HnRJStn2GjdnasW +RzlTQGGXD8Z1bPZSRa+zvkHv9ih2Z7Y53iUcI9Ky2JJH8JaIsnkX2gSCu8mMKxbkMpuhqA/PURA4 +u4WzW6q2LaWg3mMm8GC8AlaniT497+AHJ+iuUUx3qTvMimXZEkyD2S73Lh2X5Deps/KNd6vP4rtY +tzGFgkDUyZUkNoO12B5aBJSptfuodr1Z4H4nbza9RdAWlTe0a10HM1oaW9BpmMvRNKmuDtUQYbxD +de9WxniDqbtc/JxeuOSz0S0rglYkxOd0b+RbV09lPH3VbivUv8gtFi8rYsBTQyrML/IlknUjnShI +ebXYPAce/Lo4jmKXpvA4PK1re84Penhg4z3anuh9oOouFD83/fXtLYK2qHygXZuexdgTSgaGKBqo +EAht4dHLXAncTfNDgcLoJjNE4iPY0mbwhGoDzmKPY6/eusvxgVL3SbtgR/JDnIIw6ggZIxmwhmVh +GCvrz+eNlSeXg87ocaACbw5/SyYbknoVip8b+vr2dvM7LD0Q+kGEWHtsayCtUC1DiRtaAWWTesCQ +x+nAWIQ7xEAZrM11qN0jpo+PBbb38k85S+6s/gkge8Px+DOlagg/rRAf0b+PhJjQaGDLtKXg7ZkO +Ml+ty9QoQiWrW5/F5e/sNTEN6CEWBkSZAb81UZaE59kLKU862VPUhvpeJeLnvr++vcXRFpt7xMPj +kZuD1Vf++BavIwxX2dkFctirPd8AtqWOBE+GO8Dw0geNpcHFik9Wx2e0Epa20tFpLsMZ0Yqmsql2 +HJFD0bouuoqDlErbQEctTJl5K6qZRdnmgtsBavVy3Ab08Jp3J7+lkQ0x7ejuVSS+7+/r21tMvMHZ +Fr/QjofAtJRahr6um11nJ00LxfQTbnVtkK6KZjHXuhmHJNqcQFoigrNnJdpSQcN+QFl2EhSjdTW9 +Vo/pNNiij2Vk65TO/PsoemhmeKsaPBPHpuLcCyFY6Y/Od0sLW6p50NeSiB9b+/r2FgtbfO1RWzyq +zYbG6F7VimBlP8a5BNJavaCOfylUEX/1Jly2rKW7Na+0a8BDCv5D5G4PYndiz7NdAjFcktkY/UGC +pqAYdmaQeRrXoVtpNYxGQwTJ1hPnKXCs9SpyOzC0QaC3y7PPWX6kAa2k7g+uwqxArtzioXRg63a5 +cTuSG+me671LxOhdYrIJ7kmQzx91wsFZDRzdio6eMq6vVjWXO4BmGmwOpA92+93Pb3+wxu1utjvf +YukNPm+494V1O2ZXofT2DATfFeqicjlbB57qMO8uukHWXSq+T+/IRG8rY6d2lyVuoe9Nc2W9snSa +AS1LyWZorrahqr80ZfBeooLlfw3sAcMHEDUeMq0CJQoWnQECPbNRIH6e3Oe3t6e8J4c7Lt5h7Q16 +XzB1F4mfSBMurR6/ga1ep68aJXT8tMeK4jOwNObOSqQGTMEYImamkWAkD9y1wwjLKT8iIsOJZAWT +oOtATdxPaP4kjeASuuEjx0S+hwL9QVg+Re3nmaxtPI5ve857ktgRzxsquyH3biZ+4uPr21vcvcHy +7UQ+iNBowR1w6K5YEmB0dIJLcslKzR0cSKP5YOtSB/bQ17StWHAVqkiFqgnKdCPKOBcbZCKy17bS +nHWoFtmxVLzmIGBWO42mFXvTAEQJi04T1Uwylz6Pf23sSSpbotoQ4KtU+1z517e3u9ziY487eJX5 +CmcvlAYg7JCm21q9t1SIkJHsuYV5KZexJghuDW/RigA4LLmpAyXIplNtH4qpqNb3hvpIN0Oo73xU +N3t3K+BDY9lU5Aq6BPtVqKuwpIGt2Lcby2iWRTl4Hkj2bh02qblq/DSCTInPI/389vb4N3SyI6lX +cfe58a9vb5G0w+YbxCNy3S4eTo42pl5le2zJC/44kKI74mJYkMMmyM0YBr5F8qbGBWM5g5DQsCeQ +wk6nFLCZOq99o4m9wzJpq0e1zOE6lgmZgdsfqPvhX0dTUGdXbUlvaKPQzAhgQi739Obgt0Syo6YN +4S2B97m9r2/vMXHH1xvEFm9TZQM77UrdXzqDpehyToeObB4qK38n+29HJpg/G5Npx46vmbjQbukG +73G7PYftiW1Od8m7ZywzdAuUkPvagOO4Rz7/G+DtzP+XhyzDcNobb7PKoRl4uG6Em5eT7Kke83bA +LDLRYXURkGXZLXsqOhX5O8jXBPZUoMyAh2CqCSx3xClQTOK53r94bwfwv+93dg9ofrf37Jm2vvew +7O1Z1IidxizzYOime0Pbz0NWyRHNkGXK0cWAaQXzDNxdJ0NiDe8U8j1oD0lLXOleounj2w5Ty96/ +Q+oW/W+Oaneq2+O/oese0fzEnAx7NUx6XSz9QwbQWblwb81oMAaZgrk35/go7dNd/kKiUaPwa7m7 +znuGG1UcWDyeqQ43BzqQEUlwP7YsC9MDz7LZb89kd3jbc97SxBvqueHrYap+oE4YHV2s+LJyltB2 +Dj3Gaeyzzo/OpGliRxHIzLVPmdM7w/4g29ROqRwW4SLW7F1bDVgsUqF5MDZBJVGCTKfHpni6nw2N +sGV8ftueicDb89uc9BuqeENBT1J7oPYulT/QseyaT8ztUPw4jQ9afFoLogRPQHawZdE7eJwGkzA4 +Nslkg8dmcjc5Bc2bnPk5e7DGYma6O5A/SMuJO0fdgzQc9WmFfxT2c/EXkyQOm7nxHDh7rYib/b5M +C3uBO7PIHlamN30ysPcpNKBpuw4sTRNQfEdAJBtMusU3GCtqZyOfHV0t8JMCN5T6JOqH/fqGDtlH +n6jbI/nNgVhXHOoYIwfZihXo0VDKTUbH2MSIrMGTJsjVl95XrkllCzPbT20exQlTrMt2iMRICgav +aHdfiblAuoeFp5v8jkC1QrsvTPTG261TS5zLxGvdhg3s1WSImMbTM5PhH9DEln52hLahyYcR+7ZH +mUo3+Nhi7g2WG4RHTpBcToSEnBoJSVH0AFa3wUw33cvSaSXNDCwNoBYviGaL9RrZbjAO1bdtobYy +Y1Ofb2m5vXDx3SCHMITKqKmyMFBWvxuf1tOPcG2Ch6ahalwtPDmvfvpHp7yhiDe086Cz05R9397X +t7eY2OLsDX6bMVT7vQXCOawnV6JVec7t+S1TFUPhGuKXvWpcm6MfqbJijAEH3brv8Ls9i+2pPQ94 +yfYThZPlqj6V0glji5vEmapM4EyMYY/TTRYzLa8n2rroeZ0reF+xEDNZMTKDpiib3UyMRunuD3VQ +8lMw36Irf891/riJzY/5v2grzlnh4XOEuqzvLXSCK80d6KtbBZQmjfa5Q+73M0Fpei9dg4bhtImm +w54M1avbHb7TK9Dpjjm19ifahI4tireH8UDIHyBvg+RXbN2F5ifiTp9Akm89LydHd6ORbwcNSRxY +3EEHlTnRFNmVQlDdOyBnxsEEbWjxyAwHMrwWxp1W5Cgw5m7AKCPAE8uf3/7gRHZHtzvlLUW8o50b +uh627AfmZMu2XkLuZs3KAxwHoxyZ4NqknAwWdPcokrjcLyGYSNAra/oZ0E3rsEIECc2WfVUYuJCz +e/AOYC4WPdYTOIUs+5R4e3AFTK4TZeYg8CXq/O+nIuj2ADdHvaeKNwS0IbUHch+27AdCZX2zqqoG +Lit3ACFtTfkn3svKrLMHSy2/0bPqHows6x28tTh3+WVilhfbysUSmOjolBN7oC+R7RzpdCty74l9 ++WW2J7U50/3xbyllS1MPdN0jjp87//r2Dkk7bD4x/0Er6aEdidlNBft361UyfAoLZ/rupk+XEHo7 +7dMglaLQqJHHmtdjuHu9+hGspaV71RlZAmu9x32Awqs4AeqDjuIHUtuQgd1qP5mX29K7fFLrpmon +qnZ07vNwtwzSkIsHe49kjSoMZuZ3x2ucxpqVxPzxbUsoYghPmtoS34ZQXyXZx8a/vr3D0Q6Z7/CO +sqaLEimw4ZabYwKWz0LDJsocJdK2lYiQdVoxB9l1Nv9+dBcyxo4ix0LPnXEAdi7LqRMSr5LFSHJs +aTy5LjPsQekOYYg9d1qN26CRHz0IcDVHwpRU+f7YNyTyhpjudHdapx9b+/r2Fg1bhL1BbhVRWYvl +dTZIj7PFzcb8gOrdthyJMB79kOsgdMZ+MCzF2gAG7ri1FP8AtZszeHda95P907f/9C8Hev7mNa+l +rlAxdO5deW/T60Ke4O9mM7eIc1v7soOfQESV6PZfwMlyq14mreojcF2AgB7Jndyy+TK2Tolq56QX +2PX7F/C51nPSy66eGHBh/2+InukZkMivXdmfyRu2Mn7GqRFGMbcoWBctFlAIS/lCH6C1NsY4w/9E +pQc7cm8cev/w5Te9vNM2cpynkggG46GhiTEeGrFf06/NsbrhyjgO338OI4fsmsbjKmPDFM9mDZIz +9yRN7rF9o6L/dhLSSzrNDlO7Wbfff7vU565223+HqR1W9/jfndT+TLenv8OUiGginmpwb1MxGSDM +5Ese5zH0FRcJSXolBw/6z9B0rSn9NWshAItkkphiG96h47tlfdDVqzxVnwDrzzQ4LEQg2KQT5ZcM +R6uw76a7sYp+INC0cGwS0Uy55Jtqxe1wcCell8Sf28dU/2OzsO0W3mx3i5otEt8gfHs422PcbPct +arZI3CD8ypWYPmPN1qIyo9qaqDij89kV0oBE3qQkSI+DsWbKba7tscKFZZh3lRsRKg== + ]]> + <![CDATA[ + +nIWAz+u0yD5LlySm4TL4SXhvzO/z8q24O2fU8m5fM9xQhAIRNEjR9q11mmWhYpD7o5DJ3RDAelJ +NHTf4df/H3b4q4f8p1+v//Va/utf/j0lwA4JO6mbstVRDazNFq2kbryAP1/AqHFrQsznyyRvwJdJ +UCBMDAZ1wqAcz99QV/S4/FZaG38LseJvFTUVrcdewR/AovchiJYzyJqH1ovpS0W2hxotWtXb71Yu +enh7uHiWmSt9de5D78fVcOYKXqUj+6pyOTwYwoGN7QQRCroaQ6xeZyiGx8ZMZfwuUGosRIzyDZPN +Hy0W7oO1tI/d8PvWIOa79ZE75LbuwNWZLbraWLwpdTk7mozOOo6eeHvA6qViYcnqFjuKYGd/Z8TC +NdVltErBABY1C4urUwYi+FalxrkK98NjUNQoMqSuJnJWX9aRWtWDju2h0TuzODt3cLOqrihJHNX1 +hOVnUYmQ7f0stHmwr3fPlYWk4ZKoSd03Waje2j9PjrWW8t+9Z/0MLPtolRdsA4eOoCKRw80MB9Ci +Eb2XIEQWr7CJHmLe60HEbROgNZqXW1S7Ve+LRkhpXrt+opu3VadGwcNDbV6/brmoBWzxIv0YO239 +KR8aTBaweFNQlLCNjbVLR1UryagH9djUeYDFw8K+e/tRb7mEgqhxsFuehWW1VdOU/ZURZdc4Qare +sM3q2zitFSt39MHfszMGKtBm7/1gT6dTS/Y49+/WDb4VlhJvRfhrIMzJUuKzsEHjcDWK9aZzJNCs +z15o9mzeie6hUzVp6+p4u+pVOyR6O2FfZlWvMoC9PWXMq2U2gKTV7IsTMHBL04MvCWVB2cxSrD2q +/2As/n4AmLxTOoFJvy/qu2OtIr57m/iourUWbAng6tgZy7JrGjhVFamdwXFnymjjmgab3QHYdPiD +9XkOorKCzcPZqnf4mdYzxqupDpqP88TyklrfmucIv582mfrkekGCA2jZ/uyo632FAUtN19/4t/++ +qrJ/tIppiWPZ7AwkDULlBItRGm1oAjb1Mf6T11hvjBYRCGl3wieIrM5qpdF+2ASIzmlsUTCzNV+Z +KPfZiCyrzwVYVHNPVE+eHiJxgIMIAK2pvC8Yyph78wxQb1zNKlkcljkcfgDDhRkD12hNW21Or2iK +2u9OVfh+n5Ut261QviEgVFXSj27LsC2xryAK6UerOoyTykl9mwyoA1T95+hPzSfBvL6R6p2f9Roa +Is+qrLc2eHCTpp0uCGAxLWlsW0VdzZvvQMsRcmAUU51qLldXu/HB6tLeXSh7f1tYG1thX89GNcNY +FSsZo2Xc6HwVQ15Nyaa/CsjdC2dPHDVuwaveV0ueUyxgTdl6PuuwpbEx5fFFNg8pVuCEraYsqdaB +Mxd1uGreFRXf9/fPgEPtuMqlr7VaKLbo4bWFXeyFAPXyHZ4O+INMcYZMsHp7J/UEOuvkIghULdyt +r6jzFTh3m6rnFjHQQ7xhnV5xNZTYm2yIcbb8hfFUFX0H33/UHfEqyNZBPqtZu1UI8cMHmn33qKUQ +2CVDLdStfYLaU5hxF6Le6soYg4ch/KBYyMaoDOAHLK1ms3nxVeuW0lilfvUgjer7Y7XrvdtkZNgU +R7qccArNqMCcErvqoQp5Un9lSx/lWHa2Tx7z4cCD4bOJVYvqwJnipYEuGZg1r4nCoDUeAAIsL1J3 +HULfDzaVYPeaWM5uchH1WsiWzNbtR5C7+M8sOoGp1rLWtkMdvXnVABNBhsqn+xQp0e9GVd67t6JB +kEgb4/WZReCCN7UFwop6MSFyiYwWXW9X0XRVIYcq17n3PFlcPTD++IAG96+RoddbSwR8KvubCOEw +eWHu4oHGHyyrPWsj7iK7PuElSpljLWfIgXEONsJJTbcfL5H3lYzsEexAclTrjTh+2yo1cFf9L//3 +f/4v//TPf/P3P/757//nP/7tP/3rb//bAfoP36ExHTps/I+//ef/85//6e//8e9++w//9b/+lx8/ +/uXr//if//y3GPsff/tfj5H/+/F/N1IcLNMaYZANmw3FtKaBPkq+GIQfuYIwVitH3OXqmsgorlX5 +VV5yx5hq+B5YocbF47iaRE/vYoY2R51ddHo/+yunkdjTpbDBcVT38BjpNN0t/6+Fn//032wh1mNU +nVqzypRPBFJlNiEtlKqQFlhWZ1OW8h/IG0686ElSDcAhdFVgr17hfxgtOMxaeBHG9pfRKzD90O+r +CrCz1zU+5W1iAAuuKMCzSvYdV+knW+viNLPzJCJaG6jba2hqwdxdUQNPyvHswTzPtvNsRT/Len3A +SZdWE2ol0Fyd0mrU2homY7arzp6D7iuIQcDbEfz4Kx2xU29mh+DoMqOdb2/sbWZ9e9hZCWrI8C5e +3QuhkZXlzrYvGW+GlFZ2lFFproNBwXVd1DOFb04ebGbtDeQCzzejqGNjaxJjfABmpw/ALEgfMPi3 +JtvixSCl8QCbrcrAgS9hZEskb0bkzxsGJnYzstP5wZ/3EDuNN8Wlo2x9hR1GlpWtDdPVyPPBfgaT +jVjOnSLXPXtPns6yhY6+heiaMh8n0/gSl2pCkx+K488WEKvYTwtsm9JB6D94rN0l+WA13gqHqrlc +WCovgLozJvF88PetBXWcaVO/t55X3l4m+aKeBPTXYkCkmMbNWb1f7wMbYJ4muPKZLKlxZ5ZIzsfY +WpF5y8B6KvMHxgmm3AtxzLi9kStNNExw95+Dcbk2mtS0Npxdz2AhYefr6CLqd9MnSxVqV+9zlAHq +Z5OI3jjUBHMDeoirAdXRPZ7dOw1aJU9JnT5+X1yYTvy70RI5ade3EYUo9qIO6VYwOvLbHnfsdoiq +joEmjDjuAvtI2GXlq4a0uqyWg5Z0fL/rDQT0wQPNY3UXbKttMvvBBoZdOWxk8YplSbKhahKU11C2 +srMmkP4WPCjnr8gzLc7DnrQU3DD0JcoohSa12l1+6cMjmmmTc4VkWIV+s1OlS3/isZokp7Qalw4v +s2ImLSrvgLFTSWLNuh/8fal2kil7A2QHJg0VJxosH+YDky49QiLc0JmC2z99V+w9lcKSsxHVEs1S +k6DyrKvVJGkDPJdRkXczMXDeYNmboqBRSJNSAfDQ0EyzDCqRulwMbHcavx5H8Fc831lXD5bq7Ru+ +KNGx1aN1Iqd4gWyTSI2X/Uu7mVnZWdYigj74prJDfPWM1O9m21LLmOoVRf1Gop2B/9zznhxaVh9x +6cY9ep1AA9buGH8BpiSVsZ8Kf75OwM5i+coRhpqQK9TBFN4wehLYnxQrWlKXyNfJDOtQg/pTZwGY +vVEzzTAGy843s0eramDhnOZ70v7V2TQt/cjcTOpwTIUXpu1OgdPsmU5bVjG+CUy+D4NVJdBTSAik +wGkpqjKXTDbfhhzupgFM6mY8Y/FRnx+VbPu4pm3djenm1otyDOxPybY07SN4lTaYpM5yDo58IhIT +wQ2Ypxh6ykXAyo5D7IPu3CWY88DFUPbktYAyHbWF53w31UcSdzaN5AcFXij/ZbU7/u6WuanWztmN +wNNoznEKI2CNNAIiWn5Rmj+xM8ChFEjTyepwmm2uNTcjFNdz3ApJk4CDR5O9zFDkBivaBk3X7Zxg +2ZGn6ae8f0TABJ9x21zoFBPhocvNhYnhKVs/5Lhz8h1uBXAYxxkXf3Hvwa5S2NXN5vQ+swfYojoc +yJ7bw91FDjNrqv9e2iTWGSg1dInDE04u9gUGcodsuHRigc0wXO0AR1mhQ2Ftluzd54Aj8+bb0cXY +eXOtco7bT8HjV5vtoKNPvKTge3TKPBjnX4sr/3/YOSrfPMf/ntZR2R64s7HTAuCiQcn1rOLinYLf +gldmxWW+Sxupn+hSf8xukQJsZ2Om4S+C+2jspxNYSRTAYuEDAE6mPVe32BswJgYa2rQCNg8ABqxF +du6xgMrt9z88I/yy7eB25C+Cu5dWmYGtdm0SdrIwYJ5/uDBm1eJ70XP0MyxbNinMM9FDGJ8L0Mqq +AibQgaaPE2UsDGnB8aoaDTPjsGWg5NH0liIA5sx+OW5P3M17frAH72ByzQwEODu9zNWr2cDTU0ow +Ghkhn/tJ1C0MEWeWpDazPxbql8P6PWgcdQYEpqmxlijHkbGxF9VQPttzWn0vKuVlIrizKtYuunHP +wCpjdgAbW1rFa9BUT96WiYW6PzhBq5kTrMA6zNo0lg1ynisgomHRreqqFRCn+0Vw9frqExUaeC/r +VAkWG9wLg/OYAQFgUdznbVZ+DjUNq2WrzOhNI5VV3bsl8U4zYqj+YfVwYyT3sCAQck+9oQ7SgPo4 +K2oOHl1SMRHAKj/lfHn3fS4MArtXTRvVU80UoaU+MtWLyqgdhC/3gA4mqALm9cUxA9OIn9N+LJJQ +xyUvJ/i1oD5H8/bDBDY7C6RMlKYK0uRWg7YQUYSZYB0cx+rmk6qAgngRSkwJye5juyjSbx2uxRl2 +rWzRl8Be4RLgwJRcywWdAjInEsDoMKth/cHfs4WJHZoSxOpQlutM3qWWMxTLh7WxDCV+rEvYha29 +q8USqoyq+UJqFmOMLJHcVUvcy07BfB2rqpNnr0ACSw80lA/9vnjfmbKScr1GJidQ3vxzAddzD1U3 +WcmIzU23hLLxwcvQuCqHnwNXtSlASxHT0CYQwBufc+4ZCetkGc9YnEhvX2T73t36PxZPjZb1Corq +Ct9vgUVqAGWupjFPwjwKwmAHrcwL4YujkvlaubaquG2WGjOL9lDx9NfP/xsMp7uM7PxQxQ7QXVUI +m0XVGmIUi2WpbQ4tQncTu5lTZ1CiE8dbfpPPeYOLzF8EJ0obVtXAQUxAmGfh1txd2zSgunb7z3k6 +wVPX+Klu6S2YwMsyPD/PdeGRy97mM3kjCIlvLN4N8KoKA3APvKqqdglgXUDPWHpOy++hPJ7HCB// +MJfMA3BSt8jA9kbDMyzwIjGhBtlzfejFLapH/PJrUYh9aehJY9rF8/Mfnnbx3TKXQo26w31lMyYV +RbDqckNVzQZbHaIduirDRX+AAKO73MCsCzxY40nZkMUrdJobrbUT7HUoRvVccYFZywyThK4sNxY1 +wWPDMhCYbXi3OaxMdSvB64Yeq7lyAqsy28DLzlRiFPyoXITJQAJ7X8RKt40l6pl92TlsH0q+nJy1 +mv7kS2iKt7X8UFXBxmCvfGnfYulMpEG2hYWoAxXjrd5VWYe/EGbvpvI0w5xk/fYkO3B191NzvoEo +0JTEclahz6nKZGA6LLeFjFivAGTJjPFMk61kZZaxpAlMdh/FS0eqeKfFQfkKEKRGoJe/MF426rmC +6fhCE2kmhU615rSc0aYVWHl8A8qm6AnALpWDyUTtlom+wAXj2zGwUXw3pqufs0g4fp9SP/OPvdYc +yl8yucKYkk8ghQPpy4MLXb1iEVHmXLt7p1YfGL2kqp1KE/CQ9nlUZ6VmiL18vBstGQZkbDWKqzK7 +C4JHpaay6gvgzpPWhuewOJA1RcbZrW8m9zAYkMm3nHWxYdv8SnHvUiWVtGaiz+DTGw== + ]]> + <![CDATA[ + mZh6ALuXC57BQ9k1rxfuAcf2EsBgWt6d1BO5I4EWRkZVMuYz897LyIG7Uy+YfK/U4xEcs3YKT2c/ +nCenXpyesOGFd6zjbuRAk8Q5LEgkPNSMuiYdvUtOK+frwQIiF0EP+/QKNcANy1hjn9Sjkdm50J/V +MQVTIU1Q81JGKis9AwYEr9aM0FhmjZxWhaJoMlYdmMvWwOP0FMJZV7rfTJ7KbsDCbF0g3stgwgAU +LlPGXPhxiyBzYPJy/7Ou3ECoP86XEfewHjRoMH7JJpi4KpAB3IwqsYHmFcgADK4h1VXm0ibww6q/ +r0Rke5/tUs6TrdoRExZyUikFNuGZFnmqX7Pm5ywnVUQlMSMumQ83ZJ88hGhVVUPbYb7SeKOc08+V +TDoVzWzAnHT8FgG5JqiaVlndVg/BUYUis031EGJtWireSLE0Y+Wu27d4Vs5g1hDuIUK7ySkTSa2k +roLM2Vky6K+0k1NLgcmX5mjGYzrBiSuD4cQroRmSooDJ+7dKfvngBNlr45iwoi4XqDYQeDkHH/2u +BrCgXaheb2QdgRMvZ2eDIgBjpcbmWREubSXp3mWViQHfD7Vru0MrsNI1frdZ1qC5vDA9F1RSACu8 +495FCjIokyljBbUGvPaJgrR1+NDPW5JtTN2VAPSsUdwxmiTwmrvuNq8FLKHW+2M7z3xHKcUGbGMK +KKGSNWY0AVlb9LKUDvMrBLsTBEeXuJDl6wPDqtYOiYiHEp0HKue9z0G0hOzKG+S7KjbqMa0OHLKc +tHjKd6dBZQqFxWP6fa/eAAGwHPj9Os6fhyLrYqPO4E5Zkk/IS+71Fxx0Ipyu1yt55L3D5lLqA81o +Iy2uBLuFlCv05l22KgpKJ7fNZz30pJ6uoPz12IyVNAxCWy08B5il3juP2fA0dW+ZAuKfKns9+AAk +D1754O9Xa3XLV/1uGfEnSkZUlnz0Glt40udqPTzV7nXGVfcIBSIGv+75NF6RmCfC2C///bjQpOpi +WJr+6uFOSQuTxna1RGsC6fjghklVBlwGt7U6n0DKfdOd6uHye3biBaUUNt4e/jO+7HmVTqDBOl1a +q6Iyz9TLbu75T83rlc6N1XhLFUxBY/xL9QMTsn0k6oFo3pY1rwz35sGXGBNoNLdCQJHoMj3FJ+jr +GcC9Uj8vFNidjeYpNVJQB14nmFRVinesCc76WahvNIrGqjhuY2Fle+mGiuuyTAAWUPTz6rKCrxb3 +6JNgJsWamOlXAfUovDbPPLtw9dUdFifGSYsaB4GPngV72ZnALASqKy0TN0J5V7vEsk7rzM9G9xOK +kmE1KAbQtRDQVlLJs76KMGIBxeULVPH1HkemeyRVSJYowM54moDPGN5pHIujJalQCvYwXcZCCZkq +2rIss+/MZidWrPSRTxuXhSN6sUwHzpaX4MwqILBGD2LGVElNkEkZFMsARIUHeWT6dGaG1HS3IOBc +wrK+zsuzFVlXBvn469KoTDSSmLwRvAnheskxwZA5NTP1fqrxBx7ntpqYRhn37fXRz2l8norAMEMm +u5wYafo9auMij1kljGUejYlWfxPiVxNbV70h96SoHpmDUkteUodl7koiDHE1J+1qjWPKSVUP2tP4 +g8jVrnblYRC1bRZNa68wJQ/JDmcTSbtfWtbMejYvttxS7w83aqVMPcaey+O7CkOuOj5T6H9JySN4 +2VpNUCROqPqvuRs0qXT81tY1Rnys2J71JZY4V2lQQOqysBrOgh3TGzqCWkqStwrlwrqe1KLGiVSz +je2uBsriLSAXVd5GT/Qs90xng7DGgq68cC76tBcZY8n/mKDL/TX5+iGf2ovRX0+geGFLXkPJ/6hr +6rqGKeVNW2ALD5NyVWvCEoidiJt6VrS6/BfxzMyurjE726Jed/Z1n2wXqyOQBnP6fHEE0Y1l4E9V +fqCQBbzYt6uMTWCGsa/k8u62iulVI79bGrpEpeA5CT5BXrQRlrECY6P8KuJaCPZ03wfodbZzAvYD +tks06mrkrJeSb7UDWQzY7uHUx2Rdzr9flpW7bLXw+mrSQNdQ9usNYPIEDh9LvouKHRSWaWHWtGE5 +gVqsZzPq0fPSLJqmqEuv6KuXuPc7tAd9arHpouuIDyRWb8LdSrHeYSYv6NfsO2LiS1eHbdl6kpur +HMiqV3Zh+9kgVvb95AxtTSB/Zl4T5Jmk16wyz/ACF/EHFchCEYoodSOx+d5b5xHdg2BwZ0UOsyCT +aQ15lA6eJq/BUsJavHCCpBa9YbGXtGyjTw/56Tjv5DD2hMjdLF+TJTGfXuixRsvMjbF0VrGt1feN +F/uDv2fZWaNOVe+Hz3qdmarEWLvsIl1kqgd38tJgcizLm8k+Q0ZxbTkz5yIP1fezoRIMpQyhK8HQ +Mcxl9n24TjWt+d/93pN3Vis6oI11FyBqV5kco45VC/t4lLxYBSiUDgQlXjnVsYRTX658CgDr90XS +zvCeIbWrLrjJ0exC3paCnbxTlX4f4lgoWIdQVYjaWMSsJ3jqqa9q5UhLMC9OUX3aXBIfdbOt++cO +ptzHYrT+WHnjDL32hUiEiU+PlXHUD66gabmyk6O+7Wk5KavArvWxGK+6gBWklz3Ek1QNyA5sMjo6 +kK1a7bGSkoKE1NPZTjaFEr/xfINZLamsvWY3n/gEZU1AX5kDWSTcBAYVSz60Y733q8cqKjtTVb5a +tbCEugRUVXFGFehO6opnDeWgl8ZMzJqWpX/NmM9DKCqgabZpVhnOioOQOXSta1I8i2ExCUTWFsb+ +rHt3mkajM9DvVlTbG+ZO5jT7rJAIOKscC8g0TVIfEwvPIk9ySGQy17v/PixtO7HWiH/K2xbMdNZI +C2qXbeKdXPLWuV3agDXLUqOBsbhUos0TJcCTTnz1ap2Wd0T5tKiVBSJzpAGXovapi7YHnf+AzbwE +6UtrUD210ct7aVX02eAQ2C7oOYVvS9pr9Idt7da7sWGsYn3AvnPXBOesizSUZ2QTlLTee3FvmGcC +ObUVlHTgPJ0zQVYjNIfzBjcW3T61Wj6tY15P0eUASJ1T2hs2RlEunM0JprqeY7fRrQXlDGUB71b0 +2AGOiWYj/Icjth+nJGGUNjekhgfJBiWvrhJJ5JZKORvzsqwyEICCNJpVfIfU68AowVu1tt5HPxTe +o4OiGaOGpaZABGRKDNaKNtMUem61K7ILiZIpqcm1SCt423UHnsEP/dxXu/jdKt3MiBfz1sKXQAkL +IpNpw2Rhn2BZXLCuvjqYnO/BQiw6uyqsw3IdfAJkPepBUZ36UnRap20FHTRWpEVhJLFPq0APVotF +5+4Rb47HktWcCyNHUgvqTD0Vbonqmk9J65Gk3c4HtqUjnS4KtPSODJg0qx5gcKfEfEHVAcxzGaKD +t1LwQJO5UBVWU+oXIF8CwPwAza0ts3tZcUHTaxc4bKzYTvL8Er1LhYeSjkWAgbG2cInQQWOddwJV +rEZlDD16vFKnPQNSJEpQOCQabRZ9HhGwgs3VyN67+8FvvByP+L2jj/VouCWXqMawJDXfPcN/sPxl +oS6IJW5c6uljzQhenVT8Jl/jPJdDDe+bBx7kccYanywICaReb3+G1UbdhvL8PC+CMH1IiSEGpkAF +zsaqZrmLXWJbU9FDncgzDq9fpyGasqIvvqnVtAWmPUUvd3NrExYJehPRlM8IalYABXAkIQouKQcW +4nq6EeIHJzijn2Jys3VuSxYJ7kN0YFt27ybJMaNJRapCinST3KRKhfXgWfTVMgcwAhRrLTrrtmwX +GDsVeDHIgjGp82WcS59aK7VWMx20siZglJX1ii36mCu9CPyoQYd9BmmnFYaE46qibFNx1efrXEIK +omKa+xDP0Yvo8rwZMcimYuQaGaUyXcUHLHFVMlQBNhSNUpYShZZYjJscfjOcCVCQwLbCagt1/J08 +wGI5xZejNxyCwxDsWi3EqA7jxiaZ+I27RsafU05Fvyg3d8EN2Va/KEbWw2GZ4/kKMNgVYHqFAZyB ++w2LjbsWh9iZGM4GTVpVW84Ae1l0iKOU1UeLgZD9YnMuTFNxRsiopJJ5ufB7qipYfxEbXTZva/kk +0lBMUjljwMbStZBE6jaSYc/0eoYZBo1+qFl9i1JWCLM6ckIWPeOaW730LZoM2lR7D4iSDBRqK9AX +v3dh1rrxKoSsmE+eIWijTcnT1bVQUBblCAB5i9uqPORSetcBWE3J71QIFFPltSlcanTtHr51HNpS +E7rIXQHb0BMGD1tsGAX5FPRqD55+TgukxVTJ+lZXCD9mLbKfQX3JHGzOvgX1+HvzpSuOriaFBMPt +TmaO3ilDGFdf6lq8BrsBbd4f0hfDOkhW8Ia257Ir1sAI6roMxFguwkikmPVF3QpEgR7sDnsrZ1Fk +I8i18cytM7aU9kVJCqit+M/A8LxWliLOxA07RpGX9YsL3K0dzifBYieYYkpj7B4p4ZPMqcB1+iER +eDi7YtH7mEJYXp8bLIg82JNOsBW7T+MegG6Qt1OYZzi8sljONqEwVrmTAsAzWvoe7ExoVIiienCh +SvLQqlpdZrgTaI3ENcF5S82Z5sATLcsSGWRpAmb7Ga198n6zjHwSPBcOFNGFPj1TNGOL+f5HSQ2L +7tMyhfakSH4TrL5fTdE4gdVoAsZovsBtSSCwGQchy9qm+0iJMO3iuMYEFCLr0gtgZA86xKHknewu +AxuZli4PD4rXUTc+tezWZaG2erSMwEPxj5WySWMYsTK1WlXfeYvvVUAjwEHft+BlB1rWyLjGCjcW +QPCVpotLpZWq3zf5n/j0FTdo+TiLgjRgXdE8bXUYHuVcOyyA/L3iHuG8KoryPW1MAI/AsZWSBhwq +41yA/FzB+/1gT+n8ubws8J0n+dSKB8mN6nYnfsg9qIP9ve/fxx0eGkvTHejnhL3mBen3rOJvuQ0K +IIQH0MOxRl3NIE4PKL7F8Lld3oiDk+vW6qXjQJJAZd1Zd9dOkZRsUW3pBQgWmsqyhGuZjw8CBeSk +GSuDqDoxazBjvwwzLlqiqDYlu+I9FL+bc5k9zewMFbzWw4U0V6hJVDTC8J7BDqMPFSw3rEa/cTH+ +6hEhcvtb6Dcx0+X2z5PXOA1/gHuWExlx4Uu/6EleVHyNdkIDZgXSU+BEgEBODPEvCBZ+TuBo6fRt +HCCGBX73wAlSEQJQJUAg8qELLAtTz4pAGmcIp40MPO/zlUWYBS0ZZT2IvcgDaM/WWoG4a/HyVAoz +CbwK8NOql4Z8mGe0PKr/rbewr9jU3rxwBslIvSMtS7+Tukw2W83G53pj/l/23nRHriNJE30CvkP+ +KaAGaGb5vrR+SamuRt2btaBU01ONiwuBSiZL2ZMLh4tU6qcft+Wzc05EJHNhiDwkA4VukUYPP+bu +5ua2G3qtdLSDpXoeGmTQnEWxp1nSWHOqeDG2iISl1jMS6EFMxiKBqStPRD5D0fyU5jU4PU1tj9Qf +JuwkIj60BWkH05bpyQQWdzJvZEWEmvZCJkJUj+l2CsmUoMYWKtlg8r5bgpqumWKC8w== + ]]> + <![CDATA[ + dCdBUFmqxSqrULY4RSUT0PINZy/7rfNOySWISSPUwJQyYio2kD3hvi3fqiVNQ2RICSCfFDI64yRE +F4R8J+K20MO4/ZNOoYJPtaiDVBBlQ69+a5PlT41UEI11ArGIEhDpo1uIncwK8jekc8BUh/0vIsOR +edtDli5t5qafXB/bk2i+JIUNWVAp21KvFDzNXiyJisDqx/LizgF4I/bodPfc+KgFLpCk57oeBJes +zibtWiOiKc+Uas4rLOI9qiFM/XP0vhVx+W7Nqaa27e+DPbgCzSuoVZKYQ4FEp7oJBcY16DHsCMLv +vUfiDmzVlVvAgsMXX29D4AUeuqZLYKHPOp2YEIxwbG4xFXRlnJwlQHUjMOOLU7iVdDVhoS7g9+oK +Z0U32qQSqIQ9xO+z7QxcgvQtXW6xYIRuwlaZx890rjvMm1j1lbvtmV6uf8pFLaYwsBCDXFTYYCin +qCOMi1wFHle3mnS/NcmUZI8Hj2rkoaMD93Lxal4YvCBCy5F0TDb7dPjevdmCppgZAvti3ELdvn2m +wyL4jpz3zttCTMic56RW+/3ELCyOZmsFunFUAEjlzCo1Ea9UFNDYUJ5EST0gGYCLEEQAXTQHSGuT +MBIrTC+B8hxMxlHCbnKFAMaFqVKCzEaLx4AMg1lMeIQazEcNUs7WKlAToMz4cXd4nEhvFr8ynUeq +cMKzUbpJrYc09fu14hJSilPB6k1rljKTy8wXBO0sq6KoQPOxFUvCa1P9gWJukynbbHsJs7VponET +tfRKlX/Iwn2KyKhoJcim3wygusE5uB/h2VkTd5uW6NaRHSYjBBFxZ4Wkmz7T/SuaONM2ouV1Ra0D +/tQUZLFE6mT3uk6nN5omaqBu3iIsulhOnh8irRlC1MXMZK8nwvWoFcGijDFP+fB1pq/fPi9YWzXC +5JYM3QxjCTEnG/jOnm6yYamdpcrTcqXgFmEUqTFMcQCwSZSpiTFVkoOJV4qL7pr3RCdIRklc/R/z +NrNfWBBSnHIcYY3dNe38YGCyqSJF46ZpZCRNRJHZMFzBpFen+1PR1pXZoZHexrwgf4qhgG2SVQRs +nuautzqFEyXESbVmPg4Cqi45bluOoN+Etl1MCWjUPJlMzVS3hcDsaJNllMEncaVgmMm7xJeJLOkR +B9a4swGc21uT6INENuwGXyA/yFcKhg24iwZ5qmAt3cPuLIhf25PM7hkFLMSCcAGPYirJmkixZ9PD +JK6xdJwuJo65ZAFr7K40obfDh0wr1URlDoQAk4X9wEI5mhabtd9HRJTCapssDI5+XywU5BYEoHz3 +yTffEc/IeXAVWGm8OmNl/nbrJ8kOiIixGvZHPMtjAeB5beZcpN8HXDdzajSLJnQWgk3RFeZ96W0W +uJISHi/uBftUohNMFtEgNg7D6KCqmqbojOzhF0NwfNIy+LoDU9TKkgiwAo2TIp9lsi2c/KBqW03m +QWPfJFKC+Qzt96hYMT9DVFrahcDEPZPlJjrxJqJXvHpSyPuK8LSEuCBnsmROaHIFx6dFcUVbXMRQ +9fyy51MFrWSPSxfbD34PKaCbyYS+Zb7IPkWn3YKAJn3TAjSSmmZFIhTKI21vAFijsTCugYKNyZAB +OcM7TFFv3WEWFnsQpzh5q6kehEEtCshpf1iOe0MMDrqYb+EwfysyhcocaSiQn/Ar3vDLFpWXLQuW +HFfJG3g5h0ERJcViMl6bUBAnNenCO6aYtGqytOPAhiCLJm7RErS8VTkogZpFIW5Ps0Y5FNuiQkub +xVg3xECk0BGirZ5ejoi3uGnuCiTA4qYYa3jbp+Au+lhExNO842jGBNzt1jAooDo2lwuQu8HIchFj +TcHDXm9fKc1+n4MFtzizIARECXJZAs1WiFBMOYxArcVbWzsjjVJnZQDYbI3meUjokdIPZoyuBrWq +S9tzwK7QkXjLEd1hairecaYQxakis0MuqoYv1D6FVzqL+qSyzMkC27xHNiRCrdwxMrg2v466MUkC +HTUAyaFuTLQEGjezOjbz8xNmyqjZpteVlFuoyIfVMiyEr4NIS4Y+fKvpuGm7VKvbxmnGeEnHClkX +x9ItCt1oqrMGzZ1isM6k9ZhOd89xalV0ONZBQgLJNo3JLSgQhQPbPG+Ji+IJMFnGNTHyk92zzmQd +5L7Jpc5drSqEmOWIc915VAmZSj3UefGQjUl0QVy+CGmK7BHG7EhF0sofCvQoSQX3HHN8/X0pU76/ +n7KitcAfP6cI8IPWziVUQDA1Qgxh7qFEH1DyhmK8LINfIwE5jbEoognOBgmBU+BULqYlPA4IcBI5 +EeusdVaERvyInOlaDNWAagWuekzA0ZKy3wg3oE0RZwmXQLJ6K1rXhQOYwzu3D6+b18K1elLZSLVa +EYbl8eHaEpuzG5616hXbExCOpXIYiWmzwEe9Yc0W4ETHPNHfh4iyVzOnQLM76rVLggBtERxevwst +TJssPV29U6RTVDwaSFciURW3lT3/+DluK1Xw04I9TXw3vNvMfhT/ihyJWcWfBsctQssVASsaWTWG +ncRXLSkarF+kYGBZ1NAbWpul7HPwn67AkrAn/4dW41UGgnoTVuCIn/OELehIpUvCum/dFRQx8PLE +KzAG5ZxIteatdipj1T4dCtIeHXstdaMK0oebxmPuOFNjxkw9FVKC8RY1ezLxe6XjkhASiLxk+m6w +kGa4vlkObBa+mqcSLT7gsVUbULdiRhwSLBxnA6XZ694c7jKrnFX11oa8BQ4Bdqg9gCRmZ97M5iA6 +EP9LSPuiKtgVygc7ZOEyG8IYInujlklzVn9mqjbbvJVfcKJcybx01yDhwzlAEyTUT4KZZ3thSw8N +OKhkK5uDDNMgarI01PkcuGlVjGK1VmjqmcXcW+S/xpuxDwxx95antvnxpbClmZgLCyKBA4x1bLIU +YAMWDrmBVYQNAVp9h1KtUmjnfpkK01fTTZEbFXnmtL8xNvs9rI3diIqSlCPinJGCQbN6HBAb8g0B +Z2WzYipLDNhykMO7V9CqK9gYS36GJ7pZjtX2Fs4OntzU8p7RP9obUaVykBijiPOjGEKUygX8BjTY +wLfmgDDbjgss9JNPgitIwNDfTW7VwixsVvYmjaJeWTWfJEG9GcabRxGMpmXgmtTH0Q9JcSt+hsDT +uAqH/j7ZzzWNuanlQoCqheBpsJ9rjBgRc7LKHloyb6q3fPv3S0d1NJRGqQ0lV1q1IOsFEJ055WMB +xe3I/IfKHtgCDthuBl6ewUyq5HgLDz+OgybDQV5w+qL8H9WOjqhHhzIzlpLH8Yn2aGR9ndgDJmFJ +5MtTPl4sFWr7+3D5kEkWJMKV1oRyYBhWkz1X94AdtKumWotdoiYFEODZ1KwtImkTlWtBxgcH3HvM +oKUkq7YDZKDmgFRuz4NJtfLTtLs6gVoAi7VMr9Uq3VGPN6UxFEFV/yNmVcGTfWYBy1Ihj63oAZhu +7NPZTAdCaF+A3QllYQUFrWpDrlMtppnFeCHAyQk7qxVUpLtmk4i7jrHRAiTZyLT58Rk/J1W0IQyK +2RYUXHhntZXpqYL5BPl7M6+88OxmMUunu6c+lZ73th9ioBa5b9IJC0qNBYvjbBa0yoWW9AXeXVBr +KiGRtCYcb56HJod6YFtfn2phI+dnXhO8GGFSpqdHXYOKYgstGmh3uQq1DQSI+BwtB/20F60gsfVx +YJUtb48Kw3QUUc9WQCyaU4SAOfvZWAXuroPRI2rI6quXLbkrTin52aoqaDePk91onVqF30nRYD0C +FX7NwgVDUuRnGuqWdyjby74CBcZo+Sw7x6LgpBer1U4EUHuYgpIz7KKU03Ol4NiRVYQyCpQmgvw7 +RI/EJu0UVATHTtBQb9UBQsHYqYzQPCVlicCZ7Vm2tHYuNIs9U0MwsgCfamISZFLO3HoHalUSLQUL +9cDEOmvOENGmYAsDFJL2M4sq+2uuFKyWRdZcPFLB1K/ASsXgu/+pY6eEWMuSdZNJQTS85KYqDQ2q +GH0Htbirkg3BrJyVRxbgFp66t5Tyl4AUJz/DuRZLCwCLCyJYBriz0BgCRmQCetO96fcgGphEUrB6 +Ds6Y8vb3Twyx6lEwjTcIiHE4iZyExrcmqkDTkbilGdRpivvukt8AzFoxV4MWQB9AWFacFH+4BTUd +OxUX1Eq0hK0lREqjnl1LgFPBQQDnWhMNnndnFyBqtyUGaso6W2eEaTHQgb2YsE6JKxk5+nzKpwrW +3CEqHDlLYrZCP37Kw95ADBgHq9ZENdLgg82Uagyrg5Y9o86WBZYnvCo8ELUt+OxP8HtvFerJsXi6 ++2toOeDFMd8sG+NKwcs0GqTANM24KVaHj4ANJYOhjmwny5zs/hrQiLMnqk4OenoB8GawNR5BAeBT +cYr4iJLVz1OA92zPi+3ncHh7pApib6hCG4qXU+jO5ObJqO419zdtzIHVFKt8EiRdzQJ7Eur6cDYw +4jWmihNcQ/x09yTQraJVJQtzEXnu/dF0shrmNlO1J9Qw8T02ViEmaip4gKYsFGFtDAr2/O3vw+iY +RRSXf6ho+MMhuTB8BttTrmaOkpAlSiiZFEZHfj0KRW7NSx+ct116zwZM+bENmKTNlnS5ClE673Hn +vlDRZgzg0wU4cyFB1kRmc+yGzqa4VvQe15KJG5JlaQJPvRmjvE0DTBkKUbtAkqdN+n+V6rRjZC4O +zcs4iojbLUa1yWmvsSQdJyWji+onSbm5AaRQLO7XTgO1tTx1TPNCezyWJSLpzc0OaOlV5oMCxQjP +I5s0GqSW4er2Y7B21Rtg7VmJVmme7kVqR4st9VGiTvFr6T7og9SXXMAon0B/ThWekjZRZ5H/TDul +caAk/14qOiyW78TvsVin62JTPnmy2FXvpPqDAFvnhpfeS9AGn1OR1rkKO1mcnvfo+00HzWlRPGXI +0v2NgFG/rmZAgXIZNEGKA4d5zpicjuWikgKsjJHrFkzJ0EY1QxgsxV4YmAUp6jTHkj0D2egxAc+W +REld7ahKu3Sa6xmzSmFeBnL3kgkoGBTJn+UJpDAXA31z6F/XtH8dUZ10fyxWZoDBbJsUsLQpngMz +ehcTUBvHWpsh/VbQnoL8KEufwCRtVDeA2quPysxHHAHX3UP/RK87QOqw0/aNkhzDwCxd7Ln5sqvT +BD1r79ohrwiukWJttcst62ECpFgT6YarwePc6bB7p92EWURb/p70Xu41SSOrdVxnYwomiOjAyOlU +AkPDviAyhwBdbWk2KX6fqzVX57CSxVinVujFrBS2k6pN4ChcVLr3Nu1MSIVHizYPZnsjw6T5MMPQ +K5TAzBBkB1gp40mn/qWFcu+lWWST20p9DIu2siUwWXYYyo2MBcb8QJpNsmeKgY7kMhmpPqTY6Z6R +0CLNVoVdEgydXsXLwLDctCUsO5jl1xyCoITZgnSldJx77LWtJtcwGsAsEc/SQZPMaSfaLJPtoAtU +HRn8ZGxhtUhgrUiz0SozAYHZUK7Jwt9Ck+iipZC55WNvclLZInMZAScdhjGvAJs0Jg== + ]]> + <![CDATA[ + raJlSgdPpw2d1UUnv6fqBEEYnrStYaRS4DvoEXnCc1YnQCq7lZUACBlpq0vM3Qu10wkrb0UNYAZy +BAGP5DRGmSCxvYVfjJD099yCMMjQoA07XZHIK3matEK6nBYva/57Mm76sgG0DfDUjSA3OwGMzeoC +kx2obfmG0l4KJGr1jvnuaXKHUJr21iQgl13jgYVCEPkFT9T0A7ufpYWsJxNqLDo2UOQqAyVZYP6l +STFgqO9M1r5q9ZDFpHVq9kpvBDP7AczVx+n4dVPoPet1ufqqBasXx1/FAShLdfIy+SYRMXxPh76W +RNapoYF9JRFKqA+2RsVJU9jMmA4w25D0WdI20uk4H+0Uv27vVkq13wZ/jfdqVupUXPX8vyHrUcfS +OMmwCxmPYkGcN8nPS3927rVdvcie00tN4CgZ/TvmON0T+g8XZhciurTKLi3pWXNuGzpod3lwfZEK +ysuxRdL4CNgkt22i9rMnAvYRUqjU4eZ+xfoG+SztMQlI3o0SZ7PKBNQPoS5vRuM8GbkFRu6NNeX5 +Ck6eyNAsj+BE2LQCH50CWUrZuQUnH466Jnmzcu74FfofS19o+vcO4prGshVxCyoz7Im2RJR2TrSD +OXImt7JczNr7cvAMu60p9ocdidqikyh9ADvyKjKUs2dxAYu0SybmUtMEXk6xV+ymL3JNoi30guzH +5uCwG2snWO/xbIu+sPqeXW2oVHqbT7dGZ60EsWuSPW6g8XxiIOpplauRWLsgFhJdt1swgScEtydZ +D+elpkLydGaJ0mfG26kECCQK8M1OcZJRT0UCxbivd9RXfibOEDjrO6/lDbQHeHAKlBodPGsn0UiE +pN4xAbnRBCiuDO4WHkT0nMQpwj802A44RPbkyRI8w5VKhseyEIm2N+DDsd3AnZnixuYzeNp8IZfN +0UrmOyfZG/XTIaQEqZg3F9RRA46Mz3xzrETqMzArcsl8Dgxm+WnCWYChubZBMtnsKMkqW+6a4PTJ +cgoTmHmsmadUst6xsj0du+BcQ4kzLK4UXKr3s6WcKjgEYCI1ehjY0+Y6qA6/m1+/kyeb4NlYfGsB +3MBrj2uuZptbUEqFaXF2jedDM85j4i0zyyCD1Q6XJIprc6xExe9CYG+LY61J2XqUEI6rDa0pSqUP +AaZavAA5r3pzZNeqJgJuJc3AW0Bhkjsw2N/qPMdn+pnqDBkB1spJo54Mg7ChLuQXtdWebP0e6/Dc +c7PPxu5EYI9HR5EXdY7clYJbqXM8TrfAXJr7dGuSW8A6yR5JDhp1GKpxNIrTh8FbKvvCdEC14ydg +FX2EgYtfB0lg2vWdfb1+7y+ZRCkjxdYjjlG7UmhlzjgZqggm6hRbx9hWS7DkxQKdrKD/AGcuSTtZ +/xSmtjuzE7ZIab1ZDW1oHjTA41KXpLZe6WUygMEsdY4j6ASWxSvUuwTcyO+DJAQxmEuKMKxR9NVk +FRZgyDCpcvw566ORyisVtcpKe9oBJC91X9qaW6B8XDHUqVGYEQhNOswJrmIrJiBFs88MrTMXmHOW +W8Gz9ib2WzM185zRL62nhKmLsgCqjKYKOS1L7DdsHKz8+0g9VsX8qfGccgBcLkSshxlyYaTEOrG/ +VnViM7B0FuxclcjCXfTz4aw1TtPU+NtcqGPjwXCog8pAdhoJ7l4cBUtgDd4ejI15V6NIdEe9/drW +kinkQ0iDYg6SrM6GTv4aFyTVbbrYsuLIKSUMjcqyppFVG7Hs+PqHk+IXtvOuIU8MdiKQOC1RMzeI +z87fLJr0p+Ing3ruW2OJksUBpsvc+f3V8PDlqc72hpu85NmaT3eP3p8qk7IktU0uFn5OksmS5NiI +7HgYzJYjhSfWP2Dcf8IrP0ZXpDFUC7MzOHO1Dh6bU9exUl+SRzZ4w0zLpdz+lpXLct14AToxvDsv +SagLnLzVImf0fWn6HBV9jqgmg3JecwY1qoGsfmJ9JGUCDbuZHFIEpLiTAndU5TeG6j33rheZM+/l +99QuRd5D89MSUFTq2Ru9vf97FPI4m6vNcAOVuZTrxDxOdw/eo9Q2fXFGZJ3dwl7pmh1p25i4XsAH +uQfzwm+9Pe8eN4+TkNWhV7XGG4OL4VEmnLmp6aankqQO87Vz3D0D2Wk5re5EJ+gxK1+DU5Jaa6WN +JW+htT9ltZKYVVUGYtc684JKVapJjiQxiIm+ciasJ0iDY6hxiU7iUuO6IChNwGKdyn0wL65sGFvh +kh8C4xA0glGHWS8wFG2iwo0Si81gTuEWoOdNyF3rIBBQ4t55ICfUyO+5OlsjcNaKkQOYybwbBMj3 +XIDZYyTnZmICrnLO3+LgXgFWKpIxgBRs6cvRElUFygRNXoMBDlKAlodWaj7DMI4HY1gWD740MMby +A28pmoLyfOJSyNyBVJw/XKS1ZwGaA3OOkpPCKaeKUuIwlMzJiq0ZOET5nDOLUOGQZpqCSweIFF+4 +DpXAovPNVuo8x4Fx7Rxh0JRLl3lSSvdqDmfdWG/PnN5kq7VVsINK1IBp/6x21HwDOXuzT9ulhEGZ +8RK0xHsYeRM40wQLKBSqwzB0uWIwF2licMggNi4iNQ2dExuliDjQeqHUk8przZopxHQ1TrgKUIq8 +80imkAFM1iV5MZaa4hZQK9EDw6RR6ZyCuT5qmX6vNEwVcZseFpV+xVgXi1eguNVyi5L/JBMkdcER +WJKGGTge6yhADXviWX2XST11Hmc9hpr5saWRFiuFuQfQyVkMYFDe1jIsNwSrDgZMamPHLgH6FCca +E5CSFoTckiYt80hH0Vqy1yWqIkZjRb/kYu7iQ+QQ1To7LYGJHrY8wkxcVX+NkYihyNyBIh7Nh1Xp +1iS/TaoEZm5qL9RHzchyaEqpYi9q1F+s6owoU8STRl/nRC14UnAyX2zpniGbx9YJYwHYPM4xYRYS +hKtwFcOSlNPEBmB0TTkVO1rP9PeVBSxidV63jioqpiX3o9J0bA4iIMobzHaZ+GcV6zfVYgvC1SdO +myHaM6uusdnRYezE6qlyXJCxWRu8LRDN1lCVlxXA1Q0BKgjkFFe+20KQYtnghVK+E4gXQVRRqtMQ +kMJ4Y54tloBk2AxpcwfoUgUxbqDev9zJqlhJXf759e/FspwW7xJ5f1rQi8bVh5aPFQX56KPKbTJk +AROu3Fsj6wJyiDopV3MTIMvXBONXW35Pxstc5F2XxjaMlOMAycx+qlyWLAFmnDPdgMS3v3ftSsyT +qihu8Xo0LubgZ/L9cv1zKxKndCFeLyrzwQNmA+XzKlaQMtCaWMWrtoxjoGRB75J09idFSQqDbg3y +owaY5L5YFhauTM0zsV8TLLNMu4jkI7AYDAhcuQ02A1uFgSqoHLH9/T1KiMUWQSftICHOwVKVgYGF +Eh/5NhWxHnKVXrmNkUuEiIjIFZz7QkKqJF2DlxUOUSOY6JoMawESZuJMVp5TeqkxjLKx9OMaX0K1 +yjn2FPztTL8eg8hT2lFBgExrDOSMSAG2UHDrG5vOZFHBZ7+URimTNWFWsI3t7ftg5hjeZCqNwd8O +3Q7Ou7RkjgTLEK71FaAyzPoKJWmdcPJkC1wky5U/Vau+Ll3SSjamDThjsQfYduhxNMjbkGOJGlze +OqKKDdZ3fnONKzL4wO1g9CjaJIIRs6WniO8hRZXOi9gZpqjDPKuMOFnODDr3v7AYUrxMSmaMmGeS +DeJDc8RYKUwoQaOBXwfUan46iyQ10RoIhCyyYZWqPvAB+YTBmnzgIMksYbF0FXk8JCEeGlKbKQKY +VWdoUzArzHyZG+cVBKOKlTDPOlYtdytgaJUc702ghAMvFJzO1kWAVReabNKZO8dli1BVsUUTBS2g +WWBJwgMAQerhklT0p4hlFQcqgXuJiCX1KgiGKcDUkAdDXHw7SNrN8ksz6quSBWFC5DISm3VbjUO2 +Q+Jc8eW+UwZhqptR0DMWPQdCB55CqzNaGi+jmDNXO0x9QU7c1DmXJelTThXJ0icLauQaWwnxwk4d +UR7hkjNq5lThMIWRY1ovEWDL5XsJR9ENiDnsQCCoxKtF+mVVrPjIWATy2oXkFrsu7NgB1u9PFcwF +5xlcsAi76lz5qAAYqcaTEJ+fzStx80aTmNex5yxzXciYjzbHevClOVCDJwiMcPiFhYHAsmK6Vrgq +mer2ze+6DAxO+Ufy2EVqWyrKqapdMpIt5XPzAI/kMCczOtgEAoY5RD9VIgwvLdjZlBm3xikqs8IT +xtzD+4WYsYPXf9BXHiJKZLH5auPtF+jpFjRrR7iNKW4Byxx7DEZoqk+q4cw8RaL2q7C4yWA0RHjK +CGGgZQ5szboip6CRjTJeLBiPxoKb65tjXd4XW6OsY5musmDoePRu45NsFbBkDd3IxdheF0aFbfT3 +G5jisAezrZkj7CUYeOfofZ3xPfybE0dVlK42WCeqRC5Ysp9yRsZIqv27+VZMHHXxLExjgz2WGwis +St5VqQqLuNoGe8vHAnC2Y0ZiMwsXE3gufmMf51Q/uzYbCOyRRicGr68uFldS2sINcpPXItLLgUn7 +BE7y2UzCmfjBAogZF1SjQUwLouEecUqKUkJ7F/J7vbwbYg4uL6SqqUXRBpjTpk+3JrkFrJN8wKue +Qskz2ftqgwMoppsCnN8Wybw0xtrQvpZjozrXzOK7A4M9ntpc2JutTjP/NmSlHtoGajOYD8ifngmA +i1WAiy02bOPzq2JjelN1D3DRp0vNS17GGy6cbdtz7DELg6rM4YtsKZAQVfJYhdmGnirUi8trCd6a +Y6+Cnethpojg2qh5oTvJBhFgUyez07oZMylcdw6XZhppCZyTfjTTeTY/vz9DaENsJCkYXHzsSsHc +KHrhq6Si4DWp2iLNXgYwasgaG166plw2coYdLbyXTWv6TqYMAaoHZlaziME5xqWGRl+amZNkZwk4 +PrLcG0XVt6Xq2LgoXdJZtY7Fjg3YUxghnVugGFR1L3PdC4SLdHENmnetO61NxmatAvuVU2sht2w1 +Jd7BzmttVBnoEtyF0sM8NrKw+6oToA0igwvXPshSOe8pZ+70XoCTmNoI6MWqSrU/kYo9JfTMaYP9 +LOZJR5bD+HfXdG/rlPrTJcJpyT2dlFYQC6BGjnMoVdhW9hFjsrhjQSojLs1XWyewx9PFrQTpXi2f +dy5AG7y9+svBe2ROkDAb9dKJU3iiXiHCg+j6dOfgDyh8OLgiYIu8UjD3QJ7HVTDli9dkbsykBhx5 +bnXBfQB4Ro8ajbe4Y9OkCsTvJ3BNeASppoVXg7LZjqdbCg/6FBy1YIAEdmYlZjDiq7iokxmEABX5 +dmKsjIDYKW5bwmRPcnA1WI2vxQIK16RYXjJt+offT8yj2sgaFjM2Dh4H/59Y/bTVBVUcGBaa4unE +j8YOVvYRYM5NbjTbqA2wMMQ5Q7sF6FqyNXmX62L7lkO731hpO4YOwwNrqDPWt1x/Q8bLbPXzCCIa +yq48euucHQhOqVsVpAX1J2+B4HOwGRipHiWudETq0dat2mPSV6e2pPMn+0rB3lVdnQ== + ]]> + <![CDATA[ + eiqI17dWNp73AaSqcno1UUuDc0ob9twm2PrYf65HfKa0B+9n5wnNQnUDIgjK74JxWBQOrO509xx7 +lJ8hKOOLV5CIc93Ebj62Wa7T1gz7exe2nwGQdpP2gFcbr4OCN+6m+cmmi92QTbZkbQo+fbI5Wnd9 +82s7LmibysFsoftrGcGV6TksmO8LLhzY1syLuGP0HoUKe5E2DglvSpPaOgshbX5y0/PX5lV0Nqfd +XwIAhf9lcGdDeaY1TNhtAOX4CSg1apaxnAtwsc1fTIEY0QUOCHzbRmyvwd0J0aOMG2K7IWTYNu8a +vMdEcorQiXVz8xcvBTZ/CXQmW0zc3/znBHY5LG4k/54Ln803eTFpnnSVLbz2ekVq6TOMl3H1G3xo +Nng3lKdYjWenkVG19j7jOVcKrn3jBgtYjS8409Pdk3xAdYMK7ILzW2GPBVS3fCnEb4CXc6zofIJF +eIvWcqVQKcG48VLMB7PDeRssms8ebbFqUsYXTWIKamYoVG55w0uveCxhs8d4a9Y9pslT5xlEsjfv +Jhsk9kgD3CEvYaPTVIFzAMWeiil2zrvHEE2EjlDnEQrYv1Jo5/IduVIPa6mNQvWKJUqlas1oAXKH +CAZSjPIUvy2We4pXk0jfnAZMhiYL8aRqkmwg0sq4En0dqLe6VtHNOSLCM3HOGAGHogBg4BQi/rxF +z2bu/x42UKVIWN7wsVauzbkIJh1AzkYSDCI1WaAzq9QUqliku4ZnUEvLjuD55QbuzTxEhsWaFF9u +ECXiSNFClnQ2wUtsN5dVLrLeopG91FcjYhM43BeGTa4vOTsZ6uooEXU1WzrhJLXoQNhVS9JfIxF9 +ssviQ2qX9fpxLreJn6uDslKbkrJhwq1V2mMJkDM8ePUp5myyFFDt0j9+sfqu5ft3bN6ezmVei5qe +jLHuWSXp8Z/nT8q+ylb3x5atrpUCeLo0Hkxj/7VHgQvWbFSgp0sona5vaDVpU9wCtjmu36Nm9fg8 +tTAN2mmH2w9eKbgR2xSwl6YmXPsTTeB9l65/nrum6UivwdAM5splMkG2n2vHJK7SId/pZBORRj8q +9zGYrf7SFShKHzFHzb+CAlOQkubb+N/OnqkVRqul3I8FDIQ9mjfS0qx95wDHhLb0WgqeYB0jpSWb +9/ON0Tw+AfeivZXQMdj72So4EUSBLWu38IAmRvR76SK8HEq5FArMhsAG+nvcmiB1NrSXlTYUoDrD +hjE6HFPxYo/+TGiwTtVMitNdiLFoBwOqhWIoo785zZpTANBj1iUCez12dnsI8XmX7NirK+heVaQ3 +NwEzluGnw9QbTXdHGt4sgUK7fMA1bcN2HXpNHtdR+tdR+eWOplNcmO0d+6r9gvUMpAGO18BObcfV +QDQbi/8QG8vhfdKNLWFfYwFBt4nIve4MGcawr9F2QTL09Y5VXa6UZv6VVza2XXrXcb/lYNeBNV3p +GUHlwBUYivb2kRoRDEzSWJK706J1MdXRbw6NYqN0v6O6VdbOlcQBgiXqfZ4BLMpGqWKZr2jAq21t +qDqddYkBZ6fUTiDF7TLl9wWnwH2IpDkd1fPMVZuoiMAwgFOTZXLuxaKnk+WmSGMU6aBD1XzROZW9 +onqba1L8Y0ZzTzoya2PeS8MrlBSUXcfLEKJHr/ESlNU6smmjKab30kCNirxk6yPapcsKZTWEhP4/ +1jqHynrZ99G5kqoZ96wNeXq2V6hp6x7ecXsDAzqDcrlFWZPTo3KScreLfvZHmi5YP8tqetEAU+Je +U67cpYEQlSxPURsoeiI3bvjEwdIFXF2bX1K4cysbV4ziiKyBIvfclW0kCTHrtEmaS5Eq6Jr26RQr +EgN952a7bBpCXxv6VrX+8to8hYC6uU1a/+gEDosdmmq1CYJyOuq7Ky8IFQ8JVYHcV052S1vP0kgX +gQEJ3lUxCEnaOBNw6repPdu2t3uvR8lEKPsQUjO5UvuYNutfxDmKugwp+/GuteUeddO5/pEC9Rmi ++9JscyqaiXIvK0yQKJtMJ+hAIGQgpUxiJuq2WatdBluTUG1zx2vF0BjK0c7175GDF9GF5YStrxhV +jNU2tU3iXQclaoswJYbK66XeK04JxOekDDxw4wa0T03S5zkE6V2heyv9dIPWh9G9ydMEDS1mubeL +wLr9nou2EFALpgtQe18wWOVSreAuMG5JIkBttR4oRS5hZEaHrpCkQI6OFW4VKJXcY7FO+hYFKhSA +rq4c/YoJQs4Gbt3G1oa76yZgN+4TmjwhgUKBasZuB2AQa1BsY58wqEaz0jlJsS1ZJyjaP53WVTC2 +ikBFW6A4tSoFxmVgRGteKZsqU9YO1lF6f/fntbM8m44d8J+1tfXScjIkbgCjFIhOmIGclPg9mqGF +PN0uSYthWI64XaFD9KOhAYTlW8JWTac9A+7+fradQqtHXlSvGyR4OwWo3NysqyMfSvQbNJhmNKyl +GAQtEIuu01StnkUmCZTDBb2hO7t+RRY3PQcCZKOwTqAHUojzzB6uM/09p9/LirxiSRFWSdceYgew +6JWo0sZREBh/KUCgFmk4F0iihcgqZSQYyKYyFYJt8dYeEvMqMENwl+g4AUobLwjCNoG+8s0p/6GQ +CHypCLslWMZbhnQvBmfbV+leRC+xhD+IIK0Nd0MXaUyl64IJKJAEmw1U42RHaBpJwUDt+Eh7XYBB +dOJ+lBVoW+noJBxNPkYezf/QsVznUI9b+2NSaKwzFigKQuT+WmnrY15GTA+UzNpsbFWdlNCyZtlT +B75IVg+XReKT8ouyB6Z8qZ7G24W70h3aou4aunPO27+/A9edq7p1B7CzjU3CBBuP2GKkwCYxB5VD +GMyvFIO5OpDOWc2YU8UqcPv3d5zWznPdooF30ssGbf3nk9vocCfF3kLdNG9uaFON7fIUUQtxObtp +D6uO5JblZ9psdkg12tJZmnPVcfmpeI4CW5HHKXsphMFA9kCeaUfFogKvWqYJ2KidAmOQrc1l8bN2 +1Mx7eQKqlSTqCBXl0Y7MNUkKJY+NqlQ3rp6jFkkOv+UJqD5PE/ExaK2OAWxS+ISBkmdaK+mw8g6o +RZP3UHYqWRNS7kwIYV+3lPJp7GHIBeohZXoW7XwoRbT5y6w4iMomciPNrg0tg+WsD3AVgUSULi9y +WAv2ZPSp9XnnztT8+yhNfQYwUxd6hkrjRsKmamdlKT7BfZW18XCiM1GhgishyU+TyTQlgKB7suXQ +qcljQ0UQUtN7lqMUQxxgeg3FCJAqVLpOLQ3FWhC7uClkAoh11L5Z2pgmU4xjxrtIaY5ofBxVseX8 +vB7tmnMBKQZnlQrplqaKltdUJ1IuThfdgIERUhXVDkO7aSkFxa9tE0qClVulmqRtR1Hmll81l9Bc +PEEIYJepHvNQvoFAEz2zBwkrPsNTEaIuDM3Z6WHTbrKUkpR00kBBg2qZMLma3mW1a0D5pJK8zWvn +zuB0TqoAqVN2LXMs4oaZUFqBTNdSRTdRbZgeSKEFjYaWwyQTGVaSyM7Apk2MtXOoAEtFy9suOtNT +0QGAVlWZLlApfzTOrglqyVDoYa2Ihj+ZPbtaVloTLkv9F8XQS0hNypK+aLRTteD79n7RuoIKIW6w +qKZjA4QdulYwYUU4CKgmuRi8uWm0NKGm6uUORigoK1QSXbgp2ZA6BCsqf168giHZ0AQ+qW0M6hoB +i3EEcrVhgtSVzziYsTr3tBErkjb49hSmh9bhLJafPblt6O4pb/n6Tkx3rmnn+ilOIujHzFRfxgQw +WHGH4adsw2MEGciv4Ima9lQF6ZL7D5iI6t2updd6pgIMEb8vUhxYptUuw5wElDFBlGbmfhKiqVxf +h3GSLdmKgSs6QYUc36U/s8DgKuhWm5XBEK271pPibXEw5JlxtYmdUGW1Eu33KUOxgo+K+gl5qMZs +yNWleq9fcrkU28HS8ao1nCFpcTA4VKoz9h86NjpIMJAJzJJLKRfy9N+22ZNdrJsFzUu9ItmWKpq5 +n0xt3QpnyO9NLGvUueLpLpPJ7RG/DzXHEINLMGpNbkniZhHmiOBMmU49mjJaoaFC3FkYZBLemLlG +R0mNOGDjpnkoWQ1qazCNLs+MJ+Pu4JHiQAg9deO8G0u43Qn+oO3ZY2tmhh4peOHvfoi3O4kMdKXy +pHKbIh5rA1ABVpIqTu0325C+2YY5DjGC2NaQEBzlGhVCCS5udmNTK6qx9eLNnn/9ajnrzo/uRm65 +hhdP/NE/lmAnBStmX1DIbCXcyTVsTrgbar9+sUQqC1LTdwCZLYes2L5vLmc31H79Yi55s1gi39D+ +i6xNsPdQpGz28jRx8Iv/ltiIebE5a+RMRerkzYrpAhqMe3C05IV3tCAhrKJlBa98ZhsszcypH7Mq +mxKryzC+fqI6Nbm0zUvDQAayMnKmv8etz7Yu+paI/7QHnA4i2kwS61K2sJ1dYDRZj6WpnlSySKyU +xZLECUKhO9CHirj3iZF2lQG4um3UU5A4pwH0pilGeEO5WhFiRDhtW34fxZc7wF7LHDIQgSPk8BTb +oBw1qdx0UL9n9cXZS5Gpw7b6LGuQMsmKPX++xmMN5cgiTD5l7YdN/fLzWNUdSxFfsao6ybIEAcmI +LrprNINX7SL5ypp6VJMbKZFJ/FLa10K2Xx7wOj1+FHbUWN2o6v8BBbIwQT3RpQeVUGvJ/FJVkg+E +hEmXa01nTaU121QuWMtgfoAFyMUlB7CLs1qA6p0lVDV6jedVYnWmWZDeGYUAvZZ855PmztUMdA66 +EVlOEt83UjtDbrpatrLwrLnpsqiLepC9RvVQ3liuNyt3QJ1dtEcNwQsSPceHxWUf5LY5mASG9s/t +kNvcYl3D3IjkxeRdKPgGZpEqT5wwHFVEZmYRKpXpYsR9FdGsqOdNcCW/NSZA+E+WZxwfi7iugsA2 +EZ9t8FAm+q6estLFCMpbKzmmYw6thCAHnnWxVY9Aw3CxMVUs/FX6ZinBO94sJi2dsktir5JWUdJq +DoFDTFouq1mF+aeSlhxXc+L0UtLy3SbwpYG0hGPVLpGfSloixo75wQfFnwz8lWlXFQ5lrT3JPXSS +Z8j7RIl4Sli5TadSnd7tpLyBjrWwP57ia5PDWevuJ1E5iOf8WmLLkX8vwYXl3CgEUjjMAPoHg0+X +YEo88vP3dwsw/fBaZZhGV9vJDWfcyKVGUgw9X6QTJg2B/ysNJlXKsWrlSD9hOYcYDv2OK+wSyQ+K +/PtYsXjjf6Zvc645+0a9ZpXLgqhyAZu+vJqMCEh3jV8o6tEt97NQjczOV4nighB5VLgwMcvGVNnF +sVWHgBpD4fBGFTKZcAQH5fN2RGAEKUTKAwNVinoqQV6p6JdaVaekg/GEFP5ghh6n+hgJ7qEg1kTN +m4GKDgcoLl0kj+jkKYaaq0pa6JNRg2ypjBUJ7i7AgSvWzUC1+ao3O4nPfPLkoFXhhx1dBKLmHKZC +cDysIBrhPYxBtnJgFeThf8qGti5LTUF6lQ/g+KPnJ46ak0Sny09RPHEDnCx0IpHNiA== + ]]> + <![CDATA[ + bnHWoJunbNATtU3qbKuGmTwctVSSW73widy/zEizNnd5KjZnvvFUEdycR9QohExeDC5OmBt1CglV +xzZ5ylLGS8J4OpW7cpSMvJaopLVaaUjCYIbBDFMYTqbqfuISI0G8wkrXpVaryDKw8iTpwDEmbZIZ +/AssWo1ZJhWKTupmqfAGlMgtRv5DrVclMsstWajuqSreHIVQ6HpYrA9nBPDvaT+muKDIrtISJE6W +gPVY5JFCwXZiupCSUDwpcWyQhSOfKgspeXqN6a6IpTJPghtnsDBZpjKzvzmtP0/f1qq+jJVwbRpa +Z+F8bD5Lmucgv6+wyqU8D4hRzweNTSLNEn8TTy91mDH7Jxex4GcvRasDyWBWHwbQYwVOnL5M7RQr +SbyCZD/eq0QJL13eJ+JL1B6SbguFBLJZkviS3VUpgMww9oUODpKmeCua1olMSg00xYJaKIdZAhCI +RTSxSm5zy7MnP+zWzd3R7/5w/ebot1//wbujs5urlzdvr58fvf7x2cvzo6ub5+eLtKBGvcQdeYUD +sXrKXe3CuZmFkym+Eq/3yrTJDMzWcTYIQ9XzpOryOz0uMCRA6gHn+HS47L148RLfFi+UTFInnEIc +gjeuWJHDEYFdg+GoGokTCdLcVBaMQwFssanWTF9oiFSoycx0gz4Cc5sarBc7+wp8bbhB6vSZ4kpy +ERH0KVuO1D2UigjhZ7odzfO3Y5oisiisgmVBskX7XpWAKrNVp6EKJGDg1XTy3kZ6XSkCnswDdjSU +liC2glSlFx7zTE/NY3jzs4e9tAQzi2Wy4Mgu83QEoswKdhZUL3KR7L3W5pS96aLT8YGwVjRUqaym +SgYybyBt3WIOMj10TPCVgofEjURcVUxt42Py6yjtO9l0kY3damhp6RpzT7k4jd1h5OjLorgQf6n8 +LIyDYj4gP2f65GVyOKkevwaxF/LBSWwXNeVipjg2Lvekp0dQwTF3i8ykTXZdgTDJb+/82e4DuRRh +ngx8iQOeyMVCNvArdaIUiSQNpBbqQ6zhZsxDwuStZ+VgACM/PnicMbRYJG5kKZZf7C49IQjIWTTK +w7iCyJl60bgPF3PRkMVX3fVqpKZVMtnLy7ILc3YOeYXzlwtV80PKMQDyqcrnNQipRY0ASPQrvfr8 +iogXLqkPJ1ctjMayRRZum4vmJ/GcLnPcXs5WxJDHjl1uMrZoGBdN4BIQEFsqtW+srHdQC5JB4oq/ +yZaZ4j4dEKiFOdIAskanwCRMIIkcgQmK+FpZ6og6VNWZHARrATLtsHTUiOGd6QaoF5FeQbGfU69P +YakkvJhHvnYWY5KXmgkWbKHshpYq3qahzhUR14YwAGnPZ2ZrFLjjoaMSmMWNMIvsSRSMDkLlHlO7 +qPdsN1ErtZOkLPFSVAOodOVLVISxMrugPJiAzIjYebEUQCwPJrsVJLSKoq/JxAKHU2Qt12uhEpGO +hyqi4vUgAHggxt4XuVaTLMfOBi/QWEwUU99/6OIBeKqx6Cpxa19PYfmhsXQTqF6+2HWoLzNzdnJX +eURCe1HzyW0T9apwPpC812TeksePC+syb/JOe/uxFNXFlk9l8CxKgYSrrnvaNF7QRcSsc7EljVvd +2v2z3YdCp7Uf9dVtJJr5o69f3qLGVrF87FJmqT2JaFXUnBw5ZxOUtHdtaq7v/jZEf3m6cz5RaBk1 +0modSdBOohNEq+3y0BZiSiT6DOY1iTokq6tRqbJvXayN4yXyXQ3OvUifZzY4IpSxiCwPcPeqnLsQ +skFDgHuQxUqAHSzREE+rtxi5Jp2ET3fiRgbytyRPjEeE/Q4Za6QEO3qEaYHFNRUlyLAjFiQKYG8w +pXaOGGYpjJXDS4ZWyK6UQUoGk0sdrGCqTEFy7qUanoOAydhLjBHgHvkJ1sO5NNunOODn0Axtnxyt +9PpgCq+mdnp9KsCbS1GuBAMfm2u5LvCVTh5EwW3UV0bnCGw5ZmWO1V/D2auhyE1oFBxTkot9uftr +ikaVbCC2YEWyBGOndRL1H1yquQsLp1cDBzBko5rVvJqpQu3lktzJNte3gPnYFkIGQ14e2f6ofsXl +TsyEQcDSxe8WGXMoIZ6F1NqYonzoJJcmsftM4uns5pLhUxeqJRBZ6uMAZtkukhmZuY6xLBNdwpTt +q7q3OKLIwKLpVm2yfal2azIc6lHSi2ajXVTfJnu/AUYIkA5kH0dcAnIv6qFhpwnA/AbzTnH4vP3c +waVVSXIxMlXTPfV8A7LU8cUxsmSt9ph7dmCR4ycvd22l0tKMw1HOUpp5MGNCWFnGF0mkFsGGjPkk +wwgidHRMZFwQO3UDlyapX/TG5QlcM24oJ0sDrHZpvrhFt6RoBskuMALFOBB4Y5UEjkBwe5W0/IHe +pCmZfTE6ziCuYnbkAE9lcOW4gStYtiflsnuxkpMjwTgIS1vC32issQTlNm62cHYNKslR8UewBGVB +gwu0GaNYoACG0MW3zmwsk5PtCndfcBszMxgbjdFuhvK0R8Sx6E3cBJcZpVZjb1nq14Ailb3lGTut +VRdIgXLG9Dgrf4tP++O+DQxYB7mrKFHgcveq5VDvaWperq1bSeEFuM5eyMoKCuJyvFMPNt1CdWB2 +2c5T5VIqMTPz8BM0SSibUvOp7mbrLe0Ay3Yivut0N9anCy67H4Hs/RwKXZ3CG+EQCl165IkfUXbJ +TCjbgky/3EtgxBy7jfl34rAb1x3rerGjJBo/lqIi0zlXiKUGJRZLmqN8nKPW6u1gzHG6c2ZG4aEb +Q9JjFHEszXKSJzDF17mMQIQGm80tYExyunvuWTQJvdka0RUngZgYje8zqAhDyIVOwpuXwDILCZiB +q5nQZpPCwzn7OoPO9K1FFQEbFyxzcjbfBFx8ewLP8JzmnBa0uXR12k5wKmXSTMY09AFeLJSeGY30 +mwFVt9ncFCcOheWmeG3GusBMgZsbMxs7LXc2qwGXGEzgGbY263xdW3twZpIv1+va2JzazCc9TVI7 +optnn5sB56hN4NkypllnC54wWGwOte9JuW2MTVDY57MacInBBJ5ha7PO17W1B1ubI5R7tYGYOfYn +tCZyngHn5DwDT+Q8m9PIefZxkPNyC6eR017PppyAi89P4Bmq06S2pI2ln208iPt9GsPiaZxZKsJ9 +3sem+sItoXk9I6xq6y9lbn7468Nr3Xy9fMb9QNMf/Rd/WbXoDIUWfz198t2eNi1+fpuWlpvW9r9p +6bFCGOVHRQQxFu3iJUHYCbe8NMRsTGAy8VHQ0elyklvA0yTXfKbfPrYG0yNP5iknDAV1Aie2PYjE +6clIzdDx71HcwNkCqlI8bkVMnbnC/5CSaGfsFqBO25LbkkgVFIdpzkhPj9UinKl8WxFfyVB+Eso9 +cDdhDpAguz8moFqFnN0SszTiEyCnmrPDD93nGdwKq8Nj3hACnFaB72qcsosyOdWZFmOQKgXiSCIL +T1Q/ssa3kCeLTS1sl+5RQymKVKISAzZ9SSYg1x17okK16gcDF/WEUvZRl6A08nmyHkaT5oioEYo1 +6bLWppWuYpLcA3HPI+zCQa9KmjMu31cDDIORxknBIt2ra6kh5yuiTgMBPTLjUkRiYmoWN5My0kPI +ARjEBTCQ8ZKgRBX6zIVM35WUuRy1SCtvN/xA3uLPuIYfbzb5ZrSqPx+XhpVlLTshQM2kIIcPyBCB +Q5mi6BGGSfQiATW5St7LU3Guehmr9h+hVxWj6J9NLCkIMyE/lhJsQRzpmL1rrJ52IGf0OeEBv8Zm +d3H6CJCj5hjIiS76HUk6oq2W8sACdqLjp2aBsIUqN0jkT5Y09V3X+OTJN4MrfEvqPKV3UAeVRowg +q07DdkT6+6Avshx2mKGLVg9lNxs7RMSj3SVFUAKGurhe6I9ZjiJzLCMH0aRKcRfqgrWrS7aUoivk +EAweS79LvO+psjIoNhMSduRKViFIXaJQE9EVCcI/6ViNcuT4H7mStEchKI3kQXpj7O9vSZt4yhW/ +x025Z9XWTlyFwtNCsOAMse4bm+WoAeoGhAJ5MSLylrJ9C4rARXIlVPUzk3dMnY8+suEjUgSN112N +5L1nMBFTlIC3cUV5BO8Jl1ySEyiw+eVswbcUaNWa+j853BInoJVbiONRADIfAXlzJWaNmArZZwQ8 +uFaVQJwi6ZFyYBTJw+DYEK5O10Nwo0RRSm36Se908cYBNUORIs9YjaJaAcSXeSgxPg54IKjmsvJO +et1JLoe0h5P97TezEd9RVM43l+fXz4cY8eMfvtUh/++tQ/72y8uNAB7xajV1/JAFFLZ60vc5+lIC +SZYkIg8m56Q3vXbRDFtEKxqFEzlmXCnE4gMi1fsWmAYjCZRjsvkVdEX9+1GcmvIO6yNAU0ngFoUU +pGjRCS4UMBsN1x2PyCBABY4nLSop1sam7aTNh06UFDXond5ZrctDj3vjbMA0JVtRIVmJl+anaZal +HBKesdZLtrHVAzhY7y8YW8EvgS3Fwni2JSc1eApQH5w0mS4oroBdwcSigtwwYlCFNSgKD/CSSkHA +AK7Ft+dMrxI4VLXMRbpfyviKmPwFON61+bZigpgVWlRdpZK1ElAzOHt0EcAsud8UD2dKMCPLb1Ny +x1hnTOzUiU3sqfqCis96HG8ISAelp9drJEtvkiCTOTYezEhCTykoJXLc3yCkaIEUdOwpK6mCESdm +2lVkm1rstjt+FlnEsXRyCiOCbBVTsKAZSc+nsZopR3yh65zBVYsDER8ixfEESRqiqyAe+8hCL4i/ +8nlQnYvCFXZ+b8Jzo1AH6oQTxfI9nurMkdRsEJxfV2q0jBAhzhy50vvWJJmH2Hg2NLQiGV1HbIKF +efAlRgBU5PQAFfsQXk+hK6WrLIvqXPTvhZUmusUW/xYrMpIozEiLXpEsKEbEFI81qZxCeCUNkq6u +peUTlbI0nYrEZQnB4OdEjQVyd3F6MWJAsDZDM6DN28g8B/6CoRJBRtcF4iEXkMAj3/Bwxag/56SP +M73sVS97lUdDf14Fq6LtV6XQQccVpOoR+H33XhkWS9UKlEhDimnF1+UGUXwWxQjg19jmJHlBCpSL +RSK16gwkpcrig3TxgWiKRTmLsaLILknRilM1udSR8EHnTJQN4bpIeANdV00RShzEJcQzRLcG4bzp +w8BxnGdP7PSjEGrLGmJF+ocwBgrfT1BZlAGT7OJCtOvq5GZyBRRvgV/ireWaDYAFp+E9ZVwJo3Nl +VeO+agFEClFrOmNREZPvGRctpXtGVbLkuubm6AHtFPE1c4TPQ2R1kNxXUiUkxYRIOCOZJzuoKBwl +L3iMEU0II2gEJKlCtWrwF6fLySZy57kkh4gUI2K0yl2bvXhjt4oP0EYphwFMqxp7RTIP3XYJv6OH +3kfsQxYTA5WGqVBQ6EyVm2m/D330IU1VzZeg3/Ndiw498JS9SlGcGCX4XleVqyrUUcMHU4KJg8+4 +YweqMaFiOd2JClk6kwYDNDSuZc5bOHvyPCXjaWh4hjZGhQO7HhYKM5A8maPeYlZHcQ== + ]]> + <![CDATA[ + EUNpKgogdYlsAhK1Qe9rNeV/gwTOdlPG5a0p1veXKL/eq0T5mKLcpDpJsB2tKyDgleIlJeCVGXzH +HdVkBpY8xhwQwIVokqh3lyqSDk1cx7JV61JfPqcpAiwRCdDh+R9gTvsFGBaLKJ8ToKZ/UOA/lbr+ +Sc0gGrxEdKM6fJhnv3AciozNqGk2xsK6QpUOdayXsmwyNknGKd9dVDOgWm8FMKJRGUrKv6A7m7Yg +0iWpOoWxamHqlrtMcfmclxJVKsXmcgok7yOkReITfJ1SkrSgn3Yf5R5IFFUSxm3VYgTE9CmCEpzR +BxW88Domtm8pe1flS56iZgYwCyXh2OWmeQkWRkPx2ZI4FCitxWMwmbOCpj5lqnsEsAbyUpKVsjdW +OnjnuRBDARYJ9MM1GIXtkaWSH9+glWd+UtPc4OFRwE3D8+kBkCo1Xsvc/aRmtC7p7L5bRaNkhsjg +KWBdFVYSrkSXpto2Gp9KYlhWGGvlmFbDBSlVLOhQJ8E1OjZl299BdBlnIZIx2/qC5qpV3IDtw9wX +pZBxRUIzRSRWs5JkS2ThRToCCSrKtMWRQLINZX5cKThLRVCSgzSUdmLEJNqRML8/o80gGs6FlP84 +KrnFsUpiDQv897l4z61Kqlopk4e0QMxRTU3QMVi/48IhZE6k6qg4CGTaNEv23pr1p70dTpLjYPOe +R0gtgSXAVlKITBRSzkUKa/d231tmHkN2v6qL81IxXIYGXHiS3AMsqJC8M+gxZ9FzzcAnyiLlEiD6 +kY5ayuZkqrsXy7s+RmWcqqYvsuqmwBI1V3C6Vdnb17QEgRKb1CTlf87dxmpplTxZUbb2Zn8n5MVg +mEVihaIpx1bFCovUXDo0PSstCi12XW06ydZYVYs5ucsjv8iLy4TeYIrC+0mn0DxbYpxwmmSUjiRh +inioGVA0GcJbbjtZIKLI5VUm+EVx0FzJSJnqmmO0he8vH+8OU6B7QhYHXFu0HXCAoLgkGerFqZE0 +G1ZMy0maqcoTD9vV5qwf5Q4XbxJyFOnjSu2wMGtNmcaFipxkzaic6J8M/VI7IyUzDVGCltJQlTiC +X57s3CDY6buqRVGKV7zjc16qJooJQgu7FarxFtWl6MzwSywzO00MhdGqStkuRpfZwE+64lKcqtzI +Lt7enT0eUgmsWlJMNNOdREVqRHak98EOyUnZdNkeN93dLN01WFyoqLYp0hbpWSbPktNFk4u6yeqc +fqVmdU44+QlPk7hLm9SsudSN1KStRIZoNccU1N0jCm5p4hMaK0KZmSS8wOJfzSgZIoJuKZnRe11b +04CdrQXva9vfbocFMi+ddcNj24/WV01t6p+RUQOeKLdmyE5a8DRNXliyDXmYnrrZrxMVPYOluRUk +umt2FOm/sL14xNAkjbWBPU6rtqRZLdmACmmU8Ni1ekFTg1pWbsO/Dx65TPTYaoKSt6wlKqmiGZmU +HaU5LE4yu3kCb+YE1fUCcsYo6sd5WBhF8eHsFhTrIEOt2B3LVKGbEhZL12xOVxwqDzS2ZhUvbWTg +Q9emD+IgMmugpN6zFV/f6M2zk1xcp1ky8jxSJdR5klAVzh9JA9b2j+FAEZ81RewhAol0FkknO5DH +Z0UeHDS2h8eGkg03+gBqwPy93qCNMAemKbKfiX+cbMta0TN2qdbNSlCqrprBSxrdVPI8KKl5S91P +4hWCHpYkZLwUq6qeM2KUyFkfKwSEcszpWjnAMJ+pIFxHrRAz+pGhVrygXd77ncv6iePk358/f0G7 +tW/e9aVs3et13GvtHkAMnDKgruAFFGsmCcfaG40DX5paoVFTIVMHmqTaMkcDIrrBhHk4kLIV0Ixa +eUg2S/P12ENslUI8yrWzN1vL/Ds4VsMUPkUTSEmQQHF91UIeuC89F7YJ6pqmYiCdDSaUHY9g/HEe +PJBqqUQ4kOj4Y+8SBvCUcxQ0k5HKAqATQEFRohCkKDli47UeMFXk1XVSrXspRkOvm1qGqGKKpLWh +zEcpaKpGdvagShQZP8XFNJWR2z65fYmWB4L4nAhi39z5QB2fDXWsQrDcMtii0JQqC1QfqFT0+8g+ +oXwR7DvUakRq+tJeqxhOpUXF6EPSABWbkbEBRYHJv6qGJ7L2BRTc4iqlsMB5DYJokkb8VMxDakjW +qn6wUmlNDnHPba9qP3Lll7RZ+2VcX8zO/YpS5Z7z5cL9S/vszGWi+pXJqT5/tYQU6SAimWAR3eN2 +Q5ExtpgPreOtpI+6gr2W9FE/jdjLyVbP1nMO3hUjOc+m1XS4PpdFxlfrJEngS7UPKJhLlxSEpHRU +A51DaWaJ8KDCnwXVELY+KFUP1D2npXMb3ycntv0q1VWCMiUaOMM9aGkX7n+CoG15frhiiosb392G +LqZYlnyhCkJOfIUahCrlGYgbypZWzTmgv2nkT5NKMLJE2o8rVcwUTBiYj4Ce0Ji2wC3qnmIOlK1I +1qJ0AheHKmgoFonj2jF4G73HnwB/OGmNH450h6M+ZftwmKqY+Oq3wVtzbB/BQ6kaubQTRVP5+IJW +wxNFU/EqsQwuaLdNdeXnYCROT9S8+NDj95FvuRRCmFMy1dORq74gWvTAmEG2fn/5a6YQx/dkiaWi +cRKVC4Hl16DE/yhSdVHNYgOCX57unO+92WLNKC+9QHEG9tLtweorifuvxp3gliRwCEVipKsNT41C +NdtffDw5cTfFvsg5jmg9yF3ogcoMbB/d/P3730Y7Htx7qx+i3Sfm7IDbrEvtVDcr3URZ84FRWoCn +qb0kt17u/OB7cLgKtadqwCBabCQJrFoyc3x4G7qY41e9nWnjdr7v/Sx+x/0MceN6LgCLMkBbs9Ht +nFVVm27po2i9aMXsSj1bCs6nSTSzghH+yINRqY5SJy93TiHk8mCe0a1NH6prFaTrWT21CaIvD56h +lNhHwyi0NiOcuAsqNV8b2QYC5ph//j0JPsppcWL3dPbafo1TKVEcJ0mR6uWBN5R6nTWQAkRnPd35 +rV+hElTeS0usNl+N/CXvKOAwb4D1SM3wg5a1qBus4tEdwypaT9uJG0Rq8bVl0dINiG7Z/JlBkawk +9IowM/kbrqJsZKbejNSM0uJeF19n6xrQVEW0iMqipClNcSol0miyc0PWEbWbaWihRz1V9NdoQj8D +IURt/FhDlokvklHsRO+AdHukn2Tth0NRXiyVkolMK6tvI3+iFXKc5OEKAlTc4ApgqS9H5b0KGltV +h8K+m+CNSbSVGNU696y1EzeiGqxXW2BOIBJ+1SXSiF7xLAkeBJRKDgCeKG+rYiPEvLfOOlVY8mSD +1I0jl7nkvmjVThSX0/rzlZqKij1yuYapO87Gwk5sxeqU95I8Y0+71AfBcHxP+4Rh9OnOOU43xCUu +K/KYkiIUELwwqxHN9qzFjLj1ARoi8QZy1UI2GsspVyfqTrLsPNpqiY2gClXknTxZrow6VCldD6CG +yTXKU/EANus3MDvhoFVDm3bZFAREgqRuihozz8oWupAGjz6ys09p3x39lNcqSUfy1NQKnZK1RPlt +Qgo/TanFDqjSYZHWvMQcOipEibuVmrNRaMOJSt16AedDs5Sa5bEoil4p4b4rkDu5yQQFGWzUM0xN +27Uivp4F7Iz2XUOZ03KifPFO9NnmsPXl2I6rRDUn9fg4SkQL7ilbEG3Ci8FvhgAVy5Xdo9YbLqLV +GEZGybQ6UV1XN0ahApMYFi6RJ+EqLdquBIlJPHmyCUZ/mhatRmoEo21WAIHqzlY08E4odDBfKYwf +fcoPoWpbtv/eKt1wL78oUG7zIkOVe1M9Vw0ypo4ZeiZh1qyeih9LY7z5BChpSk2jknRm4eZmSRUo +ZGFSIzY9PAo+rdY8UCpqcj+lilp/Lavcl5FcTx16HTpYY/HUy1cLw5Lgx6CAZiJonEvjpe4PSV6x +oBse9lIWIDDQZ5LWDPg9hk4Ews3s+nLbCBtcG94e+fnUT7LLSyCrqR4tWK0LWkcGe9MiZxsrp6Lh +NaO5vNaXnzESIoESzRI26xvfA/re6Vq5YTEaWuJJWHyJ46HxezGvFXn+ZflDTdN2iLiJdIRSRgjM +UX7ukb9L3e00t32GagbVE7PIKPw43VpiQlW7qyGggzp3lohmlsGOXvlbkn7gwB5fitZiguiaBQy6 +0VocaaIcKulrtQZmn/JCrE+l66RHhURkowq3d9QQAqQX9cYBqlhqF0Vd9BA4uLFJPzY+P20laWf6 +pBB/kPvHbfYkZI3q5EZUDzZG1T0YyBjqfC4LmqUGldoqcqINKuht0huRV2BeX4sF58zGFmu4PgNm +SW7enCDZY0H2CjZq1jLxmo7k7MXvudtw0d8XbaxKjlfZqjjdpGayTZQSP+A2+n7Sk4kLRq5osZdE +K1JEhZYlY5HL8KPlvPEwqsyr/SczDp3EAN/R7VVdwJCtwCs1f6pOvQvReHUhhxGzFq4D8Q5vhcrf +JBRqx3SqmSyvNWGgooK9dRiItxKiZDDaqx1VR8hFre2g6VUVHkwmF+NblRmTHizXz5HXGqtdALWb +WdUwTTz3ynfJ0aa8vWa8dtRRVTJxuPJkj1sImLyBaWVSqCDVGvRUc5qB2iHwKLlUUzi4/SPaEfAV +W0q9TUpdmDTetX0kp5rIUN3sNrWkNFiHzCxQtAx2VhOIyqdLBAU1HlASGt9xraq9nHMn8HmlVjSJ +fQpRPh6pFS/5Jf5kjKenFROo5kHlyFVjmjSEpl12N4GRYuEwARCLdliKN3PZsQo00NwQt09YtHfL +4IAN56N7nyqCm450OuyMZp+hxGpWaK02BrASUUaBXHA3YnRZI4y5/NDJ8vcAz4cSDZUIGsSHmjwY +uMYAB/sUd0/ObQmkVzbj+eFZ8frrWIBvBTYs4Jbf60MmLwFWlWxVMwRU5TlTTqxxmiR+dGlbQ6y4 +C8X1iTt15N/wU4prSE+BZHrRW1UhvlSDcW7eAqseZgjsHrtj0lu+T1JNgtiMgr2dQjaiyr2cgbXY +gU0EtsfunPU2DKiqocrNYytRu7lJQEGf4sdphyV9mo+thtljgurc3N9TKIs7hgtQD5bOWFfgdlIh +wKdPdo6WNwbirrcbMwOG+e3oNq+f3y6lwz7dDoOVGVqze1inn083rk03Ls3FVRoJHqvTpvk9xqTT +3djmDif7N5/2PVkIp25FVS0nLlEtv347eFkiF0bVPz+074VJsMjSJJFc+0q4WZON1qyZjpPED1js +hwTbpzkuoT8pNLMoN/MGF5b9Lze/PTXhSYEtRuqMsD5DkKDJrHmEzhPoviItimH/r1KTh0wzGLs1 +Lzqk9NkcHu0pKalYvkcddNCyhzuhSh/qNCsHuTmDzswpoVm/WJFfmbRHIY+2jYhkRi1qY7JqFHk6 +iTLt4ta8+r007z/iENRJHQRrxc5hJVTzS8fmY2uPw+V6XNiAbs2LloUedf6atEOWGsTNsHPcLJbn +8MTFMbPDmfjp/BLPINBu5zeDUvCntAVqkvp+uRMHxc3H2ZlQov0V7k7eJNUJOCNMRw== + ]]> + <![CDATA[ + eVQ4D/va1qziRrpvmzB5VtQWTYzOelQEO6Ou8z6FlgUodpLcWHoaVA5LKxaUjHm7U+p+Krm81p3I +ZkhUbFbMyH1aG5UyEhxICcAJxZ3QMPZBaJjkHuAQjFrr7N4FBxzIbAgcot3GKk1dgZme8Xxs6qBV +it7B2GwrnnOEEux2penGlImuZ5iVbLte9R49ZePoBDUcSAmr6BFh93PrNNHeMKPXEd1QUnqvlNzT +tPH4oG8g9wW0WxesPqHsmlSslQNNaIK1/b2HtsrhABntnzZ1yiEpzDpjTE3OqtlBMvsnQZc4pS5x +kWDRILY2sZ+apPyFmiWCHZOyjtrE1YST1rvImpqBI5AjIjQS6uYpzmQ2x+Bq/Hz2HlEktk6hdaVA +AsEGU395Wwp6WeSJL5E8ZYfq7IPwAnCT68udWwy2nWcbF+FWouxOg9oFifOnzS4eVWSzZ8J2k3Kl +lJDDxNi2vgaSJU+bLxDuVRSgMHp9dmcsiCrqTSwIl2EqhUczYHuis4etzliFbRpbiBVj16VsDUPZ +jCDggpj3JZgEoQhnS0cwyQzcycwN8Ob65Ibct/sh9TEUa0XnYtTwhIkXoGoNRCGqwRzFl88m+dKM +1qSjfZPGWJeQZQPU/WmKza9BoOi2w1VaxV/pB73Ur2QLMz5I9aZlbtZlQNxU4r0CbGRBJYyVhNKE +nu9a7ZIunmHHrbuDXjy7S/aMUiRSw/FP0FlzQV/whM0vo6e4S7UysfUTT00w7hiNAtOMqua0jZ0f +tEaYX+7eNt3PnibEJiGceyPick/ta9pE6cTJ9PmbPV5kaZ4eL3vE03zxLx7eI9G6VUGgQ//ACZ1k +LC9N/JheN93kOJPiqSy17BE3FQS7ms5pNrEBuS2WiVwdsSpldvuzxdWTv9WQ6Ng/ihOwr5FpygZP +r+lspfMT4p5+Oc9Wv2j+RxZUWSj16bJvxIBTX4yeqU+3gL0YC8FDdWvZITEVF1H059AFrpsBbLdp +mpmA3//p5vovry6u31xc/+PpUwGzAjr/hyd/ekn/4p3803f/8e+/v7gc0zz5nf3x6F+f/O7vfzz9 +083z8/HH375g4CxL4J9Xl9fj357S/yNdltIEdv/rT88u3/I/+6Pf/eH6zfIf32j5x999/erVs182 +P3r+t7evfnh7eX59dv4BPv3V9O9nP15cPn91zskPv1skTczxkxneiddv39y1AsMx7A3H2aBBHa8u +fnj75vw1DRv/YDPO1vHq/PXbyzf3Wck61gB8l6v44dnr89+/Ov8/b8dm/3LXYkh6XcdiNtBerun6 +7dWfz948+4lGv3tBYR2rmSO8XMrrNxdvzn7828Xl3Wu5vvmOB69jSQvE/+VdQ/9lg3ud3Fy9vHl9 +8WaVzOvi+q5j+O7m7auz839/9ezljxdn6ziLi+tNsrq4vo3yV8i4GNkl/jcvz189e3Nz19N6+3F9 +4CVM+N5xFR5MkHfz7N+sYwu2uPQ/PxXM/7mJ+c8Xz9/cxmYNe+/Wgr+iu1zDj+cX//jxTullPYsA +vht87PldK/j6D99/ffnyx2ff+3WsgzD+lx1Kwv+8vnhz5xN/88N/nZ+9+ebm7fXzMeibm9uu0Ade +02IF72Rwv/v2/MXRVweFae8K04tXz4YAefmnm4vXB5VpXSrTShjPnjSmtI7VHDSmg8b0a77SB43p +oDF97C04aEwfC/+DxkQa00qe+oPGtEKN6d+fvX39+uLZ9TeXbz/Ex381qYMpfR00sS1z3E9d+uH2 +I1iFuvT6zfNvz3+60LJon4R2sUT5QbL4n1+8eH1+15mt9Eqsh5IeexduePffwZRWcSOe3ymCruQe +PN8SQZ/fKYOuBfV/PvDifvfy/Ozt5bNXpyQ1Dew/+JP6l5uL6zen95AxPwr3uJNknw7J17l1HP7D +NaeneTXIbylP/30n8mE9W//f+1fYv4SH6/XgPn9+e9uwVbxar9/8cnmnH+JSuefTs5vLm1f/+vOP +t1slP7hMx+hvrOntqxfPzs6/O3t299JWEvm0RHljOfqG/ds/X95cn1/fw1ixkjVt4b17XSc316/f +PLvHuta1rAntL8msvyqW9hnz5Xt4JlZo6/hyHBSf1aX+JHx197valxdv/vLs4tbH5FO526viUO9x +r5+9unjz49X5m7WQ1fx+z9fzv28zcExeuHUsgBDdQP02uWh1qPst1OMnIvMRohuo33mF14J6eOBb +9sfzV//4EO/Yjq/SXz/NF3RtJuqLh3o4PvH9X9ezf4/df99v/BohMk/DWqIcHmHqXQ3ujwyTSWvB +/33CZFaziPcIk/nm/Kfzy+9+fPb85ud1pRd8evEkf7x59fLHm8ubf9zFej7Kq/Lq2fOLt3fGGvnj +laSTAt1NXfITNBM9TrVfCfq7dfr7KsTPLy6frcV5cpsyfDebXMlR3MkXt6TcA0P6+AxpLcTz2Mi8 +daB/YEOrOYoHs6FPOpxwJXv+2Nu7EpH+Fs/A3SS/Evy34/fvjn98upYowl8eeF8PmcQfJpP4Htxn +LeT/WPazFtltHznQK1nLnnKgVxIJ9vnnQD/wwVsJlT1YyPv24vXLy2dn51fn12/++OzlGl+OL4Df +3uZhXgW/vUcgyGrIfzsG5B53dyW7vy2s/nLy47Pr6/PL784vz8/uoS9/vY6FbKO94SZ74LL+uo5l +baO98fLdJ5J7JbT2GiHcD3gqTiis/o/PxqC7/JyrVTCu3oX9p6FarISAHv3UrUS7frRlYyX4bz8W +jMCdMrc7wv+Otv7oF39cxzqxqgdxqg9cIWD+8WfXF1e326w/KoN8cXF5ebcF5vz8v1diexF8l2dr +g/7EGN8Rnnx39v8HXtIG+ht0++rm6hMJ1xRUl+i/uflEbBeE6IZR+E428dt8G2f90Fbht1ty5xDl +zv54c2dM5G8vL67Pn60k8nPCeeN+n529vXr7Dq/fzHh0vRI+Ncd5YzXPn1+8ufjpzrW8OmcbzEqW +Y0hvyXdvnr26O/7l8udnv6zkshjKGwZkaqFxp6C0kjUosh8hsX0tku5jNY2VPDeP1jRWgv+2pvGQ +qkorEVi+1KpK69j9x17hs5VQz2Ov8Frwf1QYRFsH7ocwiBUcwuNslash/8eyn5V4tQ7ds3bIFSux +Tx4CIdZ5Z77MQIhPnuOuxLv16ECI1ZD/YwIh1rL7h0CIW5b1OQVCrES9OARCfPQjeKRysRZm9din +biXm1UfbNlaC/94CIfwhEGKNEu1ayOyx13wlavejr/lK8P/SvRCHelePYR5rId5Hnfanu++rcV1+ +Yfu+qpoF7x+vsN+Ih3sk/q6lLtRjekisBPVH1hXza9n6L72u2MnNzeU3KwoCPnTgO1RMeyCjv1+B +opWYj96vXtrKi6F/6nV+9iuA3Iv/fstb8f1KqPNQ0vHjMaiyDhI4MKgDg9rBoFZCnQcGdZCgDgzq +yW/PX93carT6svjTv9FOHOSnA3tayQt1YE8H9rTFnlZCm58qe1p7WMNDXNMriW94kGv617ka81P9 +fiXbcrghH/+G1HWQwtpuyEq25dO8IZ94mZ5X51c3t5aVWEGZnvuFYPoj/1VwRz6P/++Oxv99Nf48 +/vvV+IejdSxuirp8dBUioe+/3rodaypBdI9COH4thTHeoxLO65dUC2cdyzhUwlkytkMlnEMlnN1r +sEo4y7N4ef7szbd3862L6+fnLy6ub+9+/sFPxBD/wkL6P5tWbz+sppHuo2sMrWYF7xffvxJd6D3i ++09url7evL6dO638Tq+IkB6bqIMD+PPblfRnfnQS+ipdB1v56Pf1HdxKfGt1HHxWF3t912IfF3wl ++WDvecNXJUI9+n4/e3Xx5ser8zdrYVW3NXr837e5JCZFaR0LIEQ3UL+N3leHut9C/bZIjrXldhKi +G6jfeY3Xgnp44Jt2SEZ9z5d0JQe/zkS9e7nC/nLxz/PLv1w+++X7tezl55+otL24270aU+F8d5RX +8rrMcD54LPfI+74cjyUTM/ksg/tqRYR98FJuSVZrcVoc+nUcvJS/8nIOXsqjg5fyVzuRg5dyNSa2 +HTf84KU8eCk/oJfy24sXL96+Pj+l8iJjGQcVyLbmi1GBfjm/vLz5+at/vDo/v/5q3Mzzr8abdfGP +m69+uri5PH/z1avz51/dvHp2fauB8NPTjS6V3J+eUeHfdSzrvRWkQ0PDg4J0UJAOCtJBQfooCtK3 +F+Mkr9+c3qOw3EcRaM4vxxfuI9SWldhAZwhv8Kz/vrh6e48ShG0lCzF8955i9gVE8T0XBWUdi3is +vruqRexQed++ejEe9+/u0+VjJYWAlyhvCMuy2yc318yRP5GYjS2sd92Wex3RSha0wHi5mHvpXxsK +6joWtYn5g0SE716enw0p/NXB2vLlWlvUtiLWFjW9sNHlYG05WFsO1pYtQjtYWz76cg7WlqODteVg +bXmYan6nTnj5DtQ/ukZ4MBZ9NG57MBY93lj0WhWs1aS27TYYPcTe4j8Bgwu2/d/++XIIYfewuKxl +TVt4717XvS1JK+Eh23i/j/llaKTrWNZ72V4+8azd1XG2z5xFf2Epu4eU/I95uVdZ3uFx1/vy4s1f +nl3c+lR+Knd7XQ67Qyr+evLZH5GKvxJ/3GNS8dey649IxV8L6g9Nxf/E37J1PQDv+4yt5Oo++h1b +nbR9eMtWxJoOZWU+kbdsLagfysp8wBd0JYf+WZSUue2GfXRH26GkzNGhpMweed8hTXs1OsR63Km3 +eCEfkOi8Ev75HonOf37x4vX5OkNFvgDH/A3vPjGlV+fPV3S3d9+M53c1yVxLjzdCdAP126SC1aH+ +z4Mu8etzjrXeu3soFZ/VOazWw/dJ6nXf/fjs+c3Phzqhv96aNpS6gx500IMOetB6WpAf9KBP9C6s +VR57rB7U1oH+Y/SgtaB+0IMOetBBD1r1EXwEPehOzvvU59+sYwO3eO+drHc9uP9zE/efL57fI1ks +uZXgr+gu1/Dj+T2yIn/r41oWAXz/5dGWgJW4Jw6WgBVaAv729tUPby/Pr29Npz+UW9lJj2svt/Kg +EiQ/PHt9/vtX5//n7aCD257WNVUgefHq5urOULzjlaRRCrLLBby5uRv9lVTPJlQ3lMe76ygcyr/s +dRmH8i9L1nso//IBy798AcVTHiwhCLLv3o4Xr56dvXl2+aebi7VkytmMDzJKnK3FkfhIo/LZStSf +3Ubk+4he65NpNrBeLun67dWfB+X/dHdg61oqQswx3vR+Xbw5+/FvF5d3L+b65jsevI4lLRB/qOlg +LVdGLAYPsP9+4tmBq9n3LVZ7KPjwUZZw74IPDyfGe9kP3zxbTT7hwXr4pVsPfxUp/c1dK1iBjH4/ +OZdWso417EXSdZ+XqLuSeIrPX9L9cqTF9Vz4g7z42cuLd3Ps36xjCx4eb7EWzB8ZbeHWgv/7RFus +ZhHvEW0xCcPf31Zt46AzHXSmT19n+jQ8G1+k1rSS9NU9KU0rWc1BaTooTQel6bZVHA== + ]]> + <![CDATA[ + lKaD0nRQmg5K03srTSsx+B6UphUqTZ9LwvoKc7s+v5T1uxnPelawo930AxLuV6IgHRLuPzYVfREJ +93ff65t3UdNHv9mHwmkrLBjw+8ubm7vo6qPwn3tGN6+nafRjL+2KlrDrNf7l7i6EL4iGpO/av/5w ++ezsf391JKCbl8/OLt788q+rMczqcr4ki9+ayOvLeKbvNmOudUGfmTXzYXz4NVcLOFnRdXlo+P+3 +0pfsVDthfnArxWfSdnstWQiHvts+rsQoeui7/R7P96raJT5WSl/VInbI6Q9oGr6SO/WunuG62/du +rb2OFW1hveu23K+v+zoWtMB4uZiHdQn/+cfVpMW/V5/w77Rj3kHEej8Rax2kcJCwDhLWZyFhra6R +5y21tD8vIQW7/m//fHlzfX4PKWUlPGMb793r+sSkr220DxLLJ2+9Xh1n+8xZ9CEG96Nbrb+cy/0Z +xYStq7H9o+/2uqxch27w62mp/ohu8CuRCx/TDX4tux63UL/zCq8F9Yd2g//E37J1PQBf+DO2OmH7 +8JStiDM94ilbC+qPeMrW8go/4ilbC+oPfcoOTbge8YCuNybuMaf/6Z7DukSAD9J/61Cg5Nc+xseV +Xl+hpfFxYvWdJLUKwfpBtVY+twKVa3HOHYqtLGwClzev/vhsDLor/2q1vPjqXdh/Elx4bczrsUz4 +38f3X78j9GAVPJiRuJtZHTn9364/GWQdC8WSHnTzP5eCB5+B8LI+leyW6KJD4YBP5Gqsj6Ieezf+ +vFKjxe4bcncC/tOVCPWPycB/upJL/eAU/E/c87UyueqxV5lOgS7y31ZTIfHR7q+1cqUvN1Dr0xdn +13c99nHRV5Lq+/4CrV9La8T3EGn5HaSA9L+9enb9+sVHKLP3+7fXZ39d4/28j6XpzbMf1vIG7zI0 +MXr/cS/zRjhaiTF2gfPDyioNSvr3AyV9bEo6rkfuaCUreS9a+uZASx+dlvynyJYOCt+75MC/Dynj +9xevVrKSSQz8cqwH6zuF96EnMfqvZy3vmeS1stScL9V6cIgnfCRjWdt13Fc028OZEx/m15eX69iH +ez50D96Lu/0bfi09Ix7ecmQ9uD+y6UheC/7v03RkNYt4j6Yj/+vm5vk/Xj1by6t46Dhy9NWT33z9 +B+++/7fr59Z5hECZIN//6eb6L2NFXAPiqYC/Of/HxfX8H5786aXOwf/03S9XP9xcsqv9/Ohvz67/ +8T+euKOvx//9/ecnb/V/7ujPT6boIfrf3589mQKJ/v7L+Mv/M/7wXwP081E6+uPR//f/u6PnNMlf +nzytzbXjEFM6atm5Y99CObpicD0uPQ5w6v04NBePZKx3zhOwHbsSMwPLsc89yMiSXDk64wnycYo1 +y7whVBmbj32pAsut9qNfnsgMIXUe6o9rcZWHjslcZ7zGTNmFAazjC7W3OIB+IJt94m/VPpCNsRHY +jzW0zGPpj9EL0OVIs9ZGc6VCs461BO+PTmiC2sdYAefjnounsbUepzq+O4DhuObQGZiPS3BFl1VD +FgxqPK6VN6YODBnXGo67pzkJ1mLpCkx+4MfAHBx+7o978EnAAyrfJ2BgYDnONWLWWGNWYBh7IROE +4xZSEHBq4+AEqRAdj83HrZesQOdSF2BKZZpg7EIkcDruXTHIxy7J2HDsei+6LT5nHunGtox/5gna ++EthDFqjPeYJWhxLcDRBG5vp69F/8tBx3rk3go7drl2OKx4X32kL2/iWi52JYEyaCu1hS8fjb01p +a0wbGVrGyfqm9NJ9EayKK0nJrXn+0FhUUEwnyiRobq3r0OhCkG1x44RAmck73dboAwg+F9kVPZef +dGwNGNvsbvTqg5yrL0zEdLV8L00nHWtQtMYO6XHn4xyZBmlVQegqjF2PfAv9oKEqhOWPQ8+6LD8o +s8q0biyQLwEBW65JxnqfgwL9+JzMGmvDBGM3aN8HeJxF8kU/1nOTyx1pJvn9uOZ0C8dB8N2X3491 +6dUYXw0+6tixlCbAQVAyQToudt2ySxMCzlUdy0yJgGMxrTPPSMc1NjCiDaZ18uTFE3fs4iDMcS/7 +ID933FuKxASPexmUM0jJ1zL+48c/E5PUL/ZWhPMMeBfm5+lLsjwXEtY8lhEEjVaFaHwc66TjIWCs +VZfhB1XIkgdXSNnroQe6ALKRIYcNYCVCqUYJABe5FLJkZkxyOgocmxNdK3KSJUwIlBKUQJgx6ukm +uQtKNfMd59+P+6ATxONUqjID50JXShgbl8Dj/NHO/ZNzKMQWxn/kOBz/bfwhhXEtxn+8p+Mo4+7p +OYztG6Sv87gyyOxKwb0G5cC+BK83tafcBFjG/cHDknKWPe9N+WpjrIo8F3XwTWU0vLkEayUwbHAn +F2OVZyESHxGeNs63Bj5fur6Nhw6uHI12a2Ku3OgcklKHa70pUx1H3cemMFahlKIcPNTS9RFN9i4A +SIzG3gUC56SsSj82uHIPUQ9t3A1eAX1KWd3AhbijrIBeLp5gcOVQ5V0YXDd2pg/iyoOWjoQpt+Sb +MNVWkr4L9DPhyoNpD/7CQ+lprl3495gD29r5tWRWHWLQp3nsJ4sRA8qsgk5loJ0ESPybJ6WzzplJ +eXyyj/famLU+rENiAFPvVbkUPWdHS5aehQ7x49BSVZbqQ1WeHJvTrU7VgMU7fWv5STKeHIXVtkHz +pdsEqQlwsFTBYCx/bIVwpOQaLf/3dBM6k/pgA3wfxgbQk+bpP54IktiRF640yJdvA516IR4l0kAb +vOIKxBCKChRDssggHBe9vjq5J0gZLTc8RcrgWSLhZ5OgY99VHBhShA4dHKgpUN/isW9dFqPglnWX +o6/4VufHgIG12u9LULLtyhhrHZJi6voYDSaT9T5Vz6LPIMbsVUyr9Fao3MAcTohpsIkMMF8zoSbn +i3K7Wh0e3uVjfKJPdPM45BiKjmw5ZWxgtp9X/XUl+sXPdVwISjaDOnvFmw1JZFBdbco9x7dBjOMC ++NCEcEPI8vXxViS54ETfla/i+MBYsm5JD9i+Rs8CE2Ojg4hF730P9DzyBS+hqog2LjmPHAJzSzi/ +cTe6SOoeTwifVZAlDMZYK6hK5Gxagq9uIqDQZKvpXFUeHEsoSiuu+qiwQfgqTcXckom5TW/O2Lhk +nK/IFRtbKK8tAfN4cgU45G1vBMinLr9XbsZUrdc5xBIV5pMe9NjpZp/nayPgpgL1ANbQ9VaNPwL/ +CnmcrqlJ6aVXCO8Fn4eQXelJg5Q+brxe1e6b7X/KwUOn0q2qyvcyCZtdVI/BLHsSCYvUFFzgcUIt +0lnR2zWUo6o6ETFSeZDcePyVrgbrLiqDkO4CwTkwXqLSlKacN/G1oMe3lN5VNHEB+p8jwjxRhuib +vl2t1QopJguxtLEDOeIGGZAGnihDzgMjmTX3UvX7gS8RCxFOhWx/TB9lRHuu9pgMIVgFRHBAZgqs +E84ead4TfbjpYThRvWOwmi7QFLPwn6BSL/+8K02N1zQ63T5moKImjgfb5SRYZdeFWRKr8cr5x7Pa +9I2WCVjcG8eqFJCY7GWnukt2AZsSYAkdt2LjCTgbgtWmWs089AqsKecgezgkGTxUM0kJBzMOtniV +lPIQ1OyliyI/ZRNv6SWrmTXowbl7jionQKYZayCNgrdmiCKD3oKQZhwPoJKmZ+1hvL3H0J7Gcbmk +9M4qJ57qlkHEPoM1j/2MSq0OzHVj/SRx/ub733396s3CrvOb73/7dFwS38ZFnFmTvvnm67Ozt1d/ +vXljwW2/+f6r8X9AYqEvYm97NoEjJt1F2RqRwQyYi7LXXB1WRkTTIFhFxxd8nH9uTB+D1JjAdGtZ +WRx/8K4l29laWBsgEarY0biag2jLrPbJ1g6tSlXwIWrjaAdfESV8vDFuKF6K6/iqag78z7vW/+69 +HQJ5qvfaW3f0D+yk78qXh7hLxPt7yFlDAJfr4vMQPq906yBUDS5QhSo8PSI1CKnE4KBmBubiRFW8 +RqikIqoROEdVf8c187WqsSfJtRhA16Gnziagd85FJbcWmqp9qpTTzooCMm7IoGqVbUqy3xfVBdlY +MvR7/RYkASeyiyqYLagBg3mbTDAp+5NWzyQlMtd4kpJS39hcFe6GuNkmiUdE/U4LFPyJBdQCq4Sr +IIgh0UU9mxy78YWBlYpypDeJ1umVY82sEkMA7l2J30OVJVNDrVXA0RfVpXWblNeTuj1ZOVzItvdi +q2Pl1IlFZXwGtgtiFKksD2QIPil502Ij6XciktdYYHqIzKfoLSTJWanH9HhWP4H8uA5RwD16nNNQ +6UF+TuTAMSvLw2Kk6GbQCGJfknmDz7p7gZ4pJmo8oU1kdzGM+plJqPekr4jzqihVsWDwI5KVerYv +kCrij1A/hlJXXNVXLjknyji/nh16KwuVak91XY8jlFxUpG+qaIwVDhT1+R3zqviVYIsi/XKSE7wY +nXZgQKv5n0/60W//x9Hf/9eTt0+ic0dfv1K+Qm94GHsor18eO6kYe7voY5rcVVOXgx4MJVWozkOq +M4NCgLTWzEgVSLeWsePmhTD7kEhwvVWlsyEAT8KCsHgGp6afkkvGBo2hOkCET15XG+b2VL/8OKlK +HdaQlCC+bCz9hAUF+ryKGqQqjVfnSi0S4/SVdwV5pcl44btqcINZwcwRo9eBg7KC2RNigp15aMai +rUVjR/otBSblMUN0UEN7I9W/AezxKdUqyXRdsFTXqr4UyVfbE2A6fX0sKcSqGmyWS7a9etqVJkQj +E/kskhFZB8eSsTtjL/0MrFum4jE9Aa7jIDsmqKSVw4+Qi/NyGiFHkJw6PbwpTQOm4o7CzpRgu3oc +ZkOJSwSlo0GocQFkQRr61Qw6GIoq6Lzlk7nCJ+y5z7pBjexNOB6nnMWLZY1Avnq99uxw2ATy6eL7 +AiZUXSn4VCh9uafb+3+mVLu1r1dKzJ0sNWpdkTUMYItdx7IZcw5cbMwM2sipA8IZd1FpMRfdLT0Y +g+FgYGWZDR1nFH2E5pfjuzbWm+pXTfWkb6VUYY8Q1du2xoAwJTrcOwytdEpdF8DrWwLnRzMDd7vk +xKJKVdJmQekW0n7xxB99/XLbz6hzsOmUldquQvMcPL7cPIwVKar+zCYSWS/s0grEjpeCHbexQTSW +xaQzoCIAWhSwGeTms7Ka5F1eYGBA7HiKdTnUVjWfdHsHiJj1aSJG1Krq/FHVtTl0UGYIeIdAZE0c +LEqkPrcZEJwwhJ6XYwewpJyXs86AggB+P0HZfDCflH2bJZUFAgbE7giyi7HzxWLWrR0423jL3W2k +NWQD59knNx4TTzL1lYJ9bWppVk8hA4VeSIuKXt4gkp+gUfVkNu0qoifrSTaWLJ280W0cvNPbPMSb +AGDuUUUDNs8AXNWQQzefHbNkfBj6htKmammVvKOTW6FU5rMk6Ax09FOxsAQ3/jl0XVUWKeX/svem +u5okR3bgE9Q75B8CbAGZ8n2BflVdqqWeyYaEpoghIAwKxWQ1u2d4SYFNann7CTt2jg== + ]]> + <![CDATA[ + eXz33mzWwtboh4pgLZbxeUR4uJvbcuwY3LwVH29I8dhxzJj8DC8xf9hdc/Ji/mwn/+n752eQH+GE +58tc43e4VGHyh+snPDDtjTjlnUaiRVuUb6i5t/gMl6XLz5AWfWBzI3wzWXoma997NAvJ3ZyPjpA7 +ab6Ra3XTtMxdJU/e8ko3j5G76P1YM3UzOzK3K9DrZVJRdrr0JaFHPWwKsHM+0aTdK79jRNbjUebl +eyrehJ7yeDWBn3esk11w7ejv5lf/MAM/hw/FWM0zZwPWLz7dVCTNIla49nqbKkVhYW+Pw9tiSyXW +JRb+JU4W51t88zU3ry2Z69J332Ui1qIfL99gmKNZ+DEvG3ww0c+EMH5dYQRaQNyC81pNK0fsoyjR +VVwnXCa2+872QoohJ086Pun2lonyraqlYLiSzKVQW5WwjcSlUAytEtF5X6O22ewb+4wwZeP7V5sa +eQ5ceTa1ARwy339FbmSH859r1wJ/8fX+ucV0zW/P3y1Ic3Tyn/u3A3NygNJbkKU//cpKhl7ilX7y +tf0fxsRPvjbo0vX3D7aAaMElV+iujKat6eVipPCv5Wu/un5x0E0meAvfZPJf/t31j/cIscrEuJb6 +o8h0F1fL9d0sXNAsTu8LACcs//MTfoiIyny4CkEe390a64j21A8lsrjpmkozueOY1wchnPr5T/9h +PNftKj39GevhHe2Hn1sS9xq0n//DN//l269+++3vfv0fv/njP/zNz3wx/PT//Owl/4kQu+uiLz9+ +fPOyv/3GaOJ+/9W3f//7P3x7W134cI9HvH/L8vAxZXg1OjyIjT6/+AOHLtETssjKJK4BYS0Tmktf +9k3IuUQ6auzHq7c54MpWadwQxlNoiPMHw1M/93Et/H15gOPhKUKoL6pnvl99e+0z7uu5+Oe+7Zf/ +c77tl3//x2//8PBpL5XwtdQDzbnY9vQc/sMX32+jv9jm/yyI8cUG/4Hb+wdu7h+4tX/gxv5fbVv7 +17YYdY9P61/VctGWoukTX/Xyc/lVrxP6hk71N5yIYSEeLQjqTWxmcubOvuYMB+ocbga8RwZwNngY +EupjXnbAfLjWwrcz1/Yw6E2oB1D818X2NTxdfQa1j5YBITj3lyy+7hgPF8YbnQHfeHl4j6aH8osZ +dVTbciP9YUZNkT3MqIWxGZmoIwAkkiK/NLUrSvJ9MMyWbXyh5nFnCQ8WB2bfudZC35suUox6E+oB +FNF3MXKHRdAdH/QyUz7M/nB7ijSd/qDnOr3PGe31i3My6/WwrzVPd0Dg8j99mNHh0MH7jNbWlfu3 +1PTzo9jcnU3z+HpUeH2GwyhVa6S0chcGQgkm97nUZinX+TjmTaj7a0ZdbHNw/ZEQchjUZkqgN91e +spjTXh4ujBe6DfjGy3NaH+fTZtTgjjajcET25RPFjPZLeb6Y0ZP3nvYJnh/FB+ODB92I8cxl38a1 +tyH9kHuQUDibgTD57VrkgtoaD6PehHqCyBsRULGuaSGgQqNaLnxzXuIJQhjTiqe9XxvvdRv1jTnw +ia3X/R43/+Wb4JB0rfAwsS31lxO7s2KNO7ccE0uxOe5L2rTWhXm1eM7kS82KvUtZoJc85hBXIr01 +HgY8It068mAj+6sXAWI1oE3SKDk/3DuEmlB/zPu18T63Ud94d06oQWAeVurAv14O64LVYUh+TWi5 +JvdhQi280ZijSoZaeX4UW/yC+Hx71JU5e7u592/IqlXbTSg0zjVt/eFaS2879OwMemS6v2C+c9Lq +yEIJa0ibKU1K3D6EMat41Pu18VK3Ud+YAM7q9ZeIag1FhhU6xnw5oZb+eDGh1xHCPEUxDMjzo9i8 +8dF1QCHHjqCCMDM7Khsk1ISm6qGXuNbyrXsBIHZGvQn1BD6lEnekXn32Y9RuCeGxysMThFBz6k97 +vzbe6zbqG3PAOTVYUbqfUgzWLTexHiY2tfVyYq+zlB8KyN7nR/HlkqQ+dEq1AcfJQmaVpozhLFCf +IqFPbABKz7WAAWxFQTnqTagn0MQqqTCveZmBA16dk3Ut//LwBCGMiR3zxbXxXrdR35gDn9hiqUVN +6212l51Lhu2ADWBqlrNbzXd7mN2hHMxlb1j+9flBaiFiIjivp71cO0ZoM5O/BuQpfdyEwqhvxy6f +a63u4zpcH0e9CfUAPoDENgvCmMSoNl+ZxnM8QQg1t/6092v1WrdBX08AZ9ZN/ZczO1PHut3w+h5m +9qUDEJY6Ehcrx8xKnD4kaYPeG3FPO2vNAsYdMk1rXWver1xArO18G/Au4q0F2nKxvb7chBiyo0CE +zofuHsKY0+5K41wbL3Qb9Y2X56wiOE/lOj2Wy6k060BTOV6tUYdOOGQkzZhKiZMnD/iMpswZqV5a +I8WR0xL6hCRlUM+1AAcRJBCj3oV8ggASQQzwpVctnFFtlpD+uD9BCGNG8bT3a+O9bqO+MQecUc9r +vFqnZvfb3CKU/jC5fb5aqNdyZtodYNHnF+LssFl/3tFQLLmaJQ/84DIIsedMKNTsll0eLgVKq9WH +MW8y3l5Tmxq1YDXH5TZiN1yWSjR08xBGOgoPer82Xuk26Buv7xObTR8/WFfz0qc2me5goRBLc3o5 +Ao9zasCzqhKzKef/SA1P1nRkjeUB/R5gIUP9O9hbQscKb4eC3a9FpWlv7WHUu9AfQNEDl9oEFK87 +O4PaVCERdX+AEMa0sv70XBuvdR/11QxwVs3If5jV5Qt4WyrnxaweSyxmtdESvw6Qa+PEtEpsVZZd +p9VkluIyWpanObbl0XK7CTWtSPXdrwUod7jbHaPehXwCebwuBt46F82rj2pzBeTq/QlCqHn1p71f +G+91H/X1HHBi4aTeVcDyROimlr1PrJXlvphYVCE6kMIOxucX4qLwoj3pQGxlmduiqmQWxLpIuPbR +5v069zfnvI93l/HWx+H1GICFZRwLoCENeb36avd7hyzmc3hg5Vwar3Mf8/Wrcz6xy7VG3RjYHgjY +pgc0lRa+eZhKA9Px82yzmp8fpcW8a51UKzPlV2nnXUfODvcTQs2llyTerjUTfgXaeevwOULeX06E +i+3V16DDoVFtktryiHI8QQg1ocsd23OpXuo+5qvX99lMHua7b3u3XLf7sPcpLXuOl1OqQsTk0bjn +BzGKfBZxL5VQJ8NOpK1Xmo5BkdAndQqkc661icrJT4MY9AjjATSpEltFlWdyY1SUB3jN9nmCEMak +9vF46e1lz6CvZ4DTOtNZpDrrefLb8aUZXX2+nNGOYiwAXW7oJq/QQtljEQxybaEJhAAxEALzBxRq +QtOD1N0hwslizJDx5nLGKDM7Z2kqk5tM12GknJRuHcKYSTzm/drbW55BX746J7LnM484dtwnfTGP +dqC9mMfLHxZ0ytDYzw9i4MtHDRBI87PHYDdl8XXynusm9JkcFlocD9eirK44/jNGPcJ4AjkKEo+z +tTWqTdJ1OPSHJwihJpT43du1t9cddy3wYg44pQid3A8kVqx7BfvjxJpH+zCxBvgW6HL0UQPL6mIQ +OpDSwh6VhaEJdbnvkaUkmIkyn1aDQ7WHK8HG4JHBM+QRxu1l0Uo8LDXqs6pBLe+5WWsY9w9hzOrq +L669vesZ9fUEfPosYPFlwvn92+nmu/gHJZvf/9hU86P4BySa70/7g9LM/4slmX9BUpusfPD1j19/ +MZh0/umXv/79r759Z7d4h1H+6a9w5eUC/fI/fvGTa3uW6wVb8r9ySwv/Mn/2hL8kbumrnL7Ml7uT +4q8vfpI+/1dp+e0/+Gv+9frXrTz+91d/vd78pe6d28uXTZFR//PLGwQetRBqDsjqM8VtD37x2prK +UG544F0UNBE81taGjM6l2J0dR+n8ngQel1GZhogryq4sLUT92imLq/Svck9Rw7RRcZgCWAmPIVgc +1iRnDzLszU3cbAEDsQYtj2njXZoqbjbz8+YprxVZCYVlm9cls74oD0LwVQ7+eg4/vz3eW1i2X8rx +uxYd5krM/XV81Z35eaogkxbCKMF6smcVAYCCUotFrY6JjlNtye4wUHKPwAzLb2gt4SvMrELv1c6v +a5oiGyHHhlletVL995E0NU7ThPJt+/jKod3qN3qki1hilz64i/bq5T8/rwaLvwzh9COgbN8Btvb0 +h9//0z+9+/emgl5g1xzB8r3hlt+dictSCsgLwsZFavpZBk6mJ4fKLjf3UPaHfcJyWTsv5ANfNtza +hwNl56yaJ4eKmw25WEljtQtJBj1TLZbdOKW5Zy1WL11zIXY9hDzdXgpL5U4tzhLiN5tVJhoYUfBY +iaVAtlZnpRlaq+r+VbjiuIlcxJJgeBzMC2vrMIVeR2dTKJyNSQGtjol9c7b/69sf4bdemWJ/QLPZ +uMtUUGURm7QZJ0Nplb9wTgLi75lmTLnXKRQHuMqaV7iU+8OF3YHjxtCUXY1BOCgslxvI2c1UuojK +RzxF6PwRdW72BgXVTcapVHc/s+NvYGIrbaSQuUEytb05BZ/enhlN2fVhgtoAyviZhtFoRQw64b9o +kSaHqvtbpCgNwSeOyN4UrVlqskLb9npsS3yQUmwFDUny1fSkaEsdAaB1VC0K8sVqxmJTE4KOzoWz +rrBtN1N31QnS+AZpMTmCIKGvUa99wNk5lc+2OjsPudjXT+RxMB4DL2HuIrrCFCZ+x9aVubV33LLh +9ALXlXXz0j5L/PzxC3x6+8Pwi1npg4eIEhPtz7x+8tGy7AJ7XkSL8BkEjjYOFY+pmDeW5wgnbXv5 +0zI6hKxr+c3MCdZrDCfqcaGt/CeuMZwP7tDp+1rletjNnEa7QRp8t7ojymWaZS5NWc3v9LoqDx+q +SH01B5/enprfkpEhCp+HW/SiriJT4pCdD1mZLF/kJ4Jw5H4TPun3Tof04toaLH8a9eX9P735VHpa +K9PdLPwZ18bn42ZOz50FxaKyztdjJS1iLrgGTuGbB0lBFQsQpb5AUk3cUsltMRNmZ9uxSFcQe9jx +X4I6oRXu6d07sRz0qz187F8cKecnxZSryg5bC0I/xUrHJvHUq5f/9PacaLJKhALzOZFdZat2igQE +dso2bf+alxzmPUQ1hShqvK2vcVNgdebYOZ0BX1pXU9ELV2u7af8zS+TiuXTtZElYcVXkwl2WTuTS +TzxPoU/UdygdXxjeHeany1AQPYpZ/y0OLS9hAF8bU/+YrU4hlNWbU/jp7Zk9U57KYCU9EI86ZtfU ++RAx7klOPkTMdlL+klgbW3/BvWNiRztITL2WJVzEZIHJJCvKUfIOnd0cGWHau3hCCrWJqj1eyeF/ +qL1VQWIuZ4kT14CjINKfBNuBcCn4rOogGQGSqpoxUF26uEd40LcYhO/enL9Pb0+rzugd3p3VyArX +aOKkoFhZU6QlTZRCkwbX/KBzoTeVXlppOWdlB8+UrVlO67AMkJJMK6g0pixOZNS26LdYLIsza6oy +t4awCDvbRdqBM2RMMSQ0Pbs8yxawQvs+c/DlUU8aOS4UpjkbIGmG7hOFR31z9j69PQ== + ]]> + <![CDATA[ + qZrtEagMm7Cxw8S/Zon2LWCrNJOKn/1muAWCA7xDvseqqBWwkMt+YUyX2+qCg/xfuZDFtdiOoSD2 +EcA9cosDWhE4HK8xu0lR0MRNZ9wjnTJwxL35sp/enoNjLqpidzkX4TMXAywGt7C31k1ZjSQcUdx7 +6Yjt1EBGlLN3HNyTPoUdtREbTzwymgFVsuK7nPHm21GrUTezcq5gF+4cYB2DtQQf6PbvJN0j43ZH +Wb9xmkxhofegT/NqCj69PTOy145jVG4sDxb5d4LFffOXrr3YMw8NJ/yxTQlwkXMT2WJ54vkCO97F +gSAeRDvaaZzDBnRVZ1Vxpt50vND4kKqzr9B7DZRLFIa6zQzmsTRvpXytURyEFIs003hVZzF64/0/ +vT0tmi8DMIjsD1WCsm+rH+jVQ0K+I0iSYwWFmsMWxg95F3Uec1ir2FtLE0av14gCSGwIaLuXKWZP +C2jCXT1jcrXXs9cMewpYxBgkifMA8mFeMFu3dYVhtqoPUcnob6sy5VdT8OntmdGUda9sxeSA0OCZ +u8pPKaymluQ1CiQ0gsba9i+UsdGXyO3FpoLGckRhQDm8RAeTkyJh7j6Y/f4cESWKh2uUYMufc+S8 +ZmF7LMMRtV3nsa0Rdw5NQdDdsvw7KWqyM6/6DDB3WnCaKLa+mh89xk2WxYYj4NE1E2OrsPzFBH56 +e16lBrvwgHDz44ww6r5GrNUkzyHKzxdz4Aj5cIl41SggxOsskSYYLBN8tkCKALcyGa1UPtMBQ15L +0zWc5d3msztwxCpokwpsBxlpcHgP7v4Dx6mM7ICIuob6kSdejiM9nLPXwyRFKmlwaSh44jKtwSJy +6jem79Pbs3o7dch63fG40qAenUJc1DkRbQ6kVrPTavt3VPwm+4Z84ucFuTDF4nfjLgdvVkx3SY0v +gdMl5pu0lPVspRRuUvcIk+xVMX+BolcmwRqDRlTp80BQswhx5Xm8nIFPb86L5ivHuNtVvvTBCUPz +dLGSaBLW9g/iPLEThw8V+tOESWa0fmzuTJERuEWLubzA3MztPM55wTJtcxTbjpwYKWq2EbrrfBW6 +PaGK4elBl7i0a1YSIw7bT8M3X/7T23Py2weOi+8Uev7r337z/O0/vRl1JiSE6E9L/xlvHLBgCzCb +4mUh+YYNX/U7xp3Bsr0TKdGyNXB4plfsETGYj3OJ1pPhUbP4a5LQwQegAukH6GUmnk9K0KB3oXLN +yK4leAtLCfKyKDdrEUXdBxjdbp8FLGMe7HBiYuTVa1NYoJL8DkHFHFAg4e63TEcPcWutjFvg26PJ +8Ol71r16E7XUEKN1jdDs8My4HsBnyz3qIo9anN7XvJFI3SLGK8VuDahH9q2Lm22x/2XhndEOgyJl +243xXUz0CP2rgwWhXQskr3Tj+hr6fZriLweVkQKdY5ATsQptvUlJAvbEGakHIBxhIiNU+EQ/iA6I +ab4iP2rQ17ETcElYq/jzgn7bHbGkxxpVnhy/tfHGUjK7W/j1RkcBNtpE8UjpOOeN9KeZJbY2ANFu +Ftqp8XtEviENCP2K0Gk+odvDKJlvBCfmHA/x6WxVWFgKMnKsitcPj1F5BCuLlMJctc3NNk+YeQ16 +/GTgxZsuhfvrHaspYrt1Qkqbuwq+RO4Kv5N/0EL4VraqF2CBsmFkijx+2K2eINkRteWsWuJy6/NP +t7ccWVjiVZ2oM+dTbzp8Kj2VewsjuEkKStnp3CFiunK3qYfQO3LAGVNDiomwocDhfVR5pbOWIAEu +Mvb3Fny09whLmm+YiNefs0RMrnhDimsqg4O4EseOWrMev2cxUA7WMPOteqqalKngyPCqLao3/Zwa +GB072ohbeb0sW1K4ddWXKg5723e/EQmf6ZT8tLETi85RNkLZAqy52CGydC5aJiSxrnmctjrJIxA2 +wA4bf9fKil2wk+j+MEqdQPjYKx7WtRcoLQI5G5rCIOj5pCnAMoPlK1rBS/2MyuU3y9SQWmjNixOe +eCyzOMDKZMmsDMMeNUMmbAHLp/7L1Zm9P3ECQC3egQpYmisnxu5oiPHi19kqNI+Lk5caTZQtq6Jw +RcMQofXBtinbSV4ixyMGa+2TtWNBjw+sNDIVubmdyz7JCunzLdpVeEdO0Wy9lViUZFdu8TbDhH9S +uqQLOlTyVmplZAevW7x+6YMoZYto5w77dXp9nCERxhadj65diBC4LPnat0EjRQVyqa0oU1+y6dIg +ol5c93Zh1bfH9D2dEAC/HftXwSCd7Ai1Mn2g6Fpjn8lsk/CHk0r1Eb3htVEVJPbM9aGKTHiMW7ZI +mLQmJIzHgcQoGmT/KfJVBmPJxz2VUZbUWeA+ajn8jiviW9Wf4IkTqLOTYTaOmoV4ZiEiuJEyMxfX +Usmx9tG5wW0XNgmxHeUthox6uQqH7V/KewWUE3ZTaXNVvxn3oDbTEYVBVCT6CEE5zQrW5jmJePtI +WoGZXcm61bLoC/SmFhY4hrSCWMqI44GY58lpdettioNWfMbLDQXNYN2MWBU9wIAj454GcdxYKvJU +euo7VtDktd1xOz5mCq9K1az2qdivh32PYgsUZTJkqti1dJlrMJvM6FJVHKb+8vf50MwtRn8R4Qg6 +rtpYG7ZyOR6omm1sj+76S1XP36HmM5qqEQMEZVAOo5WfKoiw5C4iNdFb5mC7B81epmOMxR4hksYI +iYJiIM8iqpWtYyDrctbRaS1+nkhrq1Jcc8FjrSAzxgu72Cp2i5BYF+AYeRyeP9ESYYkf7dKTwtHt +GzFcyoOmW8tNkaC51T4gl+AdTFOdGkpWqw2bPENsuunLtgQWFmMOacQTWe14DkJ9i8T56k3sEgRG +f3Z7sQrTQuOxce6zeyZ4KLgY+LnRPlZlFJT7BSCcmkYUiXPKSkvMIeD5ra2FpfXwVOhQ4kKU7vph +1bLqH9Vmb9/C9rM7YRrEoFd57+X9I1G4RZHZzjmbNltN2LBM1y/H0riMrz/CHrNuSpzTduCJuH2o +5dqK+uKghZmb6fVWFLu4elpU1d2KZa7lyV4dK3ECoEB3IHKlgMvp54YvUJQTz3Xr2lRFj0jybxO2 +SL7XogI047VeDOS1UsRFzA4sFjRhas6EvHIYJ+RhW7Zt8g6lXp2ZF2M4LiJ9ZJM4WxfeggU0ff2Q +7ja2phnBdrM8Hu+B7qlV0V3Tgyswmr2o7YI9PlmdhzTVWmf6ugfHvb5fIB/7rEMvigY//nuyV5sa +beygExF1U27R+GpGKNjenjUIdi0LE66zahJ/jsVEQkB0S9MAbKZgDMzEVU0ki7YLS64iky41KxYu +1gzf2M6caLGfKc5gt/ca/q2KuJXgJRBQy342Du8xyYQSIWPD8uCx7Pu04AFBbNSKZ9ad5dQPUNTU +ZB0AoG6HMImjYR7CG9iFOkB6FVcTuxTAXPQ2kTM6KsLR4PNTKP8HUVKKI+MMkm+/WSG0Nan5mNVS +tnJKOza4+k0M5IyHWjit9on3CBCNr1V71jROVxIm/edU6s97KnjvjnU6Va4PnKmSBYJ123tzAt3V +uzVPsGu9oxoQyrz9dE8UA+SA9pk2IT4AuMStd0pqCekONB5pRUtIc6AKnxSRdhdWmCWmNvxYR28/ +NuFK7t7p994UA4SeDggxt531Ntm7lFBYldYavdZ4fqGCioMMeS+yHfSddHsG2hYNe93eQw3YWPzU +OVqlgom1qCeI27Xgae393N7tIlu17Jxit29KUa0q1pqlfnSAxfrP2wcmk2z5V5+8Gmkrs/t3DOkM +x8hy3towsrOZZRPYQtfy49GDK9owWldYGWWn952Bo3tRDWgbQkxP9psqyEvxSZOyI7iT/35YUwjm +qIiPMeFynmHgWE7zkbCAwoL0RqGNCKxR1+S1OYv2XH1KwewlY/mB8IsJJlBjTzWdnO5bItzOxzIE +j4oM1DICfTW8MhbwmS4qLPcYEZnPSy1AhN80ztjoaVpvb6A+PRajSmpCUPdUExIqVrPizbLVHMrj +aFESkYmngGXae+zh6fayUrChBNgJysx0NhwpipcADOSoYesm2tX1AuACfYRCo8NmnqQ2BekLD2KV +NWMVbRlHVuT6xF3EgOcOHYgVmxXYCjYnRQuH93zRDJZSCLWYfmKdT4BOrVuPfy0RBmuzyuDBpjUZ +b/UDH3sgCrYYl7Pp86alXmMxS0yfws0lGkMBeHLqTLiCkuLazXtD+O2Twm2GdjnsPykJ/dEW+0pu +ntdw2dXXGOwqo9GOLrPpWjvLfa4uba5evQoZjOD1hbSISKW6IX09gBumVSR4WwFQBGXVPSjtaLTL +XgXvUcbh5hJitWrnJGcTHbDVwwQ5GO9XYhGPzq7ITS9qITRuSou7e1zZdqJ51k9fvBSnklSbvkZn +XLeOqNJhXzD7vGrZh26dwpwz2gy+isSQU2slemcxBhQr3yaIWYHlPUg44CYaiOoPVUP8Qj3osdCW +rhNPXcitZ7wrjIp0sjKiy07Rwp01MI52kk4tEu9S7Y2HO1depJ8WEqSeUTlEB1bsmVkhNVVCuYNe +L5+GkTPyVMWbNOkFLuuB+iBWCjpeszlxUQe/zjw6EiC5nrlHEw7PFZSYP7XeuJZuXtECcAjcDJyc +MnCsGEhhLyOrVjWvPbO4wXSXirxq6voGBguu3FOgTfdRL7+fWzKssvaBlbHV7Ts9gPDzVmSQ1Cl2 +LV3L1gNvJDE/X0r0s79MBSMZ2JPFBKIKaN+Z+6yTXnMmKVQI3Qgm13xZp5fYmQeQtiJgtpmLS3EA +ldRZTJZL2/TfpoxqwfjKWj/EWyfmWPT77M3QPIklKyaSAIkVxzFAV9F0GWKnGkWHPS0jtLDKJFLa +0coaxX9+VNe+tQfSUB12tGpfSPLjidDZTj/XmZTF9YExeXhlYTNMmKtn9s3r0ellW6urt2Ro0EVo +F/pC7RzCpVTpGvOmBDpnNagLl0IL5u813V/70hI0NW6vKEpjwBsp9Lx4nvclVPtkP/N+J1xtQUc3 +RHqG7eNUnmjZ1rWBWeJkD2JdVKW+WQ9l2pDWpg0wJrOFlz8Y+4/KZvg6kQpRttC6XW8l8dfU4T+H +DiAtyeYX+u8PjVBVHMxVUKJik1lpL575peHW6fc5micVKVF54VgA3tEIHZzRvQAmVYsU+KC7i8XW +DjnzSlyBWS7gvePppdnVM3gG9+mO89uOkbA2W2fVl7G1DgbS0UNTT3AQC8kTppiCJWzDXFOUmDox +khd4aRXweMmoKZG+DqtopkcfFtN6qpVq2DW3476qYiLHGrxETRiCpigoxLR/rJqBV545DRalJhKq +5EeFnt3DBV6aEadNFgZkx/ot3r7EYB1jHWqbOfVNiqjt2GkO8zxT0YwwAmBMqnOcHcQY1s3UT0Fv +DLRG0gZIQ1CNGYWwVb0awLDRYvKCDbd3HYCupxFDnmUeBAhOUG9N2EXSmZJQHdFKukSvh3FoECCm +azdOUYUxUmb6cPECVdxgbJH6xN+vJXevpWjA7soKAfOUVZC5CStpHq5RDEW4w3E+gQ== + ]]> + <![CDATA[ + MeGVqOgswa8RzX0PTSnwJjpXEv1FW2Kexk1RbgcUijJWOGr898bRqPW/RXGcUFnhGlwQ/x3bp3pu +wrPAO7AxRe4iUCw0TALcBLyEOzXZM06f+HvKOiO+XlHtKol5IcsQKFoM/IZ+mlSfhh3DK7e839ZD +Vg8sLQAsm6l21FFMlkwsZTVY7uuy0nVhDv6HfZJdhrlmWcFUtm0Fch5EPOrBaPAJn7gRcEdDsy/d +Xi5JRqbeZWsrL5CmaJDtodOm+SkOzM2QHg5EIXLcw8bJM6JeZt4YGKNIijSfywk/k8Arh7K6qygM +L5WEfklCfzBSCb/ZW796DYtqZdMdPFKVay8z6U1TfnQp7MIpazZIOfH4yrQwU2xomqZEg6piRqSP +2i37axEEzZLa3YH5Qya2mHLQdTMTYlUjdm7wUBHOls0vZw2mRI0Q67a7WQ3PCyeSfs9QQk5BGGuD ++glrIJcdvObyRgEsOUXFIsorviTeOxzEDwOLYXroEkIPG1j8Y56mx5cLSRcTZW0uVOXJLX9e40oz +HNLtAYYcT4EdrExsyJ/eHg26C5cnwDQAGhO681QFE5kRdgnsThWgxKbw7J4SJfoWfO8qEBk7hK75 +8Vp1kG+8lHnQL5e9yg0AhC+FW8ZfEbn7NUDpXKprHgDvSEx2KVOKsu5FtEJ8gfMClmpU+tPyy73R +05zsg2WpKBXto/s2ZHQ8k1iQgZtRJU6tYkkseQvLJzReDlO++Tv673O0X7/hnIWFhIvJrm2WsY4r +EQ1+igeoFFdpvsxexO4OJ5UMqATlWsm5j3iDww2SapQXCP7RAjq2TvfW5ihgwRcal884DA3Ji1uX +V1llIXjqEI83AoRPHGAGtbHStzu8kSFvBpgOvuu4aV8DkGc5JENtP1fEmer9DUbXAVlWPW/gqFzY +mETgoGeWDrrobZDcHfRU6Q3+JHsyyXUgt6vKcmsWs9fNdRzpIEjOScUz3mTHcm/BIOWQXJyzZvs9 +cQZKU/AZnTX4XbrQLgxo4cNW9b7GQatF0MXVNHdsAIVzDbNXtApdXaKWI0WJyf4QEP588BfCOteA +gAFLsTgoeg/o98WZTQH3D66nwvKKiEcCA8S2pd2zW5oBV/k349GF6jraTmXDEEPHAQAaMGbJqEbp +gif71NvDmrgHCmuqhW8PCMJUYtSqN1bSlYIA9VMjM9Vn0U6+cSsEO1VN0VMt0sVmp86sUR3ri89S +94HAMN1tH2ZOlSV05g+qAup4geofq6BeKX6fVOWTZrSsRj9QZGsmUQzIESlbH40eLVIhAut14EKn +Pqaoum0oBYy1dFAkrBNP8txQWJKV/1HjTetDOIUA2qsfBMsm3MD4eAg4GWFV1uAmN2EWWGvEAhyE +ETYcpyPutVQ0XQjMgLASlzOjw4DaI9pXZXnPGow+oIcz2fLsQkIg5h1E2I9dqr1qWT9PQMPRivdP +MnQjfIn2fwo+3Z5+ye9QStmuc2PF4gk1n/z3dXwIrjM4eyWg4hZn7OrTJ1yOpaGiGYDRAZasE7QK +b8PGAeaYi7Qih5tcvcTliQOsqpgewR7WpZFYb0vadjVpjqhyWjUQQFNBvkQEoXW4zkn+DFGBU3oG +UdZ8w2/45nGk/RSAw/sb+8k6hGogJtaOoBEDTPYpBd6mNKElZMKbrmU7bRaZuwVjBdNPHKDyuOqi +oQKwRtYKw88OqxhC9dPzNClvX5SoBCjF0ccIfaqpe5+JPs3916PLextB4KgklTuglJEBa5/cNwZN +6lXMHBWeM9KRsqnmgeQNj6JrANV+jDjq7JVCI8oGt2+y6bh3axnik7dpgN5om2xFkRHZLMEpUBJp +ivct8zaR8l9kgFws+DXQCWty0OxHoCIP6DrRR+2x/hCacvqQ+wCUjTKjQbqXapkttGL/KSIOYA+N +Vds+S/S+9z3lzZUWSeG0/w5X9aYbhW7sy2XLee+AlHICbgAF8gHgBFSg1ZjrfUBNLGqzRaUqzNQO +AGxLKHPVFvQaBCAV5y6yxe+oMqCSbEdo8TswEMWsNOBtANf+9vjb1Q9GdfxWPyRuQNsRAtWcbdSF +wirUcKwwgBfeVsMt3jB8BDZZxrZos3jsf4EyRk2qWf5k32zsAyBz1wz9bdR/Nal+ahIs6l8qefNX +Qyrl+HxspW5TScYI9Mxz8M30PL9ramFq5h1D3ql/TdxaHL+M6M2piDLMh5YIVQoECLDp3ivWoELq +8K6PDeBY0ulPCxYQM3HTeu+O5mKGab1o1purdXcY3Kz0ZKMLuxyppiLMyXrS9x4EqWrDtpR+zTIg +7FHXOuFDfYLhdhFjlYGrguHKoKxbUHZlpO8B6qx8M4LQkJnMAfhqIicUhmuGBWC5HqKnWC+L3BWy +fxAKO5AFNLKvGhWAAMsAQQM46RD4ggYAEIICEHn9Dm4+FH019EcRLIuJCvs5Eh0mBKWOCz0MA1BU +5D+zvG0sYMFPSmwWcxKPsE8CqPYNf8Xor+ldsjjiXg6qsgWeg0axdiGl1jwIqOlrxTZmD7QUI7LW +YiA1DcBVZV2J++0JAOmHWBWIeAMnoe/y7HCrzXYJUQEGWA518FAFFGY7hJs5wawyFtNi17fc5xN6 +fxXA9KdSjZ0ttrfjtVxIY9Vc6nKbAoGYjFkz4C/yGJMqqYFU2aSbAmuL/77F8ZwPfMbyCjoGb/iV +Lbu2n15wXK27HQhV1bkCHmTxhorbqzuuXU+v/MMQ1xyEjsvcM5Ii9gGnGBmhw544QFf0fddA6uih +bKs2fVQ2e7ey0nQQhIeeU10wDJg2ZJeTTN1hgXKrwP2jCVBxQ3Hf3PewShuKoMVICjfRRN4yKCsy +KF1GIHLN5Fk4HeEy+R083nxAaMV7DcA6U8EtyuxkGaubzOsU+pPTa3tLArbQA3/+jQQeT2er6HoN +Juctrn3PzVtghtkCmkLPSm4zHGgFilOJYHlyVvWQJGQpyXafLbLbQRMZHGUW9JfdyMIpZMeJo5sf +VnC8La2NGYrIcDRRtiN8zIwM5HA/W4lJsS+Mk0eb4lmYIi0BvobwRMaiIrfbVHYffGEjajECd42E +bc/hs82T3C1aAwSWIYo9NSOR7q1ELN4CtBB39U/IIwkK1FTgdMv2KmJy2aGKrjiSRgzIpQdrnEA/ +SVQ9jk1Refkq+6BjIucjKFEVBi07hpDZ0qYibDjhygwq5W82ebSkUBbeOHqKsn1bDGyHlLWFG5nE +vriYZ3HvhKrO3ugkkXK7IZsPRdBusgEqwx3rwC2aSF1smR2CwXYrryotwEUkBNk3bEJncWxUksUT +1BpkDkHv56FsoDApGcx1EgT+xF8vxuF6nEH2SVmb370Ml7fnS3XPRMbzs1VsDzvEJiDrUYPFr4Ev +xbXtIVi2iEgXGfMKGBRN+c1D0IVRRxa1wZCe6ObLFO4DtYA277wDK6ozovr0zy4CX0VXCeN6uP3w +J460vlcyYPPr6VlJYW96SIF7zD/qWAJV0EVtIFwRdkTjwbKmfs9eDhavXPM8vw5Go9cJVMIga2ZT +xMZJhRPP5SlCFyTGi9ioVxX53dIZDBi+y5xnC+dPzjPy4vp8XcXloDXU4yevb3UCRJU33oBBJfZP +c9Afr82TcVzWN7lQQTisCT0A4MQUKwEO4C1kOiuRjFYQbtR62gaqaq+dDoHhHdvLEpgMQFTVF+zz +FEe00OrFkxFOOKHNPkpSsv2Au/PepyWcDCY7yKISw8tZXVlzYSVvGrMcBta1h43roPJYFLYXqqsH +iiYpta+2rusARJHxZzB9yTZE2pl2yHImKxeS0cxCiXOfFPWBd3C/3q+dJ/e4YxvMW4TakvBV/WYL +S2zAmzq4NyN9tW5AjrUiS7KiSGA4GaUL6Y7c4vamPZY4RoC6izQ3UUfTOYv8Wi0kI3GKidHMbo/4 +xBxAkzywVGxB3CyrW/QGSjMaK3HQ462IXZaoVAYiQWjMIL5YAoLDgdPjs54f+7yKT0MlzcVT8hJO +4ThGEIFNo/+aitKKD4M5YVvkO+ZPQcrsbAD6vdCkKQrFAOyRbaDs21aZLoQrCvVHAKSyCnKcAnMz +pKjqZWRBGkO39SyB4ecL0BPn9x4S84hyC2HAAqrydIgOMteqilaciZuBU9FXqSzBo6l9nhiDrh0n +r6qICqK0vYrRjlwBiXSbT0wUE2RuWckZzLWkiUBDoSD/VVK0ez5ET7Daot0eTYvbrS7z1kV9R6D9 +ZApvYoujLAEDlMItnrG6B1Qei+VNXU8VFNSWdK2wj6eCXXhszHQABYqgRGNEI2uiZsth7qikDQd0 +JgXNTLuVCpc19PbuIWOtKUjUHNjlFmtb8XtlJPed00tosuUNXVzIhOr200U4gRlAxMjSisvcEHo1 +hEVOUL7zhO3zUCua+N4aHYndz7at2kkh3PbEAQQTsmuTMBHEj+DsOAM0Gvy3+SsRPr81i8oq/wQq +LGhOhIRMt1LfnQNokQ6jUQlH4CR/QJyp3AsiU08vBigKJyCpTVCUAeC2yB6mVEX4gUgfl6yk1I6k +eguzvZ+Wd7UrUZ7GocvVOboOM++xD9ZRy1khYSG3NYBaQM37IqhbhUuZwU9LfwdN5DxItaTwFZJ6 +Lao6eeqHfwq6CxKAT4cGPzFSGkYm4q8uU6JxyETE7+lMWKw70DqJa8vzv1TYiTT5bmLtMwCtqWhw +7WCHxYiQwGI3tomqUsfDL++D1kP4wZia7dJW4loSoRqjahaEQTjj7pTcyrXPJrK8ILFbjH24MBhH +WOxpuAQrAdEAJ9QD6g0Gq4PEr4xgLKHV1B39fJL9Yf0q2xr12qakS1YEPEUGftwpX8Rt0RQO8QEm +hSA2460YeWjOwxvpciXrVZ5/I+yoDirloF2UnKPtw1Gph2VTZr7tZg1l4d5A7aZ6buTDO7tibWav +5fMHUFwue3H0eyQRiN7ObihEunwsclsE2mAQ6Wr3WmwDbEkIem8Gi1+HMoRxUXRUnOIk9WINLzas +M4RahVFtBXEjuCQoR07wpUXFtQlp/Bvwv8fPGcUGSXTWrdqSUz1nEKWGo1lzPQkX9Qe2wHASYEGK +KEjwnPFDGidqtpDw95ShWZWi3OjkfocmS6IBYW5wk4dEKXumjGTivp/e3nzSboPT+x4Z884aEDP7 +grOETLsuJsOAheS9tA2e0BSVhso4kkc1njjAFN69CzFTlZ5EZUFVL+MTlynmZSjlz8j0Y3asynAX +D5fl0aruhNYDkXPrOnR0YW6qLmtkMprycWDLKN+HB3k0xefy53HA2IgkNIEB1UMSSjir3KwEtGnu +gPFm19d8SLq024M3kXEOAHkVY4vVSu0IVHE+EO/zVRK7L8emnpFwX6c5zjzqJ0eM0qh75hlARdD9 +fKYcC7WdBZEDLmVly/ngPbiliTi063YwOKsHYw5Fn29kZUbN4swQm03RXaiASA7CpZU/3Hq553V7 +/2itEYxXKXZkCu9wpYidJW//pXz9aurdom4IIAypStiPJiHJdA1OdwhzsmB0dhbVJQ== + ]]> + <![CDATA[ + aAujBIueFoXMCs379s1UX2ucj5V02oG7h/OSVMFtwhWMP0mV4aCp8AVkPCqerDAhV6Cl+SKFBXCE +dgArM0ws0pngsQBKqgkHQMwDEEVLSftFJn8TlxvAYzmlskHEo7lq4WM1Pzc/fSGxv24NS8pGdfMI +6J+iJ8jOJLCKk9FoAIYwbebUjVSkjyasdAcsp+lMCiB1CTbdpPy2gTG3ICIMXsylit/b6kZ6Nzrt +FAG8jItjTzVwjqS5sMyH9dcQEO2G2ppuzxuxiph/IwVhKesUaFaWwRixT0oHdUeG19kPdd7y6MM9 +kb68jsNEwOLIkGPPltkV2IMp6xEdY5tRnCjrnSA7viyRAD2In7bI6BpYibJqaDR9N9YcDyyKiaS0 +Wwx3MTkfhbhW87d4Zc1R8tQZ0MD8ieB1ymw2WEm0ExSPyfQOB0rZe71NAyyEJfuJnjuEJ2NbwLsK +YeSFrNR8ijOFSYSsBhW+AIbINLwOzOAZYp7ylGvnqDuL3YFJMduM5aSh3WuxlbqSEr4lXmuL4RJC +x80YAo7tLu2huC/vxMWZDrHhotoUPsARVjiKgzRE7CLZA8v6NeGxti1ZMZnl+oL1ZEzNCdEFi00n +I+FNgpMqV8ZJXyrVwhKLQNFJYjn/XE/KlrQ/poM8fumoiUwsFMFAzuVC1XoWALLzk2p45aGMrQAO +M2pm7UoivOYh3kUit4u6SbzJOcrLwAIZn1AUcct7IsUnJMppe0UE32BOomF3Palssmzl+xrISgMW +kXdhtdKQL4e6JRMhAuM8iGPuDd7okD8Kl1hDUmCJm9eRPXGAmRcNhGgtmm6GfJAB1XA7az23l71X +ojwvJ2GBo/ICu5IJG9oX5+0LrYYg6WbjNQjxsV0FyOEopyWgl7fK8R01Kb9/nIOh7qM76GyGQ8T0 +BuQTQig2yqZli22HFr5/K7XOnL2FE+yUn+shZ9/Adz78T0+TTQPdzBdJ+3HyXohLPUfOOYIKRNSk +8Ga6mt9AFv74tcGkXYe0E5znU5BM+PUB1KBsTLmsw+g9BJNBiK8qR0tIkK0MMgWhxCwCDbWditrt +pEjwnSNtrerT5sgHF6YqWsReW7kNEDiXWVX9Gk2z0GjPZYKJWPQi6pkbC7bgOq44i7Q5m3CJyzkf +XBZWMqRMQ3Rh6iFUSOLkYrvqWZG/0q8VZ3lknwhOIwFiLMDLIEP3h4u8K2EDXRBcZFMZpegna1VZ +ew4Abp2npDcn7QMdJSh8bHwpUXVUz6F4hjGmr962kfizkBJRe8Pd4gWU+GsnyuGd/eS6By1+Zb96 +KBwP4p86bWgXy3FG6rVKXLqyzIqX1uBkSi3S6fVOytBiAorrXArHkspiSXOLhnLF/dYnfUI6KuVk +OVsEFsvhNWkRUSqeJI/U+1QnVfEHYQY6YzpAeXCy0+K0PBD7KxNmXyO+gRdXYRPOFBnl0RWpkpG9 +UvCtIUkQ2ecR0ZdZSUtQAr5QnQRV2d8RT9C9HRmEjrU8fYiQqBYHauACkb2Oc2N0JZpVBFQPJKQE +fqu6BxnZcxZcVMcccwZ6zFYjIifMnE36gJgB5u/LwS4VQAn8u6zoH0j4QrnTAhnajF+QXiWwqkxe +F+dPcCGx4ZsISM2fgCa6TaIGLQd2VGL92qMLE2nZF2rQwiAJLk2xpGpUuQviUtzpeNLvg20tlG1W +WXaR4+gF8QpT3uY+e5jFH7Ur8y+u2ar+phCGUg1YNsRS63WRPYNtGF1XkGcLJ6r074yGwykyzv2D +nt4MicnQR7AEpGh/wXyhsvZlq6gnZ92pMt/cWdSORD5NA1aK6Pa5BdnxWEr666jqgYsHR3V0uxGl +hDegUJgmrQMQoP7qJMmArOigigMUoAEiV1pUVUVXCj+tWwABuH7aIdS45/ztKIvkumhCGlhIXcYP +3Zxp80kZ/3hSRgjBbqH330EKwESFRZDzvt2c3UeghflrkmfMiFqgTcZk9mUKEOw9kYU7SupJcDoi +H17VqPQHvMPeXo+vWkdCMVwoiN06rRpWRPmW+yF6AuXrbnX5K471GYFbgQiARZF/5M50hI6TeAH2 +CA7enQMw0ISPPKzS+xC6HArwPQWfRoOPLcRCVjC6iZVxCgij0ke0dlXzmHxkjBpu5w5Tql6RbHLF +ufBwJO42lOoXKXK6sUKbIZJlLavNbmftQlS/urB31eSWEV20OokiYW2LUbUHUULygKQLxZqRPGTx +iQNoT+3TPaRHjmb7Un0ULq+1jwGWArLiVQbtuZpHJRaK4QkS8aHX18/xCt6EwMm6h9pXkhV8BtX3 +7pF4mQeRPdnNylfKaf/Rigghs6qSj3A4LiZ+X+RXkPwGD+VFBUDDcf33QOYYDV+9cTsEBXzVFLZA +VLfzBuwKEthtRZj6UD7m2kjRQISB4n5gNC2Sot3BZjFAEMUELIJMq+gLVnT7G3BS9i+wEkvpR5XV +IbUkY51JMpinUtTRmkLgcH8rpZVrFLX2oBo23zMOkDbTwVsIONcPXukgB1m94sKDe0Yo84kDsC5N +9XbvHXCQlcEeQjwVVcsNr0APwEFTryYAvVyY9a2WlnW51W/3QkJOb0KmA7ipe3OJHFFXdAIp+Mj0 +lnFrqxJJXZ118aTtMMXkaHnXPL6mZH/rkZBtCmUe8H/gnbJwr92pj56Yaa/Mx7RDQJMijtA8o0Bh +uA/Al0eqnqy2NTqDWICVyNEa/UYsZdGifHlElnEHHLF45suF2hVsdE1hF3TytGtbOyobq3ecoJDb +sipCeWOrtsVcVZpnwAA2jGhei0NhVlL7Rjcgawd9e+L3KbrZlxoR6h15WvXwXVHaSRhtYAV43FZV +gEGYRTcwDzGAFFP1XjwKkd/djyxigOOqqMOyCVUr306W8VgRwUKJuDu7OFRFPqM9Cr6VSg/uxAQl +4DkorJNdTh/SAQzq2xisrBigaQCVJlpFKO2gcopTZ/TtLvfa7BnlMiX6SK158wuj4nSGuqj3TPFk +ttPDgSXae6i8VqppzWBxrs5XEL9PCsMEOcKptGgeM3Cht8P1gM0+uX4xFjTFIyFMLQzpouTJ0e5t +H7CB1FgPOhRLZvUqPRbF+StqmIAXiWS/5z9grMwo5A+Ua/Q36Tc4a1QGObuBAEbsBWCBbK5sI2SI +5JFaORrEJNLFQD7IZtPXqjcEgaregQDQ70++s4bOmdFKzcLrSS3FgzalhnKZH0SthlS/gPlNzXSK +mqbsqG5EIavKfPppUpzDkNnRTAKZ5SXDkcjVk1eF7xLlrekGyEuRLVdX6eDW9oxeCdKDfcv3Bkh4 +nty4zJuploHAOqz4qmsesATzJ1gY8bFUnNZtLWYKpwyZAJs01Teb8SN9Bf6TrA2wVd57VPONHwZN +ukWlMpRTlL4rYUnahe5b3IG/Jo2Guuoea7fyQmQ7D86gEi7/zRMHYCQR9Clk86lSN2rW5RPlVDhe +9R5PUOT1ogXxVFaV9QrAvw0JZUomb+n7pCXk5xB6nyeBE7isbdSDg5jRqbdHj4qV5SQ6/EwUF0oW +H2vc2sR41NEAUeOWsV+qhhfKFw2d1Q1E/CD5A9sGWQo9nwJxzxSiM06QAbAUG/17gjVAjTvMvgx6 +l6Rz1HSJuCQ2m85ZVkysd3PHt2rOZffEfD9ZW1aNJlen7L9GqtkS6B6KWcWplIUXIJtBUarTEvCM +GtmXIBTRgAXM311WVRNgwcRTDRZSj2tZf2CPt8eBzCC4hyY8NSZAzTymuBFtrpnisLxqjwXgHNNI +AB8dambvYA6+qR9SVWGfZZtFkNMirdzvmJ3hPXc8i876BWM88Lx8V2kbDnK23eh3koel0L2J0wyO +o8kcejmtrkdThfxpMwZzlD9PB+XKSO48DEGA5Hli/hYNA6kdy9abh5Dee4yD2W5joHnnAbbJSe3e +b1xxTPoohivoKaoAPUMyo/MU0hnBJZDuBLdiPhj+hT3/xvPGavFLEb283mp48zel6zWB48OOXOGh +M+BLnZwoZOkUKDPm+1BNv5JkaKj23rPKbvdPWknK1hMKNQ8Zql1b1WOGXwXCTAgJ+o4oWU0+ihlA +dQjdNAE1TQ5hIplEn7f2AowPT3SGjEvzJh+FSjuBNhAGBuGuGKBxt0Y7k8KeVkjtnx4rQgvkWxGr +paU99WanJD+2CX2xostJ0bRKBxdvKRjJ7qp0/4j+EKL5aF7n5x+QfezbI0cCyyitmD/asRC4bKbX +SiqvVush9qPT79nOw9T1jgJ9rso15M9D6DkuU/anxD2zfsGJTlSejUZhztzSlCqefP7tYXOtXxZW +2Q7fLZLV7EgVgTITFjbESqfLq4lVXHZrJ7Dlu6ZDu7vCjk6ej/R4drhYKRZgWkJhJm8D5rIheN24 +8YM7cT5uPqIXkBCz6eR4V0DkkwdW9fRCgyfHMPn+38F5kFXGPBW4Sl5tLf2x3L8KLjKoj6m8A1Id +LlSKsTqRfKT6mXNqhyB93JCQI0WLicd8OhP1ZpmZo17zSdTbv04jmTPS52sikaPP9/Q8Ipx07JLn +YZ8p5pdHU6iIhgazQ0Rsh7Krpuzqic4VchmlMMrhZHc6i3K1zGakZ15uCECkJLPykCLYzAS8AmXS +RVrIMH452BuELKYSWy3F0XWSqypkcDvMZbiPIgM9sl0kjAFloZ6UCSMIg/FtrNFPZODk0GR+qhzO +XdUkt1TkfO0kp+BAdsUhV1HPRi0HC1Oy72sL1qh+40xaqqTytP2SV9RVQd3EA1RErjg94C6fqkci +PsDqNcLDzVFCNMrfvQxL9Buuf4ryanhHFXcJBCCdAYon9Zqccm9kBwqRFi1DCRXd4hqB0H+/2MUr +fr8Edg2XINA0C2y/wXjYpKLhKD7JKU+0nVU3dmw0GOlZU6oIijl/PVxaRrZgPLM/3QwEbRYjBczs +pOP8RpgYZc2Tjdj9Wf2hpnP7+TpnCchs/sWYm3EJmy2jr0EKjKOH9ezEpYtuuM8tQ6LFOZbVMNIb +9RAjW07/GwFcjTWy3dksMsHHgZs8cXmDqgXNPumyTGcGbA49LQuhZEu1/zmCLEl02Z777jydQHen +vPDRPWpOaznECBNFDdI99rO7MmtDbIkWON9Rc8pAWwYt5Zua8/OtTv7tX7LViSGuoN9NMzSq+UX9 +n6/FeKl5n3Raf8CRNwKvWsQQWOHNmXTFuvaBglQedBZltNDeEz8PIU5wGcbp5cefqxceUBT8OAcU +aaX1jgoFGV1SZbx447ZXUnkuWjA9IKFV5LeDMCCfMtlFOlrvvBs836qeLL7Sn5h3FBS/OE0uhUvH +SIpkprKE2VMR+r3iu+l0PkfbJA8rSJCcgsDiD9ELF40OOpVYMIKP25wExXmoSwS/+zlYCZrAtAal +OF/0ZCObd9/xp6z5kEnz/vtGhV8j85l8cl14jCfAcDQAGT6TEHLIgwzZTnOr8pSUbbYJI9a4I6oC +FuhIkJxjna3NUDTIeHH22nOlPcSwmiM4DUtMkaXhFDRe+Fm4UJB21gB0dOxmos3dOg== + ]]> + <![CDATA[ + bVkE6zJh+cotcYrW2ao5aWrHPINksp6TdQTAo/pbR7yXdVj1NA9vNzCEKNXtaK+n5qX3iHcd/Gqd +Co0pCFwi2GFOB8Ol2Sk+I1TAbEx2/gAXqqQ1eViAB07RvkShuU5XnZnLsyG8NtgTo6PzFMMdemuf +05mReETEc9DxkjiNCWcX3hjSTsRY3dDApraagnsR2rpsU8XrSNFnj7fi90U4i1WjwMViSO6XGTS9 +nDiy4PIgjgvjymEis+k0MA+LDnxA0bCy2fm1nWCDF0A7Cr7FF9jsxzmbmpmiJNtDaLpOyAkGBk0s +eqN8ozME+4wfAT0iQDu6eUWFqRUsyNfPYUmMILLJ9RYAQam3bATPcq4s68j7UxVS5LUSfFlMDawb +IS3aMTlCDtmXJaAvbYQV9fOvz7BPd2cnG6e9PBw/Bc3LsSDl1iE4gqd0eZOzZ52NbrbZfiYfHyjm +h048krQZIjPaGpe6zzHoEDskxkZAH3UyRo+mGm69zcUI2Jx6JW/FG3E08pksV5YlVPPm6dypPoD5 +vjJFRYmwlXZzTlcdjEzoJ0+GuhJcEUPZp/0HUa5rH6aJqHtGYXgcgfbOnRF3gg6BB0p6fdn3O2jQ +YL6rSjsanVgtGmtxvWt3FKgV/Z5lf2ve2VqGSC5t2NYEPlHFx/K4AuOKHgO08zKKm4KpoonH/T3B +HyvObFFl9DBtgo/cTleWl5lTWMU1wdAkFvCWkCA15Bb6OYdFKsvGmr7dV9I5fMMeECWVPEMs7EIr +ikwE+KN4wTqDIF1qhc2PwWgu7EUOjKqvJCorptyy2iTDvVbV9c29T2FdFDEnosqeiO5yWM5XEMIb +3CKdU1RdXovjonha5MCoiuZ1KN5tvmSN1Puphs53Tlll7cw0i2P4npypp0h8yuJV46HbwbTCELGT +kRmXddPhJm6LK5vMh7hXVT1k5HyCNw9KsJ0B+LZ2TkeJNdEv68Htl6PVDvMacnncsDf0RA5S0ya9 +5hWpHBQJYiWt2NcexalbrMxiWp2O1XzPPERjHL1F0mj4l7+k6PESXTjcFJ31QNDOMVaBdNIWYLyQ +Upex5Gmy3RltVmcuM+FBsC3BmibNK+rQKPvzjifoaDfl/KZxOwUZMpzqv4DqqsiCkOoYh6Bjei1l +Y7AAHYL0b5IWoJfcMTvVmQRIp31880Ssbk+Dyz762Iot6gycXuzy5hHGQ9Bcveh7ORD480PQ8H6m +AcbUKThVAWCrzoK7KsLR6TpUz+o1LFzXUZfRNAWLDXee6EvSlF0EBPiJp6D9ElOEs9dpZyFXqHNQ +XLPLKet0OCqZuKZw4QQ2224ouYarr8K34YRpPBs9ogijswoDTGPcXmsHimoL0mAmvABT+zZAZWsA +sDZ2mrJIBWgAWbiHRh9kYprurqMwmniYmopidROjm5Mbw0PnLnNMuDa6i7EczUa9W4OnBnuwvYmB +WSdzAay9BGiVVu90349nKT9rFQqVOwgGR+A6mV4zYQC4ADIsNG4yWeRRehUBoMOjxAaCZi/t2zGs +LP2KQKGFiYvS8YnwIQB5wnE2k/2JSoQbbgvEjnPYsSt3d7qqQNGEHjZ3saq/t4qwcA4Hq3E8wJ3/ ++IGyhx4GuHci8SlkYYp0vh3UW5HCmXq+HaVKZ6gLyI7ImFm3NZoONcZtEMpSoFnhuu10wS5MEYOj +Q36Lfq5T5eqtXRb3BamxcRDHrtAErKHAi63J2c85ynofOxBoiaC3SWdUtc103NFJRRj8o4AfBU6g +n+4iLD5f0ZsYbhcNLDKwRKya6IOi8Mfif4p30BL01KH5BqK3k4+O2DpItXzjdU/szbECxWwuX7q5 +sjpvqhTY6ZDV5q07l4jYIAwzxHYAD0wj++oieGOkeN4o006GvCBY+Yn6hyTks0baEO10h4rfWzAC +B5jAOuHpFOK2ALP+UjmxKs+78jw4BZsqz3M5h+Dy5WtwD3ZwfcjQEk+Dsl/PGxuhgnpDILLMlgUt +KsrNbSR0pp/KnldnmI7BS4PFadjR/vkdOydboSraQXe2fHY1SCvb1OgqzHc1VbOsaAcP7RCBMUHr +dpQIyXWURTvo/nTVq3vjHpljS4mMGgMYci0YJyZZ/cCSf/qEkB52svaTZipZ8usNCGjKyqGUs8Sm +O/7HLG7c+hQwhjXLId9C9RA/ZlGMfKmNN3kYhmpql5ckTfKMRRLVU9CCRmA10BpjLSAWEoEKSLh9 +4kKSkUf8rV+qfiBJHKRegs9mGNFiCcvLc2sI6czoj81rq0K9Hv2Qvrk9+1T8wxSSOjR0YdNMafYa +/X27DP9+q+bsLlNRvZXxbVmDCJ64UNugeBIpAgKsyq+u+WjdOAmzIQ32UjXYjUAg3arBWAAPfVpU +zsUkqmncrhKxFrEzxNnCjqFx0AJ0jMqOzjRW8He+3D+fz3p8+Zdt8O416NzoyntsswVwdHZucCCc +FAmzx39mRlf9Liw+1uWuOJcpYEvzMAZW5dTqPGB/VtvOejzuKuaHWcVTjcoUz0nala3dKr4YtauB +kEH5TxMfiooQq3zmOQ5BJArR3VYBwiiLJ56I/zvGCZ2OyOhRg07BkB8OijU2KZX8LUWOAe6juT6V +KYfvmG97xDWMpT37UNE8ub6QtEwqI/aWe9iN/aT2Fn2mKpfTCaQzbd3M0yapP5KUqZJHikd3j0b4 +FBKrbfcXA3lWwrJ4Ca42CRGRFpVrMvblBldyZaPh7/GYrQxdYS9FAponmyl0N3Ld4r7qBQk8oyhV +sJ+y2ohE58spw2CxToi2euva5DeKUpZioQtIlmXbFMlEsJxW6RCjCMA0n7gH1tJhu0aTsScSKQtr +y9phcKQ4AfonRgx4VhscbETmwctQba3WKDZ43IGK2voG9n8Uc0+5h20tIp/UtIf3B1HXTEtXPyt1 +U+SId3UBZH9O5M+ZaTcLme16hjPGylYXI1KLUgFElRSLR9tPWmWYvtnuDL2DCKWpj0xNavBMHQ5a +YpMhSi1cMqoB9VlflHnbIUqCH/C5Cw8QxZJwwJmrX9Eovol6Ht3kTvk92XCSc3994vmiTZrPJs3q +jJU9o/SQPLd8il7dOcYriXNIrotq4akI1BpdTblPp5sUtVqLgI7VCI6Dk8zFnNU83QPTlWQ+2xpD +R8DZnS8z8VNR9l6BlRpByB2AEktDdGHEb3Hkqo4E7jmr3RZX/r634EJfQWECWJe86qn3HWG7VhV7 +T2cp4auiN7W2bs89ohphnPFIWGy85wuS6T2jDZqiA0PHX74AzB7uZ35VKx/qcv540K1yoxde6qgB +LCYbhpmjx5wX2uQJEfWw997avLnsOIBt15p5trR5b7jf7cRfz3oDkndZlDDFKzA4mqKPo/nE0RsK +vRVl4LJ+Zo4IGiNl3AVyThEtaEEeNqOP5g5X0zy7G8W3o6omzWJfBpH3u7UBm7dOaGk3pVjo1yNH +FtTz3scTkxiuGonj5wNLPkMFplPV3XmxUAVY2r5uBgRniv1it/ot+m4PfnSxNmXvOB05F67AHBy0 +aDlQeHiH23M8/XKK5UAslHXOk4LSam+9thC9N0mZPJQ1BJGgukgeSKFA8Jz9LOc9Wrl39o+wO0XA +GpGp2fQAM8JVrEgoIkSD0IkVYafUMwCxeri26VriD4HvkvtdpNcOLe6pw7XdJpCJBZtko+NL0m8k +wrh6f2mZkEc3ZXGxH17GElytpxMzSn5EcW6QBPqYOfQFMniumtNhvX61BYESJfIz43/crIfmrDi2 +65mBMaU3iiBf92RYUVsfnxY1Zyv7zqZe6Pqp56BXWXJbqI8w0COTxyhQPNrssmEHTzxoJo+r4rCf +oUGY47eMcD9zJaRNUJsAlTKjUKRFuO/FDHzeo3n6C3o0vyAWNzsWF5DcX38x3v30r9798v+6/vQn +X/5NTl//29/9+uf/4/lXv/8t//urb3/zj7+j5Kf/7ttv/vBX1y+/vP7/y//2xZ+u//2rP13//h8e +Yb7p3f9x/cv/c4n+27v27m/f/ef/O737tf3k766//QbBh6pFBB75a3NjFQBCqDyfLGZDJGbhamiF +mZoN/jekObHjQNnZCTXB4v5I8e7M3YmF0mpsmlApCL+7kGkDs93MgvBhd1RXJrEsmTDw40LFJPls +i4S/ivqpLGErpIFrCyPJl38t0txbWda5/YxGoQOoio+K3ywlU4Kid4Rz04MQYx67g4E+BYAIYjNV +ItbUddNFjItgWuiHNYcHKKOnbIp9jusk+sj46GlLulTLV1RbhEbWAfBVMqN7NkSZRjJkLnKhvWdS +cNMZAsM+nQGvtDdfZh3A0gk5KCOwog5nBVMWrqSGdq9G969ScPCR9VosccW+j5IpMrSaMkrz8UlB +ohxNuYOVwbhUW+RamwpmlA5YauLhCk4I4RkxyuwI948UE59msU9htM0fKsLUso8KlpTbadkpPJ4U +p2j7RdkaKggljEBkilq47Hm8JyrOrudSW/GNMANnUKwUZrP5QyWvLdHPr7OX9h9qVj5KHU+6efOQ +FYzE0MPeoUxlz5D/NPAOXl6Bsq0TPaHvNrRlUfRfFB608ognmc9T3xXVth/DIS5bZ19RskpFM0kE +iTj7t7Ld4wBhuuIU5uCUoFEZgwtrpoh6qa9ncrSkXEJB4YKlFJbSVNmTKmoN+SmOUzA7yC+5sQSz +7A7tjiZDMmLeNW+n63MBT6u43bUwmLAHZuKjbM2qAG3wcCXxvA4PKjB6skT+O1qEirLyJYcoGGRf +LAebruTpRO6pgsgaqeF8orSXO+LfC1LmhfI9zAkbyV1OEq2CM6x0Gaap3eKk8gOFIy+q0lnkK3U/ +GJwubsOpFzZCa0QvV5mb4MyrW3bZ3CLN04Iph/IBfRXn5FYGb9NHRsauDU5DvNWm0FpaWWzPgkpb +orNxxRxInp1+k2oj6peMHJtTEFmQdQuhJeXAAMb3UsFF4pfzWCriZcAIwsb4LQBt/H1gVIJK/o5H +MLjLFvBfOeMqhsNotrmmY6KfmF26nHXhA/JWcoehgMVqcac0DcSAuOWsJLIUBdVt0I9fPGaXrOaq +RNNYL58yl5Y0eNlSh+pRvqPSsTmVrB/qmaWWzT8mjv+Ro5FtTZM5Z1TqPTFl5b9HF5fJqbZaz9zC +AlrRCbUJvMTuNRB6dm6XA0zGAL6EoCyTmGWv+4qPbquq9HSn2wLG3wCYZpGPAKQUtc0dswjkIuuJ +Bf9K5V0PRJIbWMn+Xj3aGllin4zNI7oedg8SUFhF53/625mYvBvzkPjaKp3kPEgezzJUKVvtEEr4 +xMyOWCa97cRHSnn4mFtccrSvLotC9kvCvJSqbgaWeNR0rS4uB7JvZmTbxfa1Y7pR5em8XqOdVTBA +M4OGCsqcJp7paCY6h9Kp4LKCcNVDr91HYkcHbMOPWp3VWcTsgq42yR59sh5cCGrxSstqereuEqzZ +WvQmZim6F9d6b6cRRJu5sJLYhCC+eKIqchWJcS0W+JFiT2pDfPrpunVqwjql9fDc3g== + ]]> + <![CDATA[ + 3mxp11jr3Zx5Mw9VQUFW7wgy7p1zcZBCiKNLqqg3b6kxT0vW6WWtEALIwwGqP+m6q8jtivFyrJMX +2um9Lv99uJjdJiDEmumG6NohBFVnN2bw0W4ZdPip3cjRBVu2d8gSpqbn8qiWDYCN8MS0TkJcxh4A +rW4/MuKLMlc8LVOfdlDNeIUW0CqvEsfvLXOnk45PkNx1YcQZTk4H2puHJ9q+QISYvs5ZWCAm7YpX +m/OsS4lKAC8oXCy8VC89fj/Qti6bMXYd6R8p3QMEKLmL6cWbfeLDZqt5lEXgMzLdbFQMeg8XBtAh +McVqv1WnH2xoLIrMphSKIXf0pkPdW5ahBGb07GKlBTdZ1P3zkX0E5IWbV0I/y4LzQ97ELBxGBIyz +WqNW0UJdSRfuoKHstH7wAKqoETwdD7uGgFXuXJkw6qZBOVdT4/wZQFamsdcj2Hypi5NZ1wU6I6/T +D8/KW7aEuZx+bh4XNbF3sJ7gMdegYolAdZR/7OExwCeGey+Fx/cFMu4jxR6Jx/uGJ5Grr+sSnF9e +oFRdOKMy15uq8NqRIwm0kq/XEmHIJZuqq4xfiCl2uswnBoT6eH8xcOyISMubZ4JbQFlAMKxAPwKz +EF72IKrD1rZgeIjgVy54kSSa44mWerl/CDK7dXZxlxHsZaTV71QER66OF8f8nbK4JTZx2+/YCR8j +6r8pjmqlRkCsCdNBXDnEr1uauN7GrdTwW4YtnmF4W9J92kNV8iiZ2lXM16zs5afREtc8Yg/F2S+X +G9kubEU/hyOjUI/nXPGspsw/Uux4UCg9Z3q3WIl3QLR3JWpqqogPr2UHmGItXphjYhUMWlxm8wmI +ALExkXbBAVPbwY1l0jt1XxofKW7e1LI7LZrLPFZjZ3dAusmWYrIelH42KvL+JhYaYW59b/NdPOeN +AFj3R73rEosL+Z63fN+t58xQ33O2ErbXEq1o8RyUD9DjZuzD8JFix6h2J+fGCC36boUr5vFCb1fK +4rpPii6qc7p2gWVbeavko/uNbg2pjENCATeV8i3vDKkw4iG2nUxpmRcaTRiDNmhFR6vl2fYIT7JP +9HTguYRFFfHMaM9174ceKY15GCaGCCLwWEE3OZkmt1cIMxphFU24OnU3Pwc+Mu4qWr0WveZmDbJz +Vpq8fytw+9ng9b9+8d//5t1Pv/z173/17ddf/s3++rr853/8H7/99utz0S1Und99+V+uv/2MB9bl +izF6CyDMM48L18sI1aqgwpDUKovcka84/ZOx+yO3USbpe9Vzz0JMrsLNziiqbPW58e69kS+YpM7E +iubutVXkms7y8kK0paAxeChct+zi4pyLgsmoj1WhvnU0v3j9T1989atrcn76i9/97pvnb3/97jd/ ++ObX//jt7/74rvzVu/fGX3Bdnd69v4w5C5WkDXDisMK1ZM2L3/OflF4KxKbvkl8L0kKk7d1Xv/mi +m39qBWnDUii2zqohK+yRijXSCaJ0JPYuq9mcnsvd++XzFxW9QSwQeWk8sxv2Wz++vBS2YNnmoFvD +pK8+/eDbfvVdb3ut9OnE+R6AMpPkKySc33311V98Gf+rX3y3Ib/vB/rXf/ftN7/922/++Id//O/X +r9/99OnLv/l3XAT/6e9//4dn/yM+yPd4XEvl/IwpmjeW7fMXn1nin9kMn9k4b+yxNzfj5zfuqz3+ +pjJ4a+e8tcXe3Ilv7tp/CUX3M4Z1rzORwb9rcp9pOLLgyZtDkmSPQa8ULflqMCif1K+howsPccZL +gIf35uaIO0TxQne7JkeplKPhNm1egiQAks7ehXwEOZf5qB6yUsMfhRf3VnV33sGEloReyeyG9/LF +/4xus9C1VBtYjX6AaquJtlJFoOh6jQI++esZiz1YE4c2cjyrF7ONLqv9Um3FKwZNszSDxxg/1usf +XzOVHVpxWaLdMceXjvmh9/3qu953znEqUZYb2v9bt31Ot1UP0ZEM/pnSNNQnHIV/VG1Lbd7nASZU +A6p4b9WVD2YKHbYgFpv1re/zFikasm6rkVXr1BiCoXoGr0OVv1zYNCU7AyKVGwfI7idJufmDNcd5 +SL/1LSJhOpuvp+BfUr118/MVVT5HiZWwuI1K1C799aaG2lOU+jnotYY7a4FRY0eiFfgMBbmd9ZY8 +oGjO0RlURfY00ml9unSM4Ha5fC1GauUF27w2TReabmi6L8VJLuXLAlHgBtQDeK3A7byagj+r6jLA +GtV0HUozf4Cue48Q36URMupD+zvEYC8DyzzWnMUGk0Yi9hept0vTvS/dgHKXkq7mXduaef3T60y9 +HtPia3myK8mlb37YPb/6jvd0jropf8u23v/WcW/ruB194ZeTzT8zfuwV04iBewGYp0RTU6w5C9To +/W87GjuqfnOxLZsHdYlmAaHuYBphjaQiONFddeeq+8SwwymNZSehqeJPT0j2SIIrofkADra6vE4A +1VLmKX1gY6ukp3pjCv5lldyKkuHrrcqpA1lLDMT9BNqC/DLa2pZoZtM9A/yJuBPvx4Oz5kbN5k3A +VzDlAhqIgC8CYuv4mbUgkA12zazivLQmQz89R5UV2s1ByW1VXKIQjrxC+XCPFM8w422HWMteTcGf +UXLNCACl5JZRHmcCBu3vpsCqeXWXgal/FkNuXKeV/qmlg3T6sKystYa8Zj6jqLq90z/f+OFYwue3 +5rhLU18/6I5ffac7rsKaAW+1bhru/3/l9T2G/MUX+/ugBf/9N3/89A+GS/z5H3///377AjeYLMTj +6urvvjAwzFJVlSGLtxVRTq+lzGZAG1ouj+j9+eXbgENj/X2NOcTKVMJsKX5EnMQel0H12y9+/n1f +7uM//uYf/virP/32Vy/ei3DI7/tC33xnBKWvvyFKbuz+50fpUGIQ/TLEHT3WFKo1z1Zvwk9ffO7S +GBIO/n6ULa/U/PTFC2lQdMWIW70O7zen8IlKippDYuF3RpsPI0DzROFmi26LIYtnuknj6W8jxlve +b36bkLcvjSHHSb6GjF/jxc2tpCu6/XFEY1Dp5cXNKXxx89ulMaShDtuL2fDOii/unf2ceRgwOezz +8d4UChKob0Txx8cFEiPcPnvc6SY7j3QTxrPfBox3vN/7Nh1vXxpDxgy/3hmmXrOrmjex6ESSV6eN +en4pvTxrtWlSLUWJ0L/xNlSV2EMoiJz3EZBUCDmU1N5HcI9T78V7PQrxWNoiL8QfX4ibGhvfb9Y+ +MDF0HqsdqOvtFVz68YvHtz0/j1m53ebl/D29Oasfr2/gn3Yubail2X6QIiP33qGmDuezfUYb0wgr +RG4PmWa7RomNSTXbhtd6GAAhvRyVN6WuV8J1m+xH6ccX0ukNvB9vNb0E7+GpKFMumW9AqaCuetkz +wG1azq1ezeDTm/P6ESbFteZruv7xh9NVOxmozULmKKYSa7fZMqixspBgsNg5D2IvBvVNmb4DCdyR +ome7ZlDGO3TAzPJHEcAuNQewKhVPyy2vPheQTdnZw6mTT8KzXbNTxA6fE7ONJR2YTdqKuQCcQeBJ +6zRZT6tjyoD6bgd5wh2ACORaAR0R5D17BzDXoZfNRkxsI2mAd1S8yUKHbkGgIZYOZaXZGQH8lmSi +i3uhVG6opgjPJTSAykz4Fh8fxfHC5mftcBw4MyZE7+qHSZwzICxnupHInRHwJXcrupyMcfuISkzK +q+Qn//goxuLQY/WFzxiLyHP5uE7rTa4maPQvcXXmJ58YLyq2CCnaXfge8kBO6d46RfEhZ+gz8dJ+ +Vcvs629Bt4JO5fsm+yRNvhEQPJcC6Vtd2Jx2/M0NYwfP0v773sYgdfjwqjx2b3pmyIk+7TAS4h59 +R+EnW+qrt3x/pZAFMN4Lte6XZlVs3MdMHzySOO/No14/1Ue41H+6/k91Y/GQ76VwfvK1T6v3m75U +oXcXf+YfDHdQHQM0BR/25Q5oktdA3oXJSS+eOIKl8+kXb9+KknspvoEteKY5ak4ox9b0dXF0AiNp +FchP8WilAYtn6Dd1RLeoSCIGFgUTD0LQvYDY1Ic4VRHmfbceDxf0TawR4Vmfgoc2R7vkXPtd6END +BY2ab3/wkX9g+05dRjSM55TG/X5QTKxi5sNp6KlWSXybjy/k59XR7cpxbGeSIKRuephSNIwquz3M +P1QGCp9vHwrglyQAz3bF60MkNvqNdfDx1R9U10t+wzk916XlBRCSqxitxU8cYXiZre3ywaItpOkm +hEX88UCNYSkWqwxGkwkMAJCaKw+rQpqi+uIJaDmfEp1hCaGVUEMYsmO1h6ttfdXkCpCdFN7cUjbE +50oNv/oLlhr+5GvY3D/5et1UgncKIZ1KNkR6OnwqxpBnhsDs0ghoFFeLQK0GEH9+9QfJad5c6KV7 +AF6JLGLwwA7hp1ioDp67X7y5R23YKPCyas9KkBeSa/oMgcdG5lS14Sha9DAq2TBvwuodUM9a0B+w +0yIPMuLqrAiBdaiLxkQIz2skYllvVw+HADtAU2xunWVeAKl6JzZN5nVrAgF1yt9muInc+Y3v8c8t +p78kF89PvrZYlsIzjBxFzEVWLsIu3+vg+e4hlzePpx97OL19NP3Ig+lHH0ufOZR+7JH0mQPpxx5H +bx9GP/Yo+tEH0WeOoR97CP3II+hHH0A/+vj5n3H4rFdeb+3BUnvTBYbahEMfTH1GLl7UhaepKN3S +9k4SDMIo1jGkoDcZH6boaWrfLEoDZZk2k0rdTLyDKa2K/byp0M2E6uEBpjcN0KMffFS1mWvElbxz +kO8XoXxBiC5tgOJLxw6zcChZ+4XEhUwaC9Bt7cpT8UFHpV1C3FQ1w9Vhudk6+2vhqWE0seoIVhWL +F2qbfMWfIspC4fYicWWw5ljZV1cVvyWaQnAhs38cWCRSbhKKSMoIoXFwFWPRzyotYDlTqUEDilCM +Br0c9dN1GuxeWN1qlmH7EKaFeXxqYGH4scklP288Vqrumace3cqmOSciBEDLQZ88EacvdVh36VFD +DoW2ovN83OrqMvTk1c+dUB/feZZoFOrzaStCwdjiLU2xeErQvRZNSGJzUIYmiGVoKmGCUKzn6K4i +3Zy3utqyoSA4YCc3RDBXzui8MZ3CVr/vWSWVJZ2zgfXKQ7VG/o1EkoDf6NOVtR+rT8GdGV1pFRjZ +BP+EMM6sPFn9mdmW1hRF36RAFnPCa+3BRnnu7pM2dKFhBLRQq9BCc4CcrNy0kAryp/cClxa6zkNm +zatqViwtcpqglKhHYm3v8oyyPHcvQDTpbFJDTht0WP0hK9HFsB2+R3JvWZJXWWTrxLwZpSPLlQkX +oQDN+aBUduZU9SjIm0Vp6EyhffUk3VQ2KyiaKe0wapjd3mF8DC+wxOYYPXhnHaoD4QgtOhzvZBYt ++s75MzlpDDZmJFS8X2JHHrcdHVTAHmY6QCh9tLDDprnUxY3EdYQOwZaTDmpezleii84GRy1l6toO +/EKntlnx+xUGZClO0yUlNKmEsrqWN3YlwBukcrp2e+N6vOxpEY7Cep+WnBQjdIqrrg== + ]]> + <![CDATA[ + IuPQJblSuwcbTmJXAHyWHrrospIkbLcBLoNn+tcW+4HBPZJHesfpOl28qNoLUOc6ndcLSzXb0QbD +u7ISZRL4CPJyqOtmqCORX7cUfISiRDBqyik4ige/JNPPr43FnVVrZLumOobsVhWj9LqWhoRUvikj +cj96U0+XkRZELYNcuKd6qx728HXaRpt4B15tBXs8+wi9ViJvKiP44q+UUTUDkcpoBvnqch5YBSH7 +EFGN1v0OsM6OijLwQjSfcES2I2fToifcqZ249hJj9mx+DGFWv8ZxH4B6z7jDUlW1alqJq2OufYSs +DqYiaEa72X3BtdVljgiUHvXhyZj1dkQUwhzqRItDLO7dHvV8yQvAJBTgGqVYGqAXxsTBgStI06aJ +gHbFblWDBQAbuc3gANnkRrRNDyPq/XS2tE6tk5iJtVB3CmHrhxes+KY38a15trs2pnZW8MDsMOvn +vVumR/VNF6Z+7CG8bEnR8BBN1zdVUYt2PLaP02bYQuRHK5H2BqqIbe2WOq1hCk8vEjPnVXrHPsG4 +tsl8FXIUwkxbaezUwrvj29r3zoyRGHucJ6jGsbWKM3piVe3gZgXPa+bRx7p5hJu4ro2npUeTF9+0 +KEVdR5e4Ve3iFg3QRjBAqIX7JOMpWveoMd3NGd5OPkhlVLgF0w5rba1VpMvqacBOGsK11DsExEEr +uMZHpOnXit5VQ20rgWse1AFYna4vZhpUnKpwe61EpIzu/tkEr+NrZaTWWkBi05HansSSLkprkEoD +XKZUUE5ZbmmMtmS2raIvUfbh+lxVnTZTcCySpcboWpNIEi9bhy2EZqTOQIgzSTcBbkLmiHoED+Qy +1RuBwi0B2diXBvwDIikGVpDrM7qbWQcYugJgk9TvhzQPeyfAMANPETCaax2hF4RnZw7W74X9jKpf +sIs7Xtp2aBGCBIlobGawv0gdsW675GhMZPRF6A1mKkKNiQzvDeguhE716eoItzdhCaqpTWOpWCmK +UuJOVesWUDTHm2xjBnVY+zGMpI3CKGisyrQXwFeRNqqdqhcr+j2jP506WgpKHIeYVAO2hiphPtMQ +vy0//B7p0HJkicFoUCDr96gKx6euVbcHZ5SvCS5KkEgWum1VxwnwobXR3t4lmh97uziDq6dIMzsb +A3pU93QUSWpkh2kqGZ9RUprjhEBEbQwJ03HxnNbDO4ZFywC1Ik9O4sQvVdQvDOdGeNdLrmM0drJi +2q3mcm0LUDaJpd1OWf7EAXZIxbxoZP8ckj05XuuPRzXkNpGRjd21kOdlq/1X9HPYRc0/cYg8UzsN +1iJkp6CgbpoiGewjiceZ3En4Dj2HHoL15uKxNQB5+oHujWKEy25hLQEiShrgoJ3pIS6vxyNjShAp +F3J9GGVLT4fBg5FJtFoOfmfZ90vcYqAAWaqGB0epBliH8STv6F5QFivMECSUEIFrE5Z2ngAK0FWR +SEBmr1REaSQhpLg9sjXRzKf45aAISo42JqCp9+DR2KoX3FhdEJ7mKJnkriaO/I0dTVOOF5t3LvU+ +tFvtKACyFQ4HA7pwxF70LhWmi9TzRcym9gboshRYb1A1WZZmV6qtTAcFymhIFnwpKLsLVcL4WVYr +K/w8yUmWkymWNM91rWCqzGTzDlIEF66SyEmQGWmzJ6UV3INkCK1xiqRFbIRDPeLAczLltBGvUr33 +ZKBbSKpZz/xZ4qOIFLSH26Xe9sURK6GMdJhfo0az3CLHAjgHF6LJsBdVjWMUOXTNDiC2eYSrp87G +K+g7EHKk7KaHatCE9qBm8QWMMQ+N8Qsd8pZ7NhGhPpTX1EXN/jR0UaPvW7z+SLqI7HAmjt4aZDQ0 +82VGcRsLBi1qkacoXqbzu7uYAUJ+PAT9BP9EnUCR0LauNFEu/sW20pLwZnLQP+1IQG2ycAy3ZwXK +IkYIqbAhOkC/GUKc5EwjQYTzcsx0uqWKJMdyVkWN4vypQDJUomlKzlJPMN/OAMiogPZqCn+bkjbn +jqB/oo+33FuTKqJRYN4Q20WCDxr+HGJIUbo8RpJwzFNKOCKlk+ZSaMgbxUHrcC3h0JMQBe1SRXO4 +2sretEeqyBVccoo710XD2TayOQhjhi4aTa+7SGFvLpIPAGPxNA3qg9oIajOUSdvMkKtTxMpksEA8 ++1hG/q4gUrnRy3bnf0pk4XAhvbEZLM2FwQDg1NbMoYtYAt3dVvD3b+LqQFN1Om2bSxiVgaGJqkrC +VZBuRW6Lu0X1iibsOoxLF08mAjSTZtUiPsDjR1Rava6IZjsdJTZrvsf7mrReie6mpavjKXmi0Agq +hXCNUEanj2kELK3VsvyazAjUayXyqIzcPXPw2mtl1I9/Nrxzmtc9NtlFg7hzVJovqZ3kndn2aS5g +Fpu3YgBNYLhnaIko8Y42vyoSjb6Z3opBsssQid8P53pCCDvJlUFVOpYMuw95R+tKIjj0C3BVkEnC +D5oexxuChmwl6qLgzyx8A0Ql6j7KrEydtevoEm+Ti+I6sWIWMb5lZ8Q/vx/URdFdLTPzD0OhKYJG +B8E2chIzuZofwxUaIrxnqMx8phTtfJ01GEKz2aWJhJe0MsAiwninLjKdI0KmTRp+z4iFHjENnqhz +1FzuKCLLDYuppbH9lj3/aYNiPPmcVjYKcD0wGUI6vXHMbWpJGn6vY9VwCZh4RufaMYTrOVYREqQe +4b5ckfi9d+VCvo3Nm1cRFZxBOyaJqkpwGQ7/qlJFk6xO40TZx7Ww3SzaHrCnMvJeUEbbo96v3pR4 +MPvSU9g1yZukWll3n4o85ywmn9r7HSORuA3jaaeI6O2YXyMqKHoUKkel9Iki7ej7hxiS0xmjA0EK +ajNHhGwmNUIfsYL6Rnx32Y6cAzofb+mRt9w0B9He1VE3LQXeb6qjHv0vSTsqfQQYTVPTQ5f1wUkn +W4V3NBWxRvDxQryrxOoYPNQJfM970zvmAPb0E1z6CIwa0Ec7F1kR3pcUqmfs0zkN7IXI3Y5QR4nl +7UYy1WRGOYDXVih43VzYFk/lnG/qzLU9xFJndqwn1vTuzkRg5oeEcPXbAKPTHWHiHM+6u4wF5pnR +zb3TNhqns9kU4KYYW1EWWQwKKV15TBXd5CEZ4rFSSNfyUcBJxEmJQRz7eYoOpm0MCkFLp6XsPXih +EL0BmCskB7fto2RaJMKWb1EppF18YkbUvoJpvXJa6Py66yR6ldMFGATss0nRDymvFcnMW8zI9QGE +pZwBCK1JQR+MSLWH9S2QNMJPm9NxAdNBhNJIS+yowhsN4cuSQpYII02nyB2HbNu1lOfRxr2Ja2L+ +poebO5lzdNktq5/pPl0bLhUpnjoT1RmbA5vrFmbY9VFuIb+ird2kzRYLQZzlokZAOwdJsZ1JUkbX +Z2scQE24rNNzo2qILsqvtMhbntowEBG00bV0jjZCe6DQRux8ZOrNWlezCpX1aiZtUfTubM3DnXHa +bd7h1dRHurXIcb4RiAu5mIY6cqHVc/RnbnRNFz6zfu9cCqDP61Xwgdm1YlqKeiZldKe7tkIFeHE7 +TPQxBQnsJElNp3YnkaMezoA1hdAAY3bqGKZcgPdJjeSYIKCVMJEd82CTmPd3ZUQohz2sg15MGYmV +wzieU9ZejuDzULL8UgYoWXdl5AgE0xtNKN6teA88Q6miNORjqRdfwuO5ubOCl64yCAV23KOIECQ2 +PbimrIKjh/ppROyNFFEyc35fxVeTh7xct0scv9BE5AshgQ7s2SEtkEiZmp1hk8KiMHfEi4ri6XZq +jL3PAHTRdnTdsTj1pBqavUX7j0ky5RtyEy2Il8ylFqH76kstOWyQiqhkZVn6OnYR27fByA0banvb +I5zrWZqEkZ1x//287UrgO6iIHBAARyIy+uos0x1iGcZtl9ILL3OpLe3uQYVrYSTwV0KoSAU0Ueel +Q2y+TRWFxunFGXytQN7y0jr0z2tFZDqeishYdTo5KAGIkiIqkTBQfasIw0w4otnFpQSpSIp8FIhJ +0GNo3nhk9CBmGChMPnaoMWGXjQ2zbIvecwd6QNziM9BnAEJlYqZByhqQAK8VA/F2XLuSMLjS6NuK +JLm+kVnQ79ekIlL5u8n2YdBOI4SV2gk8hPH7JoCRGqsjj7jJFx3tOsxPbTSL4AJ84hQy55XBVqh2 +X0x0l+RhAtc6w9muTWjABB8gsQknxKKPTJ5Ld2NnRvS68DqEm7WUGW6BJlw3s4gPFXZV4+kJpuad +VqijQnzQOM39LH1e6add3oaE17kpfjnLzkkdZLcB8y3Qa9q+U/NEwKgQVujHxojfe29yRLpVylCC +D3dHObcpnpmV/t/9JPW9ChCQ16HCCYJAsvc48lkZQ/ywh1x1gQ+bUo80MLrUuYdGPZCl2FjjlomD +MQRxZSYbkADSEILW/z3jSLIRbtDweYyJVQJXuStls0cQyXvdQxZG6QrFMKKTkFlNs+hOXbWSLzTI +C5OIjdE7gY4GkQHVfX3RGN0c90pDBTkAdUYnunOTWtc3B8iYIUT7NeosUjRaYXLUn99JfZuUjloP +JO8v7MLGmlVi8vVz+fD19B007a1DLfSj6Z9EV2wpDQa3J6C4U5O2I+CRzu7eQqHk7JiZgBTM8MbE +xrQFzjZ28HQaBy+x4aNBXgxQBTHiVwcD0qSxMFaghsQCvpyWQaoI7QrdCFHQrhKf5eZKNP5lRXhJ +dxq6xD4unvLq0TgwS5dFvGIzhACtE4jtNQP2vKM2CspIGjKpW1ZTPUKeDv6WMqp9iCQ+RxMyIrpM +GYm2vfhx4Up+3XSBd4+EuI1Iwa/OkDZxZ27v0IjCDo+0fM5qs7CyLh1k3N5qgetm3GSAEUbMk6w7 +wu4nqDldGTHtaFxQbIEFgngeqIB7ShmNlbgLxEIHgFJXAFxerkUQS5Yw3wBKfWh7nhB4ye6IrINW +NDCj6ziLkNYbJUxJHDexia65bn2JY6qG6ya05ry1r7bI9ki07pQA8BNRjkyUOr/QJC80EtjYgER7 +QyOZOUyNdI1Ny287w6o0EkuJ9ofoQUkkiQWVWREARu1NfRLUNhB7BtuclaLfexdaO1XqjkFZC5ad +z0TqKANWDsyrqG2n+j2gvVNVMs4TAQhTTkH4be6C0V79PgVE9URx6LgyW3t5KsPO2/S7CK/Bx1f7 +AjAHSJi5Y5Bzj9+7Q5TbKcKfkQYaB+w5WB+GrXxKlq6fcStvb8ron8pzMaY3ohlzviuTJCPdgtVO +WVxSuMkL4M0YQG6awzUQlU7l+GkgGnR1uE4mLTE0FIURBi3d1EXIL0kXsfCyhk1zKVX6aP1gnh1T +a9PX1wkdg4/dpedCOWjsOuTXNR0laR8Pz9uHIX50iObm+v/Ye/MmuW4rT/R9gfoOOfOCHVJHi8K+ +2NEvorIWW9NUiyPasj0dHYpkMSVWqxZ2LbLlP+azP5wVyKX2IlmUM69UrDp5gQvgAgcHZ/kdiYqt +4nroGRkeMxSoSOMphRsK4KLUipw4CjMJBTGixRB1kofOgxie35DjH0tJVRIhJdW+iQ== + ]]> + <![CDATA[ + dhmIgzWfU9UDa7MK+8MK3CqecXhkY65SyclEdxGWGqokWiPLv1Sqcm7RXFIV/d2UAXGOLQ5dpJkX +KA145VP9Ws7BHEiCnpEDBchZbXoCeuZAaQhBg9gAVsL1tKjg+8MBO3AkZri/wAEhEXOoG4EPdiYx +EwGH3R1lYPRuQQ0pgh1phxHBNijUfXGMGKKhGyTwBc7QJOk3KmHNsFhdg9Iq5+nIsWu8nQQTOGFf +gaLPbIeNqmIcxXNVrFqYdbgw/01Pul48R08ZdfgKWaJu0Z9MyxvZ8qtos1BQZ+4TYxUZkZIz4OIV ++EQcEyuSCEffgWZaFMNV/UzAv4NtcoDII3jloA8iDazl0yhxmuQysxTxelSvfwrcCF2sRyhgOoNx ++BsGeVexlcnSCuxWgjl4nO+yUAqelfMuJGEYwquCpA5DziAZaHIezVcsOsJvXplISLwFuC4K4fd8 +gktDBUH8ktq+I7KUaNEN5U6kpuJU5nAS39kQJ+EBGyxns5cMtxSyZpQRUe7XiIBnsUtD4ksAxkCr +TpLBiKZpsMDROR6Jas9P9AeSc9BANGuT7PhZ7fnsWgVGkZTLsIkkrtfHJIc7TuYFRKOnO4wjYWLq +Bv3IYiJUYDSXUhDrtiSQXWEi685nATnTyIsQhwYniqKjVXYsBUOMBqJ51fk6fZlVMgeZng8JjIoU +pwCeOxoFDszMByEL0qt/TiZejME2Er1AqScxE42GIVV2PCHvRTkdQWSuKCJjiZ1Y+cyFeYRF1SQG +LNvdcJL4SUIGtqwxFdnybG6ywpCYPrGWApe53EoaDU/Y73Jj4VRbvvtpJrJNE0sqVpPAZjmuSFaD +QKY0XM4Y/HIgA1hIeEMDmxjv+Sxqaw8PNNqqSuYX4Ujt3MvHu8ANAGMZWRslVIPmnOjKKuXfkrks +x6CqEEoLHMlnDQBpr4glIoioEobUbk/UW3xFRGxnOubUyWU5sVU+XDnSmaiixsmbUZ/nzlAc8Q4m +klODQHJoBdZJwrmgqa5MEt8kScSLB8nMRzbcQIQjUbvwzCZ5m/nICS71Sa38aKLE2Z5S93OMGGOJ +VNF0pedJ7jR5EJYksQbi/Ck3oqM0eKdIWK/gjuMuL2mzs2JB2GEO4ZGt8r3ROwVUJAc5NB1HhdsK +RYiaBQ7DO1yUCop6kKTMzHdASVxiI+sOZwGcGtawI7AIKjsSdu8JM1nQGiHhApOjHA7okM3ovEQS +h50gHpfMzJw4z6to48U3x7DVkYn97Ro/cDPHIUOa6TqSlxmlO3OqbPLiqJjVKwL05pzN0Wr4JOjN +2XLvFH2F/JhZPKqqKooS/ABST1TvHuEbXtJc0p1OYGgkegQbQN7NkDmRE5tVTrtO3Ei8i4ISQSZz +nRu5INrskI0A4chSBFAdBRQL7AleKW0XTcWqzuSVZAYieh/5zGdqFTVBzl0UM13Kl3shPkD1rsYU +5kYin0J2OiPO5FaST2N6ORZHU9creTn2hp5er3uQejJM6iHJRMm02NPTWYJ6hm1C5COvYImgrytB +KzC5sHxUxHLvxR0N8RSDtKBxNj7PIV+SCtiKifDuQc5pfPCGiEPxFkxsZafFUbp8xMI3kLMXUSiR +UwV4yWZ1l0QnMCIODE3S3nk8PTI/soLMyFsqogRYZgajIdQzmgWMlUaQcDCeo22U5aUYmR2ikUWY +UWBQQtioowRXV+YXrm+zK0xk6ZyGspFHHoTMKCCOP0H1pR4W6wRwBTgE+JYJL+IIKSALFKij0Hok +llqkHSwagKO8V2dFx8m6yX8+Sop7cpIComYgcSqmxufdWdIrt88k/X7BeqkoEBIcFRHo2EIKIPV0 +QzyHvDgPUfWe+FAgkY5AZGUFrJPSzYBGc5YiDKLcK1gXQ9J7w8mI/HBUDHoC6lkpaxC3aZsUwwIE +To66ymRwPJABJHYKkFlRTPeMDAb8wXnB2eL9AH0lJXMgnMsYaauos39V9C3gL0kkI7YSWNbAyUxm +4diWcc1RHgTUa1nR5Bqa3uDAqQqLoDJQ1IM+Lm7PJ7UsRmrJFY4jnc14UKo8rHpWBKIc1VRh5CWC +hDMvavmgrhe8d8KzKNbVDnKB12A6MwQhATmx7cOJgjlqDDb4Hzs5wHJ+Zow/7McsckmkFRSEl5NX +JmpA1UsgGw6/7fMP8d5ilu28CMfiBKwIbaL2fCsJsvAQ0l9flDQWRYNy+bwAxKjeSuy2j8TaQ0AY +5QFxeTR7DTvNQ6tE27rCQtaJRR7FoBVOlMH5mlmRpXyayAhQn3bMZJYhDNqV5bTICG4AvGGNsCIb +I+PvBnF7xiBxVvokihZkIo8PjLQGU0kK8USRwsrLeKPo9gPwPuUAJ0POAUrk7S9pLA8CdznRPIvm +O7BxD+eyuEcFmmss29TOTTiFODAecc8JomFA/K2qFUTJlVw1HKlSvBWuRmc1K0pmdXbqKX9AxpUM +0tb1wFabjZimnFrMGPIEjknVCfQgmWBIiJJIfziT8WiV7vZbGceY7vWKIlHEUdF2wQi3FqRq5Boy +Iw53VZz/KFE0SWASiRvxSRsACmuVdS8+0kGPv8CiqkADohZbxRLm3GA8TKJo5kOC9V1x5GmOkQjV +LfpejWhuoQJmRtJ8TzEGlFNcDVjQUtEJJCeuC+QbhCZ+p7p8xzM1UrSoMBMRlSC1XhCZiA2TmIFe +zniJ7BZIG90BUNONm3nUYEA+j4IuNatRjLOCRNJI6+uzhcub7sfEqHBA9GrkZ9OBwW1FeRGf0oHK +MjR4rLFLTewuLSs8ZC0vEvw0YUVg4Md4WeVEFKdH7hMajGbF9w0RDMVQI6M4YJZYiW6C2J4khkxM +ZBbYH1GMABDeJ773bM1Xn1r0x7cdjJ5DIsEtSDgW7H1iQVExxWuYhcM1LBIVOwmAxC7Ci1dVNWh7 +gjCGQBpCy7m1tQIOjvLP2ckPaZHtP9aJtozxzIBWZRLisZMxQhXxxZGvZSF97pACs7KUVHtAq4R2 +gTyYxEGRwxnAfUfmVVWTVCGQO+FAEifKMDM0sQr5yQAxaWgSBSUj0Zm+o9rCGmkUx4UFJWZBIbJA +FZ+zngZUtdUqCyJMPWRB1slyx2TTOFTFi5CUcuZXgqCnnQcoWSIUlF3AewiKQE5wjyA4ldLLx9wN +nXkJrRw2JhFyPMnmOKdQIJQKyCoB2iPxBg0aUZQBul8GBQVW3EVzHPTOkvY6jegGct5JFDjAXEjz +cy6E1DIUBGKUa/gtqw2A6NSMb0yPozP9cIbIUkT26uzN4icQBSA2C7tHYu5mfO+r1psllJEOFRCA +Je5+KwxkHRtyoEUjPmTKwIfA4ZEZkVFDfMHw12Omko0R5ZHu1svOrqDH80nkNYH+hAODBOEAuRAr +6XoGDEYIrB7kg2/ViGugJdMZWc6R1YuWj7mYrTBqzFdKSpQjV3fpgEMj23FYucBEPohAug2VRzgm +FLB0euyJE2gy4DFRj8QpiCHIBy+ZPRitzbKDvFTARuZI6b+Y8bAtLNEACS8Xk5MCISIyQmK8NT3J +sTUDiVkwjCu4XhGtOD/k7BZ5qkT1q830AoAYVFPkS3ZSfjDkWw5pzf0klWTaI4ayHlkY3BkWTe0C +EbtAtf6rhjWIIA/cqKg1nR08EN/RdG5Qgqjr0IuUiU6OcprX16tnFodgKzsJIulKEl3kMZF3Lo3a +95zXArezlIYGSJCJGJEg7o51o+W5chjrBeg2qy8JSEopSVx2F2kCx3Bn8oZkOYlOskDMQ1gtBpoR +WXCXkgSjZAW+ADkpJIlCgHRq8gZJUAWqSkTOMTMdMd2yeHKiBCmciJ1RgcxxI2gNiSw4aIDpMgtZ +y4kQZHrkRIhh3m7qjIhFCoOxkVE5UdBkGUMGiyhuquI9DK4BYmMvGrxSNWYC9hRGmYIG+8rHcVOy +RGnmyoctq3ApmKVWtI0YbMDik2c7i+tZV5kG+kkJ/gFqlp0yikHcUhpPmu9BmWtJRkKiQul8FB7N +vIXdTzr0BpijBSnFslXQ6hGZ+SjjGEWaGkQUJUkCJa2wlirxEcl1byAMAMD1PqB/VpbSAA+3qG9i +YeEJbXIHPIkkp0mW2GEKws5ieZfI7u4lBeb4OMzhakX8yXkVtF1RhOJzNucnQvERLoSiHPZfkq3D +WS3IWFXJhjWyJsyfuSNaJqegjyWJpU7OhV4Tg4BmvMgJuh/ti1frme+hq569/ckpI4pJTX3lUTrR +8l7sbHyuBt7KHkSVENd4VMh9CVNa5i4U8ZaDoDQav+ZZBV0IHobZkBPF+KAwThIoDOSg92KWUyLa +KnysSw14SNJ3aKVh6l2ZaZURsWi6PFGZFJJ0lBUFeVZy4iCbGAmsqkPDKg/Z0ZRmd8qpwO94OaPC +Ivke+RSoj/fPpiCM7r65FBbJ98ikwK/z/nkUaLQekEXhQ+RQ+CNnO7CS7aD982YrcU4FSgE6gXIT +rOH8c7yzbXd/frn1LNjGZn0Ihj5NiCr4S97dwY+S+RO80c/WM3P1xwW7/ot9/mhpp3W7xTun+2X8 +M0lJebYNy53lBBLfrOYEhMUTekoIwi537GzBtljJ+1AlcM4T4D5i5lWZxZpot9spLOmWDraYzCyY +/RqYGIQv26gANz55VsKhvlAqENwajrEVpAggVdEVFHQBcuz76oyEXQL6h2dIqmi84gOKRUTysAF2 +ihG/FI00KSYp/mbsIZ7gp8YCJx/p1gzf1bMd8gE3BpvsMKWn0+2Dg8vjb08vZnDvMJ+pck9IruBa +CPz8mMmZI4bE4RkBxxgGtFBIMWObsZAHilaOLweyrGVDcRACPiRH7v5qeoI0TnfMbyyLNi5FRbrm +gYTTue+A+wy6nsfUoVmAOCA6SbKMJnXjtj3758oIXD28IAI2acTcanTHZLh3Sov79exo/sX+/Lj9 +s5IY958vMVc2JWrJ4Hav6c88bl1gnSf0Pc6Rhv/cMVELbMKBpWPYS2hOxCXqMvSTD3mZ6Im4vNxi +v7fbMDMBMvI7XSRSBXXNvSB/h8DaLVfLMtETESsYyFbvBd/blW4tD8CVU8JMvvzq5GLyGbzFycHp +8bvTy5M3k3PYRSbHp2/mC6uNwgMiR26A4l1g6cX4YzvMEPjWi5leckMY0bmCwSwL+KjRO+Pzno63 +06S01dJpKG31zqJ3uoEmNfol2gHPiWpFnyN3BjwoLJCSPnosDLJ9yIt3lqU7v8BElou0HX6Zq3e6 +1c5Yv67b1q8O0FpaWBpymkhh9eWAOoPfbVVaWnrfVDrpnUnvzEoLa0qvezbivSy1fKzRLz2b+u3W +tHI9TfptFkpbdrmwojopGGBH5wNF1AJiZCBxS24t8tLYzwjnnQ8r9wbKhQHEfEUDBBWPgXph3VPz +QTRud/5lYXoI9WiRmsEE6CaLNBqon5fuTMNEpPBiSI3MMMnAPxiaUYg6udFCsHCvvuVe6UAb5shA +reSAukDE2D6zVL7QnF8qX/SdYn4Igs6vY5NCpSRRdWw++DyuudetqdStfbzTlqKdZw== + ]]> + <![CDATA[ + gZjBYX+FuNj9TnWRhStxQsAhrUbyT3D7hUgVBFTYLd7qh5HuQs260VdqsSsMUCbUL1sjmxaqZL5l +DHCMb9HU44zfYMiH6Tt+lOGYe7AgWmkphQji6unlBbuR15nIoeJh5ggFm59lxONUM5WMa7q/Kqur +v3Ph9bTOT3ppw35/yHmC0XzQC4yLBmqVmSF45sqd+u7RebvH1S0y0odvyP/8x4dXcYknV6PGNIM6 +b9zWc1miAi2J2co69TUdiIGIODYDuSfwzmWAMTHVC2r/EpEO1G7dvUEtl+zeuUgMRJQTuZBdv9et +dmtlAB5JXsqOJi+DBEQOn1AyRmywxWkgssFnkRiogp2lCiDojrR32Wla56TQAcOdeazASzgkCKUc +K5HDQJQAihyXifRywQ4viRb0XgiGd36JWLUFYwUAX1UEq0PuBZf8KHquqgGVizTSncU1d4L1UyKr +OcvZ6FcKQByhO2l5jr7NmgMPFHKKcJQFE6sTA+FfiQpYyE7g0kaiUd9DJWJksh8TwSSBo4HZzPeS +UwSKUWIc6ihyYUCqhtinEJfvjc8Do8Zo7gYh5cEQqUQIJwtR75MYZ3X1ESJGGPqF4oFlJvGvh1Td +QQQpzQkWCSa1E0X/jCaxxXuDeum5ngWyEy3B8PYKPAt9YwW03mCHjm6JhmtQWYNQO4hsoIR1KN2o +YUrcupQo05cC8hbuNZLkIufu19WJpStvBnIxHVHbDFkyjJgQRmJZV0ElMnPSLEjT4ppkWM8kNCnu +1tzp11Xp1z9eyODVoamkvHZKIf+VuDwAXgcrZzLkgbCIdg0YVoFsyIVyqXWisCC7em/iCAWsleN3 +BmIhA4FsUExG+Aar9zICrKHDwiLRDigjA1lFFyQqPoMgFmR1dxEitSByrOV4a5RdD46xPIYD0ZLR +tZePElzNUe1KxDMGO10OxEwJaRcrAIYhGcVy5LhgBMHrm8MS8WBLNp2Ve/u2x4qItXvhE5GBunbL +oGbq27tppra37OR/TdzkrygPes4OBpDd2PPjBXLIltA3jrZe3VWt9nJ22Hq0O3u9pFQjXRqCMBvK +LgNmfbT+COoFgV1EgkkVsIvbK9QIfK6HOLmsRiNJgMTkL9iwJ7LJQBRkLiaKGVvSa4GrvM0sP0vM +ZxawCDgPSeAQ5GutWY9JHRszJk3EJQ5fdkyTbDhzDhzX2ewEp19JxeskhhpUDyFIFKFLVbQZ2Uks +Tq/AFtXN94cBRkQVdwgM+UVDAqBMkDWpDw0Qg5XIesYaGu/EoednVfU+CuTSQJoXcdNYS/QUZEAV +dLIGJAGxR9kMRIIeV+LO1iKZNSFjswKmH6EjoA6BEg8WhgD5EMptBRJtoNck5ZUkowUmPgxEwyAE +Kh4oQylmdE6UK1IHEDNeEaAOvBZE6qSd1NSiA8CI6pgoj9Tqw72JUpksEmNHUhkriIK62kcwYE4P +sizofMGU1oLlskjWewP71ADRcQ8gh1uynXbACiTSH42lET9moJECCGAisl+6dSSyi8BIXOjqDfde +QcRHSQWUKVvrpQWH+9dCs3QVLo7VAnntvWuJLkouGZCmKS1Yb6zp6cl0rI1ijyx0YIG87tZVmu/A +K5h1mUD1i4YZdD50JRHBtsTE1slOUmDcQHTkgCbqbeKEQJbcqMIyF8p3It24s7VMZbe2G4m+h9mj +yaTKwOizLLsuL1QgvkvSAFGv0FqDALUoaIiSYdtqqjfwmsAo/YXS4LiMkljvPfoto+PR0KLxRj8C +54z3SpgIRvfQ8xeIBLamRHEpcJTWYbxXIqyHSYlOFYRNKkQV0tGjh7Ld0yEne8JuW6ggZXKdhqXW +fQ1TIX/SkbPlVDn+JmCqHXL2y5a1cPokknBH8pp7IQKqsHRHpimhkXQIzpJEZS5McjtPFWXBIOIn +w4mJ0dOfilfKyzhydiAG5znvDmeDgoEir1Yl7iyO33BvrpLsb4G2VKk0oJPFAWUgWtKd/MInQsMp +2i2lsSG5x1pqF7j2ag46kqYwA4dVP/uRzNCdA82TxfdnPn5LOiUmH23RLKLkD4gvy5kXYZlwf6OG +8/Ux4Bulu0rlfXigJfK2WaKhv5dMVnkHTD5aIoMXaHvfR6xdtNWHgUzHJM7NO9B0ugtxh6eWQH0P +9wZyyVigdUjvhfIjmRVIA60QR+Ajkhddco8sGp4/3KurYKjUcALWBUFoWIUAEMsenMO9VdFodLkR +cKXOTSdQr0IeB2uByKOyVH6gorPh0UK3lLz8KPZm6H3VOw+2FlurEuJYgVMApewkKgaMkOArI/2S +ep240Iy1LhCdC3ZJRl2sV6Luh34NFcj71jv1UOzFZmoYGESmJtAEW6XTIFutBGDrzIZbBddJlozI +8yPDQHeQZLpilI+QhgEK1p6f1p7KwC3wzqfKd/OzyYvZycX87GTFXYPOlpbz/ICWR+NPMZwZ4IYd +HjHJ/RndD+94tuSgHMhXT26zx7J5W+R8bRMb0lFYSrSdKsETkkBnCQ1OKhATnMUk7iEHSin5oj8u +ryePrThC7cQl6BL45A+nHMwHST6WVhy92fmydfvZ97Cy03MjWVIQI/V4iV40vwbucA4l5+w01hlz +dsvfB1gYRews7eMbi/MESD/U2GnydK5A6IhAQDlPeqWUblnC+oe/qXBv5nij9GeocbXvUMFV3kjT +x3Ft/Gz7xYu1t309uzh4+4fT6fyH07NR4fPse3SdpRfLkDOOYPlsh03HtN7yTksg4GUUUFx18k4H +ulNIX5AbKblnLgSN+wXGEYuZnYn8YoApY5DGcDe6FbHko/WORGqE1KB0CEwO1k0WqgWQ1KgxziI3 +MJFfcG/ycHfvXK93dSSue8OP5Lx60xve/qExr4UXDFrBuujqqXyNeNptl/QdONmahf+AZf/ARf+A +Jf/ABf/UlrtuVZZDdAhPAd81pW6xC6kR2C6F+sDKu1GuPJRCpSMXKwRhnydvvE4EIb4Krn+nlp71 +UeoMGbwlgmCy0OOVKBMB5+t4L2jI5HCtlQ7E4fmdOjS1Vzp2arX/BxT1xENI4QQQEs8j6G2QMKg+ +gs4zcjkCJB2ruUpgszmhCwjBrDw1euRRmqZGFnmZyQD8z0latFIYF4mM1QYoUb0vPXFlvRd1h8Uu +VNpp4/OV2lvaaxy7tNr9xQGEoFJoNe47OIIQvA22sJ4nKEgOZcPAoMcsGKYqMV8qV1pVFFtF7Fdi +QAAkCZ3s5OI0x5nWCvKQIBRoC5QoPmGG8sf2e1FRqloWrnUgji3o5KG1vdaxX6tjsDiMEHgDKiOv +SxkAFxGUPgzDGMQ9E3HKj9mrJJYwUOnIkDQhW14mYuJub/r5hMmlQ5JIpShUshlNn69ElUsxp1y/ +FRTIJviFKjttfLpSh4ZqjWOPVju/MH4Igy75PHH48FdQbblh+GjBwunCyyRU2AOm0tmKsIWCeJMt +Eu2Q07aTweYaFU+Ec6LmqMkV9flKFJ0oYacM94ILJWYQH2sdiGMLRrK2ttc6dGtlABZHEIAyDTj0 +60Km41HoCGGBtW/oj1sEDAOsZpqVFsl05qQU6QTAzyfkTjRD4FknQ4IBr0olqhU9Bm2RKcj6vzxk +LEJPeMx+N9xbEB8nhYVaB+LYgpGsre21jv1aHQMeRQpXM3x6hG2FhG9gg0Tog0iR0Ri/4RnyEd1K +3ED9AhWLkVPKQuJjCu0diLB9ifdBJ2O+ciMOLFgpOBR4XxTRn1KRCFEMjwSyPdwLhhixA2ilA3Fs +wEjWxvZax26tjsDiENL+gcCtPIZ0XE9DEDJEd7NKBaNYj1ldaDkC0ingbJNKOCs5hEKyBkpoqGeX +tGmd6jRtlVaJDsK8vOXpShMfVUca/35rsexzMVY6EofnD+Te1F7r2KeV7i8OICUVDZS/zw6Y7Auz +UJJ2QO5NI0JN48be+IHMQgnEHxZK3cXwPkpExYYmm+9kxnAYa0U3IkbR1RYokUYRNgxUk/R7YUcl +JKWh1pE4tGAg99b2Wsd+rY7BIkNkhKC+lMkHATPY91G0lrH0kZvIKFJWeCXTjkoojZh0kQFuOrFw +XjlxFBWyIwFjodacKZXzQguEKD7E3ReJ7y1GUFOGWkfi0IKB3Fs71Dr0a3UMDoZY3pvVEeuVEQ9W +RTxUEfFgNcRDlRBPTAXxAUJtzfZ7DLXVGm8ItfXLobZme7mz/3xJKpge90egGYD+EiX1hXLjTNM9 +0ck8MBT9ghaGhHAU89DRELX9dEwHVCg0IOWqOzj4V8aoa76x9u9EioriX4F4uS/YZEoZzEPp+SiT +poPEzCFGTK6c2BYTrHE6UtCI0FEAYkxA4HnBVAI2QzIDSCYwMEeuIHZPv0zWcU6FI66GiJFGnr0A +Qf6CT8WSkjKrFym21nAuJtmZe2sxN5lkEU6Z1Prk9AvQUC+YHENmllwYIwZMVuQfC1nPvLpGUtpq +NBCWbnhl0DHgCpBF5AVL/wisQX7rjG4Ax3EG/gegsKyGLC8eVN6nqlY3zvUKSSBS0moTp00qmiCv +DSTiL1ANbPEpVt2+ISahdsxQRtgCeFyIlX7BG5PA9lYCTX3BnDbygTX3POhO0zlFSrf8HcupmaEf +Yj8twswIjFwqKVOBvdWBRA4QUbLDjXcmzb4Q1EqI+VSqDLgVuKgsqNJmSD6ZJDkvaDAAnPwvfK/g +N3NCNuwtTBeCWkEIwfZSX7D4JjkVI6Eo00mUsa3xQJUyq0lSrXy20izqBbMJybGVc38UgWzFF9He +zl94Y9HkajF5jlGydsDsCSY7JoMTt7gUcpYP9K/i5DdF8H3I6UpmTVGnIQzulTwjqPp8wWTHKSsg +MRUfMF2tPA8YlBmjCUPJYtWrWf3GCHSC0j1yH8DzLXJuIlwvREMnTrIB8zYMN1q1C1sO4XeQO5eE +9UKMj2q1vEhwH3Wk6LJiJIPn1yQqhsg51xIhFUtbmUwpkaxWy77CkDerqOaZzWkAtJNiESLrTSSL +FNAI8hOFeED3fMFkzmqNySeoXaCuTKQuLf0U0FuVaLSXG5vI24tel+NEZAEjjpiYOWUP7BqYLIp0 +UpQsGYicR6IgYHxkGgfNYIQsQsxinZSEDGYRpK9n5/b223d8QK6YSQP3HMs+lWYQPhFM6bstcRMr +rBFCtioLTGRST1mgX/BicJVVcAyyhDGQrDVOlEruOxHIqN4oaD4Y2aeqFjxlfIGxbeiwgpWi2miH +V76hCFCG8SV+kNgDERRhjc0ytfFYxG6C1nK+ZGAoVrRiWO13XAHmVSOyyZJuIPP7GlLnBpVeAybO +IJ5oyKudqIIqkzSeI/aM1QJHBOPSmSK4SCF0EargOHMeoMJQokFQsQNIx1/4XkThIK1xSbIFWM6J +i7EHmScYbHuVX2UiXKgXrGzAbFR0SDNd40PSdtYMLlkyMWA0Z9E4A69Pq5LLc1UC+g5OY03GopFP +DCwNmE1F0qoC7IRjTULxVqDZBbHIE77SuBkxSeRzAdDodwJssLfs2aBxLFbwscDdIQ== + ]]> + <![CDATA[ + qzuWlZSDiI8hAYGSiRZwQtg+BvYSiY1C7NYdOeclybRtGDESUdg9RyBYzhlTk4wOEI0RLNSsQS9B +cb8kiSTdaxnRsBKSARE1SwOquwI3zHBab5jnVfQothSJAl16BeCc8QVFxQf2ksJkG8fMryQwPEiq +A/QrJXEWAgg8n+PV3bn67nWCZI4Gs5T+jogsHhbNk4TElNkrFs/xsh8bdYEt7NndJ1niJGu9/RjD +rc7CSq2U/2Chp0ESdq32XkbFsOQAfBRhyo6ZHJhXFEGbRD6KSS7xoEoqD0wsR0usUA43cUEm4QXI +Kcm+771lwZ9zkiJvt+LoaGKQbdsSdCTem5KGEpDKBRMAZR1UW1iR07H0QcXMkUcMjCm8nfyhkH0k +PmoziCGsfU5dtGZYeLzgXE0Nw1xYikhEkhYG42R+C+Bum8Srj0/wkFqAvc8yZfSUHU6y1jeBgvL7 +QgWMQA6LmTGFLKE+kxwdvGAKFclyAMpgYs0Uys7Crviggs+bq5xrRJNiVYW/BWscGzeMZn0GU7PQ +FjpPY4Ll8dCBKwPaccxrlsO8qpNYctyvyOG29vBN5Bo+MrHHaSbcMIEm6RgcGbvxSZJ7CgMJSdUR +yS90h5k/piwnt86o91rHR0dno9DYCMQAZsIz0TMNZ6DqwbJMK8RBLppOg93tPTqbHTDPF/nId7j+ +zMOPxCw57QnNBJ2VY89D7Vjoi/jGeZxJPAMYSUlGsjL48lYkKBg3YchhI28F0exZcZmF6RINzmk1 +auC9Fd9uFBfkZEMQlKidYxxX6Kxhc67g2uOwGDauIXq3vFZxWHaavlGzxwdEs8+yGXFMImK/5qJu +fnSyw3o5kUKxap0qlFqHiCIHQTJShf+LnCAbmUBU/L9MqVFBFqiSC8qaLLgRTiKQYWtk3hbVZgUb +HI1qov6tfQPwav75j6J1vLt7H8tWPjEWEcLzitueIWRNQGqnTE64XotEdFWXRZNK6kKtQGMebBJk +UBvVPU+QbJepC204Qo20o1i4CDIrBu7BssV0bkAO1CWryn0ExI2SHxRW8/ESGeQvTVPN+Sh6fjUw ++VNaRyGKUtkFSWmRh0ANzpDnJTvJSIy4zepIGIEuVfm9V9ommMA39wYwUaY4t7XfOnQq9bj3lQFA +zT7NjkCauAQGFjQ0kccHJWuTocbZ0u3GqFxwgTQsxyqRxoFKK7uQ/ywGS1a3SISsqOK9MZJzT38r +oh8CxtsonF0mUCSGp5oQK+iuKBTJuaU6gayXiGvgTSTTYmLnkJeICw1TcjsfY2AiLc1CCQPdkAtT +B4ZpVN5RLvOFO1VOHutU4uLzO7lQdjcicroo6FXWdFGUDR5HQBN0DORIqW1ecL2CNQYQE1XyjjBo +K2z0aYk2Nkup46vlIOnFSbA8XQ6WfJjv5M38av7fl6eHs7URsuziQIm9IHMWut0AC1JrviflM+ZT +uJvvH8aSFz6NebFsaSw4kCW+FYg18sktMvQuHNxZw2xI0BRfds9OEJUCz+mUiPoyiWuSIPnMsUaO +cC7ESJuLSAqkC8JbM8f/uKy2c9Y6Fc58LGpniymOMKyHE2+AmoKsbXlwAenaHQHXwfCfnFg5JHAU +uAdZPqhwtChixag45hWsHZQnxbOcJTjT2NTEPoecnysnymyOshdGHRxw81mxASuS5Fl8lpPIkeLo +vAfH0MiCb6qafsUQOPaCZwuc/X3kEInijEiEHApgAZm76IHVWclzawWV3SGaONKi5PRzqsF2ZIw4 +4C2I07xDSj5OPl44YyydotnTA853DDAAEl0Hu3dGXEDRePsF2egZhrIJFiGI+4gkEWb/GIlJskFS +1YTQUZY5HSghGBMtsRoAAuRyB9WNgnJuBBa+UNIm1jNH4SKS3rwOmVMAD4VU7XDAKx0PxWWOBUc8 +VRoABh9Bv7vaQXlLSgzwyGpqSh5C8OV60EBiFiKmTJZXQNoqhL9m+bmodxomb1H0E85oEsjycCCm +BS/5ozRHBqmaMMObZG8CiwvlioTdvmeMZvh3DN0uovGQZHqFgiSY2FPvBtMrYP8b2B5KkQY4K5te +NIqznQkYH7PhKdBJkhkAiLKSQilprqxK2iMmZs5c3rPZJYHbd4beKz+Kkm47p7nfJRqwET0lptAR +iOhVBBrkGmUKEQuIqGrWEeApBFtJqUV3IufoYYFycRNRdm1YTVXMMpxR2AHMbu07LCdHc6k7aztw +HkYiGNa8JjGjDFaudCxXSn6IW6mrPd8SZH3FFe8NqetJGokVzWbeUES4yBiksQAyolyTJMg42q1Z +aNQi9S7PAgeKhSS6HUhHgzo+lzossBVLiQOO4BUljUcr9oTdYwVxBITjTJMONnEjCmaWyRtR8XJQ +yU26Q7RveOmCpeTaAEHsrLQg4oEfiFYiUQkmjkSawW3PaxrtKopV1DeQWxOsBC/ae/CtYtHFEZA3 +gkoEI0mMCK4JiLEaFv4wtlLcNoOVBLEsgCJcMkWKgV5L3DGdvC1Ea04SzO4pySbyB4UUhr3I8HEg +eyuOJ5KDGjqt+LMarQZ2MEqQjvB7OTB/y+w6Cv45Amqr6apxwjAQvxXsSeM565jt1hvMuujYBhes +szp+ZCmmlBNZBkDyy3YLFqh0NLdF6OHwQTLvQrR+clKBYSstIFE5QWC1um2geUgGoJv2nDjkgKVF +EoeIPQTNahxZp4mWcVzFYonvhV6rgBIGYYWgxpLkP2F8fsd2hewJjGdQINOYQGpwMLsmjTd2QKpN +qGpBYpMQ5fGkJQ6o/MpizlHkDDQHiCqToS9a6zKdoTF7nmWrHuuzgSimRsgNkcRdzitKR+AkZKRJ +jURCZO9RDQmSlDWxa/aquOFw3h10gC+ZI5aDIK9CiiTRDnV3P0yhHDlCm7M+IsZFLuwVUVkPCrAR +prJzD557d1hDHoPEkgf20QIwWYb5zOrUDykxcmBdLhraxXW6LWfW5brM3KYyzjYQg4Cwc+AlCs0u +q4q9iNYPRWwNAuB+gXrKVwmtCF4c8LI4WFnBdkdP+cSK6/LcsZmSd8LCSeLwKGBSEd2sZ6hiOAqg +9o76Txk70DJELWKRBElJEn4g7ggi5gFZlKvANSlgHKH7GHnFiCwP4jP4m1IFwHaTGBnF4xWyMVnW +bwsDhPyT3rHLrAtJXmAjJ4FXw+QjTGRbHOi7go5JFKBUTfEAL9B5y1EwtTJ4i6M5jvcq+IzlFNNI +7NDDRl4ghvgGncTBiRqtVHGWZOgHsFFGQa8BQBHDFlFGtwe2ayLbQ0W3BYjExXHgFvJCeYWUzRHI +pgjMS6Lmm+6u4OnEjWGug8Orp3TfGBIruiN4PiqEgMgB+jj/UJIBojc56R5WMbdze799EUcBSUkg +eDor+wINSkqYEUDkkEIxOClpfhYAHyRbObgYMRYlZCwxuKzgzjycRzxudyHBC1BlOuvnkyCqwLGV +4p3hRlTPH7DOFZUlUKtkroLTrOE+GYm5lxQfQfyb9DhJdvLUgSuSNqloJiQg0rG7EZ10H2Yznubg +tXiWpWEuk9Yfzuq+g6VZ0tiCO4gAikDwQ/IyLfg0hREREpfEaSCwAjb+hwG1Esmegx8w+QwRcT9g +MzvrCII4RwtRKmAzF5AThQBBdH5ko7Vl0zvQiliorCDCAFn024n43hccnJ+EqMCl7CwC9g8FTQD/ +PjF6i7E3AQsWR100NnzBjm04VaG8F21ZNhR5yPoQKw5klJKNGCaDHiwrZCh7VwGgAlD7YPxQIcWw +c56SeLFuE485rM0EMR0BFbwj846oMwOBxHtLRnFWc6MzN8r5mXW7ll1V4UyAr6SrI1FydVFWDdpw +Ef4BE3UEJxkmyH6EalwIsKC1XKUCUNuJWc08p2yzIHlGL7jPAu9VSUoXeZocd8h9ShX1SVIiSapd +MNXRoQa8nMBhSqwPpWh0TChJdtNcWI0hEl4lhQrrQIqEgoF+sQrENEeTgpaliO+TyU5EXBcsWwBT +6sj9cmtQeQKIFKwBMC4EDwZyZXHszYSZHA/Y1MmxtUXRI1FwJLDPEiSrJ+JWk24JYYiGdBAk+iIU +e4riAGdL4A01iXq/6BZRep56hI3nvTsTl6dmybrxklkMrdA86yEDrHqqOc7KCfdyDjnY54tsR072 +UzDdWd5kUIsgQ0BocAixINZxQc8AJifnHEIYi0QcQjgqODTJPhW6RB087z2KvJ7EjAgMtWQxcQR8 +ociPR695jN5MQ3rxNi/Qhoz8XPGVQHlPMOXAu8WZKUl8F2BEeI3KzMS6s+lwcJi3MtNoW/IyZd2A +QxQZ8ATSFGCsXUWEFXVzTZy2EcmZ2ZFlnRVUKinAYB/goFRH6XBEQ8qTE9FMWZdnBOIq6zYFEmP2 +zM+i+CcAmVRB6NFW1POVewWaskrpuaF+dpkHE52k7UKvNXIxQcuYeEyHypI2ZwYCrWeIHEaFO9oB +P19QQX1XRQFScGRDuGMNLWo4PXsc4OlL1GuNoKigcqv4GRncO+i+ti4EBdjaDuObFYU52CL5VK3P +7FzAaXJAi0OrGFWhQUCLILhSk9AqnFgmF5xCubCjJOdNSdJWYsK7HdFPeclDB/OTW0BHGCRKxmdQ +fBjWUHa8G2htYttbJJZHGZNJ6eZELYAKRifJpSsEJu+IxdVJ1sNio2REDZKdeciSyvHezpHPlpRn +zY7vQcyV1zvtZOxTtbIVHmztK0SKJ5MrGVAKpuN1jD7KkKQQ7YbYnUlhNdD6ZtkiVHFzJUQLNP+T +WidJOtkqikBIw0wMH4lFwEZrxs2JagbHG3Lqqs+zEe4eJTQ+C3OHFKqM8hgJJ5Na4Cl/IDNy2UkF +tQFWs5VKC2Y2BknVRNR7Ug2alSQ5STuNRJbWLfkS0K7LYmGiZJUHOjqF5X2jalpw/6/oYpiMCqHo +CYbwf4kTe0sVGt2djKJMoa+kVKFRa5kSfmFzeXYSNIgoYKGDMQcFvMO5SPw8qVdKZJDb5MYK9Dzq +bRLAPg6fBK9dS3pxCDEt4tmG7rPSCyfpXa04HmOCZSu5IvnghN0lXX0mc1sfBvZh74IVJaX3rCtV +bxMIo0WxxgFyq+kTKolSyxVSDpNs5EiIQhVqFXdAmdRezo7Pvt9/v6gYjHuCqetgDHAVsqyLKzNw +fDxFfiMUhq5CR2sARFEUNRncBjQ9lW32Vl0dkkMJ0TkFJGzEtlOw2BrI9EgVgMrVSEpFr84KJGMC +F6uyO+OIkkEnDisgcPJTTAfDXsWQTS8xI0enDyZSai3QuJH5SvrAB8na9zLwjiNnPdigZDqIBQwh +C5IC9MCK8wwDWdReCFJGEmxTlE2EGBRw0g5zh6JO8NTCSOW4NxZWnUi62YrZXkX2yD4MjZAgJivI +t0AkVTWIOsZVhpHhV4TnedCt9CpYUwKH75QHMwSdvfnohrWi62vyFFbcK2irglmEuCwDPyKROdme +iRizojkissQrLzSSFhO4F29MVVQgiUUbmpPZe+Z9GGveeQGfFpN5Lu4OTpSTQLPqAw== + ]]> + <![CDATA[ + wf5ZQBywjgCekVhXzzyL6d4js8Tkk/Aj9sYGIiyFHa2BcphD90Kwkn1YRFzwAlZPDtzIgIaSWG8D +z8DkUX3BNPLfS4HEByKS/RJeGsoEfRya3GRFdjbiYUFWYBBzdXideMqBH3kZR7IwEkWV8BV8F3Sm +KBo0gC+DUeKdaJSlCu9kIRXG8qx44mVNtUg0MBCU2xkzAtVxh4pBrNGGMSsrnl0k2Mayo7rnXQBs +Faa4YU6JucRrLhCQwChwCl2aohI5H60qFaQf0Wc2GXFmJ0Sa5QTyVfxeEcmdc2lagi3pjIa6Afat +Sl4N+DwyZXkx+eCYEayECxQIc9328JjpX28Di3VXMe4OLjJrhL2HinoPE/QeKuY9VMh7sIj3YAHv +geLdQ4W7B4p2DxbsHizWfQihTnM6RFp57JHrKAdFJG9dDqV2gxsm4jUXai6Otygu2yzwJOyxfy6p +TBw7M4iXGcle7F8QSI6gF5ZEWExJtx05QaJ2ivctUg86Q6Gz+r5KZYN9YHhZtBOywd2UoCSSEjNF ++kjxEjz72BRBaIGTfRVwNnYowwokK243QOB8iezm5DILPJYC2VDfoKpIUKUGtqK6MU05Gh6ItzBk +GQC7OMGY8dmoJzcZ3MBNrqe9qWSoZR/1KinJOS4JPMRzEScXSiuJKiPQrYhXL8U1oxEpFTnbU0gv +8Sx1iElGrBC5G2EKxpCx0s6IW3MicSR3Z/hC6ZZIXiy2F+e2JhBWgya+YrRWEO+9JlpngTMMSjdg +LpEUdF7T7kAEPOWAAEbKSG4wcKRdSmQvE41LJvVWY68iMYCp2DuW9tD2Ru+FEGqA5mpX+XBoaDJ9 +y3GUuBpoqk334v2H5dUKFgW5OoF6SsNJyCUTaCJuVBH+LKn4acswoiIG2bg4gclgRajt6aIhq0Jh +ho3hoge8YUYRwdUnvG13kQZUNjHLjmMw9rkEp4UJoxx2MfF2sBI6BS/UJ3EhIXcbIAbZbZHMu0Wm +bMiLxMLgxugw5ETljLYQKV984PMNuwBjJnJBruJwTKQltot7gRhHjyOaZsU+F2cRx4YQioVRNyY2 +VmNSOO/18azc1qRXaHSpjg0JJmtELCfXAnSmEp0KG+ztAjPPSGrHnGsRZxE1mmCYOQqwMQ6OXJ2c +ssYfsrO2yYojiUQBRaia86oWcSy3KlpQ/mVCL4jiWYKxNOTZA4aiwYKLCBjsWR7lWSKRerLX8/4R +0ZQDBqqM4db7W7rTREqJREiQrduoXIhwhDKk5WzEvhORpQf1COBDLMGojLngOh+pbJenTSckwbIj +hoHOZ+COLzsR8QH0NBPZCXS/lV0LW1vl/CLGNpASqvIBdnm1hVLZy1bGUQKc3gVpOXHMRMe/gkdF +0dwmJ2ct9oHsORzhPifajaC+vdUKIvhgv8PlyW7EnDYWuFh7Z+zEjAHkshOR1gUFqsD4RkbRzqwE +FuKexbBkoKIWUNJqNNoK0pw7cYwUz4lC84aInPMCbNxFU8hVcgmmDUqs+ZDXOLABynAAVJW4Xdid +1JgLhpbC2gtRoaDxJYiJvhoRKA1FrCYQOmxPwSg8PypILXSRboWMUUF2slzktI2YflIe3TmRLJYi +3ElJQ+HEIYiSfrBAj5Y4cU6mNFEkezNeEYxVkI2IgfzgtbiucxD0L3hHuuukVGUGjxVE2Z5qlC2r +qv0rkEsv7TrcAABDI9YHp4fE6qpCaR5oL6oaSl8h3o07xi5xeNDytHVw6msi4jmcTg9RkQQNZwDD +IXSUfAqI1bNDh2GXFDTlyAHK2QF0ipNpwD7DubONEbd9fN/BrhDRJbtX4NjVg0//2ILIjhpO0Fq1 +AdmogzXG7dJ8ywrWjztvthLd37Hnu6tVk5Z7lJdCd3KuANzNGdhHPTLo+YZd1dCVXRrA5zpUkWhk +FGNSgFYyavwR6dTgN02SCyANhRHocjKaQS0mAZOxgg/D6R4KBWqqBdVmwQ6NGhxq0XiESehNjxj1 +4t9fiu9Pp4BfzLAbe7yh5XA2Dc0ERI3CcUJe1yBiTGASBAcbmuNn0ZxAl2/H4U8QsRwtbQK2jYvs +R5TUjrw5MIiHsNNIgyYKDQv8Tz06KCULbBu42x0zuU161k5whga4NURRjBtRkJUqQUxOUF275g1V +PUGVUAxG6AZujFZ7Hgj0aJQKDLsylx4mLa5R6P7PfvaoQArsiYyuzFJBSFFDJPVkRq45tCGpBqpt +F4U2pAhqY90PUZOL+YO9HONiEehEW6sQjZUAGtStyX6SyL8S0RmqnMMw8TKelyR/DOxobInO1Wpp +huuDiIvKQohR4Iwi3r0o1VfxuGqLM2oFEioF/fNyLye8d12yMSx40A5V+skuWHZxkMBbjBZzvBml +HqGbSCscWcnP+xY57aYgboAUZUA6WphqUcrzZgrSOsgIUgF68wN/LcyJEahRFO5tRckOKboZS4ld +1YxrRYsuXBuj8CJrsHOXJ0SVBTGx1unrp0gvVJcn0cOyH2syfSWrPwzcmfX1B9nNje6bGKIceYOT +KZVJb4DtxwSuwgi8yXwsimJuKpzRmQ6AVUVjzxt0OzIm3crkWNVDt1FeD7wThcKKehjVyufa5OOw +FxLmSAKjv9F76RiTUm9ArwAUJ6kfDmyN4o2SklQglhA+UvCdfLqxQ0pprFdgeIbwdwo0QQ+RmvR4 +Esj6ZGiHlQowyJEclJOVaH1KgE24Ak66YDhjIaPByUtIxTDYgXf6wth9CQEkvGwnHdsS46pUnSa5 +ayUiX7KBgnpR4QcENhWiFiXzDZLJRsCAXEKUYLMqthbwNJWwsn66yiqQu27rg5M5hwhbweAEa6Tn +w1Ea0WEwPxaya7T8UAdi4KikZIOatzwGDcDRxSE8De1FmEyCAQ3ZudAzKjTZYglZ1i6glJP3Juwn +eFA+ZjJKnLjLyJkwMDQhRjJ5Vlx4yXEPhzcJ+6qeYcIRSsvKKcj7KtE2IctuRKgPFOpsB8eoyKHC +2agVqEfASCxedRoVHUnU0bMZxWKBNzonQkdgCI1rMUl2s5QrB/Mh39HtkMLhwC9HViPgv3Hgow2q +6CMkDZRllZmp6Q5YEMMYo7hdGKA0ceAjWt0sxyVgCkI9nbnKcQGJHbNgj6qRvfvEq8dSfDPuJgth +2QwqBJtUtmIEE6dcR5B1TCTPLtyjfGfHGIZMjCPpvYyFARuSd+L0yf76IEI72/czdqJPoZuvjPKo +If2HgsyAQk7j3mDzYAujg/B/Od6QBhbNvVEc5sQNkBstO1I3wHZNafCiUROjpcTXkT4udzUdTSEk +B7WoBZedHISixuIR0H7i9GSyITEWBtpWgthW2AwBO5LwmIRyCO1IVadgZosBKuVkCmTZ5Rw51jOD +jGIEWtDVGMq7nigkl2k2skRQRUiDG3mL6eIMEC1RxQKDpTOb9hXvoAg4GLjqh85LMZ4LN6MYtJmE +DYKMSE4K5LwPnt02Do6VbEeOPbqxSKQCxCdlpZHuDfid7WcS8hQjeJlatZ2Fc1EK8gQIAzmxLFg0 +7hsYdPUMfKUJARJxcoT77oAvhv0+SNcrGlrSMkaEAy9i5DDWsqef5KavEN2aaCNRt1SkRiuRamIU +AiKZDmrPVS3x8Wiqcn0XpM0RkUP0SQQ4BNwzFG2+4I5WQo3S8q6wl40RC3qkRUgxr31LMIl0a5FO +DbwTkXqOUXT5YORJPRcYB4FQX2zHla7iaE0KNfV1B3kKBwkMX+LhGOTgB2c0YWVeTgsO1XBJNyOO +Qnd4sBYHD1a+gbohyHEnCGqF9cNewl7xcAgy6tTQDvueD0FW7fs0w2EzQrw03Qw5XtqT5ZiIfN5b +3Iw4vbVlK0J30WTPT7XHguOo4N6xngvYM8kVhj1Z9GjDCFAZzxi8v5DqBlyTvYrbgkRnR07oOFwa +JDhv1B4qKIpVMz2iopP3F+Quupc6F2WLquozQ9wJT1EDsUgwSy39cMtheggBrKpOkww7oKiu07La +PnFL+9kuEtNLocqmQzoK5I6le9wEEeJRbNCTpSUh2mnUB2wlWc4ReIyR/a2KlV2ddKtRp3bQv0XZ +N6so39oiEGlCKoWzjRtUxXoO4hh43Iq8bFvdEkr2TbpRz5aeo0xxK+KAd1VE0OGoyP7EfuK4l8bO +kThMETqrij5WCCWn2V5BRUwMNeGqc1q+sC0PjBR8Jzqz0buSx4MLceUIr6A4EkRmp/zMbt5I9Bwj +ppJ5klAFMBD1AVR8/MQ5fblT5HxvuoiXGFZ4IRNahyymyD0jYny0Io6pNSXToRhNROjeJTtK1Gzq +yj2TZlLOgiTSdxkzWG3htXBiVkYNJh5IyjPE1BXgSMQ0tWwjsno2CRLuDwHLuUOTcfAzY6IS0XGO +JBD8QgcRcAqQgZOJiZikHviVKVqe7FEQMax4Z+BUImBW8nBSo0QKGRH/w2A8u3Jigk0tnBNvSOpX +FljRrB4GNNMJqww3JAw7g/3obl6pzAqXfFKp9nt7pLJEeF9/VC5+b29UJt/fF5Vew/09UYV6bz9U +Zln390Jl8n19UJl8fw9UGe37+p+KhHJf71PeX+7te0r33t/zlKWWe/udsoB0b69Tpt7f55TID/A4 +5d7e29+UZtADvE2ZfH9fUybf29P0Q/iZfojcJ/F95D4Zc5lcl/tkf+mjz47LnWXkOQortopHSTuh +pfMYu1Kg2Qo9ar+9W5zy9kp2FIzwczwbUDLU3H102m07vmFXzypQBbh/CveJ5DNEJzGQbHZkAwzO +LZ7ECkcFk+GKDyJg4nSMeoV2B+Ve3rMjhRPYpkSQRngQC4HVTFGChimfQnf9ijkzhE20fftQgacy +wBOc9hkPLROgmvQg8wktkxmTWhAZtTgPAZ+FfGoQLKZ0K4skrYioguYRJD8UgJDp+x+lcYmImyM6 +MWyW5zBGFEiZf1M2ENfdGCr7JiAxqssCBAVXTkNqWAOEyeEnpAGtksQtk7MxbPlFrL0AOZ8Cu4xo +4kAACyKPRquY6GBuI6SFNuQh246A0IQx0Yo6SVJYPNvtDCs6ETfPCNSKnkLgj5qZ0WtKliz+DuiG +EhXsktNCAMJQ7GJ4sSzqoODLQ0qnW0yDW2VI2bxhSVQ74OnjKzXf0jhSoyzZmBAYhYmgGKmM44sJ +E6j/WTzVADbICNJCsIzUEBR+wpCYgoC9RcAc86AT5lwXAHRAywc2z2g1aWGlqFggqk4QGhjIIxTI +RWDXGISnbbSMKoMj7UX9h5YgnT7s/5cFUB5qJV9buFd0qrg9q1axQ2BUOv4hGeGExpMEqiWNSqCM +Ow0KyBz6QZRzCIFrRlIZHpEzOAxbUxDw6SrbDoNEhy6xkXFobi2a7COIlRr9LbIkdCgCCQmR6D6z +2qNQHiaMxCe1B+ja6fmYLISOrJA3tyPKR0l9CSdRiVkXvFecBIaBxOBYndmpN7jScQOKlZDtECXq +HzW/ZchbBXAv7NmCUdaCOwCZTdBEVzrGO6S6QakK0lUwsJBJcjpGwEdNPwtyFa3X/A== + ]]> + <![CDATA[ + PDMSXNR8K3AuCAIBQ3iGgVElxF0lZTwBwElPPBIiWdHIKVqOIE6gQ0GQgkPUDi9h4oAgwLGwing9 +hNiEaUZDB5JiAVBP4kAVyKsoHBABt/hZkOIiaT5SJ0RUWO/wBEgMf+k0gSxgPJBfpiXfHmhpFfEL +4fqN4OUSuiGhZwrgV6SjfqG8Vllg0FhSBJcZqy6wTu+t3acBvETFoqk+9JnmLQWMex1BBNngrbFY +AcLLkY1ojDCI4HSMBuJIZ0HPh7xYog3NIYlzVWGXnaA4VDAWpYi8UI24TFk6E5OPZBLMOOsYjKSd ++2QCYdYHFAxU/kV4PHqUM3rgrqrbhqTsqaePId22Iz+IHZ6BMbFPTY0dP9szuCB6XrGrcWYbLaqk +ZP5SLimXutMkhBAxQkuUpCCVtZuExFi7VYYQbQH3BaFOiNhEPwSDYYmdGB2h/EK0/KBICmKu9U7x +SDFHCU5J3wFsYH0RCIErFIakZjGKYHC5c2D0ohMzgFew5iUp8GDr9ZbmKXYM986qF4z46ujoDhx7 +GR4d9MMCsWZTz+fO7hKgO2PHBkgmXtiaI9YtzIfhWKOGEK20FUXyH0exQyEOGIsAQSYkU4MV1DTg +Q9l2pTiB8SHZGo2cIu1pZfUV7xiavnZwhQ6chC1wYBOfumthrBjUWrDMR6JQITYgskQk9TfCynD/ +YXNyApfsJJHp4vAdUF6EzK4LhPsEL0PGlVkhgj1lGVfOVgFeimzOhmw4ghTTA6pQQkxW9kJ2oA2K +nBa6q20kzL6ieZSoAtggK+9lEouCNmbPFSAeLBEjHfs97qkiIbOJGqHP2CkWFGbcfNE7wXNEP2CL +4oGgQ4VArImADtxFck6JY4yihKDpMomxAwS+EjhMDbMykjyVCA8sd7VJJmGfNM0xehXSyL+PxCmB +GGN3G+g9R7cARFng3qOMB4dr4gYkeiK6tPEad8W7MZA7TAhitpBhSE4ugWYuQUJ255SemqUSWj/V +yo7RwMNCUCsxmbMrC3HqHMTYSFVUNwjAkwsfHlLIsnEG3vn5kLTDgguHE8Em2xGj+r05qdvW4hAc +3A97y5EHNwUDgHpcXGM48R9E50W1G7SFx76aauNDpb+AbMXUU4dYxyFwalqPqjEOo2aT/ZQAUViC +RlFfxeDBvqcZ0e3Gk7ZJ2LLG4Lk6+J3nKNUadRsv4tuDWnvmPJSKEHxe1ZRgBPIVdzbmEOB/SIjI +IO0FcTsn/0UgdtaLlg3eAzGQUZpPuqakZ5PVF7AMzn8LSP4/vZ3Pjw7ezg7PJtsHB/Pz8yVwfkpC +QnoSwuQPmJCbLslKkkGbfbd4Y4A+pNMeHiAkQ0knp8oCMMDKiQq3KCQ5sJWSBxrJ/yCV+IFKmQUr +h5EOFWAeRlow+qSBJo3CWpVMsk4qPZOjEadkTgWpj8LX74KbDK1SGvEy7oFSKRuddHaooI9Kf9JI +40btrB/XF21WXEpA+Y9b8A4zLur2ZtprapMifr9/eDT/Df2K0+Pb2fnF/GzrM1D+/fl3W//B75Uw +PXFy+sl/TtoRH+fCn99edQeQ6C76WdpMsBNb6It2ma1nz/CJu7OL2W8mbW0Vu/Xnr67VFd74uUvp +6f7yv1J6ur++xOM9+9deenVsr/p3eczvNvZPrd8fsvTtx3j5382Y3+6zOD6bMX8fpa8fuc2YP2bp +243cZswfo/TdRu5xx/xhLf/0St9v5B5nzB/W8k+t9NXr+/2P+ac7avcrfTNPfX9j/rCWf3qlb7+P +Pf6YP6zln17pu8sODx/zx2n5p1v6Q4z5+2n5p1v68cf89s+++vPrLH3/c8ntOMVT7ffHKP3ws+Dt +OMZT6/fHKL05f3+40o93/t7ILbctvRnzD1X64efvzZjf9nP/s+CHGPPbfz6FMb/7XPuQY373z1Ma +88db3x9izO//+cfUp9792YufT2XMP+Q+9vAxv/7zVMd8Izu8/9JPQXb4dfPzp9HvX/eYP81+/zrH +/Gn3+9cx5o/f76tr/hTHnD6PM+aP1+/lz69rntPnPmP+Pvp987Pe37Pf/5gvfj7OueT2z/5HHfOn +8L4fXvpjjPndW/4xn33z51OSU29u+cOffbvPP86YX81TH+/Zt/u8nzF/ivx8dcwf79l3+zz1s8Hj +85bHfPb9Pk/tbPD+99BPc8wfvr4/xJhf3eqHPntjs7jbWD/1Mf+0eeqHeN/3+3wc+9j9+73Y8puf +8XHW2FNY3+s/t9H1XF/6us/H3Eue9hp7f6V/XWPeP5sxv8+/d7FZrH42Y36ff29js7j6sxnz+/z7 +lEftYaWf0pjfreXXf55y6Y8x5o/T8l9P6X8U2eFepS1fj/tsa7zJZrdduf1mH7HlDkDMXfTFFxct +PMVdWXC19NUfZ6bOBp9KqaWmErxzZsf4R2i5NdnZGKuZ1l2/66fb1cZtV1rtD225NXt+p0x3dvam ++2k/7U13Xd2L1bUnPnDM3dYz68N0O+/F/e39vXbt7NtdU3b8jtl74GxpwxzN9l5r8y4naJjuxe0U +ptbRiNy75Vjz1rPr6r53yx2PR9qftlqvGI97tZze4u5ue2P7rtWeF9/jbatZ+2yae9PtsLuzt7u7 +O925au7do+Vtfbi97KY7uzDmJe2HQGvmrhWtfXawNebtNLXZe2/D1ev8zi1vsyTs173tEHct7KHp +9mN847NhlmzXut0a7rIp19d8p5bDLNkt21NXtv0uzLlH5KnWFJfTNjS8rZRggnEL18r+cIdn+/Ye +47bddnHqkk022NB4S+DLtZ6k263MNc/GN7ltp6GEuBP2w55eu6H4aMvqu73tboCr3e7sTPe3S92r +O3UK19az9nO77Kept22m33He8LOd2fd7ZX9nZ9dO22KUum+q+YaW445rjdtp20CYltb96TAiu1vP +rhqRGz6w38JusO+y222cxG37uOsyvcnbvcUrWu4b/2iF43ZraWttW5EmZjs1cXHutdJ3azHUW2Jp +G/m0tLkWXdyubdNN2zevyBtaDjXXuFPD1LTKcghhu0xxRe5Z+HZx1bRRu2r9LH0ctrjVu71XS6p+ +31nX3liabk/rfgQ5Zxztfvk27lfwRW458H8XC9Yc23vbbWXaYmwrMkxBgJourJpxtlQ/bRVPr3yr +vq2Q1vOpqaXVW5uk55G2XXe2nu2YqV+Y2XDt4LXbZjnkUrhqb4P3XVxKeTu3PWXqdrFm4n+A6j3d +Nq2OnYV6d1uXwnba3p+2MW+dbat37S4E7QulrY+yByjjfI81yVafQw17rd8LIxFNLAmAl/dL2N7d +zqn9umYOwSjHlNsuuLO9t8T5XVsZe9Ytvblop97HtlZjbu/dtXcBzw5r2k18f2/HbEOexbzwPcyr +5bnm2h37HrI6u9QmatrbLle0m3hcYzbwbL9n9m/kw9bs+lLcdpM5w350ZR/aHYCfL7cbOHNbz200 +dm5adTpTdQ+KztdU2/vv7e7lseb2xmH33jXxVvw82t24u+3rTmMtOaQ2A6DdbVW10rXVH7n+O+3e +2HJq9RSa3XbOxgravC2N1+z61vK2bgPz28XdG0f6hpbDLqElrG29hplbGt8pKcXtrWduv60MO4zc +dpMZ7dIMWffxts3UaNsYtiWD41txve3txGnablzB71vDc4F277D4Hq9seW/JLreEuERt3GCv1ux8 +NLvKz3X+VUikG65tt+f+w/qWEYRVZ8Je2k1NCvDZVt3bSKLenu5u7w8cZH3LvWlcsb1BWCXtjTFX +co1LNl7vYMXp3jac5mptS6BW5XyrHAHqbd+3+0zZBo7USksPgSdAaz32on9kH4jKrSG9nudd0OBq +96bY0HbiXbwrtN3BLXHSq2QH3b3gXaRpYye59W4f538x+zZDyq40rQXr3emnhFusMam7bSjb+206 +7bQ1vNfqb5JC4y1tNqTt0jhR2y2g5nr7U8JCy8t0b6fxyu1Y2nyM7a21pba33dbIdi6NiC32K6Vv +bnmJrdNNDPE7tvHZdjLAOtsaq3tlO6V2rLF3P9doy61vo5F2CvBDg/tfW3fR+t3r9Be3aDm8d3xr +fjds43617XcgN7GBU01eMyvv0nKea23v8iprlJUZe7+WG7Owd438/fYni61nz/ZO3gBq/Naff0/I +9e1vxq3fx9wFmKuR8xFYvJazMUKypxImf92iZBuGszQFSk5+zIk5UoqUJ6v6GCdHnCsPU7UjGbMS +HXHWGEpPXTiTyhHn5XOxcr699qdv5FdDZoXFJs62DCR28tgqyIaROE1TfF4h88PxEtm3lnBu6Qp5 +iwPnnrJpIumgbCdJkrNa6+J9kfIjjxWORH645KgScnnufJAcV1SnM5TMY3y40CTVCTez3zp2SOtc +03nMkQQDB1mJjNU317ZFTjCLObOOtzjtGr25RCmeKD8ZJ86j/K9lkQjZDivnqhnJpqfiSpzTGxLM +uVx14DETiRIlCRLs1ov3QpZDm8NCrSNxaMFILpzLCxMylsxZnDSzU5bMSJA9BDJK7rQZtjaXrJl8 ++dXJxeQzSAUyOTg9fnd6efJmcg4ZYyfHp2/GTLELq8M+9wnTshhP6cKOOVlJpORaQoapPeYgWf3t +2feX7f8rVhx8sW7NIX3dqsMv1qw7oq9Zec++h5HB1Qej8Q3+XFqBjSRrkBq0ZhUuf3HXdUhD8ICV +SBU8YC3KWD9gNT77/jWOHw6mrkl5uyurkr54yLrEGh62MqnbD1qbNBsfsjppFj5sfT77XlcoDeya +NUqdXbNKqQF/bNvQZ388OZkdz99MclxZs2syCOE++/2/n568PDs8uTg8+fGLL4bEMeMXW//+Dr4p +9M3Lo8v285vX/zU/uJA009Ozy/O3k69nJ7Mf52eTb87ezM8+v/67CX25Mzs6OvzxbPbu7eEB3/mH +09OjLyd+8u5i8i2M2ZfX3Pr55Iutz/D+BPfvH80uJtfdj7e299Hu/ebn2dF4K1a1/n4n999ct4vt +XqyKGn9ziWik5XLrq4PZRRN+8C6sSm6dtjE8mU1ezGc/rLtXbvt29uZw1qbeq4vZ2XAfVrVy8+8v +j2cnk/35fO3j5a79o18gIfm03XY0/3KCVV1991cnP01evUP6dZXCbbtY1dnpO7mxLaRvTihr+XDr +y/nJweHR9ffs0FjNzg5OZzfcun/5Zn7tHfQGd9tSbo28vq7fzY5mf/vl6ntoirYbXx2cnR4dQVcm +383ODmevj+btVZ78ePFWCr/EMTpZ85C2Ur+4oKq+aL9Pdmfnb9tCf3VxdvrT/Obi38x+WroJq1o3 +0KdHv5zMz9v8ubnWnaPZ+fnhAVbVR/zq+1/Njk9bvZ9PnhM3aR1Z4CWPzJOuWHGN93QGAH+ArFAn +NuJ/3uD/jgSJ65p6vyd3VoKPzhObJyHCf/DA9/VY5ErMkKjLZhJaTw39/z4f3fk4j3XUx5b2j3t/ +T+6MFZ/c+puM5DFr/5n39Ni+EdFjJwVGu/1X8b9b9PYxF8Eq322tGvYRbOOXIjjQXQ== + ]]> + <![CDATA[ + vIIntm1OkCqy/Z+aRBYtJrB1MdS2q0HSQE8Z6DDbJHFMq4dyG5vcBBlUIeVizY6+uOdor+3Fwp50 +bT8CdSQ2kc3jLylA3l1MhunbWYJ6kwyIj0M/WoFJk8Qy5MKzz1uB9sPhHzBzCx0zHrVLfTOm/vz7 +/K/ai2SwF3h9yWccMwy4TDDz2I3Cbbrt0NcNcea2QYLo6mzM469f0mBWHtWEQxzaaCZLQ5soUSnm +HLSTdh559IEdJJLFbkQaSmoiZkqtOFWfh8Q/Jl/gRGgNxISHhl8/tA9myqM2c5TcFttpHU1SV2Ap +ypDyiDr6BRrKVHMb9vaYfGadbNR6sMPiGHVmIr3xX07kotHnE7vq9O45qFe0guW4pUa4sRGw/Nt0 +de+9LSB6LjWkftjRIIF1qQ3WfthGkEDPjRjZ3IduyNVS+ZrGuWHOdF488bdv4GOuuaskbVh3JJqv +LLwFrn0FGV/Byjd0ehzfEPCahDvoIt8PNVhb6MWZR3hx13STjkWrJ6Lreg0s/8srvwQ+O3yDvR6/ +9iuz8mHi6zWda4e2desjfLlMicP7oLFv8pjIOtaA2EN71Yd4Jf0Aee1LqNe8AtP741S0hMzUuEfD +J3+QrtB59dpuuKu+CKtfqP7lRPa/iCIGiNYLIja+sTv28M58pdI3jSu+uvjlaH6+9eW/nZz+9QT/ +mPym9fkLOKheXpwfvpnLqmoCaevR5F+2vtw+uDj8eS43f7nD6s39wyOQaX6DG//hyYRuIOrnxC35 +ln9ZV6iJPQc/3bXQLZ40nTVe2Eu0346uLzCqclunTy++nR+cnr1pL7N9CcW555P1Zr9bJk/HvN1v +2tPmP0x+O9mafKY1g264NWja5uHksz+ez/d+np988+YNkH87wdZNfrs1+fLl7OxiTf+mR/OTNw/o +IJbvPTS36kzvRS9+RXuvaTpNtGvb7vD3o2/O+N6bekO39e60cW9sEnhk4oXXdi44yAYL/+CBsP3j +bMJ/YlwxNts2CraNglsdBbhr4ZUOT7/l29s5PXlzeXhxRe9vN4yPPAOEBz3iDNj6cu9v84NLaAJ+ +gWWXedD06HI++d3p6VNgPB9+ot6WiXy4GffeGemd+Ob0tbLe6ds22mr++vGsHaPn7Rgd4+dwKPbW +OPjXVVcmX0T3HDRY9rmtIfMT6ef0x1bhdPpwhnzNkJHQAeqUyau3szenf/0cH96H7LOF776kfb59 +O+cVsPT9Hw4vjm6cWk1c+nY+ay1/e3r2989Hws/zswsgWDZWvj46ebNww+ujyzO8wRghvZmd/cRl +iHD6bnbABBqgd7PDs1vOPRoP0kzvnJ6dzM/OV0Zk6ds1Y7J8x61GxUbpAMwXMLV9jN31dlP+8Xnr +zoxu+MPs3ZMQ7D6OIGB89Kj9qdFVehvPK0oAK7u+vJ0kb6eJC4+68X8Sso/OUfNxhZ/3uhXdc+d9 +/N3iV8Jrfn96Mv/l4PT49eTV4dFPT4HbPMYxkraub3744Xx+Aef+tysb18J3a7atxe9vtWl94XTX +/eEct+4ghOOjw+PPiUngXv5fJxfvnhbrcS6jUsdXNgc+B1aUDfKenK7hNo/CbD7+AASQPM3zSHy2 +lgD/+NZ1UAQFj4ZU3Iie23bjjTvQR2K9T1AH01nM5xPRxXTNxX8MUv5/Tt79uhQ05X2w9ad75Ft3 +zrPuczRBgP0WD3g2xIQLzHz4E96vZM9++XZ2cjE7P579eHoGPl4ff8/eaGCeJu99qNrmu8PToyYF +7f0yR21NNFX/CfG5i20JPw8m1/ezkt/r8rX2/TLnX+FsWGXuOCtMakIS6PAi+OdXOMYacCECa+cn +OC/eC1//pDbtzyfdarbZoO+xQX/bFvob0AXvfP2Xf9vsz5v9+XE5snXpeawWzuvetfP6FdzZ1fe8 +kN/r6o2b7fmh27PLmwnwkfbhz3Zmx6eXPxzNfpw/Ra3HP8AWfHl+cXgAvqNPYf99DG7zSdmg3o8e +lNX6lxdHhyfd8+2umv2l4rdT7t/FXv7jW5h1q5Zyoq+3kfN3t2qLF7PC+eHf5wt2hjcXsyPmBGw+ +h1l3Mj8/X/AKmL0+Pz26vJjLF1ph69Df784yNpbBXyMHfXVwdvj69dEvk/3ZXx+biX6slROXV441 +a5YOTYHzY2Agd1j5PGDzyay9/j/8dT77aaUr625Z0yu97Z/0prt1T5yJ4hpnIurd7OTg7QLh8GTx +z3NpxAL59PLiqjH5RA6m6FpSMJwMINnQHz+wo4mJte92CfRXV+1v4b3sbx+m+8OZYBWtSTqYf8U+ +JN+gd5ENMAUoLibqFEgG7d5k/kUkko/gNf4PsLkcHjWWNPm2cZjTD7W5PF03xsdgndfHvi93+Mr7 +1nR99d6h/4/ie0LuFbaYIN4mBsPXE7LjFGCJ5uyuPm60UvHuDGuEIZhAyyBm/bPdw/N3R7Nf6E+4 +7cvfffP6v75tdfxmslDipiH/cgwEag34jMfuDiLFp/g6b7W9gL/N5oU9jRemmx7FuHHMm6XgUWtQ +H+DwZyguXPNK86/slT4NaWVzrn1k0eP0h4s2Yc4veqTGR9cPbuxzH0DkryBBQDgBihWepA1P0oWq +NisSgel9jGjRp2iVuqtG+OMH2dKesH82n0/aRnJxCqqPpf138cs1m+7SDbcT99s2KvqlswOD24x3 +YaT9jNqUYgaaXXOfpfsW6nN4n4tupK2pz6+5z+N9APuZrdb55vyC2uh8fW6Dd+MXVHH1z322dvjC +XlVipcmNttJkoC03udFWmgy0n2/5tl++2n4ze9f++P4dvsXvf/f66NuVF/672eU5IB9Mphg1t+aN +L99xu1cuk/THU+xCYAf/N7OL2SvWMX45PZTC2692vvqqxN1WwRuo+9n/aJ//+duv/uvtT3/fLgd/ +/J/xf+8czID4P/7v/9c6j/V8FC8oBCt6f+bXfwAx42J2NplenkEkyPtXb7xC7Nq9H35oYu6qemPp +23Ua57cUa3irSf/ZXpO2353PrxPYJdKFKx5MUttsfEKulwbqnw7fkMZ9gfr7+eGPby8Wavh2fqT3 +jsR+axUqKWy+fe/al3tLOR9K421r6iqVYnIhdSfLO4CuBQ6cVx/YH0nh/Xgz/g9ns5PzH07Pjldm +u34z2ZsdrLcBD4VvN+VVGLmQkowmc74wCY9Pf57//vuXF6vU7wYqLoyTy+Od03eH83M24CLx3eHJ +y9PDE5nu9Mj2xDenx7yZDJbdi9nF/Pvd+Y9NUjlf9xUh1tFXz7vl62B21Nq4Pztoog3aiMzSVy/n +ZwfzpTbgVy8OT+Zrq/vu6uq+W1vd2fyHo8aL/ryO+Jc7SXkvL09+Qmva9Oh0tirnvbw8+Kn9Ntyw +ZjbwTf+kt9wu3K/458aYLrN8/4MOwi2a/9hiOhozEF8qY9AabuG5JitnnY9sx9is/M3K36z8f/hZ +nK6Zxva5CdldPZftlTN5gEC59VS2V07k5dre30x+fLO28SDgpVhgJ6jI/hVC43kghwfUcm22g097 +Ifnr9oPn0fVD1GZT+AQ2hcfnBAqfQ5g5CJ+DFr5fz9L/0AAfOs0fE+CDuvJ/Dn/8++zHlV408uT/ +AH1ND/p3t+Vca3yClbrsE6wTGQIZaL32rXl+tK1U2xnN4Zsf57fF6vrHM1P8Q6k/x3xXG/vqr96+ ++mScFD4KiKMeJcTvWglXgTjqDQLimHVvEQxH9Ke5CcZxnR4IX8dP92dv5wdHZ2ObD87PDj6GDYo6 +4D4C8/qPRp1dHl3858C7Xh0evztS3nUFuPQjgvit07fTi3rZeOTF0HhEDN87edPxwm8EHX/ZRPF2 +asEuvHwNUw3Br1IuAf/BDDzg/Ezt+uw/vm2lztuRB8btPz/HTv/571sr9JcHq6Py2Z/eHoK1B767 ++ybd3mnj7lKaCkSyYkS4Rf3VPHmveeyIhzugdDHPJmMNkWoP5P3NgPyGjsURwc4iBQFEUKJCDWmp +Bp8K1OA4hCBTerB24rb93I0DCIXDUmFLLiiWWk7/gD2GvNA5LUABKDYo7ZZKGzTbtFM9WmvInQWN +OFQbeepZGE0o/W1bUl//K+gy/gI/tQ5UEGRSCJA9SE8Gzz3pix36+bU6cnw2oXpak/7yr7CZj7XQ +iEFSicngPB/ZeR6GBiqJRiqJ0Ja41BRHXoeR6yC3nMz/kP/9Z07b4aAdTtpRqAqsicobeg84d587 +aBmU/107GZ9Mdv61LA5GmhgdC2gxjT+thQBzTcZAyiczjkLAp+uckZgReJ9obUvwvmQEpIqwMAZO +qpD+F1l4bQhK77yUdmah+7ReI88j6gQ5U2fvPa+fy3krCPPg6/7cPDpBUQOozRHKcQCE9J6raFPg +63/1+bk8PbJrKM15Iz0J1HxaEAVaI0PA9USD71FGgHD3LD1Xa8k0qXE4wBNVBoLrcNAW656vTEhc +vBWGjmYkendFXnaypr85m538OJcJOS4OXGAePdD7vKj0N7NFLyMLQ6M1wbisWSGOMmPQUGnLyJmd +B1tGR6vCKS5vqg8NzRAcVOJ46K8r46KlYVDGOcJvqeAi7eMbaa1K+4ClQFUM+MQvqcrAUIiUjIBW +wvw48HSXBQ8DoxXhwHz9r6nPG5cc5qLBeUMvm3oYedzhpcmoaD34xtsDhJPyoNCSNWLQLtQfHt8i +LXJji3CE2jD32cP7kcHuSZtop6gyyNt/vzybIwuRgSU2LIMx0Xgy5l1V9iAYDimdpHTQosM7IaZc +aAVX2GhkGKR8UMaxpnym8avkuV3Z6Iedl/JOp/q16qHP/jI/OgL5l+5FbNCJ7NR0L7XVY1QGd3Kx +EE6Kvj3YYTnCLiM9Wywk75FCQqgQbwVSyC0+iSCMUMb4F9ktuwRi9GwioBdLt1INIrQQkAZ+9S8T +vJEy9h7dUOfaEtq4ndN370QSvrIKuUlLAYjQa+jktcX0rnUdGeHbrq1lvFEb8Id2EII8VZNXlyfn +8xtQoVbvbvV89vX8TRuRs8ab5rOTyR/aKev8NnAY68tBhS9/OZsdH765XS39Zih6JxjS8W4o/L8u +T348QsyAw3e37MNyEaiGluG3TRy/XR0L90MFd4MVWbi9FX851aOBnADukojoRRP1x8PRMtDVEnL9 +gg/ccsjfcnz5ChL1kGJkjc/++iRIK9CYCzggKwcl7M99EjRZQ19Rwnao5v/h5v6h7cLQ9EuMnG4D +cnZ6fj75/ezi4C2mRW2HyXPI8zfHJJJIB/+5VxfU/BfgwPb68uh1+/3r9oa+2J8fz7AiOvTtzl7j +741TTF60nkK26DY68/++PD2cfQ68bT4/Ong7OzybbB8cgCZ3Obs8NfZ+2e5IV/K7s9PLd1+d/HB6 +Y5quyeINkm0La4Ev25F8TOp13TPWZgic9C8fUveadJ+TtV9p7esShF73hCvDk67+Xp91ZTbj6x7Y +JlrjG1oH/qn/Xj8YOEsOz4/7GAyU/vtNM6K9KFDGnGs19Gdv04vDn4V4fWWN3YAJtw== + ]]> + <![CDATA[ + v1qk7p38PD86fTd0Uilg3fvT7OzdVdVC635ofKu9wFeXqJqQ18Cq5Qk7ra7eec3CYV65e3pweTw/ +udidXcy2nn3/pfw9+Q3+NSi/4O8/f/3i38ETHP747P99w/cOfrV/Oz46aTd8AT9AoQ56rWffr//+ +51njQHRDZdXd+PXFL+/42y+32866rgXH84sZeZw/tAH2fg34mdN8vpqjn/JHb8RHb8OHHIXf9nva +rnT05mx+wvcsTdvhxsYH2y5+eUFmP/jqX1b78pvzGehOYUl84Bd76y4tthjK3NzMz/7p5Pz7gyZf +nB7/9oqbhza7D/sapA+rrwO/+M3Pt+tem4fnT7Vzv/l54e+rp+M9Z0Hre5uu/44DctNYvW67RPve +Pr2hGnuxOhmOTg9+mr+5uX8nTTh/en2T1r/PWXAHXvCUF8stB2mx7+c//PWj7YDnR4cHv4rtDzvy +6vTy7GA+BenySfZpscm/3NjE7n34RCb5L2u3uhv7YW15Xr2zT6w3f1vXm79SzNsNPYrRASJ/fWI9 ++qsE7C336i0H7X2a3XqrIYfL/Xp9etEEwxfzHy6+OTvEE+pNU1F8O55I11Y78ES22bYrfeK77ONt +NY/U+EH1AJQUo488fttf1cns7OL16ezszeTg9Oj0bGInZyJ13Xgn+KSf3PLe1/ryoguuXH2r6w24 +8c6hATfe+3plh129bXF2wfcYCfBu1ob+4Jf2uMM3E0EXffa9+rTBje9Qb3t+eHx5hA4zspX20Oh2 +0zeXF+8uLybfzs4v5meHf8cbJ9/O0TlXy9i4UObr+fnbG0oszwcJNGh94i5l6dObd4fPl1o/Ozo8 +XyIdz85/4g6oA/C72ZsujW9/Ndm+vDjVdsnIGqNjZ83khyNQpZ60cTnD+774eQ5e85PXs6PZycHq +KC4UOWUo54v53y5ud+c5GgqW+7J088HR4bv2skFn8bc2035sw3ZDiXdn8/P52c/zyenP87N3oBfk +AmGYJ/t0OzCt/33ZRvTil8mL+c/zoyX2/9P2Vy9nZ43ltdE43zt+PX+zfXS0f9qq/Lf5L9fd++ry +9fn8Au+cztE8quNNr+equ7+FKaOVwzJN3OzVtrw8O/3h8Giud7t1d/7p7eHB2+U71zf65e4+qF1b +C14fwpBcdy/c2Ab6XCf1b6Fn6j24NMmXnQuHWuFtnJz2lzU5PMH3fXp+eLG0fbz67ncwRjRaFwxu +0PkDf/3i9GBY0cOXOGa0Anix9O9ens0PDntnhifunRycvtFnhf4Fmq3+oLuYdqh9hSpsOOY3VnSw +5vs/zNt8nl2s+ebljz8sze5G/PPs3eqdr9pRRpv129UB7r6Ii2rwZ2B+ml9cvhssTC9mv8zP2Pex +2zAhlVjj0eTQFIHy4vXWZ18dz36cT46gxOeTFye0f1+skSf++NUuIMTh/d/z/b+l1fp9K9G+/lwa ++v2WnWy3///819YIcMJsv1xu/fcWsOPts9s7ZcoBop2IjvtfsbC4erSV8sqf7d6jhZJHW2+3/rR1 +c8fab1/tfm+/v6ZXOMLgz/ybYbBpBm59BkbjP/9u6z8m4bmridw7+VfrOE1jLOBi6PPkP/FVwP+t +0NtbF0ILNBeU/8vE62sO7TJtTpC5pM2P30wS+Ots/fmrrWf7D/hsSm9Kb0pvSm9Kb0pvSm9Kb0pv +Sm9Kb0pvSm9Kb0pvSm9Kb0pvSm9Kb0pvSm9Kb0pvSm9Kb0pvSm9Kb0pvSm9Kb0pvSm9Kb0pvSm9K +b0pvSm9Kb0pvSm9Kb0pvSm9Kb0pvSm9Kb0pvSm9Kb0pvSm9Kb0pvSm9Kb0pvSm9Kb0pvSm9Kb0pv +Sm9Kb0pvSm9Kb0pvSm9Kb0r/Q5We7u/s72jp3f09/bn6yfulXVc/G+u6awM+yVHblP41l75iFbTS +qysj4DV+XLv8AgXXzSfQ703pTenblCY+7/DCz94UrrWlh7sWPqtrbBuuJ93vTelN6VuU3tvb293b +o/m8neGa7sMC2d3d3dnd0dKjNEXroOzXVobooyxFvw9r5Wn2e1N6U3pNaZrV4wdXRsQrwCfmBFdb +HdPd6WJp3llIyqKaViWulfXxSC3flN6Ufn+l1/FznMlhGnbCjo022OgyXNnDNc3tKvtmb2mit9IJ +r3HPiEjBldaetHv1ufwTG7VN6X+U0iQH0U+czVvP4h5cLsBlE1xuFy6PV92Day+1K/LqGlaEPnvc +S65dGfdu+ab0pvT7KU3zdeTzHq44bdcOrYutZ3YbLufhantIu7zxxu2zlAWVyAZC+8Ygoem5ZKPL +ffzSo87j13uaW+zlh5U8ViwUbXrvpX237aZu2zrr2/8Vrq1nZq9d+ybDRd/EGFPEpTRNa/RWQ936 +7FWLyOrp5OqWX2VnuV3pe30+0Dzffe/nMeJPcvLrz7vi56+m3/ctTecB+uCpIOHl8LIZLteWgTO4 +Lvba6aNdbZUkvPDjSrtyMblN+yZuhV2xctBb2B4ueTb9tbJffcB+P63S19tXH+fZ9+Iq1zz7il3r +lqXv++zFlb12XS2VvnU7Fz6JThb0DNLcwrEiOTuFi+f/jtk1u7QmiE5ylXFwtVWCH/om7cC14+Hi +VTfO/5X9YevZHmiM17X3Q4/5hy59lYxwi7d37UztMjLxn/Gshz9XZksvMergr3iCzJaFPUg0LTfW +qhI2/Vxt7cgzR/r7siKPrR17MXBy0jltPaMTBB4seH3YXbhozyCJivRWdgculrHw01bJDlx4SHHF +wLXQDrKbr84J6ffqXj+OLf284tTyyaySldmg/abZQtyD9tAwXDR2dr8NNkuu+HsrjW+O+Brp0vdI +TZLblUhXsufxsnDR6ZA08VvPdgteGa+0cEW8AkgB+D9MA7eDTd3Z22kVbD1rP+kzbVfFq+CV8Uo7 +sV3IJ3d4ukz38WqNbKXpLyw83Z7W9j/qP6epXZmk9KmHC5eLIUtbu5pYs/Ws/QTzAos37TKt0/uV +O0+N4d+32zWtqeZ2hRprO0HTv9XDVXDgqeFlG68KVyvRLvoWNwNrC1zt/D2cM/h31FXR/De8WQwX +fXCn2XpGGi3ag3hJrX5GHfDAR4aTBcwj2n1otoyr+TFm6ocrvbrWqcfYL9o72x5a8IrDFfAaZzX9 +hGuXZjjN7zbPaT6vzmSaKBm3dJyjPB9rm4eVZuLWM56L+HO7TdNt+lSejwEvmYN9xsHPtr6rwwsm +i1kz1zJeocR2+fZvoMVI5MaRLRgI6JTLSxOblYhVu+TbRb+H1I63RKEB2npGeqOIldPpNwb4P+xH +09jKtDV8GhJewLU98W5iF1vPPC2QiBfuCayNLXjhtzrzQX7CHcPBxIZ53kQnu0+6Kl4ZImvBRRsE +yldmGy/aS/D39mx8Kr0TnierJ+/VOS/7N+m9aH3cWgd840z90KXHPXuUKXAH2NvGi14WDl5bJcNG +Td4IuxWvkavjS+T5T7wbp2PjyMSxA14OL3xVU1xKzKMHvjw17bLEnRtHpgbt4kXrA3l048pwTfEi +1prxwhVB19YzWt4La4KmGbBcR2dSIvOKoPMtzvytZ23ew2eY+2R9jhkvmvkwoRwxDZ75sNxav8lG +TSuAtitPBjma8/vDRcOCNrt2lnbOtnmO/9IJe5SZLB63LX2I6eD5m7cEHFqUmWDlUGlaS+MHtVe8 +bgJedP8+XG3U8MjOuwXNltXz9yjtDVLUE5rndy9NfR13i2HF056xIPuEfrVVQnsG7ROjBETyDgyw +Ydlm3B9wXegqGX/SpKG1Mu4ftGPQ0OO6aKuEVgbuGSyx4D4xyid80b6B64N2jPa+6YP7BL17YqMZ +xb2c22LINBC8S9AqKXC1VeL7+sApZdtwtX9bF4Ax0IqhtWKj07WyCz/bKtnFAei7hWsiapuQ/JMG +mhYtfWj1QEWxrRJaM6hhYvsevQacyTT/aTegHYNP53i1VYK7gh0/tJiG8wevFVwfxAJp12zvG7ux +IFORtBGHXWLcS4YV88msknVaSZwIxJb57EBj0BmaX1grDi98kU1mGqUpmLyyi9D+gWcAXR9wDZJ+ +k5lQyl+Q7hvDnUbeJUR+gumZWVVJ8nx79U1mIjmKdgtaDbRbjGuCdgzavOhWXBdNZtrHi8QzWtpT +bCJRaNMwyHBHWQr3kCYz0ZogyUlWg2nyEs3/tmzb/6PMRL/jCaHJLTvDRasBbXN0UKHm81qgBYJS +Ek3mdrKgNYH7AM9z2i2Q9/PJmyQq2uSHT1slJE3Rx+NF7IE++DvrtegWbB9taW2VkFfj+CGJa9As +05A/cKbepfT1mqKrNf+rukLaK2h3pLmPvWulcWXs7eBFJ2g6TdNUxTWx5nyB0lVbJSJfAQulkwXt +HHIS1pPF0nl3e9r4Gp946ZS7gxdN0oqCEP0cThksS+H5oq0SPKGSkH6blTGui7ZKSAwjmSqgoERr +ApvMawJ3DDqrjrtEWyUkWaGYrqeJpf2B5CreGbiTcLVVgvIVMyFqOu0M48rANTH+TjO/rRJaB7Tk +SJ6i32nd0AynoRjP4jj/RZfLu8X4Iflq+FDLaE8mbtlWCc4TnmV0QsXrgfP8YaWv1yMvrpJRcqLP +6O1P+wOteFwftBb+//bOtjeOI7vCv4D/gV8E2EA0y3kjObufSItKHMi7ibNGBASBwV1xHQW2ZMhK +HP/7VN/nVPWprulhDyVZ8qK71rOj4dRMT3eduvfc18K/3bYEMmAZsG2eIyvQq0KjSihBp4JtuHUI +zt3KCmxAsWSSzgSnAA2gpGbhOLrS4pDdh0Uf6Cj8G2RwWtcxsi6VRiUxWPqBiISSWKri33wkXANM +hKzQK2Bl1SMmxzNJs4J/hDYVzGMnxuH6Ez95042kM+kSxzDNCcah50SBwDgu+5FQwjNnIYEbaUh+ +oGfZ84EsASuOKI6QQfxGNpuyUls7bRPV+IB1fvzsw54lP8vsJ0LmtdogmOBXGGJudv1IKOEZanN8 +eYUJ5+JhixILjyWdmEVrN3X+zQGzQJfCLhrTE0oOI6O3TF2JfyM3Mv8GGQ3/FrO46gQV/EL46HCx +QWIkZuF6lMsMVge6FCjAFtVLj1VhFmACZg4jj61c+OCCIHBCo+IxoQTNKniGpIUjgy3GkCGuHUfm +33p0bcllgmPBtKsBSnhvgxLQiq3EbVHFe/4+1vn0I9uR3Qvl+HBvBKv93PhRthy4xIFloD3yCnIR +/cnwkfm3kIEeBSZYfjW/6AaL2nCRUNIiI7Qp6VKBDFmmkBuGiISSVptCZowgw7WohJLztHjPYd4V +MoAM+Gh1qcy/TU4UydBhw3QpMW80KmMcCSWhWQkNoUfJPouIgmV8YYMLGRpVQsnahllm5fNm4MtA +SsCsY00XnQlO4WveEQNH6UmL/B5lNge2LOYZVvgR6CWeJ/IrxvW4hSweS25La2fKPpmhXOnts+vs +9xcy+Ay4BshAo4J5u0UqHguzcGS4zHBdyv0X8q5VmBj40tIAWEiJzDKKrAj+3VmmsA== + ]]> + <![CDATA[ + 2Y4hw7Uo/Bdhq006kyPDtKmiS/X2qcZzkVDCv7BPuf8ClIT/AskhXm64SMzCkQHUQAZocI2q5hph +y5U1CjkBy+ARLYrX4RfOFuTZq15DouDZQL9izYMMLiGbWI4xidfAoCQHOI0J/C7utNbg8ev8eJS0 +8Tnj8Q7GKbSeQ/uHLeic0ZngUEKJeAZYcZkRG2SlRTUSIzx7BRmV5dY90c4yjF8klCAt3MvsMqNB +huMioeTKRouMrEV1ik0gw3GRUNJjYlN5+UaQ4VpUYhbm0yj2qZ5ZwMJ7lrGS/hQ/NaHE7bRoU8tu +SHKEB08sA+YNLhRZK57NyCgp8kOrHVnh/u9aGrQ6FQeim2lcTjCk2WCQc+M1dgQ07NG4ng+LkhYx +TV5WlgbsuawQtBcxDtOlNM/ss9k6J/tUyIzKGgVKXGKYR6Pw79qn0dts0aWcX8C/Ax0JJatuONsY +8IvOsOm6VC83OpQciQxJjBji35tKm3IWHvjwoICCkvT/lZVqZSzjUjIDzq0wkBgmMQr/ZtOKCHOx +DCxTPLJH4/cjIiRbqcAHK5nIKZ63LAOsmBZV4nL5i8XoVujhAw0ffE+27VXZH5O5xmCdjyHqvkgs +1rDPbvwsSDN06xKxEFpwdbLtJy3lyegOiELoUgklSiArNtvMNODf7uXbF8/k3j5YODZbdCm3TMEv +bvpR/N9IjjFkZMtUy79BhvOLbJPqmbfzC5MYSWcyP597M+TLcM+eaVGwjMQssNwO/Xtrsu4qZJjE +AB1JlvCvLC26x9CsXGaIc8MvoPWKPxcmWmlwbsMPdCxFiUjWwFVG2DvSrFpRdaTlkfEhe1HiR60z +DZlFnj2S0YuWgqbMXeIucK9Yg3Wmo7QpY+wVMkyXQisrnj10qoZftMhwXCSUxDIp2hTI6LlGkRVl +ZESkkVBCtBTaVIuM7P/eZv+3x4UklLhlyvHR2KScebN0E0rgFPi/21gRjxhxj188Zv4dlqmNJAdc +g9Nh40KLkpobI/hFjhKRNmXRHsIH+hMbujFyLKxFGrQo2djg5zV+8axxSVLFwAhSRVdx7Ms9f9iR +LUXT8wxdTslnwSVkDej6s1eh08YGiqxHn9EnKTZWnm97bQ8+3Jdhvu6EEvdjePyUcw2Ln0J1Rqcr +/LtFxhMbLcsIdCSUuM3WvBl7fBlusQ25kaQ/gg7K7jZblxwjXr6CkhHmXUmJJhYkSQPIlPNvgkG4 +xGhR7tEwv0aSBhY/pfXacnEkRiMZijXWvH36E8yaGBM7xCWEUC5hlfcUB5o3moRWZ1MB7ihucG6j +jur1nAC+G+687W1OaOFajGErzDYP7ox2rpDf3EO0e30e/MFwkVHif5Flqvdi3FRebuMXg8haZxnO +L6Cebqut/N9iFu65GGfhnUYVuEjMwuNDXGZ4lK17+WAZgYvCLJyFu33K4guFD7PbJj0Vyy2PoVlV +yMB/4XGF2G1DlheUeJRhxkc3sEzxY4JxyIsRuMgcWOyYnR5rE68483afRPbsccAaPL6Qd8UrnLN0 +JpMJB2ItJhwTUeKRrvY4yFyP5+girBDuDxYM9p/Nsh9Zy2UxSpvapJuw0ed5ZAhY+aIfhX8b20AF +8HyKgcQosbZJZ3KbLcyCE4VreOQgBxIjWEaSBo4Mjzxv+YVZaUFBRIkQWdgN92m0yOBjd/0oUSJI +kUBJ5QsHH/j6kBgX/RCbWylmisPjzA0TldyIaYVZcEd5vrNhLEOyos9Jusn2VGysxf+9zXEjbnsV +Iix7Y+CzCHRpww4dQSsVncK9A3k/90pW7lF7KEr4jCYeqzoUr8ia4/5oBwqbh19BIgwkN7gX2pm4 +c+zPe74DrPt52GPxnqP+usXKczU8otC0q3zmwgrywy1TrS4lQdaNkhFEHkbr00M+kIVxYyMzC2Pe +ija3PAykRBHb3fo3W1Tx7LnPOySD8OEalXn8BvzbYtKr+EK84B4fgtzIUSKhQXk0rViG+7x16WOg +Y4U2FLFU/cB31/JoDl6HU8etStc8rvaeCnBtjdzxdf4gL3ia7euP3bvBGKsMbUJXMK5dtu3B19BQ +ueZovI4b7Orc27zWlNELm3BrrMdBuc+ijhnkXTy2nj04d/sYelXJm8NOu7bRMG9ZqdCfAh35ju1u +muGW21ZWZP+3H0AjcNNqUcU+9TTnLSWUgBn8G2ACftF6vnss7Ir/m7vhkSGt5EAJYHfjr/FKkiX2 +XlBiWUc3qo8QliIYuTSq0IYGcR5oVmhOxjXAukzGcWTb/T2xT573Oo6S6Uddeabx17HnIveVShqH +7BgxwEJE5nQbNyLTrYTxurxPcetZB6zBore4/ccf8SGg49se7is3cQP3ynlsE/NY3ysblm1R8ix4 +9O9uZlcR6YGVMnvsDN3Giz2L5/VsHs1GPEBmukZCLl7IOP8BJ3Jtz/yQoFjfbXIvaXueZ4XmJ1Ug +RhPZwusZ32BQbANzlVdDADHwC7M5FQ+2cQ64OqKXFVfxhCanbVBxp7Ua+QzHTY2SMVnS+ON0BADy +SmXvUUQ+ehIWPrY0mIPxOy5mjmbOgcDx83v/6yWfKk8uugNWSeUbVDslf49HXpflhs0WVYZchtBO +cq4DolnglSGjG24v0jqI3b7YmTza3LHJYK2CLtYo3o+QPWmlBmNBHilrEDFi8grCJPuA5ZeX+JaQ +icpZREskIkbF/iJ2Bj3bIjNLBFpjMZlyHNhT+cnmqQK4xLewMpLOxIYIDNGZqDJF5JT74xAYgaTs +uQfTyqSIM5c20dREeMc4jz22XF3PEQaBri63QWwJSOCSqxi2BteZFDuAALf1L0SwIGUZlExHopgt +HYuVMgmu+0hQ9+rmSGq0BtliQBHaRCwq6R+OmJzrEGgRStD0sZsStgJK2C3J3QYl2lO1w4ISkwza +wx0ZcJTwjeRMKFg/trGqogIWAnhQm2ulKDAUdyEDWzVrkjWjLK4YXgUlo+R9R5g60mKNcgXhA0Vu +rJerOv+b59KpyPKL9yp2PHaQvXYmR/4IJiaeOYfP5nrts+X69eRnh0yGwQnl8KCwZ8uwER+V6zvw +F+EDsYuwBxOIfRXHjqHdwfVfeWzNxsijWCXrn21dGrZkBtYa5ITLB9gtcRcABJiHrCiRGuBARvPI +upM5LQZ/jW1e+keOrLX8jAoZMPY44POyB4OSeF5i37GHoZogOcIVoEcYU2BFuYohK0p2CrXE+xzH +tR5dp/CIzmFmzAPqamVJJC8sMiO2D3Yj93yLRcA4vEqh8vhg8tyS0ayifVqPI+P9Vbxl72ikSK4d +ww7KbeBXyG6NxRrcxy9SYozFXiadCSliaJB+hSvImJ8QwfN4vUS/kZHGI5k4aFngA2TEgsInXGKK +8Blj83SUUGuAkxqREgUlGQ2MLDmuiBCUru6xUsr/rrSpChmhRXm1HPCAzTgeE0pCs3qiEjI2sDXE +zVfGO7ICQSYbdrWbusWkrU7lWHhofUUqrgUmy+z4VpUuCY+4rJLBvGWxjRupuuiS3/LKuVXVsxL4 +XSOyblAt4Mgjn7l2mDZHNq4g+51CAIhyUX6JYinrKoxdJADMO1Di+SzSq2IJFj8RESBYAz2+M+fn +F+uhoqPDqlKi35Afrj85SkyLEkpy5htSBIoQy6mSIo4PuEaWHmTdgYZch6nDBBeBD2y5OD+14sCt +NiX5ALN42g8hIscEu30t9KiKX7gWxf2s84E9A+xIlnEUSryejTgw8ttjBsUgQgCyDtixvvCTydre +BN1ojAk/AN91vVxHV8gMaYaxbCXf0BLNl2/RMZ14DMnhaJB6i6zAqgezYLHFZpl0JghZb7PdCQee +K3Al+3tf6ULMQmwCNGChdBZumPCKAvgIkhR0aYHoxq7CZqYiSaFF4YEwfpGtsUIGLIMvwSWftajO +QgS/MFwklLDM5bgK+YFvcWcjsNJKjISSlnm7zGiQ4ax4wL/fX4WlWEWq12E2ywH/xo8Rl5ULLLMD +88b0uKoSaPUXjzB9f9U47XtyhicWIXiQMk+CJ3iEVsWl6IEQy6P4Q3kX/gs+BMHjyEBigIuQG7ky +RWHhyIwuYoTp5rd15l1i55xtM9CsnHFkidEtU9OoAiU953CZMURGLTEy/3Ybq8sMRwb+ENelVNdC +lin0qBGZUXlsTJdKzAJtym1SaProHF6p0fn38dFv09aarVE0K7Z8Nhs0C+wpWQp6xSf/oFaT2dvj +rz3/CX7sAyiJ7VweiNgnFXqGTFB8iypqYV8jPtJ8mQU33bCoYxSn4tnjaKSFyYqNRels8lXzykeS +H8bP3cMruWEso3i4kBwuM1yLgmWQMWeIyDXQKsnBxyNYsOybZcrtUiVKBMlhHhHFrSMr2FZAhLGM +bKWqbLbYp3Y2Pk3+3Vb0jW9FW5V8iOvIH72CR9GZcm3aJ3tR0lqN9tXqndAZYHDmfoSkxbHK2hYb +cp8KQ7XfhPnY5lxjrGrUQVr5eXJzEzUgT+kYMjy+86b4+tY5Y989f9KrGpkhZLjEULZCQUYnJ9wy +C7NwFi5jCMZyxTNl/t3JjAtj3oEPIQNZ4R4N+QWdZ1Qsw3Up8MFE88DnOC5ZcT3PyllGy79VQ2WP +NuX7q2cM+DGtytHY0dfDLmyci6puY61Xzis0DzMlur+Mse22Znb13e+WZ8GexP5aMaOi4iSWYeUv +kSg5o1cxyBZLqUh9ZAmqACjhpRw1gJ3W+YUjA28F9ilQgi8jR7/dDMcoMlyXylYqtCnHh3v5Il+o +stKafXYi/65ZRmeRyp49MCH/XgyrByoWDj6QGyYximeP4cjgIpisqLwY4/x78vqZqJ+3Wo38wOxM +nKaiQ9s+e23tpNACm8oz92Pz+DP3wxCY+2iyK7K2vR6io0QWaTQuyRK0LPHv8HlLs7IMSEeG46LU +T62R0bOMJ0LGqrBwstLiMelMoVOJf5uc2OMLR26gNMUGmyugVvwCLQpMeNVAJAYiJXCR6xxU0RRI +DovdkMRwlpH5NxG75seo/N/YavH7wbrNLjXg3/ALvhD9xCs1rm3kyhRHImPiWut9Yiuvws2OlT17 +/FSuNtOQc9W6dPmAlztLQX7H1nJT26PN+bzvzOvZ/bWpZnPHWGuyOVsdOOlMsear6lmx0BOzAB/Y +4bBGtcxbjUFwD4bFNtBR4teQGS4t3JcBMlxW5ArH7scADWv5uztMICtCGcIyJUSoImZrrVW+KVgZ ++r+vnGsklESEuVCClw//t7OMrEvtQnJcZ40qPHvRMKWXEwUfbWRIdxF6llFqt0qPsuqM1guhZhk1 +/36QznFgrXlWQnxHLkcQ/j08F3Exc+11IcOrT3LkrP/+/AzphZe43PHYlLZ72X1nztHWvbWsOzb7 +XFdSPQ96ZnEjWRI/Wesf9l5VhxAmWL73IyOz8GuyLCUn3CaFzPB8NPDhciM27YQS4kBAieODx7Cc +V7oU0iN2soQShAOhVmhW6FQmMyqJYXbbXKVQ2hSYMJtU5hdhmVrayPwbbUqO9RhupQ== + ]]> + <![CDATA[ + YrhGVfNvxwc6leOj7USzz4t8bGeluleOf0bILhV5p3+MrRxpFkIJ0pPJlRXB937PnzZEDNa52xcm +HIPZLZ9xrHN+cWbIkKQrxipTZD2dD7wLIZZbbFFW7TTXlhAbByVEGTYyQwpbb6UVLnKVhCqj36xU +zsirDhGhxCSUkE5oPvEKGWAC+5TKOvaj9E4xTAz0pwG/6C22B/m3e/ncl2EsI/zfvWWKOCmvrOga +VWO3LdFvbrltbLYD3lF8HIOadwcxUWXJVGuN85HJibwNav5bl8qSEd7Fz4Zcz1Fg1doe6y51n2fv +obqi9ycaO6xXUWax8AF5u0OW4L+Q/IBTWAUix0Wp5kUJf0cGB8yir4S0lkYVdtuEktCpJCf8EUzg +BZdpMFiGSYyS+YYfY2UDXcrja9c29vi/K2styOBmedxtjRLn5OhU4ANk1BpVxzKIj8r+76dWrbr1 +grMpuV6FxMiaR814ey+fry9nwlYdbEKN4v2rT6wG3VXxQsQMWuZFqTjV3WbKH4S3F441kERjHddG +zsysVFPln3GlkpuaP3HYxdm/LnYvGGbmwPJ0s0StC6ElHp971x3pUurTIznRx4dcSlqgLeHFMMuU +PjBn5Xg+m1ujkA/u0/OMuCr+XLFUYAXJAdeAZSBFnGvkPlxIEXwa4APmPZIh4rhIKLGYQtmquDBE +TvG1RN+Cj9r/3aPkaTYaWqwtejuyYmsZ+7U0cJ3DNSv3eEzbkW125ZuLV7gXpUsA+nagQeULTUvX +lmq9+pypH2Uhq3/F9Ciwkb5FxVfT7gJN1Bl3AYUx1zCV/ugxISxllxzkL2XNqbNCxfOSy2SV6b1u +vVqKUUMBDSpwQ8RU8X9bbaXKiku1APSquNyuS3X7mvq0wMwHng2xDHh3n7l6XeoMuv028AGzkJ/C +vXmsf6sgXZiFxUwJDc683b8Xj/gvijQwW5AwkaNNuzvWdlA5Zq21O27GmNeVbPN/YhUhjRURQoUP +ZSt4fba2Tm3JzEgaFyuDnWJw5r5S28rgrTa0r7PS4erj++octPLKGRCeHMpFhO6gygdiVEq/xO+B +5kTNIpBhPd+qLiXKZQIfyAT9IRaqW1W1mmlRYR0n0jr3nZ6/cANRptxD5z0ba2ssGW7OJjyfznti +WHZfjj+XTSrXL+ziQ+pMO/7rxpUsudhyxw5svADDo6vAU87J9bQp18uQLmhc7giyCnWlHrYPz46v +a8eXqhK5toSqrsiJG2E98ZvQLaQzkcXnR+7/7Xms3gcAfIRARAvnvijGqkYJW7L59KujZe959mEu +MlKVuVjAHYMjvETN3EJXQXzmbCR1MoR5WFa97LPOL2ARsedn7l+lc5rM1p22WGHZ9K0ba5oNK6W+ +LXsx9/Cp5X97V9WLfuSov6paJ2watsAK94qdNUpy5ZBSf20PHj1X1CrqDLoEWBa4ouhDOFZVbL/o +R6lSGG/btqPtz0fMf1X/vMr8VgmWGFYTQWEK3IzcpS+Ep0cbKaYCpc+rTCFLrFZI0jyabscuURRq +FKusrR91QBo4n3fbcJ3BfeQhNpe9qW2fbA5ywcNiwqbNahcWcgfQAJBy87gbcWdUea3P3Fuplty+ +XrVUSfCoa+9TbJVB1LfSd8VcecpqdgordX+AboGBFWk9FT68pi1Z5Z6VDT6s4lrJovZc6rZ+CCjA +GoAQVUyw0GD2g9KZ76ZUlnK90aqHFH8o9RHwCjk+cmeA0pnPq+ukO3Zjw3tZWvSP8IG3yyqypXWO +ewmQseax3CIgQIlXseWWhagf1Mzx/krx976y6/VZu18PclO95xg10Fr0VNWVJ0FjJA9kL0LN/6qK +OnFfnJFjwSv8m5xwtCzbxVR/zaqc63fF4iuVpby+FAsTCQEmmioihcVmNPR1QnJngA4TRG2ADKqg +1/XPveM21UIsWkq61sq6bFv1kISSXFmnz4Si8tRIL1ev2Jl7zVc1O11ywLe8/rn1qhxUdvZuGW0t +HSRG3X9M5S/6/q6KraZnDNZ8M6t4FmtmFlah82mpKTXsrNQcA5TYAUCxG1aVK40FFZTEGsUcs8fu +O8I47kXJGDvPs627i3cH4++sHF1tFoLZbUuVwst+KO+XOuf8YuL/zR4JDvfWX/NqUm7x9F6Vuf65 +V7Zt+/NhQfIe9NY3I1tjK5uUd/7GbpU7ukbqZ193I6EEmcEXurSoqzx3wzrH4OMvVQqpEcGPsuoR +Vf1z71iZOyu5tLi2/pUjnQG8L0DON6hq2jIFPxdWKHQmfBbc/IBHqX+OzMDLwWbmVTq9lkifBLEq +daGtMroq18bVYRlUy9O84+l+U6WtiWS8Z/33luChp6fNihxhOzXGtJJDB2On5u7JIxibc9Gr8H+H +lGSNjp1h1THjuh8lDrtFhtcd8PrO1hGgZEq4JYlaU7n+2i7+qzobW/+xMWRQpRBdSiEqVp1GWbVV +NxnrD7AHH03fjGLDdm0KEd1qUZYTNqi/5jnHjgyv8syBvTGERZIGRGBTeQ2fnnfjyyjZFmaBrFCl +/iq+oumWoaOtgp77jzUH+OfO7OnWWvskpyOjOe6NMfGjseDtnR3vYhtSFTbr7CMbnThwNc9tk3Qe +cylh/Lswiz7D50Y2Fh/ehcxlRe4/5t1c93XmS/xbP7bx9ZVaIl6rEDSYhUy6FPYz/hxyI6EE3wrL +DPHv/hmeey8ZfkyuUoi0IFPe65/jJ2r8qN7RtcSvId8dEzI/Np5c5Ebm36iiZPZYrULxC/DhldeM +d5T65/yT517zHNi49oXIVo1DvUYl0EClp0VUa8m9Ovet8wnHkfmC3Xef9/b2wezQhNi9+dmu5WLx +YV6pO8fRd6vMyPDCf6Bk2DHjaal/7j0zYEJtlyXsotYxY2BPtVqF7pCVxIB/1/2/9/XMoIpZYuGK +RYFfGD4K/wYNjomWZXgvGVhGxb/baraqf+72KWcZ8jJV2hRaMLkHzjLqXjIlg62umVN1WcqaVQco +VjtVpkxzKuvcpUi8SzWqvC+T9w3I1duYHN+BjFWGSJ2j0q3Rh3p6Ro5763E5b2/6ZuSIYmk9sauj +c7D7yeLgUT8c2UJ2JDIcFwklRyLDYZFQciQyHBfFez4ZGY6Lkl8yGRmOi8K/JyNj0H/sSGQ4Lgb9 +xyYgw3Ex6GV5ZWNkhnepTLNjHr8V+a7YmrDpP3idH4+SVmvjFffFmoexRKARwxjRROhBQhT44Ggk +RokwnYwMx8Wg/9gEZDguSh3RycgY9P8+EhmOixzlOR0Zg/rnRyLDcZGjgqYjw3FRqhRORoaP0svS +uwQ0h6LeXaJUvATgaE1NqU3yflDSRgAjtcYqi47XMeHAEuxWMeQNFikFL8mW691kWpvUQV0qMYsj +keG4KPx7MjIcF7ma13RkOC5K3vtkZDguSmXIycioI6mPRYbjovDvw8jAYgUKFMijutDepaztzuS4 +Ma0s1znA2/rgdX7sMe5VnBLzWHtbmOFxb86/3fPt/u+6/9hkZAz495HIcFwU/j0ZGY6Lkkc1GRmD +LgFHIsNxUfj3ZGQ4Lqz/2ERkOC4GnY1blgGzwIzuciR3nDENSjF81tn4LBdMTtdGpU05cmTtOxwf +YHaLFbei1fEt/Muym6suxw0yBv2/Z/792+ffSAve275eMwuLvuJbsdTJSuWc+6F5scesc1/tBzNf +Bv6SMWuyR9dbvdKTff2/DyJj5t9/F/ybA82pZRlwCrPoZkswUW7DhZUbMh3O/vskZEnrVXRkezcb +w0Xp0jcZGTP//s3xb4sozL00qo6XPiE8JfxuXIcsn1xn0FfeFMvU3pX6oOO9zh7JI5EXk7hC629c +qvU5/yanwWs1WQy19+Ur/JuYEB6JmeLwWCliba0LeOn/zS0gcoqYEJDR9mWx2qAlstb6uMrzTSyh +I6OJm8p571VPPsNHE0WoAMBc867yf/fIWFf+b/f4ETcVHr1B/2/QgJ/7qQ3vdcxQlEipLNANi/ao +9CQO3gOGQm7UvASEcj1ls/G6jL6K6gjyj7/Opx85QqXp6uR+Q7Fw16iw2Ob4c7fcenaB44MoESIK +WdSBjhIlkmOmutxtx4R3bWq6uEb8ed/H1WUGGU9kzRJRuK//N/5vTDCc7hgyPGIqV4ew7C1FE7rM +8C5kLjECEapylDt/A94LG0AKssfPs5zOXDtGkYNsK+AA35xH2XovvljfRWdCQ/L8JZtd4caK+mbL +YFXp8LzxEniGxcdf58fPds999njwKy0rXTIDTJCF4Z0pTWIknWmCzKi6VqBLqetL6XZcom2FD+/S +5xlNNf9GrIGJHE2YHqVFgQnrzKdqPzX/VmpGIKOPmVrviZWy+NrCv62LpfBhkYUFH31EoaocVX0q +vScf0SBemxL1yzSqpDOhR5GthOQgGNI6kok1M2ppcPAQp6ZbPGUtOHLOXl1xZ1D/4XAl308aJe6z +dx+h/N9Vn1aWVpOjpogp5xc5/tyRgbMQZJguhbdRmXQgIkfWurQw/UmaFSeN+EFuWHdX498ljlCj +zdJwuaHKcUIJ8EI0IDOIP/fOxsgKixxsImtLTqV1OV5JYtARC/0p17Xwnt+h7HlkrR75MX1ly6fZ +niqUrDQ6fkGsoffq85hBPBO5ixdSJF4rmX1FXA1WTp+Zvi//+3BNh+NX6q89u5EZ2gP2dTa2/uBV +5K17xNkWjYOg3OZ45LbnsWNpj4zJfkEQlVtg9lHq5P21XSzBSq5L5bG4HpHrvMR7JFve7iDjz3I5 ++nz20jfHH7Mk4gd6D3FyBMeYSp3jQTUjpI9VdvHcD+SHYvsQ4+q8IpkRJ1R1+0bX8ljDzC+6Qo2y +Qiu2I+5YtWa8NuKvt1I/zuwx/t0iPu8O7XvHHhvd7CT3J4K7OWvzHEa3AJidrFQLaL/DMe3ZwvbX +Mtvfi8a41BndDPr+TLvmY7k5dSy0f+vxd8x3sThbmRKsyxKSQcIgIyat9sygC4/ohskMEKVUP+sP +kLNy2kjAo878HY5PYvaE6lvVkfNij61KadrogRoqjlbHzb4zf9BxYLZXqW3QVdZ5Uz3zwC/uq0zl +391WA/H6OmN1B2Lk2axh1QOAfxPMTxlt+De1krf9qJkFilpVHdqHHXVWznu/5p/+bNcPj9wpjqy3 +N6iCfFSVo+bx5NFg/fWPh2VatiuOoG/i7x6ro3H4Goz/7sOfZB2Ic06utKlcTafrVUTPoaDflZ86 +jlxJbE9Wnh9YJcnmbrzZv+l1/m6zR1bh6GMtDVoPfft4tX+UldqOCZ86EaEf6qp9yNmeJRBohPPk +CseKeyXz2/p/M7B0sR1Uedy1nelgrvWDz/zvafbx6/z47x7b5+2xkQb3n0d95mMYG8fe+HePPU5B +aP145O+WlRCbOSXcw0OEv0TlE7E/BeM+eaTeKiE54OrKJ/IDewq1Fi2C7gE68rT7Pc/+cLOPRMYD +8D2ur43LyuPxfdTjgAvm5+lslUZsVlz5MgI4OXIeFFWX0jszc9T7wrtoe/Ude4djng== + ]]> + <![CDATA[ + /RuffTxCH3bssRThdRfLgG1T2pQmid5LRhjbY39zPfW+332kn2Iw+x2OefY8e/TwrOaw20b3k7Pt +mdrxkOgc/p7R2fu+e3o9j/eB7/q759kfa/avtZ/v++6x46HaHgfcgAIlGNciHqZUd+LwCu1+oP/l +LkuHdabJxzx7nv0JzHbrabPCD8wes5X8dqP+5tnzbI6x7LORzt4Dy0F7vJtd8Zgzn2fPs+fZ8+x5 +9jx7nj3PnmfPs+fZ8+x59jx7nj3PnmfPs+fZ8+x59jx7nj3PnmfPs+fZ8+x59jx7nj3PnmfPs+fZ +8+x59jx7nj3PnmfPs+fZ8+x59jx7nj3PnmfPs+fZ8+x59jx7nj3PnmfPs+fZ8+x59jx7nj3PnmfP +s+fZ8+x59jx7nj3Pnmf/3c4+efTo5tWLJ7dvb0+e/9PJo6svt9+mf399+9Pbuzcnfzz515Pd6Wef +nz7/95NvyrNn1+V9z25/uXvz+DH/vr777uWreOXk7HQZ4yzG5nS13cZ/F7v0z2332rO/nHz2x7uf +T2/fvHn98+enz16dPPr2d1dv3j55+de3L1+/un3zy+nvu5eef/Xsmy+fnP7+tHv3t3r3H04/u/py +efZten/64+en/5De+Yf0X/req5Pl6fOf05P08D/p+dWPJ5dn6eXunP4U53V2ukr/Pf8l/eOf05P/ +Ti/9nE7xq9P/+M+z0xfdzK9PttvlYrddL0/Xm7PFdnmxPP3hZJWernarbf/as/61zep8sVlepJfK +1D0v2czrv6ST++ybV69uf7h7cfrdm9sXL+9evT3dnH2ui5YvH4/X352sl8vF+fnZefz78eVucbnb +7U7tDC7j657/kH7w+pIXq7c+vrjYXZb3Xf/1JL1lsTk7u7jnE69HP3G7Xi3Od+uNf+jf0hW8vh65 +m4N/d/fxxeu/3H179eWuu5n/9vaX7+++7d9U39kfT84WF5u0ghbnF5eb+L/uaix2Zytds+e36Vqn +s19v0imdXy4utpeX6c6V19ZnZ+kHn69Pvz85P79YrM52p+vL9WK5Sh/3/Z6p36dfs/eHxCl9c+Bv +R2BlaVhJS6TDSPpfhxaDylcvX7z4/u4ItDBhEmAcK8eApFso2/N1h+zdousSFJd6tVit1uf9a8/6 +19abbVrBF8JNTN3zks2cAJLH+cItu0aqi22shYSWx4LLylfs5tTO5SK+OMHl8eXZcrdYXVyu6/de +bi+W8YH5vWl1PxZm7vvY6/GP7X7f5WpdfewxoNn7i3/39d3t91/dvn3z8v/SW04/++Lqy3/U5frz +316/+YE/6ca/f9StNun3X67Sb7q8XJydBerKa6t0Gc63gbrlartYn6V7uz5bLdYXl7v0Wjv3I8Bu +lTFXS6jr12/fvv7hCNgx4YPCbrtdLy7T2jxdXmwXaTGVa73aLvvXnvWvrc6Xi+V2twooau6+12zu ++5FOaa3357Dm+0I8dRKme7V6L+KpvHFEPu37zOvRz9yuN4vz1Xn1qR9dQK0Wy4T69VmH3aX2zO6V +5Xq7WG5CFJ2f79LTZTrx5cXi8mK5DPFUT/wIKBlT5P78+scjMJLe/esAZL1Zp7ufNhkDSHnNALJZ +7RbbVdqnDQz7XrO57x0gm/WS77sPIOWN9wOkf+u9APFP/UQAsknS9/KiQkgs/WUSH4aQ9eX5IukO +K0NImflhIPLoX26/u/vzm9uX3yeAfPfT7f8mvezVq9dvb9/e/Zj+klbD3U9vX7+5O/3pv17/3L2S +puS3J7b1p6cn/w9Zz7vF + ]]> + </i:pgf> +</svg> diff --git a/src/libs/resiprocate/resip/stack/doc/resip-epoll-notes.txt b/src/libs/resiprocate/resip/stack/doc/resip-epoll-notes.txt new file mode 100644 index 00000000..8712dd9d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/resip-epoll-notes.txt @@ -0,0 +1,131 @@ +File: resip/stack/doc/resip-epoll-notes.txt +Author: Kennard White +Created: Nov 10, 2010 +Updated: Dec 3, 2010 + +This memo describes the epoll() support within resiprocate. + +NOTE: This only applies to platforms with epoll (most UNIX, but not Windows). + +Overview +-------- +The primary purpose of the first version of epoll() support is to allow +resiprocate to have more than 1024 sockets concurrently open. With +select() based system, the fd_set is compile-time limited to 1024 file +descriptors (starting at fd zero). Some systems (which?) allow this +to be increased at compile time, but there are several warnings in code +not to try this. So I didn't :-). + +See resip/stack/test/testStack for example of using epoll mode. + +For the curous, my immediate application for needing many concurrent sockets +is a server-side instance of repro that is handling TCP connections in +"outbound" mode; e.g. the connection stay open indefinately. + +By default, epoll() support is disabled. A runtime call to +SipStack::setDefaultUseInternalPoll(true). must be made to turn-on +epoll support. + +This version uses epoll() internally, but doesn't change any external +interfaces. E.g., StackThread doesn't change at all. This is possible +for two reasons: + * epoll maybe used hierarchically/recursively. + * select works fine for handful of descriptors that are small + +In particular, it is possible to select() on the epoll +file-descriptor(s). SipStack internally opens an epoll descriptor that +it uses to manage sockets resip-ares (for DNS lookup) and transports. +This epoll descriptor is passe up to the threads which can then use +select. All the descriptors seen by select are opened up early and are +less than 1024. + +Performance +----------- +This primary purpose of the change is to support a large number of +transports/connections, something that is just not possible with select(). +The epoll support, in its current form, actually makes things slower! +This is because (I assume) there are two levels of system calls involved. + +Changes closely related to epoll +-------------------------------- +Added rutil/FdPoll files and related classes. This implements the system +calls for epoll. Note that this ONLY supports epoll, unlike Poll.hxx +which ONLY supports select and poll. (Aside from the system calls used, +the purpose and interfaces are different). + +Changes to contrib/ares and rutil/dns/AresDns. The challenge here is +that while ares only uses a handful of concurrent socket, they are +dynamically opened. In particular, they can be opened after we have all +of our tranport sockets open, and thus ares will get fds > 1024 and the +fdset stuff will fail. Thus needed to make ares work with epoll. Added +new callback system from contrib/ares into AresDns class, which then +handles the epoll interface on its behalf. This is the trickiest +set of changes. + +Plumb useInternalPoll flag from SipStack, ExternalDns, DnsStub, to AresDns. + +For Transport, when using InternalPoll, work previously performed by +process() is now performed by combination of processPollEvent() and +processTransmmitQueue(). The former is called by the FdPoll dispatcher, +while the later is called by TransportSelector. + +Restructure Connection objects to pass received messages up +to owning transport rather than using a fifo passed in via process(). + +resip/stack/test/testStack extended to have --epoll option to enable. +This doesn't test very much yet, but it is something. + +Other Changes +------------- +Changed UdpTransport::hasDataToSend() to always return false. We use +the socket-writability callback (fdset or poll) to drive draining the +queue. Returning true here makes the select() timeout zero, which isn't +what we want. E.g., we will wait for writability, even if process() is +immediately invoked. + +Fix some test programs (port selection & log levels) + +Fix ares set non-blocking function. Added a lot of diags (now commented out) +to find this problem. + +Add getSocketError() function to rutil/Socket.cxx + +Clarify the multi-platform Socket support in rutil/Socket.hxx + +Fix compiler warning in OpenSSLInit.cxx + +Fix int vs long int warnings in ares + +Questions +--------- +Does any code use rutil/Poll.hxx? + +Valgrind w/epoll +---------------- +Valgrind has issues when the application is using more than ~1000 sockets. +See bug http://bugs.kde.org/show_bug.cgi?id=73146 +As written in the bug report "it doesn't seem that important". +You cannot use resip::increaseLimitFds() (e.g., -n to testStack). +To work around, this you need to increase the number of allowed fds *before* +running valgrind. E.g.: + % sudo bash + # ulimit -Hn 200000 + # ulimit -Sn 200000 + # valgrind --leak-check=full ./testStack -n 10000 + +Vi editing +---------- +(These probably belong elsewhere). Resip uses 3-space indends +without tabs. Suitable options for vi are: + set shiftwidth=3 + set expandtab + +The command + :%retab +will get rid of all existing tabs + +The following can be added at the bottom of each file: + /* ex: set shiftwidth=3 expandtab: */ +For above to work, you must have modelines enabled in your ~/.vimrc + set modeline +It is disabled by default on many platforms for security reasons. diff --git a/src/libs/resiprocate/resip/stack/doc/server-invite-state.tif b/src/libs/resiprocate/resip/stack/doc/server-invite-state.tif new file mode 100644 index 00000000..73a0d4ef Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/server-invite-state.tif differ diff --git a/src/libs/resiprocate/resip/stack/doc/server-invite-tree.tif b/src/libs/resiprocate/resip/stack/doc/server-invite-tree.tif new file mode 100644 index 00000000..ee1610bd Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/server-invite-tree.tif differ diff --git a/src/libs/resiprocate/resip/stack/doc/server-noninvite-state.tif b/src/libs/resiprocate/resip/stack/doc/server-noninvite-state.tif new file mode 100644 index 00000000..b819cbfa Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/server-noninvite-state.tif differ diff --git a/src/libs/resiprocate/resip/stack/doc/server-noninvite-tree.tif b/src/libs/resiprocate/resip/stack/doc/server-noninvite-tree.tif new file mode 100644 index 00000000..256843cb Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/server-noninvite-tree.tif differ diff --git a/src/libs/resiprocate/resip/stack/doc/srv-inv-fsm.dot b/src/libs/resiprocate/resip/stack/doc/srv-inv-fsm.dot new file mode 100644 index 00000000..990ff9ba --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/srv-inv-fsm.dot @@ -0,0 +1,165 @@ +digraph moonshine_ua_fsm { +// rankdir=LR +// size="10,8" + ratio=0.8 // !ah! might be off +// rotate=90 + compound=true + fontsize=18 + fontname="Helvetica" + node [ fonstsize=8 fontname="Helvetica" ] + graph + [ +// ranksep=1.5 // modify to shrink nodes etc +// nodesep=1.5 + fontsize=8 + fontname="Helvetica" + labelfontsize=8 + labelfontname="Helvetica" + ] + + edge + [ + fontname="Helvetica" + fontsize=8 + arrowhead=normal + ] + +// Now setup labels and visual stuff. + + INIT + [ + style=filled + fillcolor=palegreen + fixedsize=true + shape=Mcircle + ] + + INIT -> TRYING + [ label="rcv(INV):\ntimerStart(TRYING)(<200ms)\npass(INV)" ] + + subgraph cluster_x { + style=invis + p1PROCEEDING + p2PROCEEDING + } + + TRYING -> p1PROCEEDING + + TRYING -> p2PROCEEDING + + p1PROCEEDING + [ + fontsize=8 + shape=plaintext + label="got(1xx):\nsnd(reponse)" + ] + + p2PROCEEDING + [ + fontsize=8 + shape=plaintext + label="rcv(INV) | timerExpires(TRYING):\nsnd(100)" + ] + + p1PROCEEDING -> PROCEEDING + p2PROCEEDING -> PROCEEDING + + PROCEEDING -> p1PROCEEDING + PROCEEDING -> p2PROCEEDING + + PROCEEDING -> pTxError + + pTxError + [ + shape=plaintext + label="transport error:\nnotify TU" + fontsize=8 + ] + + pTxError -> DELETE + + PROCEEDING -> pCOMPLETED + [ constraint=false ] + + pCOMPLETED -> COMPLETED + + pCOMPLETED + [ + shape=plaintext + fontsize=8 + label="got(300-699):\nsnd(response)" + ] + + COMPLETED -> pTxError + [ + constraint=false + ] + + COMPLETED -> COMPLETED + [ + label="expireTimer(G):\nsnd(response)\nG = 2G\nstartTimer(G)" + ] + + COMPLETED -> COMPLETED + [ + label="rcv(INVITE):\nsnd(response)" + ] + + PROCEEDING -> pSTALE + [ constraint=false ] + + pSTALE + [ + shape=plaintext + label="got(2XX):\nsetTimer(STALE),snd(response)" + fontsize=8 + ] + + TRYING -> pCOMPLETED + + TRYING -> pSTALE +// [ constraint = false ] + + pSTALE -> STALE + [ constraint = false ] + + STALE -> STALE + [ + label="rcv(ACK):\nsnd to TU" + ] + + + STALE -> DELETE + [ + label="timerExpires(STALE)" + ] + + COMPLETED -> CONFIRMED + [ + label="rcv(ACK):\nstartTimer(I)" + ] + + CONFIRMED -> DELETE + [ + label="expireTimer(I)" + ] + + DELETE + [ + style=filled + fillcolor=pink + shape=doublecircle + label=DEL + fixedsize=true + ] + + LABEL_NODE + [ + shape=plaintext + fontsize=6 + label="Server INVITE FSM\n$Id: srv-inv-fsm.dot,v 1.3 2002/09/22 22:04:13 fluffy Exp $ $Name: $" + ] + + + // Fixups +} diff --git a/src/libs/resiprocate/resip/stack/doc/srv-inv-tree.dot b/src/libs/resiprocate/resip/stack/doc/srv-inv-tree.dot new file mode 100644 index 00000000..32b5d20b --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/srv-inv-tree.dot @@ -0,0 +1,143 @@ +digraph srv_inv_tree { + rankdir=LR + size="8,10" + ratio=0.8 // !ah! might be off + rotate=90 + compound=true + fontname="Helvetica" + fontsize=6 + node [ + style=invis +// fixedsize=true + fontsize=8 + shape=circle +// width="0.01" +// height="0.01" + fontname="Helvetica" + ] + graph + [ +// ranksep=1.5 // modify to shrink nodes etc +// nodesep=1.5 + fontsize=8 + fontname="Helvetica" + labelfontsize=8 + labelfontname="Helvetica" + ] + + edge + [ + fontname="Helvetica" + fontsize=8 + arrowhead=normal + ] + +// Now setup labels and visual stuff. + + { rank=same ; n1; } + { rank=same ; n2 n3; } + { rank=same ; n11 n10 n9 n8; } + { rank=same ; n32 n25 n26 n23 n27 n28; } + + n0 -> n1 [ label="got(resp)" ] + n1 -> n3 [ label="CANCEL" ] + n3 [fixedsize=false style=solid shape=box label="Proc. SRV non-INV"] + n1 -> n2 [ label="cSeq=INV" ] + n2 -> n4 [ label="101-199" ] + n4 -> n11 [ label="Try|Proc" ] + + n11[ + fixedsize=false style=solid shape=box + label="Proceeding\nsend(RESP)\nsave for re-TX" + ] + + n4 -> n10 [ label="*" ] + n10 [fixedsize=false style=solid shape=box label="ign"] + + n2 -> n9 [ label="2xx" ] + n9 [ + fixedsize=false style=solid shape=box + fontsize=8 + label="snd(RESP)\nmach=stale\nstate=term?\nsetTimer(STALE)\nTS\n" + ] + n2 -> n8 [ label="300-699" ] + n8 [ + style=solid + shape=box + fixedsize=false + fontsize=8 + label="snd(RESP)\nsetTimer(H)\nunrel? -> setTimer(G)\nT1" + ] + + n2 -> n5 [ label="100" ] + n5 -> n6 [ label="Trying" ] + n6 [ + fixedsize=false style=solid shape=box + label="snd(PROCEEDING)" + ] + + n5 -> n7 [ label="*" ] + n7 [fixedsize=false style=solid shape=box label="ign" ] + + { rank=same; n13 n16 n21;} + + n0 -> n12 [ label="rcv(request)" ] + n12 -> n13 [ label="INV" ] + n13 -> n14 [ label="Proc | Completed"] + n14 [ + fixedsize=false style=solid shape=box + label="SEND" + ] + n13 -> n15 [ label="*" ] + + n15[fixedsize=false style=solid shape=box label="ign"] + + n12 -> n16 [label="ACK"] + n16 -> n17 [label="Completed"] + n17 -> n18 [label="reliable"] + n18 [fixedsize=false style=solid shape=box label="del(FSM)"] + + n17 -> n19 [label="unreliable"] + n19 [fixedsize=false style=solid shape=box label="confirmed\ntimerStart(I)" fontsize=6 ] + + n12 -> n21 [label="CANCEL"] + n21[fixedsize=false style=solid shape=box label="proc. srv non-INV"] + + n0 -> n22 [label="timer exp"] + n22 -> n23[label="J"] + n23 [fixedsize=false style=solid shape=box label="delState(CANCEL)"] + n22 -> n24 [label="G"] + n24 -> n25 [label="completed"] + n25[fixedsize=false style=solid shape=box label="G = 2G\nstartTimer(G)"] + + n24 -> n26 [label="*"] + n26 [fixedsize=false style=solid shape=box label="ign"] + + n22 -> n27 [label="H"] + n27[fixedsize=false style=solid shape=box label="delState(THIS)"] + + n22 -> n28 [label=I] + n28[fixedsize=false style=solid shape=box label="delState(THIS)"] + + n22 -> n29 [label=Try] + n29 -> n30 [label="*"] + n30[fixedsize=false style=solid shape=box label=ign] + n29 -> n31 [label="Trying?"] + n31[fixedsize=false style=solid shape=box label="Proceeding\nsnd(100)"] + + n0 -> n32[label="Transport Error"] + n32[fixedsize=false style=solid shape=box label="delState(THIS)"] + + LABEL_NODE + [ + fixedsize=false + style=solid + shape=plaintext + fontsize=6 + label="Server INVITE FSM\n$Id: srv-inv-tree.dot,v 1.2 2002/09/23 00:11:57 fluffy Exp $ $Name: $" + ] + + + // Fixups + +} diff --git a/src/libs/resiprocate/resip/stack/doc/stale-state.tif b/src/libs/resiprocate/resip/stack/doc/stale-state.tif new file mode 100644 index 00000000..00661dae Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/stale-state.tif differ diff --git a/src/libs/resiprocate/resip/stack/doc/stale-tree.tif b/src/libs/resiprocate/resip/stack/doc/stale-tree.tif new file mode 100644 index 00000000..de4367c3 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/stale-tree.tif differ diff --git a/src/libs/resiprocate/resip/stack/doc/static/Makefile.am b/src/libs/resiprocate/resip/stack/doc/static/Makefile.am new file mode 100644 index 00000000..dfe5e586 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/static/Makefile.am @@ -0,0 +1,7 @@ + +EXTRA_DIST = *.pdf +EXTRA_DIST += *.png +EXTRA_DIST += *.ps +EXTRA_DIST += *.svg + + diff --git a/src/libs/resiprocate/resip/stack/doc/static/Preparse.pdf b/src/libs/resiprocate/resip/stack/doc/static/Preparse.pdf new file mode 100644 index 00000000..470e6821 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/static/Preparse.pdf differ diff --git a/src/libs/resiprocate/resip/stack/doc/static/Preparse.png b/src/libs/resiprocate/resip/stack/doc/static/Preparse.png new file mode 100644 index 00000000..954c2f83 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/static/Preparse.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/static/Preparse.ps b/src/libs/resiprocate/resip/stack/doc/static/Preparse.ps new file mode 100644 index 00000000..c75c6294 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/static/Preparse.ps @@ -0,0 +1,1369 @@ +%!PS-Adobe-2.0 +%%Creator: dot version 1.9 (Wed Apr 16 21:58:33 MDT 2003) +%%For: (alan) +%%Title: pp_fsm +%%Pages: (atend) +%%BoundingBox: 35 35 613 748 +%%EndComments +save +%%BeginProlog +/DotDict 200 dict def +DotDict begin + +/setupLatin1 { +mark +/EncodingVector 256 array def + EncodingVector 0 + +ISOLatin1Encoding 0 255 getinterval putinterval + +EncodingVector + dup 306 /AE + dup 301 /Aacute + dup 302 /Acircumflex + dup 304 /Adieresis + dup 300 /Agrave + dup 305 /Aring + dup 303 /Atilde + dup 307 /Ccedilla + dup 311 /Eacute + dup 312 /Ecircumflex + dup 313 /Edieresis + dup 310 /Egrave + dup 315 /Iacute + dup 316 /Icircumflex + dup 317 /Idieresis + dup 314 /Igrave + dup 334 /Udieresis + dup 335 /Yacute + dup 376 /thorn + dup 337 /germandbls + dup 341 /aacute + dup 342 /acircumflex + dup 344 /adieresis + dup 346 /ae + dup 340 /agrave + dup 345 /aring + dup 347 /ccedilla + dup 351 /eacute + dup 352 /ecircumflex + dup 353 /edieresis + dup 350 /egrave + dup 355 /iacute + dup 356 /icircumflex + dup 357 /idieresis + dup 354 /igrave + dup 360 /dcroat + dup 361 /ntilde + dup 363 /oacute + dup 364 /ocircumflex + dup 366 /odieresis + dup 362 /ograve + dup 365 /otilde + dup 370 /oslash + dup 372 /uacute + dup 373 /ucircumflex + dup 374 /udieresis + dup 371 /ugrave + dup 375 /yacute + dup 377 /ydieresis + +% Set up ISO Latin 1 character encoding +/starnetISO { + dup dup findfont dup length dict begin + { 1 index /FID ne { def }{ pop pop } ifelse + } forall + /Encoding EncodingVector def + currentdict end definefont +} def +/Times-Roman starnetISO def +/Times-Italic starnetISO def +/Times-Bold starnetISO def +/Times-BoldItalic starnetISO def +/Helvetica starnetISO def +/Helvetica-Oblique starnetISO def +/Helvetica-Bold starnetISO def +/Helvetica-BoldOblique starnetISO def +/Courier starnetISO def +/Courier-Oblique starnetISO def +/Courier-Bold starnetISO def +/Courier-BoldOblique starnetISO def +cleartomark +} bind def + +%%BeginResource: procset +/coord-font-family /Times-Roman def +/default-font-family /Times-Roman def +/coordfont coord-font-family findfont 8 scalefont def + +/InvScaleFactor 1.0 def +/set_scale { + dup 1 exch div /InvScaleFactor exch def + dup scale +} bind def + +% styles +/solid { [] 0 setdash } bind def +/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def +/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def +/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def +/bold { 2 setlinewidth } bind def +/filled { } bind def +/unfilled { } bind def +/rounded { } bind def +/diagonals { } bind def + +% hooks for setting color +/nodecolor { sethsbcolor } bind def +/edgecolor { sethsbcolor } bind def +/graphcolor { sethsbcolor } bind def +/nopcolor {pop pop pop} bind def + +/beginpage { % i j npages + /npages exch def + /j exch def + /i exch def + /str 10 string def + npages 1 gt { + gsave + coordfont setfont + 0 0 moveto + (\() show i str cvs show (,) show j str cvs show (\)) show + grestore + } if +} bind def + +/set_font { + findfont exch + scalefont setfont +} def + +% draw aligned label in bounding box aligned to current point +/alignedtext { % width adj text + /text exch def + /adj exch def + /width exch def + gsave + width 0 gt { + text stringwidth pop adj mul 0 rmoveto + } if + [] 0 setdash + text show + grestore +} def + +/boxprim { % xcorner ycorner xsize ysize + 4 2 roll + moveto + 2 copy + exch 0 rlineto + 0 exch rlineto + pop neg 0 rlineto + closepath +} bind def + +/ellipse_path { + /ry exch def + /rx exch def + /y exch def + /x exch def + matrix currentmatrix + newpath + x y translate + rx ry scale + 0 0 1 0 360 arc + setmatrix +} bind def + +/endpage { showpage } bind def + +/layercolorseq + [ % layer color sequence - darkest to lightest + [0 0 0] + [.2 .8 .8] + [.4 .8 .8] + [.6 .8 .8] + [.8 .8 .8] + ] +def + +/layerlen layercolorseq length def + +/setlayer {/maxlayer exch def /curlayer exch def + layercolorseq curlayer 1 sub layerlen mod get + aload pop sethsbcolor + /nodecolor {nopcolor} def + /edgecolor {nopcolor} def + /graphcolor {nopcolor} def +} bind def + +/onlayer { curlayer ne {invis} if } def + +/onlayers { + /myupper exch def + /mylower exch def + curlayer mylower lt + curlayer myupper gt + or + {invis} if +} def + +/curlayer 0 def + +%%EndResource +%%EndProlog +%%BeginSetup +14 default-font-family set_font +1 setmiterlimit +% /arrowlength 10 def +% /arrowwidth 5 def + +% make sure pdfmark is harmless for PS-interpreters other than Distiller +/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse +% make '<<' and '>>' safe on PS Level 1 devices +/languagelevel where {pop languagelevel}{1} ifelse +2 lt { + userdict (<<) cvn ([) cvn load put + userdict (>>) cvn ([) cvn load put +} if + +%%EndSetup +%%Page: 1 1 +%%PageBoundingBox: 36 36 613 748 +%%PageOrientation: Landscape +gsave +35 35 578 713 boxprim clip newpath +36 36 translate +gsave 576 0 translate 90 rotate +0 0 1 beginpage +grestore +0.4804 set_scale +1199 0 translate 90 rotate +0.000 0.000 0.000 graphcolor +14.00 /Helvetica set_font + +% NewMsg +gsave 10 dict begin +117 1173 43 18 ellipse_path +stroke +gsave 10 dict begin +117 1168 moveto 64 -0.5 (NewMsg) alignedtext +end grestore +end grestore + +% StartLine +gsave 10 dict begin +209 1061 42 18 ellipse_path +stroke +gsave 10 dict begin +209 1056 moveto 63 -0.5 (StartLine) alignedtext +end grestore +end grestore + +% NewMsg -> StartLine +newpath 135 1157 moveto +145 1147 158 1135 167 1124 curveto +177 1112 187 1098 194 1086 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 196 1088 moveto +199 1078 lineto +192 1085 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +198 1114 moveto 31 -0.5 (X, Add ) alignedtext +end grestore + +% NewMsgCrLf +gsave 10 dict begin +60 1061 60 18 ellipse_path +stroke +gsave 10 dict begin +60 1056 moveto 99 -0.5 (NewMsgCrLf) alignedtext +end grestore +end grestore + +% NewMsg -> NewMsgCrLf +newpath 86 1160 moveto +71 1152 54 1140 45 1124 curveto +39 1113 41 1099 46 1088 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 48 1089 moveto +49 1079 lineto +43 1088 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +73 1114 moveto 42 -0.5 (CR, None ) alignedtext +end grestore + +% StartLine -> StartLine +newpath 238 1048 moveto +254 1046 269 1050 269 1061 curveto +269 1070 260 1074 248 1074 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 248 1072 moveto +238 1074 lineto +248 1077 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +287 1058 moveto 29 -0.5 (X, Add) alignedtext +end grestore + +% StartLineCrLf +gsave 10 dict begin +209 950 60 18 ellipse_path +stroke +gsave 10 dict begin +209 945 moveto 98 -0.5 (StartLineCrLf) alignedtext +end grestore +end grestore + +% StartLine -> StartLineCrLf +newpath 209 1043 moveto +209 1025 209 998 209 977 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 212 978 moveto +209 968 lineto +207 978 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +233 1003 moveto 39 -0.5 (CR, None) alignedtext +end grestore + +% NewMsgCrLf -> NewMsg +newpath 112 1146 moveto +109 1135 105 1121 99 1110 curveto +93 1098 85 1087 77 1078 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 109 1146 moveto +114 1155 lineto +114 1145 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +135 1114 moveto 48 -0.5 (LF, Discard ) alignedtext +end grestore + +% EndMsg +gsave 10 dict begin +794 56 40 18 ellipse_path +stroke +gsave 10 dict begin +794 51 moveto 58 -0.5 (EndMsg) alignedtext +end grestore +end grestore + +% NewMsgCrLf -> EndMsg +newpath 60 1043 moveto +60 1021 60 983 60 950 curveto +60 950 60 950 60 168 curveto +60 74 449 84 623 68 curveto +675 63 688 61 741 58 curveto +742 58 744 58 745 58 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 744 61 moveto +754 57 lineto +744 56 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +94 556 moveto 60 -0.5 (X, Bad|Discard ) alignedtext +end grestore + +% StartLineCrLf -> EndMsg +newpath 195 932 moveto +179 911 156 874 156 838 curveto +156 838 156 838 156 168 curveto +156 108 595 71 745 60 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 744 63 moveto +754 59 lineto +744 58 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +189 500 moveto 57 -0.5 (X, Bad|Discard) alignedtext +end grestore + +% BuildHdr +gsave 10 dict begin +1080 838 43 18 ellipse_path +stroke +gsave 10 dict begin +1080 833 moveto 65 -0.5 (BuildHdr) alignedtext +end grestore +end grestore + +% StartLineCrLf -> BuildHdr +newpath 264 943 moveto +423 922 880 864 1031 844 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 1029 847 moveto +1039 843 lineto +1029 842 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +716 891 moveto 87 -0.5 (LF, Reset|Fline|Discard) alignedtext +end grestore + +% BuildHdr -> BuildHdr +newpath 1110 825 moveto +1126 823 1141 827 1141 838 curveto +1141 846 1132 851 1121 851 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 1120 849 moveto +1110 851 lineto +1120 854 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +1159 835 moveto 29 -0.5 (X, Add) alignedtext +end grestore + +% EWSPostHdr +gsave 10 dict begin +1165 726 57 18 ellipse_path +stroke +gsave 10 dict begin +1165 721 moveto 92 -0.5 (EWSPostHdr) alignedtext +end grestore +end grestore + +% BuildHdr -> EWSPostHdr +newpath 1093 821 moveto +1107 802 1130 772 1146 751 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 1147 754 moveto +1151 744 lineto +1143 751 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +1151 779 moveto 46 -0.5 (LWS, None) alignedtext +end grestore + +% EWSPostColon +gsave 10 dict begin +826 615 63 18 ellipse_path +stroke +gsave 10 dict begin +826 610 moveto 105 -0.5 (EWSPostColon) alignedtext +end grestore +end grestore + +% BuildHdr -> EWSPostColon +newpath 1050 825 moveto +1016 809 960 780 921 744 curveto +888 713 858 670 841 642 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 843 641 moveto +836 633 lineto +839 643 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +996 723 moveto 137 -0.5 (COLON, Hdr|Reset|DiscardKnown) alignedtext +end grestore + +% EWSPostHdr -> EndMsg +newpath 1204 713 moveto +1243 696 1299 665 1299 615 curveto +1299 615 1299 615 1299 168 curveto +1299 89 1235 84 1162 58 curveto +1158 56 945 56 844 56 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 844 54 moveto +834 56 lineto +844 59 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +1332 388 moveto 57 -0.5 (X, Bad|Discard) alignedtext +end grestore + +% EWSPostHdr -> EWSPostHdr +newpath 1204 713 moveto +1223 711 1240 716 1240 726 curveto +1240 734 1229 739 1215 739 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 1214 737 moveto +1204 739 lineto +1214 742 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +1267 723 moveto 46 -0.5 (LWS, None) alignedtext +end grestore + +% EWSPostHdr -> EWSPostColon +newpath 1125 713 moveto +1064 693 945 654 877 632 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 877 629 moveto +867 629 lineto +876 634 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +1087 667 moveto 137 -0.5 (COLON, Hdr|Reset|DiscardKnown) alignedtext +end grestore + +% EWSPostColon -> EWSPostColon +newpath 869 602 moveto +889 600 907 605 907 615 curveto +907 623 895 628 880 628 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 879 626 moveto +869 628 lineto +879 631 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +965 612 moveto 107 -0.5 (LWS, Reset|DiscardKnown) alignedtext +end grestore + +% BuildData +gsave 10 dict begin +532 503 46 18 ellipse_path +stroke +gsave 10 dict begin +532 498 moveto 70 -0.5 (BuildData) alignedtext +end grestore +end grestore + +% EWSPostColon -> BuildData +newpath 765 610 moveto +673 603 506 586 489 566 curveto +478 553 489 538 502 525 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 503 527 moveto +509 519 lineto +500 524 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +507 556 moveto 29 -0.5 (X, Add) alignedtext +end grestore + +% EmptyHdrCrLf +gsave 10 dict begin +1192 503 66 18 ellipse_path +stroke +gsave 10 dict begin +1192 498 moveto 111 -0.5 (EmptyHdrCrLf) alignedtext +end grestore +end grestore + +% EWSPostColon -> EmptyHdrCrLf +newpath 857 599 moveto +885 585 929 565 969 552 curveto +1021 535 1081 522 1127 513 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 1125 516 moveto +1135 512 lineto +1125 511 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +1023 556 moveto 99 -0.5 (CR, Reset|DiscardKnown) alignedtext +end grestore + +% InAng +gsave 10 dict begin +613 391 33 18 ellipse_path +stroke +gsave 10 dict begin +613 386 moveto 45 -0.5 (InAng) alignedtext +end grestore +end grestore + +% EWSPostColon -> InAng +newpath 820 597 moveto +813 578 804 548 801 521 curveto +798 505 798 500 801 485 curveto +803 470 808 468 811 454 curveto +811 447 814 444 811 440 curveto +802 428 709 408 653 399 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 654 397 moveto +644 397 lineto +653 402 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +867 500 moveto 124 -0.5 (LAQUOT, Add \(dCommaSep\)) alignedtext +end grestore + +% InQ +gsave 10 dict begin +271 391 27 18 ellipse_path +stroke +gsave 10 dict begin +271 386 moveto 26 -0.5 (InQ) alignedtext +end grestore +end grestore + +% EWSPostColon -> InQ +newpath 763 613 moveto +714 609 701 606 652 601 curveto +517 585 476 587 359 521 curveto +316 497 295 496 273 454 curveto +267 443 266 430 267 418 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 269 419 moveto +268 409 lineto +264 419 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +421 500 moveto 110 -0.5 (QUOT, Add \(dCommaSep\)) alignedtext +end grestore + +% BuildData -> EWSPostColon +newpath 760 606 moveto +687 596 577 578 562 566 curveto +547 555 540 535 536 521 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 759 608 moveto +769 607 lineto +759 603 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +671 556 moveto 203 -0.5 (COMMA, Data|Reset|DiscardKnown \(dCommaSep\)) alignedtext +end grestore + +% BuildData -> BuildData +newpath 564 490 moveto +581 488 596 492 596 503 curveto +596 512 587 516 574 516 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 574 514 moveto +564 516 lineto +574 519 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +614 500 moveto 29 -0.5 (X, Add) alignedtext +end grestore + +% BuildData -> InAng +newpath 556 488 moveto +568 479 582 467 591 454 curveto +598 443 603 429 607 418 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 609 419 moveto +609 409 lineto +604 418 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +661 444 moveto 121 -0.5 (LAQUOT, Add \(dCommaSep\)) alignedtext +end grestore + +% BuildData -> InQ +newpath 489 497 moveto +429 488 300 469 285 454 curveto +276 444 273 430 271 418 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 274 419 moveto +270 409 lineto +269 419 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +345 444 moveto 108 -0.5 (QUOT, Add \(dCommaSep\)) alignedtext +end grestore + +% BuildDataCrLf +gsave 10 dict begin +783 391 64 18 ellipse_path +stroke +gsave 10 dict begin +783 386 moveto 106 -0.5 (BuildDataCrLf) alignedtext +end grestore +end grestore + +% BuildData -> BuildDataCrLf +newpath 578 500 moveto +620 495 682 483 729 454 curveto +744 444 757 429 767 416 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 768 419 moveto +772 409 lineto +764 416 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +776 444 moveto 55 -0.5 (CR, None|Flat) alignedtext +end grestore + +% EmptyHdrCrLf -> EndMsg +newpath 1196 485 moveto +1200 463 1206 424 1206 391 curveto +1206 391 1206 391 1206 168 curveto +1206 0 1011 83 843 59 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 844 57 moveto +834 58 lineto +844 62 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +1239 276 moveto 57 -0.5 (X, Bad|Discard) alignedtext +end grestore + +% EmptyHdrCont +gsave 10 dict begin +1082 391 65 18 ellipse_path +stroke +gsave 10 dict begin +1082 386 moveto 109 -0.5 (EmptyHdrCont) alignedtext +end grestore +end grestore + +% EmptyHdrCrLf -> EmptyHdrCont +newpath 1141 491 moveto +1121 484 1100 472 1087 454 curveto +1080 444 1078 430 1078 418 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 1080 419 moveto +1079 409 lineto +1075 419 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +1139 444 moveto 97 -0.5 (LF, Reset|DiscardKnown) alignedtext +end grestore + +% EmptyHdrCont -> BuildHdr +newpath 1127 828 moveto +1235 809 1345 836 1345 726 curveto +1345 726 1345 726 1345 503 curveto +1345 457 1211 420 1134 402 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 1127 825 moveto +1118 830 lineto +1128 830 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +1413 612 moveto 128 -0.5 (X, Reset|Back|Discard|EmptyHdr) alignedtext +end grestore + +% EmptyHdrCont -> EWSPostColon +newpath 854 592 moveto +876 573 909 545 937 521 curveto +993 471 1006 446 1057 408 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 853 590 moveto +847 598 lineto +856 593 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +1030 500 moveto 107 -0.5 (LWS, Reset|DiscardKnown) alignedtext +end grestore + +% CheckEndHdr +gsave 10 dict begin +913 168 61 18 ellipse_path +stroke +gsave 10 dict begin +913 163 moveto 100 -0.5 (CheckEndHdr) alignedtext +end grestore +end grestore + +% EmptyHdrCont -> CheckEndHdr +newpath 1074 373 moveto +1055 329 1007 222 1001 216 curveto +989 203 974 194 959 186 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 961 184 moveto +951 182 lineto +959 189 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +1111 276 moveto 135 -0.5 (CR, Data|Reset|Discard|EmptyHdr) alignedtext +end grestore + +% CheckEndHdr -> EndMsg +newpath 909 150 moveto +905 136 898 117 887 105 curveto +873 89 853 78 835 70 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 837 68 moveto +827 67 lineto +835 73 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +930 109 moveto 57 -0.5 (X, Bad|Discard) alignedtext +end grestore + +% CheckEndHdr -> EndMsg +newpath 859 160 moveto +835 153 808 141 794 119 curveto +787 109 786 95 787 83 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 789 84 moveto +789 74 lineto +784 83 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +839 109 moveto 81 -0.5 (LF, EndHdrs|Discard) alignedtext +end grestore + +% InAng -> BuildData +newpath 515 478 moveto +509 466 506 452 513 440 curveto +528 415 558 403 582 397 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 512 478 moveto +519 486 lineto +517 476 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +549 444 moveto 63 -0.5 (RAQUOT, Add) alignedtext +end grestore + +% InAng -> InAng +newpath 637 378 moveto +651 376 664 380 664 391 curveto +664 399 657 403 647 404 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 647 402 moveto +637 404 lineto +647 407 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +682 388 moveto 29 -0.5 (X, Add) alignedtext +end grestore + +% InAngQ +gsave 10 dict begin +557 279 39 18 ellipse_path +stroke +gsave 10 dict begin +557 274 moveto 57 -0.5 (InAngQ) alignedtext +end grestore +end grestore + +% InAng -> InAngQ +newpath 589 379 moveto +575 370 560 358 552 342 curveto +546 331 547 317 549 306 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 551 307 moveto +551 297 lineto +546 306 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +580 332 moveto 49 -0.5 (QUOT, Add) alignedtext +end grestore + +% InQ -> BuildData +newpath 486 489 moveto +456 474 445 458 405 440 curveto +368 423 323 407 296 399 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 484 491 moveto +494 493 lineto +486 486 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +461 444 moveto 49 -0.5 (QUOT, Add) alignedtext +end grestore + +% InQ -> InQ +newpath 291 379 moveto +304 375 316 379 316 391 curveto +316 400 309 404 301 404 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 301 402 moveto +291 403 lineto +301 406 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +334 388 moveto 29 -0.5 (X, Add) alignedtext +end grestore + +% InQEsc +gsave 10 dict begin +274 279 36 18 ellipse_path +stroke +gsave 10 dict begin +274 274 moveto 50 -0.5 (InQEsc) alignedtext +end grestore +end grestore + +% InQ -> InQEsc +newpath 274 373 moveto +276 364 278 352 278 342 curveto +279 330 278 317 277 306 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 280 307 moveto +276 297 lineto +275 307 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +312 332 moveto 58 -0.5 (LSLASH, Add) alignedtext +end grestore + +% BuildDataCrLf -> EndMsg +newpath 782 373 moveto +781 327 778 205 783 105 curveto +783 95 781 88 780 81 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 783 83 moveto +780 73 lineto +778 83 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +812 220 moveto 57 -0.5 (X, Bad|Discard) alignedtext +end grestore + +% CheckCont +gsave 10 dict begin +889 279 49 18 ellipse_path +stroke +gsave 10 dict begin +889 274 moveto 77 -0.5 (CheckCont) alignedtext +end grestore +end grestore + +% BuildDataCrLf -> CheckCont +newpath 787 373 moveto +790 359 797 340 808 328 curveto +819 315 834 305 848 297 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 849 299 moveto +856 292 lineto +846 295 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +838 332 moveto 53 -0.5 (LF, None|Flat) alignedtext +end grestore + +% CheckCont -> BuildHdr +newpath 1081 811 moveto +1085 731 1094 499 1088 485 curveto +1068 439 1042 443 1008 409 curveto +969 370 926 321 904 296 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 1079 810 moveto +1081 820 lineto +1084 810 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +1145 556 moveto 103 -0.5 (X, Data|Reset|Back|Discard) alignedtext +end grestore + +% CheckCont -> BuildData +newpath 588 501 moveto +597 499 601 499 612 497 curveto +701 481 731 497 811 454 curveto +835 440 842 433 856 409 curveto +876 373 884 324 887 297 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 588 499 moveto +578 501 lineto +588 504 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +895 388 moveto 44 -0.5 (LWS, Add ) alignedtext +end grestore + +% CheckCont -> CheckEndHdr +newpath 893 261 moveto +897 243 903 215 907 195 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 909 196 moveto +909 186 lineto +904 195 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +949 220 moveto 88 -0.5 (CR, Data|Reset|Discard) alignedtext +end grestore + +% InAngQ -> InAng +newpath 618 364 moveto +618 352 618 339 613 328 curveto +606 313 593 301 581 293 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 616 363 moveto +617 373 lineto +621 363 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +644 332 moveto 49 -0.5 (QUOT, Add) alignedtext +end grestore + +% InAngQ -> InAngQ +newpath 585 266 moveto +600 264 614 268 614 279 curveto +614 287 606 292 596 292 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 595 290 moveto +585 292 lineto +595 295 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +632 276 moveto 29 -0.5 (X, Add) alignedtext +end grestore + +% InAngQEsc +gsave 10 dict begin +574 168 51 18 ellipse_path +stroke +gsave 10 dict begin +574 163 moveto 81 -0.5 (InAngQEsc) alignedtext +end grestore +end grestore + +% InAngQ -> InAngQEsc +newpath 566 261 moveto +571 252 576 241 578 230 curveto +580 218 580 206 579 195 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 582 196 moveto +578 186 lineto +577 196 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +611 220 moveto 58 -0.5 (LSLASH, Add) alignedtext +end grestore + +% InAngQEsc -> InAngQ +newpath 540 255 moveto +534 243 529 229 534 216 curveto +538 204 546 193 554 185 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 537 255 moveto +544 262 lineto +541 252 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +552 220 moveto 29 -0.5 (X, Add) alignedtext +end grestore + +% InQEsc -> InQ +newpath 249 369 moveto +239 357 232 342 237 328 curveto +241 316 250 304 257 295 curveto +stroke +gsave 10 dict begin +solid +0.000 0.000 0.000 edgecolor +newpath 247 370 moveto +255 376 lineto +250 367 lineto +closepath +fill +0.000 0.000 0.000 edgecolor +end grestore +gsave 10 dict begin +8.00 /Helvetica set_font +256 332 moveto 29 -0.5 (X, Add) alignedtext +end grestore +endpage +grestore +%%PageTrailer +%%EndPage: 1 diff --git a/src/libs/resiprocate/resip/stack/doc/static/Preparse.svg b/src/libs/resiprocate/resip/stack/doc/static/Preparse.svg new file mode 100644 index 00000000..7fdd2606 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/static/Preparse.svg @@ -0,0 +1,321 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" + "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generated by dot version 1.9 (Wed Apr 16 21:58:33 MDT 2003) + For user: (alan) Title: pp_fsm Pages: 1 --> +<svg width="975px" height="605px" + xmlns="http://www.w3.org/2000/svg"> +<g id="graph0" class="graph" style="font-family:Times-Roman;font-size:9.07;"> +<title>pp_fsm</title> +<g id="node1" class="node"><title>NewMsg</title> +<ellipse cx="82" cy="21" rx="27" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="82" y="24" style="font-family:Helvetica;">NewMsg</text> +</g> +<g id="node3" class="node"><title>StartLine</title> +<ellipse cx="142" cy="76" rx="27" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="142" y="80" style="font-family:Helvetica;">StartLine</text> +</g> +<g id="edge2" class="edge"><title>NewMsg-&gt;StartLine</title> +<path style="fill:none;stroke:black;" d="M98,30C104,34 111,39 116,44 122,49 126,54 131,60"/> +<polygon style="fill:black;stroke:black;" points="131,58 134,65 129,60 131,58"/> +<text text-anchor="middle" x="137" y="50" style="font-family:Helvetica;font-size:5.19;">X, Add </text> +</g> +<g id="node5" class="node"><title>NewMsgCrLf</title> +<ellipse cx="45" cy="76" rx="38" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="45" y="80" style="font-family:Helvetica;">NewMsgCrLf</text> +</g> +<g id="edge4" class="edge"><title>NewMsg-&gt;NewMsgCrLf</title> +<path style="fill:none;stroke:black;" d="M58,27C50,30 41,35 35,44 33,48 33,54 35,59"/> +<polygon style="fill:black;stroke:black;" points="36,58 37,65 33,59 36,58"/> +<text text-anchor="middle" x="53" y="50" style="font-family:Helvetica;font-size:5.19;">CR, None </text> +</g> +<g id="edge10" class="edge"><title>StartLine-&gt;StartLine</title> +<path style="fill:none;stroke:black;" d="M160,85C171,86 181,83 181,76 181,70 175,68 167,68"/> +<polygon style="fill:black;stroke:black;" points="167,69 160,68 167,66 167,69"/> +<text text-anchor="middle" x="192" y="78" style="font-family:Helvetica;font-size:5.19;">X, Add</text> +</g> +<g id="node11" class="node"><title>StartLineCrLf</title> +<ellipse cx="142" cy="132" rx="38" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="142" y="135" style="font-family:Helvetica;">StartLineCrLf</text> +</g> +<g id="edge12" class="edge"><title>StartLine-&gt;StartLineCrLf</title> +<path style="fill:none;stroke:black;" d="M142,88C142,96 142,105 142,114"/> +<polygon style="fill:black;stroke:black;" points="144,114 142,120 140,114 144,114"/> +<text text-anchor="middle" x="157" y="106" style="font-family:Helvetica;font-size:5.19;">CR, None</text> +</g> +<g id="edge8" class="edge"><title>NewMsgCrLf-&gt;NewMsg</title> +<path style="fill:none;stroke:black;" d="M77,37C76,43 74,48 70,53 67,57 63,62 59,65"/> +<polygon style="fill:black;stroke:black;" points="76,37 79,32 79,39 76,37"/> +<text text-anchor="middle" x="96" y="50" style="font-family:Helvetica;font-size:5.19;">LF, Discard </text> +</g> +<g id="node7" class="node"><title>EndMsg</title> +<ellipse cx="521" cy="578" rx="25" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="521" y="581" style="font-family:Helvetica;">EndMsg</text> +</g> +<g id="edge6" class="edge"><title>NewMsgCrLf-&gt;EndMsg</title> +<path style="fill:none;stroke:black;" d="M45,88C45,100 45,117 45,132 45,132 45,132 45,522 45,568 381,576 488,578"/> +<polygon style="fill:black;stroke:black;" points="488,576 495,578 488,579 488,576"/> +<text text-anchor="middle" x="67" y="329" style="font-family:Helvetica;font-size:5.19;">X, Bad|Discard </text> +</g> +<g id="edge14" class="edge"><title>StartLineCrLf-&gt;EndMsg</title> +<path style="fill:none;stroke:black;" d="M130,143C120,153 107,170 107,188 107,188 107,188 107,522 107,561 391,573 489,577"/> +<polygon style="fill:black;stroke:black;" points="488,575 495,577 488,579 488,575"/> +<text text-anchor="middle" x="129" y="357" style="font-family:Helvetica;font-size:5.19;">X, Bad|Discard</text> +</g> +<g id="node14" class="node"><title>BuildHdr</title> +<ellipse cx="706" cy="188" rx="27" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="706" y="191" style="font-family:Helvetica;">BuildHdr</text> +</g> +<g id="edge16" class="edge"><title>StartLineCrLf-&gt;BuildHdr</title> +<path style="fill:none;stroke:black;" d="M179,136C282,146 575,175 673,185"/> +<polygon style="fill:black;stroke:black;" points="673,183 679,185 673,186 673,183"/> +<text text-anchor="middle" x="487" y="162" style="font-family:Helvetica;font-size:5.19;">LF, Reset|Fline|Discard</text> +</g> +<g id="edge18" class="edge"><title>BuildHdr-&gt;BuildHdr</title> +<path style="fill:none;stroke:black;" d="M726,196C736,197 746,195 746,188 746,183 740,179 733,179"/> +<polygon style="fill:black;stroke:black;" points="732,181 726,179 732,177 732,181"/> +<text text-anchor="middle" x="757" y="190" style="font-family:Helvetica;font-size:5.19;">X, Add</text> +</g> +<g id="node17" class="node"><title>EWSPostHdr</title> +<ellipse cx="761" cy="244" rx="36" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="761" y="247" style="font-family:Helvetica;">EWSPostHdr</text> +</g> +<g id="edge20" class="edge"><title>BuildHdr-&gt;EWSPostHdr</title> +<path style="fill:none;stroke:black;" d="M717,199C726,207 737,219 746,228"/> +<polygon style="fill:black;stroke:black;" points="747,227 750,232 745,229 747,227"/> +<text text-anchor="middle" x="754" y="218" style="font-family:Helvetica;font-size:5.19;">LWS, None</text> +</g> +<g id="node19" class="node"><title>EWSPostColon</title> +<ellipse cx="542" cy="299" rx="40" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="542" y="302" style="font-family:Helvetica;">EWSPostColon</text> +</g> +<g id="edge22" class="edge"><title>BuildHdr-&gt;EWSPostColon</title> +<path style="fill:none;stroke:black;" d="M684,194C662,201 628,214 603,232 583,246 564,268 553,283"/> +<polygon style="fill:black;stroke:black;" points="555,284 549,288 553,282 555,284"/> +<text text-anchor="middle" x="652" y="245" style="font-family:Helvetica;font-size:5.19;">COLON, Hdr|Reset|DiscardKnown</text> +</g> +<g id="edge24" class="edge"><title>EWSPostHdr-&gt;EndMsg</title> +<path style="fill:none;stroke:black;" d="M792,250C817,257 848,272 848,299 848,299 848,299 848,522 848,576 667,575 614,577 603,577 576,578 554,578"/> +<polygon style="fill:black;stroke:black;" points="553,579 547,578 553,576 553,579"/> +<text text-anchor="middle" x="870" y="413" style="font-family:Helvetica;font-size:5.19;">X, Bad|Discard</text> +</g> +<g id="edge26" class="edge"><title>EWSPostHdr-&gt;EWSPostHdr</title> +<path style="fill:none;stroke:black;" d="M787,252C799,253 810,250 810,244 810,238 803,235 794,235"/> +<polygon style="fill:black;stroke:black;" points="793,236 787,235 793,233 793,236"/> +<text text-anchor="middle" x="827" y="245" style="font-family:Helvetica;font-size:5.19;">LWS, None</text> +</g> +<g id="edge28" class="edge"><title>EWSPostHdr-&gt;EWSPostColon</title> +<path style="fill:none;stroke:black;" d="M732,251C693,261 622,279 579,290"/> +<polygon style="fill:black;stroke:black;" points="579,291 572,291 578,288 579,291"/> +<text text-anchor="middle" x="717" y="273" style="font-family:Helvetica;font-size:5.19;">COLON, Hdr|Reset|DiscardKnown</text> +</g> +<g id="edge32" class="edge"><title>EWSPostColon-&gt;EWSPostColon</title> +<path style="fill:none;stroke:black;" d="M569,308C582,309 594,306 594,299 594,294 586,291 577,291"/> +<polygon style="fill:black;stroke:black;" points="576,292 569,291 576,289 576,292"/> +<text text-anchor="middle" x="632" y="301" style="font-family:Helvetica;font-size:5.19;">LWS, Reset|DiscardKnown</text> +</g> +<g id="node24" class="node"><title>BuildData</title> +<ellipse cx="351" cy="355" rx="29" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="351" y="358" style="font-family:Helvetica;">BuildData</text> +</g> +<g id="edge30" class="edge"><title>EWSPostColon-&gt;BuildData</title> +<path style="fill:none;stroke:black;" d="M501,301C441,303 335,310 323,323 317,329 322,336 330,342"/> +<polygon style="fill:black;stroke:black;" points="330,340 334,345 328,343 330,340"/> +<text text-anchor="middle" x="335" y="329" style="font-family:Helvetica;font-size:5.19;">X, Add</text> +</g> +<g id="node27" class="node"><title>EmptyHdrCrLf</title> +<ellipse cx="779" cy="355" rx="42" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="779" y="358" style="font-family:Helvetica;">EmptyHdrCrLf</text> +</g> +<g id="edge34" class="edge"><title>EWSPostColon-&gt;EmptyHdrCrLf</title> +<path style="fill:none;stroke:black;" d="M566,308C589,317 621,328 634,332 644,335 697,343 735,349"/> +<polygon style="fill:black;stroke:black;" points="735,347 741,349 735,350 735,347"/> +<text text-anchor="middle" x="669" y="329" style="font-family:Helvetica;font-size:5.19;">CR, Reset|DiscardKnown</text> +</g> +<g id="node36" class="node"><title>InAng</title> +<ellipse cx="404" cy="411" rx="21" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="404" y="414" style="font-family:Helvetica;">InAng</text> +</g> +<g id="edge46" class="edge"><title>EWSPostColon-&gt;InAng</title> +<path style="fill:none;stroke:black;" d="M536,311C532,319 527,332 525,343 523,354 521,357 525,367 527,373 532,372 534,378 536,382 537,385 534,387 524,400 481,396 466,399 454,401 440,404 430,406"/> +<polygon style="fill:black;stroke:black;" points="431,408 424,407 431,404 431,408"/> +<text text-anchor="middle" x="568" y="357" style="font-family:Helvetica;font-size:5.19;">LAQUOT, Add (dCommaSep)</text> +</g> +<g id="node38" class="node"><title>InQ</title> +<ellipse cx="182" cy="411" rx="17" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="182" y="414" style="font-family:Helvetica;">InQ</text> +</g> +<g id="edge48" class="edge"><title>EWSPostColon-&gt;InQ</title> +<path style="fill:none;stroke:black;" d="M501,300C494,301 488,301 482,301 372,306 339,299 239,343 212,356 197,353 183,378 181,383 180,388 180,393"/> +<polygon style="fill:black;stroke:black;" points="182,393 180,399 179,393 182,393"/> +<text text-anchor="middle" x="281" y="357" style="font-family:Helvetica;font-size:5.19;">QUOT, Add (dCommaSep)</text> +</g> +<g id="edge94" class="edge"><title>BuildData-&gt;EWSPostColon</title> +<path style="fill:none;stroke:black;" d="M497,303C450,308 380,315 370,323 363,328 358,336 355,343"/> +<polygon style="fill:black;stroke:black;" points="496,302 503,302 496,305 496,302"/> +<text text-anchor="middle" x="441" y="329" style="font-family:Helvetica;font-size:5.19;">COMMA, Data|Reset|DiscardKnown (dCommaSep)</text> +</g> +<g id="edge50" class="edge"><title>BuildData-&gt;BuildData</title> +<path style="fill:none;stroke:black;" d="M372,363C383,365 393,362 393,355 393,349 387,347 378,347"/> +<polygon style="fill:black;stroke:black;" points="378,348 372,347 378,345 378,348"/> +<text text-anchor="middle" x="404" y="357" style="font-family:Helvetica;font-size:5.19;">X, Add</text> +</g> +<g id="edge68" class="edge"><title>BuildData-&gt;InAng</title> +<path style="fill:none;stroke:black;" d="M370,364C377,368 384,372 389,378 393,383 396,388 398,393"/> +<polygon style="fill:black;stroke:black;" points="399,393 400,399 396,394 399,393"/> +<text text-anchor="middle" x="436" y="385" style="font-family:Helvetica;font-size:5.19;">LAQUOT, Add (dCommaSep)</text> +</g> +<g id="edge84" class="edge"><title>BuildData-&gt;InQ</title> +<path style="fill:none;stroke:black;" d="M322,358C284,363 195,374 191,378 186,382 184,387 183,393"/> +<polygon style="fill:black;stroke:black;" points="185,393 182,399 182,393 185,393"/> +<text text-anchor="middle" x="232" y="385" style="font-family:Helvetica;font-size:5.19;">QUOT, Add (dCommaSep)</text> +</g> +<g id="node41" class="node"><title>BuildDataCrLf</title> +<ellipse cx="514" cy="411" rx="41" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="514" y="414" style="font-family:Helvetica;">BuildDataCrLf</text> +</g> +<g id="edge52" class="edge"><title>BuildData-&gt;BuildDataCrLf</title> +<path style="fill:none;stroke:black;" d="M380,358C422,363 439,357 480,378 488,382 495,389 501,395"/> +<polygon style="fill:black;stroke:black;" points="501,393 505,399 499,395 501,393"/> +<text text-anchor="middle" x="512" y="385" style="font-family:Helvetica;font-size:5.19;">CR, None|Flat</text> +</g> +<g id="edge36" class="edge"><title>EmptyHdrCrLf-&gt;EndMsg</title> +<path style="fill:none;stroke:black;" d="M782,367C785,378 788,396 788,411 788,411 788,411 788,522 788,575 610,570 553,576"/> +<polygon style="fill:black;stroke:black;" points="553,577 547,577 553,575 553,577"/> +<text text-anchor="middle" x="809" y="468" style="font-family:Helvetica;font-size:5.19;">X, Bad|Discard</text> +</g> +<g id="node30" class="node"><title>EmptyHdrCont</title> +<ellipse cx="708" cy="411" rx="42" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="708" y="414" style="font-family:Helvetica;">EmptyHdrCont</text> +</g> +<g id="edge38" class="edge"><title>EmptyHdrCrLf-&gt;EmptyHdrCont</title> +<path style="fill:none;stroke:black;" d="M746,363C732,367 715,372 711,378 708,382 706,387 706,393"/> +<polygon style="fill:black;stroke:black;" points="708,393 706,399 704,393 708,393"/> +<text text-anchor="middle" x="744" y="385" style="font-family:Helvetica;font-size:5.19;">LF, Reset|DiscardKnown</text> +</g> +<g id="edge40" class="edge"><title>EmptyHdrCont-&gt;BuildHdr</title> +<path style="fill:none;stroke:black;" d="M739,192C789,199 878,215 878,244 878,244 878,244 878,355 878,383 796,399 746,406"/> +<polygon style="fill:black;stroke:black;" points="739,194 733,191 739,190 739,194"/> +<text text-anchor="middle" x="922" y="301" style="font-family:Helvetica;font-size:5.19;">X, Reset|Back|Discard|EmptyHdr</text> +</g> +<g id="edge42" class="edge"><title>EmptyHdrCont-&gt;EWSPostColon</title> +<path style="fill:none;stroke:black;" d="M564,312C579,321 597,332 614,343 650,368 662,378 692,400"/> +<polygon style="fill:black;stroke:black;" points="564,314 559,310 566,312 564,314"/> +<text text-anchor="middle" x="682" y="357" style="font-family:Helvetica;font-size:5.19;">LWS, Reset|DiscardKnown</text> +</g> +<g id="node34" class="node"><title>CheckEndHdr</title> +<ellipse cx="598" cy="522" rx="39" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="598" y="525" style="font-family:Helvetica;">CheckEndHdr</text> +</g> +<g id="edge44" class="edge"><title>EmptyHdrCont-&gt;CheckEndHdr</title> +<path style="fill:none;stroke:black;" d="M700,422C695,431 687,444 681,455 669,475 672,485 655,499 649,505 641,509 634,512"/> +<polygon style="fill:black;stroke:black;" points="634,513 628,514 633,511 634,513"/> +<text text-anchor="middle" x="728" y="468" style="font-family:Helvetica;font-size:5.19;">CR, Data|Reset|Discard|EmptyHdr</text> +</g> +<g id="edge64" class="edge"><title>CheckEndHdr-&gt;EndMsg</title> +<path style="fill:none;stroke:black;" d="M594,534C592,541 587,549 581,555 572,562 561,568 550,571"/> +<polygon style="fill:black;stroke:black;" points="551,572 544,573 550,569 551,572"/> +<text text-anchor="middle" x="610" y="552" style="font-family:Helvetica;font-size:5.19;">X, Bad|Discard</text> +</g> +<g id="edge66" class="edge"><title>CheckEndHdr-&gt;EndMsg</title> +<path style="fill:none;stroke:black;" d="M564,528C546,533 526,538 521,546 518,549 517,555 517,560"/> +<polygon style="fill:black;stroke:black;" points="518,560 518,566 516,560 518,560"/> +<text text-anchor="middle" x="551" y="552" style="font-family:Helvetica;font-size:5.19;">LF, EndHdrs|Discard</text> +</g> +<g id="edge72" class="edge"><title>InAng-&gt;BuildData</title> +<path style="fill:none;stroke:black;" d="M339,371C336,377 335,382 339,387 344,395 367,402 383,406"/> +<polygon style="fill:black;stroke:black;" points="337,371 342,366 341,372 337,371"/> +<text text-anchor="middle" x="362" y="385" style="font-family:Helvetica;font-size:5.19;">RAQUOT, Add</text> +</g> +<g id="edge70" class="edge"><title>InAng-&gt;InAng</title> +<path style="fill:none;stroke:black;" d="M419,419C428,420 437,418 437,411 437,406 432,403 426,402"/> +<polygon style="fill:black;stroke:black;" points="426,404 419,402 426,400 426,404"/> +<text text-anchor="middle" x="448" y="413" style="font-family:Helvetica;font-size:5.19;">X, Add</text> +</g> +<g id="node54" class="node"><title>InAngQ</title> +<ellipse cx="367" cy="466" rx="25" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="367" y="470" style="font-family:Helvetica;">InAngQ</text> +</g> +<g id="edge74" class="edge"><title>InAng-&gt;InAngQ</title> +<path style="fill:none;stroke:black;" d="M385,417C377,420 369,426 364,434 361,439 361,444 361,449"/> +<polygon style="fill:black;stroke:black;" points="363,448 363,455 359,449 363,448"/> +<text text-anchor="middle" x="382" y="441" style="font-family:Helvetica;font-size:5.19;">QUOT, Add</text> +</g> +<g id="edge88" class="edge"><title>InQ-&gt;BuildData</title> +<path style="fill:none;stroke:black;" d="M319,363C302,371 293,379 269,387 245,396 216,403 199,407"/> +<polygon style="fill:black;stroke:black;" points="319,361 325,361 319,365 319,361"/> +<text text-anchor="middle" x="310" y="385" style="font-family:Helvetica;font-size:5.19;">QUOT, Add</text> +</g> +<g id="edge86" class="edge"><title>InQ-&gt;InQ</title> +<path style="fill:none;stroke:black;" d="M195,419C203,421 211,419 211,411 211,405 206,402 201,402"/> +<polygon style="fill:black;stroke:black;" points="201,404 195,403 201,401 201,404"/> +<text text-anchor="middle" x="223" y="413" style="font-family:Helvetica;font-size:5.19;">X, Add</text> +</g> +<g id="node64" class="node"><title>InQEsc</title> +<ellipse cx="184" cy="466" rx="23" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="184" y="470" style="font-family:Helvetica;">InQEsc</text> +</g> +<g id="edge90" class="edge"><title>InQ-&gt;InQEsc</title> +<path style="fill:none;stroke:black;" d="M184,422C186,426 186,430 186,434 187,439 186,444 186,448"/> +<polygon style="fill:black;stroke:black;" points="188,448 186,455 185,448 188,448"/> +<text text-anchor="middle" x="208" y="441" style="font-family:Helvetica;font-size:5.19;">LSLASH, Add</text> +</g> +<g id="edge54" class="edge"><title>BuildDataCrLf-&gt;EndMsg</title> +<path style="fill:none;stroke:black;" d="M513,422C512,447 510,506 514,555 514,557 514,559 514,560"/> +<polygon style="fill:black;stroke:black;" points="516,560 513,566 512,560 516,560"/> +<text text-anchor="middle" x="533" y="496" style="font-family:Helvetica;font-size:5.19;">X, Bad|Discard</text> +</g> +<g id="node44" class="node"><title>CheckCont</title> +<ellipse cx="582" cy="466" rx="31" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="582" y="470" style="font-family:Helvetica;">CheckCont</text> +</g> +<g id="edge56" class="edge"><title>BuildDataCrLf-&gt;CheckCont</title> +<path style="fill:none;stroke:black;" d="M518,422C520,430 524,437 530,443 536,449 544,454 552,457"/> +<polygon style="fill:black;stroke:black;" points="552,455 557,459 551,459 552,455"/> +<text text-anchor="middle" x="549" y="441" style="font-family:Helvetica;font-size:5.19;">LF, None|Flat</text> +</g> +<g id="edge58" class="edge"><title>CheckCont-&gt;BuildHdr</title> +<path style="fill:none;stroke:black;" d="M707,205C709,249 715,360 711,367 698,391 681,384 660,399 635,417 608,441 594,455"/> +<polygon style="fill:black;stroke:black;" points="706,206 707,199 709,206 706,206"/> +<text text-anchor="middle" x="748" y="329" style="font-family:Helvetica;font-size:5.19;">X, Data|Reset|Back|Discard</text> +</g> +<g id="edge60" class="edge"><title>CheckCont-&gt;BuildData</title> +<path style="fill:none;stroke:black;" d="M387,357C394,358 398,358 407,359 464,367 482,356 534,378 548,385 552,387 561,399 573,417 579,441 580,455"/> +<polygon style="fill:black;stroke:black;" points="387,358 381,356 387,356 387,358"/> +<text text-anchor="middle" x="588" y="413" style="font-family:Helvetica;font-size:5.19;">LWS, Add </text> +</g> +<g id="edge62" class="edge"><title>CheckCont-&gt;CheckEndHdr</title> +<path style="fill:none;stroke:black;" d="M586,478C588,486 591,496 593,505"/> +<polygon style="fill:black;stroke:black;" points="594,504 595,511 591,505 594,504"/> +<text text-anchor="middle" x="621" y="496" style="font-family:Helvetica;font-size:5.19;">CR, Data|Reset|Discard</text> +</g> +<g id="edge78" class="edge"><title>InAngQ-&gt;InAng</title> +<path style="fill:none;stroke:black;" d="M407,429C407,433 406,439 404,443 400,450 393,455 387,459"/> +<polygon style="fill:black;stroke:black;" points="405,429 406,422 408,429 405,429"/> +<text text-anchor="middle" x="424" y="441" style="font-family:Helvetica;font-size:5.19;">QUOT, Add</text> +</g> +<g id="edge76" class="edge"><title>InAngQ-&gt;InAngQ</title> +<path style="fill:none;stroke:black;" d="M385,475C395,476 404,474 404,466 404,461 399,458 393,458"/> +<polygon style="fill:black;stroke:black;" points="392,459 385,458 392,456 392,459"/> +<text text-anchor="middle" x="416" y="468" style="font-family:Helvetica;font-size:5.19;">X, Add</text> +</g> +<g id="node58" class="node"><title>InAngQEsc</title> +<ellipse cx="378" cy="522" rx="33" ry="11" style="fill:none;stroke:black;"/> +<text text-anchor="middle" x="378" y="525" style="font-family:Helvetica;">InAngQEsc</text> +</g> +<g id="edge80" class="edge"><title>InAngQ-&gt;InAngQEsc</title> +<path style="fill:none;stroke:black;" d="M375,478C378,481 380,486 381,490 381,494 382,500 381,504"/> +<polygon style="fill:black;stroke:black;" points="383,504 381,511 380,504 383,504"/> +<text text-anchor="middle" x="402" y="496" style="font-family:Helvetica;font-size:5.19;">LSLASH, Add</text> +</g> +<g id="edge82" class="edge"><title>InAngQEsc-&gt;InAngQ</title> +<path style="fill:none;stroke:black;" d="M354,483C352,488 350,494 352,499 354,504 358,508 362,512"/> +<polygon style="fill:black;stroke:black;" points="353,482 357,478 356,484 353,482"/> +<text text-anchor="middle" x="364" y="496" style="font-family:Helvetica;font-size:5.19;">X, Add</text> +</g> +<g id="edge92" class="edge"><title>InQEsc-&gt;InQ</title> +<path style="fill:none;stroke:black;" d="M166,424C161,430 157,437 160,443 162,448 166,453 170,457"/> +<polygon style="fill:black;stroke:black;" points="164,423 170,420 167,426 164,423"/> +<text text-anchor="middle" x="172" y="441" style="font-family:Helvetica;font-size:5.19;">X, Add</text> +</g> +</g></svg> diff --git a/src/libs/resiprocate/resip/stack/doc/static/README b/src/libs/resiprocate/resip/stack/doc/static/README new file mode 100644 index 00000000..646c9425 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/static/README @@ -0,0 +1,17 @@ +********************** +********************** +THIS DOCUMENTATION IS +POTENTIALLY OUT OF DATE +---------------------- +YOU WOULD BE WELL ADVISED +TO INSTALL GRAPHVIZ AND +REGENERATE IT FROM SOURCE +AS REQUIRED. +---------------------- +UPDATES TO THE SERVER +MACHINE DIAGRAMS WILL BE +PROVIDED ON AN AD HOC BASIS + +Alan Hawrylyshen +alan@jasomi.com +**************** diff --git a/src/libs/resiprocate/resip/stack/doc/static/srv-inv-fsm.pdf b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-fsm.pdf new file mode 100644 index 00000000..567580da Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-fsm.pdf differ diff --git a/src/libs/resiprocate/resip/stack/doc/static/srv-inv-fsm.png b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-fsm.png new file mode 100644 index 00000000..e36c4b9d Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-fsm.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/static/srv-inv-fsm.ps b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-fsm.ps new file mode 100644 index 00000000..e54684fa --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-fsm.ps @@ -0,0 +1,677 @@ +%!PS-Adobe-2.0 +%%Creator: dot version 1.7.14 (Mon Oct 21 18:19:04 MDT 2002) +%%For: (alan) +%%Title: moonshine_ua_fsm +%%Pages: (atend) +%%BoundingBox: 35 35 644 529 +%%EndComments +save +%%BeginProlog +/DotDict 200 dict def +DotDict begin + +/setupLatin1 { +mark +/EncodingVector 256 array def + EncodingVector 0 + +ISOLatin1Encoding 0 255 getinterval putinterval + +EncodingVector + dup 306 /AE + dup 301 /Aacute + dup 302 /Acircumflex + dup 304 /Adieresis + dup 300 /Agrave + dup 305 /Aring + dup 303 /Atilde + dup 307 /Ccedilla + dup 311 /Eacute + dup 312 /Ecircumflex + dup 313 /Edieresis + dup 310 /Egrave + dup 315 /Iacute + dup 316 /Icircumflex + dup 317 /Idieresis + dup 314 /Igrave + dup 334 /Udieresis + dup 335 /Yacute + dup 376 /thorn + dup 337 /germandbls + dup 341 /aacute + dup 342 /acircumflex + dup 344 /adieresis + dup 346 /ae + dup 340 /agrave + dup 345 /aring + dup 347 /ccedilla + dup 351 /eacute + dup 352 /ecircumflex + dup 353 /edieresis + dup 350 /egrave + dup 355 /iacute + dup 356 /icircumflex + dup 357 /idieresis + dup 354 /igrave + dup 360 /dcroat + dup 361 /ntilde + dup 363 /oacute + dup 364 /ocircumflex + dup 366 /odieresis + dup 362 /ograve + dup 365 /otilde + dup 370 /oslash + dup 372 /uacute + dup 373 /ucircumflex + dup 374 /udieresis + dup 371 /ugrave + dup 375 /yacute + dup 377 /ydieresis + +% Set up ISO Latin 1 character encoding +/starnetISO { + dup dup findfont dup length dict begin + { 1 index /FID ne { def }{ pop pop } ifelse + } forall + /Encoding EncodingVector def + currentdict end definefont +} def +/Times-Roman starnetISO def +/Times-Italic starnetISO def +/Times-Bold starnetISO def +/Times-BoldItalic starnetISO def +/Helvetica starnetISO def +/Helvetica-Oblique starnetISO def +/Helvetica-Bold starnetISO def +/Helvetica-BoldOblique starnetISO def +/Courier starnetISO def +/Courier-Oblique starnetISO def +/Courier-Bold starnetISO def +/Courier-BoldOblique starnetISO def +cleartomark +} bind def + +%%BeginResource: procset +/coord-font-family /Times-Roman def +/default-font-family /Times-Roman def +/coordfont coord-font-family findfont 8 scalefont def + +/InvScaleFactor 1.0 def +/set_scale { + dup 1 exch div /InvScaleFactor exch def + dup scale +} bind def + +% styles +/solid { } bind def +/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def +/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def +/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def +/bold { 2 setlinewidth } bind def +/filled { } bind def +/unfilled { } bind def +/rounded { } bind def +/diagonals { } bind def + +% hooks for setting color +/nodecolor { sethsbcolor } bind def +/edgecolor { sethsbcolor } bind def +/graphcolor { sethsbcolor } bind def +/nopcolor {pop pop pop} bind def + +/beginpage { % i j npages + /npages exch def + /j exch def + /i exch def + /str 10 string def + npages 1 gt { + gsave + coordfont setfont + 0 0 moveto + (\() show i str cvs show (,) show j str cvs show (\)) show + grestore + } if +} bind def + +/set_font { + findfont exch + scalefont setfont +} def + +% draw aligned label in bounding box aligned to current point +/alignedtext { % width adj text + /text exch def + /adj exch def + /width exch def + gsave + width 0 gt { + text stringwidth pop adj mul 0 rmoveto + } if + [] 0 setdash + text show + grestore +} def + +/boxprim { % xcorner ycorner xsize ysize + 4 2 roll + moveto + 2 copy + exch 0 rlineto + 0 exch rlineto + pop neg 0 rlineto + closepath +} bind def + +/ellipse_path { + /ry exch def + /rx exch def + /y exch def + /x exch def + matrix currentmatrix + newpath + x y translate + rx ry scale + 0 0 1 0 360 arc + setmatrix +} bind def + +/endpage { showpage } bind def + +/layercolorseq + [ % layer color sequence - darkest to lightest + [0 0 0] + [.2 .8 .8] + [.4 .8 .8] + [.6 .8 .8] + [.8 .8 .8] + ] +def + +/setlayer {/maxlayer exch def /curlayer exch def + layercolorseq curlayer get + aload pop sethsbcolor + /nodecolor {nopcolor} def + /edgecolor {nopcolor} def + /graphcolor {nopcolor} def +} bind def + +/onlayer { curlayer ne {invis} if } def + +/onlayers { + /myupper exch def + /mylower exch def + curlayer mylower lt + curlayer myupper gt + or + {invis} if +} def + +/curlayer 0 def + +%%EndResource +%%EndProlog +%%BeginSetup +14 default-font-family set_font +1 setmiterlimit +% /arrowlength 10 def +% /arrowwidth 5 def + +% make sure pdfmark is harmless for PS-interpreters other than Distiller +/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse +% make '<<' and '>>' safe on PS Level 1 devices +/languagelevel where {pop languagelevel}{1} ifelse +2 lt { + userdict (<<) cvn ([) cvn load put + userdict (>>) cvn ([) cvn load put +} if + +%%EndSetup +%%Page: 1 1 +%%PageBoundingBox: 36 36 644 529 +%%PageOrientation: Portrait +gsave +35 35 609 494 boxprim clip newpath +36 36 translate +0 0 1 beginpage +0 0 translate 0 rotate +[ /CropBox [36 36 644 529] /PAGES pdfmark +0.000 0.000 0.000 graphcolor +14.00 /Helvetica set_font +% cluster_x +gsave 10 dict begin +invis +newpath 8 262 moveto +254 262 lineto +254 314 lineto +8 314 lineto +closepath +stroke +end grestore + +% INIT +gsave 10 dict begin +filled +0.333 0.392 0.984 nodecolor +244 466 18 18 ellipse_path +fill +newpath 255 479 moveto +233 479 lineto +stroke +newpath 255 453 moveto +233 453 lineto +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +244 461 moveto 34 -0.5 (INIT) alignedtext +end grestore +end grestore + +% TRYING +gsave 10 dict begin +0.000 0.000 0.827 nodecolor +244 362 44 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +244 357 moveto 67 -0.5 (TRYING) alignedtext +end grestore +end grestore + +% INIT -> TRYING +newpath 244 448 moveto +244 432 244 408 244 389 curveto +stroke +newpath 242 390 moveto +244 380 lineto +247 390 lineto +closepath +fill +gsave 10 dict begin +8.00 /Helvetica set_font +308 420 moveto 37 -0.5 (rcv\(INV\):) alignedtext +308 411 moveto 120 -0.5 (timerStart\(TRYING\)\(<200ms\)) alignedtext +308 402 moveto 40 -0.5 (pass\(INV\)) alignedtext +end grestore + +% p1PROCEEDING +gsave 10 dict begin +0.000 0.000 0.827 nodecolor +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +8.00 /Helvetica set_font +44 289 moveto 32 -0.5 (got\(1xx\):) alignedtext +44 280 moveto 49 -0.5 (snd\(reponse\)) alignedtext +end grestore +end grestore + +% TRYING -> p1PROCEEDING +newpath 205 354 moveto +163 342 146 334 97 314 curveto +92 311 86 309 81 306 curveto +stroke +newpath 80 308 moveto +72 302 lineto +82 304 lineto +closepath +fill + +% p2PROCEEDING +gsave 10 dict begin +0.000 0.000 0.827 nodecolor +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +8.00 /Helvetica set_font +176 289 moveto 133 -0.5 (rcv\(INV\) | timerExpires\(TRYING\):) alignedtext +176 280 moveto 31 -0.5 (snd\(100\)) alignedtext +end grestore +end grestore + +% TRYING -> p2PROCEEDING +newpath 228 345 moveto +219 335 208 324 199 313 curveto +stroke +newpath 198 315 moveto +193 306 lineto +201 312 lineto +closepath +fill + +% pCOMPLETED +gsave 10 dict begin +0.000 0.000 0.827 nodecolor +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +8.00 /Helvetica set_font +311 289 moveto 48 -0.5 (got\(300-699\):) alignedtext +311 280 moveto 52 -0.5 (snd\(response\)) alignedtext +end grestore +end grestore + +% TRYING -> pCOMPLETED +newpath 260 345 moveto +268 335 279 324 288 313 curveto +stroke +newpath 286 311 moveto +295 306 lineto +290 315 lineto +closepath +fill + +% pSTALE +gsave 10 dict begin +0.000 0.000 0.827 nodecolor +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +8.00 /Helvetica set_font +440 289 moveto 38 -0.5 (got\(2XX\):) alignedtext +440 280 moveto 124 -0.5 (setTimer\(STALE\),snd\(response\)) alignedtext +end grestore +end grestore + +% TRYING -> pSTALE +newpath 282 353 moveto +313 342 358 324 391 309 curveto +stroke +newpath 388 308 moveto +398 306 lineto +390 312 lineto +closepath +fill + +% PROCEEDING +gsave 10 dict begin +0.000 0.000 0.827 nodecolor +133 214 66 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +133 209 moveto 110 -0.5 (PROCEEDING) alignedtext +end grestore +end grestore + +% p1PROCEEDING -> PROCEEDING +newpath 66 270 moveto +78 260 92 248 105 237 curveto +stroke +newpath 103 236 moveto +112 231 lineto +106 239 lineto +closepath +fill + +% p2PROCEEDING -> PROCEEDING +newpath 165 270 moveto +160 261 154 250 148 240 curveto +stroke +newpath 146 242 moveto +143 232 lineto +150 239 lineto +closepath +fill + +% PROCEEDING -> p1PROCEEDING +newpath 58 263 moveto +65 252 76 238 88 227 curveto +stroke +newpath 61 263 moveto +54 270 lineto +57 260 lineto +closepath +fill + +% PROCEEDING -> p2PROCEEDING +newpath 170 262 moveto +169 257 167 253 166 250 curveto +163 242 162 236 160 231 curveto +stroke +newpath 172 260 moveto +172 270 lineto +167 261 lineto +closepath +fill + +% pTxError +gsave 10 dict begin +0.000 0.000 0.827 nodecolor +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +8.00 /Helvetica set_font +162 121 moveto 56 -0.5 (transport error:) alignedtext +162 112 moveto 38 -0.5 (notify TU) alignedtext +end grestore +end grestore + +% PROCEEDING -> pTxError +newpath 139 196 moveto +143 183 149 163 153 147 curveto +stroke +newpath 150 147 moveto +156 138 lineto +155 148 lineto +closepath +fill + +% PROCEEDING -> pCOMPLETED +newpath 273 267 moveto +246 253 211 236 185 225 curveto +stroke +newpath 274 265 moveto +281 272 lineto +271 269 lineto +closepath +fill + +% PROCEEDING -> pSTALE +newpath 373 268 moveto +366 266 358 264 350 262 curveto +299 247 286 246 234 232 curveto +217 226 211 222 197 219 curveto +stroke +newpath 370 264 moveto +379 270 lineto +369 269 lineto +closepath +fill + +% DELETE +gsave 10 dict begin +filled +0.969 0.247 1.000 nodecolor +293 30 18 18 ellipse_path +fill +293 30 22 22 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +293 25 moveto 33 -0.5 (DEL) alignedtext +end grestore +end grestore + +% pTxError -> DELETE +newpath 189 102 moveto +211 86 245 63 268 48 curveto +stroke +newpath 265 47 moveto +275 43 lineto +268 51 lineto +closepath +fill + +% COMPLETED +gsave 10 dict begin +0.000 0.000 0.827 nodecolor +305 214 62 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +305 209 moveto 103 -0.5 (COMPLETED) alignedtext +end grestore +end grestore + +% pCOMPLETED -> COMPLETED +newpath 310 270 moveto +309 261 309 251 308 242 curveto +stroke +newpath 306 242 moveto +307 232 lineto +310 242 lineto +closepath +fill + +% COMPLETED -> pTxError +newpath 280 197 moveto +257 181 221 158 195 142 curveto +stroke +newpath 196 146 moveto +190 138 lineto +199 142 lineto +closepath +fill + +% COMPLETED -> COMPLETED +newpath 363 207 moveto +376 208 385 210 385 214 curveto +385 217 380 219 372 220 curveto +stroke +newpath 373 222 moveto +363 221 lineto +373 217 lineto +closepath +fill +gsave 10 dict begin +8.00 /Helvetica set_font +420 224 moveto 62 -0.5 (expireTimer\(G\):) alignedtext +420 215 moveto 52 -0.5 (snd\(response\)) alignedtext +420 206 moveto 24 -0.5 (G = 2G) alignedtext +420 197 moveto 54 -0.5 (startTimer\(G\)) alignedtext +end grestore + +% COMPLETED -> COMPLETED +newpath 327 197 moveto +380 166 455 172 455 214 curveto +455 254 387 261 334 235 curveto +stroke +newpath 334 238 moveto +327 231 lineto +337 234 lineto +closepath +fill +gsave 10 dict begin +8.00 /Helvetica set_font +485 215 moveto 52 -0.5 (rcv\(INVITE\):) alignedtext +485 206 moveto 52 -0.5 (snd\(response\)) alignedtext +end grestore + +% CONFIRMED +gsave 10 dict begin +0.000 0.000 0.827 nodecolor +293 120 62 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +293 115 moveto 103 -0.5 (CONFIRMED) alignedtext +end grestore +end grestore + +% COMPLETED -> CONFIRMED +newpath 303 196 moveto +301 183 298 163 296 147 curveto +stroke +newpath 294 148 moveto +295 138 lineto +299 148 lineto +closepath +fill +gsave 10 dict begin +8.00 /Helvetica set_font +330 168 moveto 41 -0.5 (rcv\(ACK\):) alignedtext +330 159 moveto 49 -0.5 (startTimer\(I\)) alignedtext +end grestore + +% STALE +gsave 10 dict begin +0.000 0.000 0.827 nodecolor +425 120 37 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +425 115 moveto 52 -0.5 (STALE) alignedtext +end grestore +end grestore + +% pSTALE -> STALE +newpath 496 270 moveto +514 261 532 249 542 232 curveto +550 218 549 210 542 196 curveto +526 165 492 145 465 134 curveto +stroke +newpath 464 136 moveto +456 130 lineto +466 132 lineto +closepath +fill + +% STALE -> DELETE +newpath 405 105 moveto +387 90 362 71 361 70 curveto +353 65 334 54 318 45 curveto +stroke +newpath 319 49 moveto +312 41 lineto +322 44 lineto +closepath +fill +gsave 10 dict begin +8.00 /Helvetica set_font +427 74 moveto 86 -0.5 (timerExpires\(STALE\)) alignedtext +end grestore + +% STALE -> STALE +newpath 451 107 moveto +466 105 480 109 480 120 curveto +480 128 472 133 462 133 curveto +stroke +newpath 461 136 moveto +451 133 lineto +461 131 lineto +closepath +fill +gsave 10 dict begin +8.00 /Helvetica set_font +505 121 moveto 41 -0.5 (rcv\(ACK\):) alignedtext +505 112 moveto 34 -0.5 (snd to TU) alignedtext +end grestore + +% CONFIRMED -> DELETE +newpath 293 102 moveto +293 90 293 75 293 62 curveto +stroke +newpath 291 62 moveto +293 52 lineto +296 62 lineto +closepath +fill +gsave 10 dict begin +8.00 /Helvetica set_font +325 74 moveto 56 -0.5 (expireTimer\(I\)) alignedtext +end grestore + +% LABEL_NODE +gsave 10 dict begin +0.000 0.000 0.827 nodecolor +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +6.00 /Helvetica set_font +389 467 moveto 58 -0.5 (Server INVITE FSM) alignedtext +389 461 moveto 179 -0.5 ($Id: srv-inv-fsm.ps,v 1.1 2002/11/06 21:06:05 alan Exp $ $Name: $) alignedtext +end grestore +end grestore +endpage +grestore +%%PageTrailer +%%EndPage: 1 +%%Trailer +%%Pages: 1 +end +restore +%%EOF diff --git a/src/libs/resiprocate/resip/stack/doc/static/srv-inv-fsm.svg b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-fsm.svg new file mode 100644 index 00000000..a63c3e28 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-fsm.svg @@ -0,0 +1,166 @@ +<!-- Generated by dot version 1.7.14 (Mon Oct 21 18:19:04 MDT 2002) + For user: (alan) Title: moonshine_ua_fsm Pages: 1--> +<svg width="629px" height="498px" xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<g id="moonshine_ua_fsm" class="graph"> +<g id="cluster_x" class="cluster"> +</g> +<g id="INIT" class="node"> +<ellipse cx="255" cy="29" rx="18" ry="18" style="fill:#98fb98;stroke:black"/> +<polyline style="fill:none;stroke:black" points="266,16 244,16 "/> +<polyline style="fill:none;stroke:black" points="266,42 244,42 "/> +<text text-anchor="middle" x="255" y="34" style="font-family:Helvetica;font-size:14.00">INIT</text> +</g> +<g id="TRYING" class="node"> +<ellipse cx="255" cy="133" rx="44" ry="18" style="fill:none;stroke:black"/> +<text text-anchor="middle" x="255" y="138" style="font-family:Helvetica;font-size:14.00">TRYING</text> +</g> +<g id="INIT-&gt;TRYING" class="edge"> +<g style="fill:none;stroke:black"><path d="M255 47C255 63 255 87 255 106"/></g> +<polygon style="fill:black;stroke:black" points="253,105 255,115 258,105 253,105"/> +<text text-anchor="middle" x="319" y="75" style="font-family:Helvetica;font-size:8.00">rcv(INV):</text> +<text text-anchor="middle" x="319" y="84" style="font-family:Helvetica;font-size:8.00">timerStart(TRYING)(&lt;200ms)</text> +<text text-anchor="middle" x="319" y="93" style="font-family:Helvetica;font-size:8.00">pass(INV)</text> +</g> +<g id="p1PROCEEDING" class="node"> +<text text-anchor="middle" x="55" y="206" style="font-family:Helvetica;font-size:8.00">got(1xx):</text> +<text text-anchor="middle" x="55" y="215" style="font-family:Helvetica;font-size:8.00">snd(reponse)</text> +</g> +<g id="TRYING-&gt;p1PROCEEDING" class="edge"> +<g style="fill:none;stroke:black"><path d="M216 141C174 153 157 161 108 181 103 184 97 186 92 189"/></g> +<polygon style="fill:black;stroke:black" points="91,187 83,193 93,191 91,187"/> +</g> +<g id="p2PROCEEDING" class="node"> +<text text-anchor="middle" x="187" y="206" style="font-family:Helvetica;font-size:8.00">rcv(INV) | timerExpires(TRYING):</text> +<text text-anchor="middle" x="187" y="215" style="font-family:Helvetica;font-size:8.00">snd(100)</text> +</g> +<g id="TRYING-&gt;p2PROCEEDING" class="edge"> +<g style="fill:none;stroke:black"><path d="M239 150C230 160 219 171 210 182"/></g> +<polygon style="fill:black;stroke:black" points="209,180 204,189 212,183 209,180"/> +</g> +<g id="pCOMPLETED" class="node"> +<text text-anchor="middle" x="322" y="206" style="font-family:Helvetica;font-size:8.00">got(300-699):</text> +<text text-anchor="middle" x="322" y="215" style="font-family:Helvetica;font-size:8.00">snd(response)</text> +</g> +<g id="TRYING-&gt;pCOMPLETED" class="edge"> +<g style="fill:none;stroke:black"><path d="M271 150C279 160 290 171 299 182"/></g> +<polygon style="fill:black;stroke:black" points="297,184 306,189 301,180 297,184"/> +</g> +<g id="pSTALE" class="node"> +<text text-anchor="middle" x="451" y="206" style="font-family:Helvetica;font-size:8.00">got(2XX):</text> +<text text-anchor="middle" x="451" y="215" style="font-family:Helvetica;font-size:8.00">setTimer(STALE),snd(response)</text> +</g> +<g id="TRYING-&gt;pSTALE" class="edge"> +<g style="fill:none;stroke:black"><path d="M293 142C324 153 369 171 402 186"/></g> +<polygon style="fill:black;stroke:black" points="399,187 409,189 401,183 399,187"/> +</g> +<g id="PROCEEDING" class="node"> +<ellipse cx="144" cy="281" rx="66" ry="18" style="fill:none;stroke:black"/> +<text text-anchor="middle" x="144" y="286" style="font-family:Helvetica;font-size:14.00">PROCEEDING</text> +</g> +<g id="p1PROCEEDING-&gt;PROCEEDING" class="edge"> +<g style="fill:none;stroke:black"><path d="M77 225C89 235 103 247 116 258"/></g> +<polygon style="fill:black;stroke:black" points="114,259 123,264 117,256 114,259"/> +</g> +<g id="p2PROCEEDING-&gt;PROCEEDING" class="edge"> +<g style="fill:none;stroke:black"><path d="M176 225C171 234 165 245 159 255"/></g> +<polygon style="fill:black;stroke:black" points="157,253 154,263 161,256 157,253"/> +</g> +<g id="PROCEEDING-&gt;p1PROCEEDING" class="edge"> +<g style="fill:none;stroke:black"><path d="M69 232C76 243 87 257 99 268"/></g> +<polygon style="fill:black;stroke:black" points="72,232 65,225 68,235 72,232"/> +</g> +<g id="PROCEEDING-&gt;p2PROCEEDING" class="edge"> +<g style="fill:none;stroke:black"><path d="M181 233C180 238 178 242 177 245 174 253 173 259 171 264"/></g> +<polygon style="fill:black;stroke:black" points="183,235 183,225 178,234 183,235"/> +</g> +<g id="pTxError" class="node"> +<text text-anchor="middle" x="173" y="374" style="font-family:Helvetica;font-size:8.00">transport error:</text> +<text text-anchor="middle" x="173" y="383" style="font-family:Helvetica;font-size:8.00">notify TU</text> +</g> +<g id="PROCEEDING-&gt;pTxError" class="edge"> +<g style="fill:none;stroke:black"><path d="M150 299C154 312 160 332 164 348"/></g> +<polygon style="fill:black;stroke:black" points="161,348 167,357 166,347 161,348"/> +</g> +<g id="PROCEEDING-&gt;pCOMPLETED" class="edge"> +<g style="fill:none;stroke:black"><path d="M284 228C257 242 222 259 196 270"/></g> +<polygon style="fill:black;stroke:black" points="285,230 292,223 282,226 285,230"/> +</g> +<g id="PROCEEDING-&gt;pSTALE" class="edge"> +<g style="fill:none;stroke:black"><path d="M384 227C377 229 369 231 361 233 310 248 297 249 245 263 228 269 222 273 208 276"/></g> +<polygon style="fill:black;stroke:black" points="381,231 390,225 380,226 381,231"/> +</g> +<g id="DELETE" class="node"> +<ellipse cx="304" cy="465" rx="18" ry="18" style="fill:#ffc0cb;stroke:black"/> +<ellipse cx="304" cy="465" rx="22" ry="22" style="fill:none;stroke:black"/> +<text text-anchor="middle" x="304" y="470" style="font-family:Helvetica;font-size:14.00">DEL</text> +</g> +<g id="pTxError-&gt;DELETE" class="edge"> +<g style="fill:none;stroke:black"><path d="M200 393C222 409 256 432 279 447"/></g> +<polygon style="fill:black;stroke:black" points="276,448 286,452 279,444 276,448"/> +</g> +<g id="COMPLETED" class="node"> +<ellipse cx="316" cy="281" rx="62" ry="18" style="fill:none;stroke:black"/> +<text text-anchor="middle" x="316" y="286" style="font-family:Helvetica;font-size:14.00">COMPLETED</text> +</g> +<g id="pCOMPLETED-&gt;COMPLETED" class="edge"> +<g style="fill:none;stroke:black"><path d="M321 225C320 234 320 244 319 253"/></g> +<polygon style="fill:black;stroke:black" points="317,253 318,263 321,253 317,253"/> +</g> +<g id="COMPLETED-&gt;pTxError" class="edge"> +<g style="fill:none;stroke:black"><path d="M291 298C268 314 232 337 206 353"/></g> +<polygon style="fill:black;stroke:black" points="207,349 201,357 210,353 207,349"/> +</g> +<g id="COMPLETED-&gt;COMPLETED" class="edge"> +<g style="fill:none;stroke:black"><path d="M374 288C387 287 396 285 396 281 396 278 391 276 383 275"/></g> +<polygon style="fill:black;stroke:black" points="384,273 374,274 384,278 384,273"/> +<text text-anchor="middle" x="431" y="271" style="font-family:Helvetica;font-size:8.00">expireTimer(G):</text> +<text text-anchor="middle" x="431" y="280" style="font-family:Helvetica;font-size:8.00">snd(response)</text> +<text text-anchor="middle" x="431" y="289" style="font-family:Helvetica;font-size:8.00">G = 2G</text> +<text text-anchor="middle" x="431" y="298" style="font-family:Helvetica;font-size:8.00">startTimer(G)</text> +</g> +<g id="COMPLETED-&gt;COMPLETED" class="edge"> +<g style="fill:none;stroke:black"><path d="M338 298C391 329 466 323 466 281 466 241 398 234 345 260"/></g> +<polygon style="fill:black;stroke:black" points="345,257 338,264 348,261 345,257"/> +<text text-anchor="middle" x="496" y="280" style="font-family:Helvetica;font-size:8.00">rcv(INVITE):</text> +<text text-anchor="middle" x="496" y="289" style="font-family:Helvetica;font-size:8.00">snd(response)</text> +</g> +<g id="CONFIRMED" class="node"> +<ellipse cx="304" cy="375" rx="62" ry="18" style="fill:none;stroke:black"/> +<text text-anchor="middle" x="304" y="380" style="font-family:Helvetica;font-size:14.00">CONFIRMED</text> +</g> +<g id="COMPLETED-&gt;CONFIRMED" class="edge"> +<g style="fill:none;stroke:black"><path d="M314 299C312 312 309 332 307 348"/></g> +<polygon style="fill:black;stroke:black" points="305,347 306,357 310,347 305,347"/> +<text text-anchor="middle" x="341" y="327" style="font-family:Helvetica;font-size:8.00">rcv(ACK):</text> +<text text-anchor="middle" x="341" y="336" style="font-family:Helvetica;font-size:8.00">startTimer(I)</text> +</g> +<g id="STALE" class="node"> +<ellipse cx="436" cy="375" rx="37" ry="18" style="fill:none;stroke:black"/> +<text text-anchor="middle" x="436" y="380" style="font-family:Helvetica;font-size:14.00">STALE</text> +</g> +<g id="pSTALE-&gt;STALE" class="edge"> +<g style="fill:none;stroke:black"><path d="M507 225C525 234 543 246 553 263 561 277 560 285 553 299 537 330 503 350 476 361"/></g> +<polygon style="fill:black;stroke:black" points="475,359 467,365 477,363 475,359"/> +</g> +<g id="STALE-&gt;DELETE" class="edge"> +<g style="fill:none;stroke:black"><path d="M416 390C398 405 373 424 372 425 364 430 345 441 329 450"/></g> +<polygon style="fill:black;stroke:black" points="330,446 323,454 333,451 330,446"/> +<text text-anchor="middle" x="438" y="421" style="font-family:Helvetica;font-size:8.00">timerExpires(STALE)</text> +</g> +<g id="STALE-&gt;STALE" class="edge"> +<g style="fill:none;stroke:black"><path d="M462 388C477 390 491 386 491 375 491 367 483 362 473 362"/></g> +<polygon style="fill:black;stroke:black" points="472,359 462,362 472,364 472,359"/> +<text text-anchor="middle" x="516" y="374" style="font-family:Helvetica;font-size:8.00">rcv(ACK):</text> +<text text-anchor="middle" x="516" y="383" style="font-family:Helvetica;font-size:8.00">snd to TU</text> +</g> +<g id="CONFIRMED-&gt;DELETE" class="edge"> +<g style="fill:none;stroke:black"><path d="M304 393C304 405 304 420 304 433"/></g> +<polygon style="fill:black;stroke:black" points="302,433 304,443 307,433 302,433"/> +<text text-anchor="middle" x="336" y="421" style="font-family:Helvetica;font-size:8.00">expireTimer(I)</text> +</g> +<g id="LABEL_NODE" class="node"> +<text text-anchor="middle" x="400" y="28" style="font-family:Helvetica;font-size:6.00">Server INVITE FSM</text> +<text text-anchor="middle" x="400" y="34" style="font-family:Helvetica;font-size:6.00">$Id: srv-inv-fsm.svg,v 1.2 2003/04/09 20:07:10 alan Exp $ $Name: $</text> +</g> +</g> +</svg> diff --git a/src/libs/resiprocate/resip/stack/doc/static/srv-inv-tree.pdf b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-tree.pdf new file mode 100644 index 00000000..7e991fe3 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-tree.pdf differ diff --git a/src/libs/resiprocate/resip/stack/doc/static/srv-inv-tree.png b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-tree.png new file mode 100644 index 00000000..6eb709d3 Binary files /dev/null and b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-tree.png differ diff --git a/src/libs/resiprocate/resip/stack/doc/static/srv-inv-tree.ps b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-tree.ps new file mode 100644 index 00000000..2adfca62 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-tree.ps @@ -0,0 +1,1153 @@ +%!PS-Adobe-2.0 +%%Creator: dot version 1.7.14 (Mon Oct 21 18:19:04 MDT 2002) +%%For: (alan) +%%Title: srv_inv_tree +%%Pages: (atend) +%%BoundingBox: 35 35 512 613 +%%EndComments +save +%%BeginProlog +/DotDict 200 dict def +DotDict begin + +/setupLatin1 { +mark +/EncodingVector 256 array def + EncodingVector 0 + +ISOLatin1Encoding 0 255 getinterval putinterval + +EncodingVector + dup 306 /AE + dup 301 /Aacute + dup 302 /Acircumflex + dup 304 /Adieresis + dup 300 /Agrave + dup 305 /Aring + dup 303 /Atilde + dup 307 /Ccedilla + dup 311 /Eacute + dup 312 /Ecircumflex + dup 313 /Edieresis + dup 310 /Egrave + dup 315 /Iacute + dup 316 /Icircumflex + dup 317 /Idieresis + dup 314 /Igrave + dup 334 /Udieresis + dup 335 /Yacute + dup 376 /thorn + dup 337 /germandbls + dup 341 /aacute + dup 342 /acircumflex + dup 344 /adieresis + dup 346 /ae + dup 340 /agrave + dup 345 /aring + dup 347 /ccedilla + dup 351 /eacute + dup 352 /ecircumflex + dup 353 /edieresis + dup 350 /egrave + dup 355 /iacute + dup 356 /icircumflex + dup 357 /idieresis + dup 354 /igrave + dup 360 /dcroat + dup 361 /ntilde + dup 363 /oacute + dup 364 /ocircumflex + dup 366 /odieresis + dup 362 /ograve + dup 365 /otilde + dup 370 /oslash + dup 372 /uacute + dup 373 /ucircumflex + dup 374 /udieresis + dup 371 /ugrave + dup 375 /yacute + dup 377 /ydieresis + +% Set up ISO Latin 1 character encoding +/starnetISO { + dup dup findfont dup length dict begin + { 1 index /FID ne { def }{ pop pop } ifelse + } forall + /Encoding EncodingVector def + currentdict end definefont +} def +/Times-Roman starnetISO def +/Times-Italic starnetISO def +/Times-Bold starnetISO def +/Times-BoldItalic starnetISO def +/Helvetica starnetISO def +/Helvetica-Oblique starnetISO def +/Helvetica-Bold starnetISO def +/Helvetica-BoldOblique starnetISO def +/Courier starnetISO def +/Courier-Oblique starnetISO def +/Courier-Bold starnetISO def +/Courier-BoldOblique starnetISO def +cleartomark +} bind def + +%%BeginResource: procset +/coord-font-family /Times-Roman def +/default-font-family /Times-Roman def +/coordfont coord-font-family findfont 8 scalefont def + +/InvScaleFactor 1.0 def +/set_scale { + dup 1 exch div /InvScaleFactor exch def + dup scale +} bind def + +% styles +/solid { } bind def +/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def +/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def +/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def +/bold { 2 setlinewidth } bind def +/filled { } bind def +/unfilled { } bind def +/rounded { } bind def +/diagonals { } bind def + +% hooks for setting color +/nodecolor { sethsbcolor } bind def +/edgecolor { sethsbcolor } bind def +/graphcolor { sethsbcolor } bind def +/nopcolor {pop pop pop} bind def + +/beginpage { % i j npages + /npages exch def + /j exch def + /i exch def + /str 10 string def + npages 1 gt { + gsave + coordfont setfont + 0 0 moveto + (\() show i str cvs show (,) show j str cvs show (\)) show + grestore + } if +} bind def + +/set_font { + findfont exch + scalefont setfont +} def + +% draw aligned label in bounding box aligned to current point +/alignedtext { % width adj text + /text exch def + /adj exch def + /width exch def + gsave + width 0 gt { + text stringwidth pop adj mul 0 rmoveto + } if + [] 0 setdash + text show + grestore +} def + +/boxprim { % xcorner ycorner xsize ysize + 4 2 roll + moveto + 2 copy + exch 0 rlineto + 0 exch rlineto + pop neg 0 rlineto + closepath +} bind def + +/ellipse_path { + /ry exch def + /rx exch def + /y exch def + /x exch def + matrix currentmatrix + newpath + x y translate + rx ry scale + 0 0 1 0 360 arc + setmatrix +} bind def + +/endpage { showpage } bind def + +/layercolorseq + [ % layer color sequence - darkest to lightest + [0 0 0] + [.2 .8 .8] + [.4 .8 .8] + [.6 .8 .8] + [.8 .8 .8] + ] +def + +/setlayer {/maxlayer exch def /curlayer exch def + layercolorseq curlayer get + aload pop sethsbcolor + /nodecolor {nopcolor} def + /edgecolor {nopcolor} def + /graphcolor {nopcolor} def +} bind def + +/onlayer { curlayer ne {invis} if } def + +/onlayers { + /myupper exch def + /mylower exch def + curlayer mylower lt + curlayer myupper gt + or + {invis} if +} def + +/curlayer 0 def + +%%EndResource +%%EndProlog +%%BeginSetup +14 default-font-family set_font +1 setmiterlimit +% /arrowlength 10 def +% /arrowwidth 5 def + +% make sure pdfmark is harmless for PS-interpreters other than Distiller +/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse +% make '<<' and '>>' safe on PS Level 1 devices +/languagelevel where {pop languagelevel}{1} ifelse +2 lt { + userdict (<<) cvn ([) cvn load put + userdict (>>) cvn ([) cvn load put +} if + +%%EndSetup +%%Page: 1 1 +%%PageBoundingBox: 36 36 512 613 +%%PageOrientation: Landscape +gsave +35 35 477 578 boxprim clip newpath +36 36 translate +gsave 475 0 translate 90 rotate +0 0 1 beginpage +grestore +0.5609 set_scale +848 0 translate 90 rotate +[ /CropBox [36 36 512 613] /PAGES pdfmark +0.000 0.000 0.000 graphcolor +8.00 /Helvetica set_font + +% n1 +gsave 10 dict begin +invis +0.000 0.000 0.827 nodecolor +340 609 18 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +340 606 moveto 8 -0.5 (n1) alignedtext +end grestore +end grestore + +% n2 +gsave 10 dict begin +invis +0.000 0.000 0.827 nodecolor +539 693 18 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +539 690 moveto 10 -0.5 (n2) alignedtext +end grestore +end grestore + +% n1 -> n2 +newpath 357 616 moveto +392 631 473 665 514 683 curveto +stroke +newpath 514 680 moveto +522 686 lineto +512 685 lineto +closepath +fill +gsave 10 dict begin +426 662 moveto 41 -0.5 (cSeq=INV) alignedtext +end grestore + +% n3 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 580 627 moveto +498 627 lineto +498 591 lineto +580 591 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +539 606 moveto 74 -0.5 (Proc. SRV non-INV) alignedtext +end grestore +end grestore + +% n1 -> n3 +newpath 358 609 moveto +387 609 446 609 489 609 curveto +stroke +newpath 488 607 moveto +498 609 lineto +488 612 lineto +closepath +fill +gsave 10 dict begin +426 613 moveto 40 -0.5 (CANCEL) alignedtext +end grestore + +% n9 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 1013 848 moveto +935 848 lineto +935 800 lineto +1013 800 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +974 839 moveto 42 -0.5 (snd\(RESP\)) alignedtext +974 830 moveto 44 -0.5 (mach=stale) alignedtext +974 821 moveto 45 -0.5 (state=term?) alignedtext +974 812 moveto 70 -0.5 (setTimer\(STALE\)) alignedtext +974 803 moveto 10 -0.5 (TS) alignedtext +end grestore +end grestore + +% n2 -> n9 +newpath 554 703 moveto +576 716 588 717 618 727 curveto +727 763 857 796 926 813 curveto +stroke +newpath 926 810 moveto +935 815 lineto +925 815 lineto +closepath +fill +gsave 10 dict begin +766 785 moveto 14 -0.5 (2xx) alignedtext +end grestore + +% n8 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 1018 782 moveto +930 782 lineto +930 742 lineto +1018 742 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +974 772 moveto 42 -0.5 (snd\(RESP\)) alignedtext +974 763 moveto 47 -0.5 (setTimer\(H\)) alignedtext +974 754 moveto 80 -0.5 (unrel? -> setTimer\(G\)) alignedtext +974 745 moveto 8 -0.5 (T1) alignedtext +end grestore +end grestore + +% n2 -> n8 +newpath 557 697 moveto +576 701 607 707 618 710 curveto +675 721 838 744 922 755 curveto +stroke +newpath 920 752 moveto +930 756 lineto +920 757 lineto +closepath +fill +gsave 10 dict begin +766 741 moveto 29 -0.5 (300-699) alignedtext +end grestore + +% n4 +gsave 10 dict begin +invis +0.000 0.000 0.827 nodecolor +766 693 18 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 690 moveto 10 -0.5 (n4) alignedtext +end grestore +end grestore + +% n2 -> n4 +newpath 557 693 moveto +597 693 691 693 739 693 curveto +stroke +newpath 738 691 moveto +748 693 lineto +738 696 lineto +closepath +fill +gsave 10 dict begin +652 697 moveto 24 -0.5 (101-199) alignedtext +end grestore + +% n5 +gsave 10 dict begin +invis +0.000 0.000 0.827 nodecolor +766 612 18 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 609 moveto 9 -0.5 (n5) alignedtext +end grestore +end grestore + +% n2 -> n5 +newpath 556 687 moveto +595 673 693 638 740 621 curveto +stroke +newpath 739 619 moveto +749 618 lineto +740 624 lineto +closepath +fill +gsave 10 dict begin +652 667 moveto 11 -0.5 (100) alignedtext +end grestore + +% n11 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 1004 724 moveto +944 724 lineto +944 688 lineto +1004 688 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +974 712 moveto 43 -0.5 (Proceeding) alignedtext +974 703 moveto 46 -0.5 (send\(RESP\)) alignedtext +974 694 moveto 53 -0.5 (save for re-TX) alignedtext +end grestore +end grestore + +% n10 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 1001 670 moveto +947 670 lineto +947 634 lineto +1001 634 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +974 649 moveto 12 -0.5 (ign) alignedtext +end grestore +end grestore + +% n32 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 798 576 moveto +734 576 lineto +734 540 lineto +798 540 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 555 moveto 56 -0.5 (delState\(THIS\)) alignedtext +end grestore +end grestore + +% n25 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 797 198 moveto +735 198 lineto +735 162 lineto +797 162 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 181 moveto 24 -0.5 (G = 2G) alignedtext +766 172 moveto 54 -0.5 (startTimer\(G\)) alignedtext +end grestore +end grestore + +% n26 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 793 144 moveto +739 144 lineto +739 108 lineto +793 108 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 123 moveto 12 -0.5 (ign) alignedtext +end grestore +end grestore + +% n23 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 808 360 moveto +724 360 lineto +724 324 lineto +808 324 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 339 moveto 76 -0.5 (delState\(CANCEL\)) alignedtext +end grestore +end grestore + +% n27 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 798 306 moveto +734 306 lineto +734 270 lineto +798 270 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 285 moveto 56 -0.5 (delState\(THIS\)) alignedtext +end grestore +end grestore + +% n28 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 798 252 moveto +734 252 lineto +734 216 lineto +798 216 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 231 moveto 56 -0.5 (delState\(THIS\)) alignedtext +end grestore +end grestore + +% n0 +gsave 10 dict begin +invis +0.000 0.000 0.827 nodecolor +99 527 18 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +99 524 moveto 9 -0.5 (n0) alignedtext +end grestore +end grestore + +% n0 -> n1 +newpath 116 532 moveto +135 537 165 545 190 554 curveto +212 561 217 564 237 572 curveto +264 582 295 592 316 600 curveto +stroke +newpath 315 597 moveto +323 603 lineto +313 601 lineto +closepath +fill +gsave 10 dict begin +264 594 moveto 34 -0.5 (got\(resp\)) alignedtext +end grestore + +% n0 -> n32 +newpath 117 528 moveto +206 532 600 550 727 557 curveto +stroke +newpath 724 555 moveto +734 557 lineto +724 560 lineto +closepath +fill +gsave 10 dict begin +426 546 moveto 60 -0.5 (Transport Error) alignedtext +end grestore + +% n12 +gsave 10 dict begin +invis +0.000 0.000 0.827 nodecolor +340 475 18 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +340 472 moveto 12 -0.5 (n12) alignedtext +end grestore +end grestore + +% n0 -> n12 +newpath 117 523 moveto +158 514 263 491 312 481 curveto +stroke +newpath 312 479 moveto +322 479 lineto +313 483 lineto +closepath +fill +gsave 10 dict begin +264 499 moveto 46 -0.5 (rcv\(request\)) alignedtext +end grestore + +% n22 +gsave 10 dict begin +invis +0.000 0.000 0.827 nodecolor +340 261 18 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +340 258 moveto 14 -0.5 (n22) alignedtext +end grestore +end grestore + +% n0 -> n22 +newpath 111 513 moveto +150 470 274 333 322 282 curveto +stroke +newpath 320 281 moveto +328 275 lineto +323 284 lineto +closepath +fill +gsave 10 dict begin +264 379 moveto 35 -0.5 (timer exp) alignedtext +end grestore + +% n4 -> n11 +newpath 784 694 moveto +818 696 889 700 934 703 curveto +stroke +newpath 933 700 moveto +943 704 lineto +933 705 lineto +closepath +fill +gsave 10 dict begin +868 703 moveto 32 -0.5 (Try|Proc) alignedtext +end grestore + +% n4 -> n10 +newpath 784 690 moveto +818 683 893 668 938 659 curveto +stroke +newpath 937 657 moveto +947 657 lineto +938 662 lineto +closepath +fill +gsave 10 dict begin +868 681 moveto 3 -0.5 (*) alignedtext +end grestore + +% n6 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 1019 616 moveto +929 616 lineto +929 580 lineto +1019 580 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +974 595 moveto 82 -0.5 (snd\(PROCEEDING\)) alignedtext +end grestore +end grestore + +% n5 -> n6 +newpath 784 611 moveto +814 608 874 605 920 602 curveto +stroke +newpath 919 600 moveto +929 601 lineto +919 605 lineto +closepath +fill +gsave 10 dict begin +868 610 moveto 27 -0.5 (Trying) alignedtext +end grestore + +% n7 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 1001 562 moveto +947 562 lineto +947 526 lineto +1001 526 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +974 541 moveto 12 -0.5 (ign) alignedtext +end grestore +end grestore + +% n5 -> n7 +newpath 783 606 moveto +804 599 839 587 844 586 curveto +853 583 904 566 940 555 curveto +stroke +newpath 937 553 moveto +947 553 lineto +938 558 lineto +closepath +fill +gsave 10 dict begin +868 590 moveto 3 -0.5 (*) alignedtext +end grestore + +% n13 +gsave 10 dict begin +invis +0.000 0.000 0.827 nodecolor +539 502 18 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +539 499 moveto 12 -0.5 (n13) alignedtext +end grestore +end grestore + +% n14 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 793 522 moveto +739 522 lineto +739 486 lineto +793 486 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 501 moveto 25 -0.5 (SEND) alignedtext +end grestore +end grestore + +% n13 -> n14 +newpath 557 502 moveto +595 503 684 503 732 504 curveto +stroke +newpath 729 502 moveto +739 504 lineto +729 507 lineto +closepath +fill +gsave 10 dict begin +652 506 moveto 60 -0.5 (Proc | Completed) alignedtext +end grestore + +% n15 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 793 468 moveto +739 468 lineto +739 432 lineto +793 432 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 447 moveto 12 -0.5 (ign) alignedtext +end grestore +end grestore + +% n13 -> n15 +newpath 557 498 moveto +594 489 684 469 732 458 curveto +stroke +newpath 729 456 moveto +739 456 lineto +730 461 lineto +closepath +fill +gsave 10 dict begin +652 487 moveto 3 -0.5 (*) alignedtext +end grestore + +% n16 +gsave 10 dict begin +invis +0.000 0.000 0.827 nodecolor +539 448 18 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +539 445 moveto 12 -0.5 (n16) alignedtext +end grestore +end grestore + +% n17 +gsave 10 dict begin +invis +0.000 0.000 0.827 nodecolor +766 396 18 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 393 moveto 12 -0.5 (n17) alignedtext +end grestore +end grestore + +% n16 -> n17 +newpath 557 444 moveto +596 435 692 413 739 402 curveto +stroke +newpath 738 400 moveto +748 400 lineto +739 405 lineto +closepath +fill +gsave 10 dict begin +652 433 moveto 42 -0.5 (Completed) alignedtext +end grestore + +% n21 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 576 412 moveto +502 412 lineto +502 376 lineto +576 376 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +539 391 moveto 67 -0.5 (proc. srv non-INV) alignedtext +end grestore +end grestore + +% n12 -> n13 +newpath 358 477 moveto +393 482 472 492 513 499 curveto +stroke +newpath 511 496 moveto +521 500 lineto +511 501 lineto +closepath +fill +gsave 10 dict begin +426 494 moveto 18 -0.5 (INV) alignedtext +end grestore + +% n12 -> n16 +newpath 358 471 moveto +370 469 386 466 392 465 curveto +415 461 478 455 514 451 curveto +stroke +newpath 511 449 moveto +521 450 lineto +511 454 lineto +closepath +fill +gsave 10 dict begin +426 469 moveto 21 -0.5 (ACK) alignedtext +end grestore + +% n12 -> n21 +newpath 352 461 moveto +364 450 373 448 392 439 curveto +424 424 462 412 492 405 curveto +stroke +newpath 491 403 moveto +501 402 lineto +492 408 lineto +closepath +fill +gsave 10 dict begin +426 443 moveto 40 -0.5 (CANCEL) alignedtext +end grestore + +% n18 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 1001 441 moveto +947 441 lineto +947 405 lineto +1001 405 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +974 420 moveto 36 -0.5 (del\(FSM\)) alignedtext +end grestore +end grestore + +% n17 -> n18 +newpath 784 398 moveto +819 403 893 413 938 418 curveto +stroke +newpath 937 415 moveto +947 419 lineto +937 420 lineto +closepath +fill +gsave 10 dict begin +868 415 moveto 28 -0.5 (reliable) alignedtext +end grestore + +% n19 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 1001 387 moveto +947 387 lineto +947 351 lineto +1001 351 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +6.00 /Helvetica set_font +974 370 moveto 31 -0.5 (confirmed) alignedtext +974 364 moveto 36 -0.5 (timerStart\(I\)) alignedtext +end grestore +end grestore + +% n17 -> n19 +newpath 784 394 moveto +819 389 893 379 938 374 curveto +stroke +newpath 937 372 moveto +947 373 lineto +937 377 lineto +closepath +fill +gsave 10 dict begin +868 389 moveto 39 -0.5 (unreliable) alignedtext +end grestore + +% n22 -> n23 +newpath 357 269 moveto +368 274 375 278 392 282 curveto +505 314 641 330 714 337 curveto +stroke +newpath 714 335 moveto +724 338 lineto +714 339 lineto +closepath +fill +gsave 10 dict begin +539 326 moveto 3 -0.5 (J) alignedtext +end grestore + +% n22 -> n27 +newpath 358 262 moveto +421 266 636 280 726 286 curveto +stroke +newpath 724 284 moveto +734 286 lineto +724 289 lineto +closepath +fill +gsave 10 dict begin +539 282 moveto 7 -0.5 (H) alignedtext +end grestore + +% n22 -> n28 +newpath 358 260 moveto +421 256 636 242 726 236 curveto +stroke +newpath 724 234 moveto +734 236 lineto +724 239 lineto +closepath +fill +gsave 10 dict begin +539 256 moveto 3 -0.5 (I) alignedtext +end grestore + +% n24 +gsave 10 dict begin +invis +0.000 0.000 0.827 nodecolor +539 180 18 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +539 177 moveto 14 -0.5 (n24) alignedtext +end grestore +end grestore + +% n22 -> n24 +newpath 352 247 moveto +366 232 387 210 392 207 curveto +430 187 481 182 511 180 curveto +stroke +newpath 511 178 moveto +521 180 lineto +511 183 lineto +closepath +fill +gsave 10 dict begin +426 214 moveto 7 -0.5 (G) alignedtext +end grestore + +% n29 +gsave 10 dict begin +invis +0.000 0.000 0.827 nodecolor +539 72 18 18 ellipse_path +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +539 69 moveto 14 -0.5 (n29) alignedtext +end grestore +end grestore + +% n22 -> n29 +newpath 344 243 moveto +358 208 365 199 392 170 curveto +430 132 486 100 517 83 curveto +stroke +newpath 513 82 moveto +523 80 lineto +515 87 lineto +closepath +fill +gsave 10 dict begin +426 177 moveto 14 -0.5 (Try) alignedtext +end grestore + +% n24 -> n25 +newpath 557 180 moveto +593 180 675 180 725 180 curveto +stroke +newpath 725 178 moveto +735 180 lineto +725 183 lineto +closepath +fill +gsave 10 dict begin +652 184 moveto 40 -0.5 (completed) alignedtext +end grestore + +% n24 -> n26 +newpath 557 176 moveto +594 166 684 146 732 134 curveto +stroke +newpath 729 132 moveto +739 132 lineto +730 137 lineto +closepath +fill +gsave 10 dict begin +652 166 moveto 3 -0.5 (*) alignedtext +end grestore + +% n30 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 793 90 moveto +739 90 lineto +739 54 lineto +793 54 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 69 moveto 12 -0.5 (ign) alignedtext +end grestore +end grestore + +% n29 -> n30 +newpath 557 72 moveto +594 72 680 72 729 72 curveto +stroke +newpath 729 70 moveto +739 72 lineto +729 75 lineto +closepath +fill +gsave 10 dict begin +652 76 moveto 3 -0.5 (*) alignedtext +end grestore + +% n31 +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +newpath 793 36 moveto +739 36 lineto +739 0 lineto +793 0 lineto +closepath +stroke +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +766 19 moveto 43 -0.5 (Proceeding) alignedtext +766 10 moveto 31 -0.5 (snd\(100\)) alignedtext +end grestore +end grestore + +% n29 -> n31 +newpath 557 68 moveto +594 58 684 38 732 26 curveto +stroke +newpath 729 24 moveto +739 24 lineto +730 29 lineto +closepath +fill +gsave 10 dict begin +652 58 moveto 31 -0.5 (Trying?) alignedtext +end grestore + +% LABEL_NODE +gsave 10 dict begin +solid +0.000 0.000 0.827 nodecolor +gsave 10 dict begin +0.000 0.000 0.000 nodecolor +6.00 /Helvetica set_font +99 582 moveto 58 -0.5 (Server INVITE FSM) alignedtext +99 576 moveto 176 -0.5 ($Id: srv-inv-tree.ps,v 1.1 2002/11/06 21:06:05 alan Exp $ $Name: $) alignedtext +end grestore +end grestore +endpage +grestore +%%PageTrailer +%%EndPage: 1 +%%Trailer +%%Pages: 1 +end +restore +%%EOF diff --git a/src/libs/resiprocate/resip/stack/doc/static/srv-inv-tree.svg b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-tree.svg new file mode 100644 index 00000000..1939bd87 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/static/srv-inv-tree.svg @@ -0,0 +1,281 @@ +<!-- Generated by dot version 1.7.14 (Mon Oct 21 18:19:04 MDT 2002) + For user: (alan) Title: srv_inv_tree Pages: 1--> +<svg width="497px" height="582px" xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<g id="srv_inv_tree" class="graph"> +<g id="n1" class="node"> +</g> +<g id="n2" class="node"> +</g> +<g id="n1-&gt;n2" class="edge"> +<g style="fill:none;stroke:black"><path d="M140 378C132 359 113 313 102 290"/></g> +<polygon style="fill:black;stroke:black" points="104,290 101,286 101,291 104,290"/> +<text text-anchor="middle" transform="rotate(-90 114 340)" x="114" y="340" style="font-family:Helvetica;font-size:4.49">cSeq=INV</text> +</g> +<g id="n3" class="node"> +<polygon style="fill:none;stroke:black" points="134,253 134,299 154,299 154,253 134,253"/> +<text text-anchor="middle" transform="rotate(-90 146 276)" x="146" y="276" style="font-family:Helvetica;font-size:4.49">Proc. SRV non-INV</text> +</g> +<g id="n1-&gt;n3" class="edge"> +<g style="fill:none;stroke:black"><path d="M144 378C144 361 144 328 144 304"/></g> +<polygon style="fill:black;stroke:black" points="145,305 144,299 142,305 145,305"/> +<text text-anchor="middle" transform="rotate(-90 142 340)" x="142" y="340" style="font-family:Helvetica;font-size:4.49">CANCEL</text> +</g> +<g id="n9" class="node"> +<polygon style="fill:none;stroke:black" points="10,10 10,54 37,54 37,10 10,10"/> +<text text-anchor="middle" transform="rotate(-90 15 32)" x="15" y="32" style="font-family:Helvetica;font-size:4.49">snd(RESP)</text> +<text text-anchor="middle" transform="rotate(-90 20 32)" x="20" y="32" style="font-family:Helvetica;font-size:4.49">mach=stale</text> +<text text-anchor="middle" transform="rotate(-90 25 32)" x="25" y="32" style="font-family:Helvetica;font-size:4.49">state=term?</text> +<text text-anchor="middle" transform="rotate(-90 30 32)" x="30" y="32" style="font-family:Helvetica;font-size:4.49">setTimer(STALE)</text> +<text text-anchor="middle" transform="rotate(-90 35 32)" x="35" y="32" style="font-family:Helvetica;font-size:4.49">TS</text> +</g> +<g id="n2-&gt;n9" class="edge"> +<g style="fill:none;stroke:black"><path d="M91 268C84 255 83 249 78 232 58 171 39 98 30 59"/></g> +<polygon style="fill:black;stroke:black" points="31,59 28,54 28,60 31,59"/> +<text text-anchor="middle" transform="rotate(-90 45 149)" x="45" y="149" style="font-family:Helvetica;font-size:4.49">2xx</text> +</g> +<g id="n8" class="node"> +<polygon style="fill:none;stroke:black" points="47,8 47,57 69,57 69,8 47,8"/> +<text text-anchor="middle" transform="rotate(-90 53 32)" x="53" y="32" style="font-family:Helvetica;font-size:4.49">snd(RESP)</text> +<text text-anchor="middle" transform="rotate(-90 58 32)" x="58" y="32" style="font-family:Helvetica;font-size:4.49">setTimer(H)</text> +<text text-anchor="middle" transform="rotate(-90 63 32)" x="63" y="32" style="font-family:Helvetica;font-size:4.49">unrel? -&gt; setTimer(G)</text> +<text text-anchor="middle" transform="rotate(-90 68 32)" x="68" y="32" style="font-family:Helvetica;font-size:4.49">T1</text> +</g> +<g id="n2-&gt;n8" class="edge"> +<g style="fill:none;stroke:black"><path d="M95 266C92 255 89 238 87 232 81 200 68 109 62 61"/></g> +<polygon style="fill:black;stroke:black" points="64,63 61,57 61,63 64,63"/> +<text text-anchor="middle" transform="rotate(-90 70 149)" x="70" y="149" style="font-family:Helvetica;font-size:4.49">300-699</text> +</g> +<g id="n4" class="node"> +</g> +<g id="n2-&gt;n4" class="edge"> +<g style="fill:none;stroke:black"><path d="M97 266C97 244 97 191 97 164"/></g> +<polygon style="fill:black;stroke:black" points="98,165 97,159 95,165 98,165"/> +<text text-anchor="middle" transform="rotate(-90 95 213)" x="95" y="213" style="font-family:Helvetica;font-size:4.49">101-199</text> +</g> +<g id="n5" class="node"> +</g> +<g id="n2-&gt;n5" class="edge"> +<g style="fill:none;stroke:black"><path d="M100 267C108 245 128 190 137 163"/></g> +<polygon style="fill:black;stroke:black" points="138,164 139,158 136,163 138,164"/> +<text text-anchor="middle" transform="rotate(-90 111 213)" x="111" y="213" style="font-family:Helvetica;font-size:4.49">100</text> +</g> +<g id="n11" class="node"> +<polygon style="fill:none;stroke:black" points="79,15 79,49 100,49 100,15 79,15"/> +<text text-anchor="middle" transform="rotate(-90 86 32)" x="86" y="32" style="font-family:Helvetica;font-size:4.49">Proceeding</text> +<text text-anchor="middle" transform="rotate(-90 91 32)" x="91" y="32" style="font-family:Helvetica;font-size:4.49">send(RESP)</text> +<text text-anchor="middle" transform="rotate(-90 96 32)" x="96" y="32" style="font-family:Helvetica;font-size:4.49">save for re-TX</text> +</g> +<g id="n10" class="node"> +<polygon style="fill:none;stroke:black" points="110,17 110,47 130,47 130,17 110,17"/> +<text text-anchor="middle" transform="rotate(-90 122 32)" x="122" y="32" style="font-family:Helvetica;font-size:4.49">ign</text> +</g> +<g id="n32" class="node"> +<polygon style="fill:none;stroke:black" points="162,131 162,167 183,167 183,131 162,131"/> +<text text-anchor="middle" transform="rotate(-90 174 149)" x="174" y="149" style="font-family:Helvetica;font-size:4.49">delState(THIS)</text> +</g> +<g id="n25" class="node"> +<polygon style="fill:none;stroke:black" points="374,131 374,166 395,166 395,131 374,131"/> +<text text-anchor="middle" transform="rotate(-90 384 149)" x="384" y="149" style="font-family:Helvetica;font-size:4.49">G = 2G</text> +<text text-anchor="middle" transform="rotate(-90 389 149)" x="389" y="149" style="font-family:Helvetica;font-size:4.49">startTimer(G)</text> +</g> +<g id="n26" class="node"> +<polygon style="fill:none;stroke:black" points="405,134 405,164 425,164 425,134 405,134"/> +<text text-anchor="middle" transform="rotate(-90 417 149)" x="417" y="149" style="font-family:Helvetica;font-size:4.49">ign</text> +</g> +<g id="n23" class="node"> +<polygon style="fill:none;stroke:black" points="284,125 284,172 304,172 304,125 284,125"/> +<text text-anchor="middle" transform="rotate(-90 295 149)" x="295" y="149" style="font-family:Helvetica;font-size:4.49">delState(CANCEL)</text> +</g> +<g id="n27" class="node"> +<polygon style="fill:none;stroke:black" points="314,131 314,167 334,167 334,131 314,131"/> +<text text-anchor="middle" transform="rotate(-90 326 149)" x="326" y="149" style="font-family:Helvetica;font-size:4.49">delState(THIS)</text> +</g> +<g id="n28" class="node"> +<polygon style="fill:none;stroke:black" points="344,131 344,167 364,167 364,131 344,131"/> +<text text-anchor="middle" transform="rotate(-90 356 149)" x="356" y="149" style="font-family:Helvetica;font-size:4.49">delState(THIS)</text> +</g> +<g id="n0" class="node"> +</g> +<g id="n0-&gt;n1" class="edge"> +<g style="fill:none;stroke:black"><path d="M187 513C184 503 180 486 175 472 171 460 169 457 165 446 159 430 153 413 149 401"/></g> +<polygon style="fill:black;stroke:black" points="151,402 147,397 148,403 151,402"/> +<text text-anchor="middle" transform="rotate(-90 152 430)" x="152" y="430" style="font-family:Helvetica;font-size:4.49">got(resp)</text> +</g> +<g id="n0-&gt;n32" class="edge"> +<g style="fill:none;stroke:black"><path d="M189 513C187 463 177 242 173 171"/></g> +<polygon style="fill:black;stroke:black" points="174,172 173,167 171,172 174,172"/> +<text text-anchor="middle" transform="rotate(-90 179 340)" x="179" y="340" style="font-family:Helvetica;font-size:4.49">Transport Error</text> +</g> +<g id="n12" class="node"> +</g> +<g id="n0-&gt;n12" class="edge"> +<g style="fill:none;stroke:black"><path d="M192 513C197 490 210 431 216 404"/></g> +<polygon style="fill:black;stroke:black" points="217,404 217,398 215,403 217,404"/> +<text text-anchor="middle" transform="rotate(-90 206 430)" x="206" y="430" style="font-family:Helvetica;font-size:4.49">rcv(request)</text> +</g> +<g id="n22" class="node"> +</g> +<g id="n0-&gt;n22" class="edge"> +<g style="fill:none;stroke:black"><path d="M198 516C222 494 299 425 327 398"/></g> +<polygon style="fill:black;stroke:black" points="328,399 331,395 326,397 328,399"/> +<text text-anchor="middle" transform="rotate(-90 273 430)" x="273" y="430" style="font-family:Helvetica;font-size:4.49">timer exp</text> +</g> +<g id="n4-&gt;n11" class="edge"> +<g style="fill:none;stroke:black"><path d="M96 139C95 120 93 80 91 55"/></g> +<polygon style="fill:black;stroke:black" points="93,55 91,50 90,55 93,55"/> +<text text-anchor="middle" transform="rotate(-90 91 92)" x="91" y="92" style="font-family:Helvetica;font-size:4.49">Try|Proc</text> +</g> +<g id="n4-&gt;n10" class="edge"> +<g style="fill:none;stroke:black"><path d="M99 139C102 120 111 78 116 52"/></g> +<polygon style="fill:black;stroke:black" points="117,53 117,47 114,52 117,53"/> +<text text-anchor="middle" transform="rotate(-90 104 92)" x="104" y="92" style="font-family:Helvetica;font-size:4.49">*</text> +</g> +<g id="n6" class="node"> +<polygon style="fill:none;stroke:black" points="140,7 140,57 160,57 160,7 140,7"/> +<text text-anchor="middle" transform="rotate(-90 152 32)" x="152" y="32" style="font-family:Helvetica;font-size:4.49">snd(PROCEEDING)</text> +</g> +<g id="n5-&gt;n6" class="edge"> +<g style="fill:none;stroke:black"><path d="M143 139C144 122 146 88 148 63"/></g> +<polygon style="fill:black;stroke:black" points="149,63 148,57 146,63 149,63"/> +<text text-anchor="middle" transform="rotate(-90 143 92)" x="143" y="92" style="font-family:Helvetica;font-size:4.49">Trying</text> +</g> +<g id="n7" class="node"> +<polygon style="fill:none;stroke:black" points="170,17 170,47 190,47 190,17 170,17"/> +<text text-anchor="middle" transform="rotate(-90 182 32)" x="182" y="32" style="font-family:Helvetica;font-size:4.49">ign</text> +</g> +<g id="n5-&gt;n7" class="edge"> +<g style="fill:none;stroke:black"><path d="M146 139C150 128 156 108 157 105 159 100 168 71 174 51"/></g> +<polygon style="fill:black;stroke:black" points="175,53 175,47 173,52 175,53"/> +<text text-anchor="middle" transform="rotate(-90 155 92)" x="155" y="92" style="font-family:Helvetica;font-size:4.49">*</text> +</g> +<g id="n13" class="node"> +</g> +<g id="n14" class="node"> +<polygon style="fill:none;stroke:black" points="193,134 193,164 213,164 213,134 193,134"/> +<text text-anchor="middle" transform="rotate(-90 205 149)" x="205" y="149" style="font-family:Helvetica;font-size:4.49">SEND</text> +</g> +<g id="n13-&gt;n14" class="edge"> +<g style="fill:none;stroke:black"><path d="M204 266C203 245 203 195 203 168"/></g> +<polygon style="fill:black;stroke:black" points="204,170 203,164 201,170 204,170"/> +<text text-anchor="middle" transform="rotate(-90 202 213)" x="202" y="213" style="font-family:Helvetica;font-size:4.49">Proc | Completed</text> +</g> +<g id="n15" class="node"> +<polygon style="fill:none;stroke:black" points="223,134 223,164 243,164 243,134 223,134"/> +<text text-anchor="middle" transform="rotate(-90 235 149)" x="235" y="149" style="font-family:Helvetica;font-size:4.49">ign</text> +</g> +<g id="n13-&gt;n15" class="edge"> +<g style="fill:none;stroke:black"><path d="M206 266C211 245 222 195 229 168"/></g> +<polygon style="fill:black;stroke:black" points="230,170 230,164 227,169 230,170"/> +<text text-anchor="middle" transform="rotate(-90 212 213)" x="212" y="213" style="font-family:Helvetica;font-size:4.49">*</text> +</g> +<g id="n16" class="node"> +</g> +<g id="n17" class="node"> +</g> +<g id="n16-&gt;n17" class="edge"> +<g style="fill:none;stroke:black"><path d="M236 266C242 244 254 190 260 164"/></g> +<polygon style="fill:black;stroke:black" points="261,165 261,159 258,164 261,165"/> +<text text-anchor="middle" transform="rotate(-90 243 213)" x="243" y="213" style="font-family:Helvetica;font-size:4.49">Completed</text> +</g> +<g id="n21" class="node"> +<polygon style="fill:none;stroke:black" points="254,255 254,297 275,297 275,255 254,255"/> +<text text-anchor="middle" transform="rotate(-90 266 276)" x="266" y="276" style="font-family:Helvetica;font-size:4.49">proc. srv non-INV</text> +</g> +<g id="n12-&gt;n13" class="edge"> +<g style="fill:none;stroke:black"><path d="M218 378C215 358 210 314 206 291"/></g> +<polygon style="fill:black;stroke:black" points="207,292 205,286 205,292 207,292"/> +<text text-anchor="middle" transform="rotate(-90 208 340)" x="208" y="340" style="font-family:Helvetica;font-size:4.49">INV</text> +</g> +<g id="n12-&gt;n16" class="edge"> +<g style="fill:none;stroke:black"><path d="M221 378C222 371 224 362 225 359 227 346 230 310 233 290"/></g> +<polygon style="fill:black;stroke:black" points="234,292 233,286 231,292 234,292"/> +<text text-anchor="middle" transform="rotate(-90 222 340)" x="222" y="340" style="font-family:Helvetica;font-size:4.49">ACK</text> +</g> +<g id="n12-&gt;n21" class="edge"> +<g style="fill:none;stroke:black"><path d="M227 381C233 374 234 369 239 359 248 341 254 319 258 303"/></g> +<polygon style="fill:black;stroke:black" points="259,303 260,298 257,303 259,303"/> +<text text-anchor="middle" transform="rotate(-90 237 340)" x="237" y="340" style="font-family:Helvetica;font-size:4.49">CANCEL</text> +</g> +<g id="n18" class="node"> +<polygon style="fill:none;stroke:black" points="238,17 238,47 258,47 258,17 238,17"/> +<text text-anchor="middle" transform="rotate(-90 250 32)" x="250" y="32" style="font-family:Helvetica;font-size:4.49">del(FSM)</text> +</g> +<g id="n17-&gt;n18" class="edge"> +<g style="fill:none;stroke:black"><path d="M262 139C259 119 254 78 251 52"/></g> +<polygon style="fill:black;stroke:black" points="253,53 251,47 250,53 253,53"/> +<text text-anchor="middle" transform="rotate(-90 253 92)" x="253" y="92" style="font-family:Helvetica;font-size:4.49">reliable</text> +</g> +<g id="n19" class="node"> +<polygon style="fill:none;stroke:black" points="268,17 268,47 289,47 289,17 268,17"/> +<text text-anchor="middle" transform="rotate(-90 278 32)" x="278" y="32" style="font-family:Helvetica;font-size:3.37">confirmed</text> +<text text-anchor="middle" transform="rotate(-90 281 32)" x="281" y="32" style="font-family:Helvetica;font-size:3.37">timerStart(I)</text> +</g> +<g id="n17-&gt;n19" class="edge"> +<g style="fill:none;stroke:black"><path d="M265 139C267 119 273 78 276 52"/></g> +<polygon style="fill:black;stroke:black" points="277,53 276,47 274,53 277,53"/> +<text text-anchor="middle" transform="rotate(-90 267 92)" x="267" y="92" style="font-family:Helvetica;font-size:4.49">unreliable</text> +</g> +<g id="n22-&gt;n23" class="edge"> +<g style="fill:none;stroke:black"><path d="M335 378C332 372 330 368 327 359 309 295 300 219 296 178"/></g> +<polygon style="fill:black;stroke:black" points="298,178 296,172 295,178 298,178"/> +<text text-anchor="middle" transform="rotate(-90 303 276)" x="303" y="276" style="font-family:Helvetica;font-size:4.49">J</text> +</g> +<g id="n22-&gt;n27" class="edge"> +<g style="fill:none;stroke:black"><path d="M339 378C336 342 328 222 325 171"/></g> +<polygon style="fill:black;stroke:black" points="326,172 325,167 323,172 326,172"/> +<text text-anchor="middle" transform="rotate(-90 327 276)" x="327" y="276" style="font-family:Helvetica;font-size:4.49">H</text> +</g> +<g id="n22-&gt;n28" class="edge"> +<g style="fill:none;stroke:black"><path d="M340 378C342 342 350 222 353 171"/></g> +<polygon style="fill:black;stroke:black" points="354,172 353,167 351,172 354,172"/> +<text text-anchor="middle" transform="rotate(-90 342 276)" x="342" y="276" style="font-family:Helvetica;font-size:4.49">I</text> +</g> +<g id="n24" class="node"> +</g> +<g id="n22-&gt;n24" class="edge"> +<g style="fill:none;stroke:black"><path d="M347 381C355 373 368 361 369 359 381 337 383 309 385 292"/></g> +<polygon style="fill:black;stroke:black" points="386,292 385,286 383,292 386,292"/> +<text text-anchor="middle" transform="rotate(-90 365 340)" x="365" y="340" style="font-family:Helvetica;font-size:4.49">G</text> +</g> +<g id="n29" class="node"> +</g> +<g id="n22-&gt;n29" class="edge"> +<g style="fill:none;stroke:black"><path d="M349 386C369 378 374 374 390 359 411 337 429 306 439 289"/></g> +<polygon style="fill:black;stroke:black" points="440,291 441,285 437,290 440,291"/> +<text text-anchor="middle" transform="rotate(-90 386 340)" x="386" y="340" style="font-family:Helvetica;font-size:4.49">Try</text> +</g> +<g id="n24-&gt;n25" class="edge"> +<g style="fill:none;stroke:black"><path d="M385 266C385 246 385 200 385 172"/></g> +<polygon style="fill:black;stroke:black" points="386,172 385,166 383,172 386,172"/> +<text text-anchor="middle" transform="rotate(-90 382 213)" x="382" y="213" style="font-family:Helvetica;font-size:4.49">completed</text> +</g> +<g id="n24-&gt;n26" class="edge"> +<g style="fill:none;stroke:black"><path d="M387 266C392 245 404 195 410 168"/></g> +<polygon style="fill:black;stroke:black" points="411,170 411,164 409,169 411,170"/> +<text text-anchor="middle" transform="rotate(-90 392 213)" x="392" y="213" style="font-family:Helvetica;font-size:4.49">*</text> +</g> +<g id="n30" class="node"> +<polygon style="fill:none;stroke:black" points="435,134 435,164 455,164 455,134 435,134"/> +<text text-anchor="middle" transform="rotate(-90 447 149)" x="447" y="149" style="font-family:Helvetica;font-size:4.49">ign</text> +</g> +<g id="n29-&gt;n30" class="edge"> +<g style="fill:none;stroke:black"><path d="M445 266C445 245 445 197 445 170"/></g> +<polygon style="fill:black;stroke:black" points="446,170 445,164 443,170 446,170"/> +<text text-anchor="middle" transform="rotate(-90 443 213)" x="443" y="213" style="font-family:Helvetica;font-size:4.49">*</text> +</g> +<g id="n31" class="node"> +<polygon style="fill:none;stroke:black" points="465,134 465,164 486,164 486,134 465,134"/> +<text text-anchor="middle" transform="rotate(-90 475 149)" x="475" y="149" style="font-family:Helvetica;font-size:4.49">Proceeding</text> +<text text-anchor="middle" transform="rotate(-90 480 149)" x="480" y="149" style="font-family:Helvetica;font-size:4.49">snd(100)</text> +</g> +<g id="n29-&gt;n31" class="edge"> +<g style="fill:none;stroke:black"><path d="M447 266C453 245 464 195 471 168"/></g> +<polygon style="fill:black;stroke:black" points="472,170 472,164 469,169 472,170"/> +<text text-anchor="middle" transform="rotate(-90 453 213)" x="453" y="213" style="font-family:Helvetica;font-size:4.49">Trying?</text> +</g> +<g id="LABEL_NODE" class="node"> +<text text-anchor="middle" transform="rotate(-90 159 523)" x="159" y="523" style="font-family:Helvetica;font-size:3.37">Server INVITE FSM</text> +<text text-anchor="middle" transform="rotate(-90 162 523)" x="162" y="523" style="font-family:Helvetica;font-size:3.37">$Id: srv-inv-tree.svg,v 1.2 2003/04/09 20:07:10 alan Exp $ $Name: $</text> +</g> +</g> +</svg> diff --git a/src/libs/resiprocate/resip/stack/doc/using-dialogUsageManager.html b/src/libs/resiprocate/resip/stack/doc/using-dialogUsageManager.html new file mode 100644 index 00000000..bffb054d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/using-dialogUsageManager.html @@ -0,0 +1,131 @@ +<html><head> + <meta http-equiv="Content-Type" content="text/html; charset=ISO8859_1"> + <title>Programmer Guide: Dialog Usage Manager</title><meta name="generator" content="DocBook XSL Stylesheets V1.64.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="article" lang="en"><div class="titlepage"><div><div><h1 class="title"><a name="d0e2"></a>Programmer Guide: Dialog Usage Manager</h1></div></div><div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="#d0e5"> Concepts </a></span></dt><dd><dl><dt><span class="sect2"><a href="#d0e8"> Major Components </a></span></dt><dt><span class="sect2"><a href="#d0e15"> Definitions </a></span></dt></dl></dd><dt><span class="sect1"><a href="#d0e34">Handling Invite Sessions - Client</a></span></dt><dt><span class="sect1"><a href="#d0e41">Handling Invite Sessions - Server</a></span></dt><dt><span class="sect1"><a href="#d0e50">Handling Registration - Client</a></span></dt><dt><span class="sect1"><a href="#d0e59">Handling Registrations - Server</a></span></dt><dt><span class="sect1"><a href="#d0e64">Handling Subscriptions - Client</a></span></dt><dt><span class="sect1"><a href="#d0e69">Handling Subscritpions - Server </a></span></dt><dt><span class="sect1"><a href="#d0e74">Handling Publictionas - client </a></span></dt><dt><span class="sect1"><a href="#d0e79">Handling Publications - Server </a></span></dt><dt><span class="sect1"><a href="#d0e84">Dealing with Refer </a></span></dt><dt><span class="sect1"><a href="#d0e89">Dealing with Digest authentication </a></span></dt><dt><span class="sect1"><a href="#d0e94">Dealing with complex offer/answer </a></span></dt></dl></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e5"></a> Concepts </h2></div></div><div></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e8"></a> Major Components </h3></div></div><div></div></div><p> +The DialogUsamgeManger (or DUM) is the unit that keeps track of all the data +sturcutres and sits on top of the transaction layer of the stack. It keeps track +of multiple DialogSet which contains Dialogs. Each DialogSet contains all the +Dialog that were created by a common initial request. They all share the same +SIP Call-Id and from tag from the orginal request. Inside a specific dialogSet +there can be some type of BaseCreator that represnets the intial request that +generated the dialog. This will only exist onthe UAC side. The DialogSet also +contains serveral objects dereived from BaseUsage that are using this particular +dialog. There are several types of things that are a Usage of this dialog. There +can be one InvSession, one Registration, one Publication, multiple Subscriptions +and multiple OutOfDialogRequests. Note the name OutOfDialog is a little weird - +they are actually in a thing a lot like a dialog but are transactions that are +not in one of the other categories. Typically messages that result in +OutOfDialogRequests are MESSAGE and OPTIONS. +</p><p> +An initial SIP Request is created by calling the makeX interfaces on the DUM. It +is then sent using the send interface on the DUM. This will create some internal +data structures and return a DialogSetID that can be used to find all the state +asscociates resulting from this. When a response comes into this, a callback +from one of the Handler classes will be called to notify the application about +incoming events. This will pass up some type of client or server usages class +that can be used to send aditional messages and responses inthe context of this +particularr usage of the Dialog. +</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e15"></a> Definitions </h3></div></div><div></div></div><p> +DialogUsage Manager - Main class that keeps track of all the DialogsSets, +Dialogs, and Usages. +</p><p> +DialogSet - A set of dialogs that were gerneated from a common request. They +share the same call-id and the same from tag in the +request that genreated the dialog. +</p><p> +Dialog - A container holding such things and local and remote CSEQ, URI, +Call-ID and such as defined by the SIP standard. +</p><p> +DialogID - An identifier that uniquely finds a a Dialog by Call-ID, and to and +from tags. +</p><p> +DialogSetID - An identifier that uniquily identifies a Dialog-Set and is formed +from Call-ID and +</p><p> +Usages - These are the objects are are using a dialog. They include +ClientInviteSession, ClientOutOfDialogReq, ClientPublication, +ClientRegistration, ClientSubscription, ServerInviteSession, +ServerOutOfDialogReq, ServerPublication, ServerRegistration, and +ServerSubscription. These have varios operations that can be called on them to +</p><p> +Handlers - These are objects uses to derive class from that allow callbacks from +this layer to the application using ti. They include InviteSessionHandler, +OutOfDialogHandler, RegistrationHandler, SubscribeHandler, and +PublictionHandler. +</p><p> +Handles - All the Usaves and Handlers are not really exposes to the +applications using this layer. Instead, handles to them are passed out. When +the applications goes to use a handle, the unerlying object may have been +delted and the applications must be prepared for this not to work. +</p></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e34"></a>Handling Invite Sessions - Client</h2></div></div><div></div></div><p> +Initially a cleint can call makeNewInvite on the DUM and get a SipMessage. It +can take this and modify it such as adding SDP. It then calls sends on the DUM +and sends themessage. This will cause the creation of a DialogSet for the +Dialogs resulting from this request. When a responses (such as a 180) comes back +that cuase the creation of an early dialog, the onEarly callback in the Handler +willbe called. This will pass in a ClientInviteSession to the applications and +the eactual message received. When and offer or answer is recived, the onAnswer +or onOffer callback will be called. In the typical case wher the INVITE sent +and offer and the 180 has SDP but it is not an answer, only the onEarly will be +called. If the 180 was reliable so that it was an aswer, then both the onEarly +and the onAnswer would be called. +</p><p> +If the client which to sent a new answer or offer it must call the setAnswer or +setAnswer object with the new SDP. This saves it but does not send a +messages. the client then calls sendAnyAnswer or sendAnyOffer to cause the +aproperate message to be sent to send a new offer or answer. This might be a +PRACK, an UPDATE, a reINVITE depending on the currenst state of the dialog. +</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e41"></a>Handling Invite Sessions - Server</h2></div></div><div></div></div><p> +When the sserver first recives an INVITE, it will call the onNewInvSession +handler and pass a handle to a ServerInviteSession. It the UA is busy this +could be rejected with the reject mehtod. If the INVITE contaned an offer, the +onOffer callback gets called. When this happens, the server needs to call the +setAnser function to set the new offer. This will not send the offer. The +server must then call the sendAnserInAnyMessage to actually send the +offer. This sequence of two calls seem a little weired but is required to make +the all the cases work when doing PRACK stuff. +</p><p> +From this pont on thir can be several rounds of sending and receivng offers and +aswers. When the UA which to sendd a 200 and "answer" the call, it calls the +accept method. Finially when it wishes to end the call it calls the end +method. If the other side ends the call, the onTerminated callback will get +called. +</p><p> +INFO messages can be received in the dialog with the onInfo callback. Refer is +a topic all on it's own and covered later in this document. +</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e50"></a>Handling Registration - Client</h2></div></div><div></div></div><p> +The client froms a new registration message by calling makeResitration in the +DUM. This returns a SIP messages which is sent by calling send on the DUM. This +will initate the registrtionprocess. +</p><p> +If it succeedes or failes, the aproperate onSuccess or onFailure will be +called. The DUM will contintue to run the times and keep this registration +alive. This may result in an onFailure callback at any time. +</p><p> +The callback passes back a handle to a ClientRegistration which provies +serveral methods for the client to discover and manipulate the contacts for the +registration. myContacts refers to contatst this UA has registered while +allContacts referes to any contact that has been registered for this AOR. The +add and remove binding calls allow for manipulation of contacts this UA +registered and for cotacts that other UA registered. +</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e59"></a>Handling Registrations - Server</h2></div></div><div></div></div><p> +When a new registgration is received the onAdd will be called. The server needs +to either accept this on rejct it using the coresponding function isn the +ServerRegistration class. If the registration is refreshed byt the client +onRefresh will be called and if it expereis before it is refreshed, onExpired +will be called. If the client removes on of the the contacts, onRremoveOne will +be called and if the client removes all the contacts, onRemoveAll be be called. +</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e64"></a>Handling Subscriptions - Client</h2></div></div><div></div></div><p> +</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e69"></a>Handling Subscritpions - Server </h2></div></div><div></div></div><p> +Gets a onNewSubecritpion callabck when it is created and onRefresh or +OnTerminated as the clients updates it. +</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e74"></a>Handling Publictionas - client </h2></div></div><div></div></div><p> +</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e79"></a>Handling Publications - Server </h2></div></div><div></div></div><p> +</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e84"></a>Dealing with Refer </h2></div></div><div></div></div><p> +</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e89"></a>Dealing with Digest authentication </h2></div></div><div></div></div><p> +</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e94"></a>Dealing with complex offer/answer </h2></div></div><div></div></div><p> +When you receive an offer, you need to send an aswer. If you don't like +something about the SIP message with the offer you can totally reject it at the +sip level, but if you don't like the media it proposed, you need to send a +answer with all the m lines you don't like zeroed out. You can then instantly +send a counter offer to propose somethign new. +</p></div></div></body></html> diff --git a/src/libs/resiprocate/resip/stack/doc/using-dialogUsageManager.pdf b/src/libs/resiprocate/resip/stack/doc/using-dialogUsageManager.pdf new file mode 100644 index 00000000..6bcd6fd0 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/using-dialogUsageManager.pdf @@ -0,0 +1,384 @@ +%PDF-1.3 +% +4 0 obj +<< /Type /Info +/Producer (FOP 0.20.5) >> +endobj +5 0 obj +<< /Length 2730 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb"/+?ZXu3&V'PQcso0OoCu['h\&#a\hh'rYrqDIY7D0J8[q<eNZdBWgDAp'\4["24k!.H?^\S)Foa-0$g_='&UqJSqruGS/<%7nMe7n?RIBsX7<.J92J9kM2ueM5&G]XuVmA5']el>,(AlcLhgDH)9eH'c=eF"m_YN!11Z-]-o5gs5nkWcPPnL]D1ZmM-Z'"4UJ'AaY*BFPjR?tn?/564"9iC3=7[0c^NE&&OK=Me1SZ]EW4>][.IcTU)"H=1+\WaJ>,`$)OWqD1\XNF"uN?6"bZ_/C$8I`OsO^t.%A3#H'XU9@;>$]'9=+Bq`1GJ>H1nb4Mk^SA>3::0n'L@;@bQE`*2r_<HO3u>LZJ$D#&jkJEo^W*Pd"Eb<T=]L9PKR=T[451OWj6hhs2A!1d"Eb<j.TBp"\q7$:*J^PU0R(bfcT4HrH7p923R0-WAR-bjBN8/gaSG-FFAr'9+Q>8'7-bd*B&"$Cm=nM*;3Fa?i-mp.%.jBTI2Rif8:VnfPphW_g[mjV41Y1M7h;/LKuc4K9mYCKI6=]7uo`QO?V9aT@e/the]jc?hC+PHU8Blr<U(qEdP!^4Qa>dm8=b.3h5nM3oLuK5KoKB1niN^*qe;JO.YCAc/BO1h>"rZ3hZlYOjN-[RmiB`m\b6=;an1U$Ff%2G0>l^l!'Ya:$;h%lZr94><hEn4RL0&Ra=^;E#S5L8]986mo?\WB,=e<hHT#R3qlB_6N<D9nS"*\c]0>RC*RjgZtPr28b+TEke^#\^[tn]1niNO*d>aTJ$r8kec)e:hhY.3c(=s!..ob&?o@c@KI6=r:[DHDq;+5+^3dg7ji3RKn"-"3nb+P,1G;=[++1<5DY3)OM<AbRS9T%@i%)AjHnL_2M1*<dVo=*0Da_-eLOW.ol^Nc/=*HU<SeJ([iJ(!A9@`MU_5K"b*dG;#'OQZLa*`EVDKeGH8i2,Jh6_=P2RR()7CckB<5XU_P8fTe*Lni@MIJ>AY>Z-g?>e;t6u<"%-np-:k"\%SD[o%(CoeR3E0'5KL9S&tp!_[:+`cK.)Kj[e\M0M^P)6g.Wa\V3;3d,;V*8dlR5Q-Tf>;*e0I"^0^;;`"js/j+_.a#RV\'2\4_b?.P@ShZ<k#$(B]P$fb6QT%msi*-)$[[%/g6Sd[J[]qM5WoaisZGGeC@d>Po+4Rr8m^A/"4PHE%o],or"raf'fB#7ejsqMAWisJQUOSSu>+p:)8C!5ZIDGPqYI2n,WUR]$tK6RL"NA+:GSX"`[Rj:5Ag`f";P?&PH/tX$*5HLBCV!mC&9%OKI@I/MF_]mUK"&EfY<E'M-dF@/R[%nArl*O@6#[VgE+(>N:s\N@\Y#$d0h+XPjb$YuRmkHaR@3<TWY"./?U-IZ7]R_0>?#SH]CAT+'.B)_=t'McL\&JJe9U%foU17#a=6kNMpE'qM&]<6O00dBG)N1XkV>qH;.L9+Rt=MXZ2+AIVrR3n170eX1^;RYl61&@FOs[6%6t%5H2N&8W8Z`/Aq?oGo)(32*/h,r3&sW/63&M+(XDU#n25%Yn.Pcs"4:OGS<VDf@!JQ<[tBM!OU^Ia\2GD(:_pcu+OhrGInjDq!PUHW5c+gTrAW@famFQSQX:&9bA0a0tfRL:-jq>S4C^./fuW=P_h">iSK>1qp7+]4R\X]-,>9',+sXYTUGS9s\>Hn"m$c6s^F@?q7FFC=^IBpT9;3XB:b5hYNN!etZui;I?6+f'6pFbI0F)&kbU!gO=-7p9Q83Nr#jX"9DA#X9=7](tT-.CVgq:Yb9_uLbqasDQ6l3QuHFc*Y)eaU&BML2bVo8PNGcRMC.2L<TR9*Z+>t8jt]HF1?"]5\$tgTrbtX,;OBK<`5bZ3l]8g9H>Y_D9+p.TH_SXPo23d6$qp_QpcRn6[^mg0dMuX[RY-=6E#;E&JVa@<HgsQ(K.G?jH7]KGUfZZ7[O/9RLq5dD>^'UHP_PgoOW$PLPO>`EcdG<.!RdT#bUY/:/C53;9mV-&l3e<oa[kB^N"d+nkTNHi5&L#CF6q9UCH$BO*$1.V^_9u;>+/?d-#5SYd+;?H']%2\(ad=,dV(G<eB<RTX2h>s[/j6*&RMN$Q!b5_e[A/'3Hd6<'Nu;QTaX^1'0Hcf'?/]/'I>6r&c$WU(FX;La;du5ld)Bi]I.4hC+T(\;c'so0AL`o=9?%/ZR"!;.#;;t=;.QqV'5\B[>+j'fCR:TBK0.,[(I#03Q[qi>VX&0@1uhpqVai?ic*Pt4h,&UX0s0LQ,[q>-ElU"/>n0G'H,g5/fW&<:2*YX+S*B%$.G?Ap-9H8"Y!.-OhqcFO6Kjh/?>1ti<)3,56Q;eG1=3bqcF-7&J.UWV*MVPN@Ndla\'LOIjm&'E;<gmQ+@_`RjBWa[-O*-et>VsKm8_p,0;e;o*2?O+.QZBQB_-L5MjfASD)M^'jTFFnqh^g+:>e)FSsO:-Z4bB5P+Fsji@81Z"h0`D/t$^E?eH)CkAuTN'f;rcnu@K%bEu'NSe%ESMGpX+Vqr7Ls%cQ/\N6dG44YJr-7^UNtQ#1RcesN=X'!s`hYf$N^n_QL9+.2RDY_.i8!'c_S@lQ05YI>fGNWc7uYRK5(rIY%0>MK2$b;K<ZJ/k#p64#krA"6Mq,u;<V)F`4IVP_]V8)qL+r&%CD#lc-R@'<hmrO+WLr`48+Y9Pb<@K&IYU.W#%NGkF*rsog`9p@3Er-SmHjf2\7-AG_jd]u[7OnlTk'IVN!TIU>!P7M)l^5*%K~> +endstream +endobj +6 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 5 0 R +/Annots 7 0 R +>> +endobj +7 0 obj +[ +8 0 R +10 0 R +12 0 R +14 0 R +16 0 R +18 0 R +20 0 R +22 0 R +24 0 R +26 0 R +28 0 R +30 0 R +32 0 R +34 0 R +] +endobj +8 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 589.019 157.22 579.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 9 0 R +/H /I +>> +endobj +10 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 578.019 221.5 568.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 11 0 R +/H /I +>> +endobj +12 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 144.0 567.019 189.0 557.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 13 0 R +/H /I +>> +endobj +14 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 556.019 252.78 546.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 15 0 R +/H /I +>> +endobj +16 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 545.019 254.43 535.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 17 0 R +/H /I +>> +endobj +18 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 534.019 241.39 524.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 19 0 R +/H /I +>> +endobj +20 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 523.019 246.93 513.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 21 0 R +/H /I +>> +endobj +22 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 512.019 246.95 502.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 23 0 R +/H /I +>> +endobj +24 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 501.019 248.6 491.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 25 0 R +/H /I +>> +endobj +26 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 490.019 239.72 480.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 27 0 R +/H /I +>> +endobj +28 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 479.019 243.6 469.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 29 0 R +/H /I +>> +endobj +30 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 468.019 196.65 458.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 31 0 R +/H /I +>> +endobj +32 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 457.019 259.71 447.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 33 0 R +/H /I +>> +endobj +34 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 120.0 446.019 261.91 436.019 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 35 0 R +/H /I +>> +endobj +36 0 obj +<< /Length 3496 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gau0F962>g%DM^@W:lD1._AbsWV+?W4.]$.XdS_5EcT7`5d`"uR9!88%kIYR@1saa;VcLGQ'<p!5S=2b&-UY^ATRP9Vee1--f`TdIl/91?VO""o:([cBh)Eedq#a$D2tC+s*1G0Tq?fQh5#s#P)Xq'U#mpaF'U[jQ*MU^5o2U_ZC,j)*sa_/dod>"jc2U"F&<A<<V!(-8bg3`a5=$+5!>tbqB1[TAplVR.[3IXBm+N8ZnXrJ1"uOOZHdhTn^cC-G&ssLCc%:X*nU,hlGbA*Wa4'!D_[9R%0FH&)f"5qe5eY62JTG2i_BL$&8Fl2]p/a7d&==P$&[Rdm5JFU+^4K+9a#OsqKefE?g/dS-D'N(9?^G!,p$Xh^GCW(`pe'G/HX,QR.U]+;Jb2r=%>9L0CqKLVbd85l.(9``Np:rC2C0Uc*=f>aBB2j'a*BH#k[h_12lH/T`JhB33'-BRQG;@,Zt&2O=Kjrh(_YH$=sXX/mhR&+(\_.?!bRb?ea`/rheQWP==O6&+Y(f?o"?cp-`*pp[,Cc\S.(Of_HY^<S^UV]oVQhc7=$pHQQhl,-+i84qYhV0-X)qq?55YM_(8USrp6C?S!^NJu]&"\_IL63c@9.&21=jl>2`2WF&&i2"P(&Orse#L$'g"m'pmYmjJP2qRY`=,X;"6?`qAlbOoMCFs/At_RhrhSY?D+I1_R=,GD4c6Pu3+T4Oj*f[RPF2&khA/flAs!\@IgqTNOi]G:7O2eFSk=,9q::DYdsRfc\OSN:]R59AL*lE/TRR(]bjacoOS_F>gSnAlfJ,E%5jkA_$8WLJ2-ALI60b?jhoXW5\79B3]-\m+)$YuUX=ODHt7383j\pSeNYDi92I##,(En@nB`+9_i/TWYn9F%b=#W2/sE=2ON8-XCf=ecYb:5S%f=&ue&_],?KK>3AK`YKHs)Vj(uHN>+GnS&\[;l9^98(D&hsCr9CFKN\I;R0-te!+ObB$),*SA/VU[>Tu=^qQ,H_BPTdl(ArJdQ.BKB`@KXP-+)X*h`t[D6&pQY$P6Dh"A0HnG-Ye+&.GlhSeadF,PB^?%HgIQ;^G5ZfK?Xi6'B.7&9,CUAF-CuDsk:9r+S2IRP(I?Qhrl+(TA92>HF"XN#`rU;&78g3?'VVU^1ZO2sQKN'103T]a.SbK[uc,ZXc)>5_O9Z)MMfPS^3H5'/XCbKiDX$0\fJ7f^k*d.)*eVnk?n&=gJFE8HA1M5-lPD0*+2YVH9-TFo#pu?rFFdM!H5K)C#c")YUCJ\YJ#\rG/U/c=U"\Pd4^F27=Hba/Q7X(rb&a*:L*iA$j:gq]qu=,JFVYAYO:$N`amGWXMAFjTV9<!#Fbg6.C=HCDW/TkcA9HToga9"nA/lNmZnsWUaf^hO7/;1;7`%E45*G0YOBmTVaATLu_=:"YNEO_)2fS=gphP`t;sr<!0&!@(<36C)_khJl2;@0#RKq%^0ELJ+n(?Nim_A:6sqtIj19GA&kCk>3U^AeKmo?b)9fqbV#?GP.(MeL(0"GAoF3u):]Xt@1i0*;8JMk,cGXahcW^@+"sP'">HXOnf;&(7"iM(6as=\2RcFJ+uje=R8$6FAp+YK:>NPrUq)EcJeAhBlm_#4!I-K"OeReCI(rSj*:GiK8s)'7LigGm*YKuk99[bUSVZY(No<G"Ic#!0O"I91("q"Ve#CFs4J2I$,8p\)_FCJ!VX'?/Zs8_th=`O\(Y%PJOH^Eho+BOA];KK,jZI0,:L'7T#hlq_<%a&q<?2N1+(?rX33Bsfa40?o8LFK'HLnBL/ZWkH\$<[kKJt.Vgqqo3%&j5#Zm'I>O9WL*HN^c/>=n?CRt5jN>EZJ-c+IZJQ&r]O#Xf7.$+P+Q&2oc]$jl6J`3dj^-Md6+7-u]J'J*muA>-rM?n#a5'$'JR5W&X;pu?no-Lg7QIlbs$+m:/d%.[^?c&Re0E8,u(^3lX<0,LP>SE66kW[8CVXTFSoo'5`?T^^bS`bK8?_*C<2;P"c^9+P.r[e"0_MQq56!_S/,DNDT@Ci8-4U9>Ld,-R_U%MA:ro?B$G+)%$91].(Z\Ki@ma:Pl`)kkdngMm'%lnfdgLX*/dn3.%I:_Rc'ROo#86/]583_S%^fdp@h[X@bV6F%ZB1T%6s_5T&)Vt2I-XB)Buo+o1q&`l@i&ODp:GbU,[F<A6%^c(J%/il)sXigkR+Z_CkoVJ-?_Vk#W8DL`/LK%0tLZWFW7)/Or<Y4(Ogj]#UGY4_(e,A+ijs0?Ud;]''h*%pJ58e7Hbe*>#P=:qKWas4Eq7=C*_jUCQRJr?I]b3J69p<OAqnLYEnBCfJNLnEs8X=r2Y,n!dkn+:h>pDF$fW,?Q!t[5`RL"LbJmGl5JmpOl71%&%qNiDi&upE'?ErPK1N:,&NW<\6Xt-*`(@-ItmKt.N+Ic;B;j[FSHt,^a&Q!K]`r(Z!:U_L%b`hP)X^>QRnX(;790Oq2VNTbh+JVeY/\EAO9FPW*H"ch&eo^p%-[-:%9KZO('AH=/p06q/CqTBh)7FBm\g@id\5&Yu,Cq/k89pNpZNBHJ9FM5P!'G>A"s6P;A&?(/ir4<J/u@@.fet7bAKrgU7[_Q8;;d<:p+pbCRH)nb3>Th0JJFh`gP6*e!Fc+\=HC7$1Eh_I)\F,b2c2N(^HH"R$XE7eI%E,,?qc--&(AR%M650<V)2[_l>Gjt4-A[2rlhCc\U@H)e:quX?3#M-._2eh2USRYfKDd9M;MN?k.u;^kfd*#cYIDF5/PY%>7<CteMIG>Ga>@m9KJYEobh6po>XTm<Ud\%_6YqI:-R\7A`*AC"QR5>;:PMBHhSf1:f&G(FE$-kbFIIhm=*rbc;2[Okg]D2mpjhg*4u;q!74<l'F5;`C\Vla+aCC`!"fjt[5;1rjY.5qh;\;Wo%`iQ/qH7h5"+=&qg?5lXnU<I_ej[1dp"*-G7GubPHqeMqQ.%t]p3soA&@ZVn$6eS@daR0C8U#GUR,fD&!5oO^c8&!=O=VM2*n;kI9/Qc:#riIZ*?gP*8ikD_C&@[%g>5g%X#&'=k*a[pT#jU/jfYMdeuPSh*$>(oD4jH\NC4^(UdQd93;]NM5GCW-#]o/+jZkDaQe2=oL;kO<Jo`3'tX\+!EECPB,PDE<*rGF&8/':QVUsMhb6af'U17n8B!qd"FM!XfKK"`<#*Yuc`WkDF+8"81mcP$0hn##Ej&sb_*1F]IZX=sa/"TW'@CRkV"/1%I]6]V6nFfl6qm9am'ltY1A0Q[-.aJknI7.qr\N/(6&!30L7QWEUF@>cK2Q:/^%neeW`8bC#K!)4md&i;.hT$EJh/*O;U4SMEJW1o6`EG9#U*6[9:"Fh1+udnl\fa,_S>9$'P;^>%W&#Q:EO,LHJ,;(2mHh9:S3i4ii6`GFjjCQgT&tW/6WF2gg#8_ItbbS6"f"\$>-_`Nq934U]&_]=2/Raq9t2&GSW+3s4VmtT.=nDEjtmDCI6So$-.NQHueo_pfWgc=8bJ1B?Bd?RAT#I7Pg`cL(^?$khhH?=_@~> +endstream +endobj +37 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 36 0 R +>> +endobj +38 0 obj +<< /Length 2016 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gatm<?Z4[W&:`$(nCouH<@,hsXM(H)gNC<_/o`TS_]EKJNk*<.-VABb:VW+]-ls*`D21D1r11p@j8J##0/j\#hCN;2*6#8/mNS7Y>pQ`n^1<PR4(8uOUEl=G%^SBk*Mg+&:>5/Lcf`L>kHiWD'mgH+qdlUA4PE!oE?V>Sl+:><l&jABh!CjBf,oL&4PK/4[$.L>VMA33B]L$p[CfGHW>fF@Yr2c%$J>><g\`n^qJ)Q0>CX,7okBpd9An\%Z#,Ccb-JJ_O\G/_4/"-<00K=N+Ws&J;:_\F>HMg*QM(_SUYc'p[Uq%'l\)_5:M4?D7\6jCd_VI:QkW"K8iNlB[S%AHG%hAkCO=?JNB6R-&_u37Uce3ZgoKKbdCG,dYLL6J)[Qc>^_te5C3X-*/U5KbZa)"8MW,:Rd.#!biV(QMclsQ*KuTbJX(WMo8'4\2Mag#QrY9ml#P1rS'tW>NZr`NE%(mH\&H<2R9;63CYIJC!l[+H2b#8eUfpe.!g%A5,<!]q`$_B7H\dfr49u0#=T#7j3ftr9hOG]aK#R@'RZ)oEe4Im,.'=o"r7:S\7Wr:F.*co_"p;<q&VR>4$H:/]jY?.X,buhOqXo!>Xik;SFVOV:O.8aYZ92)CN>`:t#&AjFk:;gIWaU"-U\:Pp;#@pLdF"\BqQ#pCaV<0NSlUJ/>3%;<2lMXH<&Z#mb<0ge$P08)6D51Y'cRt$U^;)=q*->/k`$:'D>s;F&!L].,'K$/N#fMrOWnB+=/4u#`r/:o0N8q];::`((a=b[]`hHm65W%)dS11e[hoDGN$J:7qkmXG#l*>(1graFC$^]O%MANela0#cs.@t*J^0\b2lkqH82Z351KXZAd).`RZ,h-rC'm@8mU<MNg(g5NA>#BPNTpDU<JD7^-p!<ZTW8gea$0Onu;Q6sIK$dZ]BTDCA4CpTXj:>]hgl,B?1.eu#=cO38,kY7hniF5fZk18i]Tr#Q4-N@V`tGDu@.RS$<FF3HU<N9o3,U=E&40GiHVbP-/4VL,),b[\/mR*A5HE+L^]57C?]KIZqPMMGm*6rFe<A(Tk0f2/BY*[15%TWIg7)RKcs&>&UQn(7HJjfGLQ0#6[[uQ3"OWMgmXrDe.W#I@NfBG0q&()@M%4YZTi/trfmMY\iCg?Bld&($F"P,%mrZ=N9JUN>oEs[P?nMM5\HpfmX3T90cri1ha!G7f-23QY\O"7(24NeJ>sqoB_YJa:<FH$q5OV$_nto(qYIpidDOKs)kYH,C^/t5uZ^'#"cp:IWo*(A1/6P/:cu7[@/S]G+E^>14eb5](1l]r]/#5#Bs6J<>`*EI64*rKWl,e\r)2C]],#9=c3naL6B1&r#mQ\aH9!\Ja>r60KMcrG_=u(*/j8rIi+B%UIn+B0$#Gjp1(jd&H\Snk.htB%c#Gq7M>GD>hm(0!]Y6^A7[>s7sPC`:uh,^O/mc%pk:0nH-b'Xe4:UV&fjBK6S5faotoa;T-f2=^HEe<n)gstc:0SB6rS:;3UCNV"A'@K8VIYA_b60Ha-5tMQ`=acdjKfL,'q)K^h*Gjhkd.[)H=d6]jJ!gJR=.7@F#D*30H9e$b-O;W:(O14;A_5a_KNBK?e!&,]6d_kSGtb-[A*0W8h_cHUl4[+DRdNX<bm?,]R[23B<PA^Imlku8OEN\2&kGB&YO8*c>;Dg@l/3RK`#:p[+:i/o#R]?HXb,EEWZF8'=u2#K).LS)U,aIDWhTfa]U.0Fa4lodgRZ`,0J"q%_bLJ!aARk/"hUZcA,@lhb*%\U?qHM%#8%WULl$b?5pY*EK&'ku$i3Nb?JO]L%Xn]J7PB-Obi1>#iZQGVr?H*q'o!!P4SkW?+^Yb;0Vl'mKPo02B6H@J`&&El=I<,JGY=]iK#5er@Bk#=EfDGCZJ;\i1Uq/0F5urUibs3(`WtNm!\,eu0pI`%/SD\R?S>`'#4:OZ3-PiGrF=30g;#$%E8W4ZD,i$7nG$1Db-4t-O-F)VIhirA4g!4K!AX>5:2-4"I@3P4dO=dIrWOC(VP*~> +endstream +endobj +39 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 38 0 R +>> +endobj +40 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F3 +/BaseFont /Helvetica-Bold +/Encoding /WinAnsiEncoding >> +endobj +41 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F5 +/BaseFont /Times-Roman +/Encoding /WinAnsiEncoding >> +endobj +42 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F1 +/BaseFont /Helvetica +/Encoding /WinAnsiEncoding >> +endobj +1 0 obj +<< /Type /Pages +/Count 3 +/Kids [6 0 R 37 0 R 39 0 R ] >> +endobj +2 0 obj +<< /Type /Catalog +/Pages 1 0 R + >> +endobj +3 0 obj +<< +/Font << /F3 40 0 R /F5 41 0 R /F1 42 0 R >> +/ProcSet [ /PDF /ImageC /Text ] >> +endobj +9 0 obj +<< +/S /GoTo +/D [6 0 R /XYZ 115.0 431.019 null] +>> +endobj +11 0 obj +<< +/S /GoTo +/D [6 0 R /XYZ 115.0 397.694 null] +>> +endobj +13 0 obj +<< +/S /GoTo +/D [6 0 R /XYZ 115.0 161.255 null] +>> +endobj +15 0 obj +<< +/S /GoTo +/D [37 0 R /XYZ 115.0 511.0 null] +>> +endobj +17 0 obj +<< +/S /GoTo +/D [37 0 R /XYZ 115.0 325.675 null] +>> +endobj +19 0 obj +<< +/S /GoTo +/D [37 0 R /XYZ 115.0 141.35 null] +>> +endobj +21 0 obj +<< +/S /GoTo +/D [39 0 R /XYZ 115.0 607.0 null] +>> +endobj +23 0 obj +<< +/S /GoTo +/D [39 0 R /XYZ 115.0 508.675 null] +>> +endobj +25 0 obj +<< +/S /GoTo +/D [39 0 R /XYZ 115.0 465.35 null] +>> +endobj +27 0 obj +<< +/S /GoTo +/D [39 0 R /XYZ 115.0 400.025 null] +>> +endobj +29 0 obj +<< +/S /GoTo +/D [39 0 R /XYZ 115.0 356.7 null] +>> +endobj +31 0 obj +<< +/S /GoTo +/D [39 0 R /XYZ 115.0 313.375 null] +>> +endobj +33 0 obj +<< +/S /GoTo +/D [39 0 R /XYZ 115.0 270.05 null] +>> +endobj +35 0 obj +<< +/S /GoTo +/D [39 0 R /XYZ 115.0 226.725 null] +>> +endobj +xref +0 43 +0000000000 65535 f +0000011272 00000 n +0000011344 00000 n +0000011394 00000 n +0000000015 00000 n +0000000071 00000 n +0000002893 00000 n +0000003013 00000 n +0000003129 00000 n +0000011495 00000 n +0000003263 00000 n +0000011560 00000 n +0000003398 00000 n +0000011626 00000 n +0000003533 00000 n +0000011692 00000 n +0000003669 00000 n +0000011757 00000 n +0000003805 00000 n +0000011824 00000 n +0000003941 00000 n +0000011890 00000 n +0000004077 00000 n +0000011955 00000 n +0000004213 00000 n +0000012022 00000 n +0000004348 00000 n +0000012088 00000 n +0000004484 00000 n +0000012155 00000 n +0000004619 00000 n +0000012220 00000 n +0000004755 00000 n +0000012287 00000 n +0000004891 00000 n +0000012353 00000 n +0000005027 00000 n +0000008616 00000 n +0000008724 00000 n +0000010833 00000 n +0000010941 00000 n +0000011054 00000 n +0000011164 00000 n +trailer +<< +/Size 43 +/Root 2 0 R +/Info 4 0 R +>> +startxref +12420 +%%EOF diff --git a/src/libs/resiprocate/resip/stack/doc/using-dialogUsageManager.xml b/src/libs/resiprocate/resip/stack/doc/using-dialogUsageManager.xml new file mode 100644 index 00000000..46dc114f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/using-dialogUsageManager.xml @@ -0,0 +1,223 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" + "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> +<article> + <artheader> + <title>Programmer Guide: Dialog Usage Manager</title> + </artheader> + +<sect1> <title> Concepts </title> + +<sect2> <title> Major Components </title> + +<para> +The DialogUsamgeManger (or DUM) is the unit that keeps track of all the data +sturcutres and sits on top of the transaction layer of the stack. It keeps track +of multiple DialogSet which contains Dialogs. Each DialogSet contains all the +Dialog that were created by a common initial request. They all share the same +SIP Call-Id and from tag from the orginal request. Inside a specific dialogSet +there can be some type of BaseCreator that represnets the intial request that +generated the dialog. This will only exist onthe UAC side. The DialogSet also +contains serveral objects dereived from BaseUsage that are using this particular +dialog. There are several types of things that are a Usage of this dialog. There +can be one InvSession, one Registration, one Publication, multiple Subscriptions +and multiple OutOfDialogRequests. Note the name OutOfDialog is a little weird - +they are actually in a thing a lot like a dialog but are transactions that are +not in one of the other categories. Typically messages that result in +OutOfDialogRequests are MESSAGE and OPTIONS. +</para> + +<para> +An initial SIP Request is created by calling the makeX interfaces on the DUM. It +is then sent using the send interface on the DUM. This will create some internal +data structures and return a DialogSetID that can be used to find all the state +asscociates resulting from this. When a response comes into this, a callback +from one of the Handler classes will be called to notify the application about +incoming events. This will pass up some type of client or server usages class +that can be used to send aditional messages and responses inthe context of this +particularr usage of the Dialog. +</para> + +</sect2> +<sect2> <title> Definitions </title> + +<para> +DialogUsage Manager - Main class that keeps track of all the DialogsSets, +Dialogs, and Usages. +</para> + +<para> +DialogSet - A set of dialogs that were gerneated from a common request. They +share the same call-id and the same from tag in the +request that genreated the dialog. +</para> + +<para> +Dialog - A container holding such things and local and remote CSEQ, URI, +Call-ID and such as defined by the SIP standard. +</para> + +<para> +DialogID - An identifier that uniquely finds a a Dialog by Call-ID, and to and +from tags. +</para> + +<para> +DialogSetID - An identifier that uniquily identifies a Dialog-Set and is formed +from Call-ID and +</para> + +<para> +Usages - These are the objects are are using a dialog. They include +ClientInviteSession, ClientOutOfDialogReq, ClientPublication, +ClientRegistration, ClientSubscription, ServerInviteSession, +ServerOutOfDialogReq, ServerPublication, ServerRegistration, and +ServerSubscription. These have varios operations that can be called on them to +</para> + +<para> +Handlers - These are objects uses to derive class from that allow callbacks from +this layer to the application using ti. They include InviteSessionHandler, +OutOfDialogHandler, RegistrationHandler, SubscribeHandler, and +PublictionHandler. +</para> + +<para> +Handles - All the Usaves and Handlers are not really exposes to the +applications using this layer. Instead, handles to them are passed out. When +the applications goes to use a handle, the unerlying object may have been +delted and the applications must be prepared for this not to work. +</para> + +</sect2> +</sect1> + +<sect1> <title>Handling Invite Sessions - Client</title> + +<para> +Initially a cleint can call makeNewInvite on the DUM and get a SipMessage. It +can take this and modify it such as adding SDP. It then calls sends on the DUM +and sends themessage. This will cause the creation of a DialogSet for the +Dialogs resulting from this request. When a responses (such as a 180) comes back +that cuase the creation of an early dialog, the onEarly callback in the Handler +willbe called. This will pass in a ClientInviteSession to the applications and +the eactual message received. When and offer or answer is recived, the onAnswer +or onOffer callback will be called. In the typical case wher the INVITE sent +and offer and the 180 has SDP but it is not an answer, only the onEarly will be +called. If the 180 was reliable so that it was an aswer, then both the onEarly +and the onAnswer would be called. +</para> + +<para> +If the client which to sent a new answer or offer it must call the setAnswer or +setAnswer object with the new SDP. This saves it but does not send a +messages. the client then calls sendAnyAnswer or sendAnyOffer to cause the +aproperate message to be sent to send a new offer or answer. This might be a +PRACK, an UPDATE, a reINVITE depending on the currenst state of the dialog. +</para> + +</sect1> +<sect1> <title>Handling Invite Sessions - Server</title> +<para> +When the sserver first recives an INVITE, it will call the onNewInvSession +handler and pass a handle to a ServerInviteSession. It the UA is busy this +could be rejected with the reject mehtod. If the INVITE contaned an offer, the +onOffer callback gets called. When this happens, the server needs to call the +setAnser function to set the new offer. This will not send the offer. The +server must then call the sendAnserInAnyMessage to actually send the +offer. This sequence of two calls seem a little weired but is required to make +the all the cases work when doing PRACK stuff. +</para> +<para> +From this pont on thir can be several rounds of sending and receivng offers and +aswers. When the UA which to sendd a 200 and "answer" the call, it calls the +accept method. Finially when it wishes to end the call it calls the end +method. If the other side ends the call, the onTerminated callback will get +called. +</para> + +<para> +INFO messages can be received in the dialog with the onInfo callback. Refer is +a topic all on it's own and covered later in this document. +</para> + +</sect1> +<sect1> <title>Handling Registration - Client</title> +<para> +The client froms a new registration message by calling makeResitration in the +DUM. This returns a SIP messages which is sent by calling send on the DUM. This +will initate the registrtionprocess. +</para> +<para> +If it succeedes or failes, the aproperate onSuccess or onFailure will be +called. The DUM will contintue to run the times and keep this registration +alive. This may result in an onFailure callback at any time. +</para> +<para> +The callback passes back a handle to a ClientRegistration which provies +serveral methods for the client to discover and manipulate the contacts for the +registration. myContacts refers to contatst this UA has registered while +allContacts referes to any contact that has been registered for this AOR. The +add and remove binding calls allow for manipulation of contacts this UA +registered and for cotacts that other UA registered. +</para> + +</sect1> +<sect1> <title>Handling Registrations - Server</title> +<para> +When a new registgration is received the onAdd will be called. The server needs +to either accept this on rejct it using the coresponding function isn the +ServerRegistration class. If the registration is refreshed byt the client +onRefresh will be called and if it expereis before it is refreshed, onExpired +will be called. If the client removes on of the the contacts, onRremoveOne will +be called and if the client removes all the contacts, onRemoveAll be be called. +</para> + +</sect1> +<sect1> <title>Handling Subscriptions - Client</title> +<para> +</para> + +</sect1> +<sect1> <title>Handling Subscritpions - Server </title> +<para> +Gets a onNewSubecritpion callabck when it is created and onRefresh or +OnTerminated as the clients updates it. +</para> + +</sect1> +<sect1> <title>Handling Publictionas - client </title> +<para> +</para> + +</sect1> +<sect1> <title>Handling Publications - Server </title> +<para> +</para> + +</sect1> +<sect1> <title>Dealing with Refer </title> +<para> +</para> + +</sect1> +<sect1> <title>Dealing with Digest authentication </title> +<para> +</para> + +</sect1> +<sect1> <title>Dealing with complex offer/answer </title> + +<para> +When you receive an offer, you need to send an aswer. If you don't like +something about the SIP message with the offer you can totally reject it at the +sip level, but if you don't like the media it proposed, you need to send a +answer with all the m lines you don't like zeroed out. You can then instantly +send a counter offer to propose somethign new. +</para> + +</sect1> + +</article> + + diff --git a/src/libs/resiprocate/resip/stack/doc/using.txt b/src/libs/resiprocate/resip/stack/doc/using.txt new file mode 100644 index 00000000..63c710f9 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/doc/using.txt @@ -0,0 +1,922 @@ +January 26. 2004 + +Using reSIProcate. + +ReSIProcate is an object oriented SIP interface and stack implemented in +C++. The reSIProcate approach emphasizes consistency, type safety, and ease of +use. + +A central component of any SIP service is handling of SIP messages and their +parts. A SIP message consists of headers, request/status line, and body. + +Headers: +======= + +Headers are accessed from messages with the header method. The header method is +overloaded so that its return value is appopriate for each type of header. The +actual header method is determined by the header type token passed to the +overloaded header method. + +Each header type defined in RFC3261 has a corresponding header access token. For +example, the header access tokens for To and From headers are h_To and +h_From. The rule for determing the header access token from a header as named in +RFC3261 is to remove all dashes from the header name and prefix the result with +"h_". For example, "Content-Disposition" becomes h_ContentDisposition. + +Given a existing message, fetching the To header is simply: +<code> +const NameAddr& to = message->header(h_To); +</code> + +The header methods are both accessors and setters. Accessing a header that isn't +in the message creates the header in a default state. So to set an empty message's +To header: + +<code> +SipMessage message; +// displayName and uri are accessor/setter methods on NameAddr, the storage class +// for To headers. +message.header(h_To).displayName() = "Speedy Shannon"; +message.header(h_To).uri() = Uri("speedy@home.com"); +</code> + +The header methods are used also to access existing headers. If you want to make +sure that you are accessing an existing header and are not creating a default +header, use the exists method. The exists method is overloaded with the same +access tokens. + +<code> +SipMessage* message; +if (!message->exists(h_To)) +{ + // complain bitterly + ... +} +else +{ + NameAddr& to = message->header(h_To); + ... +} +</code> + +However, if the message variable is declared const, the header methods will not +create a default instance of a missing header, but will throw +SipMessage::Exception. This is a typical mode when working with incoming +messages. + +<code> +try +{ + const SipMessage* message; + To::Type& to = message->header(h_To); + ... +} +catch (SipMessage::Exception e) +{ + // complain bitterly + ... +} +</code> + +The remove method is also overloaded for the access tokens. Removing a header +that does not exist is a no-op. + +<code> +SipMessage* message = ...; +message->remove(h_RecordRoutes); +</code> + +Each header type is either a single instance or multiple instance. For example, +the header type To is single instance while the header type Record-Route is +multiple instance. The return types differ accordingly. + +Multiple instance headers are accessed through a collection of the +appropriate header type. As a programming hint, access tokens for +multiple headers are pluralized. + +Similarly, the collection of each header type is named the pluralized +header type. Below is an example accessing a collection of NameAddr +instances. + +<code> +NameAddrs& rr = message.header(h_RecordRoutes); +</code> + +The collection of header values can be iterated in the usual stl like fashion. + +<code> +for (NameAddrs::iterator i = rr.begin(); i != rr.end(); ++i) +{ + NameAddr& r = *i; + ... +} +</code> + +All collections of header values support begin, end, empty, size, front, back, +push_back, push_front, reverse, and clear. Each collection is specific to the +header type so no casting is necessary. + +<code> +NameAddr na; +na.displayName() = "Alice"; +na.uri() = Uri("sip:alice@company.com"); +rr.push_back(na); +</code> + +-- + +The request/status lines are special cases of headers. They are +accessed by the header method with the header type tokens +h_RequestLine and h_StatusLine. A message may have one or the other of +these headers but never both. To determine if a message has a Request +Line, use: + +<code> +if (message->isRequest()) +{ + ... +} +</code> + +Similarly for Status Line: + +<code> +if (message->isResponse()) +{ + ... +} +</code> + +Note that a newly created message has neither a request or status line. The +application must add one or the other for the message to be well formed. + +Body: +==== + +A message body is accessed with the getContents method. The retured +value is of type Contents*, an abstract type. The return value must be +cast (dynamic_cast is recommended for runtime type safety) to be +used. The content type of a message can be determined by examining the +Content-Type header of the message. + +New message contents are created by instantiating an instance of a +type derived from Contents. For example, SdpContents. A variety of +content types are currently supported, including mulitpart, signed, +and Pkcs7. New content types can be created either inside or outside +of the reSIP library (see Creating a New Contents Type). + +Setting the contents of a message takes care of setting the Content-Type and +Content-Length of the message. + +<code> +Pkcs7* pres = new Pkcs7(); +... +message->setContents(pres); +</code> + +Recursive multipart contents are supported. + +-- + +Every RFC 3261 header has a corresponding access token. However, many +of the headers have identical form. For example. The To and From +header values both consist of a display name and a URI. The To and +From headers are managed programmatically as NameAddr instances. The +class that manages each header type is responsible for parsing header +text, providing storage and access during the life of the message, and +serializing the header value to text for transmission. + +The table below shows the reSIP types for each of the built in RFC +headers currently supported by reSIP. The reSIP type is the return +type of a SipMessage header call with the access token as its +argument. + +Table of headers +================ +RFC name reSIP access token reSIP type +---------------------------------------------------------------- +Accept h_Accepts Mimes +Accept-Encoding h_AcceptEncodings Tokens +Accept-Language h_AcceptLanguages Tokens +Alert-Info h_AlertInfos GenericUris +Allow h_Allows Tokens +Authentication-Info h_AuthenticationInfos Auths +Authorization h_Authorizations Auths +Call-ID h_CallID, h_CallId CallID, CallId +Call-Info h_CallInfos GenericUris +Contact h_Contacts NameAddrs +Content-Disposition h_ContentDisposition Token +Content-Encoding h_ContentEncoding Token +Content-Language h_ContentLanguages Tokens +Content-Length h_ContentLength UInt32Category +Content-Type h_ContentType Mime +Content-Transfer-Encoding h_ContentTransferEncoding StringCategory +CSeq h_CSeq CSeqCategory +Date h_Date DateCategory +Error-Info h_ErrorInfos GenericUris +Expires h_Expires UInt32Category +From h_From NameAddr +In-ReplyTo h_InReplyTo CallID, CallId +Max-Forwards h_MaxForwards UInt32Category +MIME-Version h_MIMEVersion Tokens +Min-Expires h_MinExpires UInt32Category +Organization h_Organization StringCategory +Priority h_Priority Token +Proxy-Authenticate h_ProxyAuthenticates Auths +Proxy-Authorization h_ProxyAuthorizations Auths +Proxy-Require h_ProxyRequires Tokens +Record-Route h_RecordRoutes NameAddrs +Reply-To h_ReplyTo NameAddr +Require h_Requires Tokens +Retry-After h_RetryAfter UInt32Category +Route h_Routes NameAddrs +Server h_Server StringCategory +Subject h_Subject StringCategory +Supported h_Supporteds Tokens +Timestamp h_Timestamp StringCategory +To h_To NameAddr +Unsupported h_Unsupporteds Tokens +User-Agent h_UserAgent StringCategory +Via h_Vias Vias +Warning h_Warnings WarningCategories +WWW-Authenticate h_WWWAuthenticates Auths + +(!dlb!: const headers accessors return non-const references -- should have const +and non-const versions of all settable accessors) + +The following table lists each of the reSIP types for managing headers. A +complete list of accessors is included for each type. Recall that many headers +are multi-valued; the return type in the multi-valued cases must be iterated to +get to the types shown. Multi-values headers are identified with (*). + +Table of reSIP header types +========================== + +RequestLine +=========== + RFC name: + Request-Line + Description: + The first line of a request message. Does not correspond to a header proper + but is accessed with the header interface in reSIP. + Example: + INVITE sip:bob@biloxi.com SIP/2.0 + Parts: + RFC Name accessor reSIP type settable + -------------------------------------------------------------- + Request-URI uri() Uri yes + Method getMethod() MethodTypes yes + Method unknownMethodName() Data yes + SIP-Version getSipVersion() Data no + + RFC Headers: + <none> + +StatusLine +========== + RFC name: + Status-Line + Description: + The first line of a response message. Does not correspond to a header proper + but is accessed with the header interface in reSIP. + Example: + SIP/2.0 200 OK + Parts: + RFC Name accessor reSIP type settable + -------------------------------------------------------------- + Status-Code responseCode() int yes // dlb should be statusCode() + SIP-Version getSipVersion() Data no + Reason-Phrase reason() Data yes + + RFC Headers: + <none> + +Auth +==== + RFC name: + challenge + Description: + Identifies the authentication scheme in a challenge response. + Example: + Digest-Authenticate: username="Alice", realm="atlanta.com", + nonce="84a4cc6f3082121f32b42a2187831a9e", + response="7587245234b3434cc3412213e5f113a5432" + Parts: + RFC Name accessor reSIP type settable + ---------------------------------------------------------- + auth-scheme scheme() Data yes + RFC Headers: + Authentication-Info + Authorization (*) + Proxy-Authenticate (*) + Proxy-Authorization (*) + WWW-Authenticate (*) + +CSeqCategory +============ + RFC name: + CSeq + Description: + Places the message in sequence in the call. + Example: + CSeq: 314159 INVITE + Parts: + RFC Name accessor reSIP type settable + -------------------------------------------------------------- + sequence() int yes + Method method() MethodTypes yes + unknownMethodName() Data no + RFC Headers: + CSeq + +CallID +====== + RFC name: + Call-ID + Description: + Uniquely identifies the call. + Example: + Call-ID: a84b4c76e66710@pc33.atlanta.com + Parts: + RFC Name accessor reSIP type settable + ---------------------------------------------------------- + value() Data yes + RFC Headers: + Call-ID + +DateCategory +============ + RFC name: + SIP-date + Description: + Human readable date string. + Example: + Date: Sat, 13 Nov 2010 23:29:00 GMT + Parts: + RFC Name accessor reSIP type settable + ---------------------------------------------------------- + wkday dayOfWeek() DayOfWeek yes + date1 + dayOfMonth int yes + month() int yes + year() int yes + time + hour() int yes + minute() int yes + second() int yes + RFC Headers: + Date + +GenericUri +========== + RFC name: + absoluteURI + Description: + Non-structured human readable URI. + Example: + Alert-Info: <http://www.example.com/sounds/moo.wav> + Parts: + RFC Name accessor reSIP type settable + ---------------------------------------------------------- + uri() Data yes + RFC Headers: + Alert-Info + Call-Info + Error-Info + +UInt32Category +=============== + RFC name: + 1*DIGIT + Description: + An integer. + Example: + Max-Forwards: 70 + Parts: + RFC Name accessor reSIP type settable + ---------------------------------------------------------- + value() int yes + comment comment() Data yes + RFC Headers: + Content-Length // note: does not permit (comment) + Max-Forwards // note: does not permit (comment) + Min-Expires // note: does not permit (comment) + Retry-After + +ExpiresCategory +=============== + RFC name: + + Description: + Seconds to expiration. + Example: + Expires: 5 + Parts: + RFC Name accessor reSIP type settable + ---------------------------------------------------------- + value() int yes + RFC Headers: + Expires + +Mime +============ + RFC name: + media-type + Description: + Mime type and sub-type. + Example: + Content-Type: application/sdp + Parts: + RFC Name accessor reSIP type settable + ---------------------------------------------------------- + m-type type() Data yes + m-subtype subType() Data yes + RFC Headers: + Accept (*) + Content-Type + +NameAddr +============ + RFC name: + name-addr + Description: + URI and display name. + Example: + To: Bob <sip:bob@biloxi.com> + Parts: + RFC Name accessor reSIP type settable + ---------------------------------------------------------- + display-name displayName() Data yes + addr-spec uri() Uri yes + RFC Headers: + Contact (*) + From + Record-Route (*) + Refer-To + Referred-By + Reply-To + Route (*) + To + +StringCategory +============== + RFC name: + TEXT-UTF8-TRIM + Description: + Unstructured human readable text. + Example: + Organization: Boxes by Bob + Parts: + RFC Name accessor reSIP type settable + ---------------------------------------------------------- + value() Data yes + RFC Headers: + Content-Transfer-Encoding + Organization + Server + Subject + User-Agent + Timestamp + extension-header (*) + +Token +===== + RFC name: + token + Description: + A word. + Example: + Accept-Encoding: gzip + Parts: + RFC Name accessor reSIP type settable + ---------------------------------------------------------- + value() Data yes + RFC Headers: + Accept-Encoding (*) + Accept-Language (*) + Allow (*) + Allow-Events (*) + Content-Disposition + Content-Encoding + Content-Language (*) + Event + Mime-Version + Priority + Proxy-Require (*) + Require (*) + Security-Client (*) + Security-Server (*) + Security-Verify (*) + Subscription-State (*) + Supported (*) + Unsupported (*) + +Via +============ + RFC name: + via-parm + Description: + Via entry. + Example: + Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds + Parts: + RFC Name accessor reSIP type settable + ------------------------------------------------------------ + protocol-name protocolName() Data yes + protocol-version protocolVersion() Data yes + transport transport() Data yes + host sentHost() Data yes + port sentPort() int yes + RFC RFC Headers: + Via (*) + +WarningCategory +============ + RFC name: + warning-value + Description: + + Example: + + Parts: + RFC Name accessor reSIP type settable + -------------------------------------------------------- + warn-code code() int yes + warn-agent hostname() Data yes + warn-text text() Data yes + RFC Headers: + Warning (*) + +According to the grammar, each header has a set of acceptable parameters. Some +headers accept no parameters. reSIP makes a simplifying assumption; all headers +can have all parameters. While it is the goal of reSIP that every legal SIP +message be parseable, reSIP does not strictly enforce production of legal +SIP. In practice, correct usage will result in legal SIP, but it is not very +difficult to use reSIP to produce a problematic message. Take home lesson -- the +reSIP programmer must take responsibilty when adding parameters to a header. + +A corollary to this simplifying assumption is that the form of a parameter is +independent of the header it appears in. A ttl parameter must always be followed +by an integer even when used in a header that does not specify the syntax for +a ttl parameter. (!dlb! potential compatibility issue) + +Parameters, like headers, corresponds to a small set of classes that manage +parsing, accesing, and serializing to text. + +(!dlb!: QuotedDataParameter should be super of DataParameter -- currently +allow setting quoted on QuotedDataParameter) + +Table of Parameters +=================== +RFC name reSIP access token reSIP type +----------------------------------------------------------- + access-type p_accessType DataParameter + algorithm p_algorithm DataParameter + boundary p_boundary DataParameter + branch p_branch BranchParameter + charset p_charset DataParameter + cnonce p_cnonce QuotedDataParameter + comp p_comp DataParameter + d-alg p_dAlg DataParameter + d-qop p_dQop DataParameter + d-ver p_dVer QuotedDataParameter + directory p_directory DataParameter + domain p_domain QuotedDataParameter + duration p_duration IntegerParameter + expiration p_expiration IntegerParameter + expires p_expires IntegerParameter + filename p_filename DataParameter + from-tag p_fromTag DataParameter + handling p_handling DataParameter + id p_id DataParameter + lr p_lr ExistsParameter + maddr p_maddr DataParameter + method p_method DataParameter + micalg p_micalg DataParameter + mobility p_mobility DataParameter + mode p_mode DataParameter + name p_name DataParameter + nc p_nc DataParameter + nonce p_nonce QuotedDataParameter + opaque p_opaque QuotedDataParameter + permission p_permission DataParameter + protocol p_protocol DataParameter // should be QuotedDataParameter? + purpose p_purpose DataParameter + q p_q FloatParameter + realm p_realm QuotedDataParameter + reason p_reason DataParameter + received p_received DataParameter + response p_response QuotedDataParameter + retry-after p_retryAfter IntegerParameter + rport p_rport RportParameter + server p_server DataParameter + site p_site DataParameter + size p_size DataParameter + smime-type p_smimeType DataParameter + stale p_stale DataParameter + tag p_tag DataParameter + to-tag p_toTag DataParameter + transport p_transport DataParameter + ttl p_ttl IntegerParameter + uri p_uri QuotedDataParameter + user p_user DataParameter + username p_username DataParameter // should be QuotedDataParameter? + +Table of reSIP Parameter Types +============================== + +BranchParameter +=============== + RFC name: + + Description: + May have RFC 3261 marker, may have reSIP specific data, may have client + data. + Example: + Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds + Parts: + accessor reSIP type settable + ---------------------------------------------------- + hasMagicCookie() bool no + getTransactionId() Data no + incrementTransportSequence void no + reset(const Data&) void yes + clientData() Data yes + RCF Parameters: + branch + +DataParameter +============= + RFC name: + token + Description: + Quoted or unquoted. Unquoted must be single word. + Example: + Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds + Parts: + accessor reSIP type settable + ------------------------------------------------ + value() Data yes + isQuoted() bool no + setQuoted(bool) void yes + RFC parameters: + ?access-type + algorithm + boundary + charset + ?comp + d-alg + d-qop + directory + filename + from-tag + handling + ?id + maddr + ?method + micalg + ?mobility + ?mode + name + nc + ?permission + purpose + ?reason + received + ?server + ?site + ?size + smime-type + stale + tag + to-tag + transport + user + +ExistsParameter +=============== + RFC name: + + Description: + Has no value; is not followed by "=". + Example: + Record-Route: <sip:p1.example.com;lr> + Parts: + accessor reSIP type settable + ------------------------------------------------ + value() bool yes + RFC parameters: + lr + +FloatParameter +============== + RFC name: + qvalue + Description: + 0-1 inclusive, up to three digits after decimal point. + Example: + Accept-Language: da, en-gb;q=0.8, en;q=0.7 + Parts: + accessor reSIP type settable + ------------------------------------------------ + value() float yes + RFC parameters: + q + +IntegerParameter +================ + RFC name: + + Description: + Integer + Example: + sip:alice@atlanta.com;maddr=239.255.255.1;ttl=15 + Parts: + accessor reSIP type settable + ------------------------------------------------ + value() int yes + RFC parameters: + duration + expiration + expires + retry-after + ttl + +QuotedDataParameter +=================== + RFC name: + quoted-string + Description: + Quoted text. + Example: + Authorization: Digest username="bob", + realm="biloxi.com", + nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", + uri="sip:bob@biloxi.com", + qop=auth, + nc=00000001, + cnonce="0a4f113b", + response="6629fae49393a05397450978507c4ef1", + opaque="5ccc069c403ebaf9f0171e9517f40e41" + Parts: + accessor reSIP type settable + ------------------------------------------------ + value() Data yes + RFC Parameters: + cnonce + d-ver + domain + nonce + opaque + realm + response + uri + +RportParameter +============== + RFC name: + quoted-string + Description: + May have a value or not. + Example: + Via: SIP/2.0/UDP whistler.gloo.net:6064;rport=6064;received=192.168.2.220;branch=z9hG4bK-kcD23-4-1 + Parts: + accessor reSIP type settable + -------------------------------------------- + port() int yes + hasValue() bool no + RFC Parameters: + rport + +MethodTypes +========== +ACK +BYE +CANCEL +INFO +INVITE +MESSAGE +NOTIFY +OPTIONS +PRACK +PUBLISH +REFER +REGISTER +SUBSCRIBE +UPDATE ?? not in build? + +Uri +=== + RFC name: + addr-spec + Description: + URI + Example: + sip:alice:secretword@atlanta.com;transport=tcp + Parts: + RFC Name accessor reSIP type settable + ------------------------------------------------------------ + header embedded() SipMessage yes + userinfo+hostport getAor() Data no + userinfo+host getAorNoPort() Data no + hasEmbedded() bool no + host host() Data yes + host opaque() Data yes + password password() Data yes + port port() int yes + userinfo user() Data yes // note: does not include user parameters + userParameters() Data yes + scheme() Data yes + +Contents +======== + RFC name: + message-body + Description: + Base class for all content types. Each derived content type defines its own + parse, accessors and stream rendering. + Example: + + --boundary42 + Content-Type: message/sip + + INVITE sip:bob@biloxi.com SIP/2.0 + Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8 + To: Bob <bob@biloxi.com> + From: Alice <alice@atlanta.com>;tag=1928301774 + Call-ID: a84b4c76e66710 + CSeq: 314159 INVITE + Max-Forwards: 70 + Date: Thu, 21 Feb 2002 13:02:03 GMT + Contact: <sip:alice@pc33.atlanta.com> + Content-Type: application/sdp + Content-Length: 147 + + v=0 + o=UserA 2890844526 2890844526 IN IP4 here.com + s=Session SDP + c=IN IP4 pc33.atlanta.com + t=0 0 + m=audio 49172 RTP/AVP 0 + a=rtpmap:0 PCMU/8000 + + --boundary42 + Content-Type: application/pkcs7-signature; name=smime.p7s + Content-Transfer-Encoding: base64 + Content-Disposition: attachment; filename=smime.p7s; + handling=required + + ghyHhHUujhJhjH77n8HHGTrfvbnj756tbB9HG4VQpfyF467GhIGfHfYT6 + 4VQpfyF467GhIGfHfYT6jH77n8HHGghyHhHUujhJh756tbB9HGTrfvbnj + n8HHGTrfvhJhjH776tbB9HG4VQbnj7567GhIGfHfYT6ghyHhHUujpfyF4 + 7GhIGfHfYT64VQbnj756 + + --boundary42- + Parts: + accessor reSIP type settable notes + ---------------------------------------------------------- + exists bool no + remove void no + header <various> yes + // shared header types + H_ContentType::Type& header(const H_ContentType& headerType) const; + H_ContentDisposition::Type& header(const H_ContentDisposition& headerType) const; + H_ContentTransferEncoding::Type& header(const H_ContentTransferEncoding& headerType) const; + H_ContentLanguages::Type& header(const H_ContentLanguages& headerType) const; + + // MIME specific header types + H_ContentID::Type& header(const H_ContentID& headerType) const; + H_ContentDescription::Type& header(const H_ContentDescription& headerType) const; + + int& verion() {return mVersion;} + int& minorVersion() {return mMinorVersion;} + + +MultipartRelatedContents +MultipartMixedContents +MultipartSigned +SdpContents +Pkcs7Contents +OctetContents + +SipMessage + non-header parts + examples + +-- +Adding a new content type at application compile time. + +-- + +Extension headers. + +SIP is an open specification. Elements may add headers that are not generally known. + Multiple. Must appear on separate lines. May have parameters. However, not all +stacks will consider semi-colons in extension headers significant, so could +cause interop problems. + +-- + +Extension parameters. + May or may not have a value. Are permitted in any header. + diff --git a/src/libs/resiprocate/resip/stack/gperfNotes.txt b/src/libs/resiprocate/resip/stack/gperfNotes.txt new file mode 100644 index 00000000..9565ef96 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/gperfNotes.txt @@ -0,0 +1,20 @@ +// -k '*' forces gperf to choose a hash for each size category instead of giving up. +// required if characters appear in the same position in several keywords +// -D forces gperf to cough up a non-perfect hash when it can't produce a perfect hash +// required if several keywords are anagrams +// +// gnu +// | class name +// | | constants +// | | | language +// | | | | custom struct +// | | | | | all characters +// | | | | | | deal with anagrams +// | | | | | | | +% gperf -g -Z ParamHash -E -L C++ -t -k '*' -D parametersA.gperf + +// replace-regexp +str\[\([0-9]+\)\] => tolower(str[\1]) +\*str == \*s => tolower(\*str) == \*s +//replace-not-regexp +!strcmp (str + 1, s + 1) => !strncasecmp (str + 1, s + 1, len-1) diff --git a/src/libs/resiprocate/resip/stack/gperf_w32.bat b/src/libs/resiprocate/resip/stack/gperf_w32.bat new file mode 100644 index 00000000..0aebd727 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/gperf_w32.bat @@ -0,0 +1,14 @@ +@echo off +echo WARNING - use of this batch file is only recommended for advanced users. +echo It is used to automate the first step required in creating the +echo GPERF HASH files for resiprocate on windows. +echo. +echo Note - Ensure gperf.exe is present in the path or resip/stack directory +echo before continuing +echo. +pause +gperf -C -D -E -L C++ -t -k "*" --compare-strncmp -Z MethodHash MethodHash.gperf > MethodHash.cxx +gperf -C -D -E -L C++ -t -k "*" --compare-strncmp --ignore-case -Z HeaderHash HeaderHash.gperf > HeaderHash.cxx +gperf -C -D -E -L C++ -t -k "*" --compare-strncmp --ignore-case -Z ParameterHash ParameterHash.gperf > ParameterHash.cxx +echo MethodHash.cxx, HeaderHash.cxx and ParameterHash.cxx have been created using gperf. +pause diff --git a/src/libs/resiprocate/resip/stack/groups.doc b/src/libs/resiprocate/resip/stack/groups.doc new file mode 100644 index 00000000..7b9c5eee --- /dev/null +++ b/src/libs/resiprocate/resip/stack/groups.doc @@ -0,0 +1,4 @@ +/** @defgroup resip_crit Critically Important Classes */ +/** @defgroup sip_grammar SIP Grammar Elements */ +/** @defgroup sip_parse SIP Parsing Infrastructure */ +/** @defgroup make_sip SIP Message Generation Functions */ diff --git a/src/libs/resiprocate/resip/stack/mainpage.doc b/src/libs/resiprocate/resip/stack/mainpage.doc new file mode 100644 index 00000000..2afa101e --- /dev/null +++ b/src/libs/resiprocate/resip/stack/mainpage.doc @@ -0,0 +1,114 @@ +/** + @mainpage The reSIProcate SIP Stack library (resip) + + @section resip_quick_start Quick Start + + @subsection resip_fundamentals Resip's Fundamental Design + The resip stack plays the role of the UAC/UAS core, and the app plays the + role of the @ref resip::TransactionUser "Transaction User" (or TU), both + as described in RFC 3261. For the unfamiliar, the TU sends and receives + @ref resip::SipMessage "SIP messages" from the core, + while the core handles details like retransmissions, timeouts, and + interactions with the transport layer. The UAS/UAC core will also inform + the TU when transactions end. + + @subsection resip_responsibilities Resip's Other Responsibilities + In addition to satisfying the duties of the UAS/UAC core, resip provides + additional functionality, such as: + + - @ref sip_parse "SIP message parsing" : Resip supplies parse-code for all + the core @ref sip_grammar "SIP grammar elements" (this parse code + is fairly liberal, and does not do deep validation). + - @ref make_sip "SIP message construction" : Resip supplies code for + constructing SIP messages according to the rules in RFC 3261. + - RFC 3263 DNS logic : The resip stack carries out all RFC 3263 DNS lookup + logic for you. This is actually a non-trivial task, if you haven't read + 3263. + - Other RFC support : Wherever possible, resip provides code that + implements all MUST and SHOULD-level requirements from supported RFCs + (a lot of this code lives in resip::Helper). + + @subsection resip_big_picture The Big Picture + The basic anatomy of a SIP application running on top of the resip stack + is as follows. You have: + - One or more subclasses of resip::TransactionUser (the "app layer") + - A single instance of resip::SipStack + - One or more subclasses of resip::Transport. + + These are all connected together through a combination of message-passing, + and direct function calls(usually reserved for stuff like configuration). + + @subsection resip_usage Usage + - Subclass resip::TransactionUser : The part of resip::TransactionUser + that is left up to the app-writer is the code that reads messages out of + the resip::TransactionUser's message-queue, and processes these messages. + What the resip::TransactionUser does with these messages is very + open-ended, but the stack expects that every request will get a final + response. + - Initialize the logging system : See resip::Log::initialize() (in rutil) + for details. + - Create a resip::SipStack : This part is pretty simple. + - Add some transports to the stack : Use resip::SipStack::addTransport() + to do this. + - Register your resip::TransactionUser : This is done with + resip::SipStack::registerTransactionUser(). + - Set up a process loop for resip::SipStack : Typically this is done by + creating a resip::StackThread, and running it (this will give SipStack a + thread of its own). If you want to run your app and the SipStack in the + same thread, use the code in StackThread as an example, and have it also + do processing for your TransactionUser. + + @subsection resip_low_detail The Internals + The resip stack can be broken down into the following large components: + - resip::SipStack : This is the part that the resip::TransactionUser + (app-layer) talks to. It also is responsible for coordinating the rest + of the major components in its process loop. + - resip::TransactionController : This is the part that manages all + the transaction-state for the stack. + - resip::ExternalDns : This is the DNS resolver. By default, this is a + resip::AresDns, but the app-writer can override (not a very fun thing + to do, really). + - resip::TransportSelector : This is the part that handles the preparatory + work for sending a SIP message out on the wire. This includes choosing + a transport to send on, filling in parts of the SIP message that can + only be filled in when we know what transport we're sending on, and + writing the SIP message into a buffer for the transport layer. + - resip::Transport : This is the base transport-layer class. Concrete + implementations of this include resip::UdpTransport, + resip::TcpTransport, and resip::TlsTransport. There may be any number + of these. + - resip::TuSelector : This is the part that determines which TU (there + may be several) a received SIP message should be sent to. It also + decides how to route other message-passing from the stack (see + TransactionTerminated and ConnectionTerminated) + + Here's a description of the typical flow: + - resip::SipStack's main process loop runs, eventually causing one of + the resip::Transport objects to read some bits off their fd. These bits + are run through a pre-parse (tokenizes the message into header field + values), and a basic validation (checks to see whether mandatory + headers are present, and performs well-formedness checks on a very + small number of headers). The resip::SipMessage is then posted to the + resip::TransactionController's message queue. + - resip::TransactionController gets the resip::SipMessage, and creates + a resip::TransactionState for it (supposing it is a new transaction). + The transaction-state logic is carried out, until a determination is + made on whether to send it to the resip::TransactionUser (app-layer). + - The resip::SipMessage is passed to the resip::TuSelector, which + posts it to the appropriate resip::TransactionUser, using a + chain-of-responsibility type pattern. + - The resip::TransactionUser gets the resip::SipMessage, and does any + processing it needs to. If the message was a request, the app-layer + will post a response to the resip::SipStack, which will place the + message in the resip::TransactionController's message queue. + - resip::TransactionController will get the resip::SipMessage, perform + any core transaction-state processing, and figure out where the message + needs to go (back to the source; although if this were a request, it + would consult the resip::ExternalDns using an async call). Once a + target has been chosen, the resip::SipMessage is passed on to the + resip::TransportSelector. + - resip::TransportSelector chooses what transport to send the message + on, fills out some stuff in the resip::SipMessage, encodes it to a + buffer, and posts it to the chosen resip::Transport. + - resip::Transport throws the bits out on the wire. +*/ \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/makeCert.cxx b/src/libs/resiprocate/resip/stack/makeCert.cxx new file mode 100644 index 00000000..9b685571 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/makeCert.cxx @@ -0,0 +1,177 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#if defined(USE_SSL) +#include <openssl/ssl.h> +#include <openssl/pem.h> +#include <openssl/ossl_typ.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include "resip/stack/X509Contents.hxx" +#include "resip/stack/Pkcs8Contents.hxx" +#include "resip/stack/MultipartMixedContents.hxx" +#include "resip/stack/Uri.hxx" +#include "rutil/Random.hxx" + +using namespace resip; + +int makeSelfCert(X509** selfcert, EVP_PKEY* privkey); + +int main() +{ + int err; + Uri aor; + Data passphrase; + RSA *rsa = NULL; + EVP_PKEY *privkey = NULL; + X509 *selfcert = NULL; + BUF_MEM *bptr = NULL; + + // initilization: are these needed? +// CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); +// bio_err=BIO_new_fp(stderr, BIO_NOCLOSE); + + Random::initialize(); + + rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL); + assert(rsa); // couldn't make key pair + + EVP_PKEY_assign_RSA(privkey, rsa); + assert(privkey); + + selfcert = X509_new(); + err = makeSelfCert(&selfcert, privkey); + assert(!err); // couldn't make cert + + unsigned char* buffer = NULL; + int len = i2d_X509(selfcert, &buffer); // if buffer is NULL, openssl + // assigns memory for buffer + assert(buffer); + Data derData((char *) buffer, len); + X509Contents *certpart = new X509Contents( derData ); + assert(certpart); + + // make an in-memory BIO [ see BIO_s_mem(3) ] + BIO *mbio = BIO_new(BIO_s_mem()); + + // encrypt the the private key with the passphrase and put it in the BIO in DER format + i2d_PKCS8PrivateKey_bio( mbio, privkey, EVP_des_ede3_cbc(), + (char *) passphrase.data(), + passphrase.size(), NULL, NULL); + + // dump the BIO into a Contents + BIO_get_mem_ptr(mbio, &bptr); + Pkcs8Contents *keypart = new Pkcs8Contents(Data(bptr->data, bptr->length)); + assert(keypart); + BIO_free(mbio); + + MultipartMixedContents *certsbody = new MultipartMixedContents; + certsbody->parts().push_back(certpart); + certsbody->parts().push_back(keypart); + assert(certsbody); +} + + +int makeSelfCert(X509 **cert, EVP_PKEY *privkey) // should include a Uri type at the end of the function call +{ + int serial; + assert(sizeof(int)==4); + const long duration = 60*60*24*30; // make cert valid for 30 days + X509* selfcert = NULL; + X509_NAME *subject = NULL; + X509_EXTENSION *ext = NULL; + + Data domain("example.org"); + Data userAtDomain("user@example.org"); + + // Setup the subjectAltName structure here with sip:, im:, and pres: URIs + // TODO: + + selfcert = *cert; + + X509_set_version(selfcert, 2L); // set version to X509v3 (starts from 0) + + // RAND_bytes((char *) serial , 4); + //serial = 1; + serial = Random::getRandom(); // get an int worth of randomness + ASN1_INTEGER_set(X509_get_serialNumber(selfcert),serial); + + X509_NAME_add_entry_by_txt( subject, "O", MBSTRING_UTF8, (unsigned char *) domain.data(), domain.size(), -1, 0); + X509_NAME_add_entry_by_txt( subject, "CN", MBSTRING_UTF8, (unsigned char *) userAtDomain.data(), userAtDomain.size(), -1, 0); + + X509_set_issuer_name(selfcert, subject); + X509_set_subject_name(selfcert, subject); + + X509_gmtime_adj(X509_get_notBefore(selfcert),0); + X509_gmtime_adj(X509_get_notAfter(selfcert), duration); + + X509_set_pubkey(selfcert, privkey); + + // need to fiddle with this to make this work with lists of IA5 URIs and UTF8 + //ext = X509V3_EXT_conf_nid( NULL , NULL , NID_subject_alt_name, subjectAltNameStr.cstr() ); + //X509_add_ext( selfcert, ext, -1); + //X509_EXTENSION_free(ext); + + ext = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints, "CA:FALSE"); + X509_add_ext( selfcert, ext, -1); + X509_EXTENSION_free(ext); + + // add extensions NID_subject_key_identifier and NID_authority_key_identifier + + X509_sign(selfcert, privkey, EVP_sha1()); + + return true; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/month.gperf b/src/libs/resiprocate/resip/stack/month.gperf new file mode 100644 index 00000000..333f071c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/month.gperf @@ -0,0 +1,14 @@ +struct months { const char *name; Month type; }; +%% +Jan, Month::Jan +Feb, Month::Feb +Mar, Month::Mar +Apr, Month::Apr +May, Month::May +Jun, Month::Jun +Jul, Month::Jul +Aug, Month::Aug +Sep, Month::Sep +Oct, Month::Oct +Nov, Month::Nov +Dec, Month::Dec diff --git a/src/libs/resiprocate/resip/stack/parametersA.gperf b/src/libs/resiprocate/resip/stack/parametersA.gperf new file mode 100644 index 00000000..58622746 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/parametersA.gperf @@ -0,0 +1,51 @@ +%{ +#ifndef ParamHash_hxx +#define ParamHash_hxx + +#include "resip/stack/ParameterTypeEnums.hxx" +#include <string.h> + +namespace Vocal2 { + +%} +struct params { const char *name; ParameterTypes::Type type; }; +%% +transport, ParameterTypes::transport +user, ParameterTypes::user +method, ParameterTypes::method +ttl, ParameterTypes::ttl +maddr, ParameterTypes::maddr +lr, ParameterTypes::lr +q, ParameterTypes::q +purpose, ParameterTypes::purpose +expires, ParameterTypes::expires +handling, ParameterTypes::handling +tag, ParameterTypes::tag +to-tag, ParameterTypes::toTag +from-tag, ParameterTypes::fromTag +duration, ParameterTypes::duration +branch, ParameterTypes::branch +received, ParameterTypes::received +mobility, ParameterTypes::mobility +comp, ParameterTypes::comp +rport, ParameterTypes::rport +algorithm, ParameterTypes::algorithm +cnonce, ParameterTypes::cnonce +domain, ParameterTypes::domain +id, ParameterTypes::id +nonce, ParameterTypes::nonce +nc, ParameterTypes::nc +opaque, ParameterTypes::opaque +realf, ParameterTypes::realm +response, ParameterTypes::response +stale, ParameterTypes::stale +username, ParameterTypes::username +qop, ParameterTypes::qop +uri, ParameterTypes::uri +retry-after, ParameterTypes::retryAfter +reason, ParameterTypes::reason +%% + +} + +#endif diff --git a/src/libs/resiprocate/resip/stack/resiprocate.pro b/src/libs/resiprocate/resip/stack/resiprocate.pro new file mode 100644 index 00000000..89137fe7 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/resiprocate.pro @@ -0,0 +1,310 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2010-11-29T21:54:39 +# +#------------------------------------------------- + +QT -= core gui + +TARGET = resiprocate +TEMPLATE = lib +CONFIG += staticlib +INCLUDEPATH += ../../ ../../contrib/ares ../../../contrib/ares +DEFINES += USE_ARES USE_IPV6 _WIN32_WINNT=0x0501 + +win32 { + DESTDIR = ../../../../Libs/compiled/win +} + +SOURCES += \ + CallId.cxx \ + BranchParameter.cxx \ + BasicNonceHelper.cxx \ + Auth.cxx \ + ApplicationSip.cxx \ + ApiCheck.cxx \ + Aor.cxx \ + Compression.cxx \ + DateCategory.cxx \ + DataParameter.cxx \ + CSeqCategory.cxx \ + CpimContents.cxx \ + ContentsFactoryBase.cxx \ + Contents.cxx \ + ConnectionManager.cxx \ + ConnectionBase.cxx \ + Connection.cxx \ + DnsResult.cxx \ + DnsInterface.cxx \ + DeprecatedDialog.cxx \ + ExternalBodyContents.cxx \ + ExtensionParameter.cxx \ + ExtensionHeader.cxx \ + ExpiresCategory.cxx \ + ExistsParameter.cxx \ + ExistsOrDataParameter.cxx \ + Embedded.cxx \ + DtlsMessage.cxx \ + GenericUri.cxx \ + GenericContents.cxx \ + FloatParameter.cxx \ + LazyParser.cxx \ + KeepAliveMessage.cxx \ + InvalidContents.cxx \ + InterruptableStackThread.cxx \ + InteropHelper.cxx \ + InternalTransport.cxx \ + IntegerParameter.cxx \ + IntegerCategory.cxx \ + Helper.cxx \ + HeaderTypes.cxx \ + Headers.cxx \ + HeaderHash.cxx \ + HeaderFieldValueList.cxx \ + HeaderFieldValue.cxx \ + SecurityAttributes.cxx \ + SdpContents.cxx \ + RportParameter.cxx \ + Rlmi.cxx \ + RequestLine.cxx \ + RAckCategory.cxx \ + QValueParameter.cxx \ + QValue.cxx \ + QuotedDataParameter.cxx \ + PrivacyCategory.cxx \ + PlainContents.cxx \ + Pkcs8Contents.cxx \ + Pkcs7Contents.cxx \ + Pidf.cxx \ + ParserContainerBase.cxx \ + ParserCategory.cxx \ + ParserCategories.cxx \ + ParameterTypes.cxx \ + ParameterHash.cxx \ + Parameter.cxx \ + OctetContents.cxx \ + NonceHelper.cxx \ + NameAddr.cxx \ + MultipartSignedContents.cxx \ + MultipartRelatedContents.cxx \ + MultipartMixedContents.cxx \ + MultipartAlternativeContents.cxx \ + MsgHeaderScanner.cxx \ + Mime.cxx \ + MethodTypes.cxx \ + MethodHash.cxx \ + MessageWaitingContents.cxx \ + MessageFilterRule.cxx \ + Message.cxx \ + XMLCursor.cxx \ + X509Contents.cxx \ + WarningCategory.cxx \ + Via.cxx \ + Uri.cxx \ + UnknownParameter.cxx \ + UInt32Parameter.cxx \ + UInt32Category.cxx \ + UdpTransport.cxx \ + TuSelector.cxx \ + TupleMarkManager.cxx \ + Tuple.cxx \ + TuIM.cxx \ + TransportSelector.cxx \ + TransportFailure.cxx \ + Transport.cxx \ + TransactionUserMessage.cxx \ + TransactionUser.cxx \ + TransactionState.cxx \ + TransactionMap.cxx \ + TransactionController.cxx \ + Token.cxx \ + TimerQueue.cxx \ + TimerMessage.cxx \ + TimeAccumulate.cxx \ + TcpTransport.cxx \ + TcpConnection.cxx \ + TcpBaseTransport.cxx \ + Symbols.cxx \ + StringCategory.cxx \ + StatusLine.cxx \ + StatisticsMessage.cxx \ + StatisticsManager.cxx \ + StatisticsHandler.cxx \ + StatelessHandler.cxx \ + StackThread.cxx \ + SipStack.cxx \ + SipMessage.cxx \ + SipFrag.cxx \ + SERNonceHelper.cxx \ + SelectInterruptor.cxx \ + ssl/TlsTransport.cxx \ + ssl/TlsConnection.cxx \ + ssl/Security.cxx \ + ssl/DtlsTransport.cxx + +win32 { + SOURCES += ssl/WinSecurity.cxx +} + +HEADERS += \ + CancelClientInviteTransaction.hxx \ + CancelableTimerQueue.hxx \ + CallId.hxx \ + BranchParameter.hxx \ + BasicNonceHelper.hxx \ + Auth.hxx \ + ApplicationSip.hxx \ + ApplicationMessage.hxx \ + ApiCheckList.hxx \ + ApiCheck.hxx \ + Aor.hxx \ + AbandonServerTransaction.hxx \ + Compression.hxx \ + DateCategory.hxx \ + DataParameter.hxx \ + CSeqCategory.hxx \ + CpimContents.hxx \ + ContentsFactoryBase.hxx \ + ContentsFactory.hxx \ + Contents.hxx \ + ConnectionTerminated.hxx \ + ConnectionManager.hxx \ + ConnectionBase.hxx \ + Connection.hxx \ + DnsResult.hxx \ + DnsInterface.hxx \ + DeprecatedDialog.hxx \ + ExternalBodyContents.hxx \ + ExtensionParameter.hxx \ + ExtensionHeader.hxx \ + ExpiresCategory.hxx \ + ExistsParameter.hxx \ + ExistsOrDataParameter.hxx \ + Embedded.hxx \ + DtlsMessage.hxx \ + GenericUri.hxx \ + GenericContents.hxx \ + FloatParameter.hxx \ + LazyParser.hxx \ + KeepAliveMessage.hxx \ + InvalidContents.hxx \ + InterruptableStackThread.hxx \ + InteropHelper.hxx \ + InternalTransport.hxx \ + IntegerParameter.hxx \ + IntegerCategory.hxx \ + Helper.hxx \ + HeaderTypes.hxx \ + Headers.hxx \ + HeaderHash.hxx \ + HeaderFieldValueList.hxx \ + HeaderFieldValue.hxx \ + SecurityTypes.hxx \ + SecurityAttributes.hxx \ + SdpContents.hxx \ + RportParameter.hxx \ + Rlmi.hxx \ + RequestLine.hxx \ + RAckCategory.hxx \ + QValueParameter.hxx \ + QValue.hxx \ + QuotedDataParameter.hxx \ + PrivacyCategory.hxx \ + PlainContents.hxx \ + Pkcs8Contents.hxx \ + Pkcs7Contents.hxx \ + Pidf.hxx \ + ParserContainerBase.hxx \ + ParserContainer.hxx \ + ParserCategory.hxx \ + ParserCategories.hxx \ + ParameterTypes.hxx \ + ParameterTypeEnums.hxx \ + parametersA.gperf \ + ParameterHash.hxx \ + Parameter.hxx \ + OctetContents.hxx \ + NonceHelper.hxx \ + NameAddr.hxx \ + MultipartSignedContents.hxx \ + MultipartRelatedContents.hxx \ + MultipartMixedContents.hxx \ + MultipartAlternativeContents.hxx \ + MsgHeaderScanner.hxx \ + Mime.hxx \ + MethodTypes.hxx \ + MethodHash.hxx \ + MessageWaitingContents.hxx \ + MessageFilterRule.hxx \ + MessageDecorator.hxx \ + Message.hxx \ + MarkListener.hxx \ + XMLCursor.hxx \ + X509Contents.hxx \ + WarningCategory.hxx \ + Via.hxx \ + ValueFifo.hxx \ + Uri.hxx \ + UnknownParameterType.hxx \ + UnknownParameter.hxx \ + UnknownHeaderType.hxx \ + UInt32Parameter.hxx \ + UInt32Category.hxx \ + UdpTransport.hxx \ + TuSelector.hxx \ + TupleMarkManager.hxx \ + Tuple.hxx \ + TuIM.hxx \ + TransportSelector.hxx \ + TransportFailure.hxx \ + Transport.hxx \ + TransactionUserMessage.hxx \ + TransactionUser.hxx \ + TransactionTerminated.hxx \ + TransactionState.hxx \ + TransactionMessage.hxx \ + TransactionMap.hxx \ + TransactionController.hxx \ + Token.hxx \ + TimerQueue.hxx \ + TimerMessage.hxx \ + TimeAccumulate.hxx \ + TcpTransport.hxx \ + TcpConnection.hxx \ + TcpBaseTransport.hxx \ + Symbols.hxx \ + StringCategory.hxx \ + StatusLine.hxx \ + StatisticsMessage.hxx \ + StatisticsManager.hxx \ + StatisticsHandler.hxx \ + StatelessHandler.hxx \ + StackThread.hxx \ + SipStack.hxx \ + SipMessage.hxx \ + SipFrag.hxx \ + ShutdownMessage.hxx \ + SERNonceHelper.hxx \ + SendData.hxx \ + SelectInterruptor.hxx \ + ssl/TlsTransport.hxx \ + ssl/TlsConnection.hxx \ + ssl/Security.hxx \ + ssl/DtlsTransport.hxx + +win32 { + HEADERS += ssl/WinSecurity.hxx +} + +unix:!symbian { + maemo5 { + target.path = /opt/usr/lib + } else { + target.path = /usr/local/lib + } + INSTALLS += target +} + +OTHER_FILES += + + diff --git a/src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj b/src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj new file mode 100644 index 00000000..9175e59d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj @@ -0,0 +1,655 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|Win32"> + <Configuration>SSL-Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|x64"> + <Configuration>SSL-Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|Win32"> + <Configuration>SSL-Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|x64"> + <Configuration>SSL-Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>resiprocate</ProjectName> + <ProjectGuid>{2A8BE839-6466-4001-B224-8F1C3168D04A}</ProjectGuid> + <RootNamespace>resiprocate</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Debug\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Release\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">SSL-Debug\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">SSL-Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">SSL-Debug\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">SSL-Debug\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">SSL-Release\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">SSL-Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">SSL-Release\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">SSL-Release\</IntDir> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <AdditionalOptions>/Zm300 %(AdditionalOptions)</AdditionalOptions> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <AdditionalOptions>/Zm300 %(AdditionalOptions)</AdditionalOptions> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalOptions>/Zm300 %(AdditionalOptions)</AdditionalOptions> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <OmitFramePointers>true</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat> + </DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <AdditionalOptions>/Zm300 %(AdditionalOptions)</AdditionalOptions> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <OmitFramePointers>true</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat> + </DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <ClCompile> + <AdditionalOptions>/Zm300 %(AdditionalOptions)</AdditionalOptions> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;NO_IPHLPAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'"> + <ClCompile> + <AdditionalOptions>/Zm300 %(AdditionalOptions)</AdditionalOptions> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;NO_IPHLPAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <ClCompile> + <AdditionalOptions>/Zm300 %(AdditionalOptions)</AdditionalOptions> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <OmitFramePointers>true</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;NO_IPHLPAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'"> + <ClCompile> + <AdditionalOptions>/Zm300 %(AdditionalOptions)</AdditionalOptions> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <OmitFramePointers>true</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;NO_IPHLPAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="Aor.cxx" /> + <ClCompile Include="ApiCheck.cxx" /> + <ClCompile Include="ApplicationSip.cxx" /> + <ClCompile Include="Auth.cxx" /> + <ClCompile Include="BasicNonceHelper.cxx" /> + <ClCompile Include="BranchParameter.cxx" /> + <ClCompile Include="CallId.cxx" /> + <ClCompile Include="Compression.cxx" /> + <ClCompile Include="Connection.cxx" /> + <ClCompile Include="ConnectionBase.cxx" /> + <ClCompile Include="ConnectionManager.cxx" /> + <ClCompile Include="Contents.cxx" /> + <ClCompile Include="ContentsFactoryBase.cxx" /> + <ClCompile Include="CpimContents.cxx" /> + <ClCompile Include="CSeqCategory.cxx" /> + <ClCompile Include="DataParameter.cxx" /> + <ClCompile Include="DateCategory.cxx" /> + <ClCompile Include="DeprecatedDialog.cxx" /> + <ClCompile Include="DnsInterface.cxx" /> + <ClCompile Include="DnsResult.cxx" /> + <ClCompile Include="DtlsMessage.cxx" /> + <ClCompile Include="ssl\DtlsTransport.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="Embedded.cxx" /> + <ClCompile Include="EventStackThread.cxx" /> + <ClCompile Include="ExistsOrDataParameter.cxx" /> + <ClCompile Include="ExistsParameter.cxx" /> + <ClCompile Include="ExpiresCategory.cxx" /> + <ClCompile Include="ExtensionHeader.cxx" /> + <ClCompile Include="ExtensionParameter.cxx" /> + <ClCompile Include="ExternalBodyContents.cxx" /> + <ClCompile Include="GenericContents.cxx" /> + <ClCompile Include="GenericUri.cxx" /> + <ClCompile Include="HeaderFieldValue.cxx" /> + <ClCompile Include="HeaderFieldValueList.cxx" /> + <ClCompile Include="HeaderHash.cxx" /> + <ClCompile Include="Headers.cxx" /> + <ClCompile Include="HeaderTypes.cxx" /> + <ClCompile Include="Helper.cxx" /> + <ClCompile Include="IntegerCategory.cxx" /> + <ClCompile Include="IntegerParameter.cxx" /> + <ClCompile Include="InternalTransport.cxx" /> + <ClCompile Include="InteropHelper.cxx" /> + <ClCompile Include="InterruptableStackThread.cxx" /> + <ClCompile Include="InvalidContents.cxx" /> + <ClCompile Include="KeepAliveMessage.cxx" /> + <ClCompile Include="LazyParser.cxx" /> + <ClCompile Include="Message.cxx" /> + <ClCompile Include="MessageFilterRule.cxx" /> + <ClCompile Include="MessageWaitingContents.cxx" /> + <ClCompile Include="MethodHash.cxx" /> + <ClCompile Include="MethodTypes.cxx" /> + <ClCompile Include="Mime.cxx" /> + <ClCompile Include="MsgHeaderScanner.cxx" /> + <ClCompile Include="MultipartAlternativeContents.cxx" /> + <ClCompile Include="MultipartMixedContents.cxx" /> + <ClCompile Include="MultipartRelatedContents.cxx" /> + <ClCompile Include="MultipartSignedContents.cxx" /> + <ClCompile Include="NameAddr.cxx" /> + <ClCompile Include="NonceHelper.cxx" /> + <ClCompile Include="OctetContents.cxx" /> + <ClCompile Include="Parameter.cxx" /> + <ClCompile Include="ParameterHash.cxx" /> + <ClCompile Include="ParameterTypes.cxx" /> + <ClCompile Include="ParserCategories.cxx" /> + <ClCompile Include="ParserCategory.cxx" /> + <ClCompile Include="ParserContainerBase.cxx" /> + <ClCompile Include="Pidf.cxx" /> + <ClCompile Include="Pkcs7Contents.cxx" /> + <ClCompile Include="Pkcs8Contents.cxx" /> + <ClCompile Include="PlainContents.cxx" /> + <ClCompile Include="PrivacyCategory.cxx" /> + <ClCompile Include="QuotedDataParameter.cxx" /> + <ClCompile Include="QValue.cxx" /> + <ClCompile Include="QValueParameter.cxx" /> + <ClCompile Include="RAckCategory.cxx" /> + <ClCompile Include="RequestLine.cxx" /> + <ClCompile Include="Rlmi.cxx" /> + <ClCompile Include="RportParameter.cxx" /> + <ClCompile Include="SdpContents.cxx" /> + <ClCompile Include="ssl\Security.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="SecurityAttributes.cxx" /> + <ClCompile Include="SERNonceHelper.cxx" /> + <ClCompile Include="SipFrag.cxx" /> + <ClCompile Include="SipMessage.cxx" /> + <ClCompile Include="SipStack.cxx" /> + <ClCompile Include="StackThread.cxx" /> + <ClCompile Include="StatelessHandler.cxx" /> + <ClCompile Include="StatisticsHandler.cxx" /> + <ClCompile Include="StatisticsManager.cxx" /> + <ClCompile Include="StatisticsMessage.cxx" /> + <ClCompile Include="StatusLine.cxx" /> + <ClCompile Include="StringCategory.cxx" /> + <ClCompile Include="Symbols.cxx" /> + <ClCompile Include="TcpBaseTransport.cxx" /> + <ClCompile Include="TcpConnection.cxx" /> + <ClCompile Include="TcpTransport.cxx" /> + <ClCompile Include="TimeAccumulate.cxx" /> + <ClCompile Include="TimerMessage.cxx" /> + <ClCompile Include="TimerQueue.cxx" /> + <ClCompile Include="ssl\TlsConnection.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="ssl\TlsTransport.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="Token.cxx" /> + <ClCompile Include="TransactionController.cxx" /> + <ClCompile Include="TransactionMap.cxx" /> + <ClCompile Include="TransactionState.cxx" /> + <ClCompile Include="TransactionUser.cxx" /> + <ClCompile Include="TransactionUserMessage.cxx" /> + <ClCompile Include="Transport.cxx" /> + <ClCompile Include="TransportFailure.cxx" /> + <ClCompile Include="TransportSelector.cxx" /> + <ClCompile Include="TransportThread.cxx" /> + <ClCompile Include="TuIM.cxx" /> + <ClCompile Include="Tuple.cxx" /> + <ClCompile Include="TupleMarkManager.cxx" /> + <ClCompile Include="TuSelector.cxx" /> + <ClCompile Include="UdpTransport.cxx" /> + <ClCompile Include="UInt32Category.cxx" /> + <ClCompile Include="UInt32Parameter.cxx" /> + <ClCompile Include="UnknownParameter.cxx" /> + <ClCompile Include="Uri.cxx" /> + <ClCompile Include="Via.cxx" /> + <ClCompile Include="WarningCategory.cxx" /> + <ClCompile Include="ssl\WinSecurity.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="X509Contents.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Aor.hxx" /> + <ClInclude Include="ApiCheck.hxx" /> + <ClInclude Include="ApiCheckList.hxx" /> + <ClInclude Include="ApplicationMessage.hxx" /> + <ClInclude Include="ApplicationSip.hxx" /> + <ClInclude Include="Auth.hxx" /> + <ClInclude Include="BasicNonceHelper.hxx" /> + <ClInclude Include="BranchParameter.hxx" /> + <ClInclude Include="CallId.hxx" /> + <ClInclude Include="CancelableTimerQueue.hxx" /> + <ClInclude Include="CancelClientInviteTransaction.hxx" /> + <ClInclude Include="Compression.hxx" /> + <ClInclude Include="Connection.hxx" /> + <ClInclude Include="ConnectionBase.hxx" /> + <ClInclude Include="ConnectionManager.hxx" /> + <ClInclude Include="ConnectionTerminated.hxx" /> + <ClInclude Include="Contents.hxx" /> + <ClInclude Include="ContentsFactory.hxx" /> + <ClInclude Include="ContentsFactoryBase.hxx" /> + <ClInclude Include="CpimContents.hxx" /> + <ClInclude Include="CSeqCategory.hxx" /> + <ClInclude Include="DataParameter.hxx" /> + <ClInclude Include="DateCategory.hxx" /> + <ClInclude Include="DeprecatedDialog.hxx" /> + <ClInclude Include="DnsInterface.hxx" /> + <ClInclude Include="DnsResult.hxx" /> + <ClInclude Include="DnsResultMessage.hxx" /> + <ClInclude Include="DtlsMessage.hxx" /> + <ClInclude Include="KeepAlivePong.hxx" /> + <ClInclude Include="MessageDecorator.hxx" /> + <ClInclude Include="ssl\DtlsTransport.hxx" /> + <ClInclude Include="Embedded.hxx" /> + <ClInclude Include="EventStackThread.hxx" /> + <ClInclude Include="ExistsOrDataParameter.hxx" /> + <ClInclude Include="ExistsParameter.hxx" /> + <ClInclude Include="ExpiresCategory.hxx" /> + <ClInclude Include="ExtensionHeader.hxx" /> + <ClInclude Include="ExtensionParameter.hxx" /> + <ClInclude Include="ExternalBodyContents.hxx" /> + <ClInclude Include="GenericContents.hxx" /> + <ClInclude Include="GenericUri.hxx" /> + <ClInclude Include="HeaderFieldValue.hxx" /> + <ClInclude Include="HeaderFieldValueList.hxx" /> + <ClInclude Include="HeaderHash.hxx" /> + <ClInclude Include="Headers.hxx" /> + <ClInclude Include="HeaderTypes.hxx" /> + <ClInclude Include="Helper.hxx" /> + <ClInclude Include="IntegerCategory.hxx" /> + <ClInclude Include="IntegerParameter.hxx" /> + <ClInclude Include="InternalTransport.hxx" /> + <ClInclude Include="InteropHelper.hxx" /> + <ClInclude Include="InterruptableStackThread.hxx" /> + <ClInclude Include="InvalidContents.hxx" /> + <ClInclude Include="KeepAliveMessage.hxx" /> + <ClInclude Include="LazyParser.hxx" /> + <ClInclude Include="MarkListener.hxx" /> + <ClInclude Include="Message.hxx" /> + <ClInclude Include="MessageFilterRule.hxx" /> + <ClInclude Include="MessageWaitingContents.hxx" /> + <ClInclude Include="MethodHash.hxx" /> + <ClInclude Include="MethodTypes.hxx" /> + <ClInclude Include="Mime.hxx" /> + <ClInclude Include="MsgHeaderScanner.hxx" /> + <ClInclude Include="MultipartAlternativeContents.hxx" /> + <ClInclude Include="MultipartMixedContents.hxx" /> + <ClInclude Include="MultipartRelatedContents.hxx" /> + <ClInclude Include="MultipartSignedContents.hxx" /> + <ClInclude Include="NameAddr.hxx" /> + <ClInclude Include="NonceHelper.hxx" /> + <ClInclude Include="OctetContents.hxx" /> + <ClInclude Include="Parameter.hxx" /> + <ClInclude Include="ParameterHash.hxx" /> + <ClInclude Include="ParameterTypeEnums.hxx" /> + <ClInclude Include="ParameterTypes.hxx" /> + <ClInclude Include="ParserCategories.hxx" /> + <ClInclude Include="ParserCategory.hxx" /> + <ClInclude Include="ParserContainer.hxx" /> + <ClInclude Include="ParserContainerBase.hxx" /> + <ClInclude Include="Pidf.hxx" /> + <ClInclude Include="Pkcs7Contents.hxx" /> + <ClInclude Include="Pkcs8Contents.hxx" /> + <ClInclude Include="PlainContents.hxx" /> + <ClInclude Include="PollStatistics.hxx" /> + <ClInclude Include="PrivacyCategory.hxx" /> + <ClInclude Include="QuotedDataParameter.hxx" /> + <ClInclude Include="QValue.hxx" /> + <ClInclude Include="QValueParameter.hxx" /> + <ClInclude Include="RAckCategory.hxx" /> + <ClInclude Include="RequestLine.hxx" /> + <ClInclude Include="Rlmi.hxx" /> + <ClInclude Include="RportParameter.hxx" /> + <ClInclude Include="SdpContents.hxx" /> + <ClInclude Include="ssl\Security.hxx" /> + <ClInclude Include="SecurityAttributes.hxx" /> + <ClInclude Include="SecurityTypes.hxx" /> + <ClInclude Include="SendData.hxx" /> + <ClInclude Include="SERNonceHelper.hxx" /> + <ClInclude Include="ShutdownMessage.hxx" /> + <ClInclude Include="SipFrag.hxx" /> + <ClInclude Include="SipMessage.hxx" /> + <ClInclude Include="SipStack.hxx" /> + <ClInclude Include="StackThread.hxx" /> + <ClInclude Include="StartLine.hxx" /> + <ClInclude Include="StatelessHandler.hxx" /> + <ClInclude Include="StatisticsHandler.hxx" /> + <ClInclude Include="StatisticsManager.hxx" /> + <ClInclude Include="StatisticsMessage.hxx" /> + <ClInclude Include="StatusLine.hxx" /> + <ClInclude Include="StringCategory.hxx" /> + <ClInclude Include="Symbols.hxx" /> + <ClInclude Include="TcpBaseTransport.hxx" /> + <ClInclude Include="TcpConnection.hxx" /> + <ClInclude Include="TcpTransport.hxx" /> + <ClInclude Include="TerminateFlow.hxx" /> + <ClInclude Include="TextParameter.hxx" /> + <ClInclude Include="TimeAccumulate.hxx" /> + <ClInclude Include="TimerMessage.hxx" /> + <ClInclude Include="TimerQueue.hxx" /> + <ClInclude Include="ssl\TlsConnection.hxx" /> + <ClInclude Include="ssl\TlsTransport.hxx" /> + <ClInclude Include="Token.hxx" /> + <ClInclude Include="TransactionController.hxx" /> + <ClInclude Include="TransactionControllerThread.hxx" /> + <ClInclude Include="TransactionMap.hxx" /> + <ClInclude Include="TransactionMessage.hxx" /> + <ClInclude Include="TransactionState.hxx" /> + <ClInclude Include="TransactionTerminated.hxx" /> + <ClInclude Include="TransactionUser.hxx" /> + <ClInclude Include="TransactionUserMessage.hxx" /> + <ClInclude Include="Transport.hxx" /> + <ClInclude Include="TransportFailure.hxx" /> + <ClInclude Include="TransportSelector.hxx" /> + <ClInclude Include="TransportSelectorThread.hxx" /> + <ClInclude Include="TransportThread.hxx" /> + <ClInclude Include="TuIM.hxx" /> + <ClInclude Include="Tuple.hxx" /> + <ClInclude Include="TupleMarkManager.hxx" /> + <ClInclude Include="TuSelector.hxx" /> + <ClInclude Include="UdpTransport.hxx" /> + <ClInclude Include="UInt32Category.hxx" /> + <ClInclude Include="UInt32Parameter.hxx" /> + <ClInclude Include="UnknownHeaderType.hxx" /> + <ClInclude Include="UnknownParameter.hxx" /> + <ClInclude Include="UnknownParameterType.hxx" /> + <ClInclude Include="Uri.hxx" /> + <ClInclude Include="ValueFifo.hxx" /> + <ClInclude Include="Via.hxx" /> + <ClInclude Include="WarningCategory.hxx" /> + <ClInclude Include="ssl\WinSecurity.hxx" /> + <ClInclude Include="X509Contents.hxx" /> + <ClInclude Include="ZeroOutStatistics.hxx" /> + </ItemGroup> + <ItemGroup> + <None Include="HeaderHash.gperf" /> + <None Include="MethodHash.gperf" /> + <None Include="ParameterHash.gperf" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\rutil\rutil_10_0.vcxproj"> + <Project>{3d0e5ceb-93dc-4fdb-918b-d08fa369e106}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj.filters b/src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj.filters new file mode 100644 index 00000000..4517fd7c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj.filters @@ -0,0 +1,856 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="GPerfFiles"> + <UniqueIdentifier>{7670bbf8-7277-4dba-b6f5-bb726a96b4e6}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{11690c26-b5eb-442d-b7fb-5fb97ce10cf0}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc</Extensions> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{4d95e332-af7e-4e86-9bd4-3c03fc017b97}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="Aor.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ApiCheck.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ApplicationSip.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Auth.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BasicNonceHelper.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BranchParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="CallId.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Compression.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Connection.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ConnectionBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ConnectionManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Contents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ContentsFactoryBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="CpimContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="CSeqCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DataParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DateCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DeprecatedDialog.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DnsInterface.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DnsResult.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DtlsMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Embedded.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ExistsOrDataParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ExistsParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ExpiresCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ExtensionHeader.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ExtensionParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ExternalBodyContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="GenericContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="GenericUri.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HeaderFieldValue.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HeaderFieldValueList.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HeaderHash.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Headers.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HeaderTypes.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Helper.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="IntegerCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="IntegerParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InternalTransport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InteropHelper.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InterruptableStackThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InvalidContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="KeepAliveMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="LazyParser.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Message.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MessageFilterRule.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MessageWaitingContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MethodHash.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MethodTypes.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Mime.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MsgHeaderScanner.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MultipartAlternativeContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MultipartMixedContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MultipartRelatedContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MultipartSignedContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="NameAddr.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="NonceHelper.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="OctetContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Parameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParameterHash.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParameterTypes.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParserCategories.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParserCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParserContainerBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Pidf.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Pkcs7Contents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Pkcs8Contents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="PlainContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="PrivacyCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="QuotedDataParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="QValue.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="QValueParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RAckCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RequestLine.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Rlmi.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RportParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SdpContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SecurityAttributes.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SERNonceHelper.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SipFrag.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SipMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SipStack.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\DtlsTransport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\Security.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\TlsConnection.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\TlsTransport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\WinSecurity.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StackThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StatelessHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StatisticsHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StatisticsManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StatisticsMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StatusLine.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StringCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Symbols.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TcpBaseTransport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TcpConnection.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TcpTransport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TimeAccumulate.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TimerMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TimerQueue.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Token.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransactionController.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransactionMap.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransactionState.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransactionUser.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransactionUserMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Transport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransportFailure.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransportSelector.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TuIM.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Tuple.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TupleMarkManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TuSelector.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UdpTransport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UInt32Category.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UInt32Parameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UnknownParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Uri.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Via.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="WarningCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="X509Contents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="EventStackThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransportThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Aor.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ApiCheck.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ApiCheckList.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ApplicationMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ApplicationSip.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Auth.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BasicNonceHelper.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BranchParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CallId.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CancelableTimerQueue.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Compression.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Connection.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConnectionBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConnectionManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Contents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ContentsFactory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ContentsFactoryBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CpimContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CSeqCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DataParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DateCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DeprecatedDialog.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DnsInterface.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DnsResult.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DtlsMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Embedded.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExistsOrDataParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExistsParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExpiresCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExtensionHeader.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExtensionParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExternalBodyContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="GenericContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="GenericUri.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HeaderFieldValue.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HeaderFieldValueList.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HeaderHash.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Headers.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HeaderTypes.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Helper.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="IntegerCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="IntegerParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InternalTransport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InteropHelper.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InterruptableStackThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InvalidContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="KeepAliveMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="LazyParser.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MarkListener.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Message.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MessageFilterRule.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MessageWaitingContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MethodHash.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MethodTypes.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Mime.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MsgHeaderScanner.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MultipartAlternativeContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MultipartMixedContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MultipartRelatedContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MultipartSignedContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="NameAddr.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="NonceHelper.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="OctetContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Parameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParameterHash.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParameterTypeEnums.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParameterTypes.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParserCategories.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParserCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParserContainer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParserContainerBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Pidf.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Pkcs7Contents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Pkcs8Contents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PlainContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PollStatistics.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PrivacyCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="QuotedDataParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="QValue.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="QValueParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RAckCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RequestLine.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Rlmi.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RportParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SdpContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SecurityAttributes.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SecurityTypes.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SendData.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SERNonceHelper.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ShutdownMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SipFrag.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SipMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SipStack.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\DtlsTransport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\Security.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\TlsConnection.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\TlsTransport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\WinSecurity.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StackThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StatelessHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StatisticsHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StatisticsManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StatisticsMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StatusLine.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StringCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Symbols.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TcpBaseTransport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TcpConnection.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TcpTransport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TextParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TimeAccumulate.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TimerMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TimerQueue.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Token.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionController.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionMap.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionState.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionTerminated.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionUser.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionUserMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Transport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransportFailure.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransportSelector.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TuIM.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Tuple.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TupleMarkManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TuSelector.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UdpTransport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UInt32Category.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UInt32Parameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UnknownHeaderType.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UnknownParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UnknownParameterType.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Uri.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ValueFifo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Via.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="WarningCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="X509Contents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ZeroOutStatistics.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="EventStackThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConnectionTerminated.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="KeepAlivePong.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TerminateFlow.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DnsResultMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StartLine.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionControllerThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransportSelectorThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransportThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CancelClientInviteTransaction.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MessageDecorator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="HeaderHash.gperf"> + <Filter>GPerfFiles</Filter> + </None> + <None Include="MethodHash.gperf"> + <Filter>GPerfFiles</Filter> + </None> + <None Include="ParameterHash.gperf"> + <Filter>GPerfFiles</Filter> + </None> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/resiprocate_7_1.vcproj b/src/libs/resiprocate/resip/stack/resiprocate_7_1.vcproj new file mode 100644 index 00000000..b45ea17c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/resiprocate_7_1.vcproj @@ -0,0 +1,1125 @@ +<?xml version="1.0" encoding="UTF-8"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="resiprocate" + ProjectGUID="{2A8BE839-6466-4001-B224-8F1C3168D04A}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + UseOfMFC="0" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="TRUE" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + UseOfMFC="0" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="TRUE" + OptimizeForProcessor="0" + OptimizeForWindowsApplication="FALSE" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6" + StringPooling="TRUE" + RuntimeLibrary="2" + BufferSecurityCheck="FALSE" + EnableFunctionLevelLinking="TRUE" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="SSL-Debug" + IntermediateDirectory="SSL-Debug" + ConfigurationType="4" + UseOfMFC="0" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="SSL-Release" + IntermediateDirectory="SSL-Release" + ConfigurationType="4" + UseOfMFC="0" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300" + Optimization="2" + InlineFunctionExpansion="1" + OmitFramePointers="TRUE" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6" + StringPooling="TRUE" + RuntimeLibrary="2" + EnableFunctionLevelLinking="TRUE" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Debug71|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + UseOfMFC="0" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="TRUE" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"> + <File + RelativePath=".\Aor.cxx"> + </File> + <File + RelativePath=".\ApiCheck.cxx"> + </File> + <File + RelativePath=".\ApplicationSip.cxx"> + </File> + <File + RelativePath=".\Auth.cxx"> + </File> + <File + RelativePath=".\BasicNonceHelper.cxx"> + </File> + <File + RelativePath=".\BranchParameter.cxx"> + </File> + <File + RelativePath=".\CallId.cxx"> + </File> + <File + RelativePath=".\Compression.cxx"> + </File> + <File + RelativePath=".\Connection.cxx"> + </File> + <File + RelativePath=".\ConnectionBase.cxx"> + </File> + <File + RelativePath=".\ConnectionManager.cxx"> + </File> + <File + RelativePath=".\Contents.cxx"> + </File> + <File + RelativePath=".\ContentsFactoryBase.cxx"> + </File> + <File + RelativePath=".\CpimContents.cxx"> + </File> + <File + RelativePath=".\CSeqCategory.cxx"> + </File> + <File + RelativePath=".\DataParameter.cxx"> + </File> + <File + RelativePath=".\DateCategory.cxx"> + </File> + <File + RelativePath=".\DeprecatedDialog.cxx"> + </File> + <File + RelativePath=".\DnsInterface.cxx"> + </File> + <File + RelativePath=".\DnsResult.cxx"> + </File> + <File + RelativePath=".\DtlsMessage.cxx"> + </File> + <File + RelativePath=".\ssl\DtlsTransport.cxx"> + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + </File> + <File + RelativePath=".\Embedded.cxx"> + </File> + <File + RelativePath=".\EventStackThread.cxx"> + </File> + <File + RelativePath=".\ExistsOrDataParameter.cxx"> + </File> + <File + RelativePath=".\ExistsParameter.cxx"> + </File> + <File + RelativePath=".\ExpiresCategory.cxx"> + </File> + <File + RelativePath=".\ExtensionHeader.cxx"> + </File> + <File + RelativePath=".\ExtensionParameter.cxx"> + </File> + <File + RelativePath=".\ExternalBodyContents.cxx"> + </File> + <File + RelativePath=".\GenericContents.cxx"> + </File> + <File + RelativePath=".\GenericUri.cxx"> + </File> + <File + RelativePath=".\HeaderFieldValue.cxx"> + </File> + <File + RelativePath=".\HeaderFieldValueList.cxx"> + </File> + <File + RelativePath=".\HeaderHash.cxx"> + </File> + <File + RelativePath=".\Headers.cxx"> + </File> + <File + RelativePath=".\HeaderTypes.cxx"> + </File> + <File + RelativePath=".\Helper.cxx"> + </File> + <File + RelativePath=".\IntegerCategory.cxx"> + </File> + <File + RelativePath=".\IntegerParameter.cxx"> + </File> + <File + RelativePath=".\InternalTransport.cxx"> + </File> + <File + RelativePath=".\InteropHelper.cxx"> + </File> + <File + RelativePath=".\InterruptableStackThread.cxx"> + </File> + <File + RelativePath=".\InvalidContents.cxx"> + </File> + <File + RelativePath=".\KeepAliveMessage.cxx"> + </File> + <File + RelativePath=".\LazyParser.cxx"> + </File> + <File + RelativePath=".\Message.cxx"> + </File> + <File + RelativePath=".\MessageFilterRule.cxx"> + </File> + <File + RelativePath=".\MessageWaitingContents.cxx"> + </File> + <File + RelativePath=".\MethodHash.cxx"> + </File> + <File + RelativePath=".\MethodTypes.cxx"> + </File> + <File + RelativePath=".\Mime.cxx"> + </File> + <File + RelativePath=".\MsgHeaderScanner.cxx"> + </File> + <File + RelativePath=".\MultipartAlternativeContents.cxx"> + </File> + <File + RelativePath=".\MultipartMixedContents.cxx"> + </File> + <File + RelativePath=".\MultipartRelatedContents.cxx"> + </File> + <File + RelativePath=".\MultipartSignedContents.cxx"> + </File> + <File + RelativePath=".\NameAddr.cxx"> + </File> + <File + RelativePath=".\NonceHelper.cxx"> + </File> + <File + RelativePath=".\OctetContents.cxx"> + </File> + <File + RelativePath=".\Parameter.cxx"> + </File> + <File + RelativePath=".\ParameterHash.cxx"> + </File> + <File + RelativePath=".\ParameterTypes.cxx"> + </File> + <File + RelativePath=".\ParserCategories.cxx"> + </File> + <File + RelativePath=".\ParserCategory.cxx"> + </File> + <File + RelativePath=".\ParserContainerBase.cxx"> + </File> + <File + RelativePath=".\Pidf.cxx"> + </File> + <File + RelativePath=".\Pkcs7Contents.cxx"> + </File> + <File + RelativePath=".\Pkcs8Contents.cxx"> + </File> + <File + RelativePath=".\PlainContents.cxx"> + </File> + <File + RelativePath=".\PrivacyCategory.cxx"> + </File> + <File + RelativePath=".\QuotedDataParameter.cxx"> + </File> + <File + RelativePath=".\QValue.cxx"> + </File> + <File + RelativePath=".\QValueParameter.cxx"> + </File> + <File + RelativePath=".\RAckCategory.cxx"> + </File> + <File + RelativePath=".\RequestLine.cxx"> + </File> + <File + RelativePath=".\Rlmi.cxx"> + </File> + <File + RelativePath=".\RportParameter.cxx"> + </File> + <File + RelativePath=".\SdpContents.cxx"> + </File> + <File + RelativePath=".\ssl\Security.cxx"> + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + </File> + <File + RelativePath=".\SecurityAttributes.cxx"> + </File> + <File + RelativePath=".\SelectInterruptor.cxx"> + </File> + <File + RelativePath=".\SERNonceHelper.cxx"> + </File> + <File + RelativePath=".\SipFrag.cxx"> + </File> + <File + RelativePath=".\SipMessage.cxx"> + </File> + <File + RelativePath=".\SipStack.cxx"> + </File> + <File + RelativePath=".\StackThread.cxx"> + </File> + <File + RelativePath=".\StatisticsHandler.cxx"> + </File> + <File + RelativePath=".\StatisticsManager.cxx"> + </File> + <File + RelativePath=".\StatisticsMessage.cxx"> + </File> + <File + RelativePath=".\StatusLine.cxx"> + </File> + <File + RelativePath=".\StringCategory.cxx"> + </File> + <File + RelativePath=".\Symbols.cxx"> + </File> + <File + RelativePath=".\TcpBaseTransport.cxx"> + </File> + <File + RelativePath=".\TcpConnection.cxx"> + </File> + <File + RelativePath=".\TcpTransport.cxx"> + </File> + <File + RelativePath=".\TimeAccumulate.cxx"> + </File> + <File + RelativePath=".\TimerMessage.cxx"> + </File> + <File + RelativePath=".\TimerQueue.cxx"> + </File> + <File + RelativePath=".\ssl\TlsConnection.cxx"> + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + </File> + <File + RelativePath=".\ssl\TlsTransport.cxx"> + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + </File> + <File + RelativePath=".\Token.cxx"> + </File> + <File + RelativePath=".\TransactionController.cxx"> + </File> + <File + RelativePath=".\TransactionMap.cxx"> + </File> + <File + RelativePath=".\TransactionState.cxx"> + </File> + <File + RelativePath=".\TransactionUser.cxx"> + </File> + <File + RelativePath=".\TransactionUserMessage.cxx"> + </File> + <File + RelativePath=".\Transport.cxx"> + </File> + <File + RelativePath=".\TransportFailure.cxx"> + </File> + <File + RelativePath=".\TransportSelector.cxx"> + </File> + <File + RelativePath=".\TuIM.cxx"> + </File> + <File + RelativePath=".\Tuple.cxx"> + </File> + <File + RelativePath=".\TupleMarkManager.cxx"> + </File> + <File + RelativePath=".\TuSelector.cxx"> + </File> + <File + RelativePath=".\UdpTransport.cxx"> + </File> + <File + RelativePath=".\UInt32Category.cxx"> + </File> + <File + RelativePath=".\UInt32Parameter.cxx"> + </File> + <File + RelativePath=".\UnknownParameter.cxx"> + </File> + <File + RelativePath=".\Uri.cxx"> + </File> + <File + RelativePath=".\Via.cxx"> + </File> + <File + RelativePath=".\WarningCategory.cxx"> + </File> + <File + RelativePath=".\ssl\WinSecurity.cxx"> + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + </File> + <File + RelativePath=".\X509Contents.cxx"> + </File> + <File + RelativePath=".\XMLCursor.cxx"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc"> + <File + RelativePath=".\Aor.hxx"> + </File> + <File + RelativePath=".\ApiCheck.hxx"> + </File> + <File + RelativePath=".\ApiCheckList.hxx"> + </File> + <File + RelativePath=".\ApplicationMessage.hxx"> + </File> + <File + RelativePath=".\ApplicationSip.hxx"> + </File> + <File + RelativePath=".\Auth.hxx"> + </File> + <File + RelativePath=".\BasicNonceHelper.hxx"> + </File> + <File + RelativePath=".\BranchParameter.hxx"> + </File> + <File + RelativePath=".\CallId.hxx"> + </File> + <File + RelativePath=".\CancelableTimerQueue.hxx"> + </File> + <File + RelativePath=".\Compression.hxx"> + </File> + <File + RelativePath=".\Connection.hxx"> + </File> + <File + RelativePath=".\ConnectionBase.hxx"> + </File> + <File + RelativePath=".\ConnectionManager.hxx"> + </File> + <File + RelativePath=".\Contents.hxx"> + </File> + <File + RelativePath=".\ContentsFactory.hxx"> + </File> + <File + RelativePath=".\ContentsFactoryBase.hxx"> + </File> + <File + RelativePath=".\CpimContents.hxx"> + </File> + <File + RelativePath=".\CSeqCategory.hxx"> + </File> + <File + RelativePath=".\DataParameter.hxx"> + </File> + <File + RelativePath=".\DateCategory.hxx"> + </File> + <File + RelativePath=".\DeprecatedDialog.hxx"> + </File> + <File + RelativePath=".\DnsInterface.hxx"> + </File> + <File + RelativePath=".\DnsResult.hxx"> + </File> + <File + RelativePath=".\DtlsMessage.hxx"> + </File> + <File + RelativePath=".\ssl\DtlsTransport.hxx"> + </File> + <File + RelativePath=".\Embedded.hxx"> + </File> + <File + RelativePath=".\EventStackThread.hxx"> + </File> + <File + RelativePath=".\ExistsOrDataParameter.hxx"> + </File> + <File + RelativePath=".\ExistsParameter.hxx"> + </File> + <File + RelativePath=".\ExpiresCategory.hxx"> + </File> + <File + RelativePath=".\ExtensionHeader.hxx"> + </File> + <File + RelativePath=".\ExtensionParameter.hxx"> + </File> + <File + RelativePath=".\ExternalBodyContents.hxx"> + </File> + <File + RelativePath=".\GenericContents.hxx"> + </File> + <File + RelativePath=".\GenericUri.hxx"> + </File> + <File + RelativePath=".\HeaderFieldValue.hxx"> + </File> + <File + RelativePath=".\HeaderFieldValueList.hxx"> + </File> + <File + RelativePath=".\HeaderHash.hxx"> + </File> + <File + RelativePath=".\Headers.hxx"> + </File> + <File + RelativePath=".\HeaderTypes.hxx"> + </File> + <File + RelativePath=".\Helper.hxx"> + </File> + <File + RelativePath=".\IntegerCategory.hxx"> + </File> + <File + RelativePath=".\IntegerParameter.hxx"> + </File> + <File + RelativePath=".\InternalTransport.hxx"> + </File> + <File + RelativePath=".\InteropHelper.hxx"> + </File> + <File + RelativePath=".\InterruptableStackThread.hxx"> + </File> + <File + RelativePath=".\InvalidContents.hxx"> + </File> + <File + RelativePath=".\KeepAliveMessage.hxx"> + </File> + <File + RelativePath=".\LazyParser.hxx"> + </File> + <File + RelativePath=".\MarkListener.hxx"> + </File> + <File + RelativePath=".\Message.hxx"> + </File> + <File + RelativePath=".\MessageFilterRule.hxx"> + </File> + <File + RelativePath=".\MessageWaitingContents.hxx"> + </File> + <File + RelativePath=".\MethodHash.hxx"> + </File> + <File + RelativePath=".\MethodTypes.hxx"> + </File> + <File + RelativePath=".\Mime.hxx"> + </File> + <File + RelativePath=".\MsgHeaderScanner.hxx"> + </File> + <File + RelativePath=".\MultipartAlternativeContents.hxx"> + </File> + <File + RelativePath=".\MultipartMixedContents.hxx"> + </File> + <File + RelativePath=".\MultipartRelatedContents.hxx"> + </File> + <File + RelativePath=".\MultipartSignedContents.hxx"> + </File> + <File + RelativePath=".\NameAddr.hxx"> + </File> + <File + RelativePath=".\NonceHelper.hxx"> + </File> + <File + RelativePath=".\OctetContents.hxx"> + </File> + <File + RelativePath=".\Parameter.hxx"> + </File> + <File + RelativePath=".\ParameterHash.hxx"> + </File> + <File + RelativePath=".\ParameterTypeEnums.hxx"> + </File> + <File + RelativePath=".\ParameterTypes.hxx"> + </File> + <File + RelativePath=".\ParserCategories.hxx"> + </File> + <File + RelativePath=".\ParserCategory.hxx"> + </File> + <File + RelativePath=".\ParserContainer.hxx"> + </File> + <File + RelativePath=".\ParserContainerBase.hxx"> + </File> + <File + RelativePath=".\Pidf.hxx"> + </File> + <File + RelativePath=".\Pkcs7Contents.hxx"> + </File> + <File + RelativePath=".\Pkcs8Contents.hxx"> + </File> + <File + RelativePath=".\PlainContents.hxx"> + </File> + <File + RelativePath=".\PrivacyCategory.hxx"> + </File> + <File + RelativePath=".\QuotedDataParameter.hxx"> + </File> + <File + RelativePath=".\QValue.hxx"> + </File> + <File + RelativePath=".\QValueParameter.hxx"> + </File> + <File + RelativePath=".\RAckCategory.hxx"> + </File> + <File + RelativePath=".\RequestLine.hxx"> + </File> + <File + RelativePath=".\Rlmi.hxx"> + </File> + <File + RelativePath=".\RportParameter.hxx"> + </File> + <File + RelativePath=".\SdpContents.hxx"> + </File> + <File + RelativePath=".\ssl\Security.hxx"> + </File> + <File + RelativePath=".\SecurityAttributes.hxx"> + </File> + <File + RelativePath=".\SecurityTypes.hxx"> + </File> + <File + RelativePath=".\SelectInterruptor.hxx"> + </File> + <File + RelativePath=".\SendData.hxx"> + </File> + <File + RelativePath=".\SERNonceHelper.hxx"> + </File> + <File + RelativePath=".\ShutdownMessage.hxx"> + </File> + <File + RelativePath=".\SipFrag.hxx"> + </File> + <File + RelativePath=".\SipMessage.hxx"> + </File> + <File + RelativePath=".\SipStack.hxx"> + </File> + <File + RelativePath=".\StackThread.hxx"> + </File> + <File + RelativePath=".\StatisticsHandler.hxx"> + </File> + <File + RelativePath=".\StatisticsManager.hxx"> + </File> + <File + RelativePath=".\StatisticsMessage.hxx"> + </File> + <File + RelativePath=".\StatusLine.hxx"> + </File> + <File + RelativePath=".\StringCategory.hxx"> + </File> + <File + RelativePath=".\Symbols.hxx"> + </File> + <File + RelativePath=".\TcpBaseTransport.hxx"> + </File> + <File + RelativePath=".\TcpConnection.hxx"> + </File> + <File + RelativePath=".\TcpTransport.hxx"> + </File> + <File + RelativePath=".\TimeAccumulate.hxx"> + </File> + <File + RelativePath=".\TimerMessage.hxx"> + </File> + <File + RelativePath=".\TimerQueue.hxx"> + </File> + <File + RelativePath=".\ssl\TlsConnection.hxx"> + </File> + <File + RelativePath=".\ssl\TlsTransport.hxx"> + </File> + <File + RelativePath=".\Token.hxx"> + </File> + <File + RelativePath=".\TransactionController.hxx"> + </File> + <File + RelativePath=".\TransactionMap.hxx"> + </File> + <File + RelativePath=".\TransactionMessage.hxx"> + </File> + <File + RelativePath=".\TransactionState.hxx"> + </File> + <File + RelativePath=".\TransactionTerminated.hxx"> + </File> + <File + RelativePath=".\TransactionUser.hxx"> + </File> + <File + RelativePath=".\TransactionUserMessage.hxx"> + </File> + <File + RelativePath=".\Transport.hxx"> + </File> + <File + RelativePath=".\TransportFailure.hxx"> + </File> + <File + RelativePath=".\TransportSelector.hxx"> + </File> + <File + RelativePath=".\TuIM.hxx"> + </File> + <File + RelativePath=".\Tuple.hxx"> + </File> + <File + RelativePath=".\TupleMarkManager.hxx"> + </File> + <File + RelativePath=".\TuSelector.hxx"> + </File> + <File + RelativePath=".\UdpTransport.hxx"> + </File> + <File + RelativePath=".\UInt32Category.hxx"> + </File> + <File + RelativePath=".\UInt32Parameter.hxx"> + </File> + <File + RelativePath=".\UnknownHeaderType.hxx"> + </File> + <File + RelativePath=".\UnknownParameter.hxx"> + </File> + <File + RelativePath=".\UnknownParameterType.hxx"> + </File> + <File + RelativePath=".\Uri.hxx"> + </File> + <File + RelativePath=".\ValueFifo.hxx"> + </File> + <File + RelativePath=".\Via.hxx"> + </File> + <File + RelativePath=".\WarningCategory.hxx"> + </File> + <File + RelativePath=".\ssl\WinSecurity.hxx"> + </File> + <File + RelativePath=".\X509Contents.hxx"> + </File> + <File + RelativePath=".\XMLCursor.hxx"> + </File> + </Filter> + <Filter + Name="GPerfFiles" + Filter=""> + <File + RelativePath=".\HeaderHash.gperf"> + </File> + <File + RelativePath=".\MethodHash.gperf"> + </File> + <File + RelativePath=".\ParameterHash.gperf"> + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/stack/resiprocate_8_0.vcproj b/src/libs/resiprocate/resip/stack/resiprocate_8_0.vcproj new file mode 100644 index 00000000..0f6c7367 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/resiprocate_8_0.vcproj @@ -0,0 +1,1490 @@ +<?xml version="1.0" encoding="UTF-8"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="resiprocate" + ProjectGUID="{2A8BE839-6466-4001-B224-8F1C3168D04A}" + RootNamespace="resiprocate" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6" + StringPooling="true" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="SSL-Debug" + IntermediateDirectory="SSL-Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="SSL-Release" + IntermediateDirectory="SSL-Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300" + Optimization="2" + InlineFunctionExpansion="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6" + StringPooling="true" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath=".\Aor.cxx" + > + </File> + <File + RelativePath=".\ApiCheck.cxx" + > + </File> + <File + RelativePath=".\ApplicationSip.cxx" + > + </File> + <File + RelativePath=".\Auth.cxx" + > + </File> + <File + RelativePath=".\BasicNonceHelper.cxx" + > + </File> + <File + RelativePath=".\BranchParameter.cxx" + > + </File> + <File + RelativePath=".\CallId.cxx" + > + </File> + <File + RelativePath=".\Compression.cxx" + > + </File> + <File + RelativePath=".\Connection.cxx" + > + </File> + <File + RelativePath=".\ConnectionBase.cxx" + > + </File> + <File + RelativePath=".\ConnectionManager.cxx" + > + </File> + <File + RelativePath=".\Contents.cxx" + > + </File> + <File + RelativePath=".\ContentsFactoryBase.cxx" + > + </File> + <File + RelativePath=".\CpimContents.cxx" + > + </File> + <File + RelativePath=".\CSeqCategory.cxx" + > + </File> + <File + RelativePath=".\DataParameter.cxx" + > + </File> + <File + RelativePath=".\DateCategory.cxx" + > + </File> + <File + RelativePath=".\DeprecatedDialog.cxx" + > + </File> + <File + RelativePath=".\DnsInterface.cxx" + > + </File> + <File + RelativePath=".\DnsResult.cxx" + > + </File> + <File + RelativePath=".\DtlsMessage.cxx" + > + </File> + <File + RelativePath=".\ssl\DtlsTransport.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\Embedded.cxx" + > + </File> + <File + RelativePath=".\EventStackThread.cxx" + > + </File> + <File + RelativePath=".\ExistsOrDataParameter.cxx" + > + </File> + <File + RelativePath=".\ExistsParameter.cxx" + > + </File> + <File + RelativePath=".\ExpiresCategory.cxx" + > + </File> + <File + RelativePath=".\ExtensionHeader.cxx" + > + </File> + <File + RelativePath=".\ExtensionParameter.cxx" + > + </File> + <File + RelativePath=".\ExternalBodyContents.cxx" + > + </File> + <File + RelativePath=".\GenericContents.cxx" + > + </File> + <File + RelativePath=".\GenericUri.cxx" + > + </File> + <File + RelativePath=".\HeaderFieldValue.cxx" + > + </File> + <File + RelativePath=".\HeaderFieldValueList.cxx" + > + </File> + <File + RelativePath=".\HeaderHash.cxx" + > + </File> + <File + RelativePath=".\Headers.cxx" + > + </File> + <File + RelativePath=".\HeaderTypes.cxx" + > + </File> + <File + RelativePath=".\Helper.cxx" + > + </File> + <File + RelativePath=".\IntegerCategory.cxx" + > + </File> + <File + RelativePath=".\IntegerParameter.cxx" + > + </File> + <File + RelativePath=".\InternalTransport.cxx" + > + </File> + <File + RelativePath=".\InteropHelper.cxx" + > + </File> + <File + RelativePath=".\InterruptableStackThread.cxx" + > + </File> + <File + RelativePath=".\InvalidContents.cxx" + > + </File> + <File + RelativePath=".\KeepAliveMessage.cxx" + > + </File> + <File + RelativePath=".\LazyParser.cxx" + > + </File> + <File + RelativePath=".\Message.cxx" + > + </File> + <File + RelativePath=".\MessageFilterRule.cxx" + > + </File> + <File + RelativePath=".\MessageWaitingContents.cxx" + > + </File> + <File + RelativePath=".\MethodHash.cxx" + > + </File> + <File + RelativePath=".\MethodTypes.cxx" + > + </File> + <File + RelativePath=".\Mime.cxx" + > + </File> + <File + RelativePath=".\MsgHeaderScanner.cxx" + > + </File> + <File + RelativePath=".\MultipartAlternativeContents.cxx" + > + </File> + <File + RelativePath=".\MultipartMixedContents.cxx" + > + </File> + <File + RelativePath=".\MultipartRelatedContents.cxx" + > + </File> + <File + RelativePath=".\MultipartSignedContents.cxx" + > + </File> + <File + RelativePath=".\NameAddr.cxx" + > + </File> + <File + RelativePath=".\NonceHelper.cxx" + > + </File> + <File + RelativePath=".\OctetContents.cxx" + > + </File> + <File + RelativePath=".\Parameter.cxx" + > + </File> + <File + RelativePath=".\ParameterHash.cxx" + > + </File> + <File + RelativePath=".\ParameterTypes.cxx" + > + </File> + <File + RelativePath=".\ParserCategories.cxx" + > + </File> + <File + RelativePath=".\ParserCategory.cxx" + > + </File> + <File + RelativePath=".\ParserContainerBase.cxx" + > + </File> + <File + RelativePath=".\Pidf.cxx" + > + </File> + <File + RelativePath=".\Pkcs7Contents.cxx" + > + </File> + <File + RelativePath=".\Pkcs8Contents.cxx" + > + </File> + <File + RelativePath=".\PlainContents.cxx" + > + </File> + <File + RelativePath=".\PrivacyCategory.cxx" + > + </File> + <File + RelativePath=".\QuotedDataParameter.cxx" + > + </File> + <File + RelativePath=".\QValue.cxx" + > + </File> + <File + RelativePath=".\QValueParameter.cxx" + > + </File> + <File + RelativePath=".\RAckCategory.cxx" + > + </File> + <File + RelativePath=".\RequestLine.cxx" + > + </File> + <File + RelativePath=".\Rlmi.cxx" + > + </File> + <File + RelativePath=".\RportParameter.cxx" + > + </File> + <File + RelativePath=".\SdpContents.cxx" + > + </File> + <File + RelativePath=".\ssl\Security.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\SecurityAttributes.cxx" + > + </File> + <File + RelativePath=".\SERNonceHelper.cxx" + > + </File> + <File + RelativePath=".\SipFrag.cxx" + > + </File> + <File + RelativePath=".\SipMessage.cxx" + > + </File> + <File + RelativePath=".\SipStack.cxx" + > + </File> + <File + RelativePath=".\StackThread.cxx" + > + </File> + <File + RelativePath=".\StatelessHandler.cxx" + > + </File> + <File + RelativePath=".\StatisticsHandler.cxx" + > + </File> + <File + RelativePath=".\StatisticsManager.cxx" + > + </File> + <File + RelativePath=".\StatisticsMessage.cxx" + > + </File> + <File + RelativePath=".\StatusLine.cxx" + > + </File> + <File + RelativePath=".\StringCategory.cxx" + > + </File> + <File + RelativePath=".\Symbols.cxx" + > + </File> + <File + RelativePath=".\TcpBaseTransport.cxx" + > + </File> + <File + RelativePath=".\TcpConnection.cxx" + > + </File> + <File + RelativePath=".\TcpTransport.cxx" + > + </File> + <File + RelativePath=".\TimeAccumulate.cxx" + > + </File> + <File + RelativePath=".\TimerMessage.cxx" + > + </File> + <File + RelativePath=".\TimerQueue.cxx" + > + </File> + <File + RelativePath=".\ssl\TlsConnection.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\ssl\TlsTransport.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\Token.cxx" + > + </File> + <File + RelativePath=".\TransactionController.cxx" + > + </File> + <File + RelativePath=".\TransactionMap.cxx" + > + </File> + <File + RelativePath=".\TransactionState.cxx" + > + </File> + <File + RelativePath=".\TransactionUser.cxx" + > + </File> + <File + RelativePath=".\TransactionUserMessage.cxx" + > + </File> + <File + RelativePath=".\Transport.cxx" + > + </File> + <File + RelativePath=".\TransportFailure.cxx" + > + </File> + <File + RelativePath=".\TransportSelector.cxx" + > + </File> + <File + RelativePath=".\TransportThread.cxx" + > + </File> + <File + RelativePath=".\TuIM.cxx" + > + </File> + <File + RelativePath=".\Tuple.cxx" + > + </File> + <File + RelativePath=".\TupleMarkManager.cxx" + > + </File> + <File + RelativePath=".\TuSelector.cxx" + > + </File> + <File + RelativePath=".\UdpTransport.cxx" + > + </File> + <File + RelativePath=".\UInt32Category.cxx" + > + </File> + <File + RelativePath=".\UInt32Parameter.cxx" + > + </File> + <File + RelativePath=".\UnknownParameter.cxx" + > + </File> + <File + RelativePath=".\Uri.cxx" + > + </File> + <File + RelativePath=".\Via.cxx" + > + </File> + <File + RelativePath=".\WarningCategory.cxx" + > + </File> + <File + RelativePath=".\ssl\WinSecurity.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\X509Contents.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + <File + RelativePath=".\Aor.hxx" + > + </File> + <File + RelativePath=".\ApiCheck.hxx" + > + </File> + <File + RelativePath=".\ApiCheckList.hxx" + > + </File> + <File + RelativePath=".\ApplicationMessage.hxx" + > + </File> + <File + RelativePath=".\ApplicationSip.hxx" + > + </File> + <File + RelativePath=".\Auth.hxx" + > + </File> + <File + RelativePath=".\BasicNonceHelper.hxx" + > + </File> + <File + RelativePath=".\BranchParameter.hxx" + > + </File> + <File + RelativePath=".\CallId.hxx" + > + </File> + <File + RelativePath=".\CancelableTimerQueue.hxx" + > + </File> + <File + RelativePath=".\Compression.hxx" + > + </File> + <File + RelativePath=".\Connection.hxx" + > + </File> + <File + RelativePath=".\ConnectionBase.hxx" + > + </File> + <File + RelativePath=".\ConnectionManager.hxx" + > + </File> + <File + RelativePath=".\Contents.hxx" + > + </File> + <File + RelativePath=".\ContentsFactory.hxx" + > + </File> + <File + RelativePath=".\ContentsFactoryBase.hxx" + > + </File> + <File + RelativePath=".\CpimContents.hxx" + > + </File> + <File + RelativePath=".\CSeqCategory.hxx" + > + </File> + <File + RelativePath=".\DataParameter.hxx" + > + </File> + <File + RelativePath=".\DateCategory.hxx" + > + </File> + <File + RelativePath=".\DeprecatedDialog.hxx" + > + </File> + <File + RelativePath=".\DnsInterface.hxx" + > + </File> + <File + RelativePath=".\DnsResult.hxx" + > + </File> + <File + RelativePath=".\DnsResultMessage.hxx" + > + </File> + <File + RelativePath=".\DtlsMessage.hxx" + > + </File> + <File + RelativePath=".\ssl\DtlsTransport.hxx" + > + </File> + <File + RelativePath=".\Embedded.hxx" + > + </File> + <File + RelativePath=".\EventStackThread.hxx" + > + </File> + <File + RelativePath=".\ExistsOrDataParameter.hxx" + > + </File> + <File + RelativePath=".\ExistsParameter.hxx" + > + </File> + <File + RelativePath=".\ExpiresCategory.hxx" + > + </File> + <File + RelativePath=".\ExtensionHeader.hxx" + > + </File> + <File + RelativePath=".\ExtensionParameter.hxx" + > + </File> + <File + RelativePath=".\ExternalBodyContents.hxx" + > + </File> + <File + RelativePath=".\GenericContents.hxx" + > + </File> + <File + RelativePath=".\GenericUri.hxx" + > + </File> + <File + RelativePath=".\HeaderFieldValue.hxx" + > + </File> + <File + RelativePath=".\HeaderFieldValueList.hxx" + > + </File> + <File + RelativePath=".\HeaderHash.hxx" + > + </File> + <File + RelativePath=".\Headers.hxx" + > + </File> + <File + RelativePath=".\HeaderTypes.hxx" + > + </File> + <File + RelativePath=".\Helper.hxx" + > + </File> + <File + RelativePath=".\IntegerCategory.hxx" + > + </File> + <File + RelativePath=".\IntegerParameter.hxx" + > + </File> + <File + RelativePath=".\InternalTransport.hxx" + > + </File> + <File + RelativePath=".\InteropHelper.hxx" + > + </File> + <File + RelativePath=".\InterruptableStackThread.hxx" + > + </File> + <File + RelativePath=".\InvalidContents.hxx" + > + </File> + <File + RelativePath=".\KeepAliveMessage.hxx" + > + </File> + <File + RelativePath=".\LazyParser.hxx" + > + </File> + <File + RelativePath=".\MarkListener.hxx" + > + </File> + <File + RelativePath=".\Message.hxx" + > + </File> + <File + RelativePath=".\MessageFilterRule.hxx" + > + </File> + <File + RelativePath=".\MessageWaitingContents.hxx" + > + </File> + <File + RelativePath=".\MethodHash.hxx" + > + </File> + <File + RelativePath=".\MethodTypes.hxx" + > + </File> + <File + RelativePath=".\Mime.hxx" + > + </File> + <File + RelativePath=".\MsgHeaderScanner.hxx" + > + </File> + <File + RelativePath=".\MultipartAlternativeContents.hxx" + > + </File> + <File + RelativePath=".\MultipartMixedContents.hxx" + > + </File> + <File + RelativePath=".\MultipartRelatedContents.hxx" + > + </File> + <File + RelativePath=".\MultipartSignedContents.hxx" + > + </File> + <File + RelativePath=".\NameAddr.hxx" + > + </File> + <File + RelativePath=".\NonceHelper.hxx" + > + </File> + <File + RelativePath=".\OctetContents.hxx" + > + </File> + <File + RelativePath=".\Parameter.hxx" + > + </File> + <File + RelativePath=".\ParameterHash.hxx" + > + </File> + <File + RelativePath=".\ParameterTypeEnums.hxx" + > + </File> + <File + RelativePath=".\ParameterTypes.hxx" + > + </File> + <File + RelativePath=".\ParserCategories.hxx" + > + </File> + <File + RelativePath=".\ParserCategory.hxx" + > + </File> + <File + RelativePath=".\ParserContainer.hxx" + > + </File> + <File + RelativePath=".\ParserContainerBase.hxx" + > + </File> + <File + RelativePath=".\Pidf.hxx" + > + </File> + <File + RelativePath=".\Pkcs7Contents.hxx" + > + </File> + <File + RelativePath=".\Pkcs8Contents.hxx" + > + </File> + <File + RelativePath=".\PlainContents.hxx" + > + </File> + <File + RelativePath=".\PollStatistics.hxx" + > + </File> + <File + RelativePath=".\PrivacyCategory.hxx" + > + </File> + <File + RelativePath=".\QuotedDataParameter.hxx" + > + </File> + <File + RelativePath=".\QValue.hxx" + > + </File> + <File + RelativePath=".\QValueParameter.hxx" + > + </File> + <File + RelativePath=".\RAckCategory.hxx" + > + </File> + <File + RelativePath=".\RequestLine.hxx" + > + </File> + <File + RelativePath=".\Rlmi.hxx" + > + </File> + <File + RelativePath=".\RportParameter.hxx" + > + </File> + <File + RelativePath=".\SdpContents.hxx" + > + </File> + <File + RelativePath=".\ssl\Security.hxx" + > + </File> + <File + RelativePath=".\SecurityAttributes.hxx" + > + </File> + <File + RelativePath=".\SecurityTypes.hxx" + > + </File> + <File + RelativePath=".\SendData.hxx" + > + </File> + <File + RelativePath=".\SERNonceHelper.hxx" + > + </File> + <File + RelativePath=".\ShutdownMessage.hxx" + > + </File> + <File + RelativePath=".\SipFrag.hxx" + > + </File> + <File + RelativePath=".\SipMessage.hxx" + > + </File> + <File + RelativePath=".\SipStack.hxx" + > + </File> + <File + RelativePath=".\StackThread.hxx" + > + </File> + <File + RelativePath=".\StartLine.hxx" + > + </File> + <File + RelativePath=".\StatelessHandler.hxx" + > + </File> + <File + RelativePath=".\StatisticsHandler.hxx" + > + </File> + <File + RelativePath=".\StatisticsManager.hxx" + > + </File> + <File + RelativePath=".\StatisticsMessage.hxx" + > + </File> + <File + RelativePath=".\StatusLine.hxx" + > + </File> + <File + RelativePath=".\StringCategory.hxx" + > + </File> + <File + RelativePath=".\Symbols.hxx" + > + </File> + <File + RelativePath=".\TcpBaseTransport.hxx" + > + </File> + <File + RelativePath=".\TcpConnection.hxx" + > + </File> + <File + RelativePath=".\TcpTransport.hxx" + > + </File> + <File + RelativePath=".\TextParameter.hxx" + > + </File> + <File + RelativePath=".\TimeAccumulate.hxx" + > + </File> + <File + RelativePath=".\TimerMessage.hxx" + > + </File> + <File + RelativePath=".\TimerQueue.hxx" + > + </File> + <File + RelativePath=".\ssl\TlsConnection.hxx" + > + </File> + <File + RelativePath=".\ssl\TlsTransport.hxx" + > + </File> + <File + RelativePath=".\Token.hxx" + > + </File> + <File + RelativePath=".\TransactionController.hxx" + > + </File> + <File + RelativePath=".\TransactionControllerThread.hxx" + > + </File> + <File + RelativePath=".\TransactionMap.hxx" + > + </File> + <File + RelativePath=".\TransactionMessage.hxx" + > + </File> + <File + RelativePath=".\TransactionState.hxx" + > + </File> + <File + RelativePath=".\TransactionTerminated.hxx" + > + </File> + <File + RelativePath=".\TransactionUser.hxx" + > + </File> + <File + RelativePath=".\TransactionUserMessage.hxx" + > + </File> + <File + RelativePath=".\Transport.hxx" + > + </File> + <File + RelativePath=".\TransportFailure.hxx" + > + </File> + <File + RelativePath=".\TransportSelector.hxx" + > + </File> + <File + RelativePath=".\TransportSelectorThread.hxx" + > + </File> + <File + RelativePath=".\TransportThread.hxx" + > + </File> + <File + RelativePath=".\TuIM.hxx" + > + </File> + <File + RelativePath=".\Tuple.hxx" + > + </File> + <File + RelativePath=".\TupleMarkManager.hxx" + > + </File> + <File + RelativePath=".\TuSelector.hxx" + > + </File> + <File + RelativePath=".\UdpTransport.hxx" + > + </File> + <File + RelativePath=".\UInt32Category.hxx" + > + </File> + <File + RelativePath=".\UInt32Parameter.hxx" + > + </File> + <File + RelativePath=".\UnknownHeaderType.hxx" + > + </File> + <File + RelativePath=".\UnknownParameter.hxx" + > + </File> + <File + RelativePath=".\UnknownParameterType.hxx" + > + </File> + <File + RelativePath=".\Uri.hxx" + > + </File> + <File + RelativePath=".\ValueFifo.hxx" + > + </File> + <File + RelativePath=".\Via.hxx" + > + </File> + <File + RelativePath=".\WarningCategory.hxx" + > + </File> + <File + RelativePath=".\ssl\WinSecurity.hxx" + > + </File> + <File + RelativePath=".\X509Contents.hxx" + > + </File> + <File + RelativePath=".\ZeroOutStatistics.hxx" + > + </File> + </Filter> + <Filter + Name="GPerfFiles" + > + <File + RelativePath=".\HeaderHash.gperf" + > + </File> + <File + RelativePath=".\MethodHash.gperf" + > + </File> + <File + RelativePath=".\ParameterHash.gperf" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcproj b/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcproj new file mode 100644 index 00000000..9c6e8447 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcproj @@ -0,0 +1,1509 @@ +<?xml version="1.0" encoding="UTF-8"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="resiprocate" + ProjectGUID="{2A8BE839-6466-4001-B224-8F1C3168D04A}" + RootNamespace="resiprocate" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300 /MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;USE_SSL" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300 /MP" + Optimization="2" + InlineFunctionExpansion="1" + FavorSizeOrSpeed="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL" + StringPooling="true" + MinimalRebuild="false" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="SSL-Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300 /MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../../openssl/include&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="SSL-Release" + IntermediateDirectory="SSL-Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm300 /MP" + Optimization="2" + InlineFunctionExpansion="1" + OmitFramePointers="false" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../../&quot;;&quot;$(ProjectDir)../../../openssl/include&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6" + StringPooling="true" + MinimalRebuild="false" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/resiprocate.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" + > + <File + RelativePath=".\Aor.cxx" + > + </File> + <File + RelativePath=".\ApiCheck.cxx" + > + </File> + <File + RelativePath=".\ApplicationSip.cxx" + > + </File> + <File + RelativePath=".\Auth.cxx" + > + </File> + <File + RelativePath=".\BasicNonceHelper.cxx" + > + </File> + <File + RelativePath=".\BranchParameter.cxx" + > + </File> + <File + RelativePath=".\CallId.cxx" + > + </File> + <File + RelativePath=".\Compression.cxx" + > + </File> + <File + RelativePath=".\Connection.cxx" + > + </File> + <File + RelativePath=".\ConnectionBase.cxx" + > + </File> + <File + RelativePath=".\ConnectionManager.cxx" + > + </File> + <File + RelativePath=".\Contents.cxx" + > + </File> + <File + RelativePath=".\ContentsFactoryBase.cxx" + > + </File> + <File + RelativePath=".\CpimContents.cxx" + > + </File> + <File + RelativePath=".\CSeqCategory.cxx" + > + </File> + <File + RelativePath=".\DataParameter.cxx" + > + </File> + <File + RelativePath=".\DateCategory.cxx" + > + </File> + <File + RelativePath=".\DeprecatedDialog.cxx" + > + </File> + <File + RelativePath=".\DnsInterface.cxx" + > + </File> + <File + RelativePath=".\DnsResult.cxx" + > + </File> + <File + RelativePath=".\DtlsMessage.cxx" + > + </File> + <File + RelativePath=".\ssl\DtlsTransport.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\Embedded.cxx" + > + </File> + <File + RelativePath=".\EventStackThread.cxx" + > + </File> + <File + RelativePath=".\ExistsOrDataParameter.cxx" + > + </File> + <File + RelativePath=".\ExistsParameter.cxx" + > + </File> + <File + RelativePath=".\ExpiresCategory.cxx" + > + </File> + <File + RelativePath=".\ExtensionHeader.cxx" + > + </File> + <File + RelativePath=".\ExtensionParameter.cxx" + > + </File> + <File + RelativePath=".\ExternalBodyContents.cxx" + > + </File> + <File + RelativePath=".\GenericContents.cxx" + > + </File> + <File + RelativePath=".\GenericUri.cxx" + > + </File> + <File + RelativePath=".\HeaderFieldValue.cxx" + > + </File> + <File + RelativePath=".\HeaderFieldValueList.cxx" + > + </File> + <File + RelativePath=".\HeaderHash.cxx" + > + </File> + <File + RelativePath=".\Headers.cxx" + > + </File> + <File + RelativePath=".\HeaderTypes.cxx" + > + </File> + <File + RelativePath=".\Helper.cxx" + > + </File> + <File + RelativePath=".\IntegerCategory.cxx" + > + </File> + <File + RelativePath=".\IntegerParameter.cxx" + > + </File> + <File + RelativePath=".\InternalTransport.cxx" + > + </File> + <File + RelativePath=".\InteropHelper.cxx" + > + </File> + <File + RelativePath=".\InterruptableStackThread.cxx" + > + </File> + <File + RelativePath=".\InvalidContents.cxx" + > + </File> + <File + RelativePath=".\KeepAliveMessage.cxx" + > + </File> + <File + RelativePath=".\LazyParser.cxx" + > + </File> + <File + RelativePath=".\Message.cxx" + > + </File> + <File + RelativePath=".\MessageFilterRule.cxx" + > + </File> + <File + RelativePath=".\MessageWaitingContents.cxx" + > + </File> + <File + RelativePath=".\MethodHash.cxx" + > + </File> + <File + RelativePath=".\MethodTypes.cxx" + > + </File> + <File + RelativePath=".\Mime.cxx" + > + </File> + <File + RelativePath=".\MsgHeaderScanner.cxx" + > + </File> + <File + RelativePath=".\MultipartAlternativeContents.cxx" + > + </File> + <File + RelativePath=".\MultipartMixedContents.cxx" + > + </File> + <File + RelativePath=".\MultipartRelatedContents.cxx" + > + </File> + <File + RelativePath=".\MultipartSignedContents.cxx" + > + </File> + <File + RelativePath=".\NameAddr.cxx" + > + </File> + <File + RelativePath=".\NonceHelper.cxx" + > + </File> + <File + RelativePath=".\OctetContents.cxx" + > + </File> + <File + RelativePath=".\Parameter.cxx" + > + </File> + <File + RelativePath=".\ParameterHash.cxx" + > + </File> + <File + RelativePath=".\ParameterTypes.cxx" + > + </File> + <File + RelativePath=".\ParserCategories.cxx" + > + </File> + <File + RelativePath=".\ParserCategory.cxx" + > + </File> + <File + RelativePath=".\ParserContainerBase.cxx" + > + </File> + <File + RelativePath=".\Pidf.cxx" + > + </File> + <File + RelativePath=".\Pkcs7Contents.cxx" + > + </File> + <File + RelativePath=".\Pkcs8Contents.cxx" + > + </File> + <File + RelativePath=".\PlainContents.cxx" + > + </File> + <File + RelativePath=".\PrivacyCategory.cxx" + > + </File> + <File + RelativePath=".\QuotedDataParameter.cxx" + > + </File> + <File + RelativePath=".\QValue.cxx" + > + </File> + <File + RelativePath=".\QValueParameter.cxx" + > + </File> + <File + RelativePath=".\RAckCategory.cxx" + > + </File> + <File + RelativePath=".\RequestLine.cxx" + > + </File> + <File + RelativePath=".\Rlmi.cxx" + > + </File> + <File + RelativePath=".\RportParameter.cxx" + > + </File> + <File + RelativePath=".\SdpContents.cxx" + > + </File> + <File + RelativePath=".\ssl\Security.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\SecurityAttributes.cxx" + > + </File> + <File + RelativePath=".\SERNonceHelper.cxx" + > + </File> + <File + RelativePath=".\SipFrag.cxx" + > + </File> + <File + RelativePath=".\SipMessage.cxx" + > + </File> + <File + RelativePath=".\SipStack.cxx" + > + </File> + <File + RelativePath=".\StackThread.cxx" + > + </File> + <File + RelativePath=".\StatelessHandler.cxx" + > + </File> + <File + RelativePath=".\StatisticsHandler.cxx" + > + </File> + <File + RelativePath=".\StatisticsManager.cxx" + > + </File> + <File + RelativePath=".\StatisticsMessage.cxx" + > + </File> + <File + RelativePath=".\StatusLine.cxx" + > + </File> + <File + RelativePath=".\StringCategory.cxx" + > + </File> + <File + RelativePath=".\Symbols.cxx" + > + </File> + <File + RelativePath=".\TcpBaseTransport.cxx" + > + </File> + <File + RelativePath=".\TcpConnection.cxx" + > + </File> + <File + RelativePath=".\TcpTransport.cxx" + > + </File> + <File + RelativePath=".\TimeAccumulate.cxx" + > + </File> + <File + RelativePath=".\TimerMessage.cxx" + > + </File> + <File + RelativePath=".\TimerQueue.cxx" + > + </File> + <File + RelativePath=".\ssl\TlsConnection.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\ssl\TlsTransport.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\Token.cxx" + > + </File> + <File + RelativePath=".\TransactionController.cxx" + > + </File> + <File + RelativePath=".\TransactionMap.cxx" + > + </File> + <File + RelativePath=".\TransactionState.cxx" + > + </File> + <File + RelativePath=".\TransactionUser.cxx" + > + </File> + <File + RelativePath=".\TransactionUserMessage.cxx" + > + </File> + <File + RelativePath=".\Transport.cxx" + > + </File> + <File + RelativePath=".\TransportFailure.cxx" + > + </File> + <File + RelativePath=".\TransportSelector.cxx" + > + </File> + <File + RelativePath=".\TransportThread.cxx" + > + </File> + <File + RelativePath=".\TuIM.cxx" + > + </File> + <File + RelativePath=".\Tuple.cxx" + > + </File> + <File + RelativePath=".\TupleMarkManager.cxx" + > + </File> + <File + RelativePath=".\TuSelector.cxx" + > + </File> + <File + RelativePath=".\UdpTransport.cxx" + > + </File> + <File + RelativePath=".\UInt32Category.cxx" + > + </File> + <File + RelativePath=".\UInt32Parameter.cxx" + > + </File> + <File + RelativePath=".\UnknownParameter.cxx" + > + </File> + <File + RelativePath=".\Uri.cxx" + > + </File> + <File + RelativePath=".\Via.cxx" + > + </File> + <File + RelativePath=".\WarningCategory.cxx" + > + </File> + <File + RelativePath=".\ssl\WinSecurity.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\X509Contents.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc" + > + <File + RelativePath=".\Aor.hxx" + > + </File> + <File + RelativePath=".\ApiCheck.hxx" + > + </File> + <File + RelativePath=".\ApiCheckList.hxx" + > + </File> + <File + RelativePath=".\ApplicationMessage.hxx" + > + </File> + <File + RelativePath=".\ApplicationSip.hxx" + > + </File> + <File + RelativePath=".\Auth.hxx" + > + </File> + <File + RelativePath=".\BasicNonceHelper.hxx" + > + </File> + <File + RelativePath=".\BranchParameter.hxx" + > + </File> + <File + RelativePath=".\CallId.hxx" + > + </File> + <File + RelativePath=".\CancelableTimerQueue.hxx" + > + </File> + <File + RelativePath=".\Compression.hxx" + > + </File> + <File + RelativePath=".\Connection.hxx" + > + </File> + <File + RelativePath=".\ConnectionBase.hxx" + > + </File> + <File + RelativePath=".\ConnectionManager.hxx" + > + </File> + <File + RelativePath=".\ConnectionTerminated.hxx" + > + </File> + <File + RelativePath=".\Contents.hxx" + > + </File> + <File + RelativePath=".\ContentsFactory.hxx" + > + </File> + <File + RelativePath=".\ContentsFactoryBase.hxx" + > + </File> + <File + RelativePath=".\CpimContents.hxx" + > + </File> + <File + RelativePath=".\CSeqCategory.hxx" + > + </File> + <File + RelativePath=".\DataParameter.hxx" + > + </File> + <File + RelativePath=".\DateCategory.hxx" + > + </File> + <File + RelativePath=".\DeprecatedDialog.hxx" + > + </File> + <File + RelativePath=".\DnsInterface.hxx" + > + </File> + <File + RelativePath=".\DnsResult.hxx" + > + </File> + <File + RelativePath=".\DnsResultMessage.hxx" + > + </File> + <File + RelativePath=".\DtlsMessage.hxx" + > + </File> + <File + RelativePath=".\ssl\DtlsTransport.hxx" + > + </File> + <File + RelativePath=".\Embedded.hxx" + > + </File> + <File + RelativePath=".\EnableFlowTimer.hxx" + > + </File> + <File + RelativePath=".\EventStackThread.hxx" + > + </File> + <File + RelativePath=".\ExistsOrDataParameter.hxx" + > + </File> + <File + RelativePath=".\ExistsParameter.hxx" + > + </File> + <File + RelativePath=".\ExpiresCategory.hxx" + > + </File> + <File + RelativePath=".\ExtensionHeader.hxx" + > + </File> + <File + RelativePath=".\ExtensionParameter.hxx" + > + </File> + <File + RelativePath=".\ExternalBodyContents.hxx" + > + </File> + <File + RelativePath=".\GenericContents.hxx" + > + </File> + <File + RelativePath=".\GenericUri.hxx" + > + </File> + <File + RelativePath=".\HeaderFieldValue.hxx" + > + </File> + <File + RelativePath=".\HeaderFieldValueList.hxx" + > + </File> + <File + RelativePath=".\HeaderHash.hxx" + > + </File> + <File + RelativePath=".\Headers.hxx" + > + </File> + <File + RelativePath=".\HeaderTypes.hxx" + > + </File> + <File + RelativePath=".\Helper.hxx" + > + </File> + <File + RelativePath=".\IntegerCategory.hxx" + > + </File> + <File + RelativePath=".\IntegerParameter.hxx" + > + </File> + <File + RelativePath=".\InternalTransport.hxx" + > + </File> + <File + RelativePath=".\InteropHelper.hxx" + > + </File> + <File + RelativePath=".\InterruptableStackThread.hxx" + > + </File> + <File + RelativePath=".\InvalidContents.hxx" + > + </File> + <File + RelativePath=".\KeepAliveMessage.hxx" + > + </File> + <File + RelativePath=".\KeepAlivePong.hxx" + > + </File> + <File + RelativePath=".\LazyParser.hxx" + > + </File> + <File + RelativePath=".\MarkListener.hxx" + > + </File> + <File + RelativePath=".\Message.hxx" + > + </File> + <File + RelativePath=".\MessageFilterRule.hxx" + > + </File> + <File + RelativePath=".\MessageWaitingContents.hxx" + > + </File> + <File + RelativePath=".\MethodHash.hxx" + > + </File> + <File + RelativePath=".\MethodTypes.hxx" + > + </File> + <File + RelativePath=".\Mime.hxx" + > + </File> + <File + RelativePath=".\MsgHeaderScanner.hxx" + > + </File> + <File + RelativePath=".\MultipartAlternativeContents.hxx" + > + </File> + <File + RelativePath=".\MultipartMixedContents.hxx" + > + </File> + <File + RelativePath=".\MultipartRelatedContents.hxx" + > + </File> + <File + RelativePath=".\MultipartSignedContents.hxx" + > + </File> + <File + RelativePath=".\NameAddr.hxx" + > + </File> + <File + RelativePath=".\NonceHelper.hxx" + > + </File> + <File + RelativePath=".\OctetContents.hxx" + > + </File> + <File + RelativePath=".\Parameter.hxx" + > + </File> + <File + RelativePath=".\ParameterHash.hxx" + > + </File> + <File + RelativePath=".\ParameterTypeEnums.hxx" + > + </File> + <File + RelativePath=".\ParameterTypes.hxx" + > + </File> + <File + RelativePath=".\ParserCategories.hxx" + > + </File> + <File + RelativePath=".\ParserCategory.hxx" + > + </File> + <File + RelativePath=".\ParserContainer.hxx" + > + </File> + <File + RelativePath=".\ParserContainerBase.hxx" + > + </File> + <File + RelativePath=".\Pidf.hxx" + > + </File> + <File + RelativePath=".\Pkcs7Contents.hxx" + > + </File> + <File + RelativePath=".\Pkcs8Contents.hxx" + > + </File> + <File + RelativePath=".\PlainContents.hxx" + > + </File> + <File + RelativePath=".\PollStatistics.hxx" + > + </File> + <File + RelativePath=".\PrivacyCategory.hxx" + > + </File> + <File + RelativePath=".\QuotedDataParameter.hxx" + > + </File> + <File + RelativePath=".\QValue.hxx" + > + </File> + <File + RelativePath=".\QValueParameter.hxx" + > + </File> + <File + RelativePath=".\RAckCategory.hxx" + > + </File> + <File + RelativePath=".\RequestLine.hxx" + > + </File> + <File + RelativePath=".\Rlmi.hxx" + > + </File> + <File + RelativePath=".\RportParameter.hxx" + > + </File> + <File + RelativePath=".\SdpContents.hxx" + > + </File> + <File + RelativePath=".\ssl\Security.hxx" + > + </File> + <File + RelativePath=".\SecurityAttributes.hxx" + > + </File> + <File + RelativePath=".\SecurityTypes.hxx" + > + </File> + <File + RelativePath=".\SendData.hxx" + > + </File> + <File + RelativePath=".\SERNonceHelper.hxx" + > + </File> + <File + RelativePath=".\ShutdownMessage.hxx" + > + </File> + <File + RelativePath=".\SipFrag.hxx" + > + </File> + <File + RelativePath=".\SipMessage.hxx" + > + </File> + <File + RelativePath=".\SipStack.hxx" + > + </File> + <File + RelativePath=".\StackThread.hxx" + > + </File> + <File + RelativePath=".\StartLine.hxx" + > + </File> + <File + RelativePath=".\StatelessHandler.hxx" + > + </File> + <File + RelativePath=".\StatisticsHandler.hxx" + > + </File> + <File + RelativePath=".\StatisticsManager.hxx" + > + </File> + <File + RelativePath=".\StatisticsMessage.hxx" + > + </File> + <File + RelativePath=".\StatusLine.hxx" + > + </File> + <File + RelativePath=".\StringCategory.hxx" + > + </File> + <File + RelativePath=".\Symbols.hxx" + > + </File> + <File + RelativePath=".\TcpBaseTransport.hxx" + > + </File> + <File + RelativePath=".\TcpConnection.hxx" + > + </File> + <File + RelativePath=".\TcpTransport.hxx" + > + </File> + <File + RelativePath=".\TerminateFlow.hxx" + > + </File> + <File + RelativePath=".\TextParameter.hxx" + > + </File> + <File + RelativePath=".\TimeAccumulate.hxx" + > + </File> + <File + RelativePath=".\TimerMessage.hxx" + > + </File> + <File + RelativePath=".\TimerQueue.hxx" + > + </File> + <File + RelativePath=".\ssl\TlsConnection.hxx" + > + </File> + <File + RelativePath=".\ssl\TlsTransport.hxx" + > + </File> + <File + RelativePath=".\Token.hxx" + > + </File> + <File + RelativePath=".\TransactionController.hxx" + > + </File> + <File + RelativePath=".\TransactionControllerThread.hxx" + > + </File> + <File + RelativePath=".\TransactionMap.hxx" + > + </File> + <File + RelativePath=".\TransactionMessage.hxx" + > + </File> + <File + RelativePath=".\TransactionState.hxx" + > + </File> + <File + RelativePath=".\TransactionTerminated.hxx" + > + </File> + <File + RelativePath=".\TransactionUser.hxx" + > + </File> + <File + RelativePath=".\TransactionUserMessage.hxx" + > + </File> + <File + RelativePath=".\Transport.hxx" + > + </File> + <File + RelativePath=".\TransportFailure.hxx" + > + </File> + <File + RelativePath=".\TransportSelector.hxx" + > + </File> + <File + RelativePath=".\TransportSelectorThread.hxx" + > + </File> + <File + RelativePath=".\TransportThread.hxx" + > + </File> + <File + RelativePath=".\TuIM.hxx" + > + </File> + <File + RelativePath=".\Tuple.hxx" + > + </File> + <File + RelativePath=".\TupleMarkManager.hxx" + > + </File> + <File + RelativePath=".\TuSelector.hxx" + > + </File> + <File + RelativePath=".\UdpTransport.hxx" + > + </File> + <File + RelativePath=".\UInt32Category.hxx" + > + </File> + <File + RelativePath=".\UInt32Parameter.hxx" + > + </File> + <File + RelativePath=".\UnknownHeaderType.hxx" + > + </File> + <File + RelativePath=".\UnknownParameter.hxx" + > + </File> + <File + RelativePath=".\UnknownParameterType.hxx" + > + </File> + <File + RelativePath=".\Uri.hxx" + > + </File> + <File + RelativePath=".\ValueFifo.hxx" + > + </File> + <File + RelativePath=".\Via.hxx" + > + </File> + <File + RelativePath=".\WarningCategory.hxx" + > + </File> + <File + RelativePath=".\ssl\WinSecurity.hxx" + > + </File> + <File + RelativePath=".\X509Contents.hxx" + > + </File> + <File + RelativePath=".\ZeroOutStatistics.hxx" + > + </File> + </Filter> + <Filter + Name="GPerfFiles" + > + <File + RelativePath=".\HeaderHash.gperf" + > + </File> + <File + RelativePath=".\MethodHash.gperf" + > + </File> + <File + RelativePath=".\ParameterHash.gperf" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj b/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj new file mode 100644 index 00000000..87d2ecd2 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj @@ -0,0 +1,473 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|Win32"> + <Configuration>SSL-Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|Win32"> + <Configuration>SSL-Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>resiprocate</ProjectName> + <ProjectGuid>{2A8BE839-6466-4001-B224-8F1C3168D04A}</ProjectGuid> + <RootNamespace>resiprocate</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <OutDir>$(Configuration)\</OutDir> + <IntDir>SSL-Debug\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <OutDir>SSL-Release\</OutDir> + <IntDir>SSL-Release\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <AdditionalOptions>/Zm300 /MP %(AdditionalOptions)</AdditionalOptions> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;USE_SSL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)resiprocate.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalOptions>/Zm300 /MP %(AdditionalOptions)</AdditionalOptions> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <OmitFramePointers>true</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat /> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)resiprocate.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <ClCompile> + <AdditionalOptions>/Zm300 /MP %(AdditionalOptions)</AdditionalOptions> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../../openssl/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)resiprocate.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <ClCompile> + <AdditionalOptions>/Zm300 /MP %(AdditionalOptions)</AdditionalOptions> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <OmitFramePointers>false</OmitFramePointers> + <AdditionalIncludeDirectories>$(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../../openssl/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)resiprocate.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="Aor.cxx" /> + <ClCompile Include="ApiCheck.cxx" /> + <ClCompile Include="ApplicationSip.cxx" /> + <ClCompile Include="Auth.cxx" /> + <ClCompile Include="BasicNonceHelper.cxx" /> + <ClCompile Include="BranchParameter.cxx" /> + <ClCompile Include="CallId.cxx" /> + <ClCompile Include="Compression.cxx" /> + <ClCompile Include="Connection.cxx" /> + <ClCompile Include="ConnectionBase.cxx" /> + <ClCompile Include="ConnectionManager.cxx" /> + <ClCompile Include="Contents.cxx" /> + <ClCompile Include="ContentsFactoryBase.cxx" /> + <ClCompile Include="CpimContents.cxx" /> + <ClCompile Include="CSeqCategory.cxx" /> + <ClCompile Include="DataParameter.cxx" /> + <ClCompile Include="DateCategory.cxx" /> + <ClCompile Include="DeprecatedDialog.cxx" /> + <ClCompile Include="DnsInterface.cxx" /> + <ClCompile Include="DnsResult.cxx" /> + <ClCompile Include="DtlsMessage.cxx" /> + <ClCompile Include="ssl\DtlsTransport.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="Embedded.cxx" /> + <ClCompile Include="EventStackThread.cxx" /> + <ClCompile Include="ExistsOrDataParameter.cxx" /> + <ClCompile Include="ExistsParameter.cxx" /> + <ClCompile Include="ExpiresCategory.cxx" /> + <ClCompile Include="ExtensionHeader.cxx" /> + <ClCompile Include="ExtensionParameter.cxx" /> + <ClCompile Include="ExternalBodyContents.cxx" /> + <ClCompile Include="GenericContents.cxx" /> + <ClCompile Include="GenericUri.cxx" /> + <ClCompile Include="HeaderFieldValue.cxx" /> + <ClCompile Include="HeaderFieldValueList.cxx" /> + <ClCompile Include="HeaderHash.cxx" /> + <ClCompile Include="Headers.cxx" /> + <ClCompile Include="HeaderTypes.cxx" /> + <ClCompile Include="Helper.cxx" /> + <ClCompile Include="IntegerCategory.cxx" /> + <ClCompile Include="IntegerParameter.cxx" /> + <ClCompile Include="InternalTransport.cxx" /> + <ClCompile Include="InteropHelper.cxx" /> + <ClCompile Include="InterruptableStackThread.cxx" /> + <ClCompile Include="InvalidContents.cxx" /> + <ClCompile Include="KeepAliveMessage.cxx" /> + <ClCompile Include="LazyParser.cxx" /> + <ClCompile Include="Message.cxx" /> + <ClCompile Include="MessageFilterRule.cxx" /> + <ClCompile Include="MessageWaitingContents.cxx" /> + <ClCompile Include="MethodHash.cxx" /> + <ClCompile Include="MethodTypes.cxx" /> + <ClCompile Include="Mime.cxx" /> + <ClCompile Include="MsgHeaderScanner.cxx" /> + <ClCompile Include="MultipartAlternativeContents.cxx" /> + <ClCompile Include="MultipartMixedContents.cxx" /> + <ClCompile Include="MultipartRelatedContents.cxx" /> + <ClCompile Include="MultipartSignedContents.cxx" /> + <ClCompile Include="NameAddr.cxx" /> + <ClCompile Include="NonceHelper.cxx" /> + <ClCompile Include="OctetContents.cxx" /> + <ClCompile Include="Parameter.cxx" /> + <ClCompile Include="ParameterHash.cxx" /> + <ClCompile Include="ParameterTypes.cxx" /> + <ClCompile Include="ParserCategories.cxx" /> + <ClCompile Include="ParserCategory.cxx" /> + <ClCompile Include="ParserContainerBase.cxx" /> + <ClCompile Include="Pidf.cxx" /> + <ClCompile Include="Pkcs7Contents.cxx" /> + <ClCompile Include="Pkcs8Contents.cxx" /> + <ClCompile Include="PlainContents.cxx" /> + <ClCompile Include="PrivacyCategory.cxx" /> + <ClCompile Include="QuotedDataParameter.cxx" /> + <ClCompile Include="QValue.cxx" /> + <ClCompile Include="QValueParameter.cxx" /> + <ClCompile Include="RAckCategory.cxx" /> + <ClCompile Include="RequestLine.cxx" /> + <ClCompile Include="Rlmi.cxx" /> + <ClCompile Include="RportParameter.cxx" /> + <ClCompile Include="SdpContents.cxx" /> + <ClCompile Include="ssl\Security.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="SecurityAttributes.cxx" /> + <ClCompile Include="SERNonceHelper.cxx" /> + <ClCompile Include="SipFrag.cxx" /> + <ClCompile Include="SipMessage.cxx" /> + <ClCompile Include="SipStack.cxx" /> + <ClCompile Include="StackThread.cxx" /> + <ClCompile Include="StatelessHandler.cxx" /> + <ClCompile Include="StatisticsHandler.cxx" /> + <ClCompile Include="StatisticsManager.cxx" /> + <ClCompile Include="StatisticsMessage.cxx" /> + <ClCompile Include="StatusLine.cxx" /> + <ClCompile Include="StringCategory.cxx" /> + <ClCompile Include="Symbols.cxx" /> + <ClCompile Include="TcpBaseTransport.cxx" /> + <ClCompile Include="TcpConnection.cxx" /> + <ClCompile Include="TcpTransport.cxx" /> + <ClCompile Include="TimeAccumulate.cxx" /> + <ClCompile Include="TimerMessage.cxx" /> + <ClCompile Include="TimerQueue.cxx" /> + <ClCompile Include="ssl\TlsConnection.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="ssl\TlsTransport.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="Token.cxx" /> + <ClCompile Include="TransactionController.cxx" /> + <ClCompile Include="TransactionMap.cxx" /> + <ClCompile Include="TransactionState.cxx" /> + <ClCompile Include="TransactionUser.cxx" /> + <ClCompile Include="TransactionUserMessage.cxx" /> + <ClCompile Include="Transport.cxx" /> + <ClCompile Include="TransportFailure.cxx" /> + <ClCompile Include="TransportSelector.cxx" /> + <ClCompile Include="TransportThread.cxx" /> + <ClCompile Include="TuIM.cxx" /> + <ClCompile Include="Tuple.cxx" /> + <ClCompile Include="TupleMarkManager.cxx" /> + <ClCompile Include="TuSelector.cxx" /> + <ClCompile Include="UdpTransport.cxx" /> + <ClCompile Include="UInt32Category.cxx" /> + <ClCompile Include="UInt32Parameter.cxx" /> + <ClCompile Include="UnknownParameter.cxx" /> + <ClCompile Include="Uri.cxx" /> + <ClCompile Include="Via.cxx" /> + <ClCompile Include="WarningCategory.cxx" /> + <ClCompile Include="ssl\WinSecurity.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="X509Contents.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Aor.hxx" /> + <ClInclude Include="ApiCheck.hxx" /> + <ClInclude Include="ApiCheckList.hxx" /> + <ClInclude Include="ApplicationMessage.hxx" /> + <ClInclude Include="ApplicationSip.hxx" /> + <ClInclude Include="Auth.hxx" /> + <ClInclude Include="BasicNonceHelper.hxx" /> + <ClInclude Include="BranchParameter.hxx" /> + <ClInclude Include="CallId.hxx" /> + <ClInclude Include="CancelableTimerQueue.hxx" /> + <ClInclude Include="Compression.hxx" /> + <ClInclude Include="Connection.hxx" /> + <ClInclude Include="ConnectionBase.hxx" /> + <ClInclude Include="ConnectionManager.hxx" /> + <ClInclude Include="ConnectionTerminated.hxx" /> + <ClInclude Include="Contents.hxx" /> + <ClInclude Include="ContentsFactory.hxx" /> + <ClInclude Include="ContentsFactoryBase.hxx" /> + <ClInclude Include="CpimContents.hxx" /> + <ClInclude Include="CSeqCategory.hxx" /> + <ClInclude Include="DataParameter.hxx" /> + <ClInclude Include="DateCategory.hxx" /> + <ClInclude Include="DeprecatedDialog.hxx" /> + <ClInclude Include="DnsInterface.hxx" /> + <ClInclude Include="DnsResult.hxx" /> + <ClInclude Include="DnsResultMessage.hxx" /> + <ClInclude Include="DtlsMessage.hxx" /> + <ClInclude Include="ssl\DtlsTransport.hxx" /> + <ClInclude Include="Embedded.hxx" /> + <ClInclude Include="EnableFlowTimer.hxx" /> + <ClInclude Include="EventStackThread.hxx" /> + <ClInclude Include="ExistsOrDataParameter.hxx" /> + <ClInclude Include="ExistsParameter.hxx" /> + <ClInclude Include="ExpiresCategory.hxx" /> + <ClInclude Include="ExtensionHeader.hxx" /> + <ClInclude Include="ExtensionParameter.hxx" /> + <ClInclude Include="ExternalBodyContents.hxx" /> + <ClInclude Include="GenericContents.hxx" /> + <ClInclude Include="GenericUri.hxx" /> + <ClInclude Include="HeaderFieldValue.hxx" /> + <ClInclude Include="HeaderFieldValueList.hxx" /> + <ClInclude Include="HeaderHash.hxx" /> + <ClInclude Include="Headers.hxx" /> + <ClInclude Include="HeaderTypes.hxx" /> + <ClInclude Include="Helper.hxx" /> + <ClInclude Include="IntegerCategory.hxx" /> + <ClInclude Include="IntegerParameter.hxx" /> + <ClInclude Include="InternalTransport.hxx" /> + <ClInclude Include="InteropHelper.hxx" /> + <ClInclude Include="InterruptableStackThread.hxx" /> + <ClInclude Include="InvalidContents.hxx" /> + <ClInclude Include="KeepAliveMessage.hxx" /> + <ClInclude Include="KeepAlivePong.hxx" /> + <ClInclude Include="LazyParser.hxx" /> + <ClInclude Include="MarkListener.hxx" /> + <ClInclude Include="Message.hxx" /> + <ClInclude Include="MessageFilterRule.hxx" /> + <ClInclude Include="MessageWaitingContents.hxx" /> + <ClInclude Include="MethodHash.hxx" /> + <ClInclude Include="MethodTypes.hxx" /> + <ClInclude Include="Mime.hxx" /> + <ClInclude Include="MsgHeaderScanner.hxx" /> + <ClInclude Include="MultipartAlternativeContents.hxx" /> + <ClInclude Include="MultipartMixedContents.hxx" /> + <ClInclude Include="MultipartRelatedContents.hxx" /> + <ClInclude Include="MultipartSignedContents.hxx" /> + <ClInclude Include="NameAddr.hxx" /> + <ClInclude Include="NonceHelper.hxx" /> + <ClInclude Include="OctetContents.hxx" /> + <ClInclude Include="Parameter.hxx" /> + <ClInclude Include="ParameterHash.hxx" /> + <ClInclude Include="ParameterTypeEnums.hxx" /> + <ClInclude Include="ParameterTypes.hxx" /> + <ClInclude Include="ParserCategories.hxx" /> + <ClInclude Include="ParserCategory.hxx" /> + <ClInclude Include="ParserContainer.hxx" /> + <ClInclude Include="ParserContainerBase.hxx" /> + <ClInclude Include="Pidf.hxx" /> + <ClInclude Include="Pkcs7Contents.hxx" /> + <ClInclude Include="Pkcs8Contents.hxx" /> + <ClInclude Include="PlainContents.hxx" /> + <ClInclude Include="PollStatistics.hxx" /> + <ClInclude Include="PrivacyCategory.hxx" /> + <ClInclude Include="QuotedDataParameter.hxx" /> + <ClInclude Include="QValue.hxx" /> + <ClInclude Include="QValueParameter.hxx" /> + <ClInclude Include="RAckCategory.hxx" /> + <ClInclude Include="RequestLine.hxx" /> + <ClInclude Include="Rlmi.hxx" /> + <ClInclude Include="RportParameter.hxx" /> + <ClInclude Include="SdpContents.hxx" /> + <ClInclude Include="ssl\Security.hxx" /> + <ClInclude Include="SecurityAttributes.hxx" /> + <ClInclude Include="SecurityTypes.hxx" /> + <ClInclude Include="SendData.hxx" /> + <ClInclude Include="SERNonceHelper.hxx" /> + <ClInclude Include="ShutdownMessage.hxx" /> + <ClInclude Include="SipFrag.hxx" /> + <ClInclude Include="SipMessage.hxx" /> + <ClInclude Include="SipStack.hxx" /> + <ClInclude Include="StackThread.hxx" /> + <ClInclude Include="StartLine.hxx" /> + <ClInclude Include="StatelessHandler.hxx" /> + <ClInclude Include="StatisticsHandler.hxx" /> + <ClInclude Include="StatisticsManager.hxx" /> + <ClInclude Include="StatisticsMessage.hxx" /> + <ClInclude Include="StatusLine.hxx" /> + <ClInclude Include="StringCategory.hxx" /> + <ClInclude Include="Symbols.hxx" /> + <ClInclude Include="TcpBaseTransport.hxx" /> + <ClInclude Include="TcpConnection.hxx" /> + <ClInclude Include="TcpTransport.hxx" /> + <ClInclude Include="TerminateFlow.hxx" /> + <ClInclude Include="TextParameter.hxx" /> + <ClInclude Include="TimeAccumulate.hxx" /> + <ClInclude Include="TimerMessage.hxx" /> + <ClInclude Include="TimerQueue.hxx" /> + <ClInclude Include="ssl\TlsConnection.hxx" /> + <ClInclude Include="ssl\TlsTransport.hxx" /> + <ClInclude Include="Token.hxx" /> + <ClInclude Include="TransactionController.hxx" /> + <ClInclude Include="TransactionControllerThread.hxx" /> + <ClInclude Include="TransactionMap.hxx" /> + <ClInclude Include="TransactionMessage.hxx" /> + <ClInclude Include="TransactionState.hxx" /> + <ClInclude Include="TransactionTerminated.hxx" /> + <ClInclude Include="TransactionUser.hxx" /> + <ClInclude Include="TransactionUserMessage.hxx" /> + <ClInclude Include="Transport.hxx" /> + <ClInclude Include="TransportFailure.hxx" /> + <ClInclude Include="TransportSelector.hxx" /> + <ClInclude Include="TransportSelectorThread.hxx" /> + <ClInclude Include="TransportThread.hxx" /> + <ClInclude Include="TuIM.hxx" /> + <ClInclude Include="Tuple.hxx" /> + <ClInclude Include="TupleMarkManager.hxx" /> + <ClInclude Include="TuSelector.hxx" /> + <ClInclude Include="UdpTransport.hxx" /> + <ClInclude Include="UInt32Category.hxx" /> + <ClInclude Include="UInt32Parameter.hxx" /> + <ClInclude Include="UnknownHeaderType.hxx" /> + <ClInclude Include="UnknownParameter.hxx" /> + <ClInclude Include="UnknownParameterType.hxx" /> + <ClInclude Include="Uri.hxx" /> + <ClInclude Include="ValueFifo.hxx" /> + <ClInclude Include="Via.hxx" /> + <ClInclude Include="WarningCategory.hxx" /> + <ClInclude Include="ssl\WinSecurity.hxx" /> + <ClInclude Include="X509Contents.hxx" /> + <ClInclude Include="ZeroOutStatistics.hxx" /> + </ItemGroup> + <ItemGroup> + <None Include="HeaderHash.gperf" /> + <None Include="MethodHash.gperf" /> + <None Include="ParameterHash.gperf" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.filters b/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.filters new file mode 100644 index 00000000..6d6858e6 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.filters @@ -0,0 +1,853 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{5105422a-a87a-4074-87f1-a17e44415a29}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{0df38903-f4ad-4501-9d85-5207452e4073}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc</Extensions> + </Filter> + <Filter Include="GPerfFiles"> + <UniqueIdentifier>{b1841523-a7a0-4f2d-a95b-594f4358e036}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="Aor.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ApiCheck.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ApplicationSip.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Auth.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BasicNonceHelper.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BranchParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="CallId.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Compression.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Connection.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ConnectionBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ConnectionManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Contents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ContentsFactoryBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="CpimContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="CSeqCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DataParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DateCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DeprecatedDialog.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DnsInterface.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DnsResult.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DtlsMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\DtlsTransport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Embedded.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="EventStackThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ExistsOrDataParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ExistsParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ExpiresCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ExtensionHeader.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ExtensionParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ExternalBodyContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="GenericContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="GenericUri.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HeaderFieldValue.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HeaderFieldValueList.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HeaderHash.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Headers.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HeaderTypes.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Helper.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="IntegerCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="IntegerParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InternalTransport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InteropHelper.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InterruptableStackThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="InvalidContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="KeepAliveMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="LazyParser.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Message.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MessageFilterRule.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MessageWaitingContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MethodHash.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MethodTypes.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Mime.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MsgHeaderScanner.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MultipartAlternativeContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MultipartMixedContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MultipartRelatedContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MultipartSignedContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="NameAddr.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="NonceHelper.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="OctetContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Parameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParameterHash.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParameterTypes.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParserCategories.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParserCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParserContainerBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Pidf.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Pkcs7Contents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Pkcs8Contents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="PlainContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="PrivacyCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="QuotedDataParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="QValue.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="QValueParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RAckCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RequestLine.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Rlmi.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RportParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SdpContents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\Security.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SecurityAttributes.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SERNonceHelper.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SipFrag.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SipMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SipStack.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StackThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StatelessHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StatisticsHandler.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StatisticsManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StatisticsMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StatusLine.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="StringCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Symbols.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TcpBaseTransport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TcpConnection.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TcpTransport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TimeAccumulate.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TimerMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TimerQueue.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\TlsConnection.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\TlsTransport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Token.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransactionController.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransactionMap.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransactionState.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransactionUser.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransactionUserMessage.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Transport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransportFailure.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransportSelector.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransportThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TuIM.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Tuple.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TupleMarkManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TuSelector.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UdpTransport.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UInt32Category.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UInt32Parameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UnknownParameter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Uri.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Via.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="WarningCategory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\WinSecurity.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="X509Contents.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Aor.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ApiCheck.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ApiCheckList.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ApplicationMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ApplicationSip.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Auth.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BasicNonceHelper.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BranchParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CallId.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CancelableTimerQueue.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Compression.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Connection.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConnectionBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConnectionManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConnectionTerminated.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Contents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ContentsFactory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ContentsFactoryBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CpimContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CSeqCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DataParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DateCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DeprecatedDialog.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DnsInterface.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DnsResult.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DnsResultMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DtlsMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\DtlsTransport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Embedded.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="EnableFlowTimer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="EventStackThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExistsOrDataParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExistsParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExpiresCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExtensionHeader.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExtensionParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ExternalBodyContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="GenericContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="GenericUri.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HeaderFieldValue.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HeaderFieldValueList.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HeaderHash.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Headers.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HeaderTypes.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Helper.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="IntegerCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="IntegerParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InternalTransport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InteropHelper.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InterruptableStackThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="InvalidContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="KeepAliveMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="KeepAlivePong.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="LazyParser.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MarkListener.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Message.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MessageFilterRule.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MessageWaitingContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MethodHash.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MethodTypes.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Mime.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MsgHeaderScanner.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MultipartAlternativeContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MultipartMixedContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MultipartRelatedContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MultipartSignedContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="NameAddr.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="NonceHelper.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="OctetContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Parameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParameterHash.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParameterTypeEnums.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParameterTypes.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParserCategories.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParserCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParserContainer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParserContainerBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Pidf.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Pkcs7Contents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Pkcs8Contents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PlainContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PollStatistics.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PrivacyCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="QuotedDataParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="QValue.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="QValueParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RAckCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RequestLine.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Rlmi.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RportParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SdpContents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\Security.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SecurityAttributes.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SecurityTypes.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SendData.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SERNonceHelper.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ShutdownMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SipFrag.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SipMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SipStack.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StackThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StartLine.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StatelessHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StatisticsHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StatisticsManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StatisticsMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StatusLine.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StringCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Symbols.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TcpBaseTransport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TcpConnection.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TcpTransport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TerminateFlow.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TextParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TimeAccumulate.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TimerMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TimerQueue.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\TlsConnection.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\TlsTransport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Token.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionController.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionControllerThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionMap.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionState.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionTerminated.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionUser.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransactionUserMessage.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Transport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransportFailure.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransportSelector.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransportSelectorThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransportThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TuIM.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Tuple.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TupleMarkManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TuSelector.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UdpTransport.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UInt32Category.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UInt32Parameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UnknownHeaderType.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UnknownParameter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UnknownParameterType.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Uri.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ValueFifo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Via.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="WarningCategory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\WinSecurity.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="X509Contents.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ZeroOutStatistics.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="HeaderHash.gperf"> + <Filter>GPerfFiles</Filter> + </None> + <None Include="MethodHash.gperf"> + <Filter>GPerfFiles</Filter> + </None> + <None Include="ParameterHash.gperf"> + <Filter>GPerfFiles</Filter> + </None> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.user b/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.user new file mode 100644 index 00000000..abe8dd89 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.user @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup /> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.cxx b/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.cxx new file mode 100644 index 00000000..47785a55 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.cxx @@ -0,0 +1,759 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#ifdef USE_SSL +#ifdef USE_DTLS + +#include <memory> + +#ifndef RESIP_COMPAT_HXX +#include "rutil/compat.hxx" +#endif + +#ifndef RESIP_DATA_HXX +#include "rutil/Data.hxx" +#endif + +#ifndef RESIP_DNSUTIL_HXX +#include "rutil/DnsUtil.hxx" +#endif + +#ifndef RESIP_SOCKET_HXX +#include "rutil/Socket.hxx" +#endif + +#ifndef RESIP_LOGGER_HXX +#include "rutil/Logger.hxx" +#endif + +#ifndef RESIP_SIPMESSAGE_HXX +#include "resip/stack/SipMessage.hxx" +#endif + +#ifndef RESIP_HELPER_HXX +#include "resip/stack/Helper.hxx" +#endif + +#ifndef RESIP_SECURITY_HXX +#include "resip/stack/ssl/Security.hxx" +#endif + +#ifndef RESIP_DTLSMESSAGE_HXX +#include "resip/stack/DtlsMessage.hxx" +#endif + +#ifndef RESIP_DTLSTRANSPORT_HXX +#include "resip/stack/ssl/DtlsTransport.hxx" +#endif + +#include "rutil/WinLeakCheck.hxx" + +#include <openssl/e_os2.h> +#include <openssl/evp.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/pem.h> +#include <openssl/pkcs7.h> +#include <openssl/x509v3.h> +#include <openssl/ssl.h> + +#ifdef USE_SIGCOMP +#include <osc/Stack.h> +#include <osc/StateChanges.h> +#include <osc/SigcompMessage.h> +#endif + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +using namespace std; +using namespace resip; + +// .slg. Note that DTLS handshakes were really broken in older versions of OpenSSL 0.9.8 +// You should use at least version 0.9.8g for both client and server. + +DtlsTransport::DtlsTransport(Fifo<TransactionMessage>& fifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + Security& security, + const Data& sipDomain, + AfterSocketCreationFuncPtr socketFunc, + Compression& compression) + : UdpTransport( fifo, portNum, version, + StunDisabled, interfaceObj, socketFunc, compression ), + mTimer( mHandshakePending ), + mSecurity( &security ), + mDomain(sipDomain) +{ + setTlsDomain(sipDomain); + InfoLog ( << "Creating DTLS transport host=" << interfaceObj + << " port=" << mTuple.getPort() + << " ipv4=" << version ) ; + + mTxFifo.setDescription("DtlsTransport::mTxFifo"); + + mTuple.setType( transport() ); + + mClientCtx = mSecurity->createDomainCtx(DTLSv1_client_method(), Data::Empty) ; + mServerCtx = mSecurity->createDomainCtx(DTLSv1_server_method(), sipDomain) ; + assert( mClientCtx ) ; + assert( mServerCtx ) ; + + mDummyBio = BIO_new( BIO_s_mem() ) ; + assert( mDummyBio ) ; + + mSendData = NULL ; + + /* DTLS: partial reads end up discarding unread UDP bytes :-( + * Setting read ahead solves this problem. + * Source of this comment is: apps/s_client.c from OpenSSL source + */ + SSL_CTX_set_read_ahead(mClientCtx, 1); + SSL_CTX_set_read_ahead(mServerCtx, 1); + + /* trying to read from this BIO always returns retry */ + BIO_set_mem_eof_return( mDummyBio, -1 ) ; +} + +DtlsTransport::~DtlsTransport() +{ + DebugLog (<< "Shutting down " << mTuple); + + while(mDtlsConnections.begin() != mDtlsConnections.end()) + { + _cleanupConnectionState(mDtlsConnections.begin()->second, mDtlsConnections.begin()->first); + } + SSL_CTX_free(mClientCtx);mClientCtx=0; + SSL_CTX_free(mServerCtx);mServerCtx=0; + + BIO_free( mDummyBio) ; +} + +void +DtlsTransport::_read( FdSet& fdset ) +{ + //should this buffer be allocated on the stack and then copied out, as it + //needs to be deleted every time EWOULDBLOCK is encountered + // .dlb. can we determine the size of the buffer before we allocate? + // something about MSG_PEEK|MSG_TRUNC in Stevens.. + // .dlb. RFC3261 18.1.1 MUST accept 65K datagrams. would have to attempt to + // adjust the UDP buffer as well... + unsigned int bufferLen = UdpTransport::MaxBufferSize + 5 ; + char* buffer = new char[ bufferLen ] ; + unsigned char *pt = new unsigned char[ bufferLen ] ; + + SSL *ssl ; + BIO *rbio ; + BIO *wbio ; + + // !jf! how do we tell if it discarded bytes + // !ah! we use the len-1 trick :-( + Tuple tuple(mTuple) ; + socklen_t slen = tuple.length() ; + int len = recvfrom( mFd, + buffer, + UdpTransport::MaxBufferSize, + 0 /*flags */, + &tuple.getMutableSockaddr(), + &slen ) ; + if ( len == SOCKET_ERROR ) + { + int err = getErrno() ; + if ( err != EWOULDBLOCK ) + { + error( err ) ; + } + } + + if (len == 0 || len == SOCKET_ERROR) + { + delete [] buffer ; + buffer = 0 ; + return ; + } + + if ( len + 1 >= UdpTransport::MaxBufferSize ) + { + InfoLog (<<"Datagram exceeded max length "<<UdpTransport::MaxBufferSize ) ; + delete [] buffer ; buffer = 0 ; + return ; + } + + //DebugLog ( << "UDP Rcv : " << len << " b" ); + //DebugLog ( << Data(buffer, len).escaped().c_str()); + + /* begin SSL stuff */ + struct sockaddr peer = tuple.getMutableSockaddr() ; + + ssl = mDtlsConnections[ *((struct sockaddr_in *)&peer) ] ; + + /* + * If we don't have a binding for this peer, + * then we're a server. + */ + if ( ssl == NULL ) + { + ssl = SSL_new( mServerCtx ) ; + assert( ssl ) ; + + // clear SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE set in SSL_CTX if we are a server + SSL_set_verify(ssl, 0, 0); + + InfoLog( << "DTLS handshake starting (Server mode)" ); + + SSL_set_accept_state( ssl ) ; + + wbio = BIO_new_dgram( (int)mFd, BIO_NOCLOSE ) ; + assert( wbio ) ; + + BIO_dgram_set_peer( wbio, &peer ) ; + + SSL_set_bio( ssl, NULL, wbio ) ; + + /* remember this connection */ + mDtlsConnections[ *((struct sockaddr_in *)&peer) ] = ssl ; + } + + rbio = BIO_new_mem_buf( buffer, len ) ; + BIO_set_mem_eof_return( rbio, -1 ) ; + + ssl->rbio = rbio ; + + len = SSL_read( ssl, pt, UdpTransport::MaxBufferSize ) ; + int err = SSL_get_error( ssl, len ) ; + + /* done with the rbio */ + BIO_free( ssl->rbio ) ; + ssl->rbio = mDummyBio ; + delete [] buffer ; + buffer = 0 ; + + if ( len <= 0 ) + { + char errorString[1024]; + + switch( err ) + { + case SSL_ERROR_NONE: + break ; + case SSL_ERROR_SSL: + { + ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); + DebugLog( << "Got DTLS read condition SSL_ERROR_SSL on" + << " addr = " << inet_ntoa(((struct sockaddr_in *)&peer)->sin_addr) + << " port = " << ntohs(((struct sockaddr_in *)&peer)->sin_port) + << " error = " << errorString ); + } + break ; + case SSL_ERROR_WANT_READ: + break ; + case SSL_ERROR_WANT_WRITE: + break ; + case SSL_ERROR_SYSCALL: + { + ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); + DebugLog( << "Got DTLS read condition SSL_ERROR_SYSCALL on" + << " addr = " << inet_ntoa(((struct sockaddr_in *)&peer)->sin_addr) + << " port = " << ntohs(((struct sockaddr_in *)&peer)->sin_port) + << " error = " << errorString ); + } + break ; + /* connection closed */ + case SSL_ERROR_ZERO_RETURN: + { + ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); + DebugLog( << "Got DTLS read condition SSL_ERROR_ZERO_RETURN on" + << " addr = " << inet_ntoa(((struct sockaddr_in *)&peer)->sin_addr) + << " port = " << ntohs(((struct sockaddr_in *)&peer)->sin_port) + << " error = " << errorString ); + + _cleanupConnectionState( ssl, *((struct sockaddr_in *)&peer) ) ; + } + break ; + case SSL_ERROR_WANT_CONNECT: + break ; + case SSL_ERROR_WANT_ACCEPT: + break ; + default: + break ; + } + } + + if ( len <= 0 ) + return ; + + if ( SSL_in_init( ssl ) ) + mTimer.add( ssl, DtlsReceiveTimeout ) ; + +#ifdef USE_SIGCOMP + osc::StateChanges *sc = 0; +#endif + + if ((pt[0] & 0xf8) == 0xf8) + { + if(!mCompression.isEnabled()) + { + InfoLog(<< "Discarding unexpected SigComp message"); + delete [] pt; + return; + } +#ifdef USE_SIGCOMP + unsigned char *newPt = new unsigned char[ bufferLen ] ; + size_t uncompressedLength = + mSigcompStack->uncompressMessage(pt, len, + newPt, UdpTransport::MaxBufferSize, + sc); + + DebugLog (<< "Unompressed message from " + << len << " bytes to " + << uncompressedLength << " bytes"); + + osc::SigcompMessage *nack = mSigcompStack->getNack(); + + if (nack) + { + mTxFifo.add(new SendData(tuple, + Data(nack->getDatagramMessage(), + nack->getDatagramLength()), + Data::Empty, + Data::Empty, + true) + ); + delete nack; + } + + delete[] buffer; + buffer = newBuffer; + len = uncompressedLength; +#endif + } + + SipMessage* message = new SipMessage(this); + + // set the received from information into the received= parameter in the + // via + + // It is presumed that UDP Datagrams are arriving atomically and that + // each one is a unique SIP message + + // Save all the info where this message came from + tuple.transport = this ; + message->setSource( tuple ) ; + //DebugLog (<< "Received from: " << tuple); + + // Tell the SipMessage about this datagram buffer. + message->addBuffer( (char *)pt ) ; + + mMsgHeaderScanner.prepareForMessage( message ) ; + + char *unprocessedCharPtr ; + if (mMsgHeaderScanner.scanChunk( (char *)pt, + len, + &unprocessedCharPtr ) != + MsgHeaderScanner::scrEnd) + { + DebugLog( << "Scanner rejecting datagram as unparsable / fragmented from " + << tuple ) ; + DebugLog( << Data( pt, len ) ) ; + delete message ; + message = 0 ; + return ; + } + + // no pp error + int used = int(unprocessedCharPtr - (char *)pt); + + if ( used < len ) + { + // body is present .. add it up. + // NB. The Sip Message uses an overlay (again) + // for the body. It ALSO expects that the body + // will be contiguous (of course). + // it doesn't need a new buffer in UDP b/c there + // will only be one datagram per buffer. (1:1 strict) + + message->setBody( (char *)pt + used, len - used ) ; + //DebugLog(<<"added " << len-used << " byte body"); + } + + if ( ! basicCheck( *message ) ) + { + delete message ; // cannot use it, so, punt on it... + // basicCheck queued any response required + message = 0 ; + return ; + } + + stampReceived( message) ; + +#ifdef USE_SIGCOMP + if (mCompression.isEnabled() && sc) + { + const Via &via = message->header(h_Vias).front(); + if (message->isRequest()) + { + // For requests, the compartment ID is read out of the + // top via header field; if not present, we use the + // TCP connection for identification purposes. + if (via.exists(p_sigcompId)) + { + Data compId = via.param(p_sigcompId); + mSigcompStack->provideCompartmentId( + sc, compId.data(), compId.size()); + } + else + { + mSigcompStack->provideCompartmentId(sc, this, sizeof(this)); + } + } + else + { + // For responses, the compartment ID is supposed to be + // the same as the compartment ID of the request. We + // *could* dig down into the transaction layer to try to + // figure this out, but that's a royal pain, and a rather + // severe layer violation. In practice, we're going to ferret + // the ID out of the the Via header field, which is where we + // squirreled it away when we sent this request in the first place. + Data compId = via.param(p_branch).getSigcompCompartment(); + mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size()); + } + + } +#endif + + mStateMachineFifo.add( message ) ; +} + +void DtlsTransport::_write( FdSet& fdset ) +{ + SSL *ssl ; + BIO *wBio ; + int retry = 0 ; + + SendData *sendData ; + if ( mSendData != NULL ) + sendData = mSendData ; + else + sendData = mTxFifo.getNext() ; + + //DebugLog (<< "Sent: " << sendData->data); + //DebugLog (<< "Sending message on udp."); + + assert( &(*sendData) ); + assert( sendData->destination.getPort() != 0 ); + + sockaddr peer = sendData->destination.getSockaddr(); + + ssl = mDtlsConnections[ *((struct sockaddr_in *)&peer) ] ; + + /* If we don't have a binding, then we're a client */ + if ( ssl == NULL ) + { + ssl = SSL_new( mClientCtx ) ; + assert( ssl ) ; + + + InfoLog( << "DTLS handshake starting (client mode)" ); + + SSL_set_connect_state( ssl ) ; + + wBio = BIO_new_dgram( (int)mFd, BIO_NOCLOSE ) ; + assert( wBio ) ; + + BIO_dgram_set_peer( wBio, &peer) ; + + /* the real rbio will be set by _read */ + SSL_set_bio( ssl, mDummyBio, wBio ) ; + + /* we should be ready to take this out if the + * connection fails later */ + mDtlsConnections [ *((struct sockaddr_in *)&peer) ] = ssl ; + } + + int expected; + int count; + +#ifdef USE_SIGCOMP + // If message needs to be compressed, compress it here. + if (mSigcompStack && + sendData->sigcompId.size() > 0 && + !sendData->isAlreadyCompressed ) + { + osc::SigcompMessage *sm = mSigcompStack->compressMessage + (sendData->data.data(), sendData->data.size(), + sendData->sigcompId.data(), sendData->sigcompId.size(), + isReliable()); + + DebugLog (<< "Compressed message from " + << sendData->data.size() << " bytes to " + << sm->getDatagramLength() << " bytes"); + + expected = sm->getDatagramLength(); + + count = SSL_Write(ssl, + sm->getDatagramMessage(), + sm->getDatagramLength()); + delete sm; + } + else +#endif + { + expected = (int)sendData->data.size(); + + count = SSL_write(ssl, sendData->data.data(), + (int)sendData->data.size()); + } + + /* + * all reads go through _read, so the most likely result during a handshake + * will be SSL_ERROR_WANT_READ + */ + + if ( count <= 0 ) + { + /* cache unqueued data */ + mSendData = sendData ; + + int err = SSL_get_error( ssl, count ) ; + + char errorString[1024]; + + switch( err ) + { + case SSL_ERROR_NONE: + break; + case SSL_ERROR_SSL: + { + ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); + DebugLog( << "Got DTLS write condition SSL_ERROR_SSL on " + << sendData->destination + << " error = " << errorString ); + } + break; + case SSL_ERROR_WANT_READ: + retry = 1 ; + break; + case SSL_ERROR_WANT_WRITE: + retry = 1 ; + fdset.setWrite(mFd); + break; + case SSL_ERROR_SYSCALL: + { + int e = getErrno(); + error(e); + + ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); + DebugLog( << "Got DTLS write condition SSL_ERROR_SYSCALL " + << "Failed (" << e << ") sending to " + << sendData->destination + << " error = " << errorString ); + + fail(sendData->transactionId); + } + break; + case SSL_ERROR_ZERO_RETURN: + { + ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); + DebugLog( << "Got DTLS write condition SSL_ERROR_ZERO_RETURN on " + << sendData->destination + << " error = " << errorString ); + + _cleanupConnectionState( ssl, *((struct sockaddr_in *)&peer) ) ; + } + break ; + case SSL_ERROR_WANT_CONNECT: + break; + case SSL_ERROR_WANT_ACCEPT: + break; + default: + break ; + } + } + else + { + mSendData = NULL ; + } + + /* + * ngm: is sendData deleted by a higher layer? Seems to be the case after + * checking with UdpTransport + */ + + if ( ! retry && count != int(sendData->data.size()) ) + { + ErrLog (<< "UDPTransport - send buffer full" ); + fail(sendData->transactionId); + } +} + +void +DtlsTransport::_doHandshake( void ) +{ + DtlsMessage *msg = mHandshakePending.getNext() ; + SSL *ssl = msg->getSsl() ; + + delete msg ; + + ERR_clear_error(); + + int ret = SSL_do_handshake( ssl ) ; + + if (ret <= 0) { + int err = SSL_get_error(ssl, ret); + + char errorString[1024]; + + switch (err) + { + case SSL_ERROR_NONE: + break; + case SSL_ERROR_SSL: + { + ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); + DebugLog( << "Got DTLS handshake code SSL_ERROR_SSL" + << " error = " << errorString ); + } + break; + case SSL_ERROR_WANT_READ: + break; + case SSL_ERROR_WANT_WRITE: + break; + case SSL_ERROR_SYSCALL: + { + ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); + DebugLog( << "Got DTLS handshake code SSL_ERROR_SYSCALL" + << " error = " << errorString ); + } + break; + case SSL_ERROR_ZERO_RETURN: + { + ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); + DebugLog( << "Got DTLS handshake code SSL_ERROR_ZERO_RETURN" + << " error = " << errorString ); + } + break; + case SSL_ERROR_WANT_CONNECT: + break; + case SSL_ERROR_WANT_ACCEPT: + break; + default: + break ; + } + } +} + +void +DtlsTransport::process(FdSet& fdset) +{ + // pull buffers to send out of TxFifo + // receive datagrams from fd + // preparse and stuff into RxFifo + + mTimer.process() ; + + while ( mHandshakePending.messageAvailable() ) + _doHandshake() ; + + if ( ( mSendData != NULL || mTxFifo.messageAvailable() ) + && fdset.readyToWrite( mFd ) ) + _write( fdset ) ; + + // !jf! this may have to change - when we read a message that is too big + if ( fdset.readyToRead(mFd) ) + _read( fdset ) ; +} + + +void +DtlsTransport::buildFdSet( FdSet& fdset ) +{ + fdset.setRead(mFd); + + if ( mSendData != NULL || mTxFifo.messageAvailable() ) + { + fdset.setWrite(mFd); + } +} + +void +DtlsTransport::_cleanupConnectionState( SSL *ssl, struct sockaddr_in peer ) +{ + /* + * SSL_free decrements the ref-count for mDummyBio by 1, so + * add 1 to the ref-count to make sure it does not get free'd + */ + CRYPTO_add(&mDummyBio->references, 1, CRYPTO_LOCK_BIO); + SSL_shutdown(ssl); + SSL_free(ssl) ; + mDtlsConnections.erase(peer) ; +} + +void +DtlsTransport::_mapDebug( const char *where, const char *action, SSL *ssl ) +{ + fprintf( stderr, "%s: %s\t%p\n", where, action, ssl ) ; + fprintf( stderr, "map sizet = %d\n", mDtlsConnections.size() ) ; +} + +void +DtlsTransport::_printSock( const struct sockaddr_in *sock ) +{ + fprintf( stderr, "addr = %s\t port = %d\n", inet_ntoa( sock->sin_addr ), + ntohs( sock->sin_port ) ) ; +} + +#endif /* USE_DTLS */ +#endif /* USE_SSL */ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.hxx b/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.hxx new file mode 100644 index 00000000..e4924f0f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.hxx @@ -0,0 +1,235 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#if !defined(RESIP_DTLSTRANSPORT_HXX) +#define RESIP_DTLSTRANSPORT_HXX + +#ifdef USE_DTLS + +#ifndef RESIP_UDPTRANSPORT_HXX +#include "resip/stack/UdpTransport.hxx" +#endif + +#ifndef RESIP_TIMERQUEUE_HXX +#include "resip/stack/TimerQueue.hxx" +#endif + +#ifndef RESIP_SENDDATA_HXX +#include "resip/stack/SendData.hxx" +#endif + +#ifndef RESIP_HEAPINSTANCECOUNTER_HXX +#include "rutil/HeapInstanceCounter.hxx" +#endif + +#ifndef RESIP_HASHMAP_HXX +#include "rutil/HashMap.hxx" +#endif + +#include <map> +#include <openssl/ssl.h> + +#include "resip/stack/Compression.hxx" + +namespace resip +{ + +class Security; +class TransactionMessage; +class UdpTransport; +class DtlsMessage; + +class DtlsTransport : public UdpTransport +{ +#if defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310)) // !slg! not sure if this works on __INTEL_COMPILER + struct sockaddr_in_hash_compare + { + enum { bucket_size = 4, min_buckets = 8 }; + + size_t operator()(const struct sockaddr_in& sock) const + { + return sock.sin_addr.s_addr; + } + bool operator()(const struct sockaddr_in& s1, + const struct sockaddr_in& s2) const + { + if ( (s1.sin_addr.s_addr < s2.sin_addr.s_addr) || + ( (s1.sin_addr.s_addr == s2.sin_addr.s_addr ) && + ( s1.sin_port < s2.sin_port) ) ) + { + return 1; + } + else + { + return 0; + } + } + }; +#elif defined(HASH_MAP_NAMESPACE) + struct addr_hash + { + size_t operator()( const struct sockaddr_in sock ) const + { + return sock.sin_addr.s_addr ; + } + }; + + struct addr_cmp + { + bool operator()(const struct sockaddr_in& s1, + const struct sockaddr_in& s2) const + { + if ( ( s1.sin_addr.s_addr == s2.sin_addr.s_addr ) && + ( s1.sin_port == s2.sin_port) ) + { + return 1; + } + else + { + return 0; + } + } + }; +#else + struct addr_less + { + bool operator()(const struct sockaddr_in& s1, + const struct sockaddr_in& s2) const + { + if ( (s1.sin_addr.s_addr < s2.sin_addr.s_addr) || + ( (s1.sin_addr.s_addr == s2.sin_addr.s_addr ) && + ( s1.sin_port < s2.sin_port) ) ) + { + return 1; + } + else + { + return 0; + } + } + }; +#endif + + public: + RESIP_HeapCount(DtlsTransport); + // Specify which udp port to use for send and receive + // interface can be an ip address or dns name. If it is an ip address, + // only bind to that interface. + DtlsTransport(Fifo<TransactionMessage>& fifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + Security& security, + const Data& sipDomain, + AfterSocketCreationFuncPtr socketFunc = 0, + Compression &compression = Compression::Disabled); + virtual ~DtlsTransport(); + + void process(FdSet& fdset); + bool isReliable() const { return false; } + bool isDatagram() const { return true; } + TransportType transport() const { return DTLS; } + virtual void buildFdSet( FdSet& fdset); + + static const unsigned long DtlsReceiveTimeout = 250000 ; + + private: + +#if defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310)) + typedef HashMap<struct sockaddr_in, + SSL*, + DtlsTransport::sockaddr_in_hash_compare> DtlsConnectionMap; +#elif defined(HASH_MAP_NAMESPACE) + typedef HashMap<struct sockaddr_in, + SSL*, + DtlsTransport::addr_hash, + DtlsTransport::addr_cmp> DtlsConnectionMap ; +#else + typedef std::map<struct sockaddr_in, + SSL*, + DtlsTransport::addr_less> DtlsConnectionMap ; +#endif + + SSL_CTX *mClientCtx ; + SSL_CTX *mServerCtx ; + MsgHeaderScanner mMsgHeaderScanner; + static const int MaxBufferSize; + Fifo<DtlsMessage> mHandshakePending ; + DtlsTimerQueue mTimer ; + Security* mSecurity ; + DtlsConnectionMap mDtlsConnections ; /* IP addr/port -> transport */ + unsigned char mDummyBuf[ 4 ] ; + BIO* mDummyBio ; + const Data mDomain; + + SendData *mSendData ;/* Data that was unqueued from mTxFifo, + * but unable to send because a handshake + * was in progress + */ + + void _read( FdSet& fdset ) ; + void _write( FdSet& fdset ) ; + void _doHandshake() ; + void _cleanupConnectionState( SSL *ssl, struct sockaddr_in peer ) ; + + void _mapDebug( const char *where, const char *action, SSL *ssl ) ; + void _printSock( const struct sockaddr_in *sock ) ; +}; + +} + +#endif /* USE_DTLS */ + +#endif /* ! RESIP_DTLSTRANSPORT_HXX */ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/MacSecurity.cxx b/src/libs/resiprocate/resip/stack/ssl/MacSecurity.cxx new file mode 100644 index 00000000..5424768e --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/MacSecurity.cxx @@ -0,0 +1,264 @@ +#if defined(TARGET_OS_MAC) + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#ifdef USE_SSL +// .amr. Must include Apple headers first, otherwise conflicts with rutil/compat.hxx happen due to SDK type differences +#include <CoreFoundation/CoreFoundation.h> +#include <CoreServices/CoreServices.h> +#include <Security/Security.h> + +#include <openssl/e_os2.h> +#include <openssl/evp.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/pem.h> +#include <openssl/pkcs7.h> +#include <openssl/ossl_typ.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/ssl.h> + +#include "resip/stack/ssl/MacSecurity.hxx" +#include "rutil/Logger.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +int verifyCallback(int iInCode, X509_STORE_CTX *pInStore); + +void +MacSecurity::preload() +{ + // load the root certificates + getCerts(); +} + +// Opens a search handle to certificates store in +// the X509Anchors keychain +KeychainHandle +MacSecurity::openSystemCertStore() +{ + OSStatus status = noErr; + + const char *pathName = nil; + SInt32 MacVersion = 0; + + if (true/*Gestalt(gestaltSystemVersion, &MacVersion) == noErr*/) + { + //if (MacVersion >= 0x1050) + { + //for Leopard OSX, the root certificate are located in SystemRootCertificates.keychain + pathName = "/System/Library/Keychains/SystemRootCertificates.keychain"; + } + /*else + { + //for earlier OSX (including Tiger), the root certificate are located in X509Anchors + pathName = "/System/Library/Keychains/X509Anchors"; + }*/ + } + if(nil == pathName) + { + ErrLog( << "Cannot retrieve OS version"); + return NULL; + } + // NOTE: instead of hardcoding the "/System" portion of the path + // we could retrieve it using ::FSFindFolder instead. But it + // doesn't seem useful right now. + SecKeychainRef systemCertsKeyChain; + status = ::SecKeychainOpen( + pathName, + &systemCertsKeyChain + ); + + if (status != noErr) + { + ErrLog( << "X509Anchors keychain could not be opened"); + assert(0); + return NULL; + } + + // Create a handle to search that iterates over root certificates + // in the X509Anchors keychain + + SecKeychainSearchRef searchReference = nil; + status = ::SecKeychainSearchCreateFromAttributes( + systemCertsKeyChain, + kSecCertificateItemClass, + NULL, + &searchReference + ); + + // Now that we have the search handle we don't need an explicit + // reference to the keychain + + ::CFRelease(systemCertsKeyChain); + + if (status != noErr) + { + ErrLog( << "System certificate store cannot be opened"); + assert(0); + return NULL; + } + + InfoLog( << "System certificate store opened"); + return searchReference; +} + +void +MacSecurity::closeCertifStore(KeychainHandle searchReference) +{ + if (NULL == searchReference) + return; + + ::CFRelease(searchReference); +} + +void +MacSecurity::getCerts() +{ + SecKeychainSearchRef searchReference = NULL; + searchReference = (SecKeychainSearchRef) openSystemCertStore(); + + // nothing to do, error already reported + if (searchReference == NULL) + return; + + // iterate over each certificate + for (;;) + { + OSStatus status = noErr; + SecKeychainItemRef itemRef = nil; + + // get the next certificate in the search + status = ::SecKeychainSearchCopyNext( + searchReference, + &itemRef + ); + if (status == errSecItemNotFound) + { + // no more certificates left + break; + } + + // get data from the certificate + if (status == noErr) + { + void *data; + UInt32 dataSize; + status = ::SecKeychainItemCopyAttributesAndData( + itemRef, + NULL, + NULL, + NULL, + &dataSize, + &data + ); + + if (status == noErr && data != NULL) + { + Data certDER(Data::Borrow, (const char*)data, dataSize); + addCertDER(BaseSecurity::RootCert, NULL, certDER, false); + + status = ::SecKeychainItemFreeAttributesAndData(NULL, data); + } + } + + // free the certificate handle + if (itemRef != NULL) + ::CFRelease(itemRef); + + if (status != noErr) + { + // there was an error loading the certificate + ErrLog( << "Couldn't load certificate, error code: " << (int)status); + assert(0); + } + } + + closeCertifStore(searchReference); +} + +// TODO: this needs to be refactored with WinSecurity.cxx +/*int +verifyCallback(int iInCode, X509_STORE_CTX *pInStore) +{ + char cBuf1[500]; + char cBuf2[500]; + X509 *pErrCert; + int iErr = 0; + int iDepth = 0; + pErrCert = X509_STORE_CTX_get_current_cert(pInStore); + iErr = X509_STORE_CTX_get_error(pInStore); + iDepth = X509_STORE_CTX_get_error_depth(pInStore); + + if (NULL != pErrCert) + X509_NAME_oneline(X509_get_subject_name(pErrCert),cBuf1,256); + + sprintf(cBuf2,"depth=%d %s\n",iDepth,cBuf1); + if(!iInCode) + { + memset(cBuf2, 0, sizeof(cBuf2) ); + sprintf(cBuf2, "\n Error %s", X509_verify_cert_error_string(pInStore->error) ); + } + + return iInCode; +} +*/ + +#endif /* USE_SSL */ + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/MacSecurity.hxx b/src/libs/resiprocate/resip/stack/ssl/MacSecurity.hxx new file mode 100644 index 00000000..8d328f9d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/MacSecurity.hxx @@ -0,0 +1,103 @@ +#if !defined(RESIP_MACSECURITY_HXX) +#define RESIP_MACSECURITY_HXX + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "resip/stack/ssl/Security.hxx" + +namespace resip +{ + +// Instead of using Mac specific data types +// we pass around handles. This keeps us from +// having to include Mac OS headers. +typedef void * KeychainHandle; + +/* + * Manages certificates in the Mac Keychain. + */ +class MacSecurity : public Security +{ + public: + + MacSecurity(){}; + + // load root certificates into memory + virtual void preload(); + + // we need to stub out these functions since we don't + // dynamically add or remove certificates on the mac + virtual void onReadPEM(const Data&, PEMType, Data&) const + { } + virtual void onWritePEM(const Data&, PEMType, const Data&) const + { } + virtual void onRemovePEM(const Data&, PEMType) const + { } + + protected: + + // Opens a search handle to certificates store in + // the X509Anchors keychain + KeychainHandle openSystemCertStore(); + + // loads root certificates into memory + void getCerts(); + + void closeCertifStore(KeychainHandle searchReference); +}; + +} // namespace resip + +#endif // ndef RESIP_MACSECURITY_HXX + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/Security.cxx b/src/libs/resiprocate/resip/stack/ssl/Security.cxx new file mode 100644 index 00000000..b90395af --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/Security.cxx @@ -0,0 +1,2792 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#ifdef USE_SSL + +#include "resip/stack/ssl/Security.hxx" + +#include <ostream> +#include <fstream> + +#include "resip/stack/Contents.hxx" +#include "resip/stack/MultipartSignedContents.hxx" +#include "resip/stack/Pkcs7Contents.hxx" +#include "resip/stack/PlainContents.hxx" +#include "resip/stack/SecurityAttributes.hxx" +#include "resip/stack/Transport.hxx" +#include "resip/stack/SipMessage.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Random.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Timer.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/FileSystem.hxx" +#include "rutil/WinLeakCheck.hxx" + +#include "rutil/ssl/SHA1Stream.hxx" + +#if !defined(WIN32) +#include <sys/types.h> +#include <sys/uio.h> +#if !defined(TARGET_ANDROID) +# include <sys/fcntl.h> +#endif +#include <unistd.h> +#include <dirent.h> +#endif + +#include <sys/types.h> +#include <openssl/e_os2.h> +#include <openssl/evp.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/pem.h> +#include <openssl/pkcs7.h> +#include <openssl/ossl_typ.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/ssl.h> + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +static const Data PEM(".pem"); + +static const Data rootCert("root_cert_"); +static const Data domainCert("domain_cert_"); +static const Data domainKey("domain_key_"); +static const Data userCert("user_cert_"); +static const Data userKey("user_key_"); +static const Data unknownKey("user_key_"); + +static const Data +pemTypePrefixes( Security::PEMType pType ) +{ + switch (pType) + { + case Security::RootCert: return rootCert; + case Security::DomainCert: return domainCert; + case Security::DomainPrivateKey: return domainKey; + case Security::UserCert: return userCert; + case Security::UserPrivateKey: return userKey; + default: + { + ErrLog( << "Some unkonw pem type prefix requested" << (int)(pType) ); + assert(0); + } + } + return unknownKey; +} + +static Data +readIntoData(const Data& filename) +{ + DebugLog( << "Trying to read file " << filename ); + + ifstream is; + is.open(filename.c_str(), ios::binary ); + if ( !is.is_open() ) + { + ErrLog( << "Could not open file " << filename << " for read"); + throw BaseSecurity::Exception("Could not read file ", + __FILE__,__LINE__); + } + + assert(is.is_open()); + + int length = 0; + + // get length of file: +#if !defined(__MSL_CPP__) || (__MSL_CPP_ >= 0x00012000) + is.seekg (0, ios::end); + length = (int)is.tellg(); + is.seekg (0, ios::beg); +#else + // this is a work around for a bug in CodeWarrior 9's implementation of seekg. + // http://groups.google.ca/group/comp.sys.mac.programmer.codewarrior/browse_frm/thread/a4279eb75f3bd55a + FILE * tmpFile = fopen(filename.c_str(), "r+b"); + assert(tmpFile != NULL); + fseek(tmpFile, 0, SEEK_END); + length = ftell(tmpFile); + fseek(tmpFile, 0, SEEK_SET); +#endif // __MWERKS__ + + // tellg/tell will return -1 if the stream is bad + if (length == -1) + { + ErrLog( << "Could not seek into file " << filename); + throw BaseSecurity::Exception("Could not seek into file ", + __FILE__,__LINE__); + } + + // !jf! +1 is a workaround for a bug in Data::c_str() that adds the 0 without + // resizing. + char* buffer = new char [length+1]; + + // read data as a block: + is.read (buffer,length); + + Data target(Data::Take, buffer, length); + + is.close(); + + return target; +} + + +static Data +getAor(const Data& filename, const Security::PEMType &pemType ) +{ + const Data& prefix = pemTypePrefixes( pemType ); + return filename.substr(prefix.size(), filename.size() - prefix.size() - PEM.size()); +} + + +int +verifyCallback(int iInCode, X509_STORE_CTX *pInStore) +{ + char cBuf1[500]; + char cBuf2[500]; + X509 *pErrCert; + int iErr = 0; + int iDepth = 0; + pErrCert = X509_STORE_CTX_get_current_cert(pInStore); + iErr = X509_STORE_CTX_get_error(pInStore); + iDepth = X509_STORE_CTX_get_error_depth(pInStore); + + if (NULL != pErrCert) + X509_NAME_oneline(X509_get_subject_name(pErrCert),cBuf1,256); + + sprintf(cBuf2,", depth=%d %s\n",iDepth,cBuf1); + if(!iInCode) + ErrLog(<< "Error when verifying server's chain of certificates: " << X509_verify_cert_error_string(pInStore->error) << cBuf2 ); + return 1; + return iInCode; +} + + +// .amr. RFC 5922 mandates exact match only on certificates, so this is the default, but RFC 2459 and RFC 3261 don't prevent wildcards, so enable if you want that mode. +bool BaseSecurity::mAllowWildcardCertificates = false; +BaseSecurity::CipherList BaseSecurity::ExportableSuite("!SSLv2:aRSA+AES:aDSS+AES:@STRENGTH:aRSA+3DES:aDSS+3DES:aRSA+RC4+MEDIUM:aDSS+RC4+MEDIUM:aRSA+DES:aDSS+DES:aRSA+RC4:aDSS+RC4"); +BaseSecurity::CipherList BaseSecurity::StrongestSuite("!SSLv2:aRSA+AES:aDSS+AES:@STRENGTH:aRSA+3DES:aDSS+3DES"); + +Security::Security(const CipherList& cipherSuite) : BaseSecurity(cipherSuite) +{ +#ifdef WIN32 + mPath = "C:\\sipCerts\\"; +#else + const char* env=getenv("HOME"); + if(env) + { + mPath = env; + } + mPath += "/.sipCerts/"; +#endif +} + +Security::Security(const Data& directory, const CipherList& cipherSuite) : + BaseSecurity(cipherSuite), + mPath(directory) +{ + // since the preloader won't work otherwise and VERY difficult to figure + // out. + if ( !mPath.postfix(Symbols::SLASH)) + { + mPath += Symbols::SLASH; + } +} + +void +Security::addCADirectory(const Data& caDirectory) +{ + mCADirectories.push_back(caDirectory); + Data &_dir = mCADirectories.back(); + if ( !_dir.postfix(Symbols::SLASH)) + { + _dir += Symbols::SLASH; + } +} + +void +Security::addCAFile(const Data& caFile) +{ + mCAFiles.push_back(caFile); +} + +void +Security::preload() +{ + FileSystem::Directory dir(mPath); + FileSystem::Directory::iterator it(dir); + for (; it != dir.end(); ++it) + { + Data name = *it; + + if (name.postfix(PEM)) + { + Data fileName = mPath + name; + bool attemptedToLoad = true; + + DebugLog(<< "Checking to load file " << name ); + try + { + if (name.prefix(pemTypePrefixes(UserCert))) + { + addCertPEM( UserCert, getAor(name, UserCert), readIntoData(fileName), false ); + } + else if (name.prefix(pemTypePrefixes(UserPrivateKey))) + { + addPrivateKeyPEM( UserPrivateKey, getAor(name, UserPrivateKey), readIntoData(fileName), false); + } + else if (name.prefix(pemTypePrefixes(DomainCert))) + { + addCertPEM( DomainCert, getAor(name, DomainCert), readIntoData(fileName), false); + } + else if (name.prefix(pemTypePrefixes(DomainPrivateKey))) + { + addPrivateKeyPEM( DomainPrivateKey, getAor(name, DomainPrivateKey), readIntoData(fileName), false); + } + else if (name.prefix(pemTypePrefixes(RootCert))) + { + addRootCertPEM(readIntoData(fileName)); + } + else + { + DebugLog(<< "PEM file " << name << " does not have appropriate resip prefix, skipping..."); + // Try to load as root cert PEM + try + { + addRootCertPEM(readIntoData(fileName)); + } + catch (Exception& e) + {} + } + } + catch (Exception& e) + { + ErrLog(<< "Some problem reading " << fileName << ": " << e); + } + catch (...) + { + ErrLog(<< "Some problem reading " << fileName ); + } + + if(attemptedToLoad) + { + InfoLog(<<"Successfully loaded " << fileName ); + } + } + } + std::list<Data>::iterator it_d = mCADirectories.begin(); + for (; it_d != mCADirectories.end(); ++it_d) + { + const Data _dir = *it_d; + FileSystem::Directory dir(_dir); + FileSystem::Directory::iterator it(dir); + for (; it != dir.end(); ++it) + { + if(!it.is_directory()) + { + Data name = *it; + Data fileName = _dir + name; + addCAFile(fileName); + } + } + } + std::list<Data>::iterator it_f = mCAFiles.begin(); + for (; it_f != mCAFiles.end(); ++it_f) + { + const Data _file = *it_f; + try + { + addRootCertPEM(readIntoData(_file)); + InfoLog(<<"Successfully loaded " << _file); + } + catch (Exception& e) + { + ErrLog(<< "Some problem reading " << _file << ": " << e); + } + catch (...) + { + ErrLog(<< "Some problem reading " << _file); + } + } +} + +SSL_CTX* +Security::createDomainCtx(const SSL_METHOD* method, const Data& domain) +{ +#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL ) + SSL_CTX* ctx = SSL_CTX_new(method); +#else + SSL_CTX* ctx = SSL_CTX_new((SSL_METHOD*)method); +#endif + assert(ctx); + + X509_STORE* x509Store = X509_STORE_new(); + assert(x509Store); + + // Load root certs into store + X509List::iterator it; + for(it = mRootCerts.begin(); it != mRootCerts.end(); it++) + { + X509_STORE_add_cert(x509Store,*it); + } + SSL_CTX_set_cert_store(ctx, x509Store); + + // Load domain cert chain and private key + if(!domain.empty()) + { + Data certFilename(mPath + pemTypePrefixes(DomainCert) + domain + PEM); + if(SSL_CTX_use_certificate_chain_file(ctx, certFilename.c_str()) != 1) + { + ErrLog (<< "Error reading domain chain file " << certFilename); + SSL_CTX_free(ctx); + throw BaseSecurity::Exception("Failed opening PEM chain file", __FILE__,__LINE__); + } + Data keyFilename(mPath + pemTypePrefixes(DomainPrivateKey) + domain + PEM); + if(SSL_CTX_use_PrivateKey_file(ctx, keyFilename.c_str(), SSL_FILETYPE_PEM) != 1) + { + ErrLog (<< "Error reading domain private key file " << keyFilename); + SSL_CTX_free(ctx); + throw BaseSecurity::Exception("Failed opening PEM private key file", __FILE__,__LINE__); + } + if (!SSL_CTX_check_private_key(ctx)) + { + ErrLog (<< "Invalid domain private key from file: " << keyFilename); + SSL_CTX_free(ctx); + throw BaseSecurity::Exception("Invalid domain private key", __FILE__,__LINE__); + } + } + + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verifyCallback); + SSL_CTX_set_cipher_list(ctx, mCipherList.cipherList().c_str()); + + return ctx; +} + +void +Security::onReadPEM(const Data& name, PEMType type, Data& buffer) const +{ + Data filename = mPath + pemTypePrefixes(type) + name + PEM; + + InfoLog (<< "Reading PEM file " << filename << " into " << name); + // .dlb. extra copy + buffer = readIntoData(filename); +} + + +void +Security::onWritePEM(const Data& name, PEMType type, const Data& buffer) const +{ + Data filename = mPath + pemTypePrefixes(type) + name + PEM; + InfoLog (<< "Writing PEM file " << filename << " for " << name); + ofstream str(filename.c_str(), ios::binary); + if (!str) + { + ErrLog (<< "Can't write to " << filename); + throw BaseSecurity::Exception("Failed opening PEM file", __FILE__,__LINE__); + } + else + { + str.write(buffer.data(), buffer.size()); + if (!str) + { + ErrLog (<< "Failed writing to " << filename << " " << buffer.size() << " bytes"); + throw BaseSecurity::Exception("Failed writing PEM file", __FILE__,__LINE__); + } + } +} + + +void +Security::onRemovePEM(const Data& name, PEMType type) const +{ + assert(0); + // TODO - should delete file +} + + +void +BaseSecurity::addCertDER (PEMType type, + const Data& key, + const Data& certDER, + bool write) +{ + if( certDER.empty() ) + { + ErrLog(<< "File is empty. Skipping."); + return; + } + + X509* cert = 0; + +#if (OPENSSL_VERSION_NUMBER < 0x0090800fL ) + unsigned char* in = (unsigned char*)certDER.data(); +#else + unsigned const char* in = (unsigned const char*)certDER.data(); +#endif + + if (d2i_X509(&cert,&in,(long)certDER.size()) == 0) + { + ErrLog(<< "Could not read DER certificate from " << certDER ); + throw BaseSecurity::Exception("Could not read DER certificate ", + __FILE__,__LINE__); + } + addCertX509(type,key,cert,write); +} + + +void +BaseSecurity::addCertPEM (PEMType type, + const Data& name, + const Data& certPEM, + bool write) +{ + if( certPEM.empty() ) + { + ErrLog(<< name << " is empty. Skipping."); + return; + } + X509* cert=NULL; + + BIO* in = BIO_new_mem_buf(const_cast<char*>(certPEM.c_str()), -1); + if ( !in ) + { + ErrLog(<< "Could not create BIO buffer from '" << certPEM << "'"); + throw Exception("Could not create BIO buffer", __FILE__,__LINE__); + } + cert = PEM_read_bio_X509(in,0,0,0); + if (cert == NULL) + { + ErrLog( << "Could not load X509 cert from '" << certPEM << "'" ); + BIO_free(in); + throw Exception("Could not load X509 cert from BIO buffer", __FILE__,__LINE__); + } + + addCertX509(type,name,cert,write); + + BIO_free(in); +} + + +void +BaseSecurity::addCertX509(PEMType type, const Data& key, X509* cert, bool write) +{ + switch (type) + { + case DomainCert: + { + mDomainCerts.insert(std::make_pair(key, cert)); + } + break; + case UserCert: + { + mUserCerts.insert(std::make_pair(key, cert)); + } + break; + case RootCert: + { + mRootCerts.push_back(cert); + X509_STORE_add_cert(mRootTlsCerts,cert); + X509_STORE_add_cert(mRootSslCerts,cert); + } + break; + default: + { + assert(0); + } + } + + if (write) + { + // creates a read/write BIO buffer. + BIO *out = BIO_new(BIO_s_mem()); + if(!out) + { + ErrLog(<< "Failed to create BIO: this cert will not be added."); + assert(0); + return; + } + + try + { + int ret = PEM_write_bio_X509(out, cert); + if(!ret) + { + assert(0); + throw Exception("PEM_write_bio_X509 failed: this cert will not be " + "added.", __FILE__,__LINE__); + } + + (void)BIO_flush(out); + // get content in BIO buffer to our buffer. + char* p = 0; + size_t len = BIO_get_mem_data(out,&p); + if(!p || !len) + { + assert(0); + throw Exception("BIO_get_mem_data failed: this cert will not be " + "added.", __FILE__,__LINE__); + } + Data buf(Data::Borrow, p, len); + + //this->onWritePEM(key, type, buf); + } + catch(Exception& e) + { + ErrLog(<<"Caught exception: " << e); + } + catch(std::exception& e) + { + ErrLog(<<"Caught unknown exception, rethrowing"); + BIO_free(out); + throw e; + } + BIO_free(out); + } +} + + +bool +BaseSecurity::hasCert (PEMType type, const Data& aor) const +{ + assert( !aor.empty() ); + const X509Map& certs = (type == DomainCert ? mDomainCerts : mUserCerts); + + X509Map::const_iterator where = certs.find(aor); + if (where != certs.end()) + { + return true; + } + + return false; + /* + try + { + Data certPEM; + onReadPEM(aor, type, certPEM); + if (certPEM.empty()) + { + return false; + } + BaseSecurity* mutable_this = const_cast<BaseSecurity*>(this); + mutable_this->addCertPEM(type, aor, certPEM, false); + } + catch (Exception& e) + { + ErrLog(<<"Caught exception: " << e); + return false; + } + catch (...) + { + ErrLog(<<"Caught exception: "); + return false; + } + + assert( certs.find(aor) != certs.end() ); + + return true; + */ +} + + +void +BaseSecurity::removeCert (PEMType type, const Data& aor) +{ + assert( !aor.empty() ); + X509Map& certs = (type == DomainCert ? mDomainCerts : mUserCerts); + + X509Map::iterator iter = certs.find(aor); + if (iter != certs.end()) + { + X509_free(iter->second); + certs.erase(iter); + + onRemovePEM(aor, type); + } + + assert( certs.find(aor) == certs.end() ); +} + + +Data +BaseSecurity::getCertDER (PEMType type, const Data& key) const +{ + assert( !key.empty() ); + + if (hasCert(type, key) == false) + { + ErrLog(<< "Could not find certificate for '" << key << "'"); + throw BaseSecurity::Exception("Could not find certificate", __FILE__,__LINE__); + } + + const X509Map& certs = (type == DomainCert ? mDomainCerts : mUserCerts); + BaseSecurity::X509Map::const_iterator where = certs.find(key); + if (where == certs.end()) + { + // not supposed to happen, + // hasCert() should have inserted a value into certs + // or we should have throwed. + assert(0); + } + + //assert(0); // the code following this has no hope of working + + X509* x = where->second; + unsigned char* buffer=0; + int len = i2d_X509(x, &buffer); + + // !kh! + // Although len == 0 is not an error, I am not sure what quite to do. + // Asserting for now. + assert(len != 0); + if(len < 0) + { + ErrLog(<< "Could encode certificate of '" << key << "' to DER form"); + throw BaseSecurity::Exception("Could encode certificate to DER form", __FILE__,__LINE__); + } + Data certDER((char*)buffer, len); + OPENSSL_free(buffer); + return certDER; +} + + +void +BaseSecurity::addPrivateKeyPKEY(PEMType type, + const Data& name, + EVP_PKEY* pKey, + bool write) +{ + PrivateKeyMap& privateKeys = (type == DomainPrivateKey ? + mDomainPrivateKeys : mUserPrivateKeys); + + /* + // make a copy of the the key + assert( EVP_PKEY_type(pKey->type) == EVP_PKEY_RSA ); + RSA* rsa = EVP_PKEY_get1_RSA(pKey); + assert( rsa ); + EVP_PKEY* nKey = EVP_PKEY_new(); + assert( nKey ); + EVP_PKEY_set1_RSA(nKey, rsa); + */ + + //privateKeys.insert(std::make_pair(name, nKey)); + privateKeys.insert(std::make_pair(name, pKey)); + + if (write) + { + // figure out a passPhrase to encrypt with + char* kstr=NULL; + int klen=0; + if (type != DomainPrivateKey) + { + PassPhraseMap::const_iterator iter = mUserPassPhrases.find(name); + if(iter != mUserPassPhrases.end()) + { + kstr = (char*)iter->second.c_str(); + klen = (int)iter->second.size(); + } + } + + BIO *bio = BIO_new(BIO_s_mem()); + if(!bio) + { + ErrLog(<< "BIO_new failed: cannot add private key."); + assert(0); + } + + try + { + assert( EVP_des_ede3_cbc() ); + const EVP_CIPHER* cipher = EVP_des_ede3_cbc(); + if (kstr == NULL ) + { + cipher = NULL; + } +#if 0 // TODO - need to figure out what format to write in + int ret = PEM_write_bio_PrivateKey(bio, pKey, cipher, + (unsigned char*)kstr, klen, + NULL, NULL); +#else + int ret = PEM_write_bio_PKCS8PrivateKey(bio, pKey, cipher, + kstr, klen, + NULL, NULL); +#endif + if(!ret) + { + assert(0); + throw Exception("PEM_write_bio_PKCS8PrivateKey failed: cannot add" + " private key.", __FILE__, __LINE__); + } + + (void)BIO_flush(bio); + char* p = 0; + size_t len = BIO_get_mem_data(bio,&p); + if(!p || !len) + { + assert(0); + throw Exception("BIO_get_mem_data failed: cannot add" + " private key.", __FILE__, __LINE__); + } + Data pem(Data::Borrow, p, len); + onWritePEM(name, type, pem ); + } + catch(Exception& e) + { + ErrLog( << "Caught exception: " << e); + } + catch(std::exception& e) + { + ErrLog(<<"Caught unknown exception, rethrowing: " << e.what()); + BIO_free(bio); + throw e; + } + BIO_free(bio); + } +} + + +void +BaseSecurity::addPrivateKeyDER( PEMType type, + const Data& name, + const Data& privateKeyDER, + bool write ) +{ + assert( !name.empty() ); + if( privateKeyDER.empty() ) + { + ErrLog(<< name << " is empty. Skipping."); + return; + } + + char* passPhrase = 0; + if (type != DomainPrivateKey) + { + PassPhraseMap::const_iterator iter = mUserPassPhrases.find(name); + if(iter != mUserPassPhrases.end()) + { + passPhrase = const_cast<char*>(iter->second.c_str()); + } + } + + BIO* in = BIO_new_mem_buf(const_cast<char*>(privateKeyDER.c_str()), -1); + if ( !in ) + { + ErrLog(<< "Could create BIO buffer from '" << privateKeyDER << "'"); + throw Exception("Could not create BIO buffer", __FILE__,__LINE__); + } + + try + { + + EVP_PKEY* privateKey; + if (d2i_PKCS8PrivateKey_bio(in, &privateKey, 0, passPhrase) == 0) + { + ErrLog(<< "Could not read private key from <" << privateKeyDER << ">" ); + throw Exception("Could not read private key ", __FILE__,__LINE__); + } + + addPrivateKeyPKEY(type,name,privateKey,write); + } + catch(std::exception& e) + { + ErrLog(<<"Caught exception: "); + BIO_free(in); + throw e; + } + + BIO_free(in); +} + + +void +BaseSecurity::addPrivateKeyPEM( PEMType type, + const Data& name, + const Data& privateKeyPEM, + bool write ) +{ + assert( !name.empty() ); + if( privateKeyPEM.empty() ) + { + ErrLog(<< name << " is empty. Skipping."); + return; + } + + BIO* in = BIO_new_mem_buf(const_cast<char*>(privateKeyPEM.c_str()), -1); + if ( !in ) + { + ErrLog(<< "Could create BIO buffer from '" << privateKeyPEM << "'"); + throw Exception("Could not create BIO buffer", __FILE__,__LINE__); + } + + char* passPhrase = 0; + try + { + if (type == UserPrivateKey) + { + PassPhraseMap::const_iterator iter = mUserPassPhrases.find(name); + if(iter != mUserPassPhrases.end()) + { + passPhrase = const_cast<char*>(iter->second.c_str()); + } + } + + EVP_PKEY* privateKey=0; + if ( ( privateKey = PEM_read_bio_PrivateKey(in, NULL, 0, passPhrase)) == NULL) + { + ErrLog(<< "Could not read private key from <" << privateKeyPEM << ">" ); + throw Exception("Could not read private key ", __FILE__,__LINE__); + } + + addPrivateKeyPKEY(type,name,privateKey,write); + } + catch(std::exception& e) + { + ErrLog(<<"Caught exception: "); + BIO_free(in); + throw e; + } + + BIO_free(in); +} + + +bool +BaseSecurity::hasPrivateKey( PEMType type, + const Data& key ) const +{ + assert( !key.empty() ); + + const PrivateKeyMap& privateKeys = (type == DomainPrivateKey + ? mDomainPrivateKeys : mUserPrivateKeys); + + PrivateKeyMap::const_iterator where = privateKeys.find(key); + if (where != privateKeys.end()) + { + return true; + } + + Data privateKeyPEM; + try + { + onReadPEM(key, type, privateKeyPEM); + BaseSecurity* mutable_this = const_cast<BaseSecurity*>(this); + mutable_this->addPrivateKeyPEM(type, key, privateKeyPEM, false); + } + catch(std::exception& e) + { + ErrLog(<<"Caught exception: " << e.what()); + return false; + } + catch(...) + { + ErrLog(<<"Caught unknown class!"); + return false; + } + + return true; +} + + +Data +BaseSecurity::getPrivateKeyPEM( PEMType type, + const Data& key) const +{ + assert( !key.empty() ); + + if ( !hasPrivateKey(type, key) ) + { + ErrLog(<< "Could find private key for '" << key << "'"); + throw Exception("Could not find private key", __FILE__,__LINE__); + } + + const PrivateKeyMap& privateKeys = (type == DomainPrivateKey ? mDomainPrivateKeys : mUserPrivateKeys); + + PrivateKeyMap::const_iterator where = privateKeys.find(key); + char* p = 0; + if (type != DomainPrivateKey) + { + PassPhraseMap::const_iterator iter = mUserPassPhrases.find(key); + if (iter != mUserPassPhrases.end()) + { + p = const_cast<char*>(iter->second.c_str()); + } + } + + assert(0); // TODO - following code has no hope of working + + // !kh! + // creates a read/write BIO buffer. + BIO *out = BIO_new(BIO_s_mem()); + assert(out); + EVP_PKEY* pk = where->second; + assert(pk); + + // write pk to out using key phrase p, with no cipher. + int ret = PEM_write_bio_PrivateKey(out, pk, 0, 0, 0, 0, p); // paraters + // are in the wrong order + (void)ret; + assert(ret == 1); + + // get content in BIO buffer to our buffer. + // hand our buffer to a Data object. + (void)BIO_flush(out); + char* buf = 0; + int len = BIO_get_mem_data(out, &buf); + Data retVal(Data::Borrow, buf, len); + + BIO_free(out); + + return retVal; +} + + +Data +BaseSecurity::getPrivateKeyDER( PEMType type, + const Data& key) const +{ + assert( !key.empty() ); + + if ( !hasPrivateKey(type, key) ) + { + ErrLog(<< "Could find private key for '" << key << "'"); + throw Exception("Could not find private key", __FILE__,__LINE__); + } + + const PrivateKeyMap& privateKeys = (type == DomainPrivateKey ? mDomainPrivateKeys : mUserPrivateKeys); + + PrivateKeyMap::const_iterator where = privateKeys.find(key); + char* p = 0; + if (type != DomainPrivateKey) + { + PassPhraseMap::const_iterator iter = mUserPassPhrases.find(key); + if(iter != mUserPassPhrases.end()) + { + p = const_cast<char*>(iter->second.c_str()); + } + } + + assert(0); // TODO - following code has no hope of working + + // !kh! + // creates a read/write BIO buffer. + BIO *out = BIO_new(BIO_s_mem()); + assert(out); + EVP_PKEY* pk = where->second; + assert(pk); + + // write pk to out using key phrase p, with no cipher. + int ret = i2d_PKCS8PrivateKey_bio(out, pk, 0, 0, 0, 0, p); + (void)ret; + assert(ret == 1); + + // get content in BIO buffer to our buffer. + // hand our buffer to a Data object. + (void)BIO_flush(out); + char* buf = 0; + int len = BIO_get_mem_data(out, &buf); + Data retVal(Data::Borrow, buf, len); + + BIO_free(out); + + return retVal; +} + + +void +BaseSecurity::removePrivateKey(PEMType type, const Data& key) +{ + assert( !key.empty() ); + + PrivateKeyMap& privateKeys = (type == DomainPrivateKey ? mDomainPrivateKeys : mUserPrivateKeys); + + assert( !key.empty() ); + PrivateKeyMap::iterator iter = privateKeys.find(key); + if (iter != privateKeys.end()) + { + EVP_PKEY_free(iter->second); + privateKeys.erase(iter); + + onRemovePEM(key, type); + } +} + + +Security::Exception::Exception(const Data& msg, const Data& file, const int line) +: BaseException(msg,file,line) +{ +} + + +BaseSecurity::BaseSecurity (const CipherList& cipherSuite) : + mTlsCtx(0), + mSslCtx(0), + mCipherList(cipherSuite), + mRootTlsCerts(0), + mRootSslCerts(0) +{ + DebugLog(<< "BaseSecurity::BaseSecurity"); + + int ret; + initialize(); + + mRootTlsCerts = X509_STORE_new(); + mRootSslCerts = X509_STORE_new(); + assert(mRootTlsCerts && mRootSslCerts); + + mTlsCtx = SSL_CTX_new( TLSv1_method() ); + if (!mTlsCtx) + { + ErrLog(<< "SSL_CTX_new failed, dumping OpenSSL error stack:"); + while (ERR_peek_error()) + { + char errBuf[120]; + ERR_error_string(ERR_get_error(), errBuf); + ErrLog(<< "OpenSSL error stack: " << errBuf); + } + } + assert(mTlsCtx); + + SSL_CTX_set_cert_store(mTlsCtx, mRootTlsCerts); + SSL_CTX_set_verify(mTlsCtx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verifyCallback); + ret = SSL_CTX_set_cipher_list(mTlsCtx, cipherSuite.cipherList().c_str()); + assert(ret); + + mSslCtx = SSL_CTX_new( SSLv23_method() ); + assert(mSslCtx); + SSL_CTX_set_cert_store(mSslCtx, mRootSslCerts); + SSL_CTX_set_verify(mSslCtx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verifyCallback); + ret = SSL_CTX_set_cipher_list(mSslCtx,cipherSuite.cipherList().c_str()); + assert(ret); +} + + +template<class T, class Func> +void clearMap(T& m, Func& clearFunc) +{ + for (typename T::iterator it = m.begin(); it != m.end(); it++) + { + clearFunc(it->second); + } + m.clear(); +} + +template<class T, class Func> +void clearList(T& m, Func& clearFunc) +{ + for (typename T::iterator it = m.begin(); it != m.end(); it++) + { + clearFunc(*it); + } + m.clear(); +} + +BaseSecurity::~BaseSecurity () +{ + DebugLog(<< "BaseSecurity::~BaseSecurity"); + + // cleanup certificates + clearList(mRootCerts, X509_free); + clearMap(mDomainCerts, X509_free); + clearMap(mUserCerts, X509_free); + + // cleanup private keys + clearMap(mDomainPrivateKeys, EVP_PKEY_free); + clearMap(mUserPrivateKeys, EVP_PKEY_free); + + // cleanup SSL_CTXes + if (mTlsCtx) + { + SSL_CTX_free(mTlsCtx);mTlsCtx=0; // This free's X509_STORE (mRootTlsCerts) + } + if (mSslCtx) + { + SSL_CTX_free(mSslCtx);mSslCtx=0; // This free's X509_STORE (mRootSslCerts) + } + +} + + +void +BaseSecurity::initialize () +{ + Timer::getTimeMs(); // initalize time offsets +} + + +Security::CertificateInfoContainer +BaseSecurity::getRootCertDescriptions() const +{ + // !kh! + // need to be implemented. + assert(0); // TODO + return CertificateInfoContainer(); +} + + +void +BaseSecurity::addRootCertPEM(const Data& x509PEMEncodedRootCerts) +{ + assert( mRootTlsCerts && mRootSslCerts ); +#if 1 + addCertPEM(RootCert,Data::Empty,x509PEMEncodedRootCerts,false); +#else + assert( !x509PEMEncodedRootCerts.empty() ); + + static X509_LOOKUP_METHOD x509_pemstring_lookup = + { + "Load cert from PEM string into cache", + NULL, /* new */ + NULL, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + pemstring_ctrl,/* ctrl */ + NULL, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ + }; + + if (mRootCerts == 0) + { + mRootCerts = X509_STORE_new(); + } + + assert( mRootCerts ); + + X509_LOOKUP* lookup = X509_STORE_add_lookup(mRootCerts, &x509_pemstring_lookup); + + if (lookup == NULL) + throw Exception("Error in BaseSecurity::addRootCertPEM()", __FILE__,__LINE__); + + // !kh! + // bug, no error handling here. + X509_LOOKUP_ctrl(lookup, X509_L_FILE_LOAD, x509PEMEncodedRootCerts.c_str(), 0, 0); +#endif +} + + +void +BaseSecurity::addDomainCertPEM(const Data& domainName, const Data& certPEM) +{ + addCertPEM(DomainCert, domainName, certPEM, true); +} + + +void +BaseSecurity::addDomainCertDER(const Data& domainName, const Data& certDER) +{ + addCertDER(DomainCert, domainName, certDER, true); +} + + +bool +BaseSecurity::hasDomainCert(const Data& domainName) const +{ + return hasCert(DomainCert, domainName); +} + + +void +BaseSecurity::removeDomainCert(const Data& domainName) +{ + return removeCert(DomainCert, domainName); +} + + +Data +BaseSecurity::getDomainCertDER(const Data& domainName) const +{ + return getCertDER(DomainCert, domainName); +} + + +void +BaseSecurity::addDomainPrivateKeyPEM(const Data& domainName, const Data& privateKeyPEM) +{ + addPrivateKeyPEM(DomainPrivateKey, domainName, privateKeyPEM, true); +} + + +bool +BaseSecurity::hasDomainPrivateKey(const Data& domainName) const +{ + return hasPrivateKey(DomainPrivateKey, domainName); +} + + +void +BaseSecurity::removeDomainPrivateKey(const Data& domainName) +{ + removePrivateKey(DomainPrivateKey, domainName); +} + + +Data +BaseSecurity::getDomainPrivateKeyPEM(const Data& domainName) const +{ + return getPrivateKeyPEM(DomainPrivateKey, domainName); +} + + +void +BaseSecurity::addUserCertPEM(const Data& aor, const Data& certPEM) +{ + addCertPEM(UserCert, aor, certPEM, true); +} + + +void +BaseSecurity::addUserCertDER(const Data& aor, const Data& certDER) +{ + addCertDER(UserCert, aor, certDER, true); +} + + +bool +BaseSecurity::hasUserCert(const Data& aor) const +{ + return hasCert(UserCert, aor); +} + + +void +BaseSecurity::removeUserCert(const Data& aor) +{ + removeCert(UserCert, aor); +} + + +Data +BaseSecurity::getUserCertDER(const Data& aor) const +{ + return getCertDER(UserCert, aor); +} + + +void +BaseSecurity::setUserPassPhrase(const Data& aor, const Data& passPhrase) +{ + assert(!aor.empty()); + + PassPhraseMap::iterator iter = mUserPassPhrases.find(aor); + if (iter == mUserPassPhrases.end()) + { + mUserPassPhrases.insert(std::make_pair(aor, passPhrase)); + } +} + + +bool +BaseSecurity::hasUserPassPhrase(const Data& aor) const +{ + assert(aor.empty()); + + PassPhraseMap::const_iterator iter = mUserPassPhrases.find(aor); + if (iter == mUserPassPhrases.end()) + { + return false; + } + else + { + return true; + } +} + + +void +BaseSecurity::removeUserPassPhrase(const Data& aor) +{ + assert(aor.empty()); + + PassPhraseMap::iterator iter = mUserPassPhrases.find(aor); + if(iter != mUserPassPhrases.end()) + { + mUserPassPhrases.erase(iter); + } +} + + +Data +BaseSecurity::getUserPassPhrase(const Data& aor) const +{ + assert(aor.empty()); + + PassPhraseMap::const_iterator iter = mUserPassPhrases.find(aor); + if(iter == mUserPassPhrases.end()) + { + return iter->second; + } + else + { + return Data::Empty; + } +} + + +void +BaseSecurity::addUserPrivateKeyPEM(const Data& aor, const Data& cert) +{ + addPrivateKeyPEM(UserPrivateKey, aor, cert, true); +} + + +void +BaseSecurity::addUserPrivateKeyDER(const Data& aor, const Data& cert) +{ + addPrivateKeyDER(UserPrivateKey, aor, cert, true); +} + + +bool +BaseSecurity::hasUserPrivateKey(const Data& aor) const +{ + return hasPrivateKey(UserPrivateKey, aor); +} + + +void +BaseSecurity::removeUserPrivateKey(const Data& aor) +{ + removePrivateKey(UserPrivateKey, aor); +} + + +Data +BaseSecurity::getUserPrivateKeyPEM(const Data& aor) const +{ + return getPrivateKeyPEM(UserPrivateKey, aor); +} + + +Data +BaseSecurity::getUserPrivateKeyDER(const Data& aor) const +{ + return getPrivateKeyDER(UserPrivateKey, aor); +} + + +void +BaseSecurity::generateUserCert (const Data& pAor, int expireDays, int keyLen ) +{ + int ret; + + InfoLog( <<"Generating new user cert for " << pAor ); + + Data domain; + Data aor; + + try + { + Uri uri( Data("sip:")+pAor ); + aor = uri.getAor(); + domain = uri.host(); + } + catch (...) + { + ErrLog( <<"Invalid aor passed to generateUserCert"); + throw Exception("Bad aor passed to generateUserCert", __FILE__,__LINE__); + } + + // Make sure that necessary algorithms exist: + assert(EVP_sha1()); + + RSA* rsa = RSA_generate_key(keyLen, RSA_F4, NULL, NULL); + assert(rsa); // couldn't make key pair + + EVP_PKEY* privkey = EVP_PKEY_new(); + assert(privkey); + ret = EVP_PKEY_set1_RSA(privkey, rsa); + assert(ret); + + X509* cert = X509_new(); + assert(cert); + + X509_NAME* subject = X509_NAME_new(); + X509_EXTENSION* ext = X509_EXTENSION_new(); + + // set version to X509v3 (starts from 0) + X509_set_version(cert, 2L); + + int serial = Random::getRandom(); // get an int worth of randomness + assert(sizeof(int)==4); + ASN1_INTEGER_set(X509_get_serialNumber(cert),serial); + + ret = X509_NAME_add_entry_by_txt( subject, "O", MBSTRING_ASC, + (unsigned char *) domain.data(), (int)domain.size(), + -1, 0); + assert(ret); + ret = X509_NAME_add_entry_by_txt( subject, "CN", MBSTRING_ASC, + (unsigned char *) aor.data(), (int)aor.size(), + -1, 0); + assert(ret); + + ret = X509_set_issuer_name(cert, subject); + assert(ret); + ret = X509_set_subject_name(cert, subject); + assert(ret); + + const long duration = 60*60*24*expireDays; + X509_gmtime_adj(X509_get_notBefore(cert),0); + X509_gmtime_adj(X509_get_notAfter(cert), duration); + + ret = X509_set_pubkey(cert, privkey); + assert(ret); + + Data subjectAltNameStr = Data("URI:sip:") + aor + + Data(",URI:im:")+aor + + Data(",URI:pres:")+aor; + ext = X509V3_EXT_conf_nid( NULL , NULL , NID_subject_alt_name, + (char*) subjectAltNameStr.c_str() ); + X509_add_ext( cert, ext, -1); + X509_EXTENSION_free(ext); + + static char CA_FALSE[] = "CA:FALSE"; + ext = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints, CA_FALSE); + ret = X509_add_ext( cert, ext, -1); + assert(ret); + X509_EXTENSION_free(ext); + + // TODO add extensions NID_subject_key_identifier and NID_authority_key_identifier + + ret = X509_sign(cert, privkey, EVP_sha1()); + assert(ret); + + addCertX509( UserCert, aor, cert, true /* write */ ); + addPrivateKeyPKEY( UserPrivateKey, aor, privkey, true /* write */ ); +} + +MultipartSignedContents* +BaseSecurity::sign(const Data& senderAor, Contents* contents) +{ + assert( contents ); + + // form the multipart + MultipartSignedContents* multi = new MultipartSignedContents; + multi->header(h_ContentType).param( p_micalg ) = "sha1"; + multi->header(h_ContentType).param( p_protocol ) = "application/pkcs7-signature"; + + // add the main body to it + Contents* body = contents->clone(); + multi->parts().push_back( body ); + + Data bodyData; + DataStream strm( bodyData ); + body->encodeHeaders( strm ); + body->encode( strm ); + strm.flush(); + + DebugLog( << "signing data <" << bodyData.escaped() << ">" ); + //Security::dumpAsn("resip-sign-out-data",bodyData); + + const char* p = bodyData.data(); + int s = (int)bodyData.size(); + BIO* in=BIO_new_mem_buf( (void*)p,s); + assert(in); + DebugLog( << "created in BIO"); + + BIO* out = BIO_new(BIO_s_mem()); // TODO - mem leak + assert(out); + DebugLog( << "created out BIO" ); + + STACK_OF(X509)* chain = sk_X509_new_null(); + assert(chain); + + DebugLog( << "searching for cert/key for <" << senderAor << ">" ); + if (mUserCerts.count(senderAor) == 0 || + mUserPrivateKeys.count(senderAor) == 0) + { + BIO_free(in); + BIO_free(out); + sk_X509_free(chain); + WarningLog (<< "Tried to sign with no cert or private key for " << senderAor); + throw Exception("No cert or private key to sign with",__FILE__,__LINE__); + } + + X509* publicCert = mUserCerts[senderAor]; + EVP_PKEY* privateKey = mUserPrivateKeys[senderAor]; + + int rv = X509_check_private_key(publicCert, privateKey); + if(!rv) + { + BIO_free(in); + BIO_free(out); + sk_X509_free(chain); + ErrLog (<< "X509_check_private_key failed for " << senderAor); + return 0; + } + + // compute the signature + int flags = 0; + flags |= PKCS7_BINARY; + flags |= PKCS7_DETACHED; + if ( true ) // don't do caps + { + flags |= PKCS7_NOSMIMECAP; + flags |= PKCS7_NOATTR; + } + if ( true ) // don't do certs + { + flags |= PKCS7_NOCERTS; + } + + PKCS7* pkcs7 = PKCS7_sign( publicCert, privateKey, chain, in, flags); + if ( !pkcs7 ) + { + BIO_free(in); + BIO_free(out); + sk_X509_free(chain); + ErrLog( << "Error creating PKCS7 signature object" ); + return 0; + } + DebugLog( << "created PKCS7 signature object " ); + + i2d_PKCS7_bio(out,pkcs7); + (void)BIO_flush(out); + + char* outBuf=0; + long size = BIO_get_mem_data(out,&outBuf); + assert( size > 0 ); + + Data outData(outBuf,size); + static char RESIP_SIGN_OUT_SIG[] = "resip-sign-out-sig"; + Security::dumpAsn(RESIP_SIGN_OUT_SIG,outData); + + Pkcs7SignedContents* sigBody = new Pkcs7SignedContents( outData ); + assert( sigBody ); + + // add the signature to it + sigBody->header(h_ContentType).param( p_name ) = "smime.p7s"; + sigBody->header(h_ContentDisposition).param( p_handling ) = "required"; + sigBody->header(h_ContentDisposition).param( p_filename ) = "smime.p7s"; + sigBody->header(h_ContentDisposition).value() = "attachment" ; + sigBody->header(h_ContentTransferEncoding).value() = "binary"; + multi->parts().push_back( sigBody ); + + assert( multi->parts().size() == 2 ); + + BIO_free(in); + BIO_free(out); + sk_X509_free(chain); + PKCS7_free(pkcs7); + + return multi; +} + + +Pkcs7Contents* +BaseSecurity::encrypt(Contents* bodyIn, const Data& recipCertName ) +{ + assert( bodyIn ); + + int flags = 0 ; + flags |= PKCS7_BINARY; + flags |= PKCS7_NOCERTS; + + Data bodyData; + DataStream strm(bodyData); + bodyIn->encodeHeaders(strm); + bodyIn->encode( strm ); + strm.flush(); + + InfoLog( << "body data to encrypt is <" << bodyData.escaped() << ">" ); + + const char* p = bodyData.data(); + int s = (int)bodyData.size(); + + BIO* in = BIO_new_mem_buf( (void*)p,s); + assert(in); + DebugLog( << "created in BIO"); + + BIO* out = BIO_new(BIO_s_mem()); + assert(out); + DebugLog( << "created out BIO" ); + + InfoLog( << "target cert name is <" << recipCertName << ">" ); + if (mUserCerts.count(recipCertName) == 0) + { + BIO_free(in); + BIO_free(out); + WarningLog (<< "Tried to encrypt with no cert or private key for " << recipCertName); + throw Exception("No cert or private key to encrypt with",__FILE__,__LINE__); + } + + X509* cert = mUserCerts[recipCertName]; + assert(cert); + + STACK_OF(X509) *certs = sk_X509_new_null(); + assert(certs); + sk_X509_push(certs, cert); + +// if you think you need to change the following few lines, please email fluffy +// the value of OPENSSL_VERSION_NUMBER ( in opensslv.h ) and the signature of +// PKCS_encrypt found ( in pkcs7.h ) and the OS you are using +#if ( OPENSSL_VERSION_NUMBER > 0x009060ffL ) +// const EVP_CIPHER* cipher = EVP_des_ede3_cbc(); + const EVP_CIPHER* cipher = EVP_aes_128_cbc(); +#else + //const EVP_CIPHER* cipher = EVP_enc_null(); + EVP_CIPHER* cipher = EVP_des_ede3_cbc(); +#endif + assert( cipher ); + +#if (OPENSSL_VERSION_NUMBER < 0x0090705fL ) +#warning PKCS7_encrypt() is broken in OpenSSL 0.9.7d +#endif + + PKCS7* pkcs7 = PKCS7_encrypt( certs, in, cipher, flags); + if ( !pkcs7 ) + { + BIO_free(in); + BIO_free(out); + sk_X509_free(certs); + ErrLog( << "Error creating PKCS7 encrypt object" ); + //throw Exception("Can't encrypt",__FILE__,__LINE__); + return 0; + } + DebugLog( << "created PKCS7 encrypt object " ); + + i2d_PKCS7_bio(out,pkcs7); + + (void)BIO_flush(out); + + char* outBuf=0; + long size = BIO_get_mem_data(out,&outBuf); + assert( size > 0 ); + + Data outData(outBuf,size); + assert( (long)outData.size() == size ); + + InfoLog( << "Encrypted body size is " << outData.size() ); + InfoLog( << "Encrypted body is <" << outData.escaped() << ">" ); + + static char RESIP_ENCRYPT_OUT[] = "resip-encrypt-out"; + Security::dumpAsn(RESIP_ENCRYPT_OUT, outData); + + Pkcs7Contents* outBody = new Pkcs7Contents( outData ); + assert( outBody ); + + outBody->header(h_ContentType).param( p_smimeType ) = "enveloped-data"; + outBody->header(h_ContentType).param( p_name ) = "smime.p7m"; + outBody->header(h_ContentDisposition).param( p_handling ) = "required"; + outBody->header(h_ContentDisposition).param( p_filename ) = "smime.p7"; + outBody->header(h_ContentDisposition).value() = "attachment" ; + outBody->header(h_ContentTransferEncoding).value() = "binary"; + + BIO_free(in); + BIO_free(out); + sk_X509_free(certs); + PKCS7_free(pkcs7); + + return outBody; +} + + +MultipartSignedContents * +BaseSecurity::signAndEncrypt( const Data& senderAor, Contents* body, const Data& recipCertName ) +{ + //assert(0); + //return 0; + return sign(senderAor, encrypt(body, recipCertName)); +} + + +Data +BaseSecurity::computeIdentity( const Data& signerDomain, const Data& in ) const +{ + DebugLog( << "Compute identity for " << in ); + + PrivateKeyMap::const_iterator k(mDomainPrivateKeys.find(signerDomain)); + if (k == mDomainPrivateKeys.end()) + { + InfoLog( << "No private key for " << signerDomain ); + throw Exception("Missing private key when computing identity",__FILE__,__LINE__); + } + + EVP_PKEY* pKey = k->second; + assert( pKey ); + + if ( pKey->type != EVP_PKEY_RSA ) + { + ErrLog( << "Private key (type=" << pKey->type <<"for " + << signerDomain << " is not of type RSA" ); + throw Exception("No RSA private key when computing identity",__FILE__,__LINE__); + } + + assert( pKey->type == EVP_PKEY_RSA ); + RSA* rsa = EVP_PKEY_get1_RSA(pKey); + + unsigned char result[4096]; + int resultSize = sizeof(result); + assert( resultSize >= RSA_size(rsa) ); + + SHA1Stream sha; + sha << in; + Data hashRes = sha.getBin(); + DebugLog( << "hash of string is 0x" << hashRes.hex() ); + +#if 1 + int r = RSA_sign(NID_sha1, (unsigned char *)hashRes.data(), (unsigned int)hashRes.size(), + result, (unsigned int*)( &resultSize ), + rsa); + if( r != 1 ) + { + ErrLog(<< "RSA_sign failed with return " << r); + assert(0); + return Data::Empty; + } +#else + resultSize = RSA_private_encrypt(hashResLen, hashRes, + result, rsa, RSA_PKCS1_PADDING); + if ( resultSize == -1 ) + { + DebugLog( << "Problem doing RSA encrypt for identity"); + while (1) + { + const char* file; + int line; + + unsigned long code = ERR_get_error_line(&file,&line); + if ( code == 0 ) + { + break; + } + + char buf[256]; + ERR_error_string_n(code,buf,sizeof(buf)); + ErrLog( << buf ); + InfoLog( << "Error code = " << code << " file="<<file<<" line=" << line ); + } + + return Data::Empty; + } +#endif + + Data res(result,resultSize); + DebugLog( << "rsa encrypt of hash is 0x"<< res.hex() ); + + Data enc = res.base64encode(); + + static char IDENTITY_IN[] = "identity-in"; + static char IDENTITY_IN_HASH[] = "identity-in-hash"; + static char IDENTITY_IN_RSA[] = "identity-in-rsa"; + static char IDENTITY_IN_BASE64[] = "identity-in-base64"; + + Security::dumpAsn(IDENTITY_IN, in ); + Security::dumpAsn(IDENTITY_IN_HASH, hashRes ); + Security::dumpAsn(IDENTITY_IN_RSA,res); + Security::dumpAsn(IDENTITY_IN_BASE64,enc); + + return enc; +} + + +bool +BaseSecurity::checkIdentity( const Data& signerDomain, const Data& in, const Data& sigBase64, X509* pCert ) const +{ + X509* cert = pCert; + if (!cert) + { + X509Map::const_iterator x=mDomainCerts.find(signerDomain); + if (x == mDomainCerts.end()) + { + ErrLog( << "No public key for " << signerDomain ); + throw Exception("Missing public key when verifying identity",__FILE__,__LINE__); + } + cert = x->second; + } + + DebugLog( << "Check identity for " << in ); + DebugLog( << " base64 data is " << sigBase64 ); + + Data sig = sigBase64.base64decode(); + DebugLog( << "decoded sig is 0x"<< sig.hex() ); + + SHA1Stream sha; + sha << in; + Data hashRes = sha.getBin(); + DebugLog( << "hash of string is 0x" << hashRes.hex() ); + + EVP_PKEY* pKey = X509_get_pubkey( cert ); + assert( pKey ); + + assert( pKey->type == EVP_PKEY_RSA ); + RSA* rsa = EVP_PKEY_get1_RSA(pKey); + +#if 1 + int ret = RSA_verify(NID_sha1, (unsigned char *)hashRes.data(), + (unsigned int)hashRes.size(), (unsigned char*)sig.data(), (unsigned int)sig.size(), + rsa); +#else + unsigned char result[4096]; + int resultSize = sizeof(result); + assert( resultSize >= RSA_size(rsa) ); + + resultSize = RSA_public_decrypt(sig.size(),(unsigned char*)sig.data(), + result, rsa, RSA_PKCS1_PADDING ); + assert( resultSize != -1 ); + //assert( resultSize == SHA_DIGEST_LENGTH ); + Data recievedHash(result,resultSize); + dumpAsn("identity-out-decrypt", recievedHash ); + + bool ret = ( computedHash == recievedHash ); +#endif + + DebugLog( << "rsa verify result is " << ret ); + + static char IDENTITY_OUT_MSG[] = "identity-out-msg"; + static char IDENTITY_OUT_BASE64[] = "identity-out-base64"; + static char IDENTITY_OUT_SIG[] = "identity-out-sig"; + static char IDENTITY_OUT_HASH[] = "identity-out-hash"; + + Security::dumpAsn(IDENTITY_OUT_MSG, in ); + Security::dumpAsn(IDENTITY_OUT_BASE64,sigBase64); + Security::dumpAsn(IDENTITY_OUT_SIG, sig); + Security::dumpAsn(IDENTITY_OUT_HASH, hashRes ); + + return (ret != 0); +} + + +void +BaseSecurity::checkAndSetIdentity(SipMessage& msg, const Data& certDer) const +{ + auto_ptr<SecurityAttributes> sec(new SecurityAttributes); + X509* cert=NULL; + + try + { + if ( !certDer.empty() ) + { +#if (OPENSSL_VERSION_NUMBER < 0x0090800fL ) + unsigned char* in = (unsigned char*)certDer.data(); +#else + unsigned const char* in = (unsigned const char*)certDer.data(); +#endif + if (d2i_X509(&cert,&in,(long)certDer.size()) == 0) + { + DebugLog(<< "Could not read DER certificate from " << certDer ); + cert = NULL; + } + } + if ( certDer.empty() || cert ) + { + if ( checkIdentity(msg.const_header(h_From).uri().host(), + msg.getCanonicalIdentityString(), + msg.const_header(h_Identity).value(), + cert ) ) + { + sec->setIdentity(msg.const_header(h_From).uri().getAor()); + sec->setIdentityStrength(SecurityAttributes::Identity); + } + else + { + sec->setIdentity(msg.const_header(h_From).uri().getAor()); + sec->setIdentityStrength(SecurityAttributes::FailedIdentity); + } + } + else + { + sec->setIdentity(msg.const_header(h_From).uri().getAor()); + sec->setIdentityStrength(SecurityAttributes::FailedIdentity); + } + } + catch (BaseException& e) + { + ErrLog(<<"Caught exception: "<< e); + sec->setIdentity(msg.const_header(h_From).uri().getAor()); + sec->setIdentityStrength(SecurityAttributes::FailedIdentity); + } + msg.setSecurityAttributes(sec); +} + + +Contents* +BaseSecurity::decrypt( const Data& decryptorAor, const Pkcs7Contents* contents) +{ + + DebugLog( << "decryptor Aor: <" << decryptorAor << ">" ); + + int flags=0; + flags |= PKCS7_BINARY; + + // for now, assume that this is only a singed message + assert( contents ); + + Data text = contents->getBodyData(); + DebugLog( << "uncode body = <" << text.escaped() << ">" ); + DebugLog( << "uncode body size = " << text.size() ); + + static char RESIP_ASN_DECRYPT[] = "resip-asn-decrypt"; + Security::dumpAsn(RESIP_ASN_DECRYPT, text ); + + BIO* in = BIO_new_mem_buf( (void*)text.c_str(), (int)text.size()); + assert(in); + InfoLog( << "created in BIO"); + + BIO* out; + out = BIO_new(BIO_s_mem()); + assert(out); + InfoLog( << "created out BIO" ); + + PKCS7* pkcs7 = d2i_PKCS7_bio(in, 0); + if ( !pkcs7 ) + { + ErrLog( << "Problems doing decode of PKCS7 object" ); + + while (1) + { + const char* file; + int line; + + unsigned long code = ERR_get_error_line(&file,&line); + if ( code == 0 ) + { + break; + } + + char buf[256]; + ERR_error_string_n(code,buf,sizeof(buf)); + ErrLog( << buf ); + InfoLog( << "Error code = " << code << " file=" << file << " line=" << line ); + } + + BIO_free(in); + BIO_free(out); + + return 0; + } + (void)BIO_flush(in); + + int type=OBJ_obj2nid(pkcs7->type); + switch (type) + { + case NID_pkcs7_signed: + InfoLog( << "data is pkcs7 signed" ); + break; + case NID_pkcs7_signedAndEnveloped: + InfoLog( << "data is pkcs7 signed and enveloped" ); + break; + case NID_pkcs7_enveloped: + InfoLog( << "data is pkcs7 enveloped" ); + break; + case NID_pkcs7_data: + InfoLog( << "data i pkcs7 data" ); + break; + case NID_pkcs7_encrypted: + InfoLog( << "data is pkcs7 encrypted " ); + break; + case NID_pkcs7_digest: + InfoLog( << "data is pkcs7 digest" ); + break; + default: + InfoLog( << "Unknown pkcs7 type" ); + break; + } + + STACK_OF(X509)* certs = sk_X509_new_null(); + assert( certs ); + + // flags |= PKCS7_NOVERIFY; + + assert( mRootTlsCerts ); + + switch (type) + { + case NID_pkcs7_signedAndEnveloped: + { + BIO_free(in); + BIO_free(out); + sk_X509_free(certs); + PKCS7_free(pkcs7); + throw Exception("Signed and enveloped is not supported", __FILE__, __LINE__); + } + break; + + case NID_pkcs7_enveloped: + { + if (mUserPrivateKeys.count(decryptorAor) == 0) + { + BIO_free(in); + BIO_free(out); + sk_X509_free(certs); + PKCS7_free(pkcs7); + InfoLog( << "Don't have a private key for " << decryptorAor << " for PKCS7_decrypt" ); + throw Exception("Missing private key", __FILE__, __LINE__); + } + else if (mUserCerts.count(decryptorAor) == 0) + { + BIO_free(in); + BIO_free(out); + sk_X509_free(certs); + PKCS7_free(pkcs7); + InfoLog( << "Don't have a public cert for " << decryptorAor << " for PKCS7_decrypt" ); + throw Exception("Missing cert", __FILE__, __LINE__); + } + + EVP_PKEY* privateKey = mUserPrivateKeys[decryptorAor]; + X509* publicCert = mUserCerts[decryptorAor]; + + if ( PKCS7_decrypt(pkcs7, privateKey, publicCert, out, flags ) != 1 ) + { + ErrLog( << "Problems doing PKCS7_decrypt" ); + while (1) + { + const char* file; + int line; + + unsigned long code = ERR_get_error_line(&file,&line); + if ( code == 0 ) + { + break; + } + + char buf[256]; + ERR_error_string_n(code,buf,sizeof(buf)); + ErrLog( << buf ); + InfoLog( << "Error code = " << code << " file=" << file << " line=" << line ); + } + + BIO_free(in); + BIO_free(out); + sk_X509_free(certs); + PKCS7_free(pkcs7); + return 0; + } + } + break; + + default: + BIO_free(in); + BIO_free(out); + sk_X509_free(certs); + PKCS7_free(pkcs7); + ErrLog(<< "Got PKCS7 data that could not be handled type=" << type ); + throw Exception("Unsupported PKCS7 data type", __FILE__, __LINE__); + } + + (void)BIO_flush(out); + BUF_MEM* bufMem; + BIO_get_mem_ptr(out, &bufMem); + + int len = bufMem->length; + char* buffer = new char[len]; + memcpy(buffer, bufMem->data, len); + + (void)BIO_set_close(out, BIO_CLOSE); + BIO_free(in); + BIO_free(out); + sk_X509_free(certs); + PKCS7_free(pkcs7); + + // parse out the header information and form new body. + // TODO !jf! this is a really crappy parser - shoudl do proper mime stuff + ParseBuffer pb(buffer, len); + + const char* headerStart = pb.position(); + + // pull out contents type only + pb.skipToChars("Content-Type"); + pb.assertNotEof(); + + pb.skipToChar(Symbols::COLON[0]); + pb.skipChar(); + pb.assertNotEof(); + + pb.skipWhitespace(); + const char* typeStart = pb.position(); + pb.assertNotEof(); + + // determine contents-type header buffer + pb.skipToTermCRLF(); + pb.assertNotEof(); + + ParseBuffer subPb(typeStart, pb.position() - typeStart); + Mime contentType; + contentType.parse(subPb); + + pb.assertNotEof(); + + // determine body start + pb.reset(typeStart); + const char* bodyStart = pb.skipToChars(Symbols::CRLFCRLF); + pb.assertNotEof(); + bodyStart += 4; + + // determine contents body buffer + pb.skipToEnd(); + Data tmp; + pb.data(tmp, bodyStart); + // create contents against body + Contents* ret = Contents::createContents(contentType, tmp); + ret->addBuffer(buffer); + + // pre-parse headers + ParseBuffer headersPb(headerStart, bodyStart-4-headerStart); + ret->preParseHeaders(headersPb); + + InfoLog( << "Got body data of " << ret->getBodyData() ); + + return ret; +} + + + + + +Contents* +BaseSecurity::checkSignature(MultipartSignedContents* multi, + Data* signedBy, + SignatureStatus* sigStat ) +{ + if ( multi->parts().size() != 2 ) + { + ErrLog(<< "Trying to decode a message with wrong number of contents " << multi->parts().size()); + throw Exception("Invalid contents passed to checkSignature", __FILE__, __LINE__); + } + + MultipartSignedContents::Parts::const_iterator it = multi->parts().begin(); + Contents* first = *it; + ++it; + assert( it != multi->parts().end() ); + Contents* second = *it; + + assert( second ); + assert( first ); + + InfoLog( << "message to signature-check is " << *first ); + + Pkcs7SignedContents* sig = dynamic_cast<Pkcs7SignedContents*>( second ); + if ( !sig ) + { + ErrLog( << "Don't know how to deal with signature type " ); + //throw Exception("Invalid contents passed to checkSignature", __FILE__, + //__LINE__); + return first; + } + Data sigData = sig->getBodyData(); + + Data textData; + DataStream strm( textData ); + first->encodeHeaders( strm ); + first->encode( strm ); + strm.flush(); + + InfoLog( << "text <" << textData.escaped() << ">" ); + InfoLog( << "signature <" << sigData.escaped() << ">" ); + + static char RESIP_ASN_UNCODE_SIGNED_TEXT[] = "resip-asn-uncode-signed-text"; + static char RESIP_ASN_UNCODE_SIGNED_SIG[] = "resip-asn-uncode-signed-sig"; + + Security::dumpAsn( RESIP_ASN_UNCODE_SIGNED_TEXT, textData ); + Security::dumpAsn( RESIP_ASN_UNCODE_SIGNED_SIG, sigData ); + + BIO* in = BIO_new_mem_buf( (void*)sigData.data(),(int)sigData.size()); + assert(in); + InfoLog( << "created in BIO"); + + BIO* out = BIO_new(BIO_s_mem()); + assert(out); + InfoLog( << "created out BIO" ); + + BIO* pkcs7Bio = BIO_new_mem_buf( (void*) textData.data(),(int)textData.size()); + assert(pkcs7Bio); + InfoLog( << "created pkcs7 BIO"); + + PKCS7* pkcs7 = d2i_PKCS7_bio(in, 0); + if ( !pkcs7 ) + { + ErrLog( << "Problems doing decode of PKCS7 object <" + << sigData.escaped() << ">" ); + + while (1) + { + const char* file; + int line; + + unsigned long code = ERR_get_error_line(&file,&line); + if ( code == 0 ) + { + break; + } + + char buf[256]; + ERR_error_string_n(code,buf,sizeof(buf)); + ErrLog( << buf ); + InfoLog( <<"Error code = "<< code <<" file=" << file << " line=" << line ); + } + BIO_free(in); + BIO_free(out); + BIO_free(pkcs7Bio); + + return first; + } + (void)BIO_flush(in); + + int type=OBJ_obj2nid(pkcs7->type); + switch (type) + { + case NID_pkcs7_signed: + InfoLog( << "data is pkcs7 signed" ); + break; + case NID_pkcs7_signedAndEnveloped: + InfoLog( << "data is pkcs7 signed and enveloped" ); + break; + case NID_pkcs7_enveloped: + InfoLog( << "data is pkcs7 enveloped" ); + break; + case NID_pkcs7_data: + InfoLog( << "data is pkcs7 data" ); + break; + case NID_pkcs7_encrypted: + InfoLog( << "data is pkcs7 encrypted " ); + break; + case NID_pkcs7_digest: + InfoLog( << "data is pkcs7 digest" ); + break; + default: + InfoLog( << "Unknown pkcs7 type" ); + break; + } + + STACK_OF(X509)* certs = 0; + certs = sk_X509_new_null(); + assert( certs ); + + if ( *signedBy == Data::Empty ) + { + //add all the certificates from mUserCerts stack to 'certs' stack + for(X509Map::iterator it = mUserCerts.begin(); it != mUserCerts.end(); it++) + { + assert(it->second); + sk_X509_push(certs, it->second); + } + } + else + { + if (mUserCerts.count( *signedBy )) + { + InfoLog( <<"Adding cert from " << *signedBy << " to check sig" ); + X509* cert = mUserCerts[ *signedBy ]; + assert(cert); + sk_X509_push(certs, cert); + } + } + + int flags = 0; + flags |= PKCS7_NOINTERN; + + // matches on certificate issuer and serial number - they must be unique + STACK_OF(X509)* signers = PKCS7_get0_signers(pkcs7, certs, flags); + if ( signers ) + { + + DebugLog( << "Found " << sk_X509_num(signers) << " signers." ); + for (int i=0; i<sk_X509_num(signers); i++) + { + X509* x = sk_X509_value(signers, i); + InfoLog(<< "Got a signer <" << i << "> : " << getCertName(x) ); + + GENERAL_NAMES* gens = 0; + gens = (GENERAL_NAMES*)X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + + for (int j = 0; j < sk_GENERAL_NAME_num(gens); j++) + { + GENERAL_NAME* gen = sk_GENERAL_NAME_value(gens, j); + if (gen->type == GEN_URI) + { + ASN1_IA5STRING* uri = gen->d.uniformResourceIdentifier; + Data name(uri->data, uri->length); + InfoLog(<< "subjectAltName of signing cert contains <" << name << ">" ); + try + { + Uri n(name); + if ( n.scheme() == "sip" ) + { + *signedBy = name; + InfoLog(<< "choose <" << name << "> signature" ); + } + } + catch (ParseException& e) + { + ErrLog(<<"Caught exception: "<< e); + } + } + } + + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + } + } + else + { + BIO_free(in); + BIO_free(out); + BIO_free(pkcs7Bio); + sk_X509_free(certs); + PKCS7_free(pkcs7); + *sigStat = SignatureIsBad; + InfoLog(<< "No valid signers of this messages" ); + return first; + } + +#if 0 + // this is debugging information to get the serial number of the signed + // information + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *si; + PKCS7_ISSUER_AND_SERIAL *ias; + ASN1_INTEGER* asnSerial; + long longSerial; + X509_NAME* name; + + sinfos = PKCS7_get_signer_info(pkcs7); + if ( sinfos ) + { + int num = sk_PKCS7_SIGNER_INFO_num(sinfos); + for ( int i=0; i<num; i++ ) + { + si = sk_PKCS7_SIGNER_INFO_value (sinfos, i) ; + ias = si->issuer_and_serial; + name = ias->issuer; + asnSerial = ias->serial; + longSerial = ASN1_INTEGER_get( (ASN1_INTEGER*)asnSerial ); + InfoLog( << "Signed with serial " << hex << longSerial ); + InfoLog( << "Name " << name ); + } + } +#endif + + assert( mRootTlsCerts ); + + switch (type) + { + case NID_pkcs7_signed: + { + int flags = 0; + + if (isSelfSigned(sk_X509_value(signers,0))) + { + flags |= PKCS7_NOVERIFY; + } + + if ( PKCS7_verify(pkcs7, certs, mRootTlsCerts, pkcs7Bio, out, flags ) != 1 ) + { + ErrLog( << "Problems doing PKCS7_verify" ); + + if ( sigStat ) + { + *sigStat = SignatureIsBad; + } + + while (1) + { + const char* file; + int line; + + unsigned long code = ERR_get_error_line(&file,&line); + if ( code == 0 ) + { + break; + } + + char buf[256]; + ERR_error_string_n(code,buf,sizeof(buf)); + ErrLog( << buf ); + InfoLog( << "Error code = " << code << " file=" << file << " line=" << line ); + } + BIO_free(in); + BIO_free(out); + BIO_free(pkcs7Bio); + sk_X509_free(certs); + PKCS7_free(pkcs7); + return first; + } + if ( sigStat ) + { + if ( (flags & PKCS7_NOVERIFY) ) + { + if (isSelfSigned(sk_X509_value(signers,0))) + { + DebugLog( << "Signature is selfSigned"); + *sigStat = SignatureSelfSigned; + } + else + { + DebugLog( << "Signature is notTrusted" ); + *sigStat = SignatureNotTrusted; + } + } + else + { + if (false) // !jf! TODO look for this cert in store + { + DebugLog( << "Signature is trusted" ); + *sigStat = SignatureTrusted; + } + else + { + DebugLog( << "Signature is caTrusted" ); + *sigStat = SignatureCATrusted; + } + } + } + } + break; + + default: + BIO_free(in); + BIO_free(out); + BIO_free(pkcs7Bio); + sk_X509_free(certs); + PKCS7_free(pkcs7); + ErrLog(<< "Got PKCS7 data that could not be handled type=" << type ); + return 0; + } + + (void)BIO_flush(out); + char* outBuf=0; + long size = BIO_get_mem_data(out,&outBuf); + assert( size >= 0 ); + + Data outData(outBuf,size); + DebugLog( << "uncoded body is <" << outData.escaped() << ">" ); + + BIO_free(in); + BIO_free(out); + BIO_free(pkcs7Bio); + sk_X509_free(certs); + PKCS7_free(pkcs7); + return first; +} + + +SSL_CTX* +BaseSecurity::getTlsCtx () +{ + assert(mTlsCtx); + return mTlsCtx; +} + + +SSL_CTX* +BaseSecurity::getSslCtx () +{ + assert(mSslCtx); + return mSslCtx; +} + +void +BaseSecurity::getCertNames(X509 *cert, std::list<PeerName> &peerNames, + bool useEmailAsSIP) +{ + if(NULL == cert) + return; + + if(peerNames.size() > 0) + peerNames.clear(); + + Data commonName; + + // look at the Common Name to find the peerName of the cert + X509_NAME* subject = X509_get_subject_name(cert); + if(NULL == subject) + { + ErrLog( << "Invalid certificate: subject not found "); + return; + } + + int i =-1; + while( true ) + { + i = X509_NAME_get_index_by_NID(subject, NID_commonName,i); + if ( i == -1 ) + { + break; + } + assert( i != -1 ); + X509_NAME_ENTRY* entry = X509_NAME_get_entry(subject,i); + assert( entry ); + + ASN1_STRING* s = X509_NAME_ENTRY_get_data(entry); + assert( s ); + + int t = M_ASN1_STRING_type(s); + int l = M_ASN1_STRING_length(s); + unsigned char* d = M_ASN1_STRING_data(s); + Data name(d,l); + DebugLog( << "got x509 string type=" << t << " len="<< l << " data=" << d ); + assert( name.size() == (unsigned)l ); + + DebugLog( << "Found common name in cert of " << name ); + + commonName = name; + } + +#if 0 // junk code to print certificates extentions for debugging + int numExt = X509_get_ext_count(cert); + ErrLog(<< "Got peer certificate with " << numExt << " extentions" ); + + for ( int i=0; i<numExt; i++ ) + { + X509_EXTENSION* ext = X509_get_ext(cert,i); + assert( ext ); + + const char* str = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); + assert(str); + DebugLog(<< "Got certificate extention" << str ); + + if ( OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == NID_subject_alt_name ) + { + DebugLog(<< "Got subjectAltName extention" ); + } + } +#endif + + // Look at the SubjectAltName, and if found, set as peerName + GENERAL_NAMES* gens; + gens = (GENERAL_NAMES*)X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); + for(int i = 0; i < sk_GENERAL_NAME_num(gens); i++) + { + GENERAL_NAME* gen = sk_GENERAL_NAME_value(gens, i); + + DebugLog(<< "subjectAltName of cert contains type <" << gen->type << ">" ); + + if (gen->type == GEN_DNS) + { + ASN1_IA5STRING* asn = gen->d.dNSName; + Data dns(asn->data, asn->length); + PeerName peerName(SubjectAltName, dns); + peerNames.push_back(peerName); + InfoLog(<< "subjectAltName of TLS session cert contains DNS <" << dns << ">" ); + } + + if (gen->type == GEN_EMAIL) + { + if(useEmailAsSIP) + { + ASN1_IA5STRING* asn = gen->d.rfc822Name; + Data email(asn->data, asn->length); + PeerName peerName(SubjectAltName, email); + peerNames.push_back(peerName); + InfoLog(<< "subjectAltName of TLS session cert contains EMAIL <" << email << ">" ); + } + else + DebugLog(<< "subjectAltName of cert has EMAIL type" ); + } + + if(gen->type == GEN_URI) + { + ASN1_IA5STRING* asn = gen->d.uniformResourceIdentifier; + Uri uri(Data(asn->data, asn->length)); + try + { + PeerName peerName(SubjectAltName, uri.host()); + peerNames.push_back(peerName); + InfoLog(<< "subjectAltName of TLS session cert contains URI <" << uri << ">" ); + } + catch (...) + { + InfoLog(<< "subjectAltName of TLS session cert contains unparseable URI"); + } + } + } + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + + // If there are no peer names from the subjectAltName, then use the commonName + if(peerNames.empty()) + { + PeerName peerName(CommonName, commonName); + peerNames.push_back(peerName); + } +} + +Data +BaseSecurity::getCertName(X509 *cert) +{ + Data certName; + std::list<PeerName> cNames; + + //get all the names (subjectAltName or CommonName) + getCertNames(cert, cNames); + + //prefere the subjectAltName + for(std::list<PeerName>::const_iterator it = cNames.begin(); it != cNames.end(); it++) + { + if(it->mType == SubjectAltName) + { + return it->mName; + } + } + + //if not subjectAltName found, get the CommonName + for(std::list<PeerName>::const_iterator it = cNames.begin(); it != cNames.end(); it++) + { + if(it->mType == CommonName) + { + return it->mName; + } + } + ErrLog(<< "This certificate doesn't have neither subjectAltName nor commonName"); + return Data::Empty; +} +/** + Applies the certificate and domain name matching rules +*/ +int +BaseSecurity::matchHostName(const Data& certificateName, const Data& domainName) +{ + if(mAllowWildcardCertificates) + return matchHostNameWithWildcards(certificateName,domainName); + return isEqualNoCase(certificateName,domainName); +} +/** + Does a wildcard match on domain and certificate name + @todo looks incomplete, make better +*/ +int +BaseSecurity::matchHostNameWithWildcards(const Data& certificateName, const Data& domainName) +{ + const char *dot = NULL; + + const char *certName = certificateName.c_str(); + if(certName == NULL) + return 0; + + const char *domName = domainName.c_str(); + if(domName == NULL) + return 0; + + dot = strchr(domName, '.'); + if (dot == NULL) + { + char *pnt = (char *)strchr(certName, '.'); // bad + /* hostname is not fully-qualified; unqualify the certName. */ + if (pnt != NULL) + { + *pnt = '\0'; + } + } + else + { + if (strncmp(certName, "*.", 2) == 0) + { + domName = dot + 1; + certName += 2; + } + } + return !strcasecmp(certName, domName); +} + +bool +BaseSecurity::isSelfSigned(const X509 *cert) +{ + int iRet = X509_NAME_cmp(cert->cert_info->issuer, cert->cert_info->subject); + return (iRet == 0); +} + +void +BaseSecurity::dumpAsn( char* name, Data data) +{ +#if 0 // for debugging + assert(name); + + if (true) // dump asn.1 stuff to debug file + { + ofstream strm(name, std::ios_base::trunc); + if ( !strm ) + { + ErrLog( <<"Could not write to " << name ); + } + else + { + strm.write( data.data() , data.size() ); + } + strm.flush(); + } +#endif +} + +X509* +BaseSecurity::getDomainCert( const Data& domain ) +{ + return mDomainCerts.count(domain) ? mDomainCerts[domain] : 0; +} + +X509* +BaseSecurity::getUserCert( const Data& aor ) +{ + return mUserCerts.count(aor) ? mUserCerts[aor] : 0; +} + +EVP_PKEY* +BaseSecurity::getDomainKey( const Data& domain ) +{ + return mDomainPrivateKeys.count(domain) ? mDomainPrivateKeys[domain] : 0; +} + +EVP_PKEY* +BaseSecurity::getUserPrivateKey( const Data& aor ) +{ + return mUserPrivateKeys.count(aor) ? mUserPrivateKeys[aor] : 0; +} + +#endif + + + + +/* ==================================================================== +* The Vovida Software License, Version 1.0 +* +* Copyright (c) 2002-2005 Vovida Networks, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. The names "VOCAL", "Vovida Open Communication Application Library", +* and "Vovida Open Communication Application Library (VOCAL)" must +* not be used to endorse or promote products derived from this +* software without prior written permission. For written +* permission, please contact vocal@vovida.org. +* +* 4. Products derived from this software may not be called "VOCAL", nor +* may "VOCAL" appear in their name, without prior written +* permission of Vovida Networks, Inc. +* +* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +* +* ==================================================================== +* +* This software consists of voluntary contributions made by Vovida +* Networks, Inc. and many individuals on behalf of Vovida Networks, +* Inc. For more information on Vovida Networks, Inc., please see +* <http://www.vovida.org/>. +* +*/ diff --git a/src/libs/resiprocate/resip/stack/ssl/Security.hxx b/src/libs/resiprocate/resip/stack/ssl/Security.hxx new file mode 100644 index 00000000..f0687606 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/Security.hxx @@ -0,0 +1,312 @@ +#if !defined(RESIP_SECURITY_HXX) +#define RESIP_SECURITY_HXX + +#include <map> +#include <vector> +#include <list> + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + + +#include "rutil/Socket.hxx" +#include "rutil/BaseException.hxx" +#include "resip/stack/SecurityTypes.hxx" +#include "resip/stack/SecurityAttributes.hxx" + +// If USE_SSL is not defined, Security will not be built, and this header will +// not be installed. If you are including this file from a source tree, and are +// getting link errors, the source tree was probably built without USE_SSL. +//#if defined(USE_SSL) +//#else +//// to ensure compilation and object size invariance. +//typedef void BIO; +//typedef void SSL; +//typedef void X509; +//typedef void X509_STORE; +//typedef void SSL_CTX; +//typedef void EVP_PKEY; +//#endif + +#include <openssl/ssl.h> + +namespace resip +{ + +class Contents; +class Pkcs7Contents; +class Security; +class MultipartSignedContents; +class SipMessage; + + +class BaseSecurity +{ + public: + class Exception : public BaseException + { + public: + Exception(const Data& msg, const Data& file, const int line); + const char* name() const { return "SecurityException"; } + }; + + class CipherList + { + public: + CipherList(){} + CipherList(const Data& cipherList) : mCipherList(cipherList) {} + Data cipherList() const { return mCipherList; } + private: + Data mCipherList; + }; + + public: + + typedef enum + { + SubjectAltName, + CommonName + }NameType; + + struct PeerName + { + NameType mType; + Data mName; + PeerName(NameType type, Data name): mType(type), mName(name){} + }; + + static CipherList ExportableSuite; + static CipherList StrongestSuite; + + BaseSecurity(const CipherList& cipherSuite = ExportableSuite); + virtual ~BaseSecurity(); + + // used to initialize the openssl library + static void initialize(); + + typedef enum + { + RootCert=1, + DomainCert, + DomainPrivateKey, + UserCert, + UserPrivateKey + } PEMType; + + virtual void preload()=0; + + // name refers to the domainname or username which could be converted to a + // filename by convention + virtual void onReadPEM(const Data& name, PEMType type, Data& buffer) const =0; + virtual void onWritePEM(const Data& name, PEMType type, const Data& buffer) const =0; + virtual void onRemovePEM(const Data& name, PEMType type) const =0; + + struct CertificateInfo + { + Data name; + Data fingerprint; + Data validFrom; + Data validTo; + }; + + typedef std::vector<CertificateInfo> CertificateInfoContainer; + CertificateInfoContainer getRootCertDescriptions() const; + + // All of these guys can throw SecurityException + + void addRootCertPEM(const Data& x509PEMEncodedRootCerts); + + void addDomainCertPEM(const Data& domainName, const Data& certPEM); + void addDomainCertDER(const Data& domainName, const Data& certDER); + bool hasDomainCert(const Data& domainName) const; + void removeDomainCert(const Data& domainName); + Data getDomainCertDER(const Data& domainName) const; + + void addDomainPrivateKeyPEM(const Data& domainName, const Data& privateKeyPEM); + bool hasDomainPrivateKey(const Data& domainName) const; + void removeDomainPrivateKey(const Data& domainName); + Data getDomainPrivateKeyPEM(const Data& domainName) const; + + void addUserCertPEM(const Data& aor, const Data& certPEM); + void addUserCertDER(const Data& aor, const Data& certDER); + bool hasUserCert(const Data& aor) const; + void removeUserCert(const Data& aor); + Data getUserCertDER(const Data& aor) const; + + void setUserPassPhrase(const Data& aor, const Data& passPhrase); + bool hasUserPassPhrase(const Data& aor) const; + void removeUserPassPhrase(const Data& aor); + Data getUserPassPhrase(const Data& aor) const; + + void addUserPrivateKeyPEM(const Data& aor, const Data& certPEM); + void addUserPrivateKeyDER(const Data& aor, const Data& certDER); + bool hasUserPrivateKey(const Data& aor) const; + void removeUserPrivateKey(const Data& aor); + Data getUserPrivateKeyPEM(const Data& aor) const; + Data getUserPrivateKeyDER(const Data& aor) const; + + void generateUserCert(const Data& aor, int expireDays=365, int keyLen=1024); + + // Produces a detached signature + MultipartSignedContents* sign(const Data& senderAor, Contents* ); + Pkcs7Contents* encrypt(Contents* , const Data& recipCertName ); + MultipartSignedContents* signAndEncrypt( const Data& senderAor, Contents* , const Data& recipCertName ); + + Data computeIdentity( const Data& signerDomain, const Data& in ) const; + bool checkIdentity( const Data& signerDomain, const Data& in, const Data& sig, X509* cert=NULL ) const; + + void checkAndSetIdentity(SipMessage& msg, const Data& derCert=Data::Empty ) const; + + // returns NULL if it fails + Contents* decrypt( const Data& decryptorAor, const Pkcs7Contents* ); + + // returns NULL if fails. returns the data that was originally signed + Contents* checkSignature( MultipartSignedContents*, + Data* signedBy, SignatureStatus* sigStat ); + // returns the first SubjectAltName or commonName, if subjectAltName does not exist + static Data getCertName(X509 *cert); + + // retrieves a list of all certificate names (subjectAltNAme's and CommonName) + static void getCertNames(X509 *cert, std::list<PeerName> &peerNames, bool useEmailAsSIP = false); + + static bool isSelfSigned(const X509* cert); + + static int matchHostName(const Data& certificateName, const Data& domainName); + + // allow particular classes to acces the functions below + // friend class TlsConnection; + + // Allow overriding of RFC 5922 rules on certificate matching. + static void setAllowWildcardCertificates(bool bEnable) { mAllowWildcardCertificates = bEnable; } + static bool allowWildcardCertificates() { return mAllowWildcardCertificates; } + + public: + SSL_CTX* getTlsCtx (); + SSL_CTX* getSslCtx (); + + X509* getDomainCert( const Data& domain ); + EVP_PKEY* getDomainKey( const Data& domain ); + X509* getUserCert(const Data& aor); + EVP_PKEY* getUserPrivateKey(const Data& aor); + + // map of name to certificates + typedef std::map<Data,X509*> X509Map; + typedef std::list<X509*> X509List; + typedef std::map<Data,EVP_PKEY*> PrivateKeyMap; + typedef std::map<Data,Data> PassPhraseMap; + + protected: + SSL_CTX* mTlsCtx; + SSL_CTX* mSslCtx; + static void dumpAsn(char*, Data); + + CipherList mCipherList; + + // root cert list + X509List mRootCerts; + X509_STORE* mRootTlsCerts; + X509_STORE* mRootSslCerts; + + X509Map mDomainCerts; + PrivateKeyMap mDomainPrivateKeys; + + X509Map mUserCerts; + PassPhraseMap mUserPassPhrases; + PrivateKeyMap mUserPrivateKeys; + + void addCertPEM (PEMType type, const Data& name, const Data& certPEM, bool write); + void addCertDER (PEMType type, const Data& name, const Data& certDER, bool write); + bool hasCert (PEMType type, const Data& name) const; + void removeCert (PEMType type, const Data& name); + Data getCertDER (PEMType type, const Data& name) const; + void addCertX509(PEMType type, const Data& name, X509* cert, bool write); + + void addPrivateKeyPEM (PEMType type, const Data& name, const Data& privateKeyPEM, bool write); + void addPrivateKeyDER (PEMType type, const Data& name, const Data& privateKeyDER, bool write); + bool hasPrivateKey (PEMType type, const Data& name) const; + void removePrivateKey (PEMType type, const Data& name); + Data getPrivateKeyPEM (PEMType type, const Data& name) const; + Data getPrivateKeyDER (PEMType type, const Data& name) const; + void addPrivateKeyPKEY(PEMType type, const Data& name, EVP_PKEY* pKey, bool write); + + // match with wildcards + static int matchHostNameWithWildcards(const Data& certificateName, const Data& domainName); + static bool mAllowWildcardCertificates; +}; + +class Security : public BaseSecurity +{ + public: + Security(const Data& pathToCerts, const CipherList& = ExportableSuite); + Security(const CipherList& = ExportableSuite); + + void addCADirectory(const Data& caDirectory); + void addCAFile(const Data& caFile); + + virtual void preload(); + virtual SSL_CTX* createDomainCtx(const SSL_METHOD* method, const Data& domain); + + virtual void onReadPEM(const Data& name, PEMType type, Data& buffer) const; + virtual void onWritePEM(const Data& name, PEMType type, const Data& buffer) const; + virtual void onRemovePEM(const Data& name, PEMType type) const; + + private: + Data mPath; + std::list<Data> mCADirectories; + std::list<Data> mCAFiles; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/TlsConnection.cxx b/src/libs/resiprocate/resip/stack/ssl/TlsConnection.cxx new file mode 100644 index 00000000..f56ffe9c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/TlsConnection.cxx @@ -0,0 +1,695 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#if defined(USE_SSL) + +#include "resip/stack/ssl/TlsConnection.hxx" +#include "resip/stack/ssl/TlsTransport.hxx" +#include "resip/stack/ssl/Security.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/Uri.hxx" +#include "rutil/Socket.hxx" + +#include <openssl/e_os2.h> +#include <openssl/evp.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/pem.h> +#include <openssl/pkcs7.h> +#include <openssl/x509v3.h> +#include <openssl/ssl.h> +#endif + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +extern int +verifyCallback(int iInCode, X509_STORE_CTX *pInStore); + +TlsConnection::TlsConnection( Transport* transport, const Tuple& tuple, + Socket fd, Security* security, + bool server, Data domain, SecurityTypes::SSLType sslType , + Compression &compression) : + Connection(transport,tuple, fd, compression), + mServer(server), + mSecurity(security), + mSslType( sslType ), + mDomain(domain) +{ +#if defined(USE_SSL) + InfoLog (<< "Creating TLS connection for domain " + << mDomain + << " " << tuple + << " on " << fd); + + mSsl = NULL; + mBio= NULL; + + if (mServer) + { + DebugLog( << "Trying to form TLS connection - acting as server" ); + if ( mDomain.empty() ) + { + ErrLog(<< "Tranport was not created with a server domain so can not act as server" ); + throw Security::Exception("Trying to act as server but no domain specified", + __FILE__,__LINE__); + } + } + else + { + DebugLog( << "Trying to form TLS connection - acting as client" ); + } + assert( mSecurity ); + + TlsTransport *t = dynamic_cast<TlsTransport*>(transport); + assert(t); + + SSL_CTX* ctx=t->getCtx(); + assert(ctx); + + mSsl = SSL_new(ctx); + assert(mSsl); + + assert( mSecurity ); + + if(mServer) + { + // clear SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE set in SSL_CTX if we are a server + int verify_mode; + switch(t->getClientVerificationMode()) + { + case SecurityTypes::None: + verify_mode = SSL_VERIFY_NONE; + DebugLog(<< "Not expecting client certificate" ); + break; + case SecurityTypes::Optional: + verify_mode = SSL_VERIFY_PEER; + DebugLog(<< "Optional client certificate mode" ); + break; + case SecurityTypes::Mandatory: + verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + DebugLog(<< "Mandatory client certificate mode" ); + break; + default: + assert( 0 ); + } + SSL_set_verify(mSsl, verify_mode, 0); + } + SSL_set_verify(mSsl, SSL_VERIFY_PEER, &verifyCallback); + + mBio = BIO_new_socket((int)fd,0/*close flag*/); + assert( mBio ); + + SSL_set_bio( mSsl, mBio, mBio ); + + mTlsState = Initial; + mHandShakeWantsRead = false; + +#endif // USE_SSL +} + +TlsConnection::~TlsConnection() +{ +#if defined(USE_SSL) + SSL_shutdown(mSsl); + SSL_free(mSsl); +#endif // USE_SSL +} + + +const char* +TlsConnection::fromState(TlsConnection::TlsState s) +{ + switch(s) + { + case Initial: return "Initial"; break; + case Handshaking: return "Handshaking"; break; + case Broken: return "Broken"; break; + case Up: return "Up"; break; + } + return "????"; +} + +TlsConnection::TlsState +TlsConnection::checkState() +{ +#if defined(USE_SSL) + //DebugLog(<<"state is " << fromTlsState(mTlsState)); + + if (mTlsState == Up || mTlsState == Broken) + { + return mTlsState; + } + + int ok=0; + + ERR_clear_error(); + + if (mTlsState != Handshaking) + { + if (mServer) + { + InfoLog( << "TLS handshake starting (Server mode)" ); + SSL_set_accept_state(mSsl); + mTlsState = Handshaking; + } + else + { + InfoLog( << "TLS handshake starting (client mode)" ); + SSL_set_connect_state(mSsl); + mTlsState = Handshaking; + } + + InfoLog( << "TLS connected" ); + mTlsState = Handshaking; + } + + mHandShakeWantsRead = false; + ok = SSL_do_handshake(mSsl); + + if ( ok <= 0 ) + { + int err = SSL_get_error(mSsl,ok); + + switch (err) + { + case SSL_ERROR_WANT_READ: + StackLog( << "TLS handshake want read" ); + mHandShakeWantsRead = true; + + return mTlsState; + case SSL_ERROR_WANT_WRITE: + StackLog( << "TLS handshake want write" ); + ensureWritable(); + return mTlsState; + + case SSL_ERROR_ZERO_RETURN: + StackLog( << "TLS connection closed cleanly"); + return mTlsState; + + case SSL_ERROR_WANT_CONNECT: + StackLog( << "BIO not connected, try later"); + return mTlsState; + +#if ( OPENSSL_VERSION_NUMBER >= 0x0090702fL ) + case SSL_ERROR_WANT_ACCEPT: + StackLog( << "TLS connection want accept" ); + return mTlsState; +#endif + + case SSL_ERROR_WANT_X509_LOOKUP: + StackLog( << "Try later"); + return mTlsState; + default: + if(err == SSL_ERROR_SYSCALL) + { + int e = getErrno(); + switch(e) + { + case EINTR: + case EAGAIN: + StackLog( << "try later"); + return mTlsState; + } + ErrLog( << "socket error " << e); + Transport::error(e); + } + else if (err == SSL_ERROR_SSL) + { + mFailureReason = TransportFailure::CertValidationFailure; + } + ErrLog( << "TLS handshake failed "); + while (true) + { + const char* file; + int line; + + unsigned long code = ERR_get_error_line(&file,&line); + if ( code == 0 ) + { + break; + } + + char buf[256]; + ERR_error_string_n(code,buf,sizeof(buf)); + ErrLog( << buf ); + ErrLog( << "Error code = " + << code << " file=" << file << " line=" << line ); + } + mBio = NULL; + mTlsState = Broken; + return mTlsState; + } + } + else // ok > 1 + { + InfoLog( << "TLS connected" ); + } + + // force peer name to get checked and perhaps cert loaded + computePeerName(); + + //post-connection verification: check that certificate name matches domain name + if (!mServer) + { + bool matches = false; + for(std::list<BaseSecurity::PeerName>::iterator it = mPeerNames.begin(); it != mPeerNames.end(); it++) + { + if(BaseSecurity::matchHostName(it->mName, who().getTargetDomain())) + { + matches=true; + break; + } + } +#if defined(TARGET_ANDROID) + if (false) +#else + if(!matches) +#endif + { + mTlsState = Broken; + mBio = NULL; + ErrLog (<< "Certificate name mismatch: trying to connect to <" + << who().getTargetDomain() + << "> remote cert domain(s) are <" + << getPeerNamesData() << ">" ); + mFailureReason = TransportFailure::CertNameMismatch; + return mTlsState; + } + } + + InfoLog( << "TLS handshake done for peer " << getPeerNamesData()); + mTlsState = Up; + if (!mOutstandingSends.empty()) + { + ensureWritable(); + } +#endif // USE_SSL + return mTlsState; +} + + +int +TlsConnection::read(char* buf, int count ) +{ +#if defined(USE_SSL) + assert( mSsl ); + assert( buf ); + + switch(checkState()) + { + case Broken: + return -1; + break; + case Up: + break; + default: + return 0; + break; + } + + if (!mBio) + { + DebugLog( << "Got TLS read bad bio " ); + return 0; + } + + if ( !isGood() ) + { + return -1; + } + + int bytesRead = SSL_read(mSsl,buf,count); + StackLog(<< "SSL_read returned " << bytesRead << " bytes [" << Data(Data::Borrow, buf, (bytesRead > 0)?(bytesRead):(0)) << "]"); + + int bytesPending = SSL_pending(mSsl); + + if ((bytesRead > 0) && (bytesPending > 0)) + { + char* buffer = getWriteBufferForExtraBytes(bytesPending); + if (buffer) + { + StackLog(<< "reading remaining buffered bytes"); + bytesPending = SSL_read(mSsl, buffer, bytesPending); + StackLog(<< "SSL_read returned " << bytesPending << " bytes [" << Data(Data::Borrow, buffer, (bytesPending > 0)?(bytesPending):(0)) << "]"); + + if (bytesPending > 0) + { + bytesRead += bytesPending; + } + else + { + bytesRead = bytesPending; + } + } + else + { + assert(0); + } + } + + if (bytesRead <= 0) + { + int err = SSL_get_error(mSsl,bytesRead); + switch (err) + { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_NONE: + { + StackLog( << "Got TLS read got condition of " << err ); + return 0; + } + break; + default: + { + char buf[256]; + ERR_error_string_n(err,buf,sizeof(buf)); + ErrLog( << "Got TLS read ret=" << bytesRead << " error=" << err << " " << buf ); + // Signal about refresh + return -1; + + } + break; + } + assert(0); + } + StackLog(<<"SSL bytesRead="<<bytesRead); + return bytesRead; +#endif // USE_SSL + return -1; +} + +bool +TlsConnection::transportWrite() +{ + switch(mTlsState) + { + case Handshaking: + case Initial: + checkState(); + if (mTlsState == Handshaking) + { + DebugLog(<< "Transportwrite--Handshaking--remove from write: " << mHandShakeWantsRead); + return mHandShakeWantsRead; + } + else + { + DebugLog(<< "Transportwrite--Handshake complete, in " << fromState(mTlsState) << " calling write"); + return false; + } + case Up: + case Broken: + DebugLog(<< "Transportwrite--" << fromState(mTlsState) << " fall through to write"); + return false; + } + assert(0); + return false; +} + +int +TlsConnection::write( const char* buf, int count ) +{ +#if defined(USE_SSL) + assert( mSsl ); + assert( buf ); + int ret; + + switch(checkState()) + { + case Broken: + return -1; + break; + case Up: + break; + default: + DebugLog( << "Tried to Tls write - but connection is not Up" ); + return 0; + break; + } + + if (!mBio) + { + DebugLog( << "Got TLS write bad bio " ); + return 0; + } + + ret = SSL_write(mSsl,(const char*)buf,count); + if (ret < 0 ) + { + int err = SSL_get_error(mSsl,ret); + switch (err) + { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_NONE: + { + StackLog( << "Got TLS write got condition of " << err ); + return 0; + } + break; + default: + { + while (true) + { + const char* file; + int line; + + unsigned long code = ERR_get_error_line(&file,&line); + if ( code == 0 ) + { + break; + } + + char buf[256]; + ERR_error_string_n(code,buf,sizeof(buf)); + ErrLog( << buf ); + DebugLog( << "Error code = " << code << " file=" << file << " line=" << line ); + } + ErrLog( << "Got TLS write error=" << err << " ret=" << ret ); + return -1; + } + break; + } + } + + Data monkey(Data::Borrow, buf, count); + + StackLog( << "Did TLS write " << ret << " " << count << " " << "[[" << monkey << "]]" ); + + return ret; +#endif // USE_SSL + return -1; +} + + +bool +TlsConnection::hasDataToRead() // has data that can be read +{ +#if defined(USE_SSL) + //hack (for now) + if(mTlsState == Initial) + return false; + + if (checkState() != Up) + { + return false; + } + + int p = SSL_pending(mSsl); + //DebugLog(<<"hasDataToRead(): " <<p); + return (p>0); +#else // USE_SSL + return false; +#endif +} + + +bool +TlsConnection::isGood() // has data that can be read +{ +#if defined(USE_SSL) + if ( mBio == 0 ) + { + return false; + } + + int mode = SSL_get_shutdown(mSsl); + if ( mode != 0 ) + { + return false; + } + +#endif + return true; +} + +bool +TlsConnection::isWritable() +{ +#if defined(USE_SSL) + switch(mTlsState) + { + case Handshaking: + return mHandShakeWantsRead ? false : true; + case Initial: + case Up: + return isGood(); + default: + return false; + } + //dragos -- to remove + DebugLog( << "Current state: " << fromState(mTlsState)); + //end dragos +#endif + return false; +} + +void TlsConnection::getPeerNames(std::list<Data> &peerNames) const +{ + for(std::list<BaseSecurity::PeerName>::const_iterator it = mPeerNames.begin(); it != mPeerNames.end(); it++) +{ + peerNames.push_back(it->mName); + } +} + +Data +TlsConnection::getPeerNamesData() const +{ + Data peerNamesString; + for(std::list<BaseSecurity::PeerName>::const_iterator it = mPeerNames.begin(); it != mPeerNames.end(); it++) + { + if(it == mPeerNames.begin()) + { + peerNamesString += it->mName; + } + else + { + peerNamesString += ", " + it->mName; + } + } + return peerNamesString; +} + + +void +TlsConnection::computePeerName() +{ +#if defined(USE_SSL) + Data commonName; + + assert(mSsl); + + if (!mBio) + { + ErrLog( << "bad bio" ); + return; + } + + // print session infor + const SSL_CIPHER *ciph; + ciph=SSL_get_current_cipher(mSsl); + InfoLog( << "TLS sessions set up with " + << SSL_get_version(mSsl) << " " + << SSL_CIPHER_get_version(ciph) << " " + << SSL_CIPHER_get_name(ciph) << " " ); + + // get the certificate if other side has one + X509* cert = SSL_get_peer_certificate(mSsl); + if ( !cert ) + { + DebugLog(<< "No peer certificate in TLS connection" ); + return; + } + + // check that this certificate is valid + if (X509_V_OK != SSL_get_verify_result(mSsl)) + { + DebugLog(<< "Peer certificate in TLS connection is not valid" ); + X509_free(cert); cert=NULL; + return; + } + + TlsTransport *t = dynamic_cast<TlsTransport*>(mTransport); + assert(t); + + mPeerNames.clear(); + BaseSecurity::getCertNames(cert, mPeerNames, + t->isUseEmailAsSIP()); + if(mPeerNames.empty()) + { + ErrLog(<< "Invalid certificate: no subjectAltName/CommonName found"); + return; + } + + if(!mServer) + { + // add the certificate to the Security store + unsigned char* buf = NULL; + int len = i2d_X509( cert, &buf ); + Data derCert( buf, len ); + for(std::list<BaseSecurity::PeerName>::iterator it = mPeerNames.begin(); it != mPeerNames.end(); it++) + { + if ( !mSecurity->hasDomainCert( it->mName ) ) + { + mSecurity->addDomainCertDER(it->mName,derCert); + } + } + OPENSSL_free(buf); buf=NULL; + } + + X509_free(cert); cert=NULL; +#endif // USE_SSL +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/TlsConnection.hxx b/src/libs/resiprocate/resip/stack/ssl/TlsConnection.hxx new file mode 100644 index 00000000..b35c11c7 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/TlsConnection.hxx @@ -0,0 +1,129 @@ +#if !defined(TlsConnection_hxx) +#define TlsConnection_hxx + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + + +#include "resip/stack/Connection.hxx" +#include "rutil/HeapInstanceCounter.hxx" +#include "resip/stack/SecurityTypes.hxx" +#include "resip/stack/ssl/Security.hxx" + +// If USE_SSL is not defined, this will not be built, and this header will +// not be installed. If you are including this file from a source tree, and are +// getting link errors, the source tree was probably built without USE_SSL. +//#ifdef USE_SSL +//#include <openssl/ssl.h> +//#else +//typedef void BIO; +//typedef void SSL; +//#endif + +#include <openssl/ssl.h> + +namespace resip +{ + +class Tuple; +class Security; + +class TlsConnection : public Connection +{ + public: + RESIP_HeapCount(TlsConnection); + + TlsConnection( Transport* transport, const Tuple& who, Socket fd, + Security* security, bool server, Data domain, + SecurityTypes::SSLType sslType , + Compression &compression); + + virtual ~TlsConnection(); + + int read( char* buf, const int count ); + int write( const char* buf, const int count ); + virtual bool hasDataToRead(); // has data that can be read + virtual bool isGood(); // has valid connection + virtual bool isWritable(); + + virtual bool transportWrite(); + + void getPeerNames(std::list<Data> & peerNames) const; + + typedef enum TlsState { Initial, Broken, Handshaking, Up } TlsState; + static const char * fromState(TlsState); + + private: + /// No default c'tor + TlsConnection(); + void computePeerName(); + Data getPeerNamesData() const; + TlsState checkState(); + + bool mServer; + Security* mSecurity; + SecurityTypes::SSLType mSslType; + Data mDomain; + + TlsState mTlsState; + bool mHandShakeWantsRead; + + SSL* mSsl; + BIO* mBio; + std::list<BaseSecurity::PeerName> mPeerNames; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/TlsTransport.cxx b/src/libs/resiprocate/resip/stack/ssl/TlsTransport.cxx new file mode 100644 index 00000000..e179ce35 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/TlsTransport.cxx @@ -0,0 +1,151 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#ifdef USE_SSL + +#include <memory> + +#include "rutil/compat.hxx" +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/ssl/TlsTransport.hxx" +#include "resip/stack/ssl/TlsConnection.hxx" +#include "resip/stack/ssl/Security.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +using namespace std; +using namespace resip; + +TlsTransport::TlsTransport(Fifo<TransactionMessage>& fifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + Security& security, + const Data& sipDomain, + SecurityTypes::SSLType sslType, + AfterSocketCreationFuncPtr socketFunc, + Compression &compression, + unsigned transportFlags, + SecurityTypes::TlsClientVerificationMode cvm, + bool useEmailAsSIP): + TcpBaseTransport(fifo, portNum, version, interfaceObj, socketFunc, compression, transportFlags), + mSecurity(&security), + mSslType(sslType), + mDomainCtx(0), + mClientVerificationMode(cvm), + mUseEmailAsSIP(useEmailAsSIP) +{ + setTlsDomain(sipDomain); + mTuple.setType(transport()); + + init(); + + // If we have specified a sipDomain, then we need to create a new context for this domain, + // otherwise we will use the SSL Ctx or TLS Ctx created in the Security class + if(!sipDomain.empty()) + { + if (sslType == SecurityTypes::SSLv23) + { + mDomainCtx = mSecurity->createDomainCtx(SSLv23_method(), sipDomain); + } + else + { + mDomainCtx = mSecurity->createDomainCtx(TLSv1_method(), sipDomain); + } + } + + InfoLog (<< "Creating TLS transport for domain " + << sipDomain << " interface=" << interfaceObj + << " port=" << mTuple.getPort()); + + mTxFifo.setDescription("TlsTransport::mTxFifo"); +} + + +TlsTransport::~TlsTransport() +{ + if (mDomainCtx) + { + SSL_CTX_free(mDomainCtx);mDomainCtx=0; + } +} + +SSL_CTX* +TlsTransport::getCtx() const +{ + if(mDomainCtx) + { + return mDomainCtx; + } + else if(mSslType == SecurityTypes::SSLv23) + { + return mSecurity->getSslCtx(); + } + return mSecurity->getTlsCtx(); +} + +Connection* +TlsTransport::createConnection(const Tuple& who, Socket fd, bool server) +{ + assert(this); + Connection* conn = new TlsConnection(this,who, fd, mSecurity, server, + tlsDomain(), mSslType, mCompression ); + conn->setTransportLogger(mTransportLogger); + return conn; +} + +#endif /* USE_SSL */ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/TlsTransport.hxx b/src/libs/resiprocate/resip/stack/ssl/TlsTransport.hxx new file mode 100644 index 00000000..0af4be50 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/TlsTransport.hxx @@ -0,0 +1,114 @@ +#if !defined(RESIP_TLSTRANSPORT_HXX) +#define RESIP_TLSTRANSPORT_HXX + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + + +#include "resip/stack/TcpBaseTransport.hxx" +#include "resip/stack/SecurityTypes.hxx" +#include "rutil/HeapInstanceCounter.hxx" +#include "resip/stack/Compression.hxx" + +#include <openssl/ssl.h> + +namespace resip +{ + +class Connection; +class Message; +class Security; + +class TlsTransport : public TcpBaseTransport +{ + public: + RESIP_HeapCount(TlsTransport); + TlsTransport(Fifo<TransactionMessage>& fifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + Security& security, + const Data& sipDomain, + SecurityTypes::SSLType sslType, + AfterSocketCreationFuncPtr socketFunc=0, + Compression &compression = Compression::Disabled, + unsigned transportFlags = 0, + SecurityTypes::TlsClientVerificationMode cvm = SecurityTypes::None, + bool useEmailAsSIP = false); + virtual ~TlsTransport(); + + TransportType transport() const { return TLS; } + SSL_CTX* getCtx() const; + + SecurityTypes::TlsClientVerificationMode getClientVerificationMode() + { return mClientVerificationMode; }; + bool isUseEmailAsSIP() + { return mUseEmailAsSIP; }; + + protected: + Connection* createConnection(const Tuple& who, Socket fd, bool server=false); + + Security* mSecurity; + SecurityTypes::SSLType mSslType; + SSL_CTX* mDomainCtx; + SecurityTypes::TlsClientVerificationMode mClientVerificationMode; + /* If true, we will accept the email address in a client's subjectAltName + as if it were a SIP URI. This is convenient because many commercial + CAs offer email certificates but not sip: certificates */ + bool mUseEmailAsSIP; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/WinSecurity.cxx b/src/libs/resiprocate/resip/stack/ssl/WinSecurity.cxx new file mode 100644 index 00000000..5979e4b3 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/WinSecurity.cxx @@ -0,0 +1,241 @@ +#ifdef TARGET_WIN + +#include <sys/types.h> + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + + +#ifdef USE_SSL +#include "resip/stack/ssl/WinSecurity.hxx" +#include <openssl/e_os2.h> +#include <openssl/evp.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/pem.h> +#include <openssl/pkcs7.h> +#include <openssl/ossl_typ.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/ssl.h> + +#include <Wincrypt.h> +#include "rutil/Logger.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +#include <windows.h> +#include <wincrypt.h> + +void +WinSecurity::preload() +{ + HCERTSTORE storeHandle = NULL; + + getCerts(WinSecurity::ROOT_CA_STORE); + //getCerts(WinSecurity::CA_STORE); + //getCredentials(WinSecurity::PRIVATE_STORE); + //getCerts(WinSecurity::USERS_STORE); +} + +void +WinSecurity::onReadPEM(const Data& name, PEMType type, Data& buffer) const +{ + return; +} + +void +WinSecurity::onWritePEM(const Data& name, PEMType type, const Data& buffer) const +{ + return; +} + +void +WinSecurity::onRemovePEM(const Data& name, PEMType type) const +{ + return; +} + +static const Data storeRootCA("Root"); +static const Data storeCA("CA"); +static const Data storePrivate("My"); +static const Data storeUsers("DOMAIN_USERS"); +static const Data storeUnknown("UNKNOWN_STORE"); +static const Data +certStoreTypes( WinSecurity::MsCertStoreType pType ) +{ + switch (pType) + { + case WinSecurity::ROOT_CA_STORE: return storeRootCA; + case WinSecurity::CA_STORE: return storeCA; + case WinSecurity::PRIVATE_STORE: return storePrivate; + case WinSecurity::USERS_STORE: return storeUsers; + default: + { + ErrLog( << "Some unknown certificate store type requested" << (int)(pType) ); + assert(0); + } + } + return storeUnknown; +} + +#ifdef UNICODE +static LPWSTR AnsiToUnicode(LPCSTR szInString) +{ + LPWSTR pwszString = NULL; + if(NULL == szInString) + return 0; + +int iLen = 0; +iLen = MultiByteToWideChar( CP_UTF8, 0, szInString, -1, 0, 0 ); +if (0 == iLen) + return pwszString; + + pwszString = (LPWSTR)LocalAlloc( + LMEM_FIXED, + iLen * sizeof(WCHAR) + ); +if (NULL == pwszString) + return pwszString; + +int iRet = MultiByteToWideChar( CP_UTF8, 0, szInString, -1, pwszString, iLen ); + +if (0 == iRet) +{ + LocalFree(pwszString); +} +return pwszString; +} +#endif + +HCERTSTORE +WinSecurity::openSystemCertStore(const Data& name) +{ + HCERTSTORE mStoreHandle = NULL; + LPCTSTR storeName = NULL; + DWORD dwFlags; + + dwFlags = CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE; + +#ifndef UNICODE + storeName = name.c_str(); +#else + storeName = AnsiToUnicode(name.c_str()); +#endif + + if (NULL == storeName) + { + ErrLog( << " Invalid store name"); + assert(0); + return NULL; + } + //mStoreHandle = ::CertOpenStore( + // CERT_STORE_PROV_SYSTEM, + // 0, + // 0, + // dwFlags, + // storeName + // ); + mStoreHandle = ::CertOpenSystemStore(0, TEXT("Root")); +#ifdef UNICODE + LocalFree((HLOCAL)storeName); +#endif + + if(NULL == mStoreHandle) + { + ErrLog( << name.c_str() << " system certificate store cannot be openned"); + assert(0); + return NULL; + } + InfoLog( << name.c_str() << " System certificate store opened"); + return mStoreHandle; +} + +void +WinSecurity::closeCertifStore(HCERTSTORE storeHandle) +{ + if (NULL == storeHandle) + return; + + ::CertCloseStore(storeHandle ,0); +} +void +WinSecurity::getCerts(MsCertStoreType eType) +{ + //retrive only certificates + HCERTSTORE storeHandle = NULL; + storeHandle = openSystemCertStore(certStoreTypes(eType)); + int i = 0; + if(NULL != storeHandle) + { + PCCERT_CONTEXT pCertContext = NULL; + while((pCertContext = ::CertEnumCertificatesInStore(storeHandle, pCertContext)) != NULL) + { + Data certDER(Data::Borrow, (const char*)pCertContext->pbCertEncoded, pCertContext->cbCertEncoded); + addCertDER (BaseSecurity::RootCert, NULL, certDER, false); + i++; + } + CertFreeCertificateContext(pCertContext); + } + InfoLog( << i << " certs loaded of type " << eType ); + closeCertifStore(storeHandle); +} + + +#endif // ifdef USE_SSL + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/WinSecurity.hxx b/src/libs/resiprocate/resip/stack/ssl/WinSecurity.hxx new file mode 100644 index 00000000..0f6c5158 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/WinSecurity.hxx @@ -0,0 +1,102 @@ +#if !defined(RESIP_WINSECURITY_HXX) +#define RESIP_WINSECURITY_HXX + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + + +#include "resip/stack/ssl/Security.hxx" +#include <wincrypt.h> + +namespace resip +{ + +/** + WARNING - This class is only appropriate for client TLS connections, as it + only loads root certs. There is currently no logic to load domain or + user certificates. +*/ + +class WinSecurity : public Security +{ + public: + + typedef enum + { + ROOT_CA_STORE=1, //"ROOT": predefined system store + CA_STORE=2, //"CA": predefined system store + PRIVATE_STORE=3, //"MY": predefined system store; should store the domain certificate/private key + USERS_STORE=4 //"DOMAIN_USERS" (only for server): + //administrator-defined system store; should store the + //certificate/private keys for the users associated + //with the domain + } MsCertStoreType; + //for details on certificate stores, see + //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seccrypto/security/certificate_services.asp + WinSecurity(const CipherList& cipherList = ExportableSuite) : Security(cipherList){} + + virtual void preload(); + virtual void onReadPEM(const Data& name, PEMType type, Data& buffer) const; + virtual void onWritePEM(const Data& name, PEMType type, const Data& buffer) const; + virtual void onRemovePEM(const Data& name, PEMType type) const; + + + protected: + HCERTSTORE openSystemCertStore(const Data& name); + void getCerts(MsCertStoreType eType); + void closeCertifStore(HCERTSTORE); +}; + +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/resip/update-svn-ignores.sh b/src/libs/resiprocate/resip/update-svn-ignores.sh new file mode 100644 index 00000000..a1b426e2 --- /dev/null +++ b/src/libs/resiprocate/resip/update-svn-ignores.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +DIRS=". resiprocate resiprocate/test resiprocate/dum resiprocate/dum/test resiprocate/dum/doc" +T=$(mktemp) + +[ -z "${T}"] || [ ! -f "${T}" ] || T=/tmp/$$.uti + + +for D in ${DIRS}; do + cp /dev/null "${T}" + for I in .cvsignore .autotools-conflicts-list; do + echo ${I} >> "${T}" + [ -f "${D}/${I}" ] && cat ${D}/${I} >> "${T}" + done + echo "+++ ${D} ignore list:" + awk '{print "\t"$0;}' "${T}" + svn propset svn:ignore -F "${T}" "${D}" +done + + +rm "${T}" diff --git a/src/libs/resiprocate/rutil/.cvsignore b/src/libs/resiprocate/rutil/.cvsignore new file mode 100644 index 00000000..ce294201 --- /dev/null +++ b/src/libs/resiprocate/rutil/.cvsignore @@ -0,0 +1,30 @@ +*~ +.DS_Store +.dependlibs +Assert.cxx +Assert.hxx +Debug +Release +bar +bin.debug.Darwin.Power_Macintosh +bin.debug.Linux.i686 +bin.debug.QNX.x86pc +bin.debug.SunOS.sun4u +bin.i686 +bin.nodebug.Linux.i686 +bin.opt.Linux.i686 +bin.opt.QNX.x86pc +bin.prof.Linux.i686 +cassert +obj.debug.Darwin.Power_Macintosh +obj.debug.Linux.i686 +obj.debug.QNX.x86pc +obj.debug.SunOS.sun4u +obj.i686 +obj.nodebug.Linux.i686 +obj.opt.Linux.i686 +obj.opt.QNX.x86pc +obj.prof.Linux.i686 +SSL-Release +SSL-Debug +*.user \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/AbstractFifo.cxx b/src/libs/resiprocate/rutil/AbstractFifo.cxx new file mode 100644 index 00000000..aac5feb5 --- /dev/null +++ b/src/libs/resiprocate/rutil/AbstractFifo.cxx @@ -0,0 +1,63 @@ +#include <cassert> +#include "rutil/AbstractFifo.hxx" + +using namespace resip; + +FifoStatsInterface::FifoStatsInterface() : + mRole(0) +{ +} + +FifoStatsInterface::~FifoStatsInterface() +{ +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/AbstractFifo.hxx b/src/libs/resiprocate/rutil/AbstractFifo.hxx new file mode 100644 index 00000000..4364eae1 --- /dev/null +++ b/src/libs/resiprocate/rutil/AbstractFifo.hxx @@ -0,0 +1,541 @@ +#ifndef RESIP_AbstractFifo_hxx +#define RESIP_AbstractFifo_hxx + +#include <cassert> +#include <deque> + +#include "rutil/Mutex.hxx" +#include "rutil/Condition.hxx" +#include "rutil/Lock.hxx" +#include "rutil/CongestionManager.hxx" + +#include "rutil/compat.hxx" +#include "rutil/Timer.hxx" + +namespace resip +{ +/** + @brief Interface for providing metrics on FIFOs, primarily used by + CongestionManager. + Provides four different types of metrics: + - size : The number of elements in the queue + - time-depth : The age of the oldest item in the queue (ie, the front) + - expected wait-time : A heuristic estimating the amount of time a message + would take to be serviced if it were added to the queue. + - average service time : The average time it takes to service a single + element from the queue (this is helpful in congestion control, but is + mostly intended for logging). +*/ +class FifoStatsInterface +{ + public: + + FifoStatsInterface(); + virtual ~FifoStatsInterface(); + + /** + Returns the expected time it will take to service all messages + currently in the queue (in milli-seconds) + */ + virtual time_t expectedWaitTimeMilliSec() const =0; + + /** + Returns the difference in time between the youngest and oldest item in + the FIFO in seconds + */ + virtual time_t getTimeDepth() const = 0; + + /** + Returns the number of elements in the FIFO + */ + virtual size_t getCountDepth() const = 0; + + /** + Returns the average time it takes for individual messages to be + serviced (in micro-seconds) + */ + virtual time_t averageServiceTimeMicroSec() const = 0; + + /** + @internal + Return this fifo's role-number. The meaning of the return is defined on + a per-application basis, and will have special meaning to the + CongestionManager implementation specific to that app. For instance, + 1 might be understood to represent the main state machine fifo in + resip, 2 might indicate a transport fifo (of which there may be + several), 3 might indicate a particular TU's fifo, etc. + These are intended for use by CongestionManager only. + */ + inline UInt8 getRole() const {return mRole;} + + /** + @internal + Set this fifo's role-number. + @see getRole() + */ + inline void setRole(UInt8 role) {mRole=role;} + + /** + Sets the description for this fifo. This is used in the logging for + this fifo's statistics, and can also be used by the CongestionManager + to assign a role-number. + @param description The description for this fifo. + */ + inline void setDescription(const resip::Data& description) + { + mDescription=description; + } + + /** + Gets the description for this fifo. + @see setDescription() + */ + virtual const resip::Data& getDescription() const {return mDescription;} + + protected: + Data mDescription; + UInt8 mRole; +}; + +/** + * The getNext() method takes an argument {ms} that normally + * the number of milliseconds to wait. There are two special values: + * NOWAIT + * Don't wait/block/sleep. If no message to retrieve, return NULL. + * FOREVER + * Wait forever until a message is available. + * Note that the encoding (0 vs -1) is the oppositive convention + * of standard APIs such as epoll_wait(). This is for historical reasons. + */ +#define RESIP_FIFO_NOWAIT -1 +#define RESIP_FIFO_FOREVER 0 + +/** + @brief The base class from which various templated Fifo classes are derived. + + (aka template hoist) + AbstractFifo's get operations are all threadsafe; AbstractFifo does not + define any put operations (these are defined in subclasses). + @note Users of the resip stack will not need to interact with this class + directly in most cases. Look at Fifo and TimeLimitFifo instead. + + @ingroup message_passing + */ +template <typename T> +class AbstractFifo : public FifoStatsInterface +{ + public: + /** + * @brief Constructor + * @param maxSize max number of messages to keep + **/ + AbstractFifo() + : FifoStatsInterface(), + mLastSampleTakenMicroSec(0), + mCounter(0), + mAverageServiceTimeMicroSec(0), + mSize(0) + {} + + virtual ~AbstractFifo() + { + } + + /** + @brief is the queue empty? + @return true if the queue is empty and false otherwise + **/ + bool empty() const + { + Lock lock(mMutex); (void)lock; + return mFifo.empty(); + } + + /** + @brief get the current size of the fifo. + @note Note you should not use this function to determine + whether a call to getNext() will block or not. Use + messageAvailable() instead. + @return the number of messages in the queue + */ + virtual unsigned int size() const + { + Lock lock(mMutex); (void)lock; + return (unsigned int)mFifo.size(); + } + + /** + @brief is a message available? + @retval true if a message is available and false otherwise + */ + + bool messageAvailable() const + { + Lock lock(mMutex); (void)lock; + return !mFifo.empty(); + } + + /** + @brief computes the time delta between the oldest and newest queue members + @note defaults to zero, overridden by TimeLimitFifo<T> + @return the time delta between the oldest and newest queue members + */ + virtual time_t getTimeDepth() const + { + return 0; + } + + virtual size_t getCountDepth() const + { + return mSize; + } + + virtual time_t expectedWaitTimeMilliSec() const + { + return ((mAverageServiceTimeMicroSec*mSize)+500)/1000; + } + + virtual time_t averageServiceTimeMicroSec() const + { + return mAverageServiceTimeMicroSec; + } + + /// remove all elements in the queue (or not) + virtual void clear() {}; + + protected: + /** + @brief Returns the first message available. + @details Returns the first message available. It will wait if no + messages are available. If a signal interrupts the wait, + it will retry the wait. Signals can therefore not be caught + via getNext. If you need to detect a signal, use block + prior to calling getNext. + @return the first message available + */ + T getNext() + { + Lock lock(mMutex); (void)lock; + onFifoPolled(); + + // Wait util there are messages available. + while (mFifo.empty()) + { + mCondition.wait(mMutex); + } + + // Return the first message on the fifo. + // + T firstMessage(mFifo.front()); + mFifo.pop_front(); + onMessagePopped(); + return firstMessage; + } + + + /** + @brief Returns the next message available. + @details Returns the next message available. Will wait up to + ms milliseconds if no information is available. If + the specified time passes or a signal interrupts the + wait, this method returns 0. This interface provides + no mechanism to distinguish between timeout and + interrupt. + */ + bool getNext(int ms, T& toReturn) + { + if(ms == 0) + { + toReturn = getNext(); + return true; + } + + if(ms < 0) + { + Lock lock(mMutex); (void)lock; + onFifoPolled(); + if (mFifo.empty()) // WATCHOUT: Do not test mSize instead + return false; + toReturn = mFifo.front(); + mFifo.pop_front(); + return true; + } + + const UInt64 begin(Timer::getTimeMs()); + const UInt64 end(begin + (unsigned int)(ms)); // !kh! ms should've been unsigned :( + Lock lock(mMutex); (void)lock; + onFifoPolled(); + + // Wait until there are messages available + while (mFifo.empty()) + { + if(ms==0) + { + return false; + } + const UInt64 now(Timer::getTimeMs()); + if(now >= end) + { + return false; + } + + unsigned int timeout((unsigned int)(end - now)); + + // bail if total wait time exceeds limit + bool signaled = mCondition.wait(mMutex, timeout); + if (!signaled) + { + return false; + } + } + + // Return the first message on the fifo. + // + toReturn=mFifo.front(); + mFifo.pop_front(); + onMessagePopped(); + return true; + } + + typedef std::deque<T> Messages; + + void getMultiple(Messages& other, unsigned int max) + { + Lock lock(mMutex); (void)lock; + onFifoPolled(); + assert(other.empty()); + while (mFifo.empty()) + { + mCondition.wait(mMutex); + } + + if(mFifo.size() <= max) + { + std::swap(mFifo, other); + onMessagePopped(mSize); + } + else + { + size_t num=max; + while( 0 != max-- ) + { + other.push_back(mFifo.front()); + mFifo.pop_front(); + } + onMessagePopped((unsigned int)num); + } + } + + bool getMultiple(int ms, Messages& other, unsigned int max) + { + if(ms==0) + { + getMultiple(other,max); + return true; + } + + assert(other.empty()); + const UInt64 begin(Timer::getTimeMs()); + const UInt64 end(begin + (unsigned int)(ms)); // !kh! ms should've been unsigned :( + Lock lock(mMutex); (void)lock; + onFifoPolled(); + + // Wait until there are messages available + while (mFifo.empty()) + { + if(ms < 0) + { + return false; + } + const UInt64 now(Timer::getTimeMs()); + if(now >= end) + { + return false; + } + + unsigned int timeout((unsigned int)(end - now)); + + // bail if total wait time exceeds limit + bool signaled = mCondition.wait(mMutex, timeout); + if (!signaled) + { + return false; + } + } + + if(mFifo.size() <= max) + { + std::swap(mFifo, other); + onMessagePopped(mSize); + } + else + { + size_t num=max; + while( 0 != max-- ) + { + other.push_back(mFifo.front()); + mFifo.pop_front(); + } + onMessagePopped((unsigned int)num); + } + return true; + } + + size_t add(const T& item) + { + Lock lock(mMutex); (void)lock; + mFifo.push_back(item); + mCondition.signal(); + onMessagePushed(1); + return mFifo.size(); + } + + size_t addMultiple(Messages& items) + { + Lock lock(mMutex); (void)lock; + size_t size=items.size(); + if(mFifo.empty()) + { + std::swap(mFifo, items); + } + else + { + // I suppose it is possible to optimize this as a push_front() from + // mFifo to items, and then do a swap, if items is larger. + while(!items.empty()) + { + mFifo.push_back(items.front()); + items.pop_front(); + } + } + mCondition.signal(); + onMessagePushed((int)size); + return mFifo.size(); + } + + /** @brief container for FIFO items */ + Messages mFifo; + /** @brief access serialization lock */ + mutable Mutex mMutex; + /** @brief condition for waiting on new queue items */ + Condition mCondition; + + mutable UInt64 mLastSampleTakenMicroSec; + mutable UInt32 mCounter; + mutable UInt32 mAverageServiceTimeMicroSec; + // std::deque has to perform some amount of traversal to calculate its + // size; we maintain this count so that it can be queried without locking, + // in situations where it being off by a small amount is ok. + UInt32 mSize; + + virtual void onFifoPolled() + { + // !bwc! TODO allow this sampling frequency to be tweaked + if(mLastSampleTakenMicroSec && + mCounter && + (mCounter >= 64 || mFifo.empty())) + { + UInt64 now(Timer::getTimeMicroSec()); + UInt64 diff = now-mLastSampleTakenMicroSec; + + if(mCounter >= 4096) + { + mAverageServiceTimeMicroSec=(UInt32)resipIntDiv(diff, mCounter); + } + else // fifo got emptied; merge into a rolling average + { + // .bwc. This is a moving average with period 64, round to + // nearest int. + mAverageServiceTimeMicroSec=(UInt32)resipIntDiv( + diff+((4096-mCounter)*mAverageServiceTimeMicroSec), + 4096U); + } + mCounter=0; + if(mFifo.empty()) + { + mLastSampleTakenMicroSec=0; + } + else + { + mLastSampleTakenMicroSec=now; + } + } + } + + /** + Called when a message (or messages) are removed from this fifo. Used to + drive service time calculations. + */ + virtual void onMessagePopped(unsigned int num=1) + { + mCounter+=num; + mSize-=num; + } + + virtual void onMessagePushed(int num) + { + if(mSize==0) + { + // Fifo went from empty to non-empty. Take a timestamp, and record + // how long it takes to process some messages. + mLastSampleTakenMicroSec=Timer::getTimeMicroSec(); + } + mSize+=num; + } + private: + // no value semantics + AbstractFifo(const AbstractFifo&); + AbstractFifo& operator=(const AbstractFifo&); +}; + +} // namespace resip + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/AsyncID.hxx b/src/libs/resiprocate/rutil/AsyncID.hxx new file mode 100644 index 00000000..d8f1226b --- /dev/null +++ b/src/libs/resiprocate/rutil/AsyncID.hxx @@ -0,0 +1,94 @@ +#if !defined(RESIP_ASYNC_ID_HXX) +#define RESIP_ASYNC_ID_HXX + +namespace resip +{ + +// ?dcm? -- I originally wanted a flexible class that would map to any asyncronous +// completetion token. One way to do this is with templates in the function +// that accept Async ids, another way is to have them passed around by +// reference, but in the CounterPath case(for example) ids are simle ulongs, so this +// would cause a lot of work in the glue code. Of course, this definition is +// located here, so it would be easy to change to a lightweight wrapper class to +// other implementation. A templatized class w/ a conversion operator would +// work. +// sometimes GC and handles make life easier. Of course the template approach +// could involve ref. counting when necessary. + +//should be small enough to happily pass by value +// class AsyncID +// { +// public: +// virtual operator==(const AsyncID& other) const = 0; +// virtual bool operator<(const AsyncID& rhs) const = 0; +// }; + +typedef unsigned long AsyncID; + +//error code of zero is success. Should define an enum for implementations to +//map to. +class AsyncResult +{ + public: + AsyncResult() : mErrorCode(0) {} + AsyncResult(long errorCode) : mErrorCode(errorCode) {} + void setError(long errorCode) { mErrorCode = errorCode; } + long errorCode() const { return mErrorCode; } + bool success() const { return mErrorCode == 0 ? true : false; } + protected: + long mErrorCode; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/AsyncProcessHandler.hxx b/src/libs/resiprocate/rutil/AsyncProcessHandler.hxx new file mode 100644 index 00000000..aea7a0b9 --- /dev/null +++ b/src/libs/resiprocate/rutil/AsyncProcessHandler.hxx @@ -0,0 +1,68 @@ +#ifndef RESIP_AsyncProcessHandler_HXX +#define RESIP_AsyncProcessHandler_HXX + +namespace resip +{ + +//called when an event from outside the process() lookp of the sipstack occurs +//which requires the sipstack to all process() +class AsyncProcessHandler +{ + public: + virtual ~AsyncProcessHandler() {} + virtual void handleProcessNotification() = 0; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/AtomicCounter.cxx b/src/libs/resiprocate/rutil/AtomicCounter.cxx new file mode 100644 index 00000000..c0d92dd3 --- /dev/null +++ b/src/libs/resiprocate/rutil/AtomicCounter.cxx @@ -0,0 +1,32 @@ +#include "rutil/AtomicCounter.hxx" +#include "rutil/Lock.hxx" + +using namespace resip; +AtomicCounter::AtomicCounter(int initialValue) + :mCounterValue(initialValue) +{ + +} + + +AtomicCounter::~AtomicCounter() +{ + +} + +int AtomicCounter::value() +{ + return mCounterValue; +} + +int AtomicCounter::increment() +{ + Lock l(mMutex); + return ++mCounterValue; +} + +int AtomicCounter::decrement() +{ + Lock l(mMutex); + return --mCounterValue; +} diff --git a/src/libs/resiprocate/rutil/AtomicCounter.hxx b/src/libs/resiprocate/rutil/AtomicCounter.hxx new file mode 100644 index 00000000..2a4e6374 --- /dev/null +++ b/src/libs/resiprocate/rutil/AtomicCounter.hxx @@ -0,0 +1,26 @@ +#ifndef ATOMICINCREMENT_HXX +#define ATOMICINCREMENT_HXX + +#include "rutil/Mutex.hxx" + +namespace resip +{ + +class AtomicCounter +{ +public: + AtomicCounter(int initialValue = 0); + ~AtomicCounter(); + + int value(); + int increment(); + int decrement(); + +protected: + Mutex mMutex; + int mCounterValue; +}; + +} + +#endif // ATOMICINCREMENT_HXX diff --git a/src/libs/resiprocate/rutil/BaseException.cxx b/src/libs/resiprocate/rutil/BaseException.cxx new file mode 100644 index 00000000..f48cb7be --- /dev/null +++ b/src/libs/resiprocate/rutil/BaseException.cxx @@ -0,0 +1,91 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rutil/BaseException.hxx" +#include "rutil/Logger.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::SIP + +BaseException::BaseException( const Data& msg, + const Data& file, + const int line) : + message( msg ), + fileName( file ), + lineNumber( line ) +{ +#if !defined(RESIP_NO_EXCEPTION_DEBUG_LOGS) + DebugLog(<< "BaseException at " << file << ":" << line << " " << message); +#endif +} + +BaseException::~BaseException() throw() +{} + +#ifndef RESIP_USE_STL_STREAMS +EncodeStream& resip::operator<<(EncodeStream& strm, const BaseException& e) +{ + strm << e.name() << " " << e.message << " @ " << e.fileName << ":" << e.lineNumber; + return strm; +} +#endif + +ostream& resip::operator<<(ostream& strm, const BaseException& e) +{ + strm << e.name() << " " << e.message << " @ " << e.fileName << ":" << e.lineNumber; + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/rutil/BaseException.hxx b/src/libs/resiprocate/rutil/BaseException.hxx new file mode 100644 index 00000000..435066be --- /dev/null +++ b/src/libs/resiprocate/rutil/BaseException.hxx @@ -0,0 +1,96 @@ +#if !defined(RESIP_BASEEXCEPTION_HXX) +#define RESIP_BASEEXCEPTION_HXX + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <exception> +#include <iostream> + +#include "rutil/Data.hxx" + +namespace resip +{ + +/** + @brief The abstract base-class for all exceptions thrown by resip code. +*/ +class BaseException : public std::exception +{ + public: + virtual const char* name() const = 0; + + const Data& getMessage() const {return message;} + virtual const char* what() const throw() {return message.data();} + + protected: + BaseException(const Data& msg, + const Data& file, + int line); + + virtual ~BaseException() throw(); + + resip::Data message; + resip::Data fileName; + int lineNumber; + +#ifndef RESIP_USE_STL_STREAMS + friend EncodeStream& operator<<(EncodeStream& strm, const BaseException& e); +#endif + friend std::ostream& operator<<(std::ostream& strm, const BaseException& e); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/CircularBuffer.hxx b/src/libs/resiprocate/rutil/CircularBuffer.hxx new file mode 100644 index 00000000..5ff19e43 --- /dev/null +++ b/src/libs/resiprocate/rutil/CircularBuffer.hxx @@ -0,0 +1,79 @@ +#if !defined(RESIP_CIRCULARBUFFER_HXX) +#define RESIP_CIRCULARBUFFER_HXX + +#include <vector> + +namespace resip +{ + +class CircularBuffer : private vector<unsigned char> +{ + public: + CircularBuffer(unsigned int capacity) + : vector<char>(0), + mPosition(0), + mSize(0) + { + reserve(capacity); + } + + void push_back(unsigned char); + unsigned char front() const; + void pop_front(); + unsigned int size(); + private: + unsigned int mPosition; + unsigned int mSize; +}; + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Coders.cxx b/src/libs/resiprocate/rutil/Coders.cxx new file mode 100644 index 00000000..b142584f --- /dev/null +++ b/src/libs/resiprocate/rutil/Coders.cxx @@ -0,0 +1,82 @@ +#include <assert.h> + +#include "compat.hxx" +#include "rutil/Coders.hxx" + + +namespace resip +{ + +using namespace std; + +Data +Base64Coder::encode(const Data& data) +{ + return data.base64encode(true/*safe URL char set*/); +} + +Data +Base64Coder::decode(const Data& source) +{ + return source.base64decode(); +} + + +}; + + +// Local Variables: +// mode:c++ +// c-file-style:"ellemtel" +// c-file-offsets:((case-label . +)) +// indent-tabs-mode:nil +// End +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Coders.hxx b/src/libs/resiprocate/rutil/Coders.hxx new file mode 100644 index 00000000..ff006c41 --- /dev/null +++ b/src/libs/resiprocate/rutil/Coders.hxx @@ -0,0 +1,72 @@ +#if !defined(RESIP_CODERS_HXX) +#define RESIP_CODERS_HXX + +#include "rutil/Data.hxx" + +namespace resip +{ + +class Base64Coder +{ + public: + // encoded data is 4/3 rds length of input + static Data encode(const Data&); + + // decoded data is 3/4s length of coded + static Data decode(const Data&); + + private: +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Condition.cxx b/src/libs/resiprocate/rutil/Condition.cxx new file mode 100644 index 00000000..9ef02f89 --- /dev/null +++ b/src/libs/resiprocate/rutil/Condition.cxx @@ -0,0 +1,580 @@ +#include <cassert> +#include <climits> + +#ifndef WIN32 +# include <pthread.h> +# include <errno.h> +# include <sys/time.h> +# include <sys/syscall.h> +# include <unistd.h> +#endif + +#include "rutil/compat.hxx" +#include "rutil/Condition.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/Timer.hxx" + +#ifdef _RESIP_MONOTONIC_CLOCK +#ifdef __APPLE__ +#undef _RESIP_MONOTONIC_CLOCK +#warning Mac OS X does not support POSIX monotonic timers. +#endif +#endif + +using namespace resip; + +Condition::Condition() +{ + //std::cerr << this << " Condition::Condition" << std::endl; + +#ifdef WIN32 +# ifdef RESIP_CONDITION_WIN32_CONFORMANCE_TO_POSIX + m_blocked = 0; + m_gone = 0; + m_waiting = 0; + m_gate = reinterpret_cast<void*>(CreateSemaphore(0, 1, 1, 0)); + m_queue = reinterpret_cast<void*>(CreateSemaphore(0, 0, LONG_MAX, 0)); + m_mutex = reinterpret_cast<void*>(CreateMutex(0, 0, 0)); + + if (!m_gate || !m_queue || !m_mutex) + { + int res = 0; + if (m_gate) + { + res = CloseHandle(reinterpret_cast<HANDLE>(m_gate)); + assert(res); + } + if (m_queue) + { + res = CloseHandle(reinterpret_cast<HANDLE>(m_queue)); + assert(res); + } + if (m_mutex) + { + res = CloseHandle(reinterpret_cast<HANDLE>(m_mutex)); + assert(res); + } + + assert(0); + } +# else + mId = CreateEvent( + NULL, //LPSECURITY_ATTRIBUTES lpEventAttributes, + // pointer to security attributes + FALSE, // BOOL bManualReset, // flag for manual-reset event + FALSE, //BOOL bInitialState, // flag for initial state + NULL //LPCTSTR lpName // pointer to event-object name + ); + assert(mId); +# endif +#else +#ifdef _RESIP_MONOTONIC_CLOCK + pthread_condattr_t attr; + struct timespec dummy; + int ret = pthread_condattr_init( &attr ); + assert( ret == 0 ); + +// if((syscall( __NR_clock_getres, CLOCK_MONOTONIC, &dummy ) == 0) && + if((clock_getres( CLOCK_MONOTONIC, &dummy ) == 0) && + (pthread_condattr_setclock( &attr, CLOCK_MONOTONIC ) == 0)) + { + ret = pthread_cond_init( &mId, &attr ); + assert( ret == 0 ); + pthread_condattr_destroy( &attr ); + return; + } + pthread_condattr_destroy( &attr ); +#endif + int rc = pthread_cond_init(&mId,0); + (void)rc; + assert( rc == 0 ); +#endif +} + + +Condition::~Condition () +{ +#ifdef WIN32 +# ifdef RESIP_CONDITION_WIN32_CONFORMANCE_TO_POSIX + int res = 0; + res = CloseHandle(reinterpret_cast<HANDLE>(m_gate)); + assert(res); + res = CloseHandle(reinterpret_cast<HANDLE>(m_queue)); + assert(res); + res = CloseHandle(reinterpret_cast<HANDLE>(m_mutex)); + assert(res); +# else + BOOL ok = CloseHandle(mId); + assert( ok ); +# endif +#else + if (pthread_cond_destroy(&mId) == EBUSY) + { + assert(0); + } +#endif +} + +#if defined(WIN32) && defined(RESIP_CONDITION_WIN32_CONFORMANCE_TO_POSIX) +void +Condition::enterWait () +{ + int res = 0; + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE); + assert(res == WAIT_OBJECT_0); + ++m_blocked; + res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0); + assert(res); +} +#endif + +void +Condition::wait (Mutex& mutex) +{ + //std::cerr << "Condition::wait " << mutex << std::endl; +#ifdef WIN32 +# ifdef RESIP_CONDITION_WIN32_CONFORMANCE_TO_POSIX + enterWait(); + + // Release the mutex + mutex.unlock(); + + // do wait + { + int res = 0; + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue), INFINITE); + assert(res == WAIT_OBJECT_0); + + unsigned was_waiting=0; + unsigned was_gone=0; + + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE); + assert(res == WAIT_OBJECT_0); + was_waiting = m_waiting; + was_gone = m_gone; + if (was_waiting != 0) + { + if (--m_waiting == 0) + { + if (m_blocked != 0) + { + res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0); // open m_gate + assert(res); + was_waiting = 0; + } + else if (m_gone != 0) + m_gone = 0; + } + } + else if (++m_gone == (ULONG_MAX / 2)) + { + // timeout occured, normalize the m_gone count + // this may occur if many calls to wait with a timeout are made and + // no call to notify_* is made + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE); + assert(res == WAIT_OBJECT_0); + m_blocked -= m_gone; + res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0); + assert(res); + m_gone = 0; + } + res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex)); + assert(res); + + if (was_waiting == 1) + { + for (/* */ ; was_gone; --was_gone) + { + // better now than spurious later + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue), + INFINITE); + assert(res == WAIT_OBJECT_0); + } + res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0); + assert(res); + } + } + + // Reacquire the mutex + mutex.lock(); + +# else + // FixMe: Race condition between time we get mId and when we + // re-acquire the mutex. + mutex.unlock(); + WaitForSingleObject(mId,INFINITE); + mutex.lock(); +# endif +#else + int ret = pthread_cond_wait(&mId, mutex.getId()); + (void)ret; + assert( ret == 0 ); +#endif +} + +void +Condition::wait (Mutex* mutex) +{ + this->wait(*mutex); +} + +bool +Condition::wait(Mutex& mutex, + unsigned int ms) +{ + if (ms == 0) + { + wait(mutex); + return true; + } + +#ifdef WIN32 +# ifdef RESIP_CONDITION_WIN32_CONFORMANCE_TO_POSIX + enterWait(); + + // Release the mutex + mutex.unlock(); + + // do timed wait + bool ret = false; + unsigned int res = 0; + +#if 0 /* unnecessary time stuff - used in BOOST implementation because expiry time is provided to do_timed_wait - we pass in an interval */ + UInt64 start = Timer::getTimeMs(); + + for (;;) + { + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue), + ms); + assert(res != WAIT_FAILED && res != WAIT_ABANDONED); + ret = (res == WAIT_OBJECT_0); + if (res == WAIT_TIMEOUT) + { + UInt64 now = Timer::getTimeMs(); + unsigned int elapsed = (unsigned int)(now - start); + if (ms > elapsed) + { + ms -= elapsed; + continue; + } + } + + break; + } +#endif + + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue),ms); + assert(res != WAIT_FAILED && res != WAIT_ABANDONED); + ret = (res == WAIT_OBJECT_0); + + unsigned was_waiting=0; + unsigned was_gone=0; + + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE); + assert(res == WAIT_OBJECT_0); + was_waiting = m_waiting; + was_gone = m_gone; + if (was_waiting != 0) + { + if (!ret) // timeout + { + if (m_blocked != 0) + --m_blocked; + else + ++m_gone; // count spurious wakeups + } + if (--m_waiting == 0) + { + if (m_blocked != 0) + { + res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0); // open m_gate + assert(res); + was_waiting = 0; + } + else if (m_gone != 0) + m_gone = 0; + } + } + else if (++m_gone == (ULONG_MAX / 2)) + { + // timeout occured, normalize the m_gone count + // this may occur if many calls to wait with a timeout are made and + // no call to notify_* is made + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE); + assert(res == WAIT_OBJECT_0); + m_blocked -= m_gone; + res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0); + assert(res); + m_gone = 0; + } + res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex)); + assert(res); + + if (was_waiting == 1) + { + for (/* */ ; was_gone; --was_gone) + { + // better now than spurious later + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue), INFINITE); + assert(res == WAIT_OBJECT_0); + } + res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0); + assert(res); + } + + // Reacquire the mutex + mutex.lock(); + + return ret; + +# else + // FixMe: Race condition between time we get mId and when we + // re-acquire the mutex. + // + // SLG: A Note about the Win32 Implementation of Conditions + // + // I have investigated a fix for this. A solution to this problem is + // non-trivial. Please read http://www.cs.wustl.edu/~schmidt/win32-cv-1.html + // for a full explanation. This is an implementation of the SetEvent solution + // discussed in that article. This solution has the following issues: + // 1. Unfairness - ie. First thread to call wait may not be first thread + // to be released from condition. + // 2. Incorrectness due to a race condition when a broadcast occurs + // (see the link for more details on these issues) + // + // There is a solution that corrects these two problem, but also introduces 2 more. + // This solution (also discussed in the link) requires the use of a primitive only + // available in WinNT and above. It also requires that the Mutex passed in be + // implemented using windows Mutexes instead of CriticalSections - they are less + // efficient. Thus the problems with this SignalObjectAndWait solution are: + // 1. Not portable to all versions of windows - ie. will not work with Win98/Me + // 2. Less efficient than tthe SetEvent solution + // + // I have choosen to stick with the SetEvent Solution for the following reasons: + // 1. Speed is important. + // 2. The Unfairness issue is not really a big problem since the stack currently + // does not call a wait function from two different threads. (assuming the + // hosting application always calls process() from the same thread). The only + // time multi-threading comes into the picture is when the transports queue + // messages from the wire onto the stateMacFifo - but they are retrieved off the + // Fifo by a single thread. + // 3. The Incorrectness issue is also not a big problem, since the stack currently + // doesn't use the broadcast member of this class. + // + // Note: The implementation of broadcast remains incomplete - since it is currently + // unused and would require an additional CriticalSection Enter and Leave to + // keep track of a counter (see the above link for more info). This can be + // easily added in the future if required. + mutex.unlock(); + DWORD ret = WaitForSingleObject(mId, ms); + mutex.lock(); + assert(ret != WAIT_FAILED); + return (ret == WAIT_OBJECT_0); +# endif +#else // WIN32 + UInt64 expires64 = Timer::getTimeMs() + ms; + timespec expiresTS; + expiresTS.tv_sec = expires64 / 1000; + expiresTS.tv_nsec = (expires64 % 1000) * 1000000L; + + assert( expiresTS.tv_nsec < 1000000000L ); + + //std::cerr << "Condition::wait " << mutex << "ms=" << ms << " expire=" << expiresTS.tv_sec << " " << expiresTS.tv_nsec << std::endl; + int ret = pthread_cond_timedwait(&mId, mutex.getId(), &expiresTS); + + if (ret == EINTR || ret == ETIMEDOUT) + { + return false; + } + else + { + //std::cerr << this << " pthread_cond_timedwait failed " << ret << " mutex=" << mutex << std::endl; + (void)ret; + assert( ret == 0 ); + return true; + } +#endif // not WIN32 +} + +bool +Condition::wait (Mutex* mutex, unsigned int ms) +{ + return this->wait(*mutex, ms); +} + +void +Condition::signal () +{ +#ifdef WIN32 +# ifdef RESIP_CONDITION_WIN32_CONFORMANCE_TO_POSIX + unsigned signals = 0; + + int res = 0; + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE); + assert(res == WAIT_OBJECT_0); + + if (m_waiting != 0) // the m_gate is already closed + { + if (m_blocked == 0) + { + res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex)); + assert(res); + return; + } + + ++m_waiting; + --m_blocked; + signals = 1; + } + else + { + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE); + assert(res == WAIT_OBJECT_0); + if (m_blocked > m_gone) + { + if (m_gone != 0) + { + m_blocked -= m_gone; + m_gone = 0; + } + signals = m_waiting = 1; + --m_blocked; + } + else + { + res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0); + assert(res); + } + } + + res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex)); + assert(res); + + if (signals) + { + res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_queue), signals, 0); + assert(res); + } +# else + BOOL ret = SetEvent( + mId // HANDLE hEvent // handle to event object + ); + assert(ret); +# endif +#else + int ret = pthread_cond_signal(&mId); + (void)ret; + assert( ret == 0 ); +#endif +} + + +void +Condition::broadcast() +{ +#ifdef WIN32 +# ifdef RESIP_CONDITION_WIN32_CONFORMANCE_TO_POSIX + unsigned signals = 0; + + int res = 0; + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE); + assert(res == WAIT_OBJECT_0); + + if (m_waiting != 0) // the m_gate is already closed + { + if (m_blocked == 0) + { + res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex)); + assert(res); + return; + } + + m_waiting += (signals = m_blocked); + m_blocked = 0; + } + else + { + res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE); + assert(res == WAIT_OBJECT_0); + if (m_blocked > m_gone) + { + if (m_gone != 0) + { + m_blocked -= m_gone; + m_gone = 0; + } + signals = m_waiting = m_blocked; + m_blocked = 0; + } + else + { + res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0); + assert(res); + } + } + + res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex)); + assert(res); + + if (signals) + { + res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_queue), signals, 0); + assert(res); + } +# else + assert(0); +# endif +#else + pthread_cond_broadcast(&mId); +#endif +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Condition.hxx b/src/libs/resiprocate/rutil/Condition.hxx new file mode 100644 index 00000000..23b75bbe --- /dev/null +++ b/src/libs/resiprocate/rutil/Condition.hxx @@ -0,0 +1,198 @@ +#if !defined(RESIP_CONDITION_HXX) +#define RESIP_CONDITION_HXX + +#if defined(WIN32) +# include <windows.h> +# include <winbase.h> +#else +# include <pthread.h> +#endif + +// !kh! +// Attempt to resolve POSIX behaviour conformance for win32 build. +#define RESIP_CONDITION_WIN32_CONFORMANCE_TO_POSIX + +namespace resip +{ + +class Mutex; + +/** + @brief + A <a href="http://en.wikipedia.org/wiki/Condition_variable#Condition_variables"> + condition variable</a> that can be signaled or waited on, wraps POSIX/Windows + implementations depending on environment. + + Here's an example (from ThreadIf): + +@code + void + ThreadIf::shutdown() + { + Lock lock(mShutdownMutex); + if (!mShutdown) + { + mShutdown = true; + mShutdownCondition.signal(); + } + } + + bool + ThreadIf::waitForShutdown(int ms) const + { + Lock lock(mShutdownMutex); + mShutdownCondition.wait(mShutdownMutex, ms); + return mShutdown; + } + @endcode + + @see Mutex +*/ +class Condition +{ + public: + Condition(); + virtual ~Condition(); + + /** wait for the condition to be signaled + @param mtx The mutex associated with the condition variable + */ + void wait (Mutex& mtx); + /** wait for the condition to be signaled + @param mtx The mutex associated with the condition variable + @retval true The condition was woken up by activity + @retval false Timeout or interrupt. + */ + bool wait (Mutex& mutex, unsigned int ms); + + // !kh! + // deprecate these? + void wait (Mutex* mutex); + bool wait (Mutex* mutex, unsigned int ms); + + /** Signal one waiting thread. + @return 0 Success + @return errorcode The error code of the failure + */ + void signal(); + + /** Signal all waiting threads. + @return 0 Success + @return errorcode The error code of the failure + */ + void broadcast(); + + private: + // !kh! + // no value sematics, therefore private and not implemented. + Condition (const Condition&); + Condition& operator= (const Condition&); + + private: +#ifdef WIN32 +# ifdef RESIP_CONDITION_WIN32_CONFORMANCE_TO_POSIX + // !kh! + // boost clone with modification (license text below) + void enterWait (); + void* m_gate; + void* m_queue; + void* m_mutex; + unsigned m_gone; // # threads that timed out and never made it to m_queue + unsigned long m_blocked; // # threads blocked on the condition + unsigned m_waiting; // # threads no longer waiting for the condition but + // still waiting to be removed from m_queue +# else + HANDLE mId; +# endif +#else + mutable pthread_cond_t mId; +#endif +}; + +} + +#endif + +// Note: Win32 Condition implementation is a modified version of the +// Boost.org Condition implementation +// + +/* ==================================================================== + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * ==================================================================== + */ + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/ConfigParse.cxx b/src/libs/resiprocate/rutil/ConfigParse.cxx new file mode 100644 index 00000000..b40fbe27 --- /dev/null +++ b/src/libs/resiprocate/rutil/ConfigParse.cxx @@ -0,0 +1,412 @@ +#include <iostream> +#include <fstream> +#include <iterator> +#include <stdexcept> +#include <map> + +#include "rutil/ConfigParse.hxx" +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +namespace resip +{ + +ConfigParse::ConfigParse() +{ +} + +ConfigParse::~ConfigParse() +{ +} + +void +ConfigParse::parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount) +{ + parseCommandLine(argc, argv, skipCount); // will fill in mCmdLineConfigFilename if present + if(mCmdLineConfigFilename.empty()) + { + parseConfigFile(defaultConfigFilename); + } + else + { + parseConfigFile(mCmdLineConfigFilename); + } +} + +void +ConfigParse::parseCommandLine(int argc, char** argv, int skipCount) +{ + int startingArgForNameValuePairs = 1 + skipCount; + char *firstArg = argv[startingArgForNameValuePairs]; + // First argument is the configuration filename - it is optional and is never proceeded with a - or / +#ifdef WIN32 + if(argc >= (startingArgForNameValuePairs + 1) && firstArg[0] != '-' && firstArg[0] != '/') +#else + if(argc >= (startingArgForNameValuePairs + 1) && firstArg[0] != '-') +#endif + { + mCmdLineConfigFilename = firstArg; + startingArgForNameValuePairs++; + } + + // Loop through command line arguments and process them + for(int i = startingArgForNameValuePairs; i < argc; i++) + { + Data argData(argv[i]); + + // Process all commandNames that don't take values + if(isEqualNoCase(argData, "-?") || + isEqualNoCase(argData, "--?") || + isEqualNoCase(argData, "--help") || + isEqualNoCase(argData, "/?")) + { + printHelpText(argc, argv); + exit(1); + } + else if(argData.at(0) == '-' || argData.at(0) == '/') + { + Data name; + Data value; + ParseBuffer pb(argData); + + try + { + pb.skipChars(Data::toBitset("-/")); // Skip any leading -'s or /'s + const char * anchor = pb.position(); + pb.skipToOneOf("=:"); + if(!pb.eof()) + { + pb.data(name, anchor); + pb.skipChar(); + anchor = pb.position(); + pb.skipToEnd(); + pb.data(value, anchor); + + //cout << "Command line Name='" << name << "' value='" << value << "'" << endl; + insertConfigValue(name, value); + } + else + { + cerr << "Invalid command line parameters:" << endl; + cerr << " Name/Value pairs must contain an = or a : between the name and the value" << endl; + exit(-1); // todo - should convert this stuff to exceptions and let user decide to exit or not + } + } + catch(BaseException& ex) + { + cerr << "Invalid command line parameters:" << endl; + cerr << " Exception parsing Name/Value pairs: " << ex << endl; + exit(-1); // todo - should convert this stuff to exceptions and let user decide to exit or not + } + } + else + { + cerr << "Invalid command line parameters:" << endl; + cerr << " Name/Value pairs must be prefixed with either a -, --, or a /" << endl; + exit(-1); // todo - should convert this stuff to exceptions and let user decide to exit or not + } + } +} + +void +ConfigParse::parseConfigFile(const Data& filename) +{ + ifstream configFile(filename.c_str()); + + if(!configFile) + { + throw Exception("Error opening/reading configuration file", __FILE__, __LINE__); + } + + string sline; + const char * anchor; + while(getline(configFile, sline)) + { + Data line(sline); + Data name; + Data value; + ParseBuffer pb(line); + + pb.skipWhitespace(); + anchor = pb.position(); + if(pb.eof() || *anchor == '#') continue; // if line is a comment or blank then skip it + + // Look for end of name + pb.skipToOneOf("= \t"); + pb.data(name,anchor); + if(*pb.position()!='=') + { + pb.skipToChar('='); + } + pb.skipChar('='); + pb.skipWhitespace(); + anchor = pb.position(); + if(!pb.eof()) + { + pb.skipToOneOf("\r\n"); + pb.data(value, anchor); + } + //cout << "Config file Name='" << name << "' value='" << value << "'" << endl; + insertConfigValue(name, value); + } +} + +bool +ConfigParse::getConfigValue(const resip::Data& name, resip::Data &value) +{ + Data lowerName(name); lowerName.lowercase(); + ConfigValuesMap::iterator it = mConfigValues.find(lowerName); + if(it != mConfigValues.end()) + { + value = it->second; + return true; + } + // Not found + return false; +} + +Data +ConfigParse::getConfigData(const resip::Data& name, const resip::Data& defaultValue, bool useDefaultIfEmpty) +{ + Data ret(defaultValue); + if(getConfigValue(name, ret) && ret.empty() && useDefaultIfEmpty) + { + return defaultValue; + } + return ret; +} + +bool +ConfigParse::getConfigValue(const resip::Data& name, bool &value) +{ + Data lowerName(name); lowerName.lowercase(); + ConfigValuesMap::iterator it = mConfigValues.find(lowerName); + if(it != mConfigValues.end()) + { + if(it->second == "1" || + isEqualNoCase(it->second, "true") || + isEqualNoCase(it->second, "on") || + isEqualNoCase(it->second, "enable")) + { + value = true; + return true; + } + else if(it->second == "0" || + isEqualNoCase(it->second, "false") || + isEqualNoCase(it->second, "off") || + isEqualNoCase(it->second, "disable")) + { + value = false; + return true; + } + cerr << "Invalid boolean setting: " << name << " = " << it->second << ": Valid values are: 1,true,on,enable,0,false,off or disable" << endl; + return false; + } + // Not found + return false; +} + +bool +ConfigParse::getConfigBool(const resip::Data& name, bool defaultValue) +{ + bool ret = defaultValue; + getConfigValue(name, ret); + return ret; +} + +bool +ConfigParse::getConfigValue(const resip::Data& name, unsigned long &value) +{ + Data lowerName(name); lowerName.lowercase(); + ConfigValuesMap::iterator it = mConfigValues.find(lowerName); + if(it != mConfigValues.end()) + { + value = it->second.convertUnsignedLong(); + return true; + } + // Not found + return false; +} + +unsigned long +ConfigParse::getConfigUnsignedLong(const resip::Data& name, unsigned long defaultValue) +{ + unsigned long ret = defaultValue; + getConfigValue(name, ret); + return ret; +} + +bool +ConfigParse::getConfigValue(const resip::Data& name, int &value) +{ + Data lowerName(name); lowerName.lowercase(); + ConfigValuesMap::iterator it = mConfigValues.find(lowerName); + if(it != mConfigValues.end()) + { + value = it->second.convertInt(); + return true; + } + // Not found + return false; +} + + +int +ConfigParse::getConfigInt(const resip::Data& name, int defaultValue) +{ + int ret = defaultValue; + getConfigValue(name, ret); + return ret; +} + +bool +ConfigParse::getConfigValue(const resip::Data& name, unsigned short &value) +{ + Data lowerName(name); lowerName.lowercase(); + ConfigValuesMap::iterator it = mConfigValues.find(lowerName); + if(it != mConfigValues.end()) + { + value = it->second.convertInt(); + return true; + } + // Not found + return false; +} + + +unsigned short +ConfigParse::getConfigUnsignedShort(const resip::Data& name, int defaultValue) +{ + int ret = defaultValue; + getConfigValue(name, ret); + return ret; +} + +bool +ConfigParse::getConfigValue(const resip::Data& name, std::vector<resip::Data> &value) +{ + Data lowerName(name); lowerName.lowercase(); + std::pair<ConfigValuesMap::iterator,ConfigValuesMap::iterator> valuesIts = mConfigValues.equal_range(lowerName); + bool found = false; + for (ConfigValuesMap::iterator it=valuesIts.first; it!=valuesIts.second; ++it) + { + found = true; + ParseBuffer pb(it->second); + Data item; + while(!it->second.empty() && !pb.eof()) + { + pb.skipWhitespace(); + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace, ","); // allow white space + pb.data(item, start); + value.push_back(item); + if(!pb.eof()) + { + pb.skipChar(); + } + } + } + + return found; +} + +void +ConfigParse::insertConfigValue(const resip::Data& name, const resip::Data& value) +{ + resip::Data lowerName(name); + lowerName.lowercase(); + mConfigValues.insert(ConfigValuesMap::value_type(lowerName, value)); +} + +resip::Data +ConfigParse::removePath(const resip::Data& fileAndPath) +{ + Data filenameOnly; + ParseBuffer pb(fileAndPath); + const char* anchor = pb.position(); + while(pb.skipToOneOf("/\\") && !pb.eof()) + { + pb.skipChar(); + anchor = pb.position(); + } + pb.data(filenameOnly, anchor); + return filenameOnly; +} + +EncodeStream& +operator<<(EncodeStream& strm, const ConfigParse& config) +{ + // Yes this is horribly inefficient - however it's only used when a user requests it + // and we want to see the items in a sorted list and hash_maps are not sorted. + std::multimap<Data, Data> sortedMap; + ConfigParse::ConfigValuesMap::const_iterator it = config.mConfigValues.begin(); + for(; it != config.mConfigValues.end(); it++) + { + sortedMap.insert(std::multimap<Data, Data>::value_type(it->first, it->second)); + } + std::multimap<Data, Data>::iterator it2 = sortedMap.begin(); + for(; it2 != sortedMap.end(); it2++) + { + strm << it2->first << " = " << it2->second << endl; + } + return strm; +} + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/ConfigParse.hxx b/src/libs/resiprocate/rutil/ConfigParse.hxx new file mode 100644 index 00000000..5e763387 --- /dev/null +++ b/src/libs/resiprocate/rutil/ConfigParse.hxx @@ -0,0 +1,123 @@ +#if !defined(ConfigParse_hxx) +#define ConfigParse_hxx + +#include <vector> +#include "rutil/BaseException.hxx" +#include "rutil/HashMap.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +class ConfigParse +{ +public: + class Exception : public BaseException + { + public: + Exception(const Data& msg, + const Data& file, + const int line) + : BaseException(msg, file, line) {} + protected: + virtual const char* name() const { return "ConfigParse::Exception"; } + }; + + ConfigParse(); + virtual ~ConfigParse(); + + // parses both command line and config file - using config file name from first command line parameter (if present) + // skipcount represents the number of command line options to skip before looking for config filename or name value pairs + virtual void parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount = 0); + virtual void parseCommandLine(int argc, char** argv, int skipCount = 0); + virtual void parseConfigFile(const resip::Data& filename); + + virtual void printHelpText(int argc, char **argv) = 0; + + bool getConfigValue(const resip::Data& name, resip::Data &value); + resip::Data getConfigData(const resip::Data& name, const resip::Data& defaultValue, bool useDefaultIfEmpty=false); + + bool getConfigValue(const resip::Data& name, bool &value); + bool getConfigBool(const resip::Data& name, bool defaultValue); + + bool getConfigValue(const resip::Data& name, unsigned long &value); + unsigned long getConfigUnsignedLong(const resip::Data& name, unsigned long defaultValue); + + bool getConfigValue(const resip::Data& name, int &value); + int getConfigInt(const resip::Data& name, int defaultValue); + + bool getConfigValue(const resip::Data& name, unsigned short &value); + unsigned short getConfigUnsignedShort(const resip::Data& name, int defaultValue); + + bool getConfigValue(const resip::Data& name, std::vector<resip::Data> &value); + +protected: + void insertConfigValue(const resip::Data& name, const resip::Data& value); + + typedef HashMultiMap<resip::Data, resip::Data> ConfigValuesMap; + ConfigValuesMap mConfigValues; + + resip::Data removePath(const resip::Data& fileAndPath); + + // Config filename from command line + resip::Data mCmdLineConfigFilename; + +private: + friend EncodeStream& operator<<(EncodeStream& strm, const ConfigParse& config); +}; + +EncodeStream& operator<<(EncodeStream& strm, const ConfigParse& config); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/CongestionManager.hxx b/src/libs/resiprocate/rutil/CongestionManager.hxx new file mode 100644 index 00000000..3e82bd65 --- /dev/null +++ b/src/libs/resiprocate/rutil/CongestionManager.hxx @@ -0,0 +1,150 @@ +#ifndef RESIP_CongestionManager_hxx +#define RESIP_CongestionManager_hxx + +#include "rutil/Data.hxx" + +namespace resip +{ +class FifoStatsInterface; + +/** + @brief Abstract base class that provides a basic congestion management + interface. + The primary job of subclasses is to implement + getRejectionBehavior() such that it will return + REJECTING_NEW_WORK or REJECTING_NON_ESSENTIAL when sufficient congestion is + detected in the fifo in question. logCurrentState() is used to provide a + logging statement for the current state of the queueing system. + + In order to write a CongestionManager that determines congestion state for + specific fifos based on the state of the whole system, you will need to + override getRejectionBehavior() to examine the fifo being passed to determine + what role it has in the system (this is done by calling + FifoStatsInterface::getDescription()), and assigning a role-number that + designates the role of this fifo (this means you only need to perform a + string comparison the first time getRejectionBehavior() is called for a + particular fifo). Here are the returns you will get from + FifoStatsInterface::getDescription() on a number of key fifos in the + resiprocate stack: + + - TransactionController::mStateMacFifo + - TlsTransport::mTxFifo + - TcpTransport::mTxFifo + - UdpTransport::mTxFifo + - DnsStub::mCommandFifo + + The following fifos don't see much use, and are therefore not that vital, but they do have descriptions. + + - SipStack::mTUFifo + - TuSelector::mShutdownFifo + + @ingroup message_passing +*/ +class CongestionManager +{ + + public: + + /** + Constructor + */ + CongestionManager(){}; + virtual ~CongestionManager(){}; + + typedef enum + { + NORMAL=0, /**< Not rejecting any work. */ + REJECTING_NEW_WORK=1, /**< Overloaded, should refuse new work. Should not + refuse continuation of old work. */ + REJECTING_NON_ESSENTIAL=2 /**< Rejecting all work that is non-essential to + the health of the system (ie, if dropping + something is liable to cause a leak, + instability, or state-bloat, don't drop it. + Otherwise, reject it.) */ + } RejectionBehavior; + + /** + Return the current rejection behavior for this fifo. + This is the primary functionality provided by this class. Implementors may + merely examine the current state of the fifo in question, or they may make + the decision based on the state of the entire system. + @param fifo The fifo in question. + @return The current desired RejectionBehavior for the fifo. + */ + virtual RejectionBehavior getRejectionBehavior(const FifoStatsInterface *fifo) const=0; + + /** + Registers a fifo with the congestion manager. May be a no-op, or may + assign a role number to the fifo. + */ + virtual void registerFifo(resip::FifoStatsInterface* fifo)=0; + + /** + Unregisters a fifo with the congestion manager. + */ + virtual void unregisterFifo(resip::FifoStatsInterface* fifo)=0; + + /** + Log the current state of all monitored fifos. + */ + virtual void logCurrentState() const=0; + + /** + Get the current state of all monitored fifos.to a stream + */ + virtual EncodeStream& encodeCurrentState(EncodeStream& strm) const=0; + +}; + + +} // namespace resip + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/ConsumerFifoBuffer.hxx b/src/libs/resiprocate/rutil/ConsumerFifoBuffer.hxx new file mode 100644 index 00000000..483b481b --- /dev/null +++ b/src/libs/resiprocate/rutil/ConsumerFifoBuffer.hxx @@ -0,0 +1,108 @@ +#ifndef ConsumerFifoBuffer_Include_Guard +#define ConsumerFifoBuffer_Include_Guard + +#include "rutil/Fifo.hxx" + +namespace resip +{ +template<typename T> +class ConsumerFifoBuffer +{ + public: + ConsumerFifoBuffer(Fifo<T>& fifo, + unsigned int bufferSize=8) : + mFifo(fifo), + mBufferSize(bufferSize) + {} + + ~ConsumerFifoBuffer() + {} + + T* getNext(int ms=0) + { + if(mBuffer.empty()) + { + mFifo.getMultiple(ms, mBuffer, mBufferSize); + } + + if(mBuffer.empty()) + { + return 0; + } + + T* next(mBuffer.front()); + mBuffer.pop_front(); + return next; + } + + bool messageAvailable() const + { + if(mBuffer.empty()) + { + return mFifo.messageAvailable(); + } + return true; + } + + unsigned int size() const + { + return mBuffer.size() + mFifo.size(); + } + + private: + Fifo<T>& mFifo; + typename Fifo<T>::Messages mBuffer; + unsigned int mBufferSize; +}; +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/CountStream.cxx b/src/libs/resiprocate/rutil/CountStream.cxx new file mode 100644 index 00000000..febc8e30 --- /dev/null +++ b/src/libs/resiprocate/rutil/CountStream.cxx @@ -0,0 +1,137 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rutil/CountStream.hxx" + +// Remove warning about 'this' use in initiator list - pointer is only stored +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) // using this in base member initializer list +#endif + +using namespace resip; + +#ifdef RESIP_USE_STL_STREAMS +static const int BuffSize(2048); +// singleton buffer -- not really used +static char Buffer[BuffSize]; +#endif + +CountBuffer::CountBuffer(size_t& count) + : mCount(count) +{ + mCount = 0; +#ifdef RESIP_USE_STL_STREAMS + setp(Buffer, Buffer+BuffSize); +#endif +} + +CountBuffer::~CountBuffer() +{} + +#ifdef RESIP_USE_STL_STREAMS +int +CountBuffer::sync() +{ + size_t len = pptr() - pbase(); + if (len > 0) + { + mCount += len; + // reset the put buffer + setp(Buffer, Buffer + BuffSize); + } + return 0; +} + +int +CountBuffer::overflow(int c) +{ + sync(); + if (c != -1) + { + pbump(1); + return c; + } + return 0; +} +#else +UInt64 CountBuffer::tellpbuf(void) +{ + return mCount; +} + + +size_t CountBuffer::writebuf(const char *str, size_t count) +{ + mCount += count; + return count; +} +size_t CountBuffer::putbuf(char ch) +{ + mCount++; + + return 1; +} +#endif + +CountStream::CountStream(size_t& count) + : CountBuffer(count), EncodeStream(this) +{ +} + +CountStream::~CountStream() +{ +#ifdef RESIP_USE_STL_STREAMS + flush(); +#endif +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/CountStream.hxx b/src/libs/resiprocate/rutil/CountStream.hxx new file mode 100644 index 00000000..f3689dfc --- /dev/null +++ b/src/libs/resiprocate/rutil/CountStream.hxx @@ -0,0 +1,129 @@ +#if !defined(RESIP_COUNTSTREAM_HXX) +#define RESIP_COUNTSTREAM_HXX + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <iostream> +#include "rutil/Data.hxx" + +namespace resip +{ + +/** + @brief Implementation of std::streambuf used to back CountStream. + @see CountStream + */ +class CountBuffer : +#ifdef RESIP_USE_STL_STREAMS + public std::streambuf +#else + public ResipStreamBuf +#endif +{ + public: + /** Constructs a CountBuffer with the reference to the size_t where the + count should be written after flush is called on the stream. + */ + CountBuffer(size_t& count); + virtual ~CountBuffer(); + + protected: +#ifdef RESIP_USE_STL_STREAMS + virtual int sync(); + virtual int overflow(int c = -1); +#else + virtual size_t writebuf(const char *s, size_t count); + virtual size_t putbuf(char ch); + virtual void flushbuf(void){} + virtual size_t readbuf(char *buf, size_t count) + { + assert(0); + return 0; + } + + virtual UInt64 tellpbuf(void); +#endif + + private: + size_t& mCount; +}; + +/** + @brief Used to count the amount of data written to a stream. + + The actual data written to the stream is not accumulated anywhere. It + follows the general pattern of DataStream where the data is accumulated into + the reference passed to the constructor. The data is valid after + CountStream's destructor is called (ie, flush occurs on destruction). +*/ +class CountStream : private CountBuffer, public EncodeStream +{ + public: + /** Constructs a CountStream with a reference to where the count of bytes + written to the stream should be stored. + @param count A reference to the size_t where the number of bytes written + to the stream after the stream goes out of scope. + */ + CountStream(size_t& count); + /** Calls flush on itself to force the update to the count reference + passed into the constructor. + */ + ~CountStream(); + +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Data.cxx b/src/libs/resiprocate/rutil/Data.cxx new file mode 100644 index 00000000..1c308eb1 --- /dev/null +++ b/src/libs/resiprocate/rutil/Data.cxx @@ -0,0 +1,2487 @@ +#include <algorithm> +#include <cassert> +#include <ctype.h> +#include <math.h> +#include <limits.h> + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "rutil/Data.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/vmd5.hxx" +#include "rutil/Coders.hxx" +#include "rutil/WinLeakCheck.hxx" + +#ifdef WIN32 +#include "Winsock2.h" +#endif + +using namespace resip; +using namespace std; + +const Data Data::Empty("", 0); +const Data::size_type Data::npos = UINT_MAX; + +Data::PreallocateType::PreallocateType(int) +{} + +const Data::PreallocateType Data::Preallocate(0); + +const bool DataHelper::isCharHex[256] = +{ +// 0 1 2 3 4 5 6 7 8 9 a b c d e f + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, //0 + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, //1 + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, //2 + true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, //3 + false, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, //4 + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, //5 + false, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, //6 + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, //8 + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, //9 + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, //a + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, //b + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, //c + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, //d + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, //e + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false //f +}; + +//must be lowercase for MD5 +static const char hexmap[] = "0123456789abcdef"; + +int +hexpair2int(char high, char low) +{ + int val; + + switch(high) + { + case '0': + val = 0x00; + break; + case '1': + val = 0x10; + break; + case '2': + val = 0x20; + break; + case '3': + val = 0x30; + break; + case '4': + val = 0x40; + break; + case '5': + val = 0x50; + break; + case '6': + val = 0x60; + break; + case '7': + val = 0x70; + break; + case '8': + val = 0x80; + break; + case '9': + val = 0x90; + break; + case 'A': + case 'a': + val = 0xA0; + break; + case 'B': + case 'b': + val = 0xB0; + break; + case 'C': + case 'c': + val = 0xC0; + break; + case 'D': + case 'd': + val = 0xD0; + break; + case 'E': + case 'e': + val = 0xE0; + break; + case 'F': + case 'f': + val = 0xF0; + break; + default: + return '?'; + break; + } + + switch(low) + { + case '0': + if (!val) + { + return '?'; + } + break; + case '1': + val += 0x01; + break; + case '2': + val += 0x02; + break; + case '3': + val += 0x03; + break; + case '4': + val += 0x04; + break; + case '5': + val += 0x05; + break; + case '6': + val += 0x06; + break; + case '7': + val += 0x07; + break; + case '8': + val += 0x08; + break; + case '9': + val += 0x09; + break; + case 'A': + case 'a': + val += 0x0A; + break; + case 'B': + case 'b': + val += 0x0B; + break; + case 'C': + case 'c': + val += 0x0C; + break; + case 'D': + case 'd': + val += 0x0D; + break; + case 'E': + case 'e': + val += 0x0E; + break; + case 'F': + case 'f': + val += 0x0F; + break; + default: + return '?'; + break; + } + return val; +} + +bool +Data::init(DataLocalSize<RESIP_DATA_LOCAL_SIZE> arg) +{ + return true; +} + +Data::Data(size_type capacity, + const Data::PreallocateType&) + : mBuf(capacity > LocalAlloc + ? new char[capacity + 1] + : mPreBuffer), + mSize(0), + mCapacity(capacity > LocalAlloc + ? capacity + : LocalAlloc), + mShareEnum(capacity > LocalAlloc ? Take : Borrow) +{ + assert( capacity >= 0 ); + mBuf[mSize] = 0; +} + +#ifdef DEPRECATED_PREALLOC +// pre-allocate capacity +Data::Data(size_type capacity, bool) + : mBuf(capacity > LocalAlloc + ? new char[capacity + 1] + : mPreBuffer), + mSize(0), + mCapacity(capacity > LocalAlloc + ? capacity + : LocalAlloc), + mShareEnum(capacity > LocalAlloc ? Take : Borrow) +{ + assert( capacity >= 0 ); + mBuf[mSize] = 0; +} +#endif + +Data::Data(const char* str, size_type length) + : mBuf(length > LocalAlloc + ? new char[length + 1] + : mPreBuffer), + mSize(length), + mCapacity(mSize > LocalAlloc + ? mSize + : LocalAlloc), + mShareEnum(mSize > LocalAlloc ? Take : Borrow) +{ + if (mSize > 0) + { + assert(str); + memcpy(mBuf, str, mSize); + } + mBuf[mSize]=0; +} + +Data::Data(const unsigned char* str, size_type length) + : mBuf(length > LocalAlloc + ? new char[length + 1] + : mPreBuffer), + mSize(length), + mCapacity(mSize > LocalAlloc + ? mSize + : LocalAlloc), + mShareEnum(mSize > LocalAlloc ? Take : Borrow) +{ + if (mSize > 0) + { + assert(str); + memcpy(mBuf, str, mSize); + } + mBuf[mSize]=0; +} + +// share memory KNOWN to be in a surrounding scope +// wears off on, c_str, operator=, operator+=, non-const +// operator[], append, reserve +Data::Data(const char* str, size_type length, bool) + : mBuf(const_cast<char*>(str)), + mSize(length), + mCapacity(mSize), + mShareEnum(Share) +{ + assert(str); +} + +Data::Data(ShareEnum se, const char* buffer, size_type length) + : mBuf(const_cast<char*>(buffer)), + mSize(length), + mCapacity(mSize), + mShareEnum(se) +{ + assert(buffer); +} + +Data::Data(ShareEnum se, const char* buffer) + : mBuf(const_cast<char*>(buffer)), + mSize(strlen(buffer)), + mCapacity(mSize), + mShareEnum(se) +{ + assert(buffer); +} + +Data::Data(ShareEnum se, const Data& staticData) + : mBuf(staticData.mBuf), + mSize(staticData.mSize), + mCapacity(mSize), + mShareEnum(Share) +{ + // !dlb! maybe: + // if you are trying to use Take, but make sure that you unset the mShareEnum on + // the staticData + assert(se == Share); // makes no sense to call this with 'Take'. +} +//============================================================================= + +Data::Data(const char* str) // We need mSize to init mBuf; do in body + : mSize(str ? strlen(str) : 0), + mCapacity(mSize > LocalAlloc + ? mSize + : LocalAlloc), + mShareEnum(mSize > LocalAlloc ? Take : Borrow) +{ + if(mSize > LocalAlloc) + { + mBuf = new char[mSize+1]; + } + else + { + mBuf = mPreBuffer; + } + + if (str) + { + memcpy(mBuf, str, mSize+1); + } + else + { + mBuf[mSize] = 0; + } +} + +Data::Data(const string& str) + : mBuf(str.size() > LocalAlloc + ? new char[str.size() + 1] + : mPreBuffer), + mSize(str.size()), + mCapacity(mSize > LocalAlloc + ? mSize + : LocalAlloc), + mShareEnum(mSize > LocalAlloc ? Take : Borrow) +{ + memcpy(mBuf, str.c_str(), mSize + 1); +} + +Data::Data(const Data& data) + : mBuf(data.mSize > LocalAlloc + ? new char[data.mSize + 1] + : mPreBuffer), + mSize(data.mSize), + mCapacity(mSize > LocalAlloc + ? mSize + : LocalAlloc), + mShareEnum(mSize > LocalAlloc ? Take : Borrow) +{ + if (mSize) + { + memcpy(mBuf, data.mBuf, mSize); + } + mBuf[mSize] = 0; +} + +#ifdef RESIP_HAS_RVALUE_REFS +Data::Data(Data &&data) + : mBuf(mPreBuffer),mSize(0),mCapacity(LocalAlloc),mShareEnum(Borrow) +{ + *this = std::move(data); +} +#endif + +// -2147483646 +static const int IntMaxSize = 12; + +Data::Data(int val) + : mBuf(IntMaxSize > LocalAlloc + ? new char[IntMaxSize + 1] + : mPreBuffer), + mSize(0), + mCapacity(IntMaxSize > LocalAlloc + ? IntMaxSize + : LocalAlloc), + mShareEnum(IntMaxSize > LocalAlloc ? Take : Borrow) +{ + if (val == 0) + { + mBuf[0] = '0'; + mBuf[1] = 0; + mSize = 1; + return; + } + + bool neg = false; + + int value = val; + if (value < 0) + { + value = -value; + neg = true; + } + + int c = 0; + int v = value; + while (v /= 10) + { + ++c; + } + + if (neg) + { + ++c; + } + + mSize = c+1; + mBuf[c+1] = 0; + + v = value; + while (v) + { + mBuf[c--] = '0' + v%10; + v /= 10; + } + + if (neg) + { + mBuf[0] = '-'; + } +} + +static const int MaxLongSize = (sizeof(unsigned long)/sizeof(int))*IntMaxSize; +Data::Data(unsigned long value) + : mBuf(MaxLongSize > LocalAlloc + ? new char[MaxLongSize + 1] + : mPreBuffer), + mSize(0), + mCapacity(MaxLongSize > LocalAlloc + ? MaxLongSize + : LocalAlloc), + mShareEnum(MaxLongSize > LocalAlloc ? Take : Borrow) +{ + if (value == 0) + { + mBuf[0] = '0'; + mBuf[1] = 0; + mSize = 1; + return; + } + + int c = 0; + unsigned long v = value; + while (v /= 10) + { + ++c; + } + + mSize = c+1; + mBuf[c+1] = 0; + + v = value; + while (v) + { + unsigned int digit = v%10; + unsigned char d = (char)digit; + mBuf[c--] = '0' + d; + v /= 10; + } +} + +#ifndef RESIP_FIXED_POINT +static const int DoubleMaxSize = MaxLongSize + Data::MaxDigitPrecision; +Data::Data(double value, + Data::DoubleDigitPrecision precision) + : mBuf(DoubleMaxSize + precision > LocalAlloc + ? new char[DoubleMaxSize + precision + 1] + : mPreBuffer), + mSize(0), + mCapacity(DoubleMaxSize + precision > LocalAlloc + ? DoubleMaxSize + precision + : LocalAlloc), + mShareEnum(DoubleMaxSize + precision > LocalAlloc ? Take : Borrow) +{ + assert(precision >= 0); + assert(precision < MaxDigitPrecision); + + double v = value; + bool neg = (value < 0.0); + + if (neg) + { + v = -v; + } + + Data m((unsigned long)v); + + // remainder + v = v - floor(v); + + int p = precision; + while (p--) + { + v *= 10; + } + + int dec = (int)floor(v+0.5); + Data d(precision, Data::Preallocate); + + if (dec == 0) + { + d = "0"; + } + else + { + d.mBuf[precision] = 0; + p = precision; + // neglect trailing zeros + bool significant = false; + while (p--) + { + if (dec % 10 || significant) + { + significant = true; + ++d.mSize; + d.mBuf[p] = '0' + (dec % 10); + } + else + { + d.mBuf[p] = 0; + } + + dec /= 10; + } + } + + if (neg) + { + mBuf[0] = '-'; + memcpy(mBuf+1, m.mBuf, m.size()); + mBuf[1+m.size()] = '.'; + memcpy(mBuf+1+m.size()+1, d.mBuf, d.size()+1); + mSize = m.size() + d.size() + 2; + } + else + { + if (mCapacity < m.size() + d.size() + 1) + { + resize(m.size() + d.size() + 1, false); + } + memcpy(mBuf, m.mBuf, m.size()); + mBuf[m.size()] = '.'; + memcpy(mBuf+m.size()+1, d.mBuf, d.size()+1); + mSize = m.size() + d.size() + 1; + } + + assert(mBuf[mSize] == 0); +} +#endif + +Data::Data(unsigned int value) + : mBuf(IntMaxSize > LocalAlloc + ? new char[IntMaxSize + 1] + : mPreBuffer), + mSize(0), + mCapacity(IntMaxSize > LocalAlloc + ? IntMaxSize + : LocalAlloc), + mShareEnum(IntMaxSize > LocalAlloc ? Take : Borrow) +{ + if (value == 0) + { + mBuf[0] = '0'; + mBuf[1] = 0; + mSize = 1; + return; + } + + int c = 0; + unsigned long v = value; + while (v /= 10) + { + ++c; + } + + mSize = c+1; + mBuf[c+1] = 0; + + v = value; + while (v) + { + unsigned int digit = v%10; + unsigned char d = (char)digit; + mBuf[c--] = '0' + d; + v /= 10; + } +} + +// 18446744073709551615 +static const int UInt64MaxSize = 20; + +Data::Data(UInt64 value) + : mBuf(UInt64MaxSize > LocalAlloc + ? new char[UInt64MaxSize + 1] + : mPreBuffer), + mSize(0), + mCapacity(UInt64MaxSize > LocalAlloc + ? UInt64MaxSize + : LocalAlloc), + mShareEnum(UInt64MaxSize > LocalAlloc ? Take : Borrow) +{ + if (value == 0) + { + mBuf[0] = '0'; + mBuf[1] = 0; + mSize = 1; + return; + } + + int c = 0; + UInt64 v = value; + while (v /= 10) + { + ++c; + } + + mSize = c+1; + mBuf[c+1] = 0; + + v = value; + while (v) + { + UInt64 digit = v%10; + unsigned char d = (char)digit; + mBuf[c--] = '0' + d; + v /= 10; + } +} + +static const int CharMaxSize = 1; +Data::Data(char c) + : mBuf(CharMaxSize > LocalAlloc + ? new char[CharMaxSize + 1] + : mPreBuffer), + mSize(1), + mCapacity(CharMaxSize > LocalAlloc + ? CharMaxSize + : LocalAlloc), + mShareEnum(CharMaxSize > LocalAlloc ? Take : Borrow) +{ + mBuf[0] = c; + mBuf[1] = 0; +} + +Data::Data(bool value) + : mBuf(value ? const_cast<char*>("true") : const_cast<char*>("false")), + mSize(value ? 4 : 5), + mCapacity(value ? 4 : 5), + mShareEnum(Borrow) +{} + +Data& +Data::setBuf(ShareEnum se, const char* buffer, size_type length) +{ + assert(buffer); + if (mShareEnum == Take) + { + delete[] mBuf; + } + mBuf = const_cast<char*>(buffer); + mCapacity = mSize = length; + mShareEnum = se; + return *this; +} + +Data& +Data::takeBuf(Data& other) +{ + if ( &other == this ) + return *this; + + if (mShareEnum == Data::Take) + delete[] mBuf; + + if ( other.mBuf == other.mPreBuffer ) + { + // plus one picks up the terminating safety NULL + memcpy( mPreBuffer, other.mPreBuffer, other.mSize+1); + mBuf = mPreBuffer; + } + else + { + mBuf = other.mBuf; + other.mBuf = other.mPreBuffer; + } + mSize = other.mSize; + mCapacity = other.mCapacity; + mShareEnum = other.mShareEnum; + + // reset {other} to same state as the default Data() constructor + // note that other.mBuf is set above + other.mSize = 0; + other.mCapacity = LocalAlloc; + other.mShareEnum = Data::Borrow; + other.mPreBuffer[0] = 0; + + return *this; +} + +Data& +Data::copy(const char *buf, size_type length) +{ + if (mShareEnum == Data::Share || mCapacity < length+1) + { + // will alloc length+1, so the term NULL below is safe + resize(length, false); + } + // {buf} might be part of ourselves already, in which case {length} + // is smaller than our capacity, so resize above won't happen, so + // just memmove (not memcpy) and everything good + mSize = length; + if (mSize>0) + { + memmove(mBuf, buf, mSize); + } + // DONT do term NULL until after copy, because may be shifting contents + // down and don't want to put NULL in middle of it + mBuf[mSize] = 0; + return *this; +} + +char* +Data::getBuf(size_type length) +{ + if (mShareEnum == Data::Share || mCapacity < length) + { + // will alloc length+1, so the term NULL below is safe + resize(length, false); + mBuf[length] = 0; + } + else if ( mCapacity != length ) + { + mBuf[length] = 0; + } + // even if we don't NULL-term it, it may have NULL term from before. + // But if external buffer (taken or borrow'd) then don't know if it + // has a NULL or not. + mSize = length; + return mBuf; +} + +bool +resip::operator==(const Data& lhs, const Data& rhs) +{ + if (lhs.mSize != rhs.mSize) + { + return false; + } + return memcmp(lhs.mBuf, rhs.mBuf, lhs.mSize) == 0; +} + +bool +resip::operator==(const Data& lhs, const char* rhs) +{ + assert(rhs); // .dlb. not consistent with constructor + if (memcmp(lhs.mBuf, rhs, lhs.mSize) != 0) + { + return false; + } + else + { + // make sure the string terminates at size + return (rhs[lhs.mSize] == 0); + } +} + +bool +resip::operator<(const Data& lhs, const Data& rhs) +{ + int res = memcmp(lhs.mBuf, rhs.mBuf, resipMin(lhs.mSize, rhs.mSize)); + + if (res < 0) + { + return true; + } + else if (res > 0) + { + return false; + } + else + { + return (lhs.mSize < rhs.mSize); + } +} + +bool +resip::operator<(const Data& lhs, const char* rhs) +{ + assert(rhs); + Data::size_type l = strlen(rhs); + int res = memcmp(lhs.mBuf, rhs, resipMin(lhs.mSize, l)); + + if (res < 0) + { + return true; + } + else if (res > 0) + { + return false; + } + else + { + return (lhs.mSize < l); + } +} + +bool +resip::operator<(const char* lhs, const Data& rhs) +{ + assert(lhs); + Data::size_type l = strlen(lhs); + int res = memcmp(lhs, rhs.mBuf, resipMin(l, rhs.mSize)); + + if (res < 0) + { + return true; + } + else if (res > 0) + { + return false; + } + else + { + return (l < rhs.mSize); + } +} + + + +#if 0 +// Moved to inline header as special case of copy() +Data& +Data::operator=(const Data& data) +{ + assert(mBuf); + + if (&data != this) + { + if (mShareEnum == Share) + { + resize(data.mSize, false); + } + else + { + if (data.mSize > mCapacity) + { + resize(data.mSize, false); + } + } + + mSize = data.mSize; + // could overlap! + if (mSize > 0) + { + memmove(mBuf, data.mBuf, mSize); + } + mBuf[mSize] = 0; + } + return *this; +} +#endif + +#ifdef RESIP_HAS_RVALUE_REFS +Data& Data::operator=(Data &&data) +{ + if (&data != this) + { + if (data.mPreBuffer != data.mBuf) + { + //data is not using the local buffer, take ownership of data. + mBuf = data.mBuf; + mCapacity = data.mCapacity; + mShareEnum = data.mShareEnum; + mSize = data.mSize; + data.mShareEnum = Borrow; //don't delete the transferred buffer in data's destructor. + } + else + { + *this = data; //lvalue assignment operator will be called for named rvalue. + } + } + + return *this; +} +#endif + +Data::size_type +Data::truncate(size_type len) +{ + if (len < mSize) + { + (*this)[len] = 0; + mSize = len; + } + + return mSize; +} + +Data& +Data::truncate2(size_type len) +{ + if (len < mSize) + { + // NOTE: Do not write terminating NULL, to avoid un-doing Share + mSize = len; + } + return *this; +} + +Data +Data::operator+(const Data& data) const +{ + Data tmp(mSize + (int)data.mSize, Data::Preallocate); + tmp.mSize = mSize + data.mSize; + tmp.mCapacity = tmp.mSize; + memcpy(tmp.mBuf, mBuf, mSize); + memcpy(tmp.mBuf + mSize, data.mBuf, data.mSize); + tmp.mBuf[tmp.mSize] = 0; + + return tmp; +} + +Data& +Data::operator^=(const Data& rhs) +{ + if (mCapacity < rhs.mSize) + { + resize(rhs.mSize, true); + } + if (mSize < rhs.mSize) + { + memset(mBuf+mSize, 0, mCapacity - mSize); + } + + char* c1 = mBuf; + char* c2 = rhs.mBuf; + char* end = c2 + rhs.mSize; + while (c2 != end) + { + *c1++ ^= *c2++; + } + mSize = resipMax(mSize, rhs.mSize); + + return *this; +} + +char& +Data::at(size_type p) +{ + if (p >= mCapacity) + { + resize(p+1, true); + } + else + { + own(); + if (p > mSize) + { + mSize = p + 1; + mBuf[mSize] = 0; + } + } + return mBuf[p]; +} + +#if 0 +// Moved to inline header as special case of copy() +Data& +Data::operator=(const char* str) +{ + assert(str); + size_type l = strlen(str); + + if (mShareEnum == Share) + { + resize(l, false); + } + else + { + if (l > mCapacity) + { + resize(l, false); + } + } + + mSize = l; + // could conceivably overlap + memmove(mBuf, str, mSize+1); + + return *this; +} +#endif + +Data +Data::operator+(const char* str) const +{ + assert(str); + size_t l = strlen(str); + Data tmp(mSize + l, Data::Preallocate); + tmp.mSize = mSize + l; + tmp.mCapacity = tmp.mSize; + memcpy(tmp.mBuf, mBuf, mSize); + memcpy(tmp.mBuf + mSize, str, l+1); + + return tmp; +} + +void +Data::reserve(size_type len) +{ + if (len > mCapacity) + { + resize(len, true); + } +} + +Data& +Data::append(const char* str, size_type len) +{ + assert(str); + if (mCapacity <= mSize + len) // append null terminates, thus the equality + { + // .dlb. pad for future growth? + resize(((mSize + len +16)*3)/2, true); + } + else + { + if (mShareEnum == Share) + { + resize(mSize + len, true); + } + } + + // could conceivably overlap + memmove(mBuf + mSize, str, len); + mSize += len; + mBuf[mSize] = 0; + + return *this; +} + + +Data +Data::operator+(char c) const +{ + Data tmp(mSize + 1, Data::Preallocate); + tmp.mSize = mSize + 1; + tmp.mCapacity = tmp.mSize; + memcpy(tmp.mBuf, mBuf, mSize); + tmp.mBuf[mSize] = c; + tmp.mBuf[mSize+1] = 0; + + return tmp; +} + +const char* +Data::c_str() const +{ + if (mShareEnum == Data::Share || mSize == mCapacity) + { + const_cast<Data*>(this)->resize(mSize+1,true); + } + // mostly is zero terminated, but not by DataStream + mBuf[mSize] = 0; + return mBuf; +} + +void +Data::own() const +{ + if (mShareEnum == Share) + { + const_cast<Data*>(this)->resize(mSize, true); + } +} + +// generate additional capacity +void +Data::resize(size_type newCapacity, + bool copy) +{ + assert(newCapacity >= mCapacity || mShareEnum == Data::Share); + + char *oldBuf = mBuf; + bool needToDelete=(mShareEnum==Take); + + if(newCapacity > LocalAlloc) + { + mBuf = new char[newCapacity+1]; + mShareEnum = Take; + } + else + { + mBuf = mPreBuffer; + mShareEnum = Borrow; + } + + if (copy) + { + memcpy(mBuf, oldBuf, mSize); + mBuf[mSize] = 0; + } + + if (needToDelete) + { + delete[] oldBuf; + } + + mCapacity = newCapacity; +} + +Data +Data::md5(EncodingType type) const +{ + MD5Context context; + MD5Init(&context); + MD5Update(&context, reinterpret_cast < unsigned const char* > (mBuf), (unsigned int)mSize); + + unsigned char digestBuf[16]; + MD5Final(digestBuf, &context); + Data digest(digestBuf,16); + + switch(type) + { + case BINARY: + return digest; + case BASE64: + return digest.base64encode(true); + case HEX: + default: + return digest.hex(); + } + assert(0); + return digest.hex(); +} + +Data +Data::escaped() const +{ + Data ret((int)((size()*11)/10), Data::Preallocate); + + const char* p = data(); + for (size_type i=0; i < size(); ++i) + { + unsigned char c = *p++; + + if ( c == 0x0d ) + { + if ( i+1 < size() ) + { + if ( *p == 0x0a ) + { + // found a CRLF sequence + ret += c; + c = *p++; i++; + ret += c; + continue; + } + } + } + + if ( !isprint(c) ) + { + ret +='%'; + + int hi = (c & 0xF0)>>4; + int low = (c & 0x0F); + + ret += hexmap[hi]; + ret += hexmap[low]; + } + else + { + ret += c; + } + } + + return ret; +} + +Data +Data::charEncoded() const +{ + Data ret((int)((size()*11)/10), Data::Preallocate); + + const char* p = data(); + for (size_type i=0; i < size(); ++i) + { + unsigned char c = *p++; + + if ( c == 0x0d ) + { + if ( i+1 < size() ) + { + if ( *p == 0x0a ) + { + // found a CRLF sequence + ret += c; + c = *p++; i++; + ret += c; + continue; + } + } + } + + if ( !isprint(c) || + // rfc 3261 reserved + mark + space + tab + strchr(" \";/?:@&=+%$,\t-_.!~*'()", c)) + { + ret +='%'; + + int hi = (c & 0xF0)>>4; + int low = (c & 0x0F); + + ret += hexmap[hi]; + ret += hexmap[low]; + } + else + { + ret += c; + } + } + + return ret; +} + +Data +Data::charUnencoded() const +{ + Data ret(size(), Data::Preallocate); + + const char* p = data(); + for (size_type i = 0; i < size(); ++i) + { + unsigned char c = *p++; + if (c == '%') + { + if ( i+2 < size()) + { + const char* high = strchr(hexmap, tolower(*p++)); + const char* low = strchr(hexmap, tolower(*p++)); + + // !rwm! changed from high==0 || low==0 + if (high == 0 && low == 0) + { + assert(0); + // ugh + return ret; + } + + int highInt = int(high - hexmap); + int lowInt = int(low - hexmap); + ret += char(highInt<<4 | lowInt); + i += 2; + } + else + { + break; + } + } + else + { + ret += c; + } + } + return ret; +} + +Data +Data::urlEncoded() const +{ + Data buffer; + DataStream strm(buffer); + urlEncode(strm); + strm.flush(); + return buffer; +} + +Data +Data::urlDecoded() const +{ + Data buffer; + DataStream strm(buffer); + urlDecode(strm); + strm.flush(); + return buffer; +} + +EncodeStream& +Data::urlDecode(EncodeStream& s) const +{ + unsigned int i = 0; + for (const char* p = data(); p != data()+size(); ++p, ++i) + { + unsigned char c = *p; + if (c == '%') + { + if (i+2 < size()) + { + s << (char) hexpair2int( *(p+1), *(p+2)); + p += 2; + } + else + { + break; + } + } + else if (c == '+') + { + s << ' '; + } + else + { + s << c; + } + } + return s; +} + +bool urlNonEncodedChars[256] = {false}; +bool +urlNonEncodedCharsInitFn() +{ + // query part of HTTP URL can be a pchar, slash, or question + // pchar is unreserved, subdelims, colon, at-sign + + for (int i = 0; i < 256; ++i) + { + unsigned char c(i); + urlNonEncodedChars[c] = (isalpha(c) || // unreserved + isdigit(c) || // unreserved + c == '-' || // these first 4 are unreserved + c == '_' || + c == '.' || + c == '~' || + c == '!' || // these are subdelims (allowed in pchars) + c == '$' || +// c == '&' || // while these are allowed subdelims, this is an error +// c == '+' || // I believe this is an error as well. + c == '\'' || + c == '(' || + c == ')' || + c == '*' || + c == ',' || + c == ';' || + c == '=' || + c == ':' || // next two explicitly allowed in pchar + c == '@' || + c == '/' || // next two explicitly allowed in query in addition to pchar + c == '?'); + } + + return false; +} + +static bool dummy = urlNonEncodedCharsInitFn(); + +// e.g. http://www.blooberry.com/indexdot/html/topics/urlencoding.htm +EncodeStream& +Data::urlEncode(EncodeStream& s) const +{ + for (const char* p = data(); p != data() + size(); ++p) + { + unsigned char c = *p; + + // pchar, slash, questionmark + // pchar = unreserved, sub-delims, colon, at-sign + // unreserved = alphanum, hyphen, underscore, period, tilde + // subdelims = bang (!), dollar, ampersand (oops!), plus, single-quote, lparen, rparen, asterisk, comma, semicolon, equal + //if (isalpha(c) || isdigit(c) || strchr("-_.~!$+'()*,;=:@/?", c)) // + // strchr is inefficient and wrong + if (urlNonEncodedChars[c]) + { + s << c; + } + else + { + if (c == 0x20) + { + s << '+'; + } + else + { + s << '%' << (hexmap[(c & 0xF0)>>4]) << (hexmap[(c & 0x0F)]); + } + } + } + + return s; +} + +Data +Data::xmlCharDataEncode() const +{ + Data buffer; + DataStream strm(buffer); + xmlCharDataEncode(strm); + strm.flush(); + return buffer; +} + +Data +Data::xmlCharDataDecode() const +{ + Data buffer; + DataStream strm(buffer); + xmlCharDataDecode(strm); + strm.flush(); + return buffer; +} + +// http://www.w3.org/TR/REC-xml/#syntax +EncodeStream& +Data::xmlCharDataEncode(EncodeStream& s) const +{ + for (const char* p = data(); p != data() + size(); ++p) + { + unsigned char c = *p; + + switch(c) + { + case '&': + s << "&amp;"; + break; + case '<': + s << "&lt;"; + break; + case '>': + s << "&gt;"; + break; + case '\'': + s << "&apos;"; + break; + case '\"': + s << "&quot;"; + break; + default: + s << c; + } + } + + return s; +} + +EncodeStream& +Data::xmlCharDataDecode(EncodeStream& s) const +{ + unsigned int i = 0; + for (const char* p = data(); p != data()+size(); ++p, ++i) + { + unsigned char c = *p; + if (c == '&') + { + // look for amp; + if(i+4 < size() && + *(p+1) == 'a' && *(p+2) == 'm' && *(p+3) == 'p' && *(p+4) == ';') + { + s << '&'; + p += 4; + } + // look for lt; + else if(i+3 < size() && + *(p+1) == 'l' && *(p+2) == 't' && *(p+3) == ';') + { + s << '<'; + p += 3; + } + // look for gt; + else if(i+3 < size() && + *(p+1) == 'g' && *(p+2) == 't' && *(p+3) == ';') + { + s << '>'; + p += 3; + } + // look for apos; + else if(i+5 < size() && + *(p+1) == 'a' && *(p+2) == 'p' && *(p+3) == 'o' && *(p+4) == 's' && *(p+5) == ';') + { + s << '\''; + p += 5; + } + // look for quot; + else if(i+5 < size() && + *(p+1) == 'q' && *(p+2) == 'u' && *(p+3) == 'o' && *(p+4) == 't' && *(p+5) == ';') + { + s << '\"'; + p += 5; + } + else // if no conversion found - just leave characters in data + { + s << c; + } + } + else + { + s << c; + } + } + return s; +} + +Data +Data::trunc(size_type s) const +{ + if (size() <= s) + { + return *this; + } + else + { + return Data(data(), s) + ".."; + } +} + +Data +Data::hex() const +{ + Data ret( 2*mSize, Data::Preallocate); + + const char* p = mBuf; + char* r = ret.mBuf; + for (size_type i=0; i < mSize; ++i) + { + unsigned char temp = *p++; + + int hi = (temp & 0xf0)>>4; + int low = (temp & 0xf); + + *r++ = hexmap[hi]; + *r++ = hexmap[low]; + } + *r = 0; + ret.mSize = 2*mSize; + return ret; +} + +Data& +Data::lowercase() +{ + own(); + char* p = mBuf; + for (size_type i=0; i < mSize; ++i) + { + *p = tolower(*p); + ++p; + } + return *this; +} + +Data& +Data::uppercase() +{ + own(); + char* p = mBuf; + for (size_type i=0; i < mSize; ++i) + { + *p = toupper(*p); + ++p; + } + return *this; +} + +Data& +Data::schemeLowercase() +{ + own(); + char* p = mBuf; + for (size_type i=0; i < mSize; ++i) + { + *p |= ' '; + ++p; + } + return *this; +} + +#if 0 +// in-lined into header as special case of truncate2() +Data& +Data::clear() +{ + mSize = 0; + return *this; +} +#endif + +int +Data::convertInt() const +{ + int val = 0; + char* p = mBuf; + const char* const end = mBuf + mSize; + int s = 1; + + for (; p != end; ++p) + { + if (!isspace(*p)) + { + goto sign_char; + } + } + return val; +sign_char: + + if (*p == '-') + { + s = -1; + ++p; + } + else if (*p == '+') + { + ++p; + } + + for(; p != end; ++p) + { + if (!isdigit(*p)) + { + break; + } + val *= 10; + val += (*p) - '0'; + } + return s*val; +} + +unsigned long +Data::convertUnsignedLong() const +{ + unsigned long val = 0; + char* p = mBuf; + const char* const end = mBuf + mSize; + + for (; p != end; ++p) + { + if (!isspace(*p)) + { + goto sign_char; + } + } + return val; +sign_char: + + if (*p == '+') + { + ++p; + } + + for(; p != end; ++p) + { + if (!isdigit(*p)) + { + break; + } + val *= 10; + val += (*p) - '0'; + } + return val; +} + +UInt64 +Data::convertUInt64() const +{ + UInt64 val = 0; + char* p = mBuf; + const char* const end = mBuf + mSize; + + for (; p != end; ++p) + { + if (!isspace(*p)) + { + goto sign_char; + } + } + return val; +sign_char: + + if (*p == '+') + { + ++p; + } + + for(; p != end; ++p) + { + if (!isdigit(*p)) + { + break; + } + val *= 10; + val += (*p) - '0'; + } + return val; +} + +size_t +Data::convertSize() const +{ + size_t val = 0; + char* p = mBuf; + const char* const end = mBuf + mSize; + + for (; p != end; ++p) + { + if (!isspace(*p)) + { + goto sign_char; + } + } + return val; +sign_char: + + if (*p == '+') + { + ++p; + } + + for(; p != end; ++p) + { + if (!isdigit(*p)) + { + break; + } + val *= 10; + val += (*p) - '0'; + } + return val; +} + +#ifndef RESIP_FIXED_POINT +double +Data::convertDouble() const +{ + long val = 0; + char* p = mBuf; + const char* const end = p + mSize; + int s = 1; + + for (; p != end; ++p) + { + if (!isspace(*p)) + { + goto sign_char; + } + } + return val; +sign_char: + + if (*p == '-') + { + s = -1; + ++p; + } + else if (*p == '+') + { + ++p; + } + + for(; p != end; ++p) + { + if (*p == '.') + { + goto decimals; + } + if (!isdigit(*p)) + { + return s*val; + } + val *= 10; + val += (*p) - '0'; + } + return s*val; + +decimals: + ++p; + long d = 0; + double div = 1.0; + for(; p != end; ++p) + { + if (!isdigit(*p)) + { + break; + } + d *= 10; + d += *p - '0'; + div *= 10; + } + return s*(val + d/div); +} +#endif + +bool +Data::prefix(const Data& pre) const +{ + if (pre.size() > size()) + { + return false; + } + + return memcmp(data(), pre.data(), pre.size()) == 0; +} + +bool +Data::postfix(const Data& post) const +{ + if (post.size() > size()) + { + return false; + } + + return memcmp(data() + (size()-post.size()), post.data(), post.size()) == 0; +} + +Data +Data::substr(size_type first, size_type count) const +{ + assert(first <= mSize); + if ( count == Data::npos) + { + return Data(mBuf+first, mSize-first); + } + else + { + assert(first + count <= mSize); + return Data(mBuf+first, count); + } +} + +Data::size_type +Data::find(const Data& match, + size_type start) const +{ + if (start < mSize) + { + ParseBuffer pb(mBuf + start, mSize - start); + pb.skipToChars(match); + if (!pb.eof()) + { + return pb.position() - pb.start() + start; + } + } + + return Data::npos; +} + +int +Data::replace(const Data& match, + const Data& replaceWith, + int max) +{ + assert(!match.empty()); + + int count = 0; + + const int incr = int(replaceWith.size() - match.size()); + for (size_type offset = find(match, 0); + count < max && offset != Data::npos; + offset = find(match, offset+replaceWith.size())) + { + if (mSize + incr >= mCapacity) + { + resize((mCapacity + incr) * 3 / 2, true); + } + else + { + own(); + } + + // move the memory forward (or backward) + memmove(mBuf + offset + replaceWith.size(), mBuf + offset + match.size(), mSize - offset - match.size()); + memcpy(mBuf + offset, replaceWith.data(), replaceWith.size()); + mSize += incr; + + ++count; + } + + return count; +} + +#ifndef RESIP_USE_STL_STREAMS +EncodeStream& +resip::operator<<(EncodeStream& strm, const Data& d) +{ + return strm.write(d.mBuf, d.mSize); +} +#endif + +// random permutation of 0..255 +static const unsigned char randomPermutation[256] = +{ + 44, 9, 46, 184, 21, 30, 92, 231, 79, 7, 166, 237, 173, 72, 91, 123, + 212, 183, 16, 99, 85, 45, 190, 130, 118, 107, 169, 119, 100, 179, 251, 177, + 23, 125, 12, 101, 121, 246, 61, 38, 156, 114, 159, 57, 181, 145, 198, 182, + 58, 215, 174, 225, 82, 178, 150, 161, 63, 103, 32, 203, 68, 151, 139, 55, + 143, 2, 36, 110, 209, 154, 204, 89, 62, 17, 187, 226, 31, 105, 195, 208, + 49, 56, 238, 172, 37, 3, 234, 206, 134, 233, 19, 148, 64, 4, 10, 224, + 144, 88, 93, 191, 20, 131, 138, 199, 243, 244, 39, 50, 214, 87, 6, 84, + 185, 112, 171, 75, 192, 193, 239, 69, 106, 43, 194, 1, 78, 67, 116, 200, + 83, 70, 213, 25, 59, 137, 52, 13, 153, 42, 232, 0, 133, 210, 76, 33, + 255, 236, 124, 104, 65, 201, 53, 155, 140, 254, 54, 196, 120, 146, 216, 29, + 28, 86, 245, 90, 98, 26, 81, 115, 180, 66, 102, 136, 167, 51, 109, 132, + 77, 175, 14, 202, 222, 48, 223, 188, 40, 242, 157, 5, 128, 229, 71, 127, + 164, 207, 247, 8, 80, 149, 94, 160, 47, 117, 135, 176, 129, 142, 189, 97, + 11, 250, 221, 218, 96, 220, 35, 197, 152, 126, 219, 74, 170, 252, 163, 41, + 95, 27, 34, 22, 205, 230, 241, 186, 168, 228, 253, 249, 113, 108, 111, 211, + 235, 217, 165, 122, 15, 141, 158, 147, 240, 24, 162, 18, 60, 73, 227, 248 +}; + +size_t +Data::rawHash(const unsigned char* c, size_t size) +{ + // 4 byte Pearson's hash + // essentially random hashing + + union + { + size_t st; + unsigned char bytes[4]; + }; + st = 0; // suppresses warnings about unused st + bytes[0] = randomPermutation[0]; + bytes[1] = randomPermutation[1]; + bytes[2] = randomPermutation[2]; + bytes[3] = randomPermutation[3]; + + const unsigned char* end = c + size; + for ( ; c != end; ++c) + { + bytes[0] = randomPermutation[*c ^ bytes[0]]; + bytes[1] = randomPermutation[*c ^ bytes[1]]; + bytes[2] = randomPermutation[*c ^ bytes[2]]; + bytes[3] = randomPermutation[*c ^ bytes[3]]; + } + + // convert from network to host byte order + return ntohl((u_long)st); +} + +// use only for ascii characters! +size_t +Data::rawCaseInsensitiveHash(const unsigned char* c, size_t size) +{ + + union + { + size_t st; + unsigned char bytes[4]; + }; + st = 0; // suppresses warnings about unused st + bytes[0] = randomPermutation[0]; + bytes[1] = randomPermutation[1]; + bytes[2] = randomPermutation[2]; + bytes[3] = randomPermutation[3]; + + const unsigned char* end = c + size; + for ( ; c != end; ++c) + { + unsigned char cc = tolower(*c); + bytes[0] = randomPermutation[cc ^ bytes[0]]; + bytes[1] = randomPermutation[cc ^ bytes[1]]; + bytes[2] = randomPermutation[cc ^ bytes[2]]; + bytes[3] = randomPermutation[cc ^ bytes[3]]; + } + + // convert from network to host byte order + return ntohl((u_long)st); +} + +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const UInt16 *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((UInt32)(((const UInt8 *)(d))[1])) << 8)\ + +(UInt32)(((const UInt8 *)(d))[0]) ) +#endif + +#undef get32bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get32bits(d) (*((const UInt32 *) (d))) +#endif + +#if !defined (get32bits) +#define get32bits(d) ((get16bits(d+2) << 16) + get16bits(d)) +#endif + +// This is intended to be a faster case-insensitive hash function that works +// well when the buffer is a RFC 3261 token. +// Having non-token characters will not prevent the hash from working, but it +// will increase the number of cases where a single char difference will result +// in a hash collision. The pairs of _printable_ characters that this hash will +// not distinguish between are @`, [{, \|, ]} and ^~ +// (Note that, for RFC 3261 tokens, this will not be a problem since @, [, {, \, +// |, ], } and ^ are not allowed in a token.) +size_t +Data::rawCaseInsensitiveTokenHash(const unsigned char* data, size_t len) +{ + // .bwc. Hsieh hash, with some bitmasking to get the case-insensitive + // property (this is what all the "0x2020 |" business is about.) + UInt32 hash = len, tmp; + int rem; + + if (len <= 0 || data == NULL) return 0; + + rem = len & 3; + len >>= 2; + + union + { + UInt32 masked; + UInt16 ui16[2]; + }; + + /* Main loop */ + for (;len > 0; len--) + { + // mask out bit 6 for case-insensitivity + masked = (0x20202020 | get32bits(data)); + hash += ui16[0]; + tmp = ((UInt32)ui16[1] << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2*sizeof (UInt16); + hash += hash >> 11; + } + + /* Handle end cases */ + switch (rem) + { + case 3: hash += (0x2020 | get16bits (data)); + hash ^= hash << 16; + hash ^= (0x20 | data[sizeof (UInt16)]) << 18; + hash += hash >> 11; + break; + case 2: hash += (0x2020 | get16bits (data)); + hash ^= hash << 11; + hash += hash >> 17; + break; + case 1: hash += (0x20 | *data); + hash ^= hash << 10; + hash += hash >> 1; + } + + /* Force "avalanching" of final 127 bits */ + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash; + +// union +// { +// size_t st; +// unsigned char bytes[4]; +// }; +// st = 0; // suppresses warnings about unused st +// bytes[0] = randomPermutation[0]; +// bytes[1] = randomPermutation[1]; +// bytes[2] = randomPermutation[2]; +// bytes[3] = randomPermutation[3]; +// +// const unsigned char* end = c + size; +// for ( ; c != end; ++c) +// { +// union +// { +// UInt32 temp; +// UInt8 cccc[4]; +// }; +// // .bwc. Mask out bit 6, use a multiplication op to write the +// // resulting byte to each of the 4 bytes in temp, and xor the whole +// // thing with bytes/st. +// temp = ( (*c | ' ') * 16843009UL) ^ st; +// bytes[0] = randomPermutation[cccc[0]]; +// bytes[1] = randomPermutation[cccc[1]]; +// bytes[2] = randomPermutation[cccc[2]]; +// bytes[3] = randomPermutation[cccc[3]]; +// } +// +// // convert from network to host byte order +// return ntohl((u_long)st); +} + +Data +bits(size_t v) +{ + Data ret; + for (unsigned int i = 0; i < 8*sizeof(size_t); ++i) + { + ret += ('0' + v%2); + v /= 2; + } + + return ret; +} + +size_t +Data::hash() const +{ + return rawHash((const unsigned char*)(this->data()), this->size()); +} + +size_t +Data::caseInsensitivehash() const +{ + return rawCaseInsensitiveHash((const unsigned char*)(this->data()), this->size()); +} + +size_t +Data::caseInsensitiveTokenHash() const +{ + return rawCaseInsensitiveTokenHash((const unsigned char*)(this->data()), this->size()); +} + +#define compUnalignedRemainder(d1, d2, size) \ +switch(size) \ +{\ + case 3: \ + if( (*d1 ^ *d2) & 0xDF) \ + { \ + return false; \ + } \ + d1++; \ + d2++; \ + /* fallthrough */ \ + case 2: \ + if((get16bits(d1) ^ get16bits(d2)) & 0xDFDF) \ + { \ + return false; \ + } \ + d1+=2; \ + d2+=2; \ + break; \ + case 1: \ + if( (*d1 ^ *d2) & 0xDF) \ + { \ + return false; \ + } \ + d1++; \ + d2++; \ + /* fallthrough */ \ + default: \ + ; \ +}\ + +bool +Data::sizeEqualCaseInsensitiveTokenCompare(const Data& rhs) const +{ + assert(mSize==rhs.mSize); + const char* d1(mBuf); + const char* d2(rhs.mBuf); + + if(mSize < 4) + { + // No point in trying 32-bit ops. + compUnalignedRemainder(d1, d2, mSize); + return true; + } + + int unalignedPrefix((ptrdiff_t)d1 & 3); + + compUnalignedRemainder(d1, d2, unalignedPrefix); + + // We are now on a 32-bit boundary with d1. + UInt32* wd1((UInt32*)(d1)); + size_t wordLen=(mSize-unalignedPrefix)>>2; + int rem=(mSize-unalignedPrefix)&3; + + if((ptrdiff_t)(d2)%4==0) + { + // d2 is aligned too. Happy day! + UInt32* wd2((UInt32*)(d2)); + for (;wordLen > 0; wordLen--) + { + // bitwise xor is zero iff equal, but we only really care about bits + // other than bit 6, so we mask out bit 6 after the xor. + if( (*wd1 ^ *wd2) & 0xDFDFDFDF) + { + return false; + } + wd1++; + wd2++; + } + d2=(const char*)wd2; + } + else + { + for (;wordLen > 0; wordLen--) + { + // bitwise xor is zero iff equal, but we only really care about bits + // other than bit 6, so we mask out bit 6 after the xor. + UInt32 test=get32bits(d2); + if( (*wd1 ^ test) & 0xDFDFDFDF) + { + return false; + } + wd1++; + d2+=4; + } + } + d1=(const char*)wd1; + + compUnalignedRemainder(d1, d2, rem); + return true; +} + +std::bitset<256> +Data::toBitset(const resip::Data& chars) +{ + std::bitset<256> result; + result.reset(); + for (unsigned int i=0; i!=chars.mSize;++i) + { + result.set(*(unsigned char*)(chars.mBuf+i)); + } + return result; +} + +std::ostream& +Data::escapeToStream(std::ostream& str, + const std::bitset<256>& shouldEscape) const +{ + static char hex[] = "0123456789ABCDEF"; + + if (empty()) + { + return str; + } + + const unsigned char* anchor = (unsigned char*)mBuf; + const unsigned char* p = (unsigned char*)mBuf; + const unsigned char* e = (unsigned char*)mBuf + mSize; + + while (p < e) + { + // ?abr? Why is this special cased? Removing this code + // does not change the behavior of this method. + if (*p == '%' + && e - p > 2 + && isHex(*(p+1)) + && isHex(*(p+2))) + { + p+=3; + } + else if (shouldEscape[*p]) + { + if(p > anchor) + { + str.write((char*)anchor, p-anchor); + } + int hi = (*p & 0xF0)>>4; + int low = (*p & 0x0F); + + str << '%' << hex[hi] << hex[low]; + anchor=++p; + } + else + { + ++p; + } + } + if(p > anchor) + { + str.write((char*)anchor, p-anchor); + } + return str; +} + +HashValueImp(resip::Data, data.hash()); + +static signed char base64Lookup[128] = +{ + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,62,-1,62,-2,63,52,53, + 54,55,56,57,58,59,60,61,-1,-1, + -1,-2,-1,-1,-1,0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10,11,12,13,14, + 15,16,17,18,19,20,21,22,23,24, + 25,-1,-1,-1,-1,63,-1,26,27,28, + 29,30,31,32,33,34,35,36,37,38, + 39,40,41,42,43,44,45,46,47,48, + 49,50,51,-1,-1,-1,-1,-1 +}; +Data +Data::base64decode() const +{ + // see RFC 3548 + // this will decode normal and URL safe alphabet +#if 0 + return Base64Coder::decode( *this ); +#else + int wc=0; + int val=0; + Data bin; + bin.reserve( size()*3/4 ); + + for( unsigned int i=0; i<size(); i++ ) + { + unsigned int x = mBuf[i] & 0x7F; + char c1,c2,c3; + + int v = base64Lookup[x]; + + if ( v >= 0 ) + { + val = val << 6; + val |= v; + wc++; + + if ( wc == 4 ) + { + c3 = char( val & 0xFF ); val = val >> 8; + c2 = char( val & 0xFF ); val = val >> 8; + c1 = char( val & 0xFF ); val = val >> 8; + + bin += c1; + bin += c2; + bin += c3; + + wc=0; + val=0; + } + } + if ( base64Lookup[x] == -2 ) + { + if (wc==2) val = val<<12; + if (wc==3) val = val<<6; + + c3 = char( val & 0xFF ); val = val >> 8; + c2 = char( val & 0xFF ); val = val >> 8; + c1 = char( val & 0xFF ); val = val >> 8; + + unsigned int xNext = mBuf[i] & 0x7F; + if ( (i+1<size() ) && ( base64Lookup[xNext] == -2 )) + { + bin += c1; + i++; + } + else + { + bin += c1; + bin += c2; + } + + break; + } + } + + return bin; +#endif +} + + +// see RFC 3548 +static unsigned char codeCharUnsafe[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; +static unsigned char codeCharSafe[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_."; +Data +Data::base64encode(bool useSafeSet) const +{ + unsigned char* codeChar = useSafeSet ? codeCharSafe : codeCharUnsafe; + + int srcLength = (int)this->size(); + unsigned int dstLimitLength = srcLength*4/3 + 1 + 2; // +2 for the == chars + unsigned char * dstData = new unsigned char[dstLimitLength]; + unsigned int dstIndex = 0; + + const char * p = static_cast<const char *>( this->data() ); + + for(int index=0;index<srcLength;index+=3) + { + unsigned char codeBits = (p[index] & 0xfc)>>2; + + assert(codeBits < 64); + dstData[dstIndex++] = codeChar[codeBits]; // c0 output + assert(dstIndex <= dstLimitLength); + + // do second codeBits + codeBits = ((p[index]&0x3)<<4); + if (index+1 < srcLength) + { + codeBits |= ((p[index+1]&0xf0)>>4); + } + assert(codeBits < 64); + dstData[dstIndex++] = codeChar[codeBits]; // c1 output + assert(dstIndex <= dstLimitLength); + + if (index+1 >= srcLength) + { + dstData[dstIndex++] = codeChar[64]; + assert(dstIndex <= dstLimitLength); + dstData[dstIndex++] = codeChar[64]; + assert(dstIndex <= dstLimitLength); + break; // encoded d0 only + } + + // do third codeBits + codeBits = ((p[index+1]&0xf)<<2); + if (index+2 < srcLength) + { + codeBits |= ((p[index+2]&0xc0)>>6); + } + assert(codeBits < 64); + dstData[dstIndex++] = codeChar[codeBits]; // c2 output + assert(dstIndex <= dstLimitLength); + + if (index+2 >= srcLength) + { + dstData[dstIndex++] = codeChar[64]; + assert(dstIndex <= dstLimitLength); + break; // encoded d0 d1 only + } + + // do fourth codeBits + codeBits = ((p[index+2]&0x3f)); + assert(codeBits < 64); + dstData[dstIndex++] = codeChar[codeBits]; // c3 output + assert(dstIndex <= dstLimitLength); + // outputed all d0,d1, and d2 + } + + return Data(Data::Take, reinterpret_cast<char*>(dstData), + dstIndex); +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/Data.hxx b/src/libs/resiprocate/rutil/Data.hxx new file mode 100644 index 00000000..c43b2445 --- /dev/null +++ b/src/libs/resiprocate/rutil/Data.hxx @@ -0,0 +1,1154 @@ +#ifndef RESIP_Data_hxx +#define RESIP_Data_hxx + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <iostream> +#include <string> +#include <bitset> +#include <cassert> + +#include "rutil/compat.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/HeapInstanceCounter.hxx" +#include "rutil/HashMap.hxx" + +#ifndef RESIP_DATA_LOCAL_SIZE +#define RESIP_DATA_LOCAL_SIZE 16 +#endif + +class TestData; +namespace resip +{ + +/** + @internal + This template is here to help diagnose API/ABI mismatches. Say you build + librutil. A single Data::init(DataLocalSize<RESIP_DATA_LOCAL_SIZE>) + function is implemented in Data.cxx, with the default + value. (Data::init(DataLocalSize<16>) ends up being defined, + Data::init(DataLocalSize<15>) does not) If, later, another build using + that librutil tries to tweak the local alloc size to 24, it will end + up attempting to call Data::init(DataLocalSize<24>); this will result + in a link-time error, that while opaque, is less opaque than the stack + corruption that would result otherwise. +**/ +template <int S> +struct DataLocalSize +{ + explicit DataLocalSize(size_t) {} +}; + +// .bwc. Pack class Data; has to come before doxygen block though. +#pragma pack(4) + +/** + @brief An alternative to std::string, encapsulates an arbitrary buffer of + bytes. + + It has a variety of memory management styles that can be + established at contruction time and changed later via setBuf(). + + Three modes of allocation are currently available: + + @li 'Borrow' - The Data instance is borrowing the memory from the passed + in buffer. It will modify its contents as necessary, + but will not deallocate it. + + @li 'Share' - The Data instance will use the buffer in a read-only mode. + If any attempt is made to modify the contents of + the Data, it will copy the buffer and modify it. + + @li 'Take' - The Data instance takes complete ownership of the + buffer. The buffer is deallocated using delete[]. + + Additionally, Data has a small locally-allocated buffer (member buffer) that + it will use to hold small amounts of data. By default, this buffer can + contain 16 bytes, meaning that Data will not use the heap unless it + needs more than 16 bytes of space. The tradeoff here, of course, is that + instances of Data will be larger than instances of std::string. Generally + speaking, if you expect to need more than 16 bytes of room, and you cannot + make good use of the flexible memory management offered by Data, you may want + to use a std::string instead. + + @see RESIP_HeapCount + + @todo It might be worthwhile examining the heap usage of this + class in the context of using realloc everywhere appropriate. + (realloc is defined in ANSI C, SVID, and the OpenGroup "Single + Unix Specification"). + + @ingroup text_proc +*/ + +class Data +{ + public: + RESIP_HeapCount(Data); + + typedef unsigned int size_type; + + inline Data() + : mBuf(mPreBuffer), + mSize(0), + mCapacity(LocalAlloc), + mShareEnum(Borrow) + { + mBuf[mSize] = 0; + } + + /** + @internal + */ + class PreallocateType + { + friend class Data; + explicit PreallocateType(int); + }; + /** + @brief used only to disambiguate constructors + */ + static const PreallocateType Preallocate; + + /** + Creates a data with a specified initial capacity. + + @param capacity The initial capacity of the buffer + + @param foo This parameter is ignored; it is merely + used to disambuguate this constructor + from the constructor that takes a single + int. Always pass Data::Preallocate. + */ + Data(size_type capacity, const PreallocateType&); + +//#define DEPRECATED_PREALLOC +#ifdef DEPRECATED_PREALLOC + /** + Creates a data with a specified initial capacity. + + @deprecated This constructor shouldn't really exist; + it would be far better to add a value + to "ShareEnum" (e.g. "Allocate") which + indicates that the Data should allocated + its own buffer. + + @param capacity The initial capacity of the buffer + + @param foo This parameter is ignored; it is merely + used to disambuguate this constructor + from the constructor that takes a single + int. Yes, it's ugly -- that's why it's + deprecated. + + @todo Remove this constructor + */ + Data(size_type capacity, bool foo); +#endif + + /** + Creates a data with a copy of the contents of the + null-terminated string. + + @warning Passing a non-null-terminated string to this + method would be a Really Bad Thing. + */ + Data(const char* str); + + /** + Creates a data with the contents of the buffer. + + @param length Number of bytes in the buffer + */ + Data(const char* buffer, size_type length); + + /** + Creates a data with the contents of the buffer. + + @param length Number of bytes in the buffer + */ + Data(const unsigned char* buffer, size_type length); + + Data(const Data& data); + +#ifdef RESIP_HAS_RVALUE_REFS + Data(Data &&data); +#endif + /** + Creates a data with the contents of the string. + */ + explicit Data(const std::string& str); + + /** + Converts the passed in value into ascii-decimal + representation, and then creates a "Data" containing + that value. (E.g. "Data(75)" will create a Data + with length=2, and contents of 0x37 0x35). + */ + explicit Data(int value); + + /** + Converts the passed in value into ascii-decimal + representation, and then creates a "Data" containing + that value. (E.g. "Data(75)" will create a Data + with length=2, and contents of 0x37 0x35). + */ + explicit Data(unsigned long value); + + /** + Converts the passed in value into ascii-decimal + representation, and then creates a "Data" containing + that value. (E.g. "Data(75)" will create a Data + with length=2, and contents of 0x37 0x35). + */ + explicit Data(unsigned int value); + + /** + Converts the passed in value into ascii-decimal + representation, and then creates a "Data" containing + that value. (E.g. "Data(75)" will create a Data + with length=2, and contents of 0x37 0x35). + */ + explicit Data(UInt64 value); + +#ifndef RESIP_FIXED_POINT + enum DoubleDigitPrecision + { + ZeroDigitPrecision = 0, OneDigitPrecision, + TwoDigitPrecision, ThreeDigitPrecision, + FourDigitPrecision, FiveDigitPrecision, + SixDigitPrecision, SevenDigitPrecision, + EightDigitPrecision, NineDigitPrecision, + TenDigitPrecision, MaxDigitPrecision + }; + /** + Converts the passed in value into ascii-decimal + representation, and then creates a "Data" containing + that value. (E.g. "Data(75.4,2)" will create a Data + with length=4, and contents of 0x37 0x35 0x2E 0x34). + + @param precision Number of digits after the decimal point. + Trailing zeros will be removed. + */ + explicit Data(double value, + Data::DoubleDigitPrecision precision = FourDigitPrecision); +#endif + + /** + Creates a buffer containing "true" or "false", depending + on the value of "value". + */ + explicit Data(bool value); + + /** + Creates a buffer containing a single character. Is this silly? + Maybe. Perhaps it can be removed. + */ + explicit Data(char c); + + /** + The various memory management behaviors. + */ + enum ShareEnum + { + /** The Data instance is borrowing the memory from the passed + in buffer. It will modify its contents as necessary, + but will not deallocate it. + */ + Borrow=0, + + /** The Data instance will use the buffer in a read-only mode. + If any attempt is made to modify the contents of + the Data, it will copy the buffer and modify it. + */ + Share=1, + + /** The Data instance takes complete ownership of the + buffer. The buffer must have been allocate using + "new char[]" so that it can be freed with "delete char[]". + */ + Take=2 + }; + + /** + Creates a Data from the passed-in buffer. + + @see ShareEnum + */ + + Data(ShareEnum, const char* buffer, size_type length); + + /** + Takes a null-terminated string and creates a buffer. + + @see ShareEnum + + @warning Passing a non-null-terminated string to this + method would be a Really Bad Thing. + */ + Data(ShareEnum, const char* buffer); + + /** + Lazily creates a Data from the passed-in Data. + + @see ShareEnum + + @warning Calling this with "Take" or "Borrow" is invalid and will + cause an assertion or crash. + + @todo This implementation has some confusing and conflicting + comments. (e.g. is Borrow actually okay? Can there be some + way to use it with Take as long as you play with mShareEnum + correctly?) + */ + Data(ShareEnum, const Data& staticData); // Cannot call with 'Take' + + inline ~Data() + { + if (mShareEnum == Take) + { + delete[] mBuf; + } + } + + /** + Set the Data to hold {buf} using share type {se}, which may be any + of Share (read-only, no-free), Borrow (read-write, no-free) + or Take (read-write, yes-free). Both the capacity + and current length are set to {length}; you can call truncate2() + afterwords to shorten. The provided buffer (and its current + contents) will be used going forward; any currently owned buffer + will be released. + NOTE: The {buf} param is declared const to support Share type; for + Borrow and Take the buffer may be written (e.g., treated non-const). + **/ + Data& setBuf(ShareEnum se, const char *buf, size_type length); + + /** + Convience function to call setBuf() with a NULL-terminated string. + This is in-lined for case where compiler knows strlen statically. + **/ + Data& setBuf(ShareEnum se, const char *str) + { + return setBuf(se, str, (size_type)strlen(str)); + }; + + + /** + Take the data from {other}. Any current buffer is released. + {this} will have the same storage mode as {other} and steal + its buffer. All storage modes of {other} (Share,Borrow,Take) + are legal. When done, {other} will be empty (it will ref its + internal buffer). + **/ + Data& takeBuf(Data& other); + + /** + Functional equivalent of: *this = Data(buf, length) + but avoid the intermediate allocation and free. Also, + will never decrease capacity. Safe to call even if {buf} + is part of {this}. + + @note The result is always NULL terminated. Unfortunately, + this requires a buffer allocation even if capacity exactly + equals length. + **/ + Data& copy(const char *buf, size_type length); + + /** + Set size to be exactly {length}, extending buffer if needed. + Also, reallocate buffer if needed so that it is writable. + Buffer contents is NOT initialized, and existing contents + may or may not be preserved. + + @note Purpose of this function is to provide a working buffer + of fixed size that the application fills in after this call. + + @note If you want just the buffer without changing the size, + use data() and cast-away the const-ness. + + @note The result may or may not be NULL terminated. The buffer + is NULL terminated only when safe to do so without extra reallocation. + **/ + char* getBuf(size_type length); + + /** + Converts from arbitrary other type to Data. Requires the other + type to have an operator<<. + */ + template<class T> + static Data from(const T& x) + { + Data d; + { + DataStream s(d); + s << x; + } + return d; + } + + friend bool operator==(const Data& lhs, const Data& rhs); + friend bool operator==(const Data& lhs, const char* rhs); + + friend bool operator<(const Data& lhs, const Data& rhs); + friend bool operator<(const Data& lhs, const char* rhs); + friend bool operator<(const char* lhs, const Data& rhs); + + Data& operator=(const Data& data) + { + if (&data==this) + return *this; + return copy(data.mBuf,data.mSize); + } + +#ifdef RESIP_HAS_RVALUE_REFS + Data& operator=(Data &&data); +#endif + + /** + Assigns a null-terminated string to the buffer. + + @warning Passing a non-null-terminated string to this + method would be a Really Bad Thing. + The strlen() inlined to take advantages of cases where + the compiler knows the length statically. + */ + Data& operator=(const char* str) + { + return copy(str, (size_type)strlen(str)); + } + + /** + Concatenates two Data objects. + */ + Data operator+(const Data& rhs) const; + + /** + Concatenates a null-terminated string after the Data object. + + @warning Passing a non-null-terminated string to this + method would be a Really Bad Thing. + */ + Data operator+(const char* str) const; + + /** + Concatenates a single byte after Data object. + */ + Data operator+(char c) const; + + /** + Appends a data object to this one. + */ + inline Data& operator+=(const Data& rhs) + { + return append(rhs.data(), rhs.size()); + } + + /** + Appends a null-terminated string to the end of the Data + object. + + @warning Passing a non-null-terminated string to this + method would be a Really Bad Thing. + */ + inline Data& operator+=(const char* str) + { + assert(str); + return append(str, (size_type)strlen(str)); + } + + + /** + Appends a single byte to the Data object. + */ + inline Data& operator+=(char c) + { + return append(&c, 1); + } + + + /** + Performs an in-place exclusive-or of this buffer + buffer with the specified buffer. If the specifed + buffer is longer than this buffer, then this buffer + will first be expanded and zero-padded. + */ + Data& operator^=(const Data& rhs); + + /** + Returns the character at the specified position. Ensures that ownership of + the buffer is taken, since the character could be modified by the caller. + */ + inline char& operator[](size_type p) + { + assert(p < mSize); + own(); + return mBuf[p]; + } + + /** + Returns the character at the specified position. + */ + inline char operator[](size_type p) const + { + assert(p < mSize); + return mBuf[p]; + } + + /** + Returns the character at the specified position. + */ + char& at(size_type p); + + /** + Guarantees that the underlying buffer used by the Data + is at least the number of bytes specified. May cause + reallocation of the buffer. + */ + void reserve(size_type capacity); + + /** + Appends the specified number of bytes to the end of + this Data. + */ + Data& append(const char* str, size_type len); + + /** + Shortens the size of this Data. Does not + impact the size of the allocated buffer. + This owns() the buffer (undoes Share) so as to write + terminating NULL. See truncate2() as alternative. + + @deprecated dlb says that no one uses this and + it should be removed. + + @todo Remove this at some point. + */ + size_type truncate(size_type len); + + /** + Shortens the size of this Data so length is at most of {len}. + (If already shorter, doesn't increase length). + Does not affect buffer allocation, and doesn't impact writing + terminating NULL. Thus is safe to use with Share'd or external + Take'n buffers. + **/ + Data& truncate2(size_type len); + + /** + Checks whether the Data is empty. + */ + bool empty() const { return mSize == 0; } + + /** + Returns the number of bytes in this Data. + + @note This does NOT indicate the capacity of the + underlying buffer. + */ + size_type size() const { return mSize; } + + /** + Returns a pointer to the contents of this Data. This + is the preferred mechanism for accessing the bytes inside + the Data. + + @note The value returned is NOT necessarily null-terminated. + */ + inline const char* data() const + { + return mBuf; + } + + /** + Returns a null-terminated string representing + + @note Depending on the memory management scheme being used, + this method often copies the contents of the Data; + consequently, this method is rather expensive and should + be avoided when possible. + + @warning Calling this method is a pretty bad idea if the + contents of Data are binary (i.e. may contain + a null in the middle of the Data). + */ + const char* c_str() const; + + /** + Returns a pointer to the beginning of the buffer used by the Data. + */ + inline const char* begin() const + { + return mBuf; + } + + /** + Returns a pointer to the end of the buffer used by the Data. + */ + inline const char* end() const + { + return mBuf + mSize; + } + + typedef enum + { + BINARY, + BASE64, + HEX + } EncodingType; + + /** + Computes the MD5 hash of the current data. + @param type The encoding of the return (default is HEX) + @return The MD5 hash, in the encoding specified by type. + */ + Data md5(EncodingType type=HEX) const; + + /** + Converts this Data to lowercase. + + @note This is silly unless the contents are ASCII. + */ + Data& lowercase(); + + /** + Converts this Data to uppercase. + + @note This is silly unless the contents are ASCII. + */ + Data& uppercase(); + + /** + Converts this Data to lowercase, assuming this Data only consists of + scheme characters. + + @note Assuming scheme contents allows the use of a bitmask instead of + tolower(), which is faster. Why, you ask? A bitmask is sufficient to + perform a lowercase operation on alphabetical data, since 'a' and 'A' + only differ on bit 6; it is set for 'a', but not for 'A'. Digits always + have bit 6 set, so setting it is a no-op. The last three characters in + the scheme character set are '+', '-', and '.'; all of these have bit 6 + set as well. Note that there is no corresponding efficient uppercase + function; clearing bit 6 on either a digit or the the three remaining + characters (+=.) will change them. + */ + Data& schemeLowercase(); + + /** + Returns a hexadecimal representation of the contents of + this Data. + */ + Data hex() const; + + /** + Returns a representation of the contents of the data + with any non-printable characters escaped. + + @warning This is extremely slow, and should not be called + except for debugging purposes. + */ + Data escaped() const; + + /** + Performs RFC 3261 escaping of SIP URIs. + + @note This method is relatively inefficient + + @deprecated Use escapeToStream instead + + @todo This method should be removed + + @see escapeToStream + */ + Data charEncoded() const; + + /** + Performs RFC 3261 un-escaping of SIP URIs. + + @note This method is relatively inefficient + + @bug This method can assert if a "%00" comes + in off the wire. That's really bad form. + + @deprecated Use something more in the spirit of escapeToStream instead + + @todo This method should be removed + + @see escapeToStream + */ + Data charUnencoded() const; + + /** + Performs in-place HTTP URL escaping of a Data. + */ + Data urlEncoded() const; + + /** + Performs in-place HTTP URL un-escaping of a Data. + */ + Data urlDecoded() const; + + /** + Escapes a Data to a stream according to HTTP URL encoding rules. + */ + EncodeStream& urlEncode(EncodeStream& s) const; + + /** + Un-escapes a Data to a stream according to HTTP URL encoding rules. + */ + EncodeStream& urlDecode(EncodeStream& s) const; + + /** + Performs in-place XML Character Data escaping of a Data. + */ + Data xmlCharDataEncode() const; + + /** + Performs in-place XML Character Data un-escaping of a Data. + */ + Data xmlCharDataDecode() const; + + /** + Escapes a Data to a stream according to XML Character Data encoding rules. + */ + EncodeStream& xmlCharDataEncode(EncodeStream& s) const; + + /** + Un-escapes a Data to a stream according to XML Character Data encoding rules. + */ + EncodeStream& xmlCharDataDecode(EncodeStream& s) const; + + /** + Shortens the size of this Data. If the contents are truncated, + this method appends two dot ('.') characters to the end. + Presumably, this is used for output purposes. + */ + Data trunc(size_type trunc) const; + + /** + Clears the contents of this Data. This call does not modify + the capacity of the Data. It does not write terminating NULL, + and thus is safe to use with external buffers. + */ + Data& clear() { return truncate2(0); } + + /** + Takes the contents of the Data and converts them to an + integer. Will strip leading whitespace. This method stops + upon encountering the first non-decimal digit (with exceptions + made for leading negative signs). + */ + int convertInt() const; + unsigned long convertUnsignedLong() const; + + /** + Takes the contents of the Data and converts them to a + size_t. Will strip leading whitespace. This method stops + upon encountering the first non-decimal digit. + */ + size_t convertSize() const; + +#ifndef RESIP_FIXED_POINT + /** + Takes the contents of the Data and converts them to a + double precision floating point value. Will strip leading + whitespace. This method stops upon encountering the first + non-decimal digit (with exceptions made for decimal points + and leading negative signs). + */ + double convertDouble() const; +#endif + + /** + Takes the contents of the Data and converts them to an + unsigned 64-bit integer. Will strip leading whitespace. + This method stops upon encountering the first non-decimal digit. + */ + UInt64 convertUInt64() const; + + /** + Returns true if this Data starts with the bytes indicated by + the passed-in Data. For example, if this Data is "abc", then + prefix(Data("ab")) would be true; however, prefix(Data("abcd")) + would be false. + */ + bool prefix(const Data& pre) const; + + /** + Returns true if this Data ends with the bytes indicated by + the passed-in Data. For example, if this Data is "abc", then + postfix(Data("bc")) would be true; however, postfix(Data("ab")) + would be false. + */ + bool postfix(const Data& post) const; + + /** + Copies a portion of this Data into a new Data. + + @param first Index of the first byte to copy + @param count Number of bytes to copy + */ + Data substr(size_type first, size_type count = Data::npos) const; + + /** + Finds a specified sequence of bytes in this Data. + + @param match The bytes to be found + + @param start Offset into this Data to start the search + + @returns An index to the start of the found bytes. + */ + size_type find(const Data& match, size_type start = 0) const; + + /** + Replaces up to max occurrences of the bytes match with + target. Returns the number of matches. + */ + int replace(const Data& match, const Data& target, int max=INT_MAX); + + /** + Constant that represents a zero-length data. + */ + static const Data Empty; + + /** + Represents an impossible position; returned to indicate failure to find. + */ + static const size_type npos; + + /** + Initializes Data class. + + @note This method is a link time constraint. Don't remove it. + */ + static bool init(DataLocalSize<RESIP_DATA_LOCAL_SIZE> arg); + + /** + Performs RFC 3548 Base 64 decoding of the contents of this data. + + @returns A new buffer containing the unencoded representation + */ + Data base64decode() const; + + /** + Performs RFC 3548 Base 64 encoding of the contents of this data. + + @returns A new buffer containing the base64 representation + */ + Data base64encode(bool useUrlSafe=false) const; + + /** + Creates a 32-bit hash based on the contents of the indicated + buffer. + + @param c Pointer to the buffer to hash + @param size Number of bytes to be hashed + */ + static size_t rawHash(const unsigned char* c, size_t size); + + /** + Creates a 32-bit hash based on the contents of this Data. + */ + size_t hash() const; + + /** + Creates a 32-bit hash based on the contents of the indicated + buffer, after normalizing any alphabetic characters to lowercase. + + @param c Pointer to the buffer to hash + @param size Number of bytes to be hashed + */ + static size_t rawCaseInsensitiveHash(const unsigned char* c, size_t size); + + /** + A faster version of rawCaseInsensitiveHash that has the same collision + properties if this Data is made up of RFC 3261 token characters. + + @param c Pointer to the buffer to hash + @param size Number of bytes to be hashed + @note This is not guaranteed to return the same value as + rawCaseInsensitiveHash. + */ + static size_t rawCaseInsensitiveTokenHash(const unsigned char* c, size_t size); + + /** + Creates a 32-bit hash based on the contents of this Data, after + normalizing any alphabetic characters to lowercase. + */ + size_t caseInsensitivehash() const; + + /** + A faster version of caseInsensitiveHash that has the same collision + properties if this Data is made up of RFC 3261 token characters. + @note This is not guaranteed to return the same value as + rawCaseInsensitiveHash. + */ + size_t caseInsensitiveTokenHash() const; + + inline bool caseInsensitiveTokenCompare(const Data& rhs) const + { + if(mSize==rhs.mSize) + { + return sizeEqualCaseInsensitiveTokenCompare(rhs); + } + return false; + } + + bool sizeEqualCaseInsensitiveTokenCompare(const Data& rhs) const; + + /** + Creates a bitset reflecting the contents of this data (as a set) + ie. "15eo" would have the bits 49, 53, 101, and 111 set to true, and + all others set to false + */ + static std::bitset<256> toBitset(const resip::Data& chars); + + /** + Performs escaping of this Data according to the indicated + Predicate. + + @param str A stream to which the escaped representation + should be added. + + @param shouldEscape A functor which takes a single character + as a parameter, and returns true if the + character should be escaped, false if + it should not. + + @deprecated dlb -- pass a 256 array of bits rather than a function. + */ + template<class Predicate> EncodeStream& + escapeToStream(EncodeStream& str, + Predicate shouldEscape) const; + + /** + Performs escaping of this Data according to a bitset. + + @param str A stream to which the escaped representation + should be added. + + @param shouldEscape A bitset representing which chars should be escaped. + */ + std::ostream& escapeToStream(std::ostream& str, + const std::bitset<256>& shouldEscape) const; + + private: + /** + @deprecated use Data(ShareEnum ...) + */ + Data(const char* buffer, size_type length, bool); + + /** + Copies the contents of this data to a new buffer if the + Data does not own the current buffer. + */ + void own() const; + + /** + @note Always allocates a new buffer + */ + void resize(size_type newSize, bool copy); + + static bool isHex(unsigned char c); + + /** Trade off between in-object and heap allocation + Larger LocalAlloc makes for larger objects that have Data members but + bulk allocation/deallocation of Data members. */ + enum {LocalAlloc = RESIP_DATA_LOCAL_SIZE }; + + char* mBuf; + size_type mSize; + size_type mCapacity; + char mPreBuffer[LocalAlloc]; + // Null terminator for mPreBuffer when mSize==LocalAlloc lands here; this + // is ok, because Borrow==0. + // Note: we could use a char here, and expand mPreBuffer by 3 bytes, but + // this imposes a performance penalty since it requires operating on a + // memory location smaller than a word (requires masking and such). + size_type mShareEnum; + + friend std::ostream& operator<<(std::ostream& strm, const Data& d); +#ifndef RESIP_USE_STL_STREAMS + friend EncodeStream& operator<<(EncodeStream& strm, const Data& d); +#endif + friend class ParseBuffer; + friend class DataBuffer; + friend class DataStream; + friend class oDataStream; + friend class ::TestData; + friend class MD5Buffer; +}; +// reset alignment to default +#pragma pack() + + +class DataHelper { + public: + static const bool isCharHex[256]; +}; + +static bool invokeDataInit = Data::init(DataLocalSize<RESIP_DATA_LOCAL_SIZE>(0)); + +inline bool Data::isHex(unsigned char c) +{ + return DataHelper::isCharHex[c]; +} + +inline bool isEqualNoCase(const Data& left, const Data& right) +{ + return ( (left.size() == right.size()) && + (strncasecmp(left.data(), right.data(), left.size()) == 0) ); +} + +inline bool isTokenEqualNoCase(const Data& left, const Data& right) +{ + return left.caseInsensitiveTokenCompare(right); +} + +inline bool isLessThanNoCase(const Data& left, const Data& right) +{ + size_t minsize = resipMin( left.size(), right.size() ); + int res = strncasecmp(left.data(), right.data(), minsize); + + if (res < 0) + { + return true; + } + else if (res > 0) + { + return false; + } + else + { + return left.size() < right.size(); + } +} + +template<class Predicate> EncodeStream& +Data::escapeToStream(EncodeStream& str, Predicate shouldEscape) const +{ + static char hex[] = "0123456789ABCDEF"; + + if (empty()) + { + return str; + } + + const unsigned char* p = (unsigned char*)mBuf; + const unsigned char* e = (unsigned char*)mBuf + mSize; + + while (p < e) + { + // ?abr? Why is this special cased? Removing this code + // does not change the behavior of this method. + if (*p == '%' + && e - p > 2 + && isHex(*(p+1)) + && isHex(*(p+2))) + { + str.write((char*)p, 3); + p+=3; + } + else if (shouldEscape[*p]) + { + int hi = (*p & 0xF0)>>4; + int low = (*p & 0x0F); + + str << '%' << hex[hi] << hex[low]; + p++; + } + else + { + str.put(*p++); + } + } + return str; +} + +inline bool operator!=(const Data& lhs, const Data& rhs) { return !(lhs == rhs); } +inline bool operator>(const Data& lhs, const Data& rhs) { return rhs < lhs; } +inline bool operator<=(const Data& lhs, const Data& rhs) { return !(rhs < lhs); } +inline bool operator>=(const Data& lhs, const Data& rhs) { return !(lhs < rhs); } +inline bool operator!=(const Data& lhs, const char* rhs) { return !(lhs == rhs); } +inline bool operator>(const Data& lhs, const char* rhs) { return rhs < lhs; } +inline bool operator<=(const Data& lhs, const char* rhs) { return !(rhs < lhs); } +inline bool operator>=(const Data& lhs, const char* rhs) { return !(lhs < rhs); } +inline bool operator==(const char* lhs, const Data& rhs) { return rhs == lhs; } +inline bool operator!=(const char* lhs, const Data& rhs) { return !(rhs == lhs); } +inline bool operator>(const char* lhs, const Data& rhs) { return rhs < lhs; } +inline bool operator<=(const char* lhs, const Data& rhs) { return !(rhs < lhs); } +inline bool operator>=(const char* lhs, const Data& rhs) { return !(lhs < rhs); } +#ifndef RESIP_USE_STL_STREAMS +EncodeStream& operator<<(EncodeStream& strm, const Data& d); +#endif +inline std::ostream& operator<<(std::ostream& strm, const Data& d) +{ + return strm.write(d.mBuf, d.mSize); +} + + +inline Data +operator+(const char* c, const Data& d) +{ + return Data(c) + d; +} + +} + +HashValue(resip::Data); + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/DataException.hxx b/src/libs/resiprocate/rutil/DataException.hxx new file mode 100644 index 00000000..c563487d --- /dev/null +++ b/src/libs/resiprocate/rutil/DataException.hxx @@ -0,0 +1,82 @@ +#ifndef RESIP_DataException_hxx +#define RESIP_DataException_hxx + +#include <exception> +#include <iostream> + +#include "rutil/Data.hxx" +#include "rutil/BaseException.hxx" + +namespace resip +{ + +class DataException : public BaseException +{ + public: + virtual const char* name() const + { + return "DataException"; + } + + const Data& getMessage() const {return message;} + + DataException(const Data& msg, + const Data& file, + int line) + : BaseException(msg, file, line) + {} +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/rutil/DataStream.cxx b/src/libs/resiprocate/rutil/DataStream.cxx new file mode 100644 index 00000000..678f302e --- /dev/null +++ b/src/libs/resiprocate/rutil/DataStream.cxx @@ -0,0 +1,229 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <cassert> +#include "rutil/DataStream.hxx" +#include "rutil/Data.hxx" + +// Remove warning about 'this' use in initiator list - pointer is only stored +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) // using this in base member initializer list +#endif + +using namespace resip; + +DataBuffer::DataBuffer(Data& str) + : mStr(str) +{ +#ifdef RESIP_USE_STL_STREAMS + char* gbuf = const_cast<char*>(mStr.mBuf); + setg(gbuf, gbuf, gbuf+mStr.size()); + // expose the excess capacity as the put buffer + setp(gbuf+mStr.mSize, gbuf+mStr.mCapacity); +#endif +} + +DataBuffer::~DataBuffer() +{} + +#ifndef RESIP_USE_STL_STREAMS +UInt64 DataBuffer::tellpbuf(void) +{ + return mStr.size(); +} + +size_t DataBuffer::readbuf(char *buf, size_t count) +{ + if (count <= 0) + { + return 0; + } + + if (!buf) + { + assert(0); + return 0; + } + + size_t cursize = mStr.size(); + + size_t toread = (cursize < count) ? (cursize) : (count); + + memcpy(buf,mStr.begin(),toread); + + //wow, not efficient. Just added this function for repro, need to revisit. @TODO. + mStr = mStr.substr(toread); + + return toread; +} + +size_t DataBuffer::writebuf(const char *str, size_t count) +{ + if( count <= 0 ) + { + return 0; + } + + mStr.append(str,count); + return count; +} +size_t DataBuffer::putbuf(char ch) +{ + mStr += ch; + + return 1; +} +#else +int +DataBuffer::sync() +{ + size_t len = pptr() - pbase(); + if (len > 0) + { + size_t pos = gptr() - eback(); // remember the get position + mStr.mSize += len; + char* gbuf = const_cast<char*>(mStr.data()); + // reset the get buffer + setg(gbuf, gbuf+pos, gbuf+mStr.size()); + // reset the put buffer + setp(gbuf + mStr.mSize, gbuf + mStr.mCapacity); + } + return 0; +} + +int +DataBuffer::overflow(int c) +{ + // sync, but reallocate + size_t len = pptr() - pbase(); + // .kw. test below is always true. Checked with David Butcher + // and he says this is safe but perhaps performs unrequired + // re-allocs. + if (len >= 0) + { + size_t pos = gptr() - eback(); // remember the get position + + // update the length + mStr.mSize += len; + + // resize the underlying Data and reset the input buffer + mStr.resize(((mStr.mCapacity+16)*3)/2, true); + + char* gbuf = const_cast<char*>(mStr.mBuf); + // reset the get buffer + setg(gbuf, gbuf+pos, gbuf+mStr.mSize); + // reset the put buffer + setp(gbuf + mStr.mSize, gbuf + mStr.mCapacity); + } + if (c != -1) + { + mStr.mBuf[mStr.mSize] = c; + pbump(1); + return c; + } + return 0; +} +#endif + +iDataStream::iDataStream(Data& str) + : DataBuffer(str), + DecodeStream(this) +{ +} + +iDataStream::~iDataStream() +{} + +oDataStream::oDataStream(Data& str) + : DataBuffer(str), + EncodeStream(this) +{ + // don't call this with a read-only buffer! + assert(str.mShareEnum != Data::Share); +} + +oDataStream::~oDataStream() +{ + flush(); +} + +void +oDataStream::reset() +{ + flush(); + mStr.clear(); +#ifdef RESIP_USE_STL_STREAMS + // reset the underlying buffer state + char* gbuf = const_cast<char*>(mStr.mBuf); + setg(gbuf, gbuf, gbuf+mStr.size()); + setp(gbuf+mStr.mSize, gbuf+mStr.mCapacity); +#endif +} + +DataStream::DataStream(Data& str) + : DataBuffer(str), +#ifdef RESIP_USE_STL_STREAMS + std::iostream(this) +#else + ResipFastOStream(this) +#endif +{ + // don't call this with a read-only buffer! + assert(str.mShareEnum != Data::Share); +} + +DataStream::~DataStream() +{ + flush(); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright 2000-2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/DataStream.hxx b/src/libs/resiprocate/rutil/DataStream.hxx new file mode 100644 index 00000000..6ad28d08 --- /dev/null +++ b/src/libs/resiprocate/rutil/DataStream.hxx @@ -0,0 +1,173 @@ +#ifndef RESIP_DataStream_hxx +#define RESIP_DataStream_hxx + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <iostream> +#include "resipfaststreams.hxx" + +namespace resip +{ + +class Data; + +/** @brief Implementation of std::streambuf used to back the DataStream, + iDataStream, and oDataStream. + */ +class DataBuffer : +#ifdef RESIP_USE_STL_STREAMS + public std::streambuf +#else + public ResipStreamBuf +#endif +{ + public: + DataBuffer(Data& str); + virtual ~DataBuffer(); + + protected: +#ifdef RESIP_USE_STL_STREAMS + virtual int sync(); + virtual int overflow(int c = -1); +#else + virtual size_t writebuf(const char *s, size_t count); + virtual size_t readbuf(char *buf, size_t count); + virtual size_t putbuf(char ch); + virtual void flushbuf(void) + {} + virtual UInt64 tellpbuf(void); +#endif + Data& mStr; + private: + DataBuffer(const DataBuffer&); + DataBuffer& operator=(const DataBuffer&); +}; + +/** + @brief An iostream that operates on an existing Data. + + The data written to the stream is appended to the reference passed to the + constructor. The data is valid after DataStream's destructor is called. + Data read from the stream is read from the reference passed to the + constructor. + */ +class DataStream : private DataBuffer +#ifdef RESIP_USE_STL_STREAMS +, public std::iostream +#else +, public ResipFastOStream +#endif + +{ + public: + /** Constructs a DataStream with a Data to operate on. + @param str A Data to operate on. + */ + DataStream(Data& str); + /** Calls flush on itself to force the update to the Data reference + passed into the constructor. + */ + ~DataStream(); + + private: + DataStream(const DataStream&); + DataStream& operator=(const DataStream&); +}; + +/** + @brief An istream that operates on an existing Data. + */ +class iDataStream : private DataBuffer, public DecodeStream +{ + public: + /** Constructs a iDataStream with a Data to operate on. + @param str A Data to operate on. + */ + iDataStream(Data& str); + ~iDataStream(); + + private: + iDataStream(const iDataStream&); + iDataStream& operator=(const iDataStream&); + +}; + +/** + @brief An ostream that operates on an existing Data. + + The data is appended to the reference passed to the constructor. The data is + valid after DataStream's destructor is called. + */ +class oDataStream : private DataBuffer, public EncodeStream +{ + public: + /** Constructs a oDataStream with a Data to operate on. + @param str A Data to operate on. + */ + oDataStream(Data& str); + /** Calls flush on itself to force the update to the Data reference + passed into the constructor. + */ + ~oDataStream(); + + /** Clears the underlying Data reference. */ + void reset(); + + private: + oDataStream(const oDataStream&); + oDataStream& operator=(const oDataStream&); +}; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/DigestStream.cxx b/src/libs/resiprocate/rutil/DigestStream.cxx new file mode 100644 index 00000000..0e3e023f --- /dev/null +++ b/src/libs/resiprocate/rutil/DigestStream.cxx @@ -0,0 +1,141 @@ +#include "rutil/DigestStream.hxx" + +// Remove warning about 'this' use in initiator list - pointer is only stored +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) // using this in base member initializer list +#endif + +using namespace resip; + +DigestBuffer::DigestBuffer(const EVP_MD* digest) +{ + EVP_MD_CTX_init(&mContext); + EVP_DigestInit_ex(&mContext, digest, 0); + setp(mBuf, mBuf + sizeof(mBuf)); +} + +DigestBuffer::~DigestBuffer() +{ + EVP_MD_CTX_cleanup(&mContext); +} + +int +DigestBuffer::sync() +{ + size_t len = pptr() - pbase(); + if (len > 0) + { + EVP_DigestUpdate(&mContext, reinterpret_cast <unsigned const char*>(pbase()), len); + // reset the put buffer + setp(mBuf, mBuf + sizeof(mBuf)); + } + return 0; +} + +int +DigestBuffer::overflow(int c) +{ + sync(); + if (c != -1) + { + mBuf[0] = c; + pbump(1); + return c; + } + return 0; +} + +Data +DigestBuffer::getHex() +{ + unsigned char buf[EVP_MD_CTX_size(&mContext)]; + unsigned int len; + EVP_DigestFinal_ex(&mContext, buf, &len); + + Data digest(Data::Share, (const char*)buf, len); + return digest.hex(); +} + +Data +DigestBuffer::getBin() +{ + unsigned char buf[EVP_MD_CTX_size(&mContext)]; + unsigned int len; + EVP_DigestFinal_ex(&mContext, buf, &len); + + Data digest(Data::Share, (const char*)buf, len); + return digest; +} + +DigestStream::DigestStream(const EVP_MD* digest) + : DigestBuffer(digest), std::ostream(this) +{ +} + +DigestStream::~DigestStream() +{} + +Data +DigestStream::getHex() +{ + flush(); + return DigestBuffer::getHex(); + //return mStreambuf.getHex(); +} + +Data +DigestStream::getBin() +{ + flush(); + return DigestBuffer::getBin(); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/DigestStream.hxx b/src/libs/resiprocate/rutil/DigestStream.hxx new file mode 100644 index 00000000..dc2f4a02 --- /dev/null +++ b/src/libs/resiprocate/rutil/DigestStream.hxx @@ -0,0 +1,100 @@ +#if !defined(RESIP_DigestSTREAM_HXX) +#define RESIP_DigestSTREAM_HXX + +#include <iostream> +#include "rutil/Data.hxx" +#include <openssl/evp.h> + +namespace resip +{ + +/** + @brief Implementation of std::streambuf used to back the DigestStream. +*/ +class DigestBuffer : public std::streambuf +{ +public: + DigestBuffer(const EVP_MD* digest); + virtual ~DigestBuffer(); + /** @returns the Digest hexadecimal representation of the data from the buffer + */ + Data getHex(); + Data getBin(); +protected: + virtual int sync(); + virtual int overflow(int c = -1); +private: + char mBuf[64]; + EVP_MD_CTX mContext; +}; + +/** + @brief Used to accumlate data written to the stream in a DigestBuffer and + convert the data to Digest. +*/ +class DigestStream : private DigestBuffer, public std::ostream +{ +public: + DigestStream(const EVP_MD* digest); + ~DigestStream(); + /** Calls flush() on itself and returns the Digest data in hex format. + @returns the Digest hexadecimal representation of the data written to the + stream and convert the data to Digest. + */ + Data getHex(); + Data getBin(); +private: +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/DinkyPool.hxx b/src/libs/resiprocate/rutil/DinkyPool.hxx new file mode 100644 index 00000000..d57ad8a9 --- /dev/null +++ b/src/libs/resiprocate/rutil/DinkyPool.hxx @@ -0,0 +1,111 @@ +#ifndef DinkyPool_Include_Guard +#define DinkyPool_Include_Guard + +#include <limits> +#include <memory> +#include <stddef.h> + +#include "rutil/PoolBase.hxx" + +namespace resip +{ +/** + A dirt-simple lightweight pool allocator meant for use in short-lifetime + objects. This will pool-allocate at most S bytes, after which no further pool + allocation will be performed, and fallback to the system new/delete will be + used (deallocating a pool allocated object will _not_ free up room in the + pool; the memory will be freed when the DinkyPool goes away). +*/ +template<unsigned int S> +class DinkyPool : public PoolBase +{ + public: + DinkyPool() : + count(0){} + + ~DinkyPool(){} + + void* allocate(size_t size) + { + if((8*count)+size <= S) + { + void* result=mBuf[count]; + count+=(size+7)/8; + return result; + } + return ::operator new(size); + } + + void deallocate(void* ptr) + { + if(ptr >= (void*)mBuf[0] && ptr < (void*)mBuf[(S+7)/8]) + { + return; + } + ::operator delete(ptr); + } + + size_t max_size() const + { + return std::numeric_limits<size_t>::max(); + } + private: + // disabled + DinkyPool& operator=(const DinkyPool& rhs); + DinkyPool(const DinkyPool& other); + + size_t count; // 8-byte chunks alloced so far + char mBuf[(S+7)/8][8]; // 8-byte chunks for alignment +}; + +} +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/DnsUtil.cxx b/src/libs/resiprocate/rutil/DnsUtil.cxx new file mode 100644 index 00000000..3560ede3 --- /dev/null +++ b/src/libs/resiprocate/rutil/DnsUtil.cxx @@ -0,0 +1,1049 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if !defined(WIN32) +#if defined(__SUNPRO_CC) || defined (__sun__) +#define BSD_COMP /* !rk! needed to enable SIOCGIFCONF */ +#endif +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/ioctl.h> +#include <net/if.h> +#include <errno.h> +#include <netdb.h> +#endif + +#include <stdio.h> +#include <memory> + +#include "rutil/compat.hxx" +#include "rutil/Socket.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/WinCompat.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 256 +#endif + +using namespace resip; +using namespace std; + + +list<Data> +DnsUtil::lookupARecords(const Data& host) +{ + list<Data> names; + + if (DnsUtil::isIpV4Address(host)) + { + names.push_back(host); + return names; + } + + struct hostent* result=0; + int ret=0; + int herrno=0; + +#if defined(__linux__) + struct hostent hostbuf; + char buffer[8192]; + ret = gethostbyname_r( host.c_str(), &hostbuf, buffer, sizeof(buffer), &result, &herrno); + assert (ret != ERANGE); +#elif defined(__QNX__) || defined(__SUNPRO_CC) + struct hostent hostbuf; + char buffer[8192]; + result = gethostbyname_r( host.c_str(), &hostbuf, buffer, sizeof(buffer), &herrno ); +#elif defined(__APPLE__) + // gethostbyname in os/x is thread-safe... + // http://developer.apple.com/technotes/tn2002/pdf/tn2053.pdf + result = gethostbyname( host.c_str() ); + ret = (result == 0); +#else + assert(0); + return names; +#endif + + if (ret != 0 || result == 0) + { + Data msg; + switch (herrno) + { + case HOST_NOT_FOUND: + msg = "host not found: "; + break; + case NO_DATA: + msg = "no data found for: "; + break; + case NO_RECOVERY: + msg = "no recovery lookup up: "; + break; + case TRY_AGAIN: + msg = "try again: "; + break; + } + msg += host; + + DebugLog (<< "DNS lookup of " << host << " resulted in " << msg); + throw Exception("no dns resolution:" + msg, __FILE__, __LINE__); + } + else + { + assert(result); + assert(result->h_length == 4); + char str[256]; + for (char** pptr = result->h_addr_list; *pptr != 0; pptr++) + { + inet_ntop(result->h_addrtype, (u_int32_t*)(*pptr), str, sizeof(str)); + names.push_back(str); + } + + StackLog (<< "DNS lookup of " << host << ": canonical name: " << result->h_name + << " " + << Inserter(names)); + + return names; + } +} + + +Data +DnsUtil::getLocalHostName() +{ + char buffer[MAXHOSTNAMELEN]; + initNetwork(); + buffer[0] = '\0'; + if (gethostname(buffer,sizeof(buffer)) == -1) + { + int err = getErrno(); + switch (err) + { +// !RjS! This makes no sense for non-windows. The +// current hack (see the #define in .hxx) needs +// to be reworked. + case WSANOTINITIALISED: + CritLog( << "could not find local hostname because network not initialized:" << strerror(err) ); + break; + default: + CritLog( << "could not find local hostname:" << strerror(err) ); + break; + } + throw Exception("could not find local hostname",__FILE__,__LINE__); + } + + struct addrinfo* result=0; + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_flags |= AI_CANONNAME; + hints.ai_family |= AF_UNSPEC; + int res = getaddrinfo(buffer, 0, &hints, &result); + if (!res) + { + // !jf! this should really use the Data class + if (strchr(result->ai_canonname, '.') != 0) + { + strncpy(buffer, result->ai_canonname, sizeof(buffer)); + } + else + { + InfoLog( << "local hostname does not contain a domain part " << buffer); + } + freeaddrinfo(result); + } + else + { + InfoLog (<< "Couldn't determine local hostname. Error was: " << gai_strerror(res) << ". Returning empty string"); + } + + return Data(buffer); +} + + +Data +DnsUtil::getLocalDomainName() +{ + Data lhn(getLocalHostName()); + size_t dpos = lhn.find("."); + if (dpos != Data::npos) + { + return lhn.substr(dpos+1); + } + else + { +#if defined( __APPLE__ ) || defined( WIN32 ) || defined(__SUNPRO_CC) || defined(__sun__) || defined(__ANDROID_API__) + throw Exception("Could not find domainname in local hostname",__FILE__,__LINE__); +#else + DebugLog( << "No domain portion in hostname <" << lhn << ">, so using getdomainname"); + char buffer[MAXHOSTNAMELEN]; + if (int e = getdomainname(buffer,sizeof(buffer)) == -1) + { + if ( e != 0 ) + { + int err = getErrno(); + CritLog(<< "Couldn't find domainname: " << strerror(err)); + throw Exception(strerror(err), __FILE__,__LINE__); + } + } + DebugLog (<< "Found local domain name " << buffer); + + return Data(buffer); +#endif + } +} + +Data +DnsUtil::getLocalIpAddress(const Data& myInterface) +{ + Data result; + std::list<std::pair<Data,Data> > ifs = DnsUtil::getInterfaces(myInterface); + + if (ifs.empty()) + { + WarningLog( << "No interfaces matching " << myInterface << " were found" ); + throw Exception("No interfaces matching", __FILE__, __LINE__); + } + else + { + InfoLog (<< "Local IP address for " << myInterface << " is " << ifs.begin()->second); + return ifs.begin()->second; + } +} + +Data +DnsUtil::inet_ntop(const struct in_addr& addr) +{ + char str[256]; + inet_ntop(AF_INET, &addr, str, sizeof(str)); + return Data(str); +} + +#ifdef USE_IPV6 +Data +DnsUtil::inet_ntop(const struct in6_addr& addr) +{ + char str[256]; + inet_ntop(AF_INET6, &addr, str, sizeof(str)); + return Data(str); +} +#endif + +Data +DnsUtil::inet_ntop(const struct sockaddr& addr) +{ +#ifdef USE_IPV6 + if (addr.sa_family == AF_INET6) + { + const struct sockaddr_in6* addr6 = reinterpret_cast<const sockaddr_in6*>(&addr); + return DnsUtil::inet_ntop(addr6->sin6_addr); + } + else +#endif + { + const struct sockaddr_in* addr4 = reinterpret_cast<const sockaddr_in*>(&addr); + return DnsUtil::inet_ntop(addr4->sin_addr); + } +} + +int +DnsUtil::inet_pton(const Data& printableIp, struct in_addr& dst) +{ + return DnsUtil::inet_pton(AF_INET, printableIp.c_str(), &dst); +} + +#ifdef USE_IPV6 +int +DnsUtil::inet_pton(const Data& printableIp, struct in6_addr& dst) +{ + return DnsUtil::inet_pton(AF_INET6, printableIp.c_str(), &dst); +} +#endif + + +bool +DnsUtil::isIpV4Address(const Data& ipAddress) +{ + // ok, this is fairly monstrous but it works. It is also more than 10 times + // faster than the commented-out code below, in the worst case scenario. + + const char* first = ipAddress.data(); + const char* end = first + ipAddress.size(); + int octets = 0; + while(octets++ < 4) + { + const char* last=first; + + // .bwc. I have tried using std::bitset instead of the 0 <= *last <= 9 + // check, but it is slower. + while(*last >= '0' && *last <= '9' && last - first <= 3 && last != end) + { + // Skip at most 3 decimals, without going past the end of the buffer. + ++last; + } + + // last should now point to either a '.', or the end of the buffer. + + switch(last-first) // number of decimals in this octet + { + case 2: + if(*first == '0') + { + // Two-decimal octet can't begin with 0... + // ?bwc? Maybe let this slide? + return false; + } + case 1: + // ... but a one-decimal octet can begin with a 0. + break; // x. or xx. + case 3: + // xxx. (could be too large) + // .bwc. I have tried implementing this with a reinterpret_cast + // and a UInt32 comparison (accounting for endianness), and memcmp, + // but both appear to be slower, even when using + // "255.255.255.255" (which maximizes the number of comparisons). + if(*first != '1') + { + if(*first == '2') + { + // Might have overflow if first digit is 2 + if(*(first+1)>'5' || (*(first+1)=='5' && *(first+2)>'5')) + { + return false; + } + } + else + { + // First digit greater than 2 means overflow, 0 not allowed. + return false; + } + } + break; + default: + return false; + } + + if(octets < 4) + { + if(*last == '.') + { + // Skip over the '.' + ++last; + } + else + { + return false; + } + } + first = last; // is now pointing at either the first digit in the next + // octet, or the end of the buffer. + } + + return first==end; +// unsigned int p1,p2,p3,p4; +// int count=0; +// int result = sscanf( ipAddress.c_str(), +// "%u.%u.%u.%u%n", +// &p1, &p2, &p3, &p4, &count ); +// +// if ( (result == 4) && (p1 <= 255) && (p2 <= 255) && (p3 <= 255) && (p4 <= 255) && (count == int(ipAddress.size())) ) +// { +// return true; +// } +// else +// { +// return false; +// } +} + +// RFC 1884 +bool +DnsUtil::isIpV6Address(const Data& ipAddress) +{ + if (ipAddress.empty()) + { + return false; + } + + // first character must be a hex digit or colon + if (!isxdigit(*ipAddress.data()) && + *ipAddress.data() != ':') + { + return false; + } + + switch (ipAddress.size()) + { + case 1: + return false; + case 2: + return (*(ipAddress.data()+1) == ':' || + *(ipAddress.data()+0) == ':'); + case 3: + return (*(ipAddress.data()+2) == ':' || + *(ipAddress.data()+1) == ':' || + *(ipAddress.data()+0) == ':'); + case 4: + return (*(ipAddress.data()+3) == ':' || + *(ipAddress.data()+2) == ':' || + *(ipAddress.data()+1) == ':' || + *(ipAddress.data()+0) == ':'); + default: + + return (*(ipAddress.data()+4) == ':' || + *(ipAddress.data()+3) == ':' || + *(ipAddress.data()+2) == ':' || + *(ipAddress.data()+1) == ':' || + *(ipAddress.data()+0) == ':'); + } +} + +Data +DnsUtil::canonicalizeIpV6Address(const Data& ipV6Address) +{ +#ifdef USE_IPV6 + struct in6_addr dst; + int res = DnsUtil::inet_pton(ipV6Address, dst); + if (res <= 0) + { + // .bwc. Until we supply an isIpV6Address that works, this is not an + // error on anyone's part but our own. Don't log as a warning/error. + InfoLog(<< ipV6Address << " is not a well formed IPV6 address"); + // .bwc. We should not assert in this function, because + // DnsUtil::isIpV6Address does not do a full validity check. If we have no + // way of determining whether a V6 addr is valid before making this call, + // this call _needs_ to be safe. + // assert(0); + return Data::Empty; + } + return DnsUtil::inet_ntop(dst); +#else + // assert(0); + + return ipV6Address; +#endif +} + +bool +DnsUtil::isIpAddress(const Data& ipAddress) +{ + return isIpV4Address(ipAddress) || isIpV6Address(ipAddress); +} + + +std::list<std::pair<Data,Data> > +DnsUtil::getInterfaces(const Data& matching) +{ + std::list<std::pair<Data,Data> > results; + +#if !defined(WIN32) + + struct ifconf ifc; + + int s = socket( AF_INET, SOCK_DGRAM, 0 ); + assert( s != INVALID_SOCKET ); // can run out of file descs + const int len = 100 * sizeof(struct ifreq); + int maxRet = 40; + + char buf[ len ]; + ifc.ifc_len = len; + ifc.ifc_buf = buf; + + int e = ioctl(s,SIOCGIFCONF,&ifc); + char *ptr = buf; + int tl = ifc.ifc_len; + int count=0; + + while ( (tl > 0) && ( count < maxRet) ) + { + struct ifreq* ifr = (struct ifreq *)ptr; + + count++; + +#if defined(__NetBSD__) || defined(__APPLE__) + int si = sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len; +#else + int si = sizeof(ifr->ifr_name) + sizeof(ifr->ifr_ifru); +#endif + + tl -= si; + ptr += si; + + char* name = ifr->ifr_name; + + struct ifreq ifr2; + ifr2 = *ifr; + + e = ioctl(s,SIOCGIFADDR,&ifr2); + if ( e == -1 ) + { + // no valid address for this interface, skip it + DebugLog (<< "Ignoring interface " << name << " as there is no valid address" ); + continue; + } + struct sockaddr a = ifr2.ifr_addr; + Data ip = DnsUtil::inet_ntop(a); + + e = ioctl(s,SIOCGIFFLAGS,&ifr2); + if ( e == -1 ) + { + // no valid flags for this interface, skip it + DebugLog (<< "Ignoring interface " << name << " as there is no valid flags" ); + continue; + } + short flags = ifr2.ifr_flags; + +#if 0 + // if this does not work on your OS, it is not used yet, + // comment it out and put a note of what OS it does not work for + struct ifmediareq media; + e = ioctl(s,SIOCGIFMEDIA,&media); + int status = media.ifm_status; + int active = media.ifm_active; + DebugLog (<< "Media status=" << hex << status + << " active=" << hex << active << dec ); +#endif + +#if 0 + // if this does not work on your OS, it is not used yet, + // comment it out and put a note of what OS it does not work for + e = ioctl(s,SIOCGIFPHYS,&ifr2); + int phys= ifr2.ifr_phys; + DebugLog (<< "Phys=" << hex << phys << dec ); +#endif + + DebugLog (<< "Considering: " << name << " -> " << ip + << " flags=0x" << hex << flags << dec ); + + if ( (flags & IFF_UP) == 0 ) + { + DebugLog (<< " ignore because: interface is not up"); + continue; + } + + if ( (flags & IFF_LOOPBACK) != 0 ) + { + DebugLog (<< " ignore because: interface is loopback"); + continue; + } + + if ( (flags & IFF_RUNNING) == 0 ) + { + DebugLog (<< " ignore because: interface is not running"); + continue; + } + + if ( (name[0]<'A') || (name[0]>'z') ) // should never happen + { + DebugLog (<< " ignore because: name looks bogus"); + assert(0); + continue; + } + + if (matching == Data::Empty || matching == name) + { + DebugLog (<< " using this"); + results.push_back(std::make_pair(Data(name), ip)); + } + } + + close(s); +#else +#if defined(WIN32) + try + { + return WinCompat::getInterfaces(matching); + } + catch(WinCompat::Exception& e) + { + DebugLog (<< " WinCompat::getInterfaces throws " << e.getMessage()); + return results; + } +#else + assert(0); +#endif +#endif + + return results; +} + +#ifdef __APPLE__ +const Data DnsUtil::UInt8ToStr[]={ + "0.", "1.", "2.", "3.", "4.", "5.", "6.", "7.", + "8.", "9.", "10.", "11.", "12.", "13.", "14.", "15.", + "16.", "17.", "18.", "19.", "20.", "21.", "22.", "23.", + "24.", "25.", "26.", "27.", "28.", "29.", "30.", "31.", + "32.", "33.", "34.", "35.", "36.", "37.", "38.", "39.", + "40.", "41.", "42.", "43.", "44.", "45.", "46.", "47.", + "48.", "49.", "50.", "51.", "52.", "53.", "54.", "55.", + "56.", "57.", "58.", "59.", "60.", "61.", "62.", "63.", + "64.", "65.", "66.", "67.", "68.", "69.", "70.", "71.", + "72.", "73.", "74.", "75.", "76.", "77.", "78.", "79.", + "80.", "81.", "82.", "83.", "84.", "85.", "86.", "87.", + "88.", "89.", "90.", "91.", "92.", "93.", "94.", "95.", + "96.", "97.", "98.", "99.","100.","101.","102.","103.", +"104.","105.","106.","107.","108.","109.","110.","111.", +"112.","113.","114.","115.","116.","117.","118.","119.", +"120.","121.","122.","123.","124.","125.","126.","127.", +"128.","129.","130.","131.","132.","133.","134.","135.", +"136.","137.","138.","139.","140.","141.","142.","143.", +"144.","145.","146.","147.","148.","149.","150.","151.", +"152.","153.","154.","155.","156.","157.","158.","159.", +"160.","161.","162.","163.","164.","165.","166.","167.", +"168.","169.","170.","171.","172.","173.","174.","175.", +"176.","177.","178.","179.","180.","181.","182.","183.", +"184.","185.","186.","187.","188.","189.","190.","191.", +"192.","193.","194.","195.","196.","197.","198.","199.", +"200.","201.","202.","203.","204.","205.","206.","207.", +"208.","209.","210.","211.","212.","213.","214.","215.", +"216.","217.","218.","219.","220.","221.","222.","223.", +"224.","225.","226.","227.","228.","229.","230.","231.", +"232.","233.","234.","235.","236.","237.","238.","239.", +"240.","241.","242.","243.","244.","245.","246.","247.", +"248.","249.","250.","251.","252.","253.","254.","255." +}; +#endif // __APPLE__ + +#if !(defined(WIN32) || defined(__CYGWIN__)) +const char *DnsUtil::inet_ntop(int af, const void* src, char* dst, + size_t size) +{ + +#ifdef __APPLE__ + if(af==AF_INET) + { + // .bwc. inet_ntop4 seems to be implemented with sprintf on OS X. + // This code is about 5-6 times faster. Linux has a well-optimized + // inet_ntop, however. + const UInt8* bytes=(const UInt8*)src; + Data dest(Data::Borrow, dst, sizeof("xxx.xxx.xxx.xxx.")); + dest.clear(); + dest.append(UInt8ToStr[bytes[0]].data(), UInt8ToStr[bytes[0]].size()); + dest.append(UInt8ToStr[bytes[1]].data(), UInt8ToStr[bytes[1]].size()); + dest.append(UInt8ToStr[bytes[2]].data(), UInt8ToStr[bytes[2]].size()); + dest.append(UInt8ToStr[bytes[3]].data(), UInt8ToStr[bytes[3]].size()-1); + return dst; + } + else +#endif // __APPLE__ + { + return ::inet_ntop(af, src, dst, size); + } +} + +int DnsUtil::inet_pton(int af, const char* src, void* dst) +{ + return ::inet_pton(af, src, dst); +} +#else +#define __restrict + +#define NS_INT16SZ 2 +#define NS_INADDRSZ 4 +#define NS_IN6ADDRSZ 16 + +const char* inet_ntop4(const u_char *src, char *dst, size_t size); +#ifdef USE_IPV6 +const char * inet_ntop6(const u_char *src, char *dst, size_t size); +#endif +//adapted from freebsd inet_ntop.c(1.12) and inet_pton.c(1.5) for windows(non-compliant snprinf workaround) +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address, more or less like inet_ntoa() + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a u_char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +const char * +DnsUtil::inet_ntop(int af, const void * __restrict src, char * __restrict dst, + size_t size) +{ + switch (af) + { + case AF_INET: + return (inet_ntop4((const u_char *)src, dst, size)); +#ifdef USE_IPV6 + case AF_INET6: + return (inet_ntop6((const u_char *)src, dst, size)); +#endif + default: + errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + + +static const char fmt[] = "%u.%u.%u.%u"; +const char* +inet_ntop4(const u_char *src, char *dst, size_t size) +{ +#ifdef WIN32 + if ( _snprintf(dst, size, fmt, src[0], src[1], src[2], src[3]) < 0) +#else + if ( snprintf(dst, size, fmt, src[0], src[1], src[2], src[3]) < 0) +#endif + { + errno = ENOSPC; + dst[size-1] = 0; + return NULL; + } + return (dst); +} + + +#ifdef USE_IPV6 +/* const char * + * inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ + +const char * +inet_ntop6(const u_char *src, char *dst, size_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct { int base, len; } best, cur; + u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; + int i; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < NS_IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + cur.base = -1; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen(tp); + break; + } + tp += sprintf(tp, "%x", words[i]); + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == + (NS_IN6ADDRSZ / NS_INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((size_t)(tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} + +static int inet_pton6(const char *src, u_char *dst); +#endif //USE_IPV6 + +static int inet_pton4(const char *src, u_char *dst); + +/* int + * inet_pton(af, src, dst) + * convert from presentation format (which usually means ASCII printable) + * to network format (which is usually some kind of binary format). + * return: + * 1 if the address was valid for the specified address family + * 0 if the address wasn't valid (`dst' is untouched in this case) + * -1 if some other error occurred (`dst' is untouched in this case, too) + * author: + * Paul Vixie, 1996. + */ +int +DnsUtil::inet_pton(int af, const char* src, void* dst) +{ + switch (af) { + case AF_INET: + return (inet_pton4(src, (u_char*) dst)); +#ifdef USE_IPV6 + case AF_INET6: + return (inet_pton6(src, (u_char*) dst)); +#endif + default: + errno = EAFNOSUPPORT; + return (-1); + } + /* NOTREACHED */ +} + +/* int + * inet_pton4(src, dst) + * like inet_aton() but without all the hexadecimal and shorthand. + * return: + * 1 if `src' is a valid dotted quad, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +static const char digits[] = "0123456789"; +static int +inet_pton4(const char *src, u_char *dst) +{ + int saw_digit, octets, ch; + u_char tmp[NS_INADDRSZ], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + u_int newVal = u_int(*tp * 10 + (pch - digits)); + + if (newVal > 255) + return (0); + *tp = newVal; + if (! saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return (0); + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return (0); + + memcpy(dst, tmp, NS_INADDRSZ); + return (1); +} + +#ifdef USE_IPV6 + +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * (1) does not touch `dst' unless it's returning 1. + * (2) :: in a full address is silently ignored. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; +static int +inet_pton6(const char *src, u_char *dst) +{ + u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + u_int val; + + memset((tp = tmp), '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += NS_INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if (saw_xdigit) { + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = int(tp - colonp); + int i; + + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return (0); + memcpy(dst, tmp, NS_IN6ADDRSZ); + return (1); +} + + +#endif +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + +/* Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + diff --git a/src/libs/resiprocate/rutil/DnsUtil.hxx b/src/libs/resiprocate/rutil/DnsUtil.hxx new file mode 100644 index 00000000..414a3049 --- /dev/null +++ b/src/libs/resiprocate/rutil/DnsUtil.hxx @@ -0,0 +1,206 @@ +#if !defined(RESIP_DNSUTIL_HXX) +#define RESIP_DNSUTIL_HXX + +#include <list> +#include "rutil/Socket.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/Data.hxx" + +#ifndef WIN32 +#include <netinet/in.h> +#else +#include <Ws2tcpip.h> +#endif + +struct in_addr; +struct in6_addr; +namespace resip +{ + +class Tuple; + +/** + @brief Provides a collection of utility functions for + manipulating DNS names and IP addresses and discovering + details about the local interfaces + @ingroup network + */ +class DnsUtil +{ + public: + class Exception : public BaseException + { + public: + Exception(const Data& msg, + const Data& file, + const int line) + : BaseException(msg, file, line) {} + protected: + virtual const char* name() const { return "DnsUtil::Exception"; } + }; + + /** @returns the fully qualified local host name as the host + * currently knows it ala gethostname(3) + */ + + static Data getLocalHostName(); + + /** @returns the suffix after the first "." in whatever getLocalHostName returns */ + static Data getLocalDomainName(); + + /** Gets the IP address of "the" local interface. Note that this will not work + * on systems with more than one ethernet interface. + * @deprecated Very few real systems have only one interface (loopback plus + * physical, vpns, wireless and wired, etc.) Use getInterfaces + * instead. + */ + + static Data getLocalIpAddress(const Data& defaultInterface=Data::Empty) ; + + // returns pair of interface name, ip address + /** @returns a list of interface name, IP addresses pairs of all available + * interfaces (note that some of these may be v4 and others v6. + */ + static std::list<std::pair<Data,Data> > getInterfaces(const Data& matchingInterface=Data::Empty); + + // wrappers for the not so ubiquitous inet_pton, inet_ntop (e.g. WIN32) + + /// Converts from the network format to presentation + /// format. That is, it converts from struct in_addr to + /// character representation of the IPv4 address. + static Data inet_ntop(const struct in_addr& addr); + + /// Converts from the network format to presentation + /// format. Converts from struct sockaddr to character + /// representation of the IPv4 address. + static Data inet_ntop(const struct sockaddr& addr); + + /// Convert from the presentation format of the IPv4 address to + /// struct in_addr. + static int inet_pton(const Data& printableIp, struct in_addr& dst); + + static bool isIpAddress(const Data& ipAddress); + static bool isIpV4Address(const Data& ipAddress); + /** + @brief based on RFC 1884 + @example + @code + Data addr("5f1b:df00:ce3e:e200:20:800:2b37:6426"); + cerr << "!! "<< addr << endl; + assert(DnsUtil::isIpV6Address(addr)); + @endcode + */ + static bool isIpV6Address(const Data& ipAddress); + +#ifdef IPPROTO_IPV6 + /// Converts from the network format to presentation + /// format. That is, it converts from struct in_addr6 to + /// character representation of the IPv6 address. + static Data inet_ntop(const struct in6_addr& addr); + + /// Convert from the presentation format of the IPv6 address to + /// struct in_addr6. + static int inet_pton(const Data& printableIp, struct in6_addr& dst); +#endif + + //pass-throughs when supported, actual implemenation in the WIN32 case + + /// Converts from the network format to presentation + /// format. + /// + /// @param af the address family (AF_INET, AF_INET6) + /// + /// @param src the address of the networking representation to + /// be converted (often of type struct in_addr *) + /// + /// @param dst the address where presentation format will be stored + /// + /// @size the size of the dst + static const char * inet_ntop(int af, const void* src, char* dst, size_t size); + +#ifdef __APPLE__ + static const Data UInt8ToStr[256]; +#endif // __APPLE__ + + /// Converts from the presentation format to network + /// format. + /// + /// @param af the address family (AF_INET, AF_INET6) + /// + /// @param src the address of the presentation representation to + /// be converted + /// + /// @param dst the address where presentation format will be + /// stored (struct in_addr *, or struct in_addr6 *) + static int inet_pton(int af, const char * src, void * dst); + + + // so string (case) comparison will work + // or something + /** Converts the printable form of an IPv6 address into + * consistent format so that string comparisons will do + * what you expect. + * For instance, XXXX:0:0:0:YYYY:192.168.2.233 will be + * converted to XXXX::::YYYY:192.168.2.233. + * Currently, this is realized by (inet_ntop(inet_pton(input)). + */ + static Data canonicalizeIpV6Address(const Data& ipV6Address); + + /// Used to synchronously query A records - only for test code usage + static std::list<Data> lookupARecords(const Data& host); + +}; + +} + + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/FdPoll.cxx b/src/libs/resiprocate/rutil/FdPoll.cxx new file mode 100644 index 00000000..19a17197 --- /dev/null +++ b/src/libs/resiprocate/rutil/FdPoll.cxx @@ -0,0 +1,947 @@ +#include <assert.h> +#include <string.h> + +#include "rutil/FdPoll.hxx" +#include "rutil/FdSetIOObserver.hxx" +#include "rutil/Logger.hxx" +#include "rutil/BaseException.hxx" + +#include <vector> + +#ifdef RESIP_POLL_IMPL_EPOLL +# include <sys/epoll.h> +#endif + +using namespace resip; +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +/***************************************************************** + * + * FdPollItemIf and FdPollItemBase impl + * + *****************************************************************/ + +FdPollItemIf::~FdPollItemIf() +{ +} + +FdPollItemBase::FdPollItemBase(FdPollGrp *grp, Socket fd, FdPollEventMask mask) : + mPollGrp(grp), mPollSocket(fd) +{ + if (mPollGrp) + mPollHandle = mPollGrp->addPollItem(fd, mask, this); +} + +FdPollItemBase::~FdPollItemBase() +{ + if (mPollGrp) + mPollGrp->delPollItem(mPollHandle); +} + +/***************************************************************** + * + * FdPollGrp + * + * Implementation for some of the base class methods. + * While some of these are epoll-specific, we can (and do) implement + * them at this level. + * For now we use delegation for the impl data structures + * rather than inhieritance. Long term, not sure which will + * be cleaner. + * + *****************************************************************/ + +FdPollGrp::FdPollGrp() +{ +} + +FdPollGrp::~FdPollGrp() +{ +} + +void +FdPollGrp::processItem(FdPollItemIf *item, FdPollEventMask mask) +{ + try + { + item->processPollEvent( mask ); + } + catch(BaseException& e) + { + // kill it or something? + ErrLog(<<"Exception thrown for FdPollItem: " << e); + } + item = NULL; // WATCHOUT: item may have been deleted + /* + * If FPEM_Error was reported, should really make sure it was deleted + * or disabled from polling. Otherwise were in stuck in an infinite loop. + * But difficult to do that checking robustly until we serials the items. + */ +} + +int +FdPollGrp::getEPollFd() const +{ + return -1; +} + +/***************************************************************** + * + * FdPollImplFdSet + * + *****************************************************************/ + +/** + This is an implemention built around FdSet, which in turn is built + around select(). As such, it should work on all platforms. The + number of concurrent fds is limited by your platform's select call. +**/ + +namespace resip +{ + +class FdPollItemFdSetInfo +{ + public: + FdPollItemFdSetInfo() + : mSocketFd(INVALID_SOCKET), mItemObj(0), mEvMask(0), mNextIdx(-1) + { + } + + Socket mSocketFd; // socket + FdPollItemIf* mItemObj; // callback object + FdPollEventMask mEvMask; // events the application wants + int mNextIdx; // next link for live or free list +}; + + + +class FdPollImplFdSet : public FdPollGrp +{ + public: + FdPollImplFdSet(); + ~FdPollImplFdSet(); + + virtual const char* getImplName() const { return "fdset"; } + + virtual FdPollItemHandle addPollItem(Socket fd, + FdPollEventMask newMask, FdPollItemIf *item); + virtual void modPollItem(FdPollItemHandle handle, + FdPollEventMask newMask); + virtual void delPollItem(FdPollItemHandle handle); + + virtual void registerFdSetIOObserver(FdSetIOObserver& observer); + virtual void unregisterFdSetIOObserver(FdSetIOObserver& observer); + + virtual bool waitAndProcess(int ms=0); + virtual void buildFdSet(FdSet& fdSet); + virtual bool processFdSet(FdSet& fdset); + + protected: + virtual unsigned int buildFdSetForObservers(FdSet& fdSet); + void killCache(Socket fd); + + std::vector<FdPollItemFdSetInfo> mItems; + std::vector<FdSetIOObserver*> mFdSetObservers; + + /* + * The ItemInfos are stored in a vector (above) that grows as needed. + * Every Info is in one single-linked list, either the "Live" list + * or the "Free" list. This is somewhat like using + * boost::intrusive::slist, except we use indices not pointers + * since the vector may reallocate and move around. + */ + int mLiveHeadIdx; + int mFreeHeadIdx; + + /* + * This is temporary cache of poll events. It is a member (and + * not on stack) for two reasons: (1) simpler memory management, + * and (2) so delPollItem() can traverse it and clean up. + */ + FdSet mSelectSet; +}; + +}; // namespace + +// NOTE: shift by one so that idx=0 doesn't have NULL handle +#define IMPL_FDSET_IdxToHandle(idx) ((FdPollItemHandle)( ((char*)0) + ((idx)+1) )) +#define IMPL_FDSET_HandleToIdx(handle) ( ((char*)(handle)) - ((char*)0) - 1) + +FdPollImplFdSet::FdPollImplFdSet() + : mLiveHeadIdx(-1), mFreeHeadIdx(-1) +{ +} + +FdPollImplFdSet::~FdPollImplFdSet() +{ + // assert( mEvCacheLen == 0 ); // poll not active + unsigned itemIdx; + for (itemIdx=0; itemIdx < mItems.size(); itemIdx++) + { + FdPollItemFdSetInfo& info = mItems[itemIdx]; + if (info.mItemObj) + { + CritLog(<<"FdPollItem idx="<<itemIdx + <<" not deleted prior to destruction"); + } + } +} + +FdPollItemHandle +FdPollImplFdSet::addPollItem(Socket fd, FdPollEventMask newMask, FdPollItemIf *item) +{ + // if this isn't true then the linked lists will get messed up + assert(item); + assert(fd!=INVALID_SOCKET); + + unsigned useIdx; + if ( mFreeHeadIdx >= 0 ) + { + useIdx = mFreeHeadIdx; + mFreeHeadIdx = mItems[useIdx].mNextIdx; + } + else + { + useIdx = mItems.size(); + unsigned newsz = 10+useIdx + useIdx/3; // plus 30% margin + // WATCHOUT: below may trigger re-allocation, invalidating any iters + // We don't use iters (only indices), but need to watchout for + // cached pointers + mItems.resize(newsz); + // push new items onto the free list + unsigned itemIdx; + for (itemIdx=useIdx+1; itemIdx < newsz; itemIdx++) + { + mItems[itemIdx].mNextIdx = mFreeHeadIdx; + mFreeHeadIdx = itemIdx; + } + } + FdPollItemFdSetInfo& info = mItems[useIdx]; + info.mItemObj = item; + info.mSocketFd = fd; + info.mEvMask = newMask; + info.mNextIdx = mLiveHeadIdx; + mLiveHeadIdx = useIdx; + + if ( info.mEvMask & FPEM_Read ) + mSelectSet.setRead(info.mSocketFd); + if ( info.mEvMask & FPEM_Write ) + mSelectSet.setWrite(info.mSocketFd); + if ( info.mEvMask & FPEM_Error ) + mSelectSet.setExcept(info.mSocketFd); + + return IMPL_FDSET_IdxToHandle(useIdx); +} + +void +FdPollImplFdSet::modPollItem(const FdPollItemHandle handle, FdPollEventMask newMask) +{ + int useIdx = IMPL_FDSET_HandleToIdx(handle); + assert(useIdx>=0 && ((unsigned)useIdx) < mItems.size()); + FdPollItemFdSetInfo& info = mItems[useIdx]; + assert(info.mSocketFd!=INVALID_SOCKET); + assert(info.mItemObj); + info.mEvMask = newMask; + + killCache(info.mSocketFd); + if ( info.mEvMask & FPEM_Read ) + mSelectSet.setRead(info.mSocketFd); + if ( info.mEvMask & FPEM_Write ) + mSelectSet.setWrite(info.mSocketFd); + if ( info.mEvMask & FPEM_Error ) + mSelectSet.setExcept(info.mSocketFd); +} + +void +FdPollImplFdSet::delPollItem(FdPollItemHandle handle) +{ + int useIdx = IMPL_FDSET_HandleToIdx(handle); + //DebugLog(<<"deleting epoll item fd="<<fd); + assert(useIdx>=0 && ((unsigned)useIdx) < mItems.size()); + FdPollItemFdSetInfo& info = mItems[useIdx]; + assert(info.mSocketFd!=INVALID_SOCKET); + assert(info.mItemObj); + killCache(info.mSocketFd); + // we don't change the lists here since the select loop might + // be iterating. Just mark it as dead and gc it later. + info.mSocketFd = INVALID_SOCKET; + info.mItemObj = NULL; + info.mEvMask = 0; +} + +void +FdPollImplFdSet::registerFdSetIOObserver(FdSetIOObserver& observer) +{ + // .bwc. Could make this sorted. Probably not worth the trouble. + mFdSetObservers.push_back(&observer); +} + +void +FdPollImplFdSet::unregisterFdSetIOObserver(FdSetIOObserver& observer) +{ + // .bwc. Could make this sorted. Probably not worth the trouble. + for(std::vector<FdSetIOObserver*>::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + if(*o==&observer) + { + mFdSetObservers.erase(o); + return; + } + } +} + + +/** + There is a boundary case: + 1. fdA and fdB are added to epoll + 2. events occur on fdA and fdB + 2. waitAndProcess() select and gets events for fdA and fdB + 3. handler for fdA deletes fdB (closing fd) + 5. handler (same or differnt) opens new fd, gets fd as fdB, and adds + it to us but under different object + 6. cache processes "old" fdB event masks but binds it to the new + (wrong) object + + For read or write events it would be relatively harmless to + pass these events to the new object (all objects should be prepared + to get EAGAIN). But passing an error event could incorrectly kill + the wrong object. + + To prevent this, we kill the events in the mSelectSet. In POSIX, + I'm pretty sure this is always safe. In Windows, I don't know what + happens if the fd isn't already in the FdSet. +**/ +void +FdPollImplFdSet::killCache(Socket fd) +{ + mSelectSet.clear(fd); +} + + +bool +FdPollImplFdSet::waitAndProcess(int ms) +{ + if(ms<0) + { + // On Linux, passing a NULL timeout ptr to select() will wait + // forever, but I don't want to trust that on all platforms. + // So use 60sec as approximation of "forever". + // Use 60sec b/c fits in short. + ms = 60*1000; + } + + // Create copy; is cheaper than rebuilding from scratch every time. + FdSet fdset(mSelectSet); + ms = resipMin(buildFdSetForObservers(fdset), (unsigned int)ms); + + // Step 2: Select on our built FdSet + int numReady = fdset.selectMilliSeconds(ms); + if ( numReady < 0 ) + { + int err = getErrno(); + if ( err!=EINTR ) + { + CritLog(<<"select() failed: "<<strerror(err)); + assert(0); // .kw. not sure correct behavior... + } + return false; + } + + if ( numReady==0 ) + { + return false; // timer expired + } + + return processFdSet(fdset); +} + +void +FdPollImplFdSet::buildFdSet(FdSet& fdset) +{ + int* prevIdxRef=&mLiveHeadIdx; + int loopCnt = 0; + int itemIdx; + + // Step 1: build a new FdSet from the Items vector + while ( (itemIdx = *prevIdxRef) != -1 ) + { + assert( ++loopCnt < 99123123 ); + FdPollItemFdSetInfo& info = mItems[itemIdx]; + if ( info.mItemObj==0 ) + { + // item was deleted, need to garbage collect + assert( info.mEvMask==0 ); + // unlink from live list + *prevIdxRef = info.mNextIdx; + // link into free list + info.mNextIdx = mFreeHeadIdx; + mFreeHeadIdx = itemIdx; + continue; + } + if ( info.mEvMask!=0 ) + { + assert(info.mSocketFd!=INVALID_SOCKET); + if ( info.mEvMask & FPEM_Read ) + fdset.setRead(info.mSocketFd); + if ( info.mEvMask & FPEM_Write ) + fdset.setWrite(info.mSocketFd); + if ( info.mEvMask & FPEM_Error ) + fdset.setExcept(info.mSocketFd); + } + prevIdxRef = &info.mNextIdx; + } + + // Allow any FdSetIOObservers a crack at the FdSet; we can't really optimize + // this part. + buildFdSetForObservers(fdset); +} + +unsigned int +FdPollImplFdSet::buildFdSetForObservers(FdSet& fdset) +{ + unsigned int ms=INT_MAX; + for(std::vector<FdSetIOObserver*>::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + (*o)->buildFdSet(fdset); + ms = resipMin(ms, (*o)->getTimeTillNextProcessMS()); + } + return ms; +} + +bool +FdPollImplFdSet::processFdSet(FdSet& fdset) +{ + bool didsomething = false; + int itemIdx; + int* prevIdxRef = &mLiveHeadIdx; + int loopCnt = 0; + + // Step 3: Invoke callbacks + // Could take advantage of early via numReady, but book keeping + // seems tedious especially if items are deleted during walk + while ( (itemIdx = *prevIdxRef) != -1 ) + { + FdPollItemFdSetInfo& info = mItems[itemIdx]; + assert( ++loopCnt < 99123123 ); + if ( info.mEvMask!=0 && info.mItemObj!=0 ) + { + FdPollEventMask usrMask = 0; + assert(info.mSocketFd!=INVALID_SOCKET); + if ( fdset.readyToRead(info.mSocketFd) ) + usrMask |= FPEM_Read; + if ( fdset.readyToWrite(info.mSocketFd) ) + usrMask |= FPEM_Write; + if ( fdset.hasException(info.mSocketFd) ) + usrMask |= FPEM_Error; + + // items's mask may have changed since select occured, so mask it again + usrMask &= info.mEvMask; + if ( usrMask ) + { + processItem(info.mItemObj, usrMask); + didsomething = true; + } + } + // WATCHOUT: {info} may have moved due to add during processItem() + // set pointer using index, not {info} + prevIdxRef = &mItems[itemIdx].mNextIdx; + } + + // Step 3.1: Invoke callbacks on any FdSetIOObservers + for(std::vector<FdSetIOObserver*>::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + // This is not strictly correct; we do not know if this observer actually + // put any FDs in the set, or if any of these FDs ended up being ready. + // Eventually, it would be nice to have process() return whether any + // actual IO was performed. + didsomething=true; + (*o)->process(fdset); + } + + return didsomething; +} + + +// end of ImplFdSet + + +/***************************************************************** + * + * FdPollImplEpoll + * + *****************************************************************/ + +#ifdef RESIP_POLL_IMPL_EPOLL + +namespace resip +{ + + + +class FdPollImplEpoll : public FdPollGrp +{ + public: + FdPollImplEpoll(); + ~FdPollImplEpoll(); + + virtual const char* getImplName() const { return "epoll"; } + + virtual FdPollItemHandle addPollItem(Socket fd, + FdPollEventMask newMask, FdPollItemIf *item); + virtual void modPollItem(FdPollItemHandle handle, + FdPollEventMask newMask); + virtual void delPollItem(FdPollItemHandle handle); + virtual void registerFdSetIOObserver(FdSetIOObserver& observer); + virtual void unregisterFdSetIOObserver(FdSetIOObserver& observer); + + virtual bool waitAndProcess(int ms=0); + + /// See baseclass. This is integer fd, not Socket + virtual int getEPollFd() const { return mEPollFd; } + virtual void buildFdSet(FdSet& fdSet); + virtual bool processFdSet(FdSet& fdset); + + protected: + void killCache(Socket fd); + bool epollWait(int ms); + + std::vector<FdPollItemIf*> mItems; // indexed by fd + std::vector<FdSetIOObserver*> mFdSetObservers; + int mEPollFd; // from epoll_create() + + /* + * This is temporary cache of poll events. It is a member (and + * not on stack) for two reasons: (1) simpler memory management, + * and (2) so delPollItem() can traverse it and clean up. + */ + std::vector<struct epoll_event> mEvCache; + int mEvCacheCur; + int mEvCacheLen; +}; + +}; // namespace + +// NOTE: shift by one so that fd=0 doesn't have NULL handle +#define IMPL_EPOLL_FdToHandle(fd) ((FdPollItemHandle)( ((char*)0) + ((fd)+1) )) +#define IMPL_EPOLL_HandleToFd(handle) ( ((char*)(handle)) - ((char*)0) - 1) + +FdPollImplEpoll::FdPollImplEpoll() : + mEPollFd(-1) +{ + int sz = 200; // ignored + if ( (mEPollFd = epoll_create(sz)) < 0 ) + { + CritLog(<<"epoll_create() failed: "<<strerror(errno)); + abort(); + } + mEvCache.resize(sz); + mEvCacheCur = mEvCacheLen = 0; +} + +FdPollImplEpoll::~FdPollImplEpoll() +{ + assert( mEvCacheLen == 0 ); // poll not active + unsigned itemIdx; + for (itemIdx=0; itemIdx < mItems.size(); itemIdx++) + { + FdPollItemIf *item = mItems[itemIdx]; + if (item) + { + CritLog(<<"FdPollItem idx="<<itemIdx + <<" not deleted prior to destruction"); + } + } + if (mEPollFd != -1) + { + close(mEPollFd); + } +} + +static inline unsigned short +CvtSysToUsrMask(unsigned long sysMask) +{ + unsigned usrMask = 0; + if ( sysMask & EPOLLIN ) + usrMask |= FPEM_Read; + if ( sysMask & EPOLLOUT ) + usrMask |= FPEM_Write; + if ( sysMask & EPOLLERR ) + usrMask |= FPEM_Error|FPEM_Read|FPEM_Write; + // NOTE: above, fake read and write if error to encourage + // apps to actually do something about it + return usrMask; +} + +static inline unsigned long +CvtUsrToSysMask(unsigned short usrMask) +{ + unsigned long sysMask = 0; + if ( usrMask & FPEM_Read ) + sysMask |= EPOLLIN; + if ( usrMask & FPEM_Write ) + sysMask |= EPOLLOUT; + if ( usrMask & FPEM_Edge ) + sysMask |= EPOLLET; + return sysMask; +} + +FdPollItemHandle +FdPollImplEpoll::addPollItem(Socket fd, FdPollEventMask newMask, FdPollItemIf *item) +{ + assert(fd>=0); + //DebugLog(<<"adding epoll item fd="<<fd); + if (mItems.size() <= (unsigned)fd) + { + unsigned newsz = fd+1; + newsz += newsz/3; // plus 30% margin + // WATCHOUT: below may trigger re-allocation, invalidating any iters + // Currently only iterator is destructor, so should be safe + mItems.resize(newsz); + } + FdPollItemIf *olditem = mItems[fd]; + assert(olditem == NULL); // what is right thing to do? + mItems[fd] = item; + struct epoll_event ev; + memset(&ev, 0, sizeof(ev)); // make valgrind happy + ev.events = CvtUsrToSysMask(newMask); + ev.data.fd = fd; + if (epoll_ctl(mEPollFd, EPOLL_CTL_ADD, fd, &ev) < 0) + { + CritLog(<<"epoll_ctl(ADD) failed: " << strerror(errno)); + abort(); + } + return IMPL_EPOLL_FdToHandle(fd); +} + +void +FdPollImplEpoll::modPollItem(const FdPollItemHandle handle, FdPollEventMask newMask) +{ + int fd = IMPL_EPOLL_HandleToFd(handle); + assert(fd>=0 && ((unsigned)fd) < mItems.size()); + assert(mItems[fd] != NULL); + + struct epoll_event ev; + memset(&ev, 0, sizeof(ev)); // make valgrind happy + ev.events = CvtUsrToSysMask(newMask); + ev.data.fd = fd; + if (epoll_ctl(mEPollFd, EPOLL_CTL_MOD, fd, &ev) < 0) + { + CritLog(<<"epoll_ctl(MOD) failed: "<<strerror(errno)); + abort(); + } +} + +void +FdPollImplEpoll::delPollItem(FdPollItemHandle handle) +{ + int fd = IMPL_EPOLL_HandleToFd(handle); + //DebugLog(<<"deleting epoll item fd="<<fd); + assert(fd>=0 && ((unsigned)fd) < mItems.size()); + assert( mItems[fd] != NULL ); + mItems[fd] = NULL; + if (epoll_ctl(mEPollFd, EPOLL_CTL_DEL, fd, NULL) < 0) + { + CritLog(<<"epoll_ctl(DEL) fd="<<fd<<" failed: " << strerror(errno)); + abort(); + } + killCache(fd); +} + +void +FdPollImplEpoll::registerFdSetIOObserver(FdSetIOObserver& observer) +{ + // .bwc. Could make this sorted. Probably not worth the trouble. + mFdSetObservers.push_back(&observer); +} + +void +FdPollImplEpoll::unregisterFdSetIOObserver(FdSetIOObserver& observer) +{ + // .bwc. Could make this sorted. Probably not worth the trouble. + for(std::vector<FdSetIOObserver*>::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + if(*o==&observer) + { + mFdSetObservers.erase(o); + return; + } + } +} + + +/** + There is a boundary case: + 1. fdA and fdB are added to epoll + 2. events occur on fdA and fdB + 2. waitAndProcess() reads queue for fdA and fdB into its cache + 3. handler for fdA deletes fdB (closing fd) + 5. handler (same or differnt) opens new fd, gets fd as fdB, and adds + it to epoll but under different object + 6. cache processes "old" fdB but binds it to the new (wrong) object + + For read or write events it would be relatively harmless to + pass these events to the new object (all objects should be prepared + to get EAGAIN). But passing an error event could incorrectly kill + the wrong object. + + To prevent this, we walk the cache and kill any events for our fd. + In theory, the kernel does the same. + + An alternative approach would be use a serial number counter, + as a lifetime indicator for each fd, and store both a 32-bit serial + and 32-bit fd into the epoll event in the kernel. We could then + recognize stale events. +**/ +void +FdPollImplEpoll::killCache(int fd) +{ + int ne; + for (ne=mEvCacheCur; ne < mEvCacheLen; ne++) + { + if ( mEvCache[ne].data.fd == fd ) + { + mEvCache[ne].data.fd = INVALID_SOCKET; + } + } +} + + +bool +FdPollImplEpoll::waitAndProcess(int ms) +{ + bool didSomething = false; + int waitMs = ms; + assert( mEvCache.size() > 0 ); + + if(!mFdSetObservers.empty()) + { + if(ms < 0) + { + ms=INT_MAX; + waitMs=INT_MAX; + } + + // Warning; big fat hack. This is likely to be a tad inefficient, and this + // is why we want to move away from FdSetIOObserver, at least in + // conjunction with stuff that uses epoll. The only holdout right now is + // the cares DNS code. + // Also, a fair bit of duplicated code here. + + FdSet fdset; + buildFdSet(fdset); // add our epoll fd, and fds from mFdSetObservers + + for(std::vector<FdSetIOObserver*>::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + ms = resipMin((unsigned int)ms, (*o)->getTimeTillNextProcessMS()); + } + + // Avoid waiting too much; this ends up overcompensating unless the + // select() times out, but it is better than just setting to 0. We could + // record the time taken by the select() call, but this would be more + // expensive. + waitMs -= ms; + + int numReady = fdset.selectMilliSeconds(ms); + + // Should we still do this? If our epoll fd is not marked ready, should we + // do the epoll_wait below? I want to say no... + if ( numReady < 0 ) + { + int err = getErrno(); + if ( err!=EINTR ) + { + CritLog(<<"select() failed: "<<strerror(err)); + assert(0); // .kw. not sure correct behavior... + } + return false; + } + if ( numReady==0 ) + return false; // timer expired + + didSomething |= processFdSet(fdset); + } + + didSomething |= epollWait(waitMs); + return didSomething; +} + +void +FdPollImplEpoll::buildFdSet(FdSet& fdset) +{ + int fd = getEPollFd(); + if (fd != -1) + { + fdset.setRead(fd); + } + for(std::vector<FdSetIOObserver*>::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + (*o)->buildFdSet(fdset); + } +} + +bool +FdPollImplEpoll::processFdSet(FdSet& fdset) +{ + bool didsomething=false; + for(std::vector<FdSetIOObserver*>::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + // This is not strictly correct; we do not know if this observer + // actually put any FDs in the set, or if any of these FDs ended up + // being ready. + // Eventually, it would be nice to have process() return whether any + // actual IO was performed. + didsomething=true; + (*o)->process(fdset); + } + + int fd = getEPollFd(); + if (fd !=- 1 && fdset.readyToRead(fd)) + { + epollWait(0); + } + return didsomething; +} + +bool +FdPollImplEpoll::epollWait(int waitMs) +{ + bool maybeMore; + bool didsomething=false; + do + { + int nfds = epoll_wait(mEPollFd, &mEvCache.front(), mEvCache.size(), waitMs); + if (nfds < 0) + { + if (errno==EINTR) + { + // signal handler (like alarm) broke loop. generally ok + DebugLog(<<"epoll_wait() broken by EINTR"); + nfds = 0; // clean-up and return. could add return code + // to indicate this, but not needed by us + } + else + { + CritLog(<<"epoll_wait() failed: " << strerror(errno)); + abort(); // TBD: just throw instead? + } + } + waitMs = 0; // don't wait anymore + mEvCacheLen = nfds; // for killCache() + maybeMore = ( ((unsigned)nfds)==mEvCache.size()) ? 1 : 0; + int ne; + for (ne=0; ne < nfds; ne++) + { + int fd = mEvCache[ne].data.fd; + if (fd == INVALID_SOCKET) + { + continue; // was killed by killCache() + } + int sysEvtMask = mEvCache[ne].events; + assert(fd>=0 && fd < (int)mItems.size()); + FdPollItemIf *item = mItems[fd]; + if (item == NULL) + { + /* this can happen if item was deleted after + * event was generated in kernel, etc. */ + continue; + } + mEvCacheCur = ne; // for killCache() + processItem(item, CvtSysToUsrMask(sysEvtMask)); + item = NULL; // WATCHOUT: item may not exist anymore + didsomething = true; + } + mEvCacheLen = 0; + } while (maybeMore); + return didsomething; +} + +#endif // RESIP_POLL_IMPL_EPOLL + +/***************************************************************** + * + * Factory + * + *****************************************************************/ + +/*static*/FdPollGrp* +FdPollGrp::create(const char *implName) +{ + if ( implName==0 || implName[0]==0 || strcmp(implName,"event")==0 ) + implName = 0; // pick the first (best) one supported +#ifdef RESIP_POLL_IMPL_EPOLL + if ( implName==0 || strcmp(implName,"epoll")==0 ) + { + return new FdPollImplEpoll(); + } +#endif + if ( implName==0 || strcmp(implName,"fdset")==0 ) + { + return new FdPollImplFdSet(); + } + assert(0); + return NULL; +} + +/*static*/const char* +FdPollGrp::getImplList() +{ + // .kw. this isn't really scalable approach if we get a lot of impls + // but it works for now +#ifdef RESIP_POLL_IMPL_EPOLL + return "event|epoll|fdset"; +#else + return "event|fdset"; +#endif +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Jacob Butcher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/FdPoll.hxx b/src/libs/resiprocate/rutil/FdPoll.hxx new file mode 100644 index 00000000..e0e36e55 --- /dev/null +++ b/src/libs/resiprocate/rutil/FdPoll.hxx @@ -0,0 +1,159 @@ +#if !defined(RESIP_FDPOLL_HXX) +#define RESIP_FDPOLL_HXX + +#include "rutil/Socket.hxx" + +/* The Makefile system may define the following: + * HAVE_EPOLL: system call epoll() is available + * + * An implementation based upon FdSet (and select()) is always available. + * + * This file and class is somewhat misnamed. It should really be + * called "SocketEvent" or such. The name "FdPoll" originated + * from an epoll-specific implementation. + */ + +#if defined(HAVE_EPOLL) +#define RESIP_POLL_IMPL_EPOLL // Only one currently implemented +#endif + +namespace resip { + + +typedef unsigned short FdPollEventMask; +#define FPEM_Read 0x0001 // POLLIN +#define FPEM_Write 0x0002 // POLLOUT +#define FPEM_Error 0x0004 // POLLERR (select exception) +#define FPEM_Edge 0x4000 // EPOLLET + +class FdPollGrp; + +/** + * This is opaque type used to identify a particular Item. It is assigned + * when Item is allocated, and then used to modify or destroy the Item. + * NOTE: FdPollItemFake doesn't exist: it is fictious, thus this type + * can never be deferenced. + */ +typedef struct FdPollItemFake* FdPollItemHandle; + +class FdPollItemIf +{ + //friend class FdPollGrp; + public: + FdPollItemIf() { }; + virtual ~FdPollItemIf(); + + /** + Called by PollGrp when activity is possible + **/ + virtual void processPollEvent(FdPollEventMask mask) = 0; +}; + +class FdPollItemBase : public FdPollItemIf +{ + //friend class FdPollGrp; + public: + FdPollItemBase(FdPollGrp *grp, Socket fd, FdPollEventMask mask); + virtual ~FdPollItemBase(); + + protected: + + FdPollGrp* mPollGrp; + Socket mPollSocket; + FdPollItemHandle mPollHandle; +}; + +class FdSetIOObserver; + +class FdPollGrp +{ + public: + FdPollGrp(); + virtual ~FdPollGrp(); + + /// factory + static FdPollGrp* create(const char *implName=NULL); + /// Return candidate impl names with vertical bar (|) between them + /// Intended for help messages + static const char* getImplList(); + + virtual const char* getImplName() const = 0; + + virtual FdPollItemHandle addPollItem(Socket sock, FdPollEventMask newMask, FdPollItemIf *item) = 0; + virtual void modPollItem(FdPollItemHandle handle, FdPollEventMask newMask) = 0; + virtual void delPollItem(FdPollItemHandle handle) = 0; + + virtual void registerFdSetIOObserver(FdSetIOObserver& observer) = 0; + virtual void unregisterFdSetIOObserver(FdSetIOObserver& observer) = 0; + + /// Wait at most {ms} milliseconds. If any file activity has + /// already occurs or occurs before {ms} expires, then + /// FdPollItem will be informed (via cb method) and this method will + /// return. Returns true iff any file activity occured. + /// ms<0: wait forever, ms=0: don't wait, ms>0: wait this long + /// NOTE: "forever" may be a little as 60sec or as much as forever + virtual bool waitAndProcess(int ms=0) = 0; + + /// get the epoll-fd (epoll_create()) + /// This is fd (type int), not Socket. It may be -1 if epoll + /// is not enabled. + virtual int getEPollFd() const; + + virtual void buildFdSet(FdSet& fdSet)=0; + virtual bool processFdSet(FdSet& fdset)=0; + + protected: + void processItem(FdPollItemIf *item, FdPollEventMask mask); +}; + + + +/////////////////////////////////////////////////////////////////////////////// + +} // namespace resip + +#endif //!defined(RESIP_FDPOLL_HXX) + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Jacob Butcher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/FdSetIOObserver.hxx b/src/libs/resiprocate/rutil/FdSetIOObserver.hxx new file mode 100644 index 00000000..12641221 --- /dev/null +++ b/src/libs/resiprocate/rutil/FdSetIOObserver.hxx @@ -0,0 +1,93 @@ +#ifndef FdSetIOObserver_Include_Guard +#define FdSetIOObserver_Include_Guard + +namespace resip +{ +class FdSet; + +/** + An interface class for elements that use an FdSet to watch for IO. This is in + contrast to an element that uses event-driven IO. +*/ +class FdSetIOObserver +{ + public: + FdSetIOObserver(){} + virtual ~FdSetIOObserver(){} + + /** + Add any FDs that we are interested in watching to an fdset, with the + understanding that a select() call will be made immediately after. + @param fdset The FdSet to be augmented + */ + virtual void buildFdSet(FdSet& fdset) = 0; + + /** + Returns the maximum timeout this object is willing to tolerate on the + select call that is to be made, to prevent starvation of work that is + not IO-based. + @return The maximum select() timeout to be used, in milliseconds. To + indicate that this object does not care, return UINT_MAX. 0 + indicates that a poll select() should be performed. + */ + virtual unsigned int getTimeTillNextProcessMS() = 0; + + /** + Called once select() returns; this allows this object to inspect which + of its FDs are ready, and perform any necessary IO with them. + @param fdset The FdSet after the call to select(). + */ + virtual void process(FdSet& fdset) = 0; +}; +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Fifo.hxx b/src/libs/resiprocate/rutil/Fifo.hxx new file mode 100644 index 00000000..303b44c1 --- /dev/null +++ b/src/libs/resiprocate/rutil/Fifo.hxx @@ -0,0 +1,206 @@ +#if !defined(RESIP_FIFO_HXX) +#define RESIP_FIFO_HXX + +#include <cassert> +#include "rutil/AbstractFifo.hxx" +#include "rutil/SelectInterruptor.hxx" + +namespace resip +{ + +/** + @brief A templated, threadsafe message-queue class. +*/ +template < class Msg > +class Fifo : public AbstractFifo<Msg*> +{ + public: + Fifo(AsyncProcessHandler* interruptor=0); + virtual ~Fifo(); + + using AbstractFifo<Msg*>::mFifo; + using AbstractFifo<Msg*>::mMutex; + using AbstractFifo<Msg*>::mCondition; + using AbstractFifo<Msg*>::empty; + using AbstractFifo<Msg*>::size; + + /// Add a message to the fifo. + size_t add(Msg* msg); + + typedef typename AbstractFifo<Msg*>::Messages Messages; + size_t addMultiple(Messages& msgs); + + /** Returns the first message available. It will wait if no + * messages are available. If a signal interrupts the wait, + * it will retry the wait. Signals can therefore not be caught + * via getNext. If you need to detect a signal, use block + * prior to calling getNext. + */ + Msg* getNext(); + + + /** Returns the next message available. Will wait up to + * ms milliseconds if no information is available. If + * the specified time passes or a signal interrupts the + * wait, this method returns 0. This interface provides + * no mechanism to distinguish between timeout and + * interrupt. + */ + Msg* getNext(int ms); + + void getMultiple(Messages& other, unsigned int max); + bool getMultiple(int ms, Messages& other, unsigned int max); + + /// delete all elements in the queue + virtual void clear(); + void setInterruptor(AsyncProcessHandler* interruptor); + + private: + AsyncProcessHandler* mInterruptor; + Fifo(const Fifo& rhs); + Fifo& operator=(const Fifo& rhs); +}; + + +template <class Msg> +Fifo<Msg>::Fifo(AsyncProcessHandler* interruptor) : + AbstractFifo<Msg*>(), + mInterruptor(interruptor) +{ +} + +template <class Msg> +Fifo<Msg>::~Fifo() +{ + clear(); +} + +template <class Msg> +void +Fifo<Msg>::setInterruptor(AsyncProcessHandler* interruptor) +{ + Lock lock(mMutex); (void)lock; + mInterruptor=interruptor; +} + + +template <class Msg> +void +Fifo<Msg>::clear() +{ + Lock lock(mMutex); (void)lock; + while ( ! mFifo.empty() ) + { + delete mFifo.front(); + mFifo.pop_front(); + } + assert(mFifo.empty()); +} + +template <class Msg> +size_t +Fifo<Msg>::add(Msg* msg) +{ + size_t size = AbstractFifo<Msg*>::add(msg); + if(size==1 && mInterruptor) + { + // Only do this when the queue goes from empty to not empty. + mInterruptor->handleProcessNotification(); + } + return size; +} + +template <class Msg> +size_t +Fifo<Msg>::addMultiple(Messages& msgs) +{ + size_t inSize = msgs.size(); + size_t size = AbstractFifo<Msg*>::addMultiple(msgs); + if(size==inSize && mInterruptor) + { + // Only do this when the queue goes from empty to not empty. + mInterruptor->handleProcessNotification(); + } + return size; +} + +template <class Msg> +Msg* +Fifo<Msg> ::getNext() +{ + return AbstractFifo<Msg*>::getNext(); +} + +template <class Msg> +Msg* +Fifo<Msg> ::getNext(int ms) +{ + Msg* result(0); + AbstractFifo<Msg*>::getNext(ms, result); + return result; +} + +template <class Msg> +void +Fifo<Msg>::getMultiple(Messages& other, unsigned int max) +{ + AbstractFifo<Msg*>::getMultiple(other, max); +} + +template <class Msg> +bool +Fifo<Msg>::getMultiple(int ms, Messages& other, unsigned int max) +{ + return AbstractFifo<Msg*>::getMultiple(ms, other, max); +} +} // namespace resip + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/FileSystem.cxx b/src/libs/resiprocate/rutil/FileSystem.cxx new file mode 100644 index 00000000..e1c6c979 --- /dev/null +++ b/src/libs/resiprocate/rutil/FileSystem.cxx @@ -0,0 +1,295 @@ +#include "rutil/FileSystem.hxx" +#include "rutil/Logger.hxx" + +#include <cassert> +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + + +static FileSystem::Directory::iterator staticEnd; + + +FileSystem::Directory::Directory(const Data& path) + : mPath(path) +{ +} + + +#ifndef WIN32 +// !jf! added this constructor since it was missing - don't know if it is correct +FileSystem::Directory::iterator::iterator() : mNixDir(0), mDirent(0) +{ +} + + +FileSystem::Directory::iterator::iterator(const Directory& dir) +{ + assert(!dir.getPath().empty()); + //InfoLog(<< "FileSystem::Directory::iterator::iterator: " << dir.getPath()); + if ((mNixDir = opendir( dir.getPath().c_str() ))) + { + mDirent = readdir(mNixDir); + if (mDirent) + { + //InfoLog(<< "FileSystem::Directory::iterator::iterator, first file " << mFile); + mFile = mDirent->d_name; + } + } + else + { + mDirent = 0; + } +} + + +FileSystem::Directory::iterator::~iterator() +{ + if (mNixDir) + { + closedir(mNixDir); + } +} + + +FileSystem::Directory::iterator& +FileSystem::Directory::iterator::operator++() +{ + if (mDirent) + { + mDirent = readdir(mNixDir); + if (mDirent) + { + mFile = mDirent->d_name; + //InfoLog(<< "FileSystem::Directory::iterator::iterator, next file " << mFile); + } + } + return *this; +} + + +bool +FileSystem::Directory::iterator::operator!=(const iterator& rhs) const +{ + return !(*this == rhs); +} + + +bool +FileSystem::Directory::iterator::operator==(const iterator& rhs) const +{ + if (mDirent && rhs.mDirent) + { + return **this == *rhs; + } + + return mDirent == rhs.mDirent; +} + + +const Data& +FileSystem::Directory::iterator::operator*() const +{ + return mFile; +} + + +const Data* +FileSystem::Directory::iterator::operator->() const +{ + return &mFile; +} + +bool +FileSystem::Directory::iterator::is_directory() const +{ + return mDirent->d_type == DT_DIR; +} + +int +FileSystem::Directory::create() const +{ + if(mkdir(mPath.c_str(), 0777) == -1) + { + return errno; + } + return 0; +} + +#else + +FileSystem::Directory::iterator::iterator() : + mWinSearch(0) +{ +} + + +FileSystem::Directory::iterator::iterator(const Directory& dir) +{ + Data searchPath; + if (dir.getPath().postfix("/") || dir.getPath().postfix("\\")) + { + searchPath = dir.getPath() + Data("*"); + } + else + { + searchPath = dir.getPath() + Data("/*"); + } + WIN32_FIND_DATAA fileData; + mWinSearch = FindFirstFileA( searchPath.c_str(), &fileData); + + if (mWinSearch == INVALID_HANDLE_VALUE) + { + mWinSearch = 0; + } + else + { + mFile = fileData.cFileName; + } +} + + +FileSystem::Directory::iterator::~iterator() +{ + if (mWinSearch) + { + FindClose(mWinSearch); + } +} + + +FileSystem::Directory::iterator& +FileSystem::Directory::iterator::operator++() +{ + WIN32_FIND_DATAA fileData; + + if (!FindNextFileA(mWinSearch, &fileData)) + { + if (GetLastError() == ERROR_NO_MORE_FILES) + { + FindClose(mWinSearch); + mWinSearch = 0; + } + } + else + { + mFile = fileData.cFileName; + mIsDirectory = (fileData.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) > 0; + } + return *this; +} + + +bool +FileSystem::Directory::iterator::operator!=(const iterator& rhs) const +{ + return !(*this == rhs); +} + + +bool +FileSystem::Directory::iterator::operator==(const iterator& rhs) const +{ + if (mWinSearch && rhs.mWinSearch) + { + return **this == *rhs; + } + else + { + return mWinSearch == rhs.mWinSearch; + } +} + + +const Data& +FileSystem::Directory::iterator::operator*() const +{ + return mFile; +} + + +const Data* +FileSystem::Directory::iterator::operator->() const +{ + return &mFile; +} + +bool +FileSystem::Directory::iterator::is_directory() const +{ + return mIsDirectory; +} + +int +FileSystem::Directory::create() const +{ + if(_mkdir(mPath.c_str()) == -1) + { + return (int)GetLastError(); + } + return 0; +} + +#endif + + +FileSystem::Directory::iterator FileSystem::Directory::begin() const +{ + return iterator(*this); +} + + +FileSystem::Directory::iterator FileSystem::Directory::end() const +{ + return staticEnd; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/FileSystem.hxx b/src/libs/resiprocate/rutil/FileSystem.hxx new file mode 100644 index 00000000..221a3bcf --- /dev/null +++ b/src/libs/resiprocate/rutil/FileSystem.hxx @@ -0,0 +1,127 @@ +#ifndef RESIP_FileSystem_hxx +#define RESIP_FileSystem_hxx + +#include "rutil/Data.hxx" + +#if !defined(WIN32) +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/uio.h> +# if !defined(TARGET_ANDROID) +# include <sys/fcntl.h> +# endif +#include <unistd.h> +#include <dirent.h> +#else +#include <direct.h> +#include "rutil/Socket.hxx" +#endif + + +namespace resip +{ + +/** + @brief Provides file-system traversal. Wraps the POSIX/Windows + implementation, depending on environment. +*/ +class FileSystem +{ + public: + class Directory + { + public: + typedef Data value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + Directory(const Data& path); + + class iterator + { + public: + iterator(const Directory& dir); + iterator(); + ~iterator(); + + iterator& operator++(); + bool operator!=(const iterator& rhs) const; + bool operator==(const iterator& rhs) const; + const Data& operator*() const; + const Data* operator->() const; + bool is_directory() const; + private: +#ifdef WIN32 + HANDLE mWinSearch; + bool mIsDirectory; +#else + DIR* mNixDir; + struct dirent* mDirent; +#endif + Data mFile; + }; + + iterator begin() const; + iterator end() const; + const Data& getPath() const { return mPath; } + int create() const; + private: + Data mPath; + }; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/FiniteFifo.hxx b/src/libs/resiprocate/rutil/FiniteFifo.hxx new file mode 100644 index 00000000..db87e2c0 --- /dev/null +++ b/src/libs/resiprocate/rutil/FiniteFifo.hxx @@ -0,0 +1,159 @@ +#if !defined(RESIP_FiniteFifo_hxx) +#define RESIP_FiniteFifo_hxx + +#include "rutil/AbstractFifo.hxx" + +// efficiency note: use a circular buffer do avoid list node allocation + +// what happens to timers that can't be queued? + +namespace resip +{ + +/** + @brief A templated, threadsafe message-queue class with a fixed size. + @ingroup message_passing + @deprecated + @todo remove class +*/ +template < class Msg > +class FiniteFifo : public AbstractFifo<Msg*> +{ + public: + FiniteFifo(unsigned int maxSize); + virtual ~FiniteFifo(); + + using AbstractFifo<Msg*>::mFifo; + using AbstractFifo<Msg*>::mMutex; + using AbstractFifo<Msg*>::mCondition; + using AbstractFifo<Msg*>::empty; + using AbstractFifo<Msg*>::size; + + // Add a message to the fifo. + // return true if succeed, false if full + bool add(Msg* msg); + + /** Returns the first message available. It will wait if no + * messages are available. If a signal interrupts the wait, + * it will retry the wait. Signals can therefore not be caught + * via getNext. If you need to detect a signal, use block + * prior to calling getNext. + */ + Msg* getNext(); + + /** Returns the next message available. Will wait up to + * ms milliseconds if no information is available. If + * the specified time passes or a signal interrupts the + * wait, this method returns 0. This interface provides + * no mechanism to distinguish between timeout and + * interrupt. + */ + Msg* getNext(int ms); + private: + unsigned int mMaxSize; +}; + +template <class Msg> +FiniteFifo<Msg>::FiniteFifo(unsigned int maxSize) + : AbstractFifo<Msg*>(), + mMaxSize(maxSize) +{ +} + +template <class Msg> +FiniteFifo<Msg>::~FiniteFifo() +{ + Lock lock(mMutex); (void)lock; + while ( ! mFifo.empty() ) + { + delete mFifo.front(); + mFifo.pop_front(); + } +} + +template <class Msg> +bool +FiniteFifo<Msg>::add(Msg* msg) +{ + Lock lock(mMutex); (void)lock; + if (mFifo.size() >= mMaxSize) + { + return false; + } + else + { + mFifo.push_back(msg); + mCondition.signal(); + return true; + } +} + +template <class Msg> +Msg* +FiniteFifo<Msg> ::getNext() +{ + return AbstractFifo<Msg*>::getNext(); +} + +template <class Msg> +Msg* +FiniteFifo<Msg> ::getNext(int ms) +{ + Msg* result(0); + AbstractFifo<Msg*>::getNext(ms, result); + return result; +} + +} // namespace resip + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/GeneralCongestionManager.cxx b/src/libs/resiprocate/rutil/GeneralCongestionManager.cxx new file mode 100644 index 00000000..6997d34e --- /dev/null +++ b/src/libs/resiprocate/rutil/GeneralCongestionManager.cxx @@ -0,0 +1,222 @@ +#include "rutil/GeneralCongestionManager.hxx" + +#include "rutil/AbstractFifo.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::STATS + +namespace resip +{ +GeneralCongestionManager::GeneralCongestionManager(MetricType defaultMetric, + UInt32 defaultMaxTolerance) : + mDefaultMetric(defaultMetric), + mDefaultMaxTolerance(defaultMaxTolerance) +{ + // !bwc! TODO allow these to be configured. + mRejectionThresholds[NORMAL]=0; + mRejectionThresholds[REJECTING_NEW_WORK]=80; + mRejectionThresholds[REJECTING_NON_ESSENTIAL]=100; +} + +GeneralCongestionManager::~GeneralCongestionManager() +{} + +void +GeneralCongestionManager::registerFifo(resip::FifoStatsInterface* fifo, + MetricType metric, + UInt32 maxTolerance) +{ + FifoInfo info; + info.fifo=fifo; + info.metric=metric; + info.maxTolerance=maxTolerance; + mFifos.push_back(info); + fifo->setRole((UInt8)mFifos.size()-1); +} + +void +GeneralCongestionManager::unregisterFifo(resip::FifoStatsInterface* fifo) +{ + if(fifo->getRole() < mFifos.size()) + { + mFifos[fifo->getRole()].fifo=0; + } +} + +bool +GeneralCongestionManager::updateFifoTolerances( + const resip::Data& fifoDescription, + MetricType metric, + UInt32 maxTolerance ) +{ + for(std::vector<FifoInfo>::iterator i=mFifos.begin(); i!=mFifos.end(); ++i) + { + if(fifoDescription.empty() || isEqualNoCase(i->fifo->getDescription(), fifoDescription)) + { + i->maxTolerance=UINT_MAX; // Set temporarily to UINT_MAX, so that we don't inadvertantly reject a request while the metric and tolerance are being changed. + i->metric=metric; + i->maxTolerance=maxTolerance; + if(!fifoDescription.empty()) return true; + } + } + return false || fifoDescription.empty(); +} + +CongestionManager::RejectionBehavior +GeneralCongestionManager::getRejectionBehavior(const FifoStatsInterface *fifo) const +{ + // !bwc! We need to also keep an eye on memory usage, and push back if it + // looks like we're going to start hitting swap sometime soon. + + UInt16 percent=getCongestionPercent(fifo); + + // .bwc. We exit this sooner the more congested we are. + if(percent > mRejectionThresholds[REJECTING_NON_ESSENTIAL]) + { + return REJECTING_NON_ESSENTIAL; + } + else if(percent > mRejectionThresholds[REJECTING_NEW_WORK]) + { + return REJECTING_NEW_WORK; + } + else + { + return NORMAL; + } +} + +void +GeneralCongestionManager::logCurrentState() const +{ + WarningLog(<<"FIFO STATISTICS"); + for(std::vector<FifoInfo>::const_iterator i=mFifos.begin(); + i!=mFifos.end();++i) + { + if(i->fifo) + { + const FifoStatsInterface& fifo=*(i->fifo); + Data buffer; + DataStream strm(buffer); + encodeFifoStats(fifo, strm); + WarningLog(<< buffer); + } + } +} + +EncodeStream& +GeneralCongestionManager::encodeCurrentState(EncodeStream& strm) const +{ + for(std::vector<FifoInfo>::const_iterator i=mFifos.begin(); + i!=mFifos.end();++i) + { + if(i->fifo) + { + const FifoStatsInterface& fifo=*(i->fifo); + encodeFifoStats(fifo, strm); + strm << std::endl; + } + } + strm.flush(); + return strm; +} + +UInt16 +GeneralCongestionManager::getCongestionPercent(const FifoStatsInterface* fifo) const +{ + if(fifo->getRole() >= mFifos.size()) + { + assert(0); + return 0; + } + + const FifoInfo& info = mFifos[fifo->getRole()]; + assert(info.fifo==fifo); + switch(info.metric) + { + case SIZE: + return resipIntDiv(100*(UInt16)fifo->getCountDepth(),info.maxTolerance); + case TIME_DEPTH: + return resipIntDiv(100*(UInt32)(fifo->getTimeDepth()),info.maxTolerance); + case WAIT_TIME: + return resipIntDiv(100*(UInt32)(fifo->expectedWaitTimeMilliSec()),info.maxTolerance); + default: + assert(0); + return 0; + } + return 0; +} + +EncodeStream& +GeneralCongestionManager::encodeFifoStats(const FifoStatsInterface& fifoStats, EncodeStream& strm) const +{ + CongestionManager::RejectionBehavior behavior = getRejectionBehavior(&fifoStats); + const FifoInfo& info = mFifos[fifoStats.getRole()]; + strm <<fifoStats.getDescription() + << ": Size=" << fifoStats.getCountDepth() + << " TimeDepth(sec)=" << fifoStats.getTimeDepth() + << " ExpWait(msec)=" << fifoStats.expectedWaitTimeMilliSec() + << " AvgSvcTime(usec)=" + << fifoStats.averageServiceTimeMicroSec() + << " Metric=" + << (info.metric == WAIT_TIME ? "WAIT_TIME" : + info.metric == TIME_DEPTH ? "TIME_DEPTH" : + "SIZE") + << " MaxTolerance=" + << info.maxTolerance + << " CurBehavior=" + << (behavior == NORMAL ? "NORMAL" : + behavior == REJECTING_NEW_WORK ? "REJECTING_NEW_WORK" : + "REJECTING_NON_ESSENTIAL"); + strm.flush(); + return strm; +} + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/GeneralCongestionManager.hxx b/src/libs/resiprocate/rutil/GeneralCongestionManager.hxx new file mode 100644 index 00000000..e23e5791 --- /dev/null +++ b/src/libs/resiprocate/rutil/GeneralCongestionManager.hxx @@ -0,0 +1,214 @@ +#ifndef GENERAL_CONGESTION_MANAGER_HXX +#define GENERAL_CONGESTION_MANAGER_HXX + +#include "rutil/CongestionManager.hxx" + +#include <vector> + +namespace resip +{ +/** + This is a general-purpose congestion manager. It is not conscious of the + roles of the fifos it manages, or the relationships between these + fifos/roles. In other words, if a crucial fifo is fully congested, this will + have no bearing on whether the other fifos in the system are considered + congested. In many cases, this is a workable restriction, but it may be + desirable to implement a subclass of CongestionManager that takes the system + as a whole into account when determining whether a specific fifo should be + considered congested. For more on implementing such a congestion manager, see + the class documentation for CongestionManager. + + @ingroup message_passing +*/ +class GeneralCongestionManager : public CongestionManager +{ + public: + /** + Enumeration of congestion metric types this class supports. + */ + typedef enum + { + SIZE=0, //!< The current size of the fifo + TIME_DEPTH, //!< The age of the oldest item in the fifo + WAIT_TIME //!< The expected service time (the time it takes for new items to be serviced) This is the recommended metric. + } MetricType; + + /** + @param defaultMetric The type of metric that will be used to define + a fifo's congestion state, by default: + - SIZE : Based solely on the number of messages in the fifo + - TIME_DEPTH : Based on the age of the oldest (front-most) message + in the fifo. + - WAIT_TIME : Based on the expected wait time for the fifo; this is + calculated by multiplying the size by the average service time. + This is the recommended metric. + + @param maxTolerance The default maximum tolerance for the given metric; + this determines when the RejectionBehavior changes + - 0-80 percent of max tolerance -> NORMAL + - 80-100 percent of max tolerance -> REJECTING_NEW_WORK + - >100 percent of max tolerance -> REJECTING_NON_ESSENTIAL + */ + GeneralCongestionManager(MetricType defaultMetric, + UInt32 defaultMaxTolerance); + virtual ~GeneralCongestionManager(); + + /** + Update the metric type and tolerances of a given fifo that the + GeneralCongestionManager is already aware of. + @param fifoDescription The description of the fifo that we are + modifying the tolerances of. Specify as empty to adjust all + registered fifos. + @param metric The type of metric that will be used to define this + fifo's congestion state. + - SIZE : Based solely on the number of messages in the fifo + - TIME_DEPTH : Based on the age of the oldest (front-most) message + in the fifo. + - WAIT_TIME : Based on the expected wait time for the fifo; this is + calculated by multiplying the size by the average service time. + This is the recommended metric. + + @param maxTolerance The maximum tolerance for the given metric; this + determines when the RejectionBehavior changes + - 0-80 percent of max tolerance -> NORMAL + - 80-100 percent of max tolerance -> REJECTING_NEW_WORK + - >100 percent of max tolerance -> REJECTING_NON_ESSENTIAL + @return True iff the tolerances were successfully adjusted (this can + fail if this GeneralCongestionManager does not know about a fifo by + this name; make sure you have either called getCongestionPercent() + or registerFifo() for this fifo first). + @note Setting the CongestionManager for the resiprocate stack will + cause getCongestionPercent() to be called for every fifo in the + stack; you may then adjust the tolerances as you wish. + */ + virtual bool updateFifoTolerances(const resip::Data& fifoDescription, + MetricType metric, + UInt32 maxTolerance ); + + /** + Add a fifo to the collection of fifos monitored by this + CongestionManager, with a specified metric and maximum tolerance. + @param fifo The fifo that we are registering. + @param metric The type of metric that will be used to define this + fifo's congestion state. + - SIZE : Based solely on the number of messages in the fifo + - TIME_DEPTH : Based on the age of the oldest (front-most) message + in the fifo. + - WAIT_TIME : Based on the expected wait time for the fifo; this is + calculated by multiplying the size by the average service time. + This is the recommended metric. + + @param maxTolerance The maximum tolerance for the given metric; this + determines when the RejectionBehavior changes + - 0-80 percent of max tolerance -> NORMAL + - 80-100 percent of max tolerance -> REJECTING_NEW_WORK + - >100 percent of max tolerance -> REJECTING_NON_ESSENTIAL + */ + virtual void registerFifo(resip::FifoStatsInterface* fifo, + MetricType metric, + UInt32 maxTolerance ); + + /** + Add a fifo to the collection of fifos monitored by this + CongestionManager, with the default metric and maximum tolerance. + @param fifo The fifo that we are registering. + */ + virtual void registerFifo(resip::FifoStatsInterface* fifo) + { + registerFifo(fifo, mDefaultMetric, mDefaultMaxTolerance); + } + + /** + Remove a fifo from the collection of fifos monitored by this + CongestionManager + @param fifo - fifo to remove + */ + virtual void unregisterFifo(resip::FifoStatsInterface* fifo); + + /** + Gets the current RejectionBehavior for this fifo, based only on the + congestion-state of this fifo (ie; this ignores the congestion-state + of other fifos in the system). + + For how this function determines congestion-state, see registerFifo(). */ + virtual RejectionBehavior getRejectionBehavior(const FifoStatsInterface *fifo) const; + + virtual void logCurrentState() const; + virtual EncodeStream& encodeCurrentState(EncodeStream& strm) const; + + private: + /** + @brief Returns the percent of maximum tolerances that this queue is at. + */ + virtual UInt16 getCongestionPercent(const FifoStatsInterface* fifo) const; + + virtual EncodeStream& encodeFifoStats(const FifoStatsInterface& fifoStats, EncodeStream& strm) const; + + typedef struct + { + FifoStatsInterface* fifo; + volatile MetricType metric; + volatile UInt32 maxTolerance; + } FifoInfo; // !bwc! TODO pick a better name + + std::vector<FifoInfo> mFifos; + UInt16 mRejectionThresholds[REJECTING_NON_ESSENTIAL+1]; + MetricType mDefaultMetric; + UInt32 mDefaultMaxTolerance; + + // disabled + GeneralCongestionManager(); + GeneralCongestionManager(const GeneralCongestionManager& orig); + GeneralCongestionManager& operator=(const GeneralCongestionManager& rhs); +}; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/GenericIPAddress.hxx b/src/libs/resiprocate/rutil/GenericIPAddress.hxx new file mode 100644 index 00000000..eb30a856 --- /dev/null +++ b/src/libs/resiprocate/rutil/GenericIPAddress.hxx @@ -0,0 +1,238 @@ +#if !defined(RESIP_GENERIC_IP_ADDRESS_HXX) +#define RESIP_GENERIC_IP_ADDRESS_HXX + +#ifndef WIN32 +#include <netinet/in.h> +#else +#include <winsock2.h> +#include <Ws2tcpip.h> +#endif + +#include "rutil/Socket.hxx" +#include "rutil/compat.hxx" + + +namespace resip +{ +/** + @brief Represents an IP-address and port (V4 or V6). + + @note This class is misnamed - it is really an IP address and port +*/ +struct GenericIPAddress +{ + public: + GenericIPAddress() + { + } + + GenericIPAddress(const sockaddr& addr) : address(addr) + { +#ifdef IPPROTO_IPV6 + if (addr.sa_family == AF_INET6) + { + v6Address = reinterpret_cast<const sockaddr_in6&>(addr); + } + else +#endif + { + v4Address = reinterpret_cast<const sockaddr_in&>(addr); + } + } + + GenericIPAddress(const sockaddr_in& v4) : v4Address(v4) + { + } + +#ifdef IPPROTO_IPV6 + GenericIPAddress(const sockaddr_in6& v6) : v6Address(v6) + { + } +#endif + + size_t length() const + { + if (address.sa_family == AF_INET) // v4 + { + return sizeof(sockaddr_in); + } +#ifdef IPPROTO_IPV6 + else if (address.sa_family == AF_INET6) // v6 + { + return sizeof(sockaddr_in6); + } +#endif + assert(0); + return 0; + } + + bool isVersion4() const + { + return address.sa_family == AF_INET; + } + + bool isVersion6() const + { +#ifdef IPPROTO_IPV6 + if (address.sa_family == AF_INET6) return true; +#endif + return false; + } + + union + { + sockaddr address; + sockaddr_in v4Address; +#ifdef IPPROTO_IPV6 + sockaddr_in6 v6Address; +#endif + char pad[28]; // this make union same size if v6 is in or out + }; + + bool operator==(const GenericIPAddress& addr) const + { + if (address.sa_family == addr.address.sa_family) + { + if (address.sa_family == AF_INET) // v4 + { + return (v4Address.sin_port == addr.v4Address.sin_port && + memcmp(&v4Address.sin_addr, &addr.v4Address.sin_addr, sizeof(in_addr)) == 0); + } + else // v6 + { +#ifdef IPPROTO_IPV6 + return (v6Address.sin6_port == addr.v6Address.sin6_port && + memcmp(&v6Address.sin6_addr, &addr.v6Address.sin6_addr, sizeof(in6_addr)) == 0); +#else + assert(0); + return false; +#endif + } + } + return false; + } + + bool operator<(const GenericIPAddress& addr) const + { + + if (address.sa_family == AF_INET && addr.address.sa_family == AF_INET) + { + int c=memcmp(&v4Address.sin_addr, + &addr.v4Address.sin_addr, + sizeof(in_addr)); + + if (c < 0) + { + return true; + } + else if (c > 0) + { + return false; + } + else if (v4Address.sin_port < addr.v4Address.sin_port) + { + return true; + } + else + { + return false; + } + } +#ifdef IPPROTO_IPV6 + else if (address.sa_family == AF_INET6 && + addr.address.sa_family == AF_INET6) + { + int c = memcmp(&v6Address.sin6_addr, + &addr.v6Address.sin6_addr, + sizeof(in6_addr)); + if (c < 0) + { + return true; + } + else if (c > 0) + { + return false; + } + else if (v6Address.sin6_port < addr.v6Address.sin6_port) + { + return true; + } + else + { + return false; + } + } + else if (address.sa_family == AF_INET6 && + addr.address.sa_family == AF_INET) + { + return true; + } + else if (address.sa_family == AF_INET && + addr.address.sa_family == AF_INET6) + { + return false; + } +#endif + else + { + //assert(0); + return false; + } + } + +}; + +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/GenericTimerQueue.hxx b/src/libs/resiprocate/rutil/GenericTimerQueue.hxx new file mode 100644 index 00000000..fd42c8dd --- /dev/null +++ b/src/libs/resiprocate/rutil/GenericTimerQueue.hxx @@ -0,0 +1,140 @@ +#ifndef RUTIL_GENERICTIMERQUEUE_HXX +#define RUTIL_GENERICTIMERQUEUE_HXX + +#include "rutil/Timer.hxx" +#include <set> +#include <vector> + +namespace resip { + +// !dcm! -- hoist? +template<class T> +class GenericTimerQueue +{ + public: + + // !dcm! -- can def. hoist + template<class E> + class TimerEntry + { + public: + TimerEntry(unsigned long tms, E* event) : + mWhen(tms + Timer::getTimeMs()), + mEvent(event) + { + } + + E* getEvent() const + { + return mEvent; + } + + bool operator<(const TimerEntry<E>& rhs) const + { + return mWhen < rhs.mWhen; + } + UInt64 mWhen; + E* mEvent; + }; + + /// deletes the message associated with the timer as well. + virtual ~GenericTimerQueue() + { + for (typename std::multiset<TimerEntry<T> >::iterator i = mTimers.begin(); i != mTimers.end(); ++i) + { + delete i->mEvent; + } + } + + virtual void process() + { + if (!mTimers.empty() && msTillNextTimer() == 0) + { + TimerEntry<T> now(0, 0); + + // hacky solution, needs work, insertion from processTimer + // caused bizarre infinite loop issues in previous revision; + // this code is in desperate need of help + typedef typename std::multiset<TimerEntry<T> > TimerSet; + typedef std::vector<typename TimerSet::iterator> ItVector; + ItVector iterators; + + typename TimerSet::iterator end = mTimers.upper_bound(now); + typename TimerSet::iterator begin = mTimers.begin(); + + for (typename TimerSet::iterator i = begin; i != end; ++i) + { + iterators.push_back(i); + } + + for (typename ItVector::iterator i = iterators.begin(); i != iterators.end(); ++i) + { + assert((*i)->getEvent()); + processTimer((*i)->getEvent()); + } + + //!dcm! -- erasing the range didn't work...upper bound was prob. end() + for (typename ItVector::iterator i = iterators.begin(); i != iterators.end(); ++i) + { + mTimers.erase(*i); + } + } + } + + virtual void processTimer(T*)=0; + + void add(T* event, unsigned long msOffset) + { + TimerEntry<T> t(msOffset, event); + mTimers.insert(t); + } + + int size() const + { + return mTimers.size(); + } + + bool empty() const + { + return mTimers.empty(); + } + + unsigned int msTillNextTimer() + { + if (!mTimers.empty()) + { + UInt64 next = mTimers.begin()->mWhen; + UInt64 now = Timer::getTimeMs(); + if (now > next) + { + return 0; + } + else + { + UInt64 ret64 = next - now; + if ( ret64 > UInt64(INT_MAX) ) + { + return INT_MAX; + } + else + { + int ret = int(ret64); + return ret; + } + } + } + else + { + return INT_MAX; + } + } + + + protected: +// friend std::ostream& operator<<(std::ostream&, const GenericTimerQueue&); + std::multiset<TimerEntry<T> > mTimers; +}; + +} + +#endif // RUTIL_GENERICTIMERQUEUE_HXX diff --git a/src/libs/resiprocate/rutil/HashMap.hxx b/src/libs/resiprocate/rutil/HashMap.hxx new file mode 100644 index 00000000..96ebbb38 --- /dev/null +++ b/src/libs/resiprocate/rutil/HashMap.hxx @@ -0,0 +1,155 @@ +#if !defined(RESIP_HASHMAP_HXX) +#define RESIP_HASHMAP_HXX + +// !cj! if all these machine have to use map then we can just delete them and use the default + +/** + @file + @brief Wraps your platform's implementation of hash_map, hash_multimap, + and hash_set. + + @ingroup data_structures +*/ + +# if ( (__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) ) || ( __GNUC__ > 4 ) +# include <tr1/unordered_map> +# include <tr1/unordered_set> +# define HASH_MAP_NAMESPACE std::tr1 +# define HashMap std::tr1::unordered_map +# define HashSet std::tr1::unordered_set +# define HashMultiMap std::tr1::unordered_multimap + +#define HashValue(type) \ +namespace std \ +{ \ +namespace tr1 \ +{ \ +template <> \ +struct hash<type> \ +{ \ + size_t operator()(const type& data) const; \ +}; \ +} \ +} +#define HashValueImp(type, ret) size_t HASH_MAP_NAMESPACE::hash<type>::operator()(const type& data) const { return ret; } + +# elif ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) || ( __GNUC__ > 3 ) +# include <ext/hash_map> +# include <ext/hash_set> +# define HASH_MAP_NAMESPACE __gnu_cxx +# define HashMap __gnu_cxx::hash_map +# define HashSet __gnu_cxx::hash_set +# define HashMultiMap __gnu_cxx::hash_multimap +// this allows us to hash on a pointer as the key +namespace HASH_MAP_NAMESPACE +{ +/** +@internal +*/ +template <class T> +struct hash<T*> +{ + size_t operator()(const T* t) const + { + return size_t(t); + } +}; + +} + +#define HashValue(type) \ +namespace HASH_MAP_NAMESPACE \ +{ \ +template <> \ +struct hash<type> \ +{ \ + size_t operator()(const type& data) const; \ +}; \ +} +#define HashValueImp(type, ret) size_t HASH_MAP_NAMESPACE::hash<type>::operator()(const type& data) const { return ret; } + +# elif defined(__INTEL_COMPILER ) +# include <hash_map> +# define HASH_MAP_NAMESPACE std +# define HashMap std::hash_map +# define HashSet std::hash_set +# define HashMultiMap std::hash_multimap +# define HashValue(type) \ + namespace HASH_MAP_NAMESPACE \ + { \ + size_t hash_value(const type& data);\ + } +# define HashValueImp(type, ret) size_t HASH_MAP_NAMESPACE::hash_value(const type& data) { return ret; } +# elif defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310) // hash_map is in stdext namespace for VS.NET 2003 +# include <hash_map> +# include <hash_set> +# define HASH_MAP_NAMESPACE stdext +# define HashMap stdext::hash_map +# define HashSet stdext::hash_set +# define HashMultiMap stdext::hash_multimap +# define HashValue(type) \ + namespace HASH_MAP_NAMESPACE \ + { \ + size_t hash_value(const type& data);\ + } +# define HashValueImp(type, ret) size_t HASH_MAP_NAMESPACE::hash_value(const type& data) { return ret; } +# else +# include <map> +# define HashMap std::map +# define HashSet std::set +# define HashMultiMap std::multimap +# define HashValue(type) +# define HashValueImp(type, ret) +# endif + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/HeapInstanceCounter.cxx b/src/libs/resiprocate/rutil/HeapInstanceCounter.cxx new file mode 100644 index 00000000..7f31dd91 --- /dev/null +++ b/src/libs/resiprocate/rutil/HeapInstanceCounter.cxx @@ -0,0 +1,162 @@ +#include "rutil/HeapInstanceCounter.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Data.hxx" + +#include <assert.h> +#include <map> + +using namespace std; +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::STATS + +typedef map<void *, unsigned long> AllocationSizeMap; + +//namespace // unnamed namespace +//{ +struct InstanceCounts +{ + InstanceCounts() + : total(0), + outstanding(0), + totalBytesOutstanding(0) + {} + + size_t total; + size_t outstanding; + size_t totalBytesOutstanding; + AllocationSizeMap allocationSizes; +}; + +// .dlb. should be using comparitor on typeinfo +typedef map<Data, InstanceCounts> AllocationMap; +Mutex allocationMutex; +AllocationMap allocationMap; +//} + +#ifdef RESIP_HEAP_COUNT +void +HeapInstanceCounter::dump() +{ + Lock l(allocationMutex); + if (allocationMap.empty()) + { + WarningLog(<< "No allocations."); + } + else + { + AllocationMap::const_iterator i(allocationMap.begin()); + AllocationMap::const_iterator iEnd(allocationMap.end()); + for (; i != iEnd; ++i) + { + if (i->second.total) + { + //abi::__cxa_demangle(typeid(obj).name(), 0, 0, &status); + WarningLog(<< i->first << " " << i->second.total << " > " << i->second.outstanding << ", " << + i->second.totalBytesOutstanding); + } + } + } +} + +void* +HeapInstanceCounter::allocate(size_t bytes, + const type_info& ti) +{ + void* addr = ::operator new(bytes); + + { //lock scope + // WarningLog(<< "allocated " << ti.name()); + Lock l(allocationMutex); + + const Data name(Data::Share, ti.name(), strlen(ti.name())); + InstanceCounts &counts = allocationMap[name]; + + counts.total += 1; + counts.outstanding += 1; + counts.totalBytesOutstanding += bytes; + counts.allocationSizes[addr] = bytes; + } + return addr; +} + +void +HeapInstanceCounter::deallocate(void* addr, + const type_info& ti) +{ + {//lock scope + // WarningLog(<< "deallocated " << ti.name()); + Lock l(allocationMutex); + const Data name(Data::Share, ti.name(), strlen(ti.name())); + if (allocationMap.count(name) != 0) + { + InstanceCounts &counts = allocationMap[name]; + + if (counts.allocationSizes.count(addr) != 0) + { + counts.outstanding -= 1; + counts.totalBytesOutstanding -= counts.allocationSizes[addr]; + counts.allocationSizes.erase(addr); + } + } + } + ::operator delete(addr); +} + +#else // RESIP_HEAP_COUNT +void +HeapInstanceCounter::dump() +{} + +#endif // RESIP_HEAP_COUNT + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/HeapInstanceCounter.hxx b/src/libs/resiprocate/rutil/HeapInstanceCounter.hxx new file mode 100644 index 00000000..e9c03718 --- /dev/null +++ b/src/libs/resiprocate/rutil/HeapInstanceCounter.hxx @@ -0,0 +1,114 @@ +#ifndef RESIP_HeapInstanceCounter_hxx +#define RESIP_HeapInstanceCounter_hxx + +#ifdef RESIP_HEAP_COUNT + +#include <typeinfo> +#include <cstddef> + +/** Counts heap instances. Place RESIP_HeapCount(ClassName) in public section + of class to be watched. + + call HeapInstanceCounter::dump() to output results as WarningLog. + + dump output is of the form: MangledClassName [total instances allocated] > [number outstanding] + + RESIP_HEAP_COUNT macro variable controls the heap counter at compile time. +*/ +#define RESIP_HeapCount(type_) \ + static void* operator new (size_t bytes) \ + { \ + return resip::HeapInstanceCounter::allocate(bytes, typeid(type_)); \ + } \ + static void* operator new (size_t bytes, void* p) \ + { \ + return p; \ + } \ + static void* operator new[] (size_t bytes) \ + { \ + return resip::HeapInstanceCounter::allocate(bytes, typeid(type_)); \ + } \ + static void operator delete (void* addr) \ + { \ + resip::HeapInstanceCounter::deallocate(addr, typeid(type_)); \ + } \ + static void operator delete[] (void* addr) \ + { \ + resip::HeapInstanceCounter::deallocate(addr, typeid(type_)); \ + } +#else +#if defined (__SUNPRO_CC) +#define RESIP_HeapCount(type_)class type_ +#else +#define RESIP_HeapCount(type_) +#endif +#endif // RESIP_HEAP_COUNT + +namespace resip +{ + +class HeapInstanceCounter +{ + public: + static void dump(); + +#ifdef RESIP_HEAP_COUNT + static void* allocate(size_t bytes, const std::type_info& ti); + static void deallocate(void* addr, const std::type_info& ti); +#endif + +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Inserter.hxx b/src/libs/resiprocate/rutil/Inserter.hxx new file mode 100644 index 00000000..0b6c9ccb --- /dev/null +++ b/src/libs/resiprocate/rutil/Inserter.hxx @@ -0,0 +1,608 @@ +#if !defined(RESIP_INSERTER_HXX) +#define RESIP_INSERTER_HXX + +#include <iostream> +#include <utility> +#include <map> +#include <set> +#include <list> +#include <vector> +#include <deque> +#include <cassert> + +#include "HashMap.hxx" +#include "rutil/compat.hxx" +#include "rutil/resipfaststreams.hxx" + +/* +Example of use Inserter + +int +main(int argc, char** argv) +{ + std::vector<std::string> v; + + v.push_back("foo"); + v.push_back("bar"); + v.push_back("baz"); + + std::cerr << Inserter(v) << std::endl; + std::cerr << Inserter("nnn") << std::endl; // though you wouldn't bother +} + +Example of use InserterP +InserterP - allows processing of collections with pointers to items + +int +main(int argc, char** argv) +{ + std::vector<std::string*> v; + + v.push_back(new std::string("foo")); + v.push_back(new std::string("bar")); + v.push_back(new std::string("baz")); + + std::cerr << InserterP(v) << std::endl; +} +*/ + +namespace resip +{ + +static const char* leftanglebracket("<"); +static const char* rightanglebracket(">"); +static const char* leftsqbracket("["); +static const char* rightsqbracket("]"); +static const char* sparrowsp(" -> "); +static const char* commaspace(", "); + +/// Completely generic insert function +#ifdef REASONABLE_TEMPLATES +template <class T> +EncodeStream& +insert(EncodeStream& s, const T& t) +{ + // use native << + s << t; + return s; +} +#endif + +// specific collections, sigh +template <class T> +EncodeStream& +insert(EncodeStream& s, const std::vector <T>& c) +{ + s << leftsqbracket; + for (typename std::vector <T>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + // recurse + insert(s, *i); + } + s << rightsqbracket; + return s; +} + +template <class T> +EncodeStream& +insert(EncodeStream& s, const std::deque<T>& c) +{ + s << leftsqbracket; + for (typename std::deque <T>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + // recurse + insert(s, *i); + } + s << rightsqbracket; + return s; +} + +template <class T> +EncodeStream& +insert(EncodeStream& s, const std::list <T>& c) +{ + s << leftsqbracket; + for (typename std::list <T>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + // recurse + insert(s, *i); + } + s << rightsqbracket; + return s; +} + +#if !defined(__INTEL_COMPILER) +template <class K, class C> +EncodeStream& +insert(EncodeStream& s, const std::set <K, C>& c) +{ + s << leftsqbracket; + for (typename std::set <K, C>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + insert(s, *i); + } + s << rightsqbracket; + return s; +} +#endif + +#if !defined(__INTEL_COMPILER) +template <class K, class C> +EncodeStream& +insert(EncodeStream& s, const std::multiset <K, C>& c) +{ + s << leftsqbracket; + for (typename std::multiset <K, C>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + insert(s, *i); + } + s << rightsqbracket; + return s; +} +#endif + +// HashMap +#if defined(HASH_MAP_NAMESPACE) +template <class K, class V, class H> +EncodeStream& +insert(EncodeStream& s, const HashMap<K,V,H>& c) +{ + s << leftsqbracket; + for (typename HashMap<K,V,H>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + insert(s, i->first); + s << sparrowsp; + insert(s, i->second); + } + s << rightsqbracket; + return s; +} +#endif + +#if defined(HASH_MAP_NAMESPACE) +template <class V, class H> +EncodeStream& +insert(EncodeStream& s, const HashSet<V,H>& c) +{ + s << leftsqbracket; + for (typename HashSet<V,H>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + insert(s, *i); + } + s << rightsqbracket; + return s; +} +#endif + +// map +template <class K, class V, class H> +EncodeStream& +insert(EncodeStream& s, const std::map <K, V, H>& c) +{ + s << leftsqbracket; + for (typename std::map<K,V, H>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + insert(s, i->first); + s << sparrowsp; + insert(s, i->second); + } + s << rightsqbracket; + return s; +} + +// special case for basic_string container +template <class T> +EncodeStream& +insert(EncodeStream& s, const std::basic_string<T>& str) +{ + // use native << + s << str; + return s; +} + +// special case for pair +template <class T, class U> +EncodeStream& +insert(EncodeStream& s, const std::pair<T, U>& p) +{ + // use native << + s << leftanglebracket << p.first << commaspace << p.second << rightanglebracket; + return s; +} + +/** + @brief Allows a (possibly recursive) container of anything with operator<< to + be dumped to a stream. + + + This is particularly useful within a Log call. + e.g. + @code + void logNameAddrs(vector<resip::NameAddr>& contacts) + { + DebugLog(<< "Contacts: " << Inserter(contacts)); + } + @endcode + + @see Inserter() + */ +template <class T> +class InserterClass +{ + public: + InserterClass(const T& t) + : _t(t) + {} + + const T& _t; +}; + +/// Function to allow an Inserter to be used directly with a stream +template <class T> +EncodeStream& +operator<<(EncodeStream& s, const InserterClass<T>& inserter) +{ +#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1310) + assert(0); // CJ - really need to fix this + return s; +#else + return insert(s, inserter._t); +#endif +} + +/// Templatized function to construct an instance of InserterClass for a +/// container to be inserted. The function induces the template type, saving the +/// user from thinking about it. +template <class T> +InserterClass<T> +Inserter(const T& t) +{ + return InserterClass<T>(t); +} + + + +/// +/// The following functions are more or less the same as the above, but add P to the naming +/// and treat data items as pointers +/// + + + +/// Completely generic insert function +#ifdef REASONABLE_TEMPLATES +template <class T> +EncodeStream& +insertP(EncodeStream& s, const T& t) +{ + // use native << + s << *t; + return s; +} +#endif + +// specific collections, sigh +template <class T> +EncodeStream& +insertP(EncodeStream& s, const std::vector <T>& c) +{ + s << leftsqbracket; + for (typename std::vector <T>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + // recurse + insert(s, *(*i)); + } + s << rightsqbracket; + return s; +} + +template <class T> +EncodeStream& +insertP(EncodeStream& s, const std::deque<T>& c) +{ + s << leftsqbracket; + for (typename std::deque <T>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + // recurse + insert(s, *(*i)); + } + s << rightsqbracket; + return s; +} + +template <class T> +EncodeStream& +insertP(EncodeStream& s, const std::list <T>& c) +{ + s << leftsqbracket; + for (typename std::list <T>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + // recurse + insert(s, *(*i)); + } + s << rightsqbracket; + return s; +} + +#if !defined(__INTEL_COMPILER) +template <class K, class C> +EncodeStream& +insertP(EncodeStream& s, const std::set <K, C>& c) +{ + s << leftsqbracket; + for (typename std::set <K, C>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + insert(s, *(*i)); + } + s << rightsqbracket; + return s; +} +#endif + +#if !defined(__INTEL_COMPILER) +template <class K, class C> +EncodeStream& +insertP(EncodeStream& s, const std::multiset <K, C>& c) +{ + s << leftsqbracket; + for (typename std::multiset <K, C>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + insert(s, *(*i)); + } + s << rightsqbracket; + return s; +} +#endif + +// HashMap +#if defined(HASH_MAP_NAMESPACE) +template <class K, class V, class H> +EncodeStream& +insertP(EncodeStream& s, const HashMap<K,V,H>& c) +{ + s << leftsqbracket; + for (typename HashMap<K,V,H>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + insert(s, i->first); + s << sparrowsp; + insert(s, *i->second); + } + s << rightsqbracket; + return s; +} +#endif + +#if defined(HASH_MAP_NAMESPACE) +template <class V, class H> +EncodeStream& +insertP(EncodeStream& s, const HashSet<V,H>& c) +{ + s << leftsqbracket; + for (typename HashSet<V,H>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + insert(s, *(*i)); + } + s << rightsqbracket; + return s; +} +#endif + +// map +template <class K, class V, class H> +EncodeStream& +insertP(EncodeStream& s, const std::map <K, V, H>& c) +{ + s << leftsqbracket; + for (typename std::map<K,V, H>::const_iterator i = c.begin(); + i != c.end(); i++) + { + if (i != c.begin()) + { + s << commaspace; + } + insert(s, i->first); + s << sparrowsp; + insert(s, *i->second); + } + s << rightsqbracket; + return s; +} + +// special case for basic_string container +template <class T> +EncodeStream& +insertP(EncodeStream& s, const std::basic_string<T>& str) +{ + // use native << + s << str; + return s; +} + +// special case for pair +template <class T, class U> +EncodeStream& +insertP(EncodeStream& s, const std::pair<T, U>& p) +{ + // use native << + s << leftanglebracket << *p.first << commaspace << *p.second << rightanglebracket; + return s; +} + +/** + @brief Allows a (possibly recursive) container of anything with operator<< to + be dumped to a stream. + + + This is particularly useful within a Log call. + e.g. + @code + void logNameAddrs(vector<resip::NameAddr>& contacts) + { + DebugLog(<< "Contacts: " << Inserter(contacts)); + } + @endcode + + @see Inserter() + */ +template <class T> +class InserterPClass +{ + public: + InserterPClass(const T& t) + : _t(t) + {} + + const T& _t; +}; + +/// Function to allow an Inserter to be used directly with a stream +template <class T> +EncodeStream& +operator<<(EncodeStream& s, const InserterPClass<T>& inserter) +{ +#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1310) + assert(0); // CJ - really need to fix this + return s; +#else + return insertP(s, inserter._t); +#endif +} + +/// Templatized function to construct an instance of InserterClass for a +/// container to be inserted. The function induces the template type, saving the +/// user from thinking about it. +template <class T> +InserterPClass<T> +InserterP(const T& t) +{ + return InserterPClass<T>(t); +} + +} // resip + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/IntrusiveListElement.hxx b/src/libs/resiprocate/rutil/IntrusiveListElement.hxx new file mode 100644 index 00000000..58cba828 --- /dev/null +++ b/src/libs/resiprocate/rutil/IntrusiveListElement.hxx @@ -0,0 +1,661 @@ +#ifndef RESIP_IntrusiveListElement +#define RESIP_IntrusiveListElement + +/** + @file + @brief Heritable intrusive doubly linked list element templates. + + For a class that is an element in a single list, use like this: + + @code + class Foo : public IntrusiveListElement<Foo*> + { + ... + }; + + Foo* fooHead = new Foo(); + // initialize head to cycle -- represent an empty list + Foo::makeList(fooHead); + @endcode + + For a class that is an element of multiple lists, use like this: + has two independent intrusive lists, named read and write + @code + class FooFoo : public IntrusiveListElement<FooFoo*>, public IntrusiveListElement1<FooFoo*> + { + public: + typedef IntrusiveListElement<FooFoo*> read; + typedef IntrusiveListElement1<FooFoo*> write; + + ... + }; + + FooFoo* fooFooHead = new FooFoo(); + // initialize head to cycle -- represent two empty lists + FooFoo::read::makeList(fooFooHead); + FooFoo::write::makeList(fooFooHead); + for (FooFoo::read::iterator f = fooFooHead->read::begin(); f != fooFooHead->read::end(); f++) + { + ... + }; + + // elsewhere: + FooFoo head; + FooFoo::read* mReadHead = FooFoo::read::makeList(&head); + FooFoo::write* mWriteHead = FooFoo::write::makeList(&head); + + FooFoo element* = new FooFoo(); + // don't need to disambiguate methods + mReadHead->push_back(element); + mWriteHead->push_back(element); + + // element could be in either list, so use aspect + element->write::remove(); + @endcode +*/ + +namespace resip +{ + +template <class P> +class IntrusiveListElement +{ + public: + IntrusiveListElement() + : mNext(0), + mPrev(0) + {} + + virtual ~IntrusiveListElement() + { + remove(); + } + + // make this element an empty list + static P makeList(P elem) + { + assert(!elem->IntrusiveListElement<P>::mNext); + + elem->IntrusiveListElement<P>::mPrev = elem; + elem->IntrusiveListElement<P>::mNext = elem; + + return elem; + } + + bool empty() const + { + assert(mPrev); + assert(mNext); + + return static_cast<const IntrusiveListElement<P>*>(mNext) == static_cast<const IntrusiveListElement<P>*>(this); + } + + // .dlb. add reverse_iterator? + + class iterator + { + public: + explicit iterator(const P start) + : mPos(start) + {} + + iterator& operator=(const iterator& rhs) + { + mPos = rhs.mPos; + return *this; + } + + iterator& operator++() + { + mPos = mPos->IntrusiveListElement<P>::mNext; + return *this; + } + + bool operator==(const iterator& rhs) + { + return mPos == rhs.mPos; + } + + bool operator!=(const iterator& rhs) + { + return mPos != rhs.mPos; + } + + P operator*() + { + return mPos; + } + + private: + P mPos; + }; + + iterator begin() + { + assert(mPrev); + assert(mNext); + return iterator(mNext); + } + + iterator end() + { + assert(mPrev); + assert(mNext); + return iterator(static_cast<P>(this)); + } + + friend class iterator; + + // pushing an element onto the same list twice is undefined + void push_front(P elem) + { + assert(mPrev); + assert(mNext); + + elem->IntrusiveListElement<P>::mNext = mNext; + elem->IntrusiveListElement<P>::mPrev = static_cast<P>(this); + + elem->IntrusiveListElement<P>::mNext->IntrusiveListElement<P>::mPrev = elem; + elem->IntrusiveListElement<P>::mPrev->IntrusiveListElement<P>::mNext = elem; + } + + // putting an element onto the same list twice is undefined + void push_back(P elem) + { + assert(mPrev); + assert(mNext); + + elem->IntrusiveListElement<P>::mPrev = mPrev; + elem->IntrusiveListElement<P>::mNext = static_cast<P>(this); + + elem->IntrusiveListElement<P>::mPrev->IntrusiveListElement<P>::mNext = elem; + elem->IntrusiveListElement<P>::mNext->IntrusiveListElement<P>::mPrev = elem; + } + + void remove() + { + if (mNext) + { + // prev -> this -> next + // <- <- + // + // prev -> next + // <- + mNext->IntrusiveListElement<P>::mPrev = mPrev; + mPrev->IntrusiveListElement<P>::mNext = mNext; + } + + mNext = 0; + mPrev = 0; + } + + protected: + mutable P mNext; + mutable P mPrev; +}; + +template <class P> +class IntrusiveListElement1 +{ + public: + IntrusiveListElement1() + : mNext(0), + mPrev(0) + {} + + virtual ~IntrusiveListElement1() + { + remove(); + } + + // make this element an empty list + static P makeList(P elem) + { + assert(!elem->IntrusiveListElement1<P>::mNext); + + elem->IntrusiveListElement1<P>::mPrev = elem; + elem->IntrusiveListElement1<P>::mNext = elem; + + return elem; + } + + bool empty() const + { + assert(mPrev); + assert(mNext); + + return static_cast<const IntrusiveListElement1<P>*>(mNext) == static_cast<const IntrusiveListElement1<P>*>(this); + } + + // .dlb. add reverse_iterator? + + class iterator + { + public: + explicit iterator(const P start) + : mPos(start) + {} + + iterator& operator=(const iterator& rhs) + { + mPos = rhs.mPos; + return *this; + } + + iterator& operator++() + { + mPos = mPos->IntrusiveListElement1<P>::mNext; + return *this; + } + + bool operator==(const iterator& rhs) + { + return mPos == rhs.mPos; + } + + bool operator!=(const iterator& rhs) + { + return mPos != rhs.mPos; + } + + P operator*() + { + return mPos; + } + + private: + P mPos; + }; + + iterator begin() + { + assert(mPrev); + assert(mNext); + return iterator(mNext); + } + + iterator end() + { + assert(mPrev); + assert(mNext); + return iterator(static_cast<P>(this)); + } + + friend class iterator; + + // pushing an element onto the same list twice is undefined + void push_front(P elem) + { + assert(mPrev); + assert(mNext); + + elem->IntrusiveListElement1<P>::mNext = mNext; + elem->IntrusiveListElement1<P>::mPrev = static_cast<P>(this); + + elem->IntrusiveListElement1<P>::mNext->IntrusiveListElement1<P>::mPrev = elem; + elem->IntrusiveListElement1<P>::mPrev->IntrusiveListElement1<P>::mNext = elem; + } + + // putting an element onto the same list twice is undefined + void push_back(P elem) + { + assert(mPrev); + assert(mNext); + + elem->IntrusiveListElement1<P>::mPrev = mPrev; + elem->IntrusiveListElement1<P>::mNext = static_cast<P>(this); + + elem->IntrusiveListElement1<P>::mPrev->IntrusiveListElement1<P>::mNext = elem; + elem->IntrusiveListElement1<P>::mNext->IntrusiveListElement1<P>::mPrev = elem; + } + + void remove() + { + if (mNext) + { + // prev -> this -> next + // <- <- + // + // prev -> next + // <- + mNext->IntrusiveListElement1<P>::mPrev = mPrev; + mPrev->IntrusiveListElement1<P>::mNext = mNext; + } + + mNext = 0; + mPrev = 0; + } + + protected: + mutable P mNext; + mutable P mPrev; +}; + +template <class P> +class IntrusiveListElement2 +{ + public: + IntrusiveListElement2() + : mNext(0), + mPrev(0) + {} + + virtual ~IntrusiveListElement2() + { + remove(); + } + + // make this element an empty list + static P makeList(P elem) + { + assert(!elem->IntrusiveListElement2<P>::mNext); + + elem->IntrusiveListElement2<P>::mPrev = elem; + elem->IntrusiveListElement2<P>::mNext = elem; + + return elem; + } + + bool empty() const + { + assert(mPrev); + assert(mNext); + + return static_cast<const IntrusiveListElement2<P>*>(mNext) == static_cast<const IntrusiveListElement2<P>*>(this); + } + + // .dlb. add reverse_iterator? + + class iterator + { + public: + explicit iterator(const P start) + : mPos(start) + {} + + iterator& operator=(const iterator& rhs) + { + mPos = rhs.mPos; + return *this; + } + + iterator& operator++() + { + mPos = mPos->IntrusiveListElement2<P>::mNext; + return *this; + } + + bool operator==(const iterator& rhs) + { + return mPos == rhs.mPos; + } + + bool operator!=(const iterator& rhs) + { + return mPos != rhs.mPos; + } + + P operator*() + { + return mPos; + } + + private: + P mPos; + }; + + iterator begin() + { + assert(mPrev); + assert(mNext); + return iterator(mNext); + } + + iterator end() + { + assert(mPrev); + assert(mNext); + return iterator(static_cast<P>(this)); + } + + friend class iterator; + + // pushing an element onto the same list twice is undefined + void push_front(P elem) + { + assert(mPrev); + assert(mNext); + + elem->IntrusiveListElement2<P>::mNext = mNext; + elem->IntrusiveListElement2<P>::mPrev = static_cast<P>(this); + + elem->IntrusiveListElement2<P>::mNext->IntrusiveListElement2<P>::mPrev = elem; + elem->IntrusiveListElement2<P>::mPrev->IntrusiveListElement2<P>::mNext = elem; + } + + // putting an element onto the same list twice is undefined + void push_back(P elem) + { + assert(mPrev); + assert(mNext); + + elem->IntrusiveListElement2<P>::mPrev = mPrev; + elem->IntrusiveListElement2<P>::mNext = static_cast<P>(this); + + elem->IntrusiveListElement2<P>::mPrev->IntrusiveListElement2<P>::mNext = elem; + elem->IntrusiveListElement2<P>::mNext->IntrusiveListElement2<P>::mPrev = elem; + } + + void remove() + { + if (mNext) + { + // prev -> this -> next + // <- <- + // + // prev -> next + // <- + mNext->IntrusiveListElement2<P>::mPrev = mPrev; + mPrev->IntrusiveListElement2<P>::mNext = mNext; + } + + mNext = 0; + mPrev = 0; + } + + protected: + mutable P mNext; + mutable P mPrev; +}; + +template <class P> +class IntrusiveListElement3 +{ + public: + IntrusiveListElement3() + : mNext(0), + mPrev(0) + {} + + virtual ~IntrusiveListElement3() + { + remove(); + } + + // make this element an empty list + static P makeList(P elem) + { + assert(!elem->IntrusiveListElement3<P>::mNext); + + elem->IntrusiveListElement3<P>::mPrev = elem; + elem->IntrusiveListElement3<P>::mNext = elem; + + return elem; + } + + bool empty() const + { + assert(mPrev); + assert(mNext); + + return static_cast<const IntrusiveListElement3<P>*>(mNext) == static_cast<const IntrusiveListElement3<P>*>(this); + } + + // .dlb. add reverse_iterator? + + class iterator + { + public: + explicit iterator(const P start) + : mPos(start) + {} + + iterator& operator=(const iterator& rhs) + { + mPos = rhs.mPos; + return *this; + } + + iterator& operator++() + { + mPos = mPos->IntrusiveListElement3<P>::mNext; + return *this; + } + + bool operator==(const iterator& rhs) + { + return mPos == rhs.mPos; + } + + bool operator!=(const iterator& rhs) + { + return mPos != rhs.mPos; + } + + P operator*() + { + return mPos; + } + + private: + P mPos; + }; + + iterator begin() + { + assert(mPrev); + assert(mNext); + return iterator(mNext); + } + + iterator end() + { + assert(mPrev); + assert(mNext); + return iterator(static_cast<P>(this)); + } + + friend class iterator; + + // pushing an element onto the same list twice is undefined + void push_front(P elem) + { + assert(mPrev); + assert(mNext); + + elem->IntrusiveListElement3<P>::mNext = mNext; + elem->IntrusiveListElement3<P>::mPrev = static_cast<P>(this); + + elem->IntrusiveListElement3<P>::mNext->IntrusiveListElement3<P>::mPrev = elem; + elem->IntrusiveListElement3<P>::mPrev->IntrusiveListElement3<P>::mNext = elem; + } + + // putting an element onto the same list twice is undefined + void push_back(P elem) + { + assert(mPrev); + assert(mNext); + + elem->IntrusiveListElement3<P>::mPrev = mPrev; + elem->IntrusiveListElement3<P>::mNext = static_cast<P>(this); + + elem->IntrusiveListElement3<P>::mPrev->IntrusiveListElement3<P>::mNext = elem; + elem->IntrusiveListElement3<P>::mNext->IntrusiveListElement3<P>::mPrev = elem; + } + + void remove() + { + if (mNext) + { + // prev -> this -> next + // <- <- + // + // prev -> next + // <- + mNext->IntrusiveListElement3<P>::mPrev = mPrev; + mPrev->IntrusiveListElement3<P>::mNext = mNext; + } + + mNext = 0; + mPrev = 0; + } + + protected: + mutable P mNext; + mutable P mPrev; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/KeyValueStore.cxx b/src/libs/resiprocate/rutil/KeyValueStore.cxx new file mode 100644 index 00000000..243770f6 --- /dev/null +++ b/src/libs/resiprocate/rutil/KeyValueStore.cxx @@ -0,0 +1,141 @@ +#include "rutil/KeyValueStore.hxx" +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +namespace resip +{ + +KeyValueStore::KeyValueStore() +{ +} + +KeyValueStore::KeyValueStore(const KeyValueStoreKeyAllocator& keyAllocator) : + mKeyAllocator(keyAllocator) +{ + if(mKeyAllocator.mNextKey > 1) // Only resize if there are allocated keys + { + Value defaultValue; + defaultValue.dataValue = 0; + defaultValue.uint64Value = 0; // largest member of union - will zero out all data + mKeyValueStore.resize(mKeyAllocator.mNextKey, defaultValue); + } +} + +KeyValueStore::~KeyValueStore() +{ + KeyValueStoreContainer::iterator it = mKeyValueStore.begin(); + for(; it != mKeyValueStore.end(); it++) + { + delete it->dataValue; + } +} + +KeyValueStore::Key +KeyValueStore::allocateNewKey() +{ + Value defaultValue; + defaultValue.dataValue = 0; + defaultValue.uint64Value = 0; // largest member of union - will zero out all data + Key key = mKeyAllocator.allocateNewKey(); + mKeyValueStore.resize(key+1, defaultValue); + return key; +} + +void +KeyValueStore::setDataValue(Key key, const Data& value) +{ + if(mKeyValueStore[key].dataValue) + { + *mKeyValueStore[key].dataValue = value; + } + else + { + mKeyValueStore[key].dataValue = new Data(value); + } +} + +const Data& +KeyValueStore::getDataValue(Key key) const +{ + if(!mKeyValueStore[key].dataValue) + { + return Data::Empty; + } + return *mKeyValueStore[key].dataValue; +} + +Data& +KeyValueStore::getDataValue(Key key) +{ + if(!mKeyValueStore[key].dataValue) + { + mKeyValueStore[key].dataValue = new Data(); + } + return *mKeyValueStore[key].dataValue; +} + +EncodeStream& +operator<<(EncodeStream& strm, const KeyValueStore& store) +{ + strm << "[KeyValueStore]"; + return strm; +} + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/KeyValueStore.hxx b/src/libs/resiprocate/rutil/KeyValueStore.hxx new file mode 100644 index 00000000..fd7db5e0 --- /dev/null +++ b/src/libs/resiprocate/rutil/KeyValueStore.hxx @@ -0,0 +1,141 @@ +#if !defined(KeyValueStore_hxx) +#define KeyValueStore_hxx + +#include <vector> +#include "rutil/Data.hxx" +#include "rutil/compat.hxx" + +namespace resip +{ +class KeyValueStoreKeyAllocator; + +class KeyValueStore +{ +public: + typedef unsigned long Key; + class KeyValueStoreKeyAllocator + { + public: + KeyValueStoreKeyAllocator() : mNextKey(1) { } + KeyValueStore::Key allocateNewKey() { return mNextKey++; } + private: + friend class KeyValueStore; + KeyValueStore::Key mNextKey; + }; + + KeyValueStore(); + KeyValueStore(const KeyValueStoreKeyAllocator& keyAllocator); + virtual ~KeyValueStore(); + + Key allocateNewKey(); + + void setDataValue(Key key, const Data& value); + const Data& getDataValue(Key key) const; + Data& getDataValue(Key key); + + void setBoolValue(Key key, bool value) { mKeyValueStore[key].boolValue = value; } + const bool& getBoolValue(Key key) const { return mKeyValueStore[key].boolValue; } + bool& getBoolValue(Key key) { return mKeyValueStore[key].boolValue; } + + void setCharValue(Key key, char value) { mKeyValueStore[key].charValue = value; } + const char& getCharValue(Key key) const { return mKeyValueStore[key].charValue; } + char& getCharValue(Key key) { return mKeyValueStore[key].charValue; } + + void setShortValue(Key key, short value) { mKeyValueStore[key].shortValue = value; } + const short& getShortValue(Key key) const { return mKeyValueStore[key].shortValue; } + short& getShortValue(Key key) { return mKeyValueStore[key].shortValue; } + + void setUShortValue(Key key, unsigned short value) { mKeyValueStore[key].ushortValue = value; } + const unsigned short& getUShortValue(Key key) const { return mKeyValueStore[key].ushortValue; } + unsigned short& getUShortValue(Key key) { return mKeyValueStore[key].ushortValue; } + + void setIntValue(Key key, int value) { mKeyValueStore[key].intValue = value; } + const int& getIntValue(Key key) const { return mKeyValueStore[key].intValue; } + int& getIntValue(Key key) { return mKeyValueStore[key].intValue; } + + void setUIntValue(Key key, unsigned int value) { mKeyValueStore[key].uintValue = value; } + const unsigned int& getUIntValue(Key key) const { return mKeyValueStore[key].uintValue; } + unsigned int& getUIntValue(Key key) { return mKeyValueStore[key].uintValue; } + + void setUInt64Value(Key key, UInt64 value) { mKeyValueStore[key].uint64Value = value; } + const UInt64& getUInt64Value(Key key) const { return mKeyValueStore[key].uint64Value; } + UInt64& getUInt64Value(Key key) { return mKeyValueStore[key].uint64Value; } + +protected: + struct Value + { + resip::Data* dataValue; + union + { + bool boolValue; + char charValue; + short shortValue; + unsigned short ushortValue; + int intValue; + unsigned int uintValue; + UInt64 uint64Value; + }; + }; + typedef std::vector<Value> KeyValueStoreContainer; + KeyValueStoreContainer mKeyValueStore; + KeyValueStoreKeyAllocator mKeyAllocator; + +private: + friend EncodeStream& operator<<(EncodeStream& strm, const KeyValueStore& store); +}; + +EncodeStream& operator<<(EncodeStream& strm, const KeyValueStore& store); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Lock.cxx b/src/libs/resiprocate/rutil/Lock.cxx new file mode 100644 index 00000000..e3301106 --- /dev/null +++ b/src/libs/resiprocate/rutil/Lock.cxx @@ -0,0 +1,119 @@ +#include "rutil/Lock.hxx" + + +using resip::Lock; +using resip::ReadLock; +using resip::WriteLock; +using resip::PtrLock; + +using resip::LockType; +using resip::Lockable; + + +static inline void takeLock(Lockable& lockable, LockType lockType) { + switch ( lockType ) + { + case resip::VOCAL_READLOCK: + { + lockable.readlock(); + break; + } + + case resip::VOCAL_WRITELOCK: + { + lockable.writelock(); + break; + } + + default: + { + lockable.lock(); + break; + } + } +} + +Lock::Lock(Lockable & lockable, LockType lockType) + : myLockable(lockable) +{ + takeLock(lockable, lockType); +} + +Lock::~Lock() +{ + myLockable.unlock(); +} + +ReadLock::ReadLock(Lockable & lockable) + : Lock(lockable, VOCAL_READLOCK) +{ +} + +WriteLock::WriteLock(Lockable & lockable) + : Lock(lockable, VOCAL_WRITELOCK) +{ +} + + +PtrLock::PtrLock(Lockable* lockable, LockType lockType) + : myLockable(lockable) +{ + if (lockable) + takeLock(*lockable, lockType); +} + +PtrLock::~PtrLock() +{ + if (myLockable) + myLockable->unlock(); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Lock.hxx b/src/libs/resiprocate/rutil/Lock.hxx new file mode 100644 index 00000000..098e7442 --- /dev/null +++ b/src/libs/resiprocate/rutil/Lock.hxx @@ -0,0 +1,117 @@ +#if !defined(RESIP_LOCK_HXX) +#define RESIP_LOCK_HXX + +#include "rutil/Lockable.hxx" + +namespace resip +{ + +enum LockType +{ + VOCAL_LOCK = 0, + VOCAL_READLOCK, + VOCAL_WRITELOCK +}; + +/** + @brief A convenience class to lock a Lockable (such as a Mutex) on object + creation, and unlock on destruction. (ie, a scoped lock) + + @see Mutex +*/ +class Lock +{ + public: + /** + @param Lockable& The object to lock + @param LockType one of VOCAL_LOCK, VOCAL_READLOCK, VOCAL_WRITELOCK + */ + Lock(Lockable &, LockType = VOCAL_LOCK); + virtual ~Lock(); + + private: + Lockable& myLockable; +}; + +class ReadLock : public Lock +{ + public: + ReadLock(Lockable &); +}; + +class WriteLock : public Lock +{ + public: + WriteLock(Lockable &); +}; + + + +/** + Much like class Lock above, but takes pointer argument to Lockable, + which may be NULL. This allow for optional locking and avoids + if/else statements in caller. +**/ +class PtrLock +{ + public: + PtrLock(Lockable*, LockType = VOCAL_LOCK); + virtual ~PtrLock(); + + private: + Lockable* myLockable; +}; + +} // namespace resip + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Lockable.hxx b/src/libs/resiprocate/rutil/Lockable.hxx new file mode 100644 index 00000000..e96864d9 --- /dev/null +++ b/src/libs/resiprocate/rutil/Lockable.hxx @@ -0,0 +1,77 @@ +#if !defined(RESIP_LOCKABLE_HXX) +#define RESIP_LOCKABLE_HXX + +/** Infrastructure common to VOCAL.<br><br> + */ +namespace resip +{ + +/** + @brief Abstract base-class for Mutexes. +*/ +class Lockable +{ + protected: + Lockable() {}; + + public: + virtual ~Lockable() {}; + virtual void lock() = 0; + virtual void unlock() = 0; + virtual void readlock() { lock(); } + virtual void writelock() { lock() ; } +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Log.cxx b/src/libs/resiprocate/rutil/Log.cxx new file mode 100644 index 00000000..1e7308b7 --- /dev/null +++ b/src/libs/resiprocate/rutil/Log.cxx @@ -0,0 +1,882 @@ +#include "rutil/Socket.hxx" + +#include <cassert> +#include <iostream> +#include <fstream> +#include <stdio.h> +#include "rutil/Data.hxx" + +#ifndef WIN32 +#include <sys/time.h> +#endif + +#include <sys/types.h> +#include <time.h> + +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/ThreadIf.hxx" +#include "rutil/Subsystem.hxx" +#include "rutil/SysLogStream.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +const Data Log::delim(" | "); +Log::ThreadData Log::mDefaultLoggerData(0, Log::Cout, Log::Info, NULL, NULL); +Data Log::mAppName; +Data Log::mHostname; +unsigned int Log::MaxLineCount = 0; // no limit by default +unsigned int Log::MaxByteCount = 0; // no limit by default + +#ifdef WIN32 +int Log::mPid=0; +#else +pid_t Log::mPid=0; +#endif + +volatile short Log::touchCount = 0; + + +/// DEPRECATED! Left for backward compatibility - use localLoggers instead +#ifdef LOG_ENABLE_THREAD_SETTING +#if defined(__APPLE__) || defined(__CYGWIN__) +HashValueImp(ThreadIf::Id, (size_t)data); +#endif +HashMap<ThreadIf::Id, std::pair<Log::ThreadSetting, bool> > Log::mThreadToLevel; +HashMap<int, std::set<ThreadIf::Id> > Log::mServiceToThreads; +ThreadIf::TlsKey* Log::mLevelKey; +#endif +HashMap<int, Log::Level> Log::mServiceToLevel; + +Log::LocalLoggerMap Log::mLocalLoggerMap; +ThreadIf::TlsKey* Log::mLocalLoggerKey; + +const char +Log::mDescriptions[][32] = {"NONE", "EMERG", "ALERT", "CRIT", "ERR", "WARNING", "NOTICE", "INFO", "DEBUG", "STACK", "CERR", ""}; + +Mutex Log::_mutex; + +extern "C" +{ + void freeThreadSetting(void* setting) + { + delete static_cast<Log::ThreadSetting*>(setting); + } + + void freeLocalLogger(void* pThreadData) + { + if (pThreadData) + { + // There was some local logger installed. Decrease its use count before we + // continue. + Log::mLocalLoggerMap.decreaseUseCount((static_cast<Log::ThreadData*>(pThreadData))->id()); + } + } +} + +unsigned int LogStaticInitializer::mInstanceCounter=0; +LogStaticInitializer::LogStaticInitializer() +{ + if (mInstanceCounter++ == 0) + { +#ifdef LOG_ENABLE_THREAD_SETTING + Log::mLevelKey = new ThreadIf::TlsKey; + ThreadIf::tlsKeyCreate(*Log::mLevelKey, freeThreadSetting); +#endif + + Log::mLocalLoggerKey = new ThreadIf::TlsKey; + ThreadIf::tlsKeyCreate(*Log::mLocalLoggerKey, freeLocalLogger); + } +} +LogStaticInitializer::~LogStaticInitializer() +{ + if (--mInstanceCounter == 0) + { +#ifdef LOG_ENABLE_THREAD_SETTING + ThreadIf::tlsKeyDelete(*Log::mLevelKey); + delete Log::mLevelKey; +#endif + + ThreadIf::tlsKeyDelete(*Log::mLocalLoggerKey); + delete Log::mLocalLoggerKey; + } +} + +void +Log::initialize(const char* typed, const char* leveld, const char* appName, const char *logFileName, ExternalLogger* externalLogger) +{ + Log::initialize(Data(typed), Data(leveld), Data(appName), logFileName, externalLogger); +} + +void +Log::initialize(const Data& typed, const Data& leveld, const Data& appName, + const char *logFileName, ExternalLogger* externalLogger) +{ + Type type = Log::Cout; + if (isEqualNoCase(typed, "cout")) type = Log::Cout; + else if (isEqualNoCase(typed, "cerr")) type = Log::Cerr; + else if (isEqualNoCase(typed, "file")) type = Log::File; + else type = Log::Syslog; + + Level level = Log::Info; + level = toLevel(leveld); + + Log::initialize(type, level, appName, logFileName, externalLogger); +} + +void +Log::initialize(Type type, Level level, const Data& appName, + const char * logFileName, + ExternalLogger* externalLogger) +{ + Lock lock(_mutex); + mDefaultLoggerData.reset(); + + mDefaultLoggerData.set(type, level, logFileName, externalLogger); + + ParseBuffer pb(appName); + pb.skipToEnd(); +#ifdef _WIN32 + pb.skipBackToChar('\\'); +#else + pb.skipBackToChar('/'); +#endif + mAppName = pb.position(); + + char buffer[1024]; + gethostname(buffer, sizeof(buffer)); + mHostname = buffer; +#ifdef WIN32 + mPid = (int)GetCurrentProcess(); +#else + mPid = getpid(); +#endif +} + +void +Log::initialize(Type type, + Level level, + const Data& appName, + ExternalLogger& logger) +{ + initialize(type, level, appName, 0, &logger); +} + +void +Log::setLevel(Level level) +{ + Lock lock(_mutex); + getLoggerData().mLevel = level; +} + +void +Log::setLevel(Level level, Subsystem& s) +{ + Lock lock(_mutex); + s.setLevel(level); +} + +void +Log::setLevel(Level level, Log::LocalLoggerId loggerId) +{ + if (loggerId) + { + ThreadData *pData = mLocalLoggerMap.getData(loggerId); + if (pData) + { + // Local logger found. Set logging level. + pData->mLevel = level; + + // We don't need local logger instance anymore. + mLocalLoggerMap.decreaseUseCount(loggerId); + pData = NULL; + } + } + else + { + Lock lock(_mutex); + mDefaultLoggerData.mLevel = level; + } +} + +Log::Level +Log::level(Log::LocalLoggerId loggerId) +{ + Level level; + ThreadData *pData; + if (loggerId && (pData = mLocalLoggerMap.getData(loggerId))) + { + // Local logger found. Set logging level. + level = pData->mLevel; + + // We don't need local logger instance anymore. + mLocalLoggerMap.decreaseUseCount(loggerId); + pData = NULL; + } + else + { + Lock lock(_mutex); + level = mDefaultLoggerData.mLevel; + } + return level; +} + +void +Log::setMaxLineCount(unsigned int maxLineCount) +{ + Lock lock(_mutex); + getLoggerData().mMaxLineCount = maxLineCount; +} + +void +Log::setMaxLineCount(unsigned int maxLineCount, Log::LocalLoggerId loggerId) +{ + if (loggerId) + { + ThreadData *pData = mLocalLoggerMap.getData(loggerId); + if (pData) + { + // Local logger found. Set logging level. + pData->mMaxLineCount = maxLineCount; + + // We don't need local logger instance anymore. + mLocalLoggerMap.decreaseUseCount(loggerId); + pData = NULL; + } + } + else + { + Lock lock(_mutex); + mDefaultLoggerData.mMaxLineCount = maxLineCount; + } +} + +void +Log::setMaxByteCount(unsigned int maxByteCount) +{ + Lock lock(_mutex); + getLoggerData().mMaxByteCount = maxByteCount; +} + +void +Log::setMaxByteCount(unsigned int maxByteCount, Log::LocalLoggerId loggerId) +{ + if (loggerId) + { + ThreadData *pData = mLocalLoggerMap.getData(loggerId); + if (pData) + { + // Local logger found. Set logging level. + pData->mMaxByteCount = maxByteCount; + + // We don't need local logger instance anymore. + mLocalLoggerMap.decreaseUseCount(loggerId); + pData = NULL; + } + } + else + { + Lock lock(_mutex); + mDefaultLoggerData.mMaxByteCount = maxByteCount; + } +} + +const static Data log_("LOG_"); + +Data +Log::toString(Level l) +{ + return log_ + mDescriptions[l+1]; +} + +Log::Level +Log::toLevel(const Data& l) +{ + Data pri( l.prefix("LOG_") ? l.substr(4) : l); + + int i=0; + while (strlen(mDescriptions[i])) + { + if (strcmp(pri.c_str(), mDescriptions[i]) == 0) + { + return Level(i-1); + } + i++; + } + + cerr << "Choosing Debug level since string was not understood: " << l << endl; + return Log::Debug; +} + +Log::Type +Log::toType(const Data& arg) +{ + if (arg == "cout" || arg == "COUT") + { + return Log::Cout; + } + else if (arg == "cerr" || arg == "CERR") + { + return Log::Cerr; + } + else if (arg == "file" || arg == "FILE") + { + return Log::File; + } + else + { + return Log::Syslog; + } +} + +EncodeStream & +Log::tags(Log::Level level, + const Subsystem& subsystem, + const char* pfile, + int line, + EncodeStream& strm) +{ + char buffer[256]; + Data ts(Data::Borrow, buffer, sizeof(buffer)); +#if defined( __APPLE__ ) + strm << mDescriptions[level+1] << Log::delim + << timestamp(ts) << Log::delim + << mAppName << Log::delim + << subsystem << Log::delim + << pthread_self() << Log::delim + << pfile << ":" << line; +#elif defined( WIN32 ) + const char* file = pfile + strlen(pfile); + while (file != pfile && + *file != '\\') + { + --file; + } + if (file != pfile) + { + ++file; + } + strm << mDescriptions[level+1] << Log::delim + << timestamp(ts) << Log::delim + << mAppName << Log::delim + << subsystem << Log::delim + << GetCurrentThreadId() << Log::delim + << file << ":" << line; +#else // #if defined( WIN32 ) || defined( __APPLE__ ) + strm << mDescriptions[level+1] << Log::delim + << timestamp(ts) << Log::delim +// << mHostname << Log::delim + << mAppName << Log::delim + << subsystem << Log::delim +// << mPid << Log::delim + << pthread_self() << Log::delim + << pfile << ":" << line; +#endif + return strm; +} + +Data +Log::timestamp() +{ + char buffer[256]; + Data result(Data::Borrow, buffer, sizeof(buffer)); + return timestamp(result); +} + +Data& +Log::timestamp(Data& res) +{ + char* datebuf = const_cast<char*>(res.data()); + const unsigned int datebufSize = 256; + res.clear(); + +#ifdef WIN32 + int result = 1; + SYSTEMTIME systemTime; + struct { time_t tv_sec; int tv_usec; } tv = {0,0}; + time(&tv.tv_sec); + GetLocalTime(&systemTime); + tv.tv_usec = systemTime.wMilliseconds * 1000; +#else + struct tm localTimeResult; + struct timeval tv; + int result = gettimeofday (&tv, NULL); +#endif + + if (result == -1) + { + /* If we can't get the time of day, don't print a timestamp. + Under Unix, this will never happen: gettimeofday can fail only + if the timezone is invalid which it can't be, since it is + uninitialized]or if tv or tz are invalid pointers. */ + datebuf [0] = 0; + } + else + { + /* The tv_sec field represents the number of seconds passed since + the Epoch, which is exactly the argument gettimeofday needs. */ + const time_t timeInSeconds = (time_t) tv.tv_sec; + strftime (datebuf, + datebufSize, + "%Y%m%d-%H%M%S", /* guaranteed to fit in 256 chars, + hence don't check return code */ +#ifdef WIN32 + localtime(&timeInSeconds)); +#else + localtime_r(&timeInSeconds, &localTimeResult)); +#endif + } + + char msbuf[5]; + /* Dividing (without remainder) by 1000 rounds the microseconds + measure to the nearest millisecond. */ + sprintf(msbuf, ".%3.3ld", long(tv.tv_usec / 1000)); + + int datebufCharsRemaining = datebufSize - (int)strlen(datebuf); + strncat (datebuf, msbuf, datebufCharsRemaining - 1); + + datebuf[datebufSize - 1] = '\0'; /* Just in case strncat truncated msbuf, + thereby leaving its last character at + the end, instead of a null terminator */ + + // ugh, resize the Data + res.at(strlen(datebuf)-1); + return res; +} + +Log::Level +Log::getServiceLevel(int service) +{ + Lock lock(_mutex); + HashMap<int, Level>::iterator res = Log::mServiceToLevel.find(service); + if(res == Log::mServiceToLevel.end()) + { + //!dcm! -- should perhaps throw an exception here, instead of setting a + //default level of LOG_ERROR, but nobody uses this yet + Log::mServiceToLevel[service] = Err; + return Err; + } + return res->second; +} + +const Log::ThreadSetting* +Log::getThreadSetting() +{ +#ifndef LOG_ENABLE_THREAD_SETTING + return 0; +#else + ThreadSetting* setting = static_cast<ThreadSetting*>(ThreadIf::tlsGetValue(*Log::mLevelKey)); + if (setting == 0) + { + return 0; + } + if (Log::touchCount > 0) + { + Lock lock(_mutex); + ThreadIf::Id thread = ThreadIf::selfId(); + HashMap<ThreadIf::Id, pair<ThreadSetting, bool> >::iterator res = Log::mThreadToLevel.find(thread); + assert(res != Log::mThreadToLevel.end()); + if (res->second.second) + { + setting->mLevel = res->second.first.mLevel; + res->second.second = false; + touchCount--; +// cerr << "**Log::getThreadSetting:touchCount: " << Log::touchCount << "**" << endl; + + //cerr << "touchcount decremented" << endl; + } + } + return setting; +#endif +} + +void +Log::setThreadSetting(int serv) +{ + Log::setThreadSetting(ThreadSetting(serv, getServiceLevel(serv))); +} + +void +Log::setThreadSetting(int serv, Log::Level l) +{ + Log::setThreadSetting(ThreadSetting(serv, l)); +} + +void +Log::setThreadSetting(ThreadSetting info) +{ +#ifndef LOG_ENABLE_THREAD_SETTING + assert(0); +#else + //cerr << "Log::setThreadSetting: " << "service: " << info.service << " level " << toString(info.level) << " for " << pthread_self() << endl; + ThreadIf::Id thread = ThreadIf::selfId(); + ThreadIf::tlsSetValue(*mLevelKey, (void *) new ThreadSetting(info)); + Lock lock(_mutex); + + if (Log::mThreadToLevel.find(thread) != Log::mThreadToLevel.end()) + { + if (Log::mThreadToLevel[thread].second == true) + { + touchCount--; + } + } + Log::mThreadToLevel[thread].first = info; + Log::mThreadToLevel[thread].second = false; + Log::mServiceToThreads[info.mService].insert(thread); +#endif +} + +void +Log::setServiceLevel(int service, Level l) +{ + Lock lock(_mutex); + Log::mServiceToLevel[service] = l; +#ifndef LOG_ENABLE_THREAD_SETTING + assert(0); +#else + set<ThreadIf::Id>& threads = Log::mServiceToThreads[service]; + for (set<ThreadIf::Id>::iterator i = threads.begin(); i != threads.end(); i++) + { + Log::mThreadToLevel[*i].first.mLevel = l; + Log::mThreadToLevel[*i].second = true; + } + Log::touchCount += (short)threads.size(); +#endif +// cerr << "**Log::setServiceLevel:touchCount: " << Log::touchCount << "**" << endl; +} + +Log::LocalLoggerId Log::localLoggerCreate(Log::Type type, + Log::Level level, + const char * logFileName, + ExternalLogger* externalLogger) +{ + return mLocalLoggerMap.create(type, level, logFileName, externalLogger); +} + +int Log::localLoggerReinitialize(Log::LocalLoggerId loggerId, + Log::Type type, + Log::Level level, + const char * logFileName, + ExternalLogger* externalLogger) +{ + return mLocalLoggerMap.reinitialize(loggerId, type, level, logFileName, externalLogger); +} + +int Log::localLoggerRemove(Log::LocalLoggerId loggerId) +{ + return mLocalLoggerMap.remove(loggerId); +} + +int Log::setThreadLocalLogger(Log::LocalLoggerId loggerId) +{ + ThreadData* pData = static_cast<ThreadData*>(ThreadIf::tlsGetValue(*Log::mLocalLoggerKey)); + if (pData) + { + // There was some local logger installed. Decrease its use count before we + // continue. + mLocalLoggerMap.decreaseUseCount(pData->id()); + pData = NULL; + } + if (loggerId) + { + pData = mLocalLoggerMap.getData(loggerId); + } + ThreadIf::tlsSetValue(*mLocalLoggerKey, (void *) pData); + return (loggerId == 0) || (pData != NULL)?0:1; +} + +std::ostream& +Log::Instance(unsigned int bytesToWrite) +{ + return getLoggerData().Instance(bytesToWrite); +} + +void +Log::reset() +{ + getLoggerData().reset(); +} + +bool +Log::isLogging(Log::Level level, const resip::Subsystem& sub) +{ + if (sub.getLevel() != Log::None) + { + return level <= sub.getLevel(); + } + else + { + return (level <= Log::getLoggerData().mLevel); + } +} + +void +Log::OutputToWin32DebugWindow(const Data& result) +{ +#ifdef WIN32 + const char *text = result.c_str(); +#ifdef UNDER_CE + LPWSTR lpwstrText = resip::ToWString(text); + OutputDebugStringW(lpwstrText); + FreeWString(lpwstrText); +#else + OutputDebugStringA(text); +#endif +#endif +} + +Log::LocalLoggerId Log::LocalLoggerMap::create(Log::Type type, + Log::Level level, + const char * logFileName, + ExternalLogger* externalLogger) +{ + Lock lock(mLoggerInstancesMapMutex); + Log::LocalLoggerId id = ++mLastLocalLoggerId; + Log::ThreadData *pNewData = new Log::ThreadData(id, type, level, logFileName, + externalLogger); + mLoggerInstancesMap[id].first = pNewData; + mLoggerInstancesMap[id].second = 0; + return id; +} + +int Log::LocalLoggerMap::reinitialize(Log::LocalLoggerId loggerId, + Log::Type type, + Log::Level level, + const char * logFileName, + ExternalLogger* externalLogger) +{ + Lock lock(mLoggerInstancesMapMutex); + LoggerInstanceMap::iterator it = mLoggerInstancesMap.find(loggerId); + if (it == mLoggerInstancesMap.end()) + { + // No such logger ID + std::cerr << "Log::LocalLoggerMap::remove(): Unknown local logger id=" << loggerId << std::endl; + return 1; + } + it->second.first->reset(); + it->second.first->set(type, level, logFileName, externalLogger); + return 0; +} + +int Log::LocalLoggerMap::remove(Log::LocalLoggerId loggerId) +{ + Lock lock(mLoggerInstancesMapMutex); + LoggerInstanceMap::iterator it = mLoggerInstancesMap.find(loggerId); + if (it == mLoggerInstancesMap.end()) + { + // No such logger ID + std::cerr << "Log::LocalLoggerMap::remove(): Unknown local logger id=" << loggerId << std::endl; + return 1; + } + if (it->second.second > 0) + { + // Non-zero use-count. + std::cerr << "Log::LocalLoggerMap::remove(): Use count is non-zero (" << it->second.second << ")!" << std::endl; + return 2; + } + delete it->second.first; // delete ThreadData + mLoggerInstancesMap.erase(it); + return 0; +} + +Log::ThreadData *Log::LocalLoggerMap::getData(Log::LocalLoggerId loggerId) +{ + Lock lock(mLoggerInstancesMapMutex); + LoggerInstanceMap::iterator it = mLoggerInstancesMap.find(loggerId); + if (it == mLoggerInstancesMap.end()) + { + // No such logger ID + return NULL; + } + it->second.second++; + return it->second.first; +} + +void Log::LocalLoggerMap::decreaseUseCount(Log::LocalLoggerId loggerId) +{ + Lock lock(mLoggerInstancesMapMutex); + LoggerInstanceMap::iterator it = mLoggerInstancesMap.find(loggerId); + if (it != mLoggerInstancesMap.end()) + { + it->second.second--; + assert(it->second.second >= 0); + } +} + + +Log::Guard::Guard(resip::Log::Level level, + const resip::Subsystem& subsystem, + const char* file, + int line) : + mLevel(level), + mSubsystem(subsystem), + mFile(file), + mLine(line), + mData(Data::Borrow, mBuffer, sizeof(mBuffer)), + mStream(mData.clear()) +{ + + if (resip::Log::getLoggerData().mType != resip::Log::OnlyExternalNoHeaders) + { + Log::tags(mLevel, mSubsystem, mFile, mLine, mStream); + mStream << resip::Log::delim; + mStream.flush(); + + mHeaderLength = mData.size(); + } + else + { + mHeaderLength = 0; + } +} + +Log::Guard::~Guard() +{ + mStream.flush(); + + if (resip::Log::getExternal()) + { + const resip::Data rest(resip::Data::Share, + mData.data() + mHeaderLength, + (int)mData.size() - mHeaderLength); + if (!(*resip::Log::getExternal())(mLevel, + mSubsystem, + resip::Log::getAppName(), + mFile, + mLine, + rest, + mData)) + { + return; + } + } + + Type logType = resip::Log::getLoggerData().mType; + + if(logType == resip::Log::OnlyExternal || + logType == resip::Log::OnlyExternalNoHeaders) + { + return; + } + + resip::Lock lock(resip::Log::_mutex); + // !dlb! implement VSDebugWindow as an external logger + if (logType == resip::Log::VSDebugWindow) + { + mData += "\r\n"; + OutputToWin32DebugWindow(mData); + } + else + { + // endl is magic in syslog -- so put it here + Instance((int)mData.size()+2) << mData << std::endl; + } +} + +std::ostream& +Log::ThreadData::Instance(unsigned int bytesToWrite) +{ +// std::cerr << "Log::ThreadData::Instance() id=" << mId << " type=" << mType << std::endl; + switch (mType) + { + case Log::Syslog: + if (mLogger == 0) + { + std::cerr << "Creating a syslog stream" << std::endl; + mLogger = new SysLogStream; + } + return *mLogger; + + case Log::Cerr: + return std::cerr; + + case Log::Cout: + return std::cout; + + case Log::File: + if (mLogger == 0 || + (maxLineCount() && mLineCount >= maxLineCount()) || + (maxByteCount() && ((unsigned int)mLogger->tellp()+bytesToWrite) >= maxByteCount())) + { + std::cerr << "Creating a logger for file \"" << mLogFileName.c_str() << "\"" << std::endl; + Data logFileName(mLogFileName != "" ? mLogFileName : "resiprocate.log"); + if (mLogger) + { + Data oldLogFileName(logFileName + ".old"); + delete mLogger; + // Keep one backup file: Delete .old file, Rename log file to .old + // Could be expanded in the future to keep X backup log files + remove(oldLogFileName.c_str()); + rename(logFileName.c_str(), oldLogFileName.c_str()); + } + // Append to log if we have a line count or byte count limit - otherwise truncate + mLogger = new std::ofstream(logFileName.c_str(), std::ios_base::out | ((maxLineCount() > 0 || maxByteCount() > 0) ? std::ios_base::app : std::ios_base::trunc)); + mLineCount = 0; + } + mLineCount++; + return *mLogger; + default: + assert(0); + return std::cout; + } +} + +void +Log::ThreadData::reset() +{ + delete mLogger; + mLogger = NULL; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Log.hxx b/src/libs/resiprocate/rutil/Log.hxx new file mode 100644 index 00000000..41e8233e --- /dev/null +++ b/src/libs/resiprocate/rutil/Log.hxx @@ -0,0 +1,490 @@ +#ifndef RESIP_Log_hxx +#define RESIP_Log_hxx + +#include "rutil/Data.hxx" + +#ifndef WIN32 +#include <syslog.h> +#include <unistd.h> +#endif + +#include <set> + +#include "rutil/Mutex.hxx" +#include "rutil/Lock.hxx" +#include "rutil/HashMap.hxx" +#include "rutil/ThreadIf.hxx" +#include <iostream> + +// !ipse! I think that this remark is no more valid with recent changes, +// but I don't have MacOs X to test with. Someone should take this duty. +// +// NOTE: disabling thread setting code for native mac os applications. +// since some logging takes place during static initialization we can't +// be sure all the pthread stuff is ready to go. this eventually causes +// crashes in the Mac OS native API. +#if !defined(TARGET_OS_MAC) +#define LOG_ENABLE_THREAD_SETTING +// defining hash function in mac os (non-sdk api) and cygwin because +// ThreadIf::Id is a pointer, (this assumes it's always the same pointer) +#if defined(__APPLE__) || defined(__CYGWIN__) +HashValue(resip::ThreadIf::Id); +#endif +#endif + +extern "C" +{ + // Forward declaration to make it friend of Log class. + void freeLocalLogger(void* pThreadData); +}; + + +namespace resip +{ + +class ExternalLogger; +class Subsystem; + +/** + @brief Singleton that handles logging calls. + + @see Logger for usage details +*/ +class Log +{ + public: + enum Type + { + Cout = 0, + Syslog, + File, + Cerr, + VSDebugWindow, ///< Use only for Visual Studio Debug Window logging - WIN32 must be defined + OnlyExternal, ///< log messages are only written to external logger + OnlyExternalNoHeaders ///< same as OnlyExternal, only the messageWithHeaders param of the ExternalLogger + ///< will be empty. This parameter usually contains a pre-formatted log entry. + }; + + enum Level + { + None = -1, +#ifdef WIN32 + Crit = 2, + Err = 3, + Warning = 4, + Info = 6, + Debug = 7, +#else + Crit = LOG_CRIT, +// #ifdef ERR // ncurses defines a macro called ERR +// SIP2_ERR = LOG_ERR, +// #else +// ERR = LOG_ERR, +// #endif + Err, + Warning = LOG_WARNING, + Info = LOG_INFO, + Debug = LOG_DEBUG, +#endif + Stack = 8, + StdErr = 9, + Bogus = 666 + }; + + /// Thread Local logger ID type. + typedef int LocalLoggerId; + + /** + @brief Implementation for logging macros. + + Log::Guard(Log::Info, Subsystem::TEST, __FILE__, __LINE__) << ... ; + */ + class Guard + { + public: + /** Remember the logging values and be a a stream to receive + the log contents. */ + Guard(Level level, + const Subsystem& system, + const char* file, + int line); + + /** Commit logging */ + ~Guard(); + + EncodeStream& asStream() {return mStream;} + operator EncodeStream&() {return mStream;} + + private: + resip::Log::Level mLevel; + const resip::Subsystem& mSubsystem; + resip::Data::size_type mHeaderLength; + const char* mFile; + int mLine; + char mBuffer[128]; + Data mData; + oDataStream mStream; + Guard& operator=(const Guard&); + }; + + class ThreadSetting + { + public: + ThreadSetting() + : mService(-1), + mLevel(Err) + {} + + ThreadSetting(int serv, Level level) + : mService(serv), + mLevel(level) + { + } + + int mService; + Level mLevel; + }; + + /// output the loglevel, hostname, appname, pid, tid, subsystem + static EncodeStream& tags(Log::Level level, + const Subsystem& subsystem, + const char* file, + int line, + EncodeStream& strm); + + static Data& timestamp(Data& result); + static Data timestamp(); + static ExternalLogger* getExternal() + { + return getLoggerData().mExternalLogger; + } + static Data getAppName() + { + return mAppName; + } + + static void initialize(Type type, + Level level, + const Data& appName, + const char * logFileName = 0, + ExternalLogger* externalLogger = 0); + static void initialize(const Data& type, + const Data& level, + const Data& appName, + const char * logFileName = 0, + ExternalLogger* externalLogger = 0); + static void initialize(const char* type, + const char* level, + const char* appName, + const char * logFileName = 0, + ExternalLogger* externalLogger = 0); + static void initialize(Type type, + Level level, + const Data& appName, + ExternalLogger& logger); + + /** @brief Set logging level for current thread. + * If thread has no local logger attached, then set global logging level. + */ + static void setLevel(Level level); + /** @brief Set logging level for given subsystem. */ + static void setLevel(Level level, Subsystem& s); + /** Set logging level for given local logger. Use 0 to set global logging level. */ + static void setLevel(Level level, LocalLoggerId loggerId); + /** @brief Return logging level for current thread. + * If thread has no local logger attached, then return global logging level. + */ + static Level level() { Lock lock(_mutex); return getLoggerData().mLevel; } + /** Return logging level for given local logger. Use 0 to set global logging level. */ + static Level level(LocalLoggerId loggerId); + static LocalLoggerId id() { Lock lock(_mutex); return getLoggerData().id(); } + static void setMaxLineCount(unsigned int maxLineCount); + static void setMaxLineCount(unsigned int maxLineCount, LocalLoggerId loggerId); + static void setMaxByteCount(unsigned int maxByteCount); + static void setMaxByteCount(unsigned int maxByteCount, LocalLoggerId loggerId); + static Level toLevel(const Data& l); + static Type toType(const Data& t); + static Data toString(Level l); + + /// DEPRECATED! Left for backward compatibility - use localLoggers instead + static void setServiceLevel(int service, Level l); + static Level getServiceLevel(int service); + + /// DEPRECATED! Left for backward compatibility - use localLoggers instead + static const ThreadSetting* getThreadSetting(); + static void setThreadSetting(ThreadSetting info); + static void setThreadSetting(int serv, Level l); + static void setThreadSetting(int serv); + + /// Create new logger instance and return its ID (zero on error) + static LocalLoggerId localLoggerCreate(Type type, + Level level, + const char * logFileName = NULL, + ExternalLogger* externalLogger = NULL); + + /** Reinitialize all new setting for a local logger instance + * @retval 0 on success + * @retval 1 if logger does not exist + */ + static int localLoggerReinitialize(LocalLoggerId loggerId, + Type type, + Level level, + const char * logFileName = NULL, + ExternalLogger* externalLogger = NULL); + + /** Destroy existing logger instance. + * @retval 0 on success + * @retval 1 if logger does not exist + * @retval 2 if logger is still in use + * @retval >2 on other failures + */ + static int localLoggerRemove(LocalLoggerId loggerId); + + /** Set logger instance with given ID as a thread local logger. + * Pass zero \p loggerId to remove thread local logger. + * @retval 0 on success + * @retval 1 if logger does not exist + * @retval >1 on other failures + */ + static int setThreadLocalLogger(LocalLoggerId loggerId); + + + static std::ostream& Instance(unsigned int bytesToWrite); + static bool isLogging(Log::Level level, const Subsystem&); + static void OutputToWin32DebugWindow(const Data& result); + static void reset(); ///< Frees logger stream + + public: + static unsigned int MaxLineCount; + static unsigned int MaxByteCount; + + protected: + static Mutex _mutex; + static volatile short touchCount; + static const Data delim; + + class ThreadData + { + public: + ThreadData(LocalLoggerId id, Type type=Cout, Level level=Info, + const char *logFileName=NULL, + ExternalLogger *pExternalLogger=NULL) + : mLevel(level), + mMaxLineCount(0), + mMaxByteCount(0), + mExternalLogger(pExternalLogger), + mId(id), + mType(type), + mLogger(NULL), + mLineCount(0) + { + if (logFileName) + { + mLogFileName = logFileName; + } + } + ~ThreadData() { reset(); } + + void set(Type type=Cout, Level level=Info, + const char *logFileName=NULL, + ExternalLogger *pExternalLogger=NULL) + { + mType = type; + mLevel = level; + + if (logFileName) + { + mLogFileName = logFileName; + } + mExternalLogger = pExternalLogger; + } + + LocalLoggerId id() const {return mId;} + unsigned int maxLineCount() { return mMaxLineCount ? mMaxLineCount : MaxLineCount; } // return local max, if not set use global max + unsigned int maxByteCount() { return mMaxByteCount ? mMaxByteCount : MaxByteCount; } // return local max, if not set use global max + + std::ostream& Instance(unsigned int bytesToWrite); ///< Return logger stream instance, creating it if needed. + void reset(); ///< Frees logger stream + + volatile Level mLevel; + volatile unsigned int mMaxLineCount; + volatile unsigned int mMaxByteCount; + ExternalLogger* mExternalLogger; + + protected: + friend class Guard; + const LocalLoggerId mId; + Type mType; + Data mLogFileName; + std::ostream* mLogger; + unsigned int mLineCount; + }; + + static ThreadData mDefaultLoggerData; ///< Default logger settings. + static Data mAppName; + static Data mHostname; +#ifndef WIN32 + static pid_t mPid; +#else + static int mPid; +#endif + static const char mDescriptions[][32]; + + static ThreadData &getLoggerData() + { + ThreadData* pData = static_cast<ThreadData*>(ThreadIf::tlsGetValue(*Log::mLocalLoggerKey)); + return pData?*pData:mDefaultLoggerData; + } + + /// Thread Local logger settings storage + class LocalLoggerMap + { + public: + LocalLoggerMap() + : mLastLocalLoggerId(0) {}; + + /// Create new logger instance and return its ID (zero on error) + LocalLoggerId create(Type type, + Level level, + const char * logFileName = NULL, + ExternalLogger* externalLogger = NULL); + + /** Reinitialize all new setting for a local logger instance + * @retval 0 on success + * @retval 1 if logger does not exist + */ + int reinitialize(LocalLoggerId loggerId, + Type type, + Level level, + const char * logFileName = NULL, + ExternalLogger* externalLogger = NULL); + + /** Remove existing logger instance from map and destroy. + * @retval 0 on success + * @retval 1 if logger does not exist + * @retval 2 if logger is still in use + * @retval >2 on other failures + */ + int remove(LocalLoggerId loggerId); + + /** Get pointer to ThreadData for given ID and increase use counter. + * @returns NULL if ID does not exist. */ + ThreadData *getData(LocalLoggerId loggerId); + + /// Decrease use counter for given loggerId. + void decreaseUseCount(LocalLoggerId loggerId); + + protected: + /// Storage for Thread Local loggers and their use-counts. + typedef HashMap<LocalLoggerId, std::pair<ThreadData*, int> > LoggerInstanceMap; + LoggerInstanceMap mLoggerInstancesMap; + /// Last used LocalLoggerId + LocalLoggerId mLastLocalLoggerId; + /// Mutex to synchronize access to Thread Local logger settings storage + Mutex mLoggerInstancesMapMutex; + }; + + friend void ::freeLocalLogger(void* pThreadData); + friend class LogStaticInitializer; + static LocalLoggerMap mLocalLoggerMap; + static ThreadIf::TlsKey* mLocalLoggerKey; + + + /// DEPRECATED! Left for backward compatibility - use localLoggers instead +#ifdef LOG_ENABLE_THREAD_SETTING + static HashMap<ThreadIf::Id, std::pair<ThreadSetting, bool> > mThreadToLevel; + static HashMap<int, std::set<ThreadIf::Id> > mServiceToThreads; + static ThreadIf::TlsKey* mLevelKey; +#endif + static HashMap<int, Level> mServiceToLevel; +}; + +/** @brief Interface functor for external logging. +*/ +class ExternalLogger +{ +public: + virtual ~ExternalLogger() {}; + /** return true to also do default logging, false to suppress default logging. */ + virtual bool operator()(Log::Level level, + const Subsystem& subsystem, + const Data& appName, + const char* file, + int line, + const Data& message, + const Data& messageWithHeaders) = 0; +}; + +/// Class to initialize Log class static variables. +class LogStaticInitializer { +public: + LogStaticInitializer(); + ~LogStaticInitializer(); +protected: + static unsigned int mInstanceCounter; + +#ifdef WIN32 + // LogStaticInitializer calls ThreadIf::tlsKeyCreate which + // relies on the static TlsDestructorInitializer having set + // up mTlsDestructorsMutex which is used to Lock TLS access + // Since the order of static initialization is not reliable, + // we must make sure that TlsDestructorInitializer is initialized + // before LogStaticInitializer is inizialized: + TlsDestructorInitializer tlsDestructorInitializer; +#endif +}; +static LogStaticInitializer _staticLogInit; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Logger.hxx b/src/libs/resiprocate/rutil/Logger.hxx new file mode 100644 index 00000000..4adfa6fd --- /dev/null +++ b/src/libs/resiprocate/rutil/Logger.hxx @@ -0,0 +1,224 @@ +#ifndef RESIP_Logger_hxx +#define RESIP_Logger_hxx + +#include "rutil/Log.hxx" +#include "rutil/Lock.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/Data.hxx" +#include "rutil/Subsystem.hxx" + +#ifdef WIN32 +#include <windows.h> +#endif + +/** + @file Defines a set of logging macros, one for each level of logging. + + <h2>Simple usage</h2> + + Each source file which uses logging facilities, must set RESIPROCATE_SUBSYSTEM + preprocessor define to one of resip subsystems. This define will be used by + logging macros to mark log entries, generated from this source file, with + appropriate subsystem tag. For the list of available resip subsystems refer + to static variables list in resip::Subsystem class. Note, that those standard + resip::Subsystem variables are just the most commonly used ones. Nothing + prevents you from creating your own resip::Subsystem instance and set + RESIPROCATE_SUBSYSTEM to point to it. That custom resip::Subsystem variable + can even be local to a file or private class member variable, you just must + ensure that it exist in all places you use logging this file. Creating own + resip::Subsystem will allow you to create own subsystem tag and set specific + logging level for it. + + Once you have RESIPROCATE_SUBSYSTEM defined you can start logging with any + of StackLog(), DebugLog(), InfoLog(), WarningLog(), ErrLog(), CritLog(). These + preprocessor macros provide a convenient way to log your data. Look at this + piece of code as an example: + +<code> +#include Logger.hxx +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::SIP + ... + DebugLog(<< "hi there " << mix << 4 << types); // note leading << and no endl +</code> + + + <h2>Initialization</h2> + + Logging may be used without (or prior to) initialization, in which case all + log data will be printed right to console (to std::cout). Likely, you will + want to use more advanced logging features like output to syslog or a file. + In this case you need to call Log::initialize() with appropriate parameters. + E.g., following example tells logger to write data to a file with the name + "resip.log". It will write only entries with logging priority Log::Info or + higher. Application name is taken from argv[0], and no external logger is + specified (last parameter is NULL). + +<code> + Log::initialize(Log::File, Log::Info, argv[0], "resip.log", NULL); +</code> + + Refer to Log::Type for a list of possible logging types and to Log::Level + for a list of available logging levels. + + + <h2>External loggers</h2> + + Sometimes you may need to provide your own, application specific way of + logging. E.g. you may want to output log data to a GUI window. This may be + implemented using external loggers. To create an external logger you just + need to inherit from ExternalLogger class and pass an object of your external + logger to Log::initialize() as the last parameter. + + + <h2Subsystem-specific logging level></h2> + + You may set logging level to output for a specific subsystem inside resip. + The recommended way to do this is with <code>Log::setLevel(level, subsystem)</code> + static function. If you set a concrete logging level for the subsystem, it + will be used instead of all other logging level settings, like global logging + level setting and thread local logger level setting. To set subsystem-specific + logging level back to default logging level, call + <code>Log::setLevel(Log::None, subsystem)</code> + + + <h2>Thread local loggers</h2> + + If your application uses several threads for resip, e.g. uses separate thread + for each resip instance, then you may want to split your log streams to be + separate too. E.g. you may use different log files for different instances. + In this case you need to use thread local loggers. + + First, you need to create a thread local logger with Log::localLoggerCreate() + static function call with desired parameters (they're closely following + Log::initialize() meaning). You will receive LocalLoggerId in response which + you will use later to refer to created local logger. If you need to change + local logger's parameters later, you should use Log::localLoggerReinitialize() + static function. And when you're done with it, free it with Log::localLoggerRemove() + static function. To actually use a created local logger, you need to call + Log::setThreadLocalLogger() from the target thread context. If you need to + remove thread local logger from a thread, just call + <code>Log::setThreadLocalLogger(0)</code> + + Note, that thread local logger may be safely used from multiple threads. + So if each of your resip instances have two threads, both of them can just + share the same local logger - just pass its LocalLoggerId to them both. + + + <h2>Still not sure?</h2> + + If you still can't get something, just look how it is used in existing code. + One particular place to look into is rutil/test/testLogger.cxx which is + a unittest for logging facility. +*/ + + +#define DELIM + + + +// unconditionally output to cerr -- easily change back and forth +#define CerrLog(args_) \ + resip::Log::tags(resip::Log::StdErr, RESIPROCATE_SUBSYSTEM, \ + __FILE__, __LINE__, resipCerr) << ' ' << '|' << ' ' \ + args_ << std::endl; + +#define StackLog(args_) \ +GenericLog(RESIPROCATE_SUBSYSTEM, resip::Log::Stack, args_) + +#define DebugLog(args_) \ +GenericLog(RESIPROCATE_SUBSYSTEM, resip::Log::Debug, args_) + +#define InfoLog(args_) \ +GenericLog(RESIPROCATE_SUBSYSTEM, resip::Log::Info, args_) + +#define WarningLog(args_) \ +GenericLog(RESIPROCATE_SUBSYSTEM, resip::Log::Warning, args_) + +#define ErrLog(args_) \ +GenericLog(RESIPROCATE_SUBSYSTEM, resip::Log::Err, args_) + +#define CritLog(args_) \ +GenericLog(RESIPROCATE_SUBSYSTEM, resip::Log::Crit, args_) + +static inline bool +genericLogCheckLevel(resip::Log::Level level, const resip::Subsystem& sub) +{ + return resip::Log::isLogging(level, sub); +} + +// do/while allows a {} block in an expression +#define GenericLog(system_, level_, args_) \ + do \ + { \ + if (genericLogCheckLevel(level_, system_)) \ + { \ + resip::Log::Guard _resip_log_guard(level_, system_, __FILE__, __LINE__); \ + _resip_log_guard.asStream() args_; \ + } \ + } while (false) + +#ifdef NO_DEBUG +// Suppress debug logging at compile time +#undef DebugLog +#define DebugLog(args_) +#undef StackLog +#define StackLog(args_) +#endif + +namespace resip +{ +/// DEPRECATED! Left for backward compatibility. +typedef Log GenericLogImpl; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/MD5Stream.cxx b/src/libs/resiprocate/rutil/MD5Stream.cxx new file mode 100644 index 00000000..b1ab07c4 --- /dev/null +++ b/src/libs/resiprocate/rutil/MD5Stream.cxx @@ -0,0 +1,135 @@ +#include "rutil/MD5Stream.hxx" + +// Remove warning about 'this' use in initiator list - pointer is only stored +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) // using this in base member initializer list +#endif + +using namespace resip; + +MD5Buffer::MD5Buffer() +{ + MD5Init(&mContext); + setp(mBuf, mBuf + sizeof(mBuf)); +} + +MD5Buffer::~MD5Buffer() +{ +} + +int +MD5Buffer::sync() +{ + size_t len = pptr() - pbase(); + if (len > 0) + { + MD5Update(&mContext, reinterpret_cast <unsigned const char*>(pbase()), (unsigned int)len); + // reset the put buffer + setp(mBuf, mBuf + sizeof(mBuf)); + } + return 0; +} + +int +MD5Buffer::overflow(int c) +{ + sync(); + if (c != -1) + { + mBuf[0] = c; + pbump(1); + return c; + } + return 0; +} + +Data +MD5Buffer::getHex() +{ + MD5Context tmp = mContext; + MD5Final((unsigned char*)mBuf, &tmp); + Data digest(Data::Share, (const char*)mBuf,16); + return digest.hex(); +} + +Data +MD5Buffer::getBin() +{ + MD5Context tmp = mContext; + MD5Final((unsigned char*)mBuf, &tmp); + Data digest(Data::Share, (const char*)mBuf,16); + return digest; +} + +MD5Stream::MD5Stream() + : std::ostream(this) +{ +} + +MD5Stream::~MD5Stream() +{} + +Data +MD5Stream::getHex() +{ + flush(); + return MD5Buffer::getHex(); + //return mStreambuf.getHex(); +} + +Data +MD5Stream::getBin() +{ + flush(); + return MD5Buffer::getBin(); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/MD5Stream.hxx b/src/libs/resiprocate/rutil/MD5Stream.hxx new file mode 100644 index 00000000..dd2df4eb --- /dev/null +++ b/src/libs/resiprocate/rutil/MD5Stream.hxx @@ -0,0 +1,101 @@ +#if !defined(RESIP_MD5STREAM_HXX) +#define RESIP_MD5STREAM_HXX + +#include <iostream> +#include "rutil/Data.hxx" +#include "rutil/vmd5.hxx" + +namespace resip +{ + +/** + @brief Implementation of std::streambuf used to back the MD5Stream. + */ +class MD5Buffer : public std::streambuf +{ + public: + MD5Buffer(); + virtual ~MD5Buffer(); + /** @returns the MD5 hexadecimal representation of the data from the buffer + */ + Data getHex(); + Data getBin(); + protected: + virtual int sync(); + virtual int overflow(int c = -1); + private: + char mBuf[64]; + MD5Context mContext; +}; + +/** + @brief Used to accumlate data written to the stream in a MD5Buffer and + convert the data to MD5. + */ +class MD5Stream : private MD5Buffer, public std::ostream +{ + public: + MD5Stream(); + ~MD5Stream(); + /** Calls flush() on itself and returns the MD5 data in hex format. + @returns the MD5 hexadecimal representation of the data written to the + stream and convert the data to MD5. + */ + Data getHex(); + Data getBin(); + private: + //MD5Buffer mStreambuf; +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Makefile b/src/libs/resiprocate/rutil/Makefile new file mode 100644 index 00000000..127da8aa --- /dev/null +++ b/src/libs/resiprocate/rutil/Makefile @@ -0,0 +1,157 @@ +############################################################################# +# Makefile for building: rutil +# Generated by qmake (2.01a) (Qt 4.7.4) on: ?? 19. ??? 14:08:39 2011 +# Project: rutil.pro +# Template: lib +# Command: d:\tools\qtsdk\desktop\qt\4.7.4\msvc2008\bin\qmake.exe -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile rutil.pro +############################################################################# + +first: debug +install: debug-install +uninstall: debug-uninstall +MAKEFILE = Makefile +QMAKE = d:\tools\qtsdk\desktop\qt\4.7.4\msvc2008\bin\qmake.exe +DEL_FILE = del +CHK_DIR_EXISTS= if not exist +MKDIR = mkdir +COPY = copy /y +COPY_FILE = $(COPY) +COPY_DIR = xcopy /s /q /y /i +INSTALL_FILE = $(COPY_FILE) +INSTALL_PROGRAM = $(COPY_FILE) +INSTALL_DIR = $(COPY_DIR) +DEL_FILE = del +SYMLINK = +DEL_DIR = rmdir +MOVE = move +CHK_DIR_EXISTS= if not exist +MKDIR = mkdir +SUBTARGETS = \ + debug \ + release + +debug: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug +debug-make_default: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug +debug-make_first: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug first +debug-all: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug all +debug-clean: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug clean +debug-distclean: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug distclean +debug-install: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug install +debug-uninstall: $(MAKEFILE).Debug FORCE + $(MAKE) -f $(MAKEFILE).Debug uninstall +release: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release +release-make_default: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release +release-make_first: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release first +release-all: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release all +release-clean: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release clean +release-distclean: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release distclean +release-install: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release install +release-uninstall: $(MAKEFILE).Release FORCE + $(MAKE) -f $(MAKEFILE).Release uninstall + +Makefile: rutil.pro d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008\qmake.conf d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\qconfig.pri \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\modules\qt_webkit_version.pri \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_functions.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_config.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\exclusive_builds.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_pre.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_pre.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug_and_release.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_post.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_post.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\staticlib.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\static.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\rtti.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\exceptions.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\stl.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_exe.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_dll.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\warn_on.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\thread.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\moc.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\windows.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\resources.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\uic.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\yacc.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\lex.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\incredibuild_xge.prf \ + d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\include_source_dir.prf + $(QMAKE) -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile rutil.pro +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\qconfig.pri: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\modules\qt_webkit_version.pri: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_functions.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_config.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\exclusive_builds.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_pre.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_pre.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug_and_release.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_post.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_post.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\staticlib.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\static.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\rtti.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\exceptions.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\stl.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_exe.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_dll.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\warn_on.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\thread.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\moc.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\windows.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\resources.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\uic.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\yacc.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\lex.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\incredibuild_xge.prf: +d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\include_source_dir.prf: +qmake: qmake_all FORCE + @$(QMAKE) -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile rutil.pro + +qmake_all: FORCE + +make_default: debug-make_default release-make_default FORCE +make_first: debug-make_first release-make_first FORCE +all: debug-all release-all FORCE +clean: debug-clean release-clean FORCE + -$(DEL_FILE) ..\..\..\Libs\compiled\win\rutil.ilk + -$(DEL_FILE) vc*.pdb + -$(DEL_FILE) vc*.idb +distclean: debug-distclean release-distclean FORCE + -$(DEL_FILE) Makefile + -$(DEL_FILE) ..\..\..\Libs\compiled\win\rutil.pdb + +check: first + +debug-mocclean: $(MAKEFILE).Debug + $(MAKE) -f $(MAKEFILE).Debug mocclean +release-mocclean: $(MAKEFILE).Release + $(MAKE) -f $(MAKEFILE).Release mocclean +mocclean: debug-mocclean release-mocclean + +debug-mocables: $(MAKEFILE).Debug + $(MAKE) -f $(MAKEFILE).Debug mocables +release-mocables: $(MAKEFILE).Release + $(MAKE) -f $(MAKEFILE).Release mocables +mocables: debug-mocables release-mocables +FORCE: + +$(MAKEFILE).Debug: Makefile +$(MAKEFILE).Release: Makefile diff --git a/src/libs/resiprocate/rutil/Mutex.cxx b/src/libs/resiprocate/rutil/Mutex.cxx new file mode 100644 index 00000000..1c6993ed --- /dev/null +++ b/src/libs/resiprocate/rutil/Mutex.cxx @@ -0,0 +1,136 @@ +/* +namespace std +{ +typedef wchar_t wint_t; +typedef unsigned int size_t; +} + +*/ +#include <cassert> +#include <cerrno> +#include "rutil/Mutex.hxx" + +#if defined(WIN32) +# include <windows.h> +# include <winbase.h> +#else +# include <pthread.h> +#endif + +using namespace resip; + +Mutex::Mutex() +{ +#ifndef WIN32 + int rc = pthread_mutex_init(&mId,0); + (void)rc; + assert( rc == 0 ); +#else + // Note: Windows Critical sections are recursive in nature and perhaps + // this implementation calls for a non-recursive implementation + // (since there also exists a RecursiveMutex class). The effort + // to make this non-recursive just doesn't make sense though. (SLG) + InitializeCriticalSection(&mId); +#endif +} + + +Mutex::~Mutex () +{ +#ifndef WIN32 + int rc = pthread_mutex_destroy(&mId); + (void)rc; + assert( rc != EBUSY ); // currently locked + assert( rc == 0 ); +#else + DeleteCriticalSection(&mId); +#endif +} + + +void +Mutex::lock() +{ +#ifndef WIN32 + int rc = pthread_mutex_lock(&mId); + (void)rc; + assert( rc != EINVAL ); + assert( rc != EDEADLK ); + assert( rc == 0 ); +#else + EnterCriticalSection(&mId); +#endif +} + +void +Mutex::unlock() +{ +#ifndef WIN32 + int rc = pthread_mutex_unlock(&mId); + (void)rc; + assert( rc != EINVAL ); + assert( rc != EPERM ); + assert( rc == 0 ); +#else + LeaveCriticalSection(&mId); +#endif +} + +#ifndef WIN32 +pthread_mutex_t* +Mutex::getId() const +{ + return ( &mId ); +} +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Mutex.hxx b/src/libs/resiprocate/rutil/Mutex.hxx new file mode 100644 index 00000000..a4fc4390 --- /dev/null +++ b/src/libs/resiprocate/rutil/Mutex.hxx @@ -0,0 +1,111 @@ +#if !defined(RESIP_MUTEX_HXX) +#define RESIP_MUTEX_HXX + +#include "rutil/compat.hxx" +#include "rutil/Lockable.hxx" + + +namespace resip +{ +class Condition; + +/** + @brief A semaphore that can be locked by only one thread at a time. + + Used to serialize access to some resource (such as a data member). Here's + an example: + + @code + void + Log::setLevel(Level level) + { + Lock lock(_mutex); + _level = level; + } + @endcode + + As indicated in the example, you will probably never use any member function + in this class. The 'Lock' class provides this functionality. + + @see Lock + @see Condition + +*/ +class Mutex : public Lockable +{ + friend class Condition; + + public: + Mutex(); + virtual ~Mutex(); + virtual void lock(); + virtual void unlock(); + + private: + // !kh! + // no value sematics, therefore private and not implemented. + Mutex (const Mutex&); + Mutex& operator= (const Mutex&); + + private: +#ifdef WIN32 + CRITICAL_SECTION mId; +#else + mutable pthread_mutex_t mId; + pthread_mutex_t* getId() const; +#endif +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/ParseBuffer.cxx b/src/libs/resiprocate/rutil/ParseBuffer.cxx new file mode 100644 index 00000000..5d6398df --- /dev/null +++ b/src/libs/resiprocate/rutil/ParseBuffer.cxx @@ -0,0 +1,1042 @@ +#include <cassert> + +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/ParseException.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +const char* ParseBuffer::ParamTerm = ";?"; // maybe include "@>,"? +const char* ParseBuffer::Whitespace = " \t\r\n"; +const Data ParseBuffer::Pointer::msg("dereferenced ParseBuffer eof"); + +ParseBuffer::ParseBuffer(const char* buff, size_t len, + const Data& errorContext) + : mBuff(buff), + mPosition(buff), + mEnd(buff+len), + mErrorContext(errorContext) +{} + +ParseBuffer::ParseBuffer(const Data& data, + const Data& errorContext) + : mBuff(data.data()), + mPosition(mBuff), + mEnd(mBuff + data.size()), + mErrorContext(errorContext) +{} + +ParseBuffer::ParseBuffer(const ParseBuffer& rhs) + : mBuff(rhs.mBuff), + mPosition(rhs.mPosition), + mEnd(rhs.mEnd), + mErrorContext(rhs.mErrorContext) +{} + +ParseBuffer& +ParseBuffer::operator=(const ParseBuffer& rhs) +{ + mBuff = rhs.mBuff; + mPosition = rhs.mPosition; + mEnd = rhs.mEnd; + + return *this; +} + +ParseBuffer::CurrentPosition +ParseBuffer::skipChar(char c) +{ + if (eof()) + { + fail(__FILE__, __LINE__,"skipped over eof"); + } + if (*mPosition != c) + { + Data msg("expected '"); + msg += c; + msg += "'"; + fail(__FILE__, __LINE__,msg); + } + ++mPosition; + return CurrentPosition(*this); +} + +ParseBuffer::CurrentPosition +ParseBuffer::skipChars(const char* cs) +{ + const char* match = cs; + while (*match != 0) + { + if (eof() || (*match != *mPosition)) + { + Data msg("Expected \""); + msg += cs; + msg += "\""; + fail(__FILE__, __LINE__,msg); + } + match++; + mPosition++; + } + return CurrentPosition(*this); +} + +ParseBuffer::CurrentPosition +ParseBuffer::skipChars(const Data& cs) +{ + const char* match = cs.data(); + for(Data::size_type i = 0; i < cs.size(); i++) + { + if (eof() || (*match != *mPosition)) + { + Data msg( "Expected \""); + msg += cs; + msg += "\""; + fail(__FILE__, __LINE__,msg); + } + match++; + mPosition++; + } + return CurrentPosition(*this); +} + +ParseBuffer::CurrentPosition +ParseBuffer::skipNonWhitespace() +{ + assertNotEof(); + while (mPosition < mEnd) + { + switch (*mPosition) + { + case ' ' : + case '\t' : + case '\r' : + case '\n' : + return CurrentPosition(*this); + default : + mPosition++; + } + } + return CurrentPosition(*this); +} + +ParseBuffer::CurrentPosition +ParseBuffer::skipWhitespace() +{ + while (mPosition < mEnd) + { + switch (*mPosition) + { + case ' ' : + case '\t' : + case '\r' : + case '\n' : + { + mPosition++; + break; + } + default : + return CurrentPosition(*this); + } + } + return CurrentPosition(*this); +} + +// "SIP header field values can be folded onto multiple lines if the +// continuation line begins with a space or horizontal tab" + +// CR can be quote with \ within "" and comments -- treat \CR as whitespace +ParseBuffer::CurrentPosition +ParseBuffer::skipLWS() +{ + enum State {WS, CR, LF}; + State state = WS; + while (mPosition < mEnd) + { + char c = *mPosition++; + if (c == '\\') + { + // treat escaped CR and LF as space + c = *mPosition++; + if (c == '\r' || c == '\n') + { + c = ' '; + } + } + switch (*mPosition++) + { + case ' ' : + case '\t' : + { + state = WS; + break; + } + case '\r' : + { + state = CR; + break; + } + case '\n' : + { + if (state == CR) + { + state = LF; + } + else + { + state = WS; + } + break; + } + default : + { + // terminating CRLF not skipped + if (state == LF) + { + mPosition -= 3; + } + else + { + mPosition--; + } + return CurrentPosition(*this); + } + } + } + return CurrentPosition(*this); +} + +static Data CRLF("\r\n"); +ParseBuffer::CurrentPosition +ParseBuffer::skipToTermCRLF() +{ + while (mPosition < mEnd) + { + skipToChars(CRLF); + mPosition += 2; + if ((*mPosition != ' ' && + *mPosition != '\t' && + // check for \CRLF -- not terminating + // \\CRLF -- terminating + ((mPosition-3 < mBuff || *(mPosition-3) != '\\') || + (mPosition-4 > mBuff && *(mPosition-4) == '\\')))) + { + mPosition -= 2; + return CurrentPosition(*this); + } + } + return CurrentPosition(*this); +} + +ParseBuffer::CurrentPosition +ParseBuffer::skipToChars(const char* cs) +{ + assert(cs); + unsigned int l = (unsigned int)strlen(cs); + + const char* rpos; + const char* cpos; + while (mPosition < mEnd) + { + rpos = mPosition; + cpos = cs; + for (unsigned int i = 0; i < l; i++) + { + if (*cpos++ != *rpos++) + { + mPosition++; + goto skip; + } + } + return CurrentPosition(*this); + skip: ; + } + return CurrentPosition(*this); +} + +ParseBuffer::CurrentPosition +ParseBuffer::skipToChars(const Data& sub) +{ + const char* begSub = sub.mBuf; + const char* endSub = sub.mBuf + sub.mSize; + if(begSub == endSub) + { + fail(__FILE__, __LINE__, "ParseBuffer::skipToChars() called with an " + "empty string. Don't do this!"); + } + + while (true) + { +next: + const char* searchPos = mPosition; + const char* subPos = sub.mBuf; + + while (subPos != endSub) + { + if (searchPos == mEnd) + { + // nope + mPosition = mEnd; + return CurrentPosition(*this); + } + if (*subPos++ != *searchPos++) + { + // nope, but try the next position + ++mPosition; + goto next; + } + } + // found a match + return CurrentPosition(*this); + } +} + +bool +ParseBuffer::oneOf(char c, const char* cs) +{ + while (*cs) + { + if (c == *(cs++)) + { + return true; + } + } + return false; +} + +bool +ParseBuffer::oneOf(char c, const Data& cs) +{ + for (Data::size_type i = 0; i < cs.size(); i++) + { + if (c == cs[i]) + { + return true; + } + } + return false; +} + +ParseBuffer::CurrentPosition +ParseBuffer::skipToOneOf(const char* cs) +{ + while (mPosition < mEnd) + { + if (oneOf(*mPosition, cs)) + { + return CurrentPosition(*this); + } + else + { + mPosition++; + } + } + return CurrentPosition(*this); +} + +ParseBuffer::CurrentPosition +ParseBuffer::skipToOneOf(const char* cs1, + const char* cs2) +{ + while (mPosition < mEnd) + { + if (oneOf(*mPosition, cs1) || + oneOf(*mPosition, cs2)) + { + return CurrentPosition(*this); + } + else + { + mPosition++; + } + } + return CurrentPosition(*this); +} + +ParseBuffer::CurrentPosition +ParseBuffer::skipToOneOf(const Data& cs) +{ + while (mPosition < mEnd) + { + if (oneOf(*mPosition, cs)) + { + return CurrentPosition(*this); + } + else + { + mPosition++; + } + } + return CurrentPosition(*this); +} + +ParseBuffer::CurrentPosition +ParseBuffer::skipToOneOf(const Data& cs1, + const Data& cs2) +{ + while (mPosition < mEnd) + { + if (oneOf(*mPosition, cs1) || + oneOf(*mPosition, cs2)) + { + return CurrentPosition(*this); + } + else + { + mPosition++; + } + } + return CurrentPosition(*this); +} + +const char* +ParseBuffer::skipToEndQuote(char quote) +{ + while (mPosition < mEnd) + { + // !dlb! mark character encoding + if (*mPosition == '\\') + { + mPosition += 2; + } + else if (*mPosition == quote) + { + return mPosition; + } + else + { + mPosition++; + } + } + + { + Data msg("Missing '"); + msg += quote; + msg += "'"; + fail(__FILE__,__LINE__,msg); + } + return 0; +} + +const char* +ParseBuffer::skipBackChar() +{ + if (bof()) + { + fail(__FILE__, __LINE__,"backed over beginning of buffer"); + } + mPosition--; + return mPosition; +} + +const char* +ParseBuffer::skipBackWhitespace() +{ + while (!bof()) + { + switch (*(--mPosition)) + { + case ' ' : + case '\t' : + case '\r' : + case '\n' : + { + break; + } + default : + return ++mPosition; + } + } + return mBuff; +} + +// abcde +// ^ +// skipBackChar('d'); +// abcde +// ^ +// skipChar('d'); +// abcde +// ^ +const char* +ParseBuffer::skipBackChar(char c) +{ + if (bof()) + { + fail(__FILE__, __LINE__,"backed over beginning of buffer"); + } + if (*(--mPosition) != c) + { + Data msg( "Expected '"); + msg += c; + msg += "'"; + fail(__FILE__, __LINE__,msg); + } + return mPosition; +} + +// abcde +// ^ +// skipBackToChar('c'); +// abcde +// ^ +const char* +ParseBuffer::skipBackToChar(char c) +{ + while (!bof()) + { + if (*(--mPosition) == c) + { + return ++mPosition; + } + } + return mBuff; +} + +const char* +ParseBuffer::skipBackToOneOf(const char* cs) +{ + while (!bof()) + { + if (oneOf(*(--mPosition),cs)) + { + return ++mPosition; + } + } + return mBuff; +} + +void +ParseBuffer::data(Data& data, const char* start) const +{ + if (!(mBuff <= start && start <= mPosition)) + { + fail(__FILE__, __LINE__,"Bad anchor position"); + } + + if (data.mShareEnum == Data::Take) + { + delete[] data.mBuf; + } + data.mSize = (unsigned int)(mPosition - start); + data.mBuf = const_cast<char*>(start); + data.mCapacity = data.mSize; + data.mShareEnum = Data::Share; +} + +static const unsigned char hexToByte[256] = +{ +// 0 1 2 3 4 5 6 7 8 9 a b c d e f + 'k','k','k','k','k','k','k','k','k','k','k','k','k','k','k','k',//0 + 'k','k','k','k','k','k','k','k','k','k','k','k','k','k','k','k',//1 + 'k','k','k','k','k','k','k','k','k','k','k','k','k','k','k','k',//2 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'k','k','k','k','k','k', //3 + 'k',0xA,0xB,0xC,0xD,0xE,0xF,'k','k','k','k','k','k','k','k','k', //4 + 'k','k','k','k','k','k','k','k','k','k','k','k','k','k','k','k',//5 + 'k',0xA,0xB,0xC,0xD,0xE,0xF,'k','k','k','k','k','k','k','k','k', //6 + 'k','k','k','k','k','k','k','k','k','k','k','k','k','k','k','k',//8 + 'k','k','k','k','k','k','k','k','k','k','k','k','k','k','k','k',//9 + 'k','k','k','k','k','k','k','k','k','k','k','k','k','k','k','k',//a + 'k','k','k','k','k','k','k','k','k','k','k','k','k','k','k','k',//b + 'k','k','k','k','k','k','k','k','k','k','k','k','k','k','k','k',//c + 'k','k','k','k','k','k','k','k','k','k','k','k','k','k','k','k',//d + 'k','k','k','k','k','k','k','k','k','k','k','k','k','k','k','k',//e + 'k','k','k','k','k','k','k','k','k','k','k','k','k','k','k','k' //f + +}; + +void +ParseBuffer::dataUnescaped(Data& dataToUse, const char* start) const +{ + if (!(mBuff <= start && start <= mPosition)) + { + fail(__FILE__, __LINE__, "Bad anchor position"); + } + + { + const char* current = start; + while (current < mPosition) + { + if (*current == '%') + { + // needs to be unencoded + goto copy; + } + current++; + } + // can use an overlay + data(dataToUse, start); + return; + } + + copy: + if ((size_t)(mPosition-start) > dataToUse.mCapacity) + { + dataToUse.resize(mPosition-start, false); + } + + char* target = dataToUse.mBuf; + const char* current = start; + while (current < mPosition) + { + if (*current == '%') + { + current++; + if (mPosition - current < 2) + { + fail(__FILE__, __LINE__,"Illegal escaping"); + } + const char high = hexToByte[(unsigned char)*current]; + const char low = hexToByte[(unsigned char)*(current + 1)]; + if (high!='k' && low!='k') + { + unsigned char escaped = 0; + escaped = high << 4 | low; + // !bwc! I think this check is bogus, especially the ':' (58) check + // You could maybe argue that the point of %-escaping is to allow + // the use of UTF-8 data (including ASCII that is not allowed in an + // on-the-wire representation of whatever it is we're unescaping), + // and not unprintable characters (the unprintable codes are not + // used by UTF-8). + if (escaped > 31 && escaped != 127 && escaped != 58) + { + *target++ = escaped; + current+= 2; + } + else + { + *target++ = '%'; + *target++ = *current++; + *target++ = *current++; + } + } + else + { + fail(__FILE__, __LINE__,"Illegal escaping, not hex"); + } + } + else + { + *target++ = *current++; + } + } + *target = 0; + dataToUse.mSize = target - dataToUse.mBuf; +} + +Data +ParseBuffer::data(const char* start) const +{ + if (!(mBuff <= start && start <= mPosition)) + { + + fail(__FILE__, __LINE__,"Bad anchor position"); + } + + Data data(start, mPosition - start); + return data; +} + +int +ParseBuffer::integer() +{ + if (this->eof()) + { + fail(__FILE__, __LINE__,"Expected a digit, got eof "); + } + + int signum = 1; + if (*mPosition == '-') + { + signum = -1; + ++mPosition; + assertNotEof(); + } + else if (*mPosition == '+') + { + ++mPosition; + assertNotEof(); + } + + if (!isdigit(*mPosition)) + { + Data msg("Expected a digit, got: "); + msg += Data(mPosition, (mEnd - mPosition)); + fail(__FILE__, __LINE__,msg); + } + + int num = 0; + int last=0; + while (!eof() && isdigit(*mPosition)) + { + last=num; + num = num*10 + (*mPosition-'0'); + if(last > num) + { + fail(__FILE__, __LINE__,"Overflow detected."); + } + ++mPosition; + } + + return signum*num; +} + +UInt8 +ParseBuffer::uInt8() +{ + const char* begin=mPosition; + UInt8 num = 0; + UInt8 last = 0; + while (!eof() && isdigit(*mPosition)) + { + last = num; + num = num*10 + (*mPosition-'0'); + if(last>num) + { + fail(__FILE__, __LINE__,"Overflow detected."); + } + ++mPosition; + } + + if(mPosition==begin) + { + fail(__FILE__, __LINE__,"Expected a digit"); + } + return num; +} + + +//!dcm! -- merge these, ask about length checks +UInt32 +ParseBuffer::uInt32() +{ + const char* begin=mPosition; + UInt32 num = 0; + while (!eof() && isdigit(*mPosition)) + { + num = num*10 + (*mPosition-'0'); + ++mPosition; + } + + switch(mPosition-begin) + { + case 0: + fail(__FILE__, __LINE__,"Expected a digit"); + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + break; + case 10: + if(*begin<'4') + { + break; + } + else if(*begin=='4' && num >= 4000000000UL) + { + break; + } + default: + fail(__FILE__, __LINE__,"Overflow detected"); + } + + return num; +} + +UInt64 +ParseBuffer::uInt64() +{ + const char* begin=mPosition; + UInt64 num = 0; + while (!eof() && isdigit(*mPosition)) + { + num = num*10 + (*mPosition-'0'); + ++mPosition; + } + + switch(mPosition-begin) + { + case 0: + fail(__FILE__, __LINE__,"Expected a digit"); + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + break; + case 20: + if(*begin=='1' && num >= 10000000000000000000ULL) + { + break; + } + default: + fail(__FILE__, __LINE__,"Overflow detected"); + } + + return num; +} + +#ifndef RESIP_FIXED_POINT +float +ParseBuffer::floatVal() +{ + const char* s = mPosition; + try + { + float mant = 0.0; + int num = integer(); + + if (*mPosition == '.') + { + skipChar(); + const char* pos = mPosition; + mant = float(integer()); + int s = int(mPosition - pos); + while (s--) + { + mant /= 10.0; + } + } + return num + mant; + } + catch (ParseException&) + { + Data msg("Expected a floating point value, got: "); + msg += Data(s, mPosition - s); + fail(__FILE__, __LINE__,msg); + return 0.0; + } +} +#endif + +int +ParseBuffer::qVal() +{ + // parse a qvalue into an integer between 0 and 1000 (ex: 1.0 -> 1000, 0.8 -> 800, 0.05 -> 50) + const char* s = mPosition; + try + { + int num = integer(); + if (num == 1) + { + num = 1000; + } + else if (num != 0) + { + // error: qvalue must start with 1 or 0 + return 0; + } + + if (*mPosition == '.') + { + skipChar(); + + int i = 100; + while(!eof() && isdigit(*mPosition) && i) + { + num += (*mPosition-'0') * i; + i /= 10; + skipChar(); + } + } + return num; + } + catch (ParseException&) + { + Data msg("Expected a floating point value, got: "); + msg += Data(s, mPosition - s); + fail(__FILE__, __LINE__,msg); + return 0; + } +} + + +Data +spaces(unsigned int numSpaces) +{ + Data sps(numSpaces, Data::Preallocate); + for (unsigned int i = 0; i < numSpaces; i++) + { + sps += ' '; + } + return sps; +} + +Data +escapeAndAnnotate(const char* buffer, + Data::size_type size, + const char* position) +{ + Data ret(2*size+16, Data::Preallocate); + + const char* lastReturn = buffer; + int lineCount = 0; + bool doneAt = false; + + const char* p = buffer; + for (unsigned int i = 0; i < size; i++) + { + unsigned char c = *p++; + + switch (c) + { + case 0x0D: // CR + { + continue; + } + case 0x0A: // LF + { + if (!doneAt && p >= position) + { + ret += "[CRLF]\n"; + ret += spaces((unsigned int)(position - lastReturn)); + ret += "^[CRLF]\n"; + doneAt = true; + } + else + { + lastReturn = p; + ret += c; + } + lineCount++; + continue; + } + } + + if (iscntrl(c) || (c >= 0x7F)) + { + ret +='*'; // indicates unprintable character + continue; + } + + ret += c; + } + if (!doneAt && p >= position) + { + ret += "\n"; + ret += spaces((unsigned int)(position - lastReturn)); + ret += "^\n"; + } + + return ret; +} + +void +ParseBuffer::fail(const char* file, unsigned int line, const Data& detail) const +{ + Data errmsg; + { + DataStream ds(errmsg); + ds << file << ":" << line + << ", Parse failed "; + + if (detail != Data::Empty) ds << detail << ' ' ; + + ds << "in context: " << mErrorContext + << std::endl + << escapeAndAnnotate(mBuff, mEnd - mBuff, mPosition); + + ds.flush(); + } + DebugLog(<<errmsg); + throw ParseException(errmsg, mErrorContext, file, line); +} + +ParseBuffer::Pointer::Pointer(const ParseBuffer& pb, + const char* position, + bool atEof) + : mPb(pb), + mPosition(position), + mIsValid(!atEof) +{} + +ParseBuffer::Pointer::Pointer(const CurrentPosition& pos) : + mPb(pos.mPb), + mPosition(pos), + mIsValid(pos.mPb.valid()) +{} + +const char& +ParseBuffer::Pointer::operator*() const +{ + if (mIsValid) + { + return *mPosition; + } + else + { + throw ParseException(msg, mPb.getContext(), __FILE__, __LINE__); + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/ParseBuffer.hxx b/src/libs/resiprocate/rutil/ParseBuffer.hxx new file mode 100644 index 00000000..ceb489c2 --- /dev/null +++ b/src/libs/resiprocate/rutil/ParseBuffer.hxx @@ -0,0 +1,319 @@ +#if !defined(RESIP_PARSEBUFFER_HXX) +#define RESIP_PARSEBUFFER_HXX + +#include "rutil/Data.hxx" +#include "rutil/ParseException.hxx" + +namespace resip +{ + +/** + @brief Provides string-parsing functionality with protection from buffer + overflow. + + Throws ParseException when parse failures occur. + @ingroup text_proc +*/ +class ParseBuffer +{ + public: + // does NOT OWN the buffer memory + ParseBuffer(const char* buff, size_t len, + const Data& errorContext = Data::Empty); + + explicit ParseBuffer(const Data& data, + const Data& errorContext = Data::Empty); + + ParseBuffer(const ParseBuffer& other); + +///@cond + // .bwc. Backwards-compatibility hack; ParseException used to be + // a full inner class of ParseBuffer, and we also had a separate + // ParseException class that other things used. For consistency, we have + // moved everything over to use ParseException, but there is app-code + // out there that still expects ParseException to exist. + typedef ParseException Exception; +///@endcond + + private: + /** + @internal + @brief Provides some access to the current position of a ParseBuffer, + which guards against invalid accesses. Just a wrapper around a + ParseBuffer&, so is very cheap to initialize/copy. + */ + class CurrentPosition + { + public: + inline explicit CurrentPosition(const ParseBuffer& pb) : + mPb(pb) + {} + + operator const char*() const + { + return mPb.mPosition; + } + + const char& operator*() const + { + mPb.assertNotEof(); + return *mPb.mPosition; + } + + const ParseBuffer& mPb; + }; + + /** + @internal + @brief Similar to CurrentPosition, but does not move depending on the + state of the ParseBuffer. Initializing one of these is more expensive. + */ + class Pointer + { + public: + Pointer(const ParseBuffer& pb, + const char* position, + bool atEof); + Pointer(const CurrentPosition& pos); + + operator const char*() const + { + return mPosition; + } + + const char& operator*() const; + private: + const ParseBuffer& mPb; + const char* mPosition; + const bool mIsValid; + static const Data msg; + }; + + public: + const Data& getContext() const {return mErrorContext;} + + // allow the buffer to be rolled back + ParseBuffer& operator=(const ParseBuffer& other); + void reset(const char* pos) + { + assert( mBuff <= mEnd); + assert( (pos >= mBuff) && (pos <= mEnd) ); + mPosition = pos; + } + + // abcdef + // ^ ^ + // begin end + bool eof() const { return mPosition >= mEnd;} + bool bof() const { return mPosition <= mBuff;} + bool valid() const {return (!eof()) && (!bof());} + Pointer start() const { return Pointer(*this, mBuff, eof()); } + CurrentPosition position() const { return CurrentPosition(*this); } + Pointer end() const { return Pointer(*this, mEnd, true); } + + CurrentPosition skipChar() + { + if (eof()) + { + fail(__FILE__, __LINE__,"skipped over eof"); + } + ++mPosition; + return CurrentPosition(*this); + } + + CurrentPosition skipChar(char c); + CurrentPosition skipChars(const char* cs); + CurrentPosition skipChars(const Data& cs); + CurrentPosition skipNonWhitespace(); + CurrentPosition skipWhitespace(); + CurrentPosition skipLWS(); + CurrentPosition skipToTermCRLF(); + CurrentPosition skipToChar(char c) + { + mPosition = (const char*)memchr(mPosition, c, mEnd-mPosition); + if(!mPosition) + { + mPosition=mEnd; + } + return CurrentPosition(*this); + } + CurrentPosition skipToChars(const char* cs); + CurrentPosition skipToChars(const Data& cs); // ?dlb? case sensitivity arg? + CurrentPosition skipToOneOf(const char* cs); + CurrentPosition skipToOneOf(const char* cs1, const char* cs2); + CurrentPosition skipToOneOf(const Data& cs); + CurrentPosition skipToOneOf(const Data& cs1, const Data& cs2); + + // std::bitset based parse function + CurrentPosition skipChars(const std::bitset<256>& cs) + { + while (mPosition < mEnd) + { + if (cs.test((unsigned char)(*mPosition))) + { + mPosition++; + } + else + { + return CurrentPosition(*this); + } + } + return CurrentPosition(*this); + } + + CurrentPosition skipToOneOf(const std::bitset<256>& cs) + { + while (mPosition < mEnd) + { + if (cs.test((unsigned char)(*mPosition))) + { + return CurrentPosition(*this); + } + else + { + mPosition++; + } + } + return CurrentPosition(*this); + } + + const char* skipToEndQuote(char quote = '"'); + CurrentPosition skipN(int count) + { + mPosition += count; + if (mPosition > mEnd) + { + fail(__FILE__, __LINE__, "skipped eof"); + } + return CurrentPosition(*this); + } + + CurrentPosition skipToEnd() + { + mPosition = mEnd; + return CurrentPosition(*this); + } + + // inverse of skipChar() -- end up at char not before it + const char* skipBackChar(); + const char* skipBackWhitespace(); + const char* skipBackN(int count) + { + mPosition -= count; + if (bof()) + { + fail(__FILE__, __LINE__,"backed over beginning of buffer"); + } + return mPosition; + } + + const char* skipBackChar(char c); + const char* skipBackToChar(char c); + const char* skipBackToOneOf(const char* cs); + + void assertEof() const + { + if (!eof()) + { + fail(__FILE__, __LINE__,"expected eof"); + } + } + + void assertNotEof() const + { + if (eof()) + { + fail(__FILE__, __LINE__,"unexpected eof"); + } + } + + void fail(const char* file, unsigned int line, + const Data& errmsg = Data::Empty) const; + + /// make the passed in data share memory with the buffer (uses Data::Share) + void data(Data& data, const char* start) const; + + Data data(const char* start) const; + + void dataUnescaped(Data& data, const char* start) const; + + int integer(); + + + UInt8 uInt8(); + UInt32 uInt32(); + UInt64 uInt64(); + + RESIP_DEPRECATED(UInt64 unsignedLongLong()){return uInt64();} + RESIP_DEPRECATED(unsigned long unsignedInteger()){return uInt32();} + +#ifndef RESIP_FIXED_POINT + float floatVal(); +#endif + int qVal(); + + static bool oneOf(char c, const char* cs); + static bool oneOf(char c, const Data& cs); + static const char* Whitespace; + static const char* ParamTerm; + private: + friend class ParseBuffer::CurrentPosition; + const char* mBuff; + const char* mPosition; + const char* mEnd; + const Data& mErrorContext; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/ParseException.cxx b/src/libs/resiprocate/rutil/ParseException.cxx new file mode 100644 index 00000000..819d2321 --- /dev/null +++ b/src/libs/resiprocate/rutil/ParseException.cxx @@ -0,0 +1,29 @@ +#include "rutil/ParseException.hxx" + +namespace resip +{ + +ParseException::ParseException(const Data& msg, + const Data& context, + const Data& file, + const int line) + : resip::BaseException(msg, file, line), + mContext(context) +{} + +ParseException::~ParseException() throw() +{} + +const char* +ParseException::name() const +{ + return "ParseException"; +} + +const Data& +ParseException::getContext() const +{ + return mContext; +} + +} diff --git a/src/libs/resiprocate/rutil/ParseException.hxx b/src/libs/resiprocate/rutil/ParseException.hxx new file mode 100644 index 00000000..e4eee420 --- /dev/null +++ b/src/libs/resiprocate/rutil/ParseException.hxx @@ -0,0 +1,83 @@ +#if !defined(RESIP_PARSEEXCEPTION_HXX) +#define RESIP_PARSEEXCEPTION_HXX + +#include "rutil/BaseException.hxx" + +#include "rutil/Data.hxx" + +namespace resip +{ + +/** + @brief BaseException used to indicate parse failures. + + @see ParseBuffer +*/ +class ParseException : public BaseException +{ + public: + ParseException(const Data& msg, + const Data& context, + const Data& file, + const int line); + ~ParseException() throw(); + const char* name() const; + const Data& getContext() const; + + private: + Data mContext; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Poll.cxx b/src/libs/resiprocate/rutil/Poll.cxx new file mode 100644 index 00000000..f09ceeca --- /dev/null +++ b/src/libs/resiprocate/rutil/Poll.cxx @@ -0,0 +1,294 @@ +#include <stdlib.h> +#include "rutil/Poll.hxx" + +using namespace resip; +using namespace std; + +#if !defined(RESIP_POLL_IMPL_POLL) && !defined(RESIP_POLL_IMPL_SELECT) && !defined(RESIP_POLL_EPOLL) +#error "Define one of RESIP_POLL_IMPL_POLL, RESIP_POLL_IMPL_SELECT, or RESIP_POLL_EPOLL." +#endif + +/////////////////////////////////////////////////////////////////////////////// + +//constructor +Poll::FDEntry::FDEntry(Poll* poll, + bool isTransport, + int/*FD*/ fd) : + _poll(poll), + _fd(fd), + _stateBitMask(isTransport ? Poll::FDEntry::rsbmIsTransport : 0), + _index((unsigned short)poll->_fdEntryVector.size()) +{ + _poll->_fdEntryVector.push_back(this); +#ifdef RESIP_POLL_IMPL_POLL + pollfd pollFD; + pollFD.fd = fd; + pollFD.events = POLLIN; + _poll->_pollFDVector.push_back(pollFD); +#endif +#ifdef RESIP_POLL_IMPL_SELECT + if (_fd >= _poll->_maxFDPlus1) + { + _poll->_maxFDPlus1 = _fd + 1; + } + FD_SET(_fd, &(_poll->_readFDSet)); +#endif +#ifdef RESIP_POLL_EXTERN + _poll->_fdEntryMap.insert(std::pair<int/*FD*/, Poll::FDEntry *>(_fd, this)); +#endif +} + +//destructor +Poll::FDEntry::~FDEntry() +{ + vector<Poll::FDEntry *> &fdEntryVector = _poll->_fdEntryVector; + Poll::FDEntry *lastFDEntry = fdEntryVector[fdEntryVector.size() - 1]; + lastFDEntry->_index = _index; + fdEntryVector[_index] = lastFDEntry; + fdEntryVector.pop_back(); +#ifdef RESIP_POLL_IMPL_POLL + vector<pollfd> &pollFDVector = _poll->_pollFDVector; + pollFDVector[_index] = pollFDVector[pollFDVector.size() - 1]; + pollFDVector.pop_back(); +#endif +#ifdef RESIP_POLL_IMPL_SELECT + FD_CLR(_fd, &(_poll->_readFDSet)); + FD_CLR(_fd, &(_poll->_writeFDSet)); +#endif +#ifdef RESIP_POLL_EXTERN + _poll->_fdEntryMap.erase(_fd); +#endif +} + +void +Poll::FDEntry::clearFDState() +{ + _stateBitMask &= ~Poll::FDEntry::fdsbmAll; +} + +void +Poll::FDEntry::setIsWritePending(bool isWritePending) +{ + if (isWritePending) + { + _stateBitMask |= Poll::FDEntry::rsbmIsWritePending; +#ifdef RESIP_POLL_IMPL_POLL + _poll->_pollFDVector[_index].events |= Poll::FDEntry::fdsbmWritable; +#endif +#ifdef RESIP_POLL_IMPL_SELECT + FD_SET(_fd, &(_poll->_writeFDSet)); +#endif + } else + { + _stateBitMask &= ~Poll::FDEntry::rsbmIsWritePending; +#ifdef RESIP_POLL_IMPL_POLL + _poll->_pollFDVector[_index].events &= ~Poll::FDEntry::fdsbmWritable; +#endif +#ifdef RESIP_POLL_IMPL_SELECT + FD_CLR(_fd, &(_poll->_writeFDSet)); +#endif + } +} + +//static +int +Poll::FDEntry::compare(const Poll::FDEntry * leftFDEntry, + const Poll::FDEntry * rightFDEntry) +{ + return (leftFDEntry->getFD() - rightFDEntry->getFD()); +} + +/////////////////////////////////////////////////////////////////////////////// + +//static +int +Poll::findFDInWaitResult(int/*FD*/ fd, + const vector<Poll::FDEntry *> & waitResult) +{ + unsigned int lowIndex = 0; + unsigned int highIndex = (unsigned int)waitResult.size(); + while (lowIndex + 1 < highIndex) + { + // The goal fd is in waitResult in the range [lowIndex, highIndex[. + unsigned int midIndex = (lowIndex + highIndex) / 2; + if (waitResult[midIndex]->_fd > fd) + { + highIndex = midIndex - 1; + } + else + { + lowIndex = midIndex; + } + }//while + return lowIndex; +} + +//constructor +Poll::Poll() +#ifdef RESIP_POLL_IMPL_SELECT + : +_maxFDPlus1(0) //!jacob! Can select handle an empty poll set? +#endif +{ +#ifdef RESIP_POLL_IMPL_SELECT + FD_ZERO(&_readFDSet); + FD_ZERO(&_writeFDSet); +#endif +} + +//destructor +Poll::~Poll() +{ +} + +#ifdef RESIP_POLL_EXTERN // { + +const vector<Poll::FDEntry *> & +Poll::beforeExternWait() +{ + _waitResult.clear(); + return _fdEntryVector; +} + +bool +Poll::setEntryFDStateForExternWait(int/*FD*/ fd, + Poll::FDEntry::StateBitMask fdStateBitMask) +{ + map<int/*FD*/, Poll::FDEntry *>::const_iterator fdEntryIterator = + _fdEntryMap.find(fd); + bool isFDInPoll = (fdEntryIterator != _fdEntryMap.end()); + if (isFDInPoll) + { + Poll::FDEntry *fdEntry = fdEntryIterator->second; + fdEntry->_stateBitMask |= fdStateBitMask & Poll::FDEntry::fdsbmAll; + _waitResult.push_back(fdEntry); + } + return isFDInPoll; +} + +const vector<Poll::FDEntry *> & +Poll::afterExternWait() +{ + return _waitResult; +} + +#else //!defined(RESIP_POLL_EXTERN) } { + +const vector<Poll::FDEntry *> & +Poll::wait(int timeoutMilliSeconds) +{ + _waitResult.clear(); +#ifdef RESIP_POLL_IMPL_POLL + pollfd *pollFDArray = &(_pollFDVector.front()); + int numReadyFDs = poll(pollFDArray, + _pollFDVector.size(), + timeoutMilliSeconds); + if (numReadyFDs < 0) + { + //!jacob! poll failed. + } + for (unsigned short index = 0; numReadyFDs > 0; ++index) + { + int revents = pollFDArray[index].revents; + if (revents) + { + Poll::FDEntry *fdEntry = _fdEntryVector[index]; + fdEntry->_stateBitMask |= revents; + _waitResult.push_back(fdEntry); + --numReadyFDs; + } + }//for + qsort(&(_waitResult.front()), + _waitResult.size(), + sizeof(Poll::FDEntry *), + reinterpret_cast<int(*)(const void *, + const void *)>(&Poll::FDEntry::compare)); +#endif +#ifdef RESIP_POLL_IMPL_SELECT + fd_set readableFDSet = _readFDSet; + fd_set writableFDSet = _writeFDSet; + fd_set errorFDSet = _readFDSet; + timeval timeoutTimeVal; + timeoutTimeVal.tv_sec = timeoutMilliSeconds / 1000; + timeoutTimeVal.tv_usec = 1000 * (timeoutMilliSeconds % 1000); + int numReadyFDs = select(_maxFDPlus1, + &readableFDSet, + &writableFDSet, + &errorFDSet, + &timeoutTimeVal); + if (numReadyFDs < 0) + { + //!jacob! select failed. + } + for (unsigned short index = 0; numReadyFDs > 0; ++index) + { + Poll::FDEntry *fdEntry = _fdEntryVector[index]; + bool isFDReadable = FD_ISSET(fdEntry->_fd, &readableFDSet); + bool isFDWritable = FD_ISSET(fdEntry->_fd, &writableFDSet); + bool isFDError = FD_ISSET(fdEntry->_fd, &errorFDSet); + if (isFDReadable || isFDWritable || isFDError) + { + if (isFDReadable) + { + fdEntry->_stateBitMask |= Poll::FDEntry::fdsbmReadable; + } + if (isFDWritable) + { + fdEntry->_stateBitMask |= Poll::FDEntry::fdsbmWritable; + } + if (isFDError) + { + fdEntry->_stateBitMask |= Poll::FDEntry::fdsbmError; + } + _waitResult.push_back(fdEntry); + --numReadyFDs; + } + }//for +#endif + return _waitResult; +} + +#endif //!defined(RESIP_POLL_EXTERN) } + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Jacob Butcher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + */ diff --git a/src/libs/resiprocate/rutil/Poll.hxx b/src/libs/resiprocate/rutil/Poll.hxx new file mode 100644 index 00000000..53a54c64 --- /dev/null +++ b/src/libs/resiprocate/rutil/Poll.hxx @@ -0,0 +1,276 @@ +#if !defined(RESIP_POLL_HXX) +#define RESIP_POLL_HXX + +// One of the following macros must be defined: +//#define RESIP_POLL_IMPL_POLL +#define RESIP_POLL_IMPL_SELECT +//#define RESIP_POLL_IMPL_EPOLL // Not yet implemented. + +/* + Define this macro to support applications that must call system call "poll" + or its ilk themselves rather than calling method "Poll::wait". +*/ +#define RESIP_POLL_EXTERN + +#include <vector> + +#ifdef RESIP_POLL_IMPL_POLL +# include <sys/poll.h> +#endif + +#ifdef RESIP_POLL_IMPL_SELECT +# ifdef WIN32 +# include <winsock2.h> +# else +# include <sys/time.h> +# include <sys/types.h> +# include <unistd.h> +# endif // WIN32 +#endif // RESIP_POLL_IMPL_SELECT + +#ifdef RESIP_POLL_EXTERN +# include <map> +#endif // RESI + +namespace resip { + +/////////////////////////////////////////////////////////////////////////////// + +/** + @brief This class abstracts the Unix system call "poll". + + It offers implementations in terms of "poll" itself, "epoll", and "select". + (Respectively #ifdef'd by RESIP_POLL_IMPL_POLL, RESIP_POLL_IMPL_SELECT, and + RESIP_POLL_IMPL_EPOLL.) + File descriptors are wrapped by inner class "Poll::FDEntry". + The actual "poll" call is represented by method "wait", or if an application + wants to control the system call directly, it can instead use methods + "beforeExternWait", "setEntryFDStateForExternWait", and "afterExternWait". + (The latter are selected by #define-ing RESIP_POLL_EXTERN.) +*/ +class Poll { + + public: + + class FDEntry { + + friend class Poll; + + public: + + typedef unsigned short StateBitMask; // FDStateBitMask | ResipStateBitMask. + enum FDStateBitMaskEnum { + fdsbmReadable = 0x0001, // (POLLIN) + fdsbmWritable = 0x0004, // (POLLOUT) + fdsbmError = 0x0008, // (POLLERR) + fdsbmAll = Poll::FDEntry::fdsbmReadable | + Poll::FDEntry::fdsbmWritable | + Poll::FDEntry::fdsbmError + }; + typedef StateBitMask FDStateBitMask; + enum ResipStateBitMaskEnum { + rsbmIsTransport = 0x0040, + rsbmIsWritePending = 0x0080 + }; + typedef StateBitMask ResipStateBitMask; + + private: + + static + int + compare(const Poll::FDEntry * leftFDEntry, + const Poll::FDEntry * rightFDEntry); + + // Fields: + Poll * _poll; + int/*FD*/ _fd; + Poll::FDEntry::StateBitMask _stateBitMask; + unsigned short _index; // Within "_poll->_fdEntryVector". + + public: + + //constructor + FDEntry(Poll * poll, + bool isTransport, + int/*FD*/ fd); + + //destructor + virtual ~FDEntry(); + + inline + int//FD + getFD() const + { + return _fd; + } + + inline + Poll::FDEntry::StateBitMask + getStateBitMask() const + { + return _stateBitMask; + } + + void + clearFDState(); + + protected: + + void + setIsWritePending(bool isWritePending); + + virtual void doRead() {}; + virtual void doWrite() {}; + virtual void doError() {}; + + private: + + // Copy constructor: declared but not defined + FDEntry(const Poll::FDEntry & from); + + // Assignment: declared but not defined + Poll::FDEntry & + operator=(const Poll::FDEntry & from); + + }; + friend class Poll::FDEntry; + + private: + + // Fields: + std::vector<Poll::FDEntry *> _fdEntryVector; +#ifdef RESIP_POLL_IMPL_POLL + std::vector<pollfd> _pollFDVector; +#endif +#ifdef RESIP_POLL_IMPL_SELECT + int/*FD*/ _maxFDPlus1; + fd_set _readFDSet; + fd_set _writeFDSet; +#endif +#ifdef RESIP_POLL_EXTERN + std::map<int/*FD*/, Poll::FDEntry *> _fdEntryMap; +#endif + std::vector<Poll::FDEntry *> _waitResult; + + public: + + /* + "waitResult" is the result of method "wait" or "afterExternWait". + Returns the index of the entry with the smallest file descriptor >= "fd" in + "waitResult", or "waitResult.size()" if none exists. + */ + static + int + findFDInWaitResult(int/*FD*/ fd, + const std::vector<Poll::FDEntry *> & waitResult); + + //constructor + Poll(); + + //destructor + ~Poll(); + +#ifdef RESIP_POLL_EXTERN // { + + // The result is the set of entries in this poll object. + const std::vector<Poll::FDEntry *> & + beforeExternWait(); + + /* + If "fd" has no entry in this poll object, ignore it and return false. + Otherwise, set the entry's FD state from "fdStateBitMask" and return true. + If the same "fd" is passed in multiple times, the "fdStateBitMask" are + or-ed together. + */ + bool + setEntryFDStateForExternWait(int/*FD*/ fd, + Poll::FDEntry::StateBitMask fdStateBitMask); + + // The result is identical to that of method "wait". + const std::vector<Poll::FDEntry *> & + afterExternWait(); + +#else //!defined(RESIP_POLL_EXTERN) } { + + /* + Wait for I/O on any of this poll object's entry's file descriptors. + More precisely, wait for the file descriptor of any entry with a pending + write to be writable or for any entry's file descriptor to have readable + input or an error. + If "timeoutMilliSeconds" is negative, it means wait indefinitely, otherwise + it indicates the maximum period to wait. + The result is an array of the entries for the file descriptors that are + readable, writable, or error, as specified by each entry's FD state. + The result contains no duplicates and is sorted by file descriptor. + (To service file descriptors with round-robin prioritization, remember the + last file descriptor serviced and use method "Poll::findFDInWaitResult" to + find the index in the result array of the highest priority entry.) + The result is valid until the next call to this method, method + "beforeExternWait", or the destructor. + At some point before then, for each entry in the result, method + "Poll::FDEntry::clearFDState" must be called. + */ + const std::vector<Poll::FDEntry *> & + wait(int timeoutMilliSeconds); + +#endif //!defined(RESIP_POLL_EXTERN) } + + private: + + // Copy constructor: declared but not defined + Poll(const Poll & from); + + // Assignment: declared but not defined + Poll & + operator=(const Poll & from); + +}; + +/////////////////////////////////////////////////////////////////////////////// + +} // namespace resip + +#endif //!defined(RESIP_POLL_HXX) + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Jacob Butcher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + */ diff --git a/src/libs/resiprocate/rutil/PoolBase.cxx b/src/libs/resiprocate/rutil/PoolBase.cxx new file mode 100644 index 00000000..b18c9d91 --- /dev/null +++ b/src/libs/resiprocate/rutil/PoolBase.cxx @@ -0,0 +1,70 @@ +#include "rutil/PoolBase.hxx" + +void* operator new(size_t size, resip::PoolBase* pool) +{ + if(pool) + { + return pool->allocate(size); + } + return ::operator new(size); +} + +void operator delete(void* ptr, resip::PoolBase* pool) +{ + if(pool) + { + pool->deallocate(ptr); + return; + } + ::operator delete(ptr); +} + + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/PoolBase.hxx b/src/libs/resiprocate/rutil/PoolBase.hxx new file mode 100644 index 00000000..67db3934 --- /dev/null +++ b/src/libs/resiprocate/rutil/PoolBase.hxx @@ -0,0 +1,71 @@ +#ifndef PoolBase_Include_Guard +#define PoolBase_Include_Guard + +#include <stddef.h> + +namespace resip +{ +class PoolBase +{ + public: + virtual ~PoolBase(){} + virtual void* allocate(size_t size)=0; + virtual void deallocate(void* ptr)=0; + virtual size_t max_size() const=0; +}; + +} + +void* operator new(size_t size, resip::PoolBase* pool); +void operator delete(void* ptr, resip::PoolBase* pool); + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/ProducerFifoBuffer.hxx b/src/libs/resiprocate/rutil/ProducerFifoBuffer.hxx new file mode 100644 index 00000000..c12cb770 --- /dev/null +++ b/src/libs/resiprocate/rutil/ProducerFifoBuffer.hxx @@ -0,0 +1,115 @@ +#ifndef ProducerFifoBuffer_Include_Guard +#define ProducerFifoBuffer_Include_Guard + +#include "rutil/Fifo.hxx" + +namespace resip +{ + +/** + Class for buffering messages placed in a Fifo, to be used by a single + producer. By adding messages in bulk, lock contention is reduced. + @todo Refactor so we can use this with AbstractFifo<T>? This is presently not + the case because AbstractFifo does not expose its API publicly. +*/ +template<typename T> +class ProducerFifoBuffer +{ + public: + ProducerFifoBuffer(Fifo<T>& fifo, + size_t bufferSize) : + mFifo(fifo), + mBufferSize(bufferSize) + {} + + ~ProducerFifoBuffer() + { + flush(); + } + + void add(T* msg) + { + mBuffer.push_back(msg); + if(mBuffer.size()>=mBufferSize) + { + flush(); + } + } + + void flush() + { + mFifo.addMultiple(mBuffer); + } + + inline size_t getBufferSize() const + {return mBufferSize;} + + inline void setBufferSize(size_t pBufferSize) + { + mBufferSize = pBufferSize; + if(mBuffer.size()>=mBufferSize) + { + flush(); + } + } + + inline const Fifo<T>& getFifo() const {return mFifo;} + inline Fifo<T>& getFifo() {return mFifo;} + + protected: + Fifo<T>& mFifo; + // The type used by AbstractFifo<T>::addMultiple() + typename Fifo<T>::Messages mBuffer; + size_t mBufferSize; +}; +} +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.cxx b/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.cxx new file mode 100644 index 00000000..4cd9ea91 --- /dev/null +++ b/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.cxx @@ -0,0 +1,407 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_RADIUS_CLIENT + +#include "Logger.hxx" +#include "RADIUSDigestAuthenticator.hxx" + + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +struct attr *RADIUSDigestAuthenticator::attrs = NULL; +struct val *RADIUSDigestAuthenticator::vals = NULL; +rc_handle *RADIUSDigestAuthenticator::rh = NULL; + +inline void init_av(rc_handle *rh, struct attr *at, struct val *vl, char *fn) +{ + int i; + DICT_ATTR *da; + DICT_VALUE *dv; + + for (i = 0; i < A_MAX; i++) + { + if (at[i].n == NULL) + continue; + da = rc_dict_findattr(rh, at[i].n); + if (da == NULL) + { + ErrLog( <<"ERROR: " << Data(fn) << ": can't get code for the " << Data(at[i].n) << " attribute\n"); + throw; + } + at[i].v = da->value; + } + for (i = 0; i < V_MAX; i++) + { + if (vl[i].n == NULL) + continue; + dv = rc_dict_findval(rh, vl[i].n); + if (dv == NULL) + { + ErrLog( <<"ERROR: " << fn << ": can't get code for the " << vl[i].n << " attribute value\n"); + throw; + } + vl[i].v = dv->value; + } +} + +RADIUSDigestAuthListener::~RADIUSDigestAuthListener() { +} + + +void RADIUSDigestAuthenticator::init(const char *radiusConfigFile) +{ + if(attrs != NULL) + throw; // may only be called once + + if((attrs = (struct attr *)malloc(sizeof(struct attr) * A_MAX)) == NULL) + { + ErrLog( <<"malloc failed"); + throw; + } + if((vals = (struct val *)malloc(sizeof(struct val) * V_MAX)) == NULL) + { + ErrLog(<< "malloc failed"); + throw; + } + + memset(attrs, 0, sizeof(struct attr) * A_MAX); + memset(vals, 0, sizeof(struct val) * V_MAX); + attrs[A_SERVICE_TYPE].n = "Service-Type"; + attrs[A_SIP_RPID].n = "Sip-RPId"; + attrs[A_SIP_URI_USER].n = "Sip-URI-User"; + attrs[A_DIGEST_RESPONSE].n = "Digest-Response"; + attrs[A_DIGEST_ALGORITHM].n = "Digest-Algorithm"; + attrs[A_DIGEST_BODY_DIGEST].n = "Digest-Body-Digest"; + attrs[A_DIGEST_CNONCE].n = "Digest-CNonce"; + attrs[A_DIGEST_NONCE_COUNT].n = "Digest-Nonce-Count"; + attrs[A_DIGEST_QOP].n = "Digest-QOP"; + attrs[A_DIGEST_METHOD].n = "Digest-Method"; + attrs[A_DIGEST_URI].n = "Digest-URI"; + attrs[A_DIGEST_NONCE].n = "Digest-Nonce"; + attrs[A_DIGEST_REALM].n = "Digest-Realm"; + attrs[A_DIGEST_USER_NAME].n = "Digest-User-Name"; + attrs[A_USER_NAME].n = "User-Name"; + attrs[A_CISCO_AVPAIR].n = NULL; + //attrs[A_CISCO_AVPAIR].n = "Cisco-AVPair"; + vals[V_SIP_SESSION].n = "Sip-Session"; + + const char *myRADIUSConfigFile = RADIUS_CONFIG; + if(radiusConfigFile != NULL) + myRADIUSConfigFile = radiusConfigFile; + if((rh = rc_read_config((char *)myRADIUSConfigFile)) == NULL) + { + ErrLog(<< "radius: Error opening configuration file \n"); + throw; + } + + if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) + { + ErrLog(<< "radius: Error opening dictionary file \n"); + throw; + } + + init_av(rh, attrs, vals, "radius"); + +} + +RADIUSDigestAuthenticator::RADIUSDigestAuthenticator( + const resip::Data& username, + const resip::Data& digestUsername, + const resip::Data& digestRealm, + const resip::Data& digestNonce, + const resip::Data& digestUri, const resip::Data& digestMethod, + const resip::Data& digestResponse, RADIUSDigestAuthListener *listener) : + username(username), + digestUsername(digestUsername), + digestRealm(digestRealm), + digestNonce(digestNonce), + digestUri(digestUri), + digestMethod(digestMethod), + digestQop(""), + digestNonceCount(""), + digestCNonce(""), + digestBodyDigest(""), + digestResponse(digestResponse), + listener(listener) +{ +} + +// QoP auth +RADIUSDigestAuthenticator::RADIUSDigestAuthenticator( + const resip::Data& username, + const resip::Data& digestUsername, + const resip::Data& digestRealm, + const resip::Data& digestNonce, + const resip::Data& digestUri, + const resip::Data& digestMethod, + const resip::Data& digestQop, + const resip::Data& digestNonceCount, + const resip::Data& digestCNonce, + const resip::Data& digestResponse, + RADIUSDigestAuthListener *listener) : + username(username), + digestUsername(digestUsername), + digestRealm(digestRealm), + digestNonce(digestNonce), + digestUri(digestUri), + digestMethod(digestMethod), + digestQop(digestQop), + digestNonceCount(digestNonceCount), + digestCNonce(digestCNonce), + digestBodyDigest(""), + digestResponse(digestResponse), + listener(listener) +{ +} + +// QoP auth-int +RADIUSDigestAuthenticator::RADIUSDigestAuthenticator( + const resip::Data& username, + const resip::Data& digestUsername, + const resip::Data& digestRealm, + const resip::Data& digestNonce, + const resip::Data& digestUri, + const resip::Data& digestMethod, + const resip::Data& digestQop, + const resip::Data& digestNonceCount, + const resip::Data& digestCNonce, + const resip::Data& digestBodyDigest, + const resip::Data& digestResponse, + RADIUSDigestAuthListener *listener) : + username(username), + digestUsername(digestUsername), + digestRealm(digestRealm), + digestNonce(digestNonce), + digestUri(digestUri), + digestMethod(digestMethod), + digestQop(digestQop), + digestNonceCount(digestNonceCount), + digestCNonce(digestCNonce), + digestBodyDigest(digestBodyDigest), + digestResponse(digestResponse), + listener(listener) +{ +} + +RADIUSDigestAuthenticator::~RADIUSDigestAuthenticator() +{ + DebugLog(<<"RADIUSDigestAuthenticator::~RADIUSDigestAuthenticator() entered"); + //terminate(); + DebugLog(<<"RADIUSDigestAuthenticator::~RADIUSDigestAuthenticator() done"); +} + +int RADIUSDigestAuthenticator::doRADIUSCheck() +{ + run(); + detach(); + return 0; + // return detach(); +} + +void RADIUSDigestAuthenticator::thread() +{ + + DebugLog(<<"RADIUSDigestAuthenticator::thread() entered"); + + VALUE_PAIR *vp_s_start = createRADIUSRequest(); + VALUE_PAIR *vp_r_start; + + if(vp_s_start == NULL) + { + WarningLog(<<"vp_s_start == NULL"); + listener->onError(); + delete listener; + //exit(); + delete this; + return; + } + + char msg[RADIUS_MSG_SIZE]; + int i; + if ((i = rc_auth(rh, RADIUS_SIP_PORT, vp_s_start, &vp_r_start, msg)) == OK_RC) + { + DebugLog(<<"rc_auth success for " << username.c_str()); + rc_avpair_free(vp_s_start); + Data rpid(""); + VALUE_PAIR *vp; + if ((vp = rc_avpair_get(vp_r_start, attrs[A_SIP_RPID].v, 0))) + { + rpid = Data(vp->strvalue, vp->lvalue); + } + listener->onSuccess(rpid); + rc_avpair_free(vp_r_start); + } + else + { + DebugLog(<<"rc_auth failure for " << username.c_str()); + rc_avpair_free(vp_s_start); + rc_avpair_free(vp_r_start); + if(i == BADRESP_RC) + listener->onAccessDenied(); + else + listener->onError(); + } + delete listener; + DebugLog(<<"RADIUSDigestAuthenticator::thread() exiting"); + //exit(); + delete this; +} + +void RADIUSDigestAuthenticator::final() +{ + DebugLog(<<"RADIUSDigestAuthenticator::final() entered"); +} + +VALUE_PAIR *RADIUSDigestAuthenticator::createRADIUSRequest() +{ + VALUE_PAIR *vp_start = NULL; + + if(!rc_avpair_add(rh, &vp_start, attrs[A_USER_NAME].v, (char *)username.data(), username.size(), 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_USER_NAME].v, (char *)digestUsername.data(), digestUsername.size(), 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_REALM].v, (char *)digestRealm.data(), digestRealm.size(), 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_NONCE].v, (char *)digestNonce.data(), digestNonce.size(), 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_URI].v, (char *)digestUri.data(), digestUri.size(), 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_METHOD].v, (char *)digestMethod.data(), digestMethod.size(), 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + if(!digestQop.empty()) + { + if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_QOP].v, (char *)digestQop.data(), digestQop.size(), 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_NONCE_COUNT].v, (char *)digestNonceCount.data(), digestNonceCount.size(), 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_CNONCE].v, (char *)digestCNonce.data(), digestCNonce.size(), 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + if(!digestBodyDigest.empty()) + { + if(!rc_avpair_add(rh, &vp_start, attrs[A_USER_NAME].v, (char *)username.data(), username.size(), 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + } + } // end QoP + + if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_RESPONSE].v, (char *)digestResponse.data(), digestResponse.size(), 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + + UINT4 service = vals[V_SIP_SESSION].v; + if (!rc_avpair_add(rh, &vp_start, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + + /* Add SIP URI as a check item */ + // xxx + if (!rc_avpair_add(rh, &vp_start, attrs[A_SIP_URI_USER].v, (char *)digestUsername.data(), digestUsername.size(), 0)) + { + rc_avpair_free(vp_start); + return NULL; + } + + return vp_start; +} + +TestRADIUSDigestAuthListener::TestRADIUSDigestAuthListener() +{ +} + +void TestRADIUSDigestAuthListener::onSuccess(const resip::Data& rpid) +{ + DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess"); + if(!rpid.empty()) + DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess rpid = " << rpid); + else + DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess, no rpid"); +} + +void TestRADIUSDigestAuthListener::onAccessDenied() +{ + DebugLog(<<"TestRADIUSDigestAuthListener::onAccessDenied"); +} + +void TestRADIUSDigestAuthListener::onError() +{ + WarningLog(<<"TestRADIUSDigestAuthListener::onError"); +} + +#endif + + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.hxx b/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.hxx new file mode 100644 index 00000000..cbf5ff5a --- /dev/null +++ b/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.hxx @@ -0,0 +1,237 @@ + +#ifndef __RADIUSDigestAuthenticator_h +#define __RADIUSDigestAuthenticator_h + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef USE_RADIUS_CLIENT + +#include <radiusclient-ng.h> + +#include "rutil/Data.hxx" +#include "rutil/ThreadIf.hxx" + +#define RADIUS_CONFIG "/etc/radiusclient/radiusclient.conf" +#define RADIUS_MSG_SIZE 4096 +#define RADIUS_SIP_PORT 5060 + +/* + + Class for performing RADIUS authentication of SIP users + + Based largely on the auth_radius module in SER - http://iptel.org/ser + + Permission has been given by Jan Janak, the author of auth_radius, for + this code to be redistributed under a BSD-like license. + + see http://www.iptel.org/ietf/aaa/draft-schulzrinne-sipping-radius-accounting-00.txt */ + +/* + * WARNING: Don't forget to update the dictionary if you update this file !!! + */ + +namespace resip +{ + +struct attr +{ + const char *n; + int v; +}; + +struct val +{ + const char *n; + int v; +}; + +#define A_USER_NAME 0 +#define A_SERVICE_TYPE 1 +#define A_CALLED_STATION_ID 2 +#define A_CALLING_STATION_ID 3 +#define A_ACCT_STATUS_TYPE 4 +#define A_ACCT_SESSION_ID 5 +#define A_SIP_METHOD 6 +#define A_SIP_RESPONSE_CODE 7 +#define A_SIP_CSEQ 8 +#define A_SIP_TO_TAG 9 +#define A_SIP_FROM_TAG 10 +#define A_SIP_TRANSLATED_REQUEST_URI 11 +#define A_DIGEST_RESPONSE 12 +#define A_DIGEST_ATTRIBUTES 13 +#define A_SIP_URI_USER 14 +#define A_SIP_RPID 15 +#define A_DIGEST_REALM 16 +#define A_DIGEST_NONCE 17 +#define A_DIGEST_METHOD 18 +#define A_DIGEST_URI 19 +#define A_DIGEST_QOP 20 +#define A_DIGEST_ALGORITHM 21 +#define A_DIGEST_BODY_DIGEST 22 +#define A_DIGEST_CNONCE 23 +#define A_DIGEST_NONCE_COUNT 24 +#define A_DIGEST_USER_NAME 25 +#define A_SIP_GROUP 26 +#define A_CISCO_AVPAIR 27 +#define A_VM_EMAIL 28 +#define A_VM_LANGUAGE 29 +#define A_MAX 30 + +#define V_STATUS_START 0 +#define V_STATUS_STOP 1 +#define V_STATUS_FAILED 2 +#define V_CALL_CHECK 3 +#define V_EMERGENCY_CALL 4 +#define V_SIP_SESSION 5 +#define V_GROUP_CHECK 6 +#define V_VM_INFO 7 +#define V_MAX 8 + + +// An instance of this class is notified when the RADIUSDigestAuthenticator +// has done it's work +class RADIUSDigestAuthListener +{ + public: + virtual ~RADIUSDigestAuthListener(); + // These methods will be called from a separate thread of execution + virtual void onSuccess(const resip::Data& rpid) = 0; + virtual void onAccessDenied() = 0; + virtual void onError() = 0; +}; + +class TestRADIUSDigestAuthListener : public RADIUSDigestAuthListener +{ + public: + TestRADIUSDigestAuthListener(); + void onSuccess(const resip::Data& rpid); + void onAccessDenied(); + void onError(); +}; + +// An instance of this class will attempt to authenticate the request +// using RADIUS +class RADIUSDigestAuthenticator : public resip::ThreadIf { + //class RADIUSDigestAuthenticator : public ost::Thread { + + private: + + resip::Data username; // username from ProxyAuth header + resip::Data digestUsername; // username from digest header + resip::Data digestRealm; // realm from digest header + resip::Data digestNonce; // nonce from digest header + resip::Data digestUri; // request URI from request line + resip::Data digestMethod; // request method (e.g. INVITE) + resip::Data digestQop; // QoP is one of "", "auth", "auth-int" + resip::Data digestNonceCount; // nonce count or "" + resip::Data digestCNonce; // cnonce or "" + resip::Data digestBodyDigest; // value of opaque or "" + resip::Data digestResponse; // digest string submitted by client + + RADIUSDigestAuthListener *listener; + + public: + + static void init(const char *radiusConfigFile); + + // No QoP + RADIUSDigestAuthenticator(const resip::Data& username, + const resip::Data& digestUsername, + const resip::Data& digestRealm, + const resip::Data& digestNonce, + const resip::Data& digestUri, + const resip::Data& digestMethod, + const resip::Data& digestResponse, + RADIUSDigestAuthListener *listener); + + // QoP auth + RADIUSDigestAuthenticator(const resip::Data& username, + const resip::Data& digestUsername, + const resip::Data& digestRealm, + const resip::Data& digestNonce, + const resip::Data& digestUri, + const resip::Data& digestMethod, + const resip::Data& digestQop, + const resip::Data& digestNonceCount, + const resip::Data& digestCNonce, + const resip::Data& digestResponse, + RADIUSDigestAuthListener *listener); + + // QoP auth-int + RADIUSDigestAuthenticator(const resip::Data& username, + const resip::Data& digestUsername, + const resip::Data& digestRealm, + const resip::Data& digestNonce, + const resip::Data& digestUri, + const resip::Data& digestMethod, + const resip::Data& digestQop, + const resip::Data& digestNonceCount, + const resip::Data& digestCNonce, + const resip::Data& digestBodyDigest, + const resip::Data& digestResponse, + RADIUSDigestAuthListener *listener); + + virtual ~RADIUSDigestAuthenticator(); + + int doRADIUSCheck(); + + protected: + + static struct attr *attrs; + static struct val *vals; + static rc_handle *rh; + + void thread(); + void final(); + + VALUE_PAIR *createRADIUSRequest(); + +}; + + +} + +#endif + +#endif + + +/* ==================================================================== + * + * Copyright 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/rutil/RWMutex.cxx b/src/libs/resiprocate/rutil/RWMutex.cxx new file mode 100644 index 00000000..6dddfe53 --- /dev/null +++ b/src/libs/resiprocate/rutil/RWMutex.cxx @@ -0,0 +1,165 @@ +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + +#include "RWMutex.hxx" +#include "Lock.hxx" +#include <cassert> + +using resip::RWMutex; +using resip::Lock; + +RWMutex::RWMutex() + : Lockable(), + mReaderCount(0), + mWriterHasLock(false), + mPendingWriterCount(0) +{ +} + + +RWMutex::~RWMutex() +{ +} + + +void +RWMutex::readlock() +{ + Lock lock(mMutex); + + while ( mWriterHasLock || mPendingWriterCount > 0 ) + { + mReadCondition.wait(mMutex); + } + + mReaderCount++; +} + + +void +RWMutex::writelock() +{ + Lock lock(mMutex); + + mPendingWriterCount++; + + while ( mWriterHasLock || mReaderCount > 0 ) + { + mPendingWriteCondition.wait(mMutex); + } + + mPendingWriterCount--; + + mWriterHasLock = true; +} + + +void +RWMutex::lock() +{ + writelock(); +} + + +void +RWMutex::unlock() +{ + Lock lock(mMutex); + + // Unlocking a write lock. + // + if ( mWriterHasLock ) + { + assert( mReaderCount == 0 ); + + mWriterHasLock = false; + + // Pending writers have priority. Could potentially starve readers. + // + if ( mPendingWriterCount > 0 ) + { + mPendingWriteCondition.signal(); + } + + // No writer, no pending writers, so all the readers can go. + // + else + { + mReadCondition.broadcast(); + } + + } + + // Unlocking a read lock. + // + else + { + assert( mReaderCount > 0 ); + + mReaderCount--; + + if ( mReaderCount == 0 && mPendingWriterCount > 0 ) + { + mPendingWriteCondition.signal(); + } + } +} + +unsigned int +RWMutex::readerCount() const +{ + return ( mReaderCount ); +} + +unsigned int +RWMutex::pendingWriterCount() const +{ + return ( mPendingWriterCount ); +} diff --git a/src/libs/resiprocate/rutil/RWMutex.hxx b/src/libs/resiprocate/rutil/RWMutex.hxx new file mode 100644 index 00000000..6f6fb45e --- /dev/null +++ b/src/libs/resiprocate/rutil/RWMutex.hxx @@ -0,0 +1,102 @@ +#if !defined(RESIP_RWMUTEX_HXX) +#define RESIP_RWMUTEX_HXX + +static const char* const resipRWMutex_hxx_Version = + "$Id: RWMutex.hxx,v 1.3 2003/06/02 20:52:32 ryker Exp $"; + +#include "Lockable.hxx" +#include "Mutex.hxx" +#include "Condition.hxx" + +namespace resip +{ + +/** + @brief Wraps the readers/writers mutex implementation on your platform. + + @note A readers/writers mutex is a mutex that can be locked in two differing + ways: + - A read-lock: Prevents other threads from obtaining a write-lock, but + not other read-locks. + - A write-lock: Prevents other threads from obtaining either a + read-lock or write-lock. + + Usually, if a thread attempts to aquire a write-lock while read-locks are + being held, this will prevent any further read-locks from being obtained, + until the write-lock is aquired and released. This prevents the "writer + starvation" problem. +*/ +class RWMutex : public Lockable +{ + public: + RWMutex(); + ~RWMutex(); + void readlock(); + void writelock(); + void lock(); + void unlock(); + unsigned int readerCount() const; + unsigned int pendingWriterCount() const; + + private: + Mutex mMutex; + Condition mReadCondition; + Condition mPendingWriteCondition; + unsigned int mReaderCount; + bool mWriterHasLock; + unsigned int mPendingWriterCount; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Random.cxx b/src/libs/resiprocate/rutil/Random.cxx new file mode 100644 index 00000000..7f6be609 --- /dev/null +++ b/src/libs/resiprocate/rutil/Random.cxx @@ -0,0 +1,544 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <cassert> +#include <stdlib.h> + +#ifdef WIN32 +#include "rutil/Socket.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/Data.hxx" +#else +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#endif + +#include "rutil/Random.hxx" +#include "rutil/Timer.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/Lock.hxx" +#include "rutil/Logger.hxx" + + +#ifdef USE_SSL +#ifdef WIN32 +//hack for name collision of OCSP_RESPONSE and wincrypt.h in latest openssl release 0.9.8h +//http://www.google.com/search?q=OCSP%5fRESPONSE+wincrypt%2eh +//continue to watch this issue for a real fix. +#undef OCSP_RESPONSE +#endif +#include "rutil/ssl/OpenSSLInit.hxx" +# define USE_OPENSSL 1 +#else +# define USE_OPENSSL 0 +#endif + +#if ( USE_OPENSSL == 1 ) +# include <openssl/e_os2.h> +# include <openssl/rand.h> +# include <openssl/err.h> +#endif + +using namespace resip; +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +Mutex Random::mMutex; +bool Random::mIsInitialized = false; + +#ifdef WIN32 +Random::Initializer Random::mInitializer; +#ifdef RESIP_RANDOM_WIN32_RTL +BOOLEAN (APIENTRY *Random::RtlGenRandom)(void*, ULONG) = 0; +#endif +#endif //WIN32 + +#ifdef RESIP_RANDOM_THREAD_MUTEX +struct random_data* Random::sRandomState = 0; +#endif + +#ifdef RESIP_RANDOM_THREAD_LOCAL +ThreadIf::TlsKey Random::sRandomStateKey = 0; +#endif + +#define RANDOM_STATE_SIZE 128 + +const char* +Random::getImplName() +{ +#ifdef WIN32 +#if defined(RESIP_RANDOM_WIN32_RTL) + return "win32_rtl"; +#else + return "win32_rand"; +#endif +#else // WIN32 +#if defined(RESIP_RANDOM_THREAD_LOCAL) + return "posix_thread_local"; +#elif defined(RESIP_RANDOM_THREAD_MUTEX) + return "posix_thread_mutex"; +#else + return "posix_random"; +#endif +#endif // not WIN32 +} + +/** + Key goal is to make sure that each thread has distinct seed. +**/ +unsigned +Random::getSimpleSeed() +{ + // !cj! need to find a better way - use pentium random commands? + Data buffer; + { + DataStream strm(buffer); +#ifdef WIN32 + strm << GetTickCount() << ":"; + strm << GetCurrentProcessId() << ":"; + strm << GetCurrentThreadId(); +#else + // .kw. previously just used the lower 32bits of getTimeMs() + strm << ResipClock::getTimeMicroSec() << ":"; + strm << getpid(); +#if defined(RESIP_RANDOM_THREAD_LOCAL) + strm << ":" << ThreadIf::selfId(); +#endif +#endif + } + return (unsigned int)buffer.hash(); +} + +void +Random::initialize() +{ +#ifdef WIN32 +//#if defined(USE_SSL) +#if 0 //!dcm! - this shouldn't be per thread for win32, and this is slow. Going + //to re-work openssl initialization + if ( !Random::mIsInitialized) + { + Lock lock(mMutex); + if (!Random::mIsInitialized) + { + mIsInitialized = true; + RAND_screen (); + } + } +#else + if (!Random::mInitializer.isInitialized()) + { + Lock lock(mMutex); + if (!Random::mInitializer.isInitialized()) + { + Random::mInitializer.setInitialized(); + + unsigned seed = getSimpleSeed(); + srand(seed); + +#ifdef RESIP_RANDOM_WIN32_RTL + // .jjg. from http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx + // srand(..) and rand() have proven to be insufficient sources of randomness, + // leading to transaction id collisions in resip. + // SystemFunction036 maps to RtlGenRandom, which is used by rand_s() (which is available + // only with the VC 8.0 runtime or later) and is the Microsoft-recommended way of getting + // a random number. This code allows that functionality to be accessed even from VC 7.1. + // However, SystemFunction036 only exists in Windows XP and later, so we may need to fallback + // to the old method using rand(). + HMODULE hLib = LoadLibrary("ADVAPI32.DLL"); + if (hLib) + { + Random::RtlGenRandom = + (BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(hLib,"SystemFunction036"); + + if (!Random::RtlGenRandom) + { + WarningLog(<< "Using srand(..) and rand() for random numbers"); + } + } +#endif // RESIP_RANDOM_WIN32_RTL + + mIsInitialized = true; + + } + } +#endif // not dead code + +#else // WIN32 + // ?dcm? -- OpenSSL will transparently initialize PRNG if /dev/urandom is + // present. In any case, will move into OpenSSLInit + if ( !Random::mIsInitialized) + { + Lock lock(mMutex); + if (!Random::mIsInitialized) + { + mIsInitialized = true; + Timer::setupTimeOffsets(); + + unsigned seed = getSimpleSeed(); + +#if defined(RESIP_RANDOM_THREAD_LOCAL) + ThreadIf::tlsKeyCreate(sRandomStateKey, ::free); +#elif defined(RESIP_RANDOM_THREAD_MUTEX) + struct random_data *buf; + size_t sz = sizeof(*buf)+RANDOM_STATE_SIZE; + buf = (struct random_data*) ::malloc(sz); + memset( buf, 0, sz); // .kw. strange segfaults without this + initstate_r(seed, ((char*)buf)+sizeof(*buf), RANDOM_STATE_SIZE, buf); + sRandomState = buf; +#else + srandom(seed); +#endif + + + int fd = open("/dev/urandom", O_RDONLY); + // !ah! blocks on embedded devices -- not enough entropy. + if ( fd != -1 ) + { + int s = read( fd,&seed,sizeof(seed) ); //!ah! blocks if /dev/random on embedded sys + + if ( s != sizeof(seed) ) + { + ErrLog( << "System is short of randomness" ); // !ah! never prints + } + } + else + { + ErrLog( << "Could not open /dev/urandom" ); + } + +#if defined(USE_SSL) + if (fd == -1 ) + { + // really bad sign - /dev/random does not exist so need to intialize + // OpenSSL some other way + + // !cj! need to fix assert(0); + } + else + { + char buf[1024/8]; // size is number byes used for OpenSSL init + + int s = read( fd,&buf,sizeof(buf) ); + + if ( s != sizeof(buf) ) + { + ErrLog( << "System is short of randomness" ); + } + + RAND_add(buf,sizeof(buf),double(s*8)); + } +#endif // SSL + if (fd != -1 ) + { + ::close(fd); + } + } + } +#endif // not WIN32 +} + +int +Random::getRandom() +{ + initialize(); + +#ifdef WIN32 + + int ret = 0; + +#ifdef RESIP_RANDOM_WIN32_RTL + // see comment in initialize() + if (Random::RtlGenRandom) + { + unsigned long buff[1]; + ULONG ulCbBuff = sizeof(buff); + if (Random::RtlGenRandom(buff,ulCbBuff)) + { + // .kw. all other impls here return positive number, so do the same... + ret = buff[0] & (~(1<<31)); + return ret; + } + } + // fallback to using rand() if this is a Windows version previous to XP +#endif // RESIP_RANDOM_WIN32_RTL + { + // rand() returns [0,RAND_MAX], which on Windows is 15 bits and positive + // code below gets 30bits of randomness; with bit31 and bit15 + // always zero; result is always positive + assert( RAND_MAX == 0x7fff ); + // WATCHOUT: on Linux, rand() returns 31bits, and assert above will fail + int r1 = rand(); + int r2 = rand(); + ret = (r1<<16) + r2; + } + + return ret; +#else // WIN32 + +#if defined(RESIP_RANDOM_THREAD_LOCAL) + struct random_data *buf = (struct random_data*) ThreadIf::tlsGetValue(sRandomStateKey); + if ( buf==NULL ) { + size_t sz = sizeof(*buf)+RANDOM_STATE_SIZE; + buf = (struct random_data*) ::malloc(sz); + memset( buf, 0, sz); // .kw. strange segfaults without this + unsigned seed = getSimpleSeed(); + initstate_r(seed, ((char*)buf)+sizeof(*buf), RANDOM_STATE_SIZE, buf); + ThreadIf::tlsSetValue(sRandomStateKey, buf); + } + int32_t ret; + random_r(buf, &ret); + return ret; +#elif defined(RESIP_RANDOM_THREAD_MUTEX) + int32_t ret; + { + Lock statelock(mMutex); + random_r(sRandomState, &ret); + } + return ret; +#else + // random returns [0,RAN_MAX]. On Linux, this is 31 bits and positive. + // On some platforms it might be on 15 bits, and will need to do something. + // assert( RAND_MAX == ((1<<31)-1) ); // ?slg? commented out assert since, RAND_MAX is not used in random(), it applies to rand() only + return random(); +#endif // THREAD_LOCAL +#endif // WIN32 +} + +int +Random::getCryptoRandom() +{ + initialize(); + +#if USE_OPENSSL + int ret; + int e = RAND_bytes( (unsigned char*)&ret , sizeof(ret) ); + if ( e < 0 ) + { + // error of some type - likely not enough rendomness to dod this + long err = ERR_get_error(); + + char buf[1024]; + ERR_error_string_n(err,buf,sizeof(buf)); + + ErrLog( << buf ); + assert(0); + } + return ret; +#else + return getRandom(); +#endif +} + +Data +Random::getRandom(unsigned int len) +{ + initialize(); + assert(len < Random::maxLength+1); + + union + { + char cbuf[Random::maxLength+1]; + unsigned int ibuf[(Random::maxLength+1)/sizeof(int)]; + }; + + for (unsigned int count=0; count<(len+sizeof(int)-1)/sizeof(int); ++count) + { + ibuf[count] = Random::getRandom(); + } + return Data(cbuf, len); +} + +Data +Random::getCryptoRandom(unsigned int len) +{ + unsigned char* buf = new unsigned char[len]; + getCryptoRandom(buf, len); // USE_SSL check is in here + return Data(Data::Take, (char*)buf, len); +} + +Data +Random::getRandomHex(unsigned int numBytes) +{ + return Random::getRandom(numBytes).hex(); +} + +Data +Random::getRandomBase64(unsigned int numBytes) +{ + return Random::getRandom(numBytes).base64encode(); +} + +Data +Random::getCryptoRandomHex(unsigned int numBytes) +{ + return Random::getCryptoRandom(numBytes).hex(); +} + +Data +Random::getCryptoRandomBase64(unsigned int numBytes) +{ + return Random::getCryptoRandom(numBytes).base64encode(); +} + +/* + [From RFC 4122] + + The version 4 UUID is meant for generating UUIDs from truly-random or + pseudo-random numbers. + + The algorithm is as follows: + + o Set the two most significant bits (bits 6 and 7) of the + clock_seq_hi_and_reserved to zero and one, respectively. + + o Set the four most significant bits (bits 12 through 15) of the + time_hi_and_version field to the 4-bit version number from + Section 4.1.3. (0 1 0 0) + + o Set all the other bits to randomly (or pseudo-randomly) chosen + values. + + UUID = time-low "-" time-mid "-" + time-high-and-version "-" + clock-seq-and-reserved + clock-seq-low "-" node + time-low = 4hexOctet + time-mid = 2hexOctet + time-high-and-version = 2hexOctet + clock-seq-and-reserved = hexOctet + clock-seq-low = hexOctet + node = 6hexOctet + hexOctet = hexDigit hexDigit +*/ +Data +Random::getVersion4UuidUrn() +{ + Data urn ("urn:uuid:"); + urn += getCryptoRandomHex(4); // time-low + urn += "-"; + urn += getCryptoRandomHex(2); // time-mid + urn += "-"; + + Data time_hi_and_version = Random::getCryptoRandom(2); + time_hi_and_version[0] &= 0x0f; + time_hi_and_version[0] |= 0x40; + urn += time_hi_and_version.hex(); + + urn += "-"; + + Data clock_seq_hi_and_reserved = Random::getCryptoRandom(1); + clock_seq_hi_and_reserved[0] &= 0x3f; + clock_seq_hi_and_reserved[0] |= 0x40; + urn += clock_seq_hi_and_reserved.hex(); + + urn += getCryptoRandomHex(1); // clock-seq-low + urn += "-"; + urn += getCryptoRandomHex(6); // node + return urn; +} + +void +Random::getCryptoRandom(unsigned char* buf, unsigned int numBytes) +{ + assert(numBytes < Random::maxLength+1); + +#if USE_OPENSSL + initialize(); + int e = RAND_bytes( (unsigned char*)buf , numBytes ); + if ( e < 0 ) + { + // error of some type - likely not enough rendomness to dod this + long err = ERR_get_error(); + + char buf[1024]; + ERR_error_string_n(err,buf,sizeof(buf)); + + ErrLog( << buf ); + assert(0); + } +#else + // !bwc! Should optimize this. + Data temp=Random::getRandom(numBytes); + memcpy(buf, temp.data(), numBytes); +#endif +} + +#ifdef WIN32 +Random::Initializer::Initializer() : mThreadStorage(::TlsAlloc()) +{ + assert(mThreadStorage != TLS_OUT_OF_INDEXES); +} + +Random::Initializer::~Initializer() +{ + ::TlsFree(mThreadStorage); +} + +void +Random::Initializer::setInitialized() +{ + ::TlsSetValue(mThreadStorage, (LPVOID) TRUE); +} + +bool +Random::Initializer::isInitialized() +{ + // Note: if value is not set yet then 0 (false) is returned + return (BOOL) ::TlsGetValue(mThreadStorage) == TRUE; +} +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2005. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/Random.hxx b/src/libs/resiprocate/rutil/Random.hxx new file mode 100644 index 00000000..9b6a77d5 --- /dev/null +++ b/src/libs/resiprocate/rutil/Random.hxx @@ -0,0 +1,175 @@ +#if !defined(RESIP_RANDOM_HXX) +#define RESIP_RANDOM_HXX + +#include "rutil/Mutex.hxx" +#include "rutil/Data.hxx" +#include "rutil/ThreadIf.hxx" // for ThreadLocalStorage +#include <cassert> +struct random_data; + +/** + * Define below to enable "RtlGenRandom" (aka SystemFunction036) on + * Windows platform. See Random.cxx for details. + */ +// #define RESIP_RANDOM_WIN32_RTL 1 + +/** + * Define below to use common random number generator sate for all resip + * threads, but private from other parts of app. + * This makes use of random_r() and friends with mutex protection. + */ +// #define RESIP_RANDOM_THREAD_MUTEX 1 + +/** + * Define below to use independent random number generator state + * for each thread. This makes use of random_r() and friends + * with TheadIf::tls (thread-local-storage). + */ +// #define RESIP_RANDOM_THREAD_LOCAL 1 + +/** + * By default, on POSIX, the standard srandom() and random() + * functions will be used. This shares the generator state with + * others libraries running in the same application. Under Linux + * random() obtains a mutex so is threadsafe. + * NOTE: See http://evanjones.ca/random-thread-safe.html for some good info. + * WATCHOUT: Some other library can call srandom() in a stupid way, + * causing duplicate callids and such. + */ + + +namespace resip +{ + +/** + @brief A static class that wraps the random-number generation code of your + platform. + @ingroup crypto +*/ +class Random +{ + public: + static unsigned getSimpleSeed(); + static void initialize(); + + enum {maxLength = 512}; + + static Data getRandom(unsigned int numBytes); + static Data getRandomHex(unsigned int numBytes); // actual length is 2*numBytes + static Data getRandomBase64(unsigned int numBytes); // actual length is 1.5*numBytes + + static Data getCryptoRandom(unsigned int numBytes); + static Data getCryptoRandomHex(unsigned int numBytes); // actual length is 2*numBytes + static Data getCryptoRandomBase64(unsigned int numBytes); // actual length is 1.5*numBytes + + static void getCryptoRandom(unsigned char* buf, unsigned int numBytes); + + /** + Returns a version 4 (random) UUID as defined in RFC 4122 + + @todo This is something of a suboptimal hack. Ideally, we would + encapsulate UUID as its own class, with options to create + any of versions 1 through 5 (and Nil UUIDs). This class + would have various access methods to pull the result out + as a bitstring, as raw data, as a URN, etc. For what + I need to do right now, however, version 4 UUIDs get me + where I need to go. <abr> + */ + static Data getVersion4UuidUrn(); + + /** + Returns a postive integer (31 bits) of randomness. Implementation + is platform dependent. + **/ + static int getRandom(); + static int getCryptoRandom(); + + static const char* getImplName(); + + private: + static Mutex mMutex; + static bool mIsInitialized; + +#ifdef WIN32 + // ensure each thread is initialized since windows requires you to call srand for each thread + ///@internal + class Initializer + { + public: + Initializer(); + ~Initializer(); + void setInitialized(); + bool isInitialized(); + + private: + DWORD mThreadStorage; + }; + static Initializer mInitializer; + +#ifdef RESIP_RANDOM_WIN32_RTL + static BOOLEAN (APIENTRY *RtlGenRandom)(void*, ULONG); +#endif +#endif // WIN32 +#ifdef RESIP_RANDOM_THREAD_LOCAL + static ThreadIf::TlsKey sRandomStateKey; +#endif +#ifdef RESIP_RANDOM_THREAD_MUTEX + static struct random_data* sRandomState; + // we re-use the initialization mutex +#endif +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2005. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/RecursiveMutex.cxx b/src/libs/resiprocate/rutil/RecursiveMutex.cxx new file mode 100644 index 00000000..9906f452 --- /dev/null +++ b/src/libs/resiprocate/rutil/RecursiveMutex.cxx @@ -0,0 +1,187 @@ +#include <cassert> +#include <cerrno> + +#include "rutil/RecursiveMutex.hxx" + +#if defined(WIN32) +# include <windows.h> +# include <winbase.h> +#else +# include <pthread.h> +#endif + +#if defined(__INTEL_COMPILER) +// !rk! hack, I'm not sure off hand why the Intel compiler can't find this +extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind) + __THROW; +#endif + +using resip::RecursiveMutex; + +// !abr! I can't find evidence that the Intel C++ Compiler has any issues +// with the use of recursive mutexes. The need for this exception should +// be re-verified and documented here. + +// .abr. .amr. OS X 10.2 is 1020. Prior to this, OS X did not support +// recursive mutexes. The iPhone Macro will be defined for all iPhone SDK based +// compiles which properly supports recursive mutexes + +#if (defined( __APPLE__ ) && (defined(MAC_OS_X_VERSION_MIN_REQUIRED) && (MAC_OS_X_VERSION_MIN_REQUIRED < 1020) && !defined(TARGET_OS_IPHONE))) || defined (__INTEL_COMPILER) +// !cj! need to write intel mutex stuff + +#warning "RecursiveMutex is not available on this platform yet." + +namespace resip +{ + +RecursiveMutex::RecursiveMutex() +{ + assert(0); +} + + +RecursiveMutex::~RecursiveMutex () +{ + assert(0); +} + + +void +RecursiveMutex::lock() +{ + assert(0); +} + +void +RecursiveMutex::unlock() +{ + assert(0); +} + +} + +#else + +namespace resip +{ + +RecursiveMutex::RecursiveMutex() +{ +#ifndef WIN32 + int rc = pthread_mutexattr_init(&mMutexAttr); + #if defined(__linux__) + pthread_mutexattr_settype(&mMutexAttr, PTHREAD_MUTEX_RECURSIVE_NP); + #else + pthread_mutexattr_settype(&mMutexAttr, PTHREAD_MUTEX_RECURSIVE); + #endif + + rc = pthread_mutex_init(&mId, &mMutexAttr); + assert( rc == 0 ); +#else + InitializeCriticalSection(&mId); +#endif +} + + +RecursiveMutex::~RecursiveMutex () +{ +#ifndef WIN32 + int rc = pthread_mutex_destroy(&mId); + assert( rc != EBUSY ); // currently locked + assert( rc == 0 ); + rc = pthread_mutexattr_destroy(&mMutexAttr); +#else + DeleteCriticalSection(&mId); +#endif +} + + +void +RecursiveMutex::lock() +{ +#ifndef WIN32 + int rc = pthread_mutex_lock(&mId); + (void)rc; + assert( rc != EINVAL ); + assert( rc != EDEADLK ); + assert( rc == 0 ); +#else + EnterCriticalSection(&mId); +#endif +} + +void +RecursiveMutex::unlock() +{ +#ifndef WIN32 + int rc = pthread_mutex_unlock(&mId); + (void)rc; + assert( rc != EINVAL ); + assert( rc != EPERM ); + assert( rc == 0 ); +#else + LeaveCriticalSection(&mId); +#endif +} + +#ifndef WIN32 +pthread_mutex_t* +RecursiveMutex::getId() const +{ + return ( &mId ); +} +#endif + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/RecursiveMutex.hxx b/src/libs/resiprocate/rutil/RecursiveMutex.hxx new file mode 100644 index 00000000..8f69b789 --- /dev/null +++ b/src/libs/resiprocate/rutil/RecursiveMutex.hxx @@ -0,0 +1,88 @@ +#if !defined(RESIP_RECURSIVEMUTEX_HXX) +#define RESIP_RECURSIVEMUTEX_HXX + +#include "rutil/compat.hxx" +#include "rutil/Lockable.hxx" + +namespace resip +{ +class Condition; + +/** + @brief Wraps the recursive mutex implementation on your platform (if there is + one). + + @note A recursive mutex is a mutex that can be locked more than once by a + given thread without causing a deadlock. +*/ +class RecursiveMutex : public Lockable +{ + public: + RecursiveMutex(); + virtual ~RecursiveMutex(); + virtual void lock(); + virtual void unlock(); + + private: +#ifdef WIN32 + CRITICAL_SECTION mId; +#else + pthread_mutexattr_t mMutexAttr; + mutable pthread_mutex_t mId; + pthread_mutex_t* getId() const; +#endif +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/AbstractFifo.obj b/src/libs/resiprocate/rutil/SSL-Debug/AbstractFifo.obj new file mode 100644 index 00000000..f7e4107c Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/AbstractFifo.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/AresDns.obj b/src/libs/resiprocate/rutil/SSL-Debug/AresDns.obj new file mode 100644 index 00000000..874e3f07 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/AresDns.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/AtomicCounter.obj b/src/libs/resiprocate/rutil/SSL-Debug/AtomicCounter.obj new file mode 100644 index 00000000..58d23107 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/AtomicCounter.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/BaseException.obj b/src/libs/resiprocate/rutil/SSL-Debug/BaseException.obj new file mode 100644 index 00000000..3ccafa97 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/BaseException.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Coders.obj b/src/libs/resiprocate/rutil/SSL-Debug/Coders.obj new file mode 100644 index 00000000..e35bc503 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Coders.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Condition.obj b/src/libs/resiprocate/rutil/SSL-Debug/Condition.obj new file mode 100644 index 00000000..a837e967 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Condition.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/ConfigParse.obj b/src/libs/resiprocate/rutil/SSL-Debug/ConfigParse.obj new file mode 100644 index 00000000..8f590d5c Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/ConfigParse.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/CountStream.obj b/src/libs/resiprocate/rutil/SSL-Debug/CountStream.obj new file mode 100644 index 00000000..4b698c2b Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/CountStream.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Data.obj b/src/libs/resiprocate/rutil/SSL-Debug/Data.obj new file mode 100644 index 00000000..2d7e29ca Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Data.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/DataStream.obj b/src/libs/resiprocate/rutil/SSL-Debug/DataStream.obj new file mode 100644 index 00000000..4d498c0f Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/DataStream.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/DnsAAAARecord.obj b/src/libs/resiprocate/rutil/SSL-Debug/DnsAAAARecord.obj new file mode 100644 index 00000000..e613aa68 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/DnsAAAARecord.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/DnsCnameRecord.obj b/src/libs/resiprocate/rutil/SSL-Debug/DnsCnameRecord.obj new file mode 100644 index 00000000..ea41395a Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/DnsCnameRecord.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/DnsHostRecord.obj b/src/libs/resiprocate/rutil/SSL-Debug/DnsHostRecord.obj new file mode 100644 index 00000000..e1921b88 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/DnsHostRecord.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/DnsNaptrRecord.obj b/src/libs/resiprocate/rutil/SSL-Debug/DnsNaptrRecord.obj new file mode 100644 index 00000000..055ecb93 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/DnsNaptrRecord.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/DnsSrvRecord.obj b/src/libs/resiprocate/rutil/SSL-Debug/DnsSrvRecord.obj new file mode 100644 index 00000000..76787b94 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/DnsSrvRecord.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/DnsStub.obj b/src/libs/resiprocate/rutil/SSL-Debug/DnsStub.obj new file mode 100644 index 00000000..cf9c11a0 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/DnsStub.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/DnsThread.obj b/src/libs/resiprocate/rutil/SSL-Debug/DnsThread.obj new file mode 100644 index 00000000..d62d1fb4 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/DnsThread.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/DnsUtil.obj b/src/libs/resiprocate/rutil/SSL-Debug/DnsUtil.obj new file mode 100644 index 00000000..5d406b9b Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/DnsUtil.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/ExternalDnsFactory.obj b/src/libs/resiprocate/rutil/SSL-Debug/ExternalDnsFactory.obj new file mode 100644 index 00000000..0130762b Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/ExternalDnsFactory.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/FdPoll.obj b/src/libs/resiprocate/rutil/SSL-Debug/FdPoll.obj new file mode 100644 index 00000000..b99667b2 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/FdPoll.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/FileSystem.obj b/src/libs/resiprocate/rutil/SSL-Debug/FileSystem.obj new file mode 100644 index 00000000..2fb6a707 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/FileSystem.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/GeneralCongestionManager.obj b/src/libs/resiprocate/rutil/SSL-Debug/GeneralCongestionManager.obj new file mode 100644 index 00000000..a423780e Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/GeneralCongestionManager.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/HeapInstanceCounter.obj b/src/libs/resiprocate/rutil/SSL-Debug/HeapInstanceCounter.obj new file mode 100644 index 00000000..142df958 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/HeapInstanceCounter.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/KeyValueStore.obj b/src/libs/resiprocate/rutil/SSL-Debug/KeyValueStore.obj new file mode 100644 index 00000000..f17b41a8 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/KeyValueStore.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/LocalDns.obj b/src/libs/resiprocate/rutil/SSL-Debug/LocalDns.obj new file mode 100644 index 00000000..f12d620c Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/LocalDns.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Lock.obj b/src/libs/resiprocate/rutil/SSL-Debug/Lock.obj new file mode 100644 index 00000000..a9c99f7a Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Lock.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Log.obj b/src/libs/resiprocate/rutil/SSL-Debug/Log.obj new file mode 100644 index 00000000..77111432 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Log.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/MD5Stream.obj b/src/libs/resiprocate/rutil/SSL-Debug/MD5Stream.obj new file mode 100644 index 00000000..90969930 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/MD5Stream.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Mutex.obj b/src/libs/resiprocate/rutil/SSL-Debug/Mutex.obj new file mode 100644 index 00000000..3d841bdc Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Mutex.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/OpenSSLInit.obj b/src/libs/resiprocate/rutil/SSL-Debug/OpenSSLInit.obj new file mode 100644 index 00000000..55cce598 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/OpenSSLInit.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/ParseBuffer.obj b/src/libs/resiprocate/rutil/SSL-Debug/ParseBuffer.obj new file mode 100644 index 00000000..f9ee17cb Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/ParseBuffer.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/ParseException.obj b/src/libs/resiprocate/rutil/SSL-Debug/ParseException.obj new file mode 100644 index 00000000..7e605d9b Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/ParseException.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Poll.obj b/src/libs/resiprocate/rutil/SSL-Debug/Poll.obj new file mode 100644 index 00000000..f8577cf4 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Poll.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/PoolBase.obj b/src/libs/resiprocate/rutil/SSL-Debug/PoolBase.obj new file mode 100644 index 00000000..5fd9f6f4 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/PoolBase.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/QueryTypes.obj b/src/libs/resiprocate/rutil/SSL-Debug/QueryTypes.obj new file mode 100644 index 00000000..bd6b0f60 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/QueryTypes.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/RRCache.obj b/src/libs/resiprocate/rutil/SSL-Debug/RRCache.obj new file mode 100644 index 00000000..bbbc5271 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/RRCache.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/RRList.obj b/src/libs/resiprocate/rutil/SSL-Debug/RRList.obj new file mode 100644 index 00000000..5e480e6f Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/RRList.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/RROverlay.obj b/src/libs/resiprocate/rutil/SSL-Debug/RROverlay.obj new file mode 100644 index 00000000..6a685b66 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/RROverlay.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/RRVip.obj b/src/libs/resiprocate/rutil/SSL-Debug/RRVip.obj new file mode 100644 index 00000000..f97a0023 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/RRVip.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/RWMutex.obj b/src/libs/resiprocate/rutil/SSL-Debug/RWMutex.obj new file mode 100644 index 00000000..99699d7e Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/RWMutex.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Random.obj b/src/libs/resiprocate/rutil/SSL-Debug/Random.obj new file mode 100644 index 00000000..80b7f4f1 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Random.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/RecursiveMutex.obj b/src/libs/resiprocate/rutil/SSL-Debug/RecursiveMutex.obj new file mode 100644 index 00000000..c324c1b7 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/RecursiveMutex.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/SHA1Stream.obj b/src/libs/resiprocate/rutil/SSL-Debug/SHA1Stream.obj new file mode 100644 index 00000000..2b0138e5 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/SHA1Stream.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/SelectInterruptor.obj b/src/libs/resiprocate/rutil/SSL-Debug/SelectInterruptor.obj new file mode 100644 index 00000000..ab913d61 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/SelectInterruptor.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/ServerProcess.obj b/src/libs/resiprocate/rutil/SSL-Debug/ServerProcess.obj new file mode 100644 index 00000000..ce0c239f Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/ServerProcess.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Socket.obj b/src/libs/resiprocate/rutil/SSL-Debug/Socket.obj new file mode 100644 index 00000000..08dfe951 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Socket.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Stun.obj b/src/libs/resiprocate/rutil/SSL-Debug/Stun.obj new file mode 100644 index 00000000..8c125766 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Stun.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Subsystem.obj b/src/libs/resiprocate/rutil/SSL-Debug/Subsystem.obj new file mode 100644 index 00000000..59bd82cf Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Subsystem.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/SysLogBuf.obj b/src/libs/resiprocate/rutil/SSL-Debug/SysLogBuf.obj new file mode 100644 index 00000000..c3c9ed14 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/SysLogBuf.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/SysLogStream.obj b/src/libs/resiprocate/rutil/SSL-Debug/SysLogStream.obj new file mode 100644 index 00000000..83392cfb Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/SysLogStream.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/ThreadIf.obj b/src/libs/resiprocate/rutil/SSL-Debug/ThreadIf.obj new file mode 100644 index 00000000..9a3959a2 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/ThreadIf.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Time.obj b/src/libs/resiprocate/rutil/SSL-Debug/Time.obj new file mode 100644 index 00000000..395d9122 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Time.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Timer.obj b/src/libs/resiprocate/rutil/SSL-Debug/Timer.obj new file mode 100644 index 00000000..e1a815d7 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Timer.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/TransportType.obj b/src/libs/resiprocate/rutil/SSL-Debug/TransportType.obj new file mode 100644 index 00000000..53494cf0 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/TransportType.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/Udp.obj b/src/libs/resiprocate/rutil/SSL-Debug/Udp.obj new file mode 100644 index 00000000..925db28c Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/Udp.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/WinCompat.obj b/src/libs/resiprocate/rutil/SSL-Debug/WinCompat.obj new file mode 100644 index 00000000..2d7be66d Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/WinCompat.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/XMLCursor.obj b/src/libs/resiprocate/rutil/SSL-Debug/XMLCursor.obj new file mode 100644 index 00000000..0e0ec3f2 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/XMLCursor.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/resipfaststreams.obj b/src/libs/resiprocate/rutil/SSL-Debug/resipfaststreams.obj new file mode 100644 index 00000000..52519f83 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/resipfaststreams.obj differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/rutil.Build.CppClean.log b/src/libs/resiprocate/rutil/SSL-Debug/rutil.Build.CppClean.log new file mode 100644 index 00000000..9a156d50 --- /dev/null +++ b/src/libs/resiprocate/rutil/SSL-Debug/rutil.Build.CppClean.log @@ -0,0 +1,68 @@ +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\vc120.pdb +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\rutil.lib +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\abstractfifo.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\aresdns.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\atomiccounter.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\baseexception.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\coders.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\condition.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\configparse.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\countstream.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\data.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\datastream.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\dnsaaaarecord.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\dnscnamerecord.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\dnshostrecord.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\dnsnaptrrecord.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\dnssrvrecord.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\dnsstub.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\dnsthread.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\dnsutil.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\externaldnsfactory.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\fdpoll.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\filesystem.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\generalcongestionmanager.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\heapinstancecounter.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\keyvaluestore.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\localdns.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\lock.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\log.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\md5stream.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\mutex.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\opensslinit.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\parsebuffer.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\parseexception.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\poll.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\poolbase.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\querytypes.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\random.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\recursivemutex.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\resipfaststreams.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\rrcache.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\rrlist.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\rroverlay.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\rrvip.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\rwmutex.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\selectinterruptor.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\serverprocess.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\sha1stream.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\socket.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\stun.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\subsystem.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\syslogbuf.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\syslogstream.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\threadif.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\time.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\timer.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\transporttype.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\udp.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\vmd5.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\wincompat.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\xmlcursor.obj +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\vc120.idb +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\rutil.tlog\cl.command.1.tlog +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\rutil.tlog\cl.read.1.tlog +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\rutil.tlog\cl.write.1.tlog +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\rutil.tlog\lib-link.read.1.tlog +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\rutil.tlog\lib-link.write.1.tlog +c:\works\own\rtphone\libs\resiprocate\rutil\ssl-debug\rutil.tlog\lib.command.1.tlog diff --git a/src/libs/resiprocate/rutil/SSL-Debug/rutil.lib b/src/libs/resiprocate/rutil/SSL-Debug/rutil.lib new file mode 100644 index 00000000..f2404c9e Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/rutil.lib differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/CL.read.1.tlog b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/CL.read.1.tlog new file mode 100644 index 00000000..4148748c Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/CL.read.1.tlog differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/Lib-link.read.1.tlog b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/Lib-link.read.1.tlog new file mode 100644 index 00000000..3af9166d Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/Lib-link.read.1.tlog differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/Lib-link.write.1.tlog b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/Lib-link.write.1.tlog new file mode 100644 index 00000000..76f06785 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/Lib-link.write.1.tlog differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/cl.command.1.tlog b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/cl.command.1.tlog new file mode 100644 index 00000000..1acc3e9b Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/cl.command.1.tlog differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/cl.write.1.tlog b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/cl.write.1.tlog new file mode 100644 index 00000000..f18acee0 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/cl.write.1.tlog differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/lib.command.1.tlog b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/lib.command.1.tlog new file mode 100644 index 00000000..d1c92b76 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/lib.command.1.tlog differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/rutil.lastbuildstate b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/rutil.lastbuildstate new file mode 100644 index 00000000..9849a2df --- /dev/null +++ b/src/libs/resiprocate/rutil/SSL-Debug/rutil.tlog/rutil.lastbuildstate @@ -0,0 +1,2 @@ +#TargetFrameworkVersion=v4.0:PlatformToolSet=v120:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit +SSL-Debug|Win32|C:\works\own\rtphone\| diff --git a/src/libs/resiprocate/rutil/SSL-Debug/rutil_9_0.log b/src/libs/resiprocate/rutil/SSL-Debug/rutil_9_0.log new file mode 100644 index 00000000..41ffb659 --- /dev/null +++ b/src/libs/resiprocate/rutil/SSL-Debug/rutil_9_0.log @@ -0,0 +1,131 @@ +Build started 10/22/2015 4:21:01 PM. + 1>Project "C:\works\own\rtphone\Libs\resiprocate\rutil\rutil_9_0.vcxproj" on node 4 (Rebuild target(s)). + 1>ClCompile: + C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\CL.exe /c /IC:\works\own\rtphone\Libs\resiprocate\rutil\../contrib/ares /IC:\works\own\rtphone\Libs\resiprocate\rutil\../ /IC:\works\own\rtphone\Libs\resiprocate\rutil\../contrib/openssl/include /IC:\works\own\rtphone\Libs\resiprocate\rutil\../../openssl/include /ZI /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D _LIB /D USE_ARES /D USE_IPV6 /D USE_SSL /D LEAK_CHECK /D _VC80_UPGRADE=0x0710 /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /GR /Fo"SSL-Debug\\" /Fd"SSL-Debug\vc120.pdb" /Gd /TP /analyze- /errorReport:prompt /MP AbstractFifo.cxx AtomicCounter.cxx dns\AresDns.cxx BaseException.cxx Coders.cxx Condition.cxx ConfigParse.cxx CountStream.cxx Data.cxx DataStream.cxx dns\DnsAAAARecord.cxx dns\DnsCnameRecord.cxx dns\DnsHostRecord.cxx dns\DnsNaptrRecord.cxx dns\DnsSrvRecord.cxx dns\DnsStub.cxx dns\DnsThread.cxx DnsUtil.cxx dns\ExternalDnsFactory.cxx FdPoll.cxx FileSystem.cxx GeneralCongestionManager.cxx HeapInstanceCounter.cxx KeyValueStore.cxx dns\LocalDns.cxx Lock.cxx Log.cxx MD5Stream.cxx Mutex.cxx ssl\OpenSSLInit.cxx ParseBuffer.cxx ParseException.cxx Poll.cxx PoolBase.cxx dns\QueryTypes.cxx Random.cxx RecursiveMutex.cxx resipfaststreams.cxx dns\RRCache.cxx dns\RRList.cxx dns\RROverlay.cxx dns\RRVip.cxx RWMutex.cxx SelectInterruptor.cxx ServerProcess.cxx ssl\SHA1Stream.cxx Socket.cxx stun\Stun.cxx Subsystem.cxx SysLogBuf.cxx SysLogStream.cxx ThreadIf.cxx Time.cxx Timer.cxx TransportType.cxx stun\Udp.cxx vmd5.cxx WinCompat.cxx XMLCursor.cxx + AbstractFifo.cxx + AtomicCounter.cxx + AresDns.cxx + BaseException.cxx + Coders.cxx + Condition.cxx + ConfigParse.cxx + CountStream.cxx + Data.cxx + DataStream.cxx + DnsAAAARecord.cxx + DnsCnameRecord.cxx + DnsHostRecord.cxx + DnsNaptrRecord.cxx + DnsSrvRecord.cxx + DnsStub.cxx + DnsThread.cxx + DnsUtil.cxx + ExternalDnsFactory.cxx + FdPoll.cxx + FileSystem.cxx + GeneralCongestionManager.cxx + HeapInstanceCounter.cxx + 1>c:\works\own\rtphone\libs\resiprocate\rutil\generalcongestionmanager.cxx(139): warning C4244: 'return' : conversion from 'UInt32' to 'UInt16', possible loss of data + 1>c:\works\own\rtphone\libs\resiprocate\rutil\generalcongestionmanager.cxx(141): warning C4244: 'return' : conversion from 'UInt32' to 'UInt16', possible loss of data + KeyValueStore.cxx + LocalDns.cxx + Lock.cxx + Log.cxx + MD5Stream.cxx + Mutex.cxx + OpenSSLInit.cxx + ParseBuffer.cxx + ParseException.cxx + Poll.cxx + PoolBase.cxx + QueryTypes.cxx + Random.cxx + RecursiveMutex.cxx + resipfaststreams.cxx + RRCache.cxx + RRList.cxx + RROverlay.cxx + RRVip.cxx + RWMutex.cxx + SelectInterruptor.cxx + ServerProcess.cxx + SHA1Stream.cxx + Socket.cxx + Stun.cxx + Subsystem.cxx + SysLogBuf.cxx + SysLogStream.cxx + ThreadIf.cxx + Time.cxx + Timer.cxx + TransportType.cxx + Udp.cxx + vmd5.cxx + WinCompat.cxx + XMLCursor.cxx + Lib: + C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\Lib.exe /OUT:"SSL-Debug\rutil.lib" /NOLOGO "SSL-Debug\AbstractFifo.obj" + "SSL-Debug\AtomicCounter.obj" + "SSL-Debug\AresDns.obj" + "SSL-Debug\BaseException.obj" + "SSL-Debug\Coders.obj" + "SSL-Debug\Condition.obj" + "SSL-Debug\ConfigParse.obj" + "SSL-Debug\CountStream.obj" + "SSL-Debug\Data.obj" + "SSL-Debug\DataStream.obj" + "SSL-Debug\DnsAAAARecord.obj" + "SSL-Debug\DnsCnameRecord.obj" + "SSL-Debug\DnsHostRecord.obj" + "SSL-Debug\DnsNaptrRecord.obj" + "SSL-Debug\DnsSrvRecord.obj" + "SSL-Debug\DnsStub.obj" + "SSL-Debug\DnsThread.obj" + "SSL-Debug\DnsUtil.obj" + "SSL-Debug\ExternalDnsFactory.obj" + "SSL-Debug\FdPoll.obj" + "SSL-Debug\FileSystem.obj" + "SSL-Debug\GeneralCongestionManager.obj" + "SSL-Debug\HeapInstanceCounter.obj" + "SSL-Debug\KeyValueStore.obj" + "SSL-Debug\LocalDns.obj" + "SSL-Debug\Lock.obj" + "SSL-Debug\Log.obj" + "SSL-Debug\MD5Stream.obj" + "SSL-Debug\Mutex.obj" + "SSL-Debug\OpenSSLInit.obj" + "SSL-Debug\ParseBuffer.obj" + "SSL-Debug\ParseException.obj" + "SSL-Debug\Poll.obj" + "SSL-Debug\PoolBase.obj" + "SSL-Debug\QueryTypes.obj" + "SSL-Debug\Random.obj" + "SSL-Debug\RecursiveMutex.obj" + "SSL-Debug\resipfaststreams.obj" + "SSL-Debug\RRCache.obj" + "SSL-Debug\RRList.obj" + "SSL-Debug\RROverlay.obj" + "SSL-Debug\RRVip.obj" + "SSL-Debug\RWMutex.obj" + "SSL-Debug\SelectInterruptor.obj" + "SSL-Debug\ServerProcess.obj" + "SSL-Debug\SHA1Stream.obj" + "SSL-Debug\Socket.obj" + "SSL-Debug\Stun.obj" + "SSL-Debug\Subsystem.obj" + "SSL-Debug\SysLogBuf.obj" + "SSL-Debug\SysLogStream.obj" + "SSL-Debug\ThreadIf.obj" + "SSL-Debug\Time.obj" + "SSL-Debug\Timer.obj" + "SSL-Debug\TransportType.obj" + "SSL-Debug\Udp.obj" + "SSL-Debug\vmd5.obj" + "SSL-Debug\WinCompat.obj" + "SSL-Debug\XMLCursor.obj" + rutil_9_0.vcxproj -> C:\works\own\rtphone\Libs\resiprocate\rutil\SSL-Debug\rutil.lib + 1>Done Building Project "C:\works\own\rtphone\Libs\resiprocate\rutil\rutil_9_0.vcxproj" (Rebuild target(s)). + +Build succeeded. + +Time Elapsed 00:02:04.96 diff --git a/src/libs/resiprocate/rutil/SSL-Debug/vc120.idb b/src/libs/resiprocate/rutil/SSL-Debug/vc120.idb new file mode 100644 index 00000000..0f966cee Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/vc120.idb differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/vc120.pdb b/src/libs/resiprocate/rutil/SSL-Debug/vc120.pdb new file mode 100644 index 00000000..beaf50be Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/vc120.pdb differ diff --git a/src/libs/resiprocate/rutil/SSL-Debug/vmd5.obj b/src/libs/resiprocate/rutil/SSL-Debug/vmd5.obj new file mode 100644 index 00000000..91a8a464 Binary files /dev/null and b/src/libs/resiprocate/rutil/SSL-Debug/vmd5.obj differ diff --git a/src/libs/resiprocate/rutil/SelectInterruptor.cxx b/src/libs/resiprocate/rutil/SelectInterruptor.cxx new file mode 100644 index 00000000..7dc7d7fe --- /dev/null +++ b/src/libs/resiprocate/rutil/SelectInterruptor.cxx @@ -0,0 +1,189 @@ +#include "rutil/SelectInterruptor.hxx" + +#include <cassert> +#include "rutil/Logger.hxx" + +#ifndef WIN32 +#include <unistd.h> +#endif + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +SelectInterruptor::SelectInterruptor() +{ + return; +#ifdef WIN32 + mSocket = ::socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + + sockaddr_in loopback; + memset(&loopback, 0, sizeof(loopback)); + loopback.sin_family = AF_INET; + loopback.sin_port = 0; + loopback.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + makeSocketNonBlocking(mSocket); //win32 woes + ::bind( mSocket, reinterpret_cast<sockaddr*>(&loopback), sizeof(loopback)); + memset(&mWakeupAddr, 0, sizeof(mWakeupAddr)); + int len = sizeof(mWakeupAddr); + int error = getsockname(mSocket, (sockaddr *)&mWakeupAddr, &len); + assert(error == 0); + error= connect(mSocket, &mWakeupAddr, sizeof(mWakeupAddr)); + assert(error == 0); + mReadThing = mSocket; +#else + int x = pipe(mPipe); + (void)x; + assert( x != -1 ); + // make write-side non-blocking to avoid deadlock + makeSocketNonBlocking(mPipe[1]); + // make read-side non-blocking so safe to read out entire pipe + // all in one go (also just safer) + makeSocketNonBlocking(mPipe[0]); + mReadThing = mPipe[0]; +#endif +} + +SelectInterruptor::~SelectInterruptor() +{ + return; +#ifdef WIN32 + closesocket(mSocket); +#else + close(mPipe[0]); + close(mPipe[1]); +#endif +} + +void +SelectInterruptor::handleProcessNotification() +{ + return; + interrupt(); +} + +void +SelectInterruptor::buildFdSet(FdSet& fdset) +{ + return; +#ifdef WIN32 + fdset.setRead(mSocket); +#else + fdset.setRead(mPipe[0]); +#endif +} + +void +SelectInterruptor::processCleanup() +{ + return; +#ifdef WIN32 + { + char rdBuf[16]; + recv(mSocket, rdBuf, sizeof(rdBuf), 0); + } +#else + { + char rdBuf[16]; + int x; + while ( (x=read(mPipe[0], rdBuf, sizeof(rdBuf))) == sizeof(rdBuf) ) + ; + // WATCHOUT: EWOULDBLOCK *will* happen above when the pending + // number of bytes is exactly size of rdBuf + // XXX: should check for certain errors (like fd closed) and die? + } +#endif +} + +void +SelectInterruptor::process(FdSet& fdset) +{ + return; + if (fdset.readyToRead(mReadThing)) + processCleanup(); +} + +void +SelectInterruptor::processPollEvent(FdPollEventMask mask) +{ + return; + if(mask & FPEM_Read) + { + processCleanup(); + } +} + + +void +SelectInterruptor::interrupt() +{ + return; + + static char wakeUp[] = "w"; +#ifdef WIN32 + int count = send(mSocket, wakeUp, sizeof(wakeUp), 0); + assert(count == sizeof(wakeUp)); +#else + ssize_t res = write(mPipe[1], wakeUp, sizeof(wakeUp)); + if ( res == -1 && errno==EAGAIN ) + { + ; // this can happen when SipStack thread gets behind. + // no need to block since our only purpose is to wake up the thread + // also, this write can occur within the SipStack thread, in which + // case we get dead-lock if this blocks + } else { + assert(res == sizeof(wakeUp)); + } +#endif +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/SelectInterruptor.hxx b/src/libs/resiprocate/rutil/SelectInterruptor.hxx new file mode 100644 index 00000000..ec68783b --- /dev/null +++ b/src/libs/resiprocate/rutil/SelectInterruptor.hxx @@ -0,0 +1,131 @@ +#ifndef RESIP_SelectInterruptor_HXX +#define RESIP_SelectInterruptor_HXX + +#include "rutil/AsyncProcessHandler.hxx" +#include "rutil/FdPoll.hxx" +#include "rutil/Socket.hxx" + +#if 0 +#if defined(WIN32) +#include <Ws2tcpip.h> +#else +#include <netinet/in.h> +#endif +#endif + +namespace resip +{ + +/** + Used to 'artificially' interrupt a select call +*/ +class SelectInterruptor : public AsyncProcessHandler, public FdPollItemIf +{ + public: + SelectInterruptor(); + virtual ~SelectInterruptor(); + + /** + Called by the stack when messages are posted to it. + Calls interrupt. + */ + virtual void handleProcessNotification(); + + /** +// cause the 'artificial' fd to signal + */ + void interrupt(); + + /** + Used to add the 'artificial' fd to the fdset that + will be responsible for interrupting a subsequent select + call. + */ + void buildFdSet(FdSet& fdset); + + /** + cleanup signalled fd + */ + void process(FdSet& fdset); + + virtual void processPollEvent(FdPollEventMask mask); + + /* Get fd of read-side, for use within PollInterruptor, + * Declared as Socket for easier cross-platform even though pipe fd + * under linux. + */ + Socket getReadSocket() const { return INVALID_SOCKET;/*mReadThing;*/ } + + protected: + + /* Cleanup the read side of the interruptor + * If fdset is provided, it will only try cleaning up if our pipe + * is ready in fdset. If NULL, it will unconditionally try reading. + * This last feature is for use within PollInterruptor. + */ + void processCleanup(); + private: +#ifndef WIN32 + int mPipe[2]; +#else + Socket mSocket; + sockaddr mWakeupAddr; +#endif + // either mPipe[0] or mSocket + Socket mReadThing; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/ServerProcess.cxx b/src/libs/resiprocate/rutil/ServerProcess.cxx new file mode 100644 index 00000000..ec16e7ea --- /dev/null +++ b/src/libs/resiprocate/rutil/ServerProcess.cxx @@ -0,0 +1,110 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#ifndef WIN32 +#include <sys/types.h> +#include <unistd.h> +#endif + +#include <iostream> +#include <fstream> +#include <signal.h> +#include <stdexcept> + +#include "rutil/ServerProcess.hxx" +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::SIP + +using namespace resip; +using namespace std; + +ServerProcess::ServerProcess() : mPidFile("") +{ +} + +ServerProcess::~ServerProcess() +{ +} + +void +ServerProcess::daemonize() +{ +#ifdef WIN32 + // fork is not possible on Windows + throw std::runtime_error("Unable to fork/daemonize on Windows, please check the config"); +#else + pid_t pid; + if ((pid = fork()) < 0) + { + // fork() failed + throw std::runtime_error(strerror(errno)); + } + else if (pid != 0) + { + // parent process done + exit(0); + } + if(chdir("/") < 0) + throw std::runtime_error(strerror(errno)); + // Nothing should be writing to stdout/stderr after this + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + if(mPidFile.size() > 0) + { + std::ofstream _pid(mPidFile.c_str(), std::ios_base::out | std::ios_base::trunc); + _pid << getpid(); + _pid.close(); + } +#endif +} + +void +ServerProcess::setPidFile(const Data& pidFile) +{ + mPidFile = pidFile; +} + +/* ==================================================================== + * + * Copyright (c) 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ +/* + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/ServerProcess.hxx b/src/libs/resiprocate/rutil/ServerProcess.hxx new file mode 100644 index 00000000..d7aee732 --- /dev/null +++ b/src/libs/resiprocate/rutil/ServerProcess.hxx @@ -0,0 +1,68 @@ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "rutil/Data.hxx" + +namespace resip +{ + +class ServerProcess +{ +public: + ServerProcess(); + virtual ~ServerProcess(); + +protected: + /* The main subclass can call daemonize() if and + when it wants to become a daemon */ + void daemonize(); + + /* Filename of PID file, or empty string for no PID file */ + void setPidFile(const Data& pidFile); + +private: + Data mPidFile; +}; + +} + +/* ==================================================================== + * + * Copyright (c) 2012 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ +/* + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/SharedCount.hxx b/src/libs/resiprocate/rutil/SharedCount.hxx new file mode 100644 index 00000000..54e353a8 --- /dev/null +++ b/src/libs/resiprocate/rutil/SharedCount.hxx @@ -0,0 +1,398 @@ +#if !defined(RESIP_SHAREDCOUNT_HXX) +#define RESIP_SHAREDCOUNT_HXX + +/** + @file + @brief Defines a threadsafe (shared) reference-count object. + + @note This implementation is a modified version of shared_count from + Boost.org +*/ + +#include <memory> // std::auto_ptr, std::allocator +#include <functional> // std::less +#include <exception> // std::exception +#include <new> // std::bad_alloc +#include <typeinfo> // std::type_info in get_deleter +#include <cstddef> // std::size_t +#include "rutil/Lock.hxx" +#include "rutil/Mutex.hxx" +//#include "rutil/Logger.hxx" + +#ifdef __BORLANDC__ +# pragma warn -8026 // Functions with excep. spec. are not expanded inline +# pragma warn -8027 // Functions containing try are not expanded inline +#endif + +namespace resip +{ + +// verify that types are complete for increased safety +template<class T> inline void checked_delete(T * x) +{ + // intentionally complex - simplification causes regressions + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete x; +}; + +template<class T> struct checked_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + // resip:: disables ADL + resip::checked_delete(x); + } +}; + +// The standard library that comes with Borland C++ 5.5.1 +// defines std::exception and its members as having C calling +// convention (-pc). When the definition of bad_weak_ptr +// is compiled with -ps, the compiler issues an error. +// Hence, the temporary #pragma option -pc below. The version +// check is deliberately conservative. +#if defined(__BORLANDC__) && __BORLANDC__ == 0x551 +# pragma option push -pc +#endif + +class bad_weak_ptr: public std::exception +{ +public: + + virtual char const * what() const throw() + { + return "resip::bad_weak_ptr"; + } +}; + +#if defined(__BORLANDC__) && __BORLANDC__ == 0x551 +# pragma option pop +#endif + +class sp_counted_base +{ +private: + +public: + + sp_counted_base(): use_count_(1), weak_count_(1) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + virtual void dispose() = 0; // nothrow + + // destruct() is called when weak_count_ drops to zero. + virtual void destruct() // nothrow + { + delete this; + } + + virtual void * get_deleter(std::type_info const & ti) = 0; + + void add_ref_copy() + { + Lock lock(mMutex); (void)lock; + ++use_count_; + //GenericLog(Subsystem::SIP, resip::Log::Info, << "********* SharedCount::add_ref_copy: " << use_count_); + } + + void add_ref_lock() + { + Lock lock(mMutex); (void)lock; + // if(use_count_ == 0) throw(resip::bad_weak_ptr()); + if (use_count_ == 0) throw resip::bad_weak_ptr(); + ++use_count_; + //GenericLog(Subsystem::SIP, resip::Log::Info, << "********* SharedCount::add_ref_lock: " << use_count_); + } + + void release() // nothrow + { + { + Lock lock(mMutex); (void)lock; + long new_use_count = --use_count_; + //GenericLog(Subsystem::SIP, resip::Log::Info, << "********* SharedCount::release: " << use_count_); + + if(new_use_count != 0) return; + } + + dispose(); + weak_release(); + } + + void weak_add_ref() // nothrow + { + Lock lock(mMutex); (void)lock; + ++weak_count_; + } + + void weak_release() // nothrow + { + long new_weak_count; + + { + Lock lock(mMutex); (void)lock; + new_weak_count = --weak_count_; + } + + if(new_weak_count == 0) + { + destruct(); + } + } + + long use_count() const // nothrow + { + Lock lock(mMutex); (void)lock; + return use_count_; + } + +private: + + sp_counted_base(sp_counted_base const &); + sp_counted_base & operator= (sp_counted_base const &); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + + mutable Mutex mMutex; +}; + +// +// Borland's Codeguard trips up over the -Vx- option here: +// +#ifdef __CODEGUARD__ +# pragma option push -Vx- +#endif + +template<class P, class D> class sp_counted_base_impl: public sp_counted_base +{ +private: + + P ptr; // copy constructor must not throw + D del; // copy constructor must not throw + + sp_counted_base_impl(sp_counted_base_impl const &); + sp_counted_base_impl & operator= (sp_counted_base_impl const &); + + typedef sp_counted_base_impl<P, D> this_type; + +public: + + // pre: initial_use_count <= initial_weak_count, d(p) must not throw + sp_counted_base_impl(P p, D d): ptr(p), del(d) + { + } + + virtual void dispose() // nothrow + { + del(ptr); + } + + virtual void * get_deleter(std::type_info const & ti) + { + return ti == typeid(D)? &del: 0; + } + + void * operator new(size_t) + { + return std::allocator<this_type>().allocate(1, static_cast<this_type *>(0)); + } + + void operator delete(void * p) + { + std::allocator<this_type>().deallocate(static_cast<this_type *>(p), 1); + } + +}; + +class shared_count +{ +private: + + sp_counted_base * pi_; + +public: + + shared_count(): pi_(0) // nothrow + { + } + + template<class P, class D> shared_count(P p, D d): pi_(0) + { + try + { + pi_ = new sp_counted_base_impl<P, D>(p, d); + } + catch(...) + { + d(p); // delete p + throw; + } + } + + // auto_ptr<Y> is special cased to provide the strong guarantee + template<class Y> + explicit shared_count(std::auto_ptr<Y> & r): pi_(new sp_counted_base_impl< Y *, checked_deleter<Y> >(r.get(), checked_deleter<Y>())) + { + r.release(); + } + + ~shared_count() // nothrow + { + if(pi_ != 0) pi_->release(); + } + + shared_count(shared_count const & r): pi_(r.pi_) // nothrow + { + if(pi_ != 0) pi_->add_ref_copy(); + } + + shared_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + if(tmp != 0) tmp->add_ref_copy(); + if(pi_ != 0) pi_->release(); + pi_ = tmp; + + return *this; + } + + void swap(shared_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + bool unique() const // nothrow + { + return use_count() == 1; + } + + friend inline bool operator==(shared_count const & a, shared_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(shared_count const & a, shared_count const & b) + { + return std::less<sp_counted_base *>()(a.pi_, b.pi_); + } + + void * get_deleter(std::type_info const & ti) const + { + return pi_? pi_->get_deleter(ti): 0; + } +}; + +#ifdef __CODEGUARD__ +# pragma option pop +#endif + +} // namespace resip + +#ifdef __BORLANDC__ +# pragma warn .8027 // Functions containing try are not expanded inline +# pragma warn .8026 // Functions with excep. spec. are not expanded inline +#endif + + +#endif + +// Note: This implementation is a modified version of shared_count from +// Boost.org +// + +/* ==================================================================== + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * ==================================================================== + */ + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/SharedPtr.hxx b/src/libs/resiprocate/rutil/SharedPtr.hxx new file mode 100644 index 00000000..82391e9c --- /dev/null +++ b/src/libs/resiprocate/rutil/SharedPtr.hxx @@ -0,0 +1,466 @@ +#if !defined(RESIP_SHAREDPTR_HXX) +#define RESIP_SHAREDPTR_HXX + +/** + @file + @brief Defines a reference-counted pointer class. + @note This implementation is a modified version of shared_ptr from + Boost.org. License text is below. + + http://www.boost.org/libs/smart_ptr/shared_ptr.htm +*/ + +#include "rutil/SharedCount.hxx" +#include <memory> // for std::auto_ptr +#include <algorithm> // for std::swap +#include <functional> // for std::less +#include <typeinfo> // for std::bad_cast +#include <iosfwd> // for std::basic_ostream +#include <cassert> + +namespace resip +{ + +template<class T> class enable_shared_from_this; + +struct static_cast_tag {}; +struct const_cast_tag {}; +struct dynamic_cast_tag {}; +struct polymorphic_cast_tag {}; + +template<class T> struct SharedPtr_traits +{ + typedef T & reference; +}; + +template<> struct SharedPtr_traits<void> +{ + typedef void reference; +}; + +template<> struct SharedPtr_traits<void const> +{ + typedef void reference; +}; + +template<> struct SharedPtr_traits<void volatile> +{ + typedef void reference; +}; + +template<> struct SharedPtr_traits<void const volatile> +{ + typedef void reference; +}; + +// enable_shared_from_this support + +template<class T, class Y> void sp_enable_shared_from_this( shared_count const & pn, resip::enable_shared_from_this<T> const * pe, Y const * px ) +{ + if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn); +} + +inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... ) +{ +} + +/** + @brief Implements reference counted copy semantics for a class T. + + The object pointed to is deleted when the last SharedPtr pointing to it + is destroyed or reset. +*/ +template<class T> class SharedPtr +{ +private: + + // Borland 5.5.1 specific workaround + typedef SharedPtr<T> this_type; + +public: + + typedef T element_type; + typedef T value_type; + typedef T * pointer; + typedef typename SharedPtr_traits<T>::reference reference; + + SharedPtr(): px(0), pn() // never throws in 1.30+ + { + } + + template<class Y> + explicit SharedPtr(Y * p): px(p), pn(p, checked_deleter<Y>()) // Y must be complete + { + sp_enable_shared_from_this( pn, p, p ); + } + + // + // Requirements: D's copy constructor must not throw + // + // SharedPtr will release p by calling d(p) + // + + template<class Y, class D> SharedPtr(Y * p, D d): px(p), pn(p, d) + { + sp_enable_shared_from_this( pn, p, p ); + } + +// generated copy constructor, assignment, destructor are fine... + +// except that Borland C++ has a bug, and g++ with -Wsynth warns +#if defined(__BORLANDC__) || defined(__GNUC__) + SharedPtr & operator=(SharedPtr const & r) // never throws + { + px = r.px; + pn = r.pn; // shared_count::op= doesn't throw + return *this; + } +#endif + + template<class Y> + SharedPtr(SharedPtr<Y> const & r): px(r.px), pn(r.pn) // never throws + { + } + + template<class Y> + SharedPtr(SharedPtr<Y> const & r, static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn) + { + } + + template<class Y> + SharedPtr(SharedPtr<Y> const & r, const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn) + { + } + + template<class Y> + SharedPtr(SharedPtr<Y> const & r, dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn) + { + if(px == 0) // need to allocate new counter -- the cast failed + { + pn = resip::shared_count(); + } + } + + template<class Y> + SharedPtr(SharedPtr<Y> const & r, polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn) + { + if(px == 0) + { + throw std::bad_cast(); + } + } + + template<class Y> + explicit SharedPtr(std::auto_ptr<Y> & r): px(r.get()), pn() + { + Y * tmp = r.get(); + pn = shared_count(r); + sp_enable_shared_from_this( pn, tmp, tmp ); + } + + template<class Y> + SharedPtr & operator=(SharedPtr<Y> const & r) // never throws + { + px = r.px; + pn = r.pn; // shared_count::op= doesn't throw + return *this; + } + + template<class Y> + SharedPtr & operator=(std::auto_ptr<Y> & r) + { + this_type(r).swap(*this); + return *this; + } + + void reset() // never throws in 1.30+ + { + this_type().swap(*this); + } + + template<class Y> void reset(Y * p) // Y must be complete + { + assert(p == 0 || p != px); // catch self-reset errors + this_type(p).swap(*this); + } + + template<class Y, class D> void reset(Y * p, D d) + { + this_type(p, d).swap(*this); + } + + reference operator* () const // never throws + { + assert(px != 0); + return *px; + } + + T * operator-> () const // never throws + { + assert(px != 0); + return px; + } + + T * get() const // never throws + { + return px; + } + + // implicit conversion to "bool" +#if defined(__SUNPRO_CC) // BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) + operator bool () const + { + return px != 0; + } +#elif defined(__MWERKS__) // BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) + typedef T * (this_type::*unspecified_bool_type)() const; + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::get; + } +#else + typedef T * this_type::*unspecified_bool_type; + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::px; + } +#endif + + // operator! is redundant, but some compilers need it + bool operator! () const // never throws + { + return px == 0; + } + + bool unique() const // never throws + { + return pn.unique(); + } + + long use_count() const // never throws + { + return pn.use_count(); + } + + void swap(SharedPtr<T> & other) // never throws + { + std::swap(px, other.px); + pn.swap(other.pn); + } + + template<class Y> bool _internal_less(SharedPtr<Y> const & rhs) const + { + return pn < rhs.pn; + } + + void * _internal_get_deleter(std::type_info const & ti) const + { + return pn.get_deleter(ti); + } + +// Tasteless as this may seem, making all members public allows member templates +// to work in the absence of member template friends. (Matthew Langston) + +private: + + template<class Y> friend class SharedPtr; + + T * px; // contained pointer + shared_count pn; // reference counter + +}; // SharedPtr + +template<class T, class U> inline bool operator==(SharedPtr<T> const & a, SharedPtr<U> const & b) +{ + return a.get() == b.get(); +} + +template<class T, class U> inline bool operator!=(SharedPtr<T> const & a, SharedPtr<U> const & b) +{ + return a.get() != b.get(); +} + +#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 + +// Resolve the ambiguity between our op!= and the one in rel_ops + +template<class T> inline bool operator!=(SharedPtr<T> const & a, SharedPtr<T> const & b) +{ + return a.get() != b.get(); +} + +#endif + +template<class T, class U> inline bool operator<(SharedPtr<T> const & a, SharedPtr<U> const & b) +{ + return a._internal_less(b); +} + +template<class T> inline void swap(SharedPtr<T> & a, SharedPtr<T> & b) +{ + a.swap(b); +} + +template<class T, class U> SharedPtr<T> static_pointer_cast(SharedPtr<U> const & r) +{ + return SharedPtr<T>(r, static_cast_tag()); +} + +template<class T, class U> SharedPtr<T> const_pointer_cast(SharedPtr<U> const & r) +{ + return SharedPtr<T>(r, const_cast_tag()); +} + +template<class T, class U> SharedPtr<T> dynamic_pointer_cast(SharedPtr<U> const & r) +{ + return SharedPtr<T>(r, dynamic_cast_tag()); +} + +// shared_*_cast names are deprecated. Use *_pointer_cast instead. + +template<class T, class U> SharedPtr<T> shared_static_cast(SharedPtr<U> const & r) +{ + return SharedPtr<T>(r, static_cast_tag()); +} + +template<class T, class U> SharedPtr<T> shared_dynamic_cast(SharedPtr<U> const & r) +{ + return SharedPtr<T>(r, dynamic_cast_tag()); +} + +template<class T, class U> SharedPtr<T> shared_polymorphic_cast(SharedPtr<U> const & r) +{ + return SharedPtr<T>(r, polymorphic_cast_tag()); +} + +template<class T, class U> SharedPtr<T> shared_polymorphic_downcast(SharedPtr<U> const & r) +{ + assert(dynamic_cast<T *>(r.get()) == r.get()); + return shared_static_cast<T>(r); +} + +template<class T> inline T * get_pointer(SharedPtr<T> const & p) +{ + return p.get(); +} + +// operator<< +#if defined(__GNUC__) && (__GNUC__ < 3) +template<class Y> EncodeStream & operator<< (EncodeStream & os, SharedPtr<Y> const & p) +{ + os << p.get(); + return os; +} +#else +template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, SharedPtr<Y> const & p) +{ + os << p.get(); + return os; +} +#endif + +// get_deleter (experimental) +#if (defined(__GNUC__) && (__GNUC__ < 3)) || (defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238)) +// g++ 2.9x doesn't allow static_cast<X const *>(void *) +// apparently EDG 2.38 also doesn't accept it +template<class D, class T> D * get_deleter(SharedPtr<T> const & p) +{ + void const * q = p._internal_get_deleter(typeid(D)); + return const_cast<D *>(static_cast<D const *>(q)); +} +#else +template<class D, class T> D * get_deleter(SharedPtr<T> const & p) +{ + return static_cast<D *>(p._internal_get_deleter(typeid(D))); +} +#endif + +} // namespace resip + +#endif + +// Note: This implementation is a modified version of shared_ptr from +// Boost.org +// +// http://www.boost.org/libs/smart_ptr/shared_ptr.htm +// + +/* ==================================================================== + * + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * ==================================================================== + */ + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Socket.cxx b/src/libs/resiprocate/rutil/Socket.cxx new file mode 100644 index 00000000..e7eabb63 --- /dev/null +++ b/src/libs/resiprocate/rutil/Socket.cxx @@ -0,0 +1,332 @@ + +#include <cassert> +#include <fcntl.h> +#include <errno.h> + +#include "rutil/compat.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Logger.hxx" + +#ifndef WIN32 +#include <unistd.h> +#include <sys/resource.h> // for getrlimit() +#endif + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +bool +resip::makeSocketNonBlocking(Socket fd) +{ +#if defined(WIN32) + unsigned long noBlock = 1; + int errNoBlock = ioctlsocket( fd, FIONBIO , &noBlock ); + if ( errNoBlock != 0 ) + { + return false; + } +#else + // Make socket non raising SIGPIPE +#ifdef TARGET_OSX + int set = 1; + setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)); +#endif + + // Make socket non blocking + int flags = fcntl( fd, F_GETFL, 0); + int errNoBlock = fcntl(fd, F_SETFL, flags | O_NONBLOCK ); + if ( errNoBlock != 0 ) // !cj! I may have messed up this line + { + return false; + } +#endif + return true; +} + + +bool +resip::makeSocketBlocking(Socket fd) +{ +#if defined(WIN32) + unsigned long noBlock = 0; + int errNoBlock = ioctlsocket( fd, FIONBIO , &noBlock ); + if ( errNoBlock != 0 ) + { + return false; + } +#else + int flags = fcntl( fd, F_GETFL, 0); + int errNoBlock = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK ); + if ( errNoBlock != 0 ) // !cj! I may have messed up this line + { + return false; + } +#endif + return true; +} + + + +void +resip::initNetwork() +{ +#if defined(WIN32) + bool doneInit=false; + if( !doneInit ) + { + doneInit=true; + + WORD wVersionRequested = MAKEWORD( 2, 2 ); + WSADATA wsaData; + int err; + + err = WSAStartup( wVersionRequested, &wsaData ); + if ( err != 0 ) + { + // could not find a usable WinSock DLL + //cerr << "Could not load winsock" << endl; + assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work + exit(1); + } + + /* Confirm that the WinSock DLL supports 2.2.*/ + /* Note that if the DLL supports versions greater */ + /* than 2.2 in addition to 2.2, it will still return */ + /* 2.2 in wVersion since that is the version we */ + /* requested. */ + + if ( LOBYTE( wsaData.wVersion ) != 2 || + HIBYTE( wsaData.wVersion ) != 2 ) + { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + WSACleanup( ); + //cerr << "Bad winsock verion" << endl; + // TODO !cj! - add error message logging + assert(0); // if this is failing, try a different version that 2.2, 1.0 or later will likely work + exit(1); + } + } +#endif +} + + +#if defined(WIN32) +int +resip::closeSocket( Socket fd ) +{ + return closesocket(fd); +} +#else +int +resip::closeSocket( Socket fd ) +{ + //int ret = ::shutdown(fd, SHUT_RDWR); !jf! + int ret = ::close(fd); + if (ret < 0) + { + InfoLog (<< "Failed to shutdown socket " << fd << " : " << strerror(errno)); + } + return ret; +} +#endif + +// code moved from resip/stack/ConnectionManager.cxx +// appears to work on both linux and windows +int resip::getSocketError(Socket fd) +{ + int errNum = 0; + int errNumSize = sizeof(errNum); + getsockopt(fd, SOL_SOCKET, SO_ERROR, + (char *)&errNum, (socklen_t *)&errNumSize); + /// XXX: should check return code of getsockopt + return errNum; +} + +/** + Returns negative on error, or number of (positive) allowed fds +**/ +int +resip::increaseLimitFds(unsigned int targetFds) +{ +#if defined(WIN32) + // kw: i don't know if any equiv on windows + return targetFds; +#else + struct rlimit lim; + + if (getrlimit(RLIMIT_NOFILE, &lim) < 0) + { + CritLog(<<"getrlimit(NOFILE) failed: " << strerror(errno)); + return -1; + } + if (lim.rlim_cur==RLIM_INFINITY || targetFds < lim.rlim_cur) + { + return targetFds; + } + + int euid = geteuid(); + if (lim.rlim_max==RLIM_INFINITY || targetFds < lim.rlim_max) + { + lim.rlim_cur=targetFds; + } + else + { + if (euid!=0) + { + CritLog(<<"Attempting to increase number of fds when not root. This probably wont work"); + } + lim.rlim_cur=targetFds; + lim.rlim_max=targetFds; + } + + if (setrlimit(RLIMIT_NOFILE, &lim) < 0) + { + CritLog(<<"setrlimit(NOFILE)=(c="<<lim.rlim_cur<<",m="<<lim.rlim_max + <<",uid="<<euid<<") failed: " << strerror(errno)); + /* There is intermediate: could raise cur to max */ + return -1; + } + return targetFds; +#endif +} + +/** + Some OSs (Linux in particular) silently ignore requests to set + too big and do not return an error code. Thus we always check. + Also, the returned value (getsockopt) can be larger than the requested + value (kernel internally doubles). + manpage says sockopt uses integer as data-type + If {buflen} is negative, we skip the set and just read + Return the get size or -1 if the set didn't work +**/ +static int trySetRcvBuf(Socket fd, int buflen) +{ + if (buflen > 0) + { + int wbuflen = buflen; +#if !defined(WIN32) + if (::setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &wbuflen, sizeof(wbuflen)) == -1) +#else + if (::setsockopt (fd, SOL_SOCKET, SO_RCVBUF, (const char*)&wbuflen, sizeof(wbuflen)) == -1) +#endif + { + return -1; + } + } + int rbuflen = 0; + unsigned optlen = sizeof(rbuflen); + if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&rbuflen, (socklen_t *)&optlen) == -1) + { + return -1; + } + assert(optlen == sizeof(rbuflen)); + if (rbuflen < buflen) + { + return -1; + } + return rbuflen; +} + +/** +**/ +int resip::setSocketRcvBufLen(Socket fd, int buflen) +{ + assert(buflen >= 1024); + int goal=buflen; + int trylen=goal; + int sts; + int lastgoodset = 0, lastgoodget=0; + + /* go down by factors of 2 */ + for (; ; trylen /= 2) + { + if (trylen < 1024) + { + ErrLog(<<"setsockopt(SO_RCVBUF) failed"); + return -1; + } + if ((sts=trySetRcvBuf(fd, trylen)) >= 0) + { + lastgoodset = trylen; + lastgoodget = sts; + break; + } + } + + /* go up by 10% steps */ + unsigned step = trylen/10; + for ( ; trylen<goal; trylen+=step) + { + if ((sts=trySetRcvBuf(fd,trylen)) < 0) + { + break; + } + lastgoodset = trylen; + lastgoodget = sts; + } + if (lastgoodset < goal) + { + ErrLog(<<"setsockopt(SO_RCVBUF) goal "<<goal<<" not met (set=" + <<lastgoodset<<",get="<<lastgoodget<<")"); + } + else + { + InfoLog(<<"setsockopt(SO_RCVBUF) goal "<<goal<<" met (set=" + <<lastgoodset<<",get="<<lastgoodget<<")"); + } + return lastgoodset; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Socket.hxx b/src/libs/resiprocate/rutil/Socket.hxx new file mode 100644 index 00000000..14b236d5 --- /dev/null +++ b/src/libs/resiprocate/rutil/Socket.hxx @@ -0,0 +1,278 @@ +#if !defined(RESIP_SOCKET_HXX) +#define RESIP_SOCKET_HXX + +#include <cassert> +#include <errno.h> +#include <algorithm> + +#ifdef WIN32 +#include <winsock2.h> +#include <stdlib.h> +#include <io.h> +#include <WS2TCPIP.H> +#endif + +#include "compat.hxx" +#include "rutil/TransportType.hxx" + +/** + @file + @brief Handles cross-platform sockets compatibility. +*/ + +#ifdef WIN32 + +/** With VS 2010 Berkeley errno constants have been redefined and are now different than WSAGetLastError() WSA prefixed constants. + @see http://msdn.microsoft.com/en-us/library/ms737828(VS.85).aspx, https://connect.microsoft.com/VisualStudio/feedback/details/509380/errno-h-socket-return-codes-now-inconsistent-with-wsagetlasterror?wa=wsignin1.0 + @see <winsock2.h> + The recommended fix is to use WSAGetLastError() and with the WSAXXX constants. One way to do this would be to create RESIP_XXX socket constants that would correclty use WSAXXX constants + on windows without using the Berkeley style constants. For now just re-assign the Berkeley style constants as WSA constants. +*/ +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +#pragma warning (push) +#pragma warning (disable: 4005 ) +#endif +typedef int socklen_t; + + +//this list taken from <winsock2.h>, see #if 0 removed block. +#define EWOULDBLOCK WSAEWOULDBLOCK +#define EINPROGRESS WSAEINPROGRESS +#define EALREADY WSAEALREADY +#define ENOTSOCK WSAENOTSOCK +#define EDESTADDRREQ WSAEDESTADDRREQ +#define EMSGSIZE WSAEMSGSIZE +#define EPROTOTYPE WSAEPROTOTYPE +#define ENOPROTOOPT WSAENOPROTOOPT +#define EPROTONOSUPPORT WSAEPROTONOSUPPORT +#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT +#define EOPNOTSUPP WSAEOPNOTSUPP +#define EPFNOSUPPORT WSAEPFNOSUPPORT +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define EADDRINUSE WSAEADDRINUSE +#define EADDRNOTAVAIL WSAEADDRNOTAVAIL +#define ENETDOWN WSAENETDOWN +#define ENETUNREACH WSAENETUNREACH +#define ENETRESET WSAENETRESET +#define ECONNABORTED WSAECONNABORTED +#define ECONNRESET WSAECONNRESET +#define ENOBUFS WSAENOBUFS +#define EISCONN WSAEISCONN +#define ENOTCONN WSAENOTCONN +#define ESHUTDOWN WSAESHUTDOWN +#define ETOOMANYREFS WSAETOOMANYREFS +#define ETIMEDOUT WSAETIMEDOUT +#define ECONNREFUSED WSAECONNREFUSED +#define ELOOP WSAELOOP +//#define ENAMETOOLONG WSAENAMETOOLONG + +#define EHOSTUNREACH WSAEHOSTUNREACH +//#define ENOTEMPTY WSAENOTEMPTY +#define EPROCLIM WSAEPROCLIM +#define EUSERS WSAEUSERS +#define EDQUOT WSAEDQUOT +#define ESTALE WSAESTALE +#define EREMOTE WSAEREMOTE + + +# define EHOSTDOWN WSAEHOSTDOWN + +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +#pragma warning (pop) +#endif + +#else + +#define WSANOTINITIALISED EPROTONOSUPPORT + +#endif + +namespace resip +{ + +/// set up network - does nothing in unix but needed for windows +void +initNetwork(); + +#ifndef WIN32 +typedef int Socket; // Un*x fds are signed +#ifndef INVALID_SOCKET +#define INVALID_SOCKET (-1) +#endif +#define SOCKET_ERROR (-1) +inline int getErrno() { return errno; } +#else +typedef SOCKET Socket; // Windows defines as *unsigned* something +// INVALID_SOCKET is defined by Windows as ~0 (since Windows socket unsigned) +// SOCKET_ERROR is defined by Windows as -1 (most func retvals are signed) +inline int getErrno() { return WSAGetLastError(); } +#endif + +//c function pointer because of ares +extern "C" { +typedef void(*AfterSocketCreationFuncPtr)(Socket s, int transportType, const char* file, int line); +} + +bool makeSocketNonBlocking(Socket fd); +bool makeSocketBlocking(Socket fd); +int closeSocket( Socket fd ); +int getSocketError(Socket fd); // getsockopt(SOCK_SOCKET,SO_ERROR) +int increaseLimitFds(unsigned int targetFds); +int setSocketRcvBufLen(Socket fd, int buflen); // setsockopt(SO_RCVBUF) + + +/** + @brief Object-oriented wrapper for your platform's file-descriptor set. +*/ +class FdSet +{ +public: + FdSet() : size(0), numReady(0) + { + FD_ZERO(&read); + FD_ZERO(&write); + FD_ZERO(&except); + } + + int select(struct timeval& tv) + { + return numReady = ::select(size, &read, &write, &except, &tv); + } + + int selectMilliSeconds(unsigned long ms) + { + struct timeval tv; + tv.tv_sec = (ms/1000); + tv.tv_usec = (ms%1000)*1000; + return select(tv); + } + + bool readyToRead(Socket fd) + { + return (FD_ISSET(fd, &read) != 0); + } + + bool readyToWrite(Socket fd) + { + return (FD_ISSET(fd, &write) != 0); + } + + bool hasException(Socket fd) + { + return (FD_ISSET(fd,&except) != 0); + } + + void setRead(Socket fd) + { + assert( FD_SETSIZE >= 8 ); +#ifndef WIN32 // windows fd are not int's and don't start at 0 - this won't work in windows + assert( fd < (int)FD_SETSIZE ); // redefineing FD_SETSIZE will not work +#else + assert(read.fd_count < FD_SETSIZE); // Ensure there is room to add new FD +#endif + FD_SET(fd, &read); + size = ( int(fd+1) > size) ? int(fd+1) : size; + } + + void setWrite(Socket fd) + { +#ifndef WIN32 // windows fd are not int's and don't start at 0 - this won't work in windows + assert( fd < (int)FD_SETSIZE ); // redefinitn FD_SETSIZE will not work +#else + assert(write.fd_count < FD_SETSIZE); // Ensure there is room to add new FD +#endif + FD_SET(fd, &write); + size = ( int(fd+1) > size) ? int(fd+1) : size; + } + + void setExcept(Socket fd) + { +#ifndef WIN32 // windows fd are not int's and don't start at 0 - this won't work in windows + assert( fd < (int)FD_SETSIZE ); // redefinitn FD_SETSIZE will not work +#else + assert(except.fd_count < FD_SETSIZE); // Ensure there is room to add new FD +#endif + FD_SET(fd,&except); + size = ( int(fd+1) > size) ? int(fd+1) : size; + } + + + void clear(Socket fd) + { + FD_CLR(fd, &read); + FD_CLR(fd, &write); + FD_CLR(fd, &except); + } + + void reset() + { + size = 0; + numReady = 0; + FD_ZERO(&read); + FD_ZERO(&write); + FD_ZERO(&except); + } + + // Make this stuff public for async dns/ares to use + fd_set read; + fd_set write; + fd_set except; + int size; + int numReady; // set after each select call +}; + + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/StlPoolAllocator.hxx b/src/libs/resiprocate/rutil/StlPoolAllocator.hxx new file mode 100644 index 00000000..26af54ed --- /dev/null +++ b/src/libs/resiprocate/rutil/StlPoolAllocator.hxx @@ -0,0 +1,207 @@ +#ifndef StlPoolAllocator_Include_Guard +#define StlPoolAllocator_Include_Guard + +#include <limits> +#include <memory> +#include <stddef.h> + +// .bwc. gcc 4.2 and above support stateful allocators. I don't know about other +// compilers; if you do, add them here please. +#if ( (__GNUC__ == 4) && (__GNUC_MINOR__ >= 2) ) || ( __GNUC__ > 4 ) +#define RESIP_HAS_STATEFUL_ALLOCATOR_SUPPORT +#endif + +#ifdef max // Max is defined under WIN32 and conflicts with std::numeric_limits<size_type>::max use below +#undef max +#endif + +namespace resip +{ +/** + A dirt-simple lightweight stl pool allocator meant for use in short-lifetime + objects. This will pool-allocate at most S bytes, after which no further pool + allocation will be performed, and fallback to the system new/delete will be + used (deallocating a pool allocated object will _not_ free up room in the + pool). +*/ +template<typename T, typename P> +class StlPoolAllocator +{ + public: + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + +#ifdef RESIP_HAS_STATEFUL_ALLOCATOR_SUPPORT + explicit StlPoolAllocator(P* pool=0) : + mPool(pool){} + StlPoolAllocator(const StlPoolAllocator& other) : + mPool(other.mPool){} + StlPoolAllocator& operator=(const StlPoolAllocator& rhs) + { + mPool=rhs.mPool; + return *this; + } +#else + // Disable pool allocation if stateful allocators are not supported by the + // STL + explicit StlPoolAllocator(P* pool=0) : + mPool(0){} + StlPoolAllocator(const StlPoolAllocator& other) : + mPool(0){} + StlPoolAllocator& operator=(const StlPoolAllocator& rhs) + { + return *this; + } +#endif + + + template<typename U> + StlPoolAllocator(const StlPoolAllocator<U,P>& other) : + mPool(other.mPool){} + + ~StlPoolAllocator(){} + + + template<typename U> + struct rebind + { + typedef StlPoolAllocator<U, P> other; + }; + + pointer address(reference ref) const + { + return &ref; + } + + const_pointer address(const_reference ref) const + { + return &ref; + } + + pointer allocate(size_type n, std::allocator<void>::const_pointer hint=0) + { + return (pointer)(allocate_raw(n*sizeof(T))); + } + + void deallocate(pointer ptr, size_type n) + { + deallocate_raw((void*)ptr); + } + + inline void* allocate_raw(size_type bytes) + { + if(mPool) + { + return mPool->allocate(bytes); + } + return ::operator new(bytes); + } + + void deallocate_raw(void* ptr) + { + if(mPool) + { + mPool->deallocate(ptr); + return; + } + ::operator delete(ptr); + } + + size_type max_size() const + { + if(mPool) + { + return mPool->max_size(); + } + return std::numeric_limits<size_type>::max()/sizeof(T); + } + + size_type max_size(size_type _sz) const + { + if(mPool) + { + return mPool->max_size(); + } + return std::numeric_limits<size_type>::max()/_sz; + } + + void construct(pointer p, const_reference orig) + { + new (p) T(orig); + } + + void destroy(pointer ptr) + { + ptr->~T(); + } + + bool operator==(const StlPoolAllocator& rhs) const + { + return mPool == rhs.mPool; + } + + bool operator!=(const StlPoolAllocator& rhs) const + { + return mPool != rhs.mPool; + } + + P* mPool; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Subsystem.cxx b/src/libs/resiprocate/rutil/Subsystem.cxx new file mode 100644 index 00000000..ff6fc3b9 --- /dev/null +++ b/src/libs/resiprocate/rutil/Subsystem.cxx @@ -0,0 +1,80 @@ +#include "rutil/Subsystem.hxx" + +using namespace resip; + +Subsystem Subsystem::APP("RESIP:APP"); +Subsystem Subsystem::CONTENTS("RESIP:CONTENTS"); +Subsystem Subsystem::DNS("RESIP:DNS"); +Subsystem Subsystem::DUM("RESIP:DUM"); +Subsystem Subsystem::PRESENCE("RESIP:PRESENCE"); +Subsystem Subsystem::SDP("RESIP:SDP"); +Subsystem Subsystem::SIP("RESIP"); // SIP Stack / Parser +Subsystem Subsystem::TEST("RESIP:TEST"); +Subsystem Subsystem::TRANSACTION("RESIP:TRANSACTION"); +Subsystem Subsystem::TRANSPORT("RESIP:TRANSPORT"); +Subsystem Subsystem::STATS("RESIP:STATS"); +Subsystem Subsystem::REPRO("REPRO:APP"); +Subsystem Subsystem::NONE("UNDEFINED"); + +const Data& Subsystem::getSubsystem() const +{ + return mSubsystem; +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const Subsystem& ss) +{ + strm << ss.mSubsystem; + return strm; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Subsystem.hxx b/src/libs/resiprocate/rutil/Subsystem.hxx new file mode 100644 index 00000000..16a776de --- /dev/null +++ b/src/libs/resiprocate/rutil/Subsystem.hxx @@ -0,0 +1,141 @@ +#if !defined(RESIP_SUBSYSTEM_HXX) +#define RESIP_SUBSYSTEM_HXX + +#include <iostream> +#include "rutil/Data.hxx" +#include "rutil/Log.hxx" + +namespace resip +{ + +/** + @brief Class used to specify what sub-system given sections of code belong + to, for use by the logging system. + + @note The logging macros defined in Logger.hxx assume that the preprocessor + macro RESIPROCATE_SUBSYSTEM is defined to an instance of this class. The + logging macro uses this object to determine what logging level should be + used, and what sub-system the logging statement should come from. So, in + your code you might do something like the following: + + @code + #define RESIPROCATE_SUBSYSTEM Subsystem::APP + //... + void doStuff() + { + DebugLog(<< "Doing some stuff..."); + } + @endcode + + This would cause your log statement to be marked as coming from + Subsystem::APP. +*/ +class Subsystem +{ + public: + // Add new systems below + static Subsystem APP; + static Subsystem CONTENTS; + static Subsystem DNS; + static Subsystem DUM; + static Subsystem NONE; // default subsystem + static Subsystem PRESENCE; + static Subsystem SDP; + static Subsystem SIP; // SIP Stack / Parser + static Subsystem TEST; + static Subsystem TRANSACTION; + static Subsystem TRANSPORT; + static Subsystem STATS; + static Subsystem REPRO; + + const Data& getSubsystem() const; + Log::Level getLevel() const { return mLevel; } + void setLevel(Log::Level level) { mLevel = level; } + protected: + explicit Subsystem(const char* rhs) : mSubsystem(rhs), mLevel(Log::None) {}; + explicit Subsystem(const Data& rhs) : mSubsystem(rhs), mLevel(Log::None) {}; + Subsystem& operator=(const Data& rhs); + + Data mSubsystem; + Log::Level mLevel; + + friend EncodeStream& operator<<(EncodeStream& strm, const Subsystem& ss); +}; + + +// in order to have subsystems in your application, subclass from this class +/* +#include "rutil/Data.hxx" +#include "rutil/Subsystem.hxx" + +namespace MyNamespace +{ + +class Subsystem : public resip::Subsystem +{ + public: + // Add new systems below + static const Subsystem SPECIAL_SUBSYSTEM; + + private: + explicit Subsystem(const char* rhs) : resip::Subsystem(rhs) {}; + explicit Subsystem(const resip::Data& rhs); + Subsystem& operator=(const resip::Data& rhs); +}; + +} +*/ + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/SysLogBuf.cxx b/src/libs/resiprocate/rutil/SysLogBuf.cxx new file mode 100644 index 00000000..4a3252d0 --- /dev/null +++ b/src/libs/resiprocate/rutil/SysLogBuf.cxx @@ -0,0 +1,100 @@ +#if !defined(WIN32) +#include <syslog.h> +#endif + +#include <cstdio> +#include <cassert> +#include "rutil/SysLogBuf.hxx" + +#ifndef EOF +# define EOF (-1) +#endif + +using resip::SysLogBuf; + +SysLogBuf::SysLogBuf () +{ +#if !defined(WIN32) + setp(buffer,buffer+Size); + openlog (0, LOG_NDELAY, LOG_LOCAL6); +#endif +} + +SysLogBuf::~SysLogBuf() +{ +} + +int +SysLogBuf::sync() +{ +#if !defined(WIN32) + *(pptr()) = 0; + syslog (LOG_LOCAL6 | LOG_DEBUG, "%s", pbase()); + setp(buffer, buffer+Size); +#else + assert(0); +#endif + return 0; +} + +int +SysLogBuf::overflow (int c) +{ + sync(); + if (c != EOF) + { + *pptr() = static_cast<unsigned char>(c); + pbump(1); + } + return c; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/SysLogBuf.hxx b/src/libs/resiprocate/rutil/SysLogBuf.hxx new file mode 100644 index 00000000..3c57921b --- /dev/null +++ b/src/libs/resiprocate/rutil/SysLogBuf.hxx @@ -0,0 +1,79 @@ +#if !defined(RESIP_SYSLOGBUF_HXX) +#define RESIP_SYSLOGBUF_HXX + +#include <iostream> + +namespace resip +{ + +class SysLogBuf : public std::streambuf +{ + public: + SysLogBuf(); + virtual ~SysLogBuf(); + + int sync (); + int overflow (int ch); + + // Defining xsputn is an optional optimization. + // (streamsize was recently added to ANSI C++, not portable yet.) + //inline streamsize xsputn (char* text, streamsize n); + + private: + enum { Size=4095 }; + char buffer[Size+1]; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/SysLogStream.cxx b/src/libs/resiprocate/rutil/SysLogStream.cxx new file mode 100644 index 00000000..126272dd --- /dev/null +++ b/src/libs/resiprocate/rutil/SysLogStream.cxx @@ -0,0 +1,69 @@ +#include "rutil/SysLogBuf.hxx" +#include "rutil/SysLogStream.hxx" + +using resip::SysLogStream; +using resip::SysLogBuf; + +// Remove warning about 'this' use in initiator list - pointer is only stored +#if defined(WIN32) && !defined(__GNUC__) +#pragma warning( disable : 4355 ) // using this in base member initializer list +#endif + +SysLogStream::SysLogStream() : + std::ostream (this) +{ +} + +SysLogStream::~SysLogStream() +{ +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/SysLogStream.hxx b/src/libs/resiprocate/rutil/SysLogStream.hxx new file mode 100644 index 00000000..4ee53f69 --- /dev/null +++ b/src/libs/resiprocate/rutil/SysLogStream.hxx @@ -0,0 +1,75 @@ +#if !defined(RESIP_SYSLOGSTREAM_HXX) +#define RESIP_SYSLOGSTREAM_HXX + +#include "rutil/SysLogBuf.hxx" + +namespace resip +{ +//class SysLogBuf; + +class SysLogStream : private SysLogBuf, public std::ostream +{ + public: + SysLogStream(); + virtual ~SysLogStream(); + + private: + //SysLogBuf* _buf; + + SysLogStream(const SysLogStream& ); + SysLogStream& operator=(const SysLogStream&); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/TODO b/src/libs/resiprocate/rutil/TODO new file mode 100644 index 00000000..8cf69ef1 --- /dev/null +++ b/src/libs/resiprocate/rutil/TODO @@ -0,0 +1,2 @@ +- reimplement CountStream at the ostream level +- remove the coders and just use stuff in string class diff --git a/src/libs/resiprocate/rutil/ThreadIf.cxx b/src/libs/resiprocate/rutil/ThreadIf.cxx new file mode 100644 index 00000000..b45f9349 --- /dev/null +++ b/src/libs/resiprocate/rutil/ThreadIf.cxx @@ -0,0 +1,381 @@ +#include "rutil/ThreadIf.hxx" + +#if defined(WIN32) +#include <stdio.h> +#include <tchar.h> +#include <time.h> +#ifdef _WIN32_WCE +typedef LPTHREAD_START_ROUTINE RESIP_THREAD_START_ROUTINE; +#else +#include <process.h> // for _beginthreadex() +typedef unsigned(__stdcall *RESIP_THREAD_START_ROUTINE)(void*); +#endif + +//from Random.cxx +#include "rutil/Socket.hxx" +#endif + +#include <cassert> +#include <iostream> +#include "rutil/ThreadIf.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/Lock.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +using namespace resip; + +#ifdef WIN32 +ThreadIf::TlsDestructorMap *ThreadIf::mTlsDestructors; +Mutex *ThreadIf::mTlsDestructorsMutex; +#endif + +extern "C" +{ +static void* +#ifdef WIN32 +#ifdef _WIN32_WCE +WINAPI +#else +__stdcall +#endif +#endif +threadIfThreadWrapper( void* threadParm ) +{ + assert( threadParm ); + ThreadIf* t = static_cast < ThreadIf* > ( threadParm ); + + assert( t ); + t->thread(); +#ifdef WIN32 + // Free data in TLS slots. + ThreadIf::tlsDestroyAll(); +#ifdef _WIN32_WCE + ExitThread( 0 ); +#else + _endthreadex(0); +#endif +#endif + return 0; +} +} + +#ifdef WIN32 +unsigned int TlsDestructorInitializer::mInstanceCounter=0; +TlsDestructorInitializer::TlsDestructorInitializer() +{ + if (mInstanceCounter++ == 0) + { + ThreadIf::mTlsDestructorsMutex = new Mutex(); + ThreadIf::mTlsDestructors = new ThreadIf::TlsDestructorMap; + } +} +TlsDestructorInitializer::~TlsDestructorInitializer() +{ + if (--mInstanceCounter == 0) + { + delete ThreadIf::mTlsDestructorsMutex; + ThreadIf::mTlsDestructors->clear(); + delete ThreadIf::mTlsDestructors; + } +} +#endif + + +ThreadIf::ThreadIf() : +#ifdef WIN32 + mThread(0), +#endif + mId(0), mShutdown(false), mShutdownMutex() +{ +} + + +ThreadIf::~ThreadIf() +{ + shutdown(); + join(); +} + +void +ThreadIf::run() +{ + assert(mId == 0); + +#if defined(WIN32) + // !kh! + // Why _beginthreadex() instead of CreateThread(): + // http://support.microsoft.com/support/kb/articles/Q104/6/41.ASP + // Example of using _beginthreadex() mixed with WaitForSingleObject() and CloseHandle(): + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__beginthread.2c_._beginthreadex.asp + + mThread = +#ifdef _WIN32_WCE + // there is no _beginthreadex() for WINCE + CreateThread +#else + (HANDLE)_beginthreadex +#endif // _WIN32_WCE + ( + NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to security attributes + 0, // DWORD dwStackSize, // initial thread stack size + RESIP_THREAD_START_ROUTINE + (threadIfThreadWrapper), // LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function + this, //LPVOID lpParameter, // argument for new thread + 0, //DWORD dwCreationFlags, // creation flags + (unsigned*)&mId// LPDWORD lpThreadId // pointer to receive thread ID + ); + assert( mThread != 0 ); +#else + // spawn the thread + if ( int retval = pthread_create( &mId, 0, threadIfThreadWrapper, this) ) + { + std::cerr << "Failed to spawn thread: " << retval << std::endl; + assert(0); + // TODO - ADD LOGING HERE + } +#endif +} + +void +ThreadIf::join() +{ + // !kh! + // perhaps assert instead of returning when join()ed already? + // programming error? + //assert(mId == 0); + + if (mId == 0) + { + return; + } + +#if defined(WIN32) + DWORD exitCode; + while (true) + { + if (GetExitCodeThread(mThread,&exitCode) != 0) + { + if (exitCode != STILL_ACTIVE) + { + break; + } + else + { + WaitForSingleObject(mThread,INFINITE); + } + } + else + { + // log something here + break; + } + } + + // !kh! + CloseHandle(mThread); + mThread=0; +#else + void* stat; + if (mId != pthread_self()) + { + int r = pthread_join( mId , &stat ); + if ( r != 0 ) + { + WarningLog( << "Internal error: pthread_join() returned " << r ); + assert(0); + // TODO + } + } + +#endif + + mId = 0; +} + +void +ThreadIf::detach() +{ +#if !defined(WIN32) + pthread_detach(mId); +#else + if(mThread) + { + CloseHandle(mThread); + mThread = 0; + } +#endif + mId = 0; +} + +ThreadIf::Id +ThreadIf::selfId() +{ +#if defined(WIN32) + return GetCurrentThreadId(); +#else + return pthread_self(); +#endif +} + +int +ThreadIf::tlsKeyCreate(TlsKey &key, TlsDestructor *destructor) +{ +#if defined(WIN32) + key = TlsAlloc(); + if (key!=TLS_OUT_OF_INDEXES) + { + Lock lock(*mTlsDestructorsMutex); + (*mTlsDestructors)[key] = destructor; + return 0; + } + else + { + return GetLastError(); + } +#else + return pthread_key_create(&key, destructor); +#endif +} + +int +ThreadIf::tlsKeyDelete(TlsKey key) +{ +#if defined(WIN32) + if (TlsFree(key)>0) + { + Lock lock(*mTlsDestructorsMutex); + mTlsDestructors->erase(key); + return 0; + } + else + { + return GetLastError(); + } +#else + return pthread_key_delete(key); +#endif +} + +int +ThreadIf::tlsSetValue(TlsKey key, const void *val) +{ +#if defined(WIN32) + return TlsSetValue(key, (LPVOID)val)>0?0:GetLastError(); +#else + return pthread_setspecific(key, val); +#endif +} + +void * +ThreadIf::tlsGetValue(TlsKey key) +{ +#if defined(WIN32) + return TlsGetValue(key); +#else + return pthread_getspecific(key); +#endif +} + + +void +ThreadIf::shutdown() +{ + Lock lock(mShutdownMutex); + if (!mShutdown) + { + mShutdown = true; + mShutdownCondition.signal(); + } +} + +bool +ThreadIf::waitForShutdown(int ms) const +{ + Lock lock(mShutdownMutex); + if(!mShutdown) + { + mShutdownCondition.wait(mShutdownMutex, ms); + } + return mShutdown; +} + +bool +ThreadIf::isShutdown() const +{ + Lock lock(mShutdownMutex); + (void)lock; + return ( mShutdown ); +} + +#ifdef WIN32 +void +ThreadIf::tlsDestroyAll() +{ + Lock lock(*mTlsDestructorsMutex); + ThreadIf::TlsDestructorMap::const_iterator i = mTlsDestructors->begin(); + while(i != mTlsDestructors->end()) + { + void *val = TlsGetValue(i->first); + if (val != NULL) + { + (*(i->second))(val); + } + i++; + } +} +#endif + +// End of File + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2008 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/ThreadIf.hxx b/src/libs/resiprocate/rutil/ThreadIf.hxx new file mode 100644 index 00000000..b6eefd2e --- /dev/null +++ b/src/libs/resiprocate/rutil/ThreadIf.hxx @@ -0,0 +1,189 @@ +#if !defined(RESIP_THREADIF_HXX) +#define RESIP_THREADIF_HXX + +#include "rutil/Socket.hxx" + +#ifdef WIN32 +# include <BaseTsd.h> +# include <winbase.h> +# include <map> +#else +# include <pthread.h> +#endif + +#include "rutil/Mutex.hxx" +#include "rutil/Condition.hxx" + +namespace resip +{ + +/** + @brief A wrapper class to create and spawn a thread. + + It is a base class. + ThreadIf::thread() is a pure virtual method . + + To use this class, derive from it and override the thread() method. + To start the thread, call the run() method. The code in thread() will + run in a separate thread. + + Call shutdown() from the constructing thread to shut down the + code. This will set the bool shutdown_ to true. The code in + thread() should react properly to shutdown_ being set, by + returning. Call join() to join the code. + + Sample: + @code + DerivedThreadIf thread; + thread.run(); + // ... do stuff ... + thread.shutdown(); + thread.join(); + @endcode +*/ +class ThreadIf +{ + public: + ThreadIf(); + virtual ~ThreadIf(); + + // runs the code in thread() . Returns immediately + virtual void run(); + + // joins to the thread running thread() + void join(); + + // guarantees resources consumed by thread are released when thread terminates + // after this join can no-longer be used + void detach(); + + // request the thread running thread() to return, by setting mShutdown + virtual void shutdown(); + + //waits for waitMs, or stops waiting and returns true if shutdown was + //called + virtual bool waitForShutdown(int ms) const; + + // returns true if the thread has been asked to shutdown or not running + bool isShutdown() const; + +#ifdef WIN32 + typedef DWORD Id; +#else + typedef pthread_t Id; +#endif + static Id selfId(); + +#ifdef WIN32 + typedef DWORD TlsKey; +#else + typedef pthread_key_t TlsKey; +#endif + typedef void TlsDestructor(void*); + + /** This function follows pthread_key_create() signature */ + static int tlsKeyCreate(TlsKey &key, TlsDestructor *destructor); + /** This function follows pthread_key_delete() signature */ + static int tlsKeyDelete(TlsKey key); + /** This function follows pthread_setspecific() signature */ + static int tlsSetValue(TlsKey key, const void *val); + /** This function follows pthread_getspecific() signature */ + static void *tlsGetValue(TlsKey key); + + + /* thread is a virtual method. Users should derive and define + thread() such that it returns when isShutdown() is true. + */ + virtual void thread() = 0; + + protected: +#ifdef WIN32 + HANDLE mThread; + typedef std::map<DWORD,TlsDestructor *> TlsDestructorMap; + public: + /// Free data in TLS slots. For internal use only! + static void tlsDestroyAll(); + protected: + /// Map of TLS destructors. We have to emulate TLS destructors under Windows. + static TlsDestructorMap *mTlsDestructors; + /// Mutex to protect access to mTlsDestructors + static Mutex *mTlsDestructorsMutex; + friend class TlsDestructorInitializer; +#endif + Id mId; + + bool mShutdown; + mutable Mutex mShutdownMutex; + mutable Condition mShutdownCondition; + + private: + // Suppress copying + ThreadIf(const ThreadIf &); + const ThreadIf & operator=(const ThreadIf &); +}; + +#ifdef WIN32 +/// Class to initialize TLS destructors array under Windows on program startup. +class TlsDestructorInitializer { +public: + TlsDestructorInitializer(); + ~TlsDestructorInitializer(); +protected: + static unsigned int mInstanceCounter; +}; +static TlsDestructorInitializer _staticTlsInit; +#endif + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Time.cxx b/src/libs/resiprocate/rutil/Time.cxx new file mode 100644 index 00000000..bb050d8f --- /dev/null +++ b/src/libs/resiprocate/rutil/Time.cxx @@ -0,0 +1,364 @@ +#include "Time.hxx" +#if defined(WIN32) +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include <windows.h> +#include <mmsystem.h> +#if (_MSC_VER >= 1400) //no atomic intrinsics on Visual Studio 2003 and below +#include <intrin.h> +#pragma intrinsic(_InterlockedCompareExchange64) +#endif +#endif +#include "rutil/Random.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Lock.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +using namespace resip; + +ResipClock::ResipClock(void) +{ +} + +ResipClock::~ResipClock(void) +{ +} + +#if defined(WIN32) && defined(_RESIP_MONOTONIC_CLOCK) +unsigned ResipClock::mMaxSystemTimeWaitMs = 60000; //set low initially, may get adjusted by actual timer chosen +#else +unsigned ResipClock::mMaxSystemTimeWaitMs = UINT_MAX; +#endif + +#ifdef WIN32 +ResipClock::WinMonoClock::PGTC64 ResipClock::WinMonoClock::mGTC64 = &ResipClock::WinMonoClock::GTCLockDuringRange::GTC64; + +ResipClock::WinMonoClock::WinMonoClock() +{ + Initialize(); +} + +void +ResipClock::WinMonoClock::Initialize(void) +{ + static Mutex mtxStart; + static volatile bool isInitialized=false; + + Lock lock(mtxStart); + + if (isInitialized) + { + return; + } + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + ResipClock::mMaxSystemTimeWaitMs = GTCInterlocked::GetMaxWaitMs(); + mGTC64 = (PGTC64)&GTCInterlocked::GTC64; + DebugLog(<< "Using GTCInterlocked::GTC64 as the monotonic clock for time functions."); +#else + ResipClock::mMaxSystemTimeWaitMs = GTCLockDuringRange::GetMaxWaitMs(); + mGTC64 = (PGTC64)&GTCLockDuringRange::GTC64; + DebugLog(<< "Using GTCLockDuringRange::GTC64 as the monotonic clock for time functions."); +#endif + + unsigned min=0,max=0,actual=0; + bool isMono = false; + + ResipClock::queryTimerInfo(min,max,actual,isMono); + + InfoLog(<< "Timer resolution: (min/max/actual/isMonotonic) = " << min << '/' << max << '/' << actual << + '/' << ((isMono)?("true"):("false"))); + + isInitialized = true; +} + +#define IS_ALIGNED(_pointer, _alignment) ((((ULONG_PTR) (_pointer)) & ((_alignment) - 1)) == 0) + +UInt64 ResipClock::WinMonoClock::GTCInterlocked::GTC64(void) +{ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) //no atomic intrinsics on Visual Studio 2003 and below + ULARGE_INTEGER timeVal; + + assert(IS_ALIGNED(&mBaseTime,8)); //if the implementation ever changes to use 64-bit atomic read/write then 64-bit alignment will be required. + + //InterlockedCompareExchange64 will issue a LOCK CMPXCHG8B to ensure atomic access to mBaseTime + //Not the most efficient wat to do a 64-bit atomic read (see fild instruction), but no intrinsic for 64-bit atomic read. + timeVal.QuadPart = _InterlockedCompareExchange64((LONGLONG volatile *)&mBaseTime,0,0); + + DWORD tickNow = ::timeGetTime(); + + if (tickNow != timeVal.LowPart) + { + //the difference in the low 32-bits and the current 32-bit timeGetTime will be the time difference from + //the base time till now. Integer arithmentic will correctly handle cases where tickNow < timeVal.LowPart (rollover). + //This diff cannot be greater than 0xFFFFFFFF, so this function must be called more frequently than once + //every 49.7 days. + + DWORD diff = tickNow - timeVal.LowPart; + + //periodically update the basetime, only really necessary at least once every 49.7 days. + if (diff > mBaseTimeUpdateInterval) + { + ULARGE_INTEGER newVal; + + newVal.QuadPart = timeVal.QuadPart + diff; //any 32-bit rollover is now part of the high 32-bits. + + //don't care if this CAS64 actually writes mBaseTime, as long as at least 1 thread updates mBaseTime. + _InterlockedCompareExchange64((LONGLONG volatile *)&mBaseTime,(LONGLONG)newVal.QuadPart,(LONGLONG)timeVal.QuadPart); + } + + timeVal.QuadPart += diff; //any 32-bit rollover is now part of the high 32-bits. + } + + return timeVal.QuadPart; +#else + assert(0); //this counter only compiles on Visual Studio 2005 + + return GTCLock::GTC64(); +#endif //#if (_MSC_VER >= 1400) //no atomic intrinsics on Visual Studio 2003 and below +} + +volatile UInt64 ResipClock::WinMonoClock::GTCInterlocked::mBaseTime = 0; + +UInt64 +ResipClock::WinMonoClock::GTCLock::GTC64(void) +{ + Lock lock(mMutex); + + DWORD tickNow = ::timeGetTime(); + + if (tickNow != mBaseTime.LowPart) + { + mBaseTime.QuadPart += (tickNow - mBaseTime.LowPart); + } + + return mBaseTime.QuadPart; +} + +ULARGE_INTEGER ResipClock::WinMonoClock::GTCLock::mBaseTime = {0,0}; +Mutex ResipClock::WinMonoClock::GTCLock::mMutex; + +UInt64 ResipClock::WinMonoClock::GTCLockDuringRange::GTC64(void) +{ + // we assume that this function is called reasonable often + // monitor wrap around only in dangerous time range: + // empiric constants + const DWORD TIMER_BEGIN_SAFE_RANGE = 0xffff; // about one minute after + const DWORD TIMER_END_SAFE_RANGE = 0xffff0000; // and before wrap around + + DWORD tick = ::timeGetTime(); + + if ( ( tick > TIMER_BEGIN_SAFE_RANGE ) && ( tick < TIMER_END_SAFE_RANGE ) ) + { + LARGE_INTEGER ret; + ret.HighPart = mWrapCounter; + ret.LowPart = tick; + return (UInt64)ret.QuadPart; + } + // most application will never be here - only long running servers + Lock lock(mWrapCounterMutex); + if (mPrevTick > tick) + { + mWrapCounter++; + } + mPrevTick = tick; + LARGE_INTEGER ret; + ret.HighPart = mWrapCounter; + ret.LowPart = tick; + return (UInt64)ret.QuadPart; +} + +UInt32 ResipClock::WinMonoClock::GTCLockDuringRange::mWrapCounter = 0; +DWORD ResipClock::WinMonoClock::GTCLockDuringRange::mPrevTick = 0; +Mutex ResipClock::WinMonoClock::GTCLockDuringRange::mWrapCounterMutex; +#endif + +UInt64 +ResipClock::getSystemTime() +{ + assert(sizeof(UInt64) == 64/8); + +#if defined(WIN32) || defined(UNDER_CE) +#ifdef _RESIP_MONOTONIC_CLOCK + static ResipClock::WinMonoClock clockInit; + return WinMonoClock::GetClock64() * 1000; +#else + FILETIME ft; + +#ifdef UNDER_CE + SYSTEMTIME st; + ::GetSystemTime(&st); + ::SystemTimeToFileTime(&st,&ft); +#else + ::GetSystemTimeAsFileTime(&ft); +#endif + + ULARGE_INTEGER li; + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + return li.QuadPart/10; + +#endif //_RESIP_MONOTONIC_CLOCK + +#else //#if defined(WIN32) || defined(UNDER_CE) + + UInt64 time=0; +#ifdef _RESIP_MONOTONIC_CLOCK + struct timespec now_monotonic; + if (clock_gettime( CLOCK_MONOTONIC, &now_monotonic ) == 0) +// if ( syscall( __NR_clock_gettime, CLOCK_MONOTONIC, &now_monotonic ) == 0 ) + { + time = now_monotonic.tv_sec; + time = time*1000000; + time += now_monotonic.tv_nsec/1000; + return time; + } +#endif + struct timeval now; + gettimeofday( &now , NULL ); + //assert( now ); + time = now.tv_sec; + time = time*1000000; + time += now.tv_usec; + return time; +#endif +} + +UInt64 +ResipClock::getForever() +{ + assert( sizeof(UInt64) == 8 ); +#if defined(WIN32) && !defined(__GNUC__) + return 18446744073709551615ui64; +#else + return 18446744073709551615ULL; +#endif +} + +UInt64 +ResipClock::getRandomFutureTimeMs( UInt64 futureMs ) +{ + UInt64 now = getTimeMs(); + + // make r a random number between 5000 and 9000 + int r = Random::getRandom()%4000; + r += 5000; + + UInt64 ret = now; + ret += (futureMs*r)/10000; + + assert( ret >= now ); + assert( ret >= now+(futureMs/2) ); + assert( ret <= now+futureMs ); + + return ret; +} + +void +ResipClock::queryTimerInfo(unsigned &min, unsigned &max, unsigned &actual, bool &isMonotonic) +{ + min = max = actual = 0; + isMonotonic = false; + +#if defined(WIN32) +#if defined(_RESIP_MONOTONIC_CLOCK) +#if !defined(NTSTATUS) +#define NTSTATUS DWORD +#endif + typedef NTSTATUS (WINAPI*PNTQTR)(PULONG,PULONG,PULONG); + + HMODULE hm = ::LoadLibrary("ntdll"); + + if (hm != NULL) + { + PNTQTR ntqtr = (PNTQTR)::GetProcAddress(hm,"NtQueryTimerResolution"); + + if (ntqtr) + { + ntqtr((PULONG)&min,(PULONG)&max,(PULONG)&actual); + min /= 10; + max /= 10; + actual /= 10; + } + + ::FreeLibrary(hm); + hm = NULL; + } + isMonotonic = true; +#else + DWORD timeAdjustment=0; + BOOL timeAdjustmentDisabled=0; + //on Vista it looks like GetSystemTime has 1ms resolution, but GetSystemTimeAdjustment still returns 15ms + //so just set the min resolution to whatever is reported, no actual resolution can be consistently found. + ::GetSystemTimeAdjustment(&timeAdjustment,(PDWORD)&min,&timeAdjustmentDisabled); + min /= 10; + isMonotonic = false; +#endif +#else //WIN32 +#ifdef __APPLE__ + //@TODO +#else + clockid_t clock = CLOCK_REALTIME; //need to test/verify CLOCK_REALTIME returns the gettimeofday resolution. +#if defined(_RESIP_MONOTONIC_CLOCK) + clock = CLOCK_MONOTONIC; + isMonotonic = true; +#endif + struct timespec res; + if (clock_getres(clock,&res) == 0) + { + actual = (res.tv_sec * 1000000) + (res.tv_nsec / 1000); + } +#endif +#endif +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ + diff --git a/src/libs/resiprocate/rutil/Time.hxx b/src/libs/resiprocate/rutil/Time.hxx new file mode 100644 index 00000000..b3dd1cbf --- /dev/null +++ b/src/libs/resiprocate/rutil/Time.hxx @@ -0,0 +1,288 @@ +#if !defined(RESIP_TIME_HXX) +#define RESIP_TIME_HXX + +#include "rutil/Mutex.hxx" +#include <limits.h> +#include <cassert> + +namespace resip +{ + +/** Clock used for timing in the Timer class and possibly other areas. Depending on the OS and compile settings this clock + may not be monotonic. Define _RESIP_MONOTONIC_CLOCK to enable monotonic timers. + The precision of this clock is available in microseconds, but the accuracy depends on other factors such as the OS and hardware. + The time values returned by this class should be considered independent of any other clock time, + including the system time (ie OS date/time,uptime,epoch,etc). + + OS Specific notes: + + <b>Windows</b> + + When _RESIP_MONOTONIC_CLOCK is defined, timeGetTime() is currently used as the underyling time source. + The default resolution/accuracy of this timer on windows is usually the same as the system time clock. + To query resolution information use ResipClock::queryTimerInfo(). timeBeginPeriod() can be used to increase + the resolution of the timer and allow for up to 1ms accuracy. This will improve the accuracy of SIP related + timers governed by resip::Timer, but also has other OS wide implications, please refer to Microsoft's + documenation on timeBeginPeriod() for more information. + + When _RESIP_MONOTONIC_CLOCK is not defined, ::GetSystemTime is used as the underlying time source. This + value can jump forward or backward (not monotonic) if the OS system time is adjusted. The default + resolution of this timer is the current system clock interrupt time and cannot be set to a higher resolution. + The resolution has been observed at approx 15ms on XP and 1ms on Vista. + + <b>POSIX</b> + + When _RESIP_MONOTONIC_CLOCK is defined, clock_gettime() is used with the CLOCK_MONOTONIC clock. + + When _RESIP_MONOTONIC_CLOCK is not defined, gettimeofday() is used as the underyling clock. + + <b>OS X</b> + + A monotonic clock is currently not implemented for OS X. There appear to be a couple of choices. + http://www.wand.net.nz/~smr26/wordpress/2009/01/19/monotonic-time-in-mac-os-x/ + http://www.meandmark.com/timing.pdf + http://developer.apple.com/qa/qa2004/qa1398.html + + + + @see resiprocate.org devlist discussion "Timers: why system time?"; + */ +class ResipClock +{ + public: + ResipClock(void); + ~ResipClock(void); + + /** Returns the current clock time in microseconds. + */ + static UInt64 getTimeMicroSec() + { + return getSystemTime(); + } + + + /** Returns the current clock time in milliseconds. + */ + static UInt64 getTimeMs() + { + return getSystemTime()/1000LL; + } + + /** Returns the current clock time in seconds. + */ + static UInt64 getTimeSecs() + { + return getSystemTime()/1000000LL; + } + + /** Returns an absolute time in ms that is between 50% and 90% of + passed in ms from now. + */ + static UInt64 getRandomFutureTimeMs( UInt64 futureMs ); + /** Infinit time in future. + */ + static UInt64 getForever(); + + /** Some monotonic clock implementations may internally only return 32-bit values that will wrap. + * @see Timer::getMaxSystemTimeWaitMs() + */ + static unsigned getMaxSystemTimeWaitMs(void) + { + return mMaxSystemTimeWaitMs; + } + + /** Gets the current clock's minimum, maximum and current/actual timer resolution and returns if the + clock is known to be monotonic. + If min, max or actual return 0 then that information is not available. + min max and actual are in units of microseconds. + */ + static void queryTimerInfo(unsigned &minRes, unsigned &maxRes, unsigned &actualRes, bool &isMonotonic); + + private: + /** Returns the current clock time in microseconds. Does not guarantee that this is related to the actual + * OS system time (eg epoch or other time). + */ + static UInt64 getSystemTime(); + + static unsigned mMaxSystemTimeWaitMs; + +#ifdef WIN32 + private: + /** Responsible for returning a 64-bit monotonic clock value for timing. Currently implemented using + * timeGetTime. Precision of this class is milliseconds, + * accuracy is dependent on the windows timer resolution. Use timeBeginPeriod() to increase the resolution. + */ + class WinMonoClock + { + public: + WinMonoClock(); + + /** Returns a monotonic clock value in milliseconds. Currently this is the system uptime as reported + * by timeGetTime. + */ + static UInt64 GetClock64(void) + { + return mGTC64(); + } + + private: + + static void Initialize(void); + /** Definition of a function that has no parameters and returns a 64-bit unsigned integer. + */ + typedef UInt64 (*PGTC64)(void); + + /** Get Tick Count wrapper for 32-bit version of ::timeGetTime that is nearly lockless and handles 32-bit wraparound. + * _InterlockedExchange64 is used, which requires the CMPXCHG8B instruction. This instruction is found + * on pentium and later intel processors and K5 and later AMD processors. + */ + class GTCInterlocked + { + public: + + static UInt64 GTC64(void); + + /** The maximum time that can elapse when using this class as the timer for resip stack processing. + @see resip::SipStack::getTimeTillNextProcessMS(). + */ + static UInt32 GetMaxWaitMs(void) + { + //Since the base time isn't updated on every call, need to ensure that it's updated once every 49.7 days. + //The base time will lag behind the current tick count, which means the lag time must be used + //to determine the max wait. + //Also need to add a cushion to this calculaton because ::timeGetTime may not be accurate to 1ms. + __int64 maxWait = (__int64)UINT_MAX - mBaseTimeUpdateInterval - mBaseTimeCushion; + if (maxWait <= 0) + { + assert(0); + const_cast<UInt32 &>(mBaseTimeUpdateInterval) = 60000; + const_cast<UInt32 &>(mBaseTimeCushion) = 120000; + return UINT_MAX - mBaseTimeUpdateInterval - mBaseTimeCushion; + } + return static_cast<UInt32>(maxWait); + } + + private: + /** Last stored time. Using InterlockedExchange (CMPXCHG8B) the alignment is not necessary, but it shouldn't hurt. + Align it on a cache line since it is rarely written and read often (to avoid false-sharing). + */ +#ifdef _MSC_VER + static _declspec(align(128)) volatile UInt64 mBaseTime; +#else + static volatile UInt64 mBaseTime; +#endif + /** Max elapsed time since last GTC64 call, in milliseconds, before writing mBaseTime. + Cannot exceed UINT_MAX - mBaseTimeCushion. + */ + static const UInt32 mBaseTimeUpdateInterval = 60000; + static const UInt32 mBaseTimeCushion = 120000; //!< large cushion to be cautious + }; + + /** Get Tick Count wrapper for 32-bit version of ::timeGetTime that minimizes locking and handles 32-bit wraparound. + * Issues a mutex lock only during a 2 minute window around the 49.7 day threshold. The lock is issued for each call to + * GTC64 during this window and durinng this window only. + * Requires SipStack::getTimeTillNextProcessMS() to not return a value greater than 2 minutes. + */ + class GTCLockDuringRange + { + public: + + static UInt64 GTC64(void); + + static UInt32 GetMaxWaitMs(void) + { + return 120000; + } + + private: + /** timeGetTime() returns DWORD - ms since system start + Therefore, the time will wrap around to zero if the system is run continuously for 49.7 days + if timer is called reasonable often we may manage wrap around by counter below + */ + static UInt32 mWrapCounter; + + /** Last obtained tick to detect the need to increment mWrapCounter + */ + static DWORD mPrevTick; + + /** we have to made it thread safe + */ + static Mutex mWrapCounterMutex; + + }; + + /** Get Tick Count wrapper for 32-bit version of ::timeGetTime that locks on a mutex on every call to GTC64() + to safely handle 32-bit wraparound. + */ + class GTCLock + { + public: + static UInt64 GTC64(void); + + private: + static ULARGE_INTEGER mBaseTime; + + /** Primary lock that is executed on each call to GTC64(). + */ + static Mutex mMutex; + }; + + static PGTC64 mGTC64; + }; +#endif +}; + + +}//namespace resip + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/TimeLimitFifo.hxx b/src/libs/resiprocate/rutil/TimeLimitFifo.hxx new file mode 100644 index 00000000..db6a9cf9 --- /dev/null +++ b/src/libs/resiprocate/rutil/TimeLimitFifo.hxx @@ -0,0 +1,453 @@ +#ifndef RESIP_TimeLimitFifo_hxx +#define RESIP_TimeLimitFifo_hxx + +#include <cassert> +#include <memory> +#include "rutil/AbstractFifo.hxx" +#include <iostream> +#if defined( WIN32 ) +#include <time.h> +#endif + +// efficiency note: use a circular buffer to avoid list node allocation + +// what happens to timers that can't be queued? + +namespace resip +{ + +/** +@brief wraps an object with a timestamp +@internal +*/ +template<typename Payload> +class Timestamped +{ + public: + Timestamped(const Payload& msg, time_t n) + : mMsg(msg), + mTime(n) + {} + + inline const Payload& getMsg() const { return mMsg;} + inline void setMsg(const Payload& pMsg) { mMsg = pMsg;} + inline const time_t& getTime() const { return mTime;} + + private: + Payload mMsg; + time_t mTime; +}; + +/** + @brief A templated, threadsafe message-queue class that enforces constraints + on time-depth. + @ingroup data_structures + @example + @code + TimeLimitFifo<Foo> tlf(5, 10); // 5 seconds or 10 count limit + // + // where Foo is defined as: + // class Foo + // { + // public: + // Foo(const Data& val) : mVal(val) {} + // Data mVal; + // }; + // + + assert(tlf.empty()); + assert(tlf.size() == 0); + assert(tlf.timeDepth() == 0); + + c = tlf.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth); + assert(c); + + // no longer empty + assert(!tlf.empty()); + assert(tlf.size() == 1); + assert(tlf.timeDepth() == 0); + + sleepMS(2000); + + // still not empty + assert(!tlf.empty()); + assert(tlf.size() == 1); + assert(tlf.timeDepth() > 1); + + if (tlf.messageAvailable()) + delete tlf.getNext(); + + // Foo* fp = tlf.getNext(); + // assert (fp->mVal == "first") + // delete fp ; + + // now its empty + assert(tlf.empty()); + assert(tlf.size() == 0); + assert(tlf.timeDepth() == 0); + @endcode +*/ +template <class Msg> +class TimeLimitFifo : public AbstractFifo< Timestamped<Msg*> > +{ + public: + typedef enum {EnforceTimeDepth, IgnoreTimeDepth, InternalElement} DepthUsage; + + /// After it runs out of the lesser of these limits it will start to refuse messages + TimeLimitFifo(unsigned int maxDurationSecs, + unsigned int maxSize); + + virtual ~TimeLimitFifo(); + + using AbstractFifo< Timestamped<Msg*> >::mFifo; + using AbstractFifo< Timestamped<Msg*> >::mMutex; + using AbstractFifo< Timestamped<Msg*> >::mCondition; + using AbstractFifo< Timestamped<Msg*> >::empty; + using AbstractFifo< Timestamped<Msg*> >::size; + using AbstractFifo< Timestamped<Msg*> >::onMessagePushed; + + /// @brief Add a message to the fifo. + /// return true iff succeeds + /// @param Msg* 'Message pointer' + /// @param DepthUsage : (Needs work...) + /// EnforceTimeDepth -- external (non ACK) requests + /// IgnoreTimeDepth -- external reponse and ACK + /// InternalElement -- internal messages (timers, application postbacks..); use reserved queue space + /// + /// +------------------------------------------------------+ + /// | | | | + /// +------------------------------------------------------+ + /// <-----enforce-------------------> + /// <---------------ignoreTimeDepth------------> + /// <--------------------- internalElement----------------> + /// + /// enforce will drop things that exceed the queue + /// ignore will go past that limit to the extent of the queue (eg. + /// internal will basically not drop anything + /// + bool add(Msg* msg, DepthUsage usage); + + /** + @brief Returns the first message available. + + @note It will wait if no messages are available. If a signal interrupts + the wait, it will retry the wait. Signals can therefore not be + caught via getNext. If you need to detect a signal, use block + prior to calling getNext. + + @return the next message in the queue + **/ + Msg* getNext(); + /** + @brief Returns the first message available within a time limit + @param ms the maximum amount of time to wait in milliseconds for a message + @note It will wait if no messages are available. If a signal interrupts + the wait, it will retry the wait. Signals can therefore not be + caught via getNext. If you need to detect a signal, use block + prior to calling getNext. + + @return the next message in the queue, or NULL if the time limit elapses + **/ + Msg* getNext(int ms); + + /** + @brief Return the time depth of the queue + @return the time delta between the youngest and oldest queue members + */ + virtual time_t timeDepth() const; + + + /** + @brief would an add called now work? + @param usage what depth policy should be used to determine if the call would work + @return true if an add called now would work + @sa DepthUsage + */ + bool wouldAccept(DepthUsage usage) const; + + /** + @brief removes all items from the FIFO + */ + void clear(); + + /** + @brief gets the depth of the FIFO + @return the depth of the FIFO + */ + virtual size_t getCountDepth() const; + /** + @brief Return the time depth of the queue + @return the time delta between the youngest and oldest queue members + @note equivalent to timeDepth() + */ + virtual time_t getTimeDepth() const; + /** + @brief returns the FIFO count depth tolerance + @return the FIFO count depth tolerance + */ + virtual size_t getCountDepthTolerance() const; + /** + @brief returns the FIFO time depth tolerance + @return the FIFO time depth tolerance + */ + virtual time_t getTimeDepthTolerance() const; + /** + @brief set the count depth tolerance of the FIFO + @todo getCountDepthTolerance returns a size_t and this takes an + unsigned int, f.setCountDepthTolerance(f.getCountDepthTolerance()) + will fail to compile on many systems [!] + @param max the new count depth tolerance of the FIFO + */ + virtual void setCountDepthTolerance(unsigned int max); + /** + @brief set the time depth tolerance of the FIFO + @param maxSec the maximum time depth tolerance + @todo examine parallelism in units [!] + */ + virtual void setTimeDepthTolerance(unsigned int maxSecs); + + private: + time_t timeDepthInternal() const; + inline bool wouldAcceptInteral(DepthUsage usage) const; + TimeLimitFifo(const TimeLimitFifo& rhs); + TimeLimitFifo& operator=(const TimeLimitFifo& rhs); + + time_t mMaxDurationSecs; + unsigned int mMaxSize; + unsigned int mUnreservedMaxSize; +}; + +template <class Msg> +TimeLimitFifo<Msg>::TimeLimitFifo(unsigned int maxDurationSecs, + unsigned int maxSize) + : AbstractFifo< Timestamped<Msg*> >(), + mMaxDurationSecs(maxDurationSecs), + mMaxSize(maxSize), + mUnreservedMaxSize((int)((maxSize*8)/10)) // !dlb! random guess +{} + +template <class Msg> +TimeLimitFifo<Msg>::~TimeLimitFifo() +{ + clear(); + assert(empty()); +} + +template <class Msg> +bool +TimeLimitFifo<Msg>::add(Msg* msg, + DepthUsage usage) +{ + Lock lock(mMutex); (void)lock; + + if (wouldAcceptInteral(usage)) + { + time_t n = time(0); + mFifo.push_back(Timestamped<Msg*>(msg, n)); + onMessagePushed(1); + mCondition.signal(); + return true; + } + else + { + return false; + } +} + +template <class Msg> +bool +TimeLimitFifo<Msg>::wouldAccept(DepthUsage usage) const +{ + Lock lock(mMutex); (void)lock; + + return wouldAcceptInteral(usage); +} + +template <class Msg> +Msg* +TimeLimitFifo<Msg>::getNext() +{ + Timestamped<Msg*> tm(AbstractFifo< Timestamped<Msg*> >::getNext()); + return tm.getMsg(); +} + +template <class Msg> +Msg* +TimeLimitFifo<Msg>::getNext(int ms) +{ + Timestamped<Msg*> tm(0,0); + if(AbstractFifo< Timestamped<Msg*> >::getNext(ms, tm)) + { + return tm.getMsg(); + } + return 0; +} + +template <class Msg> +time_t +TimeLimitFifo<Msg>::timeDepthInternal() const +{ + if(mFifo.empty()) + { + return 0; + } + + return time(0) - mFifo.front().getTime(); +} + +template <class Msg> +bool +TimeLimitFifo<Msg>::wouldAcceptInteral(DepthUsage usage) const +{ + if ((mMaxSize != 0 && + mFifo.size() >= mMaxSize)) + { + return false; + } + + if (usage == InternalElement) + { + return true; + } + + if (mUnreservedMaxSize != 0 && + mFifo.size() >= mUnreservedMaxSize) + { + return false; + } + + if (usage == IgnoreTimeDepth) + { + return true; + } + + assert(usage == EnforceTimeDepth); + + if (mFifo.size() == 0 || + mMaxDurationSecs == 0 || + timeDepthInternal() < mMaxDurationSecs) + { + return true; + } + + return false; +} + +template <class Msg> +time_t +TimeLimitFifo<Msg>::timeDepth() const +{ + Lock lock(mMutex); (void)lock; + return timeDepthInternal(); +} + +template <class Msg> +void +TimeLimitFifo<Msg>::clear() +{ + Lock lock(mMutex); (void)lock; + + while (!mFifo.empty()) + { + delete mFifo.front().getMsg(); + mFifo.pop_front(); + } +} + +template <class Msg> +size_t +TimeLimitFifo<Msg>::getCountDepth() const +{ + return size(); +} + +template <class Msg> +size_t +TimeLimitFifo<Msg>::getCountDepthTolerance() const +{ + return mUnreservedMaxSize; +} + +template <class Msg> +time_t +TimeLimitFifo<Msg>::getTimeDepth() const +{ + return timeDepth(); +} + +template <class Msg> +time_t +TimeLimitFifo<Msg>::getTimeDepthTolerance() const +{ + return mMaxDurationSecs; +} + +template <class Msg> +void +TimeLimitFifo<Msg>::setCountDepthTolerance(unsigned int maxCount) +{ + Lock lock(mMutex); (void)lock; + mUnreservedMaxSize=int(maxCount * 0.8); +} + +template <class Msg> +void +TimeLimitFifo<Msg>::setTimeDepthTolerance(unsigned int maxSecs) +{ + Lock lock(mMutex); (void)lock; + + mMaxDurationSecs=maxSecs; +} + + +} // namespace resip + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Timer.cxx b/src/libs/resiprocate/rutil/Timer.cxx new file mode 100644 index 00000000..a5d96bae --- /dev/null +++ b/src/libs/resiprocate/rutil/Timer.cxx @@ -0,0 +1,250 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rutil/Socket.hxx" + +#if defined( WIN32 ) +# include <windows.h> +# include <winbase.h> +#else +# include <sys/time.h> +# include <sys/syscall.h> +# include <unistd.h> +#endif + +#include <cassert> +#include "rutil/Time.hxx" +#include "rutil/Timer.hxx" +#include "rutil/Logger.hxx" + + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +using namespace resip; + +unsigned long +resip::Timer::T1 = 500; + +unsigned long +resip::Timer::T2 = 8 * T1; + +unsigned long +resip::Timer::T4 = 10 * T1; + +unsigned long +resip::Timer::T100 = 80; + +unsigned long +resip::Timer::TB = 64*T1; + +unsigned long +resip::Timer::TD = 32000; + +unsigned long +resip::Timer::TC = 3*60*1000; + +unsigned long +resip::Timer::TF = 64*T1; + +unsigned long +resip::Timer::TH = 64*T1; + +unsigned long +resip::Timer::TS = 32000; + +void +Timer::resetT1(unsigned long t1) +{ + T1 = t1; + T2 = 8 * T1; + T4 = 10 * T1; + TB = 64*T1; + TF = 64*T1; + TH = 64*T1; +} + +Data +Timer::toData(Type timer) +{ + switch (timer) + { + case TimerA: // doubling + return "Timer A"; + case TimerB: + return "Timer B"; + case TimerC: + return "Timer C"; + case TimerD: + return "Timer D"; + case TimerE1: + return "Timer E1"; + case TimerE2: + return "Timer E2"; + case TimerF: + return "Timer F"; + case TimerG: + return "Timer G"; + case TimerH: + return "Timer H"; + case TimerI: + return "Timer I"; + case TimerJ: + return "Timer J"; + case TimerK: + return "Timer K"; + case TimerTrying: + return "Timer Trying"; + case TimerStaleClient: + return "Timer StaleClient"; + case TimerStaleServer: + return "Timer StaleServer"; + case TimerStateless: + return "Timer Stateless"; + case TimerCleanUp: + return "Timer Cleanup"; + default: + assert(0); + } + return "Bad Bad Bad in timer"; +} + + +TransactionTimer::TransactionTimer(unsigned long ms, + Timer::Type type, + const Data& transactionId) : + mWhen(ms + Timer::getTimeMs()), + mType(type), + mTransactionId(transactionId), + mDuration(ms) +{} + +std::ostream& +TransactionTimer::encode(std::ostream& str) const +{ + UInt64 now(Timer::getTimeMs()); + str << "TransactionTimer[ when=" << mWhen << " rel="; + if (mWhen < now) + { + str << "past"; + } + else + { + str << (mWhen - now); + } + str << "]"; + return str; +} + +#ifndef RESIP_USE_STL_STREAMS +EncodeStream& +TransactionTimer::encode(EncodeStream& str) const +{ + UInt64 now(Timer::getTimeMs()); + str << "TransactionTimer[ when=" << mWhen << " rel="; + if (mWhen < now) + { + str << "past"; + } + else + { + str << (mWhen - now); + } + str << "]"; + return str; +} +#endif + +TimerWithPayload::TimerWithPayload(unsigned long ms, Message* message) : + mWhen(ms + Timer::getTimeMs()), + mMessage(message) +{ + assert(mMessage); +} + +std::ostream& +TimerWithPayload::encode(std::ostream& str) const +{ + UInt64 now(Timer::getTimeMs()); + str << "TimerWithPayload[ when=" << mWhen << " rel="; + if (mWhen < now) + { + str << "past"; + } + else + { + str << (mWhen - now); + } + str << "]"; + return str; +} + +#ifndef RESIP_USE_STL_STREAMS +EncodeStream& +TimerWithPayload::encode(EncodeStream& str) const +{ + UInt64 now(Timer::getTimeMs()); + str << "TimerWithPayload[ when=" << mWhen << " rel="; + if (mWhen < now) + { + str << "past"; + } + else + { + str << (mWhen - now); + } + str << "]"; + return str; +} +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/Timer.hxx b/src/libs/resiprocate/rutil/Timer.hxx new file mode 100644 index 00000000..d10fa8aa --- /dev/null +++ b/src/libs/resiprocate/rutil/Timer.hxx @@ -0,0 +1,325 @@ +#if !defined(RESIP_TIMER_HXX) +#define RESIP_TIMER_HXX + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rutil/Data.hxx" +#include "rutil/HeapInstanceCounter.hxx" +#include <iostream> +#include "rutil/Time.hxx" + +namespace resip +{ + +class Message; + +/** + @brief This class is used to get the current system time. + + @note Should we refactor this? It seems like the SIP-timer stuff should live + in resip/stack somewhere. +*/ +class Timer +{ + public: + RESIP_HeapCount(Timer); + typedef enum + { + TimerA, // doubling + TimerB, + TimerC, + TimerD, + TimerE1,// doubling + TimerE2,// doubling + TimerF, + TimerG, // doubling + TimerH, + TimerI, + TimerJ, + TimerK, + TimerTrying, + TimerStaleClient, + TimerStaleServer, + TimerStateless, + TimerCleanUp, + ApplicationTimer // .dlb. Fifo, so no thread issues + } Type; + + static Data toData(Type timer); + + /** @deprecated. Does not do anything at the moment. + */ + static void setupTimeOffsets() + {} + + /** Returns the current clock time in microseconds. + */ + static UInt64 getTimeMicroSec() + { + return ResipClock::getTimeMicroSec(); + } + /** Returns the current clock time in milliseconds. + */ + static UInt64 getTimeMs() + { + return ResipClock::getTimeMs(); + } + /** Returns the current clock time in seconds. + */ + static UInt64 getTimeSecs() + { + return ResipClock::getTimeSecs(); + } + /** Returns an absolute time in ms that is between 50% and 90% of + passed in ms from now. + */ + static UInt64 getRandomFutureTimeMs(UInt64 futureMs) + { + return ResipClock::getRandomFutureTimeMs(futureMs); + } + /** Infinit time in future. + */ + static UInt64 getForever() + { + return ResipClock::getForever(); + } + + /** On windows, change getSystemTime() to not use the actual clock time + returned by ::GetSystemTime(). The replacement time function on some versions of windows (< Vista, + GetTickCount()) returns a 32-bit value, so it will rollover at some point. + Any code that waits on timers should not wait longer than this value. + + @see resiprocate.org devlist discussion "Timers: why system time?"; + @see resip::SipStack::getTimeTillNextProcessMS(). + */ + static unsigned getMaxSystemTimeWaitMs(void) + { + return ResipClock::getMaxSystemTimeWaitMs(); + } + + static void resetT1(unsigned long t1); + + // These values can be changed but it is not recommended to do so after a + // stack is up and running since they are not mutexed + // These times are all in ms + static unsigned long T1; + static unsigned long T2; + static unsigned long T4; + static unsigned long T100; + + static unsigned long TB; // default 64*T1 + static unsigned long TC; + static unsigned long TF; // default 64*T1 + static unsigned long TH; // default 64*T1 + + static unsigned long TD; + static unsigned long TS; +}; + +// !bwc! There is some duplicated code between TransactionTimer and +// TimerWithPayload. Should eventually create a single template class like the +// following, and use it with Payload=Message* and Payload=TransactionTimer +// template <typename Payload> +// class Timestamped +// { +// // blah blah blah +// private: +// UInt64 mTimestamp; +// Payload mPayload; +// }; +class TransactionTimer +{ + public: + RESIP_HeapCount(TransactionTimer); + + TransactionTimer(unsigned long ms, + Timer::Type type, + const Data& transactionId); + + ~TransactionTimer(){} + + const Data& getTransactionId() const {return mTransactionId;} + Timer::Type getType() const { return mType; } + unsigned long getDuration() const { return mDuration;} + + UInt64 getWhen() const {return mWhen;} +#ifndef RESIP_USE_STL_STREAMS + EncodeStream& encode(EncodeStream& str) const; +#endif + std::ostream& encode(std::ostream& str) const; + + inline bool operator<(const TransactionTimer& rhs) const + { + return mWhen < rhs.mWhen; + } + + inline bool operator>(const TransactionTimer& rhs) const + { + return mWhen > rhs.mWhen; + } + + protected: + UInt64 mWhen; + Timer::Type mType; + Data mTransactionId; + unsigned long mDuration; // duration of time in ms + + private: + // disabled + TransactionTimer(); +}; + +class TimerWithPayload +{ + public: + RESIP_HeapCount(TimerWithPayload); + + TimerWithPayload(unsigned long ms, Message* message); + + ~TimerWithPayload(){} + + // return the message to queue, possibly null + Message* getMessage() const { return mMessage;} + + UInt64 getWhen() const {return mWhen;} +#ifndef RESIP_USE_STL_STREAMS + EncodeStream& encode(EncodeStream& str) const; +#endif + std::ostream& encode(std::ostream& str) const; + + inline bool operator<(const TimerWithPayload& rhs) const + { + return mWhen < rhs.mWhen; + } + + inline bool operator>(const TimerWithPayload& rhs) const + { + return mWhen > rhs.mWhen; + } + + protected: + UInt64 mWhen; + Message* mMessage; // message to queue on timeout + + private: + // disabled + TimerWithPayload(); +}; + + +inline std::ostream& operator<<(std::ostream& str, const TransactionTimer& t) +{ + return t.encode(str); +} + +inline std::ostream& operator<<(std::ostream& str, const TimerWithPayload& t) +{ + return t.encode(str); +} + +#ifndef RESIP_USE_STL_STREAMS +inline EncodeStream& operator<<(EncodeStream& str, const TransactionTimer& t) +{ + return t.encode(str); +} + +inline EncodeStream& operator<<(EncodeStream& str, const TimerWithPayload& t) +{ + return t.encode(str); +} +#endif + +} + +#if 0 +Timer Value Section Meaning +---------------------------------------------------------------------- +T1 500ms default Section 17.1.1.1 RTT Estimate +T2 4s Section 17.1.2.2 The maximum retransmit + interval for non-INVITE + requests and INVITE + responses +T4 5s Section 17.1.2.2 Maximum duration a + message will + remain in the network +Timer A initially T1 Section 17.1.1.2 INVITE request retransmit + interval, for UDP only +Timer B 64*T1 Section 17.1.1.2 INVITE transaction + timeout timer +Timer C > 3min Section 16.6 proxy INVITE transaction + bullet 11 timeout +Timer D > 32s for UDP Section 17.1.1.2 Wait time for response + 0s for TCP/SCTP retransmits +Timer E initially T1 Section 17.1.2.2 non-INVITE request + retransmit interval, + UDP only +Timer F 64*T1 Section 17.1.2.2 non-INVITE transaction + timeout timer +Timer G initially T1 Section 17.2.1 INVITE response + retransmit interval +Timer H 64*T1 Section 17.2.1 Wait time for + ACK receipt +Timer I T4 for UDP Section 17.2.1 Wait time for + 0s for TCP/SCTP ACK retransmits +Timer J 64*T1 for UDP Section 17.2.2 Wait time for + 0s for TCP/SCTP non-INVITE request + retransmits +Timer K T4 for UDP Section 17.1.2.2 Wait time for + 0s for TCP/SCTP response retransmits + + Table 4: Summary of timers +#endif + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/TransportType.cxx b/src/libs/resiprocate/rutil/TransportType.cxx new file mode 100644 index 00000000..5eec0c10 --- /dev/null +++ b/src/libs/resiprocate/rutil/TransportType.cxx @@ -0,0 +1,142 @@ +#include <string> +#include "rutil/TransportType.hxx" + +namespace resip +{ + +static const Data transportNames[MAX_TRANSPORT] = +{ + Data("UNKNOWN_TRANSPORT"), + Data("TLS"), + Data("TCP"), + Data("UDP"), + Data("SCTP"), + Data("DCCP"), + Data("DTLS") +}; + +static const Data transportNamesLower[MAX_TRANSPORT] = +{ + Data("UNKNOWN_TRANSPORT"), + Data("tls"), + Data("tcp"), + Data("udp"), + Data("sctp"), + Data("dccp"), + Data("dtls") +}; + +TransportType +getTransportTypeFromName(const std::string& transportName) +{ + return toTransportType(transportName.c_str()); +} + +TransportType +toTransportType(const resip::Data& transportName) +{ + for (TransportType i = UNKNOWN_TRANSPORT; i < MAX_TRANSPORT; + i = static_cast<TransportType>(i + 1)) + { + if (isEqualNoCase(transportName, transportNames[i])) + { + return i; + } + } + return UNKNOWN_TRANSPORT; +} + +std::string +getTransportNameFromType(const TransportType typeEnum) +{ + return toData(typeEnum).c_str(); +} + +std::string +getTransportNameFromTypeLower(const TransportType typeEnum) +{ + return toDataLower(typeEnum).c_str(); +} + +const resip::Data& +toData(const TransportType typeEnum) +{ + assert(typeEnum >= UNKNOWN_TRANSPORT && typeEnum < MAX_TRANSPORT); + return transportNames[typeEnum]; +} + +const resip::Data& +toDataLower(const TransportType typeEnum) +{ + assert(typeEnum >= UNKNOWN_TRANSPORT && typeEnum < MAX_TRANSPORT); + return transportNamesLower[typeEnum]; +} + +bool +isReliable(TransportType type) +{ + switch(type) + { + case TLS: + case TCP: + case SCTP: + return true; + case UDP: + case DCCP: + case DTLS: + default: + return false; + } +} + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/TransportType.hxx b/src/libs/resiprocate/rutil/TransportType.hxx new file mode 100644 index 00000000..175451bc --- /dev/null +++ b/src/libs/resiprocate/rutil/TransportType.hxx @@ -0,0 +1,117 @@ +#if !defined(RESIP_TRANSPORTTYPE_HXX) +#define RESIP_TRANSPORTTYPE_HXX + +#include <ostream> +#include <string> +#include "rutil/Data.hxx" + +namespace resip +{ + +/** + @brief An enumeration of transport protocols. +*/ +typedef enum +{ + UNKNOWN_TRANSPORT = 0, + TLS, + TCP, + UDP, + SCTP, + DCCP, + DTLS, + MAX_TRANSPORT +} TransportType; + +/** + @brief An enumeration of IP versions. +*/ +typedef enum +{ + V4, + V6 +} IpVersion; + +/** + Function which translates a transport name to its corrisponding integer enum value. + @param transportName the name of the transport e.g. "TCP" + @return the enum value for that transport +**/ +TransportType getTransportTypeFromName(const std::string & transportName); +TransportType toTransportType(const resip::Data & transportName); + +/** + Function which translates a transport enum value to its corrisponding name. + @param transportNum the enum value of the transport + @return the transport name + + @note Data version is more efficient and doesn't involve a copy +**/ +std::string getTransportNameFromType(const TransportType typeEnum); +std::string getTransportNameFromTypeLower(const TransportType typeEnum); +const resip::Data& toData(const TransportType typeEnum); +const resip::Data& toDataLower(const TransportType typeEnum); + +/// Returns true if passed in transport type is a reliable transport protocol +bool isReliable(TransportType type); + +// Indicate whether or not to run a stun server on a Transport +typedef enum +{ + StunDisabled, + StunEnabled +} StunSetting; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/WinCompat.cxx b/src/libs/resiprocate/rutil/WinCompat.cxx new file mode 100644 index 00000000..a22024a3 --- /dev/null +++ b/src/libs/resiprocate/rutil/WinCompat.cxx @@ -0,0 +1,662 @@ +#if defined(TARGET_WIN) + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <Winsock2.h> +#include <Iphlpapi.h> + +#include "rutil/GenericIPAddress.hxx" +#include "rutil/WinCompat.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +#if defined(TARGET_WIN) && defined(_MSC_VER) +FILE _iob[] = { *stdin, *stdout, *stderr }; +extern "C" FILE * __cdecl __iob_func(void) { return _iob; } +#endif + +static char* ConvertLPWSTRToLPSTR(LPWSTR lpwszStrIn) +{ + LPSTR pszOut = NULL; + if (lpwszStrIn != NULL) + { + int nInputStrLen = (int)wcslen(lpwszStrIn); + + // Double NULL Termination + int nOutputStrLen = WideCharToMultiByte (CP_ACP, 0, lpwszStrIn, nInputStrLen, NULL, 0, 0, 0) + 2; + pszOut = new char [nOutputStrLen]; + + if (pszOut) + { + memset (pszOut, 0x00, nOutputStrLen); + WideCharToMultiByte(CP_ACP, 0, lpwszStrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0); + } + } + return pszOut; +} + +using namespace resip; + +class WinCompatInstanceCleaner +{ +public: + ~WinCompatInstanceCleaner() { WinCompat::destroyInstance(); } +} winCompatInstanceCleaner; + +WinCompat::Exception::Exception(const Data& msg, const Data& file, const int line) : + BaseException(msg,file,line) +{ +} + + +WinCompat::Version +WinCompat::getVersion() +{ +#ifdef UNDER_CE +#define OSVERSIONINFOEX OSVERSIONINFO +#endif + OSVERSIONINFOEX osvi; + BOOL bOsVersionInfoEx; + + // Try calling GetVersionEx using the OSVERSIONINFOEX structure. + // If that fails, try using the OSVERSIONINFO structure. + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) ) + { + osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) + { + return WindowsUnknown; + } + } + + switch (osvi.dwPlatformId) + { + // Test for the Windows NT product family. + case VER_PLATFORM_WIN32_NT: + + // Test for the specific product family. + if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 ) + { + return WinCompat::Windows2003Server; + } + else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ) + { + return WinCompat::WindowsXP; + } + else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) + { + return WinCompat::Windows2000; + } + else if ( osvi.dwMajorVersion <= 4 ) + { + return WinCompat::WindowsNT; + } + break; + + // Test for the Windows 95 product family. + case VER_PLATFORM_WIN32_WINDOWS: + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) + { + return WinCompat::Windows95; + } + else if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) + { + if ( osvi.szCSDVersion[1] == 'A' ) + { + return WinCompat::Windows98SE; + } + else + { + return WinCompat::Windows98; + } + } + else if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) + { + return WinCompat::WindowsME; + } + break; + + default: + return WinCompat::WindowsUnknown; + } + + return WinCompat::WindowsUnknown; +} + + +WinCompat* WinCompat::mInstance = 0; + + +static Mutex WinComaptInstanceMutex; +WinCompat * +WinCompat::instance() +{ + if (!mInstance) + { + Lock lock(WinComaptInstanceMutex); + if (!mInstance) + { + mInstance = new WinCompat(); + } + } + return mInstance; +} + + +WinCompat::WinCompat() : + getBestInterfaceEx(0), + getAdaptersAddresses(0), + getAdaptersInfo(0), + loadLibraryWithIPv4Failed(false), + loadLibraryWithIPv6Failed(false), + hLib(0) +{ + + // Note: IPHLPAPI has been known to conflict with some thirdparty DLL's. + // If you don't care about Win95/98/Me as your target system - then + // you can define NO_IPHLPAPI so that you are not required to link with this + // library. (SLG) +#if !defined (NO_IPHLPAPI) + // check to see if the GetAdaptersAddresses() is in the IPHLPAPI library + HINSTANCE hLib = LoadLibrary(TEXT("iphlpapi.dll")); + if (hLib == NULL) + { + loadLibraryWithIPv6Failed = true; + loadLibraryWithIPv4Failed = true; + return; + } + + getBestInterfaceEx = (GetBestInterfaceExProc) GetProcAddress(hLib, "GetBestInterfaceEx"); + getAdaptersAddresses = (GetAdaptersAddressesProc) GetProcAddress(hLib, "GetAdaptersAddresses"); + getAdaptersInfo = (GetAdaptersInfoProc) GetProcAddress(hLib, "GetAdaptersInfo"); + getBestRoute = (GetBestRouteProc) GetProcAddress(hLib, "GetBestRoute"); + getIpAddrTable = (GetIpAddrTableProc) GetProcAddress(hLib, "GetIpAddrTable"); + if (getAdaptersAddresses == NULL || getBestInterfaceEx == NULL) + { + loadLibraryWithIPv6Failed = true; + } + if (getAdaptersInfo == NULL || getBestRoute == NULL || getIpAddrTable == NULL) + { + loadLibraryWithIPv4Failed = true; + } +#else + loadLibraryWithIPv6Failed = true; + loadLibraryWithIPv4Failed = true; +#endif + DebugLog(<< "WinCompat constructor complete!"); +} + +void WinCompat::destroyInstance() +{ + delete mInstance; + mInstance = 0; +} + +WinCompat::~WinCompat() +{ + if(hLib != NULL) + { + FreeLibrary(hLib); + } +} + + +#if !defined(NO_IPHLPAPI) +// !slg! - This function is horribly slow (upto 200ms) and can cause serious performance issues for servers. +// We should consider finding more efficient APIs, or caching some of the results. +GenericIPAddress +WinCompat::determineSourceInterfaceWithIPv6(const GenericIPAddress& destination) +{ + if (instance()->loadLibraryWithIPv6Failed) + { + throw Exception("Library iphlpapi.dll with IPv6 support not available", __FILE__,__LINE__); + } + + // Obtain the size of the structure + IP_ADAPTER_ADDRESSES *pAdapterAddresses; + DWORD dwRet, dwSize; + DWORD flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER; + unsigned short family = destination.isVersion6() ? AF_INET6 : AF_INET; + dwRet = (instance()->getAdaptersAddresses)(family, flags, NULL, NULL, &dwSize); + if (dwRet == ERROR_BUFFER_OVERFLOW) // expected error + { + // Allocate memory + pAdapterAddresses = (IP_ADAPTER_ADDRESSES *) LocalAlloc(LMEM_ZEROINIT,dwSize); + if (pAdapterAddresses == NULL) + { + throw Exception("Can't find source address for destination", __FILE__,__LINE__); + } + + // Obtain network adapter information (IPv6) + dwRet = (instance()->getAdaptersAddresses)(family, flags, NULL, pAdapterAddresses, &dwSize); + if (dwRet != ERROR_SUCCESS) + { + LocalFree(pAdapterAddresses); + throw Exception("Can't find source address for destination", __FILE__,__LINE__); + } + } + + // Check if this address is a local address - this also avoids returning + // the loopback address that can cause havoc if the registrar and user agent are on the same box + IP_ADAPTER_ADDRESSES *AI; + int i; + for (i = 0, AI = pAdapterAddresses; AI != NULL; AI = AI->Next, i++) + { + PIP_ADAPTER_UNICAST_ADDRESS defaultAdaptorAddress = 0; + for (PIP_ADAPTER_UNICAST_ADDRESS unicast = AI->FirstUnicastAddress; + unicast; unicast = unicast->Next) + { + if (unicast->Address.lpSockaddr->sa_family != family) + continue; + + // Store first address of matching family as the Adaptors default address + if(!defaultAdaptorAddress) defaultAdaptorAddress = unicast; + + if (family == AF_INET && + reinterpret_cast<const struct sockaddr_in*>(unicast->Address.lpSockaddr)->sin_addr.S_un.S_addr == + destination.v4Address.sin_addr.S_un.S_addr) + { + // Return default address for NIC. Note: We could also just return the destination, + // however returning the default address for NIC is beneficial in cases where the + // co-located registrar supports redundancy via a Virtual IP address. + GenericIPAddress ipaddress(*defaultAdaptorAddress->Address.lpSockaddr); + LocalFree(pAdapterAddresses); + return(ipaddress); + } +#ifdef USE_IPV6 + else if (family == AF_INET6 && + memcmp(&(reinterpret_cast<const struct sockaddr_in6*>(unicast->Address.lpSockaddr)->sin6_addr), + &(reinterpret_cast<const struct sockaddr_in6*>(&destination.address)->sin6_addr), + sizeof(IN6_ADDR)) == 0) + { + // explicitly cast to sockaddr_in6, to use that version of GenericIPAddress' ctor. If we don't, then compiler + // defaults to ctor for sockaddr_in (at least under Win32), which will truncate the lower-bits of the IPv6 address. + const struct sockaddr_in6* psa = reinterpret_cast<const struct sockaddr_in6*>(defaultAdaptorAddress->Address.lpSockaddr); + + // Return default address for NIC. Note: We could also just return the destination, + // however returning the default address for NIC is beneficial in cases where the + // co-located registrar supports redundancy via a Virtual IP address. + GenericIPAddress ipaddress(*psa); + LocalFree(pAdapterAddresses); + return(ipaddress); + } +#endif + } + } + + // Not a local address, get the best interface from the OS + DWORD dwBestIfIndex; + const sockaddr* saddr = &destination.address; + if ((instance()->getBestInterfaceEx)((sockaddr *)saddr, &dwBestIfIndex) != NO_ERROR) + { + LocalFree(pAdapterAddresses); + throw Exception("Can't find source address for destination", __FILE__,__LINE__); + } + + for (i = 0, AI = pAdapterAddresses; AI != NULL; AI = AI->Next, i++) + { + for (PIP_ADAPTER_UNICAST_ADDRESS unicast = AI->FirstUnicastAddress; + unicast; unicast = unicast->Next) + { + if (unicast->Address.lpSockaddr->sa_family != saddr->sa_family) + continue; + if (saddr->sa_family == AF_INET && AI->IfIndex == dwBestIfIndex) + { + GenericIPAddress ipaddress(*unicast->Address.lpSockaddr); + LocalFree(pAdapterAddresses); + return(ipaddress); + } +#ifdef USE_IPV6 + else if (saddr->sa_family == AF_INET6 && AI->Ipv6IfIndex == dwBestIfIndex) + { + // explicitly cast to sockaddr_in6, to use that version of GenericIPAddress' ctor. If we don't, then compiler + // defaults to ctor for sockaddr_in (at least under Win32), which will truncate the lower-bits of the IPv6 address. + const struct sockaddr_in6* psa = reinterpret_cast<const struct sockaddr_in6*>(unicast->Address.lpSockaddr); + GenericIPAddress ipaddress(*psa); + LocalFree(pAdapterAddresses); + return(ipaddress); + } +#endif + } + } + LocalFree(pAdapterAddresses); + throw Exception("Can't find source address for destination", __FILE__,__LINE__); + + return GenericIPAddress(); +} + + +GenericIPAddress +WinCompat::determineSourceInterfaceWithoutIPv6(const GenericIPAddress& destination) +{ + if (instance()->loadLibraryWithIPv4Failed) + { + throw Exception("Library iphlpapi.dll not available", __FILE__,__LINE__); + } + + struct sockaddr_in sourceIP; + memset(&sourceIP, 0, sizeof(sockaddr_in)); + sourceIP.sin_family = AF_INET; + + // look through the local ip address - first we want to see if the address is local, if + // not then we want to look for the Best route + PMIB_IPADDRTABLE pIpAddrTable = NULL; + ULONG addrSize = 0; + + // allocate the space + DWORD ret = instance()->getIpAddrTable(NULL, &addrSize, FALSE); + if(ERROR_INSUFFICIENT_BUFFER == ret) + { + pIpAddrTable = (PMIB_IPADDRTABLE) new char [addrSize]; + if(pIpAddrTable == 0) + { + throw Exception("Can't find source address for destination - unable to new memory", __FILE__,__LINE__); + } + } + else + { + throw Exception("Can't find source address for destination (GetIpAddrTable to get buffer space failed), ret=" + Data(ret), __FILE__,__LINE__); + } + + ret = instance()->getIpAddrTable(pIpAddrTable, &addrSize, FALSE); + if (NO_ERROR != ret) + { + delete [] (char *) pIpAddrTable; + throw Exception("Can't find source address for destination (GetIpAddrTable failed), addrSize=" + Data(addrSize) + ", ret=" + Data(ret), __FILE__,__LINE__); + } + + // Check if address is local or not + DWORD i = 0; + for(i = 0; i <pIpAddrTable->dwNumEntries; i++) + { + if(pIpAddrTable->table[i].dwAddr == + destination.v4Address.sin_addr.S_un.S_addr) + { + // Address is local - no need to find best route - this also avoids returning + // 127.0.0.1 that can cause havoc if the registrar and user agent are on the same box + // Return default address for NIC. Note: We could also just return the destination, + // however returning the default address for NIC is beneficial in cases where the + // co-located registrar supports redundancy via a Virtual IP address. + DWORD dwNicIndex = pIpAddrTable->table[i].dwIndex; + for(DWORD j = 0; j <pIpAddrTable->dwNumEntries; j++) + { + if(pIpAddrTable->table[j].dwIndex == dwNicIndex) // Default address is first address found for NIC + { + DebugLog(<< "Routing to a local address - returning default address for NIC"); + sourceIP.sin_addr.s_addr = pIpAddrTable->table[j].dwAddr; + delete [] (char *) pIpAddrTable; + return GenericIPAddress(sourceIP); + } + } + } + } + + // try to figure the best route to the destination + MIB_IPFORWARDROW bestRoute; + memset(&bestRoute, 0, sizeof(bestRoute)); + const sockaddr_in& sin = (const sockaddr_in&)destination.address; + ret = instance()->getBestRoute(sin.sin_addr.s_addr, 0, &bestRoute); + if (NO_ERROR != ret) + { + delete [] (char *) pIpAddrTable; + throw Exception("Can't find source address for destination, ret=" + Data(ret), __FILE__,__LINE__); + } + + // look through the local ip address to find one that match the best route. + enum ENICEntryPreference {ENICUnknown = 0, ENextHopNotWithinNICSubnet, ENICSubnetIsAll1s, ENICServicesNextHop}; + ENICEntryPreference eCurrSelection = ENICUnknown; + + // try to find a match + for (i=0; i<pIpAddrTable->dwNumEntries; i++) + { + MIB_IPADDRROW &entry = pIpAddrTable->table[i]; + + ULONG addr = pIpAddrTable->table[i].dwAddr; + ULONG gw = bestRoute.dwForwardNextHop; + if(entry.dwIndex == bestRoute.dwForwardIfIndex) // Note: there MAY be > 1 entry with the same index, see AddIPAddress. + { + if( (entry.dwAddr & entry.dwMask) == (bestRoute.dwForwardNextHop & entry.dwMask) ) + { + sourceIP.sin_addr.s_addr = entry.dwAddr; + eCurrSelection = ENICServicesNextHop; + break; + } + else if (entry.dwMask == 0xffffffff && eCurrSelection < ENICSubnetIsAll1s) + { + sourceIP.sin_addr.s_addr = entry.dwAddr; + eCurrSelection = ENICSubnetIsAll1s; // Lucent/Avaya VPN has Subnet Mask of 255.255.255.255. Illegal perhaps but we should use + // if cannot find one that serves next hop. + } + else if (eCurrSelection < ENextHopNotWithinNICSubnet) + { + sourceIP.sin_addr.s_addr = entry.dwAddr; + eCurrSelection = ENextHopNotWithinNICSubnet; // should use if nothing else works since bestRoute told us to use this NIC. + } + } + } + + if (eCurrSelection != ENICServicesNextHop) + { + // rarely happens but it does. We would fail before with the old code, let's see what the ip table looks like. + in_addr subnet, netMask, nextHop; + subnet.s_addr = bestRoute.dwForwardDest; + netMask.s_addr = bestRoute.dwForwardMask; + nextHop.s_addr = bestRoute.dwForwardNextHop; + // best-route + DebugLog(<< "Best Route - subnet=" <<DnsUtil::inet_ntop(subnet) + <<" net-mask=" <<DnsUtil::inet_ntop(netMask) + <<" next-hop=" <<DnsUtil::inet_ntop(nextHop) + <<" if-index=" <<bestRoute.dwForwardIfIndex ); + // ip-table + for (i=0; i<pIpAddrTable->dwNumEntries; i++) + { + MIB_IPADDRROW & entry = pIpAddrTable->table[i]; + in_addr nicIP, nicMask; + nicIP.s_addr = entry.dwAddr; + nicMask.s_addr = entry.dwMask; + DebugLog(<<"IP Table entry " <<i+1 <<'/' <<pIpAddrTable->dwNumEntries <<" if-index=" <<entry.dwIndex + <<" NIC IP=" <<DnsUtil::inet_ntop(nicIP) + <<" NIC Mask=" <<DnsUtil::inet_ntop(nicMask) ); + } + } + + delete [] (char *) pIpAddrTable; + return GenericIPAddress(sourceIP); +} +#endif // !defined(NO_IPHLPAPI) + +GenericIPAddress +WinCompat::determineSourceInterface(const GenericIPAddress& destination) +{ +// Note: IPHLPAPI has been known to conflict with some thirdparty DLL's. +// If you don't care about Win95/98/Me as your target system - then +// you can define NO_IPHLPAPI so that you are not required to link with this +// library. (SLG) + +#if !defined(NO_IPHLPAPI) + + if(destination.isVersion6()) + { + return determineSourceInterfaceWithIPv6(destination); + } + else + { + return determineSourceInterfaceWithoutIPv6(destination); + } + +#else + assert(0); +#endif + return GenericIPAddress(); +} + + +std::list<std::pair<Data,Data> > +WinCompat::getInterfaces(const Data& matching) +{ + if (instance()->loadLibraryWithIPv6Failed) + { + if (instance()->loadLibraryWithIPv4Failed) + { + throw Exception("Library iphlpapi.dll not available", __FILE__,__LINE__); + } + + // Do IPV4 only lookup - useful for Windows versions less than W2k3 and WinXp + // Note: This query does not include the Loopback Adapter + PIP_ADAPTER_INFO pAdaptersInfo=NULL; + std::list<std::pair<Data,Data> > results; + DWORD dwRet, dwSize=0; + dwRet = (instance()->getAdaptersInfo)(pAdaptersInfo, &dwSize); + if (dwRet == ERROR_BUFFER_OVERFLOW) // expected error + { + // Allocate memory + pAdaptersInfo = (PIP_ADAPTER_INFO) LocalAlloc(LMEM_ZEROINIT,dwSize); + if (pAdaptersInfo == NULL) + { + throw Exception("Can't query for adapters info - LocalAlloc error", __FILE__,__LINE__); + } + dwRet = (instance()->getAdaptersInfo)(pAdaptersInfo, &dwSize); + if (dwRet != ERROR_SUCCESS) + { + LocalFree(pAdaptersInfo); + throw Exception("Can't query for adapters info - GetAdaptersInfo", __FILE__,__LINE__); + } + else + { + IP_ADAPTER_INFO *AI; + int i; + for (i = 0, AI = pAdaptersInfo; AI != NULL; AI = AI->Next, i++) + { + //Data name(AI->AdapterName); + Data name(AI->Description); + if(matching == Data::Empty || name == matching) + { + for (const IP_ADDR_STRING *addr=&AI->IpAddressList; addr; addr = addr->Next) + { + results.push_back(std::make_pair(name, Data(addr->IpAddress.String))); + } + } + } + LocalFree(pAdaptersInfo); + } + } + return results; + } + + // Use IPV6 compatible query + // Note: This query includes the Loopback Adapter + // Obtain the size of the structure + IP_ADAPTER_ADDRESSES *pAdapterAddresses; + std::list<std::pair<Data,Data> > results; + DWORD dwRet, dwSize=0; + DWORD flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER; + dwRet = (instance()->getAdaptersAddresses)(AF_UNSPEC, flags, NULL, NULL, &dwSize); + if (dwRet == ERROR_BUFFER_OVERFLOW) // expected error + { + // Allocate memory + pAdapterAddresses = (IP_ADAPTER_ADDRESSES *) LocalAlloc(LMEM_ZEROINIT,dwSize); + if (pAdapterAddresses == NULL) + { + throw Exception("Can't query for adapter addresses - LocalAlloc error", __FILE__,__LINE__); + } + + // Obtain network adapter information (IPv6) + dwRet = (instance()->getAdaptersAddresses)(AF_UNSPEC, flags, NULL, pAdapterAddresses, &dwSize); + if (dwRet != ERROR_SUCCESS) + { + LocalFree(pAdapterAddresses); + throw Exception("Can't query for adapter addresses - GetAdapterAddresses", __FILE__,__LINE__); + } + else + { + IP_ADAPTER_ADDRESSES *AI; + int i; + for (i = 0, AI = pAdapterAddresses; AI != NULL; AI = AI->Next, i++) + { + if (AI->FirstUnicastAddress != NULL) + { + LPSTR pszSimpleCharStringFromLPWSTR = ConvertLPWSTRToLPSTR(AI->FriendlyName); + Data name(pszSimpleCharStringFromLPWSTR); + delete [] pszSimpleCharStringFromLPWSTR; + + if(matching == Data::Empty || name == matching) + { + for (PIP_ADAPTER_UNICAST_ADDRESS unicast = AI->FirstUnicastAddress; + unicast; unicast = unicast->Next) + { +#ifndef USE_IPV6 + // otherwise we would get 0.0.0.0 for AF_INET6 addresses + if (unicast->Address.lpSockaddr->sa_family != AF_INET) continue; +#endif + results.push_back(std::make_pair(name, DnsUtil::inet_ntop(*unicast->Address.lpSockaddr))); + } + } + } + } + LocalFree(pAdapterAddresses); + } + } + return results; +} + + +#endif // of TARGET_WIN +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/WinCompat.hxx b/src/libs/resiprocate/rutil/WinCompat.hxx new file mode 100644 index 00000000..3c10107a --- /dev/null +++ b/src/libs/resiprocate/rutil/WinCompat.hxx @@ -0,0 +1,79 @@ +#if !defined(resip_WinCompat_hxx) +#define resip_WinCompat_hxx + +#if defined(WIN32) +#include <Iphlpapi.h> +#include <list> + +#include "rutil/BaseException.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/GenericIPAddress.hxx" + +namespace resip +{ + +/** + @brief Class for handling compatibility across the multiple versions of + Windows. +*/ +class WinCompat +{ + public: + //typedef enum Version + // above is not valid C++ syntax + enum Version + { + NotWindows, + Windows95, + Windows98, + Windows98SE, + WindowsME, + WindowsNT, + Windows2000, + WindowsXP, + Windows2003Server, + WindowsUnknown + }; + + static Version getVersion(); + + class Exception : public BaseException + { + public: + Exception(const Data& msg, const Data& file, const int line); + const char* name() const { return "TransportException"; } + }; + + static GenericIPAddress determineSourceInterface(const GenericIPAddress& destination); + static std::list<std::pair<Data,Data> > getInterfaces(const Data& matching); + static void destroyInstance(); + + private: + static WinCompat* instance(); + static WinCompat* mInstance; + + static GenericIPAddress determineSourceInterfaceWithIPv6(const GenericIPAddress& destination); + static GenericIPAddress determineSourceInterfaceWithoutIPv6(const GenericIPAddress& destination); + typedef DWORD (WINAPI * GetBestInterfaceExProc)(const sockaddr *, DWORD *); + typedef DWORD (WINAPI * GetAdaptersAddressesProc)(ULONG, DWORD, VOID *, IP_ADAPTER_ADDRESSES *, ULONG *); + typedef DWORD (WINAPI * GetAdaptersInfoProc)(PIP_ADAPTER_INFO, PULONG); + typedef DWORD (WINAPI * GetBestRouteProc)(DWORD dwDestAddr, DWORD dwSourceAddr, PMIB_IPFORWARDROW pBestRoute); + typedef DWORD (WINAPI * GetIpAddrTableProc)(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL bOrder); + + WinCompat(); + ~WinCompat(); + + GetBestInterfaceExProc getBestInterfaceEx; + GetAdaptersAddressesProc getAdaptersAddresses; + GetAdaptersInfoProc getAdaptersInfo; + GetBestRouteProc getBestRoute; + GetIpAddrTableProc getIpAddrTable; + bool loadLibraryWithIPv4Failed; + bool loadLibraryWithIPv6Failed; + HMODULE hLib; +}; + +} + +#endif // WIN32 +#endif diff --git a/src/libs/resiprocate/rutil/WinLeakCheck.hxx b/src/libs/resiprocate/rutil/WinLeakCheck.hxx new file mode 100644 index 00000000..120bd824 --- /dev/null +++ b/src/libs/resiprocate/rutil/WinLeakCheck.hxx @@ -0,0 +1,91 @@ +#if !defined(RESIP_WINLEAKCHECK_HXX) +#define RESIP_WINLEAKCHECK_HXX + +// Used for tracking down memory leaks in Visual Studio +#if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK) +#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> +#define new new( _NORMAL_BLOCK, __FILE__, __LINE__) + +namespace resip +{ +/** + * Creating a single instance of this class at start up will cause + * memory leak information to be dumped to the debug window when + * the program terminates. + */ +class FindMemoryLeaks +{ + _CrtMemState m_checkpoint; +public: + FindMemoryLeaks() + { + _CrtMemCheckpoint(&m_checkpoint); + }; + ~FindMemoryLeaks() + { + _CrtMemState checkpoint; + _CrtMemCheckpoint(&checkpoint); + _CrtMemState diff; + _CrtMemDifference(&diff, &m_checkpoint, &checkpoint); + _CrtMemDumpStatistics(&diff); + _CrtMemDumpAllObjectsSince(&m_checkpoint); + }; +}; + +} // end namespace + +#endif + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/XMLCursor.cxx b/src/libs/resiprocate/rutil/XMLCursor.cxx new file mode 100644 index 00000000..bd8769fa --- /dev/null +++ b/src/libs/resiprocate/rutil/XMLCursor.cxx @@ -0,0 +1,688 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "rutil/XMLCursor.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::CONTENTS + +/** +Whitespace handling: +Are the following XML fragments equivalent? + +Strictly interpreted, the root of the first XML document has one +child while the root of the second XML doucment has three children. +The line breaks and spaces after the <root> and before </root> are +tagless children. + +---> + <root><child>child content</child></root> +<-- + vs. +---> + <root> + <child>child content</child> + </root> +<-- + +Treating whitespace as children is consistent with the spec but not usually +convenient. <!ATTLIST poem xml:space (default|preserve) 'preserve'> is used to +control whitespace handling. Supporting this switch is painful. For now, treat +whitespace as non-significant. +*/ + +static char BANG[] = "!"; +static char HYPHEN[] = "-"; +static char LA_QUOTE[] = "<"; +static char RA_QUOTE[] = ">"; +static char SLASH[] = "/"; +static char EQUALS[] = "="; +static char DOUBLE_QUOTE[] = "\""; +static char SINGLE_QUOTE[] = "\'"; +//http://www.w3.org/TR/1998/REC-xml-19980210 +static const Data COMMENT_START("<!--"); +static const Data COMMENT_END("-->"); +static const Data QUESTION_RA_QUOTE("?>"); + +// An alternative to stripping comments out in preparse +// is to deal with them in the parse; ignore when after non-leaf element +// put a leaf after a comment after a leaf in the first leaf's children +// getValue() needs to copy first leaf and all 'child' leaves to mValue +// +// has the advantage of allowing +// 1. lazier parsing +// 2. embedded weirdnesses like <! > and <? > +XMLCursor::XMLCursor(const ParseBuffer& pb) + : mRoot(0), + mCursor(0), + mAttributesSet(false) +{ + ParseBuffer lPb(pb); + + skipProlog(lPb); + const char* start = lPb.position(); + + lPb.skipToChars(COMMENT_START); + if (!lPb.eof()) + { + StackLog(<< "removing comments"); + lPb.reset(start); + mData.reserve(lPb.end() - lPb.start()); + + const char* anchor = start; + { + DataStream str(mData); + Data temp; + while (true) + { + lPb.skipToChars(COMMENT_START); + if (!lPb.eof()) + { + lPb.data(temp, anchor); + str << temp; + anchor = Node::skipComments(lPb); + } + else + { + lPb.data(temp, anchor); + str << temp; + break; + } + } + } + mRoot = new Node(ParseBuffer(mData.data(), mData.size())); + } + else + { + mRoot = new Node(ParseBuffer(start, pb.end() - start)); + } + mCursor = mRoot; + + if (mRoot->extractTag()) + { + InfoLog(<< "XML: empty element no a legal root"); + mRoot->mPb.fail(__FILE__, __LINE__); + } + + mTag = mRoot->mTag; + decodeName(mRoot->mTag); + + // check for # & and note -- make decode, decodeName do stuff if set + + //<top></top> // no children + ParseBuffer pbtemp(mRoot->mPb); + pbtemp.skipToChar(RA_QUOTE[0]); + pbtemp.skipChar(); + if (!WhitespaceSignificant) + { + pbtemp.skipWhitespace(); + } + //if (!pbtemp.eof()) + { + if (*pbtemp.position() == LA_QUOTE[0] && + *(pbtemp.position()+1) == SLASH[0]) + { + pbtemp.skipChar(); + pbtemp.skipChar(); + if (strncmp(mRoot->mTag.data(), pbtemp.position(), mRoot->mTag.size()) == 0) + { + // no children ever + mRoot->mPb.reset(mRoot->mPb.end()); + return; + } + } + } +} + +XMLCursor::~XMLCursor() +{ + delete mRoot; +} + +void +XMLCursor::skipProlog(ParseBuffer& pb) +{ + //'<?xml' VersionInfo '<xml?' EncodingDecl '?>'? '<?xml' SDDecl '?>'? S? '?> + + // !dlb! much more complicated than this.. can contain comments + const char* start = pb.position(); + pb.skipToChars(QUESTION_RA_QUOTE); + if(pb.eof()) + { + // No Prolog + pb.reset(start); + return; + } + pb.skipN(2); + pb.skipWhitespace(); +} + +void +XMLCursor::decode(Data& text) +{ +} + +void +XMLCursor::decodeName(Data& name) +{ +} + +void +XMLCursor::parseNextRootChild() +{ + // no next child to parse? + if (mRoot->mPb.eof()) + { + return; + } + + // next child already parsed? + if (mRoot->mNext != mRoot->mChildren.end()) + { + return; + } + + // skip self tag + if (mRoot->mPb.position() == mRoot->mPb.start()) + { + mRoot->mPb.skipToChar(RA_QUOTE[0]); + mRoot->mPb.skipChar(); + } + + if (!WhitespaceSignificant) + { + mRoot->mPb.skipWhitespace(); + } + + // root end tag? + if (*mRoot->mPb.position() == LA_QUOTE[0]) + { + ParseBuffer pb(mRoot->mPb.position(), + mRoot->mPb.end() - mRoot->mPb.position()); + pb.skipChar(); + if (!pb.eof() && *pb.position() == SLASH[0]) + { + pb.skipChar(); + // CodeWarrior isn't helpful enough to pick the "obvious" operator definition + // so we add volatile here so CW is completely unconfused what to do. + // second note - MSVC 7.0 won't compile the volatile - tried the following to fix + const char* end = pb.position(); + if ( (const char*)pb.end() < end + mTag.size() ) + { + InfoLog(<< "XML: unexpected end"); + pb.fail(__FILE__, __LINE__); + } + + if (strncmp(mTag.data(), pb.position(), mRoot->mTag.size()) == 0) + { + mRoot->mPb.skipToEnd(); + return; + } + } + } + + // leaf? + if (*mRoot->mPb.position() != LA_QUOTE[0]) + { + const char* anchor = mRoot->mPb.position(); + mRoot->mPb.skipToChar(LA_QUOTE[0]); + Node* leaf = new Node(ParseBuffer(anchor, mRoot->mPb.position() - anchor)); + leaf->mIsLeaf = true; + mRoot->addChild(leaf); + } + else + { + Node* child = new Node(mRoot->mPb); + child->skipToEndTag(); + + // leave the parse buffer after the child + mRoot->mPb.reset(child->mPb.end()); + + mRoot->addChild(child); + } + + // mNext always points at cursored child + mRoot->mNext = mRoot->mChildren.end(); + mRoot->mNext--; +} + +bool +XMLCursor::nextSibling() +{ + if (atRoot()) + { + StackLog(<< "XMLCursor::nextSibling" << *this->mCursor << " <<root>>"); + return false; + } + + StackLog(<< "XMLCursor::nextSibling" << *this->mCursor << " " << *this->mCursor->mParent); + if (mCursor->mParent == mRoot) + { + parseNextRootChild(); + } + + if (mCursor->mParent->mNext != mCursor->mParent->mChildren.end()) + { + mCursor = *((mCursor->mParent->mNext)++); + mAttributesSet = false; + return true; + } + else + { + return false; + } +} + +bool +XMLCursor::firstChild() +{ + if (atRoot() && + mRoot->mChildren.empty()) + { + parseNextRootChild(); + } + + if (mCursor->mChildren.empty()) + { + return false; + } + else + { + // mNext always points after cursored child + mCursor->mNext = mCursor->mChildren.begin(); + mCursor->mNext++; + mCursor = mCursor->mChildren.front(); + mAttributesSet = false; + return true; + } +} + +bool +XMLCursor::parent() +{ + if (atRoot()) + { + return false; + } + + mCursor = mCursor->mParent; + mAttributesSet = false; + return true; +} + +void +XMLCursor::reset() +{ + mCursor = mRoot; + mAttributesSet = false; +} + +bool +XMLCursor::atRoot() const +{ + return mCursor == mRoot; +} + +bool +XMLCursor::atLeaf() const +{ + return mCursor->mIsLeaf; +} + +const Data& +XMLCursor::getTag() const +{ + return mCursor->mTag; +} + +//<foo > +//<foo> +//<foo/> +//<foo attr = 'value' attr="value"> +//<foo attr = 'value' attr="value" > +// +//<foo attr = 'value' attr="value" /> +static const Data RA_QUOTE_SLASH(">/"); +const XMLCursor::AttributeMap& +XMLCursor::getAttributes() const +{ + if (!atLeaf() && + !mAttributesSet) + { + mAttributes.clear(); + mAttributesSet = true; + + ParseBuffer pb(mCursor->mPb); + pb.reset(mCursor->mPb.start()); + + Data attribute; + Data value; + + pb.skipToOneOf(ParseBuffer::Whitespace, RA_QUOTE_SLASH); + + while (!pb.eof() && + *pb.position() != RA_QUOTE[0] && + *pb.position() != SLASH[0]) + { + attribute.clear(); + value.clear(); + + const char* anchor = pb.skipWhitespace(); + pb.skipToOneOf(ParseBuffer::Whitespace, EQUALS); + pb.data(attribute, anchor); + XMLCursor::decodeName(attribute); + + StackLog(<< "attribute: " << attribute); + + pb.skipWhitespace(); + pb.skipToChar(EQUALS[0]); + pb.skipChar(); + pb.skipWhitespace(); + if (!pb.eof()) + { + const char quote = *pb.position(); + + StackLog(<< "quote is <" << quote << ">"); + + if(quote != DOUBLE_QUOTE[0] && + quote != SINGLE_QUOTE[0]) + { + InfoLog(<< "XML: badly quoted attribute value"); + pb.fail(__FILE__, __LINE__); + } + anchor = pb.skipChar(); + pb.skipToChar(quote); + pb.data(value, anchor); + XMLCursor::decode(value); + pb.skipChar(); + mAttributes[attribute] = value; + } + pb.skipWhitespace(); + } + } + + return mAttributes; +} + +const Data& +XMLCursor::getValue() const +{ + if (atLeaf()) + { + ParseBuffer pb(mCursor->mPb); + pb.skipToEnd(); + mValue = pb.data(pb.start()); + XMLCursor::decode(mValue); + } + else + { + mValue.clear(); + } + return mValue; +} + +EncodeStream& +XMLCursor::encode(EncodeStream& str, const AttributeMap& attrs) +{ + for(AttributeMap::const_iterator i = attrs.begin(); + i != attrs.end(); ++i) + { + if (i != attrs.begin()) + { + str << " "; + } + // !dlb! some sort of character encoding required here + str << i->first << "=\"" << i->second << "\""; + } + + return str; +} + +XMLCursor::Node::Node(const ParseBuffer& pb) + : mPb(pb.position(), pb.end() - pb.position()), + mParent(0), + mChildren(), + mNext(mChildren.begin()), + mIsLeaf(false) +{ + mPb.assertNotEof(); + StackLog(<< "XMLCursor::Node::Node" << *this); +} + +XMLCursor::Node::~Node() +{ + for (vector<Node*>::iterator i = mChildren.begin(); + i != mChildren.end(); ++i) + { + delete *i; + } +} + +// start: +//<foo > +//^ +// end: +//<foo > +// ^ +static Data SLASH_RA_QUOTE("/>"); +bool +XMLCursor::Node::extractTag() +{ + ParseBuffer pb(mPb); + const char* anchor = pb.skipChar(); + pb.skipToOneOf(ParseBuffer::Whitespace, SLASH_RA_QUOTE); + pb.assertNotEof(); + pb.data(mTag, anchor); + + return !pb.eof() && *pb.position() == SLASH[0]; +} + +void +XMLCursor::Node::addChild(Node* child) +{ + mChildren.push_back(child); + child->mParent = this; +} + +//<foo> <bar> </bar> <baz> </baz> </foo> +//^start +// ^child +// ^child +// ^end +// +//<foo> sdfsf sadfsf <bar> asdfdf </bar> sadfsdf </foo> +//^start +// ^child +// ^child sub +// ^child +void +XMLCursor::Node::skipToEndTag() +{ + extractTag(); + StackLog(<< "XMLCursor::Node::skipToEndTag(" << mTag << ")"); + //StackLog(<< "XMLCursor::Node::skipToEndTag(" << Data(mPb.position(), mPb.end() - mPb.position()) << ")"); + + //<foo /> + mPb.skipToChar(RA_QUOTE[0]); + if (*(mPb.position()-1) == SLASH[0]) + { + mPb.skipChar(); + mPb = ParseBuffer(mPb.start(), mPb.position() - mPb.start()); + return; + } + + //<foo> ...<child> ... </child> </foo> + // ^ + mPb.skipChar(); + //<foo> ...<child> ... </child> </foo> + // ^ + while (true) + { + if (!WhitespaceSignificant) + { + mPb.skipWhitespace(); + } + + // Some text contents ...< + // ^ ^ + if (*mPb.position() != LA_QUOTE[0]) + { + const char* anchor = mPb.position(); + mPb.skipToChar(LA_QUOTE[0]); + Node* leaf = new Node(ParseBuffer(anchor, mPb.position() - anchor)); + leaf->mIsLeaf = true; + addChild(leaf); + } + + //<... + //^ + mPb.skipChar(); + //<... + // ^ + + // exit condition + //</foo> + if (*mPb.position() == SLASH[0]) + { + mPb.skipChar(); + // CodeWarrior isn't helpful enough to pick the "obvious" operator definition + // so we add volatile here so CW is completely unconfused what to do. + // second note - MSVC 7.0 won't compile the volatile - tried the following to fix + const char* end = mPb.position(); + if ( (const char*)mPb.end() < end + mTag.size() ) + { + InfoLog(<< "XML: unexpected end"); + mPb.fail(__FILE__, __LINE__); + } + + if (strncmp(mTag.data(), mPb.position(), mTag.size()) == 0) + { + mPb.skipToChar(RA_QUOTE[0]); + mPb.skipChar(); + mPb = ParseBuffer(mPb.start(), mPb.position() - mPb.start()); + return; + } + else + { + InfoLog(<< "Badly formed XML: unexpected endtag"); + mPb.fail(__FILE__, __LINE__); + } + } + + //<child>... + // ^ + if (mPb.position() == mPb.start()) + { + InfoLog(<< "XML: badly formed element"); + mPb.fail(__FILE__, __LINE__); + } + + mPb.reset(mPb.position()-1); + //<child>... + //^ + Node* child = new Node(mPb); + addChild(child); + child->skipToEndTag(); + mPb.reset(child->mPb.end()); + XMLCursor::decodeName(child->mTag); + StackLog(<< mTag << "(" << child->mTag << ")"); + } +} + +//<!-- declarations for <head> & <body> --> +const char* +XMLCursor::Node::skipComments(ParseBuffer& pb) +{ + while (*pb.position() == LA_QUOTE[0] && + *(pb.position()+1) == BANG[0] && + *(pb.position()+2) == HYPHEN[0] && + *(pb.position()+3) == HYPHEN[0]) + { + pb.skipToChars(COMMENT_END); + pb.skipChars(COMMENT_END); + pb.skipWhitespace(); + if(pb.eof()) + { + return pb.end(); + } + } + + return pb.position(); +} + +EncodeStream& +resip::operator<<(EncodeStream& str, const XMLCursor::Node& node) +{ + Data::size_type size = node.mPb.end() - node.mPb.start(); + + static const Data::size_type showSize(35); + + str << &node << "[" + << Data(node.mPb.start(), + min(showSize, size)) + << "]" << (size ? "" : "..."); + + return str; +} + +EncodeStream& +resip::operator<<(EncodeStream& str, const XMLCursor& cursor) +{ + str << "XMLCursor " << *cursor.mCursor; + return str; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/XMLCursor.hxx b/src/libs/resiprocate/rutil/XMLCursor.hxx new file mode 100644 index 00000000..691bfdfe --- /dev/null +++ b/src/libs/resiprocate/rutil/XMLCursor.hxx @@ -0,0 +1,250 @@ +#if !defined(RESIP_XMLCURSOR_HXX) +#define RESIP_XMLCURSOR_HXX + +#include <iosfwd> +#include <vector> + +#include "rutil/ParseBuffer.hxx" +#include "rutil/HashMap.hxx" + +namespace resip +{ + +/* +// XML tree traversal. +// XMLCursor starts at the root. +// The attributes and value of the cursor are those of the root. +// To descend to the first child of the root, call firstChild(). +// To traverse the children of root from root, call firstChild();nextSibling();nextSibling();... +// To descend into the first child of the current element, call firstChild. +// To return to the parent of the current element, call parent. +// The traversal state among the siblings of the parent is maintained. +// +// root +// / \ +// P1 P2 +// / \ / \ +// A1 A2 B1 B2 +// +// atRoot() == true; +// firstChild(); // P1 +// firstChild(); // A1 +// nextSibling(); // A2 +// parent(); // P1 +// nextSibling(); // P2 +// firstChild(); // B1 +// nextSibling(); // B2 +// parent(); // P2 +// nextSibling(); // false, stay at P2 +// parent(); // root +// nextSibling(); // false, stay at root +// parent(); // false, stay at root +// firstChild(); // P1 + +// E.g.: Depth first traversal +// +// void traverse(XMLCursor& c) +// { +// if (c.firstChild()) +// { +// traverse(c); +// c.parent(); +// } +// +// process(c); +// +// if (c.nextSibling()) +// { +// traverse(c); +// } +// } +// +// E.g.: Lexical Order traversal +// +// void +// traverse(XMLCursor& c, int i = 0) +// { +// for (int ii = 0; ii < i; ++ii) +// { +// cerr << " "; +// } + +// cerr << c.getTag(); +// if (c.atLeaf()) +// { +// cerr << "[" << c.getValue() << "]" << endl; +// } +// else +// { +// cerr << endl; +// } + +// if (c.firstChild()) +// { +// traverse(c, i+2); +// c.parent(); +// } + +// if (c.nextSibling()) +// { +// traverse(c, i+2); +// } +// } + +*/ + +class XMLCursor +{ + public: + // !dlb! should be determined by the document + // see http://www.w3.org/TR/1998/REC-xml-19980210#sec-white-space + enum {WhitespaceSignificant = false}; + + XMLCursor(const ParseBuffer& pb); + ~XMLCursor(); + + bool nextSibling(); + bool firstChild(); + bool parent(); + void reset(); + + bool atRoot() const; + bool atLeaf() const; + + const Data& getTag() const; + typedef HashMap<Data, Data> AttributeMap; + const AttributeMap& getAttributes() const; + const Data& getValue() const; + + static EncodeStream& encode(EncodeStream& strm, const AttributeMap& attrs); + class Node; + + class AttributeValueEqual { + Data data_; + public: + AttributeValueEqual(const Data& data) : data_(data) {}; + bool operator()(const std::pair<const Data, Data>& data) { return data.second == data_; } + }; + + private: + static void skipProlog(ParseBuffer& pb); + static void decode(Data&); + static void decodeName(Data&); + + void parseNextRootChild(); + + + Node* mRoot; + Node* mCursor; + + //bool isEmpty; + + // store for undecoded root tag + Data mTag; + + // store for copy of input if commented + Data mData; + + // store date for decoding + mutable Data mValue; + // store attributes for reference + mutable AttributeMap mAttributes; + mutable bool mAttributesSet; + +public: + class Node + { + public: + Node(const ParseBuffer& pb); + ~Node(); + + void addChild(Node*); + // return true if <foo/> + bool extractTag(); + void skipToEndTag(); + static const char* skipComments(ParseBuffer& pb); + + ParseBuffer mPb; + Node* mParent; + std::vector<Node*> mChildren; + std::vector<Node*>::const_iterator mNext; + + bool mIsLeaf; + Data mTag; + + private: + Node(const Node&); + Node& operator=(const Node&); + + friend EncodeStream& operator<<(EncodeStream& str, const XMLCursor& cursor); + // friend EncodeStream& operator<<(EncodeStream& str, const XMLCursor::Node& cursor); // this line won't compile in windows + }; + private: + friend EncodeStream& operator<<(EncodeStream&, const XMLCursor&); + friend EncodeStream& operator<<(EncodeStream&, const XMLCursor::Node&); + + // no value semantics + XMLCursor(const XMLCursor&); + XMLCursor& operator=(const XMLCursor&); + friend class Node; +}; + +EncodeStream& +operator<<(EncodeStream& str, const XMLCursor& cursor); + +EncodeStream& +operator<<(EncodeStream& str, const XMLCursor::Node& cursor); + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/cajun/Readme.txt b/src/libs/resiprocate/rutil/cajun/Readme.txt new file mode 100644 index 00000000..41ed4c59 --- /dev/null +++ b/src/libs/resiprocate/rutil/cajun/Readme.txt @@ -0,0 +1,14 @@ +CAJUN* is a C++ API for the JSON object interchange format. JSON is like XML, except it doesn't suck**. It is specifically designed for representing (in plain text format) structures familiar to software engineers: booleans, numerics, strings, arrays, and objects (i.e. name/value pairs, associative array, etc.); it humbly leaves text markup to XML. It is ideal for storing persistent application data, such as configuration or user data files. + +Too many JSON parsers I've seen suffer from overly complex designs and confusing interfaces, so in true software engineer form, I thought I could do better. The goal of JSON was to create an simple, "minimalist" interface while sacrificing absolutely no power or flexibility. The STL containers, while not without their violations of that spirit, served as an inspiration. The end result is (IMHO) an interface that should be immediately intuitive to anyone familiar with C++ and the Standard Library containers. It can best be described as working with an "element", where an element may consist of: +* String (mimics std::string) +* Numeric (double) +* Boolean (bool) +* Array (std::vector<UnknownElement>) +* Object (unsorted std::map<std::string, UnknownElement>) +* UnknownElement - like boost::any, but restricted to types below. Used to aggregate elements within Objects & Arrays, and for reading documents of unknown structure + +As with any design, sacrifices were made with CAJUN. Most situations I've encountered where JSON is well-suited (reading & writing application configuration and data files) are not typically performance bottlenecks, so simplicity, safety & flexibility were favored over raw speed. The end result is a library with simple, typesafe classes, no memory-management burden on the user, and exception-based error reporting. + +* C++ API for JSON. A pint on me for who ever comes up with a good meaning for "UN". +** To be fair, XML doesn't suck intentionally, it is just often used inappropriately. \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/cajun/ReleaseNotes.txt b/src/libs/resiprocate/rutil/cajun/ReleaseNotes.txt new file mode 100644 index 00000000..c2529065 --- /dev/null +++ b/src/libs/resiprocate/rutil/cajun/ReleaseNotes.txt @@ -0,0 +1,42 @@ +2.0.2 (12/04/2011) +* Fixed exception text construction bug (pointer + offset, instead of std::string + std::string) +* Fixed crash in UnknownElement::operator= +* Fixed bug where object member names couldn't contain special characters +* Fixed crash when parsing an incomplete document +* Cosmetic changes to parser +* Added proper BSD license text + +2.0.1 (11/17/2009) +* A couple of Reader functions not inlined, sometimes resulting in linker duplicate symbols. Oops. + +2.0.0 (11/14/2009) +* Redesign/simplicification of the element class relationships: + * Element/Element_T base class or *Imp classes eliminated. Originally necessary for aggregation by Object/Array, but now unnecessary with UnknownElement type + * json_cast<> functions eliminated. Static type safety relaxed, allowing more concise document data extraction code (dynamic type safety still completely maintained). + * Quick-Interpreter/-Builder classes eliminated. Equivalent functionality now in "UnknownElement", but now more accessible + In summary, simpler design, less code in library, less code necessary to utilize library. See test app for many more new examples. +* Entire library is now inlined. Bound to be controversial, but... + * Modern compilers should eliminate redundant object code + * Fixes problems associated with different runtime libraries, library debug information, security & debug iterator compile-time options under MSVC++, among other things. + * Simply include the appropriate file & go - no linker settings to mess with. +* Added 64-bit build targets for MSVC 8/9 test app, just because. +* Scan/Parse exceptions moved into Reader class scope, and Parse exceptions fixed to always include bad token string +* A few more random bug fixes +* Tested under: + * MSVC++ 2005 + * MSVC++ 2008 + * GCC 4.4.0 + +1.1.0 (08/30/2009) +* Implemented operator == for all element types +* Added makefile for building with g++ (thanks George Morgan). +* Fixed a few compiler errors on non-Visual Studio compilers (my C++ wasn't as ANSI as I thought...) +* Support for (non-standard) comments REMOVED +* Support for Visual Studio 7.1 (2003) REMOVED +* Fixed the "Unexpected token..." exception string (was gibberish) +* Improvements to the QuickInterpreter & QuickBuilder interfaces +* Elements now sanity-check themselves during operations and throw an exception accordingly, for example if an Object gets tricked into thinking it's an Array (reinterpret_cast, reading a document with an Array root element into an Object, etc) +* Other random minor bug fixes & general cleanup + +1.0.0 (01/31/2009) +* Initial release! Remaining work: better documentation, better test/sample app, yada yada diff --git a/src/libs/resiprocate/rutil/cajun/json/elements.h b/src/libs/resiprocate/rutil/cajun/json/elements.h new file mode 100644 index 00000000..df1a0ca3 --- /dev/null +++ b/src/libs/resiprocate/rutil/cajun/json/elements.h @@ -0,0 +1,299 @@ +/****************************************************************************** + +Copyright (c) 2009-2010, Terry Caton +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the projecct nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#pragma once + +#include <deque> +#include <list> +#include <string> +#include <stdexcept> + +/* + +TODO: +* better documentation (doxygen?) +* Unicode support +* parent element accessors + +*/ + +namespace json +{ + +namespace Version +{ + enum { MAJOR = 2 }; + enum { MINOR = 0 }; + enum {ENGINEERING = 2 }; +} + +///////////////////////////////////////////////// +// forward declarations (more info further below) + + +class Visitor; +class ConstVisitor; + +template <typename ValueTypeT> +class TrivialType_T; + +typedef TrivialType_T<double> Number; +typedef TrivialType_T<bool> Boolean; +typedef TrivialType_T<std::string> String; + +class Object; +class Array; +class Null; + + + +///////////////////////////////////////////////////////////////////////// +// Exception - base class for all JSON-related runtime errors + +class Exception : public std::runtime_error +{ +public: + Exception(const std::string& sMessage); +}; + + + + +///////////////////////////////////////////////////////////////////////// +// UnknownElement - provides a typesafe surrogate for any of the JSON- +// sanctioned element types. This class allows the Array and Object +// class to effectively contain a heterogeneous set of child elements. +// The cast operators provide convenient implicit downcasting, while +// preserving dynamic type safety by throwing an exception during a +// a bad cast. +// The object & array element index operators (operators [std::string] +// and [size_t]) provide convenient, quick access to child elements. +// They are a logical extension of the cast operators. These child +// element accesses can be chained together, allowing the following +// (when document structure is well-known): +// String str = objInvoices[1]["Customer"]["Company"]; + + +class UnknownElement +{ +public: + UnknownElement(); + UnknownElement(const UnknownElement& unknown); + UnknownElement(const Object& object); + UnknownElement(const Array& array); + UnknownElement(const Number& number); + UnknownElement(const Boolean& boolean); + UnknownElement(const String& string); + UnknownElement(const Null& null); + + ~UnknownElement(); + + UnknownElement& operator = (const UnknownElement& unknown); + + // implicit cast to actual element type. throws on failure + operator const Object& () const; + operator const Array& () const; + operator const Number& () const; + operator const Boolean& () const; + operator const String& () const; + operator const Null& () const; + + // implicit cast to actual element type. *converts* on failure, and always returns success + operator Object& (); + operator Array& (); + operator Number& (); + operator Boolean& (); + operator String& (); + operator Null& (); + + // provides quick access to children when real element type is object + UnknownElement& operator[] (const std::string& key); + const UnknownElement& operator[] (const std::string& key) const; + + // provides quick access to children when real element type is array + UnknownElement& operator[] (size_t index); + const UnknownElement& operator[] (size_t index) const; + + // implements visitor pattern + void Accept(ConstVisitor& visitor) const; + void Accept(Visitor& visitor); + + // tests equality. first checks type, then value if possible + bool operator == (const UnknownElement& element) const; + +private: + class Imp; + + template <typename ElementTypeT> + class Imp_T; + + class CastVisitor; + class ConstCastVisitor; + + template <typename ElementTypeT> + class CastVisitor_T; + + template <typename ElementTypeT> + class ConstCastVisitor_T; + + template <typename ElementTypeT> + const ElementTypeT& CastTo() const; + + template <typename ElementTypeT> + ElementTypeT& ConvertTo(); + + Imp* m_pImp; +}; + + +///////////////////////////////////////////////////////////////////////////////// +// Array - mimics std::deque<UnknownElement>. The array contents are effectively +// heterogeneous thanks to the ElementUnknown class. push_back has been replaced +// by more generic insert functions. + +class Array +{ +public: + typedef std::deque<UnknownElement> Elements; + typedef Elements::iterator iterator; + typedef Elements::const_iterator const_iterator; + + iterator Begin(); + iterator End(); + const_iterator Begin() const; + const_iterator End() const; + + iterator Insert(const UnknownElement& element, iterator itWhere); + iterator Insert(const UnknownElement& element); + iterator Erase(iterator itWhere); + void Resize(size_t newSize); + void Clear(); + + size_t Size() const; + bool Empty() const; + + UnknownElement& operator[] (size_t index); + const UnknownElement& operator[] (size_t index) const; + + bool operator == (const Array& array) const; + +private: + Elements m_Elements; +}; + + +///////////////////////////////////////////////////////////////////////////////// +// Object - mimics std::map<std::string, UnknownElement>. The member value +// contents are effectively heterogeneous thanks to the UnknownElement class + +class Object +{ +public: + struct Member { + Member(const std::string& nameIn = std::string(), const UnknownElement& elementIn = UnknownElement()); + + bool operator == (const Member& member) const; + + std::string name; + UnknownElement element; + }; + + typedef std::list<Member> Members; // map faster, but does not preserve order + typedef Members::iterator iterator; + typedef Members::const_iterator const_iterator; + + bool operator == (const Object& object) const; + + iterator Begin(); + iterator End(); + const_iterator Begin() const; + const_iterator End() const; + + size_t Size() const; + bool Empty() const; + + iterator Find(const std::string& name); + const_iterator Find(const std::string& name) const; + + iterator Insert(const Member& member); + iterator Insert(const Member& member, iterator itWhere); + iterator Erase(iterator itWhere); + void Clear(); + + UnknownElement& operator [](const std::string& name); + const UnknownElement& operator [](const std::string& name) const; + +private: + class Finder; + + Members m_Members; +}; + + +///////////////////////////////////////////////////////////////////////////////// +// TrivialType_T - class template for encapsulates a simple data type, such as +// a string, number, or boolean. Provides implicit const & noncost cast operators +// for that type, allowing "DataTypeT type = trivialType;" + + +template <typename DataTypeT> +class TrivialType_T +{ +public: + TrivialType_T(const DataTypeT& t = DataTypeT()); + + operator DataTypeT&(); + operator const DataTypeT&() const; + + DataTypeT& Value(); + const DataTypeT& Value() const; + + bool operator == (const TrivialType_T<DataTypeT>& trivial) const; + +private: + DataTypeT m_tValue; +}; + + + +///////////////////////////////////////////////////////////////////////////////// +// Null - doesn't do much of anything but satisfy the JSON spec. It is the default +// element type of UnknownElement + +class Null +{ +public: + bool operator == (const Null& trivial) const; +}; + + +} // End namespace + + +#include "elements.inl" diff --git a/src/libs/resiprocate/rutil/cajun/json/elements.inl b/src/libs/resiprocate/rutil/cajun/json/elements.inl new file mode 100644 index 00000000..dbfbf2af --- /dev/null +++ b/src/libs/resiprocate/rutil/cajun/json/elements.inl @@ -0,0 +1,442 @@ +/****************************************************************************** + +Copyright (c) 2009-2010, Terry Caton +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the projecct nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#include "visitor.h" +#include "reader.h" +#include <cassert> +#include <algorithm> +#include <map> + +/* + +TODO: +* better documentation + +*/ + +namespace json +{ + + +inline Exception::Exception(const std::string& sMessage) : + std::runtime_error(sMessage) {} + + +///////////////////////// +// UnknownElement members + +class UnknownElement::Imp +{ +public: + virtual ~Imp() {} + virtual Imp* Clone() const = 0; + + virtual bool Compare(const Imp& imp) const = 0; + + virtual void Accept(ConstVisitor& visitor) const = 0; + virtual void Accept(Visitor& visitor) = 0; +}; + + +template <typename ElementTypeT> +class UnknownElement::Imp_T : public UnknownElement::Imp +{ +public: + Imp_T(const ElementTypeT& element) : m_Element(element) {} + virtual Imp* Clone() const { return new Imp_T<ElementTypeT>(*this); } + + virtual void Accept(ConstVisitor& visitor) const { visitor.Visit(m_Element); } + virtual void Accept(Visitor& visitor) { visitor.Visit(m_Element); } + + virtual bool Compare(const Imp& imp) const + { + ConstCastVisitor_T<ElementTypeT> castVisitor; + imp.Accept(castVisitor); + return castVisitor.m_pElement && + m_Element == *castVisitor.m_pElement; + } + +private: + ElementTypeT m_Element; +}; + + +class UnknownElement::ConstCastVisitor : public ConstVisitor +{ + virtual void Visit(const Array& array) {} + virtual void Visit(const Object& object) {} + virtual void Visit(const Number& number) {} + virtual void Visit(const String& string) {} + virtual void Visit(const Boolean& boolean) {} + virtual void Visit(const Null& null) {} +}; + +template <typename ElementTypeT> +class UnknownElement::ConstCastVisitor_T : public ConstCastVisitor +{ +public: + ConstCastVisitor_T() : m_pElement(0) {} + virtual void Visit(const ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions + const ElementTypeT* m_pElement; +}; + + +class UnknownElement::CastVisitor : public Visitor +{ + virtual void Visit(Array& array) {} + virtual void Visit(Object& object) {} + virtual void Visit(Number& number) {} + virtual void Visit(String& string) {} + virtual void Visit(Boolean& boolean) {} + virtual void Visit(Null& null) {} +}; + +template <typename ElementTypeT> +class UnknownElement::CastVisitor_T : public CastVisitor +{ +public: + CastVisitor_T() : m_pElement(0) {} + virtual void Visit(ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions + ElementTypeT* m_pElement; +}; + + + + +inline UnknownElement::UnknownElement() : m_pImp( new Imp_T<Null>( Null() ) ) {} +inline UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp( unknown.m_pImp->Clone()) {} +inline UnknownElement::UnknownElement(const Object& object) : m_pImp( new Imp_T<Object>(object) ) {} +inline UnknownElement::UnknownElement(const Array& array) : m_pImp( new Imp_T<Array>(array) ) {} +inline UnknownElement::UnknownElement(const Number& number) : m_pImp( new Imp_T<Number>(number) ) {} +inline UnknownElement::UnknownElement(const Boolean& boolean) : m_pImp( new Imp_T<Boolean>(boolean) ) {} +inline UnknownElement::UnknownElement(const String& string) : m_pImp( new Imp_T<String>(string) ) {} +inline UnknownElement::UnknownElement(const Null& null) : m_pImp( new Imp_T<Null>(null) ) {} + +inline UnknownElement::~UnknownElement() { delete m_pImp; } + +inline UnknownElement::operator const Object& () const { return CastTo<Object>(); } +inline UnknownElement::operator const Array& () const { return CastTo<Array>(); } +inline UnknownElement::operator const Number& () const { return CastTo<Number>(); } +inline UnknownElement::operator const Boolean& () const { return CastTo<Boolean>(); } +inline UnknownElement::operator const String& () const { return CastTo<String>(); } +inline UnknownElement::operator const Null& () const { return CastTo<Null>(); } + +inline UnknownElement::operator Object& () { return ConvertTo<Object>(); } +inline UnknownElement::operator Array& () { return ConvertTo<Array>(); } +inline UnknownElement::operator Number& () { return ConvertTo<Number>(); } +inline UnknownElement::operator Boolean& () { return ConvertTo<Boolean>(); } +inline UnknownElement::operator String& () { return ConvertTo<String>(); } +inline UnknownElement::operator Null& () { return ConvertTo<Null>(); } + +inline UnknownElement& UnknownElement::operator = (const UnknownElement& unknown) +{ + // always check for this + if (&unknown != this) + { + // we might be copying from a subtree of ourselves. delete the old imp + // only after the clone operation is complete. yes, this could be made + // more efficient, but isn't worth the complexity + Imp* pOldImp = m_pImp; + m_pImp = unknown.m_pImp->Clone(); + delete pOldImp; + } + + return *this; +} + +inline UnknownElement& UnknownElement::operator[] (const std::string& key) +{ + // the people want an object. make us one if we aren't already + Object& object = ConvertTo<Object>(); + return object[key]; +} + +inline const UnknownElement& UnknownElement::operator[] (const std::string& key) const +{ + // throws if we aren't an object + const Object& object = CastTo<Object>(); + return object[key]; +} + +inline UnknownElement& UnknownElement::operator[] (size_t index) +{ + // the people want an array. make us one if we aren't already + Array& array = ConvertTo<Array>(); + return array[index]; +} + +inline const UnknownElement& UnknownElement::operator[] (size_t index) const +{ + // throws if we aren't an array + const Array& array = CastTo<Array>(); + return array[index]; +} + + +template <typename ElementTypeT> +const ElementTypeT& UnknownElement::CastTo() const +{ + ConstCastVisitor_T<ElementTypeT> castVisitor; + m_pImp->Accept(castVisitor); + if (castVisitor.m_pElement == 0) + throw Exception("Bad cast"); + return *castVisitor.m_pElement; +} + + + +template <typename ElementTypeT> +ElementTypeT& UnknownElement::ConvertTo() +{ + CastVisitor_T<ElementTypeT> castVisitor; + m_pImp->Accept(castVisitor); + if (castVisitor.m_pElement == 0) + { + // we're not the right type. fix it & try again + *this = ElementTypeT(); + m_pImp->Accept(castVisitor); + } + + return *castVisitor.m_pElement; +} + + +inline void UnknownElement::Accept(ConstVisitor& visitor) const { m_pImp->Accept(visitor); } +inline void UnknownElement::Accept(Visitor& visitor) { m_pImp->Accept(visitor); } + + +inline bool UnknownElement::operator == (const UnknownElement& element) const +{ + return m_pImp->Compare(*element.m_pImp); +} + + + +////////////////// +// Object members + + +inline Object::Member::Member(const std::string& nameIn, const UnknownElement& elementIn) : + name(nameIn), element(elementIn) {} + +inline bool Object::Member::operator == (const Member& member) const +{ + return name == member.name && + element == member.element; +} + +class Object::Finder : public std::unary_function<Object::Member, bool> +{ +public: + Finder(const std::string& name) : m_name(name) {} + bool operator () (const Object::Member& member) { + return member.name == m_name; + } + +private: + std::string m_name; +}; + + + +inline Object::iterator Object::Begin() { return m_Members.begin(); } +inline Object::iterator Object::End() { return m_Members.end(); } +inline Object::const_iterator Object::Begin() const { return m_Members.begin(); } +inline Object::const_iterator Object::End() const { return m_Members.end(); } + +inline size_t Object::Size() const { return m_Members.size(); } +inline bool Object::Empty() const { return m_Members.empty(); } + +inline Object::iterator Object::Find(const std::string& name) +{ + return std::find_if(m_Members.begin(), m_Members.end(), Finder(name)); +} + +inline Object::const_iterator Object::Find(const std::string& name) const +{ + return std::find_if(m_Members.begin(), m_Members.end(), Finder(name)); +} + +inline Object::iterator Object::Insert(const Member& member) +{ + return Insert(member, End()); +} + +inline Object::iterator Object::Insert(const Member& member, iterator itWhere) +{ + iterator it = Find(member.name); + if (it != m_Members.end()) + throw Exception(std::string("Object member already exists: ") + member.name); + + it = m_Members.insert(itWhere, member); + return it; +} + +inline Object::iterator Object::Erase(iterator itWhere) +{ + return m_Members.erase(itWhere); +} + +inline UnknownElement& Object::operator [](const std::string& name) +{ + + iterator it = Find(name); + if (it == m_Members.end()) + { + Member member(name); + it = Insert(member, End()); + } + return it->element; +} + +inline const UnknownElement& Object::operator [](const std::string& name) const +{ + const_iterator it = Find(name); + if (it == End()) + throw Exception(std::string("Object member not found: ") + name); + return it->element; +} + +inline void Object::Clear() +{ + m_Members.clear(); +} + +inline bool Object::operator == (const Object& object) const +{ + return m_Members == object.m_Members; +} + + +///////////////// +// Array members + +inline Array::iterator Array::Begin() { return m_Elements.begin(); } +inline Array::iterator Array::End() { return m_Elements.end(); } +inline Array::const_iterator Array::Begin() const { return m_Elements.begin(); } +inline Array::const_iterator Array::End() const { return m_Elements.end(); } + +inline Array::iterator Array::Insert(const UnknownElement& element, iterator itWhere) +{ + return m_Elements.insert(itWhere, element); +} + +inline Array::iterator Array::Insert(const UnknownElement& element) +{ + return Insert(element, End()); +} + +inline Array::iterator Array::Erase(iterator itWhere) +{ + return m_Elements.erase(itWhere); +} + +inline void Array::Resize(size_t newSize) +{ + m_Elements.resize(newSize); +} + +inline size_t Array::Size() const { return m_Elements.size(); } +inline bool Array::Empty() const { return m_Elements.empty(); } + +inline UnknownElement& Array::operator[] (size_t index) +{ + size_t nMinSize = index + 1; // zero indexed + if (m_Elements.size() < nMinSize) + m_Elements.resize(nMinSize); + return m_Elements[index]; +} + +inline const UnknownElement& Array::operator[] (size_t index) const +{ + if (index >= m_Elements.size()) + throw Exception("Array out of bounds"); + return m_Elements[index]; +} + +inline void Array::Clear() { + m_Elements.clear(); +} + +inline bool Array::operator == (const Array& array) const +{ + return m_Elements == array.m_Elements; +} + + +//////////////////////// +// TrivialType_T members + +template <typename DataTypeT> +TrivialType_T<DataTypeT>::TrivialType_T(const DataTypeT& t) : + m_tValue(t) {} + +template <typename DataTypeT> +TrivialType_T<DataTypeT>::operator DataTypeT&() +{ + return Value(); +} + +template <typename DataTypeT> +TrivialType_T<DataTypeT>::operator const DataTypeT&() const +{ + return Value(); +} + +template <typename DataTypeT> +DataTypeT& TrivialType_T<DataTypeT>::Value() +{ + return m_tValue; +} + +template <typename DataTypeT> +const DataTypeT& TrivialType_T<DataTypeT>::Value() const +{ + return m_tValue; +} + +template <typename DataTypeT> +bool TrivialType_T<DataTypeT>::operator == (const TrivialType_T<DataTypeT>& trivial) const +{ + return m_tValue == trivial.m_tValue; +} + + + +////////////////// +// Null members + +inline bool Null::operator == (const Null& trivial) const +{ + return true; +} + + + +} // End namespace diff --git a/src/libs/resiprocate/rutil/cajun/json/reader.h b/src/libs/resiprocate/rutil/cajun/json/reader.h new file mode 100644 index 00000000..f4316702 --- /dev/null +++ b/src/libs/resiprocate/rutil/cajun/json/reader.h @@ -0,0 +1,148 @@ +/****************************************************************************** + +Copyright (c) 2009-2010, Terry Caton +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the projecct nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + + + +#pragma once + +#include "elements.h" +#include <iostream> +#include <vector> + +namespace json +{ + +class Reader +{ +public: + // this structure will be reported in one of the exceptions defined below + struct Location + { + Location(); + + unsigned int m_nLine; // document line, zero-indexed + unsigned int m_nLineOffset; // character offset from beginning of line, zero indexed + unsigned int m_nDocOffset; // character offset from entire document, zero indexed + }; + + // thrown during the first phase of reading. generally catches low-level problems such + // as errant characters or corrupt/incomplete documents + class ScanException : public Exception + { + public: + ScanException(const std::string& sMessage, const Reader::Location& locError) : + Exception(sMessage), + m_locError(locError) {} + + Reader::Location m_locError; + }; + + // thrown during the second phase of reading. generally catches higher-level problems such + // as missing commas or brackets + class ParseException : public Exception + { + public: + ParseException(const std::string& sMessage, const Reader::Location& locTokenBegin, const Reader::Location& locTokenEnd) : + Exception(sMessage), + m_locTokenBegin(locTokenBegin), + m_locTokenEnd(locTokenEnd) {} + + Reader::Location m_locTokenBegin; + Reader::Location m_locTokenEnd; + }; + + + // if you know what the document looks like, call one of these... + static void Read(Object& object, std::istream& istr); + static void Read(Array& array, std::istream& istr); + static void Read(String& string, std::istream& istr); + static void Read(Number& number, std::istream& istr); + static void Read(Boolean& boolean, std::istream& istr); + static void Read(Null& null, std::istream& istr); + + // ...otherwise, if you don't know, call this & visit it + static void Read(UnknownElement& elementRoot, std::istream& istr); + +private: + struct Token + { + enum Type + { + TOKEN_OBJECT_BEGIN, // { + TOKEN_OBJECT_END, // } + TOKEN_ARRAY_BEGIN, // [ + TOKEN_ARRAY_END, // ] + TOKEN_NEXT_ELEMENT, // , + TOKEN_MEMBER_ASSIGN, // : + TOKEN_STRING, // "xxx" + TOKEN_NUMBER, // [+/-]000.000[e[+/-]000] + TOKEN_BOOLEAN, // true -or- false + TOKEN_NULL, // null + }; + + Type nType; + std::string sValue; + + // for malformed file debugging + Reader::Location locBegin; + Reader::Location locEnd; + }; + + class InputStream; + class TokenStream; + typedef std::vector<Token> Tokens; + + template <typename ElementTypeT> + static void Read_i(ElementTypeT& element, std::istream& istr); + + // scanning istream into token sequence + void Scan(Tokens& tokens, InputStream& inputStream); + + void EatWhiteSpace(InputStream& inputStream); + std::string MatchString(InputStream& inputStream); + std::string MatchNumber(InputStream& inputStream); + std::string MatchExpectedString(InputStream& inputStream, const std::string& sExpected); + + // parsing token sequence into element structure + void Parse(UnknownElement& element, TokenStream& tokenStream); + void Parse(Object& object, TokenStream& tokenStream); + void Parse(Array& array, TokenStream& tokenStream); + void Parse(String& string, TokenStream& tokenStream); + void Parse(Number& number, TokenStream& tokenStream); + void Parse(Boolean& boolean, TokenStream& tokenStream); + void Parse(Null& null, TokenStream& tokenStream); + + const std::string& MatchExpectedToken(Token::Type nExpected, TokenStream& tokenStream); +}; + + +} // End namespace + + +#include "reader.inl" \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/cajun/json/reader.inl b/src/libs/resiprocate/rutil/cajun/json/reader.inl new file mode 100644 index 00000000..b297fa33 --- /dev/null +++ b/src/libs/resiprocate/rutil/cajun/json/reader.inl @@ -0,0 +1,533 @@ +/****************************************************************************** + +Copyright (c) 2009-2010, Terry Caton +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the projecct nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#include <cassert> +#include <set> +#include <sstream> + +/* + +TODO: +* better documentation +* unicode character decoding + +*/ + +namespace json +{ + +inline std::istream& operator >> (std::istream& istr, UnknownElement& elementRoot) { + Reader::Read(elementRoot, istr); + return istr; +} + +inline Reader::Location::Location() : + m_nLine(0), + m_nLineOffset(0), + m_nDocOffset(0) +{} + + +////////////////////// +// Reader::InputStream + +class Reader::InputStream // would be cool if we could inherit from std::istream & override "get" +{ +public: + InputStream(std::istream& iStr) : + m_iStr(iStr) {} + + // protect access to the input stream, so we can keeep track of document/line offsets + char Get(); // big, define outside + char Peek() { + assert(m_iStr.eof() == false); // enforce reading of only valid stream data + return m_iStr.peek(); + } + + bool EOS() { + m_iStr.peek(); // apparently eof flag isn't set until a character read is attempted. whatever. + return m_iStr.eof(); + } + + const Location& GetLocation() const { return m_Location; } + +private: + std::istream& m_iStr; + Location m_Location; +}; + + +inline char Reader::InputStream::Get() +{ + assert(m_iStr.eof() == false); // enforce reading of only valid stream data + char c = m_iStr.get(); + + ++m_Location.m_nDocOffset; + if (c == '\n') { + ++m_Location.m_nLine; + m_Location.m_nLineOffset = 0; + } + else { + ++m_Location.m_nLineOffset; + } + + return c; +} + + + +////////////////////// +// Reader::TokenStream + +class Reader::TokenStream +{ +public: + TokenStream(const Tokens& tokens); + + const Token& Peek(); + const Token& Get(); + + bool EOS() const; + +private: + const Tokens& m_Tokens; + Tokens::const_iterator m_itCurrent; +}; + + +inline Reader::TokenStream::TokenStream(const Tokens& tokens) : + m_Tokens(tokens), + m_itCurrent(tokens.begin()) +{} + +inline const Reader::Token& Reader::TokenStream::Peek() { + if (EOS()) + { + const Token& lastToken = *m_Tokens.rbegin(); + std::string sMessage = "Unexpected end of token stream"; + throw ParseException(sMessage, lastToken.locBegin, lastToken.locEnd); // nowhere to point to + } + return *(m_itCurrent); +} + +inline const Reader::Token& Reader::TokenStream::Get() { + const Token& token = Peek(); + ++m_itCurrent; + return token; +} + +inline bool Reader::TokenStream::EOS() const { + return m_itCurrent == m_Tokens.end(); +} + +/////////////////// +// Reader (finally) + + +inline void Reader::Read(Object& object, std::istream& istr) { Read_i(object, istr); } +inline void Reader::Read(Array& array, std::istream& istr) { Read_i(array, istr); } +inline void Reader::Read(String& string, std::istream& istr) { Read_i(string, istr); } +inline void Reader::Read(Number& number, std::istream& istr) { Read_i(number, istr); } +inline void Reader::Read(Boolean& boolean, std::istream& istr) { Read_i(boolean, istr); } +inline void Reader::Read(Null& null, std::istream& istr) { Read_i(null, istr); } +inline void Reader::Read(UnknownElement& unknown, std::istream& istr) { Read_i(unknown, istr); } + + +template <typename ElementTypeT> +void Reader::Read_i(ElementTypeT& element, std::istream& istr) +{ + Reader reader; + + Tokens tokens; + InputStream inputStream(istr); + reader.Scan(tokens, inputStream); + + TokenStream tokenStream(tokens); + reader.Parse(element, tokenStream); + + if (tokenStream.EOS() == false) + { + const Token& token = tokenStream.Peek(); + std::string sMessage = std::string("Expected End of token stream; found ") + token.sValue; + throw ParseException(sMessage, token.locBegin, token.locEnd); + } +} + + +inline void Reader::Scan(Tokens& tokens, InputStream& inputStream) +{ + while (EatWhiteSpace(inputStream), // ignore any leading white space... + inputStream.EOS() == false) // ...before checking for EOS + { + // if all goes well, we'll create a token each pass + Token token; + token.locBegin = inputStream.GetLocation(); + + // gives us null-terminated string + char sChar = inputStream.Peek(); + switch (sChar) + { + case '{': + token.sValue = MatchExpectedString(inputStream, "{"); + token.nType = Token::TOKEN_OBJECT_BEGIN; + break; + + case '}': + token.sValue = MatchExpectedString(inputStream, "}"); + token.nType = Token::TOKEN_OBJECT_END; + break; + + case '[': + token.sValue = MatchExpectedString(inputStream, "["); + token.nType = Token::TOKEN_ARRAY_BEGIN; + break; + + case ']': + token.sValue = MatchExpectedString(inputStream, "]"); + token.nType = Token::TOKEN_ARRAY_END; + break; + + case ',': + token.sValue = MatchExpectedString(inputStream, ","); + token.nType = Token::TOKEN_NEXT_ELEMENT; + break; + + case ':': + token.sValue = MatchExpectedString(inputStream, ":"); + token.nType = Token::TOKEN_MEMBER_ASSIGN; + break; + + case '"': + token.sValue = MatchString(inputStream); + token.nType = Token::TOKEN_STRING; + break; + + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + token.sValue = MatchNumber(inputStream); + token.nType = Token::TOKEN_NUMBER; + break; + + case 't': + token.sValue = MatchExpectedString(inputStream, "true"); + token.nType = Token::TOKEN_BOOLEAN; + break; + + case 'f': + token.sValue = MatchExpectedString(inputStream, "false"); + token.nType = Token::TOKEN_BOOLEAN; + break; + + case 'n': + token.sValue = MatchExpectedString(inputStream, "null"); + token.nType = Token::TOKEN_NULL; + break; + + default: + { + std::string sErrorMessage = std::string("Unexpected character in stream: ") + sChar; + throw ScanException(sErrorMessage, inputStream.GetLocation()); + } + } + + token.locEnd = inputStream.GetLocation(); + tokens.push_back(token); + } +} + + +inline void Reader::EatWhiteSpace(InputStream& inputStream) +{ + while (inputStream.EOS() == false && + ::isspace(inputStream.Peek())) + inputStream.Get(); +} + +inline std::string Reader::MatchExpectedString(InputStream& inputStream, const std::string& sExpected) +{ + std::string::const_iterator it(sExpected.begin()), + itEnd(sExpected.end()); + for ( ; it != itEnd; ++it) { + if (inputStream.EOS() || // did we reach the end before finding what we're looking for... + inputStream.Get() != *it) // ...or did we find something different? + { + std::string sMessage = std::string("Expected string: ") + sExpected; + throw ScanException(sMessage, inputStream.GetLocation()); + } + } + + // all's well if we made it here + return sExpected; +} + + +inline std::string Reader::MatchString(InputStream& inputStream) +{ + MatchExpectedString(inputStream, "\""); + + std::string string; + while (inputStream.EOS() == false && + inputStream.Peek() != '"') + { + char c = inputStream.Get(); + + // escape? + if (c == '\\' && + inputStream.EOS() == false) // shouldn't have reached the end yet + { + c = inputStream.Get(); + switch (c) { + case '/': string.push_back('/'); break; + case '"': string.push_back('"'); break; + case '\\': string.push_back('\\'); break; + case 'b': string.push_back('\b'); break; + case 'f': string.push_back('\f'); break; + case 'n': string.push_back('\n'); break; + case 'r': string.push_back('\r'); break; + case 't': string.push_back('\t'); break; + //case 'u': string.push_back('\u'); break; // TODO: what do we do with this? + default: { + std::string sMessage = std::string("Unrecognized escape sequence found in string: \\") + c; + throw ScanException(sMessage, inputStream.GetLocation()); + } + } + } + else { + string.push_back(c); + } + } + + // eat the last '"' that we just peeked + MatchExpectedString(inputStream, "\""); + + // all's well if we made it here + return string; +} + + +inline std::string Reader::MatchNumber(InputStream& inputStream) +{ + const char sNumericChars[] = "0123456789.eE-+"; + std::set<char> numericChars; + numericChars.insert(sNumericChars, sNumericChars + sizeof(sNumericChars)); + + std::string sNumber; + while (inputStream.EOS() == false && + numericChars.find(inputStream.Peek()) != numericChars.end()) + { + sNumber.push_back(inputStream.Get()); + } + + return sNumber; +} + + +inline void Reader::Parse(UnknownElement& element, Reader::TokenStream& tokenStream) +{ + const Token& token = tokenStream.Peek(); + switch (token.nType) { + case Token::TOKEN_OBJECT_BEGIN: + { + // implicit non-const cast will perform conversion for us (if necessary) + Object& object = element; + Parse(object, tokenStream); + break; + } + + case Token::TOKEN_ARRAY_BEGIN: + { + Array& array = element; + Parse(array, tokenStream); + break; + } + + case Token::TOKEN_STRING: + { + String& string = element; + Parse(string, tokenStream); + break; + } + + case Token::TOKEN_NUMBER: + { + Number& number = element; + Parse(number, tokenStream); + break; + } + + case Token::TOKEN_BOOLEAN: + { + Boolean& boolean = element; + Parse(boolean, tokenStream); + break; + } + + case Token::TOKEN_NULL: + { + Null& null = element; + Parse(null, tokenStream); + break; + } + + default: + { + std::string sMessage = std::string("Unexpected token: ") + token.sValue; + throw ParseException(sMessage, token.locBegin, token.locEnd); + } + } +} + + +inline void Reader::Parse(Object& object, Reader::TokenStream& tokenStream) +{ + MatchExpectedToken(Token::TOKEN_OBJECT_BEGIN, tokenStream); + + bool bContinue = (tokenStream.EOS() == false && + tokenStream.Peek().nType != Token::TOKEN_OBJECT_END); + while (bContinue) + { + Object::Member member; + + // first the member name. save the token in case we have to throw an exception + const Token& tokenName = tokenStream.Peek(); + member.name = MatchExpectedToken(Token::TOKEN_STRING, tokenStream); + + // ...then the key/value separator... + MatchExpectedToken(Token::TOKEN_MEMBER_ASSIGN, tokenStream); + + // ...then the value itself (can be anything). + Parse(member.element, tokenStream); + + // try adding it to the object (this could throw) + try + { + object.Insert(member); + } + catch (Exception&) + { + // must be a duplicate name + std::string sMessage = std::string("Duplicate object member token: ") + member.name; + throw ParseException(sMessage, tokenName.locBegin, tokenName.locEnd); + } + + bContinue = (tokenStream.EOS() == false && + tokenStream.Peek().nType == Token::TOKEN_NEXT_ELEMENT); + if (bContinue) + MatchExpectedToken(Token::TOKEN_NEXT_ELEMENT, tokenStream); + } + + MatchExpectedToken(Token::TOKEN_OBJECT_END, tokenStream); +} + + +inline void Reader::Parse(Array& array, Reader::TokenStream& tokenStream) +{ + MatchExpectedToken(Token::TOKEN_ARRAY_BEGIN, tokenStream); + + bool bContinue = (tokenStream.EOS() == false && + tokenStream.Peek().nType != Token::TOKEN_ARRAY_END); + while (bContinue) + { + // ...what's next? could be anything + Array::iterator itElement = array.Insert(UnknownElement()); + UnknownElement& element = *itElement; + Parse(element, tokenStream); + + bContinue = (tokenStream.EOS() == false && + tokenStream.Peek().nType == Token::TOKEN_NEXT_ELEMENT); + if (bContinue) + MatchExpectedToken(Token::TOKEN_NEXT_ELEMENT, tokenStream); + } + + MatchExpectedToken(Token::TOKEN_ARRAY_END, tokenStream); +} + + +inline void Reader::Parse(String& string, Reader::TokenStream& tokenStream) +{ + string = MatchExpectedToken(Token::TOKEN_STRING, tokenStream); +} + + +inline void Reader::Parse(Number& number, Reader::TokenStream& tokenStream) +{ + const Token& currentToken = tokenStream.Peek(); // might need this later for throwing exception + const std::string& sValue = MatchExpectedToken(Token::TOKEN_NUMBER, tokenStream); + + std::istringstream iStr(sValue); + double dValue; + iStr >> dValue; + + // did we consume all characters in the token? + if (iStr.eof() == false) + { + char c = iStr.peek(); + std::string sMessage = std::string("Unexpected character in NUMBER token: ") + c; + throw ParseException(sMessage, currentToken.locBegin, currentToken.locEnd); + } + + number = dValue; +} + + +inline void Reader::Parse(Boolean& boolean, Reader::TokenStream& tokenStream) +{ + const std::string& sValue = MatchExpectedToken(Token::TOKEN_BOOLEAN, tokenStream); + boolean = (sValue == "true" ? true : false); +} + + +inline void Reader::Parse(Null&, Reader::TokenStream& tokenStream) +{ + MatchExpectedToken(Token::TOKEN_NULL, tokenStream); +} + + +inline const std::string& Reader::MatchExpectedToken(Token::Type nExpected, Reader::TokenStream& tokenStream) +{ + const Token& token = tokenStream.Get(); + if (token.nType != nExpected) + { + std::string sMessage = std::string("Unexpected token: ") + token.sValue; + throw ParseException(sMessage, token.locBegin, token.locEnd); + } + + return token.sValue; +} + +} // End namespace diff --git a/src/libs/resiprocate/rutil/cajun/json/visitor.h b/src/libs/resiprocate/rutil/cajun/json/visitor.h new file mode 100644 index 00000000..a06299d1 --- /dev/null +++ b/src/libs/resiprocate/rutil/cajun/json/visitor.h @@ -0,0 +1,65 @@ +/****************************************************************************** + +Copyright (c) 2009-2010, Terry Caton +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the projecct nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#pragma once + +#include "elements.h" + +namespace json +{ + + +class Visitor +{ +public: + virtual ~Visitor() {} + + virtual void Visit(Array& array) = 0; + virtual void Visit(Object& object) = 0; + virtual void Visit(Number& number) = 0; + virtual void Visit(String& string) = 0; + virtual void Visit(Boolean& boolean) = 0; + virtual void Visit(Null& null) = 0; +}; + +class ConstVisitor +{ +public: + virtual ~ConstVisitor() {} + + virtual void Visit(const Array& array) = 0; + virtual void Visit(const Object& object) = 0; + virtual void Visit(const Number& number) = 0; + virtual void Visit(const String& string) = 0; + virtual void Visit(const Boolean& boolean) = 0; + virtual void Visit(const Null& null) = 0; +}; + + +} // End namespace diff --git a/src/libs/resiprocate/rutil/cajun/json/writer.h b/src/libs/resiprocate/rutil/cajun/json/writer.h new file mode 100644 index 00000000..594d5418 --- /dev/null +++ b/src/libs/resiprocate/rutil/cajun/json/writer.h @@ -0,0 +1,78 @@ +/****************************************************************************** + +Copyright (c) 2009-2010, Terry Caton +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the projecct nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#pragma once + +#include "elements.h" +#include "visitor.h" + +namespace json +{ + +class Writer : private ConstVisitor +{ +public: + static void Write(const Object& object, std::ostream& ostr); + static void Write(const Array& array, std::ostream& ostr); + static void Write(const String& string, std::ostream& ostr); + static void Write(const Number& number, std::ostream& ostr); + static void Write(const Boolean& boolean, std::ostream& ostr); + static void Write(const Null& null, std::ostream& ostr); + static void Write(const UnknownElement& elementRoot, std::ostream& ostr); + +private: + Writer(std::ostream& ostr); + + template <typename ElementTypeT> + static void Write_i(const ElementTypeT& element, std::ostream& ostr); + + void Write_i(const Object& object); + void Write_i(const Array& array); + void Write_i(const String& string); + void Write_i(const Number& number); + void Write_i(const Boolean& boolean); + void Write_i(const Null& null); + void Write_i(const UnknownElement& unknown); + + virtual void Visit(const Array& array); + virtual void Visit(const Object& object); + virtual void Visit(const Number& number); + virtual void Visit(const String& string); + virtual void Visit(const Boolean& boolean); + virtual void Visit(const Null& null); + + std::ostream& m_ostr; + int m_nTabDepth; +}; + + +} // End namespace + + +#include "writer.inl" \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/cajun/json/writer.inl b/src/libs/resiprocate/rutil/cajun/json/writer.inl new file mode 100644 index 00000000..a474d624 --- /dev/null +++ b/src/libs/resiprocate/rutil/cajun/json/writer.inl @@ -0,0 +1,178 @@ +/****************************************************************************** + +Copyright (c) 2009-2010, Terry Caton +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the projecct nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#include "writer.h" +#include <iostream> +#include <iomanip> + +/* + +TODO: +* better documentation +* unicode character encoding + +*/ + +namespace json +{ + + +inline void Writer::Write(const UnknownElement& elementRoot, std::ostream& ostr) { Write_i(elementRoot, ostr); } +inline void Writer::Write(const Object& object, std::ostream& ostr) { Write_i(object, ostr); } +inline void Writer::Write(const Array& array, std::ostream& ostr) { Write_i(array, ostr); } +inline void Writer::Write(const Number& number, std::ostream& ostr) { Write_i(number, ostr); } +inline void Writer::Write(const String& string, std::ostream& ostr) { Write_i(string, ostr); } +inline void Writer::Write(const Boolean& boolean, std::ostream& ostr) { Write_i(boolean, ostr); } +inline void Writer::Write(const Null& null, std::ostream& ostr) { Write_i(null, ostr); } + + +inline Writer::Writer(std::ostream& ostr) : + m_ostr(ostr), + m_nTabDepth(0) +{} + +template <typename ElementTypeT> +void Writer::Write_i(const ElementTypeT& element, std::ostream& ostr) +{ + Writer writer(ostr); + writer.Write_i(element); + ostr.flush(); // all done +} + +inline void Writer::Write_i(const Array& array) +{ + if (array.Empty()) + m_ostr << "[]"; + else + { + m_ostr << '[' << std::endl; + ++m_nTabDepth; + + Array::const_iterator it(array.Begin()), + itEnd(array.End()); + while (it != itEnd) { + m_ostr << std::string(m_nTabDepth, '\t'); + + Write_i(*it); + + if (++it != itEnd) + m_ostr << ','; + m_ostr << std::endl; + } + + --m_nTabDepth; + m_ostr << std::string(m_nTabDepth, '\t') << ']'; + } +} + +inline void Writer::Write_i(const Object& object) +{ + if (object.Empty()) + m_ostr << "{}"; + else + { + m_ostr << '{' << std::endl; + ++m_nTabDepth; + + Object::const_iterator it(object.Begin()), + itEnd(object.End()); + while (it != itEnd) { + m_ostr << std::string(m_nTabDepth, '\t'); + + Write_i(it->name); + + m_ostr << " : "; + Write_i(it->element); + + if (++it != itEnd) + m_ostr << ','; + m_ostr << std::endl; + } + + --m_nTabDepth; + m_ostr << std::string(m_nTabDepth, '\t') << '}'; + } +} + +inline void Writer::Write_i(const Number& numberElement) +{ + m_ostr << std::setprecision(20) << numberElement.Value(); +} + +inline void Writer::Write_i(const Boolean& booleanElement) +{ + m_ostr << (booleanElement.Value() ? "true" : "false"); +} + +inline void Writer::Write_i(const String& stringElement) +{ + m_ostr << '"'; + + const std::string& s = stringElement.Value(); + std::string::const_iterator it(s.begin()), + itEnd(s.end()); + for (; it != itEnd; ++it) + { + switch (*it) + { + case '"': m_ostr << "\\\""; break; + case '\\': m_ostr << "\\\\"; break; + case '\b': m_ostr << "\\b"; break; + case '\f': m_ostr << "\\f"; break; + case '\n': m_ostr << "\\n"; break; + case '\r': m_ostr << "\\r"; break; + case '\t': m_ostr << "\\t"; break; + //case '\u': m_ostr << "\\u"; break; // uh... + default: m_ostr << *it; break; + } + } + + m_ostr << '"'; +} + +inline void Writer::Write_i(const Null& ) +{ + m_ostr << "null"; +} + +inline void Writer::Write_i(const UnknownElement& unknown) +{ + unknown.Accept(*this); +} + +inline void Writer::Visit(const Array& array) { Write_i(array); } +inline void Writer::Visit(const Object& object) { Write_i(object); } +inline void Writer::Visit(const Number& number) { Write_i(number); } +inline void Writer::Visit(const String& string) { Write_i(string); } +inline void Writer::Visit(const Boolean& boolean) { Write_i(boolean); } +inline void Writer::Visit(const Null& null) { Write_i(null); } + + + +} // End namespace diff --git a/src/libs/resiprocate/rutil/compat.hxx b/src/libs/resiprocate/rutil/compat.hxx new file mode 100644 index 00000000..8d7abfac --- /dev/null +++ b/src/libs/resiprocate/rutil/compat.hxx @@ -0,0 +1,258 @@ +#if !defined(RESIP_COMPAT_HXX) +#define RESIP_COMPAT_HXX + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +/** + @file + This file is used to handle compatibility fixes/tweaks so reSIProcate can + function on multiple platforms. +*/ + +#if defined(__INTEL_COMPILER ) && defined( __OPTIMIZE__ ) +# undef __OPTIMIZE__ // weird intel bug with ntohs and htons macros +#endif + +//#if defined(HAVE_SYS_INT_TYPES_H) +//#include <sys/int_types.h> +//#endif + +#ifdef TARGET_OS_MAC +# include <MacTypes.h> +#endif + +#include <cstring> + +#ifndef WIN32 +# include <netdb.h> +# include <sys/types.h> +# include <sys/time.h> +# include <sys/socket.h> +# include <sys/select.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <unistd.h> +# include <pthread.h> +# include <limits.h> +#endif + +#ifdef WIN32 +// !cj! TODO would be nice to remove this +# ifndef __GNUC__ +# pragma warning(disable : 4996) +# endif +#define WIN32_LEAN_AND_MEAN +# include <windows.h> +# include <winsock2.h> +#undef WIN32_LEAN_AND_MEAN +# include <errno.h> +# include <io.h> +#ifdef UNDER_CE +#include "wince/WceCompat.hxx" +#endif // UNDER_CE +#endif + +#if defined(__APPLE__) + // .amr. If you get linker or type conflicts around UInt32, then use this define +# if defined(RESIP_APPLE_USE_SYSTEM_TYPES) +# include <TargetConditionals.h> +# include <CoreServices/CoreServices.h> +# endif +# if !defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_2 + // you don't include the SDK or you're running 10.3 or above + // note: this will fail on 10.2 if you don't include the SDK +# include <arpa/nameser_compat.h> +# else + // you include the SDK and you're running Mac OS 10.2 or below + typedef int socklen_t; +# endif +# ifdef __MWERKS__ /* this is a <limits.h> bug filed with Apple, Radar# 3657629. */ +# ifndef __SCHAR_MAX__ +# define __SCHAR_MAX__ 127 +# endif +# endif +#endif + +#if defined(__SUNPRO_CC) +# if defined(_TIME_T) + using std::time_t; +# endif +# include <time.h> +# include <memory.h> +# include <string.h> +#endif + +#if !defined(T_NAPTR) +# define T_NAPTR 35 +#endif + +#if !defined(T_SRV) +# define T_SRV 33 +#endif + +#if !defined(T_AAAA) +# define T_AAAA 28 +#endif + +#if !defined(T_A) +# define T_A 1 +#endif + +namespace resip +{ + +#if defined(WIN32) || defined(__QNX__) +#ifndef strcasecmp +# define strcasecmp(a,b) stricmp(a,b) +#endif +#ifndef strncasecmp +# define strncasecmp(a,b,c) strnicmp(a,b,c) +#endif +#endif + +#if defined(__QNX__) || defined(__sun) || defined(WIN32) + typedef unsigned int u_int32_t; +#endif + +template<typename _Tp> +inline const _Tp& +resipMin(const _Tp& __a, const _Tp& __b) +{ + if (__b < __a) return __b; return __a; +} + +template<typename _Tp> +inline const _Tp& +resipMax(const _Tp& __a, const _Tp& __b) +{ + if (__a < __b) return __b; return __a; +} + +template<typename _Tp1, typename _Tp2> +inline const _Tp1 +resipIntDiv(const _Tp1& __a, const _Tp2& __b) +{ + // .bwc. Divide-round-nearest without using any floating-point. + if(__a%__b > __b/2) + { + return __a/__b+1; + } + + return __a/__b; +} + +} + +// Mac OS X: UInt32 definition conflicts with the Mac OS or iPhone OS SDK. +// If you've included either SDK then these will be defined. +#if !defined(TARGET_OS_MAC) && !defined(TARGET_OS_IPHONE) +typedef unsigned char UInt8; +typedef unsigned short UInt16; +typedef unsigned long UInt32; +#endif + +#if defined( WIN32 ) + typedef unsigned __int64 UInt64; +#else + typedef unsigned long long UInt64; +#endif +//typedef struct { unsigned char octet[16]; } UInt128; + +//template "levels; ie REASONABLE and COMPLETE +//reasonable allows most things such as partial template specialization, +//etc...like most compilers and VC++2003+. +//COMPLETE would allow template metaprogramming, template< template< > > tricks, +//etc...REASONABLE should always be defined when COMPLETE is defined. + +//#if !defined(__SUNPRO_CC) && !defined(__INTEL_COMPILER) +#if !defined(__INTEL_COMPILER) +# define REASONABLE_TEMPLATES +#endif + +// .bwc. This is the only place we check for USE_IPV6 in a header file. This +// code has no effect if USE_IPV6 is not set, so this should only kick in when +// we're building the resip libs. If someone sets USE_IPV6 while building +// against the resip libs, no resip header file will care. +#ifdef USE_IPV6 +#ifndef IPPROTO_IPV6 +#if(_WIN32_WINNT >= 0x0501) // Some versions of the windows SDK define IPPROTO_IPV6 differently - always enable IP v6 if USE_IPV6 and _WIN32_WINNT >= 0x0501 +# define IPPROTO_IPV6 ::IPPROTO_IPV6 +#else +#ifdef _MSC_VER +#define __STR2__(x) #x +#define __STR1__(x) __STR2__(x) +#define __LOC__ __FILE__ "("__STR1__(__LINE__)"): " +#pragma message (__LOC__ " IPv6 support requested, but IPPROTO_V6 undefined; this platform does not appear to support IPv6 ") +#else +# ifndef __ANDROID_API__ +# warning IPv6 support requested, but IPPROTO_IPV6 undefined; this platform does not appear to support IPv6 +# else +# define IPPROTO_IPV6 ::IPPROTO_IPV6 +# endif +#endif +// .bwc. Don't do this; someone might have defined it for their own code. +// #undef USE_IPV6 +#endif +#endif +#endif + +// !bwc! Some poking around seems to indicate that icc supports gcc's function +// attributes, at least as far back as version 8. I have no idea what support is +// like prior to that. As for SUNPRO, it uses gcc's frontend, so I would expect +// gnu-c function attributes to work, but does it define __GNUC__? +#if defined(__GNUC__) || (__INTEL_COMPILER > 800) +#define RESIP_DEPRECATED(x) x __attribute__ ((deprecated)) +#elif defined(_MSC_VER) +#define RESIP_DEPRECATED(x) __declspec(deprecated) x +#else +#define RESIP_DEPRECATED(x) x +#endif + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + */ diff --git a/src/libs/resiprocate/rutil/dns/AresCompat.hxx b/src/libs/resiprocate/rutil/dns/AresCompat.hxx new file mode 100644 index 00000000..b9cbaaef --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/AresCompat.hxx @@ -0,0 +1,68 @@ +#if !defined(RESIP_ARES_COMPAT_HXX) +#define RESIP_ARES_COMPAT_HXX + +#include "ares.h" +#include "ares_dns.h" +#include "ares_version.h" +#ifdef WIN32 +#undef write // Note: ares.h defines write to be _write for WIN32 - we don't want that here, since we use fdset.write and stream write +#endif + +#ifdef ARES_VERSION_MAJOR +// c-ares +#if ARES_VERSION_MAJOR < 1 || (ARES_VERSION_MAJOR == 1 && ARES_VERSION_MINOR < 6) +#error Need c-ares >= 1.6 +#endif +#endif + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/AresDns.cxx b/src/libs/resiprocate/rutil/dns/AresDns.cxx new file mode 100644 index 00000000..403b6e5a --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/AresDns.cxx @@ -0,0 +1,732 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if !defined(WIN32) +#include <sys/types.h> +#endif +#include <time.h> + +#include "rutil/dns/AresDns.hxx" +#include "rutil/GenericIPAddress.hxx" + +#include "AresCompat.hxx" +#if !defined(USE_CARES) +#include "ares_private.h" +#endif + +#include "rutil/Logger.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/WinLeakCheck.hxx" +#include "rutil/FdPoll.hxx" + +#if !defined(WIN32) +#if !defined(__CYGWIN__) +#include <arpa/nameser.h> +#endif +#endif + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS + +/********************************************************************** + * + * class AresDnsPollItem + * + * This is callback class used for epoll-based systems. + * + **********************************************************************/ + +#ifndef USE_CARES +namespace resip +{ + +class AresDnsPollItem : public FdPollItemBase +{ + public: + AresDnsPollItem(FdPollGrp *grp, int fd, AresDns& aresObj, + ares_channel chan, int server_idx) + : FdPollItemBase(grp, fd, FPEM_Read), mAres(aresObj), + mChannel(chan), mFd(fd), mServerIdx(server_idx) + { + } + + virtual void processPollEvent(FdPollEventMask mask); + void resetPollGrp(FdPollGrp *grp) + { + if (mPollGrp) + mPollGrp->delPollItem(mPollHandle); + mPollGrp = grp; + if (mPollGrp) + mPollHandle = mPollGrp->addPollItem(mFd, FPEM_Read, this); + } + + AresDns& mAres; + ares_channel mChannel; + int mFd; + int mServerIdx; + + static void socket_poll_cb(void *cb_data, + ares_channel channel, int server_idx, + int fd, ares_poll_action_t act); +}; + +}; + +void +AresDnsPollItem::processPollEvent(FdPollEventMask mask) +{ + assert( (mask&(FPEM_Read|FPEM_Write))!= 0 ); + + time_t nowSecs; + time(&nowSecs); /// maybe nice if this was passed into us? + + ares_process_poll(mChannel, mServerIdx, + (mask&FPEM_Read)?(int)mPollSocket:-1, (mask&FPEM_Write)?(int)mPollSocket:-1, + nowSecs); +} + +/** + C-function called by ares whenever it opens, closes or changes + interest in writability. +**/ + +void +AresDnsPollItem::socket_poll_cb(void *cb_data, + ares_channel channel, int server_idx, + int fd, ares_poll_action_t act) +{ + AresDns *ares = static_cast<AresDns*>(cb_data); + //assert( ares ); + FdPollGrp *grp = ares->mPollGrp; + //assert( grp ); + AresDnsPollItem *olditem = ares->mPollItems.at(server_idx); + if ( olditem ) + { + assert( olditem->mChannel==channel ); + assert( olditem->mServerIdx==server_idx ); + } + switch ( act ) + { + case ARES_POLLACTION_OPEN: + assert( olditem==NULL ); + assert( fd!=INVALID_SOCKET ); + ares->mPollItems[server_idx] = new AresDnsPollItem( grp, fd, *ares, channel, server_idx); + break; + case ARES_POLLACTION_CLOSE: + assert( olditem ); + ares->mPollItems[server_idx] = NULL; + delete olditem; // destructor removes from poll + break; + case ARES_POLLACTION_WRITEON: + assert( olditem ); + grp->modPollItem(olditem->mPollHandle, FPEM_Read|FPEM_Write); + break; + case ARES_POLLACTION_WRITEOFF: + assert( olditem ); + grp->modPollItem(olditem->mPollHandle, FPEM_Read); + break; + default: + assert( 0 ); + } +} + +#endif + +/********************************************************************** + * + * class AresDns + * + **********************************************************************/ + +volatile bool AresDns::mHostFileLookupOnlyMode = false; + +void +AresDns::setPollGrp(FdPollGrp *grp) +{ +#ifdef USE_CARES + if(mPollGrp) + { + mPollGrp->unregisterFdSetIOObserver(*this); + } + mPollGrp=grp; + if(mPollGrp) + { + mPollGrp->registerFdSetIOObserver(*this); + } +#else + for(std::vector<AresDnsPollItem*>::iterator i=mPollItems.begin(); + i!=mPollItems.end(); ++i) + { + if(*i) + { + (*i)->resetPollGrp(grp); + } + } + mPollGrp = grp; +#endif +} + +int +AresDns::init(const std::vector<GenericIPAddress>& additionalNameservers, + AfterSocketCreationFuncPtr socketfunc, + int timeout, + int tries, + unsigned int features) +{ + mAdditionalNameservers = additionalNameservers; + mFeatures = features; + + int ret = internalInit(additionalNameservers, + socketfunc, + features, + &mChannel, + timeout, + tries); + + if (ret != Success) + return ret; + +#ifdef WIN32 + // For windows OSs it is uncommon to run a local DNS server. Therefor if there + // are no defined DNS servers in windows networking and ARES just returned the + // loopback address (ie. default localhost server / named) + // then put resip DNS resolution into hostfile lookup only mode + if(mChannel->nservers == 1 && + mChannel->servers[0].default_localhost_server) + { + // enable hostfile only lookup mode + mHostFileLookupOnlyMode = true; + } + else + { + // disable hostfile only lookup mode + mHostFileLookupOnlyMode = false; + } +#endif + + return Success; +} + +int +AresDns::internalInit(const std::vector<GenericIPAddress>& additionalNameservers, + AfterSocketCreationFuncPtr socketfunc, + unsigned int features, + ares_channeldata** channel, + int timeout, + int tries +) +{ + if(*channel) + { +#if defined(USE_ARES) + ares_destroy_suppress_callbacks(*channel); +#elif defined(USE_CARES) + // Callbacks will be supressed by looking for the ARES_EDESTRUCTION + // sentinel status + ares_destroy(*channel); +#endif + *channel = 0; + } + +#if defined(USE_ARES) + +#ifdef USE_IPV6 + int requiredCap = ARES_CAP_IPV6; +#else + int requiredCap = 0; +#endif + + // Only the contrib/ares has this function + int cap = ares_capabilities(requiredCap); + if (cap != requiredCap) + { + ErrLog (<< "Build mismatch (ipv4/ipv6) problem in ares library"); // !dcm! + return BuildMismatch; + } +#endif + + int status; + ares_options opt; + int optmask = 0; + + memset(&opt, '\0', sizeof(opt)); + +#if defined(USE_ARES) + // TODO: What is this and how does it map to c-ares? + if ((features & ExternalDns::TryServersOfNextNetworkUponRcode3)) + { + optmask |= ARES_OPT_FLAGS; + opt.flags |= ARES_FLAG_TRY_NEXT_SERVER_ON_RCODE3; + } +#endif + +#if defined(USE_CARES) + // In c-ares, we can actually set the timeout and retries via the API + if (timeout > 0) + { + opt.timeout = timeout; + optmask |= ARES_OPT_TIMEOUT; + } + + if (tries > 0) + { + opt.tries = tries; + optmask |= ARES_OPT_TRIES; + } +#endif + + if (additionalNameservers.empty()) + { +#if defined(USE_ARES) + status = ares_init_options_with_socket_function(channel, &opt, optmask, socketfunc); +#elif defined(USE_CARES) + // TODO: Does the socket function matter? + status = ares_init_options(channel, &opt, optmask); +#endif + } + else + { + optmask |= ARES_OPT_SERVERS; + opt.nservers = (int)additionalNameservers.size(); + +#if defined(USE_IPV6) && defined(USE_ARES) + // With contrib/ares, you can configure IPv6 addresses for the + // nameservers themselves. + opt.servers = new multiFamilyAddr[additionalNameservers.size()]; + for (size_t i =0; i < additionalNameservers.size(); i++) + { + if (additionalNameservers[i].isVersion4()) + { + opt.servers[i].family = AF_INET; + opt.servers[i].addr = additionalNameservers[i].v4Address.sin_addr; + } + else + { + opt.servers[i].family = AF_INET6; + opt.servers[i].addr6 = additionalNameservers[i].v6Address.sin6_addr; + } + } +#else + // If we're only supporting IPv4 or we are using c-ares, we can't + // support additional nameservers that are IPv6 right now. + opt.servers = new in_addr[additionalNameservers.size()]; + for (size_t i =0; i < additionalNameservers.size(); i++) + { + if(additionalNameservers[i].isVersion4()) + { + opt.servers[i] = additionalNameservers[i].v4Address.sin_addr; + } + else + { +#if defined(USE_CARES) + WarningLog (<< "Ignoring non-IPv4 additional name server (not yet supported with c-ares)"); +#elif defined(USE_ARES) + WarningLog (<< "Ignoring non-IPv4 additional name server (IPv6 support was not enabled)"); +#endif + } + } +#endif + +#if defined(USE_ARES) + status = ares_init_options_with_socket_function(channel, &opt, optmask, socketfunc); +#elif defined(USE_CARES) + // TODO: Does the socket function matter? + status = ares_init_options(channel, &opt, optmask); +#endif + + delete [] opt.servers; + opt.servers = 0; + } + if (status != ARES_SUCCESS) + { + ErrLog (<< "Failed to initialize DNS library (status=" << status << ")"); + return status; + } + else + { + +#if defined(USE_ARES) + + InfoLog(<< "DNS initialization: found " << (*channel)->nservers << " name servers"); + for (int i = 0; i < (*channel)->nservers; ++i) + { +#ifdef USE_IPV6 + if((*channel)->servers[i].family == AF_INET6) + { + InfoLog(<< " name server: " << DnsUtil::inet_ntop((*channel)->servers[i].addr6)); + } + else +#endif + { + InfoLog(<< " name server: " << DnsUtil::inet_ntop((*channel)->servers[i].addr)); + } + } + + // In ares, we must manipulate these directly + if (timeout > 0) + { + mChannel->timeout = timeout; + } + + if (tries > 0) + { + mChannel->tries = tries; + } + +#ifndef USE_CARES + if ( mPollGrp ) + { + // expand vector to hold {nservers} and init to NULL + mPollItems.insert( mPollItems.end(), (*channel)->nservers, (AresDnsPollItem*)0); + // tell ares to let us know when things change + ares_process_set_poll_cb(mChannel, AresDnsPollItem::socket_poll_cb, this); + } +#endif + +#elif defined(USE_CARES) + { + // Log which version of c-ares we're using + InfoLog(<< "DNS initialization: using c-ares v" + << ::ares_version(NULL)); + + // Ask for the current configuration so we can print the servers found + struct ares_options options; + std::memset(&options, 0, sizeof(options)); + int ignored; + if(ares_save_options(*channel, &options, &ignored) == ARES_SUCCESS) + { + InfoLog(<< "DNS initialization: found " + << options.nservers << " name servers"); + + // Log them all + for (int i = 0; i < options.nservers; ++i) + { + InfoLog(<< " name server: " + << DnsUtil::inet_ntop(options.servers[i])); + } + ares_destroy_options(&options); + } + } +#endif + + return Success; + } +} + +bool AresDns::checkDnsChange() +{ + // We must return 'true' if there are changes in the list of DNS servers + struct ares_channeldata* channel = 0; + bool bRet = false; + int result = internalInit(mAdditionalNameservers, 0, mFeatures, &channel); + if(result != Success || channel == 0) + { + // It has changed because it failed, I suppose + InfoLog(<< " DNS server list changed"); + return true; + } + +#if defined(USE_ARES) + { + // Compare the two lists. Are they different sizes? + if(mChannel->nservers != channel->nservers) + { + // Yes, so they're different + bRet = true; + } + else + { + // Compare them one-by-one + for (int i = 0; i < mChannel->nservers; ++i) + { + if (mChannel->servers[i].addr.s_addr + != channel->servers[i].addr.s_addr) + { + bRet = true; + break; + } + } + } + + // Destroy the secondary configuration we read + ares_destroy_suppress_callbacks(channel); + } +#elif defined(USE_CARES) + { + // Get the options, including the server list, from the old and the + // current (i.e. just read) configuration. + struct ares_options old; + struct ares_options updated; + std::memset(&old, 0, sizeof(old)); + std::memset(&updated, 0, sizeof(updated)); + int ignored; + + // Can we get the configuration? + if(ares_save_options(mChannel, &old, &ignored) != ARES_SUCCESS + || ares_save_options(channel, &updated, &ignored) != ARES_SUCCESS) + { + // It failed, so call it different + bRet = true; + } + else + { + // Compare the two lists. Are they different sizes? + if(old.nservers != updated.nservers) + { + // Yes, so they're different + bRet = true; + } + else + { + // Compare them one-by-one + for (int i = 0; i < old.nservers; ++i) + { + if (old.servers[i].s_addr != updated.servers[i].s_addr) + { + bRet = true; + break; + } + } + } + + // Free any ares_options contents we have created. + ares_destroy_options(&old); + ares_destroy_options(&updated); + } + + // Destroy the secondary configuration we read + ares_destroy(channel); + } +#endif + + // Report on the results + if(!bRet) + { + InfoLog(<< " No changes in DNS server list"); + } + else + { + InfoLog(<< " DNS server list changed"); + } + + return bRet; +} + +AresDns::~AresDns() +{ +#if defined(USE_ARES) + ares_destroy_suppress_callbacks(mChannel); +#elif defined(USE_CARES) + ares_destroy(mChannel); +#endif +} + +bool AresDns::hostFileLookup(const char* target, in_addr &addr) +{ + assert(target); + + hostent *hostdata = 0; + + // Look this up + int status = +#if defined(USE_ARES) + hostfile_lookup(target, &hostdata) +#elif defined(USE_CARES) + ares_gethostbyname_file(mChannel, target, AF_INET, &hostdata) +#endif + ; + + if (status != ARES_SUCCESS) + { + DebugLog(<< "hostFileLookup failed for " << target); + return false; + } + sockaddr_in saddr; + memset(&saddr,0,sizeof(saddr)); /* Initialize sockaddr fields. */ + saddr.sin_family = AF_INET; + memcpy((char *)&(saddr.sin_addr.s_addr),(char *)hostdata->h_addr_list[0], (size_t)hostdata->h_length); + addr = saddr.sin_addr; +#if defined(USE_ARES) + // for resip-ares, the hostdata (and its contents) is dynamically allocated + ares_free_hostent(hostdata); +#endif + + DebugLog(<< "hostFileLookup succeeded for " << target); + return true; +} + +ExternalDnsHandler* +AresDns::getHandler(void* arg) +{ + Payload* p = reinterpret_cast<Payload*>(arg); + ExternalDnsHandler *thisp = reinterpret_cast<ExternalDnsHandler*>(p->first); + return thisp; +} + +ExternalDnsRawResult +AresDns::makeRawResult(void *arg, int status, unsigned char *abuf, int alen) +{ + Payload* p = reinterpret_cast<Payload*>(arg); + void* userArg = reinterpret_cast<void*>(p->second); + + if (status != ARES_SUCCESS) + { + return ExternalDnsRawResult(status, abuf, alen, userArg); + } + else + { + return ExternalDnsRawResult(abuf, alen, userArg); + } +} + +unsigned int +AresDns::getTimeTillNextProcessMS() +{ + struct timeval tv; + tv.tv_sec = 1; tv.tv_usec = 0; + ares_timeout(mChannel, NULL, &tv); + return tv.tv_sec*1000 + tv.tv_usec / 1000; +} + +void +AresDns::buildFdSet(fd_set& read, fd_set& write, int& size) +{ + int newsize = ares_fds(mChannel, &read, &write); + if ( newsize > size ) + { + size = newsize; + } +} + +void +AresDns::processTimers() +{ +#ifdef USE_CARES + return; +#else + assert( mPollGrp!=0 ); + time_t timeSecs; + time(&timeSecs); + ares_process_poll(mChannel, /*server*/-1, /*rd*/-1, /*wr*/-1, timeSecs); +#endif +} + +void +AresDns::process(FdSet& fdset) +{ + process(fdset.read, fdset.write); +} + +void +AresDns::buildFdSet(FdSet& fdset) +{ + buildFdSet(fdset.read, fdset.write, fdset.size); +} + +void +AresDns::process(fd_set& read, fd_set& write) +{ + ares_process(mChannel, &read, &write); +} + +char* +AresDns::errorMessage(long errorCode) +{ + const char* aresMsg = ares_strerror(errorCode); + + size_t len = strlen(aresMsg); + char* errorString = new char[len+1]; + + strncpy(errorString, aresMsg, len); + errorString[len] = '\0'; + return errorString; +} + +void +AresDns::lookup(const char* target, unsigned short type, ExternalDnsHandler* handler, void* userData) +{ + ares_query(mChannel, target, C_IN, type, +#if defined(USE_ARES) + resip_AresDns_aresCallback, +#elif defined(USE_CARES) + resip_AresDns_caresCallback, +#endif + new Payload(handler, userData)); +} + +void +resip_AresDns_aresCallback(void *arg, int status, unsigned char *abuf, int alen) +{ +#if defined(USE_CARES) + // If this is destruction, skip it. We do this here for completeness. + if(status == ARES_EDESTRUCTION) + { + return; + } +#endif + + resip::AresDns::getHandler(arg)->handleDnsRaw(resip::AresDns::makeRawResult(arg, status, abuf, alen)); + resip::AresDns::Payload* p = reinterpret_cast<resip::AresDns::Payload*>(arg); + delete p; +} + +void +resip_AresDns_caresCallback(void *arg, int status, int timeouts, + unsigned char *abuf, int alen) +{ + // Simply ignore the timeouts argument + return ::resip_AresDns_aresCallback(arg, status, abuf, alen); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/dns/AresDns.hxx b/src/libs/resiprocate/rutil/dns/AresDns.hxx new file mode 100644 index 00000000..11a57949 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/AresDns.hxx @@ -0,0 +1,137 @@ +#if !defined(RESIP_ARES_DNS_HXX) +#define RESIP_ARES_DNS_HXX + +#include "rutil/FdSetIOObserver.hxx" +#include "rutil/GenericIPAddress.hxx" +#include "rutil/dns/ExternalDns.hxx" + +extern "C" +{ +struct ares_channeldata; +} + +//struct fd_set; + +extern "C" { + void resip_AresDns_aresCallback(void *arg, int status, unsigned char* abuf, int alen); + void resip_AresDns_caresCallback(void *arg, int status, int timeouts, unsigned char* abuf, int alen); +} + +namespace resip +{ +class AresDnsPollItem; +class FdPollGrp; + +class AresDns : public ExternalDns, public FdSetIOObserver +{ + friend class AresDnsPollItem; + public: + AresDns() {mChannel = 0; mFeatures = 0; mPollGrp=NULL;} + virtual ~AresDns(); + + virtual int init(const std::vector<GenericIPAddress>& additionalNameservers, + AfterSocketCreationFuncPtr socketfunc, int timeout=0, int tries=0, unsigned int features=0); + + int internalInit(const std::vector<GenericIPAddress>& additionalNameservers, + AfterSocketCreationFuncPtr socketfunc, unsigned int features=0, ares_channeldata** channel = 0, int timeout=0, int tries=0); + + virtual bool checkDnsChange(); + + virtual unsigned int getTimeTillNextProcessMS(); + virtual void process(FdSet& fdset); + virtual void buildFdSet(FdSet& fdset); + + virtual void buildFdSet(fd_set& read, fd_set& write, int& size); + virtual void process(fd_set& read, fd_set& write); + + virtual void setPollGrp(FdPollGrp *pollGrp); + virtual void processTimers(); + + //?dcm? I believe these need to do nothing in the ARES case. + virtual void freeResult(ExternalDnsRawResult /* res */) {} + virtual void freeResult(ExternalDnsHostResult /* res */) {} + + virtual char* errorMessage(long errorCode); + + void lookup(const char* target, unsigned short type, ExternalDnsHandler* handler, void* userData); + + virtual bool hostFileLookup(const char* target, in_addr &addr); + virtual bool hostFileLookupLookupOnlyMode() { return mHostFileLookupOnlyMode; } + static void enableHostFileLookupOnlyMode(bool enable) { mHostFileLookupOnlyMode = enable; } + + friend void ::resip_AresDns_aresCallback(void *arg, int status, unsigned char* abuf, int alen); + friend void ::resip_AresDns_caresCallback(void *arg, int status, int timeouts, unsigned char* abuf, int alen); + + // used for epoll() interface to ares lib + // time_t mNow; + + private: + + typedef std::pair<ExternalDnsHandler*, void*> Payload; + static ExternalDnsRawResult makeRawResult(void *arg, int status, unsigned char *abuf, int alen); + static ExternalDnsHandler* getHandler(void* arg); + struct ares_channeldata* mChannel; + std::vector<GenericIPAddress> mAdditionalNameservers; + unsigned int mFeatures; + volatile static bool mHostFileLookupOnlyMode; + + FdPollGrp* mPollGrp; + std::vector<AresDnsPollItem*> mPollItems; + +}; + +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/dns/DnsAAAARecord.cxx b/src/libs/resiprocate/rutil/dns/DnsAAAARecord.cxx new file mode 100644 index 00000000..83a93963 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsAAAARecord.cxx @@ -0,0 +1,115 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "AresCompat.hxx" + +#ifndef __CYGWIN__ +#ifndef RRFIXEDSZ +#define RRFIXEDSZ 10 +#endif +#ifndef NS_RRFIXEDSZ +#define NS_RRFIXEDSZ 10 +#endif +#endif + +#include <stdlib.h> + +#include "rutil/Socket.hxx" +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/dns/RROverlay.hxx" +#include "rutil/dns/DnsResourceRecord.hxx" +#include "rutil/dns/DnsAAAARecord.hxx" + +using namespace resip; + +DnsAAAARecord::DnsAAAARecord(const RROverlay& overlay) +{ +#ifdef USE_IPV6 + char* name = 0; + long len = 0; + ares_expand_name(overlay.data()-overlay.nameLength()-RRFIXEDSZ, overlay.msg(), overlay.msgLength(), &name, &len); + mName = name; + free(name); + memcpy(&mAddr, overlay.data(), sizeof(in6_addr)); +#else + assert(0); +#endif +} + +bool DnsAAAARecord::isSameValue(const Data& value) const +{ +#ifdef USE_IPV6 + return DnsUtil::inet_ntop(mAddr) == value; +#else + assert(0); + return false; +#endif +} + +EncodeStream& +DnsAAAARecord::dump(EncodeStream& strm) const +{ +#ifdef USE_IPV6 + strm << mName << " (AAAA) --> " << DnsUtil::inet_ntop(mAddr); + return strm; +#else + assert(0); + strm << " (AAAA) --> ? (IPV6 is disabled in this library, what " + "happened here?)"; + return strm; +#endif +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/dns/DnsAAAARecord.hxx b/src/libs/resiprocate/rutil/dns/DnsAAAARecord.hxx new file mode 100644 index 00000000..bb90e5cb --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsAAAARecord.hxx @@ -0,0 +1,96 @@ +#ifndef RESIP_DNS_AAAA_RECORD +#define RESIP_DNS_AAAA_RECORD + +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/dns/DnsResourceRecord.hxx" + +#ifndef WIN32 +#include <netinet/in.h> +#else +#include <Ws2tcpip.h> +#endif + +namespace resip +{ + +class RROverlay; + +class DnsAAAARecord : public DnsResourceRecord +{ + public: + DnsAAAARecord(const RROverlay& overlay); + virtual ~DnsAAAARecord() {} + +#ifdef IPPROTO_IPV6 + const struct in6_addr& v6Address() const { return mAddr; } +#endif + + virtual const Data& name() const { return mName; } + virtual bool isSameValue(const Data& value) const; + EncodeStream& dump(EncodeStream& strm) const; + + private: + union + { +#ifdef IPPROTO_IPV6 + struct in6_addr mAddr; +#endif + char pad[28]; // this make union same size if v6 is in or out + }; + Data mName; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/DnsCnameRecord.cxx b/src/libs/resiprocate/rutil/dns/DnsCnameRecord.cxx new file mode 100644 index 00000000..1a0db737 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsCnameRecord.cxx @@ -0,0 +1,107 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <stdlib.h> + +#include "AresCompat.hxx" + +#ifndef __CYGWIN__ +#ifndef RRFIXEDSZ +#define RRFIXEDSZ 10 +#endif +#ifndef NS_RRFIXEDSZ +#define NS_RRFIXEDSZ 10 +#endif +#endif + +#include "rutil/Data.hxx" +#include "rutil/BaseException.hxx" +#include "RROverlay.hxx" +#include "DnsResourceRecord.hxx" +#include "DnsCnameRecord.hxx" + +using namespace resip; + +DnsCnameRecord::DnsCnameRecord(const RROverlay& overlay) +{ + char* name = 0; + long len = 0; + if (ARES_SUCCESS != ares_expand_name(overlay.data()-overlay.nameLength()-RRFIXEDSZ, overlay.msg(), overlay.msgLength(), &name, &len)) + { + throw CnameException("Failed parse of CNAME record", __FILE__, __LINE__); + } + mName = name; + free(name); + + if (ARES_SUCCESS != ares_expand_name(overlay.data(), overlay.msg(), overlay.msgLength(), &name, &len)) + { + throw CnameException("Failed parse of CNAME record", __FILE__, __LINE__); + } + + mCname = name; + free(name); +} + +bool DnsCnameRecord::isSameValue(const Data& value) const +{ + return mCname==value; +} + +EncodeStream& +DnsCnameRecord::dump(EncodeStream& strm) const +{ + strm << mName << " (CNAME) --> " << mCname; + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/dns/DnsCnameRecord.hxx b/src/libs/resiprocate/rutil/dns/DnsCnameRecord.hxx new file mode 100644 index 00000000..789ff04f --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsCnameRecord.hxx @@ -0,0 +1,95 @@ +#ifndef RESIP_DNS_CNAME_RECORD +#define RESIP_DNS_CNAME_RECORD + +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/dns/DnsResourceRecord.hxx" +#include "rutil/BaseException.hxx" + +namespace resip +{ + +class RROverlay; + +class DnsCnameRecord : public DnsResourceRecord +{ + public: + class CnameException : public BaseException + { + public: + CnameException(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) + { + } + + const char* name() const { return "CnameException"; } + }; + + DnsCnameRecord(const RROverlay&); + ~DnsCnameRecord() {} + + // accessors. + const Data& cname() const { return mCname; } + const Data& name() const { return mName; } + bool isSameValue(const Data&) const; + EncodeStream& dump(EncodeStream& strm) const; + + private: + Data mCname; + Data mName; +}; + +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/DnsHandler.hxx b/src/libs/resiprocate/rutil/dns/DnsHandler.hxx new file mode 100644 index 00000000..61135f7c --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsHandler.hxx @@ -0,0 +1,74 @@ +#if !defined (RESIP_DNS_HANDLER_HXX) +#define RESIP_DNS_HANDLER_HXX + +namespace resip +{ + +class DnsResult; +class TransactionState; +class Uri; + +class DnsHandler +{ + public: + virtual ~DnsHandler()=0; + + // call when dns entries are available (or nothing found) + // this may be called synchronously with the call to lookup + virtual void handle(DnsResult* result)=0; + virtual void rewriteRequest(const Uri& uri)=0; +}; + +} + + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/DnsHostRecord.cxx b/src/libs/resiprocate/rutil/dns/DnsHostRecord.cxx new file mode 100644 index 00000000..631ead81 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsHostRecord.cxx @@ -0,0 +1,105 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <stdlib.h> + +#include "AresCompat.hxx" + +#ifndef __CYGWIN__ +#ifndef RRFIXEDSZ +#define RRFIXEDSZ 10 +#endif +#ifndef NS_RRFIXEDSZ +#define NS_RRFIXEDSZ 10 +#endif +#endif + +#include "rutil/Data.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/BaseException.hxx" +#include "RROverlay.hxx" +#include "DnsResourceRecord.hxx" +#include "DnsHostRecord.hxx" + +using namespace resip; + +DnsHostRecord::DnsHostRecord(const RROverlay& overlay) +{ + char* name = 0; + long len = 0; + int status = ares_expand_name(overlay.data()-overlay.nameLength()-RRFIXEDSZ, overlay.msg(), overlay.msgLength(), &name, &len); + (void)status; + assert(status == ARES_SUCCESS); // .kw. what should we do if bad? + mName = name; + free(name); + memcpy(&mAddr, overlay.data(), sizeof(in_addr)); +} + +Data DnsHostRecord::host() const +{ + return Data(inet_ntoa(mAddr)); +} + +bool DnsHostRecord::isSameValue(const Data& value) const +{ + return DnsUtil::inet_ntop(mAddr) == value; +} + +EncodeStream& +DnsHostRecord::dump(EncodeStream& strm) const +{ + strm << mName << "(A)--> " << DnsUtil::inet_ntop(mAddr); + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/dns/DnsHostRecord.hxx b/src/libs/resiprocate/rutil/dns/DnsHostRecord.hxx new file mode 100644 index 00000000..ff49f3d2 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsHostRecord.hxx @@ -0,0 +1,89 @@ +#ifndef RESIP_DNS_HOST_RECORD +#define RESIP_DNS_HOST_RECORD + +#include <iosfwd> + +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/dns/DnsResourceRecord.hxx" + + +namespace resip +{ + +class DnsResourceRecord; +class RROverlay; + +class DnsHostRecord : public DnsResourceRecord +{ + public: + DnsHostRecord(const RROverlay&); + DnsHostRecord(const Data name, const in_addr addr): mAddr(addr), mName(name){}; + ~DnsHostRecord() {} + + // accessors. + Data host() const; + in_addr addr() const { return mAddr; } + const Data& name() const { return mName; } + bool isSameValue(const Data& value) const; + EncodeStream& dump(EncodeStream& strm) const; + + private: + in_addr mAddr; + Data mName; +}; + +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/DnsNaptrRecord.cxx b/src/libs/resiprocate/rutil/dns/DnsNaptrRecord.cxx new file mode 100644 index 00000000..5c2ff31c --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsNaptrRecord.cxx @@ -0,0 +1,211 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <stdlib.h> + +#include "AresCompat.hxx" + +#ifndef __CYGWIN__ +#ifndef RRFIXEDSZ +#define RRFIXEDSZ 10 +#endif +#ifndef NS_RRFIXEDSZ +#define NS_RRFIXEDSZ 10 +#endif +#endif + +#include "rutil/Data.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/dns/RROverlay.hxx" +#include "rutil/dns/DnsResourceRecord.hxx" +#include "rutil/dns/DnsNaptrRecord.hxx" + +using namespace resip; +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS + +DnsNaptrRecord::RegExp::RegExp() +{ +} + +DnsNaptrRecord::RegExp::RegExp(const Data& data) +{ + if (data.size() > 1) + { + ParseBuffer pb(data, "DnsNaptrRecord::RegExp parser"); + + const char delim = data[0]; + const char* start = pb.skipChar(delim); + pb.skipToChar(delim); + + pb.data(mRegexp, start); + start = pb.skipChar(delim); + pb.skipToChar(delim); + pb.data(mReplacement, start); + start = pb.skipChar(delim); + // .kw. start above is not used -- what is going on here? + // should above code be in #if block below? + +#if 0 + //pb.data(mFlags, start); + + if (regcomp(&mRe, mRegexp.c_str(), REG_EXTENDED) != 0) + { + // couldn't parse input regexp so ignore it + mRegexp.clear(); + } +#endif + } +} + +DnsNaptrRecord::RegExp::~RegExp() +{ + //regfree(&mRe); +} + + +bool +DnsNaptrRecord::RegExp::empty() const +{ + return mRegexp.empty(); +} + +const Data& +DnsNaptrRecord::RegExp::regexp() const +{ + return mRegexp; +} + +const Data& +DnsNaptrRecord::RegExp::replacement() const +{ + return mReplacement; +} + +Data +DnsNaptrRecord::RegExp::apply(const Data& input) const +{ + // !jf! should be doing a real regexp here + //regmatch_t matches[10]; + //regexec(&mRe, input.c_str(), 10, matches, 0); + + return mReplacement; +} + +DnsNaptrRecord::DnsNaptrRecord(const RROverlay& overlay) +{ + char* name = 0; + long len = 0; + if (ARES_SUCCESS != ares_expand_name(overlay.data()-overlay.nameLength()-RRFIXEDSZ, overlay.msg(), overlay.msgLength(), &name, &len)) + { + throw NaptrException("Failed parse of NAPTR record", __FILE__, __LINE__); + } + mName = name; + free(name); + + mOrder = DNS__16BIT(overlay.data()); + mPreference = DNS__16BIT(overlay.data() + 2); + const unsigned char* pPos = overlay.data() + 4; + len = *pPos; + + if (pPos + len + 1 > overlay.data() + overlay.dataLength()) + { + throw NaptrException("Failed parse of NAPTR record", __FILE__, __LINE__); + } + + mFlags = Data(pPos + 1, len); + pPos += len + 1; + len = *pPos; + + if (pPos + len + 1 > overlay.data() + overlay.dataLength()) + { + throw NaptrException("Failed parse of NAPTR record", __FILE__, __LINE__); + } + mService = Data(pPos + 1, len); + pPos += len + 1; + len = *pPos; + + if (pPos + len + 1 > overlay.data() + overlay.dataLength()) + { + throw NaptrException("Failed parse of NAPTR record", __FILE__, __LINE__); + } + Data regexp(pPos + 1, len); + pPos += len + 1; + mRegexp = DnsNaptrRecord::RegExp(regexp); + InfoLog (<< "regexp=" << mRegexp.regexp() << " rep=" << mRegexp.replacement()); + + if (pPos[0] != 0) + { + if (ARES_SUCCESS != ares_expand_name(pPos, overlay.msg(), overlay.msgLength(), &name, &len)) + { + throw NaptrException("Failed parse of NAPTR record", __FILE__, __LINE__); + } + mReplacement = name; + free(name); + } +} + +bool DnsNaptrRecord::isSameValue(const Data& value) const +{ + return mReplacement == value; +} + +EncodeStream& +DnsNaptrRecord::dump(EncodeStream& strm) const +{ + strm << mName << " (NAPTR)--> o=" << mOrder << " p=" << mPreference; + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/dns/DnsNaptrRecord.hxx b/src/libs/resiprocate/rutil/dns/DnsNaptrRecord.hxx new file mode 100644 index 00000000..b8b5fd5a --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsNaptrRecord.hxx @@ -0,0 +1,144 @@ +#ifndef RESIP_DNS_NAPTR_RECORD +#define RESIP_DNS_NAPTR_RECORD + +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/dns/DnsResourceRecord.hxx" + +namespace resip +{ + +class Data; +class DnsResourceRecord; +class RROverlay; +class BaseException; + +class DnsNaptrRecord : public DnsResourceRecord +{ + public: + class NaptrException : public BaseException + { + public: + NaptrException(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) + { + } + + const char* name() const { return "NaptrException"; } + }; + + class RegExp + { + public: + // Takes a regexp expression as defined in rfc 2915 (section 3 + // Substitution Expression Grammar) The delimiter is whatever + // appears in the first character. This can be empty. + RegExp(const Data& data); + RegExp(); + ~RegExp(); + + bool empty() const; + + // Convenience method provided for access to the antecedent of the + // regexp (the matching regular expression) + const Data& regexp() const; + + // Convenience method provided for access to the consequent of the + // regexp (the replacement) - this must be a URI + const Data& replacement() const; + + // Applies the regular expression substitution based on the input + // string. Will return Data::Empty if the input does not match the + // substitution. + Data apply(const Data& input) const; + + private: + Data mRegexp; + Data mReplacement; + Data flags; + //regex_t mRe; + }; + + + DnsNaptrRecord() : mOrder(-1), mPreference(-1) {} + DnsNaptrRecord(const RROverlay&); + ~DnsNaptrRecord() {} + + // accessors. + int order() const { return mOrder; } + int& order() { return mOrder; } + int preference() const { return mPreference; } + const Data& flags() const { return mFlags; } + const Data& service() const { return mService; } + const RegExp& regexp() const { return mRegexp; } + const Data& replacement() const { return mReplacement; } + const Data& name() const { return mName; } + bool isSameValue(const Data& value) const; + EncodeStream& dump(EncodeStream& strm) const; + + private: + int mOrder; + int mPreference; + Data mFlags; + Data mService; + RegExp mRegexp; + Data mReplacement; + Data mName; + +}; + +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/DnsResourceRecord.cxx b/src/libs/resiprocate/rutil/dns/DnsResourceRecord.cxx new file mode 100644 index 00000000..9a283ed7 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsResourceRecord.cxx @@ -0,0 +1,60 @@ +#include "rutil/dns/DnsResourceRecord.hxx" +#include <iostream> + +EncodeStream& +resip::operator<<(EncodeStream& strm, DnsResourceRecord& rr) +{ + rr.dump(strm); + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/rutil/dns/DnsResourceRecord.hxx b/src/libs/resiprocate/rutil/dns/DnsResourceRecord.hxx new file mode 100644 index 00000000..d8196150 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsResourceRecord.hxx @@ -0,0 +1,83 @@ +#ifndef _DNS_RESOURCE_RECORD +#define _DNS_RESOURCE_RECORD + +#include <iosfwd> +#include "rutil/resipfaststreams.hxx" + +namespace resip +{ + +class Data; + +class DnsResourceRecord +{ + public: + DnsResourceRecord() {} + virtual ~DnsResourceRecord() + { + } + virtual const Data& name() const = 0; + virtual bool isSameValue(const Data& valueToCompare) const = 0; + virtual EncodeStream& dump(EncodeStream& strm) const = 0; +}; + +EncodeStream& +operator<<(EncodeStream& strm, DnsResourceRecord& rr); + +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + + + + + +#endif diff --git a/src/libs/resiprocate/rutil/dns/DnsSrvRecord.cxx b/src/libs/resiprocate/rutil/dns/DnsSrvRecord.cxx new file mode 100644 index 00000000..3165a7be --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsSrvRecord.cxx @@ -0,0 +1,110 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <stdlib.h> + +#include "AresCompat.hxx" + +#ifndef __CYGWIN__ +#ifndef RRFIXEDSZ +#define RRFIXEDSZ 10 +#endif +#ifndef NS_RRFIXEDSZ +#define NS_RRFIXEDSZ 10 +#endif +#endif + +#include "rutil/Data.hxx" +#include "rutil/BaseException.hxx" +#include "RROverlay.hxx" +#include "DnsResourceRecord.hxx" +#include "DnsSrvRecord.hxx" + +using namespace resip; + +DnsSrvRecord::DnsSrvRecord(const RROverlay& overlay) +{ + char* name = 0; + long len = 0; + if (ARES_SUCCESS != ares_expand_name(overlay.data()-overlay.nameLength()-RRFIXEDSZ, overlay.msg(), overlay.msgLength(), &name, &len)) + { + throw SrvException("Failed parse of SRV record", __FILE__, __LINE__); + } + mName = name; + free(name); + + mPriority = DNS__16BIT(overlay.data()); + mWeight = DNS__16BIT(overlay.data() + 2); + mPort = DNS__16BIT(overlay.data() + 4); + + if (ARES_SUCCESS != ares_expand_name(overlay.data() + 6, overlay.msg(), overlay.msgLength(), &name, &len)) + { + throw SrvException("Failed parse of SRV record", __FILE__, __LINE__); + } + mTarget = name; + free(name); +} + +bool DnsSrvRecord::isSameValue(const Data& value) const +{ + return value == (mTarget + ":" + Data(mPort)); +} + +EncodeStream& +DnsSrvRecord::dump(EncodeStream& strm) const +{ + strm << mName << " (SRV) --> p=" << mPriority << " w=" << mWeight << " " << mTarget << ":" << mPort; + return strm; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/dns/DnsSrvRecord.hxx b/src/libs/resiprocate/rutil/dns/DnsSrvRecord.hxx new file mode 100644 index 00000000..5a5b961e --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsSrvRecord.hxx @@ -0,0 +1,104 @@ +#ifndef RESIP_DNS_SRV_RECORD +#define RESIP_DNS_SRV_RECORD + +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/dns/DnsResourceRecord.hxx" + +namespace resip +{ + +class Data; +class DnsResourceRecord; +class RROverlay; + +class DnsSrvRecord : public DnsResourceRecord +{ + public: + class SrvException : public BaseException + { + public: + SrvException(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) + { + } + + const char* name() const { return "SrvException"; } + }; + + DnsSrvRecord(const RROverlay&); + ~DnsSrvRecord() {} + + // accessors. + int priority() const { return mPriority; } + int& priority() { return mPriority; } + int weight() const { return mWeight; } + int port() const { return mPort; } + const Data& target() const { return mTarget; } + const Data& name() const { return mName; } + bool isSameValue(const Data& value) const; + EncodeStream& dump(EncodeStream& strm) const; + + private: + int mPriority; + int mWeight; + int mPort; + Data mTarget; // domain name of the target host. + Data mName; +}; + +} + + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/DnsStub.cxx b/src/libs/resiprocate/rutil/dns/DnsStub.cxx new file mode 100644 index 00000000..8f9bc12e --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsStub.cxx @@ -0,0 +1,941 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// WINCE -- stl headers have to be defined before standard c headers because of +// MS non-consistent declaration of time_t. we defined _USE_32BIT_TIME_T +// in all projects and that solved the issue with beta compiler, however +// release version messes time_t definition again +#include <set> +#include <vector> +#include <cassert> + +#include "AresCompat.hxx" + +#ifndef WIN32 +#ifndef __CYGWIN__ +#include <arpa/nameser.h> +#endif +#endif + +#include "rutil/FdPoll.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Socket.hxx" +#include "rutil/compat.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/Data.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/dns/DnsStub.hxx" +#include "rutil/dns/ExternalDns.hxx" +#include "rutil/dns/ExternalDnsFactory.hxx" +#include "rutil/dns/QueryTypes.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS + +DnsStub::DnsResourceRecordsByPtr DnsStub::Query::Empty; + +DnsStub::NameserverList DnsStub::EmptyNameserverList; +int DnsStub::mDnsTimeout = 0; +int DnsStub::mDnsTries = 0; +unsigned int DnsStub::mDnsFeatures = 0; + +void +DnsResultSink::onLogDnsResult(const DNSResult<DnsHostRecord>& rr) +{ + DebugLog (<< rr); +} + +void +DnsResultSink::onLogDnsResult(const DNSResult<DnsAAAARecord>& rr) +{ +#if defined(USE_IPV6) + DebugLog (<< rr); +#else + ErrLog(<< "Something called " + "DnsResultSink::onLogDnsResult(const DNSResult<DnsAAAARecord>& rr)" + " when ipv6 support was disabled."); +#endif +} + +void +DnsResultSink::onLogDnsResult(const DNSResult<DnsSrvRecord>& rr) +{ + DebugLog (<< rr); +} + +void +DnsResultSink::onLogDnsResult(const DNSResult<DnsNaptrRecord>& rr) +{ + DebugLog (<< rr); +} + +void +DnsResultSink::onLogDnsResult(const DNSResult<DnsCnameRecord>& rr) +{ + DebugLog (<< rr); +} + +DnsStub::DnsStub(const NameserverList& additional, + AfterSocketCreationFuncPtr socketFunc, + AsyncProcessHandler* asyncProcessHandler, + FdPollGrp *pollGrp) : + mInterruptorHandle(0), + mCommandFifo(&mSelectInterruptor), + mTransform(0), + mDnsProvider(ExternalDnsFactory::createExternalDns()), + mPollGrp(0), + mAsyncProcessHandler(asyncProcessHandler) +{ + setPollGrp(pollGrp); + + int retCode = mDnsProvider->init(additional, socketFunc, mDnsTimeout, mDnsTries, mDnsFeatures); + if (retCode != ExternalDns::Success) + { + if (retCode == ExternalDns::BuildMismatch) + { + assert(0); + throw DnsStubException("Library was not build w/ required capabilities(probably USE_IPV6 resip/ares mismatch", + __FILE__,__LINE__); + } + + Data err(Data::Take, mDnsProvider->errorMessage(retCode)); + ErrLog (<< "Failed to initialize async dns library: " << err); + + throw DnsStubException("Failed to initialize async dns library " + err, __FILE__,__LINE__); + } +} + +DnsStub::~DnsStub() +{ + for (set<Query*>::iterator it = mQueries.begin(); it != mQueries.end(); ++it) + { + delete *it; + } + + setPollGrp(0); + delete mDnsProvider; +} + +unsigned int +DnsStub::getTimeTillNextProcessMS() +{ + if(mCommandFifo.size() > 0) return 0; + return mDnsProvider->getTimeTillNextProcessMS(); +} + +void +DnsStub::buildFdSet(FdSet& fdset) +{ + mDnsProvider->buildFdSet(fdset.read, fdset.write, fdset.size); + mSelectInterruptor.buildFdSet(fdset); +} + +void +DnsStub::processFifo() +{ + while (mCommandFifo.messageAvailable()) + { + Command* command = mCommandFifo.getNext(); + command->execute(); + delete command; + } +} + +void +DnsStub::process(FdSet& fdset) +{ + mSelectInterruptor.process(fdset); + processFifo(); + mDnsProvider->process(fdset.read, fdset.write); +} + +void +DnsStub::processTimers() +{ + // the fifo is captures as a timer within getTimeTill... above + processFifo(); + mDnsProvider->processTimers(); +} + +void +DnsStub::cache(const Data& key, + in_addr addr) +{ + DnsHostRecord record(key, addr); + mRRCache.updateCacheFromHostFile(record); +} + +void +DnsStub::cache(const Data& key, + const unsigned char* abuf, + int alen) +{ + + vector<RROverlay> overlays; + + // skip header + const unsigned char* aptr = abuf + HFIXEDSZ; + + int qdcount = DNS_HEADER_QDCOUNT(abuf); // questions. + for (int i = 0; i < qdcount && aptr; ++i) + { + aptr = skipDNSQuestion(aptr, abuf, alen); + } + + // answers. + int ancount = DNS_HEADER_ANCOUNT(abuf); + for (int i = 0; i < ancount; i++) + { + aptr = createOverlay(abuf, alen, aptr, overlays); + } + + // name server records. + int nscount = DNS_HEADER_NSCOUNT(abuf); + for (int i = 0; i < nscount; i++) + { + aptr = createOverlay(abuf, alen, aptr, overlays, true); + } + + // additional records. + int arcount = DNS_HEADER_ARCOUNT(abuf); + for (int i = 0; i < arcount; i++) + { + aptr = createOverlay(abuf, alen, aptr, overlays); + } + + // sort overlays by type. + sort(overlays.begin(), overlays.end()); + + vector<RROverlay>::iterator itLow = lower_bound(overlays.begin(), overlays.end(), *overlays.begin()); + vector<RROverlay>::iterator itHigh = upper_bound(overlays.begin(), overlays.end(), *overlays.begin()); + while (itLow != overlays.end()) + { + mRRCache.updateCache(key, (*itLow).type(), itLow, itHigh); + itLow = itHigh; + if (itHigh != overlays.end()) + { + itHigh = upper_bound(itLow, overlays.end(), *itLow); + } + } +} + +void +DnsStub::cacheTTL(const Data& key, + int rrType, + int status, + const unsigned char* abuf, + int alen) +{ + // skip header + const unsigned char* aptr = abuf + HFIXEDSZ; + + int qdcount = DNS_HEADER_QDCOUNT(abuf); // questions. + for (int i = 0; i < qdcount && aptr; ++i) + { + aptr = skipDNSQuestion(aptr, abuf, alen); + } + + vector<RROverlay> overlays; + + // answers. + int ancount = DNS_HEADER_ANCOUNT(abuf); + if (ancount != 0) return; + + // name server records. + int nscount = DNS_HEADER_NSCOUNT(abuf); + if (nscount == 0) return; + vector<RROverlay> soa; + aptr = createOverlay(abuf, alen, aptr, soa); + if(soa.empty()) + { + return; + } + + mRRCache.cacheTTL(key, rrType, status, soa[0]); +} + +const unsigned char* +DnsStub::skipDNSQuestion(const unsigned char *aptr, + const unsigned char *abuf, + int alen) +{ + char *name=0; + int status=0; + long len = 0; + + // Parse the question name. + status = ares_expand_name(aptr, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + { + throw DnsStubException("Failed DNS preparse", __FILE__, __LINE__); + } + aptr += len; + + // Make sure there's enough data after the name for the fixed part + // of the question. + if (aptr + QFIXEDSZ > abuf + alen) + { + free(name); + throw DnsStubException("Failed DNS preparse", __FILE__, __LINE__); + } + + aptr += QFIXEDSZ; + free(name); + return aptr; +} + +bool +DnsStub::checkDnsChange() +{ + return mDnsProvider ? mDnsProvider->checkDnsChange() : false; +} + +bool +DnsStub::supportedType(int type) +{ + if(mDnsProvider && mDnsProvider->hostFileLookupLookupOnlyMode()) + { + return (T_A == type); + } +#ifdef USE_IPV6 + return (T_A == type || + T_AAAA == type || + T_NAPTR == type || + T_SRV == type || + T_CNAME == type || + T_SOA == type); +#else + return (T_A == type || + T_NAPTR == type || + T_SRV == type || + T_CNAME == type || + T_SOA == type); +#endif +} + +const unsigned char* +DnsStub::createOverlay(const unsigned char* abuf, + const int alen, + const unsigned char* aptr, + vector<RROverlay>& overlays, + bool discard) +{ + const unsigned char* rptr = aptr; + char* name = 0; + long len = 0; + + int status = ares_expand_name(aptr, abuf, alen, &name, &len); + if (ARES_SUCCESS != status) + { + throw DnsStubException("Failed overlay creation", __FILE__, __LINE__); + } + free(name); + aptr += len; + int type = DNS_RR_TYPE(aptr); + int dlen = DNS_RR_LEN(aptr); + if (!supportedType(type)) + { + aptr += RRFIXEDSZ; + aptr += dlen; + return aptr; + } + // rewind before handing it off to overlay. + aptr -= len; + if (!discard) + { + RROverlay overlay(aptr, abuf, alen); + overlays.push_back(overlay); + } + return rptr + len + RRFIXEDSZ + dlen; +} + +void +DnsStub::removeQuery(Query* query) +{ + set<Query*>::iterator it = mQueries.find(query); + if (it != mQueries.end()) + { + mQueries.erase(it); + } +} + +void +DnsStub::setResultTransform(ResultTransform* transform) +{ + mTransform = transform; +} + +void +DnsStub::removeResultTransform() +{ + mTransform = 0; +} + +void +DnsStub::setPollGrp(FdPollGrp* pollGrp) +{ + if(mPollGrp) + { + // unregister our select interruptor + //mPollGrp->delPollItem(mInterruptorHandle); + mInterruptorHandle=0; + } + + mPollGrp=pollGrp; + + if (mPollGrp) + { + //mInterruptorHandle = mPollGrp->addPollItem(mSelectInterruptor.getReadSocket(), FPEM_Read, &mSelectInterruptor); + } + + mDnsProvider->setPollGrp(mPollGrp); +} + +DnsStub::Query::Query(DnsStub& stub, ResultTransform* transform, ResultConverter* resultConv, + const Data& target, int rrType, + bool followCname, int proto, DnsResultSink* s) + : mRRType(rrType), + mStub(stub), + mTransform(transform), + mResultConverter(resultConv), + mTarget(target), + mProto(proto), + mReQuery(0), + mSink(s), + mFollowCname(followCname) +{ + assert(s); +} + +DnsStub::Query::~Query() +{ + delete mResultConverter; //.dcm. flyweight? +} + +static Data +typeToData(int rr) +{ + // !dcm! fix this + if (rr == RR_A::getRRType()) + { + return RR_A::getRRTypeName(); + } +#if defined(USE_IPV6) + else if(rr == RR_AAAA::getRRType()) + { + return RR_AAAA::getRRTypeName(); + } +#endif + else if (rr ==RR_NAPTR::getRRType()) + { + return RR_NAPTR::getRRTypeName(); + } + else if(rr == RR_SRV::getRRType()) + { + return RR_SRV::getRRTypeName(); + } + else if (RR_CNAME::getRRType()) + { + return RR_CNAME::getRRTypeName(); + } + else + { + return "Unknown"; + } +} + +void +DnsStub::Query::go() +{ + StackLog(<< "DNS query of:" << mTarget << " " << typeToData(mRRType)); + + DnsResourceRecordsByPtr records; + int status = 0; + bool cached = false; + Data targetToQuery = mTarget; + cached = mStub.mRRCache.lookup(mTarget, mRRType, mProto, records, status); + + if (!cached) + { + if (mRRType != T_CNAME) + { + do + { + DnsResourceRecordsByPtr cnames; + cached = mStub.mRRCache.lookup(targetToQuery, T_CNAME, mProto, cnames, status); + if (cached) + { + targetToQuery = (dynamic_cast<DnsCnameRecord*>(cnames[0]))->cname(); + } + } while(cached); + } + } + + if (targetToQuery != mTarget) + { + StackLog(<< mTarget << " mapped to CNAME " << targetToQuery); + cached = mStub.mRRCache.lookup(targetToQuery, mRRType, mProto, records, status); + } + + if (!cached) + { + if(mStub.mDnsProvider && mStub.mDnsProvider->hostFileLookupLookupOnlyMode()) + { + assert(mRRType == T_A); + StackLog (<< targetToQuery << " not cached. Doing hostfile lookup"); + in_addr address; + if (mStub.mDnsProvider->hostFileLookup(targetToQuery.c_str(), address)) + { + mStub.cache(mTarget, address); + DnsResourceRecordsByPtr result; + int queryStatus = 0; + + mStub.mRRCache.lookup(mTarget, mRRType, mProto, result, queryStatus); + if (mTransform) + { + mTransform->transform(mTarget, mRRType, result); + } + mResultConverter->notifyUser(mTarget, queryStatus, mStub.errorMessage(queryStatus), result, mSink); + } + else + { + // Not in hosts file - return error - or.. we could fallback to doing the lookupRecords call on the local named + mResultConverter->notifyUser(mTarget, ARES_ENOTFOUND, mStub.errorMessage(ARES_ENOTFOUND), Empty, mSink); + } + mReQuery = 0; + mStub.removeQuery(this); + delete this; + return; + } + else + { + StackLog (<< targetToQuery << " not cached. Doing external dns lookup"); + mStub.lookupRecords(targetToQuery, mRRType, this); + } + } + else // is cached + { + if (mTransform && !records.empty()) + { + mTransform->transform(mTarget, mRRType, records); + } + mResultConverter->notifyUser(mTarget, status, mStub.errorMessage(status), records, mSink); + + mStub.removeQuery(this); + delete this; + } +} + +void +DnsStub::Query::process(int status, const unsigned char* abuf, const int alen) +{ + if (status != 0) + { + switch (status) + { + case ARES_ENODATA: + case ARES_EFORMERR: + case ARES_ESERVFAIL: + case ARES_ENOTFOUND: + case ARES_ENOTIMP: + case ARES_EREFUSED: + if(mRRType == T_A) + { + in_addr address; + if (mStub.mDnsProvider->hostFileLookup(mTarget.c_str(), address)) + { + mStub.cache(mTarget, address); + mReQuery = 0; + DnsResourceRecordsByPtr result; + int queryStatus = 0; + + mStub.mRRCache.lookup(mTarget, mRRType, mProto, result, queryStatus); + if (mTransform) + { + mTransform->transform(mTarget, mRRType, result); + } + mResultConverter->notifyUser(mTarget, queryStatus, mStub.errorMessage(queryStatus), result, mSink); + mStub.removeQuery(this); + delete this; + return; + } + } + try + { + mStub.cacheTTL(mTarget, mRRType, status, abuf, alen); + } + catch (BaseException& e) + { + // if the response isn't parsable, we might want to consider caching + // TTL anyways to delay the query attempt for this record. + ErrLog(<< "Couldn't parse failure response to lookup for " << mTarget); + InfoLog(<< e.getMessage()); + } + break; + + case ARES_ECONNREFUSED: + case ARES_ETIMEOUT: + ErrLog (<< "Connection error " << mStub.errorMessage(status) << " for " << mTarget); + break; + case ARES_EBADRESP: + ErrLog (<< "Server response error " << mStub.errorMessage(status) << " for " << mTarget); + break; + case ARES_EOF: + case ARES_EFILE: + case ARES_ENOMEM: + case ARES_EDESTRUCTION: + ErrLog (<< "Error " << mStub.errorMessage(status) << " for " << mTarget); + break; + case ARES_EBADNAME: + ErrLog(<< "Garbage hostname failed to resolve: " << mStub.errorMessage(status) << " for " << mTarget); + break; + case ARES_EBADQUERY: + ErrLog(<< "Query was malformed (probably because hostname was " + "too long) " << mStub.errorMessage(status) << " for " + << mTarget); + break; + case ARES_EBADFAMILY: + ErrLog (<< "Bad lookup type " << mStub.errorMessage(status) << " for " << mTarget); + // .bwc. This should not happen. If it does, we have code to fix. + assert(0); + break; + default: + ErrLog (<< "Unknown error " << mStub.errorMessage(status) << " for " << mTarget); + assert(0); + break; + } + + // For other error status values, we may also want to cacheTTL to delay + // requeries. Especially if the server refuses. + mResultConverter->notifyUser(mTarget, status, mStub.errorMessage(status), Empty, mSink); + mReQuery = 0; + mStub.removeQuery(this); + delete this; + return; + } + + bool bDeleteThis = true; + + // skip header + const unsigned char* aptr = abuf + HFIXEDSZ; + + int qdcount = DNS_HEADER_QDCOUNT(abuf); // questions. + for (int i = 0; i < qdcount && aptr; ++i) + { + try + { + aptr = mStub.skipDNSQuestion(aptr, abuf, alen); + } + catch (BaseException& e) + { + ErrLog(<< "Error parsing DNS record for " << mTarget << ": " << e.getMessage()); + mResultConverter->notifyUser(mTarget, ARES_EFORMERR, e.getMessage(), Empty, mSink); + mStub.removeQuery(this); + delete this; + return; + } + } + + int ancount = DNS_HEADER_ANCOUNT(abuf); + if (ancount == 0) + { + mResultConverter->notifyUser(mTarget, 0, mStub.errorMessage(0), Empty, mSink); + } + else + { + bool bGotAnswers = true; + Data targetToQuery; + followCname(aptr, abuf, alen, bGotAnswers, bDeleteThis, targetToQuery); + + if (bGotAnswers) + { + mReQuery = 0; + DnsResourceRecordsByPtr result; + int queryStatus = 0; + + if (mTarget != targetToQuery) DebugLog (<< mTarget << " mapped to " << targetToQuery << " and returned result"); + mStub.mRRCache.lookup(targetToQuery, mRRType, mProto, result, queryStatus); + if (mTransform) + { + mTransform->transform(mTarget, mRRType, result); + } + mResultConverter->notifyUser(mTarget, queryStatus, mStub.errorMessage(queryStatus), result, mSink); + } + } + + if (bDeleteThis) + { + mStub.removeQuery(this); + delete this; + } +} + +void +DnsStub::Query::onDnsRaw(int status, const unsigned char* abuf, int alen) +{ + process(status, abuf, alen); +} + +void +DnsStub::Query::followCname(const unsigned char* aptr, const unsigned char*abuf, const int alen, bool& bGotAnswers, bool& bDeleteThis, Data& targetToQuery) +{ + bGotAnswers = true; + bDeleteThis = true; + + char* name = 0; + long len = 0; + + if (ARES_SUCCESS != ares_expand_name(aptr, abuf, alen, &name, &len)) + { + ErrLog(<< "Failed DNS preparse for " << targetToQuery); + mResultConverter->notifyUser(mTarget, ARES_EFORMERR, "Failed DNS preparse", Empty, mSink); + bGotAnswers = false; + return; + } + + targetToQuery = name; + aptr += len; + + try + { + mStub.cache(name, abuf, alen); + } + catch (BaseException& e) + { + ErrLog(<< "Failed to cache result for " << targetToQuery << ": " << e.getMessage()); + mResultConverter->notifyUser(mTarget, ARES_EFORMERR, e.getMessage(), Empty, mSink); + bGotAnswers = false; + return; + } + + if (mRRType != T_CNAME) + { + if (DNS_RR_TYPE(aptr) == T_CNAME) + { + if (mFollowCname && mReQuery < MAX_REQUERIES) + { + ++mReQuery; + int status = 0; + bool cached = false; + + do + { + DnsResourceRecordsByPtr cnames; + cached = mStub.mRRCache.lookup(targetToQuery, T_CNAME, mProto, cnames, status); + if (cached) + { + ++mReQuery; + targetToQuery = (dynamic_cast<DnsCnameRecord*>(cnames[0]))->cname(); + } + } while(mReQuery < MAX_REQUERIES && cached); + + DnsResourceRecordsByPtr result; + if (!mStub.mRRCache.lookup(targetToQuery, mRRType, mProto, result, status)) + { + mStub.lookupRecords(targetToQuery, mRRType, this); + bDeleteThis = false; + bGotAnswers = false; + } + } + else + { + mReQuery = 0; + mResultConverter->notifyUser(mTarget, 1, mStub.errorMessage(1), Empty, mSink); + bGotAnswers = false; + } + } + } + + free(name); +} + +Data +DnsStub::errorMessage(int status) +{ + return Data(Data::Take, mDnsProvider->errorMessage(status)); +} + +void +DnsStub::lookupRecords(const Data& target, unsigned short type, DnsRawSink* sink) +{ + mDnsProvider->lookup(target.c_str(), type, this, sink); +} + +void +DnsStub::handleDnsRaw(ExternalDnsRawResult res) +{ + reinterpret_cast<DnsRawSink*>(res.userData)->onDnsRaw(res.errorCode(), res.abuf, res.alen); + mDnsProvider->freeResult(res); +} + +void +DnsStub::setEnumSuffixes(const std::vector<Data>& suffixes) +{ + SetEnumSuffixesCommand* command = new SetEnumSuffixesCommand(*this, suffixes); + mCommandFifo.add(command); + + if (mAsyncProcessHandler) + { + mAsyncProcessHandler->handleProcessNotification(); + } +} + +const std::vector<Data>& +DnsStub::getEnumSuffixes() const +{ + return mEnumSuffixes; +} + +void +DnsStub::doSetEnumSuffixes(const std::vector<Data>& suffixes) +{ + mEnumSuffixes = suffixes; +} + +void +DnsStub::setEnumDomains(const std::map<Data,Data>& domains) +{ + SetEnumDomainsCommand* command = new SetEnumDomainsCommand(*this, domains); + mCommandFifo.add(command); + + if (mAsyncProcessHandler) + { + mAsyncProcessHandler->handleProcessNotification(); + } +} + +const std::map<Data,Data>& +DnsStub::getEnumDomains() const +{ + return mEnumDomains; +} + +void +DnsStub::doSetEnumDomains(const std::map<Data,Data>& domains) +{ + mEnumDomains = domains; +} + +void +DnsStub::clearDnsCache() +{ + ClearDnsCacheCommand* command = new ClearDnsCacheCommand(*this); + mCommandFifo.add(command); + + if (mAsyncProcessHandler) + { + mAsyncProcessHandler->handleProcessNotification(); + } +} + +void +DnsStub::doClearDnsCache() +{ + mRRCache.clearCache(); +} + +void +DnsStub::logDnsCache() +{ + LogDnsCacheCommand* command = new LogDnsCacheCommand(*this); + mCommandFifo.add(command); + + if (mAsyncProcessHandler) + { + mAsyncProcessHandler->handleProcessNotification(); + } +} + +void +DnsStub::doLogDnsCache() +{ + mRRCache.logCache(); +} + +void +DnsStub::getDnsCacheDump(std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler) +{ + GetDnsCacheDumpCommand* command = new GetDnsCacheDumpCommand(*this, key, handler); + mCommandFifo.add(command); + + if (mAsyncProcessHandler) + { + mAsyncProcessHandler->handleProcessNotification(); + } +} + +void +DnsStub::doGetDnsCacheDump(std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler) +{ + assert(handler != 0); + Data dnsCacheDump; + mRRCache.getCacheDump(dnsCacheDump); + handler->onDnsCacheDumpRetrieved(key, dnsCacheDump); +} + +void +DnsStub::setDnsCacheTTL(int ttl) +{ + mRRCache.setTTL(ttl); +} + +void +DnsStub::setDnsCacheSize(int size) +{ + mRRCache.setSize(size); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/rutil/dns/DnsStub.hxx b/src/libs/resiprocate/rutil/dns/DnsStub.hxx new file mode 100644 index 00000000..8d53f885 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsStub.hxx @@ -0,0 +1,507 @@ +#ifndef RESIP_DNS_STUB_HXX +#define RESIP_DNS_STUB_HXX + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include <vector> +#include <list> +#include <map> +#include <set> + +#include "rutil/FdPoll.hxx" +#include "rutil/Fifo.hxx" +#include "rutil/GenericIPAddress.hxx" +#include "rutil/SelectInterruptor.hxx" +#include "rutil/Socket.hxx" +#include "rutil/dns/DnsResourceRecord.hxx" +#include "rutil/dns/DnsAAAARecord.hxx" +#include "rutil/dns/DnsCnameRecord.hxx" +#include "rutil/dns/DnsHostRecord.hxx" +#include "rutil/dns/DnsNaptrRecord.hxx" +#include "rutil/dns/DnsSrvRecord.hxx" +#include "rutil/dns/RRCache.hxx" +#include "rutil/dns/RROverlay.hxx" +#include "rutil/dns/ExternalDns.hxx" +#include "rutil/AsyncProcessHandler.hxx" + + +namespace resip +{ +class FdPollGrp; + +class GetDnsCacheDumpHandler +{ + public: + GetDnsCacheDumpHandler() {} + virtual ~GetDnsCacheDumpHandler() {} + virtual void onDnsCacheDumpRetrieved(std::pair<unsigned long, unsigned long> key, const Data& dnsCache) = 0; +}; + +template<typename T> +class DNSResult +{ + public: + Data domain; + int status; + Data msg; + std::vector<T> records; + EncodeStream& dump(EncodeStream& strm) const + { + if (status == 0) + { + for (typename std::vector<T>::const_iterator i=records.begin(); i != records.end(); ++i) + { + i->dump(strm); + } + } + else + { + strm << domain << " lookup failed: " << msg; + } + + return strm; + } +}; + +template<class T> +EncodeStream& operator<<(EncodeStream& strm, const DNSResult<T>& r) +{ + r.dump(strm); + return strm; +} + +class DnsResultSink +{ + public: + virtual ~DnsResultSink() {} + virtual void onDnsResult(const DNSResult<DnsHostRecord>&) = 0; + virtual void onLogDnsResult(const DNSResult<DnsHostRecord>&); + +// DnsAAAARecord will basically be non-functional if USE_IPV6 wasn't set in the +// build. + virtual void onDnsResult(const DNSResult<DnsAAAARecord>&) = 0; + virtual void onLogDnsResult(const DNSResult<DnsAAAARecord>&); + + virtual void onDnsResult(const DNSResult<DnsSrvRecord>&) = 0; + virtual void onLogDnsResult(const DNSResult<DnsSrvRecord>&); + + virtual void onDnsResult(const DNSResult<DnsNaptrRecord>&) = 0; + virtual void onLogDnsResult(const DNSResult<DnsNaptrRecord>&); + + virtual void onDnsResult(const DNSResult<DnsCnameRecord>&) = 0; + virtual void onLogDnsResult(const DNSResult<DnsCnameRecord>&); +}; + +class DnsRawSink +{ + public: + virtual ~DnsRawSink() {} + virtual void onDnsRaw(int statuts, const unsigned char* abuf, int len) = 0; +}; + +class DnsStub : public ExternalDnsHandler +{ + public: + typedef RRCache::Protocol Protocol; + typedef std::vector<Data> DataArr; + typedef std::vector<DnsResourceRecord*> DnsResourceRecordsByPtr; + typedef std::vector<GenericIPAddress> NameserverList; + + static NameserverList EmptyNameserverList; + + class ResultTransform + { + public: + virtual ~ResultTransform() {} + virtual void transform(const Data& target, int rrType, DnsResourceRecordsByPtr& src) = 0; + }; + + class DnsStubException : public BaseException + { + public: + DnsStubException(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) + { + } + + const char* name() const { return "DnsStubException"; } + }; + + DnsStub(const NameserverList& additional = EmptyNameserverList, + AfterSocketCreationFuncPtr socketFunc = 0, + AsyncProcessHandler* asyncProcessHandler = 0, + FdPollGrp *pollGrp = 0); + ~DnsStub(); + + // call this method before you create SipStack if you'd like to change the + // default DNS lookup timeout and number of retries. + static void setDnsTimeoutAndTries(int timeoutInSec, int tries) + { + mDnsTimeout = timeoutInSec; + mDnsTries = tries; + } + static void enableDnsFeatures(unsigned int features) {mDnsFeatures |= features;} // bit mask of ExternalDns::Features + + void setResultTransform(ResultTransform*); + void removeResultTransform(); + void setEnumSuffixes(const std::vector<Data>& suffixes); + const std::vector<Data>& getEnumSuffixes() const; + void setEnumDomains(const std::map<Data,Data>& domains); + const std::map<Data,Data>& getEnumDomains() const; + void clearDnsCache(); + void logDnsCache(); + void getDnsCacheDump(std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler); + void setDnsCacheTTL(int ttl); + void setDnsCacheSize(int size); + bool checkDnsChange(); + bool supportedType(int); + + template<class QueryType> void lookup(const Data& target, DnsResultSink* sink) + { + lookup<QueryType>(target, Protocol::Reserved, sink); + } + + // There are three pre-defined protocols (see RRList.hxx). Zero(0) is + // reserved for internal use, so do not use 0. If you'd like to blacklist + // for different types of protocols, just pass in any integer other than + // those used for pre-defined protocols. + // + template<class QueryType> void lookup(const Data& target, int protocol, DnsResultSink* sink) + { + QueryCommand<QueryType>* command = new QueryCommand<QueryType>(target, protocol, sink, *this); + mCommandFifo.add(command); + + if (mAsyncProcessHandler) + { + mAsyncProcessHandler->handleProcessNotification(); + } + } + + virtual void handleDnsRaw(ExternalDnsRawResult); + + virtual void process(FdSet& fdset); + virtual unsigned int getTimeTillNextProcessMS(); + virtual void buildFdSet(FdSet& fdset); + void setPollGrp(FdPollGrp* pollGrp); + + void processTimers(); + private: + void processFifo(); + + protected: + void cache(const Data& key, in_addr addr); + void cache(const Data& key, const unsigned char* abuf, int alen); + void cacheTTL(const Data& key, int rrType, int status, const unsigned char* abuf, int alen); + + private: + class ResultConverter //.dcm. -- flyweight? + { + public: + virtual void notifyUser(const Data& target, + int status, + const Data& msg, + const DnsResourceRecordsByPtr& src, + DnsResultSink* sink) = 0; + virtual ~ResultConverter() {} + }; + + template<class QueryType> + class ResultConverterImpl : public ResultConverter + { + public: + virtual void notifyUser(const Data& target, + int status, + const Data& msg, + const DnsResourceRecordsByPtr& src, + DnsResultSink* sink) + { + assert(sink); + DNSResult<typename QueryType::Type> result; + for (unsigned int i = 0; i < src.size(); ++i) + { + result.records.push_back(*(dynamic_cast<typename QueryType::Type*>(src[i]))); + } + result.domain = target; + result.status = status; + result.msg = msg; + sink->onLogDnsResult(result); + sink->onDnsResult(result); + } + }; + + class Query : public DnsRawSink + { + public: + Query(DnsStub& stub, ResultTransform* transform, ResultConverter* resultConv, + const Data& target, int rrType, bool followCname, int proto, DnsResultSink* s); + virtual ~Query(); + + enum {MAX_REQUERIES = 5}; + + void go(); + void process(int status, const unsigned char* abuf, const int alen); + void onDnsRaw(int status, const unsigned char* abuf, int alen); + void followCname(const unsigned char* aptr, const unsigned char*abuf, const int alen, bool& bGotAnswers, bool& bDeleteThis, Data& targetToQuery); + + private: + static DnsResourceRecordsByPtr Empty; + int mRRType; + DnsStub& mStub; + ResultTransform* mTransform; + ResultConverter* mResultConverter; + Data mTarget; + int mProto; + int mReQuery; + DnsResultSink* mSink; + bool mFollowCname; + }; + + private: + DnsStub(const DnsStub&); // disable copy ctor. + DnsStub& operator=(const DnsStub&); + + public: + // sailesh - due to a bug in CodeWarrior, + // QueryCommand::execute() can only access this method + // if it's public. Even using "friend" doesn't work. + template<class QueryType> + void query(const Data& target, int proto, DnsResultSink* sink) + { + Query* query = new Query(*this, mTransform, + new ResultConverterImpl<QueryType>(), + target, QueryType::getRRType(), + QueryType::SupportsCName, proto, sink); + mQueries.insert(query); + query->go(); + } + + private: + + class Command + { + public: + virtual ~Command() {} + virtual void execute() = 0; + }; + + + template<class QueryType> + class QueryCommand : public Command + { + public: + QueryCommand(const Data& target, + int proto, + DnsResultSink* sink, + DnsStub& stub) + : mTarget(target), + mProto(proto), + mSink(sink), + mStub(stub) + {} + + ~QueryCommand() {} + + void execute() + { + mStub.query<QueryType>(mTarget, mProto, mSink); + } + + private: + Data mTarget; + int mProto; + DnsResultSink* mSink; + DnsStub& mStub; + }; + + void doSetEnumSuffixes(const std::vector<Data>& suffixes); + void doSetEnumDomains(const std::map<Data,Data>& domains); + + class SetEnumSuffixesCommand : public Command + { + public: + SetEnumSuffixesCommand(DnsStub& stub, + const std::vector<Data>& suffixes) + : mStub(stub), + mEnumSuffixes(suffixes) + {} + ~SetEnumSuffixesCommand() {} + void execute() + { + mStub.doSetEnumSuffixes(mEnumSuffixes); + } + + private: + DnsStub& mStub; + std::vector<Data> mEnumSuffixes; + }; + + class SetEnumDomainsCommand : public Command + { + public: + SetEnumDomainsCommand(DnsStub& stub, + const std::map<Data,Data>& domains) + : mStub(stub), + mEnumDomains(domains) + {} + ~SetEnumDomainsCommand() {} + void execute() + { + mStub.doSetEnumDomains(mEnumDomains); + } + + private: + DnsStub& mStub; + std::map<Data,Data> mEnumDomains; + }; + + void doClearDnsCache(); + + class ClearDnsCacheCommand : public Command + { + public: + ClearDnsCacheCommand(DnsStub& stub) + : mStub(stub) + {} + ~ClearDnsCacheCommand() {} + void execute() + { + mStub.doClearDnsCache(); + } + + private: + DnsStub& mStub; + }; + + void doLogDnsCache(); + + class LogDnsCacheCommand : public Command + { + public: + LogDnsCacheCommand(DnsStub& stub) + : mStub(stub) + {} + ~LogDnsCacheCommand() {} + void execute() + { + mStub.doLogDnsCache(); + } + + private: + DnsStub& mStub; + }; + + void doGetDnsCacheDump(std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler); + + class GetDnsCacheDumpCommand : public Command + { + public: + GetDnsCacheDumpCommand(DnsStub& stub, std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler) + : mStub(stub), mKey(key), mHandler(handler) + {} + ~GetDnsCacheDumpCommand() {} + void execute() + { + mStub.doGetDnsCacheDump(mKey, mHandler); + } + + private: + DnsStub& mStub; + std::pair<unsigned long, unsigned long> mKey; + GetDnsCacheDumpHandler* mHandler; + }; + + SelectInterruptor mSelectInterruptor; + FdPollItemHandle mInterruptorHandle; + + resip::Fifo<Command> mCommandFifo; + + const unsigned char* skipDNSQuestion(const unsigned char *aptr, + const unsigned char *abuf, + int alen); + const unsigned char* createOverlay(const unsigned char* abuf, + const int alen, + const unsigned char* aptr, + std::vector<RROverlay>&, + bool discard=false); + void removeQuery(Query*); + void lookupRecords(const Data& target, unsigned short type, DnsRawSink* sink); + Data errorMessage(int status); + + ResultTransform* mTransform; + ExternalDns* mDnsProvider; + FdPollGrp* mPollGrp; + std::set<Query*> mQueries; + + std::vector<Data> mEnumSuffixes; // where to do enum lookups + std::map<Data,Data> mEnumDomains; + + static int mDnsTimeout; // in seconds + static int mDnsTries; + static unsigned int mDnsFeatures; // bit mask of ExternalDns::Features + + /// if this object exists, it gets notified when ApplicationMessage's get posted + AsyncProcessHandler* mAsyncProcessHandler; + + /// Dns Cache + RRCache mRRCache; +}; + +typedef DnsStub::Protocol Protocol; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/rutil/dns/DnsThread.cxx b/src/libs/resiprocate/rutil/dns/DnsThread.cxx new file mode 100644 index 00000000..d9034b68 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsThread.cxx @@ -0,0 +1,92 @@ +#include "rutil/dns/DnsThread.hxx" + +#include "rutil/dns/DnsStub.hxx" +#include "rutil/FdPoll.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS + +namespace resip +{ +DnsThread::DnsThread(DnsStub& dns) : + mDnsStub(dns) +{ + // ?bwc? Allow creator to specify the FdPollGrp? + // .bwc. Should use an FdSet based poll group if we're using cares. + mPollGrp.reset(FdPollGrp::create()); + mDnsStub.setPollGrp(mPollGrp.get()); +} + +DnsThread::~DnsThread() +{ + mDnsStub.setPollGrp(0); +} + +void +DnsThread::thread() +{ + while(!isShutdown()) + { + try + { + mDnsStub.processTimers(); + if (mPollGrp.get()) + mPollGrp->waitAndProcess(25); + } + catch(BaseException& e) + { + ErrLog(<< "Unhandled exception: " << e); + } + } +} + +} // of namespace resip + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/DnsThread.hxx b/src/libs/resiprocate/rutil/dns/DnsThread.hxx new file mode 100644 index 00000000..a318049a --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/DnsThread.hxx @@ -0,0 +1,79 @@ +#ifndef DnsThread_Include_Guard +#define DnsThread_Include_Guard + +#include <memory> +#include "rutil/ThreadIf.hxx" + +namespace resip +{ +class DnsStub; +class FdPollGrp; + +class DnsThread : public ThreadIf +{ + public: + DnsThread(DnsStub& dns); + virtual ~DnsThread(); + + +/////////////////// Must implement unless abstract /// + + virtual void thread(); + + protected: + DnsStub& mDnsStub; + std::auto_ptr<FdPollGrp> mPollGrp; +}; // class DnsThread + +} // namespace resip + +#endif // include guard + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/ExternalDns.hxx b/src/libs/resiprocate/rutil/dns/ExternalDns.hxx new file mode 100644 index 00000000..fbdaadb1 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/ExternalDns.hxx @@ -0,0 +1,186 @@ +#if !defined(RESIP_EXTERNAL_DNS_HXX) +#define RESIP_EXTERNAL_DNS_HXX + +#include <vector> + +#include "rutil/AsyncID.hxx" +#include "rutil/GenericIPAddress.hxx" + +struct hostent; + +namespace resip +{ +class ExternalDnsHandler; +class ExternalDnsRawResult; +class ExternalDnsHostResult; +class FdPollGrp; + +//used by the asynchronous executive +class ExternalDns +{ + public: + enum Features + { + None = 0, + TryServersOfNextNetworkUponRcode3 = 1 << 0 // 'No such name' + }; + + //returns Success, BuildMismatch, otherwise ExternalDns specific + //error message can be pulled from errorMessage + enum InitResult + { + Success = 0, + BuildMismatch = 4777 + }; + + + // + virtual int init(const std::vector<GenericIPAddress>& additionalNameservers, + AfterSocketCreationFuncPtr, + int dnsTimeout = 0, + int dnsTries = 0, + unsigned int features = 0) = 0; // bit mask of Features + + //returns 'true' only is there are changes in the DNS server list + virtual bool checkDnsChange() = 0; + + //For use in select timeout + virtual unsigned int getTimeTillNextProcessMS() = 0; + + //this is scary on windows; the standard way to get a bigger fd_set is to + //redefine FD_SETSIZE befor each inclusion of winsock2.h, so make sure + //external libraries have been properly configured + // MUST not be called when pollGrp (below) is active + virtual void buildFdSet(fd_set& read, fd_set& write, int& size) = 0; + virtual void process(fd_set& read, fd_set& write) = 0; + + virtual void setPollGrp(FdPollGrp *grp) = 0; + + // called by DnsStub to process timers requested by getTimeTillNext...() + // only used when poll group is active + virtual void processTimers() = 0; + + virtual void freeResult(ExternalDnsRawResult res) = 0; + virtual void freeResult(ExternalDnsHostResult res) = 0; + + //caller must clean up memory + virtual char* errorMessage(long errorCode) = 0; + + virtual ~ExternalDns() {} + + virtual void lookup(const char* target, unsigned short type, ExternalDnsHandler* handler, void* userData) = 0; + + virtual bool hostFileLookup(const char* target, in_addr &addr) = 0; + virtual bool hostFileLookupLookupOnlyMode() = 0; +}; + +class ExternalDnsResult : public AsyncResult +{ + public: + ExternalDnsResult(long errorCode, void* uData) : AsyncResult(errorCode) , userData(uData) {} + ExternalDnsResult(void* uData) : userData(uData) {} + void* userData; +}; + +//should this be nested? +class ExternalDnsRawResult : public ExternalDnsResult +{ + public: + ExternalDnsRawResult(unsigned char* buf, int len, void* uData) : + ExternalDnsResult(uData), + + abuf(buf), + alen(len) + {} + ExternalDnsRawResult(long errorCode, unsigned char* buf, int len, void* uData) : + ExternalDnsResult(errorCode, uData), + abuf(buf), + alen(len) + {} + + unsigned char* abuf; + int alen; +}; + +class ExternalDnsHostResult : public ExternalDnsResult +{ + public: + ExternalDnsHostResult(hostent* h, void* uData) : + ExternalDnsResult(uData), + host(h) + {} + ExternalDnsHostResult(long errorCode, void* uData) : ExternalDnsResult(errorCode, uData) {} + + hostent* host; +}; + +class ExternalDnsHandler +{ + public: + //underscores are against convention, but pretty impossible to read + //otherwise. ?dcm? -- results stack or heap? + //the free routines can be dealt w/ iheritence instead if pointers are used + //virtual void handle_NAPTR(ExternalDnsRawResult res) = 0; + //virtual void handle_SRV(ExternalDnsRawResult res) = 0; + //virtual void handle_AAAA(ExternalDnsRawResult res) = 0; + //virtual void handle_host(ExternalDnsHostResult res) = 0; + + // new version + virtual ~ExternalDnsHandler() {} + virtual void handleDnsRaw(ExternalDnsRawResult res) = 0; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/ExternalDnsFactory.cxx b/src/libs/resiprocate/rutil/dns/ExternalDnsFactory.cxx new file mode 100644 index 00000000..91c19702 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/ExternalDnsFactory.cxx @@ -0,0 +1,96 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if !defined(WIN32) +#include <sys/types.h> +#endif + +//#define USE_LOCAL_DNS +#ifdef USE_LOCAL_DNS +#include "rutil/dns/LocalDns.hxx" +#else +#include "rutil/dns/AresDns.hxx" +#endif + +#include "rutil/dns/ExternalDnsFactory.hxx" +#include "rutil/WinLeakCheck.hxx" + + +using namespace resip; + +ExternalDnsCreator* ExternalDnsFactory::mCreator = 0; + +void +ExternalDnsFactory::setExternalCreator(ExternalDnsCreator* creator) +{ + mCreator = creator; +} + +ExternalDns* +ExternalDnsFactory::createExternalDns() +{ + if(mCreator) + { + return mCreator->createExternalDns(); + } + else + { +#ifdef USE_LOCAL_DNS + InfoLog (<< "Using Local DNS instead of Ares. Should only be used for tests."); + return new LocalDns(); +#else + return new AresDns(); +#endif + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/ExternalDnsFactory.hxx b/src/libs/resiprocate/rutil/dns/ExternalDnsFactory.hxx new file mode 100644 index 00000000..bed8e6f4 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/ExternalDnsFactory.hxx @@ -0,0 +1,78 @@ +#ifndef RESIP_ExternalDnsFactory_HXX +#define RESIP_ExternalDnsFactory_HXX + + +namespace resip +{ +class ExternalDns; + +// If no creator is provided (via setExternalCreator), then default is to use AresDns +class ExternalDnsCreator +{ +public: + virtual ~ExternalDnsCreator(){} + virtual ExternalDns* createExternalDns() = 0; +}; + +class ExternalDnsFactory +{ +public: + static ExternalDns* createExternalDns(); + static void setExternalCreator(ExternalDnsCreator* creator); +private: + static ExternalDnsCreator* mCreator; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/LocalDns.cxx b/src/libs/resiprocate/rutil/dns/LocalDns.cxx new file mode 100644 index 00000000..86e689ef --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/LocalDns.cxx @@ -0,0 +1,183 @@ +#include <fstream> + +#include "rutil/dns/LocalDns.hxx" +#include "rutil/WinLeakCheck.hxx" + +#include "ares.h" +#include "ares_dns.h" +#ifdef WIN32 +#undef write // Note: ares.h defines write to be _write for WIN32 - we don't want that here, since we use fdset.write and stream write +#endif + +#include "AresCompat.hxx" + +#if !defined(WIN32) +#include <arpa/nameser.h> +#endif + +using namespace resip; +using namespace std; + +std::map<Data, Data> LocalDns::files; +Data LocalDns::mTarget; + +int +LocalDns::init() +{ + int status; + if ((status = ares_init(&mChannel)) != ARES_SUCCESS) + { + return status; + } + else + { + return 0; + } +} + +LocalDns::LocalDns() +{ + files["yahoo.com"] = "yahoo.dns"; + files["demo.xten.com"] = "demo.naptr"; + files["_ldap._tcp.openldap.org"] = "openldap.srv"; + files["quartz"] = "quartz.aaaa"; + files["crystal"] = "crystal.aaaa"; + files["www.google.com"] = "google.cname"; +} + +LocalDns::~LocalDns() +{ +} + +ExternalDnsHandler* +LocalDns::getHandler(void* arg) +{ + Payload* p = reinterpret_cast<Payload*>(arg); + ExternalDnsHandler *thisp = reinterpret_cast<ExternalDnsHandler*>(p->first); + return thisp; +} + +ExternalDnsRawResult +LocalDns::makeRawResult(void *arg, int status, unsigned char *abuf, int alen) +{ + Payload* p = reinterpret_cast<Payload*>(arg); + void* userArg = reinterpret_cast<void*>(p->second); + + if (status != ARES_SUCCESS) + { + return ExternalDnsRawResult(status, abuf, alen, userArg); + } + else + { + return ExternalDnsRawResult(abuf, alen, userArg); + } +} + +unsigned int +LocalDns::getTimeTillNextProcessMS() +{ + return 20; +} + +void +LocalDns::buildFdSet(fd_set& read, fd_set& write, int& size) +{ +} + +void +LocalDns::process(fd_set& read, fd_set& write) +{ +} + +void +LocalDns::lookup(const char* target, unsigned short type, ExternalDnsHandler* handler, void* userData) +{ + mTarget = target; + ares_query(mChannel, target, C_IN, type, LocalDns::localCallback, new Payload(handler, userData)); +} + +void LocalDns::message(const char* file, unsigned char* buf, int& len) +{ + len = 0; + ifstream fs; + fs.open(file, ios_base::binary | ios_base::in); + assert(fs.is_open()); + + unsigned char* p = buf; + + while (!fs.eof()) + { + unsigned char c = fs.get(); + if (c != char_traits<char>::eof()) + { + *p++ = c; + len++; + } + } + + fs.close(); +} + +void +LocalDns::localCallback(void *arg, int status, unsigned char *abuf, int alen) +{ + unsigned char msg[1024]; + int len = 0; + map<Data, Data>::iterator it = files.find(mTarget); + assert(it != files.end()); + message(it->second.c_str(), msg, len); + assert(0 != len); + getHandler(arg)->handleDnsRaw(makeRawResult(arg, 0, msg, len)); + Payload* p = reinterpret_cast<Payload*>(arg); + delete p; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/LocalDns.hxx b/src/libs/resiprocate/rutil/dns/LocalDns.hxx new file mode 100644 index 00000000..934c90fa --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/LocalDns.hxx @@ -0,0 +1,115 @@ +#if !defined(RESIP_LOCAL_DNS_HXX) +#define RESIP_LOCAL_DNS_HXX + +#include <map> +#include "rutil/Data.hxx" +#include "rutil/dns/ExternalDns.hxx" + +extern "C" +{ +struct ares_channeldata; +} + + +namespace resip +{ +class LocalDns : public ExternalDns +{ + public: + LocalDns(); + virtual ~LocalDns(); + + virtual int init(); + virtual unsigned int getTimeTillNextProcessMS(); + virtual void buildFdSet(fd_set& read, fd_set& write, int& size); + virtual void process(fd_set& read, fd_set& write); + + virtual void freeResult(ExternalDnsRawResult /* res */) {} + virtual void freeResult(ExternalDnsHostResult /* res */) {} + + void lookup(const char* target, unsigned short type, ExternalDnsHandler* handler, void* userData); + + virtual void lookupARecords(const char* /*target*/, ExternalDnsHandler* /*handler*/, void* /*userData*/) {} + virtual void lookupAAAARecords(const char* /*target*/, ExternalDnsHandler* /*handler*/, void* /*userData*/) {} + virtual void lookupNAPTR(const char* /*target*/, ExternalDnsHandler* /*handler*/, void* /*userData*/) {} + virtual void lookupSRV(const char* /*target*/, ExternalDnsHandler* /*handler*/, void* /*userData*/) {} + virtual char* errorMessage(long /*errorCode*/) + { + const char* msg = "Local Dns"; + + int len = (int)strlen(msg); + char* errorString = new char[len+1]; + + strncpy(errorString, msg, len); + errorString[len] = '\0'; + return errorString; + } + + private: + + struct ares_channeldata* mChannel; + + typedef std::pair<ExternalDnsHandler*, void*> Payload; + static ExternalDnsRawResult makeRawResult(void *arg, int status, unsigned char *abuf, int alen); + static ExternalDnsHandler* getHandler(void* arg); + + static void localCallback(void *arg, int status, unsigned char* abuf, int alen); + + static void message(const char* file, unsigned char* buf, int& len); + static std::map<Data, Data> files; + static Data mTarget; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/QueryTypes.cxx b/src/libs/resiprocate/rutil/dns/QueryTypes.cxx new file mode 100644 index 00000000..054f2a81 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/QueryTypes.cxx @@ -0,0 +1,79 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "QueryTypes.hxx" + +using namespace resip; + +#define defineQueryType(_name, _type, _rrType) \ + Data RR_##_name::getRRTypeName() \ +{ \ + return #_name; \ +} \ +unsigned short RR_##_name::getRRType() \ +{ \ + return _rrType; \ +} \ +RR_##_name resip::q_##_name + +defineQueryType(A, DnsHostRecord, 1); +defineQueryType(CNAME, DnsCnameRecord, 5); + +#ifdef USE_IPV6 +defineQueryType(AAAA, DnsAAAARecord, 28); +#endif + +defineQueryType(SRV, DnsSrvRecord, 33); +defineQueryType(NAPTR, DnsNaptrRecord, 35); + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + diff --git a/src/libs/resiprocate/rutil/dns/QueryTypes.hxx b/src/libs/resiprocate/rutil/dns/QueryTypes.hxx new file mode 100644 index 00000000..a3b7edc0 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/QueryTypes.hxx @@ -0,0 +1,104 @@ +#ifndef RESIP_QUERY_TYPES_HXX +#define RESIP_QUERY_TYPES_HXX + +#include "rutil/HeapInstanceCounter.hxx" +#include "rutil/compat.hxx" +#include "rutil/Socket.hxx" +#include "rutil/BaseException.hxx" +#include "DnsResourceRecord.hxx" +#include "DnsHostRecord.hxx" +#include "DnsCnameRecord.hxx" +#include "DnsAAAARecord.hxx" +#include "DnsSrvRecord.hxx" +#include "DnsNaptrRecord.hxx" + +//'Interface' of the RRType concept +// class QueryType +// { +// public: +// static unsigned short getRRType(); +// enum SupportsCName; //does following CNAME apply to this query type +// }; + + +//!dcm! -- add UnusedChecking(_enum) below; + +namespace resip +{ + +#define defineQueryType(_name, _type, _rrType, _supportsCName, _rfc) \ +class RR_##_name \ +{ \ + public: \ + RESIP_HeapCount(RR_##_name); \ + enum {SupportsCName = _supportsCName}; \ + static unsigned short getRRType(); \ + typedef _type Type; \ + static Data getRRTypeName(); \ +}; \ +extern RR_##_name q_##_name + +defineQueryType(A, DnsHostRecord, 1, true, "RFC 1035"); +defineQueryType(CNAME, DnsCnameRecord, 5, false, "RFC 1035"); + +defineQueryType(AAAA, DnsAAAARecord, 28, true, "RFC 3596"); + +defineQueryType(SRV, DnsSrvRecord, 33, true, "RFC 2782"); +defineQueryType(NAPTR, DnsNaptrRecord, 35, true, "RFC 2915"); + +} + +#undef defineQueryType + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/dns/RRCache.cxx b/src/libs/resiprocate/rutil/dns/RRCache.cxx new file mode 100644 index 00000000..0e20f3d0 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/RRCache.cxx @@ -0,0 +1,307 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "AresCompat.hxx" + +#ifndef WIN32 +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#ifndef __CYGWIN__ +# include <netinet/in.h> +# include <arpa/nameser.h> +# include <resolv.h> +#endif +#include <netdb.h> +#include <netinet/in.h> +#else +#include <Winsock2.h> +#include <svcguid.h> +#ifdef USE_IPV6 +#include <ws2tcpip.h> +#endif +#endif + +#include <set> +#include <vector> +#include <list> +#include <map> +#include <cassert> +#include "rutil/BaseException.hxx" +#include "rutil/Data.hxx" +#include "rutil/Timer.hxx" +#include "rutil/dns/RRFactory.hxx" +#include "rutil/dns/RROverlay.hxx" +#include "rutil/dns/RRFactory.hxx" +#include "rutil/dns/DnsResourceRecord.hxx" +#include "rutil/dns/DnsAAAARecord.hxx" +#include "rutil/dns/DnsHostRecord.hxx" +#include "rutil/dns/DnsNaptrRecord.hxx" +#include "rutil/dns/DnsSrvRecord.hxx" +#include "rutil/dns/DnsCnameRecord.hxx" +#include "rutil/dns/RRCache.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +RRCache::RRCache() + : mHead(), + mLruHead(LruListType::makeList(&mHead)), + mUserDefinedTTL(DEFAULT_USER_DEFINED_TTL), + mSize(DEFAULT_SIZE) +{ + mFactoryMap[T_CNAME] = &mCnameRecordFactory; + mFactoryMap[T_NAPTR] = &mNaptrRecordFacotry; + mFactoryMap[T_SRV] = &mSrvRecordFactory; +#ifdef USE_IPV6 + mFactoryMap[T_AAAA] = &mAAAARecordFactory; +#endif + mFactoryMap[T_A] = &mHostRecordFactory; +} + +RRCache::~RRCache() +{ + cleanup(); +} + +void +RRCache::updateCacheFromHostFile(const DnsHostRecord &record) +{ + //FactoryMap::iterator it = mFactoryMap.find(T_A); + RRList* key = new RRList(record, 3600); + RRSet::iterator lb = mRRSet.lower_bound(key); + if (lb != mRRSet.end() && + !(mRRSet.key_comp()(key, *lb))) + { + (*lb)->update(record, 3600); + touch(*lb); + } + else + { + RRList* val = new RRList(record, 3600); + mRRSet.insert(val); + mLruHead->push_back(val); + purge(); + } + delete key; +} + +void +RRCache::updateCache(const Data& target, + const int rrType, + Itr begin, + Itr end) +{ + Data domain = (*begin).domain(); + FactoryMap::iterator it = mFactoryMap.find(rrType); + assert(it != mFactoryMap.end()); + RRList* key = new RRList(domain, rrType); + RRSet::iterator lb = mRRSet.lower_bound(key); + if (lb != mRRSet.end() && + !(mRRSet.key_comp()(key, *lb))) + { + (*lb)->update(it->second, begin, end, mUserDefinedTTL); + touch(*lb); + } + else + { + RRList* val = new RRList(it->second, domain, rrType, begin, end, mUserDefinedTTL); + mRRSet.insert(val); + mLruHead->push_back(val); + purge(); + } + delete key; +} + +void +RRCache::cacheTTL(const Data& target, + const int rrType, + const int status, + RROverlay overlay) +{ + int ttl = getTTL(overlay); + + if (ttl < 0) + { + return; + } + + if (ttl < mUserDefinedTTL) + { + ttl = mUserDefinedTTL; + } + + RRList* val = new RRList(target, rrType, ttl, status); + RRSet::iterator it = mRRSet.find(val); + if (it != mRRSet.end()) + { + (*it)->remove(); + delete *it; + mRRSet.erase(it); + } + mRRSet.insert(val); + mLruHead->push_back(val); + purge(); +} + +bool +RRCache::lookup(const Data& target, + const int type, + const int protocol, + Result& records, + int& status) +{ + records.empty(); + status = 0; + RRList* key = new RRList(target, type); + RRSet::iterator it = mRRSet.find(key); + delete key; + if (it == mRRSet.end()) + { + return false; + } + else + { + if (Timer::getTimeSecs() >= (*it)->absoluteExpiry()) + { + delete *it; + mRRSet.erase(it); + return false; + } + else + { + records = (*it)->records(protocol); + status = (*it)->status(); + touch(*it); + return true; + } + } +} + +void +RRCache::clearCache() +{ + cleanup(); +} + +void +RRCache::touch(RRList* node) +{ + node->remove(); + mLruHead->push_back(node); +} + +void +RRCache::cleanup() +{ + for (std::set<RRList*, CompareT>::iterator it = mRRSet.begin(); it != mRRSet.end(); it++) + { + (*it)->remove(); + delete *it; + } + mRRSet.clear(); +} + +int +RRCache::getTTL(const RROverlay& overlay) +{ + // overlay is a soa answer. + if (overlay.type() != T_SOA) return -1; + char* name = 0; + long len = 0; + int status = ares_expand_name(overlay.data(), overlay.msg(), overlay.msgLength(), &name, &len); + assert( status == ARES_SUCCESS ); + const unsigned char* pPos = overlay.data() + len; + free(name); name = 0; + status = ares_expand_name(pPos, overlay.msg(), overlay.msgLength(), &name, &len); + assert( status == ARES_SUCCESS ); + free(name); + pPos += len; + pPos += 16; // skip four 32 bit entities. + return DNS__32BIT(pPos); +} + +void +RRCache::purge() +{ + if (mRRSet.size() < mSize) return; + RRList* lst = *(mLruHead->begin()); + RRSet::iterator it = mRRSet.find(lst); + assert(it != mRRSet.end()); + lst->remove(); + delete *it; + mRRSet.erase(it); +} + +void +RRCache::logCache() +{ + for (std::set<RRList*, CompareT>::iterator it = mRRSet.begin(); it != mRRSet.end(); it++) + { + (*it)->log(); + } +} + +void +RRCache::getCacheDump(Data& dnsCacheDump) +{ + DataStream strm(dnsCacheDump); + for (std::set<RRList*, CompareT>::iterator it = mRRSet.begin(); it != mRRSet.end(); it++) + { + (*it)->encodeRRList(strm); + } + strm.flush(); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/RRCache.hxx b/src/libs/resiprocate/rutil/dns/RRCache.hxx new file mode 100644 index 00000000..0971eebb --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/RRCache.hxx @@ -0,0 +1,154 @@ +#ifndef RESIP_RRCACHE_HXX +#define RESIP_RRCACHE_HXX + +#include <map> +#include <set> +#include <memory> + +#include "rutil/dns/RRFactory.hxx" +#include "rutil/dns/DnsResourceRecord.hxx" +#include "rutil/dns/DnsAAAARecord.hxx" +#include "rutil/dns/DnsHostRecord.hxx" +#include "rutil/dns/DnsNaptrRecord.hxx" +#include "rutil/dns/DnsSrvRecord.hxx" +#include "rutil/dns/DnsCnameRecord.hxx" +#include "rutil/dns/RRList.hxx" + +namespace resip +{ +class RROverlay; + +class RRCache +{ + public: + typedef RRList::Protocol Protocol; + typedef RRList::LruList LruListType; + typedef RRList::Records Result; + typedef std::vector<RROverlay>::const_iterator Itr; + typedef std::vector<Data> DataArr; + + RRCache(); + ~RRCache(); + void setTTL(int ttl) { if (ttl > 0) mUserDefinedTTL = ttl * MIN_TO_SEC; } + void setSize(int size) { mSize = size; } + // Update existing cache record, or add a new one + void updateCache(const Data& target, + const int rrType, + Itr begin, + Itr end); + void updateCacheFromHostFile(const DnsHostRecord&); + // Called to update the cache when there are DNS server errors (ie. record not found) + void cacheTTL(const Data& target, + const int rrType, + const int status, + RROverlay overlay); + bool lookup(const Data& target, const int type, const int proto, Result& records, int& status); + void clearCache(); + void logCache(); + void getCacheDump(Data& dnsCacheDump); + + private: + static const int MIN_TO_SEC = 60; + static const int DEFAULT_USER_DEFINED_TTL = 10; // in seconds. + + static const int DEFAULT_SIZE = 512; + class CompareT : public std::binary_function<const RRList*, const RRList*, bool> + { + public: + bool operator()(RRList* lhs, RRList* rhs) const + { + if (lhs->rrType() < rhs->rrType()) + { + return true; + } + else if (lhs->rrType() > rhs->rrType()) + { + return false; + } + else + { + return lhs->key() < rhs->key(); + } + } + }; + + void touch(RRList* node); + void cleanup(); + int getTTL(const RROverlay& overlay); + void purge(); + + RRList mHead; + LruListType* mLruHead; + Result Empty; + + typedef std::set<RRList*, CompareT> RRSet; + RRSet mRRSet; + + RRFactory<DnsHostRecord> mHostRecordFactory; + RRFactory<DnsSrvRecord> mSrvRecordFactory; + RRFactory<DnsAAAARecord> mAAAARecordFactory; + RRFactory<DnsNaptrRecord> mNaptrRecordFacotry; + RRFactory<DnsCnameRecord> mCnameRecordFactory; + + typedef std::map<int, resip::RRFactoryBase*> FactoryMap; + FactoryMap mFactoryMap; + + int mUserDefinedTTL; // used when the ttl in RR is 0 or less than default(60). in seconds. + unsigned int mSize; +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/RRFactory.hxx b/src/libs/resiprocate/rutil/dns/RRFactory.hxx new file mode 100644 index 00000000..cbd3a3a7 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/RRFactory.hxx @@ -0,0 +1,79 @@ +#if !defined(RESIP_RRFACTORY_HXX) +#define RESIP_RRFACTORY_HXX + +#include "rutil/dns/DnsResourceRecord.hxx" +#include "rutil/dns/RROverlay.hxx" + +namespace resip +{ + +class RRFactoryBase +{ + public: + virtual ~RRFactoryBase() {} + virtual DnsResourceRecord* create(const RROverlay&) const = 0; +}; + +template<class T> +class RRFactory : public RRFactoryBase +{ + public: + virtual DnsResourceRecord* create(const RROverlay& overlay) const + { + return new T(overlay); + } +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/RRList.cxx b/src/libs/resiprocate/rutil/dns/RRList.cxx new file mode 100644 index 00000000..e63a9dcc --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/RRList.cxx @@ -0,0 +1,284 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <vector> +#include <list> + +#include "ares.h" +#ifdef WIN32 +#undef write // Note: ares.h defines write to be _write for WIN32 - we don't want that here, since we use fdset.write and stream write +#endif + +#ifndef WIN32 +#ifndef __CYGWIN__ +#include <arpa/nameser.h> +#endif +#endif + +#include "rutil/Logger.hxx" +#include "rutil/compat.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/Timer.hxx" +#include "rutil/DnsUtil.hxx" +#include "rutil/dns/DnsResourceRecord.hxx" +#include "rutil/dns/DnsHostRecord.hxx" +#include "rutil/dns/RRFactory.hxx" +#include "rutil/dns/RRList.hxx" +#include "rutil/dns/DnsAAAARecord.hxx" +#include "rutil/dns/DnsHostRecord.hxx" +#include "rutil/dns/DnsNaptrRecord.hxx" +#include "rutil/dns/DnsSrvRecord.hxx" +#include "rutil/dns/DnsCnameRecord.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS + +RRList::RRList() : mRRType(0), mStatus(0), mAbsoluteExpiry(ULONG_MAX) {} + +RRList::RRList(const Data& key, + const int rrtype, + int ttl, + int status) + : mKey(key), mRRType(rrtype), mStatus(status) +{ + mAbsoluteExpiry = ttl + Timer::getTimeSecs(); +} + +RRList::RRList(const DnsHostRecord &record, int ttl) + : mKey(record.name()), mRRType(T_A), mStatus(0), mAbsoluteExpiry(ULONG_MAX) +{ + update(record, ttl); +} + +void RRList::update(const DnsHostRecord &record, int ttl) +{ + this->clear(); + + RecordItem item; + item.record = new DnsHostRecord(record); + mRecords.push_back(item); + mAbsoluteExpiry = Timer::getTimeSecs() + ttl; +} + +RRList::RRList(const Data& key, int rrtype) + : mKey(key), mRRType(rrtype), mStatus(0), mAbsoluteExpiry(ULONG_MAX) +{} + +RRList::~RRList() +{ + this->clear(); +} + +RRList::RRList(const RRFactoryBase* factory, + const Data& key, + const int rrType, + Itr begin, + Itr end, + int ttl) + : mKey(key), mRRType(rrType), mStatus(0) +{ + update(factory, begin, end, ttl); +} + +void RRList::update(const RRFactoryBase* factory, Itr begin, Itr end, int ttl) +{ + this->clear(); + mAbsoluteExpiry = ULONG_MAX; + + for (Itr it = begin; it != end; it++) + { + try + { + RecordItem item; + item.record = factory->create(*it); + mRecords.push_back(item); + if ((UInt64)it->ttl() < mAbsoluteExpiry) + { + mAbsoluteExpiry = it->ttl(); + } + } + catch (BaseException& e) + { + ErrLog(<< e.getMessage() << endl); + } + } + + if (mAbsoluteExpiry < (UInt64)ttl) + { + mAbsoluteExpiry = ttl; + } + + mAbsoluteExpiry += Timer::getTimeSecs(); +} + +RRList::Records RRList::records(const int protocol) +{ + Records records; + if (mRecords.empty()) return records; + + for (std::vector<RecordItem>::iterator it = mRecords.begin(); it != mRecords.end(); ++it) + { + records.push_back((*it).record); + } + return records; +} + +RRList::RecordItr RRList::find(const Data& value) +{ + for (RecordItr it = mRecords.begin(); it != mRecords.end(); ++it) + { + if ((*it).record->isSameValue(value)) + { + return it; + } + } + return mRecords.end(); +} + +void RRList::clear() +{ + for (RecordArr::iterator it = mRecords.begin(); it != mRecords.end(); ++it) + { + delete (*it).record; + } + mRecords.clear(); +} + +EncodeStream& +RRList::encodeRecordItem(RRList::RecordItem& item, EncodeStream& strm) +{ + strm << "DNSCACHE: Type="; + + switch(mRRType) + { + case T_CNAME: + { + DnsCnameRecord* record = dynamic_cast<DnsCnameRecord*>(item.record); + assert(record); + strm << "CNAME: " << record->name() << " -> " << record->cname(); + break; + } + + case T_NAPTR: + { + DnsNaptrRecord* record = dynamic_cast<DnsNaptrRecord*>(item.record); + assert(record); + strm << "NAPTR: " << record->name() << " -> repl=" << record->replacement() << " service=" << record->service() + << " order=" << record->order() << " pref=" << record->preference() << " flags=" << record->flags() + << " regexp=" << record->regexp().regexp(); + break; + } + + case T_SRV: + { + DnsSrvRecord* record = dynamic_cast<DnsSrvRecord*>(item.record); + assert(record); + strm << "SRV: " << record->name() << " -> " << record->target() << ":" << record->port() + << " priority=" << record->priority() << " weight=" << record->weight(); + break; + } + +#ifdef USE_IPV6 + case T_AAAA: + { + DnsAAAARecord* record = dynamic_cast<DnsAAAARecord*>(item.record); + assert(record); + strm << "AAAA(Host): " << record->name() << " -> " << DnsUtil::inet_ntop(record->v6Address()); + break; + } +#endif + + case T_A: + { + DnsHostRecord* record = dynamic_cast<DnsHostRecord*>(item.record); + assert(record); + strm << "A(Host): " << record->name() << " -> " << record->host(); + break; + } + default: + strm << "UNKNOWN(" << mRRType << ")" << " key=" << mKey << " name=" << item.record->name(); + break; + } + + strm << " secsToExpirey=" << (mAbsoluteExpiry - Timer::getTimeSecs()) << " status=" << mStatus; + strm.flush(); + return strm; +} + +void RRList::log() +{ + for (RecordArr::iterator it = mRecords.begin(); it != mRecords.end(); ++it) + { + Data buffer; + DataStream strm(buffer); + + encodeRecordItem(*it, strm); + WarningLog( << buffer); + } +} + +EncodeStream& +RRList:: encodeRRList(EncodeStream& strm) +{ + for (RecordArr::iterator it = mRecords.begin(); it != mRecords.end(); ++it) + { + encodeRecordItem(*it, strm); + strm << endl; + } + return strm; +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/RRList.hxx b/src/libs/resiprocate/rutil/dns/RRList.hxx new file mode 100644 index 00000000..f9802cdb --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/RRList.hxx @@ -0,0 +1,136 @@ +#ifndef RESIP_DNS_RR_LIST +#define RESIP_DNS_RR_LIST + +#include <vector> + +#include "rutil/IntrusiveListElement.hxx" +#include "rutil/dns/RRFactory.hxx" + +namespace resip +{ +class DnsResourceRecord; +class DnsHostRecord; + +class RRList : public IntrusiveListElement<RRList*> +{ + public: + + class Protocol + { + public: + static const int Reserved = 0; + static const int Sip = 1; + static const int Stun = 2; + static const int Http = 3; + static const int Enum = 4; + }; + + typedef std::vector<DnsResourceRecord*> Records; + typedef IntrusiveListElement<RRList*> LruList; + typedef std::vector<RROverlay>::const_iterator Itr; + typedef std::vector<Data> DataArr; + + RRList(); + explicit RRList(const Data& key, const int rrtype, int ttl, int status); + explicit RRList(const Data& key, int rrtype); + ~RRList(); + RRList(const RRFactoryBase* factory, + const Data& key, + const int rrType, + Itr begin, + Itr end, + int ttl); + + RRList(const DnsHostRecord &record, int ttl); + void update(const DnsHostRecord &record, int ttl); + + void update(const RRFactoryBase* factory, Itr begin, Itr end, int ttl); + Records records(const int protocol); + + const Data& key() const { return mKey; } + int status() const { return mStatus; } + int rrType() const { return mRRType; } + UInt64 absoluteExpiry() const { return mAbsoluteExpiry; } + UInt64& absoluteExpiry() { return mAbsoluteExpiry; } + void log(); + EncodeStream& encodeRRList(EncodeStream& strm); + + private: + + struct RecordItem + { + DnsResourceRecord* record; + std::vector<int> blacklistedProtocols; + }; + + typedef std::vector<RecordItem> RecordArr; + typedef RecordArr::iterator RecordItr; + + RecordArr mRecords; + + Data mKey; + int mRRType; + + int mStatus; // dns query status. + UInt64 mAbsoluteExpiry; + + RecordItr find(const Data&); + void clear(); + EncodeStream& encodeRecordItem(RRList::RecordItem& item, EncodeStream& strm); +}; + +} + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/RROverlay.cxx b/src/libs/resiprocate/rutil/dns/RROverlay.cxx new file mode 100644 index 00000000..501f72eb --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/RROverlay.cxx @@ -0,0 +1,129 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "AresCompat.hxx" + +#ifndef __CYGWIN__ +#ifndef RRFIXEDSZ +#define RRFIXEDSZ 10 +#endif +#ifndef NS_RRFIXEDSZ +#define NS_RRFIXEDSZ 10 +#endif +#endif + +#include <cstdlib> +#include <vector> +#include "rutil/Data.hxx" +#include "rutil/BaseException.hxx" +#include "RROverlay.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DNS + +// aptr - points to the begining of the resource record. +// abuf - points to the begining of the message. +// alen - length of abuf. +RROverlay::RROverlay(const unsigned char *aptr, + const unsigned char *abuf, + int alen) : + mData(0), + mMsg(0), + mMsgLen(0), + mDataLen(0), + mNameLen(0), + mTTL(0), + mType(-1) +{ + char *name; + long len = 0; + + // Parse the RR name. + int status = ares_expand_name(aptr, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + { + throw OverlayException("Failed parse of RR", __FILE__, __LINE__); + } + mDomain = name; + aptr += len; + mNameLen = len; + free(name); + + // Make sure there is enough data after the RR name for the fixed + // part of the RR. + if (aptr + RRFIXEDSZ > abuf + alen) + { + throw OverlayException("Failed parse of RR", __FILE__, __LINE__); + } + + // Parse the fixed part of the RR, and advance to the RR data field. + // + mType = DNS_RR_TYPE(aptr); + mDataLen = DNS_RR_LEN(aptr); + mTTL = DNS_RR_TTL(aptr); + + aptr += RRFIXEDSZ; + if (aptr + mDataLen > abuf + alen) + { + throw OverlayException("Failed parse of RR", __FILE__, __LINE__); + } + + mData = aptr; + mMsgLen = alen; + mMsg = abuf; + aptr += mDataLen; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/dns/RROverlay.hxx b/src/libs/resiprocate/rutil/dns/RROverlay.hxx new file mode 100644 index 00000000..0aff1034 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/RROverlay.hxx @@ -0,0 +1,110 @@ +#ifndef RESIP_RR_OVERLAY_HXX +#define RESIP_RR_OVERLAY_HXX + +namespace resip +{ +class Data; +class BaseException; + +class RROverlay +{ + friend bool operator<(const RROverlay& r1, const RROverlay& r2) + { + if (r1.mType < r2.mType) + { + return true; + } + if (r1.mType > r2.mType) + { + return false; + } + return r1.mDomain < r2.mDomain; + } + + public: + RROverlay(const unsigned char *aptr, const unsigned char *abuf, int alen); + + class OverlayException : public BaseException + { + public: + OverlayException(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) + { + } + + const char* name() const { return "OverlayException"; } + }; + + const unsigned char* data() const { return mData; } + const unsigned char* msg() const { return mMsg; } + int msgLength() const { return mMsgLen; } + int dataLength() const { return mDataLen; } + int nameLength() const { return mNameLen; } + int ttl() const { return mTTL; } + int type() const { return mType; } + const Data& domain() const { return mDomain; } + + private: + const unsigned char* mData; + const unsigned char* mMsg; + int mMsgLen; + int mDataLen; + int mNameLen; + int mTTL; + int mType; //short? + Data mDomain; // the domain name this RR refers to. +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/dns/RRVip.cxx b/src/libs/resiprocate/rutil/dns/RRVip.cxx new file mode 100644 index 00000000..3a2257ee --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/RRVip.cxx @@ -0,0 +1,300 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "AresCompat.hxx" + +#include <map> +#include <list> +#include <vector> + +#ifndef WIN32 +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#ifndef __CYGWIN__ +# include <netinet/in.h> +# include <arpa/nameser.h> +# include <resolv.h> +#endif +#include <netdb.h> +#include <netinet/in.h> +#else +#include <Winsock2.h> +#include <svcguid.h> +#ifdef USE_IPV6 +#include <ws2tcpip.h> +#endif +#endif + +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" +#include "rutil/BaseException.hxx" +#include "rutil/dns/DnsResourceRecord.hxx" +#include "rutil/dns/DnsAAAARecord.hxx" +#include "rutil/dns/DnsHostRecord.hxx" +#include "rutil/dns/DnsNaptrRecord.hxx" +#include "rutil/dns/DnsSrvRecord.hxx" +#include "rutil/dns/RRVip.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS + +using namespace resip; +using namespace std; + +RRVip::RRVip() +{ + mFactories[T_A] = new HostTransformFactory; + mFactories[T_AAAA] = new HostTransformFactory; + mFactories[T_NAPTR] = new NaptrTransformFactroy; + mFactories[T_SRV] = new SrvTransformFactory; +} + +RRVip::~RRVip() +{ + for (map<MapKey, Transform*>::iterator it = mTransforms.begin(); it != mTransforms.end(); ++it) + { + delete (*it).second; + } + + for (TransformFactoryMap::iterator it = mFactories.begin(); it != mFactories.end(); ++it) + { + delete (*it).second; + } +} + +void RRVip::vip(const Data& target, + int rrType, + const Data& vip) +{ + RRVip::MapKey key(target, rrType); + TransformMap::iterator it = mTransforms.find(key); + if (it != mTransforms.end()) + { + it->second->updateVip(vip); + } + else + { + TransformFactoryMap::iterator it = mFactories.find(rrType); + assert(it != mFactories.end()); + Transform* transform = it->second->createTransform(vip); + mTransforms.insert(TransformMap::value_type(key, transform)); + } +} + +void RRVip::removeVip(const Data& target, + int rrType) +{ + RRVip::MapKey key(target, rrType); + TransformMap::iterator it = mTransforms.find(key); + if (it != mTransforms.end()) + { + Data vip = it->second->vip(); + delete (*it).second; + mTransforms.erase(it); + DebugLog(<< "removed vip " << target << "(" << rrType << "): " << vip); + } +} + +void RRVip::transform(const Data& target, + int rrType, + std::vector<DnsResourceRecord*>& src) +{ + RRVip::MapKey key(target, rrType); + TransformMap::iterator it = mTransforms.find(key); + if (it != mTransforms.end()) + { + bool invalidVip = false; + it->second->transform(src, invalidVip); + if (invalidVip) + { + removeVip(target, rrType); + } + } +} + +RRVip::Transform::Transform(const Data& vip) + : mVip(vip) +{ +} + +RRVip::Transform::~Transform() +{ +} + +void RRVip::Transform::updateVip(const Data& vip) +{ + DebugLog(<< "updating an existing vip: " << mVip << " with " << vip); + mVip = vip; +} + +void RRVip::Transform::transform(RRVector& src, + bool& invalidVip) +{ + invalidVip = true; + RRVector::iterator it; + for (it = src.begin(); it != src.end(); ++it) + { + if ((*it)->isSameValue(mVip)) + { + invalidVip = false; + break; + } + } + if(!invalidVip) + { + DebugLog( << "tranforming records"); + if (src.begin() != it) + { + DnsResourceRecord* vip = *it; + src.erase(it); + src.insert(src.begin(), vip); + } + } +} + +RRVip::NaptrTransform::NaptrTransform(const Data& vip) + : Transform(vip) +{ + DebugLog(<< "Creating a new Napter transform for " << vip); +} + +void RRVip::NaptrTransform::transform(RRVector& src, + bool& invalidVip) +{ + invalidVip = true; + RRVector::iterator vip; + for (RRVector::iterator it = src.begin(); it != src.end(); ++it) + { + if ((*it)->isSameValue(mVip)) + { + DebugLog(<< "naptr vip record " << mVip << "found"); + invalidVip = false; + vip = it; + break; + } + } + if(!invalidVip) + { + DebugLog(<< "Transforming Naptr records"); + int min = dynamic_cast<DnsNaptrRecord*>(*(src.begin()))->order(); + for (RRVector::iterator it = src.begin(); it != src.end(); ++it) + { + int order = ((dynamic_cast<DnsNaptrRecord*>(*it))->order())++; + if (order < min) min = order; + } + dynamic_cast<DnsNaptrRecord*>((*vip))->order() = min; + } +} + +RRVip::SrvTransform::SrvTransform(const Data& vip) + : Transform(vip) +{ + DebugLog(<< "Creating a new SRV transform for" << vip); +} + +void RRVip::SrvTransform::transform(RRVector& src, + bool& invalidVip) +{ + invalidVip = true; + RRVector::iterator vip; + for (RRVector::iterator it = src.begin(); it != src.end(); ++it) + { + if ((*it)->isSameValue(mVip)) + { + invalidVip = false; + vip = it; + break; + } + } + if(!invalidVip) + { + DebugLog(<< "Transforming SRV records"); + int min = dynamic_cast<DnsSrvRecord*>(*(src.begin()))->priority(); + for (RRVector::iterator it = src.begin(); it != src.end(); ++it) + { + int priority = ((dynamic_cast<DnsSrvRecord*>(*it))->priority())++; + if (priority < min) min = priority; + } + dynamic_cast<DnsSrvRecord*>((*vip))->priority() = min; + } +} + +RRVip::MapKey::MapKey() + : mRRType(0) // .kw. what is reasonable default? +{ +} + +RRVip::MapKey::MapKey(const Data& target, int rrType) + : mTarget(target), + mRRType(rrType) +{ +} + +bool RRVip::MapKey::operator<(const MapKey& rhs) const +{ + if (mRRType < rhs.mRRType) + { + return true; + } + else if (mRRType > rhs.mRRType) + { + return false; + } + else + { + return mTarget < rhs.mTarget; + } +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/dns/RRVip.hxx b/src/libs/resiprocate/rutil/dns/RRVip.hxx new file mode 100644 index 00000000..23216ae8 --- /dev/null +++ b/src/libs/resiprocate/rutil/dns/RRVip.hxx @@ -0,0 +1,147 @@ +#ifndef RESIP_RRVIP_HXX +#define RESIP_RRVIP_HXX + +#include "rutil/dns/DnsStub.hxx" + +namespace resip +{ + +class RRVip : public DnsStub::ResultTransform +{ + public: + RRVip(); + ~RRVip(); + + void vip(const Data& target, int rrType, const Data& vip); + void removeVip(const Data& target, int rrType); + void transform(const Data& target, int rrType, std::vector<DnsResourceRecord*>&); + + private: + + RRVip(const RRVip&); + RRVip& operator=(const RRVip&); + + typedef std::vector<DnsResourceRecord*> RRVector; + class Transform + { + public: + Transform(const Data& vip); + virtual ~Transform(); + virtual void transform(RRVector& rrs, bool& invalidVip); + void updateVip(const Data& vip); + const Data& vip() { return mVip; }; + + protected: + Data mVip; // ip for a/aaaa, target host for srv, and replacement for naptr. + }; + + class NaptrTransform : public Transform + { + public: + NaptrTransform(const Data& vip); + void transform(RRVector& rrs, bool&); + }; + + class SrvTransform : public Transform + { + public: + SrvTransform(const Data& vip); + void transform(RRVector& rrs, bool&); + }; + + class MapKey + { + public: + MapKey(); + MapKey(const Data& target, int rrType); + bool operator<(const MapKey&) const; + private: + Data mTarget; + int mRRType; + }; + + class TransformFactory + { + public: + virtual ~TransformFactory() {} + virtual Transform* createTransform(const Data& vip) = 0; + }; + + class HostTransformFactory : public TransformFactory + { + public: + Transform* createTransform(const Data& vip) { return new Transform(vip); } + }; + + class NaptrTransformFactroy : public TransformFactory + { + public: + Transform* createTransform(const Data& vip) { return new NaptrTransform(vip); } + }; + + class SrvTransformFactory : public TransformFactory + { + public: + Transform* createTransform(const Data& vip) { return new SrvTransform(vip); } + }; + + typedef std::map<int, TransformFactory*> TransformFactoryMap; + TransformFactoryMap mFactories; + + typedef std::map<MapKey, Transform*> TransformMap; + TransformMap mTransforms; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/fixupGperf b/src/libs/resiprocate/rutil/fixupGperf new file mode 100644 index 00000000..2b53394b --- /dev/null +++ b/src/libs/resiprocate/rutil/fixupGperf @@ -0,0 +1,85 @@ +#!/bin/sh -x +PN=$(basename $0 ) +TMPFILES="" +cleanup() +{ + for F in ${TMPFILES}; do + /bin/rm -f ${F} + done +} + +mkTemp() +{ + FN=$( mktemp fgp.XXXXXX ) + TMPFILES="${TMPFILES} ${FN}" + printf "%s\n" "${FN}" +} + +usage() +{ + printf "%s: %s\n" "${PN}" "${*}" + printf "usage: %s file -o outputfile [--include=file ...]\n" \ + "${PN}" >&2 + cleanup + exit 1 +} + +die() +{ + printf "%s: error editing. Has output changed?\n" "${PN}" >&2 + cleanup + exit 2 +} + +[ ${#} -ge 3 ] || usage too few arguments. +[ "${2}" == "-o" ] || usage syntax error. +OF="${3}" +IF="${1}" +shift +shift +shift +[ -r "${IF}" ] || usage unable to open file. + +T1=$(mkTemp) +touch ${T1} + +NS=0 +IC=0 +while [ "$#" -ge 1 ]; do + case "${1}" in + --ignorecase) IC=1;; + --ns*=*) + printf "namespace %s\n{\n" "${1//-*=}" >> ${T1} + NS=$(( ${NS} + 1 )) + ;; + + --us*=*) + printf "using %s;\n" "${1//-*=}" >> ${T1} + ;; + + --i*=*) + printf "#include \"%s\"\n" "${1//-*=}" >> ${T1} + ;; + *) ;; + esac + shift +done + +T2=$(mkTemp) + +if [ "${IC}" -eq 1 ]; then + sed 's/str\[\([0-9][0-9]*\)\]/tolower(str[\1])/g' ${IF} >> ${T1} || die + sed 's/^\([ ]*\)if *(\*\([a-z][a-z]*\) *== *\*\([a-z][a-z]*\) *&& *!strncmp (\([^)]*\)).*$/\1 if (tolower(*\2) == *\3 \&\& !strncasecmp( \4 ))/g' ${T1} > ${T2} + +else + cat ${IF} >> ${T1} + cat ${T1} > ${T2} +fi + +# Close namespaces +while [ ${NS} -gt 0 ]; do printf "}\n" >> ${T2}; NS=$(( $NS - 1 )); done + +cp ${T2} ${OF} + +cleanup +exit 0 diff --git a/src/libs/resiprocate/rutil/mainpage.doc b/src/libs/resiprocate/rutil/mainpage.doc new file mode 100644 index 00000000..34e2a50d --- /dev/null +++ b/src/libs/resiprocate/rutil/mainpage.doc @@ -0,0 +1,8 @@ +/** +@mainpage The reSIProcate Utility Library (rutil) + +The reSIProcate Utility (rutil) library provides various utility classes for use by the resip stack and Dialog Usage Manager. In some cases, these utility classes are used to provide cross-platform implementations of important system-level stuff; see resip::ThreadIf, resip::Mutex, resip::Lock, resip::Condition, resip::Random, and resip::Timer. In other cases, these classes are an alternative to commonly used classes defined in the stl (resip::Data being an alternative for a std::string). In addition, reSIProcate's DNS subsystem is part of rutil. + +Generally speaking, you will not find anything even tangentially related to SIP in rutil. For this, you need to look at the reSIProcate stack, or Dialog Usage Manager. + +*/ \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/resipfaststreams.cxx b/src/libs/resiprocate/rutil/resipfaststreams.cxx new file mode 100644 index 00000000..412141bf --- /dev/null +++ b/src/libs/resiprocate/rutil/resipfaststreams.cxx @@ -0,0 +1,61 @@ +#include "resipfaststreams.hxx" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef RESIP_USE_STL_STREAMS +resip::ResipStdCOStream resip::resipFastCerr(resip::ResipStdBuf::stdCerr); +resip::ResipStdCOStream resip::resipFastCout(resip::ResipStdBuf::stdCout); +#endif +resip::ResipStdCOStream resip::resipFastNull(resip::ResipStdBuf::null); + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2005. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/resipfaststreams.hxx b/src/libs/resiprocate/rutil/resipfaststreams.hxx new file mode 100644 index 00000000..be5603c7 --- /dev/null +++ b/src/libs/resiprocate/rutil/resipfaststreams.hxx @@ -0,0 +1,594 @@ +#if !defined(RESIP_RESIPFASTSTREAMS_HXX) +#define RESIP_RESIPFASTSTREAMS_HXX +/*! \file resipfaststreams.hxx + \brief Replaces STL streams for general encoding purposes. + + #define RESIP_USE_STL_STREAMS will use the STL for stream encoding (std::ostream). Undefining RESIP_USE_STL_STREAMS will + cause resip to use the alternative stream handling defined in this file for encoding objects. +*/ +#define RESIP_USE_STL_STREAMS + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <iostream> //for std::endl, std::cerr, etc. +#include <stdio.h> //for snprintf + +#include <cassert> +#include "rutil/compat.hxx" + +namespace resip +{ + +class ResipStreamBuf +{ + public: + ResipStreamBuf(void) + {} + virtual ~ ResipStreamBuf(void) + {} + virtual size_t writebuf(const char *s, size_t count) = 0; + virtual size_t readbuf(char *buf, size_t count) = 0; + virtual size_t putbuf(char ch) = 0; + virtual void flushbuf(void)=0; + virtual UInt64 tellpbuf(void)=0; +}; + +class ResipBasicIOStream +{ + public: + ResipBasicIOStream(void):good_(false),eof_(true) + {} + ~ResipBasicIOStream(void) + {} + + bool good(void) const + { + return good_; + } + bool eof(void) const + { + return eof_; + } + void clear(void) const + {} + + protected: + bool good_; + bool eof_; +}; + + +#if (defined(WIN32) || defined(_WIN32_WCE)) + +#if (defined(_MSC_VER) && _MSC_VER >= 1400 ) +#define SNPRINTF_1(buffer,sizeofBuffer,count,format,var1) _snprintf_s(buffer,sizeofBuffer,_TRUNCATE,format,var1) +#define LTOA(value,string,sizeofstring,radix) _ltoa_s(value,string,sizeofstring,radix) +#define ULTOA(value,string,sizeofstring,radix) _ultoa_s(value,string,sizeofstring,radix) +#define I64TOA(value,string,sizeofstring,radix) _i64toa_s(value,string,sizeofstring,radix) +#define UI64TOA(value,string,sizeofstring,radix) _ui64toa_s(value,string,sizeofstring,radix) +#define GCVT(val,num,buffer,buffersize) _gcvt_s(buffer,buffersize,val,num) +#else +# ifndef _TRUNCATE +# define _TRUNCATE -1 +# endif +# define SNPRINTF_1(buffer,sizeofBuffer,count,format,var1) _snprintf(buffer,count,format,var1) +# define LTOA(value,string,sizeofstring,radix) _ltoa(value,string,radix) +# define ULTOA(value,string,sizeofstring,radix) _ultoa(value,string,radix) +# define I64TOA(value,string,sizeofstring,radix) _i64toa(value,string,radix) +# define UI64TOA(value,string,sizeofstring,radix) _ui64toa(value,string,radix) +# define GCVT(val,sigdigits,buffer,buffersize) _gcvt(val,sigdigits,buffer) +#endif + +#else //non-windows +# ifndef _TRUNCATE +# define _TRUNCATE -1 +# endif +# define SNPRINTF_1(buffer,sizeofBuffer,count,format,var1) snprintf(buffer,sizeofBuffer,format,var1) +# define LTOA(l,buffer,bufferlen,radix) SNPRINTF_1(buffer,bufferlen,bufferlen,"%li",l) +# define ULTOA(ul,buffer,bufferlen,radix) SNPRINTF_1(buffer,bufferlen,bufferlen,"%lu",ul) +# define I64TOA(value,string,sizeofstring,radix) SNPRINTF_1(string,sizeofstring,sizeofstring,"%ll",value) +# define UI64TOA(value,string,sizeofstring,radix) SNPRINTF_1(string,sizeofstring,sizeofstring,"%llu",value) +# define GCVT(f,sigdigits,buffer,bufferlen) SNPRINTF_1(buffer,bufferlen,bufferlen,"%f",f) +# define _CVTBUFSIZE 309+40 +#endif + +/** std::ostream replacement. +*/ +class ResipFastOStream : public ResipBasicIOStream +{ + public: + ResipFastOStream(ResipStreamBuf *buf):buf_(buf) + { + good_ = true; + } + virtual ~ResipFastOStream(void) + {} + + virtual UInt64 tellp(void) + { + if (rdbuf()) + { + return rdbuf()->tellpbuf(); + } + return 0; + } + + ResipStreamBuf * rdbuf(void) const + { + return buf_; + } + + void rdbuf(ResipStreamBuf *buf) + { + buf_ = buf; + } + + ResipFastOStream & flush(void) + { + if (rdbuf()) + { + rdbuf()->flushbuf(); + } + return *this; + } + + ResipFastOStream &write(const char *s, size_t count) + { + if (rdbuf()) + { + rdbuf()->writebuf(s,count); + } + return *this; + } + + ResipFastOStream &put(char ch) + { + if (rdbuf()) + { + rdbuf()->putbuf(ch); + } + return *this; + } + + ResipFastOStream& operator<<(bool b) + { + //int i = (b == true) ? (1):(0); + *this<<(static_cast<long>(b)); + return *this; + } + + ResipFastOStream& operator<<(short s) + { + *this<<(static_cast<long>(s)); + return *this; + } + + ResipFastOStream& operator<<(unsigned short us) + { + *this<<(static_cast<unsigned long>(us)); + return *this; + } + + ResipFastOStream& operator<<(int i) + { + *this<<(static_cast<long>(i)); + return *this; + } + +#ifdef _W64 + //for size_t + ResipFastOStream& operator<<(_W64 unsigned int ui) + { + *this<<(static_cast<unsigned long>(ui)); + return *this; + } +#else + ResipFastOStream& operator<<(unsigned int ui) + { + *this<<(static_cast<unsigned long>(ui)); + return *this; + } +#endif + + ResipFastOStream& operator<<(long l) + { + if (!buf_) + { + return *this; + } + char buf[33]; + LTOA(l,buf,33,10); + size_t count = strlen(buf); + if (buf_->writebuf(buf,count) < count) + { + good_ = false; + } + + return *this; + } + + ResipFastOStream& operator<<(unsigned long ul) + { + if (!buf_) + { + return *this; + } + char buf[33]; + ULTOA(ul,buf,33,10); + size_t count = strlen(buf); + if (buf_->writebuf(buf,count) < count) + { + good_ = false; + } + + return *this; + } + +#ifdef WIN32 + ResipFastOStream& operator<<(__int64 i64) + { + if (!buf_) + { + return *this; + } + char buf[66]; + I64TOA(i64,buf,66,10); + size_t count = strlen(buf); + if (buf_->writebuf(buf,count) < count) + { + good_ = false; + } + + return *this; + } + + ResipFastOStream& operator<<(unsigned __int64 ui64) + { + if (!buf_) + { + return *this; + } + + char buf[66]; + UI64TOA(ui64,buf,66,10); + size_t count = strlen(buf); + if (buf_->writebuf(buf,count) < count) + { + good_ = false; + } + + return *this; + } +#else + ResipFastOStream& operator<<(UInt64 ui64) + { + if (!buf_) + { + return *this; + } + + char buf[66]; + UI64TOA(ui64,buf,66,10); + + size_t count = strlen(buf); + if (buf_->writebuf(buf,count) < count) + { + good_ = false; + } + + return *this; + } +#endif + + ResipFastOStream& operator<<(float f) + { + *this<< (static_cast<double>(f)); + + return *this; + } + + ResipFastOStream& operator<<(double d) + { + if (!buf_) + { + return *this; + } + + char buf[_CVTBUFSIZE]; + GCVT(d,6,buf,_CVTBUFSIZE);//6 significant digits is the default for %f + size_t count = strlen(buf); +#ifndef WIN32 + //not using the non-standard microsoft conversion functions + //remove any trailing zeros. Note that resipfastreams does not support STL stream width or precision + //modifiers + size_t idx=0; + for (; count > 1; count--) + { + idx = count-1; + if (buf[idx] != '0' && buf[idx] != '.') + { + break; + } + } +#endif + if (buf_->writebuf(buf,count) < count) + { + good_ = false; + } + + return *this; + } + + ResipFastOStream& operator<<(const void *vp) + { + if (!buf_) + { + return *this; + } + + char buf[32]; + SNPRINTF_1(buf,32,_TRUNCATE,"%p",vp); + size_t count = strlen(buf); + if (buf_->writebuf(buf,count) < count) + { + good_ = false; + } + + return *this; + } +#ifdef WIN32 + ResipFastOStream& operator<<(std::ostream& (__cdecl *_Pfn)(std::ostream&)) +#else + ResipFastOStream& operator<<(std::ostream& (*_Pfn)(std::ostream &)) +#endif + { + if (!buf_) + { + return *this; + } + + if (_Pfn == static_cast<std::ostream& (*)(std::ostream&)>(std::endl)) + { + if (buf_->writebuf("\n",1) < 1) + { + good_ = false; + } + } + else + { + assert(0); + } + return *this; + } + + private: + ResipStreamBuf *buf_; +}; + + +inline resip::ResipFastOStream& operator<<(resip::ResipFastOStream& ostr, const char *str) +{ + ostr.write(str,strlen(str)); + + return ostr; +} + +inline resip::ResipFastOStream& operator<<(resip::ResipFastOStream& ostr, char ch) +{ + ostr.put(ch); + + return ostr; +} + +inline resip::ResipFastOStream& operator<<(resip::ResipFastOStream& ostr, unsigned char ch) +{ + ostr.put((char)ch); + + return ostr; +} + +inline resip::ResipFastOStream& operator<<(resip::ResipFastOStream& ostr, const unsigned char *str) +{ + ostr.write((const char *)str,strlen((const char *)str)); + + return ostr; +} + +inline resip::ResipFastOStream& operator<<(resip::ResipFastOStream& ostr, signed char ch) +{ + ostr.put((char)ch); + + return ostr; +} + +inline resip::ResipFastOStream& operator<<(resip::ResipFastOStream& ostr, const signed char *str) +{ + ostr.write((const char *)str,strlen((const char *)str)); + + return ostr; +} + +inline resip::ResipFastOStream & operator<<(resip::ResipFastOStream &ostr, const std::string &str) +{ + ostr.write(str.c_str(),str.size()); + + return ostr; +} + +/** std::istream replacement +*/ +class ResipFastIStream : public ResipBasicIOStream +{ + public: + ResipFastIStream(ResipStreamBuf *buf):buf_(buf) + {} + virtual ~ResipFastIStream(void) + {} + + ResipStreamBuf * rdbuf(void) const + { + return buf_; + } + + ResipFastIStream &read(char *s, size_t count) + { + if (rdbuf()) + { + rdbuf()->readbuf(s,count); + } + return *this; + } + + private: + ResipStreamBuf *buf_; +}; + +/** Used to replace std::cerr, std::cout, etc. +*/ +class ResipStdBuf : public ResipStreamBuf +{ + public: + typedef enum BufType + { + null, + stdCerr, + stdCout + } BufType; + + ResipStdBuf(BufType type) + :type_(type) + {} + + ~ResipStdBuf(void) + {} + + virtual size_t writebuf(const char *s, size_t count) + { + switch (type_) + { + case stdCerr: + { + std::cerr << s; + break; + } + case stdCout: + { + std::cout << s; + break; + } + default: + break; + } + return count; + } + virtual size_t readbuf(char * /*buf*/, size_t /*count*/) + { + return 0; + } + virtual size_t putbuf(char ch) + { + return writebuf(&ch,1); + } + virtual void flushbuf(void) + {} + virtual UInt64 tellpbuf(void) + { + return 0; + } + + private: + BufType type_; +}; + +/** A direct replacement for std::cout, std::cerr, etc. +*/ +class ResipStdCOStream: public ResipFastOStream +{ + public: + ResipStdCOStream(ResipStdBuf::BufType type) + :ResipFastOStream(0),buf_(type) + { + rdbuf(&buf_); + } + + ~ResipStdCOStream(void) + {} + + private: + ResipStdBuf buf_; +}; + +#ifdef RESIP_USE_STL_STREAMS +#define EncodeStream std::ostream +#define DecodeStream std::istream +#define resipCerr std::cerr +#define resipCout std::cout +#else +#define EncodeStream resip::ResipFastOStream +#define DecodeStream resip::ResipFastIStream +extern ResipStdCOStream resipFastCerr; +extern ResipStdCOStream resipFastCout; +#define resipCerr resip::resipFastCerr +#define resipCout resip::resipFastCout +#endif +extern ResipStdCOStream resipFastNull; + +} //namespace resip + +#endif //RESIP_RESIPFASTSTREAMS_HXX + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2005. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ + + + + diff --git a/src/libs/resiprocate/rutil/rutil.pro b/src/libs/resiprocate/rutil/rutil.pro new file mode 100644 index 00000000..55c6c8dd --- /dev/null +++ b/src/libs/resiprocate/rutil/rutil.pro @@ -0,0 +1,157 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2010-11-29T21:30:22 +# +#------------------------------------------------- + +QT -= core gui + +TARGET = rutil +TEMPLATE = lib +CONFIG += staticlib +INCLUDEPATH += ../ ../contrib/ares ../../contrib/ares +DEFINES += USE_ARES USE_IPV6 _WIN32_WINNT=0x0501 + +win32 { + DESTDIR = ../../../Libs/compiled/win +} + +SOURCES += \ + FileSystem.cxx \ + DnsUtil.cxx \ + DataStream.cxx \ + Data.cxx \ + CountStream.cxx \ + Condition.cxx \ + Coders.cxx \ + BaseException.cxx \ + AbstractFifo.cxx \ + Log.cxx \ + Lock.cxx \ + HeapInstanceCounter.cxx \ + resipfaststreams.cxx \ + RecursiveMutex.cxx \ + Random.cxx \ + RADIUSDigestAuthenticator.cxx \ + Poll.cxx \ + ParseException.cxx \ + ParseBuffer.cxx \ + Mutex.cxx \ + MD5Stream.cxx \ + vmd5.cxx \ + TransportType.cxx \ + Timer.cxx \ + Time.cxx \ + ThreadIf.cxx \ + SysLogStream.cxx \ + SysLogBuf.cxx \ + Subsystem.cxx \ + Socket.cxx \ + RWMutex.cxx \ + dns/RRVip.cxx \ + dns/RROverlay.cxx \ + dns/RRList.cxx \ + dns/RRCache.cxx \ + dns/QueryTypes.cxx \ + dns/LocalDns.cxx \ + dns/ExternalDnsFactory.cxx \ + dns/DnsStub.cxx \ + dns/DnsSrvRecord.cxx \ + dns/DnsResourceRecord.cxx \ + dns/DnsNaptrRecord.cxx \ + dns/DnsHostRecord.cxx \ + dns/DnsCnameRecord.cxx \ + dns/DnsAAAARecord.cxx \ + dns/AresDns.cxx \ + ssl/SHA1Stream.cxx \ + ssl/OpenSSLInit.cxx \ + stun/Udp.cxx \ + stun/Stun.cxx \ + ssl/SHA1Stream.cxx \ + ssl/OpenSSLInit.cxx + +HEADERS += \ + FiniteFifo.hxx \ + FileSystem.hxx \ + Fifo.hxx \ + DnsUtil.hxx \ + DataStream.hxx \ + DataException.hxx \ + Data.hxx \ + CountStream.hxx \ + Condition.hxx \ + compat.hxx \ + Coders.hxx \ + CircularBuffer.hxx \ + BaseException.hxx \ + AsyncProcessHandler.hxx \ + AsyncID.hxx \ + AbstractFifo.hxx \ + Logger.hxx \ + Log.hxx \ + Lockable.hxx \ + Lock.hxx \ + IntrusiveListElement.hxx \ + Inserter.hxx \ + HeapInstanceCounter.hxx \ + HashMap.hxx \ + GenericTimerQueue.hxx \ + GenericIPAddress.hxx \ + resipfaststreams.hxx \ + RecursiveMutex.hxx \ + Random.hxx \ + RADIUSDigestAuthenticator.hxx \ + Poll.hxx \ + ParseException.hxx \ + ParseBuffer.hxx \ + Mutex.hxx \ + MD5Stream.hxx \ + vthread.hxx \ + vmd5.hxx \ + TransportType.hxx \ + Timer.hxx \ + TimeLimitFifo.hxx \ + Time.hxx \ + ThreadIf.hxx \ + SysLogStream.hxx \ + SysLogBuf.hxx \ + Subsystem.hxx \ + Socket.hxx \ + SharedPtr.hxx \ + SharedCount.hxx \ + RWMutex.hxx \ + dns/RRVip.hxx \ + dns/RROverlay.hxx \ + dns/RRList.hxx \ + dns/RRFactory.hxx \ + dns/RRCache.hxx \ + dns/QueryTypes.hxx \ + dns/LocalDns.hxx \ + dns/ExternalDnsFactory.hxx \ + dns/ExternalDns.hxx \ + dns/DnsStub.hxx \ + dns/DnsSrvRecord.hxx \ + dns/DnsResourceRecord.hxx \ + dns/DnsNaptrRecord.hxx \ + dns/DnsHostRecord.hxx \ + dns/DnsHandler.hxx \ + dns/DnsCnameRecord.hxx \ + dns/DnsAAAARecord.hxx \ + dns/AresDns.hxx \ + dns/AresCompat.hxx \ + ssl/SHA1Stream.hxx \ + ssl/OpenSSLInit.hxx \ + stun/Udp.hxx \ + stun/Stun.hxx \ + ssl/SHA1Stream.hxx \ + ssl/OpenSSLInit.hxx +unix:!symbian { + maemo5 { + target.path = /opt/usr/lib + } else { + target.path = /usr/local/lib + } + INSTALLS += target +} + + diff --git a/src/libs/resiprocate/rutil/rutil_10_0.vcxproj b/src/libs/resiprocate/rutil/rutil_10_0.vcxproj new file mode 100644 index 00000000..5599030c --- /dev/null +++ b/src/libs/resiprocate/rutil/rutil_10_0.vcxproj @@ -0,0 +1,467 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|Win32"> + <Configuration>SSL-Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|x64"> + <Configuration>SSL-Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|Win32"> + <Configuration>SSL-Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|x64"> + <Configuration>SSL-Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>rutil</ProjectName> + <ProjectGuid>{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}</ProjectGuid> + <RootNamespace>rutil</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Debug\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Release\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">$(Configuration)\</OutDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">$(Configuration)\</IntDir> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../contrib/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../contrib/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;NO_IPHLPAPI;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)/../contrib/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)/../contrib/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)/../contrib/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|x64'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ProjectDir)/../contrib/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../contrib/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)/../contrib/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="AbstractFifo.cxx" /> + <ClCompile Include="dns\AresDns.cxx" /> + <ClCompile Include="BaseException.cxx" /> + <ClCompile Include="Coders.cxx" /> + <ClCompile Include="Condition.cxx" /> + <ClCompile Include="ConfigParse.cxx" /> + <ClCompile Include="CountStream.cxx" /> + <ClCompile Include="Data.cxx" /> + <ClCompile Include="DataStream.cxx" /> + <ClCompile Include="dns\DnsAAAARecord.cxx" /> + <ClCompile Include="dns\DnsCnameRecord.cxx" /> + <ClCompile Include="dns\DnsHostRecord.cxx" /> + <ClCompile Include="dns\DnsNaptrRecord.cxx" /> + <ClCompile Include="dns\DnsSrvRecord.cxx" /> + <ClCompile Include="dns\DnsStub.cxx" /> + <ClCompile Include="DnsUtil.cxx" /> + <ClCompile Include="dns\DnsThread.cxx" /> + <ClCompile Include="dns\ExternalDnsFactory.cxx" /> + <ClCompile Include="FdPoll.cxx" /> + <ClCompile Include="FileSystem.cxx" /> + <ClCompile Include="GeneralCongestionManager.cxx" /> + <ClCompile Include="HeapInstanceCounter.cxx" /> + <ClCompile Include="KeyValueStore.cxx" /> + <ClCompile Include="dns\LocalDns.cxx" /> + <ClCompile Include="Lock.cxx" /> + <ClCompile Include="Log.cxx" /> + <ClCompile Include="MD5Stream.cxx" /> + <ClCompile Include="Mutex.cxx" /> + <ClCompile Include="PoolBase.cxx" /> + <ClCompile Include="SelectInterruptor.cxx" /> + <ClCompile Include="ServerProcess.cxx" /> + <ClCompile Include="ssl\OpenSSLInit.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="ParseBuffer.cxx" /> + <ClCompile Include="ParseException.cxx" /> + <ClCompile Include="Poll.cxx" /> + <ClCompile Include="dns\QueryTypes.cxx" /> + <ClCompile Include="Random.cxx" /> + <ClCompile Include="RecursiveMutex.cxx" /> + <ClCompile Include="resipfaststreams.cxx" /> + <ClCompile Include="dns\RRCache.cxx" /> + <ClCompile Include="dns\RRList.cxx" /> + <ClCompile Include="dns\RROverlay.cxx" /> + <ClCompile Include="dns\RRVip.cxx" /> + <ClCompile Include="RWMutex.cxx" /> + <ClCompile Include="ssl\SHA1Stream.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="Socket.cxx" /> + <ClCompile Include="stun\Stun.cxx" /> + <ClCompile Include="Subsystem.cxx" /> + <ClCompile Include="SysLogBuf.cxx" /> + <ClCompile Include="SysLogStream.cxx" /> + <ClCompile Include="ThreadIf.cxx" /> + <ClCompile Include="Time.cxx" /> + <ClCompile Include="Timer.cxx" /> + <ClCompile Include="TransportType.cxx" /> + <ClCompile Include="stun\Udp.cxx" /> + <ClCompile Include="vmd5.cxx" /> + <ClCompile Include="WinCompat.cxx" /> + <ClCompile Include="XMLCursor.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="AbstractFifo.hxx" /> + <ClInclude Include="CongestionManager.hxx" /> + <ClInclude Include="ConsumerFifoBuffer.hxx" /> + <ClInclude Include="DinkyPool.hxx" /> + <ClInclude Include="dns\AresCompat.hxx" /> + <ClInclude Include="dns\AresDns.hxx" /> + <ClInclude Include="AsyncID.hxx" /> + <ClInclude Include="AsyncProcessHandler.hxx" /> + <ClInclude Include="BaseException.hxx" /> + <ClInclude Include="CircularBuffer.hxx" /> + <ClInclude Include="Coders.hxx" /> + <ClInclude Include="compat.hxx" /> + <ClInclude Include="Condition.hxx" /> + <ClInclude Include="ConfigParse.hxx" /> + <ClInclude Include="CountStream.hxx" /> + <ClInclude Include="Data.hxx" /> + <ClInclude Include="DataStream.hxx" /> + <ClInclude Include="dns\DnsAAAARecord.hxx" /> + <ClInclude Include="dns\DnsCnameRecord.hxx" /> + <ClInclude Include="dns\DnsHandler.hxx" /> + <ClInclude Include="dns\DnsHostRecord.hxx" /> + <ClInclude Include="dns\DnsNaptrRecord.hxx" /> + <ClInclude Include="dns\DnsResourceRecord.hxx" /> + <ClInclude Include="dns\DnsSrvRecord.hxx" /> + <ClInclude Include="dns\DnsStub.hxx" /> + <ClInclude Include="DnsUtil.hxx" /> + <ClInclude Include="dns\DnsThread.hxx" /> + <ClInclude Include="dns\ExternalDns.hxx" /> + <ClInclude Include="dns\ExternalDnsFactory.hxx" /> + <ClInclude Include="FdPoll.hxx" /> + <ClInclude Include="FdSetIOObserver.hxx" /> + <ClInclude Include="Fifo.hxx" /> + <ClInclude Include="FileSystem.hxx" /> + <ClInclude Include="FiniteFifo.hxx" /> + <ClInclude Include="GeneralCongestionManager.hxx" /> + <ClInclude Include="GenericIPAddress.hxx" /> + <ClInclude Include="HashMap.hxx" /> + <ClInclude Include="HeapInstanceCounter.hxx" /> + <ClInclude Include="KeyValueStore.hxx" /> + <ClInclude Include="Inserter.hxx" /> + <ClInclude Include="IntrusiveListElement.hxx" /> + <ClInclude Include="dns\LocalDns.hxx" /> + <ClInclude Include="Lock.hxx" /> + <ClInclude Include="Lockable.hxx" /> + <ClInclude Include="Log.hxx" /> + <ClInclude Include="Logger.hxx" /> + <ClInclude Include="MD5Stream.hxx" /> + <ClInclude Include="Mutex.hxx" /> + <ClInclude Include="PoolBase.hxx" /> + <ClInclude Include="ProducerFifoBuffer.hxx" /> + <ClInclude Include="SelectInterruptor.hxx" /> + <ClInclude Include="ServerProcess.hxx" /> + <ClInclude Include="ssl\OpenSSLInit.hxx" /> + <ClInclude Include="ParseBuffer.hxx" /> + <ClInclude Include="ParseException.hxx" /> + <ClInclude Include="Poll.hxx" /> + <ClInclude Include="dns\QueryTypes.hxx" /> + <ClInclude Include="Random.hxx" /> + <ClInclude Include="RecursiveMutex.hxx" /> + <ClInclude Include="resipfaststreams.hxx" /> + <ClInclude Include="dns\RRCache.hxx" /> + <ClInclude Include="dns\RRFactory.hxx" /> + <ClInclude Include="dns\RRList.hxx" /> + <ClInclude Include="dns\RROverlay.hxx" /> + <ClInclude Include="dns\RRVip.hxx" /> + <ClInclude Include="RWMutex.hxx" /> + <ClInclude Include="ssl\SHA1Stream.hxx" /> + <ClInclude Include="SharedCount.hxx" /> + <ClInclude Include="SharedPtr.hxx" /> + <ClInclude Include="Socket.hxx" /> + <ClInclude Include="StlPoolAllocator.hxx" /> + <ClInclude Include="stun\Stun.hxx" /> + <ClInclude Include="Subsystem.hxx" /> + <ClInclude Include="SysLogBuf.hxx" /> + <ClInclude Include="SysLogStream.hxx" /> + <ClInclude Include="ThreadIf.hxx" /> + <ClInclude Include="Time.hxx" /> + <ClInclude Include="TimeLimitFifo.hxx" /> + <ClInclude Include="Timer.hxx" /> + <ClInclude Include="TransportType.hxx" /> + <ClInclude Include="stun\Udp.hxx" /> + <ClInclude Include="vmd5.hxx" /> + <ClInclude Include="vthread.hxx" /> + <ClInclude Include="WinCompat.hxx" /> + <ClInclude Include="WinLeakCheck.hxx" /> + <ClInclude Include="XMLCursor.hxx" /> + </ItemGroup> + <ItemGroup> + <None Include="ReadMe.txt" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="dns\ares\ares_10_0.vcxproj"> + <Project>{ce7cf5e0-cad1-49d6-95d1-143ded7b226e}</Project> + <Private>true</Private> + <ReferenceOutputAssembly>true</ReferenceOutputAssembly> + <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies> + <LinkLibraryDependencies>true</LinkLibraryDependencies> + <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/rutil_10_0.vcxproj.filters b/src/libs/resiprocate/rutil/rutil_10_0.vcxproj.filters new file mode 100644 index 00000000..a0f3d90e --- /dev/null +++ b/src/libs/resiprocate/rutil/rutil_10_0.vcxproj.filters @@ -0,0 +1,456 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="AbstractFifo.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BaseException.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Coders.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Condition.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ConfigParse.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="CountStream.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Data.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DataStream.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DnsUtil.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\AresDns.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsAAAARecord.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsCnameRecord.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsHostRecord.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsNaptrRecord.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsSrvRecord.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsStub.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\ExternalDnsFactory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\LocalDns.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\QueryTypes.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\RRCache.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\RRList.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\RROverlay.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\RRVip.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="FileSystem.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HeapInstanceCounter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="KeyValueStore.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Lock.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Log.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MD5Stream.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Mutex.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParseBuffer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParseException.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Poll.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Random.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RecursiveMutex.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="resipfaststreams.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RWMutex.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Socket.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\OpenSSLInit.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\SHA1Stream.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="stun\Stun.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="stun\Udp.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Subsystem.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SysLogBuf.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SysLogStream.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ThreadIf.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Time.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Timer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransportType.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="vmd5.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="WinCompat.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="XMLCursor.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="FdPoll.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="GeneralCongestionManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="PoolBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SelectInterruptor.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerProcess.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="AbstractFifo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AsyncID.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AsyncProcessHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BaseException.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CircularBuffer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Coders.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="compat.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Condition.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConfigParse.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CountStream.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Data.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DataStream.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DnsUtil.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\AresCompat.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\AresDns.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsAAAARecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsCnameRecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsHostRecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsNaptrRecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsResourceRecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsSrvRecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsStub.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\ExternalDns.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\ExternalDnsFactory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\LocalDns.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\QueryTypes.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\RRCache.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\RRFactory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\RRList.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\RROverlay.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\RRVip.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Fifo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="FileSystem.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="FiniteFifo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="GenericIPAddress.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HashMap.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HeapInstanceCounter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="KeyValueStore.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Inserter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="IntrusiveListElement.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Lock.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Lockable.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Log.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Logger.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MD5Stream.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Mutex.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParseBuffer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParseException.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Poll.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Random.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RecursiveMutex.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="resipfaststreams.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RWMutex.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SharedCount.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SharedPtr.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Socket.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\OpenSSLInit.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\SHA1Stream.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="stun\Stun.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="stun\Udp.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Subsystem.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SysLogBuf.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SysLogStream.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ThreadIf.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Time.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TimeLimitFifo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Timer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransportType.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="vmd5.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="vthread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="WinCompat.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="WinLeakCheck.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="XMLCursor.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="FdPoll.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CongestionManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConsumerFifoBuffer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DinkyPool.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="FdSetIOObserver.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="GeneralCongestionManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PoolBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ProducerFifoBuffer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SelectInterruptor.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StlPoolAllocator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerProcess.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="ReadMe.txt" /> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/rutil_7_1.vcproj b/src/libs/resiprocate/rutil/rutil_7_1.vcproj new file mode 100644 index 00000000..3d8808f9 --- /dev/null +++ b/src/libs/resiprocate/rutil/rutil_7_1.vcproj @@ -0,0 +1,642 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="rutil" + ProjectGUID="{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + AdditionalDependencies="winmm.lib" + OutputFile="$(OutDir)/rutil.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6" + RuntimeLibrary="2" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + AdditionalDependencies="winmm.lib" + OutputFile="$(OutDir)/rutil.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL" + RuntimeLibrary="2" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + AdditionalDependencies="winmm.lib" + OutputFile="$(OutDir)/rutil.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + AdditionalDependencies="winmm.lib" + OutputFile="$(OutDir)/rutil.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Debug71|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="TRUE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + AdditionalDependencies="winmm.lib" + OutputFile="$(OutDir)/rutil.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath=".\AbstractFifo.cxx"> + </File> + <File + RelativePath=".\dns\AresDns.cxx"> + </File> + <File + RelativePath=".\BaseException.cxx"> + </File> + <File + RelativePath=".\Coders.cxx"> + </File> + <File + RelativePath=".\Condition.cxx"> + </File> + <File + RelativePath=".\CountStream.cxx"> + </File> + <File + RelativePath=".\Data.cxx"> + </File> + <File + RelativePath=".\DataStream.cxx"> + </File> + <File + RelativePath=".\dns\DnsAAAARecord.cxx"> + </File> + <File + RelativePath=".\dns\DnsCnameRecord.cxx"> + </File> + <File + RelativePath=".\dns\DnsHostRecord.cxx"> + </File> + <File + RelativePath=".\dns\DnsNaptrRecord.cxx"> + </File> + <File + RelativePath=".\dns\DnsResourceRecord.cxx"> + </File> + <File + RelativePath=".\dns\DnsSrvRecord.cxx"> + </File> + <File + RelativePath=".\dns\DnsStub.cxx"> + </File> + <File + RelativePath=".\DnsUtil.cxx"> + </File> + <File + RelativePath=".\dns\ExternalDnsFactory.cxx"> + </File> + <File + RelativePath=".\FdPoll.cxx"> + </File> + <File + RelativePath=".\FileSystem.cxx"> + </File> + <File + RelativePath=".\HeapInstanceCounter.cxx"> + </File> + <File + RelativePath=".\dns\LocalDns.cxx"> + </File> + <File + RelativePath=".\Lock.cxx"> + </File> + <File + RelativePath=".\Log.cxx"> + </File> + <File + RelativePath=".\MD5Stream.cxx"> + </File> + <File + RelativePath=".\Mutex.cxx"> + </File> + <File + RelativePath=".\ssl\OpenSSLInit.cxx"> + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + </File> + <File + RelativePath=".\ParseBuffer.cxx"> + </File> + <File + RelativePath=".\ParseException.cxx"> + </File> + <File + RelativePath=".\Poll.cxx"> + </File> + <File + RelativePath=".\dns\QueryTypes.cxx"> + </File> + <File + RelativePath=".\Random.cxx"> + </File> + <File + RelativePath=".\RecursiveMutex.cxx"> + </File> + <File + RelativePath=".\resipfaststreams.cxx"> + </File> + <File + RelativePath=".\dns\RRCache.cxx"> + </File> + <File + RelativePath=".\dns\RRList.cxx"> + </File> + <File + RelativePath=".\dns\RROverlay.cxx"> + </File> + <File + RelativePath=".\dns\RRVip.cxx"> + </File> + <File + RelativePath=".\RWMutex.cxx"> + </File> + <File + RelativePath=".\ssl\SHA1Stream.cxx"> + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="TRUE"> + <Tool + Name="VCCLCompilerTool"/> + </FileConfiguration> + </File> + <File + RelativePath=".\Socket.cxx"> + </File> + <File + RelativePath=".\stun\Stun.cxx"> + </File> + <File + RelativePath=".\Subsystem.cxx"> + </File> + <File + RelativePath=".\SysLogBuf.cxx"> + </File> + <File + RelativePath=".\SysLogStream.cxx"> + </File> + <File + RelativePath=".\ThreadIf.cxx"> + </File> + <File + RelativePath=".\Time.cxx"> + </File> + <File + RelativePath=".\Timer.cxx"> + </File> + <File + RelativePath=".\TransportType.cxx"> + </File> + <File + RelativePath=".\stun\Udp.cxx"> + </File> + <File + RelativePath=".\vmd5.cxx"> + </File> + <File + RelativePath=".\WinCompat.cxx"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath=".\AbstractFifo.hxx"> + </File> + <File + RelativePath=".\dns\AresDns.hxx"> + </File> + <File + RelativePath=".\AsyncID.hxx"> + </File> + <File + RelativePath=".\AsyncProcessHandler.hxx"> + </File> + <File + RelativePath=".\BaseException.hxx"> + </File> + <File + RelativePath=".\CircularBuffer.hxx"> + </File> + <File + RelativePath=".\Coders.hxx"> + </File> + <File + RelativePath=".\compat.hxx"> + </File> + <File + RelativePath=".\Condition.hxx"> + </File> + <File + RelativePath=".\CountStream.hxx"> + </File> + <File + RelativePath=".\Data.hxx"> + </File> + <File + RelativePath=".\DataStream.hxx"> + </File> + <File + RelativePath=".\dns\DnsAAAARecord.hxx"> + </File> + <File + RelativePath=".\dns\DnsCnameRecord.hxx"> + </File> + <File + RelativePath=".\dns\DnsHandler.hxx"> + </File> + <File + RelativePath=".\dns\DnsHostRecord.hxx"> + </File> + <File + RelativePath=".\dns\DnsNaptrRecord.hxx"> + </File> + <File + RelativePath=".\dns\DnsResourceRecord.hxx"> + </File> + <File + RelativePath=".\dns\DnsSrvRecord.hxx"> + </File> + <File + RelativePath=".\dns\DnsStub.hxx"> + </File> + <File + RelativePath=".\DnsUtil.hxx"> + </File> + <File + RelativePath=".\dns\ExternalDns.hxx"> + </File> + <File + RelativePath=".\dns\ExternalDnsFactory.hxx"> + </File> + <File + RelativePath=".\FdPoll.hxx"> + </File> + <File + RelativePath=".\Fifo.hxx"> + </File> + <File + RelativePath=".\FileSystem.hxx"> + </File> + <File + RelativePath=".\FiniteFifo.hxx"> + </File> + <File + RelativePath=".\GenericIPAddress.hxx"> + </File> + <File + RelativePath=".\HashMap.hxx"> + </File> + <File + RelativePath=".\HeapInstanceCounter.hxx"> + </File> + <File + RelativePath=".\Inserter.hxx"> + </File> + <File + RelativePath=".\IntrusiveListElement.hxx"> + </File> + <File + RelativePath=".\dns\LocalDns.hxx"> + </File> + <File + RelativePath=".\Lock.hxx"> + </File> + <File + RelativePath=".\Lockable.hxx"> + </File> + <File + RelativePath=".\Log.hxx"> + </File> + <File + RelativePath=".\Logger.hxx"> + </File> + <File + RelativePath=".\MD5Stream.hxx"> + </File> + <File + RelativePath=".\Mutex.hxx"> + </File> + <File + RelativePath=".\ssl\OpenSSLInit.hxx"> + </File> + <File + RelativePath=".\ParseBuffer.hxx"> + </File> + <File + RelativePath=".\ParseException.hxx"> + </File> + <File + RelativePath=".\Poll.hxx"> + </File> + <File + RelativePath=".\dns\QueryTypes.hxx"> + </File> + <File + RelativePath=".\Random.hxx"> + </File> + <File + RelativePath=".\RecursiveMutex.hxx"> + </File> + <File + RelativePath=".\resipfaststreams.hxx"> + </File> + <File + RelativePath=".\dns\RRCache.hxx"> + </File> + <File + RelativePath=".\dns\RRFactory.hxx"> + </File> + <File + RelativePath=".\dns\RRList.hxx"> + </File> + <File + RelativePath=".\dns\RROverlay.hxx"> + </File> + <File + RelativePath=".\dns\RRVip.hxx"> + </File> + <File + RelativePath=".\RWMutex.hxx"> + </File> + <File + RelativePath=".\ssl\SHA1Stream.hxx"> + </File> + <File + RelativePath=".\SharedCount.hxx"> + </File> + <File + RelativePath=".\SharedPtr.hxx"> + </File> + <File + RelativePath=".\Socket.hxx"> + </File> + <File + RelativePath=".\stun\Stun.hxx"> + </File> + <File + RelativePath=".\Subsystem.hxx"> + </File> + <File + RelativePath=".\SysLogBuf.hxx"> + </File> + <File + RelativePath=".\SysLogStream.hxx"> + </File> + <File + RelativePath=".\ThreadIf.hxx"> + </File> + <File + RelativePath=".\Time.hxx"> + </File> + <File + RelativePath=".\TimeLimitFifo.hxx"> + </File> + <File + RelativePath=".\Timer.hxx"> + </File> + <File + RelativePath=".\TransportType.hxx"> + </File> + <File + RelativePath=".\stun\Udp.hxx"> + </File> + <File + RelativePath=".\vmd5.hxx"> + </File> + <File + RelativePath=".\vthread.hxx"> + </File> + <File + RelativePath=".\WinCompat.hxx"> + </File> + <File + RelativePath=".\WinLeakCheck.hxx"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + <File + RelativePath=".\ReadMe.txt"> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/rutil/rutil_8_0.vcproj b/src/libs/resiprocate/rutil/rutil_8_0.vcproj new file mode 100644 index 00000000..51cbca82 --- /dev/null +++ b/src/libs/resiprocate/rutil/rutil_8_0.vcproj @@ -0,0 +1,909 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="rutil" + ProjectGUID="{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" + RootNamespace="rutil" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)dns/ares&quot;;&quot;$(ProjectDir)../&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/rutil.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)dns/ares&quot;;&quot;$(ProjectDir)../&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/rutil.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;$(ProjectDir)dns/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/rutil.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)dns/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../contrib/openssl/inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/rutil.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\AbstractFifo.cxx" + > + </File> + <File + RelativePath=".\dns\AresDns.cxx" + > + </File> + <File + RelativePath=".\BaseException.cxx" + > + </File> + <File + RelativePath=".\Coders.cxx" + > + </File> + <File + RelativePath=".\Condition.cxx" + > + </File> + <File + RelativePath=".\ConfigParse.cxx" + > + </File> + <File + RelativePath=".\CountStream.cxx" + > + </File> + <File + RelativePath=".\Data.cxx" + > + </File> + <File + RelativePath=".\DataStream.cxx" + > + </File> + <File + RelativePath=".\dns\DnsAAAARecord.cxx" + > + </File> + <File + RelativePath=".\dns\DnsCnameRecord.cxx" + > + </File> + <File + RelativePath=".\dns\DnsHostRecord.cxx" + > + </File> + <File + RelativePath=".\dns\DnsNaptrRecord.cxx" + > + </File> + <File + RelativePath=".\dns\DnsSrvRecord.cxx" + > + </File> + <File + RelativePath=".\dns\DnsStub.cxx" + > + </File> + <File + RelativePath=".\dns\DnsThread.cxx" + > + </File> + <File + RelativePath=".\DnsUtil.cxx" + > + </File> + <File + RelativePath=".\dns\ExternalDnsFactory.cxx" + > + </File> + <File + RelativePath=".\FdPoll.cxx" + > + </File> + <File + RelativePath=".\FileSystem.cxx" + > + </File> + <File + RelativePath=".\GeneralCongestionManager.cxx" + > + </File> + <File + RelativePath=".\HeapInstanceCounter.cxx" + > + </File> + <File + RelativePath=".\KeyValueStore.cxx" + > + </File> + <File + RelativePath=".\dns\LocalDns.cxx" + > + </File> + <File + RelativePath=".\Lock.cxx" + > + </File> + <File + RelativePath=".\Log.cxx" + > + </File> + <File + RelativePath=".\MD5Stream.cxx" + > + </File> + <File + RelativePath=".\Mutex.cxx" + > + </File> + <File + RelativePath=".\ssl\OpenSSLInit.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\ParseBuffer.cxx" + > + </File> + <File + RelativePath=".\ParseException.cxx" + > + </File> + <File + RelativePath=".\Poll.cxx" + > + </File> + <File + RelativePath=".\PoolBase.cxx" + > + </File> + <File + RelativePath=".\dns\QueryTypes.cxx" + > + </File> + <File + RelativePath=".\Random.cxx" + > + </File> + <File + RelativePath=".\RecursiveMutex.cxx" + > + </File> + <File + RelativePath=".\resipfaststreams.cxx" + > + </File> + <File + RelativePath=".\dns\RRCache.cxx" + > + </File> + <File + RelativePath=".\dns\RRList.cxx" + > + </File> + <File + RelativePath=".\dns\RROverlay.cxx" + > + </File> + <File + RelativePath=".\dns\RRVip.cxx" + > + </File> + <File + RelativePath=".\RWMutex.cxx" + > + </File> + <File + RelativePath=".\SelectInterruptor.cxx" + > + </File> + <File + RelativePath=".\ServerProcess.cxx" + > + </File> + <File + RelativePath=".\ssl\SHA1Stream.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\Socket.cxx" + > + </File> + <File + RelativePath=".\stun\Stun.cxx" + > + </File> + <File + RelativePath=".\Subsystem.cxx" + > + </File> + <File + RelativePath=".\SysLogBuf.cxx" + > + </File> + <File + RelativePath=".\SysLogStream.cxx" + > + </File> + <File + RelativePath=".\ThreadIf.cxx" + > + </File> + <File + RelativePath=".\Time.cxx" + > + </File> + <File + RelativePath=".\Timer.cxx" + > + </File> + <File + RelativePath=".\TransportType.cxx" + > + </File> + <File + RelativePath=".\stun\Udp.cxx" + > + </File> + <File + RelativePath=".\vmd5.cxx" + > + </File> + <File + RelativePath=".\WinCompat.cxx" + > + </File> + <File + RelativePath=".\XMLCursor.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\AbstractFifo.hxx" + > + </File> + <File + RelativePath=".\dns\AresDns.hxx" + > + </File> + <File + RelativePath=".\AsyncID.hxx" + > + </File> + <File + RelativePath=".\AsyncProcessHandler.hxx" + > + </File> + <File + RelativePath=".\BaseException.hxx" + > + </File> + <File + RelativePath=".\CircularBuffer.hxx" + > + </File> + <File + RelativePath=".\Coders.hxx" + > + </File> + <File + RelativePath=".\compat.hxx" + > + </File> + <File + RelativePath=".\Condition.hxx" + > + </File> + <File + RelativePath=".\ConfigParse.hxx" + > + </File> + <File + RelativePath=".\CongestionManager.hxx" + > + </File> + <File + RelativePath=".\ConsumerFifoBuffer.hxx" + > + </File> + <File + RelativePath=".\CountStream.hxx" + > + </File> + <File + RelativePath=".\Data.hxx" + > + </File> + <File + RelativePath=".\DataStream.hxx" + > + </File> + <File + RelativePath=".\DinkyPool.hxx" + > + </File> + <File + RelativePath=".\dns\DnsAAAARecord.hxx" + > + </File> + <File + RelativePath=".\dns\DnsCnameRecord.hxx" + > + </File> + <File + RelativePath=".\dns\DnsHandler.hxx" + > + </File> + <File + RelativePath=".\dns\DnsHostRecord.hxx" + > + </File> + <File + RelativePath=".\dns\DnsNaptrRecord.hxx" + > + </File> + <File + RelativePath=".\dns\DnsResourceRecord.hxx" + > + </File> + <File + RelativePath=".\dns\DnsSrvRecord.hxx" + > + </File> + <File + RelativePath=".\dns\DnsStub.hxx" + > + </File> + <File + RelativePath=".\dns\DnsThread.hxx" + > + </File> + <File + RelativePath=".\DnsUtil.hxx" + > + </File> + <File + RelativePath=".\dns\ExternalDns.hxx" + > + </File> + <File + RelativePath=".\dns\ExternalDnsFactory.hxx" + > + </File> + <File + RelativePath=".\FdPoll.hxx" + > + </File> + <File + RelativePath=".\FdSetIOObserver.hxx" + > + </File> + <File + RelativePath=".\Fifo.hxx" + > + </File> + <File + RelativePath=".\FileSystem.hxx" + > + </File> + <File + RelativePath=".\FiniteFifo.hxx" + > + </File> + <File + RelativePath=".\GeneralCongestionManager.hxx" + > + </File> + <File + RelativePath=".\GenericIPAddress.hxx" + > + </File> + <File + RelativePath=".\HashMap.hxx" + > + </File> + <File + RelativePath=".\HeapInstanceCounter.hxx" + > + </File> + <File + RelativePath=".\Inserter.hxx" + > + </File> + <File + RelativePath=".\IntrusiveListElement.hxx" + > + </File> + <File + RelativePath=".\KeyValueStore.hxx" + > + </File> + <File + RelativePath=".\dns\LocalDns.hxx" + > + </File> + <File + RelativePath=".\Lock.hxx" + > + </File> + <File + RelativePath=".\Lockable.hxx" + > + </File> + <File + RelativePath=".\Log.hxx" + > + </File> + <File + RelativePath=".\Logger.hxx" + > + </File> + <File + RelativePath=".\MD5Stream.hxx" + > + </File> + <File + RelativePath=".\Mutex.hxx" + > + </File> + <File + RelativePath=".\ssl\OpenSSLInit.hxx" + > + </File> + <File + RelativePath=".\ParseBuffer.hxx" + > + </File> + <File + RelativePath=".\ParseException.hxx" + > + </File> + <File + RelativePath=".\Poll.hxx" + > + </File> + <File + RelativePath=".\PoolBase.hxx" + > + </File> + <File + RelativePath=".\ProducerFifoBuffer.hxx" + > + </File> + <File + RelativePath=".\dns\QueryTypes.hxx" + > + </File> + <File + RelativePath=".\Random.hxx" + > + </File> + <File + RelativePath=".\RecursiveMutex.hxx" + > + </File> + <File + RelativePath=".\resipfaststreams.hxx" + > + </File> + <File + RelativePath=".\dns\RRCache.hxx" + > + </File> + <File + RelativePath=".\dns\RRFactory.hxx" + > + </File> + <File + RelativePath=".\dns\RRList.hxx" + > + </File> + <File + RelativePath=".\dns\RROverlay.hxx" + > + </File> + <File + RelativePath=".\dns\RRVip.hxx" + > + </File> + <File + RelativePath=".\RWMutex.hxx" + > + </File> + <File + RelativePath=".\SelectInterruptor.hxx" + > + </File> + <File + RelativePath=".\ServerProcess.hxx" + > + </File> + <File + RelativePath=".\ssl\SHA1Stream.hxx" + > + </File> + <File + RelativePath=".\SharedCount.hxx" + > + </File> + <File + RelativePath=".\SharedPtr.hxx" + > + </File> + <File + RelativePath=".\Socket.hxx" + > + </File> + <File + RelativePath=".\StlPoolAllocator.hxx" + > + </File> + <File + RelativePath=".\stun\Stun.hxx" + > + </File> + <File + RelativePath=".\Subsystem.hxx" + > + </File> + <File + RelativePath=".\SysLogBuf.hxx" + > + </File> + <File + RelativePath=".\SysLogStream.hxx" + > + </File> + <File + RelativePath=".\ThreadIf.hxx" + > + </File> + <File + RelativePath=".\Time.hxx" + > + </File> + <File + RelativePath=".\TimeLimitFifo.hxx" + > + </File> + <File + RelativePath=".\Timer.hxx" + > + </File> + <File + RelativePath=".\TransportType.hxx" + > + </File> + <File + RelativePath=".\stun\Udp.hxx" + > + </File> + <File + RelativePath=".\vmd5.hxx" + > + </File> + <File + RelativePath=".\vthread.hxx" + > + </File> + <File + RelativePath=".\WinCompat.hxx" + > + </File> + <File + RelativePath=".\WinLeakCheck.hxx" + > + </File> + <File + RelativePath=".\XMLCursor.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <File + RelativePath=".\ReadMe.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/rutil/rutil_9_0.vcproj b/src/libs/resiprocate/rutil/rutil_9_0.vcproj new file mode 100644 index 00000000..dd66b5dd --- /dev/null +++ b/src/libs/resiprocate/rutil/rutil_9_0.vcproj @@ -0,0 +1,918 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="rutil" + ProjectGUID="{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}" + RootNamespace="rutil" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)dns/ares&quot;;&quot;$(ProjectDir)../&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/rutil.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="&quot;$(ProjectDir)dns/ares&quot;;&quot;$(ProjectDir)../&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/rutil.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../openssl/include&quot;;$(NOINHERIT)" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL" + RuntimeLibrary="2" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/rutil.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="SSL-Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="&quot;$(ProjectDir)../contrib/ares&quot;;&quot;$(ProjectDir)../&quot;;&quot;$(ProjectDir)../contrib/openssl/include&quot;;&quot;$(ProjectDir)../../openssl/include&quot;;$(NOINHERIT)" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + RuntimeTypeInfo="true" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/rutil.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\AbstractFifo.cxx" + > + </File> + <File + RelativePath=".\dns\AresDns.cxx" + > + </File> + <File + RelativePath=".\BaseException.cxx" + > + </File> + <File + RelativePath=".\Coders.cxx" + > + </File> + <File + RelativePath=".\Condition.cxx" + > + </File> + <File + RelativePath=".\ConfigParse.cxx" + > + </File> + <File + RelativePath=".\CountStream.cxx" + > + </File> + <File + RelativePath=".\Data.cxx" + > + </File> + <File + RelativePath=".\DataStream.cxx" + > + </File> + <File + RelativePath=".\dns\DnsAAAARecord.cxx" + > + </File> + <File + RelativePath=".\dns\DnsCnameRecord.cxx" + > + </File> + <File + RelativePath=".\dns\DnsHostRecord.cxx" + > + </File> + <File + RelativePath=".\dns\DnsNaptrRecord.cxx" + > + </File> + <File + RelativePath=".\dns\DnsSrvRecord.cxx" + > + </File> + <File + RelativePath=".\dns\DnsStub.cxx" + > + </File> + <File + RelativePath=".\dns\DnsThread.cxx" + > + </File> + <File + RelativePath=".\DnsUtil.cxx" + > + </File> + <File + RelativePath=".\dns\ExternalDnsFactory.cxx" + > + </File> + <File + RelativePath=".\FdPoll.cxx" + > + </File> + <File + RelativePath=".\FileSystem.cxx" + > + </File> + <File + RelativePath=".\GeneralCongestionManager.cxx" + > + </File> + <File + RelativePath=".\HeapInstanceCounter.cxx" + > + </File> + <File + RelativePath=".\KeyValueStore.cxx" + > + </File> + <File + RelativePath=".\dns\LocalDns.cxx" + > + </File> + <File + RelativePath=".\Lock.cxx" + > + </File> + <File + RelativePath=".\Log.cxx" + > + </File> + <File + RelativePath=".\MD5Stream.cxx" + > + </File> + <File + RelativePath=".\Mutex.cxx" + > + </File> + <File + RelativePath=".\ssl\OpenSSLInit.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\ParseBuffer.cxx" + > + </File> + <File + RelativePath=".\ParseException.cxx" + > + </File> + <File + RelativePath=".\Poll.cxx" + > + </File> + <File + RelativePath=".\PoolBase.cxx" + > + </File> + <File + RelativePath=".\dns\QueryTypes.cxx" + > + </File> + <File + RelativePath=".\Random.cxx" + > + </File> + <File + RelativePath=".\RecursiveMutex.cxx" + > + </File> + <File + RelativePath=".\resipfaststreams.cxx" + > + </File> + <File + RelativePath=".\dns\RRCache.cxx" + > + </File> + <File + RelativePath=".\dns\RRList.cxx" + > + </File> + <File + RelativePath=".\dns\RROverlay.cxx" + > + </File> + <File + RelativePath=".\dns\RRVip.cxx" + > + </File> + <File + RelativePath=".\RWMutex.cxx" + > + </File> + <File + RelativePath=".\SelectInterruptor.cxx" + > + </File> + <File + RelativePath=".\ServerProcess.cxx" + > + </File> + <File + RelativePath=".\ssl\SHA1Stream.cxx" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\Socket.cxx" + > + </File> + <File + RelativePath=".\stun\Stun.cxx" + > + </File> + <File + RelativePath=".\Subsystem.cxx" + > + </File> + <File + RelativePath=".\SysLogBuf.cxx" + > + </File> + <File + RelativePath=".\SysLogStream.cxx" + > + </File> + <File + RelativePath=".\ThreadIf.cxx" + > + </File> + <File + RelativePath=".\Time.cxx" + > + </File> + <File + RelativePath=".\Timer.cxx" + > + </File> + <File + RelativePath=".\TransportType.cxx" + > + </File> + <File + RelativePath=".\stun\Udp.cxx" + > + </File> + <File + RelativePath=".\vmd5.cxx" + > + </File> + <File + RelativePath=".\WinCompat.cxx" + > + </File> + <File + RelativePath=".\XMLCursor.cxx" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\AbstractFifo.hxx" + > + </File> + <File + RelativePath=".\dns\AresCompat.hxx" + > + </File> + <File + RelativePath=".\dns\AresDns.hxx" + > + </File> + <File + RelativePath=".\AsyncID.hxx" + > + </File> + <File + RelativePath=".\AsyncProcessHandler.hxx" + > + </File> + <File + RelativePath=".\BaseException.hxx" + > + </File> + <File + RelativePath=".\CircularBuffer.hxx" + > + </File> + <File + RelativePath=".\Coders.hxx" + > + </File> + <File + RelativePath=".\compat.hxx" + > + </File> + <File + RelativePath=".\Condition.hxx" + > + </File> + <File + RelativePath=".\ConfigParse.hxx" + > + </File> + <File + RelativePath=".\CongestionManager.hxx" + > + </File> + <File + RelativePath=".\ConsumerFifoBuffer.hxx" + > + </File> + <File + RelativePath=".\CountStream.hxx" + > + </File> + <File + RelativePath=".\Data.hxx" + > + </File> + <File + RelativePath=".\DataStream.hxx" + > + </File> + <File + RelativePath=".\DinkyPool.hxx" + > + </File> + <File + RelativePath=".\dns\DnsAAAARecord.hxx" + > + </File> + <File + RelativePath=".\dns\DnsCnameRecord.hxx" + > + </File> + <File + RelativePath=".\dns\DnsHandler.hxx" + > + </File> + <File + RelativePath=".\dns\DnsHostRecord.hxx" + > + </File> + <File + RelativePath=".\dns\DnsNaptrRecord.hxx" + > + </File> + <File + RelativePath=".\dns\DnsResourceRecord.hxx" + > + </File> + <File + RelativePath=".\dns\DnsSrvRecord.hxx" + > + </File> + <File + RelativePath=".\dns\DnsStub.hxx" + > + </File> + <File + RelativePath=".\dns\DnsThread.hxx" + > + </File> + <File + RelativePath=".\DnsUtil.hxx" + > + </File> + <File + RelativePath=".\dns\ExternalDns.hxx" + > + </File> + <File + RelativePath=".\dns\ExternalDnsFactory.hxx" + > + </File> + <File + RelativePath=".\FdPoll.hxx" + > + </File> + <File + RelativePath=".\FdSetIOObserver.hxx" + > + </File> + <File + RelativePath=".\Fifo.hxx" + > + </File> + <File + RelativePath=".\FileSystem.hxx" + > + </File> + <File + RelativePath=".\FiniteFifo.hxx" + > + </File> + <File + RelativePath=".\GeneralCongestionManager.hxx" + > + </File> + <File + RelativePath=".\GenericIPAddress.hxx" + > + </File> + <File + RelativePath=".\HashMap.hxx" + > + </File> + <File + RelativePath=".\HeapInstanceCounter.hxx" + > + </File> + <File + RelativePath=".\Inserter.hxx" + > + </File> + <File + RelativePath=".\IntrusiveListElement.hxx" + > + </File> + <File + RelativePath=".\KeyValueStore.hxx" + > + </File> + <File + RelativePath=".\dns\LocalDns.hxx" + > + </File> + <File + RelativePath=".\Lock.hxx" + > + </File> + <File + RelativePath=".\Lockable.hxx" + > + </File> + <File + RelativePath=".\Log.hxx" + > + </File> + <File + RelativePath=".\Logger.hxx" + > + </File> + <File + RelativePath=".\MD5Stream.hxx" + > + </File> + <File + RelativePath=".\Mutex.hxx" + > + </File> + <File + RelativePath=".\ssl\OpenSSLInit.hxx" + > + </File> + <File + RelativePath=".\ParseBuffer.hxx" + > + </File> + <File + RelativePath=".\ParseException.hxx" + > + </File> + <File + RelativePath=".\Poll.hxx" + > + </File> + <File + RelativePath=".\PoolBase.hxx" + > + </File> + <File + RelativePath=".\ProducerFifoBuffer.hxx" + > + </File> + <File + RelativePath=".\dns\QueryTypes.hxx" + > + </File> + <File + RelativePath=".\Random.hxx" + > + </File> + <File + RelativePath=".\RecursiveMutex.hxx" + > + </File> + <File + RelativePath=".\resipfaststreams.hxx" + > + </File> + <File + RelativePath=".\dns\RRCache.hxx" + > + </File> + <File + RelativePath=".\dns\RRFactory.hxx" + > + </File> + <File + RelativePath=".\dns\RRList.hxx" + > + </File> + <File + RelativePath=".\dns\RROverlay.hxx" + > + </File> + <File + RelativePath=".\dns\RRVip.hxx" + > + </File> + <File + RelativePath=".\RWMutex.hxx" + > + </File> + <File + RelativePath=".\SelectInterruptor.hxx" + > + </File> + <File + RelativePath=".\ServerProcess.hxx" + > + </File> + <File + RelativePath=".\ssl\SHA1Stream.hxx" + > + </File> + <File + RelativePath=".\SharedCount.hxx" + > + </File> + <File + RelativePath=".\SharedPtr.hxx" + > + </File> + <File + RelativePath=".\Socket.hxx" + > + </File> + <File + RelativePath=".\StlPoolAllocator.hxx" + > + </File> + <File + RelativePath=".\stun\Stun.hxx" + > + </File> + <File + RelativePath=".\Subsystem.hxx" + > + </File> + <File + RelativePath=".\SysLogBuf.hxx" + > + </File> + <File + RelativePath=".\SysLogStream.hxx" + > + </File> + <File + RelativePath=".\ThreadIf.hxx" + > + </File> + <File + RelativePath=".\Time.hxx" + > + </File> + <File + RelativePath=".\TimeLimitFifo.hxx" + > + </File> + <File + RelativePath=".\Timer.hxx" + > + </File> + <File + RelativePath=".\TransportType.hxx" + > + </File> + <File + RelativePath=".\stun\Udp.hxx" + > + </File> + <File + RelativePath=".\vmd5.hxx" + > + </File> + <File + RelativePath=".\vthread.hxx" + > + </File> + <File + RelativePath=".\WinCompat.hxx" + > + </File> + <File + RelativePath=".\WinLeakCheck.hxx" + > + </File> + <File + RelativePath=".\XMLCursor.hxx" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <File + RelativePath=".\ReadMe.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/resiprocate/rutil/rutil_9_0.vcxproj b/src/libs/resiprocate/rutil/rutil_9_0.vcxproj new file mode 100644 index 00000000..45d5c9be --- /dev/null +++ b/src/libs/resiprocate/rutil/rutil_9_0.vcxproj @@ -0,0 +1,315 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Debug|Win32"> + <Configuration>SSL-Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="SSL-Release|Win32"> + <Configuration>SSL-Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>rutil</ProjectName> + <ProjectGuid>{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}</ProjectGuid> + <RootNamespace>rutil</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <OutDir>$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <OutDir>$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)rutil.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> + <AdditionalIncludeDirectories>$(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)rutil.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Release|Win32'"> + <ClCompile> + <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> + <AdditionalIncludeDirectories>$(ProjectDir)../contrib/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../../openssl/include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)rutil.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SSL-Debug|Win32'"> + <ClCompile> + <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>$(ProjectDir)../contrib/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../../openssl/include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)rutil.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="AbstractFifo.cxx" /> + <ClCompile Include="AtomicCounter.cxx" /> + <ClCompile Include="dns\AresDns.cxx" /> + <ClCompile Include="BaseException.cxx" /> + <ClCompile Include="Coders.cxx" /> + <ClCompile Include="Condition.cxx" /> + <ClCompile Include="ConfigParse.cxx" /> + <ClCompile Include="CountStream.cxx" /> + <ClCompile Include="Data.cxx" /> + <ClCompile Include="DataStream.cxx" /> + <ClCompile Include="dns\DnsAAAARecord.cxx" /> + <ClCompile Include="dns\DnsCnameRecord.cxx" /> + <ClCompile Include="dns\DnsHostRecord.cxx" /> + <ClCompile Include="dns\DnsNaptrRecord.cxx" /> + <ClCompile Include="dns\DnsSrvRecord.cxx" /> + <ClCompile Include="dns\DnsStub.cxx" /> + <ClCompile Include="dns\DnsThread.cxx" /> + <ClCompile Include="DnsUtil.cxx" /> + <ClCompile Include="dns\ExternalDnsFactory.cxx" /> + <ClCompile Include="FdPoll.cxx" /> + <ClCompile Include="FileSystem.cxx" /> + <ClCompile Include="GeneralCongestionManager.cxx" /> + <ClCompile Include="HeapInstanceCounter.cxx" /> + <ClCompile Include="KeyValueStore.cxx" /> + <ClCompile Include="dns\LocalDns.cxx" /> + <ClCompile Include="Lock.cxx" /> + <ClCompile Include="Log.cxx" /> + <ClCompile Include="MD5Stream.cxx" /> + <ClCompile Include="Mutex.cxx" /> + <ClCompile Include="ssl\OpenSSLInit.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="ParseBuffer.cxx" /> + <ClCompile Include="ParseException.cxx" /> + <ClCompile Include="Poll.cxx" /> + <ClCompile Include="PoolBase.cxx" /> + <ClCompile Include="dns\QueryTypes.cxx" /> + <ClCompile Include="Random.cxx" /> + <ClCompile Include="RecursiveMutex.cxx" /> + <ClCompile Include="resipfaststreams.cxx" /> + <ClCompile Include="dns\RRCache.cxx" /> + <ClCompile Include="dns\RRList.cxx" /> + <ClCompile Include="dns\RROverlay.cxx" /> + <ClCompile Include="dns\RRVip.cxx" /> + <ClCompile Include="RWMutex.cxx" /> + <ClCompile Include="SelectInterruptor.cxx" /> + <ClCompile Include="ServerProcess.cxx" /> + <ClCompile Include="ssl\SHA1Stream.cxx"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="Socket.cxx" /> + <ClCompile Include="stun\Stun.cxx" /> + <ClCompile Include="Subsystem.cxx" /> + <ClCompile Include="SysLogBuf.cxx" /> + <ClCompile Include="SysLogStream.cxx" /> + <ClCompile Include="ThreadIf.cxx" /> + <ClCompile Include="Time.cxx" /> + <ClCompile Include="Timer.cxx" /> + <ClCompile Include="TransportType.cxx" /> + <ClCompile Include="stun\Udp.cxx" /> + <ClCompile Include="vmd5.cxx" /> + <ClCompile Include="WinCompat.cxx" /> + <ClCompile Include="XMLCursor.cxx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="AbstractFifo.hxx" /> + <ClInclude Include="AtomicCounter.hxx" /> + <ClInclude Include="dns\AresCompat.hxx" /> + <ClInclude Include="dns\AresDns.hxx" /> + <ClInclude Include="AsyncID.hxx" /> + <ClInclude Include="AsyncProcessHandler.hxx" /> + <ClInclude Include="BaseException.hxx" /> + <ClInclude Include="CircularBuffer.hxx" /> + <ClInclude Include="Coders.hxx" /> + <ClInclude Include="compat.hxx" /> + <ClInclude Include="Condition.hxx" /> + <ClInclude Include="ConfigParse.hxx" /> + <ClInclude Include="CongestionManager.hxx" /> + <ClInclude Include="ConsumerFifoBuffer.hxx" /> + <ClInclude Include="CountStream.hxx" /> + <ClInclude Include="Data.hxx" /> + <ClInclude Include="DataStream.hxx" /> + <ClInclude Include="DinkyPool.hxx" /> + <ClInclude Include="dns\DnsAAAARecord.hxx" /> + <ClInclude Include="dns\DnsCnameRecord.hxx" /> + <ClInclude Include="dns\DnsHandler.hxx" /> + <ClInclude Include="dns\DnsHostRecord.hxx" /> + <ClInclude Include="dns\DnsNaptrRecord.hxx" /> + <ClInclude Include="dns\DnsResourceRecord.hxx" /> + <ClInclude Include="dns\DnsSrvRecord.hxx" /> + <ClInclude Include="dns\DnsStub.hxx" /> + <ClInclude Include="dns\DnsThread.hxx" /> + <ClInclude Include="DnsUtil.hxx" /> + <ClInclude Include="dns\ExternalDns.hxx" /> + <ClInclude Include="dns\ExternalDnsFactory.hxx" /> + <ClInclude Include="FdPoll.hxx" /> + <ClInclude Include="FdSetIOObserver.hxx" /> + <ClInclude Include="Fifo.hxx" /> + <ClInclude Include="FileSystem.hxx" /> + <ClInclude Include="FiniteFifo.hxx" /> + <ClInclude Include="GeneralCongestionManager.hxx" /> + <ClInclude Include="GenericIPAddress.hxx" /> + <ClInclude Include="HashMap.hxx" /> + <ClInclude Include="HeapInstanceCounter.hxx" /> + <ClInclude Include="Inserter.hxx" /> + <ClInclude Include="IntrusiveListElement.hxx" /> + <ClInclude Include="KeyValueStore.hxx" /> + <ClInclude Include="dns\LocalDns.hxx" /> + <ClInclude Include="Lock.hxx" /> + <ClInclude Include="Lockable.hxx" /> + <ClInclude Include="Log.hxx" /> + <ClInclude Include="Logger.hxx" /> + <ClInclude Include="MD5Stream.hxx" /> + <ClInclude Include="Mutex.hxx" /> + <ClInclude Include="ssl\OpenSSLInit.hxx" /> + <ClInclude Include="ParseBuffer.hxx" /> + <ClInclude Include="ParseException.hxx" /> + <ClInclude Include="Poll.hxx" /> + <ClInclude Include="PoolBase.hxx" /> + <ClInclude Include="ProducerFifoBuffer.hxx" /> + <ClInclude Include="dns\QueryTypes.hxx" /> + <ClInclude Include="Random.hxx" /> + <ClInclude Include="RecursiveMutex.hxx" /> + <ClInclude Include="resipfaststreams.hxx" /> + <ClInclude Include="dns\RRCache.hxx" /> + <ClInclude Include="dns\RRFactory.hxx" /> + <ClInclude Include="dns\RRList.hxx" /> + <ClInclude Include="dns\RROverlay.hxx" /> + <ClInclude Include="dns\RRVip.hxx" /> + <ClInclude Include="RWMutex.hxx" /> + <ClInclude Include="SelectInterruptor.hxx" /> + <ClInclude Include="ServerProcess.hxx" /> + <ClInclude Include="ssl\SHA1Stream.hxx" /> + <ClInclude Include="SharedCount.hxx" /> + <ClInclude Include="SharedPtr.hxx" /> + <ClInclude Include="Socket.hxx" /> + <ClInclude Include="StlPoolAllocator.hxx" /> + <ClInclude Include="stun\Stun.hxx" /> + <ClInclude Include="Subsystem.hxx" /> + <ClInclude Include="SysLogBuf.hxx" /> + <ClInclude Include="SysLogStream.hxx" /> + <ClInclude Include="ThreadIf.hxx" /> + <ClInclude Include="Time.hxx" /> + <ClInclude Include="TimeLimitFifo.hxx" /> + <ClInclude Include="Timer.hxx" /> + <ClInclude Include="TransportType.hxx" /> + <ClInclude Include="stun\Udp.hxx" /> + <ClInclude Include="vmd5.hxx" /> + <ClInclude Include="vthread.hxx" /> + <ClInclude Include="WinCompat.hxx" /> + <ClInclude Include="WinLeakCheck.hxx" /> + <ClInclude Include="XMLCursor.hxx" /> + </ItemGroup> + <ItemGroup> + <Text Include="ReadMe.txt" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/rutil_9_0.vcxproj.filters b/src/libs/resiprocate/rutil/rutil_9_0.vcxproj.filters new file mode 100644 index 00000000..edb73325 --- /dev/null +++ b/src/libs/resiprocate/rutil/rutil_9_0.vcxproj.filters @@ -0,0 +1,462 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="AbstractFifo.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\AresDns.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BaseException.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Coders.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Condition.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ConfigParse.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="CountStream.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Data.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DataStream.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsAAAARecord.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsCnameRecord.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsHostRecord.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsNaptrRecord.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsSrvRecord.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsStub.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\DnsThread.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DnsUtil.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\ExternalDnsFactory.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="FdPoll.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="FileSystem.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="GeneralCongestionManager.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="HeapInstanceCounter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="KeyValueStore.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\LocalDns.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Lock.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Log.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="MD5Stream.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Mutex.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\OpenSSLInit.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParseBuffer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ParseException.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Poll.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="PoolBase.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\QueryTypes.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Random.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RecursiveMutex.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="resipfaststreams.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\RRCache.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\RRList.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\RROverlay.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dns\RRVip.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="RWMutex.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SelectInterruptor.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ServerProcess.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ssl\SHA1Stream.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Socket.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="stun\Stun.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Subsystem.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SysLogBuf.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="SysLogStream.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ThreadIf.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Time.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Timer.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TransportType.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="stun\Udp.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="vmd5.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="WinCompat.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="XMLCursor.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="AtomicCounter.cxx"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="AbstractFifo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\AresCompat.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\AresDns.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AsyncID.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AsyncProcessHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BaseException.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CircularBuffer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Coders.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="compat.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Condition.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConfigParse.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CongestionManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ConsumerFifoBuffer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="CountStream.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Data.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DataStream.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DinkyPool.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsAAAARecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsCnameRecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsHandler.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsHostRecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsNaptrRecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsResourceRecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsSrvRecord.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsStub.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\DnsThread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DnsUtil.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\ExternalDns.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\ExternalDnsFactory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="FdPoll.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="FdSetIOObserver.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Fifo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="FileSystem.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="FiniteFifo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="GeneralCongestionManager.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="GenericIPAddress.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HashMap.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="HeapInstanceCounter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Inserter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="IntrusiveListElement.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="KeyValueStore.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\LocalDns.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Lock.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Lockable.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Log.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Logger.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MD5Stream.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Mutex.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\OpenSSLInit.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParseBuffer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ParseException.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Poll.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="PoolBase.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ProducerFifoBuffer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\QueryTypes.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Random.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RecursiveMutex.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="resipfaststreams.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\RRCache.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\RRFactory.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\RRList.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\RROverlay.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="dns\RRVip.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="RWMutex.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SelectInterruptor.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ServerProcess.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ssl\SHA1Stream.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SharedCount.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SharedPtr.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Socket.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="StlPoolAllocator.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="stun\Stun.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Subsystem.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SysLogBuf.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="SysLogStream.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ThreadIf.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Time.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TimeLimitFifo.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Timer.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TransportType.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="stun\Udp.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="vmd5.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="vthread.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="WinCompat.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="WinLeakCheck.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="XMLCursor.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="AtomicCounter.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <Text Include="ReadMe.txt" /> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/rutil_9_0.vcxproj.user b/src/libs/resiprocate/rutil/rutil_9_0.vcxproj.user new file mode 100644 index 00000000..abe8dd89 --- /dev/null +++ b/src/libs/resiprocate/rutil/rutil_9_0.vcxproj.user @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup /> +</Project> \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/ssl/OpenSSLInit.cxx b/src/libs/resiprocate/rutil/ssl/OpenSSLInit.cxx new file mode 100644 index 00000000..9b3e9e39 --- /dev/null +++ b/src/libs/resiprocate/rutil/ssl/OpenSSLInit.cxx @@ -0,0 +1,146 @@ +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "rutil/Mutex.hxx" +#include "rutil/Lock.hxx" +#include "rutil/Logger.hxx" + +#ifdef USE_SSL + +#include "rutil/ssl/OpenSSLInit.hxx" + +#include <openssl/e_os2.h> +#include <openssl/rand.h> +#include <openssl/err.h> +#include <openssl/crypto.h> +#include <openssl/ssl.h> + +#define OPENSSL_THREAD_DEFINES +#include <openssl/opensslconf.h> + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +using namespace resip; +using namespace std; + +#include <iostream> + +static bool invokeOpenSSLInit = OpenSSLInit::init(); //.dcm. - only in hxx +volatile bool OpenSSLInit::mInitialized = false; +Mutex* OpenSSLInit::mMutexes; + +bool +OpenSSLInit::init() +{ + static OpenSSLInit instance; + return true; +} + +OpenSSLInit::OpenSSLInit() +{ + int locks = CRYPTO_num_locks(); + mMutexes = new Mutex[locks]; + CRYPTO_set_locking_callback(::resip_OpenSSLInit_lockingFunction); + +#if !defined(WIN32) +#if defined(_POSIX_THREADS) + CRYPTO_set_id_callback(::resip_OpenSSLInit_threadIdFunction); +#else +#error Cannot set OpenSSL up to be threadsafe! +#endif +#endif + +#if 0 //?dcm? -- not used by OpenSSL yet? + CRYPTO_set_dynlock_create_callback(::resip_OpenSSLInit_dynCreateFunction); + CRYPTO_set_dynlock_destroy_callback(::resip_OpenSSLInit_dynDestroyFunction); + CRYPTO_set_dynlock_lock_callback(::resip_OpenSSLInit_dynLockFunction); +#endif + +#if 0 + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); +#endif + + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); + assert(EVP_des_ede3_cbc()); + mInitialized = true; +} + +OpenSSLInit::~OpenSSLInit() +{ + mInitialized = false; + ERR_free_strings();// Clean up data allocated during SSL_load_error_strings + ERR_remove_state(0);// free thread error queue + CRYPTO_cleanup_all_ex_data(); + EVP_cleanup();// Clean up data allocated during OpenSSL_add_all_algorithms + + //!dcm! We know we have a leak; see BaseSecurity::~BaseSecurity for + //!details. +// CRYPTO_mem_leaks_fp(stderr); + + delete [] mMutexes; +} + +void +resip_OpenSSLInit_lockingFunction(int mode, int n, const char* file, int line) +{ + if(!resip::OpenSSLInit::mInitialized) return; + if (mode & CRYPTO_LOCK) + { + OpenSSLInit::mMutexes[n].lock(); + } + else + { + OpenSSLInit::mMutexes[n].unlock(); + } +} + +unsigned long +resip_OpenSSLInit_threadIdFunction() +{ +#if defined(WIN32) + assert(0); +#else +#ifndef _POSIX_THREADS + assert(0); +#endif + unsigned long ret; + ret= (unsigned long)pthread_self(); + return ret; +#endif + return 0; +} + +CRYPTO_dynlock_value* +resip_OpenSSLInit_dynCreateFunction(char* file, int line) +{ + CRYPTO_dynlock_value* dynLock = new CRYPTO_dynlock_value; + dynLock->mutex = new Mutex; + return dynLock; +} + +void +resip_OpenSSLInit_dynDestroyFunction(CRYPTO_dynlock_value* dynlock, const char* file, int line) +{ + delete dynlock->mutex; + delete dynlock; +} + +void +resip_OpenSSLInit_dynLockFunction(int mode, struct CRYPTO_dynlock_value* dynlock, const char* file, int line) +{ + if (mode & CRYPTO_LOCK) + { + dynlock->mutex->lock(); + } + else + { + dynlock->mutex->unlock(); + } +} + +#endif diff --git a/src/libs/resiprocate/rutil/ssl/OpenSSLInit.hxx b/src/libs/resiprocate/rutil/ssl/OpenSSLInit.hxx new file mode 100644 index 00000000..235cfbd9 --- /dev/null +++ b/src/libs/resiprocate/rutil/ssl/OpenSSLInit.hxx @@ -0,0 +1,59 @@ +#if !defined(RESIP_OPENSSLINIT_HXX) +#define RESIP_OPENSSLINIT_HXX + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "rutil/Mutex.hxx" +#include "rutil/RWMutex.hxx" +#include "rutil/Data.hxx" +#include <cassert> +#include <vector> + +// This will not be built or installed if USE_SSL is not defined; if you are +// building against a source tree, and including this, and getting linker +// errors, the source tree was probably built with this flag off. Either stop +// including this file, or re-build the source tree with SSL enabled. +//#ifdef USE_SSL + +struct CRYPTO_dynlock_value +{ + resip::Mutex* mutex; +}; + +extern "C" +{ + void resip_OpenSSLInit_lockingFunction(int mode, int n, const char* file, int line); + unsigned long resip_OpenSSLInit_threadIdFunction(); + CRYPTO_dynlock_value* resip_OpenSSLInit_dynCreateFunction(char* file, int line); + void resip_OpenSSLInit_dynDestroyFunction(CRYPTO_dynlock_value*, const char* file, int line); + void resip_OpenSSLInit_dynLockFunction(int mode, struct CRYPTO_dynlock_value*, const char* file, int line); +} + +namespace resip +{ + +class OpenSSLInit +{ + public: + static bool init(); + private: + OpenSSLInit(); + ~OpenSSLInit(); + friend void ::resip_OpenSSLInit_lockingFunction(int mode, int n, const char* file, int line); + friend unsigned long ::resip_OpenSSLInit_threadIdFunction(); + friend CRYPTO_dynlock_value* ::resip_OpenSSLInit_dynCreateFunction(char* file, int line); + friend void ::resip_OpenSSLInit_dynDestroyFunction(CRYPTO_dynlock_value*, const char* file, int line); + friend void ::resip_OpenSSLInit_dynLockFunction(int mode, struct CRYPTO_dynlock_value*, const char* file, int line); + + static Mutex* mMutexes; + static volatile bool mInitialized; +}; +static bool invokeOpenSSLInit = OpenSSLInit::init(); + +} + +//#endif + +#endif diff --git a/src/libs/resiprocate/rutil/ssl/SHA1Stream.cxx b/src/libs/resiprocate/rutil/ssl/SHA1Stream.cxx new file mode 100644 index 00000000..09f7727d --- /dev/null +++ b/src/libs/resiprocate/rutil/ssl/SHA1Stream.cxx @@ -0,0 +1,162 @@ +#include <assert.h> + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "rutil/Socket.hxx" // for ntohl under windows +#include "rutil/WinLeakCheck.hxx" + +#if defined(USE_SSL) +#include "rutil/ssl/SHA1Stream.hxx" + +// Remove warning about 'this' use in initiator list - pointer is only stored +# if defined(WIN32) && !defined(__GNUC__) +# pragma warning( disable : 4355 ) // using this in base member initializer list +# endif // WIN32 + +using namespace resip; + +SHA1Buffer::SHA1Buffer() + : mContext(new SHA_CTX()), + mBuf(SHA_DIGEST_LENGTH), + mBlown(false) +{ + SHA1_Init(mContext.get()); + setp(&mBuf[0], (&mBuf[mBuf.size()-1])+1); +} + +SHA1Buffer::~SHA1Buffer() +{ +} + +int +SHA1Buffer::sync() +{ + size_t len = pptr() - pbase(); + if (len > 0) + { + SHA1_Update(mContext.get(), reinterpret_cast <unsigned const char*>(pbase()), len); + // reset the put buffer + setp(&mBuf[0], (&mBuf[mBuf.size()-1])+1); + } + return 0; +} + +int +SHA1Buffer::overflow(int c) +{ + sync(); + if (c != -1) + { + mBuf[0] = c; + pbump(1); + return c; + } + return 0; +} + +Data +SHA1Buffer::getHex() +{ + assert(mBlown == false); + SHA1_Final((unsigned char*)&mBuf[0], mContext.get()); + mBlown = true; + Data digest(Data::Share, (const char*)&mBuf[0], mBuf.size()); + return digest.hex(); +} + +Data +SHA1Buffer::getBin(unsigned int bits) +{ + assert(mBlown == false); + assert (bits % 8 == 0); + assert (bits / 8 <= mBuf.size()); + SHA1_Final((unsigned char*)&mBuf[0], mContext.get()); + mBlown = true; + return Data(&mBuf[20-bits/8], bits / 8); +} + +SHA1Stream::SHA1Stream() + : std::ostream(this) +{ +} + +SHA1Stream::~SHA1Stream() +{} + +Data +SHA1Stream::getHex() +{ + flush(); + return SHA1Buffer::getHex(); + //return mStreambuf.getHex(); +} + +Data +SHA1Stream::getBin(unsigned int bits) +{ + flush(); + return SHA1Buffer::getBin(bits); +} + +UInt32 +SHA1Stream::getUInt32() +{ + flush(); + UInt32 input = *((UInt32*)getBin(32).c_str()); + return ntohl(input); +} + + +#endif // USE_SSL + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/ssl/SHA1Stream.hxx b/src/libs/resiprocate/rutil/ssl/SHA1Stream.hxx new file mode 100644 index 00000000..efad6339 --- /dev/null +++ b/src/libs/resiprocate/rutil/ssl/SHA1Stream.hxx @@ -0,0 +1,140 @@ +#if !defined(RESIP_SHA1STREAM_HXX) +#define RESIP_SHA1STREAM_HXX + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include <iostream> +#include <memory> +#include <vector> +#include "rutil/Data.hxx" + +// This will not be compiled or installed if USE_SSL isn't set. If you are +// including this file from a source tree, and you are getting link errors, you +// are probably trying to link against libs that were built without SSL support. +// Either stop trying to use this file, or re-build the libs with ssl support +// enabled. +//#if defined (USE_SSL) +//# include "openssl/sha.h" +//#else +//// !kh! +//// so it would compile without openssl. +//// also see my comment below. +//typedef int SHA_CTX; +//#endif // USE_SSL + +# include "openssl/sha.h" + +namespace resip +{ + +/** + @brief An implementation of std::streambuf used to back the SHA1Stream. + */ +class SHA1Buffer : public std::streambuf +{ + public: + SHA1Buffer(); + virtual ~SHA1Buffer(); + /** @returns the SHA1 hexadecimal representation of the data from the buffer + */ + Data getHex(); + /** + @param bits the lowest order bits in network byte order. bits must be + multiple of 8 + @returns the SHA1 binary representation of the data from the buffer + */ + Data getBin(unsigned int bits); + + protected: + virtual int sync(); + virtual int overflow(int c = -1); + private: + // !kh! + // used pointers to keep the same object layout. + // this adds overhead, two additional new/delete. + // could get rid of the overhead if, sizeof(SHA_CTX) and SHA_DIGEST_LENGTH are known and FIXED. + // could use pimpl to get rid of one new/delete pair. + std::auto_ptr<SHA_CTX> mContext; + std::vector<char> mBuf; + bool mBlown; +}; + +/** + @brief Used to accumlate data written to the stream in a SHA1Buffer and + convert the data to SHA1. + */ +class SHA1Stream : private SHA1Buffer, public std::ostream +{ + public: + SHA1Stream(); + ~SHA1Stream(); + /** Calls flush() on itself and returns the SHA1 data in hex format. + @returns the SHA1 hexadecimal representation of the data written to the stream + */ + Data getHex(); + /** Calls flush() on itself and returns the SHA1 data in binary format. + @param bits the lowest order bits in network byte order. bits must be + multiple of 8 + @returns the SHA1 binary representation of the data written to the stream + */ + Data getBin(unsigned int bits=160); + + /** Calls getBin(32) and converts to a UInt32 */ + UInt32 getUInt32(); + +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/stun/Stun.cxx b/src/libs/resiprocate/rutil/stun/Stun.cxx new file mode 100644 index 00000000..64dbd484 --- /dev/null +++ b/src/libs/resiprocate/rutil/stun/Stun.cxx @@ -0,0 +1,2743 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <cassert> +#include <cstring> +#include <iostream> +#include <cstdlib> +#include <errno.h> + +#ifdef WIN32 +#include <winsock2.h> +#include <stdlib.h> +#include <io.h> +#include <time.h> +#else + +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/types.h> +#include <arpa/inet.h> +#include <fcntl.h> +#include <netdb.h> +#include <netinet/in.h> + +#ifndef __CYGWIN__ +#include <arpa/nameser.h> +#include <resolv.h> +#endif + +#include <net/if.h> + +#if defined (__SUNPRO_CC) || defined (__sun__) +#include <sys/sockio.h> // solaris only? +#endif + +#endif + +#include "Udp.hxx" +#include "Stun.hxx" +#include "rutil/Socket.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace std; +using namespace resip; + +static bool +stunParseAtrAddress( char* body, unsigned int hdrLen, StunAtrAddress4& result ) +{ + if ( hdrLen != 8 ) + { + // clog << "hdrLen wrong for Address" <<endl; + return false; + } + result.pad = *body++; + result.family = *body++; + if (result.family == IPv4Family) + { + UInt16 nport; + memcpy(&nport, body, 2); body+=2; + result.ipv4.port = ntohs(nport); + + UInt32 naddr; + memcpy(&naddr, body, 4); body+=4; + result.ipv4.addr = ntohl(naddr); + return true; + } + else if (result.family == IPv6Family) + { + //clog << "ipv6 not supported" << endl; + } + else + { + //clog << "bad address family: " << result.family << endl; + } + + return false; +} + +static bool +stunParseUInt32( char* body, unsigned int hdrLen, UInt32& result ) +{ + if ( hdrLen != 4 ) + { + return false; + } + else + { + UInt32 tmp; + memcpy(&tmp, body, 4); + result = ntohl(tmp); + return true; + } +} + +static bool +stunParseAtrChangeRequest( char* body, unsigned int hdrLen, StunAtrChangeRequest& result ) +{ + if ( hdrLen != 4 ) + { + //clog << "hdr length = " << hdrLen << " expecting " << sizeof(result) << endl; + + //clog << "Incorrect size for ChangeRequest" << endl; + return false; + } + else + { + memcpy(&result.value, body, 4); + result.value = ntohl(result.value); + return true; + } +} + +static bool +stunParseAtrError( char* body, unsigned int hdrLen, StunAtrError& result ) +{ + if ( hdrLen >= (sizeof(result)-sizeof(result.sizeReason)) ) // Note: result.sizeReason is extra info in StunAtrError that is not on the wire + { + //clog << "head on Error too large" << endl; + return false; + } + else + { + memcpy(&result.pad, body, 2); body+=2; + result.pad = ntohs(result.pad); + result.errorClass = *body++; + result.number = *body++; + + result.sizeReason = hdrLen - 4; + memcpy(&result.reason, body, result.sizeReason); + result.reason[result.sizeReason] = 0; + return true; + } +} + +static bool +stunParseAtrUnknown( char* body, unsigned int hdrLen, StunAtrUnknown& result ) +{ + if ( hdrLen >= sizeof(result) ) + { + return false; + } + else + { + if (hdrLen % 4 != 0) return false; + result.numAttributes = hdrLen / 4; + for (int i=0; i<result.numAttributes; i++) + { + memcpy(&result.attrType[i], body, 2); body+=2; + result.attrType[i] = ntohs(result.attrType[i]); + } + return true; + } +} + + +static bool +stunParseAtrString( char* body, unsigned int hdrLen, StunAtrString& result ) +{ + if ( hdrLen >= STUN_MAX_STRING ) + { + //clog << "String is too large" << endl; + return false; + } + else + { + if (hdrLen % 4 != 0) + { + //clog << "Bad length string " << hdrLen << endl; + return false; + } + + result.sizeValue = hdrLen; + memcpy(&result.value, body, hdrLen); + result.value[hdrLen] = 0; + return true; + } +} + + +static bool +stunParseAtrIntegrity( char* body, unsigned int hdrLen, StunAtrIntegrity& result ) +{ + if ( hdrLen != 20) + { + //clog << "MessageIntegrity must be 20 bytes" << endl; + return false; + } + else + { + memcpy(&result.hash, body, hdrLen); + return true; + } +} + + + +bool +stunParseMessage( char* buf, unsigned int bufLen, StunMessage& msg, bool verbose) +{ + if (verbose) clog << "Received stun message: " << bufLen << " bytes" << endl; + memset(&msg, 0, sizeof(msg)); + + if (sizeof(StunMsgHdr) > bufLen) + { + clog << "Bad message" << endl; + return false; + } + + memcpy(&msg.msgHdr, buf, sizeof(StunMsgHdr)); + msg.msgHdr.msgType = ntohs(msg.msgHdr.msgType); + msg.msgHdr.msgLength = ntohs(msg.msgHdr.msgLength); + + if (msg.msgHdr.msgLength + sizeof(StunMsgHdr) != bufLen) + { + clog << "Message header length doesn't match message size: " << msg.msgHdr.msgLength << " - " << bufLen << endl; + return false; + } + + char* body = buf + sizeof(StunMsgHdr); + unsigned int size = msg.msgHdr.msgLength; + + if (verbose) clog << "bytes after header = " << size << endl; + + while ( size > 0 ) + { + // !jf! should check that there are enough bytes left in the buffer + + StunAtrHdr* attr = reinterpret_cast<StunAtrHdr*>(body); + + unsigned int attrLen = ntohs(attr->length); + int atrType = ntohs(attr->type); + + if (verbose) clog << "Found attribute type=" << atrType << " length=" << attrLen << endl; + if ( attrLen+4 > size ) + { + clog << "claims attribute is larger than size of message " <<"(attribute type="<<atrType<<")"<< endl; + return false; + } + + body += 4; // skip the length and type in attribute header + size -= 4; + + switch ( atrType ) + { + case MappedAddress: + msg.hasMappedAddress = true; + if ( stunParseAtrAddress( body, attrLen, msg.mappedAddress )== false ) + { + clog << "problem parsing MappedAddress" << endl; + return false; + } + else + { + if (verbose) clog << "MappedAddress = " << msg.mappedAddress.ipv4 << endl; + } + + break; + + case ResponseAddress: + msg.hasResponseAddress = true; + if ( stunParseAtrAddress( body, attrLen, msg.responseAddress )== false ) + { + if (verbose) clog << "problem parsing ResponseAddress" << endl; + return false; + } + else + { + if (verbose) clog << "ResponseAddress = " << msg.responseAddress.ipv4 << endl; + } + break; + + case ChangeRequest: + msg.hasChangeRequest = true; + if (stunParseAtrChangeRequest( body, attrLen, msg.changeRequest) == false) + { + if (verbose) clog << "problem parsing ChangeRequest" << endl; + return false; + } + else + { + if (verbose) clog << "ChangeRequest = " << msg.changeRequest.value << endl; + } + break; + + case SourceAddress: + msg.hasSourceAddress = true; + if ( stunParseAtrAddress( body, attrLen, msg.sourceAddress )== false ) + { + if (verbose) clog << "problem parsing SourceAddress" << endl; + return false; + } + else + { + if (verbose) clog << "SourceAddress = " << msg.sourceAddress.ipv4 << endl; + } + break; + + case ChangedAddress: + msg.hasChangedAddress = true; + if ( stunParseAtrAddress( body, attrLen, msg.changedAddress )== false ) + { + if (verbose) clog << "problem parsing ChangedAddress" << endl; + return false; + } + else + { + if (verbose) clog << "ChangedAddress = " << msg.changedAddress.ipv4 << endl; + } + break; + + case Username: + msg.hasUsername = true; + if (stunParseAtrString( body, attrLen, msg.username) == false) + { + if (verbose) clog << "problem parsing Username" << endl; + return false; + } + else + { + if (verbose) clog << "Username = " << msg.username.value << endl; + } + + break; + + case Password: + msg.hasPassword = true; + if (stunParseAtrString( body, attrLen, msg.password) == false) + { + if (verbose) clog << "problem parsing Password" << endl; + return false; + } + else + { + if (verbose) clog << "Password = " << msg.password.value << endl; + } + break; + + case MessageIntegrity: + msg.hasMessageIntegrity = true; + if (stunParseAtrIntegrity( body, attrLen, msg.messageIntegrity) == false) + { + if (verbose) clog << "problem parsing MessageIntegrity" << endl; + return false; + } + else + { + if (verbose) clog << "MessageIntegrity = " << msg.messageIntegrity.hash << endl; + } + + // read the current HMAC + // look up the password given the user of given the transaction id + // compute the HMAC on the buffer + // decide if they match or not + break; + + case ErrorCode: + msg.hasErrorCode = true; + if (stunParseAtrError(body, attrLen, msg.errorCode) == false) + { + if (verbose) clog << "problem parsing ErrorCode" << endl; + return false; + } + else + { + if (verbose) clog << "ErrorCode = " << int(msg.errorCode.errorClass) + << " " << int(msg.errorCode.number) + << " " << msg.errorCode.reason << endl; + } + + break; + + case UnknownAttribute: + msg.hasUnknownAttributes = true; + if (stunParseAtrUnknown(body, attrLen, msg.unknownAttributes) == false) + { + if (verbose) clog << "problem parsing UnknownAttribute" << endl; + return false; + } + break; + + case ReflectedFrom: + msg.hasReflectedFrom = true; + if ( stunParseAtrAddress( body, attrLen, msg.reflectedFrom ) == false ) + { + if (verbose) clog << "problem parsing ReflectedFrom" << endl; + return false; + } + break; + + case XorMappedAddress: + msg.hasXorMappedAddress = true; + if ( stunParseAtrAddress( body, attrLen, msg.xorMappedAddress ) == false ) + { + if (verbose) clog << "problem parsing XorMappedAddress" << endl; + return false; + } + else + { + if (verbose) clog << "XorMappedAddress = " << msg.mappedAddress.ipv4 << endl; + } + break; + + case XorOnly: + msg.xorOnly = true; + if (verbose) + { + if (verbose) clog << "xorOnly = true" << endl; + } + break; + + case ServerName: + msg.hasServerName = true; + if (stunParseAtrString( body, attrLen, msg.serverName) == false) + { + if (verbose) clog << "problem parsing ServerName" << endl; + return false; + } + else + { + if (verbose) clog << "ServerName = " << msg.serverName.value << endl; + } + break; + + case SecondaryAddress: + msg.hasSecondaryAddress = true; + if ( stunParseAtrAddress( body, attrLen, msg.secondaryAddress ) == false ) + { + if (verbose) clog << "problem parsing secondaryAddress" << endl; + return false; + } + else + { + if (verbose) clog << "SecondaryAddress = " << msg.secondaryAddress.ipv4 << endl; + } + break; + + // TURN attributes + + case TurnLifetime: + msg.hasTurnLifetime = true; + if (stunParseUInt32( body, attrLen, msg.turnLifetime) == false) + { + return false; + } + break; + + case TurnAlternateServer: + msg.hasTurnAlternateServer = true; + if ( stunParseAtrAddress( body, attrLen, msg.turnAlternateServer ) == false ) + { + return false; + } + break; + + case TurnMagicCookie: + msg.hasTurnMagicCookie = true; + if (stunParseUInt32( body, attrLen, msg.turnMagicCookie) == false) + { + return false; + } + break; + + case TurnBandwidth: + msg.hasTurnBandwidth = true; + if (stunParseUInt32( body, attrLen, msg.turnBandwidth) == false) + { + return false; + } + break; + + case TurnDestinationAddress: + msg.hasTurnDestinationAddress = true; + if ( stunParseAtrAddress( body, attrLen, msg.turnDestinationAddress ) == false ) + { + return false; + } + break; + + case TurnRemoteAddress: + msg.hasTurnRemoteAddress = true; + if ( stunParseAtrAddress( body, attrLen, msg.turnRemoteAddress ) == false ) + { + return false; + } + break; + + //overlay on parse, ownership is buffer parsed from + case TurnData: + msg.hasTurnData = true; + msg.turnData = new resip::Data(resip::Data::Share, body, attrLen); + break; + + //case TurnNonce: + //break; + //case TurnRealm: + //break; + + default: + if (verbose) clog << "Unknown attribute: " << atrType << endl; + if ( atrType <= 0x7FFF ) + { + return false; + } + } + + body += attrLen; + size -= attrLen; + } + + return true; +} + +static char* +encode16(char* buf, UInt16 data) +{ + UInt16 ndata = htons(data); + memcpy(buf, reinterpret_cast<void*>(&ndata), sizeof(UInt16)); + return buf + sizeof(UInt16); +} + +static char* +encode32(char* buf, UInt32 data) +{ + UInt32 ndata = htonl(data); + memcpy(buf, reinterpret_cast<void*>(&ndata), sizeof(UInt32)); + return buf + sizeof(UInt32); +} + + +static char* +encode(char* buf, const char* data, unsigned int length) +{ + memcpy(buf, data, length); + return buf + length; +} + +static char* +encodeTurnData(char *ptr, const resip::Data* td) +{ + ptr = encode16(ptr, TurnData); + ptr = encode16(ptr, (UInt16)td->size()); + memcpy(ptr, td->data(), td->size()); + ptr += td->size(); + + return ptr; +} + +static char* +encodeAtrUInt32(char* ptr, UInt16 type, UInt32 value) +{ + ptr = encode16(ptr, type); + ptr = encode16(ptr, 4); + ptr = encode32(ptr, value); + return ptr; +} + +static char* +encodeAtrAddress4(char* ptr, UInt16 type, const StunAtrAddress4& atr) +{ + ptr = encode16(ptr, type); + ptr = encode16(ptr, 8); + *ptr++ = atr.pad; + *ptr++ = IPv4Family; + ptr = encode16(ptr, atr.ipv4.port); + ptr = encode32(ptr, atr.ipv4.addr); + + return ptr; +} + +static char* +encodeAtrChangeRequest(char* ptr, const StunAtrChangeRequest& atr) +{ + ptr = encode16(ptr, ChangeRequest); + ptr = encode16(ptr, 4); + ptr = encode32(ptr, atr.value); + return ptr; +} + +static char* +encodeMagicCookie(char* ptr, const UInt32& cookie) +{ + ptr = encode16(ptr, TurnMagicCookie); + ptr = encode16(ptr, 4); + ptr = encode32(ptr, cookie); + return ptr; +} + + +static char* +encodeAtrError(char* ptr, const StunAtrError& atr) +{ + ptr = encode16(ptr, ErrorCode); + ptr = encode16(ptr, 4 + atr.sizeReason); + ptr = encode16(ptr, atr.pad); + *ptr++ = atr.errorClass; + *ptr++ = atr.number; + ptr = encode(ptr, atr.reason, atr.sizeReason); + return ptr; +} + + +static char* +encodeAtrUnknown(char* ptr, const StunAtrUnknown& atr) +{ + ptr = encode16(ptr, UnknownAttribute); + ptr = encode16(ptr, 2+2*atr.numAttributes); + for (int i=0; i<atr.numAttributes; i++) + { + ptr = encode16(ptr, atr.attrType[i]); + } + return ptr; +} + + +static char* +encodeXorOnly(char* ptr) +{ + ptr = encode16(ptr, XorOnly ); + return ptr; +} + + +static char* +encodeAtrString(char* ptr, UInt16 type, const StunAtrString& atr) +{ + assert(atr.sizeValue % 4 == 0); + + ptr = encode16(ptr, type); + ptr = encode16(ptr, atr.sizeValue); + ptr = encode(ptr, atr.value, atr.sizeValue); + return ptr; +} + + +static char* +encodeAtrIntegrity(char* ptr, const StunAtrIntegrity& atr) +{ + ptr = encode16(ptr, MessageIntegrity); + ptr = encode16(ptr, 20); + ptr = encode(ptr, atr.hash, sizeof(atr.hash)); + return ptr; +} + + +unsigned int +stunEncodeMessage( const StunMessage& msg, + char* buf, + unsigned int bufLen, + const StunAtrString& password, + bool verbose) +{ + assert(bufLen >= sizeof(StunMsgHdr)); + char* ptr = buf; + + if (verbose) clog << "Encoding stun message: " << endl; + + ptr = encode16(ptr, msg.msgHdr.msgType); + char* lengthp = ptr; + ptr = encode16(ptr, 0); + ptr = encode(ptr, reinterpret_cast<const char*>(msg.msgHdr.id.octet), sizeof(msg.msgHdr.id)); + + if (msg.hasTurnMagicCookie) + { + if (verbose) clog << "Encoding TurnMagicCookie: " << msg.turnMagicCookie << endl; + ptr = encodeMagicCookie(ptr, msg.turnMagicCookie); + } + if (msg.hasTurnDestinationAddress) + { + if (verbose) clog << "Encoding TurnDestinationAddress: " << msg.turnDestinationAddress.ipv4 << endl; + ptr = encodeAtrAddress4 (ptr, TurnDestinationAddress, msg.turnDestinationAddress); + } + if (msg.hasMappedAddress) + { + if (verbose) clog << "Encoding MappedAddress: " << msg.mappedAddress.ipv4 << endl; + ptr = encodeAtrAddress4 (ptr, MappedAddress, msg.mappedAddress); + } + if (msg.hasResponseAddress) + { + if (verbose) clog << "Encoding ResponseAddress: " << msg.responseAddress.ipv4 << endl; + ptr = encodeAtrAddress4(ptr, ResponseAddress, msg.responseAddress); + } + if (msg.hasTurnAlternateServer ) + { + if (verbose) clog << "Encoding AlternateServer: " << msg.turnAlternateServer.ipv4 << endl; + ptr = encodeAtrAddress4 (ptr, TurnAlternateServer, msg.turnAlternateServer); + } + if (msg.hasChangeRequest) + { + if (verbose) clog << "Encoding ChangeRequest: " << msg.changeRequest.value << endl; + ptr = encodeAtrChangeRequest(ptr, msg.changeRequest); + } + if (msg.hasSourceAddress) + { + if (verbose) clog << "Encoding SourceAddress: " << msg.sourceAddress.ipv4 << endl; + ptr = encodeAtrAddress4(ptr, SourceAddress, msg.sourceAddress); + } + if (msg.hasChangedAddress) + { + if (verbose) clog << "Encoding ChangedAddress: " << msg.changedAddress.ipv4 << endl; + ptr = encodeAtrAddress4(ptr, ChangedAddress, msg.changedAddress); + } + if (msg.hasUsername) + { + if (verbose) clog << "Encoding Username: " << msg.username.value << endl; + ptr = encodeAtrString(ptr, Username, msg.username); + } + if (msg.hasPassword) + { + if (verbose) clog << "Encoding Password: " << msg.password.value << endl; + ptr = encodeAtrString(ptr, Password, msg.password); + } + if (msg.hasErrorCode) + { + if (verbose) clog << "Encoding ErrorCode: class=" + << int(msg.errorCode.errorClass) + << " number=" << int(msg.errorCode.number) + << " reason=" + << msg.errorCode.reason + << endl; + + ptr = encodeAtrError(ptr, msg.errorCode); + } + if (msg.hasUnknownAttributes) + { + if (verbose) clog << "Encoding UnknownAttribute: ???" << endl; + ptr = encodeAtrUnknown(ptr, msg.unknownAttributes); + } + if (msg.hasReflectedFrom) + { + if (verbose) clog << "Encoding ReflectedFrom: " << msg.reflectedFrom.ipv4 << endl; + ptr = encodeAtrAddress4(ptr, ReflectedFrom, msg.reflectedFrom); + } + if (msg.hasXorMappedAddress) + { + if (verbose) clog << "Encoding XorMappedAddress: " << msg.xorMappedAddress.ipv4 << endl; + ptr = encodeAtrAddress4 (ptr, XorMappedAddress, msg.xorMappedAddress); + } + if (msg.xorOnly) + { + if (verbose) clog << "Encoding xorOnly: " << endl; + ptr = encodeXorOnly( ptr ); + } + if (msg.hasServerName) + { + if (verbose) clog << "Encoding ServerName: " << msg.serverName.value << endl; + ptr = encodeAtrString(ptr, ServerName, msg.serverName); + } + if (msg.hasSecondaryAddress) + { + if (verbose) clog << "Encoding SecondaryAddress: " << msg.secondaryAddress.ipv4 << endl; + ptr = encodeAtrAddress4 (ptr, SecondaryAddress, msg.secondaryAddress); + } + if (msg.hasTurnLifetime) + { + if (verbose) clog << "Encoding Turn Lifetime: " << msg.turnLifetime << endl; + ptr = encodeAtrUInt32(ptr, TurnLifetime, msg.turnLifetime); + } + if (msg.hasTurnBandwidth) + { + if (verbose) clog << "Encoding Turn Bandwidth: " << msg.turnBandwidth << endl; + ptr = encodeAtrUInt32(ptr, TurnBandwidth, msg.turnBandwidth); + } + if (msg.hasTurnData) + { + if (verbose) clog << "Encoding TurnData (not shown)" << endl; + ptr = encodeTurnData (ptr, msg.turnData); + } + if (password.sizeValue > 0) + { + if (verbose) clog << "HMAC with password: " << password.value << endl; + + // allocate space for message integrity attribute (hash + attribute type + size) + char* ptrMessageIntegrity = ptr; + ptr += 20 + sizeof(MessageIntegrity) + sizeof(UInt16); + encode16(lengthp, UInt16(ptr - buf - sizeof(StunMsgHdr))); + + StunAtrIntegrity integrity; + // pad with zeros prior to calculating message integrity attribute + int padding = 0; + int len = int(ptrMessageIntegrity - buf); + if (len % 64) + { + padding = 64 - (len % 64); + memset(ptrMessageIntegrity, 0, padding); + } + computeHmac(integrity.hash, buf, len + padding, password.value, password.sizeValue); + encodeAtrIntegrity(ptrMessageIntegrity, integrity); + } + + if (verbose) clog << endl; + encode16(lengthp, UInt16(ptr - buf - sizeof(StunMsgHdr))); + return int(ptr - buf); +} + +int +stunRand() +{ + // return 32 bits of random stuff + assert( sizeof(int) == 4 ); + static bool init=false; + if ( !init ) + { + init = true; + + UInt64 tick; + +#if defined(WIN32) +#if !defined(UNDER_CE) && !defined(__GNUC__) && !defined(_WIN64) + volatile unsigned int lowtick=0,hightick=0; + __asm + { + rdtsc + mov lowtick, eax + mov hightick, edx + } + tick = hightick; + tick <<= 32; + tick |= lowtick; +#else + tick = GetTickCount(); +#endif +#elif defined(__GNUC__) && ( defined(__i686__) || defined(__i386__) || defined(__x86_64__) ) + asm("rdtsc" : "=A" (tick)); +#elif defined (__SUNPRO_CC) || defined( __sparc__ ) + tick = gethrtime(); +#elif defined(__APPLE__) || defined(__MACH__) + int fd=open("/dev/random",O_RDONLY); + read(fd,&tick,sizeof(tick)); + closeSocket(fd); +#elif defined(__linux__) + int fd=open("/dev/urandom",O_RDONLY); + read(fd,&tick,sizeof(tick)); + closeSocket(fd); +#else +# error Need some way to seed the random number generator +#endif + int seed = int(tick); +#ifdef WIN32 + srand(seed); +#else + srandom(seed); +#endif + } + +#ifdef WIN32 + assert( RAND_MAX == 0x7fff ); + int r1 = rand(); + int r2 = rand(); + + int ret = (r1<<16) + r2; + + return ret; +#else + return random(); +#endif +} + + +/// return a random number to use as a port +int +stunRandomPort() +{ + int min=0x4000; + int max=0x7FFF; + + int ret = stunRand(); + ret = ret|min; + ret = ret&max; + + return ret; +} + + +#ifndef USE_SSL +void +computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey) +{ + strncpy(hmac,"hmac-not-implemented",20); +} +#else +#ifdef WIN32 +//hack for name collision of OCSP_RESPONSE and wincrypt.h in latest openssl release 0.9.8h +//http://www.google.com/search?q=OCSP%5fRESPONSE+wincrypt%2eh +//continue to watch this issue for a real fix. +#undef OCSP_RESPONSE +#endif +#include <openssl/hmac.h> + +void +computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey) +{ + unsigned int resultSize=0; + HMAC(EVP_sha1(), + key, sizeKey, + reinterpret_cast<const unsigned char*>(input), length, + reinterpret_cast<unsigned char*>(hmac), &resultSize); + assert(resultSize == 20); +} +#endif + + +static void +toHex(const char* buffer, int bufferSize, char* output) +{ + static char hexmap[] = "0123456789abcdef"; + + const char* p = buffer; + char* r = output; + for (int i=0; i < bufferSize; i++) + { + unsigned char temp = *p++; + + int hi = (temp & 0xf0)>>4; + int low = (temp & 0xf); + + *r++ = hexmap[hi]; + *r++ = hexmap[low]; + } + *r = 0; +} + +void +stunCreateUserName(const StunAddress4& source, StunAtrString* username) +{ + UInt64 time = stunGetSystemTimeSecs(); + time -= (time % 20*60); + //UInt64 hitime = time >> 32; + UInt64 lotime = time & 0xFFFFFFFF; + + char buffer[1024]; + sprintf(buffer, + "%08x:%08x:%08x:", + UInt32(source.addr), + UInt32(stunRand()), + UInt32(lotime)); + assert( strlen(buffer) < 1024 ); + + assert(strlen(buffer) + 41 < STUN_MAX_STRING); + + char hmac[20]; + char key[] = "Jason"; + computeHmac(hmac, buffer, (int)strlen(buffer), key, (int)strlen(key) ); + char hmacHex[41]; + toHex(hmac, 20, hmacHex ); + hmacHex[40] =0; + + strcat(buffer,hmacHex); + + int l = (int)strlen(buffer); + assert( l+1 < STUN_MAX_STRING ); + assert( l%4 == 0 ); + + username->sizeValue = l; + memcpy(username->value,buffer,l); + username->value[l]=0; + + //if (verbose) clog << "computed username=" << username.value << endl; +} + +void +stunCreatePassword(const StunAtrString& username, StunAtrString* password) +{ + char hmac[20]; + char key[] = "Fluffy"; + //char buffer[STUN_MAX_STRING]; + computeHmac(hmac, username.value, (int)strlen(username.value), key, (int)strlen(key)); + toHex(hmac, 20, password->value); + password->sizeValue = 40; + password->value[40]=0; + + //clog << "password=" << password->value << endl; +} + + +UInt64 +stunGetSystemTimeSecs() +{ + UInt64 time=0; +#if defined(WIN32) + SYSTEMTIME t; + // CJ TODO - this probably has bug on wrap around every 24 hours + GetSystemTime( &t ); + time = (t.wHour*60+t.wMinute)*60+t.wSecond; +#else + struct timeval now; + gettimeofday( &now , NULL ); + //assert( now ); + time = now.tv_sec; +#endif + return time; +} + + +ostream& operator<< ( ostream& strm, const UInt128& r ) +{ + strm << int(r.octet[0]); + for ( int i=1; i<16; i++ ) + { + strm << ':' << int(r.octet[i]); + } + + return strm; +} + +ostream& +operator<<( ostream& strm, const StunAddress4& addr) +{ + UInt32 ip = addr.addr; + strm << ((int)(ip>>24)&0xFF) << "."; + strm << ((int)(ip>>16)&0xFF) << "."; + strm << ((int)(ip>> 8)&0xFF) << "."; + strm << ((int)(ip>> 0)&0xFF) ; + + strm << ":" << addr.port; + + return strm; +} + +ostream& +operator<<(ostream& os, const StunMsgHdr& h) +{ + os << "STUN: "; + switch (h.msgType) { + case BindRequestMsg: + os << "BindingRequest"; + break; + case BindResponseMsg: + os << "BindingResponse"; + break; + case BindErrorResponseMsg: + os << "BindingErrorResponse"; + break; + case TurnAllocateRequest: + os << "TurnAllocateRequest"; + break; + case TurnAllocateResponse: + os << "TurnAllocateResponse"; + break; + case TurnAllocateErrorResponse: + os << "TurnAllocateErrorResponse"; + break; + case TurnSendRequest: + os << "TurnSendRequest"; + break; + case TurnSendResponse: + os << "TurnSendResponse"; + break; + case TurnSendErrorResponse: + os << "TurnSendErrorResponse"; + break; + case TurnDataIndication: + os << "TurnDataIndication"; + break; + case TurnSetActiveDestinationRequest: + os << "TurnSetActiveDestinationRequest"; + break; + case TurnSetActiveDestinationResponse: + os << "TurnSetActiveDestinationResponse"; + break; + case TurnSetActiveDestinationErrorResponse: + os << "TurnSetActiveDestinationErrorResponse"; + break; + } + + os << ", id "; + + os << std::hex; + for (unsigned int i = 0; i < sizeof(UInt128); i++) { + os << static_cast<int>(h.id.octet[i]); + } + os << std::dec; + + return os; +} + + +// returns true if it scucceeded +bool +stunParseHostName( char* peerName, + UInt32& ip, + UInt16& portVal, + UInt16 defaultPort ) +{ + in_addr sin_addr; + + char host[512]; + strncpy(host,peerName,512); + host[512-1]='\0'; + char* port = NULL; + + int portNum = defaultPort; + + // pull out the port part if present. + char* sep = strchr(host,':'); + + if ( sep == NULL ) + { + portNum = defaultPort; + } + else + { + *sep = '\0'; + port = sep + 1; + // set port part + + char* endPtr=NULL; + + portNum = strtol(port,&endPtr,10); + + if ( endPtr != NULL ) + { + if ( *endPtr != '\0' ) + { + portNum = defaultPort; + } + } + } + + if ( portNum < 1024 ) return false; + if ( portNum >= 0xFFFF ) return false; + + // figure out the host part + struct hostent* h; + +#ifdef WIN32 + assert( strlen(host) >= 1 ); + if ( isdigit( host[0] ) ) + { + // assume it is a ip address + unsigned long a = inet_addr(host); + //cerr << "a=0x" << hex << a << dec << endl; + + ip = ntohl( a ); + } + else + { + // assume it is a host name + h = gethostbyname( host ); + + if ( h == NULL ) + { + int err = getErrno(); + std::cerr << "error was " << err << std::endl; + assert( err != WSANOTINITIALISED ); + + ip = ntohl( 0x7F000001L ); + + return false; + } + else + { + sin_addr = *(struct in_addr*)h->h_addr; + ip = ntohl( sin_addr.s_addr ); + } + } + +#else + h = gethostbyname( host ); + if ( h == NULL ) + { + int err = getErrno(); + std::cerr << "error was " << err << std::endl; + ip = ntohl( 0x7F000001L ); + return false; + } + else + { + sin_addr = *(struct in_addr*)h->h_addr; + ip = ntohl( sin_addr.s_addr ); + } +#endif + + portVal = portNum; + + return true; +} + + +bool +stunParseServerName( char* name, StunAddress4& addr) +{ + assert(name); + + // TODO - put in DNS SRV stuff. + + bool ret = stunParseHostName( name, addr.addr, addr.port, 3478); + if ( ret != true ) + { + addr.port=0xFFFF; + } + return ret; +} + +static void +stunCreateErrorResponse(StunMessage& response, int cl, int number, const char* msg) +{ + response.msgHdr.msgType = BindErrorResponseMsg; + response.hasErrorCode = true; + response.errorCode.errorClass = cl; + response.errorCode.number = number; + strcpy(response.errorCode.reason, msg); + response.errorCode.sizeReason = (UInt16)strlen(msg); +} + +#if 0 +static void +stunCreateSharedSecretErrorResponse(StunMessage& response, int cl, int number, const char* msg) +{ + response.msgHdr.msgType = SharedSecretErrorResponseMsg; + response.hasErrorCode = true; + response.errorCode.errorClass = cl; + response.errorCode.number = number; + strcpy(response.errorCode.reason, msg); +} +#endif + +static void +stunCreateSharedSecretResponse(const StunMessage& request, const StunAddress4& source, StunMessage& response) +{ + response.msgHdr.msgType = SharedSecretResponseMsg; + response.msgHdr.id = request.msgHdr.id; + + response.hasUsername = true; + stunCreateUserName( source, &response.username); + + response.hasPassword = true; + stunCreatePassword( response.username, &response.password); +} + + +// This funtion takes a single message sent to a stun server, parses +// and constructs an apropriate repsonse - returns true if message is +// valid +bool +stunServerProcessMsg( char* buf, + unsigned int bufLen, + StunAddress4& from, + StunAddress4& secondary, + StunAddress4& myAddr, + StunAddress4& altAddr, + StunMessage* resp, + StunAddress4* destination, + StunAtrString* hmacPassword, + bool* changePort, + bool* changeIp, + bool verbose) +{ + + // set up information for default response + + memset( resp, 0 , sizeof(*resp) ); + + *changeIp = false; + *changePort = false; + + StunMessage req; + bool ok = stunParseMessage( buf,bufLen, req, verbose); + + if (!ok) // Complete garbage, drop it on the floor + { + if (verbose) clog << "Request did not parse" << endl; + return false; + } + if (verbose) clog << "Request parsed ok" << endl; + + StunAddress4 mapped = req.mappedAddress.ipv4; + StunAddress4 respondTo = req.responseAddress.ipv4; + UInt32 flags = req.changeRequest.value; + + switch (req.msgHdr.msgType) + { + case SharedSecretRequestMsg: + if(verbose) clog << "Received SharedSecretRequestMsg on udp. send error 433." << endl; + // !cj! - should fix so you know if this came over TLS or UDP + stunCreateSharedSecretResponse(req, from, *resp); + //stunCreateSharedSecretErrorResponse(*resp, 4, 33, "this request must be over TLS"); + return true; + + case BindRequestMsg: + if (!req.hasMessageIntegrity) + { + if (verbose) clog << "BindRequest does not contain MessageIntegrity" << endl; + + if (0) // !jf! mustAuthenticate + { + if(verbose) clog << "Received BindRequest with no MessageIntegrity. Sending 401." << endl; + stunCreateErrorResponse(*resp, 4, 1, "Missing MessageIntegrity"); + return true; + } + } + else + { + if (!req.hasUsername) + { + if (verbose) clog << "No UserName. Send 432." << endl; + stunCreateErrorResponse(*resp, 4, 32, "No UserName and contains MessageIntegrity"); + return true; + } + else + { + if (verbose) clog << "Validating username: " << req.username.value << endl; + // !jf! could retrieve associated password from provisioning here + if (strcmp(req.username.value, "test") == 0) + { + if (0) + { + // !jf! if the credentials are stale + stunCreateErrorResponse(*resp, 4, 30, "Stale credentials on BindRequest"); + return true; + } + else + { + if (verbose) clog << "Validating MessageIntegrity" << endl; + // need access to shared secret + + unsigned char hmac[20]; +#ifdef USE_SSL + unsigned int hmacSize=20; + + HMAC(EVP_sha1(), + "1234", 4, + reinterpret_cast<const unsigned char*>(buf), bufLen-20-4, + hmac, &hmacSize); + assert(hmacSize == 20); +#endif + + if (memcmp(buf, hmac, 20) != 0) + { + if (verbose) clog << "MessageIntegrity is bad. Sending " << endl; + stunCreateErrorResponse(*resp, 4, 3, "Unknown username. Try test with password 1234"); + return true; + } + + // need to compute this later after message is filled in + resp->hasMessageIntegrity = true; + assert(req.hasUsername); + resp->hasUsername = true; + resp->username = req.username; // copy username in + } + } + else + { + if (verbose) clog << "Invalid username: " << req.username.value << "Send 430." << endl; + } + } + } + + // TODO !jf! should check for unknown attributes here and send 420 listing the + // unknown attributes. + + if ( respondTo.port == 0 ) respondTo = from; + if ( mapped.port == 0 ) mapped = from; + + *changeIp = ( flags & ChangeIpFlag )?true:false; + *changePort = ( flags & ChangePortFlag )?true:false; + + if (verbose) + { + clog << "Request is valid:" << endl; + clog << "\t flags=" << flags << endl; + clog << "\t changeIp=" << *changeIp << endl; + clog << "\t changePort=" << *changePort << endl; + clog << "\t from = " << from << endl; + clog << "\t respond to = " << respondTo << endl; + clog << "\t mapped = " << mapped << endl; + } + + // form the outgoing message + resp->msgHdr.msgType = BindResponseMsg; + for ( int i=0; i<16; i++ ) + { + resp->msgHdr.id.octet[i] = req.msgHdr.id.octet[i]; + } + + if ( req.xorOnly == false ) + { + resp->hasMappedAddress = true; + resp->mappedAddress.ipv4.port = mapped.port; + resp->mappedAddress.ipv4.addr = mapped.addr; + } + + if (1) // do xorMapped address or not + { + resp->hasXorMappedAddress = true; + UInt16 id16 = req.msgHdr.id.octet[0]<<8 + | req.msgHdr.id.octet[1]; + UInt32 id32 = req.msgHdr.id.octet[0]<<24 + | req.msgHdr.id.octet[1]<<16 + | req.msgHdr.id.octet[2]<<8 + | req.msgHdr.id.octet[3]; + resp->xorMappedAddress.ipv4.port = mapped.port^id16; + resp->xorMappedAddress.ipv4.addr = mapped.addr^id32; + } + + resp->hasSourceAddress = true; + resp->sourceAddress.ipv4.port = (*changePort) ? altAddr.port : myAddr.port; + resp->sourceAddress.ipv4.addr = (*changeIp) ? altAddr.addr : myAddr.addr; + + resp->hasChangedAddress = true; + resp->changedAddress.ipv4.port = altAddr.port; + resp->changedAddress.ipv4.addr = altAddr.addr; + + if ( secondary.port != 0 ) + { + resp->hasSecondaryAddress = true; + resp->secondaryAddress.ipv4.port = secondary.port; + resp->secondaryAddress.ipv4.addr = secondary.addr; + } + + if ( req.hasUsername && req.username.sizeValue > 0 ) + { + // copy username in + resp->hasUsername = true; + assert( req.username.sizeValue % 4 == 0 ); + assert( req.username.sizeValue < STUN_MAX_STRING ); + memcpy( resp->username.value, req.username.value, req.username.sizeValue ); + resp->username.sizeValue = req.username.sizeValue; + } + + if (1) // add ServerName + { + resp->hasServerName = true; + const char serverName[] = "Vovida.org " STUN_VERSION; // must pad to mult of 4 + + assert( sizeof(serverName) < STUN_MAX_STRING ); + //cerr << "sizeof serverName is " << sizeof(serverName) << endl; + assert( sizeof(serverName)%4 == 0 ); + memcpy( resp->serverName.value, serverName, sizeof(serverName)); + resp->serverName.sizeValue = sizeof(serverName); + } + + if ( req.hasMessageIntegrity & req.hasUsername ) + { + // this creates the password that will be used in the HMAC when then + // messages is sent + stunCreatePassword( req.username, hmacPassword ); + } + + if (req.hasUsername && (req.username.sizeValue > 64 ) ) + { + UInt32 source; + assert( sizeof(int) == sizeof(UInt32) ); + + sscanf(req.username.value, "%x", &source); + resp->hasReflectedFrom = true; + resp->reflectedFrom.ipv4.port = 0; + resp->reflectedFrom.ipv4.addr = source; + } + + destination->port = respondTo.port; + destination->addr = respondTo.addr; + + return true; + + default: + if (verbose) clog << "Unknown or unsupported request " << endl; + return false; + } + + assert(0); + return false; +} + +bool +stunInitServer(StunServerInfo& info, const StunAddress4& myAddr, + const StunAddress4& altAddr, int startMediaPort, bool verbose ) +{ + assert( myAddr.port != 0 ); + assert( altAddr.port!= 0 ); + assert( myAddr.addr != 0 ); + //assert( altAddr.addr != 0 ); + + info.myAddr = myAddr; + info.altAddr = altAddr; + + info.myFd = INVALID_SOCKET; + info.altPortFd = INVALID_SOCKET; + info.altIpFd = INVALID_SOCKET; + info.altIpPortFd = INVALID_SOCKET; + + memset(info.relays, 0, sizeof(info.relays)); + if (startMediaPort > 0) + { + info.relay = true; + + for (int i=0; i<MAX_MEDIA_RELAYS; ++i) + { + StunMediaRelay* relay = &info.relays[i]; + relay->relayPort = startMediaPort+i; + relay->fd = 0; + relay->expireTime = 0; + } + } + else + { + info.relay = false; + } + + if ((info.myFd = openPort(myAddr.port, myAddr.addr,verbose)) == INVALID_SOCKET) + { + if (verbose) clog << "Can't open " << myAddr << endl; + stunStopServer(info); + + return false; + } + //if (verbose) clog << "Opened " << myAddr.addr << ":" << myAddr.port << " --> " << info.myFd << endl; + + if ((info.altPortFd = openPort(altAddr.port,myAddr.addr,verbose)) == INVALID_SOCKET) + { + if (verbose) clog << "Can't open " << myAddr << endl; + stunStopServer(info); + return false; + } + //if (verbose) clog << "Opened " << myAddr.addr << ":" << altAddr.port << " --> " << info.altPortFd << endl; + + + info.altIpFd = INVALID_SOCKET; + if ( altAddr.addr != 0 ) + { + if ((info.altIpFd = openPort( myAddr.port, altAddr.addr,verbose)) == INVALID_SOCKET) + { + if (verbose) clog << "Can't open " << altAddr << endl; + stunStopServer(info); + return false; + } + //if (verbose) clog << "Opened " << altAddr.addr << ":" << myAddr.port << " --> " << info.altIpFd << endl;; + } + + info.altIpPortFd = INVALID_SOCKET; + if ( altAddr.addr != 0 ) + { if ((info.altIpPortFd = openPort(altAddr.port, altAddr.addr,verbose)) == INVALID_SOCKET) + { + if (verbose) clog << "Can't open " << altAddr << endl; + stunStopServer(info); + return false; + } + //if (verbose) clog << "Opened " << altAddr.addr << ":" << altAddr.port << " --> " << info.altIpPortFd << endl;; + } + + return true; +} + +void +stunStopServer(StunServerInfo& info) +{ + if (info.myFd > 0) closeSocket(info.myFd); + if (info.altPortFd > 0) closeSocket(info.altPortFd); + if (info.altIpFd > 0) closeSocket(info.altIpFd); + if (info.altIpPortFd > 0) closeSocket(info.altIpPortFd); + + if (info.relay) + { + for (int i=0; i<MAX_MEDIA_RELAYS; ++i) + { + StunMediaRelay* relay = &info.relays[i]; + if (relay->fd) + { + closeSocket(relay->fd); + relay->fd = 0; + } + } + } +} + +bool +stunServerProcess(StunServerInfo& info, bool verbose) +{ + char msg[STUN_MAX_MESSAGE_SIZE]; + int msgLen = sizeof(msg); + + bool ok = false; + bool recvAltIp =false; + bool recvAltPort = false; + + fd_set fdSet; + resip::Socket maxFd=0; + + FD_ZERO(&fdSet); + FD_SET(info.myFd,&fdSet); + if ( info.myFd >= maxFd ) maxFd=info.myFd+1; + FD_SET(info.altPortFd,&fdSet); + if ( info.altPortFd >= maxFd ) maxFd=info.altPortFd+1; + + if ( info.altIpFd != INVALID_SOCKET ) + { + FD_SET(info.altIpFd,&fdSet); + if (info.altIpFd>=maxFd) maxFd=info.altIpFd+1; + } + if ( info.altIpPortFd != INVALID_SOCKET ) + { + FD_SET(info.altIpPortFd,&fdSet); + if (info.altIpPortFd>=maxFd) maxFd=info.altIpPortFd+1; + } + + if (info.relay) + { + for (int i=0; i<MAX_MEDIA_RELAYS; ++i) + { + StunMediaRelay* relay = &info.relays[i]; + if (relay->fd) + { + FD_SET(relay->fd, &fdSet); + if ((resip::Socket)relay->fd >= maxFd) + { + maxFd=relay->fd+1; + } + } + } + } + + if ( info.altIpFd != INVALID_SOCKET ) + { + FD_SET(info.altIpFd,&fdSet); + if (info.altIpFd>=maxFd) maxFd=info.altIpFd+1; + } + if ( info.altIpPortFd != INVALID_SOCKET ) + { + FD_SET(info.altIpPortFd,&fdSet); + if (info.altIpPortFd>=maxFd) maxFd=info.altIpPortFd+1; + } + + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 1000; + + int e = (int)select( (int)maxFd, &fdSet, NULL,NULL, &tv ); + if (e < 0) + { + int err = getErrno(); + if (verbose) clog << "Error on select: " << strerror(err) << endl; + } + else if (e >= 0) + { + StunAddress4 from; + + // do the media relaying + if (info.relay) + { + time_t now = time(0); + for (int i=0; i<MAX_MEDIA_RELAYS; ++i) + { + StunMediaRelay* relay = &info.relays[i]; + if (relay->fd) + { + if (FD_ISSET(relay->fd, &fdSet)) + { + char msg[MAX_RTP_MSG_SIZE]; + int msgLen = sizeof(msg); + + StunAddress4 rtpFrom; + ok = getMessage( relay->fd, msg, &msgLen, &rtpFrom.addr, &rtpFrom.port ,verbose); + if (ok) + { + sendMessage(info.myFd, msg, msgLen, relay->destination.addr, relay->destination.port, verbose); + relay->expireTime = now + MEDIA_RELAY_TIMEOUT; + if ( verbose ) clog << "Relay packet on " + << relay->fd + << " from " << rtpFrom + << " -> " << relay->destination + << endl; + } + } + else if (now > relay->expireTime) + { + closeSocket(relay->fd); + relay->fd = 0; + } + } + } + } + + + if (FD_ISSET(info.myFd,&fdSet)) + { + if (verbose) clog << "received on A1:P1" << endl; + recvAltIp = false; + recvAltPort = false; + ok = getMessage( info.myFd, msg, &msgLen, &from.addr, &from.port,verbose ); + } + else if (FD_ISSET(info.altPortFd, &fdSet)) + { + if (verbose) clog << "received on A1:P2" << endl; + recvAltIp = false; + recvAltPort = true; + ok = getMessage( info.altPortFd, msg, &msgLen, &from.addr, &from.port,verbose ); + } + else if ( (info.altIpFd!=INVALID_SOCKET) && FD_ISSET(info.altIpFd,&fdSet)) + { + if (verbose) clog << "received on A2:P1" << endl; + recvAltIp = true; + recvAltPort = false; + ok = getMessage( info.altIpFd, msg, &msgLen, &from.addr, &from.port ,verbose); + } + else if ( (info.altIpPortFd!=INVALID_SOCKET) && FD_ISSET(info.altIpPortFd, &fdSet)) + { + if (verbose) clog << "received on A2:P2" << endl; + recvAltIp = true; + recvAltPort = true; + ok = getMessage( info.altIpPortFd, msg, &msgLen, &from.addr, &from.port,verbose ); + } + else + { + return true; + } + + int relayPort = 0; + if (info.relay) + { + for (int i=0; i<MAX_MEDIA_RELAYS; ++i) + { + StunMediaRelay* relay = &info.relays[i]; + if (relay->destination.addr == from.addr && + relay->destination.port == from.port) + { + relayPort = relay->relayPort; + relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT; + break; + } + } + + if (relayPort == 0) + { + for (int i=0; i<MAX_MEDIA_RELAYS; ++i) + { + StunMediaRelay* relay = &info.relays[i]; + if (relay->fd == 0) + { + if ( verbose ) clog << "Open relay port " << relay->relayPort << endl; + + relay->fd = (int)openPort(relay->relayPort, info.myAddr.addr, verbose); + relay->destination.addr = from.addr; + relay->destination.port = from.port; + relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT; + relayPort = relay->relayPort; + break; + } + } + } + } + + if ( !ok ) + { + if ( verbose ) clog << "Get message did not return a valid message" <<endl; + return true; + } + + if ( verbose ) clog << "Got a request (len=" << msgLen << ") from " << from << endl; + + if ( msgLen <= 0 ) + { + return true; + } + + bool changePort = false; + bool changeIp = false; + + StunMessage resp; + StunAddress4 dest; + StunAtrString hmacPassword; + hmacPassword.sizeValue = 0; + + StunAddress4 secondary; + secondary.port = 0; + secondary.addr = 0; + + if (info.relay && relayPort) + { + secondary = from; + + from.addr = info.myAddr.addr; + from.port = relayPort; + } + + ok = stunServerProcessMsg( msg, msgLen, from, secondary, + recvAltIp ? info.altAddr : info.myAddr, + recvAltIp ? info.myAddr : info.altAddr, + &resp, + &dest, + &hmacPassword, + &changePort, + &changeIp, + verbose ); + + if ( !ok ) + { + if ( verbose ) clog << "Failed to parse message" << endl; + return true; + } + + char buf[STUN_MAX_MESSAGE_SIZE]; + int len = sizeof(buf); + + len = stunEncodeMessage( resp, buf, len, hmacPassword,verbose ); + + if ( dest.addr == 0 ) ok=false; + if ( dest.port == 0 ) ok=false; + + if ( ok ) + { + assert( dest.addr != 0 ); + assert( dest.port != 0 ); + + resip::Socket sendFd; + + bool sendAltIp = recvAltIp; // send on the received IP address + bool sendAltPort = recvAltPort; // send on the received port + + if ( changeIp ) sendAltIp = !sendAltIp; // if need to change IP, then flip logic + if ( changePort ) sendAltPort = !sendAltPort; // if need to change port, then flip logic + + if ( !sendAltPort ) + { + if ( !sendAltIp ) + { + sendFd = info.myFd; + } + else + { + sendFd = info.altIpFd; + } + } + else + { + if ( !sendAltIp ) + { + sendFd = info.altPortFd; + } + else + { + sendFd = info.altIpPortFd; + } + } + + if ( sendFd != INVALID_SOCKET ) + { + sendMessage( sendFd, buf, len, dest.addr, dest.port, verbose ); + } + } + } + + return true; +} + +int +stunFindLocalInterfaces(UInt32* addresses,int maxRet) +{ +#if defined(WIN32) || defined(__sparc__) + return 0; +#else + struct ifconf ifc; + + int s = socket( AF_INET, SOCK_DGRAM, 0 ); + const int len = 100 * sizeof(struct ifreq); + + char buf[ len ]; + + ifc.ifc_len = len; + ifc.ifc_buf = buf; + + int e = ioctl(s,SIOCGIFCONF,&ifc); + char *ptr = buf; + int tl = ifc.ifc_len; + int count=0; + + while ( (tl > 0) && ( count < maxRet) ) + { + struct ifreq* ifr = (struct ifreq *)ptr; + + int si = sizeof(ifr->ifr_name) + sizeof(struct sockaddr); + tl -= si; + ptr += si; + //char* name = ifr->ifr_ifrn.ifrn_name; + //cerr << "name = " << name << endl; + + struct ifreq ifr2; + ifr2 = *ifr; + + e = ioctl(s,SIOCGIFADDR,&ifr2); + if ( e == -1 ) + { + break; + } + + //cerr << "ioctl addr e = " << e << endl; + + struct sockaddr a = ifr2.ifr_addr; + struct sockaddr_in* addr = (struct sockaddr_in*) &a; + + UInt32 ai = ntohl( addr->sin_addr.s_addr ); + if (int((ai>>24)&0xFF) != 127) + { + addresses[count++] = ai; + } + +#if 0 + cerr << "Detected interface " + << int((ai>>24)&0xFF) << "." + << int((ai>>16)&0xFF) << "." + << int((ai>> 8)&0xFF) << "." + << int((ai )&0xFF) << endl; +#endif + } + + closeSocket(s); + + return count; +#endif +} + +void +stunBuildReqSimple( StunMessage* msg, + const StunAtrString& username, + bool changePort, bool changeIp, unsigned int id ) +{ + assert( msg ); + memset( msg , 0 , sizeof(*msg) ); + + msg->msgHdr.msgType = BindRequestMsg; + + for ( int i=0; i<16; i=i+4 ) + { + assert(i+3<16); + int r = stunRand(); + msg->msgHdr.id.octet[i+0]= r>>0; + msg->msgHdr.id.octet[i+1]= r>>8; + msg->msgHdr.id.octet[i+2]= r>>16; + msg->msgHdr.id.octet[i+3]= r>>24; + } + + if ( id != 0 ) + { + msg->msgHdr.id.octet[0] = id; + } + + msg->hasChangeRequest = true; + msg->changeRequest.value =(changeIp?ChangeIpFlag:0) | + (changePort?ChangePortFlag:0); + + if ( username.sizeValue > 0 ) + { + msg->hasUsername = true; + msg->username = username; + } +} + + +static void +stunSendTest( resip::Socket myFd, StunAddress4& dest, + const StunAtrString& username, const StunAtrString& password, + int testNum, bool verbose ) +{ + assert( dest.addr != 0 ); + assert( dest.port != 0 ); + + bool changePort=false; + bool changeIP=false; + bool discard=false; + + switch (testNum) + { + case 1: + case 10: + case 11: + break; + case 2: + //changePort=true; + changeIP=true; + break; + case 3: + changePort=true; + break; + case 4: + changeIP=true; + break; + case 5: + discard=true; + break; + default: + cerr << "Test " << testNum <<" is unknown\n"; + assert(0); + } + + StunMessage req; + memset(&req, 0, sizeof(StunMessage)); + + stunBuildReqSimple( &req, username, + changePort , changeIP , + testNum ); + + char buf[STUN_MAX_MESSAGE_SIZE]; + int len = STUN_MAX_MESSAGE_SIZE; + + len = stunEncodeMessage( req, buf, len, password,verbose ); + + if ( verbose ) + { + clog << "About to send msg of len " << len << " to " << dest << endl; + } + + sendMessage( myFd, buf, len, dest.addr, dest.port, verbose ); + +} + + +void +stunGetUserNameAndPassword( const StunAddress4& dest, + StunAtrString* username, + StunAtrString* password) +{ + // !cj! This is totally bogus - need to make TLS connection to dest and get a + // username and password to use + stunCreateUserName(dest, username); + stunCreatePassword(*username, password); +} + + +bool +stunTest( StunAddress4& dest, int testNum, bool verbose, StunAddress4* sAddr, unsigned long timeoutMs ) +{ + assert( dest.addr != 0 ); + assert( dest.port != 0 ); + + int port = stunRandomPort(); + UInt32 interfaceIp=0; + if (sAddr) + { + interfaceIp = sAddr->addr; + if ( sAddr->port != 0 ) + { + port = sAddr->port; + } + } + resip::Socket myFd = openPort(port,interfaceIp,verbose); + + if (myFd == INVALID_SOCKET) + { + return false; + } + + // make socket non-blocking + if (!makeSocketNonBlocking(myFd)) + { + return false; + } + + StunAtrString username; + StunAtrString password; + + username.sizeValue = 0; + password.sizeValue = 0; + +#ifdef USE_TLS + stunGetUserNameAndPassword( dest, username, password ); +#endif + + stunSendTest( myFd, dest, username, password, testNum, verbose ); + + char msg[STUN_MAX_MESSAGE_SIZE]; + int msgLen = STUN_MAX_MESSAGE_SIZE; + + // Wait to receive a packet + resip::FdSet myFdSet; + myFdSet.setRead(myFd); + if (myFdSet.selectMilliSeconds(timeoutMs) < 1) + { + // no packet received or an error occured + return false; + } + + StunAddress4 from; + if (!getMessage(myFd, msg, &msgLen, &from.addr, &from.port, verbose)) + { + closeSocket(myFd); + return false; + } + + StunMessage resp; + memset(&resp, 0, sizeof(StunMessage)); + + if ( verbose ) clog << "Got a response" << endl; + + bool ok = stunParseMessage( msg,msgLen, resp,verbose ); + + if ( verbose ) + { + clog << "\t ok=" << ok << endl; + clog << "\t id=" << resp.msgHdr.id << endl; + clog << "\t mappedAddr=" << resp.mappedAddress.ipv4 << endl; + clog << "\t changedAddr=" << resp.changedAddress.ipv4 << endl; + clog << endl; + } + + if (sAddr) + { + sAddr->port = resp.mappedAddress.ipv4.port; + sAddr->addr = resp.mappedAddress.ipv4.addr; + } + + closeSocket(myFd); + return ok; +} + + +NatType +stunNatType( StunAddress4& dest, + bool verbose, + bool* preservePort, // if set, is return for if NAT preservers ports or not + bool* hairpin, // if set, is the return for if NAT will hairpin packets + int port, // port to use for the test, 0 to choose random port + StunAddress4* sAddr // NIC to use + ) +{ + assert( dest.addr != 0 ); + assert( dest.port != 0 ); + + if ( hairpin ) + { + *hairpin = false; + } + + if ( port == 0 ) + { + port = stunRandomPort(); + } + UInt32 interfaceIp=0; + if (sAddr) + { + interfaceIp = sAddr->addr; + } + resip::Socket myFd1 = openPort(port,interfaceIp,verbose); + resip::Socket myFd2 = openPort(port+1,interfaceIp,verbose); + + if ( ( myFd1 == INVALID_SOCKET) || ( myFd2 == INVALID_SOCKET) ) + { + cerr << "Some problem opening port/interface to send on" << endl; + return StunTypeFailure; + } + + assert( myFd1 != INVALID_SOCKET ); + assert( myFd2 != INVALID_SOCKET ); + + bool respTestI=false; + bool isNat=true; + StunAddress4 testIchangedAddr; + StunAddress4 testImappedAddr; + bool respTestI2=false; + bool mappedIpSame = true; + StunAddress4 testI2mappedAddr; + StunAddress4 testI2dest=dest; + bool respTestII=false; + bool respTestIII=false; + + bool respTestHairpin=false; + bool respTestPreservePort=false; + + memset(&testImappedAddr,0,sizeof(testImappedAddr)); + + StunAtrString username; + StunAtrString password; + + username.sizeValue = 0; + password.sizeValue = 0; + +#ifdef USE_TLS + stunGetUserNameAndPassword( dest, username, password ); +#endif + + int count=0; + while ( count < 7 ) + { + struct timeval tv; + fd_set fdSet; +#ifdef WIN32 + typedef unsigned int FdSetSize; +#else + typedef int FdSetSize; +#endif + FdSetSize fdSetSize; + FD_ZERO(&fdSet); fdSetSize=0; + FD_SET(myFd1,&fdSet); fdSetSize = ((FdSetSize)myFd1+1>fdSetSize) ? (FdSetSize)myFd1+1 : fdSetSize; + FD_SET(myFd2,&fdSet); fdSetSize = ((FdSetSize)myFd2+1>fdSetSize) ? (FdSetSize)myFd2+1 : fdSetSize; + tv.tv_sec=0; + tv.tv_usec=150*1000; // 150 ms + if ( count == 0 ) tv.tv_usec=0; + + int err = select(fdSetSize, &fdSet, NULL, NULL, &tv); + int e = getErrno(); + if ( err == SOCKET_ERROR ) + { + // error occured + cerr << "Error " << e << " " << strerror(e) << " in select" << endl; + return StunTypeFailure; + } + else if ( err == 0 ) + { + // timeout occured + count++; + + if ( !respTestI ) + { + stunSendTest( myFd1, dest, username, password, 1 ,verbose ); + } + + if ( (!respTestI2) && respTestI ) + { + // check the address to send to if valid + if ( ( testI2dest.addr != 0 ) && + ( testI2dest.port != 0 ) ) + { + stunSendTest( myFd1, testI2dest, username, password, 10 ,verbose); + } + } + + if ( !respTestII ) + { + stunSendTest( myFd2, dest, username, password, 2 ,verbose ); + } + + if ( !respTestIII ) + { + stunSendTest( myFd2, dest, username, password, 3 ,verbose ); + } + + if ( respTestI && (!respTestHairpin) ) + { + if ( ( testImappedAddr.addr != 0 ) && + ( testImappedAddr.port != 0 ) ) + { + stunSendTest( myFd1, testImappedAddr, username, password, 11 ,verbose ); + } + } + } + else + { + //if (verbose) clog << "-----------------------------------------" << endl; + assert( err>0 ); + // data is avialbe on some fd + + for ( int i=0; i<2; i++) + { + resip::Socket myFd; + if ( i==0 ) + { + myFd=myFd1; + } + else + { + myFd=myFd2; + } + + if ( myFd!=INVALID_SOCKET ) + { + if ( FD_ISSET(myFd,&fdSet) ) + { + char msg[STUN_MAX_MESSAGE_SIZE]; + int msgLen = sizeof(msg); + + StunAddress4 from; + + getMessage( myFd, + msg, + &msgLen, + &from.addr, + &from.port,verbose ); + + StunMessage resp; + memset(&resp, 0, sizeof(StunMessage)); + + stunParseMessage( msg,msgLen, resp,verbose ); + + if ( verbose ) + { + clog << "Received message of type " << resp.msgHdr.msgType + << " id=" << (int)(resp.msgHdr.id.octet[0]) << endl; + } + + switch( resp.msgHdr.id.octet[0] ) + { + case 1: + { + if ( !respTestI ) + { + + testIchangedAddr.addr = resp.changedAddress.ipv4.addr; + testIchangedAddr.port = resp.changedAddress.ipv4.port; + testImappedAddr.addr = resp.mappedAddress.ipv4.addr; + testImappedAddr.port = resp.mappedAddress.ipv4.port; + + respTestPreservePort = ( testImappedAddr.port == port ); + if ( preservePort ) + { + *preservePort = respTestPreservePort; + } + + testI2dest.addr = resp.changedAddress.ipv4.addr; + + if (sAddr) + { + sAddr->port = testImappedAddr.port; + sAddr->addr = testImappedAddr.addr; + } + + count = 0; + } + respTestI=true; + } + break; + case 2: + { + respTestII=true; + } + break; + case 3: + { + respTestIII=true; + } + break; + case 10: + { + if ( !respTestI2 ) + { + testI2mappedAddr.addr = resp.mappedAddress.ipv4.addr; + testI2mappedAddr.port = resp.mappedAddress.ipv4.port; + + mappedIpSame = false; + if ( (testI2mappedAddr.addr == testImappedAddr.addr ) && + (testI2mappedAddr.port == testImappedAddr.port )) + { + mappedIpSame = true; + } + + + } + respTestI2=true; + } + break; + case 11: + { + + if ( hairpin ) + { + *hairpin = true; + } + respTestHairpin = true; + } + break; + } + } + } + } + } + } + + closeSocket(myFd1); + closeSocket(myFd2); + + // see if we can bind to this address + //cerr << "try binding to " << testImappedAddr << endl; + resip::Socket s = openPort( 0/*use ephemeral*/, testImappedAddr.addr, false ); + if ( s != INVALID_SOCKET ) + { + closeSocket(s); + isNat = false; + //cerr << "binding worked" << endl; + } + else + { + isNat = true; + //cerr << "binding failed" << endl; + } + + if (verbose) + { + clog << "test I = " << respTestI << endl; + clog << "test II = " << respTestII << endl; + clog << "test III = " << respTestIII << endl; + clog << "test I(2) = " << respTestI2 << endl; + clog << "is nat = " << isNat <<endl; + clog << "mapped IP same = " << mappedIpSame << endl; + clog << "hairpin = " << respTestHairpin << endl; + clog << "preserver port = " << respTestPreservePort << endl; + } + +#if 0 + // implement logic flow chart from draft RFC + if ( respTestI ) + { + if ( isNat ) + { + if (respTestII) + { + return StunTypeConeNat; + } + else + { + if ( mappedIpSame ) + { + if ( respTestIII ) + { + return StunTypeRestrictedNat; + } + else + { + return StunTypePortRestrictedNat; + } + } + else + { + return StunTypeSymNat; + } + } + } + else + { + if (respTestII) + { + return StunTypeOpen; + } + else + { + return StunTypeSymFirewall; + } + } + } + else + { + return StunTypeBlocked; + } +#else + if ( respTestI ) // not blocked + { + if ( isNat ) + { + if ( mappedIpSame ) + { + if (respTestII) + { + return StunTypeIndependentFilter; + } + else + { + if ( respTestIII ) + { + return StunTypeDependentFilter; + } + else + { + return StunTypePortDependedFilter; + } + } + } + else // mappedIp is not same + { + return StunTypeDependentMapping; + } + } + else // isNat is false + { + if (respTestII) + { + return StunTypeOpen; + } + else + { + return StunTypeFirewall; + } + } + } + else + { + return StunTypeBlocked; + } +#endif + + return StunTypeUnknown; +} + + +int +stunOpenSocket( StunAddress4& dest, StunAddress4* mapAddr, + int port, StunAddress4* srcAddr, + bool verbose ) +{ + assert( dest.addr != 0 ); + assert( dest.port != 0 ); + assert( mapAddr ); + + if ( port == 0 ) + { + port = stunRandomPort(); + } + unsigned int interfaceIp = 0; + if ( srcAddr ) + { + interfaceIp = srcAddr->addr; + } + + resip::Socket myFd = openPort(port,interfaceIp,verbose); + if (myFd == INVALID_SOCKET) + { + return (int)myFd; + } + + char msg[STUN_MAX_MESSAGE_SIZE]; + int msgLen = sizeof(msg); + + StunAtrString username; + StunAtrString password; + + username.sizeValue = 0; + password.sizeValue = 0; + +#ifdef USE_TLS + stunGetUserNameAndPassword( dest, username, password ); +#endif + + stunSendTest(myFd, dest, username, password, 1, 0/*false*/ ); + + StunAddress4 from; + + getMessage( myFd, msg, &msgLen, &from.addr, &from.port,verbose ); + + StunMessage resp; + memset(&resp, 0, sizeof(StunMessage)); + + bool ok = stunParseMessage( msg, msgLen, resp,verbose ); + if (!ok) + { + return -1; + } + + StunAddress4 mappedAddr = resp.mappedAddress.ipv4; + StunAddress4 changedAddr = resp.changedAddress.ipv4; + + //clog << "--- stunOpenSocket --- " << endl; + //clog << "\treq id=" << req.id << endl; + //clog << "\tresp id=" << id << endl; + //clog << "\tmappedAddr=" << mappedAddr << endl; + + *mapAddr = mappedAddr; + + return (int)myFd; +} + + +bool +stunOpenSocketPair( StunAddress4& dest, StunAddress4* mapAddr, + int* fd1, int* fd2, + int port, StunAddress4* srcAddr, + bool verbose ) +{ + assert( dest.addr!= 0 ); + assert( dest.port != 0 ); + assert( mapAddr ); + + const int NUM=3; + + if ( port == 0 ) + { + port = stunRandomPort(); + } + + *fd1=-1; + *fd2=-1; + + char msg[STUN_MAX_MESSAGE_SIZE]; + int msgLen =sizeof(msg); + + StunAddress4 from; + int fd[NUM]; + int i; + + unsigned int interfaceIp = 0; + if ( srcAddr ) + { + interfaceIp = srcAddr->addr; + } + + for( i=0; i<NUM; i++) + { + fd[i] = (int)openPort( (port == 0) ? 0 : (port + i), + interfaceIp, verbose); + if (fd[i] < 0) + { + while (i > 0) + { + closeSocket(fd[--i]); + } + return false; + } + } + + StunAtrString username; + StunAtrString password; + + username.sizeValue = 0; + password.sizeValue = 0; + +#ifdef USE_TLS + stunGetUserNameAndPassword( dest, username, password ); +#endif + + for( i=0; i<NUM; i++) + { + stunSendTest(fd[i], dest, username, password, 1/*testNum*/, verbose ); + } + + StunAddress4 mappedAddr[NUM]; + for( i=0; i<NUM; i++) + { + msgLen = sizeof(msg)/sizeof(*msg); + getMessage( fd[i], + msg, + &msgLen, + &from.addr, + &from.port ,verbose); + + StunMessage resp; + memset(&resp, 0, sizeof(StunMessage)); + + bool ok = stunParseMessage( msg, msgLen, resp, verbose ); + if (!ok) + { + return false; + } + + mappedAddr[i] = resp.mappedAddress.ipv4; + StunAddress4 changedAddr = resp.changedAddress.ipv4; + } + + if (verbose) + { + clog << "--- stunOpenSocketPair --- " << endl; + for( i=0; i<NUM; i++) + { + clog << "\t mappedAddr=" << mappedAddr[i] << endl; + } + } + + if ( mappedAddr[0].port %2 == 0 ) + { + if ( mappedAddr[0].port+1 == mappedAddr[1].port ) + { + *mapAddr = mappedAddr[0]; + *fd1 = fd[0]; + *fd2 = fd[1]; + closeSocket( fd[2] ); + return true; + } + } + else + { + if (( mappedAddr[1].port %2 == 0 ) + && ( mappedAddr[1].port+1 == mappedAddr[2].port )) + { + *mapAddr = mappedAddr[1]; + *fd1 = fd[1]; + *fd2 = fd[2]; + closeSocket( fd[0] ); + return true; + } + } + + // something failed, close all and return error + for( i=0; i<NUM; i++) + { + closeSocket( fd[i] ); + } + + return false; +} + +bool +operator<(const UInt128& lhs, const UInt128& rhs) +{ + return memcmp(&lhs, &rhs, sizeof(lhs)) < 0; +} + +bool operator==(const UInt128& lhs, const UInt128& rhs) +{ + return memcmp(&lhs, &rhs, sizeof(lhs)) == 0; +} + +bool +operator<(const StunMsgHdr& lhs, const StunMsgHdr& rhs) +{ + return lhs.id < rhs.id; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + */ + +// Local Variables: +// mode:c++ +// c-file-style:"ellemtel" +// c-file-offsets:((case-label . +)) +// indent-tabs-mode:nil +// End: + + diff --git a/src/libs/resiprocate/rutil/stun/Stun.hxx b/src/libs/resiprocate/rutil/stun/Stun.hxx new file mode 100644 index 00000000..3a662e15 --- /dev/null +++ b/src/libs/resiprocate/rutil/stun/Stun.hxx @@ -0,0 +1,461 @@ +#ifndef STUN_HXX +#define STUN_HXX + +#include <iostream> +#include <time.h> +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" + +// if you change this version, change in makefile too +#define STUN_VERSION "0.96" + +#define STUN_MAX_STRING 256 +#define STUN_MAX_UNKNOWN_ATTRIBUTES 8 +#define STUN_MAX_MESSAGE_SIZE 2048 + +#define STUN_PORT 3478 + +#ifndef RESIP_COMPAT_HXX +// define some basic types +typedef unsigned char UInt8; +typedef unsigned short UInt16; +#ifdef __APPLE__ +typedef unsigned long UInt32; +#else +typedef unsigned int UInt32; +#endif +#if defined( WIN32 ) +typedef unsigned __int64 UInt64; +#else +typedef unsigned long long UInt64; +#endif +#endif + +typedef struct { unsigned char octet[16]; } UInt128; + +#ifdef __cplusplus +bool operator<(const UInt128&, const UInt128&); +bool operator==(const UInt128&, const UInt128&); +#endif + +/// define a structure to hold a stun address +const UInt8 IPv4Family = 0x01; +const UInt8 IPv6Family = 0x02; + +// define flags +const UInt32 ChangeIpFlag = 0x04; +const UInt32 ChangePortFlag = 0x02; + +// define stun attribute +const UInt16 MappedAddress = 0x0001; +const UInt16 ResponseAddress = 0x0002; +const UInt16 ChangeRequest = 0x0003; +const UInt16 SourceAddress = 0x0004; +const UInt16 ChangedAddress = 0x0005; +const UInt16 Username = 0x0006; +const UInt16 Password = 0x0007; +const UInt16 MessageIntegrity = 0x0008; +const UInt16 ErrorCode = 0x0009; +const UInt16 UnknownAttribute = 0x000A; +const UInt16 ReflectedFrom = 0x000B; +const UInt16 XorMappedAddress = 0x8020; +const UInt16 XorOnly = 0x0021; +const UInt16 ServerName = 0x8022; +const UInt16 SecondaryAddress = 0x8050; // Non standard extention + +// !jf! TURN specific message attributes - from turn-08 +const UInt16 TurnLifetime = 0x000d; +const UInt16 TurnAlternateServer = 0x000e; +const UInt16 TurnMagicCookie = 0x000f; +const UInt16 TurnBandwidth = 0x0010; +const UInt16 TurnDestinationAddress = 0x0011; +const UInt16 TurnRemoteAddress = 0x0012; +const UInt16 TurnData = 0x0013; +const UInt16 TurnNonce = 0x0014; +const UInt16 TurnRealm = 0x0015; + + +// define types for a stun message +const UInt16 BindRequestMsg = 0x0001; +const UInt16 BindResponseMsg = 0x0101; +const UInt16 BindErrorResponseMsg = 0x0111; +const UInt16 SharedSecretRequestMsg = 0x0002; +const UInt16 SharedSecretResponseMsg = 0x0102; +const UInt16 SharedSecretErrorResponseMsg = 0x0112; + +// define types for a turn message - per turn-08 +const UInt16 TurnAllocateRequest = 0x0003; +const UInt16 TurnAllocateResponse = 0x0103; +const UInt16 TurnAllocateErrorResponse = 0x0113; +const UInt16 TurnSendRequest = 0x0004; +const UInt16 TurnSendResponse = 0x0104; +const UInt16 TurnSendErrorResponse = 0x0114; +const UInt16 TurnDataIndication = 0x0115; +const UInt16 TurnSetActiveDestinationRequest = 0x0006; +const UInt16 TurnSetActiveDestinationResponse = 0x0106; +const UInt16 TurnSetActiveDestinationErrorResponse = 0x0116; + +typedef struct +{ + UInt16 msgType; + UInt16 msgLength; + UInt128 id; +} StunMsgHdr; + +#ifdef __cplusplus +bool operator<(const StunMsgHdr&, const StunMsgHdr&); +#endif + +typedef struct +{ + UInt16 type; + UInt16 length; +} StunAtrHdr; + +typedef struct +{ + UInt16 port; + UInt32 addr; +} StunAddress4; + +typedef struct +{ + UInt8 pad; + UInt8 family; + StunAddress4 ipv4; +} StunAtrAddress4; + +typedef struct +{ + UInt32 value; +} StunAtrChangeRequest; + +typedef struct +{ + UInt16 pad; // all 0 + UInt8 errorClass; + UInt8 number; + char reason[STUN_MAX_STRING]; + UInt16 sizeReason; +} StunAtrError; + +typedef struct +{ + UInt16 attrType[STUN_MAX_UNKNOWN_ATTRIBUTES]; + UInt16 numAttributes; +} StunAtrUnknown; + +typedef struct +{ + char value[STUN_MAX_STRING]; + UInt16 sizeValue; +} StunAtrString; + +typedef struct +{ + char hash[20]; +} StunAtrIntegrity; + + +enum StunHmacStatus +{ + HmacUnknown=0, + HmacOK, + HmacBadUserName, + HmacUnknownUserName, + HmacFailed +}; + + +typedef struct +{ + StunMsgHdr msgHdr; + + bool hasMappedAddress; + StunAtrAddress4 mappedAddress; + + bool hasResponseAddress; + StunAtrAddress4 responseAddress; + + bool hasChangeRequest; + StunAtrChangeRequest changeRequest; + + bool hasSourceAddress; + StunAtrAddress4 sourceAddress; + + bool hasChangedAddress; + StunAtrAddress4 changedAddress; + + bool hasUsername; + StunAtrString username; + + bool hasPassword; + StunAtrString password; + + bool hasMessageIntegrity; + StunAtrIntegrity messageIntegrity; + + bool hasErrorCode; + StunAtrError errorCode; + + bool hasUnknownAttributes; + StunAtrUnknown unknownAttributes; + + bool hasReflectedFrom; + StunAtrAddress4 reflectedFrom; + + bool hasXorMappedAddress; + StunAtrAddress4 xorMappedAddress; + + bool xorOnly; + + bool hasServerName; + StunAtrString serverName; + + bool hasSecondaryAddress; + StunAtrAddress4 secondaryAddress; + + bool hasTurnLifetime; + UInt32 turnLifetime; + + bool hasTurnAlternateServer; + StunAtrAddress4 turnAlternateServer; + + bool hasTurnMagicCookie; + UInt32 turnMagicCookie; + + bool hasTurnBandwidth; + UInt32 turnBandwidth; + + bool hasTurnDestinationAddress; + StunAtrAddress4 turnDestinationAddress; + + bool hasTurnRemoteAddress; + StunAtrAddress4 turnRemoteAddress; + + bool hasTurnData; + resip::Data* turnData; + + //bool hasTurnNonce; + // turnNonce; + + //bool hasTurnRealm; + // turnRealm; +} StunMessage; + + +// Define enum with different types of NAT +enum NatType +{ + StunTypeUnknown=0, + StunTypeFailure, + StunTypeOpen, + StunTypeBlocked, + + StunTypeIndependentFilter, + StunTypeDependentFilter, + StunTypePortDependedFilter, + StunTypeDependentMapping, + + //StunTypeConeNat, + //StunTypeRestrictedNat, + //StunTypePortRestrictedNat, + //StunTypeSymNat, + + StunTypeFirewall +}; + + +#define MAX_MEDIA_RELAYS 500 +#define MAX_RTP_MSG_SIZE 1500 +#define MEDIA_RELAY_TIMEOUT 3*60 + +typedef struct +{ + int relayPort; // media relay port + int fd; // media relay file descriptor + StunAddress4 destination; // NAT IP:port + time_t expireTime; // if no activity after time, close the socket +} StunMediaRelay; + +typedef struct +{ + StunAddress4 myAddr; + StunAddress4 altAddr; + resip::Socket myFd; + resip::Socket altPortFd; + resip::Socket altIpFd; + resip::Socket altIpPortFd; + bool relay; // true if media relaying is to be done + StunMediaRelay relays[MAX_MEDIA_RELAYS]; +} StunServerInfo; + +bool +stunParseMessage( char* buf, + unsigned int bufLen, + StunMessage& message, + bool verbose ); + +void +stunBuildReqSimple( StunMessage* msg, + const StunAtrString& username, + bool changePort, bool changeIp, unsigned int id=0 ); + +unsigned int +stunEncodeMessage( const StunMessage& message, + char* buf, + unsigned int bufLen, + const StunAtrString& password, + bool verbose); + +void +stunCreateUserName(const StunAddress4& addr, StunAtrString* username); + +void +stunGetUserNameAndPassword( const StunAddress4& dest, + StunAtrString* username, + StunAtrString* password); + +void +stunCreatePassword(const StunAtrString& username, StunAtrString* password); + +int +stunRand(); + +UInt64 +stunGetSystemTimeSecs(); + +/// find the IP address of a the specified stun server - return false is fails parse +bool +stunParseServerName( char* serverName, StunAddress4& stunServerAddr); + +bool +stunParseHostName( char* peerName, + UInt32& ip, + UInt16& portVal, + UInt16 defaultPort ); + +/// return true if all is OK +/// Create a media relay and do the STERN thing if startMediaPort is non-zero +bool +stunInitServer(StunServerInfo& info, + const StunAddress4& myAddr, + const StunAddress4& altAddr, + int startMediaPort, + bool verbose); + +void +stunStopServer(StunServerInfo& info); + +/// return true if all is OK +bool +stunServerProcess(StunServerInfo& info, bool verbose); + +/// returns number of address found - take array or addres +int +stunFindLocalInterfaces(UInt32* addresses, int maxSize ); + +bool +stunTest( StunAddress4& dest, int testNum, bool verbose, StunAddress4* srcAddr=0, unsigned long timeoutMs=5000 ); + +NatType +stunNatType( StunAddress4& dest, bool verbose, + bool* preservePort=0, // if set, is return for if NAT preservers ports or not + bool* hairpin=0 , // if set, is the return for if NAT will hairpin packets + int port=0, // port to use for the test, 0 to choose random port + StunAddress4* sAddr=0 // NIC to use + ); + +/// prints a StunAddress +std::ostream& +operator<<( std::ostream& strm, const StunAddress4& addr); + +std::ostream& +operator<< ( std::ostream& strm, const UInt128& ); + +std::ostream& +operator<< ( std::ostream& strm, const StunMsgHdr& ); + +bool +stunServerProcessMsg( char* buf, + unsigned int bufLen, + StunAddress4& from, + StunAddress4& secondary, + StunAddress4& myAddr, + StunAddress4& altAddr, + StunMessage* resp, + StunAddress4* destination, + StunAtrString* hmacPassword, + bool* changePort, + bool* changeIp, + bool verbose); + +int +stunOpenSocket( StunAddress4& dest, + StunAddress4* mappedAddr, + int port=0, + StunAddress4* srcAddr=0, + bool verbose=false ); + +bool +stunOpenSocketPair( StunAddress4& dest, StunAddress4* mappedAddr, + int* fd1, int* fd2, + int srcPort=0, StunAddress4* srcAddr=0, + bool verbose=false); + +int +stunRandomPort(); + +void computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey); + +#endif + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + */ + +// Local Variables: +// mode:c++ +// c-file-style:"ellemtel" +// c-file-offsets:((case-label . +)) +// indent-tabs-mode:nil +// End: + diff --git a/src/libs/resiprocate/rutil/stun/Udp.cxx b/src/libs/resiprocate/rutil/stun/Udp.cxx new file mode 100644 index 00000000..e1356e0a --- /dev/null +++ b/src/libs/resiprocate/rutil/stun/Udp.cxx @@ -0,0 +1,306 @@ +#include <cassert> +#include <cstdio> +#include <cstring> +#include <errno.h> +#include <iostream> +#include <cstdlib> +#include <time.h> + +#ifdef WIN32 + +#include <winsock2.h> +#include <stdlib.h> +#include <io.h> + +#else + +#include <arpa/inet.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <netdb.h> +#include <string.h> +#include <unistd.h> + +#endif + +#include <string.h> + +#include "rutil/stun/Udp.hxx" + +using namespace std; +using namespace resip; + +resip::Socket +openPort( unsigned short port, unsigned int interfaceIp, bool verbose ) +{ + resip::Socket fd; + + fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if ( fd == INVALID_SOCKET ) + { + int err = getErrno(); + cerr << "Could not create a UDP socket:" << err << endl; + return INVALID_SOCKET; + } + + struct sockaddr_in addr; + memset((char*) &(addr),0, sizeof((addr))); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(port); + + if ( (interfaceIp != 0) && + ( interfaceIp != 0x100007f ) ) + { + addr.sin_addr.s_addr = htonl(interfaceIp); + if (verbose ) + { + clog << "Binding to interface " + << hex << "0x" << htonl(interfaceIp) << dec << endl; + } + } + + if ( ::bind( fd,(struct sockaddr*)&addr, sizeof(addr)) != 0 ) + { + int e = getErrno(); + + switch (e) + { + case 0: + { + cerr << "Could not bind socket" << endl; + closeSocket(fd); + return INVALID_SOCKET; + } + case EADDRINUSE: + { + cerr << "Port " << port << " for receiving UDP is in use" << endl; + closeSocket(fd); + return INVALID_SOCKET; + } + break; + case EADDRNOTAVAIL: + { + if ( verbose ) + { + cerr << "Cannot assign requested address" << endl; + } + closeSocket(fd); + return INVALID_SOCKET; + } + break; + default: + { + cerr << "Could not bind UDP receive port" + << "Error=" << e << " " << strerror(e) << endl; + closeSocket(fd); + return INVALID_SOCKET; + } + break; + } + } + if ( verbose ) + { + clog << "Opened port " << port << " with fd " << fd << endl; + } + + assert( fd != INVALID_SOCKET ); + + return fd; +} + + +bool +getMessage( resip::Socket fd, char* buf, int* len, + UInt32* srcIp, unsigned short* srcPort, + bool verbose) +{ + assert( fd != INVALID_SOCKET ); + + int originalSize = *len; + assert( originalSize > 0 ); + + struct sockaddr_in from; + int fromLen = sizeof(from); + + *len = recvfrom(fd, + buf, + originalSize, + 0, + (struct sockaddr *)&from, + (socklen_t*)&fromLen); + + if ( *len == SOCKET_ERROR ) + { + int err = getErrno(); + + switch (err) + { + case ENOTSOCK: + cerr << "Error fd not a socket" << endl; + break; + case ECONNRESET: + cerr << "Error connection reset - host not reachable" << endl; + break; + + default: + cerr << "Socket Error=" << err << endl; + } + + return false; + } + + if ( *len < 0 ) + { + clog << "socket closed? negative len" << endl; + return false; + } + + if ( *len == 0 ) + { + clog << "socket closed? zero len" << endl; + return false; + } + + *srcPort = ntohs(from.sin_port); + *srcIp = ntohl(from.sin_addr.s_addr); + + if ( (*len)+1 >= originalSize ) + { + if (verbose) + { + clog << "Received a message that was too large" << endl; + } + return false; + } + buf[*len]=0; + + return true; +} + + +bool +sendMessage( resip::Socket fd, char* buf, int l, + unsigned int dstIp, unsigned short dstPort, + bool verbose) +{ + assert( fd != INVALID_SOCKET ); + + int s; + if ( dstPort == 0 ) + { + // sending on a connected port + assert( dstIp == 0 ); + + s = send(fd,buf,l,0); + } + else + { + assert( dstIp != 0 ); + assert( dstPort != 0 ); + + struct sockaddr_in to; + int toLen = sizeof(to); + memset(&to,0,toLen); + + to.sin_family = AF_INET; + to.sin_port = htons(dstPort); + to.sin_addr.s_addr = htonl(dstIp); + + s = sendto(fd, buf, l, 0,(sockaddr*)&to, toLen); + } + + if ( s == SOCKET_ERROR ) + { + int e = getErrno(); + switch (e) + { + case ECONNREFUSED: + case EHOSTDOWN: + case EHOSTUNREACH: + { + // quietly ignore this + } + break; + case EAFNOSUPPORT: + { + cerr << "err EAFNOSUPPORT in send" << endl; + } + break; + default: + { + cerr << "err " << e << " " << strerror(e) << " in send" << endl; + } + } + return false; + } + + if ( s == 0 ) + { + cerr << "no data sent in send" << endl; + return false; + } + + if ( s != l ) + { + if (verbose) + { + cerr << "only " << s << " out of " << l << " bytes sent" << endl; + } + return false; + } + + return true; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + */ + +// Local Variables: +// mode:c++ +// c-file-style:"ellemtel" +// c-file-offsets:((case-label . +)) +// indent-tabs-mode:nil +// End: diff --git a/src/libs/resiprocate/rutil/stun/Udp.hxx b/src/libs/resiprocate/rutil/stun/Udp.hxx new file mode 100644 index 00000000..5ef6efa7 --- /dev/null +++ b/src/libs/resiprocate/rutil/stun/Udp.hxx @@ -0,0 +1,87 @@ +#ifndef UDP_HXX +#define UDP_HXX + + +#ifdef __MACH__ +# ifdef __APPLE__ +# include <sys/socket.h> +# if !defined(_BSD_SOCKLEN_T_) && !defined(_SOCKLEN_T) + typedef int socklen_t; +# endif +# else + typedef int socklen_t; +# endif +#endif + +#include "rutil/Socket.hxx" + +/// Open a UDP socket to receive on the given port - if port is 0, pick a a +/// port, if interfaceIp!=0 then use ONLY the interface specified instead of +/// all of them +resip::Socket +openPort( unsigned short port, unsigned int interfaceIp, + bool verbose); + + +/// recive a UDP message +bool +getMessage( resip::Socket fd, char* buf, int* len, + UInt32* srcIp, unsigned short* srcPort, + bool verbose); + + +/// send a UDP message +bool +sendMessage( resip::Socket fd, char* msg, int len, + unsigned int dstIp, unsigned short dstPort, + bool verbose); + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + */ + +// Local Variables: +// mode:c++ +// c-file-style:"ellemtel" +// c-file-offsets:((case-label . +)) +// indent-tabs-mode:nil +// End: + +#endif diff --git a/src/libs/resiprocate/rutil/vmd5.cxx b/src/libs/resiprocate/rutil/vmd5.cxx new file mode 100644 index 00000000..b95de654 --- /dev/null +++ b/src/libs/resiprocate/rutil/vmd5.cxx @@ -0,0 +1,301 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + * + * Changed so as no longer to depend on Colin Plumb's `usual.h' header + * definitions; now uses stuff from dpkg's config.h. + * - Ian Jackson <ijackson@nyx.cs.du.edu>. + * Still in the public domain. + */ + +#include <string.h> /* for memcpy() */ +#include <sys/types.h> /* for stupid systems */ + +#ifndef WIN32 +#include <netinet/in.h> /* for ntohl() */ +#endif + +#include "rutil/vmd5.hxx" + +/* Add _BIG_ENDIAN for Solaris */ +/* Add _BIG_ENDIAN__ for MAC OSX */ +#if defined(WORDS_BIGENDIAN) || defined(_BIG_ENDIAN) || defined( __BIG_ENDIAN__ ) +void +resip::byteSwap(u_int32_t *buf, unsigned words) +{ + md5byte *p = (md5byte *)buf; + + do + { + *buf++ = (u_int32_t)((unsigned)p[3] << 8 | p[2]) << 16 | + ((unsigned)p[1] << 8 | p[0]); + p += 4; + } + while (--words); +} +#else +#define byteSwap(buf,words) +#endif + + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void +resip::MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bytes[0] = 0; + ctx->bytes[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void +resip::MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) +{ + u_int32_t t; + + /* Update byte count */ + + t = ctx->bytes[0]; + if ((ctx->bytes[0] = t + len) < t) + ctx->bytes[1]++; /* Carry from low to high */ + + t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ + if (t > len) + { + memcpy((md5byte *)ctx->in + 64 - t, buf, len); + return ; + } + /* First chunk is an odd size */ + memcpy((md5byte *)ctx->in + 64 - t, buf, t); + byteSwap(ctx->in, 16); + MD5Transform(ctx->buf, ctx->in); + buf += t; + len -= t; + + /* Process data in 64-byte chunks */ + while (len >= 64) + { + memcpy(ctx->in, buf, 64); + byteSwap(ctx->in, 16); + MD5Transform(ctx->buf, ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void +resip::MD5Final(md5byte digest[16], struct MD5Context *ctx) +{ + int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ + md5byte *p = (md5byte *)ctx->in + count; + + /* Set the first char of padding to 0x80. There is always room. */ + *p++ = 0x80; + + /* Bytes of padding needed to make 56 bytes (-8..55) */ + count = 56 - 1 - count; + + if (count < 0) + { /* Padding forces an extra block */ + memset(p, 0, count + 8); + byteSwap(ctx->in, 16); + MD5Transform(ctx->buf, ctx->in); + p = (md5byte *)ctx->in; + count = 56; + } + memset(p, 0, count); + byteSwap(ctx->in, 14); + + /* Append length in bits and transform */ + ctx->in[14] = ctx->bytes[0] << 3; + ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; + MD5Transform(ctx->buf, ctx->in); + + byteSwap(ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ +} + +#ifndef ASM_MD5 + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f,w,x,y,z,in,s) \ +(w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void +resip::MD5Transform(u_int32_t buf[4], u_int32_t const in[16]) +{ + register u_int32_t a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/vmd5.hxx b/src/libs/resiprocate/rutil/vmd5.hxx new file mode 100644 index 00000000..ddfaef0e --- /dev/null +++ b/src/libs/resiprocate/rutil/vmd5.hxx @@ -0,0 +1,98 @@ +#if !defined(RESIP_VMD5_HXX) +#define RESIP_VMD5_HXX + +/* + * This is the header file for the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + * + * Changed so as no longer to depend on Colin Plumb's `usual.h' + * header definitions; now uses stuff from dpkg's config.h + * - Ian Jackson <ijackson@nyx.cs.du.edu>. + * Still in the public domain. + */ + +#include "rutil/compat.hxx" + +namespace resip +{ + +typedef unsigned char md5byte; + +struct MD5Context +{ + u_int32_t buf[4]; + u_int32_t bytes[2]; + u_int32_t in[16]; +}; + +void MD5Init(struct MD5Context *context); +void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len); +void MD5Final(unsigned char digest[16], struct MD5Context *context); +void MD5Transform(u_int32_t buf[4], u_int32_t const in[16]); +void byteSwap(u_int32_t *buf, unsigned words); +} + +/* !MD5_H */ +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/vthread.hxx b/src/libs/resiprocate/rutil/vthread.hxx new file mode 100644 index 00000000..7bbc8505 --- /dev/null +++ b/src/libs/resiprocate/rutil/vthread.hxx @@ -0,0 +1,106 @@ +#if !defined(RESIP_VTHREAD_HXX) +#define RESIP_VTHREAD_HXX + +#ifdef WIN32 +#error this should not be used in win32 +#endif + +#include <pthread.h> + + +typedef pthread_t vthread_t; +typedef pthread_mutex_t vmutex_t; +typedef pthread_cond_t vcondition_t; +typedef pthread_attr_t vthread_attr_t; + + +#define vmutex_init(mutex) \ + pthread_mutex_init((mutex),0) + + +#define vmutex_destroy(mutex) \ + pthread_mutex_destroy((mutex)) + + +#define vmutex_lock(mutex) \ + pthread_mutex_lock((mutex)) + + +#define vmutex_unlock(mutex) \ + pthread_mutex_unlock((mutex)) + + +#define vcond_init(cond) \ + pthread_cond_init((cond),0) + + +#define vcond_destroy(cond) \ + pthread_cond_destroy((cond)) + + +#define vcond_wait(cond, mutex) \ + pthread_cond_wait((cond),(mutex)) + + +#define vcond_timedwait(cond, mutex, timeout) \ + pthread_cond_timedwait((cond),(mutex),(timeout)) + + +#define vcond_signal(cond) \ + pthread_cond_signal((cond)) + + +#define vcond_broadcast(cond) \ + pthread_cond_broadcast((cond)) + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * <http://www.vovida.org/>. + * + */ diff --git a/src/libs/resiprocate/rutil/wince/WceCompat.cxx b/src/libs/resiprocate/rutil/wince/WceCompat.cxx new file mode 100644 index 00000000..2196053d --- /dev/null +++ b/src/libs/resiprocate/rutil/wince/WceCompat.cxx @@ -0,0 +1,108 @@ + +#include <windows.h> +#include "WceCompat.hxx" + +extern "C" int errno=0; + +static char* messages[] = { +/*0 */ "No error", +/*EPERM */ "Operation not permitted", +/*ENOENT */ "No such file or directory", +/*ESRCH */ "No such process", +/*EINTR */ "Interrupted system call", +/*EIO */ "I/O error", +/*ENXIO */ "No such device or address", +/*E2BIG */ "Arg list too long", +/*ENOEXEC */ "Exec format error", +/*EBADF */ "Bad file descriptor", +/*ECHILD */ "No child processes", +/*EAGAIN */ "Resource temporarily unavailable", +/*ENOMEM */ "Not enough memory", +/*EACCES */ "Permission denied", +/*EFAULT */ "Bad address", +/*15 */ "Unknown error", // ENOTBLK "Block device required" +/*EBUSY */ "Device or resource busy", +/*EEXIST */ "File exists", +/*EXDEV */ "Improper link", // "Cross-device link" +/*ENODEV */ "No such device", +/*ENOTDIR */ "Not a directory", +/*EISDIR */ "Is a directory", +/*EINVAL */ "Invalid argument", +/*ENFILE */ "Too many open files in system", +/*EMFILE */ "Too many open files", +/*ENOTTY */ "Inappropriate I/O control operation", // "Not a character device" +/*26 */ "Unknown error", // ETXTBSY "Text file busy" +/*EFBIG */ "File too large", +/*ENOSPC */ "No space left on device", +/*ESPIPE */ "Invalid seek", // "Illegal seek" +/*EROFS */ "Read-only file system", +/*EMLINK */ "Too many links", +/*EPIPE */ "Broken pipe", +/*EDOM */ "Domain error", // "Math arg out of domain of func" +/*ERANGE */ "Result too large", // "Math result out of range" +/*35 */ "Unknown error", // ENOMSG "No message of desired type" +/*EDEADLK */ "Resource deadlock avoided", // EIDRM "Identifier removed" +/*37 */ "Unknown error", // ECHRNG "Channel number out of range" +/*ENAMETOOLONG*/ "Filename too long", +/*ENOLCK */ "No locks available", +/*ENOSYS */ "Function not implemented", +/*ENOTEMPTY */ "Directory not empty", +/*EILSEQ */ "Illegal byte sequence" +}; +static const int NUM_MESSAGES = sizeof(messages)/sizeof(messages[0]); + +extern "C" char* __cdecl strerror(int errnum) +{ + if (errnum < NUM_MESSAGES) + return messages[errnum]; + return "Unknown error"; +} + +//.dcm. wincece lacks this function(actually no time.h)--could port from BSD +// size_t __cdecl strftime ( +// char *string, +// size_t maxsize, +// const char *format, +// const struct tm *timeptr +// ) +// { +// return (_Strftime(string, maxsize, format, timeptr, 0)); +// } + +namespace resip +{ +// ******************************************************************************* + +wchar_t* ToWString(const char *str) +{ + if (!str) return 0; + + int dCharacters = MultiByteToWideChar( CP_UTF8, 0, str,strlen(str)+1, 0,0); + wchar_t *wszStr = new wchar_t[dCharacters+1]; + MultiByteToWideChar( CP_UTF8, 0, str,-1, wszStr,dCharacters); + return wszStr; +}; + +char* FromWString(const wchar_t *wstr) +{ + if (!wstr) return 0; + + int dCharacters = WideCharToMultiByte( CP_UTF8, 0, wstr,lstrlen(wstr)+1, 0,0,0,0 ); + char *str = new char[dCharacters +1]; + WideCharToMultiByte( CP_UTF8, 0, wstr,-1, str,dCharacters ,0,0 ); + return str; +}; + +void FreeWString(wchar_t* wstr) +{ + if (wstr) + delete wstr; +} + +void FreeString(char* str) +{ + if (str) + delete str; +} + +} diff --git a/src/libs/resiprocate/rutil/wince/WceCompat.hxx b/src/libs/resiprocate/rutil/wince/WceCompat.hxx new file mode 100644 index 00000000..9f6db1f6 --- /dev/null +++ b/src/libs/resiprocate/rutil/wince/WceCompat.hxx @@ -0,0 +1,17 @@ +#ifndef __WCECOMPAT_H +#define __WCECOMPAT_H + +#ifdef UNDER_CE + +#include <cassert> +namespace resip +{ +wchar_t* ToWString(const char *str); +void FreeWString(wchar_t* wstr); + + +} // namespace resip + +#endif UNDER_CE + +#endif __WCECOMPAT_H diff --git a/src/libs/resiprocate/rutil/wince/cerrno b/src/libs/resiprocate/rutil/wince/cerrno new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/resiprocate/rutil/wince/errno.h b/src/libs/resiprocate/rutil/wince/errno.h new file mode 100644 index 00000000..099e0bb4 --- /dev/null +++ b/src/libs/resiprocate/rutil/wince/errno.h @@ -0,0 +1,57 @@ +// #include "../WceCompat.hxx" + +#ifdef __cplusplus +extern "C" int errno; +extern "C" char * __cdecl strerror(int errnum ); +#else +int errno; +char * __cdecl strerror(int errnum ); +#endif + +#define strnicmp(dest,src,size_t) _strnicmp(dest,src,size_t) +#define stricmp(dest,src) _stricmp(dest,src) +#define strdup _strdup + +#if !defined(TLS_OUT_OF_INDEXES) +#define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) +#endif + +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define EINVAL 22 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define ERANGE 34 +#define EDEADLK 36 +#define ENAMETOOLONG 38 +#define ENOLCK 39 +#define ENOSYS 40 +#define ENOTEMPTY 41 +#define EILSEQ 42 + diff --git a/src/libs/resiprocate/rutil/wince/fcntl.h b/src/libs/resiprocate/rutil/wince/fcntl.h new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/resiprocate/rutil/wince/io.h b/src/libs/resiprocate/rutil/wince/io.h new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/resiprocate/rutil/wince/sys/types.h b/src/libs/resiprocate/rutil/wince/sys/types.h new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/resiprocate/rutil/wince/windns.h b/src/libs/resiprocate/rutil/wince/windns.h new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/speex/include/speex/Makefile.am b/src/libs/speex/include/speex/Makefile.am new file mode 100644 index 00000000..2ae34f9f --- /dev/null +++ b/src/libs/speex/include/speex/Makefile.am @@ -0,0 +1,9 @@ +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +nodist_pkginclude_HEADERS = speex_config_types.h + +pkginclude_HEADERS = speex.h speex_bits.h speex_buffer.h speex_callbacks.h \ + speex_echo.h speex_header.h speex_jitter.h speex_preprocess.h speex_resampler.h \ + speex_stereo.h speex_types.h + diff --git a/src/libs/speex/include/speex/Makefile.in b/src/libs/speex/include/speex/Makefile.in new file mode 100644 index 00000000..9c0a33d0 --- /dev/null +++ b/src/libs/speex/include/speex/Makefile.in @@ -0,0 +1,440 @@ +# Makefile.in generated by automake 1.8.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +subdir = include/speex +DIST_COMMON = $(pkginclude_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/speex_config_types.h.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(mkdir_p) +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = speex_config_types.h +SOURCES = +DIST_SOURCES = +am__installdirs = "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)" +nodist_pkgincludeHEADERS_INSTALL = $(INSTALL_HEADER) +pkgincludeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(nodist_pkginclude_HEADERS) $(pkginclude_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_KISS_FFT_FALSE = @BUILD_KISS_FFT_FALSE@ +BUILD_KISS_FFT_TRUE = @BUILD_KISS_FFT_TRUE@ +BUILD_SMALLFT_FALSE = @BUILD_SMALLFT_FALSE@ +BUILD_SMALLFT_TRUE = @BUILD_SMALLFT_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FFT_CFLAGS = @FFT_CFLAGS@ +FFT_LIBS = @FFT_LIBS@ +FFT_PKGCONFIG = @FFT_PKGCONFIG@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIZE16 = @SIZE16@ +SIZE32 = @SIZE32@ +SPEEX_LT_AGE = @SPEEX_LT_AGE@ +SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ +SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ +SPEEX_VERSION = @SPEEX_VERSION@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +src = @src@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +nodist_pkginclude_HEADERS = speex_config_types.h +pkginclude_HEADERS = speex.h speex_bits.h speex_buffer.h speex_callbacks.h \ + speex_echo.h speex_header.h speex_jitter.h speex_preprocess.h speex_resampler.h \ + speex_stereo.h speex_types.h + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/speex/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu include/speex/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +speex_config_types.h: $(top_builddir)/config.status $(srcdir)/speex_config_types.h.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +install-nodist_pkgincludeHEADERS: $(nodist_pkginclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(pkgincludedir)" || $(mkdir_p) "$(DESTDIR)$(pkgincludedir)" + @list='$(nodist_pkginclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(nodist_pkgincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgincludedir)/$$f'"; \ + $(nodist_pkgincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgincludedir)/$$f"; \ + done + +uninstall-nodist_pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nodist_pkginclude_HEADERS)'; for p in $$list; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f '$(DESTDIR)$(pkgincludedir)/$$f'"; \ + rm -f "$(DESTDIR)$(pkgincludedir)/$$f"; \ + done +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(pkgincludedir)" || $(mkdir_p) "$(DESTDIR)$(pkgincludedir)" + @list='$(pkginclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(pkgincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgincludedir)/$$f'"; \ + $(pkgincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgincludedir)/$$f"; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; for p in $$list; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f '$(DESTDIR)$(pkgincludedir)/$$f'"; \ + rm -f "$(DESTDIR)$(pkgincludedir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-nodist_pkgincludeHEADERS \ + install-pkgincludeHEADERS + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-nodist_pkgincludeHEADERS \ + uninstall-pkgincludeHEADERS + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool ctags distclean distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-nodist_pkgincludeHEADERS \ + install-pkgincludeHEADERS install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-info-am \ + uninstall-nodist_pkgincludeHEADERS uninstall-pkgincludeHEADERS + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/speex/include/speex/speex.h b/src/libs/speex/include/speex/speex.h new file mode 100644 index 00000000..82ba0162 --- /dev/null +++ b/src/libs/speex/include/speex/speex.h @@ -0,0 +1,424 @@ +/* Copyright (C) 2002-2006 Jean-Marc Valin*/ +/** + @file speex.h + @brief Describes the different modes of the codec +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef SPEEX_H +#define SPEEX_H +/** @defgroup Codec Speex encoder and decoder + * This is the Speex codec itself. + * @{ + */ + +#include "speex/speex_bits.h" +#include "speex/speex_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Values allowed for *ctl() requests */ + +/** Set enhancement on/off (decoder only) */ +#define SPEEX_SET_ENH 0 +/** Get enhancement state (decoder only) */ +#define SPEEX_GET_ENH 1 + +/*Would be SPEEX_SET_FRAME_SIZE, but it's (currently) invalid*/ +/** Obtain frame size used by encoder/decoder */ +#define SPEEX_GET_FRAME_SIZE 3 + +/** Set quality value */ +#define SPEEX_SET_QUALITY 4 +/** Get current quality setting */ +/* #define SPEEX_GET_QUALITY 5 -- Doesn't make much sense, does it? */ + +/** Set sub-mode to use */ +#define SPEEX_SET_MODE 6 +/** Get current sub-mode in use */ +#define SPEEX_GET_MODE 7 + +/** Set low-band sub-mode to use (wideband only)*/ +#define SPEEX_SET_LOW_MODE 8 +/** Get current low-band mode in use (wideband only)*/ +#define SPEEX_GET_LOW_MODE 9 + +/** Set high-band sub-mode to use (wideband only)*/ +#define SPEEX_SET_HIGH_MODE 10 +/** Get current high-band mode in use (wideband only)*/ +#define SPEEX_GET_HIGH_MODE 11 + +/** Set VBR on (1) or off (0) */ +#define SPEEX_SET_VBR 12 +/** Get VBR status (1 for on, 0 for off) */ +#define SPEEX_GET_VBR 13 + +/** Set quality value for VBR encoding (0-10) */ +#define SPEEX_SET_VBR_QUALITY 14 +/** Get current quality value for VBR encoding (0-10) */ +#define SPEEX_GET_VBR_QUALITY 15 + +/** Set complexity of the encoder (0-10) */ +#define SPEEX_SET_COMPLEXITY 16 +/** Get current complexity of the encoder (0-10) */ +#define SPEEX_GET_COMPLEXITY 17 + +/** Set bit-rate used by the encoder (or lower) */ +#define SPEEX_SET_BITRATE 18 +/** Get current bit-rate used by the encoder or decoder */ +#define SPEEX_GET_BITRATE 19 + +/** Define a handler function for in-band Speex request*/ +#define SPEEX_SET_HANDLER 20 + +/** Define a handler function for in-band user-defined request*/ +#define SPEEX_SET_USER_HANDLER 22 + +/** Set sampling rate used in bit-rate computation */ +#define SPEEX_SET_SAMPLING_RATE 24 +/** Get sampling rate used in bit-rate computation */ +#define SPEEX_GET_SAMPLING_RATE 25 + +/** Reset the encoder/decoder memories to zero*/ +#define SPEEX_RESET_STATE 26 + +/** Get VBR info (mostly used internally) */ +#define SPEEX_GET_RELATIVE_QUALITY 29 + +/** Set VAD status (1 for on, 0 for off) */ +#define SPEEX_SET_VAD 30 + +/** Get VAD status (1 for on, 0 for off) */ +#define SPEEX_GET_VAD 31 + +/** Set Average Bit-Rate (ABR) to n bits per seconds */ +#define SPEEX_SET_ABR 32 +/** Get Average Bit-Rate (ABR) setting (in bps) */ +#define SPEEX_GET_ABR 33 + +/** Set DTX status (1 for on, 0 for off) */ +#define SPEEX_SET_DTX 34 +/** Get DTX status (1 for on, 0 for off) */ +#define SPEEX_GET_DTX 35 + +/** Set submode encoding in each frame (1 for yes, 0 for no, setting to no breaks the standard) */ +#define SPEEX_SET_SUBMODE_ENCODING 36 +/** Get submode encoding in each frame */ +#define SPEEX_GET_SUBMODE_ENCODING 37 + +/*#define SPEEX_SET_LOOKAHEAD 38*/ +/** Returns the lookahead used by Speex */ +#define SPEEX_GET_LOOKAHEAD 39 + +/** Sets tuning for packet-loss concealment (expected loss rate) */ +#define SPEEX_SET_PLC_TUNING 40 +/** Gets tuning for PLC */ +#define SPEEX_GET_PLC_TUNING 41 + +/** Sets the max bit-rate allowed in VBR mode */ +#define SPEEX_SET_VBR_MAX_BITRATE 42 +/** Gets the max bit-rate allowed in VBR mode */ +#define SPEEX_GET_VBR_MAX_BITRATE 43 + +/** Turn on/off input/output high-pass filtering */ +#define SPEEX_SET_HIGHPASS 44 +/** Get status of input/output high-pass filtering */ +#define SPEEX_GET_HIGHPASS 45 + +/** Get "activity level" of the last decoded frame, i.e. + how much damage we cause if we remove the frame */ +#define SPEEX_GET_ACTIVITY 47 + + +/* Preserving compatibility:*/ +/** Equivalent to SPEEX_SET_ENH */ +#define SPEEX_SET_PF 0 +/** Equivalent to SPEEX_GET_ENH */ +#define SPEEX_GET_PF 1 + + + + +/* Values allowed for mode queries */ +/** Query the frame size of a mode */ +#define SPEEX_MODE_FRAME_SIZE 0 + +/** Query the size of an encoded frame for a particular sub-mode */ +#define SPEEX_SUBMODE_BITS_PER_FRAME 1 + + + +/** Get major Speex version */ +#define SPEEX_LIB_GET_MAJOR_VERSION 1 +/** Get minor Speex version */ +#define SPEEX_LIB_GET_MINOR_VERSION 3 +/** Get micro Speex version */ +#define SPEEX_LIB_GET_MICRO_VERSION 5 +/** Get extra Speex version */ +#define SPEEX_LIB_GET_EXTRA_VERSION 7 +/** Get Speex version string */ +#define SPEEX_LIB_GET_VERSION_STRING 9 + +/*#define SPEEX_LIB_SET_ALLOC_FUNC 10 +#define SPEEX_LIB_GET_ALLOC_FUNC 11 +#define SPEEX_LIB_SET_FREE_FUNC 12 +#define SPEEX_LIB_GET_FREE_FUNC 13 + +#define SPEEX_LIB_SET_WARNING_FUNC 14 +#define SPEEX_LIB_GET_WARNING_FUNC 15 +#define SPEEX_LIB_SET_ERROR_FUNC 16 +#define SPEEX_LIB_GET_ERROR_FUNC 17 +*/ + +/** Number of defined modes in Speex */ +#define SPEEX_NB_MODES 3 + +/** modeID for the defined narrowband mode */ +#define SPEEX_MODEID_NB 0 + +/** modeID for the defined wideband mode */ +#define SPEEX_MODEID_WB 1 + +/** modeID for the defined ultra-wideband mode */ +#define SPEEX_MODEID_UWB 2 + +struct SpeexMode; + + +/* Prototypes for mode function pointers */ + +/** Encoder state initialization function */ +typedef void *(*encoder_init_func)(const struct SpeexMode *mode); + +/** Encoder state destruction function */ +typedef void (*encoder_destroy_func)(void *st); + +/** Main encoding function */ +typedef int (*encode_func)(void *state, void *in, SpeexBits *bits); + +/** Function for controlling the encoder options */ +typedef int (*encoder_ctl_func)(void *state, int request, void *ptr); + +/** Decoder state initialization function */ +typedef void *(*decoder_init_func)(const struct SpeexMode *mode); + +/** Decoder state destruction function */ +typedef void (*decoder_destroy_func)(void *st); + +/** Main decoding function */ +typedef int (*decode_func)(void *state, SpeexBits *bits, void *out); + +/** Function for controlling the decoder options */ +typedef int (*decoder_ctl_func)(void *state, int request, void *ptr); + + +/** Query function for a mode */ +typedef int (*mode_query_func)(const void *mode, int request, void *ptr); + +/** Struct defining a Speex mode */ +typedef struct SpeexMode { + /** Pointer to the low-level mode data */ + const void *mode; + + /** Pointer to the mode query function */ + mode_query_func query; + + /** The name of the mode (you should not rely on this to identify the mode)*/ + const char *modeName; + + /**ID of the mode*/ + int modeID; + + /**Version number of the bitstream (incremented every time we break + bitstream compatibility*/ + int bitstream_version; + + /** Pointer to encoder initialization function */ + encoder_init_func enc_init; + + /** Pointer to encoder destruction function */ + encoder_destroy_func enc_destroy; + + /** Pointer to frame encoding function */ + encode_func enc; + + /** Pointer to decoder initialization function */ + decoder_init_func dec_init; + + /** Pointer to decoder destruction function */ + decoder_destroy_func dec_destroy; + + /** Pointer to frame decoding function */ + decode_func dec; + + /** ioctl-like requests for encoder */ + encoder_ctl_func enc_ctl; + + /** ioctl-like requests for decoder */ + decoder_ctl_func dec_ctl; + +} SpeexMode; + +/** + * Returns a handle to a newly created Speex encoder state structure. For now, + * the "mode" argument can be &nb_mode or &wb_mode . In the future, more modes + * may be added. Note that for now if you have more than one channels to + * encode, you need one state per channel. + * + * @param mode The mode to use (either speex_nb_mode or speex_wb.mode) + * @return A newly created encoder state or NULL if state allocation fails + */ +void *speex_encoder_init(const SpeexMode *mode); + +/** Frees all resources associated to an existing Speex encoder state. + * @param state Encoder state to be destroyed */ +void speex_encoder_destroy(void *state); + +/** Uses an existing encoder state to encode one frame of speech pointed to by + "in". The encoded bit-stream is saved in "bits". + @param state Encoder state + @param in Frame that will be encoded with a +-2^15 range. This data MAY be + overwritten by the encoder and should be considered uninitialised + after the call. + @param bits Bit-stream where the data will be written + @return 0 if frame needs not be transmitted (DTX only), 1 otherwise + */ +int speex_encode(void *state, float *in, SpeexBits *bits); + +/** Uses an existing encoder state to encode one frame of speech pointed to by + "in". The encoded bit-stream is saved in "bits". + @param state Encoder state + @param in Frame that will be encoded with a +-2^15 range + @param bits Bit-stream where the data will be written + @return 0 if frame needs not be transmitted (DTX only), 1 otherwise + */ +int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits); + +/** Used like the ioctl function to control the encoder parameters + * + * @param state Encoder state + * @param request ioctl-type request (one of the SPEEX_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter + */ +int speex_encoder_ctl(void *state, int request, void *ptr); + + +/** Returns a handle to a newly created decoder state structure. For now, + * the mode argument can be &nb_mode or &wb_mode . In the future, more modes + * may be added. Note that for now if you have more than one channels to + * decode, you need one state per channel. + * + * @param mode Speex mode (one of speex_nb_mode or speex_wb_mode) + * @return A newly created decoder state or NULL if state allocation fails + */ +void *speex_decoder_init(const SpeexMode *mode); + +/** Frees all resources associated to an existing decoder state. + * + * @param state State to be destroyed + */ +void speex_decoder_destroy(void *state); + +/** Uses an existing decoder state to decode one frame of speech from + * bit-stream bits. The output speech is saved written to out. + * + * @param state Decoder state + * @param bits Bit-stream from which to decode the frame (NULL if the packet was lost) + * @param out Where to write the decoded frame + * @return return status (0 for no error, -1 for end of stream, -2 corrupt stream) + */ +int speex_decode(void *state, SpeexBits *bits, float *out); + +/** Uses an existing decoder state to decode one frame of speech from + * bit-stream bits. The output speech is saved written to out. + * + * @param state Decoder state + * @param bits Bit-stream from which to decode the frame (NULL if the packet was lost) + * @param out Where to write the decoded frame + * @return return status (0 for no error, -1 for end of stream, -2 corrupt stream) + */ +int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out); + +/** Used like the ioctl function to control the encoder parameters + * + * @param state Decoder state + * @param request ioctl-type request (one of the SPEEX_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter + */ +int speex_decoder_ctl(void *state, int request, void *ptr); + + +/** Query function for mode information + * + * @param mode Speex mode + * @param request ioctl-type request (one of the SPEEX_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter + */ +int speex_mode_query(const SpeexMode *mode, int request, void *ptr); + +/** Functions for controlling the behavior of libspeex + * @param request ioctl-type request (one of the SPEEX_LIB_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter + */ +int speex_lib_ctl(int request, void *ptr); + +/** Default narrowband mode */ +extern const SpeexMode speex_nb_mode; + +/** Default wideband mode */ +extern const SpeexMode speex_wb_mode; + +/** Default "ultra-wideband" mode */ +extern const SpeexMode speex_uwb_mode; + +/** List of all modes available */ +extern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES]; + +/** Obtain one of the modes available */ +const SpeexMode * speex_lib_get_mode (int mode); + +#ifndef WIN32 +/* We actually override the function in the narrowband case so that we can avoid linking in the wideband stuff */ +#define speex_lib_get_mode(mode) ((mode)==SPEEX_MODEID_NB ? &speex_nb_mode : speex_lib_get_mode (mode)) +#endif + +#ifdef __cplusplus +} +#endif + +/** @}*/ +#endif diff --git a/src/libs/speex/include/speex/speex_bits.h b/src/libs/speex/include/speex/speex_bits.h new file mode 100644 index 00000000..a26fb4ce --- /dev/null +++ b/src/libs/speex/include/speex/speex_bits.h @@ -0,0 +1,174 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file speex_bits.h + @brief Handles bit packing/unpacking +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef BITS_H +#define BITS_H +/** @defgroup SpeexBits SpeexBits: Bit-stream manipulations + * This is the structure that holds the bit-stream when encoding or decoding + * with Speex. It allows some manipulations as well. + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Bit-packing data structure representing (part of) a bit-stream. */ +typedef struct SpeexBits { + char *chars; /**< "raw" data */ + int nbBits; /**< Total number of bits stored in the stream*/ + int charPtr; /**< Position of the byte "cursor" */ + int bitPtr; /**< Position of the bit "cursor" within the current char */ + int owner; /**< Does the struct "own" the "raw" buffer (member "chars") */ + int overflow;/**< Set to one if we try to read past the valid data */ + int buf_size;/**< Allocated size for buffer */ + int reserved1; /**< Reserved for future use */ + void *reserved2; /**< Reserved for future use */ +} SpeexBits; + +/** Initializes and allocates resources for a SpeexBits struct */ +void speex_bits_init(SpeexBits *bits); + +/** Initializes SpeexBits struct using a pre-allocated buffer*/ +void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size); + +/** Sets the bits in a SpeexBits struct to use data from an existing buffer (for decoding without copying data) */ +void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size); + +/** Frees all resources associated to a SpeexBits struct. Right now this does nothing since no resources are allocated, but this could change in the future.*/ +void speex_bits_destroy(SpeexBits *bits); + +/** Resets bits to initial value (just after initialization, erasing content)*/ +void speex_bits_reset(SpeexBits *bits); + +/** Rewind the bit-stream to the beginning (ready for read) without erasing the content */ +void speex_bits_rewind(SpeexBits *bits); + +/** Initializes the bit-stream from the data in an area of memory */ +void speex_bits_read_from(SpeexBits *bits, char *bytes, int len); + +/** Append bytes to the bit-stream + * + * @param bits Bit-stream to operate on + * @param bytes pointer to the bytes what will be appended + * @param len Number of bytes of append + */ +void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len); + +/** Write the content of a bit-stream to an area of memory + * + * @param bits Bit-stream to operate on + * @param bytes Memory location where to write the bits + * @param max_len Maximum number of bytes to write (i.e. size of the "bytes" buffer) + * @return Number of bytes written to the "bytes" buffer +*/ +int speex_bits_write(SpeexBits *bits, char *bytes, int max_len); + +/** Like speex_bits_write, but writes only the complete bytes in the stream. Also removes the written bytes from the stream */ +int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len); + +/** Append bits to the bit-stream + * @param bits Bit-stream to operate on + * @param data Value to append as integer + * @param nbBits number of bits to consider in "data" + */ +void speex_bits_pack(SpeexBits *bits, int data, int nbBits); + +/** Interpret the next bits in the bit-stream as a signed integer + * + * @param bits Bit-stream to operate on + * @param nbBits Number of bits to interpret + * @return A signed integer represented by the bits read + */ +int speex_bits_unpack_signed(SpeexBits *bits, int nbBits); + +/** Interpret the next bits in the bit-stream as an unsigned integer + * + * @param bits Bit-stream to operate on + * @param nbBits Number of bits to interpret + * @return An unsigned integer represented by the bits read + */ +unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits); + +/** Returns the number of bytes in the bit-stream, including the last one even if it is not "full" + * + * @param bits Bit-stream to operate on + * @return Number of bytes in the stream + */ +int speex_bits_nbytes(SpeexBits *bits); + +/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position + * + * @param bits Bit-stream to operate on + * @param nbBits Number of bits to look for + * @return Value of the bits peeked, interpreted as unsigned + */ +unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits); + +/** Get the value of the next bit in the stream, without modifying the + * "cursor" position + * + * @param bits Bit-stream to operate on + * @return Value of the bit peeked (one bit only) + */ +int speex_bits_peek(SpeexBits *bits); + +/** Advances the position of the "bit cursor" in the stream + * + * @param bits Bit-stream to operate on + * @param n Number of bits to advance + */ +void speex_bits_advance(SpeexBits *bits, int n); + +/** Returns the number of bits remaining to be read in a stream + * + * @param bits Bit-stream to operate on + * @return Number of bits that can still be read from the stream + */ +int speex_bits_remaining(SpeexBits *bits); + +/** Insert a terminator so that the data can be sent as a packet while auto-detecting + * the number of frames in each packet + * + * @param bits Bit-stream to operate on + */ +void speex_bits_insert_terminator(SpeexBits *bits); + +#ifdef __cplusplus +} +#endif + +/* @} */ +#endif diff --git a/src/libs/speex/include/speex/speex_buffer.h b/src/libs/speex/include/speex/speex_buffer.h new file mode 100644 index 00000000..df56f5f1 --- /dev/null +++ b/src/libs/speex/include/speex/speex_buffer.h @@ -0,0 +1,68 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: speex_buffer.h + This is a very simple ring buffer implementation. It is not thread-safe + so you need to do your own locking. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SPEEX_BUFFER_H +#define SPEEX_BUFFER_H + +#include "speex/speex_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct SpeexBuffer_; +typedef struct SpeexBuffer_ SpeexBuffer; + +SpeexBuffer *speex_buffer_init(int size); + +void speex_buffer_destroy(SpeexBuffer *st); + +int speex_buffer_write(SpeexBuffer *st, void *data, int len); + +int speex_buffer_writezeros(SpeexBuffer *st, int len); + +int speex_buffer_read(SpeexBuffer *st, void *data, int len); + +int speex_buffer_get_available(SpeexBuffer *st); + +int speex_buffer_resize(SpeexBuffer *st, int len); + +#ifdef __cplusplus +} +#endif + +#endif + + + + diff --git a/src/libs/speex/include/speex/speex_callbacks.h b/src/libs/speex/include/speex/speex_callbacks.h new file mode 100644 index 00000000..6f450b3a --- /dev/null +++ b/src/libs/speex/include/speex/speex_callbacks.h @@ -0,0 +1,134 @@ +/* Copyright (C) 2002 Jean-Marc Valin*/ +/** + @file speex_callbacks.h + @brief Describes callback handling and in-band signalling +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef SPEEX_CALLBACKS_H +#define SPEEX_CALLBACKS_H +/** @defgroup SpeexCallbacks Various definitions for Speex callbacks supported by the decoder. + * @{ + */ + +#include "speex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Total number of callbacks */ +#define SPEEX_MAX_CALLBACKS 16 + +/* Describes all the in-band requests */ + +/*These are 1-bit requests*/ +/** Request for perceptual enhancement (1 for on, 0 for off) */ +#define SPEEX_INBAND_ENH_REQUEST 0 +/** Reserved */ +#define SPEEX_INBAND_RESERVED1 1 + +/*These are 4-bit requests*/ +/** Request for a mode change */ +#define SPEEX_INBAND_MODE_REQUEST 2 +/** Request for a low mode change */ +#define SPEEX_INBAND_LOW_MODE_REQUEST 3 +/** Request for a high mode change */ +#define SPEEX_INBAND_HIGH_MODE_REQUEST 4 +/** Request for VBR (1 on, 0 off) */ +#define SPEEX_INBAND_VBR_QUALITY_REQUEST 5 +/** Request to be sent acknowledge */ +#define SPEEX_INBAND_ACKNOWLEDGE_REQUEST 6 +/** Request for VBR (1 for on, 0 for off) */ +#define SPEEX_INBAND_VBR_REQUEST 7 + +/*These are 8-bit requests*/ +/** Send a character in-band */ +#define SPEEX_INBAND_CHAR 8 +/** Intensity stereo information */ +#define SPEEX_INBAND_STEREO 9 + +/*These are 16-bit requests*/ +/** Transmit max bit-rate allowed */ +#define SPEEX_INBAND_MAX_BITRATE 10 + +/*These are 32-bit requests*/ +/** Acknowledge packet reception */ +#define SPEEX_INBAND_ACKNOWLEDGE 12 + +/** Callback function type */ +typedef int (*speex_callback_func)(SpeexBits *bits, void *state, void *data); + +/** Callback information */ +typedef struct SpeexCallback { + int callback_id; /**< ID associated to the callback */ + speex_callback_func func; /**< Callback handler function */ + void *data; /**< Data that will be sent to the handler */ + void *reserved1; /**< Reserved for future use */ + int reserved2; /**< Reserved for future use */ +} SpeexCallback; + +/** Handle in-band request */ +int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state); + +/** Standard handler for mode request (change mode, no questions asked) */ +int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data); + +/** Standard handler for high mode request (change high mode, no questions asked) */ +int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data); + +/** Standard handler for in-band characters (write to stderr) */ +int speex_std_char_handler(SpeexBits *bits, void *state, void *data); + +/** Default handler for user-defined requests: in this case, just ignore */ +int speex_default_user_handler(SpeexBits *bits, void *state, void *data); + + + +/** Standard handler for low mode request (change low mode, no questions asked) */ +int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data); + +/** Standard handler for VBR request (Set VBR, no questions asked) */ +int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data); + +/** Standard handler for enhancer request (Turn enhancer on/off, no questions asked) */ +int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data); + +/** Standard handler for VBR quality request (Set VBR quality, no questions asked) */ +int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data); + + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif diff --git a/src/libs/speex/include/speex/speex_config_types.h.in b/src/libs/speex/include/speex/speex_config_types.h.in new file mode 100644 index 00000000..3fab2ae4 --- /dev/null +++ b/src/libs/speex/include/speex/speex_config_types.h.in @@ -0,0 +1,11 @@ +#ifndef __SPEEX_TYPES_H__ +#define __SPEEX_TYPES_H__ + +/* these are filled in by configure */ +typedef @SIZE16@ spx_int16_t; +typedef unsigned @SIZE16@ spx_uint16_t; +typedef @SIZE32@ spx_int32_t; +typedef unsigned @SIZE32@ spx_uint32_t; + +#endif + diff --git a/src/libs/speex/include/speex/speex_echo.h b/src/libs/speex/include/speex/speex_echo.h new file mode 100644 index 00000000..53bcd28a --- /dev/null +++ b/src/libs/speex/include/speex/speex_echo.h @@ -0,0 +1,170 @@ +/* Copyright (C) Jean-Marc Valin */ +/** + @file speex_echo.h + @brief Echo cancellation +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SPEEX_ECHO_H +#define SPEEX_ECHO_H +/** @defgroup SpeexEchoState SpeexEchoState: Acoustic echo canceller + * This is the acoustic echo canceller module. + * @{ + */ +#include "speex/speex_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Obtain frame size used by the AEC */ +#define SPEEX_ECHO_GET_FRAME_SIZE 3 + +/** Set sampling rate */ +#define SPEEX_ECHO_SET_SAMPLING_RATE 24 +/** Get sampling rate */ +#define SPEEX_ECHO_GET_SAMPLING_RATE 25 + +/* Can't set window sizes */ +/** Get size of impulse response (int32) */ +#define SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE 27 + +/* Can't set window content */ +/** Get impulse response (int32[]) */ +#define SPEEX_ECHO_GET_IMPULSE_RESPONSE 29 + +/** Internal echo canceller state. Should never be accessed directly. */ +struct SpeexEchoState_; + +/** @class SpeexEchoState + * This holds the state of the echo canceller. You need one per channel. +*/ + +/** Internal echo canceller state. Should never be accessed directly. */ +typedef struct SpeexEchoState_ SpeexEchoState; + +/** Creates a new echo canceller state + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms) + * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms) + * @return Newly-created echo canceller state + */ +SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length); + +/** Creates a new multi-channel echo canceller state + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms) + * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms) + * @param nb_mic Number of microphone channels + * @param nb_speakers Number of speaker channels + * @return Newly-created echo canceller state + */ +SpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_length, int nb_mic, int nb_speakers); + +/** Destroys an echo canceller state + * @param st Echo canceller state +*/ +void speex_echo_state_destroy(SpeexEchoState *st); + +/** Performs echo cancellation a frame, based on the audio sent to the speaker (no delay is added + * to playback in this form) + * + * @param st Echo canceller state + * @param rec Signal from the microphone (near end + far end echo) + * @param play Signal played to the speaker (received from far end) + * @param out Returns near-end signal with echo removed + */ +void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out); + +/** Performs echo cancellation a frame (deprecated) */ +void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout); + +/** Perform echo cancellation using internal playback buffer, which is delayed by two frames + * to account for the delay introduced by most soundcards (but it could be off!) + * @param st Echo canceller state + * @param rec Signal from the microphone (near end + far end echo) + * @param out Returns near-end signal with echo removed +*/ +void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out); + +/** Let the echo canceller know that a frame was just queued to the soundcard + * @param st Echo canceller state + * @param play Signal played to the speaker (received from far end) +*/ +void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play); + +/** Reset the echo canceller to its original state + * @param st Echo canceller state + */ +void speex_echo_state_reset(SpeexEchoState *st); + +/** Used like the ioctl function to control the echo canceller parameters + * + * @param st Echo canceller state + * @param request ioctl-type request (one of the SPEEX_ECHO_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown + */ +int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr); + + + +struct SpeexDecorrState_; + +typedef struct SpeexDecorrState_ SpeexDecorrState; + + +/** Create a state for the channel decorrelation algorithm + This is useful for multi-channel echo cancellation only + * @param rate Sampling rate + * @param channels Number of channels (it's a bit pointless if you don't have at least 2) + * @param frame_size Size of the frame to process at ones (counting samples *per* channel) +*/ +SpeexDecorrState *speex_decorrelate_new(int rate, int channels, int frame_size); + +/** Remove correlation between the channels by modifying the phase and possibly + adding noise in a way that is not (or little) perceptible. + * @param st Decorrelator state + * @param in Input audio in interleaved format + * @param out Result of the decorrelation (out *may* alias in) + * @param strength How much alteration of the audio to apply from 0 to 100. +*/ +void speex_decorrelate(SpeexDecorrState *st, const spx_int16_t *in, spx_int16_t *out, int strength); + +/** Destroy a Decorrelation state + * @param st State to destroy +*/ +void speex_decorrelate_destroy(SpeexDecorrState *st); + + +#ifdef __cplusplus +} +#endif + + +/** @}*/ +#endif diff --git a/src/libs/speex/include/speex/speex_header.h b/src/libs/speex/include/speex/speex_header.h new file mode 100644 index 00000000..f85b2496 --- /dev/null +++ b/src/libs/speex/include/speex/speex_header.h @@ -0,0 +1,94 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file speex_header.h + @brief Describes the Speex header +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + +#ifndef SPEEX_HEADER_H +#define SPEEX_HEADER_H +/** @defgroup SpeexHeader SpeexHeader: Makes it easy to write/parse an Ogg/Speex header + * This is the Speex header for the Ogg encapsulation. You don't need that if you just use RTP. + * @{ + */ + +#include "speex/speex_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct SpeexMode; + +/** Length of the Speex header identifier */ +#define SPEEX_HEADER_STRING_LENGTH 8 + +/** Maximum number of characters for encoding the Speex version number in the header */ +#define SPEEX_HEADER_VERSION_LENGTH 20 + +/** Speex header info for file-based formats */ +typedef struct SpeexHeader { + char speex_string[SPEEX_HEADER_STRING_LENGTH]; /**< Identifies a Speex bit-stream, always set to "Speex " */ + char speex_version[SPEEX_HEADER_VERSION_LENGTH]; /**< Speex version */ + spx_int32_t speex_version_id; /**< Version for Speex (for checking compatibility) */ + spx_int32_t header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */ + spx_int32_t rate; /**< Sampling rate used */ + spx_int32_t mode; /**< Mode used (0 for narrowband, 1 for wideband) */ + spx_int32_t mode_bitstream_version; /**< Version ID of the bit-stream */ + spx_int32_t nb_channels; /**< Number of channels encoded */ + spx_int32_t bitrate; /**< Bit-rate used */ + spx_int32_t frame_size; /**< Size of frames */ + spx_int32_t vbr; /**< 1 for a VBR encoding, 0 otherwise */ + spx_int32_t frames_per_packet; /**< Number of frames stored per Ogg packet */ + spx_int32_t extra_headers; /**< Number of additional headers after the comments */ + spx_int32_t reserved1; /**< Reserved for future use, must be zero */ + spx_int32_t reserved2; /**< Reserved for future use, must be zero */ +} SpeexHeader; + +/** Initializes a SpeexHeader using basic information */ +void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const struct SpeexMode *m); + +/** Creates the header packet from the header itself (mostly involves endianness conversion) */ +char *speex_header_to_packet(SpeexHeader *header, int *size); + +/** Creates a SpeexHeader from a packet */ +SpeexHeader *speex_packet_to_header(char *packet, int size); + +/** Frees the memory allocated by either speex_header_to_packet() or speex_packet_to_header() */ +void speex_header_free(void *ptr); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif diff --git a/src/libs/speex/include/speex/speex_jitter.h b/src/libs/speex/include/speex/speex_jitter.h new file mode 100644 index 00000000..d68674b1 --- /dev/null +++ b/src/libs/speex/include/speex/speex_jitter.h @@ -0,0 +1,197 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file speex_jitter.h + @brief Adaptive jitter buffer for Speex +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef SPEEX_JITTER_H +#define SPEEX_JITTER_H +/** @defgroup JitterBuffer JitterBuffer: Adaptive jitter buffer + * This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size + * to maintain good quality and low latency. + * @{ + */ + +#include "speex/speex_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Generic adaptive jitter buffer state */ +struct JitterBuffer_; + +/** Generic adaptive jitter buffer state */ +typedef struct JitterBuffer_ JitterBuffer; + +/** Definition of an incoming packet */ +typedef struct _JitterBufferPacket JitterBufferPacket; + +/** Definition of an incoming packet */ +struct _JitterBufferPacket { + char *data; /**< Data bytes contained in the packet */ + spx_uint32_t len; /**< Length of the packet in bytes */ + spx_uint32_t timestamp; /**< Timestamp for the packet */ + spx_uint32_t span; /**< Time covered by the packet (same units as timestamp) */ + spx_uint16_t sequence; /**< RTP Sequence number if available (0 otherwise) */ + spx_uint32_t user_data; /**< Put whatever data you like here (it's ignored by the jitter buffer) */ +}; + +/** Packet has been retrieved */ +#define JITTER_BUFFER_OK 0 +/** Packet is lost or is late */ +#define JITTER_BUFFER_MISSING 1 +/** A "fake" packet is meant to be inserted here to increase buffering */ +#define JITTER_BUFFER_INSERTION 2 +/** There was an error in the jitter buffer */ +#define JITTER_BUFFER_INTERNAL_ERROR -1 +/** Invalid argument */ +#define JITTER_BUFFER_BAD_ARGUMENT -2 + + +/** Set minimum amount of extra buffering required (margin) */ +#define JITTER_BUFFER_SET_MARGIN 0 +/** Get minimum amount of extra buffering required (margin) */ +#define JITTER_BUFFER_GET_MARGIN 1 +/* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */ + +/** Get the amount of available packets currently buffered */ +#define JITTER_BUFFER_GET_AVAILABLE_COUNT 3 +/** Included because of an early misspelling (will remove in next release) */ +#define JITTER_BUFFER_GET_AVALIABLE_COUNT 3 + +/** Assign a function to destroy unused packet. When setting that, the jitter + buffer no longer copies packet data. */ +#define JITTER_BUFFER_SET_DESTROY_CALLBACK 4 +/** */ +#define JITTER_BUFFER_GET_DESTROY_CALLBACK 5 + +/** Tell the jitter buffer to only adjust the delay in multiples of the step parameter provided */ +#define JITTER_BUFFER_SET_DELAY_STEP 6 +/** */ +#define JITTER_BUFFER_GET_DELAY_STEP 7 + +/** Tell the jitter buffer to only do concealment in multiples of the size parameter provided */ +#define JITTER_BUFFER_SET_CONCEALMENT_SIZE 8 +#define JITTER_BUFFER_GET_CONCEALMENT_SIZE 9 + +/** Absolute max amount of loss that can be tolerated regardless of the delay. Typical loss + should be half of that or less. */ +#define JITTER_BUFFER_SET_MAX_LATE_RATE 10 +#define JITTER_BUFFER_GET_MAX_LATE_RATE 11 + +/** Equivalent cost of one percent late packet in timestamp units */ +#define JITTER_BUFFER_SET_LATE_COST 12 +#define JITTER_BUFFER_GET_LATE_COST 13 + + +/** Initialises jitter buffer + * + * @param step_size Starting value for the size of concleanment packets and delay + adjustment steps. Can be changed at any time using JITTER_BUFFER_SET_DELAY_STEP + and JITTER_BUFFER_GET_CONCEALMENT_SIZE. + * @return Newly created jitter buffer state + */ +JitterBuffer *jitter_buffer_init(int step_size); + +/** Restores jitter buffer to its original state + * + * @param jitter Jitter buffer state + */ +void jitter_buffer_reset(JitterBuffer *jitter); + +/** Destroys jitter buffer + * + * @param jitter Jitter buffer state + */ +void jitter_buffer_destroy(JitterBuffer *jitter); + +/** Put one packet into the jitter buffer + * + * @param jitter Jitter buffer state + * @param packet Incoming packet +*/ +void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet); + +/** Get one packet from the jitter buffer + * + * @param jitter Jitter buffer state + * @param packet Returned packet + * @param desired_span Number of samples (or units) we wish to get from the buffer (no guarantee) + * @param current_timestamp Timestamp for the returned packet +*/ +int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset); + +/** Used right after jitter_buffer_get() to obtain another packet that would have the same timestamp. + * This is mainly useful for media where a single "frame" can be split into several packets. + * + * @param jitter Jitter buffer state + * @param packet Returned packet + */ +int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet); + +/** Get pointer timestamp of jitter buffer + * + * @param jitter Jitter buffer state +*/ +int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter); + +/** Advance by one tick + * + * @param jitter Jitter buffer state +*/ +void jitter_buffer_tick(JitterBuffer *jitter); + +/** Telling the jitter buffer about the remaining data in the application buffer + * @param jitter Jitter buffer state + * @param rem Amount of data buffered by the application (timestamp units) + */ +void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem); + +/** Used like the ioctl function to control the jitter buffer parameters + * + * @param jitter Jitter buffer state + * @param request ioctl-type request (one of the JITTER_BUFFER_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown +*/ +int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr); + +int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/speex/include/speex/speex_preprocess.h b/src/libs/speex/include/speex/speex_preprocess.h new file mode 100644 index 00000000..f8eef2cd --- /dev/null +++ b/src/libs/speex/include/speex/speex_preprocess.h @@ -0,0 +1,219 @@ +/* Copyright (C) 2003 Epic Games + Written by Jean-Marc Valin */ +/** + * @file speex_preprocess.h + * @brief Speex preprocessor. The preprocess can do noise suppression, + * residual echo suppression (after using the echo canceller), automatic + * gain control (AGC) and voice activity detection (VAD). +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SPEEX_PREPROCESS_H +#define SPEEX_PREPROCESS_H +/** @defgroup SpeexPreprocessState SpeexPreprocessState: The Speex preprocessor + * This is the Speex preprocessor. The preprocess can do noise suppression, + * residual echo suppression (after using the echo canceller), automatic + * gain control (AGC) and voice activity detection (VAD). + * @{ + */ + +#include "speex/speex_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** State of the preprocessor (one per channel). Should never be accessed directly. */ +struct SpeexPreprocessState_; + +/** State of the preprocessor (one per channel). Should never be accessed directly. */ +typedef struct SpeexPreprocessState_ SpeexPreprocessState; + + +/** Creates a new preprocessing state. You MUST create one state per channel processed. + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms). Must be + * the same value as that used for the echo canceller for residual echo cancellation to work. + * @param sampling_rate Sampling rate used for the input. + * @return Newly created preprocessor state +*/ +SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate); + +/** Destroys a preprocessor state + * @param st Preprocessor state to destroy +*/ +void speex_preprocess_state_destroy(SpeexPreprocessState *st); + +/** Preprocess a frame + * @param st Preprocessor state + * @param x Audio sample vector (in and out). Must be same size as specified in speex_preprocess_state_init(). + * @return Bool value for voice activity (1 for speech, 0 for noise/silence), ONLY if VAD turned on. +*/ +int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x); + +/** Preprocess a frame (deprecated, use speex_preprocess_run() instead)*/ +int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo); + +/** Update preprocessor state, but do not compute the output + * @param st Preprocessor state + * @param x Audio sample vector (in only). Must be same size as specified in speex_preprocess_state_init(). +*/ +void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x); + +/** Used like the ioctl function to control the preprocessor parameters + * @param st Preprocessor state + * @param request ioctl-type request (one of the SPEEX_PREPROCESS_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown +*/ +int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr); + + + +/** Set preprocessor denoiser state */ +#define SPEEX_PREPROCESS_SET_DENOISE 0 +/** Get preprocessor denoiser state */ +#define SPEEX_PREPROCESS_GET_DENOISE 1 + +/** Set preprocessor Automatic Gain Control state */ +#define SPEEX_PREPROCESS_SET_AGC 2 +/** Get preprocessor Automatic Gain Control state */ +#define SPEEX_PREPROCESS_GET_AGC 3 + +/** Set preprocessor Voice Activity Detection state */ +#define SPEEX_PREPROCESS_SET_VAD 4 +/** Get preprocessor Voice Activity Detection state */ +#define SPEEX_PREPROCESS_GET_VAD 5 + +/** Set preprocessor Automatic Gain Control level (float) */ +#define SPEEX_PREPROCESS_SET_AGC_LEVEL 6 +/** Get preprocessor Automatic Gain Control level (float) */ +#define SPEEX_PREPROCESS_GET_AGC_LEVEL 7 + +/** Set preprocessor dereverb state */ +#define SPEEX_PREPROCESS_SET_DEREVERB 8 +/** Get preprocessor dereverb state */ +#define SPEEX_PREPROCESS_GET_DEREVERB 9 + +/** Set preprocessor dereverb level */ +#define SPEEX_PREPROCESS_SET_DEREVERB_LEVEL 10 +/** Get preprocessor dereverb level */ +#define SPEEX_PREPROCESS_GET_DEREVERB_LEVEL 11 + +/** Set preprocessor dereverb decay */ +#define SPEEX_PREPROCESS_SET_DEREVERB_DECAY 12 +/** Get preprocessor dereverb decay */ +#define SPEEX_PREPROCESS_GET_DEREVERB_DECAY 13 + +/** Set probability required for the VAD to go from silence to voice */ +#define SPEEX_PREPROCESS_SET_PROB_START 14 +/** Get probability required for the VAD to go from silence to voice */ +#define SPEEX_PREPROCESS_GET_PROB_START 15 + +/** Set probability required for the VAD to stay in the voice state (integer percent) */ +#define SPEEX_PREPROCESS_SET_PROB_CONTINUE 16 +/** Get probability required for the VAD to stay in the voice state (integer percent) */ +#define SPEEX_PREPROCESS_GET_PROB_CONTINUE 17 + +/** Set maximum attenuation of the noise in dB (negative number) */ +#define SPEEX_PREPROCESS_SET_NOISE_SUPPRESS 18 +/** Get maximum attenuation of the noise in dB (negative number) */ +#define SPEEX_PREPROCESS_GET_NOISE_SUPPRESS 19 + +/** Set maximum attenuation of the residual echo in dB (negative number) */ +#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS 20 +/** Get maximum attenuation of the residual echo in dB (negative number) */ +#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS 21 + +/** Set maximum attenuation of the residual echo in dB when near end is active (negative number) */ +#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE 22 +/** Get maximum attenuation of the residual echo in dB when near end is active (negative number) */ +#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE 23 + +/** Set the corresponding echo canceller state so that residual echo suppression can be performed (NULL for no residual echo suppression) */ +#define SPEEX_PREPROCESS_SET_ECHO_STATE 24 +/** Get the corresponding echo canceller state */ +#define SPEEX_PREPROCESS_GET_ECHO_STATE 25 + +/** Set maximal gain increase in dB/second (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_INCREMENT 26 + +/** Get maximal gain increase in dB/second (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_INCREMENT 27 + +/** Set maximal gain decrease in dB/second (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_DECREMENT 28 + +/** Get maximal gain decrease in dB/second (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_DECREMENT 29 + +/** Set maximal gain in dB (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_MAX_GAIN 30 + +/** Get maximal gain in dB (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31 + +/* Can't set loudness */ +/** Get loudness */ +#define SPEEX_PREPROCESS_GET_AGC_LOUDNESS 33 + +/* Can't set gain */ +/** Get current gain (int32 percent) */ +#define SPEEX_PREPROCESS_GET_AGC_GAIN 35 + +/* Can't set spectrum size */ +/** Get spectrum size for power spectrum (int32) */ +#define SPEEX_PREPROCESS_GET_PSD_SIZE 37 + +/* Can't set power spectrum */ +/** Get power spectrum (int32[] of squared values) */ +#define SPEEX_PREPROCESS_GET_PSD 39 + +/* Can't set noise size */ +/** Get spectrum size for noise estimate (int32) */ +#define SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE 41 + +/* Can't set noise estimate */ +/** Get noise estimate (int32[] of squared values) */ +#define SPEEX_PREPROCESS_GET_NOISE_PSD 43 + +/* Can't set speech probability */ +/** Get speech probability in last frame (int32). */ +#define SPEEX_PREPROCESS_GET_PROB 45 + +/** Set preprocessor Automatic Gain Control level (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_TARGET 46 +/** Get preprocessor Automatic Gain Control level (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_TARGET 47 + +#ifdef __cplusplus +} +#endif + +/** @}*/ +#endif diff --git a/src/libs/speex/include/speex/speex_resampler.h b/src/libs/speex/include/speex/speex_resampler.h new file mode 100644 index 00000000..54eef8d7 --- /dev/null +++ b/src/libs/speex/include/speex/speex_resampler.h @@ -0,0 +1,340 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: speex_resampler.h + Resampling code + + The design goals of this code are: + - Very fast algorithm + - Low memory requirement + - Good *perceptual* quality (and not best SNR) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef SPEEX_RESAMPLER_H +#define SPEEX_RESAMPLER_H + +#ifdef OUTSIDE_SPEEX + +/********* WARNING: MENTAL SANITY ENDS HERE *************/ + +/* If the resampler is defined outside of Speex, we change the symbol names so that + there won't be any clash if linking with Speex later on. */ + +/* #define RANDOM_PREFIX your software name here */ +#ifndef RANDOM_PREFIX +#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes" +#endif + +#define CAT_PREFIX2(a,b) a ## b +#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b) + +#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init) +#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac) +#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy) +#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float) +#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int) +#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float) +#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int) +#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate) +#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate) +#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac) +#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio) +#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality) +#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality) +#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride) +#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride) +#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride) +#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride) +#define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency) +#define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency) +#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros) +#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem) +#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror) + +#define spx_int16_t short +#define spx_int32_t int +#define spx_uint16_t unsigned short +#define spx_uint32_t unsigned int + +#else /* OUTSIDE_SPEEX */ + +#include "speex/speex_types.h" + +#endif /* OUTSIDE_SPEEX */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPEEX_RESAMPLER_QUALITY_MAX 10 +#define SPEEX_RESAMPLER_QUALITY_MIN 0 +#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4 +#define SPEEX_RESAMPLER_QUALITY_VOIP 3 +#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5 + +enum { + RESAMPLER_ERR_SUCCESS = 0, + RESAMPLER_ERR_ALLOC_FAILED = 1, + RESAMPLER_ERR_BAD_STATE = 2, + RESAMPLER_ERR_INVALID_ARG = 3, + RESAMPLER_ERR_PTR_OVERLAP = 4, + + RESAMPLER_ERR_MAX_ERROR +}; + +struct SpeexResamplerState_; +typedef struct SpeexResamplerState_ SpeexResamplerState; + +/** Create a new resampler with integer input and output rates. + * @param nb_channels Number of channels to be processed + * @param in_rate Input sampling rate (integer number of Hz). + * @param out_rate Output sampling rate (integer number of Hz). + * @param quality Resampling quality between 0 and 10, where 0 has poor quality + * and 10 has very high quality. + * @return Newly created resampler state + * @retval NULL Error: not enough memory + */ +SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, + spx_uint32_t in_rate, + spx_uint32_t out_rate, + int quality, + int *err); + +/** Create a new resampler with fractional input/output rates. The sampling + * rate ratio is an arbitrary rational number with both the numerator and + * denominator being 32-bit integers. + * @param nb_channels Number of channels to be processed + * @param ratio_num Numerator of the sampling rate ratio + * @param ratio_den Denominator of the sampling rate ratio + * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). + * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). + * @param quality Resampling quality between 0 and 10, where 0 has poor quality + * and 10 has very high quality. + * @return Newly created resampler state + * @retval NULL Error: not enough memory + */ +SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, + spx_uint32_t ratio_num, + spx_uint32_t ratio_den, + spx_uint32_t in_rate, + spx_uint32_t out_rate, + int quality, + int *err); + +/** Destroy a resampler state. + * @param st Resampler state + */ +void speex_resampler_destroy(SpeexResamplerState *st); + +/** Resample a float array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param channel_index Index of the channel to process for the multi-channel + * base (0 otherwise) + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the + * number of samples processed + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written + */ +int speex_resampler_process_float(SpeexResamplerState *st, + spx_uint32_t channel_index, + const float *in, + spx_uint32_t *in_len, + float *out, + spx_uint32_t *out_len); + +/** Resample an int array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param channel_index Index of the channel to process for the multi-channel + * base (0 otherwise) + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written + */ +int speex_resampler_process_int(SpeexResamplerState *st, + spx_uint32_t channel_index, + const spx_int16_t *in, + spx_uint32_t *in_len, + spx_int16_t *out, + spx_uint32_t *out_len); + +/** Resample an interleaved float array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed. This is all per-channel. + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written. + * This is all per-channel. + */ +int speex_resampler_process_interleaved_float(SpeexResamplerState *st, + const float *in, + spx_uint32_t *in_len, + float *out, + spx_uint32_t *out_len); + +/** Resample an interleaved int array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed. This is all per-channel. + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written. + * This is all per-channel. + */ +int speex_resampler_process_interleaved_int(SpeexResamplerState *st, + const spx_int16_t *in, + spx_uint32_t *in_len, + spx_int16_t *out, + spx_uint32_t *out_len); + +/** Set (change) the input/output sampling rates (integer value). + * @param st Resampler state + * @param in_rate Input sampling rate (integer number of Hz). + * @param out_rate Output sampling rate (integer number of Hz). + */ +int speex_resampler_set_rate(SpeexResamplerState *st, + spx_uint32_t in_rate, + spx_uint32_t out_rate); + +/** Get the current input/output sampling rates (integer value). + * @param st Resampler state + * @param in_rate Input sampling rate (integer number of Hz) copied. + * @param out_rate Output sampling rate (integer number of Hz) copied. + */ +void speex_resampler_get_rate(SpeexResamplerState *st, + spx_uint32_t *in_rate, + spx_uint32_t *out_rate); + +/** Set (change) the input/output sampling rates and resampling ratio + * (fractional values in Hz supported). + * @param st Resampler state + * @param ratio_num Numerator of the sampling rate ratio + * @param ratio_den Denominator of the sampling rate ratio + * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). + * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). + */ +int speex_resampler_set_rate_frac(SpeexResamplerState *st, + spx_uint32_t ratio_num, + spx_uint32_t ratio_den, + spx_uint32_t in_rate, + spx_uint32_t out_rate); + +/** Get the current resampling ratio. This will be reduced to the least + * common denominator. + * @param st Resampler state + * @param ratio_num Numerator of the sampling rate ratio copied + * @param ratio_den Denominator of the sampling rate ratio copied + */ +void speex_resampler_get_ratio(SpeexResamplerState *st, + spx_uint32_t *ratio_num, + spx_uint32_t *ratio_den); + +/** Set (change) the conversion quality. + * @param st Resampler state + * @param quality Resampling quality between 0 and 10, where 0 has poor + * quality and 10 has very high quality. + */ +int speex_resampler_set_quality(SpeexResamplerState *st, + int quality); + +/** Get the conversion quality. + * @param st Resampler state + * @param quality Resampling quality between 0 and 10, where 0 has poor + * quality and 10 has very high quality. + */ +void speex_resampler_get_quality(SpeexResamplerState *st, + int *quality); + +/** Set (change) the input stride. + * @param st Resampler state + * @param stride Input stride + */ +void speex_resampler_set_input_stride(SpeexResamplerState *st, + spx_uint32_t stride); + +/** Get the input stride. + * @param st Resampler state + * @param stride Input stride copied + */ +void speex_resampler_get_input_stride(SpeexResamplerState *st, + spx_uint32_t *stride); + +/** Set (change) the output stride. + * @param st Resampler state + * @param stride Output stride + */ +void speex_resampler_set_output_stride(SpeexResamplerState *st, + spx_uint32_t stride); + +/** Get the output stride. + * @param st Resampler state copied + * @param stride Output stride + */ +void speex_resampler_get_output_stride(SpeexResamplerState *st, + spx_uint32_t *stride); + +/** Get the latency in input samples introduced by the resampler. + * @param st Resampler state + */ +int speex_resampler_get_input_latency(SpeexResamplerState *st); + +/** Get the latency in output samples introduced by the resampler. + * @param st Resampler state + */ +int speex_resampler_get_output_latency(SpeexResamplerState *st); + +/** Make sure that the first samples to go out of the resamplers don't have + * leading zeros. This is only useful before starting to use a newly created + * resampler. It is recommended to use that when resampling an audio file, as + * it will generate a file with the same length. For real-time processing, + * it is probably easier not to use this call (so that the output duration + * is the same for the first frame). + * @param st Resampler state + */ +int speex_resampler_skip_zeros(SpeexResamplerState *st); + +/** Reset a resampler so a new (unrelated) stream can be processed. + * @param st Resampler state + */ +int speex_resampler_reset_mem(SpeexResamplerState *st); + +/** Returns the English meaning for an error code + * @param err Error code + * @return English string + */ +const char *speex_resampler_strerror(int err); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/speex/include/speex/speex_stereo.h b/src/libs/speex/include/speex/speex_stereo.h new file mode 100644 index 00000000..a259713b --- /dev/null +++ b/src/libs/speex/include/speex/speex_stereo.h @@ -0,0 +1,91 @@ +/* Copyright (C) 2002 Jean-Marc Valin*/ +/** + @file speex_stereo.h + @brief Describes the handling for intensity stereo +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef STEREO_H +#define STEREO_H +/** @defgroup SpeexStereoState SpeexStereoState: Handling Speex stereo files + * This describes the Speex intensity stereo encoding/decoding + * @{ + */ + +#include "speex/speex_types.h" +#include "speex/speex_bits.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** If you access any of these fields directly, I'll personally come and bite you */ +typedef struct SpeexStereoState { + float balance; /**< Left/right balance info */ + float e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */ + float smooth_left; /**< Smoothed left channel gain */ + float smooth_right; /**< Smoothed right channel gain */ + float reserved1; /**< Reserved for future use */ + float reserved2; /**< Reserved for future use */ +} SpeexStereoState; + +/** Deprecated. Use speex_stereo_state_init() instead. */ +#define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0} + +/** Initialise/create a stereo stereo state */ +SpeexStereoState *speex_stereo_state_init(); + +/** Reset/re-initialise an already allocated stereo state */ +void speex_stereo_state_reset(SpeexStereoState *stereo); + +/** Destroy a stereo stereo state */ +void speex_stereo_state_destroy(SpeexStereoState *stereo); + +/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */ +void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits); + +/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */ +void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits); + +/** Transforms a mono frame into a stereo frame using intensity stereo info */ +void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo); + +/** Transforms a mono frame into a stereo frame using intensity stereo info */ +void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo); + +/** Callback handler for intensity stereo info */ +int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif diff --git a/src/libs/speex/include/speex/speex_types.h b/src/libs/speex/include/speex/speex_types.h new file mode 100644 index 00000000..852fed80 --- /dev/null +++ b/src/libs/speex/include/speex/speex_types.h @@ -0,0 +1,126 @@ +/* speex_types.h taken from libogg */ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id: os_types.h 7524 2004-08-11 04:20:36Z conrad $ + + ********************************************************************/ +/** + @file speex_types.h + @brief Speex types +*/ +#ifndef _SPEEX_TYPES_H +#define _SPEEX_TYPES_H + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include <_G_config.h> + typedef _G_int32_t spx_int32_t; + typedef _G_uint32_t spx_uint32_t; + typedef _G_int16_t spx_int16_t; + typedef _G_uint16_t spx_uint16_t; +# elif defined(__MINGW32__) + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; +# elif defined(__MWERKS__) + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; +# else + /* MSVC/Borland */ + typedef __int32 spx_int32_t; + typedef unsigned __int32 spx_uint32_t; + typedef __int16 spx_int16_t; + typedef unsigned __int16 spx_uint16_t; +# endif + +#elif defined(__MACOS__) + +# include <sys/types.h> + typedef SInt16 spx_int16_t; + typedef UInt16 spx_uint16_t; + typedef SInt32 spx_int32_t; + typedef UInt32 spx_uint32_t; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include <sys/types.h> + typedef int16_t spx_int16_t; + typedef u_int16_t spx_uint16_t; + typedef int32_t spx_int32_t; + typedef u_int32_t spx_uint32_t; + +#elif defined(__BEOS__) + + /* Be */ +# include <inttypes.h> + typedef int16_t spx_int16_t; + typedef u_int16_t spx_uint16_t; + typedef int32_t spx_int32_t; + typedef u_int32_t spx_uint32_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short spx_int16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef int spx_int32_t; + typedef unsigned spx_uint32_t; + typedef short spx_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef signed int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef long spx_int32_t; + typedef unsigned long spx_uint32_t; + +#elif defined(CONFIG_TI_C6X) + + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#else + +# include <speex/speex_config_types.h> + +#endif + +#endif /* _SPEEX_TYPES_H */ diff --git a/src/libs/speex/libspeex/_kiss_fft_guts.h b/src/libs/speex/libspeex/_kiss_fft_guts.h new file mode 100644 index 00000000..6571e79c --- /dev/null +++ b/src/libs/speex/libspeex/_kiss_fft_guts.h @@ -0,0 +1,160 @@ +/* +Copyright (c) 2003-2004, Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define MIN(a,b) ((a)<(b) ? (a):(b)) +#define MAX(a,b) ((a)>(b) ? (a):(b)) + +/* kiss_fft.h + defines kiss_fft_scalar as either short or a float type + and defines + typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ +#include "kiss_fft.h" +#include "math_approx.h" + +#define MAXFACTORS 32 +/* e.g. an fft of length 128 has 4 factors + as far as kissfft is concerned + 4*4*4*2 + */ + +struct kiss_fft_state{ + int nfft; + int inverse; + int factors[2*MAXFACTORS]; + kiss_fft_cpx twiddles[1]; +}; + +/* + Explanation of macros dealing with complex math: + + C_MUL(m,a,b) : m = a*b + C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise + C_SUB( res, a,b) : res = a - b + C_SUBFROM( res , a) : res -= a + C_ADDTO( res , a) : res += a + * */ +#ifdef FIXED_POINT +#include "arch.h" +# define FRACBITS 15 +# define SAMPPROD spx_int32_t +#define SAMP_MAX 32767 + +#define SAMP_MIN -SAMP_MAX + +#if defined(CHECK_OVERFLOW) +# define CHECK_OVERFLOW_OP(a,op,b) \ + if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \ + fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); } +#endif + + +# define smul(a,b) ( (SAMPPROD)(a)*(b) ) +# define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS ) + +# define S_MUL(a,b) sround( smul(a,b) ) + +# define C_MUL(m,a,b) \ + do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ + (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) + +# define C_MUL4(m,a,b) \ + do{ (m).r = PSHR32( smul((a).r,(b).r) - smul((a).i,(b).i),17 ); \ + (m).i = PSHR32( smul((a).r,(b).i) + smul((a).i,(b).r),17 ); }while(0) + +# define DIVSCALAR(x,k) \ + (x) = sround( smul( x, SAMP_MAX/k ) ) + +# define C_FIXDIV(c,div) \ + do { DIVSCALAR( (c).r , div); \ + DIVSCALAR( (c).i , div); }while (0) + +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r = sround( smul( (c).r , s ) ) ;\ + (c).i = sround( smul( (c).i , s ) ) ; }while(0) + +#else /* not FIXED_POINT*/ + +# define S_MUL(a,b) ( (a)*(b) ) +#define C_MUL(m,a,b) \ + do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ + (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) + +#define C_MUL4(m,a,b) C_MUL(m,a,b) + +# define C_FIXDIV(c,div) /* NOOP */ +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r *= (s);\ + (c).i *= (s); }while(0) +#endif + +#ifndef CHECK_OVERFLOW_OP +# define CHECK_OVERFLOW_OP(a,op,b) /* noop */ +#endif + +#define C_ADD( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,+,(b).r)\ + CHECK_OVERFLOW_OP((a).i,+,(b).i)\ + (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ + }while(0) +#define C_SUB( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,-,(b).r)\ + CHECK_OVERFLOW_OP((a).i,-,(b).i)\ + (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ + }while(0) +#define C_ADDTO( res , a)\ + do { \ + CHECK_OVERFLOW_OP((res).r,+,(a).r)\ + CHECK_OVERFLOW_OP((res).i,+,(a).i)\ + (res).r += (a).r; (res).i += (a).i;\ + }while(0) + +#define C_SUBFROM( res , a)\ + do {\ + CHECK_OVERFLOW_OP((res).r,-,(a).r)\ + CHECK_OVERFLOW_OP((res).i,-,(a).i)\ + (res).r -= (a).r; (res).i -= (a).i; \ + }while(0) + + +#ifdef FIXED_POINT +# define KISS_FFT_COS(phase) floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase)))) +# define KISS_FFT_SIN(phase) floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase)))) +# define HALF_OF(x) ((x)>>1) +#elif defined(USE_SIMD) +# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) +# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) +# define HALF_OF(x) ((x)*_mm_set1_ps(.5)) +#else +# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) +# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) +# define HALF_OF(x) ((x)*.5) +#endif + +#define kf_cexp(x,phase) \ + do{ \ + (x)->r = KISS_FFT_COS(phase);\ + (x)->i = KISS_FFT_SIN(phase);\ + }while(0) +#define kf_cexp2(x,phase) \ + do{ \ + (x)->r = spx_cos_norm((phase));\ + (x)->i = spx_cos_norm((phase)-32768);\ +}while(0) + + +/* a debugging function */ +#define pcpx(c)\ + fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) ) diff --git a/src/libs/speex/libspeex/arch.h b/src/libs/speex/libspeex/arch.h new file mode 100644 index 00000000..d38c36ce --- /dev/null +++ b/src/libs/speex/libspeex/arch.h @@ -0,0 +1,239 @@ +/* Copyright (C) 2003 Jean-Marc Valin */ +/** + @file arch.h + @brief Various architecture definitions Speex +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ARCH_H +#define ARCH_H + +#ifndef SPEEX_VERSION +#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */ +#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */ +#define SPEEX_MICRO_VERSION 15 /**< Micro Speex version. */ +#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */ +#define SPEEX_VERSION "speex-1.2beta3" /**< Speex version string. */ +#endif + +/* A couple test to catch stupid option combinations */ +#ifdef FIXED_POINT + +#ifdef FLOATING_POINT +#error You cannot compile as floating point and fixed point at the same time +#endif +#ifdef _USE_SSE +#error SSE is only for floating-point +#endif +#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM)) +#error Make up your mind. What CPU do you have? +#endif +#ifdef VORBIS_PSYCHO +#error Vorbis-psy model currently not implemented in fixed-point +#endif + +#else + +#ifndef FLOATING_POINT +#error You now need to define either FIXED_POINT or FLOATING_POINT +#endif +#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM) +#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions? +#endif +#ifdef FIXED_POINT_DEBUG +#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?" +#endif + + +#endif + +#ifndef OUTSIDE_SPEEX +#include "speex/speex_types.h" +#endif + +#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */ +#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */ +#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */ +#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */ +#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */ +#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 32-bit value. */ +#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */ + +#ifdef FIXED_POINT + +typedef spx_int16_t spx_word16_t; +typedef spx_int32_t spx_word32_t; +typedef spx_word32_t spx_mem_t; +typedef spx_word16_t spx_coef_t; +typedef spx_word16_t spx_lsp_t; +typedef spx_word32_t spx_sig_t; + +#define Q15ONE 32767 + +#define LPC_SCALING 8192 +#define SIG_SCALING 16384 +#define LSP_SCALING 8192. +#define GAMMA_SCALING 32768. +#define GAIN_SCALING 64 +#define GAIN_SCALING_1 0.015625 + +#define LPC_SHIFT 13 +#define LSP_SHIFT 13 +#define SIG_SHIFT 14 +#define GAIN_SHIFT 6 + +#define VERY_SMALL 0 +#define VERY_LARGE32 ((spx_word32_t)2147483647) +#define VERY_LARGE16 ((spx_word16_t)32767) +#define Q15_ONE ((spx_word16_t)32767) + + +#ifdef FIXED_DEBUG +#include "fixed_debug.h" +#else + +#include "fixed_generic.h" + +#ifdef ARM5E_ASM +#include "fixed_arm5e.h" +#elif defined (ARM4_ASM) +#include "fixed_arm4.h" +#elif defined (BFIN_ASM) +#include "fixed_bfin.h" +#endif + +#endif + + +#else + +typedef float spx_mem_t; +typedef float spx_coef_t; +typedef float spx_lsp_t; +typedef float spx_sig_t; +typedef float spx_word16_t; +typedef float spx_word32_t; + +#define Q15ONE 1.0f +#define LPC_SCALING 1.f +#define SIG_SCALING 1.f +#define LSP_SCALING 1.f +#define GAMMA_SCALING 1.f +#define GAIN_SCALING 1.f +#define GAIN_SCALING_1 1.f + + +#define VERY_SMALL 1e-15f +#define VERY_LARGE32 1e15f +#define VERY_LARGE16 1e15f +#define Q15_ONE ((spx_word16_t)1.f) + +#define QCONST16(x,bits) (x) +#define QCONST32(x,bits) (x) + +#define NEG16(x) (-(x)) +#define NEG32(x) (-(x)) +#define EXTRACT16(x) (x) +#define EXTEND32(x) (x) +#define SHR16(a,shift) (a) +#define SHL16(a,shift) (a) +#define SHR32(a,shift) (a) +#define SHL32(a,shift) (a) +#define PSHR16(a,shift) (a) +#define PSHR32(a,shift) (a) +#define VSHR32(a,shift) (a) +#define SATURATE16(x,a) (x) +#define SATURATE32(x,a) (x) + +#define PSHR(a,shift) (a) +#define SHR(a,shift) (a) +#define SHL(a,shift) (a) +#define SATURATE(x,a) (x) + +#define ADD16(a,b) ((a)+(b)) +#define SUB16(a,b) ((a)-(b)) +#define ADD32(a,b) ((a)+(b)) +#define SUB32(a,b) ((a)-(b)) +#define MULT16_16_16(a,b) ((a)*(b)) +#define MULT16_16(a,b) ((spx_word32_t)(a)*(spx_word32_t)(b)) +#define MAC16_16(c,a,b) ((c)+(spx_word32_t)(a)*(spx_word32_t)(b)) + +#define MULT16_32_Q11(a,b) ((a)*(b)) +#define MULT16_32_Q13(a,b) ((a)*(b)) +#define MULT16_32_Q14(a,b) ((a)*(b)) +#define MULT16_32_Q15(a,b) ((a)*(b)) +#define MULT16_32_P15(a,b) ((a)*(b)) + +#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b)) +#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b)) + +#define MAC16_16_Q11(c,a,b) ((c)+(a)*(b)) +#define MAC16_16_Q13(c,a,b) ((c)+(a)*(b)) +#define MAC16_16_P13(c,a,b) ((c)+(a)*(b)) +#define MULT16_16_Q11_32(a,b) ((a)*(b)) +#define MULT16_16_Q13(a,b) ((a)*(b)) +#define MULT16_16_Q14(a,b) ((a)*(b)) +#define MULT16_16_Q15(a,b) ((a)*(b)) +#define MULT16_16_P15(a,b) ((a)*(b)) +#define MULT16_16_P13(a,b) ((a)*(b)) +#define MULT16_16_P14(a,b) ((a)*(b)) + +#define DIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b)) +#define PDIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b)) +#define DIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b)) +#define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b)) + + +#endif + + +#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + +/* 2 on TI C5x DSP */ +#define BYTES_PER_CHAR 2 +#define BITS_PER_CHAR 16 +#define LOG2_BITS_PER_CHAR 4 + +#else + +#define BYTES_PER_CHAR 1 +#define BITS_PER_CHAR 8 +#define LOG2_BITS_PER_CHAR 3 + +#endif + + + +#ifdef FIXED_DEBUG +extern long long spx_mips; +#endif + + +#endif diff --git a/src/libs/speex/libspeex/bits.c b/src/libs/speex/libspeex/bits.c new file mode 100644 index 00000000..3ef7c6c1 --- /dev/null +++ b/src/libs/speex/libspeex/bits.c @@ -0,0 +1,372 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: speex_bits.c + + Handles bit packing/unpacking + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <speex/speex_bits.h> +#include "arch.h" +#include "os_support.h" + +/* Maximum size of the bit-stream (for fixed-size allocation) */ +#ifndef MAX_CHARS_PER_FRAME +#define MAX_CHARS_PER_FRAME (2000/BYTES_PER_CHAR) +#endif + +EXPORT void speex_bits_init(SpeexBits *bits) +{ + bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME); + if (!bits->chars) + return; + + bits->buf_size = MAX_CHARS_PER_FRAME; + + bits->owner=1; + + speex_bits_reset(bits); +} + +EXPORT void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size) +{ + bits->chars = (char*)buff; + bits->buf_size = buf_size; + + bits->owner=0; + + speex_bits_reset(bits); +} + +EXPORT void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size) +{ + bits->chars = (char*)buff; + bits->buf_size = buf_size; + + bits->owner=0; + + bits->nbBits=buf_size<<LOG2_BITS_PER_CHAR; + bits->charPtr=0; + bits->bitPtr=0; + bits->overflow=0; + +} + +EXPORT void speex_bits_destroy(SpeexBits *bits) +{ + if (bits->owner) + speex_free(bits->chars); + /* Will do something once the allocation is dynamic */ +} + +EXPORT void speex_bits_reset(SpeexBits *bits) +{ + /* We only need to clear the first byte now */ + bits->chars[0]=0; + bits->nbBits=0; + bits->charPtr=0; + bits->bitPtr=0; + bits->overflow=0; +} + +EXPORT void speex_bits_rewind(SpeexBits *bits) +{ + bits->charPtr=0; + bits->bitPtr=0; + bits->overflow=0; +} + +EXPORT void speex_bits_read_from(SpeexBits *bits, char *chars, int len) +{ + int i; + int nchars = len / BYTES_PER_CHAR; + if (nchars > bits->buf_size) + { + speex_notify("Packet is larger than allocated buffer"); + if (bits->owner) + { + char *tmp = (char*)speex_realloc(bits->chars, nchars); + if (tmp) + { + bits->buf_size=nchars; + bits->chars=tmp; + } else { + nchars=bits->buf_size; + speex_warning("Could not resize input buffer: truncating input"); + } + } else { + speex_warning("Do not own input buffer: truncating oversize input"); + nchars=bits->buf_size; + } + } +#if (BYTES_PER_CHAR==2) +/* Swap bytes to proper endian order (could be done externally) */ +#define HTOLS(A) ((((A) >> 8)&0xff)|(((A) & 0xff)<<8)) +#else +#define HTOLS(A) (A) +#endif + for (i=0;i<nchars;i++) + bits->chars[i]=HTOLS(chars[i]); + + bits->nbBits=nchars<<LOG2_BITS_PER_CHAR; + bits->charPtr=0; + bits->bitPtr=0; + bits->overflow=0; +} + +static void speex_bits_flush(SpeexBits *bits) +{ + int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR); + if (bits->charPtr>0) + SPEEX_MOVE(bits->chars, &bits->chars[bits->charPtr], nchars-bits->charPtr); + bits->nbBits -= bits->charPtr<<LOG2_BITS_PER_CHAR; + bits->charPtr=0; +} + +EXPORT void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes) +{ + int i,pos; + int nchars = nbytes/BYTES_PER_CHAR; + + if (((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR)+nchars > bits->buf_size) + { + /* Packet is larger than allocated buffer */ + if (bits->owner) + { + char *tmp = (char*)speex_realloc(bits->chars, (bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1); + if (tmp) + { + bits->buf_size=(bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1; + bits->chars=tmp; + } else { + nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1; + speex_warning("Could not resize input buffer: truncating oversize input"); + } + } else { + speex_warning("Do not own input buffer: truncating oversize input"); + nchars=bits->buf_size; + } + } + + speex_bits_flush(bits); + pos=bits->nbBits>>LOG2_BITS_PER_CHAR; + for (i=0;i<nchars;i++) + bits->chars[pos+i]=HTOLS(chars[i]); + bits->nbBits+=nchars<<LOG2_BITS_PER_CHAR; +} + +EXPORT int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes) +{ + int i; + int max_nchars = max_nbytes/BYTES_PER_CHAR; + int charPtr, bitPtr, nbBits; + + /* Insert terminator, but save the data so we can put it back after */ + bitPtr=bits->bitPtr; + charPtr=bits->charPtr; + nbBits=bits->nbBits; + speex_bits_insert_terminator(bits); + bits->bitPtr=bitPtr; + bits->charPtr=charPtr; + bits->nbBits=nbBits; + + if (max_nchars > ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR)) + max_nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR); + + for (i=0;i<max_nchars;i++) + chars[i]=HTOLS(bits->chars[i]); + return max_nchars*BYTES_PER_CHAR; +} + +EXPORT int speex_bits_write_whole_bytes(SpeexBits *bits, char *chars, int max_nbytes) +{ + int max_nchars = max_nbytes/BYTES_PER_CHAR; + int i; + if (max_nchars > ((bits->nbBits)>>LOG2_BITS_PER_CHAR)) + max_nchars = ((bits->nbBits)>>LOG2_BITS_PER_CHAR); + for (i=0;i<max_nchars;i++) + chars[i]=HTOLS(bits->chars[i]); + + if (bits->bitPtr>0) + bits->chars[0]=bits->chars[max_nchars]; + else + bits->chars[0]=0; + bits->charPtr=0; + bits->nbBits &= (BITS_PER_CHAR-1); + return max_nchars*BYTES_PER_CHAR; +} + +EXPORT void speex_bits_pack(SpeexBits *bits, int data, int nbBits) +{ + unsigned int d=data; + + if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size) + { + speex_notify("Buffer too small to pack bits"); + if (bits->owner) + { + int new_nchars = ((bits->buf_size+5)*3)>>1; + char *tmp = (char*)speex_realloc(bits->chars, new_nchars); + if (tmp) + { + bits->buf_size=new_nchars; + bits->chars=tmp; + } else { + speex_warning("Could not resize input buffer: not packing"); + return; + } + } else { + speex_warning("Do not own input buffer: not packing"); + return; + } + } + + while(nbBits) + { + int bit; + bit = (d>>(nbBits-1))&1; + bits->chars[bits->charPtr] |= bit<<(BITS_PER_CHAR-1-bits->bitPtr); + bits->bitPtr++; + + if (bits->bitPtr==BITS_PER_CHAR) + { + bits->bitPtr=0; + bits->charPtr++; + bits->chars[bits->charPtr] = 0; + } + bits->nbBits++; + nbBits--; + } +} + +EXPORT int speex_bits_unpack_signed(SpeexBits *bits, int nbBits) +{ + unsigned int d=speex_bits_unpack_unsigned(bits,nbBits); + /* If number is negative */ + if (d>>(nbBits-1)) + { + d |= (-1)<<nbBits; + } + return d; +} + +EXPORT unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits) +{ + unsigned int d=0; + if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits) + bits->overflow=1; + if (bits->overflow) + return 0; + while(nbBits) + { + d<<=1; + d |= (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1; + bits->bitPtr++; + if (bits->bitPtr==BITS_PER_CHAR) + { + bits->bitPtr=0; + bits->charPtr++; + } + nbBits--; + } + return d; +} + +EXPORT unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits) +{ + unsigned int d=0; + int bitPtr, charPtr; + char *chars; + + if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits) + bits->overflow=1; + if (bits->overflow) + return 0; + + bitPtr=bits->bitPtr; + charPtr=bits->charPtr; + chars = bits->chars; + while(nbBits) + { + d<<=1; + d |= (chars[charPtr]>>(BITS_PER_CHAR-1 - bitPtr))&1; + bitPtr++; + if (bitPtr==BITS_PER_CHAR) + { + bitPtr=0; + charPtr++; + } + nbBits--; + } + return d; +} + +EXPORT int speex_bits_peek(SpeexBits *bits) +{ + if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+1>bits->nbBits) + bits->overflow=1; + if (bits->overflow) + return 0; + return (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1; +} + +EXPORT void speex_bits_advance(SpeexBits *bits, int n) +{ + if (((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+n>bits->nbBits) || bits->overflow){ + bits->overflow=1; + return; + } + bits->charPtr += (bits->bitPtr+n) >> LOG2_BITS_PER_CHAR; /* divide by BITS_PER_CHAR */ + bits->bitPtr = (bits->bitPtr+n) & (BITS_PER_CHAR-1); /* modulo by BITS_PER_CHAR */ +} + +EXPORT int speex_bits_remaining(SpeexBits *bits) +{ + if (bits->overflow) + return -1; + else + return bits->nbBits-((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr); +} + +EXPORT int speex_bits_nbytes(SpeexBits *bits) +{ + return ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR); +} + +EXPORT void speex_bits_insert_terminator(SpeexBits *bits) +{ + if (bits->bitPtr) + speex_bits_pack(bits, 0, 1); + while (bits->bitPtr) + speex_bits_pack(bits, 1, 1); +} diff --git a/src/libs/speex/libspeex/buffer.c b/src/libs/speex/libspeex/buffer.c new file mode 100644 index 00000000..242bcd1b --- /dev/null +++ b/src/libs/speex/libspeex/buffer.c @@ -0,0 +1,177 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: buffer.c + This is a very simple ring buffer implementation. It is not thread-safe + so you need to do your own locking. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define EXPORT + +#include "os_support.h" +#include "arch.h" +#include <speex/speex_buffer.h> + +struct SpeexBuffer_ { + char *data; + int size; + int read_ptr; + int write_ptr; + int available; +}; + +EXPORT SpeexBuffer *speex_buffer_init(int size) +{ + SpeexBuffer *st = speex_alloc(sizeof(SpeexBuffer)); + st->data = speex_alloc(size); + st->size = size; + st->read_ptr = 0; + st->write_ptr = 0; + st->available = 0; + return st; +} + +EXPORT void speex_buffer_destroy(SpeexBuffer *st) +{ + speex_free(st->data); + speex_free(st); +} + +EXPORT int speex_buffer_write(SpeexBuffer *st, void *_data, int len) +{ + int end; + int end1; + char *data = _data; + if (len > st->size) + { + data += len-st->size; + len = st->size; + } + end = st->write_ptr + len; + end1 = end; + if (end1 > st->size) + end1 = st->size; + SPEEX_COPY(st->data + st->write_ptr, data, end1 - st->write_ptr); + if (end > st->size) + { + end -= st->size; + SPEEX_COPY(st->data, data+end1 - st->write_ptr, end); + } + st->available += len; + if (st->available > st->size) + { + st->available = st->size; + st->read_ptr = st->write_ptr; + } + st->write_ptr += len; + if (st->write_ptr > st->size) + st->write_ptr -= st->size; + return len; +} + +EXPORT int speex_buffer_writezeros(SpeexBuffer *st, int len) +{ + /* This is almost the same as for speex_buffer_write() but using + SPEEX_MEMSET() instead of SPEEX_COPY(). Update accordingly. */ + int end; + int end1; + if (len > st->size) + { + len = st->size; + } + end = st->write_ptr + len; + end1 = end; + if (end1 > st->size) + end1 = st->size; + SPEEX_MEMSET(st->data + st->write_ptr, 0, end1 - st->write_ptr); + if (end > st->size) + { + end -= st->size; + SPEEX_MEMSET(st->data, 0, end); + } + st->available += len; + if (st->available > st->size) + { + st->available = st->size; + st->read_ptr = st->write_ptr; + } + st->write_ptr += len; + if (st->write_ptr > st->size) + st->write_ptr -= st->size; + return len; +} + +EXPORT int speex_buffer_read(SpeexBuffer *st, void *_data, int len) +{ + int end, end1; + char *data = _data; + if (len > st->available) + { + SPEEX_MEMSET(data+st->available, 0, st->size-st->available); + len = st->available; + } + end = st->read_ptr + len; + end1 = end; + if (end1 > st->size) + end1 = st->size; + SPEEX_COPY(data, st->data + st->read_ptr, end1 - st->read_ptr); + + if (end > st->size) + { + end -= st->size; + SPEEX_COPY(data+end1 - st->read_ptr, st->data, end); + } + st->available -= len; + st->read_ptr += len; + if (st->read_ptr > st->size) + st->read_ptr -= st->size; + return len; +} + +EXPORT int speex_buffer_get_available(SpeexBuffer *st) +{ + return st->available; +} + +EXPORT int speex_buffer_resize(SpeexBuffer *st, int len) +{ + int old_len = st->size; + if (len > old_len) + { + st->data = speex_realloc(st->data, len); + /* FIXME: move data/pointers properly for growing the buffer */ + } else { + /* FIXME: move data/pointers properly for shrinking the buffer */ + st->data = speex_realloc(st->data, len); + } + return len; +} diff --git a/src/libs/speex/libspeex/cb_search.c b/src/libs/speex/libspeex/cb_search.c new file mode 100644 index 00000000..63f4c6a4 --- /dev/null +++ b/src/libs/speex/libspeex/cb_search.c @@ -0,0 +1,612 @@ +/* Copyright (C) 2002-2006 Jean-Marc Valin + File: cb_search.c + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "cb_search.h" +#include "filters.h" +#include "stack_alloc.h" +#include "vq.h" +#include "arch.h" +#include "math_approx.h" +#include "os_support.h" + +#ifdef _USE_SSE +#include "cb_search_sse.h" +#elif defined(ARM4_ASM) || defined(ARM5E_ASM) +#include "cb_search_arm4.h" +#elif defined(BFIN_ASM) +#include "cb_search_bfin.h" +#endif + +#ifndef OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK +static void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack) +{ + int i, j, k; + VARDECL(spx_word16_t *shape); + ALLOC(shape, subvect_size, spx_word16_t); + for (i=0;i<shape_cb_size;i++) + { + spx_word16_t *res; + + res = resp+i*subvect_size; + for (k=0;k<subvect_size;k++) + shape[k] = (spx_word16_t)shape_cb[i*subvect_size+k]; + E[i]=0; + + /* Compute codeword response using convolution with impulse response */ + for(j=0;j<subvect_size;j++) + { + spx_word32_t resj=0; + spx_word16_t res16; + for (k=0;k<=j;k++) + resj = MAC16_16(resj,shape[k],r[j-k]); +#ifdef FIXED_POINT + res16 = EXTRACT16(SHR32(resj, 13)); +#else + res16 = 0.03125f*resj; +#endif + /* Compute codeword energy */ + E[i]=MAC16_16(E[i],res16,res16); + res[j] = res16; + /*printf ("%d\n", (int)res[j]);*/ + } + } + +} +#endif + +#ifndef OVERRIDE_TARGET_UPDATE +static inline void target_update(spx_word16_t *t, spx_word16_t g, spx_word16_t *r, int len) +{ + int n; + for (n=0;n<len;n++) + t[n] = SUB16(t[n],PSHR32(MULT16_16(g,r[n]),13)); +} +#endif + + + +static void split_cb_search_shape_sign_N1( +spx_word16_t target[], /* target vector */ +spx_coef_t ak[], /* LPCs for this subframe */ +spx_coef_t awk1[], /* Weighted LPCs for this subframe */ +spx_coef_t awk2[], /* Weighted LPCs for this subframe */ +const void *par, /* Codebook/search parameters*/ +int p, /* number of LPC coeffs */ +int nsf, /* number of samples in subframe */ +spx_sig_t *exc, +spx_word16_t *r, +SpeexBits *bits, +char *stack, +int update_target +) +{ + int i,j,m,q; + VARDECL(spx_word16_t *resp); +#ifdef _USE_SSE + VARDECL(__m128 *resp2); + VARDECL(__m128 *E); +#else + spx_word16_t *resp2; + VARDECL(spx_word32_t *E); +#endif + VARDECL(spx_word16_t *t); + VARDECL(spx_sig_t *e); + const signed char *shape_cb; + int shape_cb_size, subvect_size, nb_subvect; + const split_cb_params *params; + int best_index; + spx_word32_t best_dist; + int have_sign; + + params = (const split_cb_params *) par; + subvect_size = params->subvect_size; + nb_subvect = params->nb_subvect; + shape_cb_size = 1<<params->shape_bits; + shape_cb = params->shape_cb; + have_sign = params->have_sign; + ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t); +#ifdef _USE_SSE + ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128); + ALLOC(E, shape_cb_size>>2, __m128); +#else + resp2 = resp; + ALLOC(E, shape_cb_size, spx_word32_t); +#endif + ALLOC(t, nsf, spx_word16_t); + ALLOC(e, nsf, spx_sig_t); + + /* FIXME: Do we still need to copy the target? */ + SPEEX_COPY(t, target, nsf); + + compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack); + + for (i=0;i<nb_subvect;i++) + { + spx_word16_t *x=t+subvect_size*i; + /*Find new n-best based on previous n-best j*/ + if (have_sign) + vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack); + else + vq_nbest(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack); + + speex_bits_pack(bits,best_index,params->shape_bits+have_sign); + + { + int rind; + spx_word16_t *res; + spx_word16_t sign=1; + rind = best_index; + if (rind>=shape_cb_size) + { + sign=-1; + rind-=shape_cb_size; + } + res = resp+rind*subvect_size; + if (sign>0) + for (m=0;m<subvect_size;m++) + t[subvect_size*i+m] = SUB16(t[subvect_size*i+m], res[m]); + else + for (m=0;m<subvect_size;m++) + t[subvect_size*i+m] = ADD16(t[subvect_size*i+m], res[m]); + +#ifdef FIXED_POINT + if (sign==1) + { + for (j=0;j<subvect_size;j++) + e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5); + } else { + for (j=0;j<subvect_size;j++) + e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5)); + } +#else + for (j=0;j<subvect_size;j++) + e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j]; +#endif + + } + + for (m=0;m<subvect_size;m++) + { + spx_word16_t g; + int rind; + spx_word16_t sign=1; + rind = best_index; + if (rind>=shape_cb_size) + { + sign=-1; + rind-=shape_cb_size; + } + + q=subvect_size-m; +#ifdef FIXED_POINT + g=sign*shape_cb[rind*subvect_size+m]; +#else + g=sign*0.03125*shape_cb[rind*subvect_size+m]; +#endif + target_update(t+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1)); + } + } + + /* Update excitation */ + /* FIXME: We could update the excitation directly above */ + for (j=0;j<nsf;j++) + exc[j]=ADD32(exc[j],e[j]); + + /* Update target: only update target if necessary */ + if (update_target) + { + VARDECL(spx_word16_t *r2); + ALLOC(r2, nsf, spx_word16_t); + for (j=0;j<nsf;j++) + r2[j] = EXTRACT16(PSHR32(e[j] ,6)); + syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack); + for (j=0;j<nsf;j++) + target[j]=SUB16(target[j],PSHR16(r2[j],2)); + } +} + + + +void split_cb_search_shape_sign( +spx_word16_t target[], /* target vector */ +spx_coef_t ak[], /* LPCs for this subframe */ +spx_coef_t awk1[], /* Weighted LPCs for this subframe */ +spx_coef_t awk2[], /* Weighted LPCs for this subframe */ +const void *par, /* Codebook/search parameters*/ +int p, /* number of LPC coeffs */ +int nsf, /* number of samples in subframe */ +spx_sig_t *exc, +spx_word16_t *r, +SpeexBits *bits, +char *stack, +int complexity, +int update_target +) +{ + int i,j,k,m,n,q; + VARDECL(spx_word16_t *resp); +#ifdef _USE_SSE + VARDECL(__m128 *resp2); + VARDECL(__m128 *E); +#else + spx_word16_t *resp2; + VARDECL(spx_word32_t *E); +#endif + VARDECL(spx_word16_t *t); + VARDECL(spx_sig_t *e); + VARDECL(spx_word16_t *tmp); + VARDECL(spx_word32_t *ndist); + VARDECL(spx_word32_t *odist); + VARDECL(int *itmp); + VARDECL(spx_word16_t **ot2); + VARDECL(spx_word16_t **nt2); + spx_word16_t **ot, **nt; + VARDECL(int **nind); + VARDECL(int **oind); + VARDECL(int *ind); + const signed char *shape_cb; + int shape_cb_size, subvect_size, nb_subvect; + const split_cb_params *params; + int N=2; + VARDECL(int *best_index); + VARDECL(spx_word32_t *best_dist); + VARDECL(int *best_nind); + VARDECL(int *best_ntarget); + int have_sign; + N=complexity; + if (N>10) + N=10; + /* Complexity isn't as important for the codebooks as it is for the pitch */ + N=(2*N)/3; + if (N<1) + N=1; + if (N==1) + { + split_cb_search_shape_sign_N1(target,ak,awk1,awk2,par,p,nsf,exc,r,bits,stack,update_target); + return; + } + ALLOC(ot2, N, spx_word16_t*); + ALLOC(nt2, N, spx_word16_t*); + ALLOC(oind, N, int*); + ALLOC(nind, N, int*); + + params = (const split_cb_params *) par; + subvect_size = params->subvect_size; + nb_subvect = params->nb_subvect; + shape_cb_size = 1<<params->shape_bits; + shape_cb = params->shape_cb; + have_sign = params->have_sign; + ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t); +#ifdef _USE_SSE + ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128); + ALLOC(E, shape_cb_size>>2, __m128); +#else + resp2 = resp; + ALLOC(E, shape_cb_size, spx_word32_t); +#endif + ALLOC(t, nsf, spx_word16_t); + ALLOC(e, nsf, spx_sig_t); + ALLOC(ind, nb_subvect, int); + + ALLOC(tmp, 2*N*nsf, spx_word16_t); + for (i=0;i<N;i++) + { + ot2[i]=tmp+2*i*nsf; + nt2[i]=tmp+(2*i+1)*nsf; + } + ot=ot2; + nt=nt2; + ALLOC(best_index, N, int); + ALLOC(best_dist, N, spx_word32_t); + ALLOC(best_nind, N, int); + ALLOC(best_ntarget, N, int); + ALLOC(ndist, N, spx_word32_t); + ALLOC(odist, N, spx_word32_t); + + ALLOC(itmp, 2*N*nb_subvect, int); + for (i=0;i<N;i++) + { + nind[i]=itmp+2*i*nb_subvect; + oind[i]=itmp+(2*i+1)*nb_subvect; + } + + SPEEX_COPY(t, target, nsf); + + for (j=0;j<N;j++) + SPEEX_COPY(&ot[j][0], t, nsf); + + /* Pre-compute codewords response and energy */ + compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack); + + for (j=0;j<N;j++) + odist[j]=0; + + /*For all subvectors*/ + for (i=0;i<nb_subvect;i++) + { + /*"erase" nbest list*/ + for (j=0;j<N;j++) + ndist[j]=VERY_LARGE32; + /* This is not strictly necessary, but it provides an additonal safety + to prevent crashes in case something goes wrong in the previous + steps (e.g. NaNs) */ + for (j=0;j<N;j++) + best_nind[j] = best_ntarget[j] = 0; + /*For all n-bests of previous subvector*/ + for (j=0;j<N;j++) + { + spx_word16_t *x=ot[j]+subvect_size*i; + spx_word32_t tener = 0; + for (m=0;m<subvect_size;m++) + tener = MAC16_16(tener, x[m],x[m]); +#ifdef FIXED_POINT + tener = SHR32(tener,1); +#else + tener *= .5; +#endif + /*Find new n-best based on previous n-best j*/ + if (have_sign) + vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack); + else + vq_nbest(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack); + + /*For all new n-bests*/ + for (k=0;k<N;k++) + { + /* Compute total distance (including previous sub-vectors */ + spx_word32_t err = ADD32(ADD32(odist[j],best_dist[k]),tener); + + /*update n-best list*/ + if (err<ndist[N-1]) + { + for (m=0;m<N;m++) + { + if (err < ndist[m]) + { + for (n=N-1;n>m;n--) + { + ndist[n] = ndist[n-1]; + best_nind[n] = best_nind[n-1]; + best_ntarget[n] = best_ntarget[n-1]; + } + /* n is equal to m here, so they're interchangeable */ + ndist[m] = err; + best_nind[n] = best_index[k]; + best_ntarget[n] = j; + break; + } + } + } + } + if (i==0) + break; + } + for (j=0;j<N;j++) + { + /*previous target (we don't care what happened before*/ + for (m=(i+1)*subvect_size;m<nsf;m++) + nt[j][m]=ot[best_ntarget[j]][m]; + + /* New code: update the rest of the target only if it's worth it */ + for (m=0;m<subvect_size;m++) + { + spx_word16_t g; + int rind; + spx_word16_t sign=1; + rind = best_nind[j]; + if (rind>=shape_cb_size) + { + sign=-1; + rind-=shape_cb_size; + } + + q=subvect_size-m; +#ifdef FIXED_POINT + g=sign*shape_cb[rind*subvect_size+m]; +#else + g=sign*0.03125*shape_cb[rind*subvect_size+m]; +#endif + target_update(nt[j]+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1)); + } + + for (q=0;q<nb_subvect;q++) + nind[j][q]=oind[best_ntarget[j]][q]; + nind[j][i]=best_nind[j]; + } + + /*update old-new data*/ + /* just swap pointers instead of a long copy */ + { + spx_word16_t **tmp2; + tmp2=ot; + ot=nt; + nt=tmp2; + } + for (j=0;j<N;j++) + for (m=0;m<nb_subvect;m++) + oind[j][m]=nind[j][m]; + for (j=0;j<N;j++) + odist[j]=ndist[j]; + } + + /*save indices*/ + for (i=0;i<nb_subvect;i++) + { + ind[i]=nind[0][i]; + speex_bits_pack(bits,ind[i],params->shape_bits+have_sign); + } + + /* Put everything back together */ + for (i=0;i<nb_subvect;i++) + { + int rind; + spx_word16_t sign=1; + rind = ind[i]; + if (rind>=shape_cb_size) + { + sign=-1; + rind-=shape_cb_size; + } +#ifdef FIXED_POINT + if (sign==1) + { + for (j=0;j<subvect_size;j++) + e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5); + } else { + for (j=0;j<subvect_size;j++) + e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5)); + } +#else + for (j=0;j<subvect_size;j++) + e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j]; +#endif + } + /* Update excitation */ + for (j=0;j<nsf;j++) + exc[j]=ADD32(exc[j],e[j]); + + /* Update target: only update target if necessary */ + if (update_target) + { + VARDECL(spx_word16_t *r2); + ALLOC(r2, nsf, spx_word16_t); + for (j=0;j<nsf;j++) + r2[j] = EXTRACT16(PSHR32(e[j] ,6)); + syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack); + for (j=0;j<nsf;j++) + target[j]=SUB16(target[j],PSHR16(r2[j],2)); + } +} + + +void split_cb_shape_sign_unquant( +spx_sig_t *exc, +const void *par, /* non-overlapping codebook */ +int nsf, /* number of samples in subframe */ +SpeexBits *bits, +char *stack, +spx_int32_t *seed +) +{ + int i,j; + VARDECL(int *ind); + VARDECL(int *signs); + const signed char *shape_cb; + int shape_cb_size, subvect_size, nb_subvect; + const split_cb_params *params; + int have_sign; + + params = (const split_cb_params *) par; + subvect_size = params->subvect_size; + nb_subvect = params->nb_subvect; + shape_cb_size = 1<<params->shape_bits; + shape_cb = params->shape_cb; + have_sign = params->have_sign; + + ALLOC(ind, nb_subvect, int); + ALLOC(signs, nb_subvect, int); + + /* Decode codewords and gains */ + for (i=0;i<nb_subvect;i++) + { + if (have_sign) + signs[i] = speex_bits_unpack_unsigned(bits, 1); + else + signs[i] = 0; + ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits); + } + /* Compute decoded excitation */ + for (i=0;i<nb_subvect;i++) + { + spx_word16_t s=1; + if (signs[i]) + s=-1; +#ifdef FIXED_POINT + if (s==1) + { + for (j=0;j<subvect_size;j++) + exc[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5); + } else { + for (j=0;j<subvect_size;j++) + exc[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5)); + } +#else + for (j=0;j<subvect_size;j++) + exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j]; +#endif + } +} + +void noise_codebook_quant( +spx_word16_t target[], /* target vector */ +spx_coef_t ak[], /* LPCs for this subframe */ +spx_coef_t awk1[], /* Weighted LPCs for this subframe */ +spx_coef_t awk2[], /* Weighted LPCs for this subframe */ +const void *par, /* Codebook/search parameters*/ +int p, /* number of LPC coeffs */ +int nsf, /* number of samples in subframe */ +spx_sig_t *exc, +spx_word16_t *r, +SpeexBits *bits, +char *stack, +int complexity, +int update_target +) +{ + int i; + VARDECL(spx_word16_t *tmp); + ALLOC(tmp, nsf, spx_word16_t); + residue_percep_zero16(target, ak, awk1, awk2, tmp, nsf, p, stack); + + for (i=0;i<nsf;i++) + exc[i]+=SHL32(EXTEND32(tmp[i]),8); + SPEEX_MEMSET(target, 0, nsf); +} + + +void noise_codebook_unquant( +spx_sig_t *exc, +const void *par, /* non-overlapping codebook */ +int nsf, /* number of samples in subframe */ +SpeexBits *bits, +char *stack, +spx_int32_t *seed +) +{ + int i; + /* FIXME: This is bad, but I don't think the function ever gets called anyway */ + for (i=0;i<nsf;i++) + exc[i]=SHL32(EXTEND32(speex_rand(1, seed)),SIG_SHIFT); +} diff --git a/src/libs/speex/libspeex/cb_search.h b/src/libs/speex/libspeex/cb_search.h new file mode 100644 index 00000000..7687b453 --- /dev/null +++ b/src/libs/speex/libspeex/cb_search.h @@ -0,0 +1,103 @@ +/* Copyright (C) 2002 Jean-Marc Valin & David Rowe */ +/** + @file cb_search.h + @brief Overlapped codebook search +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CB_SEARCH_H +#define CB_SEARCH_H + +#include <speex/speex_bits.h> +#include "arch.h" + +/** Split codebook parameters. */ +typedef struct split_cb_params { + int subvect_size; + int nb_subvect; + const signed char *shape_cb; + int shape_bits; + int have_sign; +} split_cb_params; + + +void split_cb_search_shape_sign( +spx_word16_t target[], /* target vector */ +spx_coef_t ak[], /* LPCs for this subframe */ +spx_coef_t awk1[], /* Weighted LPCs for this subframe */ +spx_coef_t awk2[], /* Weighted LPCs for this subframe */ +const void *par, /* Codebook/search parameters */ +int p, /* number of LPC coeffs */ +int nsf, /* number of samples in subframe */ +spx_sig_t *exc, +spx_word16_t *r, +SpeexBits *bits, +char *stack, +int complexity, +int update_target +); + +void split_cb_shape_sign_unquant( +spx_sig_t *exc, +const void *par, /* non-overlapping codebook */ +int nsf, /* number of samples in subframe */ +SpeexBits *bits, +char *stack, +spx_int32_t *seed +); + + +void noise_codebook_quant( +spx_word16_t target[], /* target vector */ +spx_coef_t ak[], /* LPCs for this subframe */ +spx_coef_t awk1[], /* Weighted LPCs for this subframe */ +spx_coef_t awk2[], /* Weighted LPCs for this subframe */ +const void *par, /* Codebook/search parameters */ +int p, /* number of LPC coeffs */ +int nsf, /* number of samples in subframe */ +spx_sig_t *exc, +spx_word16_t *r, +SpeexBits *bits, +char *stack, +int complexity, +int update_target +); + + +void noise_codebook_unquant( +spx_sig_t *exc, +const void *par, /* non-overlapping codebook */ +int nsf, /* number of samples in subframe */ +SpeexBits *bits, +char *stack, +spx_int32_t *seed +); + +#endif diff --git a/src/libs/speex/libspeex/cb_search_arm4.h b/src/libs/speex/libspeex/cb_search_arm4.h new file mode 100644 index 00000000..19b752a4 --- /dev/null +++ b/src/libs/speex/libspeex/cb_search_arm4.h @@ -0,0 +1,137 @@ +/* Copyright (C) 2004 Jean-Marc Valin */ +/** + @file cb_search_arm4.h + @brief Fixed codebook functions (ARM4 version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* This optimization is temporaly disabled until it is fixed to account for the fact + that "r" is now a 16-bit array */ +#if 0 +#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK +static void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack) +{ + int i, j, k; + //const signed char *shape; + for (i=0;i<shape_cb_size;i+=4) + { + + //shape = shape_cb; + E[0]=0; + E[1]=0; + E[2]=0; + E[3]=0; + + /* Compute codeword response using convolution with impulse response */ + for(j=0;j<subvect_size;j++) + { +#if 1 + spx_word16_t *res; + res = resp+j; + spx_word32_t resj0,resj1,resj2,resj3; + spx_word32_t dead1, dead2, dead3, dead4, dead5, dead6, dead7, dead8; + __asm__ __volatile__ ( + "mov %0, #0 \n\t" + "mov %1, #0 \n\t" + "mov %2, #0 \n\t" + "mov %3, #0 \n\t" + ".weighted%=: \n\t" + "ldrsb %8, [%6] \n\t" + "ldr %10, [%5], #-4 \n\t" + "mov %9, %6 \n\t" + "ldrsb %11, [%9, %7]! \n\t" + "mla %0, %10, %8, %0 \n\t" + "ldrsb %8, [%9, %7]! \n\t" + "mla %1, %10, %11, %1 \n\t" + "ldrsb %11, [%9, %7]! \n\t" + "mla %2, %10, %8, %2 \n\t" + "subs %4, %4, #1 \n\t" + "mla %3, %10, %11, %3 \n\t" + "add %6, %6, #1 \n\t" + "bne .weighted%= \n\t" + : "=r" (resj0), "=r" (resj1), "=r" (resj2), "=r" (resj3), + "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4), + "=r" (dead5), "=r" (dead6), "=r" (dead7), "=r" (dead8) + : "4" (j+1), "5" (r+j), "6" (shape_cb), "7" (subvect_size) + : "cc", "memory"); +#else + spx_word16_t *res; + res = resp+j; + spx_word32_t resj0=0; + spx_word32_t resj1=0; + spx_word32_t resj2=0; + spx_word32_t resj3=0; + for (k=0;k<=j;k++) + { + const signed char *shape=shape_cb+k; + resj0 = MAC16_16(resj0,*shape,r[j-k]); + shape += subvect_size; + resj1 = MAC16_16(resj1,*shape,r[j-k]); + shape += subvect_size; + resj2 = MAC16_16(resj2,*shape,r[j-k]); + shape += subvect_size; + resj3 = MAC16_16(resj3,*shape,r[j-k]); + shape += subvect_size; + } +#endif + +#ifdef FIXED_POINT + resj0 = SHR(resj0, 11); + resj1 = SHR(resj1, 11); + resj2 = SHR(resj2, 11); + resj3 = SHR(resj3, 11); +#else + resj0 *= 0.03125; + resj1 *= 0.03125; + resj2 *= 0.03125; + resj3 *= 0.03125; +#endif + + /* Compute codeword energy */ + E[0]=ADD32(E[0],MULT16_16(resj0,resj0)); + E[1]=ADD32(E[1],MULT16_16(resj1,resj1)); + E[2]=ADD32(E[2],MULT16_16(resj2,resj2)); + E[3]=ADD32(E[3],MULT16_16(resj3,resj3)); + *res = resj0; + res += subvect_size; + *res = resj1; + res += subvect_size; + *res = resj2; + res += subvect_size; + *res = resj3; + res += subvect_size; + } + resp += subvect_size<<2; + shape_cb += subvect_size<<2; + E+=4; + } + +} +#endif diff --git a/src/libs/speex/libspeex/cb_search_bfin.h b/src/libs/speex/libspeex/cb_search_bfin.h new file mode 100644 index 00000000..ae9cf834 --- /dev/null +++ b/src/libs/speex/libspeex/cb_search_bfin.h @@ -0,0 +1,112 @@ +/* Copyright (C) 2005 Analog Devices */ +/** + @author Jean-Marc Valin + @file cb_search_bfin.h + @brief Fixed codebook functions (Blackfin version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK +void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack) +{ + int i; + for (i=0;i<shape_cb_size;i++) + { + __asm__ __volatile__ ( + "P0 = %0;\n\t" + "LC0 = P0;\n\t" + "P1 = %1;\n\t" + "P2 = %2;\n\t" + "P3 = %3;\n\t" + "P0 = 1;\n\t" + "L0 = 0;\n\t" + "L1 = 0;\n\t" + "R2 = 0;\n\t" + "A1 = 0;\n\t" + "LOOP outter%= LC0;\n\t" + "LOOP_BEGIN outter%=;\n\t" + "A0 = 0;\n\t" + "P4 = P1;\n\t" + "I1 = P2;\n\t" + "R0 = B[P4++] (X) || R1.L = W[I1--];\n\t" + "LOOP inner%= LC1 = P0;\n\t" + "LOOP_BEGIN inner%=;\n\t" + "A0 += R0.L*R1.L (IS) || R0 = B[P4++] (X) || R1.L = W[I1--];\n\t" + "LOOP_END inner%=;\n\t" + "R0 = A0;\n\t" + "R0 >>>= 13;\n\t" + "A1 += R0.L*R0.L (IS);\n\t" + "W[P3++] = R0;\n\t" + "P0 += 1;\n\t" + "P2 += 2;\n\t" + "LOOP_END outter%=;\n\t" + "P4 = %4;\n\t" + "R1 = A1;\n\t" + "[P4] = R1;\n\t" + : + : "m" (subvect_size), "m" (shape_cb), "m" (r), "m" (resp), "m" (E) + : "A0", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "I0", "I1", "L0", + "L1", "A0", "A1", "memory" +#if !(__GNUC__ == 3) + , "LC0", "LC1" /* gcc 3.4 doesn't know about LC registers */ +#endif + ); + shape_cb += subvect_size; + resp += subvect_size; + E++; + } +} + +#define OVERRIDE_TARGET_UPDATE +static inline void target_update(spx_word16_t *t, spx_word16_t g, spx_word16_t *r, int len) +{ + if (!len) + return; + __asm__ __volatile__ + ( + "I0 = %0;\n\t" + "I1 = %1;\n\t" + "L0 = 0;\n\t" + "L1 = 0;\n\t" + "R2 = 4096;\n\t" + "LOOP tupdate%= LC0 = %3;\n\t" + "LOOP_BEGIN tupdate%=;\n\t" + "R0.L = W[I0] || R1.L = W[I1++];\n\t" + "R1 = (A1 = R1.L*%2.L) (IS);\n\t" + "R1 = R1 + R2;\n\t" + "R1 >>>= 13;\n\t" + "R0.L = R0.L - R1.L;\n\t" + "W[I0++] = R0.L;\n\t" + "LOOP_END tupdate%=;\n\t" + : + : "a" (t), "a" (r), "d" (g), "a" (len) + : "R0", "R1", "R2", "A1", "I0", "I1", "L0", "L1" + ); +} diff --git a/src/libs/speex/libspeex/cb_search_sse.h b/src/libs/speex/libspeex/cb_search_sse.h new file mode 100644 index 00000000..8b039686 --- /dev/null +++ b/src/libs/speex/libspeex/cb_search_sse.h @@ -0,0 +1,84 @@ +/* Copyright (C) 2004 Jean-Marc Valin */ +/** + @file cb_search_sse.h + @brief Fixed codebook functions (SSE version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <xmmintrin.h> + +static inline void _spx_mm_getr_ps (__m128 U, float *__Z, float *__Y, float *__X, float *__W) +{ + union { + float __a[4]; + __m128 __v; + } __u; + + __u.__v = U; + + *__Z = __u.__a[0]; + *__Y = __u.__a[1]; + *__X = __u.__a[2]; + *__W = __u.__a[3]; + +} + +#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK +static void compute_weighted_codebook(const signed char *shape_cb, const spx_sig_t *_r, float *resp, __m128 *resp2, __m128 *E, int shape_cb_size, int subvect_size, char *stack) +{ + int i, j, k; + __m128 resj, EE; + VARDECL(__m128 *r); + VARDECL(__m128 *shape); + ALLOC(r, subvect_size, __m128); + ALLOC(shape, subvect_size, __m128); + for(j=0;j<subvect_size;j++) + r[j] = _mm_load_ps1(_r+j); + for (i=0;i<shape_cb_size;i+=4) + { + float *_res = resp+i*subvect_size; + const signed char *_shape = shape_cb+i*subvect_size; + EE = _mm_setzero_ps(); + for(j=0;j<subvect_size;j++) + { + shape[j] = _mm_setr_ps(0.03125*_shape[j], 0.03125*_shape[subvect_size+j], 0.03125*_shape[2*subvect_size+j], 0.03125*_shape[3*subvect_size+j]); + } + for(j=0;j<subvect_size;j++) + { + resj = _mm_setzero_ps(); + for (k=0;k<=j;k++) + resj = _mm_add_ps(resj, _mm_mul_ps(shape[k],r[j-k])); + _spx_mm_getr_ps(resj, _res+j, _res+subvect_size+j, _res+2*subvect_size+j, _res+3*subvect_size+j); + *resp2++ = resj; + EE = _mm_add_ps(EE, _mm_mul_ps(resj, resj)); + } + E[i>>2] = EE; + } +} diff --git a/src/libs/speex/libspeex/exc_10_16_table.c b/src/libs/speex/libspeex/exc_10_16_table.c new file mode 100644 index 00000000..98ae357d --- /dev/null +++ b/src/libs/speex/libspeex/exc_10_16_table.c @@ -0,0 +1,50 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: exc_10_16_table.c + Codebook for excitation in narrowband CELP mode (3200 bps) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +const signed char exc_10_16_table[160] = { +22,39,14,44,11,35,-2,23,-4,6, +46,-28,13,-27,-23,12,4,20,-5,9, +37,-18,-23,23,0,9,-6,-20,4,-1, +-17,-5,-4,17,0,1,9,-2,1,2, +2,-12,8,-25,39,15,9,16,-55,-11, +9,11,5,10,-2,-60,8,13,-6,11, +-16,27,-47,-12,11,1,16,-7,9,-3, +-29,9,-14,25,-19,34,36,12,40,-10, +-3,-24,-14,-37,-21,-35,-2,-36,3,-6, +67,28,6,-17,-3,-12,-16,-15,-17,-7, +-59,-36,-13,1,7,1,2,10,2,11, +13,10,8,-2,7,3,5,4,2,2, +-3,-8,4,-5,6,7,-42,15,35,-2, +-46,38,28,-20,-9,1,7,-3,0,-2, +0,0,0,0,0,0,0,0,0,0, +-15,-28,52,32,5,-5,-17,-20,-10,-1}; diff --git a/src/libs/speex/libspeex/exc_10_32_table.c b/src/libs/speex/libspeex/exc_10_32_table.c new file mode 100644 index 00000000..1ee56a25 --- /dev/null +++ b/src/libs/speex/libspeex/exc_10_32_table.c @@ -0,0 +1,66 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: exc_10_32_table.c + Codebook for excitation in narrowband CELP mode (4000 bps) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +const signed char exc_10_32_table[320] = { +7,17,17,27,25,22,12,4,-3,0, +28,-36,39,-24,-15,3,-9,15,-5,10, +31,-28,11,31,-21,9,-11,-11,-2,-7, +-25,14,-22,31,4,-14,19,-12,14,-5, +4,-7,4,-5,9,0,-2,42,-47,-16, +1,8,0,9,23,-57,0,28,-11,6, +-31,55,-45,3,-5,4,2,-2,4,-7, +-3,6,-2,7,-3,12,5,8,54,-10, +8,-7,-8,-24,-25,-27,-14,-5,8,5, +44,23,5,-9,-11,-11,-13,-9,-12,-8, +-29,-8,-22,6,-15,3,-12,-1,-5,-3, +34,-1,29,-16,17,-4,12,2,1,4, +-2,-4,2,-1,11,-3,-52,28,30,-9, +-32,25,44,-20,-24,4,6,-1,0,0, +0,0,0,0,0,0,0,0,0,0, +-25,-10,22,29,13,-13,-22,-13,-4,0, +-4,-16,10,15,-36,-24,28,25,-1,-3, +66,-33,-11,-15,6,0,3,4,-2,5, +24,-20,-47,29,19,-2,-4,-1,0,-1, +-2,3,1,8,-11,5,5,-57,28,28, +0,-16,4,-4,12,-6,-1,2,-20,61, +-9,24,-22,-42,29,6,17,8,4,2, +-65,15,8,10,5,6,5,3,2,-2, +-3,5,-9,4,-5,23,13,23,-3,-63, +3,-5,-4,-6,0,-3,23,-36,-46,9, +5,5,8,4,9,-5,1,-3,10,1, +-6,10,-11,24,-47,31,22,-12,14,-10, +6,11,-7,-7,7,-31,51,-12,-6,7, +6,-17,9,-11,-20,52,-19,3,-6,-6, +-8,-5,23,-41,37,1,-21,10,-14,8, +7,5,-15,-15,23,39,-26,-33,7,2, +-32,-30,-21,-8,4,12,17,15,14,11}; diff --git a/src/libs/speex/libspeex/exc_20_32_table.c b/src/libs/speex/libspeex/exc_20_32_table.c new file mode 100644 index 00000000..e4098b8d --- /dev/null +++ b/src/libs/speex/libspeex/exc_20_32_table.c @@ -0,0 +1,66 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: exc_20_32_table.c + Codebook for excitation in narrowband CELP mode (2000 bps) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +const signed char exc_20_32_table[640] = { +12,32,25,46,36,33,9,14,-3,6,1,-8,0,-10,-5,-7,-7,-7,-5,-5, +31,-27,24,-32,-4,10,-11,21,-3,19,23,-9,22,24,-10,-1,-10,-13,-7,-11, +42,-33,31,19,-8,0,-10,-16,1,-21,-17,10,-8,14,8,4,11,-2,5,-2, +-33,11,-16,33,11,-4,9,-4,11,2,6,-5,8,-5,11,-4,-6,26,-36,-16, +0,4,-2,-8,12,6,-1,34,-46,-22,9,9,21,9,5,-66,-5,26,2,10, +13,2,19,9,12,-81,3,13,13,0,-14,22,-35,6,-7,-4,6,-6,10,-6, +-31,38,-33,0,-10,-11,5,-12,12,-17,5,0,-6,13,-9,10,8,25,33,2, +-12,8,-6,10,-2,21,7,17,43,5,11,-7,-9,-20,-36,-20,-23,-4,-4,-3, +27,-9,-9,-49,-39,-38,-11,-9,6,5,23,25,5,3,3,4,1,2,-3,-1, +87,39,17,-21,-9,-19,-9,-15,-13,-14,-17,-11,-10,-11,-8,-6,-1,-3,-3,-1, +-54,-34,-27,-8,-11,-4,-5,0,0,4,8,6,9,7,9,7,6,5,5,5, +48,10,19,-10,12,-1,9,-3,2,5,-3,2,-2,-2,0,-2,-26,6,9,-7, +-16,-9,2,7,7,-5,-43,11,22,-11,-9,34,37,-15,-13,-6,1,-1,1,1, +-64,56,52,-11,-27,5,4,3,1,2,1,3,-1,-4,-4,-10,-7,-4,-4,2, +-1,-7,-7,-12,-10,-15,-9,-5,-5,-11,-16,-13,6,16,4,-13,-16,-10,-4,2, +-47,-13,25,47,19,-14,-20,-8,-17,0,-3,-13,1,6,-17,-14,15,1,10,6, +-24,0,-10,19,-69,-8,14,49,17,-5,33,-29,3,-4,0,2,-8,5,-6,2, +120,-56,-12,-47,23,-9,6,-5,1,2,-5,1,-10,4,-1,-1,4,-1,0,-3, +30,-52,-67,30,22,11,-1,-4,3,0,7,2,0,1,-10,-4,-8,-13,5,1, +1,-1,5,13,-9,-3,-10,-62,22,48,-4,-6,2,3,5,1,1,4,1,13, +3,-20,10,-9,13,-2,-4,9,-20,44,-1,20,-32,-67,19,0,28,11,8,2, +-11,15,-19,-53,31,2,34,10,6,-4,-58,8,10,13,14,1,12,2,0,0, +-128,37,-8,44,-9,26,-3,18,2,6,11,-1,9,1,5,3,0,1,1,2, +12,3,-2,-3,7,25,9,18,-6,-37,3,-8,-16,3,-10,-7,17,-34,-44,11, +17,-15,-3,-16,-1,-13,11,-46,-65,-2,8,13,2,4,4,5,15,5,9,6, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +-9,19,-12,12,-28,38,29,-1,12,2,5,23,-10,3,4,-15,21,-4,3,3, +6,17,-9,-4,-8,-20,26,5,-10,6,1,-19,18,-15,-12,47,-6,-2,-7,-9, +-1,-17,-2,-2,-14,30,-14,2,-7,-4,-1,-12,11,-25,16,-3,-12,11,-7,7, +-17,1,19,-28,31,-7,-10,7,-10,3,12,5,-16,6,24,41,-29,-54,0,1, +7,-1,5,-6,13,10,-4,-8,8,-9,-27,-53,-38,-1,10,19,17,16,12,12, +0,3,-7,-4,13,12,-31,-14,6,-5,3,5,17,43,50,25,10,1,-6,-2}; diff --git a/src/libs/speex/libspeex/exc_5_256_table.c b/src/libs/speex/libspeex/exc_5_256_table.c new file mode 100644 index 00000000..4137996d --- /dev/null +++ b/src/libs/speex/libspeex/exc_5_256_table.c @@ -0,0 +1,290 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: exc_5_256_table.c + Codebook for excitation in narrowband CELP mode (12800 bps) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +const signed char exc_5_256_table[1280] = { +-8,-37,5,-43,5, +73,61,39,12,-3, +-61,-32,2,42,30, +-3,17,-27,9,34, +20,-1,-5,2,23, +-7,-46,26,53,-47, +20,-2,-33,-89,-51, +-64,27,11,15,-34, +-5,-56,25,-9,-1, +-29,1,40,67,-23, +-16,16,33,19,7, +14,85,22,-10,-10, +-12,-7,-1,52,89, +29,11,-20,-37,-46, +-15,17,-24,-28,24, +2,1,0,23,-101, +23,14,-1,-23,-18, +9,5,-13,38,1, +-28,-28,4,27,51, +-26,34,-40,35,47, +54,38,-54,-26,-6, +42,-25,13,-30,-36, +18,41,-4,-33,23, +-32,-7,-4,51,-3, +17,-52,56,-47,36, +-2,-21,36,10,8, +-33,31,19,9,-5, +-40,10,-9,-21,19, +18,-78,-18,-5,0, +-26,-36,-47,-51,-44, +18,40,27,-2,29, +49,-26,2,32,-54, +30,-73,54,3,-5, +36,22,53,10,-1, +-84,-53,-29,-5,3, +-44,53,-51,4,22, +71,-35,-1,33,-5, +-27,-7,36,17,-23, +-39,16,-9,-55,-15, +-20,39,-35,6,-39, +-14,18,48,-64,-17, +-15,9,39,81,37, +-68,37,47,-21,-6, +-104,13,6,9,-2, +35,8,-23,18,42, +45,21,33,-5,-49, +9,-6,-43,-56,39, +2,-16,-25,87,1, +-3,-9,17,-25,-11, +-9,-1,10,2,-14, +-14,4,-1,-10,28, +-23,40,-32,26,-9, +26,4,-27,-23,3, +42,-60,1,49,-3, +27,10,-52,-40,-2, +18,45,-23,17,-44, +3,-3,17,-46,52, +-40,-47,25,75,31, +-49,53,30,-30,-32, +-36,38,-6,-15,-16, +54,-27,-48,3,38, +-29,-32,-22,-14,-4, +-23,-13,32,-39,9, +8,-45,-13,34,-16, +49,40,32,31,28, +23,23,32,47,59, +-68,8,62,44,25, +-14,-24,-65,-16,36, +67,-25,-38,-21,4, +-33,-2,42,5,-63, +40,11,26,-42,-23, +-61,79,-31,23,-20, +10,-32,53,-25,-36, +10,-26,-5,3,0, +-71,5,-10,-37,1, +-24,21,-54,-17,1, +-29,-25,-15,-27,32, +68,45,-16,-37,-18, +-5,1,0,-77,71, +-6,3,-20,71,-67, +29,-35,10,-30,19, +4,16,17,5,0, +-14,19,2,28,26, +59,3,2,24,39, +55,-50,-45,-18,-17, +33,-35,14,-1,1, +8,87,-35,-29,0, +-27,13,-7,23,-13, +37,-40,50,-35,14, +19,-7,-14,49,54, +-5,22,-2,-29,-8, +-27,38,13,27,48, +12,-41,-21,-15,28, +7,-16,-24,-19,-20, +11,-20,9,2,13, +23,-20,11,27,-27, +71,-69,8,2,-6, +22,12,16,16,9, +-16,-8,-17,1,25, +1,40,-37,-33,66, +94,53,4,-22,-25, +-41,-42,25,35,-16, +-15,57,31,-29,-32, +21,16,-60,45,15, +-1,7,57,-26,-47, +-29,11,8,15,19, +-105,-8,54,27,10, +-17,6,-12,-1,-10, +4,0,23,-10,31, +13,11,10,12,-64, +23,-3,-8,-19,16, +52,24,-40,16,10, +40,5,9,0,-13, +-7,-21,-8,-6,-7, +-21,59,16,-53,18, +-60,11,-47,14,-18, +25,-13,-24,4,-39, +16,-28,54,26,-67, +30,27,-20,-52,20, +-12,55,12,18,-16, +39,-14,-6,-26,56, +-88,-55,12,25,26, +-37,6,75,0,-34, +-81,54,-30,1,-7, +49,-23,-14,21,10, +-62,-58,-57,-47,-34, +15,-4,34,-78,31, +25,-11,7,50,-10, +42,-63,14,-36,-4, +57,55,57,53,42, +-42,-1,15,40,37, +15,25,-11,6,1, +31,-2,-6,-1,-7, +-64,34,28,30,-1, +3,21,0,-88,-12, +-56,25,-28,40,8, +-28,-14,9,12,2, +-6,-17,22,49,-6, +-26,14,28,-20,4, +-12,50,35,40,13, +-38,-58,-29,17,30, +22,60,26,-54,-39, +-12,58,-28,-63,10, +-21,-8,-12,26,-62, +6,-10,-11,-22,-6, +-7,4,1,18,2, +-70,11,14,4,13, +19,-24,-34,24,67, +17,51,-21,13,23, +54,-30,48,1,-13, +80,26,-16,-2,13, +-4,6,-30,29,-24, +73,-58,30,-27,20, +-2,-21,41,45,30, +-27,-3,-5,-18,-20, +-49,-3,-35,10,42, +-19,-67,-53,-11,9, +13,-15,-33,-51,-30, +15,7,25,-30,4, +28,-22,-34,54,-29, +39,-46,20,16,34, +-4,47,75,1,-44, +-55,-24,7,-1,9, +-42,50,-8,-36,41, +68,0,-4,-10,-23, +-15,-50,64,36,-9, +-27,12,25,-38,-47, +-37,32,-49,51,-36, +2,-4,69,-26,19, +7,45,67,46,13, +-63,46,15,-47,4, +-41,13,-6,5,-21, +37,26,-55,-7,33, +-1,-28,10,-17,-64, +-14,0,-36,-17,93, +-3,-9,-66,44,-21, +3,-12,38,-6,-13, +-12,19,13,43,-43, +-10,-12,6,-5,9, +-49,32,-5,2,4, +5,15,-16,10,-21, +8,-62,-8,64,8, +79,-1,-66,-49,-18, +5,40,-5,-30,-45, +1,-6,21,-32,93, +-18,-30,-21,32,21, +-18,22,8,5,-41, +-54,80,22,-10,-7, +-8,-23,-64,66,56, +-14,-30,-41,-46,-14, +-29,-37,27,-14,42, +-2,-9,-29,34,14, +33,-14,22,4,10, +26,26,28,32,23, +-72,-32,3,0,-14, +35,-42,-78,-32,6, +29,-18,-45,-5,7, +-33,-45,-3,-22,-34, +8,-8,4,-51,-25, +-9,59,-78,21,-5, +-25,-48,66,-15,-17, +-24,-49,-13,25,-23, +-64,-6,40,-24,-19, +-11,57,-33,-8,1, +10,-52,-54,28,39, +49,34,-11,-61,-41, +-43,10,15,-15,51, +30,15,-51,32,-34, +-2,-34,14,18,16, +1,1,-3,-3,1, +1,-18,6,16,48, +12,-5,-42,7,36, +48,7,-20,-10,7, +12,2,54,39,-38, +37,54,4,-11,-8, +-46,-10,5,-10,-34, +46,-12,29,-37,39, +36,-11,24,56,17, +14,20,25,0,-25, +-28,55,-7,-5,27, +3,9,-26,-8,6, +-24,-10,-30,-31,-34, +18,4,22,21,40, +-1,-29,-37,-8,-21, +92,-29,11,-3,11, +73,23,22,7,4, +-44,-9,-11,21,-13, +11,9,-78,-1,47, +114,-12,-37,-19,-5, +-11,-22,19,12,-30, +7,38,45,-21,-8, +-9,55,-45,56,-21, +7,17,46,-57,-87, +-6,27,31,31,7, +-56,-12,46,21,-5, +-12,36,3,3,-21, +43,19,12,-7,9, +-14,0,-9,-33,-91, +7,26,3,-11,64, +83,-31,-46,25,2, +9,5,2,2,-1, +20,-17,10,-5,-27, +-8,20,8,-19,16, +-21,-13,-31,5,5, +42,24,9,34,-20, +28,-61,22,11,-39, +64,-20,-1,-30,-9, +-20,24,-25,-24,-29, +22,-60,6,-5,41, +-9,-87,14,34,15, +-57,52,69,15,-3, +-102,58,16,3,6, +60,-75,-32,26,7, +-57,-27,-32,-24,-21, +-29,-16,62,-46,31, +30,-27,-15,7,15}; diff --git a/src/libs/speex/libspeex/exc_5_64_table.c b/src/libs/speex/libspeex/exc_5_64_table.c new file mode 100644 index 00000000..2c66d518 --- /dev/null +++ b/src/libs/speex/libspeex/exc_5_64_table.c @@ -0,0 +1,98 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: exc_5_64_table.c + Codebook for excitation in narrowband CELP mode (9600 bps) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +const signed char exc_5_64_table[320]={ +1,5,-15,49,-66, +-48,-4,50,-44,7, +37,16,-18,25,-26, +-26,-15,19,19,-27, +-47,28,57,5,-17, +-32,-41,68,21,-2, +64,56,8,-16,-13, +-26,-9,-16,11,6, +-39,25,-19,22,-31, +20,-45,55,-43,10, +-16,47,-40,40,-20, +-51,3,-17,-14,-15, +-24,53,-20,-46,46, +27,-68,32,3,-18, +-5,9,-31,16,-9, +-10,-1,-23,48,95, +47,25,-41,-32,-3, +15,-25,-55,36,41, +-27,20,5,13,14, +-22,5,2,-23,18, +46,-15,17,-18,-34, +-5,-8,27,-55,73, +16,2,-1,-17,40, +-78,33,0,2,19, +4,53,-16,-15,-16, +-28,-3,-13,49,8, +-7,-29,27,-13,32, +20,32,-61,16,14, +41,44,40,24,20, +7,4,48,-60,-77, +17,-6,-48,65,-15, +32,-30,-71,-10,-3, +-6,10,-2,-7,-29, +-56,67,-30,7,-5, +86,-6,-10,0,5, +-31,60,34,-38,-3, +24,10,-2,30,23, +24,-41,12,70,-43, +15,-17,6,13,16, +-13,8,30,-15,-8, +5,23,-34,-98,-4, +-13,13,-48,-31,70, +12,31,25,24,-24, +26,-7,33,-16,8, +5,-11,-14,-8,-65, +13,10,-2,-9,0, +-3,-68,5,35,7, +0,-31,-1,-17,-9, +-9,16,-37,-18,-1, +69,-48,-28,22,-21, +-11,5,49,55,23, +-86,-36,16,2,13, +63,-51,30,-11,13, +24,-18,-6,14,-19, +1,41,9,-5,27, +-36,-44,-34,-37,-21, +-26,31,-39,15,43, +5,-8,29,20,-8, +-20,-52,-28,-1,13, +26,-34,-10,-9,27, +-8,8,27,-66,4, +12,-22,49,10,-77, +32,-18,3,-38,12, +-3,-1,2,2,0}; diff --git a/src/libs/speex/libspeex/exc_8_128_table.c b/src/libs/speex/libspeex/exc_8_128_table.c new file mode 100644 index 00000000..17ee64b9 --- /dev/null +++ b/src/libs/speex/libspeex/exc_8_128_table.c @@ -0,0 +1,162 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: exc_8_128_table.c + Codebook for excitation in narrowband CELP mode (7000 bps) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +const signed char exc_8_128_table[1024] = { +-14,9,13,-32,2,-10,31,-10, +-8,-8,6,-4,-1,10,-64,23, +6,20,13,6,8,-22,16,34, +7,42,-49,-28,5,26,4,-15, +41,34,41,32,33,24,23,14, +8,40,34,4,-24,-41,-19,-15, +13,-13,33,-54,24,27,-44,33, +27,-15,-15,24,-19,14,-36,14, +-9,24,-12,-4,37,-5,16,-34, +5,10,33,-15,-54,-16,12,25, +12,1,2,0,3,-1,-4,-4, +11,2,-56,54,27,-20,13,-6, +-46,-41,-33,-11,-5,7,12,14, +-14,-5,8,20,6,3,4,-8, +-5,-42,11,8,-14,25,-2,2, +13,11,-22,39,-9,9,5,-45, +-9,7,-9,12,-7,34,-17,-102, +7,2,-42,18,35,-9,-34,11, +-5,-2,3,22,46,-52,-25,-9, +-94,8,11,-5,-5,-5,4,-7, +-35,-7,54,5,-32,3,24,-9, +-22,8,65,37,-1,-12,-23,-6, +-9,-28,55,-33,14,-3,2,18, +-60,41,-17,8,-16,17,-11,0, +-11,29,-28,37,9,-53,33,-14, +-9,7,-25,-7,-11,26,-32,-8, +24,-21,22,-19,19,-10,29,-14, +0,0,0,0,0,0,0,0, +-5,-52,10,41,6,-30,-4,16, +32,22,-27,-22,32,-3,-28,-3, +3,-35,6,17,23,21,8,2, +4,-45,-17,14,23,-4,-31,-11, +-3,14,1,19,-11,2,61,-8, +9,-12,7,-10,12,-3,-24,99, +-48,23,50,-37,-5,-23,0,8, +-14,35,-64,-5,46,-25,13,-1, +-49,-19,-15,9,34,50,25,11, +-6,-9,-16,-20,-32,-33,-32,-27, +10,-8,12,-15,56,-14,-32,33, +3,-9,1,65,-9,-9,-10,-2, +-6,-23,9,17,3,-28,13,-32, +4,-2,-10,4,-16,76,12,-52, +6,13,33,-6,4,-14,-9,-3, +1,-15,-16,28,1,-15,11,16, +9,4,-21,-37,-40,-6,22,12, +-15,-23,-14,-17,-16,-9,-10,-9, +13,-39,41,5,-9,16,-38,25, +46,-47,4,49,-14,17,-2,6, +18,5,-6,-33,-22,44,50,-2, +1,3,-6,7,7,-3,-21,38, +-18,34,-14,-41,60,-13,6,16, +-24,35,19,-13,-36,24,3,-17, +-14,-10,36,44,-44,-29,-3,3, +-54,-8,12,55,26,4,-2,-5, +2,-11,22,-23,2,22,1,-25, +-39,66,-49,21,-8,-2,10,-14, +-60,25,6,10,27,-25,16,5, +-2,-9,26,-13,-20,58,-2,7, +52,-9,2,5,-4,-15,23,-1, +-38,23,8,27,-6,0,-27,-7, +39,-10,-14,26,11,-45,-12,9, +-5,34,4,-35,10,43,-22,-11, +56,-7,20,1,10,1,-26,9, +94,11,-27,-14,-13,1,-11,0, +14,-5,-6,-10,-4,-15,-8,-41, +21,-5,1,-28,-8,22,-9,33, +-23,-4,-4,-12,39,4,-7,3, +-60,80,8,-17,2,-6,12,-5, +1,9,15,27,31,30,27,23, +61,47,26,10,-5,-8,-12,-13, +5,-18,25,-15,-4,-15,-11,12, +-2,-2,-16,-2,-6,24,12,11, +-4,9,1,-9,14,-45,57,12, +20,-35,26,11,-64,32,-10,-10, +42,-4,-9,-16,32,24,7,10, +52,-11,-57,29,0,8,0,-6, +17,-17,-56,-40,7,20,18,12, +-6,16,5,7,-1,9,1,10, +29,12,16,13,-2,23,7,9, +-3,-4,-5,18,-64,13,55,-25, +9,-9,24,14,-25,15,-11,-40, +-30,37,1,-19,22,-5,-31,13, +-2,0,7,-4,16,-67,12,66, +-36,24,-8,18,-15,-23,19,0, +-45,-7,4,3,-13,13,35,5, +13,33,10,27,23,0,-7,-11, +43,-74,36,-12,2,5,-8,6, +-33,11,-16,-14,-5,-7,-3,17, +-34,27,-16,11,-9,15,33,-31, +8,-16,7,-6,-7,63,-55,-17, +11,-1,20,-46,34,-30,6,9, +19,28,-9,5,-24,-8,-23,-2, +31,-19,-16,-5,-15,-18,0,26, +18,37,-5,-15,-2,17,5,-27, +21,-33,44,12,-27,-9,17,11, +25,-21,-31,-7,13,33,-8,-25, +-7,7,-10,4,-6,-9,48,-82, +-23,-8,6,11,-23,3,-3,49, +-29,25,31,4,14,16,9,-4, +-18,10,-26,3,5,-44,-9,9, +-47,-55,15,9,28,1,4,-3, +46,6,-6,-38,-29,-31,-15,-6, +3,0,14,-6,8,-54,-50,33, +-5,1,-14,33,-48,26,-4,-5, +-3,-5,-3,-5,-28,-22,77,55, +-1,2,10,10,-9,-14,-66,-49, +11,-36,-6,-20,10,-10,16,12, +4,-1,-16,45,-44,-50,31,-2, +25,42,23,-32,-22,0,11,20, +-40,-35,-40,-36,-32,-26,-21,-13, +52,-22,6,-24,-20,17,-5,-8, +36,-25,-11,21,-26,6,34,-8, +7,20,-3,5,-25,-8,18,-5, +-9,-4,1,-9,20,20,39,48, +-24,9,5,-65,22,29,4,3, +-43,-11,32,-6,9,19,-27,-10, +-47,-14,24,10,-7,-36,-7,-1, +-4,-5,-5,16,53,25,-26,-29, +-4,-12,45,-58,-34,33,-5,2, +-1,27,-48,31,-15,22,-5,4, +7,7,-25,-3,11,-22,16,-12, +8,-3,7,-11,45,14,-73,-19, +56,-46,24,-20,28,-12,-2,-1, +-36,-3,-33,19,-6,7,2,-15, +5,-31,-45,8,35,13,20,0, +-9,48,-13,-43,-3,-13,2,-5, +72,-68,-27,2,1,-2,-7,5, +36,33,-40,-12,-4,-5,23,19}; diff --git a/src/libs/speex/libspeex/fftwrap.c b/src/libs/speex/libspeex/fftwrap.c new file mode 100644 index 00000000..0eee55ce --- /dev/null +++ b/src/libs/speex/libspeex/fftwrap.c @@ -0,0 +1,398 @@ +/* Copyright (C) 2005-2006 Jean-Marc Valin + File: fftwrap.c + + Wrapper for various FFTs + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "arch.h" +#include "os_support.h" + +#define MAX_FFT_SIZE 2048 +#define USE_SMALLFT + +#ifdef FIXED_POINT +static int maximize_range(spx_word16_t *in, spx_word16_t *out, spx_word16_t bound, int len) +{ + int i, shift; + spx_word16_t max_val = 0; + for (i=0;i<len;i++) + { + if (in[i]>max_val) + max_val = in[i]; + if (-in[i]>max_val) + max_val = -in[i]; + } + shift=0; + while (max_val <= (bound>>1) && max_val != 0) + { + max_val <<= 1; + shift++; + } + for (i=0;i<len;i++) + { + out[i] = SHL16(in[i], shift); + } + return shift; +} + +static void renorm_range(spx_word16_t *in, spx_word16_t *out, int shift, int len) +{ + int i; + for (i=0;i<len;i++) + { + out[i] = PSHR16(in[i], shift); + } +} +#endif + +#ifdef USE_SMALLFT + +#include "smallft.h" +#include <math.h> + +void *spx_fft_init(int size) +{ + struct drft_lookup *table; + table = speex_alloc(sizeof(struct drft_lookup)); + spx_drft_init((struct drft_lookup *)table, size); + return (void*)table; +} + +void spx_fft_destroy(void *table) +{ + spx_drft_clear(table); + speex_free(table); +} + +void spx_fft(void *table, float *in, float *out) +{ + if (in==out) + { + int i; + float scale = 1./((struct drft_lookup *)table)->n; + speex_warning("FFT should not be done in-place"); + for (i=0;i<((struct drft_lookup *)table)->n;i++) + out[i] = scale*in[i]; + } else { + int i; + float scale = 1./((struct drft_lookup *)table)->n; + for (i=0;i<((struct drft_lookup *)table)->n;i++) + out[i] = scale*in[i]; + } + spx_drft_forward((struct drft_lookup *)table, out); +} + +void spx_ifft(void *table, float *in, float *out) +{ + if (in==out) + { + speex_warning("FFT should not be done in-place"); + } else { + int i; + for (i=0;i<((struct drft_lookup *)table)->n;i++) + out[i] = in[i]; + } + spx_drft_backward((struct drft_lookup *)table, out); +} + +#elif defined(USE_INTEL_MKL) +#include <mkl.h> + +struct mkl_config { + DFTI_DESCRIPTOR_HANDLE desc; + int N; +}; + +void *spx_fft_init(int size) +{ + struct mkl_config *table = (struct mkl_config *) speex_alloc(sizeof(struct mkl_config)); + table->N = size; + DftiCreateDescriptor(&table->desc, DFTI_SINGLE, DFTI_REAL, 1, size); + DftiSetValue(table->desc, DFTI_PACKED_FORMAT, DFTI_PACK_FORMAT); + DftiSetValue(table->desc, DFTI_PLACEMENT, DFTI_NOT_INPLACE); + DftiSetValue(table->desc, DFTI_FORWARD_SCALE, 1.0f / size); + DftiCommitDescriptor(table->desc); + return table; +} + +void spx_fft_destroy(void *table) +{ + struct mkl_config *t = (struct mkl_config *) table; + DftiFreeDescriptor(t->desc); + speex_free(table); +} + +void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + struct mkl_config *t = (struct mkl_config *) table; + DftiComputeForward(t->desc, in, out); +} + +void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + struct mkl_config *t = (struct mkl_config *) table; + DftiComputeBackward(t->desc, in, out); +} + +#elif defined(USE_GPL_FFTW3) + +#include <fftw3.h> + +struct fftw_config { + float *in; + float *out; + fftwf_plan fft; + fftwf_plan ifft; + int N; +}; + +void *spx_fft_init(int size) +{ + struct fftw_config *table = (struct fftw_config *) speex_alloc(sizeof(struct fftw_config)); + table->in = fftwf_malloc(sizeof(float) * (size+2)); + table->out = fftwf_malloc(sizeof(float) * (size+2)); + + table->fft = fftwf_plan_dft_r2c_1d(size, table->in, (fftwf_complex *) table->out, FFTW_PATIENT); + table->ifft = fftwf_plan_dft_c2r_1d(size, (fftwf_complex *) table->in, table->out, FFTW_PATIENT); + + table->N = size; + return table; +} + +void spx_fft_destroy(void *table) +{ + struct fftw_config *t = (struct fftw_config *) table; + fftwf_destroy_plan(t->fft); + fftwf_destroy_plan(t->ifft); + fftwf_free(t->in); + fftwf_free(t->out); + speex_free(table); +} + + +void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + int i; + struct fftw_config *t = (struct fftw_config *) table; + const int N = t->N; + float *iptr = t->in; + float *optr = t->out; + const float m = 1.0 / N; + for(i=0;i<N;++i) + iptr[i]=in[i] * m; + + fftwf_execute(t->fft); + + out[0] = optr[0]; + for(i=1;i<N;++i) + out[i] = optr[i+1]; +} + +void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + int i; + struct fftw_config *t = (struct fftw_config *) table; + const int N = t->N; + float *iptr = t->in; + float *optr = t->out; + + iptr[0] = in[0]; + iptr[1] = 0.0f; + for(i=1;i<N;++i) + iptr[i+1] = in[i]; + iptr[N+1] = 0.0f; + + fftwf_execute(t->ifft); + + for(i=0;i<N;++i) + out[i] = optr[i]; +} + +#elif defined(USE_KISS_FFT) + +#include "kiss_fftr.h" +#include "kiss_fft.h" + +struct kiss_config { + kiss_fftr_cfg forward; + kiss_fftr_cfg backward; + int N; +}; + +void *spx_fft_init(int size) +{ + struct kiss_config *table; + table = (struct kiss_config*)speex_alloc(sizeof(struct kiss_config)); + table->forward = kiss_fftr_alloc(size,0,NULL,NULL); + table->backward = kiss_fftr_alloc(size,1,NULL,NULL); + table->N = size; + return table; +} + +void spx_fft_destroy(void *table) +{ + struct kiss_config *t = (struct kiss_config *)table; + kiss_fftr_free(t->forward); + kiss_fftr_free(t->backward); + speex_free(table); +} + +#ifdef FIXED_POINT + +void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + int shift; + struct kiss_config *t = (struct kiss_config *)table; + shift = maximize_range(in, in, 32000, t->N); + kiss_fftr2(t->forward, in, out); + renorm_range(in, in, shift, t->N); + renorm_range(out, out, shift, t->N); +} + +#else + +void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + int i; + float scale; + struct kiss_config *t = (struct kiss_config *)table; + scale = 1./t->N; + kiss_fftr2(t->forward, in, out); + for (i=0;i<t->N;i++) + out[i] *= scale; +} +#endif + +void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + struct kiss_config *t = (struct kiss_config *)table; + kiss_fftri2(t->backward, in, out); +} + + +#else + +#error No other FFT implemented + +#endif + + +#ifdef FIXED_POINT +/*#include "smallft.h"*/ + + +void spx_fft_float(void *table, float *in, float *out) +{ + int i; +#ifdef USE_SMALLFT + int N = ((struct drft_lookup *)table)->n; +#elif defined(USE_KISS_FFT) + int N = ((struct kiss_config *)table)->N; +#else +#endif +#ifdef VAR_ARRAYS + spx_word16_t _in[N]; + spx_word16_t _out[N]; +#else + spx_word16_t _in[MAX_FFT_SIZE]; + spx_word16_t _out[MAX_FFT_SIZE]; +#endif + for (i=0;i<N;i++) + _in[i] = (int)floor(.5+in[i]); + spx_fft(table, _in, _out); + for (i=0;i<N;i++) + out[i] = _out[i]; +#if 0 + if (!fixed_point) + { + float scale; + struct drft_lookup t; + spx_drft_init(&t, ((struct kiss_config *)table)->N); + scale = 1./((struct kiss_config *)table)->N; + for (i=0;i<((struct kiss_config *)table)->N;i++) + out[i] = scale*in[i]; + spx_drft_forward(&t, out); + spx_drft_clear(&t); + } +#endif +} + +void spx_ifft_float(void *table, float *in, float *out) +{ + int i; +#ifdef USE_SMALLFT + int N = ((struct drft_lookup *)table)->n; +#elif defined(USE_KISS_FFT) + int N = ((struct kiss_config *)table)->N; +#else +#endif +#ifdef VAR_ARRAYS + spx_word16_t _in[N]; + spx_word16_t _out[N]; +#else + spx_word16_t _in[MAX_FFT_SIZE]; + spx_word16_t _out[MAX_FFT_SIZE]; +#endif + for (i=0;i<N;i++) + _in[i] = (int)floor(.5+in[i]); + spx_ifft(table, _in, _out); + for (i=0;i<N;i++) + out[i] = _out[i]; +#if 0 + if (!fixed_point) + { + int i; + struct drft_lookup t; + spx_drft_init(&t, ((struct kiss_config *)table)->N); + for (i=0;i<((struct kiss_config *)table)->N;i++) + out[i] = in[i]; + spx_drft_backward(&t, out); + spx_drft_clear(&t); + } +#endif +} + +#else + +void spx_fft_float(void *table, float *in, float *out) +{ + spx_fft(table, in, out); +} +void spx_ifft_float(void *table, float *in, float *out) +{ + spx_ifft(table, in, out); +} + +#endif diff --git a/src/libs/speex/libspeex/fftwrap.h b/src/libs/speex/libspeex/fftwrap.h new file mode 100644 index 00000000..dfaf4894 --- /dev/null +++ b/src/libs/speex/libspeex/fftwrap.h @@ -0,0 +1,58 @@ +/* Copyright (C) 2005 Jean-Marc Valin + File: fftwrap.h + + Wrapper for various FFTs + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef FFTWRAP_H +#define FFTWRAP_H + +#include "arch.h" + +/** Compute tables for an FFT */ +void *spx_fft_init(int size); + +/** Destroy tables for an FFT */ +void spx_fft_destroy(void *table); + +/** Forward (real to half-complex) transform */ +void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out); + +/** Backward (half-complex to real) transform */ +void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out); + +/** Forward (real to half-complex) transform of float data */ +void spx_fft_float(void *table, float *in, float *out); + +/** Backward (half-complex to real) transform of float data */ +void spx_ifft_float(void *table, float *in, float *out); + +#endif diff --git a/src/libs/speex/libspeex/filterbank.c b/src/libs/speex/libspeex/filterbank.c new file mode 100644 index 00000000..e2fb71d4 --- /dev/null +++ b/src/libs/speex/libspeex/filterbank.c @@ -0,0 +1,227 @@ +/* Copyright (C) 2006 Jean-Marc Valin */ +/** + @file filterbank.c + @brief Converting between psd and filterbank + */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "filterbank.h" +#include "arch.h" +#include <math.h> +#include "math_approx.h" +#include "os_support.h" + +#ifdef FIXED_POINT + +#define toBARK(n) (MULT16_16(26829,spx_atan(SHR32(MULT16_16(97,n),2))) + MULT16_16(4588,spx_atan(MULT16_32_Q15(20,MULT16_16(n,n)))) + MULT16_16(3355,n)) + +#else +#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n)) +#endif + +#define toMEL(n) (2595.f*log10(1.f+(n)/700.f)) + +FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type) +{ + FilterBank *bank; + spx_word32_t df; + spx_word32_t max_mel, mel_interval; + int i; + int id1; + int id2; + df = DIV32(SHL32(sampling,15),MULT16_16(2,len)); + max_mel = toBARK(EXTRACT16(sampling/2)); + mel_interval = PDIV32(max_mel,banks-1); + + bank = (FilterBank*)speex_alloc(sizeof(FilterBank)); + bank->nb_banks = banks; + bank->len = len; + bank->bank_left = (int*)speex_alloc(len*sizeof(int)); + bank->bank_right = (int*)speex_alloc(len*sizeof(int)); + bank->filter_left = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t)); + bank->filter_right = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t)); + /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */ +#ifndef FIXED_POINT + bank->scaling = (float*)speex_alloc(banks*sizeof(float)); +#endif + for (i=0;i<len;i++) + { + spx_word16_t curr_freq; + spx_word32_t mel; + spx_word16_t val; + curr_freq = EXTRACT16(MULT16_32_P15(i,df)); + mel = toBARK(curr_freq); + if (mel > max_mel) + break; +#ifdef FIXED_POINT + id1 = DIV32(mel,mel_interval); +#else + id1 = (int)(floor(mel/mel_interval)); +#endif + if (id1>banks-2) + { + id1 = banks-2; + val = Q15_ONE; + } else { + val = DIV32_16(mel - id1*mel_interval,EXTRACT16(PSHR32(mel_interval,15))); + } + id2 = id1+1; + bank->bank_left[i] = id1; + bank->filter_left[i] = SUB16(Q15_ONE,val); + bank->bank_right[i] = id2; + bank->filter_right[i] = val; + } + + /* Think I can safely disable normalisation for fixed-point (and probably float as well) */ +#ifndef FIXED_POINT + for (i=0;i<bank->nb_banks;i++) + bank->scaling[i] = 0; + for (i=0;i<bank->len;i++) + { + int id = bank->bank_left[i]; + bank->scaling[id] += bank->filter_left[i]; + id = bank->bank_right[i]; + bank->scaling[id] += bank->filter_right[i]; + } + for (i=0;i<bank->nb_banks;i++) + bank->scaling[i] = Q15_ONE/(bank->scaling[i]); +#endif + return bank; +} + +void filterbank_destroy(FilterBank *bank) +{ + speex_free(bank->bank_left); + speex_free(bank->bank_right); + speex_free(bank->filter_left); + speex_free(bank->filter_right); +#ifndef FIXED_POINT + speex_free(bank->scaling); +#endif + speex_free(bank); +} + +void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel) +{ + int i; + for (i=0;i<bank->nb_banks;i++) + mel[i] = 0; + + for (i=0;i<bank->len;i++) + { + int id; + id = bank->bank_left[i]; + mel[id] += MULT16_32_P15(bank->filter_left[i],ps[i]); + id = bank->bank_right[i]; + mel[id] += MULT16_32_P15(bank->filter_right[i],ps[i]); + } + /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */ +#ifndef FIXED_POINT + /*for (i=0;i<bank->nb_banks;i++) + mel[i] = MULT16_32_P15(Q15(bank->scaling[i]),mel[i]); + */ +#endif +} + +void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *ps) +{ + int i; + for (i=0;i<bank->len;i++) + { + spx_word32_t tmp; + int id1, id2; + id1 = bank->bank_left[i]; + id2 = bank->bank_right[i]; + tmp = MULT16_16(mel[id1],bank->filter_left[i]); + tmp += MULT16_16(mel[id2],bank->filter_right[i]); + ps[i] = EXTRACT16(PSHR32(tmp,15)); + } +} + + +#ifndef FIXED_POINT +void filterbank_compute_bank(FilterBank *bank, float *ps, float *mel) +{ + int i; + for (i=0;i<bank->nb_banks;i++) + mel[i] = 0; + + for (i=0;i<bank->len;i++) + { + int id = bank->bank_left[i]; + mel[id] += bank->filter_left[i]*ps[i]; + id = bank->bank_right[i]; + mel[id] += bank->filter_right[i]*ps[i]; + } + for (i=0;i<bank->nb_banks;i++) + mel[i] *= bank->scaling[i]; +} + +void filterbank_compute_psd(FilterBank *bank, float *mel, float *ps) +{ + int i; + for (i=0;i<bank->len;i++) + { + int id = bank->bank_left[i]; + ps[i] = mel[id]*bank->filter_left[i]; + id = bank->bank_right[i]; + ps[i] += mel[id]*bank->filter_right[i]; + } +} + +void filterbank_psy_smooth(FilterBank *bank, float *ps, float *mask) +{ + /* Low freq slope: 14 dB/Bark*/ + /* High freq slope: 9 dB/Bark*/ + /* Noise vs tone: 5 dB difference */ + /* FIXME: Temporary kludge */ + float bark[100]; + int i; + /* Assumes 1/3 Bark resolution */ + float decay_low = 0.34145f; + float decay_high = 0.50119f; + filterbank_compute_bank(bank, ps, bark); + for (i=1;i<bank->nb_banks;i++) + { + /*float decay_high = 13-1.6*log10(bark[i-1]); + decay_high = pow(10,(-decay_high/30.f));*/ + bark[i] = bark[i] + decay_high*bark[i-1]; + } + for (i=bank->nb_banks-2;i>=0;i--) + { + bark[i] = bark[i] + decay_low*bark[i+1]; + } + filterbank_compute_psd(bank, bark, mask); +} + +#endif diff --git a/src/libs/speex/libspeex/filterbank.h b/src/libs/speex/libspeex/filterbank.h new file mode 100644 index 00000000..3e889a22 --- /dev/null +++ b/src/libs/speex/libspeex/filterbank.h @@ -0,0 +1,66 @@ +/* Copyright (C) 2006 Jean-Marc Valin */ +/** + @file filterbank.h + @brief Converting between psd and filterbank + */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FILTERBANK_H +#define FILTERBANK_H + +#include "arch.h" + +typedef struct { + int *bank_left; + int *bank_right; + spx_word16_t *filter_left; + spx_word16_t *filter_right; +#ifndef FIXED_POINT + float *scaling; +#endif + int nb_banks; + int len; +} FilterBank; + + +FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type); + +void filterbank_destroy(FilterBank *bank); + +void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel); + +void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *psd); + +#ifndef FIXED_POINT +void filterbank_compute_bank(FilterBank *bank, float *psd, float *mel); +void filterbank_compute_psd(FilterBank *bank, float *mel, float *psd); +#endif + + +#endif diff --git a/src/libs/speex/libspeex/filters.c b/src/libs/speex/libspeex/filters.c new file mode 100644 index 00000000..36ef4f69 --- /dev/null +++ b/src/libs/speex/libspeex/filters.c @@ -0,0 +1,821 @@ +/* Copyright (C) 2002-2006 Jean-Marc Valin + File: filters.c + Various analysis/synthesis filters + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "filters.h" +#include "stack_alloc.h" +#include "arch.h" +#include "math_approx.h" +#include "ltp.h" +#include <math.h> + +#ifdef _USE_SSE +#include "filters_sse.h" +#elif defined (ARM4_ASM) || defined(ARM5E_ASM) +#include "filters_arm4.h" +#elif defined (BFIN_ASM) +#include "filters_bfin.h" +#endif + + + +void bw_lpc(spx_word16_t gamma, const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order) +{ + int i; + spx_word16_t tmp=gamma; + for (i=0;i<order;i++) + { + lpc_out[i] = MULT16_16_P15(tmp,lpc_in[i]); + tmp = MULT16_16_P15(tmp, gamma); + } +} + +void sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len) +{ + int i; + for (i=0;i<len;i++) + { + /* It's important we do the test that way so we can catch NaNs, which are neither greater nor smaller */ + if (!(vec[i]>=min_val && vec[i] <= max_val)) + { + if (vec[i] < min_val) + vec[i] = min_val; + else if (vec[i] > max_val) + vec[i] = max_val; + else /* Has to be NaN */ + vec[i] = 0; + } + } +} + +void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem) +{ + int i; +#ifdef FIXED_POINT + const spx_word16_t Pcoef[5][3] = {{16384, -31313, 14991}, {16384, -31569, 15249}, {16384, -31677, 15328}, {16384, -32313, 15947}, {16384, -22446, 6537}}; + const spx_word16_t Zcoef[5][3] = {{15672, -31344, 15672}, {15802, -31601, 15802}, {15847, -31694, 15847}, {16162, -32322, 16162}, {14418, -28836, 14418}}; +#else + const spx_word16_t Pcoef[5][3] = {{1.00000f, -1.91120f, 0.91498f}, {1.00000f, -1.92683f, 0.93071f}, {1.00000f, -1.93338f, 0.93553f}, {1.00000f, -1.97226f, 0.97332f}, {1.00000f, -1.37000f, 0.39900f}}; + const spx_word16_t Zcoef[5][3] = {{0.95654f, -1.91309f, 0.95654f}, {0.96446f, -1.92879f, 0.96446f}, {0.96723f, -1.93445f, 0.96723f}, {0.98645f, -1.97277f, 0.98645f}, {0.88000f, -1.76000f, 0.88000f}}; +#endif + const spx_word16_t *den, *num; + if (filtID>4) + filtID=4; + + den = Pcoef[filtID]; num = Zcoef[filtID]; + /*return;*/ + for (i=0;i<len;i++) + { + spx_word16_t yi; + spx_word32_t vout = ADD32(MULT16_16(num[0], x[i]),mem[0]); + yi = EXTRACT16(SATURATE(PSHR32(vout,14),32767)); + mem[0] = ADD32(MAC16_16(mem[1], num[1],x[i]), SHL32(MULT16_32_Q15(-den[1],vout),1)); + mem[1] = ADD32(MULT16_16(num[2],x[i]), SHL32(MULT16_32_Q15(-den[2],vout),1)); + y[i] = yi; + } +} + +#ifdef FIXED_POINT + +/* FIXME: These functions are ugly and probably introduce too much error */ +void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len) +{ + int i; + for (i=0;i<len;i++) + { + y[i] = SHL32(MULT16_32_Q14(EXTRACT16(SHR32(x[i],7)),scale),7); + } +} + +void signal_div(const spx_word16_t *x, spx_word16_t *y, spx_word32_t scale, int len) +{ + int i; + if (scale > SHL32(EXTEND32(SIG_SCALING), 8)) + { + spx_word16_t scale_1; + scale = PSHR32(scale, SIG_SHIFT); + scale_1 = EXTRACT16(PDIV32_16(SHL32(EXTEND32(SIG_SCALING),7),scale)); + for (i=0;i<len;i++) + { + y[i] = MULT16_16_P15(scale_1, x[i]); + } + } else if (scale > SHR32(EXTEND32(SIG_SCALING), 2)) { + spx_word16_t scale_1; + scale = PSHR32(scale, SIG_SHIFT-5); + scale_1 = DIV32_16(SHL32(EXTEND32(SIG_SCALING),3),scale); + for (i=0;i<len;i++) + { + y[i] = PSHR32(MULT16_16(scale_1, SHL16(x[i],2)),8); + } + } else { + spx_word16_t scale_1; + scale = PSHR32(scale, SIG_SHIFT-7); + if (scale < 5) + scale = 5; + scale_1 = DIV32_16(SHL32(EXTEND32(SIG_SCALING),3),scale); + for (i=0;i<len;i++) + { + y[i] = PSHR32(MULT16_16(scale_1, SHL16(x[i],2)),6); + } + } +} + +#else + +void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len) +{ + int i; + for (i=0;i<len;i++) + y[i] = scale*x[i]; +} + +void signal_div(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len) +{ + int i; + float scale_1 = 1/scale; + for (i=0;i<len;i++) + y[i] = scale_1*x[i]; +} +#endif + + + +#ifdef FIXED_POINT + + + +spx_word16_t compute_rms(const spx_sig_t *x, int len) +{ + int i; + spx_word32_t sum=0; + spx_sig_t max_val=1; + int sig_shift; + + for (i=0;i<len;i++) + { + spx_sig_t tmp = x[i]; + if (tmp<0) + tmp = -tmp; + if (tmp > max_val) + max_val = tmp; + } + + sig_shift=0; + while (max_val>16383) + { + sig_shift++; + max_val >>= 1; + } + + for (i=0;i<len;i+=4) + { + spx_word32_t sum2=0; + spx_word16_t tmp; + tmp = EXTRACT16(SHR32(x[i],sig_shift)); + sum2 = MAC16_16(sum2,tmp,tmp); + tmp = EXTRACT16(SHR32(x[i+1],sig_shift)); + sum2 = MAC16_16(sum2,tmp,tmp); + tmp = EXTRACT16(SHR32(x[i+2],sig_shift)); + sum2 = MAC16_16(sum2,tmp,tmp); + tmp = EXTRACT16(SHR32(x[i+3],sig_shift)); + sum2 = MAC16_16(sum2,tmp,tmp); + sum = ADD32(sum,SHR32(sum2,6)); + } + + return EXTRACT16(PSHR32(SHL32(EXTEND32(spx_sqrt(DIV32(sum,len))),(sig_shift+3)),SIG_SHIFT)); +} + +spx_word16_t compute_rms16(const spx_word16_t *x, int len) +{ + int i; + spx_word16_t max_val=10; + + for (i=0;i<len;i++) + { + spx_sig_t tmp = x[i]; + if (tmp<0) + tmp = -tmp; + if (tmp > max_val) + max_val = tmp; + } + if (max_val>16383) + { + spx_word32_t sum=0; + for (i=0;i<len;i+=4) + { + spx_word32_t sum2=0; + sum2 = MAC16_16(sum2,SHR16(x[i],1),SHR16(x[i],1)); + sum2 = MAC16_16(sum2,SHR16(x[i+1],1),SHR16(x[i+1],1)); + sum2 = MAC16_16(sum2,SHR16(x[i+2],1),SHR16(x[i+2],1)); + sum2 = MAC16_16(sum2,SHR16(x[i+3],1),SHR16(x[i+3],1)); + sum = ADD32(sum,SHR32(sum2,6)); + } + return SHL16(spx_sqrt(DIV32(sum,len)),4); + } else { + spx_word32_t sum=0; + int sig_shift=0; + if (max_val < 8192) + sig_shift=1; + if (max_val < 4096) + sig_shift=2; + if (max_val < 2048) + sig_shift=3; + for (i=0;i<len;i+=4) + { + spx_word32_t sum2=0; + sum2 = MAC16_16(sum2,SHL16(x[i],sig_shift),SHL16(x[i],sig_shift)); + sum2 = MAC16_16(sum2,SHL16(x[i+1],sig_shift),SHL16(x[i+1],sig_shift)); + sum2 = MAC16_16(sum2,SHL16(x[i+2],sig_shift),SHL16(x[i+2],sig_shift)); + sum2 = MAC16_16(sum2,SHL16(x[i+3],sig_shift),SHL16(x[i+3],sig_shift)); + sum = ADD32(sum,SHR32(sum2,6)); + } + return SHL16(spx_sqrt(DIV32(sum,len)),3-sig_shift); + } +} + +#ifndef OVERRIDE_NORMALIZE16 +int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len) +{ + int i; + spx_sig_t max_val=1; + int sig_shift; + + for (i=0;i<len;i++) + { + spx_sig_t tmp = x[i]; + if (tmp<0) + tmp = NEG32(tmp); + if (tmp >= max_val) + max_val = tmp; + } + + sig_shift=0; + while (max_val>max_scale) + { + sig_shift++; + max_val >>= 1; + } + + for (i=0;i<len;i++) + y[i] = EXTRACT16(SHR32(x[i], sig_shift)); + + return sig_shift; +} +#endif + +#else + +spx_word16_t compute_rms(const spx_sig_t *x, int len) +{ + int i; + float sum=0; + for (i=0;i<len;i++) + { + sum += x[i]*x[i]; + } + return sqrt(.1+sum/len); +} +spx_word16_t compute_rms16(const spx_word16_t *x, int len) +{ + return compute_rms(x, len); +} +#endif + + + +#ifndef OVERRIDE_FILTER_MEM16 +void filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack) +{ + int i,j; + spx_word16_t xi,yi,nyi; + for (i=0;i<N;i++) + { + xi= x[i]; + yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767)); + nyi = NEG16(yi); + for (j=0;j<ord-1;j++) + { + mem[j] = MAC16_16(MAC16_16(mem[j+1], num[j],xi), den[j],nyi); + } + mem[ord-1] = ADD32(MULT16_16(num[ord-1],xi), MULT16_16(den[ord-1],nyi)); + y[i] = yi; + } +} +#endif + +#ifndef OVERRIDE_IIR_MEM16 +void iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack) +{ + int i,j; + spx_word16_t yi,nyi; + + for (i=0;i<N;i++) + { + yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767)); + nyi = NEG16(yi); + for (j=0;j<ord-1;j++) + { + mem[j] = MAC16_16(mem[j+1],den[j],nyi); + } + mem[ord-1] = MULT16_16(den[ord-1],nyi); + y[i] = yi; + } +} +#endif + +#ifndef OVERRIDE_FIR_MEM16 +void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack) +{ + int i,j; + spx_word16_t xi,yi; + + for (i=0;i<N;i++) + { + xi=x[i]; + yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767)); + for (j=0;j<ord-1;j++) + { + mem[j] = MAC16_16(mem[j+1], num[j],xi); + } + mem[ord-1] = MULT16_16(num[ord-1],xi); + y[i] = yi; + } +} +#endif + + +void syn_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack) +{ + int i; + VARDECL(spx_mem_t *mem); + ALLOC(mem, ord, spx_mem_t); + for (i=0;i<ord;i++) + mem[i]=0; + iir_mem16(xx, ak, y, N, ord, mem, stack); + for (i=0;i<ord;i++) + mem[i]=0; + filter_mem16(y, awk1, awk2, y, N, ord, mem, stack); +} +void residue_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack) +{ + int i; + VARDECL(spx_mem_t *mem); + ALLOC(mem, ord, spx_mem_t); + for (i=0;i<ord;i++) + mem[i]=0; + filter_mem16(xx, ak, awk1, y, N, ord, mem, stack); + for (i=0;i<ord;i++) + mem[i]=0; + fir_mem16(y, awk2, y, N, ord, mem, stack); +} + + +#ifndef OVERRIDE_COMPUTE_IMPULSE_RESPONSE +void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack) +{ + int i,j; + spx_word16_t y1, ny1i, ny2i; + VARDECL(spx_mem_t *mem1); + VARDECL(spx_mem_t *mem2); + ALLOC(mem1, ord, spx_mem_t); + ALLOC(mem2, ord, spx_mem_t); + + y[0] = LPC_SCALING; + for (i=0;i<ord;i++) + y[i+1] = awk1[i]; + i++; + for (;i<N;i++) + y[i] = VERY_SMALL; + for (i=0;i<ord;i++) + mem1[i] = mem2[i] = 0; + for (i=0;i<N;i++) + { + y1 = ADD16(y[i], EXTRACT16(PSHR32(mem1[0],LPC_SHIFT))); + ny1i = NEG16(y1); + y[i] = PSHR32(ADD32(SHL32(EXTEND32(y1),LPC_SHIFT+1),mem2[0]),LPC_SHIFT); + ny2i = NEG16(y[i]); + for (j=0;j<ord-1;j++) + { + mem1[j] = MAC16_16(mem1[j+1], awk2[j],ny1i); + mem2[j] = MAC16_16(mem2[j+1], ak[j],ny2i); + } + mem1[ord-1] = MULT16_16(awk2[ord-1],ny1i); + mem2[ord-1] = MULT16_16(ak[ord-1],ny2i); + } +} +#endif + +/* Decomposes a signal into low-band and high-band using a QMF */ +void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *y1, spx_word16_t *y2, int N, int M, spx_word16_t *mem, char *stack) +{ + int i,j,k,M2; + VARDECL(spx_word16_t *a); + VARDECL(spx_word16_t *x); + spx_word16_t *x2; + + ALLOC(a, M, spx_word16_t); + ALLOC(x, N+M-1, spx_word16_t); + x2=x+M-1; + M2=M>>1; + for (i=0;i<M;i++) + a[M-i-1]= aa[i]; + for (i=0;i<M-1;i++) + x[i]=mem[M-i-2]; + for (i=0;i<N;i++) + x[i+M-1]=SHR16(xx[i],1); + for (i=0;i<M-1;i++) + mem[i]=SHR16(xx[N-i-1],1); + for (i=0,k=0;i<N;i+=2,k++) + { + spx_word32_t y1k=0, y2k=0; + for (j=0;j<M2;j++) + { + y1k=ADD32(y1k,MULT16_16(a[j],ADD16(x[i+j],x2[i-j]))); + y2k=SUB32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j]))); + j++; + y1k=ADD32(y1k,MULT16_16(a[j],ADD16(x[i+j],x2[i-j]))); + y2k=ADD32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j]))); + } + y1[k] = EXTRACT16(SATURATE(PSHR32(y1k,15),32767)); + y2[k] = EXTRACT16(SATURATE(PSHR32(y2k,15),32767)); + } +} + +/* Re-synthesised a signal from the QMF low-band and high-band signals */ +void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack) + /* assumptions: + all odd x[i] are zero -- well, actually they are left out of the array now + N and M are multiples of 4 */ +{ + int i, j; + int M2, N2; + VARDECL(spx_word16_t *xx1); + VARDECL(spx_word16_t *xx2); + + M2 = M>>1; + N2 = N>>1; + ALLOC(xx1, M2+N2, spx_word16_t); + ALLOC(xx2, M2+N2, spx_word16_t); + + for (i = 0; i < N2; i++) + xx1[i] = x1[N2-1-i]; + for (i = 0; i < M2; i++) + xx1[N2+i] = mem1[2*i+1]; + for (i = 0; i < N2; i++) + xx2[i] = x2[N2-1-i]; + for (i = 0; i < M2; i++) + xx2[N2+i] = mem2[2*i+1]; + + for (i = 0; i < N2; i += 2) { + spx_sig_t y0, y1, y2, y3; + spx_word16_t x10, x20; + + y0 = y1 = y2 = y3 = 0; + x10 = xx1[N2-2-i]; + x20 = xx2[N2-2-i]; + + for (j = 0; j < M2; j += 2) { + spx_word16_t x11, x21; + spx_word16_t a0, a1; + + a0 = a[2*j]; + a1 = a[2*j+1]; + x11 = xx1[N2-1+j-i]; + x21 = xx2[N2-1+j-i]; + +#ifdef FIXED_POINT + /* We multiply twice by the same coef to avoid overflows */ + y0 = MAC16_16(MAC16_16(y0, a0, x11), NEG16(a0), x21); + y1 = MAC16_16(MAC16_16(y1, a1, x11), a1, x21); + y2 = MAC16_16(MAC16_16(y2, a0, x10), NEG16(a0), x20); + y3 = MAC16_16(MAC16_16(y3, a1, x10), a1, x20); +#else + y0 = ADD32(y0,MULT16_16(a0, x11-x21)); + y1 = ADD32(y1,MULT16_16(a1, x11+x21)); + y2 = ADD32(y2,MULT16_16(a0, x10-x20)); + y3 = ADD32(y3,MULT16_16(a1, x10+x20)); +#endif + a0 = a[2*j+2]; + a1 = a[2*j+3]; + x10 = xx1[N2+j-i]; + x20 = xx2[N2+j-i]; + +#ifdef FIXED_POINT + /* We multiply twice by the same coef to avoid overflows */ + y0 = MAC16_16(MAC16_16(y0, a0, x10), NEG16(a0), x20); + y1 = MAC16_16(MAC16_16(y1, a1, x10), a1, x20); + y2 = MAC16_16(MAC16_16(y2, a0, x11), NEG16(a0), x21); + y3 = MAC16_16(MAC16_16(y3, a1, x11), a1, x21); +#else + y0 = ADD32(y0,MULT16_16(a0, x10-x20)); + y1 = ADD32(y1,MULT16_16(a1, x10+x20)); + y2 = ADD32(y2,MULT16_16(a0, x11-x21)); + y3 = ADD32(y3,MULT16_16(a1, x11+x21)); +#endif + } +#ifdef FIXED_POINT + y[2*i] = EXTRACT16(SATURATE32(PSHR32(y0,15),32767)); + y[2*i+1] = EXTRACT16(SATURATE32(PSHR32(y1,15),32767)); + y[2*i+2] = EXTRACT16(SATURATE32(PSHR32(y2,15),32767)); + y[2*i+3] = EXTRACT16(SATURATE32(PSHR32(y3,15),32767)); +#else + /* Normalize up explicitly if we're in float */ + y[2*i] = 2.f*y0; + y[2*i+1] = 2.f*y1; + y[2*i+2] = 2.f*y2; + y[2*i+3] = 2.f*y3; +#endif + } + + for (i = 0; i < M2; i++) + mem1[2*i+1] = xx1[i]; + for (i = 0; i < M2; i++) + mem2[2*i+1] = xx2[i]; +} + +#ifdef FIXED_POINT +#if 0 +const spx_word16_t shift_filt[3][7] = {{-33, 1043, -4551, 19959, 19959, -4551, 1043}, + {-98, 1133, -4425, 29179, 8895, -2328, 444}, + {444, -2328, 8895, 29179, -4425, 1133, -98}}; +#else +const spx_word16_t shift_filt[3][7] = {{-390, 1540, -4993, 20123, 20123, -4993, 1540}, + {-1064, 2817, -6694, 31589, 6837, -990, -209}, + {-209, -990, 6837, 31589, -6694, 2817, -1064}}; +#endif +#else +#if 0 +const float shift_filt[3][7] = {{-9.9369e-04, 3.1831e-02, -1.3889e-01, 6.0910e-01, 6.0910e-01, -1.3889e-01, 3.1831e-02}, + {-0.0029937, 0.0345613, -0.1350474, 0.8904793, 0.2714479, -0.0710304, 0.0135403}, + {0.0135403, -0.0710304, 0.2714479, 0.8904793, -0.1350474, 0.0345613, -0.0029937}}; +#else +const float shift_filt[3][7] = {{-0.011915f, 0.046995f, -0.152373f, 0.614108f, 0.614108f, -0.152373f, 0.046995f}, + {-0.0324855f, 0.0859768f, -0.2042986f, 0.9640297f, 0.2086420f, -0.0302054f, -0.0063646f}, + {-0.0063646f, -0.0302054f, 0.2086420f, 0.9640297f, -0.2042986f, 0.0859768f, -0.0324855f}}; +#endif +#endif + +int interp_pitch( +spx_word16_t *exc, /*decoded excitation*/ +spx_word16_t *interp, /*decoded excitation*/ +int pitch, /*pitch period*/ +int len +) +{ + int i,j,k; + spx_word32_t corr[4][7]; + spx_word32_t maxcorr; + int maxi, maxj; + for (i=0;i<7;i++) + { + corr[0][i] = inner_prod(exc, exc-pitch-3+i, len); + } + for (i=0;i<3;i++) + { + for (j=0;j<7;j++) + { + int i1, i2; + spx_word32_t tmp=0; + i1 = 3-j; + if (i1<0) + i1 = 0; + i2 = 10-j; + if (i2>7) + i2 = 7; + for (k=i1;k<i2;k++) + tmp += MULT16_32_Q15(shift_filt[i][k],corr[0][j+k-3]); + corr[i+1][j] = tmp; + } + } + maxi=maxj=0; + maxcorr = corr[0][0]; + for (i=0;i<4;i++) + { + for (j=0;j<7;j++) + { + if (corr[i][j] > maxcorr) + { + maxcorr = corr[i][j]; + maxi=i; + maxj=j; + } + } + } + for (i=0;i<len;i++) + { + spx_word32_t tmp = 0; + if (maxi>0) + { + for (k=0;k<7;k++) + { + tmp += MULT16_16(exc[i-(pitch-maxj+3)+k-3],shift_filt[maxi-1][k]); + } + } else { + tmp = SHL32(exc[i-(pitch-maxj+3)],15); + } + interp[i] = PSHR32(tmp,15); + } + return pitch-maxj+3; +} + +void multicomb( +spx_word16_t *exc, /*decoded excitation*/ +spx_word16_t *new_exc, /*enhanced excitation*/ +spx_coef_t *ak, /*LPC filter coefs*/ +int p, /*LPC order*/ +int nsf, /*sub-frame size*/ +int pitch, /*pitch period*/ +int max_pitch, +spx_word16_t comb_gain, /*gain of comb filter*/ +char *stack +) +{ + int i; + VARDECL(spx_word16_t *iexc); + spx_word16_t old_ener, new_ener; + int corr_pitch; + + spx_word16_t iexc0_mag, iexc1_mag, exc_mag; + spx_word32_t corr0, corr1; + spx_word16_t gain0, gain1; + spx_word16_t pgain1, pgain2; + spx_word16_t c1, c2; + spx_word16_t g1, g2; + spx_word16_t ngain; + spx_word16_t gg1, gg2; +#ifdef FIXED_POINT + int scaledown=0; +#endif +#if 0 /* Set to 1 to enable full pitch search */ + int nol_pitch[6]; + spx_word16_t nol_pitch_coef[6]; + spx_word16_t ol_pitch_coef; + open_loop_nbest_pitch(exc, 20, 120, nsf, + nol_pitch, nol_pitch_coef, 6, stack); + corr_pitch=nol_pitch[0]; + ol_pitch_coef = nol_pitch_coef[0]; + /*Try to remove pitch multiples*/ + for (i=1;i<6;i++) + { +#ifdef FIXED_POINT + if ((nol_pitch_coef[i]>MULT16_16_Q15(nol_pitch_coef[0],19661)) && +#else + if ((nol_pitch_coef[i]>.6*nol_pitch_coef[0]) && +#endif + (ABS(2*nol_pitch[i]-corr_pitch)<=2 || ABS(3*nol_pitch[i]-corr_pitch)<=3 || + ABS(4*nol_pitch[i]-corr_pitch)<=4 || ABS(5*nol_pitch[i]-corr_pitch)<=5)) + { + corr_pitch = nol_pitch[i]; + } + } +#else + corr_pitch = pitch; +#endif + + ALLOC(iexc, 2*nsf, spx_word16_t); + + interp_pitch(exc, iexc, corr_pitch, 80); + if (corr_pitch>max_pitch) + interp_pitch(exc, iexc+nsf, 2*corr_pitch, 80); + else + interp_pitch(exc, iexc+nsf, -corr_pitch, 80); + +#ifdef FIXED_POINT + for (i=0;i<nsf;i++) + { + if (ABS16(exc[i])>16383) + { + scaledown = 1; + break; + } + } + if (scaledown) + { + for (i=0;i<nsf;i++) + exc[i] = SHR16(exc[i],1); + for (i=0;i<2*nsf;i++) + iexc[i] = SHR16(iexc[i],1); + } +#endif + /*interp_pitch(exc, iexc+2*nsf, 2*corr_pitch, 80);*/ + + /*printf ("%d %d %f\n", pitch, corr_pitch, max_corr*ener_1);*/ + iexc0_mag = spx_sqrt(1000+inner_prod(iexc,iexc,nsf)); + iexc1_mag = spx_sqrt(1000+inner_prod(iexc+nsf,iexc+nsf,nsf)); + exc_mag = spx_sqrt(1+inner_prod(exc,exc,nsf)); + corr0 = inner_prod(iexc,exc,nsf); + if (corr0<0) + corr0=0; + corr1 = inner_prod(iexc+nsf,exc,nsf); + if (corr1<0) + corr1=0; +#ifdef FIXED_POINT + /* Doesn't cost much to limit the ratio and it makes the rest easier */ + if (SHL32(EXTEND32(iexc0_mag),6) < EXTEND32(exc_mag)) + iexc0_mag = ADD16(1,PSHR16(exc_mag,6)); + if (SHL32(EXTEND32(iexc1_mag),6) < EXTEND32(exc_mag)) + iexc1_mag = ADD16(1,PSHR16(exc_mag,6)); +#endif + if (corr0 > MULT16_16(iexc0_mag,exc_mag)) + pgain1 = QCONST16(1., 14); + else + pgain1 = PDIV32_16(SHL32(PDIV32(corr0, exc_mag),14),iexc0_mag); + if (corr1 > MULT16_16(iexc1_mag,exc_mag)) + pgain2 = QCONST16(1., 14); + else + pgain2 = PDIV32_16(SHL32(PDIV32(corr1, exc_mag),14),iexc1_mag); + gg1 = PDIV32_16(SHL32(EXTEND32(exc_mag),8), iexc0_mag); + gg2 = PDIV32_16(SHL32(EXTEND32(exc_mag),8), iexc1_mag); + if (comb_gain>0) + { +#ifdef FIXED_POINT + c1 = (MULT16_16_Q15(QCONST16(.4,15),comb_gain)+QCONST16(.07,15)); + c2 = QCONST16(.5,15)+MULT16_16_Q14(QCONST16(1.72,14),(c1-QCONST16(.07,15))); +#else + c1 = .4*comb_gain+.07; + c2 = .5+1.72*(c1-.07); +#endif + } else + { + c1=c2=0; + } +#ifdef FIXED_POINT + g1 = 32767 - MULT16_16_Q13(MULT16_16_Q15(c2, pgain1),pgain1); + g2 = 32767 - MULT16_16_Q13(MULT16_16_Q15(c2, pgain2),pgain2); +#else + g1 = 1-c2*pgain1*pgain1; + g2 = 1-c2*pgain2*pgain2; +#endif + if (g1<c1) + g1 = c1; + if (g2<c1) + g2 = c1; + g1 = (spx_word16_t)PDIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g1); + g2 = (spx_word16_t)PDIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g2); + if (corr_pitch>max_pitch) + { + gain0 = MULT16_16_Q15(QCONST16(.7,15),MULT16_16_Q14(g1,gg1)); + gain1 = MULT16_16_Q15(QCONST16(.3,15),MULT16_16_Q14(g2,gg2)); + } else { + gain0 = MULT16_16_Q15(QCONST16(.6,15),MULT16_16_Q14(g1,gg1)); + gain1 = MULT16_16_Q15(QCONST16(.6,15),MULT16_16_Q14(g2,gg2)); + } + for (i=0;i<nsf;i++) + new_exc[i] = ADD16(exc[i], EXTRACT16(PSHR32(ADD32(MULT16_16(gain0,iexc[i]), MULT16_16(gain1,iexc[i+nsf])),8))); + /* FIXME: compute_rms16 is currently not quite accurate enough (but close) */ + new_ener = compute_rms16(new_exc, nsf); + old_ener = compute_rms16(exc, nsf); + + if (old_ener < 1) + old_ener = 1; + if (new_ener < 1) + new_ener = 1; + if (old_ener > new_ener) + old_ener = new_ener; + ngain = PDIV32_16(SHL32(EXTEND32(old_ener),14),new_ener); + + for (i=0;i<nsf;i++) + new_exc[i] = MULT16_16_Q14(ngain, new_exc[i]); +#ifdef FIXED_POINT + if (scaledown) + { + for (i=0;i<nsf;i++) + exc[i] = SHL16(exc[i],1); + for (i=0;i<nsf;i++) + new_exc[i] = SHL16(SATURATE16(new_exc[i],16383),1); + } +#endif +} + diff --git a/src/libs/speex/libspeex/filters.h b/src/libs/speex/libspeex/filters.h new file mode 100644 index 00000000..e3a5980e --- /dev/null +++ b/src/libs/speex/libspeex/filters.h @@ -0,0 +1,90 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file filters.h + @brief Various analysis/synthesis filters +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FILTERS_H +#define FILTERS_H + +#include "arch.h" + +spx_word16_t compute_rms(const spx_sig_t *x, int len); +spx_word16_t compute_rms16(const spx_word16_t *x, int len); +void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len); +void signal_div(const spx_word16_t *x, spx_word16_t *y, spx_word32_t scale, int len); + +#ifdef FIXED_POINT + +int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len); + +#endif + + +#define HIGHPASS_NARROWBAND 0 +#define HIGHPASS_WIDEBAND 2 +#define HIGHPASS_INPUT 0 +#define HIGHPASS_OUTPUT 1 +#define HIGHPASS_IRS 4 + +void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem); + + +void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *, spx_word16_t *y2, int N, int M, spx_word16_t *mem, char *stack); +void qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack); + +void filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack); +void iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack); +void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack); + +/* Apply bandwidth expansion on LPC coef */ +void bw_lpc(spx_word16_t , const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order); +void sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len); + + +void syn_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack); +void residue_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack); + +void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack); + +void multicomb( +spx_word16_t *exc, /*decoded excitation*/ +spx_word16_t *new_exc, /*enhanced excitation*/ +spx_coef_t *ak, /*LPC filter coefs*/ +int p, /*LPC order*/ +int nsf, /*sub-frame size*/ +int pitch, /*pitch period*/ +int max_pitch, /*pitch gain (3-tap)*/ +spx_word16_t comb_gain, /*gain of comb filter*/ +char *stack +); + +#endif diff --git a/src/libs/speex/libspeex/filters_arm4.h b/src/libs/speex/libspeex/filters_arm4.h new file mode 100644 index 00000000..7a740424 --- /dev/null +++ b/src/libs/speex/libspeex/filters_arm4.h @@ -0,0 +1,96 @@ +/* Copyright (C) 2004 Jean-Marc Valin */ +/** + @file filters_arm4.h + @brief Various analysis/synthesis filters (ARM4 version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define OVERRIDE_NORMALIZE16 +int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len) +{ + spx_sig_t max_val=1; + int sig_shift; + int dead1, dead2, dead3, dead4, dead5, dead6; + + __asm__ __volatile__ ( + "\tmov %1, #1 \n" + "\tmov %3, #0 \n" + + ".normalize16loop1%=: \n" + + "\tldr %4, [%0], #4 \n" + "\tcmps %4, %1 \n" + "\tmovgt %1, %4 \n" + "\tcmps %4, %3 \n" + "\tmovlt %3, %4 \n" + + "\tsubs %2, %2, #1 \n" + "\tbne .normalize16loop1%=\n" + + "\trsb %3, %3, #0 \n" + "\tcmp %1, %3 \n" + "\tmovlt %1, %3 \n" + : "=r" (dead1), "=r" (max_val), "=r" (dead3), "=r" (dead4), + "=r" (dead5), "=r" (dead6) + : "0" (x), "2" (len) + : "cc"); + + sig_shift=0; + while (max_val>max_scale) + { + sig_shift++; + max_val >>= 1; + } + + __asm__ __volatile__ ( + ".normalize16loop%=: \n" + + "\tldr %4, [%0], #4 \n" + "\tldr %5, [%0], #4 \n" + "\tmov %4, %4, asr %3 \n" + "\tstrh %4, [%1], #2 \n" + "\tldr %4, [%0], #4 \n" + "\tmov %5, %5, asr %3 \n" + "\tstrh %5, [%1], #2 \n" + "\tldr %5, [%0], #4 \n" + "\tmov %4, %4, asr %3 \n" + "\tstrh %4, [%1], #2 \n" + "\tsubs %2, %2, #1 \n" + "\tmov %5, %5, asr %3 \n" + "\tstrh %5, [%1], #2 \n" + + "\tbgt .normalize16loop%=\n" + : "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4), + "=r" (dead5), "=r" (dead6) + : "0" (x), "1" (y), "2" (len>>2), "3" (sig_shift) + : "cc", "memory"); + return sig_shift; +} + diff --git a/src/libs/speex/libspeex/filters_bfin.h b/src/libs/speex/libspeex/filters_bfin.h new file mode 100644 index 00000000..1e433ee1 --- /dev/null +++ b/src/libs/speex/libspeex/filters_bfin.h @@ -0,0 +1,515 @@ +/* Copyright (C) 2005 Analog Devices */ +/** + @file filters_bfin.h + @brief Various analysis/synthesis filters (Blackfin version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define OVERRIDE_NORMALIZE16 +int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len) +{ + spx_sig_t max_val=1; + int sig_shift; + __asm__ + ( + "%0 = 0;\n\t" + "I0 = %1;\n\t" + "L0 = 0;\n\t" + "R1 = [I0++];\n\t" + "LOOP norm_max%= LC0 = %2;\n\t" + "LOOP_BEGIN norm_max%=;\n\t" + "R2 = ABS R1 || R1 = [I0++];\n\t" + "%0 = MAX(%0, R2);\n\t" + "LOOP_END norm_max%=;\n\t" + : "=&d" (max_val) + : "a" (x), "a" (len) + : "R1", "R2" + ); + + sig_shift=0; + while (max_val>max_scale) + { + sig_shift++; + max_val >>= 1; + } + + __asm__ __volatile__ + ( + "I0 = %0;\n\t" + "L0 = 0;\n\t" + "P1 = %1;\n\t" + "R0 = [I0++];\n\t" + "LOOP norm_shift%= LC0 = %3;\n\t" + "LOOP_BEGIN norm_shift%=;\n\t" + "R1 = ASHIFT R0 by %2.L || R0 = [I0++];\n\t" + "W[P1++] = R1;\n\t" + "LOOP_END norm_shift%=;\n\t" + "R1 = ASHIFT R0 by %2.L;\n\t" + "W[P1++] = R1;\n\t" + : : "a" (x), "a" (y), "d" (-sig_shift), "a" (len-1) + : "I0", "L0", "P1", "R0", "R1", "memory" + ); + return sig_shift; +} + + + +#define OVERRIDE_FILTER_MEM16 +void filter_mem16(const spx_word16_t *_x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *_y, int N, int ord, spx_mem_t *mem, char *stack) +{ + VARDECL(spx_word32_t *xy2); + VARDECL(spx_word32_t *numden_a); + spx_word32_t *xy; + spx_word16_t *numden; + int i; + + ALLOC(xy2, (N+1), spx_word32_t); + ALLOC(numden_a, (2*ord+2), spx_word32_t); + xy = xy2+1; + numden = (spx_word16_t*) numden_a; + + for (i=0;i<ord;i++) + { + numden[2*i] = num[i]; + numden[2*i+1] = den[i]; + } + __asm__ __volatile__ + ( + /* Register setup */ + "R0 = %5;\n\t" /*ord */ + + "P0 = %3;\n\t" + "I0 = P0;\n\t" + "B0 = P0;\n\t" /* numden */ + "L0 = 0;\n\t" + + "P2 = %0;\n\t" /* Fused xy */ + "I2 = P2;\n\t" + "L2 = 0;\n\t" + + "P4 = %6;\n\t" /* mem */ + "P0 = %1;\n\t" /* _x */ + "P1 = %2;\n\t" /* _y */ + + /* First sample */ + "R1 = [P4++];\n\t" + "R1 <<= 3;\n\t" /* shift mem */ + "R1.L = R1 (RND);\n\t" + "R2 = W[P0++];\n\t" /* load x[0] */ + "R1.L = R1.L + R2.L;\n\t" + "W[P1++] = R1;\n\t" /* store y[0] */ + "R2 = PACK(R1.L, R2.L);\n\t" /* pack x16 and y16 */ + "[P2] = R2;\n\t" + + /* Samples 1 to ord-1 (using memory) */ + "R0 += -1;\n\t" + "R3 = 0;\n\t" + "LC0 = R0;\n\t" + "LOOP filter_start%= LC0;\n\t" + "LOOP_BEGIN filter_start%=;\n\t" + "R3 += 1;\n\t" + "LC1 = R3;\n\t" + + "R1 = [P4++];\n\t" + "A1 = R1;\n\t" + "A0 = 0;\n\t" + "I0 = B0;\n\t" + "I2 = P2;\n\t" + "P2 += 4;\n\t" + "R4 = [I0++] || R5 = [I2--];\n\t" + "LOOP filter_start_inner%= LC1;\n\t" + "LOOP_BEGIN filter_start_inner%=;\n\t" + "A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\n\t" + "LOOP_END filter_start_inner%=;\n\t" + "A0 += A1;\n\t" + "R4 = A0;\n\t" + "R4 <<= 3;\n\t" /* shift mem */ + "R4.L = R4 (RND);\n\t" + "R2 = W[P0++];\n\t" /* load x */ + "R4.L = R4.L + R2.L;\n\t" + "W[P1++] = R4;\n\t" /* store y */ + //"R4 <<= 2;\n\t" + //"R2 <<= 2;\n\t" + "R2 = PACK(R4.L, R2.L);\n\t" /* pack x16 and y16 */ + "[P2] = R2;\n\t" + + "LOOP_END filter_start%=;\n\t" + + /* Samples ord to N*/ + "R0 = %5;\n\t" + "R0 <<= 1;\n\t" + "I0 = B0;\n\t" /* numden */ + "R0 <<= 1;\n\t" + "L0 = R0;\n\t" + + "R0 = %5;\n\t" /* org */ + "R2 = %4;\n\t" /* N */ + "R2 = R2 - R0;\n\t" + "R4 = [I0++];\n\t" /* numden */ + "LC0 = R2;\n\t" + "P3 = R0;\n\t" + "R0 <<= 2;\n\t" + "R0 += 8;\n\t" + "I2 = P2;\n\t" + "M0 = R0;\n\t" + "A1 = A0 = 0;\n\t" + "R5 = [I2--];\n\t" /* load xy */ + "LOOP filter_mid%= LC0;\n\t" + "LOOP_BEGIN filter_mid%=;\n\t" + "LOOP filter_mid_inner%= LC1=P3;\n\t" + "LOOP_BEGIN filter_mid_inner%=;\n\t" + "A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\n\t" + "LOOP_END filter_mid_inner%=;\n\t" + "R0 = (A0 += A1) || I2 += M0;\n\t" + "R0 = R0 << 3 || R5 = W[P0++];\n\t" /* load x */ + "R0.L = R0 (RND);\n\t" + "R0.L = R0.L + R5.L;\n\t" + "R5 = PACK(R0.L, R5.L) || W[P1++] = R0;\n\t" /* shift y | store y */ + "A1 = A0 = 0 || [I2--] = R5\n\t" + "LOOP_END filter_mid%=;\n\t" + "I2 += 4;\n\t" + "P2 = I2;\n\t" + /* Update memory */ + "P4 = %6;\n\t" + "R0 = %5;\n\t" + "LC0 = R0;\n\t" + "P0 = B0;\n\t" + "A1 = A0 = 0;\n\t" + "LOOP mem_update%= LC0;\n\t" + "LOOP_BEGIN mem_update%=;\n\t" + "I2 = P2;\n\t" + "I0 = P0;\n\t" + "P0 += 4;\n\t" + "R0 = LC0;\n\t" + "LC1 = R0;\n\t" + "R5 = [I2--] || R4 = [I0++];\n\t" + "LOOP mem_accum%= LC1;\n\t" + "LOOP_BEGIN mem_accum%=;\n\t" + "A1 -= R4.H*R5.H, A0 += R4.L*R5.L (IS) || R4 = [I0++] || R5 = [I2--];\n\t" + "LOOP_END mem_accum%=;\n\t" + "R0 = (A0 += A1);\n\t" + "A1 = A0 = 0 || [P4++] = R0;\n\t" + "LOOP_END mem_update%=;\n\t" + "L0 = 0;\n\t" + : : "m" (xy), "m" (_x), "m" (_y), "m" (numden), "m" (N), "m" (ord), "m" (mem) + : "A0", "A1", "R0", "R1", "R2", "R3", "R4", "R5", "P0", "P1", "P2", "P3", "P4", "B0", "I0", "I2", "L0", "L2", "M0", "memory" + ); + +} + + + +#define OVERRIDE_IIR_MEM16 +void iir_mem16(const spx_word16_t *_x, const spx_coef_t *den, spx_word16_t *_y, int N, int ord, spx_mem_t *mem, char *stack) +{ + VARDECL(spx_word16_t *y); + spx_word16_t *yy; + + ALLOC(y, (N+2), spx_word16_t); + yy = y+2; + + __asm__ __volatile__ + ( + /* Register setup */ + "R0 = %5;\n\t" /*ord */ + + "P1 = %3;\n\t" + "I1 = P1;\n\t" + "B1 = P1;\n\t" + "L1 = 0;\n\t" + + "P3 = %0;\n\t" + "I3 = P3;\n\t" + "L3 = 0;\n\t" + + "P4 = %6;\n\t" + "P0 = %1;\n\t" + "P1 = %2;\n\t" + + /* First sample */ + "R1 = [P4++];\n\t" + "R1 = R1 << 3 (S);\n\t" + "R1.L = R1 (RND);\n\t" + "R2 = W[P0++];\n\t" + "R1 = R1 + R2;\n\t" + "W[P1++] = R1;\n\t" + "W[P3] = R1;\n\t" + + /* Samples 1 to ord-1 (using memory) */ + "R0 += -1;\n\t" + "R3 = 0;\n\t" + "LC0 = R0;\n\t" + "LOOP filter_start%= LC0;\n\t" + "LOOP_BEGIN filter_start%=;\n\t" + "R3 += 1;\n\t" + "LC1 = R3;\n\t" + + "R1 = [P4++];\n\t" + "A1 = R1;\n\t" + "I1 = B1;\n\t" + "I3 = P3;\n\t" + "P3 += 2;\n\t" + "LOOP filter_start_inner%= LC1;\n\t" + "LOOP_BEGIN filter_start_inner%=;\n\t" + "R4.L = W[I1++];\n\t" + "R5.L = W[I3--];\n\t" + "A1 -= R4.L*R5.L (IS);\n\t" + "LOOP_END filter_start_inner%=;\n\t" + + "R1 = A1;\n\t" + "R1 <<= 3;\n\t" + "R1.L = R1 (RND);\n\t" + "R2 = W[P0++];\n\t" + "R1 = R1 + R2;\n\t" + "W[P1++] = R1;\n\t" + "W[P3] = R1;\n\t" + "LOOP_END filter_start%=;\n\t" + + /* Samples ord to N*/ + "R0 = %5;\n\t" + "R0 <<= 1;\n\t" + "I1 = B1;\n\t" + "L1 = R0;\n\t" + + "R0 = %5;\n\t" + "R2 = %4;\n\t" + "R2 = R2 - R0;\n\t" + "R4.L = W[I1++];\n\t" + "LC0 = R2;\n\t" + "LOOP filter_mid%= LC0;\n\t" + "LOOP_BEGIN filter_mid%=;\n\t" + "LC1 = R0;\n\t" + "A1 = 0;\n\t" + "I3 = P3;\n\t" + "P3 += 2;\n\t" + "R5.L = W[I3--];\n\t" + "LOOP filter_mid_inner%= LC1;\n\t" + "LOOP_BEGIN filter_mid_inner%=;\n\t" + "A1 -= R4.L*R5.L (IS) || R4.L = W[I1++] || R5.L = W[I3--];\n\t" + "LOOP_END filter_mid_inner%=;\n\t" + "R1 = A1;\n\t" + "R1 = R1 << 3 || R2 = W[P0++];\n\t" + "R1.L = R1 (RND);\n\t" + "R1 = R1 + R2;\n\t" + "W[P1++] = R1;\n\t" + "W[P3] = R1;\n\t" + "LOOP_END filter_mid%=;\n\t" + + /* Update memory */ + "P4 = %6;\n\t" + "R0 = %5;\n\t" + "LC0 = R0;\n\t" + "P1 = B1;\n\t" + "LOOP mem_update%= LC0;\n\t" + "LOOP_BEGIN mem_update%=;\n\t" + "A0 = 0;\n\t" + "I3 = P3;\n\t" + "I1 = P1;\n\t" + "P1 += 2;\n\t" + "R0 = LC0;\n\t" + "LC1=R0;\n\t" + "R5.L = W[I3--] || R4.L = W[I1++];\n\t" + "LOOP mem_accum%= LC1;\n\t" + "LOOP_BEGIN mem_accum%=;\n\t" + "A0 -= R4.L*R5.L (IS) || R4.L = W[I1++] || R5.L = W[I3--];\n\t" + "LOOP_END mem_accum%=;\n\t" + "R0 = A0;\n\t" + "[P4++] = R0;\n\t" + "LOOP_END mem_update%=;\n\t" + "L1 = 0;\n\t" + : : "m" (yy), "m" (_x), "m" (_y), "m" (den), "m" (N), "m" (ord), "m" (mem) + : "A0", "A1", "R0", "R1", "R2", "R3", "R4", "R5", "P0", "P1", "P2", "P3", "P4", "B1", "I1", "I3", "L1", "L3", "memory" + ); + +} + + +#define OVERRIDE_FIR_MEM16 +void fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack) +{ + int i; + spx_coef_t den2[12]; + spx_coef_t *den; + den = (spx_coef_t*)((((int)den2)+4)&0xfffffffc); + for (i=0;i<10;i++) + den[i] = 0; + filter_mem16(x, num, den, y, N, ord, mem, stack); +} + + +#define OVERRIDE_COMPUTE_IMPULSE_RESPONSE +void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack) +{ + int i; + VARDECL(spx_word16_t *ytmp); + ALLOC(ytmp, N, spx_word16_t); + spx_word16_t *ytmp2 = ytmp; + y[0] = LPC_SCALING; + for (i=0;i<ord;i++) + y[i+1] = awk1[i]; + i++; + for (;i<N;i++) + y[i] = 0; + + N-=1; + __asm__ __volatile__ + ( + "I0 = %0;\n\t" + "I1 = %1;\n\t" + "L0 = 0;\n\t" + "L1 = 0;\n\t" + "L2 = 0;\n\t" + "L3 = 0;\n\t" + "R0 = 1;\n\t" + "R0 <<= 13;\n\t" + "W[I0] = R0.L;\n\t" + "R0 <<= 1;\n\t" + "W[I1] = R0.L;\n\t" + "R0 = %5;\n\t" + "LC0 = R0;\n\t" + "R2 = 0;\n\t" + "LOOP samples%= LC0;\n\t" + "LOOP_BEGIN samples%=;\n\t" + "R2 += 1;\n\t" + "R2 = MIN(R2, %4);\n\t" + "I0 = %0;\n\t" + "I1 = %1;\n\t" + "I2 = %2;\n\t" + "I3 = %3;\n\t" + "%0 += 2;\n\t" + "%1 += 2;\n\t" + "A1 = A0 = 0;\n\t" + "R0.L = W[I0--] || R1.L = W[I2++];\n\t" + "LC1 = R2;\n\t" + "LOOP filter%= LC1;\n\t" + "LOOP_BEGIN filter%=;\n\t" + "A0 -= R0.L*R1.L (IS) || R0.L = W[I1--] || R1.L = W[I3++];\n\t" + "A1 -= R0.L*R1.L (IS) || R0.L = W[I0--] || R1.L = W[I2++];\n\t" + "LOOP_END filter%=;\n\t" + "R0 = A0, R1 = A1;\n\t" + "R3 = W[%1] (X);\n\t" + "R3 <<= 13;\n\t" + "R0 = R0 + R3;\n\t" + "R3 = R0 >>> 13;\n\t" + "W[%0] = R3.L;\n\t" + "R0 <<= 1;\n\t" + "R1 = R1 + R0;\n\t" + "R1 >>>= 13;\n\t" + "W[%1] = R1.L;\n\t" + "LOOP_END samples%=;\n\t" + : "=a" (ytmp2), "=a" (y) + : "a" (awk2), "a" (ak), "d" (ord), "m" (N), "0" (ytmp2), "1" (y) + : "A0", "A1", "R0", "R1", "R2", "R3", "I0", "I1", "I2", "I3", "L0", "L1", "L2", "L3", "A0", "A1" + ); +} + + + +#if 0 /* Equivalent C function for filter_mem2 and compute_impulse_response */ +#define min(a,b) ((a)<(b) ? (a):(b)) + +void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack) +{ + int i,j; + VARDECL(spx_word16_t *ytmp); + ALLOC(ytmp, N, spx_word16_t); + + y[0] = LPC_SCALING; + for (i=0;i<ord;i++) + y[i+1] = awk1[i]; + i++; + for (;i<N;i++) + y[i] = 0; + + for (i=0;i<N;i++) + { + spx_word32_t yi = SHL32(EXTEND32(y[i]),LPC_SHIFT); + spx_word32_t yi2 = 0; + for (j=0;j<min(i,ord);j++) + { + yi = MAC16_16(yi, awk2[j], -ytmp[i-j-1]); + yi2 = MAC16_16(yi2, ak[j], -y[i-j-1]); + } + ytmp[i] = EXTRACT16(SHR32(yi,LPC_SHIFT)); + yi2 = ADD32(yi2,SHL32(yi,1)); + y[i] = EXTRACT16(SHR32(yi2,LPC_SHIFT)); + } + +} + + +void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *_y, int N, int ord, spx_mem_t *mem) +{ + int i,j; + spx_word16_t xi,yi,nyi; + spx_word16_t x[N],y[N]; + spx_word16_t *xx, *yy; + xx = x; + yy = y; + for (i=0;i<N;i++) + { + x[i] = EXTRACT16(SHR32(_x[i],SIG_SHIFT)); + } + + for (i=0;i<ord;i++) + { + spx_word32_t yi = mem[i]; + for (j=0;j<i;j++) + { + yi = MAC16_16(yi, num[j], x[i-j-1]); + yi = MAC16_16(yi, den[j], -y[i-j-1]); + } + _y[i] = ADD32(_x[i],SHL32(yi,1)); + y[i] = EXTRACT16(SHR32(_y[i],SIG_SHIFT)); + } + for (i=ord;i<N;i++) + { + spx_word32_t yi = 0; + for (j=0;j<ord;j++) + { + yi = MAC16_16(yi, num[j], x[i-j-1]); + yi = MAC16_16(yi, den[j], -y[i-j-1]); + } + _y[i] = ADD32(_x[i],SHL32(yi,1)); + y[i] = EXTRACT16(SHR32(_y[i],SIG_SHIFT)); + } + + for (i=0;i<ord;i++) + { + spx_mem_t m = 0; + for (j=0;j<ord-i;j++) + { + m = MAC16_16(m, x[N-1-j], num[j+i]); + m = MAC16_16(m, -y[N-1-j], den[j+i]); + } + mem[i] = m; + } +} +#endif diff --git a/src/libs/speex/libspeex/filters_sse.h b/src/libs/speex/libspeex/filters_sse.h new file mode 100644 index 00000000..4bb333da --- /dev/null +++ b/src/libs/speex/libspeex/filters_sse.h @@ -0,0 +1,336 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file filters_sse.h + @brief Various analysis/synthesis filters (SSE version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <xmmintrin.h> + +void filter_mem16_10(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem) +{ + __m128 num[3], den[3], mem[3]; + + int i; + + /* Copy numerator, denominator and memory to aligned xmm */ + for (i=0;i<2;i++) + { + mem[i] = _mm_loadu_ps(_mem+4*i); + num[i] = _mm_loadu_ps(_num+4*i); + den[i] = _mm_loadu_ps(_den+4*i); + } + mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0); + num[2] = _mm_setr_ps(_num[8], _num[9], 0, 0); + den[2] = _mm_setr_ps(_den[8], _den[9], 0, 0); + + for (i=0;i<N;i++) + { + __m128 xx; + __m128 yy; + /* Compute next filter result */ + xx = _mm_load_ps1(x+i); + yy = _mm_add_ss(xx, mem[0]); + _mm_store_ss(y+i, yy); + yy = _mm_shuffle_ps(yy, yy, 0); + + /* Update memory */ + mem[0] = _mm_move_ss(mem[0], mem[1]); + mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39); + + mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0])); + mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0])); + + mem[1] = _mm_move_ss(mem[1], mem[2]); + mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39); + + mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1])); + mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1])); + + mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd); + + mem[2] = _mm_add_ps(mem[2], _mm_mul_ps(xx, num[2])); + mem[2] = _mm_sub_ps(mem[2], _mm_mul_ps(yy, den[2])); + } + /* Put memory back in its place */ + _mm_storeu_ps(_mem, mem[0]); + _mm_storeu_ps(_mem+4, mem[1]); + _mm_store_ss(_mem+8, mem[2]); + mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55); + _mm_store_ss(_mem+9, mem[2]); +} + +void filter_mem16_8(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem) +{ + __m128 num[2], den[2], mem[2]; + + int i; + + /* Copy numerator, denominator and memory to aligned xmm */ + for (i=0;i<2;i++) + { + mem[i] = _mm_loadu_ps(_mem+4*i); + num[i] = _mm_loadu_ps(_num+4*i); + den[i] = _mm_loadu_ps(_den+4*i); + } + + for (i=0;i<N;i++) + { + __m128 xx; + __m128 yy; + /* Compute next filter result */ + xx = _mm_load_ps1(x+i); + yy = _mm_add_ss(xx, mem[0]); + _mm_store_ss(y+i, yy); + yy = _mm_shuffle_ps(yy, yy, 0); + + /* Update memory */ + mem[0] = _mm_move_ss(mem[0], mem[1]); + mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39); + + mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0])); + mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0])); + + mem[1] = _mm_sub_ss(mem[1], mem[1]); + mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39); + + mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1])); + mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1])); + } + /* Put memory back in its place */ + _mm_storeu_ps(_mem, mem[0]); + _mm_storeu_ps(_mem+4, mem[1]); +} + + +#define OVERRIDE_FILTER_MEM16 +void filter_mem16(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem, char *stack) +{ + if(ord==10) + filter_mem16_10(x, _num, _den, y, N, ord, _mem); + else if (ord==8) + filter_mem16_8(x, _num, _den, y, N, ord, _mem); +} + + + +void iir_mem16_10(const float *x, const float *_den, float *y, int N, int ord, float *_mem) +{ + __m128 den[3], mem[3]; + + int i; + + /* Copy numerator, denominator and memory to aligned xmm */ + for (i=0;i<2;i++) + { + mem[i] = _mm_loadu_ps(_mem+4*i); + den[i] = _mm_loadu_ps(_den+4*i); + } + mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0); + den[2] = _mm_setr_ps(_den[8], _den[9], 0, 0); + + for (i=0;i<N;i++) + { + __m128 xx; + __m128 yy; + /* Compute next filter result */ + xx = _mm_load_ps1(x+i); + yy = _mm_add_ss(xx, mem[0]); + _mm_store_ss(y+i, yy); + yy = _mm_shuffle_ps(yy, yy, 0); + + /* Update memory */ + mem[0] = _mm_move_ss(mem[0], mem[1]); + mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39); + + mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0])); + + mem[1] = _mm_move_ss(mem[1], mem[2]); + mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39); + + mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1])); + + mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd); + + mem[2] = _mm_sub_ps(mem[2], _mm_mul_ps(yy, den[2])); + } + /* Put memory back in its place */ + _mm_storeu_ps(_mem, mem[0]); + _mm_storeu_ps(_mem+4, mem[1]); + _mm_store_ss(_mem+8, mem[2]); + mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55); + _mm_store_ss(_mem+9, mem[2]); +} + + +void iir_mem16_8(const float *x, const float *_den, float *y, int N, int ord, float *_mem) +{ + __m128 den[2], mem[2]; + + int i; + + /* Copy numerator, denominator and memory to aligned xmm */ + for (i=0;i<2;i++) + { + mem[i] = _mm_loadu_ps(_mem+4*i); + den[i] = _mm_loadu_ps(_den+4*i); + } + + for (i=0;i<N;i++) + { + __m128 xx; + __m128 yy; + /* Compute next filter result */ + xx = _mm_load_ps1(x+i); + yy = _mm_add_ss(xx, mem[0]); + _mm_store_ss(y+i, yy); + yy = _mm_shuffle_ps(yy, yy, 0); + + /* Update memory */ + mem[0] = _mm_move_ss(mem[0], mem[1]); + mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39); + + mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0])); + + mem[1] = _mm_sub_ss(mem[1], mem[1]); + mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39); + + mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1])); + } + /* Put memory back in its place */ + _mm_storeu_ps(_mem, mem[0]); + _mm_storeu_ps(_mem+4, mem[1]); +} + +#define OVERRIDE_IIR_MEM16 +void iir_mem16(const float *x, const float *_den, float *y, int N, int ord, float *_mem, char *stack) +{ + if(ord==10) + iir_mem16_10(x, _den, y, N, ord, _mem); + else if (ord==8) + iir_mem16_8(x, _den, y, N, ord, _mem); +} + + +void fir_mem16_10(const float *x, const float *_num, float *y, int N, int ord, float *_mem) +{ + __m128 num[3], mem[3]; + + int i; + + /* Copy numerator, denominator and memory to aligned xmm */ + for (i=0;i<2;i++) + { + mem[i] = _mm_loadu_ps(_mem+4*i); + num[i] = _mm_loadu_ps(_num+4*i); + } + mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0); + num[2] = _mm_setr_ps(_num[8], _num[9], 0, 0); + + for (i=0;i<N;i++) + { + __m128 xx; + __m128 yy; + /* Compute next filter result */ + xx = _mm_load_ps1(x+i); + yy = _mm_add_ss(xx, mem[0]); + _mm_store_ss(y+i, yy); + yy = _mm_shuffle_ps(yy, yy, 0); + + /* Update memory */ + mem[0] = _mm_move_ss(mem[0], mem[1]); + mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39); + + mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0])); + + mem[1] = _mm_move_ss(mem[1], mem[2]); + mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39); + + mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1])); + + mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd); + + mem[2] = _mm_add_ps(mem[2], _mm_mul_ps(xx, num[2])); + } + /* Put memory back in its place */ + _mm_storeu_ps(_mem, mem[0]); + _mm_storeu_ps(_mem+4, mem[1]); + _mm_store_ss(_mem+8, mem[2]); + mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55); + _mm_store_ss(_mem+9, mem[2]); +} + +void fir_mem16_8(const float *x, const float *_num, float *y, int N, int ord, float *_mem) +{ + __m128 num[2], mem[2]; + + int i; + + /* Copy numerator, denominator and memory to aligned xmm */ + for (i=0;i<2;i++) + { + mem[i] = _mm_loadu_ps(_mem+4*i); + num[i] = _mm_loadu_ps(_num+4*i); + } + + for (i=0;i<N;i++) + { + __m128 xx; + __m128 yy; + /* Compute next filter result */ + xx = _mm_load_ps1(x+i); + yy = _mm_add_ss(xx, mem[0]); + _mm_store_ss(y+i, yy); + yy = _mm_shuffle_ps(yy, yy, 0); + + /* Update memory */ + mem[0] = _mm_move_ss(mem[0], mem[1]); + mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39); + + mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0])); + + mem[1] = _mm_sub_ss(mem[1], mem[1]); + mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39); + + mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1])); + } + /* Put memory back in its place */ + _mm_storeu_ps(_mem, mem[0]); + _mm_storeu_ps(_mem+4, mem[1]); +} + +#define OVERRIDE_FIR_MEM16 +void fir_mem16(const float *x, const float *_num, float *y, int N, int ord, float *_mem, char *stack) +{ + if(ord==10) + fir_mem16_10(x, _num, y, N, ord, _mem); + else if (ord==8) + fir_mem16_8(x, _num, y, N, ord, _mem); +} diff --git a/src/libs/speex/libspeex/fixed_arm4.h b/src/libs/speex/libspeex/fixed_arm4.h new file mode 100644 index 00000000..b6981cae --- /dev/null +++ b/src/libs/speex/libspeex/fixed_arm4.h @@ -0,0 +1,148 @@ +/* Copyright (C) 2004 Jean-Marc Valin */ +/** + @file fixed_arm4.h + @brief ARM4 fixed-point operations +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_ARM4_H +#define FIXED_ARM4_H + +#undef MULT16_32_Q14 +static inline spx_word32_t MULT16_32_Q14(spx_word16_t x, spx_word32_t y) { + int res; + int dummy; + asm ( + "smull %0,%1,%2,%3 \n\t" + "mov %0, %0, lsr #14 \n\t" + "add %0, %0, %1, lsl #18 \n\t" + : "=&r"(res), "=&r" (dummy) + : "r"(y),"r"((int)x)); + return(res); +} + +#undef MULT16_32_Q15 +static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) { + int res; + int dummy; + asm ( + "smull %0,%1,%2,%3 \n\t" + "mov %0, %0, lsr #15 \n\t" + "add %0, %0, %1, lsl #17 \n\t" + : "=&r"(res), "=&r" (dummy) + : "r"(y),"r"((int)x)); + return(res); +} + +#undef DIV32_16 +static inline short DIV32_16(int a, int b) +{ + int res=0; + int dead1, dead2, dead3, dead4, dead5; + __asm__ __volatile__ ( + "\teor %5, %0, %1\n" + "\tmovs %4, %0\n" + "\trsbmi %0, %0, #0 \n" + "\tmovs %4, %1\n" + "\trsbmi %1, %1, #0 \n" + "\tmov %4, #1\n" + + "\tsubs %3, %0, %1, asl #14 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #14 \n" + + "\tsubs %3, %0, %1, asl #13 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #13 \n" + + "\tsubs %3, %0, %1, asl #12 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #12 \n" + + "\tsubs %3, %0, %1, asl #11 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #11 \n" + + "\tsubs %3, %0, %1, asl #10 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #10 \n" + + "\tsubs %3, %0, %1, asl #9 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #9 \n" + + "\tsubs %3, %0, %1, asl #8 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #8 \n" + + "\tsubs %3, %0, %1, asl #7 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #7 \n" + + "\tsubs %3, %0, %1, asl #6 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #6 \n" + + "\tsubs %3, %0, %1, asl #5 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #5 \n" + + "\tsubs %3, %0, %1, asl #4 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #4 \n" + + "\tsubs %3, %0, %1, asl #3 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #3 \n" + + "\tsubs %3, %0, %1, asl #2 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #2 \n" + + "\tsubs %3, %0, %1, asl #1 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #1 \n" + + "\tsubs %3, %0, %1 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4 \n" + + "\tmovs %5, %5, lsr #31 \n" + "\trsbne %2, %2, #0 \n" + : "=r" (dead1), "=r" (dead2), "=r" (res), + "=r" (dead3), "=r" (dead4), "=r" (dead5) + : "0" (a), "1" (b), "2" (res) + : "cc" + ); + return res; +} + + +#endif diff --git a/src/libs/speex/libspeex/fixed_arm5e.h b/src/libs/speex/libspeex/fixed_arm5e.h new file mode 100644 index 00000000..9b4861c9 --- /dev/null +++ b/src/libs/speex/libspeex/fixed_arm5e.h @@ -0,0 +1,178 @@ +/* Copyright (C) 2003 Jean-Marc Valin */ +/** + @file fixed_arm5e.h + @brief ARM-tuned fixed-point operations +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_ARM5E_H +#define FIXED_ARM5E_H + +#undef MULT16_16 +static inline spx_word32_t MULT16_16(spx_word16_t x, spx_word16_t y) { + int res; + asm ("smulbb %0,%1,%2;\n" + : "=&r"(res) + : "%r"(x),"r"(y)); + return(res); +} + +#undef MAC16_16 +static inline spx_word32_t MAC16_16(spx_word32_t a, spx_word16_t x, spx_word32_t y) { + int res; + asm ("smlabb %0,%1,%2,%3;\n" + : "=&r"(res) + : "%r"(x),"r"(y),"r"(a)); + return(res); +} + +#undef MULT16_32_Q15 +static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) { + int res; + asm ("smulwb %0,%1,%2;\n" + : "=&r"(res) + : "%r"(y<<1),"r"(x)); + return(res); +} + +#undef MAC16_32_Q15 +static inline spx_word32_t MAC16_32_Q15(spx_word32_t a, spx_word16_t x, spx_word32_t y) { + int res; + asm ("smlawb %0,%1,%2,%3;\n" + : "=&r"(res) + : "%r"(y<<1),"r"(x),"r"(a)); + return(res); +} + +#undef MULT16_32_Q11 +static inline spx_word32_t MULT16_32_Q11(spx_word16_t x, spx_word32_t y) { + int res; + asm ("smulwb %0,%1,%2;\n" + : "=&r"(res) + : "%r"(y<<5),"r"(x)); + return(res); +} + +#undef MAC16_32_Q11 +static inline spx_word32_t MAC16_32_Q11(spx_word32_t a, spx_word16_t x, spx_word32_t y) { + int res; + asm ("smlawb %0,%1,%2,%3;\n" + : "=&r"(res) + : "%r"(y<<5),"r"(x),"r"(a)); + return(res); +} + +#undef DIV32_16 +static inline short DIV32_16(int a, int b) +{ + int res=0; + int dead1, dead2, dead3, dead4, dead5; + __asm__ __volatile__ ( + "\teor %5, %0, %1\n" + "\tmovs %4, %0\n" + "\trsbmi %0, %0, #0 \n" + "\tmovs %4, %1\n" + "\trsbmi %1, %1, #0 \n" + "\tmov %4, #1\n" + + "\tsubs %3, %0, %1, asl #14 \n" + "\torrpl %2, %2, %4, asl #14 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #13 \n" + "\torrpl %2, %2, %4, asl #13 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #12 \n" + "\torrpl %2, %2, %4, asl #12 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #11 \n" + "\torrpl %2, %2, %4, asl #11 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #10 \n" + "\torrpl %2, %2, %4, asl #10 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #9 \n" + "\torrpl %2, %2, %4, asl #9 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #8 \n" + "\torrpl %2, %2, %4, asl #8 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #7 \n" + "\torrpl %2, %2, %4, asl #7 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #6 \n" + "\torrpl %2, %2, %4, asl #6 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #5 \n" + "\torrpl %2, %2, %4, asl #5 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #4 \n" + "\torrpl %2, %2, %4, asl #4 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #3 \n" + "\torrpl %2, %2, %4, asl #3 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #2 \n" + "\torrpl %2, %2, %4, asl #2 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #1 \n" + "\torrpl %2, %2, %4, asl #1 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1 \n" + "\torrpl %2, %2, %4 \n" + "\tmovpl %0, %3 \n" + + "\tmovs %5, %5, lsr #31 \n" + "\trsbne %2, %2, #0 \n" + : "=r" (dead1), "=r" (dead2), "=r" (res), + "=r" (dead3), "=r" (dead4), "=r" (dead5) + : "0" (a), "1" (b), "2" (res) + : "memory", "cc" + ); + return res; +} + + + + +#endif diff --git a/src/libs/speex/libspeex/fixed_bfin.h b/src/libs/speex/libspeex/fixed_bfin.h new file mode 100644 index 00000000..aa26f6a8 --- /dev/null +++ b/src/libs/speex/libspeex/fixed_bfin.h @@ -0,0 +1,173 @@ +/* Copyright (C) 2005 Analog Devices + Author: Jean-Marc Valin */ +/** + @file fixed_bfin.h + @brief Blackfin fixed-point operations +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_BFIN_H +#define FIXED_BFIN_H + +#undef PDIV32_16 +static inline spx_word16_t PDIV32_16(spx_word32_t a, spx_word16_t b) +{ + spx_word32_t res, bb; + bb = b; + a += b>>1; + __asm__ ( + "P0 = 15;\n\t" + "R0 = %1;\n\t" + "R1 = %2;\n\t" + //"R0 = R0 + R1;\n\t" + "R0 <<= 1;\n\t" + "DIVS (R0, R1);\n\t" + "LOOP divide%= LC0 = P0;\n\t" + "LOOP_BEGIN divide%=;\n\t" + "DIVQ (R0, R1);\n\t" + "LOOP_END divide%=;\n\t" + "R0 = R0.L;\n\t" + "%0 = R0;\n\t" + : "=m" (res) + : "m" (a), "m" (bb) + : "P0", "R0", "R1", "cc"); + return res; +} + +#undef DIV32_16 +static inline spx_word16_t DIV32_16(spx_word32_t a, spx_word16_t b) +{ + spx_word32_t res, bb; + bb = b; + /* Make the roundinf consistent with the C version + (do we need to do that?)*/ + if (a<0) + a += (b-1); + __asm__ ( + "P0 = 15;\n\t" + "R0 = %1;\n\t" + "R1 = %2;\n\t" + "R0 <<= 1;\n\t" + "DIVS (R0, R1);\n\t" + "LOOP divide%= LC0 = P0;\n\t" + "LOOP_BEGIN divide%=;\n\t" + "DIVQ (R0, R1);\n\t" + "LOOP_END divide%=;\n\t" + "R0 = R0.L;\n\t" + "%0 = R0;\n\t" + : "=m" (res) + : "m" (a), "m" (bb) + : "P0", "R0", "R1", "cc"); + return res; +} + +#undef MAX16 +static inline spx_word16_t MAX16(spx_word16_t a, spx_word16_t b) +{ + spx_word32_t res; + __asm__ ( + "%1 = %1.L (X);\n\t" + "%2 = %2.L (X);\n\t" + "%0 = MAX(%1,%2);" + : "=d" (res) + : "%d" (a), "d" (b) + ); + return res; +} + +#undef MULT16_32_Q15 +static inline spx_word32_t MULT16_32_Q15(spx_word16_t a, spx_word32_t b) +{ + spx_word32_t res; + __asm__ + ( + "A1 = %2.L*%1.L (M);\n\t" + "A1 = A1 >>> 15;\n\t" + "%0 = (A1 += %2.L*%1.H) ;\n\t" + : "=&W" (res), "=&d" (b) + : "d" (a), "1" (b) + : "A1" + ); + return res; +} + +#undef MAC16_32_Q15 +static inline spx_word32_t MAC16_32_Q15(spx_word32_t c, spx_word16_t a, spx_word32_t b) +{ + spx_word32_t res; + __asm__ + ( + "A1 = %2.L*%1.L (M);\n\t" + "A1 = A1 >>> 15;\n\t" + "%0 = (A1 += %2.L*%1.H);\n\t" + "%0 = %0 + %4;\n\t" + : "=&W" (res), "=&d" (b) + : "d" (a), "1" (b), "d" (c) + : "A1" + ); + return res; +} + +#undef MULT16_32_Q14 +static inline spx_word32_t MULT16_32_Q14(spx_word16_t a, spx_word32_t b) +{ + spx_word32_t res; + __asm__ + ( + "%2 <<= 1;\n\t" + "A1 = %1.L*%2.L (M);\n\t" + "A1 = A1 >>> 15;\n\t" + "%0 = (A1 += %1.L*%2.H);\n\t" + : "=W" (res), "=d" (a), "=d" (b) + : "1" (a), "2" (b) + : "A1" + ); + return res; +} + +#undef MAC16_32_Q14 +static inline spx_word32_t MAC16_32_Q14(spx_word32_t c, spx_word16_t a, spx_word32_t b) +{ + spx_word32_t res; + __asm__ + ( + "%1 <<= 1;\n\t" + "A1 = %2.L*%1.L (M);\n\t" + "A1 = A1 >>> 15;\n\t" + "%0 = (A1 += %2.L*%1.H);\n\t" + "%0 = %0 + %4;\n\t" + : "=&W" (res), "=&d" (b) + : "d" (a), "1" (b), "d" (c) + : "A1" + ); + return res; +} + +#endif diff --git a/src/libs/speex/libspeex/fixed_debug.h b/src/libs/speex/libspeex/fixed_debug.h new file mode 100644 index 00000000..54f3866e --- /dev/null +++ b/src/libs/speex/libspeex/fixed_debug.h @@ -0,0 +1,487 @@ +/* Copyright (C) 2003 Jean-Marc Valin */ +/** + @file fixed_debug.h + @brief Fixed-point operations with debugging +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_DEBUG_H +#define FIXED_DEBUG_H + +#include <stdio.h> + +extern long long spx_mips; +#define MIPS_INC spx_mips++, + +#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) +#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) + + +#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768) +#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL) + +static inline short NEG16(int x) +{ + int res; + if (!VERIFY_SHORT(x)) + { + fprintf (stderr, "NEG16: input is not short: %d\n", (int)x); + } + res = -x; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "NEG16: output is not short: %d\n", (int)res); + spx_mips++; + return res; +} +static inline int NEG32(long long x) +{ + long long res; + if (!VERIFY_INT(x)) + { + fprintf (stderr, "NEG16: input is not int: %d\n", (int)x); + } + res = -x; + if (!VERIFY_INT(res)) + fprintf (stderr, "NEG16: output is not int: %d\n", (int)res); + spx_mips++; + return res; +} + +#define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__) +static inline short _EXTRACT16(int x, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(x)) + { + fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line); + } + res = x; + spx_mips++; + return res; +} + +#define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__) +static inline int _EXTEND32(int x, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(x)) + { + fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line); + } + res = x; + spx_mips++; + return res; +} + +#define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__) +static inline short _SHR16(int a, int shift, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) + { + fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line); + } + res = a>>shift; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line); + spx_mips++; + return res; +} +#define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__) +static inline short _SHL16(int a, int shift, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) + { + fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line); + } + res = a<<shift; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line); + spx_mips++; + return res; +} + +static inline int SHR32(long long a, int shift) +{ + long long res; + if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) + { + fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift); + } + res = a>>shift; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "SHR32: output is not int: %d\n", (int)res); + } + spx_mips++; + return res; +} +static inline int SHL32(long long a, int shift) +{ + long long res; + if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) + { + fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift); + } + res = a<<shift; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "SHL32: output is not int: %d\n", (int)res); + } + spx_mips++; + return res; +} + +#define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift)) +#define PSHR32(a,shift) (SHR32(ADD32((a),((EXTEND32(1)<<((shift))>>1))),shift)) +#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) + +#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) +#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) + +//#define SHR(a,shift) ((a) >> (shift)) +//#define SHL(a,shift) ((a) << (shift)) + +#define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__) +static inline short _ADD16(int a, int b, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); + } + res = a+b; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line); + } + spx_mips++; + return res; +} + +#define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__) +static inline short _SUB16(int a, int b, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); + } + res = a-b; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line); + spx_mips++; + return res; +} + +#define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__) +static inline int _ADD32(long long a, long long b, char *file, int line) +{ + long long res; + if (!VERIFY_INT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); + } + res = a+b; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line); + } + spx_mips++; + return res; +} + +static inline int SUB32(long long a, long long b) +{ + long long res; + if (!VERIFY_INT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int)a, (int)b); + } + res = a-b; + if (!VERIFY_INT(res)) + fprintf (stderr, "SUB32: output is not int: %d\n", (int)res); + spx_mips++; + return res; +} + +#define ADD64(a,b) (MIPS_INC(a)+(b)) + +/* result fits in 16 bits */ +static inline short MULT16_16_16(int a, int b) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b); + } + res = a*b; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res); + spx_mips++; + return res; +} + +#define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__) +static inline int _MULT16_16(int a, int b, char *file, int line) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); + } + res = ((long long)a)*b; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line); + spx_mips++; + return res; +} + +#define MAC16_16(c,a,b) (spx_mips--,ADD32((c),MULT16_16((a),(b)))) +#define MAC16_16_Q11(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11))))) +#define MAC16_16_Q13(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13))))) +#define MAC16_16_P13(c,a,b) (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13)))) + + +#define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__) +static inline int _MULT16_32_QX(int a, long long b, int Q, char *file, int line) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); + } + if (ABS32(b)>=(EXTEND32(1)<<(15+Q))) + fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); + res = (((long long)a)*(long long)b) >> Q; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line); + spx_mips+=5; + return res; +} + +static inline int MULT16_32_PX(int a, long long b, int Q) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b); + } + if (ABS32(b)>=(EXTEND32(1)<<(15+Q))) + fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q, (int)a, (int)b); + res = ((((long long)a)*(long long)b) + ((EXTEND32(1)<<Q)>>1))>> Q; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res); + spx_mips+=5; + return res; +} + + +#define MULT16_32_Q11(a,b) MULT16_32_QX(a,b,11) +#define MAC16_32_Q11(c,a,b) ADD32((c),MULT16_32_Q11((a),(b))) +#define MULT16_32_Q12(a,b) MULT16_32_QX(a,b,12) +#define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13) +#define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14) +#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15) +#define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15) +#define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b))) + +static inline int SATURATE(int a, int b) +{ + if (a>b) + a=b; + if (a<-b) + a = -b; + return a; +} + +static inline int MULT16_16_Q11_32(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res >>= 11; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res); + spx_mips+=3; + return res; +} +static inline short MULT16_16_Q13(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res >>= 13; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res); + spx_mips+=3; + return res; +} +static inline short MULT16_16_Q14(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res >>= 14; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res); + spx_mips+=3; + return res; +} +static inline short MULT16_16_Q15(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res >>= 15; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res); + } + spx_mips+=3; + return res; +} + +static inline short MULT16_16_P13(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res += 4096; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res); + res >>= 13; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res); + spx_mips+=4; + return res; +} +static inline short MULT16_16_P14(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res += 8192; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res); + res >>= 14; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res); + spx_mips+=4; + return res; +} +static inline short MULT16_16_P15(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res += 16384; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res); + res >>= 15; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res); + spx_mips+=4; + return res; +} + +#define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__) + +static inline int _DIV32_16(long long a, long long b, char *file, int line) +{ + long long res; + if (b==0) + { + fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); + return 0; + } + if (!VERIFY_INT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); + } + res = a/b; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line); + if (res>32767) + res = 32767; + if (res<-32768) + res = -32768; + } + spx_mips+=20; + return res; +} + +#define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__) +static inline int _DIV32(long long a, long long b, char *file, int line) +{ + long long res; + if (b==0) + { + fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); + return 0; + } + + if (!VERIFY_INT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); + } + res = a/b; + if (!VERIFY_INT(res)) + fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line); + spx_mips+=36; + return res; +} +#define PDIV32(a,b) DIV32(ADD32((a),(b)>>1),b) +#define PDIV32_16(a,b) DIV32_16(ADD32((a),(b)>>1),b) + +#endif diff --git a/src/libs/speex/libspeex/fixed_generic.h b/src/libs/speex/libspeex/fixed_generic.h new file mode 100644 index 00000000..3fb096ed --- /dev/null +++ b/src/libs/speex/libspeex/fixed_generic.h @@ -0,0 +1,106 @@ +/* Copyright (C) 2003 Jean-Marc Valin */ +/** + @file fixed_generic.h + @brief Generic fixed-point operations +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_GENERIC_H +#define FIXED_GENERIC_H + +#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) +#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) + +#define NEG16(x) (-(x)) +#define NEG32(x) (-(x)) +#define EXTRACT16(x) ((spx_word16_t)(x)) +#define EXTEND32(x) ((spx_word32_t)(x)) +#define SHR16(a,shift) ((a) >> (shift)) +#define SHL16(a,shift) ((a) << (shift)) +#define SHR32(a,shift) ((a) >> (shift)) +#define SHL32(a,shift) ((a) << (shift)) +#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift)) +#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift)) +#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) +#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) +#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) + +#define SHR(a,shift) ((a) >> (shift)) +#define SHL(a,shift) ((spx_word32_t)(a) << (shift)) +#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift)) +#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) + + +#define ADD16(a,b) ((spx_word16_t)((spx_word16_t)(a)+(spx_word16_t)(b))) +#define SUB16(a,b) ((spx_word16_t)(a)-(spx_word16_t)(b)) +#define ADD32(a,b) ((spx_word32_t)(a)+(spx_word32_t)(b)) +#define SUB32(a,b) ((spx_word32_t)(a)-(spx_word32_t)(b)) + + +/* result fits in 16 bits */ +#define MULT16_16_16(a,b) ((((spx_word16_t)(a))*((spx_word16_t)(b)))) + +/* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */ +#define MULT16_16(a,b) (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b))) + +#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b)))) +#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12)) +#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13)) +#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14)) + +#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)) +#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))) + +#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15)) +#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)) +#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))) + + +#define MAC16_16_Q11(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),11))) +#define MAC16_16_Q13(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),13))) +#define MAC16_16_P13(c,a,b) (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13))) + +#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11)) +#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13)) +#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14)) +#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15)) + +#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13)) +#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14)) +#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15)) + +#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15)) + +#define DIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b)))) +#define PDIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word16_t)(b)))) +#define DIV32(a,b) (((spx_word32_t)(a))/((spx_word32_t)(b))) +#define PDIV32(a,b) (((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word32_t)(b))) + +#endif diff --git a/src/libs/speex/libspeex/gain_table.c b/src/libs/speex/libspeex/gain_table.c new file mode 100644 index 00000000..00b82442 --- /dev/null +++ b/src/libs/speex/libspeex/gain_table.c @@ -0,0 +1,160 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: gain_table.c + Codebook for 3-tap pitch prediction gain (128 entries) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +const signed char gain_cdbk_nb[512] = { +-32, -32, -32, 0, +-28, -67, -5, 33, +-42, -6, -32, 18, +-57, -10, -54, 35, +-16, 27, -41, 42, +19, -19, -40, 36, +-45, 24, -21, 40, +-8, -14, -18, 28, +1, 14, -58, 53, +-18, -88, -39, 39, +-38, 21, -18, 37, +-19, 20, -43, 38, +10, 17, -48, 54, +-52, -58, -13, 33, +-44, -1, -11, 32, +-12, -11, -34, 22, +14, 0, -46, 46, +-37, -35, -34, 5, +-25, 44, -30, 43, +6, -4, -63, 49, +-31, 43, -41, 43, +-23, 30, -43, 41, +-43, 26, -14, 44, +-33, 1, -13, 27, +-13, 18, -37, 37, +-46, -73, -45, 34, +-36, 24, -25, 34, +-36, -11, -20, 19, +-25, 12, -18, 33, +-36, -69, -59, 34, +-45, 6, 8, 46, +-22, -14, -24, 18, +-1, 13, -44, 44, +-39, -48, -26, 15, +-32, 31, -37, 34, +-33, 15, -46, 31, +-24, 30, -36, 37, +-41, 31, -23, 41, +-50, 22, -4, 50, +-22, 2, -21, 28, +-17, 30, -34, 40, +-7, -60, -28, 29, +-38, 42, -28, 42, +-44, -11, 21, 43, +-16, 8, -44, 34, +-39, -55, -43, 21, +-11, -35, 26, 41, +-9, 0, -34, 29, +-8, 121, -81, 113, +7, -16, -22, 33, +-37, 33, -31, 36, +-27, -7, -36, 17, +-34, 70, -57, 65, +-37, -11, -48, 21, +-40, 17, -1, 44, +-33, 6, -6, 33, +-9, 0, -20, 34, +-21, 69, -33, 57, +-29, 33, -31, 35, +-55, 12, -1, 49, +-33, 27, -22, 35, +-50, -33, -47, 17, +-50, 54, 51, 94, +-1, -5, -44, 35, +-4, 22, -40, 45, +-39, -66, -25, 24, +-33, 1, -26, 20, +-24, -23, -25, 12, +-11, 21, -45, 44, +-25, -45, -19, 17, +-43, 105, -16, 82, +5, -21, 1, 41, +-16, 11, -33, 30, +-13, -99, -4, 57, +-37, 33, -15, 44, +-25, 37, -63, 54, +-36, 24, -31, 31, +-53, -56, -38, 26, +-41, -4, 4, 37, +-33, 13, -30, 24, +49, 52, -94, 114, +-5, -30, -15, 23, +1, 38, -40, 56, +-23, 12, -36, 29, +-17, 40, -47, 51, +-37, -41, -39, 11, +-49, 34, 0, 58, +-18, -7, -4, 34, +-16, 17, -27, 35, +30, 5, -62, 65, +4, 48, -68, 76, +-43, 11, -11, 38, +-18, 19, -15, 41, +-23, -62, -39, 23, +-42, 10, -2, 41, +-21, -13, -13, 25, +-9, 13, -47, 42, +-23, -62, -24, 24, +-44, 60, -21, 58, +-18, -3, -52, 32, +-22, 22, -36, 34, +-75, 57, 16, 90, +-19, 3, 10, 45, +-29, 23, -38, 32, +-5, -62, -51, 38, +-51, 40, -18, 53, +-42, 13, -24, 32, +-34, 14, -20, 30, +-56, -75, -26, 37, +-26, 32, 15, 59, +-26, 17, -29, 29, +-7, 28, -52, 53, +-12, -30, 5, 30, +-5, -48, -5, 35, +2, 2, -43, 40, +21, 16, 16, 75, +-25, -45, -32, 10, +-43, 18, -10, 42, +9, 0, -1, 52, +-1, 7, -30, 36, +19, -48, -4, 48, +-28, 25, -29, 32, +-22, 0, -31, 22, +-32, 17, -10, 36, +-64, -41, -62, 36, +-52, 15, 16, 58, +-30, -22, -32, 6, +-7, 9, -38, 36}; diff --git a/src/libs/speex/libspeex/gain_table_lbr.c b/src/libs/speex/libspeex/gain_table_lbr.c new file mode 100644 index 00000000..3c1c3dba --- /dev/null +++ b/src/libs/speex/libspeex/gain_table_lbr.c @@ -0,0 +1,64 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: gain_table_lbr.c + Codebook for 3-tap pitch prediction gain (32 entries) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +const signed char gain_cdbk_lbr[128] = { +-32, -32, -32, 0, +-31, -58, -16, 22, +-41, -24, -43, 14, +-56, -22, -55, 29, +-13, 33, -41, 47, +-4, -39, -9, 29, +-41, 15, -12, 38, +-8, -15, -12, 31, +1, 2, -44, 40, +-22, -66, -42, 27, +-38, 28, -23, 38, +-21, 14, -37, 31, +0, 21, -50, 52, +-53, -71, -27, 33, +-37, -1, -19, 25, +-19, -5, -28, 22, +6, 65, -44, 74, +-33, -48, -33, 9, +-40, 57, -14, 58, +-17, 4, -45, 32, +-31, 38, -33, 36, +-23, 28, -40, 39, +-43, 29, -12, 46, +-34, 13, -23, 28, +-16, 15, -27, 34, +-14, -82, -15, 43, +-31, 25, -32, 29, +-21, 5, -5, 38, +-47, -63, -51, 33, +-46, 12, 3, 47, +-28, -17, -29, 11, +-10, 14, -40, 38}; diff --git a/src/libs/speex/libspeex/hexc_10_32_table.c b/src/libs/speex/libspeex/hexc_10_32_table.c new file mode 100644 index 00000000..8dd408f2 --- /dev/null +++ b/src/libs/speex/libspeex/hexc_10_32_table.c @@ -0,0 +1,66 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: hexc_10_32_table.c + Codebook for high-band excitation in SB-CELP mode (4000 bps) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +const signed char hexc_10_32_table[320] = { +-3, -2, -1, 0, -4, 5, 35, -40, -9, 13, +-44, 5, -27, -1, -7, 6, -11, 7, -8, 7, +19, -14, 15, -4, 9, -10, 10, -8, 10, -9, +-1, 1, 0, 0, 2, 5, -18, 22, -53, 50, +1, -23, 50, -36, 15, 3, -13, 14, -10, 6, +1, 5, -3, 4, -2, 5, -32, 25, 5, -2, +-1, -4, 1, 11, -29, 26, -6, -15, 30, -18, +0, 15, -17, 40, -41, 3, 9, -2, -2, 3, +-3, -1, -5, 2, 21, -6, -16, -21, 23, 2, +60, 15, 16, -16, -9, 14, 9, -1, 7, -9, +0, 1, 1, 0, -1, -6, 17, -28, 54, -45, +-1, 1, -1, -6, -6, 2, 11, 26, -29, -2, +46, -21, 34, 12, -23, 32, -23, 16, -10, 3, +66, 19, -20, 24, 7, 11, -3, 0, -3, -1, +-50, -46, 2, -18, -3, 4, -1, -2, 3, -3, +-19, 41, -36, 9, 11, -24, 21, -16, 9, -3, +-25, -3, 10, 18, -9, -2, -5, -1, -5, 6, +-4, -3, 2, -26, 21, -19, 35, -15, 7, -13, +17, -19, 39, -43, 48, -31, 16, -9, 7, -2, +-5, 3, -4, 9, -19, 27, -55, 63, -35, 10, +26, -44, -2, 9, 4, 1, -6, 8, -9, 5, +-8, -1, -3, -16, 45, -42, 5, 15, -16, 10, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +-16, 24, -55, 47, -38, 27, -19, 7, -3, 1, +16, 27, 20, -19, 18, 5, -7, 1, -5, 2, +-6, 8, -22, 0, -3, -3, 8, -1, 7, -8, +1, -3, 5, 0, 17, -48, 58, -52, 29, -7, +-2, 3, -10, 6, -26, 58, -31, 1, -6, 3, +93, -29, 39, 3, 17, 5, 6, -1, -1, -1, +27, 13, 10, 19, -7, -34, 12, 10, -4, 9, +-76, 9, 8, -28, -2, -11, 2, -1, 3, 1, +-83, 38, -39, 4, -16, -6, -2, -5, 5, -2, +}; diff --git a/src/libs/speex/libspeex/hexc_table.c b/src/libs/speex/libspeex/hexc_table.c new file mode 100644 index 00000000..268408a8 --- /dev/null +++ b/src/libs/speex/libspeex/hexc_table.c @@ -0,0 +1,162 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: hexc_table.c + Codebook for high-band excitation in SB-CELP mode (8000 bps with sign) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +const signed char hexc_table[1024] = { +-24, 21, -20, 5, -5, -7, 14, -10, +2, -27, 16, -20, 0, -32, 26, 19, +8, -11, -41, 31, 28, -27, -32, 34, +42, 34, -17, 22, -10, 13, -29, 18, +-12, -26, -24, 11, 22, 5, -5, -5, +54, -68, -43, 57, -25, 24, 4, 4, +26, -8, -12, -17, 54, 30, -45, 1, +10, -15, 18, -41, 11, 68, -67, 37, +-16, -24, -16, 38, -22, 6, -29, 30, +66, -27, 5, 7, -16, 13, 2, -12, +-7, -3, -20, 36, 4, -28, 9, 3, +32, 48, 26, 39, 3, 0, 7, -21, +-13, 5, -82, -7, 73, -20, 34, -9, +-5, 1, -1, 10, -5, -10, -1, 9, +1, -9, 10, 0, -14, 11, -1, -2, +-1, 11, 20, 96, -81, -22, -12, -9, +-58, 9, 24, -30, 26, -35, 27, -12, +13, -18, 56, -59, 15, -7, 23, -15, +-1, 6, -25, 14, -22, -20, 47, -11, +16, 2, 38, -23, -19, -30, -9, 40, +-11, 5, 4, -6, 8, 26, -21, -11, +127, 4, 1, 6, -9, 2, -7, -2, +-3, 7, -5, 10, -19, 7, -106, 91, +-3, 9, -4, 21, -8, 26, -80, 8, +1, -2, -10, -17, -17, -27, 32, 71, +6, -29, 11, -23, 54, -38, 29, -22, +39, 87, -31, -12, -20, 3, -2, -2, +2, 20, 0, -1, -35, 27, 9, -6, +-12, 3, -12, -6, 13, 1, 14, -22, +-59, -15, -17, -25, 13, -7, 7, 3, +0, 1, -7, 6, -3, 61, -37, -23, +-23, -29, 38, -31, 27, 1, -8, 2, +-27, 23, -26, 36, -34, 5, 24, -24, +-6, 7, 3, -59, 78, -62, 44, -16, +1, 6, 0, 17, 8, 45, 0, -110, +6, 14, -2, 32, -77, -56, 62, -3, +3, -13, 4, -16, 102, -15, -36, -1, +9, -113, 6, 23, 0, 9, 9, 5, +-8, -1, -14, 5, -12, 121, -53, -27, +-8, -9, 22, -13, 3, 2, -3, 1, +-2, -71, 95, 38, -19, 15, -16, -5, +71, 10, 2, -32, -13, -5, 15, -1, +-2, -14, -85, 30, 29, 6, 3, 2, +0, 0, 0, 0, 0, 0, 0, 0, +2, -65, -56, -9, 18, 18, 23, -14, +-2, 0, 12, -29, 26, -12, 1, 2, +-12, -64, 90, -6, 4, 1, 5, -5, +-110, -3, -31, 22, -29, 9, 0, 8, +-40, -5, 21, -5, -5, 13, 10, -18, +40, 1, 35, -20, 30, -28, 11, -6, +19, 7, 14, 18, -64, 9, -6, 16, +51, 68, 8, 16, 12, -8, 0, -9, +20, -22, 25, 7, -4, -13, 41, -35, +93, -18, -54, 11, -1, 1, -9, 4, +-66, 66, -31, 20, -22, 25, -23, 11, +10, 9, 19, 15, 11, -5, -31, -10, +-23, -28, -6, -6, -3, -4, 5, 3, +-28, 22, -11, -42, 25, -25, -16, 41, +34, 47, -6, 2, 42, -19, -22, 5, +-39, 32, 6, -35, 22, 17, -30, 8, +-26, -11, -11, 3, -12, 33, 33, -37, +21, -1, 6, -4, 3, 0, -5, 5, +12, -12, 57, 27, -61, -3, 20, -17, +2, 0, 4, 0, -2, -33, -58, 81, +-23, 39, -10, -5, 2, 6, -7, 5, +4, -3, -2, -13, -23, -72, 107, 15, +-5, 0, -7, -3, -6, 5, -4, 15, +47, 12, -31, 25, -16, 8, 22, -25, +-62, -56, -18, 14, 28, 12, 2, -11, +74, -66, 41, -20, -7, 16, -20, 16, +-8, 0, -16, 4, -19, 92, 12, -59, +-14, -39, 49, -25, -16, 23, -27, 19, +-3, -33, 19, 85, -29, 6, -7, -10, +16, -7, -12, 1, -6, 2, 4, -2, +64, 10, -25, 41, -2, -31, 15, 0, +110, 50, 69, 35, 28, 19, -10, 2, +-43, -49, -56, -15, -16, 10, 3, 12, +-1, -8, 1, 26, -12, -1, 7, -11, +-27, 41, 25, 1, -11, -18, 22, -7, +-1, -47, -8, 23, -3, -17, -7, 18, +-125, 59, -5, 3, 18, 1, 2, 3, +27, -35, 65, -53, 50, -46, 37, -21, +-28, 7, 14, -37, -5, -5, 12, 5, +-8, 78, -19, 21, -6, -16, 8, -7, +5, 2, 7, 2, 10, -6, 12, -60, +44, 11, -36, -32, 31, 0, 2, -2, +2, 1, -3, 7, -10, 17, -21, 10, +6, -2, 19, -2, 59, -38, -86, 38, +8, -41, -30, -45, -33, 7, 15, 28, +29, -7, 24, -40, 7, 7, 5, -2, +9, 24, -23, -18, 6, -29, 30, 2, +28, 49, -11, -46, 10, 43, -13, -9, +-1, -3, -7, -7, -17, -6, 97, -33, +-21, 3, 5, 1, 12, -43, -8, 28, +7, -43, -7, 17, -20, 19, -1, 2, +-13, 9, 54, 34, 9, -28, -11, -9, +-17, 110, -59, 44, -26, 0, 3, -12, +-47, 73, -34, -43, 38, -33, 16, -5, +-46, -4, -6, -2, -25, 19, -29, 28, +-13, 5, 14, 27, -40, -43, 4, 32, +-13, -2, -35, -4, 112, -42, 9, -12, +37, -28, 17, 14, -19, 35, -39, 23, +3, -14, -1, -57, -5, 94, -9, 3, +-39, 5, 30, -10, -32, 42, -13, -14, +-97, -63, 30, -9, 1, -7, 12, 5, +20, 17, -9, -36, -30, 25, 47, -9, +-15, 12, -22, 98, -8, -50, 15, -27, +21, -16, -11, 2, 12, -10, 10, -3, +33, 36, -96, 0, -17, 31, -9, 9, +3, -20, 13, -11, 8, -4, 10, -10, +9, 1, 112, -70, -27, 5, -21, 2, +-57, -3, -29, 10, 19, -21, 21, -10, +-66, -3, 91, -35, 30, -12, 0, -7, +59, -28, 26, 2, 14, -18, 1, 1, +11, 17, 20, -54, -59, 27, 4, 29, +32, 5, 19, 12, -4, 1, 7, -10, +5, -2, 10, 0, 23, -5, 28, -104, +46, 11, 16, 3, 29, 1, -8, -14, +1, 7, -50, 88, -62, 26, 8, -17, +-14, 50, 0, 32, -12, -3, -27, 18, +-8, -5, 8, 3, -20, -11, 37, -12, +9, 33, 46, -101, -1, -4, 1, 6, +-1, 28, -42, -15, 16, 5, -1, -2, +-55, 85, 38, -9, -4, 11, -2, -9, +-6, 3, -20, -10, -77, 89, 24, -3, +-104, -57, -26, -31, -20, -6, -9, 14, +20, -23, 46, -15, -31, 28, 1, -15, +-2, 6, -2, 31, 45, -76, 23, -25, +}; diff --git a/src/libs/speex/libspeex/high_lsp_tables.c b/src/libs/speex/libspeex/high_lsp_tables.c new file mode 100644 index 00000000..e82e8755 --- /dev/null +++ b/src/libs/speex/libspeex/high_lsp_tables.c @@ -0,0 +1,163 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: high_lsp_tables.c + Codebooks for high-band LSPs in SB-CELP mode + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +const signed char high_lsp_cdbk[512]={ +39,12,-14,-20,-29,-61,-67,-76, +-32,-71,-67,68,77,46,34,5, +-13,-48,-46,-72,-81,-84,-60,-58, +-40,-28,82,93,68,45,29,3, +-19,-47,-28,-43,-35,-30,-8,-13, +-39,-91,-91,-123,-96,10,10,-6, +-18,-55,-60,-91,-56,-36,-27,-16, +-48,-75,40,28,-10,-28,35,9, +37,19,1,-20,-31,-41,-18,-25, +-35,-68,-80,45,27,-1,47,13, +0,-29,-35,-57,-50,-79,-73,-38, +-19,5,35,14,-10,-23,16,-8, +5,-24,-40,-62,-23,-27,-22,-16, +-18,-46,-72,-77,43,21,33,1, +-80,-70,-70,-64,-56,-52,-39,-33, +-31,-38,-19,-19,-15,32,33,-2, +7,-15,-15,-24,-23,-33,-41,-56, +-24,-57,5,89,64,41,27,5, +-9,-47,-60,-97,-97,-124,-20,-9, +-44,-73,31,29,-4,64,48,7, +-35,-57,0,-3,-26,-47,-3,-6, +-40,-76,-79,-48,12,81,55,10, +9,-24,-43,-73,-57,-69,16,5, +-28,-53,18,29,20,0,-4,-11, +6,-13,23,7,-17,-35,-37,-37, +-30,-68,-63,6,24,-9,-14,3, +21,-13,-27,-57,-49,-80,-24,-41, +-5,-16,-5,1,45,25,12,-7, +3,-15,-6,-16,-15,-8,6,-13, +-42,-81,-80,-87,14,1,-10,-3, +-43,-69,-46,-24,-28,-29,36,6, +-43,-56,-12,12,54,79,43,9, +54,22,2,8,-12,-43,-46,-52, +-38,-69,-89,-5,75,38,33,5, +-13,-53,-62,-87,-89,-113,-99,-55, +-34,-37,62,55,33,16,21,-2, +-17,-46,-29,-38,-38,-48,-39,-42, +-36,-75,-72,-88,-48,-30,21,2, +-15,-57,-64,-98,-84,-76,25,1, +-46,-80,-12,18,-7,3,34,6, +38,31,23,4,-1,20,14,-15, +-43,-78,-91,-24,14,-3,54,16, +0,-27,-28,-44,-56,-83,-92,-89, +-3,34,56,41,36,22,20,-8, +-7,-35,-42,-62,-49,3,12,-10, +-50,-87,-96,-66,92,70,38,9, +-70,-71,-62,-42,-39,-43,-11,-7, +-50,-79,-58,-50,-31,32,31,-6, +-4,-25,7,-17,-38,-70,-58,-27, +-43,-83,-28,59,36,20,31,2, +-27,-71,-80,-109,-98,-75,-33,-32, +-31,-2,33,15,-6,43,33,-5, +0,-22,-10,-27,-34,-49,-11,-20, +-41,-91,-100,-121,-39,57,41,10, +-19,-50,-38,-59,-60,-70,-18,-20, +-8,-31,-8,-15,1,-14,-26,-25, +33,21,32,17,1,-19,-19,-26, +-58,-81,-35,-22,45,30,11,-11, +3,-26,-48,-87,-67,-83,-58,3, +-1,-26,-20,44,10,25,39,5, +-9,-35,-27,-38,7,10,4,-9, +-42,-85,-102,-127,52,44,28,10, +-47,-61,-40,-39,-17,-1,-10,-33, +-42,-74,-48,21,-4,70,52,10}; + + +const signed char high_lsp_cdbk2[512]={ +-36,-62,6,-9,-10,-14,-56,23, +1,-26,23,-48,-17,12,8,-7, +23,29,-36,-28,-6,-29,-17,-5, +40,23,10,10,-46,-13,36,6, +4,-30,-29,62,32,-32,-1,22, +-14,1,-4,-22,-45,2,54,4, +-30,-57,-59,-12,27,-3,-31,8, +-9,5,10,-14,32,66,19,9, +2,-25,-37,23,-15,18,-38,-31, +5,-9,-21,15,0,22,62,30, +15,-12,-14,-46,77,21,33,3, +34,29,-19,50,2,11,9,-38, +-12,-37,62,1,-15,54,32,6, +2,-24,20,35,-21,2,19,24, +-13,55,4,9,39,-19,30,-1, +-21,73,54,33,8,18,3,15, +6,-19,-47,6,-3,-48,-50,1, +26,20,8,-23,-50,65,-14,-55, +-17,-31,-37,-28,53,-1,-17,-53, +1,57,11,-8,-25,-30,-37,64, +5,-52,-45,15,23,31,15,14, +-25,24,33,-2,-44,-56,-18,6, +-21,-43,4,-12,17,-37,20,-10, +34,15,2,15,55,21,-11,-31, +-6,46,25,16,-9,-25,-8,-62, +28,17,20,-32,-29,26,30,25, +-19,2,-16,-17,26,-51,2,50, +42,19,-66,23,29,-2,3,19, +-19,-37,32,15,6,30,-34,13, +11,-5,40,31,10,-42,4,-9, +26,-9,-70,17,-2,-23,20,-22, +-55,51,-24,-31,22,-22,15,-13, +3,-10,-28,-16,56,4,-63,11, +-18,-15,-18,-38,-35,16,-7,34, +-1,-21,-49,-47,9,-37,7,8, +69,55,20,6,-33,-45,-10,-9, +6,-9,12,71,15,-3,-42,-7, +-24,32,-35,-2,-42,-17,-5,0, +-2,-33,-54,13,-12,-34,47,23, +19,55,7,-8,74,31,14,16, +-23,-26,19,12,-18,-49,-28,-31, +-20,2,-14,-20,-47,78,40,13, +-23,-11,21,-6,18,1,47,5, +38,35,32,46,22,8,13,16, +-14,18,51,19,40,39,11,-26, +-1,-17,47,2,-53,-15,31,-22, +38,21,-15,-16,5,-33,53,15, +-38,86,11,-3,-24,49,13,-4, +-11,-18,28,20,-12,-27,-26,35, +-25,-35,-3,-20,-61,30,10,-55, +-12,-22,-52,-54,-14,19,-32,-12, +45,15,-8,-48,-9,11,-32,8, +-16,-34,-13,51,18,38,-2,-32, +-17,22,-2,-18,-28,-70,59,27, +-28,-19,-10,-20,-9,-9,-8,-21, +21,-8,35,-2,45,-3,-9,12, +0,30,7,-39,43,27,-38,-91, +30,26,19,-55,-4,63,14,-17, +13,9,13,2,7,4,6,61, +72,-1,-17,29,-1,-22,-17,8, +-28,-37,63,44,41,3,2,14, +9,-6,75,-8,-7,-12,-15,-12, +13,9,-4,30,-22,-65,15,0, +-45,4,-4,1,5,22,11,23}; diff --git a/src/libs/speex/libspeex/jitter.c b/src/libs/speex/libspeex/jitter.c new file mode 100644 index 00000000..8106a966 --- /dev/null +++ b/src/libs/speex/libspeex/jitter.c @@ -0,0 +1,845 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: speex_jitter.h + + Adaptive jitter buffer for Speex + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +/* +TODO: +- Add short-term estimate +- Defensive programming + + warn when last returned < last desired (begative buffering) + + warn if update_delay not called between get() and tick() or is called twice in a row +- Linked list structure for holding the packets instead of the current fixed-size array + + return memory to a pool + + allow pre-allocation of the pool + + optional max number of elements +- Statistics + + drift + + loss + + late + + jitter + + buffering delay +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include "arch.h" +#include <speex/speex.h> +#include <speex/speex_bits.h> +#include <speex/speex_jitter.h> +#include "os_support.h" + +#ifndef NULL +#define NULL 0 +#endif + +#define EXPORT + +#define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */ + +#define TSUB(a,b) ((spx_int32_t)((a)-(b))) + +#define GT32(a,b) (((spx_int32_t)((a)-(b)))>0) +#define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0) +#define LT32(a,b) (((spx_int32_t)((a)-(b)))<0) +#define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0) + +#define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step)) + +#define MAX_TIMINGS 40 +#define MAX_BUFFERS 3 +#define TOP_DELAY 40 + +/** Buffer that keeps the time of arrival of the latest packets */ +struct TimingBuffer { + int filled; /**< Number of entries occupied in "timing" and "counts"*/ + int curr_count; /**< Number of packet timings we got (including those we discarded) */ + spx_int32_t timing[MAX_TIMINGS]; /**< Sorted list of all timings ("latest" packets first) */ + spx_int16_t counts[MAX_TIMINGS]; /**< Order the packets were put in (will be used for short-term estimate) */ +}; + +static void tb_init(struct TimingBuffer *tb) +{ + tb->filled = 0; + tb->curr_count = 0; +} + +/* Add the timing of a new packet to the TimingBuffer */ +static void tb_add(struct TimingBuffer *tb, spx_int16_t timing) +{ + int pos; + /* Discard packet that won't make it into the list because they're too early */ + if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1]) + { + tb->curr_count++; + return; + } + + /* Find where the timing info goes in the sorted list */ + pos = 0; + /* FIXME: Do bisection instead of linear search */ + while (pos<tb->filled && timing >= tb->timing[pos]) + { + pos++; + } + + speex_assert(pos <= tb->filled && pos < MAX_TIMINGS); + + /* Shift everything so we can perform the insertion */ + if (pos < tb->filled) + { + int move_size = tb->filled-pos; + if (tb->filled == MAX_TIMINGS) + move_size -= 1; + SPEEX_MOVE(&tb->timing[pos+1], &tb->timing[pos], move_size); + SPEEX_MOVE(&tb->counts[pos+1], &tb->counts[pos], move_size); + } + /* Insert */ + tb->timing[pos] = timing; + tb->counts[pos] = tb->curr_count; + + tb->curr_count++; + if (tb->filled<MAX_TIMINGS) + tb->filled++; +} + + + +/** Jitter buffer structure */ +struct JitterBuffer_ { + spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */ + spx_uint32_t last_returned_timestamp; /**< Useful for getting the next packet with the same timestamp (for fragmented media) */ + spx_uint32_t next_stop; /**< Estimated time the next get() will be called */ + + spx_int32_t buffered; /**< Amount of data we think is still buffered by the application (timestamp units)*/ + + JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packets stored in the buffer */ + spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */ + + void (*destroy) (void *); /**< Callback for destroying a packet */ + + spx_int32_t delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */ + spx_int32_t concealment_size; /**< Size of the packet loss concealment "units" */ + int reset_state; /**< True if state was just reset */ + int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */ + int late_cutoff; /**< How late must a packet be for it not to be considered at all */ + int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */ + int auto_adjust; /**< Whether to automatically adjust the delay at any time */ + + struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */ + struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */ + int window_size; /**< Total window over which the late frames are counted */ + int subwindow_size; /**< Sub-window size for faster computation */ + int max_late_rate; /**< Absolute maximum amount of late packets tolerable (in percent) */ + int latency_tradeoff; /**< Latency equivalent of losing one percent of packets */ + int auto_tradeoff; /**< Latency equivalent of losing one percent of packets (automatic default) */ + + int lost_count; /**< Number of consecutive lost packets */ +}; + +/** Based on available data, this computes the optimal delay for the jitter buffer. + The optimised function is in timestamp units and is: + cost = delay + late_factor*[number of frames that would be late if we used that delay] + @param tb Array of buffers + @param late_factor Equivalent cost of a late frame (in timestamp units) + */ +static spx_int16_t compute_opt_delay(JitterBuffer *jitter) +{ + int i; + spx_int16_t opt=0; + spx_int32_t best_cost=0x7fffffff; + int late = 0; + int pos[MAX_BUFFERS]; + int tot_count; + float late_factor; + int penalty_taken = 0; + int best = 0; + int worst = 0; + spx_int32_t deltaT; + struct TimingBuffer *tb; + + tb = jitter->_tb; + + /* Number of packet timings we have received (including those we didn't keep) */ + tot_count = 0; + for (i=0;i<MAX_BUFFERS;i++) + tot_count += tb[i].curr_count; + if (tot_count==0) + return 0; + + /* Compute cost for one lost packet */ + if (jitter->latency_tradeoff != 0) + late_factor = jitter->latency_tradeoff * 100.0f / tot_count; + else + late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count; + + /*fprintf(stderr, "late_factor = %f\n", late_factor);*/ + for (i=0;i<MAX_BUFFERS;i++) + pos[i] = 0; + + /* Pick the TOP_DELAY "latest" packets (doesn't need to actually be late + for the current settings) */ + for (i=0;i<TOP_DELAY;i++) + { + int j; + int next=-1; + int latest = 32767; + /* Pick latest amoung all sub-windows */ + for (j=0;j<MAX_BUFFERS;j++) + { + if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest) + { + next = j; + latest = tb[j].timing[pos[j]]; + } + } + if (next != -1) + { + spx_int32_t cost; + + if (i==0) + worst = latest; + best = latest; + latest = ROUND_DOWN(latest, jitter->delay_step); + pos[next]++; + + /* Actual cost function that tells us how bad using this delay would be */ + cost = -latest + late_factor*late; + /*fprintf(stderr, "cost %d = %d + %f * %d\n", cost, -latest, late_factor, late);*/ + if (cost < best_cost) + { + best_cost = cost; + opt = latest; + } + } else { + break; + } + + /* For the next timing we will consider, there will be one more late packet to count */ + late++; + /* Two-frame penalty if we're going to increase the amount of late frames (hysteresis) */ + if (latest >= 0 && !penalty_taken) + { + penalty_taken = 1; + late+=4; + } + } + + deltaT = best-worst; + /* This is a default "automatic latency tradeoff" when none is provided */ + jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY; + /*fprintf(stderr, "auto_tradeoff = %d (%d %d %d)\n", jitter->auto_tradeoff, best, worst, i);*/ + + /* FIXME: Compute a short-term estimate too and combine with the long-term one */ + + /* Prevents reducing the buffer size when we haven't really had much data */ + if (tot_count < TOP_DELAY && opt > 0) + return 0; + return opt; +} + + +/** Initialise jitter buffer */ +EXPORT JitterBuffer *jitter_buffer_init(int step_size) +{ + JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); + if (jitter) + { + int i; + spx_int32_t tmp; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + jitter->packets[i].data=NULL; + jitter->delay_step = step_size; + jitter->concealment_size = step_size; + /*FIXME: Should this be 0 or 1?*/ + jitter->buffer_margin = 0; + jitter->late_cutoff = 50; + jitter->destroy = NULL; + jitter->latency_tradeoff = 0; + jitter->auto_adjust = 1; + tmp = 4; + jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp); + jitter_buffer_reset(jitter); + } + return jitter; +} + +/** Reset jitter buffer */ +EXPORT void jitter_buffer_reset(JitterBuffer *jitter) +{ + int i; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data) + { + if (jitter->destroy) + jitter->destroy(jitter->packets[i].data); + else + speex_free(jitter->packets[i].data); + jitter->packets[i].data = NULL; + } + } + /* Timestamp is actually undefined at this point */ + jitter->pointer_timestamp = 0; + jitter->next_stop = 0; + jitter->reset_state = 1; + jitter->lost_count = 0; + jitter->buffered = 0; + jitter->auto_tradeoff = 32000; + + for (i=0;i<MAX_BUFFERS;i++) + { + tb_init(&jitter->_tb[i]); + jitter->timeBuffers[i] = &jitter->_tb[i]; + } + /*fprintf (stderr, "reset\n");*/ +} + +/** Destroy jitter buffer */ +EXPORT void jitter_buffer_destroy(JitterBuffer *jitter) +{ + jitter_buffer_reset(jitter); + speex_free(jitter); +} + +/** Take the following timing into consideration for future calculations */ +static void update_timings(JitterBuffer *jitter, spx_int32_t timing) +{ + if (timing < -32767) + timing = -32767; + if (timing > 32767) + timing = 32767; + /* If the current sub-window is full, perform a rotation and discard oldest sub-widow */ + if (jitter->timeBuffers[0]->curr_count >= jitter->subwindow_size) + { + int i; + /*fprintf(stderr, "Rotate buffer\n");*/ + struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1]; + for (i=MAX_BUFFERS-1;i>=1;i--) + jitter->timeBuffers[i] = jitter->timeBuffers[i-1]; + jitter->timeBuffers[0] = tmp; + tb_init(jitter->timeBuffers[0]); + } + tb_add(jitter->timeBuffers[0], timing); +} + +/** Compensate all timings when we do an adjustment of the buffering */ +static void shift_timings(JitterBuffer *jitter, spx_int16_t amount) +{ + int i, j; + for (i=0;i<MAX_BUFFERS;i++) + { + for (j=0;j<jitter->timeBuffers[i]->filled;j++) + jitter->timeBuffers[i]->timing[j] += amount; + } +} + + +/** Put one packet into the jitter buffer */ +EXPORT void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) +{ + int i,j; + int late; + /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ + + /* Cleanup buffer (remove old packets that weren't played) */ + if (!jitter->reset_state) + { + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */ + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp)) + { + /*fprintf (stderr, "cleaned (not played)\n");*/ + if (jitter->destroy) + jitter->destroy(jitter->packets[i].data); + else + speex_free(jitter->packets[i].data); + jitter->packets[i].data = NULL; + } + } + } + + /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/ + /* Check if packet is late (could still be useful though) */ + if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop)) + { + update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin); + late = 1; + } else { + late = 0; + } + + /* For some reason, the consumer has failed the last 20 fetches. Make sure this packet is + * used to resync. */ + if (jitter->lost_count>20) + { + jitter_buffer_reset(jitter); + } + + /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */ + if (jitter->reset_state || GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp)) + { + + /*Find an empty slot in the buffer*/ + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data==NULL) + break; + } + + /*No place left in the buffer, need to make room for it by discarding the oldest packet */ + if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) + { + int earliest=jitter->packets[0].timestamp; + i=0; + for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++) + { + if (!jitter->packets[i].data || LT32(jitter->packets[j].timestamp,earliest)) + { + earliest = jitter->packets[j].timestamp; + i=j; + } + } + if (jitter->destroy) + jitter->destroy(jitter->packets[i].data); + else + speex_free(jitter->packets[i].data); + jitter->packets[i].data=NULL; + /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ + } + + /* Copy packet in buffer */ + if (jitter->destroy) + { + jitter->packets[i].data = packet->data; + } else { + jitter->packets[i].data=(char*)speex_alloc(packet->len); + for (j=0;j<packet->len;j++) + jitter->packets[i].data[j]=packet->data[j]; + } + jitter->packets[i].timestamp=packet->timestamp; + jitter->packets[i].span=packet->span; + jitter->packets[i].len=packet->len; + jitter->packets[i].sequence=packet->sequence; + jitter->packets[i].user_data=packet->user_data; + if (jitter->reset_state || late) + jitter->arrival[i] = 0; + else + jitter->arrival[i] = jitter->next_stop; + } + + +} + +/** Get one packet from the jitter buffer */ +EXPORT int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset) +{ + int i; + unsigned int j; + int incomplete = 0; + spx_int16_t opt; + + if (start_offset != NULL) + *start_offset = 0; + + /* Syncing on the first call */ + if (jitter->reset_state) + { + int found = 0; + /* Find the oldest packet */ + spx_uint32_t oldest=0; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data && (!found || LT32(jitter->packets[i].timestamp,oldest))) + { + oldest = jitter->packets[i].timestamp; + found = 1; + } + } + if (found) + { + jitter->reset_state=0; + jitter->pointer_timestamp = oldest; + jitter->next_stop = oldest; + } else { + packet->timestamp = 0; + packet->span = jitter->interp_requested; + return JITTER_BUFFER_MISSING; + } + } + + + jitter->last_returned_timestamp = jitter->pointer_timestamp; + + if (jitter->interp_requested != 0) + { + packet->timestamp = jitter->pointer_timestamp; + packet->span = jitter->interp_requested; + + /* Increment the pointer because it got decremented in the delay update */ + jitter->pointer_timestamp += jitter->interp_requested; + packet->len = 0; + /*fprintf (stderr, "Deferred interpolate\n");*/ + + jitter->interp_requested = 0; + + jitter->buffered = packet->span - desired_span; + + return JITTER_BUFFER_INSERTION; + } + + /* Searching for the packet that fits best */ + + /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */ + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->pointer_timestamp && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span)) + break; + } + + /* If no match, try for an "older" packet that still spans (fully) the current chunk */ + if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) + { + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span)) + break; + } + } + + /* If still no match, try for an "older" packet that spans part of the current chunk */ + if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) + { + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GT32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp)) + break; + } + } + + /* If still no match, try for earliest packet possible */ + if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) + { + int found = 0; + spx_uint32_t best_time=0; + int best_span=0; + int besti=0; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + /* check if packet starts within current chunk */ + if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp)) + { + if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span))) + { + best_time = jitter->packets[i].timestamp; + best_span = jitter->packets[i].span; + besti = i; + found = 1; + } + } + } + if (found) + { + i=besti; + incomplete = 1; + /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span);*/ + } + } + + /* If we find something */ + if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) + { + spx_int32_t offset; + + /* We (obviously) haven't lost this packet */ + jitter->lost_count = 0; + + /* In this case, 0 isn't as a valid timestamp */ + if (jitter->arrival[i] != 0) + { + update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin); + } + + + /* Copy packet */ + if (jitter->destroy) + { + packet->data = jitter->packets[i].data; + packet->len = jitter->packets[i].len; + } else { + if (jitter->packets[i].len > packet->len) + { + speex_warning_int("jitter_buffer_get(): packet too large to fit. Size is", jitter->packets[i].len); + } else { + packet->len = jitter->packets[i].len; + } + for (j=0;j<packet->len;j++) + packet->data[j] = jitter->packets[i].data[j]; + /* Remove packet */ + speex_free(jitter->packets[i].data); + } + jitter->packets[i].data = NULL; + /* Set timestamp and span (if requested) */ + offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp; + if (start_offset != NULL) + *start_offset = offset; + else if (offset != 0) + speex_warning_int("jitter_buffer_get() discarding non-zero start_offset", offset); + + packet->timestamp = jitter->packets[i].timestamp; + jitter->last_returned_timestamp = packet->timestamp; + + packet->span = jitter->packets[i].span; + packet->sequence = jitter->packets[i].sequence; + packet->user_data = jitter->packets[i].user_data; + /* Point to the end of the current packet */ + jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span; + + jitter->buffered = packet->span - desired_span; + + if (start_offset != NULL) + jitter->buffered += *start_offset; + + return JITTER_BUFFER_OK; + } + + + /* If we haven't found anything worth returning */ + + /*fprintf (stderr, "not found\n");*/ + jitter->lost_count++; + /*fprintf (stderr, "m");*/ + /*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/ + + opt = compute_opt_delay(jitter); + + /* Should we force an increase in the buffer or just do normal interpolation? */ + if (opt < 0) + { + /* Need to increase buffering */ + + /* Shift histogram to compensate */ + shift_timings(jitter, -opt); + + packet->timestamp = jitter->pointer_timestamp; + packet->span = -opt; + /* Don't move the pointer_timestamp forward */ + packet->len = 0; + + jitter->buffered = packet->span - desired_span; + return JITTER_BUFFER_INSERTION; + /*jitter->pointer_timestamp -= jitter->delay_step;*/ + /*fprintf (stderr, "Forced to interpolate\n");*/ + } else { + /* Normal packet loss */ + packet->timestamp = jitter->pointer_timestamp; + + desired_span = ROUND_DOWN(desired_span, jitter->concealment_size); + packet->span = desired_span; + jitter->pointer_timestamp += desired_span; + packet->len = 0; + + jitter->buffered = packet->span - desired_span; + return JITTER_BUFFER_MISSING; + /*fprintf (stderr, "Normal loss\n");*/ + } + + +} + +EXPORT int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet) +{ + int i, j; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp) + break; + } + if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) + { + /* Copy packet */ + packet->len = jitter->packets[i].len; + if (jitter->destroy) + { + packet->data = jitter->packets[i].data; + } else { + for (j=0;j<packet->len;j++) + packet->data[j] = jitter->packets[i].data[j]; + /* Remove packet */ + speex_free(jitter->packets[i].data); + } + jitter->packets[i].data = NULL; + packet->timestamp = jitter->packets[i].timestamp; + packet->span = jitter->packets[i].span; + packet->sequence = jitter->packets[i].sequence; + packet->user_data = jitter->packets[i].user_data; + return JITTER_BUFFER_OK; + } else { + packet->data = NULL; + packet->len = 0; + packet->span = 0; + return JITTER_BUFFER_MISSING; + } +} + +/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ +static int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) +{ + spx_int16_t opt = compute_opt_delay(jitter); + /*fprintf(stderr, "opt adjustment is %d ", opt);*/ + + if (opt < 0) + { + shift_timings(jitter, -opt); + + jitter->pointer_timestamp += opt; + jitter->interp_requested = -opt; + /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/ + } else if (opt > 0) + { + shift_timings(jitter, -opt); + jitter->pointer_timestamp += opt; + /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/ + } + + return opt; +} + +/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ +EXPORT int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) +{ + /* If the programmer calls jitter_buffer_update_delay() directly, + automatically disable auto-adjustment */ + jitter->auto_adjust = 0; + + return _jitter_buffer_update_delay(jitter, packet, start_offset); +} + +/** Get pointer timestamp of jitter buffer */ +EXPORT int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) +{ + return jitter->pointer_timestamp; +} + +EXPORT void jitter_buffer_tick(JitterBuffer *jitter) +{ + /* Automatically-adjust the buffering delay if requested */ + if (jitter->auto_adjust) + _jitter_buffer_update_delay(jitter, NULL, NULL); + + if (jitter->buffered >= 0) + { + jitter->next_stop = jitter->pointer_timestamp - jitter->buffered; + } else { + jitter->next_stop = jitter->pointer_timestamp; + speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered); + } + jitter->buffered = 0; +} + +EXPORT void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) +{ + /* Automatically-adjust the buffering delay if requested */ + if (jitter->auto_adjust) + _jitter_buffer_update_delay(jitter, NULL, NULL); + + if (jitter->buffered < 0) + speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered); + jitter->next_stop = jitter->pointer_timestamp - rem; +} + + +/* Used like the ioctl function to control the jitter buffer parameters */ +EXPORT int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) +{ + int count, i; + switch(request) + { + case JITTER_BUFFER_SET_MARGIN: + jitter->buffer_margin = *(spx_int32_t*)ptr; + break; + case JITTER_BUFFER_GET_MARGIN: + *(spx_int32_t*)ptr = jitter->buffer_margin; + break; + case JITTER_BUFFER_GET_AVALIABLE_COUNT: + count = 0; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp)) + { + count++; + } + } + *(spx_int32_t*)ptr = count; + break; + case JITTER_BUFFER_SET_DESTROY_CALLBACK: + jitter->destroy = (void (*) (void *))ptr; + break; + case JITTER_BUFFER_GET_DESTROY_CALLBACK: + *(void (**) (void *))ptr = jitter->destroy; + break; + case JITTER_BUFFER_SET_DELAY_STEP: + jitter->delay_step = *(spx_int32_t*)ptr; + break; + case JITTER_BUFFER_GET_DELAY_STEP: + *(spx_int32_t*)ptr = jitter->delay_step; + break; + case JITTER_BUFFER_SET_CONCEALMENT_SIZE: + jitter->concealment_size = *(spx_int32_t*)ptr; + break; + case JITTER_BUFFER_GET_CONCEALMENT_SIZE: + *(spx_int32_t*)ptr = jitter->concealment_size; + break; + case JITTER_BUFFER_SET_MAX_LATE_RATE: + jitter->max_late_rate = *(spx_int32_t*)ptr; + jitter->window_size = 100*TOP_DELAY/jitter->max_late_rate; + jitter->subwindow_size = jitter->window_size/MAX_BUFFERS; + break; + case JITTER_BUFFER_GET_MAX_LATE_RATE: + *(spx_int32_t*)ptr = jitter->max_late_rate; + break; + case JITTER_BUFFER_SET_LATE_COST: + jitter->latency_tradeoff = *(spx_int32_t*)ptr; + break; + case JITTER_BUFFER_GET_LATE_COST: + *(spx_int32_t*)ptr = jitter->latency_tradeoff; + break; + default: + speex_warning_int("Unknown jitter_buffer_ctl request: ", request); + return -1; + } + return 0; +} + diff --git a/src/libs/speex/libspeex/kiss_fft.c b/src/libs/speex/libspeex/kiss_fft.c new file mode 100644 index 00000000..67782810 --- /dev/null +++ b/src/libs/speex/libspeex/kiss_fft.c @@ -0,0 +1,523 @@ +/* +Copyright (c) 2003-2004, Mark Borgerding +Copyright (c) 2005-2007, Jean-Marc Valin + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "_kiss_fft_guts.h" +#include "arch.h" +#include "os_support.h" + +/* The guts header contains all the multiplication and addition macros that are defined for + fixed or floating point complex numbers. It also delares the kf_ internal functions. + */ + +static void kf_bfly2( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m, + int N, + int mm + ) +{ + kiss_fft_cpx * Fout2; + kiss_fft_cpx * tw1; + kiss_fft_cpx t; + if (!st->inverse) { + int i,j; + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;i<N;i++) + { + Fout = Fout_beg + i*mm; + Fout2 = Fout + m; + tw1 = st->twiddles; + for(j=0;j<m;j++) + { + /* Almost the same as the code path below, except that we divide the input by two + (while keeping the best accuracy possible) */ + spx_word32_t tr, ti; + tr = SHR32(SUB32(MULT16_16(Fout2->r , tw1->r),MULT16_16(Fout2->i , tw1->i)), 1); + ti = SHR32(ADD32(MULT16_16(Fout2->i , tw1->r),MULT16_16(Fout2->r , tw1->i)), 1); + tw1 += fstride; + Fout2->r = PSHR32(SUB32(SHL32(EXTEND32(Fout->r), 14), tr), 15); + Fout2->i = PSHR32(SUB32(SHL32(EXTEND32(Fout->i), 14), ti), 15); + Fout->r = PSHR32(ADD32(SHL32(EXTEND32(Fout->r), 14), tr), 15); + Fout->i = PSHR32(ADD32(SHL32(EXTEND32(Fout->i), 14), ti), 15); + ++Fout2; + ++Fout; + } + } + } else { + int i,j; + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;i<N;i++) + { + Fout = Fout_beg + i*mm; + Fout2 = Fout + m; + tw1 = st->twiddles; + for(j=0;j<m;j++) + { + C_MUL (t, *Fout2 , *tw1); + tw1 += fstride; + C_SUB( *Fout2 , *Fout , t ); + C_ADDTO( *Fout , t ); + ++Fout2; + ++Fout; + } + } + } +} + +static void kf_bfly4( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m, + int N, + int mm + ) +{ + kiss_fft_cpx *tw1,*tw2,*tw3; + kiss_fft_cpx scratch[6]; + const size_t m2=2*m; + const size_t m3=3*m; + int i, j; + + if (st->inverse) + { + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;i<N;i++) + { + Fout = Fout_beg + i*mm; + tw3 = tw2 = tw1 = st->twiddles; + for (j=0;j<m;j++) + { + C_MUL(scratch[0],Fout[m] , *tw1 ); + C_MUL(scratch[1],Fout[m2] , *tw2 ); + C_MUL(scratch[2],Fout[m3] , *tw3 ); + + C_SUB( scratch[5] , *Fout, scratch[1] ); + C_ADDTO(*Fout, scratch[1]); + C_ADD( scratch[3] , scratch[0] , scratch[2] ); + C_SUB( scratch[4] , scratch[0] , scratch[2] ); + C_SUB( Fout[m2], *Fout, scratch[3] ); + tw1 += fstride; + tw2 += fstride*2; + tw3 += fstride*3; + C_ADDTO( *Fout , scratch[3] ); + + Fout[m].r = scratch[5].r - scratch[4].i; + Fout[m].i = scratch[5].i + scratch[4].r; + Fout[m3].r = scratch[5].r + scratch[4].i; + Fout[m3].i = scratch[5].i - scratch[4].r; + ++Fout; + } + } + } else + { + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;i<N;i++) + { + Fout = Fout_beg + i*mm; + tw3 = tw2 = tw1 = st->twiddles; + for (j=0;j<m;j++) + { + C_MUL4(scratch[0],Fout[m] , *tw1 ); + C_MUL4(scratch[1],Fout[m2] , *tw2 ); + C_MUL4(scratch[2],Fout[m3] , *tw3 ); + + Fout->r = PSHR16(Fout->r, 2); + Fout->i = PSHR16(Fout->i, 2); + C_SUB( scratch[5] , *Fout, scratch[1] ); + C_ADDTO(*Fout, scratch[1]); + C_ADD( scratch[3] , scratch[0] , scratch[2] ); + C_SUB( scratch[4] , scratch[0] , scratch[2] ); + Fout[m2].r = PSHR16(Fout[m2].r, 2); + Fout[m2].i = PSHR16(Fout[m2].i, 2); + C_SUB( Fout[m2], *Fout, scratch[3] ); + tw1 += fstride; + tw2 += fstride*2; + tw3 += fstride*3; + C_ADDTO( *Fout , scratch[3] ); + + Fout[m].r = scratch[5].r + scratch[4].i; + Fout[m].i = scratch[5].i - scratch[4].r; + Fout[m3].r = scratch[5].r - scratch[4].i; + Fout[m3].i = scratch[5].i + scratch[4].r; + ++Fout; + } + } + } +} + +static void kf_bfly3( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + size_t m + ) +{ + size_t k=m; + const size_t m2 = 2*m; + kiss_fft_cpx *tw1,*tw2; + kiss_fft_cpx scratch[5]; + kiss_fft_cpx epi3; + epi3 = st->twiddles[fstride*m]; + + tw1=tw2=st->twiddles; + + do{ + if (!st->inverse) { + C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); + } + + C_MUL(scratch[1],Fout[m] , *tw1); + C_MUL(scratch[2],Fout[m2] , *tw2); + + C_ADD(scratch[3],scratch[1],scratch[2]); + C_SUB(scratch[0],scratch[1],scratch[2]); + tw1 += fstride; + tw2 += fstride*2; + + Fout[m].r = Fout->r - HALF_OF(scratch[3].r); + Fout[m].i = Fout->i - HALF_OF(scratch[3].i); + + C_MULBYSCALAR( scratch[0] , epi3.i ); + + C_ADDTO(*Fout,scratch[3]); + + Fout[m2].r = Fout[m].r + scratch[0].i; + Fout[m2].i = Fout[m].i - scratch[0].r; + + Fout[m].r -= scratch[0].i; + Fout[m].i += scratch[0].r; + + ++Fout; + }while(--k); +} + +static void kf_bfly5( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m + ) +{ + kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; + int u; + kiss_fft_cpx scratch[13]; + kiss_fft_cpx * twiddles = st->twiddles; + kiss_fft_cpx *tw; + kiss_fft_cpx ya,yb; + ya = twiddles[fstride*m]; + yb = twiddles[fstride*2*m]; + + Fout0=Fout; + Fout1=Fout0+m; + Fout2=Fout0+2*m; + Fout3=Fout0+3*m; + Fout4=Fout0+4*m; + + tw=st->twiddles; + for ( u=0; u<m; ++u ) { + if (!st->inverse) { + C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5); + } + scratch[0] = *Fout0; + + C_MUL(scratch[1] ,*Fout1, tw[u*fstride]); + C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]); + C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]); + C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]); + + C_ADD( scratch[7],scratch[1],scratch[4]); + C_SUB( scratch[10],scratch[1],scratch[4]); + C_ADD( scratch[8],scratch[2],scratch[3]); + C_SUB( scratch[9],scratch[2],scratch[3]); + + Fout0->r += scratch[7].r + scratch[8].r; + Fout0->i += scratch[7].i + scratch[8].i; + + scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); + scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); + + scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); + scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); + + C_SUB(*Fout1,scratch[5],scratch[6]); + C_ADD(*Fout4,scratch[5],scratch[6]); + + scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); + scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); + scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); + scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); + + C_ADD(*Fout2,scratch[11],scratch[12]); + C_SUB(*Fout3,scratch[11],scratch[12]); + + ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; + } +} + +/* perform the butterfly for one stage of a mixed radix FFT */ +static void kf_bfly_generic( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m, + int p + ) +{ + int u,k,q1,q; + kiss_fft_cpx * twiddles = st->twiddles; + kiss_fft_cpx t; + kiss_fft_cpx scratchbuf[17]; + int Norig = st->nfft; + + /*CHECKBUF(scratchbuf,nscratchbuf,p);*/ + if (p>17) + speex_fatal("KissFFT: max radix supported is 17"); + + for ( u=0; u<m; ++u ) { + k=u; + for ( q1=0 ; q1<p ; ++q1 ) { + scratchbuf[q1] = Fout[ k ]; + if (!st->inverse) { + C_FIXDIV(scratchbuf[q1],p); + } + k += m; + } + + k=u; + for ( q1=0 ; q1<p ; ++q1 ) { + int twidx=0; + Fout[ k ] = scratchbuf[0]; + for (q=1;q<p;++q ) { + twidx += fstride * k; + if (twidx>=Norig) twidx-=Norig; + C_MUL(t,scratchbuf[q] , twiddles[twidx] ); + C_ADDTO( Fout[ k ] ,t); + } + k += m; + } + } +} + +static +void kf_shuffle( + kiss_fft_cpx * Fout, + const kiss_fft_cpx * f, + const size_t fstride, + int in_stride, + int * factors, + const kiss_fft_cfg st + ) +{ + const int p=*factors++; /* the radix */ + const int m=*factors++; /* stage's fft length/p */ + + /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/ + if (m==1) + { + int j; + for (j=0;j<p;j++) + { + Fout[j] = *f; + f += fstride*in_stride; + } + } else { + int j; + for (j=0;j<p;j++) + { + kf_shuffle( Fout , f, fstride*p, in_stride, factors,st); + f += fstride*in_stride; + Fout += m; + } + } +} + +static +void kf_work( + kiss_fft_cpx * Fout, + const kiss_fft_cpx * f, + const size_t fstride, + int in_stride, + int * factors, + const kiss_fft_cfg st, + int N, + int s2, + int m2 + ) +{ + int i; + kiss_fft_cpx * Fout_beg=Fout; + const int p=*factors++; /* the radix */ + const int m=*factors++; /* stage's fft length/p */ +#if 0 + /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/ + if (m==1) + { + /* int j; + for (j=0;j<p;j++) + { + Fout[j] = *f; + f += fstride*in_stride; + }*/ + } else { + int j; + for (j=0;j<p;j++) + { + kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m); + f += fstride*in_stride; + Fout += m; + } + } + + Fout=Fout_beg; + + switch (p) { + case 2: kf_bfly2(Fout,fstride,st,m); break; + case 3: kf_bfly3(Fout,fstride,st,m); break; + case 4: kf_bfly4(Fout,fstride,st,m); break; + case 5: kf_bfly5(Fout,fstride,st,m); break; + default: kf_bfly_generic(Fout,fstride,st,m,p); break; + } +#else + /*printf ("fft %d %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N, m2);*/ + if (m==1) + { + /*for (i=0;i<N;i++) + { + int j; + Fout = Fout_beg+i*m2; + const kiss_fft_cpx * f2 = f+i*s2; + for (j=0;j<p;j++) + { + *Fout++ = *f2; + f2 += fstride*in_stride; + } + }*/ + }else{ + kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m); + } + + + + + switch (p) { + case 2: kf_bfly2(Fout,fstride,st,m, N, m2); break; + case 3: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly3(Fout,fstride,st,m);} break; + case 4: kf_bfly4(Fout,fstride,st,m, N, m2); break; + case 5: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly5(Fout,fstride,st,m);} break; + default: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly_generic(Fout,fstride,st,m,p);} break; + } +#endif +} + +/* facbuf is populated by p1,m1,p2,m2, ... + where + p[i] * m[i] = m[i-1] + m0 = n */ +static +void kf_factor(int n,int * facbuf) +{ + int p=4; + + /*factor out powers of 4, powers of 2, then any remaining primes */ + do { + while (n % p) { + switch (p) { + case 4: p = 2; break; + case 2: p = 3; break; + default: p += 2; break; + } + if (p>32000 || (spx_int32_t)p*(spx_int32_t)p > n) + p = n; /* no more factors, skip to end */ + } + n /= p; + *facbuf++ = p; + *facbuf++ = n; + } while (n > 1); +} +/* + * + * User-callable function to allocate all necessary storage space for the fft. + * + * The return value is a contiguous block of memory, allocated with malloc. As such, + * It can be freed with free(), rather than a kiss_fft-specific function. + * */ +kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem ) +{ + kiss_fft_cfg st=NULL; + size_t memneeded = sizeof(struct kiss_fft_state) + + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/ + + if ( lenmem==NULL ) { + st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded ); + }else{ + if (mem != NULL && *lenmem >= memneeded) + st = (kiss_fft_cfg)mem; + *lenmem = memneeded; + } + if (st) { + int i; + st->nfft=nfft; + st->inverse = inverse_fft; +#ifdef FIXED_POINT + for (i=0;i<nfft;++i) { + spx_word32_t phase = i; + if (!st->inverse) + phase = -phase; + kf_cexp2(st->twiddles+i, DIV32(SHL32(phase,17),nfft)); + } +#else + for (i=0;i<nfft;++i) { + const double pi=3.14159265358979323846264338327; + double phase = ( -2*pi /nfft ) * i; + if (st->inverse) + phase *= -1; + kf_cexp(st->twiddles+i, phase ); + } +#endif + kf_factor(nfft,st->factors); + } + return st; +} + + + + +void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) +{ + if (fin == fout) + { + speex_fatal("In-place FFT not supported"); + /*CHECKBUF(tmpbuf,ntmpbuf,st->nfft); + kf_work(tmpbuf,fin,1,in_stride, st->factors,st); + SPEEX_MOVE(fout,tmpbuf,st->nfft);*/ + } else { + kf_shuffle( fout, fin, 1,in_stride, st->factors,st); + kf_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1); + } +} + +void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) +{ + kiss_fft_stride(cfg,fin,fout,1); +} + diff --git a/src/libs/speex/libspeex/kiss_fft.h b/src/libs/speex/libspeex/kiss_fft.h new file mode 100644 index 00000000..fa3f2c60 --- /dev/null +++ b/src/libs/speex/libspeex/kiss_fft.h @@ -0,0 +1,108 @@ +#ifndef KISS_FFT_H +#define KISS_FFT_H + +#include <stdlib.h> +#include <math.h> +#include "arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + ATTENTION! + If you would like a : + -- a utility that will handle the caching of fft objects + -- real-only (no imaginary time component ) FFT + -- a multi-dimensional FFT + -- a command-line utility to perform ffts + -- a command-line utility to perform fast-convolution filtering + + Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c + in the tools/ directory. +*/ + +#ifdef USE_SIMD +# include <xmmintrin.h> +# define kiss_fft_scalar __m128 +#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes) +#else +#define KISS_FFT_MALLOC speex_alloc +#endif + + +#ifdef FIXED_POINT +#include "arch.h" +# define kiss_fft_scalar spx_int16_t +#else +# ifndef kiss_fft_scalar +/* default is float */ +# define kiss_fft_scalar float +# endif +#endif + +typedef struct { + kiss_fft_scalar r; + kiss_fft_scalar i; +}kiss_fft_cpx; + +typedef struct kiss_fft_state* kiss_fft_cfg; + +/* + * kiss_fft_alloc + * + * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. + * + * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); + * + * The return value from fft_alloc is a cfg buffer used internally + * by the fft routine or NULL. + * + * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. + * The returned value should be free()d when done to avoid memory leaks. + * + * The state can be placed in a user supplied buffer 'mem': + * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, + * then the function places the cfg in mem and the size used in *lenmem + * and returns mem. + * + * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), + * then the function returns NULL and places the minimum cfg + * buffer size in *lenmem. + * */ + +kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); + +/* + * kiss_fft(cfg,in_out_buf) + * + * Perform an FFT on a complex input buffer. + * for a forward FFT, + * fin should be f[0] , f[1] , ... ,f[nfft-1] + * fout will be F[0] , F[1] , ... ,F[nfft-1] + * Note that each element is complex and can be accessed like + f[k].r and f[k].i + * */ +void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); + +/* + A more generic version of the above function. It reads its input from every Nth sample. + * */ +void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); + +/* If kiss_fft_alloc allocated a buffer, it is one contiguous + buffer and can be simply free()d when no longer needed*/ +#define kiss_fft_free speex_free + +/* + Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up + your compiler output to call this before you exit. +*/ +void kiss_fft_cleanup(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/speex/libspeex/kiss_fftr.c b/src/libs/speex/libspeex/kiss_fftr.c new file mode 100644 index 00000000..f6275b87 --- /dev/null +++ b/src/libs/speex/libspeex/kiss_fftr.c @@ -0,0 +1,297 @@ +/* +Copyright (c) 2003-2004, Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "os_support.h" +#include "kiss_fftr.h" +#include "_kiss_fft_guts.h" + +struct kiss_fftr_state{ + kiss_fft_cfg substate; + kiss_fft_cpx * tmpbuf; + kiss_fft_cpx * super_twiddles; +#ifdef USE_SIMD + long pad; +#endif +}; + +kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem) +{ + int i; + kiss_fftr_cfg st = NULL; + size_t subsize, memneeded; + + if (nfft & 1) { + speex_warning("Real FFT optimization must be even.\n"); + return NULL; + } + nfft >>= 1; + + kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize); + memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 2); + + if (lenmem == NULL) { + st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded); + } else { + if (*lenmem >= memneeded) + st = (kiss_fftr_cfg) mem; + *lenmem = memneeded; + } + if (!st) + return NULL; + + st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */ + st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize); + st->super_twiddles = st->tmpbuf + nfft; + kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); + +#ifdef FIXED_POINT + for (i=0;i<nfft;++i) { + spx_word32_t phase = i+(nfft>>1); + if (!inverse_fft) + phase = -phase; + kf_cexp2(st->super_twiddles+i, DIV32(SHL32(phase,16),nfft)); + } +#else + for (i=0;i<nfft;++i) { + const double pi=3.14159265358979323846264338327; + double phase = pi*(((double)i) /nfft + .5); + if (!inverse_fft) + phase = -phase; + kf_cexp(st->super_twiddles+i, phase ); + } +#endif + return st; +} + +void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata) +{ + /* input buffer timedata is stored row-wise */ + int k,ncfft; + kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; + + if ( st->substate->inverse) { + speex_fatal("kiss fft usage error: improper alloc\n"); + } + + ncfft = st->substate->nfft; + + /*perform the parallel fft of two real signals packed in real,imag*/ + kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); + /* The real part of the DC element of the frequency spectrum in st->tmpbuf + * contains the sum of the even-numbered elements of the input time sequence + * The imag part is the sum of the odd-numbered elements + * + * The sum of tdc.r and tdc.i is the sum of the input time sequence. + * yielding DC of input time sequence + * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... + * yielding Nyquist bin of input time sequence + */ + + tdc.r = st->tmpbuf[0].r; + tdc.i = st->tmpbuf[0].i; + C_FIXDIV(tdc,2); + CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); + CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); + freqdata[0].r = tdc.r + tdc.i; + freqdata[ncfft].r = tdc.r - tdc.i; +#ifdef USE_SIMD + freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0); +#else + freqdata[ncfft].i = freqdata[0].i = 0; +#endif + + for ( k=1;k <= ncfft/2 ; ++k ) { + fpk = st->tmpbuf[k]; + fpnk.r = st->tmpbuf[ncfft-k].r; + fpnk.i = - st->tmpbuf[ncfft-k].i; + C_FIXDIV(fpk,2); + C_FIXDIV(fpnk,2); + + C_ADD( f1k, fpk , fpnk ); + C_SUB( f2k, fpk , fpnk ); + C_MUL( tw , f2k , st->super_twiddles[k]); + + freqdata[k].r = HALF_OF(f1k.r + tw.r); + freqdata[k].i = HALF_OF(f1k.i + tw.i); + freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r); + freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i); + } +} + +void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata, kiss_fft_scalar *timedata) +{ + /* input buffer timedata is stored row-wise */ + int k, ncfft; + + if (st->substate->inverse == 0) { + speex_fatal("kiss fft usage error: improper alloc\n"); + } + + ncfft = st->substate->nfft; + + st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; + st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; + /*C_FIXDIV(st->tmpbuf[0],2);*/ + + for (k = 1; k <= ncfft / 2; ++k) { + kiss_fft_cpx fk, fnkc, fek, fok, tmp; + fk = freqdata[k]; + fnkc.r = freqdata[ncfft - k].r; + fnkc.i = -freqdata[ncfft - k].i; + /*C_FIXDIV( fk , 2 ); + C_FIXDIV( fnkc , 2 );*/ + + C_ADD (fek, fk, fnkc); + C_SUB (tmp, fk, fnkc); + C_MUL (fok, tmp, st->super_twiddles[k]); + C_ADD (st->tmpbuf[k], fek, fok); + C_SUB (st->tmpbuf[ncfft - k], fek, fok); +#ifdef USE_SIMD + st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); +#else + st->tmpbuf[ncfft - k].i *= -1; +#endif + } + kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); +} + +void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata) +{ + /* input buffer timedata is stored row-wise */ + int k,ncfft; + kiss_fft_cpx f2k,tdc; + spx_word32_t f1kr, f1ki, twr, twi; + + if ( st->substate->inverse) { + speex_fatal("kiss fft usage error: improper alloc\n"); + } + + ncfft = st->substate->nfft; + + /*perform the parallel fft of two real signals packed in real,imag*/ + kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); + /* The real part of the DC element of the frequency spectrum in st->tmpbuf + * contains the sum of the even-numbered elements of the input time sequence + * The imag part is the sum of the odd-numbered elements + * + * The sum of tdc.r and tdc.i is the sum of the input time sequence. + * yielding DC of input time sequence + * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... + * yielding Nyquist bin of input time sequence + */ + + tdc.r = st->tmpbuf[0].r; + tdc.i = st->tmpbuf[0].i; + C_FIXDIV(tdc,2); + CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); + CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); + freqdata[0] = tdc.r + tdc.i; + freqdata[2*ncfft-1] = tdc.r - tdc.i; + + for ( k=1;k <= ncfft/2 ; ++k ) + { + /*fpk = st->tmpbuf[k]; + fpnk.r = st->tmpbuf[ncfft-k].r; + fpnk.i = - st->tmpbuf[ncfft-k].i; + C_FIXDIV(fpk,2); + C_FIXDIV(fpnk,2); + + C_ADD( f1k, fpk , fpnk ); + C_SUB( f2k, fpk , fpnk ); + + C_MUL( tw , f2k , st->super_twiddles[k]); + + freqdata[2*k-1] = HALF_OF(f1k.r + tw.r); + freqdata[2*k] = HALF_OF(f1k.i + tw.i); + freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r); + freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i); + */ + + /*f1k.r = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1); + f1k.i = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1); + f2k.r = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1); + f2k.i = SHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1); + + C_MUL( tw , f2k , st->super_twiddles[k]); + + freqdata[2*k-1] = HALF_OF(f1k.r + tw.r); + freqdata[2*k] = HALF_OF(f1k.i + tw.i); + freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r); + freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i); + */ + f2k.r = SHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1); + f2k.i = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1); + + f1kr = SHL32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),13); + f1ki = SHL32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),13); + + twr = SHR32(SUB32(MULT16_16(f2k.r,st->super_twiddles[k].r),MULT16_16(f2k.i,st->super_twiddles[k].i)), 1); + twi = SHR32(ADD32(MULT16_16(f2k.i,st->super_twiddles[k].r),MULT16_16(f2k.r,st->super_twiddles[k].i)), 1); + +#ifdef FIXED_POINT + freqdata[2*k-1] = PSHR32(f1kr + twr, 15); + freqdata[2*k] = PSHR32(f1ki + twi, 15); + freqdata[2*(ncfft-k)-1] = PSHR32(f1kr - twr, 15); + freqdata[2*(ncfft-k)] = PSHR32(twi - f1ki, 15); +#else + freqdata[2*k-1] = .5f*(f1kr + twr); + freqdata[2*k] = .5f*(f1ki + twi); + freqdata[2*(ncfft-k)-1] = .5f*(f1kr - twr); + freqdata[2*(ncfft-k)] = .5f*(twi - f1ki); + +#endif + } +} + +void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata,kiss_fft_scalar *timedata) +{ + /* input buffer timedata is stored row-wise */ + int k, ncfft; + + if (st->substate->inverse == 0) { + speex_fatal ("kiss fft usage error: improper alloc\n"); + } + + ncfft = st->substate->nfft; + + st->tmpbuf[0].r = freqdata[0] + freqdata[2*ncfft-1]; + st->tmpbuf[0].i = freqdata[0] - freqdata[2*ncfft-1]; + /*C_FIXDIV(st->tmpbuf[0],2);*/ + + for (k = 1; k <= ncfft / 2; ++k) { + kiss_fft_cpx fk, fnkc, fek, fok, tmp; + fk.r = freqdata[2*k-1]; + fk.i = freqdata[2*k]; + fnkc.r = freqdata[2*(ncfft - k)-1]; + fnkc.i = -freqdata[2*(ncfft - k)]; + /*C_FIXDIV( fk , 2 ); + C_FIXDIV( fnkc , 2 );*/ + + C_ADD (fek, fk, fnkc); + C_SUB (tmp, fk, fnkc); + C_MUL (fok, tmp, st->super_twiddles[k]); + C_ADD (st->tmpbuf[k], fek, fok); + C_SUB (st->tmpbuf[ncfft - k], fek, fok); +#ifdef USE_SIMD + st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); +#else + st->tmpbuf[ncfft - k].i *= -1; +#endif + } + kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); +} diff --git a/src/libs/speex/libspeex/kiss_fftr.h b/src/libs/speex/libspeex/kiss_fftr.h new file mode 100644 index 00000000..7bfb4233 --- /dev/null +++ b/src/libs/speex/libspeex/kiss_fftr.h @@ -0,0 +1,51 @@ +#ifndef KISS_FTR_H +#define KISS_FTR_H + +#include "kiss_fft.h" +#ifdef __cplusplus +extern "C" { +#endif + + +/* + + Real optimized version can save about 45% cpu time vs. complex fft of a real seq. + + + + */ + +typedef struct kiss_fftr_state *kiss_fftr_cfg; + + +kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem); +/* + nfft must be even + + If you don't care to allocate space, use mem = lenmem = NULL +*/ + + +void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata); +/* + input timedata has nfft scalar points + output freqdata has nfft/2+1 complex points +*/ + +void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata); + +void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata); + +void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata, kiss_fft_scalar *timedata); + +/* + input freqdata has nfft/2+1 complex points + output timedata has nfft scalar points +*/ + +#define kiss_fftr_free speex_free + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/libs/speex/libspeex/lpc.c b/src/libs/speex/libspeex/lpc.c new file mode 100644 index 00000000..fd5d3821 --- /dev/null +++ b/src/libs/speex/libspeex/lpc.c @@ -0,0 +1,201 @@ +/* + Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, + Technische Universitaet Berlin + + Any use of this software is permitted provided that this notice is not + removed and that neither the authors nor the Technische Universitaet Berlin + are deemed to have made any representations as to the suitability of this + software for any purpose nor are held responsible for any defects of + this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + + As a matter of courtesy, the authors request to be informed about uses + this software has found, about bugs in this software, and about any + improvements that may be of general interest. + + Berlin, 28.11.1994 + Jutta Degener + Carsten Bormann + + + Code modified by Jean-Marc Valin + + Speex License: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "lpc.h" + +#ifdef BFIN_ASM +#include "lpc_bfin.h" +#endif + +/* LPC analysis + * + * The next two functions calculate linear prediction coefficients + * and/or the related reflection coefficients from the first P_MAX+1 + * values of the autocorrelation function. + */ + +/* Invented by N. Levinson in 1947, modified by J. Durbin in 1959. + */ + +/* returns minimum mean square error */ +spx_word32_t _spx_lpc( +spx_coef_t *lpc, /* out: [0...p-1] LPC coefficients */ +const spx_word16_t *ac, /* in: [0...p] autocorrelation values */ +int p +) +{ + int i, j; + spx_word16_t r; + spx_word16_t error = ac[0]; + + if (ac[0] == 0) + { + for (i = 0; i < p; i++) + lpc[i] = 0; + return 0; + } + + for (i = 0; i < p; i++) { + + /* Sum up this iteration's reflection coefficient */ + spx_word32_t rr = NEG32(SHL32(EXTEND32(ac[i + 1]),13)); + for (j = 0; j < i; j++) + rr = SUB32(rr,MULT16_16(lpc[j],ac[i - j])); +#ifdef FIXED_POINT + r = DIV32_16(rr+PSHR32(error,1),ADD16(error,8)); +#else + r = rr/(error+.003*ac[0]); +#endif + /* Update LPC coefficients and total error */ + lpc[i] = r; + for (j = 0; j < i>>1; j++) + { + spx_word16_t tmp = lpc[j]; + lpc[j] = MAC16_16_P13(lpc[j],r,lpc[i-1-j]); + lpc[i-1-j] = MAC16_16_P13(lpc[i-1-j],r,tmp); + } + if (i & 1) + lpc[j] = MAC16_16_P13(lpc[j],lpc[j],r); + + error = SUB16(error,MULT16_16_Q13(r,MULT16_16_Q13(error,r))); + } + return error; +} + + +#ifdef FIXED_POINT + +/* Compute the autocorrelation + * ,--, + * ac(i) = > x(n) * x(n-i) for all n + * `--' + * for lags between 0 and lag-1, and x == 0 outside 0...n-1 + */ + +#ifndef OVERRIDE_SPEEX_AUTOCORR +void _spx_autocorr( +const spx_word16_t *x, /* in: [0...n-1] samples x */ +spx_word16_t *ac, /* out: [0...lag-1] ac values */ +int lag, +int n +) +{ + spx_word32_t d; + int i, j; + spx_word32_t ac0=1; + int shift, ac_shift; + + for (j=0;j<n;j++) + ac0 = ADD32(ac0,SHR32(MULT16_16(x[j],x[j]),8)); + ac0 = ADD32(ac0,n); + shift = 8; + while (shift && ac0<0x40000000) + { + shift--; + ac0 <<= 1; + } + ac_shift = 18; + while (ac_shift && ac0<0x40000000) + { + ac_shift--; + ac0 <<= 1; + } + + + for (i=0;i<lag;i++) + { + d=0; + for (j=i;j<n;j++) + { + d = ADD32(d,SHR32(MULT16_16(x[j],x[j-i]), shift)); + } + + ac[i] = SHR32(d, ac_shift); + } +} +#endif + + +#else + + + +/* Compute the autocorrelation + * ,--, + * ac(i) = > x(n) * x(n-i) for all n + * `--' + * for lags between 0 and lag-1, and x == 0 outside 0...n-1 + */ +void _spx_autocorr( +const spx_word16_t *x, /* in: [0...n-1] samples x */ +float *ac, /* out: [0...lag-1] ac values */ +int lag, +int n +) +{ + float d; + int i; + while (lag--) + { + for (i = lag, d = 0; i < n; i++) + d += x[i] * x[i-lag]; + ac[lag] = d; + } + ac[0] += 10; +} + +#endif + + diff --git a/src/libs/speex/libspeex/lpc.h b/src/libs/speex/libspeex/lpc.h new file mode 100644 index 00000000..952ecdd9 --- /dev/null +++ b/src/libs/speex/libspeex/lpc.h @@ -0,0 +1,53 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file lpc.h + @brief Functions for LPC (Linear Prediction Coefficients) analysis +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef LPC_H +#define LPC_H + +#include "arch.h" + +void _spx_autocorr( + const spx_word16_t * x, /* in: [0...n-1] samples x */ + spx_word16_t *ac, /* out: [0...lag-1] ac values */ + int lag, int n); + +spx_word32_t /* returns minimum mean square error */ +_spx_lpc( + spx_coef_t * lpc, /* [0...p-1] LPC coefficients */ + const spx_word16_t * ac, /* in: [0...p] autocorrelation values */ + int p + ); + + +#endif diff --git a/src/libs/speex/libspeex/lpc_bfin.h b/src/libs/speex/libspeex/lpc_bfin.h new file mode 100644 index 00000000..7310ffba --- /dev/null +++ b/src/libs/speex/libspeex/lpc_bfin.h @@ -0,0 +1,131 @@ +/* Copyright (C) 2005 Analog Devices */ +/** + @file lpc_bfin.h + @author Jean-Marc Valin + @brief Functions for LPC (Linear Prediction Coefficients) analysis (Blackfin version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define OVERRIDE_SPEEX_AUTOCORR +void _spx_autocorr( +const spx_word16_t *x, /* in: [0...n-1] samples x */ +spx_word16_t *ac, /* out: [0...lag-1] ac values */ +int lag, +int n + ) +{ + spx_word32_t d; + const spx_word16_t *xs; + int i, j; + spx_word32_t ac0=1; + spx_word32_t ac32[11], *ac32top; + int shift, ac_shift; + ac32top = ac32+lag-1; + int lag_1, N_lag; + int nshift; + lag_1 = lag-1; + N_lag = n-lag_1; + for (j=0;j<n;j++) + ac0 = ADD32(ac0,SHR32(MULT16_16(x[j],x[j]),8)); + ac0 = ADD32(ac0,n); + shift = 8; + while (shift && ac0<0x40000000) + { + shift--; + ac0 <<= 1; + } + ac_shift = 18; + while (ac_shift && ac0<0x40000000) + { + ac_shift--; + ac0 <<= 1; + } + + xs = x+lag-1; + nshift = -shift; + __asm__ __volatile__ + ( + "P2 = %0;\n\t" + "I0 = P2;\n\t" /* x in I0 */ + "B0 = P2;\n\t" /* x in B0 */ + "R0 = %3;\n\t" /* len in R0 */ + "P3 = %3;\n\t" /* len in R0 */ + "P4 = %4;\n\t" /* nb_pitch in R0 */ + "R1 = R0 << 1;\n\t" /* number of bytes in x */ + "L0 = R1;\n\t" + "P0 = %1;\n\t" + "P1 = %2;\n\t" + "B1 = P1;\n\t" + "R4 = %5;\n\t" + "L1 = 0;\n\t" /*Disable looping on I1*/ + + "r0 = [I0++];\n\t" + "R2 = 0;R3=0;" + "LOOP pitch%= LC0 = P4 >> 1;\n\t" + "LOOP_BEGIN pitch%=;\n\t" + "I1 = P0;\n\t" + "A1 = A0 = 0;\n\t" + "R1 = [I1++];\n\t" + "LOOP inner_prod%= LC1 = P3 >> 1;\n\t" + "LOOP_BEGIN inner_prod%=;\n\t" + "A1 += R0.L*R1.H, A0 += R0.L*R1.L (IS) || R1.L = W[I1++];\n\t" + "A1 += R0.H*R1.L, A0 += R0.H*R1.H (IS) || R1.H = W[I1++] || R0 = [I0++];\n\t" + "LOOP_END inner_prod%=;\n\t" + "A0 = ASHIFT A0 by R4.L;\n\t" + "A1 = ASHIFT A1 by R4.L;\n\t" + + "R2 = A0, R3 = A1;\n\t" + "[P1--] = R2;\n\t" + "[P1--] = R3;\n\t" + "P0 += 4;\n\t" + "LOOP_END pitch%=;\n\t" + : : "m" (xs), "m" (x), "m" (ac32top), "m" (N_lag), "m" (lag_1), "m" (nshift) + : "A0", "A1", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "R3", "R4", "I0", "I1", "L0", "L1", "B0", "B1", "memory" + ); + d=0; + for (j=0;j<n;j++) + { + d = ADD32(d,SHR32(MULT16_16(x[j],x[j]), shift)); + } + ac32[0] = d; + + for (i=0;i<lag;i++) + { + d=0; + for (j=i;j<lag_1;j++) + { + d = ADD32(d,SHR32(MULT16_16(x[j],x[j-i]), shift)); + } + if (i) + ac32[i] += d; + ac[i] = SHR32(ac32[i], ac_shift); + } +} + diff --git a/src/libs/speex/libspeex/lsp.c b/src/libs/speex/libspeex/lsp.c new file mode 100644 index 00000000..a73d8835 --- /dev/null +++ b/src/libs/speex/libspeex/lsp.c @@ -0,0 +1,656 @@ +/*---------------------------------------------------------------------------*\ +Original copyright + FILE........: lsp.c + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + +Heavily modified by Jean-Marc Valin (c) 2002-2006 (fixed-point, + optimizations, additional functions, ...) + + This file contains functions for converting Linear Prediction + Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the + LSP coefficients are not in radians format but in the x domain of the + unit circle. + + Speex License: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*---------------------------------------------------------------------------*\ + + Introduction to Line Spectrum Pairs (LSPs) + ------------------------------------------ + + LSPs are used to encode the LPC filter coefficients {ak} for + transmission over the channel. LSPs have several properties (like + less sensitivity to quantisation noise) that make them superior to + direct quantisation of {ak}. + + A(z) is a polynomial of order lpcrdr with {ak} as the coefficients. + + A(z) is transformed to P(z) and Q(z) (using a substitution and some + algebra), to obtain something like: + + A(z) = 0.5[P(z)(z+z^-1) + Q(z)(z-z^-1)] (1) + + As you can imagine A(z) has complex zeros all over the z-plane. P(z) + and Q(z) have the very neat property of only having zeros _on_ the + unit circle. So to find them we take a test point z=exp(jw) and + evaluate P (exp(jw)) and Q(exp(jw)) using a grid of points between 0 + and pi. + + The zeros (roots) of P(z) also happen to alternate, which is why we + swap coefficients as we find roots. So the process of finding the + LSP frequencies is basically finding the roots of 5th order + polynomials. + + The root so P(z) and Q(z) occur in symmetrical pairs at +/-w, hence + the name Line Spectrum Pairs (LSPs). + + To convert back to ak we just evaluate (1), "clocking" an impulse + thru it lpcrdr times gives us the impulse response of A(z) which is + {ak}. + +\*---------------------------------------------------------------------------*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <math.h> +#include "lsp.h" +#include "stack_alloc.h" +#include "math_approx.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifdef FIXED_POINT + +#define FREQ_SCALE 16384 + +/*#define ANGLE2X(a) (32768*cos(((a)/8192.)))*/ +#define ANGLE2X(a) (SHL16(spx_cos(a),2)) + +/*#define X2ANGLE(x) (acos(.00006103515625*(x))*LSP_SCALING)*/ +#define X2ANGLE(x) (spx_acos(x)) + +#ifdef BFIN_ASM +#include "lsp_bfin.h" +#endif + +#else + +/*#define C1 0.99940307 +#define C2 -0.49558072 +#define C3 0.03679168*/ + +#define FREQ_SCALE 1. +#define ANGLE2X(a) (spx_cos(a)) +#define X2ANGLE(x) (acos(x)) + +#endif + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: cheb_poly_eva() + + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + This function evaluates a series of Chebyshev polynomials + +\*---------------------------------------------------------------------------*/ + +#ifdef FIXED_POINT + +#ifndef OVERRIDE_CHEB_POLY_EVA +static inline spx_word32_t cheb_poly_eva( + spx_word16_t *coef, /* P or Q coefs in Q13 format */ + spx_word16_t x, /* cos of freq (-1.0 to 1.0) in Q14 format */ + int m, /* LPC order/2 */ + char *stack +) +{ + int i; + spx_word16_t b0, b1; + spx_word32_t sum; + + /*Prevents overflows*/ + if (x>16383) + x = 16383; + if (x<-16383) + x = -16383; + + /* Initialise values */ + b1=16384; + b0=x; + + /* Evaluate Chebyshev series formulation usin g iterative approach */ + sum = ADD32(EXTEND32(coef[m]), EXTEND32(MULT16_16_P14(coef[m-1],x))); + for(i=2;i<=m;i++) + { + spx_word16_t tmp=b0; + b0 = SUB16(MULT16_16_Q13(x,b0), b1); + b1 = tmp; + sum = ADD32(sum, EXTEND32(MULT16_16_P14(coef[m-i],b0))); + } + + return sum; +} +#endif + +#else + +static float cheb_poly_eva(spx_word32_t *coef, spx_word16_t x, int m, char *stack) +{ + int k; + float b0, b1, tmp; + + /* Initial conditions */ + b0=0; /* b_(m+1) */ + b1=0; /* b_(m+2) */ + + x*=2; + + /* Calculate the b_(k) */ + for(k=m;k>0;k--) + { + tmp=b0; /* tmp holds the previous value of b0 */ + b0=x*b0-b1+coef[m-k]; /* b0 holds its new value based on b0 and b1 */ + b1=tmp; /* b1 holds the previous value of b0 */ + } + + return(-b1+.5*x*b0+coef[m]); +} +#endif + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: lpc_to_lsp() + + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + This function converts LPC coefficients to LSP + coefficients. + +\*---------------------------------------------------------------------------*/ + +#ifdef FIXED_POINT +#define SIGN_CHANGE(a,b) (((a)&0x70000000)^((b)&0x70000000)||(b==0)) +#else +#define SIGN_CHANGE(a,b) (((a)*(b))<0.0) +#endif + + +int lpc_to_lsp (spx_coef_t *a,int lpcrdr,spx_lsp_t *freq,int nb,spx_word16_t delta, char *stack) +/* float *a lpc coefficients */ +/* int lpcrdr order of LPC coefficients (10) */ +/* float *freq LSP frequencies in the x domain */ +/* int nb number of sub-intervals (4) */ +/* float delta grid spacing interval (0.02) */ + + +{ + spx_word16_t temp_xr,xl,xr,xm=0; + spx_word32_t psuml,psumr,psumm,temp_psumr/*,temp_qsumr*/; + int i,j,m,flag,k; + VARDECL(spx_word32_t *Q); /* ptrs for memory allocation */ + VARDECL(spx_word32_t *P); + VARDECL(spx_word16_t *Q16); /* ptrs for memory allocation */ + VARDECL(spx_word16_t *P16); + spx_word32_t *px; /* ptrs of respective P'(z) & Q'(z) */ + spx_word32_t *qx; + spx_word32_t *p; + spx_word32_t *q; + spx_word16_t *pt; /* ptr used for cheb_poly_eval() + whether P' or Q' */ + int roots=0; /* DR 8/2/94: number of roots found */ + flag = 1; /* program is searching for a root when, + 1 else has found one */ + m = lpcrdr/2; /* order of P'(z) & Q'(z) polynomials */ + + /* Allocate memory space for polynomials */ + ALLOC(Q, (m+1), spx_word32_t); + ALLOC(P, (m+1), spx_word32_t); + + /* determine P'(z)'s and Q'(z)'s coefficients where + P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */ + + px = P; /* initialise ptrs */ + qx = Q; + p = px; + q = qx; + +#ifdef FIXED_POINT + *px++ = LPC_SCALING; + *qx++ = LPC_SCALING; + for(i=0;i<m;i++){ + *px++ = SUB32(ADD32(EXTEND32(a[i]),EXTEND32(a[lpcrdr-i-1])), *p++); + *qx++ = ADD32(SUB32(EXTEND32(a[i]),EXTEND32(a[lpcrdr-i-1])), *q++); + } + px = P; + qx = Q; + for(i=0;i<m;i++) + { + /*if (fabs(*px)>=32768) + speex_warning_int("px", *px); + if (fabs(*qx)>=32768) + speex_warning_int("qx", *qx);*/ + *px = PSHR32(*px,2); + *qx = PSHR32(*qx,2); + px++; + qx++; + } + /* The reason for this lies in the way cheb_poly_eva() is implemented for fixed-point */ + P[m] = PSHR32(P[m],3); + Q[m] = PSHR32(Q[m],3); +#else + *px++ = LPC_SCALING; + *qx++ = LPC_SCALING; + for(i=0;i<m;i++){ + *px++ = (a[i]+a[lpcrdr-1-i]) - *p++; + *qx++ = (a[i]-a[lpcrdr-1-i]) + *q++; + } + px = P; + qx = Q; + for(i=0;i<m;i++){ + *px = 2**px; + *qx = 2**qx; + px++; + qx++; + } +#endif + + px = P; /* re-initialise ptrs */ + qx = Q; + + /* now that we have computed P and Q convert to 16 bits to + speed up cheb_poly_eval */ + + ALLOC(P16, m+1, spx_word16_t); + ALLOC(Q16, m+1, spx_word16_t); + + for (i=0;i<m+1;i++) + { + P16[i] = P[i]; + Q16[i] = Q[i]; + } + + /* Search for a zero in P'(z) polynomial first and then alternate to Q'(z). + Keep alternating between the two polynomials as each zero is found */ + + xr = 0; /* initialise xr to zero */ + xl = FREQ_SCALE; /* start at point xl = 1 */ + + for(j=0;j<lpcrdr;j++){ + if(j&1) /* determines whether P' or Q' is eval. */ + pt = Q16; + else + pt = P16; + + psuml = cheb_poly_eva(pt,xl,m,stack); /* evals poly. at xl */ + flag = 1; + while(flag && (xr >= -FREQ_SCALE)){ + spx_word16_t dd; + /* Modified by JMV to provide smaller steps around x=+-1 */ +#ifdef FIXED_POINT + dd = MULT16_16_Q15(delta,SUB16(FREQ_SCALE, MULT16_16_Q14(MULT16_16_Q14(xl,xl),14000))); + if (psuml<512 && psuml>-512) + dd = PSHR16(dd,1); +#else + dd=delta*(1-.9*xl*xl); + if (fabs(psuml)<.2) + dd *= .5; +#endif + xr = SUB16(xl, dd); /* interval spacing */ + psumr = cheb_poly_eva(pt,xr,m,stack);/* poly(xl-delta_x) */ + temp_psumr = psumr; + temp_xr = xr; + + /* if no sign change increment xr and re-evaluate poly(xr). Repeat til + sign change. + if a sign change has occurred the interval is bisected and then + checked again for a sign change which determines in which + interval the zero lies in. + If there is no sign change between poly(xm) and poly(xl) set interval + between xm and xr else set interval between xl and xr and repeat till + root is located within the specified limits */ + + if(SIGN_CHANGE(psumr,psuml)) + { + roots++; + + psumm=psuml; + for(k=0;k<=nb;k++){ +#ifdef FIXED_POINT + xm = ADD16(PSHR16(xl,1),PSHR16(xr,1)); /* bisect the interval */ +#else + xm = .5*(xl+xr); /* bisect the interval */ +#endif + psumm=cheb_poly_eva(pt,xm,m,stack); + /*if(psumm*psuml>0.)*/ + if(!SIGN_CHANGE(psumm,psuml)) + { + psuml=psumm; + xl=xm; + } else { + psumr=psumm; + xr=xm; + } + } + + /* once zero is found, reset initial interval to xr */ + freq[j] = X2ANGLE(xm); + xl = xm; + flag = 0; /* reset flag for next search */ + } + else{ + psuml=temp_psumr; + xl=temp_xr; + } + } + } + return(roots); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: lsp_to_lpc() + + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + Converts LSP coefficients to LPC coefficients. + +\*---------------------------------------------------------------------------*/ + +#ifdef FIXED_POINT + +void lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack) +/* float *freq array of LSP frequencies in the x domain */ +/* float *ak array of LPC coefficients */ +/* int lpcrdr order of LPC coefficients */ +{ + int i,j; + spx_word32_t xout1,xout2,xin; + spx_word32_t mult, a; + VARDECL(spx_word16_t *freqn); + VARDECL(spx_word32_t **xp); + VARDECL(spx_word32_t *xpmem); + VARDECL(spx_word32_t **xq); + VARDECL(spx_word32_t *xqmem); + int m = lpcrdr>>1; + + /* + + Reconstruct P(z) and Q(z) by cascading second order polynomials + in form 1 - 2cos(w)z(-1) + z(-2), where w is the LSP frequency. + In the time domain this is: + + y(n) = x(n) - 2cos(w)x(n-1) + x(n-2) + + This is what the ALLOCS below are trying to do: + + int xp[m+1][lpcrdr+1+2]; // P matrix in QIMP + int xq[m+1][lpcrdr+1+2]; // Q matrix in QIMP + + These matrices store the output of each stage on each row. The + final (m-th) row has the output of the final (m-th) cascaded + 2nd order filter. The first row is the impulse input to the + system (not written as it is known). + + The version below takes advantage of the fact that a lot of the + outputs are zero or known, for example if we put an inpulse + into the first section the "clock" it 10 times only the first 3 + outputs samples are non-zero (it's an FIR filter). + */ + + ALLOC(xp, (m+1), spx_word32_t*); + ALLOC(xpmem, (m+1)*(lpcrdr+1+2), spx_word32_t); + + ALLOC(xq, (m+1), spx_word32_t*); + ALLOC(xqmem, (m+1)*(lpcrdr+1+2), spx_word32_t); + + for(i=0; i<=m; i++) { + xp[i] = xpmem + i*(lpcrdr+1+2); + xq[i] = xqmem + i*(lpcrdr+1+2); + } + + /* work out 2cos terms in Q14 */ + + ALLOC(freqn, lpcrdr, spx_word16_t); + for (i=0;i<lpcrdr;i++) + freqn[i] = ANGLE2X(freq[i]); + + #define QIMP 21 /* scaling for impulse */ + + xin = SHL32(EXTEND32(1), (QIMP-1)); /* 0.5 in QIMP format */ + + /* first col and last non-zero values of each row are trivial */ + + for(i=0;i<=m;i++) { + xp[i][1] = 0; + xp[i][2] = xin; + xp[i][2+2*i] = xin; + xq[i][1] = 0; + xq[i][2] = xin; + xq[i][2+2*i] = xin; + } + + /* 2nd row (first output row) is trivial */ + + xp[1][3] = -MULT16_32_Q14(freqn[0],xp[0][2]); + xq[1][3] = -MULT16_32_Q14(freqn[1],xq[0][2]); + + xout1 = xout2 = 0; + + /* now generate remaining rows */ + + for(i=1;i<m;i++) { + + for(j=1;j<2*(i+1)-1;j++) { + mult = MULT16_32_Q14(freqn[2*i],xp[i][j+1]); + xp[i+1][j+2] = ADD32(SUB32(xp[i][j+2], mult), xp[i][j]); + mult = MULT16_32_Q14(freqn[2*i+1],xq[i][j+1]); + xq[i+1][j+2] = ADD32(SUB32(xq[i][j+2], mult), xq[i][j]); + } + + /* for last col xp[i][j+2] = xq[i][j+2] = 0 */ + + mult = MULT16_32_Q14(freqn[2*i],xp[i][j+1]); + xp[i+1][j+2] = SUB32(xp[i][j], mult); + mult = MULT16_32_Q14(freqn[2*i+1],xq[i][j+1]); + xq[i+1][j+2] = SUB32(xq[i][j], mult); + } + + /* process last row to extra a{k} */ + + for(j=1;j<=lpcrdr;j++) { + int shift = QIMP-13; + + /* final filter sections */ + a = PSHR32(xp[m][j+2] + xout1 + xq[m][j+2] - xout2, shift); + xout1 = xp[m][j+2]; + xout2 = xq[m][j+2]; + + /* hard limit ak's to +/- 32767 */ + + if (a < -32767) a = -32767; + if (a > 32767) a = 32767; + ak[j-1] = (short)a; + + } + +} + +#else + +void lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack) +/* float *freq array of LSP frequencies in the x domain */ +/* float *ak array of LPC coefficients */ +/* int lpcrdr order of LPC coefficients */ + + +{ + int i,j; + float xout1,xout2,xin1,xin2; + VARDECL(float *Wp); + float *pw,*n1,*n2,*n3,*n4=NULL; + VARDECL(float *x_freq); + int m = lpcrdr>>1; + + ALLOC(Wp, 4*m+2, float); + pw = Wp; + + /* initialise contents of array */ + + for(i=0;i<=4*m+1;i++){ /* set contents of buffer to 0 */ + *pw++ = 0.0; + } + + /* Set pointers up */ + + pw = Wp; + xin1 = 1.0; + xin2 = 1.0; + + ALLOC(x_freq, lpcrdr, float); + for (i=0;i<lpcrdr;i++) + x_freq[i] = ANGLE2X(freq[i]); + + /* reconstruct P(z) and Q(z) by cascading second order + polynomials in form 1 - 2xz(-1) +z(-2), where x is the + LSP coefficient */ + + for(j=0;j<=lpcrdr;j++){ + int i2=0; + for(i=0;i<m;i++,i2+=2){ + n1 = pw+(i*4); + n2 = n1 + 1; + n3 = n2 + 1; + n4 = n3 + 1; + xout1 = xin1 - 2.f*x_freq[i2] * *n1 + *n2; + xout2 = xin2 - 2.f*x_freq[i2+1] * *n3 + *n4; + *n2 = *n1; + *n4 = *n3; + *n1 = xin1; + *n3 = xin2; + xin1 = xout1; + xin2 = xout2; + } + xout1 = xin1 + *(n4+1); + xout2 = xin2 - *(n4+2); + if (j>0) + ak[j-1] = (xout1 + xout2)*0.5f; + *(n4+1) = xin1; + *(n4+2) = xin2; + + xin1 = 0.0; + xin2 = 0.0; + } + +} +#endif + + +#ifdef FIXED_POINT + +/*Makes sure the LSPs are stable*/ +void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin) +{ + int i; + spx_word16_t m = margin; + spx_word16_t m2 = 25736-margin; + + if (lsp[0]<m) + lsp[0]=m; + if (lsp[len-1]>m2) + lsp[len-1]=m2; + for (i=1;i<len-1;i++) + { + if (lsp[i]<lsp[i-1]+m) + lsp[i]=lsp[i-1]+m; + + if (lsp[i]>lsp[i+1]-m) + lsp[i]= SHR16(lsp[i],1) + SHR16(lsp[i+1]-m,1); + } +} + + +void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes) +{ + int i; + spx_word16_t tmp = DIV32_16(SHL32(EXTEND32(1 + subframe),14),nb_subframes); + spx_word16_t tmp2 = 16384-tmp; + for (i=0;i<len;i++) + { + interp_lsp[i] = MULT16_16_P14(tmp2,old_lsp[i]) + MULT16_16_P14(tmp,new_lsp[i]); + } +} + +#else + +/*Makes sure the LSPs are stable*/ +void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin) +{ + int i; + if (lsp[0]<LSP_SCALING*margin) + lsp[0]=LSP_SCALING*margin; + if (lsp[len-1]>LSP_SCALING*(M_PI-margin)) + lsp[len-1]=LSP_SCALING*(M_PI-margin); + for (i=1;i<len-1;i++) + { + if (lsp[i]<lsp[i-1]+LSP_SCALING*margin) + lsp[i]=lsp[i-1]+LSP_SCALING*margin; + + if (lsp[i]>lsp[i+1]-LSP_SCALING*margin) + lsp[i]= .5f* (lsp[i] + lsp[i+1]-LSP_SCALING*margin); + } +} + + +void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes) +{ + int i; + float tmp = (1.0f + subframe)/nb_subframes; + for (i=0;i<len;i++) + { + interp_lsp[i] = (1-tmp)*old_lsp[i] + tmp*new_lsp[i]; + } +} + +#endif diff --git a/src/libs/speex/libspeex/lsp.h b/src/libs/speex/libspeex/lsp.h new file mode 100644 index 00000000..b55bd42f --- /dev/null +++ b/src/libs/speex/libspeex/lsp.h @@ -0,0 +1,64 @@ +/*---------------------------------------------------------------------------*\ +Original Copyright + FILE........: AK2LSPD.H + TYPE........: Turbo C header file + COMPANY.....: Voicetronix + AUTHOR......: James Whitehall + DATE CREATED: 21/11/95 + +Modified by Jean-Marc Valin + + This file contains functions for converting Linear Prediction + Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the + LSP coefficients are not in radians format but in the x domain of the + unit circle. + +\*---------------------------------------------------------------------------*/ +/** + @file lsp.h + @brief Line Spectral Pair (LSP) functions. +*/ +/* Speex License: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef __AK2LSPD__ +#define __AK2LSPD__ + +#include "arch.h" + +int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack); +void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack); + +/*Added by JMV*/ +void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin); + +void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes); + +#endif /* __AK2LSPD__ */ diff --git a/src/libs/speex/libspeex/lsp_bfin.h b/src/libs/speex/libspeex/lsp_bfin.h new file mode 100644 index 00000000..20e50528 --- /dev/null +++ b/src/libs/speex/libspeex/lsp_bfin.h @@ -0,0 +1,89 @@ +/* Copyright (C) 2006 David Rowe */ +/** + @file lsp_bfin.h + @author David Rowe + @brief LSP routines optimised for the Blackfin +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define OVERRIDE_CHEB_POLY_EVA +#ifdef OVERRIDE_CHEB_POLY_EVA +static inline spx_word32_t cheb_poly_eva( + spx_word16_t *coef, /* P or Q coefs in Q13 format */ + spx_word16_t x, /* cos of freq (-1.0 to 1.0) in Q14 format */ + int m, /* LPC order/2 */ + char *stack +) +{ + spx_word32_t sum; + + __asm__ __volatile__ + ( + "P0 = %2;\n\t" /* P0: coef[m], coef[m-1],..., coef[0] */ + "R4 = 8192;\n\t" /* R4: rounding constant */ + "R2 = %1;\n\t" /* R2: x */ + + "R5 = -16383;\n\t" + "R2 = MAX(R2,R5);\n\t" + "R5 = 16383;\n\t" + "R2 = MIN(R2,R5);\n\t" + + "R3 = W[P0--] (X);\n\t" /* R3: sum */ + "R5 = W[P0--] (X);\n\t" + "R5 = R5.L * R2.L (IS);\n\t" + "R5 = R5 + R4;\n\t" + "R5 >>>= 14;\n\t" + "R3 = R3 + R5;\n\t" + + "R0 = R2;\n\t" /* R0: b0 */ + "R1 = 16384;\n\t" /* R1: b1 */ + "LOOP cpe%= LC0 = %3;\n\t" + "LOOP_BEGIN cpe%=;\n\t" + "P1 = R0;\n\t" + "R0 = R2.L * R0.L (IS) || R5 = W[P0--] (X);\n\t" + "R0 >>>= 13;\n\t" + "R0 = R0 - R1;\n\t" + "R1 = P1;\n\t" + "R5 = R5.L * R0.L (IS);\n\t" + "R5 = R5 + R4;\n\t" + "R5 >>>= 14;\n\t" + "R3 = R3 + R5;\n\t" + "LOOP_END cpe%=;\n\t" + "%0 = R3;\n\t" + : "=&d" (sum) + : "a" (x), "a" (&coef[m]), "a" (m-1) + : "R0", "R1", "R3", "R2", "R4", "R5", "P0", "P1" + ); + return sum; +} +#endif + + + diff --git a/src/libs/speex/libspeex/lsp_tables_nb.c b/src/libs/speex/libspeex/lsp_tables_nb.c new file mode 100644 index 00000000..16f2e1b6 --- /dev/null +++ b/src/libs/speex/libspeex/lsp_tables_nb.c @@ -0,0 +1,360 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: lsp_tables_nb.c + Codebooks for LSPs in narrowband CELP mode + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +const signed char cdbk_nb[640]={ +30,19,38,34,40,32,46,43,58,43, +5,-18,-25,-40,-33,-55,-52,20,34,28, +-20,-63,-97,-92,61,53,47,49,53,75, +-14,-53,-77,-79,0,-3,-5,19,22,26, +-9,-53,-55,66,90,72,85,68,74,52, +-4,-41,-58,-31,-18,-31,27,32,30,18, +24,3,8,5,-12,-3,26,28,74,63, +-2,-39,-67,-77,-106,-74,59,59,73,65, +44,40,71,72,82,83,98,88,89,60, +-6,-31,-47,-48,-13,-39,-9,7,2,79, +-1,-39,-60,-17,87,81,65,50,45,19, +-21,-67,-91,-87,-41,-50,7,18,39,74, +10,-31,-28,39,24,13,23,5,56,45, +29,10,-5,-13,-11,-35,-18,-8,-10,-8, +-25,-71,-77,-21,2,16,50,63,87,87, +5,-32,-40,-51,-68,0,12,6,54,34, +5,-12,32,52,68,64,69,59,65,45, +14,-16,-31,-40,-65,-67,41,49,47,37, +-11,-52,-75,-84,-4,57,48,42,42,33, +-11,-51,-68,-6,13,0,8,-8,26,32, +-23,-53,0,36,56,76,97,105,111,97, +-1,-28,-39,-40,-43,-54,-44,-40,-18,35, +16,-20,-19,-28,-42,29,47,38,74,45, +3,-29,-48,-62,-80,-104,-33,56,59,59, +10,17,46,72,84,101,117,123,123,106, +-7,-33,-49,-51,-70,-67,-27,-31,70,67, +-16,-62,-85,-20,82,71,86,80,85,74, +-19,-58,-75,-45,-29,-33,-18,-25,45,57, +-12,-42,-5,12,28,36,52,64,81,82, +13,-9,-27,-28,22,3,2,22,26,6, +-6,-44,-51,2,15,10,48,43,49,34, +-19,-62,-84,-89,-102,-24,8,17,61,68, +39,24,23,19,16,-5,12,15,27,15, +-8,-44,-49,-60,-18,-32,-28,52,54,62, +-8,-48,-77,-70,66,101,83,63,61,37, +-12,-50,-75,-64,33,17,13,25,15,77, +1,-42,-29,72,64,46,49,31,61,44, +-8,-47,-54,-46,-30,19,20,-1,-16,0, +16,-12,-18,-9,-26,-27,-10,-22,53,45, +-10,-47,-75,-82,-105,-109,8,25,49,77, +50,65,114,117,124,118,115,96,90,61, +-9,-45,-63,-60,-75,-57,8,11,20,29, +0,-35,-49,-43,40,47,35,40,55,38, +-24,-76,-103,-112,-27,3,23,34,52,75, +8,-29,-43,12,63,38,35,29,24,8, +25,11,1,-15,-18,-43,-7,37,40,21, +-20,-56,-19,-19,-4,-2,11,29,51,63, +-2,-44,-62,-75,-89,30,57,51,74,51, +50,46,68,64,65,52,63,55,65,43, +18,-9,-26,-35,-55,-69,3,6,8,17, +-15,-61,-86,-97,1,86,93,74,78,67, +-1,-38,-66,-48,48,39,29,25,17,-1, +13,13,29,39,50,51,69,82,97,98, +-2,-36,-46,-27,-16,-30,-13,-4,-7,-4, +25,-5,-11,-6,-25,-21,33,12,31,29, +-8,-38,-52,-63,-68,-89,-33,-1,10,74, +-2,-15,59,91,105,105,101,87,84,62, +-7,-33,-50,-35,-54,-47,25,17,82,81, +-13,-56,-83,21,58,31,42,25,72,65, +-24,-66,-91,-56,9,-2,21,10,69,75, +2,-24,11,22,25,28,38,34,48,33, +7,-29,-26,17,15,-1,14,0,-2,0, +-6,-41,-67,6,-2,-9,19,2,85,74, +-22,-67,-84,-71,-50,3,11,-9,2,62}; + +const signed char cdbk_nb_low1[320]={ +-34,-52,-15,45,2, +23,21,52,24,-33, +-9,-1,9,-44,-41, +-13,-17,44,22,-17, +-6,-4,-1,22,38, +26,16,2,50,27, +-35,-34,-9,-41,6, +0,-16,-34,51,8, +-14,-31,-49,15,-33, +45,49,33,-11,-37, +-62,-54,45,11,-5, +-72,11,-1,-12,-11, +24,27,-11,-43,46, +43,33,-12,-9,-1, +1,-4,-23,-57,-71, +11,8,16,17,-8, +-20,-31,-41,53,48, +-16,3,65,-24,-8, +-23,-32,-37,-32,-49, +-10,-17,6,38,5, +-9,-17,-46,8,52, +3,6,45,40,39, +-7,-6,-34,-74,31, +8,1,-16,43,68, +-11,-19,-31,4,6, +0,-6,-17,-16,-38, +-16,-30,2,9,-39, +-16,-1,43,-10,48, +3,3,-16,-31,-3, +62,68,43,13,3, +-10,8,20,-56,12, +12,-2,-18,22,-15, +-40,-36,1,7,41, +0,1,46,-6,-62, +-4,-12,-2,-11,-83, +-13,-2,91,33,-10, +0,4,-11,-16,79, +32,37,14,9,51, +-21,-28,-56,-34,0, +21,9,-26,11,28, +-42,-54,-23,-2,-15, +31,30,8,-39,-66, +-39,-36,31,-28,-40, +-46,35,40,22,24, +33,48,23,-34,14, +40,32,17,27,-3, +25,26,-13,-61,-17, +11,4,31,60,-6, +-26,-41,-64,13,16, +-26,54,31,-11,-23, +-9,-11,-34,-71,-21, +-34,-35,55,50,29, +-22,-27,-50,-38,57, +33,42,57,48,26, +11,0,-49,-31,26, +-4,-14,5,78,37, +17,0,-49,-12,-23, +26,14,2,2,-43, +-17,-12,10,-8,-4, +8,18,12,-6,20, +-12,-6,-13,-25,34, +15,40,49,7,8, +13,20,20,-19,-22, +-2,-8,2,51,-51}; + +const signed char cdbk_nb_low2[320]={ +-6,53,-21,-24,4, +26,17,-4,-37,25, +17,-36,-13,31,3, +-6,27,15,-10,31, +28,26,-10,-10,-40, +16,-7,15,13,41, +-9,0,-4,50,-6, +-7,14,38,22,0, +-48,2,1,-13,-19, +32,-3,-60,11,-17, +-1,-24,-34,-1,35, +-5,-27,28,44,13, +25,15,42,-11,15, +51,35,-36,20,8, +-4,-12,-29,19,-47, +49,-15,-4,16,-29, +-39,14,-30,4,25, +-9,-5,-51,-14,-3, +-40,-32,38,5,-9, +-8,-4,-1,-22,71, +-3,14,26,-18,-22, +24,-41,-25,-24,6, +23,19,-10,39,-26, +-27,65,45,2,-7, +-26,-8,22,-12,16, +15,16,-35,-5,33, +-21,-8,0,23,33, +34,6,21,36,6, +-7,-22,8,-37,-14, +31,38,11,-4,-3, +-39,-32,-8,32,-23, +-6,-12,16,20,-28, +-4,23,13,-52,-1, +22,6,-33,-40,-6, +4,-62,13,5,-26, +35,39,11,2,57, +-11,9,-20,-28,-33, +52,-5,-6,-2,22, +-14,-16,-48,35,1, +-58,20,13,33,-1, +-74,56,-18,-22,-31, +12,6,-14,4,-2, +-9,-47,10,-3,29, +-17,-5,61,14,47, +-12,2,72,-39,-17, +92,64,-53,-51,-15, +-30,-38,-41,-29,-28, +27,9,36,9,-35, +-42,81,-21,20,25, +-16,-5,-17,-35,21, +15,-28,48,2,-2, +9,-19,29,-40,30, +-18,-18,18,-16,-57, +15,-20,-12,-15,-37, +-15,33,-39,21,-22, +-13,35,11,13,-38, +-63,29,23,-27,32, +18,3,-26,42,33, +-64,-66,-17,16,56, +2,36,3,31,21, +-41,-39,8,-57,14, +37,-2,19,-36,-19, +-23,-29,-16,1,-3, +-8,-10,31,64,-65}; + +const signed char cdbk_nb_high1[320]={ +-26,-8,29,21,4, +19,-39,33,-7,-36, +56,54,48,40,29, +-4,-24,-42,-66,-43, +-60,19,-2,37,41, +-10,-37,-60,-64,18, +-22,77,73,40,25, +4,19,-19,-66,-2, +11,5,21,14,26, +-25,-86,-4,18,1, +26,-37,10,37,-1, +24,-12,-59,-11,20, +-6,34,-16,-16,42, +19,-28,-51,53,32, +4,10,62,21,-12, +-34,27,4,-48,-48, +-50,-49,31,-7,-21, +-42,-25,-4,-43,-22, +59,2,27,12,-9, +-6,-16,-8,-32,-58, +-16,-29,-5,41,23, +-30,-33,-46,-13,-10, +-38,52,52,1,-17, +-9,10,26,-25,-6, +33,-20,53,55,25, +-32,-5,-42,23,21, +66,5,-28,20,9, +75,29,-7,-42,-39, +15,3,-23,21,6, +11,1,-29,14,63, +10,54,26,-24,-51, +-49,7,-23,-51,15, +-66,1,60,25,10, +0,-30,-4,-15,17, +19,59,40,4,-5, +33,6,-22,-58,-70, +-5,23,-6,60,44, +-29,-16,-47,-29,52, +-19,50,28,16,35, +31,36,0,-21,6, +21,27,22,42,7, +-66,-40,-8,7,19, +46,0,-4,60,36, +45,-7,-29,-6,-32, +-39,2,6,-9,33, +20,-51,-34,18,-6, +19,6,11,5,-19, +-29,-2,42,-11,-45, +-21,-55,57,37,2, +-14,-67,-16,-27,-38, +69,48,19,2,-17, +20,-20,-16,-34,-17, +-25,-61,10,73,45, +16,-40,-64,-17,-29, +-22,56,17,-39,8, +-11,8,-25,-18,-13, +-19,8,54,57,36, +-17,-26,-4,6,-21, +40,42,-4,20,31, +53,10,-34,-53,31, +-17,35,0,15,-6, +-20,-63,-73,22,25, +29,17,8,-29,-39, +-69,18,15,-15,-5}; + +const signed char cdbk_nb_high2[320]={ +11,47,16,-9,-46, +-32,26,-64,34,-5, +38,-7,47,20,2, +-73,-99,-3,-45,20, +70,-52,15,-6,-7, +-82,31,21,47,51, +39,-3,9,0,-41, +-7,-15,-54,2,0, +27,-31,9,-45,-22, +-38,-24,-24,8,-33, +23,5,50,-36,-17, +-18,-51,-2,13,19, +43,12,-15,-12,61, +38,38,7,13,0, +6,-1,3,62,9, +27,22,-33,38,-35, +-9,30,-43,-9,-32, +-1,4,-4,1,-5, +-11,-8,38,31,11, +-10,-42,-21,-37,1, +43,15,-13,-35,-19, +-18,15,23,-26,59, +1,-21,53,8,-41, +-50,-14,-28,4,21, +25,-28,-40,5,-40, +-41,4,51,-33,-8, +-8,1,17,-60,12, +25,-41,17,34,43, +19,45,7,-37,24, +-15,56,-2,35,-10, +48,4,-47,-2,5, +-5,-54,5,-3,-33, +-10,30,-2,-44,-24, +-38,9,-9,42,4, +6,-56,44,-16,9, +-40,-26,18,-20,10, +28,-41,-21,-4,13, +-18,32,-30,-3,37, +15,22,28,50,-40, +3,-29,-64,7,51, +-19,-11,17,-27,-40, +-64,24,-12,-7,-27, +3,37,48,-1,2, +-9,-38,-34,46,1, +27,-6,19,-13,26, +10,34,20,25,40, +50,-6,-7,30,9, +-24,0,-23,71,-61, +22,58,-34,-4,2, +-49,-33,25,30,-8, +-6,-16,77,2,38, +-8,-35,-6,-30,56, +78,31,33,-20,13, +-39,20,22,4,21, +-8,4,-6,10,-83, +-41,9,-25,-43,15, +-7,-12,-34,-39,-37, +-33,19,30,16,-33, +42,-25,25,-68,44, +-15,-11,-4,23,50, +14,4,-39,-43,20, +-30,60,9,-20,7, +16,19,-33,37,29, +16,-35,7,38,-27}; diff --git a/src/libs/speex/libspeex/ltp.c b/src/libs/speex/libspeex/ltp.c new file mode 100644 index 00000000..0129c95f --- /dev/null +++ b/src/libs/speex/libspeex/ltp.c @@ -0,0 +1,839 @@ +/* Copyright (C) 2002-2006 Jean-Marc Valin + File: ltp.c + Long-Term Prediction functions + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <math.h> +#include "ltp.h" +#include "stack_alloc.h" +#include "filters.h" +#include <speex/speex_bits.h> +#include "math_approx.h" +#include "os_support.h" + +#ifndef NULL +#define NULL 0 +#endif + + +#ifdef _USE_SSE +#include "ltp_sse.h" +#elif defined (ARM4_ASM) || defined(ARM5E_ASM) +#include "ltp_arm4.h" +#elif defined (BFIN_ASM) +#include "ltp_bfin.h" +#endif + +#ifndef OVERRIDE_INNER_PROD +spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) +{ + spx_word32_t sum=0; + len >>= 2; + while(len--) + { + spx_word32_t part=0; + part = MAC16_16(part,*x++,*y++); + part = MAC16_16(part,*x++,*y++); + part = MAC16_16(part,*x++,*y++); + part = MAC16_16(part,*x++,*y++); + /* HINT: If you had a 40-bit accumulator, you could shift only at the end */ + sum = ADD32(sum,SHR32(part,6)); + } + return sum; +} +#endif + +#ifndef OVERRIDE_PITCH_XCORR +#if 0 /* HINT: Enable this for machines with enough registers (i.e. not x86) */ +void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack) +{ + int i,j; + for (i=0;i<nb_pitch;i+=4) + { + /* Compute correlation*/ + /*corr[nb_pitch-1-i]=inner_prod(x, _y+i, len);*/ + spx_word32_t sum1=0; + spx_word32_t sum2=0; + spx_word32_t sum3=0; + spx_word32_t sum4=0; + const spx_word16_t *y = _y+i; + const spx_word16_t *x = _x; + spx_word16_t y0, y1, y2, y3; + /*y0=y[0];y1=y[1];y2=y[2];y3=y[3];*/ + y0=*y++; + y1=*y++; + y2=*y++; + y3=*y++; + for (j=0;j<len;j+=4) + { + spx_word32_t part1; + spx_word32_t part2; + spx_word32_t part3; + spx_word32_t part4; + part1 = MULT16_16(*x,y0); + part2 = MULT16_16(*x,y1); + part3 = MULT16_16(*x,y2); + part4 = MULT16_16(*x,y3); + x++; + y0=*y++; + part1 = MAC16_16(part1,*x,y1); + part2 = MAC16_16(part2,*x,y2); + part3 = MAC16_16(part3,*x,y3); + part4 = MAC16_16(part4,*x,y0); + x++; + y1=*y++; + part1 = MAC16_16(part1,*x,y2); + part2 = MAC16_16(part2,*x,y3); + part3 = MAC16_16(part3,*x,y0); + part4 = MAC16_16(part4,*x,y1); + x++; + y2=*y++; + part1 = MAC16_16(part1,*x,y3); + part2 = MAC16_16(part2,*x,y0); + part3 = MAC16_16(part3,*x,y1); + part4 = MAC16_16(part4,*x,y2); + x++; + y3=*y++; + + sum1 = ADD32(sum1,SHR32(part1,6)); + sum2 = ADD32(sum2,SHR32(part2,6)); + sum3 = ADD32(sum3,SHR32(part3,6)); + sum4 = ADD32(sum4,SHR32(part4,6)); + } + corr[nb_pitch-1-i]=sum1; + corr[nb_pitch-2-i]=sum2; + corr[nb_pitch-3-i]=sum3; + corr[nb_pitch-4-i]=sum4; + } + +} +#else +void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack) +{ + int i; + for (i=0;i<nb_pitch;i++) + { + /* Compute correlation*/ + corr[nb_pitch-1-i]=inner_prod(_x, _y+i, len); + } + +} +#endif +#endif + +#ifndef OVERRIDE_COMPUTE_PITCH_ERROR +static inline spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control) +{ + spx_word32_t sum = 0; + sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0])); + sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1])); + sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2])); + sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3])); + sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4])); + sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5])); + sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6])); + sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7])); + sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8])); + return sum; +} +#endif + +#ifndef OVERRIDE_OPEN_LOOP_NBEST_PITCH +void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack) +{ + int i,j,k; + VARDECL(spx_word32_t *best_score); + VARDECL(spx_word32_t *best_ener); + spx_word32_t e0; + VARDECL(spx_word32_t *corr); +#ifdef FIXED_POINT + /* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16) + arrays for (normalized) 16-bit values */ + VARDECL(spx_word16_t *corr16); + VARDECL(spx_word16_t *ener16); + spx_word32_t *energy; + int cshift=0, eshift=0; + int scaledown = 0; + ALLOC(corr16, end-start+1, spx_word16_t); + ALLOC(ener16, end-start+1, spx_word16_t); + ALLOC(corr, end-start+1, spx_word32_t); + energy = corr; +#else + /* In floating-point, we need to float arrays and no normalized copies */ + VARDECL(spx_word32_t *energy); + spx_word16_t *corr16; + spx_word16_t *ener16; + ALLOC(energy, end-start+2, spx_word32_t); + ALLOC(corr, end-start+1, spx_word32_t); + corr16 = corr; + ener16 = energy; +#endif + + ALLOC(best_score, N, spx_word32_t); + ALLOC(best_ener, N, spx_word32_t); + for (i=0;i<N;i++) + { + best_score[i]=-1; + best_ener[i]=0; + pitch[i]=start; + } + +#ifdef FIXED_POINT + for (i=-end;i<len;i++) + { + if (ABS16(sw[i])>16383) + { + scaledown=1; + break; + } + } + /* If the weighted input is close to saturation, then we scale it down */ + if (scaledown) + { + for (i=-end;i<len;i++) + { + sw[i]=SHR16(sw[i],1); + } + } +#endif + energy[0]=inner_prod(sw-start, sw-start, len); + e0=inner_prod(sw, sw, len); + for (i=start;i<end;i++) + { + /* Update energy for next pitch*/ + energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(sw[-i-1],sw[-i-1]),6)), SHR32(MULT16_16(sw[-i+len-1],sw[-i+len-1]),6)); + if (energy[i-start+1] < 0) + energy[i-start+1] = 0; + } + +#ifdef FIXED_POINT + eshift = normalize16(energy, ener16, 32766, end-start+1); +#endif + + /* In fixed-point, this actually overrites the energy array (aliased to corr) */ + pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack); + +#ifdef FIXED_POINT + /* Normalize to 180 so we can square it and it still fits in 16 bits */ + cshift = normalize16(corr, corr16, 180, end-start+1); + /* If we scaled weighted input down, we need to scale it up again (OK, so we've just lost the LSB, who cares?) */ + if (scaledown) + { + for (i=-end;i<len;i++) + { + sw[i]=SHL16(sw[i],1); + } + } +#endif + + /* Search for the best pitch prediction gain */ + for (i=start;i<=end;i++) + { + spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]); + /* Instead of dividing the tmp by the energy, we multiply on the other side */ + if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start]))) + { + /* We can safely put it last and then check */ + best_score[N-1]=tmp; + best_ener[N-1]=ener16[i-start]+1; + pitch[N-1]=i; + /* Check if it comes in front of others */ + for (j=0;j<N-1;j++) + { + if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start]))) + { + for (k=N-1;k>j;k--) + { + best_score[k]=best_score[k-1]; + best_ener[k]=best_ener[k-1]; + pitch[k]=pitch[k-1]; + } + best_score[j]=tmp; + best_ener[j]=ener16[i-start]+1; + pitch[j]=i; + break; + } + } + } + } + + /* Compute open-loop gain if necessary */ + if (gain) + { + for (j=0;j<N;j++) + { + spx_word16_t g; + i=pitch[j]; + g = DIV32(SHL32(EXTEND32(corr16[i-start]),cshift), 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(SHL32(EXTEND32(ener16[i-start]),eshift))),6)); + /* FIXME: g = max(g,corr/energy) */ + if (g<0) + g = 0; + gain[j]=g; + } + } + + +} +#endif + +#ifndef OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ +static int pitch_gain_search_3tap_vq( + const signed char *gain_cdbk, + int gain_cdbk_size, + spx_word16_t *C16, + spx_word16_t max_gain +) +{ + const signed char *ptr=gain_cdbk; + int best_cdbk=0; + spx_word32_t best_sum=-VERY_LARGE32; + spx_word32_t sum=0; + spx_word16_t g[3]; + spx_word16_t pitch_control=64; + spx_word16_t gain_sum; + int i; + + for (i=0;i<gain_cdbk_size;i++) { + + ptr = gain_cdbk+4*i; + g[0]=ADD16((spx_word16_t)ptr[0],32); + g[1]=ADD16((spx_word16_t)ptr[1],32); + g[2]=ADD16((spx_word16_t)ptr[2],32); + gain_sum = (spx_word16_t)ptr[3]; + + sum = compute_pitch_error(C16, g, pitch_control); + + if (sum>best_sum && gain_sum<=max_gain) { + best_sum=sum; + best_cdbk=i; + } + } + + return best_cdbk; +} +#endif + +/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ +static spx_word32_t pitch_gain_search_3tap( +const spx_word16_t target[], /* Target vector */ +const spx_coef_t ak[], /* LPCs for this subframe */ +const spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ +const spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ +spx_sig_t exc[], /* Excitation */ +const signed char *gain_cdbk, +int gain_cdbk_size, +int pitch, /* Pitch value */ +int p, /* Number of LPC coeffs */ +int nsf, /* Number of samples in subframe */ +SpeexBits *bits, +char *stack, +const spx_word16_t *exc2, +const spx_word16_t *r, +spx_word16_t *new_target, +int *cdbk_index, +int plc_tuning, +spx_word32_t cumul_gain, +int scaledown +) +{ + int i,j; + VARDECL(spx_word16_t *tmp1); + VARDECL(spx_word16_t *e); + spx_word16_t *x[3]; + spx_word32_t corr[3]; + spx_word32_t A[3][3]; + spx_word16_t gain[3]; + spx_word32_t err; + spx_word16_t max_gain=128; + int best_cdbk=0; + + ALLOC(tmp1, 3*nsf, spx_word16_t); + ALLOC(e, nsf, spx_word16_t); + + if (cumul_gain > 262144) + max_gain = 31; + + x[0]=tmp1; + x[1]=tmp1+nsf; + x[2]=tmp1+2*nsf; + + for (j=0;j<nsf;j++) + new_target[j] = target[j]; + + { + VARDECL(spx_mem_t *mm); + int pp=pitch-1; + ALLOC(mm, p, spx_mem_t); + for (j=0;j<nsf;j++) + { + if (j-pp<0) + e[j]=exc2[j-pp]; + else if (j-pp-pitch<0) + e[j]=exc2[j-pp-pitch]; + else + e[j]=0; + } +#ifdef FIXED_POINT + /* Scale target and excitation down if needed (avoiding overflow) */ + if (scaledown) + { + for (j=0;j<nsf;j++) + e[j] = SHR16(e[j],1); + for (j=0;j<nsf;j++) + new_target[j] = SHR16(new_target[j],1); + } +#endif + for (j=0;j<p;j++) + mm[j] = 0; + iir_mem16(e, ak, e, nsf, p, mm, stack); + for (j=0;j<p;j++) + mm[j] = 0; + filter_mem16(e, awk1, awk2, e, nsf, p, mm, stack); + for (j=0;j<nsf;j++) + x[2][j] = e[j]; + } + for (i=1;i>=0;i--) + { + spx_word16_t e0=exc2[-pitch-1+i]; +#ifdef FIXED_POINT + /* Scale excitation down if needed (avoiding overflow) */ + if (scaledown) + e0 = SHR16(e0,1); +#endif + x[i][0]=MULT16_16_Q14(r[0], e0); + for (j=0;j<nsf-1;j++) + x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0)); + } + + for (i=0;i<3;i++) + corr[i]=inner_prod(x[i],new_target,nsf); + for (i=0;i<3;i++) + for (j=0;j<=i;j++) + A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf); + + { + spx_word32_t C[9]; +#ifdef FIXED_POINT + spx_word16_t C16[9]; +#else + spx_word16_t *C16=C; +#endif + C[0]=corr[2]; + C[1]=corr[1]; + C[2]=corr[0]; + C[3]=A[1][2]; + C[4]=A[0][1]; + C[5]=A[0][2]; + C[6]=A[2][2]; + C[7]=A[1][1]; + C[8]=A[0][0]; + + /*plc_tuning *= 2;*/ + if (plc_tuning<2) + plc_tuning=2; + if (plc_tuning>30) + plc_tuning=30; +#ifdef FIXED_POINT + C[0] = SHL32(C[0],1); + C[1] = SHL32(C[1],1); + C[2] = SHL32(C[2],1); + C[3] = SHL32(C[3],1); + C[4] = SHL32(C[4],1); + C[5] = SHL32(C[5],1); + C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]); + C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]); + C[8] = MAC16_32_Q15(C[8],MULT16_16_16(plc_tuning,655),C[8]); + normalize16(C, C16, 32767, 9); +#else + C[6]*=.5*(1+.02*plc_tuning); + C[7]*=.5*(1+.02*plc_tuning); + C[8]*=.5*(1+.02*plc_tuning); +#endif + + best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain); + +#ifdef FIXED_POINT + gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]); + gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]); + gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+2]); + /*printf ("%d %d %d %d\n",gain[0],gain[1],gain[2], best_cdbk);*/ +#else + gain[0] = 0.015625*gain_cdbk[best_cdbk*4] + .5; + gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5; + gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5; +#endif + *cdbk_index=best_cdbk; + } + + SPEEX_MEMSET(exc, 0, nsf); + for (i=0;i<3;i++) + { + int j; + int tmp1, tmp3; + int pp=pitch+1-i; + tmp1=nsf; + if (tmp1>pp) + tmp1=pp; + for (j=0;j<tmp1;j++) + exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]); + tmp3=nsf; + if (tmp3>pp+pitch) + tmp3=pp+pitch; + for (j=tmp1;j<tmp3;j++) + exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]); + } + for (i=0;i<nsf;i++) + { + spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])), + MULT16_16(gain[2],x[0][i])); + new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6))); + } + err = inner_prod(new_target, new_target, nsf); + + return err; +} + +/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ +int pitch_search_3tap( +spx_word16_t target[], /* Target vector */ +spx_word16_t *sw, +spx_coef_t ak[], /* LPCs for this subframe */ +spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ +spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ +spx_sig_t exc[], /* Excitation */ +const void *par, +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ +int p, /* Number of LPC coeffs */ +int nsf, /* Number of samples in subframe */ +SpeexBits *bits, +char *stack, +spx_word16_t *exc2, +spx_word16_t *r, +int complexity, +int cdbk_offset, +int plc_tuning, +spx_word32_t *cumul_gain +) +{ + int i; + int cdbk_index, pitch=0, best_gain_index=0; + VARDECL(spx_sig_t *best_exc); + VARDECL(spx_word16_t *new_target); + VARDECL(spx_word16_t *best_target); + int best_pitch=0; + spx_word32_t err, best_err=-1; + int N; + const ltp_params *params; + const signed char *gain_cdbk; + int gain_cdbk_size; + int scaledown=0; + + VARDECL(int *nbest); + + params = (const ltp_params*) par; + gain_cdbk_size = 1<<params->gain_bits; + gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; + + N=complexity; + if (N>10) + N=10; + if (N<1) + N=1; + + ALLOC(nbest, N, int); + params = (const ltp_params*) par; + + if (end<start) + { + speex_bits_pack(bits, 0, params->pitch_bits); + speex_bits_pack(bits, 0, params->gain_bits); + SPEEX_MEMSET(exc, 0, nsf); + return start; + } + +#ifdef FIXED_POINT + /* Check if we need to scale everything down in the pitch search to avoid overflows */ + for (i=0;i<nsf;i++) + { + if (ABS16(target[i])>16383) + { + scaledown=1; + break; + } + } + for (i=-end;i<nsf;i++) + { + if (ABS16(exc2[i])>16383) + { + scaledown=1; + break; + } + } +#endif + if (N>end-start+1) + N=end-start+1; + if (end != start) + open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack); + else + nbest[0] = start; + + ALLOC(best_exc, nsf, spx_sig_t); + ALLOC(new_target, nsf, spx_word16_t); + ALLOC(best_target, nsf, spx_word16_t); + + for (i=0;i<N;i++) + { + pitch=nbest[i]; + SPEEX_MEMSET(exc, 0, nsf); + err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf, + bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown); + if (err<best_err || best_err<0) + { + SPEEX_COPY(best_exc, exc, nsf); + SPEEX_COPY(best_target, new_target, nsf); + best_err=err; + best_pitch=pitch; + best_gain_index=cdbk_index; + } + } + /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/ + speex_bits_pack(bits, best_pitch-start, params->pitch_bits); + speex_bits_pack(bits, best_gain_index, params->gain_bits); +#ifdef FIXED_POINT + *cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4*best_gain_index+3],8), MAX32(1024,*cumul_gain)); +#else + *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3]; +#endif + /*printf ("%f\n", cumul_gain);*/ + /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/ + SPEEX_COPY(exc, best_exc, nsf); + SPEEX_COPY(target, best_target, nsf); +#ifdef FIXED_POINT + /* Scale target back up if needed */ + if (scaledown) + { + for (i=0;i<nsf;i++) + target[i]=SHL16(target[i],1); + } +#endif + return pitch; +} + +void pitch_unquant_3tap( +spx_word16_t exc[], /* Input excitation */ +spx_word32_t exc_out[], /* Output excitation */ +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ +const void *par, +int nsf, /* Number of samples in subframe */ +int *pitch_val, +spx_word16_t *gain_val, +SpeexBits *bits, +char *stack, +int count_lost, +int subframe_offset, +spx_word16_t last_pitch_gain, +int cdbk_offset +) +{ + int i; + int pitch; + int gain_index; + spx_word16_t gain[3]; + const signed char *gain_cdbk; + int gain_cdbk_size; + const ltp_params *params; + + params = (const ltp_params*) par; + gain_cdbk_size = 1<<params->gain_bits; + gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; + + pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); + pitch += start; + gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits); + /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/ +#ifdef FIXED_POINT + gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]); + gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]); + gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+2]); +#else + gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5; + gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5; + gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5; +#endif + + if (count_lost && pitch > subframe_offset) + { + spx_word16_t gain_sum; + if (1) { +#ifdef FIXED_POINT + spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain,1); + if (tmp>62) + tmp=62; +#else + spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain; + if (tmp>.95) + tmp=.95; +#endif + gain_sum = gain_3tap_to_1tap(gain); + + if (gain_sum > tmp) + { + spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp),14),gain_sum); + for (i=0;i<3;i++) + gain[i]=MULT16_16_Q14(fact,gain[i]); + } + + } + + } + + *pitch_val = pitch; + gain_val[0]=gain[0]; + gain_val[1]=gain[1]; + gain_val[2]=gain[2]; + gain[0] = SHL16(gain[0],7); + gain[1] = SHL16(gain[1],7); + gain[2] = SHL16(gain[2],7); + SPEEX_MEMSET(exc_out, 0, nsf); + for (i=0;i<3;i++) + { + int j; + int tmp1, tmp3; + int pp=pitch+1-i; + tmp1=nsf; + if (tmp1>pp) + tmp1=pp; + for (j=0;j<tmp1;j++) + exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]); + tmp3=nsf; + if (tmp3>pp+pitch) + tmp3=pp+pitch; + for (j=tmp1;j<tmp3;j++) + exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]); + } + /*for (i=0;i<nsf;i++) + exc[i]=PSHR32(exc32[i],13);*/ +} + + +/** Forced pitch delay and gain */ +int forced_pitch_quant( +spx_word16_t target[], /* Target vector */ +spx_word16_t *sw, +spx_coef_t ak[], /* LPCs for this subframe */ +spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ +spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ +spx_sig_t exc[], /* Excitation */ +const void *par, +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ +int p, /* Number of LPC coeffs */ +int nsf, /* Number of samples in subframe */ +SpeexBits *bits, +char *stack, +spx_word16_t *exc2, +spx_word16_t *r, +int complexity, +int cdbk_offset, +int plc_tuning, +spx_word32_t *cumul_gain +) +{ + int i; + VARDECL(spx_word16_t *res); + ALLOC(res, nsf, spx_word16_t); +#ifdef FIXED_POINT + if (pitch_coef>63) + pitch_coef=63; +#else + if (pitch_coef>.99) + pitch_coef=.99; +#endif + for (i=0;i<nsf&&i<start;i++) + { + exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]); + } + for (;i<nsf;i++) + { + exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]); + } + for (i=0;i<nsf;i++) + res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1)); + syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack); + for (i=0;i<nsf;i++) + target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700)); + return start; +} + +/** Unquantize forced pitch delay and gain */ +void forced_pitch_unquant( +spx_word16_t exc[], /* Input excitation */ +spx_word32_t exc_out[], /* Output excitation */ +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ +const void *par, +int nsf, /* Number of samples in subframe */ +int *pitch_val, +spx_word16_t *gain_val, +SpeexBits *bits, +char *stack, +int count_lost, +int subframe_offset, +spx_word16_t last_pitch_gain, +int cdbk_offset +) +{ + int i; +#ifdef FIXED_POINT + if (pitch_coef>63) + pitch_coef=63; +#else + if (pitch_coef>.99) + pitch_coef=.99; +#endif + for (i=0;i<nsf;i++) + { + exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7)); + exc[i] = EXTRACT16(PSHR32(exc_out[i],13)); + } + *pitch_val = start; + gain_val[0]=gain_val[2]=0; + gain_val[1] = pitch_coef; +} diff --git a/src/libs/speex/libspeex/ltp.h b/src/libs/speex/libspeex/ltp.h new file mode 100644 index 00000000..1e435bc3 --- /dev/null +++ b/src/libs/speex/libspeex/ltp.h @@ -0,0 +1,141 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file ltp.h + @brief Long-Term Prediction functions +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <speex/speex_bits.h> +#include "arch.h" + +/** LTP parameters. */ +typedef struct { + const signed char *gain_cdbk; + int gain_bits; + int pitch_bits; +} ltp_params; + +#ifdef FIXED_POINT +#define gain_3tap_to_1tap(g) (ABS(g[1]) + (g[0]>0 ? g[0] : -SHR16(g[0],1)) + (g[2]>0 ? g[2] : -SHR16(g[2],1))) +#else +#define gain_3tap_to_1tap(g) (ABS(g[1]) + (g[0]>0 ? g[0] : -.5*g[0]) + (g[2]>0 ? g[2] : -.5*g[2])) +#endif + +spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len); +void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack); + +void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack); + + +/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ +int pitch_search_3tap( +spx_word16_t target[], /* Target vector */ +spx_word16_t *sw, +spx_coef_t ak[], /* LPCs for this subframe */ +spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ +spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ +spx_sig_t exc[], /* Overlapping codebook */ +const void *par, +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ +int p, /* Number of LPC coeffs */ +int nsf, /* Number of samples in subframe */ +SpeexBits *bits, +char *stack, +spx_word16_t *exc2, +spx_word16_t *r, +int complexity, +int cdbk_offset, +int plc_tuning, +spx_word32_t *cumul_gain +); + +/*Unquantize adaptive codebook and update pitch contribution*/ +void pitch_unquant_3tap( +spx_word16_t exc[], /* Input excitation */ +spx_word32_t exc_out[], /* Output excitation */ +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ +const void *par, +int nsf, /* Number of samples in subframe */ +int *pitch_val, +spx_word16_t *gain_val, +SpeexBits *bits, +char *stack, +int lost, +int subframe_offset, +spx_word16_t last_pitch_gain, +int cdbk_offset +); + +/** Forced pitch delay and gain */ +int forced_pitch_quant( +spx_word16_t target[], /* Target vector */ +spx_word16_t *sw, +spx_coef_t ak[], /* LPCs for this subframe */ +spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ +spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ +spx_sig_t exc[], /* Excitation */ +const void *par, +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ +int p, /* Number of LPC coeffs */ +int nsf, /* Number of samples in subframe */ +SpeexBits *bits, +char *stack, +spx_word16_t *exc2, +spx_word16_t *r, +int complexity, +int cdbk_offset, +int plc_tuning, +spx_word32_t *cumul_gain +); + +/** Unquantize forced pitch delay and gain */ +void forced_pitch_unquant( +spx_word16_t exc[], /* Input excitation */ +spx_word32_t exc_out[], /* Output excitation */ +int start, /* Smallest pitch value allowed */ +int end, /* Largest pitch value allowed */ +spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ +const void *par, +int nsf, /* Number of samples in subframe */ +int *pitch_val, +spx_word16_t *gain_val, +SpeexBits *bits, +char *stack, +int lost, +int subframe_offset, +spx_word16_t last_pitch_gain, +int cdbk_offset +); diff --git a/src/libs/speex/libspeex/ltp_arm4.h b/src/libs/speex/libspeex/ltp_arm4.h new file mode 100644 index 00000000..cdb94e60 --- /dev/null +++ b/src/libs/speex/libspeex/ltp_arm4.h @@ -0,0 +1,187 @@ +/* Copyright (C) 2004 Jean-Marc Valin */ +/** + @file ltp_arm4.h + @brief Long-Term Prediction functions (ARM4 version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define OVERRIDE_INNER_PROD +spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) +{ + spx_word32_t sum1=0,sum2=0; + spx_word16_t *deadx, *deady; + int deadlen, dead1, dead2, dead3, dead4, dead5, dead6; + __asm__ __volatile__ ( + "\tldrsh %5, [%0], #2 \n" + "\tldrsh %6, [%1], #2 \n" + ".inner_prod_loop%=:\n" + "\tsub %7, %7, %7\n" + "\tsub %10, %10, %10\n" + + "\tldrsh %8, [%0], #2 \n" + "\tldrsh %9, [%1], #2 \n" + "\tmla %7, %5, %6, %7\n" + "\tldrsh %5, [%0], #2 \n" + "\tldrsh %6, [%1], #2 \n" + "\tmla %10, %8, %9, %10\n" + "\tldrsh %8, [%0], #2 \n" + "\tldrsh %9, [%1], #2 \n" + "\tmla %7, %5, %6, %7\n" + "\tldrsh %5, [%0], #2 \n" + "\tldrsh %6, [%1], #2 \n" + "\tmla %10, %8, %9, %10\n" + + "\tldrsh %8, [%0], #2 \n" + "\tldrsh %9, [%1], #2 \n" + "\tmla %7, %5, %6, %7\n" + "\tldrsh %5, [%0], #2 \n" + "\tldrsh %6, [%1], #2 \n" + "\tmla %10, %8, %9, %10\n" + "\tldrsh %8, [%0], #2 \n" + "\tldrsh %9, [%1], #2 \n" + "\tmla %7, %5, %6, %7\n" + "\tldrsh %5, [%0], #2 \n" + "\tldrsh %6, [%1], #2 \n" + "\tmla %10, %8, %9, %10\n" + + "\tsubs %4, %4, #1\n" + "\tadd %2, %2, %7, asr #5\n" + "\tadd %3, %3, %10, asr #5\n" + "\tbne .inner_prod_loop%=\n" + : "=r" (deadx), "=r" (deady), "+r" (sum1), "+r" (sum2), + "=r" (deadlen), "=r" (dead1), "=r" (dead2), "=r" (dead3), + "=r" (dead4), "=r" (dead5), "=r" (dead6) + : "0" (x), "1" (y), "4" (len>>3) + : "cc" + ); + return (sum1+sum2)>>1; +} + +#define OVERRIDE_PITCH_XCORR +void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack) +{ + int i,j; + for (i=0;i<nb_pitch;i+=4) + { + /* Compute correlation*/ + //corr[nb_pitch-1-i]=inner_prod(x, _y+i, len); + spx_word32_t sum1=0; + spx_word32_t sum2=0; + spx_word32_t sum3=0; + spx_word32_t sum4=0; + const spx_word16_t *y = _y+i; + const spx_word16_t *x = _x; + spx_word32_t y0, y1, y2, y3; + y0=*y++; + y1=*y++; + y2=*y++; + y3=*y++; + for (j=0;j<len;j+=4) + { + spx_word32_t part1, part2, part3, part4, x0; + spx_word32_t dead1; + __asm__ __volatile__ ( +#ifdef SHORTCUTS + "\tldrsh %10, [%8], #4 \n" + "\tmul %4, %10, %0 \n" + "\tldrsh %15, [%8], #4 \n" + "\tmul %5, %10, %1 \n" + "\tldrsh %0, [%9], #2 \n" + "\tmul %6, %10, %2 \n" + "\tldrsh %1, [%9], #2 \n" + "\tmul %7, %10, %3 \n" + + + "\tmla %4, %15, %2, %4 \n" + "\tldrsh %2, [%9], #2 \n" + "\tmla %5, %15, %3, %5 \n" + "\tldrsh %3, [%9], #2 \n" + "\tmla %6, %15, %0, %6 \n" + "\tmla %7, %15, %1, %7 \n" + +#else + "\tldrsh %10, [%8], #2 \n" + "\tmul %4, %10, %0 \n" + "\tmul %5, %10, %1 \n" + "\tmul %6, %10, %2 \n" + "\tmul %7, %10, %3 \n" + + "\tldrsh %10, [%8], #2 \n" + "\tldrsh %0, [%9], #2 \n" + "\tmla %4, %10, %1, %4 \n" + "\tmla %5, %10, %2, %5 \n" + "\tmla %6, %10, %3, %6 \n" + "\tmla %7, %10, %0, %7 \n" + + "\tldrsh %10, [%8], #2 \n" + "\tldrsh %1, [%9], #2 \n" + "\tmla %4, %10, %2, %4 \n" + "\tmla %5, %10, %3, %5 \n" + "\tmla %6, %10, %0, %6 \n" + "\tmla %7, %10, %1, %7 \n" + + "\tldrsh %10, [%8], #2 \n" + "\tldrsh %2, [%9], #2 \n" + "\tmla %4, %10, %3, %4 \n" + "\tmla %5, %10, %0, %5 \n" + "\tmla %6, %10, %1, %6 \n" + "\tmla %7, %10, %2, %7 \n" + + "\tldrsh %3, [%9], #2 \n" +#endif + + "\tldr %10, %11 \n" + "\tldr %15, %12 \n" + "\tadd %4, %10, %4, asr #6 \n" + "\tstr %4, %11 \n" + "\tldr %10, %13 \n" + "\tadd %5, %15, %5, asr #6 \n" + "\tstr %5, %12 \n" + "\tldr %15, %14 \n" + "\tadd %6, %10, %6, asr #6 \n" + "\tadd %7, %15, %7, asr #6 \n" + "\tstr %6, %13 \n" + "\tstr %7, %14 \n" + + : "+r" (y0), "+r" (y1), "+r" (y2), "+r" (y3), + "=r" (part1), "=r" (part2), "=r" (part3), "=r" (part4), + "+r" (x), "+r" (y), "=r" (x0), "+m" (sum1), + "+m" (sum2), "+m" (sum3), "+m" (sum4), "=r" (dead1) + : + : "cc", "memory" + ); + } + corr[nb_pitch-1-i]=sum1; + corr[nb_pitch-2-i]=sum2; + corr[nb_pitch-3-i]=sum3; + corr[nb_pitch-4-i]=sum4; + } + +} diff --git a/src/libs/speex/libspeex/ltp_bfin.h b/src/libs/speex/libspeex/ltp_bfin.h new file mode 100644 index 00000000..b530f859 --- /dev/null +++ b/src/libs/speex/libspeex/ltp_bfin.h @@ -0,0 +1,419 @@ +/* Copyright (C) 2005 Analog Devices */ +/** + @file ltp_bfin.h + @author Jean-Marc Valin + @brief Long-Term Prediction functions (Blackfin version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define OVERRIDE_INNER_PROD +spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) +{ + spx_word32_t sum=0; + __asm__ __volatile__ ( + "P0 = %3;\n\t" + "P1 = %1;\n\t" + "P2 = %2;\n\t" + "I0 = P1;\n\t" + "I1 = P2;\n\t" + "L0 = 0;\n\t" + "L1 = 0;\n\t" + "A0 = 0;\n\t" + "R0.L = W[I0++] || R1.L = W[I1++];\n\t" + "LOOP inner%= LC0 = P0;\n\t" + "LOOP_BEGIN inner%=;\n\t" + "A0 += R0.L*R1.L (IS) || R0.L = W[I0++] || R1.L = W[I1++];\n\t" + "LOOP_END inner%=;\n\t" + "A0 += R0.L*R1.L (IS);\n\t" + "A0 = A0 >>> 6;\n\t" + "R0 = A0;\n\t" + "%0 = R0;\n\t" + : "=m" (sum) + : "m" (x), "m" (y), "d" (len-1) + : "P0", "P1", "P2", "R0", "R1", "A0", "I0", "I1", "L0", "L1", "R3" + ); + return sum; +} + +#define OVERRIDE_PITCH_XCORR +void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack) +{ + corr += nb_pitch - 1; + __asm__ __volatile__ ( + "P2 = %0;\n\t" + "I0 = P2;\n\t" /* x in I0 */ + "B0 = P2;\n\t" /* x in B0 */ + "R0 = %3;\n\t" /* len in R0 */ + "P3 = %3;\n\t" + "P3 += -2;\n\t" /* len in R0 */ + "P4 = %4;\n\t" /* nb_pitch in R0 */ + "R1 = R0 << 1;\n\t" /* number of bytes in x */ + "L0 = R1;\n\t" + "P0 = %1;\n\t" + + "P1 = %2;\n\t" + "B1 = P1;\n\t" + "L1 = 0;\n\t" /*Disable looping on I1*/ + + "r0 = [I0++];\n\t" + "LOOP pitch%= LC0 = P4 >> 1;\n\t" + "LOOP_BEGIN pitch%=;\n\t" + "I1 = P0;\n\t" + "A1 = A0 = 0;\n\t" + "R1 = [I1++];\n\t" + "LOOP inner_prod%= LC1 = P3 >> 1;\n\t" + "LOOP_BEGIN inner_prod%=;\n\t" + "A1 += R0.L*R1.H, A0 += R0.L*R1.L (IS) || R1.L = W[I1++];\n\t" + "A1 += R0.H*R1.L, A0 += R0.H*R1.H (IS) || R1.H = W[I1++] || R0 = [I0++];\n\t" + "LOOP_END inner_prod%=;\n\t" + "A1 += R0.L*R1.H, A0 += R0.L*R1.L (IS) || R1.L = W[I1++];\n\t" + "A1 += R0.H*R1.L, A0 += R0.H*R1.H (IS) || R0 = [I0++];\n\t" + "A0 = A0 >>> 6;\n\t" + "A1 = A1 >>> 6;\n\t" + "R2 = A0, R3 = A1;\n\t" + "[P1--] = r2;\n\t" + "[P1--] = r3;\n\t" + "P0 += 4;\n\t" + "LOOP_END pitch%=;\n\t" + "L0 = 0;\n\t" + : : "m" (_x), "m" (_y), "m" (corr), "m" (len), "m" (nb_pitch) + : "A0", "A1", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "R3", "I0", "I1", "L0", "L1", "B0", "B1", "memory" + ); +} + +#define OVERRIDE_COMPUTE_PITCH_ERROR +static inline spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control) +{ + spx_word32_t sum; + __asm__ __volatile__ + ( + "A0 = 0;\n\t" + + "R0 = W[%1++];\n\t" + "R1.L = %2.L*%5.L (IS);\n\t" + "A0 += R1.L*R0.L (IS) || R0 = W[%1++];\n\t" + + "R1.L = %3.L*%5.L (IS);\n\t" + "A0 += R1.L*R0.L (IS) || R0 = W[%1++];\n\t" + + "R1.L = %4.L*%5.L (IS);\n\t" + "A0 += R1.L*R0.L (IS) || R0 = W[%1++];\n\t" + + "R1.L = %2.L*%3.L (IS);\n\t" + "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t" + + "R1.L = %4.L*%3.L (IS);\n\t" + "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t" + + "R1.L = %4.L*%2.L (IS);\n\t" + "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t" + + "R1.L = %2.L*%2.L (IS);\n\t" + "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t" + + "R1.L = %3.L*%3.L (IS);\n\t" + "A0 -= R1.L*R0.L (IS) || R0 = W[%1++];\n\t" + + "R1.L = %4.L*%4.L (IS);\n\t" + "A0 -= R1.L*R0.L (IS);\n\t" + + "%0 = A0;\n\t" + : "=&D" (sum), "=a" (C) + : "d" (g[0]), "d" (g[1]), "d" (g[2]), "d" (pitch_control), "1" (C) + : "R0", "R1", "R2", "A0" + ); + return sum; +} + +#define OVERRIDE_OPEN_LOOP_NBEST_PITCH +#ifdef OVERRIDE_OPEN_LOOP_NBEST_PITCH +void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack) +{ + int i,j,k; + VARDECL(spx_word32_t *best_score); + VARDECL(spx_word32_t *best_ener); + spx_word32_t e0; + VARDECL(spx_word32_t *corr); + VARDECL(spx_word32_t *energy); + + ALLOC(best_score, N, spx_word32_t); + ALLOC(best_ener, N, spx_word32_t); + ALLOC(corr, end-start+1, spx_word32_t); + ALLOC(energy, end-start+2, spx_word32_t); + + for (i=0;i<N;i++) + { + best_score[i]=-1; + best_ener[i]=0; + pitch[i]=start; + } + + energy[0]=inner_prod(sw-start, sw-start, len); + e0=inner_prod(sw, sw, len); + + /* energy update -------------------------------------*/ + + __asm__ __volatile__ + ( +" P0 = %0;\n\t" +" I1 = %1;\n\t" +" L1 = 0;\n\t" +" I2 = %2;\n\t" +" L2 = 0;\n\t" +" R2 = [P0++];\n\t" +" R3 = 0;\n\t" +" LSETUP (eu1, eu2) LC1 = %3;\n\t" +"eu1: R1.L = W [I1--] || R0.L = W [I2--] ;\n\t" +" R1 = R1.L * R1.L (IS);\n\t" +" R0 = R0.L * R0.L (IS);\n\t" +" R1 >>>= 6;\n\t" +" R1 = R1 + R2;\n\t" +" R0 >>>= 6;\n\t" +" R1 = R1 - R0;\n\t" +" R2 = MAX(R1,R3);\n\t" +"eu2: [P0++] = R2;\n\t" + : : "d" (energy), "d" (&sw[-start-1]), "d" (&sw[-start+len-1]), + "a" (end-start) + : "P0", "I1", "I2", "R0", "R1", "R2", "R3" +#if (__GNUC__ == 4) + , "LC1" +#endif + ); + + pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack); + + /* FIXME: Fixed-point and floating-point code should be merged */ + { + VARDECL(spx_word16_t *corr16); + VARDECL(spx_word16_t *ener16); + ALLOC(corr16, end-start+1, spx_word16_t); + ALLOC(ener16, end-start+1, spx_word16_t); + /* Normalize to 180 so we can square it and it still fits in 16 bits */ + normalize16(corr, corr16, 180, end-start+1); + normalize16(energy, ener16, 180, end-start+1); + + if (N == 1) { + /* optimised asm to handle N==1 case */ + __asm__ __volatile__ + ( +" I0 = %1;\n\t" /* I0: corr16[] */ +" L0 = 0;\n\t" +" I1 = %2;\n\t" /* I1: energy */ +" L1 = 0;\n\t" +" R2 = -1;\n\t" /* R2: best score */ +" R3 = 0;\n\t" /* R3: best energy */ +" P0 = %4;\n\t" /* P0: best pitch */ +" P1 = %4;\n\t" /* P1: counter */ +" LSETUP (sl1, sl2) LC1 = %3;\n\t" +"sl1: R0.L = W [I0++] || R1.L = W [I1++];\n\t" +" R0 = R0.L * R0.L (IS);\n\t" +" R1 += 1;\n\t" +" R4 = R0.L * R3.L;\n\t" +" R5 = R2.L * R1.L;\n\t" +" cc = R5 < R4;\n\t" +" if cc R2 = R0;\n\t" +" if cc R3 = R1;\n\t" +" if cc P0 = P1;\n\t" +"sl2: P1 += 1;\n\t" +" %0 = P0;\n\t" + : "=&d" (pitch[0]) + : "a" (corr16), "a" (ener16), "a" (end+1-start), "d" (start) + : "P0", "P1", "I0", "I1", "R0", "R1", "R2", "R3", "R4", "R5" +#if (__GNUC__ == 4) + , "LC1" +#endif + ); + + } + else { + for (i=start;i<=end;i++) + { + spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]); + /* Instead of dividing the tmp by the energy, we multiply on the other side */ + if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start]))) + { + /* We can safely put it last and then check */ + best_score[N-1]=tmp; + best_ener[N-1]=ener16[i-start]+1; + pitch[N-1]=i; + /* Check if it comes in front of others */ + for (j=0;j<N-1;j++) + { + if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start]))) + { + for (k=N-1;k>j;k--) + { + best_score[k]=best_score[k-1]; + best_ener[k]=best_ener[k-1]; + pitch[k]=pitch[k-1]; + } + best_score[j]=tmp; + best_ener[j]=ener16[i-start]+1; + pitch[j]=i; + break; + } + } + } + } + } + } + + /* Compute open-loop gain */ + if (gain) + { + for (j=0;j<N;j++) + { + spx_word16_t g; + i=pitch[j]; + g = DIV32(corr[i-start], 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(energy[i-start])),6)); + /* FIXME: g = max(g,corr/energy) */ + if (g<0) + g = 0; + gain[j]=g; + } + } +} +#endif + +#define OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ +#ifdef OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ +static int pitch_gain_search_3tap_vq( + const signed char *gain_cdbk, + int gain_cdbk_size, + spx_word16_t *C16, + spx_word16_t max_gain +) +{ + const signed char *ptr=gain_cdbk; + int best_cdbk=0; + spx_word32_t best_sum=-VERY_LARGE32; + spx_word32_t sum=0; + spx_word16_t g[3]; + spx_word16_t pitch_control=64; + spx_word16_t gain_sum; + int i; + + /* fast asm version of VQ codebook search */ + + __asm__ __volatile__ + ( + +" P0 = %2;\n\t" /* P0: ptr to gain_cdbk */ +" L1 = 0;\n\t" /* no circ addr for L1 */ +" %0 = 0;\n\t" /* %0: best_sum */ +" %1 = 0;\n\t" /* %1: best_cbdk */ +" P1 = 0;\n\t" /* P1: loop counter */ + +" LSETUP (pgs1, pgs2) LC1 = %4;\n\t" +"pgs1: R2 = B [P0++] (X);\n\t" /* R2: g[0] */ +" R3 = B [P0++] (X);\n\t" /* R3: g[1] */ +" R4 = B [P0++] (X);\n\t" /* R4: g[2] */ +" R2 += 32;\n\t" +" R3 += 32;\n\t" +" R4 += 32;\n\t" +" R4.H = 64;\n\t" /* R4.H: pitch_control */ + +" R0 = B [P0++] (X);\n\t" +" B0 = R0;\n\t" /* BO: gain_sum */ + + /* compute_pitch_error() -------------------------------*/ + +" I1 = %3;\n\t" /* I1: ptr to C */ +" A0 = 0;\n\t" + +" R0.L = W[I1++];\n\t" +" R1.L = R2.L*R4.H (IS);\n\t" +" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" + +" R1.L = R3.L*R4.H (IS);\n\t" +" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" + +" R1.L = R4.L*R4.H (IS);\n\t" +" A0 += R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" + +" R1.L = R2.L*R3.L (IS);\n\t" +" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" + +" R1.L = R4.L*R3.L (IS);\n\t" +" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" + +" R1.L = R4.L*R2.L (IS);\n\t" +" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" + +" R1.L = R2.L*R2.L (IS);\n\t" +" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" + +" R1.L = R3.L*R3.L (IS);\n\t" +" A0 -= R1.L*R0.L (IS) || R0.L = W[I1++];\n\t" + +" R1.L = R4.L*R4.L (IS);\n\t" +" R0 = (A0 -= R1.L*R0.L) (IS);\n\t" + +/* + Re-arrange the if-then to code efficiently on the Blackfin: + + if (sum>best_sum && gain_sum<=max_gain) ------ (1) + + if (sum>best_sum && !(gain_sum>max_gain)) ------ (2) + + if (max_gain<=gain_sum) { ------ (3) + sum = -VERY_LARGE32; + } + if (best_sum<=sum) + + The blackin cc instructions are all of the form: + + cc = x < y (or cc = x <= y) +*/ +" R1 = B0\n\t" +" R2 = %5\n\t" +" R3 = %6\n\t" +" cc = R2 <= R1;\n\t" +" if cc R0 = R3;\n\t" +" cc = %0 <= R0;\n\t" +" if cc %0 = R0;\n\t" +" if cc %1 = P1;\n\t" + +"pgs2: P1 += 1;\n\t" + + : "=&d" (best_sum), "=&d" (best_cdbk) + : "a" (gain_cdbk), "a" (C16), "a" (gain_cdbk_size), "a" (max_gain), + "b" (-VERY_LARGE32) + : "R0", "R1", "R2", "R3", "R4", "P0", + "P1", "I1", "L1", "A0", "B0" +#if (__GNUC__ == 4) + , "LC1" +#endif + ); + + return best_cdbk; +} +#endif + diff --git a/src/libs/speex/libspeex/ltp_sse.h b/src/libs/speex/libspeex/ltp_sse.h new file mode 100644 index 00000000..bed6eaac --- /dev/null +++ b/src/libs/speex/libspeex/ltp_sse.h @@ -0,0 +1,92 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file ltp_sse.h + @brief Long-Term Prediction functions (SSE version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <xmmintrin.h> + +#define OVERRIDE_INNER_PROD +float inner_prod(const float *a, const float *b, int len) +{ + int i; + float ret; + __m128 sum = _mm_setzero_ps(); + for (i=0;i<(len>>2);i+=2) + { + sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+0), _mm_loadu_ps(b+0))); + sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+4), _mm_loadu_ps(b+4))); + a += 8; + b += 8; + } + sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum)); + sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55)); + _mm_store_ss(&ret, sum); + return ret; +} + +#define OVERRIDE_PITCH_XCORR +void pitch_xcorr(const float *_x, const float *_y, float *corr, int len, int nb_pitch, char *stack) +{ + int i, offset; + VARDECL(__m128 *x); + VARDECL(__m128 *y); + int N, L; + N = len>>2; + L = nb_pitch>>2; + ALLOC(x, N, __m128); + ALLOC(y, N+L, __m128); + for (i=0;i<N;i++) + x[i] = _mm_loadu_ps(_x+(i<<2)); + for (offset=0;offset<4;offset++) + { + for (i=0;i<N+L;i++) + y[i] = _mm_loadu_ps(_y+(i<<2)+offset); + for (i=0;i<L;i++) + { + int j; + __m128 sum, *xx, *yy; + sum = _mm_setzero_ps(); + yy = y+i; + xx = x; + for (j=0;j<N;j+=2) + { + sum = _mm_add_ps(sum, _mm_mul_ps(xx[0], yy[0])); + sum = _mm_add_ps(sum, _mm_mul_ps(xx[1], yy[1])); + xx += 2; + yy += 2; + } + sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum)); + sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55)); + _mm_store_ss(corr+nb_pitch-1-(i<<2)-offset, sum); + } + } +} diff --git a/src/libs/speex/libspeex/math_approx.h b/src/libs/speex/libspeex/math_approx.h new file mode 100644 index 00000000..9ca83075 --- /dev/null +++ b/src/libs/speex/libspeex/math_approx.h @@ -0,0 +1,332 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file math_approx.h + @brief Various math approximation functions for Speex +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef MATH_APPROX_H +#define MATH_APPROX_H + +#include "arch.h" + +#ifndef FIXED_POINT + +#define spx_sqrt sqrt +#define spx_acos acos +#define spx_exp exp +#define spx_cos_norm(x) (cos((.5f*M_PI)*(x))) +#define spx_atan atan + +/** Generate a pseudo-random number */ +static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed) +{ + const unsigned int jflone = 0x3f800000; + const unsigned int jflmsk = 0x007fffff; + union {int i; float f;} ran; + *seed = 1664525 * *seed + 1013904223; + ran.i = jflone | (jflmsk & *seed); + ran.f -= 1.5; + return 3.4642*std*ran.f; +} + + +#endif + + +static inline spx_int16_t spx_ilog2(spx_uint32_t x) +{ + int r=0; + if (x>=(spx_int32_t)65536) + { + x >>= 16; + r += 16; + } + if (x>=256) + { + x >>= 8; + r += 8; + } + if (x>=16) + { + x >>= 4; + r += 4; + } + if (x>=4) + { + x >>= 2; + r += 2; + } + if (x>=2) + { + r += 1; + } + return r; +} + +static inline spx_int16_t spx_ilog4(spx_uint32_t x) +{ + int r=0; + if (x>=(spx_int32_t)65536) + { + x >>= 16; + r += 8; + } + if (x>=256) + { + x >>= 8; + r += 4; + } + if (x>=16) + { + x >>= 4; + r += 2; + } + if (x>=4) + { + r += 1; + } + return r; +} + +#ifdef FIXED_POINT + +/** Generate a pseudo-random number */ +static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed) +{ + spx_word32_t res; + *seed = 1664525 * *seed + 1013904223; + res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std); + return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14)); +} + +/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */ +/*#define C0 3634 +#define C1 21173 +#define C2 -12627 +#define C3 4215*/ + +/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */ +#define C0 3634 +#define C1 21173 +#define C2 -12627 +#define C3 4204 + +static inline spx_word16_t spx_sqrt(spx_word32_t x) +{ + int k; + spx_word32_t rt; + k = spx_ilog4(x)-6; + x = VSHR32(x, (k<<1)); + rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3))))))); + rt = VSHR32(rt,7-k); + return rt; +} + +/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */ + + +#define A1 16469 +#define A2 2242 +#define A3 1486 + +static inline spx_word16_t spx_acos(spx_word16_t x) +{ + int s=0; + spx_word16_t ret; + spx_word16_t sq; + if (x<0) + { + s=1; + x = NEG16(x); + } + x = SUB16(16384,x); + + x = x >> 1; + sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3)))))); + ret = spx_sqrt(SHL32(EXTEND32(sq),13)); + + /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/ + if (s) + ret = SUB16(25736,ret); + return ret; +} + + +#define K1 8192 +#define K2 -4096 +#define K3 340 +#define K4 -10 + +static inline spx_word16_t spx_cos(spx_word16_t x) +{ + spx_word16_t x2; + + if (x<12868) + { + x2 = MULT16_16_P13(x,x); + return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2)))))); + } else { + x = SUB16(25736,x); + x2 = MULT16_16_P13(x,x); + return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2)))))); + } +} + +#define L1 32767 +#define L2 -7651 +#define L3 8277 +#define L4 -626 + +static inline spx_word16_t _spx_cos_pi_2(spx_word16_t x) +{ + spx_word16_t x2; + + x2 = MULT16_16_P15(x,x); + return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2)))))))); +} + +static inline spx_word16_t spx_cos_norm(spx_word32_t x) +{ + x = x&0x0001ffff; + if (x>SHL32(EXTEND32(1), 16)) + x = SUB32(SHL32(EXTEND32(1), 17),x); + if (x&0x00007fff) + { + if (x<SHL32(EXTEND32(1), 15)) + { + return _spx_cos_pi_2(EXTRACT16(x)); + } else { + return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x))); + } + } else { + if (x&0x0000ffff) + return 0; + else if (x&0x0001ffff) + return -32767; + else + return 32767; + } +} + +/* + K0 = 1 + K1 = log(2) + K2 = 3-4*log(2) + K3 = 3*log(2) - 2 +*/ +#define D0 16384 +#define D1 11356 +#define D2 3726 +#define D3 1301 +/* Input in Q11 format, output in Q16 */ +static inline spx_word32_t spx_exp2(spx_word16_t x) +{ + int integer; + spx_word16_t frac; + integer = SHR16(x,11); + if (integer>14) + return 0x7fffffff; + else if (integer < -15) + return 0; + frac = SHL16(x-SHL16(integer,11),3); + frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac)))))); + return VSHR32(EXTEND32(frac), -integer-2); +} + +/* Input in Q11 format, output in Q16 */ +static inline spx_word32_t spx_exp(spx_word16_t x) +{ + if (x>21290) + return 0x7fffffff; + else if (x<-21290) + return 0; + else + return spx_exp2(MULT16_16_P14(23637,x)); +} +#define M1 32767 +#define M2 -21 +#define M3 -11943 +#define M4 4936 + +static inline spx_word16_t spx_atan01(spx_word16_t x) +{ + return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x))))))); +} + +#undef M1 +#undef M2 +#undef M3 +#undef M4 + +/* Input in Q15, output in Q14 */ +static inline spx_word16_t spx_atan(spx_word32_t x) +{ + if (x <= 32767) + { + return SHR16(spx_atan01(x),1); + } else { + int e = spx_ilog2(x); + if (e>=29) + return 25736; + x = DIV32_16(SHL32(EXTEND32(32767),29-e), EXTRACT16(SHR32(x, e-14))); + return SUB16(25736, SHR16(spx_atan01(x),1)); + } +} +#else + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + +#define C1 0.9999932946f +#define C2 -0.4999124376f +#define C3 0.0414877472f +#define C4 -0.0012712095f + + +#define SPX_PI_2 1.5707963268 +static inline spx_word16_t spx_cos(spx_word16_t x) +{ + if (x<SPX_PI_2) + { + x *= x; + return C1 + x*(C2+x*(C3+C4*x)); + } else { + x = M_PI-x; + x *= x; + return NEG16(C1 + x*(C2+x*(C3+C4*x))); + } +} + +#endif + + +#endif diff --git a/src/libs/speex/libspeex/mdf.c b/src/libs/speex/libspeex/mdf.c new file mode 100644 index 00000000..87c39d5c --- /dev/null +++ b/src/libs/speex/libspeex/mdf.c @@ -0,0 +1,1287 @@ +/* Copyright (C) 2003-2008 Jean-Marc Valin + + File: mdf.c + Echo canceller based on the MDF algorithm (see below) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + The echo canceller is based on the MDF algorithm described in: + + J. S. Soo, K. K. Pang Multidelay block frequency adaptive filter, + IEEE Trans. Acoust. Speech Signal Process., Vol. ASSP-38, No. 2, + February 1990. + + We use the Alternatively Updated MDF (AUMDF) variant. Robustness to + double-talk is achieved using a variable learning rate as described in: + + Valin, J.-M., On Adjusting the Learning Rate in Frequency Domain Echo + Cancellation With Double-Talk. IEEE Transactions on Audio, + Speech and Language Processing, Vol. 15, No. 3, pp. 1030-1034, 2007. + http://people.xiph.org/~jm/papers/valin_taslp2006.pdf + + There is no explicit double-talk detection, but a continuous variation + in the learning rate based on residual echo, double-talk and background + noise. + + About the fixed-point version: + All the signals are represented with 16-bit words. The filter weights + are represented with 32-bit words, but only the top 16 bits are used + in most cases. The lower 16 bits are completely unreliable (due to the + fact that the update is done only on the top bits), but help in the + adaptation -- probably by removing a "threshold effect" due to + quantization (rounding going to zero) when the gradient is small. + + Another kludge that seems to work good: when performing the weight + update, we only move half the way toward the "goal" this seems to + reduce the effect of quantization noise in the update phase. This + can be seen as applying a gradient descent on a "soft constraint" + instead of having a hard constraint. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "arch.h" +#include "speex/speex_echo.h" +#include "fftwrap.h" +#include "pseudofloat.h" +#include "math_approx.h" +#include "os_support.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifdef FIXED_POINT +#define WEIGHT_SHIFT 11 +#define NORMALIZE_SCALEDOWN 5 +#define NORMALIZE_SCALEUP 3 +#else +#define WEIGHT_SHIFT 0 +#endif + +#ifdef FIXED_POINT +#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x))) +#else +#define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x)))) +#endif + +/* If enabled, the AEC will use a foreground filter and a background filter to be more robust to double-talk + and difficult signals in general. The cost is an extra FFT and a matrix-vector multiply */ +#define TWO_PATH + +#define EXPORT + +#ifdef FIXED_POINT +static const spx_float_t MIN_LEAK = {20972, -22}; + +/* Constants for the two-path filter */ +static const spx_float_t VAR1_SMOOTH = {23593, -16}; +static const spx_float_t VAR2_SMOOTH = {23675, -15}; +static const spx_float_t VAR1_UPDATE = {16384, -15}; +static const spx_float_t VAR2_UPDATE = {16384, -16}; +static const spx_float_t VAR_BACKTRACK = {16384, -12}; +#define TOP16(x) ((x)>>16) + +#else + +static const spx_float_t MIN_LEAK = .005f; + +/* Constants for the two-path filter */ +static const spx_float_t VAR1_SMOOTH = .36f; +static const spx_float_t VAR2_SMOOTH = .7225f; +static const spx_float_t VAR1_UPDATE = .5f; +static const spx_float_t VAR2_UPDATE = .25f; +static const spx_float_t VAR_BACKTRACK = 4.f; +#define TOP16(x) (x) +#endif + + +#define PLAYBACK_DELAY 2 + +void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len); + + +/** Speex echo cancellation state. */ +struct SpeexEchoState_ { + int frame_size; /**< Number of samples processed each time */ + int window_size; + int M; + int cancel_count; + int adapted; + int saturated; + int screwed_up; + int C; /** Number of input channels (microphones) */ + int K; /** Number of output channels (loudspeakers) */ + spx_int32_t sampling_rate; + spx_word16_t spec_average; + spx_word16_t beta0; + spx_word16_t beta_max; + spx_word32_t sum_adapt; + spx_word16_t leak_estimate; + + spx_word16_t *e; /* scratch */ + spx_word16_t *x; /* Far-end input buffer (2N) */ + spx_word16_t *X; /* Far-end buffer (M+1 frames) in frequency domain */ + spx_word16_t *input; /* scratch */ + spx_word16_t *y; /* scratch */ + spx_word16_t *last_y; + spx_word16_t *Y; /* scratch */ + spx_word16_t *E; + spx_word32_t *PHI; /* scratch */ + spx_word32_t *W; /* (Background) filter weights */ +#ifdef TWO_PATH + spx_word16_t *foreground; /* Foreground filter weights */ + spx_word32_t Davg1; /* 1st recursive average of the residual power difference */ + spx_word32_t Davg2; /* 2nd recursive average of the residual power difference */ + spx_float_t Dvar1; /* Estimated variance of 1st estimator */ + spx_float_t Dvar2; /* Estimated variance of 2nd estimator */ +#endif + spx_word32_t *power; /* Power of the far-end signal */ + spx_float_t *power_1;/* Inverse power of far-end */ + spx_word16_t *wtmp; /* scratch */ +#ifdef FIXED_POINT + spx_word16_t *wtmp2; /* scratch */ +#endif + spx_word32_t *Rf; /* scratch */ + spx_word32_t *Yf; /* scratch */ + spx_word32_t *Xf; /* scratch */ + spx_word32_t *Eh; + spx_word32_t *Yh; + spx_float_t Pey; + spx_float_t Pyy; + spx_word16_t *window; + spx_word16_t *prop; + void *fft_table; + spx_word16_t *memX, *memD, *memE; + spx_word16_t preemph; + spx_word16_t notch_radius; + spx_mem_t *notch_mem; + + /* NOTE: If you only use speex_echo_cancel() and want to save some memory, remove this */ + spx_int16_t *play_buf; + int play_buf_pos; + int play_buf_started; +}; + +static inline void filter_dc_notch16(const spx_int16_t *in, spx_word16_t radius, spx_word16_t *out, int len, spx_mem_t *mem, int stride) +{ + int i; + spx_word16_t den2; +#ifdef FIXED_POINT + den2 = MULT16_16_Q15(radius,radius) + MULT16_16_Q15(QCONST16(.7,15),MULT16_16_Q15(32767-radius,32767-radius)); +#else + den2 = radius*radius + .7*(1-radius)*(1-radius); +#endif + /*printf ("%d %d %d %d %d %d\n", num[0], num[1], num[2], den[0], den[1], den[2]);*/ + for (i=0;i<len;i++) + { + spx_word16_t vin = in[i*stride]; + spx_word32_t vout = mem[0] + SHL32(EXTEND32(vin),15); +#ifdef FIXED_POINT + mem[0] = mem[1] + SHL32(SHL32(-EXTEND32(vin),15) + MULT16_32_Q15(radius,vout),1); +#else + mem[0] = mem[1] + 2*(-vin + radius*vout); +#endif + mem[1] = SHL32(EXTEND32(vin),15) - MULT16_32_Q15(den2,vout); + out[i] = SATURATE32(PSHR32(MULT16_32_Q15(radius,vout),15),32767); + } +} + +/* This inner product is slightly different from the codec version because of fixed-point */ +static inline spx_word32_t mdf_inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) +{ + spx_word32_t sum=0; + len >>= 1; + while(len--) + { + spx_word32_t part=0; + part = MAC16_16(part,*x++,*y++); + part = MAC16_16(part,*x++,*y++); + /* HINT: If you had a 40-bit accumulator, you could shift only at the end */ + sum = ADD32(sum,SHR32(part,6)); + } + return sum; +} + +/** Compute power spectrum of a half-complex (packed) vector */ +static inline void power_spectrum(const spx_word16_t *X, spx_word32_t *ps, int N) +{ + int i, j; + ps[0]=MULT16_16(X[0],X[0]); + for (i=1,j=1;i<N-1;i+=2,j++) + { + ps[j] = MULT16_16(X[i],X[i]) + MULT16_16(X[i+1],X[i+1]); + } + ps[j]=MULT16_16(X[i],X[i]); +} + +/** Compute power spectrum of a half-complex (packed) vector and accumulate */ +static inline void power_spectrum_accum(const spx_word16_t *X, spx_word32_t *ps, int N) +{ + int i, j; + ps[0]+=MULT16_16(X[0],X[0]); + for (i=1,j=1;i<N-1;i+=2,j++) + { + ps[j] += MULT16_16(X[i],X[i]) + MULT16_16(X[i+1],X[i+1]); + } + ps[j]+=MULT16_16(X[i],X[i]); +} + +/** Compute cross-power spectrum of a half-complex (packed) vectors and add to acc */ +#ifdef FIXED_POINT +static inline void spectral_mul_accum(const spx_word16_t *X, const spx_word32_t *Y, spx_word16_t *acc, int N, int M) +{ + int i,j; + spx_word32_t tmp1=0,tmp2=0; + for (j=0;j<M;j++) + { + tmp1 = MAC16_16(tmp1, X[j*N],TOP16(Y[j*N])); + } + acc[0] = PSHR32(tmp1,WEIGHT_SHIFT); + for (i=1;i<N-1;i+=2) + { + tmp1 = tmp2 = 0; + for (j=0;j<M;j++) + { + tmp1 = SUB32(MAC16_16(tmp1, X[j*N+i],TOP16(Y[j*N+i])), MULT16_16(X[j*N+i+1],TOP16(Y[j*N+i+1]))); + tmp2 = MAC16_16(MAC16_16(tmp2, X[j*N+i+1],TOP16(Y[j*N+i])), X[j*N+i], TOP16(Y[j*N+i+1])); + } + acc[i] = PSHR32(tmp1,WEIGHT_SHIFT); + acc[i+1] = PSHR32(tmp2,WEIGHT_SHIFT); + } + tmp1 = tmp2 = 0; + for (j=0;j<M;j++) + { + tmp1 = MAC16_16(tmp1, X[(j+1)*N-1],TOP16(Y[(j+1)*N-1])); + } + acc[N-1] = PSHR32(tmp1,WEIGHT_SHIFT); +} +static inline void spectral_mul_accum16(const spx_word16_t *X, const spx_word16_t *Y, spx_word16_t *acc, int N, int M) +{ + int i,j; + spx_word32_t tmp1=0,tmp2=0; + for (j=0;j<M;j++) + { + tmp1 = MAC16_16(tmp1, X[j*N],Y[j*N]); + } + acc[0] = PSHR32(tmp1,WEIGHT_SHIFT); + for (i=1;i<N-1;i+=2) + { + tmp1 = tmp2 = 0; + for (j=0;j<M;j++) + { + tmp1 = SUB32(MAC16_16(tmp1, X[j*N+i],Y[j*N+i]), MULT16_16(X[j*N+i+1],Y[j*N+i+1])); + tmp2 = MAC16_16(MAC16_16(tmp2, X[j*N+i+1],Y[j*N+i]), X[j*N+i], Y[j*N+i+1]); + } + acc[i] = PSHR32(tmp1,WEIGHT_SHIFT); + acc[i+1] = PSHR32(tmp2,WEIGHT_SHIFT); + } + tmp1 = tmp2 = 0; + for (j=0;j<M;j++) + { + tmp1 = MAC16_16(tmp1, X[(j+1)*N-1],Y[(j+1)*N-1]); + } + acc[N-1] = PSHR32(tmp1,WEIGHT_SHIFT); +} + +#else +static inline void spectral_mul_accum(const spx_word16_t *X, const spx_word32_t *Y, spx_word16_t *acc, int N, int M) +{ + int i,j; + for (i=0;i<N;i++) + acc[i] = 0; + for (j=0;j<M;j++) + { + acc[0] += X[0]*Y[0]; + for (i=1;i<N-1;i+=2) + { + acc[i] += (X[i]*Y[i] - X[i+1]*Y[i+1]); + acc[i+1] += (X[i+1]*Y[i] + X[i]*Y[i+1]); + } + acc[i] += X[i]*Y[i]; + X += N; + Y += N; + } +} +#define spectral_mul_accum16 spectral_mul_accum +#endif + +/** Compute weighted cross-power spectrum of a half-complex (packed) vector with conjugate */ +static inline void weighted_spectral_mul_conj(const spx_float_t *w, const spx_float_t p, const spx_word16_t *X, const spx_word16_t *Y, spx_word32_t *prod, int N) +{ + int i, j; + spx_float_t W; + W = FLOAT_AMULT(p, w[0]); + prod[0] = FLOAT_MUL32(W,MULT16_16(X[0],Y[0])); + for (i=1,j=1;i<N-1;i+=2,j++) + { + W = FLOAT_AMULT(p, w[j]); + prod[i] = FLOAT_MUL32(W,MAC16_16(MULT16_16(X[i],Y[i]), X[i+1],Y[i+1])); + prod[i+1] = FLOAT_MUL32(W,MAC16_16(MULT16_16(-X[i+1],Y[i]), X[i],Y[i+1])); + } + W = FLOAT_AMULT(p, w[j]); + prod[i] = FLOAT_MUL32(W,MULT16_16(X[i],Y[i])); +} + +static inline void mdf_adjust_prop(const spx_word32_t *W, int N, int M, int P, spx_word16_t *prop) +{ + int i, j, p; + spx_word16_t max_sum = 1; + spx_word32_t prop_sum = 1; + for (i=0;i<M;i++) + { + spx_word32_t tmp = 1; + for (p=0;p<P;p++) + for (j=0;j<N;j++) + tmp += MULT16_16(EXTRACT16(SHR32(W[p*N*M + i*N+j],18)), EXTRACT16(SHR32(W[p*N*M + i*N+j],18))); +#ifdef FIXED_POINT + /* Just a security in case an overflow were to occur */ + tmp = MIN32(ABS32(tmp), 536870912); +#endif + prop[i] = spx_sqrt(tmp); + if (prop[i] > max_sum) + max_sum = prop[i]; + } + for (i=0;i<M;i++) + { + prop[i] += MULT16_16_Q15(QCONST16(.1f,15),max_sum); + prop_sum += EXTEND32(prop[i]); + } + for (i=0;i<M;i++) + { + prop[i] = DIV32(MULT16_16(QCONST16(.99f,15), prop[i]),prop_sum); + /*printf ("%f ", prop[i]);*/ + } + /*printf ("\n");*/ +} + +#ifdef DUMP_ECHO_CANCEL_DATA +#include <stdio.h> +static FILE *rFile=NULL, *pFile=NULL, *oFile=NULL; + +static void dump_audio(const spx_int16_t *rec, const spx_int16_t *play, const spx_int16_t *out, int len) +{ + if (!(rFile && pFile && oFile)) + { + speex_fatal("Dump files not open"); + } + fwrite(rec, sizeof(spx_int16_t), len, rFile); + fwrite(play, sizeof(spx_int16_t), len, pFile); + fwrite(out, sizeof(spx_int16_t), len, oFile); +} +#endif + +/** Creates a new echo canceller state */ +EXPORT SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length) +{ + return speex_echo_state_init_mc(frame_size, filter_length, 1, 1); +} + +EXPORT SpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_length, int nb_mic, int nb_speakers) +{ + int i,N,M, C, K; + SpeexEchoState *st = (SpeexEchoState *)speex_alloc(sizeof(SpeexEchoState)); + + st->K = nb_speakers; + st->C = nb_mic; + C=st->C; + K=st->K; +#ifdef DUMP_ECHO_CANCEL_DATA + if (rFile || pFile || oFile) + speex_fatal("Opening dump files twice"); + rFile = fopen("aec_rec.sw", "wb"); + pFile = fopen("aec_play.sw", "wb"); + oFile = fopen("aec_out.sw", "wb"); +#endif + + st->frame_size = frame_size; + st->window_size = 2*frame_size; + N = st->window_size; + M = st->M = (filter_length+st->frame_size-1)/frame_size; + st->cancel_count=0; + st->sum_adapt = 0; + st->saturated = 0; + st->screwed_up = 0; + /* This is the default sampling rate */ + st->sampling_rate = 8000; + st->spec_average = DIV32_16(SHL32(EXTEND32(st->frame_size), 15), st->sampling_rate); +#ifdef FIXED_POINT + st->beta0 = DIV32_16(SHL32(EXTEND32(st->frame_size), 16), st->sampling_rate); + st->beta_max = DIV32_16(SHL32(EXTEND32(st->frame_size), 14), st->sampling_rate); +#else + st->beta0 = (2.0f*st->frame_size)/st->sampling_rate; + st->beta_max = (.5f*st->frame_size)/st->sampling_rate; +#endif + st->leak_estimate = 0; + + st->fft_table = spx_fft_init(N); + + st->e = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->x = (spx_word16_t*)speex_alloc(K*N*sizeof(spx_word16_t)); + st->input = (spx_word16_t*)speex_alloc(C*st->frame_size*sizeof(spx_word16_t)); + st->y = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->last_y = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->Yf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); + st->Rf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); + st->Xf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); + st->Yh = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); + st->Eh = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); + + st->X = (spx_word16_t*)speex_alloc(K*(M+1)*N*sizeof(spx_word16_t)); + st->Y = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->E = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->W = (spx_word32_t*)speex_alloc(C*K*M*N*sizeof(spx_word32_t)); +#ifdef TWO_PATH + st->foreground = (spx_word16_t*)speex_alloc(M*N*C*K*sizeof(spx_word16_t)); +#endif + st->PHI = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); + st->power = (spx_word32_t*)speex_alloc((frame_size+1)*sizeof(spx_word32_t)); + st->power_1 = (spx_float_t*)speex_alloc((frame_size+1)*sizeof(spx_float_t)); + st->window = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); + st->prop = (spx_word16_t*)speex_alloc(M*sizeof(spx_word16_t)); + st->wtmp = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); +#ifdef FIXED_POINT + st->wtmp2 = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); + for (i=0;i<N>>1;i++) + { + st->window[i] = (16383-SHL16(spx_cos(DIV32_16(MULT16_16(25736,i<<1),N)),1)); + st->window[N-i-1] = st->window[i]; + } +#else + for (i=0;i<N;i++) + st->window[i] = .5-.5*cos(2*M_PI*i/N); +#endif + for (i=0;i<=st->frame_size;i++) + st->power_1[i] = FLOAT_ONE; + for (i=0;i<N*M*K*C;i++) + st->W[i] = 0; + { + spx_word32_t sum = 0; + /* Ratio of ~10 between adaptation rate of first and last block */ + spx_word16_t decay = SHR32(spx_exp(NEG16(DIV32_16(QCONST16(2.4,11),M))),1); + st->prop[0] = QCONST16(.7, 15); + sum = EXTEND32(st->prop[0]); + for (i=1;i<M;i++) + { + st->prop[i] = MULT16_16_Q15(st->prop[i-1], decay); + sum = ADD32(sum, EXTEND32(st->prop[i])); + } + for (i=M-1;i>=0;i--) + { + st->prop[i] = DIV32(MULT16_16(QCONST16(.8f,15), st->prop[i]),sum); + } + } + + st->memX = (spx_word16_t*)speex_alloc(K*sizeof(spx_word16_t)); + st->memD = (spx_word16_t*)speex_alloc(C*sizeof(spx_word16_t)); + st->memE = (spx_word16_t*)speex_alloc(C*sizeof(spx_word16_t)); + st->preemph = QCONST16(.9,15); + if (st->sampling_rate<12000) + st->notch_radius = QCONST16(.9, 15); + else if (st->sampling_rate<24000) + st->notch_radius = QCONST16(.982, 15); + else + st->notch_radius = QCONST16(.992, 15); + + st->notch_mem = (spx_mem_t*)speex_alloc(2*C*sizeof(spx_mem_t)); + st->adapted = 0; + st->Pey = st->Pyy = FLOAT_ONE; + +#ifdef TWO_PATH + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; +#endif + + st->play_buf = (spx_int16_t*)speex_alloc(K*(PLAYBACK_DELAY+1)*st->frame_size*sizeof(spx_int16_t)); + st->play_buf_pos = PLAYBACK_DELAY*st->frame_size; + st->play_buf_started = 0; + + return st; +} + +/** Resets echo canceller state */ +EXPORT void speex_echo_state_reset(SpeexEchoState *st) +{ + int i, M, N, C, K; + st->cancel_count=0; + st->screwed_up = 0; + N = st->window_size; + M = st->M; + C=st->C; + K=st->K; + for (i=0;i<N*M;i++) + st->W[i] = 0; +#ifdef TWO_PATH + for (i=0;i<N*M;i++) + st->foreground[i] = 0; +#endif + for (i=0;i<N*(M+1);i++) + st->X[i] = 0; + for (i=0;i<=st->frame_size;i++) + { + st->power[i] = 0; + st->power_1[i] = FLOAT_ONE; + st->Eh[i] = 0; + st->Yh[i] = 0; + } + for (i=0;i<st->frame_size;i++) + { + st->last_y[i] = 0; + } + for (i=0;i<N*C;i++) + { + st->E[i] = 0; + } + for (i=0;i<N*K;i++) + { + st->x[i] = 0; + } + for (i=0;i<2*C;i++) + st->notch_mem[i] = 0; + for (i=0;i<C;i++) + st->memD[i]=st->memE[i]=0; + for (i=0;i<K;i++) + st->memX[i]=0; + + st->saturated = 0; + st->adapted = 0; + st->sum_adapt = 0; + st->Pey = st->Pyy = FLOAT_ONE; +#ifdef TWO_PATH + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; +#endif + for (i=0;i<3*st->frame_size;i++) + st->play_buf[i] = 0; + st->play_buf_pos = PLAYBACK_DELAY*st->frame_size; + st->play_buf_started = 0; + +} + +/** Destroys an echo canceller state */ +EXPORT void speex_echo_state_destroy(SpeexEchoState *st) +{ + spx_fft_destroy(st->fft_table); + + speex_free(st->e); + speex_free(st->x); + speex_free(st->input); + speex_free(st->y); + speex_free(st->last_y); + speex_free(st->Yf); + speex_free(st->Rf); + speex_free(st->Xf); + speex_free(st->Yh); + speex_free(st->Eh); + + speex_free(st->X); + speex_free(st->Y); + speex_free(st->E); + speex_free(st->W); +#ifdef TWO_PATH + speex_free(st->foreground); +#endif + speex_free(st->PHI); + speex_free(st->power); + speex_free(st->power_1); + speex_free(st->window); + speex_free(st->prop); + speex_free(st->wtmp); +#ifdef FIXED_POINT + speex_free(st->wtmp2); +#endif + speex_free(st->memX); + speex_free(st->memD); + speex_free(st->memE); + speex_free(st->notch_mem); + + speex_free(st->play_buf); + speex_free(st); + +#ifdef DUMP_ECHO_CANCEL_DATA + fclose(rFile); + fclose(pFile); + fclose(oFile); + rFile = pFile = oFile = NULL; +#endif +} + +EXPORT void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out) +{ + int i; + /*speex_warning_int("capture with fill level ", st->play_buf_pos/st->frame_size);*/ + st->play_buf_started = 1; + if (st->play_buf_pos>=st->frame_size) + { + speex_echo_cancellation(st, rec, st->play_buf, out); + st->play_buf_pos -= st->frame_size; + for (i=0;i<st->play_buf_pos;i++) + st->play_buf[i] = st->play_buf[i+st->frame_size]; + } else { + speex_warning("No playback frame available (your application is buggy and/or got xruns)"); + if (st->play_buf_pos!=0) + { + speex_warning("internal playback buffer corruption?"); + st->play_buf_pos = 0; + } + for (i=0;i<st->frame_size;i++) + out[i] = rec[i]; + } +} + +EXPORT void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play) +{ + /*speex_warning_int("playback with fill level ", st->play_buf_pos/st->frame_size);*/ + if (!st->play_buf_started) + { + speex_warning("discarded first playback frame"); + return; + } + if (st->play_buf_pos<=PLAYBACK_DELAY*st->frame_size) + { + int i; + for (i=0;i<st->frame_size;i++) + st->play_buf[st->play_buf_pos+i] = play[i]; + st->play_buf_pos += st->frame_size; + if (st->play_buf_pos <= (PLAYBACK_DELAY-1)*st->frame_size) + { + speex_warning("Auto-filling the buffer (your application is buggy and/or got xruns)"); + for (i=0;i<st->frame_size;i++) + st->play_buf[st->play_buf_pos+i] = play[i]; + st->play_buf_pos += st->frame_size; + } + } else { + speex_warning("Had to discard a playback frame (your application is buggy and/or got xruns)"); + } +} + +/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */ +EXPORT void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout) +{ + speex_echo_cancellation(st, in, far_end, out); +} + +/** Performs echo cancellation on a frame */ +EXPORT void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out) +{ + int i,j, chan, speak; + int N,M, C, K; + spx_word32_t Syy,See,Sxx,Sdd, Sff; +#ifdef TWO_PATH + spx_word32_t Dbf; + int update_foreground; +#endif + spx_word32_t Sey; + spx_word16_t ss, ss_1; + spx_float_t Pey = FLOAT_ONE, Pyy=FLOAT_ONE; + spx_float_t alpha, alpha_1; + spx_word16_t RER; + spx_word32_t tmp32; + + N = st->window_size; + M = st->M; + C = st->C; + K = st->K; + + st->cancel_count++; +#ifdef FIXED_POINT + ss=DIV32_16(11469,M); + ss_1 = SUB16(32767,ss); +#else + ss=.35/M; + ss_1 = 1-ss; +#endif + + for (chan = 0; chan < C; chan++) + { + /* Apply a notch filter to make sure DC doesn't end up causing problems */ + filter_dc_notch16(in+chan, st->notch_radius, st->input+chan*st->frame_size, st->frame_size, st->notch_mem+2*chan, C); + /* Copy input data to buffer and apply pre-emphasis */ + /* Copy input data to buffer */ + for (i=0;i<st->frame_size;i++) + { + spx_word32_t tmp32; + /* FIXME: This core has changed a bit, need to merge properly */ + tmp32 = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(MULT16_16_P15(st->preemph, st->memD[chan]))); +#ifdef FIXED_POINT + if (tmp32 > 32767) + { + tmp32 = 32767; + if (st->saturated == 0) + st->saturated = 1; + } + if (tmp32 < -32767) + { + tmp32 = -32767; + if (st->saturated == 0) + st->saturated = 1; + } +#endif + st->memD[chan] = st->input[chan*st->frame_size+i]; + st->input[chan*st->frame_size+i] = EXTRACT16(tmp32); + } + } + + for (speak = 0; speak < K; speak++) + { + for (i=0;i<st->frame_size;i++) + { + spx_word32_t tmp32; + st->x[speak*N+i] = st->x[speak*N+i+st->frame_size]; + tmp32 = SUB32(EXTEND32(far_end[i*K+speak]), EXTEND32(MULT16_16_P15(st->preemph, st->memX[speak]))); +#ifdef FIXED_POINT + /*FIXME: If saturation occurs here, we need to freeze adaptation for M frames (not just one) */ + if (tmp32 > 32767) + { + tmp32 = 32767; + st->saturated = M+1; + } + if (tmp32 < -32767) + { + tmp32 = -32767; + st->saturated = M+1; + } +#endif + st->x[speak*N+i+st->frame_size] = EXTRACT16(tmp32); + st->memX[speak] = far_end[i*K+speak]; + } + } + + for (speak = 0; speak < K; speak++) + { + /* Shift memory: this could be optimized eventually*/ + for (j=M-1;j>=0;j--) + { + for (i=0;i<N;i++) + st->X[(j+1)*N*K+speak*N+i] = st->X[j*N*K+speak*N+i]; + } + /* Convert x (echo input) to frequency domain */ + spx_fft(st->fft_table, st->x+speak*N, &st->X[speak*N]); + } + + Sxx = 0; + for (speak = 0; speak < K; speak++) + { + Sxx += mdf_inner_prod(st->x+speak*N+st->frame_size, st->x+speak*N+st->frame_size, st->frame_size); + power_spectrum_accum(st->X+speak*N, st->Xf, N); + } + + Sff = 0; + for (chan = 0; chan < C; chan++) + { +#ifdef TWO_PATH + /* Compute foreground filter */ + spectral_mul_accum16(st->X, st->foreground+chan*N*K*M, st->Y+chan*N, N, M*K); + spx_ifft(st->fft_table, st->Y+chan*N, st->e+chan*N); + for (i=0;i<st->frame_size;i++) + st->e[chan*N+i] = SUB16(st->input[chan*st->frame_size+i], st->e[chan*N+i+st->frame_size]); + Sff += mdf_inner_prod(st->e+chan*N, st->e+chan*N, st->frame_size); +#endif + } + + /* Adjust proportional adaption rate */ + /* FIXME: Adjust that for C, K*/ + if (st->adapted) + mdf_adjust_prop (st->W, N, M, C*K, st->prop); + /* Compute weight gradient */ + if (st->saturated == 0) + { + for (chan = 0; chan < C; chan++) + { + for (speak = 0; speak < K; speak++) + { + for (j=M-1;j>=0;j--) + { + weighted_spectral_mul_conj(st->power_1, FLOAT_SHL(PSEUDOFLOAT(st->prop[j]),-15), &st->X[(j+1)*N*K+speak*N], st->E+chan*N, st->PHI, N); + for (i=0;i<N;i++) + st->W[chan*N*K*M + j*N*K + speak*N + i] += st->PHI[i]; + } + } + } + } else { + st->saturated--; + } + + /* FIXME: MC conversion required */ + /* Update weight to prevent circular convolution (MDF / AUMDF) */ + for (chan = 0; chan < C; chan++) + { + for (speak = 0; speak < K; speak++) + { + for (j=0;j<M;j++) + { + /* This is a variant of the Alternatively Updated MDF (AUMDF) */ + /* Remove the "if" to make this an MDF filter */ + if (j==0 || st->cancel_count%(M-1) == j-1) + { +#ifdef FIXED_POINT + for (i=0;i<N;i++) + st->wtmp2[i] = EXTRACT16(PSHR32(st->W[chan*N*K*M + j*N*K + speak*N + i],NORMALIZE_SCALEDOWN+16)); + spx_ifft(st->fft_table, st->wtmp2, st->wtmp); + for (i=0;i<st->frame_size;i++) + { + st->wtmp[i]=0; + } + for (i=st->frame_size;i<N;i++) + { + st->wtmp[i]=SHL16(st->wtmp[i],NORMALIZE_SCALEUP); + } + spx_fft(st->fft_table, st->wtmp, st->wtmp2); + /* The "-1" in the shift is a sort of kludge that trades less efficient update speed for decrease noise */ + for (i=0;i<N;i++) + st->W[chan*N*K*M + j*N*K + speak*N + i] -= SHL32(EXTEND32(st->wtmp2[i]),16+NORMALIZE_SCALEDOWN-NORMALIZE_SCALEUP-1); +#else + spx_ifft(st->fft_table, &st->W[chan*N*K*M + j*N*K + speak*N], st->wtmp); + for (i=st->frame_size;i<N;i++) + { + st->wtmp[i]=0; + } + spx_fft(st->fft_table, st->wtmp, &st->W[chan*N*K*M + j*N*K + speak*N]); +#endif + } + } + } + } + + /* So we can use power_spectrum_accum */ + for (i=0;i<=st->frame_size;i++) + st->Rf[i] = st->Yf[i] = st->Xf[i] = 0; + + Dbf = 0; + See = 0; +#ifdef TWO_PATH + /* Difference in response, this is used to estimate the variance of our residual power estimate */ + for (chan = 0; chan < C; chan++) + { + spectral_mul_accum(st->X, st->W+chan*N*K*M, st->Y+chan*N, N, M*K); + spx_ifft(st->fft_table, st->Y+chan*N, st->y+chan*N); + for (i=0;i<st->frame_size;i++) + st->e[chan*N+i] = SUB16(st->e[chan*N+i+st->frame_size], st->y[chan*N+i+st->frame_size]); + Dbf += 10+mdf_inner_prod(st->e+chan*N, st->e+chan*N, st->frame_size); + for (i=0;i<st->frame_size;i++) + st->e[chan*N+i] = SUB16(st->input[chan*st->frame_size+i], st->y[chan*N+i+st->frame_size]); + See += mdf_inner_prod(st->e+chan*N, st->e+chan*N, st->frame_size); + } +#endif + +#ifndef TWO_PATH + Sff = See; +#endif + +#ifdef TWO_PATH + /* Logic for updating the foreground filter */ + + /* For two time windows, compute the mean of the energy difference, as well as the variance */ + st->Davg1 = ADD32(MULT16_32_Q15(QCONST16(.6f,15),st->Davg1), MULT16_32_Q15(QCONST16(.4f,15),SUB32(Sff,See))); + st->Davg2 = ADD32(MULT16_32_Q15(QCONST16(.85f,15),st->Davg2), MULT16_32_Q15(QCONST16(.15f,15),SUB32(Sff,See))); + st->Dvar1 = FLOAT_ADD(FLOAT_MULT(VAR1_SMOOTH, st->Dvar1), FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.4f,15),Sff), MULT16_32_Q15(QCONST16(.4f,15),Dbf))); + st->Dvar2 = FLOAT_ADD(FLOAT_MULT(VAR2_SMOOTH, st->Dvar2), FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.15f,15),Sff), MULT16_32_Q15(QCONST16(.15f,15),Dbf))); + + /* Equivalent float code: + st->Davg1 = .6*st->Davg1 + .4*(Sff-See); + st->Davg2 = .85*st->Davg2 + .15*(Sff-See); + st->Dvar1 = .36*st->Dvar1 + .16*Sff*Dbf; + st->Dvar2 = .7225*st->Dvar2 + .0225*Sff*Dbf; + */ + + update_foreground = 0; + /* Check if we have a statistically significant reduction in the residual echo */ + /* Note that this is *not* Gaussian, so we need to be careful about the longer tail */ + if (FLOAT_GT(FLOAT_MUL32U(SUB32(Sff,See),ABS32(SUB32(Sff,See))), FLOAT_MUL32U(Sff,Dbf))) + update_foreground = 1; + else if (FLOAT_GT(FLOAT_MUL32U(st->Davg1, ABS32(st->Davg1)), FLOAT_MULT(VAR1_UPDATE,(st->Dvar1)))) + update_foreground = 1; + else if (FLOAT_GT(FLOAT_MUL32U(st->Davg2, ABS32(st->Davg2)), FLOAT_MULT(VAR2_UPDATE,(st->Dvar2)))) + update_foreground = 1; + + /* Do we update? */ + if (update_foreground) + { + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; + /* Copy background filter to foreground filter */ + for (i=0;i<N*M*C*K;i++) + st->foreground[i] = EXTRACT16(PSHR32(st->W[i],16)); + /* Apply a smooth transition so as to not introduce blocking artifacts */ + for (chan = 0; chan < C; chan++) + for (i=0;i<st->frame_size;i++) + st->e[chan*N+i+st->frame_size] = MULT16_16_Q15(st->window[i+st->frame_size],st->e[chan*N+i+st->frame_size]) + MULT16_16_Q15(st->window[i],st->y[chan*N+i+st->frame_size]); + } else { + int reset_background=0; + /* Otherwise, check if the background filter is significantly worse */ + if (FLOAT_GT(FLOAT_MUL32U(NEG32(SUB32(Sff,See)),ABS32(SUB32(Sff,See))), FLOAT_MULT(VAR_BACKTRACK,FLOAT_MUL32U(Sff,Dbf)))) + reset_background = 1; + if (FLOAT_GT(FLOAT_MUL32U(NEG32(st->Davg1), ABS32(st->Davg1)), FLOAT_MULT(VAR_BACKTRACK,st->Dvar1))) + reset_background = 1; + if (FLOAT_GT(FLOAT_MUL32U(NEG32(st->Davg2), ABS32(st->Davg2)), FLOAT_MULT(VAR_BACKTRACK,st->Dvar2))) + reset_background = 1; + if (reset_background) + { + /* Copy foreground filter to background filter */ + for (i=0;i<N*M*C*K;i++) + st->W[i] = SHL32(EXTEND32(st->foreground[i]),16); + /* We also need to copy the output so as to get correct adaptation */ + for (chan = 0; chan < C; chan++) + { + for (i=0;i<st->frame_size;i++) + st->y[chan*N+i+st->frame_size] = st->e[chan*N+i+st->frame_size]; + for (i=0;i<st->frame_size;i++) + st->e[chan*N+i] = SUB16(st->input[chan*st->frame_size+i], st->y[chan*N+i+st->frame_size]); + } + See = Sff; + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; + } + } +#endif + + Sey = Syy = Sdd = 0; + for (chan = 0; chan < C; chan++) + { + /* Compute error signal (for the output with de-emphasis) */ + for (i=0;i<st->frame_size;i++) + { + spx_word32_t tmp_out; +#ifdef TWO_PATH + tmp_out = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(st->e[chan*N+i+st->frame_size])); +#else + tmp_out = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(st->y[chan*N+i+st->frame_size])); +#endif + tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE[chan]))); + /* This is an arbitrary test for saturation in the microphone signal */ + if (in[i*C+chan] <= -32000 || in[i*C+chan] >= 32000) + { + if (st->saturated == 0) + st->saturated = 1; + } + out[i*C+chan] = WORD2INT(tmp_out); + st->memE[chan] = tmp_out; + } + +#ifdef DUMP_ECHO_CANCEL_DATA + dump_audio(in, far_end, out, st->frame_size); +#endif + + /* Compute error signal (filter update version) */ + for (i=0;i<st->frame_size;i++) + { + st->e[chan*N+i+st->frame_size] = st->e[chan*N+i]; + st->e[chan*N+i] = 0; + } + + /* Compute a bunch of correlations */ + /* FIXME: bad merge */ + Sey += mdf_inner_prod(st->e+chan*N+st->frame_size, st->y+chan*N+st->frame_size, st->frame_size); + Syy += mdf_inner_prod(st->y+chan*N+st->frame_size, st->y+chan*N+st->frame_size, st->frame_size); + Sdd += mdf_inner_prod(st->input+chan*st->frame_size, st->input+chan*st->frame_size, st->frame_size); + + /* Convert error to frequency domain */ + spx_fft(st->fft_table, st->e+chan*N, st->E+chan*N); + for (i=0;i<st->frame_size;i++) + st->y[i+chan*N] = 0; + spx_fft(st->fft_table, st->y+chan*N, st->Y+chan*N); + + /* Compute power spectrum of echo (X), error (E) and filter response (Y) */ + power_spectrum_accum(st->E+chan*N, st->Rf, N); + power_spectrum_accum(st->Y+chan*N, st->Yf, N); + + } + + /*printf ("%f %f %f %f\n", Sff, See, Syy, Sdd, st->update_cond);*/ + + /* Do some sanity check */ + if (!(Syy>=0 && Sxx>=0 && See >= 0) +#ifndef FIXED_POINT + || !(Sff < N*1e9 && Syy < N*1e9 && Sxx < N*1e9) +#endif + ) + { + /* Things have gone really bad */ + st->screwed_up += 50; + for (i=0;i<st->frame_size*C;i++) + out[i] = 0; + } else if (SHR32(Sff, 2) > ADD32(Sdd, SHR32(MULT16_16(N, 10000),6))) + { + /* AEC seems to add lots of echo instead of removing it, let's see if it will improve */ + st->screwed_up++; + } else { + /* Everything's fine */ + st->screwed_up=0; + } + if (st->screwed_up>=50) + { + speex_warning("The echo canceller started acting funny and got slapped (reset). It swears it will behave now."); + speex_echo_state_reset(st); + return; + } + + /* Add a small noise floor to make sure not to have problems when dividing */ + See = MAX32(See, SHR32(MULT16_16(N, 100),6)); + + for (speak = 0; speak < K; speak++) + { + Sxx += mdf_inner_prod(st->x+speak*N+st->frame_size, st->x+speak*N+st->frame_size, st->frame_size); + power_spectrum_accum(st->X+speak*N, st->Xf, N); + } + + + /* Smooth far end energy estimate over time */ + for (j=0;j<=st->frame_size;j++) + st->power[j] = MULT16_32_Q15(ss_1,st->power[j]) + 1 + MULT16_32_Q15(ss,st->Xf[j]); + + /* Compute filtered spectra and (cross-)correlations */ + for (j=st->frame_size;j>=0;j--) + { + spx_float_t Eh, Yh; + Eh = PSEUDOFLOAT(st->Rf[j] - st->Eh[j]); + Yh = PSEUDOFLOAT(st->Yf[j] - st->Yh[j]); + Pey = FLOAT_ADD(Pey,FLOAT_MULT(Eh,Yh)); + Pyy = FLOAT_ADD(Pyy,FLOAT_MULT(Yh,Yh)); +#ifdef FIXED_POINT + st->Eh[j] = MAC16_32_Q15(MULT16_32_Q15(SUB16(32767,st->spec_average),st->Eh[j]), st->spec_average, st->Rf[j]); + st->Yh[j] = MAC16_32_Q15(MULT16_32_Q15(SUB16(32767,st->spec_average),st->Yh[j]), st->spec_average, st->Yf[j]); +#else + st->Eh[j] = (1-st->spec_average)*st->Eh[j] + st->spec_average*st->Rf[j]; + st->Yh[j] = (1-st->spec_average)*st->Yh[j] + st->spec_average*st->Yf[j]; +#endif + } + + Pyy = FLOAT_SQRT(Pyy); + Pey = FLOAT_DIVU(Pey,Pyy); + + /* Compute correlation updatete rate */ + tmp32 = MULT16_32_Q15(st->beta0,Syy); + if (tmp32 > MULT16_32_Q15(st->beta_max,See)) + tmp32 = MULT16_32_Q15(st->beta_max,See); + alpha = FLOAT_DIV32(tmp32, See); + alpha_1 = FLOAT_SUB(FLOAT_ONE, alpha); + /* Update correlations (recursive average) */ + st->Pey = FLOAT_ADD(FLOAT_MULT(alpha_1,st->Pey) , FLOAT_MULT(alpha,Pey)); + st->Pyy = FLOAT_ADD(FLOAT_MULT(alpha_1,st->Pyy) , FLOAT_MULT(alpha,Pyy)); + if (FLOAT_LT(st->Pyy, FLOAT_ONE)) + st->Pyy = FLOAT_ONE; + /* We don't really hope to get better than 33 dB (MIN_LEAK-3dB) attenuation anyway */ + if (FLOAT_LT(st->Pey, FLOAT_MULT(MIN_LEAK,st->Pyy))) + st->Pey = FLOAT_MULT(MIN_LEAK,st->Pyy); + if (FLOAT_GT(st->Pey, st->Pyy)) + st->Pey = st->Pyy; + /* leak_estimate is the linear regression result */ + st->leak_estimate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIVU(st->Pey, st->Pyy),14)); + /* This looks like a stupid bug, but it's right (because we convert from Q14 to Q15) */ + if (st->leak_estimate > 16383) + st->leak_estimate = 32767; + else + st->leak_estimate = SHL16(st->leak_estimate,1); + /*printf ("%f\n", st->leak_estimate);*/ + + /* Compute Residual to Error Ratio */ +#ifdef FIXED_POINT + tmp32 = MULT16_32_Q15(st->leak_estimate,Syy); + tmp32 = ADD32(SHR32(Sxx,13), ADD32(tmp32, SHL32(tmp32,1))); + /* Check for y in e (lower bound on RER) */ + { + spx_float_t bound = PSEUDOFLOAT(Sey); + bound = FLOAT_DIVU(FLOAT_MULT(bound, bound), PSEUDOFLOAT(ADD32(1,Syy))); + if (FLOAT_GT(bound, PSEUDOFLOAT(See))) + tmp32 = See; + else if (tmp32 < FLOAT_EXTRACT32(bound)) + tmp32 = FLOAT_EXTRACT32(bound); + } + if (tmp32 > SHR32(See,1)) + tmp32 = SHR32(See,1); + RER = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32,See),15)); +#else + RER = (.0001*Sxx + 3.*MULT16_32_Q15(st->leak_estimate,Syy)) / See; + /* Check for y in e (lower bound on RER) */ + if (RER < Sey*Sey/(1+See*Syy)) + RER = Sey*Sey/(1+See*Syy); + if (RER > .5) + RER = .5; +#endif + + /* We consider that the filter has had minimal adaptation if the following is true*/ + if (!st->adapted && st->sum_adapt > SHL32(EXTEND32(M),15) && MULT16_32_Q15(st->leak_estimate,Syy) > MULT16_32_Q15(QCONST16(.03f,15),Syy)) + { + st->adapted = 1; + } + + if (st->adapted) + { + /* Normal learning rate calculation once we're past the minimal adaptation phase */ + for (i=0;i<=st->frame_size;i++) + { + spx_word32_t r, e; + /* Compute frequency-domain adaptation mask */ + r = MULT16_32_Q15(st->leak_estimate,SHL32(st->Yf[i],3)); + e = SHL32(st->Rf[i],3)+1; +#ifdef FIXED_POINT + if (r>SHR32(e,1)) + r = SHR32(e,1); +#else + if (r>.5*e) + r = .5*e; +#endif + r = MULT16_32_Q15(QCONST16(.7,15),r) + MULT16_32_Q15(QCONST16(.3,15),(spx_word32_t)(MULT16_32_Q15(RER,e))); + /*st->power_1[i] = adapt_rate*r/(e*(1+st->power[i]));*/ + st->power_1[i] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,st->power[i]+10)),WEIGHT_SHIFT+16); + } + } else { + /* Temporary adaption rate if filter is not yet adapted enough */ + spx_word16_t adapt_rate=0; + + if (Sxx > SHR32(MULT16_16(N, 1000),6)) + { + tmp32 = MULT16_32_Q15(QCONST16(.25f, 15), Sxx); +#ifdef FIXED_POINT + if (tmp32 > SHR32(See,2)) + tmp32 = SHR32(See,2); +#else + if (tmp32 > .25*See) + tmp32 = .25*See; +#endif + adapt_rate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32, See),15)); + } + for (i=0;i<=st->frame_size;i++) + st->power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(st->power[i],10)),WEIGHT_SHIFT+1); + + + /* How much have we adapted so far? */ + st->sum_adapt = ADD32(st->sum_adapt,adapt_rate); + } + + /* FIXME: MC conversion required */ + for (i=0;i<st->frame_size;i++) + st->last_y[i] = st->last_y[st->frame_size+i]; + if (st->adapted) + { + /* If the filter is adapted, take the filtered echo */ + for (i=0;i<st->frame_size;i++) + st->last_y[st->frame_size+i] = in[i]-out[i]; + } else { + /* If filter isn't adapted yet, all we can do is take the far end signal directly */ + /* moved earlier: for (i=0;i<N;i++) + st->last_y[i] = st->x[i];*/ + } + +} + +/* Compute spectrum of estimated echo for use in an echo post-filter */ +void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *residual_echo, int len) +{ + int i; + spx_word16_t leak2; + int N; + + N = st->window_size; + + /* Apply hanning window (should pre-compute it)*/ + for (i=0;i<N;i++) + st->y[i] = MULT16_16_Q15(st->window[i],st->last_y[i]); + + /* Compute power spectrum of the echo */ + spx_fft(st->fft_table, st->y, st->Y); + power_spectrum(st->Y, residual_echo, N); + +#ifdef FIXED_POINT + if (st->leak_estimate > 16383) + leak2 = 32767; + else + leak2 = SHL16(st->leak_estimate, 1); +#else + if (st->leak_estimate>.5) + leak2 = 1; + else + leak2 = 2*st->leak_estimate; +#endif + /* Estimate residual echo */ + for (i=0;i<=st->frame_size;i++) + residual_echo[i] = (spx_int32_t)MULT16_32_Q15(leak2,residual_echo[i]); + +} + +EXPORT int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr) +{ + switch(request) + { + + case SPEEX_ECHO_GET_FRAME_SIZE: + (*(int*)ptr) = st->frame_size; + break; + case SPEEX_ECHO_SET_SAMPLING_RATE: + st->sampling_rate = (*(int*)ptr); + st->spec_average = DIV32_16(SHL32(EXTEND32(st->frame_size), 15), st->sampling_rate); +#ifdef FIXED_POINT + st->beta0 = DIV32_16(SHL32(EXTEND32(st->frame_size), 16), st->sampling_rate); + st->beta_max = DIV32_16(SHL32(EXTEND32(st->frame_size), 14), st->sampling_rate); +#else + st->beta0 = (2.0f*st->frame_size)/st->sampling_rate; + st->beta_max = (.5f*st->frame_size)/st->sampling_rate; +#endif + if (st->sampling_rate<12000) + st->notch_radius = QCONST16(.9, 15); + else if (st->sampling_rate<24000) + st->notch_radius = QCONST16(.982, 15); + else + st->notch_radius = QCONST16(.992, 15); + break; + case SPEEX_ECHO_GET_SAMPLING_RATE: + (*(int*)ptr) = st->sampling_rate; + break; + case SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE: + /*FIXME: Implement this for multiple channels */ + *((spx_int32_t *)ptr) = st->M * st->frame_size; + break; + case SPEEX_ECHO_GET_IMPULSE_RESPONSE: + { + int M = st->M, N = st->window_size, n = st->frame_size, i, j; + spx_int32_t *filt = (spx_int32_t *) ptr; + for(j=0;j<M;j++) + { + /*FIXME: Implement this for multiple channels */ +#ifdef FIXED_POINT + for (i=0;i<N;i++) + st->wtmp2[i] = EXTRACT16(PSHR32(st->W[j*N+i],16+NORMALIZE_SCALEDOWN)); + spx_ifft(st->fft_table, st->wtmp2, st->wtmp); +#else + spx_ifft(st->fft_table, &st->W[j*N], st->wtmp); +#endif + for(i=0;i<n;i++) + filt[j*n+i] = PSHR32(MULT16_16(32767,st->wtmp[i]), WEIGHT_SHIFT-NORMALIZE_SCALEDOWN); + } + } + break; + default: + speex_warning_int("Unknown speex_echo_ctl request: ", request); + return -1; + } + return 0; +} diff --git a/src/libs/speex/libspeex/misc_bfin.h b/src/libs/speex/libspeex/misc_bfin.h new file mode 100644 index 00000000..77b082c0 --- /dev/null +++ b/src/libs/speex/libspeex/misc_bfin.h @@ -0,0 +1,54 @@ +/* Copyright (C) 2005 Analog Devices */ +/** + @file misc_bfin.h + @author Jean-Marc Valin + @brief Various compatibility routines for Speex (Blackfin version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define OVERRIDE_SPEEX_MOVE +void *speex_move (void *dest, void *src, int n) +{ + __asm__ __volatile__ + ( + "L0 = 0;\n\t" + "I0 = %0;\n\t" + "R0 = [I0++];\n\t" + "LOOP move%= LC0 = %2;\n\t" + "LOOP_BEGIN move%=;\n\t" + "[%1++] = R0 || R0 = [I0++];\n\t" + "LOOP_END move%=;\n\t" + "[%1++] = R0;\n\t" + : "=a" (src), "=a" (dest) + : "a" ((n>>2)-1), "0" (src), "1" (dest) + : "R0", "I0", "L0", "memory" + ); + return dest; +} diff --git a/src/libs/speex/libspeex/modes.c b/src/libs/speex/libspeex/modes.c new file mode 100644 index 00000000..1917ab9a --- /dev/null +++ b/src/libs/speex/libspeex/modes.c @@ -0,0 +1,367 @@ +/* Copyright (C) 2002-2006 Jean-Marc Valin + File: modes.c + + Describes the different modes of the codec + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "modes.h" +#include "ltp.h" +#include "quant_lsp.h" +#include "cb_search.h" +#include "sb_celp.h" +#include "nb_celp.h" +#include "vbr.h" +#include "arch.h" +#include <math.h> + +#ifndef NULL +#define NULL 0 +#endif + +#define EXPORT + +/* Extern declarations for all codebooks we use here */ +extern const signed char gain_cdbk_nb[]; +extern const signed char gain_cdbk_lbr[]; +extern const signed char exc_5_256_table[]; +extern const signed char exc_5_64_table[]; +extern const signed char exc_8_128_table[]; +extern const signed char exc_10_32_table[]; +extern const signed char exc_10_16_table[]; +extern const signed char exc_20_32_table[]; + + +/* Parameters for Long-Term Prediction (LTP)*/ +static const ltp_params ltp_params_nb = { + gain_cdbk_nb, + 7, + 7 +}; + +/* Parameters for Long-Term Prediction (LTP)*/ +static const ltp_params ltp_params_vlbr = { + gain_cdbk_lbr, + 5, + 0 +}; + +/* Parameters for Long-Term Prediction (LTP)*/ +static const ltp_params ltp_params_lbr = { + gain_cdbk_lbr, + 5, + 7 +}; + +/* Parameters for Long-Term Prediction (LTP)*/ +static const ltp_params ltp_params_med = { + gain_cdbk_lbr, + 5, + 7 +}; + +/* Split-VQ innovation parameters for very low bit-rate narrowband */ +static const split_cb_params split_cb_nb_vlbr = { + 10, /*subvect_size*/ + 4, /*nb_subvect*/ + exc_10_16_table, /*shape_cb*/ + 4, /*shape_bits*/ + 0, +}; + +/* Split-VQ innovation parameters for very low bit-rate narrowband */ +static const split_cb_params split_cb_nb_ulbr = { + 20, /*subvect_size*/ + 2, /*nb_subvect*/ + exc_20_32_table, /*shape_cb*/ + 5, /*shape_bits*/ + 0, +}; + +/* Split-VQ innovation parameters for low bit-rate narrowband */ +static const split_cb_params split_cb_nb_lbr = { + 10, /*subvect_size*/ + 4, /*nb_subvect*/ + exc_10_32_table, /*shape_cb*/ + 5, /*shape_bits*/ + 0, +}; + + +/* Split-VQ innovation parameters narrowband */ +static const split_cb_params split_cb_nb = { + 5, /*subvect_size*/ + 8, /*nb_subvect*/ + exc_5_64_table, /*shape_cb*/ + 6, /*shape_bits*/ + 0, +}; + +/* Split-VQ innovation parameters narrowband */ +static const split_cb_params split_cb_nb_med = { + 8, /*subvect_size*/ + 5, /*nb_subvect*/ + exc_8_128_table, /*shape_cb*/ + 7, /*shape_bits*/ + 0, +}; + +/* Split-VQ innovation for low-band wideband */ +static const split_cb_params split_cb_sb = { + 5, /*subvect_size*/ + 8, /*nb_subvect*/ + exc_5_256_table, /*shape_cb*/ + 8, /*shape_bits*/ + 0, +}; + + + +/* 2150 bps "vocoder-like" mode for comfort noise */ +static const SpeexSubmode nb_submode1 = { + 0, + 1, + 0, + 0, + /* LSP quantization */ + lsp_quant_lbr, + lsp_unquant_lbr, + /* No pitch quantization */ + forced_pitch_quant, + forced_pitch_unquant, + NULL, + /* No innovation quantization (noise only) */ + noise_codebook_quant, + noise_codebook_unquant, + NULL, + -1, + 43 +}; + +/* 3.95 kbps very low bit-rate mode */ +static const SpeexSubmode nb_submode8 = { + 0, + 1, + 0, + 0, + /*LSP quantization*/ + lsp_quant_lbr, + lsp_unquant_lbr, + /*No pitch quantization*/ + forced_pitch_quant, + forced_pitch_unquant, + NULL, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_nb_ulbr, + QCONST16(.5,15), + 79 +}; + +/* 5.95 kbps very low bit-rate mode */ +static const SpeexSubmode nb_submode2 = { + 0, + 0, + 0, + 0, + /*LSP quantization*/ + lsp_quant_lbr, + lsp_unquant_lbr, + /*No pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + &ltp_params_vlbr, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_nb_vlbr, + QCONST16(.6,15), + 119 +}; + +/* 8 kbps low bit-rate mode */ +static const SpeexSubmode nb_submode3 = { + -1, + 0, + 1, + 0, + /*LSP quantization*/ + lsp_quant_lbr, + lsp_unquant_lbr, + /*Pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + &ltp_params_lbr, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_nb_lbr, + QCONST16(.55,15), + 160 +}; + +/* 11 kbps medium bit-rate mode */ +static const SpeexSubmode nb_submode4 = { + -1, + 0, + 1, + 0, + /*LSP quantization*/ + lsp_quant_lbr, + lsp_unquant_lbr, + /*Pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + &ltp_params_med, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_nb_med, + QCONST16(.45,15), + 220 +}; + +/* 15 kbps high bit-rate mode */ +static const SpeexSubmode nb_submode5 = { + -1, + 0, + 3, + 0, + /*LSP quantization*/ + lsp_quant_nb, + lsp_unquant_nb, + /*Pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + &ltp_params_nb, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_nb, + QCONST16(.3,15), + 300 +}; + +/* 18.2 high bit-rate mode */ +static const SpeexSubmode nb_submode6 = { + -1, + 0, + 3, + 0, + /*LSP quantization*/ + lsp_quant_nb, + lsp_unquant_nb, + /*Pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + &ltp_params_nb, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_sb, + QCONST16(.2,15), + 364 +}; + +/* 24.6 kbps high bit-rate mode */ +static const SpeexSubmode nb_submode7 = { + -1, + 0, + 3, + 1, + /*LSP quantization*/ + lsp_quant_nb, + lsp_unquant_nb, + /*Pitch quantization*/ + pitch_search_3tap, + pitch_unquant_3tap, + &ltp_params_nb, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, + &split_cb_nb, + QCONST16(.1,15), + 492 +}; + + +/* Default mode for narrowband */ +static const SpeexNBMode nb_mode = { + 160, /*frameSize*/ + 40, /*subframeSize*/ + 10, /*lpcSize*/ + 17, /*pitchStart*/ + 144, /*pitchEnd*/ +#ifdef FIXED_POINT + 29491, 19661, /* gamma1, gamma2 */ +#else + 0.9, 0.6, /* gamma1, gamma2 */ +#endif + QCONST16(.0002,15), /*lpc_floor*/ + {NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7, + &nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, + 5, + {1, 8, 2, 3, 3, 4, 4, 5, 5, 6, 7} +}; + + +/* Default mode for narrowband */ +EXPORT const SpeexMode speex_nb_mode = { + &nb_mode, + nb_mode_query, + "narrowband", + 0, + 4, + &nb_encoder_init, + &nb_encoder_destroy, + &nb_encode, + &nb_decoder_init, + &nb_decoder_destroy, + &nb_decode, + &nb_encoder_ctl, + &nb_decoder_ctl, +}; + + + +EXPORT int speex_mode_query(const SpeexMode *mode, int request, void *ptr) +{ + return mode->query(mode->mode, request, ptr); +} + +#ifdef FIXED_DEBUG +long long spx_mips=0; +#endif + diff --git a/src/libs/speex/libspeex/modes.h b/src/libs/speex/libspeex/modes.h new file mode 100644 index 00000000..26e2d861 --- /dev/null +++ b/src/libs/speex/libspeex/modes.h @@ -0,0 +1,161 @@ +/* Copyright (C) 2002-2006 Jean-Marc Valin */ +/** + @file modes.h + @brief Describes the different modes of the codec +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef MODES_H +#define MODES_H + +#include <speex/speex.h> +#include <speex/speex_bits.h> +#include "arch.h" + +#define NB_SUBMODES 16 +#define NB_SUBMODE_BITS 4 + +#define SB_SUBMODES 8 +#define SB_SUBMODE_BITS 3 + +/* Used internally, NOT TO BE USED in applications */ +/** Used internally*/ +#define SPEEX_GET_PI_GAIN 100 +/** Used internally*/ +#define SPEEX_GET_EXC 101 +/** Used internally*/ +#define SPEEX_GET_INNOV 102 +/** Used internally*/ +#define SPEEX_GET_DTX_STATUS 103 +/** Used internally*/ +#define SPEEX_SET_INNOVATION_SAVE 104 +/** Used internally*/ +#define SPEEX_SET_WIDEBAND 105 + +/** Used internally*/ +#define SPEEX_GET_STACK 106 + + +/** Quantizes LSPs */ +typedef void (*lsp_quant_func)(spx_lsp_t *, spx_lsp_t *, int, SpeexBits *); + +/** Decodes quantized LSPs */ +typedef void (*lsp_unquant_func)(spx_lsp_t *, int, SpeexBits *); + + +/** Long-term predictor quantization */ +typedef int (*ltp_quant_func)(spx_word16_t *, spx_word16_t *, spx_coef_t *, spx_coef_t *, + spx_coef_t *, spx_sig_t *, const void *, int, int, spx_word16_t, + int, int, SpeexBits*, char *, spx_word16_t *, spx_word16_t *, int, int, int, spx_word32_t *); + +/** Long-term un-quantize */ +typedef void (*ltp_unquant_func)(spx_word16_t *, spx_word32_t *, int, int, spx_word16_t, const void *, int, int *, + spx_word16_t *, SpeexBits*, char*, int, int, spx_word16_t, int); + + +/** Innovation quantization function */ +typedef void (*innovation_quant_func)(spx_word16_t *, spx_coef_t *, spx_coef_t *, spx_coef_t *, const void *, int, int, + spx_sig_t *, spx_word16_t *, SpeexBits *, char *, int, int); + +/** Innovation unquantization function */ +typedef void (*innovation_unquant_func)(spx_sig_t *, const void *, int, SpeexBits*, char *, spx_int32_t *); + +/** Description of a Speex sub-mode (wither narrowband or wideband */ +typedef struct SpeexSubmode { + int lbr_pitch; /**< Set to -1 for "normal" modes, otherwise encode pitch using a global pitch and allowing a +- lbr_pitch variation (for low not-rates)*/ + int forced_pitch_gain; /**< Use the same (forced) pitch gain for all sub-frames */ + int have_subframe_gain; /**< Number of bits to use as sub-frame innovation gain */ + int double_codebook; /**< Apply innovation quantization twice for higher quality (and higher bit-rate)*/ + /*LSP functions*/ + lsp_quant_func lsp_quant; /**< LSP quantization function */ + lsp_unquant_func lsp_unquant; /**< LSP unquantization function */ + + /*Long-term predictor functions*/ + ltp_quant_func ltp_quant; /**< Long-term predictor (pitch) quantizer */ + ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */ + const void *ltp_params; /**< Pitch parameters (options) */ + + /*Quantization of innovation*/ + innovation_quant_func innovation_quant; /**< Innovation quantization */ + innovation_unquant_func innovation_unquant; /**< Innovation un-quantization */ + const void *innovation_params; /**< Innovation quantization parameters*/ + + spx_word16_t comb_gain; /**< Gain of enhancer comb filter */ + + int bits_per_frame; /**< Number of bits per frame after encoding*/ +} SpeexSubmode; + +/** Struct defining the encoding/decoding mode*/ +typedef struct SpeexNBMode { + int frameSize; /**< Size of frames used for encoding */ + int subframeSize; /**< Size of sub-frames used for encoding */ + int lpcSize; /**< Order of LPC filter */ + int pitchStart; /**< Smallest pitch value allowed */ + int pitchEnd; /**< Largest pitch value allowed */ + + spx_word16_t gamma1; /**< Perceptual filter parameter #1 */ + spx_word16_t gamma2; /**< Perceptual filter parameter #2 */ + spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */ + + const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */ + int defaultSubmode; /**< Default sub-mode to use when encoding */ + int quality_map[11]; /**< Mode corresponding to each quality setting */ +} SpeexNBMode; + + +/** Struct defining the encoding/decoding mode for SB-CELP (wideband) */ +typedef struct SpeexSBMode { + const SpeexMode *nb_mode; /**< Embedded narrowband mode */ + int frameSize; /**< Size of frames used for encoding */ + int subframeSize; /**< Size of sub-frames used for encoding */ + int lpcSize; /**< Order of LPC filter */ + spx_word16_t gamma1; /**< Perceptual filter parameter #1 */ + spx_word16_t gamma2; /**< Perceptual filter parameter #1 */ + spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */ + spx_word16_t folding_gain; + + const SpeexSubmode *submodes[SB_SUBMODES]; /**< Sub-mode data for the mode */ + int defaultSubmode; /**< Default sub-mode to use when encoding */ + int low_quality_map[11]; /**< Mode corresponding to each quality setting */ + int quality_map[11]; /**< Mode corresponding to each quality setting */ +#ifndef DISABLE_VBR + const float (*vbr_thresh)[11]; +#endif + int nb_modes; +} SpeexSBMode; + +int speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits); +int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out); + +int nb_mode_query(const void *mode, int request, void *ptr); +int wb_mode_query(const void *mode, int request, void *ptr); + +#endif diff --git a/src/libs/speex/libspeex/modes_wb.c b/src/libs/speex/libspeex/modes_wb.c new file mode 100644 index 00000000..5701b2b4 --- /dev/null +++ b/src/libs/speex/libspeex/modes_wb.c @@ -0,0 +1,302 @@ +/* Copyright (C) 2002-2007 Jean-Marc Valin + File: modes.c + + Describes the wideband modes of the codec + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "modes.h" +#include "ltp.h" +#include "quant_lsp.h" +#include "cb_search.h" +#include "sb_celp.h" +#include "nb_celp.h" +#include "vbr.h" +#include "arch.h" +#include <math.h> +#include "os_support.h" + + +#ifndef NULL +#define NULL 0 +#endif + +#define EXPORT + +EXPORT const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode}; + +extern const signed char hexc_table[]; +extern const signed char hexc_10_32_table[]; + +#ifndef DISABLE_WIDEBAND + +/* Split-VQ innovation for high-band wideband */ +static const split_cb_params split_cb_high = { + 8, /*subvect_size*/ + 5, /*nb_subvect*/ + hexc_table, /*shape_cb*/ + 7, /*shape_bits*/ + 1, +}; + + +/* Split-VQ innovation for high-band wideband */ +static const split_cb_params split_cb_high_lbr = { + 10, /*subvect_size*/ + 4, /*nb_subvect*/ + hexc_10_32_table, /*shape_cb*/ + 5, /*shape_bits*/ + 0, +}; + +#endif + + +static const SpeexSubmode wb_submode1 = { + 0, + 0, + 1, + 0, + /*LSP quantization*/ + lsp_quant_high, + lsp_unquant_high, + /*Pitch quantization*/ + NULL, + NULL, + NULL, + /*No innovation quantization*/ + NULL, + NULL, + NULL, + -1, + 36 +}; + + +static const SpeexSubmode wb_submode2 = { + 0, + 0, + 1, + 0, + /*LSP quantization*/ + lsp_quant_high, + lsp_unquant_high, + /*Pitch quantization*/ + NULL, + NULL, + NULL, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, +#ifdef DISABLE_WIDEBAND + NULL, +#else + &split_cb_high_lbr, +#endif + -1, + 112 +}; + + +static const SpeexSubmode wb_submode3 = { + 0, + 0, + 1, + 0, + /*LSP quantization*/ + lsp_quant_high, + lsp_unquant_high, + /*Pitch quantization*/ + NULL, + NULL, + NULL, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, +#ifdef DISABLE_WIDEBAND + NULL, +#else + &split_cb_high, +#endif + -1, + 192 +}; + +static const SpeexSubmode wb_submode4 = { + 0, + 0, + 1, + 1, + /*LSP quantization*/ + lsp_quant_high, + lsp_unquant_high, + /*Pitch quantization*/ + NULL, + NULL, + NULL, + /*Innovation quantization*/ + split_cb_search_shape_sign, + split_cb_shape_sign_unquant, +#ifdef DISABLE_WIDEBAND + NULL, +#else + &split_cb_high, +#endif + -1, + 352 +}; + + +/* Split-band wideband CELP mode*/ +static const SpeexSBMode sb_wb_mode = { + &speex_nb_mode, + 160, /*frameSize*/ + 40, /*subframeSize*/ + 8, /*lpcSize*/ +#ifdef FIXED_POINT + 29491, 19661, /* gamma1, gamma2 */ +#else + 0.9, 0.6, /* gamma1, gamma2 */ +#endif + QCONST16(.0002,15), /*lpc_floor*/ + QCONST16(0.9f,15), + {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL}, + 3, + {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7}, + {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4}, +#ifndef DISABLE_VBR + vbr_hb_thresh, +#endif + 5 +}; + + +EXPORT const SpeexMode speex_wb_mode = { + &sb_wb_mode, + wb_mode_query, + "wideband (sub-band CELP)", + 1, + 4, + &sb_encoder_init, + &sb_encoder_destroy, + &sb_encode, + &sb_decoder_init, + &sb_decoder_destroy, + &sb_decode, + &sb_encoder_ctl, + &sb_decoder_ctl, +}; + + + +/* "Ultra-wideband" mode stuff */ + + + +/* Split-band "ultra-wideband" (32 kbps) CELP mode*/ +static const SpeexSBMode sb_uwb_mode = { + &speex_wb_mode, + 320, /*frameSize*/ + 80, /*subframeSize*/ + 8, /*lpcSize*/ +#ifdef FIXED_POINT + 29491, 19661, /* gamma1, gamma2 */ +#else + 0.9, 0.6, /* gamma1, gamma2 */ +#endif + QCONST16(.0002,15), /*lpc_floor*/ + QCONST16(0.7f,15), + {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL}, + 1, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, +#ifndef DISABLE_VBR + vbr_uhb_thresh, +#endif + 2 +}; + +int wb_mode_query(const void *mode, int request, void *ptr) +{ + const SpeexSBMode *m = (const SpeexSBMode*)mode; + + switch (request) + { + case SPEEX_MODE_FRAME_SIZE: + *((int*)ptr)=2*m->frameSize; + break; + case SPEEX_SUBMODE_BITS_PER_FRAME: + if (*((int*)ptr)==0) + *((int*)ptr) = SB_SUBMODE_BITS+1; + else if (m->submodes[*((int*)ptr)]==NULL) + *((int*)ptr) = -1; + else + *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame; + break; + default: + speex_warning_int("Unknown wb_mode_query request: ", request); + return -1; + } + return 0; +} + + +EXPORT const SpeexMode speex_uwb_mode = { + &sb_uwb_mode, + wb_mode_query, + "ultra-wideband (sub-band CELP)", + 2, + 4, + &sb_encoder_init, + &sb_encoder_destroy, + &sb_encode, + &sb_decoder_init, + &sb_decoder_destroy, + &sb_decode, + &sb_encoder_ctl, + &sb_decoder_ctl, +}; + +/* We have defined speex_lib_get_mode() as a macro in speex.h */ +#undef speex_lib_get_mode + +EXPORT const SpeexMode * speex_lib_get_mode (int mode) +{ + if (mode < 0 || mode >= SPEEX_NB_MODES) return NULL; + + return speex_mode_list[mode]; +} + + + diff --git a/src/libs/speex/libspeex/nb_celp.c b/src/libs/speex/libspeex/nb_celp.c new file mode 100644 index 00000000..9dd726a0 --- /dev/null +++ b/src/libs/speex/libspeex/nb_celp.c @@ -0,0 +1,1903 @@ +/* Copyright (C) 2002-2006 Jean-Marc Valin + File: nb_celp.c + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <math.h> +#include "nb_celp.h" +#include "lpc.h" +#include "lsp.h" +#include "ltp.h" +#include "quant_lsp.h" +#include "cb_search.h" +#include "filters.h" +#include "stack_alloc.h" +#include "vq.h" +#include <speex/speex_bits.h> +#include "vbr.h" +#include "arch.h" +#include "math_approx.h" +#include "os_support.h" +#include <speex/speex_callbacks.h> + +#ifdef VORBIS_PSYCHO +#include "vorbis_psy.h" +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#define SUBMODE(x) st->submodes[st->submodeID]->x + +/* Default size for the encoder and decoder stack (can be changed at compile time). + This does not apply when using variable-size arrays or alloca. */ +#ifndef NB_ENC_STACK +#define NB_ENC_STACK (8000*sizeof(spx_sig_t)) +#endif + +#ifndef NB_DEC_STACK +#define NB_DEC_STACK (4000*sizeof(spx_sig_t)) +#endif + + +#ifdef FIXED_POINT +const spx_word32_t ol_gain_table[32]={18900, 25150, 33468, 44536, 59265, 78865, 104946, 139653, 185838, 247297, 329081, 437913, 582736, 775454, 1031906, 1373169, 1827293, 2431601, 3235761, 4305867, 5729870, 7624808, 10146425, 13501971, 17967238, 23909222, 31816294, 42338330, 56340132, 74972501, 99766822, 132760927}; +const spx_word16_t exc_gain_quant_scal3_bound[7]={1841, 3883, 6051, 8062, 10444, 13580, 18560}; +const spx_word16_t exc_gain_quant_scal3[8]={1002, 2680, 5086, 7016, 9108, 11781, 15380, 21740}; +const spx_word16_t exc_gain_quant_scal1_bound[1]={14385}; +const spx_word16_t exc_gain_quant_scal1[2]={11546, 17224}; + +#define LSP_MARGIN 16 +#define LSP_DELTA1 6553 +#define LSP_DELTA2 1638 + +#else + +const float exc_gain_quant_scal3_bound[7]={0.112338f, 0.236980f, 0.369316f, 0.492054f, 0.637471f, 0.828874f, 1.132784f}; +const float exc_gain_quant_scal3[8]={0.061130f, 0.163546f, 0.310413f, 0.428220f, 0.555887f, 0.719055f, 0.938694f, 1.326874f}; +const float exc_gain_quant_scal1_bound[1]={0.87798f}; +const float exc_gain_quant_scal1[2]={0.70469f, 1.05127f}; + +#define LSP_MARGIN .002f +#define LSP_DELTA1 .2f +#define LSP_DELTA2 .05f + +#endif + +#ifdef VORBIS_PSYCHO +#define EXTRA_BUFFER 100 +#else +#define EXTRA_BUFFER 0 +#endif + + +#define sqr(x) ((x)*(x)) + +extern const spx_word16_t lag_window[]; +extern const spx_word16_t lpc_window[]; + +void *nb_encoder_init(const SpeexMode *m) +{ + EncState *st; + const SpeexNBMode *mode; + int i; + + mode=(const SpeexNBMode *)m->mode; + st = (EncState*)speex_alloc(sizeof(EncState)); + if (!st) + return NULL; +#if defined(VAR_ARRAYS) || defined (USE_ALLOCA) + st->stack = NULL; +#else + st->stack = (char*)speex_alloc_scratch(NB_ENC_STACK); +#endif + + st->mode=m; + + st->frameSize = mode->frameSize; + st->nbSubframes=mode->frameSize/mode->subframeSize; + st->subframeSize=mode->subframeSize; + st->windowSize = st->frameSize+st->subframeSize; + st->lpcSize = mode->lpcSize; + st->gamma1=mode->gamma1; + st->gamma2=mode->gamma2; + st->min_pitch=mode->pitchStart; + st->max_pitch=mode->pitchEnd; + st->lpc_floor = mode->lpc_floor; + + st->submodes=mode->submodes; + st->submodeID=st->submodeSelect=mode->defaultSubmode; + st->bounded_pitch = 1; + + st->encode_submode = 1; + +#ifdef VORBIS_PSYCHO + st->psy = vorbis_psy_init(8000, 256); + st->curve = (float*)speex_alloc(128*sizeof(float)); + st->old_curve = (float*)speex_alloc(128*sizeof(float)); + st->psy_window = (float*)speex_alloc(256*sizeof(float)); +#endif + + st->cumul_gain = 1024; + + /* Allocating input buffer */ + st->winBuf = (spx_word16_t*)speex_alloc((st->windowSize-st->frameSize)*sizeof(spx_word16_t)); + /* Allocating excitation buffer */ + st->excBuf = (spx_word16_t*)speex_alloc((mode->frameSize+mode->pitchEnd+2)*sizeof(spx_word16_t)); + st->exc = st->excBuf + mode->pitchEnd + 2; + st->swBuf = (spx_word16_t*)speex_alloc((mode->frameSize+mode->pitchEnd+2)*sizeof(spx_word16_t)); + st->sw = st->swBuf + mode->pitchEnd + 2; + + st->window= lpc_window; + + /* Create the window for autocorrelation (lag-windowing) */ + st->lagWindow = lag_window; + + st->old_lsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); + st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); + st->first = 1; + for (i=0;i<st->lpcSize;i++) + st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); + + st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); + st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); + st->mem_sw_whole = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); + st->mem_exc = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); + st->mem_exc2 = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); + + st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t)); + st->innov_rms_save = NULL; + + st->pitch = (int*)speex_alloc((st->nbSubframes)*sizeof(int)); + +#ifndef DISABLE_VBR + st->vbr = (VBRState*)speex_alloc(sizeof(VBRState)); + vbr_init(st->vbr); + st->vbr_quality = 8; + st->vbr_enabled = 0; + st->vbr_max = 0; + st->vad_enabled = 0; + st->dtx_enabled = 0; + st->dtx_count=0; + st->abr_enabled = 0; + st->abr_drift = 0; + st->abr_drift2 = 0; +#endif /* #ifndef DISABLE_VBR */ + + st->plc_tuning = 2; + st->complexity=2; + st->sampling_rate=8000; + st->isWideband = 0; + st->highpass_enabled = 1; + +#ifdef ENABLE_VALGRIND + VALGRIND_MAKE_READABLE(st, NB_ENC_STACK); +#endif + return st; +} + +void nb_encoder_destroy(void *state) +{ + EncState *st=(EncState *)state; + /* Free all allocated memory */ +#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA)) + speex_free_scratch(st->stack); +#endif + + speex_free (st->winBuf); + speex_free (st->excBuf); + speex_free (st->old_qlsp); + speex_free (st->swBuf); + + speex_free (st->old_lsp); + speex_free (st->mem_sp); + speex_free (st->mem_sw); + speex_free (st->mem_sw_whole); + speex_free (st->mem_exc); + speex_free (st->mem_exc2); + speex_free (st->pi_gain); + speex_free (st->pitch); + +#ifndef DISABLE_VBR + vbr_destroy(st->vbr); + speex_free (st->vbr); +#endif /* #ifndef DISABLE_VBR */ + +#ifdef VORBIS_PSYCHO + vorbis_psy_destroy(st->psy); + speex_free (st->curve); + speex_free (st->old_curve); + speex_free (st->psy_window); +#endif + + /*Free state memory... should be last*/ + speex_free(st); +} + +int nb_encode(void *state, void *vin, SpeexBits *bits) +{ + EncState *st; + int i, sub, roots; + int ol_pitch; + spx_word16_t ol_pitch_coef; + spx_word32_t ol_gain; + VARDECL(spx_word16_t *ringing); + VARDECL(spx_word16_t *target); + VARDECL(spx_sig_t *innov); + VARDECL(spx_word32_t *exc32); + VARDECL(spx_mem_t *mem); + VARDECL(spx_coef_t *bw_lpc1); + VARDECL(spx_coef_t *bw_lpc2); + VARDECL(spx_coef_t *lpc); + VARDECL(spx_lsp_t *lsp); + VARDECL(spx_lsp_t *qlsp); + VARDECL(spx_lsp_t *interp_lsp); + VARDECL(spx_lsp_t *interp_qlsp); + VARDECL(spx_coef_t *interp_lpc); + VARDECL(spx_coef_t *interp_qlpc); + char *stack; + VARDECL(spx_word16_t *syn_resp); + VARDECL(spx_word16_t *real_exc); + + spx_word32_t ener=0; + spx_word16_t fine_gain; + spx_word16_t *in = (spx_word16_t*)vin; + + st=(EncState *)state; + stack=st->stack; + + ALLOC(lpc, st->lpcSize, spx_coef_t); + ALLOC(bw_lpc1, st->lpcSize, spx_coef_t); + ALLOC(bw_lpc2, st->lpcSize, spx_coef_t); + ALLOC(lsp, st->lpcSize, spx_lsp_t); + ALLOC(qlsp, st->lpcSize, spx_lsp_t); + ALLOC(interp_lsp, st->lpcSize, spx_lsp_t); + ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t); + ALLOC(interp_lpc, st->lpcSize, spx_coef_t); + ALLOC(interp_qlpc, st->lpcSize, spx_coef_t); + + /* Move signals 1 frame towards the past */ + SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, st->max_pitch+2); + SPEEX_MOVE(st->swBuf, st->swBuf+st->frameSize, st->max_pitch+2); + + if (st->highpass_enabled) + highpass(in, in, st->frameSize, (st->isWideband?HIGHPASS_WIDEBAND:HIGHPASS_NARROWBAND)|HIGHPASS_INPUT, st->mem_hp); + + { + VARDECL(spx_word16_t *w_sig); + VARDECL(spx_word16_t *autocorr); + ALLOC(w_sig, st->windowSize, spx_word16_t); + ALLOC(autocorr, st->lpcSize+1, spx_word16_t); + /* Window for analysis */ + for (i=0;i<st->windowSize-st->frameSize;i++) + w_sig[i] = EXTRACT16(SHR32(MULT16_16(st->winBuf[i],st->window[i]),SIG_SHIFT)); + for (;i<st->windowSize;i++) + w_sig[i] = EXTRACT16(SHR32(MULT16_16(in[i-st->windowSize+st->frameSize],st->window[i]),SIG_SHIFT)); + /* Compute auto-correlation */ + _spx_autocorr(w_sig, autocorr, st->lpcSize+1, st->windowSize); + autocorr[0] = ADD16(autocorr[0],MULT16_16_Q15(autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */ + + /* Lag windowing: equivalent to filtering in the power-spectrum domain */ + for (i=0;i<st->lpcSize+1;i++) + autocorr[i] = MULT16_16_Q14(autocorr[i],st->lagWindow[i]); + + /* Levinson-Durbin */ + _spx_lpc(lpc, autocorr, st->lpcSize); + /* LPC to LSPs (x-domain) transform */ + roots=lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA1, stack); + /* Check if we found all the roots */ + if (roots!=st->lpcSize) + { + /*If we can't find all LSP's, do some damage control and use previous filter*/ + for (i=0;i<st->lpcSize;i++) + { + lsp[i]=st->old_lsp[i]; + } + } + } + + + + + /* Whole frame analysis (open-loop estimation of pitch and excitation gain) */ + { + int diff = st->windowSize-st->frameSize; + if (st->first) + for (i=0;i<st->lpcSize;i++) + interp_lsp[i] = lsp[i]; + else + lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, st->nbSubframes, st->nbSubframes<<1); + + lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN); + + /* Compute interpolated LPCs (unquantized) for whole frame*/ + lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack); + + + /*Open-loop pitch*/ + if (!st->submodes[st->submodeID] || (st->complexity>2 && SUBMODE(have_subframe_gain)<3) || SUBMODE(forced_pitch_gain) || SUBMODE(lbr_pitch) != -1 +#ifndef DISABLE_VBR + || st->vbr_enabled || st->vad_enabled +#endif + ) + { + int nol_pitch[6]; + spx_word16_t nol_pitch_coef[6]; + + bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize); + bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize); + + SPEEX_COPY(st->sw, st->winBuf, diff); + SPEEX_COPY(st->sw+diff, in, st->frameSize-diff); + filter_mem16(st->sw, bw_lpc1, bw_lpc2, st->sw, st->frameSize, st->lpcSize, st->mem_sw_whole, stack); + + open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize, + nol_pitch, nol_pitch_coef, 6, stack); + ol_pitch=nol_pitch[0]; + ol_pitch_coef = nol_pitch_coef[0]; + /*Try to remove pitch multiples*/ + for (i=1;i<6;i++) + { +#ifdef FIXED_POINT + if ((nol_pitch_coef[i]>MULT16_16_Q15(nol_pitch_coef[0],27853)) && +#else + if ((nol_pitch_coef[i]>.85*nol_pitch_coef[0]) && +#endif + (ABS(2*nol_pitch[i]-ol_pitch)<=2 || ABS(3*nol_pitch[i]-ol_pitch)<=3 || + ABS(4*nol_pitch[i]-ol_pitch)<=4 || ABS(5*nol_pitch[i]-ol_pitch)<=5)) + { + /*ol_pitch_coef=nol_pitch_coef[i];*/ + ol_pitch = nol_pitch[i]; + } + } + /*if (ol_pitch>50) + ol_pitch/=2;*/ + /*ol_pitch_coef = sqrt(ol_pitch_coef);*/ + + } else { + ol_pitch=0; + ol_pitch_coef=0; + } + + /*Compute "real" excitation*/ + SPEEX_COPY(st->exc, st->winBuf, diff); + SPEEX_COPY(st->exc+diff, in, st->frameSize-diff); + fir_mem16(st->exc, interp_lpc, st->exc, st->frameSize, st->lpcSize, st->mem_exc, stack); + + /* Compute open-loop excitation gain */ + { + spx_word16_t g = compute_rms16(st->exc, st->frameSize); + if (st->submodeID!=1 && ol_pitch>0) + ol_gain = MULT16_16(g, MULT16_16_Q14(QCONST16(1.1,14), + spx_sqrt(QCONST32(1.,28)-MULT16_32_Q15(QCONST16(.8,15),SHL32(MULT16_16(ol_pitch_coef,ol_pitch_coef),16))))); + else + ol_gain = SHL32(EXTEND32(g),SIG_SHIFT); + } + } + +#ifdef VORBIS_PSYCHO + SPEEX_MOVE(st->psy_window, st->psy_window+st->frameSize, 256-st->frameSize); + SPEEX_COPY(&st->psy_window[256-st->frameSize], in, st->frameSize); + compute_curve(st->psy, st->psy_window, st->curve); + /*print_vec(st->curve, 128, "curve");*/ + if (st->first) + SPEEX_COPY(st->old_curve, st->curve, 128); +#endif + + /*VBR stuff*/ +#ifndef DISABLE_VBR + if (st->vbr && (st->vbr_enabled||st->vad_enabled)) + { + float lsp_dist=0; + for (i=0;i<st->lpcSize;i++) + lsp_dist += (st->old_lsp[i] - lsp[i])*(st->old_lsp[i] - lsp[i]); + lsp_dist /= LSP_SCALING*LSP_SCALING; + + if (st->abr_enabled) + { + float qual_change=0; + if (st->abr_drift2 * st->abr_drift > 0) + { + /* Only adapt if long-term and short-term drift are the same sign */ + qual_change = -.00001*st->abr_drift/(1+st->abr_count); + if (qual_change>.05) + qual_change=.05; + if (qual_change<-.05) + qual_change=-.05; + } + st->vbr_quality += qual_change; + if (st->vbr_quality>10) + st->vbr_quality=10; + if (st->vbr_quality<0) + st->vbr_quality=0; + } + + st->relative_quality = vbr_analysis(st->vbr, in, st->frameSize, ol_pitch, GAIN_SCALING_1*ol_pitch_coef); + /*if (delta_qual<0)*/ + /* delta_qual*=.1*(3+st->vbr_quality);*/ + if (st->vbr_enabled) + { + spx_int32_t mode; + int choice=0; + float min_diff=100; + mode = 8; + while (mode) + { + int v1; + float thresh; + v1=(int)floor(st->vbr_quality); + if (v1==10) + thresh = vbr_nb_thresh[mode][v1]; + else + thresh = (st->vbr_quality-v1)*vbr_nb_thresh[mode][v1+1] + (1+v1-st->vbr_quality)*vbr_nb_thresh[mode][v1]; + if (st->relative_quality > thresh && + st->relative_quality-thresh<min_diff) + { + choice = mode; + min_diff = st->relative_quality-thresh; + } + mode--; + } + mode=choice; + if (mode==0) + { + if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20) + { + mode=1; + st->dtx_count=1; + } else { + mode=0; + st->dtx_count++; + } + } else { + st->dtx_count=0; + } + + speex_encoder_ctl(state, SPEEX_SET_MODE, &mode); + if (st->vbr_max>0) + { + spx_int32_t rate; + speex_encoder_ctl(state, SPEEX_GET_BITRATE, &rate); + if (rate > st->vbr_max) + { + rate = st->vbr_max; + speex_encoder_ctl(state, SPEEX_SET_BITRATE, &rate); + } + } + + if (st->abr_enabled) + { + spx_int32_t bitrate; + speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate); + st->abr_drift+=(bitrate-st->abr_enabled); + st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled); + st->abr_count += 1.0; + } + + } else { + /*VAD only case*/ + int mode; + if (st->relative_quality<2) + { + if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20) + { + st->dtx_count=1; + mode=1; + } else { + mode=0; + st->dtx_count++; + } + } else { + st->dtx_count = 0; + mode=st->submodeSelect; + } + /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/ + st->submodeID=mode; + } + } else { + st->relative_quality = -1; + } +#endif /* #ifndef DISABLE_VBR */ + + if (st->encode_submode) + { + /* First, transmit a zero for narrowband */ + speex_bits_pack(bits, 0, 1); + + /* Transmit the sub-mode we use for this frame */ + speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS); + + } + + /* If null mode (no transmission), just set a couple things to zero*/ + if (st->submodes[st->submodeID] == NULL) + { + for (i=0;i<st->frameSize;i++) + st->exc[i]=st->sw[i]=VERY_SMALL; + + for (i=0;i<st->lpcSize;i++) + st->mem_sw[i]=0; + st->first=1; + st->bounded_pitch = 1; + + SPEEX_COPY(st->winBuf, in+2*st->frameSize-st->windowSize, st->windowSize-st->frameSize); + + /* Clear memory (no need to really compute it) */ + for (i=0;i<st->lpcSize;i++) + st->mem_sp[i] = 0; + return 0; + + } + + /* LSP Quantization */ + if (st->first) + { + for (i=0;i<st->lpcSize;i++) + st->old_lsp[i] = lsp[i]; + } + + + /*Quantize LSPs*/ +#if 1 /*0 for unquantized*/ + SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits); +#else + for (i=0;i<st->lpcSize;i++) + qlsp[i]=lsp[i]; +#endif + + /*If we use low bit-rate pitch mode, transmit open-loop pitch*/ + if (SUBMODE(lbr_pitch)!=-1) + { + speex_bits_pack(bits, ol_pitch-st->min_pitch, 7); + } + + if (SUBMODE(forced_pitch_gain)) + { + int quant; + /* This just damps the pitch a bit, because it tends to be too aggressive when forced */ + ol_pitch_coef = MULT16_16_Q15(QCONST16(.9,15), ol_pitch_coef); +#ifdef FIXED_POINT + quant = PSHR16(MULT16_16_16(15, ol_pitch_coef),GAIN_SHIFT); +#else + quant = (int)floor(.5+15*ol_pitch_coef*GAIN_SCALING_1); +#endif + if (quant>15) + quant=15; + if (quant<0) + quant=0; + speex_bits_pack(bits, quant, 4); + ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT)); + } + + + /*Quantize and transmit open-loop excitation gain*/ +#ifdef FIXED_POINT + { + int qe = scal_quant32(ol_gain, ol_gain_table, 32); + /*ol_gain = exp(qe/3.5)*SIG_SCALING;*/ + ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]); + speex_bits_pack(bits, qe, 5); + } +#else + { + int qe = (int)(floor(.5+3.5*log(ol_gain*1.0/SIG_SCALING))); + if (qe<0) + qe=0; + if (qe>31) + qe=31; + ol_gain = exp(qe/3.5)*SIG_SCALING; + speex_bits_pack(bits, qe, 5); + } +#endif + + + + /* Special case for first frame */ + if (st->first) + { + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = qlsp[i]; + } + + /* Target signal */ + ALLOC(target, st->subframeSize, spx_word16_t); + ALLOC(innov, st->subframeSize, spx_sig_t); + ALLOC(exc32, st->subframeSize, spx_word32_t); + ALLOC(ringing, st->subframeSize, spx_word16_t); + ALLOC(syn_resp, st->subframeSize, spx_word16_t); + ALLOC(real_exc, st->subframeSize, spx_word16_t); + ALLOC(mem, st->lpcSize, spx_mem_t); + + /* Loop on sub-frames */ + for (sub=0;sub<st->nbSubframes;sub++) + { + int offset; + spx_word16_t *sw; + spx_word16_t *exc; + int pitch; + int response_bound = st->subframeSize; + + /* Offset relative to start of frame */ + offset = st->subframeSize*sub; + /* Excitation */ + exc=st->exc+offset; + /* Weighted signal */ + sw=st->sw+offset; + + /* LSP interpolation (quantized and unquantized) */ + lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes); + lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes); + + /* Make sure the filters are stable */ + lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN); + lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN); + + /* Compute interpolated LPCs (quantized and unquantized) */ + lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack); + + lsp_to_lpc(interp_qlsp, interp_qlpc, st->lpcSize, stack); + + /* Compute analysis filter gain at w=pi (for use in SB-CELP) */ + { + spx_word32_t pi_g=LPC_SCALING; + for (i=0;i<st->lpcSize;i+=2) + { + /*pi_g += -st->interp_qlpc[i] + st->interp_qlpc[i+1];*/ + pi_g = ADD32(pi_g, SUB32(EXTEND32(interp_qlpc[i+1]),EXTEND32(interp_qlpc[i]))); + } + st->pi_gain[sub] = pi_g; + } + +#ifdef VORBIS_PSYCHO + { + float curr_curve[128]; + float fact = ((float)sub+1.0f)/st->nbSubframes; + for (i=0;i<128;i++) + curr_curve[i] = (1.0f-fact)*st->old_curve[i] + fact*st->curve[i]; + curve_to_lpc(st->psy, curr_curve, bw_lpc1, bw_lpc2, 10); + } +#else + /* Compute bandwidth-expanded (unquantized) LPCs for perceptual weighting */ + bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize); + if (st->gamma2>=0) + bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize); + else + { + for (i=0;i<st->lpcSize;i++) + bw_lpc2[i]=0; + } + /*print_vec(st->bw_lpc1, 10, "bw_lpc");*/ +#endif + + /*FIXME: This will break if we change the window size */ + speex_assert(st->windowSize-st->frameSize == st->subframeSize); + if (sub==0) + { + for (i=0;i<st->subframeSize;i++) + real_exc[i] = sw[i] = st->winBuf[i]; + } else { + for (i=0;i<st->subframeSize;i++) + real_exc[i] = sw[i] = in[i+((sub-1)*st->subframeSize)]; + } + fir_mem16(real_exc, interp_qlpc, real_exc, st->subframeSize, st->lpcSize, st->mem_exc2, stack); + + if (st->complexity==0) + response_bound >>= 1; + compute_impulse_response(interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, response_bound, st->lpcSize, stack); + for (i=response_bound;i<st->subframeSize;i++) + syn_resp[i]=VERY_SMALL; + + /* Compute zero response of A(z/g1) / ( A(z/g2) * A(z) ) */ + for (i=0;i<st->lpcSize;i++) + mem[i]=SHL32(st->mem_sp[i],1); + for (i=0;i<st->subframeSize;i++) + ringing[i] = VERY_SMALL; +#ifdef SHORTCUTS2 + iir_mem16(ringing, interp_qlpc, ringing, response_bound, st->lpcSize, mem, stack); + for (i=0;i<st->lpcSize;i++) + mem[i]=SHL32(st->mem_sw[i],1); + filter_mem16(ringing, st->bw_lpc1, st->bw_lpc2, ringing, response_bound, st->lpcSize, mem, stack); + SPEEX_MEMSET(&ringing[response_bound], 0, st->subframeSize-response_bound); +#else + iir_mem16(ringing, interp_qlpc, ringing, st->subframeSize, st->lpcSize, mem, stack); + for (i=0;i<st->lpcSize;i++) + mem[i]=SHL32(st->mem_sw[i],1); + filter_mem16(ringing, bw_lpc1, bw_lpc2, ringing, st->subframeSize, st->lpcSize, mem, stack); +#endif + + /* Compute weighted signal */ + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sw[i]; + filter_mem16(sw, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, mem, stack); + + if (st->complexity==0) + for (i=0;i<st->lpcSize;i++) + st->mem_sw[i]=mem[i]; + + /* Compute target signal (saturation prevents overflows on clipped input speech) */ + for (i=0;i<st->subframeSize;i++) + target[i]=EXTRACT16(SATURATE(SUB32(sw[i],PSHR32(ringing[i],1)),32767)); + + /* Reset excitation */ + SPEEX_MEMSET(exc, 0, st->subframeSize); + + /* If we have a long-term predictor (otherwise, something's wrong) */ + speex_assert (SUBMODE(ltp_quant)); + { + int pit_min, pit_max; + /* Long-term prediction */ + if (SUBMODE(lbr_pitch) != -1) + { + /* Low bit-rate pitch handling */ + int margin; + margin = SUBMODE(lbr_pitch); + if (margin) + { + if (ol_pitch < st->min_pitch+margin-1) + ol_pitch=st->min_pitch+margin-1; + if (ol_pitch > st->max_pitch-margin) + ol_pitch=st->max_pitch-margin; + pit_min = ol_pitch-margin+1; + pit_max = ol_pitch+margin; + } else { + pit_min=pit_max=ol_pitch; + } + } else { + pit_min = st->min_pitch; + pit_max = st->max_pitch; + } + + /* Force pitch to use only the current frame if needed */ + if (st->bounded_pitch && pit_max>offset) + pit_max=offset; + + /* Perform pitch search */ + pitch = SUBMODE(ltp_quant)(target, sw, interp_qlpc, bw_lpc1, bw_lpc2, + exc32, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef, + st->lpcSize, st->subframeSize, bits, stack, + exc, syn_resp, st->complexity, 0, st->plc_tuning, &st->cumul_gain); + + st->pitch[sub]=pitch; + } + /* Quantization of innovation */ + SPEEX_MEMSET(innov, 0, st->subframeSize); + + /* FIXME: Make sure this is save from overflows (so far so good) */ + for (i=0;i<st->subframeSize;i++) + real_exc[i] = EXTRACT16(SUB32(EXTEND32(real_exc[i]), PSHR32(exc32[i],SIG_SHIFT-1))); + + ener = SHL32(EXTEND32(compute_rms16(real_exc, st->subframeSize)),SIG_SHIFT); + + /*FIXME: Should use DIV32_16 and make sure result fits in 16 bits */ +#ifdef FIXED_POINT + { + spx_word32_t f = PDIV32(ener,PSHR32(ol_gain,SIG_SHIFT)); + if (f<=32767) + fine_gain = f; + else + fine_gain = 32767; + } +#else + fine_gain = PDIV32_16(ener,PSHR32(ol_gain,SIG_SHIFT)); +#endif + /* Calculate gain correction for the sub-frame (if any) */ + if (SUBMODE(have_subframe_gain)) + { + int qe; + if (SUBMODE(have_subframe_gain)==3) + { + qe = scal_quant(fine_gain, exc_gain_quant_scal3_bound, 8); + speex_bits_pack(bits, qe, 3); + ener=MULT16_32_Q14(exc_gain_quant_scal3[qe],ol_gain); + } else { + qe = scal_quant(fine_gain, exc_gain_quant_scal1_bound, 2); + speex_bits_pack(bits, qe, 1); + ener=MULT16_32_Q14(exc_gain_quant_scal1[qe],ol_gain); + } + } else { + ener=ol_gain; + } + + /*printf ("%f %f\n", ener, ol_gain);*/ + + /* Normalize innovation */ + signal_div(target, target, ener, st->subframeSize); + + /* Quantize innovation */ + speex_assert (SUBMODE(innovation_quant)); + { + /* Codebook search */ + SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2, + SUBMODE(innovation_params), st->lpcSize, st->subframeSize, + innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook)); + + /* De-normalize innovation and update excitation */ + signal_mul(innov, innov, ener, st->subframeSize); + + for (i=0;i<st->subframeSize;i++) + exc[i] = EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767)); + + /* In some (rare) modes, we do a second search (more bits) to reduce noise even more */ + if (SUBMODE(double_codebook)) { + char *tmp_stack=stack; + VARDECL(spx_sig_t *innov2); + ALLOC(innov2, st->subframeSize, spx_sig_t); + SPEEX_MEMSET(innov2, 0, st->subframeSize); + for (i=0;i<st->subframeSize;i++) + target[i]=MULT16_16_P13(QCONST16(2.2f,13), target[i]); + SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2, + SUBMODE(innovation_params), st->lpcSize, st->subframeSize, + innov2, syn_resp, bits, stack, st->complexity, 0); + signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize); + for (i=0;i<st->subframeSize;i++) + innov[i] = ADD32(innov[i],innov2[i]); + stack = tmp_stack; + } + for (i=0;i<st->subframeSize;i++) + exc[i] = EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767)); + if (st->innov_rms_save) + { + st->innov_rms_save[sub] = compute_rms(innov, st->subframeSize); + } + } + + /* Final signal synthesis from excitation */ + iir_mem16(exc, interp_qlpc, sw, st->subframeSize, st->lpcSize, st->mem_sp, stack); + + /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */ + if (st->complexity!=0) + filter_mem16(sw, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw, stack); + + } + + /* Store the LSPs for interpolation in the next frame */ + if (st->submodeID>=1) + { + for (i=0;i<st->lpcSize;i++) + st->old_lsp[i] = lsp[i]; + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = qlsp[i]; + } + +#ifdef VORBIS_PSYCHO + if (st->submodeID>=1) + SPEEX_COPY(st->old_curve, st->curve, 128); +#endif + + if (st->submodeID==1) + { +#ifndef DISABLE_VBR + if (st->dtx_count) + speex_bits_pack(bits, 15, 4); + else +#endif + speex_bits_pack(bits, 0, 4); + } + + /* The next frame will not be the first (Duh!) */ + st->first = 0; + SPEEX_COPY(st->winBuf, in+2*st->frameSize-st->windowSize, st->windowSize-st->frameSize); + + if (SUBMODE(innovation_quant) == noise_codebook_quant || st->submodeID==0) + st->bounded_pitch = 1; + else + st->bounded_pitch = 0; + + return 1; +} + +void *nb_decoder_init(const SpeexMode *m) +{ + DecState *st; + const SpeexNBMode *mode; + int i; + + mode=(const SpeexNBMode*)m->mode; + st = (DecState *)speex_alloc(sizeof(DecState)); + if (!st) + return NULL; +#if defined(VAR_ARRAYS) || defined (USE_ALLOCA) + st->stack = NULL; +#else + st->stack = (char*)speex_alloc_scratch(NB_DEC_STACK); +#endif + + st->mode=m; + + + st->encode_submode = 1; + + st->first=1; + /* Codec parameters, should eventually have several "modes"*/ + st->frameSize = mode->frameSize; + st->nbSubframes=mode->frameSize/mode->subframeSize; + st->subframeSize=mode->subframeSize; + st->lpcSize = mode->lpcSize; + st->min_pitch=mode->pitchStart; + st->max_pitch=mode->pitchEnd; + + st->submodes=mode->submodes; + st->submodeID=mode->defaultSubmode; + + st->lpc_enh_enabled=1; + + st->excBuf = (spx_word16_t*)speex_alloc((st->frameSize + 2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t)); + st->exc = st->excBuf + 2*st->max_pitch + st->subframeSize + 6; + SPEEX_MEMSET(st->excBuf, 0, st->frameSize + st->max_pitch); + + st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); + st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); + st->mem_sp = (spx_mem_t*)speex_alloc(st->lpcSize*sizeof(spx_mem_t)); + st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t)); + st->last_pitch = 40; + st->count_lost=0; + st->pitch_gain_buf[0] = st->pitch_gain_buf[1] = st->pitch_gain_buf[2] = 0; + st->pitch_gain_buf_idx = 0; + st->seed = 1000; + + st->sampling_rate=8000; + st->last_ol_gain = 0; + + st->user_callback.func = &speex_default_user_handler; + st->user_callback.data = NULL; + for (i=0;i<16;i++) + st->speex_callbacks[i].func = NULL; + + st->voc_m1=st->voc_m2=st->voc_mean=0; + st->voc_offset=0; + st->dtx_enabled=0; + st->isWideband = 0; + st->highpass_enabled = 1; + +#ifdef ENABLE_VALGRIND + VALGRIND_MAKE_READABLE(st, NB_DEC_STACK); +#endif + return st; +} + +void nb_decoder_destroy(void *state) +{ + DecState *st; + st=(DecState*)state; + +#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA)) + speex_free_scratch(st->stack); +#endif + + speex_free (st->excBuf); + speex_free (st->interp_qlpc); + speex_free (st->old_qlsp); + speex_free (st->mem_sp); + speex_free (st->pi_gain); + + speex_free(state); +} + +#define median3(a, b, c) ((a) < (b) ? ((b) < (c) ? (b) : ((a) < (c) ? (c) : (a))) : ((c) < (b) ? (b) : ((c) < (a) ? (c) : (a)))) + +#ifdef FIXED_POINT +const spx_word16_t attenuation[10] = {32767, 31483, 27923, 22861, 17278, 12055, 7764, 4616, 2533, 1283}; +#else +const spx_word16_t attenuation[10] = {1., 0.961, 0.852, 0.698, 0.527, 0.368, 0.237, 0.141, 0.077, 0.039}; + +#endif + +static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack) +{ + int i; + int pitch_val; + spx_word16_t pitch_gain; + spx_word16_t fact; + spx_word16_t gain_med; + spx_word16_t innov_gain; + spx_word16_t noise_gain; + + if (st->count_lost<10) + fact = attenuation[st->count_lost]; + else + fact = 0; + + gain_med = median3(st->pitch_gain_buf[0], st->pitch_gain_buf[1], st->pitch_gain_buf[2]); + if (gain_med < st->last_pitch_gain) + st->last_pitch_gain = gain_med; + +#ifdef FIXED_POINT + pitch_gain = st->last_pitch_gain; + if (pitch_gain>54) + pitch_gain = 54; + pitch_gain = SHL16(pitch_gain, 9); +#else + pitch_gain = GAIN_SCALING_1*st->last_pitch_gain; + if (pitch_gain>.85) + pitch_gain=.85; +#endif + pitch_gain = MULT16_16_Q15(fact,pitch_gain) + VERY_SMALL; + /* FIXME: This was rms of innovation (not exc) */ + innov_gain = compute_rms16(st->exc, st->frameSize); + noise_gain = MULT16_16_Q15(innov_gain, MULT16_16_Q15(fact, SUB16(Q15ONE,MULT16_16_Q15(pitch_gain,pitch_gain)))); + /* Shift all buffers by one frame */ + SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, 2*st->max_pitch + st->subframeSize + 12); + + + pitch_val = st->last_pitch + SHR32((spx_int32_t)speex_rand(1+st->count_lost, &st->seed),SIG_SHIFT); + if (pitch_val > st->max_pitch) + pitch_val = st->max_pitch; + if (pitch_val < st->min_pitch) + pitch_val = st->min_pitch; + for (i=0;i<st->frameSize;i++) + { + st->exc[i]= MULT16_16_Q15(pitch_gain, (st->exc[i-pitch_val]+VERY_SMALL)) + + speex_rand(noise_gain, &st->seed); + } + + bw_lpc(QCONST16(.98,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize); + iir_mem16(&st->exc[-st->subframeSize], st->interp_qlpc, out, st->frameSize, + st->lpcSize, st->mem_sp, stack); + highpass(out, out, st->frameSize, HIGHPASS_NARROWBAND|HIGHPASS_OUTPUT, st->mem_hp); + + st->first = 0; + st->count_lost++; + st->pitch_gain_buf[st->pitch_gain_buf_idx++] = PSHR16(pitch_gain,9); + if (st->pitch_gain_buf_idx > 2) /* rollover */ + st->pitch_gain_buf_idx = 0; +} + +/* Just so we don't need to carry the complete wideband mode information */ +static const int wb_skip_table[8] = {0, 36, 112, 192, 352, 0, 0, 0}; + +int nb_decode(void *state, SpeexBits *bits, void *vout) +{ + DecState *st; + int i, sub; + int pitch; + spx_word16_t pitch_gain[3]; + spx_word32_t ol_gain=0; + int ol_pitch=0; + spx_word16_t ol_pitch_coef=0; + int best_pitch=40; + spx_word16_t best_pitch_gain=0; + int wideband; + int m; + char *stack; + VARDECL(spx_sig_t *innov); + VARDECL(spx_word32_t *exc32); + VARDECL(spx_coef_t *ak); + VARDECL(spx_lsp_t *qlsp); + spx_word16_t pitch_average=0; + + spx_word16_t *out = (spx_word16_t*)vout; + VARDECL(spx_lsp_t *interp_qlsp); + + st=(DecState*)state; + stack=st->stack; + + /* Check if we're in DTX mode*/ + if (!bits && st->dtx_enabled) + { + st->submodeID=0; + } else + { + /* If bits is NULL, consider the packet to be lost (what could we do anyway) */ + if (!bits) + { + nb_decode_lost(st, out, stack); + return 0; + } + + if (st->encode_submode) + { + + /* Search for next narrowband block (handle requests, skip wideband blocks) */ + do { + if (speex_bits_remaining(bits)<5) + return -1; + wideband = speex_bits_unpack_unsigned(bits, 1); + if (wideband) /* Skip wideband block (for compatibility) */ + { + int submode; + int advance; + advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); + /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/ + advance = wb_skip_table[submode]; + if (advance < 0) + { + speex_notify("Invalid mode encountered. The stream is corrupted."); + return -2; + } + advance -= (SB_SUBMODE_BITS+1); + speex_bits_advance(bits, advance); + + if (speex_bits_remaining(bits)<5) + return -1; + wideband = speex_bits_unpack_unsigned(bits, 1); + if (wideband) + { + advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); + /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/ + advance = wb_skip_table[submode]; + if (advance < 0) + { + speex_notify("Invalid mode encountered. The stream is corrupted."); + return -2; + } + advance -= (SB_SUBMODE_BITS+1); + speex_bits_advance(bits, advance); + wideband = speex_bits_unpack_unsigned(bits, 1); + if (wideband) + { + speex_notify("More than two wideband layers found. The stream is corrupted."); + return -2; + } + + } + } + if (speex_bits_remaining(bits)<4) + return -1; + /* FIXME: Check for overflow */ + m = speex_bits_unpack_unsigned(bits, 4); + if (m==15) /* We found a terminator */ + { + return -1; + } else if (m==14) /* Speex in-band request */ + { + int ret = speex_inband_handler(bits, st->speex_callbacks, state); + if (ret) + return ret; + } else if (m==13) /* User in-band request */ + { + int ret = st->user_callback.func(bits, state, st->user_callback.data); + if (ret) + return ret; + } else if (m>8) /* Invalid mode */ + { + speex_notify("Invalid mode encountered. The stream is corrupted."); + return -2; + } + + } while (m>8); + + /* Get the sub-mode that was used */ + st->submodeID = m; + } + + } + + /* Shift all buffers by one frame */ + SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, 2*st->max_pitch + st->subframeSize + 12); + + /* If null mode (no transmission), just set a couple things to zero*/ + if (st->submodes[st->submodeID] == NULL) + { + VARDECL(spx_coef_t *lpc); + ALLOC(lpc, st->lpcSize, spx_coef_t); + bw_lpc(QCONST16(0.93f,15), st->interp_qlpc, lpc, st->lpcSize); + { + spx_word16_t innov_gain=0; + /* FIXME: This was innov, not exc */ + innov_gain = compute_rms16(st->exc, st->frameSize); + for (i=0;i<st->frameSize;i++) + st->exc[i]=speex_rand(innov_gain, &st->seed); + } + + + st->first=1; + + /* Final signal synthesis from excitation */ + iir_mem16(st->exc, lpc, out, st->frameSize, st->lpcSize, st->mem_sp, stack); + + st->count_lost=0; + return 0; + } + + ALLOC(qlsp, st->lpcSize, spx_lsp_t); + + /* Unquantize LSPs */ + SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits); + + /*Damp memory if a frame was lost and the LSP changed too much*/ + if (st->count_lost) + { + spx_word16_t fact; + spx_word32_t lsp_dist=0; + for (i=0;i<st->lpcSize;i++) + lsp_dist = ADD32(lsp_dist, EXTEND32(ABS(st->old_qlsp[i] - qlsp[i]))); +#ifdef FIXED_POINT + fact = SHR16(19661,SHR32(lsp_dist,LSP_SHIFT+2)); +#else + fact = .6*exp(-.2*lsp_dist); +#endif + for (i=0;i<st->lpcSize;i++) + st->mem_sp[i] = MULT16_32_Q15(fact,st->mem_sp[i]); + } + + + /* Handle first frame and lost-packet case */ + if (st->first || st->count_lost) + { + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = qlsp[i]; + } + + /* Get open-loop pitch estimation for low bit-rate pitch coding */ + if (SUBMODE(lbr_pitch)!=-1) + { + ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7); + } + + if (SUBMODE(forced_pitch_gain)) + { + int quant; + quant = speex_bits_unpack_unsigned(bits, 4); + ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT)); + } + + /* Get global excitation gain */ + { + int qe; + qe = speex_bits_unpack_unsigned(bits, 5); +#ifdef FIXED_POINT + /* FIXME: Perhaps we could slightly lower the gain here when the output is going to saturate? */ + ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]); +#else + ol_gain = SIG_SCALING*exp(qe/3.5); +#endif + } + + ALLOC(ak, st->lpcSize, spx_coef_t); + ALLOC(innov, st->subframeSize, spx_sig_t); + ALLOC(exc32, st->subframeSize, spx_word32_t); + + if (st->submodeID==1) + { + int extra; + extra = speex_bits_unpack_unsigned(bits, 4); + + if (extra==15) + st->dtx_enabled=1; + else + st->dtx_enabled=0; + } + if (st->submodeID>1) + st->dtx_enabled=0; + + /*Loop on subframes */ + for (sub=0;sub<st->nbSubframes;sub++) + { + int offset; + spx_word16_t *exc; + spx_word16_t *sp; + spx_word16_t *innov_save = NULL; + spx_word16_t tmp; + + /* Offset relative to start of frame */ + offset = st->subframeSize*sub; + /* Excitation */ + exc=st->exc+offset; + /* Original signal */ + sp=out+offset; + if (st->innov_save) + innov_save = st->innov_save+offset; + + + /* Reset excitation */ + SPEEX_MEMSET(exc, 0, st->subframeSize); + + /*Adaptive codebook contribution*/ + speex_assert (SUBMODE(ltp_unquant)); + { + int pit_min, pit_max; + /* Handle pitch constraints if any */ + if (SUBMODE(lbr_pitch) != -1) + { + int margin; + margin = SUBMODE(lbr_pitch); + if (margin) + { +/* GT - need optimization? + if (ol_pitch < st->min_pitch+margin-1) + ol_pitch=st->min_pitch+margin-1; + if (ol_pitch > st->max_pitch-margin) + ol_pitch=st->max_pitch-margin; + pit_min = ol_pitch-margin+1; + pit_max = ol_pitch+margin; +*/ + pit_min = ol_pitch-margin+1; + if (pit_min < st->min_pitch) + pit_min = st->min_pitch; + pit_max = ol_pitch+margin; + if (pit_max > st->max_pitch) + pit_max = st->max_pitch; + } else { + pit_min = pit_max = ol_pitch; + } + } else { + pit_min = st->min_pitch; + pit_max = st->max_pitch; + } + + + + SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params), + st->subframeSize, &pitch, &pitch_gain[0], bits, stack, + st->count_lost, offset, st->last_pitch_gain, 0); + + /* Ensuring that things aren't blowing up as would happen if e.g. an encoder is + crafting packets to make us produce NaNs and slow down the decoder (vague DoS threat). + We can probably be even more aggressive and limit to 15000 or so. */ + sanitize_values32(exc32, NEG32(QCONST32(32000,SIG_SHIFT-1)), QCONST32(32000,SIG_SHIFT-1), st->subframeSize); + + tmp = gain_3tap_to_1tap(pitch_gain); + + pitch_average += tmp; + if ((tmp>best_pitch_gain&&ABS(2*best_pitch-pitch)>=3&&ABS(3*best_pitch-pitch)>=4&&ABS(4*best_pitch-pitch)>=5) + || (tmp>MULT16_16_Q15(QCONST16(.6,15),best_pitch_gain)&&(ABS(best_pitch-2*pitch)<3||ABS(best_pitch-3*pitch)<4||ABS(best_pitch-4*pitch)<5)) + || (MULT16_16_Q15(QCONST16(.67,15),tmp)>best_pitch_gain&&(ABS(2*best_pitch-pitch)<3||ABS(3*best_pitch-pitch)<4||ABS(4*best_pitch-pitch)<5)) ) + { + best_pitch = pitch; + if (tmp > best_pitch_gain) + best_pitch_gain = tmp; + } + } + + /* Unquantize the innovation */ + { + int q_energy; + spx_word32_t ener; + + SPEEX_MEMSET(innov, 0, st->subframeSize); + + /* Decode sub-frame gain correction */ + if (SUBMODE(have_subframe_gain)==3) + { + q_energy = speex_bits_unpack_unsigned(bits, 3); + ener = MULT16_32_Q14(exc_gain_quant_scal3[q_energy],ol_gain); + } else if (SUBMODE(have_subframe_gain)==1) + { + q_energy = speex_bits_unpack_unsigned(bits, 1); + ener = MULT16_32_Q14(exc_gain_quant_scal1[q_energy],ol_gain); + } else { + ener = ol_gain; + } + + speex_assert (SUBMODE(innovation_unquant)); + { + /*Fixed codebook contribution*/ + SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed); + /* De-normalize innovation and update excitation */ + + signal_mul(innov, innov, ener, st->subframeSize); + + /* Decode second codebook (only for some modes) */ + if (SUBMODE(double_codebook)) + { + char *tmp_stack=stack; + VARDECL(spx_sig_t *innov2); + ALLOC(innov2, st->subframeSize, spx_sig_t); + SPEEX_MEMSET(innov2, 0, st->subframeSize); + SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed); + signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize); + for (i=0;i<st->subframeSize;i++) + innov[i] = ADD32(innov[i], innov2[i]); + stack = tmp_stack; + } + for (i=0;i<st->subframeSize;i++) + exc[i]=EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767)); + /*print_vec(exc, 40, "innov");*/ + if (innov_save) + { + for (i=0;i<st->subframeSize;i++) + innov_save[i] = EXTRACT16(PSHR32(innov[i], SIG_SHIFT)); + } + } + + /*Vocoder mode*/ + if (st->submodeID==1) + { + spx_word16_t g=ol_pitch_coef; + g=MULT16_16_P14(QCONST16(1.5f,14),(g-QCONST16(.2f,6))); + if (g<0) + g=0; + if (g>GAIN_SCALING) + g=GAIN_SCALING; + + SPEEX_MEMSET(exc, 0, st->subframeSize); + while (st->voc_offset<st->subframeSize) + { + /* exc[st->voc_offset]= g*sqrt(2*ol_pitch)*ol_gain; + Not quite sure why we need the factor of two in the sqrt */ + if (st->voc_offset>=0) + exc[st->voc_offset]=MULT16_16(spx_sqrt(MULT16_16_16(2,ol_pitch)),EXTRACT16(PSHR32(MULT16_16(g,PSHR32(ol_gain,SIG_SHIFT)),6))); + st->voc_offset+=ol_pitch; + } + st->voc_offset -= st->subframeSize; + + for (i=0;i<st->subframeSize;i++) + { + spx_word16_t exci=exc[i]; + exc[i]= ADD16(ADD16(MULT16_16_Q15(QCONST16(.7f,15),exc[i]) , MULT16_16_Q15(QCONST16(.3f,15),st->voc_m1)), + SUB16(MULT16_16_Q15(Q15_ONE-MULT16_16_16(QCONST16(.85f,9),g),EXTRACT16(PSHR32(innov[i],SIG_SHIFT))), + MULT16_16_Q15(MULT16_16_16(QCONST16(.15f,9),g),EXTRACT16(PSHR32(st->voc_m2,SIG_SHIFT))) + )); + st->voc_m1 = exci; + st->voc_m2=innov[i]; + st->voc_mean = EXTRACT16(PSHR32(ADD32(MULT16_16(QCONST16(.8f,15),st->voc_mean), MULT16_16(QCONST16(.2f,15),exc[i])), 15)); + exc[i]-=st->voc_mean; + } + } + + } + } + + ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t); + + if (st->lpc_enh_enabled && SUBMODE(comb_gain)>0 && !st->count_lost) + { + multicomb(st->exc-st->subframeSize, out, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack); + multicomb(st->exc+st->subframeSize, out+2*st->subframeSize, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack); + } else { + SPEEX_COPY(out, &st->exc[-st->subframeSize], st->frameSize); + } + + /* If the last packet was lost, re-scale the excitation to obtain the same energy as encoded in ol_gain */ + if (st->count_lost) + { + spx_word16_t exc_ener; + spx_word32_t gain32; + spx_word16_t gain; + exc_ener = compute_rms16 (st->exc, st->frameSize); + gain32 = PDIV32(ol_gain, ADD16(exc_ener,1)); +#ifdef FIXED_POINT + if (gain32 > 32767) + gain32 = 32767; + gain = EXTRACT16(gain32); +#else + if (gain32 > 2) + gain32=2; + gain = gain32; +#endif + for (i=0;i<st->frameSize;i++) + { + st->exc[i] = MULT16_16_Q14(gain, st->exc[i]); + out[i]=st->exc[i-st->subframeSize]; + } + } + + /*Loop on subframes */ + for (sub=0;sub<st->nbSubframes;sub++) + { + int offset; + spx_word16_t *sp; + spx_word16_t *exc; + /* Offset relative to start of frame */ + offset = st->subframeSize*sub; + /* Original signal */ + sp=out+offset; + /* Excitation */ + exc=st->exc+offset; + + /* LSP interpolation (quantized and unquantized) */ + lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes); + + /* Make sure the LSP's are stable */ + lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN); + + /* Compute interpolated LPCs (unquantized) */ + lsp_to_lpc(interp_qlsp, ak, st->lpcSize, stack); + + /* Compute analysis filter at w=pi */ + { + spx_word32_t pi_g=LPC_SCALING; + for (i=0;i<st->lpcSize;i+=2) + { + /*pi_g += -st->interp_qlpc[i] + st->interp_qlpc[i+1];*/ + pi_g = ADD32(pi_g, SUB32(EXTEND32(ak[i+1]),EXTEND32(ak[i]))); + } + st->pi_gain[sub] = pi_g; + } + + iir_mem16(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, + st->mem_sp, stack); + + for (i=0;i<st->lpcSize;i++) + st->interp_qlpc[i] = ak[i]; + + } + + if (st->highpass_enabled) + highpass(out, out, st->frameSize, (st->isWideband?HIGHPASS_WIDEBAND:HIGHPASS_NARROWBAND)|HIGHPASS_OUTPUT, st->mem_hp); + /*for (i=0;i<st->frameSize;i++) + printf ("%d\n", (int)st->frame[i]);*/ + + /* Tracking output level */ + st->level = 1+PSHR32(ol_gain,SIG_SHIFT); + st->max_level = MAX16(MULT16_16_Q15(QCONST16(.99f,15), st->max_level), st->level); + st->min_level = MIN16(ADD16(1,MULT16_16_Q14(QCONST16(1.01f,14), st->min_level)), st->level); + if (st->max_level < st->min_level+1) + st->max_level = st->min_level+1; + /*printf ("%f %f %f %d\n", og, st->min_level, st->max_level, update);*/ + + /* Store the LSPs for interpolation in the next frame */ + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = qlsp[i]; + + /* The next frame will not be the first (Duh!) */ + st->first = 0; + st->count_lost=0; + st->last_pitch = best_pitch; +#ifdef FIXED_POINT + st->last_pitch_gain = PSHR16(pitch_average,2); +#else + st->last_pitch_gain = .25*pitch_average; +#endif + st->pitch_gain_buf[st->pitch_gain_buf_idx++] = st->last_pitch_gain; + if (st->pitch_gain_buf_idx > 2) /* rollover */ + st->pitch_gain_buf_idx = 0; + + st->last_ol_gain = ol_gain; + + return 0; +} + +int nb_encoder_ctl(void *state, int request, void *ptr) +{ + EncState *st; + st=(EncState*)state; + switch(request) + { + case SPEEX_GET_FRAME_SIZE: + (*(spx_int32_t*)ptr) = st->frameSize; + break; + case SPEEX_SET_LOW_MODE: + case SPEEX_SET_MODE: + st->submodeSelect = st->submodeID = (*(spx_int32_t*)ptr); + break; + case SPEEX_GET_LOW_MODE: + case SPEEX_GET_MODE: + (*(spx_int32_t*)ptr) = st->submodeID; + break; +#ifndef DISABLE_VBR + case SPEEX_SET_VBR: + st->vbr_enabled = (*(spx_int32_t*)ptr); + break; + case SPEEX_GET_VBR: + (*(spx_int32_t*)ptr) = st->vbr_enabled; + break; + case SPEEX_SET_VAD: + st->vad_enabled = (*(spx_int32_t*)ptr); + break; + case SPEEX_GET_VAD: + (*(spx_int32_t*)ptr) = st->vad_enabled; + break; + case SPEEX_SET_DTX: + st->dtx_enabled = (*(spx_int32_t*)ptr); + break; + case SPEEX_GET_DTX: + (*(spx_int32_t*)ptr) = st->dtx_enabled; + break; + case SPEEX_SET_ABR: + st->abr_enabled = (*(spx_int32_t*)ptr); + st->vbr_enabled = st->abr_enabled!=0; + if (st->vbr_enabled) + { + spx_int32_t i=10; + spx_int32_t rate, target; + float vbr_qual; + target = (*(spx_int32_t*)ptr); + while (i>=0) + { + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); + speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); + if (rate <= target) + break; + i--; + } + vbr_qual=i; + if (vbr_qual<0) + vbr_qual=0; + speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual); + st->abr_count=0; + st->abr_drift=0; + st->abr_drift2=0; + } + + break; + case SPEEX_GET_ABR: + (*(spx_int32_t*)ptr) = st->abr_enabled; + break; +#endif /* #ifndef DISABLE_VBR */ +#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) + case SPEEX_SET_VBR_QUALITY: + st->vbr_quality = (*(float*)ptr); + break; + case SPEEX_GET_VBR_QUALITY: + (*(float*)ptr) = st->vbr_quality; + break; +#endif /* !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */ + case SPEEX_SET_QUALITY: + { + int quality = (*(spx_int32_t*)ptr); + if (quality < 0) + quality = 0; + if (quality > 10) + quality = 10; + st->submodeSelect = st->submodeID = ((const SpeexNBMode*)(st->mode->mode))->quality_map[quality]; + } + break; + case SPEEX_SET_COMPLEXITY: + st->complexity = (*(spx_int32_t*)ptr); + if (st->complexity<0) + st->complexity=0; + break; + case SPEEX_GET_COMPLEXITY: + (*(spx_int32_t*)ptr) = st->complexity; + break; + case SPEEX_SET_BITRATE: + { + spx_int32_t i=10; + spx_int32_t rate, target; + target = (*(spx_int32_t*)ptr); + while (i>=0) + { + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); + speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); + if (rate <= target) + break; + i--; + } + } + break; + case SPEEX_GET_BITRATE: + if (st->submodes[st->submodeID]) + (*(spx_int32_t*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize; + else + (*(spx_int32_t*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize; + break; + case SPEEX_SET_SAMPLING_RATE: + st->sampling_rate = (*(spx_int32_t*)ptr); + break; + case SPEEX_GET_SAMPLING_RATE: + (*(spx_int32_t*)ptr)=st->sampling_rate; + break; + case SPEEX_RESET_STATE: + { + int i; + st->bounded_pitch = 1; + st->first = 1; + for (i=0;i<st->lpcSize;i++) + st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); + for (i=0;i<st->lpcSize;i++) + st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0; + for (i=0;i<st->frameSize+st->max_pitch+1;i++) + st->excBuf[i]=st->swBuf[i]=0; + for (i=0;i<st->windowSize-st->frameSize;i++) + st->winBuf[i]=0; + } + break; + case SPEEX_SET_SUBMODE_ENCODING: + st->encode_submode = (*(spx_int32_t*)ptr); + break; + case SPEEX_GET_SUBMODE_ENCODING: + (*(spx_int32_t*)ptr) = st->encode_submode; + break; + case SPEEX_GET_LOOKAHEAD: + (*(spx_int32_t*)ptr)=(st->windowSize-st->frameSize); + break; + case SPEEX_SET_PLC_TUNING: + st->plc_tuning = (*(spx_int32_t*)ptr); + if (st->plc_tuning>100) + st->plc_tuning=100; + break; + case SPEEX_GET_PLC_TUNING: + (*(spx_int32_t*)ptr)=(st->plc_tuning); + break; +#ifndef DISABLE_VBR + case SPEEX_SET_VBR_MAX_BITRATE: + st->vbr_max = (*(spx_int32_t*)ptr); + break; + case SPEEX_GET_VBR_MAX_BITRATE: + (*(spx_int32_t*)ptr) = st->vbr_max; + break; +#endif /* #ifndef DISABLE_VBR */ + case SPEEX_SET_HIGHPASS: + st->highpass_enabled = (*(spx_int32_t*)ptr); + break; + case SPEEX_GET_HIGHPASS: + (*(spx_int32_t*)ptr) = st->highpass_enabled; + break; + + /* This is all internal stuff past this point */ + case SPEEX_GET_PI_GAIN: + { + int i; + spx_word32_t *g = (spx_word32_t*)ptr; + for (i=0;i<st->nbSubframes;i++) + g[i]=st->pi_gain[i]; + } + break; + case SPEEX_GET_EXC: + { + int i; + for (i=0;i<st->nbSubframes;i++) + ((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize); + } + break; +#ifndef DISABLE_VBR + case SPEEX_GET_RELATIVE_QUALITY: + (*(float*)ptr)=st->relative_quality; + break; +#endif /* #ifndef DISABLE_VBR */ + case SPEEX_SET_INNOVATION_SAVE: + st->innov_rms_save = (spx_word16_t*)ptr; + break; + case SPEEX_SET_WIDEBAND: + st->isWideband = *((spx_int32_t*)ptr); + break; + case SPEEX_GET_STACK: + *((char**)ptr) = st->stack; + break; + default: + speex_warning_int("Unknown nb_ctl request: ", request); + return -1; + } + return 0; +} + +int nb_decoder_ctl(void *state, int request, void *ptr) +{ + DecState *st; + st=(DecState*)state; + switch(request) + { + case SPEEX_SET_LOW_MODE: + case SPEEX_SET_MODE: + st->submodeID = (*(spx_int32_t*)ptr); + break; + case SPEEX_GET_LOW_MODE: + case SPEEX_GET_MODE: + (*(spx_int32_t*)ptr) = st->submodeID; + break; + case SPEEX_SET_ENH: + st->lpc_enh_enabled = *((spx_int32_t*)ptr); + break; + case SPEEX_GET_ENH: + *((spx_int32_t*)ptr) = st->lpc_enh_enabled; + break; + case SPEEX_GET_FRAME_SIZE: + (*(spx_int32_t*)ptr) = st->frameSize; + break; + case SPEEX_GET_BITRATE: + if (st->submodes[st->submodeID]) + (*(spx_int32_t*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize; + else + (*(spx_int32_t*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize; + break; + case SPEEX_SET_SAMPLING_RATE: + st->sampling_rate = (*(spx_int32_t*)ptr); + break; + case SPEEX_GET_SAMPLING_RATE: + (*(spx_int32_t*)ptr)=st->sampling_rate; + break; + case SPEEX_SET_HANDLER: + { + SpeexCallback *c = (SpeexCallback*)ptr; + st->speex_callbacks[c->callback_id].func=c->func; + st->speex_callbacks[c->callback_id].data=c->data; + st->speex_callbacks[c->callback_id].callback_id=c->callback_id; + } + break; + case SPEEX_SET_USER_HANDLER: + { + SpeexCallback *c = (SpeexCallback*)ptr; + st->user_callback.func=c->func; + st->user_callback.data=c->data; + st->user_callback.callback_id=c->callback_id; + } + break; + case SPEEX_RESET_STATE: + { + int i; + for (i=0;i<st->lpcSize;i++) + st->mem_sp[i]=0; + for (i=0;i<st->frameSize + st->max_pitch + 1;i++) + st->excBuf[i]=0; + } + break; + case SPEEX_SET_SUBMODE_ENCODING: + st->encode_submode = (*(spx_int32_t*)ptr); + break; + case SPEEX_GET_SUBMODE_ENCODING: + (*(spx_int32_t*)ptr) = st->encode_submode; + break; + case SPEEX_GET_LOOKAHEAD: + (*(spx_int32_t*)ptr)=st->subframeSize; + break; + case SPEEX_SET_HIGHPASS: + st->highpass_enabled = (*(spx_int32_t*)ptr); + break; + case SPEEX_GET_HIGHPASS: + (*(spx_int32_t*)ptr) = st->highpass_enabled; + break; + /* FIXME: Convert to fixed-point and re-enable even when float API is disabled */ +#ifndef DISABLE_FLOAT_API + case SPEEX_GET_ACTIVITY: + { + float ret; + ret = log(st->level/st->min_level)/log(st->max_level/st->min_level); + if (ret>1) + ret = 1; + /* Done in a strange way to catch NaNs as well */ + if (!(ret > 0)) + ret = 0; + /*printf ("%f %f %f %f\n", st->level, st->min_level, st->max_level, ret);*/ + (*(spx_int32_t*)ptr) = (int)(100*ret); + } + break; +#endif + case SPEEX_GET_PI_GAIN: + { + int i; + spx_word32_t *g = (spx_word32_t*)ptr; + for (i=0;i<st->nbSubframes;i++) + g[i]=st->pi_gain[i]; + } + break; + case SPEEX_GET_EXC: + { + int i; + for (i=0;i<st->nbSubframes;i++) + ((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize); + } + break; + case SPEEX_GET_DTX_STATUS: + *((spx_int32_t*)ptr) = st->dtx_enabled; + break; + case SPEEX_SET_INNOVATION_SAVE: + st->innov_save = (spx_word16_t*)ptr; + break; + case SPEEX_SET_WIDEBAND: + st->isWideband = *((spx_int32_t*)ptr); + break; + case SPEEX_GET_STACK: + *((char**)ptr) = st->stack; + break; + default: + speex_warning_int("Unknown nb_ctl request: ", request); + return -1; + } + return 0; +} diff --git a/src/libs/speex/libspeex/nb_celp.h b/src/libs/speex/libspeex/nb_celp.h new file mode 100644 index 00000000..14c776ff --- /dev/null +++ b/src/libs/speex/libspeex/nb_celp.h @@ -0,0 +1,203 @@ +/* Copyright (C) 2002-2006 Jean-Marc Valin */ +/** + @file nb_celp.h + @brief Narrowband CELP encoder/decoder +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef NB_CELP_H +#define NB_CELP_H + +#include "modes.h" +#include <speex/speex_bits.h> +#include <speex/speex_callbacks.h> +#include "vbr.h" +#include "filters.h" + +#ifdef VORBIS_PSYCHO +#include "vorbis_psy.h" +#endif + +/**Structure representing the full state of the narrowband encoder*/ +typedef struct EncState { + const SpeexMode *mode; /**< Mode corresponding to the state */ + int first; /**< Is this the first frame? */ + int frameSize; /**< Size of frames */ + int subframeSize; /**< Size of sub-frames */ + int nbSubframes; /**< Number of sub-frames */ + int windowSize; /**< Analysis (LPC) window length */ + int lpcSize; /**< LPC order */ + int min_pitch; /**< Minimum pitch value allowed */ + int max_pitch; /**< Maximum pitch value allowed */ + + spx_word32_t cumul_gain; /**< Product of previously used pitch gains (Q10) */ + int bounded_pitch; /**< Next frame should not rely on previous frames for pitch */ + int ol_pitch; /**< Open-loop pitch */ + int ol_voiced; /**< Open-loop voiced/non-voiced decision */ + int *pitch; + +#ifdef VORBIS_PSYCHO + VorbisPsy *psy; + float *psy_window; + float *curve; + float *old_curve; +#endif + + spx_word16_t gamma1; /**< Perceptual filter: A(z/gamma1) */ + spx_word16_t gamma2; /**< Perceptual filter: A(z/gamma2) */ + spx_word16_t lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/ + char *stack; /**< Pseudo-stack allocation for temporary memory */ + spx_word16_t *winBuf; /**< Input buffer (original signal) */ + spx_word16_t *excBuf; /**< Excitation buffer */ + spx_word16_t *exc; /**< Start of excitation frame */ + spx_word16_t *swBuf; /**< Weighted signal buffer */ + spx_word16_t *sw; /**< Start of weighted signal frame */ + const spx_word16_t *window; /**< Temporary (Hanning) window */ + const spx_word16_t *lagWindow; /**< Window applied to auto-correlation */ + spx_lsp_t *old_lsp; /**< LSPs for previous frame */ + spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */ + spx_mem_t *mem_sp; /**< Filter memory for signal synthesis */ + spx_mem_t *mem_sw; /**< Filter memory for perceptually-weighted signal */ + spx_mem_t *mem_sw_whole; /**< Filter memory for perceptually-weighted signal (whole frame)*/ + spx_mem_t *mem_exc; /**< Filter memory for excitation (whole frame) */ + spx_mem_t *mem_exc2; /**< Filter memory for excitation (whole frame) */ + spx_mem_t mem_hp[2]; /**< High-pass filter memory */ + spx_word32_t *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */ + spx_word16_t *innov_rms_save; /**< If non-NULL, innovation RMS is copied here */ + +#ifndef DISABLE_VBR + VBRState *vbr; /**< State of the VBR data */ + float vbr_quality; /**< Quality setting for VBR encoding */ + float relative_quality; /**< Relative quality that will be needed by VBR */ + spx_int32_t vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */ + spx_int32_t vbr_max; /**< Max bit-rate allowed in VBR mode */ + int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */ + int dtx_enabled; /**< 1 for enabling DTX, 0 otherwise */ + int dtx_count; /**< Number of consecutive DTX frames */ + spx_int32_t abr_enabled; /**< ABR setting (in bps), 0 if off */ + float abr_drift; + float abr_drift2; + float abr_count; +#endif /* #ifndef DISABLE_VBR */ + + int complexity; /**< Complexity setting (0-10 from least complex to most complex) */ + spx_int32_t sampling_rate; + int plc_tuning; + int encode_submode; + const SpeexSubmode * const *submodes; /**< Sub-mode data */ + int submodeID; /**< Activated sub-mode */ + int submodeSelect; /**< Mode chosen by the user (may differ from submodeID if VAD is on) */ + int isWideband; /**< Is this used as part of the embedded wideband codec */ + int highpass_enabled; /**< Is the input filter enabled */ +} EncState; + +/**Structure representing the full state of the narrowband decoder*/ +typedef struct DecState { + const SpeexMode *mode; /**< Mode corresponding to the state */ + int first; /**< Is this the first frame? */ + int count_lost; /**< Was the last frame lost? */ + int frameSize; /**< Size of frames */ + int subframeSize; /**< Size of sub-frames */ + int nbSubframes; /**< Number of sub-frames */ + int lpcSize; /**< LPC order */ + int min_pitch; /**< Minimum pitch value allowed */ + int max_pitch; /**< Maximum pitch value allowed */ + spx_int32_t sampling_rate; + + spx_word16_t last_ol_gain; /**< Open-loop gain for previous frame */ + + char *stack; /**< Pseudo-stack allocation for temporary memory */ + spx_word16_t *excBuf; /**< Excitation buffer */ + spx_word16_t *exc; /**< Start of excitation frame */ + spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */ + spx_coef_t *interp_qlpc; /**< Interpolated quantized LPCs */ + spx_mem_t *mem_sp; /**< Filter memory for synthesis signal */ + spx_mem_t mem_hp[2]; /**< High-pass filter memory */ + spx_word32_t *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */ + spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */ + + spx_word16_t level; + spx_word16_t max_level; + spx_word16_t min_level; + + /* This is used in packet loss concealment */ + int last_pitch; /**< Pitch of last correctly decoded frame */ + spx_word16_t last_pitch_gain; /**< Pitch gain of last correctly decoded frame */ + spx_word16_t pitch_gain_buf[3]; /**< Pitch gain of last decoded frames */ + int pitch_gain_buf_idx; /**< Tail of the buffer */ + spx_int32_t seed; /** Seed used for random number generation */ + + int encode_submode; + const SpeexSubmode * const *submodes; /**< Sub-mode data */ + int submodeID; /**< Activated sub-mode */ + int lpc_enh_enabled; /**< 1 when LPC enhancer is on, 0 otherwise */ + SpeexCallback speex_callbacks[SPEEX_MAX_CALLBACKS]; + + SpeexCallback user_callback; + + /*Vocoder data*/ + spx_word16_t voc_m1; + spx_word32_t voc_m2; + spx_word16_t voc_mean; + int voc_offset; + + int dtx_enabled; + int isWideband; /**< Is this used as part of the embedded wideband codec */ + int highpass_enabled; /**< Is the input filter enabled */ +} DecState; + +/** Initializes encoder state*/ +void *nb_encoder_init(const SpeexMode *m); + +/** De-allocates encoder state resources*/ +void nb_encoder_destroy(void *state); + +/** Encodes one frame*/ +int nb_encode(void *state, void *in, SpeexBits *bits); + + +/** Initializes decoder state*/ +void *nb_decoder_init(const SpeexMode *m); + +/** De-allocates decoder state resources*/ +void nb_decoder_destroy(void *state); + +/** Decodes one frame*/ +int nb_decode(void *state, SpeexBits *bits, void *out); + +/** ioctl-like function for controlling a narrowband encoder */ +int nb_encoder_ctl(void *state, int request, void *ptr); + +/** ioctl-like function for controlling a narrowband decoder */ +int nb_decoder_ctl(void *state, int request, void *ptr); + + +#endif diff --git a/src/libs/speex/libspeex/os_support.h b/src/libs/speex/libspeex/os_support.h new file mode 100644 index 00000000..1aa45ebe --- /dev/null +++ b/src/libs/speex/libspeex/os_support.h @@ -0,0 +1,170 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: os_support.h + This is the (tiny) OS abstraction layer. Aside from math.h, this is the + only place where system headers are allowed. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef OS_SUPPORT_H +#define OS_SUPPORT_H + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef OS_SUPPORT_CUSTOM +#include "os_support_custom.h" +#endif + +#define EXPORT +/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free + NOTE: speex_alloc needs to CLEAR THE MEMORY */ +#ifndef OVERRIDE_SPEEX_ALLOC +static inline void *speex_alloc (int size) +{ + /* WARNING: this is not equivalent to malloc(). If you want to use malloc() + or your own allocator, YOU NEED TO CLEAR THE MEMORY ALLOCATED. Otherwise + you will experience strange bugs */ + return calloc(size,1); +} +#endif + +/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */ +#ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH +static inline void *speex_alloc_scratch (int size) +{ + /* Scratch space doesn't need to be cleared */ + return calloc(size,1); +} +#endif + +/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */ +#ifndef OVERRIDE_SPEEX_REALLOC +static inline void *speex_realloc (void *ptr, int size) +{ + return realloc(ptr, size); +} +#endif + +/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */ +#ifndef OVERRIDE_SPEEX_FREE +static inline void speex_free (void *ptr) +{ + free(ptr); +} +#endif + +/** Same as speex_free, except that the area is only needed inside a Speex call (might cause problem with wideband though) */ +#ifndef OVERRIDE_SPEEX_FREE_SCRATCH +static inline void speex_free_scratch (void *ptr) +{ + free(ptr); +} +#endif + +/** Copy n bytes of memory from src to dst. The 0* term provides compile-time type checking */ +#ifndef OVERRIDE_SPEEX_COPY +#define SPEEX_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) )) +#endif + +/** Copy n bytes of memory from src to dst, allowing overlapping regions. The 0* term + provides compile-time type checking */ +#ifndef OVERRIDE_SPEEX_MOVE +#define SPEEX_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) )) +#endif + +/** Set n bytes of memory to value of c, starting at address s */ +#ifndef OVERRIDE_SPEEX_MEMSET +#define SPEEX_MEMSET(dst, c, n) (memset((dst), (c), (n)*sizeof(*(dst)))) +#endif + + +#ifndef OVERRIDE_SPEEX_FATAL +static inline void _speex_fatal(const char *str, const char *file, int line) +{ + fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); + exit(1); +} +#endif + +#ifndef OVERRIDE_SPEEX_WARNING +static inline void speex_warning(const char *str) +{ +#ifndef DISABLE_WARNINGS + fprintf (stderr, "warning: %s\n", str); +#endif +} +#endif + +#ifndef OVERRIDE_SPEEX_WARNING_INT +static inline void speex_warning_int(const char *str, int val) +{ +#ifndef DISABLE_WARNINGS + fprintf (stderr, "warning: %s %d\n", str, val); +#endif +} +#endif + +#ifndef OVERRIDE_SPEEX_NOTIFY +static inline void speex_notify(const char *str) +{ +#ifndef DISABLE_NOTIFICATIONS + fprintf (stderr, "notification: %s\n", str); +#endif +} +#endif + +#ifndef OVERRIDE_SPEEX_PUTC +/** Speex wrapper for putc */ +static inline void _speex_putc(int ch, void *file) +{ + FILE *f = (FILE *)file; + fprintf(f, "%c", ch); +} +#endif + +#define speex_fatal(str) _speex_fatal(str, __FILE__, __LINE__); +#define speex_assert(cond) {if (!(cond)) {speex_fatal("assertion failed: " #cond);}} + +#ifndef RELEASE +static inline void print_vec(float *vec, int len, char *name) +{ + int i; + printf ("%s ", name); + for (i=0;i<len;i++) + printf (" %f", vec[i]); + printf ("\n"); +} +#endif + +#endif + diff --git a/src/libs/speex/libspeex/preprocess.c b/src/libs/speex/libspeex/preprocess.c new file mode 100644 index 00000000..130d5bfb --- /dev/null +++ b/src/libs/speex/libspeex/preprocess.c @@ -0,0 +1,1220 @@ +/* Copyright (C) 2003 Epic Games (written by Jean-Marc Valin) + Copyright (C) 2004-2006 Epic Games + + File: preprocess.c + Preprocessor with denoising based on the algorithm by Ephraim and Malah + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +/* + Recommended papers: + + Y. Ephraim and D. Malah, "Speech enhancement using minimum mean-square error + short-time spectral amplitude estimator". IEEE Transactions on Acoustics, + Speech and Signal Processing, vol. ASSP-32, no. 6, pp. 1109-1121, 1984. + + Y. Ephraim and D. Malah, "Speech enhancement using minimum mean-square error + log-spectral amplitude estimator". IEEE Transactions on Acoustics, Speech and + Signal Processing, vol. ASSP-33, no. 2, pp. 443-445, 1985. + + I. Cohen and B. Berdugo, "Speech enhancement for non-stationary noise environments". + Signal Processing, vol. 81, no. 2, pp. 2403-2418, 2001. + + Stefan Gustafsson, Rainer Martin, Peter Jax, and Peter Vary. "A psychoacoustic + approach to combined acoustic echo cancellation and noise reduction". IEEE + Transactions on Speech and Audio Processing, 2002. + + J.-M. Valin, J. Rouat, and F. Michaud, "Microphone array post-filter for separation + of simultaneous non-stationary sources". In Proceedings IEEE International + Conference on Acoustics, Speech, and Signal Processing, 2004. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <math.h> +#include "speex/speex_preprocess.h" +#include "speex/speex_echo.h" +#include "arch.h" +#include "fftwrap.h" +#include "filterbank.h" +#include "math_approx.h" +#include "os_support.h" + +#ifndef M_PI +#define M_PI 3.14159263 +#endif + +#define LOUDNESS_EXP 5.f +#define AMP_SCALE .001f +#define AMP_SCALE_1 1000.f + +#define NB_BANDS 24 + +#define SPEECH_PROB_START_DEFAULT QCONST16(0.35f,15) +#define SPEECH_PROB_CONTINUE_DEFAULT QCONST16(0.20f,15) +#define NOISE_SUPPRESS_DEFAULT -15 +#define ECHO_SUPPRESS_DEFAULT -40 +#define ECHO_SUPPRESS_ACTIVE_DEFAULT -15 + +#ifndef NULL +#define NULL 0 +#endif + +#define SQR(x) ((x)*(x)) +#define SQR16(x) (MULT16_16((x),(x))) +#define SQR16_Q15(x) (MULT16_16_Q15((x),(x))) + +#define EXPORT +#ifdef FIXED_POINT +static inline spx_word16_t DIV32_16_Q8(spx_word32_t a, spx_word32_t b) +{ + if (SHR32(a,7) >= b) + { + return 32767; + } else { + if (b>=QCONST32(1,23)) + { + a = SHR32(a,8); + b = SHR32(b,8); + } + if (b>=QCONST32(1,19)) + { + a = SHR32(a,4); + b = SHR32(b,4); + } + if (b>=QCONST32(1,15)) + { + a = SHR32(a,4); + b = SHR32(b,4); + } + a = SHL32(a,8); + return PDIV32_16(a,b); + } + +} +static inline spx_word16_t DIV32_16_Q15(spx_word32_t a, spx_word32_t b) +{ + if (SHR32(a,15) >= b) + { + return 32767; + } else { + if (b>=QCONST32(1,23)) + { + a = SHR32(a,8); + b = SHR32(b,8); + } + if (b>=QCONST32(1,19)) + { + a = SHR32(a,4); + b = SHR32(b,4); + } + if (b>=QCONST32(1,15)) + { + a = SHR32(a,4); + b = SHR32(b,4); + } + a = SHL32(a,15)-a; + return DIV32_16(a,b); + } +} +#define SNR_SCALING 256.f +#define SNR_SCALING_1 0.0039062f +#define SNR_SHIFT 8 + +#define FRAC_SCALING 32767.f +#define FRAC_SCALING_1 3.0518e-05 +#define FRAC_SHIFT 1 + +#define EXPIN_SCALING 2048.f +#define EXPIN_SCALING_1 0.00048828f +#define EXPIN_SHIFT 11 +#define EXPOUT_SCALING_1 1.5259e-05 + +#define NOISE_SHIFT 7 + +#else + +#define DIV32_16_Q8(a,b) ((a)/(b)) +#define DIV32_16_Q15(a,b) ((a)/(b)) +#define SNR_SCALING 1.f +#define SNR_SCALING_1 1.f +#define SNR_SHIFT 0 +#define FRAC_SCALING 1.f +#define FRAC_SCALING_1 1.f +#define FRAC_SHIFT 0 +#define NOISE_SHIFT 0 + +#define EXPIN_SCALING 1.f +#define EXPIN_SCALING_1 1.f +#define EXPOUT_SCALING_1 1.f + +#endif + +/** Speex pre-processor state. */ +struct SpeexPreprocessState_ { + /* Basic info */ + int frame_size; /**< Number of samples processed each time */ + int ps_size; /**< Number of points in the power spectrum */ + int sampling_rate; /**< Sampling rate of the input/output */ + int nbands; + FilterBank *bank; + + /* Parameters */ + int denoise_enabled; + int vad_enabled; + int dereverb_enabled; + spx_word16_t reverb_decay; + spx_word16_t reverb_level; + spx_word16_t speech_prob_start; + spx_word16_t speech_prob_continue; + int noise_suppress; + int echo_suppress; + int echo_suppress_active; + SpeexEchoState *echo_state; + + spx_word16_t speech_prob; /**< Probability last frame was speech */ + + /* DSP-related arrays */ + spx_word16_t *frame; /**< Processing frame (2*ps_size) */ + spx_word16_t *ft; /**< Processing frame in freq domain (2*ps_size) */ + spx_word32_t *ps; /**< Current power spectrum */ + spx_word16_t *gain2; /**< Adjusted gains */ + spx_word16_t *gain_floor; /**< Minimum gain allowed */ + spx_word16_t *window; /**< Analysis/Synthesis window */ + spx_word32_t *noise; /**< Noise estimate */ + spx_word32_t *reverb_estimate; /**< Estimate of reverb energy */ + spx_word32_t *old_ps; /**< Power spectrum for last frame */ + spx_word16_t *gain; /**< Ephraim Malah gain */ + spx_word16_t *prior; /**< A-priori SNR */ + spx_word16_t *post; /**< A-posteriori SNR */ + + spx_word32_t *S; /**< Smoothed power spectrum */ + spx_word32_t *Smin; /**< See Cohen paper */ + spx_word32_t *Stmp; /**< See Cohen paper */ + int *update_prob; /**< Probability of speech presence for noise update */ + + spx_word16_t *zeta; /**< Smoothed a priori SNR */ + spx_word32_t *echo_noise; + spx_word32_t *residual_echo; + + /* Misc */ + spx_word16_t *inbuf; /**< Input buffer (overlapped analysis) */ + spx_word16_t *outbuf; /**< Output buffer (for overlap and add) */ + + /* AGC stuff, only for floating point for now */ +#ifndef FIXED_POINT + int agc_enabled; + float agc_level; + float loudness_accum; + float *loudness_weight; /**< Perceptual loudness curve */ + float loudness; /**< Loudness estimate */ + float agc_gain; /**< Current AGC gain */ + float max_gain; /**< Maximum gain allowed */ + float max_increase_step; /**< Maximum increase in gain from one frame to another */ + float max_decrease_step; /**< Maximum decrease in gain from one frame to another */ + float prev_loudness; /**< Loudness of previous frame */ + float init_max; /**< Current gain limit during initialisation */ +#endif + int nb_adapt; /**< Number of frames used for adaptation so far */ + int was_speech; + int min_count; /**< Number of frames processed so far */ + void *fft_lookup; /**< Lookup table for the FFT */ +#ifdef FIXED_POINT + int frame_shift; +#endif +}; + + +static void conj_window(spx_word16_t *w, int len) +{ + int i; + for (i=0;i<len;i++) + { + spx_word16_t tmp; +#ifdef FIXED_POINT + spx_word16_t x = DIV32_16(MULT16_16(32767,i),len); +#else + spx_word16_t x = DIV32_16(MULT16_16(QCONST16(4.f,13),i),len); +#endif + int inv=0; + if (x<QCONST16(1.f,13)) + { + } else if (x<QCONST16(2.f,13)) + { + x=QCONST16(2.f,13)-x; + inv=1; + } else if (x<QCONST16(3.f,13)) + { + x=x-QCONST16(2.f,13); + inv=1; + } else { + x=QCONST16(2.f,13)-x+QCONST16(2.f,13); /* 4 - x */ + } + x = MULT16_16_Q14(QCONST16(1.271903f,14), x); + tmp = SQR16_Q15(QCONST16(.5f,15)-MULT16_16_P15(QCONST16(.5f,15),spx_cos_norm(SHL32(EXTEND32(x),2)))); + if (inv) + tmp=SUB16(Q15_ONE,tmp); + w[i]=spx_sqrt(SHL32(EXTEND32(tmp),15)); + } +} + + +#ifdef FIXED_POINT +/* This function approximates the gain function + y = gamma(1.25)^2 * M(-.25;1;-x) / sqrt(x) + which multiplied by xi/(1+xi) is the optimal gain + in the loudness domain ( sqrt[amplitude] ) + Input in Q11 format, output in Q15 +*/ +static inline spx_word32_t hypergeom_gain(spx_word32_t xx) +{ + int ind; + spx_word16_t frac; + /* Q13 table */ + static const spx_word16_t table[21] = { + 6730, 8357, 9868, 11267, 12563, 13770, 14898, + 15959, 16961, 17911, 18816, 19682, 20512, 21311, + 22082, 22827, 23549, 24250, 24931, 25594, 26241}; + ind = SHR32(xx,10); + if (ind<0) + return Q15_ONE; + if (ind>19) + return ADD32(EXTEND32(Q15_ONE),EXTEND32(DIV32_16(QCONST32(.1296,23), SHR32(xx,EXPIN_SHIFT-SNR_SHIFT)))); + frac = SHL32(xx-SHL32(ind,10),5); + return SHL32(DIV32_16(PSHR32(MULT16_16(Q15_ONE-frac,table[ind]) + MULT16_16(frac,table[ind+1]),7),(spx_sqrt(SHL32(xx,15)+6711))),7); +} + +static inline spx_word16_t qcurve(spx_word16_t x) +{ + x = MAX16(x, 1); + return DIV32_16(SHL32(EXTEND32(32767),9),ADD16(512,MULT16_16_Q15(QCONST16(.60f,15),DIV32_16(32767,x)))); +} + +/* Compute the gain floor based on different floors for the background noise and residual echo */ +static void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len) +{ + int i; + + if (noise_suppress > effective_echo_suppress) + { + spx_word16_t noise_gain, gain_ratio; + noise_gain = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(0.11513,11),noise_suppress)),1))); + gain_ratio = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(.2302585f,11),effective_echo_suppress-noise_suppress)),1))); + + /* gain_floor = sqrt [ (noise*noise_floor + echo*echo_floor) / (noise+echo) ] */ + for (i=0;i<len;i++) + gain_floor[i] = MULT16_16_Q15(noise_gain, + spx_sqrt(SHL32(EXTEND32(DIV32_16_Q15(PSHR32(noise[i],NOISE_SHIFT) + MULT16_32_Q15(gain_ratio,echo[i]), + (1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]) )),15))); + } else { + spx_word16_t echo_gain, gain_ratio; + echo_gain = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(0.11513,11),effective_echo_suppress)),1))); + gain_ratio = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(.2302585f,11),noise_suppress-effective_echo_suppress)),1))); + + /* gain_floor = sqrt [ (noise*noise_floor + echo*echo_floor) / (noise+echo) ] */ + for (i=0;i<len;i++) + gain_floor[i] = MULT16_16_Q15(echo_gain, + spx_sqrt(SHL32(EXTEND32(DIV32_16_Q15(MULT16_32_Q15(gain_ratio,PSHR32(noise[i],NOISE_SHIFT)) + echo[i], + (1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]) )),15))); + } +} + +#else +/* This function approximates the gain function + y = gamma(1.25)^2 * M(-.25;1;-x) / sqrt(x) + which multiplied by xi/(1+xi) is the optimal gain + in the loudness domain ( sqrt[amplitude] ) +*/ +static inline spx_word32_t hypergeom_gain(spx_word32_t xx) +{ + int ind; + float integer, frac; + float x; + static const float table[21] = { + 0.82157f, 1.02017f, 1.20461f, 1.37534f, 1.53363f, 1.68092f, 1.81865f, + 1.94811f, 2.07038f, 2.18638f, 2.29688f, 2.40255f, 2.50391f, 2.60144f, + 2.69551f, 2.78647f, 2.87458f, 2.96015f, 3.04333f, 3.12431f, 3.20326f}; + x = EXPIN_SCALING_1*xx; + integer = floor(2*x); + ind = (int)integer; + if (ind<0) + return FRAC_SCALING; + if (ind>19) + return FRAC_SCALING*(1+.1296/x); + frac = 2*x-integer; + return FRAC_SCALING*((1-frac)*table[ind] + frac*table[ind+1])/sqrt(x+.0001f); +} + +static inline spx_word16_t qcurve(spx_word16_t x) +{ + return 1.f/(1.f+.15f/(SNR_SCALING_1*x)); +} + +static void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len) +{ + int i; + float echo_floor; + float noise_floor; + + noise_floor = exp(.2302585f*noise_suppress); + echo_floor = exp(.2302585f*effective_echo_suppress); + + /* Compute the gain floor based on different floors for the background noise and residual echo */ + for (i=0;i<len;i++) + gain_floor[i] = FRAC_SCALING*sqrt(noise_floor*PSHR32(noise[i],NOISE_SHIFT) + echo_floor*echo[i])/sqrt(1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]); +} + +#endif +EXPORT SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate) +{ + int i; + int N, N3, N4, M; + + SpeexPreprocessState *st = (SpeexPreprocessState *)speex_alloc(sizeof(SpeexPreprocessState)); + st->frame_size = frame_size; + + /* Round ps_size down to the nearest power of two */ +#if 0 + i=1; + st->ps_size = st->frame_size; + while(1) + { + if (st->ps_size & ~i) + { + st->ps_size &= ~i; + i<<=1; + } else { + break; + } + } + + + if (st->ps_size < 3*st->frame_size/4) + st->ps_size = st->ps_size * 3 / 2; +#else + st->ps_size = st->frame_size; +#endif + + N = st->ps_size; + N3 = 2*N - st->frame_size; + N4 = st->frame_size - N3; + + st->sampling_rate = sampling_rate; + st->denoise_enabled = 1; + st->vad_enabled = 0; + st->dereverb_enabled = 0; + st->reverb_decay = 0; + st->reverb_level = 0; + st->noise_suppress = NOISE_SUPPRESS_DEFAULT; + st->echo_suppress = ECHO_SUPPRESS_DEFAULT; + st->echo_suppress_active = ECHO_SUPPRESS_ACTIVE_DEFAULT; + + st->speech_prob_start = SPEECH_PROB_START_DEFAULT; + st->speech_prob_continue = SPEECH_PROB_CONTINUE_DEFAULT; + + st->echo_state = NULL; + + st->nbands = NB_BANDS; + M = st->nbands; + st->bank = filterbank_new(M, sampling_rate, N, 1); + + st->frame = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t)); + st->window = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t)); + st->ft = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t)); + + st->ps = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->noise = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->echo_noise = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->residual_echo = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->reverb_estimate = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->old_ps = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->prior = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->post = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->gain = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->gain2 = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->gain_floor = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->zeta = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + + st->S = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); + st->Smin = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); + st->Stmp = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); + st->update_prob = (int*)speex_alloc(N*sizeof(int)); + + st->inbuf = (spx_word16_t*)speex_alloc(N3*sizeof(spx_word16_t)); + st->outbuf = (spx_word16_t*)speex_alloc(N3*sizeof(spx_word16_t)); + + conj_window(st->window, 2*N3); + for (i=2*N3;i<2*st->ps_size;i++) + st->window[i]=Q15_ONE; + + if (N4>0) + { + for (i=N3-1;i>=0;i--) + { + st->window[i+N3+N4]=st->window[i+N3]; + st->window[i+N3]=1; + } + } + for (i=0;i<N+M;i++) + { + st->noise[i]=QCONST32(1.f,NOISE_SHIFT); + st->reverb_estimate[i]=0; + st->old_ps[i]=1; + st->gain[i]=Q15_ONE; + st->post[i]=SHL16(1, SNR_SHIFT); + st->prior[i]=SHL16(1, SNR_SHIFT); + } + + for (i=0;i<N;i++) + st->update_prob[i] = 1; + for (i=0;i<N3;i++) + { + st->inbuf[i]=0; + st->outbuf[i]=0; + } +#ifndef FIXED_POINT + st->agc_enabled = 0; + st->agc_level = 8000; + st->loudness_weight = (float*)speex_alloc(N*sizeof(float)); + for (i=0;i<N;i++) + { + float ff=((float)i)*.5*sampling_rate/((float)N); + /*st->loudness_weight[i] = .5f*(1.f/(1.f+ff/8000.f))+1.f*exp(-.5f*(ff-3800.f)*(ff-3800.f)/9e5f);*/ + st->loudness_weight[i] = .35f-.35f*ff/16000.f+.73f*exp(-.5f*(ff-3800)*(ff-3800)/9e5f); + if (st->loudness_weight[i]<.01f) + st->loudness_weight[i]=.01f; + st->loudness_weight[i] *= st->loudness_weight[i]; + } + /*st->loudness = pow(AMP_SCALE*st->agc_level,LOUDNESS_EXP);*/ + st->loudness = 1e-15; + st->agc_gain = 1; + st->max_gain = 30; + st->max_increase_step = exp(0.11513f * 12.*st->frame_size / st->sampling_rate); + st->max_decrease_step = exp(-0.11513f * 40.*st->frame_size / st->sampling_rate); + st->prev_loudness = 1; + st->init_max = 1; +#endif + st->was_speech = 0; + + st->fft_lookup = spx_fft_init(2*N); + + st->nb_adapt=0; + st->min_count=0; + return st; +} + +EXPORT void speex_preprocess_state_destroy(SpeexPreprocessState *st) +{ + speex_free(st->frame); + speex_free(st->ft); + speex_free(st->ps); + speex_free(st->gain2); + speex_free(st->gain_floor); + speex_free(st->window); + speex_free(st->noise); + speex_free(st->reverb_estimate); + speex_free(st->old_ps); + speex_free(st->gain); + speex_free(st->prior); + speex_free(st->post); +#ifndef FIXED_POINT + speex_free(st->loudness_weight); +#endif + speex_free(st->echo_noise); + speex_free(st->residual_echo); + + speex_free(st->S); + speex_free(st->Smin); + speex_free(st->Stmp); + speex_free(st->update_prob); + speex_free(st->zeta); + + speex_free(st->inbuf); + speex_free(st->outbuf); + + spx_fft_destroy(st->fft_lookup); + filterbank_destroy(st->bank); + speex_free(st); +} + +/* FIXME: The AGC doesn't work yet with fixed-point*/ +#ifndef FIXED_POINT +static void speex_compute_agc(SpeexPreprocessState *st, spx_word16_t Pframe, spx_word16_t *ft) +{ + int i; + int N = st->ps_size; + float target_gain; + float loudness=1.f; + float rate; + + for (i=2;i<N;i++) + { + loudness += 2.f*N*st->ps[i]* st->loudness_weight[i]; + } + loudness=sqrt(loudness); + /*if (loudness < 2*pow(st->loudness, 1.0/LOUDNESS_EXP) && + loudness*2 > pow(st->loudness, 1.0/LOUDNESS_EXP))*/ + if (Pframe>.3f) + { + /*rate=2.0f*Pframe*Pframe/(1+st->nb_loudness_adapt);*/ + rate = .03*Pframe*Pframe; + st->loudness = (1-rate)*st->loudness + (rate)*pow(AMP_SCALE*loudness, LOUDNESS_EXP); + st->loudness_accum = (1-rate)*st->loudness_accum + rate; + if (st->init_max < st->max_gain && st->nb_adapt > 20) + st->init_max *= 1.f + .1f*Pframe*Pframe; + } + /*printf ("%f %f %f %f\n", Pframe, loudness, pow(st->loudness, 1.0f/LOUDNESS_EXP), st->loudness2);*/ + + target_gain = AMP_SCALE*st->agc_level*pow(st->loudness/(1e-4+st->loudness_accum), -1.0f/LOUDNESS_EXP); + + if ((Pframe>.5 && st->nb_adapt > 20) || target_gain < st->agc_gain) + { + if (target_gain > st->max_increase_step*st->agc_gain) + target_gain = st->max_increase_step*st->agc_gain; + if (target_gain < st->max_decrease_step*st->agc_gain && loudness < 10*st->prev_loudness) + target_gain = st->max_decrease_step*st->agc_gain; + if (target_gain > st->max_gain) + target_gain = st->max_gain; + if (target_gain > st->init_max) + target_gain = st->init_max; + + st->agc_gain = target_gain; + } + /*fprintf (stderr, "%f %f %f\n", loudness, (float)AMP_SCALE_1*pow(st->loudness, 1.0f/LOUDNESS_EXP), st->agc_gain);*/ + + for (i=0;i<2*N;i++) + ft[i] *= st->agc_gain; + st->prev_loudness = loudness; +} +#endif + +static void preprocess_analysis(SpeexPreprocessState *st, spx_int16_t *x) +{ + int i; + int N = st->ps_size; + int N3 = 2*N - st->frame_size; + int N4 = st->frame_size - N3; + spx_word32_t *ps=st->ps; + + /* 'Build' input frame */ + for (i=0;i<N3;i++) + st->frame[i]=st->inbuf[i]; + for (i=0;i<st->frame_size;i++) + st->frame[N3+i]=x[i]; + + /* Update inbuf */ + for (i=0;i<N3;i++) + st->inbuf[i]=x[N4+i]; + + /* Windowing */ + for (i=0;i<2*N;i++) + st->frame[i] = MULT16_16_Q15(st->frame[i], st->window[i]); + +#ifdef FIXED_POINT + { + spx_word16_t max_val=0; + for (i=0;i<2*N;i++) + max_val = MAX16(max_val, ABS16(st->frame[i])); + st->frame_shift = 14-spx_ilog2(EXTEND32(max_val)); + for (i=0;i<2*N;i++) + st->frame[i] = SHL16(st->frame[i], st->frame_shift); + } +#endif + + /* Perform FFT */ + spx_fft(st->fft_lookup, st->frame, st->ft); + + /* Power spectrum */ + ps[0]=MULT16_16(st->ft[0],st->ft[0]); + for (i=1;i<N;i++) + ps[i]=MULT16_16(st->ft[2*i-1],st->ft[2*i-1]) + MULT16_16(st->ft[2*i],st->ft[2*i]); + for (i=0;i<N;i++) + st->ps[i] = PSHR32(st->ps[i], 2*st->frame_shift); + + filterbank_compute_bank32(st->bank, ps, ps+N); +} + +static void update_noise_prob(SpeexPreprocessState *st) +{ + int i; + int min_range; + int N = st->ps_size; + + for (i=1;i<N-1;i++) + st->S[i] = MULT16_32_Q15(QCONST16(.8f,15),st->S[i]) + MULT16_32_Q15(QCONST16(.05f,15),st->ps[i-1]) + + MULT16_32_Q15(QCONST16(.1f,15),st->ps[i]) + MULT16_32_Q15(QCONST16(.05f,15),st->ps[i+1]); + st->S[0] = MULT16_32_Q15(QCONST16(.8f,15),st->S[0]) + MULT16_32_Q15(QCONST16(.2f,15),st->ps[0]); + st->S[N-1] = MULT16_32_Q15(QCONST16(.8f,15),st->S[N-1]) + MULT16_32_Q15(QCONST16(.2f,15),st->ps[N-1]); + + if (st->nb_adapt==1) + { + for (i=0;i<N;i++) + st->Smin[i] = st->Stmp[i] = 0; + } + + if (st->nb_adapt < 100) + min_range = 15; + else if (st->nb_adapt < 1000) + min_range = 50; + else if (st->nb_adapt < 10000) + min_range = 150; + else + min_range = 300; + if (st->min_count > min_range) + { + st->min_count = 0; + for (i=0;i<N;i++) + { + st->Smin[i] = MIN32(st->Stmp[i], st->S[i]); + st->Stmp[i] = st->S[i]; + } + } else { + for (i=0;i<N;i++) + { + st->Smin[i] = MIN32(st->Smin[i], st->S[i]); + st->Stmp[i] = MIN32(st->Stmp[i], st->S[i]); + } + } + for (i=0;i<N;i++) + { + if (MULT16_32_Q15(QCONST16(.4f,15),st->S[i]) > st->Smin[i]) + st->update_prob[i] = 1; + else + st->update_prob[i] = 0; + /*fprintf (stderr, "%f ", st->S[i]/st->Smin[i]);*/ + /*fprintf (stderr, "%f ", st->update_prob[i]);*/ + } + +} + +#define NOISE_OVERCOMPENS 1. + +void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len); + +EXPORT int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo) +{ + return speex_preprocess_run(st, x); +} + +EXPORT int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x) +{ + int i; + int M; + int N = st->ps_size; + int N3 = 2*N - st->frame_size; + int N4 = st->frame_size - N3; + spx_word32_t *ps=st->ps; + spx_word32_t Zframe; + spx_word16_t Pframe; + spx_word16_t beta, beta_1; + spx_word16_t effective_echo_suppress; + + st->nb_adapt++; + if (st->nb_adapt>20000) + st->nb_adapt = 20000; + st->min_count++; + + beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt)); + beta_1 = Q15_ONE-beta; + M = st->nbands; + /* Deal with residual echo if provided */ + if (st->echo_state) + { + speex_echo_get_residual(st->echo_state, st->residual_echo, N); +#ifndef FIXED_POINT + /* If there are NaNs or ridiculous values, it'll show up in the DC and we just reset everything to zero */ + if (!(st->residual_echo[0] >=0 && st->residual_echo[0]<N*1e9f)) + { + for (i=0;i<N;i++) + st->residual_echo[i] = 0; + } +#endif + for (i=0;i<N;i++) + st->echo_noise[i] = MAX32(MULT16_32_Q15(QCONST16(.6f,15),st->echo_noise[i]), st->residual_echo[i]); + filterbank_compute_bank32(st->bank, st->echo_noise, st->echo_noise+N); + } else { + for (i=0;i<N+M;i++) + st->echo_noise[i] = 0; + } + preprocess_analysis(st, x); + + update_noise_prob(st); + + /* Noise estimation always updated for the 10 first frames */ + /*if (st->nb_adapt<10) + { + for (i=1;i<N-1;i++) + st->update_prob[i] = 0; + } + */ + + /* Update the noise estimate for the frequencies where it can be */ + for (i=0;i<N;i++) + { + if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i], NOISE_SHIFT)) + st->noise[i] = MAX32(EXTEND32(0),MULT16_32_Q15(beta_1,st->noise[i]) + MULT16_32_Q15(beta,SHL32(st->ps[i],NOISE_SHIFT))); + } + filterbank_compute_bank32(st->bank, st->noise, st->noise+N); + + /* Special case for first frame */ + if (st->nb_adapt==1) + for (i=0;i<N+M;i++) + st->old_ps[i] = ps[i]; + + /* Compute a posteriori SNR */ + for (i=0;i<N+M;i++) + { + spx_word16_t gamma; + + /* Total noise estimate including residual echo and reverberation */ + spx_word32_t tot_noise = ADD32(ADD32(ADD32(EXTEND32(1), PSHR32(st->noise[i],NOISE_SHIFT)) , st->echo_noise[i]) , st->reverb_estimate[i]); + + /* A posteriori SNR = ps/noise - 1*/ + st->post[i] = SUB16(DIV32_16_Q8(ps[i],tot_noise), QCONST16(1.f,SNR_SHIFT)); + st->post[i]=MIN16(st->post[i], QCONST16(100.f,SNR_SHIFT)); + + /* Computing update gamma = .1 + .9*(old/(old+noise))^2 */ + gamma = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.89f,15),SQR16_Q15(DIV32_16_Q15(st->old_ps[i],ADD32(st->old_ps[i],tot_noise)))); + + /* A priori SNR update = gamma*max(0,post) + (1-gamma)*old/noise */ + st->prior[i] = EXTRACT16(PSHR32(ADD32(MULT16_16(gamma,MAX16(0,st->post[i])), MULT16_16(Q15_ONE-gamma,DIV32_16_Q8(st->old_ps[i],tot_noise))), 15)); + st->prior[i]=MIN16(st->prior[i], QCONST16(100.f,SNR_SHIFT)); + } + + /*print_vec(st->post, N+M, "");*/ + + /* Recursive average of the a priori SNR. A bit smoothed for the psd components */ + st->zeta[0] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[0]), MULT16_16(QCONST16(.3f,15),st->prior[0])),15); + for (i=1;i<N-1;i++) + st->zeta[i] = PSHR32(ADD32(ADD32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[i]), MULT16_16(QCONST16(.15f,15),st->prior[i])), + MULT16_16(QCONST16(.075f,15),st->prior[i-1])), MULT16_16(QCONST16(.075f,15),st->prior[i+1])),15); + for (i=N-1;i<N+M;i++) + st->zeta[i] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[i]), MULT16_16(QCONST16(.3f,15),st->prior[i])),15); + + /* Speech probability of presence for the entire frame is based on the average filterbank a priori SNR */ + Zframe = 0; + for (i=N;i<N+M;i++) + Zframe = ADD32(Zframe, EXTEND32(st->zeta[i])); + Pframe = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.899f,15),qcurve(DIV32_16(Zframe,st->nbands))); + + effective_echo_suppress = EXTRACT16(PSHR32(ADD32(MULT16_16(SUB16(Q15_ONE,Pframe), st->echo_suppress), MULT16_16(Pframe, st->echo_suppress_active)),15)); + + compute_gain_floor(st->noise_suppress, effective_echo_suppress, st->noise+N, st->echo_noise+N, st->gain_floor+N, M); + + /* Compute Ephraim & Malah gain speech probability of presence for each critical band (Bark scale) + Technically this is actually wrong because the EM gaim assumes a slightly different probability + distribution */ + for (i=N;i<N+M;i++) + { + /* See EM and Cohen papers*/ + spx_word32_t theta; + /* Gain from hypergeometric function */ + spx_word32_t MM; + /* Weiner filter gain */ + spx_word16_t prior_ratio; + /* a priority probability of speech presence based on Bark sub-band alone */ + spx_word16_t P1; + /* Speech absence a priori probability (considering sub-band and frame) */ + spx_word16_t q; +#ifdef FIXED_POINT + spx_word16_t tmp; +#endif + + prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT))); + theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT)); + + MM = hypergeom_gain(theta); + /* Gain with bound */ + st->gain[i] = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM))); + /* Save old Bark power spectrum */ + st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]); + + P1 = QCONST16(.199f,15)+MULT16_16_Q15(QCONST16(.8f,15),qcurve (st->zeta[i])); + q = Q15_ONE-MULT16_16_Q15(Pframe,P1); +#ifdef FIXED_POINT + theta = MIN32(theta, EXTEND32(32767)); +/*Q8*/tmp = MULT16_16_Q15((SHL32(1,SNR_SHIFT)+st->prior[i]),EXTRACT16(MIN32(Q15ONE,SHR32(spx_exp(-EXTRACT16(theta)),1)))); + tmp = MIN16(QCONST16(3.,SNR_SHIFT), tmp); /* Prevent overflows in the next line*/ +/*Q8*/tmp = EXTRACT16(PSHR32(MULT16_16(PDIV32_16(SHL32(EXTEND32(q),8),(Q15_ONE-q)),tmp),8)); + st->gain2[i]=DIV32_16(SHL32(EXTEND32(32767),SNR_SHIFT), ADD16(256,tmp)); +#else + st->gain2[i]=1/(1.f + (q/(1.f-q))*(1+st->prior[i])*exp(-theta)); +#endif + } + /* Convert the EM gains and speech prob to linear frequency */ + filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2); + filterbank_compute_psd16(st->bank,st->gain+N, st->gain); + + /* Use 1 for linear gain resolution (best) or 0 for Bark gain resolution (faster) */ + if (1) + { + filterbank_compute_psd16(st->bank,st->gain_floor+N, st->gain_floor); + + /* Compute gain according to the Ephraim-Malah algorithm -- linear frequency */ + for (i=0;i<N;i++) + { + spx_word32_t MM; + spx_word32_t theta; + spx_word16_t prior_ratio; + spx_word16_t tmp; + spx_word16_t p; + spx_word16_t g; + + /* Wiener filter gain */ + prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT))); + theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT)); + + /* Optimal estimator for loudness domain */ + MM = hypergeom_gain(theta); + /* EM gain with bound */ + g = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM))); + /* Interpolated speech probability of presence */ + p = st->gain2[i]; + + /* Constrain the gain to be close to the Bark scale gain */ + if (MULT16_16_Q15(QCONST16(.333f,15),g) > st->gain[i]) + g = MULT16_16(3,st->gain[i]); + st->gain[i] = g; + + /* Save old power spectrum */ + st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]); + + /* Apply gain floor */ + if (st->gain[i] < st->gain_floor[i]) + st->gain[i] = st->gain_floor[i]; + + /* Exponential decay model for reverberation (unused) */ + /*st->reverb_estimate[i] = st->reverb_decay*st->reverb_estimate[i] + st->reverb_decay*st->reverb_level*st->gain[i]*st->gain[i]*st->ps[i];*/ + + /* Take into account speech probability of presence (loudness domain MMSE estimator) */ + /* gain2 = [p*sqrt(gain)+(1-p)*sqrt(gain _floor) ]^2 */ + tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15))); + st->gain2[i]=SQR16_Q15(tmp); + + /* Use this if you want a log-domain MMSE estimator instead */ + /*st->gain2[i] = pow(st->gain[i], p) * pow(st->gain_floor[i],1.f-p);*/ + } + } else { + for (i=N;i<N+M;i++) + { + spx_word16_t tmp; + spx_word16_t p = st->gain2[i]; + st->gain[i] = MAX16(st->gain[i], st->gain_floor[i]); + tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15))); + st->gain2[i]=SQR16_Q15(tmp); + } + filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2); + } + + /* If noise suppression is off, don't apply the gain (but then why call this in the first place!) */ + if (!st->denoise_enabled) + { + for (i=0;i<N+M;i++) + st->gain2[i]=Q15_ONE; + } + + /* Apply computed gain */ + for (i=1;i<N;i++) + { + st->ft[2*i-1] = MULT16_16_P15(st->gain2[i],st->ft[2*i-1]); + st->ft[2*i] = MULT16_16_P15(st->gain2[i],st->ft[2*i]); + } + st->ft[0] = MULT16_16_P15(st->gain2[0],st->ft[0]); + st->ft[2*N-1] = MULT16_16_P15(st->gain2[N-1],st->ft[2*N-1]); + + /*FIXME: This *will* not work for fixed-point */ +#ifndef FIXED_POINT + if (st->agc_enabled) + speex_compute_agc(st, Pframe, st->ft); +#endif + + /* Inverse FFT with 1/N scaling */ + spx_ifft(st->fft_lookup, st->ft, st->frame); + /* Scale back to original (lower) amplitude */ + for (i=0;i<2*N;i++) + st->frame[i] = PSHR16(st->frame[i], st->frame_shift); + + /*FIXME: This *will* not work for fixed-point */ +#ifndef FIXED_POINT + if (st->agc_enabled) + { + float max_sample=0; + for (i=0;i<2*N;i++) + if (fabs(st->frame[i])>max_sample) + max_sample = fabs(st->frame[i]); + if (max_sample>28000.f) + { + float damp = 28000.f/max_sample; + for (i=0;i<2*N;i++) + st->frame[i] *= damp; + } + } +#endif + + /* Synthesis window (for WOLA) */ + for (i=0;i<2*N;i++) + st->frame[i] = MULT16_16_Q15(st->frame[i], st->window[i]); + + /* Perform overlap and add */ + for (i=0;i<N3;i++) + x[i] = st->outbuf[i] + st->frame[i]; + for (i=0;i<N4;i++) + x[N3+i] = st->frame[N3+i]; + + /* Update outbuf */ + for (i=0;i<N3;i++) + st->outbuf[i] = st->frame[st->frame_size+i]; + + /* FIXME: This VAD is a kludge */ + st->speech_prob = Pframe; + if (st->vad_enabled) + { + if (st->speech_prob > st->speech_prob_start || (st->was_speech && st->speech_prob > st->speech_prob_continue)) + { + st->was_speech=1; + return 1; + } else + { + st->was_speech=0; + return 0; + } + } else { + return 1; + } +} + +EXPORT void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x) +{ + int i; + int N = st->ps_size; + int N3 = 2*N - st->frame_size; + int M; + spx_word32_t *ps=st->ps; + + M = st->nbands; + st->min_count++; + + preprocess_analysis(st, x); + + update_noise_prob(st); + + for (i=1;i<N-1;i++) + { + if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i],NOISE_SHIFT)) + { + st->noise[i] = MULT16_32_Q15(QCONST16(.95f,15),st->noise[i]) + MULT16_32_Q15(QCONST16(.05f,15),SHL32(st->ps[i],NOISE_SHIFT)); + } + } + + for (i=0;i<N3;i++) + st->outbuf[i] = MULT16_16_Q15(x[st->frame_size-N3+i],st->window[st->frame_size+i]); + + /* Save old power spectrum */ + for (i=0;i<N+M;i++) + st->old_ps[i] = ps[i]; + + for (i=0;i<N;i++) + st->reverb_estimate[i] = MULT16_32_Q15(st->reverb_decay, st->reverb_estimate[i]); +} + + +EXPORT int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) +{ + int i; + SpeexPreprocessState *st; + st=(SpeexPreprocessState*)state; + switch(request) + { + case SPEEX_PREPROCESS_SET_DENOISE: + st->denoise_enabled = (*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_DENOISE: + (*(spx_int32_t*)ptr) = st->denoise_enabled; + break; +#ifndef FIXED_POINT + case SPEEX_PREPROCESS_SET_AGC: + st->agc_enabled = (*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_AGC: + (*(spx_int32_t*)ptr) = st->agc_enabled; + break; +#ifndef DISABLE_FLOAT_API + case SPEEX_PREPROCESS_SET_AGC_LEVEL: + st->agc_level = (*(float*)ptr); + if (st->agc_level<1) + st->agc_level=1; + if (st->agc_level>32768) + st->agc_level=32768; + break; + case SPEEX_PREPROCESS_GET_AGC_LEVEL: + (*(float*)ptr) = st->agc_level; + break; +#endif /* #ifndef DISABLE_FLOAT_API */ + case SPEEX_PREPROCESS_SET_AGC_INCREMENT: + st->max_increase_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate); + break; + case SPEEX_PREPROCESS_GET_AGC_INCREMENT: + (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_increase_step)*st->sampling_rate/st->frame_size); + break; + case SPEEX_PREPROCESS_SET_AGC_DECREMENT: + st->max_decrease_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate); + break; + case SPEEX_PREPROCESS_GET_AGC_DECREMENT: + (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_decrease_step)*st->sampling_rate/st->frame_size); + break; + case SPEEX_PREPROCESS_SET_AGC_MAX_GAIN: + st->max_gain = exp(0.11513f * (*(spx_int32_t*)ptr)); + break; + case SPEEX_PREPROCESS_GET_AGC_MAX_GAIN: + (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_gain)); + break; +#endif + case SPEEX_PREPROCESS_SET_VAD: + speex_warning("The VAD has been replaced by a hack pending a complete rewrite"); + st->vad_enabled = (*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_VAD: + (*(spx_int32_t*)ptr) = st->vad_enabled; + break; + + case SPEEX_PREPROCESS_SET_DEREVERB: + st->dereverb_enabled = (*(spx_int32_t*)ptr); + for (i=0;i<st->ps_size;i++) + st->reverb_estimate[i]=0; + break; + case SPEEX_PREPROCESS_GET_DEREVERB: + (*(spx_int32_t*)ptr) = st->dereverb_enabled; + break; + + case SPEEX_PREPROCESS_SET_DEREVERB_LEVEL: + /* FIXME: Re-enable when de-reverberation is actually enabled again */ + /*st->reverb_level = (*(float*)ptr);*/ + break; + case SPEEX_PREPROCESS_GET_DEREVERB_LEVEL: + /* FIXME: Re-enable when de-reverberation is actually enabled again */ + /*(*(float*)ptr) = st->reverb_level;*/ + break; + + case SPEEX_PREPROCESS_SET_DEREVERB_DECAY: + /* FIXME: Re-enable when de-reverberation is actually enabled again */ + /*st->reverb_decay = (*(float*)ptr);*/ + break; + case SPEEX_PREPROCESS_GET_DEREVERB_DECAY: + /* FIXME: Re-enable when de-reverberation is actually enabled again */ + /*(*(float*)ptr) = st->reverb_decay;*/ + break; + + case SPEEX_PREPROCESS_SET_PROB_START: + *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr)); + st->speech_prob_start = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100); + break; + case SPEEX_PREPROCESS_GET_PROB_START: + (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_start, 100); + break; + + case SPEEX_PREPROCESS_SET_PROB_CONTINUE: + *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr)); + st->speech_prob_continue = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100); + break; + case SPEEX_PREPROCESS_GET_PROB_CONTINUE: + (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_continue, 100); + break; + + case SPEEX_PREPROCESS_SET_NOISE_SUPPRESS: + st->noise_suppress = -ABS(*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_NOISE_SUPPRESS: + (*(spx_int32_t*)ptr) = st->noise_suppress; + break; + case SPEEX_PREPROCESS_SET_ECHO_SUPPRESS: + st->echo_suppress = -ABS(*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_ECHO_SUPPRESS: + (*(spx_int32_t*)ptr) = st->echo_suppress; + break; + case SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE: + st->echo_suppress_active = -ABS(*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE: + (*(spx_int32_t*)ptr) = st->echo_suppress_active; + break; + case SPEEX_PREPROCESS_SET_ECHO_STATE: + st->echo_state = (SpeexEchoState*)ptr; + break; + case SPEEX_PREPROCESS_GET_ECHO_STATE: + (*(SpeexEchoState**)ptr) = (SpeexEchoState*)st->echo_state; + break; +#ifndef FIXED_POINT + case SPEEX_PREPROCESS_GET_AGC_LOUDNESS: + (*(spx_int32_t*)ptr) = pow(st->loudness, 1.0/LOUDNESS_EXP); + break; + case SPEEX_PREPROCESS_GET_AGC_GAIN: + (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->agc_gain)); + break; +#endif + case SPEEX_PREPROCESS_GET_PSD_SIZE: + case SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE: + (*(spx_int32_t*)ptr) = st->ps_size; + break; + case SPEEX_PREPROCESS_GET_PSD: + for(i=0;i<st->ps_size;i++) + ((spx_int32_t *)ptr)[i] = (spx_int32_t) st->ps[i]; + break; + case SPEEX_PREPROCESS_GET_NOISE_PSD: + for(i=0;i<st->ps_size;i++) + ((spx_int32_t *)ptr)[i] = (spx_int32_t) PSHR32(st->noise[i], NOISE_SHIFT); + break; + case SPEEX_PREPROCESS_GET_PROB: + (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob, 100); + break; +#ifndef FIXED_POINT + case SPEEX_PREPROCESS_SET_AGC_TARGET: + st->agc_level = (*(spx_int32_t*)ptr); + if (st->agc_level<1) + st->agc_level=1; + if (st->agc_level>32768) + st->agc_level=32768; + break; + case SPEEX_PREPROCESS_GET_AGC_TARGET: + (*(spx_int32_t*)ptr) = st->agc_level; + break; +#endif + default: + speex_warning_int("Unknown speex_preprocess_ctl request: ", request); + return -1; + } + return 0; +} + +#ifdef FIXED_DEBUG +long long spx_mips=0; +#endif + diff --git a/src/libs/speex/libspeex/pseudofloat.h b/src/libs/speex/libspeex/pseudofloat.h new file mode 100644 index 00000000..fa841a01 --- /dev/null +++ b/src/libs/speex/libspeex/pseudofloat.h @@ -0,0 +1,379 @@ +/* Copyright (C) 2005 Jean-Marc Valin */ +/** + @file pseudofloat.h + @brief Pseudo-floating point + * This header file provides a lightweight floating point type for + * use on fixed-point platforms when a large dynamic range is + * required. The new type is not compatible with the 32-bit IEEE format, + * it is not even remotely as accurate as 32-bit floats, and is not + * even guaranteed to produce even remotely correct results for code + * other than Speex. It makes all kinds of shortcuts that are acceptable + * for Speex, but may not be acceptable for your application. You're + * quite welcome to reuse this code and improve it, but don't assume + * it works out of the box. Most likely, it doesn't. + */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef PSEUDOFLOAT_H +#define PSEUDOFLOAT_H + +#include "arch.h" +#include "os_support.h" +#include "math_approx.h" +#include <math.h> + +#ifdef FIXED_POINT + +typedef struct { + spx_int16_t m; + spx_int16_t e; +} spx_float_t; + +static const spx_float_t FLOAT_ZERO = {0,0}; +static const spx_float_t FLOAT_ONE = {16384,-14}; +static const spx_float_t FLOAT_HALF = {16384,-15}; + +#define MIN(a,b) ((a)<(b)?(a):(b)) +static inline spx_float_t PSEUDOFLOAT(spx_int32_t x) +{ + int e=0; + int sign=0; + if (x<0) + { + sign = 1; + x = -x; + } + if (x==0) + { + spx_float_t r = {0,0}; + return r; + } + e = spx_ilog2(ABS32(x))-14; + x = VSHR32(x, e); + if (sign) + { + spx_float_t r; + r.m = -x; + r.e = e; + return r; + } + else + { + spx_float_t r; + r.m = x; + r.e = e; + return r; + } +} + + +static inline spx_float_t FLOAT_ADD(spx_float_t a, spx_float_t b) +{ + spx_float_t r; + if (a.m==0) + return b; + else if (b.m==0) + return a; + if ((a).e > (b).e) + { + r.m = ((a).m>>1) + ((b).m>>MIN(15,(a).e-(b).e+1)); + r.e = (a).e+1; + } + else + { + r.m = ((b).m>>1) + ((a).m>>MIN(15,(b).e-(a).e+1)); + r.e = (b).e+1; + } + if (r.m>0) + { + if (r.m<16384) + { + r.m<<=1; + r.e-=1; + } + } else { + if (r.m>-16384) + { + r.m<<=1; + r.e-=1; + } + } + /*printf ("%f + %f = %f\n", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/ + return r; +} + +static inline spx_float_t FLOAT_SUB(spx_float_t a, spx_float_t b) +{ + spx_float_t r; + if (a.m==0) + return b; + else if (b.m==0) + return a; + if ((a).e > (b).e) + { + r.m = ((a).m>>1) - ((b).m>>MIN(15,(a).e-(b).e+1)); + r.e = (a).e+1; + } + else + { + r.m = ((a).m>>MIN(15,(b).e-(a).e+1)) - ((b).m>>1); + r.e = (b).e+1; + } + if (r.m>0) + { + if (r.m<16384) + { + r.m<<=1; + r.e-=1; + } + } else { + if (r.m>-16384) + { + r.m<<=1; + r.e-=1; + } + } + /*printf ("%f + %f = %f\n", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/ + return r; +} + +static inline int FLOAT_LT(spx_float_t a, spx_float_t b) +{ + if (a.m==0) + return b.m>0; + else if (b.m==0) + return a.m<0; + if ((a).e > (b).e) + return ((a).m>>1) < ((b).m>>MIN(15,(a).e-(b).e+1)); + else + return ((b).m>>1) > ((a).m>>MIN(15,(b).e-(a).e+1)); + +} + +static inline int FLOAT_GT(spx_float_t a, spx_float_t b) +{ + return FLOAT_LT(b,a); +} + +static inline spx_float_t FLOAT_MULT(spx_float_t a, spx_float_t b) +{ + spx_float_t r; + r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15); + r.e = (a).e+(b).e+15; + if (r.m>0) + { + if (r.m<16384) + { + r.m<<=1; + r.e-=1; + } + } else { + if (r.m>-16384) + { + r.m<<=1; + r.e-=1; + } + } + /*printf ("%f * %f = %f\n", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/ + return r; +} + +static inline spx_float_t FLOAT_AMULT(spx_float_t a, spx_float_t b) +{ + spx_float_t r; + r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15); + r.e = (a).e+(b).e+15; + return r; +} + + +static inline spx_float_t FLOAT_SHL(spx_float_t a, int b) +{ + spx_float_t r; + r.m = a.m; + r.e = a.e+b; + return r; +} + +static inline spx_int16_t FLOAT_EXTRACT16(spx_float_t a) +{ + if (a.e<0) + return EXTRACT16((EXTEND32(a.m)+(EXTEND32(1)<<(-a.e-1)))>>-a.e); + else + return a.m<<a.e; +} + +static inline spx_int32_t FLOAT_EXTRACT32(spx_float_t a) +{ + if (a.e<0) + return (EXTEND32(a.m)+(EXTEND32(1)<<(-a.e-1)))>>-a.e; + else + return EXTEND32(a.m)<<a.e; +} + +static inline spx_int32_t FLOAT_MUL32(spx_float_t a, spx_word32_t b) +{ + return VSHR32(MULT16_32_Q15(a.m, b),-a.e-15); +} + +static inline spx_float_t FLOAT_MUL32U(spx_word32_t a, spx_word32_t b) +{ + int e1, e2; + spx_float_t r; + if (a==0 || b==0) + { + return FLOAT_ZERO; + } + e1 = spx_ilog2(ABS32(a)); + a = VSHR32(a, e1-14); + e2 = spx_ilog2(ABS32(b)); + b = VSHR32(b, e2-14); + r.m = MULT16_16_Q15(a,b); + r.e = e1+e2-13; + return r; +} + +/* Do NOT attempt to divide by a negative number */ +static inline spx_float_t FLOAT_DIV32_FLOAT(spx_word32_t a, spx_float_t b) +{ + int e=0; + spx_float_t r; + if (a==0) + { + return FLOAT_ZERO; + } + e = spx_ilog2(ABS32(a))-spx_ilog2(b.m-1)-15; + a = VSHR32(a, e); + if (ABS32(a)>=SHL32(EXTEND32(b.m-1),15)) + { + a >>= 1; + e++; + } + r.m = DIV32_16(a,b.m); + r.e = e-b.e; + return r; +} + + +/* Do NOT attempt to divide by a negative number */ +static inline spx_float_t FLOAT_DIV32(spx_word32_t a, spx_word32_t b) +{ + int e0=0,e=0; + spx_float_t r; + if (a==0) + { + return FLOAT_ZERO; + } + if (b>32767) + { + e0 = spx_ilog2(b)-14; + b = VSHR32(b, e0); + e0 = -e0; + } + e = spx_ilog2(ABS32(a))-spx_ilog2(b-1)-15; + a = VSHR32(a, e); + if (ABS32(a)>=SHL32(EXTEND32(b-1),15)) + { + a >>= 1; + e++; + } + e += e0; + r.m = DIV32_16(a,b); + r.e = e; + return r; +} + +/* Do NOT attempt to divide by a negative number */ +static inline spx_float_t FLOAT_DIVU(spx_float_t a, spx_float_t b) +{ + int e=0; + spx_int32_t num; + spx_float_t r; + if (b.m<=0) + { + speex_warning_int("Attempted to divide by", b.m); + return FLOAT_ONE; + } + num = a.m; + a.m = ABS16(a.m); + while (a.m >= b.m) + { + e++; + a.m >>= 1; + } + num = num << (15-e); + r.m = DIV32_16(num,b.m); + r.e = a.e-b.e-15+e; + return r; +} + +static inline spx_float_t FLOAT_SQRT(spx_float_t a) +{ + spx_float_t r; + spx_int32_t m; + m = SHL32(EXTEND32(a.m), 14); + r.e = a.e - 14; + if (r.e & 1) + { + r.e -= 1; + m <<= 1; + } + r.e >>= 1; + r.m = spx_sqrt(m); + return r; +} + +#else + +#define spx_float_t float +#define FLOAT_ZERO 0.f +#define FLOAT_ONE 1.f +#define FLOAT_HALF 0.5f +#define PSEUDOFLOAT(x) (x) +#define FLOAT_MULT(a,b) ((a)*(b)) +#define FLOAT_AMULT(a,b) ((a)*(b)) +#define FLOAT_MUL32(a,b) ((a)*(b)) +#define FLOAT_DIV32(a,b) ((a)/(b)) +#define FLOAT_EXTRACT16(a) (a) +#define FLOAT_EXTRACT32(a) (a) +#define FLOAT_ADD(a,b) ((a)+(b)) +#define FLOAT_SUB(a,b) ((a)-(b)) +#define REALFLOAT(x) (x) +#define FLOAT_DIV32_FLOAT(a,b) ((a)/(b)) +#define FLOAT_MUL32U(a,b) ((a)*(b)) +#define FLOAT_SHL(a,b) (a) +#define FLOAT_LT(a,b) ((a)<(b)) +#define FLOAT_GT(a,b) ((a)>(b)) +#define FLOAT_DIVU(a,b) ((a)/(b)) +#define FLOAT_SQRT(a) (spx_sqrt(a)) + +#endif + +#endif diff --git a/src/libs/speex/libspeex/quant_lsp.c b/src/libs/speex/libspeex/quant_lsp.c new file mode 100644 index 00000000..e624d1a2 --- /dev/null +++ b/src/libs/speex/libspeex/quant_lsp.c @@ -0,0 +1,385 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: quant_lsp.c + LSP vector quantization + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "quant_lsp.h" +#include "os_support.h" +#include <math.h> +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#include "arch.h" + +#ifdef BFIN_ASM +#include "quant_lsp_bfin.h" +#endif + +#ifdef FIXED_POINT + +#define LSP_LINEAR(i) (SHL16(i+1,11)) +#define LSP_LINEAR_HIGH(i) (ADD16(MULT16_16_16(i,2560),6144)) +#define LSP_DIV_256(x) (SHL16((spx_word16_t)x, 5)) +#define LSP_DIV_512(x) (SHL16((spx_word16_t)x, 4)) +#define LSP_DIV_1024(x) (SHL16((spx_word16_t)x, 3)) +#define LSP_PI 25736 + +#else + +#define LSP_LINEAR(i) (.25*(i)+.25) +#define LSP_LINEAR_HIGH(i) (.3125*(i)+.75) +#define LSP_SCALE 256. +#define LSP_DIV_256(x) (0.0039062*(x)) +#define LSP_DIV_512(x) (0.0019531*(x)) +#define LSP_DIV_1024(x) (0.00097656*(x)) +#define LSP_PI M_PI + +#endif + +static void compute_quant_weights(spx_lsp_t *qlsp, spx_word16_t *quant_weight, int order) +{ + int i; + spx_word16_t tmp1, tmp2; + for (i=0;i<order;i++) + { + if (i==0) + tmp1 = qlsp[i]; + else + tmp1 = qlsp[i]-qlsp[i-1]; + if (i==order-1) + tmp2 = LSP_PI-qlsp[i]; + else + tmp2 = qlsp[i+1]-qlsp[i]; + if (tmp2<tmp1) + tmp1 = tmp2; +#ifdef FIXED_POINT + quant_weight[i] = DIV32_16(81920,ADD16(300,tmp1)); +#else + quant_weight[i] = 10/(.04+tmp1); +#endif + } + +} + +/* Note: x is modified*/ +#ifndef OVERRIDE_LSP_QUANT +static int lsp_quant(spx_word16_t *x, const signed char *cdbk, int nbVec, int nbDim) +{ + int i,j; + spx_word32_t dist; + spx_word16_t tmp; + spx_word32_t best_dist=VERY_LARGE32; + int best_id=0; + const signed char *ptr=cdbk; + for (i=0;i<nbVec;i++) + { + dist=0; + for (j=0;j<nbDim;j++) + { + tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5)); + dist=MAC16_16(dist,tmp,tmp); + } + if (dist<best_dist) + { + best_dist=dist; + best_id=i; + } + } + + for (j=0;j<nbDim;j++) + x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5)); + + return best_id; +} +#endif + +/* Note: x is modified*/ +#ifndef OVERRIDE_LSP_WEIGHT_QUANT +static int lsp_weight_quant(spx_word16_t *x, spx_word16_t *weight, const signed char *cdbk, int nbVec, int nbDim) +{ + int i,j; + spx_word32_t dist; + spx_word16_t tmp; + spx_word32_t best_dist=VERY_LARGE32; + int best_id=0; + const signed char *ptr=cdbk; + for (i=0;i<nbVec;i++) + { + dist=0; + for (j=0;j<nbDim;j++) + { + tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5)); + dist=MAC16_32_Q15(dist,weight[j],MULT16_16(tmp,tmp)); + } + if (dist<best_dist) + { + best_dist=dist; + best_id=i; + } + } + + for (j=0;j<nbDim;j++) + x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5)); + return best_id; +} +#endif + +void lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) +{ + int i; + int id; + spx_word16_t quant_weight[10]; + + for (i=0;i<order;i++) + qlsp[i]=lsp[i]; + + compute_quant_weights(qlsp, quant_weight, order); + + for (i=0;i<order;i++) + qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i)); + +#ifndef FIXED_POINT + for (i=0;i<order;i++) + qlsp[i] = LSP_SCALE*qlsp[i]; +#endif + id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order); + speex_bits_pack(bits, id, 6); + + for (i=0;i<order;i++) + qlsp[i]*=2; + + id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5); + speex_bits_pack(bits, id, 6); + + for (i=0;i<5;i++) + qlsp[i]*=2; + + id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low2, NB_CDBK_SIZE_LOW2, 5); + speex_bits_pack(bits, id, 6); + + id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5); + speex_bits_pack(bits, id, 6); + + for (i=5;i<10;i++) + qlsp[i]*=2; + + id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high2, NB_CDBK_SIZE_HIGH2, 5); + speex_bits_pack(bits, id, 6); + +#ifdef FIXED_POINT + for (i=0;i<order;i++) + qlsp[i]=PSHR16(qlsp[i],2); +#else + for (i=0;i<order;i++) + qlsp[i]=qlsp[i] * .00097656; +#endif + + for (i=0;i<order;i++) + qlsp[i]=lsp[i]-qlsp[i]; +} + +void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits) +{ + int i, id; + for (i=0;i<order;i++) + lsp[i]=LSP_LINEAR(i); + + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<10;i++) + lsp[i] = ADD32(lsp[i], LSP_DIV_256(cdbk_nb[id*10+i])); + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<5;i++) + lsp[i] = ADD16(lsp[i], LSP_DIV_512(cdbk_nb_low1[id*5+i])); + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<5;i++) + lsp[i] = ADD32(lsp[i], LSP_DIV_1024(cdbk_nb_low2[id*5+i])); + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<5;i++) + lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_512(cdbk_nb_high1[id*5+i])); + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<5;i++) + lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_1024(cdbk_nb_high2[id*5+i])); +} + + +void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) +{ + int i; + int id; + spx_word16_t quant_weight[10]; + + for (i=0;i<order;i++) + qlsp[i]=lsp[i]; + + compute_quant_weights(qlsp, quant_weight, order); + + for (i=0;i<order;i++) + qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i)); +#ifndef FIXED_POINT + for (i=0;i<order;i++) + qlsp[i]=qlsp[i]*LSP_SCALE; +#endif + id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order); + speex_bits_pack(bits, id, 6); + + for (i=0;i<order;i++) + qlsp[i]*=2; + + id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5); + speex_bits_pack(bits, id, 6); + + id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5); + speex_bits_pack(bits, id, 6); + +#ifdef FIXED_POINT + for (i=0;i<order;i++) + qlsp[i] = PSHR16(qlsp[i],1); +#else + for (i=0;i<order;i++) + qlsp[i] = qlsp[i]*0.0019531; +#endif + + for (i=0;i<order;i++) + qlsp[i]=lsp[i]-qlsp[i]; +} + +void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits) +{ + int i, id; + for (i=0;i<order;i++) + lsp[i]=LSP_LINEAR(i); + + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<10;i++) + lsp[i] += LSP_DIV_256(cdbk_nb[id*10+i]); + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<5;i++) + lsp[i] += LSP_DIV_512(cdbk_nb_low1[id*5+i]); + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<5;i++) + lsp[i+5] += LSP_DIV_512(cdbk_nb_high1[id*5+i]); + +} + + +#ifdef DISABLE_WIDEBAND +void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) +{ + speex_fatal("Wideband and Ultra-wideband are disabled"); +} +void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits) +{ + speex_fatal("Wideband and Ultra-wideband are disabled"); +} +#else +extern const signed char high_lsp_cdbk[]; +extern const signed char high_lsp_cdbk2[]; + + +void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) +{ + int i; + int id; + spx_word16_t quant_weight[10]; + + for (i=0;i<order;i++) + qlsp[i]=lsp[i]; + + compute_quant_weights(qlsp, quant_weight, order); + + /* quant_weight[0] = 10/(qlsp[1]-qlsp[0]); + quant_weight[order-1] = 10/(qlsp[order-1]-qlsp[order-2]); + for (i=1;i<order-1;i++) + { + tmp1 = 10/(qlsp[i]-qlsp[i-1]); + tmp2 = 10/(qlsp[i+1]-qlsp[i]); + quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2; + }*/ + + for (i=0;i<order;i++) + qlsp[i]=SUB16(qlsp[i],LSP_LINEAR_HIGH(i)); +#ifndef FIXED_POINT + for (i=0;i<order;i++) + qlsp[i] = qlsp[i]*LSP_SCALE; +#endif + id = lsp_quant(qlsp, high_lsp_cdbk, 64, order); + speex_bits_pack(bits, id, 6); + + for (i=0;i<order;i++) + qlsp[i]*=2; + + id = lsp_weight_quant(qlsp, quant_weight, high_lsp_cdbk2, 64, order); + speex_bits_pack(bits, id, 6); + +#ifdef FIXED_POINT + for (i=0;i<order;i++) + qlsp[i] = PSHR16(qlsp[i],1); +#else + for (i=0;i<order;i++) + qlsp[i] = qlsp[i]*0.0019531; +#endif + + for (i=0;i<order;i++) + qlsp[i]=lsp[i]-qlsp[i]; +} + +void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits) +{ + + int i, id; + for (i=0;i<order;i++) + lsp[i]=LSP_LINEAR_HIGH(i); + + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<order;i++) + lsp[i] += LSP_DIV_256(high_lsp_cdbk[id*order+i]); + + + id=speex_bits_unpack_unsigned(bits, 6); + for (i=0;i<order;i++) + lsp[i] += LSP_DIV_512(high_lsp_cdbk2[id*order+i]); +} + +#endif + diff --git a/src/libs/speex/libspeex/quant_lsp.h b/src/libs/speex/libspeex/quant_lsp.h new file mode 100644 index 00000000..3bf4d402 --- /dev/null +++ b/src/libs/speex/libspeex/quant_lsp.h @@ -0,0 +1,74 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file quant_lsp.h + @brief LSP vector quantization +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef QUANT_LSP_H +#define QUANT_LSP_H + +#include <speex/speex_bits.h> +#include "arch.h" + +#define MAX_LSP_SIZE 20 + +#define NB_CDBK_SIZE 64 +#define NB_CDBK_SIZE_LOW1 64 +#define NB_CDBK_SIZE_LOW2 64 +#define NB_CDBK_SIZE_HIGH1 64 +#define NB_CDBK_SIZE_HIGH2 64 + +/*Narrowband codebooks*/ +extern const signed char cdbk_nb[]; +extern const signed char cdbk_nb_low1[]; +extern const signed char cdbk_nb_low2[]; +extern const signed char cdbk_nb_high1[]; +extern const signed char cdbk_nb_high2[]; + +/* Quantizes narrowband LSPs with 30 bits */ +void lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits); + +/* Decodes quantized narrowband LSPs */ +void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits); + +/* Quantizes low bit-rate narrowband LSPs with 18 bits */ +void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits); + +/* Decodes quantized low bit-rate narrowband LSPs */ +void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits); + +/* Quantizes high-band LSPs with 12 bits */ +void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits); + +/* Decodes high-band LSPs */ +void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits); + +#endif diff --git a/src/libs/speex/libspeex/quant_lsp_bfin.h b/src/libs/speex/libspeex/quant_lsp_bfin.h new file mode 100644 index 00000000..087b466b --- /dev/null +++ b/src/libs/speex/libspeex/quant_lsp_bfin.h @@ -0,0 +1,165 @@ +/* Copyright (C) 2006 David Rowe */ +/** + @file quant_lsp_bfin.h + @author David Rowe + @brief Various compatibility routines for Speex (Blackfin version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define OVERRIDE_LSP_QUANT +#ifdef OVERRIDE_LSP_QUANT + +/* + Note http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html + well tell you all the magic resgister constraints used below + for gcc in-line asm. +*/ + +static int lsp_quant( + spx_word16_t *x, + const signed char *cdbk, + int nbVec, + int nbDim +) +{ + int j; + spx_word32_t best_dist=1<<30; + int best_id=0; + + __asm__ __volatile__ + ( +" %0 = 1 (X);\n\t" /* %0: best_dist */ +" %0 <<= 30;\n\t" +" %1 = 0 (X);\n\t" /* %1: best_i */ +" P2 = %3\n\t" /* P2: ptr to cdbk */ +" R5 = 0;\n\t" /* R5: best cb entry */ + +" R0 = %5;\n\t" /* set up circ addr */ +" R0 <<= 1;\n\t" +" L0 = R0;\n\t" +" I0 = %2;\n\t" /* %2: &x[0] */ +" B0 = %2;\n\t" + +" R2.L = W [I0++];\n\t" +" LSETUP (1f, 2f) LC0 = %4;\n\t" +"1: R3 = 0;\n\t" /* R3: dist */ +" LSETUP (3f, 4f) LC1 = %5;\n\t" +"3: R1 = B [P2++] (X);\n\t" +" R1 <<= 5;\n\t" +" R0.L = R2.L - R1.L || R2.L = W [I0++];\n\t" +" R0 = R0.L*R0.L;\n\t" +"4: R3 = R3 + R0;\n\t" + +" cc =R3<%0;\n\t" +" if cc %0=R3;\n\t" +" if cc %1=R5;\n\t" +"2: R5 += 1;\n\t" +" L0 = 0;\n\t" + : "=&d" (best_dist), "=&d" (best_id) + : "a" (x), "b" (cdbk), "a" (nbVec), "a" (nbDim) + : "I0", "P2", "R0", "R1", "R2", "R3", "R5", "L0", "B0", "A0" + ); + + for (j=0;j<nbDim;j++) { + x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5)); + } + return best_id; +} +#endif + +#define OVERRIDE_LSP_WEIGHT_QUANT +#ifdef OVERRIDE_LSP_WEIGHT_QUANT + +/* + Note http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html + well tell you all the magic resgister constraints used below + for gcc in-line asm. +*/ + +static int lsp_weight_quant( + spx_word16_t *x, + spx_word16_t *weight, + const signed char *cdbk, + int nbVec, + int nbDim +) +{ + int j; + spx_word32_t best_dist=1<<30; + int best_id=0; + + __asm__ __volatile__ + ( +" %0 = 1 (X);\n\t" /* %0: best_dist */ +" %0 <<= 30;\n\t" +" %1 = 0 (X);\n\t" /* %1: best_i */ +" P2 = %4\n\t" /* P2: ptr to cdbk */ +" R5 = 0;\n\t" /* R5: best cb entry */ + +" R0 = %6;\n\t" /* set up circ addr */ +" R0 <<= 1;\n\t" +" L0 = R0;\n\t" +" L1 = R0;\n\t" +" I0 = %2;\n\t" /* %2: &x[0] */ +" I1 = %3;\n\t" /* %3: &weight[0] */ +" B0 = %2;\n\t" +" B1 = %3;\n\t" + +" LSETUP (1f, 2f) LC0 = %5;\n\t" +"1: R3 = 0 (X);\n\t" /* R3: dist */ +" LSETUP (3f, 4f) LC1 = %6;\n\t" +"3: R0.L = W [I0++] || R2.L = W [I1++];\n\t" +" R1 = B [P2++] (X);\n\t" +" R1 <<= 5;\n\t" +" R0.L = R0.L - R1.L;\n\t" +" R0 = R0.L*R0.L;\n\t" +" A1 = R2.L*R0.L (M,IS);\n\t" +" A1 = A1 >>> 16;\n\t" +" R1 = (A1 += R2.L*R0.H) (IS);\n\t" +"4: R3 = R3 + R1;\n\t" + +" cc =R3<%0;\n\t" +" if cc %0=R3;\n\t" +" if cc %1=R5;\n\t" +"2: R5 += 1;\n\t" +" L0 = 0;\n\t" +" L1 = 0;\n\t" + : "=&d" (best_dist), "=&d" (best_id) + : "a" (x), "a" (weight), "b" (cdbk), "a" (nbVec), "a" (nbDim) + : "I0", "I1", "P2", "R0", "R1", "R2", "R3", "R5", "A1", + "L0", "L1", "B0", "B1" + ); + + for (j=0;j<nbDim;j++) { + x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5)); + } + return best_id; +} +#endif diff --git a/src/libs/speex/libspeex/resample_sse.h b/src/libs/speex/libspeex/resample_sse.h new file mode 100644 index 00000000..4bd35a2d --- /dev/null +++ b/src/libs/speex/libspeex/resample_sse.h @@ -0,0 +1,128 @@ +/* Copyright (C) 2007-2008 Jean-Marc Valin + * Copyright (C) 2008 Thorvald Natvig + */ +/** + @file resample_sse.h + @brief Resampler functions (SSE version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <xmmintrin.h> + +#define OVERRIDE_INNER_PRODUCT_SINGLE +static inline float inner_product_single(const float *a, const float *b, unsigned int len) +{ + int i; + float ret; + __m128 sum = _mm_setzero_ps(); + for (i=0;i<len;i+=8) + { + sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i))); + sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4))); + } + sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum)); + sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55)); + _mm_store_ss(&ret, sum); + return ret; +} + +#define OVERRIDE_INTERPOLATE_PRODUCT_SINGLE +static inline float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) { + int i; + float ret; + __m128 sum = _mm_setzero_ps(); + __m128 f = _mm_loadu_ps(frac); + for(i=0;i<len;i+=2) + { + sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample))); + sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample))); + } + sum = _mm_mul_ps(f, sum); + sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum)); + sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55)); + _mm_store_ss(&ret, sum); + return ret; +} + +#ifdef _USE_SSE2 +#include <emmintrin.h> +#define OVERRIDE_INNER_PRODUCT_DOUBLE + +static inline double inner_product_double(const float *a, const float *b, unsigned int len) +{ + int i; + double ret; + __m128d sum = _mm_setzero_pd(); + __m128 t; + for (i=0;i<len;i+=8) + { + t = _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i)); + sum = _mm_add_pd(sum, _mm_cvtps_pd(t)); + sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t))); + + t = _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4)); + sum = _mm_add_pd(sum, _mm_cvtps_pd(t)); + sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t))); + } + sum = _mm_add_sd(sum, (__m128d) _mm_movehl_ps((__m128) sum, (__m128) sum)); + _mm_store_sd(&ret, sum); + return ret; +} + +#define OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE +static inline double interpolate_product_double(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) { + int i; + double ret; + __m128d sum; + __m128d sum1 = _mm_setzero_pd(); + __m128d sum2 = _mm_setzero_pd(); + __m128 f = _mm_loadu_ps(frac); + __m128d f1 = _mm_cvtps_pd(f); + __m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f,f)); + __m128 t; + for(i=0;i<len;i+=2) + { + t = _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample)); + sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t)); + sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t))); + + t = _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample)); + sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t)); + sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t))); + } + sum1 = _mm_mul_pd(f1, sum1); + sum2 = _mm_mul_pd(f2, sum2); + sum = _mm_add_pd(sum1, sum2); + sum = _mm_add_sd(sum, (__m128d) _mm_movehl_ps((__m128) sum, (__m128) sum)); + _mm_store_sd(&ret, sum); + return ret; +} + +#endif diff --git a/src/libs/speex/libspeex/sb_celp.c b/src/libs/speex/libspeex/sb_celp.c new file mode 100644 index 00000000..6c19ff8b --- /dev/null +++ b/src/libs/speex/libspeex/sb_celp.c @@ -0,0 +1,1488 @@ +/* Copyright (C) 2002-2006 Jean-Marc Valin + File: sb_celp.c + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <math.h> +#include "sb_celp.h" +#include "filters.h" +#include "lpc.h" +#include "lsp.h" +#include "stack_alloc.h" +#include "cb_search.h" +#include "quant_lsp.h" +#include "vq.h" +#include "ltp.h" +#include "arch.h" +#include "math_approx.h" +#include "os_support.h" + +#ifndef NULL +#define NULL 0 +#endif + +/* Default size for the encoder and decoder stack (can be changed at compile time). + This does not apply when using variable-size arrays or alloca. */ +#ifndef SB_ENC_STACK +#define SB_ENC_STACK (10000*sizeof(spx_sig_t)) +#endif + +#ifndef SB_DEC_STACK +#define SB_DEC_STACK (6000*sizeof(spx_sig_t)) +#endif + + +#ifdef DISABLE_WIDEBAND +void *sb_encoder_init(const SpeexMode *m) +{ + speex_fatal("Wideband and Ultra-wideband are disabled"); + return NULL; +} +void sb_encoder_destroy(void *state) +{ + speex_fatal("Wideband and Ultra-wideband are disabled"); +} +int sb_encode(void *state, void *vin, SpeexBits *bits) +{ + speex_fatal("Wideband and Ultra-wideband are disabled"); + return -2; +} +void *sb_decoder_init(const SpeexMode *m) +{ + speex_fatal("Wideband and Ultra-wideband are disabled"); + return NULL; +} +void sb_decoder_destroy(void *state) +{ + speex_fatal("Wideband and Ultra-wideband are disabled"); +} +int sb_decode(void *state, SpeexBits *bits, void *vout) +{ + speex_fatal("Wideband and Ultra-wideband are disabled"); + return -2; +} +int sb_encoder_ctl(void *state, int request, void *ptr) +{ + speex_fatal("Wideband and Ultra-wideband are disabled"); + return -2; +} +int sb_decoder_ctl(void *state, int request, void *ptr) +{ + speex_fatal("Wideband and Ultra-wideband are disabled"); + return -2; +} +#else + + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + +#define sqr(x) ((x)*(x)) + +#define SUBMODE(x) st->submodes[st->submodeID]->x + +#ifdef FIXED_POINT +static const spx_word16_t gc_quant_bound[16] = {125, 164, 215, 282, 370, 484, 635, 832, 1090, 1428, 1871, 2452, 3213, 4210, 5516, 7228}; +static const spx_word16_t fold_quant_bound[32] = { + 39, 44, 50, 57, 64, 73, 83, 94, + 106, 120, 136, 154, 175, 198, 225, 255, + 288, 327, 370, 420, 476, 539, 611, 692, + 784, 889, 1007, 1141, 1293, 1465, 1660, 1881}; +#define LSP_MARGIN 410 +#define LSP_DELTA1 6553 +#define LSP_DELTA2 1638 + +#else + +static const spx_word16_t gc_quant_bound[16] = { + 0.97979, 1.28384, 1.68223, 2.20426, 2.88829, 3.78458, 4.95900, 6.49787, + 8.51428, 11.15642, 14.61846, 19.15484, 25.09895, 32.88761, 43.09325, 56.46588}; +static const spx_word16_t fold_quant_bound[32] = { + 0.30498, 0.34559, 0.39161, 0.44375, 0.50283, 0.56979, 0.64565, 0.73162, + 0.82903, 0.93942, 1.06450, 1.20624, 1.36685, 1.54884, 1.75506, 1.98875, + 2.25355, 2.55360, 2.89361, 3.27889, 3.71547, 4.21018, 4.77076, 5.40598, + 6.12577, 6.94141, 7.86565, 8.91295, 10.09969, 11.44445, 12.96826, 14.69497}; + +#define LSP_MARGIN .05 +#define LSP_DELTA1 .2 +#define LSP_DELTA2 .05 + +#endif + +#define QMF_ORDER 64 + +#ifdef FIXED_POINT +static const spx_word16_t h0[64] = {2, -7, -7, 18, 15, -39, -25, 75, 35, -130, -41, 212, 38, -327, -17, 483, -32, -689, 124, 956, -283, -1307, 543, 1780, -973, -2467, 1733, 3633, -3339, -6409, 9059, 30153, 30153, 9059, -6409, -3339, 3633, 1733, -2467, -973, 1780, 543, -1307, -283, 956, 124, -689, -32, 483, -17, -327, 38, 212, -41, -130, 35, 75, -25, -39, 15, 18, -7, -7, 2}; + +#else +static const float h0[64] = { + 3.596189e-05f, -0.0001123515f, + -0.0001104587f, 0.0002790277f, + 0.0002298438f, -0.0005953563f, + -0.0003823631f, 0.00113826f, + 0.0005308539f, -0.001986177f, + -0.0006243724f, 0.003235877f, + 0.0005743159f, -0.004989147f, + -0.0002584767f, 0.007367171f, + -0.0004857935f, -0.01050689f, + 0.001894714f, 0.01459396f, + -0.004313674f, -0.01994365f, + 0.00828756f, 0.02716055f, + -0.01485397f, -0.03764973f, + 0.026447f, 0.05543245f, + -0.05095487f, -0.09779096f, + 0.1382363f, 0.4600981f, + 0.4600981f, 0.1382363f, + -0.09779096f, -0.05095487f, + 0.05543245f, 0.026447f, + -0.03764973f, -0.01485397f, + 0.02716055f, 0.00828756f, + -0.01994365f, -0.004313674f, + 0.01459396f, 0.001894714f, + -0.01050689f, -0.0004857935f, + 0.007367171f, -0.0002584767f, + -0.004989147f, 0.0005743159f, + 0.003235877f, -0.0006243724f, + -0.001986177f, 0.0005308539f, + 0.00113826f, -0.0003823631f, + -0.0005953563f, 0.0002298438f, + 0.0002790277f, -0.0001104587f, + -0.0001123515f, 3.596189e-05f +}; + +#endif + +extern const spx_word16_t lag_window[]; +extern const spx_word16_t lpc_window[]; + + +void *sb_encoder_init(const SpeexMode *m) +{ + int i; + spx_int32_t tmp; + SBEncState *st; + const SpeexSBMode *mode; + + st = (SBEncState*)speex_alloc(sizeof(SBEncState)); + if (!st) + return NULL; + st->mode = m; + mode = (const SpeexSBMode*)m->mode; + + + st->st_low = speex_encoder_init(mode->nb_mode); +#if defined(VAR_ARRAYS) || defined (USE_ALLOCA) + st->stack = NULL; +#else + /*st->stack = (char*)speex_alloc_scratch(SB_ENC_STACK);*/ + speex_encoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack); +#endif + + st->full_frame_size = 2*mode->frameSize; + st->frame_size = mode->frameSize; + st->subframeSize = mode->subframeSize; + st->nbSubframes = mode->frameSize/mode->subframeSize; + st->windowSize = st->frame_size+st->subframeSize; + st->lpcSize=mode->lpcSize; + + st->encode_submode = 1; + st->submodes=mode->submodes; + st->submodeSelect = st->submodeID=mode->defaultSubmode; + + tmp=9; + speex_encoder_ctl(st->st_low, SPEEX_SET_QUALITY, &tmp); + tmp=1; + speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp); + + st->lpc_floor = mode->lpc_floor; + st->gamma1=mode->gamma1; + st->gamma2=mode->gamma2; + st->first=1; + + st->high=(spx_word16_t*)speex_alloc((st->windowSize-st->frame_size)*sizeof(spx_word16_t)); + + st->h0_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t)); + st->h1_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t)); + + st->window= lpc_window; + + st->lagWindow = lag_window; + + st->old_lsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); + st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); + st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); + st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t)); + st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t)); + st->innov_rms_save = NULL; + + st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); + st->mem_sp2 = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); + st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); + + for (i=0;i<st->lpcSize;i++) + st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); + +#ifndef DISABLE_VBR + st->vbr_quality = 8; + st->vbr_enabled = 0; + st->vbr_max = 0; + st->vbr_max_high = 20000; /* We just need a big value here */ + st->vad_enabled = 0; + st->abr_enabled = 0; + st->relative_quality=0; +#endif /* #ifndef DISABLE_VBR */ + + st->complexity=2; + speex_encoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate); + st->sampling_rate*=2; +#ifdef ENABLE_VALGRIND + VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st)); +#endif + return st; +} + +void sb_encoder_destroy(void *state) +{ + SBEncState *st=(SBEncState*)state; + + speex_encoder_destroy(st->st_low); +#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA)) + /*speex_free_scratch(st->stack);*/ +#endif + + speex_free(st->high); + + speex_free(st->h0_mem); + speex_free(st->h1_mem); + + speex_free(st->old_lsp); + speex_free(st->old_qlsp); + speex_free(st->interp_qlpc); + speex_free(st->pi_gain); + speex_free(st->exc_rms); + + speex_free(st->mem_sp); + speex_free(st->mem_sp2); + speex_free(st->mem_sw); + + + speex_free(st); +} + + +int sb_encode(void *state, void *vin, SpeexBits *bits) +{ + SBEncState *st; + int i, roots, sub; + char *stack; + VARDECL(spx_mem_t *mem); + VARDECL(spx_sig_t *innov); + VARDECL(spx_word16_t *target); + VARDECL(spx_word16_t *syn_resp); + VARDECL(spx_word32_t *low_pi_gain); + spx_word16_t *low; + spx_word16_t *high; + VARDECL(spx_word16_t *low_exc_rms); + VARDECL(spx_word16_t *low_innov_rms); + const SpeexSBMode *mode; + spx_int32_t dtx; + spx_word16_t *in = (spx_word16_t*)vin; + spx_word16_t e_low=0, e_high=0; + VARDECL(spx_coef_t *lpc); + VARDECL(spx_coef_t *interp_lpc); + VARDECL(spx_coef_t *bw_lpc1); + VARDECL(spx_coef_t *bw_lpc2); + VARDECL(spx_lsp_t *lsp); + VARDECL(spx_lsp_t *qlsp); + VARDECL(spx_lsp_t *interp_lsp); + VARDECL(spx_lsp_t *interp_qlsp); + + st = (SBEncState*)state; + stack=st->stack; + mode = (const SpeexSBMode*)(st->mode->mode); + low = in; + high = in+st->frame_size; + + /* High-band buffering / sync with low band */ + /* Compute the two sub-bands by filtering with QMF h0*/ + qmf_decomp(in, h0, low, high, st->full_frame_size, QMF_ORDER, st->h0_mem, stack); + +#ifndef DISABLE_VBR + if (st->vbr_enabled || st->vad_enabled) + { + /* Need to compute things here before the signal is trashed by the encoder */ + /*FIXME: Are the two signals (low, high) in sync? */ + e_low = compute_rms16(low, st->frame_size); + e_high = compute_rms16(high, st->frame_size); + } +#endif /* #ifndef DISABLE_VBR */ + + ALLOC(low_innov_rms, st->nbSubframes, spx_word16_t); + speex_encoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_rms); + /* Encode the narrowband part*/ + speex_encode_native(st->st_low, low, bits); + + high = high - (st->windowSize-st->frame_size); + SPEEX_COPY(high, st->high, st->windowSize-st->frame_size); + SPEEX_COPY(st->high, &high[st->frame_size], st->windowSize-st->frame_size); + + + ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t); + ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t); + speex_encoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain); + speex_encoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms); + + speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, &dtx); + + if (dtx==0) + dtx=1; + else + dtx=0; + + ALLOC(lpc, st->lpcSize, spx_coef_t); + ALLOC(interp_lpc, st->lpcSize, spx_coef_t); + ALLOC(bw_lpc1, st->lpcSize, spx_coef_t); + ALLOC(bw_lpc2, st->lpcSize, spx_coef_t); + + ALLOC(lsp, st->lpcSize, spx_lsp_t); + ALLOC(qlsp, st->lpcSize, spx_lsp_t); + ALLOC(interp_lsp, st->lpcSize, spx_lsp_t); + ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t); + + { + VARDECL(spx_word16_t *autocorr); + VARDECL(spx_word16_t *w_sig); + ALLOC(autocorr, st->lpcSize+1, spx_word16_t); + ALLOC(w_sig, st->windowSize, spx_word16_t); + /* Window for analysis */ + /* FIXME: This is a kludge */ + if (st->subframeSize==80) + { + for (i=0;i<st->windowSize;i++) + w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i>>1]),SIG_SHIFT)); + } else { + for (i=0;i<st->windowSize;i++) + w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i]),SIG_SHIFT)); + } + /* Compute auto-correlation */ + _spx_autocorr(w_sig, autocorr, st->lpcSize+1, st->windowSize); + autocorr[0] = ADD16(autocorr[0],MULT16_16_Q15(autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */ + + /* Lag windowing: equivalent to filtering in the power-spectrum domain */ + for (i=0;i<st->lpcSize+1;i++) + autocorr[i] = MULT16_16_Q14(autocorr[i],st->lagWindow[i]); + + /* Levinson-Durbin */ + _spx_lpc(lpc, autocorr, st->lpcSize); + } + + /* LPC to LSPs (x-domain) transform */ + roots=lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA1, stack); + if (roots!=st->lpcSize) + { + roots = lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA2, stack); + if (roots!=st->lpcSize) { + /*If we can't find all LSP's, do some damage control and use a flat filter*/ + for (i=0;i<st->lpcSize;i++) + { + lsp[i]=st->old_lsp[i]; + } + } + } + +#ifndef DISABLE_VBR + /* VBR code */ + if ((st->vbr_enabled || st->vad_enabled) && !dtx) + { + float ratio; + if (st->abr_enabled) + { + float qual_change=0; + if (st->abr_drift2 * st->abr_drift > 0) + { + /* Only adapt if long-term and short-term drift are the same sign */ + qual_change = -.00001*st->abr_drift/(1+st->abr_count); + if (qual_change>.1) + qual_change=.1; + if (qual_change<-.1) + qual_change=-.1; + } + st->vbr_quality += qual_change; + if (st->vbr_quality>10) + st->vbr_quality=10; + if (st->vbr_quality<0) + st->vbr_quality=0; + } + + + ratio = 2*log((1.f+e_high)/(1.f+e_low)); + + speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &st->relative_quality); + if (ratio<-4) + ratio=-4; + if (ratio>2) + ratio=2; + /*if (ratio>-2)*/ + if (st->vbr_enabled) + { + spx_int32_t modeid; + modeid = mode->nb_modes-1; + st->relative_quality+=1.0*(ratio+2); + if (st->relative_quality<-1) + st->relative_quality=-1; + while (modeid) + { + int v1; + float thresh; + v1=(int)floor(st->vbr_quality); + if (v1==10) + thresh = mode->vbr_thresh[modeid][v1]; + else + thresh = (st->vbr_quality-v1) * mode->vbr_thresh[modeid][v1+1] + + (1+v1-st->vbr_quality) * mode->vbr_thresh[modeid][v1]; + if (st->relative_quality >= thresh && st->sampling_rate*st->submodes[modeid]->bits_per_frame/st->full_frame_size <= st->vbr_max_high) + break; + modeid--; + } + speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid); + if (st->abr_enabled) + { + spx_int32_t bitrate; + speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate); + st->abr_drift+=(bitrate-st->abr_enabled); + st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled); + st->abr_count += 1.0; + } + + } else { + /* VAD only */ + int modeid; + if (st->relative_quality<2.0) + modeid=1; + else + modeid=st->submodeSelect; + /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/ + st->submodeID=modeid; + + } + /*fprintf (stderr, "%f %f\n", ratio, low_qual);*/ + } +#endif /* #ifndef DISABLE_VBR */ + + if (st->encode_submode) + { + speex_bits_pack(bits, 1, 1); + if (dtx) + speex_bits_pack(bits, 0, SB_SUBMODE_BITS); + else + speex_bits_pack(bits, st->submodeID, SB_SUBMODE_BITS); + } + + /* If null mode (no transmission), just set a couple things to zero*/ + if (dtx || st->submodes[st->submodeID] == NULL) + { + for (i=0;i<st->frame_size;i++) + high[i]=VERY_SMALL; + + for (i=0;i<st->lpcSize;i++) + st->mem_sw[i]=0; + st->first=1; + + /* Final signal synthesis from excitation */ + iir_mem16(high, st->interp_qlpc, high, st->frame_size, st->lpcSize, st->mem_sp, stack); + + if (dtx) + return 0; + else + return 1; + } + + + /* LSP quantization */ + SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits); + + if (st->first) + { + for (i=0;i<st->lpcSize;i++) + st->old_lsp[i] = lsp[i]; + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = qlsp[i]; + } + + ALLOC(mem, st->lpcSize, spx_mem_t); + ALLOC(syn_resp, st->subframeSize, spx_word16_t); + ALLOC(innov, st->subframeSize, spx_sig_t); + ALLOC(target, st->subframeSize, spx_word16_t); + + for (sub=0;sub<st->nbSubframes;sub++) + { + VARDECL(spx_word16_t *exc); + VARDECL(spx_word16_t *res); + VARDECL(spx_word16_t *sw); + spx_word16_t *sp; + spx_word16_t filter_ratio; /*Q7*/ + int offset; + spx_word32_t rl, rh; /*Q13*/ + spx_word16_t eh=0; + + offset = st->subframeSize*sub; + sp=high+offset; + ALLOC(exc, st->subframeSize, spx_word16_t); + ALLOC(res, st->subframeSize, spx_word16_t); + ALLOC(sw, st->subframeSize, spx_word16_t); + + /* LSP interpolation (quantized and unquantized) */ + lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes); + lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes); + + lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN); + lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN); + + lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack); + lsp_to_lpc(interp_qlsp, st->interp_qlpc, st->lpcSize, stack); + + bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize); + bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize); + + /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band + filters */ + st->pi_gain[sub]=LPC_SCALING; + rh = LPC_SCALING; + for (i=0;i<st->lpcSize;i+=2) + { + rh += st->interp_qlpc[i+1] - st->interp_qlpc[i]; + st->pi_gain[sub] += st->interp_qlpc[i] + st->interp_qlpc[i+1]; + } + + rl = low_pi_gain[sub]; +#ifdef FIXED_POINT + filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767)); +#else + filter_ratio=(rl+.01)/(rh+.01); +#endif + + /* Compute "real excitation" */ + fir_mem16(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2, stack); + /* Compute energy of low-band and high-band excitation */ + + eh = compute_rms16(exc, st->subframeSize); + + if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */ + spx_word32_t g; /*Q7*/ + spx_word16_t el; /*Q0*/ + el = low_innov_rms[sub]; + + /* Gain to use if we want to use the low-band excitation for high-band */ + g=PDIV32(MULT16_16(filter_ratio,eh),EXTEND32(ADD16(1,el))); + +#if 0 + { + char *tmp_stack=stack; + float *tmp_sig; + float g2; + ALLOC(tmp_sig, st->subframeSize, spx_sig_t); + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sp[i]; + iir_mem2(st->low_innov+offset, st->interp_qlpc, tmp_sig, st->subframeSize, st->lpcSize, mem); + g2 = compute_rms(sp, st->subframeSize)/(.01+compute_rms(tmp_sig, st->subframeSize)); + /*fprintf (stderr, "gains: %f %f\n", g, g2);*/ + g = g2; + stack = tmp_stack; + } +#endif + + /*print_vec(&g, 1, "gain factor");*/ + /* Gain quantization */ + { + int quant = scal_quant(g, fold_quant_bound, 32); + /*speex_warning_int("tata", quant);*/ + if (quant<0) + quant=0; + if (quant>31) + quant=31; + speex_bits_pack(bits, quant, 5); + } + if (st->innov_rms_save) + { + st->innov_rms_save[sub] = eh; + } + st->exc_rms[sub] = eh; + } else { + spx_word16_t gc; /*Q7*/ + spx_word32_t scale; /*Q14*/ + spx_word16_t el; /*Q0*/ + el = low_exc_rms[sub]; /*Q0*/ + + gc = PDIV32_16(MULT16_16(filter_ratio,1+eh),1+el); + + /* This is a kludge that cleans up a historical bug */ + if (st->subframeSize==80) + gc = MULT16_16_P15(QCONST16(0.70711f,15),gc); + /*printf ("%f %f %f %f\n", el, eh, filter_ratio, gc);*/ + { + int qgc = scal_quant(gc, gc_quant_bound, 16); + speex_bits_pack(bits, qgc, 4); + gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]); + } + if (st->subframeSize==80) + gc = MULT16_16_P14(QCONST16(1.4142f,14), gc); + + scale = SHL32(MULT16_16(PDIV32_16(SHL32(EXTEND32(gc),SIG_SHIFT-6),filter_ratio),(1+el)),6); + + compute_impulse_response(st->interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack); + + + /* Reset excitation */ + for (i=0;i<st->subframeSize;i++) + res[i]=VERY_SMALL; + + /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */ + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sp[i]; + iir_mem16(res, st->interp_qlpc, res, st->subframeSize, st->lpcSize, mem, stack); + + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sw[i]; + filter_mem16(res, bw_lpc1, bw_lpc2, res, st->subframeSize, st->lpcSize, mem, stack); + + /* Compute weighted signal */ + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sw[i]; + filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, mem, stack); + + /* Compute target signal */ + for (i=0;i<st->subframeSize;i++) + target[i]=SUB16(sw[i],res[i]); + + signal_div(target, target, scale, st->subframeSize); + + /* Reset excitation */ + SPEEX_MEMSET(innov, 0, st->subframeSize); + + /*print_vec(target, st->subframeSize, "\ntarget");*/ + SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2, + SUBMODE(innovation_params), st->lpcSize, st->subframeSize, + innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook)); + /*print_vec(target, st->subframeSize, "after");*/ + + signal_mul(innov, innov, scale, st->subframeSize); + + if (SUBMODE(double_codebook)) { + char *tmp_stack=stack; + VARDECL(spx_sig_t *innov2); + ALLOC(innov2, st->subframeSize, spx_sig_t); + SPEEX_MEMSET(innov2, 0, st->subframeSize); + for (i=0;i<st->subframeSize;i++) + target[i]=MULT16_16_P13(QCONST16(2.5f,13), target[i]); + + SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2, + SUBMODE(innovation_params), st->lpcSize, st->subframeSize, + innov2, syn_resp, bits, stack, st->complexity, 0); + signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize); + + for (i=0;i<st->subframeSize;i++) + innov[i] = ADD32(innov[i],innov2[i]); + stack = tmp_stack; + } + for (i=0;i<st->subframeSize;i++) + exc[i] = PSHR32(innov[i],SIG_SHIFT); + + if (st->innov_rms_save) + { + st->innov_rms_save[sub] = MULT16_16_Q15(QCONST16(.70711f, 15), compute_rms(innov, st->subframeSize)); + } + st->exc_rms[sub] = compute_rms16(exc, st->subframeSize); + + + } + + + /*Keep the previous memory*/ + for (i=0;i<st->lpcSize;i++) + mem[i]=st->mem_sp[i]; + /* Final signal synthesis from excitation */ + iir_mem16(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp, stack); + + /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */ + filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw, stack); + } + + for (i=0;i<st->lpcSize;i++) + st->old_lsp[i] = lsp[i]; + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = qlsp[i]; + + st->first=0; + + return 1; +} + + + + + +void *sb_decoder_init(const SpeexMode *m) +{ + spx_int32_t tmp; + SBDecState *st; + const SpeexSBMode *mode; + st = (SBDecState*)speex_alloc(sizeof(SBDecState)); + if (!st) + return NULL; + st->mode = m; + mode=(const SpeexSBMode*)m->mode; + st->encode_submode = 1; + + st->st_low = speex_decoder_init(mode->nb_mode); +#if defined(VAR_ARRAYS) || defined (USE_ALLOCA) + st->stack = NULL; +#else + /*st->stack = (char*)speex_alloc_scratch(SB_DEC_STACK);*/ + speex_decoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack); +#endif + + st->full_frame_size = 2*mode->frameSize; + st->frame_size = mode->frameSize; + st->subframeSize = mode->subframeSize; + st->nbSubframes = mode->frameSize/mode->subframeSize; + st->lpcSize=mode->lpcSize; + speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate); + st->sampling_rate*=2; + tmp=1; + speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp); + + st->submodes=mode->submodes; + st->submodeID=mode->defaultSubmode; + + st->first=1; + + st->g0_mem = (spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t)); + st->g1_mem = (spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t)); + + st->excBuf = (spx_word16_t*)speex_alloc((st->subframeSize)*sizeof(spx_word16_t)); + + st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); + st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); + + st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t)); + st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t)); + st->mem_sp = (spx_mem_t*)speex_alloc((2*st->lpcSize)*sizeof(spx_mem_t)); + + st->innov_save = NULL; + + + st->lpc_enh_enabled=0; + st->seed = 1000; + +#ifdef ENABLE_VALGRIND + VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st)); +#endif + return st; +} + +void sb_decoder_destroy(void *state) +{ + SBDecState *st; + st = (SBDecState*)state; + speex_decoder_destroy(st->st_low); +#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA)) + /*speex_free_scratch(st->stack);*/ +#endif + + speex_free(st->g0_mem); + speex_free(st->g1_mem); + speex_free(st->excBuf); + speex_free(st->old_qlsp); + speex_free(st->interp_qlpc); + speex_free(st->pi_gain); + speex_free(st->exc_rms); + speex_free(st->mem_sp); + + speex_free(state); +} + +static void sb_decode_lost(SBDecState *st, spx_word16_t *out, int dtx, char *stack) +{ + int i; + int saved_modeid=0; + + if (dtx) + { + saved_modeid=st->submodeID; + st->submodeID=1; + } else { + bw_lpc(QCONST16(0.99f,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize); + } + + st->first=1; + + + /* Final signal synthesis from excitation */ + if (!dtx) + { + st->last_ener = MULT16_16_Q15(QCONST16(.9f,15),st->last_ener); + } + for (i=0;i<st->frame_size;i++) + out[i+st->frame_size] = speex_rand(st->last_ener, &st->seed); + + iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize, + st->mem_sp, stack); + + + /* Reconstruct the original */ + qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack); + if (dtx) + { + st->submodeID=saved_modeid; + } + + return; +} + +int sb_decode(void *state, SpeexBits *bits, void *vout) +{ + int i, sub; + SBDecState *st; + int wideband; + int ret; + char *stack; + VARDECL(spx_word32_t *low_pi_gain); + VARDECL(spx_word16_t *low_exc_rms); + VARDECL(spx_coef_t *ak); + VARDECL(spx_lsp_t *qlsp); + VARDECL(spx_lsp_t *interp_qlsp); + spx_int32_t dtx; + const SpeexSBMode *mode; + spx_word16_t *out = (spx_word16_t*)vout; + spx_word16_t *low_innov_alias; + spx_word32_t exc_ener_sum = 0; + + st = (SBDecState*)state; + stack=st->stack; + mode = (const SpeexSBMode*)(st->mode->mode); + + low_innov_alias = out+st->frame_size; + speex_decoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_alias); + /* Decode the low-band */ + ret = speex_decode_native(st->st_low, bits, out); + + speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, &dtx); + + /* If error decoding the narrowband part, propagate error */ + if (ret!=0) + { + return ret; + } + + if (!bits) + { + sb_decode_lost(st, out, dtx, stack); + return 0; + } + + if (st->encode_submode) + { + + /*Check "wideband bit"*/ + if (speex_bits_remaining(bits)>0) + wideband = speex_bits_peek(bits); + else + wideband = 0; + if (wideband) + { + /*Regular wideband frame, read the submode*/ + wideband = speex_bits_unpack_unsigned(bits, 1); + st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); + } else + { + /*Was a narrowband frame, set "null submode"*/ + st->submodeID = 0; + } + if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL) + { + speex_notify("Invalid mode encountered. The stream is corrupted."); + return -2; + } + } + + /* If null mode (no transmission), just set a couple things to zero*/ + if (st->submodes[st->submodeID] == NULL) + { + if (dtx) + { + sb_decode_lost(st, out, 1, stack); + return 0; + } + + for (i=0;i<st->frame_size;i++) + out[st->frame_size+i]=VERY_SMALL; + + st->first=1; + + /* Final signal synthesis from excitation */ + iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize, st->mem_sp, stack); + + qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack); + + return 0; + + } + + ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t); + ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t); + speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain); + speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms); + + ALLOC(qlsp, st->lpcSize, spx_lsp_t); + ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t); + SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits); + + if (st->first) + { + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = qlsp[i]; + } + + ALLOC(ak, st->lpcSize, spx_coef_t); + + for (sub=0;sub<st->nbSubframes;sub++) + { + VARDECL(spx_word32_t *exc); + spx_word16_t *innov_save=NULL; + spx_word16_t *sp; + spx_word16_t filter_ratio; + spx_word16_t el=0; + int offset; + spx_word32_t rl=0,rh=0; + + offset = st->subframeSize*sub; + sp=out+st->frame_size+offset; + ALLOC(exc, st->subframeSize, spx_word32_t); + /* Pointer for saving innovation */ + if (st->innov_save) + { + innov_save = st->innov_save+2*offset; + SPEEX_MEMSET(innov_save, 0, 2*st->subframeSize); + } + + /* LSP interpolation */ + lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes); + + lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN); + + /* LSP to LPC */ + lsp_to_lpc(interp_qlsp, ak, st->lpcSize, stack); + + /* Calculate reponse ratio between the low and high filter in the middle + of the band (4000 Hz) */ + + st->pi_gain[sub]=LPC_SCALING; + rh = LPC_SCALING; + for (i=0;i<st->lpcSize;i+=2) + { + rh += ak[i+1] - ak[i]; + st->pi_gain[sub] += ak[i] + ak[i+1]; + } + + rl = low_pi_gain[sub]; +#ifdef FIXED_POINT + filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767)); +#else + filter_ratio=(rl+.01)/(rh+.01); +#endif + + SPEEX_MEMSET(exc, 0, st->subframeSize); + if (!SUBMODE(innovation_unquant)) + { + spx_word32_t g; + int quant; + + quant = speex_bits_unpack_unsigned(bits, 5); + g= spx_exp(MULT16_16(QCONST16(.125f,11),(quant-10))); + + g = PDIV32(g, filter_ratio); + + for (i=0;i<st->subframeSize;i+=2) + { + exc[i]=SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i]),SHL32(g,6)),SIG_SHIFT); + exc[i+1]=NEG32(SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i+1]),SHL32(g,6)),SIG_SHIFT)); + } + + } else { + spx_word16_t gc; + spx_word32_t scale; + int qgc = speex_bits_unpack_unsigned(bits, 4); + + el = low_exc_rms[sub]; + gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]); + + if (st->subframeSize==80) + gc = MULT16_16_P14(QCONST16(1.4142f,14),gc); + + scale = SHL32(PDIV32(SHL32(MULT16_16(gc, el),3), filter_ratio),SIG_SHIFT-3); + SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize, + bits, stack, &st->seed); + + signal_mul(exc,exc,scale,st->subframeSize); + + if (SUBMODE(double_codebook)) { + char *tmp_stack=stack; + VARDECL(spx_sig_t *innov2); + ALLOC(innov2, st->subframeSize, spx_sig_t); + SPEEX_MEMSET(innov2, 0, st->subframeSize); + SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, + bits, stack, &st->seed); + signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize); + for (i=0;i<st->subframeSize;i++) + exc[i] = ADD32(exc[i],innov2[i]); + stack = tmp_stack; + } + + } + + if (st->innov_save) + { + for (i=0;i<st->subframeSize;i++) + innov_save[2*i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT)); + } + + iir_mem16(st->excBuf, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, + st->mem_sp, stack); + for (i=0;i<st->subframeSize;i++) + st->excBuf[i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT)); + for (i=0;i<st->lpcSize;i++) + st->interp_qlpc[i] = ak[i]; + st->exc_rms[sub] = compute_rms16(st->excBuf, st->subframeSize); + exc_ener_sum = ADD32(exc_ener_sum, DIV32(MULT16_16(st->exc_rms[sub],st->exc_rms[sub]), st->nbSubframes)); + } + st->last_ener = spx_sqrt(exc_ener_sum); + + qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack); + for (i=0;i<st->lpcSize;i++) + st->old_qlsp[i] = qlsp[i]; + + st->first=0; + + return 0; +} + + +int sb_encoder_ctl(void *state, int request, void *ptr) +{ + SBEncState *st; + st=(SBEncState*)state; + switch(request) + { + case SPEEX_GET_FRAME_SIZE: + (*(spx_int32_t*)ptr) = st->full_frame_size; + break; + case SPEEX_SET_HIGH_MODE: + st->submodeSelect = st->submodeID = (*(spx_int32_t*)ptr); + break; + case SPEEX_SET_LOW_MODE: + speex_encoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr); + break; + case SPEEX_SET_DTX: + speex_encoder_ctl(st->st_low, SPEEX_SET_DTX, ptr); + break; + case SPEEX_GET_DTX: + speex_encoder_ctl(st->st_low, SPEEX_GET_DTX, ptr); + break; + case SPEEX_GET_LOW_MODE: + speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr); + break; + case SPEEX_SET_MODE: + speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr); + break; +#ifndef DISABLE_VBR + case SPEEX_SET_VBR: + st->vbr_enabled = (*(spx_int32_t*)ptr); + speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr); + break; + case SPEEX_GET_VBR: + (*(spx_int32_t*)ptr) = st->vbr_enabled; + break; + case SPEEX_SET_VAD: + st->vad_enabled = (*(spx_int32_t*)ptr); + speex_encoder_ctl(st->st_low, SPEEX_SET_VAD, ptr); + break; + case SPEEX_GET_VAD: + (*(spx_int32_t*)ptr) = st->vad_enabled; + break; +#endif /* #ifndef DISABLE_VBR */ +#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) + case SPEEX_SET_VBR_QUALITY: + { + spx_int32_t q; + float qual = (*(float*)ptr)+.6; + st->vbr_quality = (*(float*)ptr); + if (qual>10) + qual=10; + q=(int)floor(.5+*(float*)ptr); + if (q>10) + q=10; + speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_QUALITY, &qual); + speex_encoder_ctl(state, SPEEX_SET_QUALITY, &q); + break; + } + case SPEEX_GET_VBR_QUALITY: + (*(float*)ptr) = st->vbr_quality; + break; +#endif /* #if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */ +#ifndef DISABLE_VBR + case SPEEX_SET_ABR: + st->abr_enabled = (*(spx_int32_t*)ptr); + st->vbr_enabled = st->abr_enabled!=0; + speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, &st->vbr_enabled); + if (st->vbr_enabled) + { + spx_int32_t i=10, rate, target; + float vbr_qual; + target = (*(spx_int32_t*)ptr); + while (i>=0) + { + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); + speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); + if (rate <= target) + break; + i--; + } + vbr_qual=i; + if (vbr_qual<0) + vbr_qual=0; + speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual); + st->abr_count=0; + st->abr_drift=0; + st->abr_drift2=0; + } + + break; + case SPEEX_GET_ABR: + (*(spx_int32_t*)ptr) = st->abr_enabled; + break; +#endif /* #ifndef DISABLE_VBR */ + + case SPEEX_SET_QUALITY: + { + spx_int32_t nb_qual; + int quality = (*(spx_int32_t*)ptr); + if (quality < 0) + quality = 0; + if (quality > 10) + quality = 10; + st->submodeSelect = st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality]; + nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality]; + speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual); + } + break; + case SPEEX_SET_COMPLEXITY: + speex_encoder_ctl(st->st_low, SPEEX_SET_COMPLEXITY, ptr); + st->complexity = (*(spx_int32_t*)ptr); + if (st->complexity<1) + st->complexity=1; + break; + case SPEEX_GET_COMPLEXITY: + (*(spx_int32_t*)ptr) = st->complexity; + break; + case SPEEX_SET_BITRATE: + { + spx_int32_t i=10; + spx_int32_t rate, target; + target = (*(spx_int32_t*)ptr); + while (i>=0) + { + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); + speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); + if (rate <= target) + break; + i--; + } + } + break; + case SPEEX_GET_BITRATE: + speex_encoder_ctl(st->st_low, request, ptr); + /*fprintf (stderr, "before: %d\n", (*(int*)ptr));*/ + if (st->submodes[st->submodeID]) + (*(spx_int32_t*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size; + else + (*(spx_int32_t*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size; + /*fprintf (stderr, "after: %d\n", (*(int*)ptr));*/ + break; + case SPEEX_SET_SAMPLING_RATE: + { + spx_int32_t tmp=(*(spx_int32_t*)ptr); + st->sampling_rate = tmp; + tmp>>=1; + speex_encoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp); + } + break; + case SPEEX_GET_SAMPLING_RATE: + (*(spx_int32_t*)ptr)=st->sampling_rate; + break; + case SPEEX_RESET_STATE: + { + int i; + st->first = 1; + for (i=0;i<st->lpcSize;i++) + st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); + for (i=0;i<st->lpcSize;i++) + st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0; + for (i=0;i<QMF_ORDER;i++) + st->h0_mem[i]=st->h1_mem[i]=0; + } + break; + case SPEEX_SET_SUBMODE_ENCODING: + st->encode_submode = (*(spx_int32_t*)ptr); + speex_encoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr); + break; + case SPEEX_GET_SUBMODE_ENCODING: + (*(spx_int32_t*)ptr) = st->encode_submode; + break; + case SPEEX_GET_LOOKAHEAD: + speex_encoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr); + (*(spx_int32_t*)ptr) = 2*(*(spx_int32_t*)ptr) + QMF_ORDER - 1; + break; + case SPEEX_SET_PLC_TUNING: + speex_encoder_ctl(st->st_low, SPEEX_SET_PLC_TUNING, ptr); + break; + case SPEEX_GET_PLC_TUNING: + speex_encoder_ctl(st->st_low, SPEEX_GET_PLC_TUNING, ptr); + break; +#ifndef DISABLE_VBR + case SPEEX_SET_VBR_MAX_BITRATE: + { + st->vbr_max = (*(spx_int32_t*)ptr); + if (SPEEX_SET_VBR_MAX_BITRATE<1) + { + speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_MAX_BITRATE, &st->vbr_max); + st->vbr_max_high = 17600; + } else { + spx_int32_t low_rate; + if (st->vbr_max >= 42200) + { + st->vbr_max_high = 17600; + } else if (st->vbr_max >= 27800) + { + st->vbr_max_high = 9600; + } else if (st->vbr_max > 20600) + { + st->vbr_max_high = 5600; + } else { + st->vbr_max_high = 1800; + } + if (st->subframeSize==80) + st->vbr_max_high = 1800; + low_rate = st->vbr_max - st->vbr_max_high; + speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_MAX_BITRATE, &low_rate); + } + } + break; + case SPEEX_GET_VBR_MAX_BITRATE: + (*(spx_int32_t*)ptr) = st->vbr_max; + break; +#endif /* #ifndef DISABLE_VBR */ + case SPEEX_SET_HIGHPASS: + speex_encoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr); + break; + case SPEEX_GET_HIGHPASS: + speex_encoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr); + break; + + + /* This is all internal stuff past this point */ + case SPEEX_GET_PI_GAIN: + { + int i; + spx_word32_t *g = (spx_word32_t*)ptr; + for (i=0;i<st->nbSubframes;i++) + g[i]=st->pi_gain[i]; + } + break; + case SPEEX_GET_EXC: + { + int i; + for (i=0;i<st->nbSubframes;i++) + ((spx_word16_t*)ptr)[i] = st->exc_rms[i]; + } + break; +#ifndef DISABLE_VBR + case SPEEX_GET_RELATIVE_QUALITY: + (*(float*)ptr)=st->relative_quality; + break; +#endif /* #ifndef DISABLE_VBR */ + case SPEEX_SET_INNOVATION_SAVE: + st->innov_rms_save = (spx_word16_t*)ptr; + break; + case SPEEX_SET_WIDEBAND: + speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr); + break; + case SPEEX_GET_STACK: + *((char**)ptr) = st->stack; + break; + default: + speex_warning_int("Unknown nb_ctl request: ", request); + return -1; + } + return 0; +} + +int sb_decoder_ctl(void *state, int request, void *ptr) +{ + SBDecState *st; + st=(SBDecState*)state; + switch(request) + { + case SPEEX_SET_HIGH_MODE: + st->submodeID = (*(spx_int32_t*)ptr); + break; + case SPEEX_SET_LOW_MODE: + speex_decoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr); + break; + case SPEEX_GET_LOW_MODE: + speex_decoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr); + break; + case SPEEX_GET_FRAME_SIZE: + (*(spx_int32_t*)ptr) = st->full_frame_size; + break; + case SPEEX_SET_ENH: + speex_decoder_ctl(st->st_low, request, ptr); + st->lpc_enh_enabled = *((spx_int32_t*)ptr); + break; + case SPEEX_GET_ENH: + *((spx_int32_t*)ptr) = st->lpc_enh_enabled; + break; + case SPEEX_SET_MODE: + case SPEEX_SET_QUALITY: + { + spx_int32_t nb_qual; + int quality = (*(spx_int32_t*)ptr); + if (quality < 0) + quality = 0; + if (quality > 10) + quality = 10; + st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality]; + nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality]; + speex_decoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual); + } + break; + case SPEEX_GET_BITRATE: + speex_decoder_ctl(st->st_low, request, ptr); + if (st->submodes[st->submodeID]) + (*(spx_int32_t*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size; + else + (*(spx_int32_t*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size; + break; + case SPEEX_SET_SAMPLING_RATE: + { + spx_int32_t tmp=(*(spx_int32_t*)ptr); + st->sampling_rate = tmp; + tmp>>=1; + speex_decoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp); + } + break; + case SPEEX_GET_SAMPLING_RATE: + (*(spx_int32_t*)ptr)=st->sampling_rate; + break; + case SPEEX_SET_HANDLER: + speex_decoder_ctl(st->st_low, SPEEX_SET_HANDLER, ptr); + break; + case SPEEX_SET_USER_HANDLER: + speex_decoder_ctl(st->st_low, SPEEX_SET_USER_HANDLER, ptr); + break; + case SPEEX_RESET_STATE: + { + int i; + for (i=0;i<2*st->lpcSize;i++) + st->mem_sp[i]=0; + for (i=0;i<QMF_ORDER;i++) + st->g0_mem[i]=st->g1_mem[i]=0; + st->last_ener=0; + } + break; + case SPEEX_SET_SUBMODE_ENCODING: + st->encode_submode = (*(spx_int32_t*)ptr); + speex_decoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr); + break; + case SPEEX_GET_SUBMODE_ENCODING: + (*(spx_int32_t*)ptr) = st->encode_submode; + break; + case SPEEX_GET_LOOKAHEAD: + speex_decoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr); + (*(spx_int32_t*)ptr) = 2*(*(spx_int32_t*)ptr); + break; + case SPEEX_SET_HIGHPASS: + speex_decoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr); + break; + case SPEEX_GET_HIGHPASS: + speex_decoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr); + break; + case SPEEX_GET_ACTIVITY: + speex_decoder_ctl(st->st_low, SPEEX_GET_ACTIVITY, ptr); + break; + case SPEEX_GET_PI_GAIN: + { + int i; + spx_word32_t *g = (spx_word32_t*)ptr; + for (i=0;i<st->nbSubframes;i++) + g[i]=st->pi_gain[i]; + } + break; + case SPEEX_GET_EXC: + { + int i; + for (i=0;i<st->nbSubframes;i++) + ((spx_word16_t*)ptr)[i] = st->exc_rms[i]; + } + break; + case SPEEX_GET_DTX_STATUS: + speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, ptr); + break; + case SPEEX_SET_INNOVATION_SAVE: + st->innov_save = (spx_word16_t*)ptr; + break; + case SPEEX_SET_WIDEBAND: + speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr); + break; + case SPEEX_GET_STACK: + *((char**)ptr) = st->stack; + break; + default: + speex_warning_int("Unknown nb_ctl request: ", request); + return -1; + } + return 0; +} + +#endif + diff --git a/src/libs/speex/libspeex/sb_celp.h b/src/libs/speex/libspeex/sb_celp.h new file mode 100644 index 00000000..e8c37612 --- /dev/null +++ b/src/libs/speex/libspeex/sb_celp.h @@ -0,0 +1,155 @@ +/* Copyright (C) 2002-2006 Jean-Marc Valin */ +/** + @file sb_celp.h + @brief Sub-band CELP mode used for wideband encoding +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef SB_CELP_H +#define SB_CELP_H + +#include "modes.h" +#include <speex/speex_bits.h> +#include "nb_celp.h" + +/**Structure representing the full state of the sub-band encoder*/ +typedef struct SBEncState { + const SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */ + void *st_low; /**< State of the low-band (narrowband) encoder */ + int full_frame_size; /**< Length of full-band frames*/ + int frame_size; /**< Length of high-band frames*/ + int subframeSize; /**< Length of high-band sub-frames*/ + int nbSubframes; /**< Number of high-band sub-frames*/ + int windowSize; /**< Length of high-band LPC window*/ + int lpcSize; /**< Order of high-band LPC analysis */ + int first; /**< First frame? */ + spx_word16_t lpc_floor; /**< Controls LPC analysis noise floor */ + spx_word16_t gamma1; /**< Perceptual weighting coef 1 */ + spx_word16_t gamma2; /**< Perceptual weighting coef 2 */ + + char *stack; /**< Temporary allocation stack */ + spx_word16_t *high; /**< High-band signal (buffer) */ + spx_word16_t *h0_mem, *h1_mem; + + const spx_word16_t *window; /**< LPC analysis window */ + const spx_word16_t *lagWindow; /**< Auto-correlation window */ + spx_lsp_t *old_lsp; /**< LSPs of previous frame */ + spx_lsp_t *old_qlsp; /**< Quantized LSPs of previous frame */ + spx_coef_t *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */ + + spx_mem_t *mem_sp; /**< Synthesis signal memory */ + spx_mem_t *mem_sp2; + spx_mem_t *mem_sw; /**< Perceptual signal memory */ + spx_word32_t *pi_gain; + spx_word16_t *exc_rms; + spx_word16_t *innov_rms_save; /**< If non-NULL, innovation is copied here */ + +#ifndef DISABLE_VBR + float vbr_quality; /**< Quality setting for VBR encoding */ + int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */ + spx_int32_t vbr_max; /**< Max bit-rate allowed in VBR mode (total) */ + spx_int32_t vbr_max_high; /**< Max bit-rate allowed in VBR mode for the high-band */ + spx_int32_t abr_enabled; /**< ABR setting (in bps), 0 if off */ + float abr_drift; + float abr_drift2; + float abr_count; + int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */ + float relative_quality; +#endif /* #ifndef DISABLE_VBR */ + + int encode_submode; + const SpeexSubmode * const *submodes; + int submodeID; + int submodeSelect; + int complexity; + spx_int32_t sampling_rate; + +} SBEncState; + + +/**Structure representing the full state of the sub-band decoder*/ +typedef struct SBDecState { + const SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */ + void *st_low; /**< State of the low-band (narrowband) encoder */ + int full_frame_size; + int frame_size; + int subframeSize; + int nbSubframes; + int lpcSize; + int first; + spx_int32_t sampling_rate; + int lpc_enh_enabled; + + char *stack; + spx_word16_t *g0_mem, *g1_mem; + + spx_word16_t *excBuf; + spx_lsp_t *old_qlsp; + spx_coef_t *interp_qlpc; + + spx_mem_t *mem_sp; + spx_word32_t *pi_gain; + spx_word16_t *exc_rms; + spx_word16_t *innov_save; /** If non-NULL, innovation is copied here */ + + spx_word16_t last_ener; + spx_int32_t seed; + + int encode_submode; + const SpeexSubmode * const *submodes; + int submodeID; +} SBDecState; + + +/**Initializes encoder state*/ +void *sb_encoder_init(const SpeexMode *m); + +/**De-allocates encoder state resources*/ +void sb_encoder_destroy(void *state); + +/**Encodes one frame*/ +int sb_encode(void *state, void *in, SpeexBits *bits); + + +/**Initializes decoder state*/ +void *sb_decoder_init(const SpeexMode *m); + +/**De-allocates decoder state resources*/ +void sb_decoder_destroy(void *state); + +/**Decodes one frame*/ +int sb_decode(void *state, SpeexBits *bits, void *out); + +int sb_encoder_ctl(void *state, int request, void *ptr); + +int sb_decoder_ctl(void *state, int request, void *ptr); + +#endif diff --git a/src/libs/speex/libspeex/scal.c b/src/libs/speex/libspeex/scal.c new file mode 100644 index 00000000..2ecd34cd --- /dev/null +++ b/src/libs/speex/libspeex/scal.c @@ -0,0 +1,290 @@ +/* Copyright (C) 2006-2008 CSIRO, Jean-Marc Valin, Xiph.Org Foundation + + File: scal.c + Shaped comb-allpass filter for channel decorrelation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +The algorithm implemented here is described in: + +* J.-M. Valin, Perceptually-Motivated Nonlinear Channel Decorrelation For + Stereo Acoustic Echo Cancellation, Accepted for Joint Workshop on + Hands­free Speech Communication and Microphone Arrays (HSCMA), 2008. + http://people.xiph.org/~jm/papers/valin_hscma2008.pdf + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "speex/speex_echo.h" +#include "vorbis_psy.h" +#include "arch.h" +#include "os_support.h" +#include "smallft.h" +#include <math.h> +#include <stdlib.h> + +#define EXPORT +#define ALLPASS_ORDER 20 + +struct SpeexDecorrState_ { + int rate; + int channels; + int frame_size; +#ifdef VORBIS_PSYCHO + VorbisPsy *psy; + struct drft_lookup lookup; + float *wola_mem; + float *curve; +#endif + float *vorbis_win; + int seed; + float *y; + + /* Per-channel stuff */ + float *buff; + float (*ring)[ALLPASS_ORDER]; + int *ringID; + int *order; + float *alpha; +}; + + + +EXPORT SpeexDecorrState *speex_decorrelate_new(int rate, int channels, int frame_size) +{ + int i, ch; + SpeexDecorrState *st = speex_alloc(sizeof(SpeexDecorrState)); + st->rate = rate; + st->channels = channels; + st->frame_size = frame_size; +#ifdef VORBIS_PSYCHO + st->psy = vorbis_psy_init(rate, 2*frame_size); + spx_drft_init(&st->lookup, 2*frame_size); + st->wola_mem = speex_alloc(frame_size*sizeof(float)); + st->curve = speex_alloc(frame_size*sizeof(float)); +#endif + st->y = speex_alloc(frame_size*sizeof(float)); + + st->buff = speex_alloc(channels*2*frame_size*sizeof(float)); + st->ringID = speex_alloc(channels*sizeof(int)); + st->order = speex_alloc(channels*sizeof(int)); + st->alpha = speex_alloc(channels*sizeof(float)); + st->ring = speex_alloc(channels*ALLPASS_ORDER*sizeof(float)); + + /*FIXME: The +20 is there only as a kludge for ALL_PASS_OLA*/ + st->vorbis_win = speex_alloc((2*frame_size+20)*sizeof(float)); + for (i=0;i<2*frame_size;i++) + st->vorbis_win[i] = sin(.5*M_PI* sin(M_PI*i/(2*frame_size))*sin(M_PI*i/(2*frame_size)) ); + st->seed = rand(); + + for (ch=0;ch<channels;ch++) + { + for (i=0;i<ALLPASS_ORDER;i++) + st->ring[ch][i] = 0; + st->ringID[ch] = 0; + st->alpha[ch] = 0; + st->order[ch] = 10; + } + return st; +} + +static float uni_rand(int *seed) +{ + const unsigned int jflone = 0x3f800000; + const unsigned int jflmsk = 0x007fffff; + union {int i; float f;} ran; + *seed = 1664525 * *seed + 1013904223; + ran.i = jflone | (jflmsk & *seed); + ran.f -= 1.5; + return 2*ran.f; +} + +static unsigned int irand(int *seed) +{ + *seed = 1664525 * *seed + 1013904223; + return ((unsigned int)*seed)>>16; +} + + +EXPORT void speex_decorrelate(SpeexDecorrState *st, const spx_int16_t *in, spx_int16_t *out, int strength) +{ + int ch; + float amount; + + if (strength<0) + strength = 0; + if (strength>100) + strength = 100; + + amount = .01*strength; + for (ch=0;ch<st->channels;ch++) + { + int i; + int N=2*st->frame_size; + float beta, beta2; + float *x; + float max_alpha = 0; + + float *buff; + float *ring; + int ringID; + int order; + float alpha; + + buff = st->buff+ch*2*st->frame_size; + ring = st->ring[ch]; + ringID = st->ringID[ch]; + order = st->order[ch]; + alpha = st->alpha[ch]; + + for (i=0;i<st->frame_size;i++) + buff[i] = buff[i+st->frame_size]; + for (i=0;i<st->frame_size;i++) + buff[i+st->frame_size] = in[i*st->channels+ch]; + + x = buff+st->frame_size; + beta = 1.-.3*amount*amount; + if (amount>1) + beta = 1-sqrt(.4*amount); + else + beta = 1-0.63246*amount; + if (beta<0) + beta = 0; + + beta2 = beta; + for (i=0;i<st->frame_size;i++) + { + st->y[i] = alpha*(x[i-ALLPASS_ORDER+order]-beta*x[i-ALLPASS_ORDER+order-1])*st->vorbis_win[st->frame_size+i+order] + + x[i-ALLPASS_ORDER]*st->vorbis_win[st->frame_size+i] + - alpha*(ring[ringID] + - beta*ring[ringID+1>=order?0:ringID+1]); + ring[ringID++]=st->y[i]; + st->y[i] *= st->vorbis_win[st->frame_size+i]; + if (ringID>=order) + ringID=0; + } + order = order+(irand(&st->seed)%3)-1; + if (order < 5) + order = 5; + if (order > 10) + order = 10; + /*order = 5+(irand(&st->seed)%6);*/ + max_alpha = pow(.96+.04*(amount-1),order); + if (max_alpha > .98/(1.+beta2)) + max_alpha = .98/(1.+beta2); + + alpha = alpha + .4*uni_rand(&st->seed); + if (alpha > max_alpha) + alpha = max_alpha; + if (alpha < -max_alpha) + alpha = -max_alpha; + for (i=0;i<ALLPASS_ORDER;i++) + ring[i] = 0; + ringID = 0; + for (i=0;i<st->frame_size;i++) + { + float tmp = alpha*(x[i-ALLPASS_ORDER+order]-beta*x[i-ALLPASS_ORDER+order-1])*st->vorbis_win[i+order] + + x[i-ALLPASS_ORDER]*st->vorbis_win[i] + - alpha*(ring[ringID] + - beta*ring[ringID+1>=order?0:ringID+1]); + ring[ringID++]=tmp; + tmp *= st->vorbis_win[i]; + if (ringID>=order) + ringID=0; + st->y[i] += tmp; + } + +#ifdef VORBIS_PSYCHO + float frame[N]; + float scale = 1./N; + for (i=0;i<2*st->frame_size;i++) + frame[i] = buff[i]; + //float coef = .5*0.78130; + float coef = M_PI*0.075063 * 0.93763 * amount * .8 * 0.707; + compute_curve(st->psy, buff, st->curve); + for (i=1;i<st->frame_size;i++) + { + float x1,x2; + float gain; + do { + x1 = uni_rand(&st->seed); + x2 = uni_rand(&st->seed); + } while (x1*x1+x2*x2 > 1.); + gain = coef*sqrt(.1+st->curve[i]); + frame[2*i-1] = gain*x1; + frame[2*i] = gain*x2; + } + frame[0] = coef*uni_rand(&st->seed)*sqrt(.1+st->curve[0]); + frame[2*st->frame_size-1] = coef*uni_rand(&st->seed)*sqrt(.1+st->curve[st->frame_size-1]); + spx_drft_backward(&st->lookup,frame); + for (i=0;i<2*st->frame_size;i++) + frame[i] *= st->vorbis_win[i]; +#endif + + for (i=0;i<st->frame_size;i++) + { +#ifdef VORBIS_PSYCHO + float tmp = st->y[i] + frame[i] + st->wola_mem[i]; + st->wola_mem[i] = frame[i+st->frame_size]; +#else + float tmp = st->y[i]; +#endif + if (tmp>32767) + tmp = 32767; + if (tmp < -32767) + tmp = -32767; + out[i*st->channels+ch] = tmp; + } + + st->ringID[ch] = ringID; + st->order[ch] = order; + st->alpha[ch] = alpha; + + } +} + +EXPORT void speex_decorrelate_destroy(SpeexDecorrState *st) +{ +#ifdef VORBIS_PSYCHO + vorbis_psy_destroy(st->psy); + speex_free(st->wola_mem); + speex_free(st->curve); +#endif + speex_free(st->buff); + speex_free(st->ring); + speex_free(st->ringID); + speex_free(st->alpha); + speex_free(st->vorbis_win); + speex_free(st->order); + speex_free(st->y); + speex_free(st); +} diff --git a/src/libs/speex/libspeex/smallft.c b/src/libs/speex/libspeex/smallft.c new file mode 100644 index 00000000..5c26d016 --- /dev/null +++ b/src/libs/speex/libspeex/smallft.c @@ -0,0 +1,1261 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: *unnormalized* fft transform + last mod: $Id: smallft.c,v 1.19 2003/10/08 05:12:37 jm Exp $ + + ********************************************************************/ + +/* FFT implementation from OggSquish, minus cosine transforms, + * minus all but radix 2/4 case. In Vorbis we only need this + * cut-down version. + * + * To do more than just power-of-two sized vectors, see the full + * version I wrote for NetLib. + * + * Note that the packing is a little strange; rather than the FFT r/i + * packing following R_0, I_n, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, + * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the + * FORTRAN version + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <math.h> +#include "smallft.h" +#include "arch.h" +#include "os_support.h" + +static void drfti1(int n, float *wa, int *ifac){ + static int ntryh[4] = { 4,2,3,5 }; + static float tpi = 6.28318530717958648f; + float arg,argh,argld,fi; + int ntry=0,i,j=-1; + int k1, l1, l2, ib; + int ld, ii, ip, is, nq, nr; + int ido, ipm, nfm1; + int nl=n; + int nf=0; + + L101: + j++; + if (j < 4) + ntry=ntryh[j]; + else + ntry+=2; + + L104: + nq=nl/ntry; + nr=nl-ntry*nq; + if (nr!=0) goto L101; + + nf++; + ifac[nf+1]=ntry; + nl=nq; + if(ntry!=2)goto L107; + if(nf==1)goto L107; + + for (i=1;i<nf;i++){ + ib=nf-i+1; + ifac[ib+1]=ifac[ib]; + } + ifac[2] = 2; + + L107: + if(nl!=1)goto L104; + ifac[0]=n; + ifac[1]=nf; + argh=tpi/n; + is=0; + nfm1=nf-1; + l1=1; + + if(nfm1==0)return; + + for (k1=0;k1<nfm1;k1++){ + ip=ifac[k1+2]; + ld=0; + l2=l1*ip; + ido=n/l2; + ipm=ip-1; + + for (j=0;j<ipm;j++){ + ld+=l1; + i=is; + argld=(float)ld*argh; + fi=0.f; + for (ii=2;ii<ido;ii+=2){ + fi+=1.f; + arg=fi*argld; + wa[i++]=cos(arg); + wa[i++]=sin(arg); + } + is+=ido; + } + l1=l2; + } +} + +static void fdrffti(int n, float *wsave, int *ifac){ + + if (n == 1) return; + drfti1(n, wsave+n, ifac); +} + +static void dradf2(int ido,int l1,float *cc,float *ch,float *wa1){ + int i,k; + float ti2,tr2; + int t0,t1,t2,t3,t4,t5,t6; + + t1=0; + t0=(t2=l1*ido); + t3=ido<<1; + for(k=0;k<l1;k++){ + ch[t1<<1]=cc[t1]+cc[t2]; + ch[(t1<<1)+t3-1]=cc[t1]-cc[t2]; + t1+=ido; + t2+=ido; + } + + if(ido<2)return; + if(ido==2)goto L105; + + t1=0; + t2=t0; + for(k=0;k<l1;k++){ + t3=t2; + t4=(t1<<1)+(ido<<1); + t5=t1; + t6=t1+t1; + for(i=2;i<ido;i+=2){ + t3+=2; + t4-=2; + t5+=2; + t6+=2; + tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3]; + ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1]; + ch[t6]=cc[t5]+ti2; + ch[t4]=ti2-cc[t5]; + ch[t6-1]=cc[t5-1]+tr2; + ch[t4-1]=cc[t5-1]-tr2; + } + t1+=ido; + t2+=ido; + } + + if(ido%2==1)return; + + L105: + t3=(t2=(t1=ido)-1); + t2+=t0; + for(k=0;k<l1;k++){ + ch[t1]=-cc[t2]; + ch[t1-1]=cc[t3]; + t1+=ido<<1; + t2+=ido; + t3+=ido; + } +} + +static void dradf4(int ido,int l1,float *cc,float *ch,float *wa1, + float *wa2,float *wa3){ + static float hsqt2 = .70710678118654752f; + int i,k,t0,t1,t2,t3,t4,t5,t6; + float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4; + t0=l1*ido; + + t1=t0; + t4=t1<<1; + t2=t1+(t1<<1); + t3=0; + + for(k=0;k<l1;k++){ + tr1=cc[t1]+cc[t2]; + tr2=cc[t3]+cc[t4]; + + ch[t5=t3<<2]=tr1+tr2; + ch[(ido<<2)+t5-1]=tr2-tr1; + ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4]; + ch[t5]=cc[t2]-cc[t1]; + + t1+=ido; + t2+=ido; + t3+=ido; + t4+=ido; + } + + if(ido<2)return; + if(ido==2)goto L105; + + + t1=0; + for(k=0;k<l1;k++){ + t2=t1; + t4=t1<<2; + t5=(t6=ido<<1)+t4; + for(i=2;i<ido;i+=2){ + t3=(t2+=2); + t4+=2; + t5-=2; + + t3+=t0; + cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3]; + ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1]; + t3+=t0; + cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3]; + ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1]; + t3+=t0; + cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3]; + ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1]; + + tr1=cr2+cr4; + tr4=cr4-cr2; + ti1=ci2+ci4; + ti4=ci2-ci4; + + ti2=cc[t2]+ci3; + ti3=cc[t2]-ci3; + tr2=cc[t2-1]+cr3; + tr3=cc[t2-1]-cr3; + + ch[t4-1]=tr1+tr2; + ch[t4]=ti1+ti2; + + ch[t5-1]=tr3-ti4; + ch[t5]=tr4-ti3; + + ch[t4+t6-1]=ti4+tr3; + ch[t4+t6]=tr4+ti3; + + ch[t5+t6-1]=tr2-tr1; + ch[t5+t6]=ti1-ti2; + } + t1+=ido; + } + if(ido&1)return; + + L105: + + t2=(t1=t0+ido-1)+(t0<<1); + t3=ido<<2; + t4=ido; + t5=ido<<1; + t6=ido; + + for(k=0;k<l1;k++){ + ti1=-hsqt2*(cc[t1]+cc[t2]); + tr1=hsqt2*(cc[t1]-cc[t2]); + + ch[t4-1]=tr1+cc[t6-1]; + ch[t4+t5-1]=cc[t6-1]-tr1; + + ch[t4]=ti1-cc[t1+t0]; + ch[t4+t5]=ti1+cc[t1+t0]; + + t1+=ido; + t2+=ido; + t4+=t3; + t6+=ido; + } +} + +static void dradfg(int ido,int ip,int l1,int idl1,float *cc,float *c1, + float *c2,float *ch,float *ch2,float *wa){ + + static float tpi=6.283185307179586f; + int idij,ipph,i,j,k,l,ic,ik,is; + int t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; + float dc2,ai1,ai2,ar1,ar2,ds2; + int nbd; + float dcp,arg,dsp,ar1h,ar2h; + int idp2,ipp2; + + arg=tpi/(float)ip; + dcp=cos(arg); + dsp=sin(arg); + ipph=(ip+1)>>1; + ipp2=ip; + idp2=ido; + nbd=(ido-1)>>1; + t0=l1*ido; + t10=ip*ido; + + if(ido==1)goto L119; + for(ik=0;ik<idl1;ik++)ch2[ik]=c2[ik]; + + t1=0; + for(j=1;j<ip;j++){ + t1+=t0; + t2=t1; + for(k=0;k<l1;k++){ + ch[t2]=c1[t2]; + t2+=ido; + } + } + + is=-ido; + t1=0; + if(nbd>l1){ + for(j=1;j<ip;j++){ + t1+=t0; + is+=ido; + t2= -ido+t1; + for(k=0;k<l1;k++){ + idij=is-1; + t2+=ido; + t3=t2; + for(i=2;i<ido;i+=2){ + idij+=2; + t3+=2; + ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3]; + ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1]; + } + } + } + }else{ + + for(j=1;j<ip;j++){ + is+=ido; + idij=is-1; + t1+=t0; + t2=t1; + for(i=2;i<ido;i+=2){ + idij+=2; + t2+=2; + t3=t2; + for(k=0;k<l1;k++){ + ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3]; + ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1]; + t3+=ido; + } + } + } + } + + t1=0; + t2=ipp2*t0; + if(nbd<l1){ + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t5=t3-ido; + t6=t4-ido; + for(k=0;k<l1;k++){ + t5+=ido; + t6+=ido; + c1[t5-1]=ch[t5-1]+ch[t6-1]; + c1[t6-1]=ch[t5]-ch[t6]; + c1[t5]=ch[t5]+ch[t6]; + c1[t6]=ch[t6-1]-ch[t5-1]; + } + } + } + }else{ + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(k=0;k<l1;k++){ + t5=t3; + t6=t4; + for(i=2;i<ido;i+=2){ + t5+=2; + t6+=2; + c1[t5-1]=ch[t5-1]+ch[t6-1]; + c1[t6-1]=ch[t5]-ch[t6]; + c1[t5]=ch[t5]+ch[t6]; + c1[t6]=ch[t6-1]-ch[t5-1]; + } + t3+=ido; + t4+=ido; + } + } + } + +L119: + for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik]; + + t1=0; + t2=ipp2*idl1; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1-ido; + t4=t2-ido; + for(k=0;k<l1;k++){ + t3+=ido; + t4+=ido; + c1[t3]=ch[t3]+ch[t4]; + c1[t4]=ch[t4]-ch[t3]; + } + } + + ar1=1.f; + ai1=0.f; + t1=0; + t2=ipp2*idl1; + t3=(ip-1)*idl1; + for(l=1;l<ipph;l++){ + t1+=idl1; + t2-=idl1; + ar1h=dcp*ar1-dsp*ai1; + ai1=dcp*ai1+dsp*ar1; + ar1=ar1h; + t4=t1; + t5=t2; + t6=t3; + t7=idl1; + + for(ik=0;ik<idl1;ik++){ + ch2[t4++]=c2[ik]+ar1*c2[t7++]; + ch2[t5++]=ai1*c2[t6++]; + } + + dc2=ar1; + ds2=ai1; + ar2=ar1; + ai2=ai1; + + t4=idl1; + t5=(ipp2-1)*idl1; + for(j=2;j<ipph;j++){ + t4+=idl1; + t5-=idl1; + + ar2h=dc2*ar2-ds2*ai2; + ai2=dc2*ai2+ds2*ar2; + ar2=ar2h; + + t6=t1; + t7=t2; + t8=t4; + t9=t5; + for(ik=0;ik<idl1;ik++){ + ch2[t6++]+=ar2*c2[t8++]; + ch2[t7++]+=ai2*c2[t9++]; + } + } + } + + t1=0; + for(j=1;j<ipph;j++){ + t1+=idl1; + t2=t1; + for(ik=0;ik<idl1;ik++)ch2[ik]+=c2[t2++]; + } + + if(ido<l1)goto L132; + + t1=0; + t2=0; + for(k=0;k<l1;k++){ + t3=t1; + t4=t2; + for(i=0;i<ido;i++)cc[t4++]=ch[t3++]; + t1+=ido; + t2+=t10; + } + + goto L135; + + L132: + for(i=0;i<ido;i++){ + t1=i; + t2=i; + for(k=0;k<l1;k++){ + cc[t2]=ch[t1]; + t1+=ido; + t2+=t10; + } + } + + L135: + t1=0; + t2=ido<<1; + t3=0; + t4=ipp2*t0; + for(j=1;j<ipph;j++){ + + t1+=t2; + t3+=t0; + t4-=t0; + + t5=t1; + t6=t3; + t7=t4; + + for(k=0;k<l1;k++){ + cc[t5-1]=ch[t6]; + cc[t5]=ch[t7]; + t5+=t10; + t6+=ido; + t7+=ido; + } + } + + if(ido==1)return; + if(nbd<l1)goto L141; + + t1=-ido; + t3=0; + t4=0; + t5=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t2; + t3+=t2; + t4+=t0; + t5-=t0; + t6=t1; + t7=t3; + t8=t4; + t9=t5; + for(k=0;k<l1;k++){ + for(i=2;i<ido;i+=2){ + ic=idp2-i; + cc[i+t7-1]=ch[i+t8-1]+ch[i+t9-1]; + cc[ic+t6-1]=ch[i+t8-1]-ch[i+t9-1]; + cc[i+t7]=ch[i+t8]+ch[i+t9]; + cc[ic+t6]=ch[i+t9]-ch[i+t8]; + } + t6+=t10; + t7+=t10; + t8+=ido; + t9+=ido; + } + } + return; + + L141: + + t1=-ido; + t3=0; + t4=0; + t5=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t2; + t3+=t2; + t4+=t0; + t5-=t0; + for(i=2;i<ido;i+=2){ + t6=idp2+t1-i; + t7=i+t3; + t8=i+t4; + t9=i+t5; + for(k=0;k<l1;k++){ + cc[t7-1]=ch[t8-1]+ch[t9-1]; + cc[t6-1]=ch[t8-1]-ch[t9-1]; + cc[t7]=ch[t8]+ch[t9]; + cc[t6]=ch[t9]-ch[t8]; + t6+=t10; + t7+=t10; + t8+=ido; + t9+=ido; + } + } + } +} + +static void drftf1(int n,float *c,float *ch,float *wa,int *ifac){ + int i,k1,l1,l2; + int na,kh,nf; + int ip,iw,ido,idl1,ix2,ix3; + + nf=ifac[1]; + na=1; + l2=n; + iw=n; + + for(k1=0;k1<nf;k1++){ + kh=nf-k1; + ip=ifac[kh+1]; + l1=l2/ip; + ido=n/l2; + idl1=ido*l1; + iw-=(ip-1)*ido; + na=1-na; + + if(ip!=4)goto L102; + + ix2=iw+ido; + ix3=ix2+ido; + if(na!=0) + dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1); + else + dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1); + goto L110; + + L102: + if(ip!=2)goto L104; + if(na!=0)goto L103; + + dradf2(ido,l1,c,ch,wa+iw-1); + goto L110; + + L103: + dradf2(ido,l1,ch,c,wa+iw-1); + goto L110; + + L104: + if(ido==1)na=1-na; + if(na!=0)goto L109; + + dradfg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1); + na=1; + goto L110; + + L109: + dradfg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1); + na=0; + + L110: + l2=l1; + } + + if(na==1)return; + + for(i=0;i<n;i++)c[i]=ch[i]; +} + +static void dradb2(int ido,int l1,float *cc,float *ch,float *wa1){ + int i,k,t0,t1,t2,t3,t4,t5,t6; + float ti2,tr2; + + t0=l1*ido; + + t1=0; + t2=0; + t3=(ido<<1)-1; + for(k=0;k<l1;k++){ + ch[t1]=cc[t2]+cc[t3+t2]; + ch[t1+t0]=cc[t2]-cc[t3+t2]; + t2=(t1+=ido)<<1; + } + + if(ido<2)return; + if(ido==2)goto L105; + + t1=0; + t2=0; + for(k=0;k<l1;k++){ + t3=t1; + t5=(t4=t2)+(ido<<1); + t6=t0+t1; + for(i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t5-=2; + t6+=2; + ch[t3-1]=cc[t4-1]+cc[t5-1]; + tr2=cc[t4-1]-cc[t5-1]; + ch[t3]=cc[t4]-cc[t5]; + ti2=cc[t4]+cc[t5]; + ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2; + ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2; + } + t2=(t1+=ido)<<1; + } + + if(ido%2==1)return; + +L105: + t1=ido-1; + t2=ido-1; + for(k=0;k<l1;k++){ + ch[t1]=cc[t2]+cc[t2]; + ch[t1+t0]=-(cc[t2+1]+cc[t2+1]); + t1+=ido; + t2+=ido<<1; + } +} + +static void dradb3(int ido,int l1,float *cc,float *ch,float *wa1, + float *wa2){ + static float taur = -.5f; + static float taui = .8660254037844386f; + int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; + float ci2,ci3,di2,di3,cr2,cr3,dr2,dr3,ti2,tr2; + t0=l1*ido; + + t1=0; + t2=t0<<1; + t3=ido<<1; + t4=ido+(ido<<1); + t5=0; + for(k=0;k<l1;k++){ + tr2=cc[t3-1]+cc[t3-1]; + cr2=cc[t5]+(taur*tr2); + ch[t1]=cc[t5]+tr2; + ci3=taui*(cc[t3]+cc[t3]); + ch[t1+t0]=cr2-ci3; + ch[t1+t2]=cr2+ci3; + t1+=ido; + t3+=t4; + t5+=t4; + } + + if(ido==1)return; + + t1=0; + t3=ido<<1; + for(k=0;k<l1;k++){ + t7=t1+(t1<<1); + t6=(t5=t7+t3); + t8=t1; + t10=(t9=t1+t0)+t0; + + for(i=2;i<ido;i+=2){ + t5+=2; + t6-=2; + t7+=2; + t8+=2; + t9+=2; + t10+=2; + tr2=cc[t5-1]+cc[t6-1]; + cr2=cc[t7-1]+(taur*tr2); + ch[t8-1]=cc[t7-1]+tr2; + ti2=cc[t5]-cc[t6]; + ci2=cc[t7]+(taur*ti2); + ch[t8]=cc[t7]+ti2; + cr3=taui*(cc[t5-1]-cc[t6-1]); + ci3=taui*(cc[t5]+cc[t6]); + dr2=cr2-ci3; + dr3=cr2+ci3; + di2=ci2+cr3; + di3=ci2-cr3; + ch[t9-1]=wa1[i-2]*dr2-wa1[i-1]*di2; + ch[t9]=wa1[i-2]*di2+wa1[i-1]*dr2; + ch[t10-1]=wa2[i-2]*dr3-wa2[i-1]*di3; + ch[t10]=wa2[i-2]*di3+wa2[i-1]*dr3; + } + t1+=ido; + } +} + +static void dradb4(int ido,int l1,float *cc,float *ch,float *wa1, + float *wa2,float *wa3){ + static float sqrt2=1.414213562373095f; + int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8; + float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4; + t0=l1*ido; + + t1=0; + t2=ido<<2; + t3=0; + t6=ido<<1; + for(k=0;k<l1;k++){ + t4=t3+t6; + t5=t1; + tr3=cc[t4-1]+cc[t4-1]; + tr4=cc[t4]+cc[t4]; + tr1=cc[t3]-cc[(t4+=t6)-1]; + tr2=cc[t3]+cc[t4-1]; + ch[t5]=tr2+tr3; + ch[t5+=t0]=tr1-tr4; + ch[t5+=t0]=tr2-tr3; + ch[t5+=t0]=tr1+tr4; + t1+=ido; + t3+=t2; + } + + if(ido<2)return; + if(ido==2)goto L105; + + t1=0; + for(k=0;k<l1;k++){ + t5=(t4=(t3=(t2=t1<<2)+t6))+t6; + t7=t1; + for(i=2;i<ido;i+=2){ + t2+=2; + t3+=2; + t4-=2; + t5-=2; + t7+=2; + ti1=cc[t2]+cc[t5]; + ti2=cc[t2]-cc[t5]; + ti3=cc[t3]-cc[t4]; + tr4=cc[t3]+cc[t4]; + tr1=cc[t2-1]-cc[t5-1]; + tr2=cc[t2-1]+cc[t5-1]; + ti4=cc[t3-1]-cc[t4-1]; + tr3=cc[t3-1]+cc[t4-1]; + ch[t7-1]=tr2+tr3; + cr3=tr2-tr3; + ch[t7]=ti2+ti3; + ci3=ti2-ti3; + cr2=tr1-tr4; + cr4=tr1+tr4; + ci2=ti1+ti4; + ci4=ti1-ti4; + + ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2; + ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2; + ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3; + ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3; + ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4; + ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4; + } + t1+=ido; + } + + if(ido%2 == 1)return; + + L105: + + t1=ido; + t2=ido<<2; + t3=ido-1; + t4=ido+(ido<<1); + for(k=0;k<l1;k++){ + t5=t3; + ti1=cc[t1]+cc[t4]; + ti2=cc[t4]-cc[t1]; + tr1=cc[t1-1]-cc[t4-1]; + tr2=cc[t1-1]+cc[t4-1]; + ch[t5]=tr2+tr2; + ch[t5+=t0]=sqrt2*(tr1-ti1); + ch[t5+=t0]=ti2+ti2; + ch[t5+=t0]=-sqrt2*(tr1+ti1); + + t3+=ido; + t1+=t2; + t4+=t2; + } +} + +static void dradbg(int ido,int ip,int l1,int idl1,float *cc,float *c1, + float *c2,float *ch,float *ch2,float *wa){ + static float tpi=6.283185307179586f; + int idij,ipph,i,j,k,l,ik,is,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10, + t11,t12; + float dc2,ai1,ai2,ar1,ar2,ds2; + int nbd; + float dcp,arg,dsp,ar1h,ar2h; + int ipp2; + + t10=ip*ido; + t0=l1*ido; + arg=tpi/(float)ip; + dcp=cos(arg); + dsp=sin(arg); + nbd=(ido-1)>>1; + ipp2=ip; + ipph=(ip+1)>>1; + if(ido<l1)goto L103; + + t1=0; + t2=0; + for(k=0;k<l1;k++){ + t3=t1; + t4=t2; + for(i=0;i<ido;i++){ + ch[t3]=cc[t4]; + t3++; + t4++; + } + t1+=ido; + t2+=t10; + } + goto L106; + + L103: + t1=0; + for(i=0;i<ido;i++){ + t2=t1; + t3=t1; + for(k=0;k<l1;k++){ + ch[t2]=cc[t3]; + t2+=ido; + t3+=t10; + } + t1++; + } + + L106: + t1=0; + t2=ipp2*t0; + t7=(t5=ido<<1); + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + t6=t5; + for(k=0;k<l1;k++){ + ch[t3]=cc[t6-1]+cc[t6-1]; + ch[t4]=cc[t6]+cc[t6]; + t3+=ido; + t4+=ido; + t6+=t10; + } + t5+=t7; + } + + if (ido == 1)goto L116; + if(nbd<l1)goto L112; + + t1=0; + t2=ipp2*t0; + t7=0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + + t7+=(ido<<1); + t8=t7; + for(k=0;k<l1;k++){ + t5=t3; + t6=t4; + t9=t8; + t11=t8; + for(i=2;i<ido;i+=2){ + t5+=2; + t6+=2; + t9+=2; + t11-=2; + ch[t5-1]=cc[t9-1]+cc[t11-1]; + ch[t6-1]=cc[t9-1]-cc[t11-1]; + ch[t5]=cc[t9]-cc[t11]; + ch[t6]=cc[t9]+cc[t11]; + } + t3+=ido; + t4+=ido; + t8+=t10; + } + } + goto L116; + + L112: + t1=0; + t2=ipp2*t0; + t7=0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + t7+=(ido<<1); + t8=t7; + t9=t7; + for(i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t8+=2; + t9-=2; + t5=t3; + t6=t4; + t11=t8; + t12=t9; + for(k=0;k<l1;k++){ + ch[t5-1]=cc[t11-1]+cc[t12-1]; + ch[t6-1]=cc[t11-1]-cc[t12-1]; + ch[t5]=cc[t11]-cc[t12]; + ch[t6]=cc[t11]+cc[t12]; + t5+=ido; + t6+=ido; + t11+=t10; + t12+=t10; + } + } + } + +L116: + ar1=1.f; + ai1=0.f; + t1=0; + t9=(t2=ipp2*idl1); + t3=(ip-1)*idl1; + for(l=1;l<ipph;l++){ + t1+=idl1; + t2-=idl1; + + ar1h=dcp*ar1-dsp*ai1; + ai1=dcp*ai1+dsp*ar1; + ar1=ar1h; + t4=t1; + t5=t2; + t6=0; + t7=idl1; + t8=t3; + for(ik=0;ik<idl1;ik++){ + c2[t4++]=ch2[t6++]+ar1*ch2[t7++]; + c2[t5++]=ai1*ch2[t8++]; + } + dc2=ar1; + ds2=ai1; + ar2=ar1; + ai2=ai1; + + t6=idl1; + t7=t9-idl1; + for(j=2;j<ipph;j++){ + t6+=idl1; + t7-=idl1; + ar2h=dc2*ar2-ds2*ai2; + ai2=dc2*ai2+ds2*ar2; + ar2=ar2h; + t4=t1; + t5=t2; + t11=t6; + t12=t7; + for(ik=0;ik<idl1;ik++){ + c2[t4++]+=ar2*ch2[t11++]; + c2[t5++]+=ai2*ch2[t12++]; + } + } + } + + t1=0; + for(j=1;j<ipph;j++){ + t1+=idl1; + t2=t1; + for(ik=0;ik<idl1;ik++)ch2[ik]+=ch2[t2++]; + } + + t1=0; + t2=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(k=0;k<l1;k++){ + ch[t3]=c1[t3]-c1[t4]; + ch[t4]=c1[t3]+c1[t4]; + t3+=ido; + t4+=ido; + } + } + + if(ido==1)goto L132; + if(nbd<l1)goto L128; + + t1=0; + t2=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(k=0;k<l1;k++){ + t5=t3; + t6=t4; + for(i=2;i<ido;i+=2){ + t5+=2; + t6+=2; + ch[t5-1]=c1[t5-1]-c1[t6]; + ch[t6-1]=c1[t5-1]+c1[t6]; + ch[t5]=c1[t5]+c1[t6-1]; + ch[t6]=c1[t5]-c1[t6-1]; + } + t3+=ido; + t4+=ido; + } + } + goto L132; + + L128: + t1=0; + t2=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t5=t3; + t6=t4; + for(k=0;k<l1;k++){ + ch[t5-1]=c1[t5-1]-c1[t6]; + ch[t6-1]=c1[t5-1]+c1[t6]; + ch[t5]=c1[t5]+c1[t6-1]; + ch[t6]=c1[t5]-c1[t6-1]; + t5+=ido; + t6+=ido; + } + } + } + +L132: + if(ido==1)return; + + for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik]; + + t1=0; + for(j=1;j<ip;j++){ + t2=(t1+=t0); + for(k=0;k<l1;k++){ + c1[t2]=ch[t2]; + t2+=ido; + } + } + + if(nbd>l1)goto L139; + + is= -ido-1; + t1=0; + for(j=1;j<ip;j++){ + is+=ido; + t1+=t0; + idij=is; + t2=t1; + for(i=2;i<ido;i+=2){ + t2+=2; + idij+=2; + t3=t2; + for(k=0;k<l1;k++){ + c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3]; + c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1]; + t3+=ido; + } + } + } + return; + + L139: + is= -ido-1; + t1=0; + for(j=1;j<ip;j++){ + is+=ido; + t1+=t0; + t2=t1; + for(k=0;k<l1;k++){ + idij=is; + t3=t2; + for(i=2;i<ido;i+=2){ + idij+=2; + t3+=2; + c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3]; + c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1]; + } + t2+=ido; + } + } +} + +static void drftb1(int n, float *c, float *ch, float *wa, int *ifac){ + int i,k1,l1,l2; + int na; + int nf,ip,iw,ix2,ix3,ido,idl1; + + nf=ifac[1]; + na=0; + l1=1; + iw=1; + + for(k1=0;k1<nf;k1++){ + ip=ifac[k1 + 2]; + l2=ip*l1; + ido=n/l2; + idl1=ido*l1; + if(ip!=4)goto L103; + ix2=iw+ido; + ix3=ix2+ido; + + if(na!=0) + dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1); + else + dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1); + na=1-na; + goto L115; + + L103: + if(ip!=2)goto L106; + + if(na!=0) + dradb2(ido,l1,ch,c,wa+iw-1); + else + dradb2(ido,l1,c,ch,wa+iw-1); + na=1-na; + goto L115; + + L106: + if(ip!=3)goto L109; + + ix2=iw+ido; + if(na!=0) + dradb3(ido,l1,ch,c,wa+iw-1,wa+ix2-1); + else + dradb3(ido,l1,c,ch,wa+iw-1,wa+ix2-1); + na=1-na; + goto L115; + + L109: +/* The radix five case can be translated later..... */ +/* if(ip!=5)goto L112; + + ix2=iw+ido; + ix3=ix2+ido; + ix4=ix3+ido; + if(na!=0) + dradb5(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1); + else + dradb5(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1); + na=1-na; + goto L115; + + L112:*/ + if(na!=0) + dradbg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1); + else + dradbg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1); + if(ido==1)na=1-na; + + L115: + l1=l2; + iw+=(ip-1)*ido; + } + + if(na==0)return; + + for(i=0;i<n;i++)c[i]=ch[i]; +} + +void spx_drft_forward(struct drft_lookup *l,float *data){ + if(l->n==1)return; + drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); +} + +void spx_drft_backward(struct drft_lookup *l,float *data){ + if (l->n==1)return; + drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); +} + +void spx_drft_init(struct drft_lookup *l,int n) +{ + l->n=n; + l->trigcache=(float*)speex_alloc(3*n*sizeof(*l->trigcache)); + l->splitcache=(int*)speex_alloc(32*sizeof(*l->splitcache)); + fdrffti(n, l->trigcache, l->splitcache); +} + +void spx_drft_clear(struct drft_lookup *l) +{ + if(l) + { + if(l->trigcache) + speex_free(l->trigcache); + if(l->splitcache) + speex_free(l->splitcache); + } +} diff --git a/src/libs/speex/libspeex/smallft.h b/src/libs/speex/libspeex/smallft.h new file mode 100644 index 00000000..446e2f65 --- /dev/null +++ b/src/libs/speex/libspeex/smallft.h @@ -0,0 +1,46 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: fft transform + last mod: $Id: smallft.h,v 1.3 2003/09/16 18:35:45 jm Exp $ + + ********************************************************************/ +/** + @file smallft.h + @brief Discrete Rotational Fourier Transform (DRFT) +*/ + +#ifndef _V_SMFT_H_ +#define _V_SMFT_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** Discrete Rotational Fourier Transform lookup */ +struct drft_lookup{ + int n; + float *trigcache; + int *splitcache; +}; + +extern void spx_drft_forward(struct drft_lookup *l,float *data); +extern void spx_drft_backward(struct drft_lookup *l,float *data); +extern void spx_drft_init(struct drft_lookup *l,int n); +extern void spx_drft_clear(struct drft_lookup *l); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/speex/libspeex/speex.c b/src/libs/speex/libspeex/speex.c new file mode 100644 index 00000000..371be80f --- /dev/null +++ b/src/libs/speex/libspeex/speex.c @@ -0,0 +1,250 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: speex.c + + Basic Speex functions + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "modes.h" +#include <math.h> +#include "os_support.h" + +#ifndef NULL +#define NULL 0 +#endif + +#define MAX_IN_SAMPLES 640 + +#define EXPORT + +EXPORT void *speex_encoder_init(const SpeexMode *mode) +{ + return mode->enc_init(mode); +} + +EXPORT void *speex_decoder_init(const SpeexMode *mode) +{ + return mode->dec_init(mode); +} + +EXPORT void speex_encoder_destroy(void *state) +{ + (*((SpeexMode**)state))->enc_destroy(state); +} + +EXPORT void speex_decoder_destroy(void *state) +{ + (*((SpeexMode**)state))->dec_destroy(state); +} + + + +int speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits) +{ + return (*((SpeexMode**)state))->enc(state, in, bits); +} + +int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out) +{ + return (*((SpeexMode**)state))->dec(state, bits, out); +} + + + +#ifdef FIXED_POINT + +#ifndef DISABLE_FLOAT_API +EXPORT int speex_encode(void *state, float *in, SpeexBits *bits) +{ + int i; + spx_int32_t N; + spx_int16_t short_in[MAX_IN_SAMPLES]; + speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N); + for (i=0;i<N;i++) + { + if (in[i]>32767.f) + short_in[i] = 32767; + else if (in[i]<-32768.f) + short_in[i] = -32768; + else + short_in[i] = (spx_int16_t)floor(.5+in[i]); + } + return (*((SpeexMode**)state))->enc(state, short_in, bits); +} +#endif /* #ifndef DISABLE_FLOAT_API */ + +EXPORT int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits) +{ + SpeexMode *mode; + mode = *(SpeexMode**)state; + return (mode)->enc(state, in, bits); +} + +#ifndef DISABLE_FLOAT_API +EXPORT int speex_decode(void *state, SpeexBits *bits, float *out) +{ + int i, ret; + spx_int32_t N; + spx_int16_t short_out[MAX_IN_SAMPLES]; + speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N); + ret = (*((SpeexMode**)state))->dec(state, bits, short_out); + for (i=0;i<N;i++) + out[i] = short_out[i]; + return ret; +} +#endif /* #ifndef DISABLE_FLOAT_API */ + +EXPORT int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out) +{ + SpeexMode *mode = *(SpeexMode**)state; + return (mode)->dec(state, bits, out); +} + +#else + +EXPORT int speex_encode(void *state, float *in, SpeexBits *bits) +{ + return (*((SpeexMode**)state))->enc(state, in, bits); +} + +EXPORT int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits) +{ + int i; + spx_int32_t N; + float float_in[MAX_IN_SAMPLES]; + speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N); + for (i=0;i<N;i++) + float_in[i] = in[i]; + return (*((SpeexMode**)state))->enc(state, float_in, bits); +} + +EXPORT int speex_decode(void *state, SpeexBits *bits, float *out) +{ + return (*((SpeexMode**)state))->dec(state, bits, out); +} + +EXPORT int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out) +{ + int i; + spx_int32_t N; + float float_out[MAX_IN_SAMPLES]; + int ret; + speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N); + ret = (*((SpeexMode**)state))->dec(state, bits, float_out); + for (i=0;i<N;i++) + { + if (float_out[i]>32767.f) + out[i] = 32767; + else if (float_out[i]<-32768.f) + out[i] = -32768; + else + out[i] = (spx_int16_t)floor(.5+float_out[i]); + } + return ret; +} +#endif + + + +EXPORT int speex_encoder_ctl(void *state, int request, void *ptr) +{ + return (*((SpeexMode**)state))->enc_ctl(state, request, ptr); +} + +EXPORT int speex_decoder_ctl(void *state, int request, void *ptr) +{ + return (*((SpeexMode**)state))->dec_ctl(state, request, ptr); +} + + + +int nb_mode_query(const void *mode, int request, void *ptr) +{ + const SpeexNBMode *m = (const SpeexNBMode*)mode; + + switch (request) + { + case SPEEX_MODE_FRAME_SIZE: + *((int*)ptr)=m->frameSize; + break; + case SPEEX_SUBMODE_BITS_PER_FRAME: + if (*((int*)ptr)==0) + *((int*)ptr) = NB_SUBMODE_BITS+1; + else if (m->submodes[*((int*)ptr)]==NULL) + *((int*)ptr) = -1; + else + *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame; + break; + default: + speex_warning_int("Unknown nb_mode_query request: ", request); + return -1; + } + return 0; +} + + + +EXPORT int speex_lib_ctl(int request, void *ptr) +{ + switch (request) + { + case SPEEX_LIB_GET_MAJOR_VERSION: + *((int*)ptr) = SPEEX_MAJOR_VERSION; + break; + case SPEEX_LIB_GET_MINOR_VERSION: + *((int*)ptr) = SPEEX_MINOR_VERSION; + break; + case SPEEX_LIB_GET_MICRO_VERSION: + *((int*)ptr) = SPEEX_MICRO_VERSION; + break; + case SPEEX_LIB_GET_EXTRA_VERSION: + *((const char**)ptr) = SPEEX_EXTRA_VERSION; + break; + case SPEEX_LIB_GET_VERSION_STRING: + *((const char**)ptr) = SPEEX_VERSION; + break; + /*case SPEEX_LIB_SET_ALLOC_FUNC: + break; + case SPEEX_LIB_GET_ALLOC_FUNC: + break; + case SPEEX_LIB_SET_FREE_FUNC: + break; + case SPEEX_LIB_GET_FREE_FUNC: + break;*/ + default: + speex_warning_int("Unknown wb_mode_query request: ", request); + return -1; + } + return 0; +} diff --git a/src/libs/speex/libspeex/speex_callbacks.c b/src/libs/speex/libspeex/speex_callbacks.c new file mode 100644 index 00000000..81fcabc7 --- /dev/null +++ b/src/libs/speex/libspeex/speex_callbacks.c @@ -0,0 +1,146 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File speex_callbacks.c + Callback handling and in-band signalling + + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <speex/speex_callbacks.h> +#include "arch.h" +#include "os_support.h" + +#define EXPORT + +EXPORT int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state) +{ + int id; + SpeexCallback *callback; + /*speex_bits_advance(bits, 5);*/ + id=speex_bits_unpack_unsigned(bits, 4); + callback = callback_list+id; + + if (callback->func) + { + return callback->func(bits, state, callback->data); + } else + /*If callback is not registered, skip the right number of bits*/ + { + int adv; + if (id<2) + adv = 1; + else if (id<8) + adv = 4; + else if (id<10) + adv = 8; + else if (id<12) + adv = 16; + else if (id<14) + adv = 32; + else + adv = 64; + speex_bits_advance(bits, adv); + } + return 0; +} + +EXPORT int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data) +{ + spx_int32_t m; + m = speex_bits_unpack_unsigned(bits, 4); + speex_encoder_ctl(data, SPEEX_SET_MODE, &m); + return 0; +} + +EXPORT int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data) +{ + spx_int32_t m; + m = speex_bits_unpack_unsigned(bits, 4); + speex_encoder_ctl(data, SPEEX_SET_LOW_MODE, &m); + return 0; +} + +EXPORT int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data) +{ + spx_int32_t m; + m = speex_bits_unpack_unsigned(bits, 4); + speex_encoder_ctl(data, SPEEX_SET_HIGH_MODE, &m); + return 0; +} + +#ifndef DISABLE_VBR +EXPORT int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data) +{ + spx_int32_t vbr; + vbr = speex_bits_unpack_unsigned(bits, 1); + speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr); + return 0; +} +#endif /* #ifndef DISABLE_VBR */ + +EXPORT int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data) +{ + spx_int32_t enh; + enh = speex_bits_unpack_unsigned(bits, 1); + speex_decoder_ctl(data, SPEEX_SET_ENH, &enh); + return 0; +} + +#ifndef DISABLE_VBR +EXPORT int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data) +{ + float qual; + qual = speex_bits_unpack_unsigned(bits, 4); + speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual); + return 0; +} +#endif /* #ifndef DISABLE_VBR */ + +EXPORT int speex_std_char_handler(SpeexBits *bits, void *state, void *data) +{ + unsigned char ch; + ch = speex_bits_unpack_unsigned(bits, 8); + _speex_putc(ch, data); + /*printf("speex_std_char_handler ch=%x\n", ch);*/ + return 0; +} + + + +/* Default handler for user callbacks: skip it */ +EXPORT int speex_default_user_handler(SpeexBits *bits, void *state, void *data) +{ + int req_size = speex_bits_unpack_unsigned(bits, 4); + speex_bits_advance(bits, 5+8*req_size); + return 0; +} diff --git a/src/libs/speex/libspeex/speex_header.c b/src/libs/speex/libspeex/speex_header.c new file mode 100644 index 00000000..49761a63 --- /dev/null +++ b/src/libs/speex/libspeex/speex_header.c @@ -0,0 +1,202 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: speex_header.c + Describes the Speex header + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "arch.h" +#include <speex/speex_header.h> +#include <speex/speex.h> +#include "os_support.h" + +#ifndef NULL +#define NULL 0 +#endif + +#define EXPORT + +/** Convert little endian */ +static inline spx_int32_t le_int(spx_int32_t i) +{ +#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) ) + spx_uint32_t ui, ret; + ui = i; + ret = ui>>24; + ret |= (ui>>8)&0x0000ff00; + ret |= (ui<<8)&0x00ff0000; + ret |= (ui<<24); + return ret; +#else + return i; +#endif +} + +#define ENDIAN_SWITCH(x) {x=le_int(x);} + + +/* +typedef struct SpeexHeader { + char speex_string[8]; + char speex_version[SPEEX_HEADER_VERSION_LENGTH]; + int speex_version_id; + int header_size; + int rate; + int mode; + int mode_bitstream_version; + int nb_channels; + int bitrate; + int frame_size; + int vbr; + int frames_per_packet; + int extra_headers; + int reserved1; + int reserved2; +} SpeexHeader; +*/ + +EXPORT void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m) +{ + int i; + const char *h="Speex "; + /* + strncpy(header->speex_string, "Speex ", 8); + strncpy(header->speex_version, SPEEX_VERSION, SPEEX_HEADER_VERSION_LENGTH-1); + header->speex_version[SPEEX_HEADER_VERSION_LENGTH-1]=0; + */ + for (i=0;i<8;i++) + header->speex_string[i]=h[i]; + for (i=0;i<SPEEX_HEADER_VERSION_LENGTH-1 && SPEEX_VERSION[i];i++) + header->speex_version[i]=SPEEX_VERSION[i]; + for (;i<SPEEX_HEADER_VERSION_LENGTH;i++) + header->speex_version[i]=0; + + header->speex_version_id = 1; + header->header_size = sizeof(SpeexHeader); + + header->rate = rate; + header->mode = m->modeID; + header->mode_bitstream_version = m->bitstream_version; + if (m->modeID<0) + speex_warning("This mode is meant to be used alone"); + header->nb_channels = nb_channels; + header->bitrate = -1; + speex_mode_query(m, SPEEX_MODE_FRAME_SIZE, &header->frame_size); + header->vbr = 0; + + header->frames_per_packet = 0; + header->extra_headers = 0; + header->reserved1 = 0; + header->reserved2 = 0; +} + +EXPORT char *speex_header_to_packet(SpeexHeader *header, int *size) +{ + SpeexHeader *le_header; + le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader)); + + SPEEX_COPY(le_header, header, 1); + + /*Make sure everything is now little-endian*/ + ENDIAN_SWITCH(le_header->speex_version_id); + ENDIAN_SWITCH(le_header->header_size); + ENDIAN_SWITCH(le_header->rate); + ENDIAN_SWITCH(le_header->mode); + ENDIAN_SWITCH(le_header->mode_bitstream_version); + ENDIAN_SWITCH(le_header->nb_channels); + ENDIAN_SWITCH(le_header->bitrate); + ENDIAN_SWITCH(le_header->frame_size); + ENDIAN_SWITCH(le_header->vbr); + ENDIAN_SWITCH(le_header->frames_per_packet); + ENDIAN_SWITCH(le_header->extra_headers); + + *size = sizeof(SpeexHeader); + return (char *)le_header; +} + +EXPORT SpeexHeader *speex_packet_to_header(char *packet, int size) +{ + int i; + SpeexHeader *le_header; + const char *h = "Speex "; + for (i=0;i<8;i++) + if (packet[i]!=h[i]) + { + speex_notify("This doesn't look like a Speex file"); + return NULL; + } + + /*FIXME: Do we allow larger headers?*/ + if (size < (int)sizeof(SpeexHeader)) + { + speex_notify("Speex header too small"); + return NULL; + } + + le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader)); + + SPEEX_COPY(le_header, (SpeexHeader*)packet, 1); + + /*Make sure everything is converted correctly from little-endian*/ + ENDIAN_SWITCH(le_header->speex_version_id); + ENDIAN_SWITCH(le_header->header_size); + ENDIAN_SWITCH(le_header->rate); + ENDIAN_SWITCH(le_header->mode); + ENDIAN_SWITCH(le_header->mode_bitstream_version); + ENDIAN_SWITCH(le_header->nb_channels); + ENDIAN_SWITCH(le_header->bitrate); + ENDIAN_SWITCH(le_header->frame_size); + ENDIAN_SWITCH(le_header->vbr); + ENDIAN_SWITCH(le_header->frames_per_packet); + ENDIAN_SWITCH(le_header->extra_headers); + + if (le_header->mode >= SPEEX_NB_MODES || le_header->mode < 0) + { + speex_notify("Invalid mode specified in Speex header"); + speex_free (le_header); + return NULL; + } + + if (le_header->nb_channels>2) + le_header->nb_channels = 2; + if (le_header->nb_channels<1) + le_header->nb_channels = 1; + + return le_header; + +} + +EXPORT void speex_header_free(void *ptr) +{ + speex_free(ptr); +} diff --git a/src/libs/speex/libspeex/speex_resample.c b/src/libs/speex/libspeex/speex_resample.c new file mode 100644 index 00000000..ba18d74c --- /dev/null +++ b/src/libs/speex/libspeex/speex_resample.c @@ -0,0 +1,1133 @@ +/* Copyright (C) 2007-2008 Jean-Marc Valin + Copyright (C) 2008 Thorvald Natvig + + File: resample.c + Arbitrary resampling code + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + The design goals of this code are: + - Very fast algorithm + - SIMD-friendly algorithm + - Low memory requirement + - Good *perceptual* quality (and not best SNR) + + Warning: This resampler is relatively new. Although I think I got rid of + all the major bugs and I don't expect the API to change anymore, there + may be something I've missed. So use with caution. + + This algorithm is based on this original resampling algorithm: + Smith, Julius O. Digital Audio Resampling Home Page + Center for Computer Research in Music and Acoustics (CCRMA), + Stanford University, 2007. + Web published at http://www-ccrma.stanford.edu/~jos/resample/. + + There is one main difference, though. This resampler uses cubic + interpolation instead of linear interpolation in the above paper. This + makes the table much smaller and makes it possible to compute that table + on a per-stream basis. In turn, being able to tweak the table for each + stream makes it possible to both reduce complexity on simple ratios + (e.g. 2/3), and get rid of the rounding operations in the inner loop. + The latter both reduces CPU time and makes the algorithm more SIMD-friendly. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef OUTSIDE_SPEEX +#include <stdlib.h> +static void *speex_alloc (int size) {return calloc(size,1);} +static void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);} +static void speex_free (void *ptr) {free(ptr);} +#include "speex_resampler.h" +#include "arch.h" +#else /* OUTSIDE_SPEEX */ + +#include "speex/speex_resampler.h" +#include "arch.h" +#include "os_support.h" +#endif /* OUTSIDE_SPEEX */ + +#include "stack_alloc.h" +#include <math.h> + +#ifndef M_PI +#define M_PI 3.14159263 +#endif + +#ifdef FIXED_POINT +#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x))) +#else +#define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x)))) +#endif + +#define IMAX(a,b) ((a) > (b) ? (a) : (b)) +#define IMIN(a,b) ((a) < (b) ? (a) : (b)) + +#ifndef NULL +#define NULL 0 +#endif + +#ifdef _USE_SSE +#include "resample_sse.h" +#endif + +/* Numer of elements to allocate on the stack */ +#ifdef VAR_ARRAYS +#define FIXED_STACK_ALLOC 8192 +#else +#define FIXED_STACK_ALLOC 1024 +#endif + +#define EXPORT + +typedef int (*resampler_basic_func)(SpeexResamplerState *, spx_uint32_t , const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *); + +struct SpeexResamplerState_ { + spx_uint32_t in_rate; + spx_uint32_t out_rate; + spx_uint32_t num_rate; + spx_uint32_t den_rate; + + int quality; + spx_uint32_t nb_channels; + spx_uint32_t filt_len; + spx_uint32_t mem_alloc_size; + spx_uint32_t buffer_size; + int int_advance; + int frac_advance; + float cutoff; + spx_uint32_t oversample; + int initialised; + int started; + + /* These are per-channel */ + spx_int32_t *last_sample; + spx_uint32_t *samp_frac_num; + spx_uint32_t *magic_samples; + + spx_word16_t *mem; + spx_word16_t *sinc_table; + spx_uint32_t sinc_table_length; + resampler_basic_func resampler_ptr; + + int in_stride; + int out_stride; +} ; + +static double kaiser12_table[68] = { + 0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076, + 0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014, + 0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601, + 0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014, + 0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490, + 0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546, + 0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178, + 0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947, + 0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058, + 0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438, + 0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734, + 0.00001000, 0.00000000}; +/* +static double kaiser12_table[36] = { + 0.99440475, 1.00000000, 0.99440475, 0.97779076, 0.95066529, 0.91384741, + 0.86843014, 0.81573067, 0.75723148, 0.69451601, 0.62920216, 0.56287762, + 0.49704014, 0.43304576, 0.37206735, 0.31506490, 0.26276832, 0.21567274, + 0.17404546, 0.13794294, 0.10723616, 0.08164178, 0.06075685, 0.04409466, + 0.03111947, 0.02127838, 0.01402878, 0.00886058, 0.00531256, 0.00298291, + 0.00153438, 0.00069463, 0.00025272, 0.0000527734, 0.00000500, 0.00000000}; +*/ +static double kaiser10_table[36] = { + 0.99537781, 1.00000000, 0.99537781, 0.98162644, 0.95908712, 0.92831446, + 0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347, + 0.56155915, 0.50119680, 0.44221549, 0.38553619, 0.33194107, 0.28205962, + 0.23636152, 0.19515633, 0.15859932, 0.12670280, 0.09935205, 0.07632451, + 0.05731132, 0.04193980, 0.02979584, 0.02044510, 0.01345224, 0.00839739, + 0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.00000000, 0.00000000}; + +static double kaiser8_table[36] = { + 0.99635258, 1.00000000, 0.99635258, 0.98548012, 0.96759014, 0.94302200, + 0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126, + 0.63451750, 0.58014482, 0.52566725, 0.47185369, 0.41941150, 0.36897272, + 0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758, + 0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490, + 0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000}; + +static double kaiser6_table[36] = { + 0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003, + 0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565, + 0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561, + 0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058, + 0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.08693120, 0.06722600, + 0.05031820, 0.03607231, 0.02432151, 0.01487334, 0.00752000, 0.00000000}; + +struct FuncDef { + double *table; + int oversample; +}; + +static struct FuncDef _KAISER12 = {kaiser12_table, 64}; +#define KAISER12 (&_KAISER12) +/*static struct FuncDef _KAISER12 = {kaiser12_table, 32}; +#define KAISER12 (&_KAISER12)*/ +static struct FuncDef _KAISER10 = {kaiser10_table, 32}; +#define KAISER10 (&_KAISER10) +static struct FuncDef _KAISER8 = {kaiser8_table, 32}; +#define KAISER8 (&_KAISER8) +static struct FuncDef _KAISER6 = {kaiser6_table, 32}; +#define KAISER6 (&_KAISER6) + +struct QualityMapping { + int base_length; + int oversample; + float downsample_bandwidth; + float upsample_bandwidth; + struct FuncDef *window_func; +}; + + +/* This table maps conversion quality to internal parameters. There are two + reasons that explain why the up-sampling bandwidth is larger than the + down-sampling bandwidth: + 1) When up-sampling, we can assume that the spectrum is already attenuated + close to the Nyquist rate (from an A/D or a previous resampling filter) + 2) Any aliasing that occurs very close to the Nyquist rate will be masked + by the sinusoids/noise just below the Nyquist rate (guaranteed only for + up-sampling). +*/ +static const struct QualityMapping quality_map[11] = { + { 8, 4, 0.830f, 0.860f, KAISER6 }, /* Q0 */ + { 16, 4, 0.850f, 0.880f, KAISER6 }, /* Q1 */ + { 32, 4, 0.882f, 0.910f, KAISER6 }, /* Q2 */ /* 82.3% cutoff ( ~60 dB stop) 6 */ + { 48, 8, 0.895f, 0.917f, KAISER8 }, /* Q3 */ /* 84.9% cutoff ( ~80 dB stop) 8 */ + { 64, 8, 0.921f, 0.940f, KAISER8 }, /* Q4 */ /* 88.7% cutoff ( ~80 dB stop) 8 */ + { 80, 16, 0.922f, 0.940f, KAISER10}, /* Q5 */ /* 89.1% cutoff (~100 dB stop) 10 */ + { 96, 16, 0.940f, 0.945f, KAISER10}, /* Q6 */ /* 91.5% cutoff (~100 dB stop) 10 */ + {128, 16, 0.950f, 0.950f, KAISER10}, /* Q7 */ /* 93.1% cutoff (~100 dB stop) 10 */ + {160, 16, 0.960f, 0.960f, KAISER10}, /* Q8 */ /* 94.5% cutoff (~100 dB stop) 10 */ + {192, 32, 0.968f, 0.968f, KAISER12}, /* Q9 */ /* 95.5% cutoff (~100 dB stop) 10 */ + {256, 32, 0.975f, 0.975f, KAISER12}, /* Q10 */ /* 96.6% cutoff (~100 dB stop) 10 */ +}; +/*8,24,40,56,80,104,128,160,200,256,320*/ +static double compute_func(float x, struct FuncDef *func) +{ + float y, frac; + double interp[4]; + int ind; + y = x*func->oversample; + ind = (int)floor(y); + frac = (y-ind); + /* CSE with handle the repeated powers */ + interp[3] = -0.1666666667*frac + 0.1666666667*(frac*frac*frac); + interp[2] = frac + 0.5*(frac*frac) - 0.5*(frac*frac*frac); + /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ + interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac); + /* Just to make sure we don't have rounding problems */ + interp[1] = 1.f-interp[3]-interp[2]-interp[0]; + + /*sum = frac*accum[1] + (1-frac)*accum[2];*/ + return interp[0]*func->table[ind] + interp[1]*func->table[ind+1] + interp[2]*func->table[ind+2] + interp[3]*func->table[ind+3]; +} + +#if 0 +#include <stdio.h> +int main(int argc, char **argv) +{ + int i; + for (i=0;i<256;i++) + { + printf ("%f\n", compute_func(i/256., KAISER12)); + } + return 0; +} +#endif + +#ifdef FIXED_POINT +/* The slow way of computing a sinc for the table. Should improve that some day */ +static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func) +{ + /*fprintf (stderr, "%f ", x);*/ + float xx = x * cutoff; + if (fabs(x)<1e-6f) + return WORD2INT(32768.*cutoff); + else if (fabs(x) > .5f*N) + return 0; + /*FIXME: Can it really be any slower than this? */ + return WORD2INT(32768.*cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func)); +} +#else +/* The slow way of computing a sinc for the table. Should improve that some day */ +static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func) +{ + /*fprintf (stderr, "%f ", x);*/ + float xx = x * cutoff; + if (fabs(x)<1e-6) + return cutoff; + else if (fabs(x) > .5*N) + return 0; + /*FIXME: Can it really be any slower than this? */ + return cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func); +} +#endif + +#ifdef FIXED_POINT +static void cubic_coef(spx_word16_t x, spx_word16_t interp[4]) +{ + /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation + but I know it's MMSE-optimal on a sinc */ + spx_word16_t x2, x3; + x2 = MULT16_16_P15(x, x); + x3 = MULT16_16_P15(x, x2); + interp[0] = PSHR32(MULT16_16(QCONST16(-0.16667f, 15),x) + MULT16_16(QCONST16(0.16667f, 15),x3),15); + interp[1] = EXTRACT16(EXTEND32(x) + SHR32(SUB32(EXTEND32(x2),EXTEND32(x3)),1)); + interp[3] = PSHR32(MULT16_16(QCONST16(-0.33333f, 15),x) + MULT16_16(QCONST16(.5f,15),x2) - MULT16_16(QCONST16(0.16667f, 15),x3),15); + /* Just to make sure we don't have rounding problems */ + interp[2] = Q15_ONE-interp[0]-interp[1]-interp[3]; + if (interp[2]<32767) + interp[2]+=1; +} +#else +static void cubic_coef(spx_word16_t frac, spx_word16_t interp[4]) +{ + /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation + but I know it's MMSE-optimal on a sinc */ + interp[0] = -0.16667f*frac + 0.16667f*frac*frac*frac; + interp[1] = frac + 0.5f*frac*frac - 0.5f*frac*frac*frac; + /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ + interp[3] = -0.33333f*frac + 0.5f*frac*frac - 0.16667f*frac*frac*frac; + /* Just to make sure we don't have rounding problems */ + interp[2] = 1.-interp[0]-interp[1]-interp[3]; +} +#endif + +static int resampler_basic_direct_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const spx_word16_t *sinc_table = st->sinc_table; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + spx_word32_t sum; + int j; + + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + const spx_word16_t *sinc = & sinc_table[samp_frac_num*N]; + const spx_word16_t *iptr = & in[last_sample]; + +#ifndef OVERRIDE_INNER_PRODUCT_SINGLE + float accum[4] = {0,0,0,0}; + + for(j=0;j<N;j+=4) { + accum[0] += sinc[j]*iptr[j]; + accum[1] += sinc[j+1]*iptr[j+1]; + accum[2] += sinc[j+2]*iptr[j+2]; + accum[3] += sinc[j+3]*iptr[j+3]; + } + sum = accum[0] + accum[1] + accum[2] + accum[3]; +#else + sum = inner_product_single(sinc, iptr, N); +#endif + + out[out_stride * out_sample++] = PSHR32(sum, 15); + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) + { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} + +#ifdef FIXED_POINT +#else +/* This is the same as the previous function, except with a double-precision accumulator */ +static int resampler_basic_direct_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const spx_word16_t *sinc_table = st->sinc_table; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + double sum; + int j; + + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + const spx_word16_t *sinc = & sinc_table[samp_frac_num*N]; + const spx_word16_t *iptr = & in[last_sample]; + +#ifndef OVERRIDE_INNER_PRODUCT_DOUBLE + double accum[4] = {0,0,0,0}; + + for(j=0;j<N;j+=4) { + accum[0] += sinc[j]*iptr[j]; + accum[1] += sinc[j+1]*iptr[j+1]; + accum[2] += sinc[j+2]*iptr[j+2]; + accum[3] += sinc[j+3]*iptr[j+3]; + } + sum = accum[0] + accum[1] + accum[2] + accum[3]; +#else + sum = inner_product_double(sinc, iptr, N); +#endif + + out[out_stride * out_sample++] = PSHR32(sum, 15); + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) + { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} +#endif + +static int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + int j; + spx_word32_t sum; + + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + const spx_word16_t *iptr = & in[last_sample]; + + const int offset = samp_frac_num*st->oversample/st->den_rate; +#ifdef FIXED_POINT + const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate); +#else + const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate; +#endif + spx_word16_t interp[4]; + + +#ifndef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE + spx_word32_t accum[4] = {0,0,0,0}; + + for(j=0;j<N;j++) { + const spx_word16_t curr_in=iptr[j]; + accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]); + accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); + accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); + accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); + } + + cubic_coef(frac, interp); + sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]); +#else + cubic_coef(frac, interp); + sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); +#endif + + out[out_stride * out_sample++] = PSHR32(sum,15); + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) + { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} + +#ifdef FIXED_POINT +#else +/* This is the same as the previous function, except with a double-precision accumulator */ +static int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + int j; + spx_word32_t sum; + + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + const spx_word16_t *iptr = & in[last_sample]; + + const int offset = samp_frac_num*st->oversample/st->den_rate; +#ifdef FIXED_POINT + const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate); +#else + const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate; +#endif + spx_word16_t interp[4]; + + +#ifndef OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE + double accum[4] = {0,0,0,0}; + + for(j=0;j<N;j++) { + const double curr_in=iptr[j]; + accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]); + accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); + accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); + accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); + } + + cubic_coef(frac, interp); + sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]); +#else + cubic_coef(frac, interp); + sum = interpolate_product_double(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); +#endif + + out[out_stride * out_sample++] = PSHR32(sum,15); + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) + { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} +#endif + +static void update_filter(SpeexResamplerState *st) +{ + spx_uint32_t old_length; + + old_length = st->filt_len; + st->oversample = quality_map[st->quality].oversample; + st->filt_len = quality_map[st->quality].base_length; + + if (st->num_rate > st->den_rate) + { + /* down-sampling */ + st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate; + /* FIXME: divide the numerator and denominator by a certain amount if they're too large */ + st->filt_len = st->filt_len*st->num_rate / st->den_rate; + /* Round down to make sure we have a multiple of 4 */ + st->filt_len &= (~0x3); + if (2*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (4*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (8*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (16*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (st->oversample < 1) + st->oversample = 1; + } else { + /* up-sampling */ + st->cutoff = quality_map[st->quality].upsample_bandwidth; + } + + /* Choose the resampling type that requires the least amount of memory */ + if (st->den_rate <= st->oversample) + { + spx_uint32_t i; + if (!st->sinc_table) + st->sinc_table = (spx_word16_t *)speex_alloc(st->filt_len*st->den_rate*sizeof(spx_word16_t)); + else if (st->sinc_table_length < st->filt_len*st->den_rate) + { + st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,st->filt_len*st->den_rate*sizeof(spx_word16_t)); + st->sinc_table_length = st->filt_len*st->den_rate; + } + for (i=0;i<st->den_rate;i++) + { + spx_int32_t j; + for (j=0;j<st->filt_len;j++) + { + st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-(spx_int32_t)st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func); + } + } +#ifdef FIXED_POINT + st->resampler_ptr = resampler_basic_direct_single; +#else + if (st->quality>8) + st->resampler_ptr = resampler_basic_direct_double; + else + st->resampler_ptr = resampler_basic_direct_single; +#endif + /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/ + } else { + spx_int32_t i; + if (!st->sinc_table) + st->sinc_table = (spx_word16_t *)speex_alloc((st->filt_len*st->oversample+8)*sizeof(spx_word16_t)); + else if (st->sinc_table_length < st->filt_len*st->oversample+8) + { + st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,(st->filt_len*st->oversample+8)*sizeof(spx_word16_t)); + st->sinc_table_length = st->filt_len*st->oversample+8; + } + for (i=-4;i<(spx_int32_t)(st->oversample*st->filt_len+4);i++) + st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)st->oversample - st->filt_len/2), st->filt_len, quality_map[st->quality].window_func); +#ifdef FIXED_POINT + st->resampler_ptr = resampler_basic_interpolate_single; +#else + if (st->quality>8) + st->resampler_ptr = resampler_basic_interpolate_double; + else + st->resampler_ptr = resampler_basic_interpolate_single; +#endif + /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/ + } + st->int_advance = st->num_rate/st->den_rate; + st->frac_advance = st->num_rate%st->den_rate; + + + /* Here's the place where we update the filter memory to take into account + the change in filter length. It's probably the messiest part of the code + due to handling of lots of corner cases. */ + if (!st->mem) + { + spx_uint32_t i; + st->mem_alloc_size = st->filt_len-1 + st->buffer_size; + st->mem = (spx_word16_t*)speex_alloc(st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t)); + for (i=0;i<st->nb_channels*st->mem_alloc_size;i++) + st->mem[i] = 0; + /*speex_warning("init filter");*/ + } else if (!st->started) + { + spx_uint32_t i; + st->mem_alloc_size = st->filt_len-1 + st->buffer_size; + st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t)); + for (i=0;i<st->nb_channels*st->mem_alloc_size;i++) + st->mem[i] = 0; + /*speex_warning("reinit filter");*/ + } else if (st->filt_len > old_length) + { + spx_int32_t i; + /* Increase the filter length */ + /*speex_warning("increase filter size");*/ + int old_alloc_size = st->mem_alloc_size; + if ((st->filt_len-1 + st->buffer_size) > st->mem_alloc_size) + { + st->mem_alloc_size = st->filt_len-1 + st->buffer_size; + st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t)); + } + for (i=st->nb_channels-1;i>=0;i--) + { + spx_int32_t j; + spx_uint32_t olen = old_length; + /*if (st->magic_samples[i])*/ + { + /* Try and remove the magic samples as if nothing had happened */ + + /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */ + olen = old_length + 2*st->magic_samples[i]; + for (j=old_length-2+st->magic_samples[i];j>=0;j--) + st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j]; + for (j=0;j<st->magic_samples[i];j++) + st->mem[i*st->mem_alloc_size+j] = 0; + st->magic_samples[i] = 0; + } + if (st->filt_len > olen) + { + /* If the new filter length is still bigger than the "augmented" length */ + /* Copy data going backward */ + for (j=0;j<olen-1;j++) + st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)]; + /* Then put zeros for lack of anything better */ + for (;j<st->filt_len-1;j++) + st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0; + /* Adjust last_sample */ + st->last_sample[i] += (st->filt_len - olen)/2; + } else { + /* Put back some of the magic! */ + st->magic_samples[i] = (olen - st->filt_len)/2; + for (j=0;j<st->filt_len-1+st->magic_samples[i];j++) + st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; + } + } + } else if (st->filt_len < old_length) + { + spx_uint32_t i; + /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic" + samples so they can be used directly as input the next time(s) */ + for (i=0;i<st->nb_channels;i++) + { + spx_uint32_t j; + spx_uint32_t old_magic = st->magic_samples[i]; + st->magic_samples[i] = (old_length - st->filt_len)/2; + /* We must copy some of the memory that's no longer used */ + /* Copy data going backward */ + for (j=0;j<st->filt_len-1+st->magic_samples[i]+old_magic;j++) + st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; + st->magic_samples[i] += old_magic; + } + } + +} + +EXPORT SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) +{ + return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err); +} + +EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) +{ + spx_uint32_t i; + SpeexResamplerState *st; + if (quality > 10 || quality < 0) + { + if (err) + *err = RESAMPLER_ERR_INVALID_ARG; + return NULL; + } + st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState)); + st->initialised = 0; + st->started = 0; + st->in_rate = 0; + st->out_rate = 0; + st->num_rate = 0; + st->den_rate = 0; + st->quality = -1; + st->sinc_table_length = 0; + st->mem_alloc_size = 0; + st->filt_len = 0; + st->mem = 0; + st->resampler_ptr = 0; + + st->cutoff = 1.f; + st->nb_channels = nb_channels; + st->in_stride = 1; + st->out_stride = 1; + +#ifdef FIXED_POINT + st->buffer_size = 160; +#else + st->buffer_size = 160; +#endif + + /* Per channel data */ + st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(int)); + st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int)); + st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int)); + for (i=0;i<nb_channels;i++) + { + st->last_sample[i] = 0; + st->magic_samples[i] = 0; + st->samp_frac_num[i] = 0; + } + + speex_resampler_set_quality(st, quality); + speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate); + + + update_filter(st); + + st->initialised = 1; + if (err) + *err = RESAMPLER_ERR_SUCCESS; + + return st; +} + +EXPORT void speex_resampler_destroy(SpeexResamplerState *st) +{ + speex_free(st->mem); + speex_free(st->sinc_table); + speex_free(st->last_sample); + speex_free(st->magic_samples); + speex_free(st->samp_frac_num); + speex_free(st); +} + +static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t channel_index, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + int j=0; + const int N = st->filt_len; + int out_sample = 0; + spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size; + spx_uint32_t ilen; + + st->started = 1; + + /* Call the right resampler through the function ptr */ + out_sample = st->resampler_ptr(st, channel_index, mem, in_len, out, out_len); + + if (st->last_sample[channel_index] < (spx_int32_t)*in_len) + *in_len = st->last_sample[channel_index]; + *out_len = out_sample; + st->last_sample[channel_index] -= *in_len; + + ilen = *in_len; + + for(j=0;j<N-1;++j) + mem[j] = mem[j+ilen]; + + return RESAMPLER_ERR_SUCCESS; +} + +static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_index, spx_word16_t **out, spx_uint32_t out_len) { + spx_uint32_t tmp_in_len = st->magic_samples[channel_index]; + spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size; + const int N = st->filt_len; + + speex_resampler_process_native(st, channel_index, &tmp_in_len, *out, &out_len); + + st->magic_samples[channel_index] -= tmp_in_len; + + /* If we couldn't process all "magic" input samples, save the rest for next time */ + if (st->magic_samples[channel_index]) + { + spx_uint32_t i; + for (i=0;i<st->magic_samples[channel_index];i++) + mem[N-1+i]=mem[N-1+i+tmp_in_len]; + } + *out += out_len*st->out_stride; + return out_len; +} + +#ifdef FIXED_POINT +EXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len) +#else +EXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +#endif +{ + int j; + spx_uint32_t ilen = *in_len; + spx_uint32_t olen = *out_len; + spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size; + const int filt_offs = st->filt_len - 1; + const spx_uint32_t xlen = st->mem_alloc_size - filt_offs; + const int istride = st->in_stride; + + if (st->magic_samples[channel_index]) + olen -= speex_resampler_magic(st, channel_index, &out, olen); + if (! st->magic_samples[channel_index]) { + while (ilen && olen) { + spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen; + spx_uint32_t ochunk = olen; + + if (in) { + for(j=0;j<ichunk;++j) + x[j+filt_offs]=in[j*istride]; + } else { + for(j=0;j<ichunk;++j) + x[j+filt_offs]=0; + } + speex_resampler_process_native(st, channel_index, &ichunk, out, &ochunk); + ilen -= ichunk; + olen -= ochunk; + out += ochunk * st->out_stride; + if (in) + in += ichunk * istride; + } + } + *in_len -= ilen; + *out_len -= olen; + return RESAMPLER_ERR_SUCCESS; +} + +#ifdef FIXED_POINT +EXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +#else +EXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len) +#endif +{ + int j; + const int istride_save = st->in_stride; + const int ostride_save = st->out_stride; + spx_uint32_t ilen = *in_len; + spx_uint32_t olen = *out_len; + spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size; + const spx_uint32_t xlen = st->mem_alloc_size - (st->filt_len - 1); +#ifdef VAR_ARRAYS + const unsigned int ylen = (olen < FIXED_STACK_ALLOC) ? olen : FIXED_STACK_ALLOC; + VARDECL(spx_word16_t *ystack); + ALLOC(ystack, ylen, spx_word16_t); +#else + const unsigned int ylen = FIXED_STACK_ALLOC; + spx_word16_t ystack[FIXED_STACK_ALLOC]; +#endif + + st->out_stride = 1; + + while (ilen && olen) { + spx_word16_t *y = ystack; + spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen; + spx_uint32_t ochunk = (olen > ylen) ? ylen : olen; + spx_uint32_t omagic = 0; + + if (st->magic_samples[channel_index]) { + omagic = speex_resampler_magic(st, channel_index, &y, ochunk); + ochunk -= omagic; + olen -= omagic; + } + if (! st->magic_samples[channel_index]) { + if (in) { + for(j=0;j<ichunk;++j) +#ifdef FIXED_POINT + x[j+st->filt_len-1]=WORD2INT(in[j*istride_save]); +#else + x[j+st->filt_len-1]=in[j*istride_save]; +#endif + } else { + for(j=0;j<ichunk;++j) + x[j+st->filt_len-1]=0; + } + + speex_resampler_process_native(st, channel_index, &ichunk, y, &ochunk); + } else { + ichunk = 0; + ochunk = 0; + } + + for (j=0;j<ochunk+omagic;++j) +#ifdef FIXED_POINT + out[j*ostride_save] = ystack[j]; +#else + out[j*ostride_save] = WORD2INT(ystack[j]); +#endif + + ilen -= ichunk; + olen -= ochunk; + out += (ochunk+omagic) * ostride_save; + if (in) + in += ichunk * istride_save; + } + st->out_stride = ostride_save; + *in_len -= ilen; + *out_len -= olen; + + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +{ + spx_uint32_t i; + int istride_save, ostride_save; + spx_uint32_t bak_len = *out_len; + istride_save = st->in_stride; + ostride_save = st->out_stride; + st->in_stride = st->out_stride = st->nb_channels; + for (i=0;i<st->nb_channels;i++) + { + *out_len = bak_len; + if (in != NULL) + speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len); + else + speex_resampler_process_float(st, i, NULL, in_len, out+i, out_len); + } + st->in_stride = istride_save; + st->out_stride = ostride_save; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_process_interleaved_int(SpeexResamplerState *st, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len) +{ + spx_uint32_t i; + int istride_save, ostride_save; + spx_uint32_t bak_len = *out_len; + istride_save = st->in_stride; + ostride_save = st->out_stride; + st->in_stride = st->out_stride = st->nb_channels; + for (i=0;i<st->nb_channels;i++) + { + *out_len = bak_len; + if (in != NULL) + speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len); + else + speex_resampler_process_int(st, i, NULL, in_len, out+i, out_len); + } + st->in_stride = istride_save; + st->out_stride = ostride_save; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate) +{ + return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate); +} + +EXPORT void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate) +{ + *in_rate = st->in_rate; + *out_rate = st->out_rate; +} + +EXPORT int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate) +{ + spx_uint32_t fact; + spx_uint32_t old_den; + spx_uint32_t i; + if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den) + return RESAMPLER_ERR_SUCCESS; + + old_den = st->den_rate; + st->in_rate = in_rate; + st->out_rate = out_rate; + st->num_rate = ratio_num; + st->den_rate = ratio_den; + /* FIXME: This is terribly inefficient, but who cares (at least for now)? */ + for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++) + { + while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0)) + { + st->num_rate /= fact; + st->den_rate /= fact; + } + } + + if (old_den > 0) + { + for (i=0;i<st->nb_channels;i++) + { + st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den; + /* Safety net */ + if (st->samp_frac_num[i] >= st->den_rate) + st->samp_frac_num[i] = st->den_rate-1; + } + } + + if (st->initialised) + update_filter(st); + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den) +{ + *ratio_num = st->num_rate; + *ratio_den = st->den_rate; +} + +EXPORT int speex_resampler_set_quality(SpeexResamplerState *st, int quality) +{ + if (quality > 10 || quality < 0) + return RESAMPLER_ERR_INVALID_ARG; + if (st->quality == quality) + return RESAMPLER_ERR_SUCCESS; + st->quality = quality; + if (st->initialised) + update_filter(st); + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT void speex_resampler_get_quality(SpeexResamplerState *st, int *quality) +{ + *quality = st->quality; +} + +EXPORT void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride) +{ + st->in_stride = stride; +} + +EXPORT void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride) +{ + *stride = st->in_stride; +} + +EXPORT void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride) +{ + st->out_stride = stride; +} + +EXPORT void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride) +{ + *stride = st->out_stride; +} + +EXPORT int speex_resampler_get_input_latency(SpeexResamplerState *st) +{ + return st->filt_len / 2; +} + +EXPORT int speex_resampler_get_output_latency(SpeexResamplerState *st) +{ + return ((st->filt_len / 2) * st->den_rate + (st->num_rate >> 1)) / st->num_rate; +} + +EXPORT int speex_resampler_skip_zeros(SpeexResamplerState *st) +{ + spx_uint32_t i; + for (i=0;i<st->nb_channels;i++) + st->last_sample[i] = st->filt_len/2; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_reset_mem(SpeexResamplerState *st) +{ + spx_uint32_t i; + for (i=0;i<st->nb_channels*(st->filt_len-1);i++) + st->mem[i] = 0; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT const char *speex_resampler_strerror(int err) +{ + switch (err) + { + case RESAMPLER_ERR_SUCCESS: + return "Success."; + case RESAMPLER_ERR_ALLOC_FAILED: + return "Memory allocation failed."; + case RESAMPLER_ERR_BAD_STATE: + return "Bad resampler state."; + case RESAMPLER_ERR_INVALID_ARG: + return "Invalid argument."; + case RESAMPLER_ERR_PTR_OVERLAP: + return "Input and output buffers overlap."; + default: + return "Unknown error. Bad error code or strange version mismatch."; + } +} diff --git a/src/libs/speex/libspeex/stack_alloc.h b/src/libs/speex/libspeex/stack_alloc.h new file mode 100644 index 00000000..5264e666 --- /dev/null +++ b/src/libs/speex/libspeex/stack_alloc.h @@ -0,0 +1,115 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file stack_alloc.h + @brief Temporary memory allocation on stack +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef STACK_ALLOC_H +#define STACK_ALLOC_H + +#ifdef USE_ALLOCA +# ifdef WIN32 +# include <malloc.h> +# else +# ifdef HAVE_ALLOCA_H +# include <alloca.h> +# else +# include <stdlib.h> +# endif +# endif +#endif + +/** + * @def ALIGN(stack, size) + * + * Aligns the stack to a 'size' boundary + * + * @param stack Stack + * @param size New size boundary + */ + +/** + * @def PUSH(stack, size, type) + * + * Allocates 'size' elements of type 'type' on the stack + * + * @param stack Stack + * @param size Number of elements + * @param type Type of element + */ + +/** + * @def VARDECL(var) + * + * Declare variable on stack + * + * @param var Variable to declare + */ + +/** + * @def ALLOC(var, size, type) + * + * Allocate 'size' elements of 'type' on stack + * + * @param var Name of variable to allocate + * @param size Number of elements + * @param type Type of element + */ + +#ifdef ENABLE_VALGRIND + +#include <valgrind/memcheck.h> + +#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) + +#define PUSH(stack, size, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(type)),VALGRIND_MAKE_WRITABLE(stack, ((size)*sizeof(type))),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type)))) + +#else + +#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) + +#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type)))) + +#endif + +#if defined(VAR_ARRAYS) +#define VARDECL(var) +#define ALLOC(var, size, type) type var[size] +#elif defined(USE_ALLOCA) +#define VARDECL(var) var +#define ALLOC(var, size, type) var = alloca(sizeof(type)*(size)) +#else +#define VARDECL(var) var +#define ALLOC(var, size, type) var = PUSH(stack, size, type) +#endif + + +#endif diff --git a/src/libs/speex/libspeex/stereo.c b/src/libs/speex/libspeex/stereo.c new file mode 100644 index 00000000..d566e0d0 --- /dev/null +++ b/src/libs/speex/libspeex/stereo.c @@ -0,0 +1,298 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: stereo.c + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <speex/speex_stereo.h> +#include <speex/speex_callbacks.h> +#include "math_approx.h" +#include "vq.h" +#include <math.h> +#include "os_support.h" + +typedef struct RealSpeexStereoState { + spx_word32_t balance; /**< Left/right balance info */ + spx_word32_t e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */ + spx_word32_t smooth_left; /**< Smoothed left channel gain */ + spx_word32_t smooth_right; /**< Smoothed right channel gain */ + spx_uint32_t reserved1; /**< Reserved for future use */ + spx_int32_t reserved2; /**< Reserved for future use */ +} RealSpeexStereoState; + + +/*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/ +#ifndef FIXED_POINT +static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f}; +static const float e_ratio_quant_bounds[3] = {0.2825f, 0.356f, 0.4485f}; +#else +static const spx_word16_t e_ratio_quant[4] = {8192, 10332, 13009, 16384}; +static const spx_word16_t e_ratio_quant_bounds[3] = {9257, 11665, 14696}; +static const spx_word16_t balance_bounds[31] = {18, 23, 30, 38, 49, 63, 81, 104, + 134, 172, 221, 284, 364, 468, 600, 771, + 990, 1271, 1632, 2096, 2691, 3455, 4436, 5696, + 7314, 9392, 12059, 15484, 19882, 25529, 32766}; +#endif + +/* This is an ugly compatibility hack that properly resets the stereo state + In case it it compiled in fixed-point, but initialised with the deprecated + floating point static initialiser */ +#ifdef FIXED_POINT +#define COMPATIBILITY_HACK(s) do {if ((s)->reserved1 != 0xdeadbeef) speex_stereo_state_reset((SpeexStereoState*)s); } while (0); +#else +#define COMPATIBILITY_HACK(s) +#endif + +#define EXPORT + +EXPORT SpeexStereoState *speex_stereo_state_init() +{ + SpeexStereoState *stereo = speex_alloc(sizeof(SpeexStereoState)); + speex_stereo_state_reset(stereo); + return stereo; +} + +EXPORT void speex_stereo_state_reset(SpeexStereoState *_stereo) +{ + RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; +#ifdef FIXED_POINT + stereo->balance = 65536; + stereo->e_ratio = 16384; + stereo->smooth_left = 16384; + stereo->smooth_right = 16384; + stereo->reserved1 = 0xdeadbeef; + stereo->reserved2 = 0; +#else + stereo->balance = 1.0f; + stereo->e_ratio = .5f; + stereo->smooth_left = 1.f; + stereo->smooth_right = 1.f; + stereo->reserved1 = 0; + stereo->reserved2 = 0; +#endif +} + +EXPORT void speex_stereo_state_destroy(SpeexStereoState *stereo) +{ + speex_free(stereo); +} + +#ifndef DISABLE_FLOAT_API +EXPORT void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits) +{ + int i, tmp; + float e_left=0, e_right=0, e_tot=0; + float balance, e_ratio; + for (i=0;i<frame_size;i++) + { + e_left += ((float)data[2*i])*data[2*i]; + e_right += ((float)data[2*i+1])*data[2*i+1]; + data[i] = .5*(((float)data[2*i])+data[2*i+1]); + e_tot += ((float)data[i])*data[i]; + } + balance=(e_left+1)/(e_right+1); + e_ratio = e_tot/(1+e_left+e_right); + + /*Quantization*/ + speex_bits_pack(bits, 14, 5); + speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4); + + balance=4*log(balance); + + /*Pack sign*/ + if (balance>0) + speex_bits_pack(bits, 0, 1); + else + speex_bits_pack(bits, 1, 1); + balance=floor(.5+fabs(balance)); + if (balance>30) + balance=31; + + speex_bits_pack(bits, (int)balance, 5); + + /* FIXME: this is a hack */ + tmp=scal_quant(e_ratio*Q15_ONE, e_ratio_quant_bounds, 4); + speex_bits_pack(bits, tmp, 2); +} +#endif /* #ifndef DISABLE_FLOAT_API */ + +EXPORT void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits) +{ + int i, tmp; + spx_word32_t e_left=0, e_right=0, e_tot=0; + spx_word32_t balance, e_ratio; + spx_word32_t largest, smallest; + int balance_id; +#ifdef FIXED_POINT + int shift; +#endif + + /* In band marker */ + speex_bits_pack(bits, 14, 5); + /* Stereo marker */ + speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4); + + for (i=0;i<frame_size;i++) + { + e_left += SHR32(MULT16_16(data[2*i],data[2*i]),8); + e_right += SHR32(MULT16_16(data[2*i+1],data[2*i+1]),8); +#ifdef FIXED_POINT + /* I think this is actually unbiased */ + data[i] = SHR16(data[2*i],1)+PSHR16(data[2*i+1],1); +#else + data[i] = .5*(((float)data[2*i])+data[2*i+1]); +#endif + e_tot += SHR32(MULT16_16(data[i],data[i]),8); + } + if (e_left > e_right) + { + speex_bits_pack(bits, 0, 1); + largest = e_left; + smallest = e_right; + } else { + speex_bits_pack(bits, 1, 1); + largest = e_right; + smallest = e_left; + } + + /* Balance quantization */ +#ifdef FIXED_POINT + shift = spx_ilog2(largest)-15; + largest = VSHR32(largest, shift-4); + smallest = VSHR32(smallest, shift); + balance = DIV32(largest, ADD32(smallest, 1)); + if (balance > 32767) + balance = 32767; + balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32); +#else + balance=(largest+1.)/(smallest+1.); + balance=4*log(balance); + balance_id=floor(.5+fabs(balance)); + if (balance_id>30) + balance_id=31; +#endif + + speex_bits_pack(bits, balance_id, 5); + + /* "coherence" quantisation */ +#ifdef FIXED_POINT + shift = spx_ilog2(e_tot); + e_tot = VSHR32(e_tot, shift-25); + e_left = VSHR32(e_left, shift-10); + e_right = VSHR32(e_right, shift-10); + e_ratio = DIV32(e_tot, e_left+e_right+1); +#else + e_ratio = e_tot/(1.+e_left+e_right); +#endif + + tmp=scal_quant(EXTRACT16(e_ratio), e_ratio_quant_bounds, 4); + /*fprintf (stderr, "%d %d %d %d\n", largest, smallest, balance_id, e_ratio);*/ + speex_bits_pack(bits, tmp, 2); +} + +#ifndef DISABLE_FLOAT_API +EXPORT void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *_stereo) +{ + int i; + spx_word32_t balance; + spx_word16_t e_left, e_right, e_ratio; + RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; + + COMPATIBILITY_HACK(stereo); + + balance=stereo->balance; + e_ratio=stereo->e_ratio; + + /* These two are Q14, with max value just below 2. */ + e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance)))); + e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8); + + for (i=frame_size-1;i>=0;i--) + { + spx_word16_t tmp=data[i]; + stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15)); + stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15)); + data[2*i] = (float)MULT16_16_P14(stereo->smooth_left, tmp); + data[2*i+1] = (float)MULT16_16_P14(stereo->smooth_right, tmp); + } +} +#endif /* #ifndef DISABLE_FLOAT_API */ + +EXPORT void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *_stereo) +{ + int i; + spx_word32_t balance; + spx_word16_t e_left, e_right, e_ratio; + RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; + + COMPATIBILITY_HACK(stereo); + + balance=stereo->balance; + e_ratio=stereo->e_ratio; + + /* These two are Q14, with max value just below 2. */ + e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance)))); + e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8); + + for (i=frame_size-1;i>=0;i--) + { + spx_int16_t tmp=data[i]; + stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15)); + stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15)); + data[2*i] = (spx_int16_t)MULT16_16_P14(stereo->smooth_left, tmp); + data[2*i+1] = (spx_int16_t)MULT16_16_P14(stereo->smooth_right, tmp); + } +} + +EXPORT int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data) +{ + RealSpeexStereoState *stereo; + spx_word16_t sign=1, dexp; + int tmp; + + stereo = (RealSpeexStereoState*)data; + + COMPATIBILITY_HACK(stereo); + + if (speex_bits_unpack_unsigned(bits, 1)) + sign=-1; + dexp = speex_bits_unpack_unsigned(bits, 5); +#ifndef FIXED_POINT + stereo->balance = exp(sign*.25*dexp); +#else + stereo->balance = spx_exp(MULT16_16(sign, SHL16(dexp, 9))); +#endif + tmp = speex_bits_unpack_unsigned(bits, 2); + stereo->e_ratio = e_ratio_quant[tmp]; + + return 0; +} diff --git a/src/libs/speex/libspeex/testdenoise.c b/src/libs/speex/libspeex/testdenoise.c new file mode 100644 index 00000000..49f51202 --- /dev/null +++ b/src/libs/speex/libspeex/testdenoise.c @@ -0,0 +1,44 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <speex/speex_preprocess.h> +#include <stdio.h> + +#define NN 160 + +int main() +{ + short in[NN]; + int i; + SpeexPreprocessState *st; + int count=0; + float f; + + st = speex_preprocess_state_init(NN, 8000); + i=1; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i); + i=0; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i); + i=8000; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i); + i=0; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i); + f=.0; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); + f=.0; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); + while (1) + { + int vad; + fread(in, sizeof(short), NN, stdin); + if (feof(stdin)) + break; + vad = speex_preprocess_run(st, in); + /*fprintf (stderr, "%d\n", vad);*/ + fwrite(in, sizeof(short), NN, stdout); + count++; + } + speex_preprocess_state_destroy(st); + return 0; +} diff --git a/src/libs/speex/libspeex/testecho.c b/src/libs/speex/libspeex/testecho.c new file mode 100644 index 00000000..5ae855f0 --- /dev/null +++ b/src/libs/speex/libspeex/testecho.c @@ -0,0 +1,53 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "speex/speex_echo.h" +#include "speex/speex_preprocess.h" + + +#define NN 128 +#define TAIL 1024 + +int main(int argc, char **argv) +{ + FILE *echo_fd, *ref_fd, *e_fd; + short echo_buf[NN], ref_buf[NN], e_buf[NN]; + SpeexEchoState *st; + SpeexPreprocessState *den; + int sampleRate = 8000; + + if (argc != 4) + { + fprintf(stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n"); + exit(1); + } + echo_fd = fopen(argv[2], "rb"); + ref_fd = fopen(argv[1], "rb"); + e_fd = fopen(argv[3], "wb"); + + st = speex_echo_state_init(NN, TAIL); + den = speex_preprocess_state_init(NN, sampleRate); + speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate); + speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, st); + + while (!feof(ref_fd) && !feof(echo_fd)) + { + fread(ref_buf, sizeof(short), NN, ref_fd); + fread(echo_buf, sizeof(short), NN, echo_fd); + speex_echo_cancellation(st, ref_buf, echo_buf, e_buf); + speex_preprocess_run(den, e_buf); + fwrite(e_buf, sizeof(short), NN, e_fd); + } + speex_echo_state_destroy(st); + speex_preprocess_state_destroy(den); + fclose(e_fd); + fclose(echo_fd); + fclose(ref_fd); + return 0; +} diff --git a/src/libs/speex/libspeex/testenc.c b/src/libs/speex/libspeex/testenc.c new file mode 100644 index 00000000..44c132f1 --- /dev/null +++ b/src/libs/speex/libspeex/testenc.c @@ -0,0 +1,146 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <speex/speex.h> +#include <stdio.h> +#include <stdlib.h> +#include <speex/speex_callbacks.h> + +#ifdef FIXED_DEBUG +extern long long spx_mips; +#endif + +#define FRAME_SIZE 160 +#include <math.h> +int main(int argc, char **argv) +{ + char *inFile, *outFile, *bitsFile; + FILE *fin, *fout, *fbits=NULL; + short in_short[FRAME_SIZE]; + short out_short[FRAME_SIZE]; + int snr_frames = 0; + char cbits[200]; + int nbBits; + int i; + void *st; + void *dec; + SpeexBits bits; + spx_int32_t tmp; + int bitCount=0; + spx_int32_t skip_group_delay; + SpeexCallback callback; + + st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB)); + dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB)); + + /* BEGIN: You probably don't need the following in a real application */ + callback.callback_id = SPEEX_INBAND_CHAR; + callback.func = speex_std_char_handler; + callback.data = stderr; + speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback); + + callback.callback_id = SPEEX_INBAND_MODE_REQUEST; + callback.func = speex_std_mode_request_handler; + callback.data = st; + speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback); + /* END of unnecessary stuff */ + + tmp=1; + speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp); + tmp=0; + speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp); + tmp=8; + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp); + tmp=1; + speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp); + + /* Turn this off if you want to measure SNR (on by default) */ + tmp=1; + speex_encoder_ctl(st, SPEEX_SET_HIGHPASS, &tmp); + speex_decoder_ctl(dec, SPEEX_SET_HIGHPASS, &tmp); + + speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay); + speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp); + skip_group_delay += tmp; + + if (argc != 4 && argc != 3) + { + fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc); + exit(1); + } + inFile = argv[1]; + fin = fopen(inFile, "rb"); + outFile = argv[2]; + fout = fopen(outFile, "wb+"); + if (argc==4) + { + bitsFile = argv[3]; + fbits = fopen(bitsFile, "wb"); + } + speex_bits_init(&bits); + while (!feof(fin)) + { + fread(in_short, sizeof(short), FRAME_SIZE, fin); + if (feof(fin)) + break; + speex_bits_reset(&bits); + + speex_encode_int(st, in_short, &bits); + nbBits = speex_bits_write(&bits, cbits, 200); + bitCount+=bits.nbBits; + + if (argc==4) + fwrite(cbits, 1, nbBits, fbits); + speex_bits_rewind(&bits); + + speex_decode_int(dec, &bits, out_short); + speex_bits_reset(&bits); + + fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout); + skip_group_delay = 0; + } + fprintf (stderr, "Total encoded size: %d bits\n", bitCount); + speex_encoder_destroy(st); + speex_decoder_destroy(dec); + speex_bits_destroy(&bits); + +#ifndef DISABLE_FLOAT_API + { + float sigpow,errpow,snr, seg_snr=0; + sigpow = 0; + errpow = 0; + + /* This code just computes SNR, so you don't need it either */ + rewind(fin); + rewind(fout); + + while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) + && + FRAME_SIZE == fread(out_short, sizeof(short), FRAME_SIZE,fout) ) + { + float s=0, e=0; + for (i=0;i<FRAME_SIZE;++i) { + s += (float)in_short[i] * in_short[i]; + e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]); + } + seg_snr += 10*log10((s+160)/(e+160)); + sigpow += s; + errpow += e; + snr_frames++; + } + snr = 10 * log10( sigpow / errpow ); + seg_snr /= snr_frames; + fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr); + +#ifdef FIXED_DEBUG + printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames)); +#endif + } +#endif + + fclose(fin); + fclose(fout); + + return 0; +} diff --git a/src/libs/speex/libspeex/testenc_uwb.c b/src/libs/speex/libspeex/testenc_uwb.c new file mode 100644 index 00000000..503b64dc --- /dev/null +++ b/src/libs/speex/libspeex/testenc_uwb.c @@ -0,0 +1,137 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <speex/speex.h> +#include <stdio.h> +#include <stdlib.h> +#include <speex/speex_callbacks.h> + +#ifdef FIXED_DEBUG +extern long long spx_mips; +#endif + +#define FRAME_SIZE 640 +#include <math.h> +int main(int argc, char **argv) +{ + char *inFile, *outFile, *bitsFile; + FILE *fin, *fout, *fbits=NULL; + short in_short[FRAME_SIZE]; + short out_short[FRAME_SIZE]; + float in_float[FRAME_SIZE]; + float sigpow,errpow,snr, seg_snr=0; + int snr_frames = 0; + char cbits[200]; + int nbBits; + int i; + void *st; + void *dec; + SpeexBits bits; + spx_int32_t tmp; + int bitCount=0; + spx_int32_t skip_group_delay; + SpeexCallback callback; + + sigpow = 0; + errpow = 0; + + st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB)); + dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB)); + + callback.callback_id = SPEEX_INBAND_CHAR; + callback.func = speex_std_char_handler; + callback.data = stderr; + speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback); + + callback.callback_id = SPEEX_INBAND_MODE_REQUEST; + callback.func = speex_std_mode_request_handler; + callback.data = st; + speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback); + + tmp=0; + speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp); + tmp=0; + speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp); + tmp=7; + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp); + tmp=1; + speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp); + + speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay); + speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp); + skip_group_delay += tmp; + + + if (argc != 4 && argc != 3) + { + fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc); + exit(1); + } + inFile = argv[1]; + fin = fopen(inFile, "rb"); + outFile = argv[2]; + fout = fopen(outFile, "wb+"); + if (argc==4) + { + bitsFile = argv[3]; + fbits = fopen(bitsFile, "wb"); + } + speex_bits_init(&bits); + while (!feof(fin)) + { + fread(in_short, sizeof(short), FRAME_SIZE, fin); + if (feof(fin)) + break; + for (i=0;i<FRAME_SIZE;i++) + in_float[i]=in_short[i]; + speex_bits_reset(&bits); + + speex_encode_int(st, in_short, &bits); + nbBits = speex_bits_write(&bits, cbits, 200); + bitCount+=bits.nbBits; + + if (argc==4) + fwrite(cbits, 1, nbBits, fbits); + speex_bits_rewind(&bits); + + speex_decode_int(dec, &bits, out_short); + speex_bits_reset(&bits); + + fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout); + skip_group_delay = 0; + } + fprintf (stderr, "Total encoded size: %d bits\n", bitCount); + speex_encoder_destroy(st); + speex_decoder_destroy(dec); + + rewind(fin); + rewind(fout); + + while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) + && + FRAME_SIZE == fread(out_short, sizeof(short), FRAME_SIZE,fout) ) + { + float s=0, e=0; + for (i=0;i<FRAME_SIZE;++i) { + s += (float)in_short[i] * in_short[i]; + e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]); + } + seg_snr += 10*log10((s+1)/(e+1)); + sigpow += s; + errpow += e; + snr_frames++; + } + fclose(fin); + fclose(fout); + + snr = 10 * log10( sigpow / errpow ); + seg_snr /= snr_frames; + fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr); + +#ifdef FIXED_DEBUG + printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames)); +#endif + + return 1; +} diff --git a/src/libs/speex/libspeex/testenc_wb.c b/src/libs/speex/libspeex/testenc_wb.c new file mode 100644 index 00000000..3f13184a --- /dev/null +++ b/src/libs/speex/libspeex/testenc_wb.c @@ -0,0 +1,140 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <speex/speex.h> +#include <stdio.h> +#include <stdlib.h> +#include <speex/speex_callbacks.h> + +#ifdef FIXED_DEBUG +extern long long spx_mips; +#endif + +#define FRAME_SIZE 320 +#include <math.h> +int main(int argc, char **argv) +{ + char *inFile, *outFile, *bitsFile; + FILE *fin, *fout, *fbits=NULL; + short in_short[FRAME_SIZE]; + short out_short[FRAME_SIZE]; + float sigpow,errpow,snr, seg_snr=0; + int snr_frames = 0; + char cbits[200]; + int nbBits; + int i; + void *st; + void *dec; + SpeexBits bits; + spx_int32_t tmp; + int bitCount=0; + spx_int32_t skip_group_delay; + SpeexCallback callback; + + sigpow = 0; + errpow = 0; + + st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_WB)); + dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_WB)); + + callback.callback_id = SPEEX_INBAND_CHAR; + callback.func = speex_std_char_handler; + callback.data = stderr; + speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback); + + callback.callback_id = SPEEX_INBAND_MODE_REQUEST; + callback.func = speex_std_mode_request_handler; + callback.data = st; + speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback); + + tmp=1; + speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp); + tmp=0; + speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp); + tmp=8; + speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp); + tmp=3; + speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp); + /*tmp=3; + speex_encoder_ctl(st, SPEEX_SET_HIGH_MODE, &tmp); + tmp=6; + speex_encoder_ctl(st, SPEEX_SET_LOW_MODE, &tmp); +*/ + + speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay); + speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp); + skip_group_delay += tmp; + + + if (argc != 4 && argc != 3) + { + fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc); + exit(1); + } + inFile = argv[1]; + fin = fopen(inFile, "rb"); + outFile = argv[2]; + fout = fopen(outFile, "wb+"); + if (argc==4) + { + bitsFile = argv[3]; + fbits = fopen(bitsFile, "wb"); + } + speex_bits_init(&bits); + while (!feof(fin)) + { + fread(in_short, sizeof(short), FRAME_SIZE, fin); + if (feof(fin)) + break; + speex_bits_reset(&bits); + + speex_encode_int(st, in_short, &bits); + nbBits = speex_bits_write(&bits, cbits, 200); + bitCount+=bits.nbBits; + + if (argc==4) + fwrite(cbits, 1, nbBits, fbits); + speex_bits_rewind(&bits); + + speex_decode_int(dec, &bits, out_short); + speex_bits_reset(&bits); + + fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout); + skip_group_delay = 0; + } + fprintf (stderr, "Total encoded size: %d bits\n", bitCount); + speex_encoder_destroy(st); + speex_decoder_destroy(dec); + speex_bits_destroy(&bits); + + rewind(fin); + rewind(fout); + + while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) + && + FRAME_SIZE == fread(out_short, sizeof(short), FRAME_SIZE,fout) ) + { + float s=0, e=0; + for (i=0;i<FRAME_SIZE;++i) { + s += (float)in_short[i] * in_short[i]; + e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]); + } + seg_snr += 10*log10((s+160)/(e+160)); + sigpow += s; + errpow += e; + snr_frames++; + } + fclose(fin); + fclose(fout); + + snr = 10 * log10( sigpow / errpow ); + seg_snr /= snr_frames; + fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr); + +#ifdef FIXED_DEBUG + printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames)); +#endif + + return 1; +} diff --git a/src/libs/speex/libspeex/testjitter.c b/src/libs/speex/libspeex/testjitter.c new file mode 100644 index 00000000..3bcbe2fe --- /dev/null +++ b/src/libs/speex/libspeex/testjitter.c @@ -0,0 +1,75 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <speex/speex_jitter.h> +#include <stdio.h> + +union jbpdata { + unsigned int idx; + unsigned char data[4]; +}; + +void synthIn(JitterBufferPacket *in, int idx, int span) { + union jbpdata d; + d.idx = idx; + + in->data = d.data; + in->len = sizeof(d); + in->timestamp = idx * 10; + in->span = span * 10; + in->sequence = idx; + in->user_data = 0; +} + +void jitterFill(JitterBuffer *jb) { + char buffer[65536]; + JitterBufferPacket in, out; + int i; + + out.data = buffer; + + jitter_buffer_reset(jb); + + for(i=0;i<100;++i) { + synthIn(&in, i, 1); + jitter_buffer_put(jb, &in); + + out.len = 65536; + if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) { + printf("Fill test failed iteration %d\n", i); + } + if (out.timestamp != i * 10) { + printf("Fill test expected %d got %d\n", i*10, out.timestamp); + } + jitter_buffer_tick(jb); + } +} + +int main() +{ + char buffer[65536]; + JitterBufferPacket in, out; + int i; + + JitterBuffer *jb = jitter_buffer_init(10); + + out.data = buffer; + + /* Frozen sender case */ + jitterFill(jb); + for(i=0;i<100;++i) { + out.len = 65536; + jitter_buffer_get(jb, &out, 10, NULL); + jitter_buffer_tick(jb); + } + synthIn(&in, 100, 1); + jitter_buffer_put(jb, &in); + out.len = 65536; + if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) { + printf("Failed frozen sender resynchronize\n"); + } else { + printf("Frozen sender: Jitter %d\n", out.timestamp - 100*10); + } + return 0; +} diff --git a/src/libs/speex/libspeex/vbr.c b/src/libs/speex/libspeex/vbr.c new file mode 100644 index 00000000..5b7dd9bf --- /dev/null +++ b/src/libs/speex/libspeex/vbr.c @@ -0,0 +1,275 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: vbr.c + + VBR-related routines + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "vbr.h" +#include <math.h> + + +#define sqr(x) ((x)*(x)) + +#define MIN_ENERGY 6000 +#define NOISE_POW .3 + +#ifndef DISABLE_VBR + +const float vbr_nb_thresh[9][11]={ + {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* CNG */ + { 4.0f, 2.5f, 2.0f, 1.2f, 0.5f, 0.0f, -0.5f, -0.7f, -0.8f, -0.9f, -1.0f}, /* 2 kbps */ + {10.0f, 6.5f, 5.2f, 4.5f, 3.9f, 3.5f, 3.0f, 2.5f, 2.3f, 1.8f, 1.0f}, /* 6 kbps */ + {11.0f, 8.8f, 7.5f, 6.5f, 5.0f, 3.9f, 3.9f, 3.9f, 3.5f, 3.0f, 1.0f}, /* 8 kbps */ + {11.0f, 11.0f, 9.9f, 8.5f, 7.0f, 6.0f, 4.5f, 4.0f, 4.0f, 4.0f, 2.0f}, /* 11 kbps */ + {11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 8.0f, 7.0f, 6.0f, 5.0f, 3.0f}, /* 15 kbps */ + {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.5f, 7.0f, 6.0f, 5.0f}, /* 18 kbps */ + {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.8f, 9.5f, 7.5f}, /* 24 kbps */ + { 7.0f, 4.5f, 3.7f, 3.0f, 2.5f, 2.0f, 1.8f, 1.5f, 1.0f, 0.0f, 0.0f} /* 4 kbps */ +}; + + +const float vbr_hb_thresh[5][11]={ + {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */ + {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* 2 kbps */ + {11.0f, 11.0f, 9.5f, 8.5f, 7.5f, 6.0f, 5.0f, 3.9f, 3.0f, 2.0f, 1.0f}, /* 6 kbps */ + {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.5f, 8.7f, 7.8f, 7.0f, 6.5f, 4.0f}, /* 10 kbps */ + {11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 11.0f, 9.8f, 7.5f, 5.5f} /* 18 kbps */ +}; + +const float vbr_uhb_thresh[2][11]={ + {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* silence */ + { 3.9f, 2.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f} /* 2 kbps */ +}; + +void vbr_init(VBRState *vbr) +{ + int i; + + vbr->average_energy=0; + vbr->last_energy=1; + vbr->accum_sum=0; + vbr->energy_alpha=.1; + vbr->soft_pitch=0; + vbr->last_pitch_coef=0; + vbr->last_quality=0; + + vbr->noise_accum = .05*pow(MIN_ENERGY, NOISE_POW); + vbr->noise_accum_count=.05; + vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count; + vbr->consec_noise=0; + + + for (i=0;i<VBR_MEMORY_SIZE;i++) + vbr->last_log_energy[i] = log(MIN_ENERGY); +} + + +/* + This function should analyse the signal and decide how critical the + coding error will be perceptually. The following factors should be + taken into account: + + -Attacks (positive energy derivative) should be coded with more bits + + -Stationary voiced segments should receive more bits + + -Segments with (very) low absolute energy should receive less bits (maybe + only shaped noise?) + + -DTX for near-zero energy? + + -Stationary fricative segments should have less bits + + -Temporal masking: when energy slope is decreasing, decrease the bit-rate + + -Decrease bit-rate for males (low pitch)? + + -(wideband only) less bits in the high-band when signal is very + non-stationary (harder to notice high-frequency noise)??? + +*/ + +float vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float pitch_coef) +{ + int i; + float ener=0, ener1=0, ener2=0; + float qual=7; + int va; + float log_energy; + float non_st=0; + float voicing; + float pow_ener; + + for (i=0;i<len>>1;i++) + ener1 += ((float)sig[i])*sig[i]; + + for (i=len>>1;i<len;i++) + ener2 += ((float)sig[i])*sig[i]; + ener=ener1+ener2; + + log_energy = log(ener+MIN_ENERGY); + for (i=0;i<VBR_MEMORY_SIZE;i++) + non_st += sqr(log_energy-vbr->last_log_energy[i]); + non_st = non_st/(30*VBR_MEMORY_SIZE); + if (non_st>1) + non_st=1; + + voicing = 3*(pitch_coef-.4)*fabs(pitch_coef-.4); + vbr->average_energy = (1-vbr->energy_alpha)*vbr->average_energy + vbr->energy_alpha*ener; + vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count; + pow_ener = pow(ener,NOISE_POW); + if (vbr->noise_accum_count<.06 && ener>MIN_ENERGY) + vbr->noise_accum = .05*pow_ener; + + if ((voicing<.3 && non_st < .2 && pow_ener < 1.2*vbr->noise_level) + || (voicing<.3 && non_st < .05 && pow_ener < 1.5*vbr->noise_level) + || (voicing<.4 && non_st < .05 && pow_ener < 1.2*vbr->noise_level) + || (voicing<0 && non_st < .05)) + { + float tmp; + va = 0; + vbr->consec_noise++; + if (pow_ener > 3*vbr->noise_level) + tmp = 3*vbr->noise_level; + else + tmp = pow_ener; + if (vbr->consec_noise>=4) + { + vbr->noise_accum = .95*vbr->noise_accum + .05*tmp; + vbr->noise_accum_count = .95*vbr->noise_accum_count + .05; + } + } else { + va = 1; + vbr->consec_noise=0; + } + + if (pow_ener < vbr->noise_level && ener>MIN_ENERGY) + { + vbr->noise_accum = .95*vbr->noise_accum + .05*pow_ener; + vbr->noise_accum_count = .95*vbr->noise_accum_count + .05; + } + + /* Checking for very low absolute energy */ + if (ener < 30000) + { + qual -= .7; + if (ener < 10000) + qual-=.7; + if (ener < 3000) + qual-=.7; + } else { + float short_diff, long_diff; + short_diff = log((ener+1)/(1+vbr->last_energy)); + long_diff = log((ener+1)/(1+vbr->average_energy)); + /*fprintf (stderr, "%f %f\n", short_diff, long_diff);*/ + + if (long_diff<-5) + long_diff=-5; + if (long_diff>2) + long_diff=2; + + if (long_diff>0) + qual += .6*long_diff; + if (long_diff<0) + qual += .5*long_diff; + if (short_diff>0) + { + if (short_diff>5) + short_diff=5; + qual += .5*short_diff; + } + /* Checking for energy increases */ + if (ener2 > 1.6*ener1) + qual += .5; + } + vbr->last_energy = ener; + vbr->soft_pitch = .6*vbr->soft_pitch + .4*pitch_coef; + qual += 2.2*((pitch_coef-.4) + (vbr->soft_pitch-.4)); + + if (qual < vbr->last_quality) + qual = .5*qual + .5*vbr->last_quality; + if (qual<4) + qual=4; + if (qual>10) + qual=10; + + /* + if (vbr->consec_noise>=2) + qual-=1.3; + if (vbr->consec_noise>=5) + qual-=1.3; + if (vbr->consec_noise>=12) + qual-=1.3; + */ + if (vbr->consec_noise>=3) + qual=4; + + if (vbr->consec_noise) + qual -= 1.0 * (log(3.0 + vbr->consec_noise)-log(3)); + if (qual<0) + qual=0; + + if (ener<60000) + { + if (vbr->consec_noise>2) + qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3)); + if (ener<10000&&vbr->consec_noise>2) + qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3)); + if (qual<0) + qual=0; + qual += .3*log(.0001+ener/60000.0); + } + if (qual<-1) + qual=-1; + + /*printf ("%f %f %f %f %d\n", qual, voicing, non_st, pow_ener/(.01+vbr->noise_level), va);*/ + + vbr->last_pitch_coef = pitch_coef; + vbr->last_quality = qual; + + for (i=VBR_MEMORY_SIZE-1;i>0;i--) + vbr->last_log_energy[i] = vbr->last_log_energy[i-1]; + vbr->last_log_energy[0] = log_energy; + + /*printf ("VBR: %f %f %f %d %f\n", (float)(log_energy-log(vbr->average_energy+MIN_ENERGY)), non_st, voicing, va, vbr->noise_level);*/ + + return qual; +} + +void vbr_destroy(VBRState *vbr) +{ +} + +#endif /* #ifndef DISABLE_VBR */ diff --git a/src/libs/speex/libspeex/vbr.h b/src/libs/speex/libspeex/vbr.h new file mode 100644 index 00000000..ff1e3e46 --- /dev/null +++ b/src/libs/speex/libspeex/vbr.h @@ -0,0 +1,70 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file vbr.h + @brief Variable Bit-Rate (VBR) related routines +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + +#ifndef VBR_H +#define VBR_H + +#include "arch.h" + +#define VBR_MEMORY_SIZE 5 + +extern const float vbr_nb_thresh[9][11]; +extern const float vbr_hb_thresh[5][11]; +extern const float vbr_uhb_thresh[2][11]; + +/** VBR state. */ +typedef struct VBRState { + float energy_alpha; + float average_energy; + float last_energy; + float last_log_energy[VBR_MEMORY_SIZE]; + float accum_sum; + float last_pitch_coef; + float soft_pitch; + float last_quality; + float noise_level; + float noise_accum; + float noise_accum_count; + int consec_noise; +} VBRState; + +void vbr_init(VBRState *vbr); + +float vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float pitch_coef); + +void vbr_destroy(VBRState *vbr); + +#endif diff --git a/src/libs/speex/libspeex/vorbis_psy.h b/src/libs/speex/libspeex/vorbis_psy.h new file mode 100644 index 00000000..68710577 --- /dev/null +++ b/src/libs/speex/libspeex/vorbis_psy.h @@ -0,0 +1,97 @@ +/* Copyright (C) 2005 Jean-Marc Valin, CSIRO, Christopher Montgomery + File: vorbis_psy.h + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef VORBIS_PSY_H +#define VORBIS_PSY_H + +#ifdef VORBIS_PSYCHO + +#include "smallft.h" +#define P_BANDS 17 /* 62Hz to 16kHz */ +#define NOISE_COMPAND_LEVELS 40 + + +#define todB(x) ((x)>1e-13?log((x)*(x))*4.34294480f:-30) +#define fromdB(x) (exp((x)*.11512925f)) + +/* The bark scale equations are approximations, since the original + table was somewhat hand rolled. The below are chosen to have the + best possible fit to the rolled tables, thus their somewhat odd + appearance (these are more accurate and over a longer range than + the oft-quoted bark equations found in the texts I have). The + approximations are valid from 0 - 30kHz (nyquist) or so. + + all f in Hz, z in Bark */ + +#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n)) +#define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f) + +/* Frequency to octave. We arbitrarily declare 63.5 Hz to be octave + 0.0 */ + +#define toOC(n) (log(n)*1.442695f-5.965784f) +#define fromOC(o) (exp(((o)+5.965784f)*.693147f)) + + +typedef struct { + + float noisewindowlo; + float noisewindowhi; + int noisewindowlomin; + int noisewindowhimin; + int noisewindowfixed; + float noiseoff[P_BANDS]; + float noisecompand[NOISE_COMPAND_LEVELS]; + +} VorbisPsyInfo; + + + +typedef struct { + int n; + int rate; + struct drft_lookup lookup; + VorbisPsyInfo *vi; + + float *window; + float *noiseoffset; + long *bark; + +} VorbisPsy; + + +VorbisPsy *vorbis_psy_init(int rate, int size); +void vorbis_psy_destroy(VorbisPsy *psy); +void compute_curve(VorbisPsy *psy, float *audio, float *curve); +void curve_to_lpc(VorbisPsy *psy, float *curve, float *awk1, float *awk2, int ord); + +#endif +#endif diff --git a/src/libs/speex/libspeex/vq.c b/src/libs/speex/libspeex/vq.c new file mode 100644 index 00000000..609f124e --- /dev/null +++ b/src/libs/speex/libspeex/vq.c @@ -0,0 +1,147 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: vq.c + Vector quantization + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "vq.h" +#include "stack_alloc.h" +#include "arch.h" + +#ifdef _USE_SSE +#include <xmmintrin.h> +#include "vq_sse.h" +#elif defined(SHORTCUTS) && (defined(ARM4_ASM) || defined(ARM5E_ASM)) +#include "vq_arm4.h" +#elif defined(BFIN_ASM) +#include "vq_bfin.h" +#endif + + +int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries) +{ + int i=0; + while (i<entries-1 && in>boundary[0]) + { + boundary++; + i++; + } + return i; +} + +int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries) +{ + int i=0; + while (i<entries-1 && in>boundary[0]) + { + boundary++; + i++; + } + return i; +} + + +#ifndef OVERRIDE_VQ_NBEST +/*Finds the indices of the n-best entries in a codebook*/ +void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack) +{ + int i,j,k,used; + used = 0; + for (i=0;i<entries;i++) + { + spx_word32_t dist=0; + for (j=0;j<len;j++) + dist = MAC16_16(dist,in[j],*codebook++); +#ifdef FIXED_POINT + dist=SUB32(SHR32(E[i],1),dist); +#else + dist=.5f*E[i]-dist; +#endif + if (i<N || dist<best_dist[N-1]) + { + for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--) + { + best_dist[k]=best_dist[k-1]; + nbest[k] = nbest[k-1]; + } + best_dist[k]=dist; + nbest[k]=i; + used++; + } + } +} +#endif + + + + +#ifndef OVERRIDE_VQ_NBEST_SIGN +/*Finds the indices of the n-best entries in a codebook with sign*/ +void vq_nbest_sign(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack) +{ + int i,j,k, sign, used; + used=0; + for (i=0;i<entries;i++) + { + spx_word32_t dist=0; + for (j=0;j<len;j++) + dist = MAC16_16(dist,in[j],*codebook++); + if (dist>0) + { + sign=0; + dist=-dist; + } else + { + sign=1; + } +#ifdef FIXED_POINT + dist = ADD32(dist,SHR32(E[i],1)); +#else + dist = ADD32(dist,.5f*E[i]); +#endif + if (i<N || dist<best_dist[N-1]) + { + for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--) + { + best_dist[k]=best_dist[k-1]; + nbest[k] = nbest[k-1]; + } + best_dist[k]=dist; + nbest[k]=i; + used++; + if (sign) + nbest[k]+=entries; + } + } +} +#endif diff --git a/src/libs/speex/libspeex/vq.h b/src/libs/speex/libspeex/vq.h new file mode 100644 index 00000000..5a4ced24 --- /dev/null +++ b/src/libs/speex/libspeex/vq.h @@ -0,0 +1,54 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file vq.h + @brief Vector quantization +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef VQ_H +#define VQ_H + +#include "arch.h" + +int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries); +int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries); + +#ifdef _USE_SSE +#include <xmmintrin.h> +void vq_nbest(spx_word16_t *in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack); + +void vq_nbest_sign(spx_word16_t *in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack); +#else +void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack); + +void vq_nbest_sign(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack); +#endif + +#endif diff --git a/src/libs/speex/libspeex/vq_arm4.h b/src/libs/speex/libspeex/vq_arm4.h new file mode 100644 index 00000000..585b8613 --- /dev/null +++ b/src/libs/speex/libspeex/vq_arm4.h @@ -0,0 +1,115 @@ +/* Copyright (C) 2004 Jean-Marc Valin */ +/** + @file vq_arm4.h + @brief ARM4-optimized vq routine +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define OVERRIDE_VQ_NBEST +void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack) +{ + int i,j; + for (i=0;i<entries;i+=4) + { +#if 1 + spx_word32_t dist1, dist2, dist3, dist4; + int dead1, dead2, dead3, dead4, dead5, dead6, dead7, dead8; + __asm__ __volatile__ ( + "mov %0, #0 \n\t" + "mov %1, #0 \n\t" + "mov %2, #0 \n\t" + "mov %3, #0 \n\t" + "mov %10, %4 \n\t" + "add %4, %4, %4\n\t" + ".vqloop%=:\n\t" + "ldrsh %7, [%5], #2 \n\t" + "ldrsh %8, [%6] \n\t" + "mov %9, %6 \n\t" + "mla %0, %7, %8, %0 \n\t" + "ldrsh %8, [%9, %4]! \n\t" + "mla %1, %7, %8, %1 \n\t" + "ldrsh %8, [%9, %4]!\n\t" + "mla %2, %7, %8, %2 \n\t" + "ldrsh %8, [%9, %4]! \n\t" + "mla %3, %7, %8, %3 \n\t" + "subs %10, %10, #1 \n\t" + "add %6, %6, #2 \n\t" + "bne .vqloop%=" + : "=r" (dist1), "=r" (dist2), "=r" (dist3), "=r" (dist4), + "=r" (dead1), "=r" (dead2), "=r" (codebook), "=r" (dead4), + "=r" (dead5), "=r" (dead6), "=r" (dead7) + : "4" (len), "5" (in), "6" (codebook) + : "cc"); +#else +dist1=dist2=dist3=dist4=0; + /* spx_word32_t dist1=0; + spx_word32_t dist2=0; + spx_word32_t dist3=0; + spx_word32_t dist4=0;*/ + for (j=0;j<2;j++) + { + const spx_word16_t *code = codebook; + dist1 = MAC16_16(dist1,in[j],*code); + code += len; + dist2 = MAC16_16(dist2,in[j],*code); + code += len; + dist3 = MAC16_16(dist3,in[j],*code); + code += len; + dist4 = MAC16_16(dist4,in[j],*code); + codebook++; + } +#endif + dist1=SUB32(SHR(*E++,1),dist1); + if (dist1<*best_dist || i==0) + { + *best_dist=dist1; + *nbest=i; + } + dist2=SUB32(SHR(*E++,1),dist2); + if (dist2<*best_dist) + { + *best_dist=dist2; + *nbest=i+1; + } + dist3=SUB32(SHR(*E++,1),dist3); + if (dist3<*best_dist) + { + *best_dist=dist3; + *nbest=i+2; + } + dist4=SUB32(SHR(*E++,1),dist4); + if (dist4<*best_dist) + { + *best_dist=dist4; + *nbest=i+3; + } + codebook += 3*len; + } +} diff --git a/src/libs/speex/libspeex/vq_bfin.h b/src/libs/speex/libspeex/vq_bfin.h new file mode 100644 index 00000000..2cc9ea5f --- /dev/null +++ b/src/libs/speex/libspeex/vq_bfin.h @@ -0,0 +1,107 @@ +/* Copyright (C) 2005 Analog Devices */ +/** + @file vq_bfin.h + @author Jean-Marc Valin + @brief Blackfin-optimized vq routine +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define OVERRIDE_VQ_NBEST +void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack) +{ + if (N==1) + { + best_dist[0] = 2147483647; + { + spx_word32_t dist; + __asm__ __volatile__ + ( + "LC0 = %8;\n\t" + "R2 = 0;\n\t" + "I0 = %6;\n\t" + "B0 = %6;\n\t" + "L0 = %9;\n\t" + "LOOP entries_loop%= LC0;\n\t" + "LOOP_BEGIN entries_loop%=;\n\t" + "%0 = [%4++];\n\t" + "%0 >>= 1;\n\t" + "A0 = %0;\n\t" + "R0.L = W[%1++%7] || R1.L = W[I0++];\n\t" + "LOOP vq_loop%= LC1 = %5;\n\t" + "LOOP_BEGIN vq_loop%=;\n\t" + "%0 = (A0 -= R0.L*R1.L) (IS) || R0.L = W[%1++%7] || R1.L = W[I0++];\n\t" + "LOOP_END vq_loop%=;\n\t" + "%0 = (A0 -= R0.L*R1.L) (IS);\n\t" + "cc = %0 < %2;\n\t" + "if cc %2 = %0;\n\t" + "if cc %3 = R2;\n\t" + "R2 += 1;\n\t" + "LOOP_END entries_loop%=;\n\t" + : "=&D" (dist), "=&a" (codebook), "=&d" (best_dist[0]), "=&d" (nbest[0]), "=&a" (E) + : "a" (len-1), "a" (in), "a" (2), "d" (entries), "d" (len<<1), "1" (codebook), "4" (E), "2" (best_dist[0]), "3" (nbest[0]) + : "R0", "R1", "R2", "I0", "L0", "B0", "A0", "cc", "memory" + ); + } + } else { + int i,k,used; + used = 0; + for (i=0;i<entries;i++) + { + spx_word32_t dist; + __asm__ + ( + "%0 >>= 1;\n\t" + "A0 = %0;\n\t" + "I0 = %3;\n\t" + "L0 = 0;\n\t" + "R0.L = W[%1++%4] || R1.L = W[I0++];\n\t" + "LOOP vq_loop%= LC0 = %2;\n\t" + "LOOP_BEGIN vq_loop%=;\n\t" + "%0 = (A0 -= R0.L*R1.L) (IS) || R0.L = W[%1++%4] || R1.L = W[I0++];\n\t" + "LOOP_END vq_loop%=;\n\t" + "%0 = (A0 -= R0.L*R1.L) (IS);\n\t" + : "=D" (dist), "=a" (codebook) + : "a" (len-1), "a" (in), "a" (2), "1" (codebook), "0" (E[i]) + : "R0", "R1", "I0", "L0", "A0" + ); + if (i<N || dist<best_dist[N-1]) + { + for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--) + { + best_dist[k]=best_dist[k-1]; + nbest[k] = nbest[k-1]; + } + best_dist[k]=dist; + nbest[k]=i; + used++; + } + } + } +} diff --git a/src/libs/speex/libspeex/vq_sse.h b/src/libs/speex/libspeex/vq_sse.h new file mode 100644 index 00000000..00a42ce3 --- /dev/null +++ b/src/libs/speex/libspeex/vq_sse.h @@ -0,0 +1,120 @@ +/* Copyright (C) 2004 Jean-Marc Valin */ +/** + @file vq_sse.h + @brief SSE-optimized vq routine +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define OVERRIDE_VQ_NBEST +void vq_nbest(spx_word16_t *_in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack) +{ + int i,j,k,used; + VARDECL(float *dist); + VARDECL(__m128 *in); + __m128 half; + used = 0; + ALLOC(dist, entries, float); + half = _mm_set_ps1(.5f); + ALLOC(in, len, __m128); + for (i=0;i<len;i++) + in[i] = _mm_set_ps1(_in[i]); + for (i=0;i<entries>>2;i++) + { + __m128 d = _mm_mul_ps(E[i], half); + for (j=0;j<len;j++) + d = _mm_sub_ps(d, _mm_mul_ps(in[j], *codebook++)); + _mm_storeu_ps(dist+4*i, d); + } + for (i=0;i<entries;i++) + { + if (i<N || dist[i]<best_dist[N-1]) + { + for (k=N-1; (k >= 1) && (k > used || dist[i] < best_dist[k-1]); k--) + { + best_dist[k]=best_dist[k-1]; + nbest[k] = nbest[k-1]; + } + best_dist[k]=dist[i]; + nbest[k]=i; + used++; + } + } +} + + + + +#define OVERRIDE_VQ_NBEST_SIGN +void vq_nbest_sign(spx_word16_t *_in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack) +{ + int i,j,k,used; + VARDECL(float *dist); + VARDECL(__m128 *in); + __m128 half; + used = 0; + ALLOC(dist, entries, float); + half = _mm_set_ps1(.5f); + ALLOC(in, len, __m128); + for (i=0;i<len;i++) + in[i] = _mm_set_ps1(_in[i]); + for (i=0;i<entries>>2;i++) + { + __m128 d = _mm_setzero_ps(); + for (j=0;j<len;j++) + d = _mm_add_ps(d, _mm_mul_ps(in[j], *codebook++)); + _mm_storeu_ps(dist+4*i, d); + } + for (i=0;i<entries;i++) + { + int sign; + if (dist[i]>0) + { + sign=0; + dist[i]=-dist[i]; + } else + { + sign=1; + } + dist[i] += .5f*((float*)E)[i]; + if (i<N || dist[i]<best_dist[N-1]) + { + for (k=N-1; (k >= 1) && (k > used || dist[i] < best_dist[k-1]); k--) + { + best_dist[k]=best_dist[k-1]; + nbest[k] = nbest[k-1]; + } + best_dist[k]=dist[i]; + nbest[k]=i; + used++; + if (sign) + nbest[k]+=entries; + } + } +} diff --git a/src/libs/speex/libspeex/window.c b/src/libs/speex/libspeex/window.c new file mode 100644 index 00000000..ac042d45 --- /dev/null +++ b/src/libs/speex/libspeex/window.c @@ -0,0 +1,102 @@ +/* Copyright (C) 2006 Jean-Marc Valin + File: window.c + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "arch.h" + +#ifdef FIXED_POINT +const spx_word16_t lag_window[11] = { + 16384, 16337, 16199, 15970, 15656, 15260, 14790, 14254, 13659, 13015, 12330 +}; + +const spx_word16_t lpc_window[200] = { +1310, 1313, 1321, 1333, 1352, 1375, 1403, 1436, +1475, 1518, 1567, 1621, 1679, 1743, 1811, 1884, +1962, 2044, 2132, 2224, 2320, 2421, 2526, 2636, +2750, 2868, 2990, 3116, 3246, 3380, 3518, 3659, +3804, 3952, 4104, 4259, 4417, 4578, 4742, 4909, +5079, 5251, 5425, 5602, 5781, 5963, 6146, 6331, +6518, 6706, 6896, 7087, 7280, 7473, 7668, 7863, +8059, 8256, 8452, 8650, 8847, 9044, 9241, 9438, +9635, 9831, 10026, 10220, 10414, 10606, 10797, 10987, +11176, 11363, 11548, 11731, 11912, 12091, 12268, 12443, +12615, 12785, 12952, 13116, 13277, 13435, 13590, 13742, +13890, 14035, 14176, 14314, 14448, 14578, 14704, 14826, +14944, 15058, 15168, 15273, 15374, 15470, 15562, 15649, +15732, 15810, 15883, 15951, 16015, 16073, 16127, 16175, +16219, 16257, 16291, 16319, 16342, 16360, 16373, 16381, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16361, 16294, 16183, 16028, 15830, +15588, 15304, 14979, 14613, 14207, 13763, 13282, 12766, +12215, 11631, 11016, 10373, 9702, 9007, 8289, 7551, +6797, 6028, 5251, 4470, 3695, 2943, 2248, 1696 +}; +#else +const spx_word16_t lag_window[11] = { + 1.00000, 0.99716, 0.98869, 0.97474, 0.95554, 0.93140, 0.90273, 0.86998, 0.83367, 0.79434, 0.75258 +}; + +const spx_word16_t lpc_window[200] = { + 0.080000f, 0.080158f, 0.080630f, 0.081418f, 0.082520f, 0.083935f, 0.085663f, 0.087703f, + 0.090052f, 0.092710f, 0.095674f, 0.098943f, 0.102514f, 0.106385f, 0.110553f, 0.115015f, + 0.119769f, 0.124811f, 0.130137f, 0.135744f, 0.141628f, 0.147786f, 0.154212f, 0.160902f, + 0.167852f, 0.175057f, 0.182513f, 0.190213f, 0.198153f, 0.206328f, 0.214731f, 0.223357f, + 0.232200f, 0.241254f, 0.250513f, 0.259970f, 0.269619f, 0.279453f, 0.289466f, 0.299651f, + 0.310000f, 0.320507f, 0.331164f, 0.341965f, 0.352901f, 0.363966f, 0.375151f, 0.386449f, + 0.397852f, 0.409353f, 0.420943f, 0.432615f, 0.444361f, 0.456172f, 0.468040f, 0.479958f, + 0.491917f, 0.503909f, 0.515925f, 0.527959f, 0.540000f, 0.552041f, 0.564075f, 0.576091f, + 0.588083f, 0.600042f, 0.611960f, 0.623828f, 0.635639f, 0.647385f, 0.659057f, 0.670647f, + 0.682148f, 0.693551f, 0.704849f, 0.716034f, 0.727099f, 0.738035f, 0.748836f, 0.759493f, + 0.770000f, 0.780349f, 0.790534f, 0.800547f, 0.810381f, 0.820030f, 0.829487f, 0.838746f, + 0.847800f, 0.856643f, 0.865269f, 0.873672f, 0.881847f, 0.889787f, 0.897487f, 0.904943f, + 0.912148f, 0.919098f, 0.925788f, 0.932214f, 0.938372f, 0.944256f, 0.949863f, 0.955189f, + 0.960231f, 0.964985f, 0.969447f, 0.973615f, 0.977486f, 0.981057f, 0.984326f, 0.987290f, + 0.989948f, 0.992297f, 0.994337f, 0.996065f, 0.997480f, 0.998582f, 0.999370f, 0.999842f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 0.998640f, 0.994566f, 0.987787f, 0.978324f, 0.966203f, + 0.951458f, 0.934131f, 0.914270f, 0.891931f, 0.867179f, 0.840084f, 0.810723f, 0.779182f, + 0.745551f, 0.709930f, 0.672424f, 0.633148f, 0.592223f, 0.549781f, 0.505964f, 0.460932f, + 0.414863f, 0.367968f, 0.320511f, 0.272858f, 0.225569f, 0.179655f, 0.137254f, 0.103524f +}; +#endif diff --git a/src/libs/speex/win32/VS2008/libspeex/libspeex.vcproj b/src/libs/speex/win32/VS2008/libspeex/libspeex.vcproj new file mode 100644 index 00000000..5e8c89c8 --- /dev/null +++ b/src/libs/speex/win32/VS2008/libspeex/libspeex.vcproj @@ -0,0 +1,1704 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="libspeex" + ProjectGUID="{E972C52F-9E85-4D65-B19C-031E511E9DB4}" + RootNamespace="libspeex" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Release_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Release_SSE2|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="2" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Release_Dynamic|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + ModuleDefinitionFile="libspeex.def" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + ModuleDefinitionFile="libspeex.def" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Debug_RTL_dll|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Release_RTL_dll|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Debug_WM5_PPC_ARM|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;FIXED_POINT;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;$(ARCHFAM);$(_ARCHFAM_)" + MinimalRebuild="true" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="0" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Release_WM5_PPC_ARM|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;FIXED_POINT;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;$(ARCHFAM);$(_ARCHFAM_)" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="0" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeex.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\..\..\libspeex\bits.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\cb_search.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\exc_10_16_table.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\exc_10_32_table.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\exc_20_32_table.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\exc_5_256_table.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\exc_5_64_table.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\exc_8_128_table.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\fftwrap.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\filterbank.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\filters.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\gain_table.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\gain_table_lbr.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\hexc_10_32_table.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\hexc_table.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\high_lsp_tables.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\jitter.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fft.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fftr.c" + > + </File> + <File + RelativePath=".\libspeex.def" + > + </File> + <File + RelativePath="..\..\..\libspeex\lpc.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\lsp.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\lsp_tables_nb.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\ltp.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\mdf.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\modes.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\modes_wb.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\nb_celp.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\preprocess.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\quant_lsp.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\sb_celp.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\smallft.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\speex.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\speex_callbacks.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\speex_header.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\stereo.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\vbr.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\vq.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\window.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\..\..\libspeex\cb_search.h" + > + </File> + <File + RelativePath="..\..\config.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\fftwrap.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\filters.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\filters_sse.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fft.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fftr.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\lpc.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\lsp.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\ltp.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\ltp_sse.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\math_approx.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\misc.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\modes.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\nb_celp.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\pseudofloat.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\quant_lsp.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\sb_celp.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_bits.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_callbacks.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_echo.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_header.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_jitter.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_noglobals.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_preprocess.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_stereo.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_types.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\stack_alloc.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\vbr.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\vq.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <File + RelativePath=".\ReadMe.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcproj b/src/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcproj new file mode 100644 index 00000000..a2b194f6 --- /dev/null +++ b/src/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcproj @@ -0,0 +1,473 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="libspeexdsp" + ProjectGUID="{03207781-0D1C-4DB3-A71D-45C608F28DBD}" + RootNamespace="libspeexdsp" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + TreatWChar_tAsBuiltInType="false" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + WholeProgramOptimization="false" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_Dynamic_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="../../../bin/libspeexdsp.dll" + ModuleDefinitionFile="..\..\libspeexdsp.def" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + ImportLibrary="../../../lib/libspeexdsp.lib" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_Static_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\..\..\libspeex\buffer.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\fftwrap.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\filterbank.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\jitter.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fft.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fftr.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\mdf.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\preprocess.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\smallft.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\speex_resample.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\..\..\libspeex\_kiss_fft_guts.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\arch.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\fftwrap.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\filterbank.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\fixed_debug.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\fixed_generic.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fft.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fftr.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\math_approx.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\os_support.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\pseudofloat.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\smallft.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <Filter + Name="Public Header Files" + > + <File + RelativePath="..\..\..\include\speex\speex.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_bits.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_buffer.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_echo.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_jitter.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_preprocess.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_resampler.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_types.h" + > + </File> + </Filter> + <File + RelativePath="..\..\config.h" + > + </File> + <File + RelativePath="..\..\libspeexdsp.def" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj b/src/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj new file mode 100644 index 00000000..ea06f961 --- /dev/null +++ b/src/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj @@ -0,0 +1,226 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release_Dynamic_SSE|Win32"> + <Configuration>Release_Dynamic_SSE</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release_Static_SSE|Win32"> + <Configuration>Release_Static_SSE</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{03207781-0D1C-4DB3-A71D-45C608F28DBD}</ProjectGuid> + <RootNamespace>libspeexdsp</RootNamespace> + <Keyword>Win32Proj</Keyword> + <ProjectName>speexdsp</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140_xp</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|Win32'"> + <OutDir>$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|Win32'"> + <OutDir>$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <CompileAs>CompileAsC</CompileAs> + </ClCompile> + <Lib> + <OutputFile>../../../lib/libspeexdsp.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>Full</Optimization> + <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> + <IntrinsicFunctions>true</IntrinsicFunctions> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <WholeProgramOptimization>false</WholeProgramOptimization> + <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <ExceptionHandling /> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <CompileAs>CompileAsC</CompileAs> + <DisableSpecificWarnings>4244;4305;4311;4100;4127;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <Lib> + <OutputFile>../../../lib/libspeexdsp.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|Win32'"> + <ClCompile> + <Optimization>Full</Optimization> + <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> + <IntrinsicFunctions>true</IntrinsicFunctions> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <ExceptionHandling /> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <CompileAs>CompileAsC</CompileAs> + <DisableSpecificWarnings>4244;4305;4311;4100;4127;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <Link> + <OutputFile>../../../bin/libspeexdsp.dll</OutputFile> + <ModuleDefinitionFile>..\..\libspeexdsp.def</ModuleDefinitionFile> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention /> + <ImportLibrary>../../../lib/libspeexdsp.lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|Win32'"> + <ClCompile> + <Optimization>Full</Optimization> + <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> + <IntrinsicFunctions>true</IntrinsicFunctions> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <ExceptionHandling /> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <CompileAs>CompileAsC</CompileAs> + <DisableSpecificWarnings>4244;4305;4311;4100;4127;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <Lib> + <OutputFile>../../../lib/libspeexdsp.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\libspeex\buffer.c" /> + <ClCompile Include="..\..\..\libspeex\fftwrap.c" /> + <ClCompile Include="..\..\..\libspeex\filterbank.c" /> + <ClCompile Include="..\..\..\libspeex\jitter.c" /> + <ClCompile Include="..\..\..\libspeex\kiss_fft.c" /> + <ClCompile Include="..\..\..\libspeex\kiss_fftr.c" /> + <ClCompile Include="..\..\..\libspeex\mdf.c" /> + <ClCompile Include="..\..\..\libspeex\preprocess.c" /> + <ClCompile Include="..\..\..\libspeex\smallft.c" /> + <ClCompile Include="..\..\..\libspeex\speex_resample.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\libspeex\_kiss_fft_guts.h" /> + <ClInclude Include="..\..\..\libspeex\arch.h" /> + <ClInclude Include="..\..\..\libspeex\fftwrap.h" /> + <ClInclude Include="..\..\..\libspeex\filterbank.h" /> + <ClInclude Include="..\..\..\libspeex\fixed_debug.h" /> + <ClInclude Include="..\..\..\libspeex\fixed_generic.h" /> + <ClInclude Include="..\..\..\libspeex\kiss_fft.h" /> + <ClInclude Include="..\..\..\libspeex\kiss_fftr.h" /> + <ClInclude Include="..\..\..\libspeex\math_approx.h" /> + <ClInclude Include="..\..\..\libspeex\os_support.h" /> + <ClInclude Include="..\..\..\libspeex\pseudofloat.h" /> + <ClInclude Include="..\..\..\libspeex\smallft.h" /> + <ClInclude Include="..\..\..\include\speex\speex.h" /> + <ClInclude Include="..\..\..\include\speex\speex_bits.h" /> + <ClInclude Include="..\..\..\include\speex\speex_buffer.h" /> + <ClInclude Include="..\..\..\include\speex\speex_echo.h" /> + <ClInclude Include="..\..\..\include\speex\speex_jitter.h" /> + <ClInclude Include="..\..\..\include\speex\speex_preprocess.h" /> + <ClInclude Include="..\..\..\include\speex\speex_resampler.h" /> + <ClInclude Include="..\..\..\include\speex\speex_types.h" /> + <ClInclude Include="..\..\config.h" /> + </ItemGroup> + <ItemGroup> + <None Include="..\..\libspeexdsp.def" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj.filters b/src/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj.filters new file mode 100644 index 00000000..6cafdb27 --- /dev/null +++ b/src/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj.filters @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + <Filter Include="Public Header Files"> + <UniqueIdentifier>{144c31bb-b61d-432a-96e8-8dc8f2422f13}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\..\libspeex\buffer.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\fftwrap.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\filterbank.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\jitter.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\kiss_fft.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\kiss_fftr.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\mdf.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\preprocess.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\smallft.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\speex_resample.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\libspeex\_kiss_fft_guts.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\arch.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\fftwrap.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\filterbank.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\fixed_debug.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\fixed_generic.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\kiss_fft.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\kiss_fftr.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\math_approx.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\os_support.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\pseudofloat.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\smallft.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_bits.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_buffer.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_echo.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_jitter.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_preprocess.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_resampler.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_types.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\config.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="..\..\libspeexdsp.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj.user b/src/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj.user new file mode 100644 index 00000000..abe8dd89 --- /dev/null +++ b/src/libs/speex/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj.user @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup /> +</Project> \ No newline at end of file diff --git a/src/libs/speex/win32/config.h b/src/libs/speex/win32/config.h new file mode 100644 index 00000000..abd35f09 --- /dev/null +++ b/src/libs/speex/win32/config.h @@ -0,0 +1,20 @@ +// Microsoft version of 'inline' +#define inline __inline + +// Visual Studio support alloca(), but it always align variables to 16-bit +// boundary, while SSE need 128-bit alignment. So we disable alloca() when +// SSE is enabled. +#ifndef _USE_SSE +# define USE_ALLOCA +#endif + +/* Default to floating point */ +#ifndef FIXED_POINT +# define FLOATING_POINT +# define USE_SMALLFT +#else +# define USE_KISS_FFT +#endif + +/* We don't support visibility on Win32 */ +#define EXPORT diff --git a/src/libs/speexdsp/.cvsignore b/src/libs/speexdsp/.cvsignore new file mode 100644 index 00000000..0c6bca2d --- /dev/null +++ b/src/libs/speexdsp/.cvsignore @@ -0,0 +1,17 @@ +Makefile +Makefile.in +Speex.spec +aclocal.m4 +autom4te.cache +config.guess +config.log +config.status +config.sub +configure +depcomp +install-sh +libtool +ltconfig +ltmain.sh +missing +mkinstalldirs diff --git a/src/libs/speexdsp/.gitignore b/src/libs/speexdsp/.gitignore new file mode 100644 index 00000000..770bb8aa --- /dev/null +++ b/src/libs/speexdsp/.gitignore @@ -0,0 +1,36 @@ +*.o +*.lo +Makefile.in +*~ +*.orig +fixed +float +aclocal.m4 +autom4te.cache +compile +config.guess +config.h.in +config.sub +configure +depcomp +install-sh +ltmain.sh +missing +Makefile +.deps +.libs +*.la +work +SpeexDSP.spec +config.h +config.log +config.status +include/speex/speexdsp_config_types.h +*.sw[lmnop] +testdenoise +testecho +testjitter +libtool +speexdsp.pc +stamp-* +patches diff --git a/src/libs/speexdsp/AUTHORS b/src/libs/speexdsp/AUTHORS new file mode 100644 index 00000000..395c3fec --- /dev/null +++ b/src/libs/speexdsp/AUTHORS @@ -0,0 +1,18 @@ +Jean-Marc Valin <jean-marc.valin@usherbrooke.ca> + All the code except the following + +David Rowe <david@rowetel.com> + lsp.c lsp.h + Also ideas and feedback + +John Francis Edwards + wave_out.[ch], some #ifdefs for windows port and MSVC project files + +Segher Boessenkool + Misc. optimizations (for QMF in particular) + +Atsuhiko Yamanaka <ymnk@jcraft.com>: + Patch to speexenc.c to add Vorbis comment format + +Radim Kolar <hsn@cybermail.net>: + Patch to speexenc.c for supporting more input formats diff --git a/src/libs/speexdsp/CMakeLists.txt b/src/libs/speexdsp/CMakeLists.txt new file mode 100644 index 00000000..2d79e7e9 --- /dev/null +++ b/src/libs/speexdsp/CMakeLists.txt @@ -0,0 +1,20 @@ +project (speexdsp) + +# Rely on C++ 11 +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +set (SPEEXDSP_SOURCES + libspeexdsp/buffer.c + libspeexdsp/fftwrap.c + libspeexdsp/filterbank.c +# libspeexdsp/kiss_fft.c +# libspeexdsp/kiss_fftr.c + libspeexdsp/mdf.c + libspeexdsp/scal.c + libspeexdsp/smallft.c + libspeexdsp/speex_resample.c + libspeexdsp/speex_preprocess.c +) + +add_library(speexdsp ${SPEEXDSP_SOURCES}) diff --git a/src/libs/speexdsp/COPYING b/src/libs/speexdsp/COPYING new file mode 100644 index 00000000..de6fbe2c --- /dev/null +++ b/src/libs/speexdsp/COPYING @@ -0,0 +1,35 @@ +Copyright 2002-2008 Xiph.org Foundation +Copyright 2002-2008 Jean-Marc Valin +Copyright 2005-2007 Analog Devices Inc. +Copyright 2005-2008 Commonwealth Scientific and Industrial Research + Organisation (CSIRO) +Copyright 1993, 2002, 2006 David Rowe +Copyright 2003 EpicGames +Copyright 1992-1994 Jutta Degener, Carsten Bormann + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/libs/speexdsp/ChangeLog b/src/libs/speexdsp/ChangeLog new file mode 100644 index 00000000..9a6cd8af --- /dev/null +++ b/src/libs/speexdsp/ChangeLog @@ -0,0 +1,21 @@ +2005-09-07 Thomas Vander Stichele <thomas at apestaart dot org> + + * libspeex/cb_search.c: (split_cb_search_shape_sign_N1): + add declaration for n, seems like an obvious build fix, slap + me down if it's not + +2004-02-18 Jean-Marc Valin <jean-marc.valin@usherbrooke.ca> + Patch for compiling with mingw32 sent by j@thing.net + +2004-02-18 Jean-Marc Valin <jean-marc.valin@usherbrooke.ca> + Integrated IRIX patch (getopt stuff) from Michael Pruett <michael@68k.org> + +2004-02-18 Jean-Marc Valin <jean-marc.valin@usherbrooke.ca> + Changed the Makefile.am so that KDevelop can parse SUBDIRS correctly + +2002/03/27 Jean-Marc Valin: +Working encoder and decoder for both narrowband and wideband. + +2002/02/27 Jean-Marc Valin: +Got the basic encoder working as a demo with quantization only on some +parameters. diff --git a/src/libs/speexdsp/Doxyfile b/src/libs/speexdsp/Doxyfile new file mode 100644 index 00000000..772934fc --- /dev/null +++ b/src/libs/speexdsp/Doxyfile @@ -0,0 +1,225 @@ +# Doxyfile 1.5.1-KDevelop + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = Speex +PROJECT_NUMBER = 1.2-beta2 +OUTPUT_DIRECTORY = doc +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = include/speex +FILE_PATTERNS = +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = speex_config_types.h +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = gif +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/src/libs/speexdsp/IDEAS b/src/libs/speexdsp/IDEAS new file mode 100644 index 00000000..73fe26e7 --- /dev/null +++ b/src/libs/speexdsp/IDEAS @@ -0,0 +1,4 @@ +- Non-linear adaptive codebook (use exc[n]*|exc[n]| to reduce noise + component in adaptive codebook excitation) + +- Include time-domain masking for VBR diff --git a/src/libs/speexdsp/INSTALL b/src/libs/speexdsp/INSTALL new file mode 100644 index 00000000..a2482ca7 --- /dev/null +++ b/src/libs/speexdsp/INSTALL @@ -0,0 +1,8 @@ +Installing Speex is as easy as: + +% ./configure [--prefix=<install-path>] +% make +% make install + +Note that if you are using the code from SVN, you will need to run "autogen.sh" +instead of "configure". diff --git a/src/libs/speexdsp/Makefile.am b/src/libs/speexdsp/Makefile.am new file mode 100644 index 00000000..555728ef --- /dev/null +++ b/src/libs/speexdsp/Makefile.am @@ -0,0 +1,19 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# To disable automatic dependency tracking if using other tools than +# gcc and gmake, add the option 'no-dependencies' +AUTOMAKE_OPTIONS = 1.8 +ACLOCAL_AMFLAGS = -I m4 + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = speexdsp.pc + +EXTRA_DIST = SpeexDSP.spec SpeexDSP.spec.in SpeexDSP.kdevelop speexdsp.pc.in README.blackfin README.symbian README.TI-DSP + +#Fools KDevelop into including all files +SUBDIRS = libspeexdsp include doc win32 symbian ti + +DIST_SUBDIRS = libspeexdsp include doc win32 symbian ti + +rpm: dist + rpmbuild -ta ${PACKAGE}-${VERSION}.tar.gz diff --git a/src/libs/speexdsp/NEWS b/src/libs/speexdsp/NEWS new file mode 100644 index 00000000..9a995291 --- /dev/null +++ b/src/libs/speexdsp/NEWS @@ -0,0 +1 @@ +2002/02/13: Creation of the "Speex" project diff --git a/src/libs/speexdsp/OPTIMIZE b/src/libs/speexdsp/OPTIMIZE new file mode 100644 index 00000000..d36f5f7d --- /dev/null +++ b/src/libs/speexdsp/OPTIMIZE @@ -0,0 +1,10 @@ +Narrowband: + +- pitch_gain_search_3tap calls syn_filt_zero more times than it should (we're +computing some things twice) + +Wideband + +- All narrowband optimizations apply +- Lots of time spent in the codebook search. We could speed that up by using + a hierarchical codebook diff --git a/src/libs/speexdsp/README b/src/libs/speexdsp/README new file mode 100644 index 00000000..84fe74ad --- /dev/null +++ b/src/libs/speexdsp/README @@ -0,0 +1,9 @@ +See INSTALL file for instruction on how to install Speex. + +The Speex is a patent-free, Open Source/Free Software voice codec. Unlike other codecs like MP3 and Ogg Vorbis, Speex is designed to compress voice at bitrates in the 2-45 kbps range. Possible applications include VoIP, internet audio streaming, archiving of speech data (e.g. voice mail), and audio books. In some sense, it is meant to be complementary to the Ogg Vorbis codec. + +To use the Speex command line tools: + +% speexenc [options] input_file.wav compressed_file.spx + +% speexdec [options] compressed_file.spx output_file.wav diff --git a/src/libs/speexdsp/README.TI-DSP b/src/libs/speexdsp/README.TI-DSP new file mode 100644 index 00000000..c3b75767 --- /dev/null +++ b/src/libs/speexdsp/README.TI-DSP @@ -0,0 +1,56 @@ +These are all of the changes and additions necessary to build a loopback application for the +TI C6415, C5509A, or C5416 simulators using the TI Code Composer Studio (CCS) development system. +A trial version of the tools can be downloaded from the TI website. + +This build runs 8kbps narrowband, with minimum complexity. + +Several changes are introduced in Speex 1.1.11 which are used in these applications: + +arch.h: Added switch for compilers not supporting "long long" (C55x does, C54x, CCS 2.x C64x does not) +bits.c: Allow external definition for max buffer size, changed MAX_BYTES_PER_FRAME + to MAX_CHARS_PER_FRAME for consistency +misc.c: Added override switches to alloc routines, conditional include of user file "user_misc.h". + These changes allow manual memory allocation rather than using heap + +The arch.h change allows operation with 2.x versions of Code Composer Studio. +The bits.c change reduces the data memory usage. +The misc.c change allows private memory allocation, for cases where it is not +desirable to use the normal heap. + +Added files: + +testenc-TI-C5x.c (For C54x and C55x builds, derived from testenc.c, + manual alloc, byte packing/unpacking added) +testenc-TI-C64x.c (For C64x builds, derived from testenc.c, manual alloc, byte packing/unpacking added) + +config.h (not automatically generated, sets memory sizes, enables/disables manual alloc) +user_misc.h (contains the manual memory alloc routines, with debug code to display mem usage) +speex\speex_config_types.h (match Speex types to compiler types, not generated from types.in) + +speex_c54_test\speex_c54_test.cmd (C5416 linker command file) +speex_c54_test\speex_c54_test.pjt (Code Composer Studio Project File ) +speex_c55_test\speex_c55_test.cmd (C5509A linker command file) +speex_c55_test\speex_c55_test.pjt (Code Composer Studio Project File ) +speex_c64_test\speex_c64_test.cmd (C6415 linker command file) +speex_c64_test\speex_c64_test.pjt (Code Composer Studio Project File ) + +samples\male.snd + +Usage: +1. Create a Speex 1.1.11 (or later) source tree. +2. Edit the files testenc-TI-C5x.c and/or testenc-TI-C64x.c to change the hard-coded path + for the test audio and data files. + This build uses the file e:\speextrunktest\samples\male.snd. + Note: This is a headerless 16-bit stereo audio file derived from the male.wav test file + http://www.speex.org/samples/male.wav +3. Edit the .pjt file with a text editor and change projdir or projectdir to the correct path + (one place near the top of the file). +4. Edit config.h if desired, to change the memory allocation method (calloc or manual), + and to enable/disable debug prints for the memory allocation + (this makes it easier to determine the required size). +5. Run Code Composer Studio, and open the project for the desired target (e.g. speex_c55_test). + Note that the correct simulator must be selected (in CCS Setup) before starting CCS. +6. Build and run the simulation. + +Note that assembly optimizations will be required to run C54x in real time. +There are no assembly optimizations in any of these builds. diff --git a/src/libs/speexdsp/README.Trimedia b/src/libs/speexdsp/README.Trimedia new file mode 100644 index 00000000..8adc80e9 --- /dev/null +++ b/src/libs/speexdsp/README.Trimedia @@ -0,0 +1,191 @@ +################# REMOVE warnings on trimedia compiler ############################## +################# Not critical to compilation ############################## + +1. Change the following statements to remove warning for constant expression +(i) mdf.c [if(0) --> #if 0] +(ii) ltp.c [if(1) --> #if 1] +(iii) preprocess.c [if(1) --> #if 1] +(iv) sb_celp.c [if (SPEEX_SET_VBR_MAX_BITRATE<1) --> #if (SPEEX_SET_VBR_MAX_BITRATE<1)] + +2. add REMARK_ON macro to remove warning on not reference variable +-- uses (void)<variable> to remove warning on not referenced variable +-- #define REMARK_ON +-- (void)<variable> +-- #endif +-- search for REMARK_ON on the following files +(i) jitter.c +(ii) lsp.c +(iii) ltp.c +(iv) mdf.c +(v) filters.c +(vi) filterbank.c +(vii) cb_search.c +(viii) vq.c +(ix) vbr.c +(x) stereo.c +(xi) speex_callbacks.c +(xii) preprocess.c + +3. commented out the following in pseudofloat.h for unused variable +//static const spx_float_t FLOAT_HALF = {16384,-15}; + +4. commented out unused variable in nb_celp.c +//spx_word16_t *sp; ***unused variable*** +//sp=out+offset; ***unused variable*** +//int submode; ***unused variable*** +// ***unused variable*** +// advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); +advance = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); +// ***unused variable*** +//advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); +advance = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); +// spx_word16_t *exc; ***unused variable*** +// exc=st->exc+offset; ***unused variable*** + +5. commented out unused variable in vbr.c +//int va; ***unused variable*** +//va = 0; ***unused variable*** +//va = 1; ***unused variable*** + +6. added HAVE_CONFIG into medfilter.c + +################# Patches for trimedia compiler ############################## +################# Critical to compilation ############################## +-- change the following in modes.c and speex.h as compiler does not support const * const... +(i) modes.c +#ifdef __TCS__ +const SpeexMode * speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode}; +#else +const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode}; +#endif + +(ii) speex.h +#ifdef __TCS__ +extern const SpeexMode * speex_mode_list[SPEEX_NB_MODES]; +#else +extern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES]; +#endif + +-- added the #elif defined (TM_ASM) to the following files for optimized codes +(1) arch.h +(2) cb_search.c +(3) fftwrap.c +(4) filterbank.c +(5) filters.c +(6) kiss_fft.c +(7) kiss_fftr.c +(8) lpc.c +(9) lsp.c +(10) ltp.c +(11) mdf.c +(12) misc.c +(13) preprocess.c +(14) quant_lsp.c +(15) vq.c + +-- reorder macro definations in quant_lsp.c +#ifdef FIXED_POINT + +#define LSP_LINEAR(i) (SHL16(i+1,11)) +#define LSP_LINEAR_HIGH(i) (ADD16(MULT16_16_16(i,2560),6144)) +#define LSP_DIV_256(x) (SHL16((spx_word16_t)x, 5)) +#define LSP_DIV_512(x) (SHL16((spx_word16_t)x, 4)) +#define LSP_DIV_1024(x) (SHL16((spx_word16_t)x, 3)) +#define LSP_PI 25736 + +#else + +#define LSP_LINEAR(i) (.25*(i)+.25) +#define LSP_LINEAR_HIGH(i) (.3125*(i)+.75) +#define LSP_SCALE 256. +#define LSP_DIV_256(x) (0.0039062*(x)) +#define LSP_DIV_512(x) (0.0019531*(x)) +#define LSP_DIV_1024(x) (0.00097656*(x)) +#define LSP_PI M_PI + +#endif + +#ifdef BFIN_ASM +#include "quant_lsp_bfin.h" +#elif defined (TM_ASM) +#include "quant_lsp_tm.h" +#endif + +-- added macro PREPROCESS_MDF_FLOAT to allow using of floating point +-- in mdf and preprocess while keeping fixed point in encoder/decoder +-- This is due to the fact that preprocess/mdf run faster on floating +-- point on trimedia +-- added the following 3 lines to the files below +#ifdef PREPROCESS_MDF_FLOAT +#undef FIXED_POINT +#endif +(1) mdf.c +(2) preprocess.c +(3) filterbank.c +(4) fftwrap.c +(5) kiss_fft.c +(6) kiss_fftr.c + +-- created a new USE_COMPACT_KISS_FFT for fftwrap.c and shifted defination +-- to config file so that user configure the usage of fft on config.h +-- TOEXPLORE:is it possible to share table between mdf/preprocess? +-- Introducing this macro made the following changes in C code +-- New macro to facilitate integration +(grouping real/complex for dc and nyquist frequency seems to require a large +amount of memory for mdf, therefore did not made the changes for that) +(1) modify preprocess.c on init and destroy +(2) modify mdf.c on init and destroy +(3) shifted power_spectrum to fftwrap.c to share optimised code between + preprocess.c and mdf.c + +################# NOTES ############################## +(1) fixed point encoding/decoding is tested on narrowband + - some of the QX fractions are packed together to + (frac1 * a + frac2 * a) >> X (should be more accurate in rounding) + instead of + ((frac1 * a) >> X) + ((frac2 * a) >> X) + will cause some different between optimized and unoptimized code. + tried decoding/encoding optimized code on some audio files retains + the clearity of the word + + - wideband/ultrawideband is not heavily tested yet + +(2) optimized fixed point code requires memory alignment + - used config to debug on functions where memory is not align + +(3) floating point optimization for preprocess/mdf is tested + fixed point is not tested yet (except fft/filterbank) + Note (1) also applies to sround in fft for fixed point + some optimization is provided for fixed point as it requires lesser + memory compared to floating point. + +(4) unroll configurations provided to reduce code size if required + +(5) use profile options only if compiler profiling fails to work + +(6) can't include the makefile as it is close proprietary + +################# TODO:For Trimedia ############################## +(1) Possible add TSSA wrapper for codec but don't think this can be open source. +(2) Optimizations for fixed point in mdf/preprocess + +################# Added Files ############################## +- _kiss_fft_guts_tm.h +- cb_search_tm.h +- fftwrap_tm.h +- filterbank_tm.h +- filters_tm.h +- fixed_tm.h +- kiss_fft_tm.h +- kiss_fftr_tm.h +- lpc_tm.h +- lsp_tm.h +- ltp_tm.h +- mdf_tm.h +- misc_tm.h +- preprocess_tm.h +- profile_tm.h +- quant_lsp_tm.h +- vq_tm.h +- config.h +- speex_config_types.h diff --git a/src/libs/speexdsp/README.blackfin b/src/libs/speexdsp/README.blackfin new file mode 100644 index 00000000..7e8d600a --- /dev/null +++ b/src/libs/speexdsp/README.blackfin @@ -0,0 +1,21 @@ +Speex has been ported to the Blackfin DSP, for the STAMP development board. + +This port has been tested on the STAMP development board and requires the +toolchain available at http://blackfin.uclinux.org/ + +1/ In order to cross-compile for uClinux from the Speex tarball: + + ./configure --enable-blackfin-asm --enable-fixed-point --host=bfin-uclinux + cd libspeex + make + +The --enable-blackfin-asm option is not required, but it speeds up Speex by +approximately a factor of two. + +2/ In order to cross-compile for uClinux from the Speex SVN: + + svn co http://svn.xiph.org/trunk/speex speex-trunk + cd speex-trunk + ./autogen.sh --enable-blackfin-asm --enable-fixed-point --host=bfin-uclinux + cd libspeex + make diff --git a/src/libs/speexdsp/README.symbian b/src/libs/speexdsp/README.symbian new file mode 100644 index 00000000..a4f8d958 --- /dev/null +++ b/src/libs/speexdsp/README.symbian @@ -0,0 +1,43 @@ +Using Speex on Symbian OS +Conrad Parker and Colin Ward, CSIRO Australia, July 2004 + + +Introduction +------------ + +The symbian/ directory contains the following files for Symbian's abuild tool: + + bld.inf Component definition file + speex.mmp Project specification file + config.h Configuration options for both emulator and device builds + + +Developing applications for libspeex for Symbian OS +--------------------------------------------------- + + Any references to the statically defined SpeexMode structures must be + replaced by a call to a speex_lib_get_mode () for that mode. + + * References to the statically defined array speex_mode_list[modeID] + must be replaced by a call to speex_lib_get_mode (modeID): + +- mode = speex_mode_list[modeID]; ++ mode = speex_lib_get_mode (modeID); + + * References to the statically defined mode structures must be replaced: + + SpeexMode * mode1, * mode2, * mode3; + +- mode1 = &speex_nb_mode; ++ mode1 = speex_lib_get_mode (SPEEX_MODEID_NB); + +- mode2 = &speex_wb_mode; ++ mode2 = speex_lib_get_mode (SPEEX_MODEID_WB); + +- mode3 = &speex_uwb_mode; ++ mode3 = speex_lib_get_mode (SPEEX_MODEID_UWB); + + Note that the constants SPEEX_MODEID_NB, SPEEX_MODEID_WB and + SPEEX_MODEID_UWB were introduced in libspeex 1.1.6, and are + defined in <speex/speex.h>. speex_lib_get_mode() was introduced + in libspeex 1.1.7 and is declared in <speex/speex.h>. diff --git a/src/libs/speexdsp/README.win32 b/src/libs/speexdsp/README.win32 new file mode 100644 index 00000000..51426b8c --- /dev/null +++ b/src/libs/speexdsp/README.win32 @@ -0,0 +1,11 @@ +Win32 Specific options + +In order to enable the following options within Speex, you will need to manually edit the project options for the appropriate VC configuration. These macros can be specified by adding them as "Preprocessor Definitions" under the appropriate Configuration's project options. If you don't know how to do this, please check your Visual C documentation. + +Feature: + +Intel Streaming SIMD Extensions - SSE - macro: USE_SSE +Fixed point - macro: FIXED_POINT +Epic 48 - macro: EPIC_48K + +Note: USE_SSE and FIXED_POINT are mutually exclusive. diff --git a/src/libs/speexdsp/SpeexDSP.kdevelop b/src/libs/speexdsp/SpeexDSP.kdevelop new file mode 100644 index 00000000..1b3d683b --- /dev/null +++ b/src/libs/speexdsp/SpeexDSP.kdevelop @@ -0,0 +1,201 @@ +<?xml version = '1.0'?> +<kdevelop> + <general> + <author>Jean-Marc Valin</author> + <email>jean-marc.valin@usherbrooke.ca</email> + <version>$VERSION$</version> + <projectmanagement>KDevAutoProject</projectmanagement> + <primarylanguage>C</primarylanguage> + <ignoreparts/> + <projectdirectory>.</projectdirectory> + <absoluteprojectpath>false</absoluteprojectpath> + <description/> + <secondaryLanguages/> + <versioncontrol>kdevsubversion</versioncontrol> + <defaultencoding/> + <projectname>Speex</projectname> + </general> + <kdevautoproject> + <general> + <activetarget>libspeex/libspeex.la</activetarget> + <useconfiguration>float</useconfiguration> + </general> + <run> + <mainprogram>src/Speex</mainprogram> + <directoryradio>executable</directoryradio> + <customdirectory>/</customdirectory> + <programargs/> + <terminal>false</terminal> + <autocompile>true</autocompile> + <envvars/> + <autoinstall>false</autoinstall> + <autokdesu>false</autokdesu> + </run> + <configurations> + <float> + <builddir>float</builddir> + <ccompiler>kdevgccoptions</ccompiler> + <cxxcompiler>kdevgppoptions</cxxcompiler> + <f77compiler>kdevpgf77options</f77compiler> + <cflags>-O2 -g -Wall</cflags> + <envvars/> + <configargs>--disable-shared</configargs> + <topsourcedir/> + <cppflags/> + <ldflags/> + <ccompilerbinary/> + <cxxcompilerbinary/> + <f77compilerbinary/> + <cxxflags/> + <f77flags/> + </float> + <fixed> + <configargs>--enable-fixed-point --disable-shared</configargs> + <builddir>fixed</builddir> + <ccompiler>kdevgccoptions</ccompiler> + <cxxcompiler>kdevgppoptions</cxxcompiler> + <f77compiler>kdevpgf77options</f77compiler> + <cflags>-O2 -g -Wall</cflags> + <envvars/> + <topsourcedir/> + <cppflags/> + <ldflags/> + <ccompilerbinary/> + <cxxcompilerbinary/> + <f77compilerbinary/> + <cxxflags/> + <f77flags/> + </fixed> + <default> + <envvars/> + </default> + </configurations> + <make> + <envvars> + <envvar value="1" name="WANT_AUTOCONF_2_5" /> + <envvar value="1" name="WANT_AUTOMAKE_1_6" /> + </envvars> + <abortonerror>false</abortonerror> + <numberofjobs>4</numberofjobs> + <dontact>false</dontact> + <makebin/> + <runmultiplejobs>true</runmultiplejobs> + <prio>0</prio> + </make> + </kdevautoproject> + <kdevdebugger> + <general> + <dbgshell>libtool</dbgshell> + <programargs/> + <gdbpath/> + <configGdbScript/> + <runShellScript/> + <runGdbScript/> + <breakonloadinglibs>true</breakonloadinglibs> + <separatetty>false</separatetty> + <floatingtoolbar>false</floatingtoolbar> + </general> + <display> + <staticmembers>false</staticmembers> + <demanglenames>true</demanglenames> + <outputradix>10</outputradix> + </display> + </kdevdebugger> + <kdevfilecreate> + <filetypes/> + <useglobaltypes> + <type ext="c" /> + <type ext="h" /> + </useglobaltypes> + </kdevfilecreate> + <kdevcppsupport> + <references/> + <codecompletion> + <includeGlobalFunctions>true</includeGlobalFunctions> + <includeTypes>true</includeTypes> + <includeEnums>true</includeEnums> + <includeTypedefs>false</includeTypedefs> + <automaticCodeCompletion>true</automaticCodeCompletion> + <automaticArgumentsHint>true</automaticArgumentsHint> + <automaticHeaderCompletion>true</automaticHeaderCompletion> + <codeCompletionDelay>350</codeCompletionDelay> + <argumentsHintDelay>400</argumentsHintDelay> + <headerCompletionDelay>250</headerCompletionDelay> + <showOnlyAccessibleItems>false</showOnlyAccessibleItems> + <completionBoxItemOrder>0</completionBoxItemOrder> + <howEvaluationContextMenu>true</howEvaluationContextMenu> + <showCommentWithArgumentHint>true</showCommentWithArgumentHint> + <statusBarTypeEvaluation>false</statusBarTypeEvaluation> + <namespaceAliases>std=_GLIBCXX_STD;__gnu_cxx=std</namespaceAliases> + <processPrimaryTypes>true</processPrimaryTypes> + <processFunctionArguments>true</processFunctionArguments> + <preProcessAllHeaders>false</preProcessAllHeaders> + <parseMissingHeaders>false</parseMissingHeaders> + <resolveIncludePaths>true</resolveIncludePaths> + <alwaysParseInBackground>true</alwaysParseInBackground> + <usePermanentCaching>true</usePermanentCaching> + <alwaysIncludeNamespaces>true</alwaysIncludeNamespaces> + <includePaths>.;</includePaths> + <parseMissingHeadersExperimental>false</parseMissingHeadersExperimental> + <resolveIncludePathsUsingMakeExperimental>false</resolveIncludePathsUsingMakeExperimental> + </codecompletion> + <qt> + <used>false</used> + <version>3</version> + <root>/usr/share/qt3</root> + <includestyle>3</includestyle> + <designerintegration>EmbeddedKDevDesigner</designerintegration> + <qmake>/usr/share/qt3/bin/qmake</qmake> + <designer>/usr/bin/designer-qt3</designer> + <designerpluginpaths/> + </qt> + <creategettersetter> + <prefixGet/> + <prefixSet>set</prefixSet> + <prefixVariable>m_,_</prefixVariable> + <parameterName>theValue</parameterName> + <inlineGet>true</inlineGet> + <inlineSet>true</inlineSet> + </creategettersetter> + <splitheadersource> + <enabled>true</enabled> + <synchronize>true</synchronize> + <orientation>Horizontal</orientation> + </splitheadersource> + </kdevcppsupport> + <kdevfileview> + <groups> + <hidenonprojectfiles>false</hidenonprojectfiles> + <hidenonlocation>false</hidenonlocation> + </groups> + <tree> + <hidepatterns>*.o,*.lo,CVS</hidepatterns> + <hidenonprojectfiles>true</hidenonprojectfiles> + <showvcsfields>false</showvcsfields> + </tree> + </kdevfileview> + <kdevdoctreeview> + <projectdoc> + <userdocDir>html/</userdocDir> + <apidocDir>html/</apidocDir> + </projectdoc> + <ignoreqt_xml/> + <ignoredoxygen/> + <ignorekdocs/> + <ignoretocs/> + <ignoredevhelp/> + </kdevdoctreeview> + <cppsupportpart> + <filetemplates> + <interfacesuffix>.h</interfacesuffix> + <implementationsuffix>.cpp</implementationsuffix> + </filetemplates> + </cppsupportpart> + <kdevdocumentation> + <projectdoc> + <docsystem/> + <docurl/> + <usermanualurl/> + </projectdoc> + </kdevdocumentation> +</kdevelop> diff --git a/src/libs/speexdsp/SpeexDSP.spec.in b/src/libs/speexdsp/SpeexDSP.spec.in new file mode 100644 index 00000000..440856bb --- /dev/null +++ b/src/libs/speexdsp/SpeexDSP.spec.in @@ -0,0 +1,67 @@ +%define name @PACKAGE@ +%define ver @VERSION@ +%define rel 1 + +Summary: An open-source, patent-free speech codec +Name: %name +Version: %ver +Release: %rel +License: BSD +Group: Application/Devel +Source: http://www.speex.org/download/%{name}-%{ver}.tar.gz +URL: http://www.speex.org/ +Vendor: Speex +Packager: Jean-Marc Valin (jean-marc.valin@usherbrooke.ca) +BuildRoot: /var/tmp/%{name}-build-root +Docdir: /usr/share/doc + +%description +Speex is a patent-free audio codec designed especially for voice (unlike +Vorbis which targets general audio) signals and providing good narrowband +and wideband quality. This project aims to be complementary to the Vorbis +codec. + +%package devel +Summary: Speex development files +Group: Development/Libraries +Requires: %{name} = %{version} + +%description devel +Speex development files. + +%changelog +* Thu Oct 03 2002 Jean-Marc Valin +- Added devel package inspired from PLD spec file + +* Tue Jul 30 2002 Fredrik Rambris <boost@users.sourceforge.net> 0.5.2 +- Added buildroot and docdir and ldconfig. Makes it builadble by non-roots + and also doesn't write to actual library paths when building. + +%prep +%setup + +%build +export CFLAGS='-O3' +./configure --prefix=/usr --enable-shared --enable-static +make + +%install +rm -rf $RPM_BUILD_ROOT +make DESTDIR=$RPM_BUILD_ROOT install + +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig + +%files +%defattr(644,root,root,755) +%doc COPYING AUTHORS ChangeLog NEWS README +%doc doc/manual.pdf +%attr(755,root,root) %{_bindir}/speex* +%attr(755,root,root) %{_libdir}/libspeex*.so* + +%files devel +%defattr(644,root,root,755) +%attr(755,root,root) %{_libdir}/libspeex*.la +%{_includedir}/speex/speex*.h +%{_libdir}/pkgconfig/speexdsp.pc +%{_libdir}/libspeex*.a diff --git a/src/libs/speexdsp/TODO b/src/libs/speexdsp/TODO new file mode 100644 index 00000000..fd3c953a --- /dev/null +++ b/src/libs/speexdsp/TODO @@ -0,0 +1,48 @@ +For 1.2: +Major points: +- Make documentation match the actual code (especially jitter buffer, AEC and preprocessor) +- Get AGC to work in fixed-point even if not totally converted +- Stabilise all APIs (need feedback) +- Short-term estimate in jitter buffer +- Control delay in new AEC API. +- NaN checks? +- Better error reporting +- Make kiss-fft 32-bit safe + +Minor issues: +- Fix last frame of speexenc + + +Post 1.2: +improve float<->int conversion +split encoder and decoder? +Merge TriMedia stuff +packet dump +Do VAD properly +--enable-{aec,preprocessor,jitter,resampler} + +Optimisations +- Add restrict in a few places? +- enable 4x4 version of pitch_xcorr() at least on some archs? +- use __builtin_expect() (likely()/unlikely()) + +Would be nice: +Implement wideband split as IIR instead of QMF? + +Allocator override (speex_lib_ctl?) +Fixed-point: + - VBR + - Jitter buffer + - AGC +Denoiser: + - Better noise adaptation +AGC: + - Use median filtering instead of "non-linear mean"? + +Standards +-Complete Speex RTP profile +-MIME type registration + +ideas: +Peelable stream (double codebook, higher bands, stereo) +LPC from spectral domain diff --git a/src/libs/speexdsp/acinclude.m4 b/src/libs/speexdsp/acinclude.m4 new file mode 100644 index 00000000..0e1f1abf --- /dev/null +++ b/src/libs/speexdsp/acinclude.m4 @@ -0,0 +1,102 @@ +# Configure paths for libogg +# Jack Moffitt <jack@icecast.org> 10-21-2000 +# Shamelessly stolen from Owen Taylor and Manish Singh + +dnl XIPH_PATH_OGG([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Test for libogg, and define OGG_CFLAGS and OGG_LIBS +dnl +AC_DEFUN([XIPH_PATH_OGG], +[dnl +dnl Get the cflags and libraries +dnl +AC_ARG_WITH(ogg,[ --with-ogg=PFX Prefix where libogg is installed (optional)], ogg_prefix="$withval", ogg_prefix="") +AC_ARG_WITH(ogg-libraries,[ --with-ogg-libraries=DIR Directory where libogg library is installed (optional)], ogg_libraries="$withval", ogg_libraries="") +AC_ARG_WITH(ogg-includes,[ --with-ogg-includes=DIR Directory where libogg header files are installed (optional)], ogg_includes="$withval", ogg_includes="") +AC_ARG_ENABLE(oggtest, [ --disable-oggtest Do not try to compile and run a test Ogg program],, enable_oggtest=yes) + + if test "x$ogg_libraries" != "x" ; then + OGG_LIBS="-L$ogg_libraries" + elif test "x$ogg_prefix" != "x" ; then + OGG_LIBS="-L$ogg_prefix/lib" + elif test "x$prefix" != "xNONE" ; then + OGG_LIBS="-L$prefix/lib" + fi + + OGG_LIBS="$OGG_LIBS -logg" + + if test "x$ogg_includes" != "x" ; then + OGG_CFLAGS="-I$ogg_includes" + elif test "x$ogg_prefix" != "x" ; then + OGG_CFLAGS="-I$ogg_prefix/include" + elif test "x$prefix" != "xNONE"; then + OGG_CFLAGS="-I$prefix/include" + fi + + AC_MSG_CHECKING(for Ogg) + no_ogg="" + + + if test "x$enable_oggtest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $OGG_CFLAGS" + LIBS="$LIBS $OGG_LIBS" +dnl +dnl Now check if the installed Ogg is sufficiently new. +dnl + rm -f conf.oggtest + AC_TRY_RUN([ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ogg/ogg.h> + +int main () +{ + system("touch conf.oggtest"); + return 0; +} + +],, no_ogg=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + + if test "x$no_ogg" = "x" ; then + AC_MSG_RESULT(yes) + ifelse([$1], , :, [$1]) + else + AC_MSG_RESULT(no) + if test -f conf.oggtest ; then + : + else + echo "*** Could not run Ogg test program, checking why..." + CFLAGS="$CFLAGS $OGG_CFLAGS" + LIBS="$LIBS $OGG_LIBS" + AC_TRY_LINK([ +#include <stdio.h> +#include <ogg/ogg.h> +], [ return 0; ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding Ogg or finding the wrong" + echo "*** version of Ogg. If it is not finding Ogg, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means Ogg was incorrectly installed" + echo "*** or that you have moved Ogg since it was installed." ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + OGG_CFLAGS="" + OGG_LIBS="" + ifelse([$2], , :, [$2]) + fi + AC_SUBST(OGG_CFLAGS) + AC_SUBST(OGG_LIBS) + rm -f conf.oggtest +]) diff --git a/src/libs/speexdsp/autogen.sh b/src/libs/speexdsp/autogen.sh new file mode 100644 index 00000000..b58da316 --- /dev/null +++ b/src/libs/speexdsp/autogen.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Run this to set up the build system: configure, makefiles, etc. +set -e + +srcdir=`dirname $0` +test -n "$srcdir" && cd "$srcdir" + +echo "Updating build configuration files, please wait...." + +mkdir -p m4 + +ACLOCAL_FLAGS="-I m4" +autoreconf -if + diff --git a/src/libs/speexdsp/configure.ac b/src/libs/speexdsp/configure.ac new file mode 100644 index 00000000..2ba0b13d --- /dev/null +++ b/src/libs/speexdsp/configure.ac @@ -0,0 +1,297 @@ +dnl Process this file with autoconf to produce a configure script. -*-m4-*- + +AC_INIT([speexdsp],[1.2rc1],[speex-dev@xiph.org]) + +AC_CONFIG_SRCDIR([libspeexdsp/preprocess.c]) +AC_CONFIG_MACRO_DIR([m4]) + +dnl enable silent rules on automake 1.11 and later +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + + +SPEEXDSP_LT_CURRENT=6 +SPEEXDSP_LT_REVISION=0 +SPEEXDSP_LT_AGE=5 + + +AC_SUBST(SPEEXDSP_LT_CURRENT) +AC_SUBST(SPEEXDSP_LT_REVISION) +AC_SUBST(SPEEXDSP_LT_AGE) + +AM_INIT_AUTOMAKE([foreign no-define]) +AM_MAINTAINER_MODE([enable]) + +AC_CANONICAL_HOST +AC_LIBTOOL_WIN32_DLL +AM_PROG_LIBTOOL + +AC_C_BIGENDIAN +AC_C_CONST +AC_C_INLINE +AC_C_RESTRICT + + +AC_MSG_CHECKING(for C99 variable-size arrays) +AC_TRY_COMPILE( , [ +int foo; +foo = 10; +int array[foo]; +], +[has_var_arrays=yes;AC_DEFINE([VAR_ARRAYS], [], [Use C99 variable-size arrays]) +], +has_var_arrays=no +) +AC_MSG_RESULT($has_var_arrays) + +AC_CHECK_HEADERS([alloca.h getopt.h]) +AC_MSG_CHECKING(for alloca) +AC_TRY_COMPILE( [ +#ifdef HAVE_ALLOCA_H +# include <alloca.h> +#endif +#include <stdlib.h> +], [ +int foo=10; +int *array = alloca(foo); +], +[ +has_alloca=yes; +if test x$has_var_arrays = "xno" ; then +AC_DEFINE([USE_ALLOCA], [], [Make use of alloca]) +fi +], +has_alloca=no +) +AC_MSG_RESULT($has_alloca) + +AC_MSG_CHECKING(for SSE in current arch/CFLAGS) +AC_LINK_IFELSE([ +AC_LANG_PROGRAM([[ +#include <xmmintrin.h> +__m128 testfunc(float *a, float *b) { + return _mm_add_ps(_mm_loadu_ps(a), _mm_loadu_ps(b)); +} +]])], +[ +has_sse=yes +], +[ +has_sse=no +] +) +AC_MSG_RESULT($has_sse) + +SAVE_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -fvisibility=hidden" +AC_MSG_CHECKING(for ELF visibility) +AC_COMPILE_IFELSE([ +AC_LANG_PROGRAM([[ +#pragma GCC visibility push(hidden) +__attribute__((visibility("default"))) +int var=10; +]])], +[ +has_visibility=yes +AC_DEFINE([EXPORT], [__attribute__((visibility("default")))], [Symbol visibility prefix]) +], +[ +has_visibility=no +AC_DEFINE([EXPORT], [], [Symbol visibility prefix]) +CFLAGS="$SAVE_CFLAGS" +] +) +AC_MSG_RESULT($has_visibility) + +AC_CHECK_HEADERS(sys/soundcard.h sys/audioio.h) + +AC_SUBST(src) + +LT_LIB_M + + +AC_ARG_ENABLE(valgrind, [ --enable-valgrind Enable valgrind extra checks], +[if test "$enableval" = yes; then + AC_DEFINE([ENABLE_VALGRIND], , [Enable valgrind extra checks]) +fi]) + +AC_ARG_ENABLE(sse, [ --enable-sse Enable SSE support], [ +if test "x$enableval" != xno; then +has_sse=yes +CFLAGS="$CFLAGS -O3 -msse" +else +has_sse=no +fi +]) + + +FFT=smallft + +AC_ARG_ENABLE(fixed-point, [ --enable-fixed-point Compile as fixed-point], +[if test "$enableval" = yes; then + FFT=kiss + has_sse=no + AC_DEFINE([FIXED_POINT], , [Compile as fixed-point]) +else + AC_DEFINE([FLOATING_POINT], , [Compile as floating-point]) +fi], +AC_DEFINE([FLOATING_POINT], , [Compile as floating-point])) + +if test "$has_sse" = yes; then + AC_DEFINE([_USE_SSE], , [Enable SSE support]) +fi + +AC_ARG_ENABLE(float-api, [ --disable-float-api Disable the floating-point API], +[if test "$enableval" = no; then + AC_DEFINE([DISABLE_FLOAT_API], , [Disable all parts of the API that are using floats]) +fi]) + +AC_ARG_ENABLE(arm4-asm, [ --enable-arm4-asm Make use of ARM4 assembly optimizations], +[if test "$enableval" = yes; then + AC_DEFINE([ARM4_ASM], , [Make use of ARM4 assembly optimizations]) +fi]) + +AC_ARG_ENABLE(arm5e-asm, [ --enable-arm5e-asm Make use of ARM5E assembly optimizations], +[if test "$enableval" = yes; then + AC_DEFINE([ARM5E_ASM], , [Make use of ARM5E assembly optimizations]) +fi]) + +AC_ARG_ENABLE(blackfin-asm, [ --enable-blackfin-asm Make use of Blackfin assembly optimizations], +[if test "$enableval" = yes; then + AC_DEFINE([BFIN_ASM], , [Make use of Blackfin assembly optimizations]) +fi]) +case $host_os in + uclinux) LDFLAGS="-Wl,-elf2flt=-s100000 $LDFLAGS";; +esac + +AC_ARG_ENABLE(fixed-point-debug, [ --enable-fixed-point-debug Debug fixed-point implementation], +[if test "$enableval" = yes; then + AC_DEFINE([FIXED_DEBUG], , [Debug fixed-point implementation]) +fi]) + +AC_ARG_ENABLE(ti-c55x, [ --enable-ti-c55x Enable support for TI C55X DSP], +[if test "$enableval" = yes; then + has_char16=yes; + AC_DEFINE([TI_C55X], , [Enable support for TI C55X DSP]) +fi]) + +AC_ARG_WITH([fft], [AS_HELP_STRING([--with-fft=choice],[use an alternate FFT implementation. The available choices are +kiss (default fixed point), smallft (default floating point), gpl-fftw3 and proprietary-intel-mkl])], +[FFT=$withval] +) + +FFT_PKGCONFIG= +AS_CASE([$FFT], + [kiss], [ + AC_DEFINE([USE_KISS_FFT], [], [Use KISS Fast Fourier Transform]) + ], + [smallft], [ + AC_DEFINE([USE_SMALLFT], [], [Use FFT from OggVorbis]) + ], + [gpl-fftw3], [ + AC_DEFINE([USE_GPL_FFTW3], [], [Use FFTW3 for FFT]) + PKG_CHECK_MODULES(FFT, fftw3f) + ], + [proprietary-intel-mkl], [ + AC_DEFINE([USE_INTEL_MKL], [], [Use Intel Math Kernel Library for FFT]) + AC_MSG_CHECKING(for valid MKL) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ +#include <mkl.h> +void func() { + DFTI_DESCRIPTOR_HANDLE h; + MKL_LONG result=DftiCreateDescriptor(&h, DFTI_SINGLE, DFTI_REAL, 0); +}]])], + [AC_MSG_RESULT(yes)], + [AC_MSG_FAILURE([Failed to compile MKL test program. Make sure you set CFLAGS to include the include directory and set LDFLAGS to include the library directory and all necesarry libraries.])] + ) + ], + [AC_MSG_FAILURE([Unknown FFT $FFT specified for --with-fft])] +) +AM_CONDITIONAL(BUILD_KISS_FFT, [test "$FFT" = "kiss"]) +AM_CONDITIONAL(BUILD_SMALLFT, [test "$FFT" = "smallft"]) +AC_SUBST(FFT_PKGCONFIG) + + +AC_CHECK_SIZEOF([int16_t]) +AC_CHECK_SIZEOF([uint16_t]) +AC_CHECK_SIZEOF([u_int16_t]) +AC_CHECK_SIZEOF([int32_t]) +AC_CHECK_SIZEOF([uint32_t]) +AC_CHECK_SIZEOF([u_int32_t]) +AC_CHECK_SIZEOF([short]) +AC_CHECK_SIZEOF([int]) +AC_CHECK_SIZEOF([long]) + +AS_IF([test "$has_char16" = "yes"], + [ + SIZEOF16=1 + SIZEOF32=2 + ],[ + SIZEOF16=2 + SIZEOF32=4 + ]) + +case $SIZEOF16 in + $ac_cv_sizeof_int16_t) SIZE16="int16_t";; + $ac_cv_sizeof_short) SIZE16="short";; + $ac_cv_sizeof_int) SIZE16="int";; +esac + +case $SIZEOF16 in + $ac_cv_sizeof_uint16_t) USIZE16="uint16_t";; + $ac_cv_sizeof_u_int16_t) USIZE16="u_int16_t";; + $ac_cv_sizeof_short) USIZE16="unsigned short";; + $ac_cv_sizeof_int) USIZE16="unsigned int";; +esac + +case $SIZEOF32 in + $ac_cv_sizeof_int32_t) SIZE32="int32_t";; + $ac_cv_sizeof_int) SIZE32="int";; + $ac_cv_sizeof_long) SIZE32="long";; + $ac_cv_sizeof_short) SIZE32="short";; +esac + +case $SIZEOF32 in + $ac_cv_sizeof_uint32_t) USIZE32="uint32_t";; + $ac_cv_sizeof_u_int32_t) USIZE32="u_int32_t";; + $ac_cv_sizeof_short) USIZE32="unsigned short";; + $ac_cv_sizeof_int) USIZE32="unsigned int";; + $ac_cv_sizeof_long) USIZE32="unsigned long";; +esac + +AS_IF([test -z "$SIZE16"],[AC_MSG_ERROR([No 16 bit type found on this platform!])]) +AS_IF([test -z "$SIZE32"],[AC_MSG_ERROR([No 32 bit type found on this platform!])]) +AS_IF([test -z "$USIZE16"],[AC_MSG_ERROR([No unsigned 16 bit type found on this platform!])]) +AS_IF([test -z "$USIZE32"],[AC_MSG_ERROR([No unsigned 32 bit type found on this platform!])]) + +AC_SUBST([SIZE16]) +AC_SUBST([USIZE16]) +AC_SUBST([SIZE32]) +AC_SUBST([USIZE32]) + +AC_CONFIG_FILES([ + Makefile libspeexdsp/Makefile doc/Makefile SpeexDSP.spec + include/Makefile include/speex/Makefile speexdsp.pc + win32/Makefile win32/libspeexdsp/Makefile + symbian/Makefile + + win32/VS2003/Makefile + win32/VS2003/libspeexdsp/Makefile + win32/VS2003/tests/Makefile + + win32/VS2005/Makefile + win32/VS2005/libspeexdsp/Makefile + win32/VS2005/tests/Makefile + + win32/VS2008/Makefile + win32/VS2008/libspeexdsp/Makefile + win32/VS2008/tests/Makefile + include/speex/speexdsp_config_types.h ti/Makefile + ti/speex_C54_test/Makefile ti/speex_C55_test/Makefile + ti/speex_C64_test/Makefile ]) + +AC_CONFIG_HEADERS([config.h]) + +AC_OUTPUT + +echo "Type \"make; make install\" to compile and install Speex"; diff --git a/src/libs/speexdsp/doc/.cvsignore b/src/libs/speexdsp/doc/.cvsignore new file mode 100644 index 00000000..282522db --- /dev/null +++ b/src/libs/speexdsp/doc/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/src/libs/speexdsp/doc/Makefile.am b/src/libs/speexdsp/doc/Makefile.am new file mode 100644 index 00000000..d2896efa --- /dev/null +++ b/src/libs/speexdsp/doc/Makefile.am @@ -0,0 +1,3 @@ +doc_DATA = manual.pdf + +EXTRA_DIST = $(doc_DATA) diff --git a/src/libs/speexdsp/doc/celp_decoder.eps b/src/libs/speexdsp/doc/celp_decoder.eps new file mode 100644 index 00000000..87f07044 --- /dev/null +++ b/src/libs/speexdsp/doc/celp_decoder.eps @@ -0,0 +1,688 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 442 315 +%%Pages: 0 +%%Creator: Sun Microsystems, Inc. +%%Title: none +%%CreationDate: none +%%LanguageLevel: 2 +%%EndComments +%%BeginProlog +%%BeginResource: SDRes +/b4_inc_state save def +/dict_count countdictstack def +/op_count count 1 sub def +userdict begin +0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath +/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if +/bdef {bind def} bind def +/c {setgray} bdef +/l {neg lineto} bdef +/rl {neg rlineto} bdef +/lc {setlinecap} bdef +/lj {setlinejoin} bdef +/lw {setlinewidth} bdef +/ml {setmiterlimit} bdef +/ld {setdash} bdef +/m {neg moveto} bdef +/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef +/r {rotate} bdef +/t {neg translate} bdef +/s {scale} bdef +/sw {show} bdef +/gs {gsave} bdef +/gr {grestore} bdef +/f {findfont dup length dict begin +{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def +currentdict end /NFont exch definefont pop /NFont findfont} bdef +/p {closepath} bdef +/sf {scalefont setfont} bdef +/ef {eofill}bdef +/pc {closepath stroke}bdef +/ps {stroke}bdef +/pum {matrix currentmatrix}bdef +/pom {setmatrix}bdef +/bs {/aString exch def /nXOfs exch def /nWidth exch def currentpoint nXOfs 0 rmoveto pum nWidth aString stringwidth pop div 1 scale aString show pom moveto} bdef +%%EndResource +%%EndProlog +%%BeginSetup +%%EndSetup +%%Page: 1 1 +%%BeginPageSetup +%%EndPageSetup +pum +0.02836 0.02834 s +0 -11113 t +/tm matrix currentmatrix def +tm setmatrix +-5152 -9418 t +1 1 s +0 lw 1 lj 0.000 c 6935 14318 m 5435 14318 l 5435 10318 l 8435 10318 l +8435 14318 l 6935 14318 l pc +11436 12317 m 10934 12818 l 10936 11817 l 11436 12317 l pc +5831 11966 m 8109 11966 l ps +6425 11966 m 6425 11636 l ps +6123 11966 m 6123 12366 l ps +6727 11966 m 6727 11707 l ps +7719 11966 m 7719 11872 l ps +7070 11966 m 7070 12248 l ps +7439 11966 m 7439 11636 l ps +5830 10920 m 8108 10920 l ps +6163 10920 m 6163 10590 l ps +6470 10920 m 6470 11320 l ps +6726 10920 m 6726 10661 l ps +7109 10920 m 7109 10826 l ps +7417 10920 m 7417 11202 l ps +7699 10920 m 7699 10590 l ps +5831 10921 m 8109 10921 l ps +6164 10921 m 6164 10591 l ps +6471 10921 m 6471 11321 l ps +6727 10921 m 6727 10662 l ps +7110 10921 m 7110 10827 l ps +7418 10921 m 7418 11203 l ps +7700 10921 m 7700 10591 l ps +5857 12918 m 8135 12918 l ps +6190 12918 m 6188 12729 l ps +6497 12918 m 6497 13318 l ps +6753 12918 m 6751 13247 l ps +7136 12918 m 7136 12824 l ps +7444 12918 m 7442 12611 l ps +7796 12919 m 7794 13248 l ps +6935 17818 m 5435 17818 l 5435 15818 l 8435 15818 l 8435 17818 l 6935 17818 l +pc +gs +pum +6263 17039 t +219 -104 m 214 -66 184 -39 147 -39 ct 120 -39 99 -51 85 -74 ct 74 -92 71 -110 69 -147 ct +268 -147 l 266 -213 260 -244 245 -277 ct 224 -321 193 -341 149 -341 ct 71 -341 20 -271 20 -160 ct +20 -55 68 9 146 9 ct 208 9 252 -32 264 -104 ct 219 -104 l p +69 -192 m 72 -252 104 -292 147 -292 ct 171 -292 191 -280 203 -260 ct 214 -243 218 -226 220 -192 ct +69 -192 l p ef +362 -412 m 418 -412 l 418 -458 l 321 -458 l 321 124 l 418 124 l 418 78 l +362 78 l 362 -412 l p ef +508 -332 m 465 -332 l 465 0 l 511 0 l 511 -180 l 511 -250 539 -292 586 -292 ct +625 -292 642 -265 642 -204 ct 642 0 l 687 0 l 687 -226 l 687 -299 653 -341 595 -341 ct +558 -341 532 -324 508 -283 ct 508 -332 l p ef +870 -204 m 742 -204 l 742 -147 l 870 -147 l 870 -204 l p ef +899 -400 m 1026 -400 l 1026 0 l 1077 0 l 1077 -400 l 1204 -400 l +1204 -455 l 899 -455 l 899 -400 l p ef +1281 78 m 1225 78 l 1225 124 l 1322 124 l 1322 -458 l 1225 -458 l +1225 -412 l 1281 -412 l 1281 78 l p ef +pom +gr +10410 12492 m 10410 12142 l 10935 12317 l 10410 12492 l p ef +1 lw 0 lj 8435 12318 m 9685 12318 l 9685 12317 l 10515 12317 l ps +0 lw 1 lj 11434 16817 m 10932 17318 l 10934 16317 l 11434 16817 l pc +10483 16967 m 10483 16667 l 10933 16817 l 10483 16967 l p ef +1 lw 0 lj 8435 16818 m 9684 16818 l 9684 16817 l 10573 16817 l ps +0 lw 1 lj 13085 14818 m 12947 14818 12835 14706 12835 14568 ct 12835 14430 12947 14318 13085 14318 ct +13223 14318 13335 14430 13335 14568 ct 13335 14706 13223 14818 13085 14818 ct +pc +gs +pum +12931 14791 t +133 -183 m 20 -183 l 20 -137 l 133 -137 l 133 0 l 171 0 l 171 -137 l +283 -137 l 283 -183 l 171 -183 l 171 -320 l 133 -320 l 133 -183 l +p ef +pom +gr +13234 15268 m 12934 15268 l 13084 14818 l 13234 15268 l p ef +1 lw 0 lj 11435 16817 m 13084 16817 l 13084 15178 l ps +12934 13868 m 13234 13868 l 13084 14318 l 12934 13868 l p ef +11437 12317 m 13084 12317 l 13084 13958 l ps +0 lw 1 lj 17835 15318 m 16335 15318 l 16335 13818 l 19335 13818 l 19335 15318 l +17835 15318 l pc +16668 15023 m 16778 14801 16891 14569 16925 14316 ct 16997 13766 17307 14273 17221 14551 ct +17165 14731 17523 15058 17694 14622 ct 17856 14213 18050 14912 18286 15000 ct +18489 15075 18680 14999 18878 15000 ct 18878 15000 18878 15000 19076 15047 ct +19076 15047 19076 15047 19135 15118 ct ps +15885 14718 m 15885 14418 l 16335 14568 l 15885 14718 l p ef +1 lw 0 lj 13335 14567 m 14935 14567 l 14935 14568 l 15975 14568 l ps +gs +pum +17085 13052 t +208 -214 m 206 -241 203 -254 195 -269 ct 180 -296 151 -311 114 -311 ct 84 -311 61 -302 46 -283 ct +33 -266 25 -243 25 -219 ct 25 -180 43 -156 78 -146 ct 129 -131 l 170 -120 182 -108 182 -79 ct +182 -46 158 -27 118 -27 ct 90 -27 69 -37 58 -56 ct 51 -68 49 -78 48 -98 ct 16 -98 l +17 -65 22 -48 35 -30 ct 54 -3 78 8 116 8 ct 177 8 214 -26 214 -83 ct 214 -126 195 -154 158 -164 ct +87 -184 l 67 -190 57 -202 57 -224 ct 57 -257 78 -276 114 -276 ct 137 -276 156 -267 166 -250 ct +172 -240 175 -231 176 -214 ct 208 -214 l p ef +319 -39 m 271 -221 l 236 -221 l 304 5 l 300 16 297 25 296 28 ct 289 51 284 57 271 57 ct +265 57 259 55 253 53 ct 253 87 l 255 87 l 261 90 263 90 268 90 ct 304 90 309 83 337 -4 ct +402 -221 l 368 -221 l 319 -39 l p ef +457 -221 m 428 -221 l 428 0 l 458 0 l 458 -120 l 458 -166 477 -194 508 -194 ct +534 -194 546 -176 546 -136 ct 546 0 l 576 0 l 576 -150 l 576 -199 553 -227 515 -227 ct +490 -227 472 -216 457 -188 ct 457 -221 l p ef +690 -190 m 690 -221 l 660 -221 l 660 -282 l 630 -282 l 630 -221 l +605 -221 l 605 -190 l 630 -190 l 630 -44 l 630 -12 641 2 665 2 ct 667 2 669 2 676 1 ct +678 1 683 0 689 0 ct 689 -29 l 679 -29 l 665 -29 660 -34 660 -46 ct 660 -190 l +690 -190 l p ef +751 -303 m 721 -303 l 721 0 l 751 0 l 751 -120 l 751 -167 770 -194 803 -194 ct +828 -194 839 -179 839 -144 ct 839 0 l 869 0 l 869 -150 l 869 -199 846 -227 808 -227 ct +784 -227 769 -218 751 -190 ct 751 -303 l p ef +1038 -69 m 1035 -44 1015 -26 991 -26 ct 973 -26 958 -34 950 -49 ct 942 -61 940 -73 939 -98 ct +1071 -98 l 1070 -142 1066 -162 1056 -184 ct 1042 -214 1022 -227 992 -227 ct +940 -227 906 -180 906 -106 ct 906 -36 938 6 990 6 ct 1032 6 1061 -21 1069 -69 ct +1038 -69 l p +939 -128 m 941 -167 962 -194 991 -194 ct 1007 -194 1020 -186 1028 -173 ct 1035 -162 1038 -151 1040 -128 ct +939 -128 l p ef +1242 -158 m 1240 -202 1215 -227 1174 -227 ct 1132 -227 1104 -200 1104 -157 ct +1104 -129 1118 -111 1146 -103 ct 1182 -92 l 1210 -84 1218 -77 1218 -60 ct 1218 -39 1202 -26 1175 -26 ct +1144 -26 1130 -39 1128 -71 ct 1099 -71 l 1100 -49 1102 -38 1108 -27 ct 1120 -5 1143 6 1173 6 ct +1219 6 1248 -22 1248 -66 ct 1248 -97 1234 -113 1197 -125 ct 1167 -134 l 1140 -142 1134 -148 1134 -163 ct +1134 -183 1148 -195 1172 -195 ct 1198 -195 1211 -183 1213 -158 ct 1242 -158 l +p ef +1315 -221 m 1285 -221 l 1285 0 l 1315 0 l 1315 -221 l p +1315 -261 m 1315 -303 l 1285 -303 l 1285 -261 l 1315 -261 l p ef +1492 -158 m 1490 -202 1465 -227 1424 -227 ct 1382 -227 1354 -200 1354 -157 ct +1354 -129 1368 -111 1396 -103 ct 1432 -92 l 1460 -84 1468 -77 1468 -60 ct 1468 -39 1452 -26 1425 -26 ct +1394 -26 1380 -39 1378 -71 ct 1349 -71 l 1350 -49 1352 -38 1358 -27 ct 1370 -5 1393 6 1423 6 ct +1469 6 1498 -22 1498 -66 ct 1498 -97 1484 -113 1447 -125 ct 1417 -134 l 1390 -142 1384 -148 1384 -163 ct +1384 -183 1398 -195 1422 -195 ct 1448 -195 1461 -183 1463 -158 ct 1492 -158 l +p ef +pom +pum +17085 13581 t +90 -190 m 90 -221 l 60 -221 l 60 -248 l 60 -266 65 -274 78 -274 ct 81 -274 85 -274 90 -273 ct +90 -307 l 81 -307 79 -307 76 -307 ct 46 -307 30 -291 30 -259 ct 30 -221 l 4 -221 l +4 -190 l 30 -190 l 30 0 l 60 0 l 60 -190 l 90 -190 l p ef +150 -221 m 120 -221 l 120 0 l 150 0 l 150 -221 l p +150 -261 m 150 -303 l 120 -303 l 120 -261 l 150 -261 l p ef +227 -303 m 197 -303 l 197 0 l 227 0 l 227 -303 l p ef +339 -190 m 339 -221 l 309 -221 l 309 -282 l 279 -282 l 279 -221 l +254 -221 l 254 -190 l 279 -190 l 279 -44 l 279 -12 290 2 314 2 ct 316 2 318 2 325 1 ct +327 1 332 0 338 0 ct 338 -29 l 328 -29 l 314 -29 309 -34 309 -46 ct 309 -190 l +339 -190 l p ef +492 -69 m 489 -44 469 -26 445 -26 ct 427 -26 412 -34 404 -49 ct 396 -61 394 -73 393 -98 ct +525 -98 l 524 -142 520 -162 510 -184 ct 496 -214 476 -227 446 -227 ct 394 -227 360 -180 360 -106 ct +360 -36 392 6 444 6 ct 486 6 515 -21 523 -69 ct 492 -69 l p +393 -128 m 395 -167 416 -194 445 -194 ct 461 -194 474 -186 482 -173 ct 489 -162 492 -151 494 -128 ct +393 -128 l p ef +657 -188 m 657 -226 l 654 -227 651 -227 649 -227 ct 627 -227 613 -215 597 -183 ct +597 -221 l 568 -221 l 568 0 l 599 0 l 599 -129 l 599 -163 618 -188 645 -188 ct +657 -188 l p ef +878 -297 m 854 -297 l 844 -253 834 -244 789 -240 ct 789 -211 l 845 -211 l +845 0 l 878 0 l 878 -297 l p ef +1050 -311 m 1027 -311 l 943 8 l 965 8 l 1050 -311 l p ef +1211 -88 m 1235 0 l 1272 0 l 1182 -303 l 1144 -303 l 1050 0 l 1085 0 l +1111 -88 l 1211 -88 l p +1121 -125 m 1161 -259 l 1199 -125 l 1121 -125 l p ef +1360 -310 m 1316 -231 1301 -179 1301 -110 ct 1301 -42 1314 1 1361 87 ct 1381 87 l +1343 -5 1334 -42 1334 -107 ct 1334 -182 1344 -225 1381 -310 ct 1360 -310 l p ef +1552 -190 m 1552 -221 l 1412 -221 l 1412 -190 l 1513 -190 l 1403 -29 l +1403 0 l 1555 0 l 1555 -30 l 1444 -30 l 1552 -190 l p ef +1599 87 m 1642 8 1657 -43 1657 -111 ct 1657 -179 1644 -223 1598 -310 ct 1577 -310 l +1616 -217 1625 -179 1625 -115 ct 1625 -40 1615 2 1578 87 ct 1599 87 l p ef +pom +gr +gs +pum +5708 9956 t +63 -137 m 185 -137 l 185 -174 l 63 -174 l 63 -266 l 202 -266 l 202 -303 l +30 -303 l 30 0 l 63 0 l 63 -137 l p ef +265 -221 m 235 -221 l 235 0 l 265 0 l 265 -221 l p +265 -261 m 265 -303 l 235 -303 l 235 -261 l 265 -261 l p ef +394 -113 m 455 -221 l 418 -221 l 375 -143 l 334 -221 l 294 -221 l +355 -113 l 291 0 l 330 0 l 373 -83 l 419 0 l 458 0 l 394 -113 l +p ef +606 -69 m 603 -44 583 -26 559 -26 ct 541 -26 526 -34 518 -49 ct 510 -61 508 -73 507 -98 ct +639 -98 l 638 -142 634 -162 624 -184 ct 610 -214 590 -227 560 -227 ct 508 -227 474 -180 474 -106 ct +474 -36 506 6 558 6 ct 600 6 629 -21 637 -69 ct 606 -69 l p +507 -128 m 509 -167 530 -194 559 -194 ct 575 -194 588 -186 596 -173 ct 603 -162 606 -151 608 -128 ct +507 -128 l p ef +829 -303 m 798 -303 l 798 -187 l 784 -216 768 -227 743 -227 ct 698 -227 668 -182 668 -115 ct +668 -41 699 6 747 6 ct 772 6 787 -4 800 -31 ct 800 0 l 829 0 l 829 -303 l +p +749 -194 m 780 -194 798 -162 798 -104 ct 798 -76 793 -57 782 -43 ct 773 -32 761 -26 748 -26 ct +717 -26 699 -58 699 -113 ct 699 -167 716 -194 749 -194 ct p ef +1113 -146 m 1107 -200 1085 -227 1044 -227 ct 991 -227 958 -180 958 -106 ct +958 -37 990 6 1039 6 ct 1081 6 1106 -22 1113 -78 ct 1083 -78 l 1077 -43 1062 -26 1039 -26 ct +1008 -26 991 -56 991 -109 ct 991 -163 1009 -194 1041 -194 ct 1065 -194 1078 -180 1083 -146 ct +1113 -146 l p ef +1219 -227 m 1168 -227 1134 -180 1134 -110 ct 1134 -41 1168 5 1218 5 ct 1268 5 1302 -41 1302 -110 ct +1302 -178 1268 -227 1219 -227 ct p +1219 -195 m 1250 -195 1270 -161 1270 -110 ct 1270 -59 1250 -26 1218 -26 ct +1186 -26 1165 -59 1165 -110 ct 1165 -162 1186 -195 1219 -195 ct p ef +1490 -303 m 1459 -303 l 1459 -187 l 1445 -216 1429 -227 1404 -227 ct 1359 -227 1329 -182 1329 -115 ct +1329 -41 1360 6 1408 6 ct 1433 6 1448 -4 1461 -31 ct 1461 0 l 1490 0 l 1490 -303 l +p +1410 -194 m 1441 -194 1459 -162 1459 -104 ct 1459 -76 1454 -57 1443 -43 ct +1434 -32 1422 -26 1409 -26 ct 1378 -26 1360 -58 1360 -113 ct 1360 -167 1377 -194 1410 -194 ct +p ef +1656 -69 m 1653 -44 1633 -26 1609 -26 ct 1591 -26 1576 -34 1568 -49 ct 1560 -61 1558 -73 1557 -98 ct +1689 -98 l 1688 -142 1684 -162 1674 -184 ct 1660 -214 1640 -227 1610 -227 ct +1558 -227 1524 -180 1524 -106 ct 1524 -36 1556 6 1608 6 ct 1650 6 1679 -21 1687 -69 ct +1656 -69 l p +1557 -128 m 1559 -167 1580 -194 1609 -194 ct 1625 -194 1638 -186 1646 -173 ct +1653 -162 1656 -151 1658 -128 ct 1557 -128 l p ef +1755 0 m 1755 -28 l 1768 -3 1782 6 1806 6 ct 1854 6 1885 -41 1885 -115 ct +1885 -182 1855 -227 1810 -227 ct 1788 -227 1772 -217 1756 -192 ct 1756 -303 l +1726 -303 l 1726 0 l 1755 0 l p +1805 -194 m 1837 -194 1853 -167 1853 -113 ct 1853 -58 1835 -26 1804 -26 ct +1792 -26 1780 -32 1771 -43 ct 1760 -57 1755 -76 1755 -105 ct 1755 -163 1772 -194 1805 -194 ct +p ef +1998 -227 m 1947 -227 1913 -180 1913 -110 ct 1913 -41 1947 5 1997 5 ct 2047 5 2081 -41 2081 -110 ct +2081 -178 2047 -227 1998 -227 ct p +1998 -195 m 2029 -195 2049 -161 2049 -110 ct 2049 -59 2029 -26 1997 -26 ct +1965 -26 1944 -59 1944 -110 ct 1944 -162 1965 -195 1998 -195 ct p ef +2193 -227 m 2142 -227 2108 -180 2108 -110 ct 2108 -41 2142 5 2192 5 ct 2242 5 2276 -41 2276 -110 ct +2276 -178 2242 -227 2193 -227 ct p +2193 -195 m 2224 -195 2244 -161 2244 -110 ct 2244 -59 2224 -26 2192 -26 ct +2160 -26 2139 -59 2139 -110 ct 2139 -162 2160 -195 2193 -195 ct p ef +2390 -138 m 2459 -221 l 2421 -221 l 2342 -127 l 2342 -303 l 2313 -303 l +2313 0 l 2342 0 l 2342 -83 l 2368 -111 l 2424 0 l 2463 0 l 2390 -138 l +p ef +pom +gr +gs +pum +5390 15539 t +165 -88 m 189 0 l 226 0 l 136 -303 l 98 -303 l 4 0 l 39 0 l 65 -88 l +165 -88 l p +75 -125 m 115 -259 l 153 -125 l 75 -125 l p ef +406 -303 m 375 -303 l 375 -187 l 361 -216 345 -227 320 -227 ct 275 -227 245 -182 245 -115 ct +245 -41 276 6 324 6 ct 349 6 364 -4 377 -31 ct 377 0 l 406 0 l 406 -303 l +p +326 -194 m 357 -194 375 -162 375 -104 ct 375 -76 370 -57 359 -43 ct 350 -32 338 -26 325 -26 ct +294 -26 276 -58 276 -113 ct 276 -167 293 -194 326 -194 ct p ef +477 -153 m 481 -184 493 -196 520 -196 ct 547 -196 562 -184 562 -159 ct 562 -143 557 -136 546 -134 ct +495 -126 l 460 -121 440 -96 440 -58 ct 440 -19 463 6 498 6 ct 524 6 543 -4 562 -29 ct +565 -5 573 4 594 4 ct 598 4 602 3 608 1 ct 610 0 610 0 612 0 ct 612 -27 l 605 -25 603 -25 601 -25 ct +595 -25 591 -30 591 -38 ct 591 -165 l 591 -204 565 -227 522 -227 ct 493 -227 472 -217 460 -198 ct +453 -186 450 -175 449 -153 ct 477 -153 l p +561 -76 m 561 -48 535 -24 504 -24 ct 484 -24 472 -38 472 -61 ct 472 -83 483 -94 511 -98 ct +546 -104 554 -107 561 -112 ct 561 -76 l p ef +642 87 m 672 87 l 672 -24 l 685 -2 699 6 722 6 ct 770 6 801 -42 801 -115 ct +801 -182 771 -227 726 -227 ct 701 -227 687 -217 671 -188 ct 671 -221 l 642 -221 l +642 87 l p +721 -194 m 752 -194 769 -166 769 -114 ct 769 -58 751 -26 720 -26 ct 690 -26 671 -55 671 -103 ct +671 -163 688 -194 721 -194 ct p ef +906 -190 m 906 -221 l 876 -221 l 876 -282 l 846 -282 l 846 -221 l +821 -221 l 821 -190 l 846 -190 l 846 -44 l 846 -12 857 2 881 2 ct 883 2 885 2 892 1 ct +894 1 899 0 905 0 ct 905 -29 l 895 -29 l 881 -29 876 -34 876 -46 ct 876 -190 l +906 -190 l p ef +967 -221 m 937 -221 l 937 0 l 967 0 l 967 -221 l p +967 -261 m 967 -303 l 937 -303 l 937 -261 l 967 -261 l p ef +1076 -39 m 1029 -221 l 993 -221 l 1059 0 l 1092 0 l 1161 -221 l 1128 -221 l +1076 -39 l p ef +1309 -69 m 1306 -44 1286 -26 1262 -26 ct 1244 -26 1229 -34 1221 -49 ct 1213 -61 1211 -73 1210 -98 ct +1342 -98 l 1341 -142 1337 -162 1327 -184 ct 1313 -214 1293 -227 1263 -227 ct +1211 -227 1177 -180 1177 -106 ct 1177 -36 1209 6 1261 6 ct 1303 6 1332 -21 1340 -69 ct +1309 -69 l p +1210 -128 m 1212 -167 1233 -194 1262 -194 ct 1278 -194 1291 -186 1299 -173 ct +1306 -162 1309 -151 1311 -128 ct 1210 -128 l p ef +1621 -146 m 1615 -200 1593 -227 1552 -227 ct 1499 -227 1466 -180 1466 -106 ct +1466 -37 1498 6 1547 6 ct 1589 6 1614 -22 1621 -78 ct 1591 -78 l 1585 -43 1570 -26 1547 -26 ct +1516 -26 1499 -56 1499 -109 ct 1499 -163 1517 -194 1549 -194 ct 1573 -194 1586 -180 1591 -146 ct +1621 -146 l p ef +1727 -227 m 1676 -227 1642 -180 1642 -110 ct 1642 -41 1676 5 1726 5 ct 1776 5 1810 -41 1810 -110 ct +1810 -178 1776 -227 1727 -227 ct p +1727 -195 m 1758 -195 1778 -161 1778 -110 ct 1778 -59 1758 -26 1726 -26 ct +1694 -26 1673 -59 1673 -110 ct 1673 -162 1694 -195 1727 -195 ct p ef +1998 -303 m 1967 -303 l 1967 -187 l 1953 -216 1937 -227 1912 -227 ct 1867 -227 1837 -182 1837 -115 ct +1837 -41 1868 6 1916 6 ct 1941 6 1956 -4 1969 -31 ct 1969 0 l 1998 0 l 1998 -303 l +p +1918 -194 m 1949 -194 1967 -162 1967 -104 ct 1967 -76 1962 -57 1951 -43 ct +1942 -32 1930 -26 1917 -26 ct 1886 -26 1868 -58 1868 -113 ct 1868 -167 1885 -194 1918 -194 ct +p ef +2164 -69 m 2161 -44 2141 -26 2117 -26 ct 2099 -26 2084 -34 2076 -49 ct 2068 -61 2066 -73 2065 -98 ct +2197 -98 l 2196 -142 2192 -162 2182 -184 ct 2168 -214 2148 -227 2118 -227 ct +2066 -227 2032 -180 2032 -106 ct 2032 -36 2064 6 2116 6 ct 2158 6 2187 -21 2195 -69 ct +2164 -69 l p +2065 -128 m 2067 -167 2088 -194 2117 -194 ct 2133 -194 2146 -186 2154 -173 ct +2161 -162 2164 -151 2166 -128 ct 2065 -128 l p ef +2263 0 m 2263 -28 l 2276 -3 2290 6 2314 6 ct 2362 6 2393 -41 2393 -115 ct +2393 -182 2363 -227 2318 -227 ct 2296 -227 2280 -217 2264 -192 ct 2264 -303 l +2234 -303 l 2234 0 l 2263 0 l p +2313 -194 m 2345 -194 2361 -167 2361 -113 ct 2361 -58 2343 -26 2312 -26 ct +2300 -26 2288 -32 2279 -43 ct 2268 -57 2263 -76 2263 -105 ct 2263 -163 2280 -194 2313 -194 ct +p ef +2506 -227 m 2455 -227 2421 -180 2421 -110 ct 2421 -41 2455 5 2505 5 ct 2555 5 2589 -41 2589 -110 ct +2589 -178 2555 -227 2506 -227 ct p +2506 -195 m 2537 -195 2557 -161 2557 -110 ct 2557 -59 2537 -26 2505 -26 ct +2473 -26 2452 -59 2452 -110 ct 2452 -162 2473 -195 2506 -195 ct p ef +2701 -227 m 2650 -227 2616 -180 2616 -110 ct 2616 -41 2650 5 2700 5 ct 2750 5 2784 -41 2784 -110 ct +2784 -178 2750 -227 2701 -227 ct p +2701 -195 m 2732 -195 2752 -161 2752 -110 ct 2752 -59 2732 -26 2700 -26 ct +2668 -26 2647 -59 2647 -110 ct 2647 -162 2668 -195 2701 -195 ct p ef +2898 -138 m 2967 -221 l 2929 -221 l 2850 -127 l 2850 -303 l 2821 -303 l +2821 0 l 2850 0 l 2850 -83 l 2876 -111 l 2932 0 l 2971 0 l 2898 -138 l +p ef +pom +gr +gs +pum +14016 13846 t +213 -36 m 63 -36 l 63 -137 l 199 -137 l 199 -174 l 63 -174 l 63 -266 l +211 -266 l 211 -303 l 30 -303 l 30 0 l 213 0 l 213 -36 l p ef +339 -113 m 400 -221 l 363 -221 l 320 -143 l 279 -221 l 239 -221 l +300 -113 l 236 0 l 275 0 l 318 -83 l 364 0 l 403 0 l 339 -113 l +p ef +571 -146 m 565 -200 543 -227 502 -227 ct 449 -227 416 -180 416 -106 ct 416 -37 448 6 497 6 ct +539 6 564 -22 571 -78 ct 541 -78 l 535 -43 520 -26 497 -26 ct 466 -26 449 -56 449 -109 ct +449 -163 467 -194 499 -194 ct 523 -194 536 -180 541 -146 ct 571 -146 l p ef +633 -221 m 603 -221 l 603 0 l 633 0 l 633 -221 l p +633 -261 m 633 -303 l 603 -303 l 603 -261 l 633 -261 l p ef +745 -190 m 745 -221 l 715 -221 l 715 -282 l 685 -282 l 685 -221 l +660 -221 l 660 -190 l 685 -190 l 685 -44 l 685 -12 696 2 720 2 ct 722 2 724 2 731 1 ct +733 1 738 0 744 0 ct 744 -29 l 734 -29 l 720 -29 715 -34 715 -46 ct 715 -190 l +745 -190 l p ef +803 -153 m 807 -184 819 -196 846 -196 ct 873 -196 888 -184 888 -159 ct 888 -143 883 -136 872 -134 ct +821 -126 l 786 -121 766 -96 766 -58 ct 766 -19 789 6 824 6 ct 850 6 869 -4 888 -29 ct +891 -5 899 4 920 4 ct 924 4 928 3 934 1 ct 936 0 936 0 938 0 ct 938 -27 l 931 -25 929 -25 927 -25 ct +921 -25 917 -30 917 -38 ct 917 -165 l 917 -204 891 -227 848 -227 ct 819 -227 798 -217 786 -198 ct +779 -186 776 -175 775 -153 ct 803 -153 l p +887 -76 m 887 -48 861 -24 830 -24 ct 810 -24 798 -38 798 -61 ct 798 -83 809 -94 837 -98 ct +872 -104 880 -107 887 -112 ct 887 -76 l p ef +1037 -190 m 1037 -221 l 1007 -221 l 1007 -282 l 977 -282 l 977 -221 l +952 -221 l 952 -190 l 977 -190 l 977 -44 l 977 -12 988 2 1012 2 ct 1014 2 1016 2 1023 1 ct +1025 1 1030 0 1036 0 ct 1036 -29 l 1026 -29 l 1012 -29 1007 -34 1007 -46 ct +1007 -190 l 1037 -190 l p ef +1099 -221 m 1069 -221 l 1069 0 l 1099 0 l 1099 -221 l p +1099 -261 m 1099 -303 l 1069 -303 l 1069 -261 l 1099 -261 l p ef +1219 -227 m 1168 -227 1134 -180 1134 -110 ct 1134 -41 1168 5 1218 5 ct 1268 5 1302 -41 1302 -110 ct +1302 -178 1268 -227 1219 -227 ct p +1219 -195 m 1250 -195 1270 -161 1270 -110 ct 1270 -59 1250 -26 1218 -26 ct +1186 -26 1165 -59 1165 -110 ct 1165 -162 1186 -195 1219 -195 ct p ef +1368 -221 m 1339 -221 l 1339 0 l 1369 0 l 1369 -120 l 1369 -166 1388 -194 1419 -194 ct +1445 -194 1457 -176 1457 -136 ct 1457 0 l 1487 0 l 1487 -150 l 1487 -199 1464 -227 1426 -227 ct +1401 -227 1383 -216 1368 -188 ct 1368 -221 l p ef +pom +pum +14480 14375 t +145 -69 m 142 -44 122 -26 98 -26 ct 80 -26 65 -34 57 -49 ct 49 -61 47 -73 46 -98 ct +178 -98 l 177 -142 173 -162 163 -184 ct 149 -214 129 -227 99 -227 ct 47 -227 13 -180 13 -106 ct +13 -36 45 6 97 6 ct 139 6 168 -21 176 -69 ct 145 -69 l p +46 -128 m 48 -167 69 -194 98 -194 ct 114 -194 127 -186 135 -173 ct 142 -162 145 -151 147 -128 ct +46 -128 l p ef +244 -274 m 281 -274 l 281 -305 l 217 -305 l 217 82 l 281 82 l 281 52 l +244 52 l 244 -274 l p ef +343 -221 m 314 -221 l 314 0 l 344 0 l 344 -120 l 344 -166 363 -194 394 -194 ct +420 -194 432 -176 432 -136 ct 432 0 l 462 0 l 462 -150 l 462 -199 439 -227 401 -227 ct +376 -227 358 -216 343 -188 ct 343 -221 l p ef +533 52 m 496 52 l 496 82 l 561 82 l 561 -305 l 496 -305 l 496 -274 l +533 -274 l 533 52 l p ef +pom +gr +gs +pum +9491 13237 t +63 -137 m 185 -137 l 185 -174 l 63 -174 l 63 -266 l 202 -266 l 202 -303 l +30 -303 l 30 0 l 63 0 l 63 -137 l p ef +265 -221 m 235 -221 l 235 0 l 265 0 l 265 -221 l p +265 -261 m 265 -303 l 235 -303 l 235 -261 l 265 -261 l p ef +394 -113 m 455 -221 l 418 -221 l 375 -143 l 334 -221 l 294 -221 l +355 -113 l 291 0 l 330 0 l 373 -83 l 419 0 l 458 0 l 394 -113 l +p ef +606 -69 m 603 -44 583 -26 559 -26 ct 541 -26 526 -34 518 -49 ct 510 -61 508 -73 507 -98 ct +639 -98 l 638 -142 634 -162 624 -184 ct 610 -214 590 -227 560 -227 ct 508 -227 474 -180 474 -106 ct +474 -36 506 6 558 6 ct 600 6 629 -21 637 -69 ct 606 -69 l p +507 -128 m 509 -167 530 -194 559 -194 ct 575 -194 588 -186 596 -173 ct 603 -162 606 -151 608 -128 ct +507 -128 l p ef +829 -303 m 798 -303 l 798 -187 l 784 -216 768 -227 743 -227 ct 698 -227 668 -182 668 -115 ct +668 -41 699 6 747 6 ct 772 6 787 -4 800 -31 ct 800 0 l 829 0 l 829 -303 l +p +749 -194 m 780 -194 798 -162 798 -104 ct 798 -76 793 -57 782 -43 ct 773 -32 761 -26 748 -26 ct +717 -26 699 -58 699 -113 ct 699 -167 716 -194 749 -194 ct p ef +1113 -146 m 1107 -200 1085 -227 1044 -227 ct 991 -227 958 -180 958 -106 ct +958 -37 990 6 1039 6 ct 1081 6 1106 -22 1113 -78 ct 1083 -78 l 1077 -43 1062 -26 1039 -26 ct +1008 -26 991 -56 991 -109 ct 991 -163 1009 -194 1041 -194 ct 1065 -194 1078 -180 1083 -146 ct +1113 -146 l p ef +1219 -227 m 1168 -227 1134 -180 1134 -110 ct 1134 -41 1168 5 1218 5 ct 1268 5 1302 -41 1302 -110 ct +1302 -178 1268 -227 1219 -227 ct p +1219 -195 m 1250 -195 1270 -161 1270 -110 ct 1270 -59 1250 -26 1218 -26 ct +1186 -26 1165 -59 1165 -110 ct 1165 -162 1186 -195 1219 -195 ct p ef +1490 -303 m 1459 -303 l 1459 -187 l 1445 -216 1429 -227 1404 -227 ct 1359 -227 1329 -182 1329 -115 ct +1329 -41 1360 6 1408 6 ct 1433 6 1448 -4 1461 -31 ct 1461 0 l 1490 0 l 1490 -303 l +p +1410 -194 m 1441 -194 1459 -162 1459 -104 ct 1459 -76 1454 -57 1443 -43 ct +1434 -32 1422 -26 1409 -26 ct 1378 -26 1360 -58 1360 -113 ct 1360 -167 1377 -194 1410 -194 ct +p ef +1656 -69 m 1653 -44 1633 -26 1609 -26 ct 1591 -26 1576 -34 1568 -49 ct 1560 -61 1558 -73 1557 -98 ct +1689 -98 l 1688 -142 1684 -162 1674 -184 ct 1660 -214 1640 -227 1610 -227 ct +1558 -227 1524 -180 1524 -106 ct 1524 -36 1556 6 1608 6 ct 1650 6 1679 -21 1687 -69 ct +1656 -69 l p +1557 -128 m 1559 -167 1580 -194 1609 -194 ct 1625 -194 1638 -186 1646 -173 ct +1653 -162 1656 -151 1658 -128 ct 1557 -128 l p ef +1755 0 m 1755 -28 l 1768 -3 1782 6 1806 6 ct 1854 6 1885 -41 1885 -115 ct +1885 -182 1855 -227 1810 -227 ct 1788 -227 1772 -217 1756 -192 ct 1756 -303 l +1726 -303 l 1726 0 l 1755 0 l p +1805 -194 m 1837 -194 1853 -167 1853 -113 ct 1853 -58 1835 -26 1804 -26 ct +1792 -26 1780 -32 1771 -43 ct 1760 -57 1755 -76 1755 -105 ct 1755 -163 1772 -194 1805 -194 ct +p ef +1998 -227 m 1947 -227 1913 -180 1913 -110 ct 1913 -41 1947 5 1997 5 ct 2047 5 2081 -41 2081 -110 ct +2081 -178 2047 -227 1998 -227 ct p +1998 -195 m 2029 -195 2049 -161 2049 -110 ct 2049 -59 2029 -26 1997 -26 ct +1965 -26 1944 -59 1944 -110 ct 1944 -162 1965 -195 1998 -195 ct p ef +2193 -227 m 2142 -227 2108 -180 2108 -110 ct 2108 -41 2142 5 2192 5 ct 2242 5 2276 -41 2276 -110 ct +2276 -178 2242 -227 2193 -227 ct p +2193 -195 m 2224 -195 2244 -161 2244 -110 ct 2244 -59 2224 -26 2192 -26 ct +2160 -26 2139 -59 2139 -110 ct 2139 -162 2160 -195 2193 -195 ct p ef +2390 -138 m 2459 -221 l 2421 -221 l 2342 -127 l 2342 -303 l 2313 -303 l +2313 0 l 2342 0 l 2342 -83 l 2368 -111 l 2424 0 l 2463 0 l 2390 -138 l +p ef +2734 -221 m 2705 -221 l 2705 -188 l 2688 -217 2674 -227 2649 -227 ct 2604 -227 2574 -182 2574 -115 ct +2574 -42 2606 6 2654 6 ct 2676 6 2691 -2 2703 -24 ct 2703 -15 l 2703 11 2701 25 2695 37 ct +2687 54 2673 62 2651 62 ct 2628 62 2616 52 2610 27 ct 2580 27 l 2585 55 2591 68 2605 79 ct +2617 88 2632 93 2650 93 ct 2681 93 2705 80 2719 57 ct 2729 39 2734 17 2734 -18 ct +2734 -221 l p +2656 -194 m 2687 -194 2704 -162 2704 -104 ct 2704 -55 2686 -26 2654 -26 ct +2624 -26 2606 -58 2606 -113 ct 2606 -167 2623 -194 2656 -194 ct p ef +2805 -153 m 2809 -184 2821 -196 2848 -196 ct 2875 -196 2890 -184 2890 -159 ct +2890 -143 2885 -136 2874 -134 ct 2823 -126 l 2788 -121 2768 -96 2768 -58 ct +2768 -19 2791 6 2826 6 ct 2852 6 2871 -4 2890 -29 ct 2893 -5 2901 4 2922 4 ct 2926 4 2930 3 2936 1 ct +2938 0 2938 0 2940 0 ct 2940 -27 l 2933 -25 2931 -25 2929 -25 ct 2923 -25 2919 -30 2919 -38 ct +2919 -165 l 2919 -204 2893 -227 2850 -227 ct 2821 -227 2800 -217 2788 -198 ct +2781 -186 2778 -175 2777 -153 ct 2805 -153 l p +2889 -76 m 2889 -48 2863 -24 2832 -24 ct 2812 -24 2800 -38 2800 -61 ct 2800 -83 2811 -94 2839 -98 ct +2874 -104 2882 -107 2889 -112 ct 2889 -76 l p ef +3004 -221 m 2974 -221 l 2974 0 l 3004 0 l 3004 -221 l p +3004 -261 m 3004 -303 l 2974 -303 l 2974 -261 l 3004 -261 l p ef +3078 -221 m 3049 -221 l 3049 0 l 3079 0 l 3079 -120 l 3079 -166 3098 -194 3129 -194 ct +3155 -194 3167 -176 3167 -136 ct 3167 0 l 3197 0 l 3197 -150 l 3197 -199 3174 -227 3136 -227 ct +3111 -227 3093 -216 3078 -188 ct 3078 -221 l p ef +pom +gr +gs +pum +9174 17762 t +165 -88 m 189 0 l 226 0 l 136 -303 l 98 -303 l 4 0 l 39 0 l 65 -88 l +165 -88 l p +75 -125 m 115 -259 l 153 -125 l 75 -125 l p ef +406 -303 m 375 -303 l 375 -187 l 361 -216 345 -227 320 -227 ct 275 -227 245 -182 245 -115 ct +245 -41 276 6 324 6 ct 349 6 364 -4 377 -31 ct 377 0 l 406 0 l 406 -303 l +p +326 -194 m 357 -194 375 -162 375 -104 ct 375 -76 370 -57 359 -43 ct 350 -32 338 -26 325 -26 ct +294 -26 276 -58 276 -113 ct 276 -167 293 -194 326 -194 ct p ef +477 -153 m 481 -184 493 -196 520 -196 ct 547 -196 562 -184 562 -159 ct 562 -143 557 -136 546 -134 ct +495 -126 l 460 -121 440 -96 440 -58 ct 440 -19 463 6 498 6 ct 524 6 543 -4 562 -29 ct +565 -5 573 4 594 4 ct 598 4 602 3 608 1 ct 610 0 610 0 612 0 ct 612 -27 l 605 -25 603 -25 601 -25 ct +595 -25 591 -30 591 -38 ct 591 -165 l 591 -204 565 -227 522 -227 ct 493 -227 472 -217 460 -198 ct +453 -186 450 -175 449 -153 ct 477 -153 l p +561 -76 m 561 -48 535 -24 504 -24 ct 484 -24 472 -38 472 -61 ct 472 -83 483 -94 511 -98 ct +546 -104 554 -107 561 -112 ct 561 -76 l p ef +642 87 m 672 87 l 672 -24 l 685 -2 699 6 722 6 ct 770 6 801 -42 801 -115 ct +801 -182 771 -227 726 -227 ct 701 -227 687 -217 671 -188 ct 671 -221 l 642 -221 l +642 87 l p +721 -194 m 752 -194 769 -166 769 -114 ct 769 -58 751 -26 720 -26 ct 690 -26 671 -55 671 -103 ct +671 -163 688 -194 721 -194 ct p ef +906 -190 m 906 -221 l 876 -221 l 876 -282 l 846 -282 l 846 -221 l +821 -221 l 821 -190 l 846 -190 l 846 -44 l 846 -12 857 2 881 2 ct 883 2 885 2 892 1 ct +894 1 899 0 905 0 ct 905 -29 l 895 -29 l 881 -29 876 -34 876 -46 ct 876 -190 l +906 -190 l p ef +967 -221 m 937 -221 l 937 0 l 967 0 l 967 -221 l p +967 -261 m 967 -303 l 937 -303 l 937 -261 l 967 -261 l p ef +1076 -39 m 1029 -221 l 993 -221 l 1059 0 l 1092 0 l 1161 -221 l 1128 -221 l +1076 -39 l p ef +1309 -69 m 1306 -44 1286 -26 1262 -26 ct 1244 -26 1229 -34 1221 -49 ct 1213 -61 1211 -73 1210 -98 ct +1342 -98 l 1341 -142 1337 -162 1327 -184 ct 1313 -214 1293 -227 1263 -227 ct +1211 -227 1177 -180 1177 -106 ct 1177 -36 1209 6 1261 6 ct 1303 6 1332 -21 1340 -69 ct +1309 -69 l p +1210 -128 m 1212 -167 1233 -194 1262 -194 ct 1278 -194 1291 -186 1299 -173 ct +1306 -162 1309 -151 1311 -128 ct 1210 -128 l p ef +1621 -146 m 1615 -200 1593 -227 1552 -227 ct 1499 -227 1466 -180 1466 -106 ct +1466 -37 1498 6 1547 6 ct 1589 6 1614 -22 1621 -78 ct 1591 -78 l 1585 -43 1570 -26 1547 -26 ct +1516 -26 1499 -56 1499 -109 ct 1499 -163 1517 -194 1549 -194 ct 1573 -194 1586 -180 1591 -146 ct +1621 -146 l p ef +1727 -227 m 1676 -227 1642 -180 1642 -110 ct 1642 -41 1676 5 1726 5 ct 1776 5 1810 -41 1810 -110 ct +1810 -178 1776 -227 1727 -227 ct p +1727 -195 m 1758 -195 1778 -161 1778 -110 ct 1778 -59 1758 -26 1726 -26 ct +1694 -26 1673 -59 1673 -110 ct 1673 -162 1694 -195 1727 -195 ct p ef +1998 -303 m 1967 -303 l 1967 -187 l 1953 -216 1937 -227 1912 -227 ct 1867 -227 1837 -182 1837 -115 ct +1837 -41 1868 6 1916 6 ct 1941 6 1956 -4 1969 -31 ct 1969 0 l 1998 0 l 1998 -303 l +p +1918 -194 m 1949 -194 1967 -162 1967 -104 ct 1967 -76 1962 -57 1951 -43 ct +1942 -32 1930 -26 1917 -26 ct 1886 -26 1868 -58 1868 -113 ct 1868 -167 1885 -194 1918 -194 ct +p ef +2164 -69 m 2161 -44 2141 -26 2117 -26 ct 2099 -26 2084 -34 2076 -49 ct 2068 -61 2066 -73 2065 -98 ct +2197 -98 l 2196 -142 2192 -162 2182 -184 ct 2168 -214 2148 -227 2118 -227 ct +2066 -227 2032 -180 2032 -106 ct 2032 -36 2064 6 2116 6 ct 2158 6 2187 -21 2195 -69 ct +2164 -69 l p +2065 -128 m 2067 -167 2088 -194 2117 -194 ct 2133 -194 2146 -186 2154 -173 ct +2161 -162 2164 -151 2166 -128 ct 2065 -128 l p ef +2263 0 m 2263 -28 l 2276 -3 2290 6 2314 6 ct 2362 6 2393 -41 2393 -115 ct +2393 -182 2363 -227 2318 -227 ct 2296 -227 2280 -217 2264 -192 ct 2264 -303 l +2234 -303 l 2234 0 l 2263 0 l p +2313 -194 m 2345 -194 2361 -167 2361 -113 ct 2361 -58 2343 -26 2312 -26 ct +2300 -26 2288 -32 2279 -43 ct 2268 -57 2263 -76 2263 -105 ct 2263 -163 2280 -194 2313 -194 ct +p ef +2506 -227 m 2455 -227 2421 -180 2421 -110 ct 2421 -41 2455 5 2505 5 ct 2555 5 2589 -41 2589 -110 ct +2589 -178 2555 -227 2506 -227 ct p +2506 -195 m 2537 -195 2557 -161 2557 -110 ct 2557 -59 2537 -26 2505 -26 ct +2473 -26 2452 -59 2452 -110 ct 2452 -162 2473 -195 2506 -195 ct p ef +2701 -227 m 2650 -227 2616 -180 2616 -110 ct 2616 -41 2650 5 2700 5 ct 2750 5 2784 -41 2784 -110 ct +2784 -178 2750 -227 2701 -227 ct p +2701 -195 m 2732 -195 2752 -161 2752 -110 ct 2752 -59 2732 -26 2700 -26 ct +2668 -26 2647 -59 2647 -110 ct 2647 -162 2668 -195 2701 -195 ct p ef +2898 -138 m 2967 -221 l 2929 -221 l 2850 -127 l 2850 -303 l 2821 -303 l +2821 0 l 2850 0 l 2850 -83 l 2876 -111 l 2932 0 l 2971 0 l 2898 -138 l +p ef +3242 -221 m 3213 -221 l 3213 -188 l 3196 -217 3182 -227 3157 -227 ct 3112 -227 3082 -182 3082 -115 ct +3082 -42 3114 6 3162 6 ct 3184 6 3199 -2 3211 -24 ct 3211 -15 l 3211 11 3209 25 3203 37 ct +3195 54 3181 62 3159 62 ct 3136 62 3124 52 3118 27 ct 3088 27 l 3093 55 3099 68 3113 79 ct +3125 88 3140 93 3158 93 ct 3189 93 3213 80 3227 57 ct 3237 39 3242 17 3242 -18 ct +3242 -221 l p +3164 -194 m 3195 -194 3212 -162 3212 -104 ct 3212 -55 3194 -26 3162 -26 ct +3132 -26 3114 -58 3114 -113 ct 3114 -167 3131 -194 3164 -194 ct p ef +3313 -153 m 3317 -184 3329 -196 3356 -196 ct 3383 -196 3398 -184 3398 -159 ct +3398 -143 3393 -136 3382 -134 ct 3331 -126 l 3296 -121 3276 -96 3276 -58 ct +3276 -19 3299 6 3334 6 ct 3360 6 3379 -4 3398 -29 ct 3401 -5 3409 4 3430 4 ct 3434 4 3438 3 3444 1 ct +3446 0 3446 0 3448 0 ct 3448 -27 l 3441 -25 3439 -25 3437 -25 ct 3431 -25 3427 -30 3427 -38 ct +3427 -165 l 3427 -204 3401 -227 3358 -227 ct 3329 -227 3308 -217 3296 -198 ct +3289 -186 3286 -175 3285 -153 ct 3313 -153 l p +3397 -76 m 3397 -48 3371 -24 3340 -24 ct 3320 -24 3308 -38 3308 -61 ct 3308 -83 3319 -94 3347 -98 ct +3382 -104 3390 -107 3397 -112 ct 3397 -76 l p ef +3512 -221 m 3482 -221 l 3482 0 l 3512 0 l 3512 -221 l p +3512 -261 m 3512 -303 l 3482 -303 l 3482 -261 l 3512 -261 l p ef +3586 -221 m 3557 -221 l 3557 0 l 3587 0 l 3587 -120 l 3587 -166 3606 -194 3637 -194 ct +3663 -194 3675 -176 3675 -136 ct 3675 0 l 3705 0 l 3705 -150 l 3705 -199 3682 -227 3644 -227 ct +3619 -227 3601 -216 3586 -188 ct 3586 -221 l p ef +pom +gr +0 lw 1 lj 11185 19818 m 9435 19818 l 9435 18318 l 12935 18318 l 12935 19818 l +11185 19818 l pc +gs +pum +10523 19288 t +41 0 m 191 0 l 234 0 272 -17 297 -48 ct 332 -92 351 -157 351 -233 ct 351 -368 289 -455 193 -455 ct +41 -455 l 41 0 l p +92 -403 m 187 -403 l 259 -403 299 -341 299 -227 ct 299 -119 257 -52 190 -52 ct +92 -52 l 92 -403 l p ef +596 -104 m 591 -66 561 -39 524 -39 ct 497 -39 476 -51 462 -74 ct 451 -92 448 -110 446 -147 ct +645 -147 l 643 -213 637 -244 622 -277 ct 601 -321 570 -341 526 -341 ct 448 -341 397 -271 397 -160 ct +397 -55 445 9 523 9 ct 585 9 629 -32 641 -104 ct 596 -104 l p +446 -192 m 449 -252 481 -292 524 -292 ct 548 -292 568 -280 580 -260 ct 591 -243 595 -226 597 -192 ct +446 -192 l p ef +745 -455 m 699 -455 l 699 0 l 745 0 l 745 -455 l p ef +853 -231 m 859 -277 877 -295 917 -295 ct 958 -295 980 -276 980 -240 ct 980 -215 973 -204 956 -201 ct +880 -190 l 827 -182 798 -145 798 -87 ct 798 -29 832 9 885 9 ct 923 9 951 -6 981 -44 ct +984 -8 997 6 1028 6 ct 1035 6 1040 5 1049 1 ct 1052 0 1053 0 1055 0 ct 1055 -40 l +1045 -38 1043 -38 1039 -38 ct 1029 -38 1024 -45 1024 -57 ct 1024 -248 l 1024 -306 985 -341 920 -341 ct +878 -341 845 -326 827 -297 ct 817 -280 813 -264 811 -231 ct 853 -231 l p +979 -114 m 979 -73 940 -36 894 -36 ct 863 -36 845 -57 845 -92 ct 845 -125 862 -141 904 -148 ct +956 -157 969 -160 979 -169 ct 979 -114 l p ef +1197 -59 m 1124 -332 l 1072 -332 l 1173 8 l 1168 24 1164 38 1162 43 ct +1152 76 1144 85 1125 85 ct 1115 85 1106 83 1097 80 ct 1097 130 l 1101 132 l +1109 135 1113 135 1119 135 ct 1174 135 1182 125 1223 -6 ct 1321 -332 l 1270 -332 l +1197 -59 l p ef +pom +gr +13385 18918 m 13385 19218 l 12935 19068 l 13385 18918 l p ef +1 lw 0 lj 14935 14567 m 14935 19068 l 13295 19068 l ps +7085 18268 m 6785 18268 l 6935 17818 l 7085 18268 l p ef +9435 19068 m 6935 19068 l 6935 18178 l ps +20025 14718 m 20031 14418 l 20478 14577 l 20025 14718 l p ef +19335 14568 m 20127 14568 l ps +gs +pum +10179 20249 t +63 -128 m 141 -128 l 186 -128 215 -163 215 -217 ct 215 -269 186 -303 141 -303 ct +30 -303 l 30 0 l 63 0 l 63 -128 l p +63 -268 m 131 -268 l 164 -268 181 -251 181 -216 ct 181 -181 164 -163 130 -163 ct +63 -163 l 63 -268 l p ef +282 -153 m 286 -184 298 -196 325 -196 ct 352 -196 367 -184 367 -159 ct 367 -143 362 -136 351 -134 ct +300 -126 l 265 -121 245 -96 245 -58 ct 245 -19 268 6 303 6 ct 329 6 348 -4 367 -29 ct +370 -5 378 4 399 4 ct 403 4 407 3 413 1 ct 415 0 415 0 417 0 ct 417 -27 l 410 -25 408 -25 406 -25 ct +400 -25 396 -30 396 -38 ct 396 -165 l 396 -204 370 -227 327 -227 ct 298 -227 277 -217 265 -198 ct +258 -186 255 -175 254 -153 ct 282 -153 l p +366 -76 m 366 -48 340 -24 309 -24 ct 289 -24 277 -38 277 -61 ct 277 -83 288 -94 316 -98 ct +351 -104 359 -107 366 -112 ct 366 -76 l p ef +582 -158 m 580 -202 555 -227 514 -227 ct 472 -227 444 -200 444 -157 ct 444 -129 458 -111 486 -103 ct +522 -92 l 550 -84 558 -77 558 -60 ct 558 -39 542 -26 515 -26 ct 484 -26 470 -39 468 -71 ct +439 -71 l 440 -49 442 -38 448 -27 ct 460 -5 483 6 513 6 ct 559 6 588 -22 588 -66 ct +588 -97 574 -113 537 -125 ct 507 -134 l 480 -142 474 -148 474 -163 ct 474 -183 488 -195 512 -195 ct +538 -195 551 -183 553 -158 ct 582 -158 l p ef +690 -190 m 690 -221 l 660 -221 l 660 -282 l 630 -282 l 630 -221 l +605 -221 l 605 -190 l 630 -190 l 630 -44 l 630 -12 641 2 665 2 ct 667 2 669 2 676 1 ct +678 1 683 0 689 0 ct 689 -29 l 679 -29 l 665 -29 660 -34 660 -46 ct 660 -190 l +690 -190 l p ef +950 -158 m 948 -202 923 -227 882 -227 ct 840 -227 812 -200 812 -157 ct 812 -129 826 -111 854 -103 ct +890 -92 l 918 -84 926 -77 926 -60 ct 926 -39 910 -26 883 -26 ct 852 -26 838 -39 836 -71 ct +807 -71 l 808 -49 810 -38 816 -27 ct 828 -5 851 6 881 6 ct 927 6 956 -22 956 -66 ct +956 -97 942 -113 905 -125 ct 875 -134 l 848 -142 842 -148 842 -163 ct 842 -183 856 -195 880 -195 ct +906 -195 919 -183 921 -158 ct 950 -158 l p ef +1138 0 m 1138 -221 l 1108 -221 l 1108 -99 l 1108 -54 1088 -26 1058 -26 ct +1034 -26 1023 -42 1023 -74 ct 1023 -221 l 992 -221 l 992 -62 l 992 -19 1015 6 1052 6 ct +1079 6 1093 -3 1109 -34 ct 1109 0 l 1138 0 l p ef +1213 0 m 1213 -28 l 1226 -3 1240 6 1264 6 ct 1312 6 1343 -41 1343 -115 ct +1343 -182 1313 -227 1268 -227 ct 1246 -227 1230 -217 1214 -192 ct 1214 -303 l +1184 -303 l 1184 0 l 1213 0 l p +1263 -194 m 1295 -194 1311 -167 1311 -113 ct 1311 -58 1293 -26 1262 -26 ct +1250 -26 1238 -32 1229 -43 ct 1218 -57 1213 -76 1213 -105 ct 1213 -163 1230 -194 1263 -194 ct +p ef +1449 -190 m 1449 -221 l 1419 -221 l 1419 -248 l 1419 -266 1424 -274 1437 -274 ct +1440 -274 1444 -274 1449 -273 ct 1449 -307 l 1440 -307 1438 -307 1435 -307 ct +1405 -307 1389 -291 1389 -259 ct 1389 -221 l 1363 -221 l 1363 -190 l 1389 -190 l +1389 0 l 1419 0 l 1419 -190 l 1449 -190 l p ef +1571 -188 m 1571 -226 l 1568 -227 1565 -227 1563 -227 ct 1541 -227 1527 -215 1511 -183 ct +1511 -221 l 1482 -221 l 1482 0 l 1513 0 l 1513 -129 l 1513 -163 1532 -188 1559 -188 ct +1571 -188 l p ef +1620 -153 m 1624 -184 1636 -196 1663 -196 ct 1690 -196 1705 -184 1705 -159 ct +1705 -143 1700 -136 1689 -134 ct 1638 -126 l 1603 -121 1583 -96 1583 -58 ct +1583 -19 1606 6 1641 6 ct 1667 6 1686 -4 1705 -29 ct 1708 -5 1716 4 1737 4 ct 1741 4 1745 3 1751 1 ct +1753 0 1753 0 1755 0 ct 1755 -27 l 1748 -25 1746 -25 1744 -25 ct 1738 -25 1734 -30 1734 -38 ct +1734 -165 l 1734 -204 1708 -227 1665 -227 ct 1636 -227 1615 -217 1603 -198 ct +1596 -186 1593 -175 1592 -153 ct 1620 -153 l p +1704 -76 m 1704 -48 1678 -24 1647 -24 ct 1627 -24 1615 -38 1615 -61 ct 1615 -83 1626 -94 1654 -98 ct +1689 -104 1697 -107 1704 -112 ct 1704 -76 l p ef +1787 0 m 1817 0 l 1817 -120 l 1817 -165 1836 -194 1866 -194 ct 1883 -194 1894 -179 1894 -153 ct +1894 0 l 1924 0 l 1924 -134 l 1924 -168 1943 -194 1968 -194 ct 1990 -194 2001 -177 2001 -142 ct +2001 0 l 2031 0 l 2031 -153 l 2031 -199 2009 -227 1974 -227 ct 1952 -227 1940 -219 1920 -191 ct +1908 -217 1894 -227 1872 -227 ct 1848 -227 1831 -216 1816 -188 ct 1816 -221 l +1787 -221 l 1787 0 l p ef +2198 -69 m 2195 -44 2175 -26 2151 -26 ct 2133 -26 2118 -34 2110 -49 ct 2102 -61 2100 -73 2099 -98 ct +2231 -98 l 2230 -142 2226 -162 2216 -184 ct 2202 -214 2182 -227 2152 -227 ct +2100 -227 2066 -180 2066 -106 ct 2066 -36 2098 6 2150 6 ct 2192 6 2221 -21 2229 -69 ct +2198 -69 l p +2099 -128 m 2101 -167 2122 -194 2151 -194 ct 2167 -194 2180 -186 2188 -173 ct +2195 -162 2198 -151 2200 -128 ct 2099 -128 l p ef +pom +gr +tm setmatrix +0 0 t +1 1 s +0 11113 t +pom +count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore +%%PageTrailer +%%Trailer +%%EOF diff --git a/src/libs/speexdsp/doc/celp_decoder.odg b/src/libs/speexdsp/doc/celp_decoder.odg new file mode 100644 index 00000000..ed537ad4 Binary files /dev/null and b/src/libs/speexdsp/doc/celp_decoder.odg differ diff --git a/src/libs/speexdsp/doc/components.eps b/src/libs/speexdsp/doc/components.eps new file mode 100644 index 00000000..8ac53a4a --- /dev/null +++ b/src/libs/speexdsp/doc/components.eps @@ -0,0 +1,1361 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 770 174 +%%Pages: 0 +%%Creator: Sun Microsystems, Inc. +%%Title: none +%%CreationDate: none +%%LanguageLevel: 2 +%%EndComments +%%BeginProlog +%%BeginResource: procset SDRes-Prolog 1.0 0 +/b4_inc_state save def +/dict_count countdictstack def +/op_count count 1 sub def +userdict begin +0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath +/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if +/bdef {bind def} bind def +/c {setrgbcolor} bdef +/l {neg lineto} bdef +/rl {neg rlineto} bdef +/lc {setlinecap} bdef +/lj {setlinejoin} bdef +/lw {setlinewidth} bdef +/ml {setmiterlimit} bdef +/ld {setdash} bdef +/m {neg moveto} bdef +/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef +/r {rotate} bdef +/t {neg translate} bdef +/s {scale} bdef +/sw {show} bdef +/gs {gsave} bdef +/gr {grestore} bdef +/f {findfont dup length dict begin +{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def +currentdict end /NFont exch definefont pop /NFont findfont} bdef +/p {closepath} bdef +/sf {scalefont setfont} bdef +/ef {eofill}bdef +/pc {closepath stroke}bdef +/ps {stroke}bdef +/pum {matrix currentmatrix}bdef +/pom {setmatrix}bdef +/bs {/aString exch def /nXOfs exch def /nWidth exch def currentpoint nXOfs 0 rmoveto pum nWidth aString stringwidth pop div 1 scale aString show pom moveto} bdef +%%EndResource +%%EndProlog +%%BeginSetup +%%EndSetup +%%Page: 1 1 +%%BeginPageSetup +%%EndPageSetup +pum +0.02835 0.0284 s +0 -6126 t +/tm matrix currentmatrix def +tm setmatrix +-450 -7975 t +1 1 s +50 lw 1 lj 0.003 0.003 0.003 c 4400 9500 m 2900 9500 l 2900 8000 l 5900 8000 l +5900 9500 l 4400 9500 l pc +gs +gs +pum +3380 8974 t +50 0 m 50 -455 l 251 -455 l 292 -455 323 -451 344 -443 ct 365 -435 382 -420 394 -399 ct +407 -379 413 -356 413 -331 ct 413 -299 403 -271 382 -249 ct 361 -227 329 -213 285 -207 ct +301 -199 313 -192 322 -184 ct 339 -168 356 -148 371 -124 ct 451 0 l 375 0 l +315 -95 l 297 -122 283 -143 271 -157 ct 260 -172 250 -182 241 -188 ct 232 -194 223 -198 213 -200 ct +207 -201 195 -202 180 -202 ct 110 -202 l 110 0 l 50 0 l p +110 -254 m 239 -254 l 267 -254 288 -257 304 -263 ct 319 -268 331 -277 339 -290 ct +347 -303 351 -316 351 -331 ct 351 -352 344 -370 328 -384 ct 312 -398 288 -405 254 -405 ct +110 -405 l 110 -254 l p ef +724 -107 m 782 -99 l 773 -66 756 -40 731 -21 ct 707 -2 675 7 637 7 ct 589 7 551 -8 523 -37 ct +494 -67 480 -109 480 -162 ct 480 -218 495 -261 523 -291 ct 552 -322 589 -337 634 -337 ct +678 -337 714 -322 742 -292 ct 770 -262 784 -220 784 -166 ct 784 -163 784 -158 783 -151 ct +538 -151 l 540 -115 550 -87 569 -68 ct 587 -49 610 -39 637 -39 ct 658 -39 675 -44 690 -55 ct +704 -66 716 -83 724 -107 ct p +541 -197 m 725 -197 l 722 -225 715 -245 704 -259 ct 686 -280 663 -291 635 -291 ct +609 -291 587 -283 570 -265 ct 553 -248 543 -226 541 -197 ct p ef +1066 -121 m 1121 -114 l 1115 -76 1099 -46 1075 -25 ct 1050 -4 1020 7 984 7 ct +939 7 902 -8 875 -37 ct 848 -67 834 -109 834 -164 ct 834 -199 840 -230 851 -257 ct +863 -284 881 -304 905 -317 ct 929 -330 956 -337 984 -337 ct 1020 -337 1049 -328 1072 -310 ct +1094 -292 1109 -266 1115 -233 ct 1061 -224 l 1056 -247 1047 -263 1034 -274 ct +1021 -286 1005 -291 986 -291 ct 958 -291 935 -281 918 -261 ct 900 -241 891 -209 891 -165 ct +891 -121 900 -89 917 -69 ct 934 -49 956 -39 983 -39 ct 1005 -39 1023 -46 1038 -59 ct +1053 -72 1062 -93 1066 -121 ct p ef +1147 -165 m 1147 -226 1164 -271 1198 -301 ct 1226 -325 1261 -337 1302 -337 ct +1347 -337 1384 -322 1412 -293 ct 1441 -263 1456 -222 1456 -170 ct 1456 -127 1449 -94 1437 -70 ct +1424 -45 1405 -27 1381 -13 ct 1357 0 1330 7 1302 7 ct 1255 7 1218 -8 1190 -37 ct +1161 -67 1147 -110 1147 -165 ct p +1204 -165 m 1204 -123 1214 -91 1232 -70 ct 1250 -49 1274 -39 1302 -39 ct 1329 -39 1352 -49 1371 -71 ct +1389 -92 1398 -124 1398 -167 ct 1398 -208 1389 -239 1370 -260 ct 1352 -281 1329 -291 1302 -291 ct +1274 -291 1250 -281 1232 -260 ct 1214 -239 1204 -207 1204 -165 ct p ef +1518 0 m 1518 -330 l 1568 -330 l 1568 -280 l 1581 -303 1593 -318 1604 -326 ct +1615 -333 1627 -337 1640 -337 ct 1659 -337 1678 -331 1697 -319 ct 1678 -267 l +1664 -275 1651 -279 1637 -279 ct 1625 -279 1614 -276 1604 -268 ct 1594 -261 1587 -251 1583 -238 ct +1577 -218 1574 -196 1574 -173 ct 1574 0 l 1518 0 l p ef +1944 0 m 1944 -42 l 1924 -9 1893 7 1852 7 ct 1826 7 1802 0 1780 -15 ct 1758 -29 1741 -49 1729 -75 ct +1717 -101 1711 -131 1711 -165 ct 1711 -198 1716 -228 1727 -254 ct 1738 -281 1755 -302 1776 -316 ct +1798 -330 1823 -337 1850 -337 ct 1870 -337 1887 -333 1903 -325 ct 1918 -316 1931 -305 1941 -292 ct +1941 -455 l 1996 -455 l 1996 0 l 1944 0 l p +1768 -165 m 1768 -123 1777 -91 1795 -70 ct 1813 -49 1833 -39 1858 -39 ct 1882 -39 1903 -49 1920 -69 ct +1937 -89 1945 -119 1945 -160 ct 1945 -205 1937 -238 1919 -259 ct 1902 -280 1881 -291 1855 -291 ct +1830 -291 1810 -281 1793 -261 ct 1776 -240 1768 -208 1768 -165 ct p ef +pom +gr +gr +12748 9525 m 12697 9525 l 12697 9475 l 12748 9475 l 12748 9525 l p ef +12646 9525 m 12595 9525 l 12595 9475 l 12646 9475 l 12646 9525 l p ef +12544 9525 m 12493 9525 l 12493 9475 l 12544 9475 l 12544 9525 l p ef +12442 9525 m 12391 9525 l 12391 9475 l 12442 9475 l 12442 9525 l p ef +12340 9525 m 12289 9525 l 12289 9475 l 12340 9475 l 12340 9525 l p ef +12238 9525 m 12187 9525 l 12187 9475 l 12238 9475 l 12238 9525 l p ef +12136 9525 m 12085 9525 l 12085 9475 l 12136 9475 l 12136 9525 l p ef +12034 9525 m 11983 9525 l 11983 9475 l 12034 9475 l 12034 9525 l p ef +11932 9525 m 11881 9525 l 11881 9475 l 11932 9475 l 11932 9525 l p ef +11830 9525 m 11779 9525 l 11779 9475 l 11830 9475 l 11830 9525 l p ef +11728 9525 m 11677 9525 l 11677 9475 l 11728 9475 l 11728 9525 l p ef +11626 9525 m 11575 9525 l 11575 9475 l 11626 9475 l 11626 9525 l p ef +11524 9525 m 11473 9525 l 11473 9475 l 11524 9475 l 11524 9525 l p ef +11422 9525 m 11400 9525 l 11400 9500 l 11400 9475 l 11422 9475 l 11422 9500 l +11422 9525 l p ef +11400 9500 m 11400 9525 l 11396 9525 l 11391 9523 l 11388 9522 l 11384 9519 l +11381 9516 l 11378 9513 l 11377 9509 l 11375 9504 l 11375 9500 l 11375 9500 l +11400 9500 l p ef +11375 9500 m 11375 9471 l 11400 9471 l 11425 9471 l 11425 9500 l 11400 9500 l +11375 9500 l p ef +11375 9420 m 11375 9369 l 11425 9369 l 11425 9420 l 11375 9420 l p ef +11375 9318 m 11375 9267 l 11425 9267 l 11425 9318 l 11375 9318 l p ef +11375 9216 m 11375 9165 l 11425 9165 l 11425 9216 l 11375 9216 l p ef +11375 9114 m 11375 9063 l 11425 9063 l 11425 9114 l 11375 9114 l p ef +11375 9012 m 11375 8961 l 11425 8961 l 11425 9012 l 11375 9012 l p ef +11375 8910 m 11375 8859 l 11425 8859 l 11425 8910 l 11375 8910 l p ef +11375 8808 m 11375 8757 l 11425 8757 l 11425 8808 l 11375 8808 l p ef +11375 8706 m 11375 8655 l 11425 8655 l 11425 8706 l 11375 8706 l p ef +11375 8604 m 11375 8553 l 11425 8553 l 11425 8604 l 11375 8604 l p ef +11375 8502 m 11375 8451 l 11425 8451 l 11425 8502 l 11375 8502 l p ef +11375 8400 m 11375 8349 l 11425 8349 l 11425 8400 l 11375 8400 l p ef +11375 8298 m 11375 8247 l 11425 8247 l 11425 8298 l 11375 8298 l p ef +11375 8196 m 11375 8145 l 11425 8145 l 11425 8196 l 11375 8196 l p ef +11375 8094 m 11375 8043 l 11425 8043 l 11425 8094 l 11375 8094 l p ef +11408 7975 m 11459 7975 l 11459 8025 l 11408 8025 l 11408 7975 l p ef +11510 7975 m 11561 7975 l 11561 8025 l 11510 8025 l 11510 7975 l p ef +11612 7975 m 11663 7975 l 11663 8025 l 11612 8025 l 11612 7975 l p ef +11714 7975 m 11765 7975 l 11765 8025 l 11714 8025 l 11714 7975 l p ef +11816 7975 m 11867 7975 l 11867 8025 l 11816 8025 l 11816 7975 l p ef +11918 7975 m 11969 7975 l 11969 8025 l 11918 8025 l 11918 7975 l p ef +12020 7975 m 12071 7975 l 12071 8025 l 12020 8025 l 12020 7975 l p ef +12122 7975 m 12173 7975 l 12173 8025 l 12122 8025 l 12122 7975 l p ef +12224 7975 m 12275 7975 l 12275 8025 l 12224 8025 l 12224 7975 l p ef +12326 7975 m 12377 7975 l 12377 8025 l 12326 8025 l 12326 7975 l p ef +12428 7975 m 12479 7975 l 12479 8025 l 12428 8025 l 12428 7975 l p ef +12530 7975 m 12581 7975 l 12581 8025 l 12530 8025 l 12530 7975 l p ef +12632 7975 m 12683 7975 l 12683 8025 l 12632 8025 l 12632 7975 l p ef +12734 7975 m 12785 7975 l 12785 8025 l 12734 8025 l 12734 7975 l p ef +12836 7975 m 12887 7975 l 12887 8025 l 12836 8025 l 12836 7975 l p ef +12938 7975 m 12989 7975 l 12989 8025 l 12938 8025 l 12938 7975 l p ef +13040 7975 m 13091 7975 l 13091 8025 l 13040 8025 l 13040 7975 l p ef +13142 7975 m 13193 7975 l 13193 8025 l 13142 8025 l 13142 7975 l p ef +13244 7975 m 13295 7975 l 13295 8025 l 13244 8025 l 13244 7975 l p ef +13346 7975 m 13397 7975 l 13397 8025 l 13346 8025 l 13346 7975 l p ef +13448 7975 m 13499 7975 l 13499 8025 l 13448 8025 l 13448 7975 l p ef +13550 7975 m 13601 7975 l 13601 8025 l 13550 8025 l 13550 7975 l p ef +13652 7975 m 13703 7975 l 13703 8025 l 13652 8025 l 13652 7975 l p ef +13754 7975 m 13805 7975 l 13805 8025 l 13754 8025 l 13754 7975 l p ef +13856 7975 m 13907 7975 l 13907 8025 l 13856 8025 l 13856 7975 l p ef +13958 7975 m 14009 7975 l 14009 8025 l 13958 8025 l 13958 7975 l p ef +14060 7975 m 14111 7975 l 14111 8025 l 14060 8025 l 14060 7975 l p ef +14162 7975 m 14213 7975 l 14213 8025 l 14162 8025 l 14162 7975 l p ef +14264 7975 m 14300 7975 l 14300 8000 l 14300 8025 l 14264 8025 l 14264 8000 l +14264 7975 l p ef +14300 8000 m 14300 7975 l 14304 7975 l 14309 7977 l 14312 7978 l 14316 7981 l +14319 7984 l 14322 7987 l 14323 7991 l 14325 7996 l 14325 8000 l 14325 8000 l +14300 8000 l p ef +14325 8000 m 14325 8015 l 14300 8015 l 14275 8015 l 14275 8000 l 14300 8000 l +14325 8000 l p ef +14325 8066 m 14325 8117 l 14275 8117 l 14275 8066 l 14325 8066 l p ef +14325 8168 m 14325 8219 l 14275 8219 l 14275 8168 l 14325 8168 l p ef +14325 8270 m 14325 8321 l 14275 8321 l 14275 8270 l 14325 8270 l p ef +14325 8372 m 14325 8423 l 14275 8423 l 14275 8372 l 14325 8372 l p ef +14325 8474 m 14325 8525 l 14275 8525 l 14275 8474 l 14325 8474 l p ef +14325 8576 m 14325 8627 l 14275 8627 l 14275 8576 l 14325 8576 l p ef +14325 8678 m 14325 8729 l 14275 8729 l 14275 8678 l 14325 8678 l p ef +14325 8780 m 14325 8831 l 14275 8831 l 14275 8780 l 14325 8780 l p ef +14325 8882 m 14325 8933 l 14275 8933 l 14275 8882 l 14325 8882 l p ef +14325 8984 m 14325 9035 l 14275 9035 l 14275 8984 l 14325 8984 l p ef +14325 9086 m 14325 9137 l 14275 9137 l 14275 9086 l 14325 9086 l p ef +14325 9188 m 14325 9239 l 14275 9239 l 14275 9188 l 14325 9188 l p ef +14325 9290 m 14325 9341 l 14275 9341 l 14275 9290 l 14325 9290 l p ef +14325 9392 m 14325 9443 l 14275 9443 l 14275 9392 l 14325 9392 l p ef +14325 9494 m 14325 9500 l 14300 9500 l 14275 9500 l 14275 9494 l 14300 9494 l +14325 9494 l p ef +14300 9500 m 14325 9500 l 14325 9504 l 14323 9509 l 14322 9512 l 14319 9516 l +14316 9519 l 14313 9522 l 14309 9523 l 14304 9525 l 14300 9525 l 14300 9525 l +14300 9500 l p ef +14300 9525 m 14255 9525 l 14255 9500 l 14255 9475 l 14300 9475 l 14300 9500 l +14300 9525 l p ef +14204 9525 m 14153 9525 l 14153 9475 l 14204 9475 l 14204 9525 l p ef +14102 9525 m 14051 9525 l 14051 9475 l 14102 9475 l 14102 9525 l p ef +14000 9525 m 13949 9525 l 13949 9475 l 14000 9475 l 14000 9525 l p ef +13898 9525 m 13847 9525 l 13847 9475 l 13898 9475 l 13898 9525 l p ef +13796 9525 m 13745 9525 l 13745 9475 l 13796 9475 l 13796 9525 l p ef +13694 9525 m 13643 9525 l 13643 9475 l 13694 9475 l 13694 9525 l p ef +13592 9525 m 13541 9525 l 13541 9475 l 13592 9475 l 13592 9525 l p ef +13490 9525 m 13439 9525 l 13439 9475 l 13490 9475 l 13490 9525 l p ef +13388 9525 m 13337 9525 l 13337 9475 l 13388 9475 l 13388 9525 l p ef +13286 9525 m 13235 9525 l 13235 9475 l 13286 9475 l 13286 9525 l p ef +13184 9525 m 13133 9525 l 13133 9475 l 13184 9475 l 13184 9525 l p ef +13082 9525 m 13031 9525 l 13031 9475 l 13082 9475 l 13082 9525 l p ef +12980 9525 m 12929 9525 l 12929 9475 l 12980 9475 l 12980 9525 l p ef +12878 9525 m 12850 9525 l 12850 9500 l 12850 9475 l 12878 9475 l 12878 9500 l +12878 9525 l p ef +12850 9525 m 12799 9525 l 12799 9500 l 12799 9475 l 12850 9475 l 12850 9500 l +12850 9525 l p ef +gs +gs +pum +12191 8974 t +-1 0 m 174 -455 l 238 -455 l 424 0 l 356 0 l 303 -138 l 113 -138 l +63 0 l -1 0 l p +130 -187 m 284 -187 l 237 -313 l 222 -351 212 -383 205 -407 ct 199 -378 191 -349 180 -320 ct +130 -187 l p ef +473 0 m 473 -455 l 802 -455 l 802 -401 l 533 -401 l 533 -262 l 785 -262 l +785 -209 l 533 -209 l 533 -54 l 812 -54 l 812 0 l 473 0 l p ef +1220 -159 m 1280 -144 l 1268 -95 1245 -57 1212 -31 ct 1180 -5 1140 8 1092 8 ct +1043 8 1003 -2 973 -22 ct 942 -42 919 -71 903 -109 ct 887 -147 879 -187 879 -231 ct +879 -278 888 -319 906 -355 ct 924 -390 950 -417 983 -435 ct 1016 -453 1053 -463 1093 -463 ct +1139 -463 1177 -451 1208 -428 ct 1239 -405 1261 -372 1273 -330 ct 1213 -316 l +1203 -349 1188 -373 1168 -388 ct 1148 -403 1122 -411 1092 -411 ct 1057 -411 1028 -403 1004 -386 ct +981 -369 964 -347 955 -318 ct 945 -290 941 -261 941 -231 ct 941 -192 946 -159 958 -130 ct +969 -101 986 -79 1010 -65 ct 1034 -51 1060 -44 1087 -44 ct 1121 -44 1150 -53 1173 -73 ct +1196 -92 1212 -121 1220 -159 ct p ef +pom +gr +gr +17600 9525 m 17549 9525 l 17549 9475 l 17600 9475 l 17600 9525 l p ef +17498 9525 m 17447 9525 l 17447 9475 l 17498 9475 l 17498 9525 l p ef +17396 9525 m 17345 9525 l 17345 9475 l 17396 9475 l 17396 9525 l p ef +17294 9525 m 17243 9525 l 17243 9475 l 17294 9475 l 17294 9525 l p ef +17192 9525 m 17141 9525 l 17141 9475 l 17192 9475 l 17192 9525 l p ef +17090 9525 m 17039 9525 l 17039 9475 l 17090 9475 l 17090 9525 l p ef +16988 9525 m 16937 9525 l 16937 9475 l 16988 9475 l 16988 9525 l p ef +16886 9525 m 16835 9525 l 16835 9475 l 16886 9475 l 16886 9525 l p ef +16784 9525 m 16733 9525 l 16733 9475 l 16784 9475 l 16784 9525 l p ef +16682 9525 m 16631 9525 l 16631 9475 l 16682 9475 l 16682 9525 l p ef +16580 9525 m 16529 9525 l 16529 9475 l 16580 9475 l 16580 9525 l p ef +16478 9525 m 16427 9525 l 16427 9475 l 16478 9475 l 16478 9525 l p ef +16376 9525 m 16325 9525 l 16325 9475 l 16376 9475 l 16376 9525 l p ef +16274 9525 m 16223 9525 l 16223 9475 l 16274 9475 l 16274 9525 l p ef +16172 9525 m 16121 9525 l 16121 9475 l 16172 9475 l 16172 9525 l p ef +16070 9525 m 16019 9525 l 16019 9475 l 16070 9475 l 16070 9525 l p ef +15968 9525 m 15917 9525 l 15917 9475 l 15968 9475 l 15968 9525 l p ef +15866 9525 m 15815 9525 l 15815 9475 l 15866 9475 l 15866 9525 l p ef +15764 9525 m 15713 9525 l 15713 9475 l 15764 9475 l 15764 9525 l p ef +15662 9525 m 15611 9525 l 15611 9475 l 15662 9475 l 15662 9525 l p ef +15560 9525 m 15509 9525 l 15509 9475 l 15560 9475 l 15560 9525 l p ef +15458 9525 m 15407 9525 l 15407 9475 l 15458 9475 l 15458 9525 l p ef +15375 9456 m 15375 9405 l 15425 9405 l 15425 9456 l 15375 9456 l p ef +15375 9354 m 15375 9303 l 15425 9303 l 15425 9354 l 15375 9354 l p ef +15375 9252 m 15375 9201 l 15425 9201 l 15425 9252 l 15375 9252 l p ef +15375 9150 m 15375 9099 l 15425 9099 l 15425 9150 l 15375 9150 l p ef +15375 9048 m 15375 8997 l 15425 8997 l 15425 9048 l 15375 9048 l p ef +15375 8946 m 15375 8895 l 15425 8895 l 15425 8946 l 15375 8946 l p ef +15375 8844 m 15375 8793 l 15425 8793 l 15425 8844 l 15375 8844 l p ef +15375 8742 m 15375 8691 l 15425 8691 l 15425 8742 l 15375 8742 l p ef +15375 8640 m 15375 8589 l 15425 8589 l 15425 8640 l 15375 8640 l p ef +15375 8538 m 15375 8487 l 15425 8487 l 15425 8538 l 15375 8538 l p ef +15375 8436 m 15375 8385 l 15425 8385 l 15425 8436 l 15375 8436 l p ef +15375 8334 m 15375 8283 l 15425 8283 l 15425 8334 l 15375 8334 l p ef +15375 8232 m 15375 8181 l 15425 8181 l 15425 8232 l 15375 8232 l p ef +15375 8130 m 15375 8079 l 15425 8079 l 15425 8130 l 15375 8130 l p ef +15375 8028 m 15375 8000 l 15400 8000 l 15425 8000 l 15425 8028 l 15400 8028 l +15375 8028 l p ef +15400 8000 m 15375 8000 l 15375 7996 l 15377 7991 l 15378 7988 l 15381 7984 l +15384 7981 l 15387 7978 l 15391 7977 l 15396 7975 l 15400 7975 l 15400 7975 l +15400 8000 l p ef +15400 7975 m 15423 7975 l 15423 8000 l 15423 8025 l 15400 8025 l 15400 8000 l +15400 7975 l p ef +15474 7975 m 15525 7975 l 15525 8025 l 15474 8025 l 15474 7975 l p ef +15576 7975 m 15627 7975 l 15627 8025 l 15576 8025 l 15576 7975 l p ef +15678 7975 m 15729 7975 l 15729 8025 l 15678 8025 l 15678 7975 l p ef +15780 7975 m 15831 7975 l 15831 8025 l 15780 8025 l 15780 7975 l p ef +15882 7975 m 15933 7975 l 15933 8025 l 15882 8025 l 15882 7975 l p ef +15984 7975 m 16035 7975 l 16035 8025 l 15984 8025 l 15984 7975 l p ef +16086 7975 m 16137 7975 l 16137 8025 l 16086 8025 l 16086 7975 l p ef +16188 7975 m 16239 7975 l 16239 8025 l 16188 8025 l 16188 7975 l p ef +16290 7975 m 16341 7975 l 16341 8025 l 16290 8025 l 16290 7975 l p ef +16392 7975 m 16443 7975 l 16443 8025 l 16392 8025 l 16392 7975 l p ef +16494 7975 m 16545 7975 l 16545 8025 l 16494 8025 l 16494 7975 l p ef +16596 7975 m 16647 7975 l 16647 8025 l 16596 8025 l 16596 7975 l p ef +16698 7975 m 16749 7975 l 16749 8025 l 16698 8025 l 16698 7975 l p ef +16800 7975 m 16851 7975 l 16851 8025 l 16800 8025 l 16800 7975 l p ef +16902 7975 m 16953 7975 l 16953 8025 l 16902 8025 l 16902 7975 l p ef +17004 7975 m 17055 7975 l 17055 8025 l 17004 8025 l 17004 7975 l p ef +17106 7975 m 17157 7975 l 17157 8025 l 17106 8025 l 17106 7975 l p ef +17208 7975 m 17259 7975 l 17259 8025 l 17208 8025 l 17208 7975 l p ef +17310 7975 m 17361 7975 l 17361 8025 l 17310 8025 l 17310 7975 l p ef +17412 7975 m 17463 7975 l 17463 8025 l 17412 8025 l 17412 7975 l p ef +17514 7975 m 17565 7975 l 17565 8025 l 17514 8025 l 17514 7975 l p ef +17616 7975 m 17667 7975 l 17667 8025 l 17616 8025 l 17616 7975 l p ef +17718 7975 m 17769 7975 l 17769 8025 l 17718 8025 l 17718 7975 l p ef +17820 7975 m 17871 7975 l 17871 8025 l 17820 8025 l 17820 7975 l p ef +17922 7975 m 17973 7975 l 17973 8025 l 17922 8025 l 17922 7975 l p ef +18024 7975 m 18075 7975 l 18075 8025 l 18024 8025 l 18024 7975 l p ef +18126 7975 m 18177 7975 l 18177 8025 l 18126 8025 l 18126 7975 l p ef +18228 7975 m 18279 7975 l 18279 8025 l 18228 8025 l 18228 7975 l p ef +18330 7975 m 18381 7975 l 18381 8025 l 18330 8025 l 18330 7975 l p ef +18432 7975 m 18483 7975 l 18483 8025 l 18432 8025 l 18432 7975 l p ef +18534 7975 m 18585 7975 l 18585 8025 l 18534 8025 l 18534 7975 l p ef +18636 7975 m 18687 7975 l 18687 8025 l 18636 8025 l 18636 7975 l p ef +18738 7975 m 18789 7975 l 18789 8025 l 18738 8025 l 18738 7975 l p ef +18840 7975 m 18891 7975 l 18891 8025 l 18840 8025 l 18840 7975 l p ef +18942 7975 m 18993 7975 l 18993 8025 l 18942 8025 l 18942 7975 l p ef +19044 7975 m 19095 7975 l 19095 8025 l 19044 8025 l 19044 7975 l p ef +19146 7975 m 19197 7975 l 19197 8025 l 19146 8025 l 19146 7975 l p ef +19248 7975 m 19299 7975 l 19299 8025 l 19248 8025 l 19248 7975 l p ef +19350 7975 m 19401 7975 l 19401 8025 l 19350 8025 l 19350 7975 l p ef +19452 7975 m 19503 7975 l 19503 8025 l 19452 8025 l 19452 7975 l p ef +19554 7975 m 19605 7975 l 19605 8025 l 19554 8025 l 19554 7975 l p ef +19656 7975 m 19707 7975 l 19707 8025 l 19656 8025 l 19656 7975 l p ef +19758 7975 m 19800 7975 l 19800 8000 l 19800 8025 l 19758 8025 l 19758 8000 l +19758 7975 l p ef +19800 8000 m 19800 7975 l 19804 7975 l 19809 7977 l 19812 7978 l 19816 7981 l +19819 7984 l 19822 7987 l 19823 7991 l 19825 7996 l 19825 8000 l 19825 8000 l +19800 8000 l p ef +19825 8000 m 19825 8009 l 19800 8009 l 19775 8009 l 19775 8000 l 19800 8000 l +19825 8000 l p ef +19825 8060 m 19825 8111 l 19775 8111 l 19775 8060 l 19825 8060 l p ef +19825 8162 m 19825 8213 l 19775 8213 l 19775 8162 l 19825 8162 l p ef +19825 8264 m 19825 8315 l 19775 8315 l 19775 8264 l 19825 8264 l p ef +19825 8366 m 19825 8417 l 19775 8417 l 19775 8366 l 19825 8366 l p ef +19825 8468 m 19825 8519 l 19775 8519 l 19775 8468 l 19825 8468 l p ef +19825 8570 m 19825 8621 l 19775 8621 l 19775 8570 l 19825 8570 l p ef +19825 8672 m 19825 8723 l 19775 8723 l 19775 8672 l 19825 8672 l p ef +19825 8774 m 19825 8825 l 19775 8825 l 19775 8774 l 19825 8774 l p ef +19825 8876 m 19825 8927 l 19775 8927 l 19775 8876 l 19825 8876 l p ef +19825 8978 m 19825 9029 l 19775 9029 l 19775 8978 l 19825 8978 l p ef +19825 9080 m 19825 9131 l 19775 9131 l 19775 9080 l 19825 9080 l p ef +19825 9182 m 19825 9233 l 19775 9233 l 19775 9182 l 19825 9182 l p ef +19825 9284 m 19825 9335 l 19775 9335 l 19775 9284 l 19825 9284 l p ef +19825 9386 m 19825 9437 l 19775 9437 l 19775 9386 l 19825 9386 l p ef +19825 9488 m 19825 9500 l 19800 9500 l 19775 9500 l 19775 9488 l 19800 9488 l +19825 9488 l p ef +19800 9500 m 19825 9500 l 19825 9504 l 19823 9509 l 19822 9512 l 19819 9516 l +19816 9519 l 19813 9522 l 19809 9523 l 19804 9525 l 19800 9525 l 19800 9525 l +19800 9500 l p ef +19800 9525 m 19761 9525 l 19761 9500 l 19761 9475 l 19800 9475 l 19800 9500 l +19800 9525 l p ef +19710 9525 m 19659 9525 l 19659 9475 l 19710 9475 l 19710 9525 l p ef +19608 9525 m 19557 9525 l 19557 9475 l 19608 9475 l 19608 9525 l p ef +19506 9525 m 19455 9525 l 19455 9475 l 19506 9475 l 19506 9525 l p ef +19404 9525 m 19353 9525 l 19353 9475 l 19404 9475 l 19404 9525 l p ef +19302 9525 m 19251 9525 l 19251 9475 l 19302 9475 l 19302 9525 l p ef +19200 9525 m 19149 9525 l 19149 9475 l 19200 9475 l 19200 9525 l p ef +19098 9525 m 19047 9525 l 19047 9475 l 19098 9475 l 19098 9525 l p ef +18996 9525 m 18945 9525 l 18945 9475 l 18996 9475 l 18996 9525 l p ef +18894 9525 m 18843 9525 l 18843 9475 l 18894 9475 l 18894 9525 l p ef +18792 9525 m 18741 9525 l 18741 9475 l 18792 9475 l 18792 9525 l p ef +18690 9525 m 18639 9525 l 18639 9475 l 18690 9475 l 18690 9525 l p ef +18588 9525 m 18537 9525 l 18537 9475 l 18588 9475 l 18588 9525 l p ef +18486 9525 m 18435 9525 l 18435 9475 l 18486 9475 l 18486 9525 l p ef +18384 9525 m 18333 9525 l 18333 9475 l 18384 9475 l 18384 9525 l p ef +18282 9525 m 18231 9525 l 18231 9475 l 18282 9475 l 18282 9525 l p ef +18180 9525 m 18129 9525 l 18129 9475 l 18180 9475 l 18180 9525 l p ef +18078 9525 m 18027 9525 l 18027 9475 l 18078 9475 l 18078 9525 l p ef +17976 9525 m 17925 9525 l 17925 9475 l 17976 9475 l 17976 9525 l p ef +17874 9525 m 17823 9525 l 17823 9475 l 17874 9475 l 17874 9525 l p ef +17772 9525 m 17721 9525 l 17721 9475 l 17772 9475 l 17772 9525 l p ef +17670 9525 m 17619 9525 l 17619 9475 l 17670 9475 l 17670 9525 l p ef +gs +gs +pum +15705 8974 t +49 0 m 49 -455 l 220 -455 l 251 -455 274 -454 290 -451 ct 312 -447 331 -440 346 -429 ct +361 -419 373 -404 382 -385 ct 391 -367 396 -346 396 -323 ct 396 -285 384 -252 359 -225 ct +334 -198 290 -185 226 -185 ct 109 -185 l 109 0 l 49 0 l p +109 -239 m 227 -239 l 266 -239 293 -246 309 -260 ct 326 -275 334 -295 334 -322 ct +334 -341 329 -357 320 -370 ct 310 -384 297 -393 282 -397 ct 271 -400 253 -401 225 -401 ct +109 -401 l 109 -239 l p ef +464 0 m 464 -330 l 514 -330 l 514 -280 l 527 -303 539 -318 550 -326 ct +561 -333 573 -337 586 -337 ct 605 -337 624 -331 643 -319 ct 624 -267 l 610 -275 597 -279 583 -279 ct +571 -279 560 -276 550 -268 ct 540 -261 533 -251 529 -238 ct 523 -218 520 -196 520 -173 ct +520 0 l 464 0 l p ef +902 -107 m 960 -99 l 951 -66 934 -40 909 -21 ct 885 -2 853 7 815 7 ct 767 7 729 -8 701 -37 ct +672 -67 658 -109 658 -162 ct 658 -218 673 -261 701 -291 ct 730 -322 767 -337 812 -337 ct +856 -337 892 -322 920 -292 ct 948 -262 962 -220 962 -166 ct 962 -163 962 -158 961 -151 ct +716 -151 l 718 -115 728 -87 747 -68 ct 765 -49 788 -39 815 -39 ct 836 -39 853 -44 868 -55 ct +882 -66 894 -83 902 -107 ct p +719 -197 m 903 -197 l 900 -225 893 -245 882 -259 ct 864 -280 841 -291 813 -291 ct +787 -291 765 -283 748 -265 ct 731 -248 721 -226 719 -197 ct p ef +1028 126 m 1028 -330 l 1079 -330 l 1079 -287 l 1091 -304 1104 -316 1119 -324 ct +1134 -333 1153 -337 1174 -337 ct 1202 -337 1227 -330 1249 -315 ct 1270 -301 1286 -280 1297 -254 ct +1308 -228 1314 -199 1314 -167 ct 1314 -134 1308 -103 1296 -77 ct 1284 -50 1266 -29 1243 -15 ct +1220 0 1196 7 1170 7 ct 1152 7 1135 3 1120 -5 ct 1105 -13 1093 -23 1084 -35 ct +1084 126 l 1028 126 l p +1078 -163 m 1078 -121 1087 -90 1104 -69 ct 1121 -49 1142 -39 1166 -39 ct 1191 -39 1213 -49 1230 -70 ct +1248 -91 1257 -124 1257 -168 ct 1257 -210 1248 -241 1231 -262 ct 1214 -283 1193 -293 1169 -293 ct +1145 -293 1124 -282 1106 -260 ct 1088 -238 1078 -205 1078 -163 ct p ef +1379 0 m 1379 -330 l 1429 -330 l 1429 -280 l 1442 -303 1454 -318 1465 -326 ct +1476 -333 1488 -337 1501 -337 ct 1520 -337 1539 -331 1558 -319 ct 1539 -267 l +1525 -275 1512 -279 1498 -279 ct 1486 -279 1475 -276 1465 -268 ct 1455 -261 1448 -251 1444 -238 ct +1438 -218 1435 -196 1435 -173 ct 1435 0 l 1379 0 l p ef +1570 -165 m 1570 -226 1587 -271 1621 -301 ct 1649 -325 1684 -337 1725 -337 ct +1770 -337 1807 -322 1835 -293 ct 1864 -263 1879 -222 1879 -170 ct 1879 -127 1872 -94 1860 -70 ct +1847 -45 1828 -27 1804 -13 ct 1780 0 1753 7 1725 7 ct 1678 7 1641 -8 1613 -37 ct +1584 -67 1570 -110 1570 -165 ct p +1627 -165 m 1627 -123 1637 -91 1655 -70 ct 1673 -49 1697 -39 1725 -39 ct 1752 -39 1775 -49 1794 -71 ct +1812 -92 1821 -124 1821 -167 ct 1821 -208 1812 -239 1793 -260 ct 1775 -281 1752 -291 1725 -291 ct +1697 -291 1673 -281 1655 -260 ct 1637 -239 1627 -207 1627 -165 ct p ef +2158 -121 m 2213 -114 l 2207 -76 2191 -46 2167 -25 ct 2142 -4 2112 7 2076 7 ct +2031 7 1994 -8 1967 -37 ct 1940 -67 1926 -109 1926 -164 ct 1926 -199 1932 -230 1943 -257 ct +1955 -284 1973 -304 1997 -317 ct 2021 -330 2048 -337 2076 -337 ct 2112 -337 2141 -328 2164 -310 ct +2186 -292 2201 -266 2207 -233 ct 2153 -224 l 2148 -247 2139 -263 2126 -274 ct +2113 -286 2097 -291 2078 -291 ct 2050 -291 2027 -281 2010 -261 ct 1992 -241 1983 -209 1983 -165 ct +1983 -121 1992 -89 2009 -69 ct 2026 -49 2048 -39 2075 -39 ct 2097 -39 2115 -46 2130 -59 ct +2145 -72 2154 -93 2158 -121 ct p ef +2485 -107 m 2543 -99 l 2534 -66 2517 -40 2492 -21 ct 2468 -2 2436 7 2398 7 ct +2350 7 2312 -8 2284 -37 ct 2255 -67 2241 -109 2241 -162 ct 2241 -218 2256 -261 2284 -291 ct +2313 -322 2350 -337 2395 -337 ct 2439 -337 2475 -322 2503 -292 ct 2531 -262 2545 -220 2545 -166 ct +2545 -163 2545 -158 2544 -151 ct 2299 -151 l 2301 -115 2311 -87 2330 -68 ct +2348 -49 2371 -39 2398 -39 ct 2419 -39 2436 -44 2451 -55 ct 2465 -66 2477 -83 2485 -107 ct +p +2302 -197 m 2486 -197 l 2483 -225 2476 -245 2465 -259 ct 2447 -280 2424 -291 2396 -291 ct +2370 -291 2348 -283 2331 -265 ct 2314 -248 2304 -226 2302 -197 ct p ef +2590 -99 m 2645 -107 l 2648 -85 2656 -68 2671 -57 ct 2685 -45 2705 -39 2730 -39 ct +2756 -39 2775 -44 2787 -55 ct 2799 -65 2806 -77 2806 -91 ct 2806 -104 2800 -114 2789 -121 ct +2782 -126 2763 -132 2732 -140 ct 2691 -150 2663 -159 2647 -167 ct 2631 -174 2619 -185 2611 -198 ct +2603 -211 2599 -226 2599 -242 ct 2599 -257 2602 -270 2609 -283 ct 2616 -295 2625 -306 2636 -314 ct +2645 -320 2657 -326 2672 -330 ct 2687 -335 2703 -337 2720 -337 ct 2746 -337 2769 -333 2788 -326 ct +2808 -318 2822 -308 2831 -296 ct 2841 -283 2847 -266 2851 -245 ct 2796 -237 l +2794 -254 2786 -267 2774 -277 ct 2763 -286 2746 -291 2724 -291 ct 2698 -291 2680 -287 2669 -278 ct +2658 -270 2653 -260 2653 -249 ct 2653 -241 2655 -235 2660 -229 ct 2664 -223 2671 -218 2681 -214 ct +2687 -212 2703 -207 2730 -200 ct 2770 -189 2797 -181 2813 -174 ct 2829 -167 2841 -158 2850 -145 ct +2859 -132 2863 -116 2863 -97 ct 2863 -79 2858 -61 2847 -45 ct 2836 -28 2820 -15 2800 -6 ct +2779 3 2756 7 2730 7 ct 2688 7 2655 -2 2632 -20 ct 2610 -37 2596 -64 2590 -99 ct +p ef +2907 -99 m 2962 -107 l 2965 -85 2973 -68 2988 -57 ct 3002 -45 3022 -39 3047 -39 ct +3073 -39 3092 -44 3104 -55 ct 3116 -65 3123 -77 3123 -91 ct 3123 -104 3117 -114 3106 -121 ct +3099 -126 3080 -132 3049 -140 ct 3008 -150 2980 -159 2964 -167 ct 2948 -174 2936 -185 2928 -198 ct +2920 -211 2916 -226 2916 -242 ct 2916 -257 2919 -270 2926 -283 ct 2933 -295 2942 -306 2953 -314 ct +2962 -320 2974 -326 2989 -330 ct 3004 -335 3020 -337 3037 -337 ct 3063 -337 3086 -333 3105 -326 ct +3125 -318 3139 -308 3148 -296 ct 3158 -283 3164 -266 3168 -245 ct 3113 -237 l +3111 -254 3103 -267 3091 -277 ct 3080 -286 3063 -291 3041 -291 ct 3015 -291 2997 -287 2986 -278 ct +2975 -270 2970 -260 2970 -249 ct 2970 -241 2972 -235 2977 -229 ct 2981 -223 2988 -218 2998 -214 ct +3004 -212 3020 -207 3047 -200 ct 3087 -189 3114 -181 3130 -174 ct 3146 -167 3158 -158 3167 -145 ct +3176 -132 3180 -116 3180 -97 ct 3180 -79 3175 -61 3164 -45 ct 3153 -28 3137 -15 3117 -6 ct +3096 3 3073 7 3047 7 ct 3005 7 2972 -2 2949 -20 ct 2927 -37 2913 -64 2907 -99 ct +p ef +3226 -165 m 3226 -226 3243 -271 3277 -301 ct 3305 -325 3340 -337 3381 -337 ct +3426 -337 3463 -322 3491 -293 ct 3520 -263 3535 -222 3535 -170 ct 3535 -127 3528 -94 3516 -70 ct +3503 -45 3484 -27 3460 -13 ct 3436 0 3409 7 3381 7 ct 3334 7 3297 -8 3269 -37 ct +3240 -67 3226 -110 3226 -165 ct p +3283 -165 m 3283 -123 3293 -91 3311 -70 ct 3329 -49 3353 -39 3381 -39 ct 3408 -39 3431 -49 3450 -71 ct +3468 -92 3477 -124 3477 -167 ct 3477 -208 3468 -239 3449 -260 ct 3431 -281 3408 -291 3381 -291 ct +3353 -291 3329 -281 3311 -260 ct 3293 -239 3283 -207 3283 -165 ct p ef +3597 0 m 3597 -330 l 3647 -330 l 3647 -280 l 3660 -303 3672 -318 3683 -326 ct +3694 -333 3706 -337 3719 -337 ct 3738 -337 3757 -331 3776 -319 ct 3757 -267 l +3743 -275 3730 -279 3716 -279 ct 3704 -279 3693 -276 3683 -268 ct 3673 -261 3666 -251 3662 -238 ct +3656 -218 3653 -196 3653 -173 ct 3653 0 l 3597 0 l p ef +pom +gr +gr +4400 13500 m 2900 13500 l 2900 12000 l 5900 12000 l 5900 13500 l 4400 13500 l +pc +gs +gs +pum +3122 12970 t +49 0 m 49 -455 l 220 -455 l 251 -455 274 -454 290 -451 ct 312 -447 331 -440 346 -429 ct +361 -419 373 -404 382 -385 ct 391 -367 396 -346 396 -323 ct 396 -285 384 -252 359 -225 ct +334 -198 290 -185 226 -185 ct 109 -185 l 109 0 l 49 0 l p +109 -239 m 227 -239 l 266 -239 293 -246 309 -260 ct 326 -275 334 -295 334 -322 ct +334 -341 329 -357 320 -370 ct 310 -384 297 -393 282 -397 ct 271 -400 253 -401 225 -401 ct +109 -401 l 109 -239 l p ef +464 0 m 464 -455 l 519 -455 l 519 0 l 464 0 l p ef +820 -41 m 799 -24 779 -11 760 -4 ct 741 3 720 7 699 7 ct 662 7 635 -2 615 -20 ct +596 -37 586 -60 586 -87 ct 586 -103 590 -118 597 -131 ct 604 -145 614 -156 626 -164 ct +638 -172 651 -178 666 -182 ct 677 -185 693 -188 716 -190 ct 761 -196 794 -202 815 -209 ct +815 -217 815 -222 815 -224 ct 815 -247 810 -263 800 -272 ct 785 -285 764 -291 736 -291 ct +710 -291 690 -286 678 -277 ct 665 -268 656 -252 650 -228 ct 596 -236 l 601 -259 609 -278 620 -292 ct +631 -307 648 -318 669 -326 ct 691 -333 716 -337 744 -337 ct 772 -337 795 -334 813 -327 ct +830 -321 843 -312 851 -302 ct 860 -292 865 -280 869 -264 ct 871 -255 872 -238 872 -213 ct +872 -138 l 872 -87 873 -54 875 -40 ct 877 -26 882 -13 889 0 ct 831 0 l 825 -12 821 -26 820 -41 ct +p +815 -166 m 795 -157 764 -150 724 -145 ct 701 -141 685 -138 675 -133 ct 666 -129 658 -123 653 -115 ct +648 -107 645 -99 645 -89 ct 645 -74 651 -62 662 -52 ct 674 -42 690 -37 712 -37 ct +733 -37 752 -41 769 -51 ct 786 -60 798 -73 806 -89 ct 812 -102 815 -121 815 -145 ct +815 -166 l p ef +953 127 m 947 75 l 959 78 970 80 979 80 ct 992 80 1001 78 1009 73 ct 1016 69 1022 64 1027 56 ct +1031 51 1036 37 1044 15 ct 1045 11 1047 7 1049 1 ct 924 -330 l 984 -330 l 1053 -139 l +1062 -114 1070 -89 1077 -62 ct 1083 -88 1091 -113 1100 -137 ct 1170 -330 l 1226 -330 l +1101 6 l 1087 42 1077 67 1069 81 ct 1059 99 1048 113 1035 121 ct 1022 130 1007 134 989 134 ct +979 134 967 132 953 127 ct p ef +1316 0 m 1265 0 l 1265 -455 l 1320 -455 l 1320 -293 l 1344 -322 1374 -337 1411 -337 ct +1431 -337 1450 -333 1468 -325 ct 1486 -317 1501 -305 1513 -290 ct 1524 -276 1534 -258 1540 -237 ct +1547 -216 1550 -194 1550 -170 ct 1550 -114 1536 -70 1508 -39 ct 1480 -8 1447 7 1408 7 ct +1369 7 1338 -9 1316 -42 ct 1316 0 l p +1316 -167 m 1316 -128 1321 -100 1332 -82 ct 1349 -53 1373 -39 1403 -39 ct 1428 -39 1449 -50 1466 -71 ct +1484 -92 1493 -123 1493 -165 ct 1493 -208 1485 -240 1467 -260 ct 1450 -281 1430 -291 1406 -291 ct +1381 -291 1360 -281 1342 -259 ct 1325 -238 1316 -208 1316 -167 ct p ef +1832 -41 m 1811 -24 1791 -11 1772 -4 ct 1753 3 1732 7 1711 7 ct 1674 7 1647 -2 1627 -20 ct +1608 -37 1598 -60 1598 -87 ct 1598 -103 1602 -118 1609 -131 ct 1616 -145 1626 -156 1638 -164 ct +1650 -172 1663 -178 1678 -182 ct 1689 -185 1705 -188 1728 -190 ct 1773 -196 1806 -202 1827 -209 ct +1827 -217 1827 -222 1827 -224 ct 1827 -247 1822 -263 1812 -272 ct 1797 -285 1776 -291 1748 -291 ct +1722 -291 1702 -286 1690 -277 ct 1677 -268 1668 -252 1662 -228 ct 1608 -236 l +1613 -259 1621 -278 1632 -292 ct 1643 -307 1660 -318 1681 -326 ct 1703 -333 1728 -337 1756 -337 ct +1784 -337 1807 -334 1825 -327 ct 1842 -321 1855 -312 1863 -302 ct 1872 -292 1877 -280 1881 -264 ct +1883 -255 1884 -238 1884 -213 ct 1884 -138 l 1884 -87 1885 -54 1887 -40 ct +1889 -26 1894 -13 1901 0 ct 1843 0 l 1837 -12 1833 -26 1832 -41 ct p +1827 -166 m 1807 -157 1776 -150 1736 -145 ct 1713 -141 1697 -138 1687 -133 ct +1678 -129 1670 -123 1665 -115 ct 1660 -107 1657 -99 1657 -89 ct 1657 -74 1663 -62 1674 -52 ct +1686 -42 1702 -37 1724 -37 ct 1745 -37 1764 -41 1781 -51 ct 1798 -60 1810 -73 1818 -89 ct +1824 -102 1827 -121 1827 -145 ct 1827 -166 l p ef +2183 -121 m 2238 -114 l 2232 -76 2216 -46 2192 -25 ct 2167 -4 2137 7 2101 7 ct +2056 7 2019 -8 1992 -37 ct 1965 -67 1951 -109 1951 -164 ct 1951 -199 1957 -230 1968 -257 ct +1980 -284 1998 -304 2022 -317 ct 2046 -330 2073 -337 2101 -337 ct 2137 -337 2166 -328 2189 -310 ct +2211 -292 2226 -266 2232 -233 ct 2178 -224 l 2173 -247 2164 -263 2151 -274 ct +2138 -286 2122 -291 2103 -291 ct 2075 -291 2052 -281 2035 -261 ct 2017 -241 2008 -209 2008 -165 ct +2008 -121 2017 -89 2034 -69 ct 2051 -49 2073 -39 2100 -39 ct 2122 -39 2140 -46 2155 -59 ct +2170 -72 2179 -93 2183 -121 ct p ef +2286 0 m 2286 -455 l 2342 -455 l 2342 -196 l 2474 -330 l 2546 -330 l +2420 -207 l 2559 0 l 2490 0 l 2381 -169 l 2342 -131 l 2342 0 l 2286 0 l +p ef +pom +gr +gr +22600 9500 m 21100 9500 l 21100 8000 l 24100 8000 l 24100 9500 l 22600 9500 l +pc +gs +gs +pum +21425 8974 t +50 0 m 50 -455 l 379 -455 l 379 -401 l 110 -401 l 110 -262 l 362 -262 l +362 -209 l 110 -209 l 110 -54 l 389 -54 l 389 0 l 50 0 l p ef +465 0 m 465 -330 l 515 -330 l 515 -283 l 539 -319 574 -337 620 -337 ct +640 -337 658 -333 675 -326 ct 691 -319 704 -310 712 -298 ct 720 -287 726 -273 729 -257 ct +731 -247 732 -229 732 -203 ct 732 0 l 677 0 l 677 -200 l 677 -223 674 -240 670 -252 ct +666 -263 658 -272 647 -279 ct 636 -285 623 -289 608 -289 ct 584 -289 564 -281 547 -266 ct +529 -251 521 -222 521 -180 ct 521 0 l 465 0 l p ef +1032 -121 m 1087 -114 l 1081 -76 1065 -46 1041 -25 ct 1016 -4 986 7 950 7 ct +905 7 868 -8 841 -37 ct 814 -67 800 -109 800 -164 ct 800 -199 806 -230 817 -257 ct +829 -284 847 -304 871 -317 ct 895 -330 922 -337 950 -337 ct 986 -337 1015 -328 1038 -310 ct +1060 -292 1075 -266 1081 -233 ct 1027 -224 l 1022 -247 1013 -263 1000 -274 ct +987 -286 971 -291 952 -291 ct 924 -291 901 -281 884 -261 ct 866 -241 857 -209 857 -165 ct +857 -121 866 -89 883 -69 ct 900 -49 922 -39 949 -39 ct 971 -39 989 -46 1004 -59 ct +1019 -72 1028 -93 1032 -121 ct p ef +1113 -165 m 1113 -226 1130 -271 1164 -301 ct 1192 -325 1227 -337 1268 -337 ct +1313 -337 1350 -322 1378 -293 ct 1407 -263 1422 -222 1422 -170 ct 1422 -127 1415 -94 1403 -70 ct +1390 -45 1371 -27 1347 -13 ct 1323 0 1296 7 1268 7 ct 1221 7 1184 -8 1156 -37 ct +1127 -67 1113 -110 1113 -165 ct p +1170 -165 m 1170 -123 1180 -91 1198 -70 ct 1216 -49 1240 -39 1268 -39 ct 1295 -39 1318 -49 1337 -71 ct +1355 -92 1364 -124 1364 -167 ct 1364 -208 1355 -239 1336 -260 ct 1318 -281 1295 -291 1268 -291 ct +1240 -291 1216 -281 1198 -260 ct 1180 -239 1170 -207 1170 -165 ct p ef +1699 0 m 1699 -42 l 1679 -9 1648 7 1607 7 ct 1581 7 1557 0 1535 -15 ct 1513 -29 1496 -49 1484 -75 ct +1472 -101 1466 -131 1466 -165 ct 1466 -198 1471 -228 1482 -254 ct 1493 -281 1510 -302 1531 -316 ct +1553 -330 1578 -337 1605 -337 ct 1625 -337 1642 -333 1658 -325 ct 1673 -316 1686 -305 1696 -292 ct +1696 -455 l 1751 -455 l 1751 0 l 1699 0 l p +1523 -165 m 1523 -123 1532 -91 1550 -70 ct 1568 -49 1588 -39 1613 -39 ct 1637 -39 1658 -49 1675 -69 ct +1692 -89 1700 -119 1700 -160 ct 1700 -205 1692 -238 1674 -259 ct 1657 -280 1636 -291 1610 -291 ct +1585 -291 1565 -281 1548 -261 ct 1531 -240 1523 -208 1523 -165 ct p ef +2062 -107 m 2120 -99 l 2111 -66 2094 -40 2069 -21 ct 2045 -2 2013 7 1975 7 ct +1927 7 1889 -8 1861 -37 ct 1832 -67 1818 -109 1818 -162 ct 1818 -218 1833 -261 1861 -291 ct +1890 -322 1927 -337 1972 -337 ct 2016 -337 2052 -322 2080 -292 ct 2108 -262 2122 -220 2122 -166 ct +2122 -163 2122 -158 2121 -151 ct 1876 -151 l 1878 -115 1888 -87 1907 -68 ct +1925 -49 1948 -39 1975 -39 ct 1996 -39 2013 -44 2028 -55 ct 2042 -66 2054 -83 2062 -107 ct +p +1879 -197 m 2063 -197 l 2060 -225 2053 -245 2042 -259 ct 2024 -280 2001 -291 1973 -291 ct +1947 -291 1925 -283 1908 -265 ct 1891 -248 1881 -226 1879 -197 ct p ef +2187 0 m 2187 -330 l 2237 -330 l 2237 -280 l 2250 -303 2262 -318 2273 -326 ct +2284 -333 2296 -337 2309 -337 ct 2328 -337 2347 -331 2366 -319 ct 2347 -267 l +2333 -275 2320 -279 2306 -279 ct 2294 -279 2283 -276 2273 -268 ct 2263 -261 2256 -251 2252 -238 ct +2246 -218 2243 -196 2243 -173 ct 2243 0 l 2187 0 l p ef +pom +gr +gr +17400 13500 m 15900 13500 l 15900 12000 l 18900 12000 l 18900 13500 l +17400 13500 l pc +gs +gs +pum +16195 12970 t +49 0 m 49 -455 l 206 -455 l 241 -455 268 -453 287 -448 ct 313 -442 335 -432 353 -416 ct +377 -396 395 -370 407 -338 ct 419 -307 425 -271 425 -230 ct 425 -195 421 -165 413 -138 ct +405 -111 394 -89 382 -72 ct 369 -54 355 -41 340 -31 ct 325 -21 307 -13 286 -8 ct +265 -3 241 0 213 0 ct 49 0 l p +109 -54 m 206 -54 l 236 -54 260 -56 277 -62 ct 294 -68 307 -76 318 -86 ct +332 -100 343 -119 351 -143 ct 359 -167 363 -197 363 -231 ct 363 -279 355 -315 339 -341 ct +324 -366 305 -383 282 -392 ct 266 -398 240 -401 205 -401 ct 109 -401 l 109 -54 l +p ef +724 -107 m 782 -99 l 773 -66 756 -40 731 -21 ct 707 -2 675 7 637 7 ct 589 7 551 -8 523 -37 ct +494 -67 480 -109 480 -162 ct 480 -218 495 -261 523 -291 ct 552 -322 589 -337 634 -337 ct +678 -337 714 -322 742 -292 ct 770 -262 784 -220 784 -166 ct 784 -163 784 -158 783 -151 ct +538 -151 l 540 -115 550 -87 569 -68 ct 587 -49 610 -39 637 -39 ct 658 -39 675 -44 690 -55 ct +704 -66 716 -83 724 -107 ct p +541 -197 m 725 -197 l 722 -225 715 -245 704 -259 ct 686 -280 663 -291 635 -291 ct +609 -291 587 -283 570 -265 ct 553 -248 543 -226 541 -197 ct p ef +1066 -121 m 1121 -114 l 1115 -76 1099 -46 1075 -25 ct 1050 -4 1020 7 984 7 ct +939 7 902 -8 875 -37 ct 848 -67 834 -109 834 -164 ct 834 -199 840 -230 851 -257 ct +863 -284 881 -304 905 -317 ct 929 -330 956 -337 984 -337 ct 1020 -337 1049 -328 1072 -310 ct +1094 -292 1109 -266 1115 -233 ct 1061 -224 l 1056 -247 1047 -263 1034 -274 ct +1021 -286 1005 -291 986 -291 ct 958 -291 935 -281 918 -261 ct 900 -241 891 -209 891 -165 ct +891 -121 900 -89 917 -69 ct 934 -49 956 -39 983 -39 ct 1005 -39 1023 -46 1038 -59 ct +1053 -72 1062 -93 1066 -121 ct p ef +1147 -165 m 1147 -226 1164 -271 1198 -301 ct 1226 -325 1261 -337 1302 -337 ct +1347 -337 1384 -322 1412 -293 ct 1441 -263 1456 -222 1456 -170 ct 1456 -127 1449 -94 1437 -70 ct +1424 -45 1405 -27 1381 -13 ct 1357 0 1330 7 1302 7 ct 1255 7 1218 -8 1190 -37 ct +1161 -67 1147 -110 1147 -165 ct p +1204 -165 m 1204 -123 1214 -91 1232 -70 ct 1250 -49 1274 -39 1302 -39 ct 1329 -39 1352 -49 1371 -71 ct +1389 -92 1398 -124 1398 -167 ct 1398 -208 1389 -239 1370 -260 ct 1352 -281 1329 -291 1302 -291 ct +1274 -291 1250 -281 1232 -260 ct 1214 -239 1204 -207 1204 -165 ct p ef +1732 0 m 1732 -42 l 1712 -9 1681 7 1640 7 ct 1614 7 1590 0 1568 -15 ct 1546 -29 1529 -49 1517 -75 ct +1505 -101 1499 -131 1499 -165 ct 1499 -198 1504 -228 1515 -254 ct 1526 -281 1543 -302 1564 -316 ct +1586 -330 1611 -337 1638 -337 ct 1658 -337 1675 -333 1691 -325 ct 1706 -316 1719 -305 1729 -292 ct +1729 -455 l 1784 -455 l 1784 0 l 1732 0 l p +1556 -165 m 1556 -123 1565 -91 1583 -70 ct 1601 -49 1621 -39 1646 -39 ct 1670 -39 1691 -49 1708 -69 ct +1725 -89 1733 -119 1733 -160 ct 1733 -205 1725 -238 1707 -259 ct 1690 -280 1669 -291 1643 -291 ct +1618 -291 1598 -281 1581 -261 ct 1564 -240 1556 -208 1556 -165 ct p ef +2096 -107 m 2154 -99 l 2145 -66 2128 -40 2103 -21 ct 2079 -2 2047 7 2009 7 ct +1961 7 1923 -8 1895 -37 ct 1866 -67 1852 -109 1852 -162 ct 1852 -218 1867 -261 1895 -291 ct +1924 -322 1961 -337 2006 -337 ct 2050 -337 2086 -322 2114 -292 ct 2142 -262 2156 -220 2156 -166 ct +2156 -163 2156 -158 2155 -151 ct 1910 -151 l 1912 -115 1922 -87 1941 -68 ct +1959 -49 1982 -39 2009 -39 ct 2030 -39 2047 -44 2062 -55 ct 2076 -66 2088 -83 2096 -107 ct +p +1913 -197 m 2097 -197 l 2094 -225 2087 -245 2076 -259 ct 2058 -280 2035 -291 2007 -291 ct +1981 -291 1959 -283 1942 -265 ct 1925 -248 1915 -226 1913 -197 ct p ef +2221 0 m 2221 -330 l 2271 -330 l 2271 -280 l 2284 -303 2296 -318 2307 -326 ct +2318 -333 2330 -337 2343 -337 ct 2362 -337 2381 -331 2400 -319 ct 2381 -267 l +2367 -275 2354 -279 2340 -279 ct 2328 -279 2317 -276 2307 -268 ct 2297 -261 2290 -251 2286 -238 ct +2280 -218 2277 -196 2277 -173 ct 2277 0 l 2221 0 l p ef +pom +gr +gr +22600 13500 m 21100 13500 l 21100 12000 l 24100 12000 l 24100 13500 l +22600 13500 l pc +gs +gs +pum +21916 12626 t +18 -129 m 73 -136 l 74 -102 81 -78 92 -65 ct 104 -52 120 -46 140 -46 ct 155 -46 168 -49 179 -56 ct +190 -63 198 -72 202 -84 ct 206 -96 208 -115 208 -141 ct 208 -455 l 268 -455 l +268 -145 l 268 -107 264 -77 254 -56 ct 245 -35 231 -19 211 -8 ct 191 3 167 8 140 8 ct +101 8 70 -3 49 -26 ct 28 -49 17 -84 18 -129 ct p ef +360 -391 m 360 -455 l 416 -455 l 416 -391 l 360 -391 l p +360 0 m 360 -330 l 416 -330 l 416 0 l 360 0 l p ef +621 -50 m 629 -1 l 613 2 599 4 587 4 ct 566 4 551 1 539 -6 ct 528 -12 520 -20 516 -31 ct +511 -41 509 -63 509 -97 ct 509 -287 l 468 -287 l 468 -330 l 509 -330 l +509 -412 l 565 -445 l 565 -330 l 621 -330 l 621 -287 l 565 -287 l +565 -94 l 565 -78 566 -68 568 -63 ct 570 -58 573 -55 577 -52 ct 582 -49 588 -48 596 -48 ct +602 -48 611 -49 621 -50 ct p ef +799 -50 m 807 -1 l 791 2 777 4 765 4 ct 744 4 729 1 717 -6 ct 706 -12 698 -20 694 -31 ct +689 -41 687 -63 687 -97 ct 687 -287 l 646 -287 l 646 -330 l 687 -330 l +687 -412 l 743 -445 l 743 -330 l 799 -330 l 799 -287 l 743 -287 l +743 -94 l 743 -78 744 -68 746 -63 ct 748 -58 751 -55 755 -52 ct 760 -49 766 -48 774 -48 ct +780 -48 789 -49 799 -50 ct p ef +1080 -107 m 1138 -99 l 1129 -66 1112 -40 1087 -21 ct 1063 -2 1031 7 993 7 ct +945 7 907 -8 879 -37 ct 850 -67 836 -109 836 -162 ct 836 -218 851 -261 879 -291 ct +908 -322 945 -337 990 -337 ct 1034 -337 1070 -322 1098 -292 ct 1126 -262 1140 -220 1140 -166 ct +1140 -163 1140 -158 1139 -151 ct 894 -151 l 896 -115 906 -87 925 -68 ct 943 -49 966 -39 993 -39 ct +1014 -39 1031 -44 1046 -55 ct 1060 -66 1072 -83 1080 -107 ct p +897 -197 m 1081 -197 l 1078 -225 1071 -245 1060 -259 ct 1042 -280 1019 -291 991 -291 ct +965 -291 943 -283 926 -265 ct 909 -248 899 -226 897 -197 ct p ef +1205 0 m 1205 -330 l 1255 -330 l 1255 -280 l 1268 -303 1280 -318 1291 -326 ct +1302 -333 1314 -337 1327 -337 ct 1346 -337 1365 -331 1384 -319 ct 1365 -267 l +1351 -275 1338 -279 1324 -279 ct 1312 -279 1301 -276 1291 -268 ct 1281 -261 1274 -251 1270 -238 ct +1264 -218 1261 -196 1261 -173 ct 1261 0 l 1205 0 l p ef +pom +gr +gs +pum +21764 13337 t +47 0 m 47 -455 l 217 -455 l 252 -455 280 -450 301 -441 ct 322 -432 338 -418 350 -399 ct +362 -380 368 -359 368 -339 ct 368 -319 362 -301 352 -284 ct 341 -266 325 -253 304 -242 ct +332 -234 353 -220 368 -201 ct 382 -181 390 -158 390 -132 ct 390 -111 385 -91 376 -72 ct +367 -54 356 -40 343 -30 ct 330 -20 313 -13 293 -8 ct 273 -3 249 0 220 0 ct 47 0 l +p +107 -264 m 205 -264 l 232 -264 251 -265 262 -269 ct 278 -274 289 -281 297 -292 ct +305 -302 309 -315 309 -331 ct 309 -347 305 -360 298 -371 ct 290 -383 280 -391 267 -395 ct +253 -399 230 -401 198 -401 ct 107 -401 l 107 -264 l p +107 -54 m 220 -54 l 239 -54 253 -54 261 -56 ct 275 -58 286 -62 295 -68 ct +305 -74 312 -82 318 -94 ct 324 -105 327 -117 327 -132 ct 327 -149 323 -164 314 -176 ct +306 -189 294 -197 278 -202 ct 263 -207 241 -210 212 -210 ct 107 -210 l 107 -54 l +p ef +681 0 m 681 -49 l 655 -12 620 7 576 7 ct 557 7 539 3 522 -4 ct 505 -12 492 -21 484 -32 ct +476 -44 470 -57 467 -74 ct 465 -85 464 -102 464 -126 ct 464 -330 l 519 -330 l +519 -147 l 519 -118 521 -98 523 -88 ct 526 -74 534 -62 545 -54 ct 557 -45 571 -41 587 -41 ct +604 -41 620 -45 634 -54 ct 649 -63 660 -74 666 -89 ct 672 -104 675 -125 675 -153 ct +675 -330 l 731 -330 l 731 0 l 681 0 l p ef +830 0 m 830 -286 l 781 -286 l 781 -329 l 830 -329 l 830 -364 l 830 -387 832 -403 836 -414 ct +841 -428 851 -440 864 -449 ct 878 -458 897 -462 921 -462 ct 937 -462 954 -460 973 -457 ct +965 -408 l 953 -410 943 -411 932 -411 ct 915 -411 903 -407 896 -400 ct 889 -393 886 -379 886 -360 ct +886 -329 l 950 -329 l 950 -286 l 886 -286 l 886 0 l 830 0 l p ef +995 0 m 995 -286 l 946 -286 l 946 -329 l 995 -329 l 995 -364 l 995 -387 997 -403 1001 -414 ct +1006 -428 1016 -440 1029 -449 ct 1043 -458 1062 -462 1086 -462 ct 1102 -462 1119 -460 1138 -457 ct +1130 -408 l 1118 -410 1108 -411 1097 -411 ct 1080 -411 1068 -407 1061 -400 ct +1054 -393 1051 -379 1051 -360 ct 1051 -329 l 1115 -329 l 1115 -286 l 1051 -286 l +1051 0 l 995 0 l p ef +1385 -107 m 1443 -99 l 1434 -66 1417 -40 1392 -21 ct 1368 -2 1336 7 1298 7 ct +1250 7 1212 -8 1184 -37 ct 1155 -67 1141 -109 1141 -162 ct 1141 -218 1156 -261 1184 -291 ct +1213 -322 1250 -337 1295 -337 ct 1339 -337 1375 -322 1403 -292 ct 1431 -262 1445 -220 1445 -166 ct +1445 -163 1445 -158 1444 -151 ct 1199 -151 l 1201 -115 1211 -87 1230 -68 ct +1248 -49 1271 -39 1298 -39 ct 1319 -39 1336 -44 1351 -55 ct 1365 -66 1377 -83 1385 -107 ct +p +1202 -197 m 1386 -197 l 1383 -225 1376 -245 1365 -259 ct 1347 -280 1324 -291 1296 -291 ct +1270 -291 1248 -283 1231 -265 ct 1214 -248 1204 -226 1202 -197 ct p ef +1510 0 m 1510 -330 l 1560 -330 l 1560 -280 l 1573 -303 1585 -318 1596 -326 ct +1607 -333 1619 -337 1632 -337 ct 1651 -337 1670 -331 1689 -319 ct 1670 -267 l +1656 -275 1643 -279 1629 -279 ct 1617 -279 1606 -276 1596 -268 ct 1586 -261 1579 -251 1575 -238 ct +1569 -218 1566 -196 1566 -173 ct 1566 0 l 1510 0 l p ef +pom +gr +gr +7100 8750 m 6538 8938 l 6538 8563 l 7100 8750 l p ef +5900 8725 m 6650 8725 l 6650 8775 l 5900 8775 l 5900 8725 l p ef +15400 8750 m 14838 8938 l 14838 8563 l 15400 8750 l p ef +14300 8725 m 14950 8725 l 14950 8775 l 14300 8775 l 14300 8725 l p ef +21100 8750 m 20538 8938 l 20538 8563 l 21100 8750 l p ef +19800 8725 m 20650 8725 l 20650 8775 l 19800 8775 l 19800 8725 l p ef +10500 12750 m 11063 12563 l 11063 12938 l 10500 12750 l p ef +15900 12775 m 10950 12775 l 10950 12725 l 15900 12725 l 15900 12775 l +p ef +18900 12750 m 19463 12563 l 19463 12938 l 18900 12750 l p ef +21100 12775 m 19350 12775 l 19350 12725 l 21100 12725 l 21100 12775 l +p ef +12850 9500 m 13038 10063 l 12663 10063 l 12850 9500 l p ef +15900 12775 m 12850 12775 l 12850 12750 l 12850 12725 l 15900 12725 l +15900 12750 l 15900 12775 l p ef +12850 12750 m 12850 12775 l 12846 12775 l 12841 12773 l 12838 12772 l +12834 12769 l 12831 12766 l 12828 12763 l 12827 12759 l 12825 12754 l +12825 12750 l 12825 12750 l 12850 12750 l p ef +12825 12750 m 12825 9950 l 12850 9950 l 12875 9950 l 12875 12750 l +12850 12750 l 12825 12750 l p ef +1225 13350 m 1000 13350 l 1000 12150 l 1450 12150 l 1450 13350 l 1225 13350 l +pc +500 14050 m 500 11549 l 1001 12175 l 1001 13425 l 500 14050 l pc +1450 12750 m 2013 12563 l 2013 12938 l 1450 12750 l p ef +2900 12775 m 1900 12775 l 1900 12725 l 2900 12725 l 2900 12775 l p ef +24100 12750 m 24663 12563 l 24663 12938 l 24100 12750 l p ef +25100 12775 m 24550 12775 l 24550 12725 l 25100 12725 l 25100 12775 l +p ef +25100 8750 m 24538 8938 l 24538 8563 l 25100 8750 l p ef +24100 8725 m 24650 8725 l 24650 8775 l 24100 8775 l 24100 8725 l p ef +1000 9250 m 724 9250 500 9026 500 8750 ct 500 8474 724 8250 1000 8250 ct 1276 8250 1500 8474 1500 8750 ct +1500 9026 1276 9250 1000 9250 ct pc +500 8250 m 500 9250 l ps +2900 8750 m 2338 8938 l 2338 8563 l 2900 8750 l p ef +1500 8724 m 2200 8724 l 2200 8749 l 2200 8774 l 1500 8774 l 1500 8749 l +1500 8724 l p ef +2200 8749 m 2200 8724 l 2204 8724 l 2209 8726 l 2212 8727 l 2216 8730 l +2219 8733 l 2222 8736 l 2223 8740 l 2225 8745 l 2225 8749 l 2225 8749 l +2200 8749 l p ef +2225 8749 m 2225 8750 l 2200 8750 l 2175 8750 l 2175 8749 l 2200 8749 l +2225 8749 l p ef +2200 8750 m 2200 8775 l 2196 8775 l 2191 8773 l 2188 8772 l 2184 8769 l +2181 8766 l 2178 8763 l 2177 8759 l 2175 8754 l 2175 8750 l 2175 8750 l +2200 8750 l p ef +2200 8725 m 2450 8725 l 2450 8750 l 2450 8775 l 2200 8775 l 2200 8750 l +2200 8725 l p ef +4400 9500 m 4588 10063 l 4213 10063 l 4400 9500 l p ef +4400 12000 m 4213 11438 l 4588 11438 l 4400 12000 l p ef +4425 9950 m 4425 11550 l 4375 11550 l 4375 9950 l 4425 9950 l p ef +8698 9525 m 8647 9525 l 8647 9475 l 8698 9475 l 8698 9525 l p ef +8596 9525 m 8545 9525 l 8545 9475 l 8596 9475 l 8596 9525 l p ef +8494 9525 m 8443 9525 l 8443 9475 l 8494 9475 l 8494 9525 l p ef +8392 9525 m 8341 9525 l 8341 9475 l 8392 9475 l 8392 9525 l p ef +8290 9525 m 8239 9525 l 8239 9475 l 8290 9475 l 8290 9525 l p ef +8188 9525 m 8137 9525 l 8137 9475 l 8188 9475 l 8188 9525 l p ef +8086 9525 m 8035 9525 l 8035 9475 l 8086 9475 l 8086 9525 l p ef +7984 9525 m 7933 9525 l 7933 9475 l 7984 9475 l 7984 9525 l p ef +7882 9525 m 7831 9525 l 7831 9475 l 7882 9475 l 7882 9525 l p ef +7780 9525 m 7729 9525 l 7729 9475 l 7780 9475 l 7780 9525 l p ef +7678 9525 m 7627 9525 l 7627 9475 l 7678 9475 l 7678 9525 l p ef +7576 9525 m 7525 9525 l 7525 9475 l 7576 9475 l 7576 9525 l p ef +7474 9525 m 7423 9525 l 7423 9475 l 7474 9475 l 7474 9525 l p ef +7372 9525 m 7321 9525 l 7321 9475 l 7372 9475 l 7372 9525 l p ef +7270 9525 m 7219 9525 l 7219 9475 l 7270 9475 l 7270 9525 l p ef +7168 9525 m 7117 9525 l 7117 9475 l 7168 9475 l 7168 9525 l p ef +7075 9466 m 7075 9415 l 7125 9415 l 7125 9466 l 7075 9466 l p ef +7075 9364 m 7075 9313 l 7125 9313 l 7125 9364 l 7075 9364 l p ef +7075 9262 m 7075 9211 l 7125 9211 l 7125 9262 l 7075 9262 l p ef +7075 9160 m 7075 9109 l 7125 9109 l 7125 9160 l 7075 9160 l p ef +7075 9058 m 7075 9007 l 7125 9007 l 7125 9058 l 7075 9058 l p ef +7075 8956 m 7075 8905 l 7125 8905 l 7125 8956 l 7075 8956 l p ef +7075 8854 m 7075 8803 l 7125 8803 l 7125 8854 l 7075 8854 l p ef +7075 8752 m 7075 8701 l 7125 8701 l 7125 8752 l 7075 8752 l p ef +7075 8650 m 7075 8599 l 7125 8599 l 7125 8650 l 7075 8650 l p ef +7075 8548 m 7075 8497 l 7125 8497 l 7125 8548 l 7075 8548 l p ef +7075 8446 m 7075 8395 l 7125 8395 l 7125 8446 l 7075 8446 l p ef +7075 8344 m 7075 8293 l 7125 8293 l 7125 8344 l 7075 8344 l p ef +7075 8242 m 7075 8191 l 7125 8191 l 7125 8242 l 7075 8242 l p ef +7075 8140 m 7075 8089 l 7125 8089 l 7125 8140 l 7075 8140 l p ef +7075 8038 m 7075 8000 l 7100 8000 l 7125 8000 l 7125 8038 l 7100 8038 l +7075 8038 l p ef +7100 8000 m 7075 8000 l 7075 7996 l 7077 7991 l 7078 7988 l 7081 7984 l +7084 7981 l 7087 7978 l 7091 7977 l 7096 7975 l 7100 7975 l 7100 7975 l +7100 8000 l p ef +7100 7975 m 7113 7975 l 7113 8000 l 7113 8025 l 7100 8025 l 7100 8000 l +7100 7975 l p ef +7164 7975 m 7215 7975 l 7215 8025 l 7164 8025 l 7164 7975 l p ef +7266 7975 m 7317 7975 l 7317 8025 l 7266 8025 l 7266 7975 l p ef +7368 7975 m 7419 7975 l 7419 8025 l 7368 8025 l 7368 7975 l p ef +7470 7975 m 7521 7975 l 7521 8025 l 7470 8025 l 7470 7975 l p ef +7572 7975 m 7623 7975 l 7623 8025 l 7572 8025 l 7572 7975 l p ef +7674 7975 m 7725 7975 l 7725 8025 l 7674 8025 l 7674 7975 l p ef +7776 7975 m 7827 7975 l 7827 8025 l 7776 8025 l 7776 7975 l p ef +7878 7975 m 7929 7975 l 7929 8025 l 7878 8025 l 7878 7975 l p ef +7980 7975 m 8031 7975 l 8031 8025 l 7980 8025 l 7980 7975 l p ef +8082 7975 m 8133 7975 l 8133 8025 l 8082 8025 l 8082 7975 l p ef +8184 7975 m 8235 7975 l 8235 8025 l 8184 8025 l 8184 7975 l p ef +8286 7975 m 8337 7975 l 8337 8025 l 8286 8025 l 8286 7975 l p ef +8388 7975 m 8439 7975 l 8439 8025 l 8388 8025 l 8388 7975 l p ef +8490 7975 m 8541 7975 l 8541 8025 l 8490 8025 l 8490 7975 l p ef +8592 7975 m 8643 7975 l 8643 8025 l 8592 8025 l 8592 7975 l p ef +8694 7975 m 8745 7975 l 8745 8025 l 8694 8025 l 8694 7975 l p ef +8796 7975 m 8847 7975 l 8847 8025 l 8796 8025 l 8796 7975 l p ef +8898 7975 m 8949 7975 l 8949 8025 l 8898 8025 l 8898 7975 l p ef +9000 7975 m 9051 7975 l 9051 8025 l 9000 8025 l 9000 7975 l p ef +9102 7975 m 9153 7975 l 9153 8025 l 9102 8025 l 9102 7975 l p ef +9204 7975 m 9255 7975 l 9255 8025 l 9204 8025 l 9204 7975 l p ef +9306 7975 m 9357 7975 l 9357 8025 l 9306 8025 l 9306 7975 l p ef +9408 7975 m 9459 7975 l 9459 8025 l 9408 8025 l 9408 7975 l p ef +9510 7975 m 9561 7975 l 9561 8025 l 9510 8025 l 9510 7975 l p ef +9612 7975 m 9663 7975 l 9663 8025 l 9612 8025 l 9612 7975 l p ef +9714 7975 m 9765 7975 l 9765 8025 l 9714 8025 l 9714 7975 l p ef +9816 7975 m 9867 7975 l 9867 8025 l 9816 8025 l 9816 7975 l p ef +9918 7975 m 9969 7975 l 9969 8025 l 9918 8025 l 9918 7975 l p ef +10020 7975 m 10071 7975 l 10071 8025 l 10020 8025 l 10020 7975 l p ef +10122 7975 m 10173 7975 l 10173 8025 l 10122 8025 l 10122 7975 l p ef +10224 7975 m 10275 7975 l 10275 8025 l 10224 8025 l 10224 7975 l p ef +10326 7975 m 10377 7975 l 10377 8025 l 10326 8025 l 10326 7975 l p ef +10428 7975 m 10479 7975 l 10479 8025 l 10428 8025 l 10428 7975 l p ef +10525 8030 m 10525 8081 l 10475 8081 l 10475 8030 l 10525 8030 l p ef +10525 8132 m 10525 8183 l 10475 8183 l 10475 8132 l 10525 8132 l p ef +10525 8234 m 10525 8285 l 10475 8285 l 10475 8234 l 10525 8234 l p ef +10525 8336 m 10525 8387 l 10475 8387 l 10475 8336 l 10525 8336 l p ef +10525 8438 m 10525 8489 l 10475 8489 l 10475 8438 l 10525 8438 l p ef +10525 8540 m 10525 8591 l 10475 8591 l 10475 8540 l 10525 8540 l p ef +10525 8642 m 10525 8693 l 10475 8693 l 10475 8642 l 10525 8642 l p ef +10525 8744 m 10525 8795 l 10475 8795 l 10475 8744 l 10525 8744 l p ef +10525 8846 m 10525 8897 l 10475 8897 l 10475 8846 l 10525 8846 l p ef +10525 8948 m 10525 8999 l 10475 8999 l 10475 8948 l 10525 8948 l p ef +10525 9050 m 10525 9101 l 10475 9101 l 10475 9050 l 10525 9050 l p ef +10525 9152 m 10525 9203 l 10475 9203 l 10475 9152 l 10525 9152 l p ef +10525 9254 m 10525 9305 l 10475 9305 l 10475 9254 l 10525 9254 l p ef +10525 9356 m 10525 9407 l 10475 9407 l 10475 9356 l 10525 9356 l p ef +10525 9458 m 10525 9500 l 10500 9500 l 10475 9500 l 10475 9458 l 10500 9458 l +10525 9458 l p ef +10500 9500 m 10525 9500 l 10525 9504 l 10523 9509 l 10522 9512 l 10519 9516 l +10516 9519 l 10513 9522 l 10509 9523 l 10504 9525 l 10500 9525 l 10500 9525 l +10500 9500 l p ef +10500 9525 m 10491 9525 l 10491 9500 l 10491 9475 l 10500 9475 l 10500 9500 l +10500 9525 l p ef +10440 9525 m 10389 9525 l 10389 9475 l 10440 9475 l 10440 9525 l p ef +10338 9525 m 10287 9525 l 10287 9475 l 10338 9475 l 10338 9525 l p ef +10236 9525 m 10185 9525 l 10185 9475 l 10236 9475 l 10236 9525 l p ef +10134 9525 m 10083 9525 l 10083 9475 l 10134 9475 l 10134 9525 l p ef +10032 9525 m 9981 9525 l 9981 9475 l 10032 9475 l 10032 9525 l p ef +9930 9525 m 9879 9525 l 9879 9475 l 9930 9475 l 9930 9525 l p ef +9828 9525 m 9777 9525 l 9777 9475 l 9828 9475 l 9828 9525 l p ef +9726 9525 m 9675 9525 l 9675 9475 l 9726 9475 l 9726 9525 l p ef +9624 9525 m 9573 9525 l 9573 9475 l 9624 9475 l 9624 9525 l p ef +9522 9525 m 9471 9525 l 9471 9475 l 9522 9475 l 9522 9525 l p ef +9420 9525 m 9369 9525 l 9369 9475 l 9420 9475 l 9420 9525 l p ef +9318 9525 m 9267 9525 l 9267 9475 l 9318 9475 l 9318 9525 l p ef +9216 9525 m 9165 9525 l 9165 9475 l 9216 9475 l 9216 9525 l p ef +9114 9525 m 9063 9525 l 9063 9475 l 9114 9475 l 9114 9525 l p ef +9012 9525 m 8961 9525 l 8961 9475 l 9012 9475 l 9012 9525 l p ef +8910 9525 m 8859 9525 l 8859 9475 l 8910 9475 l 8910 9525 l p ef +8808 9525 m 8800 9525 l 8800 9500 l 8800 9475 l 8808 9475 l 8808 9500 l +8808 9525 l p ef +8800 9525 m 8749 9525 l 8749 9500 l 8749 9475 l 8800 9475 l 8800 9500 l +8800 9525 l p ef +gs +gs +pum +7276 8974 t +50 0 m 50 -455 l 251 -455 l 292 -455 323 -451 344 -443 ct 365 -435 382 -420 394 -399 ct +407 -379 413 -356 413 -331 ct 413 -299 403 -271 382 -249 ct 361 -227 329 -213 285 -207 ct +301 -199 313 -192 322 -184 ct 339 -168 356 -148 371 -124 ct 451 0 l 375 0 l +315 -95 l 297 -122 283 -143 271 -157 ct 260 -172 250 -182 241 -188 ct 232 -194 223 -198 213 -200 ct +207 -201 195 -202 180 -202 ct 110 -202 l 110 0 l 50 0 l p +110 -254 m 239 -254 l 267 -254 288 -257 304 -263 ct 319 -268 331 -277 339 -290 ct +347 -303 351 -316 351 -331 ct 351 -352 344 -370 328 -384 ct 312 -398 288 -405 254 -405 ct +110 -405 l 110 -254 l p ef +724 -107 m 782 -99 l 773 -66 756 -40 731 -21 ct 707 -2 675 7 637 7 ct 589 7 551 -8 523 -37 ct +494 -67 480 -109 480 -162 ct 480 -218 495 -261 523 -291 ct 552 -322 589 -337 634 -337 ct +678 -337 714 -322 742 -292 ct 770 -262 784 -220 784 -166 ct 784 -163 784 -158 783 -151 ct +538 -151 l 540 -115 550 -87 569 -68 ct 587 -49 610 -39 637 -39 ct 658 -39 675 -44 690 -55 ct +704 -66 716 -83 724 -107 ct p +541 -197 m 725 -197 l 722 -225 715 -245 704 -259 ct 686 -280 663 -291 635 -291 ct +609 -291 587 -283 570 -265 ct 553 -248 543 -226 541 -197 ct p ef +829 -99 m 884 -107 l 887 -85 895 -68 910 -57 ct 924 -45 944 -39 969 -39 ct +995 -39 1014 -44 1026 -55 ct 1038 -65 1045 -77 1045 -91 ct 1045 -104 1039 -114 1028 -121 ct +1021 -126 1002 -132 971 -140 ct 930 -150 902 -159 886 -167 ct 870 -174 858 -185 850 -198 ct +842 -211 838 -226 838 -242 ct 838 -257 841 -270 848 -283 ct 855 -295 864 -306 875 -314 ct +884 -320 896 -326 911 -330 ct 926 -335 942 -337 959 -337 ct 985 -337 1008 -333 1027 -326 ct +1047 -318 1061 -308 1070 -296 ct 1080 -283 1086 -266 1090 -245 ct 1035 -237 l +1033 -254 1025 -267 1013 -277 ct 1002 -286 985 -291 963 -291 ct 937 -291 919 -287 908 -278 ct +897 -270 892 -260 892 -249 ct 892 -241 894 -235 899 -229 ct 903 -223 910 -218 920 -214 ct +926 -212 942 -207 969 -200 ct 1009 -189 1036 -181 1052 -174 ct 1068 -167 1080 -158 1089 -145 ct +1098 -132 1102 -116 1102 -97 ct 1102 -79 1097 -61 1086 -45 ct 1075 -28 1059 -15 1039 -6 ct +1018 3 995 7 969 7 ct 927 7 894 -2 871 -20 ct 849 -37 835 -64 829 -99 ct p ef +1383 -41 m 1362 -24 1342 -11 1323 -4 ct 1304 3 1283 7 1262 7 ct 1225 7 1198 -2 1178 -20 ct +1159 -37 1149 -60 1149 -87 ct 1149 -103 1153 -118 1160 -131 ct 1167 -145 1177 -156 1189 -164 ct +1201 -172 1214 -178 1229 -182 ct 1240 -185 1256 -188 1279 -190 ct 1324 -196 1357 -202 1378 -209 ct +1378 -217 1378 -222 1378 -224 ct 1378 -247 1373 -263 1363 -272 ct 1348 -285 1327 -291 1299 -291 ct +1273 -291 1253 -286 1241 -277 ct 1228 -268 1219 -252 1213 -228 ct 1159 -236 l +1164 -259 1172 -278 1183 -292 ct 1194 -307 1211 -318 1232 -326 ct 1254 -333 1279 -337 1307 -337 ct +1335 -337 1358 -334 1376 -327 ct 1393 -321 1406 -312 1414 -302 ct 1423 -292 1428 -280 1432 -264 ct +1434 -255 1435 -238 1435 -213 ct 1435 -138 l 1435 -87 1436 -54 1438 -40 ct +1440 -26 1445 -13 1452 0 ct 1394 0 l 1388 -12 1384 -26 1383 -41 ct p +1378 -166 m 1358 -157 1327 -150 1287 -145 ct 1264 -141 1248 -138 1238 -133 ct +1229 -129 1221 -123 1216 -115 ct 1211 -107 1208 -99 1208 -89 ct 1208 -74 1214 -62 1225 -52 ct +1237 -42 1253 -37 1275 -37 ct 1296 -37 1315 -41 1332 -51 ct 1349 -60 1361 -73 1369 -89 ct +1375 -102 1378 -121 1378 -145 ct 1378 -166 l p ef +1519 0 m 1519 -330 l 1569 -330 l 1569 -283 l 1579 -299 1593 -312 1610 -322 ct +1627 -332 1647 -337 1669 -337 ct 1693 -337 1713 -332 1729 -322 ct 1744 -312 1755 -297 1762 -279 ct +1788 -318 1822 -337 1863 -337 ct 1896 -337 1921 -328 1939 -310 ct 1956 -292 1965 -264 1965 -226 ct +1965 0 l 1910 0 l 1910 -208 l 1910 -230 1908 -246 1904 -256 ct 1901 -266 1894 -274 1884 -280 ct +1875 -286 1864 -289 1851 -289 ct 1828 -289 1809 -281 1793 -265 ct 1778 -250 1770 -225 1770 -191 ct +1770 0 l 1715 0 l 1715 -214 l 1715 -239 1710 -258 1701 -270 ct 1692 -282 1677 -289 1656 -289 ct +1641 -289 1626 -284 1613 -276 ct 1599 -268 1590 -256 1584 -240 ct 1578 -224 1575 -201 1575 -171 ct +1575 0 l 1519 0 l p ef +2049 126 m 2049 -330 l 2100 -330 l 2100 -287 l 2112 -304 2125 -316 2140 -324 ct +2155 -333 2174 -337 2195 -337 ct 2223 -337 2248 -330 2270 -315 ct 2291 -301 2307 -280 2318 -254 ct +2329 -228 2335 -199 2335 -167 ct 2335 -134 2329 -103 2317 -77 ct 2305 -50 2287 -29 2264 -15 ct +2241 0 2217 7 2191 7 ct 2173 7 2156 3 2141 -5 ct 2126 -13 2114 -23 2105 -35 ct +2105 126 l 2049 126 l p +2099 -163 m 2099 -121 2108 -90 2125 -69 ct 2142 -49 2163 -39 2187 -39 ct 2212 -39 2234 -49 2251 -70 ct +2269 -91 2278 -124 2278 -168 ct 2278 -210 2269 -241 2252 -262 ct 2235 -283 2214 -293 2190 -293 ct +2166 -293 2145 -282 2127 -260 ct 2109 -238 2099 -205 2099 -163 ct p ef +2399 0 m 2399 -455 l 2454 -455 l 2454 0 l 2399 0 l p ef +2765 -107 m 2823 -99 l 2814 -66 2797 -40 2772 -21 ct 2748 -2 2716 7 2678 7 ct +2630 7 2592 -8 2564 -37 ct 2535 -67 2521 -109 2521 -162 ct 2521 -218 2536 -261 2564 -291 ct +2593 -322 2630 -337 2675 -337 ct 2719 -337 2755 -322 2783 -292 ct 2811 -262 2825 -220 2825 -166 ct +2825 -163 2825 -158 2824 -151 ct 2579 -151 l 2581 -115 2591 -87 2610 -68 ct +2628 -49 2651 -39 2678 -39 ct 2699 -39 2716 -44 2731 -55 ct 2745 -66 2757 -83 2765 -107 ct +p +2582 -197 m 2766 -197 l 2763 -225 2756 -245 2745 -259 ct 2727 -280 2704 -291 2676 -291 ct +2650 -291 2628 -283 2611 -265 ct 2594 -248 2584 -226 2582 -197 ct p ef +2890 0 m 2890 -330 l 2940 -330 l 2940 -280 l 2953 -303 2965 -318 2976 -326 ct +2987 -333 2999 -337 3012 -337 ct 3031 -337 3050 -331 3069 -319 ct 3050 -267 l +3036 -275 3023 -279 3009 -279 ct 2997 -279 2986 -276 2976 -268 ct 2966 -261 2959 -251 2955 -238 ct +2949 -218 2946 -196 2946 -173 ct 2946 0 l 2890 0 l p ef +pom +gr +gr +11400 8750 m 10838 8938 l 10838 8563 l 11400 8750 l p ef +10500 8725 m 10950 8725 l 10950 8775 l 10500 8775 l 10500 8725 l p ef +8698 13525 m 8647 13525 l 8647 13475 l 8698 13475 l 8698 13525 l p ef +8596 13525 m 8545 13525 l 8545 13475 l 8596 13475 l 8596 13525 l p ef +8494 13525 m 8443 13525 l 8443 13475 l 8494 13475 l 8494 13525 l p ef +8392 13525 m 8341 13525 l 8341 13475 l 8392 13475 l 8392 13525 l p ef +8290 13525 m 8239 13525 l 8239 13475 l 8290 13475 l 8290 13525 l p ef +8188 13525 m 8137 13525 l 8137 13475 l 8188 13475 l 8188 13525 l p ef +8086 13525 m 8035 13525 l 8035 13475 l 8086 13475 l 8086 13525 l p ef +7984 13525 m 7933 13525 l 7933 13475 l 7984 13475 l 7984 13525 l p ef +7882 13525 m 7831 13525 l 7831 13475 l 7882 13475 l 7882 13525 l p ef +7780 13525 m 7729 13525 l 7729 13475 l 7780 13475 l 7780 13525 l p ef +7678 13525 m 7627 13525 l 7627 13475 l 7678 13475 l 7678 13525 l p ef +7576 13525 m 7525 13525 l 7525 13475 l 7576 13475 l 7576 13525 l p ef +7474 13525 m 7423 13525 l 7423 13475 l 7474 13475 l 7474 13525 l p ef +7372 13525 m 7321 13525 l 7321 13475 l 7372 13475 l 7372 13525 l p ef +7270 13525 m 7219 13525 l 7219 13475 l 7270 13475 l 7270 13525 l p ef +7168 13525 m 7117 13525 l 7117 13475 l 7168 13475 l 7168 13525 l p ef +7075 13466 m 7075 13415 l 7125 13415 l 7125 13466 l 7075 13466 l p ef +7075 13364 m 7075 13313 l 7125 13313 l 7125 13364 l 7075 13364 l p ef +7075 13262 m 7075 13211 l 7125 13211 l 7125 13262 l 7075 13262 l p ef +7075 13160 m 7075 13109 l 7125 13109 l 7125 13160 l 7075 13160 l p ef +7075 13058 m 7075 13007 l 7125 13007 l 7125 13058 l 7075 13058 l p ef +7075 12956 m 7075 12905 l 7125 12905 l 7125 12956 l 7075 12956 l p ef +7075 12854 m 7075 12803 l 7125 12803 l 7125 12854 l 7075 12854 l p ef +7075 12752 m 7075 12701 l 7125 12701 l 7125 12752 l 7075 12752 l p ef +7075 12650 m 7075 12599 l 7125 12599 l 7125 12650 l 7075 12650 l p ef +7075 12548 m 7075 12497 l 7125 12497 l 7125 12548 l 7075 12548 l p ef +7075 12446 m 7075 12395 l 7125 12395 l 7125 12446 l 7075 12446 l p ef +7075 12344 m 7075 12293 l 7125 12293 l 7125 12344 l 7075 12344 l p ef +7075 12242 m 7075 12191 l 7125 12191 l 7125 12242 l 7075 12242 l p ef +7075 12140 m 7075 12089 l 7125 12089 l 7125 12140 l 7075 12140 l p ef +7075 12038 m 7075 12000 l 7100 12000 l 7125 12000 l 7125 12038 l 7100 12038 l +7075 12038 l p ef +7100 12000 m 7075 12000 l 7075 11996 l 7077 11991 l 7078 11988 l 7081 11984 l +7084 11981 l 7087 11978 l 7091 11977 l 7096 11975 l 7100 11975 l 7100 11975 l +7100 12000 l p ef +7100 11975 m 7113 11975 l 7113 12000 l 7113 12025 l 7100 12025 l 7100 12000 l +7100 11975 l p ef +7164 11975 m 7215 11975 l 7215 12025 l 7164 12025 l 7164 11975 l p ef +7266 11975 m 7317 11975 l 7317 12025 l 7266 12025 l 7266 11975 l p ef +7368 11975 m 7419 11975 l 7419 12025 l 7368 12025 l 7368 11975 l p ef +7470 11975 m 7521 11975 l 7521 12025 l 7470 12025 l 7470 11975 l p ef +7572 11975 m 7623 11975 l 7623 12025 l 7572 12025 l 7572 11975 l p ef +7674 11975 m 7725 11975 l 7725 12025 l 7674 12025 l 7674 11975 l p ef +7776 11975 m 7827 11975 l 7827 12025 l 7776 12025 l 7776 11975 l p ef +7878 11975 m 7929 11975 l 7929 12025 l 7878 12025 l 7878 11975 l p ef +7980 11975 m 8031 11975 l 8031 12025 l 7980 12025 l 7980 11975 l p ef +8082 11975 m 8133 11975 l 8133 12025 l 8082 12025 l 8082 11975 l p ef +8184 11975 m 8235 11975 l 8235 12025 l 8184 12025 l 8184 11975 l p ef +8286 11975 m 8337 11975 l 8337 12025 l 8286 12025 l 8286 11975 l p ef +8388 11975 m 8439 11975 l 8439 12025 l 8388 12025 l 8388 11975 l p ef +8490 11975 m 8541 11975 l 8541 12025 l 8490 12025 l 8490 11975 l p ef +8592 11975 m 8643 11975 l 8643 12025 l 8592 12025 l 8592 11975 l p ef +8694 11975 m 8745 11975 l 8745 12025 l 8694 12025 l 8694 11975 l p ef +8796 11975 m 8847 11975 l 8847 12025 l 8796 12025 l 8796 11975 l p ef +8898 11975 m 8949 11975 l 8949 12025 l 8898 12025 l 8898 11975 l p ef +9000 11975 m 9051 11975 l 9051 12025 l 9000 12025 l 9000 11975 l p ef +9102 11975 m 9153 11975 l 9153 12025 l 9102 12025 l 9102 11975 l p ef +9204 11975 m 9255 11975 l 9255 12025 l 9204 12025 l 9204 11975 l p ef +9306 11975 m 9357 11975 l 9357 12025 l 9306 12025 l 9306 11975 l p ef +9408 11975 m 9459 11975 l 9459 12025 l 9408 12025 l 9408 11975 l p ef +9510 11975 m 9561 11975 l 9561 12025 l 9510 12025 l 9510 11975 l p ef +9612 11975 m 9663 11975 l 9663 12025 l 9612 12025 l 9612 11975 l p ef +9714 11975 m 9765 11975 l 9765 12025 l 9714 12025 l 9714 11975 l p ef +9816 11975 m 9867 11975 l 9867 12025 l 9816 12025 l 9816 11975 l p ef +9918 11975 m 9969 11975 l 9969 12025 l 9918 12025 l 9918 11975 l p ef +10020 11975 m 10071 11975 l 10071 12025 l 10020 12025 l 10020 11975 l +p ef +10122 11975 m 10173 11975 l 10173 12025 l 10122 12025 l 10122 11975 l +p ef +10224 11975 m 10275 11975 l 10275 12025 l 10224 12025 l 10224 11975 l +p ef +10326 11975 m 10377 11975 l 10377 12025 l 10326 12025 l 10326 11975 l +p ef +10428 11975 m 10479 11975 l 10479 12025 l 10428 12025 l 10428 11975 l +p ef +10525 12030 m 10525 12081 l 10475 12081 l 10475 12030 l 10525 12030 l +p ef +10525 12132 m 10525 12183 l 10475 12183 l 10475 12132 l 10525 12132 l +p ef +10525 12234 m 10525 12285 l 10475 12285 l 10475 12234 l 10525 12234 l +p ef +10525 12336 m 10525 12387 l 10475 12387 l 10475 12336 l 10525 12336 l +p ef +10525 12438 m 10525 12489 l 10475 12489 l 10475 12438 l 10525 12438 l +p ef +10525 12540 m 10525 12591 l 10475 12591 l 10475 12540 l 10525 12540 l +p ef +10525 12642 m 10525 12693 l 10475 12693 l 10475 12642 l 10525 12642 l +p ef +10525 12744 m 10525 12795 l 10475 12795 l 10475 12744 l 10525 12744 l +p ef +10525 12846 m 10525 12897 l 10475 12897 l 10475 12846 l 10525 12846 l +p ef +10525 12948 m 10525 12999 l 10475 12999 l 10475 12948 l 10525 12948 l +p ef +10525 13050 m 10525 13101 l 10475 13101 l 10475 13050 l 10525 13050 l +p ef +10525 13152 m 10525 13203 l 10475 13203 l 10475 13152 l 10525 13152 l +p ef +10525 13254 m 10525 13305 l 10475 13305 l 10475 13254 l 10525 13254 l +p ef +10525 13356 m 10525 13407 l 10475 13407 l 10475 13356 l 10525 13356 l +p ef +10525 13458 m 10525 13500 l 10500 13500 l 10475 13500 l 10475 13458 l +10500 13458 l 10525 13458 l p ef +10500 13500 m 10525 13500 l 10525 13504 l 10523 13509 l 10522 13512 l +10519 13516 l 10516 13519 l 10513 13522 l 10509 13523 l 10504 13525 l +10500 13525 l 10500 13525 l 10500 13500 l p ef +10500 13525 m 10491 13525 l 10491 13500 l 10491 13475 l 10500 13475 l +10500 13500 l 10500 13525 l p ef +10440 13525 m 10389 13525 l 10389 13475 l 10440 13475 l 10440 13525 l +p ef +10338 13525 m 10287 13525 l 10287 13475 l 10338 13475 l 10338 13525 l +p ef +10236 13525 m 10185 13525 l 10185 13475 l 10236 13475 l 10236 13525 l +p ef +10134 13525 m 10083 13525 l 10083 13475 l 10134 13475 l 10134 13525 l +p ef +10032 13525 m 9981 13525 l 9981 13475 l 10032 13475 l 10032 13525 l +p ef +9930 13525 m 9879 13525 l 9879 13475 l 9930 13475 l 9930 13525 l p ef +9828 13525 m 9777 13525 l 9777 13475 l 9828 13475 l 9828 13525 l p ef +9726 13525 m 9675 13525 l 9675 13475 l 9726 13475 l 9726 13525 l p ef +9624 13525 m 9573 13525 l 9573 13475 l 9624 13475 l 9624 13525 l p ef +9522 13525 m 9471 13525 l 9471 13475 l 9522 13475 l 9522 13525 l p ef +9420 13525 m 9369 13525 l 9369 13475 l 9420 13475 l 9420 13525 l p ef +9318 13525 m 9267 13525 l 9267 13475 l 9318 13475 l 9318 13525 l p ef +9216 13525 m 9165 13525 l 9165 13475 l 9216 13475 l 9216 13525 l p ef +9114 13525 m 9063 13525 l 9063 13475 l 9114 13475 l 9114 13525 l p ef +9012 13525 m 8961 13525 l 8961 13475 l 9012 13475 l 9012 13525 l p ef +8910 13525 m 8859 13525 l 8859 13475 l 8910 13475 l 8910 13525 l p ef +8808 13525 m 8800 13525 l 8800 13500 l 8800 13475 l 8808 13475 l 8808 13500 l +8808 13525 l p ef +8800 13525 m 8749 13525 l 8749 13500 l 8749 13475 l 8800 13475 l 8800 13500 l +8800 13525 l p ef +gs +gs +pum +7276 12970 t +50 0 m 50 -455 l 251 -455 l 292 -455 323 -451 344 -443 ct 365 -435 382 -420 394 -399 ct +407 -379 413 -356 413 -331 ct 413 -299 403 -271 382 -249 ct 361 -227 329 -213 285 -207 ct +301 -199 313 -192 322 -184 ct 339 -168 356 -148 371 -124 ct 451 0 l 375 0 l +315 -95 l 297 -122 283 -143 271 -157 ct 260 -172 250 -182 241 -188 ct 232 -194 223 -198 213 -200 ct +207 -201 195 -202 180 -202 ct 110 -202 l 110 0 l 50 0 l p +110 -254 m 239 -254 l 267 -254 288 -257 304 -263 ct 319 -268 331 -277 339 -290 ct +347 -303 351 -316 351 -331 ct 351 -352 344 -370 328 -384 ct 312 -398 288 -405 254 -405 ct +110 -405 l 110 -254 l p ef +724 -107 m 782 -99 l 773 -66 756 -40 731 -21 ct 707 -2 675 7 637 7 ct 589 7 551 -8 523 -37 ct +494 -67 480 -109 480 -162 ct 480 -218 495 -261 523 -291 ct 552 -322 589 -337 634 -337 ct +678 -337 714 -322 742 -292 ct 770 -262 784 -220 784 -166 ct 784 -163 784 -158 783 -151 ct +538 -151 l 540 -115 550 -87 569 -68 ct 587 -49 610 -39 637 -39 ct 658 -39 675 -44 690 -55 ct +704 -66 716 -83 724 -107 ct p +541 -197 m 725 -197 l 722 -225 715 -245 704 -259 ct 686 -280 663 -291 635 -291 ct +609 -291 587 -283 570 -265 ct 553 -248 543 -226 541 -197 ct p ef +829 -99 m 884 -107 l 887 -85 895 -68 910 -57 ct 924 -45 944 -39 969 -39 ct +995 -39 1014 -44 1026 -55 ct 1038 -65 1045 -77 1045 -91 ct 1045 -104 1039 -114 1028 -121 ct +1021 -126 1002 -132 971 -140 ct 930 -150 902 -159 886 -167 ct 870 -174 858 -185 850 -198 ct +842 -211 838 -226 838 -242 ct 838 -257 841 -270 848 -283 ct 855 -295 864 -306 875 -314 ct +884 -320 896 -326 911 -330 ct 926 -335 942 -337 959 -337 ct 985 -337 1008 -333 1027 -326 ct +1047 -318 1061 -308 1070 -296 ct 1080 -283 1086 -266 1090 -245 ct 1035 -237 l +1033 -254 1025 -267 1013 -277 ct 1002 -286 985 -291 963 -291 ct 937 -291 919 -287 908 -278 ct +897 -270 892 -260 892 -249 ct 892 -241 894 -235 899 -229 ct 903 -223 910 -218 920 -214 ct +926 -212 942 -207 969 -200 ct 1009 -189 1036 -181 1052 -174 ct 1068 -167 1080 -158 1089 -145 ct +1098 -132 1102 -116 1102 -97 ct 1102 -79 1097 -61 1086 -45 ct 1075 -28 1059 -15 1039 -6 ct +1018 3 995 7 969 7 ct 927 7 894 -2 871 -20 ct 849 -37 835 -64 829 -99 ct p ef +1383 -41 m 1362 -24 1342 -11 1323 -4 ct 1304 3 1283 7 1262 7 ct 1225 7 1198 -2 1178 -20 ct +1159 -37 1149 -60 1149 -87 ct 1149 -103 1153 -118 1160 -131 ct 1167 -145 1177 -156 1189 -164 ct +1201 -172 1214 -178 1229 -182 ct 1240 -185 1256 -188 1279 -190 ct 1324 -196 1357 -202 1378 -209 ct +1378 -217 1378 -222 1378 -224 ct 1378 -247 1373 -263 1363 -272 ct 1348 -285 1327 -291 1299 -291 ct +1273 -291 1253 -286 1241 -277 ct 1228 -268 1219 -252 1213 -228 ct 1159 -236 l +1164 -259 1172 -278 1183 -292 ct 1194 -307 1211 -318 1232 -326 ct 1254 -333 1279 -337 1307 -337 ct +1335 -337 1358 -334 1376 -327 ct 1393 -321 1406 -312 1414 -302 ct 1423 -292 1428 -280 1432 -264 ct +1434 -255 1435 -238 1435 -213 ct 1435 -138 l 1435 -87 1436 -54 1438 -40 ct +1440 -26 1445 -13 1452 0 ct 1394 0 l 1388 -12 1384 -26 1383 -41 ct p +1378 -166 m 1358 -157 1327 -150 1287 -145 ct 1264 -141 1248 -138 1238 -133 ct +1229 -129 1221 -123 1216 -115 ct 1211 -107 1208 -99 1208 -89 ct 1208 -74 1214 -62 1225 -52 ct +1237 -42 1253 -37 1275 -37 ct 1296 -37 1315 -41 1332 -51 ct 1349 -60 1361 -73 1369 -89 ct +1375 -102 1378 -121 1378 -145 ct 1378 -166 l p ef +1519 0 m 1519 -330 l 1569 -330 l 1569 -283 l 1579 -299 1593 -312 1610 -322 ct +1627 -332 1647 -337 1669 -337 ct 1693 -337 1713 -332 1729 -322 ct 1744 -312 1755 -297 1762 -279 ct +1788 -318 1822 -337 1863 -337 ct 1896 -337 1921 -328 1939 -310 ct 1956 -292 1965 -264 1965 -226 ct +1965 0 l 1910 0 l 1910 -208 l 1910 -230 1908 -246 1904 -256 ct 1901 -266 1894 -274 1884 -280 ct +1875 -286 1864 -289 1851 -289 ct 1828 -289 1809 -281 1793 -265 ct 1778 -250 1770 -225 1770 -191 ct +1770 0 l 1715 0 l 1715 -214 l 1715 -239 1710 -258 1701 -270 ct 1692 -282 1677 -289 1656 -289 ct +1641 -289 1626 -284 1613 -276 ct 1599 -268 1590 -256 1584 -240 ct 1578 -224 1575 -201 1575 -171 ct +1575 0 l 1519 0 l p ef +2049 126 m 2049 -330 l 2100 -330 l 2100 -287 l 2112 -304 2125 -316 2140 -324 ct +2155 -333 2174 -337 2195 -337 ct 2223 -337 2248 -330 2270 -315 ct 2291 -301 2307 -280 2318 -254 ct +2329 -228 2335 -199 2335 -167 ct 2335 -134 2329 -103 2317 -77 ct 2305 -50 2287 -29 2264 -15 ct +2241 0 2217 7 2191 7 ct 2173 7 2156 3 2141 -5 ct 2126 -13 2114 -23 2105 -35 ct +2105 126 l 2049 126 l p +2099 -163 m 2099 -121 2108 -90 2125 -69 ct 2142 -49 2163 -39 2187 -39 ct 2212 -39 2234 -49 2251 -70 ct +2269 -91 2278 -124 2278 -168 ct 2278 -210 2269 -241 2252 -262 ct 2235 -283 2214 -293 2190 -293 ct +2166 -293 2145 -282 2127 -260 ct 2109 -238 2099 -205 2099 -163 ct p ef +2399 0 m 2399 -455 l 2454 -455 l 2454 0 l 2399 0 l p ef +2765 -107 m 2823 -99 l 2814 -66 2797 -40 2772 -21 ct 2748 -2 2716 7 2678 7 ct +2630 7 2592 -8 2564 -37 ct 2535 -67 2521 -109 2521 -162 ct 2521 -218 2536 -261 2564 -291 ct +2593 -322 2630 -337 2675 -337 ct 2719 -337 2755 -322 2783 -292 ct 2811 -262 2825 -220 2825 -166 ct +2825 -163 2825 -158 2824 -151 ct 2579 -151 l 2581 -115 2591 -87 2610 -68 ct +2628 -49 2651 -39 2678 -39 ct 2699 -39 2716 -44 2731 -55 ct 2745 -66 2757 -83 2765 -107 ct +p +2582 -197 m 2766 -197 l 2763 -225 2756 -245 2745 -259 ct 2727 -280 2704 -291 2676 -291 ct +2650 -291 2628 -283 2611 -265 ct 2594 -248 2584 -226 2582 -197 ct p ef +2890 0 m 2890 -330 l 2940 -330 l 2940 -280 l 2953 -303 2965 -318 2976 -326 ct +2987 -333 2999 -337 3012 -337 ct 3031 -337 3050 -331 3069 -319 ct 3050 -267 l +3036 -275 3023 -279 3009 -279 ct 2997 -279 2986 -276 2976 -268 ct 2966 -261 2959 -251 2955 -238 ct +2949 -218 2946 -196 2946 -173 ct 2946 0 l 2890 0 l p ef +pom +gr +gr +5900 12750 m 6463 12563 l 6463 12938 l 5900 12750 l p ef +7100 12775 m 6350 12775 l 6350 12725 l 7100 12725 l 7100 12775 l p ef +gs +gs +pum +25603 12626 t +52 -1 m 52 -455 l 359 -455 l 359 -401 l 112 -401 l 112 -261 l 326 -261 l +326 -207 l 112 -207 l 112 -1 l 52 -1 l p ef +430 0 m 430 -330 l 480 -330 l 480 -280 l 493 -303 505 -318 516 -326 ct +527 -333 539 -337 552 -337 ct 571 -337 590 -331 609 -319 ct 590 -267 l 576 -275 563 -279 549 -279 ct +537 -279 526 -276 516 -268 ct 506 -261 499 -251 495 -238 ct 489 -218 486 -196 486 -173 ct +486 0 l 430 0 l p ef +622 -165 m 622 -226 639 -271 673 -301 ct 701 -325 736 -337 777 -337 ct 822 -337 859 -322 887 -293 ct +916 -263 931 -222 931 -170 ct 931 -127 924 -94 912 -70 ct 899 -45 880 -27 856 -13 ct +832 0 805 7 777 7 ct 730 7 693 -8 665 -37 ct 636 -67 622 -110 622 -165 ct p +679 -165 m 679 -123 689 -91 707 -70 ct 725 -49 749 -39 777 -39 ct 804 -39 827 -49 846 -71 ct +864 -92 873 -124 873 -167 ct 873 -208 864 -239 845 -260 ct 827 -281 804 -291 777 -291 ct +749 -291 725 -281 707 -260 ct 689 -239 679 -207 679 -165 ct p ef +995 0 m 995 -330 l 1045 -330 l 1045 -283 l 1055 -299 1069 -312 1086 -322 ct +1103 -332 1123 -337 1145 -337 ct 1169 -337 1189 -332 1205 -322 ct 1220 -312 1231 -297 1238 -279 ct +1264 -318 1298 -337 1339 -337 ct 1372 -337 1397 -328 1415 -310 ct 1432 -292 1441 -264 1441 -226 ct +1441 0 l 1386 0 l 1386 -208 l 1386 -230 1384 -246 1380 -256 ct 1377 -266 1370 -274 1360 -280 ct +1351 -286 1340 -289 1327 -289 ct 1304 -289 1285 -281 1269 -265 ct 1254 -250 1246 -225 1246 -191 ct +1246 0 l 1191 0 l 1191 -214 l 1191 -239 1186 -258 1177 -270 ct 1168 -282 1153 -289 1132 -289 ct +1117 -289 1102 -284 1089 -276 ct 1075 -268 1066 -256 1060 -240 ct 1054 -224 1051 -201 1051 -171 ct +1051 0 l 995 0 l p ef +pom +gr +gs +pum +25241 13337 t +42 0 m 42 -330 l 92 -330 l 92 -283 l 116 -319 151 -337 197 -337 ct 217 -337 235 -333 252 -326 ct +268 -319 281 -310 289 -298 ct 297 -287 303 -273 306 -257 ct 308 -247 309 -229 309 -203 ct +309 0 l 254 0 l 254 -200 l 254 -223 251 -240 247 -252 ct 243 -263 235 -272 224 -279 ct +213 -285 200 -289 185 -289 ct 161 -289 141 -281 124 -266 ct 106 -251 98 -222 98 -180 ct +98 0 l 42 0 l p ef +618 -107 m 676 -99 l 667 -66 650 -40 625 -21 ct 601 -2 569 7 531 7 ct 483 7 445 -8 417 -37 ct +388 -67 374 -109 374 -162 ct 374 -218 389 -261 417 -291 ct 446 -322 483 -337 528 -337 ct +572 -337 608 -322 636 -292 ct 664 -262 678 -220 678 -166 ct 678 -163 678 -158 677 -151 ct +432 -151 l 434 -115 444 -87 463 -68 ct 481 -49 504 -39 531 -39 ct 552 -39 569 -44 584 -55 ct +598 -66 610 -83 618 -107 ct p +435 -197 m 619 -197 l 616 -225 609 -245 598 -259 ct 580 -280 557 -291 529 -291 ct +503 -291 481 -283 464 -265 ct 447 -248 437 -226 435 -197 ct p ef +867 -50 m 875 -1 l 859 2 845 4 833 4 ct 812 4 797 1 785 -6 ct 774 -12 766 -20 762 -31 ct +757 -41 755 -63 755 -97 ct 755 -287 l 714 -287 l 714 -330 l 755 -330 l +755 -412 l 811 -445 l 811 -330 l 867 -330 l 867 -287 l 811 -287 l +811 -94 l 811 -78 812 -68 814 -63 ct 816 -58 819 -55 823 -52 ct 828 -49 834 -48 842 -48 ct +848 -48 857 -49 867 -50 ct p ef +984 0 m 883 -330 l 941 -330 l 993 -139 l 1012 -69 l 1013 -72 1019 -95 1030 -137 ct +1082 -330 l 1139 -330 l 1189 -138 l 1205 -75 l 1224 -139 l 1280 -330 l +1335 -330 l 1232 0 l 1174 0 l 1121 -197 l 1109 -253 l 1042 0 l 984 0 l +p ef +1346 -165 m 1346 -226 1363 -271 1397 -301 ct 1425 -325 1460 -337 1501 -337 ct +1546 -337 1583 -322 1611 -293 ct 1640 -263 1655 -222 1655 -170 ct 1655 -127 1648 -94 1636 -70 ct +1623 -45 1604 -27 1580 -13 ct 1556 0 1529 7 1501 7 ct 1454 7 1417 -8 1389 -37 ct +1360 -67 1346 -110 1346 -165 ct p +1403 -165 m 1403 -123 1413 -91 1431 -70 ct 1449 -49 1473 -39 1501 -39 ct 1528 -39 1551 -49 1570 -71 ct +1588 -92 1597 -124 1597 -167 ct 1597 -208 1588 -239 1569 -260 ct 1551 -281 1528 -291 1501 -291 ct +1473 -291 1449 -281 1431 -260 ct 1413 -239 1403 -207 1403 -165 ct p ef +1717 0 m 1717 -330 l 1767 -330 l 1767 -280 l 1780 -303 1792 -318 1803 -326 ct +1814 -333 1826 -337 1839 -337 ct 1858 -337 1877 -331 1896 -319 ct 1877 -267 l +1863 -275 1850 -279 1836 -279 ct 1824 -279 1813 -276 1803 -268 ct 1793 -261 1786 -251 1782 -238 ct +1776 -218 1773 -196 1773 -173 ct 1773 0 l 1717 0 l p ef +1930 0 m 1930 -455 l 1986 -455 l 1986 -196 l 2118 -330 l 2190 -330 l +2064 -207 l 2203 0 l 2134 0 l 2025 -169 l 1986 -131 l 1986 0 l 1930 0 l +p ef +pom +gr +gr +gs +gs +pum +26008 8604 t +165 0 m 165 -401 l 15 -401 l 15 -455 l 375 -455 l 375 -401 l 225 -401 l +225 0 l 165 0 l p ef +343 -165 m 343 -226 360 -271 394 -301 ct 422 -325 457 -337 498 -337 ct 543 -337 580 -322 608 -293 ct +637 -263 652 -222 652 -170 ct 652 -127 645 -94 633 -70 ct 620 -45 601 -27 577 -13 ct +553 0 526 7 498 7 ct 451 7 414 -8 386 -37 ct 357 -67 343 -110 343 -165 ct p +400 -165 m 400 -123 410 -91 428 -70 ct 446 -49 470 -39 498 -39 ct 525 -39 548 -49 567 -71 ct +585 -92 594 -124 594 -167 ct 594 -208 585 -239 566 -260 ct 548 -281 525 -291 498 -291 ct +470 -291 446 -281 428 -260 ct 410 -239 400 -207 400 -165 ct p ef +pom +gr +gs +pum +25241 9315 t +42 0 m 42 -330 l 92 -330 l 92 -283 l 116 -319 151 -337 197 -337 ct 217 -337 235 -333 252 -326 ct +268 -319 281 -310 289 -298 ct 297 -287 303 -273 306 -257 ct 308 -247 309 -229 309 -203 ct +309 0 l 254 0 l 254 -200 l 254 -223 251 -240 247 -252 ct 243 -263 235 -272 224 -279 ct +213 -285 200 -289 185 -289 ct 161 -289 141 -281 124 -266 ct 106 -251 98 -222 98 -180 ct +98 0 l 42 0 l p ef +618 -107 m 676 -99 l 667 -66 650 -40 625 -21 ct 601 -2 569 7 531 7 ct 483 7 445 -8 417 -37 ct +388 -67 374 -109 374 -162 ct 374 -218 389 -261 417 -291 ct 446 -322 483 -337 528 -337 ct +572 -337 608 -322 636 -292 ct 664 -262 678 -220 678 -166 ct 678 -163 678 -158 677 -151 ct +432 -151 l 434 -115 444 -87 463 -68 ct 481 -49 504 -39 531 -39 ct 552 -39 569 -44 584 -55 ct +598 -66 610 -83 618 -107 ct p +435 -197 m 619 -197 l 616 -225 609 -245 598 -259 ct 580 -280 557 -291 529 -291 ct +503 -291 481 -283 464 -265 ct 447 -248 437 -226 435 -197 ct p ef +867 -50 m 875 -1 l 859 2 845 4 833 4 ct 812 4 797 1 785 -6 ct 774 -12 766 -20 762 -31 ct +757 -41 755 -63 755 -97 ct 755 -287 l 714 -287 l 714 -330 l 755 -330 l +755 -412 l 811 -445 l 811 -330 l 867 -330 l 867 -287 l 811 -287 l +811 -94 l 811 -78 812 -68 814 -63 ct 816 -58 819 -55 823 -52 ct 828 -49 834 -48 842 -48 ct +848 -48 857 -49 867 -50 ct p ef +984 0 m 883 -330 l 941 -330 l 993 -139 l 1012 -69 l 1013 -72 1019 -95 1030 -137 ct +1082 -330 l 1139 -330 l 1189 -138 l 1205 -75 l 1224 -139 l 1280 -330 l +1335 -330 l 1232 0 l 1174 0 l 1121 -197 l 1109 -253 l 1042 0 l 984 0 l +p ef +1346 -165 m 1346 -226 1363 -271 1397 -301 ct 1425 -325 1460 -337 1501 -337 ct +1546 -337 1583 -322 1611 -293 ct 1640 -263 1655 -222 1655 -170 ct 1655 -127 1648 -94 1636 -70 ct +1623 -45 1604 -27 1580 -13 ct 1556 0 1529 7 1501 7 ct 1454 7 1417 -8 1389 -37 ct +1360 -67 1346 -110 1346 -165 ct p +1403 -165 m 1403 -123 1413 -91 1431 -70 ct 1449 -49 1473 -39 1501 -39 ct 1528 -39 1551 -49 1570 -71 ct +1588 -92 1597 -124 1597 -167 ct 1597 -208 1588 -239 1569 -260 ct 1551 -281 1528 -291 1501 -291 ct +1473 -291 1449 -281 1431 -260 ct 1413 -239 1403 -207 1403 -165 ct p ef +1717 0 m 1717 -330 l 1767 -330 l 1767 -280 l 1780 -303 1792 -318 1803 -326 ct +1814 -333 1826 -337 1839 -337 ct 1858 -337 1877 -331 1896 -319 ct 1877 -267 l +1863 -275 1850 -279 1836 -279 ct 1824 -279 1813 -276 1803 -268 ct 1793 -261 1786 -251 1782 -238 ct +1776 -218 1773 -196 1773 -173 ct 1773 0 l 1717 0 l p ef +1930 0 m 1930 -455 l 1986 -455 l 1986 -196 l 2118 -330 l 2190 -330 l +2064 -207 l 2203 0 l 2134 0 l 2025 -169 l 1986 -131 l 1986 0 l 1930 0 l +p ef +pom +gr +gr +gs +gs +pum +4551 10959 t +29 -146 m 85 -151 l 88 -128 94 -109 104 -95 ct 114 -80 129 -68 150 -59 ct +170 -51 194 -46 220 -46 ct 242 -46 263 -49 280 -56 ct 298 -63 311 -72 320 -84 ct +328 -96 332 -109 332 -123 ct 332 -137 328 -150 320 -161 ct 312 -171 298 -180 279 -187 ct +267 -192 240 -200 198 -210 ct 156 -220 127 -229 110 -238 ct 89 -249 73 -263 62 -280 ct +51 -297 46 -316 46 -337 ct 46 -360 52 -381 65 -401 ct 78 -421 97 -436 122 -447 ct +147 -457 175 -462 206 -462 ct 240 -462 269 -457 295 -446 ct 321 -435 341 -419 354 -398 ct +368 -377 376 -353 377 -326 ct 319 -322 l 316 -351 305 -372 288 -387 ct 270 -402 243 -409 208 -409 ct +172 -409 145 -402 129 -389 ct 112 -376 104 -360 104 -341 ct 104 -324 110 -311 122 -301 ct +133 -290 163 -279 212 -268 ct 261 -257 295 -247 313 -239 ct 339 -227 359 -211 371 -193 ct +384 -174 390 -153 390 -128 ct 390 -104 383 -81 370 -60 ct 356 -38 336 -22 310 -10 ct +284 2 255 8 222 8 ct 181 8 147 2 119 -10 ct 91 -22 69 -40 53 -64 ct 38 -88 29 -115 29 -146 ct +p ef +680 -41 m 659 -24 639 -11 620 -4 ct 601 3 580 7 559 7 ct 522 7 495 -2 475 -20 ct +456 -37 446 -60 446 -87 ct 446 -103 450 -118 457 -131 ct 464 -145 474 -156 486 -164 ct +498 -172 511 -178 526 -182 ct 537 -185 553 -188 576 -190 ct 621 -196 654 -202 675 -209 ct +675 -217 675 -222 675 -224 ct 675 -247 670 -263 660 -272 ct 645 -285 624 -291 596 -291 ct +570 -291 550 -286 538 -277 ct 525 -268 516 -252 510 -228 ct 456 -236 l 461 -259 469 -278 480 -292 ct +491 -307 508 -318 529 -326 ct 551 -333 576 -337 604 -337 ct 632 -337 655 -334 673 -327 ct +690 -321 703 -312 711 -302 ct 720 -292 725 -280 729 -264 ct 731 -255 732 -238 732 -213 ct +732 -138 l 732 -87 733 -54 735 -40 ct 737 -26 742 -13 749 0 ct 691 0 l 685 -12 681 -26 680 -41 ct +p +675 -166 m 655 -157 624 -150 584 -145 ct 561 -141 545 -138 535 -133 ct 526 -129 518 -123 513 -115 ct +508 -107 505 -99 505 -89 ct 505 -74 511 -62 522 -52 ct 534 -42 550 -37 572 -37 ct +593 -37 612 -41 629 -51 ct 646 -60 658 -73 666 -89 ct 672 -102 675 -121 675 -145 ct +675 -166 l p ef +817 0 m 817 -330 l 867 -330 l 867 -283 l 877 -299 891 -312 908 -322 ct +925 -332 945 -337 967 -337 ct 991 -337 1011 -332 1027 -322 ct 1042 -312 1053 -297 1060 -279 ct +1086 -318 1120 -337 1161 -337 ct 1194 -337 1219 -328 1237 -310 ct 1254 -292 1263 -264 1263 -226 ct +1263 0 l 1208 0 l 1208 -208 l 1208 -230 1206 -246 1202 -256 ct 1199 -266 1192 -274 1182 -280 ct +1173 -286 1162 -289 1149 -289 ct 1126 -289 1107 -281 1091 -265 ct 1076 -250 1068 -225 1068 -191 ct +1068 0 l 1013 0 l 1013 -214 l 1013 -239 1008 -258 999 -270 ct 990 -282 975 -289 954 -289 ct +939 -289 924 -284 911 -276 ct 897 -268 888 -256 882 -240 ct 876 -224 873 -201 873 -171 ct +873 0 l 817 0 l p ef +1571 -107 m 1629 -99 l 1620 -66 1603 -40 1578 -21 ct 1554 -2 1522 7 1484 7 ct +1436 7 1398 -8 1370 -37 ct 1341 -67 1327 -109 1327 -162 ct 1327 -218 1342 -261 1370 -291 ct +1399 -322 1436 -337 1481 -337 ct 1525 -337 1561 -322 1589 -292 ct 1617 -262 1631 -220 1631 -166 ct +1631 -163 1631 -158 1630 -151 ct 1385 -151 l 1387 -115 1397 -87 1416 -68 ct +1434 -49 1457 -39 1484 -39 ct 1505 -39 1522 -44 1537 -55 ct 1551 -66 1563 -83 1571 -107 ct +p +1388 -197 m 1572 -197 l 1569 -225 1562 -245 1551 -259 ct 1533 -280 1510 -291 1482 -291 ct +1456 -291 1434 -283 1417 -265 ct 1400 -248 1390 -226 1388 -197 ct p ef +2090 -121 m 2145 -114 l 2139 -76 2123 -46 2099 -25 ct 2074 -4 2044 7 2008 7 ct +1963 7 1926 -8 1899 -37 ct 1872 -67 1858 -109 1858 -164 ct 1858 -199 1864 -230 1875 -257 ct +1887 -284 1905 -304 1929 -317 ct 1953 -330 1980 -337 2008 -337 ct 2044 -337 2073 -328 2096 -310 ct +2118 -292 2133 -266 2139 -233 ct 2085 -224 l 2080 -247 2071 -263 2058 -274 ct +2045 -286 2029 -291 2010 -291 ct 1982 -291 1959 -281 1942 -261 ct 1924 -241 1915 -209 1915 -165 ct +1915 -121 1924 -89 1941 -69 ct 1958 -49 1980 -39 2007 -39 ct 2029 -39 2047 -46 2062 -59 ct +2077 -72 2086 -93 2090 -121 ct p ef +2192 0 m 2192 -455 l 2247 -455 l 2247 0 l 2192 0 l p ef +2311 -165 m 2311 -226 2328 -271 2362 -301 ct 2390 -325 2425 -337 2466 -337 ct +2511 -337 2548 -322 2576 -293 ct 2605 -263 2620 -222 2620 -170 ct 2620 -127 2613 -94 2601 -70 ct +2588 -45 2569 -27 2545 -13 ct 2521 0 2494 7 2466 7 ct 2419 7 2382 -8 2354 -37 ct +2325 -67 2311 -110 2311 -165 ct p +2368 -165 m 2368 -123 2378 -91 2396 -70 ct 2414 -49 2438 -39 2466 -39 ct 2493 -39 2516 -49 2535 -71 ct +2553 -92 2562 -124 2562 -167 ct 2562 -208 2553 -239 2534 -260 ct 2516 -281 2493 -291 2466 -291 ct +2438 -291 2414 -281 2396 -260 ct 2378 -239 2368 -207 2368 -165 ct p ef +2899 -121 m 2954 -114 l 2948 -76 2932 -46 2908 -25 ct 2883 -4 2853 7 2817 7 ct +2772 7 2735 -8 2708 -37 ct 2681 -67 2667 -109 2667 -164 ct 2667 -199 2673 -230 2684 -257 ct +2696 -284 2714 -304 2738 -317 ct 2762 -330 2789 -337 2817 -337 ct 2853 -337 2882 -328 2905 -310 ct +2927 -292 2942 -266 2948 -233 ct 2894 -224 l 2889 -247 2880 -263 2867 -274 ct +2854 -286 2838 -291 2819 -291 ct 2791 -291 2768 -281 2751 -261 ct 2733 -241 2724 -209 2724 -165 ct +2724 -121 2733 -89 2750 -69 ct 2767 -49 2789 -39 2816 -39 ct 2838 -39 2856 -46 2871 -59 ct +2886 -72 2895 -93 2899 -121 ct p ef +3001 0 m 3001 -455 l 3057 -455 l 3057 -196 l 3189 -330 l 3261 -330 l +3135 -207 l 3274 0 l 3205 0 l 3096 -169 l 3057 -131 l 3057 0 l 3001 0 l +p ef +pom +gr +gr +0 6126 t +pom +count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore +%%PageTrailer +%%Trailer +%%EOF diff --git a/src/libs/speexdsp/doc/components.odg b/src/libs/speexdsp/doc/components.odg new file mode 100644 index 00000000..28aa86c9 Binary files /dev/null and b/src/libs/speexdsp/doc/components.odg differ diff --git a/src/libs/speexdsp/doc/draft-herlein-avt-rtp-speex-00.txt b/src/libs/speexdsp/doc/draft-herlein-avt-rtp-speex-00.txt new file mode 100644 index 00000000..36733e95 --- /dev/null +++ b/src/libs/speexdsp/doc/draft-herlein-avt-rtp-speex-00.txt @@ -0,0 +1,699 @@ + + + + +Internet Engineering Task Force Greg Herlein +Internet Draft Jean-Marc Valin +draft-herlein-avt-rtp-speex-00.txt Simon Morlat +March 3, 2004 Roger Hardiman +Expires: September 3, 2004 Phil Kerr + + + RTP Payload Format for the Speex Codec + +Status of this Memo + + This document is an Internet-Draft and is in full conformance with + all provisions of Section 10 of RFC 2026. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF), its areas, and its working groups. Note that + other groups may also distribute working documents as Internet- + Drafts. + + Internet-Drafts are draft documents valid for a maximum of six + months and may be updated, replaced, or obsoleted by other + documents at any time. It is inappropriate to use Internet-Drafts + as reference material or to cite them other than as "work in + progress". + + The list of current Internet-Drafts can be accessed at + http://www.ietf.org/ietf/1id-abstracts.txt + + To view the list Internet-Draft Shadow Directories, see + http://www.ietf.org/shadow.html. + + +Copyright Notice + + Copyright (C) The Internet Society (2003). All Rights Reserved. + + +Abstract + + Speex is an open-source voice codec suitable for use in Voice over + IP (VoIP) type applications. This document describes the payload + format for Speex generated bit streams within an RTP packet. Also + included here are the necessary details for the use of Speex with + the Session Description Protocol (SDP) and a preliminary method of + using Speex within H.323 applications. + + +1. Conventions used in this document + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in RFC 2119 [5]. + +Herlein, Valin, et. al. Expires September 3, 2004 [Page 1] +^L +Internet-Draft draft-herlein-avt-rtp-speex-00.txt March 3, 2004 + + +2. Overview of the Speex Codec + + Speex is based on the CELP [12] encoding technique with support for + either narrowband (nominal 8kHz), wideband (nominal 16kHz) or + ultra-wideband (nominal 32kHz), and (non-optimal) rates up to 48 kHz + sampling also available. The main characteristics can be summarized + as follows: + + o Free software/open-source + o Integration of wideband and narrowband in the same bit-stream + o Wide range of bit-rates available + o Dynamic bit-rate switching and variable bit-rate (VBR) + o Voice Activity Detection (VAD, integrated with VBR) + o Variable complexity + + +3. RTP payload format for Speex + + For RTP based transportation of Speex encoded audio the standard + RTP header [2] is followed by one or more payload data blocks. + An optional padding terminator may also be used. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | one or more frames of Speex .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | one or more frames of Speex .... | padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +3.1 RTP Header + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + The RTP header begins with an octet of fields (V, P, X, and CC) to + support specialized RTP uses (see [8] and [9] for details). For + Speex the following values are used. + +Herlein, Valin, et. al. Expires September 3, 2004 [Page 2] +^L +Internet-Draft draft-herlein-avt-rtp-speex-00.txt March 3, 2004 + + + Version (V): 2 bits + This field identifies the version of RTP. The version + used by this specification is two (2). + + Padding (P): 1 bit + If the padding bit is set, the packet contains one or more + additional padding octets at the end which are not part of + the payload. P is set if the total packet size is less than + the MTU. + + Extension (X): 1 bit + If the extension, X, bit is set, the fixed header MUST be + followed by exactly one header extension, with a format defined + in Section 5.3.1. of [8], + + CSRC count (CC): 4 bits + The CSRC count contains the number of CSRC identifiers. + + Marker (M): 1 bit + The M bit indicates if the packet contains comfort noise. This + field is used in conjunction with the cng SDP attribute and is + detailed further in section 5 below. In normal usage this bit + is set if the packet contains comfort noise. + + Payload Type (PT): 7 bits + An RTP profile for a class of applications is expected to assign + a payload type for this format, or a dynamically allocated + payload type SHOULD be chosen which designates the payload as + Speex. + + Sequence number: 16 bits + The sequence number increments by one for each RTP data packet + sent, and may be used by the receiver to detect packet loss and + to restore packet sequence. This field is detailed further in + [2]. + + Timestamp: 32 bits + A timestamp representing the sampling time of the first sample of + the first Speex packet in the RTP packet. The clock frequency + MUST be set to the sample rate of the encoded audio data. + + Speex uses 20 msec frames and a variable sampling rate clock. + The RTP timestamp MUST be in units of 1/X of a second where X + is the sample rate used. Speex uses a nominal 8kHz sampling rate + for narrowband use, a nominal 16kHz sampling rate for wideband use, + and a nominal 32kHz sampling rate for ultra-wideband use. + + SSRC/CSRC identifiers: + These two fields, 32 bits each with one SSRC field and a maximum + of 16 CSRC fields, are as defined in [2]. + + + +Herlein, Valin, et. al. Expires September 3, 2004 [Page 3] +^L +Internet-Draft draft-herlein-avt-rtp-speex-00.txt March 3, 2004 + + +3.2 Speex payload + + For the purposes of packetizing the bit stream in RTP, it is only + necessary to consider the sequence of bits as output by the Speex + encoder [11], and present the same sequence to the decoder. The + payload format described here maintains this sequence. + + A typical Speex frame, encoded at the maximum bitrate, is approx. + 110 octets and the total number of Speex frames SHOULD be kept + less than the path MTU to prevent fragmentation. Speex frames MUST + NOT be fragmented across multiple RTP packets, + + An RTP packet MAY contain Speex frames of the same bit rate or of + varying bit rates, since the bit-rate for a frame is conveyed in + band with the signal. + + The encoding and decoding algorithm can change the bit rate at any + 20 msec frame boundary, with the bit rate change notification provided + in-band with the bit stream. Each frame contains both "mode" + (narrowband, wideband or ultra-wideband) and "sub-mode" (bit-rate) + information in the bit stream. No out-of-band notification is + required for the decoder to process changes in the bit rate sent + by the encoder. + + It is RECOMMENDED that values of 8000, 16000 and 32000 be used + for normal internet telephony applications, though the sample + rate is supported at rates as low as 6000 Hz and as high as + 48 kHz. + + The RTP payload MUST be padded to provide an integer number of + octets as the payload length. These padding bits are LSB aligned + in network byte order and consist of a 0 followed by all ones + (until the end of the octet). This padding is only required for + the last frame in the packet, and only to ensure the packet + contents ends on an octet boundary. + + +3.2.1 Example Speex packet + + In the example below we have a single Speex frame with 5 bits + of padding to ensure the packet size falls on an octet boundary. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + + +Herlein, Valin, et. al. Expires September 3, 2004 [Page 4] +^L +Internet-Draft draft-herlein-avt-rtp-speex-00.txt March 3, 2004 + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. |0 1 1 1 1| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +3.4 Multiple Speex frames in a RTP packet + + Below is an example of two Speex frames contained within one RTP + packet. The Speex frame length in this example fall on an octet + boundary so there is no padding. + + Speex codecs [11] are able to detect the the bitrate from the + payload and are responsible for detecting the 20 msec boundaries + between each frame. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +4. MIME registration of Speex + + Full definition of the MIME type for Speex will be part of the Ogg + Vorbis MIME type definition application [10]. + + MIME media type name: audio + + MIME subtype: speex + +Herlein, Valin, et. al. Expires September 3, 2004 [Page 5] +^L +Internet-Draft draft-herlein-avt-rtp-speex-00.txt March 3, 2004 + + + Optional parameters: + + Required parameters: to be included in the Ogg MIME specification. + + Encoding considerations: + + Security Considerations: + See Section 6 of RFC 3047. + + Interoperability considerations: none + + Published specification: + + Applications which use this media type: + + Additional information: none + + Person & email address to contact for further information: + Greg Herlein <gherlein@herlein.com> + Jean-Marc Valin <jean-marc.valin@hermes.usherb.ca> + + Intended usage: COMMON + + Author/Change controller: + Author: Greg Herlein <gherlein@herlein.com> + Change controller: Greg Herlein <gherlein@herlein.com> + + This transport type signifies that the content is to be interpreted + according to this document if the contents are transmitted over RTP. + Should this transport type appear over a lossless streaming protocol + such as TCP, the content encapsulation should be interpreted as an + Ogg Stream in accordance with RFC 3534, with the exception that the + content of the Ogg Stream may be assumed to be Speex audio and + Speex audio only. + + +5. SDP usage of Speex + + When conveying information by SDP [4], the encoding name MUST be + set to "speex". An example of the media representation in SDP for + offering a single channel of Speex at 8000 samples per second might + be: + + m=audio 8088 RTP/AVP 97 + a=rtpmap:97 speex/8000 + + Note that the RTP payload type code of 97 is defined in this media + definition to be 'mapped' to the speex codec at an 8kHz sampling + frequency using the 'a=rtpmap' line. Any number from 96 to 127 + could have been chosen (the allowed range for dynamic types). + + + +Herlein, Valin, et. al. Expires September 3, 2004 [Page 6] +^L +Internet-Draft draft-herlein-avt-rtp-speex-00.txt March 3, 2004 + + + The value of the sampling frequency is typically 8000 for narrow band + operation, 16000 for wide band operation, and 32000 for ultra-wide + band operation. + + If for some reason the offerer has bandwidth limitations, the client + may use the "b=" header, as explained in SDP [4]. The following example + illustrates the case where the offerer cannot receive more than + 10 kbit/s. + + m=audio 8088 RTP/AVP 97 + b=AS:10 + a=rtmap:97 speex/8000 + + In this case, if the remote part agrees, it should configure its + Speex encoder so that it does not use modes that produce more than + 10 kbit/s. Note that the "b=" constraint also applies on all + payload types that may be proposed in the media line ("m="). + + An other way to make recommendations to the remote Speex encoder + is to use its specific parameters via the a=fmtp: directive. The + following parameters are defined for use in this way: + + ptime: duration of each packet in milliseconds. + + sr: actual sample rate in Hz. + + ebw: encoding bandwidth - either 'narrow' or 'wide' or + 'ultra' (corresponds to nominal 8000, 16000, and + 32000 Hz sampling rates). + + vbr: variable bit rate - either 'on' 'off' or 'vad' + (defaults to off). If on, variable bit rate is + enabled. If off, disabled. If set to 'vad' then + constant bit rate is used but silence will be encoded + with special short frames to indicate a lack of voice + for that period. + + cng: comfort noise generation - either 'on' or 'off'. If + off then silence frames will be silent; if 'on' then + those frames will be filled with comfort noise. + + mode: Speex encoding mode. Can be {1,2,3,4,5,6,any} + defaults to 3 in narrowband, 6 in wide and ultra-wide. + + penh: use of perceptual enhancement. 1 indicates + to the decoder that perceptual enhancement is recommended, + 0 indicates that it is not. Defaults to on (1). + + + + + + +Herlein, Valin, et. al. Expires September 3, 2004 [Page 7] +^L +Internet-Draft draft-herlein-avt-rtp-speex-00.txt March 3, 2004 + + + Examples: + + m=audio 8008 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=fmtp:97 mode=4 + + This examples illustrate an offerer that wishes to receive + a Speex stream at 8000Hz, but only using speex mode 3. + + The offerer may suggest to the remote decoder to activate + its perceptual enhancement filter like this: + + m=audio 8088 RTP/AVP 97 + a=rtmap:97 speex/8000 + a=fmtp:97 penh=1 + + Several Speex specific parameters can be given in a single + a=fmtp line provided that they are separated by a semi-colon: + + a=fmtp:97 mode=any;penh=1 + + The offerer may indicate that it wishes to send variable bit rate + frames with comfort noise: + + m=audio 8088 RTP/AVP 97 + a=rtmap:97 speex/8000 + a=fmtp:97 vbr=on;cng=on + + The "ptime" attribute is used to denote the packetization + interval (ie, how many milliseconds of audio is encoded in a + single RTP packet). Since Speex uses 20 msec frames, ptime values + of multiples of 20 denote multiple Speex frames per packet. + Values of ptime which are not multiples of 20 MUST be ignored + and clients MUST use the default value of 20 instead. + + In the example below the ptime value is set to 40, indicating that + there are 2 frames in each packet. + + m=audio 8008 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=ptime:40 + + Note that the ptime parameter applies to all payloads listed + in the media line and is not used as part of an a=fmtp directive. + + Values of ptime not multiple of 20 msec are meaningless, so the + receiver of such ptime values MUST ignore them. If during the + life of an RTP session the ptime value changes, when there are + multiple Speex frames for example, the SDP value must also reflect + the new value. + + + +Herlein, Valin, et. al. Expires September 3, 2004 [Page 8] +^L +Internet-Draft draft-herlein-avt-rtp-speex-00.txt March 3, 2004 + + + Care must be taken when setting the value of ptime so that the + RTP packet size does not exceed the path MTU. + + +6. ITU H.323/H.245 Use of Speex + + Application is underway to make Speex a standard ITU codec. + However, until that is finalized, Speex MAY be used in H.323 [6] by + using a non-standard codec block definition in the H.245 [7] codec + capability negotiations. + + +6.1 NonStandardMessage format + + For Speex use in H.245 [7] based systems, the fields in the + NonStandardMessage should be: + + t35CountryCode = Hex: B5 + t35Extension = Hex: 00 + manufacturerCode = Hex: 0026 + [Length of the Binary Sequence (8 bit number)] + [Binary Sequence consisting of an ASCII string, no NULL terminator] + + The binary sequence is an ascii string merely for ease of use. + The string is not null terminated. The format of this string is + + speex [optional variables] + + The optional variables are identical to those used for the SDP + a=fmtp strings discussed in section 5 above. The string is built + to be all on one line, each key-value pair separated by a + semi-colon. The optional variables MAY be omitted, which causes + the default values to be assumed. They are: + + ebw=narrow;mode=3;vbr=off;cng=off;ptime=20;sr=8000;penh=no; + + The fifth byte of the block is the length of the binary sequence. + + NOTE: this method can result in the advertising of a large number + of Speex 'codecs' based on the number of variables possible. For + most VoIP applications, use of the default binary sequence of + 'speex' is RECOMMENDED to be used in addition to all other options. + This maximizes the chances that two H.323 based applications that + support Speex can find a mutual codec. + + +6.2 RTP Payload Types + + Dynamic payload type codes MUST be negotiated 'out-of-band' + for the assignment of a dynamic payload type from the + range of 96-127. H.323 applications MUST use the H.245 + H2250LogicalChannelParameters encoding to accomplish this. + +Herlein, Valin, et. al. Expires September 3, 2004 [Page 9] +^L +Internet-Draft draft-herlein-avt-rtp-speex-00.txt March 3, 2004 + + +7. Security Considerations + + RTP packets using the payload format defined in this specification + are subject to the security considerations discussed in the RTP + specification [2], and any appropriate RTP profile. This implies + that confidentiality of the media streams is achieved by encryption. + Because the data compression used with this payload format is applied + end-to-end, encryption may be performed after compression so there is + no conflict between the two operations. + + A potential denial-of-service threat exists for data encodings using + compression techniques that have non-uniform receiver-end + computational load. The attacker can inject pathological datagrams + into the stream which are complex to decode and cause the receiver to + be overloaded. However, this encoding does not exhibit any + significant non-uniformity. + + As with any IP-based protocol, in some circumstances a receiver may + be overloaded simply by the receipt of too many packets, either + desired or undesired. Network-layer authentication may be used to + discard packets from undesired sources, but the processing cost of + the authentication itself may be too high. + + +8. Normative References + + 1. Bradner, S., "The Internet Standards Process -- Revision 3", BCP + 9, RFC 2026, October 1996. + + 2. Schulzrinne, H., Casner, S., Frederick, R. and V. Jacobson, "RTP: + A Transport Protocol for real-time applications", RFC 1889, + January 1996. + + 3. Freed, N. and N. Borenstein, "Multipurpose Internet Mail + Extensions (MIME) Part One: Format of Internet Message Bodies", + RFC 2045, November 1996. + + 4. Handley, M. and V. Jacobson, "SDP: Session Description + Protocol", RFC 2327, April 1998. + + 5. Bradner, S., "Key words for use in RFCs to Indicate Requirement + Levels", BCP 14, RFC 2119, March 1997. + + 6. ITU-T Recommendation H.323. "Packet-based Multimedia + Communications Systems," 1998. + + 7. ITU-T Recommendation H.245 (1998), "Control of communications + between Visual Telephone Systems and Terminal Equipment". + + 8. RTP: A transport protocol for real-time applications. Work + in progress, draft-ietf-avt-rtp-new-12.txt. + +Herlein, Valin, et. al. Expires September 3, 2004 [Page 10] +^L +Internet-Draft draft-herlein-avt-rtp-speex-00.txt March 3, 2004 + + + 9. RTP Profile for Audio and Video Conferences with Minimal + Control. Work in progress, draft-ietf-avt-profile-new-13.txt. + + 10. L. Walleij, "The application/ogg Media Type", RFC 3534, May + 2003. + + +8.1 Informative References + + 11. Speexenc/speexdec, reference command-line encoder/decoder, + Speex website, http://www.speex.org/ + + 12. CELP, U.S. Federal Standard 1016. National Technical + Information Service (NTIS) website, http://www.ntis.gov/ + + +9. Acknowledgments + + The authors would like to thank Equivalence Pty Ltd of Australia + for their assistance in attempting to standardize the use of Speex + in H.323 applications, and for implementing Speex in their open + source OpenH323 stack. The authors would also like to thank Brian + C. Wiles <brian@streamcomm.com> of StreamComm for his assistance in + developing the proposed standard for Speex use in H.323 + applications. + + The authors would also like to thank the following members of the + Speex and AVT communities for their input: Ross Finlayson, + Federico Montesino Pouzols, Henning Schulzrinne, Magnus Westerlund. + + +10. Author's Address + + Greg Herlein <gherlein@herlein.com> + 2034 Filbert Street + San Francisco, CA + United States 94123 + + + Jean-Marc Valin <jean-marc.valin@hermes.usherb.ca> + Department of Electrical and Computer Engineering + University of Sherbrooke + 2500 blvd Universit + Sherbrooke, Quebec, Canada, J1K 2R1 + + + Simon MORLAT <simon.morlat@linphone.org> + 35, av de Vizille App 42 + 38000 GRENOBLE + FRANCE + + + + +Herlein, Valin, et. al. Expires September 3, 2004 [Page 11] +^L +Internet-Draft draft-herlein-avt-rtp-speex-00.txt March 3, 2004 + + + Roger Hardiman <roger@freebsd.org> + 49 Nettleton Road + Cheltenham + Gloucestershire + GL51 6NR + England + + + Phil Kerr <philkerr@elec.gla.ac.uk> + Centre for Music Technology + University of Glasgow + Glasgow + G12 8LT + Scotland + + +10. Full Copyright Statement + + Copyright (C) The Internet Society (2003). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + +Herlein, Valin, et. al. Expires September 3, 2004 [Page 12] +^L + + diff --git a/src/libs/speexdsp/doc/draft-herlein-speex-rtp-profile-02.txt b/src/libs/speexdsp/doc/draft-herlein-speex-rtp-profile-02.txt new file mode 100644 index 00000000..2b25ea64 --- /dev/null +++ b/src/libs/speexdsp/doc/draft-herlein-speex-rtp-profile-02.txt @@ -0,0 +1,841 @@ + + +AVT Working Group G. Herlein +Internet-Draft S. Morlat +Expires: October 3, 2005 J. Jean-Marc + R. Hardiman + P. Kerr + April 04, 2005 + + + draft-herlein-speex-rtp-profile-02 + RTP Payload Format for the Speex Codec + +Status of this Memo + + This document is an Internet-Draft and is subject to all provisions + of section 3 of RFC 3667. By submitting this Internet-Draft, each + author represents that any applicable patent or other IPR claims of + which he or she is aware have been or will be disclosed, and any of + which he or she become aware will be disclosed, in accordance with + RFC 3668. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF), its areas, and its working groups. Note that + other groups may also distribute working documents as + Internet-Drafts. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + The list of current Internet-Drafts can be accessed at + http://www.ietf.org/ietf/1id-abstracts.txt. + + The list of Internet-Draft Shadow Directories can be accessed at + http://www.ietf.org/shadow.html. + + This Internet-Draft will expire on October 3, 2005. + +Copyright Notice + + Copyright (C) The Internet Society (2005). + +Abstract + + Speex is an open-source voice codec suitable for use in Voice over IP + (VoIP) type applications. This document describes the payload format + for Speex generated bit streams within an RTP packet. Also included + here are the necessary details for the use of Speex with the Session + Description Protocol (SDP) and a preliminary method of using Speex + + + +Herlein, et al. Expires October 3, 2005 [Page 1] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + + within H.323 applications. + +Table of Contents + + 1. Conventions used in this document . . . . . . . . . . . . . 3 + 2. Overview of the Speex Codec . . . . . . . . . . . . . . . . 3 + 3. RTP payload format for Speex . . . . . . . . . . . . . . . . 3 + 4. RTP Header . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 5. Speex payload . . . . . . . . . . . . . . . . . . . . . . . 5 + 6. Example Speex packet . . . . . . . . . . . . . . . . . . . . 6 + 7. Multiple Speex frames in a RTP packet . . . . . . . . . . . 6 + 8. MIME registration of Speex . . . . . . . . . . . . . . . . . 7 + 9. SDP usage of Speex . . . . . . . . . . . . . . . . . . . . . 8 + 10. ITU H.323/H.245 Use of Speex . . . . . . . . . . . . . . . . 10 + 11. NonStandardMessage format . . . . . . . . . . . . . . . . . 10 + 12. RTP Payload Types . . . . . . . . . . . . . . . . . . . . . 11 + 13. Security Considerations . . . . . . . . . . . . . . . . . . 11 + 14. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . 12 + 15. References . . . . . . . . . . . . . . . . . . . . . . . . . 12 + 15.1 Normative References . . . . . . . . . . . . . . . . . . . 12 + 15.2 Informative References . . . . . . . . . . . . . . . . . . 13 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 13 + Intellectual Property and Copyright Statements . . . . . . . 15 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 3, 2005 [Page 2] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + +1. Conventions used in this document + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in RFC 2119 [1]. + +2. Overview of the Speex Codec + + Speex is based on the CELP [10] encoding technique with support for + either narrowband (nominal 8kHz), wideband (nominal 16kHz) or + ultra-wideband (nominal 32kHz), and (non-optimal) rates up to 48 kHz + sampling also available. The main characteristics can be summarized + as follows: + + o Free software/open-source + o Integration of wideband and narrowband in the same bit-stream + o Wide range of bit-rates available + o Dynamic bit-rate switching and variable bit-rate (VBR) + o Voice Activity Detection (VAD, integrated with VBR) + o Variable complexity + +3. RTP payload format for Speex + + For RTP based transportation of Speex encoded audio the standard RTP + header [2] is followed by one or more payload data blocks. An + optional padding terminator may also be used. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | one or more frames of Speex .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | one or more frames of Speex .... | padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +4. RTP Header + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + + + +Herlein, et al. Expires October 3, 2005 [Page 3] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + The RTP header begins with an octet of fields (V, P, X, and CC) to + support specialized RTP uses (see [2] and [7] for details). For + Speex the following values are used. + + Version (V): 2 bits + + This field identifies the version of RTP. The version used by this + specification is two [2]. + + Padding (P): 1 bit + + If the padding bit is set, the packet contains one or more additional + padding octets at the end which are not part of the payload. P is + set if the total packet size is less than the MTU. + + Extension (X): 1 bit + + If the extension, X, bit is set, the fixed header MUST be followed by + exactly one header extension, with a format defined in Section 5.3.1. + of [2]. + + CSRC count (CC): 4 bits + + The CSRC count contains the number of CSRC identifiers. + + Marker (M): 1 bit + + The M bit indicates if the packet contains comfort noise. This field + is used in conjunction with the cng SDP attribute and is detailed + further in section 5 below. In normal usage this bit is set if the + packet contains comfort noise. + + Payload Type (PT): 7 bits + + An RTP profile for a class of applications is expected to assign a + payload type for this format, or a dynamically allocated payload type + SHOULD be chosen which designates the payload as Speex. + + Sequence number: 16 bits + + The sequence number increments by one for each RTP data packet sent, + and may be used by the receiver to detect packet loss and to restore + packet sequence. This field is detailed further in [2]. + + + +Herlein, et al. Expires October 3, 2005 [Page 4] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + + Timestamp: 32 bits + + A timestamp representing the sampling time of the first sample of the + first Speex packet in the RTP packet. The clock frequency MUST be + set to the sample rate of the encoded audio data. Speex uses 20 msec + frames and a variable sampling rate clock. The RTP timestamp MUST be + in units of 1/X of a second where X is the sample rate used. Speex + uses a nominal 8kHz sampling rate for narrowband use, a nominal 16kHz + sampling rate for wideband use, and a nominal 32kHz sampling rate for + ultra-wideband use. + + SSRC/CSRC identifiers: + + These two fields, 32 bits each with one SSRC field and a maximum of + 16 CSRC fields, are as defined in [2]. + +5. Speex payload + + For the purposes of packetizing the bit stream in RTP, it is only + necessary to consider the sequence of bits as output by the Speex + encoder [9], and present the same sequence to the decoder. The + payload format described here maintains this sequence. + + A typical Speex frame, encoded at the maximum bitrate, is approx. + 110 octets and the total number of Speex frames SHOULD be kept less + than the path MTU to prevent fragmentation. Speex frames MUST NOT be + fragmented across multiple RTP packets, + + An RTP packet MAY contain Speex frames of the same bit rate or of + varying bit rates, since the bit-rate for a frame is conveyed in band + with the signal. + + The encoding and decoding algorithm can change the bit rate at any 20 + msec frame boundary, with the bit rate change notification provided + in-band with the bit stream. Each frame contains both "mode" + (narrowband, wideband or ultra-wideband) and "sub-mode" (bit-rate) + information in the bit stream. No out-of-band notification is + required for the decoder to process changes in the bit rate sent by + the encoder. + + It is RECOMMENDED that values of 8000, 16000 and 32000 be used for + normal internet telephony applications, though the sample rate is + supported at rates as low as 6000 Hz and as high as 48 kHz. + + The RTP payload MUST be padded to provide an integer number of octets + as the payload length. These padding bits are LSB aligned in network + octet order and consist of a 0 followed by all ones (until the end of + the octet). This padding is only required for the last frame in the + + + +Herlein, et al. Expires October 3, 2005 [Page 5] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + + packet, and only to ensure the packet contents ends on an octet + boundary. + +6. Example Speex packet + + In the example below we have a single Speex frame with 5 bits of + padding to ensure the packet size falls on an octet boundary. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. |0 1 1 1 1| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +7. Multiple Speex frames in a RTP packet + + Below is an example of two Speex frames contained within one RTP + packet. The Speex frame length in this example fall on an octet + boundary so there is no padding. + + Speex codecs [9] are able to detect the the bitrate from the payload + and are responsible for detecting the 20 msec boundaries between each + frame. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + +Herlein, et al. Expires October 3, 2005 [Page 6] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +8. MIME registration of Speex + + Full definition of the MIME [3] type for Speex will be part of the + Ogg Vorbis MIME type definition application [8]. + + MIME media type name: audio + + MIME subtype: speex + + Optional parameters: + + Required parameters: to be included in the Ogg MIME specification. + + Encoding considerations: + + Security Considerations: + + See Section 6 of RFC 3047. + + Interoperability considerations: none + + Published specification: + + Applications which use this media type: + + Additional information: none + + Person & email address to contact for further information: + + Greg Herlein <gherlein@herlein.com> + Jean-Marc Valin <jean-marc.valin@hermes.usherb.ca> + + Intended usage: COMMON + + + + +Herlein, et al. Expires October 3, 2005 [Page 7] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + + Author/Change controller: + + Author: Greg Herlein <gherlein@herlein.com> + Change controller: Greg Herlein <gherlein@herlein.com> + Change controller: IETF AVT Working Group + + This transport type signifies that the content is to be interpreted + according to this document if the contents are transmitted over RTP. + Should this transport type appear over a lossless streaming protocol + such as TCP, the content encapsulation should be interpreted as an + Ogg Stream in accordance with [8], with the exception that the + content of the Ogg Stream may be assumed to be Speex audio and Speex + audio only. + +9. SDP usage of Speex + + When conveying information by SDP [4], the encoding name MUST be set + to "speex". An example of the media representation in SDP for + offering a single channel of Speex at 8000 samples per second might + be: + + m=audio 8088 RTP/AVP 97 + a=rtpmap:97 speex/8000 + + Note that the RTP payload type code of 97 is defined in this media + definition to be 'mapped' to the speex codec at an 8kHz sampling + frequency using the 'a=rtpmap' line. Any number from 96 to 127 could + have been chosen (the allowed range for dynamic types). + + The value of the sampling frequency is typically 8000 for narrow band + operation, 16000 for wide band operation, and 32000 for ultra-wide + band operation. + + If for some reason the offerer has bandwidth limitations, the client + may use the "b=" header, as explained in SDP [4]. The following + example illustrates the case where the offerer cannot receive more + than 10 kbit/s. + + m=audio 8088 RTP/AVP 97 + b=AS:10 + a=rtmap:97 speex/8000 + + In this case, if the remote part agrees, it should configure its + Speex encoder so that it does not use modes that produce more than 10 + kbit/s. Note that the "b=" constraint also applies on all payload + types that may be proposed in the media line ("m="). + + An other way to make recommendations to the remote Speex encoder is + + + +Herlein, et al. Expires October 3, 2005 [Page 8] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + + to use its specific parameters via the a=fmtp: directive. The + following parameters are defined for use in this way: + + ptime: duration of each packet in milliseconds. + + sr: actual sample rate in Hz. + + ebw: encoding bandwidth - either 'narrow' or 'wide' or 'ultra' + (corresponds to nominal 8000, 16000, and 32000 Hz sampling rates). + + vbr: variable bit rate - either 'on' 'off' or 'vad' (defaults + to off). If on, variable bit rate is enabled. If off, disabled. + If set to 'vad' then constant bit rate is used but silence will be + encoded with special short frames to indicate a lack of voice for + that period. + + cng: comfort noise generation - either 'on' or 'off'. If off + then silence frames will be silent; if 'on' then those frames will + be filled with comfort noise. + + mode: Speex encoding mode. Can be {1,2,3,4,5,6,any} defaults to + 3 in narrowband, 6 in wide and ultra-wide. + + penh: use of perceptual enhancement. 1 indicates to the decoder + that perceptual enhancement is recommended, 0 indicates that it is + not. Defaults to on (1). + + + Examples: + + m=audio 8008 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=fmtp:97 mode=4 + + This examples illustrate an offerer that wishes to receive a Speex + stream at 8000Hz, but only using speex mode 3. + + The offerer may suggest to the remote decoder to activate its + perceptual enhancement filter like this: + + m=audio 8088 RTP/AVP 97 + a=rtmap:97 speex/8000 + a=fmtp:97 penh=1 + + Several Speex specific parameters can be given in a single a=fmtp + line provided that they are separated by a semi-colon: + + + + + +Herlein, et al. Expires October 3, 2005 [Page 9] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + + a=fmtp:97 mode=any;penh=1 + + The offerer may indicate that it wishes to send variable bit rate + frames with comfort noise: + + m=audio 8088 RTP/AVP 97 + a=rtmap:97 speex/8000 + a=fmtp:97 vbr=on;cng=on + + The "ptime" attribute is used to denote the packetization interval + (ie, how many milliseconds of audio is encoded in a single RTP + packet). Since Speex uses 20 msec frames, ptime values of multiples + of 20 denote multiple Speex frames per packet. Values of ptime which + are not multiples of 20 MUST be ignored and clients MUST use the + default value of 20 instead. + + In the example below the ptime value is set to 40, indicating that + there are 2 frames in each packet. + + m=audio 8008 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=ptime:40 + + Note that the ptime parameter applies to all payloads listed in the + media line and is not used as part of an a=fmtp directive. + + Values of ptime not multiple of 20 msec are meaningless, so the + receiver of such ptime values MUST ignore them. If during the life + of an RTP session the ptime value changes, when there are multiple + Speex frames for example, the SDP value must also reflect the new + value. + + Care must be taken when setting the value of ptime so that the RTP + packet size does not exceed the path MTU. + +10. ITU H.323/H.245 Use of Speex + + Application is underway to make Speex a standard ITU codec. However, + until that is finalized, Speex MAY be used in H.323 [5] by using a + non-standard codec block definition in the H.245 [6] codec capability + negotiations. + +11. NonStandardMessage format + + For Speex use in H.245 [6] based systems, the fields in the + NonStandardMessage should be: + + + + + +Herlein, et al. Expires October 3, 2005 [Page 10] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + + t35CountryCode = Hex: B5 + t35Extension = Hex: 00 + manufacturerCode = Hex: 0026 + [Length of the Binary Sequence (8 bit number)] + [Binary Sequence consisting of an ASCII string, no NULL + terminator] + + The binary sequence is an ascii string merely for ease of use. The + string is not null terminated. The format of this string is + + speex [optional variables] + + The optional variables are identical to those used for the SDP a=fmtp + strings discussed in section 5 above. The string is built to be all + on one line, each key-value pair separated by a semi-colon. The + optional variables MAY be omitted, which causes the default values to + be assumed. They are: + + ebw=narrow;mode=3;vbr=off;cng=off;ptime=20;sr=8000;penh=no; + + The fifth octet of the block is the length of the binary sequence. + + NOTE: this method can result in the advertising of a large number of + Speex 'codecs' based on the number of variables possible. For most + VoIP applications, use of the default binary sequence of 'speex' is + RECOMMENDED to be used in addition to all other options. This + maximizes the chances that two H.323 based applications that support + Speex can find a mutual codec. + +12. RTP Payload Types + + Dynamic payload type codes MUST be negotiated 'out-of-band' for the + assignment of a dynamic payload type from the range of 96-127. H.323 + applications MUST use the H.245 H2250LogicalChannelParameters + encoding to accomplish this. + +13. Security Considerations + + RTP packets using the payload format defined in this specification + are subject to the security considerations discussed in the RTP + specification [2], and any appropriate RTP profile. This implies + that confidentiality of the media streams is achieved by encryption. + Because the data compression used with this payload format is applied + end-to-end, encryption may be performed after compression so there is + no conflict between the two operations. + + A potential denial-of-service threat exists for data encodings using + compression techniques that have non-uniform receiver-end + + + +Herlein, et al. Expires October 3, 2005 [Page 11] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + + computational load. The attacker can inject pathological datagrams + into the stream which are complex to decode and cause the receiver to + be overloaded. However, this encoding does not exhibit any + significant non-uniformity. + + As with any IP-based protocol, in some circumstances a receiver may + be overloaded simply by the receipt of too many packets, either + desired or undesired. Network-layer authentication may be used to + discard packets from undesired sources, but the processing cost of + the authentication itself may be too high. + +14. Acknowledgments + + The authors would like to thank Equivalence Pty Ltd of Australia for + their assistance in attempting to standardize the use of Speex in + H.323 applications, and for implementing Speex in their open source + OpenH323 stack. The authors would also like to thank Brian C. Wiles + <brian@streamcomm.com> of StreamComm for his assistance in developing + the proposed standard for Speex use in H.323 applications. + + The authors would also like to thank the following members of the + Speex and AVT communities for their input: Ross Finlayson, Federico + Montesino Pouzols, Henning Schulzrinne, Magnus Westerlund. + +15. References + +15.1 Normative References + + [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement + Levels", RFC 2119. + + [2] Schulzrinne, H., Casner, S., Frederick, R. and V. Jacobson, + "RTP: A Transport Protocol for real-time applications", RFC + 3550. + + [3] "Multipurpose Internet Mail Extensions (MIME) Part One: Format + of Internet Message Bodies", RFC 2045. + + [4] Jacobson, V. and M. Handley, "SDP: Session Description + Protocol", RFC 2327. + + [5] "Packet-based Multimedia Communications Systems", ITU-T + Recommendation H.323. + + [6] "Control of communications between Visual Telephone Systems and + Terminal Equipment", ITU-T Recommendation H.245. + + [7] Schulzrinne, H. and S. Casner, "RTP Profile for Audio and Video + + + +Herlein, et al. Expires October 3, 2005 [Page 12] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + + Conferences with Minimal Control.", RFC 3551. + + [8] Walleij, L., "The application/ogg Media Type", RFC 3534. + +15.2 Informative References + + [9] "Speexenc/speexdec, reference command-line encoder/decoder", + Speex website http://www.speex.org/. + + [10] "CELP, U.S. Federal Standard 1016.", National Technical + Information Service (NTIS) website http://www.ntis.gov/. + + +Authors' Addresses + + Greg Herlein + 2034 Filbert Street + San Francisco, California 94123 + United States + + EMail: gherlein@herlein.com + + + Simon Morlat + 35, av de Vizille App 42 + Grenoble 38000 + France + + EMail: simon.morlat@linphone.org + + + Jean-Marc Valin + Department of Electrical and Computer Engineering + University of Sherbrooke + 2500 blvd Universite + Sherbrooke, Quebec J1K 2R1 + Canada + + EMail: jean-marc.valin@hermes.usherb.ca + + + Roger Hardiman + 49 Nettleton Road + Cheltenham, Gloucestershire GL51 6NR + England + + EMail: roger@freebsd.org + + + + +Herlein, et al. Expires October 3, 2005 [Page 13] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + + Phil Kerr + England + + EMail: phil@plus24.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 3, 2005 [Page 14] + +Internet-Draft draft-herlein-speex-rtp-profile-02 April 2005 + + +Intellectual Property Statement + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at + ietf-ipr@ietf.org. + + +Disclaimer of Validity + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE + INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + +Copyright Statement + + Copyright (C) The Internet Society (2005). This document is subject + to the rights, licenses and restrictions contained in BCP 78, and + except as set forth therein, the authors retain all their rights. + + +Acknowledgment + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + +Herlein, et al. Expires October 3, 2005 [Page 15] + + diff --git a/src/libs/speexdsp/doc/draft-herlein-speex-rtp-profile-03.txt b/src/libs/speexdsp/doc/draft-herlein-speex-rtp-profile-03.txt new file mode 100644 index 00000000..d1ad4b37 --- /dev/null +++ b/src/libs/speexdsp/doc/draft-herlein-speex-rtp-profile-03.txt @@ -0,0 +1,1232 @@ + + +AVT Working Group G. Herlein +Internet-Draft S. Morlat +Expires: July 2, 2005 J. Jean-Marc + R. Hardiman + P. Kerr + January 01, 2005 + + + draft-herlein-speex-rtp-profile-03 + RTP Payload Format for the Speex Codec + +Status of this Memo + + This document is an Internet-Draft and is subject to all provisions + of section 3 of RFC 3667. By submitting this Internet-Draft, each + author represents that any applicable patent or other IPR claims of + which he or she is aware have been or will be disclosed, and any of + which he or she become aware will be disclosed, in accordance with + RFC 3668. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF), its areas, and its working groups. Note that + other groups may also distribute working documents as + Internet-Drafts. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + The list of current Internet-Drafts can be accessed at + http://www.ietf.org/ietf/1id-abstracts.txt. + + The list of Internet-Draft Shadow Directories can be accessed at + http://www.ietf.org/shadow.html. + + This Internet-Draft will expire on July 2, 2005. + +Copyright Notice + + Copyright (C) The Internet Society (2005). + +Abstract + + Speex is an open-source voice codec suitable for use in Voice over IP + (VoIP) type applications. This document describes the payload format + for Speex generated bit streams within an RTP packet. Also included + here are the necessary details for the use of Speex with the Session + Description Protocol (SDP) and a preliminary method of using Speex + + + +Herlein, et al. Expires July 2, 2005 [Page 1] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + + within H.323 applications. + +Table of Contents + + 1. Conventions used in this document . . . . . . . . . . . . . 3 + 2. Overview of the Speex Codec . . . . . . . . . . . . . . . . 4 + 3. RTP payload format for Speex . . . . . . . . . . . . . . . . 5 + 4. RTP Header . . . . . . . . . . . . . . . . . . . . . . . . . 6 + 5. Speex payload . . . . . . . . . . . . . . . . . . . . . . . 8 + 6. Example Speex packet . . . . . . . . . . . . . . . . . . . . 9 + 7. Multiple Speex frames in a RTP packet . . . . . . . . . . . 10 + 8. MIME registration of Speex . . . . . . . . . . . . . . . . . 11 + 9. SDP usage of Speex . . . . . . . . . . . . . . . . . . . . . 12 + 10. ITU H.323/H.245 Use of Speex . . . . . . . . . . . . . . . . 15 + 11. NonStandardMessage format . . . . . . . . . . . . . . . . . 16 + 12. RTP Payload Types . . . . . . . . . . . . . . . . . . . . . 17 + 13. Security Considerations . . . . . . . . . . . . . . . . . . 18 + 14. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . 19 + 15. References . . . . . . . . . . . . . . . . . . . . . . . . . 20 + 15.1 Normative References . . . . . . . . . . . . . . . . . . . 20 + 15.2 Informative References . . . . . . . . . . . . . . . . . . 20 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 20 + Intellectual Property and Copyright Statements . . . . . . . 22 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 2] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +1. Conventions used in this document + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in RFC 2119 [1]. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 3] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +2. Overview of the Speex Codec + + Speex is based on the CELP [10] encoding technique with support for + either narrowband (nominal 8kHz), wideband (nominal 16kHz) or + ultra-wideband (nominal 32kHz), and (non-optimal) rates up to 48 kHz + sampling also available. The main characteristics can be summarized + as follows: + + o Free software/open-source + o Integration of wideband and narrowband in the same bit-stream + o Wide range of bit-rates available + o Dynamic bit-rate switching and variable bit-rate (VBR) + o Voice Activity Detection (VAD, integrated with VBR) + o Variable complexity + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 4] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +3. RTP payload format for Speex + + For RTP based transportation of Speex encoded audio the standard RTP + header [2] is followed by one or more payload data blocks. An + optional padding terminator may also be used. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | one or more frames of Speex .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | one or more frames of Speex .... | padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 5] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +4. RTP Header + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + The RTP header begins with an octet of fields (V, P, X, and CC) to + support specialized RTP uses (see [2] and [7] for details). For + Speex the following values are used. + + Version (V): 2 bits + + This field identifies the version of RTP. The version used by this + specification is two [2]. + + Padding (P): 1 bit + + If the padding bit is set, the packet contains one or more additional + padding octets at the end which are not part of the payload. P is + set if the total packet size is less than the MTU. + + Extension (X): 1 bit + + If the extension, X, bit is set, the fixed header MUST be followed by + exactly one header extension, with a format defined in Section 5.3.1. + of [2]. + + CSRC count (CC): 4 bits + + The CSRC count contains the number of CSRC identifiers. + + Marker (M): 1 bit + + The M bit indicates if the packet contains comfort noise. This field + is used in conjunction with the cng SDP attribute and is detailed + further in section 5 below. In normal usage this bit is set if the + packet contains comfort noise. + + Payload Type (PT): 7 bits + + + +Herlein, et al. Expires July 2, 2005 [Page 6] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + + An RTP profile for a class of applications is expected to assign a + payload type for this format, or a dynamically allocated payload type + SHOULD be chosen which designates the payload as Speex. + + Sequence number: 16 bits + + The sequence number increments by one for each RTP data packet sent, + and may be used by the receiver to detect packet loss and to restore + packet sequence. This field is detailed further in [2]. + + Timestamp: 32 bits + + A timestamp representing the sampling time of the first sample of the + first Speex packet in the RTP packet. The clock frequency MUST be + set to the sample rate of the encoded audio data. Speex uses 20 msec + frames and a variable sampling rate clock. The RTP timestamp MUST be + in units of 1/X of a second where X is the sample rate used. Speex + uses a nominal 8kHz sampling rate for narrowband use, a nominal 16kHz + sampling rate for wideband use, and a nominal 32kHz sampling rate for + ultra-wideband use. + + SSRC/CSRC identifiers: + + These two fields, 32 bits each with one SSRC field and a maximum of + 16 CSRC fields, are as defined in [2]. + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 7] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +5. Speex payload + + For the purposes of packetizing the bit stream in RTP, it is only + necessary to consider the sequence of bits as output by the Speex + encoder [9], and present the same sequence to the decoder. The + payload format described here maintains this sequence. + + A typical Speex frame, encoded at the maximum bitrate, is approx. + 110 octets and the total number of Speex frames SHOULD be kept less + than the path MTU to prevent fragmentation. Speex frames MUST NOT be + fragmented across multiple RTP packets, + + An RTP packet MAY contain Speex frames of the same bit rate or of + varying bit rates, since the bit-rate for a frame is conveyed in band + with the signal. + + The encoding and decoding algorithm can change the bit rate at any 20 + msec frame boundary, with the bit rate change notification provided + in-band with the bit stream. Each frame contains both "mode" + (narrowband, wideband or ultra-wideband) and "sub-mode" (bit-rate) + information in the bit stream. No out-of-band notification is + required for the decoder to process changes in the bit rate sent by + the encoder. + + It is RECOMMENDED that values of 8000, 16000 and 32000 be used for + normal internet telephony applications, though the sample rate is + supported at rates as low as 6000 Hz and as high as 48 kHz. + + The RTP payload MUST be padded to provide an integer number of octets + as the payload length. These padding bits are LSB aligned in network + octet order and consist of a 0 followed by all ones (until the end of + the octet). This padding is only required for the last frame in the + packet, and only to ensure the packet contents ends on an octet + boundary. + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 8] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +6. Example Speex packet + + In the example below we have a single Speex frame with 5 bits of + padding to ensure the packet size falls on an octet boundary. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. |0 1 1 1 1| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 9] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +7. Multiple Speex frames in a RTP packet + + Below is an example of two Speex frames contained within one RTP + packet. The Speex frame length in this example fall on an octet + boundary so there is no padding. + + Speex codecs [9] are able to detect the the bitrate from the payload + and are responsible for detecting the 20 msec boundaries between each + frame. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 10] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +8. MIME registration of Speex + + Full definition of the MIME [3] type for Speex will be part of the + Ogg Vorbis MIME type definition application [8]. + + MIME media type name: audio + + MIME subtype: speex + + Optional parameters: + + Required parameters: to be included in the Ogg MIME specification. + + Encoding considerations: + + Security Considerations: + + See Section 6 of RFC 3047. + + Interoperability considerations: none + + Published specification: + + Applications which use this media type: + + Additional information: none + + Person & email address to contact for further information: + + Greg Herlein <gherlein@herlein.com> + Jean-Marc Valin <jean-marc.valin@hermes.usherb.ca> + + Intended usage: COMMON + + Author/Change controller: + + Author: Greg Herlein <gherlein@herlein.com> + Change controller: Greg Herlein <gherlein@herlein.com> + Change controller: IETF AVT Working Group + + This transport type signifies that the content is to be interpreted + according to this document if the contents are transmitted over RTP. + Should this transport type appear over a lossless streaming protocol + such as TCP, the content encapsulation should be interpreted as an + Ogg Stream in accordance with [8], with the exception that the + content of the Ogg Stream may be assumed to be Speex audio and Speex + audio only. + + + + +Herlein, et al. Expires July 2, 2005 [Page 11] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +9. SDP usage of Speex + + When conveying information by SDP [4], the encoding name MUST be set + to "speex". An example of the media representation in SDP for + offering a single channel of Speex at 8000 samples per second might + be: + + m=audio 8088 RTP/AVP 97 + a=rtpmap:97 speex/8000 + + Note that the RTP payload type code of 97 is defined in this media + definition to be 'mapped' to the speex codec at an 8kHz sampling + frequency using the 'a=rtpmap' line. Any number from 96 to 127 could + have been chosen (the allowed range for dynamic types). + + The value of the sampling frequency is typically 8000 for narrow band + operation, 16000 for wide band operation, and 32000 for ultra-wide + band operation. + + If for some reason the offerer has bandwidth limitations, the client + may use the "b=" header, as explained in SDP [4]. The following + example illustrates the case where the offerer cannot receive more + than 10 kbit/s. + + m=audio 8088 RTP/AVP 97 + b=AS:10 + a=rtmap:97 speex/8000 + + In this case, if the remote part agrees, it should configure its + Speex encoder so that it does not use modes that produce more than 10 + kbit/s. Note that the "b=" constraint also applies on all payload + types that may be proposed in the media line ("m="). + + An other way to make recommendations to the remote Speex encoder is + to use its specific parameters via the a=fmtp: directive. The + following parameters are defined for use in this way: + + ptime: duration of each packet in milliseconds. + + sr: actual sample rate in Hz. + + ebw: encoding bandwidth - either 'narrow' or 'wide' or 'ultra' + (corresponds to nominal 8000, 16000, and 32000 Hz sampling rates). + + vbr: variable bit rate - either 'on' 'off' or 'vad' (defaults + to off). If on, variable bit rate is enabled. If off, disabled. + If set to 'vad' then constant bit rate is used but silence will be + encoded with special short frames to indicate a lack of voice for + + + +Herlein, et al. Expires July 2, 2005 [Page 12] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + + that period. + + cng: comfort noise generation - either 'on' or 'off'. If off + then silence frames will be silent; if 'on' then those frames will + be filled with comfort noise. + + mode: Speex encoding mode. Can be {1,2,3,4,5,6,any} defaults to + 3 in narrowband, 6 in wide and ultra-wide. + + penh: use of perceptual enhancement. 1 indicates to the decoder + that perceptual enhancement is recommended, 0 indicates that it is + not. Defaults to on (1). + + + Examples: + + m=audio 8008 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=fmtp:97 mode=4 + + This examples illustrate an offerer that wishes to receive a Speex + stream at 8000Hz, but only using speex mode 3. + + The offerer may suggest to the remote decoder to activate its + perceptual enhancement filter like this: + + m=audio 8088 RTP/AVP 97 + a=rtmap:97 speex/8000 + a=fmtp:97 penh=1 + + Several Speex specific parameters can be given in a single a=fmtp + line provided that they are separated by a semi-colon: + + a=fmtp:97 mode=any;penh=1 + + The offerer may indicate that it wishes to send variable bit rate + frames with comfort noise: + + m=audio 8088 RTP/AVP 97 + a=rtmap:97 speex/8000 + a=fmtp:97 vbr=on;cng=on + + The "ptime" attribute is used to denote the packetization interval + (ie, how many milliseconds of audio is encoded in a single RTP + packet). Since Speex uses 20 msec frames, ptime values of multiples + of 20 denote multiple Speex frames per packet. Values of ptime which + are not multiples of 20 MUST be ignored and clients MUST use the + default value of 20 instead. + + + +Herlein, et al. Expires July 2, 2005 [Page 13] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + + In the example below the ptime value is set to 40, indicating that + there are 2 frames in each packet. + + m=audio 8008 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=ptime:40 + + Note that the ptime parameter applies to all payloads listed in the + media line and is not used as part of an a=fmtp directive. + + Values of ptime not multiple of 20 msec are meaningless, so the + receiver of such ptime values MUST ignore them. If during the life + of an RTP session the ptime value changes, when there are multiple + Speex frames for example, the SDP value must also reflect the new + value. + + Care must be taken when setting the value of ptime so that the RTP + packet size does not exceed the path MTU. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 14] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +10. ITU H.323/H.245 Use of Speex + + Application is underway to make Speex a standard ITU codec. However, + until that is finalized, Speex MAY be used in H.323 [5] by using a + non-standard codec block definition in the H.245 [6] codec capability + negotiations. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 15] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +11. NonStandardMessage format + + For Speex use in H.245 [6] based systems, the fields in the + NonStandardMessage should be: + + t35CountryCode = Hex: B5 + t35Extension = Hex: 00 + manufacturerCode = Hex: 0026 + [Length of the Binary Sequence (8 bit number)] + [Binary Sequence consisting of an ASCII string, no NULL + terminator] + + The binary sequence is an ascii string merely for ease of use. The + string is not null terminated. The format of this string is + + speex [optional variables] + + The optional variables are identical to those used for the SDP a=fmtp + strings discussed in section 5 above. The string is built to be all + on one line, each key-value pair separated by a semi-colon. The + optional variables MAY be omitted, which causes the default values to + be assumed. They are: + + ebw=narrow;mode=3;vbr=off;cng=off;ptime=20;sr=8000;penh=no; + + The fifth octet of the block is the length of the binary sequence. + + NOTE: this method can result in the advertising of a large number of + Speex 'codecs' based on the number of variables possible. For most + VoIP applications, use of the default binary sequence of 'speex' is + RECOMMENDED to be used in addition to all other options. This + maximizes the chances that two H.323 based applications that support + Speex can find a mutual codec. + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 16] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +12. RTP Payload Types + + Dynamic payload type codes MUST be negotiated 'out-of-band' for the + assignment of a dynamic payload type from the range of 96-127. H.323 + applications MUST use the H.245 H2250LogicalChannelParameters + encoding to accomplish this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 17] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +13. Security Considerations + + RTP packets using the payload format defined in this specification + are subject to the security considerations discussed in the RTP + specification [2], and any appropriate RTP profile. This implies + that confidentiality of the media streams is achieved by encryption. + Because the data compression used with this payload format is applied + end-to-end, encryption may be performed after compression so there is + no conflict between the two operations. + + A potential denial-of-service threat exists for data encodings using + compression techniques that have non-uniform receiver-end + computational load. The attacker can inject pathological datagrams + into the stream which are complex to decode and cause the receiver to + be overloaded. However, this encoding does not exhibit any + significant non-uniformity. + + As with any IP-based protocol, in some circumstances a receiver may + be overloaded simply by the receipt of too many packets, either + desired or undesired. Network-layer authentication may be used to + discard packets from undesired sources, but the processing cost of + the authentication itself may be too high. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 18] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +14. Acknowledgments + + The authors would like to thank Equivalence Pty Ltd of Australia for + their assistance in attempting to standardize the use of Speex in + H.323 applications, and for implementing Speex in their open source + OpenH323 stack. The authors would also like to thank Brian C. Wiles + <brian@streamcomm.com> of StreamComm for his assistance in developing + the proposed standard for Speex use in H.323 applications. + + The authors would also like to thank the following members of the + Speex and AVT communities for their input: Ross Finlayson, Federico + Montesino Pouzols, Henning Schulzrinne, Magnus Westerlund. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 19] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +15. References + +15.1 Normative References + + [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement + Levels", RFC 2119. + + [2] Schulzrinne, H., Casner, S., Frederick, R. and V. Jacobson, + "RTP: A Transport Protocol for real-time applications", RFC + 3550. + + [3] "Multipurpose Internet Mail Extensions (MIME) Part One: Format + of Internet Message Bodies", RFC 2045. + + [4] Jacobson, V. and M. Handley, "SDP: Session Description + Protocol", RFC 2327. + + [5] "Packet-based Multimedia Communications Systems", ITU-T + Recommendation H.323. + + [6] "Control of communications between Visual Telephone Systems and + Terminal Equipment", ITU-T Recommendation H.245. + + [7] Schulzrinne, H. and S. Casner, "RTP Profile for Audio and Video + Conferences with Minimal Control.", RFC 3551. + + [8] Walleij, L., "The application/ogg Media Type", RFC 3534. + +15.2 Informative References + + [9] "Speexenc/speexdec, reference command-line encoder/decoder", + Speex website http://www.speex.org/. + + [10] "CELP, U.S. Federal Standard 1016.", National Technical + Information Service (NTIS) website http://www.ntis.gov/. + + +Authors' Addresses + + Greg Herlein + 2034 Filbert Street + San Francisco, California 94123 + United States + + EMail: gherlein@herlein.com + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 20] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + + Simon Morlat + 35, av de Vizille App 42 + Grenoble 38000 + France + + EMail: simon.morlat@linphone.org + + + Jean-Marc Valin + Department of Electrical and Computer Engineering + University of Sherbrooke + 2500 blvd Universite + Sherbrooke, Quebec J1K 2R1 + Canada + + EMail: jean-marc.valin@hermes.usherb.ca + + + Roger Hardiman + 49 Nettleton Road + Cheltenham, Gloucestershire GL51 6NR + England + + EMail: roger@freebsd.org + + + Phil Kerr + England + + EMail: phil@plus24.com + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires July 2, 2005 [Page 21] + +Internet-Draft draft-herlein-speex-rtp-profile-03 January 2005 + + +Intellectual Property Statement + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at + ietf-ipr@ietf.org. + + +Disclaimer of Validity + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE + INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + +Copyright Statement + + Copyright (C) The Internet Society (2005). This document is subject + to the rights, licenses and restrictions contained in BCP 78, and + except as set forth therein, the authors retain all their rights. + + +Acknowledgment + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + +Herlein, et al. Expires July 2, 2005 [Page 22] + diff --git a/src/libs/speexdsp/doc/draft-herlein-speex-rtp-profile-03.xml b/src/libs/speexdsp/doc/draft-herlein-speex-rtp-profile-03.xml new file mode 100644 index 00000000..709efcdf --- /dev/null +++ b/src/libs/speexdsp/doc/draft-herlein-speex-rtp-profile-03.xml @@ -0,0 +1,815 @@ +<?xml version='1.0'?> +<!DOCTYPE rfc SYSTEM 'rfc2629.dtd'> +<?rfc toc="yes" ?> + +<rfc ipr="full3667" docName="RTP Payload Format for the Speex Codec"> + +<front> +<title>draft-herlein-speex-rtp-profile-03</title> + +<author initials="G" surname="Herlein" fullname="Greg Herlein"> +<organization></organization> +<address> +<email>gherlein@herlein.com</email> +<postal> +<street>2034 Filbert Street</street> +<city>San Francisco</city> +<region>California</region> +<code>94123</code> +<country>United States</country> +</postal> +</address> +</author> + +<author initials="S" surname="Morlat" fullname="Simon Morlat"> +<address> +<email>simon.morlat@linphone.org</email> +<postal> +<street>35, av de Vizille App 42</street> +<city>Grenoble</city> +<code>38000</code> +<country>France</country> +</postal> +</address> +</author> + +<author initials="J" surname="Jean-Marc" fullname="Jean-Marc Valin"> +<address> +<email>jean-marc.valin@hermes.usherb.ca</email> +<postal> +<street>Department of Electrical and Computer Engineering</street> +<street>University of Sherbrooke</street> +<street>2500 blvd Universite</street> +<city>Sherbrooke</city> +<region>Quebec</region> +<code>J1K 2R1</code> +<country>Canada</country> +</postal> +</address> +</author> + +<author initials="R" surname="Hardiman" fullname="Roger Hardiman"> +<address> +<email>roger@freebsd.org</email> +<postal> +<street>49 Nettleton Road</street> +<city>Cheltenham</city> +<region>Gloucestershire</region> +<code>GL51 6NR</code> +<country>England</country> +</postal> +</address> +</author> + + +<author initials="P" surname="Kerr" fullname="Phil Kerr"> +<address> +<email>phil@plus24.com</email> +<postal> +<country>England</country> +</postal> +</address> +</author> + +<date day="01" month="January" year="2005" /> + +<area>General</area> +<workgroup>AVT Working Group</workgroup> +<keyword>I-D</keyword> + +<keyword>Internet-Draft</keyword> +<keyword>Speex</keyword> +<keyword>RTP</keyword> +<abstract> +<t> +Speex is an open-source voice codec suitable for use in Voice over +IP (VoIP) type applications. This document describes the payload +format for Speex generated bit streams within an RTP packet. Also +included here are the necessary details for the use of Speex with +the Session Description Protocol (SDP) and a preliminary method of +using Speex within H.323 applications. +</t> +</abstract> +</front> + +<middle> + +<section anchor="Conventions used in this document" title="Conventions used in this document"> +<t> +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in RFC 2119 <xref target="rfc2119"></xref>. +</t> +</section> + +<section anchor="Overview of the Speex Codec" title="Overview of the Speex Codec"> + +<t> +Speex is based on the CELP <xref target="CELP"></xref> encoding technique with support for +either narrowband (nominal 8kHz), wideband (nominal 16kHz) or +ultra-wideband (nominal 32kHz), and (non-optimal) rates up to 48 kHz +sampling also available. The main characteristics can be summarized +as follows: +</t> + +<t> +<list style="symbols"> +<t>Free software/open-source</t> +<t>Integration of wideband and narrowband in the same bit-stream</t> +<t>Wide range of bit-rates available</t> +<t>Dynamic bit-rate switching and variable bit-rate (VBR)</t> +<t>Voice Activity Detection (VAD, integrated with VBR)</t> +<t>Variable complexity</t> +</list> +</t> + +</section> + +<section anchor="RTP payload format for Speex" title="RTP payload format for Speex"> + +<t> +For RTP based transportation of Speex encoded audio the standard +RTP header [2] is followed by one or more payload data blocks. +An optional padding terminator may also be used. +</t> +<artwork><![CDATA[ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | one or more frames of Speex .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | one or more frames of Speex .... | padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +]]></artwork> + +</section> + +<section anchor="RTP Header" title="RTP Header"> + +<artwork><![CDATA[ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +]]></artwork> + +<t> +The RTP header begins with an octet of fields (V, P, X, and CC) to +support specialized RTP uses (see <xref target="rfc3550"></xref> and <xref target="rfc3551"></xref> for details). For +Speex the following values are used. +</t> + +<t>Version (V): 2 bits</t><t> + This field identifies the version of RTP. The version + used by this specification is two <xref target="rfc3550"></xref>. +</t> + +<t>Padding (P): 1 bit</t><t> + If the padding bit is set, the packet contains one or more + additional padding octets at the end which are not part of + the payload. P is set if the total packet size is less than + the MTU. +</t> + +<t>Extension (X): 1 bit</t><t> + If the extension, X, bit is set, the fixed header MUST be + followed by exactly one header extension, with a format defined + in Section 5.3.1. of <xref target="rfc3550"></xref>. +</t> + +<t>CSRC count (CC): 4 bits</t><t> + The CSRC count contains the number of CSRC identifiers. +</t> + +<t>Marker (M): 1 bit</t><t> + The M bit indicates if the packet contains comfort noise. This + field is used in conjunction with the cng SDP attribute and is + detailed further in section 5 below. In normal usage this bit + is set if the packet contains comfort noise. +</t> + +<t>Payload Type (PT): 7 bits</t><t> + An RTP profile for a class of applications is expected to assign + a payload type for this format, or a dynamically allocated + payload type SHOULD be chosen which designates the payload as + Speex. +</t> + +<t>Sequence number: 16 bits</t><t> + The sequence number increments by one for each RTP data packet + sent, and may be used by the receiver to detect packet loss and + to restore packet sequence. This field is detailed further in + <xref target="rfc3550"></xref>. +</t> + +<t>Timestamp: 32 bits</t><t> + A timestamp representing the sampling time of the first sample of + the first Speex packet in the RTP packet. The clock frequency + MUST be set to the sample rate of the encoded audio data. + + Speex uses 20 msec frames and a variable sampling rate clock. + The RTP timestamp MUST be in units of 1/X of a second where X + is the sample rate used. Speex uses a nominal 8kHz sampling rate + for narrowband use, a nominal 16kHz sampling rate for wideband use, + and a nominal 32kHz sampling rate for ultra-wideband use. +</t> + +<t>SSRC/CSRC identifiers:</t><t> + These two fields, 32 bits each with one SSRC field and a maximum + of 16 CSRC fields, are as defined in <xref target="rfc3550"></xref>. +</t> + +</section> + +<section anchor="Speex payload" title="Speex payload"> + +<t> +For the purposes of packetizing the bit stream in RTP, it is only +necessary to consider the sequence of bits as output by the Speex +encoder <xref target="speexenc"></xref>, and present the same sequence to the decoder. The +payload format described here maintains this sequence. +</t> + +<t> +A typical Speex frame, encoded at the maximum bitrate, is approx. +110 octets and the total number of Speex frames SHOULD be kept +less than the path MTU to prevent fragmentation. Speex frames MUST +NOT be fragmented across multiple RTP packets, +</t> + +<t> +An RTP packet MAY contain Speex frames of the same bit rate or of +varying bit rates, since the bit-rate for a frame is conveyed in +band with the signal. +</t> + +<t> +The encoding and decoding algorithm can change the bit rate at any +20 msec frame boundary, with the bit rate change notification provided +in-band with the bit stream. Each frame contains both "mode" +(narrowband, wideband or ultra-wideband) and "sub-mode" (bit-rate) +information in the bit stream. No out-of-band notification is +required for the decoder to process changes in the bit rate sent +by the encoder. +</t> + +<t> +It is RECOMMENDED that values of 8000, 16000 and 32000 be used +for normal internet telephony applications, though the sample +rate is supported at rates as low as 6000 Hz and as high as +48 kHz. +</t> + +<t> +The RTP payload MUST be padded to provide an integer number of +octets as the payload length. These padding bits are LSB aligned +in network octet order and consist of a 0 followed by all ones +(until the end of the octet). This padding is only required for +the last frame in the packet, and only to ensure the packet +contents ends on an octet boundary. +</t> + +</section> + +<section anchor="Example Speex packet" title="Example Speex packet"> + +<t> +In the example below we have a single Speex frame with 5 bits +of padding to ensure the packet size falls on an octet boundary. +</t> + +<artwork><![CDATA[ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. |0 1 1 1 1| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +]]></artwork> + +</section> + +<section anchor="Multiple Speex frames in a RTP packet" title="Multiple Speex frames in a RTP packet"> + +<t> +Below is an example of two Speex frames contained within one RTP +packet. The Speex frame length in this example fall on an octet +boundary so there is no padding. +</t> + +<t> +Speex codecs <xref target="speexenc"></xref> are able to detect the the bitrate from the +payload and are responsible for detecting the 20 msec boundaries +between each frame. +</t> + +<artwork><![CDATA[ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +]]></artwork> + +</section> + +<section anchor="MIME registration of Speex" title="MIME registration of Speex"> + +<t> +Full definition of the MIME <xref target="rfc2045"></xref> type for Speex will be part of the Ogg +Vorbis MIME type definition application <xref target="rfc3534"></xref>. +</t> + +<t>MIME media type name: audio</t> + +<t>MIME subtype: speex</t> + +<t>Optional parameters:</t> + +<t>Required parameters: to be included in the Ogg MIME specification.</t> + +<t>Encoding considerations:</t> + +<t>Security Considerations:</t> +<t>See Section 6 of RFC 3047.</t> + +<t>Interoperability considerations: none</t> + +<t>Published specification: </t> + +<t>Applications which use this media type:</t> + +<t>Additional information: none</t> + +<t>Person &amp; email address to contact for further information:<vspace blankLines="1" /> +<list style="empty"> +<t>Greg Herlein &lt;gherlein@herlein.com&gt;</t> +<t>Jean-Marc Valin &lt;jean-marc.valin@hermes.usherb.ca&gt;</t> +</list> +</t> + +<t>Intended usage: COMMON</t> + +<t>Author/Change controller:</t> + +<t> +<list style="empty"> +<t>Author: Greg Herlein &lt;gherlein@herlein.com&gt;</t> +<t>Change controller: Greg Herlein &lt;gherlein@herlein.com&gt;</t> +<t>Change controller: IETF AVT Working Group</t> +</list> +</t> + +<t> +This transport type signifies that the content is to be interpreted +according to this document if the contents are transmitted over RTP. +Should this transport type appear over a lossless streaming protocol +such as TCP, the content encapsulation should be interpreted as an +Ogg Stream in accordance with <xref target="rfc3534"></xref>, with the exception that the +content of the Ogg Stream may be assumed to be Speex audio and +Speex audio only. +</t> + +</section> + +<section anchor="SDP usage of Speex" title="SDP usage of Speex"> + +<t> +When conveying information by SDP <xref target="rfc2327"></xref>, the encoding name MUST be +set to "speex". An example of the media representation in SDP for +offering a single channel of Speex at 8000 samples per second might +be: +</t> + +<vspace blankLines="1" /> +<list style="empty"> +<t>m=audio 8088 RTP/AVP 97</t> +<t>a=rtpmap:97 speex/8000</t> +</list> + +<t> +Note that the RTP payload type code of 97 is defined in this media +definition to be 'mapped' to the speex codec at an 8kHz sampling +frequency using the 'a=rtpmap' line. Any number from 96 to 127 +could have been chosen (the allowed range for dynamic types). +</t> + +<t> +The value of the sampling frequency is typically 8000 for narrow band +operation, 16000 for wide band operation, and 32000 for ultra-wide +band operation. +</t> + +<t> +If for some reason the offerer has bandwidth limitations, the client +may use the "b=" header, as explained in SDP <xref target="rfc2327"></xref>. The following example +illustrates the case where the offerer cannot receive more than +10 kbit/s. +</t> + +<vspace blankLines="1" /> +<list style="empty"> +<t>m=audio 8088 RTP/AVP 97</t> +<t>b=AS:10</t> +<t>a=rtmap:97 speex/8000</t> +</list> + +<t> +In this case, if the remote part agrees, it should configure its +Speex encoder so that it does not use modes that produce more than +10 kbit/s. Note that the "b=" constraint also applies on all +payload types that may be proposed in the media line ("m="). +</t> + +<t> +An other way to make recommendations to the remote Speex encoder +is to use its specific parameters via the a=fmtp: directive. The +following parameters are defined for use in this way: +</t> + +<vspace blankLines="1" /> +<list style="empty"> +<t>ptime: duration of each packet in milliseconds.<vspace blankLines="1" /></t> + +<t>sr: actual sample rate in Hz.<vspace blankLines="1" /></t> + +<t>ebw: encoding bandwidth - either 'narrow' or 'wide' or + 'ultra' (corresponds to nominal 8000, 16000, and + 32000 Hz sampling rates).<vspace blankLines="1" /></t> + +<t>vbr: variable bit rate - either 'on' 'off' or 'vad' + (defaults to off). If on, variable bit rate is + enabled. If off, disabled. If set to 'vad' then + constant bit rate is used but silence will be encoded + with special short frames to indicate a lack of voice + for that period.<vspace blankLines="1" /></t> + +<t>cng: comfort noise generation - either 'on' or 'off'. If + off then silence frames will be silent; if 'on' then + those frames will be filled with comfort noise.<vspace blankLines="1" /></t> + +<t>mode: Speex encoding mode. Can be {1,2,3,4,5,6,any} + defaults to 3 in narrowband, 6 in wide and ultra-wide.<vspace blankLines="1" /></t> + +<t>penh: use of perceptual enhancement. 1 indicates + to the decoder that perceptual enhancement is recommended, + 0 indicates that it is not. Defaults to on (1).<vspace blankLines="1" /></t> +</list> + +<t>Examples:</t> + +<vspace blankLines="1" /> +<list style="empty"> + <t>m=audio 8008 RTP/AVP 97</t> + <t>a=rtpmap:97 speex/8000</t> + <t>a=fmtp:97 mode=4</t> +</list> + +<t> +This examples illustrate an offerer that wishes to receive +a Speex stream at 8000Hz, but only using speex mode 3. +</t> + +<t> +The offerer may suggest to the remote decoder to activate +its perceptual enhancement filter like this: +</t> + +<vspace blankLines="1" /> +<list style="empty"> + <t>m=audio 8088 RTP/AVP 97</t> + <t>a=rtmap:97 speex/8000</t> + <t>a=fmtp:97 penh=1 </t> +</list> + +<t> +Several Speex specific parameters can be given in a single +a=fmtp line provided that they are separated by a semi-colon: +</t> + +<vspace blankLines="1" /> +<list style="empty"> + <t>a=fmtp:97 mode=any;penh=1</t> +</list> + +<t> +The offerer may indicate that it wishes to send variable bit rate +frames with comfort noise: +</t> + +<vspace blankLines="1" /> +<list style="empty"> + <t>m=audio 8088 RTP/AVP 97</t> + <t>a=rtmap:97 speex/8000</t> + <t>a=fmtp:97 vbr=on;cng=on</t> +</list> + +<t> +The "ptime" attribute is used to denote the packetization +interval (ie, how many milliseconds of audio is encoded in a +single RTP packet). Since Speex uses 20 msec frames, ptime values +of multiples of 20 denote multiple Speex frames per packet. +Values of ptime which are not multiples of 20 MUST be ignored +and clients MUST use the default value of 20 instead. +</t> + +<t> +In the example below the ptime value is set to 40, indicating that +there are 2 frames in each packet. +</t> + +<vspace blankLines="1" /> +<list style="empty"> + <t>m=audio 8008 RTP/AVP 97</t> + <t>a=rtpmap:97 speex/8000</t> + <t>a=ptime:40</t> +</list> + +<t> +Note that the ptime parameter applies to all payloads listed +in the media line and is not used as part of an a=fmtp directive. +</t> + +<t> +Values of ptime not multiple of 20 msec are meaningless, so the +receiver of such ptime values MUST ignore them. If during the +life of an RTP session the ptime value changes, when there are +multiple Speex frames for example, the SDP value must also reflect +the new value. +</t> + +<t> +Care must be taken when setting the value of ptime so that the +RTP packet size does not exceed the path MTU. +</t> + +</section> +<section anchor="ITU H.323/H.245 Use of Speex" title="ITU H.323/H.245 Use of Speex"> + +<t> +Application is underway to make Speex a standard ITU codec. +However, until that is finalized, Speex MAY be used in H.323 <xref target="H323"></xref> by +using a non-standard codec block definition in the H.245 <xref target="H245"></xref> codec +capability negotiations. +</t> + +</section> + +<section anchor="NonStandardMessage format" title="NonStandardMessage format"> + +<t> +For Speex use in H.245 <xref target="H245"></xref> based systems, the fields in the +NonStandardMessage should be: +</t> + +<vspace blankLines="1" /> +<list style="empty"> +<t>t35CountryCode = Hex: B5</t> +<t>t35Extension = Hex: 00</t> +<t>manufacturerCode = Hex: 0026</t> +<t>[Length of the Binary Sequence (8 bit number)]</t> +<t>[Binary Sequence consisting of an ASCII string, no NULL terminator]</t> +</list> + +<t> +The binary sequence is an ascii string merely for ease of use. +The string is not null terminated. The format of this string is +</t> + +<vspace blankLines="1" /> +<list style="empty"> +<t>speex [optional variables]</t> +</list> + +<t> +The optional variables are identical to those used for the SDP +a=fmtp strings discussed in section 5 above. The string is built +to be all on one line, each key-value pair separated by a +semi-colon. The optional variables MAY be omitted, which causes +the default values to be assumed. They are: +</t> + +<vspace blankLines="1" /> +<list style="empty"> +<t>ebw=narrow;mode=3;vbr=off;cng=off;ptime=20;sr=8000;penh=no;</t> +</list> + +<t> +The fifth octet of the block is the length of the binary sequence. +</t> + +<t> +NOTE: this method can result in the advertising of a large number +of Speex 'codecs' based on the number of variables possible. For +most VoIP applications, use of the default binary sequence of +'speex' is RECOMMENDED to be used in addition to all other options. +This maximizes the chances that two H.323 based applications that +support Speex can find a mutual codec. +</t> + +</section> + +<section anchor="RTP Payload Types" title="RTP Payload Types"> + +<t> +Dynamic payload type codes MUST be negotiated 'out-of-band' +for the assignment of a dynamic payload type from the +range of 96-127. H.323 applications MUST use the H.245 +H2250LogicalChannelParameters encoding to accomplish this. +</t> + +</section> + +<section anchor="Security Considerations" title="Security Considerations"> + +<t> +RTP packets using the payload format defined in this specification +are subject to the security considerations discussed in the RTP +specification <xref target="rfc3550"></xref>, and any appropriate RTP profile. This implies +that confidentiality of the media streams is achieved by encryption. +Because the data compression used with this payload format is applied +end-to-end, encryption may be performed after compression so there is +no conflict between the two operations. +</t> + +<t> +A potential denial-of-service threat exists for data encodings using +compression techniques that have non-uniform receiver-end +computational load. The attacker can inject pathological datagrams +into the stream which are complex to decode and cause the receiver to +be overloaded. However, this encoding does not exhibit any +significant non-uniformity. +</t> + +<t> +As with any IP-based protocol, in some circumstances a receiver may +be overloaded simply by the receipt of too many packets, either +desired or undesired. Network-layer authentication may be used to +discard packets from undesired sources, but the processing cost of +the authentication itself may be too high. +</t> + +</section> + +<section anchor="Acknowledgments" title="Acknowledgments"> + +<t> +The authors would like to thank Equivalence Pty Ltd of Australia +for their assistance in attempting to standardize the use of Speex +in H.323 applications, and for implementing Speex in their open +source OpenH323 stack. The authors would also like to thank Brian +C. Wiles &lt;brian@streamcomm.com&gt; of StreamComm for his assistance in +developing the proposed standard for Speex use in H.323 +applications. +</t> + +<t> +The authors would also like to thank the following members of the +Speex and AVT communities for their input: Ross Finlayson, +Federico Montesino Pouzols, Henning Schulzrinne, Magnus Westerlund. +</t> +</section> + +</middle> + +<back> + +<references title="Normative References"> + +<reference anchor="rfc2119"> +<front> +<title>Key words for use in RFCs to Indicate Requirement Levels </title> +<author initials="S." surname="Bradner" fullname="Scott Bradner"></author> +</front> +<seriesInfo name="RFC" value="2119" /> +</reference> + +<reference anchor="rfc3550"> +<front> +<title>RTP: A Transport Protocol for real-time applications</title> +<author initials="H." surname="Schulzrinne" fullname=""></author> +<author initials="S." surname="Casner" fullname=""></author> +<author initials="R." surname="Frederick" fullname=""></author> +<author initials="V." surname="Jacobson" fullname=""></author> +</front> +<seriesInfo name="RFC" value="3550" /> +</reference> + +<reference anchor="rfc2045"> +<front> +<title>Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</title> +<author initials="" surname="" fullname=""></author> +</front> +<date month="November" year="1998" /> +<seriesInfo name="RFC" value="2045" /> +</reference> + +<reference anchor="rfc2327"> +<front> +<title>SDP: Session Description Protocol</title> +<author initials="V." surname="Jacobson" fullname=""></author> +<author initials="M." surname="Handley" fullname=""></author> +</front> +<date month="April" year="1998" /> +<seriesInfo name="RFC" value="2327" /> +</reference> + +<reference anchor="H323"> +<front> +<title>Packet-based Multimedia Communications Systems</title> +<author initials="" surname="" fullname=""></author> +</front> +<date month="" year="1998" /> +<seriesInfo name="ITU-T Recommendation" value="H.323" /> +</reference> + +<reference anchor="H245"> +<front> +<title>Control of communications between Visual Telephone Systems and Terminal Equipment</title> +<author initials="" surname="" fullname=""></author> +</front> +<date month="" year="1998" /> +<seriesInfo name="ITU-T Recommendation" value="H.245" /> +</reference> + +<reference anchor="rfc3551"> +<front> +<title>RTP Profile for Audio and Video Conferences with Minimal Control.</title> +<author initials="H." surname="Schulzrinne" fullname=""></author> +<author initials="S." surname="Casner" fullname=""></author> +</front> +<date month="July" year="2003" /> +<seriesInfo name="RFC" value="3551" /> +</reference> + +<reference anchor="rfc3534"> +<front> +<title>The application/ogg Media Type</title> +<author initials="L." surname="Walleij" fullname=""></author> +</front> +<date month="May" year="2003" /> +<seriesInfo name="RFC" value="3534" /> +</reference> + +</references> + +<references title="Informative References"> + +<reference anchor="speexenc"> +<front> +<title>Speexenc/speexdec, reference command-line encoder/decoder</title> +</front> +<seriesInfo name="Speex website" value="http://www.speex.org/" /> +</reference> + +<reference anchor="CELP"> +<front> +<title>CELP, U.S. Federal Standard 1016.</title> +<author initials="" surname="" fullname=""></author> +</front> +<seriesInfo name="National Technical Information Service (NTIS) website" value="http://www.ntis.gov/" /> +</reference> + +</references> + +</back> +</rfc> diff --git a/src/libs/speexdsp/doc/draft-ietf-avt-rtp-speex-00.txt b/src/libs/speexdsp/doc/draft-ietf-avt-rtp-speex-00.txt new file mode 100644 index 00000000..53facab4 --- /dev/null +++ b/src/libs/speexdsp/doc/draft-ietf-avt-rtp-speex-00.txt @@ -0,0 +1,784 @@ + + + +AVT Working Group G. Herlein +Internet-Draft S. Morlat +Expires: April 15, 2006 J. Jean-Marc + R. Hardiman + P. Kerr + October 12, 2005 + + + draft-ietf-avt-rtp-speex-00 + RTP Payload Format for the Speex Codec + +Status of this Memo + + By submitting this Internet-Draft, each author represents that any + applicable patent or other IPR claims of which he or she is aware + have been or will be disclosed, and any of which he or she becomes + aware will be disclosed, in accordance with Section 6 of BCP 79. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF), its areas, and its working groups. Note that + other groups may also distribute working documents as Internet- + Drafts. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + The list of current Internet-Drafts can be accessed at + http://www.ietf.org/ietf/1id-abstracts.txt. + + The list of Internet-Draft Shadow Directories can be accessed at + http://www.ietf.org/shadow.html. + + This Internet-Draft will expire on April 15, 2006. + +Copyright Notice + + Copyright (C) The Internet Society (2005). + +Abstract + + Speex is an open-source voice codec suitable for use in Voice over IP + (VoIP) type applications. This document describes the payload format + for Speex generated bit streams within an RTP packet. Also included + here are the necessary details for the use of Speex with the Session + Description Protocol (SDP). + + + + +Herlein, et al. Expires April 15, 2006 [Page 1] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + +Editors Note + + All references to RFC XXXX are to be replaced by references to the + RFC number of this memo, when published. + +Table of Contents + + 1. Conventions used in this document . . . . . . . . . . . . . 3 + 2. Overview of the Speex Codec . . . . . . . . . . . . . . . . 3 + 3. RTP payload format for Speex . . . . . . . . . . . . . . . . 3 + 4. RTP Header . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 5. Speex payload . . . . . . . . . . . . . . . . . . . . . . . 5 + 6. Example Speex packet . . . . . . . . . . . . . . . . . . . . 6 + 7. Multiple Speex frames in a RTP packet . . . . . . . . . . . 6 + 8. MIME registration of Speex . . . . . . . . . . . . . . . . . 7 + 9. SDP usage of Speex . . . . . . . . . . . . . . . . . . . . . 8 + 10. ITU H.323 Use of Speex . . . . . . . . . . . . . . . . . . . 10 + 11. Security Considerations . . . . . . . . . . . . . . . . . . 10 + 12. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . 11 + 13. References . . . . . . . . . . . . . . . . . . . . . . . . . 11 + 13.1 Normative References . . . . . . . . . . . . . . . . . . 11 + 13.2 Informative References . . . . . . . . . . . . . . . . . 12 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 12 + Intellectual Property and Copyright Statements . . . . . . . 14 + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires April 15, 2006 [Page 2] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + +1. Conventions used in this document + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in RFC 2119 [1]. + +2. Overview of the Speex Codec + + Speex is based on the CELP [8] encoding technique with support for + either narrowband (nominal 8kHz), wideband (nominal 16kHz) or ultra- + wideband (nominal 32kHz), and (non-optimal) rates up to 48 kHz + sampling also available. The main characteristics can be summarized + as follows: + + o Free software/open-source + o Integration of wideband and narrowband in the same bit-stream + o Wide range of bit-rates available + o Dynamic bit-rate switching and variable bit-rate (VBR) + o Voice Activity Detection (VAD, integrated with VBR) + o Variable complexity + +3. RTP payload format for Speex + + For RTP based transportation of Speex encoded audio the standard RTP + header [2] is followed by one or more payload data blocks. An + optional padding terminator may also be used. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | one or more frames of Speex .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | one or more frames of Speex .... | padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +4. RTP Header + + + + + + + + + + + + +Herlein, et al. Expires April 15, 2006 [Page 3] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + The RTP header begins with an octet of fields (V, P, X, and CC) to + support specialized RTP uses (see [2] and [5] for details). For + Speex the following values are used. + + Version (V): 2 bits + + This field identifies the version of RTP. The version used by this + specification is two [2]. + + Padding (P): 1 bit + + If the padding bit is set, the packet contains one or more additional + padding octets at the end which are not part of the payload. + + Extension (X): 1 bit + + If the extension, X, bit is set, the fixed header MUST be followed by + exactly one header extension, with a format defined in Section 5.3.1. + of [2]. + + CSRC count (CC): 4 bits + + The CSRC count contains the number of CSRC identifiers. + + Marker (M): 1 bit + + The M bit indicates if the packet contains comfort noise. This field + is used in conjunction with the cng SDP attribute and conforms to + Section 4.1. of [5]. + + Payload Type (PT): 7 bits + + An RTP profile for a class of applications is expected to assign a + payload type for this format, or a dynamically allocated payload type + SHOULD be chosen which designates the payload as Speex. + + + +Herlein, et al. Expires April 15, 2006 [Page 4] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + + Sequence number: 16 bits + + The sequence number increments by one for each RTP data packet sent, + and may be used by the receiver to detect packet loss and to restore + packet sequence. This field is detailed further in [2]. + + Timestamp: 32 bits + + A timestamp representing the sampling time of the first sample of the + first Speex packet in the RTP packet. The clock frequency MUST be + set to the sample rate of the encoded audio data. Speex uses 20 msec + frames and a variable sampling rate clock. The RTP timestamp MUST be + in units of 1/X of a second where X is the sample rate used. Speex + uses a nominal 8kHz sampling rate for narrowband use, a nominal 16kHz + sampling rate for wideband use, and a nominal 32kHz sampling rate for + ultra-wideband use. + + SSRC/CSRC identifiers: + + These two fields, 32 bits each with one SSRC field and a maximum of + 16 CSRC fields, are as defined in [2]. + +5. Speex payload + + For the purposes of packetizing the bit stream in RTP, it is only + necessary to consider the sequence of bits as output by the Speex + encoder [7], and present the same sequence to the decoder. The + payload format described here maintains this sequence. + + A typical Speex frame, encoded at the maximum bitrate, is approx. 110 + octets and the total number of Speex frames SHOULD be kept less than + the path MTU to prevent fragmentation. Speex frames MUST NOT be + fragmented across multiple RTP packets, + + An RTP packet MAY contain Speex frames of the same bit rate or of + varying bit rates, since the bit-rate for a frame is conveyed in band + with the signal. + + The encoding and decoding algorithm can change the bit rate at any 20 + msec frame boundary, with the bit rate change notification provided + in-band with the bit stream. Each frame contains both "mode" + (narrowband, wideband or ultra-wideband) and "sub-mode" (bit-rate) + information in the bit stream. No out-of-band notification is + required for the decoder to process changes in the bit rate sent by + the encoder. + + It is RECOMMENDED that values of 8000, 16000 and 32000 be used for + normal internet telephony applications, though the sample rate is + + + +Herlein, et al. Expires April 15, 2006 [Page 5] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + + supported at rates as low as 6000 Hz and as high as 48 kHz. + + The RTP payload MUST be padded to provide an integer number of octets + as the payload length. These padding bits are LSB aligned in network + octet order and consist of a 0 followed by all ones (until the end of + the octet). This padding is only required for the last frame in the + packet, and only to ensure the packet contents ends on an octet + boundary. + +6. Example Speex packet + + In the example below we have a single Speex frame with 5 bits of + padding to ensure the packet size falls on an octet boundary. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. |0 1 1 1 1| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +7. Multiple Speex frames in a RTP packet + + Below is an example of two Speex frames contained within one RTP + packet. The Speex frame length in this example fall on an octet + boundary so there is no padding. + + Speex codecs [7] are able to detect the bitrate from the payload and + are responsible for detecting the 20 msec boundaries between each + frame. + + + + + +Herlein, et al. Expires April 15, 2006 [Page 6] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +8. MIME registration of Speex + + Full definition of the MIME [3] type for Speex will be part of the + Ogg Vorbis MIME type definition application [6]. + + MIME media type name: audio + + MIME subtype: speex + + Optional parameters: + + Required parameters: to be included in the Ogg MIME specification. + + Encoding considerations: + + This type is only defined for transfer via HTTP as specified in RFC + XXXX. + + Security Considerations: + + See Section 6 of RFC 3047. + + Interoperability considerations: none + + Published specification: + + Applications which use this media type: + + + +Herlein, et al. Expires April 15, 2006 [Page 7] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + + Additional information: none + + Person & email address to contact for further information: + + Greg Herlein <gherlein@herlein.com> + Jean-Marc Valin <jean-marc.valin@usherbrooke.ca> + + Intended usage: COMMON + + Author/Change controller: + + Author: Greg Herlein <gherlein@herlein.com> + Change controller: Greg Herlein <gherlein@herlein.com> + Change controller: IETF AVT Working Group + + This transport type signifies that the content is to be interpreted + according to this document if the contents are transmitted over RTP. + Should this transport type appear over a lossless streaming protocol + such as TCP, the content encapsulation should be interpreted as an + Ogg Stream in accordance with [6], with the exception that the + content of the Ogg Stream may be assumed to be Speex audio and Speex + audio only. + +9. SDP usage of Speex + + When conveying information by SDP [4], the encoding name MUST be set + to "speex". An example of the media representation in SDP for + offering a single channel of Speex at 8000 samples per second might + be: + + m=audio 8088 RTP/AVP 97 + a=rtpmap:97 speex/8000 + + Note that the RTP payload type code of 97 is defined in this media + definition to be 'mapped' to the speex codec at an 8kHz sampling + frequency using the 'a=rtpmap' line. Any number from 96 to 127 could + have been chosen (the allowed range for dynamic types). + + The value of the sampling frequency is typically 8000 for narrow band + operation, 16000 for wide band operation, and 32000 for ultra-wide + band operation. + + If for some reason the offerer has bandwidth limitations, the client + may use the "b=" header, as explained in SDP [4]. The following + example illustrates the case where the offerer cannot receive more + than 10 kbit/s. + + + + + +Herlein, et al. Expires April 15, 2006 [Page 8] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + + m=audio 8088 RTP/AVP 97 + b=AS:10 + a=rtmap:97 speex/8000 + + In this case, if the remote part agrees, it should configure its + Speex encoder so that it does not use modes that produce more than 10 + kbit/s. Note that the "b=" constraint also applies on all payload + types that may be proposed in the media line ("m="). + + An other way to make recommendations to the remote Speex encoder is + to use its specific parameters via the a=fmtp: directive. The + following parameters are defined for use in this way: + + ptime: duration of each packet in milliseconds. + + sr: actual sample rate in Hz. + + ebw: encoding bandwidth - either 'narrow' or 'wide' or 'ultra' + (corresponds to nominal 8000, 16000, and 32000 Hz sampling rates). + + vbr: variable bit rate - either 'on' 'off' or 'vad' (defaults + to off). If on, variable bit rate is enabled. If off, disabled. + If set to 'vad' then constant bit rate is used but silence will be + encoded with special short frames to indicate a lack of voice for + that period. + + cng: comfort noise generation - either 'on' or 'off'. If off + then silence frames will be silent; if 'on' then those frames will + be filled with comfort noise. + + mode: Speex encoding mode. Can be {1,2,3,4,5,6,any} defaults to + 3 in narrowband, 6 in wide and ultra-wide. + + + Examples: + + m=audio 8008 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=fmtp:97 mode=4 + + This examples illustrate an offerer that wishes to receive a Speex + stream at 8000Hz, but only using speex mode 4. + + Several Speex specific parameters can be given in a single a=fmtp + line provided that they are separated by a semi-colon: + + + + + + +Herlein, et al. Expires April 15, 2006 [Page 9] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + + a=fmtp:97 mode=any;mode=1 + + The offerer may indicate that it wishes to send variable bit rate + frames with comfort noise: + + m=audio 8088 RTP/AVP 97 + a=rtmap:97 speex/8000 + a=fmtp:97 vbr=on;cng=on + + The "ptime" attribute is used to denote the packetization interval + (ie, how many milliseconds of audio is encoded in a single RTP + packet). Since Speex uses 20 msec frames, ptime values of multiples + of 20 denote multiple Speex frames per packet. Values of ptime which + are not multiples of 20 MUST be ignored and clients MUST use the + default value of 20 instead. + + In the example below the ptime value is set to 40, indicating that + there are 2 frames in each packet. + + m=audio 8008 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=ptime:40 + + Note that the ptime parameter applies to all payloads listed in the + media line and is not used as part of an a=fmtp directive. + + Values of ptime not multiple of 20 msec are meaningless, so the + receiver of such ptime values MUST ignore them. If during the life + of an RTP session the ptime value changes, when there are multiple + Speex frames for example, the SDP value must also reflect the new + value. + + Care must be taken when setting the value of ptime so that the RTP + packet size does not exceed the path MTU. + +10. ITU H.323 Use of Speex + + It is outside the scope of this document to cover the use of Speex + and H.323, more details may be found on the Speex website [9]. + +11. Security Considerations + + RTP packets using the payload format defined in this specification + are subject to the security considerations discussed in the RTP + specification [2], and any appropriate RTP profile. This implies + that confidentiality of the media streams is achieved by encryption. + Because the data compression used with this payload format is applied + end-to-end, encryption may be performed after compression so there is + + + +Herlein, et al. Expires April 15, 2006 [Page 10] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + + no conflict between the two operations. + + A potential denial-of-service threat exists for data encodings using + compression techniques that have non-uniform receiver-end + computational load. The attacker can inject pathological datagrams + into the stream which are complex to decode and cause the receiver to + be overloaded. However, this encoding does not exhibit any + significant non-uniformity. + + As with any IP-based protocol, in some circumstances a receiver may + be overloaded simply by the receipt of too many packets, either + desired or undesired. Network-layer authentication may be used to + discard packets from undesired sources, but the processing cost of + the authentication itself may be too high. + +12. Acknowledgments + + The authors would like to thank Equivalence Pty Ltd of Australia for + their assistance in attempting to standardize the use of Speex in + H.323 applications, and for implementing Speex in their open source + OpenH323 stack. The authors would also like to thank Brian C. Wiles + <brian@streamcomm.com> of StreamComm for his assistance in developing + the proposed standard for Speex use in H.323 applications. + + The authors would also like to thank the following members of the + Speex and AVT communities for their input: Ross Finlayson, Federico + Montesino Pouzols, Henning Schulzrinne, Magnus Westerlund. + +13. References + +13.1 Normative References + + [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement + Levels", RFC 2119. + + [2] Schulzrinne, H., Casner, S., Frederick, R., and V. Jacobson, + "RTP: A Transport Protocol for real-time applications", + RFC 3550. + + [3] "Multipurpose Internet Mail Extensions (MIME) Part One: Format + of Internet Message Bodies", RFC 2045. + + [4] Jacobson, V. and M. Handley, "SDP: Session Description + Protocol", RFC 2327. + + [5] Schulzrinne, H. and S. Casner, "RTP Profile for Audio and Video + Conferences with Minimal Control.", RFC 3551. + + + + +Herlein, et al. Expires April 15, 2006 [Page 11] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + + [6] Walleij, L., "The application/ogg Media Type", RFC 3534. + +13.2 Informative References + + [7] "Speexenc/speexdec, reference command-line encoder/decoder", + Speex website http://www.speex.org/. + + [8] "CELP, U.S. Federal Standard 1016.", National Technical + Information Service (NTIS) website http://www.ntis.gov/. + + [9] "ITU H.323/H.245 Use of Speex", Speex + website http://www.speex.org/itu/. + + +Authors' Addresses + + Greg Herlein + 2034 Filbert Street + San Francisco, California 94123 + United States + + Email: gherlein@herlein.com + + + Simon Morlat + 35, av de Vizille App 42 + Grenoble 38000 + France + + Email: simon.morlat@linphone.org + + + Jean-Marc Valin + Department of Electrical and Computer Engineering + University of Sherbrooke + 2500 blvd Universite + Sherbrooke, Quebec J1K 2R1 + Canada + + Email: jean-marc.valin@usherbrooke.ca + + + + + + + + + + + +Herlein, et al. Expires April 15, 2006 [Page 12] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + + Roger Hardiman + 49 Nettleton Road + Cheltenham, Gloucestershire GL51 6NR + England + + Email: roger@freebsd.org + + + Phil Kerr + England + + Email: phil@plus24.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires April 15, 2006 [Page 13] + +Internet-Draft draft-ietf-avt-rtp-speex-00 October 2005 + + +Intellectual Property Statement + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at + ietf-ipr@ietf.org. + + +Disclaimer of Validity + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE + INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + +Copyright Statement + + Copyright (C) The Internet Society (2005). This document is subject + to the rights, licenses and restrictions contained in BCP 78, and + except as set forth therein, the authors retain all their rights. + + +Acknowledgment + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + +Herlein, et al. Expires April 15, 2006 [Page 14] + diff --git a/src/libs/speexdsp/doc/draft-ietf-avt-rtp-speex-01-tmp.txt b/src/libs/speexdsp/doc/draft-ietf-avt-rtp-speex-01-tmp.txt new file mode 100644 index 00000000..1410b858 --- /dev/null +++ b/src/libs/speexdsp/doc/draft-ietf-avt-rtp-speex-01-tmp.txt @@ -0,0 +1,1008 @@ + + + +AVT G. Herlein +Internet-Draft +Intended status: Standards Track J. Valin +Expires: October 24, 2007 University of Sherbrooke + A. Heggestad + April 22, 2007 + + + RTP Payload Format for the Speex Codec + draft-ietf-avt-rtp-speex-01 (non-final) + +Status of this Memo + + By submitting this Internet-Draft, each author represents that any + applicable patent or other IPR claims of which he or she is aware + have been or will be disclosed, and any of which he or she becomes + aware will be disclosed, in accordance with Section 6 of BCP 79. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF), its areas, and its working groups. Note that + other groups may also distribute working documents as Internet- + Drafts. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + The list of current Internet-Drafts can be accessed at + http://www.ietf.org/ietf/1id-abstracts.txt. + + The list of Internet-Draft Shadow Directories can be accessed at + http://www.ietf.org/shadow.html. + + This Internet-Draft will expire on October 24, 2007. + +Copyright Notice + + Copyright (C) The Internet Society (2007). + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 1] + +Internet-Draft Speex April 2007 + + +Abstract + + Speex is an open-source voice codec suitable for use in Voice over IP + (VoIP) type applications. This document describes the payload format + for Speex generated bit streams within an RTP packet. Also included + here are the necessary details for the use of Speex with the Session + Description Protocol (SDP). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 2] + +Internet-Draft Speex April 2007 + + +Editors Note + + All references to RFC XXXX are to be replaced by references to the + RFC number of this memo, when published. + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 + 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 5 + 3. RTP usage for Speex . . . . . . . . . . . . . . . . . . . . . 6 + 3.1. RTP Speex Header Fields . . . . . . . . . . . . . . . . . 6 + 3.2. RTP payload format for Speex . . . . . . . . . . . . . . . 6 + 3.3. Speex payload . . . . . . . . . . . . . . . . . . . . . . 6 + 3.4. Example Speex packet . . . . . . . . . . . . . . . . . . . 7 + 3.5. Multiple Speex frames in a RTP packet . . . . . . . . . . 7 + 4. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9 + 4.1. Media Type Registration . . . . . . . . . . . . . . . . . 9 + 4.1.1. Registration of media type audio/speex . . . . . . . . 9 + 5. SDP usage of Speex . . . . . . . . . . . . . . . . . . . . . . 11 + 6. Security Considerations . . . . . . . . . . . . . . . . . . . 14 + 7. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 15 + 8. References . . . . . . . . . . . . . . . . . . . . . . . . . . 16 + 8.1. Normative References . . . . . . . . . . . . . . . . . . . 16 + 8.2. Informative References . . . . . . . . . . . . . . . . . . 16 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 17 + Intellectual Property and Copyright Statements . . . . . . . . . . 18 + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 3] + +Internet-Draft Speex April 2007 + + +1. Introduction + + Speex is based on the CELP [CELP] encoding technique with support for + either narrowband (nominal 8kHz), wideband (nominal 16kHz) or ultra- + wideband (nominal 32kHz). The main characteristics can be summarized + as follows: + + o Free software/open-source + + o Integration of wideband and narrowband in the same bit-stream + + o Wide range of bit-rates available + + o Dynamic bit-rate switching and variable bit-rate (VBR) + + o Voice Activity Detection (VAD, integrated with VBR) + + o Variable complexity + + To be compliant with this specification, implementations MUST support + 8 kHz sampling rate (narrowband)" and SHOULD support 8 kbps bitrate. + The sampling rate MUST be 8, 16 or 32 kHz. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 4] + +Internet-Draft Speex April 2007 + + +2. Terminology + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in RFC2119 [RFC2119] and + indicate requirement levels for compliant RTP implementations. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 5] + +Internet-Draft Speex April 2007 + + +3. RTP usage for Speex + +3.1. RTP Speex Header Fields + + The RTP header is defined in the RTP specification [RFC3550]. This + section defines how fields in the RTP header are used. + + Payload Type (PT): The assignment of an RTP payload type for this + packet format is outside the scope of this document; it is + specified by the RTP profile under which this payload format is + used, or signaled dynamically out-of-band (e.g., using SDP). + + Marker (M) bit: The M bit is set to one to indicate that the RTP + packet payload contains at least one complete frame + + Extension (X) bit: Defined by the RTP profile used. + + Timestamp: A 32-bit word that corresponds to the sampling instant + for the first frame in the RTP packet. + +3.2. RTP payload format for Speex + + The RTP payload for Speex has the format shown in Figure 1. No + additional header fields specific to this payload format are + required. For RTP based transportation of Speex encoded audio the + standard RTP header [RFC3550] is followed by one or more payload data + blocks. An optional padding terminator may also be used. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | one or more frames of Speex .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | one or more frames of Speex .... | padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 1: RTP payload for Speex + +3.3. Speex payload + + For the purposes of packetizing the bit stream in RTP, it is only + necessary to consider the sequence of bits as output by the Speex + encoder [speexenc], and present the same sequence to the decoder. + The payload format described here maintains this sequence. + + A typical Speex frame, encoded at the maximum bitrate, is approx. 110 + + + +Herlein, et al. Expires October 24, 2007 [Page 6] + +Internet-Draft Speex April 2007 + + + octets and the total number of Speex frames SHOULD be kept less than + the path MTU to prevent fragmentation. Speex frames MUST NOT be + fragmented across multiple RTP packets, + + An RTP packet MAY contain Speex frames of the same bit rate or of + varying bit rates, since the bit-rate for a frame is conveyed in band + with the signal. + + The encoding and decoding algorithm can change the bit rate at any 20 + msec frame boundary, with the bit rate change notification provided + in-band with the bit stream. Each frame contains both "mode" + (narrowband, wideband or ultra-wideband) and "sub-mode" (bit-rate) + information in the bit stream. No out-of-band notification is + required for the decoder to process changes in the bit rate sent by + the encoder. + + Sampling rate values of 8000, 16000 or 32000 Hz MUST be used. Any + other sampling rates MUST NOT be used. + + The RTP payload MUST be padded to provide an integer number of octets + as the payload length. These padding bits are LSB aligned in network + octet order and consist of a 0 followed by all ones (until the end of + the octet). This padding is only required for the last frame in the + packet, and only to ensure the packet contents ends on an octet + boundary. + +3.4. Example Speex packet + + In the example below we have a single Speex frame with 5 bits of + padding to ensure the packet size falls on an octet boundary. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. |0 1 1 1 1| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +3.5. Multiple Speex frames in a RTP packet + + Below is an example of two Speex frames contained within one RTP + packet. The Speex frame length in this example fall on an octet + boundary so there is no padding. + + Speex codecs [speexenc] are able to detect the bitrate from the + + + +Herlein, et al. Expires October 24, 2007 [Page 7] + +Internet-Draft Speex April 2007 + + + payload and are responsible for detecting the 20 msec boundaries + between each frame. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | ..speex frame 1.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex frame 1.. | ..speex frame 2.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex frame 2.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 8] + +Internet-Draft Speex April 2007 + + +4. IANA Considerations + + This document defines the Speex media type. + +4.1. Media Type Registration + + This section describes the media types and names associated with this + payload format. The section registers the media types, as per + RFC4288 [RFC4288] + +4.1.1. Registration of media type audio/speex + + Media type name: audio + + Media subtype name: speex + + Required parameters: + + None + + Optional parameters: + + ptime: see RFC 4566. SHOULD be a multiple of 20 msec. + + maxptime: see RFC 4566. SHOULD be a multiple of 20 msec. + + Encoding considerations: + + This media type is framed and binary, see section 4.8 in + [RFC4288]. + + Security considerations: See Section 6 + + Interoperability considerations: + + None. + + Published specification: RFC XXXX [This RFC]. + + Applications which use this media type: + + Audio streaming and conferencing applications. + + Additional information: none + + Person and email address to contact for further information : + + + + + +Herlein, et al. Expires October 24, 2007 [Page 9] + +Internet-Draft Speex April 2007 + + + Alfred E. Heggestad: aeh@db.org + + Intended usage: COMMON + + Restrictions on usage: + + This media type depends on RTP framing, and hence is only defined + for transfer via RTP [RFC3550]. Transport within other framing + protocols is not defined at this time. + + Author: Alfred E. Heggestad + + Change controller: + + IETF Audio/Video Transport working group delegated from the IESG. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 10] + +Internet-Draft Speex April 2007 + + +5. SDP usage of Speex + + When conveying information by SDP [RFC4566], the encoding name MUST + be set to "speex". An example of the media representation in SDP for + offering a single channel of Speex at 8000 samples per second might + be: + + m=audio 8088 RTP/AVP 97 + a=rtpmap:97 speex/8000 + + Note that the RTP payload type code of 97 is defined in this media + definition to be 'mapped' to the speex codec at an 8kHz sampling + frequency using the 'a=rtpmap' line. Any number from 96 to 127 could + have been chosen (the allowed range for dynamic types). + + The value of the sampling frequency is typically 8000 for narrow band + operation, 16000 for wide band operation, and 32000 for ultra-wide + band operation. + + If for some reason the offerer has bandwidth limitations, the client + may use the "b=" header, as explained in SDP [RFC4566]. The + following example illustrates the case where the offerer cannot + receive more than 10 kbit/s. + + m=audio 8088 RTP/AVP 97 + b=AS:10 + a=rtmap:97 speex/8000 + + In this case, if the remote part agrees, it should configure its + Speex encoder so that it does not use modes that produce more than 10 + kbit/s. Note that the "b=" constraint also applies on all payload + types that may be proposed in the media line ("m="). + + An other way to make recommendations to the remote Speex encoder is + to use its specific parameters via the a=fmtp: directive. The + following parameters are defined for use in this way: + + ptime: duration of each packet in milliseconds. + + + sr: actual sample rate in Hz. + + + ebw: encoding bandwidth - either 'narrow' or 'wide' or 'ultra' + (corresponds to nominal 8000, 16000, and 32000 Hz sampling rates). + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 11] + +Internet-Draft Speex April 2007 + + + vbr: variable bit rate - either 'on' 'off' or 'vad' (defaults to + off). If on, variable bit rate is enabled. If off, disabled. If + set to 'vad' then constant bit rate is used but silence will be + encoded with special short frames to indicate a lack of voice for + that period. + + + cng: comfort noise generation - either 'on' or 'off'. If off then + silence frames will be silent; if 'on' then those frames will be + filled with comfort noise. + + + mode: Speex encoding mode. Can be {1,2,3,4,5,6,any} defaults to 3 + in narrowband, 6 in wide and ultra-wide. + + + Examples: + + m=audio 8008 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=fmtp:97 mode=4 + + This examples illustrate an offerer that wishes to receive a Speex + stream at 8000Hz, but only using speex mode 4. + + Several Speex specific parameters can be given in a single a=fmtp + line provided that they are separated by a semi-colon: + + a=fmtp:97 mode=any;mode=1 + + The offerer may indicate that it wishes to send variable bit rate + frames with comfort noise: + + m=audio 8088 RTP/AVP 97 + a=rtmap:97 speex/8000 + a=fmtp:97 vbr=on;cng=on + + The "ptime" attribute is used to denote the packetization interval + (ie, how many milliseconds of audio is encoded in a single RTP + packet). Since Speex uses 20 msec frames, ptime values of multiples + of 20 denote multiple Speex frames per packet. Values of ptime which + are not multiples of 20 MUST be ignored and clients MUST use the + default value of 20 instead. + + Implementations SHOULD support ptime of 20 msec (i.e. one frame per + packet) + + In the example below the ptime value is set to 40, indicating that + + + +Herlein, et al. Expires October 24, 2007 [Page 12] + +Internet-Draft Speex April 2007 + + + there are 2 frames in each packet. + + m=audio 8008 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=ptime:40 + + Note that the ptime parameter applies to all payloads listed in the + media line and is not used as part of an a=fmtp directive. + + Values of ptime not multiple of 20 msec are meaningless, so the + receiver of such ptime values MUST ignore them. If during the life + of an RTP session the ptime value changes, when there are multiple + Speex frames for example, the SDP value must also reflect the new + value. + + Care must be taken when setting the value of ptime so that the RTP + packet size does not exceed the path MTU. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 13] + +Internet-Draft Speex April 2007 + + +6. Security Considerations + + RTP packets using the payload format defined in this specification + are subject to the security considerations discussed in the RTP + specification [RFC3550], and any appropriate RTP profile. This + implies that confidentiality of the media streams is achieved by + encryption. Because the data compression used with this payload + format is applied end-to-end, encryption may be performed after + compression so there is no conflict between the two operations. + + A potential denial-of-service threat exists for data encodings using + compression techniques that have non-uniform receiver-end + computational load. The attacker can inject pathological datagrams + into the stream which are complex to decode and cause the receiver to + be overloaded. However, this encoding does not exhibit any + significant non-uniformity. + + As with any IP-based protocol, in some circumstances a receiver may + be overloaded simply by the receipt of too many packets, either + desired or undesired. Network-layer authentication may be used to + discard packets from undesired sources, but the processing cost of + the authentication itself may be too high. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 14] + +Internet-Draft Speex April 2007 + + +7. Acknowledgements + + The authors would like to thank Equivalence Pty Ltd of Australia for + their assistance in attempting to standardize the use of Speex in + H.323 applications, and for implementing Speex in their open source + OpenH323 stack. The authors would also like to thank Brian C. Wiles + <brian@streamcomm.com> of StreamComm for his assistance in developing + the proposed standard for Speex use in H.323 applications. + + The authors would also like to thank the following members of the + Speex and AVT communities for their input: Ross Finlayson, Federico + Montesino Pouzols, Henning Schulzrinne, Magnus Westerlund. + + Thanks to former authors of this document; Simon Morlat, Roger + Hardiman, Phil Kerr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 15] + +Internet-Draft Speex April 2007 + + +8. References + +8.1. Normative References + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC3550] Schulzrinne, H., Casner, S., Frederick, R., and V. + Jacobson, "RTP: A Transport Protocol for Real-Time + Applications", STD 64, RFC 3550, July 2003. + + [RFC4566] Handley, M., Jacobson, V., and C. Perkins, "SDP: Session + Description Protocol", RFC 4566, July 2006. + +8.2. Informative References + + [CELP] "CELP, U.S. Federal Standard 1016.", National Technical + Information Service (NTIS) website http://www.ntis.gov/. + + [RFC4288] Freed, N. and J. Klensin, "Media Type Specifications and + Registration Procedures", BCP 13, RFC 4288, December 2005. + + [speexenc] + Valin, J., "Speexenc/speexdec, reference command-line + encoder/decoder", Speex website http://www.speex.org/. + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 16] + +Internet-Draft Speex April 2007 + + +Authors' Addresses + + Greg Herlein + 2034 Filbert Street + San Francisco, California 94123 + United States + + Email: gherlein@herlein.com + + + Jean-Marc Valin + University of Sherbrooke + Department of Electrical and Computer Engineering + University of Sherbrooke + 2500 blvd Universite + Sherbrooke, Quebec J1K 2R1 + Canada + + Email: jean-marc.valin@usherbrooke.ca + + + Alfred E. Heggestad + Biskop J. Nilssonsgt. 20a + Oslo 0659 + Norway + + Email: aeh@db.org + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires October 24, 2007 [Page 17] + +Internet-Draft Speex April 2007 + + +Full Copyright Statement + + Copyright (C) The Internet Society (2007). + + This document is subject to the rights, licenses and restrictions + contained in BCP 78, and except as set forth therein, the authors + retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE + INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at + ietf-ipr@ietf.org. + + +Acknowledgment + + Funding for the RFC Editor function is provided by the IETF + Administrative Support Activity (IASA). + + + + + +Herlein, et al. Expires October 24, 2007 [Page 18] + diff --git a/src/libs/speexdsp/doc/draft-ietf-avt-rtp-speex-05-tmp.txt b/src/libs/speexdsp/doc/draft-ietf-avt-rtp-speex-05-tmp.txt new file mode 100644 index 00000000..70c8007a --- /dev/null +++ b/src/libs/speexdsp/doc/draft-ietf-avt-rtp-speex-05-tmp.txt @@ -0,0 +1,1288 @@ + + + +AVT G. Herlein +Internet-Draft +Intended status: Standards Track J. Valin +Expires: August 19, 2008 CSIRO + A. Heggestad + Creytiv.com + A. Moizard + Antisip + February 16, 2008 + + + RTP Payload Format for the Speex Codec + draft-ietf-avt-rtp-speex-05 + +Status of this Memo + + By submitting this Internet-Draft, each author represents that any + applicable patent or other IPR claims of which he or she is aware + have been or will be disclosed, and any of which he or she becomes + aware will be disclosed, in accordance with Section 6 of BCP 79. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF), its areas, and its working groups. Note that + other groups may also distribute working documents as Internet- + Drafts. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + The list of current Internet-Drafts can be accessed at + http://www.ietf.org/ietf/1id-abstracts.txt. + + The list of Internet-Draft Shadow Directories can be accessed at + http://www.ietf.org/shadow.html. + + This Internet-Draft will expire on August 19, 2008. + +Copyright Notice + + Copyright (C) The IETF Trust (2008). + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 1] + +Internet-Draft Speex February 2008 + + +Abstract + + Speex is an open-source voice codec suitable for use in Voice over IP + (VoIP) type applications. This document describes the payload format + for Speex generated bit streams within an RTP packet. Also included + here are the necessary details for the use of Speex with the Session + Description Protocol (SDP). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 2] + +Internet-Draft Speex February 2008 + + +Editors Note + + All references to RFC XXXX are to be replaced by references to the + RFC number of this memo, when published. + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 + 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 5 + 3. RTP usage for Speex . . . . . . . . . . . . . . . . . . . . . 6 + 3.1. RTP Speex Header Fields . . . . . . . . . . . . . . . . . 6 + 3.2. RTP payload format for Speex . . . . . . . . . . . . . . . 6 + 3.3. Speex payload . . . . . . . . . . . . . . . . . . . . . . 6 + 3.4. Example Speex packet . . . . . . . . . . . . . . . . . . . 7 + 3.5. Multiple Speex frames in a RTP packet . . . . . . . . . . 7 + 4. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9 + 4.1. Media Type Registration . . . . . . . . . . . . . . . . . 9 + 4.1.1. Registration of media type audio/speex . . . . . . . . 9 + 5. SDP usage of Speex . . . . . . . . . . . . . . . . . . . . . . 12 + 5.1. Example supporting all modes, prefer mode 4 . . . . . . . 15 + 5.2. Example supporting only mode 3 and 5 . . . . . . . . . . . 15 + 5.3. Example with Variable Bit Rate and Comfort Noise . . . . . 15 + 5.4. Example with Voice Activity Detection . . . . . . . . . . 15 + 5.5. Example with Multiple sampling rates . . . . . . . . . . . 15 + 5.6. Example with ptime and Multiple Speex frames . . . . . . . 16 + 5.7. Example with Complete Offer/Answer exchange . . . . . . . 16 + 6. Implementation Guidelines . . . . . . . . . . . . . . . . . . 17 + 7. Security Considerations . . . . . . . . . . . . . . . . . . . 18 + 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 19 + 9. Copying conditions . . . . . . . . . . . . . . . . . . . . . . 20 + 10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 21 + 10.1. Normative References . . . . . . . . . . . . . . . . . . . 21 + 10.2. Informative References . . . . . . . . . . . . . . . . . . 21 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 22 + Intellectual Property and Copyright Statements . . . . . . . . . . 23 + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 3] + +Internet-Draft Speex February 2008 + + +1. Introduction + + Speex is based on the CELP [CELP] encoding technique with support for + either narrowband (nominal 8kHz), wideband (nominal 16kHz) or ultra- + wideband (nominal 32kHz). The main characteristics can be summarized + as follows: + + o Free software/open-source + + o Integration of wideband and narrowband in the same bit-stream + + o Wide range of bit-rates available + + o Dynamic bit-rate switching and variable bit-rate (VBR) + + o Voice Activity Detection (VAD, integrated with VBR) + + o Variable complexity + + The Speex codec supports a wide range of bit-rates from 2.15 kbit/s + to 44 kbit/s. In some cases however, it may not be possible for an + implementation to include support for all rates (e.g. because of + bandwidth, RAM or CPU constraints). In those cases, to be compliant + with this specification, implementations MUST support at least + narrowband (8 kHz) encoding and decoding at 8 kbit/s bit-rate + (narrowband mode 3). Support for narrowband at 15 kbit/s (narrowband + mode 5) is RECOMMENDED and support for wideband at 27.8 kbit/s + (wideband mode 8) is also RECOMMENDED. The sampling rate MUST be 8, + 16 or 32 kHz. + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 4] + +Internet-Draft Speex February 2008 + + +2. Terminology + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in RFC2119 [RFC2119] and + indicate requirement levels for compliant RTP implementations. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 5] + +Internet-Draft Speex February 2008 + + +3. RTP usage for Speex + +3.1. RTP Speex Header Fields + + The RTP header is defined in the RTP specification [RFC3550]. This + section defines how fields in the RTP header are used. + + Payload Type (PT): The assignment of an RTP payload type for this + packet format is outside the scope of this document; it is + specified by the RTP profile under which this payload format is + used, or signaled dynamically out-of-band (e.g., using SDP). + + Marker (M) bit: The M bit is set to one on the first packet sent + after a silence period, during which packets have not been + transmitted contiguously. + + Extension (X) bit: Defined by the RTP profile used. + + Timestamp: A 32-bit word that corresponds to the sampling instant + for the first frame in the RTP packet. + +3.2. RTP payload format for Speex + + The RTP payload for Speex has the format shown in Figure 1. No + additional header fields specific to this payload format are + required. For RTP based transportation of Speex encoded audio the + standard RTP header [RFC3550] is followed by one or more payload data + blocks. An optional padding terminator may also be used. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | one or more frames of Speex .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | one or more frames of Speex .... | padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 1: RTP payload for Speex + +3.3. Speex payload + + For the purposes of packetizing the bit stream in RTP, it is only + necessary to consider the sequence of bits as output by the Speex + encoder [speex_manual], and present the same sequence to the decoder. + The payload format described here maintains this sequence. + + + + +Herlein, et al. Expires August 19, 2008 [Page 6] + +Internet-Draft Speex February 2008 + + + A typical Speex frame, encoded at the maximum bitrate, is approx. 110 + octets and the total number of Speex frames SHOULD be kept less than + the path MTU to prevent fragmentation. Speex frames MUST NOT be + fragmented across multiple RTP packets, + + An RTP packet MAY contain Speex frames of the same bit rate or of + varying bit rates, since the bit-rate for a frame is conveyed in band + with the signal. + + The encoding and decoding algorithm can change the bit rate at any 20 + msec frame boundary, with the bit rate change notification provided + in-band with the bit stream. Each frame contains both sampling rate + (narrowband, wideband or ultra-wideband) and "mode" (bit-rate) + information in the bit stream. No out-of-band notification is + required for the decoder to process changes in the bit rate sent by + the encoder. + + The sampling rate MUST be either 8000 Hz, 16000 Hz, or 32000 Hz. + + The RTP payload MUST be padded to provide an integer number of octets + as the payload length. These padding bits are LSB aligned in network + octet order and consist of a 0 followed by all ones (until the end of + the octet). This padding is only required for the last frame in the + packet, and only to ensure the packet contents ends on an octet + boundary. + +3.4. Example Speex packet + + In the example below we have a single Speex frame with 5 bits of + padding to ensure the packet size falls on an octet boundary. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | ..speex data.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex data.. |0 1 1 1 1| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +3.5. Multiple Speex frames in a RTP packet + + Below is an example of two Speex frames contained within one RTP + packet. The Speex frame length in this example fall on an octet + boundary so there is no padding. + + The Speex decoder [speex_manual] can detect the bitrate from the + + + +Herlein, et al. Expires August 19, 2008 [Page 7] + +Internet-Draft Speex February 2008 + + + payload and is responsible for detecting the 20 msec boundaries + between each frame. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | RTP Header | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | ..speex frame 1.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex frame 1.. | ..speex frame 2.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ..speex frame 2.. | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 8] + +Internet-Draft Speex February 2008 + + +4. IANA Considerations + + This document defines the Speex media type. + +4.1. Media Type Registration + + This section describes the media types and names associated with this + payload format. The section registers the media types, as per + RFC4288 [RFC4288] + +4.1.1. Registration of media type audio/speex + + Media type name: audio + + Media subtype name: speex + + Required parameters: + + rate: RTP timestamp clock rate, which is equal to the sampling + rate in Hz. The sampling rate MUST be either 8000, 16000, or + 32000. + + Optional parameters: + + ptime: SHOULD be a multiple of 20 msec [RFC4566] + + maxptime: SHOULD be a multiple of 20 msec [RFC4566] + + vbr: variable bit rate - either 'on' 'off' or 'vad' (defaults to + off). If on, variable bit rate is enabled. If off, disabled. If + set to 'vad' then constant bit rate is used but silence will be + encoded with special short frames to indicate a lack of voice for + that period. + + + cng: comfort noise generation - either 'on' or 'off'. If off then + silence frames will be silent; if 'on' then those frames will be + filled with comfort noise. + + + mode: List supported Speex decoding modes. The valid modes are + different for narrowband and wideband, and are defined as follows: + + * {1,2,3,4,5,6,7,8,any} for narrowband + + * {0,1,2,3,4,5,6,7,8,9,10,any} for wideband and ultra-wideband + + Several 'mode' parameters can be provided. In this case, the + + + +Herlein, et al. Expires August 19, 2008 [Page 9] + +Internet-Draft Speex February 2008 + + + remote party SHOULD configure its encoder using the first + supported mode provided. When 'any' is used, the offerer + indicates that it supports all decoding modes. If the 'mode' + parameter is not provided, the mode value is considered to be + equivalent to 'mode=3;mode=any' in narrowband and + 'mode=8;mode=any' in wideband and ultra-wideband. Note that each + Speex frame does contains the mode (or bit-rate) that should be + used to decode it. Thus application MUST be able to decode any + Speex frame unless the SDP clearly specify that some modes are not + supported. (e.g., by not including 'mode=any') + + Encoding considerations: + + This media type is framed and binary, see section 4.8 in + [RFC4288]. + + Security considerations: See Section 6 + + Interoperability considerations: + + None. + + Published specification: + + RFC XXXX [RFC Editor: please replace by the RFC number of this + memo, when published] + + Applications which use this media type: + + Audio streaming and conferencing applications. + + Additional information: none + + Person and email address to contact for further information : + + Alfred E. Heggestad: aeh@db.org + + Intended usage: COMMON + + Restrictions on usage: + + This media type depends on RTP framing, and hence is only defined + for transfer via RTP [RFC3550]. Transport within other framing + protocols is not defined at this time. + + Author: Alfred E. Heggestad + + Change controller: + + + +Herlein, et al. Expires August 19, 2008 [Page 10] + +Internet-Draft Speex February 2008 + + + IETF Audio/Video Transport working group delegated from the IESG. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 11] + +Internet-Draft Speex February 2008 + + +5. SDP usage of Speex + + The information carried in the media type specification has a + specific mapping to fields in the Session Description Protocol (SDP) + [RFC4566], which is commonly used to describe RTP sessions. When SDP + is used to specify sessions employing the Speex codec, the mapping is + as follows: + + o The media type ("audio") goes in SDP "m=" as the media name. + + o The media subtype ("speex") goes in SDP "a=rtpmap" as the encoding + name. The required parameter "rate" also goes in "a=rtpmap" as + the clock rate. + + o The parameters "ptime" and "maxptime" go in the SDP "a=ptime" and + "a=maxptime" attributes, respectively. + + o Any remaining parameters go in the SDP "a=fmtp" attribute by + copying them directly from the media type string as a semicolon + separated list of parameter=value pairs. + + The tables below include the equivalence between modes and bitrates + for narrowband, wideband and ultra-wideband. Also, the corresponding + "Speex quality" setting (see SPEEX_SET_QUALITY in The Speex Codec + Manual [speex_manual]) is included as an indication. + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 12] + +Internet-Draft Speex February 2008 + + + +------+---------------+-------------+ + | mode | Speex quality | bitrate | + +------+---------------+-------------+ + | 1 | 0 | 2.15 kbit/s | + | | | | + | 2 | 2 | 5.95 kbit/s | + | | | | + | 3 | 3 or 4 | 8.00 kbit/s | + | | | | + | 4 | 5 or 6 | 11.0 kbit/s | + | | | | + | 5 | 7 or 8 | 15.0 kbit/s | + | | | | + | 6 | 9 | 18.2 kbit/s | + | | | | + | 7 | 10 | 24.6 kbit/s | + | | | | + | 8 | 1 | 3.95 kbit/s | + +------+---------------+-------------+ + + Mode vs Bitrate table for narrowband + + Table 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 13] + +Internet-Draft Speex February 2008 + + + +------+---------------+------------------+------------------------+ + | mode | Speex quality | wideband bitrate | ultra wideband bitrate | + +------+---------------+------------------+------------------------+ + | 0 | 0 | 3.95 kbit/s | 5.75 kbit/s | + | | | | | + | 1 | 1 | 5.75 kbit/s | 7.55 kbit/s | + | | | | | + | 2 | 2 | 7.75 kbit/s | 9.55 kbit/s | + | | | | | + | 3 | 3 | 9.80 kbit/s | 11.6 kbit/s | + | | | | | + | 4 | 4 | 12.8 kbit/s | 14.6 kbit/s | + | | | | | + | 5 | 5 | 16.8 kbit/s | 18.6 kbit/s | + | | | | | + | 6 | 6 | 20.6 kbit/s | 22.4 kbit/s | + | | | | | + | 7 | 7 | 23.8 kbit/s | 25.6 kbit/s | + | | | | | + | 8 | 8 | 27.8 kbit/s | 29.6 kbit/s | + | | | | | + | 9 | 9 | 34.2 kbit/s | 36.0 kbit/s | + | | | | | + | 10 | 10 | 42.2 kbit/s | 44.0 kbit/s | + +------+---------------+------------------+------------------------+ + + Mode vs Bitrate table for wideband and ultra-wideband + + Table 2 + + The Speex parameters indicate the decoding capabilities of the agent, + and what the agent prefers to receive. + + The Speex parameters in an SDP Offer/Answer exchange are completely + orthogonal, and there is no relationship between the SDP Offer and + the Answer. + + Several Speex specific parameters can be given in a single a=fmtp + line provided that they are separated by a semi-colon: + + a=fmtp:97 mode=1;mode=any;vbr=on + + Some example SDP session descriptions utilizing Speex encodings + follow. + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 14] + +Internet-Draft Speex February 2008 + + +5.1. Example supporting all modes, prefer mode 4 + + The offerer indicates that it wishes to receive a Speex stream at + 8000Hz, and wishes to receive Speex 'mode 4'. It is important to + understand that any other mode might still be sent by remote party: + the device might have bandwidth limitation or might only be able to + send 'mode=3'. Thus, application that support all decoding modes + SHOULD include 'mode=any' as shown in the example below: + + m=audio 8088 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=fmtp:97 mode=4;mode=any + +5.2. Example supporting only mode 3 and 5 + + The offerer indicates the mode he wishes to receive (Speex 'mode 3'). + This offer indicates mode 3 and mode 5 are supported and that no + other modes are supported. The remote party MUST NOT configure its + encoder using another Speex mode. + + m=audio 8088 RTP/AVP 97 + a=rtmap:97 speex/8000 + a=fmtp:97 mode=3;mode=5 + +5.3. Example with Variable Bit Rate and Comfort Noise + + The offerer indicates that it wishes to receive variable bit rate + frames with comfort noise: + + m=audio 8088 RTP/AVP 97 + a=rtmap:97 speex/8000 + a=fmtp:97 vbr=on;cng=on + +5.4. Example with Voice Activity Detection + + The offerer indicates that it wishes to use silence suppression. In + this case vbr=vad parameter will be used: + + m=audio 8088 RTP/AVP 97 + a=rtmap:97 speex/8000 + a=fmtp:97 vbr=vad + +5.5. Example with Multiple sampling rates + + The offerer indicates that it wishes to receive Speex audio at 16000 + Hz with mode 10 (42.2 kbit/s), alternatively Speex audio at 8000 Hz + with mode 7 (24.6 kbit/s). The offerer supports decoding all modes. + + + + +Herlein, et al. Expires August 19, 2008 [Page 15] + +Internet-Draft Speex February 2008 + + + m=audio 8088 RTP/AVP 97 98 + a=rtmap:97 speex/16000 + a=fmtp:97 mode=10;mode=any + a=rtmap:98 speex/8000 + a=fmtp:98 mode=7;mode=any + +5.6. Example with ptime and Multiple Speex frames + + The "ptime" attribute is used to denote the packetization interval + (ie, how many milliseconds of audio is encoded in a single RTP + packet). Since Speex uses 20 msec frames, ptime values of multiples + of 20 denote multiple Speex frames per packet. Values of ptime which + are not multiples of 20 MUST be rounded up to the first multiple of + 20 above the ptime value. + + In the example below the ptime value is set to 40, indicating that + there are 2 frames in each packet. + + m=audio 8088 RTP/AVP 97 + a=rtpmap:97 speex/8000 + a=ptime:40 + + Note that the ptime parameter applies to all payloads listed in the + media line and is not used as part of an a=fmtp directive. + + Care must be taken when setting the value of ptime so that the RTP + packet size does not exceed the path MTU. + +5.7. Example with Complete Offer/Answer exchange + + The offerer indicates that it wishes to receive Speex audio at 16000 + Hz, alternatively Speex audio at 8000 Hz. The offerer does support + ALL modes because no mode is specified. + + m=audio 8088 RTP/AVP 97 98 + a=rtmap:97 speex/16000 + a=rtmap:98 speex/8000 + + The answerer indicates that it wishes to receive Speex audio at 8000 + Hz, which is the only sampling rate it supports. The answerer does + support ALL modes because no mode is specified. + + m=audio 8088 RTP/AVP 99 + a=rtmap:99 speex/8000 + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 16] + +Internet-Draft Speex February 2008 + + +6. Implementation Guidelines + + Implementations that supports Speex are responsible for correctly + decoding incoming Speex frames. + + Each Speex frame does contains all needed informations to decode + itself. In particular, the 'mode' and 'ptime' values proposed in the + SDP contents MUST NOT be used for decoding: those values are not + needed to properly decode a RTP Speex stream. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 17] + +Internet-Draft Speex February 2008 + + +7. Security Considerations + + RTP packets using the payload format defined in this specification + are subject to the security considerations discussed in the RTP + specification [RFC3550], and any appropriate RTP profile. This + implies that confidentiality of the media streams is achieved by + encryption. Because the data compression used with this payload + format is applied end-to-end, encryption may be performed after + compression so there is no conflict between the two operations. + + A potential denial-of-service threat exists for data encodings using + compression techniques that have non-uniform receiver-end + computational load. The attacker can inject pathological datagrams + into the stream which are complex to decode and cause the receiver to + be overloaded. However, this encoding does not exhibit any + significant non-uniformity. + + As with any IP-based protocol, in some circumstances a receiver may + be overloaded simply by the receipt of too many packets, either + desired or undesired. Network-layer authentication may be used to + discard packets from undesired sources, but the processing cost of + the authentication itself may be too high. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 18] + +Internet-Draft Speex February 2008 + + +8. Acknowledgements + + The authors would like to thank Equivalence Pty Ltd of Australia for + their assistance in attempting to standardize the use of Speex in + H.323 applications, and for implementing Speex in their open source + OpenH323 stack. The authors would also like to thank Brian C. Wiles + <brian@streamcomm.com> of StreamComm for his assistance in developing + the proposed standard for Speex use in H.323 applications. + + The authors would also like to thank the following members of the + Speex and AVT communities for their input: Ross Finlayson, Federico + Montesino Pouzols, Henning Schulzrinne, Magnus Westerlund, Colin + Perkins, Ivo Emanuel Goncalves. + + Thanks to former authors of this document; Simon Morlat, Roger + Hardiman, Phil Kerr. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 19] + +Internet-Draft Speex February 2008 + + +9. Copying conditions + + The authors agree to grant third parties the irrevocable right to + copy, use and distribute the work, with or without modification, in + any medium, without royalty, provided that, unless separate + permission is granted, redistributed modified works do not contain + misleading author, version, name of work, or endorsement information. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 20] + +Internet-Draft Speex February 2008 + + +10. References + +10.1. Normative References + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC3550] Schulzrinne, H., Casner, S., Frederick, R., and V. + Jacobson, "RTP: A Transport Protocol for Real-Time + Applications", STD 64, RFC 3550, July 2003. + + [RFC4566] Handley, M., Jacobson, V., and C. Perkins, "SDP: Session + Description Protocol", RFC 4566, July 2006. + +10.2. Informative References + + [CELP] "CELP, U.S. Federal Standard 1016.", National Technical + Information Service (NTIS) website http://www.ntis.gov/. + + [RFC4288] Freed, N. and J. Klensin, "Media Type Specifications and + Registration Procedures", BCP 13, RFC 4288, December 2005. + + [speex_manual] + Valin, J., "The Speex Codec Manual", Speex + website http://www.speex.org/docs/. + + + + + + + + + + + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 21] + +Internet-Draft Speex February 2008 + + +Authors' Addresses + + Greg Herlein + 2034 Filbert Street + San Francisco, California 94123 + United States + + Email: gherlein@herlein.com + + + Jean-Marc Valin + CSIRO + PO Box 76 + Epping, NSW 1710 + Australia + + Email: jean-marc.valin@usherbrooke.ca + + + Alfred E. Heggestad + Creytiv.com + Biskop J. Nilssonsgt. 20a + Oslo 0659 + Norway + + Email: aeh@db.org + + + Aymeric Moizard + Antisip + 4 Quai Perrache + Lyon 69002 + France + + Email: jack@atosc.org + + + + + + + + + + + + + + + + +Herlein, et al. Expires August 19, 2008 [Page 22] + +Internet-Draft Speex February 2008 + + +Full Copyright Statement + + Copyright (C) The IETF Trust (2008). + + This document is subject to the rights, licenses and restrictions + contained in BCP 78, and except as set forth therein, the authors + retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND + THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF + THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at + ietf-ipr@ietf.org. + + +Acknowledgment + + Funding for the RFC Editor function is provided by the IETF + Administrative Support Activity (IASA). + + + + + +Herlein, et al. Expires August 19, 2008 [Page 23] + diff --git a/src/libs/speexdsp/doc/echo_path.eps b/src/libs/speexdsp/doc/echo_path.eps new file mode 100644 index 00000000..c5a458c5 --- /dev/null +++ b/src/libs/speexdsp/doc/echo_path.eps @@ -0,0 +1,1298 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 415 235 +%%Pages: 0 +%%Creator: Sun Microsystems, Inc. +%%Title: none +%%CreationDate: none +%%LanguageLevel: 2 +%%EndComments +%%BeginProlog +%%BeginResource: procset SDRes-Prolog 1.0 0 +/b4_inc_state save def +/dict_count countdictstack def +/op_count count 1 sub def +userdict begin +0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath +/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if +/bdef {bind def} bind def +/c {setgray} bdef +/l {neg lineto} bdef +/rl {neg rlineto} bdef +/lc {setlinecap} bdef +/lj {setlinejoin} bdef +/lw {setlinewidth} bdef +/ml {setmiterlimit} bdef +/ld {setdash} bdef +/m {neg moveto} bdef +/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef +/r {rotate} bdef +/t {neg translate} bdef +/s {scale} bdef +/sw {show} bdef +/gs {gsave} bdef +/gr {grestore} bdef +/f {findfont dup length dict begin +{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def +currentdict end /NFont exch definefont pop /NFont findfont} bdef +/p {closepath} bdef +/sf {scalefont setfont} bdef +/ef {eofill}bdef +/pc {closepath stroke}bdef +/ps {stroke}bdef +/pum {matrix currentmatrix}bdef +/pom {setmatrix}bdef +/bs {/aString exch def /nXOfs exch def /nWidth exch def currentpoint nXOfs 0 rmoveto pum nWidth aString stringwidth pop div 1 scale aString show pom moveto} bdef +%%EndResource +%%EndProlog +%%BeginSetup +%%EndSetup +%%Page: 1 1 +%%BeginPageSetup +%%EndPageSetup +pum +0.02836 0.02836 s +0 -8286 t +/tm matrix currentmatrix def +tm setmatrix +-3900 -8857 t +1 1 s +0.000 c 10000 12000 m 9581 12419 l 9413 12084 l 10000 12000 l p ef +6989 13478 m 9586 12179 l 9609 12224 l 7011 13522 l 6989 13478 l p ef +0.996 c 8500 13800 m 7500 13800 l 7500 11800 l 9500 11800 l 9500 13800 l +8500 13800 l p ef +50 lw 1 lj 0.000 c 8500 13800 m 7500 13800 l 7500 11800 l 9500 11800 l +9500 13800 l 8500 13800 l pc +gs +gs +pum +8080 12960 t +103 -334 m 103 -334 103 -334 8 -334 ct 8 -334 8 -334 8 -323 ct 31 -318 34 -314 34 -294 ct +34 -294 34 -294 34 -42 ct 34 -21 30 -16 8 -12 ct 8 -12 8 -12 8 0 ct 8 0 8 0 127 0 ct +127 0 127 0 127 -12 ct 109 -14 103 -22 103 -40 ct 103 -40 103 -40 103 -172 ct 103 -174 106 -179 111 -184 ct +122 -195 134 -201 145 -201 ct 163 -201 171 -188 171 -160 ct 171 -160 171 -160 171 -40 ct +171 -22 165 -14 148 -12 ct 148 -12 148 -12 148 0 ct 148 0 148 0 264 0 ct 264 0 264 0 264 -12 ct +246 -13 240 -21 240 -42 ct 240 -42 240 -42 240 -164 ct 240 -207 213 -234 173 -234 ct +147 -234 128 -224 103 -195 ct 103 -195 103 -195 103 -334 ct p ef +pom +gr +gs +pum +8351 12960 t +143 -334 m 107 -310 92 -297 75 -274 ct 40 -231 23 -182 23 -124 ct 23 -62 41 -13 84 37 ct +104 61 116 72 141 87 ct 141 87 141 87 147 79 ct 108 48 95 31 82 -6 ct 70 -39 65 -76 65 -126 ct +65 -178 71 -218 84 -249 ct 98 -279 112 -297 147 -326 ct 147 -326 147 -326 143 -334 ct +p ef +pom +gr +gs +pum +8516 12960 t +227 -58 m 227 -58 227 -58 217 -45 ct 203 -27 194 -19 187 -19 ct 183 -19 179 -23 179 -27 ct +179 -31 179 -31 186 -58 ct 186 -58 186 -58 214 -160 ct 216 -170 218 -181 218 -188 ct +218 -206 205 -218 186 -218 ct 154 -218 123 -189 72 -110 ct 72 -110 72 -110 105 -217 ct +105 -217 105 -217 104 -218 ct 77 -213 67 -211 24 -203 ct 24 -203 24 -203 24 -195 ct +49 -195 55 -192 55 -182 ct 55 -179 55 -176 54 -173 ct 54 -173 54 -173 7 0 ct 7 0 7 0 44 0 ct +67 -78 72 -89 93 -123 ct 123 -168 148 -193 166 -193 ct 174 -193 178 -188 178 -179 ct +178 -173 175 -156 171 -141 ct 171 -141 171 -141 150 -60 ct 143 -35 142 -28 142 -23 ct +142 -4 149 4 165 4 ct 187 4 200 -6 234 -52 ct 234 -52 234 -52 227 -58 ct p ef +pom +gr +gs +pum +8766 12960 t +18 87 m 54 64 69 51 87 28 ct 121 -15 138 -64 138 -122 ct 138 -185 120 -233 77 -283 ct +58 -307 45 -318 20 -334 ct 20 -334 20 -334 14 -326 ct 53 -295 66 -277 79 -240 ct +91 -207 96 -170 96 -120 ct 96 -69 90 -28 77 2 ct 63 33 49 51 14 79 ct 14 79 14 79 18 87 ct +p ef +pom +gr +gr +14100 16000 m 13824 16000 13600 15776 13600 15500 ct 13600 15224 13824 15000 14100 15000 ct +14376 15000 14600 15224 14600 15500 ct 14600 15776 14376 16000 14100 16000 ct +pc +gs +gs +pum +13954 15668 t +121 -141 m 15 -141 l 15 -108 l 121 -108 l 121 0 l 153 0 l 153 -108 l +259 -108 l 259 -141 l 153 -141 l 153 -250 l 121 -250 l 121 -141 l +p ef +pom +gr +gr +8500 16000 m 8224 16000 8000 15776 8000 15500 ct 8000 15224 8224 15000 8500 15000 ct +8776 15000 9000 15224 9000 15500 ct 9000 15776 8776 16000 8500 16000 ct pc +8500 15000 m 8313 14438 l 8688 14438 l 8500 15000 l p ef +8525 13800 m 8525 14550 l 8475 14550 l 8475 13800 l 8525 13800 l p ef +9000 15500 m 9563 15313 l 9563 15688 l 9000 15500 l p ef +13600 15525 m 9450 15525 l 9450 15475 l 13600 15475 l 13600 15525 l +p ef +14100 13800 m 13100 13800 l 13100 11800 l 15100 11800 l 15100 13800 l +14100 13800 l pc +gs +gs +pum +13663 12960 t +103 -334 m 103 -334 103 -334 8 -334 ct 8 -334 8 -334 8 -323 ct 31 -318 34 -314 34 -294 ct +34 -294 34 -294 34 -42 ct 34 -21 30 -16 8 -12 ct 8 -12 8 -12 8 0 ct 8 0 8 0 127 0 ct +127 0 127 0 127 -12 ct 109 -14 103 -22 103 -40 ct 103 -40 103 -40 103 -172 ct 103 -174 106 -179 111 -184 ct +122 -195 134 -201 145 -201 ct 163 -201 171 -188 171 -160 ct 171 -160 171 -160 171 -40 ct +171 -22 165 -14 148 -12 ct 148 -12 148 -12 148 0 ct 148 0 148 0 264 0 ct 264 0 264 0 264 -12 ct +246 -13 240 -21 240 -42 ct 240 -42 240 -42 240 -164 ct 240 -207 213 -234 173 -234 ct +147 -234 128 -224 103 -195 ct 103 -195 103 -195 103 -334 ct p ef +pom +gr +gs +pum +13934 12960 t +143 -334 m 107 -310 92 -297 75 -274 ct 40 -231 23 -182 23 -124 ct 23 -62 41 -13 84 37 ct +104 61 116 72 141 87 ct 141 87 141 87 147 79 ct 108 48 95 31 82 -6 ct 70 -39 65 -76 65 -126 ct +65 -178 71 -218 84 -249 ct 98 -279 112 -297 147 -326 ct 147 -326 147 -326 143 -334 ct +p ef +pom +gr +gs +pum +14099 12960 t +227 -58 m 227 -58 227 -58 217 -45 ct 203 -27 194 -19 187 -19 ct 183 -19 179 -23 179 -27 ct +179 -31 179 -31 186 -58 ct 186 -58 186 -58 214 -160 ct 216 -170 218 -181 218 -188 ct +218 -206 205 -218 186 -218 ct 154 -218 123 -189 72 -110 ct 72 -110 72 -110 105 -217 ct +105 -217 105 -217 104 -218 ct 77 -213 67 -211 24 -203 ct 24 -203 24 -203 24 -195 ct +49 -195 55 -192 55 -182 ct 55 -179 55 -176 54 -173 ct 54 -173 54 -173 7 0 ct 7 0 7 0 44 0 ct +67 -78 72 -89 93 -123 ct 123 -168 148 -193 166 -193 ct 174 -193 178 -188 178 -179 ct +178 -173 175 -156 171 -141 ct 171 -141 171 -141 150 -60 ct 143 -35 142 -28 142 -23 ct +142 -4 149 4 165 4 ct 187 4 200 -6 234 -52 ct 234 -52 234 -52 227 -58 ct p ef +pom +gr +gs +pum +14349 12960 t +18 87 m 54 64 69 51 87 28 ct 121 -15 138 -64 138 -122 ct 138 -185 120 -233 77 -283 ct +58 -307 45 -318 20 -334 ct 20 -334 20 -334 14 -326 ct 53 -295 66 -277 79 -240 ct +91 -207 96 -170 96 -120 ct 96 -69 90 -28 77 2 ct 63 33 49 51 14 79 ct 14 79 14 79 18 87 ct +p ef +pom +gr +gr +14100 15000 m 13913 14438 l 14288 14438 l 14100 15000 l p ef +14125 13800 m 14125 14550 l 14075 14550 l 14075 13800 l 14125 13800 l +p ef +5900 15500 m 6463 15313 l 6463 15688 l 5900 15500 l p ef +8000 15525 m 6350 15525 l 6350 15475 l 8000 15475 l 8000 15525 l p ef +8500 11800 m 8313 11238 l 8688 11238 l 8500 11800 l p ef +5600 10575 m 8500 10575 l 8500 10600 l 8500 10625 l 5600 10625 l 5600 10600 l +5600 10575 l p ef +8500 10600 m 8500 10575 l 8504 10575 l 8509 10577 l 8512 10578 l 8516 10581 l +8519 10584 l 8522 10587 l 8523 10591 l 8525 10596 l 8525 10600 l 8525 10600 l +8500 10600 l p ef +8525 10600 m 8525 11350 l 8500 11350 l 8475 11350 l 8475 10600 l 8500 10600 l +8525 10600 l p ef +14600 15500 m 15163 15313 l 15163 15688 l 14600 15500 l p ef +15900 15525 m 15050 15525 l 15050 15475 l 15900 15475 l 15900 15525 l +p ef +14100 11800 m 13913 11238 l 14288 11238 l 14100 11800 l p ef +5600 10575 m 14100 10575 l 14100 10600 l 14100 10625 l 5600 10625 l +5600 10600 l 5600 10575 l p ef +14100 10600 m 14100 10575 l 14104 10575 l 14109 10577 l 14112 10578 l +14116 10581 l 14119 10584 l 14122 10587 l 14123 10591 l 14125 10596 l +14125 10600 l 14125 10600 l 14100 10600 l p ef +14125 10600 m 14125 11350 l 14100 11350 l 14075 11350 l 14075 10600 l +14100 10600 l 14125 10600 l p ef +7000 15500 m 7000 13500 l ps +gs +gs +pum +16150 15536 t +10 -200 m 16 -200 20 -200 25 -200 ct 44 -200 49 -192 56 -146 ct 61 -112 67 -37 67 -8 ct +67 6 68 9 72 9 ct 84 9 130 -43 180 -114 ct 198 -138 210 -170 210 -189 ct 210 -205 198 -218 183 -218 ct +172 -218 165 -212 165 -201 ct 165 -193 167 -188 176 -180 ct 183 -174 185 -170 185 -165 ct +185 -142 153 -87 118 -50 ct 118 -50 118 -50 102 -35 ct 99 -104 96 -130 89 -167 ct +80 -217 80 -218 75 -218 ct 73 -218 69 -217 65 -216 ct 56 -214 29 -209 10 -206 ct +10 -206 10 -206 10 -200 ct p ef +pom +gr +gs +pum +16370 15536 t +143 -334 m 107 -310 92 -297 75 -274 ct 40 -231 23 -182 23 -124 ct 23 -62 41 -13 84 37 ct +104 61 116 72 141 87 ct 141 87 141 87 147 79 ct 108 48 95 31 82 -6 ct 70 -39 65 -76 65 -126 ct +65 -178 71 -218 84 -249 ct 98 -279 112 -297 147 -326 ct 147 -326 147 -326 143 -334 ct +p ef +pom +gr +gs +pum +16535 15536 t +227 -58 m 227 -58 227 -58 217 -45 ct 203 -27 194 -19 187 -19 ct 183 -19 179 -23 179 -27 ct +179 -31 179 -31 186 -58 ct 186 -58 186 -58 214 -160 ct 216 -170 218 -181 218 -188 ct +218 -206 205 -218 186 -218 ct 154 -218 123 -189 72 -110 ct 72 -110 72 -110 105 -217 ct +105 -217 105 -217 104 -218 ct 77 -213 67 -211 24 -203 ct 24 -203 24 -203 24 -195 ct +49 -195 55 -192 55 -182 ct 55 -179 55 -176 54 -173 ct 54 -173 54 -173 7 0 ct 7 0 7 0 44 0 ct +67 -78 72 -89 93 -123 ct 123 -168 148 -193 166 -193 ct 174 -193 178 -188 178 -179 ct +178 -173 175 -156 171 -141 ct 171 -141 171 -141 150 -60 ct 143 -35 142 -28 142 -23 ct +142 -4 149 4 165 4 ct 187 4 200 -6 234 -52 ct 234 -52 234 -52 227 -58 ct p ef +pom +gr +gs +pum +16785 15536 t +18 87 m 54 64 69 51 87 28 ct 121 -15 138 -64 138 -122 ct 138 -185 120 -233 77 -283 ct +58 -307 45 -318 20 -334 ct 20 -334 20 -334 14 -326 ct 53 -295 66 -277 79 -240 ct +91 -207 96 -170 96 -120 ct 96 -69 90 -28 77 2 ct 63 33 49 51 14 79 ct 14 79 14 79 18 87 ct +p ef +pom +gr +gr +gs +gs +pum +9747 15298 t +229 -55 m 202 -24 197 -20 188 -20 ct 183 -20 179 -24 179 -30 ct 179 -37 195 -97 211 -152 ct +225 -197 235 -237 260 -336 ct 260 -336 260 -336 258 -338 ct 232 -333 214 -330 182 -327 ct +182 -327 182 -327 182 -318 ct 209 -318 213 -316 213 -306 ct 213 -299 212 -296 206 -271 ct +206 -271 206 -271 184 -190 ct 180 -210 171 -218 152 -218 ct 87 -218 7 -125 7 -51 ct +7 -16 27 5 59 5 ct 93 5 115 -11 148 -60 ct 143 -35 142 -27 142 -16 ct 142 -3 150 6 163 6 ct +183 6 209 -14 235 -50 ct 235 -50 235 -50 229 -55 ct p +154 -207 m 168 -207 176 -198 176 -180 ct 176 -104 124 -19 79 -19 ct 62 -19 50 -32 50 -51 ct +50 -92 75 -149 108 -183 ct 122 -198 140 -207 154 -207 ct p ef +pom +gr +gs +pum +9997 15298 t +143 -334 m 107 -310 92 -297 75 -274 ct 40 -231 23 -182 23 -124 ct 23 -62 41 -13 84 37 ct +104 61 116 72 141 87 ct 141 87 141 87 147 79 ct 108 48 95 31 82 -6 ct 70 -39 65 -76 65 -126 ct +65 -178 71 -218 84 -249 ct 98 -279 112 -297 147 -326 ct 147 -326 147 -326 143 -334 ct +p ef +pom +gr +gs +pum +10162 15298 t +227 -58 m 227 -58 227 -58 217 -45 ct 203 -27 194 -19 187 -19 ct 183 -19 179 -23 179 -27 ct +179 -31 179 -31 186 -58 ct 186 -58 186 -58 214 -160 ct 216 -170 218 -181 218 -188 ct +218 -206 205 -218 186 -218 ct 154 -218 123 -189 72 -110 ct 72 -110 72 -110 105 -217 ct +105 -217 105 -217 104 -218 ct 77 -213 67 -211 24 -203 ct 24 -203 24 -203 24 -195 ct +49 -195 55 -192 55 -182 ct 55 -179 55 -176 54 -173 ct 54 -173 54 -173 7 0 ct 7 0 7 0 44 0 ct +67 -78 72 -89 93 -123 ct 123 -168 148 -193 166 -193 ct 174 -193 178 -188 178 -179 ct +178 -173 175 -156 171 -141 ct 171 -141 171 -141 150 -60 ct 143 -35 142 -28 142 -23 ct +142 -4 149 4 165 4 ct 187 4 200 -6 234 -52 ct 234 -52 234 -52 227 -58 ct p ef +pom +gr +gs +pum +10412 15298 t +18 87 m 54 64 69 51 87 28 ct 121 -15 138 -64 138 -122 ct 138 -185 120 -233 77 -283 ct +58 -307 45 -318 20 -334 ct 20 -334 20 -334 14 -326 ct 53 -295 66 -277 79 -240 ct +91 -207 96 -170 96 -120 ct 96 -69 90 -28 77 2 ct 63 33 49 51 14 79 ct 14 79 14 79 18 87 ct +p ef +pom +gr +gr +gs +gs +pum +4561 10747 t +199 -55 m 195 -51 192 -48 188 -42 ct 176 -27 170 -22 165 -22 ct 158 -22 153 -29 150 -42 ct +149 -46 148 -49 148 -51 ct 135 -101 130 -123 130 -131 ct 152 -169 169 -190 178 -190 ct +181 -190 185 -189 190 -186 ct 196 -183 200 -182 204 -182 ct 214 -182 221 -189 221 -200 ct +221 -210 212 -218 201 -218 ct 179 -218 160 -200 126 -147 ct 126 -147 126 -147 121 -175 ct +114 -208 108 -218 95 -218 ct 84 -218 67 -214 37 -204 ct 37 -204 37 -204 32 -202 ct +32 -202 32 -202 34 -194 ct 52 -199 57 -200 61 -200 ct 74 -200 77 -195 83 -166 ct +83 -166 83 -166 98 -105 ct 98 -105 98 -105 57 -47 ct 47 -33 38 -24 32 -24 ct 29 -24 24 -25 19 -28 ct +13 -32 7 -33 3 -33 ct -6 -33 -13 -26 -13 -16 ct -13 -3 -3 5 11 5 ct 27 5 33 1 57 -30 ct +71 -45 81 -59 102 -87 ct 102 -87 102 -87 117 -28 ct 123 -3 129 5 145 5 ct 164 5 177 -7 206 -51 ct +206 -51 206 -51 199 -55 ct p ef +pom +gr +gs +pum +4781 10747 t +143 -334 m 107 -310 92 -297 75 -274 ct 40 -231 23 -182 23 -124 ct 23 -62 41 -13 84 37 ct +104 61 116 72 141 87 ct 141 87 141 87 147 79 ct 108 48 95 31 82 -6 ct 70 -39 65 -76 65 -126 ct +65 -178 71 -218 84 -249 ct 98 -279 112 -297 147 -326 ct 147 -326 147 -326 143 -334 ct +p ef +pom +gr +gs +pum +4946 10747 t +227 -58 m 227 -58 227 -58 217 -45 ct 203 -27 194 -19 187 -19 ct 183 -19 179 -23 179 -27 ct +179 -31 179 -31 186 -58 ct 186 -58 186 -58 214 -160 ct 216 -170 218 -181 218 -188 ct +218 -206 205 -218 186 -218 ct 154 -218 123 -189 72 -110 ct 72 -110 72 -110 105 -217 ct +105 -217 105 -217 104 -218 ct 77 -213 67 -211 24 -203 ct 24 -203 24 -203 24 -195 ct +49 -195 55 -192 55 -182 ct 55 -179 55 -176 54 -173 ct 54 -173 54 -173 7 0 ct 7 0 7 0 44 0 ct +67 -78 72 -89 93 -123 ct 123 -168 148 -193 166 -193 ct 174 -193 178 -188 178 -179 ct +178 -173 175 -156 171 -141 ct 171 -141 171 -141 150 -60 ct 143 -35 142 -28 142 -23 ct +142 -4 149 4 165 4 ct 187 4 200 -6 234 -52 ct 234 -52 234 -52 227 -58 ct p ef +pom +gr +gs +pum +5196 10747 t +18 87 m 54 64 69 51 87 28 ct 121 -15 138 -64 138 -122 ct 138 -185 120 -233 77 -283 ct +58 -307 45 -318 20 -334 ct 20 -334 20 -334 14 -326 ct 53 -295 66 -277 79 -240 ct +91 -207 96 -170 96 -120 ct 96 -69 90 -28 77 2 ct 63 33 49 51 14 79 ct 14 79 14 79 18 87 ct +p ef +pom +gr +gr +gs +gs +pum +4932 15694 t +177 -54 m 141 -25 126 -17 105 -17 ct 77 -17 58 -35 58 -62 ct 58 -69 59 -77 63 -92 ct +63 -92 63 -92 77 -94 ct 151 -105 204 -142 204 -185 ct 204 -206 189 -218 164 -218 ct +93 -218 15 -137 15 -63 ct 15 -23 42 5 81 5 ct 116 5 154 -15 183 -48 ct 183 -48 183 -48 177 -54 ct +p +75 -125 m 92 -169 128 -207 154 -207 ct 164 -207 171 -199 171 -188 ct 171 -172 162 -155 146 -140 ct +128 -123 109 -114 67 -103 ct 67 -103 67 -103 75 -125 ct p ef +pom +gr +gs +pum +5152 15694 t +143 -334 m 107 -310 92 -297 75 -274 ct 40 -231 23 -182 23 -124 ct 23 -62 41 -13 84 37 ct +104 61 116 72 141 87 ct 141 87 141 87 147 79 ct 108 48 95 31 82 -6 ct 70 -39 65 -76 65 -126 ct +65 -178 71 -218 84 -249 ct 98 -279 112 -297 147 -326 ct 147 -326 147 -326 143 -334 ct +p ef +pom +gr +gs +pum +5317 15694 t +227 -58 m 227 -58 227 -58 217 -45 ct 203 -27 194 -19 187 -19 ct 183 -19 179 -23 179 -27 ct +179 -31 179 -31 186 -58 ct 186 -58 186 -58 214 -160 ct 216 -170 218 -181 218 -188 ct +218 -206 205 -218 186 -218 ct 154 -218 123 -189 72 -110 ct 72 -110 72 -110 105 -217 ct +105 -217 105 -217 104 -218 ct 77 -213 67 -211 24 -203 ct 24 -203 24 -203 24 -195 ct +49 -195 55 -192 55 -182 ct 55 -179 55 -176 54 -173 ct 54 -173 54 -173 7 0 ct 7 0 7 0 44 0 ct +67 -78 72 -89 93 -123 ct 123 -168 148 -193 166 -193 ct 174 -193 178 -188 178 -179 ct +178 -173 175 -156 171 -141 ct 171 -141 171 -141 150 -60 ct 143 -35 142 -28 142 -23 ct +142 -4 149 4 165 4 ct 187 4 200 -6 234 -52 ct 234 -52 234 -52 227 -58 ct p ef +pom +gr +gs +pum +5567 15694 t +18 87 m 54 64 69 51 87 28 ct 121 -15 138 -64 138 -122 ct 138 -185 120 -233 77 -283 ct +58 -307 45 -318 20 -334 ct 20 -334 20 -334 14 -326 ct 53 -295 66 -277 79 -240 ct +91 -207 96 -170 96 -120 ct 96 -69 90 -28 77 2 ct 63 33 49 51 14 79 ct 14 79 14 79 18 87 ct +p ef +pom +gr +gr +gs +gs +pum +8954 15959 t +121 -141 m 15 -141 l 15 -108 l 121 -108 l 121 0 l 153 0 l 153 -108 l +259 -108 l 259 -141 l 153 -141 l 153 -250 l 121 -250 l 121 -141 l +p ef +pom +gr +gr +gs +gs +pum +8848 15033 t +19 -127 m 19 -96 l 138 -96 l 138 -127 l 19 -127 l p ef +pom +gr +gr +gs +gs +pum +8080 12705 t +45 -147 m 114 -290 l 183 -147 l 216 -147 l 128 -327 l 99 -327 l 12 -147 l +45 -147 l p ef +pom +gr +gr +0.996 c 12400 9601 m 12394 11602 l 11895 11099 l 11897 10099 l 12400 9601 l +p ef +0.000 c 12400 9601 m 12394 11602 l 11895 11099 l 11897 10099 l 12400 9601 l +pc +0.996 c 11397 10599 m 11398 10099 l 11898 10100 l 11895 11100 l 11395 11099 l +11397 10599 l p ef +0.000 c 11397 10599 m 11398 10099 l 11898 10100 l 11895 11100 l 11395 11099 l +11397 10599 l pc +0.996 c 11900 16000 m 11624 16000 11400 15776 11400 15500 ct 11400 15224 11624 15000 11900 15000 ct +12176 15000 12400 15224 12400 15500 ct 12400 15776 12176 16000 11900 16000 ct +p ef +0.000 c 11900 16000 m 11624 16000 11400 15776 11400 15500 ct 11400 15224 11624 15000 11900 15000 ct +12176 15000 12400 15224 12400 15500 ct 12400 15776 12176 16000 11900 16000 ct +pc +12400 15000 m 12400 16000 l ps +gs +gs +pum +14880 16144 t +8 -196 m 11 -198 15 -198 21 -198 ct 34 -198 39 -191 39 -166 ct 39 -166 39 -166 39 -44 ct +39 -15 33 -8 9 -8 ct 9 -8 9 -8 9 0 ct 9 0 9 0 111 0 ct 111 0 111 0 111 -8 ct 87 -8 79 -14 79 -32 ct +79 -32 79 -32 79 -171 ct 103 -194 113 -200 129 -200 ct 153 -200 165 -184 165 -152 ct +165 -152 165 -152 165 -48 ct 165 -17 158 -8 134 -8 ct 134 -8 134 -8 134 0 ct 134 0 134 0 235 0 ct +235 0 235 0 235 -7 ct 211 -10 205 -16 205 -40 ct 205 -40 205 -40 205 -153 ct 205 -199 184 -227 148 -227 ct +126 -227 111 -219 78 -187 ct 78 -187 78 -187 78 -226 ct 78 -226 78 -226 75 -227 ct +51 -218 34 -213 8 -205 ct 8 -205 8 -205 8 -196 ct p ef +448 -81 m 424 -43 403 -29 372 -29 ct 345 -29 324 -43 310 -72 ct 301 -90 298 -107 297 -137 ct +297 -137 297 -137 446 -137 ct 442 -169 437 -183 425 -199 ct 411 -217 388 -227 363 -227 ct +339 -227 316 -218 298 -201 ct 275 -181 262 -146 262 -106 ct 262 -37 297 5 353 5 ct +399 5 435 -24 455 -78 ct 455 -78 455 -78 448 -81 ct p +298 -153 m 303 -191 320 -209 349 -209 ct 379 -209 390 -196 397 -153 ct 397 -153 397 -153 298 -153 ct +p ef +684 -32 m 676 -26 670 -23 663 -23 ct 652 -23 648 -30 648 -52 ct 648 -52 648 -52 648 -148 ct +648 -173 646 -188 638 -200 ct 628 -218 607 -227 578 -227 ct 533 -227 497 -203 497 -171 ct +497 -160 507 -150 518 -150 ct 530 -150 540 -160 540 -171 ct 540 -173 539 -175 539 -179 ct +538 -183 537 -187 537 -191 ct 537 -204 553 -215 572 -215 ct 596 -215 609 -201 609 -174 ct +609 -174 609 -174 609 -144 ct 534 -113 526 -109 505 -90 ct 495 -81 488 -64 488 -48 ct +488 -17 509 5 539 5 ct 560 5 580 -5 609 -31 ct 612 -5 621 5 640 5 ct 657 5 667 -1 684 -20 ct +684 -20 684 -20 684 -32 ct p +609 -61 m 609 -45 607 -41 596 -35 ct 585 -28 571 -24 561 -24 ct 544 -24 531 -40 531 -62 ct +531 -62 531 -62 531 -63 ct 531 -92 550 -110 609 -132 ct 609 -132 609 -132 609 -61 ct +p ef +693 -192 m 700 -194 705 -194 710 -194 ct 722 -194 727 -186 727 -164 ct 727 -164 727 -164 727 -41 ct +727 -17 723 -13 692 -7 ct 692 -7 692 -7 692 0 ct 692 0 692 0 809 0 ct 809 0 809 0 809 -8 ct +776 -8 767 -15 767 -44 ct 767 -44 767 -44 767 -155 ct 767 -171 788 -196 801 -196 ct +804 -196 809 -193 814 -188 ct 822 -182 827 -179 833 -179 ct 845 -179 852 -187 852 -201 ct +852 -217 842 -227 826 -227 ct 805 -227 791 -216 767 -181 ct 767 -181 767 -181 767 -226 ct +767 -226 767 -226 765 -227 ct 739 -216 722 -210 693 -200 ct 693 -200 693 -200 693 -192 ct +p ef +1176 -81 m 1152 -43 1131 -29 1100 -29 ct 1073 -29 1052 -43 1038 -72 ct 1029 -90 1026 -107 1025 -137 ct +1025 -137 1025 -137 1174 -137 ct 1170 -169 1165 -183 1153 -199 ct 1139 -217 1116 -227 1091 -227 ct +1067 -227 1044 -218 1026 -201 ct 1003 -181 990 -146 990 -106 ct 990 -37 1025 5 1081 5 ct +1127 5 1163 -24 1183 -78 ct 1183 -78 1183 -78 1176 -81 ct p +1026 -153 m 1031 -191 1048 -209 1077 -209 ct 1107 -209 1118 -196 1125 -153 ct +1125 -153 1125 -153 1026 -153 ct p ef +1206 -196 m 1209 -198 1213 -198 1219 -198 ct 1232 -198 1237 -191 1237 -166 ct +1237 -166 1237 -166 1237 -44 ct 1237 -15 1231 -8 1207 -8 ct 1207 -8 1207 -8 1207 0 ct +1207 0 1207 0 1309 0 ct 1309 0 1309 0 1309 -8 ct 1285 -8 1277 -14 1277 -32 ct 1277 -32 1277 -32 1277 -171 ct +1301 -194 1311 -200 1327 -200 ct 1351 -200 1363 -184 1363 -152 ct 1363 -152 1363 -152 1363 -48 ct +1363 -17 1356 -8 1332 -8 ct 1332 -8 1332 -8 1332 0 ct 1332 0 1332 0 1433 0 ct 1433 0 1433 0 1433 -7 ct +1409 -10 1403 -16 1403 -40 ct 1403 -40 1403 -40 1403 -153 ct 1403 -199 1382 -227 1346 -227 ct +1324 -227 1309 -219 1276 -187 ct 1276 -187 1276 -187 1276 -226 ct 1276 -226 1276 -226 1273 -227 ct +1249 -218 1232 -213 1206 -205 ct 1206 -205 1206 -205 1206 -196 ct p ef +1615 5 m 1615 5 1615 5 1686 -21 ct 1686 -21 1686 -21 1686 -28 ct 1677 -28 1676 -28 1675 -28 ct +1657 -28 1653 -33 1653 -56 ct 1653 -56 1653 -56 1653 -336 ct 1653 -336 1653 -336 1651 -337 ct +1628 -329 1611 -324 1580 -315 ct 1580 -315 1580 -315 1580 -308 ct 1584 -308 1586 -308 1590 -308 ct +1608 -308 1613 -303 1613 -283 ct 1613 -283 1613 -283 1613 -206 ct 1594 -222 1581 -227 1562 -227 ct +1506 -227 1461 -171 1461 -101 ct 1461 -38 1497 5 1551 5 ct 1578 5 1596 -5 1613 -28 ct +1613 -28 1613 -28 1613 4 ct 1613 4 1613 4 1615 5 ct p +1613 -50 m 1613 -47 1609 -41 1604 -35 ct 1596 -26 1584 -21 1570 -21 ct 1529 -21 1503 -60 1503 -121 ct +1503 -177 1526 -213 1563 -213 ct 1589 -213 1613 -190 1613 -164 ct 1613 -164 1613 -164 1613 -50 ct +p ef +1973 -155 m 1973 -155 1973 -155 1971 -222 ct 1971 -222 1971 -222 1965 -222 ct +1965 -222 1965 -222 1964 -221 ct 1960 -218 1959 -217 1957 -217 ct 1955 -217 1950 -218 1944 -221 ct +1934 -225 1923 -227 1911 -227 ct 1872 -227 1845 -202 1845 -166 ct 1845 -138 1860 -118 1901 -95 ct +1901 -95 1901 -95 1929 -78 ct 1946 -69 1955 -57 1955 -41 ct 1955 -20 1939 -6 1914 -6 ct +1898 -6 1883 -12 1874 -23 ct 1864 -35 1859 -47 1853 -75 ct 1853 -75 1853 -75 1845 -75 ct +1845 -75 1845 -75 1845 2 ct 1845 2 1845 2 1851 2 ct 1855 -3 1857 -4 1863 -4 ct +1867 -4 1874 -3 1885 0 ct 1898 3 1912 5 1920 5 ct 1957 5 1988 -24 1988 -58 ct 1988 -83 1977 -99 1948 -117 ct +1948 -117 1948 -117 1896 -148 ct 1882 -156 1875 -169 1875 -182 ct 1875 -202 1890 -216 1912 -216 ct +1940 -216 1954 -199 1965 -155 ct 1965 -155 1965 -155 1973 -155 ct p ef +2019 -195 m 2024 -195 2027 -195 2031 -195 ct 2048 -195 2051 -190 2051 -167 ct +2051 -167 2051 -167 2051 65 ct 2051 90 2046 96 2017 99 ct 2017 99 2017 99 2017 107 ct +2017 107 2017 107 2135 107 ct 2135 107 2135 107 2135 98 ct 2098 98 2092 93 2092 61 ct +2092 61 2092 61 2092 -16 ct 2109 0 2121 5 2141 5 ct 2198 5 2243 -50 2243 -122 ct +2243 -183 2209 -227 2162 -227 ct 2135 -227 2113 -215 2092 -189 ct 2092 -189 2092 -189 2092 -226 ct +2092 -226 2092 -226 2089 -227 ct 2063 -217 2046 -210 2019 -202 ct 2019 -202 2019 -202 2019 -195 ct +p +2092 -165 m 2092 -180 2119 -197 2141 -197 ct 2177 -197 2201 -160 2201 -103 ct +2201 -48 2177 -11 2142 -11 ct 2120 -11 2092 -29 2092 -44 ct 2092 -44 2092 -44 2092 -165 ct +p ef +2463 -81 m 2439 -43 2418 -29 2387 -29 ct 2360 -29 2339 -43 2325 -72 ct 2316 -90 2313 -107 2312 -137 ct +2312 -137 2312 -137 2461 -137 ct 2457 -169 2452 -183 2440 -199 ct 2426 -217 2403 -227 2378 -227 ct +2354 -227 2331 -218 2313 -201 ct 2290 -181 2277 -146 2277 -106 ct 2277 -37 2312 5 2368 5 ct +2414 5 2450 -24 2470 -78 ct 2470 -78 2470 -78 2463 -81 ct p +2313 -153 m 2318 -191 2335 -209 2364 -209 ct 2394 -209 2405 -196 2412 -153 ct +2412 -153 2412 -153 2313 -153 ct p ef +2683 -81 m 2659 -43 2638 -29 2607 -29 ct 2580 -29 2559 -43 2545 -72 ct 2536 -90 2533 -107 2532 -137 ct +2532 -137 2532 -137 2681 -137 ct 2677 -169 2672 -183 2660 -199 ct 2646 -217 2623 -227 2598 -227 ct +2574 -227 2551 -218 2533 -201 ct 2510 -181 2497 -146 2497 -106 ct 2497 -37 2532 5 2588 5 ct +2634 5 2670 -24 2690 -78 ct 2690 -78 2690 -78 2683 -81 ct p +2533 -153 m 2538 -191 2555 -209 2584 -209 ct 2614 -209 2625 -196 2632 -153 ct +2632 -153 2632 -153 2533 -153 ct p ef +2898 -77 m 2874 -42 2857 -31 2829 -31 ct 2785 -31 2754 -70 2754 -127 ct 2754 -178 2781 -213 2820 -213 ct +2838 -213 2844 -207 2849 -189 ct 2849 -189 2849 -189 2852 -178 ct 2856 -164 2864 -155 2874 -155 ct +2887 -155 2898 -164 2898 -176 ct 2898 -204 2864 -227 2823 -227 ct 2799 -227 2775 -217 2755 -199 ct +2731 -178 2717 -144 2717 -105 ct 2717 -41 2755 5 2809 5 ct 2831 5 2850 -3 2868 -18 ct +2881 -30 2890 -43 2904 -72 ct 2904 -72 2904 -72 2898 -77 ct p ef +3001 -169 m 3021 -192 3036 -200 3055 -200 ct 3079 -200 3091 -182 3091 -148 ct +3091 -148 3091 -148 3091 -50 ct 3091 -16 3086 -10 3058 -7 ct 3058 -7 3058 -7 3058 0 ct +3058 0 3058 0 3161 0 ct 3161 0 3161 0 3161 -7 ct 3135 -12 3132 -16 3132 -50 ct +3132 -50 3132 -50 3132 -148 ct 3132 -200 3111 -227 3072 -227 ct 3044 -227 3023 -215 3001 -185 ct +3001 -185 3001 -185 3001 -336 ct 3001 -336 3001 -336 2999 -337 ct 2982 -331 2970 -327 2943 -319 ct +2943 -319 2943 -319 2930 -315 ct 2930 -315 2930 -315 2930 -308 ct 2932 -308 2933 -308 2936 -308 ct +2956 -308 2960 -304 2960 -283 ct 2960 -283 2960 -283 2960 -50 ct 2960 -15 2957 -11 2929 -7 ct +2929 -7 2929 -7 2929 0 ct 2929 0 2929 0 3034 0 ct 3034 0 3034 0 3034 -7 ct 3006 -10 3001 -16 3001 -50 ct +3001 -50 3001 -50 3001 -169 ct p ef +pom +gr +gs +pum +15519 16745 t +214 -32 m 206 -26 200 -23 193 -23 ct 182 -23 178 -30 178 -52 ct 178 -52 178 -52 178 -148 ct +178 -173 176 -188 168 -200 ct 158 -218 137 -227 108 -227 ct 63 -227 27 -203 27 -171 ct +27 -160 37 -150 48 -150 ct 60 -150 70 -160 70 -171 ct 70 -173 69 -175 69 -179 ct +68 -183 67 -187 67 -191 ct 67 -204 83 -215 102 -215 ct 126 -215 139 -201 139 -174 ct +139 -174 139 -174 139 -144 ct 64 -113 56 -109 35 -90 ct 25 -81 18 -64 18 -48 ct +18 -17 39 5 69 5 ct 90 5 110 -5 139 -31 ct 142 -5 151 5 170 5 ct 187 5 197 -1 214 -20 ct +214 -20 214 -20 214 -32 ct p +139 -61 m 139 -45 137 -41 126 -35 ct 115 -28 101 -24 91 -24 ct 74 -24 61 -40 61 -62 ct +61 -62 61 -62 61 -63 ct 61 -92 80 -110 139 -132 ct 139 -132 139 -132 139 -61 ct +p ef +228 -196 m 231 -198 235 -198 241 -198 ct 254 -198 259 -191 259 -166 ct 259 -166 259 -166 259 -44 ct +259 -15 253 -8 229 -8 ct 229 -8 229 -8 229 0 ct 229 0 229 0 331 0 ct 331 0 331 0 331 -8 ct +307 -8 299 -14 299 -32 ct 299 -32 299 -32 299 -171 ct 323 -194 333 -200 349 -200 ct +373 -200 385 -184 385 -152 ct 385 -152 385 -152 385 -48 ct 385 -17 378 -8 354 -8 ct +354 -8 354 -8 354 0 ct 354 0 354 0 455 0 ct 455 0 455 0 455 -7 ct 431 -10 425 -16 425 -40 ct +425 -40 425 -40 425 -153 ct 425 -199 404 -227 368 -227 ct 346 -227 331 -219 298 -187 ct +298 -187 298 -187 298 -226 ct 298 -226 298 -226 295 -227 ct 271 -218 254 -213 228 -205 ct +228 -205 228 -205 228 -196 ct p ef +637 5 m 637 5 637 5 708 -21 ct 708 -21 708 -21 708 -28 ct 699 -28 698 -28 697 -28 ct +679 -28 675 -33 675 -56 ct 675 -56 675 -56 675 -336 ct 675 -336 675 -336 673 -337 ct +650 -329 633 -324 602 -315 ct 602 -315 602 -315 602 -308 ct 606 -308 608 -308 612 -308 ct +630 -308 635 -303 635 -283 ct 635 -283 635 -283 635 -206 ct 616 -222 603 -227 584 -227 ct +528 -227 483 -171 483 -101 ct 483 -38 519 5 573 5 ct 600 5 618 -5 635 -28 ct 635 -28 635 -28 635 4 ct +635 4 635 4 637 5 ct p +635 -50 m 635 -47 631 -41 626 -35 ct 618 -26 606 -21 592 -21 ct 551 -21 525 -60 525 -121 ct +525 -177 548 -213 585 -213 ct 611 -213 635 -190 635 -164 ct 635 -164 635 -164 635 -50 ct +p ef +850 -196 m 853 -198 857 -198 863 -198 ct 876 -198 881 -191 881 -166 ct 881 -166 881 -166 881 -44 ct +881 -15 875 -8 851 -8 ct 851 -8 851 -8 851 0 ct 851 0 851 0 953 0 ct 953 0 953 0 953 -8 ct +929 -8 921 -14 921 -32 ct 921 -32 921 -32 921 -171 ct 945 -194 955 -200 971 -200 ct +995 -200 1007 -184 1007 -152 ct 1007 -152 1007 -152 1007 -48 ct 1007 -17 1000 -8 976 -8 ct +976 -8 976 -8 976 0 ct 976 0 976 0 1077 0 ct 1077 0 1077 0 1077 -7 ct 1053 -10 1047 -16 1047 -40 ct +1047 -40 1047 -40 1047 -153 ct 1047 -199 1026 -227 990 -227 ct 968 -227 953 -219 920 -187 ct +920 -187 920 -187 920 -226 ct 920 -226 920 -226 917 -227 ct 893 -218 876 -213 850 -205 ct +850 -205 850 -205 850 -196 ct p ef +1213 -227 m 1150 -227 1106 -180 1106 -112 ct 1106 -45 1151 5 1212 5 ct 1273 5 1320 -47 1320 -115 ct +1320 -180 1275 -227 1213 -227 ct p +1207 -213 m 1247 -213 1276 -166 1276 -98 ct 1276 -42 1254 -9 1218 -9 ct 1199 -9 1181 -21 1171 -40 ct +1157 -66 1150 -101 1150 -136 ct 1150 -183 1172 -213 1207 -213 ct p ef +1427 -227 m 1427 -227 1427 -227 1352 -200 ct 1352 -200 1352 -200 1352 -192 ct +1352 -192 1352 -192 1356 -193 ct 1361 -194 1368 -194 1372 -194 ct 1384 -194 1388 -186 1388 -164 ct +1388 -164 1388 -164 1388 -49 ct 1388 -14 1383 -8 1350 -8 ct 1350 -8 1350 -8 1350 0 ct +1350 0 1350 0 1464 0 ct 1464 0 1464 0 1464 -8 ct 1433 -8 1429 -15 1429 -50 ct 1429 -50 1429 -50 1429 -225 ct +1429 -225 1429 -225 1427 -227 ct p +1404 -337 m 1391 -337 1380 -326 1380 -312 ct 1380 -298 1390 -287 1404 -287 ct +1418 -287 1429 -298 1429 -312 ct 1429 -326 1418 -337 1404 -337 ct p ef +1635 -155 m 1635 -155 1635 -155 1633 -222 ct 1633 -222 1633 -222 1627 -222 ct +1627 -222 1627 -222 1626 -221 ct 1622 -218 1621 -217 1619 -217 ct 1617 -217 1612 -218 1606 -221 ct +1596 -225 1585 -227 1573 -227 ct 1534 -227 1507 -202 1507 -166 ct 1507 -138 1522 -118 1563 -95 ct +1563 -95 1563 -95 1591 -78 ct 1608 -69 1617 -57 1617 -41 ct 1617 -20 1601 -6 1576 -6 ct +1560 -6 1545 -12 1536 -23 ct 1526 -35 1521 -47 1515 -75 ct 1515 -75 1515 -75 1507 -75 ct +1507 -75 1507 -75 1507 2 ct 1507 2 1507 2 1513 2 ct 1517 -3 1519 -4 1525 -4 ct +1529 -4 1536 -3 1547 0 ct 1560 3 1574 5 1582 5 ct 1619 5 1650 -24 1650 -58 ct 1650 -83 1639 -99 1610 -117 ct +1610 -117 1610 -117 1558 -148 ct 1544 -156 1537 -169 1537 -182 ct 1537 -202 1552 -216 1574 -216 ct +1602 -216 1616 -199 1627 -155 ct 1627 -155 1627 -155 1635 -155 ct p ef +1874 -81 m 1850 -43 1829 -29 1798 -29 ct 1771 -29 1750 -43 1736 -72 ct 1727 -90 1724 -107 1723 -137 ct +1723 -137 1723 -137 1872 -137 ct 1868 -169 1863 -183 1851 -199 ct 1837 -217 1814 -227 1789 -227 ct +1765 -227 1742 -218 1724 -201 ct 1701 -181 1688 -146 1688 -106 ct 1688 -37 1723 5 1779 5 ct +1825 5 1861 -24 1881 -78 ct 1881 -78 1881 -78 1874 -81 ct p +1724 -153 m 1729 -191 1746 -209 1775 -209 ct 1805 -209 1816 -196 1823 -153 ct +1823 -153 1823 -153 1724 -153 ct p ef +pom +gr +gr +gs +gs +pum +5435 10350 t +150 -222 m 150 -222 150 -222 90 -222 ct 90 -222 90 -222 90 -279 ct 90 -308 99 -323 118 -323 ct +128 -323 135 -318 143 -304 ct 151 -291 157 -286 165 -286 ct 176 -286 185 -295 185 -306 ct +185 -324 164 -337 135 -337 ct 105 -337 79 -324 67 -301 ct 54 -279 50 -261 50 -222 ct +50 -222 50 -222 10 -222 ct 10 -222 10 -222 10 -206 ct 10 -206 10 -206 50 -206 ct +50 -206 50 -206 50 -51 ct 50 -14 45 -8 10 -8 ct 10 -8 10 -8 10 0 ct 10 0 10 0 136 0 ct +136 0 136 0 136 -8 ct 96 -8 91 -13 91 -51 ct 91 -51 91 -51 91 -206 ct 91 -206 91 -206 150 -206 ct +150 -206 150 -206 150 -222 ct p ef +375 -32 m 367 -26 361 -23 354 -23 ct 343 -23 339 -30 339 -52 ct 339 -52 339 -52 339 -148 ct +339 -173 337 -188 329 -200 ct 319 -218 298 -227 269 -227 ct 224 -227 188 -203 188 -171 ct +188 -160 198 -150 209 -150 ct 221 -150 231 -160 231 -171 ct 231 -173 230 -175 230 -179 ct +229 -183 228 -187 228 -191 ct 228 -204 244 -215 263 -215 ct 287 -215 300 -201 300 -174 ct +300 -174 300 -174 300 -144 ct 225 -113 217 -109 196 -90 ct 186 -81 179 -64 179 -48 ct +179 -17 200 5 230 5 ct 251 5 271 -5 300 -31 ct 303 -5 312 5 331 5 ct 348 5 358 -1 375 -20 ct +375 -20 375 -20 375 -32 ct p +300 -61 m 300 -45 298 -41 287 -35 ct 276 -28 262 -24 252 -24 ct 235 -24 222 -40 222 -62 ct +222 -62 222 -62 222 -63 ct 222 -92 241 -110 300 -132 ct 300 -132 300 -132 300 -61 ct +p ef +384 -192 m 391 -194 396 -194 401 -194 ct 413 -194 418 -186 418 -164 ct 418 -164 418 -164 418 -41 ct +418 -17 414 -13 383 -7 ct 383 -7 383 -7 383 0 ct 383 0 383 0 500 0 ct 500 0 500 0 500 -8 ct +467 -8 458 -15 458 -44 ct 458 -44 458 -44 458 -155 ct 458 -171 479 -196 492 -196 ct +495 -196 500 -193 505 -188 ct 513 -182 518 -179 524 -179 ct 536 -179 543 -187 543 -201 ct +543 -217 533 -227 517 -227 ct 496 -227 482 -216 458 -181 ct 458 -181 458 -181 458 -226 ct +458 -226 458 -226 456 -227 ct 430 -216 413 -210 384 -200 ct 384 -200 384 -200 384 -192 ct +p ef +867 -81 m 843 -43 822 -29 791 -29 ct 764 -29 743 -43 729 -72 ct 720 -90 717 -107 716 -137 ct +716 -137 716 -137 865 -137 ct 861 -169 856 -183 844 -199 ct 830 -217 807 -227 782 -227 ct +758 -227 735 -218 717 -201 ct 694 -181 681 -146 681 -106 ct 681 -37 716 5 772 5 ct +818 5 854 -24 874 -78 ct 874 -78 874 -78 867 -81 ct p +717 -153 m 722 -191 739 -209 768 -209 ct 798 -209 809 -196 816 -153 ct 816 -153 816 -153 717 -153 ct +p ef +897 -196 m 900 -198 904 -198 910 -198 ct 923 -198 928 -191 928 -166 ct 928 -166 928 -166 928 -44 ct +928 -15 922 -8 898 -8 ct 898 -8 898 -8 898 0 ct 898 0 898 0 1000 0 ct 1000 0 1000 0 1000 -8 ct +976 -8 968 -14 968 -32 ct 968 -32 968 -32 968 -171 ct 992 -194 1002 -200 1018 -200 ct +1042 -200 1054 -184 1054 -152 ct 1054 -152 1054 -152 1054 -48 ct 1054 -17 1047 -8 1023 -8 ct +1023 -8 1023 -8 1023 0 ct 1023 0 1023 0 1124 0 ct 1124 0 1124 0 1124 -7 ct 1100 -10 1094 -16 1094 -40 ct +1094 -40 1094 -40 1094 -153 ct 1094 -199 1073 -227 1037 -227 ct 1015 -227 1000 -219 967 -187 ct +967 -187 967 -187 967 -226 ct 967 -226 967 -226 964 -227 ct 940 -218 923 -213 897 -205 ct +897 -205 897 -205 897 -196 ct p ef +1306 5 m 1306 5 1306 5 1377 -21 ct 1377 -21 1377 -21 1377 -28 ct 1368 -28 1367 -28 1366 -28 ct +1348 -28 1344 -33 1344 -56 ct 1344 -56 1344 -56 1344 -336 ct 1344 -336 1344 -336 1342 -337 ct +1319 -329 1302 -324 1271 -315 ct 1271 -315 1271 -315 1271 -308 ct 1275 -308 1277 -308 1281 -308 ct +1299 -308 1304 -303 1304 -283 ct 1304 -283 1304 -283 1304 -206 ct 1285 -222 1272 -227 1253 -227 ct +1197 -227 1152 -171 1152 -101 ct 1152 -38 1188 5 1242 5 ct 1269 5 1287 -5 1304 -28 ct +1304 -28 1304 -28 1304 4 ct 1304 4 1304 4 1306 5 ct p +1304 -50 m 1304 -47 1300 -41 1295 -35 ct 1287 -26 1275 -21 1261 -21 ct 1220 -21 1194 -60 1194 -121 ct +1194 -177 1217 -213 1254 -213 ct 1280 -213 1304 -190 1304 -164 ct 1304 -164 1304 -164 1304 -50 ct +p ef +1664 -155 m 1664 -155 1664 -155 1662 -222 ct 1662 -222 1662 -222 1656 -222 ct +1656 -222 1656 -222 1655 -221 ct 1651 -218 1650 -217 1648 -217 ct 1646 -217 1641 -218 1635 -221 ct +1625 -225 1614 -227 1602 -227 ct 1563 -227 1536 -202 1536 -166 ct 1536 -138 1551 -118 1592 -95 ct +1592 -95 1592 -95 1620 -78 ct 1637 -69 1646 -57 1646 -41 ct 1646 -20 1630 -6 1605 -6 ct +1589 -6 1574 -12 1565 -23 ct 1555 -35 1550 -47 1544 -75 ct 1544 -75 1544 -75 1536 -75 ct +1536 -75 1536 -75 1536 2 ct 1536 2 1536 2 1542 2 ct 1546 -3 1548 -4 1554 -4 ct +1558 -4 1565 -3 1576 0 ct 1589 3 1603 5 1611 5 ct 1648 5 1679 -24 1679 -58 ct 1679 -83 1668 -99 1639 -117 ct +1639 -117 1639 -117 1587 -148 ct 1573 -156 1566 -169 1566 -182 ct 1566 -202 1581 -216 1603 -216 ct +1631 -216 1645 -199 1656 -155 ct 1656 -155 1656 -155 1664 -155 ct p ef +1710 -195 m 1715 -195 1718 -195 1722 -195 ct 1739 -195 1742 -190 1742 -167 ct +1742 -167 1742 -167 1742 65 ct 1742 90 1737 96 1708 99 ct 1708 99 1708 99 1708 107 ct +1708 107 1708 107 1826 107 ct 1826 107 1826 107 1826 98 ct 1789 98 1783 93 1783 61 ct +1783 61 1783 61 1783 -16 ct 1800 0 1812 5 1832 5 ct 1889 5 1934 -50 1934 -122 ct +1934 -183 1900 -227 1853 -227 ct 1826 -227 1804 -215 1783 -189 ct 1783 -189 1783 -189 1783 -226 ct +1783 -226 1783 -226 1780 -227 ct 1754 -217 1737 -210 1710 -202 ct 1710 -202 1710 -202 1710 -195 ct +p +1783 -165 m 1783 -180 1810 -197 1832 -197 ct 1868 -197 1892 -160 1892 -103 ct +1892 -48 1868 -11 1833 -11 ct 1811 -11 1783 -29 1783 -44 ct 1783 -44 1783 -44 1783 -165 ct +p ef +2154 -81 m 2130 -43 2109 -29 2078 -29 ct 2051 -29 2030 -43 2016 -72 ct 2007 -90 2004 -107 2003 -137 ct +2003 -137 2003 -137 2152 -137 ct 2148 -169 2143 -183 2131 -199 ct 2117 -217 2094 -227 2069 -227 ct +2045 -227 2022 -218 2004 -201 ct 1981 -181 1968 -146 1968 -106 ct 1968 -37 2003 5 2059 5 ct +2105 5 2141 -24 2161 -78 ct 2161 -78 2161 -78 2154 -81 ct p +2004 -153 m 2009 -191 2026 -209 2055 -209 ct 2085 -209 2096 -196 2103 -153 ct +2103 -153 2103 -153 2004 -153 ct p ef +2374 -81 m 2350 -43 2329 -29 2298 -29 ct 2271 -29 2250 -43 2236 -72 ct 2227 -90 2224 -107 2223 -137 ct +2223 -137 2223 -137 2372 -137 ct 2368 -169 2363 -183 2351 -199 ct 2337 -217 2314 -227 2289 -227 ct +2265 -227 2242 -218 2224 -201 ct 2201 -181 2188 -146 2188 -106 ct 2188 -37 2223 5 2279 5 ct +2325 5 2361 -24 2381 -78 ct 2381 -78 2381 -78 2374 -81 ct p +2224 -153 m 2229 -191 2246 -209 2275 -209 ct 2305 -209 2316 -196 2323 -153 ct +2323 -153 2323 -153 2224 -153 ct p ef +2589 -77 m 2565 -42 2548 -31 2520 -31 ct 2476 -31 2445 -70 2445 -127 ct 2445 -178 2472 -213 2511 -213 ct +2529 -213 2535 -207 2540 -189 ct 2540 -189 2540 -189 2543 -178 ct 2547 -164 2555 -155 2565 -155 ct +2578 -155 2589 -164 2589 -176 ct 2589 -204 2555 -227 2514 -227 ct 2490 -227 2466 -217 2446 -199 ct +2422 -178 2408 -144 2408 -105 ct 2408 -41 2446 5 2500 5 ct 2522 5 2541 -3 2559 -18 ct +2572 -30 2581 -43 2595 -72 ct 2595 -72 2595 -72 2589 -77 ct p ef +2692 -169 m 2712 -192 2727 -200 2746 -200 ct 2770 -200 2782 -182 2782 -148 ct +2782 -148 2782 -148 2782 -50 ct 2782 -16 2777 -10 2749 -7 ct 2749 -7 2749 -7 2749 0 ct +2749 0 2749 0 2852 0 ct 2852 0 2852 0 2852 -7 ct 2826 -12 2823 -16 2823 -50 ct +2823 -50 2823 -50 2823 -148 ct 2823 -200 2802 -227 2763 -227 ct 2735 -227 2714 -215 2692 -185 ct +2692 -185 2692 -185 2692 -336 ct 2692 -336 2692 -336 2690 -337 ct 2673 -331 2661 -327 2634 -319 ct +2634 -319 2634 -319 2621 -315 ct 2621 -315 2621 -315 2621 -308 ct 2623 -308 2624 -308 2627 -308 ct +2647 -308 2651 -304 2651 -283 ct 2651 -283 2651 -283 2651 -50 ct 2651 -15 2648 -11 2620 -7 ct +2620 -7 2620 -7 2620 0 ct 2620 0 2620 0 2725 0 ct 2725 0 2725 0 2725 -7 ct 2697 -10 2692 -16 2692 -50 ct +2692 -50 2692 -50 2692 -169 ct p ef +pom +gr +gr +gs +gs +pum +10779 16488 t +9 -196 m 15 -198 19 -198 25 -198 ct 37 -198 42 -190 42 -166 ct 42 -166 42 -166 42 -41 ct +42 -15 35 -7 8 -7 ct 8 -7 8 -7 8 0 ct 8 0 8 0 115 0 ct 115 0 115 0 115 -8 ct 90 -8 82 -13 82 -33 ct +82 -33 82 -33 82 -172 ct 82 -173 86 -178 90 -181 ct 102 -193 122 -201 139 -201 ct +161 -201 171 -184 171 -149 ct 171 -149 171 -149 171 -42 ct 171 -14 166 -8 138 -8 ct +138 -8 138 -8 138 0 ct 138 0 138 0 247 0 ct 247 0 247 0 247 -7 ct 219 -7 212 -16 212 -46 ct +212 -46 212 -46 212 -171 ct 227 -192 243 -201 265 -201 ct 292 -201 301 -188 301 -147 ct +301 -147 301 -147 301 -43 ct 301 -15 297 -11 269 -7 ct 269 -7 269 -7 269 0 ct 269 0 269 0 375 0 ct +375 0 375 0 375 -8 ct 375 -8 375 -8 363 -8 ct 348 -8 342 -18 342 -37 ct 342 -37 342 -37 342 -139 ct +342 -197 323 -227 286 -227 ct 258 -227 233 -214 207 -185 ct 198 -214 182 -227 155 -227 ct +134 -227 121 -220 80 -189 ct 80 -189 80 -189 80 -226 ct 80 -226 80 -226 77 -227 ct +52 -218 36 -212 9 -205 ct 9 -205 9 -205 9 -196 ct p ef +470 -227 m 470 -227 470 -227 395 -200 ct 395 -200 395 -200 395 -192 ct 395 -192 395 -192 399 -193 ct +404 -194 411 -194 415 -194 ct 427 -194 431 -186 431 -164 ct 431 -164 431 -164 431 -49 ct +431 -14 426 -8 393 -8 ct 393 -8 393 -8 393 0 ct 393 0 393 0 507 0 ct 507 0 507 0 507 -8 ct +476 -8 472 -15 472 -50 ct 472 -50 472 -50 472 -225 ct 472 -225 472 -225 470 -227 ct +p +447 -337 m 434 -337 423 -326 423 -312 ct 423 -298 433 -287 447 -287 ct 461 -287 472 -298 472 -312 ct +472 -326 461 -337 447 -337 ct p ef +718 -77 m 694 -42 677 -31 649 -31 ct 605 -31 574 -70 574 -127 ct 574 -178 601 -213 640 -213 ct +658 -213 664 -207 669 -189 ct 669 -189 669 -189 672 -178 ct 676 -164 684 -155 694 -155 ct +707 -155 718 -164 718 -176 ct 718 -204 684 -227 643 -227 ct 619 -227 595 -217 575 -199 ct +551 -178 537 -144 537 -105 ct 537 -41 575 5 629 5 ct 651 5 670 -3 688 -18 ct 701 -30 710 -43 724 -72 ct +724 -72 724 -72 718 -77 ct p ef +748 -192 m 755 -194 760 -194 765 -194 ct 777 -194 782 -186 782 -164 ct 782 -164 782 -164 782 -41 ct +782 -17 778 -13 747 -7 ct 747 -7 747 -7 747 0 ct 747 0 747 0 864 0 ct 864 0 864 0 864 -8 ct +831 -8 822 -15 822 -44 ct 822 -44 822 -44 822 -155 ct 822 -171 843 -196 856 -196 ct +859 -196 864 -193 869 -188 ct 877 -182 882 -179 888 -179 ct 900 -179 907 -187 907 -201 ct +907 -217 897 -227 881 -227 ct 860 -227 846 -216 822 -181 ct 822 -181 822 -181 822 -226 ct +822 -226 822 -226 820 -227 ct 794 -216 777 -210 748 -200 ct 748 -200 748 -200 748 -192 ct +p ef +1031 -227 m 968 -227 924 -180 924 -112 ct 924 -45 969 5 1030 5 ct 1091 5 1138 -47 1138 -115 ct +1138 -180 1093 -227 1031 -227 ct p +1025 -213 m 1065 -213 1094 -166 1094 -98 ct 1094 -42 1072 -9 1036 -9 ct 1017 -9 999 -21 989 -40 ct +975 -66 968 -101 968 -136 ct 968 -183 990 -213 1025 -213 ct p ef +1164 -195 m 1169 -195 1172 -195 1176 -195 ct 1193 -195 1196 -190 1196 -167 ct +1196 -167 1196 -167 1196 65 ct 1196 90 1191 96 1162 99 ct 1162 99 1162 99 1162 107 ct +1162 107 1162 107 1280 107 ct 1280 107 1280 107 1280 98 ct 1243 98 1237 93 1237 61 ct +1237 61 1237 61 1237 -16 ct 1254 0 1266 5 1286 5 ct 1343 5 1388 -50 1388 -122 ct +1388 -183 1354 -227 1307 -227 ct 1280 -227 1258 -215 1237 -189 ct 1237 -189 1237 -189 1237 -226 ct +1237 -226 1237 -226 1234 -227 ct 1208 -217 1191 -210 1164 -202 ct 1164 -202 1164 -202 1164 -195 ct +p +1237 -165 m 1237 -180 1264 -197 1286 -197 ct 1322 -197 1346 -160 1346 -103 ct +1346 -48 1322 -11 1287 -11 ct 1265 -11 1237 -29 1237 -44 ct 1237 -44 1237 -44 1237 -165 ct +p ef +1486 -169 m 1506 -192 1521 -200 1540 -200 ct 1564 -200 1576 -182 1576 -148 ct +1576 -148 1576 -148 1576 -50 ct 1576 -16 1571 -10 1543 -7 ct 1543 -7 1543 -7 1543 0 ct +1543 0 1543 0 1646 0 ct 1646 0 1646 0 1646 -7 ct 1620 -12 1617 -16 1617 -50 ct +1617 -50 1617 -50 1617 -148 ct 1617 -200 1596 -227 1557 -227 ct 1529 -227 1508 -215 1486 -185 ct +1486 -185 1486 -185 1486 -336 ct 1486 -336 1486 -336 1484 -337 ct 1467 -331 1455 -327 1428 -319 ct +1428 -319 1428 -319 1415 -315 ct 1415 -315 1415 -315 1415 -308 ct 1417 -308 1418 -308 1421 -308 ct +1441 -308 1445 -304 1445 -283 ct 1445 -283 1445 -283 1445 -50 ct 1445 -15 1442 -11 1414 -7 ct +1414 -7 1414 -7 1414 0 ct 1414 0 1414 0 1519 0 ct 1519 0 1519 0 1519 -7 ct 1491 -10 1486 -16 1486 -50 ct +1486 -50 1486 -50 1486 -169 ct p ef +1780 -227 m 1717 -227 1673 -180 1673 -112 ct 1673 -45 1718 5 1779 5 ct 1840 5 1887 -47 1887 -115 ct +1887 -180 1842 -227 1780 -227 ct p +1774 -213 m 1814 -213 1843 -166 1843 -98 ct 1843 -42 1821 -9 1785 -9 ct 1766 -9 1748 -21 1738 -40 ct +1724 -66 1717 -101 1717 -136 ct 1717 -183 1739 -213 1774 -213 ct p ef +1917 -196 m 1920 -198 1924 -198 1930 -198 ct 1943 -198 1948 -191 1948 -166 ct +1948 -166 1948 -166 1948 -44 ct 1948 -15 1942 -8 1918 -8 ct 1918 -8 1918 -8 1918 0 ct +1918 0 1918 0 2020 0 ct 2020 0 2020 0 2020 -8 ct 1996 -8 1988 -14 1988 -32 ct 1988 -32 1988 -32 1988 -171 ct +2012 -194 2022 -200 2038 -200 ct 2062 -200 2074 -184 2074 -152 ct 2074 -152 2074 -152 2074 -48 ct +2074 -17 2067 -8 2043 -8 ct 2043 -8 2043 -8 2043 0 ct 2043 0 2043 0 2144 0 ct 2144 0 2144 0 2144 -7 ct +2120 -10 2114 -16 2114 -40 ct 2114 -40 2114 -40 2114 -153 ct 2114 -199 2093 -227 2057 -227 ct +2035 -227 2020 -219 1987 -187 ct 1987 -187 1987 -187 1987 -226 ct 1987 -226 1987 -226 1984 -227 ct +1960 -218 1943 -213 1917 -205 ct 1917 -205 1917 -205 1917 -196 ct p ef +2357 -81 m 2333 -43 2312 -29 2281 -29 ct 2254 -29 2233 -43 2219 -72 ct 2210 -90 2207 -107 2206 -137 ct +2206 -137 2206 -137 2355 -137 ct 2351 -169 2346 -183 2334 -199 ct 2320 -217 2297 -227 2272 -227 ct +2248 -227 2225 -218 2207 -201 ct 2184 -181 2171 -146 2171 -106 ct 2171 -37 2206 5 2262 5 ct +2308 5 2344 -24 2364 -78 ct 2364 -78 2364 -78 2357 -81 ct p +2207 -153 m 2212 -191 2229 -209 2258 -209 ct 2288 -209 2299 -196 2306 -153 ct +2306 -153 2306 -153 2207 -153 ct p ef +pom +gr +gr +gs +gs +pum +15356 12996 t +3 -192 m 10 -194 15 -194 20 -194 ct 32 -194 37 -186 37 -164 ct 37 -164 37 -164 37 -41 ct +37 -17 33 -13 2 -7 ct 2 -7 2 -7 2 0 ct 2 0 2 0 119 0 ct 119 0 119 0 119 -8 ct 86 -8 77 -15 77 -44 ct +77 -44 77 -44 77 -155 ct 77 -171 98 -196 111 -196 ct 114 -196 119 -193 124 -188 ct +132 -182 137 -179 143 -179 ct 155 -179 162 -187 162 -201 ct 162 -217 152 -227 136 -227 ct +115 -227 101 -216 77 -181 ct 77 -181 77 -181 77 -226 ct 77 -226 77 -226 75 -227 ct +49 -216 32 -210 3 -200 ct 3 -200 3 -200 3 -192 ct p ef +363 -81 m 339 -43 318 -29 287 -29 ct 260 -29 239 -43 225 -72 ct 216 -90 213 -107 212 -137 ct +212 -137 212 -137 361 -137 ct 357 -169 352 -183 340 -199 ct 326 -217 303 -227 278 -227 ct +254 -227 231 -218 213 -201 ct 190 -181 177 -146 177 -106 ct 177 -37 212 5 268 5 ct +314 5 350 -24 370 -78 ct 370 -78 370 -78 363 -81 ct p +213 -153 m 218 -191 235 -209 264 -209 ct 294 -209 305 -196 312 -153 ct 312 -153 312 -153 213 -153 ct +p ef +616 -222 m 616 -222 616 -222 549 -222 ct 549 -222 549 -222 549 -215 ct 564 -213 571 -208 571 -199 ct +571 -194 570 -189 568 -184 ct 568 -184 568 -184 521 -56 ct 521 -56 521 -56 471 -182 ct +468 -189 467 -196 467 -201 ct 467 -210 472 -213 489 -215 ct 489 -215 489 -215 489 -222 ct +489 -222 489 -222 394 -222 ct 394 -222 394 -222 394 -214 ct 413 -214 416 -209 438 -158 ct +438 -158 438 -158 496 -16 ct 497 -13 499 -10 500 -6 ct 503 3 506 7 509 7 ct 512 7 515 1 522 -18 ct +522 -18 522 -18 584 -176 ct 599 -210 601 -213 616 -215 ct 616 -215 616 -215 616 -222 ct +p ef +829 -81 m 805 -43 784 -29 753 -29 ct 726 -29 705 -43 691 -72 ct 682 -90 679 -107 678 -137 ct +678 -137 678 -137 827 -137 ct 823 -169 818 -183 806 -199 ct 792 -217 769 -227 744 -227 ct +720 -227 697 -218 679 -201 ct 656 -181 643 -146 643 -106 ct 643 -37 678 5 734 5 ct +780 5 816 -24 836 -78 ct 836 -78 836 -78 829 -81 ct p +679 -153 m 684 -191 701 -209 730 -209 ct 760 -209 771 -196 778 -153 ct 778 -153 778 -153 679 -153 ct +p ef +854 -192 m 861 -194 866 -194 871 -194 ct 883 -194 888 -186 888 -164 ct 888 -164 888 -164 888 -41 ct +888 -17 884 -13 853 -7 ct 853 -7 853 -7 853 0 ct 853 0 853 0 970 0 ct 970 0 970 0 970 -8 ct +937 -8 928 -15 928 -44 ct 928 -44 928 -44 928 -155 ct 928 -171 949 -196 962 -196 ct +965 -196 970 -193 975 -188 ct 983 -182 988 -179 994 -179 ct 1006 -179 1013 -187 1013 -201 ct +1013 -217 1003 -227 987 -227 ct 966 -227 952 -216 928 -181 ct 928 -181 928 -181 928 -226 ct +928 -226 928 -226 926 -227 ct 900 -216 883 -210 854 -200 ct 854 -200 854 -200 854 -192 ct +p ef +1090 -336 m 1090 -336 1090 -336 1088 -337 ct 1067 -330 1054 -326 1031 -319 ct +1031 -319 1031 -319 1017 -315 ct 1017 -315 1017 -315 1017 -308 ct 1020 -308 1022 -308 1026 -308 ct +1045 -308 1049 -304 1049 -283 ct 1049 -283 1049 -283 1049 -27 ct 1049 -11 1091 5 1129 5 ct +1193 5 1243 -49 1243 -120 ct 1243 -181 1206 -227 1157 -227 ct 1128 -227 1100 -209 1090 -185 ct +1090 -185 1090 -185 1090 -336 ct p +1090 -159 m 1090 -178 1113 -196 1138 -196 ct 1176 -196 1200 -157 1200 -97 ct +1200 -42 1177 -11 1137 -11 ct 1112 -11 1090 -22 1090 -35 ct 1090 -35 1090 -35 1090 -159 ct +p ef +1464 -81 m 1440 -43 1419 -29 1388 -29 ct 1361 -29 1340 -43 1326 -72 ct 1317 -90 1314 -107 1313 -137 ct +1313 -137 1313 -137 1462 -137 ct 1458 -169 1453 -183 1441 -199 ct 1427 -217 1404 -227 1379 -227 ct +1355 -227 1332 -218 1314 -201 ct 1291 -181 1278 -146 1278 -106 ct 1278 -37 1313 5 1369 5 ct +1415 5 1451 -24 1471 -78 ct 1471 -78 1471 -78 1464 -81 ct p +1314 -153 m 1319 -191 1336 -209 1365 -209 ct 1395 -209 1406 -196 1413 -153 ct +1413 -153 1413 -153 1314 -153 ct p ef +1489 -192 m 1496 -194 1501 -194 1506 -194 ct 1518 -194 1523 -186 1523 -164 ct +1523 -164 1523 -164 1523 -41 ct 1523 -17 1519 -13 1488 -7 ct 1488 -7 1488 -7 1488 0 ct +1488 0 1488 0 1605 0 ct 1605 0 1605 0 1605 -8 ct 1572 -8 1563 -15 1563 -44 ct 1563 -44 1563 -44 1563 -155 ct +1563 -171 1584 -196 1597 -196 ct 1600 -196 1605 -193 1610 -188 ct 1618 -182 1623 -179 1629 -179 ct +1641 -179 1648 -187 1648 -201 ct 1648 -217 1638 -227 1622 -227 ct 1601 -227 1587 -216 1563 -181 ct +1563 -181 1563 -181 1563 -226 ct 1563 -226 1563 -226 1561 -227 ct 1535 -216 1518 -210 1489 -200 ct +1489 -200 1489 -200 1489 -192 ct p ef +1865 -32 m 1857 -26 1851 -23 1844 -23 ct 1833 -23 1829 -30 1829 -52 ct 1829 -52 1829 -52 1829 -148 ct +1829 -173 1827 -188 1819 -200 ct 1809 -218 1788 -227 1759 -227 ct 1714 -227 1678 -203 1678 -171 ct +1678 -160 1688 -150 1699 -150 ct 1711 -150 1721 -160 1721 -171 ct 1721 -173 1720 -175 1720 -179 ct +1719 -183 1718 -187 1718 -191 ct 1718 -204 1734 -215 1753 -215 ct 1777 -215 1790 -201 1790 -174 ct +1790 -174 1790 -174 1790 -144 ct 1715 -113 1707 -109 1686 -90 ct 1676 -81 1669 -64 1669 -48 ct +1669 -17 1690 5 1720 5 ct 1741 5 1761 -5 1790 -31 ct 1793 -5 1802 5 1821 5 ct 1838 5 1848 -1 1865 -20 ct +1865 -20 1865 -20 1865 -32 ct p +1790 -61 m 1790 -45 1788 -41 1777 -35 ct 1766 -28 1752 -24 1742 -24 ct 1725 -24 1712 -40 1712 -62 ct +1712 -62 1712 -62 1712 -63 ct 1712 -92 1731 -110 1790 -132 ct 1790 -132 1790 -132 1790 -61 ct +p ef +1994 -222 m 1994 -222 1994 -222 1946 -222 ct 1946 -222 1946 -222 1946 -279 ct +1946 -284 1945 -286 1942 -286 ct 1939 -281 1936 -277 1932 -272 ct 1914 -245 1893 -221 1886 -219 ct +1880 -216 1877 -212 1877 -210 ct 1877 -208 1878 -207 1879 -206 ct 1879 -206 1879 -206 1905 -206 ct +1905 -206 1905 -206 1905 -58 ct 1905 -16 1919 5 1948 5 ct 1972 5 1990 -7 2006 -33 ct +2006 -33 2006 -33 2000 -38 ct 1990 -26 1981 -21 1971 -21 ct 1953 -21 1946 -34 1946 -65 ct +1946 -65 1946 -65 1946 -206 ct 1946 -206 1946 -206 1994 -206 ct 1994 -206 1994 -206 1994 -222 ct +p ef +2096 -227 m 2096 -227 2096 -227 2021 -200 ct 2021 -200 2021 -200 2021 -192 ct +2021 -192 2021 -192 2025 -193 ct 2030 -194 2037 -194 2041 -194 ct 2053 -194 2057 -186 2057 -164 ct +2057 -164 2057 -164 2057 -49 ct 2057 -14 2052 -8 2019 -8 ct 2019 -8 2019 -8 2019 0 ct +2019 0 2019 0 2133 0 ct 2133 0 2133 0 2133 -8 ct 2102 -8 2098 -15 2098 -50 ct 2098 -50 2098 -50 2098 -225 ct +2098 -225 2098 -225 2096 -227 ct p +2073 -337 m 2060 -337 2049 -326 2049 -312 ct 2049 -298 2059 -287 2073 -287 ct +2087 -287 2098 -298 2098 -312 ct 2098 -326 2087 -337 2073 -337 ct p ef +2272 -227 m 2209 -227 2165 -180 2165 -112 ct 2165 -45 2210 5 2271 5 ct 2332 5 2379 -47 2379 -115 ct +2379 -180 2334 -227 2272 -227 ct p +2266 -213 m 2306 -213 2335 -166 2335 -98 ct 2335 -42 2313 -9 2277 -9 ct 2258 -9 2240 -21 2230 -40 ct +2216 -66 2209 -101 2209 -136 ct 2209 -183 2231 -213 2266 -213 ct p ef +2408 -196 m 2411 -198 2415 -198 2421 -198 ct 2434 -198 2439 -191 2439 -166 ct +2439 -166 2439 -166 2439 -44 ct 2439 -15 2433 -8 2409 -8 ct 2409 -8 2409 -8 2409 0 ct +2409 0 2409 0 2511 0 ct 2511 0 2511 0 2511 -8 ct 2487 -8 2479 -14 2479 -32 ct 2479 -32 2479 -32 2479 -171 ct +2503 -194 2513 -200 2529 -200 ct 2553 -200 2565 -184 2565 -152 ct 2565 -152 2565 -152 2565 -48 ct +2565 -17 2558 -8 2534 -8 ct 2534 -8 2534 -8 2534 0 ct 2534 0 2534 0 2635 0 ct 2635 0 2635 0 2635 -7 ct +2611 -10 2605 -16 2605 -40 ct 2605 -40 2605 -40 2605 -153 ct 2605 -199 2584 -227 2548 -227 ct +2526 -227 2511 -219 2478 -187 ct 2478 -187 2478 -187 2478 -226 ct 2478 -226 2478 -226 2475 -227 ct +2451 -218 2434 -213 2408 -205 ct 2408 -205 2408 -205 2408 -196 ct p ef +pom +gr +gr +gs +gs +pum +4561 12996 t +214 -32 m 206 -26 200 -23 193 -23 ct 182 -23 178 -30 178 -52 ct 178 -52 178 -52 178 -148 ct +178 -173 176 -188 168 -200 ct 158 -218 137 -227 108 -227 ct 63 -227 27 -203 27 -171 ct +27 -160 37 -150 48 -150 ct 60 -150 70 -160 70 -171 ct 70 -173 69 -175 69 -179 ct +68 -183 67 -187 67 -191 ct 67 -204 83 -215 102 -215 ct 126 -215 139 -201 139 -174 ct +139 -174 139 -174 139 -144 ct 64 -113 56 -109 35 -90 ct 25 -81 18 -64 18 -48 ct +18 -17 39 5 69 5 ct 90 5 110 -5 139 -31 ct 142 -5 151 5 170 5 ct 187 5 197 -1 214 -20 ct +214 -20 214 -20 214 -32 ct p +139 -61 m 139 -45 137 -41 126 -35 ct 115 -28 101 -24 91 -24 ct 74 -24 61 -40 61 -62 ct +61 -62 61 -62 61 -63 ct 61 -92 80 -110 139 -132 ct 139 -132 139 -132 139 -61 ct +p ef +387 5 m 387 5 387 5 458 -21 ct 458 -21 458 -21 458 -28 ct 449 -28 448 -28 447 -28 ct +429 -28 425 -33 425 -56 ct 425 -56 425 -56 425 -336 ct 425 -336 425 -336 423 -337 ct +400 -329 383 -324 352 -315 ct 352 -315 352 -315 352 -308 ct 356 -308 358 -308 362 -308 ct +380 -308 385 -303 385 -283 ct 385 -283 385 -283 385 -206 ct 366 -222 353 -227 334 -227 ct +278 -227 233 -171 233 -101 ct 233 -38 269 5 323 5 ct 350 5 368 -5 385 -28 ct 385 -28 385 -28 385 4 ct +385 4 385 4 387 5 ct p +385 -50 m 385 -47 381 -41 376 -35 ct 368 -26 356 -21 342 -21 ct 301 -21 275 -60 275 -121 ct +275 -177 298 -213 335 -213 ct 361 -213 385 -190 385 -164 ct 385 -164 385 -164 385 -50 ct +p ef +684 -32 m 676 -26 670 -23 663 -23 ct 652 -23 648 -30 648 -52 ct 648 -52 648 -52 648 -148 ct +648 -173 646 -188 638 -200 ct 628 -218 607 -227 578 -227 ct 533 -227 497 -203 497 -171 ct +497 -160 507 -150 518 -150 ct 530 -150 540 -160 540 -171 ct 540 -173 539 -175 539 -179 ct +538 -183 537 -187 537 -191 ct 537 -204 553 -215 572 -215 ct 596 -215 609 -201 609 -174 ct +609 -174 609 -174 609 -144 ct 534 -113 526 -109 505 -90 ct 495 -81 488 -64 488 -48 ct +488 -17 509 5 539 5 ct 560 5 580 -5 609 -31 ct 612 -5 621 5 640 5 ct 657 5 667 -1 684 -20 ct +684 -20 684 -20 684 -32 ct p +609 -61 m 609 -45 607 -41 596 -35 ct 585 -28 571 -24 561 -24 ct 544 -24 531 -40 531 -62 ct +531 -62 531 -62 531 -63 ct 531 -92 550 -110 609 -132 ct 609 -132 609 -132 609 -61 ct +p ef +694 -195 m 699 -195 702 -195 706 -195 ct 723 -195 726 -190 726 -167 ct 726 -167 726 -167 726 65 ct +726 90 721 96 692 99 ct 692 99 692 99 692 107 ct 692 107 692 107 810 107 ct 810 107 810 107 810 98 ct +773 98 767 93 767 61 ct 767 61 767 61 767 -16 ct 784 0 796 5 816 5 ct 873 5 918 -50 918 -122 ct +918 -183 884 -227 837 -227 ct 810 -227 788 -215 767 -189 ct 767 -189 767 -189 767 -226 ct +767 -226 767 -226 764 -227 ct 738 -217 721 -210 694 -202 ct 694 -202 694 -202 694 -195 ct +p +767 -165 m 767 -180 794 -197 816 -197 ct 852 -197 876 -160 876 -103 ct 876 -48 852 -11 817 -11 ct +795 -11 767 -29 767 -44 ct 767 -44 767 -44 767 -165 ct p ef +1063 -222 m 1063 -222 1063 -222 1015 -222 ct 1015 -222 1015 -222 1015 -279 ct +1015 -284 1014 -286 1011 -286 ct 1008 -281 1005 -277 1001 -272 ct 983 -245 962 -221 955 -219 ct +949 -216 946 -212 946 -210 ct 946 -208 947 -207 948 -206 ct 948 -206 948 -206 974 -206 ct +974 -206 974 -206 974 -58 ct 974 -16 988 5 1017 5 ct 1041 5 1059 -7 1075 -33 ct +1075 -33 1075 -33 1069 -38 ct 1059 -26 1050 -21 1040 -21 ct 1022 -21 1015 -34 1015 -65 ct +1015 -65 1015 -65 1015 -206 ct 1015 -206 1015 -206 1063 -206 ct 1063 -206 1063 -206 1063 -222 ct +p ef +1165 -227 m 1165 -227 1165 -227 1090 -200 ct 1090 -200 1090 -200 1090 -192 ct +1090 -192 1090 -192 1094 -193 ct 1099 -194 1106 -194 1110 -194 ct 1122 -194 1126 -186 1126 -164 ct +1126 -164 1126 -164 1126 -49 ct 1126 -14 1121 -8 1088 -8 ct 1088 -8 1088 -8 1088 0 ct +1088 0 1088 0 1202 0 ct 1202 0 1202 0 1202 -8 ct 1171 -8 1167 -15 1167 -50 ct 1167 -50 1167 -50 1167 -225 ct +1167 -225 1167 -225 1165 -227 ct p +1142 -337 m 1129 -337 1118 -326 1118 -312 ct 1118 -298 1128 -287 1142 -287 ct +1156 -287 1167 -298 1167 -312 ct 1167 -326 1156 -337 1142 -337 ct p ef +1450 -222 m 1450 -222 1450 -222 1383 -222 ct 1383 -222 1383 -222 1383 -215 ct +1398 -213 1405 -208 1405 -199 ct 1405 -194 1404 -189 1402 -184 ct 1402 -184 1402 -184 1355 -56 ct +1355 -56 1355 -56 1305 -182 ct 1302 -189 1301 -196 1301 -201 ct 1301 -210 1306 -213 1323 -215 ct +1323 -215 1323 -215 1323 -222 ct 1323 -222 1323 -222 1228 -222 ct 1228 -222 1228 -222 1228 -214 ct +1247 -214 1250 -209 1272 -158 ct 1272 -158 1272 -158 1330 -16 ct 1331 -13 1333 -10 1334 -6 ct +1337 3 1340 7 1343 7 ct 1346 7 1349 1 1356 -18 ct 1356 -18 1356 -18 1418 -176 ct +1433 -210 1435 -213 1450 -215 ct 1450 -215 1450 -215 1450 -222 ct p ef +1663 -81 m 1639 -43 1618 -29 1587 -29 ct 1560 -29 1539 -43 1525 -72 ct 1516 -90 1513 -107 1512 -137 ct +1512 -137 1512 -137 1661 -137 ct 1657 -169 1652 -183 1640 -199 ct 1626 -217 1603 -227 1578 -227 ct +1554 -227 1531 -218 1513 -201 ct 1490 -181 1477 -146 1477 -106 ct 1477 -37 1512 5 1568 5 ct +1614 5 1650 -24 1670 -78 ct 1670 -78 1670 -78 1663 -81 ct p +1513 -153 m 1518 -191 1535 -209 1564 -209 ct 1594 -209 1605 -196 1612 -153 ct +1612 -153 1612 -153 1513 -153 ct p ef +1958 -222 m 1958 -222 1958 -222 1898 -222 ct 1898 -222 1898 -222 1898 -279 ct +1898 -308 1907 -323 1926 -323 ct 1936 -323 1943 -318 1951 -304 ct 1959 -291 1965 -286 1973 -286 ct +1984 -286 1993 -295 1993 -306 ct 1993 -324 1972 -337 1943 -337 ct 1913 -337 1887 -324 1875 -301 ct +1862 -279 1858 -261 1858 -222 ct 1858 -222 1858 -222 1818 -222 ct 1818 -222 1818 -222 1818 -206 ct +1818 -206 1818 -206 1858 -206 ct 1858 -206 1858 -206 1858 -51 ct 1858 -14 1853 -8 1818 -8 ct +1818 -8 1818 -8 1818 0 ct 1818 0 1818 0 1944 0 ct 1944 0 1944 0 1944 -8 ct 1904 -8 1899 -13 1899 -51 ct +1899 -51 1899 -51 1899 -206 ct 1899 -206 1899 -206 1958 -206 ct 1958 -206 1958 -206 1958 -222 ct +p ef +2054 -227 m 2054 -227 2054 -227 1979 -200 ct 1979 -200 1979 -200 1979 -192 ct +1979 -192 1979 -192 1983 -193 ct 1988 -194 1995 -194 1999 -194 ct 2011 -194 2015 -186 2015 -164 ct +2015 -164 2015 -164 2015 -49 ct 2015 -14 2010 -8 1977 -8 ct 1977 -8 1977 -8 1977 0 ct +1977 0 1977 0 2091 0 ct 2091 0 2091 0 2091 -8 ct 2060 -8 2056 -15 2056 -50 ct 2056 -50 2056 -50 2056 -225 ct +2056 -225 2056 -225 2054 -227 ct p +2031 -337 m 2018 -337 2007 -326 2007 -312 ct 2007 -298 2017 -287 2031 -287 ct +2045 -287 2056 -298 2056 -312 ct 2056 -326 2045 -337 2031 -337 ct p ef +2117 -307 m 2117 -307 2117 -307 2120 -307 ct 2125 -308 2131 -308 2135 -308 ct +2151 -308 2155 -301 2155 -278 ct 2155 -278 2155 -278 2155 -42 ct 2155 -15 2149 -8 2118 -8 ct +2118 -8 2118 -8 2118 0 ct 2118 0 2118 0 2232 0 ct 2232 0 2232 0 2232 -8 ct 2202 -8 2196 -14 2196 -41 ct +2196 -41 2196 -41 2196 -336 ct 2196 -336 2196 -336 2194 -337 ct 2169 -328 2151 -323 2117 -315 ct +2117 -315 2117 -315 2117 -307 ct p ef +2367 -222 m 2367 -222 2367 -222 2319 -222 ct 2319 -222 2319 -222 2319 -279 ct +2319 -284 2318 -286 2315 -286 ct 2312 -281 2309 -277 2305 -272 ct 2287 -245 2266 -221 2259 -219 ct +2253 -216 2250 -212 2250 -210 ct 2250 -208 2251 -207 2252 -206 ct 2252 -206 2252 -206 2278 -206 ct +2278 -206 2278 -206 2278 -58 ct 2278 -16 2292 5 2321 5 ct 2345 5 2363 -7 2379 -33 ct +2379 -33 2379 -33 2373 -38 ct 2363 -26 2354 -21 2344 -21 ct 2326 -21 2319 -34 2319 -65 ct +2319 -65 2319 -65 2319 -206 ct 2319 -206 2319 -206 2367 -206 ct 2367 -206 2367 -206 2367 -222 ct +p ef +2581 -81 m 2557 -43 2536 -29 2505 -29 ct 2478 -29 2457 -43 2443 -72 ct 2434 -90 2431 -107 2430 -137 ct +2430 -137 2430 -137 2579 -137 ct 2575 -169 2570 -183 2558 -199 ct 2544 -217 2521 -227 2496 -227 ct +2472 -227 2449 -218 2431 -201 ct 2408 -181 2395 -146 2395 -106 ct 2395 -37 2430 5 2486 5 ct +2532 5 2568 -24 2588 -78 ct 2588 -78 2588 -78 2581 -81 ct p +2431 -153 m 2436 -191 2453 -209 2482 -209 ct 2512 -209 2523 -196 2530 -153 ct +2530 -153 2530 -153 2431 -153 ct p ef +2607 -192 m 2614 -194 2619 -194 2624 -194 ct 2636 -194 2641 -186 2641 -164 ct +2641 -164 2641 -164 2641 -41 ct 2641 -17 2637 -13 2606 -7 ct 2606 -7 2606 -7 2606 0 ct +2606 0 2606 0 2723 0 ct 2723 0 2723 0 2723 -8 ct 2690 -8 2681 -15 2681 -44 ct 2681 -44 2681 -44 2681 -155 ct +2681 -171 2702 -196 2715 -196 ct 2718 -196 2723 -193 2728 -188 ct 2736 -182 2741 -179 2747 -179 ct +2759 -179 2766 -187 2766 -201 ct 2766 -217 2756 -227 2740 -227 ct 2719 -227 2705 -216 2681 -181 ct +2681 -181 2681 -181 2681 -226 ct 2681 -226 2681 -226 2679 -227 ct 2653 -216 2636 -210 2607 -200 ct +2607 -200 2607 -200 2607 -192 ct p ef +pom +gr +gr +gs +gs +pum +10753 9450 t +9 -307 m 9 -307 9 -307 12 -307 ct 17 -308 23 -308 27 -308 ct 43 -308 47 -301 47 -278 ct +47 -278 47 -278 47 -42 ct 47 -15 41 -8 10 -8 ct 10 -8 10 -8 10 0 ct 10 0 10 0 124 0 ct +124 0 124 0 124 -8 ct 94 -8 88 -14 88 -41 ct 88 -41 88 -41 88 -336 ct 88 -336 88 -336 86 -337 ct +61 -328 43 -323 9 -315 ct 9 -315 9 -315 9 -307 ct p ef +256 -227 m 193 -227 149 -180 149 -112 ct 149 -45 194 5 255 5 ct 316 5 363 -47 363 -115 ct +363 -180 318 -227 256 -227 ct p +250 -213 m 290 -213 319 -166 319 -98 ct 319 -42 297 -9 261 -9 ct 242 -9 224 -21 214 -40 ct +200 -66 193 -101 193 -136 ct 193 -183 215 -213 250 -213 ct p ef +617 -25 m 617 -25 617 -25 614 -25 ct 592 -25 587 -30 587 -53 ct 587 -53 587 -53 587 -222 ct +587 -222 587 -222 510 -222 ct 510 -222 510 -222 510 -213 ct 540 -213 546 -208 546 -183 ct +546 -183 546 -183 546 -67 ct 546 -53 544 -46 537 -41 ct 524 -30 509 -24 494 -24 ct +476 -24 460 -41 460 -61 ct 460 -61 460 -61 460 -222 ct 460 -222 460 -222 389 -222 ct +389 -222 389 -222 389 -214 ct 413 -214 419 -206 419 -184 ct 419 -184 419 -184 419 -59 ct +419 -20 443 5 478 5 ct 496 5 515 -3 528 -16 ct 528 -16 528 -16 549 -38 ct 549 -38 549 -38 549 4 ct +549 4 549 4 551 5 ct 575 -5 592 -11 617 -18 ct 617 -18 617 -18 617 -25 ct p ef +798 5 m 798 5 798 5 869 -21 ct 869 -21 869 -21 869 -28 ct 860 -28 859 -28 858 -28 ct +840 -28 836 -33 836 -56 ct 836 -56 836 -56 836 -336 ct 836 -336 836 -336 834 -337 ct +811 -329 794 -324 763 -315 ct 763 -315 763 -315 763 -308 ct 767 -308 769 -308 773 -308 ct +791 -308 796 -303 796 -283 ct 796 -283 796 -283 796 -206 ct 777 -222 764 -227 745 -227 ct +689 -227 644 -171 644 -101 ct 644 -38 680 5 734 5 ct 761 5 779 -5 796 -28 ct 796 -28 796 -28 796 4 ct +796 4 796 4 798 5 ct p +796 -50 m 796 -47 792 -41 787 -35 ct 779 -26 767 -21 753 -21 ct 712 -21 686 -60 686 -121 ct +686 -177 709 -213 746 -213 ct 772 -213 796 -190 796 -164 ct 796 -164 796 -164 796 -50 ct +p ef +1034 -155 m 1034 -155 1034 -155 1032 -222 ct 1032 -222 1032 -222 1026 -222 ct +1026 -222 1026 -222 1025 -221 ct 1021 -218 1020 -217 1018 -217 ct 1016 -217 1011 -218 1005 -221 ct +995 -225 984 -227 972 -227 ct 933 -227 906 -202 906 -166 ct 906 -138 921 -118 962 -95 ct +962 -95 962 -95 990 -78 ct 1007 -69 1016 -57 1016 -41 ct 1016 -20 1000 -6 975 -6 ct +959 -6 944 -12 935 -23 ct 925 -35 920 -47 914 -75 ct 914 -75 914 -75 906 -75 ct +906 -75 906 -75 906 2 ct 906 2 906 2 912 2 ct 916 -3 918 -4 924 -4 ct 928 -4 935 -3 946 0 ct +959 3 973 5 981 5 ct 1018 5 1049 -24 1049 -58 ct 1049 -83 1038 -99 1009 -117 ct +1009 -117 1009 -117 957 -148 ct 943 -156 936 -169 936 -182 ct 936 -202 951 -216 973 -216 ct +1001 -216 1015 -199 1026 -155 ct 1026 -155 1026 -155 1034 -155 ct p ef +1079 -195 m 1084 -195 1087 -195 1091 -195 ct 1108 -195 1111 -190 1111 -167 ct +1111 -167 1111 -167 1111 65 ct 1111 90 1106 96 1077 99 ct 1077 99 1077 99 1077 107 ct +1077 107 1077 107 1195 107 ct 1195 107 1195 107 1195 98 ct 1158 98 1152 93 1152 61 ct +1152 61 1152 61 1152 -16 ct 1169 0 1181 5 1201 5 ct 1258 5 1303 -50 1303 -122 ct +1303 -183 1269 -227 1222 -227 ct 1195 -227 1173 -215 1152 -189 ct 1152 -189 1152 -189 1152 -226 ct +1152 -226 1152 -226 1149 -227 ct 1123 -217 1106 -210 1079 -202 ct 1079 -202 1079 -202 1079 -195 ct +p +1152 -165 m 1152 -180 1179 -197 1201 -197 ct 1237 -197 1261 -160 1261 -103 ct +1261 -48 1237 -11 1202 -11 ct 1180 -11 1152 -29 1152 -44 ct 1152 -44 1152 -44 1152 -165 ct +p ef +1523 -81 m 1499 -43 1478 -29 1447 -29 ct 1420 -29 1399 -43 1385 -72 ct 1376 -90 1373 -107 1372 -137 ct +1372 -137 1372 -137 1521 -137 ct 1517 -169 1512 -183 1500 -199 ct 1486 -217 1463 -227 1438 -227 ct +1414 -227 1391 -218 1373 -201 ct 1350 -181 1337 -146 1337 -106 ct 1337 -37 1372 5 1428 5 ct +1474 5 1510 -24 1530 -78 ct 1530 -78 1530 -78 1523 -81 ct p +1373 -153 m 1378 -191 1395 -209 1424 -209 ct 1454 -209 1465 -196 1472 -153 ct +1472 -153 1472 -153 1373 -153 ct p ef +1759 -32 m 1751 -26 1745 -23 1738 -23 ct 1727 -23 1723 -30 1723 -52 ct 1723 -52 1723 -52 1723 -148 ct +1723 -173 1721 -188 1713 -200 ct 1703 -218 1682 -227 1653 -227 ct 1608 -227 1572 -203 1572 -171 ct +1572 -160 1582 -150 1593 -150 ct 1605 -150 1615 -160 1615 -171 ct 1615 -173 1614 -175 1614 -179 ct +1613 -183 1612 -187 1612 -191 ct 1612 -204 1628 -215 1647 -215 ct 1671 -215 1684 -201 1684 -174 ct +1684 -174 1684 -174 1684 -144 ct 1609 -113 1601 -109 1580 -90 ct 1570 -81 1563 -64 1563 -48 ct +1563 -17 1584 5 1614 5 ct 1635 5 1655 -5 1684 -31 ct 1687 -5 1696 5 1715 5 ct 1732 5 1742 -1 1759 -20 ct +1759 -20 1759 -20 1759 -32 ct p +1684 -61 m 1684 -45 1682 -41 1671 -35 ct 1660 -28 1646 -24 1636 -24 ct 1619 -24 1606 -40 1606 -62 ct +1606 -62 1606 -62 1606 -63 ct 1606 -92 1625 -110 1684 -132 ct 1684 -132 1684 -132 1684 -61 ct +p ef +1768 -307 m 1775 -307 1779 -308 1784 -308 ct 1800 -308 1805 -302 1805 -278 ct +1805 -278 1805 -278 1805 -40 ct 1805 -15 1803 -13 1768 -7 ct 1768 -7 1768 -7 1768 0 ct +1768 0 1768 0 1882 0 ct 1882 0 1882 0 1882 -8 ct 1882 -8 1882 -8 1872 -8 ct 1853 -8 1845 -15 1845 -32 ct +1845 -32 1845 -32 1845 -124 ct 1845 -124 1845 -124 1913 -32 ct 1913 -32 1913 -32 1915 -30 ct +1916 -28 1917 -27 1918 -25 ct 1922 -20 1923 -17 1923 -15 ct 1923 -10 1919 -7 1913 -7 ct +1913 -7 1913 -7 1904 -7 ct 1904 -7 1904 -7 1904 0 ct 1904 0 1904 0 2009 0 ct 2009 0 2009 0 2009 -8 ct +1988 -8 1973 -18 1953 -43 ct 1953 -43 1953 -43 1879 -139 ct 1879 -139 1879 -139 1893 -152 ct +1927 -185 1957 -208 1971 -212 ct 1979 -214 1985 -215 1994 -215 ct 1994 -215 1994 -215 1997 -215 ct +1997 -215 1997 -215 1997 -222 ct 1997 -222 1997 -222 1899 -222 ct 1899 -222 1899 -222 1899 -215 ct +1918 -215 1923 -213 1923 -206 ct 1923 -202 1918 -195 1912 -189 ct 1912 -189 1912 -189 1845 -129 ct +1845 -129 1845 -129 1845 -336 ct 1845 -336 1845 -336 1843 -337 ct 1825 -331 1811 -327 1783 -319 ct +1783 -319 1783 -319 1768 -315 ct 1768 -315 1768 -315 1768 -307 ct p ef +2217 -81 m 2193 -43 2172 -29 2141 -29 ct 2114 -29 2093 -43 2079 -72 ct 2070 -90 2067 -107 2066 -137 ct +2066 -137 2066 -137 2215 -137 ct 2211 -169 2206 -183 2194 -199 ct 2180 -217 2157 -227 2132 -227 ct +2108 -227 2085 -218 2067 -201 ct 2044 -181 2031 -146 2031 -106 ct 2031 -37 2066 5 2122 5 ct +2168 5 2204 -24 2224 -78 ct 2224 -78 2224 -78 2217 -81 ct p +2067 -153 m 2072 -191 2089 -209 2118 -209 ct 2148 -209 2159 -196 2166 -153 ct +2166 -153 2166 -153 2067 -153 ct p ef +2242 -192 m 2249 -194 2254 -194 2259 -194 ct 2271 -194 2276 -186 2276 -164 ct +2276 -164 2276 -164 2276 -41 ct 2276 -17 2272 -13 2241 -7 ct 2241 -7 2241 -7 2241 0 ct +2241 0 2241 0 2358 0 ct 2358 0 2358 0 2358 -8 ct 2325 -8 2316 -15 2316 -44 ct 2316 -44 2316 -44 2316 -155 ct +2316 -171 2337 -196 2350 -196 ct 2353 -196 2358 -193 2363 -188 ct 2371 -182 2376 -179 2382 -179 ct +2394 -179 2401 -187 2401 -201 ct 2401 -217 2391 -227 2375 -227 ct 2354 -227 2340 -216 2316 -181 ct +2316 -181 2316 -181 2316 -226 ct 2316 -226 2316 -226 2314 -227 ct 2288 -216 2271 -210 2242 -200 ct +2242 -200 2242 -200 2242 -192 ct p ef +pom +gr +gr +gs +gs +pum +4619 16250 t +121 -227 m 58 -227 14 -180 14 -112 ct 14 -45 59 5 120 5 ct 181 5 228 -47 228 -115 ct +228 -180 183 -227 121 -227 ct p +115 -213 m 155 -213 184 -166 184 -98 ct 184 -42 162 -9 126 -9 ct 107 -9 89 -21 79 -40 ct +65 -66 58 -101 58 -136 ct 58 -183 80 -213 115 -213 ct p ef +482 -25 m 482 -25 482 -25 479 -25 ct 457 -25 452 -30 452 -53 ct 452 -53 452 -53 452 -222 ct +452 -222 452 -222 375 -222 ct 375 -222 375 -222 375 -213 ct 405 -213 411 -208 411 -183 ct +411 -183 411 -183 411 -67 ct 411 -53 409 -46 402 -41 ct 389 -30 374 -24 359 -24 ct +341 -24 325 -41 325 -61 ct 325 -61 325 -61 325 -222 ct 325 -222 325 -222 254 -222 ct +254 -222 254 -222 254 -214 ct 278 -214 284 -206 284 -184 ct 284 -184 284 -184 284 -59 ct +284 -20 308 5 343 5 ct 361 5 380 -3 393 -16 ct 393 -16 393 -16 414 -38 ct 414 -38 414 -38 414 4 ct +414 4 414 4 416 5 ct 440 -5 457 -11 482 -18 ct 482 -18 482 -18 482 -25 ct p ef +618 -222 m 618 -222 618 -222 570 -222 ct 570 -222 570 -222 570 -279 ct 570 -284 569 -286 566 -286 ct +563 -281 560 -277 556 -272 ct 538 -245 517 -221 510 -219 ct 504 -216 501 -212 501 -210 ct +501 -208 502 -207 503 -206 ct 503 -206 503 -206 529 -206 ct 529 -206 529 -206 529 -58 ct +529 -16 543 5 572 5 ct 596 5 614 -7 630 -33 ct 630 -33 630 -33 624 -38 ct 614 -26 605 -21 595 -21 ct +577 -21 570 -34 570 -65 ct 570 -65 570 -65 570 -206 ct 570 -206 570 -206 618 -206 ct +618 -206 618 -206 618 -222 ct p ef +639 -195 m 644 -195 647 -195 651 -195 ct 668 -195 671 -190 671 -167 ct 671 -167 671 -167 671 65 ct +671 90 666 96 637 99 ct 637 99 637 99 637 107 ct 637 107 637 107 755 107 ct 755 107 755 107 755 98 ct +718 98 712 93 712 61 ct 712 61 712 61 712 -16 ct 729 0 741 5 761 5 ct 818 5 863 -50 863 -122 ct +863 -183 829 -227 782 -227 ct 755 -227 733 -215 712 -189 ct 712 -189 712 -189 712 -226 ct +712 -226 712 -226 709 -227 ct 683 -217 666 -210 639 -202 ct 639 -202 639 -202 639 -195 ct +p +712 -165 m 712 -180 739 -197 761 -197 ct 797 -197 821 -160 821 -103 ct 821 -48 797 -11 762 -11 ct +740 -11 712 -29 712 -44 ct 712 -44 712 -44 712 -165 ct p ef +1117 -25 m 1117 -25 1117 -25 1114 -25 ct 1092 -25 1087 -30 1087 -53 ct 1087 -53 1087 -53 1087 -222 ct +1087 -222 1087 -222 1010 -222 ct 1010 -222 1010 -222 1010 -213 ct 1040 -213 1046 -208 1046 -183 ct +1046 -183 1046 -183 1046 -67 ct 1046 -53 1044 -46 1037 -41 ct 1024 -30 1009 -24 994 -24 ct +976 -24 960 -41 960 -61 ct 960 -61 960 -61 960 -222 ct 960 -222 960 -222 889 -222 ct +889 -222 889 -222 889 -214 ct 913 -214 919 -206 919 -184 ct 919 -184 919 -184 919 -59 ct +919 -20 943 5 978 5 ct 996 5 1015 -3 1028 -16 ct 1028 -16 1028 -16 1049 -38 ct +1049 -38 1049 -38 1049 4 ct 1049 4 1049 4 1051 5 ct 1075 -5 1092 -11 1117 -18 ct +1117 -18 1117 -18 1117 -25 ct p ef +1253 -222 m 1253 -222 1253 -222 1205 -222 ct 1205 -222 1205 -222 1205 -279 ct +1205 -284 1204 -286 1201 -286 ct 1198 -281 1195 -277 1191 -272 ct 1173 -245 1152 -221 1145 -219 ct +1139 -216 1136 -212 1136 -210 ct 1136 -208 1137 -207 1138 -206 ct 1138 -206 1138 -206 1164 -206 ct +1164 -206 1164 -206 1164 -58 ct 1164 -16 1178 5 1207 5 ct 1231 5 1249 -7 1265 -33 ct +1265 -33 1265 -33 1259 -38 ct 1249 -26 1240 -21 1230 -21 ct 1212 -21 1205 -34 1205 -65 ct +1205 -65 1205 -65 1205 -206 ct 1205 -206 1205 -206 1253 -206 ct 1253 -206 1253 -206 1253 -222 ct +p ef +pom +gr +gs +pum +4138 16851 t +143 -334 m 107 -310 92 -297 75 -274 ct 40 -231 23 -182 23 -124 ct 23 -62 41 -13 84 37 ct +104 61 116 72 141 87 ct 141 87 141 87 147 79 ct 108 48 95 31 82 -6 ct 70 -39 65 -76 65 -126 ct +65 -178 71 -218 84 -249 ct 98 -279 112 -297 147 -326 ct 147 -326 147 -326 143 -334 ct +p ef +288 -222 m 288 -222 288 -222 240 -222 ct 240 -222 240 -222 240 -279 ct 240 -284 239 -286 236 -286 ct +233 -281 230 -277 226 -272 ct 208 -245 187 -221 180 -219 ct 174 -216 171 -212 171 -210 ct +171 -208 172 -207 173 -206 ct 173 -206 173 -206 199 -206 ct 199 -206 199 -206 199 -58 ct +199 -16 213 5 242 5 ct 266 5 284 -7 300 -33 ct 300 -33 300 -33 294 -38 ct 284 -26 275 -21 265 -21 ct +247 -21 240 -34 240 -65 ct 240 -65 240 -65 240 -206 ct 240 -206 240 -206 288 -206 ct +288 -206 288 -206 288 -222 ct p ef +426 -227 m 363 -227 319 -180 319 -112 ct 319 -45 364 5 425 5 ct 486 5 533 -47 533 -115 ct +533 -180 488 -227 426 -227 ct p +420 -213 m 460 -213 489 -166 489 -98 ct 489 -42 467 -9 431 -9 ct 412 -9 394 -21 384 -40 ct +370 -66 363 -101 363 -136 ct 363 -183 385 -213 420 -213 ct p ef +827 -222 m 827 -222 827 -222 767 -222 ct 767 -222 767 -222 767 -279 ct 767 -308 776 -323 795 -323 ct +805 -323 812 -318 820 -304 ct 828 -291 834 -286 842 -286 ct 853 -286 862 -295 862 -306 ct +862 -324 841 -337 812 -337 ct 782 -337 756 -324 744 -301 ct 731 -279 727 -261 727 -222 ct +727 -222 727 -222 687 -222 ct 687 -222 687 -222 687 -206 ct 687 -206 687 -206 727 -206 ct +727 -206 727 -206 727 -51 ct 727 -14 722 -8 687 -8 ct 687 -8 687 -8 687 0 ct 687 0 687 0 813 0 ct +813 0 813 0 813 -8 ct 773 -8 768 -13 768 -51 ct 768 -51 768 -51 768 -206 ct 768 -206 768 -206 827 -206 ct +827 -206 827 -206 827 -222 ct p ef +1052 -32 m 1044 -26 1038 -23 1031 -23 ct 1020 -23 1016 -30 1016 -52 ct 1016 -52 1016 -52 1016 -148 ct +1016 -173 1014 -188 1006 -200 ct 996 -218 975 -227 946 -227 ct 901 -227 865 -203 865 -171 ct +865 -160 875 -150 886 -150 ct 898 -150 908 -160 908 -171 ct 908 -173 907 -175 907 -179 ct +906 -183 905 -187 905 -191 ct 905 -204 921 -215 940 -215 ct 964 -215 977 -201 977 -174 ct +977 -174 977 -174 977 -144 ct 902 -113 894 -109 873 -90 ct 863 -81 856 -64 856 -48 ct +856 -17 877 5 907 5 ct 928 5 948 -5 977 -31 ct 980 -5 989 5 1008 5 ct 1025 5 1035 -1 1052 -20 ct +1052 -20 1052 -20 1052 -32 ct p +977 -61 m 977 -45 975 -41 964 -35 ct 953 -28 939 -24 929 -24 ct 912 -24 899 -40 899 -62 ct +899 -62 899 -62 899 -63 ct 899 -92 918 -110 977 -132 ct 977 -132 977 -132 977 -61 ct +p ef +1061 -192 m 1068 -194 1073 -194 1078 -194 ct 1090 -194 1095 -186 1095 -164 ct +1095 -164 1095 -164 1095 -41 ct 1095 -17 1091 -13 1060 -7 ct 1060 -7 1060 -7 1060 0 ct +1060 0 1060 0 1177 0 ct 1177 0 1177 0 1177 -8 ct 1144 -8 1135 -15 1135 -44 ct 1135 -44 1135 -44 1135 -155 ct +1135 -171 1156 -196 1169 -196 ct 1172 -196 1177 -193 1182 -188 ct 1190 -182 1195 -179 1201 -179 ct +1213 -179 1220 -187 1220 -201 ct 1220 -217 1210 -227 1194 -227 ct 1173 -227 1159 -216 1135 -181 ct +1135 -181 1135 -181 1135 -226 ct 1135 -226 1135 -226 1133 -227 ct 1107 -216 1090 -210 1061 -200 ct +1061 -200 1061 -200 1061 -192 ct p ef +1544 -81 m 1520 -43 1499 -29 1468 -29 ct 1441 -29 1420 -43 1406 -72 ct 1397 -90 1394 -107 1393 -137 ct +1393 -137 1393 -137 1542 -137 ct 1538 -169 1533 -183 1521 -199 ct 1507 -217 1484 -227 1459 -227 ct +1435 -227 1412 -218 1394 -201 ct 1371 -181 1358 -146 1358 -106 ct 1358 -37 1393 5 1449 5 ct +1495 5 1531 -24 1551 -78 ct 1551 -78 1551 -78 1544 -81 ct p +1394 -153 m 1399 -191 1416 -209 1445 -209 ct 1475 -209 1486 -196 1493 -153 ct +1493 -153 1493 -153 1394 -153 ct p ef +1574 -196 m 1577 -198 1581 -198 1587 -198 ct 1600 -198 1605 -191 1605 -166 ct +1605 -166 1605 -166 1605 -44 ct 1605 -15 1599 -8 1575 -8 ct 1575 -8 1575 -8 1575 0 ct +1575 0 1575 0 1677 0 ct 1677 0 1677 0 1677 -8 ct 1653 -8 1645 -14 1645 -32 ct 1645 -32 1645 -32 1645 -171 ct +1669 -194 1679 -200 1695 -200 ct 1719 -200 1731 -184 1731 -152 ct 1731 -152 1731 -152 1731 -48 ct +1731 -17 1724 -8 1700 -8 ct 1700 -8 1700 -8 1700 0 ct 1700 0 1700 0 1801 0 ct 1801 0 1801 0 1801 -7 ct +1777 -10 1771 -16 1771 -40 ct 1771 -40 1771 -40 1771 -153 ct 1771 -199 1750 -227 1714 -227 ct +1692 -227 1677 -219 1644 -187 ct 1644 -187 1644 -187 1644 -226 ct 1644 -226 1644 -226 1641 -227 ct +1617 -218 1600 -213 1574 -205 ct 1574 -205 1574 -205 1574 -196 ct p ef +1983 5 m 1983 5 1983 5 2054 -21 ct 2054 -21 2054 -21 2054 -28 ct 2045 -28 2044 -28 2043 -28 ct +2025 -28 2021 -33 2021 -56 ct 2021 -56 2021 -56 2021 -336 ct 2021 -336 2021 -336 2019 -337 ct +1996 -329 1979 -324 1948 -315 ct 1948 -315 1948 -315 1948 -308 ct 1952 -308 1954 -308 1958 -308 ct +1976 -308 1981 -303 1981 -283 ct 1981 -283 1981 -283 1981 -206 ct 1962 -222 1949 -227 1930 -227 ct +1874 -227 1829 -171 1829 -101 ct 1829 -38 1865 5 1919 5 ct 1946 5 1964 -5 1981 -28 ct +1981 -28 1981 -28 1981 4 ct 1981 4 1981 4 1983 5 ct p +1981 -50 m 1981 -47 1977 -41 1972 -35 ct 1964 -26 1952 -21 1938 -21 ct 1897 -21 1871 -60 1871 -121 ct +1871 -177 1894 -213 1931 -213 ct 1957 -213 1981 -190 1981 -164 ct 1981 -164 1981 -164 1981 -50 ct +p ef +2084 87 m 2120 64 2135 51 2153 28 ct 2187 -15 2204 -64 2204 -122 ct 2204 -185 2186 -233 2143 -283 ct +2124 -307 2111 -318 2086 -334 ct 2086 -334 2086 -334 2080 -326 ct 2119 -295 2132 -277 2145 -240 ct +2157 -207 2162 -170 2162 -120 ct 2162 -69 2156 -28 2143 2 ct 2129 33 2115 51 2080 79 ct +2080 79 2080 79 2084 87 ct p ef +pom +gr +gr +gs +gs +pum +8742 14319 t +7 -199 m 14 -200 17 -201 23 -201 ct 51 -201 58 -188 81 -103 ct 89 -71 101 -13 101 -4 ct +101 4 98 11 91 20 ct 76 41 66 54 60 59 ct 50 70 44 74 38 74 ct 35 74 31 73 26 69 ct +18 63 13 60 7 60 ct -3 60 -12 69 -12 80 ct -12 92 -1 102 13 102 ct 45 102 110 27 163 -71 ct +197 -131 210 -167 210 -191 ct 210 -206 198 -219 183 -219 ct 172 -219 164 -211 164 -200 ct +164 -193 168 -188 178 -181 ct 187 -176 191 -171 191 -164 ct 191 -145 172 -106 130 -36 ct +130 -36 130 -36 121 -94 ct 113 -137 85 -219 78 -219 ct 78 -219 78 -219 76 -219 ct +76 -218 74 -218 72 -218 ct 67 -217 49 -214 23 -209 ct 21 -209 14 -208 7 -207 ct +7 -207 7 -207 7 -199 ct p ef +pom +gr +gs +pum +8962 14319 t +143 -334 m 107 -310 92 -297 75 -274 ct 40 -231 23 -182 23 -124 ct 23 -62 41 -13 84 37 ct +104 61 116 72 141 87 ct 141 87 141 87 147 79 ct 108 48 95 31 82 -6 ct 70 -39 65 -76 65 -126 ct +65 -178 71 -218 84 -249 ct 98 -279 112 -297 147 -326 ct 147 -326 147 -326 143 -334 ct +p ef +pom +gr +gs +pum +9127 14319 t +227 -58 m 227 -58 227 -58 217 -45 ct 203 -27 194 -19 187 -19 ct 183 -19 179 -23 179 -27 ct +179 -31 179 -31 186 -58 ct 186 -58 186 -58 214 -160 ct 216 -170 218 -181 218 -188 ct +218 -206 205 -218 186 -218 ct 154 -218 123 -189 72 -110 ct 72 -110 72 -110 105 -217 ct +105 -217 105 -217 104 -218 ct 77 -213 67 -211 24 -203 ct 24 -203 24 -203 24 -195 ct +49 -195 55 -192 55 -182 ct 55 -179 55 -176 54 -173 ct 54 -173 54 -173 7 0 ct 7 0 7 0 44 0 ct +67 -78 72 -89 93 -123 ct 123 -168 148 -193 166 -193 ct 174 -193 178 -188 178 -179 ct +178 -173 175 -156 171 -141 ct 171 -141 171 -141 150 -60 ct 143 -35 142 -28 142 -23 ct +142 -4 149 4 165 4 ct 187 4 200 -6 234 -52 ct 234 -52 234 -52 227 -58 ct p ef +pom +gr +gs +pum +9377 14319 t +18 87 m 54 64 69 51 87 28 ct 121 -15 138 -64 138 -122 ct 138 -185 120 -233 77 -283 ct +58 -307 45 -318 20 -334 ct 20 -334 20 -334 14 -326 ct 53 -295 66 -277 79 -240 ct +91 -207 96 -170 96 -120 ct 96 -69 90 -28 77 2 ct 63 33 49 51 14 79 ct 14 79 14 79 18 87 ct +p ef +pom +gr +gr +gs +gs +pum +8742 14186 t +45 -147 m 114 -290 l 183 -147 l 216 -147 l 128 -327 l 99 -327 l 12 -147 l +45 -147 l p ef +pom +gr +gr +gs +gs +pum +14351 14292 t +7 -199 m 14 -200 17 -201 23 -201 ct 51 -201 58 -188 81 -103 ct 89 -71 101 -13 101 -4 ct +101 4 98 11 91 20 ct 76 41 66 54 60 59 ct 50 70 44 74 38 74 ct 35 74 31 73 26 69 ct +18 63 13 60 7 60 ct -3 60 -12 69 -12 80 ct -12 92 -1 102 13 102 ct 45 102 110 27 163 -71 ct +197 -131 210 -167 210 -191 ct 210 -206 198 -219 183 -219 ct 172 -219 164 -211 164 -200 ct +164 -193 168 -188 178 -181 ct 187 -176 191 -171 191 -164 ct 191 -145 172 -106 130 -36 ct +130 -36 130 -36 121 -94 ct 113 -137 85 -219 78 -219 ct 78 -219 78 -219 76 -219 ct +76 -218 74 -218 72 -218 ct 67 -217 49 -214 23 -209 ct 21 -209 14 -208 7 -207 ct +7 -207 7 -207 7 -199 ct p ef +pom +gr +gs +pum +14571 14292 t +143 -334 m 107 -310 92 -297 75 -274 ct 40 -231 23 -182 23 -124 ct 23 -62 41 -13 84 37 ct +104 61 116 72 141 87 ct 141 87 141 87 147 79 ct 108 48 95 31 82 -6 ct 70 -39 65 -76 65 -126 ct +65 -178 71 -218 84 -249 ct 98 -279 112 -297 147 -326 ct 147 -326 147 -326 143 -334 ct +p ef +pom +gr +gs +pum +14736 14292 t +227 -58 m 227 -58 227 -58 217 -45 ct 203 -27 194 -19 187 -19 ct 183 -19 179 -23 179 -27 ct +179 -31 179 -31 186 -58 ct 186 -58 186 -58 214 -160 ct 216 -170 218 -181 218 -188 ct +218 -206 205 -218 186 -218 ct 154 -218 123 -189 72 -110 ct 72 -110 72 -110 105 -217 ct +105 -217 105 -217 104 -218 ct 77 -213 67 -211 24 -203 ct 24 -203 24 -203 24 -195 ct +49 -195 55 -192 55 -182 ct 55 -179 55 -176 54 -173 ct 54 -173 54 -173 7 0 ct 7 0 7 0 44 0 ct +67 -78 72 -89 93 -123 ct 123 -168 148 -193 166 -193 ct 174 -193 178 -188 178 -179 ct +178 -173 175 -156 171 -141 ct 171 -141 171 -141 150 -60 ct 143 -35 142 -28 142 -23 ct +142 -4 149 4 165 4 ct 187 4 200 -6 234 -52 ct 234 -52 234 -52 227 -58 ct p ef +pom +gr +gs +pum +14986 14292 t +18 87 m 54 64 69 51 87 28 ct 121 -15 138 -64 138 -122 ct 138 -185 120 -233 77 -283 ct +58 -307 45 -318 20 -334 ct 20 -334 20 -334 14 -326 ct 53 -295 66 -277 79 -240 ct +91 -207 96 -170 96 -120 ct 96 -69 90 -28 77 2 ct 63 33 49 51 14 79 ct 14 79 14 79 18 87 ct +p ef +pom +gr +gr +tm setmatrix +0 0 t +1 1 s +0 8286 t +pom +count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore +%%PageTrailer +%%Trailer +%%EOF diff --git a/src/libs/speexdsp/doc/echo_path.odg b/src/libs/speexdsp/doc/echo_path.odg new file mode 100644 index 00000000..460af845 Binary files /dev/null and b/src/libs/speexdsp/doc/echo_path.odg differ diff --git a/src/libs/speexdsp/doc/manual.lyx b/src/libs/speexdsp/doc/manual.lyx new file mode 100644 index 00000000..fcbe985a --- /dev/null +++ b/src/libs/speexdsp/doc/manual.lyx @@ -0,0 +1,11984 @@ +#LyX 1.6.1 created this file. For more info see http://www.lyx.org/ +\lyxformat 345 +\begin_document +\begin_header +\textclass scrbook +\use_default_options true +\language english +\inputencoding auto +\font_roman default +\font_sans default +\font_typewriter default +\font_default_family default +\font_sc false +\font_osf false +\font_sf_scale 100 +\font_tt_scale 100 + +\graphics default +\paperfontsize 10 +\spacing single +\use_hyperref false +\papersize letterpaper +\use_geometry true +\use_amsmath 2 +\use_esint 2 +\cite_engine basic +\use_bibtopic false +\paperorientation portrait +\leftmargin 2cm +\topmargin 2cm +\rightmargin 2cm +\bottommargin 2cm +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\defskip medskip +\quotes_language english +\papercolumns 1 +\papersides 1 +\paperpagestyle headings +\tracking_changes false +\output_changes false +\author "" +\author "" +\end_header + +\begin_body + +\begin_layout Title +The Speex Manual +\begin_inset Newline newline +\end_inset + +Version 1.2 +\end_layout + +\begin_layout Author +Jean-Marc Valin +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Standard +Copyright +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +copyright +\end_layout + +\end_inset + + 2002-2008 Jean-Marc Valin/Xiph.org Foundation +\end_layout + +\begin_layout Standard +Permission is granted to copy, distribute and/or modify this document under + the terms of the GNU Free Documentation License, Version 1.1 or any later + version published by the Free Software Foundation; with no Invariant Section, + with no Front-Cover Texts, and with no Back-Cover. + A copy of the license is included in the section entitled "GNU Free Documentati +on License". + +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\begin_inset CommandInset toc +LatexCommand tableofcontents + +\end_inset + + +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset FloatList table + +\end_inset + + +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +Introduction to Speex +\end_layout + +\begin_layout Standard +The Speex codec ( +\family typewriter +http://www.speex.org/ +\family default +) exists because there is a need for a speech codec that is open-source + and free from software patent royalties. + These are essential conditions for being usable in any open-source software. + In essence, Speex is to speech what Vorbis is to audio/music. + Unlike many other speech codecs, Speex is not designed for mobile phones + but rather for packet networks and voice over IP (VoIP) applications. + File-based compression is of course also supported. + +\end_layout + +\begin_layout Standard +The Speex codec is designed to be very flexible and support a wide range + of speech quality and bit-rate. + Support for very good quality speech also means that Speex can encode wideband + speech (16 kHz sampling rate) in addition to narrowband speech (telephone + quality, 8 kHz sampling rate). +\end_layout + +\begin_layout Standard +Designing for VoIP instead of mobile phones means that Speex is robust to + lost packets, but not to corrupted ones. + This is based on the assumption that in VoIP, packets either arrive unaltered + or don't arrive at all. + Because Speex is targeted at a wide range of devices, it has modest (adjustable +) complexity and a small memory footprint. +\end_layout + +\begin_layout Standard +All the design goals led to the choice of CELP +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +CELP +\end_layout + +\end_inset + + as the encoding technique. + One of the main reasons is that CELP has long proved that it could work + reliably and scale well to both low bit-rates (e.g. + DoD CELP @ 4.8 kbps) and high bit-rates (e.g. + G.728 @ 16 kbps). + +\end_layout + +\begin_layout Section +Getting help +\begin_inset CommandInset label +LatexCommand label +name "sec:Getting-help" + +\end_inset + + +\end_layout + +\begin_layout Standard +As for many open source projects, there are many ways to get help with Speex. + These include: +\end_layout + +\begin_layout Itemize +This manual +\end_layout + +\begin_layout Itemize +Other documentation on the Speex website (http://www.speex.org/) +\end_layout + +\begin_layout Itemize +Mailing list: Discuss any Speex-related topic on speex-dev@xiph.org (not + just for developers) +\end_layout + +\begin_layout Itemize +IRC: The main channel is #speex on irc.freenode.net. + Note that due to time differences, it may take a while to get someone, + so please be patient. +\end_layout + +\begin_layout Itemize +Email the author privately at jean-marc.valin@usherbrooke.ca +\series bold +only +\series default + for private/delicate topics you do not wish to discuss publicly. +\end_layout + +\begin_layout Standard +Before asking for help (mailing list or IRC), +\series bold +it is important to first read this manual +\series default + (OK, so if you made it here it's already a good sign). + It is generally considered rude to ask on a mailing list about topics that + are clearly detailed in the documentation. + On the other hand, it's perfectly OK (and encouraged) to ask for clarifications + about something covered in the manual. + This manual does not (yet) cover everything about Speex, so everyone is + encouraged to ask questions, send comments, feature requests, or just let + us know how Speex is being used. + +\end_layout + +\begin_layout Standard +Here are some additional guidelines related to the mailing list. + Before reporting bugs in Speex to the list, it is strongly recommended + (if possible) to first test whether these bugs can be reproduced using + the speexenc and speexdec (see Section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Command-line-encoder/decoder" + +\end_inset + +) command-line utilities. + Bugs reported based on 3rd party code are both harder to find and far too + often caused by errors that have nothing to do with Speex. + +\end_layout + +\begin_layout Section +About this document +\end_layout + +\begin_layout Standard +This document is divided in the following way. + Section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Feature-description" + +\end_inset + + describes the different Speex features and defines many basic terms that + are used throughout this manual. + Section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Command-line-encoder/decoder" + +\end_inset + + documents the standard command-line tools provided in the Speex distribution. + Section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Programming-with-Speex" + +\end_inset + + includes detailed instructions about programming using the libspeex +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +libspeex +\end_layout + +\end_inset + + API. + Section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Formats-and-standards" + +\end_inset + + has some information related to Speex and standards. + +\end_layout + +\begin_layout Standard +The three last sections describe the algorithms used in Speex. + These sections require signal processing knowledge, but are not required + for merely using Speex. + They are intended for people who want to understand how Speex really works + and/or want to do research based on Speex. + Section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Introduction-to-CELP" + +\end_inset + + explains the general idea behind CELP, while sections +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Speex-narrowband-mode" + +\end_inset + + and +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Speex-wideband-mode" + +\end_inset + + are specific to Speex. +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +Codec description +\begin_inset CommandInset label +LatexCommand label +name "sec:Feature-description" + +\end_inset + + +\end_layout + +\begin_layout Standard +This section describes Speex and its features into more details. +\end_layout + +\begin_layout Section +Concepts +\end_layout + +\begin_layout Standard +Before introducing all the Speex features, here are some concepts in speech + coding that help better understand the rest of the manual. + Although some are general concepts in speech/audio processing, others are + specific to Speex. +\end_layout + +\begin_layout Subsection* +Sampling rate +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +sampling rate +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The sampling rate expressed in Hertz (Hz) is the number of samples taken + from a signal per second. + For a sampling rate of +\begin_inset Formula $F_{s}$ +\end_inset + + kHz, the highest frequency that can be represented is equal to +\begin_inset Formula $F_{s}/2$ +\end_inset + + kHz ( +\begin_inset Formula $F_{s}/2$ +\end_inset + + is known as the Nyquist frequency). + This is a fundamental property in signal processing and is described by + the sampling theorem. + Speex is mainly designed for three different sampling rates: 8 kHz, 16 + kHz, and 32 kHz. + These are respectively referred to as narrowband +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +narrowband +\end_layout + +\end_inset + +, wideband +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +wideband +\end_layout + +\end_inset + + and ultra-wideband +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +ultra-wideband +\end_layout + +\end_inset + +. + +\end_layout + +\begin_layout Subsection* +Bit-rate +\end_layout + +\begin_layout Standard +When encoding a speech signal, the bit-rate is defined as the number of + bits per unit of time required to encode the speech. + It is measured in +\emph on +bits per second +\emph default + (bps), or generally +\emph on +kilobits per second +\emph default +. + It is important to make the distinction between +\emph on +kilo +\series bold +bits +\series default +\emph default + +\emph on +per second +\emph default + (k +\series bold +b +\series default +ps) and +\emph on +kilo +\series bold +bytes +\series default +\emph default + +\emph on +per second +\emph default + (k +\series bold +B +\series default +ps). +\end_layout + +\begin_layout Subsection* +Quality +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +quality +\end_layout + +\end_inset + + (variable) +\end_layout + +\begin_layout Standard +Speex is a lossy codec, which means that it achieves compression at the + expense of fidelity of the input speech signal. + Unlike some other speech codecs, it is possible to control the trade-off + made between quality and bit-rate. + The Speex encoding process is controlled most of the time by a quality + parameter that ranges from 0 to 10. + In constant bit-rate +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +constant bit-rate +\end_layout + +\end_inset + + (CBR) operation, the quality parameter is an integer, while for variable + bit-rate (VBR), the parameter is a float. + +\end_layout + +\begin_layout Subsection* +Complexity +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +complexity +\end_layout + +\end_inset + + (variable) +\end_layout + +\begin_layout Standard +With Speex, it is possible to vary the complexity allowed for the encoder. + This is done by controlling how the search is performed with an integer + ranging from 1 to 10 in a way that's similar to the -1 to -9 options to + +\emph on +gzip +\emph default + and +\emph on +bzip2 +\emph default + compression utilities. + For normal use, the noise level at complexity 1 is between 1 and 2 dB higher + than at complexity 10, but the CPU requirements for complexity 10 is about + 5 times higher than for complexity 1. + In practice, the best trade-off is between complexity 2 and 4, though higher + settings are often useful when encoding non-speech sounds like DTMF +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +DTMF +\end_layout + +\end_inset + + tones. +\end_layout + +\begin_layout Subsection* +Variable Bit-Rate +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +variable bit-rate +\end_layout + +\end_inset + + (VBR) +\end_layout + +\begin_layout Standard +Variable bit-rate (VBR) allows a codec to change its bit-rate dynamically + to adapt to the +\begin_inset Quotes eld +\end_inset + +difficulty +\begin_inset Quotes erd +\end_inset + + of the audio being encoded. + In the example of Speex, sounds like vowels and high-energy transients + require a higher bit-rate to achieve good quality, while fricatives (e.g. + s,f sounds) can be coded adequately with less bits. + For this reason, VBR can achieve lower bit-rate for the same quality, or + a better quality for a certain bit-rate. + Despite its advantages, VBR has two main drawbacks: first, by only specifying + quality, there's no guaranty about the final average bit-rate. + Second, for some real-time applications like voice over IP (VoIP), what + counts is the maximum bit-rate, which must be low enough for the communication + channel. +\end_layout + +\begin_layout Subsection* +Average Bit-Rate +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +average bit-rate +\end_layout + +\end_inset + + (ABR) +\end_layout + +\begin_layout Standard +Average bit-rate solves one of the problems of VBR, as it dynamically adjusts + VBR quality in order to meet a specific target bit-rate. + Because the quality/bit-rate is adjusted in real-time (open-loop), the + global quality will be slightly lower than that obtained by encoding in + VBR with exactly the right quality setting to meet the target average bit-rate. +\end_layout + +\begin_layout Subsection* +Voice Activity Detection +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +voice activity detection +\end_layout + +\end_inset + + (VAD) +\end_layout + +\begin_layout Standard +When enabled, voice activity detection detects whether the audio being encoded + is speech or silence/background noise. + VAD is always implicitly activated when encoding in VBR, so the option + is only useful in non-VBR operation. + In this case, Speex detects non-speech periods and encode them with just + enough bits to reproduce the background noise. + This is called +\begin_inset Quotes eld +\end_inset + +comfort noise generation +\begin_inset Quotes erd +\end_inset + + (CNG). +\end_layout + +\begin_layout Subsection* +Discontinuous Transmission +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +discontinuous transmission +\end_layout + +\end_inset + + (DTX) +\end_layout + +\begin_layout Standard +Discontinuous transmission is an addition to VAD/VBR operation, that allows + to stop transmitting completely when the background noise is stationary. + In file-based operation, since we cannot just stop writing to the file, + only 5 bits are used for such frames (corresponding to 250 bps). +\end_layout + +\begin_layout Subsection* +Perceptual enhancement +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +perceptual enhancement +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Perceptual enhancement is a part of the decoder which, when turned on, attempts + to reduce the perception of the noise/distortion produced by the encoding/decod +ing process. + In most cases, perceptual enhancement brings the sound further from the + original +\emph on +objectively +\emph default + (e.g. + considering only SNR), but in the end it still +\emph on +sounds +\emph default + better (subjective improvement). +\end_layout + +\begin_layout Subsection* +Latency and algorithmic delay +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +algorithmic delay +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Every speech codec introduces a delay in the transmission. + For Speex, this delay is equal to the frame size, plus some amount of +\begin_inset Quotes eld +\end_inset + +look-ahead +\begin_inset Quotes erd +\end_inset + + required to process each frame. + In narrowband operation (8 kHz), the look-ahead is 10 ms, in wideband operation + (16 kHz), the look-ahead is 13.9 ms and in ultra-wideband operation (32 + kHz) look-ahead is 15.9 ms, resulting in the algorithic delays of 30 ms, + 33.9 ms and 35.9 ms accordingly. + These values don't account for the CPU time it takes to encode or decode + the frames. +\end_layout + +\begin_layout Section +Codec +\end_layout + +\begin_layout Standard +The main characteristics of Speex can be summarized as follows: +\end_layout + +\begin_layout Itemize +Free software/open-source +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +open-source +\end_layout + +\end_inset + +, patent +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +patent +\end_layout + +\end_inset + + and royalty-free +\end_layout + +\begin_layout Itemize +Integration of narrowband +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +narrowband +\end_layout + +\end_inset + + and wideband +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +wideband +\end_layout + +\end_inset + + using an embedded bit-stream +\end_layout + +\begin_layout Itemize +Wide range of bit-rates available (from 2.15 kbps to 44 kbps) +\end_layout + +\begin_layout Itemize +Dynamic bit-rate switching (AMR) and Variable Bit-Rate +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +variable bit-rate +\end_layout + +\end_inset + + (VBR) operation +\end_layout + +\begin_layout Itemize +Voice Activity Detection +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +voice activity detection +\end_layout + +\end_inset + + (VAD, integrated with VBR) and discontinuous transmission (DTX) +\end_layout + +\begin_layout Itemize +Variable complexity +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +complexity +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Itemize +Embedded wideband structure (scalable sampling rate) +\end_layout + +\begin_layout Itemize +Ultra-wideband sampling rate at 32 kHz +\end_layout + +\begin_layout Itemize +Intensity stereo encoding option +\end_layout + +\begin_layout Itemize +Fixed-point implementation +\end_layout + +\begin_layout Section +Preprocessor +\end_layout + +\begin_layout Standard +This part refers to the preprocessor module introduced in the 1.1.x branch. + The preprocessor is designed to be used on the audio +\emph on +before +\emph default + running the encoder. + The preprocessor provides three main functionalities: +\end_layout + +\begin_layout Itemize +noise suppression +\end_layout + +\begin_layout Itemize +automatic gain control (AGC) +\end_layout + +\begin_layout Itemize +voice activity detection (VAD) +\end_layout + +\begin_layout Standard +The denoiser can be used to reduce the amount of background noise present + in the input signal. + This provides higher quality speech whether or not the denoised signal + is encoded with Speex (or at all). + However, when using the denoised signal with the codec, there is an additional + benefit. + Speech codecs in general (Speex included) tend to perform poorly on noisy + input, which tends to amplify the noise. + The denoiser greatly reduces this effect. +\end_layout + +\begin_layout Standard +Automatic gain control (AGC) is a feature that deals with the fact that + the recording volume may vary by a large amount between different setups. + The AGC provides a way to adjust a signal to a reference volume. + This is useful for voice over IP because it removes the need for manual + adjustment of the microphone gain. + A secondary advantage is that by setting the microphone gain to a conservative + (low) level, it is easier to avoid clipping. +\end_layout + +\begin_layout Standard +The voice activity detector (VAD) provided by the preprocessor is more advanced + than the one directly provided in the codec. + +\end_layout + +\begin_layout Section +Adaptive Jitter Buffer +\end_layout + +\begin_layout Standard +When transmitting voice (or any content for that matter) over UDP or RTP, + packet may be lost, arrive with different delay, or even out of order. + The purpose of a jitter buffer is to reorder packets and buffer them long + enough (but no longer than necessary) so they can be sent to be decoded. + +\end_layout + +\begin_layout Section +Acoustic Echo Canceller +\end_layout + +\begin_layout Standard +In any hands-free communication system (Fig. + +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:Acoustic-echo-model" + +\end_inset + +), speech from the remote end is played in the local loudspeaker, propagates + in the room and is captured by the microphone. + If the audio captured from the microphone is sent directly to the remote + end, then the remote user hears an echo of his voice. + An acoustic echo canceller is designed to remove the acoustic echo before + it is sent to the remote end. + It is important to understand that the echo canceller is meant to improve + the quality on the +\series bold +remote +\series default + end. + For those who care a lot about mouth-to-ear delays it should be noted that + unlike Speex codec, resampler and preprocessor, this Acoustic Echo Canceller + does not introduce any latency. +\end_layout + +\begin_layout Standard +\begin_inset Float figure +wide false +sideways false +status open + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{center} +\end_layout + +\end_inset + + +\begin_inset Graphics + filename echo_path.eps + width 10cm + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +end{center} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +Acoustic echo model +\begin_inset CommandInset label +LatexCommand label +name "fig:Acoustic-echo-model" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +Resampler +\end_layout + +\begin_layout Standard +In some cases, it may be useful to convert audio from one sampling rate + to another. + There are many reasons for that. + It can be for mixing streams that have different sampling rates, for supporting + sampling rates that the soundcard doesn't support, for transcoding, etc. + That's why there is now a resampler that is part of the Speex project. + This resampler can be used to convert between any two arbitrary rates (the + ratio must only be a rational number) and there is control over the quality/com +plexity tradeoff. + Keep in mind, that resampler introduce some delay in audio stream, which + size depends on resampler quality setting. + Refer to resampler API documentation to know how to get exact delay values. +\end_layout + +\begin_layout Section +Integration +\end_layout + +\begin_layout Standard +Knowing +\emph on +how +\emph default + to use each of the components is not that useful unless we know +\emph on +where +\emph default + to use them. + Figure +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:Integration-VoIP" + +\end_inset + + shows where each of the components would be used in a typical VoIP client. + Components in dotted lines are optional, though they may be very useful + in some circumstances. + There are several important things to note from there. + The AEC must be placed as close as possible to the playback and capture. + Only the resampling may be closer. + Also, it is very important to use the same clock for both mic capture and + speaker/headphones playback. +\end_layout + +\begin_layout Standard +\begin_inset Float figure +wide false +sideways false +status open + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{center} +\end_layout + +\end_inset + + +\begin_inset Graphics + filename components.eps + width 80text% + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +end{center} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +Integration of all the components in a VoIP client. +\begin_inset CommandInset label +LatexCommand label +name "fig:Integration-VoIP" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +Compiling and Porting +\end_layout + +\begin_layout Standard +Compiling Speex under UNIX/Linux or any other platform supported by autoconf + (e.g. + Win32/cygwin) is as easy as typing: +\end_layout + +\begin_layout LyX-Code +% ./configure [options] +\end_layout + +\begin_layout LyX-Code +% make +\end_layout + +\begin_layout LyX-Code +% make install +\end_layout + +\begin_layout Standard +The options supported by the Speex configure script are: +\end_layout + +\begin_layout Description +--prefix=<path> Specifies the base path for installing Speex (e.g. + /usr) +\end_layout + +\begin_layout Description +--enable-shared/--disable-shared Whether to compile shared libraries +\end_layout + +\begin_layout Description +--enable-static/--disable-static Whether to compile static libraries +\end_layout + +\begin_layout Description +--disable-wideband Disable the wideband part of Speex (typically to save + space) +\end_layout + +\begin_layout Description +--enable-valgrind Enable extra hits for valgrind for debugging purposes + (do not use by default) +\end_layout + +\begin_layout Description +--enable-sse Enable use of SSE instructions (x86/float only) +\end_layout + +\begin_layout Description +--enable-fixed-point +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +fixed-point +\end_layout + +\end_inset + + Compile Speex for a processor that does not have a floating point unit + (FPU) +\end_layout + +\begin_layout Description +--enable-arm4-asm Enable assembly specific to the ARMv4 architecture (gcc + only) +\end_layout + +\begin_layout Description +--enable-arm5e-asm Enable assembly specific to the ARMv5E architecture (gcc + only) +\end_layout + +\begin_layout Description +--enable-fixed-point-debug Use only for debugging the fixed-point +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +fixed-point +\end_layout + +\end_inset + + code (very slow) +\end_layout + +\begin_layout Description +--enable-ti-c55x Enable support for the TI C5x family +\end_layout + +\begin_layout Description +--enable-blackfin-asm Enable assembly specific to the Blackfin DSP architecture + (gcc only) +\end_layout + +\begin_layout Section +Platforms +\end_layout + +\begin_layout Standard +Speex is known to compile and work on a large number of architectures, both + floating-point and fixed-point. + In general, any architecture that can natively compute the multiplication + of two signed 16-bit numbers (32-bit result) and runs at a sufficient clock + rate (architecture-dependent) is capable of running Speex. + Architectures on which Speex is +\series bold +known +\series default + to work (it probably works on many others) are: +\end_layout + +\begin_layout Itemize +x86 & x86-64 +\end_layout + +\begin_layout Itemize +Power +\end_layout + +\begin_layout Itemize +SPARC +\end_layout + +\begin_layout Itemize +ARM +\end_layout + +\begin_layout Itemize +Blackfin +\end_layout + +\begin_layout Itemize +Coldfire (68k family) +\end_layout + +\begin_layout Itemize +TI C54xx & C55xx +\end_layout + +\begin_layout Itemize +TI C6xxx +\end_layout + +\begin_layout Itemize +TriMedia (experimental) +\end_layout + +\begin_layout Standard +Operating systems on top of which Speex is known to work include (it probably + works on many others): +\end_layout + +\begin_layout Itemize +Linux +\end_layout + +\begin_layout Itemize +\begin_inset Formula $\mu$ +\end_inset + +Clinux +\end_layout + +\begin_layout Itemize +MacOS X +\end_layout + +\begin_layout Itemize +BSD +\end_layout + +\begin_layout Itemize +Other UNIX/POSIX variants +\end_layout + +\begin_layout Itemize +Symbian +\end_layout + +\begin_layout Standard +The source code directory include additional information for compiling on + certain architectures or operating systems in README.xxx files. +\end_layout + +\begin_layout Section +Porting and Optimising +\end_layout + +\begin_layout Standard +Here are a few things to consider when porting or optimising Speex for a + new platform or an existing one. +\end_layout + +\begin_layout Subsection +CPU optimisation +\end_layout + +\begin_layout Standard +The single factor that will affect the CPU usage of Speex the most is whether + it is compiled for floating point or fixed-point. + If your CPU/DSP does not have a floating-point unit FPU, then compiling + as fixed-point will be orders of magnitudes faster. + If there is an FPU present, then it is important to test which version + is faster. + On the x86 architecture, floating-point is +\series bold +generally +\series default + faster, but not always. + To compile Speex as fixed-point, you need to pass --fixed-point to the + configure script or define the FIXED_POINT macro for the compiler. + As of 1.2beta3, it is now possible to disable the floating-point compatibility + API, which means that your code can link without a float emulation library. + To do that configure with --disable-float-api or define the DISABLE_FLOAT_API + macro. + Until the VBR feature is ported to fixed-point, you will also need to configure + with --disable-vbr or define DISABLE_VBR. +\end_layout + +\begin_layout Standard +Other important things to check on some DSP architectures are: +\end_layout + +\begin_layout Itemize +Make sure the cache is set to write-back mode +\end_layout + +\begin_layout Itemize +If the chip has SRAM instead of cache, make sure as much code and data are + in SRAM, rather than in RAM +\end_layout + +\begin_layout Standard +If you are going to be writing assembly, then the following functions are + +\series bold +usually +\series default + the first ones you should consider optimising: +\end_layout + +\begin_layout Itemize +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +filter_mem16() +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Itemize +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +iir_mem16() +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Itemize +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +vq_nbest() +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Itemize +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +pitch_xcorr() +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Itemize +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +interp_pitch() +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The filtering functions +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +filter_mem16() +\end_layout + +\end_inset + + and +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +iir_mem16() +\end_layout + +\end_inset + + are implemented in the direct form II transposed (DF2T). + However, for architectures based on multiply-accumulate (MAC), DF2T requires + frequent reload of the accumulator, which can make the code very slow. + For these architectures (e.g. + Blackfin and Coldfire), a better approach is to implement those functions + as direct form I (DF1), which is easier to express in terms of MAC. + When doing that however, +\series bold +it is important to make sure that the DF1 implementation still behaves like + the original DF2T behaviour when it comes to memory values +\series default +. + This is necessary because the filter is time-varying and must compute exactly + the same value (not counting machine rounding) on any encoder or decoder. +\end_layout + +\begin_layout Subsection +Memory optimisation +\end_layout + +\begin_layout Standard +Memory optimisation is mainly something that should be considered for small + embedded platforms. + For PCs, Speex is already so tiny that it's just not worth doing any of + the things suggested here. + There are several ways to reduce the memory usage of Speex, both in terms + of code size and data size. + For optimising code size, the trick is to first remove features you do + not need. + Some examples of things that can easily be disabled +\series bold +if you don't need them +\series default + are: +\end_layout + +\begin_layout Itemize +Wideband support (--disable-wideband) +\end_layout + +\begin_layout Itemize +Support for stereo (removing stereo.c) +\end_layout + +\begin_layout Itemize +VBR support (--disable-vbr or DISABLE_VBR) +\end_layout + +\begin_layout Itemize +Static codebooks that are not needed for the bit-rates you are using (*_table.c + files) +\end_layout + +\begin_layout Standard +Speex also has several methods for allocating temporary arrays. + When using a compiler that supports C99 properly (as of 2007, Microsoft + compilers don't, but gcc does), it is best to define VAR_ARRAYS. + That makes use of the variable-size array feature of C99. + The next best is to define USE_ALLOCA so that Speex can use alloca() to + allocate the temporary arrays. + Note that on many systems, alloca() is buggy so it may not work. + If none of VAR_ARRAYS and USE_ALLOCA are defined, then Speex falls back + to allocating a large +\begin_inset Quotes eld +\end_inset + +scratch space +\begin_inset Quotes erd +\end_inset + + and doing its own internal allocation. + The main disadvantage of this solution is that it is wasteful. + It needs to allocate enough stack for the worst case scenario (worst bit-rate, + highest complexity setting, ...) and by default, the memory isn't shared between + multiple encoder/decoder states. + Still, if the +\begin_inset Quotes eld +\end_inset + +manual +\begin_inset Quotes erd +\end_inset + + allocation is the only option left, there are a few things that can be + improved. + By overriding the speex_alloc_scratch() call in os_support.h, it is possible + to always return the same memory area for all states +\begin_inset Foot +status collapsed + +\begin_layout Plain Layout +In this case, one must be careful with threads +\end_layout + +\end_inset + +. + In addition to that, by redefining the NB_ENC_STACK and NB_DEC_STACK (or + similar for wideband), it is possible to only allocate memory for a scenario + that is known in advance. + In this case, it is important to measure the amount of memory required + for the specific sampling rate, bit-rate and complexity level being used. +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +Command-line encoder/decoder +\begin_inset CommandInset label +LatexCommand label +name "sec:Command-line-encoder/decoder" + +\end_inset + + +\end_layout + +\begin_layout Standard +The base Speex distribution includes a command-line encoder ( +\emph on +speexenc +\emph default +) and decoder ( +\emph on +speexdec +\emph default +). + Those tools produce and read Speex files encapsulated in the Ogg container. + Although it is possible to encapsulate Speex in any container, Ogg is the + recommended container for files. + This section describes how to use the command line tools for Speex files + in Ogg. +\end_layout + +\begin_layout Section + +\emph on +speexenc +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +speexenc +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The +\emph on +speexenc +\emph default + utility is used to create Speex files from raw PCM or wave files. + It can be used by calling: +\end_layout + +\begin_layout LyX-Code +speexenc [options] input_file output_file +\end_layout + +\begin_layout Standard +The value '-' for input_file or output_file corresponds respectively to + stdin and stdout. + The valid options are: +\end_layout + +\begin_layout Description +--narrowband +\begin_inset space ~ +\end_inset + +(-n) Tell Speex to treat the input as narrowband (8 kHz). + This is the default +\end_layout + +\begin_layout Description +--wideband +\begin_inset space ~ +\end_inset + +(-w) Tell Speex to treat the input as wideband (16 kHz) +\end_layout + +\begin_layout Description +--ultra-wideband +\begin_inset space ~ +\end_inset + +(-u) Tell Speex to treat the input as +\begin_inset Quotes eld +\end_inset + +ultra-wideband +\begin_inset Quotes erd +\end_inset + + (32 kHz) +\end_layout + +\begin_layout Description +--quality +\begin_inset space ~ +\end_inset + +n Set the encoding quality (0-10), default is 8 +\end_layout + +\begin_layout Description +--bitrate +\begin_inset space ~ +\end_inset + +n Encoding bit-rate (use bit-rate n or lower) +\end_layout + +\begin_layout Description +--vbr Enable VBR (Variable Bit-Rate), disabled by default +\end_layout + +\begin_layout Description +--abr +\begin_inset space ~ +\end_inset + +n Enable ABR (Average Bit-Rate) at n kbps, disabled by default +\end_layout + +\begin_layout Description +--vad Enable VAD (Voice Activity Detection), disabled by default +\end_layout + +\begin_layout Description +--dtx Enable DTX (Discontinuous Transmission), disabled by default +\end_layout + +\begin_layout Description +--nframes +\begin_inset space ~ +\end_inset + +n Pack n frames in each Ogg packet (this saves space at low bit-rates) +\end_layout + +\begin_layout Description +--comp +\begin_inset space ~ +\end_inset + +n Set encoding speed/quality tradeoff. + The higher the value of n, the slower the encoding (default is 3) +\end_layout + +\begin_layout Description +-V Verbose operation, print bit-rate currently in use +\end_layout + +\begin_layout Description +--help +\begin_inset space ~ +\end_inset + +(-h) Print the help +\end_layout + +\begin_layout Description +--version +\begin_inset space ~ +\end_inset + +(-v) Print version information +\end_layout + +\begin_layout Subsection* +Speex comments +\end_layout + +\begin_layout Description +--comment Add the given string as an extra comment. + This may be used multiple times. + +\end_layout + +\begin_layout Description +--author Author of this track. + +\end_layout + +\begin_layout Description +--title Title for this track. + +\end_layout + +\begin_layout Subsection* +Raw input options +\end_layout + +\begin_layout Description +--rate +\begin_inset space ~ +\end_inset + +n Sampling rate for raw input +\end_layout + +\begin_layout Description +--stereo Consider raw input as stereo +\end_layout + +\begin_layout Description +--le Raw input is little-endian +\end_layout + +\begin_layout Description +--be Raw input is big-endian +\end_layout + +\begin_layout Description +--8bit Raw input is 8-bit unsigned +\end_layout + +\begin_layout Description +--16bit Raw input is 16-bit signed +\end_layout + +\begin_layout Section + +\emph on +speexdec +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +speexdec +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The +\emph on +speexdec +\emph default + utility is used to decode Speex files and can be used by calling: +\end_layout + +\begin_layout LyX-Code +speexdec [options] speex_file [output_file] +\end_layout + +\begin_layout Standard +The value '-' for input_file or output_file corresponds respectively to + stdin and stdout. + Also, when no output_file is specified, the file is played to the soundcard. + The valid options are: +\end_layout + +\begin_layout Description +--enh enable post-filter (default) +\end_layout + +\begin_layout Description +--no-enh disable post-filter +\end_layout + +\begin_layout Description +--force-nb Force decoding in narrowband +\end_layout + +\begin_layout Description +--force-wb Force decoding in wideband +\end_layout + +\begin_layout Description +--force-uwb Force decoding in ultra-wideband +\end_layout + +\begin_layout Description +--mono Force decoding in mono +\end_layout + +\begin_layout Description +--stereo Force decoding in stereo +\end_layout + +\begin_layout Description +--rate +\begin_inset space ~ +\end_inset + +n Force decoding at n Hz sampling rate +\end_layout + +\begin_layout Description +--packet-loss +\begin_inset space ~ +\end_inset + +n Simulate n % random packet loss +\end_layout + +\begin_layout Description +-V Verbose operation, print bit-rate currently in use +\end_layout + +\begin_layout Description +--help +\begin_inset space ~ +\end_inset + +(-h) Print the help +\end_layout + +\begin_layout Description +--version +\begin_inset space ~ +\end_inset + +(-v) Print version information +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +Using the Speex Codec API ( +\emph on +libspeex +\emph default + +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +libspeex +\end_layout + +\end_inset + +) +\begin_inset CommandInset label +LatexCommand label +name "sec:Programming-with-Speex" + +\end_inset + + +\end_layout + +\begin_layout Standard +The +\emph on +libspeex +\emph default + library contains all the functions for encoding and decoding speech with + the Speex codec. + When linking on a UNIX system, one must add +\emph on +-lspeex -lm +\emph default + to the compiler command line. + One important thing to know is that +\series bold +libspeex calls are reentrant, but not thread-safe +\series default +. + That means that it is fine to use calls from many threads, but +\series bold +calls using the same state from multiple threads must be protected by mutexes +\series default +. + Examples of code can also be found in Appendix +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Sample-code" + +\end_inset + + and the complete API documentation is included in the Documentation section + of the Speex website (http://www.speex.org/). +\end_layout + +\begin_layout Section +Encoding +\begin_inset CommandInset label +LatexCommand label +name "sub:Encoding" + +\end_inset + + +\end_layout + +\begin_layout Standard +In order to encode speech using Speex, one first needs to: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +#include <speex/speex.h> +\end_layout + +\end_inset + +Then in the code, a Speex bit-packing struct must be declared, along with + a Speex encoder state: +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +SpeexBits bits; +\end_layout + +\begin_layout Plain Layout + +void *enc_state; +\end_layout + +\end_inset + +The two are initialized by: +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_bits_init(&bits); +\end_layout + +\begin_layout Plain Layout + +enc_state = speex_encoder_init(&speex_nb_mode); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +For wideband coding, +\emph on +speex_nb_mode +\emph default + will be replaced by +\emph on +speex_wb_mode +\emph default +. + In most cases, you will need to know the frame size used at the sampling + rate you are using. + You can get that value in the +\emph on +frame_size +\emph default + variable (expressed in +\series bold +samples +\series default +, not bytes) with: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_encoder_ctl(enc_state,SPEEX_GET_FRAME_SIZE,&frame_size); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +In practice, +\emph on +frame_size +\emph default + will correspond to 20 ms when using 8, 16, or 32 kHz sampling rate. + There are many parameters that can be set for the Speex encoder, but the + most useful one is the quality parameter that controls the quality vs bit-rate + tradeoff. + This is set by: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_encoder_ctl(enc_state,SPEEX_SET_QUALITY,&quality); +\end_layout + +\end_inset + +where +\emph on +quality +\emph default + is an integer value ranging from 0 to 10 (inclusively). + The mapping between quality and bit-rate is described in Fig. + +\begin_inset CommandInset ref +LatexCommand ref +reference "cap:quality_vs_bps" + +\end_inset + + for narrowband. +\end_layout + +\begin_layout Standard +Once the initialization is done, for every input frame: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_bits_reset(&bits); +\end_layout + +\begin_layout Plain Layout + +speex_encode_int(enc_state, input_frame, &bits); +\end_layout + +\begin_layout Plain Layout + +nbBytes = speex_bits_write(&bits, byte_ptr, MAX_NB_BYTES); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +where +\emph on +input_frame +\emph default + is a +\emph on +( +\emph default +short +\emph on +*) +\emph default + pointing to the beginning of a speech frame, +\emph on +byte_ptr +\emph default + is a +\emph on +(char *) +\emph default + where the encoded frame will be written, +\emph on +MAX_NB_BYTES +\emph default + is the maximum number of bytes that can be written to +\emph on +byte_ptr +\emph default + without causing an overflow and +\emph on +nbBytes +\emph default + is the number of bytes actually written to +\emph on +byte_ptr +\emph default + (the encoded size in bytes). + Before calling speex_bits_write, it is possible to find the number of bytes + that need to be written by calling +\family typewriter +speex_bits_nbytes(&bits) +\family default +, which returns a number of bytes. +\end_layout + +\begin_layout Standard +It is still possible to use the +\emph on +speex_encode() +\emph default + function, which takes a +\emph on +(float *) +\emph default + for the audio. + However, this would make an eventual port to an FPU-less platform (like + ARM) more complicated. + Internally, +\emph on +speex_encode() +\emph default + and +\emph on +speex_encode_int() +\emph default + are processed in the same way. + Whether the encoder uses the fixed-point version is only decided by the + compile-time flags, not at the API level. +\end_layout + +\begin_layout Standard +After you're done with the encoding, free all resources with: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_bits_destroy(&bits); +\end_layout + +\begin_layout Plain Layout + +speex_encoder_destroy(enc_state); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +That's about it for the encoder. + +\end_layout + +\begin_layout Section +Decoding +\begin_inset CommandInset label +LatexCommand label +name "sub:Decoding" + +\end_inset + + +\end_layout + +\begin_layout Standard +In order to decode speech using Speex, you first need to: +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +#include <speex/speex.h> +\end_layout + +\end_inset + +You also need to declare a Speex bit-packing struct +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +SpeexBits bits; +\end_layout + +\end_inset + +and a Speex decoder state +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +void *dec_state; +\end_layout + +\end_inset + +The two are initialized by: +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_bits_init(&bits); +\end_layout + +\begin_layout Plain Layout + +dec_state = speex_decoder_init(&speex_nb_mode); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +For wideband decoding, +\emph on +speex_nb_mode +\emph default + will be replaced by +\emph on +speex_wb_mode +\emph default +. + If you need to obtain the size of the frames that will be used by the decoder, + you can get that value in the +\emph on +frame_size +\emph default + variable (expressed in +\series bold +samples +\series default +, not bytes) with: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &frame_size); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +There is also a parameter that can be set for the decoder: whether or not + to use a perceptual enhancer. + This can be set by: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_decoder_ctl(dec_state, SPEEX_SET_ENH, &enh); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +where +\emph on +enh +\emph default + is an int with value 0 to have the enhancer disabled and 1 to have it enabled. + As of 1.2-beta1, the default is now to enable the enhancer. +\end_layout + +\begin_layout Standard +Again, once the decoder initialization is done, for every input frame: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_bits_read_from(&bits, input_bytes, nbBytes); +\end_layout + +\begin_layout Plain Layout + +speex_decode_int(dec_state, &bits, output_frame); +\end_layout + +\end_inset + +where input_bytes is a +\emph on +(char *) +\emph default + containing the bit-stream data received for a frame, +\emph on +nbBytes +\emph default + is the size (in bytes) of that bit-stream, and +\emph on +output_frame +\emph default + is a +\emph on +(short *) +\emph default + and points to the area where the decoded speech frame will be written. + A NULL value as the second argument indicates that we don't have the bits + for the current frame. + When a frame is lost, the Speex decoder will do its best to "guess" the + correct signal. +\end_layout + +\begin_layout Standard +As for the encoder, the +\emph on +speex_decode() +\emph default + function can still be used, with a +\emph on +(float *) +\emph default + as the output for the audio. + After you're done with the decoding, free all resources with: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_bits_destroy(&bits); +\end_layout + +\begin_layout Plain Layout + +speex_decoder_destroy(dec_state); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +Codec Options (speex_*_ctl) +\begin_inset CommandInset label +LatexCommand label +name "sub:Codec-Options" + +\end_inset + + +\end_layout + +\begin_layout Quote +\align center + +\emph on +Entities should not be multiplied beyond necessity -- William of Ockham. +\end_layout + +\begin_layout Quote +\align center + +\emph on +Just because there's an option for it doesn't mean you have to turn it on + -- me. +\end_layout + +\begin_layout Standard +The Speex encoder and decoder support many options and requests that can + be accessed through the +\emph on +speex_encoder_ctl +\emph default + and +\emph on +speex_decoder_ctl +\emph default + functions. + These functions are similar to the +\emph on +ioctl +\emph default + system call and their prototypes are: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +void speex_encoder_ctl(void *encoder, int request, void *ptr); +\end_layout + +\begin_layout Plain Layout + +void speex_decoder_ctl(void *encoder, int request, void *ptr); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Despite those functions, the defaults are usually good for many applications + and +\series bold +optional settings should only be used when one understands them and knows + that they are needed +\series default +. + A common error is to attempt to set many unnecessary settings. + +\end_layout + +\begin_layout Standard +Here is a list of the values allowed for the requests. + Some only apply to the encoder or the decoder. + Because the last argument is of type +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +void * +\end_layout + +\end_inset + +, the +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +_ctl() +\end_layout + +\end_inset + + functions are +\series bold +not type safe +\series default +, and should thus be used with care. + The type +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + is the same as the C99 +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +int32_t +\end_layout + +\end_inset + + type. +\end_layout + +\begin_layout Description +SPEEX_SET_ENH +\begin_inset Formula $\ddagger$ +\end_inset + + Set perceptual enhancer +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +perceptual enhancement +\end_layout + +\end_inset + + to on (1) or off (0) ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +, default is on) +\end_layout + +\begin_layout Description +SPEEX_GET_ENH +\begin_inset Formula $\ddagger$ +\end_inset + + Get perceptual enhancer status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_GET_FRAME_SIZE Get the number of samples per frame for the current + mode ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_SET_QUALITY +\begin_inset Formula $\dagger$ +\end_inset + + Set the encoder speech quality ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + from 0 to 10, default is 8) +\end_layout + +\begin_layout Description +SPEEX_GET_QUALITY +\begin_inset Formula $\dagger$ +\end_inset + + Get the current encoder speech quality ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + from 0 to 10) +\end_layout + +\begin_layout Description +SPEEX_SET_MODE +\begin_inset Formula $\dagger$ +\end_inset + + Set the mode number, as specified in the RTP spec ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_GET_MODE +\begin_inset Formula $\dagger$ +\end_inset + + Get the current mode number, as specified in the RTP spec ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_SET_VBR +\begin_inset Formula $\dagger$ +\end_inset + + Set variable bit-rate (VBR) to on (1) or off (0) ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +, default is off) +\end_layout + +\begin_layout Description +SPEEX_GET_VBR +\begin_inset Formula $\dagger$ +\end_inset + + Get variable bit-rate +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +variable bit-rate +\end_layout + +\end_inset + + (VBR) status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_SET_VBR_QUALITY +\begin_inset Formula $\dagger$ +\end_inset + + Set the encoder VBR speech quality (float 0.0 to 10.0, default is 8.0) +\end_layout + +\begin_layout Description +SPEEX_GET_VBR_QUALITY +\begin_inset Formula $\dagger$ +\end_inset + + Get the current encoder VBR speech quality (float 0 to 10) +\end_layout + +\begin_layout Description +SPEEX_SET_COMPLEXITY +\begin_inset Formula $\dagger$ +\end_inset + + Set the CPU resources allowed for the encoder ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + from 1 to 10, default is 2) +\end_layout + +\begin_layout Description +SPEEX_GET_COMPLEXITY +\begin_inset Formula $\dagger$ +\end_inset + + Get the CPU resources allowed for the encoder ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + from 1 to 10, default is 2) +\end_layout + +\begin_layout Description +SPEEX_SET_BITRATE +\begin_inset Formula $\dagger$ +\end_inset + + Set the bit-rate to use the closest value not exceeding the parameter ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + in bits per second) +\end_layout + +\begin_layout Description +SPEEX_GET_BITRATE Get the current bit-rate in use ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + in bits per second) +\end_layout + +\begin_layout Description +SPEEX_SET_SAMPLING_RATE Set real sampling rate ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + in Hz) +\end_layout + +\begin_layout Description +SPEEX_GET_SAMPLING_RATE Get real sampling rate ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + in Hz) +\end_layout + +\begin_layout Description +SPEEX_RESET_STATE Reset the encoder/decoder state to its original state, + clearing all memories (no argument) +\end_layout + +\begin_layout Description +SPEEX_SET_VAD +\begin_inset Formula $\dagger$ +\end_inset + + Set voice activity detection +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +voice activity detection +\end_layout + +\end_inset + + (VAD) to on (1) or off (0) ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +, default is off) +\end_layout + +\begin_layout Description +SPEEX_GET_VAD +\begin_inset Formula $\dagger$ +\end_inset + + Get voice activity detection (VAD) status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_SET_DTX +\begin_inset Formula $\dagger$ +\end_inset + + Set discontinuous transmission +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +discontinuous transmission +\end_layout + +\end_inset + + (DTX) to on (1) or off (0) ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +, default is off) +\end_layout + +\begin_layout Description +SPEEX_GET_DTX +\begin_inset Formula $\dagger$ +\end_inset + + Get discontinuous transmission (DTX) status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_SET_ABR +\begin_inset Formula $\dagger$ +\end_inset + + Set average bit-rate +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +average bit-rate +\end_layout + +\end_inset + + (ABR) to a value n in bits per second ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + in bits per second) +\end_layout + +\begin_layout Description +SPEEX_GET_ABR +\begin_inset Formula $\dagger$ +\end_inset + + Get average bit-rate (ABR) setting ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + in bits per second) +\end_layout + +\begin_layout Description +SPEEX_SET_PLC_TUNING +\begin_inset Formula $\dagger$ +\end_inset + + Tell the encoder to optimize encoding for a certain percentage of packet + loss ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + in percent) +\end_layout + +\begin_layout Description +SPEEX_GET_PLC_TUNING +\begin_inset Formula $\dagger$ +\end_inset + + Get the current tuning of the encoder for PLC ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + in percent) +\end_layout + +\begin_layout Description +SPEEX_GET_LOOKAHEAD Returns the lookahead used by Speex separately for an + encoder and a decoder. + Sum encoder and decoder lookahead values to get the total codec lookahead. +\end_layout + +\begin_layout Description +SPEEX_SET_VBR_MAX_BITRATE +\begin_inset Formula $\dagger$ +\end_inset + + Set the maximum bit-rate allowed in VBR operation ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + in bits per second) +\end_layout + +\begin_layout Description +SPEEX_GET_VBR_MAX_BITRATE +\begin_inset Formula $\dagger$ +\end_inset + + Get the current maximum bit-rate allowed in VBR operation ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + + in bits per second) +\end_layout + +\begin_layout Description +SPEEX_SET_HIGHPASS Set the high-pass filter on (1) or off (0) ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +, default is on) +\end_layout + +\begin_layout Description +SPEEX_GET_HIGHPASS Get the current high-pass filter status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +\begin_inset Formula $\dagger$ +\end_inset + + applies only to the encoder +\end_layout + +\begin_layout Description +\begin_inset Formula $\ddagger$ +\end_inset + + applies only to the decoder +\end_layout + +\begin_layout Section +Mode queries +\begin_inset CommandInset label +LatexCommand label +name "sub:Mode-queries" + +\end_inset + + +\end_layout + +\begin_layout Standard +Speex modes have a query system similar to the speex_encoder_ctl and speex_decod +er_ctl calls. + Since modes are read-only, it is only possible to get information about + a particular mode. + The function used to do that is: +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +void speex_mode_query(SpeexMode *mode, int request, void *ptr); +\end_layout + +\end_inset + +The admissible values for request are (unless otherwise note, the values + are returned through +\emph on +ptr +\emph default +): +\end_layout + +\begin_layout Description +SPEEX_MODE_FRAME_SIZE Get the frame size (in samples) for the mode +\end_layout + +\begin_layout Description +SPEEX_SUBMODE_BITRATE Get the bit-rate for a submode number specified through + +\emph on +ptr +\emph default + (integer in bps). + +\end_layout + +\begin_layout Section +Packing and in-band signalling +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +in-band signalling +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Sometimes it is desirable to pack more than one frame per packet (or other + basic unit of storage). + The proper way to do it is to call speex_encode +\begin_inset Formula $N$ +\end_inset + + times before writing the stream with speex_bits_write. + In cases where the number of frames is not determined by an out-of-band + mechanism, it is possible to include a terminator code. + That terminator consists of the code 15 (decimal) encoded with 5 bits, + as shown in Table +\begin_inset CommandInset ref +LatexCommand ref +reference "cap:quality_vs_bps" + +\end_inset + +. + Note that as of version 1.0.2, calling speex_bits_write automatically inserts + the terminator so as to fill the last byte. + This doesn't involves any overhead and makes sure Speex can always detect + when there is no more frame in a packet. +\end_layout + +\begin_layout Standard +It is also possible to send in-band +\begin_inset Quotes eld +\end_inset + +messages +\begin_inset Quotes erd +\end_inset + + to the other side. + All these messages are encoded as +\begin_inset Quotes eld +\end_inset + +pseudo-frames +\begin_inset Quotes erd +\end_inset + + of mode 14 which contain a 4-bit message type code, followed by the message. + Table +\begin_inset CommandInset ref +LatexCommand ref +reference "cap:In-band-signalling-codes" + +\end_inset + + lists the available codes, their meaning and the size of the message that + follows. + Most of these messages are requests that are sent to the encoder or decoder + on the other end, which is free to comply or ignore them. + By default, all in-band messages are ignored. +\end_layout + +\begin_layout Standard +\begin_inset Float table +placement htbp +wide false +sideways false +status open + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{center} +\end_layout + +\end_inset + + +\begin_inset Tabular +<lyxtabular version="3" rows="17" columns="3"> +<features> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Code +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Size (bits) +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Content +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Asks decoder to set perceptual enhancement off (0) or on(1) +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Asks (if 1) the encoder to be less +\begin_inset Quotes eld +\end_inset + +aggressive +\begin_inset Quotes erd +\end_inset + + due to high packet loss +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +2 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Asks encoder to switch to mode N +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Asks encoder to switch to mode N for low-band +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Asks encoder to switch to mode N for high-band +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Asks encoder to switch to quality N for VBR +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +6 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Request acknowledge (0=no, 1=all, 2=only for in-band data) +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Asks encoder to set CBR (0), VAD(1), DTX(3), VBR(5), VBR+DTX(7) +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +8 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +8 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Transmit (8-bit) character to the other end +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +9 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +8 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Intensity stereo information +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +10 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +16 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Announce maximum bit-rate acceptable (N in bytes/second) +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +11 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +16 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +reserved +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +12 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +32 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Acknowledge receiving packet N +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +13 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +32 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +reserved +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +14 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +64 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +reserved +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +15 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +64 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +reserved +\end_layout + +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +end{center} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +In-band signalling codes +\begin_inset CommandInset label +LatexCommand label +name "cap:In-band-signalling-codes" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Finally, applications may define custom in-band messages using mode 13. + The size of the message in bytes is encoded with 5 bits, so that the decoder + can skip it if it doesn't know how to interpret it. +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +Speech Processing API ( +\emph on +libspeexdsp +\emph default +) +\end_layout + +\begin_layout Standard +As of version 1.2beta3, the non-codec parts of the Speex package are now + in a separate library called +\emph on +libspeexdsp +\emph default +. + This library includes the preprocessor, the acoustic echo canceller, the + jitter buffer, and the resampler. + In a UNIX environment, it can be linked into a program by adding +\emph on +-lspeexdsp -lm +\emph default + to the compiler command line. + Just like for libspeex, +\series bold +libspeexdsp calls are reentrant, but not thread-safe +\series default +. + That means that it is fine to use calls from many threads, but +\series bold +calls using the same state from multiple threads must be protected by mutexes +\series default +. +\end_layout + +\begin_layout Section +Preprocessor +\begin_inset CommandInset label +LatexCommand label +name "sub:Preprocessor" + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +In order to use the Speex preprocessor +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +preprocessor +\end_layout + +\end_inset + +, you first need to: +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +#include <speex/speex_preprocess.h> +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +Then, a preprocessor state can be created as: +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +SpeexPreprocessState *preprocess_state = speex_preprocess_state_init(frame_size, + sampling_rate); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +and it is recommended to use the same value for +\family typewriter +frame_size +\family default + as is used by the encoder (20 +\emph on +ms +\emph default +). +\end_layout + +\begin_layout Standard +For each input frame, you need to call: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_preprocess_run(preprocess_state, audio_frame); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +where +\family typewriter +audio_frame +\family default + is used both as input and output. + In cases where the output audio is not useful for a certain frame, it is + possible to use instead: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_preprocess_estimate_update(preprocess_state, audio_frame); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +This call will update all the preprocessor internal state variables without + computing the output audio, thus saving some CPU cycles. +\end_layout + +\begin_layout Standard +The behaviour of the preprocessor can be changed using: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_preprocess_ctl(preprocess_state, request, ptr); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\noindent +which is used in the same way as the encoder and decoder equivalent. + Options are listed in Section +\begin_inset CommandInset ref +LatexCommand ref +reference "sub:Preprocessor-options" + +\end_inset + +. +\end_layout + +\begin_layout Standard +The preprocessor state can be destroyed using: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_preprocess_state_destroy(preprocess_state); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +Preprocessor options +\begin_inset CommandInset label +LatexCommand label +name "sub:Preprocessor-options" + +\end_inset + + +\end_layout + +\begin_layout Standard +As with the codec, the preprocessor also has options that can be controlled + using an ioctl()-like call. + The available options are: +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_DENOISE Turns denoising on(1) or off(0) ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_DENOISE Get denoising status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_AGC Turns automatic gain control (AGC) on(1) or off(0) + ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_AGC Get AGC status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_VAD Turns voice activity detector (VAD) on(1) or off(0) + ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_VAD Get VAD status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_AGC_LEVEL +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_AGC_LEVEL +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_DEREVERB Turns reverberation removal on(1) or off(0) + ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_DEREVERB Get reverberation removal status ( +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_DEREVERB_LEVEL Not working yet, do not use +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_DEREVERB_LEVEL Not working yet, do not use +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_DEREVERB_DECAY Not working yet, do not use +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_DEREVERB_DECAY Not working yet, do not use +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_PROB_START +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_PROB_START +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_PROB_CONTINUE +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_PROB_CONTINUE +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_NOISE_SUPPRESS Set maximum attenuation of the noise + in dB (negative +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_NOISE_SUPPRESS Get maximum attenuation of the noise + in dB (negative +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_ECHO_SUPPRESS Set maximum attenuation of the residual + echo in dB (negative +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_ECHO_SUPPRESS Get maximum attenuation of the residual + echo in dB (negative +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE Set maximum attenuation of the + echo in dB when near end is active (negative +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE Get maximum attenuation of the + echo in dB when near end is active (negative +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +spx_int32_t +\end_layout + +\end_inset + +) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_SET_ECHO_STATE Set the associated echo canceller for residual + echo suppression (pointer or NULL for no residual echo suppression) +\end_layout + +\begin_layout Description +SPEEX_PREPROCESS_GET_ECHO_STATE Get the associated echo canceller (pointer) +\end_layout + +\begin_layout Section +Echo Cancellation +\begin_inset CommandInset label +LatexCommand label +name "sub:Echo-Cancellation" + +\end_inset + + +\end_layout + +\begin_layout Standard +The Speex library now includes an echo cancellation +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +echo cancellation +\end_layout + +\end_inset + + algorithm suitable for Acoustic Echo Cancellation +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +acoustic echo cancellation +\end_layout + +\end_inset + + (AEC). + In order to use the echo canceller, you first need to +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +#include <speex/speex_echo.h> +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Then, an echo canceller state can be created by: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +SpeexEchoState *echo_state = speex_echo_state_init(frame_size, filter_length); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +where +\family typewriter +frame_size +\family default + is the amount of data (in samples) you want to process at once and +\family typewriter +filter_length +\family default + is the length (in samples) of the echo cancelling filter you want to use + (also known as +\shape italic +tail length +\shape default + +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +tail length +\end_layout + +\end_inset + +). + It is recommended to use a frame size in the order of 20 ms (or equal to + the codec frame size) and make sure it is easy to perform an FFT of that + size (powers of two are better than prime sizes). + The recommended tail length is approximately the third of the room reverberatio +n time. + For example, in a small room, reverberation time is in the order of 300 + ms, so a tail length of 100 ms is a good choice (800 samples at 8000 Hz + sampling rate). +\end_layout + +\begin_layout Standard +Once the echo canceller state is created, audio can be processed by: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_echo_cancellation(echo_state, input_frame, echo_frame, output_frame); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +where +\family typewriter +input_frame +\family default + is the audio as captured by the microphone, +\family typewriter +echo_frame +\family default + is the signal that was played in the speaker (and needs to be removed) + and +\family typewriter +output_frame +\family default + is the signal with echo removed. + +\end_layout + +\begin_layout Standard +One important thing to keep in mind is the relationship between +\family typewriter +input_frame +\family default + and +\family typewriter +echo_frame +\family default +. + It is important that, at any time, any echo that is present in the input + has already been sent to the echo canceller as +\family typewriter +echo_frame +\family default +. + In other words, the echo canceller cannot remove a signal that it hasn't + yet received. + On the other hand, the delay between the input signal and the echo signal + must be small enough because otherwise part of the echo cancellation filter + is inefficient. + In the ideal case, you code would look like: +\begin_inset listings +lstparams "breaklines=true" +inline false +status open + +\begin_layout Plain Layout + +write_to_soundcard(echo_frame, frame_size); +\end_layout + +\begin_layout Plain Layout + +read_from_soundcard(input_frame, frame_size); +\end_layout + +\begin_layout Plain Layout + +speex_echo_cancellation(echo_state, input_frame, echo_frame, output_frame); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +If you wish to further reduce the echo present in the signal, you can do + so by associating the echo canceller to the preprocessor (see Section +\begin_inset CommandInset ref +LatexCommand ref +reference "sub:Preprocessor" + +\end_inset + +). + This is done by calling: +\begin_inset listings +lstparams "breaklines=true" +inline false +status open + +\begin_layout Plain Layout + +speex_preprocess_ctl(preprocess_state, SPEEX_PREPROCESS_SET_ECHO_STATE,echo_stat +e); +\end_layout + +\end_inset + +in the initialisation. +\end_layout + +\begin_layout Standard +As of version 1.2-beta2, there is an alternative, simpler API that can be + used instead of +\emph on +speex_echo_cancellation() +\emph default +. + When audio capture and playback are handled asynchronously (e.g. + in different threads or using the +\emph on +poll() +\emph default + or +\emph on +select() +\emph default + system call), it can be difficult to keep track of what input_frame comes + with what echo_frame. + Instead, the playback context/thread can simply call: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_echo_playback(echo_state, echo_frame); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +every time an audio frame is played. + Then, the capture context/thread calls: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_echo_capture(echo_state, input_frame, output_frame); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +for every frame captured. + Internally, +\emph on +speex_echo_playback() +\emph default + simply buffers the playback frame so it can be used by +\emph on +speex_echo_capture() +\emph default + to call +\emph on +speex_echo_cancel() +\emph default +. + A side effect of using this alternate API is that the playback audio is + delayed by two frames, which is the normal delay caused by the soundcard. + When capture and playback are already synchronised, +\emph on +speex_echo_cancellation() +\emph default + is preferable since it gives better control on the exact input/echo timing. +\end_layout + +\begin_layout Standard +The echo cancellation state can be destroyed with: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_echo_state_destroy(echo_state); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +It is also possible to reset the state of the echo canceller so it can be + reused without the need to create another state with: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +speex_echo_state_reset(echo_state); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +Troubleshooting +\end_layout + +\begin_layout Standard +There are several things that may prevent the echo canceller from working + properly. + One of them is a bug (or something suboptimal) in the code, but there are + many others you should consider first +\end_layout + +\begin_layout Itemize +Using a different soundcard to do the capture and plaback will +\series bold +not +\series default + work, regardless of what you may think. + The only exception to that is if the two cards can be made to have their + sampling clock +\begin_inset Quotes eld +\end_inset + +locked +\begin_inset Quotes erd +\end_inset + + on the same clock source. + If not, the clocks will always have a small amount of drift, which will + prevent the echo canceller from adapting. +\end_layout + +\begin_layout Itemize +The delay between the record and playback signals must be minimal. + Any signal played has to +\begin_inset Quotes eld +\end_inset + +appear +\begin_inset Quotes erd +\end_inset + + on the playback (far end) signal slightly before the echo canceller +\begin_inset Quotes eld +\end_inset + +sees +\begin_inset Quotes erd +\end_inset + + it in the near end signal, but excessive delay means that part of the filter + length is wasted. + In the worst situations, the delay is such that it is longer than the filter + length, in which case, no echo can be cancelled. +\end_layout + +\begin_layout Itemize +When it comes to echo tail length (filter length), longer is +\series bold +not +\series default + better. + Actually, the longer the tail length, the longer it takes for the filter + to adapt. + Of course, a tail length that is too short will not cancel enough echo, + but the most common problem seen is that people set a very long tail length + and then wonder why no echo is being cancelled. +\end_layout + +\begin_layout Itemize +Non-linear distortion cannot (by definition) be modeled by the linear adaptive + filter used in the echo canceller and thus cannot be cancelled. + Use good audio gear and avoid saturation/clipping. +\end_layout + +\begin_layout Standard +Also useful is reading +\emph on +Echo Cancellation Demystified +\emph default + by Alexey Frunze +\begin_inset Foot +status collapsed + +\begin_layout Plain Layout +http://www.embeddedstar.com/articles/2003/7/article20030720-1.html +\end_layout + +\end_inset + +, which explains the fundamental principles of echo cancellation. + The details of the algorithm described in the article are different, but + the general ideas of echo cancellation through adaptive filters are the + same. +\end_layout + +\begin_layout Standard +As of version 1.2beta2, a new +\family typewriter +echo_diagnostic.m +\family default + tool is included in the source distribution. + The first step is to define DUMP_ECHO_CANCEL_DATA during the build. + This causes the echo canceller to automatically save the near-end, far-end + and output signals to files (aec_rec.sw aec_play.sw and aec_out.sw). + These are exactly what the AEC receives and outputs. + From there, it is necessary to start Octave and type: +\end_layout + +\begin_layout Standard +\begin_inset listings +lstparams "language=Matlab" +inline false +status open + +\begin_layout Plain Layout + +echo_diagnostic('aec_rec.sw', 'aec_play.sw', 'aec_diagnostic.sw', 1024); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The value of 1024 is the filter length and can be changed. + There will be some (hopefully) useful messages printed and echo cancelled + audio will be saved to aec_diagnostic.sw . + If even that output is bad (almost no cancellation) then there is probably + problem with the playback or recording process. +\end_layout + +\begin_layout Section +Jitter Buffer +\end_layout + +\begin_layout Standard +The jitter buffer can be enabled by including: +\begin_inset listings +lstparams "breaklines=true" +inline false +status open + +\begin_layout Plain Layout + +#include <speex/speex_jitter.h> +\end_layout + +\end_inset + + and a new jitter buffer state can be initialised by: +\end_layout + +\begin_layout Standard +\begin_inset listings +lstparams "breaklines=true" +inline false +status open + +\begin_layout Plain Layout + +JitterBuffer *state = jitter_buffer_init(step); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +where the +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +step +\end_layout + +\end_inset + + argument is the default time step (in timestamp units) used for adjusting + the delay and doing concealment. + A value of 1 is always correct, but higher values may be more convenient + sometimes. + For example, if you are only able to do concealment on 20ms frames, there + is no point in the jitter buffer asking you to do it on one sample. + Another example is that for video, it makes no sense to adjust the delay + by less than a full frame. + The value provided can always be changed at a later time. +\end_layout + +\begin_layout Standard +The jitter buffer API is based on the +\begin_inset listings +inline true +status open + +\begin_layout Plain Layout + +JitterBufferPacket +\end_layout + +\end_inset + + type, which is defined as: +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +typedef struct { +\end_layout + +\begin_layout Plain Layout + + char *data; /* Data bytes contained in the packet */ +\end_layout + +\begin_layout Plain Layout + + spx_uint32_t len; /* Length of the packet in bytes */ +\end_layout + +\begin_layout Plain Layout + + spx_uint32_t timestamp; /* Timestamp for the packet */ +\end_layout + +\begin_layout Plain Layout + + spx_uint32_t span; /* Time covered by the packet (timestamp units) + */ +\end_layout + +\begin_layout Plain Layout + +} JitterBufferPacket; +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +As an example, for audio the timestamp field would be what is obtained from + the RTP timestamp field and the span would be the number of samples that + are encoded in the packet. + For Speex narrowband, span would be 160 if only one frame is included in + the packet. + +\end_layout + +\begin_layout Standard +When a packet arrives, it need to be inserter into the jitter buffer by: +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +JitterBufferPacket packet; +\end_layout + +\begin_layout Plain Layout + +/* Fill in each field in the packet struct */ +\end_layout + +\begin_layout Plain Layout + +jitter_buffer_put(state, &packet); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +When the decoder is ready to decode a packet the packet to be decoded can + be obtained by: +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +int start_offset; +\end_layout + +\begin_layout Plain Layout + +err = jitter_buffer_get(state, &packet, desired_span, &start_offset); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +If +\begin_inset listings +inline true +status open + +\begin_layout Plain Layout + +jitter_buffer_put() +\end_layout + +\end_inset + + and +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +jitter_buffer_get() +\end_layout + +\end_inset + + are called from different threads, then +\series bold +you need to protect the jitter buffer state with a mutex +\series default +. + +\end_layout + +\begin_layout Standard +Because the jitter buffer is designed not to use an explicit timer, it needs + to be told about the time explicitly. + This is done by calling: +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +jitter_buffer_tick(state); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +This needs to be done periodically in the playing thread. + This will be the last jitter buffer call before going to sleep (until more + data is played back). + In some cases, it may be preferable to use +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +jitter_buffer_remaining_span(state, remaining); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The second argument is used to specify that we are still holding data that + has not been written to the playback device. + For instance, if 256 samples were needed by the soundcard (specified by + +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +desired_span +\end_layout + +\end_inset + +), but +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +jitter_buffer_get() +\end_layout + +\end_inset + + returned 320 samples, we would have +\begin_inset listings +inline true +status open + +\begin_layout Plain Layout + +remaining=64 +\end_layout + +\end_inset + +. +\end_layout + +\begin_layout Section +Resampler +\end_layout + +\begin_layout Standard +Speex includes a resampling modules. + To make use of the resampler, it is necessary to include its header file: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +#include <speex/speex_resampler.h> +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +For each stream that is to be resampled, it is necessary to create a resampler + state with: +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +SpeexResamplerState *resampler; +\end_layout + +\begin_layout Plain Layout + +resampler = speex_resampler_init(nb_channels, input_rate, output_rate, quality, + &err); +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +where +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +nb_channels +\end_layout + +\end_inset + + is the number of channels that will be used (either interleaved or non-interlea +ved), +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +input_rate +\end_layout + +\end_inset + + is the sampling rate of the input stream, +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +output_rate +\end_layout + +\end_inset + + is the sampling rate of the output stream and +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +quality +\end_layout + +\end_inset + + is the requested quality setting (0 to 10). + The quality parameter is useful for controlling the quality/complexity/latency + tradeoff. + Using a higher quality setting means less noise/aliasing, a higher complexity + and a higher latency. + Usually, a quality of 3 is acceptable for most desktop uses and quality + 10 is mostly recommended for pro audio work. + Quality 0 usually has a decent sound (certainly better than using linear + interpolation resampling), but artifacts may be heard. +\end_layout + +\begin_layout Standard +The actual resampling is performed using +\end_layout + +\begin_layout Standard +\begin_inset listings +inline false +status open + +\begin_layout Plain Layout + +err = speex_resampler_process_int(resampler, channelID, in, &in_length, + out, &out_length); +\end_layout + +\end_inset + +where +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +channelID +\end_layout + +\end_inset + + is the ID of the channel to be processed. + For a mono stream, use 0. + The +\emph on +in +\emph default + pointer points to the first sample of the input buffer for the selected + channel and +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +out +\end_layout + +\end_inset + + points to the first sample of the output. + The size of the input and output buffers are specified by +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +in_length +\end_layout + +\end_inset + + and +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +out_length +\end_layout + +\end_inset + + respectively. + Upon completion, these values are replaced by the number of samples read + and written by the resampler. + Unless an error occurs, either all input samples will be read or all output + samples will be written to (or both). + For floating-point samples, the function +\begin_inset listings +inline true +status open + +\begin_layout Plain Layout + +speex_resampler_process_float() +\end_layout + +\end_inset + + behaves similarly. +\end_layout + +\begin_layout Standard +It is also possible to process multiple channels at once. + To do that, you can use speex_resampler_process_interleaved_int() or +\begin_inset listings +inline true +status open + +\begin_layout Plain Layout + +speex_resampler_process_interleaved_float() +\end_layout + +\end_inset + +. + The arguments are the same except that there is no +\begin_inset listings +inline true +status collapsed + +\begin_layout Plain Layout + +channelID +\end_layout + +\end_inset + + argument. + Note that the +\series bold +length parameters are per-channel +\series default +. + So if you have 1024 samples for each of 4 channels, you pass 1024 and not + 4096. +\end_layout + +\begin_layout Standard +The resampler allows changing the quality and input/output sampling frequencies + on the fly without glitches. + This can be done with calls such as +\begin_inset listings +inline true +status open + +\begin_layout Plain Layout + +speex_resampler_set_quality() +\end_layout + +\end_inset + + and +\begin_inset listings +inline true +status open + +\begin_layout Plain Layout + +speex_resampler_set_rate() +\end_layout + +\end_inset + +. + The only side effect is that a new filter will have to be recomputed, consuming + many CPU cycles. + +\end_layout + +\begin_layout Standard +When resampling a file, it is often desirable to have the output file perfectly + synchronised with the input. + To do that, you need to call +\begin_inset listings +inline true +status open + +\begin_layout Plain Layout + +speex_resampler_skip_zeros() +\end_layout + +\end_inset + + +\series bold +before +\series default + you start processing any samples. + For real-time applications (e.g. + VoIP), it is not recommended to do that as the first process frame will + be shorter to compensate for the delay (the skipped zeros). + Instead, in real-time applications you may want to know how many delay + is introduced by the resampler. + This can be done at run-time with +\begin_inset listings +inline true +status open + +\begin_layout Plain Layout + +speex_resampler_get_input_latency() +\end_layout + +\end_inset + + and +\begin_inset listings +inline true +status open + +\begin_layout Plain Layout + +speex_resampler_get_output_latency() +\end_layout + +\end_inset + + functions. + First function returns delay measured in samples at input samplerate, while + second returns delay measured in samples at output samplerate. +\end_layout + +\begin_layout Standard +To destroy a resampler state, just call +\begin_inset listings +inline true +status open + +\begin_layout Plain Layout + +speex_resampler_destroy() +\end_layout + +\end_inset + +. +\end_layout + +\begin_layout Section +Ring Buffer +\end_layout + +\begin_layout Standard +In some cases, it is necessary to interface components that use different + block sizes. + For example, it is possible that the soundcard does not support reading/writing + in blocks of 20 +\begin_inset space ~ +\end_inset + +ms or sometimes, complicated resampling ratios mean that the blocks don't + always have the same time. + In thoses cases, it is often necessary to buffer a bit of audio using a + ring buffer. +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +Formats and standards +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +standards +\end_layout + +\end_inset + + +\begin_inset CommandInset label +LatexCommand label +name "sec:Formats-and-standards" + +\end_inset + + +\end_layout + +\begin_layout Standard +Speex can encode speech in both narrowband and wideband and provides different + bit-rates. + However, not all features need to be supported by a certain implementation + or device. + In order to be called +\begin_inset Quotes eld +\end_inset + +Speex compatible +\begin_inset Quotes erd +\end_inset + + (whatever that means), an implementation must implement at least a basic + set of features. +\end_layout + +\begin_layout Standard +At the minimum, all narrowband modes of operation MUST be supported at the + decoder. + This includes the decoding of a wideband bit-stream by the narrowband decoder +\begin_inset Foot +status collapsed + +\begin_layout Plain Layout +The wideband bit-stream contains an embedded narrowband bit-stream which + can be decoded alone +\end_layout + +\end_inset + +. + If present, a wideband decoder MUST be able to decode a narrowband stream, + and MAY either be able to decode all wideband modes or be able to decode + the embedded narrowband part of all modes (which includes ignoring the + high-band bits). +\end_layout + +\begin_layout Standard +For encoders, at least one narrowband or wideband mode MUST be supported. + The main reason why all encoding modes do not have to be supported is that + some platforms may not be able to handle the complexity of encoding in + some modes. +\end_layout + +\begin_layout Section +RTP +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +RTP +\end_layout + +\end_inset + + Payload Format +\end_layout + +\begin_layout Standard +The RTP payload draft is included in appendix +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:IETF-draft" + +\end_inset + + and the latest version is available at +\begin_inset Flex URL +status collapsed + +\begin_layout Plain Layout + +http://www.speex.org/drafts/latest +\end_layout + +\end_inset + +. + This draft has been sent (2003/02/26) to the Internet Engineering Task + Force (IETF) and will be discussed at the March 18th meeting in San Francisco. + +\end_layout + +\begin_layout Section +MIME Type +\end_layout + +\begin_layout Standard +For now, you should use the MIME type audio/x-speex for Speex-in-Ogg. + We will apply for type +\family typewriter +audio/speex +\family default + in the near future. +\end_layout + +\begin_layout Section +Ogg +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +Ogg +\end_layout + +\end_inset + + file format +\end_layout + +\begin_layout Standard +Speex bit-streams can be stored in Ogg files. + In this case, the first packet of the Ogg file contains the Speex header + described in table +\begin_inset CommandInset ref +LatexCommand ref +reference "cap:ogg_speex_header" + +\end_inset + +. + All integer fields in the headers are stored as little-endian. + The +\family typewriter +speex_string +\family default + field must contain the +\begin_inset Quotes eld +\end_inset + + +\family typewriter +Speex +\family default + +\begin_inset space ~ +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset Quotes erd +\end_inset + + (with 3 trailing spaces), which identifies the bit-stream. + The next field, +\family typewriter +speex_version +\family default + contains the version of Speex that encoded the file. + For now, refer to speex_header.[ch] for more info. + The +\emph on +beginning of stream +\emph default + ( +\family typewriter +b_o_s +\family default +) flag is set to 1 for the header. + The header packet has +\family typewriter +packetno=0 +\family default + and +\family typewriter +granulepos=0 +\family default +. +\end_layout + +\begin_layout Standard +The second packet contains the Speex comment header. + The format used is the Vorbis comment format described here: http://www.xiph.org/ +ogg/vorbis/doc/v-comment.html . + This packet has +\family typewriter +packetno=1 +\family default + and +\family typewriter +granulepos=0 +\family default +. +\end_layout + +\begin_layout Standard +The third and subsequent packets each contain one or more (number found + in header) Speex frames. + These are identified with +\family typewriter +packetno +\family default + starting from 2 and the +\family typewriter +granulepos +\family default + is the number of the last sample encoded in that packet. + The last of these packets has the +\emph on +end of stream +\emph default + ( +\family typewriter +e_o_s +\family default +) flag is set to 1. +\end_layout + +\begin_layout Standard +\begin_inset Float table +placement htbp +wide true +sideways false +status open + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{center} +\end_layout + +\end_inset + + +\begin_inset Tabular +<lyxtabular version="3" rows="16" columns="3"> +<features> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Field +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Type +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Size +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +speex_string +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +char[] +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +8 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +speex_version +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +char[] +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +20 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +speex_version_id +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +header_size +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +rate +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +mode +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +mode_bitstream_version +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +nb_channels +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +bitrate +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frame_size +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +vbr +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frames_per_packet +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +extra_headers +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +reserved1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +reserved2 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +int +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +end{center} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +Ogg/Speex header packet +\begin_inset CommandInset label +LatexCommand label +name "cap:ogg_speex_header" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +clearpage +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Chapter +Introduction to CELP Coding +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +CELP +\end_layout + +\end_inset + + +\begin_inset CommandInset label +LatexCommand label +name "sec:Introduction-to-CELP" + +\end_inset + + +\end_layout + +\begin_layout Quote +\align center + +\emph on +Do not meddle in the affairs of poles, for they are subtle and quick to + leave the unit circle. +\end_layout + +\begin_layout Standard +Speex is based on CELP, which stands for Code Excited Linear Prediction. + This section attempts to introduce the principles behind CELP, so if you + are already familiar with CELP, you can safely skip to section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Speex-narrowband-mode" + +\end_inset + +. + The CELP technique is based on three ideas: +\end_layout + +\begin_layout Enumerate +The use of a linear prediction (LP) model to model the vocal tract +\end_layout + +\begin_layout Enumerate +The use of (adaptive and fixed) codebook entries as input (excitation) of + the LP model +\end_layout + +\begin_layout Enumerate +The search performed in closed-loop in a +\begin_inset Quotes eld +\end_inset + +perceptually weighted domain +\begin_inset Quotes erd +\end_inset + + +\end_layout + +\begin_layout Standard +This section describes the basic ideas behind CELP. + This is still a work in progress. +\end_layout + +\begin_layout Section +Source-Filter Model of Speech Prediction +\end_layout + +\begin_layout Standard +The source-filter model of speech production assumes that the vocal cords + are the source of spectrally flat sound (the excitation signal), and that + the vocal tract acts as a filter to spectrally shape the various sounds + of speech. + While still an approximation, the model is widely used in speech coding + because of its simplicity.Its use is also the reason why most speech codecs + (Speex included) perform badly on music signals. + The different phonemes can be distinguished by their excitation (source) + and spectral shape (filter). + Voiced sounds (e.g. + vowels) have an excitation signal that is periodic and that can be approximated + by an impulse train in the time domain or by regularly-spaced harmonics + in the frequency domain. + On the other hand, fricatives (such as the "s", "sh" and "f" sounds) have + an excitation signal that is similar to white Gaussian noise. + So called voice fricatives (such as "z" and "v") have excitation signal + composed of an harmonic part and a noisy part. +\end_layout + +\begin_layout Standard +The source-filter model is usually tied with the use of Linear prediction. + The CELP model is based on source-filter model, as can be seen from the + CELP decoder illustrated in Figure +\begin_inset CommandInset ref +LatexCommand ref +reference "fig:The-CELP-model" + +\end_inset + +. + +\end_layout + +\begin_layout Standard +\begin_inset Float figure +wide false +sideways false +status open + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{center} +\end_layout + +\end_inset + + +\begin_inset Graphics + filename celp_decoder.eps + width 45page% + keepAspectRatio + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +end{center} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +The CELP model of speech synthesis (decoder) +\begin_inset CommandInset label +LatexCommand label +name "fig:The-CELP-model" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +Linear Prediction Coefficients (LPC) +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +linear prediction +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Linear prediction is at the base of many speech coding techniques, including + CELP. + The idea behind it is to predict the signal +\begin_inset Formula $x[n]$ +\end_inset + + using a linear combination of its past samples: +\end_layout + +\begin_layout Standard +\begin_inset Formula \[ +y[n]=\sum_{i=1}^{N}a_{i}x[n-i]\] + +\end_inset + +where +\begin_inset Formula $y[n]$ +\end_inset + + is the linear prediction of +\begin_inset Formula $x[n]$ +\end_inset + +. + The prediction error is thus given by: +\begin_inset Formula \[ +e[n]=x[n]-y[n]=x[n]-\sum_{i=1}^{N}a_{i}x[n-i]\] + +\end_inset + + +\end_layout + +\begin_layout Standard +The goal of the LPC analysis is to find the best prediction coefficients + +\begin_inset Formula $a_{i}$ +\end_inset + + which minimize the quadratic error function: +\begin_inset Formula \[ +E=\sum_{n=0}^{L-1}\left[e[n]\right]^{2}=\sum_{n=0}^{L-1}\left[x[n]-\sum_{i=1}^{N}a_{i}x[n-i]\right]^{2}\] + +\end_inset + +That can be done by making all derivatives +\begin_inset Formula $\frac{\partial E}{\partial a_{i}}$ +\end_inset + + equal to zero: +\begin_inset Formula \[ +\frac{\partial E}{\partial a_{i}}=\frac{\partial}{\partial a_{i}}\sum_{n=0}^{L-1}\left[x[n]-\sum_{i=1}^{N}a_{i}x[n-i]\right]^{2}=0\] + +\end_inset + + +\end_layout + +\begin_layout Standard +For an order +\begin_inset Formula $N$ +\end_inset + + filter, the filter coefficients +\begin_inset Formula $a_{i}$ +\end_inset + + are found by solving the system +\begin_inset Formula $N\times N$ +\end_inset + + linear system +\begin_inset Formula $\mathbf{Ra}=\mathbf{r}$ +\end_inset + +, where +\begin_inset Formula \[ +\mathbf{R}=\left[\begin{array}{cccc} +R(0) & R(1) & \cdots & R(N-1)\\ +R(1) & R(0) & \cdots & R(N-2)\\ +\vdots & \vdots & \ddots & \vdots\\ +R(N-1) & R(N-2) & \cdots & R(0)\end{array}\right]\] + +\end_inset + + +\begin_inset Formula \[ +\mathbf{r}=\left[\begin{array}{c} +R(1)\\ +R(2)\\ +\vdots\\ +R(N)\end{array}\right]\] + +\end_inset + +with +\begin_inset Formula $R(m)$ +\end_inset + +, the auto-correlation +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +auto-correlation +\end_layout + +\end_inset + + of the signal +\begin_inset Formula $x[n]$ +\end_inset + +, computed as: +\end_layout + +\begin_layout Standard +\begin_inset Formula \[ +R(m)=\sum_{i=0}^{N-1}x[i]x[i-m]\] + +\end_inset + + +\end_layout + +\begin_layout Standard +Because +\begin_inset Formula $\mathbf{R}$ +\end_inset + + is Hermitian Toeplitz, the Levinson-Durbin +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +Levinson-Durbin +\end_layout + +\end_inset + + algorithm can be used, making the solution to the problem +\begin_inset Formula $\mathcal{O}\left(N^{2}\right)$ +\end_inset + + instead of +\begin_inset Formula $\mathcal{O}\left(N^{3}\right)$ +\end_inset + +. + Also, it can be proven that all the roots of +\begin_inset Formula $A(z)$ +\end_inset + + are within the unit circle, which means that +\begin_inset Formula $1/A(z)$ +\end_inset + + is always stable. + This is in theory; in practice because of finite precision, there are two + commonly used techniques to make sure we have a stable filter. + First, we multiply +\begin_inset Formula $R(0)$ +\end_inset + + by a number slightly above one (such as 1.0001), which is equivalent to + adding noise to the signal. + Also, we can apply a window to the auto-correlation, which is equivalent + to filtering in the frequency domain, reducing sharp resonances. +\end_layout + +\begin_layout Section +Pitch Prediction +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +pitch +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +During voiced segments, the speech signal is periodic, so it is possible + to take advantage of that property by approximating the excitation signal + +\begin_inset Formula $e[n]$ +\end_inset + + by a gain times the past of the excitation: +\end_layout + +\begin_layout Standard +\begin_inset Formula \[ +e[n]\simeq p[n]=\beta e[n-T]\ ,\] + +\end_inset + +where +\begin_inset Formula $T$ +\end_inset + + is the pitch period, +\begin_inset Formula $\beta$ +\end_inset + + is the pitch gain. + We call that long-term prediction since the excitation is predicted from + +\begin_inset Formula $e[n-T]$ +\end_inset + + with +\begin_inset Formula $T\gg N$ +\end_inset + +. +\end_layout + +\begin_layout Section +Innovation Codebook +\end_layout + +\begin_layout Standard +The final excitation +\begin_inset Formula $e[n]$ +\end_inset + + will be the sum of the pitch prediction and an +\emph on +innovation +\emph default + signal +\begin_inset Formula $c[n]$ +\end_inset + + taken from a fixed codebook, hence the name +\emph on +Code +\emph default + Excited Linear Prediction. + The final excitation is given by +\end_layout + +\begin_layout Standard +\begin_inset Formula \[ +e[n]=p[n]+c[n]=\beta e[n-T]+c[n]\ .\] + +\end_inset + +The quantization of +\begin_inset Formula $c[n]$ +\end_inset + + is where most of the bits in a CELP codec are allocated. + It represents the information that couldn't be obtained either from linear + prediction or pitch prediction. + In the +\emph on +z +\emph default +-domain we can represent the final signal +\begin_inset Formula $X(z)$ +\end_inset + + as +\begin_inset Formula \[ +X(z)=\frac{C(z)}{A(z)\left(1-\beta z^{-T}\right)}\] + +\end_inset + + +\end_layout + +\begin_layout Section +Noise Weighting +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +error weighting +\end_layout + +\end_inset + + +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +analysis-by-synthesis +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +Most (if not all) modern audio codecs attempt to +\begin_inset Quotes eld +\end_inset + +shape +\begin_inset Quotes erd +\end_inset + + the noise so that it appears mostly in the frequency regions where the + ear cannot detect it. + For example, the ear is more tolerant to noise in parts of the spectrum + that are louder and +\emph on +vice versa +\emph default +. + In order to maximize speech quality, CELP codecs minimize the mean square + of the error (noise) in the perceptually weighted domain. + This means that a perceptual noise weighting filter +\begin_inset Formula $W(z)$ +\end_inset + + is applied to the error signal in the encoder. + In most CELP codecs, +\begin_inset Formula $W(z)$ +\end_inset + + is a pole-zero weighting filter derived from the linear prediction coefficients + (LPC), generally using bandwidth expansion. + Let the spectral envelope be represented by the synthesis filter +\begin_inset Formula $1/A(z)$ +\end_inset + +, CELP codecs typically derive the noise weighting filter as +\begin_inset Formula \begin{equation} +W(z)=\frac{A(z/\gamma_{1})}{A(z/\gamma_{2})}\ ,\label{eq:gamma-weighting}\end{equation} + +\end_inset + +where +\begin_inset Formula $\gamma_{1}=0.9$ +\end_inset + + and +\begin_inset Formula $\gamma_{2}=0.6$ +\end_inset + + in the Speex reference implementation. + If a filter +\begin_inset Formula $A(z)$ +\end_inset + + has (complex) poles at +\begin_inset Formula $p_{i}$ +\end_inset + + in the +\begin_inset Formula $z$ +\end_inset + +-plane, the filter +\begin_inset Formula $A(z/\gamma)$ +\end_inset + + will have its poles at +\begin_inset Formula $p'_{i}=\gamma p_{i}$ +\end_inset + +, making it a flatter version of +\begin_inset Formula $A(z)$ +\end_inset + +. +\end_layout + +\begin_layout Standard +The weighting filter is applied to the error signal used to optimize the + codebook search through analysis-by-synthesis (AbS). + This results in a spectral shape of the noise that tends towards +\begin_inset Formula $1/W(z)$ +\end_inset + +. + While the simplicity of the model has been an important reason for the + success of CELP, it remains that +\begin_inset Formula $W(z)$ +\end_inset + + is a very rough approximation for the perceptually optimal noise weighting + function. + Fig. + +\begin_inset CommandInset ref +LatexCommand ref +reference "cap:Standard-noise-shaping" + +\end_inset + + illustrates the noise shaping that results from Eq. + +\begin_inset CommandInset ref +LatexCommand ref +reference "eq:gamma-weighting" + +\end_inset + +. + Throughout this paper, we refer to +\begin_inset Formula $W(z)$ +\end_inset + + as the noise weighting filter and to +\begin_inset Formula $1/W(z)$ +\end_inset + + as the noise shaping filter (or curve). +\end_layout + +\begin_layout Standard +\begin_inset Float figure +wide false +sideways false +status open + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{center} +\end_layout + +\end_inset + + +\begin_inset Graphics + filename ref_shaping.eps + width 45page% + keepAspectRatio + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +end{center} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +Standard noise shaping in CELP. + Arbitrary y-axis offset. +\begin_inset CommandInset label +LatexCommand label +name "cap:Standard-noise-shaping" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +Analysis-by-Synthesis +\end_layout + +\begin_layout Standard +One of the main principles behind CELP is called Analysis-by-Synthesis (AbS), + meaning that the encoding (analysis) is performed by perceptually optimising + the decoded (synthesis) signal in a closed loop. + In theory, the best CELP stream would be produced by trying all possible + bit combinations and selecting the one that produces the best-sounding + decoded signal. + This is obviously not possible in practice for two reasons: the required + complexity is beyond any currently available hardware and the +\begin_inset Quotes eld +\end_inset + +best sounding +\begin_inset Quotes erd +\end_inset + + selection criterion implies a human listener. + +\end_layout + +\begin_layout Standard +In order to achieve real-time encoding using limited computing resources, + the CELP optimisation is broken down into smaller, more manageable, sequential + searches using the perceptual weighting function described earlier. +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +The Speex Decoder Specification +\end_layout + +\begin_layout Section +Narrowband decoder +\end_layout + +\begin_layout Standard +<Insert decoder figure here> +\end_layout + +\begin_layout Subsection +Narrowband modes +\end_layout + +\begin_layout Standard +There are 7 different narrowband bit-rates defined for Speex, ranging from + 250 bps to 24.6 kbps, although the modes below 5.9 kbps should not be used + for speech. + The bit-allocation for each mode is detailed in table +\begin_inset CommandInset ref +LatexCommand ref +reference "cap:bits-narrowband" + +\end_inset + +. + Each frame starts with the mode ID encoded with 4 bits which allows a range + from 0 to 15, though only the first 7 values are used (the others are reserved). + The parameters are listed in the table in the order they are packed in + the bit-stream. + All frame-based parameters are packed before sub-frame parameters. + The parameters for a certain sub-frame are all packed before the following + sub-frame is packed. + The +\begin_inset Quotes eld +\end_inset + +OL +\begin_inset Quotes erd +\end_inset + + in the parameter description means that the parameter is an open loop estimatio +n based on the whole frame. +\end_layout + +\begin_layout Standard +\begin_inset Float table +placement h +wide true +sideways false +status open + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{center} +\end_layout + +\end_inset + + +\begin_inset Tabular +<lyxtabular version="3" rows="12" columns="11"> +<features> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Parameter +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Update rate +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +2 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +6 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +8 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Wideband bit +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Mode ID +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +LSP +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +18 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +18 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +18 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +18 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +30 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +30 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +30 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +18 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +OL pitch +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +OL pitch gain +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +OL Exc gain +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Fine pitch +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +sub-frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Pitch gain +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +sub-frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Innovation gain +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +sub-frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Innovation VQ +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +sub-frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +16 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +20 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +35 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +48 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +64 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +96 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +10 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Total +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +43 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +119 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +160 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +220 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +300 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +364 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +492 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +79 +\end_layout + +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +end{center} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +Bit allocation for narrowband modes +\begin_inset CommandInset label +LatexCommand label +name "cap:bits-narrowband" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Subsection +LSP decoding +\end_layout + +\begin_layout Standard +Depending on the mode, LSP parameters are encoded using either 18 bits or + 30 bits. +\end_layout + +\begin_layout Standard +Interpolation +\end_layout + +\begin_layout Standard +Safe margin +\end_layout + +\begin_layout Subsection +Adaptive codebook +\end_layout + +\begin_layout Standard +For rates of 8 kbit/s and above, the pitch period is encoded for each subframe. + The real period is +\begin_inset Formula $T=p_{i}+17$ +\end_inset + + where +\begin_inset Formula $p_{i}$ +\end_inset + + is a value encoded with 7 bits and 17 corresponds to the minimum pitch. + The maximum period is 144. + At 5.95 kbit/s (mode 2), the pitch period is similarly encoded, but only + once for the frame. + Each sub-frame then has a 2-bit offset that is added to the pitch value + of the frame. + In that case, the pitch for each sub-frame is equal to +\begin_inset Formula $T-1+offset$ +\end_inset + +. + For rates below 5.95 kbit/s, only the per-frame pitch is used and the pitch + is constant for all sub-frames. +\end_layout + +\begin_layout Standard +Speex uses a 3-tap predictor for rates of 5.95 kbit/s and above. + The three gain values are obtained from a 5-bit or a 7-bit codebook, depending + on the mode. + +\end_layout + +\begin_layout Subsection +Innovation codebook +\end_layout + +\begin_layout Standard +Split codebook, size and entries depend on bit-rate +\end_layout + +\begin_layout Standard +a 5-bit gain is encoder on a per-frame basis +\end_layout + +\begin_layout Standard +Depending on the mode, higher resolution per sub-frame +\end_layout + +\begin_layout Standard +innovation sub-vectors concatenated, gain applied +\end_layout + +\begin_layout Subsection +Perceptual enhancement +\end_layout + +\begin_layout Standard +Optional, implementation-defined. + +\end_layout + +\begin_layout Subsection +Bit-stream definition +\end_layout + +\begin_layout Standard +This section defines the bit-stream that is transmitted on the wire. + One speex packet consist of 1 frame header and 4 sub-frames: +\end_layout + +\begin_layout Standard +\begin_inset Tabular +<lyxtabular version="3" rows="1" columns="5"> +<features> +<column alignment="center" valignment="top" width="0"> +<column alignment="center" valignment="top" width="0"> +<column alignment="center" valignment="top" width="0"> +<column alignment="center" valignment="top" width="0"> +<column alignment="center" valignment="top" width="0"> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Frame Header +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Subframe 1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Subframe2 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Subframe 3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Subframe 4 +\end_layout + +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\end_layout + +\begin_layout Standard +The frame header is variable length, depending on decoding mode and submode. + The narrowband frame header is defined as follows: +\end_layout + +\begin_layout Standard +\begin_inset Tabular +<lyxtabular version="3" rows="1" columns="6"> +<features> +<column alignment="center" valignment="top" width="0"> +<column alignment="center" valignment="top" width="0"> +<column alignment="center" valignment="top" width="0"> +<column alignment="center" valignment="top" width="0"> +<column alignment="center" valignment="top" width="0"> +<column alignment="center" valignment="top" width="0"> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +wb bit +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +modeid +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +LSP +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +OL-pitch +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +OL-pitchgain +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +OL ExcGain +\end_layout + +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\end_layout + +\begin_layout Standard +wb-bit: Wideband bit (1 bit) 0=narrowband, 1=wideband +\end_layout + +\begin_layout Standard +modeid: Mode identifier (4 bits) +\end_layout + +\begin_layout Standard +LSP: Line Spectral Pairs (0, 18 or 30 bits) +\end_layout + +\begin_layout Standard +OL-pitch: Open Loop Pitch (0 or 7 bits) +\end_layout + +\begin_layout Standard +OL-pitchgain: Open Loop Pitch Gain (0 or 4 bits) +\end_layout + +\begin_layout Standard +OL-ExcGain: Open Loop Excitation Gain (0 or 5 bits) +\end_layout + +\begin_layout Standard +... +\end_layout + +\begin_layout Standard +Each subframe is defined as follows: +\end_layout + +\begin_layout Standard +\begin_inset Tabular +<lyxtabular version="3" rows="1" columns="4"> +<features> +<column alignment="center" valignment="top" width="0"> +<column alignment="center" valignment="top" width="0"> +<column alignment="center" valignment="top" width="0"> +<column alignment="center" valignment="top" width="0"> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +FinePitch +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +PitchGain +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +InnovationGain +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Innovation VQ +\end_layout + +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\end_layout + +\begin_layout Standard +FinePitch: (0 or 7 bits) +\end_layout + +\begin_layout Standard +PitchGain: (0, 5, or 7 bits) +\end_layout + +\begin_layout Standard +Innovation Gain: (0, 1, 3 bits) +\end_layout + +\begin_layout Standard +Innovation VQ: (0-96 bits) +\end_layout + +\begin_layout Standard +... +\end_layout + +\begin_layout Subsection +Sample decoder +\end_layout + +\begin_layout Standard +This section contains some sample source code, showing how a basic Speex + decoder can be implemented. + The sample decoder is narrowband submode 3 only, and with no advanced features + like enhancement, vbr etc. +\end_layout + +\begin_layout Standard +... +\end_layout + +\begin_layout Subsection +Lookup tables +\end_layout + +\begin_layout Standard +The Speex decoder includes a set of lookup tables and codebooks, which are + used to convert between values of different domains. + This includes: +\end_layout + +\begin_layout Standard +- Excitation 10x16 (3200 bps) +\end_layout + +\begin_layout Standard +- Excitation 10x32 (4000 bps) +\end_layout + +\begin_layout Standard +- Excitation 20x32 (2000 bps) +\end_layout + +\begin_layout Standard +- Excitation 5x256 (12800 bps) +\end_layout + +\begin_layout Standard +- Excitation 5x64 (9600 bps) +\end_layout + +\begin_layout Standard +- Excitation 8x128 (7000 bps) +\end_layout + +\begin_layout Standard +- Codebook for 3-tap pitch prediction gain (Normal and Low Bitrate) +\end_layout + +\begin_layout Standard +- Codebook for LSPs in narrowband CELP mode +\end_layout + +\begin_layout Standard +... +\end_layout + +\begin_layout Standard +The exact lookup tables are included here for reference. +\end_layout + +\begin_layout Section +Wideband embedded decoder +\end_layout + +\begin_layout Standard +QMF filter. + Narrowband signal decoded using narrowband decoder +\end_layout + +\begin_layout Standard +For the high band, the decoder is similar to the narrowband decoder, with + the main difference being that there is no adaptive codebook. +\end_layout + +\begin_layout Standard +Gain is per-subframe +\end_layout + +\begin_layout Chapter +Speex narrowband mode +\begin_inset CommandInset label +LatexCommand label +name "sec:Speex-narrowband-mode" + +\end_inset + + +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +narrowband +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +This section looks at how Speex works for narrowband ( +\begin_inset Formula $8\:\mathrm{kHz}$ +\end_inset + + sampling rate) operation. + The frame size for this mode is +\begin_inset Formula $20\:\mathrm{ms}$ +\end_inset + +, corresponding to 160 samples. + Each frame is also subdivided into 4 sub-frames of 40 samples each. +\end_layout + +\begin_layout Standard +Also many design decisions were based on the original goals and assumptions: +\end_layout + +\begin_layout Itemize +Minimizing the amount of information extracted from past frames (for robustness + to packet loss) +\end_layout + +\begin_layout Itemize +Dynamically-selectable codebooks (LSP, pitch and innovation) +\end_layout + +\begin_layout Itemize +sub-vector fixed (innovation) codebooks +\end_layout + +\begin_layout Section +Whole-Frame Analysis +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +linear prediction +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +In narrowband, Speex frames are 20 ms long (160 samples) and are subdivided + in 4 sub-frames of 5 ms each (40 samples). + For most narrowband bit-rates (8 kbps and above), the only parameters encoded + at the frame level are the Line Spectral Pairs (LSP) and a global excitation + gain +\begin_inset Formula $g_{frame}$ +\end_inset + +, as shown in Fig. + +\begin_inset CommandInset ref +LatexCommand ref +reference "cap:Frame-open-loop-analysis" + +\end_inset + +. + All other parameters are encoded at the sub-frame level. +\end_layout + +\begin_layout Standard +Linear prediction analysis is performed once per frame using an asymmetric + Hamming window centered on the fourth sub-frame. + Because linear prediction coefficients (LPC) are not robust to quantization, + they are first converted to line spectral pairs (LSP) +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +line spectral pair +\end_layout + +\end_inset + +. + The LSP's are considered to be associated to the +\begin_inset Formula $4^{th}$ +\end_inset + + sub-frames and the LSP's associated to the first 3 sub-frames are linearly + interpolated using the current and previous LSP coefficients. + The LSP coefficients and converted back to the LPC filter +\begin_inset Formula $\hat{A}(z)$ +\end_inset + +. + The non-quantized interpolated filter is denoted +\begin_inset Formula $A(z)$ +\end_inset + + and can be used for the weighting filter +\begin_inset Formula $W(z)$ +\end_inset + + because it does not need to be available to the decoder. + +\end_layout + +\begin_layout Standard +To make Speex more robust to packet loss, no prediction is applied on the + LSP coefficients prior to quantization. + The LSPs are encoded using vector quantization (VQ) with 30 bits for higher + quality modes and 18 bits for lower quality. +\end_layout + +\begin_layout Standard +\begin_inset Float figure +wide false +sideways false +status open + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{center} +\end_layout + +\end_inset + + +\begin_inset Graphics + filename speex_analysis.eps + width 35page% + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +end{center} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +Frame open-loop analysis +\begin_inset CommandInset label +LatexCommand label +name "cap:Frame-open-loop-analysis" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +Sub-Frame Analysis-by-Synthesis +\end_layout + +\begin_layout Standard +\begin_inset Float figure +wide false +sideways false +status open + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{center} +\end_layout + +\end_inset + + +\begin_inset Graphics + filename speex_abs.eps + lyxscale 75 + width 40page% + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +end{center} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +Analysis-by-synthesis closed-loop optimization on a sub-frame. +\begin_inset CommandInset label +LatexCommand label +name "cap:Sub-frame-AbS" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +The analysis-by-synthesis (AbS) encoder loop is described in Fig. + +\begin_inset CommandInset ref +LatexCommand ref +reference "cap:Sub-frame-AbS" + +\end_inset + +. + There are three main aspects where Speex significantly differs from most + other CELP codecs. + First, while most recent CELP codecs make use of fractional pitch estimation + with a single gain, Speex uses an integer to encode the pitch period, but + uses a 3-tap predictor (3 gains). + The adaptive codebook contribution +\begin_inset Formula $e_{a}[n]$ +\end_inset + + can thus be expressed as: +\begin_inset Formula \begin{equation} +e_{a}[n]=g_{0}e[n-T-1]+g_{1}e[n-T]+g_{2}e[n-T+1]\label{eq:adaptive-3tap}\end{equation} + +\end_inset + +where +\begin_inset Formula $g_{0}$ +\end_inset + +, +\begin_inset Formula $g_{1}$ +\end_inset + + and +\begin_inset Formula $g_{2}$ +\end_inset + + are the jointly quantized pitch gains and +\begin_inset Formula $e[n]$ +\end_inset + + is the codec excitation memory. + It is worth noting that when the pitch is smaller than the sub-frame size, + we repeat the excitation at a period +\begin_inset Formula $T$ +\end_inset + +. + For example, when +\begin_inset Formula $n-T+1\geq0$ +\end_inset + +, we use +\begin_inset Formula $n-2T+1$ +\end_inset + + instead. + In most modes, the pitch period is encoded with 7 bits in the +\begin_inset Formula $\left[17,144\right]$ +\end_inset + + range and the +\begin_inset Formula $\beta_{i}$ +\end_inset + + coefficients are vector-quantized using 7 bits at higher bit-rates (15 + kbps narrowband and above) and 5 bits at lower bit-rates (11 kbps narrowband + and below). +\end_layout + +\begin_layout Standard +Many current CELP codecs use moving average (MA) prediction to encode the + fixed codebook gain. + This provides slightly better coding at the expense of introducing a dependency + on previously encoded frames. + A second difference is that Speex encodes the fixed codebook gain as the + product of the global excitation gain +\begin_inset Formula $g_{frame}$ +\end_inset + + with a sub-frame gain corrections +\begin_inset Formula $g_{subf}$ +\end_inset + +. + This increases robustness to packet loss by eliminating the inter-frame + dependency. + The sub-frame gain correction is encoded before the fixed codebook is searched + (not closed-loop optimized) and uses between 0 and 3 bits per sub-frame, + depending on the bit-rate. +\end_layout + +\begin_layout Standard +The third difference is that Speex uses sub-vector quantization of the innovatio +n (fixed codebook) signal instead of an algebraic codebook. + Each sub-frame is divided into sub-vectors of lengths ranging between 5 + and 20 samples. + Each sub-vector is chosen from a bitrate-dependent codebook and all sub-vectors + are concatenated to form a sub-frame. + As an example, the 3.95 kbps mode uses a sub-vector size of 20 samples with + 32 entries in the codebook (5 bits). + This means that the innovation is encoded with 10 bits per sub-frame, or + 2000 bps. + On the other hand, the 18.2 kbps mode uses a sub-vector size of 5 samples + with 256 entries in the codebook (8 bits), so the innovation uses 64 bits + per sub-frame, or 12800 bps. + +\end_layout + +\begin_layout Section +Bit-rates +\end_layout + +\begin_layout Standard +So far, no MOS (Mean Opinion Score +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +mean opinion score +\end_layout + +\end_inset + +) subjective evaluation has been performed for Speex. + In order to give an idea of the quality achievable with it, table +\begin_inset CommandInset ref +LatexCommand ref +reference "cap:quality_vs_bps" + +\end_inset + + presents my own subjective opinion on it. + It should be noted that different people will perceive the quality differently + and that the person that designed the codec often has a bias (one way or + another) when it comes to subjective evaluation. + Last thing, it should be noted that for most codecs (including Speex) encoding + quality sometimes varies depending on the input. + Note that the complexity is only approximate (within 0.5 mflops and using + the lowest complexity setting). + Decoding requires approximately 0.5 mflops +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +complexity +\end_layout + +\end_inset + + in most modes (1 mflops with perceptual enhancement). +\end_layout + +\begin_layout Standard +\begin_inset Float table +placement h +wide true +sideways false +status open + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{center} +\end_layout + +\end_inset + + +\begin_inset Tabular +<lyxtabular version="3" rows="17" columns="5"> +<features> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Mode +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Quality +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Bit-rate +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +bit-rate +\end_layout + +\end_inset + + (bps) +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +mflops +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +complexity +\end_layout + +\end_inset + + +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Quality/description +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +250 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +No transmission (DTX) +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +2,150 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +6 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Vocoder (mostly for comfort noise) +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +2 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +2 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5,950 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +9 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Very noticeable artifacts/noise, good intelligibility +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3-4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +8,000 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +10 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Artifacts/noise sometimes noticeable +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5-6 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +11,000 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +14 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Artifacts usually noticeable only with headphones +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7-8 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +15,000 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +11 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Need good headphones to tell the difference +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +6 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +9 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +18,200 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +17.5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Hard to tell the difference even with good headphones +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +10 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +24,600 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +14.5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Completely transparent for voice, good quality music +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +8 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3,950 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +10.5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Very noticeable artifacts/noise, good intelligibility +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +9 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +reserved +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +10 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +reserved +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +11 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +reserved +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +12 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +reserved +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +13 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Application-defined, interpreted by callback or skipped +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +14 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Speex in-band signaling +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +15 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +- +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Terminator code +\end_layout + +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +end{center} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +Quality versus bit-rate +\begin_inset CommandInset label +LatexCommand label +name "cap:quality_vs_bps" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Section +Perceptual enhancement +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +perceptual enhancement +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard + +\series bold +This section was only valid for version 1.1.12 and earlier. + It does not apply to version 1.2-beta1 (and later), for which the new perceptual + enhancement is not yet documented. +\end_layout + +\begin_layout Standard +This part of the codec only applies to the decoder and can even be changed + without affecting inter-operability. + For that reason, the implementation provided and described here should + only be considered as a reference implementation. + The enhancement system is divided into two parts. + First, the synthesis filter +\begin_inset Formula $S(z)=1/A(z)$ +\end_inset + + is replaced by an enhanced filter: +\begin_inset Formula \[ +S'(z)=\frac{A\left(z/a_{2}\right)A\left(z/a_{3}\right)}{A\left(z\right)A\left(z/a_{1}\right)}\] + +\end_inset + +where +\begin_inset Formula $a_{1}$ +\end_inset + + and +\begin_inset Formula $a_{2}$ +\end_inset + + depend on the mode in use and +\begin_inset Formula $a_{3}=\frac{1}{r}\left(1-\frac{1-ra_{1}}{1-ra_{2}}\right)$ +\end_inset + + with +\begin_inset Formula $r=.9$ +\end_inset + +. + The second part of the enhancement consists of using a comb filter to enhance + the pitch in the excitation domain. + +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +Speex wideband mode (sub-band CELP) +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +wideband +\end_layout + +\end_inset + + +\begin_inset CommandInset label +LatexCommand label +name "sec:Speex-wideband-mode" + +\end_inset + + +\end_layout + +\begin_layout Standard +For wideband, the Speex approach uses a +\emph on +q +\emph default +uadrature +\emph on +m +\emph default +irror +\emph on +f +\emph default +ilter +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +quadrature mirror filter +\end_layout + +\end_inset + + (QMF) to split the band in two. + The 16 kHz signal is thus divided into two 8 kHz signals, one representing + the low band (0-4 kHz), the other the high band (4-8 kHz). + The low band is encoded with the narrowband mode described in section +\begin_inset CommandInset ref +LatexCommand ref +reference "sec:Speex-narrowband-mode" + +\end_inset + + in such a way that the resulting +\begin_inset Quotes eld +\end_inset + +embedded narrowband bit-stream +\begin_inset Quotes erd +\end_inset + + can also be decoded with the narrowband decoder. + Since the low band encoding has already been described, only the high band + encoding is described in this section. +\end_layout + +\begin_layout Section +Linear Prediction +\end_layout + +\begin_layout Standard +The linear prediction part used for the high-band is very similar to what + is done for narrowband. + The only difference is that we use only 12 bits to encode the high-band + LSP's using a multi-stage vector quantizer (MSVQ). + The first level quantizes the 10 coefficients with 6 bits and the error + is then quantized using 6 bits, too. +\end_layout + +\begin_layout Section +Pitch Prediction +\end_layout + +\begin_layout Standard +That part is easy: there's no pitch prediction for the high-band. + There are two reasons for that. + First, there is usually little harmonic structure in this band (above 4 + kHz). + Second, it would be very hard to implement since the QMF folds the 4-8 + kHz band into 4-0 kHz (reversing the frequency axis), which means that + the location of the harmonics is no longer at multiples of the fundamental + (pitch). +\end_layout + +\begin_layout Section +Excitation Quantization +\end_layout + +\begin_layout Standard +The high-band excitation is coded in the same way as for narrowband. + +\end_layout + +\begin_layout Section +Bit allocation +\end_layout + +\begin_layout Standard +For the wideband mode, the entire narrowband frame is packed before the + high-band is encoded. + The narrowband part of the bit-stream is as defined in table +\begin_inset CommandInset ref +LatexCommand ref +reference "cap:bits-narrowband" + +\end_inset + +. + The high-band follows, as described in table +\begin_inset CommandInset ref +LatexCommand ref +reference "cap:bits-wideband" + +\end_inset + +. + For wideband, the mode ID is the same as the Speex quality setting and + is defined in table +\begin_inset CommandInset ref +LatexCommand ref +reference "tab:wideband-quality" + +\end_inset + +. + This also means that a wideband frame may be correctly decoded by a narrowband + decoder with the only caveat that if more than one frame is packed in the + same packet, the decoder will need to skip the high-band parts in order + to sync with the bit-stream. +\end_layout + +\begin_layout Standard +\begin_inset Float table +placement h +wide true +sideways false +status open + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{center} +\end_layout + +\end_inset + + +\begin_inset Tabular +<lyxtabular version="3" rows="7" columns="7"> +<features> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Parameter +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Update rate +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +2 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Wideband bit +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Mode ID +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +LSP +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +12 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +12 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +12 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +12 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Excitation gain +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +sub-frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Excitation VQ +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +sub-frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +20 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +40 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +80 +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Total +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +frame +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +36 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +112 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +192 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +352 +\end_layout + +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +end{center} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +Bit allocation for high-band in wideband mode +\begin_inset CommandInset label +LatexCommand label +name "cap:bits-wideband" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Float table +placement h +wide true +sideways false +status open + +\begin_layout Plain Layout +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +begin{center} +\end_layout + +\end_inset + + +\begin_inset Tabular +<lyxtabular version="3" rows="12" columns="3"> +<features> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<column alignment="center" valignment="top" width="0pt"> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Mode/Quality +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Bit-rate +\begin_inset Index +status collapsed + +\begin_layout Plain Layout +bit-rate +\end_layout + +\end_inset + + (bps) +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Quality/description +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +0 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3,950 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Barely intelligible (mostly for comfort noise) +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +1 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5,750 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Very noticeable artifacts/noise, poor intelligibility +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +2 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7,750 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Very noticeable artifacts/noise, good intelligibility +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +3 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +9,800 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Artifacts/noise sometimes annoying +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +4 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +12,800 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Artifacts/noise usually noticeable +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +5 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +16,800 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Artifacts/noise sometimes noticeable +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +6 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +20,600 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Need good headphones to tell the difference +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +7 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +23,800 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Need good headphones to tell the difference +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +8 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +27,800 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Hard to tell the difference even with good headphones +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +9 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +34,200 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Hard to tell the difference even with good headphones +\end_layout + +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +10 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +42,200 +\end_layout + +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\begin_layout Plain Layout +Completely transparent for voice, good quality music +\end_layout + +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +end{center} +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Plain Layout +\begin_inset Caption + +\begin_layout Plain Layout +Quality versus bit-rate for the wideband encoder +\begin_inset CommandInset label +LatexCommand label +name "tab:wideband-quality" + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +clearpage +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset ERT +status collapsed + +\begin_layout Plain Layout + + +\backslash +clearpage +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Chapter +\start_of_appendix +Sample code +\begin_inset CommandInset label +LatexCommand label +name "sec:Sample-code" + +\end_inset + + +\end_layout + +\begin_layout Standard +This section shows sample code for encoding and decoding speech using the + Speex API. + The commands can be used to encode and decode a file by calling: +\family typewriter + +\begin_inset Newline newline +\end_inset + +% sampleenc in_file.sw | sampledec out_file.sw +\family default + +\begin_inset Newline newline +\end_inset + +where both files are raw (no header) files encoded at 16 bits per sample + (in the machine natural endianness). +\end_layout + +\begin_layout Section +sampleenc.c +\end_layout + +\begin_layout Standard +sampleenc takes a raw 16 bits/sample file, encodes it and outputs a Speex + stream to stdout. + Note that the packing used is +\series bold +not +\series default + compatible with that of speexenc/speexdec. +\end_layout + +\begin_layout Standard +\begin_inset CommandInset include +LatexCommand lstinputlisting +filename "sampleenc.c" +lstparams "caption={Source code for sampleenc},label={sampleenc-source-code},numbers=left,numberstyle={\\footnotesize}" + +\end_inset + + +\end_layout + +\begin_layout Section +sampledec.c +\end_layout + +\begin_layout Standard +sampledec reads a Speex stream from stdin, decodes it and outputs it to + a raw 16 bits/sample file. + Note that the packing used is +\series bold +not +\series default + compatible with that of speexenc/speexdec. +\end_layout + +\begin_layout Standard +\begin_inset CommandInset include +LatexCommand lstinputlisting +filename "sampledec.c" +lstparams "caption={Source code for sampledec},label={sampledec-source-code},numbers=left,numberstyle={\\footnotesize}" + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +Jitter Buffer for Speex +\end_layout + +\begin_layout Standard +\begin_inset CommandInset include +LatexCommand lstinputlisting +filename "../speexclient/speex_jitter_buffer.c" +lstparams "caption={Example of using the jitter buffer for Speex packets},label={example-speex-jitter},numbers=left,numberstyle={\\footnotesize}" + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +IETF RTP Profile +\begin_inset CommandInset label +LatexCommand label +name "sec:IETF-draft" + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset CommandInset include +LatexCommand verbatiminput +filename "draft-ietf-avt-rtp-speex-05-tmp.txt" + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +Speex License +\begin_inset CommandInset label +LatexCommand label +name "sec:Speex-License" + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset CommandInset include +LatexCommand verbatiminput +filename "../COPYING" + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Newpage newpage +\end_inset + + +\end_layout + +\begin_layout Chapter +GNU Free Documentation License +\end_layout + +\begin_layout Standard +Version 1.1, March 2000 +\end_layout + +\begin_layout Standard +Copyright (C) 2000 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted + to copy and distribute verbatim copies of this license document, but changing + it is not allowed. + +\end_layout + +\begin_layout Section* +0. + PREAMBLE +\end_layout + +\begin_layout Standard +The purpose of this License is to make a manual, textbook, or other written + document "free" in the sense of freedom: to assure everyone the effective + freedom to copy and redistribute it, with or without modifying it, either + commercially or noncommercially. + Secondarily, this License preserves for the author and publisher a way + to get credit for their work, while not being considered responsible for + modifications made by others. +\end_layout + +\begin_layout Standard +This License is a kind of "copyleft", which means that derivative works + of the document must themselves be free in the same sense. + It complements the GNU General Public License, which is a copyleft license + designed for free software. +\end_layout + +\begin_layout Standard +We have designed this License in order to use it for manuals for free software, + because free software needs free documentation: a free program should come + with manuals providing the same freedoms that the software does. + But this License is not limited to software manuals; it can be used for + any textual work, regardless of subject matter or whether it is published + as a printed book. + We recommend this License principally for works whose purpose is instruction + or reference. + +\end_layout + +\begin_layout Section* +1. + APPLICABILITY AND DEFINITIONS +\end_layout + +\begin_layout Standard +This License applies to any manual or other work that contains a notice + placed by the copyright holder saying it can be distributed under the terms + of this License. + The "Document", below, refers to any such manual or work. + Any member of the public is a licensee, and is addressed as "you". +\end_layout + +\begin_layout Standard +A "Modified Version" of the Document means any work containing the Document + or a portion of it, either copied verbatim, or with modifications and/or + translated into another language. +\end_layout + +\begin_layout Standard +A "Secondary Section" is a named appendix or a front-matter section of the + Document that deals exclusively with the relationship of the publishers + or authors of the Document to the Document's overall subject (or to related + matters) and contains nothing that could fall directly within that overall + subject. + (For example, if the Document is in part a textbook of mathematics, a Secondary + Section may not explain any mathematics.) The relationship could be a matter + of historical connection with the subject or with related matters, or of + legal, commercial, philosophical, ethical or political position regarding + them. +\end_layout + +\begin_layout Standard +The "Invariant Sections" are certain Secondary Sections whose titles are + designated, as being those of Invariant Sections, in the notice that says + that the Document is released under this License. +\end_layout + +\begin_layout Standard +The "Cover Texts" are certain short passages of text that are listed, as + Front-Cover Texts or Back-Cover Texts, in the notice that says that the + Document is released under this License. +\end_layout + +\begin_layout Standard +A "Transparent" copy of the Document means a machine-readable copy, represented + in a format whose specification is available to the general public, whose + contents can be viewed and edited directly and straightforwardly with generic + text editors or (for images composed of pixels) generic paint programs + or (for drawings) some widely available drawing editor, and that is suitable + for input to text formatters or for automatic translation to a variety + of formats suitable for input to text formatters. + A copy made in an otherwise Transparent file format whose markup has been + designed to thwart or discourage subsequent modification by readers is + not Transparent. + A copy that is not "Transparent" is called "Opaque". +\end_layout + +\begin_layout Standard +Examples of suitable formats for Transparent copies include plain ASCII + without markup, Texinfo input format, LaTeX input format, SGML or XML using + a publicly available DTD, and standard-conforming simple HTML designed + for human modification. + Opaque formats include PostScript, PDF, proprietary formats that can be + read and edited only by proprietary word processors, SGML or XML for which + the DTD and/or processing tools are not generally available, and the machine-ge +nerated HTML produced by some word processors for output purposes only. +\end_layout + +\begin_layout Standard +The "Title Page" means, for a printed book, the title page itself, plus + such following pages as are needed to hold, legibly, the material this + License requires to appear in the title page. + For works in formats which do not have any title page as such, "Title Page" + means the text near the most prominent appearance of the work's title, + preceding the beginning of the body of the text. +\end_layout + +\begin_layout Section* +2. + VERBATIM COPYING +\end_layout + +\begin_layout Standard +You may copy and distribute the Document in any medium, either commercially + or noncommercially, provided that this License, the copyright notices, + and the license notice saying this License applies to the Document are + reproduced in all copies, and that you add no other conditions whatsoever + to those of this License. + You may not use technical measures to obstruct or control the reading or + further copying of the copies you make or distribute. + However, you may accept compensation in exchange for copies. + If you distribute a large enough number of copies you must also follow + the conditions in section 3. +\end_layout + +\begin_layout Standard +You may also lend copies, under the same conditions stated above, and you + may publicly display copies. +\end_layout + +\begin_layout Section* +3. + COPYING IN QUANTITY +\end_layout + +\begin_layout Standard +If you publish printed copies of the Document numbering more than 100, and + the Document's license notice requires Cover Texts, you must enclose the + copies in covers that carry, clearly and legibly, all these Cover Texts: + Front-Cover Texts on the front cover, and Back-Cover Texts on the back + cover. + Both covers must also clearly and legibly identify you as the publisher + of these copies. + The front cover must present the full title with all words of the title + equally prominent and visible. + You may add other material on the covers in addition. + Copying with changes limited to the covers, as long as they preserve the + title of the Document and satisfy these conditions, can be treated as verbatim + copying in other respects. +\end_layout + +\begin_layout Standard +If the required texts for either cover are too voluminous to fit legibly, + you should put the first ones listed (as many as fit reasonably) on the + actual cover, and continue the rest onto adjacent pages. +\end_layout + +\begin_layout Standard +If you publish or distribute Opaque copies of the Document numbering more + than 100, you must either include a machine-readable Transparent copy along + with each Opaque copy, or state in or with each Opaque copy a publicly-accessib +le computer-network location containing a complete Transparent copy of the + Document, free of added material, which the general network-using public + has access to download anonymously at no charge using public-standard network + protocols. + If you use the latter option, you must take reasonably prudent steps, when + you begin distribution of Opaque copies in quantity, to ensure that this + Transparent copy will remain thus accessible at the stated location until + at least one year after the last time you distribute an Opaque copy (directly + or through your agents or retailers) of that edition to the public. +\end_layout + +\begin_layout Standard +It is requested, but not required, that you contact the authors of the Document + well before redistributing any large number of copies, to give them a chance + to provide you with an updated version of the Document. + +\end_layout + +\begin_layout Section* +4. + MODIFICATIONS +\end_layout + +\begin_layout Standard +You may copy and distribute a Modified Version of the Document under the + conditions of sections 2 and 3 above, provided that you release the Modified + Version under precisely this License, with the Modified Version filling + the role of the Document, thus licensing distribution and modification + of the Modified Version to whoever possesses a copy of it. + In addition, you must do these things in the Modified Version: +\end_layout + +\begin_layout Itemize +A. + Use in the Title Page (and on the covers, if any) a title distinct from + that of the Document, and from those of previous versions (which should, + if there were any, be listed in the History section of the Document). + You may use the same title as a previous version if the original publisher + of that version gives permission. +\end_layout + +\begin_layout Itemize +B. + List on the Title Page, as authors, one or more persons or entities responsible + for authorship of the modifications in the Modified Version, together with + at least five of the principal authors of the Document (all of its principal + authors, if it has less than five). +\end_layout + +\begin_layout Itemize +C. + State on the Title page the name of the publisher of the Modified Version, + as the publisher. +\end_layout + +\begin_layout Itemize +D. + Preserve all the copyright notices of the Document. +\end_layout + +\begin_layout Itemize +E. + Add an appropriate copyright notice for your modifications adjacent to + the other copyright notices. +\end_layout + +\begin_layout Itemize +F. + Include, immediately after the copyright notices, a license notice giving + the public permission to use the Modified Version under the terms of this + License, in the form shown in the Addendum below. +\end_layout + +\begin_layout Itemize +G. + Preserve in that license notice the full lists of Invariant Sections and + required Cover Texts given in the Document's license notice. +\end_layout + +\begin_layout Itemize +H. + Include an unaltered copy of this License. +\end_layout + +\begin_layout Itemize +I. + Preserve the section entitled "History", and its title, and add to it an + item stating at least the title, year, new authors, and publisher of the + Modified Version as given on the Title Page. + If there is no section entitled "History" in the Document, create one stating + the title, year, authors, and publisher of the Document as given on its + Title Page, then add an item describing the Modified Version as stated + in the previous sentence. +\end_layout + +\begin_layout Itemize +J. + Preserve the network location, if any, given in the Document for public + access to a Transparent copy of the Document, and likewise the network + locations given in the Document for previous versions it was based on. + These may be placed in the "History" section. + You may omit a network location for a work that was published at least + four years before the Document itself, or if the original publisher of + the version it refers to gives permission. +\end_layout + +\begin_layout Itemize +K. + In any section entitled "Acknowledgements" or "Dedications", preserve the + section's title, and preserve in the section all the substance and tone + of each of the contributor acknowledgements and/or dedications given therein. +\end_layout + +\begin_layout Itemize +L. + Preserve all the Invariant Sections of the Document, unaltered in their + text and in their titles. + Section numbers or the equivalent are not considered part of the section + titles. +\end_layout + +\begin_layout Itemize +M. + Delete any section entitled "Endorsements". + Such a section may not be included in the Modified Version. +\end_layout + +\begin_layout Itemize +N. + Do not retitle any existing section as "Endorsements" or to conflict in + title with any Invariant Section. + +\end_layout + +\begin_layout Standard +If the Modified Version includes new front-matter sections or appendices + that qualify as Secondary Sections and contain no material copied from + the Document, you may at your option designate some or all of these sections + as invariant. + To do this, add their titles to the list of Invariant Sections in the Modified + Version's license notice. + These titles must be distinct from any other section titles. +\end_layout + +\begin_layout Standard +You may add a section entitled "Endorsements", provided it contains nothing + but endorsements of your Modified Version by various parties--for example, + statements of peer review or that the text has been approved by an organization + as the authoritative definition of a standard. +\end_layout + +\begin_layout Standard +You may add a passage of up to five words as a Front-Cover Text, and a passage + of up to 25 words as a Back-Cover Text, to the end of the list of Cover + Texts in the Modified Version. + Only one passage of Front-Cover Text and one of Back-Cover Text may be + added by (or through arrangements made by) any one entity. + If the Document already includes a cover text for the same cover, previously + added by you or by arrangement made by the same entity you are acting on + behalf of, you may not add another; but you may replace the old one, on + explicit permission from the previous publisher that added the old one. +\end_layout + +\begin_layout Standard +The author(s) and publisher(s) of the Document do not by this License give + permission to use their names for publicity for or to assert or imply endorseme +nt of any Modified Version. + +\end_layout + +\begin_layout Section* +5. + COMBINING DOCUMENTS +\end_layout + +\begin_layout Standard +You may combine the Document with other documents released under this License, + under the terms defined in section 4 above for modified versions, provided + that you include in the combination all of the Invariant Sections of all + of the original documents, unmodified, and list them all as Invariant Sections + of your combined work in its license notice. +\end_layout + +\begin_layout Standard +The combined work need only contain one copy of this License, and multiple + identical Invariant Sections may be replaced with a single copy. + If there are multiple Invariant Sections with the same name but different + contents, make the title of each such section unique by adding at the end + of it, in parentheses, the name of the original author or publisher of + that section if known, or else a unique number. + Make the same adjustment to the section titles in the list of Invariant + Sections in the license notice of the combined work. +\end_layout + +\begin_layout Standard +In the combination, you must combine any sections entitled "History" in + the various original documents, forming one section entitled "History"; + likewise combine any sections entitled "Acknowledgements", and any sections + entitled "Dedications". + You must delete all sections entitled "Endorsements." +\end_layout + +\begin_layout Section* +6. + COLLECTIONS OF DOCUMENTS +\end_layout + +\begin_layout Standard +You may make a collection consisting of the Document and other documents + released under this License, and replace the individual copies of this + License in the various documents with a single copy that is included in + the collection, provided that you follow the rules of this License for + verbatim copying of each of the documents in all other respects. +\end_layout + +\begin_layout Standard +You may extract a single document from such a collection, and distribute + it individually under this License, provided you insert a copy of this + License into the extracted document, and follow this License in all other + respects regarding verbatim copying of that document. + +\end_layout + +\begin_layout Section* +7. + AGGREGATION WITH INDEPENDENT WORKS +\end_layout + +\begin_layout Standard +A compilation of the Document or its derivatives with other separate and + independent documents or works, in or on a volume of a storage or distribution + medium, does not as a whole count as a Modified Version of the Document, + provided no compilation copyright is claimed for the compilation. + Such a compilation is called an "aggregate", and this License does not + apply to the other self-contained works thus compiled with the Document, + on account of their being thus compiled, if they are not themselves derivative + works of the Document. +\end_layout + +\begin_layout Standard +If the Cover Text requirement of section 3 is applicable to these copies + of the Document, then if the Document is less than one quarter of the entire + aggregate, the Document's Cover Texts may be placed on covers that surround + only the Document within the aggregate. + Otherwise they must appear on covers around the whole aggregate. +\end_layout + +\begin_layout Section* +8. + TRANSLATION +\end_layout + +\begin_layout Standard +Translation is considered a kind of modification, so you may distribute + translations of the Document under the terms of section 4. + Replacing Invariant Sections with translations requires special permission + from their copyright holders, but you may include translations of some + or all Invariant Sections in addition to the original versions of these + Invariant Sections. + You may include a translation of this License provided that you also include + the original English version of this License. + In case of a disagreement between the translation and the original English + version of this License, the original English version will prevail. +\end_layout + +\begin_layout Section* +9. + TERMINATION +\end_layout + +\begin_layout Standard +You may not copy, modify, sublicense, or distribute the Document except + as expressly provided for under this License. + Any other attempt to copy, modify, sublicense or distribute the Document + is void, and will automatically terminate your rights under this License. + However, parties who have received copies, or rights, from you under this + License will not have their licenses terminated so long as such parties + remain in full compliance. + +\end_layout + +\begin_layout Section* +10. + FUTURE REVISIONS OF THIS LICENSE +\end_layout + +\begin_layout Standard +The Free Software Foundation may publish new, revised versions of the GNU + Free Documentation License from time to time. + Such new versions will be similar in spirit to the present version, but + may differ in detail to address new problems or concerns. + See http://www.gnu.org/copyleft/. +\end_layout + +\begin_layout Standard +Each version of the License is given a distinguishing version number. + If the Document specifies that a particular numbered version of this License + "or any later version" applies to it, you have the option of following + the terms and conditions either of that specified version or of any later + version that has been published (not as a draft) by the Free Software Foundatio +n. + If the Document does not specify a version number of this License, you + may choose any version ever published (not as a draft) by the Free Software + Foundation. +\end_layout + +\begin_layout Standard +\begin_inset CommandInset index_print +LatexCommand printindex + +\end_inset + + +\end_layout + +\end_body +\end_document diff --git a/src/libs/speexdsp/doc/manual.pdf b/src/libs/speexdsp/doc/manual.pdf new file mode 100644 index 00000000..292f304d Binary files /dev/null and b/src/libs/speexdsp/doc/manual.pdf differ diff --git a/src/libs/speexdsp/doc/programming.html b/src/libs/speexdsp/doc/programming.html new file mode 100644 index 00000000..7b5bc7ae --- /dev/null +++ b/src/libs/speexdsp/doc/programming.html @@ -0,0 +1,125 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + <title>Speex Programming</title> + + <meta http-equiv="content-type" + content="text/html; charset=ISO-8859-1"> +</head> + <body> + +<div align="center"> +<h1>Speex Programming</h1> + +<div align="left"> +<h2>Encoding</h2> + In order to encode speech using Speex, you first need to:<br> + +<blockquote> + <pre><big>#include &lt;speex.h&gt;</big></pre> + </blockquote> + You then need to declare a Speex bit-packing struct<br> + +<blockquote> + <pre><big>SpeexBits bits;</big></pre> + </blockquote> + and a Speex encoder state<br> + +<blockquote> + <pre><big>void *enc_state;</big></pre> + </blockquote> + The two are initialized by:<br> + +<blockquote> + <pre><big>speex_bits_init(&amp;bits);</big></pre> + + <pre><big>enc_state = speex_encoder_init(&amp;speex_nb_mode);</big></pre> + </blockquote> + For wideband coding, <i>speex_nb_mode</i> will be replaced by <i>speex_wb_mode</i> +. In most cases, you will need to know the frame size used by the mode you +are using. You can get that value in the <i>frame_size</i> variable with:<br> +<blockquote><big><tt>speex_encoder_ctl(enc_state, SPEEX_GET_FRAME_SIZE, &amp;frame_size);</tt></big><br> +</blockquote> + For every input frame:<br> + +<blockquote> + <pre><big>speex_bits_reset(&amp;bits);</big></pre> + + <pre><big>speex_encode(enc_state, input_frame, &amp;bits);</big></pre> + + <pre><big>nbBytes = speex_bits_write(&amp;bits, byte_ptr, MAX_NB_BYTES);</big></pre> + </blockquote> + where <i>input_frame</i> is a <i>(float *)</i> pointing to the beginning +of a speech frame, byte_ptr is a <i>(char *)</i> where the encoded frame will +be written, <i>MAX_NB_BYTES</i> is the maximum number of bytes that can be +written to <i>byte_ptr</i> without causing an overflow and <i>nbBytes</i> + is the number of bytes actually written to <i>byte_ptr</i> (the encoded +size in bytes).<br> + <br> + After you're done with the encoding, free all resources with:<br> + +<blockquote> + <pre><big>speex_bits_destroy(&amp;bits);</big></pre> + + <pre><big>speex_encoder_destroy(&amp;enc_state);</big></pre> + </blockquote> + That's about it for the encoder.<br> + +<h2>Decoding</h2> + In order to encode speech using Speex, you first need to:<br> + +<blockquote> + <pre><big>#include &lt;speex.h&gt;</big></pre> + </blockquote> + You then need to declare a Speex bit-packing struct<br> + +<blockquote> + <pre><big>SpeexBits bits;</big></pre> + </blockquote> + and a Speex encoder state<br> + +<blockquote> + <pre><big>void *dec_state;</big></pre> + </blockquote> + The two are initialized by:<br> + +<blockquote> + <pre><big>speex_bits_init(&amp;bits);</big></pre> + + <pre><big>dec_state = speex_decoder_init(&amp;speex_nb_mode);</big></pre> + </blockquote> + For wideband decoding, <i>speex_nb_mode</i> will be replaced by <i>speex_wb_mode</i> +. You can get that value in the <i>frame_size</i> variable with:<br> + +<blockquote><big><tt>speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &amp;frame_size);</tt></big><br> +</blockquote> + There is also a parameter that can be set for the decoder: whether or not +to use a perceptual post-filter. This can be set by:<br> +<blockquote><big><tt>speex_decoder_ctl(dec_state, SPEEX_SET_PF, &amp;pf);</tt></big><br> +</blockquote> +where <i>pf</i> is an <i>int</i> that with value 0 to have the post-filter +disabled and 1 to have it enabled.<br> +<br> +For every input frame:<br> + +<blockquote> + <pre><big>speex_bits_read_from(&amp;bits, input_bytes, nbBytes);</big></pre> + + <pre><big>speex_decode(st, &amp;bits, output_frame, 0);</big></pre> + </blockquote> + where <i>input_bytes</i> is a <i>(char *)</i> containing the bit-stream +data received for a frame, <i>nbBytes</i> is the size (in bytes) of that +bit-stream, and <i>output_frame</i> is a <i>(float *)</i> and points to the +area where the decoded speech frame will be written. The last argument indicates +whether the frame we'd like to decode was lost. A value of 0 indicates the +normal case where bits points to the bit of the current frame. A value of +1 indicates that we don't have the bits for the current frame, in which case +the bits argument should be the same as the bits for the last correctly received +frame. When a frame is lost, the Speex decoder will do its best to "guess" +the sorrect signal.<br> + <br> + </div> + </div> + +</body> +</html> diff --git a/src/libs/speexdsp/doc/ref_shaping.eps b/src/libs/speexdsp/doc/ref_shaping.eps new file mode 100644 index 00000000..4ef7007f --- /dev/null +++ b/src/libs/speexdsp/doc/ref_shaping.eps @@ -0,0 +1,2045 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: printout.eps +%%Creator: gnuplot 4.0 patchlevel 0 +%%CreationDate: Mon Mar 6 17:15:27 2006 +%%DocumentFonts: (atend) +%%BoundingBox: 50 50 410 302 +%%Orientation: Portrait +%%EndComments +/gnudict 256 dict def +gnudict begin +/Color true def +/Solid false def +/gnulinewidth 5.000 def +/userlinewidth gnulinewidth def +/vshift -46 def +/dl {10.0 mul} def +/hpt_ 31.5 def +/vpt_ 31.5 def +/hpt hpt_ def +/vpt vpt_ def +/Rounded false def +/M {moveto} bind def +/L {lineto} bind def +/R {rmoveto} bind def +/V {rlineto} bind def +/N {newpath moveto} bind def +/C {setrgbcolor} bind def +/f {rlineto fill} bind def +/vpt2 vpt 2 mul def +/hpt2 hpt 2 mul def +/Lshow { currentpoint stroke M + 0 vshift R show } def +/Rshow { currentpoint stroke M + dup stringwidth pop neg vshift R show } def +/Cshow { currentpoint stroke M + dup stringwidth pop -2 div vshift R show } def +/UP { dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def + /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def } def +/DL { Color {setrgbcolor Solid {pop []} if 0 setdash } + {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse } def +/BL { stroke userlinewidth 2 mul setlinewidth + Rounded { 1 setlinejoin 1 setlinecap } if } def +/AL { stroke userlinewidth 2 div setlinewidth + Rounded { 1 setlinejoin 1 setlinecap } if } def +/UL { dup gnulinewidth mul /userlinewidth exch def + dup 1 lt {pop 1} if 10 mul /udl exch def } def +/PL { stroke userlinewidth setlinewidth + Rounded { 1 setlinejoin 1 setlinecap } if } def +/LTw { PL [] 1 setgray } def +/LTb { BL [] 0 0 0 DL } def +/LTa { AL [1 udl mul 2 udl mul] 0 setdash 0 0 0 setrgbcolor } def +/LT0 { PL [] 1 0 0 DL } def +/LT1 { PL [4 dl 2 dl] 0 1 0 DL } def +/LT2 { PL [2 dl 3 dl] 0 0 1 DL } def +/LT3 { PL [1 dl 1.5 dl] 1 0 1 DL } def +/LT4 { PL [5 dl 2 dl 1 dl 2 dl] 0 1 1 DL } def +/LT5 { PL [4 dl 3 dl 1 dl 3 dl] 1 1 0 DL } def +/LT6 { PL [2 dl 2 dl 2 dl 4 dl] 0 0 0 DL } def +/LT7 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 1 0.3 0 DL } def +/LT8 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 0.5 0.5 0.5 DL } def +/Pnt { stroke [] 0 setdash + gsave 1 setlinecap M 0 0 V stroke grestore } def +/Dia { stroke [] 0 setdash 2 copy vpt add M + hpt neg vpt neg V hpt vpt neg V + hpt vpt V hpt neg vpt V closepath stroke + Pnt } def +/Pls { stroke [] 0 setdash vpt sub M 0 vpt2 V + currentpoint stroke M + hpt neg vpt neg R hpt2 0 V stroke + } def +/Box { stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M + 0 vpt2 neg V hpt2 0 V 0 vpt2 V + hpt2 neg 0 V closepath stroke + Pnt } def +/Crs { stroke [] 0 setdash exch hpt sub exch vpt add M + hpt2 vpt2 neg V currentpoint stroke M + hpt2 neg 0 R hpt2 vpt2 V stroke } def +/TriU { stroke [] 0 setdash 2 copy vpt 1.12 mul add M + hpt neg vpt -1.62 mul V + hpt 2 mul 0 V + hpt neg vpt 1.62 mul V closepath stroke + Pnt } def +/Star { 2 copy Pls Crs } def +/BoxF { stroke [] 0 setdash exch hpt sub exch vpt add M + 0 vpt2 neg V hpt2 0 V 0 vpt2 V + hpt2 neg 0 V closepath fill } def +/TriUF { stroke [] 0 setdash vpt 1.12 mul add M + hpt neg vpt -1.62 mul V + hpt 2 mul 0 V + hpt neg vpt 1.62 mul V closepath fill } def +/TriD { stroke [] 0 setdash 2 copy vpt 1.12 mul sub M + hpt neg vpt 1.62 mul V + hpt 2 mul 0 V + hpt neg vpt -1.62 mul V closepath stroke + Pnt } def +/TriDF { stroke [] 0 setdash vpt 1.12 mul sub M + hpt neg vpt 1.62 mul V + hpt 2 mul 0 V + hpt neg vpt -1.62 mul V closepath fill} def +/DiaF { stroke [] 0 setdash vpt add M + hpt neg vpt neg V hpt vpt neg V + hpt vpt V hpt neg vpt V closepath fill } def +/Pent { stroke [] 0 setdash 2 copy gsave + translate 0 hpt M 4 {72 rotate 0 hpt L} repeat + closepath stroke grestore Pnt } def +/PentF { stroke [] 0 setdash gsave + translate 0 hpt M 4 {72 rotate 0 hpt L} repeat + closepath fill grestore } def +/Circle { stroke [] 0 setdash 2 copy + hpt 0 360 arc stroke Pnt } def +/CircleF { stroke [] 0 setdash hpt 0 360 arc fill } def +/C0 { BL [] 0 setdash 2 copy moveto vpt 90 450 arc } bind def +/C1 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 0 90 arc closepath fill + vpt 0 360 arc closepath } bind def +/C2 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 90 180 arc closepath fill + vpt 0 360 arc closepath } bind def +/C3 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 0 180 arc closepath fill + vpt 0 360 arc closepath } bind def +/C4 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 180 270 arc closepath fill + vpt 0 360 arc closepath } bind def +/C5 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 0 90 arc + 2 copy moveto + 2 copy vpt 180 270 arc closepath fill + vpt 0 360 arc } bind def +/C6 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 90 270 arc closepath fill + vpt 0 360 arc closepath } bind def +/C7 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 0 270 arc closepath fill + vpt 0 360 arc closepath } bind def +/C8 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 270 360 arc closepath fill + vpt 0 360 arc closepath } bind def +/C9 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 270 450 arc closepath fill + vpt 0 360 arc closepath } bind def +/C10 { BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill + 2 copy moveto + 2 copy vpt 90 180 arc closepath fill + vpt 0 360 arc closepath } bind def +/C11 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 0 180 arc closepath fill + 2 copy moveto + 2 copy vpt 270 360 arc closepath fill + vpt 0 360 arc closepath } bind def +/C12 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 180 360 arc closepath fill + vpt 0 360 arc closepath } bind def +/C13 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 0 90 arc closepath fill + 2 copy moveto + 2 copy vpt 180 360 arc closepath fill + vpt 0 360 arc closepath } bind def +/C14 { BL [] 0 setdash 2 copy moveto + 2 copy vpt 90 360 arc closepath fill + vpt 0 360 arc } bind def +/C15 { BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill + vpt 0 360 arc closepath } bind def +/Rec { newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto + neg 0 rlineto closepath } bind def +/Square { dup Rec } bind def +/Bsquare { vpt sub exch vpt sub exch vpt2 Square } bind def +/S0 { BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare } bind def +/S1 { BL [] 0 setdash 2 copy vpt Square fill Bsquare } bind def +/S2 { BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare } bind def +/S3 { BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare } bind def +/S4 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def +/S5 { BL [] 0 setdash 2 copy 2 copy vpt Square fill + exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def +/S6 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare } bind def +/S7 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill + 2 copy vpt Square fill + Bsquare } bind def +/S8 { BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare } bind def +/S9 { BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare } bind def +/S10 { BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill + Bsquare } bind def +/S11 { BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill + Bsquare } bind def +/S12 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare } bind def +/S13 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill + 2 copy vpt Square fill Bsquare } bind def +/S14 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill + 2 copy exch vpt sub exch vpt Square fill Bsquare } bind def +/S15 { BL [] 0 setdash 2 copy Bsquare fill Bsquare } bind def +/D0 { gsave translate 45 rotate 0 0 S0 stroke grestore } bind def +/D1 { gsave translate 45 rotate 0 0 S1 stroke grestore } bind def +/D2 { gsave translate 45 rotate 0 0 S2 stroke grestore } bind def +/D3 { gsave translate 45 rotate 0 0 S3 stroke grestore } bind def +/D4 { gsave translate 45 rotate 0 0 S4 stroke grestore } bind def +/D5 { gsave translate 45 rotate 0 0 S5 stroke grestore } bind def +/D6 { gsave translate 45 rotate 0 0 S6 stroke grestore } bind def +/D7 { gsave translate 45 rotate 0 0 S7 stroke grestore } bind def +/D8 { gsave translate 45 rotate 0 0 S8 stroke grestore } bind def +/D9 { gsave translate 45 rotate 0 0 S9 stroke grestore } bind def +/D10 { gsave translate 45 rotate 0 0 S10 stroke grestore } bind def +/D11 { gsave translate 45 rotate 0 0 S11 stroke grestore } bind def +/D12 { gsave translate 45 rotate 0 0 S12 stroke grestore } bind def +/D13 { gsave translate 45 rotate 0 0 S13 stroke grestore } bind def +/D14 { gsave translate 45 rotate 0 0 S14 stroke grestore } bind def +/D15 { gsave translate 45 rotate 0 0 S15 stroke grestore } bind def +/DiaE { stroke [] 0 setdash vpt add M + hpt neg vpt neg V hpt vpt neg V + hpt vpt V hpt neg vpt V closepath stroke } def +/BoxE { stroke [] 0 setdash exch hpt sub exch vpt add M + 0 vpt2 neg V hpt2 0 V 0 vpt2 V + hpt2 neg 0 V closepath stroke } def +/TriUE { stroke [] 0 setdash vpt 1.12 mul add M + hpt neg vpt -1.62 mul V + hpt 2 mul 0 V + hpt neg vpt 1.62 mul V closepath stroke } def +/TriDE { stroke [] 0 setdash vpt 1.12 mul sub M + hpt neg vpt 1.62 mul V + hpt 2 mul 0 V + hpt neg vpt -1.62 mul V closepath stroke } def +/PentE { stroke [] 0 setdash gsave + translate 0 hpt M 4 {72 rotate 0 hpt L} repeat + closepath stroke grestore } def +/CircE { stroke [] 0 setdash + hpt 0 360 arc stroke } def +/Opaque { gsave closepath 1 setgray fill grestore 0 setgray closepath } def +/DiaW { stroke [] 0 setdash vpt add M + hpt neg vpt neg V hpt vpt neg V + hpt vpt V hpt neg vpt V Opaque stroke } def +/BoxW { stroke [] 0 setdash exch hpt sub exch vpt add M + 0 vpt2 neg V hpt2 0 V 0 vpt2 V + hpt2 neg 0 V Opaque stroke } def +/TriUW { stroke [] 0 setdash vpt 1.12 mul add M + hpt neg vpt -1.62 mul V + hpt 2 mul 0 V + hpt neg vpt 1.62 mul V Opaque stroke } def +/TriDW { stroke [] 0 setdash vpt 1.12 mul sub M + hpt neg vpt 1.62 mul V + hpt 2 mul 0 V + hpt neg vpt -1.62 mul V Opaque stroke } def +/PentW { stroke [] 0 setdash gsave + translate 0 hpt M 4 {72 rotate 0 hpt L} repeat + Opaque stroke grestore } def +/CircW { stroke [] 0 setdash + hpt 0 360 arc Opaque stroke } def +/BoxFill { gsave Rec 1 setgray fill grestore } def +/BoxColFill { + gsave Rec + /Fillden exch def + currentrgbcolor + /ColB exch def /ColG exch def /ColR exch def + /ColR ColR Fillden mul Fillden sub 1 add def + /ColG ColG Fillden mul Fillden sub 1 add def + /ColB ColB Fillden mul Fillden sub 1 add def + ColR ColG ColB setrgbcolor + fill grestore } def +% +% PostScript Level 1 Pattern Fill routine +% Usage: x y w h s a XX PatternFill +% x,y = lower left corner of box to be filled +% w,h = width and height of box +% a = angle in degrees between lines and x-axis +% XX = 0/1 for no/yes cross-hatch +% +/PatternFill { gsave /PFa [ 9 2 roll ] def + PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate + PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec + gsave 1 setgray fill grestore clip + currentlinewidth 0.5 mul setlinewidth + /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def + 0 0 M PFa 5 get rotate PFs -2 div dup translate + 0 1 PFs PFa 4 get div 1 add floor cvi + { PFa 4 get mul 0 M 0 PFs V } for + 0 PFa 6 get ne { + 0 1 PFs PFa 4 get div 1 add floor cvi + { PFa 4 get mul 0 2 1 roll M PFs 0 V } for + } if + stroke grestore } def +% +/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont +dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall +currentdict end definefont pop +end +%%EndProlog +gnudict begin +gsave +50 50 translate +0.050 0.050 scale +0 setgray +newpath +(Helvetica) findfont 140 scalefont setfont +1.000 UL +LTb +630 420 M +63 0 V +6269 0 R +-63 0 V +546 420 M +(-40) Rshow +1.000 UL +LTb +630 1056 M +63 0 V +6269 0 R +-63 0 V +-6353 0 R +(-30) Rshow +1.000 UL +LTb +630 1692 M +63 0 V +6269 0 R +-63 0 V +-6353 0 R +(-20) Rshow +1.000 UL +LTb +630 2328 M +63 0 V +6269 0 R +-63 0 V +-6353 0 R +(-10) Rshow +1.000 UL +LTb +630 2964 M +63 0 V +6269 0 R +-63 0 V +-6353 0 R +( 0) Rshow +1.000 UL +LTb +630 3600 M +63 0 V +6269 0 R +-63 0 V +-6353 0 R +( 10) Rshow +1.000 UL +LTb +630 4236 M +63 0 V +6269 0 R +-63 0 V +-6353 0 R +( 20) Rshow +1.000 UL +LTb +630 4872 M +63 0 V +6269 0 R +-63 0 V +-6353 0 R +( 30) Rshow +1.000 UL +LTb +630 420 M +0 63 V +0 4389 R +0 -63 V +630 280 M +( 0) Cshow +1.000 UL +LTb +1421 420 M +0 63 V +0 4389 R +0 -63 V +0 -4529 R +( 500) Cshow +1.000 UL +LTb +2213 420 M +0 63 V +0 4389 R +0 -63 V +0 -4529 R +( 1000) Cshow +1.000 UL +LTb +3004 420 M +0 63 V +0 4389 R +0 -63 V +0 -4529 R +( 1500) Cshow +1.000 UL +LTb +3796 420 M +0 63 V +0 4389 R +0 -63 V +0 -4529 R +( 2000) Cshow +1.000 UL +LTb +4587 420 M +0 63 V +0 4389 R +0 -63 V +0 -4529 R +( 2500) Cshow +1.000 UL +LTb +5379 420 M +0 63 V +0 4389 R +0 -63 V +0 -4529 R +( 3000) Cshow +1.000 UL +LTb +6170 420 M +0 63 V +0 4389 R +0 -63 V +0 -4529 R +( 3500) Cshow +1.000 UL +LTb +6962 420 M +0 63 V +0 4389 R +0 -63 V +0 -4529 R +( 4000) Cshow +1.000 UL +LTb +1.000 UL +LTb +630 420 M +6332 0 V +0 4452 V +-6332 0 V +630 420 L +LTb +140 2646 M +currentpoint gsave translate 90 rotate 0 0 M +(Response \(dB\)) Cshow +grestore +LTb +3796 70 M +(Frequency \(Hz\)) Cshow +1.000 UP +1.000 UL +LT0 +LTb +6311 4739 M +(Speech signal) Rshow +LT0 +6395 4739 M +399 0 V +630 1817 M +12 -132 V +13 -287 V +12 256 V +12 139 V +13 -127 V +12 -193 V +13 256 V +12 101 V +12 -189 V +13 -269 V +12 429 V +12 152 V +13 -102 V +12 -276 V +13 139 V +12 115 V +12 -205 V +13 -174 V +12 485 V +12 193 V +13 37 V +12 -17 V +12 41 V +13 230 V +12 242 V +13 107 V +12 190 V +12 513 V +13 436 V +12 323 V +12 236 V +13 168 V +12 110 V +12 58 V +13 9 V +12 -40 V +13 -90 V +12 -141 V +12 -197 V +13 -251 V +12 -289 V +12 -283 V +13 -247 V +12 -265 V +13 -324 V +12 -302 V +12 -231 V +13 -75 V +12 150 V +12 1 V +13 -298 V +1273 782 L +12 1103 V +13 76 V +12 -338 V +13 252 V +12 357 V +12 86 V +13 -118 V +12 -341 V +12 -20 V +13 364 V +12 243 V +12 212 V +13 214 V +12 208 V +13 180 V +12 136 V +12 82 V +13 23 V +12 -40 V +12 -107 V +13 -177 V +12 -240 V +13 -259 V +12 -215 V +12 -220 V +13 -297 V +12 -196 V +12 -128 V +13 -701 V +12 632 V +12 329 V +13 -25 V +12 -470 V +13 -54 V +12 538 V +12 70 V +13 -246 V +1743 551 L +12 1111 V +13 185 V +12 -159 V +1793 652 L +12 893 V +12 321 V +13 103 V +12 164 V +12 262 V +13 239 V +12 190 V +12 141 V +stroke +1891 2965 M +13 91 V +12 39 V +13 -13 V +12 -62 V +12 -97 V +13 -110 V +12 -120 V +12 -161 V +13 -265 V +12 -453 V +12 -215 V +13 139 V +12 -195 V +2062 420 L +5 0 R +10 961 V +12 135 V +13 -422 V +12 167 V +12 491 V +13 101 V +12 -169 V +13 -737 V +12 482 V +12 299 V +13 -48 V +12 -421 V +12 -151 V +13 434 V +12 -3 V +12 -378 V +13 -12 V +12 298 V +13 -187 V +12 -44 V +12 658 V +13 272 V +12 90 V +12 -49 V +13 -191 V +12 -370 V +13 -579 V +12 -329 V +12 385 V +13 444 V +12 172 V +12 -57 V +13 -407 V +12 -311 V +12 617 V +13 97 V +12 -198 V +13 -469 V +12 446 V +12 177 V +13 -114 V +12 -483 V +12 196 V +13 269 V +12 -74 V +12 -404 V +13 263 V +12 248 V +13 -37 V +12 -66 V +12 339 V +13 312 V +12 244 V +12 215 V +13 176 V +12 125 V +13 69 V +12 15 V +12 -30 V +13 -64 V +12 -85 V +12 -104 V +13 -138 V +12 -195 V +12 -278 V +13 -354 V +12 -257 V +13 -43 V +12 -20 V +12 -73 V +13 -202 V +12 -25 V +12 318 V +13 132 V +12 -73 V +12 -242 V +13 107 V +12 220 V +13 7 V +12 -277 V +9 -811 V +6 0 R +10 887 V +12 241 V +12 20 V +13 -14 V +12 241 V +13 323 V +12 262 V +stroke +3153 2380 M +12 197 V +13 138 V +12 86 V +12 36 V +13 -10 V +12 -54 V +12 -92 V +13 -116 V +12 -108 V +13 -73 V +12 -63 V +12 -107 V +13 -195 V +12 -267 V +12 -88 V +13 50 V +12 -97 V +13 -367 V +12 -285 V +12 374 V +13 3 V +12 -352 V +12 88 V +13 347 V +12 47 V +12 -192 V +13 -264 V +12 200 V +13 16 V +12 -421 V +12 296 V +13 398 V +12 65 V +12 -212 V +13 69 V +12 453 V +12 240 V +13 104 V +12 12 V +13 -52 V +12 -82 V +12 -69 V +13 -34 V +12 -25 V +12 -64 V +13 -158 V +12 -346 V +13 -166 V +12 375 V +12 139 V +13 -46 V +12 -207 V +12 -187 V +13 102 V +12 -14 V +12 -357 V +13 -271 V +12 601 V +13 119 V +12 -172 V +12 -486 V +13 521 V +12 256 V +12 10 V +13 -219 V +12 -294 V +13 446 V +12 285 V +12 167 V +13 137 V +12 152 V +12 161 V +13 144 V +12 106 V +12 58 V +13 7 V +12 -44 V +13 -87 V +12 -116 V +12 -119 V +13 -118 V +12 -152 V +12 -241 V +13 -363 V +12 -109 V +12 172 V +13 43 V +12 -75 V +13 -176 V +12 -313 V +12 -344 V +13 236 V +12 93 V +12 -169 V +13 -102 V +12 320 V +13 123 V +12 17 V +12 207 V +13 270 V +12 201 V +12 186 V +13 217 V +12 213 V +stroke +4439 2543 M +12 174 V +13 125 V +12 79 V +13 42 V +12 14 V +12 -3 V +13 -17 V +12 -34 V +12 -62 V +13 -102 V +12 -149 V +12 -182 V +13 -151 V +12 -70 V +13 -73 V +12 -146 V +12 -150 V +13 43 V +12 81 V +12 -27 V +13 -148 V +12 -213 V +13 -14 V +12 246 V +12 262 V +13 190 V +12 94 V +12 -7 V +13 -56 V +12 149 V +12 312 V +13 269 V +12 212 V +13 169 V +12 136 V +12 105 V +13 76 V +12 45 V +12 15 V +13 -15 V +12 -43 V +13 -66 V +12 -80 V +12 -83 V +13 -79 V +12 -80 V +12 -99 V +13 -136 V +12 -193 V +12 -274 V +13 -400 V +12 -462 V +13 173 V +12 148 V +12 -21 V +13 -198 V +12 -146 V +12 391 V +13 253 V +12 99 V +12 -38 V +13 -208 V +12 -260 V +13 418 V +12 330 V +12 210 V +13 153 V +12 123 V +12 105 V +13 88 V +12 68 V +13 47 V +12 24 V +12 1 V +13 -19 V +12 -38 V +12 -54 V +13 -67 V +12 -80 V +12 -93 V +13 -111 V +12 -132 V +13 -152 V +12 -167 V +12 -183 V +13 -211 V +12 -236 V +12 -139 V +13 15 V +12 -22 V +13 -164 V +12 -405 V +12 -211 V +13 440 V +12 230 V +12 152 V +13 96 V +12 29 V +12 -28 V +13 -10 V +12 81 V +13 96 V +12 29 V +12 -69 V +stroke +5725 2104 M +13 -186 V +12 -239 V +12 142 V +13 249 V +12 155 V +12 88 V +13 49 V +12 35 V +13 39 V +12 38 V +12 13 V +13 -34 V +12 -87 V +12 -112 V +13 -72 V +12 -35 V +13 -100 V +12 -269 V +12 -452 V +13 296 V +12 99 V +12 -312 V +13 242 V +12 513 V +12 237 V +13 88 V +12 -21 V +13 -82 V +12 -1 V +12 153 V +13 177 V +12 156 V +12 145 V +13 134 V +12 114 V +12 87 V +13 56 V +12 26 V +13 -3 V +12 -30 V +12 -52 V +13 -74 V +12 -93 V +12 -108 V +13 -121 V +12 -130 V +13 -129 V +12 -118 V +12 -100 V +13 -92 V +12 -105 V +12 -135 V +13 -172 V +12 -195 V +12 -222 V +13 -353 V +12 -548 V +13 682 V +12 273 V +12 79 V +13 -59 V +12 -188 V +12 -225 V +13 39 V +12 80 V +13 -43 V +12 -44 V +12 184 V +13 213 V +12 127 V +12 42 V +13 -37 V +12 -115 V +12 -182 V +13 -179 V +12 -53 V +13 12 V +12 6 V +12 20 V +13 10 V +12 -65 V +12 -195 V +13 -296 V +12 56 V +12 100 V +13 -118 V +12 -182 V +13 253 V +12 155 V +12 -50 V +13 -222 V +12 21 V +12 197 V +13 7 V +12 -194 V +13 -77 V +12 240 V +12 73 V +13 -132 V +1.000 UL +LT1 +LTb +6311 4599 M +(LPC synthesis filter) Rshow +LT1 +6395 4599 M +399 0 V +630 4034 M +12 0 V +13 0 V +12 1 V +12 1 V +13 1 V +12 1 V +13 1 V +12 2 V +12 2 V +13 3 V +12 2 V +12 4 V +13 3 V +12 5 V +13 4 V +12 6 V +12 6 V +13 7 V +12 8 V +12 8 V +13 10 V +12 11 V +12 11 V +13 13 V +12 15 V +13 16 V +12 17 V +12 19 V +13 21 V +12 23 V +12 25 V +13 27 V +12 29 V +12 31 V +13 32 V +12 33 V +13 33 V +12 30 V +12 26 V +13 16 V +12 4 V +12 -11 V +13 -26 V +12 -38 V +13 -49 V +12 -54 V +12 -56 V +13 -58 V +12 -57 V +12 -55 V +13 -53 V +12 -52 V +12 -49 V +13 -47 V +12 -45 V +13 -44 V +12 -41 V +12 -40 V +13 -38 V +12 -37 V +12 -35 V +13 -35 V +12 -33 V +12 -31 V +13 -31 V +12 -30 V +13 -29 V +12 -28 V +12 -27 V +13 -26 V +12 -26 V +12 -24 V +13 -25 V +12 -23 V +13 -23 V +12 -22 V +12 -22 V +13 -21 V +12 -20 V +12 -20 V +13 -20 V +12 -19 V +12 -19 V +13 -18 V +12 -17 V +13 -18 V +12 -17 V +12 -16 V +13 -16 V +12 -16 V +12 -15 V +13 -15 V +12 -15 V +13 -14 V +12 -14 V +12 -14 V +13 -13 V +12 -13 V +12 -13 V +13 -12 V +12 -13 V +12 -11 V +stroke +1891 2822 M +13 -12 V +12 -11 V +13 -11 V +12 -11 V +12 -11 V +13 -10 V +12 -10 V +12 -10 V +13 -10 V +12 -9 V +12 -9 V +13 -9 V +12 -8 V +13 -9 V +12 -8 V +12 -8 V +13 -8 V +12 -7 V +12 -8 V +13 -7 V +12 -7 V +13 -7 V +12 -6 V +12 -6 V +13 -7 V +12 -6 V +12 -5 V +13 -6 V +12 -5 V +12 -6 V +13 -5 V +12 -5 V +13 -4 V +12 -5 V +12 -4 V +13 -5 V +12 -4 V +12 -4 V +13 -3 V +12 -4 V +13 -3 V +12 -4 V +12 -3 V +13 -3 V +12 -2 V +12 -3 V +13 -3 V +12 -2 V +12 -2 V +13 -2 V +12 -2 V +13 -2 V +12 -2 V +12 -1 V +13 -2 V +12 -1 V +12 -1 V +13 -2 V +12 -1 V +12 0 V +13 -1 V +12 -1 V +13 0 V +12 -1 V +12 0 V +13 0 V +12 -1 V +12 0 V +13 0 V +12 0 V +13 0 V +12 1 V +12 0 V +13 0 V +12 1 V +12 0 V +13 1 V +12 0 V +12 1 V +13 1 V +12 0 V +13 1 V +12 1 V +12 1 V +13 0 V +12 1 V +12 1 V +13 1 V +12 1 V +12 0 V +13 1 V +12 1 V +13 1 V +12 0 V +12 1 V +13 1 V +12 0 V +12 1 V +13 1 V +12 0 V +13 1 V +12 0 V +12 0 V +13 1 V +stroke +3178 2508 M +12 0 V +12 0 V +13 0 V +12 0 V +12 0 V +13 0 V +12 0 V +13 0 V +12 0 V +12 -1 V +13 0 V +12 -1 V +12 0 V +13 -1 V +12 0 V +13 -1 V +12 -1 V +12 0 V +13 -1 V +12 -1 V +12 -1 V +13 -1 V +12 -1 V +12 0 V +13 -1 V +12 -1 V +13 -1 V +12 -1 V +12 -1 V +13 -1 V +12 -1 V +12 -1 V +13 -1 V +12 -1 V +12 0 V +13 -1 V +12 -1 V +13 -1 V +12 0 V +12 -1 V +13 0 V +12 -1 V +12 0 V +13 0 V +12 0 V +13 0 V +12 0 V +12 0 V +13 0 V +12 0 V +12 0 V +13 1 V +12 1 V +12 0 V +13 1 V +12 1 V +13 1 V +12 2 V +12 1 V +13 1 V +12 2 V +12 2 V +13 2 V +12 2 V +13 2 V +12 3 V +12 2 V +13 3 V +12 3 V +12 3 V +13 4 V +12 3 V +12 4 V +13 4 V +12 4 V +13 4 V +12 4 V +12 5 V +13 5 V +12 5 V +12 5 V +13 6 V +12 6 V +12 6 V +13 6 V +12 6 V +13 7 V +12 7 V +12 7 V +13 8 V +12 8 V +12 8 V +13 8 V +12 9 V +13 9 V +12 9 V +12 9 V +13 10 V +12 10 V +12 11 V +13 11 V +12 11 V +12 12 V +13 12 V +stroke +4464 2759 M +12 12 V +13 13 V +12 13 V +12 14 V +13 14 V +12 15 V +12 15 V +13 16 V +12 16 V +12 17 V +13 17 V +12 18 V +13 18 V +12 19 V +12 20 V +13 21 V +12 21 V +12 22 V +13 23 V +12 23 V +13 24 V +12 26 V +12 26 V +13 26 V +12 28 V +12 28 V +13 30 V +12 29 V +12 31 V +13 30 V +12 31 V +13 30 V +12 29 V +12 27 V +13 26 V +12 22 V +12 18 V +13 13 V +12 8 V +13 2 V +12 -3 V +12 -9 V +13 -13 V +12 -16 V +12 -20 V +13 -21 V +12 -23 V +12 -24 V +13 -23 V +12 -24 V +13 -23 V +12 -23 V +12 -22 V +13 -21 V +12 -21 V +12 -20 V +13 -18 V +12 -18 V +12 -17 V +13 -16 V +12 -16 V +13 -14 V +12 -14 V +12 -13 V +13 -13 V +12 -11 V +12 -11 V +13 -11 V +12 -10 V +13 -9 V +12 -8 V +12 -8 V +13 -8 V +12 -6 V +12 -7 V +13 -6 V +12 -5 V +12 -5 V +13 -4 V +12 -4 V +13 -4 V +12 -3 V +12 -3 V +13 -2 V +12 -2 V +12 -2 V +13 -1 V +12 -1 V +13 0 V +12 0 V +12 0 V +13 0 V +12 1 V +12 1 V +13 1 V +12 2 V +12 2 V +13 2 V +12 2 V +13 2 V +12 3 V +12 3 V +13 2 V +12 3 V +stroke +5750 3038 M +12 3 V +13 3 V +12 3 V +12 3 V +13 3 V +12 2 V +13 3 V +12 2 V +12 2 V +13 2 V +12 2 V +12 1 V +13 0 V +12 1 V +13 0 V +12 -1 V +12 -1 V +13 -2 V +12 -2 V +12 -3 V +13 -4 V +12 -4 V +12 -4 V +13 -6 V +12 -5 V +13 -7 V +12 -6 V +12 -8 V +13 -7 V +12 -9 V +12 -8 V +13 -9 V +12 -9 V +12 -10 V +13 -9 V +12 -10 V +13 -10 V +12 -10 V +12 -11 V +13 -10 V +12 -10 V +12 -11 V +13 -10 V +12 -10 V +13 -11 V +12 -10 V +12 -10 V +13 -10 V +12 -10 V +12 -9 V +13 -10 V +12 -10 V +12 -9 V +13 -9 V +12 -9 V +13 -9 V +12 -8 V +12 -8 V +13 -9 V +12 -8 V +12 -7 V +13 -8 V +12 -7 V +13 -7 V +12 -7 V +12 -7 V +13 -7 V +12 -6 V +12 -6 V +13 -6 V +12 -6 V +12 -5 V +13 -5 V +12 -5 V +13 -5 V +12 -5 V +12 -4 V +13 -4 V +12 -4 V +12 -4 V +13 -4 V +12 -3 V +12 -3 V +13 -3 V +12 -3 V +13 -2 V +12 -3 V +12 -2 V +13 -2 V +12 -2 V +12 -1 V +13 -1 V +12 -2 V +13 0 V +12 -1 V +12 -1 V +13 0 V +1.000 UL +LT2 +LTb +6311 4459 M +(Reference shaping) Rshow +LT2 +6395 4459 M +399 0 V +630 3487 M +12 0 V +13 0 V +12 1 V +12 0 V +13 1 V +12 1 V +13 1 V +12 2 V +12 1 V +13 2 V +12 2 V +12 2 V +13 2 V +12 2 V +13 3 V +12 2 V +12 3 V +13 3 V +12 3 V +12 2 V +13 4 V +12 3 V +12 3 V +13 3 V +12 3 V +13 2 V +12 3 V +12 3 V +13 2 V +12 2 V +12 1 V +13 1 V +12 1 V +12 0 V +13 0 V +12 -2 V +13 -2 V +12 -2 V +12 -4 V +13 -4 V +12 -6 V +12 -6 V +13 -7 V +12 -8 V +13 -8 V +12 -10 V +12 -10 V +13 -11 V +12 -12 V +12 -12 V +13 -13 V +12 -13 V +12 -14 V +13 -14 V +12 -14 V +13 -15 V +12 -15 V +12 -15 V +13 -15 V +12 -15 V +12 -15 V +13 -14 V +12 -15 V +12 -15 V +13 -15 V +12 -14 V +13 -14 V +12 -15 V +12 -13 V +13 -14 V +12 -14 V +12 -13 V +13 -13 V +12 -13 V +13 -12 V +12 -12 V +12 -12 V +13 -12 V +12 -12 V +12 -11 V +13 -11 V +12 -11 V +12 -10 V +13 -10 V +12 -10 V +13 -10 V +12 -10 V +12 -9 V +13 -9 V +12 -9 V +12 -9 V +13 -8 V +12 -8 V +13 -8 V +12 -8 V +12 -8 V +13 -7 V +12 -7 V +12 -7 V +13 -7 V +12 -6 V +12 -7 V +stroke +1891 2847 M +13 -6 V +12 -6 V +13 -6 V +12 -5 V +12 -6 V +13 -5 V +12 -5 V +12 -5 V +13 -5 V +12 -5 V +12 -4 V +13 -5 V +12 -4 V +13 -4 V +12 -4 V +12 -4 V +13 -4 V +12 -3 V +12 -4 V +13 -3 V +12 -3 V +13 -3 V +12 -3 V +12 -3 V +13 -2 V +12 -3 V +12 -2 V +13 -3 V +12 -2 V +12 -2 V +13 -2 V +12 -2 V +13 -2 V +12 -1 V +12 -2 V +13 -1 V +12 -2 V +12 -1 V +13 -1 V +12 -1 V +13 -2 V +12 0 V +12 -1 V +13 -1 V +12 -1 V +12 -1 V +13 0 V +12 -1 V +12 0 V +13 0 V +12 -1 V +13 0 V +12 0 V +12 0 V +13 0 V +12 0 V +12 0 V +13 0 V +12 0 V +12 1 V +13 0 V +12 0 V +13 1 V +12 0 V +12 0 V +13 1 V +12 0 V +12 1 V +13 1 V +12 0 V +13 1 V +12 1 V +12 0 V +13 1 V +12 1 V +12 1 V +13 0 V +12 1 V +12 1 V +13 1 V +12 1 V +13 1 V +12 0 V +12 1 V +13 1 V +12 1 V +12 1 V +13 1 V +12 1 V +12 0 V +13 1 V +12 1 V +13 1 V +12 0 V +12 1 V +13 1 V +12 1 V +12 0 V +13 1 V +12 1 V +13 0 V +12 1 V +12 0 V +13 1 V +stroke +3178 2736 M +12 0 V +12 1 V +13 0 V +12 1 V +12 0 V +13 0 V +12 1 V +13 0 V +12 0 V +12 0 V +13 1 V +12 0 V +12 0 V +13 0 V +12 0 V +13 0 V +12 0 V +12 0 V +13 0 V +12 0 V +12 0 V +13 0 V +12 0 V +12 0 V +13 0 V +12 0 V +13 0 V +12 0 V +12 0 V +13 0 V +12 0 V +12 0 V +13 0 V +12 -1 V +12 0 V +13 0 V +12 0 V +13 0 V +12 1 V +12 0 V +13 0 V +12 0 V +12 0 V +13 0 V +12 0 V +13 1 V +12 0 V +12 0 V +13 1 V +12 0 V +12 1 V +13 1 V +12 0 V +12 1 V +13 1 V +12 1 V +13 0 V +12 1 V +12 2 V +13 1 V +12 1 V +12 1 V +13 2 V +12 1 V +13 2 V +12 1 V +12 2 V +13 2 V +12 2 V +12 2 V +13 2 V +12 3 V +12 2 V +13 3 V +12 2 V +13 3 V +12 3 V +12 3 V +13 3 V +12 3 V +12 4 V +13 3 V +12 4 V +12 4 V +13 4 V +12 4 V +13 4 V +12 5 V +12 4 V +13 5 V +12 5 V +12 5 V +13 5 V +12 5 V +13 6 V +12 6 V +12 6 V +13 6 V +12 6 V +12 6 V +13 7 V +12 6 V +12 7 V +13 7 V +stroke +4464 2918 M +12 8 V +13 7 V +12 8 V +12 7 V +13 8 V +12 8 V +12 9 V +13 8 V +12 9 V +12 8 V +13 9 V +12 9 V +13 9 V +12 9 V +12 9 V +13 9 V +12 10 V +12 9 V +13 9 V +12 10 V +13 9 V +12 9 V +12 9 V +13 9 V +12 9 V +12 8 V +13 8 V +12 8 V +12 8 V +13 7 V +12 7 V +13 6 V +12 6 V +12 6 V +13 4 V +12 5 V +12 3 V +13 3 V +12 3 V +13 1 V +12 1 V +12 1 V +13 0 V +12 -1 V +12 -1 V +13 -2 V +12 -2 V +12 -3 V +13 -4 V +12 -3 V +13 -4 V +12 -5 V +12 -4 V +13 -5 V +12 -5 V +12 -5 V +13 -5 V +12 -6 V +12 -5 V +13 -6 V +12 -5 V +13 -6 V +12 -5 V +12 -5 V +13 -5 V +12 -6 V +12 -5 V +13 -5 V +12 -4 V +13 -5 V +12 -4 V +12 -5 V +13 -4 V +12 -4 V +12 -4 V +13 -3 V +12 -4 V +12 -3 V +13 -3 V +12 -3 V +13 -3 V +12 -3 V +12 -2 V +13 -2 V +12 -2 V +12 -2 V +13 -2 V +12 -2 V +13 -1 V +12 -2 V +12 -1 V +13 -1 V +12 -1 V +12 -1 V +13 -1 V +12 0 V +12 -1 V +13 -1 V +12 0 V +13 -1 V +12 0 V +12 0 V +13 -1 V +12 0 V +stroke +5750 3036 M +12 0 V +13 -1 V +12 0 V +12 0 V +13 -1 V +12 0 V +13 -1 V +12 0 V +12 -1 V +13 -1 V +12 0 V +12 -1 V +13 -1 V +12 -2 V +13 -1 V +12 -1 V +12 -2 V +13 -1 V +12 -2 V +12 -2 V +13 -2 V +12 -3 V +12 -2 V +13 -3 V +12 -2 V +13 -3 V +12 -3 V +12 -3 V +13 -4 V +12 -3 V +12 -4 V +13 -3 V +12 -4 V +12 -4 V +13 -4 V +12 -4 V +13 -4 V +12 -4 V +12 -5 V +13 -4 V +12 -4 V +12 -5 V +13 -4 V +12 -5 V +13 -4 V +12 -5 V +12 -5 V +13 -4 V +12 -5 V +12 -4 V +13 -5 V +12 -4 V +12 -4 V +13 -5 V +12 -4 V +13 -4 V +12 -5 V +12 -4 V +13 -4 V +12 -4 V +12 -4 V +13 -4 V +12 -4 V +13 -3 V +12 -4 V +12 -4 V +13 -3 V +12 -3 V +12 -4 V +13 -3 V +12 -3 V +12 -3 V +13 -3 V +12 -3 V +13 -2 V +12 -3 V +12 -2 V +13 -3 V +12 -2 V +12 -2 V +13 -2 V +12 -2 V +12 -2 V +13 -1 V +12 -2 V +13 -1 V +12 -2 V +12 -1 V +13 -1 V +12 -1 V +12 -1 V +13 -1 V +12 0 V +13 -1 V +12 0 V +12 0 V +13 -1 V +1.000 UL +LTb +630 420 M +6332 0 V +0 4452 V +-6332 0 V +630 420 L +1.000 UP +stroke +grestore +end +showpage +%%Trailer +%%DocumentFonts: Helvetica diff --git a/src/libs/speexdsp/doc/rtp.txt b/src/libs/speexdsp/doc/rtp.txt new file mode 100644 index 00000000..1c251530 --- /dev/null +++ b/src/libs/speexdsp/doc/rtp.txt @@ -0,0 +1,76 @@ +The Speex RTP payload is defined as a header, followed by any number of +requests to the remote encoder and all encoded speech frames. + ++--------+----------+----------------+ +| Header | Requests | Speech data... | ++--------+----------+----------------+ + +The header contains only the number of frames sent +encoded in 6 bits + + 0 1 2 3 4 5 ++-+-+-+-+-+-+ +| NB frames | ++-+-+-+-+-+-+ + +There can be any number of requests of the form + + 0 1 2 3 4 5 6 7 0 1 ++-+-+-+-+-+-+-+-+-+-+ +|R| ReqID | ReqVal | ++-+-+-+-+-+-+-+-+-+-+ + +where R is 1 when a request is following and 0 when there is no more +request. Each request (if R=1) is composed of a 4-bit request ID (ReqID) and +a 5-bit value (ReqVal) + +Possible values for ReqID are: + 0: REQ_PERSIST ReqVal=1 for persistent requests/mode selection, + 0 otherwise + 1: PERSIST_ACK Acknowledge a REQ_PERSIST from the other end, + ReqVal equals the value received + 2: MODE Choose the encoder mode directly + 3: QUALITY Choose the encoder quality + 4: VBR Set VBR on (ReqVal=1) or off (ReqVal=2) + 5: VBR_QUALITY Set the encoder quality for VBR mode + 6: LOW_MODE Set the encoder mode for low-band (wideband only) + 7: HIGH_MODE Set the encoder mode for high-band (wideband only) + +All requests should be considered at the receiver as a suggestion and +compliance is not mandatory. The PERSIST_ACK should be sent upon receiving a +REQ_PERSIST request to indicate that the request has been received. + +The speech data part contains speech frames one after the other. The size of +the encoded frames can be found since the mode is directly encoded into each +frame. + +For example, a frame where we request VBR to be on with quality 8 and we +transmit two frames encoded at 8.35 kbps (167 bits/frame) will be: + + 0 1 2 3 + 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| NB=2 |1|ReqID=2| ReqVal=0|1|ReqID=3|ReqVal=8 |0| frame 1 | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| frame 1 | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| frame 1 | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| frame 1 | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| frame 1 | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| frame 1 | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +|end| frame 2 | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| frame 2 | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| frame 2 | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| frame 2 | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| frame 2 | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| end frame 2 |P|P|P|P|P|P| ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ diff --git a/src/libs/speexdsp/doc/sampledec.c b/src/libs/speexdsp/doc/sampledec.c new file mode 100644 index 00000000..2878c472 --- /dev/null +++ b/src/libs/speexdsp/doc/sampledec.c @@ -0,0 +1,65 @@ +#include <speex/speex.h> +#include <stdio.h> + +/*The frame size in hardcoded for this sample code but it doesn't have to be*/ +#define FRAME_SIZE 160 +int main(int argc, char **argv) +{ + char *outFile; + FILE *fout; + /*Holds the audio that will be written to file (16 bits per sample)*/ + short out[FRAME_SIZE]; + /*Speex handle samples as float, so we need an array of floats*/ + float output[FRAME_SIZE]; + char cbits[200]; + int nbBytes; + /*Holds the state of the decoder*/ + void *state; + /*Holds bits so they can be read and written to by the Speex routines*/ + SpeexBits bits; + int i, tmp; + + /*Create a new decoder state in narrowband mode*/ + state = speex_decoder_init(&speex_nb_mode); + + /*Set the perceptual enhancement on*/ + tmp=1; + speex_decoder_ctl(state, SPEEX_SET_ENH, &tmp); + + outFile = argv[1]; + fout = fopen(outFile, "w"); + + /*Initialization of the structure that holds the bits*/ + speex_bits_init(&bits); + while (1) + { + /*Read the size encoded by sampleenc, this part will likely be + different in your application*/ + fread(&nbBytes, sizeof(int), 1, stdin); + fprintf (stderr, "nbBytes: %d\n", nbBytes); + if (feof(stdin)) + break; + + /*Read the "packet" encoded by sampleenc*/ + fread(cbits, 1, nbBytes, stdin); + /*Copy the data into the bit-stream struct*/ + speex_bits_read_from(&bits, cbits, nbBytes); + + /*Decode the data*/ + speex_decode(state, &bits, output); + + /*Copy from float to short (16 bits) for output*/ + for (i=0;i<FRAME_SIZE;i++) + out[i]=output[i]; + + /*Write the decoded audio to file*/ + fwrite(out, sizeof(short), FRAME_SIZE, fout); + } + + /*Destroy the decoder state*/ + speex_decoder_destroy(state); + /*Destroy the bit-stream truct*/ + speex_bits_destroy(&bits); + fclose(fout); + return 0; +} diff --git a/src/libs/speexdsp/doc/sampleenc.c b/src/libs/speexdsp/doc/sampleenc.c new file mode 100644 index 00000000..d508181f --- /dev/null +++ b/src/libs/speexdsp/doc/sampleenc.c @@ -0,0 +1,64 @@ +#include <speex/speex.h> +#include <stdio.h> + +/*The frame size in hardcoded for this sample code but it doesn't have to be*/ +#define FRAME_SIZE 160 +int main(int argc, char **argv) +{ + char *inFile; + FILE *fin; + short in[FRAME_SIZE]; + float input[FRAME_SIZE]; + char cbits[200]; + int nbBytes; + /*Holds the state of the encoder*/ + void *state; + /*Holds bits so they can be read and written to by the Speex routines*/ + SpeexBits bits; + int i, tmp; + + /*Create a new encoder state in narrowband mode*/ + state = speex_encoder_init(&speex_nb_mode); + + /*Set the quality to 8 (15 kbps)*/ + tmp=8; + speex_encoder_ctl(state, SPEEX_SET_QUALITY, &tmp); + + inFile = argv[1]; + fin = fopen(inFile, "r"); + + /*Initialization of the structure that holds the bits*/ + speex_bits_init(&bits); + while (1) + { + /*Read a 16 bits/sample audio frame*/ + fread(in, sizeof(short), FRAME_SIZE, fin); + if (feof(fin)) + break; + /*Copy the 16 bits values to float so Speex can work on them*/ + for (i=0;i<FRAME_SIZE;i++) + input[i]=in[i]; + + /*Flush all the bits in the struct so we can encode a new frame*/ + speex_bits_reset(&bits); + + /*Encode the frame*/ + speex_encode(state, input, &bits); + /*Copy the bits to an array of char that can be written*/ + nbBytes = speex_bits_write(&bits, cbits, 200); + + /*Write the size of the frame first. This is what sampledec expects but + it's likely to be different in your own application*/ + fwrite(&nbBytes, sizeof(int), 1, stdout); + /*Write the compressed data*/ + fwrite(cbits, 1, nbBytes, stdout); + + } + + /*Destroy the encoder state*/ + speex_encoder_destroy(state); + /*Destroy the bit-packing struct*/ + speex_bits_destroy(&bits); + fclose(fin); + return 0; +} diff --git a/src/libs/speexdsp/doc/speex_abs.eps b/src/libs/speexdsp/doc/speex_abs.eps new file mode 100644 index 00000000..079c0719 --- /dev/null +++ b/src/libs/speexdsp/doc/speex_abs.eps @@ -0,0 +1,3022 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 437 624 +%%Pages: 0 +%%Creator: Sun Microsystems, Inc. +%%Title: none +%%CreationDate: none +%%LanguageLevel: 2 +%%EndComments +%%BeginProlog +%%BeginResource: SDRes +/b4_inc_state save def +/dict_count countdictstack def +/op_count count 1 sub def +userdict begin +0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath +/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if +/bdef {bind def} bind def +/c {setgray} bdef +/l {neg lineto} bdef +/rl {neg rlineto} bdef +/lc {setlinecap} bdef +/lj {setlinejoin} bdef +/lw {setlinewidth} bdef +/ml {setmiterlimit} bdef +/ld {setdash} bdef +/m {neg moveto} bdef +/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef +/r {rotate} bdef +/t {neg translate} bdef +/s {scale} bdef +/sw {show} bdef +/gs {gsave} bdef +/gr {grestore} bdef +/f {findfont dup length dict begin +{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def +currentdict end /NFont exch definefont pop /NFont findfont} bdef +/p {closepath} bdef +/sf {scalefont setfont} bdef +/ef {eofill}bdef +/pc {closepath stroke}bdef +/ps {stroke}bdef +/pum {matrix currentmatrix}bdef +/pom {setmatrix}bdef +/bs {/aString exch def /nXOfs exch def /nWidth exch def currentpoint nXOfs 0 rmoveto pum nWidth aString stringwidth pop div 1 scale aString show pom moveto} bdef +%%EndResource +%%EndProlog +%%BeginSetup +%%EndSetup +%%Page: 1 1 +%%BeginPageSetup +%%EndPageSetup +pum +0.02834 0.02834 s +0 -22011 t +/tm matrix currentmatrix def +tm setmatrix +-2435 -3035 t +1 1 s +50 lw 1 lj 0.000 c 4385 7335 m 3135 7335 l 3135 5835 l 5635 5835 l 5635 7335 l +4385 7335 l pc +4385 10135 m 3971 10135 3635 9799 3635 9385 ct 3635 8971 3971 8635 4385 8635 ct +4799 8635 5135 8971 5135 9385 ct 5135 9799 4799 10135 4385 10135 ct pc +gs +gs +pum +4102 9722 t +246 -115 m 246 -309 l 54 -309 l 54 -390 l 246 -390 l 246 -582 l 328 -582 l +328 -390 l 520 -390 l 520 -309 l 328 -309 l 328 -115 l 246 -115 l +p ef +pom +gr +gr +gs +gs +pum +3626 3671 t +181 -260 m 181 -260 181 -260 181 -174 ct 181 -174 181 -174 171 -174 ct 164 -201 155 -220 145 -229 ct +134 -239 120 -244 103 -244 ct 91 -244 80 -241 73 -234 ct 65 -227 61 -219 61 -211 ct +61 -201 64 -192 70 -185 ct 75 -177 87 -169 104 -161 ct 104 -161 104 -161 144 -141 ct +181 -123 200 -99 200 -69 ct 200 -47 191 -28 174 -14 ct 157 0 138 7 116 7 ct 101 7 83 4 64 -1 ct +58 -2 53 -3 49 -3 ct 45 -3 41 -1 39 3 ct 39 3 39 3 29 3 ct 29 3 29 3 29 -87 ct 29 -87 29 -87 39 -87 ct +44 -61 54 -42 68 -29 ct 83 -16 99 -9 116 -9 ct 129 -9 139 -13 147 -20 ct 155 -28 159 -37 159 -47 ct +159 -60 155 -70 146 -79 ct 137 -88 119 -98 93 -111 ct 66 -124 48 -136 40 -147 ct +32 -157 28 -171 28 -187 ct 28 -208 35 -225 49 -239 ct 63 -253 82 -260 104 -260 ct +114 -260 126 -258 140 -254 ct 149 -251 155 -250 158 -250 ct 161 -250 164 -251 165 -252 ct +167 -253 169 -256 171 -260 ct 171 -260 171 -260 181 -260 ct p ef +220 -228 m 220 -228 220 -228 298 -259 ct 298 -259 298 -259 309 -259 ct 309 -259 309 -259 309 -201 ct +322 -223 335 -238 348 -247 ct 361 -256 375 -260 389 -260 ct 414 -260 435 -250 452 -230 ct +473 -206 483 -175 483 -136 ct 483 -92 471 -56 446 -28 ct 425 -5 400 7 369 7 ct +355 7 343 5 334 1 ct 326 -2 318 -7 309 -16 ct 309 -16 309 -16 309 63 ct 309 80 310 91 312 96 ct +314 100 318 104 323 107 ct 329 110 338 111 352 111 ct 352 111 352 111 352 121 ct +352 121 352 121 217 121 ct 217 121 217 121 217 111 ct 217 111 217 111 224 111 ct +234 111 243 109 251 105 ct 254 103 257 100 259 95 ct 261 91 262 79 262 61 ct 262 61 262 61 262 -179 ct +262 -195 261 -205 260 -209 ct 258 -213 256 -216 253 -219 ct 250 -221 245 -222 240 -222 ct +236 -222 230 -221 223 -218 ct 223 -218 223 -218 220 -228 ct p +309 -185 m 309 -185 309 -185 309 -90 ct 309 -70 310 -57 311 -50 ct 314 -40 320 -30 330 -22 ct +340 -14 353 -10 368 -10 ct 386 -10 401 -17 412 -31 ct 427 -50 434 -77 434 -111 ct +434 -149 426 -179 409 -200 ct 397 -214 383 -221 367 -221 ct 359 -221 350 -219 341 -214 ct +335 -211 324 -201 309 -185 ct p ef +564 -158 m 564 -121 573 -92 591 -71 ct 609 -50 630 -39 655 -39 ct 671 -39 686 -43 698 -52 ct +710 -61 720 -77 728 -99 ct 728 -99 728 -99 737 -94 ct 733 -68 722 -45 703 -24 ct +685 -3 662 7 634 7 ct 604 7 578 -5 556 -28 ct 535 -52 524 -83 524 -123 ct 524 -166 535 -200 557 -224 ct +579 -248 607 -260 640 -260 ct 668 -260 692 -251 710 -232 ct 728 -214 737 -189 737 -158 ct +737 -158 737 -158 564 -158 ct p +564 -174 m 564 -174 564 -174 680 -174 ct 679 -190 677 -201 674 -208 ct 670 -218 663 -226 654 -231 ct +645 -237 635 -240 626 -240 ct 610 -240 597 -234 585 -223 ct 573 -211 566 -195 564 -174 ct +p ef +814 -158 m 814 -121 823 -92 841 -71 ct 859 -50 880 -39 905 -39 ct 921 -39 936 -43 948 -52 ct +960 -61 970 -77 978 -99 ct 978 -99 978 -99 987 -94 ct 983 -68 972 -45 953 -24 ct +935 -3 912 7 884 7 ct 854 7 828 -5 806 -28 ct 785 -52 774 -83 774 -123 ct 774 -166 785 -200 807 -224 ct +829 -248 857 -260 890 -260 ct 918 -260 942 -251 960 -232 ct 978 -214 987 -189 987 -158 ct +987 -158 987 -158 814 -158 ct p +814 -174 m 814 -174 814 -174 930 -174 ct 929 -190 927 -201 924 -208 ct 920 -218 913 -226 904 -231 ct +895 -237 885 -240 876 -240 ct 860 -240 847 -234 835 -223 ct 823 -211 816 -195 814 -174 ct +p ef +1236 -95 m 1229 -62 1216 -37 1196 -19 ct 1176 -2 1154 7 1130 7 ct 1101 7 1076 -5 1055 -29 ct +1034 -53 1023 -85 1023 -126 ct 1023 -166 1035 -198 1058 -223 ct 1082 -248 1111 -260 1144 -260 ct +1169 -260 1189 -253 1205 -240 ct 1221 -227 1229 -214 1229 -199 ct 1229 -192 1227 -187 1222 -182 ct +1218 -178 1211 -176 1203 -176 ct 1193 -176 1185 -180 1179 -187 ct 1176 -190 1174 -198 1173 -209 ct +1172 -220 1168 -228 1161 -234 ct 1155 -239 1146 -242 1135 -242 ct 1116 -242 1102 -235 1090 -222 ct +1075 -204 1068 -180 1068 -150 ct 1068 -120 1075 -94 1090 -71 ct 1105 -48 1125 -36 1150 -36 ct +1168 -36 1184 -42 1199 -54 ct 1209 -62 1218 -77 1228 -99 ct 1228 -99 1228 -99 1236 -95 ct +p ef +1345 -392 m 1345 -392 1345 -392 1345 -208 ct 1365 -230 1381 -244 1393 -251 ct +1405 -257 1417 -260 1429 -260 ct 1443 -260 1456 -256 1466 -248 ct 1476 -240 1484 -228 1489 -211 ct +1492 -199 1494 -178 1494 -146 ct 1494 -146 1494 -146 1494 -57 ct 1494 -41 1495 -30 1498 -24 ct +1500 -20 1503 -16 1507 -14 ct 1511 -11 1519 -10 1531 -10 ct 1531 -10 1531 -10 1531 0 ct +1531 0 1531 0 1407 0 ct 1407 0 1407 0 1407 -10 ct 1407 -10 1407 -10 1413 -10 ct +1425 -10 1433 -12 1437 -15 ct 1442 -19 1445 -24 1447 -31 ct 1448 -34 1448 -43 1448 -57 ct +1448 -57 1448 -57 1448 -147 ct 1448 -174 1447 -192 1444 -201 ct 1441 -210 1436 -216 1430 -221 ct +1424 -225 1417 -227 1408 -227 ct 1399 -227 1389 -225 1380 -220 ct 1370 -215 1359 -205 1345 -191 ct +1345 -191 1345 -191 1345 -57 ct 1345 -40 1346 -29 1348 -25 ct 1350 -21 1353 -17 1359 -14 ct +1364 -11 1373 -10 1386 -10 ct 1386 -10 1386 -10 1386 0 ct 1386 0 1386 0 1262 0 ct +1262 0 1262 0 1262 -10 ct 1273 -10 1281 -12 1287 -15 ct 1291 -17 1294 -21 1296 -26 ct +1298 -31 1299 -41 1299 -57 ct 1299 -57 1299 -57 1299 -286 ct 1299 -314 1298 -332 1297 -338 ct +1296 -345 1294 -349 1291 -352 ct 1288 -354 1284 -355 1279 -355 ct 1276 -355 1269 -354 1261 -351 ct +1261 -351 1261 -351 1257 -361 ct 1257 -361 1257 -361 1332 -392 ct 1332 -392 1332 -392 1345 -392 ct +p ef +pom +gr +gs +pum +3255 4298 t +181 -260 m 181 -260 181 -260 181 -174 ct 181 -174 181 -174 171 -174 ct 164 -201 155 -220 145 -229 ct +134 -239 120 -244 103 -244 ct 91 -244 80 -241 73 -234 ct 65 -227 61 -219 61 -211 ct +61 -201 64 -192 70 -185 ct 75 -177 87 -169 104 -161 ct 104 -161 104 -161 144 -141 ct +181 -123 200 -99 200 -69 ct 200 -47 191 -28 174 -14 ct 157 0 138 7 116 7 ct 101 7 83 4 64 -1 ct +58 -2 53 -3 49 -3 ct 45 -3 41 -1 39 3 ct 39 3 39 3 29 3 ct 29 3 29 3 29 -87 ct 29 -87 29 -87 39 -87 ct +44 -61 54 -42 68 -29 ct 83 -16 99 -9 116 -9 ct 129 -9 139 -13 147 -20 ct 155 -28 159 -37 159 -47 ct +159 -60 155 -70 146 -79 ct 137 -88 119 -98 93 -111 ct 66 -124 48 -136 40 -147 ct +32 -157 28 -171 28 -187 ct 28 -208 35 -225 49 -239 ct 63 -253 82 -260 104 -260 ct +114 -260 126 -258 140 -254 ct 149 -251 155 -250 158 -250 ct 161 -250 164 -251 165 -252 ct +167 -253 169 -256 171 -260 ct 171 -260 171 -260 181 -260 ct p ef +459 -253 m 459 -253 459 -253 459 -99 ct 459 -70 460 -53 461 -47 ct 462 -40 465 -36 468 -33 ct +471 -31 474 -29 478 -29 ct 484 -29 490 -31 497 -34 ct 497 -34 497 -34 501 -24 ct +501 -24 501 -24 426 7 ct 426 7 426 7 414 7 ct 414 7 414 7 414 -46 ct 392 -23 376 -8 364 -2 ct +353 4 341 7 328 7 ct 314 7 301 3 291 -5 ct 280 -14 273 -24 269 -37 ct 265 -50 263 -68 263 -92 ct +263 -92 263 -92 263 -205 ct 263 -217 262 -225 259 -229 ct 257 -234 253 -237 248 -240 ct +243 -242 233 -243 220 -243 ct 220 -243 220 -243 220 -253 ct 220 -253 220 -253 309 -253 ct +309 -253 309 -253 309 -84 ct 309 -60 313 -44 321 -37 ct 330 -30 339 -26 351 -26 ct +359 -26 368 -28 378 -33 ct 388 -38 400 -48 414 -62 ct 414 -62 414 -62 414 -205 ct +414 -220 411 -230 406 -235 ct 401 -240 390 -243 373 -243 ct 373 -243 373 -243 373 -253 ct +373 -253 373 -253 459 -253 ct p ef +591 -209 m 615 -243 642 -260 670 -260 ct 696 -260 718 -249 737 -227 ct 756 -205 766 -175 766 -136 ct +766 -92 751 -56 721 -28 ct 696 -5 667 7 636 7 ct 621 7 607 4 591 -1 ct 576 -6 561 -14 545 -25 ct +545 -25 545 -25 545 -286 ct 545 -314 544 -332 543 -338 ct 542 -345 539 -349 536 -352 ct +533 -354 530 -355 525 -355 ct 520 -355 514 -354 506 -351 ct 506 -351 506 -351 502 -361 ct +502 -361 502 -361 578 -392 ct 578 -392 578 -392 591 -392 ct 591 -392 591 -392 591 -209 ct +p +591 -192 m 591 -192 591 -192 591 -41 ct 600 -32 610 -25 620 -20 ct 630 -15 640 -13 650 -13 ct +667 -13 682 -22 697 -41 ct 711 -59 718 -86 718 -121 ct 718 -153 711 -178 697 -195 ct +682 -212 666 -221 648 -221 ct 638 -221 629 -219 619 -214 ct 612 -210 602 -203 591 -192 ct +p ef +810 -148 m 953 -148 l 953 -106 l 810 -106 l 810 -148 l p ef +1091 -233 m 1091 -233 1091 -233 1091 -67 ct 1091 -43 1094 -28 1099 -22 ct 1106 -14 1115 -10 1126 -10 ct +1126 -10 1126 -10 1149 -10 ct 1149 -10 1149 -10 1149 0 ct 1149 0 1149 0 998 0 ct +998 0 998 0 998 -10 ct 998 -10 998 -10 1009 -10 ct 1017 -10 1023 -12 1029 -16 ct +1035 -19 1039 -24 1042 -30 ct 1044 -37 1045 -49 1045 -67 ct 1045 -67 1045 -67 1045 -233 ct +1045 -233 1045 -233 996 -233 ct 996 -233 996 -233 996 -253 ct 996 -253 996 -253 1045 -253 ct +1045 -253 1045 -253 1045 -270 ct 1045 -295 1049 -316 1057 -334 ct 1065 -351 1078 -365 1094 -376 ct +1111 -387 1130 -392 1151 -392 ct 1170 -392 1188 -386 1204 -373 ct 1215 -365 1220 -355 1220 -345 ct +1220 -340 1218 -334 1213 -329 ct 1208 -324 1203 -322 1197 -322 ct 1193 -322 1189 -324 1184 -327 ct +1179 -330 1174 -336 1167 -346 ct 1160 -356 1154 -363 1148 -367 ct 1142 -370 1136 -372 1129 -372 ct +1121 -372 1113 -370 1108 -365 ct 1102 -361 1097 -354 1095 -344 ct 1092 -335 1091 -310 1091 -271 ct +1091 -271 1091 -271 1091 -253 ct 1091 -253 1091 -253 1156 -253 ct 1156 -253 1156 -253 1156 -233 ct +1156 -233 1156 -233 1091 -233 ct p ef +1256 -260 m 1256 -260 1256 -260 1256 -203 ct 1277 -241 1299 -260 1321 -260 ct +1331 -260 1339 -257 1346 -251 ct 1353 -245 1356 -238 1356 -230 ct 1356 -222 1354 -216 1349 -211 ct +1344 -206 1338 -204 1332 -204 ct 1325 -204 1318 -207 1310 -214 ct 1302 -220 1296 -223 1292 -223 ct +1289 -223 1285 -221 1282 -217 ct 1273 -210 1265 -198 1256 -180 ct 1256 -180 1256 -180 1256 -59 ct +1256 -45 1258 -34 1261 -27 ct 1264 -22 1268 -18 1274 -15 ct 1280 -12 1289 -10 1301 -10 ct +1301 -10 1301 -10 1301 0 ct 1301 0 1301 0 1169 0 ct 1169 0 1169 0 1169 -10 ct 1182 -10 1192 -12 1199 -16 ct +1203 -19 1207 -24 1209 -30 ct 1210 -33 1210 -42 1210 -57 ct 1210 -57 1210 -57 1210 -154 ct +1210 -184 1209 -201 1208 -207 ct 1207 -213 1205 -217 1202 -219 ct 1199 -222 1195 -223 1190 -223 ct +1184 -223 1178 -222 1171 -219 ct 1171 -219 1171 -219 1168 -229 ct 1168 -229 1168 -229 1244 -260 ct +1244 -260 1244 -260 1256 -260 ct p ef +1511 -37 m 1485 -17 1469 -5 1462 -2 ct 1452 3 1442 5 1430 5 ct 1413 5 1398 -1 1387 -13 ct +1376 -25 1370 -40 1370 -60 ct 1370 -72 1373 -83 1378 -92 ct 1386 -104 1399 -116 1418 -127 ct +1436 -138 1468 -151 1511 -167 ct 1511 -167 1511 -167 1511 -177 ct 1511 -202 1507 -219 1499 -228 ct +1491 -237 1480 -242 1464 -242 ct 1453 -242 1444 -239 1437 -233 ct 1430 -226 1426 -219 1426 -211 ct +1426 -211 1426 -211 1427 -195 ct 1427 -187 1425 -180 1420 -176 ct 1416 -171 1410 -169 1403 -169 ct +1397 -169 1391 -171 1387 -176 ct 1382 -181 1380 -188 1380 -196 ct 1380 -212 1388 -227 1404 -240 ct +1420 -253 1443 -260 1472 -260 ct 1494 -260 1513 -256 1527 -249 ct 1538 -243 1546 -234 1551 -222 ct +1554 -214 1556 -198 1556 -174 ct 1556 -174 1556 -174 1556 -89 ct 1556 -65 1556 -50 1557 -45 ct +1558 -39 1560 -36 1562 -34 ct 1564 -32 1566 -31 1569 -31 ct 1572 -31 1575 -32 1577 -33 ct +1581 -35 1588 -42 1599 -53 ct 1599 -53 1599 -53 1599 -38 ct 1579 -10 1559 4 1541 4 ct +1532 4 1524 1 1519 -5 ct 1514 -11 1511 -22 1511 -37 ct p +1511 -54 m 1511 -54 1511 -54 1511 -149 ct 1483 -138 1465 -130 1457 -126 ct +1442 -118 1432 -110 1425 -101 ct 1419 -92 1416 -83 1416 -72 ct 1416 -59 1420 -49 1428 -40 ct +1436 -31 1445 -27 1455 -27 ct 1470 -27 1488 -36 1511 -54 ct p ef +1693 -206 m 1711 -225 1722 -235 1725 -238 ct 1734 -245 1742 -250 1752 -254 ct +1762 -258 1771 -260 1780 -260 ct 1796 -260 1810 -255 1821 -246 ct 1832 -237 1840 -224 1844 -206 ct +1863 -228 1879 -243 1892 -250 ct 1905 -257 1918 -260 1932 -260 ct 1945 -260 1957 -257 1967 -250 ct +1978 -243 1986 -232 1992 -216 ct 1996 -205 1998 -188 1998 -166 ct 1998 -166 1998 -166 1998 -57 ct +1998 -41 1999 -30 2001 -25 ct 2003 -21 2007 -17 2011 -14 ct 2016 -11 2024 -10 2035 -10 ct +2035 -10 2035 -10 2035 0 ct 2035 0 2035 0 1911 0 ct 1911 0 1911 0 1911 -10 ct 1911 -10 1911 -10 1916 -10 ct +1927 -10 1936 -12 1942 -16 ct 1946 -19 1949 -24 1951 -30 ct 1952 -33 1952 -42 1952 -57 ct +1952 -57 1952 -57 1952 -166 ct 1952 -186 1950 -201 1945 -209 ct 1937 -221 1926 -227 1910 -227 ct +1901 -227 1891 -225 1881 -220 ct 1871 -215 1859 -206 1846 -193 ct 1846 -193 1846 -193 1845 -189 ct +1845 -189 1845 -189 1846 -178 ct 1846 -178 1846 -178 1846 -57 ct 1846 -40 1847 -29 1849 -25 ct +1851 -21 1854 -17 1860 -14 ct 1865 -11 1874 -10 1887 -10 ct 1887 -10 1887 -10 1887 0 ct +1887 0 1887 0 1759 0 ct 1759 0 1759 0 1759 -10 ct 1773 -10 1783 -12 1788 -15 ct +1793 -18 1797 -23 1799 -30 ct 1800 -33 1800 -42 1800 -57 ct 1800 -57 1800 -57 1800 -166 ct +1800 -186 1797 -201 1791 -210 ct 1783 -221 1772 -227 1757 -227 ct 1747 -227 1738 -224 1728 -219 ct +1713 -211 1701 -202 1693 -193 ct 1693 -193 1693 -193 1693 -57 ct 1693 -41 1694 -30 1696 -25 ct +1699 -20 1702 -16 1707 -14 ct 1711 -11 1720 -10 1734 -10 ct 1734 -10 1734 -10 1734 0 ct +1734 0 1734 0 1610 0 ct 1610 0 1610 0 1610 -10 ct 1621 -10 1629 -11 1633 -14 ct +1638 -16 1641 -20 1644 -26 ct 1646 -31 1647 -41 1647 -57 ct 1647 -57 1647 -57 1647 -154 ct +1647 -182 1646 -199 1645 -207 ct 1643 -213 1641 -217 1639 -220 ct 1636 -222 1632 -223 1627 -223 ct +1622 -223 1616 -222 1609 -219 ct 1609 -219 1609 -219 1605 -229 ct 1605 -229 1605 -229 1681 -260 ct +1681 -260 1681 -260 1693 -260 ct 1693 -260 1693 -260 1693 -206 ct p ef +2088 -158 m 2088 -121 2097 -92 2115 -71 ct 2133 -50 2154 -39 2179 -39 ct 2195 -39 2210 -43 2222 -52 ct +2234 -61 2244 -77 2252 -99 ct 2252 -99 2252 -99 2261 -94 ct 2257 -68 2246 -45 2227 -24 ct +2209 -3 2186 7 2158 7 ct 2128 7 2102 -5 2080 -28 ct 2059 -52 2048 -83 2048 -123 ct +2048 -166 2059 -200 2081 -224 ct 2103 -248 2131 -260 2164 -260 ct 2192 -260 2216 -251 2234 -232 ct +2252 -214 2261 -189 2261 -158 ct 2261 -158 2261 -158 2088 -158 ct p +2088 -174 m 2088 -174 2088 -174 2204 -174 ct 2203 -190 2201 -201 2198 -208 ct +2194 -218 2187 -226 2178 -231 ct 2169 -237 2159 -240 2150 -240 ct 2134 -240 2121 -234 2109 -223 ct +2097 -211 2090 -195 2088 -174 ct p ef +pom +gr +gr +4385 5835 m 4198 5273 l 4573 5273 l 4385 5835 l p ef +4410 4535 m 4410 5385 l 4360 5385 l 4360 4535 l 4410 4535 l p ef +4384 8635 m 4197 8073 l 4572 8073 l 4384 8635 l p ef +4410 7335 m 4410 7985 l 4385 7985 l 4360 7985 l 4360 7335 l 4385 7335 l +4410 7335 l p ef +4385 7985 m 4410 7985 l 4410 7989 l 4408 7994 l 4407 7997 l 4404 8001 l +4401 8004 l 4398 8007 l 4394 8008 l 4389 8010 l 4385 8010 l 4385 8010 l +4385 7985 l p ef +4385 8010 m 4384 8010 l 4384 7985 l 4384 7960 l 4385 7960 l 4385 7985 l +4385 8010 l p ef +4384 7985 m 4359 7985 l 4359 7981 l 4361 7976 l 4362 7973 l 4365 7969 l +4368 7966 l 4371 7963 l 4375 7962 l 4380 7960 l 4384 7960 l 4384 7960 l +4384 7985 l p ef +4409 7985 m 4409 8185 l 4384 8185 l 4359 8185 l 4359 7985 l 4384 7985 l +4409 7985 l p ef +gs +7170 8666 m 8954 8666 l 8954 10294 l 7170 10294 l 7170 8666 l eoclip newpath +gs +tm setmatrix +4736 5636 t +1 1 s +gs +gs +0 0 m 1784 0 l 1784 1628 l 0 1628 l 0 0 l eoclip newpath +gs +pum +159 556 t +86 9 m 86 9 86 9 122 -341 ct 124 -355 124 -365 124 -373 ct 124 -385 121 -394 114 -400 ct +107 -406 95 -410 77 -410 ct 77 -410 77 -410 81 -421 ct 81 -421 81 -421 237 -421 ct +237 -421 237 -421 234 -410 ct 213 -410 198 -406 191 -399 ct 183 -391 177 -372 175 -341 ct +175 -341 175 -341 151 -113 ct 151 -113 151 -113 311 -361 ct 311 -365 311 -369 311 -371 ct +311 -383 308 -392 301 -398 ct 294 -405 279 -409 257 -410 ct 257 -410 257 -410 259 -421 ct +259 -421 259 -421 430 -421 ct 430 -421 430 -421 426 -410 ct 407 -410 393 -408 387 -405 ct +382 -403 377 -399 374 -394 ct 371 -389 368 -380 366 -368 ct 365 -364 363 -340 358 -296 ct +354 -251 347 -190 338 -113 ct 338 -113 338 -113 472 -317 ct 486 -339 496 -354 499 -363 ct +503 -372 505 -380 505 -386 ct 505 -392 502 -397 497 -401 ct 492 -406 484 -409 472 -410 ct +472 -410 472 -410 474 -421 ct 474 -421 474 -421 599 -421 ct 599 -421 599 -421 596 -410 ct +585 -409 575 -406 567 -402 ct 558 -397 548 -389 537 -376 ct 530 -368 516 -349 496 -317 ct +496 -317 496 -317 284 9 ct 284 9 284 9 273 9 ct 273 9 273 9 307 -317 ct 307 -317 307 -317 97 9 ct +97 9 97 9 86 9 ct p ef +pom +gr +gs +pum +847 556 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1138 556 t +54 -273 m 54 -273 54 -273 249 -273 ct 249 -273 249 -273 249 -265 ct 249 -265 249 -265 35 -42 ct +35 -42 35 -42 125 -42 ct 147 -42 161 -43 166 -44 ct 172 -46 178 -50 183 -55 ct +187 -60 193 -70 199 -84 ct 199 -84 199 -84 210 -84 ct 210 -84 210 -84 183 0 ct +183 0 183 0 -18 0 ct -18 0 -18 0 -18 -9 ct -18 -9 -18 -9 196 -232 ct 196 -232 196 -232 109 -232 ct +90 -232 78 -232 74 -231 ct 68 -229 63 -226 57 -221 ct 51 -216 45 -208 39 -196 ct +39 -196 39 -196 28 -196 ct 28 -196 28 -196 54 -273 ct p ef +pom +gr +gs +pum +1429 556 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gs +132 767 m 1521 0 rl 0 31 rl 1521 neg 0 rl ef p ef + +gr +gs +pum +370 1323 t +208 -345 m 197 -344 l 113 -410 l 25 -342 l 11 -345 l 113 -462 l 208 -345 l +p ef +pom +gr +gs +pum +318 1455 t +328 -430 m 328 -430 328 -430 296 -80 ct 294 -64 294 -53 294 -48 ct 294 -40 295 -33 298 -29 ct +302 -23 307 -18 314 -15 ct 321 -12 332 -11 348 -11 ct 348 -11 348 -11 345 0 ct +345 0 345 0 180 0 ct 180 0 180 0 184 -11 ct 184 -11 184 -11 191 -11 ct 204 -11 215 -14 224 -20 ct +230 -24 234 -30 238 -39 ct 240 -46 242 -61 244 -85 ct 244 -85 244 -85 249 -138 ct +249 -138 249 -138 128 -138 ct 128 -138 128 -138 86 -80 ct 76 -67 70 -57 67 -52 ct +65 -46 64 -41 64 -36 ct 64 -29 66 -24 72 -19 ct 77 -14 86 -11 98 -11 ct 98 -11 98 -11 95 0 ct +95 0 95 0 -30 0 ct -30 0 -30 0 -27 -11 ct -12 -12 2 -17 14 -26 ct 25 -36 43 -57 66 -88 ct +66 -88 66 -88 317 -430 ct 317 -430 317 -430 328 -430 ct p +268 -327 m 144 -159 l 251 -159 l 268 -327 l p ef +pom +gr +gs +pum +767 1455 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1032 1455 t +54 -273 m 54 -273 54 -273 249 -273 ct 249 -273 249 -273 249 -265 ct 249 -265 249 -265 35 -42 ct +35 -42 35 -42 125 -42 ct 147 -42 161 -43 166 -44 ct 172 -46 178 -50 183 -55 ct +187 -60 193 -70 199 -84 ct 199 -84 199 -84 210 -84 ct 210 -84 210 -84 183 0 ct +183 0 183 0 -18 0 ct -18 0 -18 0 -18 -9 ct -18 -9 -18 -9 196 -232 ct 196 -232 196 -232 109 -232 ct +90 -232 78 -232 74 -231 ct 68 -229 63 -226 57 -221 ct 51 -216 45 -208 39 -196 ct +39 -196 39 -196 28 -196 ct 28 -196 28 -196 54 -273 ct p ef +pom +gr +gs +pum +1349 1455 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gr +gr +gr +gr +8085 10285 m 7035 10285 l 7035 8485 l 9135 8485 l 9135 10285 l 8085 10285 l +pc +5135 9384 m 5698 9197 l 5698 9572 l 5135 9384 l p ef +7035 9410 m 6085 9410 l 6085 9385 l 6085 9360 l 7035 9360 l 7035 9385 l +7035 9410 l p ef +6085 9385 m 6085 9410 l 6081 9410 l 6076 9408 l 6073 9407 l 6069 9404 l +6066 9401 l 6063 9398 l 6062 9394 l 6060 9389 l 6060 9385 l 6060 9385 l +6085 9385 l p ef +6060 9385 m 6060 9384 l 6085 9384 l 6110 9384 l 6110 9385 l 6085 9385 l +6060 9385 l p ef +6085 9384 m 6085 9359 l 6089 9359 l 6094 9361 l 6097 9362 l 6101 9365 l +6104 9368 l 6107 9371 l 6108 9375 l 6110 9380 l 6110 9384 l 6110 9384 l +6085 9384 l p ef +6085 9409 m 5585 9409 l 5585 9384 l 5585 9359 l 6085 9359 l 6085 9384 l +6085 9409 l p ef +4385 12536 m 3971 12536 3635 12200 3635 11786 ct 3635 11372 3971 11036 4385 11036 ct +4799 11036 5135 11372 5135 11786 ct 5135 12200 4799 12536 4385 12536 ct pc +gs +gs +pum +4102 12130 t +246 -115 m 246 -309 l 54 -309 l 54 -390 l 246 -390 l 246 -582 l 328 -582 l +328 -390 l 520 -390 l 520 -309 l 328 -309 l 328 -115 l 246 -115 l +p ef +pom +gr +gr +gs +7170 11067 m 8954 11067 l 8954 12695 l 7170 12695 l 7170 11067 l eoclip newpath +gs +tm setmatrix +4736 8043 t +1 1 s +gs +gs +0 0 m 1784 0 l 1784 1628 l 0 1628 l 0 0 l eoclip newpath +gs +pum +159 556 t +86 9 m 86 9 86 9 122 -341 ct 124 -355 124 -365 124 -373 ct 124 -385 121 -394 114 -400 ct +107 -406 95 -410 77 -410 ct 77 -410 77 -410 81 -421 ct 81 -421 81 -421 237 -421 ct +237 -421 237 -421 234 -410 ct 213 -410 198 -406 191 -399 ct 183 -391 177 -372 175 -341 ct +175 -341 175 -341 151 -113 ct 151 -113 151 -113 311 -361 ct 311 -365 311 -369 311 -371 ct +311 -383 308 -392 301 -398 ct 294 -405 279 -409 257 -410 ct 257 -410 257 -410 259 -421 ct +259 -421 259 -421 430 -421 ct 430 -421 430 -421 426 -410 ct 407 -410 393 -408 387 -405 ct +382 -403 377 -399 374 -394 ct 371 -389 368 -380 366 -368 ct 365 -364 363 -340 358 -296 ct +354 -251 347 -190 338 -113 ct 338 -113 338 -113 472 -317 ct 486 -339 496 -354 499 -363 ct +503 -372 505 -380 505 -386 ct 505 -392 502 -397 497 -401 ct 492 -406 484 -409 472 -410 ct +472 -410 472 -410 474 -421 ct 474 -421 474 -421 599 -421 ct 599 -421 599 -421 596 -410 ct +585 -409 575 -406 567 -402 ct 558 -397 548 -389 537 -376 ct 530 -368 516 -349 496 -317 ct +496 -317 496 -317 284 9 ct 284 9 284 9 273 9 ct 273 9 273 9 307 -317 ct 307 -317 307 -317 97 9 ct +97 9 97 9 86 9 ct p ef +pom +gr +gs +pum +847 556 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1138 556 t +54 -273 m 54 -273 54 -273 249 -273 ct 249 -273 249 -273 249 -265 ct 249 -265 249 -265 35 -42 ct +35 -42 35 -42 125 -42 ct 147 -42 161 -43 166 -44 ct 172 -46 178 -50 183 -55 ct +187 -60 193 -70 199 -84 ct 199 -84 199 -84 210 -84 ct 210 -84 210 -84 183 0 ct +183 0 183 0 -18 0 ct -18 0 -18 0 -18 -9 ct -18 -9 -18 -9 196 -232 ct 196 -232 196 -232 109 -232 ct +90 -232 78 -232 74 -231 ct 68 -229 63 -226 57 -221 ct 51 -216 45 -208 39 -196 ct +39 -196 39 -196 28 -196 ct 28 -196 28 -196 54 -273 ct p ef +pom +gr +gs +pum +1429 556 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gs +132 767 m 1521 0 rl 0 31 rl 1521 neg 0 rl ef p ef + +gr +gs +pum +370 1323 t +208 -345 m 197 -344 l 113 -410 l 25 -342 l 11 -345 l 113 -462 l 208 -345 l +p ef +pom +gr +gs +pum +318 1455 t +328 -430 m 328 -430 328 -430 296 -80 ct 294 -64 294 -53 294 -48 ct 294 -40 295 -33 298 -29 ct +302 -23 307 -18 314 -15 ct 321 -12 332 -11 348 -11 ct 348 -11 348 -11 345 0 ct +345 0 345 0 180 0 ct 180 0 180 0 184 -11 ct 184 -11 184 -11 191 -11 ct 204 -11 215 -14 224 -20 ct +230 -24 234 -30 238 -39 ct 240 -46 242 -61 244 -85 ct 244 -85 244 -85 249 -138 ct +249 -138 249 -138 128 -138 ct 128 -138 128 -138 86 -80 ct 76 -67 70 -57 67 -52 ct +65 -46 64 -41 64 -36 ct 64 -29 66 -24 72 -19 ct 77 -14 86 -11 98 -11 ct 98 -11 98 -11 95 0 ct +95 0 95 0 -30 0 ct -30 0 -30 0 -27 -11 ct -12 -12 2 -17 14 -26 ct 25 -36 43 -57 66 -88 ct +66 -88 66 -88 317 -430 ct 317 -430 317 -430 328 -430 ct p +268 -327 m 144 -159 l 251 -159 l 268 -327 l p ef +pom +gr +gs +pum +767 1455 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1032 1455 t +54 -273 m 54 -273 54 -273 249 -273 ct 249 -273 249 -273 249 -265 ct 249 -265 249 -265 35 -42 ct +35 -42 35 -42 125 -42 ct 147 -42 161 -43 166 -44 ct 172 -46 178 -50 183 -55 ct +187 -60 193 -70 199 -84 ct 199 -84 199 -84 210 -84 ct 210 -84 210 -84 183 0 ct +183 0 183 0 -18 0 ct -18 0 -18 0 -18 -9 ct -18 -9 -18 -9 196 -232 ct 196 -232 196 -232 109 -232 ct +90 -232 78 -232 74 -231 ct 68 -229 63 -226 57 -221 ct 51 -216 45 -208 39 -196 ct +39 -196 39 -196 28 -196 ct 28 -196 28 -196 54 -273 ct p ef +pom +gr +gs +pum +1349 1455 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gr +gr +gr +gr +8085 12686 m 7035 12686 l 7035 10886 l 9135 10886 l 9135 12686 l 8085 12686 l +pc +5135 11785 m 5698 11598 l 5698 11973 l 5135 11785 l p ef +7035 11811 m 6085 11811 l 6085 11786 l 6085 11761 l 7035 11761 l 7035 11786 l +7035 11811 l p ef +6085 11786 m 6085 11811 l 6081 11811 l 6076 11809 l 6073 11808 l 6069 11805 l +6066 11802 l 6063 11799 l 6062 11795 l 6060 11790 l 6060 11786 l 6060 11786 l +6085 11786 l p ef +6060 11786 m 6060 11785 l 6085 11785 l 6110 11785 l 6110 11786 l 6085 11786 l +6060 11786 l p ef +6085 11785 m 6085 11760 l 6089 11760 l 6094 11762 l 6097 11763 l 6101 11766 l +6104 11769 l 6107 11772 l 6108 11776 l 6110 11781 l 6110 11785 l 6110 11785 l +6085 11785 l p ef +6085 11810 m 5585 11810 l 5585 11785 l 5585 11760 l 6085 11760 l 6085 11785 l +6085 11810 l p ef +4384 11036 m 4197 10474 l 4572 10474 l 4384 11036 l p ef +4409 10135 m 4409 10586 l 4359 10586 l 4359 10135 l 4409 10135 l p ef +15735 12685 m 14335 12685 l 14335 10885 l 17135 10885 l 17135 12685 l +15735 12685 l pc +gs +gs +pum +14696 11662 t +259 -125 m 259 -125 259 -125 114 -125 ct 114 -125 114 -125 88 -66 ct 82 -52 79 -41 79 -33 ct +79 -28 81 -23 87 -18 ct 92 -14 104 -11 122 -10 ct 122 -10 122 -10 122 0 ct 122 0 122 0 4 0 ct +4 0 4 0 4 -10 ct 20 -13 30 -16 35 -21 ct 44 -30 54 -48 66 -75 ct 66 -75 66 -75 200 -382 ct +200 -382 200 -382 211 -382 ct 211 -382 211 -382 338 -71 ct 348 -46 358 -30 367 -23 ct +375 -15 387 -11 402 -10 ct 402 -10 402 -10 402 0 ct 402 0 402 0 254 0 ct 254 0 254 0 254 -10 ct +269 -11 279 -13 284 -17 ct 289 -22 292 -27 292 -33 ct 292 -41 288 -53 281 -71 ct +281 -71 281 -71 259 -125 ct p +250 -146 m 189 -297 l 123 -146 l 250 -146 l p ef +604 -29 m 592 -16 580 -7 568 -1 ct 556 4 543 7 530 7 ct 502 7 478 -4 457 -27 ct +436 -50 426 -80 426 -116 ct 426 -152 437 -185 460 -215 ct 483 -245 513 -260 549 -260 ct +571 -260 589 -252 604 -237 ct 604 -237 604 -237 604 -286 ct 604 -314 603 -332 602 -338 ct +601 -345 598 -349 595 -352 ct 593 -354 589 -355 585 -355 ct 580 -355 573 -354 566 -351 ct +566 -351 566 -351 562 -361 ct 562 -361 562 -361 637 -392 ct 637 -392 637 -392 649 -392 ct +649 -392 649 -392 649 -99 ct 649 -70 650 -53 651 -46 ct 652 -40 655 -36 658 -33 ct +661 -31 664 -29 668 -29 ct 673 -29 680 -31 688 -34 ct 688 -34 688 -34 691 -24 ct +691 -24 691 -24 617 7 ct 617 7 617 7 604 7 ct 604 7 604 7 604 -29 ct p +604 -48 m 604 -48 604 -48 604 -177 ct 603 -189 600 -201 594 -211 ct 589 -221 581 -229 572 -234 ct +563 -239 554 -242 545 -242 ct 529 -242 515 -235 502 -220 ct 485 -201 477 -174 477 -137 ct +477 -100 485 -72 501 -52 ct 518 -33 536 -23 555 -23 ct 572 -23 588 -31 604 -48 ct +p ef +851 -37 m 825 -17 809 -5 802 -2 ct 792 3 782 5 770 5 ct 753 5 738 -1 727 -13 ct +716 -25 710 -40 710 -60 ct 710 -72 713 -83 718 -92 ct 726 -104 739 -116 758 -127 ct +776 -138 808 -151 851 -167 ct 851 -167 851 -167 851 -177 ct 851 -202 847 -219 839 -228 ct +831 -237 820 -242 804 -242 ct 793 -242 784 -239 777 -233 ct 770 -226 766 -219 766 -211 ct +766 -211 766 -211 767 -195 ct 767 -187 765 -180 760 -176 ct 756 -171 750 -169 743 -169 ct +737 -169 731 -171 727 -176 ct 722 -181 720 -188 720 -196 ct 720 -212 728 -227 744 -240 ct +760 -253 783 -260 812 -260 ct 834 -260 853 -256 867 -249 ct 878 -243 886 -234 891 -222 ct +894 -214 896 -198 896 -174 ct 896 -174 896 -174 896 -89 ct 896 -65 896 -50 897 -45 ct +898 -39 900 -36 902 -34 ct 904 -32 906 -31 909 -31 ct 912 -31 915 -32 917 -33 ct +921 -35 928 -42 939 -53 ct 939 -53 939 -53 939 -38 ct 919 -10 899 4 881 4 ct 872 4 864 1 859 -5 ct +854 -11 851 -22 851 -37 ct p +851 -54 m 851 -54 851 -54 851 -149 ct 823 -138 805 -130 797 -126 ct 782 -118 772 -110 765 -101 ct +759 -92 756 -83 756 -72 ct 756 -59 760 -49 768 -40 ct 776 -31 785 -27 795 -27 ct +810 -27 828 -36 851 -54 ct p ef +940 -228 m 940 -228 940 -228 1018 -259 ct 1018 -259 1018 -259 1029 -259 ct +1029 -259 1029 -259 1029 -201 ct 1042 -223 1055 -238 1068 -247 ct 1081 -256 1095 -260 1109 -260 ct +1134 -260 1155 -250 1172 -230 ct 1193 -206 1203 -175 1203 -136 ct 1203 -92 1191 -56 1166 -28 ct +1145 -5 1120 7 1089 7 ct 1075 7 1063 5 1054 1 ct 1046 -2 1038 -7 1029 -16 ct 1029 -16 1029 -16 1029 63 ct +1029 80 1030 91 1032 96 ct 1034 100 1038 104 1043 107 ct 1049 110 1058 111 1072 111 ct +1072 111 1072 111 1072 121 ct 1072 121 1072 121 937 121 ct 937 121 937 121 937 111 ct +937 111 937 111 944 111 ct 954 111 963 109 971 105 ct 974 103 977 100 979 95 ct +981 91 982 79 982 61 ct 982 61 982 61 982 -179 ct 982 -195 981 -205 980 -209 ct +978 -213 976 -216 973 -219 ct 970 -221 965 -222 960 -222 ct 956 -222 950 -221 943 -218 ct +943 -218 943 -218 940 -228 ct p +1029 -185 m 1029 -185 1029 -185 1029 -90 ct 1029 -70 1030 -57 1031 -50 ct 1034 -40 1040 -30 1050 -22 ct +1060 -14 1073 -10 1088 -10 ct 1106 -10 1121 -17 1132 -31 ct 1147 -50 1154 -77 1154 -111 ct +1154 -149 1146 -179 1129 -200 ct 1117 -214 1103 -221 1087 -221 ct 1079 -221 1070 -219 1061 -214 ct +1055 -211 1044 -201 1029 -185 ct p ef +1314 -337 m 1314 -337 1314 -337 1314 -253 ct 1314 -253 1314 -253 1373 -253 ct +1373 -253 1373 -253 1373 -234 ct 1373 -234 1373 -234 1314 -234 ct 1314 -234 1314 -234 1314 -70 ct +1314 -53 1316 -42 1321 -37 ct 1326 -31 1332 -28 1339 -28 ct 1345 -28 1351 -30 1357 -34 ct +1362 -37 1367 -43 1370 -50 ct 1370 -50 1370 -50 1381 -50 ct 1375 -32 1365 -19 1354 -10 ct +1342 -1 1329 4 1317 4 ct 1308 4 1300 2 1292 -3 ct 1284 -8 1278 -14 1274 -23 ct +1270 -32 1268 -45 1268 -64 ct 1268 -64 1268 -64 1268 -234 ct 1268 -234 1268 -234 1228 -234 ct +1228 -234 1228 -234 1228 -243 ct 1238 -247 1248 -254 1259 -264 ct 1270 -273 1279 -285 1287 -298 ct +1292 -305 1297 -318 1305 -337 ct 1305 -337 1305 -337 1314 -337 ct p ef +1462 -392 m 1470 -392 1476 -389 1482 -384 ct 1487 -378 1490 -372 1490 -364 ct +1490 -356 1487 -350 1482 -344 ct 1476 -339 1470 -336 1462 -336 ct 1454 -336 1448 -339 1442 -344 ct +1437 -350 1434 -356 1434 -364 ct 1434 -372 1437 -378 1442 -384 ct 1448 -389 1454 -392 1462 -392 ct +p +1485 -260 m 1485 -260 1485 -260 1485 -57 ct 1485 -41 1486 -31 1488 -26 ct 1491 -20 1494 -16 1498 -14 ct +1503 -11 1510 -10 1522 -10 ct 1522 -10 1522 -10 1522 0 ct 1522 0 1522 0 1402 0 ct +1402 0 1402 0 1402 -10 ct 1414 -10 1422 -11 1426 -14 ct 1430 -16 1433 -20 1435 -25 ct +1438 -31 1439 -41 1439 -57 ct 1439 -57 1439 -57 1439 -154 ct 1439 -181 1438 -199 1437 -207 ct +1435 -213 1433 -217 1431 -220 ct 1428 -222 1424 -223 1419 -223 ct 1414 -223 1408 -222 1401 -219 ct +1401 -219 1401 -219 1397 -229 ct 1397 -229 1397 -229 1473 -260 ct 1473 -260 1473 -260 1485 -260 ct +p ef +1543 -253 m 1543 -253 1543 -253 1661 -253 ct 1661 -253 1661 -253 1661 -243 ct +1661 -243 1661 -243 1653 -243 ct 1646 -243 1641 -241 1637 -238 ct 1633 -234 1631 -230 1631 -224 ct +1631 -217 1633 -210 1637 -201 ct 1637 -201 1637 -201 1696 -62 ct 1696 -62 1696 -62 1754 -206 ct +1758 -216 1760 -224 1760 -230 ct 1760 -232 1760 -234 1758 -236 ct 1756 -239 1754 -240 1750 -241 ct +1747 -243 1741 -243 1731 -243 ct 1731 -243 1731 -243 1731 -253 ct 1731 -253 1731 -253 1813 -253 ct +1813 -253 1813 -253 1813 -243 ct 1804 -242 1797 -240 1793 -237 ct 1787 -231 1781 -222 1776 -209 ct +1776 -209 1776 -209 1687 7 ct 1687 7 1687 7 1676 7 ct 1676 7 1676 7 1587 -205 ct +1583 -216 1579 -223 1575 -227 ct 1571 -232 1567 -235 1561 -238 ct 1558 -240 1552 -242 1543 -243 ct +1543 -243 1543 -243 1543 -253 ct p ef +1880 -158 m 1880 -121 1889 -92 1907 -71 ct 1925 -50 1946 -39 1971 -39 ct 1987 -39 2002 -43 2014 -52 ct +2026 -61 2036 -77 2044 -99 ct 2044 -99 2044 -99 2053 -94 ct 2049 -68 2038 -45 2019 -24 ct +2001 -3 1978 7 1950 7 ct 1920 7 1894 -5 1872 -28 ct 1851 -52 1840 -83 1840 -123 ct +1840 -166 1851 -200 1873 -224 ct 1895 -248 1923 -260 1956 -260 ct 1984 -260 2008 -251 2026 -232 ct +2044 -214 2053 -189 2053 -158 ct 2053 -158 2053 -158 1880 -158 ct p +1880 -174 m 1880 -174 1880 -174 1996 -174 ct 1995 -190 1993 -201 1990 -208 ct +1986 -218 1979 -226 1970 -231 ct 1961 -237 1951 -240 1942 -240 ct 1926 -240 1913 -234 1901 -223 ct +1889 -211 1882 -195 1880 -174 ct p ef +pom +gr +gs +pum +14631 12289 t +233 -95 m 226 -62 213 -37 193 -19 ct 173 -2 151 7 127 7 ct 98 7 73 -5 52 -29 ct +31 -53 20 -85 20 -126 ct 20 -166 32 -198 55 -223 ct 79 -248 108 -260 141 -260 ct +166 -260 186 -253 202 -240 ct 218 -227 226 -214 226 -199 ct 226 -192 224 -187 219 -182 ct +215 -178 208 -176 200 -176 ct 190 -176 182 -180 176 -187 ct 173 -190 171 -198 170 -209 ct +169 -220 165 -228 158 -234 ct 152 -239 143 -242 132 -242 ct 113 -242 99 -235 87 -222 ct +72 -204 65 -180 65 -150 ct 65 -120 72 -94 87 -71 ct 102 -48 122 -36 147 -36 ct +165 -36 181 -42 196 -54 ct 206 -62 215 -77 225 -99 ct 225 -99 225 -99 233 -95 ct +p ef +392 -260 m 430 -260 461 -246 484 -217 ct 503 -192 513 -163 513 -131 ct 513 -109 508 -86 497 -63 ct +486 -40 471 -22 452 -11 ct 433 1 412 7 389 7 ct 351 7 321 -8 298 -38 ct 279 -64 270 -92 270 -124 ct +270 -147 276 -170 287 -193 ct 299 -216 314 -233 332 -244 ct 351 -255 371 -260 392 -260 ct +p +383 -242 m 374 -242 364 -239 354 -233 ct 344 -228 336 -218 330 -203 ct 324 -189 321 -170 321 -147 ct +321 -111 328 -79 343 -53 ct 358 -26 377 -13 401 -13 ct 418 -13 433 -20 445 -35 ct +456 -50 462 -75 462 -110 ct 462 -155 452 -190 433 -216 ct 420 -233 403 -242 383 -242 ct +p ef +731 -29 m 719 -16 707 -7 695 -1 ct 683 4 670 7 657 7 ct 629 7 605 -4 584 -27 ct +563 -50 553 -80 553 -116 ct 553 -152 564 -185 587 -215 ct 610 -245 640 -260 676 -260 ct +698 -260 716 -252 731 -237 ct 731 -237 731 -237 731 -286 ct 731 -314 730 -332 729 -338 ct +728 -345 725 -349 722 -352 ct 720 -354 716 -355 712 -355 ct 707 -355 700 -354 693 -351 ct +693 -351 693 -351 689 -361 ct 689 -361 689 -361 764 -392 ct 764 -392 764 -392 776 -392 ct +776 -392 776 -392 776 -99 ct 776 -70 777 -53 778 -46 ct 779 -40 782 -36 785 -33 ct +788 -31 791 -29 795 -29 ct 800 -29 807 -31 815 -34 ct 815 -34 815 -34 818 -24 ct +818 -24 818 -24 744 7 ct 744 7 744 7 731 7 ct 731 7 731 7 731 -29 ct p +731 -48 m 731 -48 731 -48 731 -177 ct 730 -189 727 -201 721 -211 ct 716 -221 708 -229 699 -234 ct +690 -239 681 -242 672 -242 ct 656 -242 642 -235 629 -220 ct 612 -201 604 -174 604 -137 ct +604 -100 612 -72 628 -52 ct 645 -33 663 -23 682 -23 ct 699 -23 715 -31 731 -48 ct +p ef +877 -158 m 877 -121 886 -92 904 -71 ct 922 -50 943 -39 968 -39 ct 984 -39 999 -43 1011 -52 ct +1023 -61 1033 -77 1041 -99 ct 1041 -99 1041 -99 1050 -94 ct 1046 -68 1035 -45 1016 -24 ct +998 -3 975 7 947 7 ct 917 7 891 -5 869 -28 ct 848 -52 837 -83 837 -123 ct 837 -166 848 -200 870 -224 ct +892 -248 920 -260 953 -260 ct 981 -260 1005 -251 1023 -232 ct 1041 -214 1050 -189 1050 -158 ct +1050 -158 1050 -158 877 -158 ct p +877 -174 m 877 -174 877 -174 993 -174 ct 992 -190 990 -201 987 -208 ct 983 -218 976 -226 967 -231 ct +958 -237 948 -240 939 -240 ct 923 -240 910 -234 898 -223 ct 886 -211 879 -195 877 -174 ct +p ef +1154 -209 m 1178 -243 1205 -260 1233 -260 ct 1259 -260 1281 -249 1300 -227 ct +1319 -205 1329 -175 1329 -136 ct 1329 -92 1314 -56 1284 -28 ct 1259 -5 1230 7 1199 7 ct +1184 7 1170 4 1154 -1 ct 1139 -6 1124 -14 1108 -25 ct 1108 -25 1108 -25 1108 -286 ct +1108 -314 1107 -332 1106 -338 ct 1105 -345 1102 -349 1099 -352 ct 1096 -354 1093 -355 1088 -355 ct +1083 -355 1077 -354 1069 -351 ct 1069 -351 1069 -351 1065 -361 ct 1065 -361 1065 -361 1141 -392 ct +1141 -392 1141 -392 1154 -392 ct 1154 -392 1154 -392 1154 -209 ct p +1154 -192 m 1154 -192 1154 -192 1154 -41 ct 1163 -32 1173 -25 1183 -20 ct 1193 -15 1203 -13 1213 -13 ct +1230 -13 1245 -22 1260 -41 ct 1274 -59 1281 -86 1281 -121 ct 1281 -153 1274 -178 1260 -195 ct +1245 -212 1229 -221 1211 -221 ct 1201 -221 1192 -219 1182 -214 ct 1175 -210 1165 -203 1154 -192 ct +p ef +1492 -260 m 1530 -260 1561 -246 1584 -217 ct 1603 -192 1613 -163 1613 -131 ct +1613 -109 1608 -86 1597 -63 ct 1586 -40 1571 -22 1552 -11 ct 1533 1 1512 7 1489 7 ct +1451 7 1421 -8 1398 -38 ct 1379 -64 1370 -92 1370 -124 ct 1370 -147 1376 -170 1387 -193 ct +1399 -216 1414 -233 1432 -244 ct 1451 -255 1471 -260 1492 -260 ct p +1483 -242 m 1474 -242 1464 -239 1454 -233 ct 1444 -228 1436 -218 1430 -203 ct +1424 -189 1421 -170 1421 -147 ct 1421 -111 1428 -79 1443 -53 ct 1458 -26 1477 -13 1501 -13 ct +1518 -13 1533 -20 1545 -35 ct 1556 -50 1562 -75 1562 -110 ct 1562 -155 1552 -190 1533 -216 ct +1520 -233 1503 -242 1483 -242 ct p ef +1776 -260 m 1814 -260 1845 -246 1868 -217 ct 1887 -192 1897 -163 1897 -131 ct +1897 -109 1892 -86 1881 -63 ct 1870 -40 1855 -22 1836 -11 ct 1817 1 1796 7 1773 7 ct +1735 7 1705 -8 1682 -38 ct 1663 -64 1654 -92 1654 -124 ct 1654 -147 1660 -170 1671 -193 ct +1683 -216 1698 -233 1716 -244 ct 1735 -255 1755 -260 1776 -260 ct p +1767 -242 m 1758 -242 1748 -239 1738 -233 ct 1728 -228 1720 -218 1714 -203 ct +1708 -189 1705 -170 1705 -147 ct 1705 -111 1712 -79 1727 -53 ct 1742 -26 1761 -13 1785 -13 ct +1802 -13 1817 -20 1829 -35 ct 1840 -50 1846 -75 1846 -110 ct 1846 -155 1836 -190 1817 -216 ct +1804 -233 1787 -242 1767 -242 ct p ef +2011 -392 m 2011 -392 2011 -392 2011 -141 ct 2011 -141 2011 -141 2074 -200 ct +2088 -212 2096 -220 2098 -223 ct 2100 -225 2100 -227 2100 -229 ct 2100 -233 2099 -236 2096 -239 ct +2093 -241 2088 -243 2081 -243 ct 2081 -243 2081 -243 2081 -253 ct 2081 -253 2081 -253 2190 -253 ct +2190 -253 2190 -253 2190 -244 ct 2175 -244 2163 -241 2153 -237 ct 2143 -233 2132 -225 2120 -214 ct +2120 -214 2120 -214 2056 -155 ct 2056 -155 2056 -155 2120 -72 ct 2138 -50 2150 -35 2155 -29 ct +2164 -21 2172 -15 2179 -13 ct 2183 -11 2192 -10 2203 -10 ct 2203 -10 2203 -10 2203 0 ct +2203 0 2203 0 2081 0 ct 2081 0 2081 0 2081 -10 ct 2088 -10 2092 -11 2095 -13 ct +2097 -15 2099 -18 2099 -21 ct 2099 -26 2095 -32 2088 -42 ct 2088 -42 2088 -42 2011 -141 ct +2011 -141 2011 -141 2011 -57 ct 2011 -41 2012 -30 2014 -25 ct 2017 -19 2020 -16 2024 -14 ct +2029 -11 2038 -10 2052 -10 ct 2052 -10 2052 -10 2052 0 ct 2052 0 2052 0 1924 0 ct +1924 0 1924 0 1924 -10 ct 1937 -10 1946 -12 1952 -15 ct 1956 -17 1959 -20 1961 -24 ct +1964 -30 1965 -40 1965 -55 ct 1965 -55 1965 -55 1965 -286 ct 1965 -315 1964 -332 1963 -339 ct +1962 -345 1960 -350 1957 -352 ct 1954 -354 1950 -356 1946 -356 ct 1942 -356 1936 -354 1929 -351 ct +1929 -351 1929 -351 1924 -361 ct 1924 -361 1924 -361 1998 -392 ct 1998 -392 1998 -392 2011 -392 ct +p ef +pom +gr +gr +11685 12685 m 10435 12685 l 10435 10885 l 12935 10885 l 12935 12685 l +11685 12685 l pc +gs +gs +pum +11111 11662 t +27 -302 m 38 -327 51 -347 68 -360 ct 84 -374 105 -381 129 -381 ct 159 -381 183 -371 199 -352 ct +211 -337 217 -322 217 -305 ct 217 -278 200 -250 165 -221 ct 188 -212 205 -200 217 -183 ct +229 -166 235 -147 235 -124 ct 235 -92 225 -64 204 -40 ct 177 -9 138 6 87 6 ct 62 6 45 3 36 -3 ct +27 -10 22 -17 22 -24 ct 22 -29 24 -34 28 -38 ct 33 -42 38 -44 44 -44 ct 49 -44 53 -43 58 -42 ct +61 -41 68 -37 79 -32 ct 90 -26 98 -22 102 -21 ct 109 -19 116 -18 124 -18 ct 143 -18 159 -25 173 -40 ct +187 -54 194 -71 194 -91 ct 194 -106 191 -120 184 -134 ct 180 -144 174 -152 169 -157 ct +161 -164 150 -171 137 -177 ct 123 -183 109 -186 95 -186 ct 95 -186 95 -186 86 -186 ct +86 -186 86 -186 86 -194 ct 100 -196 115 -201 129 -210 ct 144 -218 155 -229 161 -241 ct +168 -253 171 -266 171 -281 ct 171 -300 165 -315 153 -327 ct 141 -338 126 -344 108 -344 ct +80 -344 56 -329 36 -298 ct 36 -298 36 -298 27 -302 ct p ef +307 -148 m 450 -148 l 450 -106 l 307 -106 l 307 -148 l p ef +561 -337 m 561 -337 561 -337 561 -253 ct 561 -253 561 -253 620 -253 ct 620 -253 620 -253 620 -234 ct +620 -234 620 -234 561 -234 ct 561 -234 561 -234 561 -70 ct 561 -53 563 -42 568 -37 ct +573 -31 579 -28 586 -28 ct 592 -28 598 -30 604 -34 ct 609 -37 614 -43 617 -50 ct +617 -50 617 -50 628 -50 ct 622 -32 612 -19 601 -10 ct 589 -1 576 4 564 4 ct 555 4 547 2 539 -3 ct +531 -8 525 -14 521 -23 ct 517 -32 515 -45 515 -64 ct 515 -64 515 -64 515 -234 ct +515 -234 515 -234 475 -234 ct 475 -234 475 -234 475 -243 ct 485 -247 495 -254 506 -264 ct +517 -273 526 -285 534 -298 ct 539 -305 544 -318 552 -337 ct 552 -337 552 -337 561 -337 ct +p ef +788 -37 m 762 -17 746 -5 739 -2 ct 729 3 719 5 707 5 ct 690 5 675 -1 664 -13 ct +653 -25 647 -40 647 -60 ct 647 -72 650 -83 655 -92 ct 663 -104 676 -116 695 -127 ct +713 -138 745 -151 788 -167 ct 788 -167 788 -167 788 -177 ct 788 -202 784 -219 776 -228 ct +768 -237 757 -242 741 -242 ct 730 -242 721 -239 714 -233 ct 707 -226 703 -219 703 -211 ct +703 -211 703 -211 704 -195 ct 704 -187 702 -180 697 -176 ct 693 -171 687 -169 680 -169 ct +674 -169 668 -171 664 -176 ct 659 -181 657 -188 657 -196 ct 657 -212 665 -227 681 -240 ct +697 -253 720 -260 749 -260 ct 771 -260 790 -256 804 -249 ct 815 -243 823 -234 828 -222 ct +831 -214 833 -198 833 -174 ct 833 -174 833 -174 833 -89 ct 833 -65 833 -50 834 -45 ct +835 -39 837 -36 839 -34 ct 841 -32 843 -31 846 -31 ct 849 -31 852 -32 854 -33 ct +858 -35 865 -42 876 -53 ct 876 -53 876 -53 876 -38 ct 856 -10 836 4 818 4 ct 809 4 801 1 796 -5 ct +791 -11 788 -22 788 -37 ct p +788 -54 m 788 -54 788 -54 788 -149 ct 760 -138 742 -130 734 -126 ct 719 -118 709 -110 702 -101 ct +696 -92 693 -83 693 -72 ct 693 -59 697 -49 705 -40 ct 713 -31 722 -27 732 -27 ct +747 -27 765 -36 788 -54 ct p ef +876 -228 m 876 -228 876 -228 954 -259 ct 954 -259 954 -259 965 -259 ct 965 -259 965 -259 965 -201 ct +978 -223 991 -238 1004 -247 ct 1017 -256 1031 -260 1045 -260 ct 1070 -260 1091 -250 1108 -230 ct +1129 -206 1139 -175 1139 -136 ct 1139 -92 1127 -56 1102 -28 ct 1081 -5 1056 7 1025 7 ct +1011 7 999 5 990 1 ct 982 -2 974 -7 965 -16 ct 965 -16 965 -16 965 63 ct 965 80 966 91 968 96 ct +970 100 974 104 979 107 ct 985 110 994 111 1008 111 ct 1008 111 1008 111 1008 121 ct +1008 121 1008 121 873 121 ct 873 121 873 121 873 111 ct 873 111 873 111 880 111 ct +890 111 899 109 907 105 ct 910 103 913 100 915 95 ct 917 91 918 79 918 61 ct 918 61 918 61 918 -179 ct +918 -195 917 -205 916 -209 ct 914 -213 912 -216 909 -219 ct 906 -221 901 -222 896 -222 ct +892 -222 886 -221 879 -218 ct 879 -218 879 -218 876 -228 ct p +965 -185 m 965 -185 965 -185 965 -90 ct 965 -70 966 -57 967 -50 ct 970 -40 976 -30 986 -22 ct +996 -14 1009 -10 1024 -10 ct 1042 -10 1057 -17 1068 -31 ct 1083 -50 1090 -77 1090 -111 ct +1090 -149 1082 -179 1065 -200 ct 1053 -214 1039 -221 1023 -221 ct 1015 -221 1006 -219 997 -214 ct +991 -211 980 -201 965 -185 ct p ef +pom +gr +gs +pum +11204 12289 t +85 -93 m 69 -101 58 -111 49 -125 ct 41 -138 37 -153 37 -169 ct 37 -194 46 -215 65 -233 ct +84 -251 108 -260 138 -260 ct 162 -260 183 -254 200 -242 ct 200 -242 200 -242 254 -242 ct +262 -242 266 -242 268 -241 ct 269 -241 270 -240 270 -239 ct 271 -237 272 -234 272 -230 ct +272 -225 272 -222 271 -220 ct 270 -219 269 -218 268 -218 ct 266 -217 262 -217 254 -217 ct +254 -217 254 -217 221 -217 ct 231 -204 236 -187 236 -167 ct 236 -143 227 -123 209 -107 ct +191 -90 167 -82 137 -82 ct 124 -82 111 -84 98 -88 ct 90 -81 85 -74 82 -69 ct 79 -64 78 -59 78 -56 ct +78 -52 80 -49 83 -46 ct 86 -43 91 -41 100 -40 ct 105 -39 118 -39 139 -38 ct 176 -37 201 -36 212 -34 ct +229 -32 243 -25 253 -15 ct 263 -5 268 8 268 23 ct 268 44 258 63 239 82 ct 211 109 173 122 128 122 ct +92 122 63 114 39 98 ct 25 89 18 79 18 69 ct 18 65 19 60 21 56 ct 24 49 30 40 40 28 ct +41 26 50 16 67 -2 ct 58 -8 51 -13 47 -18 ct 43 -22 41 -27 41 -33 ct 41 -40 44 -47 49 -56 ct +54 -65 66 -77 85 -93 ct p +133 -246 m 119 -246 108 -241 99 -230 ct 90 -219 85 -203 85 -181 ct 85 -152 91 -130 104 -114 ct +113 -102 125 -96 140 -96 ct 154 -96 166 -101 175 -112 ct 184 -122 188 -138 188 -160 ct +188 -189 182 -212 169 -228 ct 160 -240 148 -246 133 -246 ct p +82 0 m 74 9 68 18 63 26 ct 59 34 57 42 57 49 ct 57 57 62 65 73 72 ct 91 83 117 89 152 89 ct +185 89 209 83 225 71 ct 240 60 248 47 248 34 ct 248 24 243 17 234 13 ct 224 9 206 7 177 6 ct +136 5 104 3 82 0 ct p ef +445 -37 m 419 -17 403 -5 396 -2 ct 386 3 376 5 364 5 ct 347 5 332 -1 321 -13 ct +310 -25 304 -40 304 -60 ct 304 -72 307 -83 312 -92 ct 320 -104 333 -116 352 -127 ct +370 -138 402 -151 445 -167 ct 445 -167 445 -167 445 -177 ct 445 -202 441 -219 433 -228 ct +425 -237 414 -242 398 -242 ct 387 -242 378 -239 371 -233 ct 364 -226 360 -219 360 -211 ct +360 -211 360 -211 361 -195 ct 361 -187 359 -180 354 -176 ct 350 -171 344 -169 337 -169 ct +331 -169 325 -171 321 -176 ct 316 -181 314 -188 314 -196 ct 314 -212 322 -227 338 -240 ct +354 -253 377 -260 406 -260 ct 428 -260 447 -256 461 -249 ct 472 -243 480 -234 485 -222 ct +488 -214 490 -198 490 -174 ct 490 -174 490 -174 490 -89 ct 490 -65 490 -50 491 -45 ct +492 -39 494 -36 496 -34 ct 498 -32 500 -31 503 -31 ct 506 -31 509 -32 511 -33 ct +515 -35 522 -42 533 -53 ct 533 -53 533 -53 533 -38 ct 513 -10 493 4 475 4 ct 466 4 458 1 453 -5 ct +448 -11 445 -22 445 -37 ct p +445 -54 m 445 -54 445 -54 445 -149 ct 417 -138 399 -130 391 -126 ct 376 -118 366 -110 359 -101 ct +353 -92 350 -83 350 -72 ct 350 -59 354 -49 362 -40 ct 370 -31 379 -27 389 -27 ct +404 -27 422 -36 445 -54 ct p ef +615 -392 m 623 -392 629 -389 635 -384 ct 640 -378 643 -372 643 -364 ct 643 -356 640 -350 635 -344 ct +629 -339 623 -336 615 -336 ct 607 -336 601 -339 595 -344 ct 590 -350 587 -356 587 -364 ct +587 -372 590 -378 595 -384 ct 601 -389 607 -392 615 -392 ct p +638 -260 m 638 -260 638 -260 638 -57 ct 638 -41 639 -31 641 -26 ct 644 -20 647 -16 651 -14 ct +656 -11 663 -10 675 -10 ct 675 -10 675 -10 675 0 ct 675 0 675 0 555 0 ct 555 0 555 0 555 -10 ct +567 -10 575 -11 579 -14 ct 583 -16 586 -20 588 -25 ct 591 -31 592 -41 592 -57 ct +592 -57 592 -57 592 -154 ct 592 -181 591 -199 590 -207 ct 588 -213 586 -217 584 -220 ct +581 -222 577 -223 572 -223 ct 567 -223 561 -222 554 -219 ct 554 -219 554 -219 550 -229 ct +550 -229 550 -229 626 -260 ct 626 -260 626 -260 638 -260 ct p ef +782 -207 m 811 -242 839 -260 866 -260 ct 880 -260 892 -257 901 -250 ct 911 -243 919 -231 925 -216 ct +929 -205 931 -188 931 -165 ct 931 -165 931 -165 931 -57 ct 931 -41 932 -30 935 -25 ct +937 -20 940 -16 944 -14 ct 948 -11 956 -10 968 -10 ct 968 -10 968 -10 968 0 ct +968 0 968 0 844 0 ct 844 0 844 0 844 -10 ct 844 -10 844 -10 849 -10 ct 861 -10 869 -12 874 -15 ct +879 -19 882 -24 884 -31 ct 885 -34 885 -43 885 -57 ct 885 -57 885 -57 885 -161 ct +885 -184 882 -201 876 -211 ct 870 -222 860 -227 846 -227 ct 825 -227 803 -215 782 -191 ct +782 -191 782 -191 782 -57 ct 782 -40 783 -29 785 -25 ct 788 -20 791 -16 796 -14 ct +800 -11 809 -10 823 -10 ct 823 -10 823 -10 823 0 ct 823 0 823 0 699 0 ct 699 0 699 0 699 -10 ct +699 -10 699 -10 704 -10 ct 717 -10 725 -13 729 -20 ct 734 -26 736 -39 736 -57 ct +736 -57 736 -57 736 -151 ct 736 -181 735 -200 734 -206 ct 733 -213 731 -217 728 -220 ct +725 -222 721 -223 716 -223 ct 711 -223 705 -222 698 -219 ct 698 -219 698 -219 694 -229 ct +694 -229 694 -229 770 -260 ct 770 -260 770 -260 782 -260 ct 782 -260 782 -260 782 -207 ct +p ef +pom +gr +gr +9135 11786 m 9698 11599 l 9698 11974 l 9135 11786 l p ef +10435 11810 m 9785 11810 l 9785 11785 l 9785 11760 l 10435 11760 l +10435 11785 l 10435 11810 l p ef +9785 11785 m 9760 11785 l 9760 11781 l 9762 11776 l 9763 11773 l 9766 11769 l +9769 11766 l 9772 11763 l 9776 11762 l 9781 11760 l 9785 11760 l 9785 11760 l +9785 11785 l p ef +9810 11785 m 9810 11786 l 9785 11786 l 9760 11786 l 9760 11785 l 9785 11785 l +9810 11785 l p ef +9785 11786 m 9810 11786 l 9810 11790 l 9808 11795 l 9807 11798 l 9804 11802 l +9801 11805 l 9798 11808 l 9794 11809 l 9789 11811 l 9785 11811 l 9785 11811 l +9785 11786 l p ef +9785 11811 m 9585 11811 l 9585 11786 l 9585 11761 l 9785 11761 l 9785 11786 l +9785 11811 l p ef +12935 11785 m 13498 11598 l 13498 11973 l 12935 11785 l p ef +14335 11810 m 13385 11810 l 13385 11760 l 14335 11760 l 14335 11810 l +p ef +gs +7170 15868 m 8954 15868 l 8954 17496 l 7170 17496 l 7170 15868 l eoclip newpath +gs +tm setmatrix +4736 12832 t +1 1 s +gs +gs +0 0 m 1784 0 l 1784 1628 l 0 1628 l 0 0 l eoclip newpath +gs +pum +370 503 t +208 -345 m 197 -344 l 113 -410 l 25 -342 l 11 -345 l 113 -462 l 208 -345 l +p ef +pom +gr +gs +pum +318 635 t +328 -430 m 328 -430 328 -430 296 -80 ct 294 -64 294 -53 294 -48 ct 294 -40 295 -33 298 -29 ct +302 -23 307 -18 314 -15 ct 321 -12 332 -11 348 -11 ct 348 -11 348 -11 345 0 ct +345 0 345 0 180 0 ct 180 0 180 0 184 -11 ct 184 -11 184 -11 191 -11 ct 204 -11 215 -14 224 -20 ct +230 -24 234 -30 238 -39 ct 240 -46 242 -61 244 -85 ct 244 -85 244 -85 249 -138 ct +249 -138 249 -138 128 -138 ct 128 -138 128 -138 86 -80 ct 76 -67 70 -57 67 -52 ct +65 -46 64 -41 64 -36 ct 64 -29 66 -24 72 -19 ct 77 -14 86 -11 98 -11 ct 98 -11 98 -11 95 0 ct +95 0 95 0 -30 0 ct -30 0 -30 0 -27 -11 ct -12 -12 2 -17 14 -26 ct 25 -36 43 -57 66 -88 ct +66 -88 66 -88 317 -430 ct 317 -430 317 -430 328 -430 ct p +268 -327 m 144 -159 l 251 -159 l 268 -327 l p ef +pom +gr +gs +pum +767 635 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1032 635 t +54 -273 m 54 -273 54 -273 249 -273 ct 249 -273 249 -273 249 -265 ct 249 -265 249 -265 35 -42 ct +35 -42 35 -42 125 -42 ct 147 -42 161 -43 166 -44 ct 172 -46 178 -50 183 -55 ct +187 -60 193 -70 199 -84 ct 199 -84 199 -84 210 -84 ct 210 -84 210 -84 183 0 ct +183 0 183 0 -18 0 ct -18 0 -18 0 -18 -9 ct -18 -9 -18 -9 196 -232 ct 196 -232 196 -232 109 -232 ct +90 -232 78 -232 74 -231 ct 68 -229 63 -226 57 -221 ct 51 -216 45 -208 39 -196 ct +39 -196 39 -196 28 -196 ct 28 -196 28 -196 54 -273 ct p ef +pom +gr +gs +pum +1349 635 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gs +132 847 m 1521 0 rl 0 31 rl 1521 neg 0 rl ef p ef + +gr +gs +pum +159 1455 t +86 9 m 86 9 86 9 122 -341 ct 124 -355 124 -365 124 -373 ct 124 -385 121 -394 114 -400 ct +107 -406 95 -410 77 -410 ct 77 -410 77 -410 81 -421 ct 81 -421 81 -421 237 -421 ct +237 -421 237 -421 234 -410 ct 213 -410 198 -406 191 -399 ct 183 -391 177 -372 175 -341 ct +175 -341 175 -341 151 -113 ct 151 -113 151 -113 311 -361 ct 311 -365 311 -369 311 -371 ct +311 -383 308 -392 301 -398 ct 294 -405 279 -409 257 -410 ct 257 -410 257 -410 259 -421 ct +259 -421 259 -421 430 -421 ct 430 -421 430 -421 426 -410 ct 407 -410 393 -408 387 -405 ct +382 -403 377 -399 374 -394 ct 371 -389 368 -380 366 -368 ct 365 -364 363 -340 358 -296 ct +354 -251 347 -190 338 -113 ct 338 -113 338 -113 472 -317 ct 486 -339 496 -354 499 -363 ct +503 -372 505 -380 505 -386 ct 505 -392 502 -397 497 -401 ct 492 -406 484 -409 472 -410 ct +472 -410 472 -410 474 -421 ct 474 -421 474 -421 599 -421 ct 599 -421 599 -421 596 -410 ct +585 -409 575 -406 567 -402 ct 558 -397 548 -389 537 -376 ct 530 -368 516 -349 496 -317 ct +496 -317 496 -317 284 9 ct 284 9 284 9 273 9 ct 273 9 273 9 307 -317 ct 307 -317 307 -317 97 9 ct +97 9 97 9 86 9 ct p ef +pom +gr +gs +pum +847 1455 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1138 1455 t +54 -273 m 54 -273 54 -273 249 -273 ct 249 -273 249 -273 249 -265 ct 249 -265 249 -265 35 -42 ct +35 -42 35 -42 125 -42 ct 147 -42 161 -43 166 -44 ct 172 -46 178 -50 183 -55 ct +187 -60 193 -70 199 -84 ct 199 -84 199 -84 210 -84 ct 210 -84 210 -84 183 0 ct +183 0 183 0 -18 0 ct -18 0 -18 0 -18 -9 ct -18 -9 -18 -9 196 -232 ct 196 -232 196 -232 109 -232 ct +90 -232 78 -232 74 -231 ct 68 -229 63 -226 57 -221 ct 51 -216 45 -208 39 -196 ct +39 -196 39 -196 28 -196 ct 28 -196 28 -196 54 -273 ct p ef +pom +gr +gs +pum +1429 1455 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gr +gr +gr +gr +8085 17487 m 7035 17487 l 7035 15687 l 9135 15687 l 9135 17487 l 8085 17487 l +pc +gs +10470 15716 m 12288 15716 l 12288 17480 l 10470 17480 l 10470 15716 l eoclip newpath +gs +tm setmatrix +8043 12674 t +1 1 s +gs +gs +0 0 m 1818 0 l 1818 1764 l 0 1764 l 0 0 l eoclip newpath +gs +pum +159 741 t +650 93 m 650 93 650 93 56 93 ct 56 93 56 93 56 76 ct 56 76 56 76 359 -301 ct 359 -301 359 -301 56 -670 ct +56 -670 56 -670 56 -687 ct 56 -687 56 -687 634 -687 ct 634 -687 634 -687 646 -534 ct +646 -534 646 -534 627 -534 ct 620 -611 582 -650 516 -650 ct 516 -650 516 -650 181 -650 ct +181 -650 181 -650 435 -339 ct 435 -339 435 -339 150 13 ct 150 13 150 13 520 13 ct +595 13 642 -24 661 -98 ct 661 -98 661 -98 679 -96 ct 679 -96 679 -96 650 93 ct +p ef +pom +gr +gs +pum +1005 661 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1270 661 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gs +pum +1455 344 t +175 -48 m 175 -48 175 -48 157 0 ct 157 0 157 0 8 0 ct 8 0 8 0 8 -7 ct 52 -47 83 -79 101 -105 ct +119 -130 128 -153 128 -174 ct 128 -190 123 -204 113 -214 ct 103 -225 91 -230 78 -230 ct +65 -230 54 -226 44 -219 ct 34 -212 27 -202 22 -188 ct 22 -188 22 -188 15 -188 ct +18 -211 26 -228 39 -240 ct 52 -252 68 -258 88 -258 ct 108 -258 125 -251 139 -238 ct +153 -225 160 -209 160 -191 ct 160 -179 157 -166 151 -153 ct 142 -133 127 -112 106 -89 ct +75 -55 55 -35 48 -28 ct 48 -28 48 -28 114 -28 ct 127 -28 137 -29 142 -29 ct 147 -30 152 -32 157 -36 ct +161 -39 165 -43 168 -48 ct 168 -48 168 -48 175 -48 ct p ef +pom +gr +gs +132 900 m 1555 0 rl 0 31 rl 1555 neg 0 rl ef p ef + +gr +gs +pum +318 1535 t +208 -345 m 197 -344 l 113 -410 l 25 -342 l 11 -345 l 113 -462 l 208 -345 l +p ef +pom +gr +gs +pum +265 1535 t +331 -261 m 331 -261 331 -261 322 -229 ct 322 -229 322 -229 270 -229 ct 274 -218 276 -207 276 -198 ct +276 -170 264 -146 241 -124 ct 217 -103 185 -91 144 -89 ct 122 -82 106 -75 95 -65 ct +91 -62 89 -59 89 -55 ct 89 -51 91 -47 95 -44 ct 98 -40 108 -37 123 -33 ct 123 -33 123 -33 183 -20 ct +216 -12 238 -3 248 8 ct 259 19 264 31 264 46 ct 264 63 258 78 245 92 ct 233 106 215 117 190 125 ct +166 133 140 137 111 137 ct 85 137 62 134 41 128 ct 20 122 5 114 -4 103 ct -13 93 -18 82 -18 71 ct +-18 63 -15 53 -9 44 ct -3 34 4 26 13 20 ct 19 16 35 7 61 -8 ct 52 -15 47 -23 47 -32 ct +47 -40 51 -49 59 -58 ct 67 -68 85 -78 111 -89 ct 89 -93 71 -103 58 -118 ct 45 -132 39 -149 39 -167 ct +39 -196 52 -222 78 -245 ct 104 -268 138 -280 181 -280 ct 196 -280 209 -278 219 -275 ct +229 -272 239 -268 248 -261 ct 248 -261 248 -261 331 -261 ct p +225 -211 m 225 -228 220 -240 211 -250 ct 201 -259 189 -264 173 -264 ct 149 -264 129 -252 114 -229 ct +98 -206 90 -182 90 -157 ct 90 -141 95 -128 105 -118 ct 115 -108 127 -103 142 -103 ct +153 -103 164 -106 174 -112 ct 185 -118 194 -126 201 -136 ct 209 -147 214 -160 219 -176 ct +223 -192 225 -204 225 -211 ct p +74 0 m 57 8 45 18 36 30 ct 27 42 23 53 23 65 ct 23 79 29 90 42 99 ct 59 112 85 118 120 118 ct +149 118 175 113 196 103 ct 217 93 227 80 227 64 ct 227 56 223 48 215 41 ct 208 34 193 28 170 24 ct +158 21 126 13 74 0 ct p ef +pom +gr +gs +pum +714 1693 t +119 -164 m 119 -164 119 -164 116 -150 ct 116 -150 116 -150 88 -150 ct 88 -150 88 -150 65 -69 ct +55 -34 45 -6 36 13 ct 23 41 9 60 -6 70 ct -18 78 -29 82 -41 82 ct -49 82 -55 80 -60 75 ct +-64 72 -66 68 -66 63 ct -66 59 -64 55 -61 52 ct -58 49 -54 48 -50 48 ct -46 48 -44 49 -41 51 ct +-39 53 -38 56 -38 58 ct -38 61 -39 64 -41 66 ct -43 68 -44 69 -44 70 ct -44 71 -44 72 -43 73 ct +-42 74 -40 74 -38 74 ct -32 74 -27 72 -21 69 ct -15 66 -10 61 -5 54 ct -1 48 3 38 8 26 ct +9 21 14 4 22 -25 ct 22 -25 22 -25 59 -150 ct 59 -150 59 -150 22 -150 ct 22 -150 22 -150 25 -164 ct +36 -164 44 -165 49 -166 ct 53 -168 57 -170 61 -174 ct 65 -178 70 -186 75 -197 ct +82 -212 89 -224 95 -232 ct 104 -243 113 -251 123 -257 ct 132 -262 142 -265 150 -265 ct +159 -265 166 -263 172 -258 ct 177 -253 180 -248 180 -242 ct 180 -238 179 -234 176 -231 ct +173 -228 169 -227 165 -227 ct 161 -227 158 -228 156 -230 ct 153 -233 152 -235 152 -238 ct +152 -240 153 -243 155 -245 ct 157 -248 158 -250 158 -251 ct 158 -253 157 -254 156 -255 ct +155 -256 153 -257 150 -257 ct 143 -257 136 -254 130 -249 ct 122 -242 115 -232 109 -217 ct +106 -210 100 -192 92 -164 ct 92 -164 92 -164 119 -164 ct p ef +125 -158 m 125 -158 125 -158 189 -168 ct 189 -168 189 -168 163 -78 ct 185 -115 204 -141 222 -155 ct +232 -164 240 -168 247 -168 ct 251 -168 254 -167 256 -164 ct 259 -162 260 -158 260 -154 ct +260 -146 258 -138 254 -130 ct 251 -125 247 -122 241 -122 ct 238 -122 236 -123 234 -125 ct +232 -127 230 -130 230 -134 ct 230 -136 229 -138 228 -138 ct 227 -139 226 -140 225 -140 ct +223 -140 221 -140 219 -139 ct 216 -137 211 -132 204 -124 ct 194 -112 183 -96 171 -77 ct +166 -68 161 -59 158 -49 ct 153 -35 150 -26 149 -23 ct 149 -23 149 -23 142 0 ct +142 0 142 0 114 0 ct 114 0 114 0 147 -116 ct 151 -129 153 -139 153 -144 ct 153 -146 153 -148 151 -150 ct +148 -152 145 -153 141 -153 ct 139 -153 134 -152 128 -151 ct 128 -151 128 -151 125 -158 ct +p ef +443 -166 m 443 -166 443 -166 406 -40 ct 406 -40 406 -40 402 -23 ct 402 -21 401 -20 401 -19 ct +401 -17 402 -15 403 -14 ct 403 -13 404 -13 405 -13 ct 406 -13 408 -13 409 -15 ct +413 -18 417 -26 423 -37 ct 423 -37 423 -37 429 -33 ct 422 -20 415 -11 407 -5 ct +399 1 392 4 386 4 ct 382 4 378 3 376 0 ct 373 -3 372 -6 372 -11 ct 372 -17 373 -25 376 -35 ct +376 -35 376 -35 380 -50 ct 362 -29 346 -14 331 -5 ct 320 1 309 4 299 4 ct 289 4 280 0 273 -7 ct +266 -14 262 -25 262 -38 ct 262 -57 268 -77 281 -99 ct 294 -120 311 -138 331 -151 ct +346 -161 361 -166 374 -166 ct 383 -166 390 -164 395 -160 ct 401 -157 405 -151 408 -142 ct +408 -142 408 -142 413 -162 ct 413 -162 413 -162 443 -166 ct p +373 -157 m 365 -157 356 -153 346 -146 ct 332 -136 320 -120 309 -100 ct 298 -80 293 -61 293 -45 ct +293 -37 295 -30 300 -25 ct 305 -20 310 -18 317 -18 ct 332 -18 349 -28 367 -47 ct +389 -73 399 -100 398 -128 ct 398 -138 396 -145 392 -150 ct 387 -155 381 -157 373 -157 ct +p ef +528 -168 m 528 -168 528 -168 504 -84 ct 515 -104 524 -119 532 -129 ct 544 -144 555 -155 567 -162 ct +573 -166 580 -168 588 -168 ct 594 -168 599 -166 603 -162 ct 607 -158 609 -153 609 -147 ct +609 -141 608 -133 605 -123 ct 605 -123 605 -123 591 -76 ct 612 -114 632 -140 652 -155 ct +662 -164 673 -168 683 -168 ct 689 -168 694 -166 698 -162 ct 702 -158 704 -151 704 -143 ct +704 -135 703 -128 700 -120 ct 700 -120 700 -120 677 -48 ct 672 -33 669 -24 669 -22 ct +669 -21 670 -19 671 -18 ct 672 -17 673 -17 674 -17 ct 675 -17 677 -18 680 -20 ct +686 -25 692 -33 698 -42 ct 698 -42 698 -42 704 -38 ct 701 -33 696 -26 688 -18 ct +681 -9 674 -3 669 0 ct 663 3 658 4 654 4 ct 650 4 646 3 643 0 ct 641 -3 639 -7 639 -11 ct +639 -17 642 -29 648 -47 ct 648 -47 648 -47 668 -106 ct 672 -120 674 -128 675 -129 ct +675 -132 675 -134 675 -136 ct 675 -139 675 -142 673 -143 ct 671 -145 670 -146 668 -146 ct +662 -146 656 -143 650 -138 ct 631 -122 613 -100 597 -72 ct 586 -53 576 -29 567 0 ct +567 0 567 0 540 0 ct 540 0 540 0 574 -112 ct 578 -124 580 -132 580 -136 ct 580 -140 579 -142 577 -144 ct +576 -145 574 -146 572 -146 ct 568 -146 564 -145 559 -142 ct 551 -137 542 -126 530 -111 ct +518 -95 508 -80 502 -65 ct 499 -59 491 -37 479 0 ct 479 0 479 0 452 0 ct 452 0 452 0 487 -120 ct +487 -120 487 -120 491 -136 ct 492 -138 493 -140 493 -141 ct 493 -144 491 -146 489 -148 ct +486 -150 483 -151 479 -151 ct 478 -151 473 -150 466 -149 ct 466 -149 466 -149 464 -156 ct +464 -156 464 -156 528 -168 ct p ef +763 -70 m 762 -64 762 -59 762 -55 ct 762 -44 766 -35 774 -27 ct 782 -20 792 -16 803 -16 ct +812 -16 821 -18 830 -21 ct 838 -25 851 -33 867 -45 ct 867 -45 867 -45 871 -40 ct +841 -11 813 4 786 4 ct 768 4 754 -2 745 -13 ct 736 -24 731 -37 731 -51 ct 731 -69 737 -88 748 -107 ct +760 -126 774 -141 792 -152 ct 809 -163 827 -168 845 -168 ct 858 -168 868 -165 874 -160 ct +881 -155 884 -148 884 -141 ct 884 -131 880 -121 871 -112 ct 860 -99 844 -89 823 -82 ct +809 -77 789 -73 763 -70 ct p +764 -79 m 783 -81 799 -85 811 -90 ct 826 -97 838 -105 846 -114 ct 854 -124 858 -133 858 -141 ct +858 -147 856 -151 853 -154 ct 850 -157 845 -159 838 -159 ct 825 -159 811 -152 797 -139 ct +782 -125 771 -105 764 -79 ct p ef +pom +gr +gr +gr +gr +gr +11285 17781 m 10235 17781 l 10235 15384 l 12335 15384 l 12335 17781 l +11285 17781 l pc +gs +2935 18044 m 5886 18044 l 5886 19635 l 2935 19635 l 2935 18044 l eoclip newpath +gs +tm setmatrix +503 15002 t +1 1 s +gs +gs +0 0 m 2956 0 l 2956 1591 l 0 1591 l 0 0 l eoclip newpath +gs +pum +1323 556 t +74 -379 m 74 -379 74 -379 176 -429 ct 176 -429 176 -429 186 -429 ct 186 -429 186 -429 186 -74 ct +186 -50 187 -36 189 -30 ct 191 -24 195 -19 201 -16 ct 207 -13 220 -11 239 -11 ct +239 -11 239 -11 239 0 ct 239 0 239 0 82 0 ct 82 0 82 0 82 -11 ct 101 -11 114 -13 120 -16 ct +125 -19 129 -23 132 -28 ct 134 -33 135 -49 135 -74 ct 135 -74 135 -74 135 -301 ct +135 -331 134 -351 132 -359 ct 130 -366 128 -371 124 -374 ct 120 -377 116 -379 110 -379 ct +103 -379 92 -375 79 -369 ct 79 -369 79 -369 74 -379 ct p ef +pom +gr +gs +132 741 m 2693 0 rl 0 31 rl 2693 neg 0 rl ef p ef + +gr +gs +pum +265 1349 t +208 -345 m 197 -344 l 113 -410 l 25 -342 l 11 -345 l 113 -462 l 208 -345 l +p ef +pom +gr +gs +pum +212 1376 t +331 -261 m 331 -261 331 -261 322 -229 ct 322 -229 322 -229 270 -229 ct 274 -218 276 -207 276 -198 ct +276 -170 264 -146 241 -124 ct 217 -103 185 -91 144 -89 ct 122 -82 106 -75 95 -65 ct +91 -62 89 -59 89 -55 ct 89 -51 91 -47 95 -44 ct 98 -40 108 -37 123 -33 ct 123 -33 123 -33 183 -20 ct +216 -12 238 -3 248 8 ct 259 19 264 31 264 46 ct 264 63 258 78 245 92 ct 233 106 215 117 190 125 ct +166 133 140 137 111 137 ct 85 137 62 134 41 128 ct 20 122 5 114 -4 103 ct -13 93 -18 82 -18 71 ct +-18 63 -15 53 -9 44 ct -3 34 4 26 13 20 ct 19 16 35 7 61 -8 ct 52 -15 47 -23 47 -32 ct +47 -40 51 -49 59 -58 ct 67 -68 85 -78 111 -89 ct 89 -93 71 -103 58 -118 ct 45 -132 39 -149 39 -167 ct +39 -196 52 -222 78 -245 ct 104 -268 138 -280 181 -280 ct 196 -280 209 -278 219 -275 ct +229 -272 239 -268 248 -261 ct 248 -261 248 -261 331 -261 ct p +225 -211 m 225 -228 220 -240 211 -250 ct 201 -259 189 -264 173 -264 ct 149 -264 129 -252 114 -229 ct +98 -206 90 -182 90 -157 ct 90 -141 95 -128 105 -118 ct 115 -108 127 -103 142 -103 ct +153 -103 164 -106 174 -112 ct 185 -118 194 -126 201 -136 ct 209 -147 214 -160 219 -176 ct +223 -192 225 -204 225 -211 ct p +74 0 m 57 8 45 18 36 30 ct 27 42 23 53 23 65 ct 23 79 29 90 42 99 ct 59 112 85 118 120 118 ct +149 118 175 113 196 103 ct 217 93 227 80 227 64 ct 227 56 223 48 215 41 ct 208 34 193 28 170 24 ct +158 21 126 13 74 0 ct p ef +pom +gr +gs +pum +661 1508 t +119 -164 m 119 -164 119 -164 116 -150 ct 116 -150 116 -150 88 -150 ct 88 -150 88 -150 65 -69 ct +55 -34 45 -6 36 13 ct 23 41 9 60 -6 70 ct -18 78 -29 82 -41 82 ct -49 82 -55 80 -60 75 ct +-64 72 -66 68 -66 63 ct -66 59 -64 55 -61 52 ct -58 49 -54 48 -50 48 ct -46 48 -44 49 -41 51 ct +-39 53 -38 56 -38 58 ct -38 61 -39 64 -41 66 ct -43 68 -44 69 -44 70 ct -44 71 -44 72 -43 73 ct +-42 74 -40 74 -38 74 ct -32 74 -27 72 -21 69 ct -15 66 -10 61 -5 54 ct -1 48 3 38 8 26 ct +9 21 14 4 22 -25 ct 22 -25 22 -25 59 -150 ct 59 -150 59 -150 22 -150 ct 22 -150 22 -150 25 -164 ct +36 -164 44 -165 49 -166 ct 53 -168 57 -170 61 -174 ct 65 -178 70 -186 75 -197 ct +82 -212 89 -224 95 -232 ct 104 -243 113 -251 123 -257 ct 132 -262 142 -265 150 -265 ct +159 -265 166 -263 172 -258 ct 177 -253 180 -248 180 -242 ct 180 -238 179 -234 176 -231 ct +173 -228 169 -227 165 -227 ct 161 -227 158 -228 156 -230 ct 153 -233 152 -235 152 -238 ct +152 -240 153 -243 155 -245 ct 157 -248 158 -250 158 -251 ct 158 -253 157 -254 156 -255 ct +155 -256 153 -257 150 -257 ct 143 -257 136 -254 130 -249 ct 122 -242 115 -232 109 -217 ct +106 -210 100 -192 92 -164 ct 92 -164 92 -164 119 -164 ct p ef +125 -158 m 125 -158 125 -158 189 -168 ct 189 -168 189 -168 163 -78 ct 185 -115 204 -141 222 -155 ct +232 -164 240 -168 247 -168 ct 251 -168 254 -167 256 -164 ct 259 -162 260 -158 260 -154 ct +260 -146 258 -138 254 -130 ct 251 -125 247 -122 241 -122 ct 238 -122 236 -123 234 -125 ct +232 -127 230 -130 230 -134 ct 230 -136 229 -138 228 -138 ct 227 -139 226 -140 225 -140 ct +223 -140 221 -140 219 -139 ct 216 -137 211 -132 204 -124 ct 194 -112 183 -96 171 -77 ct +166 -68 161 -59 158 -49 ct 153 -35 150 -26 149 -23 ct 149 -23 149 -23 142 0 ct +142 0 142 0 114 0 ct 114 0 114 0 147 -116 ct 151 -129 153 -139 153 -144 ct 153 -146 153 -148 151 -150 ct +148 -152 145 -153 141 -153 ct 139 -153 134 -152 128 -151 ct 128 -151 128 -151 125 -158 ct +p ef +443 -166 m 443 -166 443 -166 406 -40 ct 406 -40 406 -40 402 -23 ct 402 -21 401 -20 401 -19 ct +401 -17 402 -15 403 -14 ct 403 -13 404 -13 405 -13 ct 406 -13 408 -13 409 -15 ct +413 -18 417 -26 423 -37 ct 423 -37 423 -37 429 -33 ct 422 -20 415 -11 407 -5 ct +399 1 392 4 386 4 ct 382 4 378 3 376 0 ct 373 -3 372 -6 372 -11 ct 372 -17 373 -25 376 -35 ct +376 -35 376 -35 380 -50 ct 362 -29 346 -14 331 -5 ct 320 1 309 4 299 4 ct 289 4 280 0 273 -7 ct +266 -14 262 -25 262 -38 ct 262 -57 268 -77 281 -99 ct 294 -120 311 -138 331 -151 ct +346 -161 361 -166 374 -166 ct 383 -166 390 -164 395 -160 ct 401 -157 405 -151 408 -142 ct +408 -142 408 -142 413 -162 ct 413 -162 413 -162 443 -166 ct p +373 -157 m 365 -157 356 -153 346 -146 ct 332 -136 320 -120 309 -100 ct 298 -80 293 -61 293 -45 ct +293 -37 295 -30 300 -25 ct 305 -20 310 -18 317 -18 ct 332 -18 349 -28 367 -47 ct +389 -73 399 -100 398 -128 ct 398 -138 396 -145 392 -150 ct 387 -155 381 -157 373 -157 ct +p ef +528 -168 m 528 -168 528 -168 504 -84 ct 515 -104 524 -119 532 -129 ct 544 -144 555 -155 567 -162 ct +573 -166 580 -168 588 -168 ct 594 -168 599 -166 603 -162 ct 607 -158 609 -153 609 -147 ct +609 -141 608 -133 605 -123 ct 605 -123 605 -123 591 -76 ct 612 -114 632 -140 652 -155 ct +662 -164 673 -168 683 -168 ct 689 -168 694 -166 698 -162 ct 702 -158 704 -151 704 -143 ct +704 -135 703 -128 700 -120 ct 700 -120 700 -120 677 -48 ct 672 -33 669 -24 669 -22 ct +669 -21 670 -19 671 -18 ct 672 -17 673 -17 674 -17 ct 675 -17 677 -18 680 -20 ct +686 -25 692 -33 698 -42 ct 698 -42 698 -42 704 -38 ct 701 -33 696 -26 688 -18 ct +681 -9 674 -3 669 0 ct 663 3 658 4 654 4 ct 650 4 646 3 643 0 ct 641 -3 639 -7 639 -11 ct +639 -17 642 -29 648 -47 ct 648 -47 648 -47 668 -106 ct 672 -120 674 -128 675 -129 ct +675 -132 675 -134 675 -136 ct 675 -139 675 -142 673 -143 ct 671 -145 670 -146 668 -146 ct +662 -146 656 -143 650 -138 ct 631 -122 613 -100 597 -72 ct 586 -53 576 -29 567 0 ct +567 0 567 0 540 0 ct 540 0 540 0 574 -112 ct 578 -124 580 -132 580 -136 ct 580 -140 579 -142 577 -144 ct +576 -145 574 -146 572 -146 ct 568 -146 564 -145 559 -142 ct 551 -137 542 -126 530 -111 ct +518 -95 508 -80 502 -65 ct 499 -59 491 -37 479 0 ct 479 0 479 0 452 0 ct 452 0 452 0 487 -120 ct +487 -120 487 -120 491 -136 ct 492 -138 493 -140 493 -141 ct 493 -144 491 -146 489 -148 ct +486 -150 483 -151 479 -151 ct 478 -151 473 -150 466 -149 ct 466 -149 466 -149 464 -156 ct +464 -156 464 -156 528 -168 ct p ef +763 -70 m 762 -64 762 -59 762 -55 ct 762 -44 766 -35 774 -27 ct 782 -20 792 -16 803 -16 ct +812 -16 821 -18 830 -21 ct 838 -25 851 -33 867 -45 ct 867 -45 867 -45 871 -40 ct +841 -11 813 4 786 4 ct 768 4 754 -2 745 -13 ct 736 -24 731 -37 731 -51 ct 731 -69 737 -88 748 -107 ct +760 -126 774 -141 792 -152 ct 809 -163 827 -168 845 -168 ct 858 -168 868 -165 874 -160 ct +881 -155 884 -148 884 -141 ct 884 -131 880 -121 871 -112 ct 860 -99 844 -89 823 -82 ct +809 -77 789 -73 763 -70 ct p +764 -79 m 783 -81 799 -85 811 -90 ct 826 -97 838 -105 846 -114 ct 854 -124 858 -133 858 -141 ct +858 -147 856 -151 853 -154 ct 850 -157 845 -159 838 -159 ct 825 -159 811 -152 797 -139 ct +782 -125 771 -105 764 -79 ct p ef +pom +gr +gs +pum +1720 1349 t +208 -345 m 197 -344 l 113 -410 l 25 -342 l 11 -345 l 113 -462 l 208 -345 l +p ef +pom +gr +gs +pum +1667 1376 t +331 -261 m 331 -261 331 -261 322 -229 ct 322 -229 322 -229 270 -229 ct 274 -218 276 -207 276 -198 ct +276 -170 264 -146 241 -124 ct 217 -103 185 -91 144 -89 ct 122 -82 106 -75 95 -65 ct +91 -62 89 -59 89 -55 ct 89 -51 91 -47 95 -44 ct 98 -40 108 -37 123 -33 ct 123 -33 123 -33 183 -20 ct +216 -12 238 -3 248 8 ct 259 19 264 31 264 46 ct 264 63 258 78 245 92 ct 233 106 215 117 190 125 ct +166 133 140 137 111 137 ct 85 137 62 134 41 128 ct 20 122 5 114 -4 103 ct -13 93 -18 82 -18 71 ct +-18 63 -15 53 -9 44 ct -3 34 4 26 13 20 ct 19 16 35 7 61 -8 ct 52 -15 47 -23 47 -32 ct +47 -40 51 -49 59 -58 ct 67 -68 85 -78 111 -89 ct 89 -93 71 -103 58 -118 ct 45 -132 39 -149 39 -167 ct +39 -196 52 -222 78 -245 ct 104 -268 138 -280 181 -280 ct 196 -280 209 -278 219 -275 ct +229 -272 239 -268 248 -261 ct 248 -261 248 -261 331 -261 ct p +225 -211 m 225 -228 220 -240 211 -250 ct 201 -259 189 -264 173 -264 ct 149 -264 129 -252 114 -229 ct +98 -206 90 -182 90 -157 ct 90 -141 95 -128 105 -118 ct 115 -108 127 -103 142 -103 ct +153 -103 164 -106 174 -112 ct 185 -118 194 -126 201 -136 ct 209 -147 214 -160 219 -176 ct +223 -192 225 -204 225 -211 ct p +74 0 m 57 8 45 18 36 30 ct 27 42 23 53 23 65 ct 23 79 29 90 42 99 ct 59 112 85 118 120 118 ct +149 118 175 113 196 103 ct 217 93 227 80 227 64 ct 227 56 223 48 215 41 ct 208 34 193 28 170 24 ct +158 21 126 13 74 0 ct p ef +pom +gr +gs +pum +2064 1508 t +134 -168 m 134 -168 134 -168 124 -111 ct 124 -111 124 -111 117 -111 ct 116 -128 113 -140 107 -148 ct +101 -155 93 -159 84 -159 ct 77 -159 71 -157 66 -153 ct 62 -148 60 -143 60 -137 ct +60 -133 61 -129 63 -126 ct 64 -122 68 -117 74 -110 ct 89 -93 99 -79 103 -70 ct +108 -62 110 -53 110 -45 ct 110 -32 105 -21 94 -11 ct 84 -1 71 4 55 4 ct 46 4 36 2 24 -3 ct +20 -4 17 -5 15 -5 ct 10 -5 6 -2 3 4 ct 3 4 3 4 -4 4 ct -4 4 -4 4 6 -56 ct 6 -56 6 -56 13 -56 ct +14 -37 18 -24 25 -17 ct 32 -9 41 -5 53 -5 ct 63 -5 70 -8 76 -13 ct 81 -18 84 -25 84 -32 ct +84 -37 83 -42 81 -46 ct 78 -53 71 -63 60 -76 ct 49 -89 42 -99 39 -106 ct 36 -112 34 -119 34 -125 ct +34 -137 38 -147 47 -156 ct 55 -164 66 -168 80 -168 ct 83 -168 87 -168 90 -167 ct +92 -167 96 -165 102 -163 ct 108 -160 112 -159 114 -159 ct 119 -159 124 -162 127 -168 ct +127 -168 127 -168 134 -168 ct p ef +331 -164 m 331 -164 331 -164 297 -52 ct 292 -35 289 -24 289 -20 ct 289 -18 290 -16 290 -15 ct +291 -14 292 -14 293 -14 ct 294 -14 296 -15 298 -17 ct 300 -18 306 -26 314 -39 ct +314 -39 314 -39 319 -35 ct 311 -20 302 -9 293 -2 ct 287 2 281 4 276 4 ct 271 4 268 3 266 0 ct +263 -3 262 -6 262 -10 ct 262 -15 263 -20 264 -27 ct 267 -35 273 -55 282 -86 ct +260 -51 242 -28 227 -15 ct 212 -2 198 4 186 4 ct 180 4 175 2 171 -2 ct 167 -6 165 -11 165 -17 ct +165 -26 169 -40 175 -59 ct 175 -59 175 -59 194 -117 ct 199 -130 202 -139 202 -142 ct +202 -144 201 -145 200 -146 ct 198 -147 197 -148 196 -148 ct 192 -148 189 -147 186 -145 ct +183 -143 176 -136 165 -124 ct 165 -124 165 -124 159 -128 ct 169 -143 180 -153 191 -160 ct +200 -165 208 -168 215 -168 ct 220 -168 224 -166 227 -163 ct 230 -160 232 -155 232 -150 ct +232 -143 229 -131 223 -114 ct 223 -114 223 -114 203 -55 ct 197 -39 194 -29 194 -24 ct +194 -22 195 -20 197 -19 ct 199 -17 201 -16 203 -16 ct 208 -16 213 -18 220 -23 ct +227 -27 236 -36 247 -50 ct 259 -64 268 -77 275 -90 ct 282 -102 290 -122 299 -149 ct +299 -149 299 -149 304 -164 ct 304 -164 304 -164 331 -164 ct p ef +453 -265 m 453 -265 453 -265 415 -136 ct 427 -148 437 -157 445 -161 ct 454 -166 463 -168 472 -168 ct +485 -168 496 -164 504 -154 ct 513 -145 517 -133 517 -118 ct 517 -98 511 -78 500 -59 ct +489 -39 475 -23 459 -12 ct 442 -2 425 4 409 4 ct 391 4 372 -3 353 -17 ct 353 -17 353 -17 409 -213 ct +414 -228 416 -236 416 -239 ct 416 -242 415 -244 413 -246 ct 410 -248 406 -249 400 -249 ct +397 -249 393 -249 387 -248 ct 387 -248 387 -248 387 -255 ct 387 -255 387 -255 453 -265 ct +p +380 -15 m 392 -8 403 -5 412 -5 ct 422 -5 433 -9 444 -17 ct 456 -25 465 -38 474 -57 ct +482 -76 486 -95 486 -114 ct 486 -125 483 -134 478 -140 ct 473 -147 466 -150 459 -150 ct +448 -150 437 -145 427 -136 ct 417 -127 409 -114 404 -97 ct 404 -97 404 -97 380 -15 ct +p ef +648 -164 m 648 -164 648 -164 645 -150 ct 645 -150 645 -150 617 -150 ct 617 -150 617 -150 594 -69 ct +584 -34 574 -6 565 13 ct 552 41 538 60 523 70 ct 511 78 500 82 488 82 ct 481 82 474 80 469 75 ct +465 72 463 68 463 63 ct 463 59 465 55 468 52 ct 471 49 475 48 479 48 ct 483 48 485 49 488 51 ct +490 53 491 56 491 58 ct 491 61 490 64 488 66 ct 486 68 485 69 485 70 ct 485 71 485 72 486 73 ct +487 74 489 74 491 74 ct 497 74 502 72 508 69 ct 514 66 519 61 524 54 ct 528 48 532 38 537 26 ct +538 21 543 4 551 -25 ct 551 -25 551 -25 588 -150 ct 588 -150 588 -150 551 -150 ct +551 -150 551 -150 554 -164 ct 565 -164 573 -165 578 -166 ct 582 -168 586 -170 590 -174 ct +594 -178 599 -186 604 -197 ct 611 -212 618 -224 624 -232 ct 633 -243 642 -251 652 -257 ct +661 -262 671 -265 679 -265 ct 688 -265 695 -263 701 -258 ct 706 -253 709 -248 709 -242 ct +709 -238 708 -234 705 -231 ct 702 -228 698 -227 694 -227 ct 690 -227 687 -228 685 -230 ct +682 -233 681 -235 681 -238 ct 681 -240 682 -243 684 -245 ct 686 -248 687 -250 687 -251 ct +687 -253 686 -254 685 -255 ct 684 -256 682 -257 679 -257 ct 672 -257 665 -254 659 -249 ct +651 -242 644 -232 638 -217 ct 635 -210 629 -192 621 -164 ct 621 -164 621 -164 648 -164 ct +p ef +pom +gr +gr +gr +gr +gr +4385 19688 m 2635 19688 l 2635 17888 l 6135 17888 l 6135 19688 l 4385 19688 l +pc +4385 17888 m 4198 17326 l 4573 17326 l 4385 17888 l p ef +4409 12536 m 4409 15212 l 4384 15212 l 4359 15212 l 4359 12536 l 4384 12536 l +4409 12536 l p ef +4384 15212 m 4384 15237 l 4380 15237 l 4375 15235 l 4372 15234 l 4368 15231 l +4365 15228 l 4362 15225 l 4361 15221 l 4359 15216 l 4359 15212 l 4359 15212 l +4384 15212 l p ef +4384 15187 m 4385 15187 l 4385 15212 l 4385 15237 l 4384 15237 l 4384 15212 l +4384 15187 l p ef +4385 15212 m 4385 15187 l 4389 15187 l 4394 15189 l 4397 15190 l 4401 15193 l +4404 15196 l 4407 15199 l 4408 15203 l 4410 15208 l 4410 15212 l 4410 15212 l +4385 15212 l p ef +4410 15212 m 4410 17438 l 4385 17438 l 4360 17438 l 4360 15212 l 4385 15212 l +4410 15212 l p ef +7035 16587 m 6473 16775 l 6473 16400 l 7035 16587 l p ef +4409 12536 m 4409 16587 l 4384 16587 l 4359 16587 l 4359 12536 l 4384 12536 l +4409 12536 l p ef +4384 16587 m 4384 16612 l 4380 16612 l 4375 16610 l 4372 16609 l 4368 16606 l +4365 16603 l 4362 16600 l 4361 16596 l 4359 16591 l 4359 16587 l 4359 16587 l +4384 16587 l p ef +4384 16562 m 6585 16562 l 6585 16587 l 6585 16612 l 4384 16612 l 4384 16587 l +4384 16562 l p ef +10235 16583 m 9674 16775 l 9671 16400 l 10235 16583 l p ef +9135 16562 m 9685 16562 l 9685 16587 l 9685 16612 l 9135 16612 l 9135 16587 l +9135 16562 l p ef +9685 16587 m 9710 16587 l 9710 16591 l 9708 16596 l 9707 16599 l 9704 16603 l +9701 16606 l 9698 16609 l 9694 16610 l 9689 16612 l 9685 16612 l 9685 16612 l +9685 16587 l p ef +9660 16587 m 9660 16583 l 9685 16583 l 9710 16583 l 9710 16587 l 9685 16587 l +9660 16587 l p ef +9685 16583 m 9660 16583 l 9660 16579 l 9662 16574 l 9663 16571 l 9666 16567 l +9669 16564 l 9672 16561 l 9676 16560 l 9681 16558 l 9685 16558 l 9685 16558 l +9685 16583 l p ef +9685 16558 m 9785 16558 l 9785 16583 l 9785 16608 l 9685 16608 l 9685 16583 l +9685 16558 l p ef +4385 22337 m 3971 22337 3635 22001 3635 21587 ct 3635 21173 3971 20837 4385 20837 ct +4799 20837 5135 21173 5135 21587 ct 5135 22001 4799 22337 4385 22337 ct pc +gs +gs +pum +4102 21920 t +246 -115 m 246 -309 l 54 -309 l 54 -390 l 246 -390 l 246 -582 l 328 -582 l +328 -390 l 520 -390 l 520 -309 l 328 -309 l 328 -115 l 246 -115 l +p ef +pom +gr +gr +gs +7170 20868 m 8954 20868 l 8954 22496 l 7170 22496 l 7170 20868 l eoclip newpath +gs +tm setmatrix +4736 17833 t +1 1 s +gs +gs +0 0 m 1784 0 l 1784 1628 l 0 1628 l 0 0 l eoclip newpath +gs +pum +159 556 t +86 9 m 86 9 86 9 122 -341 ct 124 -355 124 -365 124 -373 ct 124 -385 121 -394 114 -400 ct +107 -406 95 -410 77 -410 ct 77 -410 77 -410 81 -421 ct 81 -421 81 -421 237 -421 ct +237 -421 237 -421 234 -410 ct 213 -410 198 -406 191 -399 ct 183 -391 177 -372 175 -341 ct +175 -341 175 -341 151 -113 ct 151 -113 151 -113 311 -361 ct 311 -365 311 -369 311 -371 ct +311 -383 308 -392 301 -398 ct 294 -405 279 -409 257 -410 ct 257 -410 257 -410 259 -421 ct +259 -421 259 -421 430 -421 ct 430 -421 430 -421 426 -410 ct 407 -410 393 -408 387 -405 ct +382 -403 377 -399 374 -394 ct 371 -389 368 -380 366 -368 ct 365 -364 363 -340 358 -296 ct +354 -251 347 -190 338 -113 ct 338 -113 338 -113 472 -317 ct 486 -339 496 -354 499 -363 ct +503 -372 505 -380 505 -386 ct 505 -392 502 -397 497 -401 ct 492 -406 484 -409 472 -410 ct +472 -410 472 -410 474 -421 ct 474 -421 474 -421 599 -421 ct 599 -421 599 -421 596 -410 ct +585 -409 575 -406 567 -402 ct 558 -397 548 -389 537 -376 ct 530 -368 516 -349 496 -317 ct +496 -317 496 -317 284 9 ct 284 9 284 9 273 9 ct 273 9 273 9 307 -317 ct 307 -317 307 -317 97 9 ct +97 9 97 9 86 9 ct p ef +pom +gr +gs +pum +847 556 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1138 556 t +54 -273 m 54 -273 54 -273 249 -273 ct 249 -273 249 -273 249 -265 ct 249 -265 249 -265 35 -42 ct +35 -42 35 -42 125 -42 ct 147 -42 161 -43 166 -44 ct 172 -46 178 -50 183 -55 ct +187 -60 193 -70 199 -84 ct 199 -84 199 -84 210 -84 ct 210 -84 210 -84 183 0 ct +183 0 183 0 -18 0 ct -18 0 -18 0 -18 -9 ct -18 -9 -18 -9 196 -232 ct 196 -232 196 -232 109 -232 ct +90 -232 78 -232 74 -231 ct 68 -229 63 -226 57 -221 ct 51 -216 45 -208 39 -196 ct +39 -196 39 -196 28 -196 ct 28 -196 28 -196 54 -273 ct p ef +pom +gr +gs +pum +1429 556 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gs +132 767 m 1521 0 rl 0 31 rl 1521 neg 0 rl ef p ef + +gr +gs +pum +370 1323 t +208 -345 m 197 -344 l 113 -410 l 25 -342 l 11 -345 l 113 -462 l 208 -345 l +p ef +pom +gr +gs +pum +318 1455 t +328 -430 m 328 -430 328 -430 296 -80 ct 294 -64 294 -53 294 -48 ct 294 -40 295 -33 298 -29 ct +302 -23 307 -18 314 -15 ct 321 -12 332 -11 348 -11 ct 348 -11 348 -11 345 0 ct +345 0 345 0 180 0 ct 180 0 180 0 184 -11 ct 184 -11 184 -11 191 -11 ct 204 -11 215 -14 224 -20 ct +230 -24 234 -30 238 -39 ct 240 -46 242 -61 244 -85 ct 244 -85 244 -85 249 -138 ct +249 -138 249 -138 128 -138 ct 128 -138 128 -138 86 -80 ct 76 -67 70 -57 67 -52 ct +65 -46 64 -41 64 -36 ct 64 -29 66 -24 72 -19 ct 77 -14 86 -11 98 -11 ct 98 -11 98 -11 95 0 ct +95 0 95 0 -30 0 ct -30 0 -30 0 -27 -11 ct -12 -12 2 -17 14 -26 ct 25 -36 43 -57 66 -88 ct +66 -88 66 -88 317 -430 ct 317 -430 317 -430 328 -430 ct p +268 -327 m 144 -159 l 251 -159 l 268 -327 l p ef +pom +gr +gs +pum +767 1455 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1032 1455 t +54 -273 m 54 -273 54 -273 249 -273 ct 249 -273 249 -273 249 -265 ct 249 -265 249 -265 35 -42 ct +35 -42 35 -42 125 -42 ct 147 -42 161 -43 166 -44 ct 172 -46 178 -50 183 -55 ct +187 -60 193 -70 199 -84 ct 199 -84 199 -84 210 -84 ct 210 -84 210 -84 183 0 ct +183 0 183 0 -18 0 ct -18 0 -18 0 -18 -9 ct -18 -9 -18 -9 196 -232 ct 196 -232 196 -232 109 -232 ct +90 -232 78 -232 74 -231 ct 68 -229 63 -226 57 -221 ct 51 -216 45 -208 39 -196 ct +39 -196 39 -196 28 -196 ct 28 -196 28 -196 54 -273 ct p ef +pom +gr +gs +pum +1349 1455 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gr +gr +gr +gr +8085 22487 m 7035 22487 l 7035 20687 l 9135 20687 l 9135 22487 l 8085 22487 l +pc +5135 21586 m 5698 21399 l 5698 21774 l 5135 21586 l p ef +7035 21612 m 6085 21612 l 6085 21587 l 6085 21562 l 7035 21562 l 7035 21587 l +7035 21612 l p ef +6085 21587 m 6085 21612 l 6081 21612 l 6076 21610 l 6073 21609 l 6069 21606 l +6066 21603 l 6063 21600 l 6062 21596 l 6060 21591 l 6060 21587 l 6060 21587 l +6085 21587 l p ef +6060 21587 m 6060 21586 l 6085 21586 l 6110 21586 l 6110 21587 l 6085 21587 l +6060 21587 l p ef +6085 21586 m 6085 21561 l 6089 21561 l 6094 21563 l 6097 21564 l 6101 21567 l +6104 21570 l 6107 21573 l 6108 21577 l 6110 21582 l 6110 21586 l 6110 21586 l +6085 21586 l p ef +6085 21611 m 5585 21611 l 5585 21586 l 5585 21561 l 6085 21561 l 6085 21586 l +6085 21611 l p ef +12135 22485 m 10635 22485 l 10635 20685 l 13635 20685 l 13635 22485 l +12135 22485 l pc +gs +gs +pum +11484 21451 t +116 -354 m 116 -354 116 -354 116 -207 ct 116 -207 116 -207 184 -207 ct 200 -207 211 -210 218 -217 ct +226 -224 231 -238 233 -258 ct 233 -258 233 -258 243 -258 ct 243 -258 243 -258 243 -131 ct +243 -131 243 -131 233 -131 ct 233 -146 231 -156 227 -163 ct 224 -170 219 -175 212 -179 ct +206 -182 197 -184 184 -184 ct 184 -184 184 -184 116 -184 ct 116 -184 116 -184 116 -66 ct +116 -47 117 -35 120 -28 ct 121 -24 125 -20 131 -17 ct 139 -12 147 -10 156 -10 ct +156 -10 156 -10 169 -10 ct 169 -10 169 -10 169 0 ct 169 0 169 0 10 0 ct 10 0 10 0 10 -10 ct +10 -10 10 -10 23 -10 ct 38 -10 50 -15 56 -24 ct 61 -29 63 -44 63 -66 ct 63 -66 63 -66 63 -308 ct +63 -327 62 -339 59 -346 ct 58 -350 54 -354 48 -357 ct 40 -362 32 -364 23 -364 ct +23 -364 23 -364 10 -364 ct 10 -364 10 -364 10 -374 ct 10 -374 10 -374 286 -374 ct +286 -374 286 -374 290 -292 ct 290 -292 290 -292 280 -292 ct 275 -310 270 -322 264 -331 ct +258 -339 250 -345 241 -348 ct 231 -352 217 -354 198 -354 ct 198 -354 198 -354 116 -354 ct +p ef +395 -392 m 403 -392 409 -389 415 -384 ct 420 -378 423 -372 423 -364 ct 423 -356 420 -350 415 -344 ct +409 -339 403 -336 395 -336 ct 387 -336 381 -339 375 -344 ct 370 -350 367 -356 367 -364 ct +367 -372 370 -378 375 -384 ct 381 -389 387 -392 395 -392 ct p +418 -260 m 418 -260 418 -260 418 -57 ct 418 -41 419 -31 421 -26 ct 424 -20 427 -16 431 -14 ct +436 -11 443 -10 455 -10 ct 455 -10 455 -10 455 0 ct 455 0 455 0 335 0 ct 335 0 335 0 335 -10 ct +347 -10 355 -11 359 -14 ct 363 -16 366 -20 368 -25 ct 371 -31 372 -41 372 -57 ct +372 -57 372 -57 372 -154 ct 372 -181 371 -199 370 -207 ct 368 -213 366 -217 364 -220 ct +361 -222 357 -223 352 -223 ct 347 -223 341 -222 334 -219 ct 334 -219 334 -219 330 -229 ct +330 -229 330 -229 406 -260 ct 406 -260 406 -260 418 -260 ct p ef +477 -253 m 477 -253 477 -253 593 -253 ct 593 -253 593 -253 593 -243 ct 586 -243 581 -242 578 -239 ct +575 -236 574 -233 574 -229 ct 574 -224 578 -217 585 -208 ct 587 -205 590 -200 594 -194 ct +594 -194 594 -194 612 -166 ct 612 -166 612 -166 633 -194 ct 646 -211 653 -223 653 -228 ct +653 -232 651 -236 648 -239 ct 645 -242 640 -243 633 -243 ct 633 -243 633 -243 633 -253 ct +633 -253 633 -253 716 -253 ct 716 -253 716 -253 716 -243 ct 707 -242 700 -240 693 -236 ct +684 -229 672 -216 657 -195 ct 657 -195 657 -195 623 -149 ct 623 -149 623 -149 685 -58 ct +701 -36 712 -22 718 -18 ct 725 -13 733 -11 744 -10 ct 744 -10 744 -10 744 0 ct +744 0 744 0 624 0 ct 624 0 624 0 624 -10 ct 632 -10 639 -12 644 -16 ct 647 -18 649 -22 649 -26 ct +649 -30 643 -41 631 -58 ct 631 -58 631 -58 594 -112 ct 594 -112 594 -112 554 -59 ct +542 -42 536 -32 536 -29 ct 536 -24 538 -20 542 -16 ct 546 -12 553 -10 561 -10 ct +561 -10 561 -10 561 0 ct 561 0 561 0 479 0 ct 479 0 479 0 479 -10 ct 486 -11 491 -13 496 -17 ct +503 -22 515 -36 531 -58 ct 531 -58 531 -58 584 -128 ct 584 -128 584 -128 536 -198 ct +523 -218 512 -230 505 -235 ct 497 -240 488 -243 477 -243 ct 477 -243 477 -243 477 -253 ct +p ef +814 -158 m 814 -121 823 -92 841 -71 ct 859 -50 880 -39 905 -39 ct 921 -39 936 -43 948 -52 ct +960 -61 970 -77 978 -99 ct 978 -99 978 -99 987 -94 ct 983 -68 972 -45 953 -24 ct +935 -3 912 7 884 7 ct 854 7 828 -5 806 -28 ct 785 -52 774 -83 774 -123 ct 774 -166 785 -200 807 -224 ct +829 -248 857 -260 890 -260 ct 918 -260 942 -251 960 -232 ct 978 -214 987 -189 987 -158 ct +987 -158 987 -158 814 -158 ct p +814 -174 m 814 -174 814 -174 930 -174 ct 929 -190 927 -201 924 -208 ct 920 -218 913 -226 904 -231 ct +895 -237 885 -240 876 -240 ct 860 -240 847 -234 835 -223 ct 823 -211 816 -195 814 -174 ct +p ef +1201 -29 m 1189 -16 1177 -7 1165 -1 ct 1153 4 1140 7 1127 7 ct 1099 7 1075 -4 1054 -27 ct +1033 -50 1023 -80 1023 -116 ct 1023 -152 1034 -185 1057 -215 ct 1080 -245 1110 -260 1146 -260 ct +1168 -260 1186 -252 1201 -237 ct 1201 -237 1201 -237 1201 -286 ct 1201 -314 1200 -332 1199 -338 ct +1198 -345 1195 -349 1192 -352 ct 1190 -354 1186 -355 1182 -355 ct 1177 -355 1170 -354 1163 -351 ct +1163 -351 1163 -351 1159 -361 ct 1159 -361 1159 -361 1234 -392 ct 1234 -392 1234 -392 1246 -392 ct +1246 -392 1246 -392 1246 -99 ct 1246 -70 1247 -53 1248 -46 ct 1249 -40 1252 -36 1255 -33 ct +1258 -31 1261 -29 1265 -29 ct 1270 -29 1277 -31 1285 -34 ct 1285 -34 1285 -34 1288 -24 ct +1288 -24 1288 -24 1214 7 ct 1214 7 1214 7 1201 7 ct 1201 7 1201 7 1201 -29 ct p +1201 -48 m 1201 -48 1201 -48 1201 -177 ct 1200 -189 1197 -201 1191 -211 ct +1186 -221 1178 -229 1169 -234 ct 1160 -239 1151 -242 1142 -242 ct 1126 -242 1112 -235 1099 -220 ct +1082 -201 1074 -174 1074 -137 ct 1074 -100 1082 -72 1098 -52 ct 1115 -33 1133 -23 1152 -23 ct +1169 -23 1185 -31 1201 -48 ct p ef +pom +gr +gs +pum +11027 22078 t +233 -95 m 226 -62 213 -37 193 -19 ct 173 -2 151 7 127 7 ct 98 7 73 -5 52 -29 ct +31 -53 20 -85 20 -126 ct 20 -166 32 -198 55 -223 ct 79 -248 108 -260 141 -260 ct +166 -260 186 -253 202 -240 ct 218 -227 226 -214 226 -199 ct 226 -192 224 -187 219 -182 ct +215 -178 208 -176 200 -176 ct 190 -176 182 -180 176 -187 ct 173 -190 171 -198 170 -209 ct +169 -220 165 -228 158 -234 ct 152 -239 143 -242 132 -242 ct 113 -242 99 -235 87 -222 ct +72 -204 65 -180 65 -150 ct 65 -120 72 -94 87 -71 ct 102 -48 122 -36 147 -36 ct +165 -36 181 -42 196 -54 ct 206 -62 215 -77 225 -99 ct 225 -99 225 -99 233 -95 ct +p ef +392 -260 m 430 -260 461 -246 484 -217 ct 503 -192 513 -163 513 -131 ct 513 -109 508 -86 497 -63 ct +486 -40 471 -22 452 -11 ct 433 1 412 7 389 7 ct 351 7 321 -8 298 -38 ct 279 -64 270 -92 270 -124 ct +270 -147 276 -170 287 -193 ct 299 -216 314 -233 332 -244 ct 351 -255 371 -260 392 -260 ct +p +383 -242 m 374 -242 364 -239 354 -233 ct 344 -228 336 -218 330 -203 ct 324 -189 321 -170 321 -147 ct +321 -111 328 -79 343 -53 ct 358 -26 377 -13 401 -13 ct 418 -13 433 -20 445 -35 ct +456 -50 462 -75 462 -110 ct 462 -155 452 -190 433 -216 ct 420 -233 403 -242 383 -242 ct +p ef +731 -29 m 719 -16 707 -7 695 -1 ct 683 4 670 7 657 7 ct 629 7 605 -4 584 -27 ct +563 -50 553 -80 553 -116 ct 553 -152 564 -185 587 -215 ct 610 -245 640 -260 676 -260 ct +698 -260 716 -252 731 -237 ct 731 -237 731 -237 731 -286 ct 731 -314 730 -332 729 -338 ct +728 -345 725 -349 722 -352 ct 720 -354 716 -355 712 -355 ct 707 -355 700 -354 693 -351 ct +693 -351 693 -351 689 -361 ct 689 -361 689 -361 764 -392 ct 764 -392 764 -392 776 -392 ct +776 -392 776 -392 776 -99 ct 776 -70 777 -53 778 -46 ct 779 -40 782 -36 785 -33 ct +788 -31 791 -29 795 -29 ct 800 -29 807 -31 815 -34 ct 815 -34 815 -34 818 -24 ct +818 -24 818 -24 744 7 ct 744 7 744 7 731 7 ct 731 7 731 7 731 -29 ct p +731 -48 m 731 -48 731 -48 731 -177 ct 730 -189 727 -201 721 -211 ct 716 -221 708 -229 699 -234 ct +690 -239 681 -242 672 -242 ct 656 -242 642 -235 629 -220 ct 612 -201 604 -174 604 -137 ct +604 -100 612 -72 628 -52 ct 645 -33 663 -23 682 -23 ct 699 -23 715 -31 731 -48 ct +p ef +877 -158 m 877 -121 886 -92 904 -71 ct 922 -50 943 -39 968 -39 ct 984 -39 999 -43 1011 -52 ct +1023 -61 1033 -77 1041 -99 ct 1041 -99 1041 -99 1050 -94 ct 1046 -68 1035 -45 1016 -24 ct +998 -3 975 7 947 7 ct 917 7 891 -5 869 -28 ct 848 -52 837 -83 837 -123 ct 837 -166 848 -200 870 -224 ct +892 -248 920 -260 953 -260 ct 981 -260 1005 -251 1023 -232 ct 1041 -214 1050 -189 1050 -158 ct +1050 -158 1050 -158 877 -158 ct p +877 -174 m 877 -174 877 -174 993 -174 ct 992 -190 990 -201 987 -208 ct 983 -218 976 -226 967 -231 ct +958 -237 948 -240 939 -240 ct 923 -240 910 -234 898 -223 ct 886 -211 879 -195 877 -174 ct +p ef +1154 -209 m 1178 -243 1205 -260 1233 -260 ct 1259 -260 1281 -249 1300 -227 ct +1319 -205 1329 -175 1329 -136 ct 1329 -92 1314 -56 1284 -28 ct 1259 -5 1230 7 1199 7 ct +1184 7 1170 4 1154 -1 ct 1139 -6 1124 -14 1108 -25 ct 1108 -25 1108 -25 1108 -286 ct +1108 -314 1107 -332 1106 -338 ct 1105 -345 1102 -349 1099 -352 ct 1096 -354 1093 -355 1088 -355 ct +1083 -355 1077 -354 1069 -351 ct 1069 -351 1069 -351 1065 -361 ct 1065 -361 1065 -361 1141 -392 ct +1141 -392 1141 -392 1154 -392 ct 1154 -392 1154 -392 1154 -209 ct p +1154 -192 m 1154 -192 1154 -192 1154 -41 ct 1163 -32 1173 -25 1183 -20 ct 1193 -15 1203 -13 1213 -13 ct +1230 -13 1245 -22 1260 -41 ct 1274 -59 1281 -86 1281 -121 ct 1281 -153 1274 -178 1260 -195 ct +1245 -212 1229 -221 1211 -221 ct 1201 -221 1192 -219 1182 -214 ct 1175 -210 1165 -203 1154 -192 ct +p ef +1492 -260 m 1530 -260 1561 -246 1584 -217 ct 1603 -192 1613 -163 1613 -131 ct +1613 -109 1608 -86 1597 -63 ct 1586 -40 1571 -22 1552 -11 ct 1533 1 1512 7 1489 7 ct +1451 7 1421 -8 1398 -38 ct 1379 -64 1370 -92 1370 -124 ct 1370 -147 1376 -170 1387 -193 ct +1399 -216 1414 -233 1432 -244 ct 1451 -255 1471 -260 1492 -260 ct p +1483 -242 m 1474 -242 1464 -239 1454 -233 ct 1444 -228 1436 -218 1430 -203 ct +1424 -189 1421 -170 1421 -147 ct 1421 -111 1428 -79 1443 -53 ct 1458 -26 1477 -13 1501 -13 ct +1518 -13 1533 -20 1545 -35 ct 1556 -50 1562 -75 1562 -110 ct 1562 -155 1552 -190 1533 -216 ct +1520 -233 1503 -242 1483 -242 ct p ef +1776 -260 m 1814 -260 1845 -246 1868 -217 ct 1887 -192 1897 -163 1897 -131 ct +1897 -109 1892 -86 1881 -63 ct 1870 -40 1855 -22 1836 -11 ct 1817 1 1796 7 1773 7 ct +1735 7 1705 -8 1682 -38 ct 1663 -64 1654 -92 1654 -124 ct 1654 -147 1660 -170 1671 -193 ct +1683 -216 1698 -233 1716 -244 ct 1735 -255 1755 -260 1776 -260 ct p +1767 -242 m 1758 -242 1748 -239 1738 -233 ct 1728 -228 1720 -218 1714 -203 ct +1708 -189 1705 -170 1705 -147 ct 1705 -111 1712 -79 1727 -53 ct 1742 -26 1761 -13 1785 -13 ct +1802 -13 1817 -20 1829 -35 ct 1840 -50 1846 -75 1846 -110 ct 1846 -155 1836 -190 1817 -216 ct +1804 -233 1787 -242 1767 -242 ct p ef +2011 -392 m 2011 -392 2011 -392 2011 -141 ct 2011 -141 2011 -141 2074 -200 ct +2088 -212 2096 -220 2098 -223 ct 2100 -225 2100 -227 2100 -229 ct 2100 -233 2099 -236 2096 -239 ct +2093 -241 2088 -243 2081 -243 ct 2081 -243 2081 -243 2081 -253 ct 2081 -253 2081 -253 2190 -253 ct +2190 -253 2190 -253 2190 -244 ct 2175 -244 2163 -241 2153 -237 ct 2143 -233 2132 -225 2120 -214 ct +2120 -214 2120 -214 2056 -155 ct 2056 -155 2056 -155 2120 -72 ct 2138 -50 2150 -35 2155 -29 ct +2164 -21 2172 -15 2179 -13 ct 2183 -11 2192 -10 2203 -10 ct 2203 -10 2203 -10 2203 0 ct +2203 0 2203 0 2081 0 ct 2081 0 2081 0 2081 -10 ct 2088 -10 2092 -11 2095 -13 ct +2097 -15 2099 -18 2099 -21 ct 2099 -26 2095 -32 2088 -42 ct 2088 -42 2088 -42 2011 -141 ct +2011 -141 2011 -141 2011 -57 ct 2011 -41 2012 -30 2014 -25 ct 2017 -19 2020 -16 2024 -14 ct +2029 -11 2038 -10 2052 -10 ct 2052 -10 2052 -10 2052 0 ct 2052 0 2052 0 1924 0 ct +1924 0 1924 0 1924 -10 ct 1937 -10 1946 -12 1952 -15 ct 1956 -17 1959 -20 1961 -24 ct +1964 -30 1965 -40 1965 -55 ct 1965 -55 1965 -55 1965 -286 ct 1965 -315 1964 -332 1963 -339 ct +1962 -345 1960 -350 1957 -352 ct 1954 -354 1950 -356 1946 -356 ct 1942 -356 1936 -354 1929 -351 ct +1929 -351 1929 -351 1924 -361 ct 1924 -361 1924 -361 1998 -392 ct 1998 -392 1998 -392 2011 -392 ct +p ef +pom +gr +gr +9135 21587 m 9698 21400 l 9698 21775 l 9135 21587 l p ef +10635 21610 m 9885 21610 l 9885 21585 l 9885 21560 l 10635 21560 l +10635 21585 l 10635 21610 l p ef +9885 21585 m 9860 21585 l 9860 21581 l 9862 21576 l 9863 21573 l 9866 21569 l +9869 21566 l 9872 21563 l 9876 21562 l 9881 21560 l 9885 21560 l 9885 21560 l +9885 21585 l p ef +9910 21585 m 9910 21587 l 9885 21587 l 9860 21587 l 9860 21585 l 9885 21585 l +9910 21585 l p ef +9885 21587 m 9910 21587 l 9910 21591 l 9908 21596 l 9907 21599 l 9904 21603 l +9901 21606 l 9898 21609 l 9894 21610 l 9889 21612 l 9885 21612 l 9885 21612 l +9885 21587 l p ef +9885 21612 m 9585 21612 l 9585 21587 l 9585 21562 l 9885 21562 l 9885 21587 l +9885 21612 l p ef +4384 20837 m 4197 20275 l 4572 20275 l 4384 20837 l p ef +4410 19688 m 4410 20263 l 4385 20263 l 4360 20263 l 4360 19688 l 4385 19688 l +4410 19688 l p ef +4385 20263 m 4410 20263 l 4410 20267 l 4408 20272 l 4407 20275 l 4404 20279 l +4401 20282 l 4398 20285 l 4394 20286 l 4389 20288 l 4385 20288 l 4385 20288 l +4385 20263 l p ef +4385 20288 m 4384 20288 l 4384 20263 l 4384 20238 l 4385 20238 l 4385 20263 l +4385 20288 l p ef +4384 20263 m 4359 20263 l 4359 20259 l 4361 20254 l 4362 20251 l 4365 20247 l +4368 20244 l 4371 20241 l 4375 20240 l 4380 20238 l 4384 20238 l 4384 20238 l +4384 20263 l p ef +4409 20263 m 4409 20387 l 4384 20387 l 4359 20387 l 4359 20263 l 4384 20263 l +4409 20263 l p ef +gs +7270 13617 m 8965 13617 l 8965 14492 l 7270 14492 l 7270 13617 l eoclip newpath +gs +tm setmatrix +4842 10583 t +1 1 s +gs +gs +0 0 m 1695 0 l 1695 875 l 0 875 l 0 0 l eoclip newpath +gs +pum +106 741 t +650 93 m 650 93 650 93 56 93 ct 56 93 56 93 56 76 ct 56 76 56 76 359 -301 ct 359 -301 359 -301 56 -670 ct +56 -670 56 -670 56 -687 ct 56 -687 56 -687 634 -687 ct 634 -687 634 -687 646 -534 ct +646 -534 646 -534 627 -534 ct 620 -611 582 -650 516 -650 ct 516 -650 516 -650 181 -650 ct +181 -650 181 -650 435 -339 ct 435 -339 435 -339 150 13 ct 150 13 150 13 520 13 ct +595 13 642 -24 661 -98 ct 661 -98 661 -98 679 -96 ct 679 -96 679 -96 650 93 ct +p ef +pom +gr +gs +pum +953 661 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1217 661 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gs +pum +1402 344 t +175 -48 m 175 -48 175 -48 157 0 ct 157 0 157 0 8 0 ct 8 0 8 0 8 -7 ct 52 -47 83 -79 101 -105 ct +119 -130 128 -153 128 -174 ct 128 -190 123 -204 113 -214 ct 103 -225 91 -230 78 -230 ct +65 -230 54 -226 44 -219 ct 34 -212 27 -202 22 -188 ct 22 -188 22 -188 15 -188 ct +18 -211 26 -228 39 -240 ct 52 -252 68 -258 88 -258 ct 108 -258 125 -251 139 -238 ct +153 -225 160 -209 160 -191 ct 160 -179 157 -166 151 -153 ct 142 -133 127 -112 106 -89 ct +75 -55 55 -35 48 -28 ct 48 -28 48 -28 114 -28 ct 127 -28 137 -29 142 -29 ct 147 -30 152 -32 157 -36 ct +161 -39 165 -43 168 -48 ct 168 -48 168 -48 175 -48 ct p ef +pom +gr +gr +gr +gr +gr +8085 14734 m 7035 14734 l 7035 13385 l 9135 13385 l 9135 14734 l 8085 14734 l +pc +7035 14060 m 6473 14248 l 6473 13873 l 7035 14060 l p ef +4409 12536 m 4409 13044 l 4359 13044 l 4359 12536 l 4409 12536 l p ef +4409 13552 m 4409 14060 l 4359 14060 l 4359 13552 l 4409 13552 l p ef +4892 14035 m 5400 14035 l 5400 14085 l 4892 14085 l 4892 14035 l p ef +5908 14035 m 6416 14035 l 6416 14085 l 5908 14085 l 5908 14035 l p ef +11685 12685 m 11873 13248 l 11498 13248 l 11685 12685 l p ef +9135 14035 m 9643 14035 l 9643 14085 l 9135 14085 l 9135 14035 l p ef +10151 14035 m 10659 14035 l 10659 14085 l 10151 14085 l 10151 14035 l +p ef +11167 14035 m 11675 14035 l 11675 14085 l 11167 14085 l 11167 14035 l +p ef +11660 13562 m 11660 13135 l 11710 13135 l 11710 13562 l 11660 13562 l +p ef +15735 12685 m 15923 13248 l 15548 13248 l 15735 12685 l p ef +9135 14035 m 9643 14035 l 9643 14085 l 9135 14085 l 9135 14035 l p ef +10151 14035 m 10659 14035 l 10659 14085 l 10151 14085 l 10151 14035 l +p ef +11167 14035 m 11675 14035 l 11675 14085 l 11167 14085 l 11167 14035 l +p ef +12183 14035 m 12691 14035 l 12691 14085 l 12183 14085 l 12183 14035 l +p ef +13199 14035 m 13707 14035 l 13707 14085 l 13199 14085 l 13199 14035 l +p ef +14215 14035 m 14723 14035 l 14723 14085 l 14215 14085 l 14215 14035 l +p ef +15231 14035 m 15735 14035 l 15735 14060 l 15735 14085 l 15231 14085 l +15231 14060 l 15231 14035 l p ef +15735 14060 m 15760 14060 l 15760 14064 l 15758 14069 l 15757 14072 l +15754 14076 l 15751 14079 l 15748 14082 l 15744 14083 l 15739 14085 l +15735 14085 l 15735 14085 l 15735 14060 l p ef +15710 14060 m 15710 14056 l 15735 14056 l 15760 14056 l 15760 14060 l +15735 14060 l 15710 14060 l p ef +15710 13548 m 15710 13135 l 15760 13135 l 15760 13548 l 15710 13548 l +p ef +gs +7270 23718 m 8965 23718 l 8965 24593 l 7270 24593 l 7270 23718 l eoclip newpath +gs +tm setmatrix +4842 20690 t +1 1 s +gs +gs +0 0 m 1695 0 l 1695 875 l 0 875 l 0 0 l eoclip newpath +gs +pum +106 741 t +650 93 m 650 93 650 93 56 93 ct 56 93 56 93 56 76 ct 56 76 56 76 359 -301 ct 359 -301 359 -301 56 -670 ct +56 -670 56 -670 56 -687 ct 56 -687 56 -687 634 -687 ct 634 -687 634 -687 646 -534 ct +646 -534 646 -534 627 -534 ct 620 -611 582 -650 516 -650 ct 516 -650 516 -650 181 -650 ct +181 -650 181 -650 435 -339 ct 435 -339 435 -339 150 13 ct 150 13 150 13 520 13 ct +595 13 642 -24 661 -98 ct 661 -98 661 -98 679 -96 ct 679 -96 679 -96 650 93 ct +p ef +pom +gr +gs +pum +953 661 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1217 661 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gs +pum +1402 344 t +175 -48 m 175 -48 175 -48 157 0 ct 157 0 157 0 8 0 ct 8 0 8 0 8 -7 ct 52 -47 83 -79 101 -105 ct +119 -130 128 -153 128 -174 ct 128 -190 123 -204 113 -214 ct 103 -225 91 -230 78 -230 ct +65 -230 54 -226 44 -219 ct 34 -212 27 -202 22 -188 ct 22 -188 22 -188 15 -188 ct +18 -211 26 -228 39 -240 ct 52 -252 68 -258 88 -258 ct 108 -258 125 -251 139 -238 ct +153 -225 160 -209 160 -191 ct 160 -179 157 -166 151 -153 ct 142 -133 127 -112 106 -89 ct +75 -55 55 -35 48 -28 ct 48 -28 48 -28 114 -28 ct 127 -28 137 -29 142 -29 ct 147 -30 152 -32 157 -36 ct +161 -39 165 -43 168 -48 ct 168 -48 168 -48 175 -48 ct p ef +pom +gr +gr +gr +gr +gr +8085 24835 m 7035 24835 l 7035 23486 l 9135 23486 l 9135 24835 l 8085 24835 l +pc +7035 24161 m 6473 24349 l 6473 23974 l 7035 24161 l p ef +4409 22337 m 4409 22845 l 4359 22845 l 4359 22337 l 4409 22337 l p ef +4409 23353 m 4409 23861 l 4359 23861 l 4359 23353 l 4409 23353 l p ef +4592 24136 m 5100 24136 l 5100 24186 l 4592 24186 l 4592 24136 l p ef +5608 24136 m 6116 24136 l 6116 24186 l 5608 24186 l 5608 24136 l p ef +12135 22485 m 12323 23048 l 11948 23048 l 12135 22485 l p ef +9135 24136 m 9643 24136 l 9643 24186 l 9135 24186 l 9135 24136 l p ef +10151 24136 m 10659 24136 l 10659 24186 l 10151 24186 l 10151 24136 l +p ef +11167 24136 m 11675 24136 l 11675 24186 l 11167 24186 l 11167 24136 l +p ef +12110 24113 m 12110 23605 l 12160 23605 l 12160 24113 l 12110 24113 l +p ef +12110 23097 m 12110 22935 l 12160 22935 l 12160 23097 l 12110 23097 l +p ef +gs +gs +pum +11087 14652 t +0 -228 m 0 -228 0 -228 78 -259 ct 78 -259 78 -259 89 -259 ct 89 -259 89 -259 89 -201 ct +102 -223 115 -238 128 -247 ct 141 -256 155 -260 169 -260 ct 194 -260 215 -250 232 -230 ct +253 -206 263 -175 263 -136 ct 263 -92 251 -56 226 -28 ct 205 -5 180 7 149 7 ct +135 7 123 5 114 1 ct 106 -2 98 -7 89 -16 ct 89 -16 89 -16 89 63 ct 89 80 90 91 92 96 ct +94 100 98 104 103 107 ct 109 110 118 111 132 111 ct 132 111 132 111 132 121 ct +132 121 132 121 -3 121 ct -3 121 -3 121 -3 111 ct -3 111 -3 111 4 111 ct 14 111 23 109 31 105 ct +34 103 37 100 39 95 ct 41 91 42 79 42 61 ct 42 61 42 61 42 -179 ct 42 -195 41 -205 40 -209 ct +38 -213 36 -216 33 -219 ct 30 -221 25 -222 20 -222 ct 16 -222 10 -221 3 -218 ct +3 -218 3 -218 0 -228 ct p +89 -185 m 89 -185 89 -185 89 -90 ct 89 -70 90 -57 91 -50 ct 94 -40 100 -30 110 -22 ct +120 -14 133 -10 148 -10 ct 166 -10 181 -17 192 -31 ct 207 -50 214 -77 214 -111 ct +214 -149 206 -179 189 -200 ct 177 -214 163 -221 147 -221 ct 139 -221 130 -219 121 -214 ct +115 -211 104 -201 89 -185 ct p ef +366 -392 m 374 -392 380 -389 386 -384 ct 391 -378 394 -372 394 -364 ct 394 -356 391 -350 386 -344 ct +380 -339 374 -336 366 -336 ct 358 -336 352 -339 346 -344 ct 341 -350 338 -356 338 -364 ct +338 -372 341 -378 346 -384 ct 352 -389 358 -392 366 -392 ct p +389 -260 m 389 -260 389 -260 389 -57 ct 389 -41 390 -31 392 -26 ct 395 -20 398 -16 402 -14 ct +407 -11 414 -10 426 -10 ct 426 -10 426 -10 426 0 ct 426 0 426 0 306 0 ct 306 0 306 0 306 -10 ct +318 -10 326 -11 330 -14 ct 334 -16 337 -20 339 -25 ct 342 -31 343 -41 343 -57 ct +343 -57 343 -57 343 -154 ct 343 -181 342 -199 341 -207 ct 339 -213 337 -217 335 -220 ct +332 -222 328 -223 323 -223 ct 318 -223 312 -222 305 -219 ct 305 -219 305 -219 301 -229 ct +301 -229 301 -229 377 -260 ct 377 -260 377 -260 389 -260 ct p ef +531 -337 m 531 -337 531 -337 531 -253 ct 531 -253 531 -253 590 -253 ct 590 -253 590 -253 590 -234 ct +590 -234 590 -234 531 -234 ct 531 -234 531 -234 531 -70 ct 531 -53 533 -42 538 -37 ct +543 -31 549 -28 556 -28 ct 562 -28 568 -30 574 -34 ct 579 -37 584 -43 587 -50 ct +587 -50 587 -50 598 -50 ct 592 -32 582 -19 571 -10 ct 559 -1 546 4 534 4 ct 525 4 517 2 509 -3 ct +501 -8 495 -14 491 -23 ct 487 -32 485 -45 485 -64 ct 485 -64 485 -64 485 -234 ct +485 -234 485 -234 445 -234 ct 445 -234 445 -234 445 -243 ct 455 -247 465 -254 476 -264 ct +487 -273 496 -285 504 -298 ct 509 -305 514 -318 522 -337 ct 522 -337 522 -337 531 -337 ct +p ef +830 -95 m 823 -62 810 -37 790 -19 ct 770 -2 748 7 724 7 ct 695 7 670 -5 649 -29 ct +628 -53 617 -85 617 -126 ct 617 -166 629 -198 652 -223 ct 676 -248 705 -260 738 -260 ct +763 -260 783 -253 799 -240 ct 815 -227 823 -214 823 -199 ct 823 -192 821 -187 816 -182 ct +812 -178 805 -176 797 -176 ct 787 -176 779 -180 773 -187 ct 770 -190 768 -198 767 -209 ct +766 -220 762 -228 755 -234 ct 749 -239 740 -242 729 -242 ct 710 -242 696 -235 684 -222 ct +669 -204 662 -180 662 -150 ct 662 -120 669 -94 684 -71 ct 699 -48 719 -36 744 -36 ct +762 -36 778 -42 793 -54 ct 803 -62 812 -77 822 -99 ct 822 -99 822 -99 830 -95 ct +p ef +939 -392 m 939 -392 939 -392 939 -208 ct 959 -230 975 -244 987 -251 ct 999 -257 1011 -260 1023 -260 ct +1037 -260 1050 -256 1060 -248 ct 1070 -240 1078 -228 1083 -211 ct 1086 -199 1088 -178 1088 -146 ct +1088 -146 1088 -146 1088 -57 ct 1088 -41 1089 -30 1092 -24 ct 1094 -20 1097 -16 1101 -14 ct +1105 -11 1113 -10 1125 -10 ct 1125 -10 1125 -10 1125 0 ct 1125 0 1125 0 1001 0 ct +1001 0 1001 0 1001 -10 ct 1001 -10 1001 -10 1007 -10 ct 1019 -10 1027 -12 1031 -15 ct +1036 -19 1039 -24 1041 -31 ct 1042 -34 1042 -43 1042 -57 ct 1042 -57 1042 -57 1042 -147 ct +1042 -174 1041 -192 1038 -201 ct 1035 -210 1030 -216 1024 -221 ct 1018 -225 1011 -227 1002 -227 ct +993 -227 983 -225 974 -220 ct 964 -215 953 -205 939 -191 ct 939 -191 939 -191 939 -57 ct +939 -40 940 -29 942 -25 ct 944 -21 947 -17 953 -14 ct 958 -11 967 -10 980 -10 ct +980 -10 980 -10 980 0 ct 980 0 980 0 856 0 ct 856 0 856 0 856 -10 ct 867 -10 875 -12 881 -15 ct +885 -17 888 -21 890 -26 ct 892 -31 893 -41 893 -57 ct 893 -57 893 -57 893 -286 ct +893 -314 892 -332 891 -338 ct 890 -345 888 -349 885 -352 ct 882 -354 878 -355 873 -355 ct +870 -355 863 -354 855 -351 ct 855 -351 855 -351 851 -361 ct 851 -361 851 -361 926 -392 ct +926 -392 926 -392 939 -392 ct p ef +1529 -125 m 1529 -125 1529 -125 1384 -125 ct 1384 -125 1384 -125 1358 -66 ct +1352 -52 1349 -41 1349 -33 ct 1349 -28 1351 -23 1357 -18 ct 1362 -14 1374 -11 1392 -10 ct +1392 -10 1392 -10 1392 0 ct 1392 0 1392 0 1274 0 ct 1274 0 1274 0 1274 -10 ct 1290 -13 1300 -16 1305 -21 ct +1314 -30 1324 -48 1336 -75 ct 1336 -75 1336 -75 1470 -382 ct 1470 -382 1470 -382 1481 -382 ct +1481 -382 1481 -382 1608 -71 ct 1618 -46 1628 -30 1637 -23 ct 1645 -15 1657 -11 1672 -10 ct +1672 -10 1672 -10 1672 0 ct 1672 0 1672 0 1524 0 ct 1524 0 1524 0 1524 -10 ct 1539 -11 1549 -13 1554 -17 ct +1559 -22 1562 -27 1562 -33 ct 1562 -41 1558 -53 1551 -71 ct 1551 -71 1551 -71 1529 -125 ct +p +1520 -146 m 1459 -297 l 1393 -146 l 1520 -146 l p ef +1763 -209 m 1787 -243 1814 -260 1842 -260 ct 1868 -260 1890 -249 1909 -227 ct +1928 -205 1938 -175 1938 -136 ct 1938 -92 1923 -56 1893 -28 ct 1868 -5 1839 7 1808 7 ct +1793 7 1779 4 1763 -1 ct 1748 -6 1733 -14 1717 -25 ct 1717 -25 1717 -25 1717 -286 ct +1717 -314 1716 -332 1715 -338 ct 1714 -345 1711 -349 1708 -352 ct 1705 -354 1702 -355 1697 -355 ct +1692 -355 1686 -354 1678 -351 ct 1678 -351 1678 -351 1674 -361 ct 1674 -361 1674 -361 1750 -392 ct +1750 -392 1750 -392 1763 -392 ct 1763 -392 1763 -392 1763 -209 ct p +1763 -192 m 1763 -192 1763 -192 1763 -41 ct 1772 -32 1782 -25 1792 -20 ct 1802 -15 1812 -13 1822 -13 ct +1839 -13 1854 -22 1869 -41 ct 1883 -59 1890 -86 1890 -121 ct 1890 -153 1883 -178 1869 -195 ct +1854 -212 1838 -221 1820 -221 ct 1810 -221 1801 -219 1791 -214 ct 1784 -210 1774 -203 1763 -192 ct +p ef +2219 -382 m 2219 -382 2219 -382 2219 -254 ct 2219 -254 2219 -254 2209 -254 ct +2206 -279 2200 -298 2191 -313 ct 2183 -327 2170 -339 2155 -347 ct 2139 -356 2122 -360 2105 -360 ct +2086 -360 2070 -354 2058 -343 ct 2045 -331 2039 -318 2039 -303 ct 2039 -291 2043 -281 2051 -272 ct +2062 -258 2090 -239 2133 -217 ct 2168 -198 2191 -183 2204 -173 ct 2217 -163 2227 -152 2234 -138 ct +2241 -125 2244 -110 2244 -96 ct 2244 -67 2233 -43 2211 -23 ct 2189 -2 2161 8 2126 8 ct +2115 8 2105 7 2095 6 ct 2090 5 2078 1 2060 -4 ct 2042 -10 2031 -13 2026 -13 ct +2021 -13 2018 -12 2015 -9 ct 2012 -6 2010 -1 2009 8 ct 2009 8 2009 8 1999 8 ct +1999 8 1999 8 1999 -120 ct 1999 -120 1999 -120 2009 -120 ct 2014 -93 2020 -73 2028 -60 ct +2036 -46 2049 -35 2066 -26 ct 2082 -17 2100 -13 2120 -13 ct 2143 -13 2162 -19 2175 -31 ct +2188 -43 2195 -58 2195 -74 ct 2195 -83 2192 -93 2187 -102 ct 2182 -111 2174 -120 2164 -128 ct +2157 -134 2137 -145 2105 -163 ct 2073 -181 2050 -195 2036 -206 ct 2023 -217 2013 -229 2006 -241 ct +1999 -254 1995 -268 1995 -284 ct 1995 -311 2005 -334 2026 -353 ct 2047 -372 2073 -382 2105 -382 ct +2125 -382 2146 -377 2168 -368 ct 2178 -363 2186 -361 2190 -361 ct 2195 -361 2199 -362 2202 -365 ct +2205 -368 2207 -374 2209 -382 ct 2209 -382 2209 -382 2219 -382 ct p ef +2518 -392 m 2518 -392 2518 -392 2518 -57 ct 2518 -41 2519 -31 2521 -26 ct 2524 -21 2527 -17 2532 -14 ct +2537 -11 2546 -10 2559 -10 ct 2559 -10 2559 -10 2559 0 ct 2559 0 2559 0 2435 0 ct +2435 0 2435 0 2435 -10 ct 2447 -10 2454 -11 2459 -14 ct 2463 -16 2466 -20 2468 -25 ct +2471 -31 2472 -41 2472 -57 ct 2472 -57 2472 -57 2472 -286 ct 2472 -314 2471 -332 2470 -338 ct +2469 -345 2467 -349 2464 -352 ct 2461 -354 2458 -355 2453 -355 ct 2449 -355 2443 -354 2436 -351 ct +2436 -351 2436 -351 2431 -361 ct 2431 -361 2431 -361 2506 -392 ct 2506 -392 2506 -392 2518 -392 ct +p ef +2712 -260 m 2750 -260 2781 -246 2804 -217 ct 2823 -192 2833 -163 2833 -131 ct +2833 -109 2828 -86 2817 -63 ct 2806 -40 2791 -22 2772 -11 ct 2753 1 2732 7 2709 7 ct +2671 7 2641 -8 2618 -38 ct 2599 -64 2590 -92 2590 -124 ct 2590 -147 2596 -170 2607 -193 ct +2619 -216 2634 -233 2652 -244 ct 2671 -255 2691 -260 2712 -260 ct p +2703 -242 m 2694 -242 2684 -239 2674 -233 ct 2664 -228 2656 -218 2650 -203 ct +2644 -189 2641 -170 2641 -147 ct 2641 -111 2648 -79 2663 -53 ct 2678 -26 2697 -13 2721 -13 ct +2738 -13 2753 -20 2765 -35 ct 2776 -50 2782 -75 2782 -110 ct 2782 -155 2772 -190 2753 -216 ct +2740 -233 2723 -242 2703 -242 ct p ef +2995 -260 m 3033 -260 3064 -246 3087 -217 ct 3106 -192 3116 -163 3116 -131 ct +3116 -109 3111 -86 3100 -63 ct 3089 -40 3074 -22 3055 -11 ct 3036 1 3015 7 2992 7 ct +2954 7 2924 -8 2901 -38 ct 2882 -64 2873 -92 2873 -124 ct 2873 -147 2879 -170 2890 -193 ct +2902 -216 2917 -233 2935 -244 ct 2954 -255 2974 -260 2995 -260 ct p +2986 -242 m 2977 -242 2967 -239 2957 -233 ct 2947 -228 2939 -218 2933 -203 ct +2927 -189 2924 -170 2924 -147 ct 2924 -111 2931 -79 2946 -53 ct 2961 -26 2980 -13 3004 -13 ct +3021 -13 3036 -20 3048 -35 ct 3059 -50 3065 -75 3065 -110 ct 3065 -155 3055 -190 3036 -216 ct +3023 -233 3006 -242 2986 -242 ct p ef +3137 -228 m 3137 -228 3137 -228 3215 -259 ct 3215 -259 3215 -259 3226 -259 ct +3226 -259 3226 -259 3226 -201 ct 3239 -223 3252 -238 3265 -247 ct 3278 -256 3292 -260 3306 -260 ct +3331 -260 3352 -250 3369 -230 ct 3390 -206 3400 -175 3400 -136 ct 3400 -92 3388 -56 3363 -28 ct +3342 -5 3317 7 3286 7 ct 3272 7 3260 5 3251 1 ct 3243 -2 3235 -7 3226 -16 ct 3226 -16 3226 -16 3226 63 ct +3226 80 3227 91 3229 96 ct 3231 100 3235 104 3240 107 ct 3246 110 3255 111 3269 111 ct +3269 111 3269 111 3269 121 ct 3269 121 3269 121 3134 121 ct 3134 121 3134 121 3134 111 ct +3134 111 3134 111 3141 111 ct 3151 111 3160 109 3168 105 ct 3171 103 3174 100 3176 95 ct +3178 91 3179 79 3179 61 ct 3179 61 3179 61 3179 -179 ct 3179 -195 3178 -205 3177 -209 ct +3175 -213 3173 -216 3170 -219 ct 3167 -221 3162 -222 3157 -222 ct 3153 -222 3147 -221 3140 -218 ct +3140 -218 3140 -218 3137 -228 ct p +3226 -185 m 3226 -185 3226 -185 3226 -90 ct 3226 -70 3227 -57 3228 -50 ct 3231 -40 3237 -30 3247 -22 ct +3257 -14 3270 -10 3285 -10 ct 3303 -10 3318 -17 3329 -31 ct 3344 -50 3351 -77 3351 -111 ct +3351 -149 3343 -179 3326 -200 ct 3314 -214 3300 -221 3284 -221 ct 3276 -221 3267 -219 3258 -214 ct +3252 -211 3241 -201 3226 -185 ct p ef +pom +gr +gr +gs +gs +pum +9976 24759 t +82 -392 m 90 -392 96 -389 102 -384 ct 107 -378 110 -372 110 -364 ct 110 -356 107 -350 102 -344 ct +96 -339 90 -336 82 -336 ct 74 -336 68 -339 62 -344 ct 57 -350 54 -356 54 -364 ct +54 -372 57 -378 62 -384 ct 68 -389 74 -392 82 -392 ct p +105 -260 m 105 -260 105 -260 105 -57 ct 105 -41 106 -31 108 -26 ct 111 -20 114 -16 118 -14 ct +123 -11 130 -10 142 -10 ct 142 -10 142 -10 142 0 ct 142 0 142 0 22 0 ct 22 0 22 0 22 -10 ct +34 -10 42 -11 46 -14 ct 50 -16 53 -20 55 -25 ct 58 -31 59 -41 59 -57 ct 59 -57 59 -57 59 -154 ct +59 -181 58 -199 57 -207 ct 55 -213 53 -217 51 -220 ct 48 -222 44 -223 39 -223 ct +34 -223 28 -222 21 -219 ct 21 -219 21 -219 17 -229 ct 17 -229 17 -229 93 -260 ct +93 -260 93 -260 105 -260 ct p ef +249 -207 m 278 -242 306 -260 333 -260 ct 347 -260 359 -257 368 -250 ct 378 -243 386 -231 392 -216 ct +396 -205 398 -188 398 -165 ct 398 -165 398 -165 398 -57 ct 398 -41 399 -30 402 -25 ct +404 -20 407 -16 411 -14 ct 415 -11 423 -10 435 -10 ct 435 -10 435 -10 435 0 ct +435 0 435 0 311 0 ct 311 0 311 0 311 -10 ct 311 -10 311 -10 316 -10 ct 328 -10 336 -12 341 -15 ct +346 -19 349 -24 351 -31 ct 352 -34 352 -43 352 -57 ct 352 -57 352 -57 352 -161 ct +352 -184 349 -201 343 -211 ct 337 -222 327 -227 313 -227 ct 292 -227 270 -215 249 -191 ct +249 -191 249 -191 249 -57 ct 249 -40 250 -29 252 -25 ct 255 -20 258 -16 263 -14 ct +267 -11 276 -10 290 -10 ct 290 -10 290 -10 290 0 ct 290 0 290 0 166 0 ct 166 0 166 0 166 -10 ct +166 -10 166 -10 171 -10 ct 184 -10 192 -13 196 -20 ct 201 -26 203 -39 203 -57 ct +203 -57 203 -57 203 -151 ct 203 -181 202 -200 201 -206 ct 200 -213 198 -217 195 -220 ct +192 -222 188 -223 183 -223 ct 178 -223 172 -222 165 -219 ct 165 -219 165 -219 161 -229 ct +161 -229 161 -229 237 -260 ct 237 -260 237 -260 249 -260 ct 249 -260 249 -260 249 -207 ct +p ef +532 -207 m 561 -242 589 -260 616 -260 ct 630 -260 642 -257 651 -250 ct 661 -243 669 -231 675 -216 ct +679 -205 681 -188 681 -165 ct 681 -165 681 -165 681 -57 ct 681 -41 682 -30 685 -25 ct +687 -20 690 -16 694 -14 ct 698 -11 706 -10 718 -10 ct 718 -10 718 -10 718 0 ct +718 0 718 0 594 0 ct 594 0 594 0 594 -10 ct 594 -10 594 -10 599 -10 ct 611 -10 619 -12 624 -15 ct +629 -19 632 -24 634 -31 ct 635 -34 635 -43 635 -57 ct 635 -57 635 -57 635 -161 ct +635 -184 632 -201 626 -211 ct 620 -222 610 -227 596 -227 ct 575 -227 553 -215 532 -191 ct +532 -191 532 -191 532 -57 ct 532 -40 533 -29 535 -25 ct 538 -20 541 -16 546 -14 ct +550 -11 559 -10 573 -10 ct 573 -10 573 -10 573 0 ct 573 0 573 0 449 0 ct 449 0 449 0 449 -10 ct +449 -10 449 -10 454 -10 ct 467 -10 475 -13 479 -20 ct 484 -26 486 -39 486 -57 ct +486 -57 486 -57 486 -151 ct 486 -181 485 -200 484 -206 ct 483 -213 481 -217 478 -220 ct +475 -222 471 -223 466 -223 ct 461 -223 455 -222 448 -219 ct 448 -219 448 -219 444 -229 ct +444 -229 444 -229 520 -260 ct 520 -260 520 -260 532 -260 ct 532 -260 532 -260 532 -207 ct +p ef +866 -260 m 904 -260 935 -246 958 -217 ct 977 -192 987 -163 987 -131 ct 987 -109 982 -86 971 -63 ct +960 -40 945 -22 926 -11 ct 907 1 886 7 863 7 ct 825 7 795 -8 772 -38 ct 753 -64 744 -92 744 -124 ct +744 -147 750 -170 761 -193 ct 773 -216 788 -233 806 -244 ct 825 -255 845 -260 866 -260 ct +p +857 -242 m 848 -242 838 -239 828 -233 ct 818 -228 810 -218 804 -203 ct 798 -189 795 -170 795 -147 ct +795 -111 802 -79 817 -53 ct 832 -26 851 -13 875 -13 ct 892 -13 907 -20 919 -35 ct +930 -50 936 -75 936 -110 ct 936 -155 926 -190 907 -216 ct 894 -233 877 -242 857 -242 ct +p ef +1014 -253 m 1014 -253 1014 -253 1132 -253 ct 1132 -253 1132 -253 1132 -243 ct +1132 -243 1132 -243 1124 -243 ct 1117 -243 1112 -241 1108 -238 ct 1104 -234 1102 -230 1102 -224 ct +1102 -217 1104 -210 1108 -201 ct 1108 -201 1108 -201 1167 -62 ct 1167 -62 1167 -62 1225 -206 ct +1229 -216 1231 -224 1231 -230 ct 1231 -232 1231 -234 1229 -236 ct 1227 -239 1225 -240 1221 -241 ct +1218 -243 1212 -243 1202 -243 ct 1202 -243 1202 -243 1202 -253 ct 1202 -253 1202 -253 1284 -253 ct +1284 -253 1284 -253 1284 -243 ct 1275 -242 1268 -240 1264 -237 ct 1258 -231 1252 -222 1247 -209 ct +1247 -209 1247 -209 1158 7 ct 1158 7 1158 7 1147 7 ct 1147 7 1147 7 1058 -205 ct +1054 -216 1050 -223 1046 -227 ct 1042 -232 1038 -235 1032 -238 ct 1029 -240 1023 -242 1014 -243 ct +1014 -243 1014 -243 1014 -253 ct p ef +1452 -37 m 1426 -17 1410 -5 1403 -2 ct 1393 3 1383 5 1371 5 ct 1354 5 1339 -1 1328 -13 ct +1317 -25 1311 -40 1311 -60 ct 1311 -72 1314 -83 1319 -92 ct 1327 -104 1340 -116 1359 -127 ct +1377 -138 1409 -151 1452 -167 ct 1452 -167 1452 -167 1452 -177 ct 1452 -202 1448 -219 1440 -228 ct +1432 -237 1421 -242 1405 -242 ct 1394 -242 1385 -239 1378 -233 ct 1371 -226 1367 -219 1367 -211 ct +1367 -211 1367 -211 1368 -195 ct 1368 -187 1366 -180 1361 -176 ct 1357 -171 1351 -169 1344 -169 ct +1338 -169 1332 -171 1328 -176 ct 1323 -181 1321 -188 1321 -196 ct 1321 -212 1329 -227 1345 -240 ct +1361 -253 1384 -260 1413 -260 ct 1435 -260 1454 -256 1468 -249 ct 1479 -243 1487 -234 1492 -222 ct +1495 -214 1497 -198 1497 -174 ct 1497 -174 1497 -174 1497 -89 ct 1497 -65 1497 -50 1498 -45 ct +1499 -39 1501 -36 1503 -34 ct 1505 -32 1507 -31 1510 -31 ct 1513 -31 1516 -32 1518 -33 ct +1522 -35 1529 -42 1540 -53 ct 1540 -53 1540 -53 1540 -38 ct 1520 -10 1500 4 1482 4 ct +1473 4 1465 1 1460 -5 ct 1455 -11 1452 -22 1452 -37 ct p +1452 -54 m 1452 -54 1452 -54 1452 -149 ct 1424 -138 1406 -130 1398 -126 ct +1383 -118 1373 -110 1366 -101 ct 1360 -92 1357 -83 1357 -72 ct 1357 -59 1361 -49 1369 -40 ct +1377 -31 1386 -27 1396 -27 ct 1411 -27 1429 -36 1452 -54 ct p ef +1632 -337 m 1632 -337 1632 -337 1632 -253 ct 1632 -253 1632 -253 1691 -253 ct +1691 -253 1691 -253 1691 -234 ct 1691 -234 1691 -234 1632 -234 ct 1632 -234 1632 -234 1632 -70 ct +1632 -53 1634 -42 1639 -37 ct 1644 -31 1650 -28 1657 -28 ct 1663 -28 1669 -30 1675 -34 ct +1680 -37 1685 -43 1688 -50 ct 1688 -50 1688 -50 1699 -50 ct 1693 -32 1683 -19 1672 -10 ct +1660 -1 1647 4 1635 4 ct 1626 4 1618 2 1610 -3 ct 1602 -8 1596 -14 1592 -23 ct +1588 -32 1586 -45 1586 -64 ct 1586 -64 1586 -64 1586 -234 ct 1586 -234 1586 -234 1546 -234 ct +1546 -234 1546 -234 1546 -243 ct 1556 -247 1566 -254 1577 -264 ct 1588 -273 1597 -285 1605 -298 ct +1610 -305 1615 -318 1623 -337 ct 1623 -337 1623 -337 1632 -337 ct p ef +1780 -392 m 1788 -392 1794 -389 1800 -384 ct 1805 -378 1808 -372 1808 -364 ct +1808 -356 1805 -350 1800 -344 ct 1794 -339 1788 -336 1780 -336 ct 1772 -336 1766 -339 1760 -344 ct +1755 -350 1752 -356 1752 -364 ct 1752 -372 1755 -378 1760 -384 ct 1766 -389 1772 -392 1780 -392 ct +p +1803 -260 m 1803 -260 1803 -260 1803 -57 ct 1803 -41 1804 -31 1806 -26 ct 1809 -20 1812 -16 1816 -14 ct +1821 -11 1828 -10 1840 -10 ct 1840 -10 1840 -10 1840 0 ct 1840 0 1840 0 1720 0 ct +1720 0 1720 0 1720 -10 ct 1732 -10 1740 -11 1744 -14 ct 1748 -16 1751 -20 1753 -25 ct +1756 -31 1757 -41 1757 -57 ct 1757 -57 1757 -57 1757 -154 ct 1757 -181 1756 -199 1755 -207 ct +1753 -213 1751 -217 1749 -220 ct 1746 -222 1742 -223 1737 -223 ct 1732 -223 1726 -222 1719 -219 ct +1719 -219 1719 -219 1715 -229 ct 1715 -229 1715 -229 1791 -260 ct 1791 -260 1791 -260 1803 -260 ct +p ef +1996 -260 m 2034 -260 2065 -246 2088 -217 ct 2107 -192 2117 -163 2117 -131 ct +2117 -109 2112 -86 2101 -63 ct 2090 -40 2075 -22 2056 -11 ct 2037 1 2016 7 1993 7 ct +1955 7 1925 -8 1902 -38 ct 1883 -64 1874 -92 1874 -124 ct 1874 -147 1880 -170 1891 -193 ct +1903 -216 1918 -233 1936 -244 ct 1955 -255 1975 -260 1996 -260 ct p +1987 -242 m 1978 -242 1968 -239 1958 -233 ct 1948 -228 1940 -218 1934 -203 ct +1928 -189 1925 -170 1925 -147 ct 1925 -111 1932 -79 1947 -53 ct 1962 -26 1981 -13 2005 -13 ct +2022 -13 2037 -20 2049 -35 ct 2060 -50 2066 -75 2066 -110 ct 2066 -155 2056 -190 2037 -216 ct +2024 -233 2007 -242 1987 -242 ct p ef +2230 -207 m 2259 -242 2287 -260 2314 -260 ct 2328 -260 2340 -257 2349 -250 ct +2359 -243 2367 -231 2373 -216 ct 2377 -205 2379 -188 2379 -165 ct 2379 -165 2379 -165 2379 -57 ct +2379 -41 2380 -30 2383 -25 ct 2385 -20 2388 -16 2392 -14 ct 2396 -11 2404 -10 2416 -10 ct +2416 -10 2416 -10 2416 0 ct 2416 0 2416 0 2292 0 ct 2292 0 2292 0 2292 -10 ct 2292 -10 2292 -10 2297 -10 ct +2309 -10 2317 -12 2322 -15 ct 2327 -19 2330 -24 2332 -31 ct 2333 -34 2333 -43 2333 -57 ct +2333 -57 2333 -57 2333 -161 ct 2333 -184 2330 -201 2324 -211 ct 2318 -222 2308 -227 2294 -227 ct +2273 -227 2251 -215 2230 -191 ct 2230 -191 2230 -191 2230 -57 ct 2230 -40 2231 -29 2233 -25 ct +2236 -20 2239 -16 2244 -14 ct 2248 -11 2257 -10 2271 -10 ct 2271 -10 2271 -10 2271 0 ct +2271 0 2271 0 2147 0 ct 2147 0 2147 0 2147 -10 ct 2147 -10 2147 -10 2152 -10 ct +2165 -10 2173 -13 2177 -20 ct 2182 -26 2184 -39 2184 -57 ct 2184 -57 2184 -57 2184 -151 ct +2184 -181 2183 -200 2182 -206 ct 2181 -213 2179 -217 2176 -220 ct 2173 -222 2169 -223 2164 -223 ct +2159 -223 2153 -222 2146 -219 ct 2146 -219 2146 -219 2142 -229 ct 2142 -229 2142 -229 2218 -260 ct +2218 -260 2218 -260 2230 -260 ct 2230 -260 2230 -260 2230 -207 ct p ef +2820 -125 m 2820 -125 2820 -125 2675 -125 ct 2675 -125 2675 -125 2649 -66 ct +2643 -52 2640 -41 2640 -33 ct 2640 -28 2642 -23 2648 -18 ct 2653 -14 2665 -11 2683 -10 ct +2683 -10 2683 -10 2683 0 ct 2683 0 2683 0 2565 0 ct 2565 0 2565 0 2565 -10 ct 2581 -13 2591 -16 2596 -21 ct +2605 -30 2615 -48 2627 -75 ct 2627 -75 2627 -75 2761 -382 ct 2761 -382 2761 -382 2772 -382 ct +2772 -382 2772 -382 2899 -71 ct 2909 -46 2919 -30 2928 -23 ct 2936 -15 2948 -11 2963 -10 ct +2963 -10 2963 -10 2963 0 ct 2963 0 2963 0 2815 0 ct 2815 0 2815 0 2815 -10 ct 2830 -11 2840 -13 2845 -17 ct +2850 -22 2853 -27 2853 -33 ct 2853 -41 2849 -53 2842 -71 ct 2842 -71 2842 -71 2820 -125 ct +p +2811 -146 m 2750 -297 l 2684 -146 l 2811 -146 l p ef +3055 -209 m 3079 -243 3106 -260 3134 -260 ct 3160 -260 3182 -249 3201 -227 ct +3220 -205 3230 -175 3230 -136 ct 3230 -92 3215 -56 3185 -28 ct 3160 -5 3131 7 3100 7 ct +3085 7 3071 4 3055 -1 ct 3040 -6 3025 -14 3009 -25 ct 3009 -25 3009 -25 3009 -286 ct +3009 -314 3008 -332 3007 -338 ct 3006 -345 3003 -349 3000 -352 ct 2997 -354 2994 -355 2989 -355 ct +2984 -355 2978 -354 2970 -351 ct 2970 -351 2970 -351 2966 -361 ct 2966 -361 2966 -361 3042 -392 ct +3042 -392 3042 -392 3055 -392 ct 3055 -392 3055 -392 3055 -209 ct p +3055 -192 m 3055 -192 3055 -192 3055 -41 ct 3064 -32 3074 -25 3084 -20 ct 3094 -15 3104 -13 3114 -13 ct +3131 -13 3146 -22 3161 -41 ct 3175 -59 3182 -86 3182 -121 ct 3182 -153 3175 -178 3161 -195 ct +3146 -212 3130 -221 3112 -221 ct 3102 -221 3093 -219 3083 -214 ct 3076 -210 3066 -203 3055 -192 ct +p ef +3510 -382 m 3510 -382 3510 -382 3510 -254 ct 3510 -254 3510 -254 3500 -254 ct +3497 -279 3491 -298 3482 -313 ct 3474 -327 3461 -339 3446 -347 ct 3430 -356 3413 -360 3396 -360 ct +3377 -360 3361 -354 3349 -343 ct 3336 -331 3330 -318 3330 -303 ct 3330 -291 3334 -281 3342 -272 ct +3353 -258 3381 -239 3424 -217 ct 3459 -198 3482 -183 3495 -173 ct 3508 -163 3518 -152 3525 -138 ct +3532 -125 3535 -110 3535 -96 ct 3535 -67 3524 -43 3502 -23 ct 3480 -2 3452 8 3417 8 ct +3406 8 3396 7 3386 6 ct 3381 5 3369 1 3351 -4 ct 3333 -10 3322 -13 3317 -13 ct +3312 -13 3309 -12 3306 -9 ct 3303 -6 3301 -1 3300 8 ct 3300 8 3300 8 3290 8 ct +3290 8 3290 8 3290 -120 ct 3290 -120 3290 -120 3300 -120 ct 3305 -93 3311 -73 3319 -60 ct +3327 -46 3340 -35 3357 -26 ct 3373 -17 3391 -13 3411 -13 ct 3434 -13 3453 -19 3466 -31 ct +3479 -43 3486 -58 3486 -74 ct 3486 -83 3483 -93 3478 -102 ct 3473 -111 3465 -120 3455 -128 ct +3448 -134 3428 -145 3396 -163 ct 3364 -181 3341 -195 3327 -206 ct 3314 -217 3304 -229 3297 -241 ct +3290 -254 3286 -268 3286 -284 ct 3286 -311 3296 -334 3317 -353 ct 3338 -372 3364 -382 3396 -382 ct +3416 -382 3437 -377 3459 -368 ct 3469 -363 3477 -361 3481 -361 ct 3486 -361 3490 -362 3493 -365 ct +3496 -368 3498 -374 3500 -382 ct 3500 -382 3500 -382 3510 -382 ct p ef +3809 -392 m 3809 -392 3809 -392 3809 -57 ct 3809 -41 3810 -31 3812 -26 ct 3815 -21 3818 -17 3823 -14 ct +3828 -11 3837 -10 3850 -10 ct 3850 -10 3850 -10 3850 0 ct 3850 0 3850 0 3726 0 ct +3726 0 3726 0 3726 -10 ct 3738 -10 3745 -11 3750 -14 ct 3754 -16 3757 -20 3759 -25 ct +3762 -31 3763 -41 3763 -57 ct 3763 -57 3763 -57 3763 -286 ct 3763 -314 3762 -332 3761 -338 ct +3760 -345 3758 -349 3755 -352 ct 3752 -354 3749 -355 3744 -355 ct 3740 -355 3734 -354 3727 -351 ct +3727 -351 3727 -351 3722 -361 ct 3722 -361 3722 -361 3797 -392 ct 3797 -392 3797 -392 3809 -392 ct +p ef +4003 -260 m 4041 -260 4072 -246 4095 -217 ct 4114 -192 4124 -163 4124 -131 ct +4124 -109 4119 -86 4108 -63 ct 4097 -40 4082 -22 4063 -11 ct 4044 1 4023 7 4000 7 ct +3962 7 3932 -8 3909 -38 ct 3890 -64 3881 -92 3881 -124 ct 3881 -147 3887 -170 3898 -193 ct +3910 -216 3925 -233 3943 -244 ct 3962 -255 3982 -260 4003 -260 ct p +3994 -242 m 3985 -242 3975 -239 3965 -233 ct 3955 -228 3947 -218 3941 -203 ct +3935 -189 3932 -170 3932 -147 ct 3932 -111 3939 -79 3954 -53 ct 3969 -26 3988 -13 4012 -13 ct +4029 -13 4044 -20 4056 -35 ct 4067 -50 4073 -75 4073 -110 ct 4073 -155 4063 -190 4044 -216 ct +4031 -233 4014 -242 3994 -242 ct p ef +4286 -260 m 4324 -260 4355 -246 4378 -217 ct 4397 -192 4407 -163 4407 -131 ct +4407 -109 4402 -86 4391 -63 ct 4380 -40 4365 -22 4346 -11 ct 4327 1 4306 7 4283 7 ct +4245 7 4215 -8 4192 -38 ct 4173 -64 4164 -92 4164 -124 ct 4164 -147 4170 -170 4181 -193 ct +4193 -216 4208 -233 4226 -244 ct 4245 -255 4265 -260 4286 -260 ct p +4277 -242 m 4268 -242 4258 -239 4248 -233 ct 4238 -228 4230 -218 4224 -203 ct +4218 -189 4215 -170 4215 -147 ct 4215 -111 4222 -79 4237 -53 ct 4252 -26 4271 -13 4295 -13 ct +4312 -13 4327 -20 4339 -35 ct 4350 -50 4356 -75 4356 -110 ct 4356 -155 4346 -190 4327 -216 ct +4314 -233 4297 -242 4277 -242 ct p ef +4428 -228 m 4428 -228 4428 -228 4506 -259 ct 4506 -259 4506 -259 4517 -259 ct +4517 -259 4517 -259 4517 -201 ct 4530 -223 4543 -238 4556 -247 ct 4569 -256 4583 -260 4597 -260 ct +4622 -260 4643 -250 4660 -230 ct 4681 -206 4691 -175 4691 -136 ct 4691 -92 4679 -56 4654 -28 ct +4633 -5 4608 7 4577 7 ct 4563 7 4551 5 4542 1 ct 4534 -2 4526 -7 4517 -16 ct 4517 -16 4517 -16 4517 63 ct +4517 80 4518 91 4520 96 ct 4522 100 4526 104 4531 107 ct 4537 110 4546 111 4560 111 ct +4560 111 4560 111 4560 121 ct 4560 121 4560 121 4425 121 ct 4425 121 4425 121 4425 111 ct +4425 111 4425 111 4432 111 ct 4442 111 4451 109 4459 105 ct 4462 103 4465 100 4467 95 ct +4469 91 4470 79 4470 61 ct 4470 61 4470 61 4470 -179 ct 4470 -195 4469 -205 4468 -209 ct +4466 -213 4464 -216 4461 -219 ct 4458 -221 4453 -222 4448 -222 ct 4444 -222 4438 -221 4431 -218 ct +4431 -218 4431 -218 4428 -228 ct p +4517 -185 m 4517 -185 4517 -185 4517 -90 ct 4517 -70 4518 -57 4519 -50 ct 4522 -40 4528 -30 4538 -22 ct +4548 -14 4561 -10 4576 -10 ct 4594 -10 4609 -17 4620 -31 ct 4635 -50 4642 -77 4642 -111 ct +4642 -149 4634 -179 4617 -200 ct 4605 -214 4591 -221 4575 -221 ct 4567 -221 4558 -219 4549 -214 ct +4543 -211 4532 -201 4517 -185 ct p ef +pom +gr +gr +gs +3535 6235 m 5208 6235 l 5208 6964 l 3535 6964 l 3535 6235 l eoclip newpath +gs +tm setmatrix +1111 3201 t +1 1 s +gs +gs +0 0 m 1673 0 l 1673 729 l 0 729 l 0 0 l eoclip newpath +gs +pum +106 556 t +86 9 m 86 9 86 9 122 -341 ct 124 -355 124 -365 124 -373 ct 124 -385 121 -394 114 -400 ct +107 -406 95 -410 77 -410 ct 77 -410 77 -410 81 -421 ct 81 -421 81 -421 237 -421 ct +237 -421 237 -421 234 -410 ct 213 -410 198 -406 191 -399 ct 183 -391 177 -372 175 -341 ct +175 -341 175 -341 151 -113 ct 151 -113 151 -113 311 -361 ct 311 -365 311 -369 311 -371 ct +311 -383 308 -392 301 -398 ct 294 -405 279 -409 257 -410 ct 257 -410 257 -410 259 -421 ct +259 -421 259 -421 430 -421 ct 430 -421 430 -421 426 -410 ct 407 -410 393 -408 387 -405 ct +382 -403 377 -399 374 -394 ct 371 -389 368 -380 366 -368 ct 365 -364 363 -340 358 -296 ct +354 -251 347 -190 338 -113 ct 338 -113 338 -113 472 -317 ct 486 -339 496 -354 499 -363 ct +503 -372 505 -380 505 -386 ct 505 -392 502 -397 497 -401 ct 492 -406 484 -409 472 -410 ct +472 -410 472 -410 474 -421 ct 474 -421 474 -421 599 -421 ct 599 -421 599 -421 596 -410 ct +585 -409 575 -406 567 -402 ct 558 -397 548 -389 537 -376 ct 530 -368 516 -349 496 -317 ct +496 -317 496 -317 284 9 ct 284 9 284 9 273 9 ct 273 9 273 9 307 -317 ct 307 -317 307 -317 97 9 ct +97 9 97 9 86 9 ct p ef +pom +gr +gs +pum +767 556 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1058 556 t +54 -273 m 54 -273 54 -273 249 -273 ct 249 -273 249 -273 249 -265 ct 249 -265 249 -265 35 -42 ct +35 -42 35 -42 125 -42 ct 147 -42 161 -43 166 -44 ct 172 -46 178 -50 183 -55 ct +187 -60 193 -70 199 -84 ct 199 -84 199 -84 210 -84 ct 210 -84 210 -84 183 0 ct +183 0 183 0 -18 0 ct -18 0 -18 0 -18 -9 ct -18 -9 -18 -9 196 -232 ct 196 -232 196 -232 109 -232 ct +90 -232 78 -232 74 -231 ct 68 -229 63 -226 57 -221 ct 51 -216 45 -208 39 -196 ct +39 -196 39 -196 28 -196 ct 28 -196 28 -196 54 -273 ct p ef +pom +gr +gs +pum +1376 556 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gr +gr +gr +gr +gs +12335 15640 m 13606 15640 l 13606 16435 l 12335 16435 l 12335 15640 l eoclip newpath +gs +tm setmatrix +9895 12594 t +1 1 s +gs +gs +0 0 m 1271 0 l 1271 795 l 0 795 l 0 0 l eoclip newpath +gs +pum +159 556 t +331 -261 m 331 -261 331 -261 322 -229 ct 322 -229 322 -229 270 -229 ct 274 -218 276 -207 276 -198 ct +276 -170 264 -146 241 -124 ct 217 -103 185 -91 144 -89 ct 122 -82 106 -75 95 -65 ct +91 -62 89 -59 89 -55 ct 89 -51 91 -47 95 -44 ct 98 -40 108 -37 123 -33 ct 123 -33 123 -33 183 -20 ct +216 -12 238 -3 248 8 ct 259 19 264 31 264 46 ct 264 63 258 78 245 92 ct 233 106 215 117 190 125 ct +166 133 140 137 111 137 ct 85 137 62 134 41 128 ct 20 122 5 114 -4 103 ct -13 93 -18 82 -18 71 ct +-18 63 -15 53 -9 44 ct -3 34 4 26 13 20 ct 19 16 35 7 61 -8 ct 52 -15 47 -23 47 -32 ct +47 -40 51 -49 59 -58 ct 67 -68 85 -78 111 -89 ct 89 -93 71 -103 58 -118 ct 45 -132 39 -149 39 -167 ct +39 -196 52 -222 78 -245 ct 104 -268 138 -280 181 -280 ct 196 -280 209 -278 219 -275 ct +229 -272 239 -268 248 -261 ct 248 -261 248 -261 331 -261 ct p +225 -211 m 225 -228 220 -240 211 -250 ct 201 -259 189 -264 173 -264 ct 149 -264 129 -252 114 -229 ct +98 -206 90 -182 90 -157 ct 90 -141 95 -128 105 -118 ct 115 -108 127 -103 142 -103 ct +153 -103 164 -106 174 -112 ct 185 -118 194 -126 201 -136 ct 209 -147 214 -160 219 -176 ct +223 -192 225 -204 225 -211 ct p +74 0 m 57 8 45 18 36 30 ct 27 42 23 53 23 65 ct 23 79 29 90 42 99 ct 59 112 85 118 120 118 ct +149 118 175 113 196 103 ct 217 93 227 80 227 64 ct 227 56 223 48 215 41 ct 208 34 193 28 170 24 ct +158 21 126 13 74 0 ct p ef +pom +gr +gs +pum +529 714 t +134 -168 m 134 -168 134 -168 124 -111 ct 124 -111 124 -111 117 -111 ct 116 -128 113 -140 107 -148 ct +101 -155 93 -159 84 -159 ct 77 -159 71 -157 66 -153 ct 62 -148 60 -143 60 -137 ct +60 -133 61 -129 63 -126 ct 64 -122 68 -117 74 -110 ct 89 -93 99 -79 103 -70 ct +108 -62 110 -53 110 -45 ct 110 -32 105 -21 94 -11 ct 84 -1 71 4 55 4 ct 46 4 36 2 24 -3 ct +20 -4 17 -5 15 -5 ct 10 -5 6 -2 3 4 ct 3 4 3 4 -4 4 ct -4 4 -4 4 6 -56 ct 6 -56 6 -56 13 -56 ct +14 -37 18 -24 25 -17 ct 32 -9 41 -5 53 -5 ct 63 -5 70 -8 76 -13 ct 81 -18 84 -25 84 -32 ct +84 -37 83 -42 81 -46 ct 78 -53 71 -63 60 -76 ct 49 -89 42 -99 39 -106 ct 36 -112 34 -119 34 -125 ct +34 -137 38 -147 47 -156 ct 55 -164 66 -168 80 -168 ct 83 -168 87 -168 90 -167 ct +92 -167 96 -165 102 -163 ct 108 -160 112 -159 114 -159 ct 119 -159 124 -162 127 -168 ct +127 -168 127 -168 134 -168 ct p ef +331 -164 m 331 -164 331 -164 297 -52 ct 292 -35 289 -24 289 -20 ct 289 -18 290 -16 290 -15 ct +291 -14 292 -14 293 -14 ct 294 -14 296 -15 298 -17 ct 300 -18 306 -26 314 -39 ct +314 -39 314 -39 319 -35 ct 311 -20 302 -9 293 -2 ct 287 2 281 4 276 4 ct 271 4 268 3 266 0 ct +263 -3 262 -6 262 -10 ct 262 -15 263 -20 264 -27 ct 267 -35 273 -55 282 -86 ct +260 -51 242 -28 227 -15 ct 212 -2 198 4 186 4 ct 180 4 175 2 171 -2 ct 167 -6 165 -11 165 -17 ct +165 -26 169 -40 175 -59 ct 175 -59 175 -59 194 -117 ct 199 -130 202 -139 202 -142 ct +202 -144 201 -145 200 -146 ct 198 -147 197 -148 196 -148 ct 192 -148 189 -147 186 -145 ct +183 -143 176 -136 165 -124 ct 165 -124 165 -124 159 -128 ct 169 -143 180 -153 191 -160 ct +200 -165 208 -168 215 -168 ct 220 -168 224 -166 227 -163 ct 230 -160 232 -155 232 -150 ct +232 -143 229 -131 223 -114 ct 223 -114 223 -114 203 -55 ct 197 -39 194 -29 194 -24 ct +194 -22 195 -20 197 -19 ct 199 -17 201 -16 203 -16 ct 208 -16 213 -18 220 -23 ct +227 -27 236 -36 247 -50 ct 259 -64 268 -77 275 -90 ct 282 -102 290 -122 299 -149 ct +299 -149 299 -149 304 -164 ct 304 -164 304 -164 331 -164 ct p ef +453 -265 m 453 -265 453 -265 415 -136 ct 427 -148 437 -157 445 -161 ct 454 -166 463 -168 472 -168 ct +485 -168 496 -164 504 -154 ct 513 -145 517 -133 517 -118 ct 517 -98 511 -78 500 -59 ct +489 -39 475 -23 459 -12 ct 442 -2 425 4 409 4 ct 391 4 372 -3 353 -17 ct 353 -17 353 -17 409 -213 ct +414 -228 416 -236 416 -239 ct 416 -242 415 -244 413 -246 ct 410 -248 406 -249 400 -249 ct +397 -249 393 -249 387 -248 ct 387 -248 387 -248 387 -255 ct 387 -255 387 -255 453 -265 ct +p +380 -15 m 392 -8 403 -5 412 -5 ct 422 -5 433 -9 444 -17 ct 456 -25 465 -38 474 -57 ct +482 -76 486 -95 486 -114 ct 486 -125 483 -134 478 -140 ct 473 -147 466 -150 459 -150 ct +448 -150 437 -145 427 -136 ct 417 -127 409 -114 404 -97 ct 404 -97 404 -97 380 -15 ct +p ef +648 -164 m 648 -164 648 -164 645 -150 ct 645 -150 645 -150 617 -150 ct 617 -150 617 -150 594 -69 ct +584 -34 574 -6 565 13 ct 552 41 538 60 523 70 ct 511 78 500 82 488 82 ct 481 82 474 80 469 75 ct +465 72 463 68 463 63 ct 463 59 465 55 468 52 ct 471 49 475 48 479 48 ct 483 48 485 49 488 51 ct +490 53 491 56 491 58 ct 491 61 490 64 488 66 ct 486 68 485 69 485 70 ct 485 71 485 72 486 73 ct +487 74 489 74 491 74 ct 497 74 502 72 508 69 ct 514 66 519 61 524 54 ct 528 48 532 38 537 26 ct +538 21 543 4 551 -25 ct 551 -25 551 -25 588 -150 ct 588 -150 588 -150 551 -150 ct +551 -150 551 -150 554 -164 ct 565 -164 573 -165 578 -166 ct 582 -168 586 -170 590 -174 ct +594 -178 599 -186 604 -197 ct 611 -212 618 -224 624 -232 ct 633 -243 642 -251 652 -257 ct +661 -262 671 -265 679 -265 ct 688 -265 695 -263 701 -258 ct 706 -253 709 -248 709 -242 ct +709 -238 708 -234 705 -231 ct 702 -228 698 -227 694 -227 ct 690 -227 687 -228 685 -230 ct +682 -233 681 -235 681 -238 ct 681 -240 682 -243 684 -245 ct 686 -248 687 -250 687 -251 ct +687 -253 686 -254 685 -255 ct 684 -256 682 -257 679 -257 ct 672 -257 665 -254 659 -249 ct +651 -242 644 -232 638 -217 ct 635 -210 629 -192 621 -164 ct 621 -164 621 -164 648 -164 ct +p ef +pom +gr +gr +gr +gr +gr +13835 16605 m 13273 16793 l 13273 16418 l 13835 16605 l p ef +12335 16558 m 13085 16558 l 13085 16583 l 13085 16608 l 12335 16608 l +12335 16583 l 12335 16558 l p ef +13085 16583 m 13085 16558 l 13089 16558 l 13094 16560 l 13097 16561 l +13101 16564 l 13104 16567 l 13107 16570 l 13108 16574 l 13110 16579 l +13110 16583 l 13110 16583 l 13085 16583 l p ef +13110 16583 m 13110 16605 l 13085 16605 l 13060 16605 l 13060 16583 l +13085 16583 l 13110 16583 l p ef +13085 16605 m 13085 16630 l 13081 16630 l 13076 16628 l 13073 16627 l +13069 16624 l 13066 16621 l 13063 16618 l 13062 16614 l 13060 16609 l +13060 16605 l 13060 16605 l 13085 16605 l p ef +13085 16580 m 13385 16580 l 13385 16605 l 13385 16630 l 13085 16630 l +13085 16605 l 13085 16580 l p ef +gs +gs +pum +5240 9069 t +29 -234 m 29 -234 29 -234 123 -249 ct 123 -249 123 -249 84 -115 ct 117 -170 146 -208 173 -230 ct +188 -243 200 -249 209 -249 ct 215 -249 220 -247 224 -244 ct 227 -240 229 -235 229 -228 ct +229 -216 226 -204 220 -193 ct 215 -185 209 -181 201 -181 ct 196 -181 193 -182 190 -185 ct +187 -188 185 -192 184 -198 ct 184 -201 183 -204 181 -205 ct 180 -206 178 -207 176 -207 ct +173 -207 170 -206 167 -205 ct 163 -202 155 -195 146 -183 ct 130 -165 114 -142 96 -113 ct +88 -101 81 -88 76 -72 ct 68 -51 64 -39 63 -35 ct 63 -35 63 -35 54 0 ct 54 0 54 0 12 0 ct +12 0 12 0 61 -171 ct 67 -191 70 -205 70 -214 ct 70 -217 69 -220 66 -222 ct 62 -225 58 -226 52 -226 ct +48 -226 42 -226 32 -224 ct 32 -224 32 -224 29 -234 ct p ef +346 -359 m 353 -359 360 -356 365 -351 ct 370 -346 373 -339 373 -332 ct 373 -324 370 -318 365 -312 ct +359 -307 353 -304 346 -304 ct 338 -304 332 -307 326 -312 ct 321 -318 318 -324 318 -332 ct +318 -339 321 -346 326 -351 ct 331 -356 338 -359 346 -359 ct p +358 -251 m 358 -251 358 -251 300 -55 ct 296 -42 294 -34 294 -31 ct 294 -29 294 -26 296 -25 ct +298 -23 299 -22 302 -22 ct 304 -22 307 -23 311 -26 ct 320 -34 330 -46 339 -61 ct +339 -61 339 -61 349 -55 ct 337 -36 323 -20 307 -8 ct 295 1 284 6 273 6 ct 266 6 260 4 256 -1 ct +251 -5 249 -10 249 -17 ct 249 -24 251 -35 256 -52 ct 256 -52 256 -52 295 -177 ct +301 -197 304 -210 304 -215 ct 304 -219 303 -223 300 -225 ct 297 -228 293 -229 288 -229 ct +284 -229 276 -228 263 -226 ct 263 -226 263 -226 263 -236 ct 263 -236 263 -236 358 -251 ct +p ef +500 -249 m 500 -249 500 -249 464 -123 ct 501 -174 529 -208 549 -225 ct 568 -241 587 -249 605 -249 ct +615 -249 623 -246 630 -239 ct 636 -233 639 -224 639 -214 ct 639 -203 636 -188 630 -170 ct +630 -170 630 -170 593 -55 ct 589 -42 586 -34 586 -31 ct 586 -28 587 -26 588 -25 ct +590 -23 591 -22 593 -22 ct 595 -22 597 -23 600 -25 ct 609 -33 619 -45 629 -60 ct +629 -60 629 -60 638 -55 ct 621 -31 606 -14 591 -4 ct 581 3 571 6 563 6 ct 557 6 551 4 548 0 ct +544 -4 542 -9 542 -16 ct 542 -25 545 -40 552 -61 ct 552 -61 552 -61 589 -172 ct +594 -185 596 -196 596 -204 ct 596 -207 595 -210 592 -213 ct 590 -215 586 -216 583 -216 ct +577 -216 570 -214 562 -209 ct 548 -201 532 -188 516 -169 ct 500 -150 483 -126 465 -97 ct +456 -81 448 -64 442 -46 ct 442 -46 442 -46 429 0 ct 429 0 429 0 388 0 ct 388 0 388 0 438 -173 ct +444 -193 447 -206 447 -210 ct 447 -214 445 -217 442 -220 ct 439 -223 435 -225 430 -225 ct +428 -225 424 -224 418 -224 ct 418 -224 418 -224 408 -222 ct 408 -222 408 -222 406 -232 ct +406 -232 406 -232 500 -249 ct p ef +954 -232 m 954 -232 954 -232 946 -204 ct 946 -204 946 -204 900 -204 ct 903 -194 905 -185 905 -176 ct +905 -152 895 -130 874 -111 ct 853 -92 824 -81 788 -79 ct 768 -73 754 -66 744 -58 ct +741 -55 739 -52 739 -49 ct 739 -45 741 -42 744 -39 ct 747 -36 756 -33 770 -29 ct +770 -29 770 -29 822 -17 ct 851 -11 871 -3 880 7 ct 889 17 894 28 894 41 ct 894 56 888 70 877 82 ct +866 95 850 104 829 111 ct 807 118 784 122 758 122 ct 735 122 714 119 695 114 ct +677 108 663 101 655 92 ct 647 83 643 73 643 64 ct 643 56 646 48 651 39 ct 656 31 663 24 671 18 ct +676 15 690 6 714 -7 ct 705 -13 701 -21 701 -28 ct 701 -36 705 -44 712 -52 ct 719 -60 734 -69 758 -79 ct +738 -83 723 -91 711 -104 ct 700 -117 694 -132 694 -148 ct 694 -174 706 -197 729 -218 ct +752 -239 782 -249 820 -249 ct 834 -249 846 -248 855 -245 ct 863 -242 872 -238 880 -232 ct +880 -232 880 -232 954 -232 ct p +860 -188 m 860 -202 856 -214 847 -222 ct 839 -231 828 -235 814 -235 ct 792 -235 774 -225 760 -204 ct +746 -183 739 -162 739 -139 ct 739 -125 744 -113 753 -104 ct 762 -95 772 -91 785 -91 ct +795 -91 805 -94 815 -99 ct 824 -104 832 -112 839 -121 ct 845 -130 850 -142 854 -157 ct +858 -171 860 -181 860 -188 ct p +726 0 m 710 7 699 16 691 27 ct 683 37 679 48 679 58 ct 679 70 685 80 696 88 ct +711 99 735 105 765 105 ct 792 105 814 101 833 92 ct 852 83 861 71 861 57 ct 861 50 858 43 851 37 ct +844 30 831 25 811 21 ct 800 19 772 12 726 0 ct p ef +1070 -359 m 1077 -359 1084 -356 1089 -351 ct 1094 -346 1097 -339 1097 -332 ct +1097 -324 1094 -318 1089 -312 ct 1083 -307 1077 -304 1070 -304 ct 1062 -304 1056 -307 1050 -312 ct +1045 -318 1042 -324 1042 -332 ct 1042 -339 1045 -346 1050 -351 ct 1055 -356 1062 -359 1070 -359 ct +p +1082 -251 m 1082 -251 1082 -251 1024 -55 ct 1020 -42 1018 -34 1018 -31 ct 1018 -29 1018 -26 1020 -25 ct +1022 -23 1023 -22 1026 -22 ct 1028 -22 1031 -23 1035 -26 ct 1044 -34 1054 -46 1063 -61 ct +1063 -61 1063 -61 1073 -55 ct 1061 -36 1047 -20 1031 -8 ct 1019 1 1008 6 997 6 ct +990 6 984 4 980 -1 ct 975 -5 973 -10 973 -17 ct 973 -24 975 -35 980 -52 ct 980 -52 980 -52 1019 -177 ct +1025 -197 1028 -210 1028 -215 ct 1028 -219 1027 -223 1024 -225 ct 1021 -228 1017 -229 1012 -229 ct +1008 -229 1000 -228 987 -226 ct 987 -226 987 -226 987 -236 ct 987 -236 987 -236 1082 -251 ct +p ef +1224 -249 m 1224 -249 1224 -249 1188 -123 ct 1225 -174 1253 -208 1273 -225 ct +1292 -241 1311 -249 1329 -249 ct 1339 -249 1347 -246 1354 -239 ct 1360 -233 1363 -224 1363 -214 ct +1363 -203 1360 -188 1354 -170 ct 1354 -170 1354 -170 1317 -55 ct 1313 -42 1310 -34 1310 -31 ct +1310 -28 1311 -26 1312 -25 ct 1314 -23 1315 -22 1317 -22 ct 1319 -22 1321 -23 1324 -25 ct +1333 -33 1343 -45 1353 -60 ct 1353 -60 1353 -60 1362 -55 ct 1345 -31 1330 -14 1315 -4 ct +1305 3 1295 6 1287 6 ct 1281 6 1275 4 1272 0 ct 1268 -4 1266 -9 1266 -16 ct 1266 -25 1269 -40 1276 -61 ct +1276 -61 1276 -61 1313 -172 ct 1318 -185 1320 -196 1320 -204 ct 1320 -207 1319 -210 1316 -213 ct +1314 -215 1310 -216 1307 -216 ct 1301 -216 1294 -214 1286 -209 ct 1272 -201 1256 -188 1240 -169 ct +1224 -150 1207 -126 1189 -97 ct 1180 -81 1172 -64 1166 -46 ct 1166 -46 1166 -46 1153 0 ct +1153 0 1153 0 1112 0 ct 1112 0 1112 0 1162 -173 ct 1168 -193 1171 -206 1171 -210 ct +1171 -214 1169 -217 1166 -220 ct 1163 -223 1159 -225 1154 -225 ct 1152 -225 1148 -224 1142 -224 ct +1142 -224 1142 -224 1132 -222 ct 1132 -222 1132 -222 1130 -232 ct 1130 -232 1130 -232 1224 -249 ct +p ef +1678 -232 m 1678 -232 1678 -232 1670 -204 ct 1670 -204 1670 -204 1624 -204 ct +1627 -194 1629 -185 1629 -176 ct 1629 -152 1619 -130 1598 -111 ct 1577 -92 1548 -81 1512 -79 ct +1492 -73 1478 -66 1468 -58 ct 1465 -55 1463 -52 1463 -49 ct 1463 -45 1465 -42 1468 -39 ct +1471 -36 1480 -33 1494 -29 ct 1494 -29 1494 -29 1546 -17 ct 1575 -11 1595 -3 1604 7 ct +1613 17 1618 28 1618 41 ct 1618 56 1612 70 1601 82 ct 1590 95 1574 104 1553 111 ct +1531 118 1508 122 1482 122 ct 1459 122 1438 119 1419 114 ct 1401 108 1387 101 1379 92 ct +1371 83 1367 73 1367 64 ct 1367 56 1370 48 1375 39 ct 1380 31 1387 24 1395 18 ct +1400 15 1414 6 1438 -7 ct 1429 -13 1425 -21 1425 -28 ct 1425 -36 1429 -44 1436 -52 ct +1443 -60 1458 -69 1482 -79 ct 1462 -83 1447 -91 1435 -104 ct 1424 -117 1418 -132 1418 -148 ct +1418 -174 1430 -197 1453 -218 ct 1476 -239 1506 -249 1544 -249 ct 1558 -249 1570 -248 1579 -245 ct +1587 -242 1596 -238 1604 -232 ct 1604 -232 1604 -232 1678 -232 ct p +1584 -188 m 1584 -202 1580 -214 1571 -222 ct 1563 -231 1552 -235 1538 -235 ct +1516 -235 1498 -225 1484 -204 ct 1470 -183 1463 -162 1463 -139 ct 1463 -125 1468 -113 1477 -104 ct +1486 -95 1496 -91 1509 -91 ct 1519 -91 1529 -94 1539 -99 ct 1548 -104 1556 -112 1563 -121 ct +1569 -130 1574 -142 1578 -157 ct 1582 -171 1584 -181 1584 -188 ct p +1450 0 m 1434 7 1423 16 1415 27 ct 1407 37 1403 48 1403 58 ct 1403 70 1409 80 1420 88 ct +1435 99 1459 105 1489 105 ct 1516 105 1538 101 1557 92 ct 1576 83 1585 71 1585 57 ct +1585 50 1582 43 1575 37 ct 1568 30 1555 25 1535 21 ct 1524 19 1496 12 1450 0 ct +p ef +pom +gr +gr +gs +gs +pum +11442 9254 t +92 -207 m 121 -242 149 -260 176 -260 ct 190 -260 202 -257 211 -250 ct 221 -243 229 -231 235 -216 ct +239 -205 241 -188 241 -165 ct 241 -165 241 -165 241 -57 ct 241 -41 242 -30 245 -25 ct +247 -20 250 -16 254 -14 ct 258 -11 266 -10 278 -10 ct 278 -10 278 -10 278 0 ct +278 0 278 0 154 0 ct 154 0 154 0 154 -10 ct 154 -10 154 -10 159 -10 ct 171 -10 179 -12 184 -15 ct +189 -19 192 -24 194 -31 ct 195 -34 195 -43 195 -57 ct 195 -57 195 -57 195 -161 ct +195 -184 192 -201 186 -211 ct 180 -222 170 -227 156 -227 ct 135 -227 113 -215 92 -191 ct +92 -191 92 -191 92 -57 ct 92 -40 93 -29 95 -25 ct 98 -20 101 -16 106 -14 ct 110 -11 119 -10 133 -10 ct +133 -10 133 -10 133 0 ct 133 0 133 0 9 0 ct 9 0 9 0 9 -10 ct 9 -10 9 -10 14 -10 ct +27 -10 35 -13 39 -20 ct 44 -26 46 -39 46 -57 ct 46 -57 46 -57 46 -151 ct 46 -181 45 -200 44 -206 ct +43 -213 41 -217 38 -220 ct 35 -222 31 -223 26 -223 ct 21 -223 15 -222 8 -219 ct +8 -219 8 -219 4 -229 ct 4 -229 4 -229 80 -260 ct 80 -260 80 -260 92 -260 ct 92 -260 92 -260 92 -207 ct +p ef +523 -253 m 523 -253 523 -253 523 -99 ct 523 -70 524 -53 525 -47 ct 526 -40 529 -36 532 -33 ct +535 -31 538 -29 542 -29 ct 548 -29 554 -31 561 -34 ct 561 -34 561 -34 565 -24 ct +565 -24 565 -24 490 7 ct 490 7 490 7 478 7 ct 478 7 478 7 478 -46 ct 456 -23 440 -8 428 -2 ct +417 4 405 7 392 7 ct 378 7 365 3 355 -5 ct 344 -14 337 -24 333 -37 ct 329 -50 327 -68 327 -92 ct +327 -92 327 -92 327 -205 ct 327 -217 326 -225 323 -229 ct 321 -234 317 -237 312 -240 ct +307 -242 297 -243 284 -243 ct 284 -243 284 -243 284 -253 ct 284 -253 284 -253 373 -253 ct +373 -253 373 -253 373 -84 ct 373 -60 377 -44 385 -37 ct 394 -30 403 -26 415 -26 ct +423 -26 432 -28 442 -33 ct 452 -38 464 -48 478 -62 ct 478 -62 478 -62 478 -205 ct +478 -220 475 -230 470 -235 ct 465 -240 454 -243 437 -243 ct 437 -243 437 -243 437 -253 ct +437 -253 437 -253 523 -253 ct p ef +672 -392 m 672 -392 672 -392 672 -57 ct 672 -41 673 -31 675 -26 ct 678 -21 681 -17 686 -14 ct +691 -11 700 -10 713 -10 ct 713 -10 713 -10 713 0 ct 713 0 713 0 589 0 ct 589 0 589 0 589 -10 ct +601 -10 608 -11 613 -14 ct 617 -16 620 -20 622 -25 ct 625 -31 626 -41 626 -57 ct +626 -57 626 -57 626 -286 ct 626 -314 625 -332 624 -338 ct 623 -345 621 -349 618 -352 ct +615 -354 612 -355 607 -355 ct 603 -355 597 -354 590 -351 ct 590 -351 590 -351 585 -361 ct +585 -361 585 -361 660 -392 ct 660 -392 660 -392 672 -392 ct p ef +829 -392 m 829 -392 829 -392 829 -57 ct 829 -41 830 -31 832 -26 ct 835 -21 838 -17 843 -14 ct +848 -11 857 -10 870 -10 ct 870 -10 870 -10 870 0 ct 870 0 870 0 746 0 ct 746 0 746 0 746 -10 ct +758 -10 765 -11 770 -14 ct 774 -16 777 -20 779 -25 ct 782 -31 783 -41 783 -57 ct +783 -57 783 -57 783 -286 ct 783 -314 782 -332 781 -338 ct 780 -345 778 -349 775 -352 ct +772 -354 769 -355 764 -355 ct 760 -355 754 -354 747 -351 ct 747 -351 747 -351 742 -361 ct +742 -361 742 -361 817 -392 ct 817 -392 817 -392 829 -392 ct p ef +pom +gr +gs +pum +10769 9881 t +60 -158 m 60 -121 69 -92 87 -71 ct 105 -50 126 -39 151 -39 ct 167 -39 182 -43 194 -52 ct +206 -61 216 -77 224 -99 ct 224 -99 224 -99 233 -94 ct 229 -68 218 -45 199 -24 ct +181 -3 158 7 130 7 ct 100 7 74 -5 52 -28 ct 31 -52 20 -83 20 -123 ct 20 -166 31 -200 53 -224 ct +75 -248 103 -260 136 -260 ct 164 -260 188 -251 206 -232 ct 224 -214 233 -189 233 -158 ct +233 -158 233 -158 60 -158 ct p +60 -174 m 60 -174 60 -174 176 -174 ct 175 -190 173 -201 170 -208 ct 166 -218 159 -226 150 -231 ct +141 -237 131 -240 122 -240 ct 106 -240 93 -234 81 -223 ct 69 -211 62 -195 60 -174 ct +p ef +257 -253 m 257 -253 257 -253 373 -253 ct 373 -253 373 -253 373 -243 ct 366 -243 361 -242 358 -239 ct +355 -236 354 -233 354 -229 ct 354 -224 358 -217 365 -208 ct 367 -205 370 -200 374 -194 ct +374 -194 374 -194 392 -166 ct 392 -166 392 -166 413 -194 ct 426 -211 433 -223 433 -228 ct +433 -232 431 -236 428 -239 ct 425 -242 420 -243 413 -243 ct 413 -243 413 -243 413 -253 ct +413 -253 413 -253 496 -253 ct 496 -253 496 -253 496 -243 ct 487 -242 480 -240 473 -236 ct +464 -229 452 -216 437 -195 ct 437 -195 437 -195 403 -149 ct 403 -149 403 -149 465 -58 ct +481 -36 492 -22 498 -18 ct 505 -13 513 -11 524 -10 ct 524 -10 524 -10 524 0 ct +524 0 524 0 404 0 ct 404 0 404 0 404 -10 ct 412 -10 419 -12 424 -16 ct 427 -18 429 -22 429 -26 ct +429 -30 423 -41 411 -58 ct 411 -58 411 -58 374 -112 ct 374 -112 374 -112 334 -59 ct +322 -42 316 -32 316 -29 ct 316 -24 318 -20 322 -16 ct 326 -12 333 -10 341 -10 ct +341 -10 341 -10 341 0 ct 341 0 341 0 259 0 ct 259 0 259 0 259 -10 ct 266 -11 271 -13 276 -17 ct +283 -22 295 -36 311 -58 ct 311 -58 311 -58 364 -128 ct 364 -128 364 -128 316 -198 ct +303 -218 292 -230 285 -235 ct 277 -240 268 -243 257 -243 ct 257 -243 257 -243 257 -253 ct +p ef +766 -95 m 759 -62 746 -37 726 -19 ct 706 -2 684 7 660 7 ct 631 7 606 -5 585 -29 ct +564 -53 553 -85 553 -126 ct 553 -166 565 -198 588 -223 ct 612 -248 641 -260 674 -260 ct +699 -260 719 -253 735 -240 ct 751 -227 759 -214 759 -199 ct 759 -192 757 -187 752 -182 ct +748 -178 741 -176 733 -176 ct 723 -176 715 -180 709 -187 ct 706 -190 704 -198 703 -209 ct +702 -220 698 -228 691 -234 ct 685 -239 676 -242 665 -242 ct 646 -242 632 -235 620 -222 ct +605 -204 598 -180 598 -150 ct 598 -120 605 -94 620 -71 ct 635 -48 655 -36 680 -36 ct +698 -36 714 -42 729 -54 ct 739 -62 748 -77 758 -99 ct 758 -99 758 -99 766 -95 ct +p ef +865 -392 m 873 -392 879 -389 885 -384 ct 890 -378 893 -372 893 -364 ct 893 -356 890 -350 885 -344 ct +879 -339 873 -336 865 -336 ct 857 -336 851 -339 845 -344 ct 840 -350 837 -356 837 -364 ct +837 -372 840 -378 845 -384 ct 851 -389 857 -392 865 -392 ct p +888 -260 m 888 -260 888 -260 888 -57 ct 888 -41 889 -31 891 -26 ct 894 -20 897 -16 901 -14 ct +906 -11 913 -10 925 -10 ct 925 -10 925 -10 925 0 ct 925 0 925 0 805 0 ct 805 0 805 0 805 -10 ct +817 -10 825 -11 829 -14 ct 833 -16 836 -20 838 -25 ct 841 -31 842 -41 842 -57 ct +842 -57 842 -57 842 -154 ct 842 -181 841 -199 840 -207 ct 838 -213 836 -217 834 -220 ct +831 -222 827 -223 822 -223 ct 817 -223 811 -222 804 -219 ct 804 -219 804 -219 800 -229 ct +800 -229 800 -229 876 -260 ct 876 -260 876 -260 888 -260 ct p ef +1031 -337 m 1031 -337 1031 -337 1031 -253 ct 1031 -253 1031 -253 1090 -253 ct +1090 -253 1090 -253 1090 -234 ct 1090 -234 1090 -234 1031 -234 ct 1031 -234 1031 -234 1031 -70 ct +1031 -53 1033 -42 1038 -37 ct 1043 -31 1049 -28 1056 -28 ct 1062 -28 1068 -30 1074 -34 ct +1079 -37 1084 -43 1087 -50 ct 1087 -50 1087 -50 1098 -50 ct 1092 -32 1082 -19 1071 -10 ct +1059 -1 1046 4 1034 4 ct 1025 4 1017 2 1009 -3 ct 1001 -8 995 -14 991 -23 ct 987 -32 985 -45 985 -64 ct +985 -64 985 -64 985 -234 ct 985 -234 985 -234 945 -234 ct 945 -234 945 -234 945 -243 ct +955 -247 965 -254 976 -264 ct 987 -273 996 -285 1004 -298 ct 1009 -305 1014 -318 1022 -337 ct +1022 -337 1022 -337 1031 -337 ct p ef +1257 -37 m 1231 -17 1215 -5 1208 -2 ct 1198 3 1188 5 1176 5 ct 1159 5 1144 -1 1133 -13 ct +1122 -25 1116 -40 1116 -60 ct 1116 -72 1119 -83 1124 -92 ct 1132 -104 1145 -116 1164 -127 ct +1182 -138 1214 -151 1257 -167 ct 1257 -167 1257 -167 1257 -177 ct 1257 -202 1253 -219 1245 -228 ct +1237 -237 1226 -242 1210 -242 ct 1199 -242 1190 -239 1183 -233 ct 1176 -226 1172 -219 1172 -211 ct +1172 -211 1172 -211 1173 -195 ct 1173 -187 1171 -180 1166 -176 ct 1162 -171 1156 -169 1149 -169 ct +1143 -169 1137 -171 1133 -176 ct 1128 -181 1126 -188 1126 -196 ct 1126 -212 1134 -227 1150 -240 ct +1166 -253 1189 -260 1218 -260 ct 1240 -260 1259 -256 1273 -249 ct 1284 -243 1292 -234 1297 -222 ct +1300 -214 1302 -198 1302 -174 ct 1302 -174 1302 -174 1302 -89 ct 1302 -65 1302 -50 1303 -45 ct +1304 -39 1306 -36 1308 -34 ct 1310 -32 1312 -31 1315 -31 ct 1318 -31 1321 -32 1323 -33 ct +1327 -35 1334 -42 1345 -53 ct 1345 -53 1345 -53 1345 -38 ct 1325 -10 1305 4 1287 4 ct +1278 4 1270 1 1265 -5 ct 1260 -11 1257 -22 1257 -37 ct p +1257 -54 m 1257 -54 1257 -54 1257 -149 ct 1229 -138 1211 -130 1203 -126 ct +1188 -118 1178 -110 1171 -101 ct 1165 -92 1162 -83 1162 -72 ct 1162 -59 1166 -49 1174 -40 ct +1182 -31 1191 -27 1201 -27 ct 1216 -27 1234 -36 1257 -54 ct p ef +1437 -337 m 1437 -337 1437 -337 1437 -253 ct 1437 -253 1437 -253 1496 -253 ct +1496 -253 1496 -253 1496 -234 ct 1496 -234 1496 -234 1437 -234 ct 1437 -234 1437 -234 1437 -70 ct +1437 -53 1439 -42 1444 -37 ct 1449 -31 1455 -28 1462 -28 ct 1468 -28 1474 -30 1480 -34 ct +1485 -37 1490 -43 1493 -50 ct 1493 -50 1493 -50 1504 -50 ct 1498 -32 1488 -19 1477 -10 ct +1465 -1 1452 4 1440 4 ct 1431 4 1423 2 1415 -3 ct 1407 -8 1401 -14 1397 -23 ct +1393 -32 1391 -45 1391 -64 ct 1391 -64 1391 -64 1391 -234 ct 1391 -234 1391 -234 1351 -234 ct +1351 -234 1351 -234 1351 -243 ct 1361 -247 1371 -254 1382 -264 ct 1393 -273 1402 -285 1410 -298 ct +1415 -305 1420 -318 1428 -337 ct 1428 -337 1428 -337 1437 -337 ct p ef +1585 -392 m 1593 -392 1599 -389 1605 -384 ct 1610 -378 1613 -372 1613 -364 ct +1613 -356 1610 -350 1605 -344 ct 1599 -339 1593 -336 1585 -336 ct 1577 -336 1571 -339 1565 -344 ct +1560 -350 1557 -356 1557 -364 ct 1557 -372 1560 -378 1565 -384 ct 1571 -389 1577 -392 1585 -392 ct +p +1608 -260 m 1608 -260 1608 -260 1608 -57 ct 1608 -41 1609 -31 1611 -26 ct 1614 -20 1617 -16 1621 -14 ct +1626 -11 1633 -10 1645 -10 ct 1645 -10 1645 -10 1645 0 ct 1645 0 1645 0 1525 0 ct +1525 0 1525 0 1525 -10 ct 1537 -10 1545 -11 1549 -14 ct 1553 -16 1556 -20 1558 -25 ct +1561 -31 1562 -41 1562 -57 ct 1562 -57 1562 -57 1562 -154 ct 1562 -181 1561 -199 1560 -207 ct +1558 -213 1556 -217 1554 -220 ct 1551 -222 1547 -223 1542 -223 ct 1537 -223 1531 -222 1524 -219 ct +1524 -219 1524 -219 1520 -229 ct 1520 -229 1520 -229 1596 -260 ct 1596 -260 1596 -260 1608 -260 ct +p ef +1801 -260 m 1839 -260 1870 -246 1893 -217 ct 1912 -192 1922 -163 1922 -131 ct +1922 -109 1917 -86 1906 -63 ct 1895 -40 1880 -22 1861 -11 ct 1842 1 1821 7 1798 7 ct +1760 7 1730 -8 1707 -38 ct 1688 -64 1679 -92 1679 -124 ct 1679 -147 1685 -170 1696 -193 ct +1708 -216 1723 -233 1741 -244 ct 1760 -255 1780 -260 1801 -260 ct p +1792 -242 m 1783 -242 1773 -239 1763 -233 ct 1753 -228 1745 -218 1739 -203 ct +1733 -189 1730 -170 1730 -147 ct 1730 -111 1737 -79 1752 -53 ct 1767 -26 1786 -13 1810 -13 ct +1827 -13 1842 -20 1854 -35 ct 1865 -50 1871 -75 1871 -110 ct 1871 -155 1861 -190 1842 -216 ct +1829 -233 1812 -242 1792 -242 ct p ef +2035 -207 m 2064 -242 2092 -260 2119 -260 ct 2133 -260 2145 -257 2154 -250 ct +2164 -243 2172 -231 2178 -216 ct 2182 -205 2184 -188 2184 -165 ct 2184 -165 2184 -165 2184 -57 ct +2184 -41 2185 -30 2188 -25 ct 2190 -20 2193 -16 2197 -14 ct 2201 -11 2209 -10 2221 -10 ct +2221 -10 2221 -10 2221 0 ct 2221 0 2221 0 2097 0 ct 2097 0 2097 0 2097 -10 ct 2097 -10 2097 -10 2102 -10 ct +2114 -10 2122 -12 2127 -15 ct 2132 -19 2135 -24 2137 -31 ct 2138 -34 2138 -43 2138 -57 ct +2138 -57 2138 -57 2138 -161 ct 2138 -184 2135 -201 2129 -211 ct 2123 -222 2113 -227 2099 -227 ct +2078 -227 2056 -215 2035 -191 ct 2035 -191 2035 -191 2035 -57 ct 2035 -40 2036 -29 2038 -25 ct +2041 -20 2044 -16 2049 -14 ct 2053 -11 2062 -10 2076 -10 ct 2076 -10 2076 -10 2076 0 ct +2076 0 2076 0 1952 0 ct 1952 0 1952 0 1952 -10 ct 1952 -10 1952 -10 1957 -10 ct +1970 -10 1978 -13 1982 -20 ct 1987 -26 1989 -39 1989 -57 ct 1989 -57 1989 -57 1989 -151 ct +1989 -181 1988 -200 1987 -206 ct 1986 -213 1984 -217 1981 -220 ct 1978 -222 1974 -223 1969 -223 ct +1964 -223 1958 -222 1951 -219 ct 1951 -219 1951 -219 1947 -229 ct 1947 -229 1947 -229 2023 -260 ct +2023 -260 2023 -260 2035 -260 ct 2035 -260 2035 -260 2035 -207 ct p ef +pom +gr +gr +9135 9385 m 9698 9198 l 9698 9573 l 9135 9385 l p ef +10635 9410 m 9585 9410 l 9585 9360 l 10635 9360 l 10635 9410 l p ef +gs +gs +pum +5372 21285 t +31 -212 m 31 -299 l 298 -299 l 298 -212 l 31 -212 l p ef +pom +gr +gr +gs +gs +pum +5372 11495 t +31 -212 m 31 -299 l 298 -299 l 298 -212 l 31 -212 l p ef +pom +gr +gr +gs +gs +pum +5372 10199 t +31 -212 m 31 -299 l 298 -299 l 298 -212 l 31 -212 l p ef +pom +gr +gr +gs +gs +pum +2673 10762 t +153 -317 m 153 -317 153 -317 131 -243 ct 131 -243 131 -243 169 -243 ct 169 -243 169 -243 164 -225 ct +164 -225 164 -225 125 -225 ct 125 -225 125 -225 76 -63 ct 69 -44 66 -33 66 -27 ct +66 -24 67 -22 68 -20 ct 69 -19 71 -18 73 -18 ct 77 -18 82 -21 89 -27 ct 93 -31 101 -42 115 -61 ct +115 -61 115 -61 124 -54 ct 108 -30 93 -13 79 -4 ct 69 3 59 6 49 6 ct 42 6 36 4 31 -1 ct +26 -6 24 -13 24 -20 ct 24 -30 27 -45 33 -66 ct 33 -66 33 -66 81 -225 ct 81 -225 81 -225 39 -225 ct +39 -225 39 -225 42 -236 ct 62 -242 79 -250 93 -261 ct 107 -272 123 -291 141 -317 ct +141 -317 141 -317 153 -317 ct p ef +436 -245 m 436 -245 436 -245 383 -58 ct 383 -58 383 -58 377 -33 ct 376 -31 375 -29 375 -28 ct +375 -25 376 -23 377 -21 ct 378 -19 379 -19 381 -19 ct 383 -19 385 -20 388 -22 ct +393 -27 399 -38 408 -55 ct 408 -55 408 -55 417 -48 ct 406 -30 395 -16 384 -7 ct +373 2 362 6 353 6 ct 346 6 341 4 337 0 ct 334 -4 332 -9 332 -17 ct 332 -26 334 -38 338 -52 ct +338 -52 338 -52 344 -73 ct 318 -42 293 -20 271 -7 ct 255 2 240 6 224 6 ct 209 6 197 1 186 -10 ct +175 -21 170 -36 170 -55 ct 170 -84 180 -114 199 -146 ct 218 -178 242 -203 271 -222 ct +294 -237 316 -245 336 -245 ct 348 -245 358 -242 366 -237 ct 375 -232 381 -223 385 -210 ct +385 -210 385 -210 393 -238 ct 393 -238 393 -238 436 -245 ct p +334 -231 m 321 -231 308 -226 293 -215 ct 273 -200 255 -177 239 -147 ct 223 -117 215 -90 215 -66 ct +215 -53 219 -44 226 -37 ct 233 -30 241 -26 250 -26 ct 273 -26 297 -40 324 -69 ct +356 -108 372 -147 371 -188 ct 371 -203 368 -214 361 -221 ct 355 -228 346 -231 334 -231 ct +p ef +469 -234 m 469 -234 469 -234 563 -249 ct 563 -249 563 -249 524 -115 ct 557 -170 586 -208 613 -230 ct +628 -243 640 -249 649 -249 ct 655 -249 660 -247 664 -244 ct 667 -240 669 -235 669 -228 ct +669 -216 666 -204 660 -193 ct 655 -185 649 -181 641 -181 ct 636 -181 633 -182 630 -185 ct +627 -188 625 -192 624 -198 ct 624 -201 623 -204 621 -205 ct 620 -206 618 -207 616 -207 ct +613 -207 610 -206 607 -205 ct 603 -202 595 -195 586 -183 ct 570 -165 554 -142 536 -113 ct +528 -101 521 -88 516 -72 ct 508 -51 504 -39 503 -35 ct 503 -35 503 -35 494 0 ct +494 0 494 0 452 0 ct 452 0 452 0 501 -171 ct 507 -191 510 -205 510 -214 ct 510 -217 509 -220 506 -222 ct +502 -225 498 -226 492 -226 ct 488 -226 482 -226 472 -224 ct 472 -224 472 -224 469 -234 ct +p ef +954 -232 m 954 -232 954 -232 946 -204 ct 946 -204 946 -204 900 -204 ct 903 -194 905 -185 905 -176 ct +905 -152 895 -130 874 -111 ct 853 -92 824 -81 788 -79 ct 768 -73 754 -66 744 -58 ct +741 -55 739 -52 739 -49 ct 739 -45 741 -42 744 -39 ct 747 -36 756 -33 770 -29 ct +770 -29 770 -29 822 -17 ct 851 -11 871 -3 880 7 ct 889 17 894 28 894 41 ct 894 56 888 70 877 82 ct +866 95 850 104 829 111 ct 807 118 784 122 758 122 ct 735 122 714 119 695 114 ct +677 108 663 101 655 92 ct 647 83 643 73 643 64 ct 643 56 646 48 651 39 ct 656 31 663 24 671 18 ct +676 15 690 6 714 -7 ct 705 -13 701 -21 701 -28 ct 701 -36 705 -44 712 -52 ct 719 -60 734 -69 758 -79 ct +738 -83 723 -91 711 -104 ct 700 -117 694 -132 694 -148 ct 694 -174 706 -197 729 -218 ct +752 -239 782 -249 820 -249 ct 834 -249 846 -248 855 -245 ct 863 -242 872 -238 880 -232 ct +880 -232 880 -232 954 -232 ct p +860 -188 m 860 -202 856 -214 847 -222 ct 839 -231 828 -235 814 -235 ct 792 -235 774 -225 760 -204 ct +746 -183 739 -162 739 -139 ct 739 -125 744 -113 753 -104 ct 762 -95 772 -91 785 -91 ct +795 -91 805 -94 815 -99 ct 824 -104 832 -112 839 -121 ct 845 -130 850 -142 854 -157 ct +858 -171 860 -181 860 -188 ct p +726 0 m 710 7 699 16 691 27 ct 683 37 679 48 679 58 ct 679 70 685 80 696 88 ct +711 99 735 105 765 105 ct 792 105 814 101 833 92 ct 852 83 861 71 861 57 ct 861 50 858 43 851 37 ct +844 30 831 25 811 21 ct 800 19 772 12 726 0 ct p ef +1008 -106 m 1007 -97 1006 -89 1006 -83 ct 1006 -66 1012 -52 1024 -40 ct 1035 -29 1050 -23 1067 -23 ct +1080 -23 1093 -26 1105 -31 ct 1118 -37 1136 -49 1161 -68 ct 1161 -68 1161 -68 1167 -60 ct +1123 -16 1082 6 1042 6 ct 1015 6 995 -2 981 -19 ct 968 -36 961 -55 961 -75 ct 961 -102 969 -130 986 -159 ct +1003 -187 1024 -209 1050 -225 ct 1075 -241 1102 -249 1129 -249 ct 1148 -249 1163 -245 1172 -237 ct +1181 -230 1186 -220 1186 -210 ct 1186 -195 1180 -180 1168 -167 ct 1151 -149 1128 -134 1096 -123 ct +1075 -116 1046 -110 1008 -106 ct p +1010 -118 m 1038 -121 1060 -126 1078 -134 ct 1101 -144 1118 -156 1130 -170 ct +1141 -184 1147 -197 1147 -209 ct 1147 -217 1145 -223 1140 -228 ct 1135 -233 1128 -235 1118 -235 ct +1099 -235 1079 -225 1057 -205 ct 1036 -186 1020 -157 1010 -118 ct p ef +1347 -317 m 1347 -317 1347 -317 1325 -243 ct 1325 -243 1325 -243 1363 -243 ct +1363 -243 1363 -243 1358 -225 ct 1358 -225 1358 -225 1319 -225 ct 1319 -225 1319 -225 1270 -63 ct +1263 -44 1260 -33 1260 -27 ct 1260 -24 1261 -22 1262 -20 ct 1263 -19 1265 -18 1267 -18 ct +1271 -18 1276 -21 1283 -27 ct 1287 -31 1295 -42 1309 -61 ct 1309 -61 1309 -61 1318 -54 ct +1302 -30 1287 -13 1273 -4 ct 1263 3 1253 6 1243 6 ct 1236 6 1230 4 1225 -1 ct 1220 -6 1218 -13 1218 -20 ct +1218 -30 1221 -45 1227 -66 ct 1227 -66 1227 -66 1275 -225 ct 1275 -225 1275 -225 1233 -225 ct +1233 -225 1233 -225 1236 -236 ct 1256 -242 1273 -250 1287 -261 ct 1301 -272 1317 -291 1335 -317 ct +1335 -317 1335 -317 1347 -317 ct p ef +pom +gr +gr +gs +gs +pum +6483 18964 t +85 -93 m 69 -101 58 -111 49 -125 ct 41 -138 37 -153 37 -169 ct 37 -194 46 -215 65 -233 ct +84 -251 108 -260 138 -260 ct 162 -260 183 -254 200 -242 ct 200 -242 200 -242 254 -242 ct +262 -242 266 -242 268 -241 ct 269 -241 270 -240 270 -239 ct 271 -237 272 -234 272 -230 ct +272 -225 272 -222 271 -220 ct 270 -219 269 -218 268 -218 ct 266 -217 262 -217 254 -217 ct +254 -217 254 -217 221 -217 ct 231 -204 236 -187 236 -167 ct 236 -143 227 -123 209 -107 ct +191 -90 167 -82 137 -82 ct 124 -82 111 -84 98 -88 ct 90 -81 85 -74 82 -69 ct 79 -64 78 -59 78 -56 ct +78 -52 80 -49 83 -46 ct 86 -43 91 -41 100 -40 ct 105 -39 118 -39 139 -38 ct 176 -37 201 -36 212 -34 ct +229 -32 243 -25 253 -15 ct 263 -5 268 8 268 23 ct 268 44 258 63 239 82 ct 211 109 173 122 128 122 ct +92 122 63 114 39 98 ct 25 89 18 79 18 69 ct 18 65 19 60 21 56 ct 24 49 30 40 40 28 ct +41 26 50 16 67 -2 ct 58 -8 51 -13 47 -18 ct 43 -22 41 -27 41 -33 ct 41 -40 44 -47 49 -56 ct +54 -65 66 -77 85 -93 ct p +133 -246 m 119 -246 108 -241 99 -230 ct 90 -219 85 -203 85 -181 ct 85 -152 91 -130 104 -114 ct +113 -102 125 -96 140 -96 ct 154 -96 166 -101 175 -112 ct 184 -122 188 -138 188 -160 ct +188 -189 182 -212 169 -228 ct 160 -240 148 -246 133 -246 ct p +82 0 m 74 9 68 18 63 26 ct 59 34 57 42 57 49 ct 57 57 62 65 73 72 ct 91 83 117 89 152 89 ct +185 89 209 83 225 71 ct 240 60 248 47 248 34 ct 248 24 243 17 234 13 ct 224 9 206 7 177 6 ct +136 5 104 3 82 0 ct p ef +445 -37 m 419 -17 403 -5 396 -2 ct 386 3 376 5 364 5 ct 347 5 332 -1 321 -13 ct +310 -25 304 -40 304 -60 ct 304 -72 307 -83 312 -92 ct 320 -104 333 -116 352 -127 ct +370 -138 402 -151 445 -167 ct 445 -167 445 -167 445 -177 ct 445 -202 441 -219 433 -228 ct +425 -237 414 -242 398 -242 ct 387 -242 378 -239 371 -233 ct 364 -226 360 -219 360 -211 ct +360 -211 360 -211 361 -195 ct 361 -187 359 -180 354 -176 ct 350 -171 344 -169 337 -169 ct +331 -169 325 -171 321 -176 ct 316 -181 314 -188 314 -196 ct 314 -212 322 -227 338 -240 ct +354 -253 377 -260 406 -260 ct 428 -260 447 -256 461 -249 ct 472 -243 480 -234 485 -222 ct +488 -214 490 -198 490 -174 ct 490 -174 490 -174 490 -89 ct 490 -65 490 -50 491 -45 ct +492 -39 494 -36 496 -34 ct 498 -32 500 -31 503 -31 ct 506 -31 509 -32 511 -33 ct +515 -35 522 -42 533 -53 ct 533 -53 533 -53 533 -38 ct 513 -10 493 4 475 4 ct 466 4 458 1 453 -5 ct +448 -11 445 -22 445 -37 ct p +445 -54 m 445 -54 445 -54 445 -149 ct 417 -138 399 -130 391 -126 ct 376 -118 366 -110 359 -101 ct +353 -92 350 -83 350 -72 ct 350 -59 354 -49 362 -40 ct 370 -31 379 -27 389 -27 ct +404 -27 422 -36 445 -54 ct p ef +615 -392 m 623 -392 629 -389 635 -384 ct 640 -378 643 -372 643 -364 ct 643 -356 640 -350 635 -344 ct +629 -339 623 -336 615 -336 ct 607 -336 601 -339 595 -344 ct 590 -350 587 -356 587 -364 ct +587 -372 590 -378 595 -384 ct 601 -389 607 -392 615 -392 ct p +638 -260 m 638 -260 638 -260 638 -57 ct 638 -41 639 -31 641 -26 ct 644 -20 647 -16 651 -14 ct +656 -11 663 -10 675 -10 ct 675 -10 675 -10 675 0 ct 675 0 675 0 555 0 ct 555 0 555 0 555 -10 ct +567 -10 575 -11 579 -14 ct 583 -16 586 -20 588 -25 ct 591 -31 592 -41 592 -57 ct +592 -57 592 -57 592 -154 ct 592 -181 591 -199 590 -207 ct 588 -213 586 -217 584 -220 ct +581 -222 577 -223 572 -223 ct 567 -223 561 -222 554 -219 ct 554 -219 554 -219 550 -229 ct +550 -229 550 -229 626 -260 ct 626 -260 626 -260 638 -260 ct p ef +782 -207 m 811 -242 839 -260 866 -260 ct 880 -260 892 -257 901 -250 ct 911 -243 919 -231 925 -216 ct +929 -205 931 -188 931 -165 ct 931 -165 931 -165 931 -57 ct 931 -41 932 -30 935 -25 ct +937 -20 940 -16 944 -14 ct 948 -11 956 -10 968 -10 ct 968 -10 968 -10 968 0 ct +968 0 968 0 844 0 ct 844 0 844 0 844 -10 ct 844 -10 844 -10 849 -10 ct 861 -10 869 -12 874 -15 ct +879 -19 882 -24 884 -31 ct 885 -34 885 -43 885 -57 ct 885 -57 885 -57 885 -161 ct +885 -184 882 -201 876 -211 ct 870 -222 860 -227 846 -227 ct 825 -227 803 -215 782 -191 ct +782 -191 782 -191 782 -57 ct 782 -40 783 -29 785 -25 ct 788 -20 791 -16 796 -14 ct +800 -11 809 -10 823 -10 ct 823 -10 823 -10 823 0 ct 823 0 823 0 699 0 ct 699 0 699 0 699 -10 ct +699 -10 699 -10 704 -10 ct 717 -10 725 -13 729 -20 ct 734 -26 736 -39 736 -57 ct +736 -57 736 -57 736 -151 ct 736 -181 735 -200 734 -206 ct 733 -213 731 -217 728 -220 ct +725 -222 721 -223 716 -223 ct 711 -223 705 -222 698 -219 ct 698 -219 698 -219 694 -229 ct +694 -229 694 -229 770 -260 ct 770 -260 770 -260 782 -260 ct 782 -260 782 -260 782 -207 ct +p ef +1205 -207 m 1234 -242 1262 -260 1289 -260 ct 1303 -260 1315 -257 1324 -250 ct +1334 -243 1342 -231 1348 -216 ct 1352 -205 1354 -188 1354 -165 ct 1354 -165 1354 -165 1354 -57 ct +1354 -41 1355 -30 1358 -25 ct 1360 -20 1363 -16 1367 -14 ct 1371 -11 1379 -10 1391 -10 ct +1391 -10 1391 -10 1391 0 ct 1391 0 1391 0 1267 0 ct 1267 0 1267 0 1267 -10 ct 1267 -10 1267 -10 1272 -10 ct +1284 -10 1292 -12 1297 -15 ct 1302 -19 1305 -24 1307 -31 ct 1308 -34 1308 -43 1308 -57 ct +1308 -57 1308 -57 1308 -161 ct 1308 -184 1305 -201 1299 -211 ct 1293 -222 1283 -227 1269 -227 ct +1248 -227 1226 -215 1205 -191 ct 1205 -191 1205 -191 1205 -57 ct 1205 -40 1206 -29 1208 -25 ct +1211 -20 1214 -16 1219 -14 ct 1223 -11 1232 -10 1246 -10 ct 1246 -10 1246 -10 1246 0 ct +1246 0 1246 0 1122 0 ct 1122 0 1122 0 1122 -10 ct 1122 -10 1122 -10 1127 -10 ct +1140 -10 1148 -13 1152 -20 ct 1157 -26 1159 -39 1159 -57 ct 1159 -57 1159 -57 1159 -151 ct +1159 -181 1158 -200 1157 -206 ct 1156 -213 1154 -217 1151 -220 ct 1148 -222 1144 -223 1139 -223 ct +1134 -223 1128 -222 1121 -219 ct 1121 -219 1121 -219 1117 -229 ct 1117 -229 1117 -229 1193 -260 ct +1193 -260 1193 -260 1205 -260 ct 1205 -260 1205 -260 1205 -207 ct p ef +1539 -260 m 1577 -260 1608 -246 1631 -217 ct 1650 -192 1660 -163 1660 -131 ct +1660 -109 1655 -86 1644 -63 ct 1633 -40 1618 -22 1599 -11 ct 1580 1 1559 7 1536 7 ct +1498 7 1468 -8 1445 -38 ct 1426 -64 1417 -92 1417 -124 ct 1417 -147 1423 -170 1434 -193 ct +1446 -216 1461 -233 1479 -244 ct 1498 -255 1518 -260 1539 -260 ct p +1530 -242 m 1521 -242 1511 -239 1501 -233 ct 1491 -228 1483 -218 1477 -203 ct +1471 -189 1468 -170 1468 -147 ct 1468 -111 1475 -79 1490 -53 ct 1505 -26 1524 -13 1548 -13 ct +1565 -13 1580 -20 1592 -35 ct 1603 -50 1609 -75 1609 -110 ct 1609 -155 1599 -190 1580 -216 ct +1567 -233 1550 -242 1530 -242 ct p ef +1773 -260 m 1773 -260 1773 -260 1773 -203 ct 1794 -241 1816 -260 1838 -260 ct +1848 -260 1856 -257 1863 -251 ct 1870 -245 1873 -238 1873 -230 ct 1873 -222 1871 -216 1866 -211 ct +1861 -206 1855 -204 1849 -204 ct 1842 -204 1835 -207 1827 -214 ct 1819 -220 1813 -223 1809 -223 ct +1806 -223 1802 -221 1799 -217 ct 1790 -210 1782 -198 1773 -180 ct 1773 -180 1773 -180 1773 -59 ct +1773 -45 1775 -34 1778 -27 ct 1781 -22 1785 -18 1791 -15 ct 1797 -12 1806 -10 1818 -10 ct +1818 -10 1818 -10 1818 0 ct 1818 0 1818 0 1686 0 ct 1686 0 1686 0 1686 -10 ct 1699 -10 1709 -12 1716 -16 ct +1720 -19 1724 -24 1726 -30 ct 1727 -33 1727 -42 1727 -57 ct 1727 -57 1727 -57 1727 -154 ct +1727 -184 1726 -201 1725 -207 ct 1724 -213 1722 -217 1719 -219 ct 1716 -222 1712 -223 1707 -223 ct +1701 -223 1695 -222 1688 -219 ct 1688 -219 1688 -219 1685 -229 ct 1685 -229 1685 -229 1761 -260 ct +1761 -260 1761 -260 1773 -260 ct p ef +1960 -206 m 1978 -225 1989 -235 1992 -238 ct 2001 -245 2009 -250 2019 -254 ct +2029 -258 2038 -260 2047 -260 ct 2063 -260 2077 -255 2088 -246 ct 2099 -237 2107 -224 2111 -206 ct +2130 -228 2146 -243 2159 -250 ct 2172 -257 2185 -260 2199 -260 ct 2212 -260 2224 -257 2234 -250 ct +2245 -243 2253 -232 2259 -216 ct 2263 -205 2265 -188 2265 -166 ct 2265 -166 2265 -166 2265 -57 ct +2265 -41 2266 -30 2268 -25 ct 2270 -21 2274 -17 2278 -14 ct 2283 -11 2291 -10 2302 -10 ct +2302 -10 2302 -10 2302 0 ct 2302 0 2302 0 2178 0 ct 2178 0 2178 0 2178 -10 ct 2178 -10 2178 -10 2183 -10 ct +2194 -10 2203 -12 2209 -16 ct 2213 -19 2216 -24 2218 -30 ct 2219 -33 2219 -42 2219 -57 ct +2219 -57 2219 -57 2219 -166 ct 2219 -186 2217 -201 2212 -209 ct 2204 -221 2193 -227 2177 -227 ct +2168 -227 2158 -225 2148 -220 ct 2138 -215 2126 -206 2113 -193 ct 2113 -193 2113 -193 2112 -189 ct +2112 -189 2112 -189 2113 -178 ct 2113 -178 2113 -178 2113 -57 ct 2113 -40 2114 -29 2116 -25 ct +2118 -21 2121 -17 2127 -14 ct 2132 -11 2141 -10 2154 -10 ct 2154 -10 2154 -10 2154 0 ct +2154 0 2154 0 2026 0 ct 2026 0 2026 0 2026 -10 ct 2040 -10 2050 -12 2055 -15 ct +2060 -18 2064 -23 2066 -30 ct 2067 -33 2067 -42 2067 -57 ct 2067 -57 2067 -57 2067 -166 ct +2067 -186 2064 -201 2058 -210 ct 2050 -221 2039 -227 2024 -227 ct 2014 -227 2005 -224 1995 -219 ct +1980 -211 1968 -202 1960 -193 ct 1960 -193 1960 -193 1960 -57 ct 1960 -41 1961 -30 1963 -25 ct +1966 -20 1969 -16 1974 -14 ct 1978 -11 1987 -10 2001 -10 ct 2001 -10 2001 -10 2001 0 ct +2001 0 2001 0 1877 0 ct 1877 0 1877 0 1877 -10 ct 1888 -10 1896 -11 1900 -14 ct +1905 -16 1908 -20 1911 -26 ct 1913 -31 1914 -41 1914 -57 ct 1914 -57 1914 -57 1914 -154 ct +1914 -182 1913 -199 1912 -207 ct 1910 -213 1908 -217 1906 -220 ct 1903 -222 1899 -223 1894 -223 ct +1889 -223 1883 -222 1876 -219 ct 1876 -219 1876 -219 1872 -229 ct 1872 -229 1872 -229 1948 -260 ct +1948 -260 1948 -260 1960 -260 ct 1960 -260 1960 -260 1960 -206 ct p ef +2455 -37 m 2429 -17 2413 -5 2406 -2 ct 2396 3 2386 5 2374 5 ct 2357 5 2342 -1 2331 -13 ct +2320 -25 2314 -40 2314 -60 ct 2314 -72 2317 -83 2322 -92 ct 2330 -104 2343 -116 2362 -127 ct +2380 -138 2412 -151 2455 -167 ct 2455 -167 2455 -167 2455 -177 ct 2455 -202 2451 -219 2443 -228 ct +2435 -237 2424 -242 2408 -242 ct 2397 -242 2388 -239 2381 -233 ct 2374 -226 2370 -219 2370 -211 ct +2370 -211 2370 -211 2371 -195 ct 2371 -187 2369 -180 2364 -176 ct 2360 -171 2354 -169 2347 -169 ct +2341 -169 2335 -171 2331 -176 ct 2326 -181 2324 -188 2324 -196 ct 2324 -212 2332 -227 2348 -240 ct +2364 -253 2387 -260 2416 -260 ct 2438 -260 2457 -256 2471 -249 ct 2482 -243 2490 -234 2495 -222 ct +2498 -214 2500 -198 2500 -174 ct 2500 -174 2500 -174 2500 -89 ct 2500 -65 2500 -50 2501 -45 ct +2502 -39 2504 -36 2506 -34 ct 2508 -32 2510 -31 2513 -31 ct 2516 -31 2519 -32 2521 -33 ct +2525 -35 2532 -42 2543 -53 ct 2543 -53 2543 -53 2543 -38 ct 2523 -10 2503 4 2485 4 ct +2476 4 2468 1 2463 -5 ct 2458 -11 2455 -22 2455 -37 ct p +2455 -54 m 2455 -54 2455 -54 2455 -149 ct 2427 -138 2409 -130 2401 -126 ct +2386 -118 2376 -110 2369 -101 ct 2363 -92 2360 -83 2360 -72 ct 2360 -59 2364 -49 2372 -40 ct +2380 -31 2389 -27 2399 -27 ct 2414 -27 2432 -36 2455 -54 ct p ef +2649 -392 m 2649 -392 2649 -392 2649 -57 ct 2649 -41 2650 -31 2652 -26 ct 2655 -21 2658 -17 2663 -14 ct +2668 -11 2677 -10 2690 -10 ct 2690 -10 2690 -10 2690 0 ct 2690 0 2690 0 2566 0 ct +2566 0 2566 0 2566 -10 ct 2578 -10 2585 -11 2590 -14 ct 2594 -16 2597 -20 2599 -25 ct +2602 -31 2603 -41 2603 -57 ct 2603 -57 2603 -57 2603 -286 ct 2603 -314 2602 -332 2601 -338 ct +2600 -345 2598 -349 2595 -352 ct 2592 -354 2589 -355 2584 -355 ct 2580 -355 2574 -354 2567 -351 ct +2567 -351 2567 -351 2562 -361 ct 2562 -361 2562 -361 2637 -392 ct 2637 -392 2637 -392 2649 -392 ct +p ef +2783 -392 m 2791 -392 2797 -389 2803 -384 ct 2808 -378 2811 -372 2811 -364 ct +2811 -356 2808 -350 2803 -344 ct 2797 -339 2791 -336 2783 -336 ct 2775 -336 2769 -339 2763 -344 ct +2758 -350 2755 -356 2755 -364 ct 2755 -372 2758 -378 2763 -384 ct 2769 -389 2775 -392 2783 -392 ct +p +2806 -260 m 2806 -260 2806 -260 2806 -57 ct 2806 -41 2807 -31 2809 -26 ct 2812 -20 2815 -16 2819 -14 ct +2824 -11 2831 -10 2843 -10 ct 2843 -10 2843 -10 2843 0 ct 2843 0 2843 0 2723 0 ct +2723 0 2723 0 2723 -10 ct 2735 -10 2743 -11 2747 -14 ct 2751 -16 2754 -20 2756 -25 ct +2759 -31 2760 -41 2760 -57 ct 2760 -57 2760 -57 2760 -154 ct 2760 -181 2759 -199 2758 -207 ct +2756 -213 2754 -217 2752 -220 ct 2749 -222 2745 -223 2740 -223 ct 2735 -223 2729 -222 2722 -219 ct +2722 -219 2722 -219 2718 -229 ct 2718 -229 2718 -229 2794 -260 ct 2794 -260 2794 -260 2806 -260 ct +p ef +3095 -77 m 3095 -77 3095 -77 3092 0 ct 3092 0 3092 0 2869 0 ct 2869 0 2869 0 2869 -10 ct +2869 -10 2869 -10 3038 -234 ct 3038 -234 3038 -234 2953 -234 ct 2935 -234 2924 -233 2918 -231 ct +2913 -228 2908 -224 2905 -217 ct 2900 -208 2897 -197 2896 -183 ct 2896 -183 2896 -183 2886 -183 ct +2886 -183 2886 -183 2887 -253 ct 2887 -253 2887 -253 3099 -253 ct 3099 -253 3099 -253 3099 -243 ct +3099 -243 3099 -243 2930 -18 ct 2930 -18 2930 -18 3022 -18 ct 3041 -18 3054 -20 3061 -23 ct +3068 -26 3073 -32 3078 -40 ct 3081 -46 3083 -58 3085 -77 ct 3085 -77 3085 -77 3095 -77 ct +p ef +3268 -37 m 3242 -17 3226 -5 3219 -2 ct 3209 3 3199 5 3187 5 ct 3170 5 3155 -1 3144 -13 ct +3133 -25 3127 -40 3127 -60 ct 3127 -72 3130 -83 3135 -92 ct 3143 -104 3156 -116 3175 -127 ct +3193 -138 3225 -151 3268 -167 ct 3268 -167 3268 -167 3268 -177 ct 3268 -202 3264 -219 3256 -228 ct +3248 -237 3237 -242 3221 -242 ct 3210 -242 3201 -239 3194 -233 ct 3187 -226 3183 -219 3183 -211 ct +3183 -211 3183 -211 3184 -195 ct 3184 -187 3182 -180 3177 -176 ct 3173 -171 3167 -169 3160 -169 ct +3154 -169 3148 -171 3144 -176 ct 3139 -181 3137 -188 3137 -196 ct 3137 -212 3145 -227 3161 -240 ct +3177 -253 3200 -260 3229 -260 ct 3251 -260 3270 -256 3284 -249 ct 3295 -243 3303 -234 3308 -222 ct +3311 -214 3313 -198 3313 -174 ct 3313 -174 3313 -174 3313 -89 ct 3313 -65 3313 -50 3314 -45 ct +3315 -39 3317 -36 3319 -34 ct 3321 -32 3323 -31 3326 -31 ct 3329 -31 3332 -32 3334 -33 ct +3338 -35 3345 -42 3356 -53 ct 3356 -53 3356 -53 3356 -38 ct 3336 -10 3316 4 3298 4 ct +3289 4 3281 1 3276 -5 ct 3271 -11 3268 -22 3268 -37 ct p +3268 -54 m 3268 -54 3268 -54 3268 -149 ct 3240 -138 3222 -130 3214 -126 ct +3199 -118 3189 -110 3182 -101 ct 3176 -92 3173 -83 3173 -72 ct 3173 -59 3177 -49 3185 -40 ct +3193 -31 3202 -27 3212 -27 ct 3227 -27 3245 -36 3268 -54 ct p ef +3448 -337 m 3448 -337 3448 -337 3448 -253 ct 3448 -253 3448 -253 3507 -253 ct +3507 -253 3507 -253 3507 -234 ct 3507 -234 3507 -234 3448 -234 ct 3448 -234 3448 -234 3448 -70 ct +3448 -53 3450 -42 3455 -37 ct 3460 -31 3466 -28 3473 -28 ct 3479 -28 3485 -30 3491 -34 ct +3496 -37 3501 -43 3504 -50 ct 3504 -50 3504 -50 3515 -50 ct 3509 -32 3499 -19 3488 -10 ct +3476 -1 3463 4 3451 4 ct 3442 4 3434 2 3426 -3 ct 3418 -8 3412 -14 3408 -23 ct +3404 -32 3402 -45 3402 -64 ct 3402 -64 3402 -64 3402 -234 ct 3402 -234 3402 -234 3362 -234 ct +3362 -234 3362 -234 3362 -243 ct 3372 -247 3382 -254 3393 -264 ct 3404 -273 3413 -285 3421 -298 ct +3426 -305 3431 -318 3439 -337 ct 3439 -337 3439 -337 3448 -337 ct p ef +3596 -392 m 3604 -392 3610 -389 3616 -384 ct 3621 -378 3624 -372 3624 -364 ct +3624 -356 3621 -350 3616 -344 ct 3610 -339 3604 -336 3596 -336 ct 3588 -336 3582 -339 3576 -344 ct +3571 -350 3568 -356 3568 -364 ct 3568 -372 3571 -378 3576 -384 ct 3582 -389 3588 -392 3596 -392 ct +p +3619 -260 m 3619 -260 3619 -260 3619 -57 ct 3619 -41 3620 -31 3622 -26 ct 3625 -20 3628 -16 3632 -14 ct +3637 -11 3644 -10 3656 -10 ct 3656 -10 3656 -10 3656 0 ct 3656 0 3656 0 3536 0 ct +3536 0 3536 0 3536 -10 ct 3548 -10 3556 -11 3560 -14 ct 3564 -16 3567 -20 3569 -25 ct +3572 -31 3573 -41 3573 -57 ct 3573 -57 3573 -57 3573 -154 ct 3573 -181 3572 -199 3571 -207 ct +3569 -213 3567 -217 3565 -220 ct 3562 -222 3558 -223 3553 -223 ct 3548 -223 3542 -222 3535 -219 ct +3535 -219 3535 -219 3531 -229 ct 3531 -229 3531 -229 3607 -260 ct 3607 -260 3607 -260 3619 -260 ct +p ef +3812 -260 m 3850 -260 3881 -246 3904 -217 ct 3923 -192 3933 -163 3933 -131 ct +3933 -109 3928 -86 3917 -63 ct 3906 -40 3891 -22 3872 -11 ct 3853 1 3832 7 3809 7 ct +3771 7 3741 -8 3718 -38 ct 3699 -64 3690 -92 3690 -124 ct 3690 -147 3696 -170 3707 -193 ct +3719 -216 3734 -233 3752 -244 ct 3771 -255 3791 -260 3812 -260 ct p +3803 -242 m 3794 -242 3784 -239 3774 -233 ct 3764 -228 3756 -218 3750 -203 ct +3744 -189 3741 -170 3741 -147 ct 3741 -111 3748 -79 3763 -53 ct 3778 -26 3797 -13 3821 -13 ct +3838 -13 3853 -20 3865 -35 ct 3876 -50 3882 -75 3882 -110 ct 3882 -155 3872 -190 3853 -216 ct +3840 -233 3823 -242 3803 -242 ct p ef +4046 -207 m 4075 -242 4103 -260 4130 -260 ct 4144 -260 4156 -257 4165 -250 ct +4175 -243 4183 -231 4189 -216 ct 4193 -205 4195 -188 4195 -165 ct 4195 -165 4195 -165 4195 -57 ct +4195 -41 4196 -30 4199 -25 ct 4201 -20 4204 -16 4208 -14 ct 4212 -11 4220 -10 4232 -10 ct +4232 -10 4232 -10 4232 0 ct 4232 0 4232 0 4108 0 ct 4108 0 4108 0 4108 -10 ct 4108 -10 4108 -10 4113 -10 ct +4125 -10 4133 -12 4138 -15 ct 4143 -19 4146 -24 4148 -31 ct 4149 -34 4149 -43 4149 -57 ct +4149 -57 4149 -57 4149 -161 ct 4149 -184 4146 -201 4140 -211 ct 4134 -222 4124 -227 4110 -227 ct +4089 -227 4067 -215 4046 -191 ct 4046 -191 4046 -191 4046 -57 ct 4046 -40 4047 -29 4049 -25 ct +4052 -20 4055 -16 4060 -14 ct 4064 -11 4073 -10 4087 -10 ct 4087 -10 4087 -10 4087 0 ct +4087 0 4087 0 3963 0 ct 3963 0 3963 0 3963 -10 ct 3963 -10 3963 -10 3968 -10 ct +3981 -10 3989 -13 3993 -20 ct 3998 -26 4000 -39 4000 -57 ct 4000 -57 4000 -57 4000 -151 ct +4000 -181 3999 -200 3998 -206 ct 3997 -213 3995 -217 3992 -220 ct 3989 -222 3985 -223 3980 -223 ct +3975 -223 3969 -222 3962 -219 ct 3962 -219 3962 -219 3958 -229 ct 3958 -229 3958 -229 4034 -260 ct +4034 -260 4034 -260 4046 -260 ct 4046 -260 4046 -260 4046 -207 ct p ef +pom +gr +gr +14985 17255 m 13835 17255 l 13835 15955 l 16135 15955 l 16135 17255 l +14985 17255 l pc +gs +gs +pum +13971 16795 t +249 4 m 268 36 288 60 310 75 ct 332 90 356 99 384 101 ct 384 101 384 101 384 110 ct +359 109 332 104 303 95 ct 274 85 247 73 221 56 ct 195 40 173 22 154 4 ct 128 -7 107 -18 91 -30 ct +69 -48 52 -70 40 -96 ct 27 -122 21 -152 21 -188 ct 21 -243 39 -290 75 -327 ct 111 -364 155 -382 206 -382 ct +255 -382 297 -364 333 -327 ct 368 -290 386 -243 386 -187 ct 386 -141 373 -101 348 -66 ct +323 -32 290 -8 249 4 ct p +203 -361 m 170 -361 143 -349 122 -325 ct 97 -295 84 -249 84 -188 ct 84 -127 97 -81 123 -48 ct +143 -23 170 -10 203 -10 ct 237 -10 265 -23 286 -48 ct 311 -78 323 -121 323 -180 ct +323 -224 316 -262 303 -292 ct 292 -316 278 -333 261 -344 ct 244 -355 224 -361 203 -361 ct +p ef +645 -253 m 645 -253 645 -253 645 -99 ct 645 -70 646 -53 647 -47 ct 648 -40 651 -36 654 -33 ct +657 -31 660 -29 664 -29 ct 670 -29 676 -31 683 -34 ct 683 -34 683 -34 687 -24 ct +687 -24 687 -24 612 7 ct 612 7 612 7 600 7 ct 600 7 600 7 600 -46 ct 578 -23 562 -8 550 -2 ct +539 4 527 7 514 7 ct 500 7 487 3 477 -5 ct 466 -14 459 -24 455 -37 ct 451 -50 449 -68 449 -92 ct +449 -92 449 -92 449 -205 ct 449 -217 448 -225 445 -229 ct 443 -234 439 -237 434 -240 ct +429 -242 419 -243 406 -243 ct 406 -243 406 -243 406 -253 ct 406 -253 406 -253 495 -253 ct +495 -253 495 -253 495 -84 ct 495 -60 499 -44 507 -37 ct 516 -30 525 -26 537 -26 ct +545 -26 554 -28 564 -33 ct 574 -38 586 -48 600 -62 ct 600 -62 600 -62 600 -205 ct +600 -220 597 -230 592 -235 ct 587 -240 576 -243 559 -243 ct 559 -243 559 -243 559 -253 ct +559 -253 559 -253 645 -253 ct p ef +851 -37 m 825 -17 809 -5 802 -2 ct 792 3 782 5 770 5 ct 753 5 738 -1 727 -13 ct +716 -25 710 -40 710 -60 ct 710 -72 713 -83 718 -92 ct 726 -104 739 -116 758 -127 ct +776 -138 808 -151 851 -167 ct 851 -167 851 -167 851 -177 ct 851 -202 847 -219 839 -228 ct +831 -237 820 -242 804 -242 ct 793 -242 784 -239 777 -233 ct 770 -226 766 -219 766 -211 ct +766 -211 766 -211 767 -195 ct 767 -187 765 -180 760 -176 ct 756 -171 750 -169 743 -169 ct +737 -169 731 -171 727 -176 ct 722 -181 720 -188 720 -196 ct 720 -212 728 -227 744 -240 ct +760 -253 783 -260 812 -260 ct 834 -260 853 -256 867 -249 ct 878 -243 886 -234 891 -222 ct +894 -214 896 -198 896 -174 ct 896 -174 896 -174 896 -89 ct 896 -65 896 -50 897 -45 ct +898 -39 900 -36 902 -34 ct 904 -32 906 -31 909 -31 ct 912 -31 915 -32 917 -33 ct +921 -35 928 -42 939 -53 ct 939 -53 939 -53 939 -38 ct 919 -10 899 4 881 4 ct 872 4 864 1 859 -5 ct +854 -11 851 -22 851 -37 ct p +851 -54 m 851 -54 851 -54 851 -149 ct 823 -138 805 -130 797 -126 ct 782 -118 772 -110 765 -101 ct +759 -92 756 -83 756 -72 ct 756 -59 760 -49 768 -40 ct 776 -31 785 -27 795 -27 ct +810 -27 828 -36 851 -54 ct p ef +1032 -207 m 1061 -242 1089 -260 1116 -260 ct 1130 -260 1142 -257 1151 -250 ct +1161 -243 1169 -231 1175 -216 ct 1179 -205 1181 -188 1181 -165 ct 1181 -165 1181 -165 1181 -57 ct +1181 -41 1182 -30 1185 -25 ct 1187 -20 1190 -16 1194 -14 ct 1198 -11 1206 -10 1218 -10 ct +1218 -10 1218 -10 1218 0 ct 1218 0 1218 0 1094 0 ct 1094 0 1094 0 1094 -10 ct 1094 -10 1094 -10 1099 -10 ct +1111 -10 1119 -12 1124 -15 ct 1129 -19 1132 -24 1134 -31 ct 1135 -34 1135 -43 1135 -57 ct +1135 -57 1135 -57 1135 -161 ct 1135 -184 1132 -201 1126 -211 ct 1120 -222 1110 -227 1096 -227 ct +1075 -227 1053 -215 1032 -191 ct 1032 -191 1032 -191 1032 -57 ct 1032 -40 1033 -29 1035 -25 ct +1038 -20 1041 -16 1046 -14 ct 1050 -11 1059 -10 1073 -10 ct 1073 -10 1073 -10 1073 0 ct +1073 0 1073 0 949 0 ct 949 0 949 0 949 -10 ct 949 -10 949 -10 954 -10 ct 967 -10 975 -13 979 -20 ct +984 -26 986 -39 986 -57 ct 986 -57 986 -57 986 -151 ct 986 -181 985 -200 984 -206 ct +983 -213 981 -217 978 -220 ct 975 -222 971 -223 966 -223 ct 961 -223 955 -222 948 -219 ct +948 -219 948 -219 944 -229 ct 944 -229 944 -229 1020 -260 ct 1020 -260 1020 -260 1032 -260 ct +1032 -260 1032 -260 1032 -207 ct p ef +1314 -337 m 1314 -337 1314 -337 1314 -253 ct 1314 -253 1314 -253 1373 -253 ct +1373 -253 1373 -253 1373 -234 ct 1373 -234 1373 -234 1314 -234 ct 1314 -234 1314 -234 1314 -70 ct +1314 -53 1316 -42 1321 -37 ct 1326 -31 1332 -28 1339 -28 ct 1345 -28 1351 -30 1357 -34 ct +1362 -37 1367 -43 1370 -50 ct 1370 -50 1370 -50 1381 -50 ct 1375 -32 1365 -19 1354 -10 ct +1342 -1 1329 4 1317 4 ct 1308 4 1300 2 1292 -3 ct 1284 -8 1278 -14 1274 -23 ct +1270 -32 1268 -45 1268 -64 ct 1268 -64 1268 -64 1268 -234 ct 1268 -234 1268 -234 1228 -234 ct +1228 -234 1228 -234 1228 -243 ct 1238 -247 1248 -254 1259 -264 ct 1270 -273 1279 -285 1287 -298 ct +1292 -305 1297 -318 1305 -337 ct 1305 -337 1305 -337 1314 -337 ct p ef +1462 -392 m 1470 -392 1476 -389 1482 -384 ct 1487 -378 1490 -372 1490 -364 ct +1490 -356 1487 -350 1482 -344 ct 1476 -339 1470 -336 1462 -336 ct 1454 -336 1448 -339 1442 -344 ct +1437 -350 1434 -356 1434 -364 ct 1434 -372 1437 -378 1442 -384 ct 1448 -389 1454 -392 1462 -392 ct +p +1485 -260 m 1485 -260 1485 -260 1485 -57 ct 1485 -41 1486 -31 1488 -26 ct 1491 -20 1494 -16 1498 -14 ct +1503 -11 1510 -10 1522 -10 ct 1522 -10 1522 -10 1522 0 ct 1522 0 1522 0 1402 0 ct +1402 0 1402 0 1402 -10 ct 1414 -10 1422 -11 1426 -14 ct 1430 -16 1433 -20 1435 -25 ct +1438 -31 1439 -41 1439 -57 ct 1439 -57 1439 -57 1439 -154 ct 1439 -181 1438 -199 1437 -207 ct +1435 -213 1433 -217 1431 -220 ct 1428 -222 1424 -223 1419 -223 ct 1414 -223 1408 -222 1401 -219 ct +1401 -219 1401 -219 1397 -229 ct 1397 -229 1397 -229 1473 -260 ct 1473 -260 1473 -260 1485 -260 ct +p ef +1774 -77 m 1774 -77 1774 -77 1771 0 ct 1771 0 1771 0 1548 0 ct 1548 0 1548 0 1548 -10 ct +1548 -10 1548 -10 1717 -234 ct 1717 -234 1717 -234 1632 -234 ct 1614 -234 1603 -233 1597 -231 ct +1592 -228 1587 -224 1584 -217 ct 1579 -208 1576 -197 1575 -183 ct 1575 -183 1575 -183 1565 -183 ct +1565 -183 1565 -183 1566 -253 ct 1566 -253 1566 -253 1778 -253 ct 1778 -253 1778 -253 1778 -243 ct +1778 -243 1778 -243 1609 -18 ct 1609 -18 1609 -18 1701 -18 ct 1720 -18 1733 -20 1740 -23 ct +1747 -26 1752 -32 1757 -40 ct 1760 -46 1762 -58 1764 -77 ct 1764 -77 1764 -77 1774 -77 ct +p ef +1846 -158 m 1846 -121 1855 -92 1873 -71 ct 1891 -50 1912 -39 1937 -39 ct 1953 -39 1968 -43 1980 -52 ct +1992 -61 2002 -77 2010 -99 ct 2010 -99 2010 -99 2019 -94 ct 2015 -68 2004 -45 1985 -24 ct +1967 -3 1944 7 1916 7 ct 1886 7 1860 -5 1838 -28 ct 1817 -52 1806 -83 1806 -123 ct +1806 -166 1817 -200 1839 -224 ct 1861 -248 1889 -260 1922 -260 ct 1950 -260 1974 -251 1992 -232 ct +2010 -214 2019 -189 2019 -158 ct 2019 -158 2019 -158 1846 -158 ct p +1846 -174 m 1846 -174 1846 -174 1962 -174 ct 1961 -190 1959 -201 1956 -208 ct +1952 -218 1945 -226 1936 -231 ct 1927 -237 1917 -240 1908 -240 ct 1892 -240 1879 -234 1867 -223 ct +1855 -211 1848 -195 1846 -174 ct p ef +pom +gr +gr +gs +16136 15641 m 17407 15641 l 17407 16436 l 16136 16436 l 16136 15641 l eoclip newpath +gs +tm setmatrix +13705 12594 t +1 1 s +gs +gs +0 0 m 1272 0 l 1272 795 l 0 795 l 0 0 l eoclip newpath +gs +pum +212 556 t +208 -345 m 197 -344 l 113 -410 l 25 -342 l 11 -345 l 113 -462 l 208 -345 l +p ef +pom +gr +gs +pum +159 556 t +331 -261 m 331 -261 331 -261 322 -229 ct 322 -229 322 -229 270 -229 ct 274 -218 276 -207 276 -198 ct +276 -170 264 -146 241 -124 ct 217 -103 185 -91 144 -89 ct 122 -82 106 -75 95 -65 ct +91 -62 89 -59 89 -55 ct 89 -51 91 -47 95 -44 ct 98 -40 108 -37 123 -33 ct 123 -33 123 -33 183 -20 ct +216 -12 238 -3 248 8 ct 259 19 264 31 264 46 ct 264 63 258 78 245 92 ct 233 106 215 117 190 125 ct +166 133 140 137 111 137 ct 85 137 62 134 41 128 ct 20 122 5 114 -4 103 ct -13 93 -18 82 -18 71 ct +-18 63 -15 53 -9 44 ct -3 34 4 26 13 20 ct 19 16 35 7 61 -8 ct 52 -15 47 -23 47 -32 ct +47 -40 51 -49 59 -58 ct 67 -68 85 -78 111 -89 ct 89 -93 71 -103 58 -118 ct 45 -132 39 -149 39 -167 ct +39 -196 52 -222 78 -245 ct 104 -268 138 -280 181 -280 ct 196 -280 209 -278 219 -275 ct +229 -272 239 -268 248 -261 ct 248 -261 248 -261 331 -261 ct p +225 -211 m 225 -228 220 -240 211 -250 ct 201 -259 189 -264 173 -264 ct 149 -264 129 -252 114 -229 ct +98 -206 90 -182 90 -157 ct 90 -141 95 -128 105 -118 ct 115 -108 127 -103 142 -103 ct +153 -103 164 -106 174 -112 ct 185 -118 194 -126 201 -136 ct 209 -147 214 -160 219 -176 ct +223 -192 225 -204 225 -211 ct p +74 0 m 57 8 45 18 36 30 ct 27 42 23 53 23 65 ct 23 79 29 90 42 99 ct 59 112 85 118 120 118 ct +149 118 175 113 196 103 ct 217 93 227 80 227 64 ct 227 56 223 48 215 41 ct 208 34 193 28 170 24 ct +158 21 126 13 74 0 ct p ef +pom +gr +gs +pum +529 714 t +134 -168 m 134 -168 134 -168 124 -111 ct 124 -111 124 -111 117 -111 ct 116 -128 113 -140 107 -148 ct +101 -155 93 -159 84 -159 ct 77 -159 71 -157 66 -153 ct 62 -148 60 -143 60 -137 ct +60 -133 61 -129 63 -126 ct 64 -122 68 -117 74 -110 ct 89 -93 99 -79 103 -70 ct +108 -62 110 -53 110 -45 ct 110 -32 105 -21 94 -11 ct 84 -1 71 4 55 4 ct 46 4 36 2 24 -3 ct +20 -4 17 -5 15 -5 ct 10 -5 6 -2 3 4 ct 3 4 3 4 -4 4 ct -4 4 -4 4 6 -56 ct 6 -56 6 -56 13 -56 ct +14 -37 18 -24 25 -17 ct 32 -9 41 -5 53 -5 ct 63 -5 70 -8 76 -13 ct 81 -18 84 -25 84 -32 ct +84 -37 83 -42 81 -46 ct 78 -53 71 -63 60 -76 ct 49 -89 42 -99 39 -106 ct 36 -112 34 -119 34 -125 ct +34 -137 38 -147 47 -156 ct 55 -164 66 -168 80 -168 ct 83 -168 87 -168 90 -167 ct +92 -167 96 -165 102 -163 ct 108 -160 112 -159 114 -159 ct 119 -159 124 -162 127 -168 ct +127 -168 127 -168 134 -168 ct p ef +331 -164 m 331 -164 331 -164 297 -52 ct 292 -35 289 -24 289 -20 ct 289 -18 290 -16 290 -15 ct +291 -14 292 -14 293 -14 ct 294 -14 296 -15 298 -17 ct 300 -18 306 -26 314 -39 ct +314 -39 314 -39 319 -35 ct 311 -20 302 -9 293 -2 ct 287 2 281 4 276 4 ct 271 4 268 3 266 0 ct +263 -3 262 -6 262 -10 ct 262 -15 263 -20 264 -27 ct 267 -35 273 -55 282 -86 ct +260 -51 242 -28 227 -15 ct 212 -2 198 4 186 4 ct 180 4 175 2 171 -2 ct 167 -6 165 -11 165 -17 ct +165 -26 169 -40 175 -59 ct 175 -59 175 -59 194 -117 ct 199 -130 202 -139 202 -142 ct +202 -144 201 -145 200 -146 ct 198 -147 197 -148 196 -148 ct 192 -148 189 -147 186 -145 ct +183 -143 176 -136 165 -124 ct 165 -124 165 -124 159 -128 ct 169 -143 180 -153 191 -160 ct +200 -165 208 -168 215 -168 ct 220 -168 224 -166 227 -163 ct 230 -160 232 -155 232 -150 ct +232 -143 229 -131 223 -114 ct 223 -114 223 -114 203 -55 ct 197 -39 194 -29 194 -24 ct +194 -22 195 -20 197 -19 ct 199 -17 201 -16 203 -16 ct 208 -16 213 -18 220 -23 ct +227 -27 236 -36 247 -50 ct 259 -64 268 -77 275 -90 ct 282 -102 290 -122 299 -149 ct +299 -149 299 -149 304 -164 ct 304 -164 304 -164 331 -164 ct p ef +453 -265 m 453 -265 453 -265 415 -136 ct 427 -148 437 -157 445 -161 ct 454 -166 463 -168 472 -168 ct +485 -168 496 -164 504 -154 ct 513 -145 517 -133 517 -118 ct 517 -98 511 -78 500 -59 ct +489 -39 475 -23 459 -12 ct 442 -2 425 4 409 4 ct 391 4 372 -3 353 -17 ct 353 -17 353 -17 409 -213 ct +414 -228 416 -236 416 -239 ct 416 -242 415 -244 413 -246 ct 410 -248 406 -249 400 -249 ct +397 -249 393 -249 387 -248 ct 387 -248 387 -248 387 -255 ct 387 -255 387 -255 453 -265 ct +p +380 -15 m 392 -8 403 -5 412 -5 ct 422 -5 433 -9 444 -17 ct 456 -25 465 -38 474 -57 ct +482 -76 486 -95 486 -114 ct 486 -125 483 -134 478 -140 ct 473 -147 466 -150 459 -150 ct +448 -150 437 -145 427 -136 ct 417 -127 409 -114 404 -97 ct 404 -97 404 -97 380 -15 ct +p ef +648 -164 m 648 -164 648 -164 645 -150 ct 645 -150 645 -150 617 -150 ct 617 -150 617 -150 594 -69 ct +584 -34 574 -6 565 13 ct 552 41 538 60 523 70 ct 511 78 500 82 488 82 ct 481 82 474 80 469 75 ct +465 72 463 68 463 63 ct 463 59 465 55 468 52 ct 471 49 475 48 479 48 ct 483 48 485 49 488 51 ct +490 53 491 56 491 58 ct 491 61 490 64 488 66 ct 486 68 485 69 485 70 ct 485 71 485 72 486 73 ct +487 74 489 74 491 74 ct 497 74 502 72 508 69 ct 514 66 519 61 524 54 ct 528 48 532 38 537 26 ct +538 21 543 4 551 -25 ct 551 -25 551 -25 588 -150 ct 588 -150 588 -150 551 -150 ct +551 -150 551 -150 554 -164 ct 565 -164 573 -165 578 -166 ct 582 -168 586 -170 590 -174 ct +594 -178 599 -186 604 -197 ct 611 -212 618 -224 624 -232 ct 633 -243 642 -251 652 -257 ct +661 -262 671 -265 679 -265 ct 688 -265 695 -263 701 -258 ct 706 -253 709 -248 709 -242 ct +709 -238 708 -234 705 -231 ct 702 -228 698 -227 694 -227 ct 690 -227 687 -228 685 -230 ct +682 -233 681 -235 681 -238 ct 681 -240 682 -243 684 -245 ct 686 -248 687 -250 687 -251 ct +687 -253 686 -254 685 -255 ct 684 -256 682 -257 679 -257 ct 672 -257 665 -254 659 -249 ct +651 -242 644 -232 638 -217 ct 635 -210 629 -192 621 -164 ct 621 -164 621 -164 648 -164 ct +p ef +pom +gr +gr +gr +gr +gr +17535 16605 m 16973 16793 l 16973 16418 l 17535 16605 l p ef +16135 16580 m 17085 16580 l 17085 16630 l 16135 16630 l 16135 16580 l +p ef +tm setmatrix +0 0 t +1 1 s +0 22011 t +pom +count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore +%%PageTrailer +%%Trailer +%%EOF diff --git a/src/libs/speexdsp/doc/speex_abs.odg b/src/libs/speexdsp/doc/speex_abs.odg new file mode 100644 index 00000000..a43291bf Binary files /dev/null and b/src/libs/speexdsp/doc/speex_abs.odg differ diff --git a/src/libs/speexdsp/doc/speex_analysis.eps b/src/libs/speexdsp/doc/speex_analysis.eps new file mode 100644 index 00000000..5f34fc2d --- /dev/null +++ b/src/libs/speexdsp/doc/speex_analysis.eps @@ -0,0 +1,744 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 465 180 +%%Pages: 0 +%%Creator: Sun Microsystems, Inc. +%%Title: none +%%CreationDate: none +%%LanguageLevel: 2 +%%EndComments +%%BeginProlog +%%BeginResource: SDRes +/b4_inc_state save def +/dict_count countdictstack def +/op_count count 1 sub def +userdict begin +0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit[] 0 setdash newpath +/languagelevel where {pop languagelevel 1 ne {false setstrokeadjust false setoverprint} if} if +/bdef {bind def} bind def +/c {setgray} bdef +/l {neg lineto} bdef +/rl {neg rlineto} bdef +/lc {setlinecap} bdef +/lj {setlinejoin} bdef +/lw {setlinewidth} bdef +/ml {setmiterlimit} bdef +/ld {setdash} bdef +/m {neg moveto} bdef +/ct {6 2 roll neg 6 2 roll neg 6 2 roll neg curveto} bdef +/r {rotate} bdef +/t {neg translate} bdef +/s {scale} bdef +/sw {show} bdef +/gs {gsave} bdef +/gr {grestore} bdef +/f {findfont dup length dict begin +{1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def +currentdict end /NFont exch definefont pop /NFont findfont} bdef +/p {closepath} bdef +/sf {scalefont setfont} bdef +/ef {eofill}bdef +/pc {closepath stroke}bdef +/ps {stroke}bdef +/pum {matrix currentmatrix}bdef +/pom {setmatrix}bdef +/bs {/aString exch def /nXOfs exch def /nWidth exch def currentpoint nXOfs 0 rmoveto pum nWidth aString stringwidth pop div 1 scale aString show pom moveto} bdef +%%EndResource +%%EndProlog +%%BeginSetup +%%EndSetup +%%Page: 1 1 +%%BeginPageSetup +%%EndPageSetup +pum +0.02832 0.02831 s +0 -6358 t +/tm matrix currentmatrix def +tm setmatrix +-700 -3000 t +1 1 s +50 lw 1 lj 0.000 c 3900 7000 m 3100 7000 l 3100 5500 l 4700 5500 l 4700 7000 l +3900 7000 l pc +gs +gs +pum +3293 6460 t +47 0 m 47 -455 l 107 -455 l 107 -54 l 330 -54 l 330 0 l 47 0 l p ef +400 0 m 400 0 400 0 400 -455 ct 400 -455 400 -455 571 -455 ct 602 -455 625 -454 641 -451 ct +663 -447 682 -440 697 -429 ct 712 -419 724 -404 733 -385 ct 742 -367 747 -346 747 -323 ct +747 -285 735 -252 710 -225 ct 685 -198 641 -185 577 -185 ct 577 -185 577 -185 460 -185 ct +460 -185 460 -185 460 0 ct 460 0 460 0 400 0 ct p +460 -239 m 460 -239 460 -239 578 -239 ct 617 -239 644 -246 660 -261 ct 677 -275 685 -295 685 -322 ct +685 -341 680 -357 671 -370 ct 661 -384 648 -393 633 -397 ct 622 -400 604 -401 576 -401 ct +576 -401 576 -401 460 -401 ct 460 -401 460 -401 460 -239 ct p ef +1149 -159 m 1149 -159 1149 -159 1209 -144 ct 1196 -95 1174 -57 1141 -31 ct +1108 -5 1068 8 1021 8 ct 972 8 932 -2 901 -22 ct 870 -42 847 -71 831 -109 ct 815 -147 807 -187 807 -231 ct +807 -278 816 -320 834 -355 ct 852 -390 878 -417 911 -436 ct 945 -454 981 -463 1022 -463 ct +1067 -463 1105 -451 1136 -428 ct 1167 -405 1189 -373 1201 -331 ct 1201 -331 1201 -331 1142 -317 ct +1131 -350 1116 -374 1096 -389 ct 1076 -404 1051 -412 1020 -412 ct 985 -412 956 -404 933 -387 ct +909 -370 893 -347 883 -319 ct 874 -291 869 -261 869 -231 ct 869 -192 875 -158 886 -129 ct +897 -101 915 -79 939 -65 ct 962 -50 988 -43 1016 -43 ct 1050 -43 1078 -53 1102 -72 ct +1125 -92 1141 -121 1149 -159 ct p ef +pom +gr +gr +gs +gs +pum +1170 3636 t +181 -260 m 181 -260 181 -260 181 -174 ct 181 -174 181 -174 171 -174 ct 164 -201 155 -220 145 -229 ct +134 -239 120 -244 103 -244 ct 91 -244 80 -241 73 -234 ct 65 -227 61 -219 61 -211 ct +61 -201 64 -192 70 -185 ct 75 -177 87 -169 104 -161 ct 104 -161 104 -161 144 -141 ct +181 -123 200 -99 200 -69 ct 200 -47 191 -28 174 -14 ct 157 0 138 7 116 7 ct 101 7 83 4 64 -1 ct +58 -2 53 -3 49 -3 ct 45 -3 41 -1 39 3 ct 39 3 39 3 29 3 ct 29 3 29 3 29 -87 ct 29 -87 29 -87 39 -87 ct +44 -61 54 -42 68 -29 ct 83 -16 99 -9 116 -9 ct 129 -9 139 -13 147 -20 ct 155 -28 159 -37 159 -47 ct +159 -60 155 -70 146 -79 ct 137 -88 119 -98 93 -111 ct 66 -124 48 -136 40 -147 ct +32 -157 28 -171 28 -187 ct 28 -208 35 -225 49 -239 ct 63 -253 82 -260 104 -260 ct +114 -260 126 -258 140 -254 ct 149 -251 155 -250 158 -250 ct 161 -250 164 -251 165 -252 ct +167 -253 169 -256 171 -260 ct 171 -260 171 -260 181 -260 ct p ef +220 -228 m 220 -228 220 -228 298 -259 ct 298 -259 298 -259 309 -259 ct 309 -259 309 -259 309 -201 ct +322 -223 335 -238 348 -247 ct 361 -256 375 -260 389 -260 ct 414 -260 435 -250 452 -230 ct +473 -206 483 -175 483 -136 ct 483 -92 471 -56 446 -28 ct 425 -5 400 7 369 7 ct +355 7 343 5 334 1 ct 326 -2 318 -7 309 -16 ct 309 -16 309 -16 309 63 ct 309 80 310 91 312 96 ct +314 100 318 104 323 107 ct 329 110 338 111 352 111 ct 352 111 352 111 352 121 ct +352 121 352 121 217 121 ct 217 121 217 121 217 111 ct 217 111 217 111 224 111 ct +234 111 243 109 251 105 ct 254 103 257 100 259 95 ct 261 91 262 79 262 61 ct 262 61 262 61 262 -179 ct +262 -195 261 -205 260 -209 ct 258 -213 256 -216 253 -219 ct 250 -221 245 -222 240 -222 ct +236 -222 230 -221 223 -218 ct 223 -218 223 -218 220 -228 ct p +309 -185 m 309 -185 309 -185 309 -90 ct 309 -70 310 -57 311 -50 ct 314 -40 320 -30 330 -22 ct +340 -14 353 -10 368 -10 ct 386 -10 401 -17 412 -31 ct 427 -50 434 -77 434 -111 ct +434 -149 426 -179 409 -200 ct 397 -214 383 -221 367 -221 ct 359 -221 350 -219 341 -214 ct +335 -211 324 -201 309 -185 ct p ef +564 -158 m 564 -121 573 -92 591 -71 ct 609 -50 630 -39 655 -39 ct 671 -39 686 -43 698 -52 ct +710 -61 720 -77 728 -99 ct 728 -99 728 -99 737 -94 ct 733 -68 722 -45 703 -24 ct +685 -3 662 7 634 7 ct 604 7 578 -5 556 -28 ct 535 -52 524 -83 524 -123 ct 524 -166 535 -200 557 -224 ct +579 -248 607 -260 640 -260 ct 668 -260 692 -251 710 -232 ct 728 -214 737 -189 737 -158 ct +737 -158 737 -158 564 -158 ct p +564 -174 m 564 -174 564 -174 680 -174 ct 679 -190 677 -201 674 -208 ct 670 -218 663 -226 654 -231 ct +645 -237 635 -240 626 -240 ct 610 -240 597 -234 585 -223 ct 573 -211 566 -195 564 -174 ct +p ef +814 -158 m 814 -121 823 -92 841 -71 ct 859 -50 880 -39 905 -39 ct 921 -39 936 -43 948 -52 ct +960 -61 970 -77 978 -99 ct 978 -99 978 -99 987 -94 ct 983 -68 972 -45 953 -24 ct +935 -3 912 7 884 7 ct 854 7 828 -5 806 -28 ct 785 -52 774 -83 774 -123 ct 774 -166 785 -200 807 -224 ct +829 -248 857 -260 890 -260 ct 918 -260 942 -251 960 -232 ct 978 -214 987 -189 987 -158 ct +987 -158 987 -158 814 -158 ct p +814 -174 m 814 -174 814 -174 930 -174 ct 929 -190 927 -201 924 -208 ct 920 -218 913 -226 904 -231 ct +895 -237 885 -240 876 -240 ct 860 -240 847 -234 835 -223 ct 823 -211 816 -195 814 -174 ct +p ef +1236 -95 m 1229 -62 1216 -37 1196 -19 ct 1176 -2 1154 7 1130 7 ct 1101 7 1076 -5 1055 -29 ct +1034 -53 1023 -85 1023 -126 ct 1023 -166 1035 -198 1058 -223 ct 1082 -248 1111 -260 1144 -260 ct +1169 -260 1189 -253 1205 -240 ct 1221 -227 1229 -214 1229 -199 ct 1229 -192 1227 -187 1222 -182 ct +1218 -178 1211 -176 1203 -176 ct 1193 -176 1185 -180 1179 -187 ct 1176 -190 1174 -198 1173 -209 ct +1172 -220 1168 -228 1161 -234 ct 1155 -239 1146 -242 1135 -242 ct 1116 -242 1102 -235 1090 -222 ct +1075 -204 1068 -180 1068 -150 ct 1068 -120 1075 -94 1090 -71 ct 1105 -48 1125 -36 1150 -36 ct +1168 -36 1184 -42 1199 -54 ct 1209 -62 1218 -77 1228 -99 ct 1228 -99 1228 -99 1236 -95 ct +p ef +1345 -392 m 1345 -392 1345 -392 1345 -208 ct 1365 -230 1381 -244 1393 -251 ct +1405 -257 1417 -260 1429 -260 ct 1443 -260 1456 -256 1466 -248 ct 1476 -240 1484 -228 1489 -211 ct +1492 -199 1494 -178 1494 -146 ct 1494 -146 1494 -146 1494 -57 ct 1494 -41 1495 -30 1498 -24 ct +1500 -20 1503 -16 1507 -14 ct 1511 -11 1519 -10 1531 -10 ct 1531 -10 1531 -10 1531 0 ct +1531 0 1531 0 1407 0 ct 1407 0 1407 0 1407 -10 ct 1407 -10 1407 -10 1413 -10 ct +1425 -10 1433 -12 1437 -15 ct 1442 -19 1445 -24 1447 -31 ct 1448 -34 1448 -43 1448 -57 ct +1448 -57 1448 -57 1448 -147 ct 1448 -174 1447 -192 1444 -201 ct 1441 -210 1436 -216 1430 -221 ct +1424 -225 1417 -227 1408 -227 ct 1399 -227 1389 -225 1380 -220 ct 1370 -215 1359 -205 1345 -191 ct +1345 -191 1345 -191 1345 -57 ct 1345 -40 1346 -29 1348 -25 ct 1350 -21 1353 -17 1359 -14 ct +1364 -11 1373 -10 1386 -10 ct 1386 -10 1386 -10 1386 0 ct 1386 0 1386 0 1262 0 ct +1262 0 1262 0 1262 -10 ct 1273 -10 1281 -12 1287 -15 ct 1291 -17 1294 -21 1296 -26 ct +1298 -31 1299 -41 1299 -57 ct 1299 -57 1299 -57 1299 -286 ct 1299 -314 1298 -332 1297 -338 ct +1296 -345 1294 -349 1291 -352 ct 1288 -354 1284 -355 1279 -355 ct 1276 -355 1269 -354 1261 -351 ct +1261 -351 1261 -351 1257 -361 ct 1257 -361 1257 -361 1332 -392 ct 1332 -392 1332 -392 1345 -392 ct +p ef +pom +gr +gs +pum +1286 4263 t +117 -233 m 117 -233 117 -233 117 -67 ct 117 -43 120 -28 125 -22 ct 132 -14 141 -10 152 -10 ct +152 -10 152 -10 175 -10 ct 175 -10 175 -10 175 0 ct 175 0 175 0 24 0 ct 24 0 24 0 24 -10 ct +24 -10 24 -10 35 -10 ct 43 -10 49 -12 55 -16 ct 61 -19 65 -24 68 -30 ct 70 -37 71 -49 71 -67 ct +71 -67 71 -67 71 -233 ct 71 -233 71 -233 22 -233 ct 22 -233 22 -233 22 -253 ct +22 -253 22 -253 71 -253 ct 71 -253 71 -253 71 -270 ct 71 -295 75 -316 83 -334 ct +91 -351 104 -365 120 -376 ct 137 -387 156 -392 177 -392 ct 196 -392 214 -386 230 -373 ct +241 -365 246 -355 246 -345 ct 246 -340 244 -334 239 -329 ct 234 -324 229 -322 223 -322 ct +219 -322 215 -324 210 -327 ct 205 -330 200 -336 193 -346 ct 186 -356 180 -363 174 -367 ct +168 -370 162 -372 155 -372 ct 147 -372 139 -370 134 -365 ct 128 -361 123 -354 121 -344 ct +118 -335 117 -310 117 -271 ct 117 -271 117 -271 117 -253 ct 117 -253 117 -253 182 -253 ct +182 -253 182 -253 182 -233 ct 182 -233 182 -233 117 -233 ct p ef +283 -260 m 283 -260 283 -260 283 -203 ct 304 -241 326 -260 348 -260 ct 358 -260 366 -257 373 -251 ct +380 -245 383 -238 383 -230 ct 383 -222 381 -216 376 -211 ct 371 -206 365 -204 359 -204 ct +352 -204 345 -207 337 -214 ct 329 -220 323 -223 319 -223 ct 316 -223 312 -221 309 -217 ct +300 -210 292 -198 283 -180 ct 283 -180 283 -180 283 -59 ct 283 -45 285 -34 288 -27 ct +291 -22 295 -18 301 -15 ct 307 -12 316 -10 328 -10 ct 328 -10 328 -10 328 0 ct +328 0 328 0 196 0 ct 196 0 196 0 196 -10 ct 209 -10 219 -12 226 -16 ct 230 -19 234 -24 236 -30 ct +237 -33 237 -42 237 -57 ct 237 -57 237 -57 237 -154 ct 237 -184 236 -201 235 -207 ct +234 -213 232 -217 229 -219 ct 226 -222 222 -223 217 -223 ct 211 -223 205 -222 198 -219 ct +198 -219 198 -219 195 -229 ct 195 -229 195 -229 271 -260 ct 271 -260 271 -260 283 -260 ct +p ef +538 -37 m 512 -17 496 -5 489 -2 ct 479 3 469 5 457 5 ct 440 5 425 -1 414 -13 ct +403 -25 397 -40 397 -60 ct 397 -72 400 -83 405 -92 ct 413 -104 426 -116 445 -127 ct +463 -138 495 -151 538 -167 ct 538 -167 538 -167 538 -177 ct 538 -202 534 -219 526 -228 ct +518 -237 507 -242 491 -242 ct 480 -242 471 -239 464 -233 ct 457 -226 453 -219 453 -211 ct +453 -211 453 -211 454 -195 ct 454 -187 452 -180 447 -176 ct 443 -171 437 -169 430 -169 ct +424 -169 418 -171 414 -176 ct 409 -181 407 -188 407 -196 ct 407 -212 415 -227 431 -240 ct +447 -253 470 -260 499 -260 ct 521 -260 540 -256 554 -249 ct 565 -243 573 -234 578 -222 ct +581 -214 583 -198 583 -174 ct 583 -174 583 -174 583 -89 ct 583 -65 583 -50 584 -45 ct +585 -39 587 -36 589 -34 ct 591 -32 593 -31 596 -31 ct 599 -31 602 -32 604 -33 ct +608 -35 615 -42 626 -53 ct 626 -53 626 -53 626 -38 ct 606 -10 586 4 568 4 ct 559 4 551 1 546 -5 ct +541 -11 538 -22 538 -37 ct p +538 -54 m 538 -54 538 -54 538 -149 ct 510 -138 492 -130 484 -126 ct 469 -118 459 -110 452 -101 ct +446 -92 443 -83 443 -72 ct 443 -59 447 -49 455 -40 ct 463 -31 472 -27 482 -27 ct +497 -27 515 -36 538 -54 ct p ef +720 -206 m 738 -225 749 -235 752 -238 ct 761 -245 769 -250 779 -254 ct 789 -258 798 -260 807 -260 ct +823 -260 837 -255 848 -246 ct 859 -237 867 -224 871 -206 ct 890 -228 906 -243 919 -250 ct +932 -257 945 -260 959 -260 ct 972 -260 984 -257 994 -250 ct 1005 -243 1013 -232 1019 -216 ct +1023 -205 1025 -188 1025 -166 ct 1025 -166 1025 -166 1025 -57 ct 1025 -41 1026 -30 1028 -25 ct +1030 -21 1034 -17 1038 -14 ct 1043 -11 1051 -10 1062 -10 ct 1062 -10 1062 -10 1062 0 ct +1062 0 1062 0 938 0 ct 938 0 938 0 938 -10 ct 938 -10 938 -10 943 -10 ct 954 -10 963 -12 969 -16 ct +973 -19 976 -24 978 -30 ct 979 -33 979 -42 979 -57 ct 979 -57 979 -57 979 -166 ct +979 -186 977 -201 972 -209 ct 964 -221 953 -227 937 -227 ct 928 -227 918 -225 908 -220 ct +898 -215 886 -206 873 -193 ct 873 -193 873 -193 872 -189 ct 872 -189 872 -189 873 -178 ct +873 -178 873 -178 873 -57 ct 873 -40 874 -29 876 -25 ct 878 -21 881 -17 887 -14 ct +892 -11 901 -10 914 -10 ct 914 -10 914 -10 914 0 ct 914 0 914 0 786 0 ct 786 0 786 0 786 -10 ct +800 -10 810 -12 815 -15 ct 820 -18 824 -23 826 -30 ct 827 -33 827 -42 827 -57 ct +827 -57 827 -57 827 -166 ct 827 -186 824 -201 818 -210 ct 810 -221 799 -227 784 -227 ct +774 -227 765 -224 755 -219 ct 740 -211 728 -202 720 -193 ct 720 -193 720 -193 720 -57 ct +720 -41 721 -30 723 -25 ct 726 -20 729 -16 734 -14 ct 738 -11 747 -10 761 -10 ct +761 -10 761 -10 761 0 ct 761 0 761 0 637 0 ct 637 0 637 0 637 -10 ct 648 -10 656 -11 660 -14 ct +665 -16 668 -20 671 -26 ct 673 -31 674 -41 674 -57 ct 674 -57 674 -57 674 -154 ct +674 -182 673 -199 672 -207 ct 670 -213 668 -217 666 -220 ct 663 -222 659 -223 654 -223 ct +649 -223 643 -222 636 -219 ct 636 -219 636 -219 632 -229 ct 632 -229 632 -229 708 -260 ct +708 -260 708 -260 720 -260 ct 720 -260 720 -260 720 -206 ct p ef +1114 -158 m 1114 -121 1123 -92 1141 -71 ct 1159 -50 1180 -39 1205 -39 ct 1221 -39 1236 -43 1248 -52 ct +1260 -61 1270 -77 1278 -99 ct 1278 -99 1278 -99 1287 -94 ct 1283 -68 1272 -45 1253 -24 ct +1235 -3 1212 7 1184 7 ct 1154 7 1128 -5 1106 -28 ct 1085 -52 1074 -83 1074 -123 ct +1074 -166 1085 -200 1107 -224 ct 1129 -248 1157 -260 1190 -260 ct 1218 -260 1242 -251 1260 -232 ct +1278 -214 1287 -189 1287 -158 ct 1287 -158 1287 -158 1114 -158 ct p +1114 -174 m 1114 -174 1114 -174 1230 -174 ct 1229 -190 1227 -201 1224 -208 ct +1220 -218 1213 -226 1204 -231 ct 1195 -237 1185 -240 1176 -240 ct 1160 -240 1147 -234 1135 -223 ct +1123 -211 1116 -195 1114 -174 ct p ef +pom +gr +gr +3100 6250 m 2538 6438 l 2538 6063 l 3100 6250 l p ef +1975 4500 m 1975 6250 l 1950 6250 l 1925 6250 l 1925 4500 l 1950 4500 l +1975 4500 l p ef +1950 6250 m 1950 6275 l 1946 6275 l 1941 6273 l 1938 6272 l 1934 6269 l +1931 6266 l 1928 6263 l 1927 6259 l 1925 6254 l 1925 6250 l 1925 6250 l +1950 6250 l p ef +1950 6225 m 2650 6225 l 2650 6250 l 2650 6275 l 1950 6275 l 1950 6250 l +1950 6225 l p ef +gs +4635 7681 m 6248 7681 l 6248 9206 l 4635 9206 l 4635 7681 l eoclip newpath +gs +tm setmatrix +3942 4683 t +1 1 s +gs +gs +0 0 m 1613 0 l 1613 1525 l 0 1525 l 0 0 l eoclip newpath +gs +pum +661 556 t +74 -379 m 74 -379 74 -379 176 -429 ct 176 -429 176 -429 186 -429 ct 186 -429 186 -429 186 -74 ct +186 -50 187 -36 189 -30 ct 191 -24 195 -19 201 -16 ct 207 -13 220 -11 239 -11 ct +239 -11 239 -11 239 0 ct 239 0 239 0 82 0 ct 82 0 82 0 82 -11 ct 101 -11 114 -13 120 -16 ct +125 -19 129 -23 132 -28 ct 134 -33 135 -49 135 -74 ct 135 -74 135 -74 135 -301 ct +135 -331 134 -351 132 -359 ct 130 -366 128 -371 124 -374 ct 120 -377 116 -379 110 -379 ct +103 -379 92 -375 79 -369 ct 79 -369 79 -369 74 -379 ct p ef +pom +gr +gs +132 741 m 1350 0 rl 0 31 rl 1350 neg 0 rl ef p ef + +gr +gs +pum +238 1376 t +328 -430 m 328 -430 328 -430 296 -80 ct 294 -64 294 -53 294 -48 ct 294 -40 295 -33 298 -29 ct +302 -23 307 -18 314 -15 ct 321 -12 332 -11 348 -11 ct 348 -11 348 -11 345 0 ct +345 0 345 0 180 0 ct 180 0 180 0 184 -11 ct 184 -11 184 -11 191 -11 ct 204 -11 215 -14 224 -20 ct +230 -24 234 -30 238 -39 ct 240 -46 242 -61 244 -85 ct 244 -85 244 -85 249 -138 ct +249 -138 249 -138 128 -138 ct 128 -138 128 -138 86 -80 ct 76 -67 70 -57 67 -52 ct +65 -46 64 -41 64 -36 ct 64 -29 66 -24 72 -19 ct 77 -14 86 -11 98 -11 ct 98 -11 98 -11 95 0 ct +95 0 95 0 -30 0 ct -30 0 -30 0 -27 -11 ct -12 -12 2 -17 14 -26 ct 25 -36 43 -57 66 -88 ct +66 -88 66 -88 317 -430 ct 317 -430 317 -430 328 -430 ct p +268 -327 m 144 -159 l 251 -159 l 268 -327 l p ef +pom +gr +gs +pum +661 1376 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +953 1376 t +54 -273 m 54 -273 54 -273 249 -273 ct 249 -273 249 -273 249 -265 ct 249 -265 249 -265 35 -42 ct +35 -42 35 -42 125 -42 ct 147 -42 161 -43 166 -44 ct 172 -46 178 -50 183 -55 ct +187 -60 193 -70 199 -84 ct 199 -84 199 -84 210 -84 ct 210 -84 210 -84 183 0 ct +183 0 183 0 -18 0 ct -18 0 -18 0 -18 -9 ct -18 -9 -18 -9 196 -232 ct 196 -232 196 -232 109 -232 ct +90 -232 78 -232 74 -231 ct 68 -229 63 -226 57 -221 ct 51 -216 45 -208 39 -196 ct +39 -196 39 -196 28 -196 ct 28 -196 28 -196 54 -273 ct p ef +pom +gr +gs +pum +1270 1376 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gr +gr +gr +gr +5400 9300 m 4400 9300 l 4400 7500 l 6400 7500 l 6400 9300 l 5400 9300 l +pc +7700 7000 m 6800 7000 l 6800 5500 l 8600 5500 l 8600 7000 l 7700 7000 l +pc +gs +gs +pum +7102 6460 t +47 0 m 47 -455 l 107 -455 l 107 -54 l 330 -54 l 330 0 l 47 0 l p ef +380 -146 m 380 -146 380 -146 437 -151 ct 440 -128 446 -110 456 -95 ct 465 -80 481 -69 501 -60 ct +522 -51 545 -46 571 -46 ct 593 -46 614 -49 631 -56 ct 649 -63 662 -72 670 -84 ct +679 -96 683 -109 683 -123 ct 683 -138 679 -150 670 -161 ct 662 -171 648 -180 629 -187 ct +617 -192 590 -200 549 -210 ct 507 -220 478 -229 461 -238 ct 440 -249 424 -264 413 -280 ct +402 -297 397 -316 397 -337 ct 397 -360 404 -382 416 -402 ct 429 -422 448 -437 473 -447 ct +498 -458 526 -463 557 -463 ct 590 -463 620 -458 646 -447 ct 671 -436 691 -420 705 -399 ct +719 -378 726 -354 727 -327 ct 727 -327 727 -327 669 -323 ct 666 -351 656 -373 638 -387 ct +620 -402 594 -409 559 -409 ct 523 -409 496 -402 480 -389 ct 463 -376 455 -360 455 -341 ct +455 -324 461 -311 473 -300 ct 484 -290 514 -279 563 -268 ct 611 -257 645 -247 663 -239 ct +690 -227 709 -211 722 -193 ct 735 -174 741 -153 741 -128 ct 741 -104 734 -81 720 -60 ct +706 -38 687 -22 661 -10 ct 635 2 606 8 573 8 ct 532 8 498 2 470 -10 ct 442 -22 421 -40 405 -64 ct +389 -88 381 -116 380 -146 ct p ef +824 0 m 824 0 824 0 824 -455 ct 824 -455 824 -455 995 -455 ct 1026 -455 1049 -454 1065 -451 ct +1087 -447 1106 -440 1121 -429 ct 1136 -419 1148 -404 1157 -385 ct 1166 -367 1171 -346 1171 -323 ct +1171 -285 1159 -252 1134 -225 ct 1109 -198 1065 -185 1001 -185 ct 1001 -185 1001 -185 884 -185 ct +884 -185 884 -185 884 0 ct 884 0 884 0 824 0 ct p +884 -239 m 884 -239 884 -239 1002 -239 ct 1041 -239 1068 -246 1084 -261 ct +1101 -275 1109 -295 1109 -322 ct 1109 -341 1104 -357 1095 -370 ct 1085 -384 1072 -393 1057 -397 ct +1046 -400 1028 -401 1000 -401 ct 1000 -401 1000 -401 884 -401 ct 884 -401 884 -401 884 -239 ct +p ef +pom +gr +gr +6800 6250 m 6238 6438 l 6238 6063 l 6800 6250 l p ef +4700 6225 m 6350 6225 l 6350 6275 l 4700 6275 l 4700 6225 l p ef +4400 8400 m 3988 8538 l 3988 8263 l 4400 8400 l p ef +4070 8425 m 1950 8425 l 1950 8400 l 1950 8375 l 4070 8375 l 4070 8400 l +4070 8425 l p ef +1950 8400 m 1950 8425 l 1946 8425 l 1941 8423 l 1938 8422 l 1934 8419 l +1931 8416 l 1928 8413 l 1927 8409 l 1925 8404 l 1925 8400 l 1925 8400 l +1950 8400 l p ef +1925 8400 m 1925 4500 l 1950 4500 l 1975 4500 l 1975 8400 l 1950 8400 l +1925 8400 l p ef +1950 4500 m 1950 4500 l 1950 4500 l 1950 4500 l 1950 4500 l 1950 4500 l +1950 4500 l p ef +5400 7500 m 5213 6938 l 5588 6938 l 5400 7500 l p ef +4700 6225 m 5400 6225 l 5400 6250 l 5400 6275 l 4700 6275 l 4700 6250 l +4700 6225 l p ef +5400 6250 m 5400 6225 l 5404 6225 l 5409 6227 l 5412 6228 l 5416 6231 l +5419 6234 l 5422 6237 l 5423 6241 l 5425 6246 l 5425 6250 l 5425 6250 l +5400 6250 l p ef +5425 6250 m 5425 7050 l 5400 7050 l 5375 7050 l 5375 6250 l 5400 6250 l +5425 6250 l p ef +10600 7000 m 9700 7000 l 9700 5500 l 11500 5500 l 11500 7000 l 10600 7000 l +pc +gs +gs +pum +10153 6460 t +178 0 m 178 0 178 0 2 -455 ct 2 -455 2 -455 67 -455 ct 67 -455 67 -455 186 -124 ct +195 -98 203 -73 210 -50 ct 217 -74 225 -99 234 -124 ct 234 -124 234 -124 357 -455 ct +357 -455 357 -455 419 -455 ct 419 -455 419 -455 241 0 ct 241 0 241 0 178 0 ct p ef +817 -48 m 845 -29 870 -15 894 -6 ct 894 -6 894 -6 876 36 ct 843 24 811 5 778 -21 ct +745 -2 707 8 667 8 ct 625 8 588 -2 555 -22 ct 521 -42 495 -70 477 -106 ct 459 -142 450 -182 450 -227 ct +450 -272 459 -313 477 -350 ct 496 -387 521 -415 555 -434 ct 589 -453 626 -463 668 -463 ct +710 -463 748 -453 781 -433 ct 815 -413 841 -385 858 -349 ct 876 -313 885 -273 885 -227 ct +885 -190 879 -156 868 -126 ct 857 -96 839 -70 817 -48 ct p +684 -125 m 719 -115 747 -101 770 -82 ct 805 -114 823 -162 823 -227 ct 823 -264 817 -296 804 -324 ct +792 -352 773 -373 749 -388 ct 725 -403 698 -411 668 -411 ct 623 -411 586 -396 556 -365 ct +527 -334 512 -288 512 -227 ct 512 -168 527 -122 556 -91 ct 585 -59 623 -43 668 -43 ct +690 -43 710 -47 729 -55 ct 710 -67 690 -76 669 -81 ct 669 -81 669 -81 684 -125 ct +p ef +pom +gr +gr +9700 6250 m 9138 6438 l 9138 6063 l 9700 6250 l p ef +8600 6225 m 9250 6225 l 9250 6275 l 8600 6275 l 8600 6225 l p ef +gs +8135 7931 m 9830 7931 l 9830 8806 l 8135 8806 l 8135 7931 l eoclip newpath +gs +tm setmatrix +7435 4921 t +1 1 s +gs +gs +0 0 m 1695 0 l 1695 875 l 0 875 l 0 0 l eoclip newpath +gs +pum +106 741 t +650 93 m 650 93 650 93 56 93 ct 56 93 56 93 56 76 ct 56 76 56 76 359 -301 ct 359 -301 359 -301 56 -670 ct +56 -670 56 -670 56 -687 ct 56 -687 56 -687 634 -687 ct 634 -687 634 -687 646 -534 ct +646 -534 646 -534 627 -534 ct 620 -611 582 -650 516 -650 ct 516 -650 516 -650 181 -650 ct +181 -650 181 -650 435 -339 ct 435 -339 435 -339 150 13 ct 150 13 150 13 520 13 ct +595 13 642 -24 661 -98 ct 661 -98 661 -98 679 -96 ct 679 -96 679 -96 650 93 ct +p ef +pom +gr +gs +pum +953 661 t +168 131 m 127 98 96 50 75 -12 ct 56 -66 47 -123 47 -183 ct 47 -241 56 -298 75 -354 ct +98 -419 128 -467 168 -497 ct 168 -497 168 -497 168 -481 ct 139 -454 116 -408 101 -342 ct +89 -290 83 -237 83 -183 ct 83 -129 89 -76 101 -24 ct 116 43 139 89 168 116 ct 168 116 168 116 168 131 ct +p ef +pom +gr +gs +pum +1217 661 t +33 116 m 61 90 82 46 97 -18 ct 110 -70 117 -120 117 -170 ct 117 -229 111 -284 100 -335 ct +86 -404 63 -453 33 -481 ct 33 -481 33 -481 33 -497 ct 72 -468 103 -421 125 -354 ct +143 -299 153 -241 153 -183 ct 153 -123 144 -66 125 -11 ct 103 54 72 102 33 131 ct +33 131 33 131 33 116 ct p ef +pom +gr +gs +pum +1402 344 t +175 -48 m 175 -48 175 -48 157 0 ct 157 0 157 0 8 0 ct 8 0 8 0 8 -7 ct 52 -47 83 -79 101 -105 ct +119 -130 128 -153 128 -174 ct 128 -190 123 -204 113 -214 ct 103 -225 91 -230 78 -230 ct +65 -230 54 -226 44 -219 ct 34 -212 27 -202 22 -188 ct 22 -188 22 -188 15 -188 ct +18 -211 26 -228 39 -240 ct 52 -252 68 -258 88 -258 ct 108 -258 125 -251 139 -238 ct +153 -225 160 -209 160 -191 ct 160 -179 157 -166 151 -153 ct 142 -133 127 -112 106 -89 ct +75 -55 55 -35 48 -28 ct 48 -28 48 -28 114 -28 ct 127 -28 137 -29 142 -29 ct 147 -30 152 -32 157 -36 ct +161 -39 165 -43 168 -48 ct 168 -48 168 -48 175 -48 ct p ef +pom +gr +gr +gr +gr +gr +8950 9100 m 7900 9100 l 7900 7700 l 10000 7700 l 10000 9100 l 8950 9100 l +pc +7900 8400 m 7338 8588 l 7338 8213 l 7900 8400 l p ef +6400 8375 m 7450 8375 l 7450 8425 l 6400 8425 l 6400 8375 l p ef +13350 9100 m 12300 9100 l 12300 7700 l 14400 7700 l 14400 9100 l 13350 9100 l +pc +gs +gs +pum +12395 8584 t +242 -260 m 242 -260 242 -260 242 64 ct 242 81 243 91 245 96 ct 248 101 251 104 256 107 ct +260 110 269 111 283 111 ct 283 111 283 111 283 121 ct 283 121 283 121 156 121 ct +156 121 156 121 156 111 ct 156 111 156 111 161 111 ct 172 111 179 109 185 106 ct +189 104 191 101 194 95 ct 196 90 197 79 197 64 ct 197 64 197 64 197 -45 ct 180 -25 166 -11 153 -4 ct +141 3 128 7 114 7 ct 90 7 68 -4 49 -26 ct 30 -48 20 -78 20 -115 ct 20 -158 33 -193 58 -220 ct +83 -247 114 -260 149 -260 ct 160 -260 170 -259 178 -256 ct 187 -253 195 -248 202 -243 ct +213 -248 223 -253 233 -260 ct 233 -260 233 -260 242 -260 ct p +197 -62 m 197 -62 197 -62 197 -180 ct 197 -194 195 -205 192 -213 ct 188 -221 182 -227 172 -233 ct +163 -238 153 -241 141 -241 ct 121 -241 103 -232 88 -215 ct 73 -197 66 -171 66 -136 ct +66 -102 74 -76 89 -58 ct 104 -41 122 -32 143 -32 ct 154 -32 163 -34 172 -39 ct +181 -44 189 -51 197 -62 ct p ef +523 -253 m 523 -253 523 -253 523 -99 ct 523 -70 524 -53 525 -47 ct 526 -40 529 -36 532 -33 ct +535 -31 538 -29 542 -29 ct 548 -29 554 -31 561 -34 ct 561 -34 561 -34 565 -24 ct +565 -24 565 -24 490 7 ct 490 7 490 7 478 7 ct 478 7 478 7 478 -46 ct 456 -23 440 -8 428 -2 ct +417 4 405 7 392 7 ct 378 7 365 3 355 -5 ct 344 -14 337 -24 333 -37 ct 329 -50 327 -68 327 -92 ct +327 -92 327 -92 327 -205 ct 327 -217 326 -225 323 -229 ct 321 -234 317 -237 312 -240 ct +307 -242 297 -243 284 -243 ct 284 -243 284 -243 284 -253 ct 284 -253 284 -253 373 -253 ct +373 -253 373 -253 373 -84 ct 373 -60 377 -44 385 -37 ct 394 -30 403 -26 415 -26 ct +423 -26 432 -28 442 -33 ct 452 -38 464 -48 478 -62 ct 478 -62 478 -62 478 -205 ct +478 -220 475 -230 470 -235 ct 465 -240 454 -243 437 -243 ct 437 -243 437 -243 437 -253 ct +437 -253 437 -253 523 -253 ct p ef +728 -37 m 702 -17 686 -5 679 -2 ct 669 3 659 5 647 5 ct 630 5 615 -1 604 -13 ct +593 -25 587 -40 587 -60 ct 587 -72 590 -83 595 -92 ct 603 -104 616 -116 635 -127 ct +653 -138 685 -151 728 -167 ct 728 -167 728 -167 728 -177 ct 728 -202 724 -219 716 -228 ct +708 -237 697 -242 681 -242 ct 670 -242 661 -239 654 -233 ct 647 -226 643 -219 643 -211 ct +643 -211 643 -211 644 -195 ct 644 -187 642 -180 637 -176 ct 633 -171 627 -169 620 -169 ct +614 -169 608 -171 604 -176 ct 599 -181 597 -188 597 -196 ct 597 -212 605 -227 621 -240 ct +637 -253 660 -260 689 -260 ct 711 -260 730 -256 744 -249 ct 755 -243 763 -234 768 -222 ct +771 -214 773 -198 773 -174 ct 773 -174 773 -174 773 -89 ct 773 -65 773 -50 774 -45 ct +775 -39 777 -36 779 -34 ct 781 -32 783 -31 786 -31 ct 789 -31 792 -32 794 -33 ct +798 -35 805 -42 816 -53 ct 816 -53 816 -53 816 -38 ct 796 -10 776 4 758 4 ct 749 4 741 1 736 -5 ct +731 -11 728 -22 728 -37 ct p +728 -54 m 728 -54 728 -54 728 -149 ct 700 -138 682 -130 674 -126 ct 659 -118 649 -110 642 -101 ct +636 -92 633 -83 633 -72 ct 633 -59 637 -49 645 -40 ct 653 -31 662 -27 672 -27 ct +687 -27 705 -36 728 -54 ct p ef +909 -207 m 938 -242 966 -260 993 -260 ct 1007 -260 1019 -257 1028 -250 ct 1038 -243 1046 -231 1052 -216 ct +1056 -205 1058 -188 1058 -165 ct 1058 -165 1058 -165 1058 -57 ct 1058 -41 1059 -30 1062 -25 ct +1064 -20 1067 -16 1071 -14 ct 1075 -11 1083 -10 1095 -10 ct 1095 -10 1095 -10 1095 0 ct +1095 0 1095 0 971 0 ct 971 0 971 0 971 -10 ct 971 -10 971 -10 976 -10 ct 988 -10 996 -12 1001 -15 ct +1006 -19 1009 -24 1011 -31 ct 1012 -34 1012 -43 1012 -57 ct 1012 -57 1012 -57 1012 -161 ct +1012 -184 1009 -201 1003 -211 ct 997 -222 987 -227 973 -227 ct 952 -227 930 -215 909 -191 ct +909 -191 909 -191 909 -57 ct 909 -40 910 -29 912 -25 ct 915 -20 918 -16 923 -14 ct +927 -11 936 -10 950 -10 ct 950 -10 950 -10 950 0 ct 950 0 950 0 826 0 ct 826 0 826 0 826 -10 ct +826 -10 826 -10 831 -10 ct 844 -10 852 -13 856 -20 ct 861 -26 863 -39 863 -57 ct +863 -57 863 -57 863 -151 ct 863 -181 862 -200 861 -206 ct 860 -213 858 -217 855 -220 ct +852 -222 848 -223 843 -223 ct 838 -223 832 -222 825 -219 ct 825 -219 825 -219 821 -229 ct +821 -229 821 -229 897 -260 ct 897 -260 897 -260 909 -260 ct 909 -260 909 -260 909 -207 ct +p ef +1192 -337 m 1192 -337 1192 -337 1192 -253 ct 1192 -253 1192 -253 1251 -253 ct +1251 -253 1251 -253 1251 -234 ct 1251 -234 1251 -234 1192 -234 ct 1192 -234 1192 -234 1192 -70 ct +1192 -53 1194 -42 1199 -37 ct 1204 -31 1210 -28 1217 -28 ct 1223 -28 1229 -30 1235 -34 ct +1240 -37 1245 -43 1248 -50 ct 1248 -50 1248 -50 1259 -50 ct 1253 -32 1243 -19 1232 -10 ct +1220 -1 1207 4 1195 4 ct 1186 4 1178 2 1170 -3 ct 1162 -8 1156 -14 1152 -23 ct +1148 -32 1146 -45 1146 -64 ct 1146 -64 1146 -64 1146 -234 ct 1146 -234 1146 -234 1106 -234 ct +1106 -234 1106 -234 1106 -243 ct 1116 -247 1126 -254 1137 -264 ct 1148 -273 1157 -285 1165 -298 ct +1170 -305 1175 -318 1183 -337 ct 1183 -337 1183 -337 1192 -337 ct p ef +1339 -392 m 1347 -392 1353 -389 1359 -384 ct 1364 -378 1367 -372 1367 -364 ct +1367 -356 1364 -350 1359 -344 ct 1353 -339 1347 -336 1339 -336 ct 1331 -336 1325 -339 1319 -344 ct +1314 -350 1311 -356 1311 -364 ct 1311 -372 1314 -378 1319 -384 ct 1325 -389 1331 -392 1339 -392 ct +p +1362 -260 m 1362 -260 1362 -260 1362 -57 ct 1362 -41 1363 -31 1365 -26 ct 1368 -20 1371 -16 1375 -14 ct +1380 -11 1387 -10 1399 -10 ct 1399 -10 1399 -10 1399 0 ct 1399 0 1399 0 1279 0 ct +1279 0 1279 0 1279 -10 ct 1291 -10 1299 -11 1303 -14 ct 1307 -16 1310 -20 1312 -25 ct +1315 -31 1316 -41 1316 -57 ct 1316 -57 1316 -57 1316 -154 ct 1316 -181 1315 -199 1314 -207 ct +1312 -213 1310 -217 1308 -220 ct 1305 -222 1301 -223 1296 -223 ct 1291 -223 1285 -222 1278 -219 ct +1278 -219 1278 -219 1274 -229 ct 1274 -229 1274 -229 1350 -260 ct 1350 -260 1350 -260 1362 -260 ct +p ef +1651 -77 m 1651 -77 1651 -77 1648 0 ct 1648 0 1648 0 1425 0 ct 1425 0 1425 0 1425 -10 ct +1425 -10 1425 -10 1594 -234 ct 1594 -234 1594 -234 1509 -234 ct 1491 -234 1480 -233 1474 -231 ct +1469 -228 1464 -224 1461 -217 ct 1456 -208 1453 -197 1452 -183 ct 1452 -183 1452 -183 1442 -183 ct +1442 -183 1442 -183 1443 -253 ct 1443 -253 1443 -253 1655 -253 ct 1655 -253 1655 -253 1655 -243 ct +1655 -243 1655 -243 1486 -18 ct 1486 -18 1486 -18 1578 -18 ct 1597 -18 1610 -20 1617 -23 ct +1624 -26 1629 -32 1634 -40 ct 1637 -46 1639 -58 1641 -77 ct 1641 -77 1641 -77 1651 -77 ct +p ef +1724 -158 m 1724 -121 1733 -92 1751 -71 ct 1769 -50 1790 -39 1815 -39 ct 1831 -39 1846 -43 1858 -52 ct +1870 -61 1880 -77 1888 -99 ct 1888 -99 1888 -99 1897 -94 ct 1893 -68 1882 -45 1863 -24 ct +1845 -3 1822 7 1794 7 ct 1764 7 1738 -5 1716 -28 ct 1695 -52 1684 -83 1684 -123 ct +1684 -166 1695 -200 1717 -224 ct 1739 -248 1767 -260 1800 -260 ct 1828 -260 1852 -251 1870 -232 ct +1888 -214 1897 -189 1897 -158 ct 1897 -158 1897 -158 1724 -158 ct p +1724 -174 m 1724 -174 1724 -174 1840 -174 ct 1839 -190 1837 -201 1834 -208 ct +1830 -218 1823 -226 1814 -231 ct 1805 -237 1795 -240 1786 -240 ct 1770 -240 1757 -234 1745 -223 ct +1733 -211 1726 -195 1724 -174 ct p ef +pom +gr +gr +12300 8400 m 11738 8588 l 11738 8213 l 12300 8400 l p ef +10000 8375 m 11850 8375 l 11850 8425 l 10000 8425 l 10000 8375 l p ef +gs +10100 7500 m 11689 7500 l 11689 8295 l 10100 8295 l 10100 7500 l eoclip newpath +gs +tm setmatrix +9393 4498 t +1 1 s +gs +gs +0 0 m 1589 0 l 1589 795 l 0 795 l 0 0 l eoclip newpath +gs +pum +159 556 t +331 -261 m 331 -261 331 -261 322 -229 ct 322 -229 322 -229 270 -229 ct 274 -218 276 -207 276 -198 ct +276 -170 264 -146 241 -124 ct 217 -103 185 -91 144 -89 ct 122 -82 106 -75 95 -65 ct +91 -62 89 -59 89 -55 ct 89 -51 91 -47 95 -44 ct 98 -40 108 -37 123 -33 ct 123 -33 123 -33 183 -20 ct +216 -12 238 -3 248 8 ct 259 19 264 31 264 46 ct 264 63 258 78 245 92 ct 233 106 215 117 190 125 ct +166 133 140 137 111 137 ct 85 137 62 134 41 128 ct 20 122 5 114 -4 103 ct -13 93 -18 82 -18 71 ct +-18 63 -15 53 -9 44 ct -3 34 4 26 13 20 ct 19 16 35 7 61 -8 ct 52 -15 47 -23 47 -32 ct +47 -40 51 -49 59 -58 ct 67 -68 85 -78 111 -89 ct 89 -93 71 -103 58 -118 ct 45 -132 39 -149 39 -167 ct +39 -196 52 -222 78 -245 ct 104 -268 138 -280 181 -280 ct 196 -280 209 -278 219 -275 ct +229 -272 239 -268 248 -261 ct 248 -261 248 -261 331 -261 ct p +225 -211 m 225 -228 220 -240 211 -250 ct 201 -259 189 -264 173 -264 ct 149 -264 129 -252 114 -229 ct +98 -206 90 -182 90 -157 ct 90 -141 95 -128 105 -118 ct 115 -108 127 -103 142 -103 ct +153 -103 164 -106 174 -112 ct 185 -118 194 -126 201 -136 ct 209 -147 214 -160 219 -176 ct +223 -192 225 -204 225 -211 ct p +74 0 m 57 8 45 18 36 30 ct 27 42 23 53 23 65 ct 23 79 29 90 42 99 ct 59 112 85 118 120 118 ct +149 118 175 113 196 103 ct 217 93 227 80 227 64 ct 227 56 223 48 215 41 ct 208 34 193 28 170 24 ct +158 21 126 13 74 0 ct p ef +pom +gr +gs +pum +609 714 t +119 -164 m 119 -164 119 -164 116 -150 ct 116 -150 116 -150 88 -150 ct 88 -150 88 -150 65 -69 ct +55 -34 45 -6 36 13 ct 23 41 9 60 -6 70 ct -18 78 -29 82 -41 82 ct -49 82 -55 80 -60 75 ct +-64 72 -66 68 -66 63 ct -66 59 -64 55 -61 52 ct -58 49 -54 48 -50 48 ct -46 48 -44 49 -41 51 ct +-39 53 -38 56 -38 58 ct -38 61 -39 64 -41 66 ct -43 68 -44 69 -44 70 ct -44 71 -44 72 -43 73 ct +-42 74 -40 74 -38 74 ct -32 74 -27 72 -21 69 ct -15 66 -10 61 -5 54 ct -1 48 3 38 8 26 ct +9 21 14 4 22 -25 ct 22 -25 22 -25 59 -150 ct 59 -150 59 -150 22 -150 ct 22 -150 22 -150 25 -164 ct +36 -164 44 -165 49 -166 ct 53 -168 57 -170 61 -174 ct 65 -178 70 -186 75 -197 ct +82 -212 89 -224 95 -232 ct 104 -243 113 -251 123 -257 ct 132 -262 142 -265 150 -265 ct +159 -265 166 -263 172 -258 ct 177 -253 180 -248 180 -242 ct 180 -238 179 -234 176 -231 ct +173 -228 169 -227 165 -227 ct 161 -227 158 -228 156 -230 ct 153 -233 152 -235 152 -238 ct +152 -240 153 -243 155 -245 ct 157 -248 158 -250 158 -251 ct 158 -253 157 -254 156 -255 ct +155 -256 153 -257 150 -257 ct 143 -257 136 -254 130 -249 ct 122 -242 115 -232 109 -217 ct +106 -210 100 -192 92 -164 ct 92 -164 92 -164 119 -164 ct p ef +125 -158 m 125 -158 125 -158 189 -168 ct 189 -168 189 -168 163 -78 ct 185 -115 204 -141 222 -155 ct +232 -164 240 -168 247 -168 ct 251 -168 254 -167 256 -164 ct 259 -162 260 -158 260 -154 ct +260 -146 258 -138 254 -130 ct 251 -125 247 -122 241 -122 ct 238 -122 236 -123 234 -125 ct +232 -127 230 -130 230 -134 ct 230 -136 229 -138 228 -138 ct 227 -139 226 -140 225 -140 ct +223 -140 221 -140 219 -139 ct 216 -137 211 -132 204 -124 ct 194 -112 183 -96 171 -77 ct +166 -68 161 -59 158 -49 ct 153 -35 150 -26 149 -23 ct 149 -23 149 -23 142 0 ct +142 0 142 0 114 0 ct 114 0 114 0 147 -116 ct 151 -129 153 -139 153 -144 ct 153 -146 153 -148 151 -150 ct +148 -152 145 -153 141 -153 ct 139 -153 134 -152 128 -151 ct 128 -151 128 -151 125 -158 ct +p ef +443 -166 m 443 -166 443 -166 406 -40 ct 406 -40 406 -40 402 -23 ct 402 -21 401 -20 401 -19 ct +401 -17 402 -15 403 -14 ct 403 -13 404 -13 405 -13 ct 406 -13 408 -13 409 -15 ct +413 -18 417 -26 423 -37 ct 423 -37 423 -37 429 -33 ct 422 -20 415 -11 407 -5 ct +399 1 392 4 386 4 ct 382 4 378 3 376 0 ct 373 -3 372 -6 372 -11 ct 372 -17 373 -25 376 -35 ct +376 -35 376 -35 380 -50 ct 362 -29 346 -14 331 -5 ct 320 1 309 4 299 4 ct 289 4 280 0 273 -7 ct +266 -14 262 -25 262 -38 ct 262 -57 268 -77 281 -99 ct 294 -120 311 -138 331 -151 ct +346 -161 361 -166 374 -166 ct 383 -166 390 -164 395 -160 ct 401 -157 405 -151 408 -142 ct +408 -142 408 -142 413 -162 ct 413 -162 413 -162 443 -166 ct p +373 -157 m 365 -157 356 -153 346 -146 ct 332 -136 320 -120 309 -100 ct 298 -80 293 -61 293 -45 ct +293 -37 295 -30 300 -25 ct 305 -20 310 -18 317 -18 ct 332 -18 349 -28 367 -47 ct +389 -73 399 -100 398 -128 ct 398 -138 396 -145 392 -150 ct 387 -155 381 -157 373 -157 ct +p ef +528 -168 m 528 -168 528 -168 504 -84 ct 515 -104 524 -119 532 -129 ct 544 -144 555 -155 567 -162 ct +573 -166 580 -168 588 -168 ct 594 -168 599 -166 603 -162 ct 607 -158 609 -153 609 -147 ct +609 -141 608 -133 605 -123 ct 605 -123 605 -123 591 -76 ct 612 -114 632 -140 652 -155 ct +662 -164 673 -168 683 -168 ct 689 -168 694 -166 698 -162 ct 702 -158 704 -151 704 -143 ct +704 -135 703 -128 700 -120 ct 700 -120 700 -120 677 -48 ct 672 -33 669 -24 669 -22 ct +669 -21 670 -19 671 -18 ct 672 -17 673 -17 674 -17 ct 675 -17 677 -18 680 -20 ct +686 -25 692 -33 698 -42 ct 698 -42 698 -42 704 -38 ct 701 -33 696 -26 688 -18 ct +681 -9 674 -3 669 0 ct 663 3 658 4 654 4 ct 650 4 646 3 643 0 ct 641 -3 639 -7 639 -11 ct +639 -17 642 -29 648 -47 ct 648 -47 648 -47 668 -106 ct 672 -120 674 -128 675 -129 ct +675 -132 675 -134 675 -136 ct 675 -139 675 -142 673 -143 ct 671 -145 670 -146 668 -146 ct +662 -146 656 -143 650 -138 ct 631 -122 613 -100 597 -72 ct 586 -53 576 -29 567 0 ct +567 0 567 0 540 0 ct 540 0 540 0 574 -112 ct 578 -124 580 -132 580 -136 ct 580 -140 579 -142 577 -144 ct +576 -145 574 -146 572 -146 ct 568 -146 564 -145 559 -142 ct 551 -137 542 -126 530 -111 ct +518 -95 508 -80 502 -65 ct 499 -59 491 -37 479 0 ct 479 0 479 0 452 0 ct 452 0 452 0 487 -120 ct +487 -120 487 -120 491 -136 ct 492 -138 493 -140 493 -141 ct 493 -144 491 -146 489 -148 ct +486 -150 483 -151 479 -151 ct 478 -151 473 -150 466 -149 ct 466 -149 466 -149 464 -156 ct +464 -156 464 -156 528 -168 ct p ef +763 -70 m 762 -64 762 -59 762 -55 ct 762 -44 766 -35 774 -27 ct 782 -20 792 -16 803 -16 ct +812 -16 821 -18 830 -21 ct 838 -25 851 -33 867 -45 ct 867 -45 867 -45 871 -40 ct +841 -11 813 4 786 4 ct 768 4 754 -2 745 -13 ct 736 -24 731 -37 731 -51 ct 731 -69 737 -88 748 -107 ct +760 -126 774 -141 792 -152 ct 809 -163 827 -168 845 -168 ct 858 -168 868 -165 874 -160 ct +881 -155 884 -148 884 -141 ct 884 -131 880 -121 871 -112 ct 860 -99 844 -89 823 -82 ct +809 -77 789 -73 763 -70 ct p +764 -79 m 783 -81 799 -85 811 -90 ct 826 -97 838 -105 846 -114 ct 854 -124 858 -133 858 -141 ct +858 -147 856 -151 853 -154 ct 850 -157 845 -159 838 -159 ct 825 -159 811 -152 797 -139 ct +782 -125 771 -105 764 -79 ct p ef +pom +gr +gr +gr +gr +gr +gs +14601 7501 m 16190 7501 l 16190 8296 l 14601 8296 l 14601 7501 l eoclip newpath +gs +tm setmatrix +13891 4498 t +1 1 s +gs +gs +0 0 m 1590 0 l 1590 795 l 0 795 l 0 0 l eoclip newpath +gs +pum +212 556 t +208 -345 m 197 -344 l 113 -410 l 25 -342 l 11 -345 l 113 -462 l 208 -345 l +p ef +pom +gr +gs +pum +159 556 t +331 -261 m 331 -261 331 -261 322 -229 ct 322 -229 322 -229 270 -229 ct 274 -218 276 -207 276 -198 ct +276 -170 264 -146 241 -124 ct 217 -103 185 -91 144 -89 ct 122 -82 106 -75 95 -65 ct +91 -62 89 -59 89 -55 ct 89 -51 91 -47 95 -44 ct 98 -40 108 -37 123 -33 ct 123 -33 123 -33 183 -20 ct +216 -12 238 -3 248 8 ct 259 19 264 31 264 46 ct 264 63 258 78 245 92 ct 233 106 215 117 190 125 ct +166 133 140 137 111 137 ct 85 137 62 134 41 128 ct 20 122 5 114 -4 103 ct -13 93 -18 82 -18 71 ct +-18 63 -15 53 -9 44 ct -3 34 4 26 13 20 ct 19 16 35 7 61 -8 ct 52 -15 47 -23 47 -32 ct +47 -40 51 -49 59 -58 ct 67 -68 85 -78 111 -89 ct 89 -93 71 -103 58 -118 ct 45 -132 39 -149 39 -167 ct +39 -196 52 -222 78 -245 ct 104 -268 138 -280 181 -280 ct 196 -280 209 -278 219 -275 ct +229 -272 239 -268 248 -261 ct 248 -261 248 -261 331 -261 ct p +225 -211 m 225 -228 220 -240 211 -250 ct 201 -259 189 -264 173 -264 ct 149 -264 129 -252 114 -229 ct +98 -206 90 -182 90 -157 ct 90 -141 95 -128 105 -118 ct 115 -108 127 -103 142 -103 ct +153 -103 164 -106 174 -112 ct 185 -118 194 -126 201 -136 ct 209 -147 214 -160 219 -176 ct +223 -192 225 -204 225 -211 ct p +74 0 m 57 8 45 18 36 30 ct 27 42 23 53 23 65 ct 23 79 29 90 42 99 ct 59 112 85 118 120 118 ct +149 118 175 113 196 103 ct 217 93 227 80 227 64 ct 227 56 223 48 215 41 ct 208 34 193 28 170 24 ct +158 21 126 13 74 0 ct p ef +pom +gr +gs +pum +609 714 t +119 -164 m 119 -164 119 -164 116 -150 ct 116 -150 116 -150 88 -150 ct 88 -150 88 -150 65 -69 ct +55 -34 45 -6 36 13 ct 23 41 9 60 -6 70 ct -18 78 -29 82 -41 82 ct -49 82 -55 80 -60 75 ct +-64 72 -66 68 -66 63 ct -66 59 -64 55 -61 52 ct -58 49 -54 48 -50 48 ct -46 48 -44 49 -41 51 ct +-39 53 -38 56 -38 58 ct -38 61 -39 64 -41 66 ct -43 68 -44 69 -44 70 ct -44 71 -44 72 -43 73 ct +-42 74 -40 74 -38 74 ct -32 74 -27 72 -21 69 ct -15 66 -10 61 -5 54 ct -1 48 3 38 8 26 ct +9 21 14 4 22 -25 ct 22 -25 22 -25 59 -150 ct 59 -150 59 -150 22 -150 ct 22 -150 22 -150 25 -164 ct +36 -164 44 -165 49 -166 ct 53 -168 57 -170 61 -174 ct 65 -178 70 -186 75 -197 ct +82 -212 89 -224 95 -232 ct 104 -243 113 -251 123 -257 ct 132 -262 142 -265 150 -265 ct +159 -265 166 -263 172 -258 ct 177 -253 180 -248 180 -242 ct 180 -238 179 -234 176 -231 ct +173 -228 169 -227 165 -227 ct 161 -227 158 -228 156 -230 ct 153 -233 152 -235 152 -238 ct +152 -240 153 -243 155 -245 ct 157 -248 158 -250 158 -251 ct 158 -253 157 -254 156 -255 ct +155 -256 153 -257 150 -257 ct 143 -257 136 -254 130 -249 ct 122 -242 115 -232 109 -217 ct +106 -210 100 -192 92 -164 ct 92 -164 92 -164 119 -164 ct p ef +125 -158 m 125 -158 125 -158 189 -168 ct 189 -168 189 -168 163 -78 ct 185 -115 204 -141 222 -155 ct +232 -164 240 -168 247 -168 ct 251 -168 254 -167 256 -164 ct 259 -162 260 -158 260 -154 ct +260 -146 258 -138 254 -130 ct 251 -125 247 -122 241 -122 ct 238 -122 236 -123 234 -125 ct +232 -127 230 -130 230 -134 ct 230 -136 229 -138 228 -138 ct 227 -139 226 -140 225 -140 ct +223 -140 221 -140 219 -139 ct 216 -137 211 -132 204 -124 ct 194 -112 183 -96 171 -77 ct +166 -68 161 -59 158 -49 ct 153 -35 150 -26 149 -23 ct 149 -23 149 -23 142 0 ct +142 0 142 0 114 0 ct 114 0 114 0 147 -116 ct 151 -129 153 -139 153 -144 ct 153 -146 153 -148 151 -150 ct +148 -152 145 -153 141 -153 ct 139 -153 134 -152 128 -151 ct 128 -151 128 -151 125 -158 ct +p ef +443 -166 m 443 -166 443 -166 406 -40 ct 406 -40 406 -40 402 -23 ct 402 -21 401 -20 401 -19 ct +401 -17 402 -15 403 -14 ct 403 -13 404 -13 405 -13 ct 406 -13 408 -13 409 -15 ct +413 -18 417 -26 423 -37 ct 423 -37 423 -37 429 -33 ct 422 -20 415 -11 407 -5 ct +399 1 392 4 386 4 ct 382 4 378 3 376 0 ct 373 -3 372 -6 372 -11 ct 372 -17 373 -25 376 -35 ct +376 -35 376 -35 380 -50 ct 362 -29 346 -14 331 -5 ct 320 1 309 4 299 4 ct 289 4 280 0 273 -7 ct +266 -14 262 -25 262 -38 ct 262 -57 268 -77 281 -99 ct 294 -120 311 -138 331 -151 ct +346 -161 361 -166 374 -166 ct 383 -166 390 -164 395 -160 ct 401 -157 405 -151 408 -142 ct +408 -142 408 -142 413 -162 ct 413 -162 413 -162 443 -166 ct p +373 -157 m 365 -157 356 -153 346 -146 ct 332 -136 320 -120 309 -100 ct 298 -80 293 -61 293 -45 ct +293 -37 295 -30 300 -25 ct 305 -20 310 -18 317 -18 ct 332 -18 349 -28 367 -47 ct +389 -73 399 -100 398 -128 ct 398 -138 396 -145 392 -150 ct 387 -155 381 -157 373 -157 ct +p ef +528 -168 m 528 -168 528 -168 504 -84 ct 515 -104 524 -119 532 -129 ct 544 -144 555 -155 567 -162 ct +573 -166 580 -168 588 -168 ct 594 -168 599 -166 603 -162 ct 607 -158 609 -153 609 -147 ct +609 -141 608 -133 605 -123 ct 605 -123 605 -123 591 -76 ct 612 -114 632 -140 652 -155 ct +662 -164 673 -168 683 -168 ct 689 -168 694 -166 698 -162 ct 702 -158 704 -151 704 -143 ct +704 -135 703 -128 700 -120 ct 700 -120 700 -120 677 -48 ct 672 -33 669 -24 669 -22 ct +669 -21 670 -19 671 -18 ct 672 -17 673 -17 674 -17 ct 675 -17 677 -18 680 -20 ct +686 -25 692 -33 698 -42 ct 698 -42 698 -42 704 -38 ct 701 -33 696 -26 688 -18 ct +681 -9 674 -3 669 0 ct 663 3 658 4 654 4 ct 650 4 646 3 643 0 ct 641 -3 639 -7 639 -11 ct +639 -17 642 -29 648 -47 ct 648 -47 648 -47 668 -106 ct 672 -120 674 -128 675 -129 ct +675 -132 675 -134 675 -136 ct 675 -139 675 -142 673 -143 ct 671 -145 670 -146 668 -146 ct +662 -146 656 -143 650 -138 ct 631 -122 613 -100 597 -72 ct 586 -53 576 -29 567 0 ct +567 0 567 0 540 0 ct 540 0 540 0 574 -112 ct 578 -124 580 -132 580 -136 ct 580 -140 579 -142 577 -144 ct +576 -145 574 -146 572 -146 ct 568 -146 564 -145 559 -142 ct 551 -137 542 -126 530 -111 ct +518 -95 508 -80 502 -65 ct 499 -59 491 -37 479 0 ct 479 0 479 0 452 0 ct 452 0 452 0 487 -120 ct +487 -120 487 -120 491 -136 ct 492 -138 493 -140 493 -141 ct 493 -144 491 -146 489 -148 ct +486 -150 483 -151 479 -151 ct 478 -151 473 -150 466 -149 ct 466 -149 466 -149 464 -156 ct +464 -156 464 -156 528 -168 ct p ef +763 -70 m 762 -64 762 -59 762 -55 ct 762 -44 766 -35 774 -27 ct 782 -20 792 -16 803 -16 ct +812 -16 821 -18 830 -21 ct 838 -25 851 -33 867 -45 ct 867 -45 867 -45 871 -40 ct +841 -11 813 4 786 4 ct 768 4 754 -2 745 -13 ct 736 -24 731 -37 731 -51 ct 731 -69 737 -88 748 -107 ct +760 -126 774 -141 792 -152 ct 809 -163 827 -168 845 -168 ct 858 -168 868 -165 874 -160 ct +881 -155 884 -148 884 -141 ct 884 -131 880 -121 871 -112 ct 860 -99 844 -89 823 -82 ct +809 -77 789 -73 763 -70 ct p +764 -79 m 783 -81 799 -85 811 -90 ct 826 -97 838 -105 846 -114 ct 854 -124 858 -133 858 -141 ct +858 -147 856 -151 853 -154 ct 850 -157 845 -159 838 -159 ct 825 -159 811 -152 797 -139 ct +782 -125 771 -105 764 -79 ct p ef +pom +gr +gr +gr +gr +gr +16800 8400 m 16238 8588 l 16238 8213 l 16800 8400 l p ef +14400 8375 m 16350 8375 l 16350 8425 l 14400 8425 l 14400 8375 l p ef +13028 6249 m 12578 6399 l 12578 6099 l 13028 6249 l p ef +1 lw 0 lj 11500 6250 m 12527 6250 l 12527 6249 l 12668 6249 l ps +tm setmatrix +0 0 t +1 1 s +0 6358 t +pom +count op_count sub {pop} repeat countdictstack dict_count sub {end} repeat b4_inc_state restore +%%PageTrailer +%%Trailer +%%EOF diff --git a/src/libs/speexdsp/doc/speex_analysis.odg b/src/libs/speexdsp/doc/speex_analysis.odg new file mode 100644 index 00000000..919945d8 Binary files /dev/null and b/src/libs/speexdsp/doc/speex_analysis.odg differ diff --git a/src/libs/speexdsp/html/index.html b/src/libs/speexdsp/html/index.html new file mode 100644 index 00000000..789a796e --- /dev/null +++ b/src/libs/speexdsp/html/index.html @@ -0,0 +1,215 @@ +<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"><html><head> + + + + + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + + + + + + + + <meta name="GENERATOR" content="Mozilla/4.78 [fr] (X11; U; Linux 2.4.17 i686) [Netscape]"> + + + + + + + + <meta name="Author" content="Jean-Marc Valin"> + <title>The Speex Speech Codec</title> + + + + + + + </head> + +<body text="#000000" bgcolor="#ffffff" link="#0000ef" vlink="#59188e" alink="#ff0000"> + +<center> +<img src="speex.png" alt="Speex"> +</center> +<br> +<br> + + + <a href="http://sourceforge.net/projects/speex">The Speex project</a> + aims to build an open-source (LGPL) <A href="patents.html">patent-free</A> voice codec. Unlike + other codecs like MP3 and <a href="http://www.vorbis.org/">Ogg Vorbis</a>, +Speex is specially designed for compressing voice at low bit-rates in the +8-32 kbps/channel range. Possible applications include Voice over IP (VoIP), + Internet audio streaming, archiving of speech data (e.g. voice mail), and +audio books. In some sense, it is meant to be complementary to the +Ogg Vorbis codec. +<p>If you are interested in participating to the project, contact us at <a href="mailto:speex-devel@lists.sourceforge.net"> + speex-devel@lists.sourceforge.net</a> or <a href="http://lists.sourceforge.net/lists/listinfo/speex-devel"> + join our mailing list</a>. Right now, we are mostly looking for + developers with signal processing and speech coding knowledge, as well + as people with knowledge about patents in that field. See the +<A href="http://sourceforge.net/pm/task.php?group_project_id=19556&group_id=46651&func=browse">task list</A> for more details about what's left to do in Speex<br> +</p> + + + + +<h2>Download</h2> + + + + You can download Speex from <a href="http://sourceforge.net/project/showfiles.php?group_id=46651"> + here</a>.<br> + + +<h2>Documentation</h2> +This Speex manual includes information about the +algorithms used in Speex, the bit-stream, the API and more. +<br> +<A href="manual.pdf">Speex manual (PDF)</A> +<br> +<A href="manual.ps">Speex manual (Postscript)</A> +<br> +<A href="manual/">Speex manual (HTML online)</A> +<br> +<A href="manual.tar.gz">Speex manual (HTML tarball)</A> +<br><br> +There is also some API documentation generated by Doxygen directly from the header files +<br> +<A href="refman.pdf">Speex API (PDF)</A> + +<h2>Samples</h2> + +You can listen to samples encoded with Speex <A href="/audio/samples/">here</A> + +<h2>Who uses Speex</h2> + +<A href="http://www.linphone.org">LinPhone</a>: A SIP-based VoIP phone written for GNOME +<br> +<A href="http://jzb.rapanden.dk/speex/">Speex XMMS plugin</a> written by <a href="mailto:jzb@rapanden.dk">Jens Burkal</a> +<br> +<A href="http://www.openh323.org">OpenH323</a>: An open-source H.323 stack +<br> +<A href="http://www.gnomemeeting.org">GnomeMeeting</A>: A H323 Video Conferencing Program + +<br><br> +In development: +<br> +<A href="http://www.asteriskpbx.org">Asterisk</a>: An open-source PBX + +<h2>News</h2> + +<h3>2002/09/04</h3> + +Speex 0.8.1 released. This release fixes a bug in the new 0.8 API (function +speex_mode_query). For those using only speexenc/speexdec, no need to upgrade +but those using libspeex (directly or through another application) should. + +<h3>2002/08/24</h3> + Speex 0.8.0 released. The speex_decode() function no longer uses the +'lost' parameter. Applications will need + to be updated. + +<h3>2002/08/09</h3> + Speex 0.7.0 released. The format of the bit stream has changed once again +and the bandwidth required has been + reduced slightly. + +<h3>2002/08/01</h3> + +Speex 0.6.0 has been released. This is a major release that contains many improvements and lots of bug-fixing. The post-filter that was causing problems throughout 0.5.x was replaced with a new perceptual enhancement system, which sounds better and consume much less CPU. Also many changes to Ogg encoder/decoder, including possibility to see the bit-rate being played/encoded. There is also a discontinuous transmission (DTX) mode. Last but not least, 0.6.0 now reports no error when being run with the valgrind memory debugger. + +<h3>2002/07/26</h3> + +Speex 0.5.2 is out and brings a number of improvements and bug fixes. First, +the search has been improved and it is now possible to choose the right +quality/encoding time tradeoff (--comp option). Is is also possible to pack +more that one frame in an Ogg packet (--nframes), reducing the overhead for +low bit-rates. Last but not least: there is now some documentation about +Speex! + + +<h3>2002/07/17</h3> + +Version 0.5.1 is released. This release brings quality improvements at very +low bit-rate (5.7 kbps) and a new post-filter. VBR should also be a bit +better though there's still a lot to do. Most of the modes are bit-rate +compatible with 0.5.0, with the exception of the very low bit-rate (which is +sometimes used in VBR, so expect some glitches). The source (and probably +binary) compatibility with 0.5.0 is maintained. + +<h3>2002/07/08</h3> + +Speex 0.5.0 is out. The most important new feature is Varible Bit-Rate +(VBR). It can be enabled by using the --vbr option to speexenc. When +encoding in VBR, the --quality option can still be used. Note VBR +implementation in this release is experimental and still requires lots of +tuning. + +<h3>2002/06/23</h3> + +Speex 0.4.0 is here, adding many more bit-rates to both narrowband and wideband, as +well as the ability to change bit-rate dynamically from frame to frame. The +narrowband modes now range from 8 kbps to 18 kbps, while wideband range from +10 kbps to 28 kbps. There is also a "noise coding" mode at 2 kbps for +narrowband and 3 kbps for wideband. All this will lead to real Variable +Bit-Rate (VBR) in the future. Also, worth mentioning the codec latency has +been reduced from 40 ms to 30 ms (20 ms frames + 10 ms lookahead). + +<h3>2002/06/12</h3> + +Speex 0.3.0 has been released. There is now a new "low bit-rate" narrowband +mode for coding speech at 8 kbps. There's also support for big-endian +machines (untested, please report bugs). Speex files now have real header +containing information like bit-stream version (revents from playing an +incompatible bit-stream), sampling rate, bit-rate and user comments. On the +quality side, the post-filter has been improved and there has been more +codebook optimization. Note that this release breaks bit-stream +compatibility with previous releases. + +<h3>2002/06/07</h3> + +Speex 0.2.0 is out. This is a major release with lots of improvements and +bugfixes. First, the encoder and decoder can work directly from wav files +(mono only for now) and the decoder can play directly to soundcard. Also, +most of the codebooks have been re-trained in order to improve quality (but +this also breaks format compatibility with previous versions), while +slightly decreasing complexity. Speex is now able to encode both DTMF and +music (not as good as Vorbis of course) after bugs were fixed in the pitch +prediction and LSP quantization. Last but not the least, the perceptual +post-filter has been improved. + +<h3>2002/06/04</h3> + +Speex 0.1.2 is out. This adds a perceptual post-filter at the decoder to +(hopefully) increase quality. It can be enabled with the --pf option to +speexdec. The Speex format remains the same for both narrowband +and wideband. + +<h3>2002/05/15</h3> + +Speex 0.1.0 has been released. Speex now uses the Ogg bitstream (using +libogg). That means that there is now (limited) bitstream error +recovery. Also, the narrowband bit-rate has been reduced from 15.7 kbps to +15.1 kbps and the wideband bit-rate has been reduced from 31.3 kbps to 27.7 +kbps. The quality remains roughly the same for both narrowband and +wideband. Once again, this breaks compatibility with previous versions. + +<hr width="100%" size="2"> +<div align="right"><a href="http://uk.eurorights.org/issues/cd/quick/"><img +border="0" width="160" height="40" src="badcd002.png" +alt="Say NO to corrupt audio discs" /></a> +<br> +<img src="http://sourceforge.net/sflogo.php?group_id=46651&amp;amp;type=5" alt="SourceForge Logo"> +<br> + +<a href="mailto:jean-marc.valin@hermes.usherb.ca">Jean-Mrc Valin</a> <br> + $Date: 2002/09/16 00:59:10 $</div> + + + + +</body></html> diff --git a/src/libs/speexdsp/html/patents.html b/src/libs/speexdsp/html/patents.html new file mode 100644 index 00000000..d81c961e --- /dev/null +++ b/src/libs/speexdsp/html/patents.html @@ -0,0 +1,39 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + <title>Speex and patents</title> + + <meta name="author" content="Jean-Marc Valin"> +</head> + <body> + +<div align="center"> +<h1>Position regarding patents</h1> + +<div align="left">The goal of Speex is to provide a codec that is open-source +(released under the <a href="http://www.gnu.org/licenses/lgpl.html">LGPL</a>) +and that can be used in open-source software. This implies that it also has +to be free from patent restrictions. Unfortunately, the field of speech coding +known to be a real patent minefield and to make the matter worse, each country +has its own patent laws and list of granted patents so tracking them all +would be next to impossible. This is why we cannot provide an absolute warranty +that Speex is indeed completely patent-free.<br> +<br> + That being said, we are doing our best to keep away from known patents and +we do not patent the algorithms we use. That's about all we can do about it. +If you are aware of a patent issue with Speex, please <a + href="mailto:speex-devel@lists.sourceforge.net">let us know</a>.<br> + <br> +Normally there shouldn't be any problem when you use Speex. However for the +reasons explained above, if you are thinking about using Speex commercially, +we strongly suggest that you have a closer look at patent issues with respect +to your country. Note that this is not specific to Speex, since many "standardized" +codecs have an unclear patent status (like <a + href="http://www.mp3-tech.org/patents.html">MP3</a>, <a + href="http://kbs.cs.tu-berlin.de/%7Ejutta/toast.html">GSM</a> and probably +others), not to mention the risks of a previously unknown patent holder claiming +rights on a standardized codec long after standardization (<a href="http://lpf.ai.mit.edu/Patents/Gif/Gif.html">GIF</a>, <a href="http://www.itworld.com/Man/2687/020719jpegpatent/">JPEG</a>).<br> +</div> + </div> +</body> +</html> diff --git a/src/libs/speexdsp/html/speex.png b/src/libs/speexdsp/html/speex.png new file mode 100644 index 00000000..4db28733 Binary files /dev/null and b/src/libs/speexdsp/html/speex.png differ diff --git a/src/libs/speexdsp/html/speex.webprj b/src/libs/speexdsp/html/speex.webprj new file mode 100644 index 00000000..23139f61 --- /dev/null +++ b/src/libs/speexdsp/html/speex.webprj @@ -0,0 +1,7 @@ +<!DOCTYPE webproject ><webproject> + <project usePreviewPrefix="0" previewPrefix="" type="Local" name="speex" > + <upload/> + <author></author> + <email></email> + </project> +</webproject> diff --git a/src/libs/speexdsp/html/speex.xcf b/src/libs/speexdsp/html/speex.xcf new file mode 100644 index 00000000..e5547123 Binary files /dev/null and b/src/libs/speexdsp/html/speex.xcf differ diff --git a/src/libs/speexdsp/include/Makefile.am b/src/libs/speexdsp/include/Makefile.am new file mode 100644 index 00000000..09613b63 --- /dev/null +++ b/src/libs/speexdsp/include/Makefile.am @@ -0,0 +1,2 @@ + +SUBDIRS = speex diff --git a/src/libs/speexdsp/include/speex/Makefile.am b/src/libs/speexdsp/include/speex/Makefile.am new file mode 100644 index 00000000..c462a055 --- /dev/null +++ b/src/libs/speexdsp/include/speex/Makefile.am @@ -0,0 +1,7 @@ +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +nodist_pkginclude_HEADERS = speexdsp_config_types.h + +pkginclude_HEADERS = speex_echo.h speex_jitter.h speex_preprocess.h speex_resampler.h \ + speexdsp_types.h diff --git a/src/libs/speexdsp/include/speex/speex_buffer.h b/src/libs/speexdsp/include/speex/speex_buffer.h new file mode 100644 index 00000000..5bd128ae --- /dev/null +++ b/src/libs/speexdsp/include/speex/speex_buffer.h @@ -0,0 +1,68 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: speex_buffer.h + This is a very simple ring buffer implementation. It is not thread-safe + so you need to do your own locking. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SPEEX_BUFFER_H +#define SPEEX_BUFFER_H + +#include "speexdsp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct SpeexBuffer_; +typedef struct SpeexBuffer_ SpeexBuffer; + +SpeexBuffer *speex_buffer_init(int size); + +void speex_buffer_destroy(SpeexBuffer *st); + +int speex_buffer_write(SpeexBuffer *st, void *data, int len); + +int speex_buffer_writezeros(SpeexBuffer *st, int len); + +int speex_buffer_read(SpeexBuffer *st, void *data, int len); + +int speex_buffer_get_available(SpeexBuffer *st); + +int speex_buffer_resize(SpeexBuffer *st, int len); + +#ifdef __cplusplus +} +#endif + +#endif + + + + diff --git a/src/libs/speexdsp/include/speex/speex_echo.h b/src/libs/speexdsp/include/speex/speex_echo.h new file mode 100644 index 00000000..6f14d091 --- /dev/null +++ b/src/libs/speexdsp/include/speex/speex_echo.h @@ -0,0 +1,170 @@ +/* Copyright (C) Jean-Marc Valin */ +/** + @file speex_echo.h + @brief Echo cancellation +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SPEEX_ECHO_H +#define SPEEX_ECHO_H +/** @defgroup SpeexEchoState SpeexEchoState: Acoustic echo canceller + * This is the acoustic echo canceller module. + * @{ + */ +#include "speexdsp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Obtain frame size used by the AEC */ +#define SPEEX_ECHO_GET_FRAME_SIZE 3 + +/** Set sampling rate */ +#define SPEEX_ECHO_SET_SAMPLING_RATE 24 +/** Get sampling rate */ +#define SPEEX_ECHO_GET_SAMPLING_RATE 25 + +/* Can't set window sizes */ +/** Get size of impulse response (int32) */ +#define SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE 27 + +/* Can't set window content */ +/** Get impulse response (int32[]) */ +#define SPEEX_ECHO_GET_IMPULSE_RESPONSE 29 + +/** Internal echo canceller state. Should never be accessed directly. */ +struct SpeexEchoState_; + +/** @class SpeexEchoState + * This holds the state of the echo canceller. You need one per channel. +*/ + +/** Internal echo canceller state. Should never be accessed directly. */ +typedef struct SpeexEchoState_ SpeexEchoState; + +/** Creates a new echo canceller state + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms) + * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms) + * @return Newly-created echo canceller state + */ +SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length); + +/** Creates a new multi-channel echo canceller state + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms) + * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms) + * @param nb_mic Number of microphone channels + * @param nb_speakers Number of speaker channels + * @return Newly-created echo canceller state + */ +SpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_length, int nb_mic, int nb_speakers); + +/** Destroys an echo canceller state + * @param st Echo canceller state +*/ +void speex_echo_state_destroy(SpeexEchoState *st); + +/** Performs echo cancellation a frame, based on the audio sent to the speaker (no delay is added + * to playback in this form) + * + * @param st Echo canceller state + * @param rec Signal from the microphone (near end + far end echo) + * @param play Signal played to the speaker (received from far end) + * @param out Returns near-end signal with echo removed + */ +void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out); + +/** Performs echo cancellation a frame (deprecated) */ +void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout); + +/** Perform echo cancellation using internal playback buffer, which is delayed by two frames + * to account for the delay introduced by most soundcards (but it could be off!) + * @param st Echo canceller state + * @param rec Signal from the microphone (near end + far end echo) + * @param out Returns near-end signal with echo removed +*/ +void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out); + +/** Let the echo canceller know that a frame was just queued to the soundcard + * @param st Echo canceller state + * @param play Signal played to the speaker (received from far end) +*/ +void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play); + +/** Reset the echo canceller to its original state + * @param st Echo canceller state + */ +void speex_echo_state_reset(SpeexEchoState *st); + +/** Used like the ioctl function to control the echo canceller parameters + * + * @param st Echo canceller state + * @param request ioctl-type request (one of the SPEEX_ECHO_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown + */ +int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr); + + + +struct SpeexDecorrState_; + +typedef struct SpeexDecorrState_ SpeexDecorrState; + + +/** Create a state for the channel decorrelation algorithm + This is useful for multi-channel echo cancellation only + * @param rate Sampling rate + * @param channels Number of channels (it's a bit pointless if you don't have at least 2) + * @param frame_size Size of the frame to process at ones (counting samples *per* channel) +*/ +SpeexDecorrState *speex_decorrelate_new(int rate, int channels, int frame_size); + +/** Remove correlation between the channels by modifying the phase and possibly + adding noise in a way that is not (or little) perceptible. + * @param st Decorrelator state + * @param in Input audio in interleaved format + * @param out Result of the decorrelation (out *may* alias in) + * @param strength How much alteration of the audio to apply from 0 to 100. +*/ +void speex_decorrelate(SpeexDecorrState *st, const spx_int16_t *in, spx_int16_t *out, int strength); + +/** Destroy a Decorrelation state + * @param st State to destroy +*/ +void speex_decorrelate_destroy(SpeexDecorrState *st); + + +#ifdef __cplusplus +} +#endif + + +/** @}*/ +#endif diff --git a/src/libs/speexdsp/include/speex/speex_jitter.h b/src/libs/speexdsp/include/speex/speex_jitter.h new file mode 100644 index 00000000..66708da5 --- /dev/null +++ b/src/libs/speexdsp/include/speex/speex_jitter.h @@ -0,0 +1,197 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file speex_jitter.h + @brief Adaptive jitter buffer for Speex +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef SPEEX_JITTER_H +#define SPEEX_JITTER_H +/** @defgroup JitterBuffer JitterBuffer: Adaptive jitter buffer + * This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size + * to maintain good quality and low latency. + * @{ + */ + +#include "speexdsp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Generic adaptive jitter buffer state */ +struct JitterBuffer_; + +/** Generic adaptive jitter buffer state */ +typedef struct JitterBuffer_ JitterBuffer; + +/** Definition of an incoming packet */ +typedef struct _JitterBufferPacket JitterBufferPacket; + +/** Definition of an incoming packet */ +struct _JitterBufferPacket { + char *data; /**< Data bytes contained in the packet */ + spx_uint32_t len; /**< Length of the packet in bytes */ + spx_uint32_t timestamp; /**< Timestamp for the packet */ + spx_uint32_t span; /**< Time covered by the packet (same units as timestamp) */ + spx_uint16_t sequence; /**< RTP Sequence number if available (0 otherwise) */ + spx_uint32_t user_data; /**< Put whatever data you like here (it's ignored by the jitter buffer) */ +}; + +/** Packet has been retrieved */ +#define JITTER_BUFFER_OK 0 +/** Packet is lost or is late */ +#define JITTER_BUFFER_MISSING 1 +/** A "fake" packet is meant to be inserted here to increase buffering */ +#define JITTER_BUFFER_INSERTION 2 +/** There was an error in the jitter buffer */ +#define JITTER_BUFFER_INTERNAL_ERROR -1 +/** Invalid argument */ +#define JITTER_BUFFER_BAD_ARGUMENT -2 + + +/** Set minimum amount of extra buffering required (margin) */ +#define JITTER_BUFFER_SET_MARGIN 0 +/** Get minimum amount of extra buffering required (margin) */ +#define JITTER_BUFFER_GET_MARGIN 1 +/* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */ + +/** Get the amount of available packets currently buffered */ +#define JITTER_BUFFER_GET_AVAILABLE_COUNT 3 +/** Included because of an early misspelling (will remove in next release) */ +#define JITTER_BUFFER_GET_AVALIABLE_COUNT 3 + +/** Assign a function to destroy unused packet. When setting that, the jitter + buffer no longer copies packet data. */ +#define JITTER_BUFFER_SET_DESTROY_CALLBACK 4 +/** */ +#define JITTER_BUFFER_GET_DESTROY_CALLBACK 5 + +/** Tell the jitter buffer to only adjust the delay in multiples of the step parameter provided */ +#define JITTER_BUFFER_SET_DELAY_STEP 6 +/** */ +#define JITTER_BUFFER_GET_DELAY_STEP 7 + +/** Tell the jitter buffer to only do concealment in multiples of the size parameter provided */ +#define JITTER_BUFFER_SET_CONCEALMENT_SIZE 8 +#define JITTER_BUFFER_GET_CONCEALMENT_SIZE 9 + +/** Absolute max amount of loss that can be tolerated regardless of the delay. Typical loss + should be half of that or less. */ +#define JITTER_BUFFER_SET_MAX_LATE_RATE 10 +#define JITTER_BUFFER_GET_MAX_LATE_RATE 11 + +/** Equivalent cost of one percent late packet in timestamp units */ +#define JITTER_BUFFER_SET_LATE_COST 12 +#define JITTER_BUFFER_GET_LATE_COST 13 + + +/** Initialises jitter buffer + * + * @param step_size Starting value for the size of concleanment packets and delay + adjustment steps. Can be changed at any time using JITTER_BUFFER_SET_DELAY_STEP + and JITTER_BUFFER_GET_CONCEALMENT_SIZE. + * @return Newly created jitter buffer state + */ +JitterBuffer *jitter_buffer_init(int step_size); + +/** Restores jitter buffer to its original state + * + * @param jitter Jitter buffer state + */ +void jitter_buffer_reset(JitterBuffer *jitter); + +/** Destroys jitter buffer + * + * @param jitter Jitter buffer state + */ +void jitter_buffer_destroy(JitterBuffer *jitter); + +/** Put one packet into the jitter buffer + * + * @param jitter Jitter buffer state + * @param packet Incoming packet +*/ +void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet); + +/** Get one packet from the jitter buffer + * + * @param jitter Jitter buffer state + * @param packet Returned packet + * @param desired_span Number of samples (or units) we wish to get from the buffer (no guarantee) + * @param current_timestamp Timestamp for the returned packet +*/ +int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset); + +/** Used right after jitter_buffer_get() to obtain another packet that would have the same timestamp. + * This is mainly useful for media where a single "frame" can be split into several packets. + * + * @param jitter Jitter buffer state + * @param packet Returned packet + */ +int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet); + +/** Get pointer timestamp of jitter buffer + * + * @param jitter Jitter buffer state +*/ +int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter); + +/** Advance by one tick + * + * @param jitter Jitter buffer state +*/ +void jitter_buffer_tick(JitterBuffer *jitter); + +/** Telling the jitter buffer about the remaining data in the application buffer + * @param jitter Jitter buffer state + * @param rem Amount of data buffered by the application (timestamp units) + */ +void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem); + +/** Used like the ioctl function to control the jitter buffer parameters + * + * @param jitter Jitter buffer state + * @param request ioctl-type request (one of the JITTER_BUFFER_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown +*/ +int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr); + +int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/speexdsp/include/speex/speex_preprocess.h b/src/libs/speexdsp/include/speex/speex_preprocess.h new file mode 100644 index 00000000..b9555eb5 --- /dev/null +++ b/src/libs/speexdsp/include/speex/speex_preprocess.h @@ -0,0 +1,219 @@ +/* Copyright (C) 2003 Epic Games + Written by Jean-Marc Valin */ +/** + * @file speex_preprocess.h + * @brief Speex preprocessor. The preprocess can do noise suppression, + * residual echo suppression (after using the echo canceller), automatic + * gain control (AGC) and voice activity detection (VAD). +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SPEEX_PREPROCESS_H +#define SPEEX_PREPROCESS_H +/** @defgroup SpeexPreprocessState SpeexPreprocessState: The Speex preprocessor + * This is the Speex preprocessor. The preprocess can do noise suppression, + * residual echo suppression (after using the echo canceller), automatic + * gain control (AGC) and voice activity detection (VAD). + * @{ + */ + +#include "speexdsp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** State of the preprocessor (one per channel). Should never be accessed directly. */ +struct SpeexPreprocessState_; + +/** State of the preprocessor (one per channel). Should never be accessed directly. */ +typedef struct SpeexPreprocessState_ SpeexPreprocessState; + + +/** Creates a new preprocessing state. You MUST create one state per channel processed. + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms). Must be + * the same value as that used for the echo canceller for residual echo cancellation to work. + * @param sampling_rate Sampling rate used for the input. + * @return Newly created preprocessor state +*/ +SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate); + +/** Destroys a preprocessor state + * @param st Preprocessor state to destroy +*/ +void speex_preprocess_state_destroy(SpeexPreprocessState *st); + +/** Preprocess a frame + * @param st Preprocessor state + * @param x Audio sample vector (in and out). Must be same size as specified in speex_preprocess_state_init(). + * @return Bool value for voice activity (1 for speech, 0 for noise/silence), ONLY if VAD turned on. +*/ +int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x); + +/** Preprocess a frame (deprecated, use speex_preprocess_run() instead)*/ +int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo); + +/** Update preprocessor state, but do not compute the output + * @param st Preprocessor state + * @param x Audio sample vector (in only). Must be same size as specified in speex_preprocess_state_init(). +*/ +void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x); + +/** Used like the ioctl function to control the preprocessor parameters + * @param st Preprocessor state + * @param request ioctl-type request (one of the SPEEX_PREPROCESS_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown +*/ +int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr); + + + +/** Set preprocessor denoiser state */ +#define SPEEX_PREPROCESS_SET_DENOISE 0 +/** Get preprocessor denoiser state */ +#define SPEEX_PREPROCESS_GET_DENOISE 1 + +/** Set preprocessor Automatic Gain Control state */ +#define SPEEX_PREPROCESS_SET_AGC 2 +/** Get preprocessor Automatic Gain Control state */ +#define SPEEX_PREPROCESS_GET_AGC 3 + +/** Set preprocessor Voice Activity Detection state */ +#define SPEEX_PREPROCESS_SET_VAD 4 +/** Get preprocessor Voice Activity Detection state */ +#define SPEEX_PREPROCESS_GET_VAD 5 + +/** Set preprocessor Automatic Gain Control level (float) */ +#define SPEEX_PREPROCESS_SET_AGC_LEVEL 6 +/** Get preprocessor Automatic Gain Control level (float) */ +#define SPEEX_PREPROCESS_GET_AGC_LEVEL 7 + +/** Set preprocessor dereverb state */ +#define SPEEX_PREPROCESS_SET_DEREVERB 8 +/** Get preprocessor dereverb state */ +#define SPEEX_PREPROCESS_GET_DEREVERB 9 + +/** Set preprocessor dereverb level */ +#define SPEEX_PREPROCESS_SET_DEREVERB_LEVEL 10 +/** Get preprocessor dereverb level */ +#define SPEEX_PREPROCESS_GET_DEREVERB_LEVEL 11 + +/** Set preprocessor dereverb decay */ +#define SPEEX_PREPROCESS_SET_DEREVERB_DECAY 12 +/** Get preprocessor dereverb decay */ +#define SPEEX_PREPROCESS_GET_DEREVERB_DECAY 13 + +/** Set probability required for the VAD to go from silence to voice */ +#define SPEEX_PREPROCESS_SET_PROB_START 14 +/** Get probability required for the VAD to go from silence to voice */ +#define SPEEX_PREPROCESS_GET_PROB_START 15 + +/** Set probability required for the VAD to stay in the voice state (integer percent) */ +#define SPEEX_PREPROCESS_SET_PROB_CONTINUE 16 +/** Get probability required for the VAD to stay in the voice state (integer percent) */ +#define SPEEX_PREPROCESS_GET_PROB_CONTINUE 17 + +/** Set maximum attenuation of the noise in dB (negative number) */ +#define SPEEX_PREPROCESS_SET_NOISE_SUPPRESS 18 +/** Get maximum attenuation of the noise in dB (negative number) */ +#define SPEEX_PREPROCESS_GET_NOISE_SUPPRESS 19 + +/** Set maximum attenuation of the residual echo in dB (negative number) */ +#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS 20 +/** Get maximum attenuation of the residual echo in dB (negative number) */ +#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS 21 + +/** Set maximum attenuation of the residual echo in dB when near end is active (negative number) */ +#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE 22 +/** Get maximum attenuation of the residual echo in dB when near end is active (negative number) */ +#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE 23 + +/** Set the corresponding echo canceller state so that residual echo suppression can be performed (NULL for no residual echo suppression) */ +#define SPEEX_PREPROCESS_SET_ECHO_STATE 24 +/** Get the corresponding echo canceller state */ +#define SPEEX_PREPROCESS_GET_ECHO_STATE 25 + +/** Set maximal gain increase in dB/second (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_INCREMENT 26 + +/** Get maximal gain increase in dB/second (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_INCREMENT 27 + +/** Set maximal gain decrease in dB/second (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_DECREMENT 28 + +/** Get maximal gain decrease in dB/second (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_DECREMENT 29 + +/** Set maximal gain in dB (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_MAX_GAIN 30 + +/** Get maximal gain in dB (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31 + +/* Can't set loudness */ +/** Get loudness */ +#define SPEEX_PREPROCESS_GET_AGC_LOUDNESS 33 + +/* Can't set gain */ +/** Get current gain (int32 percent) */ +#define SPEEX_PREPROCESS_GET_AGC_GAIN 35 + +/* Can't set spectrum size */ +/** Get spectrum size for power spectrum (int32) */ +#define SPEEX_PREPROCESS_GET_PSD_SIZE 37 + +/* Can't set power spectrum */ +/** Get power spectrum (int32[] of squared values) */ +#define SPEEX_PREPROCESS_GET_PSD 39 + +/* Can't set noise size */ +/** Get spectrum size for noise estimate (int32) */ +#define SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE 41 + +/* Can't set noise estimate */ +/** Get noise estimate (int32[] of squared values) */ +#define SPEEX_PREPROCESS_GET_NOISE_PSD 43 + +/* Can't set speech probability */ +/** Get speech probability in last frame (int32). */ +#define SPEEX_PREPROCESS_GET_PROB 45 + +/** Set preprocessor Automatic Gain Control level (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_TARGET 46 +/** Get preprocessor Automatic Gain Control level (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_TARGET 47 + +#ifdef __cplusplus +} +#endif + +/** @}*/ +#endif diff --git a/src/libs/speexdsp/include/speex/speex_resampler.h b/src/libs/speexdsp/include/speex/speex_resampler.h new file mode 100644 index 00000000..50d777f5 --- /dev/null +++ b/src/libs/speexdsp/include/speex/speex_resampler.h @@ -0,0 +1,340 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: speex_resampler.h + Resampling code + + The design goals of this code are: + - Very fast algorithm + - Low memory requirement + - Good *perceptual* quality (and not best SNR) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef SPEEX_RESAMPLER_H +#define SPEEX_RESAMPLER_H + +#ifdef OUTSIDE_SPEEX + +/********* WARNING: MENTAL SANITY ENDS HERE *************/ + +/* If the resampler is defined outside of Speex, we change the symbol names so that + there won't be any clash if linking with Speex later on. */ + +/* #define RANDOM_PREFIX your software name here */ +#ifndef RANDOM_PREFIX +#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes" +#endif + +#define CAT_PREFIX2(a,b) a ## b +#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b) + +#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init) +#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac) +#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy) +#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float) +#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int) +#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float) +#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int) +#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate) +#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate) +#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac) +#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio) +#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality) +#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality) +#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride) +#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride) +#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride) +#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride) +#define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency) +#define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency) +#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros) +#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem) +#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror) + +#define spx_int16_t short +#define spx_int32_t int +#define spx_uint16_t unsigned short +#define spx_uint32_t unsigned int + +#else /* OUTSIDE_SPEEX */ + +#include "speexdsp_types.h" + +#endif /* OUTSIDE_SPEEX */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPEEX_RESAMPLER_QUALITY_MAX 10 +#define SPEEX_RESAMPLER_QUALITY_MIN 0 +#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4 +#define SPEEX_RESAMPLER_QUALITY_VOIP 3 +#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5 + +enum { + RESAMPLER_ERR_SUCCESS = 0, + RESAMPLER_ERR_ALLOC_FAILED = 1, + RESAMPLER_ERR_BAD_STATE = 2, + RESAMPLER_ERR_INVALID_ARG = 3, + RESAMPLER_ERR_PTR_OVERLAP = 4, + + RESAMPLER_ERR_MAX_ERROR +}; + +struct SpeexResamplerState_; +typedef struct SpeexResamplerState_ SpeexResamplerState; + +/** Create a new resampler with integer input and output rates. + * @param nb_channels Number of channels to be processed + * @param in_rate Input sampling rate (integer number of Hz). + * @param out_rate Output sampling rate (integer number of Hz). + * @param quality Resampling quality between 0 and 10, where 0 has poor quality + * and 10 has very high quality. + * @return Newly created resampler state + * @retval NULL Error: not enough memory + */ +SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, + spx_uint32_t in_rate, + spx_uint32_t out_rate, + int quality, + int *err); + +/** Create a new resampler with fractional input/output rates. The sampling + * rate ratio is an arbitrary rational number with both the numerator and + * denominator being 32-bit integers. + * @param nb_channels Number of channels to be processed + * @param ratio_num Numerator of the sampling rate ratio + * @param ratio_den Denominator of the sampling rate ratio + * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). + * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). + * @param quality Resampling quality between 0 and 10, where 0 has poor quality + * and 10 has very high quality. + * @return Newly created resampler state + * @retval NULL Error: not enough memory + */ +SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, + spx_uint32_t ratio_num, + spx_uint32_t ratio_den, + spx_uint32_t in_rate, + spx_uint32_t out_rate, + int quality, + int *err); + +/** Destroy a resampler state. + * @param st Resampler state + */ +void speex_resampler_destroy(SpeexResamplerState *st); + +/** Resample a float array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param channel_index Index of the channel to process for the multi-channel + * base (0 otherwise) + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the + * number of samples processed + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written + */ +int speex_resampler_process_float(SpeexResamplerState *st, + spx_uint32_t channel_index, + const float *in, + spx_uint32_t *in_len, + float *out, + spx_uint32_t *out_len); + +/** Resample an int array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param channel_index Index of the channel to process for the multi-channel + * base (0 otherwise) + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written + */ +int speex_resampler_process_int(SpeexResamplerState *st, + spx_uint32_t channel_index, + const spx_int16_t *in, + spx_uint32_t *in_len, + spx_int16_t *out, + spx_uint32_t *out_len); + +/** Resample an interleaved float array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed. This is all per-channel. + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written. + * This is all per-channel. + */ +int speex_resampler_process_interleaved_float(SpeexResamplerState *st, + const float *in, + spx_uint32_t *in_len, + float *out, + spx_uint32_t *out_len); + +/** Resample an interleaved int array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed. This is all per-channel. + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written. + * This is all per-channel. + */ +int speex_resampler_process_interleaved_int(SpeexResamplerState *st, + const spx_int16_t *in, + spx_uint32_t *in_len, + spx_int16_t *out, + spx_uint32_t *out_len); + +/** Set (change) the input/output sampling rates (integer value). + * @param st Resampler state + * @param in_rate Input sampling rate (integer number of Hz). + * @param out_rate Output sampling rate (integer number of Hz). + */ +int speex_resampler_set_rate(SpeexResamplerState *st, + spx_uint32_t in_rate, + spx_uint32_t out_rate); + +/** Get the current input/output sampling rates (integer value). + * @param st Resampler state + * @param in_rate Input sampling rate (integer number of Hz) copied. + * @param out_rate Output sampling rate (integer number of Hz) copied. + */ +void speex_resampler_get_rate(SpeexResamplerState *st, + spx_uint32_t *in_rate, + spx_uint32_t *out_rate); + +/** Set (change) the input/output sampling rates and resampling ratio + * (fractional values in Hz supported). + * @param st Resampler state + * @param ratio_num Numerator of the sampling rate ratio + * @param ratio_den Denominator of the sampling rate ratio + * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). + * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). + */ +int speex_resampler_set_rate_frac(SpeexResamplerState *st, + spx_uint32_t ratio_num, + spx_uint32_t ratio_den, + spx_uint32_t in_rate, + spx_uint32_t out_rate); + +/** Get the current resampling ratio. This will be reduced to the least + * common denominator. + * @param st Resampler state + * @param ratio_num Numerator of the sampling rate ratio copied + * @param ratio_den Denominator of the sampling rate ratio copied + */ +void speex_resampler_get_ratio(SpeexResamplerState *st, + spx_uint32_t *ratio_num, + spx_uint32_t *ratio_den); + +/** Set (change) the conversion quality. + * @param st Resampler state + * @param quality Resampling quality between 0 and 10, where 0 has poor + * quality and 10 has very high quality. + */ +int speex_resampler_set_quality(SpeexResamplerState *st, + int quality); + +/** Get the conversion quality. + * @param st Resampler state + * @param quality Resampling quality between 0 and 10, where 0 has poor + * quality and 10 has very high quality. + */ +void speex_resampler_get_quality(SpeexResamplerState *st, + int *quality); + +/** Set (change) the input stride. + * @param st Resampler state + * @param stride Input stride + */ +void speex_resampler_set_input_stride(SpeexResamplerState *st, + spx_uint32_t stride); + +/** Get the input stride. + * @param st Resampler state + * @param stride Input stride copied + */ +void speex_resampler_get_input_stride(SpeexResamplerState *st, + spx_uint32_t *stride); + +/** Set (change) the output stride. + * @param st Resampler state + * @param stride Output stride + */ +void speex_resampler_set_output_stride(SpeexResamplerState *st, + spx_uint32_t stride); + +/** Get the output stride. + * @param st Resampler state copied + * @param stride Output stride + */ +void speex_resampler_get_output_stride(SpeexResamplerState *st, + spx_uint32_t *stride); + +/** Get the latency introduced by the resampler measured in input samples. + * @param st Resampler state + */ +int speex_resampler_get_input_latency(SpeexResamplerState *st); + +/** Get the latency introduced by the resampler measured in output samples. + * @param st Resampler state + */ +int speex_resampler_get_output_latency(SpeexResamplerState *st); + +/** Make sure that the first samples to go out of the resamplers don't have + * leading zeros. This is only useful before starting to use a newly created + * resampler. It is recommended to use that when resampling an audio file, as + * it will generate a file with the same length. For real-time processing, + * it is probably easier not to use this call (so that the output duration + * is the same for the first frame). + * @param st Resampler state + */ +int speex_resampler_skip_zeros(SpeexResamplerState *st); + +/** Reset a resampler so a new (unrelated) stream can be processed. + * @param st Resampler state + */ +int speex_resampler_reset_mem(SpeexResamplerState *st); + +/** Returns the English meaning for an error code + * @param err Error code + * @return English string + */ +const char *speex_resampler_strerror(int err); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/speexdsp/include/speex/speexdsp_config_types.h.in b/src/libs/speexdsp/include/speex/speexdsp_config_types.h.in new file mode 100644 index 00000000..02b82fd0 --- /dev/null +++ b/src/libs/speexdsp/include/speex/speexdsp_config_types.h.in @@ -0,0 +1,18 @@ +#ifndef __SPEEX_TYPES_H__ +#define __SPEEX_TYPES_H__ + +#if defined HAVE_STDINT_H +# include <stdint.h> +#elif defined HAVE_INTTYPES_H +# include <inttypes.h> +#elif defined HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif + +typedef @SIZE16@ spx_int16_t; +typedef @USIZE16@ spx_uint16_t; +typedef @SIZE32@ spx_int32_t; +typedef @USIZE32@ spx_uint32_t; + +#endif + diff --git a/src/libs/speexdsp/include/speex/speexdsp_types.h b/src/libs/speexdsp/include/speex/speexdsp_types.h new file mode 100644 index 00000000..334d6745 --- /dev/null +++ b/src/libs/speexdsp/include/speex/speexdsp_types.h @@ -0,0 +1,126 @@ +/* speexdsp_types.h taken from libogg */ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id: os_types.h 7524 2004-08-11 04:20:36Z conrad $ + + ********************************************************************/ +/** + @file speexdsp_types.h + @brief Speex types +*/ +#ifndef _SPEEX_TYPES_H +#define _SPEEX_TYPES_H + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include <_G_config.h> + typedef _G_int32_t spx_int32_t; + typedef _G_uint32_t spx_uint32_t; + typedef _G_int16_t spx_int16_t; + typedef _G_uint16_t spx_uint16_t; +# elif defined(__MINGW32__) + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; +# elif defined(__MWERKS__) + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; +# else + /* MSVC/Borland */ + typedef __int32 spx_int32_t; + typedef unsigned __int32 spx_uint32_t; + typedef __int16 spx_int16_t; + typedef unsigned __int16 spx_uint16_t; +# endif + +#elif defined(__MACOS__) + +# include <sys/types.h> + typedef SInt16 spx_int16_t; + typedef UInt16 spx_uint16_t; + typedef SInt32 spx_int32_t; + typedef UInt32 spx_uint32_t; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include <sys/types.h> + typedef int16_t spx_int16_t; + typedef u_int16_t spx_uint16_t; + typedef int32_t spx_int32_t; + typedef u_int32_t spx_uint32_t; + +#elif defined(__BEOS__) + + /* Be */ +# include <inttypes.h> + typedef int16_t spx_int16_t; + typedef u_int16_t spx_uint16_t; + typedef int32_t spx_int32_t; + typedef u_int32_t spx_uint32_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short spx_int16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef int spx_int32_t; + typedef unsigned spx_uint32_t; + typedef short spx_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef signed int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef long spx_int32_t; + typedef unsigned long spx_uint32_t; + +#elif defined(CONFIG_TI_C6X) + + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#else + +#include "speexdsp_config_types.h" + +#endif + +#endif /* _SPEEX_TYPES_H */ diff --git a/src/libs/speexdsp/libspeexdsp/.cvsignore b/src/libs/speexdsp/libspeexdsp/.cvsignore new file mode 100644 index 00000000..09a90ac7 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/.cvsignore @@ -0,0 +1,11 @@ +.deps +.libs +*.la +*.lo +*.o +Makefile +Makefile.in +testdenoise +testenc +testenc_uwb +testenc_wb diff --git a/src/libs/speexdsp/libspeexdsp/Makefile.am b/src/libs/speexdsp/libspeexdsp/Makefile.am new file mode 100644 index 00000000..7bb6eacf --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/Makefile.am @@ -0,0 +1,40 @@ +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST=echo_diagnostic.m + +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include/speex -I$(top_builddir) @FFT_CFLAGS@ + +lib_LTLIBRARIES = libspeexdsp.la + +# Sources for compilation in the library +if BUILD_KISS_FFT + FFTSRC=kiss_fft.c _kiss_fft_guts.h kiss_fft.h kiss_fftr.c kiss_fftr.h +else +if BUILD_SMALLFT + FFTSRC=smallft.c +else + FFTSRC= +endif +endif + +libspeexdsp_la_SOURCES = preprocess.c jitter.c mdf.c fftwrap.c filterbank.c resample.c buffer.c scal.c $(FFTSRC) + +noinst_HEADERS = arch.h bfin.h \ + fixed_arm4.h \ + fixed_arm5e.h fixed_bfin.h fixed_debug.h \ + math_approx.h misc_bfin.h \ + stack_alloc.h fftwrap.h \ + filterbank.h fixed_generic.h os_support.h \ + pseudofloat.h smallft.h vorbis_psy.h resample_sse.h + +libspeexdsp_la_LDFLAGS = -no-undefined -version-info @SPEEXDSP_LT_CURRENT@:@SPEEXDSP_LT_REVISION@:@SPEEXDSP_LT_AGE@ +libspeexdsp_la_LIBADD = $(LIBM) + +noinst_PROGRAMS = testdenoise testecho testjitter +testdenoise_SOURCES = testdenoise.c +testdenoise_LDADD = libspeexdsp.la @FFT_LIBS@ +testecho_SOURCES = testecho.c +testecho_LDADD = libspeexdsp.la @FFT_LIBS@ +testjitter_SOURCES = testjitter.c +testjitter_LDADD = libspeexdsp.la @FFT_LIBS@ diff --git a/src/libs/speexdsp/libspeexdsp/_kiss_fft_guts.h b/src/libs/speexdsp/libspeexdsp/_kiss_fft_guts.h new file mode 100644 index 00000000..6571e79c --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/_kiss_fft_guts.h @@ -0,0 +1,160 @@ +/* +Copyright (c) 2003-2004, Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define MIN(a,b) ((a)<(b) ? (a):(b)) +#define MAX(a,b) ((a)>(b) ? (a):(b)) + +/* kiss_fft.h + defines kiss_fft_scalar as either short or a float type + and defines + typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ +#include "kiss_fft.h" +#include "math_approx.h" + +#define MAXFACTORS 32 +/* e.g. an fft of length 128 has 4 factors + as far as kissfft is concerned + 4*4*4*2 + */ + +struct kiss_fft_state{ + int nfft; + int inverse; + int factors[2*MAXFACTORS]; + kiss_fft_cpx twiddles[1]; +}; + +/* + Explanation of macros dealing with complex math: + + C_MUL(m,a,b) : m = a*b + C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise + C_SUB( res, a,b) : res = a - b + C_SUBFROM( res , a) : res -= a + C_ADDTO( res , a) : res += a + * */ +#ifdef FIXED_POINT +#include "arch.h" +# define FRACBITS 15 +# define SAMPPROD spx_int32_t +#define SAMP_MAX 32767 + +#define SAMP_MIN -SAMP_MAX + +#if defined(CHECK_OVERFLOW) +# define CHECK_OVERFLOW_OP(a,op,b) \ + if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \ + fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); } +#endif + + +# define smul(a,b) ( (SAMPPROD)(a)*(b) ) +# define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS ) + +# define S_MUL(a,b) sround( smul(a,b) ) + +# define C_MUL(m,a,b) \ + do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ + (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) + +# define C_MUL4(m,a,b) \ + do{ (m).r = PSHR32( smul((a).r,(b).r) - smul((a).i,(b).i),17 ); \ + (m).i = PSHR32( smul((a).r,(b).i) + smul((a).i,(b).r),17 ); }while(0) + +# define DIVSCALAR(x,k) \ + (x) = sround( smul( x, SAMP_MAX/k ) ) + +# define C_FIXDIV(c,div) \ + do { DIVSCALAR( (c).r , div); \ + DIVSCALAR( (c).i , div); }while (0) + +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r = sround( smul( (c).r , s ) ) ;\ + (c).i = sround( smul( (c).i , s ) ) ; }while(0) + +#else /* not FIXED_POINT*/ + +# define S_MUL(a,b) ( (a)*(b) ) +#define C_MUL(m,a,b) \ + do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ + (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) + +#define C_MUL4(m,a,b) C_MUL(m,a,b) + +# define C_FIXDIV(c,div) /* NOOP */ +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r *= (s);\ + (c).i *= (s); }while(0) +#endif + +#ifndef CHECK_OVERFLOW_OP +# define CHECK_OVERFLOW_OP(a,op,b) /* noop */ +#endif + +#define C_ADD( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,+,(b).r)\ + CHECK_OVERFLOW_OP((a).i,+,(b).i)\ + (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ + }while(0) +#define C_SUB( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,-,(b).r)\ + CHECK_OVERFLOW_OP((a).i,-,(b).i)\ + (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ + }while(0) +#define C_ADDTO( res , a)\ + do { \ + CHECK_OVERFLOW_OP((res).r,+,(a).r)\ + CHECK_OVERFLOW_OP((res).i,+,(a).i)\ + (res).r += (a).r; (res).i += (a).i;\ + }while(0) + +#define C_SUBFROM( res , a)\ + do {\ + CHECK_OVERFLOW_OP((res).r,-,(a).r)\ + CHECK_OVERFLOW_OP((res).i,-,(a).i)\ + (res).r -= (a).r; (res).i -= (a).i; \ + }while(0) + + +#ifdef FIXED_POINT +# define KISS_FFT_COS(phase) floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase)))) +# define KISS_FFT_SIN(phase) floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase)))) +# define HALF_OF(x) ((x)>>1) +#elif defined(USE_SIMD) +# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) +# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) +# define HALF_OF(x) ((x)*_mm_set1_ps(.5)) +#else +# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) +# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) +# define HALF_OF(x) ((x)*.5) +#endif + +#define kf_cexp(x,phase) \ + do{ \ + (x)->r = KISS_FFT_COS(phase);\ + (x)->i = KISS_FFT_SIN(phase);\ + }while(0) +#define kf_cexp2(x,phase) \ + do{ \ + (x)->r = spx_cos_norm((phase));\ + (x)->i = spx_cos_norm((phase)-32768);\ +}while(0) + + +/* a debugging function */ +#define pcpx(c)\ + fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) ) diff --git a/src/libs/speexdsp/libspeexdsp/arch.h b/src/libs/speexdsp/libspeexdsp/arch.h new file mode 100644 index 00000000..18446ddf --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/arch.h @@ -0,0 +1,231 @@ +/* Copyright (C) 2003 Jean-Marc Valin */ +/** + @file arch.h + @brief Various architecture definitions Speex +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ARCH_H +#define ARCH_H + +/* A couple test to catch stupid option combinations */ +#ifdef FIXED_POINT + +#ifdef FLOATING_POINT +#error You cannot compile as floating point and fixed point at the same time +#endif +#ifdef _USE_SSE +#error SSE is only for floating-point +#endif +#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM)) +#error Make up your mind. What CPU do you have? +#endif +#ifdef VORBIS_PSYCHO +#error Vorbis-psy model currently not implemented in fixed-point +#endif + +#else + +#ifndef FLOATING_POINT +#error You now need to define either FIXED_POINT or FLOATING_POINT +#endif +#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM) +#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions? +#endif +#ifdef FIXED_POINT_DEBUG +#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?" +#endif + + +#endif + +#ifndef OUTSIDE_SPEEX +#include "speex/speexdsp_types.h" +#endif + +#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */ +#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */ +#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */ +#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */ +#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */ +#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 32-bit value. */ +#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */ + +#ifdef FIXED_POINT + +typedef spx_int16_t spx_word16_t; +typedef spx_int32_t spx_word32_t; +typedef spx_word32_t spx_mem_t; +typedef spx_word16_t spx_coef_t; +typedef spx_word16_t spx_lsp_t; +typedef spx_word32_t spx_sig_t; + +#define Q15ONE 32767 + +#define LPC_SCALING 8192 +#define SIG_SCALING 16384 +#define LSP_SCALING 8192. +#define GAMMA_SCALING 32768. +#define GAIN_SCALING 64 +#define GAIN_SCALING_1 0.015625 + +#define LPC_SHIFT 13 +#define LSP_SHIFT 13 +#define SIG_SHIFT 14 +#define GAIN_SHIFT 6 + +#define VERY_SMALL 0 +#define VERY_LARGE32 ((spx_word32_t)2147483647) +#define VERY_LARGE16 ((spx_word16_t)32767) +#define Q15_ONE ((spx_word16_t)32767) + + +#ifdef FIXED_DEBUG +#include "fixed_debug.h" +#else + +#include "fixed_generic.h" + +#ifdef ARM5E_ASM +#include "fixed_arm5e.h" +#elif defined (ARM4_ASM) +#include "fixed_arm4.h" +#elif defined (BFIN_ASM) +#include "fixed_bfin.h" +#endif + +#endif + + +#else + +typedef float spx_mem_t; +typedef float spx_coef_t; +typedef float spx_lsp_t; +typedef float spx_sig_t; +typedef float spx_word16_t; +typedef float spx_word32_t; + +#define Q15ONE 1.0f +#define LPC_SCALING 1.f +#define SIG_SCALING 1.f +#define LSP_SCALING 1.f +#define GAMMA_SCALING 1.f +#define GAIN_SCALING 1.f +#define GAIN_SCALING_1 1.f + + +#define VERY_SMALL 1e-15f +#define VERY_LARGE32 1e15f +#define VERY_LARGE16 1e15f +#define Q15_ONE ((spx_word16_t)1.f) + +#define QCONST16(x,bits) (x) +#define QCONST32(x,bits) (x) + +#define NEG16(x) (-(x)) +#define NEG32(x) (-(x)) +#define EXTRACT16(x) (x) +#define EXTEND32(x) (x) +#define SHR16(a,shift) (a) +#define SHL16(a,shift) (a) +#define SHR32(a,shift) (a) +#define SHL32(a,shift) (a) +#define PSHR16(a,shift) (a) +#define PSHR32(a,shift) (a) +#define VSHR32(a,shift) (a) +#define SATURATE16(x,a) (x) +#define SATURATE32(x,a) (x) + +#define PSHR(a,shift) (a) +#define SHR(a,shift) (a) +#define SHL(a,shift) (a) +#define SATURATE(x,a) (x) + +#define ADD16(a,b) ((a)+(b)) +#define SUB16(a,b) ((a)-(b)) +#define ADD32(a,b) ((a)+(b)) +#define SUB32(a,b) ((a)-(b)) +#define MULT16_16_16(a,b) ((a)*(b)) +#define MULT16_16(a,b) ((spx_word32_t)(a)*(spx_word32_t)(b)) +#define MAC16_16(c,a,b) ((c)+(spx_word32_t)(a)*(spx_word32_t)(b)) + +#define MULT16_32_Q11(a,b) ((a)*(b)) +#define MULT16_32_Q13(a,b) ((a)*(b)) +#define MULT16_32_Q14(a,b) ((a)*(b)) +#define MULT16_32_Q15(a,b) ((a)*(b)) +#define MULT16_32_P15(a,b) ((a)*(b)) + +#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b)) +#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b)) + +#define MAC16_16_Q11(c,a,b) ((c)+(a)*(b)) +#define MAC16_16_Q13(c,a,b) ((c)+(a)*(b)) +#define MAC16_16_P13(c,a,b) ((c)+(a)*(b)) +#define MULT16_16_Q11_32(a,b) ((a)*(b)) +#define MULT16_16_Q13(a,b) ((a)*(b)) +#define MULT16_16_Q14(a,b) ((a)*(b)) +#define MULT16_16_Q15(a,b) ((a)*(b)) +#define MULT16_16_P15(a,b) ((a)*(b)) +#define MULT16_16_P13(a,b) ((a)*(b)) +#define MULT16_16_P14(a,b) ((a)*(b)) + +#define DIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b)) +#define PDIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b)) +#define DIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b)) +#define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b)) + + +#endif + + +#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + +/* 2 on TI C5x DSP */ +#define BYTES_PER_CHAR 2 +#define BITS_PER_CHAR 16 +#define LOG2_BITS_PER_CHAR 4 + +#else + +#define BYTES_PER_CHAR 1 +#define BITS_PER_CHAR 8 +#define LOG2_BITS_PER_CHAR 3 + +#endif + + + +#ifdef FIXED_DEBUG +extern long long spx_mips; +#endif + + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/bfin.h b/src/libs/speexdsp/libspeexdsp/bfin.h new file mode 100644 index 00000000..b934cf2f --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/bfin.h @@ -0,0 +1,15 @@ +/* Common Blackfin assembly defines + * + * Copyright (C) 2005-2009 Analog Devices + */ + +#if __GNUC__ <= 3 +/* GCC-3.4 and older did not use hardware loops and thus did not have + * register constraints for declaring clobbers. + */ +# define BFIN_HWLOOP0_REGS +# define BFIN_HWLOOP1_REGS +#else +# define BFIN_HWLOOP0_REGS , "LB0", "LT0", "LC0" +# define BFIN_HWLOOP1_REGS , "LB1", "LT1", "LC1" +#endif diff --git a/src/libs/speexdsp/libspeexdsp/buffer.c b/src/libs/speexdsp/libspeexdsp/buffer.c new file mode 100644 index 00000000..c82cab5b --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/buffer.c @@ -0,0 +1,176 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: buffer.c + This is a very simple ring buffer implementation. It is not thread-safe + so you need to do your own locking. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include "os_support.h" +#include "arch.h" +#include "speex/speex_buffer.h" + +struct SpeexBuffer_ { + char *data; + int size; + int read_ptr; + int write_ptr; + int available; +}; + +EXPORT SpeexBuffer *speex_buffer_init(int size) +{ + SpeexBuffer *st = speex_alloc(sizeof(SpeexBuffer)); + st->data = speex_alloc(size); + st->size = size; + st->read_ptr = 0; + st->write_ptr = 0; + st->available = 0; + return st; +} + +EXPORT void speex_buffer_destroy(SpeexBuffer *st) +{ + speex_free(st->data); + speex_free(st); +} + +EXPORT int speex_buffer_write(SpeexBuffer *st, void *_data, int len) +{ + int end; + int end1; + char *data = _data; + if (len > st->size) + { + data += len-st->size; + len = st->size; + } + end = st->write_ptr + len; + end1 = end; + if (end1 > st->size) + end1 = st->size; + SPEEX_COPY(st->data + st->write_ptr, data, end1 - st->write_ptr); + if (end > st->size) + { + end -= st->size; + SPEEX_COPY(st->data, data+end1 - st->write_ptr, end); + } + st->available += len; + if (st->available > st->size) + { + st->available = st->size; + st->read_ptr = st->write_ptr; + } + st->write_ptr += len; + if (st->write_ptr > st->size) + st->write_ptr -= st->size; + return len; +} + +EXPORT int speex_buffer_writezeros(SpeexBuffer *st, int len) +{ + /* This is almost the same as for speex_buffer_write() but using + SPEEX_MEMSET() instead of SPEEX_COPY(). Update accordingly. */ + int end; + int end1; + if (len > st->size) + { + len = st->size; + } + end = st->write_ptr + len; + end1 = end; + if (end1 > st->size) + end1 = st->size; + SPEEX_MEMSET(st->data + st->write_ptr, 0, end1 - st->write_ptr); + if (end > st->size) + { + end -= st->size; + SPEEX_MEMSET(st->data, 0, end); + } + st->available += len; + if (st->available > st->size) + { + st->available = st->size; + st->read_ptr = st->write_ptr; + } + st->write_ptr += len; + if (st->write_ptr > st->size) + st->write_ptr -= st->size; + return len; +} + +EXPORT int speex_buffer_read(SpeexBuffer *st, void *_data, int len) +{ + int end, end1; + char *data = _data; + if (len > st->available) + { + SPEEX_MEMSET(data+st->available, 0, st->size-st->available); + len = st->available; + } + end = st->read_ptr + len; + end1 = end; + if (end1 > st->size) + end1 = st->size; + SPEEX_COPY(data, st->data + st->read_ptr, end1 - st->read_ptr); + + if (end > st->size) + { + end -= st->size; + SPEEX_COPY(data+end1 - st->read_ptr, st->data, end); + } + st->available -= len; + st->read_ptr += len; + if (st->read_ptr > st->size) + st->read_ptr -= st->size; + return len; +} + +EXPORT int speex_buffer_get_available(SpeexBuffer *st) +{ + return st->available; +} + +EXPORT int speex_buffer_resize(SpeexBuffer *st, int len) +{ + int old_len = st->size; + if (len > old_len) + { + st->data = speex_realloc(st->data, len); + /* FIXME: move data/pointers properly for growing the buffer */ + } else { + /* FIXME: move data/pointers properly for shrinking the buffer */ + st->data = speex_realloc(st->data, len); + } + return len; +} diff --git a/src/libs/speexdsp/libspeexdsp/echo_diagnostic.m b/src/libs/speexdsp/libspeexdsp/echo_diagnostic.m new file mode 100644 index 00000000..aebf3906 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/echo_diagnostic.m @@ -0,0 +1,72 @@ +% Attempts to diagnose AEC problems from recorded samples +% +% out = echo_diagnostic(rec_file, play_file, out_file, tail_length) +% +% Computes the full matrix inversion to cancel echo from the +% recording 'rec_file' using the far end signal 'play_file' using +% a filter length of 'tail_length'. The output is saved to 'out_file'. +function out = echo_diagnostic(rec_file, play_file, out_file, tail_length) + +F=fopen(rec_file,'rb'); +rec=fread(F,Inf,'short'); +fclose (F); +F=fopen(play_file,'rb'); +play=fread(F,Inf,'short'); +fclose (F); + +rec = [rec; zeros(1024,1)]; +play = [play; zeros(1024,1)]; + +N = length(rec); +corr = real(ifft(fft(rec).*conj(fft(play)))); +acorr = real(ifft(fft(play).*conj(fft(play)))); + +[a,b] = max(corr); + +if b > N/2 + b = b-N; +end +printf ("Far end to near end delay is %d samples\n", b); +if (b > .3*tail_length) + printf ('This is too much delay, try delaying the far-end signal a bit\n'); +else if (b < 0) + printf ('You have a negative delay, the echo canceller has no chance to cancel anything!\n'); + else + printf ('Delay looks OK.\n'); + end + end +end +N2 = round(N/2); +corr1 = real(ifft(fft(rec(1:N2)).*conj(fft(play(1:N2))))); +corr2 = real(ifft(fft(rec(N2+1:end)).*conj(fft(play(N2+1:end))))); + +[a,b1] = max(corr1); +if b1 > N2/2 + b1 = b1-N2; +end +[a,b2] = max(corr2); +if b2 > N2/2 + b2 = b2-N2; +end +drift = (b1-b2)/N2; +printf ('Drift estimate is %f%% (%d samples)\n', 100*drift, b1-b2); +if abs(b1-b2) < 10 + printf ('A drift of a few (+-10) samples is normal.\n'); +else + if abs(b1-b2) < 30 + printf ('There may be (not sure) excessive clock drift. Is the capture and playback done on the same soundcard?\n'); + else + printf ('Your clock is drifting! No way the AEC will be able to do anything with that. Most likely, you''re doing capture and playback from two different cards.\n'); + end + end +end +acorr(1) = .001+1.00001*acorr(1); +AtA = toeplitz(acorr(1:tail_length)); +bb = corr(1:tail_length); +h = AtA\bb; + +out = (rec - filter(h, 1, play)); + +F=fopen(out_file,'w'); +fwrite(F,out,'short'); +fclose (F); diff --git a/src/libs/speexdsp/libspeexdsp/fftwrap.c b/src/libs/speexdsp/libspeexdsp/fftwrap.c new file mode 100644 index 00000000..a14b1e4f --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/fftwrap.c @@ -0,0 +1,448 @@ +/* Copyright (C) 2005-2006 Jean-Marc Valin + File: fftwrap.c + + Wrapper for various FFTs + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "arch.h" +#include "os_support.h" + +#define MAX_FFT_SIZE 2048 + +#ifdef FIXED_POINT +static int maximize_range(spx_word16_t *in, spx_word16_t *out, spx_word16_t bound, int len) +{ + int i, shift; + spx_word16_t max_val = 0; + for (i=0;i<len;i++) + { + if (in[i]>max_val) + max_val = in[i]; + if (-in[i]>max_val) + max_val = -in[i]; + } + shift=0; + while (max_val <= (bound>>1) && max_val != 0) + { + max_val <<= 1; + shift++; + } + for (i=0;i<len;i++) + { + out[i] = SHL16(in[i], shift); + } + return shift; +} + +static void renorm_range(spx_word16_t *in, spx_word16_t *out, int shift, int len) +{ + int i; + for (i=0;i<len;i++) + { + out[i] = PSHR16(in[i], shift); + } +} +#endif + +#ifdef USE_SMALLFT + +#include "smallft.h" +#include <math.h> + +void *spx_fft_init(int size) +{ + struct drft_lookup *table; + table = speex_alloc(sizeof(struct drft_lookup)); + spx_drft_init((struct drft_lookup *)table, size); + return (void*)table; +} + +void spx_fft_destroy(void *table) +{ + spx_drft_clear(table); + speex_free(table); +} + +void spx_fft(void *table, float *in, float *out) +{ + if (in==out) + { + int i; + float scale = 1./((struct drft_lookup *)table)->n; + speex_warning("FFT should not be done in-place"); + for (i=0;i<((struct drft_lookup *)table)->n;i++) + out[i] = scale*in[i]; + } else { + int i; + float scale = 1./((struct drft_lookup *)table)->n; + for (i=0;i<((struct drft_lookup *)table)->n;i++) + out[i] = scale*in[i]; + } + spx_drft_forward((struct drft_lookup *)table, out); +} + +void spx_ifft(void *table, float *in, float *out) +{ + if (in==out) + { + speex_warning("FFT should not be done in-place"); + } else { + int i; + for (i=0;i<((struct drft_lookup *)table)->n;i++) + out[i] = in[i]; + } + spx_drft_backward((struct drft_lookup *)table, out); +} + +#elif defined(USE_INTEL_MKL) +#include <mkl.h> + +struct mkl_config { + DFTI_DESCRIPTOR_HANDLE desc; + int N; +}; + +void *spx_fft_init(int size) +{ + struct mkl_config *table = (struct mkl_config *) speex_alloc(sizeof(struct mkl_config)); + table->N = size; + DftiCreateDescriptor(&table->desc, DFTI_SINGLE, DFTI_REAL, 1, size); + DftiSetValue(table->desc, DFTI_PACKED_FORMAT, DFTI_PACK_FORMAT); + DftiSetValue(table->desc, DFTI_PLACEMENT, DFTI_NOT_INPLACE); + DftiSetValue(table->desc, DFTI_FORWARD_SCALE, 1.0f / size); + DftiCommitDescriptor(table->desc); + return table; +} + +void spx_fft_destroy(void *table) +{ + struct mkl_config *t = (struct mkl_config *) table; + DftiFreeDescriptor(t->desc); + speex_free(table); +} + +void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + struct mkl_config *t = (struct mkl_config *) table; + DftiComputeForward(t->desc, in, out); +} + +void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + struct mkl_config *t = (struct mkl_config *) table; + DftiComputeBackward(t->desc, in, out); +} + +#elif defined(USE_INTEL_IPP) + +#include <ipps.h> + +struct ipp_fft_config +{ + IppsDFTSpec_R_32f *dftSpec; + Ipp8u *buffer; +}; + +void *spx_fft_init(int size) +{ + int bufferSize = 0; + int hint; + struct ipp_fft_config *table; + + table = (struct ipp_fft_config *)speex_alloc(sizeof(struct ipp_fft_config)); + + /* there appears to be no performance difference between ippAlgHintFast and + ippAlgHintAccurate when using the with the floating point version + of the fft. */ + hint = ippAlgHintAccurate; + + ippsDFTInitAlloc_R_32f(&table->dftSpec, size, IPP_FFT_DIV_FWD_BY_N, hint); + + ippsDFTGetBufSize_R_32f(table->dftSpec, &bufferSize); + table->buffer = ippsMalloc_8u(bufferSize); + + return table; +} + +void spx_fft_destroy(void *table) +{ + struct ipp_fft_config *t = (struct ipp_fft_config *)table; + ippsFree(t->buffer); + ippsDFTFree_R_32f(t->dftSpec); + speex_free(t); +} + +void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + struct ipp_fft_config *t = (struct ipp_fft_config *)table; + ippsDFTFwd_RToPack_32f(in, out, t->dftSpec, t->buffer); +} + +void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + struct ipp_fft_config *t = (struct ipp_fft_config *)table; + ippsDFTInv_PackToR_32f(in, out, t->dftSpec, t->buffer); +} + +#elif defined(USE_GPL_FFTW3) + +#include <fftw3.h> + +struct fftw_config { + float *in; + float *out; + fftwf_plan fft; + fftwf_plan ifft; + int N; +}; + +void *spx_fft_init(int size) +{ + struct fftw_config *table = (struct fftw_config *) speex_alloc(sizeof(struct fftw_config)); + table->in = fftwf_malloc(sizeof(float) * (size+2)); + table->out = fftwf_malloc(sizeof(float) * (size+2)); + + table->fft = fftwf_plan_dft_r2c_1d(size, table->in, (fftwf_complex *) table->out, FFTW_PATIENT); + table->ifft = fftwf_plan_dft_c2r_1d(size, (fftwf_complex *) table->in, table->out, FFTW_PATIENT); + + table->N = size; + return table; +} + +void spx_fft_destroy(void *table) +{ + struct fftw_config *t = (struct fftw_config *) table; + fftwf_destroy_plan(t->fft); + fftwf_destroy_plan(t->ifft); + fftwf_free(t->in); + fftwf_free(t->out); + speex_free(table); +} + + +void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + int i; + struct fftw_config *t = (struct fftw_config *) table; + const int N = t->N; + float *iptr = t->in; + float *optr = t->out; + const float m = 1.0 / N; + for(i=0;i<N;++i) + iptr[i]=in[i] * m; + + fftwf_execute(t->fft); + + out[0] = optr[0]; + for(i=1;i<N;++i) + out[i] = optr[i+1]; +} + +void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + int i; + struct fftw_config *t = (struct fftw_config *) table; + const int N = t->N; + float *iptr = t->in; + float *optr = t->out; + + iptr[0] = in[0]; + iptr[1] = 0.0f; + for(i=1;i<N;++i) + iptr[i+1] = in[i]; + iptr[N+1] = 0.0f; + + fftwf_execute(t->ifft); + + for(i=0;i<N;++i) + out[i] = optr[i]; +} + +#elif defined(USE_KISS_FFT) + +#include "kiss_fftr.h" +#include "kiss_fft.h" + +struct kiss_config { + kiss_fftr_cfg forward; + kiss_fftr_cfg backward; + int N; +}; + +void *spx_fft_init(int size) +{ + struct kiss_config *table; + table = (struct kiss_config*)speex_alloc(sizeof(struct kiss_config)); + table->forward = kiss_fftr_alloc(size,0,NULL,NULL); + table->backward = kiss_fftr_alloc(size,1,NULL,NULL); + table->N = size; + return table; +} + +void spx_fft_destroy(void *table) +{ + struct kiss_config *t = (struct kiss_config *)table; + kiss_fftr_free(t->forward); + kiss_fftr_free(t->backward); + speex_free(table); +} + +#ifdef FIXED_POINT + +void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + int shift; + struct kiss_config *t = (struct kiss_config *)table; + shift = maximize_range(in, in, 32000, t->N); + kiss_fftr2(t->forward, in, out); + renorm_range(in, in, shift, t->N); + renorm_range(out, out, shift, t->N); +} + +#else + +void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + int i; + float scale; + struct kiss_config *t = (struct kiss_config *)table; + scale = 1./t->N; + kiss_fftr2(t->forward, in, out); + for (i=0;i<t->N;i++) + out[i] *= scale; +} +#endif + +void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out) +{ + struct kiss_config *t = (struct kiss_config *)table; + kiss_fftri2(t->backward, in, out); +} + + +#else + +#error No other FFT implemented + +#endif + + +#ifdef FIXED_POINT +/*#include "smallft.h"*/ + + +void spx_fft_float(void *table, float *in, float *out) +{ + int i; +#ifdef USE_SMALLFT + int N = ((struct drft_lookup *)table)->n; +#elif defined(USE_KISS_FFT) + int N = ((struct kiss_config *)table)->N; +#else +#endif +#ifdef VAR_ARRAYS + spx_word16_t _in[N]; + spx_word16_t _out[N]; +#else + spx_word16_t _in[MAX_FFT_SIZE]; + spx_word16_t _out[MAX_FFT_SIZE]; +#endif + for (i=0;i<N;i++) + _in[i] = (int)floor(.5+in[i]); + spx_fft(table, _in, _out); + for (i=0;i<N;i++) + out[i] = _out[i]; +#if 0 + if (!fixed_point) + { + float scale; + struct drft_lookup t; + spx_drft_init(&t, ((struct kiss_config *)table)->N); + scale = 1./((struct kiss_config *)table)->N; + for (i=0;i<((struct kiss_config *)table)->N;i++) + out[i] = scale*in[i]; + spx_drft_forward(&t, out); + spx_drft_clear(&t); + } +#endif +} + +void spx_ifft_float(void *table, float *in, float *out) +{ + int i; +#ifdef USE_SMALLFT + int N = ((struct drft_lookup *)table)->n; +#elif defined(USE_KISS_FFT) + int N = ((struct kiss_config *)table)->N; +#else +#endif +#ifdef VAR_ARRAYS + spx_word16_t _in[N]; + spx_word16_t _out[N]; +#else + spx_word16_t _in[MAX_FFT_SIZE]; + spx_word16_t _out[MAX_FFT_SIZE]; +#endif + for (i=0;i<N;i++) + _in[i] = (int)floor(.5+in[i]); + spx_ifft(table, _in, _out); + for (i=0;i<N;i++) + out[i] = _out[i]; +#if 0 + if (!fixed_point) + { + int i; + struct drft_lookup t; + spx_drft_init(&t, ((struct kiss_config *)table)->N); + for (i=0;i<((struct kiss_config *)table)->N;i++) + out[i] = in[i]; + spx_drft_backward(&t, out); + spx_drft_clear(&t); + } +#endif +} + +#else + +void spx_fft_float(void *table, float *in, float *out) +{ + spx_fft(table, in, out); +} +void spx_ifft_float(void *table, float *in, float *out) +{ + spx_ifft(table, in, out); +} + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/fftwrap.h b/src/libs/speexdsp/libspeexdsp/fftwrap.h new file mode 100644 index 00000000..dfaf4894 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/fftwrap.h @@ -0,0 +1,58 @@ +/* Copyright (C) 2005 Jean-Marc Valin + File: fftwrap.h + + Wrapper for various FFTs + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef FFTWRAP_H +#define FFTWRAP_H + +#include "arch.h" + +/** Compute tables for an FFT */ +void *spx_fft_init(int size); + +/** Destroy tables for an FFT */ +void spx_fft_destroy(void *table); + +/** Forward (real to half-complex) transform */ +void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out); + +/** Backward (half-complex to real) transform */ +void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out); + +/** Forward (real to half-complex) transform of float data */ +void spx_fft_float(void *table, float *in, float *out); + +/** Backward (half-complex to real) transform of float data */ +void spx_ifft_float(void *table, float *in, float *out); + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/filterbank.c b/src/libs/speexdsp/libspeexdsp/filterbank.c new file mode 100644 index 00000000..e2fb71d4 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/filterbank.c @@ -0,0 +1,227 @@ +/* Copyright (C) 2006 Jean-Marc Valin */ +/** + @file filterbank.c + @brief Converting between psd and filterbank + */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "filterbank.h" +#include "arch.h" +#include <math.h> +#include "math_approx.h" +#include "os_support.h" + +#ifdef FIXED_POINT + +#define toBARK(n) (MULT16_16(26829,spx_atan(SHR32(MULT16_16(97,n),2))) + MULT16_16(4588,spx_atan(MULT16_32_Q15(20,MULT16_16(n,n)))) + MULT16_16(3355,n)) + +#else +#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n)) +#endif + +#define toMEL(n) (2595.f*log10(1.f+(n)/700.f)) + +FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type) +{ + FilterBank *bank; + spx_word32_t df; + spx_word32_t max_mel, mel_interval; + int i; + int id1; + int id2; + df = DIV32(SHL32(sampling,15),MULT16_16(2,len)); + max_mel = toBARK(EXTRACT16(sampling/2)); + mel_interval = PDIV32(max_mel,banks-1); + + bank = (FilterBank*)speex_alloc(sizeof(FilterBank)); + bank->nb_banks = banks; + bank->len = len; + bank->bank_left = (int*)speex_alloc(len*sizeof(int)); + bank->bank_right = (int*)speex_alloc(len*sizeof(int)); + bank->filter_left = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t)); + bank->filter_right = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t)); + /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */ +#ifndef FIXED_POINT + bank->scaling = (float*)speex_alloc(banks*sizeof(float)); +#endif + for (i=0;i<len;i++) + { + spx_word16_t curr_freq; + spx_word32_t mel; + spx_word16_t val; + curr_freq = EXTRACT16(MULT16_32_P15(i,df)); + mel = toBARK(curr_freq); + if (mel > max_mel) + break; +#ifdef FIXED_POINT + id1 = DIV32(mel,mel_interval); +#else + id1 = (int)(floor(mel/mel_interval)); +#endif + if (id1>banks-2) + { + id1 = banks-2; + val = Q15_ONE; + } else { + val = DIV32_16(mel - id1*mel_interval,EXTRACT16(PSHR32(mel_interval,15))); + } + id2 = id1+1; + bank->bank_left[i] = id1; + bank->filter_left[i] = SUB16(Q15_ONE,val); + bank->bank_right[i] = id2; + bank->filter_right[i] = val; + } + + /* Think I can safely disable normalisation for fixed-point (and probably float as well) */ +#ifndef FIXED_POINT + for (i=0;i<bank->nb_banks;i++) + bank->scaling[i] = 0; + for (i=0;i<bank->len;i++) + { + int id = bank->bank_left[i]; + bank->scaling[id] += bank->filter_left[i]; + id = bank->bank_right[i]; + bank->scaling[id] += bank->filter_right[i]; + } + for (i=0;i<bank->nb_banks;i++) + bank->scaling[i] = Q15_ONE/(bank->scaling[i]); +#endif + return bank; +} + +void filterbank_destroy(FilterBank *bank) +{ + speex_free(bank->bank_left); + speex_free(bank->bank_right); + speex_free(bank->filter_left); + speex_free(bank->filter_right); +#ifndef FIXED_POINT + speex_free(bank->scaling); +#endif + speex_free(bank); +} + +void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel) +{ + int i; + for (i=0;i<bank->nb_banks;i++) + mel[i] = 0; + + for (i=0;i<bank->len;i++) + { + int id; + id = bank->bank_left[i]; + mel[id] += MULT16_32_P15(bank->filter_left[i],ps[i]); + id = bank->bank_right[i]; + mel[id] += MULT16_32_P15(bank->filter_right[i],ps[i]); + } + /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */ +#ifndef FIXED_POINT + /*for (i=0;i<bank->nb_banks;i++) + mel[i] = MULT16_32_P15(Q15(bank->scaling[i]),mel[i]); + */ +#endif +} + +void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *ps) +{ + int i; + for (i=0;i<bank->len;i++) + { + spx_word32_t tmp; + int id1, id2; + id1 = bank->bank_left[i]; + id2 = bank->bank_right[i]; + tmp = MULT16_16(mel[id1],bank->filter_left[i]); + tmp += MULT16_16(mel[id2],bank->filter_right[i]); + ps[i] = EXTRACT16(PSHR32(tmp,15)); + } +} + + +#ifndef FIXED_POINT +void filterbank_compute_bank(FilterBank *bank, float *ps, float *mel) +{ + int i; + for (i=0;i<bank->nb_banks;i++) + mel[i] = 0; + + for (i=0;i<bank->len;i++) + { + int id = bank->bank_left[i]; + mel[id] += bank->filter_left[i]*ps[i]; + id = bank->bank_right[i]; + mel[id] += bank->filter_right[i]*ps[i]; + } + for (i=0;i<bank->nb_banks;i++) + mel[i] *= bank->scaling[i]; +} + +void filterbank_compute_psd(FilterBank *bank, float *mel, float *ps) +{ + int i; + for (i=0;i<bank->len;i++) + { + int id = bank->bank_left[i]; + ps[i] = mel[id]*bank->filter_left[i]; + id = bank->bank_right[i]; + ps[i] += mel[id]*bank->filter_right[i]; + } +} + +void filterbank_psy_smooth(FilterBank *bank, float *ps, float *mask) +{ + /* Low freq slope: 14 dB/Bark*/ + /* High freq slope: 9 dB/Bark*/ + /* Noise vs tone: 5 dB difference */ + /* FIXME: Temporary kludge */ + float bark[100]; + int i; + /* Assumes 1/3 Bark resolution */ + float decay_low = 0.34145f; + float decay_high = 0.50119f; + filterbank_compute_bank(bank, ps, bark); + for (i=1;i<bank->nb_banks;i++) + { + /*float decay_high = 13-1.6*log10(bark[i-1]); + decay_high = pow(10,(-decay_high/30.f));*/ + bark[i] = bark[i] + decay_high*bark[i-1]; + } + for (i=bank->nb_banks-2;i>=0;i--) + { + bark[i] = bark[i] + decay_low*bark[i+1]; + } + filterbank_compute_psd(bank, bark, mask); +} + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/filterbank.h b/src/libs/speexdsp/libspeexdsp/filterbank.h new file mode 100644 index 00000000..3e889a22 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/filterbank.h @@ -0,0 +1,66 @@ +/* Copyright (C) 2006 Jean-Marc Valin */ +/** + @file filterbank.h + @brief Converting between psd and filterbank + */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FILTERBANK_H +#define FILTERBANK_H + +#include "arch.h" + +typedef struct { + int *bank_left; + int *bank_right; + spx_word16_t *filter_left; + spx_word16_t *filter_right; +#ifndef FIXED_POINT + float *scaling; +#endif + int nb_banks; + int len; +} FilterBank; + + +FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type); + +void filterbank_destroy(FilterBank *bank); + +void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel); + +void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *psd); + +#ifndef FIXED_POINT +void filterbank_compute_bank(FilterBank *bank, float *psd, float *mel); +void filterbank_compute_psd(FilterBank *bank, float *mel, float *psd); +#endif + + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/fixed_arm4.h b/src/libs/speexdsp/libspeexdsp/fixed_arm4.h new file mode 100644 index 00000000..b6981cae --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/fixed_arm4.h @@ -0,0 +1,148 @@ +/* Copyright (C) 2004 Jean-Marc Valin */ +/** + @file fixed_arm4.h + @brief ARM4 fixed-point operations +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_ARM4_H +#define FIXED_ARM4_H + +#undef MULT16_32_Q14 +static inline spx_word32_t MULT16_32_Q14(spx_word16_t x, spx_word32_t y) { + int res; + int dummy; + asm ( + "smull %0,%1,%2,%3 \n\t" + "mov %0, %0, lsr #14 \n\t" + "add %0, %0, %1, lsl #18 \n\t" + : "=&r"(res), "=&r" (dummy) + : "r"(y),"r"((int)x)); + return(res); +} + +#undef MULT16_32_Q15 +static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) { + int res; + int dummy; + asm ( + "smull %0,%1,%2,%3 \n\t" + "mov %0, %0, lsr #15 \n\t" + "add %0, %0, %1, lsl #17 \n\t" + : "=&r"(res), "=&r" (dummy) + : "r"(y),"r"((int)x)); + return(res); +} + +#undef DIV32_16 +static inline short DIV32_16(int a, int b) +{ + int res=0; + int dead1, dead2, dead3, dead4, dead5; + __asm__ __volatile__ ( + "\teor %5, %0, %1\n" + "\tmovs %4, %0\n" + "\trsbmi %0, %0, #0 \n" + "\tmovs %4, %1\n" + "\trsbmi %1, %1, #0 \n" + "\tmov %4, #1\n" + + "\tsubs %3, %0, %1, asl #14 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #14 \n" + + "\tsubs %3, %0, %1, asl #13 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #13 \n" + + "\tsubs %3, %0, %1, asl #12 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #12 \n" + + "\tsubs %3, %0, %1, asl #11 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #11 \n" + + "\tsubs %3, %0, %1, asl #10 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #10 \n" + + "\tsubs %3, %0, %1, asl #9 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #9 \n" + + "\tsubs %3, %0, %1, asl #8 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #8 \n" + + "\tsubs %3, %0, %1, asl #7 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #7 \n" + + "\tsubs %3, %0, %1, asl #6 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #6 \n" + + "\tsubs %3, %0, %1, asl #5 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #5 \n" + + "\tsubs %3, %0, %1, asl #4 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #4 \n" + + "\tsubs %3, %0, %1, asl #3 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #3 \n" + + "\tsubs %3, %0, %1, asl #2 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #2 \n" + + "\tsubs %3, %0, %1, asl #1 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4, asl #1 \n" + + "\tsubs %3, %0, %1 \n" + "\tmovpl %0, %3 \n" + "\torrpl %2, %2, %4 \n" + + "\tmovs %5, %5, lsr #31 \n" + "\trsbne %2, %2, #0 \n" + : "=r" (dead1), "=r" (dead2), "=r" (res), + "=r" (dead3), "=r" (dead4), "=r" (dead5) + : "0" (a), "1" (b), "2" (res) + : "cc" + ); + return res; +} + + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/fixed_arm5e.h b/src/libs/speexdsp/libspeexdsp/fixed_arm5e.h new file mode 100644 index 00000000..9b4861c9 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/fixed_arm5e.h @@ -0,0 +1,178 @@ +/* Copyright (C) 2003 Jean-Marc Valin */ +/** + @file fixed_arm5e.h + @brief ARM-tuned fixed-point operations +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_ARM5E_H +#define FIXED_ARM5E_H + +#undef MULT16_16 +static inline spx_word32_t MULT16_16(spx_word16_t x, spx_word16_t y) { + int res; + asm ("smulbb %0,%1,%2;\n" + : "=&r"(res) + : "%r"(x),"r"(y)); + return(res); +} + +#undef MAC16_16 +static inline spx_word32_t MAC16_16(spx_word32_t a, spx_word16_t x, spx_word32_t y) { + int res; + asm ("smlabb %0,%1,%2,%3;\n" + : "=&r"(res) + : "%r"(x),"r"(y),"r"(a)); + return(res); +} + +#undef MULT16_32_Q15 +static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) { + int res; + asm ("smulwb %0,%1,%2;\n" + : "=&r"(res) + : "%r"(y<<1),"r"(x)); + return(res); +} + +#undef MAC16_32_Q15 +static inline spx_word32_t MAC16_32_Q15(spx_word32_t a, spx_word16_t x, spx_word32_t y) { + int res; + asm ("smlawb %0,%1,%2,%3;\n" + : "=&r"(res) + : "%r"(y<<1),"r"(x),"r"(a)); + return(res); +} + +#undef MULT16_32_Q11 +static inline spx_word32_t MULT16_32_Q11(spx_word16_t x, spx_word32_t y) { + int res; + asm ("smulwb %0,%1,%2;\n" + : "=&r"(res) + : "%r"(y<<5),"r"(x)); + return(res); +} + +#undef MAC16_32_Q11 +static inline spx_word32_t MAC16_32_Q11(spx_word32_t a, spx_word16_t x, spx_word32_t y) { + int res; + asm ("smlawb %0,%1,%2,%3;\n" + : "=&r"(res) + : "%r"(y<<5),"r"(x),"r"(a)); + return(res); +} + +#undef DIV32_16 +static inline short DIV32_16(int a, int b) +{ + int res=0; + int dead1, dead2, dead3, dead4, dead5; + __asm__ __volatile__ ( + "\teor %5, %0, %1\n" + "\tmovs %4, %0\n" + "\trsbmi %0, %0, #0 \n" + "\tmovs %4, %1\n" + "\trsbmi %1, %1, #0 \n" + "\tmov %4, #1\n" + + "\tsubs %3, %0, %1, asl #14 \n" + "\torrpl %2, %2, %4, asl #14 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #13 \n" + "\torrpl %2, %2, %4, asl #13 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #12 \n" + "\torrpl %2, %2, %4, asl #12 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #11 \n" + "\torrpl %2, %2, %4, asl #11 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #10 \n" + "\torrpl %2, %2, %4, asl #10 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #9 \n" + "\torrpl %2, %2, %4, asl #9 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #8 \n" + "\torrpl %2, %2, %4, asl #8 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #7 \n" + "\torrpl %2, %2, %4, asl #7 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #6 \n" + "\torrpl %2, %2, %4, asl #6 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #5 \n" + "\torrpl %2, %2, %4, asl #5 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #4 \n" + "\torrpl %2, %2, %4, asl #4 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #3 \n" + "\torrpl %2, %2, %4, asl #3 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #2 \n" + "\torrpl %2, %2, %4, asl #2 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1, asl #1 \n" + "\torrpl %2, %2, %4, asl #1 \n" + "\tmovpl %0, %3 \n" + + "\tsubs %3, %0, %1 \n" + "\torrpl %2, %2, %4 \n" + "\tmovpl %0, %3 \n" + + "\tmovs %5, %5, lsr #31 \n" + "\trsbne %2, %2, #0 \n" + : "=r" (dead1), "=r" (dead2), "=r" (res), + "=r" (dead3), "=r" (dead4), "=r" (dead5) + : "0" (a), "1" (b), "2" (res) + : "memory", "cc" + ); + return res; +} + + + + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/fixed_bfin.h b/src/libs/speexdsp/libspeexdsp/fixed_bfin.h new file mode 100644 index 00000000..9eb21e33 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/fixed_bfin.h @@ -0,0 +1,176 @@ +/* Copyright (C) 2005 Analog Devices + Author: Jean-Marc Valin */ +/** + @file fixed_bfin.h + @brief Blackfin fixed-point operations +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_BFIN_H +#define FIXED_BFIN_H + +#include "bfin.h" + +#undef PDIV32_16 +static inline spx_word16_t PDIV32_16(spx_word32_t a, spx_word16_t b) +{ + spx_word32_t res, bb; + bb = b; + a += b>>1; + __asm__ ( + "P0 = 15;\n\t" + "R0 = %1;\n\t" + "R1 = %2;\n\t" + //"R0 = R0 + R1;\n\t" + "R0 <<= 1;\n\t" + "DIVS (R0, R1);\n\t" + "LOOP divide%= LC0 = P0;\n\t" + "LOOP_BEGIN divide%=;\n\t" + "DIVQ (R0, R1);\n\t" + "LOOP_END divide%=;\n\t" + "R0 = R0.L;\n\t" + "%0 = R0;\n\t" + : "=m" (res) + : "m" (a), "m" (bb) + : "P0", "R0", "R1", "ASTAT" BFIN_HWLOOP0_REGS); + return res; +} + +#undef DIV32_16 +static inline spx_word16_t DIV32_16(spx_word32_t a, spx_word16_t b) +{ + spx_word32_t res, bb; + bb = b; + /* Make the roundinf consistent with the C version + (do we need to do that?)*/ + if (a<0) + a += (b-1); + __asm__ ( + "P0 = 15;\n\t" + "R0 = %1;\n\t" + "R1 = %2;\n\t" + "R0 <<= 1;\n\t" + "DIVS (R0, R1);\n\t" + "LOOP divide%= LC0 = P0;\n\t" + "LOOP_BEGIN divide%=;\n\t" + "DIVQ (R0, R1);\n\t" + "LOOP_END divide%=;\n\t" + "R0 = R0.L;\n\t" + "%0 = R0;\n\t" + : "=m" (res) + : "m" (a), "m" (bb) + : "P0", "R0", "R1", "ASTAT" BFIN_HWLOOP0_REGS); + return res; +} + +#undef MAX16 +static inline spx_word16_t MAX16(spx_word16_t a, spx_word16_t b) +{ + spx_word32_t res; + __asm__ ( + "%1 = %1.L (X);\n\t" + "%2 = %2.L (X);\n\t" + "%0 = MAX(%1,%2);" + : "=d" (res) + : "%d" (a), "d" (b) + : "ASTAT" + ); + return res; +} + +#undef MULT16_32_Q15 +static inline spx_word32_t MULT16_32_Q15(spx_word16_t a, spx_word32_t b) +{ + spx_word32_t res; + __asm__ + ( + "A1 = %2.L*%1.L (M);\n\t" + "A1 = A1 >>> 15;\n\t" + "%0 = (A1 += %2.L*%1.H) ;\n\t" + : "=&W" (res), "=&d" (b) + : "d" (a), "1" (b) + : "A1", "ASTAT" + ); + return res; +} + +#undef MAC16_32_Q15 +static inline spx_word32_t MAC16_32_Q15(spx_word32_t c, spx_word16_t a, spx_word32_t b) +{ + spx_word32_t res; + __asm__ + ( + "A1 = %2.L*%1.L (M);\n\t" + "A1 = A1 >>> 15;\n\t" + "%0 = (A1 += %2.L*%1.H);\n\t" + "%0 = %0 + %4;\n\t" + : "=&W" (res), "=&d" (b) + : "d" (a), "1" (b), "d" (c) + : "A1", "ASTAT" + ); + return res; +} + +#undef MULT16_32_Q14 +static inline spx_word32_t MULT16_32_Q14(spx_word16_t a, spx_word32_t b) +{ + spx_word32_t res; + __asm__ + ( + "%2 <<= 1;\n\t" + "A1 = %1.L*%2.L (M);\n\t" + "A1 = A1 >>> 15;\n\t" + "%0 = (A1 += %1.L*%2.H);\n\t" + : "=W" (res), "=d" (a), "=d" (b) + : "1" (a), "2" (b) + : "A1", "ASTAT" + ); + return res; +} + +#undef MAC16_32_Q14 +static inline spx_word32_t MAC16_32_Q14(spx_word32_t c, spx_word16_t a, spx_word32_t b) +{ + spx_word32_t res; + __asm__ + ( + "%1 <<= 1;\n\t" + "A1 = %2.L*%1.L (M);\n\t" + "A1 = A1 >>> 15;\n\t" + "%0 = (A1 += %2.L*%1.H);\n\t" + "%0 = %0 + %4;\n\t" + : "=&W" (res), "=&d" (b) + : "d" (a), "1" (b), "d" (c) + : "A1", "ASTAT" + ); + return res; +} + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/fixed_debug.h b/src/libs/speexdsp/libspeexdsp/fixed_debug.h new file mode 100644 index 00000000..54f3866e --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/fixed_debug.h @@ -0,0 +1,487 @@ +/* Copyright (C) 2003 Jean-Marc Valin */ +/** + @file fixed_debug.h + @brief Fixed-point operations with debugging +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_DEBUG_H +#define FIXED_DEBUG_H + +#include <stdio.h> + +extern long long spx_mips; +#define MIPS_INC spx_mips++, + +#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) +#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) + + +#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768) +#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL) + +static inline short NEG16(int x) +{ + int res; + if (!VERIFY_SHORT(x)) + { + fprintf (stderr, "NEG16: input is not short: %d\n", (int)x); + } + res = -x; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "NEG16: output is not short: %d\n", (int)res); + spx_mips++; + return res; +} +static inline int NEG32(long long x) +{ + long long res; + if (!VERIFY_INT(x)) + { + fprintf (stderr, "NEG16: input is not int: %d\n", (int)x); + } + res = -x; + if (!VERIFY_INT(res)) + fprintf (stderr, "NEG16: output is not int: %d\n", (int)res); + spx_mips++; + return res; +} + +#define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__) +static inline short _EXTRACT16(int x, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(x)) + { + fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line); + } + res = x; + spx_mips++; + return res; +} + +#define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__) +static inline int _EXTEND32(int x, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(x)) + { + fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line); + } + res = x; + spx_mips++; + return res; +} + +#define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__) +static inline short _SHR16(int a, int shift, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) + { + fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line); + } + res = a>>shift; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line); + spx_mips++; + return res; +} +#define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__) +static inline short _SHL16(int a, int shift, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) + { + fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line); + } + res = a<<shift; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line); + spx_mips++; + return res; +} + +static inline int SHR32(long long a, int shift) +{ + long long res; + if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) + { + fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift); + } + res = a>>shift; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "SHR32: output is not int: %d\n", (int)res); + } + spx_mips++; + return res; +} +static inline int SHL32(long long a, int shift) +{ + long long res; + if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) + { + fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift); + } + res = a<<shift; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "SHL32: output is not int: %d\n", (int)res); + } + spx_mips++; + return res; +} + +#define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift)) +#define PSHR32(a,shift) (SHR32(ADD32((a),((EXTEND32(1)<<((shift))>>1))),shift)) +#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) + +#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) +#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) + +//#define SHR(a,shift) ((a) >> (shift)) +//#define SHL(a,shift) ((a) << (shift)) + +#define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__) +static inline short _ADD16(int a, int b, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); + } + res = a+b; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line); + } + spx_mips++; + return res; +} + +#define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__) +static inline short _SUB16(int a, int b, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); + } + res = a-b; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line); + spx_mips++; + return res; +} + +#define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__) +static inline int _ADD32(long long a, long long b, char *file, int line) +{ + long long res; + if (!VERIFY_INT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); + } + res = a+b; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line); + } + spx_mips++; + return res; +} + +static inline int SUB32(long long a, long long b) +{ + long long res; + if (!VERIFY_INT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int)a, (int)b); + } + res = a-b; + if (!VERIFY_INT(res)) + fprintf (stderr, "SUB32: output is not int: %d\n", (int)res); + spx_mips++; + return res; +} + +#define ADD64(a,b) (MIPS_INC(a)+(b)) + +/* result fits in 16 bits */ +static inline short MULT16_16_16(int a, int b) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b); + } + res = a*b; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res); + spx_mips++; + return res; +} + +#define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__) +static inline int _MULT16_16(int a, int b, char *file, int line) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); + } + res = ((long long)a)*b; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line); + spx_mips++; + return res; +} + +#define MAC16_16(c,a,b) (spx_mips--,ADD32((c),MULT16_16((a),(b)))) +#define MAC16_16_Q11(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11))))) +#define MAC16_16_Q13(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13))))) +#define MAC16_16_P13(c,a,b) (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13)))) + + +#define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__) +static inline int _MULT16_32_QX(int a, long long b, int Q, char *file, int line) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); + } + if (ABS32(b)>=(EXTEND32(1)<<(15+Q))) + fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); + res = (((long long)a)*(long long)b) >> Q; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line); + spx_mips+=5; + return res; +} + +static inline int MULT16_32_PX(int a, long long b, int Q) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b); + } + if (ABS32(b)>=(EXTEND32(1)<<(15+Q))) + fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q, (int)a, (int)b); + res = ((((long long)a)*(long long)b) + ((EXTEND32(1)<<Q)>>1))>> Q; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res); + spx_mips+=5; + return res; +} + + +#define MULT16_32_Q11(a,b) MULT16_32_QX(a,b,11) +#define MAC16_32_Q11(c,a,b) ADD32((c),MULT16_32_Q11((a),(b))) +#define MULT16_32_Q12(a,b) MULT16_32_QX(a,b,12) +#define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13) +#define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14) +#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15) +#define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15) +#define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b))) + +static inline int SATURATE(int a, int b) +{ + if (a>b) + a=b; + if (a<-b) + a = -b; + return a; +} + +static inline int MULT16_16_Q11_32(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res >>= 11; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res); + spx_mips+=3; + return res; +} +static inline short MULT16_16_Q13(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res >>= 13; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res); + spx_mips+=3; + return res; +} +static inline short MULT16_16_Q14(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res >>= 14; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res); + spx_mips+=3; + return res; +} +static inline short MULT16_16_Q15(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res >>= 15; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res); + } + spx_mips+=3; + return res; +} + +static inline short MULT16_16_P13(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res += 4096; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res); + res >>= 13; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res); + spx_mips+=4; + return res; +} +static inline short MULT16_16_P14(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res += 8192; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res); + res >>= 14; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res); + spx_mips+=4; + return res; +} +static inline short MULT16_16_P15(int a, int b) +{ + long long res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b); + } + res = ((long long)a)*b; + res += 16384; + if (!VERIFY_INT(res)) + fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res); + res >>= 15; + if (!VERIFY_SHORT(res)) + fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res); + spx_mips+=4; + return res; +} + +#define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__) + +static inline int _DIV32_16(long long a, long long b, char *file, int line) +{ + long long res; + if (b==0) + { + fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); + return 0; + } + if (!VERIFY_INT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); + } + res = a/b; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line); + if (res>32767) + res = 32767; + if (res<-32768) + res = -32768; + } + spx_mips+=20; + return res; +} + +#define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__) +static inline int _DIV32(long long a, long long b, char *file, int line) +{ + long long res; + if (b==0) + { + fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); + return 0; + } + + if (!VERIFY_INT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); + } + res = a/b; + if (!VERIFY_INT(res)) + fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line); + spx_mips+=36; + return res; +} +#define PDIV32(a,b) DIV32(ADD32((a),(b)>>1),b) +#define PDIV32_16(a,b) DIV32_16(ADD32((a),(b)>>1),b) + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/fixed_generic.h b/src/libs/speexdsp/libspeexdsp/fixed_generic.h new file mode 100644 index 00000000..3fb096ed --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/fixed_generic.h @@ -0,0 +1,106 @@ +/* Copyright (C) 2003 Jean-Marc Valin */ +/** + @file fixed_generic.h + @brief Generic fixed-point operations +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_GENERIC_H +#define FIXED_GENERIC_H + +#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) +#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) + +#define NEG16(x) (-(x)) +#define NEG32(x) (-(x)) +#define EXTRACT16(x) ((spx_word16_t)(x)) +#define EXTEND32(x) ((spx_word32_t)(x)) +#define SHR16(a,shift) ((a) >> (shift)) +#define SHL16(a,shift) ((a) << (shift)) +#define SHR32(a,shift) ((a) >> (shift)) +#define SHL32(a,shift) ((a) << (shift)) +#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift)) +#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift)) +#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) +#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) +#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) + +#define SHR(a,shift) ((a) >> (shift)) +#define SHL(a,shift) ((spx_word32_t)(a) << (shift)) +#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift)) +#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) + + +#define ADD16(a,b) ((spx_word16_t)((spx_word16_t)(a)+(spx_word16_t)(b))) +#define SUB16(a,b) ((spx_word16_t)(a)-(spx_word16_t)(b)) +#define ADD32(a,b) ((spx_word32_t)(a)+(spx_word32_t)(b)) +#define SUB32(a,b) ((spx_word32_t)(a)-(spx_word32_t)(b)) + + +/* result fits in 16 bits */ +#define MULT16_16_16(a,b) ((((spx_word16_t)(a))*((spx_word16_t)(b)))) + +/* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */ +#define MULT16_16(a,b) (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b))) + +#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b)))) +#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12)) +#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13)) +#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14)) + +#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)) +#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))) + +#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15)) +#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)) +#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))) + + +#define MAC16_16_Q11(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),11))) +#define MAC16_16_Q13(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),13))) +#define MAC16_16_P13(c,a,b) (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13))) + +#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11)) +#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13)) +#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14)) +#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15)) + +#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13)) +#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14)) +#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15)) + +#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15)) + +#define DIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b)))) +#define PDIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word16_t)(b)))) +#define DIV32(a,b) (((spx_word32_t)(a))/((spx_word32_t)(b))) +#define PDIV32(a,b) (((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word32_t)(b))) + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/jitter.c b/src/libs/speexdsp/libspeexdsp/jitter.c new file mode 100644 index 00000000..c4b5308f --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/jitter.c @@ -0,0 +1,842 @@ +/* Copyright (C) 2002 Jean-Marc Valin + File: speex_jitter.h + + Adaptive jitter buffer for Speex + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +/* +TODO: +- Add short-term estimate +- Defensive programming + + warn when last returned < last desired (begative buffering) + + warn if update_delay not called between get() and tick() or is called twice in a row +- Linked list structure for holding the packets instead of the current fixed-size array + + return memory to a pool + + allow pre-allocation of the pool + + optional max number of elements +- Statistics + + drift + + loss + + late + + jitter + + buffering delay +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include "arch.h" +#include "speex/speex_bits.h" +#include "speex/speex_jitter.h" +#include "os_support.h" + +#ifndef NULL +#define NULL 0 +#endif + +#define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */ + +#define TSUB(a,b) ((spx_int32_t)((a)-(b))) + +#define GT32(a,b) (((spx_int32_t)((a)-(b)))>0) +#define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0) +#define LT32(a,b) (((spx_int32_t)((a)-(b)))<0) +#define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0) + +#define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step)) + +#define MAX_TIMINGS 40 +#define MAX_BUFFERS 3 +#define TOP_DELAY 40 + +/** Buffer that keeps the time of arrival of the latest packets */ +struct TimingBuffer { + int filled; /**< Number of entries occupied in "timing" and "counts"*/ + int curr_count; /**< Number of packet timings we got (including those we discarded) */ + spx_int32_t timing[MAX_TIMINGS]; /**< Sorted list of all timings ("latest" packets first) */ + spx_int16_t counts[MAX_TIMINGS]; /**< Order the packets were put in (will be used for short-term estimate) */ +}; + +static void tb_init(struct TimingBuffer *tb) +{ + tb->filled = 0; + tb->curr_count = 0; +} + +/* Add the timing of a new packet to the TimingBuffer */ +static void tb_add(struct TimingBuffer *tb, spx_int16_t timing) +{ + int pos; + /* Discard packet that won't make it into the list because they're too early */ + if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1]) + { + tb->curr_count++; + return; + } + + /* Find where the timing info goes in the sorted list */ + pos = 0; + /* FIXME: Do bisection instead of linear search */ + while (pos<tb->filled && timing >= tb->timing[pos]) + { + pos++; + } + + speex_assert(pos <= tb->filled && pos < MAX_TIMINGS); + + /* Shift everything so we can perform the insertion */ + if (pos < tb->filled) + { + int move_size = tb->filled-pos; + if (tb->filled == MAX_TIMINGS) + move_size -= 1; + SPEEX_MOVE(&tb->timing[pos+1], &tb->timing[pos], move_size); + SPEEX_MOVE(&tb->counts[pos+1], &tb->counts[pos], move_size); + } + /* Insert */ + tb->timing[pos] = timing; + tb->counts[pos] = tb->curr_count; + + tb->curr_count++; + if (tb->filled<MAX_TIMINGS) + tb->filled++; +} + + + +/** Jitter buffer structure */ +struct JitterBuffer_ { + spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */ + spx_uint32_t last_returned_timestamp; /**< Useful for getting the next packet with the same timestamp (for fragmented media) */ + spx_uint32_t next_stop; /**< Estimated time the next get() will be called */ + + spx_int32_t buffered; /**< Amount of data we think is still buffered by the application (timestamp units)*/ + + JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packets stored in the buffer */ + spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */ + + void (*destroy) (void *); /**< Callback for destroying a packet */ + + spx_int32_t delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */ + spx_int32_t concealment_size; /**< Size of the packet loss concealment "units" */ + int reset_state; /**< True if state was just reset */ + int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */ + int late_cutoff; /**< How late must a packet be for it not to be considered at all */ + int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */ + int auto_adjust; /**< Whether to automatically adjust the delay at any time */ + + struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */ + struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */ + int window_size; /**< Total window over which the late frames are counted */ + int subwindow_size; /**< Sub-window size for faster computation */ + int max_late_rate; /**< Absolute maximum amount of late packets tolerable (in percent) */ + int latency_tradeoff; /**< Latency equivalent of losing one percent of packets */ + int auto_tradeoff; /**< Latency equivalent of losing one percent of packets (automatic default) */ + + int lost_count; /**< Number of consecutive lost packets */ +}; + +/** Based on available data, this computes the optimal delay for the jitter buffer. + The optimised function is in timestamp units and is: + cost = delay + late_factor*[number of frames that would be late if we used that delay] + @param tb Array of buffers + @param late_factor Equivalent cost of a late frame (in timestamp units) + */ +static spx_int16_t compute_opt_delay(JitterBuffer *jitter) +{ + int i; + spx_int16_t opt=0; + spx_int32_t best_cost=0x7fffffff; + int late = 0; + int pos[MAX_BUFFERS]; + int tot_count; + float late_factor; + int penalty_taken = 0; + int best = 0; + int worst = 0; + spx_int32_t deltaT; + struct TimingBuffer *tb; + + tb = jitter->_tb; + + /* Number of packet timings we have received (including those we didn't keep) */ + tot_count = 0; + for (i=0;i<MAX_BUFFERS;i++) + tot_count += tb[i].curr_count; + if (tot_count==0) + return 0; + + /* Compute cost for one lost packet */ + if (jitter->latency_tradeoff != 0) + late_factor = jitter->latency_tradeoff * 100.0f / tot_count; + else + late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count; + + /*fprintf(stderr, "late_factor = %f\n", late_factor);*/ + for (i=0;i<MAX_BUFFERS;i++) + pos[i] = 0; + + /* Pick the TOP_DELAY "latest" packets (doesn't need to actually be late + for the current settings) */ + for (i=0;i<TOP_DELAY;i++) + { + int j; + int next=-1; + int latest = 32767; + /* Pick latest amoung all sub-windows */ + for (j=0;j<MAX_BUFFERS;j++) + { + if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest) + { + next = j; + latest = tb[j].timing[pos[j]]; + } + } + if (next != -1) + { + spx_int32_t cost; + + if (i==0) + worst = latest; + best = latest; + latest = ROUND_DOWN(latest, jitter->delay_step); + pos[next]++; + + /* Actual cost function that tells us how bad using this delay would be */ + cost = -latest + late_factor*late; + /*fprintf(stderr, "cost %d = %d + %f * %d\n", cost, -latest, late_factor, late);*/ + if (cost < best_cost) + { + best_cost = cost; + opt = latest; + } + } else { + break; + } + + /* For the next timing we will consider, there will be one more late packet to count */ + late++; + /* Two-frame penalty if we're going to increase the amount of late frames (hysteresis) */ + if (latest >= 0 && !penalty_taken) + { + penalty_taken = 1; + late+=4; + } + } + + deltaT = best-worst; + /* This is a default "automatic latency tradeoff" when none is provided */ + jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY; + /*fprintf(stderr, "auto_tradeoff = %d (%d %d %d)\n", jitter->auto_tradeoff, best, worst, i);*/ + + /* FIXME: Compute a short-term estimate too and combine with the long-term one */ + + /* Prevents reducing the buffer size when we haven't really had much data */ + if (tot_count < TOP_DELAY && opt > 0) + return 0; + return opt; +} + + +/** Initialise jitter buffer */ +EXPORT JitterBuffer *jitter_buffer_init(int step_size) +{ + JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); + if (jitter) + { + int i; + spx_int32_t tmp; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + jitter->packets[i].data=NULL; + jitter->delay_step = step_size; + jitter->concealment_size = step_size; + /*FIXME: Should this be 0 or 1?*/ + jitter->buffer_margin = 0; + jitter->late_cutoff = 50; + jitter->destroy = NULL; + jitter->latency_tradeoff = 0; + jitter->auto_adjust = 1; + tmp = 4; + jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp); + jitter_buffer_reset(jitter); + } + return jitter; +} + +/** Reset jitter buffer */ +EXPORT void jitter_buffer_reset(JitterBuffer *jitter) +{ + int i; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data) + { + if (jitter->destroy) + jitter->destroy(jitter->packets[i].data); + else + speex_free(jitter->packets[i].data); + jitter->packets[i].data = NULL; + } + } + /* Timestamp is actually undefined at this point */ + jitter->pointer_timestamp = 0; + jitter->next_stop = 0; + jitter->reset_state = 1; + jitter->lost_count = 0; + jitter->buffered = 0; + jitter->auto_tradeoff = 32000; + + for (i=0;i<MAX_BUFFERS;i++) + { + tb_init(&jitter->_tb[i]); + jitter->timeBuffers[i] = &jitter->_tb[i]; + } + /*fprintf (stderr, "reset\n");*/ +} + +/** Destroy jitter buffer */ +EXPORT void jitter_buffer_destroy(JitterBuffer *jitter) +{ + jitter_buffer_reset(jitter); + speex_free(jitter); +} + +/** Take the following timing into consideration for future calculations */ +static void update_timings(JitterBuffer *jitter, spx_int32_t timing) +{ + if (timing < -32767) + timing = -32767; + if (timing > 32767) + timing = 32767; + /* If the current sub-window is full, perform a rotation and discard oldest sub-widow */ + if (jitter->timeBuffers[0]->curr_count >= jitter->subwindow_size) + { + int i; + /*fprintf(stderr, "Rotate buffer\n");*/ + struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1]; + for (i=MAX_BUFFERS-1;i>=1;i--) + jitter->timeBuffers[i] = jitter->timeBuffers[i-1]; + jitter->timeBuffers[0] = tmp; + tb_init(jitter->timeBuffers[0]); + } + tb_add(jitter->timeBuffers[0], timing); +} + +/** Compensate all timings when we do an adjustment of the buffering */ +static void shift_timings(JitterBuffer *jitter, spx_int16_t amount) +{ + int i, j; + for (i=0;i<MAX_BUFFERS;i++) + { + for (j=0;j<jitter->timeBuffers[i]->filled;j++) + jitter->timeBuffers[i]->timing[j] += amount; + } +} + + +/** Put one packet into the jitter buffer */ +EXPORT void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) +{ + int i,j; + int late; + /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ + + /* Cleanup buffer (remove old packets that weren't played) */ + if (!jitter->reset_state) + { + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */ + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp)) + { + /*fprintf (stderr, "cleaned (not played)\n");*/ + if (jitter->destroy) + jitter->destroy(jitter->packets[i].data); + else + speex_free(jitter->packets[i].data); + jitter->packets[i].data = NULL; + } + } + } + + /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/ + /* Check if packet is late (could still be useful though) */ + if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop)) + { + update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin); + late = 1; + } else { + late = 0; + } + + /* For some reason, the consumer has failed the last 20 fetches. Make sure this packet is + * used to resync. */ + if (jitter->lost_count>20) + { + jitter_buffer_reset(jitter); + } + + /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */ + if (jitter->reset_state || GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp)) + { + + /*Find an empty slot in the buffer*/ + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data==NULL) + break; + } + + /*No place left in the buffer, need to make room for it by discarding the oldest packet */ + if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) + { + int earliest=jitter->packets[0].timestamp; + i=0; + for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++) + { + if (!jitter->packets[i].data || LT32(jitter->packets[j].timestamp,earliest)) + { + earliest = jitter->packets[j].timestamp; + i=j; + } + } + if (jitter->destroy) + jitter->destroy(jitter->packets[i].data); + else + speex_free(jitter->packets[i].data); + jitter->packets[i].data=NULL; + /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ + } + + /* Copy packet in buffer */ + if (jitter->destroy) + { + jitter->packets[i].data = packet->data; + } else { + jitter->packets[i].data=(char*)speex_alloc(packet->len); + for (j=0;j<packet->len;j++) + jitter->packets[i].data[j]=packet->data[j]; + } + jitter->packets[i].timestamp=packet->timestamp; + jitter->packets[i].span=packet->span; + jitter->packets[i].len=packet->len; + jitter->packets[i].sequence=packet->sequence; + jitter->packets[i].user_data=packet->user_data; + if (jitter->reset_state || late) + jitter->arrival[i] = 0; + else + jitter->arrival[i] = jitter->next_stop; + } + + +} + +/** Get one packet from the jitter buffer */ +EXPORT int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset) +{ + int i; + unsigned int j; + int incomplete = 0; + spx_int16_t opt; + + if (start_offset != NULL) + *start_offset = 0; + + /* Syncing on the first call */ + if (jitter->reset_state) + { + int found = 0; + /* Find the oldest packet */ + spx_uint32_t oldest=0; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data && (!found || LT32(jitter->packets[i].timestamp,oldest))) + { + oldest = jitter->packets[i].timestamp; + found = 1; + } + } + if (found) + { + jitter->reset_state=0; + jitter->pointer_timestamp = oldest; + jitter->next_stop = oldest; + } else { + packet->timestamp = 0; + packet->span = jitter->interp_requested; + return JITTER_BUFFER_MISSING; + } + } + + + jitter->last_returned_timestamp = jitter->pointer_timestamp; + + if (jitter->interp_requested != 0) + { + packet->timestamp = jitter->pointer_timestamp; + packet->span = jitter->interp_requested; + + /* Increment the pointer because it got decremented in the delay update */ + jitter->pointer_timestamp += jitter->interp_requested; + packet->len = 0; + /*fprintf (stderr, "Deferred interpolate\n");*/ + + jitter->interp_requested = 0; + + jitter->buffered = packet->span - desired_span; + + return JITTER_BUFFER_INSERTION; + } + + /* Searching for the packet that fits best */ + + /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */ + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->pointer_timestamp && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span)) + break; + } + + /* If no match, try for an "older" packet that still spans (fully) the current chunk */ + if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) + { + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span)) + break; + } + } + + /* If still no match, try for an "older" packet that spans part of the current chunk */ + if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) + { + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GT32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp)) + break; + } + } + + /* If still no match, try for earliest packet possible */ + if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) + { + int found = 0; + spx_uint32_t best_time=0; + int best_span=0; + int besti=0; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + /* check if packet starts within current chunk */ + if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp)) + { + if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span))) + { + best_time = jitter->packets[i].timestamp; + best_span = jitter->packets[i].span; + besti = i; + found = 1; + } + } + } + if (found) + { + i=besti; + incomplete = 1; + /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span);*/ + } + } + + /* If we find something */ + if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) + { + spx_int32_t offset; + + /* We (obviously) haven't lost this packet */ + jitter->lost_count = 0; + + /* In this case, 0 isn't as a valid timestamp */ + if (jitter->arrival[i] != 0) + { + update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin); + } + + + /* Copy packet */ + if (jitter->destroy) + { + packet->data = jitter->packets[i].data; + packet->len = jitter->packets[i].len; + } else { + if (jitter->packets[i].len > packet->len) + { + speex_warning_int("jitter_buffer_get(): packet too large to fit. Size is", jitter->packets[i].len); + } else { + packet->len = jitter->packets[i].len; + } + for (j=0;j<packet->len;j++) + packet->data[j] = jitter->packets[i].data[j]; + /* Remove packet */ + speex_free(jitter->packets[i].data); + } + jitter->packets[i].data = NULL; + /* Set timestamp and span (if requested) */ + offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp; + if (start_offset != NULL) + *start_offset = offset; + else if (offset != 0) + speex_warning_int("jitter_buffer_get() discarding non-zero start_offset", offset); + + packet->timestamp = jitter->packets[i].timestamp; + jitter->last_returned_timestamp = packet->timestamp; + + packet->span = jitter->packets[i].span; + packet->sequence = jitter->packets[i].sequence; + packet->user_data = jitter->packets[i].user_data; + /* Point to the end of the current packet */ + jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span; + + jitter->buffered = packet->span - desired_span; + + if (start_offset != NULL) + jitter->buffered += *start_offset; + + return JITTER_BUFFER_OK; + } + + + /* If we haven't found anything worth returning */ + + /*fprintf (stderr, "not found\n");*/ + jitter->lost_count++; + /*fprintf (stderr, "m");*/ + /*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/ + + opt = compute_opt_delay(jitter); + + /* Should we force an increase in the buffer or just do normal interpolation? */ + if (opt < 0) + { + /* Need to increase buffering */ + + /* Shift histogram to compensate */ + shift_timings(jitter, -opt); + + packet->timestamp = jitter->pointer_timestamp; + packet->span = -opt; + /* Don't move the pointer_timestamp forward */ + packet->len = 0; + + jitter->buffered = packet->span - desired_span; + return JITTER_BUFFER_INSERTION; + /*jitter->pointer_timestamp -= jitter->delay_step;*/ + /*fprintf (stderr, "Forced to interpolate\n");*/ + } else { + /* Normal packet loss */ + packet->timestamp = jitter->pointer_timestamp; + + desired_span = ROUND_DOWN(desired_span, jitter->concealment_size); + packet->span = desired_span; + jitter->pointer_timestamp += desired_span; + packet->len = 0; + + jitter->buffered = packet->span - desired_span; + return JITTER_BUFFER_MISSING; + /*fprintf (stderr, "Normal loss\n");*/ + } + + +} + +EXPORT int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet) +{ + int i, j; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp) + break; + } + if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) + { + /* Copy packet */ + packet->len = jitter->packets[i].len; + if (jitter->destroy) + { + packet->data = jitter->packets[i].data; + } else { + for (j=0;j<packet->len;j++) + packet->data[j] = jitter->packets[i].data[j]; + /* Remove packet */ + speex_free(jitter->packets[i].data); + } + jitter->packets[i].data = NULL; + packet->timestamp = jitter->packets[i].timestamp; + packet->span = jitter->packets[i].span; + packet->sequence = jitter->packets[i].sequence; + packet->user_data = jitter->packets[i].user_data; + return JITTER_BUFFER_OK; + } else { + packet->data = NULL; + packet->len = 0; + packet->span = 0; + return JITTER_BUFFER_MISSING; + } +} + +/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ +static int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) +{ + spx_int16_t opt = compute_opt_delay(jitter); + /*fprintf(stderr, "opt adjustment is %d ", opt);*/ + + if (opt < 0) + { + shift_timings(jitter, -opt); + + jitter->pointer_timestamp += opt; + jitter->interp_requested = -opt; + /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/ + } else if (opt > 0) + { + shift_timings(jitter, -opt); + jitter->pointer_timestamp += opt; + /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/ + } + + return opt; +} + +/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ +EXPORT int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) +{ + /* If the programmer calls jitter_buffer_update_delay() directly, + automatically disable auto-adjustment */ + jitter->auto_adjust = 0; + + return _jitter_buffer_update_delay(jitter, packet, start_offset); +} + +/** Get pointer timestamp of jitter buffer */ +EXPORT int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) +{ + return jitter->pointer_timestamp; +} + +EXPORT void jitter_buffer_tick(JitterBuffer *jitter) +{ + /* Automatically-adjust the buffering delay if requested */ + if (jitter->auto_adjust) + _jitter_buffer_update_delay(jitter, NULL, NULL); + + if (jitter->buffered >= 0) + { + jitter->next_stop = jitter->pointer_timestamp - jitter->buffered; + } else { + jitter->next_stop = jitter->pointer_timestamp; + speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered); + } + jitter->buffered = 0; +} + +EXPORT void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) +{ + /* Automatically-adjust the buffering delay if requested */ + if (jitter->auto_adjust) + _jitter_buffer_update_delay(jitter, NULL, NULL); + + if (jitter->buffered < 0) + speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered); + jitter->next_stop = jitter->pointer_timestamp - rem; +} + + +/* Used like the ioctl function to control the jitter buffer parameters */ +EXPORT int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) +{ + int count, i; + switch(request) + { + case JITTER_BUFFER_SET_MARGIN: + jitter->buffer_margin = *(spx_int32_t*)ptr; + break; + case JITTER_BUFFER_GET_MARGIN: + *(spx_int32_t*)ptr = jitter->buffer_margin; + break; + case JITTER_BUFFER_GET_AVALIABLE_COUNT: + count = 0; + for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) + { + if (jitter->packets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp)) + { + count++; + } + } + *(spx_int32_t*)ptr = count; + break; + case JITTER_BUFFER_SET_DESTROY_CALLBACK: + jitter->destroy = (void (*) (void *))ptr; + break; + case JITTER_BUFFER_GET_DESTROY_CALLBACK: + *(void (**) (void *))ptr = jitter->destroy; + break; + case JITTER_BUFFER_SET_DELAY_STEP: + jitter->delay_step = *(spx_int32_t*)ptr; + break; + case JITTER_BUFFER_GET_DELAY_STEP: + *(spx_int32_t*)ptr = jitter->delay_step; + break; + case JITTER_BUFFER_SET_CONCEALMENT_SIZE: + jitter->concealment_size = *(spx_int32_t*)ptr; + break; + case JITTER_BUFFER_GET_CONCEALMENT_SIZE: + *(spx_int32_t*)ptr = jitter->concealment_size; + break; + case JITTER_BUFFER_SET_MAX_LATE_RATE: + jitter->max_late_rate = *(spx_int32_t*)ptr; + jitter->window_size = 100*TOP_DELAY/jitter->max_late_rate; + jitter->subwindow_size = jitter->window_size/MAX_BUFFERS; + break; + case JITTER_BUFFER_GET_MAX_LATE_RATE: + *(spx_int32_t*)ptr = jitter->max_late_rate; + break; + case JITTER_BUFFER_SET_LATE_COST: + jitter->latency_tradeoff = *(spx_int32_t*)ptr; + break; + case JITTER_BUFFER_GET_LATE_COST: + *(spx_int32_t*)ptr = jitter->latency_tradeoff; + break; + default: + speex_warning_int("Unknown jitter_buffer_ctl request: ", request); + return -1; + } + return 0; +} + diff --git a/src/libs/speexdsp/libspeexdsp/kiss_fft.c b/src/libs/speexdsp/libspeexdsp/kiss_fft.c new file mode 100644 index 00000000..bad1d10f --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/kiss_fft.c @@ -0,0 +1,523 @@ +/* +Copyright (c) 2003-2004, Mark Borgerding +Copyright (c) 2005-2007, Jean-Marc Valin + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "_kiss_fft_guts.h" +#include "arch.h" +#include "os_support.h" + +/* The guts header contains all the multiplication and addition macros that are defined for + fixed or floating point complex numbers. It also delares the kf_ internal functions. + */ + +static void kf_bfly2( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m, + int N, + int mm + ) +{ + kiss_fft_cpx * Fout2; + kiss_fft_cpx * tw1; + kiss_fft_cpx t; + if (!st->inverse) { + int i,j; + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;i<N;i++) + { + Fout = Fout_beg + i*mm; + Fout2 = Fout + m; + tw1 = st->twiddles; + for(j=0;j<m;j++) + { + /* Almost the same as the code path below, except that we divide the input by two + (while keeping the best accuracy possible) */ + spx_word32_t tr, ti; + tr = SHR32(SUB32(MULT16_16(Fout2->r , tw1->r),MULT16_16(Fout2->i , tw1->i)), 1); + ti = SHR32(ADD32(MULT16_16(Fout2->i , tw1->r),MULT16_16(Fout2->r , tw1->i)), 1); + tw1 += fstride; + Fout2->r = PSHR32(SUB32(SHL32(EXTEND32(Fout->r), 14), tr), 15); + Fout2->i = PSHR32(SUB32(SHL32(EXTEND32(Fout->i), 14), ti), 15); + Fout->r = PSHR32(ADD32(SHL32(EXTEND32(Fout->r), 14), tr), 15); + Fout->i = PSHR32(ADD32(SHL32(EXTEND32(Fout->i), 14), ti), 15); + ++Fout2; + ++Fout; + } + } + } else { + int i,j; + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;i<N;i++) + { + Fout = Fout_beg + i*mm; + Fout2 = Fout + m; + tw1 = st->twiddles; + for(j=0;j<m;j++) + { + C_MUL (t, *Fout2 , *tw1); + tw1 += fstride; + C_SUB( *Fout2 , *Fout , t ); + C_ADDTO( *Fout , t ); + ++Fout2; + ++Fout; + } + } + } +} + +static void kf_bfly4( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m, + int N, + int mm + ) +{ + kiss_fft_cpx *tw1,*tw2,*tw3; + kiss_fft_cpx scratch[6]; + const size_t m2=2*m; + const size_t m3=3*m; + int i, j; + + if (st->inverse) + { + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;i<N;i++) + { + Fout = Fout_beg + i*mm; + tw3 = tw2 = tw1 = st->twiddles; + for (j=0;j<m;j++) + { + C_MUL(scratch[0],Fout[m] , *tw1 ); + C_MUL(scratch[1],Fout[m2] , *tw2 ); + C_MUL(scratch[2],Fout[m3] , *tw3 ); + + C_SUB( scratch[5] , *Fout, scratch[1] ); + C_ADDTO(*Fout, scratch[1]); + C_ADD( scratch[3] , scratch[0] , scratch[2] ); + C_SUB( scratch[4] , scratch[0] , scratch[2] ); + C_SUB( Fout[m2], *Fout, scratch[3] ); + tw1 += fstride; + tw2 += fstride*2; + tw3 += fstride*3; + C_ADDTO( *Fout , scratch[3] ); + + Fout[m].r = scratch[5].r - scratch[4].i; + Fout[m].i = scratch[5].i + scratch[4].r; + Fout[m3].r = scratch[5].r + scratch[4].i; + Fout[m3].i = scratch[5].i - scratch[4].r; + ++Fout; + } + } + } else + { + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;i<N;i++) + { + Fout = Fout_beg + i*mm; + tw3 = tw2 = tw1 = st->twiddles; + for (j=0;j<m;j++) + { + C_MUL4(scratch[0],Fout[m] , *tw1 ); + C_MUL4(scratch[1],Fout[m2] , *tw2 ); + C_MUL4(scratch[2],Fout[m3] , *tw3 ); + + Fout->r = PSHR16(Fout->r, 2); + Fout->i = PSHR16(Fout->i, 2); + C_SUB( scratch[5] , *Fout, scratch[1] ); + C_ADDTO(*Fout, scratch[1]); + C_ADD( scratch[3] , scratch[0] , scratch[2] ); + C_SUB( scratch[4] , scratch[0] , scratch[2] ); + Fout[m2].r = PSHR16(Fout[m2].r, 2); + Fout[m2].i = PSHR16(Fout[m2].i, 2); + C_SUB( Fout[m2], *Fout, scratch[3] ); + tw1 += fstride; + tw2 += fstride*2; + tw3 += fstride*3; + C_ADDTO( *Fout , scratch[3] ); + + Fout[m].r = scratch[5].r + scratch[4].i; + Fout[m].i = scratch[5].i - scratch[4].r; + Fout[m3].r = scratch[5].r - scratch[4].i; + Fout[m3].i = scratch[5].i + scratch[4].r; + ++Fout; + } + } + } +} + +static void kf_bfly3( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + size_t m + ) +{ + size_t k=m; + const size_t m2 = 2*m; + kiss_fft_cpx *tw1,*tw2; + kiss_fft_cpx scratch[5]; + kiss_fft_cpx epi3; + epi3 = st->twiddles[fstride*m]; + + tw1=tw2=st->twiddles; + + do{ + if (!st->inverse) { + C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); + } + + C_MUL(scratch[1],Fout[m] , *tw1); + C_MUL(scratch[2],Fout[m2] , *tw2); + + C_ADD(scratch[3],scratch[1],scratch[2]); + C_SUB(scratch[0],scratch[1],scratch[2]); + tw1 += fstride; + tw2 += fstride*2; + + Fout[m].r = Fout->r - HALF_OF(scratch[3].r); + Fout[m].i = Fout->i - HALF_OF(scratch[3].i); + + C_MULBYSCALAR( scratch[0] , epi3.i ); + + C_ADDTO(*Fout,scratch[3]); + + Fout[m2].r = Fout[m].r + scratch[0].i; + Fout[m2].i = Fout[m].i - scratch[0].r; + + Fout[m].r -= scratch[0].i; + Fout[m].i += scratch[0].r; + + ++Fout; + }while(--k); +} + +static void kf_bfly5( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m + ) +{ + kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; + int u; + kiss_fft_cpx scratch[13]; + kiss_fft_cpx * twiddles = st->twiddles; + kiss_fft_cpx *tw; + kiss_fft_cpx ya,yb; + ya = twiddles[fstride*m]; + yb = twiddles[fstride*2*m]; + + Fout0=Fout; + Fout1=Fout0+m; + Fout2=Fout0+2*m; + Fout3=Fout0+3*m; + Fout4=Fout0+4*m; + + tw=st->twiddles; + for ( u=0; u<m; ++u ) { + if (!st->inverse) { + C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5); + } + scratch[0] = *Fout0; + + C_MUL(scratch[1] ,*Fout1, tw[u*fstride]); + C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]); + C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]); + C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]); + + C_ADD( scratch[7],scratch[1],scratch[4]); + C_SUB( scratch[10],scratch[1],scratch[4]); + C_ADD( scratch[8],scratch[2],scratch[3]); + C_SUB( scratch[9],scratch[2],scratch[3]); + + Fout0->r += scratch[7].r + scratch[8].r; + Fout0->i += scratch[7].i + scratch[8].i; + + scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); + scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); + + scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); + scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); + + C_SUB(*Fout1,scratch[5],scratch[6]); + C_ADD(*Fout4,scratch[5],scratch[6]); + + scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); + scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); + scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); + scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); + + C_ADD(*Fout2,scratch[11],scratch[12]); + C_SUB(*Fout3,scratch[11],scratch[12]); + + ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; + } +} + +/* perform the butterfly for one stage of a mixed radix FFT */ +static void kf_bfly_generic( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m, + int p + ) +{ + int u,k,q1,q; + kiss_fft_cpx * twiddles = st->twiddles; + kiss_fft_cpx t; + kiss_fft_cpx scratchbuf[17]; + int Norig = st->nfft; + + /*CHECKBUF(scratchbuf,nscratchbuf,p);*/ + if (p>17) + speex_fatal("KissFFT: max radix supported is 17"); + + for ( u=0; u<m; ++u ) { + k=u; + for ( q1=0 ; q1<p ; ++q1 ) { + scratchbuf[q1] = Fout[ k ]; + if (!st->inverse) { + C_FIXDIV(scratchbuf[q1],p); + } + k += m; + } + + k=u; + for ( q1=0 ; q1<p ; ++q1 ) { + int twidx=0; + Fout[ k ] = scratchbuf[0]; + for (q=1;q<p;++q ) { + twidx += fstride * k; + if (twidx>=Norig) twidx-=Norig; + C_MUL(t,scratchbuf[q] , twiddles[twidx] ); + C_ADDTO( Fout[ k ] ,t); + } + k += m; + } + } +} + +static +void kf_shuffle( + kiss_fft_cpx * Fout, + const kiss_fft_cpx * f, + const size_t fstride, + int in_stride, + int * factors, + const kiss_fft_cfg st + ) +{ + const int p=*factors++; /* the radix */ + const int m=*factors++; /* stage's fft length/p */ + + /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/ + if (m==1) + { + int j; + for (j=0;j<p;j++) + { + Fout[j] = *f; + f += fstride*in_stride; + } + } else { + int j; + for (j=0;j<p;j++) + { + kf_shuffle( Fout , f, fstride*p, in_stride, factors,st); + f += fstride*in_stride; + Fout += m; + } + } +} + +static +void kf_work( + kiss_fft_cpx * Fout, + const kiss_fft_cpx * f, + const size_t fstride, + int in_stride, + int * factors, + const kiss_fft_cfg st, + int N, + int s2, + int m2 + ) +{ + int i; + kiss_fft_cpx * Fout_beg=Fout; + const int p=*factors++; /* the radix */ + const int m=*factors++; /* stage's fft length/p */ +#if 0 + /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/ + if (m==1) + { + /* int j; + for (j=0;j<p;j++) + { + Fout[j] = *f; + f += fstride*in_stride; + }*/ + } else { + int j; + for (j=0;j<p;j++) + { + kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m); + f += fstride*in_stride; + Fout += m; + } + } + + Fout=Fout_beg; + + switch (p) { + case 2: kf_bfly2(Fout,fstride,st,m); break; + case 3: kf_bfly3(Fout,fstride,st,m); break; + case 4: kf_bfly4(Fout,fstride,st,m); break; + case 5: kf_bfly5(Fout,fstride,st,m); break; + default: kf_bfly_generic(Fout,fstride,st,m,p); break; + } +#else + /*printf ("fft %d %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N, m2);*/ + if (m==1) + { + /*for (i=0;i<N;i++) + { + int j; + Fout = Fout_beg+i*m2; + const kiss_fft_cpx * f2 = f+i*s2; + for (j=0;j<p;j++) + { + *Fout++ = *f2; + f2 += fstride*in_stride; + } + }*/ + }else{ + kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m); + } + + + + + switch (p) { + case 2: kf_bfly2(Fout,fstride,st,m, N, m2); break; + case 3: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly3(Fout,fstride,st,m);} break; + case 4: kf_bfly4(Fout,fstride,st,m, N, m2); break; + case 5: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly5(Fout,fstride,st,m);} break; + default: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly_generic(Fout,fstride,st,m,p);} break; + } +#endif +} + +/* facbuf is populated by p1,m1,p2,m2, ... + where + p[i] * m[i] = m[i-1] + m0 = n */ +static +void kf_factor(int n,int * facbuf) +{ + int p=4; + + /*factor out powers of 4, powers of 2, then any remaining primes */ + do { + while (n % p) { + switch (p) { + case 4: p = 2; break; + case 2: p = 3; break; + default: p += 2; break; + } + if (p>32000 || (spx_int32_t)p*(spx_int32_t)p > n) + p = n; /* no more factors, skip to end */ + } + n /= p; + *facbuf++ = p; + *facbuf++ = n; + } while (n > 1); +} +/* + * + * User-callable function to allocate all necessary storage space for the fft. + * + * The return value is a contiguous block of memory, allocated with malloc. As such, + * It can be freed with free(), rather than a kiss_fft-specific function. + * */ +kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem ) +{ + kiss_fft_cfg st=NULL; + size_t memneeded = sizeof(struct kiss_fft_state) + + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/ + + if ( lenmem==NULL ) { + st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded ); + }else{ + if (mem != NULL && *lenmem >= memneeded) + st = (kiss_fft_cfg)mem; + *lenmem = memneeded; + } + if (st) { + int i; + st->nfft=nfft; + st->inverse = inverse_fft; +#ifdef FIXED_POINT + for (i=0;i<nfft;++i) { + spx_word32_t phase = i; + if (!st->inverse) + phase = -phase; + kf_cexp2(st->twiddles+i, DIV32(SHL32(phase,17),nfft)); + } +#else + for (i=0;i<nfft;++i) { + const double pi=3.14159265358979323846264338327; + double phase = ( -2*pi /nfft ) * i; + if (st->inverse) + phase *= -1; + kf_cexp(st->twiddles+i, phase ); + } +#endif + kf_factor(nfft,st->factors); + } + return st; +} + + + + +void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) +{ + if (fin == fout) + { + speex_fatal("In-place FFT not supported"); + /*CHECKBUF(tmpbuf,ntmpbuf,st->nfft); + kf_work(tmpbuf,fin,1,in_stride, st->factors,st); + SPEEX_MOVE(fout,tmpbuf,st->nfft);*/ + } else { + kf_shuffle( fout, fin, 1,in_stride, st->factors,st); + kf_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1); + } +} + +void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) +{ + kiss_fft_stride(cfg,fin,fout,1); +} + diff --git a/src/libs/speexdsp/libspeexdsp/kiss_fft.h b/src/libs/speexdsp/libspeexdsp/kiss_fft.h new file mode 100644 index 00000000..fa3f2c60 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/kiss_fft.h @@ -0,0 +1,108 @@ +#ifndef KISS_FFT_H +#define KISS_FFT_H + +#include <stdlib.h> +#include <math.h> +#include "arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + ATTENTION! + If you would like a : + -- a utility that will handle the caching of fft objects + -- real-only (no imaginary time component ) FFT + -- a multi-dimensional FFT + -- a command-line utility to perform ffts + -- a command-line utility to perform fast-convolution filtering + + Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c + in the tools/ directory. +*/ + +#ifdef USE_SIMD +# include <xmmintrin.h> +# define kiss_fft_scalar __m128 +#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes) +#else +#define KISS_FFT_MALLOC speex_alloc +#endif + + +#ifdef FIXED_POINT +#include "arch.h" +# define kiss_fft_scalar spx_int16_t +#else +# ifndef kiss_fft_scalar +/* default is float */ +# define kiss_fft_scalar float +# endif +#endif + +typedef struct { + kiss_fft_scalar r; + kiss_fft_scalar i; +}kiss_fft_cpx; + +typedef struct kiss_fft_state* kiss_fft_cfg; + +/* + * kiss_fft_alloc + * + * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. + * + * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); + * + * The return value from fft_alloc is a cfg buffer used internally + * by the fft routine or NULL. + * + * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. + * The returned value should be free()d when done to avoid memory leaks. + * + * The state can be placed in a user supplied buffer 'mem': + * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, + * then the function places the cfg in mem and the size used in *lenmem + * and returns mem. + * + * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), + * then the function returns NULL and places the minimum cfg + * buffer size in *lenmem. + * */ + +kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); + +/* + * kiss_fft(cfg,in_out_buf) + * + * Perform an FFT on a complex input buffer. + * for a forward FFT, + * fin should be f[0] , f[1] , ... ,f[nfft-1] + * fout will be F[0] , F[1] , ... ,F[nfft-1] + * Note that each element is complex and can be accessed like + f[k].r and f[k].i + * */ +void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); + +/* + A more generic version of the above function. It reads its input from every Nth sample. + * */ +void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); + +/* If kiss_fft_alloc allocated a buffer, it is one contiguous + buffer and can be simply free()d when no longer needed*/ +#define kiss_fft_free speex_free + +/* + Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up + your compiler output to call this before you exit. +*/ +void kiss_fft_cleanup(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/kiss_fftr.c b/src/libs/speexdsp/libspeexdsp/kiss_fftr.c new file mode 100644 index 00000000..f6275b87 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/kiss_fftr.c @@ -0,0 +1,297 @@ +/* +Copyright (c) 2003-2004, Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "os_support.h" +#include "kiss_fftr.h" +#include "_kiss_fft_guts.h" + +struct kiss_fftr_state{ + kiss_fft_cfg substate; + kiss_fft_cpx * tmpbuf; + kiss_fft_cpx * super_twiddles; +#ifdef USE_SIMD + long pad; +#endif +}; + +kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem) +{ + int i; + kiss_fftr_cfg st = NULL; + size_t subsize, memneeded; + + if (nfft & 1) { + speex_warning("Real FFT optimization must be even.\n"); + return NULL; + } + nfft >>= 1; + + kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize); + memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 2); + + if (lenmem == NULL) { + st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded); + } else { + if (*lenmem >= memneeded) + st = (kiss_fftr_cfg) mem; + *lenmem = memneeded; + } + if (!st) + return NULL; + + st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */ + st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize); + st->super_twiddles = st->tmpbuf + nfft; + kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); + +#ifdef FIXED_POINT + for (i=0;i<nfft;++i) { + spx_word32_t phase = i+(nfft>>1); + if (!inverse_fft) + phase = -phase; + kf_cexp2(st->super_twiddles+i, DIV32(SHL32(phase,16),nfft)); + } +#else + for (i=0;i<nfft;++i) { + const double pi=3.14159265358979323846264338327; + double phase = pi*(((double)i) /nfft + .5); + if (!inverse_fft) + phase = -phase; + kf_cexp(st->super_twiddles+i, phase ); + } +#endif + return st; +} + +void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata) +{ + /* input buffer timedata is stored row-wise */ + int k,ncfft; + kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; + + if ( st->substate->inverse) { + speex_fatal("kiss fft usage error: improper alloc\n"); + } + + ncfft = st->substate->nfft; + + /*perform the parallel fft of two real signals packed in real,imag*/ + kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); + /* The real part of the DC element of the frequency spectrum in st->tmpbuf + * contains the sum of the even-numbered elements of the input time sequence + * The imag part is the sum of the odd-numbered elements + * + * The sum of tdc.r and tdc.i is the sum of the input time sequence. + * yielding DC of input time sequence + * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... + * yielding Nyquist bin of input time sequence + */ + + tdc.r = st->tmpbuf[0].r; + tdc.i = st->tmpbuf[0].i; + C_FIXDIV(tdc,2); + CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); + CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); + freqdata[0].r = tdc.r + tdc.i; + freqdata[ncfft].r = tdc.r - tdc.i; +#ifdef USE_SIMD + freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0); +#else + freqdata[ncfft].i = freqdata[0].i = 0; +#endif + + for ( k=1;k <= ncfft/2 ; ++k ) { + fpk = st->tmpbuf[k]; + fpnk.r = st->tmpbuf[ncfft-k].r; + fpnk.i = - st->tmpbuf[ncfft-k].i; + C_FIXDIV(fpk,2); + C_FIXDIV(fpnk,2); + + C_ADD( f1k, fpk , fpnk ); + C_SUB( f2k, fpk , fpnk ); + C_MUL( tw , f2k , st->super_twiddles[k]); + + freqdata[k].r = HALF_OF(f1k.r + tw.r); + freqdata[k].i = HALF_OF(f1k.i + tw.i); + freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r); + freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i); + } +} + +void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata, kiss_fft_scalar *timedata) +{ + /* input buffer timedata is stored row-wise */ + int k, ncfft; + + if (st->substate->inverse == 0) { + speex_fatal("kiss fft usage error: improper alloc\n"); + } + + ncfft = st->substate->nfft; + + st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; + st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; + /*C_FIXDIV(st->tmpbuf[0],2);*/ + + for (k = 1; k <= ncfft / 2; ++k) { + kiss_fft_cpx fk, fnkc, fek, fok, tmp; + fk = freqdata[k]; + fnkc.r = freqdata[ncfft - k].r; + fnkc.i = -freqdata[ncfft - k].i; + /*C_FIXDIV( fk , 2 ); + C_FIXDIV( fnkc , 2 );*/ + + C_ADD (fek, fk, fnkc); + C_SUB (tmp, fk, fnkc); + C_MUL (fok, tmp, st->super_twiddles[k]); + C_ADD (st->tmpbuf[k], fek, fok); + C_SUB (st->tmpbuf[ncfft - k], fek, fok); +#ifdef USE_SIMD + st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); +#else + st->tmpbuf[ncfft - k].i *= -1; +#endif + } + kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); +} + +void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata) +{ + /* input buffer timedata is stored row-wise */ + int k,ncfft; + kiss_fft_cpx f2k,tdc; + spx_word32_t f1kr, f1ki, twr, twi; + + if ( st->substate->inverse) { + speex_fatal("kiss fft usage error: improper alloc\n"); + } + + ncfft = st->substate->nfft; + + /*perform the parallel fft of two real signals packed in real,imag*/ + kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); + /* The real part of the DC element of the frequency spectrum in st->tmpbuf + * contains the sum of the even-numbered elements of the input time sequence + * The imag part is the sum of the odd-numbered elements + * + * The sum of tdc.r and tdc.i is the sum of the input time sequence. + * yielding DC of input time sequence + * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... + * yielding Nyquist bin of input time sequence + */ + + tdc.r = st->tmpbuf[0].r; + tdc.i = st->tmpbuf[0].i; + C_FIXDIV(tdc,2); + CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); + CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); + freqdata[0] = tdc.r + tdc.i; + freqdata[2*ncfft-1] = tdc.r - tdc.i; + + for ( k=1;k <= ncfft/2 ; ++k ) + { + /*fpk = st->tmpbuf[k]; + fpnk.r = st->tmpbuf[ncfft-k].r; + fpnk.i = - st->tmpbuf[ncfft-k].i; + C_FIXDIV(fpk,2); + C_FIXDIV(fpnk,2); + + C_ADD( f1k, fpk , fpnk ); + C_SUB( f2k, fpk , fpnk ); + + C_MUL( tw , f2k , st->super_twiddles[k]); + + freqdata[2*k-1] = HALF_OF(f1k.r + tw.r); + freqdata[2*k] = HALF_OF(f1k.i + tw.i); + freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r); + freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i); + */ + + /*f1k.r = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1); + f1k.i = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1); + f2k.r = PSHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1); + f2k.i = SHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1); + + C_MUL( tw , f2k , st->super_twiddles[k]); + + freqdata[2*k-1] = HALF_OF(f1k.r + tw.r); + freqdata[2*k] = HALF_OF(f1k.i + tw.i); + freqdata[2*(ncfft-k)-1] = HALF_OF(f1k.r - tw.r); + freqdata[2*(ncfft-k)] = HALF_OF(tw.i - f1k.i); + */ + f2k.r = SHR32(SUB32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),1); + f2k.i = PSHR32(ADD32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),1); + + f1kr = SHL32(ADD32(EXTEND32(st->tmpbuf[k].r), EXTEND32(st->tmpbuf[ncfft-k].r)),13); + f1ki = SHL32(SUB32(EXTEND32(st->tmpbuf[k].i), EXTEND32(st->tmpbuf[ncfft-k].i)),13); + + twr = SHR32(SUB32(MULT16_16(f2k.r,st->super_twiddles[k].r),MULT16_16(f2k.i,st->super_twiddles[k].i)), 1); + twi = SHR32(ADD32(MULT16_16(f2k.i,st->super_twiddles[k].r),MULT16_16(f2k.r,st->super_twiddles[k].i)), 1); + +#ifdef FIXED_POINT + freqdata[2*k-1] = PSHR32(f1kr + twr, 15); + freqdata[2*k] = PSHR32(f1ki + twi, 15); + freqdata[2*(ncfft-k)-1] = PSHR32(f1kr - twr, 15); + freqdata[2*(ncfft-k)] = PSHR32(twi - f1ki, 15); +#else + freqdata[2*k-1] = .5f*(f1kr + twr); + freqdata[2*k] = .5f*(f1ki + twi); + freqdata[2*(ncfft-k)-1] = .5f*(f1kr - twr); + freqdata[2*(ncfft-k)] = .5f*(twi - f1ki); + +#endif + } +} + +void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata,kiss_fft_scalar *timedata) +{ + /* input buffer timedata is stored row-wise */ + int k, ncfft; + + if (st->substate->inverse == 0) { + speex_fatal ("kiss fft usage error: improper alloc\n"); + } + + ncfft = st->substate->nfft; + + st->tmpbuf[0].r = freqdata[0] + freqdata[2*ncfft-1]; + st->tmpbuf[0].i = freqdata[0] - freqdata[2*ncfft-1]; + /*C_FIXDIV(st->tmpbuf[0],2);*/ + + for (k = 1; k <= ncfft / 2; ++k) { + kiss_fft_cpx fk, fnkc, fek, fok, tmp; + fk.r = freqdata[2*k-1]; + fk.i = freqdata[2*k]; + fnkc.r = freqdata[2*(ncfft - k)-1]; + fnkc.i = -freqdata[2*(ncfft - k)]; + /*C_FIXDIV( fk , 2 ); + C_FIXDIV( fnkc , 2 );*/ + + C_ADD (fek, fk, fnkc); + C_SUB (tmp, fk, fnkc); + C_MUL (fok, tmp, st->super_twiddles[k]); + C_ADD (st->tmpbuf[k], fek, fok); + C_SUB (st->tmpbuf[ncfft - k], fek, fok); +#ifdef USE_SIMD + st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); +#else + st->tmpbuf[ncfft - k].i *= -1; +#endif + } + kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); +} diff --git a/src/libs/speexdsp/libspeexdsp/kiss_fftr.h b/src/libs/speexdsp/libspeexdsp/kiss_fftr.h new file mode 100644 index 00000000..7bfb4233 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/kiss_fftr.h @@ -0,0 +1,51 @@ +#ifndef KISS_FTR_H +#define KISS_FTR_H + +#include "kiss_fft.h" +#ifdef __cplusplus +extern "C" { +#endif + + +/* + + Real optimized version can save about 45% cpu time vs. complex fft of a real seq. + + + + */ + +typedef struct kiss_fftr_state *kiss_fftr_cfg; + + +kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem); +/* + nfft must be even + + If you don't care to allocate space, use mem = lenmem = NULL +*/ + + +void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata); +/* + input timedata has nfft scalar points + output freqdata has nfft/2+1 complex points +*/ + +void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata); + +void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata); + +void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata, kiss_fft_scalar *timedata); + +/* + input freqdata has nfft/2+1 complex points + output timedata has nfft scalar points +*/ + +#define kiss_fftr_free speex_free + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/libs/speexdsp/libspeexdsp/math_approx.h b/src/libs/speexdsp/libspeexdsp/math_approx.h new file mode 100644 index 00000000..de3b0edf --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/math_approx.h @@ -0,0 +1,336 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file math_approx.h + @brief Various math approximation functions for Speex +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef MATH_APPROX_H +#define MATH_APPROX_H + +#include "arch.h" + +#ifdef TARGET_WIN +# define inline __inline +#endif + +#ifndef FIXED_POINT + +#define spx_sqrt sqrt +#define spx_acos acos +#define spx_exp exp +#define spx_cos_norm(x) (cos((.5f*M_PI)*(x))) +#define spx_atan atan + +/** Generate a pseudo-random number */ +static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed) +{ + const unsigned int jflone = 0x3f800000; + const unsigned int jflmsk = 0x007fffff; + union {int i; float f;} ran; + *seed = 1664525 * *seed + 1013904223; + ran.i = jflone | (jflmsk & *seed); + ran.f -= 1.5; + return 3.4642*std*ran.f; +} + + +#endif + + +static inline spx_int16_t spx_ilog2(spx_uint32_t x) +{ + int r=0; + if (x>=(spx_int32_t)65536) + { + x >>= 16; + r += 16; + } + if (x>=256) + { + x >>= 8; + r += 8; + } + if (x>=16) + { + x >>= 4; + r += 4; + } + if (x>=4) + { + x >>= 2; + r += 2; + } + if (x>=2) + { + r += 1; + } + return r; +} + +static inline spx_int16_t spx_ilog4(spx_uint32_t x) +{ + int r=0; + if (x>=(spx_int32_t)65536) + { + x >>= 16; + r += 8; + } + if (x>=256) + { + x >>= 8; + r += 4; + } + if (x>=16) + { + x >>= 4; + r += 2; + } + if (x>=4) + { + r += 1; + } + return r; +} + +#ifdef FIXED_POINT + +/** Generate a pseudo-random number */ +static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed) +{ + spx_word32_t res; + *seed = 1664525 * *seed + 1013904223; + res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std); + return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14)); +} + +/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */ +/*#define C0 3634 +#define C1 21173 +#define C2 -12627 +#define C3 4215*/ + +/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */ +#define C0 3634 +#define C1 21173 +#define C2 -12627 +#define C3 4204 + +static inline spx_word16_t spx_sqrt(spx_word32_t x) +{ + int k; + spx_word32_t rt; + k = spx_ilog4(x)-6; + x = VSHR32(x, (k<<1)); + rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3))))))); + rt = VSHR32(rt,7-k); + return rt; +} + +/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */ + + +#define A1 16469 +#define A2 2242 +#define A3 1486 + +static inline spx_word16_t spx_acos(spx_word16_t x) +{ + int s=0; + spx_word16_t ret; + spx_word16_t sq; + if (x<0) + { + s=1; + x = NEG16(x); + } + x = SUB16(16384,x); + + x = x >> 1; + sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3)))))); + ret = spx_sqrt(SHL32(EXTEND32(sq),13)); + + /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/ + if (s) + ret = SUB16(25736,ret); + return ret; +} + + +#define K1 8192 +#define K2 -4096 +#define K3 340 +#define K4 -10 + +static inline spx_word16_t spx_cos(spx_word16_t x) +{ + spx_word16_t x2; + + if (x<12868) + { + x2 = MULT16_16_P13(x,x); + return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2)))))); + } else { + x = SUB16(25736,x); + x2 = MULT16_16_P13(x,x); + return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2)))))); + } +} + +#define L1 32767 +#define L2 -7651 +#define L3 8277 +#define L4 -626 + +static inline spx_word16_t _spx_cos_pi_2(spx_word16_t x) +{ + spx_word16_t x2; + + x2 = MULT16_16_P15(x,x); + return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2)))))))); +} + +static inline spx_word16_t spx_cos_norm(spx_word32_t x) +{ + x = x&0x0001ffff; + if (x>SHL32(EXTEND32(1), 16)) + x = SUB32(SHL32(EXTEND32(1), 17),x); + if (x&0x00007fff) + { + if (x<SHL32(EXTEND32(1), 15)) + { + return _spx_cos_pi_2(EXTRACT16(x)); + } else { + return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x))); + } + } else { + if (x&0x0000ffff) + return 0; + else if (x&0x0001ffff) + return -32767; + else + return 32767; + } +} + +/* + K0 = 1 + K1 = log(2) + K2 = 3-4*log(2) + K3 = 3*log(2) - 2 +*/ +#define D0 16384 +#define D1 11356 +#define D2 3726 +#define D3 1301 +/* Input in Q11 format, output in Q16 */ +static inline spx_word32_t spx_exp2(spx_word16_t x) +{ + int integer; + spx_word16_t frac; + integer = SHR16(x,11); + if (integer>14) + return 0x7fffffff; + else if (integer < -15) + return 0; + frac = SHL16(x-SHL16(integer,11),3); + frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac)))))); + return VSHR32(EXTEND32(frac), -integer-2); +} + +/* Input in Q11 format, output in Q16 */ +static inline spx_word32_t spx_exp(spx_word16_t x) +{ + if (x>21290) + return 0x7fffffff; + else if (x<-21290) + return 0; + else + return spx_exp2(MULT16_16_P14(23637,x)); +} +#define M1 32767 +#define M2 -21 +#define M3 -11943 +#define M4 4936 + +static inline spx_word16_t spx_atan01(spx_word16_t x) +{ + return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x))))))); +} + +#undef M1 +#undef M2 +#undef M3 +#undef M4 + +/* Input in Q15, output in Q14 */ +static inline spx_word16_t spx_atan(spx_word32_t x) +{ + if (x <= 32767) + { + return SHR16(spx_atan01(x),1); + } else { + int e = spx_ilog2(x); + if (e>=29) + return 25736; + x = DIV32_16(SHL32(EXTEND32(32767),29-e), EXTRACT16(SHR32(x, e-14))); + return SUB16(25736, SHR16(spx_atan01(x),1)); + } +} +#else + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + +#define C1 0.9999932946f +#define C2 -0.4999124376f +#define C3 0.0414877472f +#define C4 -0.0012712095f + + +#define SPX_PI_2 1.5707963268 +static inline spx_word16_t spx_cos(spx_word16_t x) +{ + if (x<SPX_PI_2) + { + x *= x; + return C1 + x*(C2+x*(C3+C4*x)); + } else { + x = M_PI-x; + x *= x; + return NEG16(C1 + x*(C2+x*(C3+C4*x))); + } +} + +#endif + + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/mdf.c b/src/libs/speexdsp/libspeexdsp/mdf.c new file mode 100644 index 00000000..9d128bf8 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/mdf.c @@ -0,0 +1,1286 @@ +/* Copyright (C) 2003-2008 Jean-Marc Valin + + File: mdf.c + Echo canceller based on the MDF algorithm (see below) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + The echo canceller is based on the MDF algorithm described in: + + J. S. Soo, K. K. Pang Multidelay block frequency adaptive filter, + IEEE Trans. Acoust. Speech Signal Process., Vol. ASSP-38, No. 2, + February 1990. + + We use the Alternatively Updated MDF (AUMDF) variant. Robustness to + double-talk is achieved using a variable learning rate as described in: + + Valin, J.-M., On Adjusting the Learning Rate in Frequency Domain Echo + Cancellation With Double-Talk. IEEE Transactions on Audio, + Speech and Language Processing, Vol. 15, No. 3, pp. 1030-1034, 2007. + http://people.xiph.org/~jm/papers/valin_taslp2006.pdf + + There is no explicit double-talk detection, but a continuous variation + in the learning rate based on residual echo, double-talk and background + noise. + + About the fixed-point version: + All the signals are represented with 16-bit words. The filter weights + are represented with 32-bit words, but only the top 16 bits are used + in most cases. The lower 16 bits are completely unreliable (due to the + fact that the update is done only on the top bits), but help in the + adaptation -- probably by removing a "threshold effect" due to + quantization (rounding going to zero) when the gradient is small. + + Another kludge that seems to work good: when performing the weight + update, we only move half the way toward the "goal" this seems to + reduce the effect of quantization noise in the update phase. This + can be seen as applying a gradient descent on a "soft constraint" + instead of having a hard constraint. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "arch.h" +#include "speex/speex_echo.h" +#include "fftwrap.h" +#include "pseudofloat.h" +#include "math_approx.h" +#include "os_support.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifdef FIXED_POINT +#define WEIGHT_SHIFT 11 +#define NORMALIZE_SCALEDOWN 5 +#define NORMALIZE_SCALEUP 3 +#else +#define WEIGHT_SHIFT 0 +#endif + +#ifdef FIXED_POINT +#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x))) +#else +#define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x)))) +#endif + +/* If enabled, the AEC will use a foreground filter and a background filter to be more robust to double-talk + and difficult signals in general. The cost is an extra FFT and a matrix-vector multiply */ +#define TWO_PATH + +#ifdef FIXED_POINT +static const spx_float_t MIN_LEAK = {20972, -22}; + +/* Constants for the two-path filter */ +static const spx_float_t VAR1_SMOOTH = {23593, -16}; +static const spx_float_t VAR2_SMOOTH = {23675, -15}; +static const spx_float_t VAR1_UPDATE = {16384, -15}; +static const spx_float_t VAR2_UPDATE = {16384, -16}; +static const spx_float_t VAR_BACKTRACK = {16384, -12}; +#define TOP16(x) ((x)>>16) + +#else + +static const spx_float_t MIN_LEAK = .005f; + +/* Constants for the two-path filter */ +static const spx_float_t VAR1_SMOOTH = .36f; +static const spx_float_t VAR2_SMOOTH = .7225f; +static const spx_float_t VAR1_UPDATE = .5f; +static const spx_float_t VAR2_UPDATE = .25f; +static const spx_float_t VAR_BACKTRACK = 4.f; +#define TOP16(x) (x) +#endif + + +#define PLAYBACK_DELAY 2 + +void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len); + + +/** Speex echo cancellation state. */ +struct SpeexEchoState_ { + int frame_size; /**< Number of samples processed each time */ + int window_size; + int M; + int cancel_count; + int adapted; + int saturated; + int screwed_up; + int C; /** Number of input channels (microphones) */ + int K; /** Number of output channels (loudspeakers) */ + spx_int32_t sampling_rate; + spx_word16_t spec_average; + spx_word16_t beta0; + spx_word16_t beta_max; + spx_word32_t sum_adapt; + spx_word16_t leak_estimate; + + spx_word16_t *e; /* scratch */ + spx_word16_t *x; /* Far-end input buffer (2N) */ + spx_word16_t *X; /* Far-end buffer (M+1 frames) in frequency domain */ + spx_word16_t *input; /* scratch */ + spx_word16_t *y; /* scratch */ + spx_word16_t *last_y; + spx_word16_t *Y; /* scratch */ + spx_word16_t *E; + spx_word32_t *PHI; /* scratch */ + spx_word32_t *W; /* (Background) filter weights */ +#ifdef TWO_PATH + spx_word16_t *foreground; /* Foreground filter weights */ + spx_word32_t Davg1; /* 1st recursive average of the residual power difference */ + spx_word32_t Davg2; /* 2nd recursive average of the residual power difference */ + spx_float_t Dvar1; /* Estimated variance of 1st estimator */ + spx_float_t Dvar2; /* Estimated variance of 2nd estimator */ +#endif + spx_word32_t *power; /* Power of the far-end signal */ + spx_float_t *power_1;/* Inverse power of far-end */ + spx_word16_t *wtmp; /* scratch */ +#ifdef FIXED_POINT + spx_word16_t *wtmp2; /* scratch */ +#endif + spx_word32_t *Rf; /* scratch */ + spx_word32_t *Yf; /* scratch */ + spx_word32_t *Xf; /* scratch */ + spx_word32_t *Eh; + spx_word32_t *Yh; + spx_float_t Pey; + spx_float_t Pyy; + spx_word16_t *window; + spx_word16_t *prop; + void *fft_table; + spx_word16_t *memX, *memD, *memE; + spx_word16_t preemph; + spx_word16_t notch_radius; + spx_mem_t *notch_mem; + + /* NOTE: If you only use speex_echo_cancel() and want to save some memory, remove this */ + spx_int16_t *play_buf; + int play_buf_pos; + int play_buf_started; +}; + +static inline void filter_dc_notch16(const spx_int16_t *in, spx_word16_t radius, spx_word16_t *out, int len, spx_mem_t *mem, int stride) +{ + int i; + spx_word16_t den2; +#ifdef FIXED_POINT + den2 = MULT16_16_Q15(radius,radius) + MULT16_16_Q15(QCONST16(.7,15),MULT16_16_Q15(32767-radius,32767-radius)); +#else + den2 = radius*radius + .7*(1-radius)*(1-radius); +#endif + /*printf ("%d %d %d %d %d %d\n", num[0], num[1], num[2], den[0], den[1], den[2]);*/ + for (i=0;i<len;i++) + { + spx_word16_t vin = in[i*stride]; + spx_word32_t vout = mem[0] + SHL32(EXTEND32(vin),15); +#ifdef FIXED_POINT + mem[0] = mem[1] + SHL32(SHL32(-EXTEND32(vin),15) + MULT16_32_Q15(radius,vout),1); +#else + mem[0] = mem[1] + 2*(-vin + radius*vout); +#endif + mem[1] = SHL32(EXTEND32(vin),15) - MULT16_32_Q15(den2,vout); + out[i] = SATURATE32(PSHR32(MULT16_32_Q15(radius,vout),15),32767); + } +} + +/* This inner product is slightly different from the codec version because of fixed-point */ +static inline spx_word32_t mdf_inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) +{ + spx_word32_t sum=0; + len >>= 1; + while(len--) + { + spx_word32_t part=0; + part = MAC16_16(part,*x++,*y++); + part = MAC16_16(part,*x++,*y++); + /* HINT: If you had a 40-bit accumulator, you could shift only at the end */ + sum = ADD32(sum,SHR32(part,6)); + } + return sum; +} + +/** Compute power spectrum of a half-complex (packed) vector */ +static inline void power_spectrum(const spx_word16_t *X, spx_word32_t *ps, int N) +{ + int i, j; + ps[0]=MULT16_16(X[0],X[0]); + for (i=1,j=1;i<N-1;i+=2,j++) + { + ps[j] = MULT16_16(X[i],X[i]) + MULT16_16(X[i+1],X[i+1]); + } + ps[j]=MULT16_16(X[i],X[i]); +} + +/** Compute power spectrum of a half-complex (packed) vector and accumulate */ +static inline void power_spectrum_accum(const spx_word16_t *X, spx_word32_t *ps, int N) +{ + int i, j; + ps[0]+=MULT16_16(X[0],X[0]); + for (i=1,j=1;i<N-1;i+=2,j++) + { + ps[j] += MULT16_16(X[i],X[i]) + MULT16_16(X[i+1],X[i+1]); + } + ps[j]+=MULT16_16(X[i],X[i]); +} + +/** Compute cross-power spectrum of a half-complex (packed) vectors and add to acc */ +#ifdef FIXED_POINT +static inline void spectral_mul_accum(const spx_word16_t *X, const spx_word32_t *Y, spx_word16_t *acc, int N, int M) +{ + int i,j; + spx_word32_t tmp1=0,tmp2=0; + for (j=0;j<M;j++) + { + tmp1 = MAC16_16(tmp1, X[j*N],TOP16(Y[j*N])); + } + acc[0] = PSHR32(tmp1,WEIGHT_SHIFT); + for (i=1;i<N-1;i+=2) + { + tmp1 = tmp2 = 0; + for (j=0;j<M;j++) + { + tmp1 = SUB32(MAC16_16(tmp1, X[j*N+i],TOP16(Y[j*N+i])), MULT16_16(X[j*N+i+1],TOP16(Y[j*N+i+1]))); + tmp2 = MAC16_16(MAC16_16(tmp2, X[j*N+i+1],TOP16(Y[j*N+i])), X[j*N+i], TOP16(Y[j*N+i+1])); + } + acc[i] = PSHR32(tmp1,WEIGHT_SHIFT); + acc[i+1] = PSHR32(tmp2,WEIGHT_SHIFT); + } + tmp1 = tmp2 = 0; + for (j=0;j<M;j++) + { + tmp1 = MAC16_16(tmp1, X[(j+1)*N-1],TOP16(Y[(j+1)*N-1])); + } + acc[N-1] = PSHR32(tmp1,WEIGHT_SHIFT); +} +static inline void spectral_mul_accum16(const spx_word16_t *X, const spx_word16_t *Y, spx_word16_t *acc, int N, int M) +{ + int i,j; + spx_word32_t tmp1=0,tmp2=0; + for (j=0;j<M;j++) + { + tmp1 = MAC16_16(tmp1, X[j*N],Y[j*N]); + } + acc[0] = PSHR32(tmp1,WEIGHT_SHIFT); + for (i=1;i<N-1;i+=2) + { + tmp1 = tmp2 = 0; + for (j=0;j<M;j++) + { + tmp1 = SUB32(MAC16_16(tmp1, X[j*N+i],Y[j*N+i]), MULT16_16(X[j*N+i+1],Y[j*N+i+1])); + tmp2 = MAC16_16(MAC16_16(tmp2, X[j*N+i+1],Y[j*N+i]), X[j*N+i], Y[j*N+i+1]); + } + acc[i] = PSHR32(tmp1,WEIGHT_SHIFT); + acc[i+1] = PSHR32(tmp2,WEIGHT_SHIFT); + } + tmp1 = tmp2 = 0; + for (j=0;j<M;j++) + { + tmp1 = MAC16_16(tmp1, X[(j+1)*N-1],Y[(j+1)*N-1]); + } + acc[N-1] = PSHR32(tmp1,WEIGHT_SHIFT); +} + +#else +static inline void spectral_mul_accum(const spx_word16_t *X, const spx_word32_t *Y, spx_word16_t *acc, int N, int M) +{ + int i,j; + for (i=0;i<N;i++) + acc[i] = 0; + for (j=0;j<M;j++) + { + acc[0] += X[0]*Y[0]; + for (i=1;i<N-1;i+=2) + { + acc[i] += (X[i]*Y[i] - X[i+1]*Y[i+1]); + acc[i+1] += (X[i+1]*Y[i] + X[i]*Y[i+1]); + } + acc[i] += X[i]*Y[i]; + X += N; + Y += N; + } +} +#define spectral_mul_accum16 spectral_mul_accum +#endif + +/** Compute weighted cross-power spectrum of a half-complex (packed) vector with conjugate */ +static inline void weighted_spectral_mul_conj(const spx_float_t *w, const spx_float_t p, const spx_word16_t *X, const spx_word16_t *Y, spx_word32_t *prod, int N) +{ + int i, j; + spx_float_t W; + W = FLOAT_AMULT(p, w[0]); + prod[0] = FLOAT_MUL32(W,MULT16_16(X[0],Y[0])); + for (i=1,j=1;i<N-1;i+=2,j++) + { + W = FLOAT_AMULT(p, w[j]); + prod[i] = FLOAT_MUL32(W,MAC16_16(MULT16_16(X[i],Y[i]), X[i+1],Y[i+1])); + prod[i+1] = FLOAT_MUL32(W,MAC16_16(MULT16_16(-X[i+1],Y[i]), X[i],Y[i+1])); + } + W = FLOAT_AMULT(p, w[j]); + prod[i] = FLOAT_MUL32(W,MULT16_16(X[i],Y[i])); +} + +static inline void mdf_adjust_prop(const spx_word32_t *W, int N, int M, int P, spx_word16_t *prop) +{ + int i, j, p; + spx_word16_t max_sum = 1; + spx_word32_t prop_sum = 1; + for (i=0;i<M;i++) + { + spx_word32_t tmp = 1; + for (p=0;p<P;p++) + for (j=0;j<N;j++) + tmp += MULT16_16(EXTRACT16(SHR32(W[p*N*M + i*N+j],18)), EXTRACT16(SHR32(W[p*N*M + i*N+j],18))); +#ifdef FIXED_POINT + /* Just a security in case an overflow were to occur */ + tmp = MIN32(ABS32(tmp), 536870912); +#endif + prop[i] = spx_sqrt(tmp); + if (prop[i] > max_sum) + max_sum = prop[i]; + } + for (i=0;i<M;i++) + { + prop[i] += MULT16_16_Q15(QCONST16(.1f,15),max_sum); + prop_sum += EXTEND32(prop[i]); + } + for (i=0;i<M;i++) + { + prop[i] = DIV32(MULT16_16(QCONST16(.99f,15), prop[i]),prop_sum); + /*printf ("%f ", prop[i]);*/ + } + /*printf ("\n");*/ +} + +#ifdef DUMP_ECHO_CANCEL_DATA +#include <stdio.h> +static FILE *rFile=NULL, *pFile=NULL, *oFile=NULL; + +static void dump_audio(const spx_int16_t *rec, const spx_int16_t *play, const spx_int16_t *out, int len) +{ + if (!(rFile && pFile && oFile)) + { + speex_fatal("Dump files not open"); + } + fwrite(rec, sizeof(spx_int16_t), len, rFile); + fwrite(play, sizeof(spx_int16_t), len, pFile); + fwrite(out, sizeof(spx_int16_t), len, oFile); +} +#endif + +/** Creates a new echo canceller state */ +EXPORT SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length) +{ + return speex_echo_state_init_mc(frame_size, filter_length, 1, 1); +} + +EXPORT SpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_length, int nb_mic, int nb_speakers) +{ + int i,N,M, C, K; + SpeexEchoState *st = (SpeexEchoState *)speex_alloc(sizeof(SpeexEchoState)); + + st->K = nb_speakers; + st->C = nb_mic; + C=st->C; + K=st->K; +#ifdef DUMP_ECHO_CANCEL_DATA + if (rFile || pFile || oFile) + speex_fatal("Opening dump files twice"); + rFile = fopen("aec_rec.sw", "wb"); + pFile = fopen("aec_play.sw", "wb"); + oFile = fopen("aec_out.sw", "wb"); +#endif + + st->frame_size = frame_size; + st->window_size = 2*frame_size; + N = st->window_size; + M = st->M = (filter_length+st->frame_size-1)/frame_size; + st->cancel_count=0; + st->sum_adapt = 0; + st->saturated = 0; + st->screwed_up = 0; + /* This is the default sampling rate */ + st->sampling_rate = 8000; + st->spec_average = DIV32_16(SHL32(EXTEND32(st->frame_size), 15), st->sampling_rate); +#ifdef FIXED_POINT + st->beta0 = DIV32_16(SHL32(EXTEND32(st->frame_size), 16), st->sampling_rate); + st->beta_max = DIV32_16(SHL32(EXTEND32(st->frame_size), 14), st->sampling_rate); +#else + st->beta0 = (2.0f*st->frame_size)/st->sampling_rate; + st->beta_max = (.5f*st->frame_size)/st->sampling_rate; +#endif + st->leak_estimate = 0; + + st->fft_table = spx_fft_init(N); + + st->e = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->x = (spx_word16_t*)speex_alloc(K*N*sizeof(spx_word16_t)); + st->input = (spx_word16_t*)speex_alloc(C*st->frame_size*sizeof(spx_word16_t)); + st->y = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->last_y = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->Yf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); + st->Rf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); + st->Xf = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); + st->Yh = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); + st->Eh = (spx_word32_t*)speex_alloc((st->frame_size+1)*sizeof(spx_word32_t)); + + st->X = (spx_word16_t*)speex_alloc(K*(M+1)*N*sizeof(spx_word16_t)); + st->Y = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->E = (spx_word16_t*)speex_alloc(C*N*sizeof(spx_word16_t)); + st->W = (spx_word32_t*)speex_alloc(C*K*M*N*sizeof(spx_word32_t)); +#ifdef TWO_PATH + st->foreground = (spx_word16_t*)speex_alloc(M*N*C*K*sizeof(spx_word16_t)); +#endif + st->PHI = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); + st->power = (spx_word32_t*)speex_alloc((frame_size+1)*sizeof(spx_word32_t)); + st->power_1 = (spx_float_t*)speex_alloc((frame_size+1)*sizeof(spx_float_t)); + st->window = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); + st->prop = (spx_word16_t*)speex_alloc(M*sizeof(spx_word16_t)); + st->wtmp = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); +#ifdef FIXED_POINT + st->wtmp2 = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t)); + for (i=0;i<N>>1;i++) + { + st->window[i] = (16383-SHL16(spx_cos(DIV32_16(MULT16_16(25736,i<<1),N)),1)); + st->window[N-i-1] = st->window[i]; + } +#else + for (i=0;i<N;i++) + st->window[i] = .5-.5*cos(2*M_PI*i/N); +#endif + for (i=0;i<=st->frame_size;i++) + st->power_1[i] = FLOAT_ONE; + for (i=0;i<N*M*K*C;i++) + st->W[i] = 0; + { + spx_word32_t sum = 0; + /* Ratio of ~10 between adaptation rate of first and last block */ + spx_word16_t decay = SHR32(spx_exp(NEG16(DIV32_16(QCONST16(2.4,11),M))),1); + st->prop[0] = QCONST16(.7, 15); + sum = EXTEND32(st->prop[0]); + for (i=1;i<M;i++) + { + st->prop[i] = MULT16_16_Q15(st->prop[i-1], decay); + sum = ADD32(sum, EXTEND32(st->prop[i])); + } + for (i=M-1;i>=0;i--) + { + st->prop[i] = DIV32(MULT16_16(QCONST16(.8f,15), st->prop[i]),sum); + } + } + + st->memX = (spx_word16_t*)speex_alloc(K*sizeof(spx_word16_t)); + st->memD = (spx_word16_t*)speex_alloc(C*sizeof(spx_word16_t)); + st->memE = (spx_word16_t*)speex_alloc(C*sizeof(spx_word16_t)); + st->preemph = QCONST16(.9,15); + if (st->sampling_rate<12000) + st->notch_radius = QCONST16(.9, 15); + else if (st->sampling_rate<24000) + st->notch_radius = QCONST16(.982, 15); + else + st->notch_radius = QCONST16(.992, 15); + + st->notch_mem = (spx_mem_t*)speex_alloc(2*C*sizeof(spx_mem_t)); + st->adapted = 0; + st->Pey = st->Pyy = FLOAT_ONE; + +#ifdef TWO_PATH + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; +#endif + + st->play_buf = (spx_int16_t*)speex_alloc(K*(PLAYBACK_DELAY+1)*st->frame_size*sizeof(spx_int16_t)); + st->play_buf_pos = PLAYBACK_DELAY*st->frame_size; + st->play_buf_started = 0; + + return st; +} + +/** Resets echo canceller state */ +EXPORT void speex_echo_state_reset(SpeexEchoState *st) +{ + int i, M, N, C, K; + st->cancel_count=0; + st->screwed_up = 0; + N = st->window_size; + M = st->M; + C=st->C; + K=st->K; + for (i=0;i<N*M;i++) + st->W[i] = 0; +#ifdef TWO_PATH + for (i=0;i<N*M;i++) + st->foreground[i] = 0; +#endif + for (i=0;i<N*(M+1);i++) + st->X[i] = 0; + for (i=0;i<=st->frame_size;i++) + { + st->power[i] = 0; + st->power_1[i] = FLOAT_ONE; + st->Eh[i] = 0; + st->Yh[i] = 0; + } + for (i=0;i<st->frame_size;i++) + { + st->last_y[i] = 0; + } + for (i=0;i<N*C;i++) + { + st->E[i] = 0; + } + for (i=0;i<N*K;i++) + { + st->x[i] = 0; + } + for (i=0;i<2*C;i++) + st->notch_mem[i] = 0; + for (i=0;i<C;i++) + st->memD[i]=st->memE[i]=0; + for (i=0;i<K;i++) + st->memX[i]=0; + + st->saturated = 0; + st->adapted = 0; + st->sum_adapt = 0; + st->Pey = st->Pyy = FLOAT_ONE; +#ifdef TWO_PATH + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; +#endif + for (i=0;i<3*st->frame_size;i++) + st->play_buf[i] = 0; + st->play_buf_pos = PLAYBACK_DELAY*st->frame_size; + st->play_buf_started = 0; + +} + +/** Destroys an echo canceller state */ +EXPORT void speex_echo_state_destroy(SpeexEchoState *st) +{ + // RESOLVE problem with FFT ! + //spx_fft_destroy(st->fft_table); + + speex_free(st->e); + speex_free(st->x); + speex_free(st->input); + speex_free(st->y); + speex_free(st->last_y); + speex_free(st->Yf); + speex_free(st->Rf); + speex_free(st->Xf); + speex_free(st->Yh); + speex_free(st->Eh); + + speex_free(st->X); + speex_free(st->Y); + speex_free(st->E); + speex_free(st->W); +#ifdef TWO_PATH + speex_free(st->foreground); +#endif + speex_free(st->PHI); + speex_free(st->power); + speex_free(st->power_1); + speex_free(st->window); + speex_free(st->prop); + speex_free(st->wtmp); +#ifdef FIXED_POINT + speex_free(st->wtmp2); +#endif + speex_free(st->memX); + speex_free(st->memD); + speex_free(st->memE); + speex_free(st->notch_mem); + + speex_free(st->play_buf); + speex_free(st); + +#ifdef DUMP_ECHO_CANCEL_DATA + fclose(rFile); + fclose(pFile); + fclose(oFile); + rFile = pFile = oFile = NULL; +#endif +} + +EXPORT void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out) +{ + int i; + /*speex_warning_int("capture with fill level ", st->play_buf_pos/st->frame_size);*/ + st->play_buf_started = 1; + if (st->play_buf_pos>=st->frame_size) + { + speex_echo_cancellation(st, rec, st->play_buf, out); + st->play_buf_pos -= st->frame_size; + for (i=0;i<st->play_buf_pos;i++) + st->play_buf[i] = st->play_buf[i+st->frame_size]; + } else { + speex_warning("No playback frame available (your application is buggy and/or got xruns)"); + if (st->play_buf_pos!=0) + { + speex_warning("internal playback buffer corruption?"); + st->play_buf_pos = 0; + } + for (i=0;i<st->frame_size;i++) + out[i] = rec[i]; + } +} + +EXPORT void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play) +{ + /*speex_warning_int("playback with fill level ", st->play_buf_pos/st->frame_size);*/ + if (!st->play_buf_started) + { + speex_warning("discarded first playback frame"); + return; + } + if (st->play_buf_pos<=PLAYBACK_DELAY*st->frame_size) + { + int i; + for (i=0;i<st->frame_size;i++) + st->play_buf[st->play_buf_pos+i] = play[i]; + st->play_buf_pos += st->frame_size; + if (st->play_buf_pos <= (PLAYBACK_DELAY-1)*st->frame_size) + { + speex_warning("Auto-filling the buffer (your application is buggy and/or got xruns)"); + for (i=0;i<st->frame_size;i++) + st->play_buf[st->play_buf_pos+i] = play[i]; + st->play_buf_pos += st->frame_size; + } + } else { + speex_warning("Had to discard a playback frame (your application is buggy and/or got xruns)"); + } +} + +/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */ +EXPORT void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout) +{ + speex_echo_cancellation(st, in, far_end, out); +} + +/** Performs echo cancellation on a frame */ +EXPORT void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out) +{ + int i,j, chan, speak; + int N,M, C, K; + spx_word32_t Syy,See,Sxx,Sdd, Sff; +#ifdef TWO_PATH + spx_word32_t Dbf; + int update_foreground; +#endif + spx_word32_t Sey; + spx_word16_t ss, ss_1; + spx_float_t Pey = FLOAT_ONE, Pyy=FLOAT_ONE; + spx_float_t alpha, alpha_1; + spx_word16_t RER; + spx_word32_t tmp32; + + N = st->window_size; + M = st->M; + C = st->C; + K = st->K; + + st->cancel_count++; +#ifdef FIXED_POINT + ss=DIV32_16(11469,M); + ss_1 = SUB16(32767,ss); +#else + ss=.35/M; + ss_1 = 1-ss; +#endif + + for (chan = 0; chan < C; chan++) + { + /* Apply a notch filter to make sure DC doesn't end up causing problems */ + filter_dc_notch16(in+chan, st->notch_radius, st->input+chan*st->frame_size, st->frame_size, st->notch_mem+2*chan, C); + /* Copy input data to buffer and apply pre-emphasis */ + /* Copy input data to buffer */ + for (i=0;i<st->frame_size;i++) + { + spx_word32_t tmp32; + /* FIXME: This core has changed a bit, need to merge properly */ + tmp32 = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(MULT16_16_P15(st->preemph, st->memD[chan]))); +#ifdef FIXED_POINT + if (tmp32 > 32767) + { + tmp32 = 32767; + if (st->saturated == 0) + st->saturated = 1; + } + if (tmp32 < -32767) + { + tmp32 = -32767; + if (st->saturated == 0) + st->saturated = 1; + } +#endif + st->memD[chan] = st->input[chan*st->frame_size+i]; + st->input[chan*st->frame_size+i] = EXTRACT16(tmp32); + } + } + + for (speak = 0; speak < K; speak++) + { + for (i=0;i<st->frame_size;i++) + { + spx_word32_t tmp32; + st->x[speak*N+i] = st->x[speak*N+i+st->frame_size]; + tmp32 = SUB32(EXTEND32(far_end[i*K+speak]), EXTEND32(MULT16_16_P15(st->preemph, st->memX[speak]))); +#ifdef FIXED_POINT + /*FIXME: If saturation occurs here, we need to freeze adaptation for M frames (not just one) */ + if (tmp32 > 32767) + { + tmp32 = 32767; + st->saturated = M+1; + } + if (tmp32 < -32767) + { + tmp32 = -32767; + st->saturated = M+1; + } +#endif + st->x[speak*N+i+st->frame_size] = EXTRACT16(tmp32); + st->memX[speak] = far_end[i*K+speak]; + } + } + + for (speak = 0; speak < K; speak++) + { + /* Shift memory: this could be optimized eventually*/ + for (j=M-1;j>=0;j--) + { + for (i=0;i<N;i++) + st->X[(j+1)*N*K+speak*N+i] = st->X[j*N*K+speak*N+i]; + } + /* Convert x (echo input) to frequency domain */ + spx_fft(st->fft_table, st->x+speak*N, &st->X[speak*N]); + } + + Sxx = 0; + for (speak = 0; speak < K; speak++) + { + Sxx += mdf_inner_prod(st->x+speak*N+st->frame_size, st->x+speak*N+st->frame_size, st->frame_size); + power_spectrum_accum(st->X+speak*N, st->Xf, N); + } + + Sff = 0; + for (chan = 0; chan < C; chan++) + { +#ifdef TWO_PATH + /* Compute foreground filter */ + spectral_mul_accum16(st->X, st->foreground+chan*N*K*M, st->Y+chan*N, N, M*K); + spx_ifft(st->fft_table, st->Y+chan*N, st->e+chan*N); + for (i=0;i<st->frame_size;i++) + st->e[chan*N+i] = SUB16(st->input[chan*st->frame_size+i], st->e[chan*N+i+st->frame_size]); + Sff += mdf_inner_prod(st->e+chan*N, st->e+chan*N, st->frame_size); +#endif + } + + /* Adjust proportional adaption rate */ + /* FIXME: Adjust that for C, K*/ + if (st->adapted) + mdf_adjust_prop (st->W, N, M, C*K, st->prop); + /* Compute weight gradient */ + if (st->saturated == 0) + { + for (chan = 0; chan < C; chan++) + { + for (speak = 0; speak < K; speak++) + { + for (j=M-1;j>=0;j--) + { + weighted_spectral_mul_conj(st->power_1, FLOAT_SHL(PSEUDOFLOAT(st->prop[j]),-15), &st->X[(j+1)*N*K+speak*N], st->E+chan*N, st->PHI, N); + for (i=0;i<N;i++) + st->W[chan*N*K*M + j*N*K + speak*N + i] += st->PHI[i]; + } + } + } + } else { + st->saturated--; + } + + /* FIXME: MC conversion required */ + /* Update weight to prevent circular convolution (MDF / AUMDF) */ + for (chan = 0; chan < C; chan++) + { + for (speak = 0; speak < K; speak++) + { + for (j=0;j<M;j++) + { + /* This is a variant of the Alternatively Updated MDF (AUMDF) */ + /* Remove the "if" to make this an MDF filter */ + if (j==0 || st->cancel_count%(M-1) == j-1) + { +#ifdef FIXED_POINT + for (i=0;i<N;i++) + st->wtmp2[i] = EXTRACT16(PSHR32(st->W[chan*N*K*M + j*N*K + speak*N + i],NORMALIZE_SCALEDOWN+16)); + spx_ifft(st->fft_table, st->wtmp2, st->wtmp); + for (i=0;i<st->frame_size;i++) + { + st->wtmp[i]=0; + } + for (i=st->frame_size;i<N;i++) + { + st->wtmp[i]=SHL16(st->wtmp[i],NORMALIZE_SCALEUP); + } + spx_fft(st->fft_table, st->wtmp, st->wtmp2); + /* The "-1" in the shift is a sort of kludge that trades less efficient update speed for decrease noise */ + for (i=0;i<N;i++) + st->W[chan*N*K*M + j*N*K + speak*N + i] -= SHL32(EXTEND32(st->wtmp2[i]),16+NORMALIZE_SCALEDOWN-NORMALIZE_SCALEUP-1); +#else + spx_ifft(st->fft_table, &st->W[chan*N*K*M + j*N*K + speak*N], st->wtmp); + for (i=st->frame_size;i<N;i++) + { + st->wtmp[i]=0; + } + spx_fft(st->fft_table, st->wtmp, &st->W[chan*N*K*M + j*N*K + speak*N]); +#endif + } + } + } + } + + /* So we can use power_spectrum_accum */ + for (i=0;i<=st->frame_size;i++) + st->Rf[i] = st->Yf[i] = st->Xf[i] = 0; + + Dbf = 0; + See = 0; +#ifdef TWO_PATH + /* Difference in response, this is used to estimate the variance of our residual power estimate */ + for (chan = 0; chan < C; chan++) + { + spectral_mul_accum(st->X, st->W+chan*N*K*M, st->Y+chan*N, N, M*K); + spx_ifft(st->fft_table, st->Y+chan*N, st->y+chan*N); + for (i=0;i<st->frame_size;i++) + st->e[chan*N+i] = SUB16(st->e[chan*N+i+st->frame_size], st->y[chan*N+i+st->frame_size]); + Dbf += 10+mdf_inner_prod(st->e+chan*N, st->e+chan*N, st->frame_size); + for (i=0;i<st->frame_size;i++) + st->e[chan*N+i] = SUB16(st->input[chan*st->frame_size+i], st->y[chan*N+i+st->frame_size]); + See += mdf_inner_prod(st->e+chan*N, st->e+chan*N, st->frame_size); + } +#endif + +#ifndef TWO_PATH + Sff = See; +#endif + +#ifdef TWO_PATH + /* Logic for updating the foreground filter */ + + /* For two time windows, compute the mean of the energy difference, as well as the variance */ + st->Davg1 = ADD32(MULT16_32_Q15(QCONST16(.6f,15),st->Davg1), MULT16_32_Q15(QCONST16(.4f,15),SUB32(Sff,See))); + st->Davg2 = ADD32(MULT16_32_Q15(QCONST16(.85f,15),st->Davg2), MULT16_32_Q15(QCONST16(.15f,15),SUB32(Sff,See))); + st->Dvar1 = FLOAT_ADD(FLOAT_MULT(VAR1_SMOOTH, st->Dvar1), FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.4f,15),Sff), MULT16_32_Q15(QCONST16(.4f,15),Dbf))); + st->Dvar2 = FLOAT_ADD(FLOAT_MULT(VAR2_SMOOTH, st->Dvar2), FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.15f,15),Sff), MULT16_32_Q15(QCONST16(.15f,15),Dbf))); + + /* Equivalent float code: + st->Davg1 = .6*st->Davg1 + .4*(Sff-See); + st->Davg2 = .85*st->Davg2 + .15*(Sff-See); + st->Dvar1 = .36*st->Dvar1 + .16*Sff*Dbf; + st->Dvar2 = .7225*st->Dvar2 + .0225*Sff*Dbf; + */ + + update_foreground = 0; + /* Check if we have a statistically significant reduction in the residual echo */ + /* Note that this is *not* Gaussian, so we need to be careful about the longer tail */ + if (FLOAT_GT(FLOAT_MUL32U(SUB32(Sff,See),ABS32(SUB32(Sff,See))), FLOAT_MUL32U(Sff,Dbf))) + update_foreground = 1; + else if (FLOAT_GT(FLOAT_MUL32U(st->Davg1, ABS32(st->Davg1)), FLOAT_MULT(VAR1_UPDATE,(st->Dvar1)))) + update_foreground = 1; + else if (FLOAT_GT(FLOAT_MUL32U(st->Davg2, ABS32(st->Davg2)), FLOAT_MULT(VAR2_UPDATE,(st->Dvar2)))) + update_foreground = 1; + + /* Do we update? */ + if (update_foreground) + { + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; + /* Copy background filter to foreground filter */ + for (i=0;i<N*M*C*K;i++) + st->foreground[i] = EXTRACT16(PSHR32(st->W[i],16)); + /* Apply a smooth transition so as to not introduce blocking artifacts */ + for (chan = 0; chan < C; chan++) + for (i=0;i<st->frame_size;i++) + st->e[chan*N+i+st->frame_size] = MULT16_16_Q15(st->window[i+st->frame_size],st->e[chan*N+i+st->frame_size]) + MULT16_16_Q15(st->window[i],st->y[chan*N+i+st->frame_size]); + } else { + int reset_background=0; + /* Otherwise, check if the background filter is significantly worse */ + if (FLOAT_GT(FLOAT_MUL32U(NEG32(SUB32(Sff,See)),ABS32(SUB32(Sff,See))), FLOAT_MULT(VAR_BACKTRACK,FLOAT_MUL32U(Sff,Dbf)))) + reset_background = 1; + if (FLOAT_GT(FLOAT_MUL32U(NEG32(st->Davg1), ABS32(st->Davg1)), FLOAT_MULT(VAR_BACKTRACK,st->Dvar1))) + reset_background = 1; + if (FLOAT_GT(FLOAT_MUL32U(NEG32(st->Davg2), ABS32(st->Davg2)), FLOAT_MULT(VAR_BACKTRACK,st->Dvar2))) + reset_background = 1; + if (reset_background) + { + /* Copy foreground filter to background filter */ + for (i=0;i<N*M*C*K;i++) + st->W[i] = SHL32(EXTEND32(st->foreground[i]),16); + /* We also need to copy the output so as to get correct adaptation */ + for (chan = 0; chan < C; chan++) + { + for (i=0;i<st->frame_size;i++) + st->y[chan*N+i+st->frame_size] = st->e[chan*N+i+st->frame_size]; + for (i=0;i<st->frame_size;i++) + st->e[chan*N+i] = SUB16(st->input[chan*st->frame_size+i], st->y[chan*N+i+st->frame_size]); + } + See = Sff; + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; + } + } +#endif + + Sey = Syy = Sdd = 0; + for (chan = 0; chan < C; chan++) + { + /* Compute error signal (for the output with de-emphasis) */ + for (i=0;i<st->frame_size;i++) + { + spx_word32_t tmp_out; +#ifdef TWO_PATH + tmp_out = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(st->e[chan*N+i+st->frame_size])); +#else + tmp_out = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(st->y[chan*N+i+st->frame_size])); +#endif + tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE[chan]))); + /* This is an arbitrary test for saturation in the microphone signal */ + if (in[i*C+chan] <= -32000 || in[i*C+chan] >= 32000) + { + if (st->saturated == 0) + st->saturated = 1; + } + out[i*C+chan] = WORD2INT(tmp_out); + st->memE[chan] = tmp_out; + } + +#ifdef DUMP_ECHO_CANCEL_DATA + dump_audio(in, far_end, out, st->frame_size); +#endif + + /* Compute error signal (filter update version) */ + for (i=0;i<st->frame_size;i++) + { + st->e[chan*N+i+st->frame_size] = st->e[chan*N+i]; + st->e[chan*N+i] = 0; + } + + /* Compute a bunch of correlations */ + /* FIXME: bad merge */ + Sey += mdf_inner_prod(st->e+chan*N+st->frame_size, st->y+chan*N+st->frame_size, st->frame_size); + Syy += mdf_inner_prod(st->y+chan*N+st->frame_size, st->y+chan*N+st->frame_size, st->frame_size); + Sdd += mdf_inner_prod(st->input+chan*st->frame_size, st->input+chan*st->frame_size, st->frame_size); + + /* Convert error to frequency domain */ + spx_fft(st->fft_table, st->e+chan*N, st->E+chan*N); + for (i=0;i<st->frame_size;i++) + st->y[i+chan*N] = 0; + spx_fft(st->fft_table, st->y+chan*N, st->Y+chan*N); + + /* Compute power spectrum of echo (X), error (E) and filter response (Y) */ + power_spectrum_accum(st->E+chan*N, st->Rf, N); + power_spectrum_accum(st->Y+chan*N, st->Yf, N); + + } + + /*printf ("%f %f %f %f\n", Sff, See, Syy, Sdd, st->update_cond);*/ + + /* Do some sanity check */ + if (!(Syy>=0 && Sxx>=0 && See >= 0) +#ifndef FIXED_POINT + || !(Sff < N*1e9 && Syy < N*1e9 && Sxx < N*1e9) +#endif + ) + { + /* Things have gone really bad */ + st->screwed_up += 50; + for (i=0;i<st->frame_size*C;i++) + out[i] = 0; + } else if (SHR32(Sff, 2) > ADD32(Sdd, SHR32(MULT16_16(N, 10000),6))) + { + /* AEC seems to add lots of echo instead of removing it, let's see if it will improve */ + st->screwed_up++; + } else { + /* Everything's fine */ + st->screwed_up=0; + } + if (st->screwed_up>=50) + { + speex_warning("The echo canceller started acting funny and got slapped (reset). It swears it will behave now."); + speex_echo_state_reset(st); + return; + } + + /* Add a small noise floor to make sure not to have problems when dividing */ + See = MAX32(See, SHR32(MULT16_16(N, 100),6)); + + for (speak = 0; speak < K; speak++) + { + Sxx += mdf_inner_prod(st->x+speak*N+st->frame_size, st->x+speak*N+st->frame_size, st->frame_size); + power_spectrum_accum(st->X+speak*N, st->Xf, N); + } + + + /* Smooth far end energy estimate over time */ + for (j=0;j<=st->frame_size;j++) + st->power[j] = MULT16_32_Q15(ss_1,st->power[j]) + 1 + MULT16_32_Q15(ss,st->Xf[j]); + + /* Compute filtered spectra and (cross-)correlations */ + for (j=st->frame_size;j>=0;j--) + { + spx_float_t Eh, Yh; + Eh = PSEUDOFLOAT(st->Rf[j] - st->Eh[j]); + Yh = PSEUDOFLOAT(st->Yf[j] - st->Yh[j]); + Pey = FLOAT_ADD(Pey,FLOAT_MULT(Eh,Yh)); + Pyy = FLOAT_ADD(Pyy,FLOAT_MULT(Yh,Yh)); +#ifdef FIXED_POINT + st->Eh[j] = MAC16_32_Q15(MULT16_32_Q15(SUB16(32767,st->spec_average),st->Eh[j]), st->spec_average, st->Rf[j]); + st->Yh[j] = MAC16_32_Q15(MULT16_32_Q15(SUB16(32767,st->spec_average),st->Yh[j]), st->spec_average, st->Yf[j]); +#else + st->Eh[j] = (1-st->spec_average)*st->Eh[j] + st->spec_average*st->Rf[j]; + st->Yh[j] = (1-st->spec_average)*st->Yh[j] + st->spec_average*st->Yf[j]; +#endif + } + + Pyy = FLOAT_SQRT(Pyy); + Pey = FLOAT_DIVU(Pey,Pyy); + + /* Compute correlation updatete rate */ + tmp32 = MULT16_32_Q15(st->beta0,Syy); + if (tmp32 > MULT16_32_Q15(st->beta_max,See)) + tmp32 = MULT16_32_Q15(st->beta_max,See); + alpha = FLOAT_DIV32(tmp32, See); + alpha_1 = FLOAT_SUB(FLOAT_ONE, alpha); + /* Update correlations (recursive average) */ + st->Pey = FLOAT_ADD(FLOAT_MULT(alpha_1,st->Pey) , FLOAT_MULT(alpha,Pey)); + st->Pyy = FLOAT_ADD(FLOAT_MULT(alpha_1,st->Pyy) , FLOAT_MULT(alpha,Pyy)); + if (FLOAT_LT(st->Pyy, FLOAT_ONE)) + st->Pyy = FLOAT_ONE; + /* We don't really hope to get better than 33 dB (MIN_LEAK-3dB) attenuation anyway */ + if (FLOAT_LT(st->Pey, FLOAT_MULT(MIN_LEAK,st->Pyy))) + st->Pey = FLOAT_MULT(MIN_LEAK,st->Pyy); + if (FLOAT_GT(st->Pey, st->Pyy)) + st->Pey = st->Pyy; + /* leak_estimate is the linear regression result */ + st->leak_estimate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIVU(st->Pey, st->Pyy),14)); + /* This looks like a stupid bug, but it's right (because we convert from Q14 to Q15) */ + if (st->leak_estimate > 16383) + st->leak_estimate = 32767; + else + st->leak_estimate = SHL16(st->leak_estimate,1); + /*printf ("%f\n", st->leak_estimate);*/ + + /* Compute Residual to Error Ratio */ +#ifdef FIXED_POINT + tmp32 = MULT16_32_Q15(st->leak_estimate,Syy); + tmp32 = ADD32(SHR32(Sxx,13), ADD32(tmp32, SHL32(tmp32,1))); + /* Check for y in e (lower bound on RER) */ + { + spx_float_t bound = PSEUDOFLOAT(Sey); + bound = FLOAT_DIVU(FLOAT_MULT(bound, bound), PSEUDOFLOAT(ADD32(1,Syy))); + if (FLOAT_GT(bound, PSEUDOFLOAT(See))) + tmp32 = See; + else if (tmp32 < FLOAT_EXTRACT32(bound)) + tmp32 = FLOAT_EXTRACT32(bound); + } + if (tmp32 > SHR32(See,1)) + tmp32 = SHR32(See,1); + RER = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32,See),15)); +#else + RER = (.0001*Sxx + 3.*MULT16_32_Q15(st->leak_estimate,Syy)) / See; + /* Check for y in e (lower bound on RER) */ + if (RER < Sey*Sey/(1+See*Syy)) + RER = Sey*Sey/(1+See*Syy); + if (RER > .5) + RER = .5; +#endif + + /* We consider that the filter has had minimal adaptation if the following is true*/ + if (!st->adapted && st->sum_adapt > SHL32(EXTEND32(M),15) && MULT16_32_Q15(st->leak_estimate,Syy) > MULT16_32_Q15(QCONST16(.03f,15),Syy)) + { + st->adapted = 1; + } + + if (st->adapted) + { + /* Normal learning rate calculation once we're past the minimal adaptation phase */ + for (i=0;i<=st->frame_size;i++) + { + spx_word32_t r, e; + /* Compute frequency-domain adaptation mask */ + r = MULT16_32_Q15(st->leak_estimate,SHL32(st->Yf[i],3)); + e = SHL32(st->Rf[i],3)+1; +#ifdef FIXED_POINT + if (r>SHR32(e,1)) + r = SHR32(e,1); +#else + if (r>.5*e) + r = .5*e; +#endif + r = MULT16_32_Q15(QCONST16(.7,15),r) + MULT16_32_Q15(QCONST16(.3,15),(spx_word32_t)(MULT16_32_Q15(RER,e))); + /*st->power_1[i] = adapt_rate*r/(e*(1+st->power[i]));*/ + st->power_1[i] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,st->power[i]+10)),WEIGHT_SHIFT+16); + } + } else { + /* Temporary adaption rate if filter is not yet adapted enough */ + spx_word16_t adapt_rate=0; + + if (Sxx > SHR32(MULT16_16(N, 1000),6)) + { + tmp32 = MULT16_32_Q15(QCONST16(.25f, 15), Sxx); +#ifdef FIXED_POINT + if (tmp32 > SHR32(See,2)) + tmp32 = SHR32(See,2); +#else + if (tmp32 > .25*See) + tmp32 = .25*See; +#endif + adapt_rate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32, See),15)); + } + for (i=0;i<=st->frame_size;i++) + st->power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(st->power[i],10)),WEIGHT_SHIFT+1); + + + /* How much have we adapted so far? */ + st->sum_adapt = ADD32(st->sum_adapt,adapt_rate); + } + + /* FIXME: MC conversion required */ + for (i=0;i<st->frame_size;i++) + st->last_y[i] = st->last_y[st->frame_size+i]; + if (st->adapted) + { + /* If the filter is adapted, take the filtered echo */ + for (i=0;i<st->frame_size;i++) + st->last_y[st->frame_size+i] = in[i]-out[i]; + } else { + /* If filter isn't adapted yet, all we can do is take the far end signal directly */ + /* moved earlier: for (i=0;i<N;i++) + st->last_y[i] = st->x[i];*/ + } + +} + +/* Compute spectrum of estimated echo for use in an echo post-filter */ +void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *residual_echo, int len) +{ + int i; + spx_word16_t leak2; + int N; + + N = st->window_size; + + /* Apply hanning window (should pre-compute it)*/ + for (i=0;i<N;i++) + st->y[i] = MULT16_16_Q15(st->window[i],st->last_y[i]); + + /* Compute power spectrum of the echo */ + spx_fft(st->fft_table, st->y, st->Y); + power_spectrum(st->Y, residual_echo, N); + +#ifdef FIXED_POINT + if (st->leak_estimate > 16383) + leak2 = 32767; + else + leak2 = SHL16(st->leak_estimate, 1); +#else + if (st->leak_estimate>.5) + leak2 = 1; + else + leak2 = 2*st->leak_estimate; +#endif + /* Estimate residual echo */ + for (i=0;i<=st->frame_size;i++) + residual_echo[i] = (spx_int32_t)MULT16_32_Q15(leak2,residual_echo[i]); + +} + +EXPORT int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr) +{ + switch(request) + { + + case SPEEX_ECHO_GET_FRAME_SIZE: + (*(int*)ptr) = st->frame_size; + break; + case SPEEX_ECHO_SET_SAMPLING_RATE: + st->sampling_rate = (*(int*)ptr); + st->spec_average = DIV32_16(SHL32(EXTEND32(st->frame_size), 15), st->sampling_rate); +#ifdef FIXED_POINT + st->beta0 = DIV32_16(SHL32(EXTEND32(st->frame_size), 16), st->sampling_rate); + st->beta_max = DIV32_16(SHL32(EXTEND32(st->frame_size), 14), st->sampling_rate); +#else + st->beta0 = (2.0f*st->frame_size)/st->sampling_rate; + st->beta_max = (.5f*st->frame_size)/st->sampling_rate; +#endif + if (st->sampling_rate<12000) + st->notch_radius = QCONST16(.9, 15); + else if (st->sampling_rate<24000) + st->notch_radius = QCONST16(.982, 15); + else + st->notch_radius = QCONST16(.992, 15); + break; + case SPEEX_ECHO_GET_SAMPLING_RATE: + (*(int*)ptr) = st->sampling_rate; + break; + case SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE: + /*FIXME: Implement this for multiple channels */ + *((spx_int32_t *)ptr) = st->M * st->frame_size; + break; + case SPEEX_ECHO_GET_IMPULSE_RESPONSE: + { + int M = st->M, N = st->window_size, n = st->frame_size, i, j; + spx_int32_t *filt = (spx_int32_t *) ptr; + for(j=0;j<M;j++) + { + /*FIXME: Implement this for multiple channels */ +#ifdef FIXED_POINT + for (i=0;i<N;i++) + st->wtmp2[i] = EXTRACT16(PSHR32(st->W[j*N+i],16+NORMALIZE_SCALEDOWN)); + spx_ifft(st->fft_table, st->wtmp2, st->wtmp); +#else + spx_ifft(st->fft_table, &st->W[j*N], st->wtmp); +#endif + for(i=0;i<n;i++) + filt[j*n+i] = PSHR32(MULT16_16(32767,st->wtmp[i]), WEIGHT_SHIFT-NORMALIZE_SCALEDOWN); + } + } + break; + default: + speex_warning_int("Unknown speex_echo_ctl request: ", request); + return -1; + } + return 0; +} diff --git a/src/libs/speexdsp/libspeexdsp/misc_bfin.h b/src/libs/speexdsp/libspeexdsp/misc_bfin.h new file mode 100644 index 00000000..3c8c09d2 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/misc_bfin.h @@ -0,0 +1,56 @@ +/* Copyright (C) 2005 Analog Devices */ +/** + @file misc_bfin.h + @author Jean-Marc Valin + @brief Various compatibility routines for Speex (Blackfin version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "bfin.h" + +#define OVERRIDE_SPEEX_MOVE +void *speex_move (void *dest, void *src, int n) +{ + __asm__ __volatile__ + ( + "L0 = 0;\n\t" + "I0 = %0;\n\t" + "R0 = [I0++];\n\t" + "LOOP move%= LC0 = %2;\n\t" + "LOOP_BEGIN move%=;\n\t" + "[%1++] = R0 || R0 = [I0++];\n\t" + "LOOP_END move%=;\n\t" + "[%1++] = R0;\n\t" + : "=a" (src), "=a" (dest) + : "a" ((n>>2)-1), "0" (src), "1" (dest) + : "R0", "I0", "L0", "memory" BFIN_HWLOOP0_REGS + ); + return dest; +} diff --git a/src/libs/speexdsp/libspeexdsp/os_support.h b/src/libs/speexdsp/libspeexdsp/os_support.h new file mode 100644 index 00000000..a1d560ba --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/os_support.h @@ -0,0 +1,175 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: os_support.h + This is the (tiny) OS abstraction layer. Aside from math.h, this is the + only place where system headers are allowed. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef OS_SUPPORT_H +#define OS_SUPPORT_H + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#define EXPORT + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef OS_SUPPORT_CUSTOM +#include "os_support_custom.h" +#endif + +#ifdef TARGET_WIN +# define inline __inline +#endif + +/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free + NOTE: speex_alloc needs to CLEAR THE MEMORY */ +#ifndef OVERRIDE_SPEEX_ALLOC +static inline void *speex_alloc (int size) +{ + /* WARNING: this is not equivalent to malloc(). If you want to use malloc() + or your own allocator, YOU NEED TO CLEAR THE MEMORY ALLOCATED. Otherwise + you will experience strange bugs */ + return calloc(size,1); +} +#endif + +/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */ +#ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH +static inline void *speex_alloc_scratch (int size) +{ + /* Scratch space doesn't need to be cleared */ + return calloc(size,1); +} +#endif + +/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */ +#ifndef OVERRIDE_SPEEX_REALLOC +static inline void *speex_realloc (void *ptr, int size) +{ + return realloc(ptr, size); +} +#endif + +/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */ +#ifndef OVERRIDE_SPEEX_FREE +static inline void speex_free (void *ptr) +{ + free(ptr); +} +#endif + +/** Same as speex_free, except that the area is only needed inside a Speex call (might cause problem with wideband though) */ +#ifndef OVERRIDE_SPEEX_FREE_SCRATCH +static inline void speex_free_scratch (void *ptr) +{ + free(ptr); +} +#endif + +/** Copy n bytes of memory from src to dst. The 0* term provides compile-time type checking */ +#ifndef OVERRIDE_SPEEX_COPY +#define SPEEX_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) )) +#endif + +/** Copy n bytes of memory from src to dst, allowing overlapping regions. The 0* term + provides compile-time type checking */ +#ifndef OVERRIDE_SPEEX_MOVE +#define SPEEX_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) )) +#endif + +/** Set n bytes of memory to value of c, starting at address s */ +#ifndef OVERRIDE_SPEEX_MEMSET +#define SPEEX_MEMSET(dst, c, n) (memset((dst), (c), (n)*sizeof(*(dst)))) +#endif + + +#ifndef OVERRIDE_SPEEX_FATAL +static inline void _speex_fatal(const char *str, const char *file, int line) +{ + fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); + exit(1); +} +#endif + +#ifndef OVERRIDE_SPEEX_WARNING +static inline void speex_warning(const char *str) +{ +#ifndef DISABLE_WARNINGS + fprintf (stderr, "warning: %s\n", str); +#endif +} +#endif + +#ifndef OVERRIDE_SPEEX_WARNING_INT +static inline void speex_warning_int(const char *str, int val) +{ +#ifndef DISABLE_WARNINGS + fprintf (stderr, "warning: %s %d\n", str, val); +#endif +} +#endif + +#ifndef OVERRIDE_SPEEX_NOTIFY +static inline void speex_notify(const char *str) +{ +#ifndef DISABLE_NOTIFICATIONS + fprintf (stderr, "notification: %s\n", str); +#endif +} +#endif + +#ifndef OVERRIDE_SPEEX_PUTC +/** Speex wrapper for putc */ +static inline void _speex_putc(int ch, void *file) +{ + FILE *f = (FILE *)file; + fprintf(f, "%c", ch); +} +#endif + +#define speex_fatal(str) _speex_fatal(str, __FILE__, __LINE__); +#define speex_assert(cond) {if (!(cond)) {speex_fatal("assertion failed: " #cond);}} + +#ifndef RELEASE +static inline void print_vec(float *vec, int len, char *name) +{ + int i; + printf ("%s ", name); + for (i=0;i<len;i++) + printf (" %f", vec[i]); + printf ("\n"); +} +#endif + +#endif + diff --git a/src/libs/speexdsp/libspeexdsp/pseudofloat.h b/src/libs/speexdsp/libspeexdsp/pseudofloat.h new file mode 100644 index 00000000..fa841a01 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/pseudofloat.h @@ -0,0 +1,379 @@ +/* Copyright (C) 2005 Jean-Marc Valin */ +/** + @file pseudofloat.h + @brief Pseudo-floating point + * This header file provides a lightweight floating point type for + * use on fixed-point platforms when a large dynamic range is + * required. The new type is not compatible with the 32-bit IEEE format, + * it is not even remotely as accurate as 32-bit floats, and is not + * even guaranteed to produce even remotely correct results for code + * other than Speex. It makes all kinds of shortcuts that are acceptable + * for Speex, but may not be acceptable for your application. You're + * quite welcome to reuse this code and improve it, but don't assume + * it works out of the box. Most likely, it doesn't. + */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef PSEUDOFLOAT_H +#define PSEUDOFLOAT_H + +#include "arch.h" +#include "os_support.h" +#include "math_approx.h" +#include <math.h> + +#ifdef FIXED_POINT + +typedef struct { + spx_int16_t m; + spx_int16_t e; +} spx_float_t; + +static const spx_float_t FLOAT_ZERO = {0,0}; +static const spx_float_t FLOAT_ONE = {16384,-14}; +static const spx_float_t FLOAT_HALF = {16384,-15}; + +#define MIN(a,b) ((a)<(b)?(a):(b)) +static inline spx_float_t PSEUDOFLOAT(spx_int32_t x) +{ + int e=0; + int sign=0; + if (x<0) + { + sign = 1; + x = -x; + } + if (x==0) + { + spx_float_t r = {0,0}; + return r; + } + e = spx_ilog2(ABS32(x))-14; + x = VSHR32(x, e); + if (sign) + { + spx_float_t r; + r.m = -x; + r.e = e; + return r; + } + else + { + spx_float_t r; + r.m = x; + r.e = e; + return r; + } +} + + +static inline spx_float_t FLOAT_ADD(spx_float_t a, spx_float_t b) +{ + spx_float_t r; + if (a.m==0) + return b; + else if (b.m==0) + return a; + if ((a).e > (b).e) + { + r.m = ((a).m>>1) + ((b).m>>MIN(15,(a).e-(b).e+1)); + r.e = (a).e+1; + } + else + { + r.m = ((b).m>>1) + ((a).m>>MIN(15,(b).e-(a).e+1)); + r.e = (b).e+1; + } + if (r.m>0) + { + if (r.m<16384) + { + r.m<<=1; + r.e-=1; + } + } else { + if (r.m>-16384) + { + r.m<<=1; + r.e-=1; + } + } + /*printf ("%f + %f = %f\n", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/ + return r; +} + +static inline spx_float_t FLOAT_SUB(spx_float_t a, spx_float_t b) +{ + spx_float_t r; + if (a.m==0) + return b; + else if (b.m==0) + return a; + if ((a).e > (b).e) + { + r.m = ((a).m>>1) - ((b).m>>MIN(15,(a).e-(b).e+1)); + r.e = (a).e+1; + } + else + { + r.m = ((a).m>>MIN(15,(b).e-(a).e+1)) - ((b).m>>1); + r.e = (b).e+1; + } + if (r.m>0) + { + if (r.m<16384) + { + r.m<<=1; + r.e-=1; + } + } else { + if (r.m>-16384) + { + r.m<<=1; + r.e-=1; + } + } + /*printf ("%f + %f = %f\n", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/ + return r; +} + +static inline int FLOAT_LT(spx_float_t a, spx_float_t b) +{ + if (a.m==0) + return b.m>0; + else if (b.m==0) + return a.m<0; + if ((a).e > (b).e) + return ((a).m>>1) < ((b).m>>MIN(15,(a).e-(b).e+1)); + else + return ((b).m>>1) > ((a).m>>MIN(15,(b).e-(a).e+1)); + +} + +static inline int FLOAT_GT(spx_float_t a, spx_float_t b) +{ + return FLOAT_LT(b,a); +} + +static inline spx_float_t FLOAT_MULT(spx_float_t a, spx_float_t b) +{ + spx_float_t r; + r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15); + r.e = (a).e+(b).e+15; + if (r.m>0) + { + if (r.m<16384) + { + r.m<<=1; + r.e-=1; + } + } else { + if (r.m>-16384) + { + r.m<<=1; + r.e-=1; + } + } + /*printf ("%f * %f = %f\n", REALFLOAT(a), REALFLOAT(b), REALFLOAT(r));*/ + return r; +} + +static inline spx_float_t FLOAT_AMULT(spx_float_t a, spx_float_t b) +{ + spx_float_t r; + r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15); + r.e = (a).e+(b).e+15; + return r; +} + + +static inline spx_float_t FLOAT_SHL(spx_float_t a, int b) +{ + spx_float_t r; + r.m = a.m; + r.e = a.e+b; + return r; +} + +static inline spx_int16_t FLOAT_EXTRACT16(spx_float_t a) +{ + if (a.e<0) + return EXTRACT16((EXTEND32(a.m)+(EXTEND32(1)<<(-a.e-1)))>>-a.e); + else + return a.m<<a.e; +} + +static inline spx_int32_t FLOAT_EXTRACT32(spx_float_t a) +{ + if (a.e<0) + return (EXTEND32(a.m)+(EXTEND32(1)<<(-a.e-1)))>>-a.e; + else + return EXTEND32(a.m)<<a.e; +} + +static inline spx_int32_t FLOAT_MUL32(spx_float_t a, spx_word32_t b) +{ + return VSHR32(MULT16_32_Q15(a.m, b),-a.e-15); +} + +static inline spx_float_t FLOAT_MUL32U(spx_word32_t a, spx_word32_t b) +{ + int e1, e2; + spx_float_t r; + if (a==0 || b==0) + { + return FLOAT_ZERO; + } + e1 = spx_ilog2(ABS32(a)); + a = VSHR32(a, e1-14); + e2 = spx_ilog2(ABS32(b)); + b = VSHR32(b, e2-14); + r.m = MULT16_16_Q15(a,b); + r.e = e1+e2-13; + return r; +} + +/* Do NOT attempt to divide by a negative number */ +static inline spx_float_t FLOAT_DIV32_FLOAT(spx_word32_t a, spx_float_t b) +{ + int e=0; + spx_float_t r; + if (a==0) + { + return FLOAT_ZERO; + } + e = spx_ilog2(ABS32(a))-spx_ilog2(b.m-1)-15; + a = VSHR32(a, e); + if (ABS32(a)>=SHL32(EXTEND32(b.m-1),15)) + { + a >>= 1; + e++; + } + r.m = DIV32_16(a,b.m); + r.e = e-b.e; + return r; +} + + +/* Do NOT attempt to divide by a negative number */ +static inline spx_float_t FLOAT_DIV32(spx_word32_t a, spx_word32_t b) +{ + int e0=0,e=0; + spx_float_t r; + if (a==0) + { + return FLOAT_ZERO; + } + if (b>32767) + { + e0 = spx_ilog2(b)-14; + b = VSHR32(b, e0); + e0 = -e0; + } + e = spx_ilog2(ABS32(a))-spx_ilog2(b-1)-15; + a = VSHR32(a, e); + if (ABS32(a)>=SHL32(EXTEND32(b-1),15)) + { + a >>= 1; + e++; + } + e += e0; + r.m = DIV32_16(a,b); + r.e = e; + return r; +} + +/* Do NOT attempt to divide by a negative number */ +static inline spx_float_t FLOAT_DIVU(spx_float_t a, spx_float_t b) +{ + int e=0; + spx_int32_t num; + spx_float_t r; + if (b.m<=0) + { + speex_warning_int("Attempted to divide by", b.m); + return FLOAT_ONE; + } + num = a.m; + a.m = ABS16(a.m); + while (a.m >= b.m) + { + e++; + a.m >>= 1; + } + num = num << (15-e); + r.m = DIV32_16(num,b.m); + r.e = a.e-b.e-15+e; + return r; +} + +static inline spx_float_t FLOAT_SQRT(spx_float_t a) +{ + spx_float_t r; + spx_int32_t m; + m = SHL32(EXTEND32(a.m), 14); + r.e = a.e - 14; + if (r.e & 1) + { + r.e -= 1; + m <<= 1; + } + r.e >>= 1; + r.m = spx_sqrt(m); + return r; +} + +#else + +#define spx_float_t float +#define FLOAT_ZERO 0.f +#define FLOAT_ONE 1.f +#define FLOAT_HALF 0.5f +#define PSEUDOFLOAT(x) (x) +#define FLOAT_MULT(a,b) ((a)*(b)) +#define FLOAT_AMULT(a,b) ((a)*(b)) +#define FLOAT_MUL32(a,b) ((a)*(b)) +#define FLOAT_DIV32(a,b) ((a)/(b)) +#define FLOAT_EXTRACT16(a) (a) +#define FLOAT_EXTRACT32(a) (a) +#define FLOAT_ADD(a,b) ((a)+(b)) +#define FLOAT_SUB(a,b) ((a)-(b)) +#define REALFLOAT(x) (x) +#define FLOAT_DIV32_FLOAT(a,b) ((a)/(b)) +#define FLOAT_MUL32U(a,b) ((a)*(b)) +#define FLOAT_SHL(a,b) (a) +#define FLOAT_LT(a,b) ((a)<(b)) +#define FLOAT_GT(a,b) ((a)>(b)) +#define FLOAT_DIVU(a,b) ((a)/(b)) +#define FLOAT_SQRT(a) (spx_sqrt(a)) + +#endif + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/resample_sse.h b/src/libs/speexdsp/libspeexdsp/resample_sse.h new file mode 100644 index 00000000..64be8a16 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/resample_sse.h @@ -0,0 +1,128 @@ +/* Copyright (C) 2007-2008 Jean-Marc Valin + * Copyright (C) 2008 Thorvald Natvig + */ +/** + @file resample_sse.h + @brief Resampler functions (SSE version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <xmmintrin.h> + +#define OVERRIDE_INNER_PRODUCT_SINGLE +static inline float inner_product_single(const float *a, const float *b, unsigned int len) +{ + int i; + float ret; + __m128 sum = _mm_setzero_ps(); + for (i=0;i<len;i+=8) + { + sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i))); + sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4))); + } + sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum)); + sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55)); + _mm_store_ss(&ret, sum); + return ret; +} + +#define OVERRIDE_INTERPOLATE_PRODUCT_SINGLE +static inline float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) { + int i; + float ret; + __m128 sum = _mm_setzero_ps(); + __m128 f = _mm_loadu_ps(frac); + for(i=0;i<len;i+=2) + { + sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample))); + sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample))); + } + sum = _mm_mul_ps(f, sum); + sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum)); + sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55)); + _mm_store_ss(&ret, sum); + return ret; +} + +#ifdef _USE_SSE2 +#include <emmintrin.h> +#define OVERRIDE_INNER_PRODUCT_DOUBLE + +static inline double inner_product_double(const float *a, const float *b, unsigned int len) +{ + int i; + double ret; + __m128d sum = _mm_setzero_pd(); + __m128 t; + for (i=0;i<len;i+=8) + { + t = _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i)); + sum = _mm_add_pd(sum, _mm_cvtps_pd(t)); + sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t))); + + t = _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4)); + sum = _mm_add_pd(sum, _mm_cvtps_pd(t)); + sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t))); + } + sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum)); + _mm_store_sd(&ret, sum); + return ret; +} + +#define OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE +static inline double interpolate_product_double(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) { + int i; + double ret; + __m128d sum; + __m128d sum1 = _mm_setzero_pd(); + __m128d sum2 = _mm_setzero_pd(); + __m128 f = _mm_loadu_ps(frac); + __m128d f1 = _mm_cvtps_pd(f); + __m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f,f)); + __m128 t; + for(i=0;i<len;i+=2) + { + t = _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample)); + sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t)); + sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t))); + + t = _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample)); + sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t)); + sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t))); + } + sum1 = _mm_mul_pd(f1, sum1); + sum2 = _mm_mul_pd(f2, sum2); + sum = _mm_add_pd(sum1, sum2); + sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum)); + _mm_store_sd(&ret, sum); + return ret; +} + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/scal.c b/src/libs/speexdsp/libspeexdsp/scal.c new file mode 100644 index 00000000..315ed5a1 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/scal.c @@ -0,0 +1,293 @@ +/* Copyright (C) 2006-2008 CSIRO, Jean-Marc Valin, Xiph.Org Foundation + + File: scal.c + Shaped comb-allpass filter for channel decorrelation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +The algorithm implemented here is described in: + +* J.-M. Valin, Perceptually-Motivated Nonlinear Channel Decorrelation For + Stereo Acoustic Echo Cancellation, Accepted for Joint Workshop on + Hands­free Speech Communication and Microphone Arrays (HSCMA), 2008. + http://people.xiph.org/~jm/papers/valin_hscma2008.pdf + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "speex/speex_echo.h" +#include "vorbis_psy.h" +#include "arch.h" +#include "os_support.h" +#include "smallft.h" +#include <math.h> +#include <stdlib.h> + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + +#define ALLPASS_ORDER 20 + +struct SpeexDecorrState_ { + int rate; + int channels; + int frame_size; +#ifdef VORBIS_PSYCHO + VorbisPsy *psy; + struct drft_lookup lookup; + float *wola_mem; + float *curve; +#endif + float *vorbis_win; + int seed; + float *y; + + /* Per-channel stuff */ + float *buff; + float (*ring)[ALLPASS_ORDER]; + int *ringID; + int *order; + float *alpha; +}; + + + +EXPORT SpeexDecorrState *speex_decorrelate_new(int rate, int channels, int frame_size) +{ + int i, ch; + SpeexDecorrState *st = speex_alloc(sizeof(SpeexDecorrState)); + st->rate = rate; + st->channels = channels; + st->frame_size = frame_size; +#ifdef VORBIS_PSYCHO + st->psy = vorbis_psy_init(rate, 2*frame_size); + spx_drft_init(&st->lookup, 2*frame_size); + st->wola_mem = speex_alloc(frame_size*sizeof(float)); + st->curve = speex_alloc(frame_size*sizeof(float)); +#endif + st->y = speex_alloc(frame_size*sizeof(float)); + + st->buff = speex_alloc(channels*2*frame_size*sizeof(float)); + st->ringID = speex_alloc(channels*sizeof(int)); + st->order = speex_alloc(channels*sizeof(int)); + st->alpha = speex_alloc(channels*sizeof(float)); + st->ring = speex_alloc(channels*ALLPASS_ORDER*sizeof(float)); + + /*FIXME: The +20 is there only as a kludge for ALL_PASS_OLA*/ + st->vorbis_win = speex_alloc((2*frame_size+20)*sizeof(float)); + for (i=0;i<2*frame_size;i++) + st->vorbis_win[i] = sin(.5*M_PI* sin(M_PI*i/(2*frame_size))*sin(M_PI*i/(2*frame_size)) ); + st->seed = rand(); + + for (ch=0;ch<channels;ch++) + { + for (i=0;i<ALLPASS_ORDER;i++) + st->ring[ch][i] = 0; + st->ringID[ch] = 0; + st->alpha[ch] = 0; + st->order[ch] = 10; + } + return st; +} + +static float uni_rand(int *seed) +{ + const unsigned int jflone = 0x3f800000; + const unsigned int jflmsk = 0x007fffff; + union {int i; float f;} ran; + *seed = 1664525 * *seed + 1013904223; + ran.i = jflone | (jflmsk & *seed); + ran.f -= 1.5; + return 2*ran.f; +} + +static unsigned int irand(int *seed) +{ + *seed = 1664525 * *seed + 1013904223; + return ((unsigned int)*seed)>>16; +} + + +EXPORT void speex_decorrelate(SpeexDecorrState *st, const spx_int16_t *in, spx_int16_t *out, int strength) +{ + int ch; + float amount; + + if (strength<0) + strength = 0; + if (strength>100) + strength = 100; + + amount = .01*strength; + for (ch=0;ch<st->channels;ch++) + { + int i; + int N=2*st->frame_size; + float beta, beta2; + float *x; + float max_alpha = 0; + + float *buff; + float *ring; + int ringID; + int order; + float alpha; + + buff = st->buff+ch*2*st->frame_size; + ring = st->ring[ch]; + ringID = st->ringID[ch]; + order = st->order[ch]; + alpha = st->alpha[ch]; + + for (i=0;i<st->frame_size;i++) + buff[i] = buff[i+st->frame_size]; + for (i=0;i<st->frame_size;i++) + buff[i+st->frame_size] = in[i*st->channels+ch]; + + x = buff+st->frame_size; + beta = 1.-.3*amount*amount; + if (amount>1) + beta = 1-sqrt(.4*amount); + else + beta = 1-0.63246*amount; + if (beta<0) + beta = 0; + + beta2 = beta; + for (i=0;i<st->frame_size;i++) + { + st->y[i] = alpha*(x[i-ALLPASS_ORDER+order]-beta*x[i-ALLPASS_ORDER+order-1])*st->vorbis_win[st->frame_size+i+order] + + x[i-ALLPASS_ORDER]*st->vorbis_win[st->frame_size+i] + - alpha*(ring[ringID] + - beta*ring[ringID+1>=order?0:ringID+1]); + ring[ringID++]=st->y[i]; + st->y[i] *= st->vorbis_win[st->frame_size+i]; + if (ringID>=order) + ringID=0; + } + order = order+(irand(&st->seed)%3)-1; + if (order < 5) + order = 5; + if (order > 10) + order = 10; + /*order = 5+(irand(&st->seed)%6);*/ + max_alpha = pow(.96+.04*(amount-1),order); + if (max_alpha > .98/(1.+beta2)) + max_alpha = .98/(1.+beta2); + + alpha = alpha + .4*uni_rand(&st->seed); + if (alpha > max_alpha) + alpha = max_alpha; + if (alpha < -max_alpha) + alpha = -max_alpha; + for (i=0;i<ALLPASS_ORDER;i++) + ring[i] = 0; + ringID = 0; + for (i=0;i<st->frame_size;i++) + { + float tmp = alpha*(x[i-ALLPASS_ORDER+order]-beta*x[i-ALLPASS_ORDER+order-1])*st->vorbis_win[i+order] + + x[i-ALLPASS_ORDER]*st->vorbis_win[i] + - alpha*(ring[ringID] + - beta*ring[ringID+1>=order?0:ringID+1]); + ring[ringID++]=tmp; + tmp *= st->vorbis_win[i]; + if (ringID>=order) + ringID=0; + st->y[i] += tmp; + } + +#ifdef VORBIS_PSYCHO + float frame[N]; + float scale = 1./N; + for (i=0;i<2*st->frame_size;i++) + frame[i] = buff[i]; + //float coef = .5*0.78130; + float coef = M_PI*0.075063 * 0.93763 * amount * .8 * 0.707; + compute_curve(st->psy, buff, st->curve); + for (i=1;i<st->frame_size;i++) + { + float x1,x2; + float gain; + do { + x1 = uni_rand(&st->seed); + x2 = uni_rand(&st->seed); + } while (x1*x1+x2*x2 > 1.); + gain = coef*sqrt(.1+st->curve[i]); + frame[2*i-1] = gain*x1; + frame[2*i] = gain*x2; + } + frame[0] = coef*uni_rand(&st->seed)*sqrt(.1+st->curve[0]); + frame[2*st->frame_size-1] = coef*uni_rand(&st->seed)*sqrt(.1+st->curve[st->frame_size-1]); + spx_drft_backward(&st->lookup,frame); + for (i=0;i<2*st->frame_size;i++) + frame[i] *= st->vorbis_win[i]; +#endif + + for (i=0;i<st->frame_size;i++) + { +#ifdef VORBIS_PSYCHO + float tmp = st->y[i] + frame[i] + st->wola_mem[i]; + st->wola_mem[i] = frame[i+st->frame_size]; +#else + float tmp = st->y[i]; +#endif + if (tmp>32767) + tmp = 32767; + if (tmp < -32767) + tmp = -32767; + out[i*st->channels+ch] = tmp; + } + + st->ringID[ch] = ringID; + st->order[ch] = order; + st->alpha[ch] = alpha; + + } +} + +EXPORT void speex_decorrelate_destroy(SpeexDecorrState *st) +{ +#ifdef VORBIS_PSYCHO + vorbis_psy_destroy(st->psy); + speex_free(st->wola_mem); + speex_free(st->curve); +#endif + speex_free(st->buff); + speex_free(st->ring); + speex_free(st->ringID); + speex_free(st->alpha); + speex_free(st->vorbis_win); + speex_free(st->order); + speex_free(st->y); + speex_free(st); +} diff --git a/src/libs/speexdsp/libspeexdsp/smallft.c b/src/libs/speexdsp/libspeexdsp/smallft.c new file mode 100644 index 00000000..5c26d016 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/smallft.c @@ -0,0 +1,1261 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: *unnormalized* fft transform + last mod: $Id: smallft.c,v 1.19 2003/10/08 05:12:37 jm Exp $ + + ********************************************************************/ + +/* FFT implementation from OggSquish, minus cosine transforms, + * minus all but radix 2/4 case. In Vorbis we only need this + * cut-down version. + * + * To do more than just power-of-two sized vectors, see the full + * version I wrote for NetLib. + * + * Note that the packing is a little strange; rather than the FFT r/i + * packing following R_0, I_n, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, + * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the + * FORTRAN version + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <math.h> +#include "smallft.h" +#include "arch.h" +#include "os_support.h" + +static void drfti1(int n, float *wa, int *ifac){ + static int ntryh[4] = { 4,2,3,5 }; + static float tpi = 6.28318530717958648f; + float arg,argh,argld,fi; + int ntry=0,i,j=-1; + int k1, l1, l2, ib; + int ld, ii, ip, is, nq, nr; + int ido, ipm, nfm1; + int nl=n; + int nf=0; + + L101: + j++; + if (j < 4) + ntry=ntryh[j]; + else + ntry+=2; + + L104: + nq=nl/ntry; + nr=nl-ntry*nq; + if (nr!=0) goto L101; + + nf++; + ifac[nf+1]=ntry; + nl=nq; + if(ntry!=2)goto L107; + if(nf==1)goto L107; + + for (i=1;i<nf;i++){ + ib=nf-i+1; + ifac[ib+1]=ifac[ib]; + } + ifac[2] = 2; + + L107: + if(nl!=1)goto L104; + ifac[0]=n; + ifac[1]=nf; + argh=tpi/n; + is=0; + nfm1=nf-1; + l1=1; + + if(nfm1==0)return; + + for (k1=0;k1<nfm1;k1++){ + ip=ifac[k1+2]; + ld=0; + l2=l1*ip; + ido=n/l2; + ipm=ip-1; + + for (j=0;j<ipm;j++){ + ld+=l1; + i=is; + argld=(float)ld*argh; + fi=0.f; + for (ii=2;ii<ido;ii+=2){ + fi+=1.f; + arg=fi*argld; + wa[i++]=cos(arg); + wa[i++]=sin(arg); + } + is+=ido; + } + l1=l2; + } +} + +static void fdrffti(int n, float *wsave, int *ifac){ + + if (n == 1) return; + drfti1(n, wsave+n, ifac); +} + +static void dradf2(int ido,int l1,float *cc,float *ch,float *wa1){ + int i,k; + float ti2,tr2; + int t0,t1,t2,t3,t4,t5,t6; + + t1=0; + t0=(t2=l1*ido); + t3=ido<<1; + for(k=0;k<l1;k++){ + ch[t1<<1]=cc[t1]+cc[t2]; + ch[(t1<<1)+t3-1]=cc[t1]-cc[t2]; + t1+=ido; + t2+=ido; + } + + if(ido<2)return; + if(ido==2)goto L105; + + t1=0; + t2=t0; + for(k=0;k<l1;k++){ + t3=t2; + t4=(t1<<1)+(ido<<1); + t5=t1; + t6=t1+t1; + for(i=2;i<ido;i+=2){ + t3+=2; + t4-=2; + t5+=2; + t6+=2; + tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3]; + ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1]; + ch[t6]=cc[t5]+ti2; + ch[t4]=ti2-cc[t5]; + ch[t6-1]=cc[t5-1]+tr2; + ch[t4-1]=cc[t5-1]-tr2; + } + t1+=ido; + t2+=ido; + } + + if(ido%2==1)return; + + L105: + t3=(t2=(t1=ido)-1); + t2+=t0; + for(k=0;k<l1;k++){ + ch[t1]=-cc[t2]; + ch[t1-1]=cc[t3]; + t1+=ido<<1; + t2+=ido; + t3+=ido; + } +} + +static void dradf4(int ido,int l1,float *cc,float *ch,float *wa1, + float *wa2,float *wa3){ + static float hsqt2 = .70710678118654752f; + int i,k,t0,t1,t2,t3,t4,t5,t6; + float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4; + t0=l1*ido; + + t1=t0; + t4=t1<<1; + t2=t1+(t1<<1); + t3=0; + + for(k=0;k<l1;k++){ + tr1=cc[t1]+cc[t2]; + tr2=cc[t3]+cc[t4]; + + ch[t5=t3<<2]=tr1+tr2; + ch[(ido<<2)+t5-1]=tr2-tr1; + ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4]; + ch[t5]=cc[t2]-cc[t1]; + + t1+=ido; + t2+=ido; + t3+=ido; + t4+=ido; + } + + if(ido<2)return; + if(ido==2)goto L105; + + + t1=0; + for(k=0;k<l1;k++){ + t2=t1; + t4=t1<<2; + t5=(t6=ido<<1)+t4; + for(i=2;i<ido;i+=2){ + t3=(t2+=2); + t4+=2; + t5-=2; + + t3+=t0; + cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3]; + ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1]; + t3+=t0; + cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3]; + ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1]; + t3+=t0; + cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3]; + ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1]; + + tr1=cr2+cr4; + tr4=cr4-cr2; + ti1=ci2+ci4; + ti4=ci2-ci4; + + ti2=cc[t2]+ci3; + ti3=cc[t2]-ci3; + tr2=cc[t2-1]+cr3; + tr3=cc[t2-1]-cr3; + + ch[t4-1]=tr1+tr2; + ch[t4]=ti1+ti2; + + ch[t5-1]=tr3-ti4; + ch[t5]=tr4-ti3; + + ch[t4+t6-1]=ti4+tr3; + ch[t4+t6]=tr4+ti3; + + ch[t5+t6-1]=tr2-tr1; + ch[t5+t6]=ti1-ti2; + } + t1+=ido; + } + if(ido&1)return; + + L105: + + t2=(t1=t0+ido-1)+(t0<<1); + t3=ido<<2; + t4=ido; + t5=ido<<1; + t6=ido; + + for(k=0;k<l1;k++){ + ti1=-hsqt2*(cc[t1]+cc[t2]); + tr1=hsqt2*(cc[t1]-cc[t2]); + + ch[t4-1]=tr1+cc[t6-1]; + ch[t4+t5-1]=cc[t6-1]-tr1; + + ch[t4]=ti1-cc[t1+t0]; + ch[t4+t5]=ti1+cc[t1+t0]; + + t1+=ido; + t2+=ido; + t4+=t3; + t6+=ido; + } +} + +static void dradfg(int ido,int ip,int l1,int idl1,float *cc,float *c1, + float *c2,float *ch,float *ch2,float *wa){ + + static float tpi=6.283185307179586f; + int idij,ipph,i,j,k,l,ic,ik,is; + int t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; + float dc2,ai1,ai2,ar1,ar2,ds2; + int nbd; + float dcp,arg,dsp,ar1h,ar2h; + int idp2,ipp2; + + arg=tpi/(float)ip; + dcp=cos(arg); + dsp=sin(arg); + ipph=(ip+1)>>1; + ipp2=ip; + idp2=ido; + nbd=(ido-1)>>1; + t0=l1*ido; + t10=ip*ido; + + if(ido==1)goto L119; + for(ik=0;ik<idl1;ik++)ch2[ik]=c2[ik]; + + t1=0; + for(j=1;j<ip;j++){ + t1+=t0; + t2=t1; + for(k=0;k<l1;k++){ + ch[t2]=c1[t2]; + t2+=ido; + } + } + + is=-ido; + t1=0; + if(nbd>l1){ + for(j=1;j<ip;j++){ + t1+=t0; + is+=ido; + t2= -ido+t1; + for(k=0;k<l1;k++){ + idij=is-1; + t2+=ido; + t3=t2; + for(i=2;i<ido;i+=2){ + idij+=2; + t3+=2; + ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3]; + ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1]; + } + } + } + }else{ + + for(j=1;j<ip;j++){ + is+=ido; + idij=is-1; + t1+=t0; + t2=t1; + for(i=2;i<ido;i+=2){ + idij+=2; + t2+=2; + t3=t2; + for(k=0;k<l1;k++){ + ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3]; + ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1]; + t3+=ido; + } + } + } + } + + t1=0; + t2=ipp2*t0; + if(nbd<l1){ + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t5=t3-ido; + t6=t4-ido; + for(k=0;k<l1;k++){ + t5+=ido; + t6+=ido; + c1[t5-1]=ch[t5-1]+ch[t6-1]; + c1[t6-1]=ch[t5]-ch[t6]; + c1[t5]=ch[t5]+ch[t6]; + c1[t6]=ch[t6-1]-ch[t5-1]; + } + } + } + }else{ + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(k=0;k<l1;k++){ + t5=t3; + t6=t4; + for(i=2;i<ido;i+=2){ + t5+=2; + t6+=2; + c1[t5-1]=ch[t5-1]+ch[t6-1]; + c1[t6-1]=ch[t5]-ch[t6]; + c1[t5]=ch[t5]+ch[t6]; + c1[t6]=ch[t6-1]-ch[t5-1]; + } + t3+=ido; + t4+=ido; + } + } + } + +L119: + for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik]; + + t1=0; + t2=ipp2*idl1; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1-ido; + t4=t2-ido; + for(k=0;k<l1;k++){ + t3+=ido; + t4+=ido; + c1[t3]=ch[t3]+ch[t4]; + c1[t4]=ch[t4]-ch[t3]; + } + } + + ar1=1.f; + ai1=0.f; + t1=0; + t2=ipp2*idl1; + t3=(ip-1)*idl1; + for(l=1;l<ipph;l++){ + t1+=idl1; + t2-=idl1; + ar1h=dcp*ar1-dsp*ai1; + ai1=dcp*ai1+dsp*ar1; + ar1=ar1h; + t4=t1; + t5=t2; + t6=t3; + t7=idl1; + + for(ik=0;ik<idl1;ik++){ + ch2[t4++]=c2[ik]+ar1*c2[t7++]; + ch2[t5++]=ai1*c2[t6++]; + } + + dc2=ar1; + ds2=ai1; + ar2=ar1; + ai2=ai1; + + t4=idl1; + t5=(ipp2-1)*idl1; + for(j=2;j<ipph;j++){ + t4+=idl1; + t5-=idl1; + + ar2h=dc2*ar2-ds2*ai2; + ai2=dc2*ai2+ds2*ar2; + ar2=ar2h; + + t6=t1; + t7=t2; + t8=t4; + t9=t5; + for(ik=0;ik<idl1;ik++){ + ch2[t6++]+=ar2*c2[t8++]; + ch2[t7++]+=ai2*c2[t9++]; + } + } + } + + t1=0; + for(j=1;j<ipph;j++){ + t1+=idl1; + t2=t1; + for(ik=0;ik<idl1;ik++)ch2[ik]+=c2[t2++]; + } + + if(ido<l1)goto L132; + + t1=0; + t2=0; + for(k=0;k<l1;k++){ + t3=t1; + t4=t2; + for(i=0;i<ido;i++)cc[t4++]=ch[t3++]; + t1+=ido; + t2+=t10; + } + + goto L135; + + L132: + for(i=0;i<ido;i++){ + t1=i; + t2=i; + for(k=0;k<l1;k++){ + cc[t2]=ch[t1]; + t1+=ido; + t2+=t10; + } + } + + L135: + t1=0; + t2=ido<<1; + t3=0; + t4=ipp2*t0; + for(j=1;j<ipph;j++){ + + t1+=t2; + t3+=t0; + t4-=t0; + + t5=t1; + t6=t3; + t7=t4; + + for(k=0;k<l1;k++){ + cc[t5-1]=ch[t6]; + cc[t5]=ch[t7]; + t5+=t10; + t6+=ido; + t7+=ido; + } + } + + if(ido==1)return; + if(nbd<l1)goto L141; + + t1=-ido; + t3=0; + t4=0; + t5=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t2; + t3+=t2; + t4+=t0; + t5-=t0; + t6=t1; + t7=t3; + t8=t4; + t9=t5; + for(k=0;k<l1;k++){ + for(i=2;i<ido;i+=2){ + ic=idp2-i; + cc[i+t7-1]=ch[i+t8-1]+ch[i+t9-1]; + cc[ic+t6-1]=ch[i+t8-1]-ch[i+t9-1]; + cc[i+t7]=ch[i+t8]+ch[i+t9]; + cc[ic+t6]=ch[i+t9]-ch[i+t8]; + } + t6+=t10; + t7+=t10; + t8+=ido; + t9+=ido; + } + } + return; + + L141: + + t1=-ido; + t3=0; + t4=0; + t5=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t2; + t3+=t2; + t4+=t0; + t5-=t0; + for(i=2;i<ido;i+=2){ + t6=idp2+t1-i; + t7=i+t3; + t8=i+t4; + t9=i+t5; + for(k=0;k<l1;k++){ + cc[t7-1]=ch[t8-1]+ch[t9-1]; + cc[t6-1]=ch[t8-1]-ch[t9-1]; + cc[t7]=ch[t8]+ch[t9]; + cc[t6]=ch[t9]-ch[t8]; + t6+=t10; + t7+=t10; + t8+=ido; + t9+=ido; + } + } + } +} + +static void drftf1(int n,float *c,float *ch,float *wa,int *ifac){ + int i,k1,l1,l2; + int na,kh,nf; + int ip,iw,ido,idl1,ix2,ix3; + + nf=ifac[1]; + na=1; + l2=n; + iw=n; + + for(k1=0;k1<nf;k1++){ + kh=nf-k1; + ip=ifac[kh+1]; + l1=l2/ip; + ido=n/l2; + idl1=ido*l1; + iw-=(ip-1)*ido; + na=1-na; + + if(ip!=4)goto L102; + + ix2=iw+ido; + ix3=ix2+ido; + if(na!=0) + dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1); + else + dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1); + goto L110; + + L102: + if(ip!=2)goto L104; + if(na!=0)goto L103; + + dradf2(ido,l1,c,ch,wa+iw-1); + goto L110; + + L103: + dradf2(ido,l1,ch,c,wa+iw-1); + goto L110; + + L104: + if(ido==1)na=1-na; + if(na!=0)goto L109; + + dradfg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1); + na=1; + goto L110; + + L109: + dradfg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1); + na=0; + + L110: + l2=l1; + } + + if(na==1)return; + + for(i=0;i<n;i++)c[i]=ch[i]; +} + +static void dradb2(int ido,int l1,float *cc,float *ch,float *wa1){ + int i,k,t0,t1,t2,t3,t4,t5,t6; + float ti2,tr2; + + t0=l1*ido; + + t1=0; + t2=0; + t3=(ido<<1)-1; + for(k=0;k<l1;k++){ + ch[t1]=cc[t2]+cc[t3+t2]; + ch[t1+t0]=cc[t2]-cc[t3+t2]; + t2=(t1+=ido)<<1; + } + + if(ido<2)return; + if(ido==2)goto L105; + + t1=0; + t2=0; + for(k=0;k<l1;k++){ + t3=t1; + t5=(t4=t2)+(ido<<1); + t6=t0+t1; + for(i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t5-=2; + t6+=2; + ch[t3-1]=cc[t4-1]+cc[t5-1]; + tr2=cc[t4-1]-cc[t5-1]; + ch[t3]=cc[t4]-cc[t5]; + ti2=cc[t4]+cc[t5]; + ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2; + ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2; + } + t2=(t1+=ido)<<1; + } + + if(ido%2==1)return; + +L105: + t1=ido-1; + t2=ido-1; + for(k=0;k<l1;k++){ + ch[t1]=cc[t2]+cc[t2]; + ch[t1+t0]=-(cc[t2+1]+cc[t2+1]); + t1+=ido; + t2+=ido<<1; + } +} + +static void dradb3(int ido,int l1,float *cc,float *ch,float *wa1, + float *wa2){ + static float taur = -.5f; + static float taui = .8660254037844386f; + int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; + float ci2,ci3,di2,di3,cr2,cr3,dr2,dr3,ti2,tr2; + t0=l1*ido; + + t1=0; + t2=t0<<1; + t3=ido<<1; + t4=ido+(ido<<1); + t5=0; + for(k=0;k<l1;k++){ + tr2=cc[t3-1]+cc[t3-1]; + cr2=cc[t5]+(taur*tr2); + ch[t1]=cc[t5]+tr2; + ci3=taui*(cc[t3]+cc[t3]); + ch[t1+t0]=cr2-ci3; + ch[t1+t2]=cr2+ci3; + t1+=ido; + t3+=t4; + t5+=t4; + } + + if(ido==1)return; + + t1=0; + t3=ido<<1; + for(k=0;k<l1;k++){ + t7=t1+(t1<<1); + t6=(t5=t7+t3); + t8=t1; + t10=(t9=t1+t0)+t0; + + for(i=2;i<ido;i+=2){ + t5+=2; + t6-=2; + t7+=2; + t8+=2; + t9+=2; + t10+=2; + tr2=cc[t5-1]+cc[t6-1]; + cr2=cc[t7-1]+(taur*tr2); + ch[t8-1]=cc[t7-1]+tr2; + ti2=cc[t5]-cc[t6]; + ci2=cc[t7]+(taur*ti2); + ch[t8]=cc[t7]+ti2; + cr3=taui*(cc[t5-1]-cc[t6-1]); + ci3=taui*(cc[t5]+cc[t6]); + dr2=cr2-ci3; + dr3=cr2+ci3; + di2=ci2+cr3; + di3=ci2-cr3; + ch[t9-1]=wa1[i-2]*dr2-wa1[i-1]*di2; + ch[t9]=wa1[i-2]*di2+wa1[i-1]*dr2; + ch[t10-1]=wa2[i-2]*dr3-wa2[i-1]*di3; + ch[t10]=wa2[i-2]*di3+wa2[i-1]*dr3; + } + t1+=ido; + } +} + +static void dradb4(int ido,int l1,float *cc,float *ch,float *wa1, + float *wa2,float *wa3){ + static float sqrt2=1.414213562373095f; + int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8; + float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4; + t0=l1*ido; + + t1=0; + t2=ido<<2; + t3=0; + t6=ido<<1; + for(k=0;k<l1;k++){ + t4=t3+t6; + t5=t1; + tr3=cc[t4-1]+cc[t4-1]; + tr4=cc[t4]+cc[t4]; + tr1=cc[t3]-cc[(t4+=t6)-1]; + tr2=cc[t3]+cc[t4-1]; + ch[t5]=tr2+tr3; + ch[t5+=t0]=tr1-tr4; + ch[t5+=t0]=tr2-tr3; + ch[t5+=t0]=tr1+tr4; + t1+=ido; + t3+=t2; + } + + if(ido<2)return; + if(ido==2)goto L105; + + t1=0; + for(k=0;k<l1;k++){ + t5=(t4=(t3=(t2=t1<<2)+t6))+t6; + t7=t1; + for(i=2;i<ido;i+=2){ + t2+=2; + t3+=2; + t4-=2; + t5-=2; + t7+=2; + ti1=cc[t2]+cc[t5]; + ti2=cc[t2]-cc[t5]; + ti3=cc[t3]-cc[t4]; + tr4=cc[t3]+cc[t4]; + tr1=cc[t2-1]-cc[t5-1]; + tr2=cc[t2-1]+cc[t5-1]; + ti4=cc[t3-1]-cc[t4-1]; + tr3=cc[t3-1]+cc[t4-1]; + ch[t7-1]=tr2+tr3; + cr3=tr2-tr3; + ch[t7]=ti2+ti3; + ci3=ti2-ti3; + cr2=tr1-tr4; + cr4=tr1+tr4; + ci2=ti1+ti4; + ci4=ti1-ti4; + + ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2; + ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2; + ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3; + ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3; + ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4; + ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4; + } + t1+=ido; + } + + if(ido%2 == 1)return; + + L105: + + t1=ido; + t2=ido<<2; + t3=ido-1; + t4=ido+(ido<<1); + for(k=0;k<l1;k++){ + t5=t3; + ti1=cc[t1]+cc[t4]; + ti2=cc[t4]-cc[t1]; + tr1=cc[t1-1]-cc[t4-1]; + tr2=cc[t1-1]+cc[t4-1]; + ch[t5]=tr2+tr2; + ch[t5+=t0]=sqrt2*(tr1-ti1); + ch[t5+=t0]=ti2+ti2; + ch[t5+=t0]=-sqrt2*(tr1+ti1); + + t3+=ido; + t1+=t2; + t4+=t2; + } +} + +static void dradbg(int ido,int ip,int l1,int idl1,float *cc,float *c1, + float *c2,float *ch,float *ch2,float *wa){ + static float tpi=6.283185307179586f; + int idij,ipph,i,j,k,l,ik,is,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10, + t11,t12; + float dc2,ai1,ai2,ar1,ar2,ds2; + int nbd; + float dcp,arg,dsp,ar1h,ar2h; + int ipp2; + + t10=ip*ido; + t0=l1*ido; + arg=tpi/(float)ip; + dcp=cos(arg); + dsp=sin(arg); + nbd=(ido-1)>>1; + ipp2=ip; + ipph=(ip+1)>>1; + if(ido<l1)goto L103; + + t1=0; + t2=0; + for(k=0;k<l1;k++){ + t3=t1; + t4=t2; + for(i=0;i<ido;i++){ + ch[t3]=cc[t4]; + t3++; + t4++; + } + t1+=ido; + t2+=t10; + } + goto L106; + + L103: + t1=0; + for(i=0;i<ido;i++){ + t2=t1; + t3=t1; + for(k=0;k<l1;k++){ + ch[t2]=cc[t3]; + t2+=ido; + t3+=t10; + } + t1++; + } + + L106: + t1=0; + t2=ipp2*t0; + t7=(t5=ido<<1); + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + t6=t5; + for(k=0;k<l1;k++){ + ch[t3]=cc[t6-1]+cc[t6-1]; + ch[t4]=cc[t6]+cc[t6]; + t3+=ido; + t4+=ido; + t6+=t10; + } + t5+=t7; + } + + if (ido == 1)goto L116; + if(nbd<l1)goto L112; + + t1=0; + t2=ipp2*t0; + t7=0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + + t7+=(ido<<1); + t8=t7; + for(k=0;k<l1;k++){ + t5=t3; + t6=t4; + t9=t8; + t11=t8; + for(i=2;i<ido;i+=2){ + t5+=2; + t6+=2; + t9+=2; + t11-=2; + ch[t5-1]=cc[t9-1]+cc[t11-1]; + ch[t6-1]=cc[t9-1]-cc[t11-1]; + ch[t5]=cc[t9]-cc[t11]; + ch[t6]=cc[t9]+cc[t11]; + } + t3+=ido; + t4+=ido; + t8+=t10; + } + } + goto L116; + + L112: + t1=0; + t2=ipp2*t0; + t7=0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + t7+=(ido<<1); + t8=t7; + t9=t7; + for(i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t8+=2; + t9-=2; + t5=t3; + t6=t4; + t11=t8; + t12=t9; + for(k=0;k<l1;k++){ + ch[t5-1]=cc[t11-1]+cc[t12-1]; + ch[t6-1]=cc[t11-1]-cc[t12-1]; + ch[t5]=cc[t11]-cc[t12]; + ch[t6]=cc[t11]+cc[t12]; + t5+=ido; + t6+=ido; + t11+=t10; + t12+=t10; + } + } + } + +L116: + ar1=1.f; + ai1=0.f; + t1=0; + t9=(t2=ipp2*idl1); + t3=(ip-1)*idl1; + for(l=1;l<ipph;l++){ + t1+=idl1; + t2-=idl1; + + ar1h=dcp*ar1-dsp*ai1; + ai1=dcp*ai1+dsp*ar1; + ar1=ar1h; + t4=t1; + t5=t2; + t6=0; + t7=idl1; + t8=t3; + for(ik=0;ik<idl1;ik++){ + c2[t4++]=ch2[t6++]+ar1*ch2[t7++]; + c2[t5++]=ai1*ch2[t8++]; + } + dc2=ar1; + ds2=ai1; + ar2=ar1; + ai2=ai1; + + t6=idl1; + t7=t9-idl1; + for(j=2;j<ipph;j++){ + t6+=idl1; + t7-=idl1; + ar2h=dc2*ar2-ds2*ai2; + ai2=dc2*ai2+ds2*ar2; + ar2=ar2h; + t4=t1; + t5=t2; + t11=t6; + t12=t7; + for(ik=0;ik<idl1;ik++){ + c2[t4++]+=ar2*ch2[t11++]; + c2[t5++]+=ai2*ch2[t12++]; + } + } + } + + t1=0; + for(j=1;j<ipph;j++){ + t1+=idl1; + t2=t1; + for(ik=0;ik<idl1;ik++)ch2[ik]+=ch2[t2++]; + } + + t1=0; + t2=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(k=0;k<l1;k++){ + ch[t3]=c1[t3]-c1[t4]; + ch[t4]=c1[t3]+c1[t4]; + t3+=ido; + t4+=ido; + } + } + + if(ido==1)goto L132; + if(nbd<l1)goto L128; + + t1=0; + t2=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(k=0;k<l1;k++){ + t5=t3; + t6=t4; + for(i=2;i<ido;i+=2){ + t5+=2; + t6+=2; + ch[t5-1]=c1[t5-1]-c1[t6]; + ch[t6-1]=c1[t5-1]+c1[t6]; + ch[t5]=c1[t5]+c1[t6-1]; + ch[t6]=c1[t5]-c1[t6-1]; + } + t3+=ido; + t4+=ido; + } + } + goto L132; + + L128: + t1=0; + t2=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t5=t3; + t6=t4; + for(k=0;k<l1;k++){ + ch[t5-1]=c1[t5-1]-c1[t6]; + ch[t6-1]=c1[t5-1]+c1[t6]; + ch[t5]=c1[t5]+c1[t6-1]; + ch[t6]=c1[t5]-c1[t6-1]; + t5+=ido; + t6+=ido; + } + } + } + +L132: + if(ido==1)return; + + for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik]; + + t1=0; + for(j=1;j<ip;j++){ + t2=(t1+=t0); + for(k=0;k<l1;k++){ + c1[t2]=ch[t2]; + t2+=ido; + } + } + + if(nbd>l1)goto L139; + + is= -ido-1; + t1=0; + for(j=1;j<ip;j++){ + is+=ido; + t1+=t0; + idij=is; + t2=t1; + for(i=2;i<ido;i+=2){ + t2+=2; + idij+=2; + t3=t2; + for(k=0;k<l1;k++){ + c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3]; + c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1]; + t3+=ido; + } + } + } + return; + + L139: + is= -ido-1; + t1=0; + for(j=1;j<ip;j++){ + is+=ido; + t1+=t0; + t2=t1; + for(k=0;k<l1;k++){ + idij=is; + t3=t2; + for(i=2;i<ido;i+=2){ + idij+=2; + t3+=2; + c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3]; + c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1]; + } + t2+=ido; + } + } +} + +static void drftb1(int n, float *c, float *ch, float *wa, int *ifac){ + int i,k1,l1,l2; + int na; + int nf,ip,iw,ix2,ix3,ido,idl1; + + nf=ifac[1]; + na=0; + l1=1; + iw=1; + + for(k1=0;k1<nf;k1++){ + ip=ifac[k1 + 2]; + l2=ip*l1; + ido=n/l2; + idl1=ido*l1; + if(ip!=4)goto L103; + ix2=iw+ido; + ix3=ix2+ido; + + if(na!=0) + dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1); + else + dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1); + na=1-na; + goto L115; + + L103: + if(ip!=2)goto L106; + + if(na!=0) + dradb2(ido,l1,ch,c,wa+iw-1); + else + dradb2(ido,l1,c,ch,wa+iw-1); + na=1-na; + goto L115; + + L106: + if(ip!=3)goto L109; + + ix2=iw+ido; + if(na!=0) + dradb3(ido,l1,ch,c,wa+iw-1,wa+ix2-1); + else + dradb3(ido,l1,c,ch,wa+iw-1,wa+ix2-1); + na=1-na; + goto L115; + + L109: +/* The radix five case can be translated later..... */ +/* if(ip!=5)goto L112; + + ix2=iw+ido; + ix3=ix2+ido; + ix4=ix3+ido; + if(na!=0) + dradb5(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1); + else + dradb5(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1); + na=1-na; + goto L115; + + L112:*/ + if(na!=0) + dradbg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1); + else + dradbg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1); + if(ido==1)na=1-na; + + L115: + l1=l2; + iw+=(ip-1)*ido; + } + + if(na==0)return; + + for(i=0;i<n;i++)c[i]=ch[i]; +} + +void spx_drft_forward(struct drft_lookup *l,float *data){ + if(l->n==1)return; + drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); +} + +void spx_drft_backward(struct drft_lookup *l,float *data){ + if (l->n==1)return; + drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); +} + +void spx_drft_init(struct drft_lookup *l,int n) +{ + l->n=n; + l->trigcache=(float*)speex_alloc(3*n*sizeof(*l->trigcache)); + l->splitcache=(int*)speex_alloc(32*sizeof(*l->splitcache)); + fdrffti(n, l->trigcache, l->splitcache); +} + +void spx_drft_clear(struct drft_lookup *l) +{ + if(l) + { + if(l->trigcache) + speex_free(l->trigcache); + if(l->splitcache) + speex_free(l->splitcache); + } +} diff --git a/src/libs/speexdsp/libspeexdsp/smallft.h b/src/libs/speexdsp/libspeexdsp/smallft.h new file mode 100644 index 00000000..446e2f65 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/smallft.h @@ -0,0 +1,46 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: fft transform + last mod: $Id: smallft.h,v 1.3 2003/09/16 18:35:45 jm Exp $ + + ********************************************************************/ +/** + @file smallft.h + @brief Discrete Rotational Fourier Transform (DRFT) +*/ + +#ifndef _V_SMFT_H_ +#define _V_SMFT_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** Discrete Rotational Fourier Transform lookup */ +struct drft_lookup{ + int n; + float *trigcache; + int *splitcache; +}; + +extern void spx_drft_forward(struct drft_lookup *l,float *data); +extern void spx_drft_backward(struct drft_lookup *l,float *data); +extern void spx_drft_init(struct drft_lookup *l,int n); +extern void spx_drft_clear(struct drft_lookup *l); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/speex_preprocess.c b/src/libs/speexdsp/libspeexdsp/speex_preprocess.c new file mode 100644 index 00000000..b8e287a7 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/speex_preprocess.c @@ -0,0 +1,1215 @@ +/* Copyright (C) 2003 Epic Games (written by Jean-Marc Valin) + Copyright (C) 2004-2006 Epic Games + + File: preprocess.c + Preprocessor with denoising based on the algorithm by Ephraim and Malah + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +/* + Recommended papers: + + Y. Ephraim and D. Malah, "Speech enhancement using minimum mean-square error + short-time spectral amplitude estimator". IEEE Transactions on Acoustics, + Speech and Signal Processing, vol. ASSP-32, no. 6, pp. 1109-1121, 1984. + + Y. Ephraim and D. Malah, "Speech enhancement using minimum mean-square error + log-spectral amplitude estimator". IEEE Transactions on Acoustics, Speech and + Signal Processing, vol. ASSP-33, no. 2, pp. 443-445, 1985. + + I. Cohen and B. Berdugo, "Speech enhancement for non-stationary noise environments". + Signal Processing, vol. 81, no. 2, pp. 2403-2418, 2001. + + Stefan Gustafsson, Rainer Martin, Peter Jax, and Peter Vary. "A psychoacoustic + approach to combined acoustic echo cancellation and noise reduction". IEEE + Transactions on Speech and Audio Processing, 2002. + + J.-M. Valin, J. Rouat, and F. Michaud, "Microphone array post-filter for separation + of simultaneous non-stationary sources". In Proceedings IEEE International + Conference on Acoustics, Speech, and Signal Processing, 2004. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <math.h> +#include "speex/speex_preprocess.h" +#include "speex/speex_echo.h" +#include "arch.h" +#include "fftwrap.h" +#include "filterbank.h" +#include "math_approx.h" +#include "os_support.h" + +#define LOUDNESS_EXP 5.f +#define AMP_SCALE .001f +#define AMP_SCALE_1 1000.f + +#define NB_BANDS 24 + +#define SPEECH_PROB_START_DEFAULT QCONST16(0.35f,15) +#define SPEECH_PROB_CONTINUE_DEFAULT QCONST16(0.20f,15) +#define NOISE_SUPPRESS_DEFAULT -15 +#define ECHO_SUPPRESS_DEFAULT -40 +#define ECHO_SUPPRESS_ACTIVE_DEFAULT -15 + +#ifndef NULL +#define NULL 0 +#endif + +#define SQR(x) ((x)*(x)) +#define SQR16(x) (MULT16_16((x),(x))) +#define SQR16_Q15(x) (MULT16_16_Q15((x),(x))) + +#ifdef FIXED_POINT +static inline spx_word16_t DIV32_16_Q8(spx_word32_t a, spx_word32_t b) +{ + if (SHR32(a,7) >= b) + { + return 32767; + } else { + if (b>=QCONST32(1,23)) + { + a = SHR32(a,8); + b = SHR32(b,8); + } + if (b>=QCONST32(1,19)) + { + a = SHR32(a,4); + b = SHR32(b,4); + } + if (b>=QCONST32(1,15)) + { + a = SHR32(a,4); + b = SHR32(b,4); + } + a = SHL32(a,8); + return PDIV32_16(a,b); + } + +} +static inline spx_word16_t DIV32_16_Q15(spx_word32_t a, spx_word32_t b) +{ + if (SHR32(a,15) >= b) + { + return 32767; + } else { + if (b>=QCONST32(1,23)) + { + a = SHR32(a,8); + b = SHR32(b,8); + } + if (b>=QCONST32(1,19)) + { + a = SHR32(a,4); + b = SHR32(b,4); + } + if (b>=QCONST32(1,15)) + { + a = SHR32(a,4); + b = SHR32(b,4); + } + a = SHL32(a,15)-a; + return DIV32_16(a,b); + } +} +#define SNR_SCALING 256.f +#define SNR_SCALING_1 0.0039062f +#define SNR_SHIFT 8 + +#define FRAC_SCALING 32767.f +#define FRAC_SCALING_1 3.0518e-05 +#define FRAC_SHIFT 1 + +#define EXPIN_SCALING 2048.f +#define EXPIN_SCALING_1 0.00048828f +#define EXPIN_SHIFT 11 +#define EXPOUT_SCALING_1 1.5259e-05 + +#define NOISE_SHIFT 7 + +#else + +#define DIV32_16_Q8(a,b) ((a)/(b)) +#define DIV32_16_Q15(a,b) ((a)/(b)) +#define SNR_SCALING 1.f +#define SNR_SCALING_1 1.f +#define SNR_SHIFT 0 +#define FRAC_SCALING 1.f +#define FRAC_SCALING_1 1.f +#define FRAC_SHIFT 0 +#define NOISE_SHIFT 0 + +#define EXPIN_SCALING 1.f +#define EXPIN_SCALING_1 1.f +#define EXPOUT_SCALING_1 1.f + +#endif + +/** Speex pre-processor state. */ +struct SpeexPreprocessState_ { + /* Basic info */ + int frame_size; /**< Number of samples processed each time */ + int ps_size; /**< Number of points in the power spectrum */ + int sampling_rate; /**< Sampling rate of the input/output */ + int nbands; + FilterBank *bank; + + /* Parameters */ + int denoise_enabled; + int vad_enabled; + int dereverb_enabled; + spx_word16_t reverb_decay; + spx_word16_t reverb_level; + spx_word16_t speech_prob_start; + spx_word16_t speech_prob_continue; + int noise_suppress; + int echo_suppress; + int echo_suppress_active; + SpeexEchoState *echo_state; + + spx_word16_t speech_prob; /**< Probability last frame was speech */ + + /* DSP-related arrays */ + spx_word16_t *frame; /**< Processing frame (2*ps_size) */ + spx_word16_t *ft; /**< Processing frame in freq domain (2*ps_size) */ + spx_word32_t *ps; /**< Current power spectrum */ + spx_word16_t *gain2; /**< Adjusted gains */ + spx_word16_t *gain_floor; /**< Minimum gain allowed */ + spx_word16_t *window; /**< Analysis/Synthesis window */ + spx_word32_t *noise; /**< Noise estimate */ + spx_word32_t *reverb_estimate; /**< Estimate of reverb energy */ + spx_word32_t *old_ps; /**< Power spectrum for last frame */ + spx_word16_t *gain; /**< Ephraim Malah gain */ + spx_word16_t *prior; /**< A-priori SNR */ + spx_word16_t *post; /**< A-posteriori SNR */ + + spx_word32_t *S; /**< Smoothed power spectrum */ + spx_word32_t *Smin; /**< See Cohen paper */ + spx_word32_t *Stmp; /**< See Cohen paper */ + int *update_prob; /**< Probability of speech presence for noise update */ + + spx_word16_t *zeta; /**< Smoothed a priori SNR */ + spx_word32_t *echo_noise; + spx_word32_t *residual_echo; + + /* Misc */ + spx_word16_t *inbuf; /**< Input buffer (overlapped analysis) */ + spx_word16_t *outbuf; /**< Output buffer (for overlap and add) */ + + /* AGC stuff, only for floating point for now */ +#ifndef FIXED_POINT + int agc_enabled; + float agc_level; + float loudness_accum; + float *loudness_weight; /**< Perceptual loudness curve */ + float loudness; /**< Loudness estimate */ + float agc_gain; /**< Current AGC gain */ + float max_gain; /**< Maximum gain allowed */ + float max_increase_step; /**< Maximum increase in gain from one frame to another */ + float max_decrease_step; /**< Maximum decrease in gain from one frame to another */ + float prev_loudness; /**< Loudness of previous frame */ + float init_max; /**< Current gain limit during initialisation */ +#endif + int nb_adapt; /**< Number of frames used for adaptation so far */ + int was_speech; + int min_count; /**< Number of frames processed so far */ + void *fft_lookup; /**< Lookup table for the FFT */ +#ifdef FIXED_POINT + int frame_shift; +#endif +}; + + +static void conj_window(spx_word16_t *w, int len) +{ + int i; + for (i=0;i<len;i++) + { + spx_word16_t tmp; +#ifdef FIXED_POINT + spx_word16_t x = DIV32_16(MULT16_16(32767,i),len); +#else + spx_word16_t x = DIV32_16(MULT16_16(QCONST16(4.f,13),i),len); +#endif + int inv=0; + if (x<QCONST16(1.f,13)) + { + } else if (x<QCONST16(2.f,13)) + { + x=QCONST16(2.f,13)-x; + inv=1; + } else if (x<QCONST16(3.f,13)) + { + x=x-QCONST16(2.f,13); + inv=1; + } else { + x=QCONST16(2.f,13)-x+QCONST16(2.f,13); /* 4 - x */ + } + x = MULT16_16_Q14(QCONST16(1.271903f,14), x); + tmp = SQR16_Q15(QCONST16(.5f,15)-MULT16_16_P15(QCONST16(.5f,15),spx_cos_norm(SHL32(EXTEND32(x),2)))); + if (inv) + tmp=SUB16(Q15_ONE,tmp); + w[i]=spx_sqrt(SHL32(EXTEND32(tmp),15)); + } +} + + +#ifdef FIXED_POINT +/* This function approximates the gain function + y = gamma(1.25)^2 * M(-.25;1;-x) / sqrt(x) + which multiplied by xi/(1+xi) is the optimal gain + in the loudness domain ( sqrt[amplitude] ) + Input in Q11 format, output in Q15 +*/ +static inline spx_word32_t hypergeom_gain(spx_word32_t xx) +{ + int ind; + spx_word16_t frac; + /* Q13 table */ + static const spx_word16_t table[21] = { + 6730, 8357, 9868, 11267, 12563, 13770, 14898, + 15959, 16961, 17911, 18816, 19682, 20512, 21311, + 22082, 22827, 23549, 24250, 24931, 25594, 26241}; + ind = SHR32(xx,10); + if (ind<0) + return Q15_ONE; + if (ind>19) + return ADD32(EXTEND32(Q15_ONE),EXTEND32(DIV32_16(QCONST32(.1296,23), SHR32(xx,EXPIN_SHIFT-SNR_SHIFT)))); + frac = SHL32(xx-SHL32(ind,10),5); + return SHL32(DIV32_16(PSHR32(MULT16_16(Q15_ONE-frac,table[ind]) + MULT16_16(frac,table[ind+1]),7),(spx_sqrt(SHL32(xx,15)+6711))),7); +} + +static inline spx_word16_t qcurve(spx_word16_t x) +{ + x = MAX16(x, 1); + return DIV32_16(SHL32(EXTEND32(32767),9),ADD16(512,MULT16_16_Q15(QCONST16(.60f,15),DIV32_16(32767,x)))); +} + +/* Compute the gain floor based on different floors for the background noise and residual echo */ +static void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len) +{ + int i; + + if (noise_suppress > effective_echo_suppress) + { + spx_word16_t noise_gain, gain_ratio; + noise_gain = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(0.11513,11),noise_suppress)),1))); + gain_ratio = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(.2302585f,11),effective_echo_suppress-noise_suppress)),1))); + + /* gain_floor = sqrt [ (noise*noise_floor + echo*echo_floor) / (noise+echo) ] */ + for (i=0;i<len;i++) + gain_floor[i] = MULT16_16_Q15(noise_gain, + spx_sqrt(SHL32(EXTEND32(DIV32_16_Q15(PSHR32(noise[i],NOISE_SHIFT) + MULT16_32_Q15(gain_ratio,echo[i]), + (1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]) )),15))); + } else { + spx_word16_t echo_gain, gain_ratio; + echo_gain = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(0.11513,11),effective_echo_suppress)),1))); + gain_ratio = EXTRACT16(MIN32(Q15_ONE,SHR32(spx_exp(MULT16_16(QCONST16(.2302585f,11),noise_suppress-effective_echo_suppress)),1))); + + /* gain_floor = sqrt [ (noise*noise_floor + echo*echo_floor) / (noise+echo) ] */ + for (i=0;i<len;i++) + gain_floor[i] = MULT16_16_Q15(echo_gain, + spx_sqrt(SHL32(EXTEND32(DIV32_16_Q15(MULT16_32_Q15(gain_ratio,PSHR32(noise[i],NOISE_SHIFT)) + echo[i], + (1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]) )),15))); + } +} + +#else +/* This function approximates the gain function + y = gamma(1.25)^2 * M(-.25;1;-x) / sqrt(x) + which multiplied by xi/(1+xi) is the optimal gain + in the loudness domain ( sqrt[amplitude] ) +*/ +static inline spx_word32_t hypergeom_gain(spx_word32_t xx) +{ + int ind; + float integer, frac; + float x; + static const float table[21] = { + 0.82157f, 1.02017f, 1.20461f, 1.37534f, 1.53363f, 1.68092f, 1.81865f, + 1.94811f, 2.07038f, 2.18638f, 2.29688f, 2.40255f, 2.50391f, 2.60144f, + 2.69551f, 2.78647f, 2.87458f, 2.96015f, 3.04333f, 3.12431f, 3.20326f}; + x = EXPIN_SCALING_1*xx; + integer = floor(2*x); + ind = (int)integer; + if (ind<0) + return FRAC_SCALING; + if (ind>19) + return FRAC_SCALING*(1+.1296/x); + frac = 2*x-integer; + return FRAC_SCALING*((1-frac)*table[ind] + frac*table[ind+1])/sqrt(x+.0001f); +} + +static inline spx_word16_t qcurve(spx_word16_t x) +{ + return 1.f/(1.f+.15f/(SNR_SCALING_1*x)); +} + +static void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len) +{ + int i; + float echo_floor; + float noise_floor; + + noise_floor = exp(.2302585f*noise_suppress); + echo_floor = exp(.2302585f*effective_echo_suppress); + + /* Compute the gain floor based on different floors for the background noise and residual echo */ + for (i=0;i<len;i++) + gain_floor[i] = FRAC_SCALING*sqrt(noise_floor*PSHR32(noise[i],NOISE_SHIFT) + echo_floor*echo[i])/sqrt(1+PSHR32(noise[i],NOISE_SHIFT) + echo[i]); +} + +#endif +EXPORT SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate) +{ + int i; + int N, N3, N4, M; + + SpeexPreprocessState *st = (SpeexPreprocessState *)speex_alloc(sizeof(SpeexPreprocessState)); + st->frame_size = frame_size; + + /* Round ps_size down to the nearest power of two */ +#if 0 + i=1; + st->ps_size = st->frame_size; + while(1) + { + if (st->ps_size & ~i) + { + st->ps_size &= ~i; + i<<=1; + } else { + break; + } + } + + + if (st->ps_size < 3*st->frame_size/4) + st->ps_size = st->ps_size * 3 / 2; +#else + st->ps_size = st->frame_size; +#endif + + N = st->ps_size; + N3 = 2*N - st->frame_size; + N4 = st->frame_size - N3; + + st->sampling_rate = sampling_rate; + st->denoise_enabled = 1; + st->vad_enabled = 0; + st->dereverb_enabled = 0; + st->reverb_decay = 0; + st->reverb_level = 0; + st->noise_suppress = NOISE_SUPPRESS_DEFAULT; + st->echo_suppress = ECHO_SUPPRESS_DEFAULT; + st->echo_suppress_active = ECHO_SUPPRESS_ACTIVE_DEFAULT; + + st->speech_prob_start = SPEECH_PROB_START_DEFAULT; + st->speech_prob_continue = SPEECH_PROB_CONTINUE_DEFAULT; + + st->echo_state = NULL; + + st->nbands = NB_BANDS; + M = st->nbands; + st->bank = filterbank_new(M, sampling_rate, N, 1); + + st->frame = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t)); + st->window = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t)); + st->ft = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t)); + + st->ps = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->noise = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->echo_noise = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->residual_echo = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->reverb_estimate = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->old_ps = (spx_word32_t*)speex_alloc((N+M)*sizeof(spx_word32_t)); + st->prior = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->post = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->gain = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->gain2 = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->gain_floor = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + st->zeta = (spx_word16_t*)speex_alloc((N+M)*sizeof(spx_word16_t)); + + st->S = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); + st->Smin = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); + st->Stmp = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t)); + st->update_prob = (int*)speex_alloc(N*sizeof(int)); + + st->inbuf = (spx_word16_t*)speex_alloc(N3*sizeof(spx_word16_t)); + st->outbuf = (spx_word16_t*)speex_alloc(N3*sizeof(spx_word16_t)); + + conj_window(st->window, 2*N3); + for (i=2*N3;i<2*st->ps_size;i++) + st->window[i]=Q15_ONE; + + if (N4>0) + { + for (i=N3-1;i>=0;i--) + { + st->window[i+N3+N4]=st->window[i+N3]; + st->window[i+N3]=1; + } + } + for (i=0;i<N+M;i++) + { + st->noise[i]=QCONST32(1.f,NOISE_SHIFT); + st->reverb_estimate[i]=0; + st->old_ps[i]=1; + st->gain[i]=Q15_ONE; + st->post[i]=SHL16(1, SNR_SHIFT); + st->prior[i]=SHL16(1, SNR_SHIFT); + } + + for (i=0;i<N;i++) + st->update_prob[i] = 1; + for (i=0;i<N3;i++) + { + st->inbuf[i]=0; + st->outbuf[i]=0; + } +#ifndef FIXED_POINT + st->agc_enabled = 0; + st->agc_level = 8000; + st->loudness_weight = (float*)speex_alloc(N*sizeof(float)); + for (i=0;i<N;i++) + { + float ff=((float)i)*.5*sampling_rate/((float)N); + /*st->loudness_weight[i] = .5f*(1.f/(1.f+ff/8000.f))+1.f*exp(-.5f*(ff-3800.f)*(ff-3800.f)/9e5f);*/ + st->loudness_weight[i] = .35f-.35f*ff/16000.f+.73f*exp(-.5f*(ff-3800)*(ff-3800)/9e5f); + if (st->loudness_weight[i]<.01f) + st->loudness_weight[i]=.01f; + st->loudness_weight[i] *= st->loudness_weight[i]; + } + /*st->loudness = pow(AMP_SCALE*st->agc_level,LOUDNESS_EXP);*/ + st->loudness = 1e-15; + st->agc_gain = 1; + st->max_gain = 30; + st->max_increase_step = exp(0.11513f * 12.*st->frame_size / st->sampling_rate); + st->max_decrease_step = exp(-0.11513f * 40.*st->frame_size / st->sampling_rate); + st->prev_loudness = 1; + st->init_max = 1; +#endif + st->was_speech = 0; + + st->fft_lookup = spx_fft_init(2*N); + + st->nb_adapt=0; + st->min_count=0; + return st; +} + +EXPORT void speex_preprocess_state_destroy(SpeexPreprocessState *st) +{ + speex_free(st->frame); + speex_free(st->ft); + speex_free(st->ps); + speex_free(st->gain2); + speex_free(st->gain_floor); + speex_free(st->window); + speex_free(st->noise); + speex_free(st->reverb_estimate); + speex_free(st->old_ps); + speex_free(st->gain); + speex_free(st->prior); + speex_free(st->post); +#ifndef FIXED_POINT + speex_free(st->loudness_weight); +#endif + speex_free(st->echo_noise); + speex_free(st->residual_echo); + + speex_free(st->S); + speex_free(st->Smin); + speex_free(st->Stmp); + speex_free(st->update_prob); + speex_free(st->zeta); + + speex_free(st->inbuf); + speex_free(st->outbuf); + + spx_fft_destroy(st->fft_lookup); + filterbank_destroy(st->bank); + speex_free(st); +} + +/* FIXME: The AGC doesn't work yet with fixed-point*/ +#ifndef FIXED_POINT +static void speex_compute_agc(SpeexPreprocessState *st, spx_word16_t Pframe, spx_word16_t *ft) +{ + int i; + int N = st->ps_size; + float target_gain; + float loudness=1.f; + float rate; + + for (i=2;i<N;i++) + { + loudness += 2.f*N*st->ps[i]* st->loudness_weight[i]; + } + loudness=sqrt(loudness); + /*if (loudness < 2*pow(st->loudness, 1.0/LOUDNESS_EXP) && + loudness*2 > pow(st->loudness, 1.0/LOUDNESS_EXP))*/ + if (Pframe>.3f) + { + /*rate=2.0f*Pframe*Pframe/(1+st->nb_loudness_adapt);*/ + rate = .03*Pframe*Pframe; + st->loudness = (1-rate)*st->loudness + (rate)*pow(AMP_SCALE*loudness, LOUDNESS_EXP); + st->loudness_accum = (1-rate)*st->loudness_accum + rate; + if (st->init_max < st->max_gain && st->nb_adapt > 20) + st->init_max *= 1.f + .1f*Pframe*Pframe; + } + /*printf ("%f %f %f %f\n", Pframe, loudness, pow(st->loudness, 1.0f/LOUDNESS_EXP), st->loudness2);*/ + + target_gain = AMP_SCALE*st->agc_level*pow(st->loudness/(1e-4+st->loudness_accum), -1.0f/LOUDNESS_EXP); + + if ((Pframe>.5 && st->nb_adapt > 20) || target_gain < st->agc_gain) + { + if (target_gain > st->max_increase_step*st->agc_gain) + target_gain = st->max_increase_step*st->agc_gain; + if (target_gain < st->max_decrease_step*st->agc_gain && loudness < 10*st->prev_loudness) + target_gain = st->max_decrease_step*st->agc_gain; + if (target_gain > st->max_gain) + target_gain = st->max_gain; + if (target_gain > st->init_max) + target_gain = st->init_max; + + st->agc_gain = target_gain; + } + /*fprintf (stderr, "%f %f %f\n", loudness, (float)AMP_SCALE_1*pow(st->loudness, 1.0f/LOUDNESS_EXP), st->agc_gain);*/ + + for (i=0;i<2*N;i++) + ft[i] *= st->agc_gain; + st->prev_loudness = loudness; +} +#endif + +static void preprocess_analysis(SpeexPreprocessState *st, spx_int16_t *x) +{ + int i; + int N = st->ps_size; + int N3 = 2*N - st->frame_size; + int N4 = st->frame_size - N3; + spx_word32_t *ps=st->ps; + + /* 'Build' input frame */ + for (i=0;i<N3;i++) + st->frame[i]=st->inbuf[i]; + for (i=0;i<st->frame_size;i++) + st->frame[N3+i]=x[i]; + + /* Update inbuf */ + for (i=0;i<N3;i++) + st->inbuf[i]=x[N4+i]; + + /* Windowing */ + for (i=0;i<2*N;i++) + st->frame[i] = MULT16_16_Q15(st->frame[i], st->window[i]); + +#ifdef FIXED_POINT + { + spx_word16_t max_val=0; + for (i=0;i<2*N;i++) + max_val = MAX16(max_val, ABS16(st->frame[i])); + st->frame_shift = 14-spx_ilog2(EXTEND32(max_val)); + for (i=0;i<2*N;i++) + st->frame[i] = SHL16(st->frame[i], st->frame_shift); + } +#endif + + /* Perform FFT */ + spx_fft(st->fft_lookup, st->frame, st->ft); + + /* Power spectrum */ + ps[0]=MULT16_16(st->ft[0],st->ft[0]); + for (i=1;i<N;i++) + ps[i]=MULT16_16(st->ft[2*i-1],st->ft[2*i-1]) + MULT16_16(st->ft[2*i],st->ft[2*i]); + for (i=0;i<N;i++) + st->ps[i] = PSHR32(st->ps[i], 2*st->frame_shift); + + filterbank_compute_bank32(st->bank, ps, ps+N); +} + +static void update_noise_prob(SpeexPreprocessState *st) +{ + int i; + int min_range; + int N = st->ps_size; + + for (i=1;i<N-1;i++) + st->S[i] = MULT16_32_Q15(QCONST16(.8f,15),st->S[i]) + MULT16_32_Q15(QCONST16(.05f,15),st->ps[i-1]) + + MULT16_32_Q15(QCONST16(.1f,15),st->ps[i]) + MULT16_32_Q15(QCONST16(.05f,15),st->ps[i+1]); + st->S[0] = MULT16_32_Q15(QCONST16(.8f,15),st->S[0]) + MULT16_32_Q15(QCONST16(.2f,15),st->ps[0]); + st->S[N-1] = MULT16_32_Q15(QCONST16(.8f,15),st->S[N-1]) + MULT16_32_Q15(QCONST16(.2f,15),st->ps[N-1]); + + if (st->nb_adapt==1) + { + for (i=0;i<N;i++) + st->Smin[i] = st->Stmp[i] = 0; + } + + if (st->nb_adapt < 100) + min_range = 15; + else if (st->nb_adapt < 1000) + min_range = 50; + else if (st->nb_adapt < 10000) + min_range = 150; + else + min_range = 300; + if (st->min_count > min_range) + { + st->min_count = 0; + for (i=0;i<N;i++) + { + st->Smin[i] = MIN32(st->Stmp[i], st->S[i]); + st->Stmp[i] = st->S[i]; + } + } else { + for (i=0;i<N;i++) + { + st->Smin[i] = MIN32(st->Smin[i], st->S[i]); + st->Stmp[i] = MIN32(st->Stmp[i], st->S[i]); + } + } + for (i=0;i<N;i++) + { + if (MULT16_32_Q15(QCONST16(.4f,15),st->S[i]) > st->Smin[i]) + st->update_prob[i] = 1; + else + st->update_prob[i] = 0; + /*fprintf (stderr, "%f ", st->S[i]/st->Smin[i]);*/ + /*fprintf (stderr, "%f ", st->update_prob[i]);*/ + } + +} + +#define NOISE_OVERCOMPENS 1. + +void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len); + +EXPORT int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo) +{ + return speex_preprocess_run(st, x); +} + +EXPORT int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x) +{ + int i; + int M; + int N = st->ps_size; + int N3 = 2*N - st->frame_size; + int N4 = st->frame_size - N3; + spx_word32_t *ps=st->ps; + spx_word32_t Zframe; + spx_word16_t Pframe; + spx_word16_t beta, beta_1; + spx_word16_t effective_echo_suppress; + + st->nb_adapt++; + if (st->nb_adapt>20000) + st->nb_adapt = 20000; + st->min_count++; + + beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt)); + beta_1 = Q15_ONE-beta; + M = st->nbands; + /* Deal with residual echo if provided */ + if (st->echo_state) + { + speex_echo_get_residual(st->echo_state, st->residual_echo, N); +#ifndef FIXED_POINT + /* If there are NaNs or ridiculous values, it'll show up in the DC and we just reset everything to zero */ + if (!(st->residual_echo[0] >=0 && st->residual_echo[0]<N*1e9f)) + { + for (i=0;i<N;i++) + st->residual_echo[i] = 0; + } +#endif + for (i=0;i<N;i++) + st->echo_noise[i] = MAX32(MULT16_32_Q15(QCONST16(.6f,15),st->echo_noise[i]), st->residual_echo[i]); + filterbank_compute_bank32(st->bank, st->echo_noise, st->echo_noise+N); + } else { + for (i=0;i<N+M;i++) + st->echo_noise[i] = 0; + } + preprocess_analysis(st, x); + + update_noise_prob(st); + + /* Noise estimation always updated for the 10 first frames */ + /*if (st->nb_adapt<10) + { + for (i=1;i<N-1;i++) + st->update_prob[i] = 0; + } + */ + + /* Update the noise estimate for the frequencies where it can be */ + for (i=0;i<N;i++) + { + if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i], NOISE_SHIFT)) + st->noise[i] = MAX32(EXTEND32(0),MULT16_32_Q15(beta_1,st->noise[i]) + MULT16_32_Q15(beta,SHL32(st->ps[i],NOISE_SHIFT))); + } + filterbank_compute_bank32(st->bank, st->noise, st->noise+N); + + /* Special case for first frame */ + if (st->nb_adapt==1) + for (i=0;i<N+M;i++) + st->old_ps[i] = ps[i]; + + /* Compute a posteriori SNR */ + for (i=0;i<N+M;i++) + { + spx_word16_t gamma; + + /* Total noise estimate including residual echo and reverberation */ + spx_word32_t tot_noise = ADD32(ADD32(ADD32(EXTEND32(1), PSHR32(st->noise[i],NOISE_SHIFT)) , st->echo_noise[i]) , st->reverb_estimate[i]); + + /* A posteriori SNR = ps/noise - 1*/ + st->post[i] = SUB16(DIV32_16_Q8(ps[i],tot_noise), QCONST16(1.f,SNR_SHIFT)); + st->post[i]=MIN16(st->post[i], QCONST16(100.f,SNR_SHIFT)); + + /* Computing update gamma = .1 + .9*(old/(old+noise))^2 */ + gamma = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.89f,15),SQR16_Q15(DIV32_16_Q15(st->old_ps[i],ADD32(st->old_ps[i],tot_noise)))); + + /* A priori SNR update = gamma*max(0,post) + (1-gamma)*old/noise */ + st->prior[i] = EXTRACT16(PSHR32(ADD32(MULT16_16(gamma,MAX16(0,st->post[i])), MULT16_16(Q15_ONE-gamma,DIV32_16_Q8(st->old_ps[i],tot_noise))), 15)); + st->prior[i]=MIN16(st->prior[i], QCONST16(100.f,SNR_SHIFT)); + } + + /*print_vec(st->post, N+M, "");*/ + + /* Recursive average of the a priori SNR. A bit smoothed for the psd components */ + st->zeta[0] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[0]), MULT16_16(QCONST16(.3f,15),st->prior[0])),15); + for (i=1;i<N-1;i++) + st->zeta[i] = PSHR32(ADD32(ADD32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[i]), MULT16_16(QCONST16(.15f,15),st->prior[i])), + MULT16_16(QCONST16(.075f,15),st->prior[i-1])), MULT16_16(QCONST16(.075f,15),st->prior[i+1])),15); + for (i=N-1;i<N+M;i++) + st->zeta[i] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),st->zeta[i]), MULT16_16(QCONST16(.3f,15),st->prior[i])),15); + + /* Speech probability of presence for the entire frame is based on the average filterbank a priori SNR */ + Zframe = 0; + for (i=N;i<N+M;i++) + Zframe = ADD32(Zframe, EXTEND32(st->zeta[i])); + Pframe = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.899f,15),qcurve(DIV32_16(Zframe,st->nbands))); + + effective_echo_suppress = EXTRACT16(PSHR32(ADD32(MULT16_16(SUB16(Q15_ONE,Pframe), st->echo_suppress), MULT16_16(Pframe, st->echo_suppress_active)),15)); + + compute_gain_floor(st->noise_suppress, effective_echo_suppress, st->noise+N, st->echo_noise+N, st->gain_floor+N, M); + + /* Compute Ephraim & Malah gain speech probability of presence for each critical band (Bark scale) + Technically this is actually wrong because the EM gaim assumes a slightly different probability + distribution */ + for (i=N;i<N+M;i++) + { + /* See EM and Cohen papers*/ + spx_word32_t theta; + /* Gain from hypergeometric function */ + spx_word32_t MM; + /* Weiner filter gain */ + spx_word16_t prior_ratio; + /* a priority probability of speech presence based on Bark sub-band alone */ + spx_word16_t P1; + /* Speech absence a priori probability (considering sub-band and frame) */ + spx_word16_t q; +#ifdef FIXED_POINT + spx_word16_t tmp; +#endif + + prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT))); + theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT)); + + MM = hypergeom_gain(theta); + /* Gain with bound */ + st->gain[i] = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM))); + /* Save old Bark power spectrum */ + st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]); + + P1 = QCONST16(.199f,15)+MULT16_16_Q15(QCONST16(.8f,15),qcurve (st->zeta[i])); + q = Q15_ONE-MULT16_16_Q15(Pframe,P1); +#ifdef FIXED_POINT + theta = MIN32(theta, EXTEND32(32767)); +/*Q8*/tmp = MULT16_16_Q15((SHL32(1,SNR_SHIFT)+st->prior[i]),EXTRACT16(MIN32(Q15ONE,SHR32(spx_exp(-EXTRACT16(theta)),1)))); + tmp = MIN16(QCONST16(3.,SNR_SHIFT), tmp); /* Prevent overflows in the next line*/ +/*Q8*/tmp = EXTRACT16(PSHR32(MULT16_16(PDIV32_16(SHL32(EXTEND32(q),8),(Q15_ONE-q)),tmp),8)); + st->gain2[i]=DIV32_16(SHL32(EXTEND32(32767),SNR_SHIFT), ADD16(256,tmp)); +#else + st->gain2[i]=1/(1.f + (q/(1.f-q))*(1+st->prior[i])*exp(-theta)); +#endif + } + /* Convert the EM gains and speech prob to linear frequency */ + filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2); + filterbank_compute_psd16(st->bank,st->gain+N, st->gain); + + /* Use 1 for linear gain resolution (best) or 0 for Bark gain resolution (faster) */ + if (1) + { + filterbank_compute_psd16(st->bank,st->gain_floor+N, st->gain_floor); + + /* Compute gain according to the Ephraim-Malah algorithm -- linear frequency */ + for (i=0;i<N;i++) + { + spx_word32_t MM; + spx_word32_t theta; + spx_word16_t prior_ratio; + spx_word16_t tmp; + spx_word16_t p; + spx_word16_t g; + + /* Wiener filter gain */ + prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT))); + theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT)); + + /* Optimal estimator for loudness domain */ + MM = hypergeom_gain(theta); + /* EM gain with bound */ + g = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM))); + /* Interpolated speech probability of presence */ + p = st->gain2[i]; + + /* Constrain the gain to be close to the Bark scale gain */ + if (MULT16_16_Q15(QCONST16(.333f,15),g) > st->gain[i]) + g = MULT16_16(3,st->gain[i]); + st->gain[i] = g; + + /* Save old power spectrum */ + st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]); + + /* Apply gain floor */ + if (st->gain[i] < st->gain_floor[i]) + st->gain[i] = st->gain_floor[i]; + + /* Exponential decay model for reverberation (unused) */ + /*st->reverb_estimate[i] = st->reverb_decay*st->reverb_estimate[i] + st->reverb_decay*st->reverb_level*st->gain[i]*st->gain[i]*st->ps[i];*/ + + /* Take into account speech probability of presence (loudness domain MMSE estimator) */ + /* gain2 = [p*sqrt(gain)+(1-p)*sqrt(gain _floor) ]^2 */ + tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15))); + st->gain2[i]=SQR16_Q15(tmp); + + /* Use this if you want a log-domain MMSE estimator instead */ + /*st->gain2[i] = pow(st->gain[i], p) * pow(st->gain_floor[i],1.f-p);*/ + } + } else { + for (i=N;i<N+M;i++) + { + spx_word16_t tmp; + spx_word16_t p = st->gain2[i]; + st->gain[i] = MAX16(st->gain[i], st->gain_floor[i]); + tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15))); + st->gain2[i]=SQR16_Q15(tmp); + } + filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2); + } + + /* If noise suppression is off, don't apply the gain (but then why call this in the first place!) */ + if (!st->denoise_enabled) + { + for (i=0;i<N+M;i++) + st->gain2[i]=Q15_ONE; + } + + /* Apply computed gain */ + for (i=1;i<N;i++) + { + st->ft[2*i-1] = MULT16_16_P15(st->gain2[i],st->ft[2*i-1]); + st->ft[2*i] = MULT16_16_P15(st->gain2[i],st->ft[2*i]); + } + st->ft[0] = MULT16_16_P15(st->gain2[0],st->ft[0]); + st->ft[2*N-1] = MULT16_16_P15(st->gain2[N-1],st->ft[2*N-1]); + + /*FIXME: This *will* not work for fixed-point */ +#ifndef FIXED_POINT + if (st->agc_enabled) + speex_compute_agc(st, Pframe, st->ft); +#endif + + /* Inverse FFT with 1/N scaling */ + spx_ifft(st->fft_lookup, st->ft, st->frame); + /* Scale back to original (lower) amplitude */ + for (i=0;i<2*N;i++) + st->frame[i] = PSHR16(st->frame[i], st->frame_shift); + + /*FIXME: This *will* not work for fixed-point */ +#ifndef FIXED_POINT + if (st->agc_enabled) + { + float max_sample=0; + for (i=0;i<2*N;i++) + if (fabs(st->frame[i])>max_sample) + max_sample = fabs(st->frame[i]); + if (max_sample>28000.f) + { + float damp = 28000.f/max_sample; + for (i=0;i<2*N;i++) + st->frame[i] *= damp; + } + } +#endif + + /* Synthesis window (for WOLA) */ + for (i=0;i<2*N;i++) + st->frame[i] = MULT16_16_Q15(st->frame[i], st->window[i]); + + /* Perform overlap and add */ + for (i=0;i<N3;i++) + x[i] = st->outbuf[i] + st->frame[i]; + for (i=0;i<N4;i++) + x[N3+i] = st->frame[N3+i]; + + /* Update outbuf */ + for (i=0;i<N3;i++) + st->outbuf[i] = st->frame[st->frame_size+i]; + + /* FIXME: This VAD is a kludge */ + st->speech_prob = Pframe; + if (st->vad_enabled) + { + if (st->speech_prob > st->speech_prob_start || (st->was_speech && st->speech_prob > st->speech_prob_continue)) + { + st->was_speech=1; + return 1; + } else + { + st->was_speech=0; + return 0; + } + } else { + return 1; + } +} + +EXPORT void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x) +{ + int i; + int N = st->ps_size; + int N3 = 2*N - st->frame_size; + int M; + spx_word32_t *ps=st->ps; + + M = st->nbands; + st->min_count++; + + preprocess_analysis(st, x); + + update_noise_prob(st); + + for (i=1;i<N-1;i++) + { + if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i],NOISE_SHIFT)) + { + st->noise[i] = MULT16_32_Q15(QCONST16(.95f,15),st->noise[i]) + MULT16_32_Q15(QCONST16(.05f,15),SHL32(st->ps[i],NOISE_SHIFT)); + } + } + + for (i=0;i<N3;i++) + st->outbuf[i] = MULT16_16_Q15(x[st->frame_size-N3+i],st->window[st->frame_size+i]); + + /* Save old power spectrum */ + for (i=0;i<N+M;i++) + st->old_ps[i] = ps[i]; + + for (i=0;i<N;i++) + st->reverb_estimate[i] = MULT16_32_Q15(st->reverb_decay, st->reverb_estimate[i]); +} + + +EXPORT int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) +{ + int i; + SpeexPreprocessState *st; + st=(SpeexPreprocessState*)state; + switch(request) + { + case SPEEX_PREPROCESS_SET_DENOISE: + st->denoise_enabled = (*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_DENOISE: + (*(spx_int32_t*)ptr) = st->denoise_enabled; + break; +#ifndef FIXED_POINT + case SPEEX_PREPROCESS_SET_AGC: + st->agc_enabled = (*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_AGC: + (*(spx_int32_t*)ptr) = st->agc_enabled; + break; +#ifndef DISABLE_FLOAT_API + case SPEEX_PREPROCESS_SET_AGC_LEVEL: + st->agc_level = (*(float*)ptr); + if (st->agc_level<1) + st->agc_level=1; + if (st->agc_level>32768) + st->agc_level=32768; + break; + case SPEEX_PREPROCESS_GET_AGC_LEVEL: + (*(float*)ptr) = st->agc_level; + break; +#endif /* #ifndef DISABLE_FLOAT_API */ + case SPEEX_PREPROCESS_SET_AGC_INCREMENT: + st->max_increase_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate); + break; + case SPEEX_PREPROCESS_GET_AGC_INCREMENT: + (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_increase_step)*st->sampling_rate/st->frame_size); + break; + case SPEEX_PREPROCESS_SET_AGC_DECREMENT: + st->max_decrease_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate); + break; + case SPEEX_PREPROCESS_GET_AGC_DECREMENT: + (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_decrease_step)*st->sampling_rate/st->frame_size); + break; + case SPEEX_PREPROCESS_SET_AGC_MAX_GAIN: + st->max_gain = exp(0.11513f * (*(spx_int32_t*)ptr)); + break; + case SPEEX_PREPROCESS_GET_AGC_MAX_GAIN: + (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->max_gain)); + break; +#endif + case SPEEX_PREPROCESS_SET_VAD: + speex_warning("The VAD has been replaced by a hack pending a complete rewrite"); + st->vad_enabled = (*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_VAD: + (*(spx_int32_t*)ptr) = st->vad_enabled; + break; + + case SPEEX_PREPROCESS_SET_DEREVERB: + st->dereverb_enabled = (*(spx_int32_t*)ptr); + for (i=0;i<st->ps_size;i++) + st->reverb_estimate[i]=0; + break; + case SPEEX_PREPROCESS_GET_DEREVERB: + (*(spx_int32_t*)ptr) = st->dereverb_enabled; + break; + + case SPEEX_PREPROCESS_SET_DEREVERB_LEVEL: + /* FIXME: Re-enable when de-reverberation is actually enabled again */ + /*st->reverb_level = (*(float*)ptr);*/ + break; + case SPEEX_PREPROCESS_GET_DEREVERB_LEVEL: + /* FIXME: Re-enable when de-reverberation is actually enabled again */ + /*(*(float*)ptr) = st->reverb_level;*/ + break; + + case SPEEX_PREPROCESS_SET_DEREVERB_DECAY: + /* FIXME: Re-enable when de-reverberation is actually enabled again */ + /*st->reverb_decay = (*(float*)ptr);*/ + break; + case SPEEX_PREPROCESS_GET_DEREVERB_DECAY: + /* FIXME: Re-enable when de-reverberation is actually enabled again */ + /*(*(float*)ptr) = st->reverb_decay;*/ + break; + + case SPEEX_PREPROCESS_SET_PROB_START: + *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr)); + st->speech_prob_start = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100); + break; + case SPEEX_PREPROCESS_GET_PROB_START: + (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_start, 100); + break; + + case SPEEX_PREPROCESS_SET_PROB_CONTINUE: + *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr)); + st->speech_prob_continue = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100); + break; + case SPEEX_PREPROCESS_GET_PROB_CONTINUE: + (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_continue, 100); + break; + + case SPEEX_PREPROCESS_SET_NOISE_SUPPRESS: + st->noise_suppress = -ABS(*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_NOISE_SUPPRESS: + (*(spx_int32_t*)ptr) = st->noise_suppress; + break; + case SPEEX_PREPROCESS_SET_ECHO_SUPPRESS: + st->echo_suppress = -ABS(*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_ECHO_SUPPRESS: + (*(spx_int32_t*)ptr) = st->echo_suppress; + break; + case SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE: + st->echo_suppress_active = -ABS(*(spx_int32_t*)ptr); + break; + case SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE: + (*(spx_int32_t*)ptr) = st->echo_suppress_active; + break; + case SPEEX_PREPROCESS_SET_ECHO_STATE: + st->echo_state = (SpeexEchoState*)ptr; + break; + case SPEEX_PREPROCESS_GET_ECHO_STATE: + (*(SpeexEchoState**)ptr) = (SpeexEchoState*)st->echo_state; + break; +#ifndef FIXED_POINT + case SPEEX_PREPROCESS_GET_AGC_LOUDNESS: + (*(spx_int32_t*)ptr) = pow(st->loudness, 1.0/LOUDNESS_EXP); + break; + case SPEEX_PREPROCESS_GET_AGC_GAIN: + (*(spx_int32_t*)ptr) = floor(.5+8.6858*log(st->agc_gain)); + break; +#endif + case SPEEX_PREPROCESS_GET_PSD_SIZE: + case SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE: + (*(spx_int32_t*)ptr) = st->ps_size; + break; + case SPEEX_PREPROCESS_GET_PSD: + for(i=0;i<st->ps_size;i++) + ((spx_int32_t *)ptr)[i] = (spx_int32_t) st->ps[i]; + break; + case SPEEX_PREPROCESS_GET_NOISE_PSD: + for(i=0;i<st->ps_size;i++) + ((spx_int32_t *)ptr)[i] = (spx_int32_t) PSHR32(st->noise[i], NOISE_SHIFT); + break; + case SPEEX_PREPROCESS_GET_PROB: + (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob, 100); + break; +#ifndef FIXED_POINT + case SPEEX_PREPROCESS_SET_AGC_TARGET: + st->agc_level = (*(spx_int32_t*)ptr); + if (st->agc_level<1) + st->agc_level=1; + if (st->agc_level>32768) + st->agc_level=32768; + break; + case SPEEX_PREPROCESS_GET_AGC_TARGET: + (*(spx_int32_t*)ptr) = st->agc_level; + break; +#endif + default: + speex_warning_int("Unknown speex_preprocess_ctl request: ", request); + return -1; + } + return 0; +} + +#ifdef FIXED_DEBUG +long long spx_mips=0; +#endif + diff --git a/src/libs/speexdsp/libspeexdsp/speex_resample.c b/src/libs/speexdsp/libspeexdsp/speex_resample.c new file mode 100644 index 00000000..71214459 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/speex_resample.c @@ -0,0 +1,1141 @@ +/* Copyright (C) 2007-2008 Jean-Marc Valin + Copyright (C) 2008 Thorvald Natvig + + File: resample.c + Arbitrary resampling code + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + The design goals of this code are: + - Very fast algorithm + - SIMD-friendly algorithm + - Low memory requirement + - Good *perceptual* quality (and not best SNR) + + Warning: This resampler is relatively new. Although I think I got rid of + all the major bugs and I don't expect the API to change anymore, there + may be something I've missed. So use with caution. + + This algorithm is based on this original resampling algorithm: + Smith, Julius O. Digital Audio Resampling Home Page + Center for Computer Research in Music and Acoustics (CCRMA), + Stanford University, 2007. + Web published at http://www-ccrma.stanford.edu/~jos/resample/. + + There is one main difference, though. This resampler uses cubic + interpolation instead of linear interpolation in the above paper. This + makes the table much smaller and makes it possible to compute that table + on a per-stream basis. In turn, being able to tweak the table for each + stream makes it possible to both reduce complexity on simple ratios + (e.g. 2/3), and get rid of the rounding operations in the inner loop. + The latter both reduces CPU time and makes the algorithm more SIMD-friendly. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef OUTSIDE_SPEEX +#include <stdlib.h> +static void *speex_alloc (int size) {return calloc(size,1);} +static void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);} +static void speex_free (void *ptr) {free(ptr);} +#include "speex_resampler.h" +#include "arch.h" +#else /* OUTSIDE_SPEEX */ + +#include "speex/speex_resampler.h" +#include "arch.h" +#include "os_support.h" +#endif /* OUTSIDE_SPEEX */ + +#include "stack_alloc.h" +#include <math.h> + +#ifndef M_PI +#define M_PI 3.14159263 +#endif + +#ifdef FIXED_POINT +#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x))) +#else +#define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x)))) +#endif + +#define IMAX(a,b) ((a) > (b) ? (a) : (b)) +#define IMIN(a,b) ((a) < (b) ? (a) : (b)) + +#ifndef NULL +#define NULL 0 +#endif + +#ifdef _USE_SSE +#include "resample_sse.h" +#endif + +/* Numer of elements to allocate on the stack */ +#ifdef VAR_ARRAYS +#define FIXED_STACK_ALLOC 8192 +#else +#define FIXED_STACK_ALLOC 1024 +#endif + +typedef int (*resampler_basic_func)(SpeexResamplerState *, spx_uint32_t , const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *); + +struct SpeexResamplerState_ { + spx_uint32_t in_rate; + spx_uint32_t out_rate; + spx_uint32_t num_rate; + spx_uint32_t den_rate; + + int quality; + spx_uint32_t nb_channels; + spx_uint32_t filt_len; + spx_uint32_t mem_alloc_size; + spx_uint32_t buffer_size; + int int_advance; + int frac_advance; + float cutoff; + spx_uint32_t oversample; + int initialised; + int started; + + /* These are per-channel */ + spx_int32_t *last_sample; + spx_uint32_t *samp_frac_num; + spx_uint32_t *magic_samples; + + spx_word16_t *mem; + spx_word16_t *sinc_table; + spx_uint32_t sinc_table_length; + resampler_basic_func resampler_ptr; + + int in_stride; + int out_stride; +} ; + +static double kaiser12_table[68] = { + 0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076, + 0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014, + 0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601, + 0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014, + 0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490, + 0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546, + 0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178, + 0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947, + 0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058, + 0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438, + 0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734, + 0.00001000, 0.00000000}; +/* +static double kaiser12_table[36] = { + 0.99440475, 1.00000000, 0.99440475, 0.97779076, 0.95066529, 0.91384741, + 0.86843014, 0.81573067, 0.75723148, 0.69451601, 0.62920216, 0.56287762, + 0.49704014, 0.43304576, 0.37206735, 0.31506490, 0.26276832, 0.21567274, + 0.17404546, 0.13794294, 0.10723616, 0.08164178, 0.06075685, 0.04409466, + 0.03111947, 0.02127838, 0.01402878, 0.00886058, 0.00531256, 0.00298291, + 0.00153438, 0.00069463, 0.00025272, 0.0000527734, 0.00000500, 0.00000000}; +*/ +static double kaiser10_table[36] = { + 0.99537781, 1.00000000, 0.99537781, 0.98162644, 0.95908712, 0.92831446, + 0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347, + 0.56155915, 0.50119680, 0.44221549, 0.38553619, 0.33194107, 0.28205962, + 0.23636152, 0.19515633, 0.15859932, 0.12670280, 0.09935205, 0.07632451, + 0.05731132, 0.04193980, 0.02979584, 0.02044510, 0.01345224, 0.00839739, + 0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.00000000, 0.00000000}; + +static double kaiser8_table[36] = { + 0.99635258, 1.00000000, 0.99635258, 0.98548012, 0.96759014, 0.94302200, + 0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126, + 0.63451750, 0.58014482, 0.52566725, 0.47185369, 0.41941150, 0.36897272, + 0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758, + 0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490, + 0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000}; + +static double kaiser6_table[36] = { + 0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003, + 0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565, + 0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561, + 0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058, + 0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.08693120, 0.06722600, + 0.05031820, 0.03607231, 0.02432151, 0.01487334, 0.00752000, 0.00000000}; + +struct FuncDef { + double *table; + int oversample; +}; + +static struct FuncDef _KAISER12 = {kaiser12_table, 64}; +#define KAISER12 (&_KAISER12) +/*static struct FuncDef _KAISER12 = {kaiser12_table, 32}; +#define KAISER12 (&_KAISER12)*/ +static struct FuncDef _KAISER10 = {kaiser10_table, 32}; +#define KAISER10 (&_KAISER10) +static struct FuncDef _KAISER8 = {kaiser8_table, 32}; +#define KAISER8 (&_KAISER8) +static struct FuncDef _KAISER6 = {kaiser6_table, 32}; +#define KAISER6 (&_KAISER6) + +struct QualityMapping { + int base_length; + int oversample; + float downsample_bandwidth; + float upsample_bandwidth; + struct FuncDef *window_func; +}; + + +/* This table maps conversion quality to internal parameters. There are two + reasons that explain why the up-sampling bandwidth is larger than the + down-sampling bandwidth: + 1) When up-sampling, we can assume that the spectrum is already attenuated + close to the Nyquist rate (from an A/D or a previous resampling filter) + 2) Any aliasing that occurs very close to the Nyquist rate will be masked + by the sinusoids/noise just below the Nyquist rate (guaranteed only for + up-sampling). +*/ +static const struct QualityMapping quality_map[11] = { + { 8, 4, 0.830f, 0.860f, KAISER6 }, /* Q0 */ + { 16, 4, 0.850f, 0.880f, KAISER6 }, /* Q1 */ + { 32, 4, 0.882f, 0.910f, KAISER6 }, /* Q2 */ /* 82.3% cutoff ( ~60 dB stop) 6 */ + { 48, 8, 0.895f, 0.917f, KAISER8 }, /* Q3 */ /* 84.9% cutoff ( ~80 dB stop) 8 */ + { 64, 8, 0.921f, 0.940f, KAISER8 }, /* Q4 */ /* 88.7% cutoff ( ~80 dB stop) 8 */ + { 80, 16, 0.922f, 0.940f, KAISER10}, /* Q5 */ /* 89.1% cutoff (~100 dB stop) 10 */ + { 96, 16, 0.940f, 0.945f, KAISER10}, /* Q6 */ /* 91.5% cutoff (~100 dB stop) 10 */ + {128, 16, 0.950f, 0.950f, KAISER10}, /* Q7 */ /* 93.1% cutoff (~100 dB stop) 10 */ + {160, 16, 0.960f, 0.960f, KAISER10}, /* Q8 */ /* 94.5% cutoff (~100 dB stop) 10 */ + {192, 32, 0.968f, 0.968f, KAISER12}, /* Q9 */ /* 95.5% cutoff (~100 dB stop) 10 */ + {256, 32, 0.975f, 0.975f, KAISER12}, /* Q10 */ /* 96.6% cutoff (~100 dB stop) 10 */ +}; +/*8,24,40,56,80,104,128,160,200,256,320*/ +static double compute_func(float x, struct FuncDef *func) +{ + float y, frac; + double interp[4]; + int ind; + y = x*func->oversample; + ind = (int)floor(y); + frac = (y-ind); + /* CSE with handle the repeated powers */ + interp[3] = -0.1666666667*frac + 0.1666666667*(frac*frac*frac); + interp[2] = frac + 0.5*(frac*frac) - 0.5*(frac*frac*frac); + /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ + interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac); + /* Just to make sure we don't have rounding problems */ + interp[1] = 1.f-interp[3]-interp[2]-interp[0]; + + /*sum = frac*accum[1] + (1-frac)*accum[2];*/ + return interp[0]*func->table[ind] + interp[1]*func->table[ind+1] + interp[2]*func->table[ind+2] + interp[3]*func->table[ind+3]; +} + +#if 0 +#include <stdio.h> +int main(int argc, char **argv) +{ + int i; + for (i=0;i<256;i++) + { + printf ("%f\n", compute_func(i/256., KAISER12)); + } + return 0; +} +#endif + +#ifdef FIXED_POINT +/* The slow way of computing a sinc for the table. Should improve that some day */ +static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func) +{ + /*fprintf (stderr, "%f ", x);*/ + float xx = x * cutoff; + if (fabs(x)<1e-6f) + return WORD2INT(32768.*cutoff); + else if (fabs(x) > .5f*N) + return 0; + /*FIXME: Can it really be any slower than this? */ + return WORD2INT(32768.*cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func)); +} +#else +/* The slow way of computing a sinc for the table. Should improve that some day */ +static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func) +{ + /*fprintf (stderr, "%f ", x);*/ + float xx = x * cutoff; + if (fabs(x)<1e-6) + return cutoff; + else if (fabs(x) > .5*N) + return 0; + /*FIXME: Can it really be any slower than this? */ + return cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func); +} +#endif + +#ifdef FIXED_POINT +static void cubic_coef(spx_word16_t x, spx_word16_t interp[4]) +{ + /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation + but I know it's MMSE-optimal on a sinc */ + spx_word16_t x2, x3; + x2 = MULT16_16_P15(x, x); + x3 = MULT16_16_P15(x, x2); + interp[0] = PSHR32(MULT16_16(QCONST16(-0.16667f, 15),x) + MULT16_16(QCONST16(0.16667f, 15),x3),15); + interp[1] = EXTRACT16(EXTEND32(x) + SHR32(SUB32(EXTEND32(x2),EXTEND32(x3)),1)); + interp[3] = PSHR32(MULT16_16(QCONST16(-0.33333f, 15),x) + MULT16_16(QCONST16(.5f,15),x2) - MULT16_16(QCONST16(0.16667f, 15),x3),15); + /* Just to make sure we don't have rounding problems */ + interp[2] = Q15_ONE-interp[0]-interp[1]-interp[3]; + if (interp[2]<32767) + interp[2]+=1; +} +#else +static void cubic_coef(spx_word16_t frac, spx_word16_t interp[4]) +{ + /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation + but I know it's MMSE-optimal on a sinc */ + interp[0] = -0.16667f*frac + 0.16667f*frac*frac*frac; + interp[1] = frac + 0.5f*frac*frac - 0.5f*frac*frac*frac; + /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ + interp[3] = -0.33333f*frac + 0.5f*frac*frac - 0.16667f*frac*frac*frac; + /* Just to make sure we don't have rounding problems */ + interp[2] = 1.-interp[0]-interp[1]-interp[3]; +} +#endif + +static int resampler_basic_direct_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const spx_word16_t *sinc_table = st->sinc_table; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + spx_word32_t sum; + int j; + + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + const spx_word16_t *sinc = & sinc_table[samp_frac_num*N]; + const spx_word16_t *iptr = & in[last_sample]; + +#ifndef OVERRIDE_INNER_PRODUCT_SINGLE + sum = 0; + for(j=0;j<N;j++) sum += MULT16_16(sinc[j], iptr[j]); + +/* This code is slower on most DSPs which have only 2 accumulators. + Plus this this forces truncation to 32 bits and you lose the HW guard bits. + I think we can trust the compiler and let it vectorize and/or unroll itself. + spx_word32_t accum[4] = {0,0,0,0}; + for(j=0;j<N;j+=4) { + accum[0] += MULT16_16(sinc[j], iptr[j]); + accum[1] += MULT16_16(sinc[j+1], iptr[j+1]); + accum[2] += MULT16_16(sinc[j+2], iptr[j+2]); + accum[3] += MULT16_16(sinc[j+3], iptr[j+3]); + } + sum = accum[0] + accum[1] + accum[2] + accum[3]; +*/ +#else + sum = inner_product_single(sinc, iptr, N); +#endif + + out[out_stride * out_sample++] = SATURATE32(PSHR32(sum, 15), 32767); + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) + { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} + +#ifdef FIXED_POINT +#else +/* This is the same as the previous function, except with a double-precision accumulator */ +static int resampler_basic_direct_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const spx_word16_t *sinc_table = st->sinc_table; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + double sum; + int j; + + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + const spx_word16_t *sinc = & sinc_table[samp_frac_num*N]; + const spx_word16_t *iptr = & in[last_sample]; + +#ifndef OVERRIDE_INNER_PRODUCT_DOUBLE + double accum[4] = {0,0,0,0}; + + for(j=0;j<N;j+=4) { + accum[0] += sinc[j]*iptr[j]; + accum[1] += sinc[j+1]*iptr[j+1]; + accum[2] += sinc[j+2]*iptr[j+2]; + accum[3] += sinc[j+3]*iptr[j+3]; + } + sum = accum[0] + accum[1] + accum[2] + accum[3]; +#else + sum = inner_product_double(sinc, iptr, N); +#endif + + out[out_stride * out_sample++] = PSHR32(sum, 15); + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) + { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} +#endif + +static int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + int j; + spx_word32_t sum; + + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + const spx_word16_t *iptr = & in[last_sample]; + + const int offset = samp_frac_num*st->oversample/st->den_rate; +#ifdef FIXED_POINT + const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate); +#else + const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate; +#endif + spx_word16_t interp[4]; + + +#ifndef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE + spx_word32_t accum[4] = {0,0,0,0}; + + for(j=0;j<N;j++) { + const spx_word16_t curr_in=iptr[j]; + accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]); + accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); + accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); + accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); + } + + cubic_coef(frac, interp); + sum = MULT16_32_Q15(interp[0],SHR32(accum[0], 1)) + MULT16_32_Q15(interp[1],SHR32(accum[1], 1)) + MULT16_32_Q15(interp[2],SHR32(accum[2], 1)) + MULT16_32_Q15(interp[3],SHR32(accum[3], 1)); +#else + cubic_coef(frac, interp); + sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); +#endif + + out[out_stride * out_sample++] = SATURATE32(PSHR32(sum, 14), 32767); + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) + { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} + +#ifdef FIXED_POINT +#else +/* This is the same as the previous function, except with a double-precision accumulator */ +static int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + const int N = st->filt_len; + int out_sample = 0; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + const int out_stride = st->out_stride; + const int int_advance = st->int_advance; + const int frac_advance = st->frac_advance; + const spx_uint32_t den_rate = st->den_rate; + int j; + spx_word32_t sum; + + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + const spx_word16_t *iptr = & in[last_sample]; + + const int offset = samp_frac_num*st->oversample/st->den_rate; +#ifdef FIXED_POINT + const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate); +#else + const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate; +#endif + spx_word16_t interp[4]; + + +#ifndef OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE + double accum[4] = {0,0,0,0}; + + for(j=0;j<N;j++) { + const double curr_in=iptr[j]; + accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]); + accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); + accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); + accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); + } + + cubic_coef(frac, interp); + sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]); +#else + cubic_coef(frac, interp); + sum = interpolate_product_double(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); +#endif + + out[out_stride * out_sample++] = PSHR32(sum,15); + last_sample += int_advance; + samp_frac_num += frac_advance; + if (samp_frac_num >= den_rate) + { + samp_frac_num -= den_rate; + last_sample++; + } + } + + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} +#endif + +static void update_filter(SpeexResamplerState *st) +{ + spx_uint32_t old_length; + + old_length = st->filt_len; + st->oversample = quality_map[st->quality].oversample; + st->filt_len = quality_map[st->quality].base_length; + + if (st->num_rate > st->den_rate) + { + /* down-sampling */ + st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate; + /* FIXME: divide the numerator and denominator by a certain amount if they're too large */ + st->filt_len = st->filt_len*st->num_rate / st->den_rate; + /* Round up to make sure we have a multiple of 8 for SSE */ + st->filt_len = ((st->filt_len-1)&(~0x7))+8; + if (2*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (4*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (8*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (16*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (st->oversample < 1) + st->oversample = 1; + } else { + /* up-sampling */ + st->cutoff = quality_map[st->quality].upsample_bandwidth; + } + + /* Choose the resampling type that requires the least amount of memory */ + if (st->filt_len*st->den_rate <= st->filt_len*st->oversample+8) + { + spx_uint32_t i; + if (!st->sinc_table) + st->sinc_table = (spx_word16_t *)speex_alloc(st->filt_len*st->den_rate*sizeof(spx_word16_t)); + else if (st->sinc_table_length < st->filt_len*st->den_rate) + { + st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,st->filt_len*st->den_rate*sizeof(spx_word16_t)); + st->sinc_table_length = st->filt_len*st->den_rate; + } + for (i=0;i<st->den_rate;i++) + { + spx_int32_t j; + for (j=0;j<st->filt_len;j++) + { + st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-(spx_int32_t)st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func); + } + } +#ifdef FIXED_POINT + st->resampler_ptr = resampler_basic_direct_single; +#else + if (st->quality>8) + st->resampler_ptr = resampler_basic_direct_double; + else + st->resampler_ptr = resampler_basic_direct_single; +#endif + /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/ + } else { + spx_int32_t i; + if (!st->sinc_table) + st->sinc_table = (spx_word16_t *)speex_alloc((st->filt_len*st->oversample+8)*sizeof(spx_word16_t)); + else if (st->sinc_table_length < st->filt_len*st->oversample+8) + { + st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,(st->filt_len*st->oversample+8)*sizeof(spx_word16_t)); + st->sinc_table_length = st->filt_len*st->oversample+8; + } + for (i=-4;i<(spx_int32_t)(st->oversample*st->filt_len+4);i++) + st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)st->oversample - st->filt_len/2), st->filt_len, quality_map[st->quality].window_func); +#ifdef FIXED_POINT + st->resampler_ptr = resampler_basic_interpolate_single; +#else + if (st->quality>8) + st->resampler_ptr = resampler_basic_interpolate_double; + else + st->resampler_ptr = resampler_basic_interpolate_single; +#endif + /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/ + } + st->int_advance = st->num_rate/st->den_rate; + st->frac_advance = st->num_rate%st->den_rate; + + + /* Here's the place where we update the filter memory to take into account + the change in filter length. It's probably the messiest part of the code + due to handling of lots of corner cases. */ + if (!st->mem) + { + spx_uint32_t i; + st->mem_alloc_size = st->filt_len-1 + st->buffer_size; + st->mem = (spx_word16_t*)speex_alloc(st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t)); + for (i=0;i<st->nb_channels*st->mem_alloc_size;i++) + st->mem[i] = 0; + /*speex_warning("init filter");*/ + } else if (!st->started) + { + spx_uint32_t i; + st->mem_alloc_size = st->filt_len-1 + st->buffer_size; + st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t)); + for (i=0;i<st->nb_channels*st->mem_alloc_size;i++) + st->mem[i] = 0; + /*speex_warning("reinit filter");*/ + } else if (st->filt_len > old_length) + { + spx_int32_t i; + /* Increase the filter length */ + /*speex_warning("increase filter size");*/ + int old_alloc_size = st->mem_alloc_size; + if ((st->filt_len-1 + st->buffer_size) > st->mem_alloc_size) + { + st->mem_alloc_size = st->filt_len-1 + st->buffer_size; + st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t)); + } + for (i=st->nb_channels-1;i>=0;i--) + { + spx_int32_t j; + spx_uint32_t olen = old_length; + /*if (st->magic_samples[i])*/ + { + /* Try and remove the magic samples as if nothing had happened */ + + /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */ + olen = old_length + 2*st->magic_samples[i]; + for (j=old_length-2+st->magic_samples[i];j>=0;j--) + st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j]; + for (j=0;j<st->magic_samples[i];j++) + st->mem[i*st->mem_alloc_size+j] = 0; + st->magic_samples[i] = 0; + } + if (st->filt_len > olen) + { + /* If the new filter length is still bigger than the "augmented" length */ + /* Copy data going backward */ + for (j=0;j<olen-1;j++) + st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)]; + /* Then put zeros for lack of anything better */ + for (;j<st->filt_len-1;j++) + st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0; + /* Adjust last_sample */ + st->last_sample[i] += (st->filt_len - olen)/2; + } else { + /* Put back some of the magic! */ + st->magic_samples[i] = (olen - st->filt_len)/2; + for (j=0;j<st->filt_len-1+st->magic_samples[i];j++) + st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; + } + } + } else if (st->filt_len < old_length) + { + spx_uint32_t i; + /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic" + samples so they can be used directly as input the next time(s) */ + for (i=0;i<st->nb_channels;i++) + { + spx_uint32_t j; + spx_uint32_t old_magic = st->magic_samples[i]; + st->magic_samples[i] = (old_length - st->filt_len)/2; + /* We must copy some of the memory that's no longer used */ + /* Copy data going backward */ + for (j=0;j<st->filt_len-1+st->magic_samples[i]+old_magic;j++) + st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; + st->magic_samples[i] += old_magic; + } + } + +} + +EXPORT SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) +{ + return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err); +} + +EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) +{ + spx_uint32_t i; + SpeexResamplerState *st; + if (quality > 10 || quality < 0) + { + if (err) + *err = RESAMPLER_ERR_INVALID_ARG; + return NULL; + } + st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState)); + st->initialised = 0; + st->started = 0; + st->in_rate = 0; + st->out_rate = 0; + st->num_rate = 0; + st->den_rate = 0; + st->quality = -1; + st->sinc_table_length = 0; + st->mem_alloc_size = 0; + st->filt_len = 0; + st->mem = 0; + st->resampler_ptr = 0; + + st->cutoff = 1.f; + st->nb_channels = nb_channels; + st->in_stride = 1; + st->out_stride = 1; + +#ifdef FIXED_POINT + st->buffer_size = 160; +#else + st->buffer_size = 160; +#endif + + /* Per channel data */ + st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(spx_int32_t)); + st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(spx_uint32_t)); + st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(spx_uint32_t)); + for (i=0;i<nb_channels;i++) + { + st->last_sample[i] = 0; + st->magic_samples[i] = 0; + st->samp_frac_num[i] = 0; + } + + speex_resampler_set_quality(st, quality); + speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate); + + + update_filter(st); + + st->initialised = 1; + if (err) + *err = RESAMPLER_ERR_SUCCESS; + + return st; +} + +EXPORT void speex_resampler_destroy(SpeexResamplerState *st) +{ + speex_free(st->mem); + speex_free(st->sinc_table); + speex_free(st->last_sample); + speex_free(st->magic_samples); + speex_free(st->samp_frac_num); + speex_free(st); +} + +static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t channel_index, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + int j=0; + const int N = st->filt_len; + int out_sample = 0; + spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size; + spx_uint32_t ilen; + + st->started = 1; + + /* Call the right resampler through the function ptr */ + out_sample = st->resampler_ptr(st, channel_index, mem, in_len, out, out_len); + + if (st->last_sample[channel_index] < (spx_int32_t)*in_len) + *in_len = st->last_sample[channel_index]; + *out_len = out_sample; + st->last_sample[channel_index] -= *in_len; + + ilen = *in_len; + + for(j=0;j<N-1;++j) + mem[j] = mem[j+ilen]; + + return RESAMPLER_ERR_SUCCESS; +} + +static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_index, spx_word16_t **out, spx_uint32_t out_len) { + spx_uint32_t tmp_in_len = st->magic_samples[channel_index]; + spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size; + const int N = st->filt_len; + + speex_resampler_process_native(st, channel_index, &tmp_in_len, *out, &out_len); + + st->magic_samples[channel_index] -= tmp_in_len; + + /* If we couldn't process all "magic" input samples, save the rest for next time */ + if (st->magic_samples[channel_index]) + { + spx_uint32_t i; + for (i=0;i<st->magic_samples[channel_index];i++) + mem[N-1+i]=mem[N-1+i+tmp_in_len]; + } + *out += out_len*st->out_stride; + return out_len; +} + +#ifdef FIXED_POINT +EXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len) +#else +EXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +#endif +{ + int j; + spx_uint32_t ilen = *in_len; + spx_uint32_t olen = *out_len; + spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size; + const int filt_offs = st->filt_len - 1; + const spx_uint32_t xlen = st->mem_alloc_size - filt_offs; + const int istride = st->in_stride; + + if (st->magic_samples[channel_index]) + olen -= speex_resampler_magic(st, channel_index, &out, olen); + if (! st->magic_samples[channel_index]) { + while (ilen && olen) { + spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen; + spx_uint32_t ochunk = olen; + + if (in) { + for(j=0;j<ichunk;++j) + x[j+filt_offs]=in[j*istride]; + } else { + for(j=0;j<ichunk;++j) + x[j+filt_offs]=0; + } + speex_resampler_process_native(st, channel_index, &ichunk, out, &ochunk); + ilen -= ichunk; + olen -= ochunk; + out += ochunk * st->out_stride; + if (in) + in += ichunk * istride; + } + } + *in_len -= ilen; + *out_len -= olen; + return RESAMPLER_ERR_SUCCESS; +} + +#ifdef FIXED_POINT +EXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +#else +EXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len) +#endif +{ + int j; + const int istride_save = st->in_stride; + const int ostride_save = st->out_stride; + spx_uint32_t ilen = *in_len; + spx_uint32_t olen = *out_len; + spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size; + const spx_uint32_t xlen = st->mem_alloc_size - (st->filt_len - 1); +#ifdef VAR_ARRAYS + const unsigned int ylen = (olen < FIXED_STACK_ALLOC) ? olen : FIXED_STACK_ALLOC; + VARDECL(spx_word16_t *ystack); + ALLOC(ystack, ylen, spx_word16_t); +#else + const unsigned int ylen = FIXED_STACK_ALLOC; + spx_word16_t ystack[FIXED_STACK_ALLOC]; +#endif + + st->out_stride = 1; + + while (ilen && olen) { + spx_word16_t *y = ystack; + spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen; + spx_uint32_t ochunk = (olen > ylen) ? ylen : olen; + spx_uint32_t omagic = 0; + + if (st->magic_samples[channel_index]) { + omagic = speex_resampler_magic(st, channel_index, &y, ochunk); + ochunk -= omagic; + olen -= omagic; + } + if (! st->magic_samples[channel_index]) { + if (in) { + for(j=0;j<ichunk;++j) +#ifdef FIXED_POINT + x[j+st->filt_len-1]=WORD2INT(in[j*istride_save]); +#else + x[j+st->filt_len-1]=in[j*istride_save]; +#endif + } else { + for(j=0;j<ichunk;++j) + x[j+st->filt_len-1]=0; + } + + speex_resampler_process_native(st, channel_index, &ichunk, y, &ochunk); + } else { + ichunk = 0; + ochunk = 0; + } + + for (j=0;j<ochunk+omagic;++j) +#ifdef FIXED_POINT + out[j*ostride_save] = ystack[j]; +#else + out[j*ostride_save] = WORD2INT(ystack[j]); +#endif + + ilen -= ichunk; + olen -= ochunk; + out += (ochunk+omagic) * ostride_save; + if (in) + in += ichunk * istride_save; + } + st->out_stride = ostride_save; + *in_len -= ilen; + *out_len -= olen; + + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +{ + spx_uint32_t i; + int istride_save, ostride_save; + spx_uint32_t bak_out_len = *out_len; + spx_uint32_t bak_in_len = *in_len; + istride_save = st->in_stride; + ostride_save = st->out_stride; + st->in_stride = st->out_stride = st->nb_channels; + for (i=0;i<st->nb_channels;i++) + { + *out_len = bak_out_len; + *in_len = bak_in_len; + if (in != NULL) + speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len); + else + speex_resampler_process_float(st, i, NULL, in_len, out+i, out_len); + } + st->in_stride = istride_save; + st->out_stride = ostride_save; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_process_interleaved_int(SpeexResamplerState *st, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len) +{ + spx_uint32_t i; + int istride_save, ostride_save; + spx_uint32_t bak_out_len = *out_len; + spx_uint32_t bak_in_len = *in_len; + istride_save = st->in_stride; + ostride_save = st->out_stride; + st->in_stride = st->out_stride = st->nb_channels; + for (i=0;i<st->nb_channels;i++) + { + *out_len = bak_out_len; + *in_len = bak_in_len; + if (in != NULL) + speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len); + else + speex_resampler_process_int(st, i, NULL, in_len, out+i, out_len); + } + st->in_stride = istride_save; + st->out_stride = ostride_save; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate) +{ + return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate); +} + +EXPORT void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate) +{ + *in_rate = st->in_rate; + *out_rate = st->out_rate; +} + +EXPORT int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate) +{ + spx_uint32_t fact; + spx_uint32_t old_den; + spx_uint32_t i; + if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den) + return RESAMPLER_ERR_SUCCESS; + + old_den = st->den_rate; + st->in_rate = in_rate; + st->out_rate = out_rate; + st->num_rate = ratio_num; + st->den_rate = ratio_den; + /* FIXME: This is terribly inefficient, but who cares (at least for now)? */ + for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++) + { + while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0)) + { + st->num_rate /= fact; + st->den_rate /= fact; + } + } + + if (old_den > 0) + { + for (i=0;i<st->nb_channels;i++) + { + st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den; + /* Safety net */ + if (st->samp_frac_num[i] >= st->den_rate) + st->samp_frac_num[i] = st->den_rate-1; + } + } + + if (st->initialised) + update_filter(st); + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den) +{ + *ratio_num = st->num_rate; + *ratio_den = st->den_rate; +} + +EXPORT int speex_resampler_set_quality(SpeexResamplerState *st, int quality) +{ + if (quality > 10 || quality < 0) + return RESAMPLER_ERR_INVALID_ARG; + if (st->quality == quality) + return RESAMPLER_ERR_SUCCESS; + st->quality = quality; + if (st->initialised) + update_filter(st); + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT void speex_resampler_get_quality(SpeexResamplerState *st, int *quality) +{ + *quality = st->quality; +} + +EXPORT void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride) +{ + st->in_stride = stride; +} + +EXPORT void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride) +{ + *stride = st->in_stride; +} + +EXPORT void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride) +{ + st->out_stride = stride; +} + +EXPORT void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride) +{ + *stride = st->out_stride; +} + +EXPORT int speex_resampler_get_input_latency(SpeexResamplerState *st) +{ + return st->filt_len / 2; +} + +EXPORT int speex_resampler_get_output_latency(SpeexResamplerState *st) +{ + return ((st->filt_len / 2) * st->den_rate + (st->num_rate >> 1)) / st->num_rate; +} + +EXPORT int speex_resampler_skip_zeros(SpeexResamplerState *st) +{ + spx_uint32_t i; + for (i=0;i<st->nb_channels;i++) + st->last_sample[i] = st->filt_len/2; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT int speex_resampler_reset_mem(SpeexResamplerState *st) +{ + spx_uint32_t i; + for (i=0;i<st->nb_channels*(st->filt_len-1);i++) + st->mem[i] = 0; + return RESAMPLER_ERR_SUCCESS; +} + +EXPORT const char *speex_resampler_strerror(int err) +{ + switch (err) + { + case RESAMPLER_ERR_SUCCESS: + return "Success."; + case RESAMPLER_ERR_ALLOC_FAILED: + return "Memory allocation failed."; + case RESAMPLER_ERR_BAD_STATE: + return "Bad resampler state."; + case RESAMPLER_ERR_INVALID_ARG: + return "Invalid argument."; + case RESAMPLER_ERR_PTR_OVERLAP: + return "Input and output buffers overlap."; + default: + return "Unknown error. Bad error code or strange version mismatch."; + } +} diff --git a/src/libs/speexdsp/libspeexdsp/stack_alloc.h b/src/libs/speexdsp/libspeexdsp/stack_alloc.h new file mode 100644 index 00000000..5264e666 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/stack_alloc.h @@ -0,0 +1,115 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file stack_alloc.h + @brief Temporary memory allocation on stack +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef STACK_ALLOC_H +#define STACK_ALLOC_H + +#ifdef USE_ALLOCA +# ifdef WIN32 +# include <malloc.h> +# else +# ifdef HAVE_ALLOCA_H +# include <alloca.h> +# else +# include <stdlib.h> +# endif +# endif +#endif + +/** + * @def ALIGN(stack, size) + * + * Aligns the stack to a 'size' boundary + * + * @param stack Stack + * @param size New size boundary + */ + +/** + * @def PUSH(stack, size, type) + * + * Allocates 'size' elements of type 'type' on the stack + * + * @param stack Stack + * @param size Number of elements + * @param type Type of element + */ + +/** + * @def VARDECL(var) + * + * Declare variable on stack + * + * @param var Variable to declare + */ + +/** + * @def ALLOC(var, size, type) + * + * Allocate 'size' elements of 'type' on stack + * + * @param var Name of variable to allocate + * @param size Number of elements + * @param type Type of element + */ + +#ifdef ENABLE_VALGRIND + +#include <valgrind/memcheck.h> + +#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) + +#define PUSH(stack, size, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(type)),VALGRIND_MAKE_WRITABLE(stack, ((size)*sizeof(type))),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type)))) + +#else + +#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) + +#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type)))) + +#endif + +#if defined(VAR_ARRAYS) +#define VARDECL(var) +#define ALLOC(var, size, type) type var[size] +#elif defined(USE_ALLOCA) +#define VARDECL(var) var +#define ALLOC(var, size, type) var = alloca(sizeof(type)*(size)) +#else +#define VARDECL(var) var +#define ALLOC(var, size, type) var = PUSH(stack, size, type) +#endif + + +#endif diff --git a/src/libs/speexdsp/libspeexdsp/testdenoise.c b/src/libs/speexdsp/libspeexdsp/testdenoise.c new file mode 100644 index 00000000..adebe941 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/testdenoise.c @@ -0,0 +1,44 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "speex/speex_preprocess.h" +#include <stdio.h> + +#define NN 160 + +int main() +{ + short in[NN]; + int i; + SpeexPreprocessState *st; + int count=0; + float f; + + st = speex_preprocess_state_init(NN, 8000); + i=1; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i); + i=0; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i); + i=8000; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i); + i=0; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i); + f=.0; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); + f=.0; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); + while (1) + { + int vad; + fread(in, sizeof(short), NN, stdin); + if (feof(stdin)) + break; + vad = speex_preprocess_run(st, in); + /*fprintf (stderr, "%d\n", vad);*/ + fwrite(in, sizeof(short), NN, stdout); + count++; + } + speex_preprocess_state_destroy(st); + return 0; +} diff --git a/src/libs/speexdsp/libspeexdsp/testecho.c b/src/libs/speexdsp/libspeexdsp/testecho.c new file mode 100644 index 00000000..1624dc2a --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/testecho.c @@ -0,0 +1,53 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "speex/speex_echo.h" +#include "speex/speex_preprocess.h" +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + + +#define NN 128 +#define TAIL 1024 + +int main(int argc, char **argv) +{ + FILE *echo_fd, *ref_fd, *e_fd; + short echo_buf[NN], ref_buf[NN], e_buf[NN]; + SpeexEchoState *st; + SpeexPreprocessState *den; + int sampleRate = 8000; + + if (argc != 4) + { + fprintf(stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n"); + exit(1); + } + echo_fd = fopen(argv[2], "rb"); + ref_fd = fopen(argv[1], "rb"); + e_fd = fopen(argv[3], "wb"); + + st = speex_echo_state_init(NN, TAIL); + den = speex_preprocess_state_init(NN, sampleRate); + speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate); + speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, st); + + while (!feof(ref_fd) && !feof(echo_fd)) + { + fread(ref_buf, sizeof(short), NN, ref_fd); + fread(echo_buf, sizeof(short), NN, echo_fd); + speex_echo_cancellation(st, ref_buf, echo_buf, e_buf); + speex_preprocess_run(den, e_buf); + fwrite(e_buf, sizeof(short), NN, e_fd); + } + speex_echo_state_destroy(st); + speex_preprocess_state_destroy(den); + fclose(e_fd); + fclose(echo_fd); + fclose(ref_fd); + return 0; +} diff --git a/src/libs/speexdsp/libspeexdsp/testjitter.c b/src/libs/speexdsp/libspeexdsp/testjitter.c new file mode 100644 index 00000000..557c5c3f --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/testjitter.c @@ -0,0 +1,75 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "speex/speex_jitter.h" +#include <stdio.h> + +union jbpdata { + unsigned int idx; + unsigned char data[4]; +}; + +void synthIn(JitterBufferPacket *in, int idx, int span) { + union jbpdata d; + d.idx = idx; + + in->data = d.data; + in->len = sizeof(d); + in->timestamp = idx * 10; + in->span = span * 10; + in->sequence = idx; + in->user_data = 0; +} + +void jitterFill(JitterBuffer *jb) { + char buffer[65536]; + JitterBufferPacket in, out; + int i; + + out.data = buffer; + + jitter_buffer_reset(jb); + + for(i=0;i<100;++i) { + synthIn(&in, i, 1); + jitter_buffer_put(jb, &in); + + out.len = 65536; + if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) { + printf("Fill test failed iteration %d\n", i); + } + if (out.timestamp != i * 10) { + printf("Fill test expected %d got %d\n", i*10, out.timestamp); + } + jitter_buffer_tick(jb); + } +} + +int main() +{ + char buffer[65536]; + JitterBufferPacket in, out; + int i; + + JitterBuffer *jb = jitter_buffer_init(10); + + out.data = buffer; + + /* Frozen sender case */ + jitterFill(jb); + for(i=0;i<100;++i) { + out.len = 65536; + jitter_buffer_get(jb, &out, 10, NULL); + jitter_buffer_tick(jb); + } + synthIn(&in, 100, 1); + jitter_buffer_put(jb, &in); + out.len = 65536; + if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) { + printf("Failed frozen sender resynchronize\n"); + } else { + printf("Frozen sender: Jitter %d\n", out.timestamp - 100*10); + } + return 0; +} diff --git a/src/libs/speexdsp/libspeexdsp/testresample.c b/src/libs/speexdsp/libspeexdsp/testresample.c new file mode 100644 index 00000000..1681e52b --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/testresample.c @@ -0,0 +1,86 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: testresample.c + Testing the resampling code + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "speex/speex_resampler.h" +#include <stdio.h> +#include <math.h> +#include <stdlib.h> + +#define NN 256 + +int main() +{ + spx_uint32_t i; + short *in; + short *out; + float *fin, *fout; + int count = 0; + SpeexResamplerState *st = speex_resampler_init(1, 8000, 12000, 10, NULL); + speex_resampler_set_rate(st, 96000, 44100); + speex_resampler_skip_zeros(st); + + in = malloc(NN*sizeof(short)); + out = malloc(2*NN*sizeof(short)); + fin = malloc(NN*sizeof(float)); + fout = malloc(2*NN*sizeof(float)); + while (1) + { + spx_uint32_t in_len; + spx_uint32_t out_len; + fread(in, sizeof(short), NN, stdin); + if (feof(stdin)) + break; + for (i=0;i<NN;i++) + fin[i]=in[i]; + in_len = NN; + out_len = 2*NN; + /*if (count==2) + speex_resampler_set_quality(st, 10);*/ + speex_resampler_process_float(st, 0, fin, &in_len, fout, &out_len); + for (i=0;i<out_len;i++) + out[i]=floor(.5+fout[i]); + /*speex_warning_int("writing", out_len);*/ + fwrite(out, sizeof(short), out_len, stdout); + count++; + } + speex_resampler_destroy(st); + free(in); + free(out); + free(fin); + free(fout); + return 0; +} + diff --git a/src/libs/speexdsp/libspeexdsp/vorbis_psy.h b/src/libs/speexdsp/libspeexdsp/vorbis_psy.h new file mode 100644 index 00000000..68710577 --- /dev/null +++ b/src/libs/speexdsp/libspeexdsp/vorbis_psy.h @@ -0,0 +1,97 @@ +/* Copyright (C) 2005 Jean-Marc Valin, CSIRO, Christopher Montgomery + File: vorbis_psy.h + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef VORBIS_PSY_H +#define VORBIS_PSY_H + +#ifdef VORBIS_PSYCHO + +#include "smallft.h" +#define P_BANDS 17 /* 62Hz to 16kHz */ +#define NOISE_COMPAND_LEVELS 40 + + +#define todB(x) ((x)>1e-13?log((x)*(x))*4.34294480f:-30) +#define fromdB(x) (exp((x)*.11512925f)) + +/* The bark scale equations are approximations, since the original + table was somewhat hand rolled. The below are chosen to have the + best possible fit to the rolled tables, thus their somewhat odd + appearance (these are more accurate and over a longer range than + the oft-quoted bark equations found in the texts I have). The + approximations are valid from 0 - 30kHz (nyquist) or so. + + all f in Hz, z in Bark */ + +#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n)) +#define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f) + +/* Frequency to octave. We arbitrarily declare 63.5 Hz to be octave + 0.0 */ + +#define toOC(n) (log(n)*1.442695f-5.965784f) +#define fromOC(o) (exp(((o)+5.965784f)*.693147f)) + + +typedef struct { + + float noisewindowlo; + float noisewindowhi; + int noisewindowlomin; + int noisewindowhimin; + int noisewindowfixed; + float noiseoff[P_BANDS]; + float noisecompand[NOISE_COMPAND_LEVELS]; + +} VorbisPsyInfo; + + + +typedef struct { + int n; + int rate; + struct drft_lookup lookup; + VorbisPsyInfo *vi; + + float *window; + float *noiseoffset; + long *bark; + +} VorbisPsy; + + +VorbisPsy *vorbis_psy_init(int rate, int size); +void vorbis_psy_destroy(VorbisPsy *psy); +void compute_curve(VorbisPsy *psy, float *audio, float *curve); +void curve_to_lpc(VorbisPsy *psy, float *curve, float *awk1, float *awk2, int ord); + +#endif +#endif diff --git a/src/libs/speexdsp/macosx/English.lproj/InfoPlist.strings b/src/libs/speexdsp/macosx/English.lproj/InfoPlist.strings new file mode 100644 index 00000000..166513d3 Binary files /dev/null and b/src/libs/speexdsp/macosx/English.lproj/InfoPlist.strings differ diff --git a/src/libs/speexdsp/macosx/Info.plist b/src/libs/speexdsp/macosx/Info.plist new file mode 100644 index 00000000..1d1c47c8 --- /dev/null +++ b/src/libs/speexdsp/macosx/Info.plist @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>Speex</string> + <key>CFBundleGetInfoString</key> + <string>Speex framework 1.1.12svn, Copyright © 2002-2006 Xiph.Org Foundation</string> + <key>CFBundleIconFile</key> + <string></string> + <key>CFBundleIdentifier</key> + <string>org.xiph.speex</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundlePackageType</key> + <string>FMWK</string> + <key>CFBundleShortVersionString</key> + <string>1.1.12svn</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1.1.12d1</string> + <key>NSHumanReadableCopyright</key> + <string>Speex framework 1.1.12svn, Copyright © 2002-2006 Xiph.Org Foundation</string> + <key>CSResourcesFileMapped</key> + <true/> +</dict> +</plist> diff --git a/src/libs/speexdsp/macosx/Speex.xcodeproj/project.pbxproj b/src/libs/speexdsp/macosx/Speex.xcodeproj/project.pbxproj new file mode 100644 index 00000000..8a04da26 --- /dev/null +++ b/src/libs/speexdsp/macosx/Speex.xcodeproj/project.pbxproj @@ -0,0 +1,538 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 37CA8DF00DD73408005C8CB6 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 37CA8DED0DD73408005C8CB6 /* buffer.c */; }; + 37CA8DF10DD73408005C8CB6 /* resample.c in Sources */ = {isa = PBXBuildFile; fileRef = 37CA8DEE0DD73408005C8CB6 /* resample.c */; }; + 37CA8DF30DD73408005C8CB6 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 37CA8DED0DD73408005C8CB6 /* buffer.c */; }; + 37CA8DF40DD73408005C8CB6 /* resample.c in Sources */ = {isa = PBXBuildFile; fileRef = 37CA8DEE0DD73408005C8CB6 /* resample.c */; }; + 37CA8DF60DD73424005C8CB6 /* resample_sse.h in Headers */ = {isa = PBXBuildFile; fileRef = 37CA8DEF0DD73408005C8CB6 /* resample_sse.h */; }; + 37CA8DF90DD7347D005C8CB6 /* speex_buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 37CA8DF70DD7347D005C8CB6 /* speex_buffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 37CA8DFA0DD7347D005C8CB6 /* speex_resampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 37CA8DF80DD7347D005C8CB6 /* speex_resampler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 37CA8E000DD7352A005C8CB6 /* os_support.h in Headers */ = {isa = PBXBuildFile; fileRef = 37CA8DFF0DD7352A005C8CB6 /* os_support.h */; }; + 73814AFF0907FB8200C478FC /* speex_echo.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF30907FB8200C478FC /* speex_echo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B000907FB8200C478FC /* speex_header.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF40907FB8200C478FC /* speex_header.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B010907FB8200C478FC /* speex_jitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF50907FB8200C478FC /* speex_jitter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B020907FB8200C478FC /* speex_preprocess.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF60907FB8200C478FC /* speex_preprocess.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B030907FB8200C478FC /* speex_stereo.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF70907FB8200C478FC /* speex_stereo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B040907FB8200C478FC /* speex_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF80907FB8200C478FC /* speex_types.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B060907FBAB00C478FC /* speex_callbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF10907FB8200C478FC /* speex_callbacks.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B750907FC9900C478FC /* jitter.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B280907FC9900C478FC /* jitter.c */; }; + 73814B8E0907FC9900C478FC /* preprocess.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B410907FC9900C478FC /* preprocess.c */; }; + 73814B930907FC9900C478FC /* smallft.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B460907FC9900C478FC /* smallft.c */; }; + 738837440B1934D0005C7A69 /* mdf.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B390907FC9900C478FC /* mdf.c */; }; + 738837540B193581005C7A69 /* _kiss_fft_guts.h in Headers */ = {isa = PBXBuildFile; fileRef = 738837460B193581005C7A69 /* _kiss_fft_guts.h */; }; + 738837550B193581005C7A69 /* fftwrap.c in Sources */ = {isa = PBXBuildFile; fileRef = 738837470B193581005C7A69 /* fftwrap.c */; }; + 738837560B193581005C7A69 /* fftwrap.h in Headers */ = {isa = PBXBuildFile; fileRef = 738837480B193581005C7A69 /* fftwrap.h */; }; + 738837570B193581005C7A69 /* filterbank.c in Sources */ = {isa = PBXBuildFile; fileRef = 738837490B193581005C7A69 /* filterbank.c */; }; + 738837580B193581005C7A69 /* filterbank.h in Headers */ = {isa = PBXBuildFile; fileRef = 7388374A0B193581005C7A69 /* filterbank.h */; }; + 738837590B193581005C7A69 /* kiss_fft.c in Sources */ = {isa = PBXBuildFile; fileRef = 7388374B0B193581005C7A69 /* kiss_fft.c */; }; + 7388375A0B193581005C7A69 /* kiss_fft.h in Headers */ = {isa = PBXBuildFile; fileRef = 7388374C0B193581005C7A69 /* kiss_fft.h */; }; + 7388375B0B193581005C7A69 /* kiss_fftr.c in Sources */ = {isa = PBXBuildFile; fileRef = 7388374D0B193581005C7A69 /* kiss_fftr.c */; }; + 7388375C0B193581005C7A69 /* kiss_fftr.h in Headers */ = {isa = PBXBuildFile; fileRef = 7388374E0B193581005C7A69 /* kiss_fftr.h */; }; + 7388375D0B193581005C7A69 /* lsp_bfin.h in Headers */ = {isa = PBXBuildFile; fileRef = 7388374F0B193581005C7A69 /* lsp_bfin.h */; }; + 7388375E0B193581005C7A69 /* pseudofloat.h in Headers */ = {isa = PBXBuildFile; fileRef = 738837500B193581005C7A69 /* pseudofloat.h */; }; + 7388375F0B193581005C7A69 /* quant_lsp_bfin.h in Headers */ = {isa = PBXBuildFile; fileRef = 738837510B193581005C7A69 /* quant_lsp_bfin.h */; }; + 738837600B193581005C7A69 /* vorbis_psy.c in Sources */ = {isa = PBXBuildFile; fileRef = 738837520B193581005C7A69 /* vorbis_psy.c */; }; + 738837610B193581005C7A69 /* vorbis_psy.h in Headers */ = {isa = PBXBuildFile; fileRef = 738837530B193581005C7A69 /* vorbis_psy.h */; }; + 738837830B193791005C7A69 /* fftwrap.c in Sources */ = {isa = PBXBuildFile; fileRef = 738837470B193581005C7A69 /* fftwrap.c */; }; + 738837840B193792005C7A69 /* filterbank.c in Sources */ = {isa = PBXBuildFile; fileRef = 738837490B193581005C7A69 /* filterbank.c */; }; + 7388378B0B1937A0005C7A69 /* jitter.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B280907FC9900C478FC /* jitter.c */; }; + 7388378C0B1937A4005C7A69 /* kiss_fft.c in Sources */ = {isa = PBXBuildFile; fileRef = 7388374B0B193581005C7A69 /* kiss_fft.c */; }; + 7388378D0B1937A9005C7A69 /* kiss_fftr.c in Sources */ = {isa = PBXBuildFile; fileRef = 7388374D0B193581005C7A69 /* kiss_fftr.c */; }; + 738837940B1937BB005C7A69 /* mdf.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B390907FC9900C478FC /* mdf.c */; }; + 738837980B1937C2005C7A69 /* preprocess.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B410907FC9900C478FC /* preprocess.c */; }; + 7388379B0B1937C9005C7A69 /* smallft.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B460907FC9900C478FC /* smallft.c */; }; + 738837A10B1937DD005C7A69 /* vorbis_psy.c in Sources */ = {isa = PBXBuildFile; fileRef = 738837520B193581005C7A69 /* vorbis_psy.c */; }; + 8D07F2C00486CC7A007CD1D0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; + 32BAE0B70371A74B00C91783 /* Speex_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Speex_Prefix.pch; sourceTree = "<group>"; }; + 37CA8DED0DD73408005C8CB6 /* buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = buffer.c; path = ../libspeex/buffer.c; sourceTree = SOURCE_ROOT; }; + 37CA8DEE0DD73408005C8CB6 /* resample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = resample.c; path = ../libspeex/resample.c; sourceTree = SOURCE_ROOT; }; + 37CA8DEF0DD73408005C8CB6 /* resample_sse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = resample_sse.h; path = ../libspeex/resample_sse.h; sourceTree = SOURCE_ROOT; }; + 37CA8DF70DD7347D005C8CB6 /* speex_buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = speex_buffer.h; sourceTree = "<group>"; }; + 37CA8DF80DD7347D005C8CB6 /* speex_resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = speex_resampler.h; sourceTree = "<group>"; }; + 37CA8DFF0DD7352A005C8CB6 /* os_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = os_support.h; path = ../libspeex/os_support.h; sourceTree = SOURCE_ROOT; }; + 73814AEF0907FB8200C478FC /* speex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex.h; sourceTree = "<group>"; }; + 73814AF10907FB8200C478FC /* speex_callbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_callbacks.h; sourceTree = "<group>"; }; + 73814AF30907FB8200C478FC /* speex_echo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_echo.h; sourceTree = "<group>"; }; + 73814AF40907FB8200C478FC /* speex_header.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_header.h; sourceTree = "<group>"; }; + 73814AF50907FB8200C478FC /* speex_jitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_jitter.h; sourceTree = "<group>"; }; + 73814AF60907FB8200C478FC /* speex_preprocess.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_preprocess.h; sourceTree = "<group>"; }; + 73814AF70907FB8200C478FC /* speex_stereo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_stereo.h; sourceTree = "<group>"; }; + 73814AF80907FB8200C478FC /* speex_types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_types.h; sourceTree = "<group>"; }; + 73814B0C0907FC9900C478FC /* arch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = arch.h; path = ../libspeex/arch.h; sourceTree = SOURCE_ROOT; }; + 73814B1E0907FC9900C478FC /* fixed_arm4.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fixed_arm4.h; path = ../libspeex/fixed_arm4.h; sourceTree = SOURCE_ROOT; }; + 73814B1F0907FC9900C478FC /* fixed_arm5e.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fixed_arm5e.h; path = ../libspeex/fixed_arm5e.h; sourceTree = SOURCE_ROOT; }; + 73814B200907FC9900C478FC /* fixed_bfin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fixed_bfin.h; path = ../libspeex/fixed_bfin.h; sourceTree = SOURCE_ROOT; }; + 73814B210907FC9900C478FC /* fixed_debug.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fixed_debug.h; path = ../libspeex/fixed_debug.h; sourceTree = SOURCE_ROOT; }; + 73814B220907FC9900C478FC /* fixed_generic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fixed_generic.h; path = ../libspeex/fixed_generic.h; sourceTree = SOURCE_ROOT; }; + 73814B280907FC9900C478FC /* jitter.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jitter.c; path = ../libspeex/jitter.c; sourceTree = SOURCE_ROOT; }; + 73814B380907FC9900C478FC /* math_approx.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = math_approx.h; path = ../libspeex/math_approx.h; sourceTree = SOURCE_ROOT; }; + 73814B390907FC9900C478FC /* mdf.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = mdf.c; path = ../libspeex/mdf.c; sourceTree = SOURCE_ROOT; }; + 73814B3A0907FC9900C478FC /* misc_bfin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = misc_bfin.h; path = ../libspeex/misc_bfin.h; sourceTree = SOURCE_ROOT; }; + 73814B410907FC9900C478FC /* preprocess.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = preprocess.c; path = ../libspeex/preprocess.c; sourceTree = SOURCE_ROOT; }; + 73814B460907FC9900C478FC /* smallft.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = smallft.c; path = ../libspeex/smallft.c; sourceTree = SOURCE_ROOT; }; + 73814B470907FC9900C478FC /* smallft.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = smallft.h; path = ../libspeex/smallft.h; sourceTree = SOURCE_ROOT; }; + 73814B4B0907FC9900C478FC /* stack_alloc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = stack_alloc.h; path = ../libspeex/stack_alloc.h; sourceTree = SOURCE_ROOT; }; + 73814B4D0907FC9900C478FC /* testdenoise.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = testdenoise.c; path = ../libspeex/testdenoise.c; sourceTree = SOURCE_ROOT; }; + 73814B4E0907FC9900C478FC /* testecho.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = testecho.c; path = ../libspeex/testecho.c; sourceTree = SOURCE_ROOT; }; + 738837460B193581005C7A69 /* _kiss_fft_guts.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = _kiss_fft_guts.h; path = ../libspeex/_kiss_fft_guts.h; sourceTree = SOURCE_ROOT; }; + 738837470B193581005C7A69 /* fftwrap.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = fftwrap.c; path = ../libspeex/fftwrap.c; sourceTree = SOURCE_ROOT; }; + 738837480B193581005C7A69 /* fftwrap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fftwrap.h; path = ../libspeex/fftwrap.h; sourceTree = SOURCE_ROOT; }; + 738837490B193581005C7A69 /* filterbank.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = filterbank.c; path = ../libspeex/filterbank.c; sourceTree = SOURCE_ROOT; }; + 7388374A0B193581005C7A69 /* filterbank.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = filterbank.h; path = ../libspeex/filterbank.h; sourceTree = SOURCE_ROOT; }; + 7388374B0B193581005C7A69 /* kiss_fft.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = kiss_fft.c; path = ../libspeex/kiss_fft.c; sourceTree = SOURCE_ROOT; }; + 7388374C0B193581005C7A69 /* kiss_fft.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = kiss_fft.h; path = ../libspeex/kiss_fft.h; sourceTree = SOURCE_ROOT; }; + 7388374D0B193581005C7A69 /* kiss_fftr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = kiss_fftr.c; path = ../libspeex/kiss_fftr.c; sourceTree = SOURCE_ROOT; }; + 7388374E0B193581005C7A69 /* kiss_fftr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = kiss_fftr.h; path = ../libspeex/kiss_fftr.h; sourceTree = SOURCE_ROOT; }; + 7388374F0B193581005C7A69 /* lsp_bfin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lsp_bfin.h; path = ../libspeex/lsp_bfin.h; sourceTree = SOURCE_ROOT; }; + 738837500B193581005C7A69 /* pseudofloat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = pseudofloat.h; path = ../libspeex/pseudofloat.h; sourceTree = SOURCE_ROOT; }; + 738837510B193581005C7A69 /* quant_lsp_bfin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = quant_lsp_bfin.h; path = ../libspeex/quant_lsp_bfin.h; sourceTree = SOURCE_ROOT; }; + 738837520B193581005C7A69 /* vorbis_psy.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = vorbis_psy.c; path = ../libspeex/vorbis_psy.c; sourceTree = SOURCE_ROOT; }; + 738837530B193581005C7A69 /* vorbis_psy.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = vorbis_psy.h; path = ../libspeex/vorbis_psy.h; sourceTree = SOURCE_ROOT; }; + 738837770B193667005C7A69 /* libspeex.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libspeex.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; + 8D07F2C80486CC7A007CD1D0 /* Speex.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Speex.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 738837750B193667005C7A69 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C30486CC7A007CD1D0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DDFF38A45A11DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + 8D07F2C80486CC7A007CD1D0 /* Speex.framework */, + 738837770B193667005C7A69 /* libspeex.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + 0867D691FE84028FC02AAC07 /* Speex */ = { + isa = PBXGroup; + children = ( + 08FB77ACFE841707C02AAC07 /* Source */, + 73814AEB0907FB6400C478FC /* Headers */, + 089C1665FE841158C02AAC07 /* Resources */, + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, + 034768DDFF38A45A11DB9C8B /* Products */, + ); + name = Speex; + sourceTree = "<group>"; + }; + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + ); + name = "External Frameworks and Libraries"; + sourceTree = "<group>"; + }; + 089C1665FE841158C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8D07F2C70486CC7A007CD1D0 /* Info.plist */, + 089C1666FE841158C02AAC07 /* InfoPlist.strings */, + ); + name = Resources; + sourceTree = "<group>"; + }; + 08FB77ACFE841707C02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 37CA8DFF0DD7352A005C8CB6 /* os_support.h */, + 37CA8DED0DD73408005C8CB6 /* buffer.c */, + 37CA8DEE0DD73408005C8CB6 /* resample.c */, + 37CA8DEF0DD73408005C8CB6 /* resample_sse.h */, + 738837460B193581005C7A69 /* _kiss_fft_guts.h */, + 738837470B193581005C7A69 /* fftwrap.c */, + 738837480B193581005C7A69 /* fftwrap.h */, + 738837490B193581005C7A69 /* filterbank.c */, + 7388374A0B193581005C7A69 /* filterbank.h */, + 7388374B0B193581005C7A69 /* kiss_fft.c */, + 7388374C0B193581005C7A69 /* kiss_fft.h */, + 7388374D0B193581005C7A69 /* kiss_fftr.c */, + 7388374E0B193581005C7A69 /* kiss_fftr.h */, + 738837500B193581005C7A69 /* pseudofloat.h */, + 738837520B193581005C7A69 /* vorbis_psy.c */, + 738837530B193581005C7A69 /* vorbis_psy.h */, + 73814B0C0907FC9900C478FC /* arch.h */, + 73814B1E0907FC9900C478FC /* fixed_arm4.h */, + 73814B1F0907FC9900C478FC /* fixed_arm5e.h */, + 73814B200907FC9900C478FC /* fixed_bfin.h */, + 73814B210907FC9900C478FC /* fixed_debug.h */, + 73814B220907FC9900C478FC /* fixed_generic.h */, + 73814B280907FC9900C478FC /* jitter.c */, + 73814B380907FC9900C478FC /* math_approx.h */, + 73814B390907FC9900C478FC /* mdf.c */, + 73814B3A0907FC9900C478FC /* misc_bfin.h */, + 73814B410907FC9900C478FC /* preprocess.c */, + 73814B460907FC9900C478FC /* smallft.c */, + 73814B470907FC9900C478FC /* smallft.h */, + 73814B4B0907FC9900C478FC /* stack_alloc.h */, + 73814B4D0907FC9900C478FC /* testdenoise.c */, + 73814B4E0907FC9900C478FC /* testecho.c */, + 32BAE0B70371A74B00C91783 /* Speex_Prefix.pch */, + ); + name = Source; + sourceTree = "<group>"; + }; + 73814AEB0907FB6400C478FC /* Headers */ = { + isa = PBXGroup; + children = ( + 73814AEC0907FB8200C478FC /* speex */, + ); + name = Headers; + sourceTree = "<group>"; + }; + 73814AEC0907FB8200C478FC /* speex */ = { + isa = PBXGroup; + children = ( + 73814AEF0907FB8200C478FC /* speex.h */, + 37CA8DF70DD7347D005C8CB6 /* speex_buffer.h */, + 73814AF30907FB8200C478FC /* speex_echo.h */, + 73814AF40907FB8200C478FC /* speex_header.h */, + 73814AF50907FB8200C478FC /* speex_jitter.h */, + 73814AF60907FB8200C478FC /* speex_preprocess.h */, + 37CA8DF80DD7347D005C8CB6 /* speex_resampler.h */, + 73814AF80907FB8200C478FC /* speex_types.h */, + ); + name = speex; + path = ../include/speex; + sourceTree = SOURCE_ROOT; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 738837730B193667005C7A69 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 73814AFF0907FB8200C478FC /* speex_echo.h in Headers */, + 73814B000907FB8200C478FC /* speex_header.h in Headers */, + 73814B010907FB8200C478FC /* speex_jitter.h in Headers */, + 73814B020907FB8200C478FC /* speex_preprocess.h in Headers */, + 73814B030907FB8200C478FC /* speex_stereo.h in Headers */, + 73814B040907FB8200C478FC /* speex_types.h in Headers */, + 73814B060907FBAB00C478FC /* speex_callbacks.h in Headers */, + 73814B080907FBAE00C478FC /* speex.h in Headers */, + 738837540B193581005C7A69 /* _kiss_fft_guts.h in Headers */, + 738837560B193581005C7A69 /* fftwrap.h in Headers */, + 738837580B193581005C7A69 /* filterbank.h in Headers */, + 7388375A0B193581005C7A69 /* kiss_fft.h in Headers */, + 7388375C0B193581005C7A69 /* kiss_fftr.h in Headers */, + 7388375D0B193581005C7A69 /* lsp_bfin.h in Headers */, + 7388375E0B193581005C7A69 /* pseudofloat.h in Headers */, + 7388375F0B193581005C7A69 /* quant_lsp_bfin.h in Headers */, + 738837610B193581005C7A69 /* vorbis_psy.h in Headers */, + 37CA8DF60DD73424005C8CB6 /* resample_sse.h in Headers */, + 37CA8DF90DD7347D005C8CB6 /* speex_buffer.h in Headers */, + 37CA8DFA0DD7347D005C8CB6 /* speex_resampler.h in Headers */, + 37CA8E000DD7352A005C8CB6 /* os_support.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 738837760B193667005C7A69 /* libspeex (static) */ = { + isa = PBXNativeTarget; + buildConfigurationList = 738837780B193687005C7A69 /* Build configuration list for PBXNativeTarget "libspeex (static)" */; + buildPhases = ( + 738837730B193667005C7A69 /* Headers */, + 738837740B193667005C7A69 /* Sources */, + 738837750B193667005C7A69 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "libspeex (static)"; + productName = speex; + productReference = 738837770B193667005C7A69 /* libspeex.a */; + productType = "com.apple.product-type.library.static"; + }; + 8D07F2BC0486CC7A007CD1D0 /* Speex */ = { + isa = PBXNativeTarget; + buildConfigurationList = 73814ADF0907FB1E00C478FC /* Build configuration list for PBXNativeTarget "Speex" */; + buildPhases = ( + 8D07F2BD0486CC7A007CD1D0 /* Headers */, + 8D07F2BF0486CC7A007CD1D0 /* Resources */, + 8D07F2C10486CC7A007CD1D0 /* Sources */, + 8D07F2C30486CC7A007CD1D0 /* Frameworks */, + 8D07F2C50486CC7A007CD1D0 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Speex; + productInstallPath = "$(HOME)/Library/Frameworks"; + productName = Speex; + productReference = 8D07F2C80486CC7A007CD1D0 /* Speex.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 73814AE30907FB1E00C478FC /* Build configuration list for PBXProject "Speex" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + mainGroup = 0867D691FE84028FC02AAC07 /* Speex */; + productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ..; + targets = ( + 8D07F2BC0486CC7A007CD1D0 /* Speex */, + 738837760B193667005C7A69 /* libspeex (static) */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D07F2C00486CC7A007CD1D0 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 8D07F2C50486CC7A007CD1D0 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 738837740B193667005C7A69 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 738837830B193791005C7A69 /* fftwrap.c in Sources */, + 738837840B193792005C7A69 /* filterbank.c in Sources */, + 7388378B0B1937A0005C7A69 /* jitter.c in Sources */, + 7388378C0B1937A4005C7A69 /* kiss_fft.c in Sources */, + 7388378D0B1937A9005C7A69 /* kiss_fftr.c in Sources */, + 738837940B1937BB005C7A69 /* mdf.c in Sources */, + 738837980B1937C2005C7A69 /* preprocess.c in Sources */, + 7388379B0B1937C9005C7A69 /* smallft.c in Sources */, + 738837A10B1937DD005C7A69 /* vorbis_psy.c in Sources */, + 37CA8DF30DD73408005C8CB6 /* buffer.c in Sources */, + 37CA8DF40DD73408005C8CB6 /* resample.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D07F2C10486CC7A007CD1D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 73814B750907FC9900C478FC /* jitter.c in Sources */, + 73814B8E0907FC9900C478FC /* preprocess.c in Sources */, + 73814B930907FC9900C478FC /* smallft.c in Sources */, + 738837440B1934D0005C7A69 /* mdf.c in Sources */, + 738837550B193581005C7A69 /* fftwrap.c in Sources */, + 738837570B193581005C7A69 /* filterbank.c in Sources */, + 738837590B193581005C7A69 /* kiss_fft.c in Sources */, + 7388375B0B193581005C7A69 /* kiss_fftr.c in Sources */, + 738837600B193581005C7A69 /* vorbis_psy.c in Sources */, + 37CA8DF00DD73408005C8CB6 /* buffer.c in Sources */, + 37CA8DF10DD73408005C8CB6 /* resample.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C1667FE841158C02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = "<group>"; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 73814AE00907FB1E00C478FC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Speex_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = /Library/Frameworks; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + PRODUCT_NAME = Speex; + WRAPPER_EXTENSION = framework; + ZERO_LINK = YES; + }; + name = Debug; + }; + 73814AE10907FB1E00C478FC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Speex_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = /Library/Frameworks; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + PRODUCT_NAME = Speex; + WRAPPER_EXTENSION = framework; + ZERO_LINK = NO; + }; + name = Release; + }; + 73814AE40907FB1E00C478FC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + __MACOSX__, + FLOATING_POINT, + "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1)", + ); + GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1 = "EXPORT=__attribute__((visibility(\\\"default\\\")))"; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + 73814AE50907FB1E00C478FC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + __MACOSX__, + FLOATING_POINT, + "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1)", + ); + GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1 = "EXPORT=__attribute__((visibility(\\\"default\\\")))"; + OTHER_CFLAGS = ( + "$(OTHER_CFLAGS)", + "-falign-loops=16", + ); + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; + 738837790B193687005C7A69 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = speex; + ZERO_LINK = YES; + }; + name = Debug; + }; + 7388377A0B193687005C7A69 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = speex; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 73814ADF0907FB1E00C478FC /* Build configuration list for PBXNativeTarget "Speex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 73814AE00907FB1E00C478FC /* Debug */, + 73814AE10907FB1E00C478FC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 73814AE30907FB1E00C478FC /* Build configuration list for PBXProject "Speex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 73814AE40907FB1E00C478FC /* Debug */, + 73814AE50907FB1E00C478FC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 738837780B193687005C7A69 /* Build configuration list for PBXNativeTarget "libspeex (static)" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 738837790B193687005C7A69 /* Debug */, + 7388377A0B193687005C7A69 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/src/libs/speexdsp/macosx/Speex_Prefix.pch b/src/libs/speexdsp/macosx/Speex_Prefix.pch new file mode 100644 index 00000000..13abf5e4 --- /dev/null +++ b/src/libs/speexdsp/macosx/Speex_Prefix.pch @@ -0,0 +1,5 @@ +// +// Prefix header for all source files of the 'Speex' target in the 'Speex' project. +// + +#include <Carbon/Carbon.h> diff --git a/src/libs/speexdsp/macosx/Speex_UB.xcodeproj/project.pbxproj b/src/libs/speexdsp/macosx/Speex_UB.xcodeproj/project.pbxproj new file mode 100644 index 00000000..1cd5f2e4 --- /dev/null +++ b/src/libs/speexdsp/macosx/Speex_UB.xcodeproj/project.pbxproj @@ -0,0 +1,435 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 73814AFF0907FB8200C478FC /* speex_echo.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF30907FB8200C478FC /* speex_echo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B000907FB8200C478FC /* speex_header.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF40907FB8200C478FC /* speex_header.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B010907FB8200C478FC /* speex_jitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF50907FB8200C478FC /* speex_jitter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B020907FB8200C478FC /* speex_preprocess.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF60907FB8200C478FC /* speex_preprocess.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B030907FB8200C478FC /* speex_stereo.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF70907FB8200C478FC /* speex_stereo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B040907FB8200C478FC /* speex_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF80907FB8200C478FC /* speex_types.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B060907FBAB00C478FC /* speex_callbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF10907FB8200C478FC /* speex_callbacks.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B070907FBAD00C478FC /* speex_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AF00907FB8200C478FC /* speex_bits.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B080907FBAE00C478FC /* speex.h in Headers */ = {isa = PBXBuildFile; fileRef = 73814AEF0907FB8200C478FC /* speex.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73814B750907FC9900C478FC /* jitter.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B280907FC9900C478FC /* jitter.c */; }; + 73814B840907FC9900C478FC /* math_approx.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B370907FC9900C478FC /* math_approx.c */; }; + 73814B880907FC9900C478FC /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B3B0907FC9900C478FC /* misc.c */; }; + 73814B8E0907FC9900C478FC /* preprocess.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B410907FC9900C478FC /* preprocess.c */; }; + 73814B930907FC9900C478FC /* smallft.c in Sources */ = {isa = PBXBuildFile; fileRef = 73814B460907FC9900C478FC /* smallft.c */; }; + 8D07F2C00486CC7A007CD1D0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; +/* End PBXBuildFile section */ + +/* Begin PBXBuildStyle section */ + 4F0BB7EC011F40E904CA0E50 /* Development */ = { + isa = PBXBuildStyle; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + ZERO_LINK = YES; + }; + name = Development; + }; + 4F0BB7ED011F40E904CA0E50 /* Deployment */ = { + isa = PBXBuildStyle; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + ZERO_LINK = NO; + }; + name = Deployment; + }; +/* End PBXBuildStyle section */ + +/* Begin PBXFileReference section */ + 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; + 32BAE0B70371A74B00C91783 /* Speex_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Speex_Prefix.pch; sourceTree = "<group>"; }; + 73814AEF0907FB8200C478FC /* speex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex.h; sourceTree = "<group>"; }; + 73814AF00907FB8200C478FC /* speex_bits.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_bits.h; sourceTree = "<group>"; }; + 73814AF10907FB8200C478FC /* speex_callbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_callbacks.h; sourceTree = "<group>"; }; + 73814AF30907FB8200C478FC /* speex_echo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_echo.h; sourceTree = "<group>"; }; + 73814AF40907FB8200C478FC /* speex_header.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_header.h; sourceTree = "<group>"; }; + 73814AF50907FB8200C478FC /* speex_jitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_jitter.h; sourceTree = "<group>"; }; + 73814AF60907FB8200C478FC /* speex_preprocess.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_preprocess.h; sourceTree = "<group>"; }; + 73814AF70907FB8200C478FC /* speex_stereo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_stereo.h; sourceTree = "<group>"; }; + 73814AF80907FB8200C478FC /* speex_types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speex_types.h; sourceTree = "<group>"; }; + 73814B0C0907FC9900C478FC /* arch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = arch.h; path = ../libspeex/arch.h; sourceTree = SOURCE_ROOT; }; + 73814B1E0907FC9900C478FC /* fixed_arm4.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fixed_arm4.h; path = ../libspeex/fixed_arm4.h; sourceTree = SOURCE_ROOT; }; + 73814B1F0907FC9900C478FC /* fixed_arm5e.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fixed_arm5e.h; path = ../libspeex/fixed_arm5e.h; sourceTree = SOURCE_ROOT; }; + 73814B200907FC9900C478FC /* fixed_bfin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fixed_bfin.h; path = ../libspeex/fixed_bfin.h; sourceTree = SOURCE_ROOT; }; + 73814B210907FC9900C478FC /* fixed_debug.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fixed_debug.h; path = ../libspeex/fixed_debug.h; sourceTree = SOURCE_ROOT; }; + 73814B220907FC9900C478FC /* fixed_generic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fixed_generic.h; path = ../libspeex/fixed_generic.h; sourceTree = SOURCE_ROOT; }; + 73814B280907FC9900C478FC /* jitter.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jitter.c; path = ../libspeex/jitter.c; sourceTree = SOURCE_ROOT; }; + 73814B370907FC9900C478FC /* math_approx.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = math_approx.c; path = ../libspeex/math_approx.c; sourceTree = SOURCE_ROOT; }; + 73814B380907FC9900C478FC /* math_approx.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = math_approx.h; path = ../libspeex/math_approx.h; sourceTree = SOURCE_ROOT; }; + 73814B390907FC9900C478FC /* mdf.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = mdf.c; path = ../libspeex/mdf.c; sourceTree = SOURCE_ROOT; }; + 73814B3A0907FC9900C478FC /* misc_bfin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = misc_bfin.h; path = ../libspeex/misc_bfin.h; sourceTree = SOURCE_ROOT; }; + 73814B3B0907FC9900C478FC /* misc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = misc.c; path = ../libspeex/misc.c; sourceTree = SOURCE_ROOT; }; + 73814B3C0907FC9900C478FC /* misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = misc.h; path = ../libspeex/misc.h; sourceTree = SOURCE_ROOT; }; + 73814B3E0907FC9900C478FC /* modes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = modes.h; path = ../libspeex/modes.h; sourceTree = SOURCE_ROOT; }; + 73814B410907FC9900C478FC /* preprocess.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = preprocess.c; path = ../libspeex/preprocess.c; sourceTree = SOURCE_ROOT; }; + 73814B460907FC9900C478FC /* smallft.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = smallft.c; path = ../libspeex/smallft.c; sourceTree = SOURCE_ROOT; }; + 73814B470907FC9900C478FC /* smallft.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = smallft.h; path = ../libspeex/smallft.h; sourceTree = SOURCE_ROOT; }; + 73814B4B0907FC9900C478FC /* stack_alloc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = stack_alloc.h; path = ../libspeex/stack_alloc.h; sourceTree = SOURCE_ROOT; }; + 73814B4D0907FC9900C478FC /* testdenoise.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = testdenoise.c; path = ../libspeex/testdenoise.c; sourceTree = SOURCE_ROOT; }; + 73814B4E0907FC9900C478FC /* testecho.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = testecho.c; path = ../libspeex/testecho.c; sourceTree = SOURCE_ROOT; }; + 8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; + 8D07F2C80486CC7A007CD1D0 /* Speex.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Speex.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D07F2C30486CC7A007CD1D0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DDFF38A45A11DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + 8D07F2C80486CC7A007CD1D0 /* Speex.framework */, + ); + name = Products; + sourceTree = "<group>"; + }; + 0867D691FE84028FC02AAC07 /* Speex */ = { + isa = PBXGroup; + children = ( + 08FB77ACFE841707C02AAC07 /* Source */, + 73814AEB0907FB6400C478FC /* Headers */, + 089C1665FE841158C02AAC07 /* Resources */, + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, + 034768DDFF38A45A11DB9C8B /* Products */, + ); + name = Speex; + sourceTree = "<group>"; + }; + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + ); + name = "External Frameworks and Libraries"; + sourceTree = "<group>"; + }; + 089C1665FE841158C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8D07F2C70486CC7A007CD1D0 /* Info.plist */, + 089C1666FE841158C02AAC07 /* InfoPlist.strings */, + ); + name = Resources; + sourceTree = "<group>"; + }; + 08FB77ACFE841707C02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 73814B0C0907FC9900C478FC /* arch.h */, + 73814B1E0907FC9900C478FC /* fixed_arm4.h */, + 73814B1F0907FC9900C478FC /* fixed_arm5e.h */, + 73814B200907FC9900C478FC /* fixed_bfin.h */, + 73814B210907FC9900C478FC /* fixed_debug.h */, + 73814B220907FC9900C478FC /* fixed_generic.h */, + 73814B280907FC9900C478FC /* jitter.c */, + 73814B370907FC9900C478FC /* math_approx.c */, + 73814B380907FC9900C478FC /* math_approx.h */, + 73814B390907FC9900C478FC /* mdf.c */, + 73814B3A0907FC9900C478FC /* misc_bfin.h */, + 73814B3B0907FC9900C478FC /* misc.c */, + 73814B3C0907FC9900C478FC /* misc.h */, + 73814B410907FC9900C478FC /* preprocess.c */, + 73814B460907FC9900C478FC /* smallft.c */, + 73814B470907FC9900C478FC /* smallft.h */, + 73814B4B0907FC9900C478FC /* stack_alloc.h */, + 73814B4D0907FC9900C478FC /* testdenoise.c */, + 73814B4E0907FC9900C478FC /* testecho.c */, + 32BAE0B70371A74B00C91783 /* Speex_Prefix.pch */, + ); + name = Source; + sourceTree = "<group>"; + }; + 73814AEB0907FB6400C478FC /* Headers */ = { + isa = PBXGroup; + children = ( + 73814AEC0907FB8200C478FC /* speex */, + ); + name = Headers; + sourceTree = "<group>"; + }; + 73814AEC0907FB8200C478FC /* speex */ = { + isa = PBXGroup; + children = ( + 73814AEF0907FB8200C478FC /* speex.h */, + 73814AF00907FB8200C478FC /* speex_bits.h */, + 73814AF10907FB8200C478FC /* speex_callbacks.h */, + 73814AF30907FB8200C478FC /* speex_echo.h */, + 73814AF40907FB8200C478FC /* speex_header.h */, + 73814AF50907FB8200C478FC /* speex_jitter.h */, + 73814AF60907FB8200C478FC /* speex_preprocess.h */, + 73814AF70907FB8200C478FC /* speex_stereo.h */, + 73814AF80907FB8200C478FC /* speex_types.h */, + ); + name = speex; + path = ../include/speex; + sourceTree = SOURCE_ROOT; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 73814AFF0907FB8200C478FC /* speex_echo.h in Headers */, + 73814B000907FB8200C478FC /* speex_header.h in Headers */, + 73814B010907FB8200C478FC /* speex_jitter.h in Headers */, + 73814B020907FB8200C478FC /* speex_preprocess.h in Headers */, + 73814B030907FB8200C478FC /* speex_stereo.h in Headers */, + 73814B040907FB8200C478FC /* speex_types.h in Headers */, + 73814B060907FBAB00C478FC /* speex_callbacks.h in Headers */, + 73814B070907FBAD00C478FC /* speex_bits.h in Headers */, + 73814B080907FBAE00C478FC /* speex.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 8D07F2BC0486CC7A007CD1D0 /* Speex */ = { + isa = PBXNativeTarget; + buildConfigurationList = 73814ADF0907FB1E00C478FC /* Build configuration list for PBXNativeTarget "Speex" */; + buildPhases = ( + 8D07F2BD0486CC7A007CD1D0 /* Headers */, + 8D07F2BF0486CC7A007CD1D0 /* Resources */, + 8D07F2C10486CC7A007CD1D0 /* Sources */, + 8D07F2C30486CC7A007CD1D0 /* Frameworks */, + 8D07F2C50486CC7A007CD1D0 /* Rez */, + ); + buildRules = ( + ); + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Speex_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Frameworks"; + LIBRARY_STYLE = DYNAMIC; + PRODUCT_NAME = Speex; + WRAPPER_EXTENSION = framework; + }; + dependencies = ( + ); + name = Speex; + productInstallPath = "$(HOME)/Library/Frameworks"; + productName = Speex; + productReference = 8D07F2C80486CC7A007CD1D0 /* Speex.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 73814AE30907FB1E00C478FC /* Build configuration list for PBXProject "Speex_UB" */; + buildSettings = { + }; + buildStyles = ( + 4F0BB7EC011F40E904CA0E50 /* Development */, + 4F0BB7ED011F40E904CA0E50 /* Deployment */, + ); + hasScannedForEncodings = 1; + mainGroup = 0867D691FE84028FC02AAC07 /* Speex */; + productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; + projectDirPath = ""; + targets = ( + 8D07F2BC0486CC7A007CD1D0 /* Speex */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D07F2C00486CC7A007CD1D0 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 8D07F2C50486CC7A007CD1D0 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D07F2C10486CC7A007CD1D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 73814B750907FC9900C478FC /* jitter.c in Sources */, + 73814B840907FC9900C478FC /* math_approx.c in Sources */, + 73814B880907FC9900C478FC /* misc.c in Sources */, + 73814B8E0907FC9900C478FC /* preprocess.c in Sources */, + 73814B930907FC9900C478FC /* smallft.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C1667FE841158C02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = "<group>"; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 73814AE00907FB1E00C478FC /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Speex_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = /Library/Frameworks; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + PRODUCT_NAME = Speex; + WRAPPER_EXTENSION = framework; + ZERO_LINK = YES; + }; + name = Development; + }; + 73814AE10907FB1E00C478FC /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Speex_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = /Library/Frameworks; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + PRODUCT_NAME = Speex; + WRAPPER_EXTENSION = framework; + ZERO_LINK = NO; + }; + name = Deployment; + }; + 73814AE20907FB1E00C478FC /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Speex_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = /Library/Frameworks; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + PRODUCT_NAME = Speex; + WRAPPER_EXTENSION = framework; + }; + name = Default; + }; + 73814AE40907FB1E00C478FC /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_PREPROCESSOR_DEFINITIONS = __MACOSX__; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Development; + }; + 73814AE50907FB1E00C478FC /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_PREPROCESSOR_DEFINITIONS = __MACOSX__; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Deployment; + }; + 73814AE60907FB1E00C478FC /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_PREPROCESSOR_DEFINITIONS = __MACOSX__; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Default; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 73814ADF0907FB1E00C478FC /* Build configuration list for PBXNativeTarget "Speex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 73814AE00907FB1E00C478FC /* Development */, + 73814AE10907FB1E00C478FC /* Deployment */, + 73814AE20907FB1E00C478FC /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 73814AE30907FB1E00C478FC /* Build configuration list for PBXProject "Speex_UB" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 73814AE40907FB1E00C478FC /* Development */, + 73814AE50907FB1E00C478FC /* Deployment */, + 73814AE60907FB1E00C478FC /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/src/libs/speexdsp/regression-fixes/1-resampler_unsigned_fix.patch b/src/libs/speexdsp/regression-fixes/1-resampler_unsigned_fix.patch new file mode 100644 index 00000000..99a4c8a6 --- /dev/null +++ b/src/libs/speexdsp/regression-fixes/1-resampler_unsigned_fix.patch @@ -0,0 +1,17 @@ +diff --git a/libspeex/resample.c b/libspeex/resample.c +index 4403f78..48ffcef 100644 +--- a/libspeex/resample.c ++++ b/libspeex/resample.c +@@ -561,10 +561,10 @@ static void update_filter(SpeexResamplerState *st) + } + for (i=0;i<st->den_rate;i++) + { +- spx_uint32_t j; ++ spx_int32_t j; + for (j=0;j<st->filt_len;j++) + { +- st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func); ++ st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-(spx_int32_t)st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func); + } + } + #ifdef FIXED_POINT diff --git a/src/libs/speexdsp/regressions b/src/libs/speexdsp/regressions new file mode 100644 index 00000000..2a176317 --- /dev/null +++ b/src/libs/speexdsp/regressions @@ -0,0 +1,4 @@ +1: 723f644e09333a0230383eae4af1f3aa3e46e1c3 (r12736): broke resampler badly +Changed the sign of a bunch of parameters in the API. Tons of signed/unsigned changes in the code as a consequence of that. Hopefully this will be the last change to the API. +Fixed: 2007-08-11 + diff --git a/src/libs/speexdsp/speexdsp.pc.in b/src/libs/speexdsp/speexdsp.pc.in new file mode 100644 index 00000000..6c6d26f3 --- /dev/null +++ b/src/libs/speexdsp/speexdsp.pc.in @@ -0,0 +1,15 @@ +# libspeexdsp pkg-config source file + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: speexdsp +Description: Speexdsp is a speech processing library that goes along with the Speex codec +Version: @PACKAGE_VERSION@ +Requires: @FFT_PKGCONFIG@ +Conflicts: +Libs: -L${libdir} -lspeexdsp +Libs.private: @LIBM@ +Cflags: -I${includedir} diff --git a/src/libs/speexdsp/symbian/Makefile.am b/src/libs/speexdsp/symbian/Makefile.am new file mode 100644 index 00000000..6cdaf24b --- /dev/null +++ b/src/libs/speexdsp/symbian/Makefile.am @@ -0,0 +1,6 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = bld.inf config.h speex.mmp diff --git a/src/libs/speexdsp/symbian/bld.inf b/src/libs/speexdsp/symbian/bld.inf new file mode 100644 index 00000000..da5ef487 --- /dev/null +++ b/src/libs/speexdsp/symbian/bld.inf @@ -0,0 +1,49 @@ +/* + Copyright (C) 2003 Commonwealth Scientific and Industrial Research + Organisation (CSIRO) Australia + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of CSIRO Australia nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +PRJ_EXPORTS + +..\include\speex\speex_bits.h \epoc32\include\speex\speex_bits.h +..\include\speex\speex_callbacks.h \epoc32\include\speex\speex_callbacks.h +..\include\speex\speex_config_types.h \epoc32\include\speex\speex_config_types.h +..\include\speex\speex_echo.h \epoc32\include\speex\speex_echo.h +..\include\speex\speex.h \epoc32\include\speex\speex.h +..\include\speex\speex_header.h \epoc32\include\speex\speex_header.h +..\include\speex\speex_jitter.h \epoc32\include\speex\speex_jitter.h +..\include\speex\speex_preprocess.h \epoc32\include\speex\speex_preprocess.h +..\include\speex\speex_stereo.h \epoc32\include\speex\speex_stereo.h +..\include\speex\speex_types.h \epoc32\include\speex\speex_types.h + + +PRJ_MMPFILES + +speex.mmp diff --git a/src/libs/speexdsp/symbian/speex.mmp b/src/libs/speexdsp/symbian/speex.mmp new file mode 100644 index 00000000..6274e4de --- /dev/null +++ b/src/libs/speexdsp/symbian/speex.mmp @@ -0,0 +1,40 @@ +/* + Copyright (C) 2003 Commonwealth Scientific and Industrial Research + Organisation (CSIRO) Australia + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of CSIRO Australia nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +TARGET speex.lib +TARGETTYPE lib +UID 0 +MACRO HAVE_CONFIG_H +SOURCEPATH ..\libspeex +SOURCE buffer.c fftwrap.c filterbank.c jitter.c kiss_fft.c kiss_fftr.c mdf.c preprocess.c resample.c scal.c smallft.c +USERINCLUDE . ..\include\speex +SYSTEMINCLUDE \epoc32\include \epoc32\include\libc ..\include diff --git a/src/libs/speexdsp/ti/Makefile.am b/src/libs/speexdsp/ti/Makefile.am new file mode 100644 index 00000000..fd3c4962 --- /dev/null +++ b/src/libs/speexdsp/ti/Makefile.am @@ -0,0 +1,9 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +SUBDIRS = speex_C54_test speex_C55_test speex_C64_test + +EXTRA_DIST = config.h os_support_custom.h + diff --git a/src/libs/speexdsp/ti/os_support_custom.h b/src/libs/speexdsp/ti/os_support_custom.h new file mode 100644 index 00000000..1accbcb1 --- /dev/null +++ b/src/libs/speexdsp/ti/os_support_custom.h @@ -0,0 +1,128 @@ +/* Copyright (C) 2007 Psi Systems, Inc. + Author: Jean-Marc Valin + File: os_support_custom.h + Memory Allocation overrides to allow user control rather than C alloc/free. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef MANUAL_ALLOC + +/* To avoid changing the Speex call model, this file relies on four static variables + The user main creates two linear buffers, and initializes spxGlobalHeap/ScratchPtr + to point to the start of the two buffers, and initializes spxGlobalHeap/ScratchEnd + to point to the first address following the last byte of the two buffers. + + This mechanism allows, for example, data caching for multichannel applications, + where the Speex state is swapped from a large slow memory to a small fast memory + each time the codec runs. + + Persistent data is allocated in spxGlobalHeap (instead of calloc), while scratch + data is allocated in spxGlobalScratch. +*/ + +extern char *spxGlobalHeapPtr, *spxGlobalHeapEnd; +extern char *spxGlobalScratchPtr, *spxGlobalScratchEnd; + +/* Make sure that all structures are aligned to largest type */ +#define BLOCK_MASK (sizeof(long double)-1) +extern inline void speex_warning(const char *str); + +#define OVERRIDE_SPEEX_ALLOC +static inline void *speex_alloc (int size) +{ + void *ptr; + + ptr = (void *) (((int)spxGlobalHeapPtr + BLOCK_MASK) & ~BLOCK_MASK); //Start on 8 boundary + + spxGlobalHeapPtr = (char *)((int)ptr + size); // Update pointer to next free location + + if (spxGlobalHeapPtr > spxGlobalHeapEnd ) + { +#ifdef VERBOSE_ALLOC + fprintf (stderr, "insufficient space for persistent alloc request %d bytes\n", size); +#endif + return 0; + } + +#ifdef VERBOSE_ALLOC + fprintf (stderr, "Persist Allocated %d chars at %x, %d remaining\n", size, ptr, ((int)spxGlobalHeapEnd - (int)spxGlobalHeapPtr)); +#endif + memset(ptr, 0, size); + return ptr; +} + +#define OVERRIDE_SPEEX_ALLOC_SCRATCH +static inline void *speex_alloc_scratch (int size) +{ + void *ptr; + + ptr = (void *) (((int)spxGlobalScratchPtr + BLOCK_MASK) & ~BLOCK_MASK); //Start on 8 boundary + + spxGlobalScratchPtr = (char *)((int)ptr + size); // Update pointer to next free location + + if (spxGlobalScratchPtr > spxGlobalScratchEnd ) + { +#ifdef VERBOSE_ALLOC + fprintf (stderr, "insufficient space for scratch alloc request %d bytes\n", size); +#endif + return 0; + } + +#ifdef VERBOSE_ALLOC + fprintf (stderr, "Scratch Allocated %d chars at %x, %d remaining\n", size, ptr, ((int)spxGlobalScratchEnd - (int)spxGlobalScratchPtr)); +#endif + memset(ptr, 0, size); + return ptr; +} + +#define OVERRIDE_SPEEX_REALLOC +static inline void *speex_realloc (void *ptr, int size) +{ +#ifdef VERBOSE_ALLOC + speex_warning("realloc attempted, not allowed"); +#endif + return 0; +} + +#define OVERRIDE_SPEEX_FREE +static inline void speex_free (void *ptr) +{ +#ifdef VERBOSE_ALLOC + speex_warning("at speex_free"); +#endif +} +#define OVERRIDE_SPEEX_FREE_SCRATCH +static inline void speex_free_scratch (void *ptr) +{ +#ifdef VERBOSE_ALLOC + speex_warning("at speex_free_scratch"); +#endif +} + +#endif /* !MANUAL_ALLOC */ diff --git a/src/libs/speexdsp/ti/speex_C54_test/Makefile.am b/src/libs/speexdsp/ti/speex_C54_test/Makefile.am new file mode 100644 index 00000000..f7b10bc4 --- /dev/null +++ b/src/libs/speexdsp/ti/speex_C54_test/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = speex_C54_test.cmd speex_C54_test.pjt + + diff --git a/src/libs/speexdsp/ti/speex_C54_test/speex_C54_test.cmd b/src/libs/speexdsp/ti/speex_C54_test/speex_C54_test.cmd new file mode 100644 index 00000000..4989a35f --- /dev/null +++ b/src/libs/speexdsp/ti/speex_C54_test/speex_C54_test.cmd @@ -0,0 +1,71 @@ +/* Copyright (C) 2005 Psi Systems, Inc. + File: speex_C54_test.cmd + Linker command file with memory allocation for TI TMS320VC5416 processor + for use with TI Code Composer (TM) DSP development tools. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +-c +-stack 0x2000 +-heap 0x1000 /* If private memory allocation is used for Speex */ +/*-heap 0x6000 /* If calloc is used for Speex */ +-lrts_ext.lib + +MEMORY +{ +/* PAGE 0: P_DARAM03: origin = 0x80, len = 0x7f00*/ + PAGE 0: P_DARAM03: origin = 0x5000, len = 0x2f80 + PAGE 0: VECT: origin = 0x7f80, len = 0x80 + PAGE 0: P_DARAM47: origin = 0x18000, len = 0x8000 + PAGE 0: SARAM03: origin = 0x28000, len = 0x8000 + PAGE 0: SARAM47: origin = 0x38000, len = 0x8000 + + PAGE 1: USERREGS: origin = 0x60, len = 0x1a + PAGE 1: BIOSREGS: origin = 0x7c, len = 0x4 + PAGE 1: CSLREGS: origin = 0x7a, len = 0x2 + D_DARAM03: origin = 0x80, len = 0x4f80 + D_DARAM47: origin = 0x8000, len = 0x8000 +} + +SECTIONS +{ + .vectors: {} > VECT PAGE 0 + .bootmem: {rts_ext.lib (.text)} > P_DARAM03 PAGE 0 +/* .bootmem: {} > P_DARAM03 PAGE 0 */ + .text: {} > SARAM03 PAGE 0 + .cinit: {} > SARAM03 PAGE 0 + .switch: {} > SARAM03 PAGE 0 + .bss: {} > D_DARAM03 | D_DARAM47 PAGE 1 + .far: {} > D_DARAM03 | D_DARAM47 PAGE 1 + .const: {} > D_DARAM03 | D_DARAM47 PAGE 1 + .sysmem: {} > D_DARAM47 PAGE 1 + .cio: {} > D_DARAM03 | D_DARAM47 PAGE 1 + .stack: {} > D_DARAM03 | D_DARAM47 PAGE 1 + .myheap: {} > D_DARAM47 PAGE 1 +} diff --git a/src/libs/speexdsp/ti/speex_C54_test/speex_C54_test.pjt b/src/libs/speexdsp/ti/speex_C54_test/speex_C54_test.pjt new file mode 100644 index 00000000..e74bb1ba --- /dev/null +++ b/src/libs/speexdsp/ti/speex_C54_test/speex_C54_test.pjt @@ -0,0 +1,44 @@ +; Code Composer Project File, Version 2.0 (do not modify or remove this line) + +[Project Settings] +ProjectDir="C:\Speex\speex_14274\ti\speex_C54_test\" +ProjectType=Executable +CPUFamily=TMS320C54XX +Tool="Compiler" +Tool="CustomBuilder" +Tool="DspBiosBuilder" +Tool="Linker" +Config="Debug" +Config="Release" + +[Source Files] +Source="..\..\libspeexdsp\buffer.c" +Source="..\..\libspeexdsp\fftwrap.c" +Source="..\..\libspeexdsp\filterbank.c" +Source="..\..\libspeexdsp\jitter.c" +Source="..\..\libspeexdsp\kiss_fft.c" +Source="..\..\libspeexdsp\kiss_fftr.c" +Source="..\..\libspeexdsp\mdf.c" +Source="..\..\libspeexdsp\preprocess.c" +Source="..\..\libspeexdsp\resample.c" +Source="..\..\libspeexdsp\scal.c" +Source="speex_C54_test.cmd" + +["Compiler" Settings: "Debug"] +Options=-g -q -o3 -fr"..\ti\speex_C54_test\Debug" -i"..\ti" -i"..\include" -d"_DEBUG" -d"CONFIG_TI_C54X" -d"HAVE_CONFIG_H" -d"NO_LONGLONG" -mf -ms + +["Compiler" Settings: "Release"] +Options=-q -o2 -fr"..\ti\speex_C54_test\Release" -i"..\ti" -i"..\include" -d"CONFIG_TI_C54X" -d"HAVE_CONFIG_H" -d"NO_LONGLONG" -mf -ms + +["DspBiosBuilder" Settings: "Debug"] +Options=-v54 + +["DspBiosBuilder" Settings: "Release"] +Options=-v54 + +["Linker" Settings: "Debug"] +Options=-q -c -heap4096 -m".\Debug\speex_C54_test.map" -o".\Debug\speex_C54_test.out" -stack4096 -w -x + +["Linker" Settings: "Release"] +Options=-q -c -m".\Release\speex_C54_test.map" -o".\Release\speex_C54_test.out" -w -x + diff --git a/src/libs/speexdsp/ti/speex_C55_test/Makefile.am b/src/libs/speexdsp/ti/speex_C55_test/Makefile.am new file mode 100644 index 00000000..6c89ed7c --- /dev/null +++ b/src/libs/speexdsp/ti/speex_C55_test/Makefile.am @@ -0,0 +1,6 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = speex_C55_test.cmd speex_C55_test.pjt diff --git a/src/libs/speexdsp/ti/speex_C55_test/speex_C55_test.cmd b/src/libs/speexdsp/ti/speex_C55_test/speex_C55_test.cmd new file mode 100644 index 00000000..17cbf01d --- /dev/null +++ b/src/libs/speexdsp/ti/speex_C55_test/speex_C55_test.cmd @@ -0,0 +1,65 @@ +/* Copyright (C) 2005 Psi Systems, Inc. + File: speex_C55_test.cmd + Linker command file with memory allocation for TI TMS320VC5509A processor + for use with TI Code Composer (TM) DSP development tools. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +-c +-stack 0x1c00 +-heap 0x1000 /* If private memory allocation is used for Speex */ +/*-heap 0x6000 / * If calloc is used for Speex */ +-sysstack 0x200 +-lrts55.lib + +MEMORY +{ + DARAM: origin = 0x200, len = 0x7e00 + DARAM_B: origin = 0x8000, len = 0x8000 + VECT: origin = 0x100, len = 0x100 + SARAM_A: origin = 0x10000, len = 0x10000 + SARAM_B: origin = 0x20000, len = 0x20000 +} + +SECTIONS +{ + .vectors: {} > VECT + .bootmem: {} > DARAM + .text: {} > SARAM_B + .cinit: {} > SARAM_B + .switch: {} > SARAM_B + .bss: {} > DARAM +/* .far: {} > DARAM*/ + .const: {} > DARAM + .sysmem: {} > DARAM_B + .cio: {} > DARAM + .stack: {} > DARAM + .sysstack: {} > DARAM + .myheap: {} > SARAM_A +} diff --git a/src/libs/speexdsp/ti/speex_C55_test/speex_C55_test.pjt b/src/libs/speexdsp/ti/speex_C55_test/speex_C55_test.pjt new file mode 100644 index 00000000..a4e0cd5f --- /dev/null +++ b/src/libs/speexdsp/ti/speex_C55_test/speex_C55_test.pjt @@ -0,0 +1,44 @@ +; Code Composer Project File, Version 2.0 (do not modify or remove this line) + +[Project Settings] +ProjectDir="C:\Speex\speex_14274\ti\speex_C55_test\" +ProjectType=Executable +CPUFamily=TMS320C55XX +Tool="Compiler" +Tool="CustomBuilder" +Tool="DspBiosBuilder" +Tool="Linker" +Config="Debug" +Config="Release" + +[Source Files] +Source="..\..\libspeexdsp\buffer.c" +Source="..\..\libspeexdsp\fftwrap.c" +Source="..\..\libspeexdsp\filterbank.c" +Source="..\..\libspeexdsp\jitter.c" +Source="..\..\libspeexdsp\kiss_fft.c" +Source="..\..\libspeexdsp\kiss_fftr.c" +Source="..\..\libspeexdsp\mdf.c" +Source="..\..\libspeexdsp\preprocess.c" +Source="..\..\libspeexdsp\resample.c" +Source="..\..\libspeexdsp\scal.c" +Source="speex_C55_test.cmd" + +["Compiler" Settings: "Debug"] +Options=-g -q -o3 -fr"..\ti\speex_C55_test\Debug" -i"..\ti" -i"..\include" -d"_DEBUG" -d"CONFIG_TI_C55X" -d"HAVE_CONFIG_H" -mn + +["Compiler" Settings: "Release"] +Options=-q -o2 -fr"..\ti\speex_C55_test\Release" -i"..\ti" -i"..\include" -d"CONFIG_TI_C55X" -d"HAVE_CONFIG_H" -mn + +["DspBiosBuilder" Settings: "Debug"] +Options=-v55 + +["DspBiosBuilder" Settings: "Release"] +Options=-v55 + +["Linker" Settings: "Debug"] +Options=-q -c -m".\Debug\speex_C55_test.map" -o".\Debug\speex_C55_test.out" -w -x + +["Linker" Settings: "Release"] +Options=-q -c -m".\Release\speex_C55_test.map" -o".\Release\speex_C55_test.out" -w -x + diff --git a/src/libs/speexdsp/ti/speex_C64_test/Makefile.am b/src/libs/speexdsp/ti/speex_C64_test/Makefile.am new file mode 100644 index 00000000..14ea2baa --- /dev/null +++ b/src/libs/speexdsp/ti/speex_C64_test/Makefile.am @@ -0,0 +1,6 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = speex_C64_test.cmd speex_C64_test.pjt diff --git a/src/libs/speexdsp/ti/speex_C64_test/speex_C64_test.cmd b/src/libs/speexdsp/ti/speex_C64_test/speex_C64_test.cmd new file mode 100644 index 00000000..1e023db6 --- /dev/null +++ b/src/libs/speexdsp/ti/speex_C64_test/speex_C64_test.cmd @@ -0,0 +1,59 @@ +/* Copyright (C) 2005 Psi Systems, Inc. + File: speex_C64_test.cmd + Linker command file with memory allocation for TI TMS320C6415 processor + for use with TI Code Composer (TM) DSP development tools. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +-stack 0x10000 +-heap 0x10000 + + +MEMORY +{ + VECRAM : origin = 0x0, len = 0x200 + IPRAM : origin = 0x200, len = 0x40000 + IDRAM : origin = 0x80000, len = 0x70000 +} + +SECTIONS +{ + .vectors > VECRAM + .text > IPRAM + + .bss > IDRAM + .cinit > IDRAM + .const > IDRAM + .far > IDRAM + .stack > IDRAM + .cio > IDRAM + .sysmem > IDRAM + .switch > IDRAM + .myheap > IDRAM +} diff --git a/src/libs/speexdsp/ti/speex_C64_test/speex_C64_test.pjt b/src/libs/speexdsp/ti/speex_C64_test/speex_C64_test.pjt new file mode 100644 index 00000000..f4767d06 --- /dev/null +++ b/src/libs/speexdsp/ti/speex_C64_test/speex_C64_test.pjt @@ -0,0 +1,45 @@ +; Code Composer Project File, Version 2.0 (do not modify or remove this line) + +[Project Settings] +ProjectDir="C:\Speex\speex_14274\ti\speex_C64_test\" +ProjectType=Executable +CPUFamily=TMS320C64XX +Tool="Compiler" +Tool="CustomBuilder" +Tool="DspBiosBuilder" +Tool="Linker" +Config="Debug" +Config="Release" + +[Source Files] +Source="..\..\..\..\CCStudio_v3.1\C6000\cgtools\lib\rts6400.lib" +Source="..\..\libspeexdsp\buffer.c" +Source="..\..\libspeexdsp\fftwrap.c" +Source="..\..\libspeexdsp\filterbank.c" +Source="..\..\libspeexdsp\jitter.c" +Source="..\..\libspeexdsp\kiss_fft.c" +Source="..\..\libspeexdsp\kiss_fftr.c" +Source="..\..\libspeexdsp\mdf.c" +Source="..\..\libspeexdsp\preprocess.c" +Source="..\..\libspeexdsp\resample.c" +Source="..\..\libspeexdsp\scal.c" +Source="speex_C64_test.cmd" + +["Compiler" Settings: "Debug"] +Options=-g -o3 -fr"$(Proj_dir)\Debug" -i"..\ti" -i"..\include" -d"_DEBUG" -d"CONFIG_TI_C6X" -d"HAVE_CONFIG_H" -mv6400 + +["Compiler" Settings: "Release"] +Options=-o3 -fr"$(Proj_dir)\Release" -i"..\ti" -i"..\include" -d"HAVE_CONFIG_H" -mv6400 + +["DspBiosBuilder" Settings: "Debug"] +Options=-v6x + +["DspBiosBuilder" Settings: "Release"] +Options=-v6x + +["Linker" Settings: "Debug"] +Options=-c -m".\Debug\speex_C64_test.map" -o".\Debug\speex_C64_test.out" -w -x + +["Linker" Settings: "Release"] +Options=-c -m".\Release\speex_C64_test.map" -o".\Release\speex_C64_test.out" -w -x + diff --git a/src/libs/speexdsp/tmv/_kiss_fft_guts_tm.h b/src/libs/speexdsp/tmv/_kiss_fft_guts_tm.h new file mode 100644 index 00000000..9cf28647 --- /dev/null +++ b/src/libs/speexdsp/tmv/_kiss_fft_guts_tm.h @@ -0,0 +1,188 @@ +/* Copyright (C) 2007 Hong Zhiqian */ +/** + @file _kiss_fft_guts_tm.h + @author Hong Zhiqian + @brief Various compatibility routines for Speex (TriMedia version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _KISS_FFT_GUTS_TM_ +#define _KISS_FFT_GUTS_TM_ + +#ifdef TM_ASM + +#include <ops/custom_defs.h> + +#ifdef FIXED_POINT + +#undef sround +#define sround(x) sex16(((x) + (1<<(FRACBITS-1)) ) >> FRACBITS) + +#undef MIN +#undef MAX +#define MIN(a,b) imin(a,b) +#define MAX(a,b) imax(a,b) + +#define TM_MUL(res,a,b) \ + { register int a0, a1, b0, b1; \ + \ + a0 = sex16((a)); \ + a1 = asri(16,(a)); \ + b0 = sex16((b)); \ + b1 = asri(16,(b)); \ + (res)= pack16lsb( \ + sround(ifir16((a),funshift2((b),(b)))), \ + sround(a0*b0-a1*b1)); \ + } \ + +#define TM_ADD(res,a,b) \ + { (res)=dspidualadd((a),(b)); \ + } \ + +#define TM_SUB(res,a,b) \ + { (res)=dspidualsub((a),(b)); \ + } \ + +#define TM_SHR(res,a,shift) \ + { (res)=dualasr((a),(shift)); \ + } \ + +#define TM_DIV(res,c,frac) \ + { register int c1, c0; \ + \ + c1 = asri(16,(c)); \ + c0 = sex16((c)); \ + (res) = pack16lsb(sround(c1 * (32767/(frac))), sround(c0 * (32767/(frac))));\ + } \ + +#define TM_NEGMSB(res, a) \ + { (res) = pack16lsb((ineg(asri(16,(a)))), (a)); \ + } \ + +#else + +#undef MIN +#undef MAX +#define MIN(a,b) fmin(a,b) +#define MAX(a,b) fmax(a,b) + +#endif +#endif + +#undef CHECKBUF +#define CHECKBUF(buf,nbuf,n) \ + { \ + if ( nbuf < (size_t)(n) ) { \ + speex_free(buf); \ + buf = (kiss_fft_cpx*)KISS_FFT_MALLOC(sizeof(kiss_fft_cpx)*(n)); \ + nbuf = (size_t)(n); \ + } \ + } \ + +#undef C_ADD +#define C_ADD( res, a,b) \ + { \ + CHECK_OVERFLOW_OP((a).r,+,(b).r) \ + CHECK_OVERFLOW_OP((a).i,+,(b).i) \ + (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ + } \ + + +#undef C_SUB +#define C_SUB( res, a,b) \ + { \ + CHECK_OVERFLOW_OP((a).r,-,(b).r) \ + CHECK_OVERFLOW_OP((a).i,-,(b).i) \ + (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ + } \ + +#undef C_ADDTO +#define C_ADDTO( res , a) \ + { \ + CHECK_OVERFLOW_OP((res).r,+,(a).r) \ + CHECK_OVERFLOW_OP((res).i,+,(a).i) \ + (res).r += (a).r; (res).i += (a).i; \ + } \ + +#undef C_SUBFROM +#define C_SUBFROM( res, a) \ + { \ + CHECK_OVERFLOW_OP((res).r,-,(a).r) \ + CHECK_OVERFLOW_OP((res).i,-,(a).i) \ + (res).r -= (a).r; (res).i -= (a).i; \ + } \ + +#undef kf_cexp +#define kf_cexp(x,phase) \ + { (x)->r = KISS_FFT_COS(phase); \ + (x)->i = KISS_FFT_SIN(phase); } \ + +#undef kf_cexp2 +#define kf_cexp2(x,phase) \ + { (x)->r = spx_cos_norm((phase)); \ + (x)->i = spx_cos_norm((phase)-32768); } \ + + +#ifdef FIXED_POINT + +#undef C_MUL +#define C_MUL(m,a,b) \ + { (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ + (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); } \ + +#undef C_FIXDIV +#define C_FIXDIV(c,div) \ + { DIVSCALAR( (c).r , div); \ + DIVSCALAR( (c).i , div); } \ + +#undef C_MULBYSCALAR +#define C_MULBYSCALAR( c, s ) \ + { (c).r = sround( smul( (c).r , s ) ) ; \ + (c).i = sround( smul( (c).i , s ) ) ; } \ + +#else + +#undef C_MUL +#define C_MUL(m,a,b) \ + { (m).r = (a).r*(b).r - (a).i*(b).i; \ + (m).i = (a).r*(b).i + (a).i*(b).r; } \ + + +#undef C_MULBYSCALAR +#define C_MULBYSCALAR( c, s ) \ + { (c).r *= (s); \ + (c).i *= (s); } \ + + + +#endif + +#endif + diff --git a/src/libs/speexdsp/tmv/fftwrap_tm.h b/src/libs/speexdsp/tmv/fftwrap_tm.h new file mode 100644 index 00000000..a063865b --- /dev/null +++ b/src/libs/speexdsp/tmv/fftwrap_tm.h @@ -0,0 +1,233 @@ +/* Copyright (C) 2007 Hong Zhiqian */ +/** + @file fftwrap_tm.h + @author Hong Zhiqian + @brief Various compatibility routines for Speex (TriMedia version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#include <ops/custom_defs.h> +#include "profile_tm.h" + +#ifdef FIXED_POINT + +#define OVERRIDE_MAXIMIZE_RANGE +static int maximize_range(Int16 *in, Int16 *out, int bound, int len) +{ + register int max_val=0; + register int shift=0; + register int i, j; + + TMDEBUG_ALIGNMEM(in); + TMDEBUG_ALIGNMEM(out); + + MAXIMIZERANGE_START(); + + len >>= 1; + + for ( i=0 ; i<len ; i+=4 ) + { + register int x10, x32, x54, x76; + + x10 = ld32x(in,i); + x32 = ld32x(in,i+1); + x54 = ld32x(in,i+2); + x76 = ld32x(in,i+3); + + x10 = dspidualabs(x10); + x32 = dspidualabs(x32); + x54 = dspidualabs(x54); + x76 = dspidualabs(x76); + + x10 = imax(sex16(x10), asri(16,x10)); + x32 = imax(sex16(x32), asri(16,x32)); + x54 = imax(sex16(x54), asri(16,x54)); + x76 = imax(sex16(x76), asri(16,x76)); + + max_val = imax(max_val,x10); + max_val = imax(max_val,x32); + max_val = imax(max_val,x54); + max_val = imax(max_val,x76); + } + + while ( max_val <= (bound>>1) && max_val != 0 ) + { max_val <<= 1; + shift++; + } + + if ( shift != 0 ) + { + for ( i=0,j=0 ; i<len ; i+=4,j+=16 ) + { + register int x10, x32, x54, x76; + + x10 = ld32x(in,i); + x32 = ld32x(in,i+1); + x54 = ld32x(in,i+2); + x76 = ld32x(in,i+3); + + x10 = dualasl(x10, shift); + x32 = dualasl(x32, shift); + x54 = dualasl(x54, shift); + x76 = dualasl(x76, shift); + + st32d(j,out,x10); + st32d(j+4,out,x32); + st32d(j+8,out,x54); + st32d(j+12,out,x76); + } + } + + MAXIMIZERANGE_STOP(); + + return shift; +} + +#define OVERRIDE_RENORM_RANGE +static void renorm_range(Int16 *in, Int16 *out, int shift, int len) +{ + register int i, j, s, l; + + TMDEBUG_ALIGNMEM(in); + TMDEBUG_ALIGNMEM(out); + + RENORMRANGE_START(); + + s = (1<<((shift))>>1); + s = pack16lsb(s,s); + + len >>= 1; + l = len & (int)0xFFFFFFFE; + + for ( i=0,j=0 ; i<l; i+=2,j+=8 ) + { + register int x10, x32; + + x10 = ld32x(in,i); + x32 = ld32x(in,i+1); + + x10 = dspidualadd(x10, s); + x32 = dspidualadd(x32, s); + + x10 = dualasr(x10, shift); + x32 = dualasr(x32, shift); + + st32d(j,out,x10); + st32d(j+4,out,x32); + } + + if ( len & (int)0x01 ) + { + register int x10; + + x10 = ld32x(in,i); + x10 = dspidualadd(x10, s); + x10 = dualasr(x10, shift); + st32d(j,out,x10); + } + + RENORMRANGE_STOP(); +} + +#endif + +#ifdef USE_COMPACT_KISS_FFT +#ifdef FIXED_POINT + +#define OVERRIDE_POWER_SPECTRUM +void power_spectrum(const spx_word16_t *X, spx_word32_t *ps, int N) +{ + register int x10, x32, x54, x76, *x; + register int i; + + x = (int*)(X-1); + + TMDEBUG_ALIGNMEM(x); + + POWERSPECTRUM_START(); + + x76 = 0; + ps[0] = MULT16_16(X[0],X[0]); + N >>= 1; + + for( i=1 ; i<N ; i+=4 ) + { + x10 = ld32x(x, i); + x32 = ld32x(x, i+1); + x54 = ld32x(x, i+2); + x76 = ld32x(x, i+3); + + ps[i] = ifir16(x10,x10); + ps[i+1] = ifir16(x32,x32); + ps[i+2] = ifir16(x54,x54); + ps[i+3] = ifir16(x76,x76); + } + + x76 = sex16(x76); + ps[N] = x76 * x76; + + POWERSPECTRUM_STOP(); +} + +#else + +#define OVERRIDE_POWER_SPECTRUM +void power_spectrum(const float * restrict X, float * restrict ps, int N) +{ + register int i, j; + register float xx; + + POWERSPECTRUM_START(); + + xx = X[0]; + + ps[0]=MULT16_16(xx,xx); + +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 + for (i=1,j=1;i<N-1;i+=2,j++) + { register float xi, xii; + + xi = X[i]; + xii = X[i+1]; + + ps[j] = MULT16_16(xi,xi) + MULT16_16(xii,xii); + } +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 + + xx = X[i]; + ps[j]=MULT16_16(xx,xx); + + POWERSPECTRUM_STOP(); +} + +#endif +#endif + diff --git a/src/libs/speexdsp/tmv/filterbank_tm.h b/src/libs/speexdsp/tmv/filterbank_tm.h new file mode 100644 index 00000000..e3cdac90 --- /dev/null +++ b/src/libs/speexdsp/tmv/filterbank_tm.h @@ -0,0 +1,289 @@ +/* Copyright (C) 2007 Hong Zhiqian */ +/** + @file filterbank_tm.h + @author Hong Zhiqian + @brief Various compatibility routines for Speex (TriMedia version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#include <ops/custom_defs.h> +#include "profile_tm.h" + +#ifdef FIXED_POINT + +#define OVERRIDE_FILTERBANK_COMPUTE_BANK32 +void filterbank_compute_bank32(FilterBank * restrict bank, spx_word32_t * restrict ps, spx_word32_t * restrict mel) +{ + register int i, j, k, banks, len, zero, s; + register int * restrict left; + register int * restrict right; + register int * restrict bleft; + register int * restrict bright; + + left = (int*)bank->filter_left; + right = (int*)bank->filter_right; + bleft = (int*)bank->bank_left; + bright = (int*)bank->bank_right; + + TMDEBUG_ALIGNMEM(ps); + TMDEBUG_ALIGNMEM(mel); + TMDEBUG_ALIGNMEM(left); + TMDEBUG_ALIGNMEM(right); + TMDEBUG_ALIGNMEM(bleft); + TMDEBUG_ALIGNMEM(bright); + + FILTERBANKCOMPUTEBANK32_START(); + + banks = bank->nb_banks << 2; + zero = 0; + len = bank->len; + s = (1<<((15))>>1); + +#if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEBANK32) +#pragma TCS_unroll=2 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<banks ; i+=4 ) + { st32d(i, mel, zero); + } +#if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEBANK32) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + +#if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEBANK32) +#pragma TCS_unroll=2 +#pragma TCS_unrollexact=1 +#endif + for ( i=0,j=1,k=0 ; i<len ; i+=2,j+=2,++k ) + { register int ps1, ps0, _mel, ps0_msb, ps0_lsb, ps1_msb, ps1_lsb; + register int left10, right10, left1, left0, right1, right0; + register int il1, ir1, il0, ir0; + + ps0 = ld32x(ps,i); + il0 = ld32x(bleft,i); + _mel = ld32x(mel,il0); + left10 = ld32x(left,k); + ir0 = ld32x(bright,i); + right10 = ld32x(right,k); + + ps0_msb = ps0 >> 15; + ps0_lsb = ps0 & 0x00007fff; + left0 = sex16(left10); + right0 = sex16(right10); + + _mel += left0 * ps0_msb + ((left0 * ps0_lsb + s ) >> 15); + mel[il0]= _mel; + _mel = ld32x(mel,ir0); + _mel += right0 * ps0_msb + ((right0 * ps0_lsb + s ) >> 15); + mel[ir0]= _mel; + + ps1 = ld32x(ps,j); + il1 = ld32x(bleft,j); + _mel = ld32x(mel,il1); + ir1 = ld32x(bright,j); + + left1 = asri(16,left10); + right1 = asri(16,right10); + ps1_msb = ps1 >> 15; + ps1_lsb = ps1 & 0x00007fff; + + _mel += left1 * ps1_msb + ((left1 * ps1_lsb + s ) >> 15); + mel[il1]= _mel; + _mel = ld32x(mel,ir1); + _mel += right1 * ps1_msb + ((right1 * ps1_lsb + s ) >> 15); + mel[ir1]= _mel; + } +#if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEBANK32) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + FILTERBANKCOMPUTEBANK32_STOP(); +} + +#define OVERRIDE_FILTERBANK_COMPUTE_PSD16 +void filterbank_compute_psd16(FilterBank * restrict bank, spx_word16_t * restrict mel, spx_word16_t * restrict ps) +{ + register int i, j, k, len, s; + register int * restrict left; + register int * restrict right; + register int * restrict bleft; + register int * restrict bright; + + left = (int*)bank->filter_left; + right = (int*)bank->filter_right; + bleft = (int*)bank->bank_left; + bright = (int*)bank->bank_right; + + TMDEBUG_ALIGNMEM(ps); + TMDEBUG_ALIGNMEM(mel); + TMDEBUG_ALIGNMEM(left); + TMDEBUG_ALIGNMEM(right); + TMDEBUG_ALIGNMEM(bleft); + TMDEBUG_ALIGNMEM(bright); + + FILTERBANKCOMPUTEPSD16_START(); + + len = bank->len; + s = (1<<((15))>>1); + +#if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEPSD16) +#pragma TCS_unroll=2 +#pragma TCS_unrollexact=1 +#endif + for ( i=0,j=0,k=0 ; i<len ; i+=2,j+=4,++k ) + { + register int mell0, melr0, mel1, mel0, mell1, melr1; + register int il1, ir1, il0, ir0; + register int left10, right10, lr1, lr0; + register int acc0, acc1, ps10; + + acc0 = acc1 = s; + + il0 = ld32x(bleft, i); + ir0 = ld32x(bright,i); + mell0 = mel[il0]; + melr0 = mel[ir0]; + left10 = ld32x(left, k); + right10 = ld32x(right, k); + mel0 = pack16lsb(mell0, melr0); + lr0 = pack16lsb(left10, right10); + + acc0 += ifir16(mel0, lr0); + acc0 >>= 15; + + il1 = ld32x(bleft, i+1); + ir1 = ld32x(bright,i+1); + mell1 = mel[il1]; + melr1 = mel[ir1]; + mel1 = pack16lsb(mell1, melr1); + lr1 = pack16msb(left10, right10); + + acc1 += ifir16(mel1, lr1); + acc1 >>= 15; + + ps10 = pack16lsb(acc1, acc0); + + st32d(j, ps, ps10); + } +#if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEPSD16) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + FILTERBANKCOMPUTEPSD16_STOP(); +} + +#else + +#define OVERRIDE_FILTERBANK_COMPUTE_BANK32 +void filterbank_compute_bank32(FilterBank * restrict bank, float * restrict ps, float * restrict mel) +{ + register int i, banks, len; + register int * restrict bleft, * restrict bright; + register float * restrict left, * restrict right; + + banks = bank->nb_banks; + len = bank->len; + bleft = bank->bank_left; + bright= bank->bank_right; + left = bank->filter_left; + right = bank->filter_right; + + FILTERBANKCOMPUTEBANK32_START(); + + memset(mel, 0, banks * sizeof(float)); + +#if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEBANK32) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<len ; ++i) + { + register int id1, id2; + register float psi; + + id1 = bleft[i]; + id2 = bright[i]; + psi = ps[i]; + + mel[id1] += left[i] * psi; + mel[id2] += right[i] * psi; + } +#if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEBANK32) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + FILTERBANKCOMPUTEBANK32_STOP(); +} + +#define OVERRIDE_FILTERBANK_COMPUTE_PSD16 +void filterbank_compute_psd16(FilterBank * restrict bank, float * restrict mel, float * restrict ps) +{ + register int i, len; + register int * restrict bleft, * restrict bright; + register float * restrict left, * restrict right; + + len = bank->len; + bleft = bank->bank_left; + bright= bank->bank_right; + left = bank->filter_left; + right = bank->filter_right; + + FILTERBANKCOMPUTEPSD16_START(); + +#if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEPSD16) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<len ; ++i ) + { + register float acc; + register int id1, id2; + + id1 = bleft[i]; + id2 = bright[i]; + + acc = mel[id1] * left[i]; + acc += mel[id2] * right[i]; + + ps[i] = acc; + } +#if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEPSD16) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + FILTERBANKCOMPUTEPSD16_STOP(); +} + + +#endif diff --git a/src/libs/speexdsp/tmv/fixed_tm.h b/src/libs/speexdsp/tmv/fixed_tm.h new file mode 100644 index 00000000..a70a4202 --- /dev/null +++ b/src/libs/speexdsp/tmv/fixed_tm.h @@ -0,0 +1,100 @@ +/* Copyright (C) 2007 Hong Zhiqian */ +/** + @file fixed_tm.h + @author Hong Zhiqian + @brief Various compatibility routines for Speex (TriMedia version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef FIXED_TM_H +#define FIXED_TM_H + +#include <ops/custom_defs.h> + + +#undef SATURATE +#undef SATURATE16 +#undef SATURATE32 +#define SATURATE(x,a) iclipi(x,a) +#define SATURATE16(x,a) iclipi(x,a) +#define SATURATE32(x,a) iclipi(x,a) + +#undef EXTEND32 +#define EXTEND32(x) sex16(x) + +#undef NEG16 +#undef NEG32 +#define NEG16(x) ineg((int)(x)) +#define NEG32(x) ineg(x) + +#undef ABS +#undef ABS16 +#undef ABS32 +#define ABS(x) iabs(x) +#define ABS32(x) iabs(x) +#define ABS16(x) iabs((int)(x)) + +#undef MIN16 +#undef MIN32 +#define MIN16(a,b) imin((int)(a),(int)(b)) +#define MIN32(a,b) imin(a,b) + +#undef MAX16 +#undef MAX32 +#define MAX16(a,b) imax((int)(a),(int)(b)) +#define MAX32(a,b) imax(a,b) + +#undef ADD16 +#undef SUB16 +#undef ADD32 +#undef SUB32 +#undef MULT16_16 +#undef MULT16_16_16 + +#define ADD16(a,b) ((int)(a) + (int)(b)) +#define SUB16(a,b) ((int)(a) - (int)(b)) +#define ADD32(a,b) ((int)(a) + (int)(b)) +#define SUB32(a,b) ((int)(a) - (int)(b)) +#define MULT16_16_16(a,b) ((int)(a) * (int)(b)) +#define MULT16_16(a,b) ((int)(a) * (int)(b)) + +#if TM_DEBUGMEM_ALIGNNMENT +#include <stdio.h> +#define TMDEBUG_ALIGNMEM(x) \ + { if( ((int)(x) & (int)(0x00000003)) != 0 ) \ + { printf("memory not align. file: %s, line: %d\n", __FILE__, __LINE__); \ + } \ + } + +#else +#define TMDEBUG_ALIGNMEM(x) +#endif + +#endif + diff --git a/src/libs/speexdsp/tmv/kiss_fft_tm.h b/src/libs/speexdsp/tmv/kiss_fft_tm.h new file mode 100644 index 00000000..6f8b985c --- /dev/null +++ b/src/libs/speexdsp/tmv/kiss_fft_tm.h @@ -0,0 +1,599 @@ +/* Copyright (C) 2007 Hong Zhiqian */ +/** + @file kiss_fft_tm.h + @author Hong Zhiqian + @brief Various compatibility routines for Speex (TriMedia version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "_kiss_fft_guts_tm.h" + +#ifdef TM_ASM + +#include "profile_tm.h" + +#ifdef FIXED_POINT + +#define OVERRIDE_KFBFLY2 +static void kf_bfly2( + kiss_fft_cpx *Fout, + const int fstride, + const kiss_fft_cfg st, + int m + ) +{ + register int * restrict Fout2; + register int * restrict tw1 = (int*)st->twiddles; + register int i, j; + register int _inv = !st->inverse; + + Fout2 = (int*)Fout + m; + + for ( i=0,j=0 ; i<m ; ++i,j+=4,tw1+=fstride ) + { register int tw_10, ff_10, f2_10; + + ff_10 = ld32x(Fout, i); + f2_10 = ld32x(Fout2, i); + tw_10 = ld32(tw1); + + if ( _inv ) + { TM_SHR(f2_10, f2_10, 1); + TM_SHR(ff_10, ff_10, 1); + } + + TM_MUL(tw_10, tw_10, f2_10); + TM_SUB(f2_10, ff_10, tw_10); + TM_ADD(ff_10, ff_10, tw_10); + + st32d(j, Fout2, f2_10); + st32d(j, Fout, ff_10); + } +} + +#define OVERRIDE_KFBFLY4 +static void kf_bfly4( + kiss_fft_cpx *Fout, + const int fstride, + const kiss_fft_cfg st, + const int m + ) +{ + register int * restrict tw1; + register int * restrict tw2; + register int * restrict tw3; + register int * restrict Fout1; + register int * restrict Fout2; + register int * restrict Fout3; + register int i, j; + register int fstride2, fstride3; + register int _inv = !st->inverse; + + tw3 = tw2 = tw1 = (int*)st->twiddles; + fstride2 = fstride << 1; + fstride3 = fstride * 3; + + Fout1 = (int*)Fout + m; + Fout2 = (int*)Fout + (m << 1); + Fout3 = (int*)Fout + (m * 3); + + + for ( i=0,j=0 ; i<m ; ++i,j+=4,tw1+=fstride,tw2+=fstride2,tw3+=fstride3 ) + { register int sc0, sc1, sc2, sc3, sc4, sc5; + register int ff0; + + sc0 = ld32x(Fout1,i); + sc3 = ld32(tw1); + sc1 = ld32x(Fout2, i); + sc4 = ld32(tw2); + sc2 = ld32x(Fout3, i); + sc5 = ld32(tw3); + ff0 = ld32x(Fout,i); + + if ( _inv ) + { + TM_ADD(sc0, sc0, 0x00020002); + TM_ADD(sc1, sc1, 0x00020002); + TM_ADD(sc2, sc2, 0x00020002); + TM_ADD(ff0, ff0, 0x00020002); + TM_SHR(sc0, sc0, 2); + TM_SHR(sc1, sc1, 2); + TM_SHR(sc2, sc2, 2); + TM_SHR(ff0, ff0, 2); + } + + TM_MUL(sc0, sc0, sc3); + TM_MUL(sc1, sc1, sc4); + TM_MUL(sc2, sc2, sc5); + TM_SUB(sc5, ff0, sc1); + TM_ADD(ff0, ff0, sc1); + TM_ADD(sc3, sc0, sc2); + TM_SUB(sc4, sc0, sc2); + TM_SUB(sc1, ff0, sc3); + TM_ADD(ff0, ff0, sc3); + + st32d(j, Fout2, sc1); + st32d(j, Fout, ff0); + + sc5 = funshift2(sc5, sc5); + + if ( _inv ) + { TM_ADD(ff0, sc5, sc4); + TM_SUB(sc1, sc5, sc4); + } else + { TM_ADD(sc1, sc5, sc4); + TM_SUB(ff0, sc5, sc4); + } + + sc0 = funshift2(sc1, ff0); + sc2 = funshift2(ff0, sc1); + + st32d(j, Fout1, sc0); + st32d(j, Fout3, sc2); + } +} + + +#define OVERRIDE_KFBFLY3 +static void kf_bfly3( + kiss_fft_cpx *Fout, + const int fstride, + const kiss_fft_cfg st, + int m + ) +{ + register int * restrict tw1; + register int * restrict tw2; + register int * restrict Fout1; + register int * restrict Fout2; + register int epi; + register int i, j; + register int fstride2; + register int _inv = !st->inverse; + + tw1 = tw2 = (int*)st->twiddles; + Fout1 = (int*)Fout + m; + Fout2 = (int*)Fout + (m << 1); + epi = tw1[fstride*m]; + epi = pack16lsb(epi,epi); + fstride2 = fstride << 1; + + for ( i=0,j=0 ; i<m ; ++i,j+=4,tw1+=fstride,tw2+=fstride2 ) + { register int sc0, sc1, sc2, sc3, sc4, sc5; + register int ff0; + + sc1 = ld32x(Fout1,i); + sc2 = ld32x(Fout2,i); + sc3 = ld32(tw1); + sc4 = ld32(tw2); + ff0 = ld32x(Fout,i); + + if ( _inv ) + { + TM_DIV(sc1, sc1, 3); + TM_DIV(sc2, sc2, 3); + TM_DIV(ff0, ff0, 3); + } + + TM_MUL(sc1, sc1, sc3); + TM_MUL(sc2, sc2, sc4); + TM_ADD(sc3, sc1, sc2); + TM_SUB(sc0, sc1, sc2); + TM_SHR(sc4, sc3, 1); + TM_SUB(sc1, ff0, sc4); + + sc0 = dspidualmul(sc0, epi); + sc0 = funshift2(sc0, sc0); + + TM_ADD(ff0, ff0, sc3); + TM_ADD(sc4, sc1, sc0); + TM_SUB(sc5, sc1, sc0); + + sc1 = funshift2(sc4, sc5); + sc2 = funshift2(sc5, sc4); + sc2 = funshift2(sc2, sc2); + + st32d(j, Fout1, sc1); + st32d(j, Fout, ff0); + st32d(j, Fout2, sc2); + } +} + + +#define OVERRIDE_KFBFLY5 +static void kf_bfly5( + kiss_fft_cpx *Fout, + const int fstride, + const kiss_fft_cfg st, + int m + ) +{ + register int * restrict tw1; + register int * restrict tw2; + register int * restrict tw3; + register int * restrict tw4; + register int * restrict Fout1; + register int * restrict Fout2; + register int * restrict Fout3; + register int * restrict Fout4; + register int fstride2, fstride3, fstride4; + register int i, j; + register int yab_msb, yab_lsb, yba_msb, yba_lsb; + register int _inv = !st->inverse; + + + Fout1=(int*)Fout+m; + Fout2=(int*)Fout+(m<<1); + Fout3=(int*)Fout+(3 *m); + Fout4=(int*)Fout+(m<<2); + + tw1 = tw2 = tw3 = tw4 = (int*)st->twiddles; + + i = tw1[fstride*m]; + yab_lsb = tw1[fstride*(m<<1)]; + yab_msb = pack16msb(i, yab_lsb); + yab_lsb = pack16lsb(i, yab_lsb); + yba_msb = funshift2(-sex16(yab_msb), yab_msb); + yba_lsb = funshift2(yab_lsb, yab_lsb); + + fstride2 = fstride << 1; + fstride3 = fstride * 3; + fstride4 = fstride << 2; + + for ( i=0,j=0 ; i<m ; ++i,j+=4,tw1+=fstride,tw2+=fstride2,tw3+=fstride3,tw4+=fstride4 ) + { register int sc0, sc1, sc2, sc3, sc4, sc5, sc6; + register int sc7, sc8, sc9, sc10, sc11, sc12; + register int ff0, sc78_msb, sc78_lsb, sc90_msb, sc90_lsb; + + sc0 = ld32x(Fout,i); + sc1 = ld32x(Fout1,i); + sc2 = ld32x(Fout2,i); + sc3 = ld32x(Fout3,i); + sc4 = ld32x(Fout4,i); + sc5 = ld32(tw1); + sc6 = ld32(tw2); + sc7 = ld32(tw3); + sc8 = ld32(tw4); + + if ( _inv ) + { + TM_DIV(sc0, sc0, 5); + TM_DIV(sc1, sc1, 5); + TM_DIV(sc2, sc2, 5); + TM_DIV(sc3, sc3, 5); + TM_DIV(sc4, sc4, 5); + } + + ff0 = sc0; + + TM_MUL(sc1, sc1, sc5); + TM_MUL(sc2, sc2, sc6); + TM_MUL(sc3, sc3, sc7); + TM_MUL(sc4, sc4, sc8); + TM_ADD(sc7, sc1, sc4); + TM_SUB(sc10,sc1, sc4); + TM_ADD(sc8, sc2, sc3); + TM_SUB(sc9, sc2, sc3); + + TM_ADD(ff0, ff0, sc7); + TM_ADD(ff0, ff0, sc8); + st32d(j, Fout, ff0); + + sc78_msb = pack16msb(sc7,sc8); + sc78_lsb = pack16lsb(sc7,sc8); + sc90_msb = pack16msb(sc10,sc9); + sc90_lsb = pack16lsb(sc10,sc9); + + sc5 = pack16lsb( sround(ifir16(sc78_msb,yab_lsb)), sround(ifir16(sc78_lsb,yab_lsb))); + sc6 = pack16lsb(-sround(ifir16(sc90_lsb,yab_msb)), sround(ifir16(sc90_msb,yab_msb))); + + TM_ADD(sc5, sc5, sc0); + TM_SUB(sc1, sc5, sc6); + TM_ADD(sc4, sc5, sc6); + st32d(j, Fout1, sc1); + st32d(j, Fout4, sc4); + + sc11 = pack16lsb( sround(ifir16(sc78_msb,yba_lsb)), sround(ifir16(sc78_lsb,yba_lsb))); + sc12 = pack16lsb(-sround(ifir16(sc90_lsb,yba_msb)), sround(ifir16(sc90_msb,yba_msb))); + + TM_ADD(sc11, sc11, sc0); + TM_ADD(sc2, sc11, sc12); + TM_SUB(sc3, sc11, sc12); + st32d(j, Fout2, sc2); + st32d(j, Fout3, sc3); + + } +} + + +#define OVERRIDE_KF_BFLY_GENERIC +static void kf_bfly_generic( + kiss_fft_cpx * restrict Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m, + int p + ) +{ + register int _inv = !st->inverse; + register int i, j, k, l; + register int * restrict twiddles = (int*)st->twiddles; + register int Norig = st->nfft; + + CHECKBUF(scratchbuf,nscratchbuf,p); + + for ( i=0; i<m; ++i ) + { register int sc10; + + for ( j=0,k=i ; j<p ; ++j,k+=m ) + { register int f10; + + f10 = ld32x(Fout,k); + + if ( _inv ) + { TM_DIV(f10, f10, p); + } + + st32d(j<<2, scratchbuf, f10); + } + + for ( j=0,k=i,sc10=ld32(scratchbuf) ; j<p ; ++j,k+=m ) + { + register int twidx = 0; + register int f10; + + for ( l=1,f10 = sc10 ; l<p ; ++l ) + { register int tw, sc; + + twidx += fstride * k; + if ( twidx>=Norig ) + { twidx -= Norig; + } + + sc = ld32x(scratchbuf,l); + tw = ld32x(twiddles,twidx); + + TM_MUL(sc, sc, tw); + TM_ADD(f10, f10, sc); + } + st32d(k<<2, Fout, f10); + } + } +} + +#else + +#define OVERRIDE_KFBFLY2 +static void kf_bfly2( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m + ) +{ + register kiss_fft_cpx * restrict Fout2; + register kiss_fft_cpx * restrict tw1 = st->twiddles; + + Fout2 = Fout + m; + + do + { + register kiss_fft_cpx _fout2, _fout, t; + + _fout2 = *Fout2; + _fout = *Fout; + + C_MUL ( t, _fout2, *tw1); + C_SUB (_fout2, _fout, t); + C_ADD (_fout, _fout, t); + + *Fout2 = _fout2; + *Fout = _fout; + + tw1 += fstride; + ++Fout2; + ++Fout; + + } while ( --m ); +} + +#define OVERRIDE_KFBFLY4 +static void kf_bfly4( + kiss_fft_cpx * Fout, + const int fstride, + const kiss_fft_cfg st, + int m + ) +{ + register kiss_fft_cpx * restrict tw1,* restrict tw2,* restrict tw3; + register kiss_fft_cpx * restrict Fout1, * restrict Fout2, * restrict Fout3; + register int _inv = !st->inverse; + + tw3 = tw2 = tw1 = st->twiddles; + + Fout1 = Fout + m; + Fout2 = Fout + (m << 1); + Fout3 = Fout + (m * 3); + + do { + + register kiss_fft_cpx _fout; + register kiss_fft_cpx sc0, sc1, sc2, sc3, sc4, sc5; + + _fout = *Fout; + + C_MUL( sc0,*Fout1, *tw1); + C_MUL( sc1,*Fout2, *tw2); + C_MUL( sc2,*Fout3, *tw3); + C_SUB( sc5, _fout, sc1); + C_ADD( _fout, _fout, sc1); + C_ADD( sc3, sc0, sc2); + C_SUB( sc4, sc0, sc2); + C_SUB(*Fout2, _fout, sc3); + C_ADD( *Fout, _fout, sc3); + + tw1 += fstride; + tw2 += (fstride << 1); + tw3 += (fstride * 3); + + if ( _inv ) + { + Fout1->r = sc5.r + sc4.i; + Fout1->i = sc5.i - sc4.r; + Fout3->r = sc5.r - sc4.i; + Fout3->i = sc5.i + sc4.r; + } + else + { Fout1->r = sc5.r - sc4.i; + Fout1->i = sc5.i + sc4.r; + Fout3->r = sc5.r + sc4.i; + Fout3->i = sc5.i - sc4.r; + } + + + ++Fout; ++Fout1; ++Fout2; ++Fout3; + + } while(--m); +} + +#define OVERRIDE_KFBFLY3 +static void kf_bfly3( + kiss_fft_cpx * Fout, + const int fstride, + const kiss_fft_cfg st, + int m + ) +{ + register kiss_fft_cpx * restrict Fout1, * restrict Fout2; + register kiss_fft_cpx * restrict tw1,* restrict tw2; + register float epi; + + tw1 = tw2 = st->twiddles; + epi = st->twiddles[fstride*m].i; + Fout1 = Fout + m; + Fout2 = Fout + (m << 1); + + do { + + register kiss_fft_cpx _fout; + register kiss_fft_cpx sc0, sc1, sc2, sc3; + + _fout = *Fout; + + C_MUL( sc1, *Fout1, *tw1); + C_MUL( sc2, *Fout2, *tw2); + C_ADD( sc3, sc1, sc2); + C_SUB( sc0, sc1, sc2); + tw1 += fstride; + tw2 += (fstride << 1); + + sc1.r = _fout.r - HALF_OF(sc3.r); + sc1.i = _fout.i - HALF_OF(sc3.i); + + C_MULBYSCALAR(sc0, epi); + C_ADD(*Fout, _fout, sc3); + + Fout2->r = sc1.r + sc0.i; + Fout2->i = sc1.i - sc0.r; + + Fout1->r = sc1.i - sc0.i; + Fout1->i = sc1.r + sc0.r; + + ++Fout; ++Fout1; ++Fout2; + + } while(--m); +} + +#define OVERRIDE_KFBFLY5 +static void kf_bfly5( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m + ) +{ + register kiss_fft_cpx * restrict Fout1,* restrict Fout2,* restrict Fout3,* restrict Fout4; + register int u; + register kiss_fft_cpx *tw; + register float yar, yai, ybr, ybi; + + Fout1=Fout+m; + Fout2=Fout+(m<<1); + Fout3=Fout+(m*3); + Fout4=Fout+(m<<2); + + tw = st->twiddles; + yar = tw[fstride*m].r; + yai = tw[fstride*m].i; + ybr = tw[fstride*2*m].r; + ybi = tw[fstride*2*m].i; + + for ( u=0; u<m; ++u ) + { + register kiss_fft_cpx sc0, sc1, sc2, sc3, sc4, sc5, sc6, sc7, sc8, sc9, sc10, sc11, sc12; + + sc0 = *Fout; + + C_MUL( sc1,*Fout1, tw[u*fstride]); + C_MUL( sc2,*Fout2, tw[2*u*fstride]); + C_MUL( sc3,*Fout3, tw[3*u*fstride]); + C_MUL( sc4,*Fout4, tw[4*u*fstride]); + + C_ADD( sc7, sc1, sc4); + C_SUB( sc10, sc1, sc4); + C_ADD( sc8, sc2, sc3); + C_SUB( sc9, sc2, sc3); + + Fout->r = sc0.r + sc7.r + sc8.r; + Fout->i = sc0.i + sc7.i + sc8.i; + + sc5.r = sc0.r + S_MUL(sc7.r,yar) + S_MUL(sc8.r,ybr); + sc5.i = sc0.i + S_MUL(sc7.i,yar) + S_MUL(sc8.i,ybr); + + sc6.r = S_MUL(sc10.i,yai) + S_MUL(sc9.i,ybi); + sc6.i = -S_MUL(sc10.r,yai) - S_MUL(sc9.r,ybi); + + C_SUB(*Fout1,sc5,sc6); + C_ADD(*Fout4,sc5,sc6); + + sc11.r = sc0.r + S_MUL(sc7.r,ybr) + S_MUL(sc8.r,yar); + sc11.i = sc0.i + S_MUL(sc7.i,ybr) + S_MUL(sc8.i,yar); + sc12.r = - S_MUL(sc10.i,ybi) + S_MUL(sc9.i,yai); + sc12.i = S_MUL(sc10.r,ybi) - S_MUL(sc9.r,yai); + C_ADD(*Fout2,sc11,sc12); + C_SUB(*Fout3,sc11,sc12); + + ++Fout1; ++Fout2; ++Fout3; ++Fout4; + } +} + + +#endif + +#endif diff --git a/src/libs/speexdsp/tmv/kiss_fftr_tm.h b/src/libs/speexdsp/tmv/kiss_fftr_tm.h new file mode 100644 index 00000000..8005b22b --- /dev/null +++ b/src/libs/speexdsp/tmv/kiss_fftr_tm.h @@ -0,0 +1,235 @@ +/* Copyright (C) 2007 Hong Zhiqian */ +/** + @file kiss_fftr_tm.h + @author Hong Zhiqian + @brief Various compatibility routines for Speex (TriMedia version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#include "_kiss_fft_guts_tm.h" + +#ifdef TM_ASM + +#include "profile_tm.h" + +#ifdef FIXED_POINT + +#define TM_NDIV(res,c,frac) \ + { register int c1, c0; \ + \ + c1 = -asri(16,(c)); \ + c0 = sex16((c)); \ + (res) = pack16lsb(sround(c1 * (32767/(frac))), sround(c0 * (32767/(frac))));\ + } + + +#define OVERRIDE_KISS_FFTR +void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar * restrict timedata, kiss_fft_cpx * restrict freqdata) +{ + register int ncfft, ncfft2, k; + register int * restrict tmpbuf; + register int * restrict twiddles; + + ncfft = st->substate->nfft; + ncfft2 = ncfft >> 1; + tmpbuf = (int*)st->tmpbuf; + twiddles = (int*)st->super_twiddles; + + TMDEBUG_ALIGNMEM(timedata); + TMDEBUG_ALIGNMEM(freqdata); + TMDEBUG_ALIGNMEM(tmpbuf); + TMDEBUG_ALIGNMEM(twiddles); + + kiss_fft(st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf); + + { + register int tdcr, tdci; + tdcr = sround(st->tmpbuf[0].r * (32767/2)); + tdci = sround(st->tmpbuf[0].i * (32767/2)); + + freqdata[0].r = tdcr + tdci; + freqdata[ncfft].r = tdcr - tdci; + freqdata[ncfft].i = freqdata[0].i = 0; + } + + for ( k=1 ; k <= ncfft2 ; ++k ) + { + register int fpk, fpnk, i, tw, f1k, f2k; + register int fq1, fq2; + + i = ncfft-k; + + fpk = ld32x(tmpbuf,k); + tw = ld32x(twiddles,k); + fpnk = ld32x(tmpbuf,i); + + TM_DIV(fpk, fpk, 2); + TM_NDIV(fpnk,fpnk,2); + + TM_ADD( f1k, fpk , fpnk ); + TM_SUB( f2k, fpk , fpnk ); + TM_MUL( tw , f2k, tw ); + TM_ADD( fq1, f1k, tw ); + TM_SHR( fq1, fq1, 1 ); + TM_SUB( fq2, f1k, tw ); + TM_NEGMSB( fq2, fq2 ); + TM_SHR( fq2, fq2, 1 ); + + + st32d( k<<2, freqdata, fq1 ); + st32d( i<<2, freqdata, fq2 ); + } +} + +#define OVERRIDE_KISS_FFTRI +void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx * restrict freqdata,kiss_fft_scalar * restrict timedata) +{ + register int k, ncfft, ncfft2; + register int * restrict tmpbuf; + register int * restrict twiddles; + + ncfft = st->substate->nfft; + ncfft2 = ncfft >> 1; + tmpbuf = (int*)st->tmpbuf; + twiddles = (int*)st->super_twiddles; + + TMDEBUG_ALIGNMEM(freqdata); + TMDEBUG_ALIGNMEM(timedata); + TMDEBUG_ALIGNMEM(tmpbuf); + TMDEBUG_ALIGNMEM(twiddles); + + { + register int fqr, fqnr; + + fqr = freqdata[0].r; + fqnr = freqdata[ncfft].r; + + st->tmpbuf[0].r = fqr + fqnr; + st->tmpbuf[0].i = fqr - fqnr; + } + + for ( k=1 ; k <= ncfft2 ; ++k ) + { + register int fk, fnkc, i, tw, fek, fok, tmp; + register int tbk, tbn; + + i = ncfft-k; + + fk = ld32x(freqdata,k); + tw = ld32x(twiddles,k); + fnkc = pack16lsb(-freqdata[i].i, freqdata[i].r); + + TM_ADD (fek, fk, fnkc); + TM_SUB (tmp, fk, fnkc); + TM_MUL (fok, tmp, tw ); + TM_ADD (tbk, fek, fok); + TM_SUB (tbn, fek, fok); + TM_NEGMSB(tbn, tbn); + + st32d(k<<2, tmpbuf, tbk); + st32d(i<<2, tmpbuf, tbn); + } + kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); +} + +#else + +#define OVERRIDE_KISS_FFTR +void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar * restrict timedata,kiss_fft_cpx * restrict freqdata) +{ + register kiss_fft_cpx fpnk, fpk, f1k, f2k, twk; + register int k, ncfft; + register kiss_fft_cpx * restrict tmpbuf, * restrict tw; + register float tdcr, tdci; + + ncfft = st->substate->nfft; + tmpbuf= st->tmpbuf; + tw = st->super_twiddles; + + kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, tmpbuf ); + + tdcr = tmpbuf[0].r; + tdci = tmpbuf[0].i; + + freqdata[0].r = tdcr + tdci; + freqdata[ncfft].r = tdcr - tdci; + freqdata[ncfft].i = freqdata[0].i = 0; + + for ( k=1;k <= ncfft/2 ; ++k ) + { + fpk = tmpbuf[k]; + fpnk.r = tmpbuf[ncfft-k].r; + fpnk.i = -tmpbuf[ncfft-k].i; + + C_ADD( f1k, fpk , fpnk ); + C_SUB( f2k, fpk , fpnk ); + C_MUL( twk, f2k , tw[k]); + + freqdata[k].r = HALF_OF(f1k.r + twk.r); + freqdata[k].i = HALF_OF(f1k.i + twk.i); + freqdata[ncfft-k].r = HALF_OF(f1k.r - twk.r); + freqdata[ncfft-k].i = HALF_OF(twk.i - f1k.i); + } +} + +#define OVERRIDE_KISS_FFTRI +void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx * restrict freqdata,kiss_fft_scalar * restrict timedata) +{ + register int k, ncfft; + register kiss_fft_cpx * restrict tmpbuf, * restrict tw; + + + ncfft = st->substate->nfft; + tmpbuf= st->tmpbuf; + tw = st->super_twiddles; + + tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; + tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; + + for (k = 1; k <= ncfft / 2; ++k) + { + register kiss_fft_cpx fk, fnkc, fek, fok, tmp; + fk = freqdata[k]; + fnkc.r = freqdata[ncfft - k].r; + fnkc.i = -freqdata[ncfft - k].i; + + C_ADD (fek, fk, fnkc); + C_SUB (tmp, fk, fnkc); + C_MUL (fok,tmp,tw[k]); + C_ADD (tmpbuf[k],fek, fok); + C_SUB (tmp, fek, fok); + tmpbuf[ncfft - k].r = tmp.r; + tmpbuf[ncfft - k].i = -tmp.i; + } + kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); +} + +#endif +#endif + diff --git a/src/libs/speexdsp/tmv/mdf_tm.h b/src/libs/speexdsp/tmv/mdf_tm.h new file mode 100644 index 00000000..0a6128e9 --- /dev/null +++ b/src/libs/speexdsp/tmv/mdf_tm.h @@ -0,0 +1,1192 @@ +/* Copyright (C) 2007 Hong Zhiqian */ +/** + @file mdf_tm.h + @author Hong Zhiqian + @brief Various compatibility routines for Speex (TriMedia version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#include <ops/custom_defs.h> +#include "profile_tm.h" + +// shifted power spectrum to fftwrap.c so that optimisation can be shared between mdf.c and preprocess.c +#define OVERRIDE_POWER_SPECTRUM + +#ifdef FIXED_POINT + +#else + +#define OVERRIDE_FILTER_DC_NOTCH16 +void filter_dc_notch16( + const spx_int16_t * restrict in, + float radius, + float * restrict out, + int len, + float * restrict mem +) +{ + register int i; + register float den2, r1; + register float mem0, mem1; + + FILTERDCNOTCH16_START(); + + r1 = 1 - radius; + den2 = (radius * radius) + (0.7 * r1 * r1); + mem0 = mem[0]; + mem1 = mem[1]; + +#if (TM_UNROLL && TM_UNROLL_FILTERDCNOTCH16) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<len ; ++i ) + { + register float vin = in[i]; + register float vout = mem0 + vin; + register float rvout = radius * vout; + + mem0 = mem1 + 2 * (-vin + rvout); + mem1 = vin - (den2 * vout); + + out[i] = rvout; + } +#if (TM_UNROLL && TM_UNROLL_FILTERDCNOTCH16) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + mem[0] = mem0; + mem[1] = mem1; + + FILTERDCNOTCH16_STOP(); +} + +#define OVERRIDE_MDF_INNER_PROD +float mdf_inner_prod( + const float * restrict x, + const float * restrict y, + int len +) +{ + register float sum = 0; + + MDFINNERPROD_START(); + + len >>= 1; + +#if (TM_UNROLL && TM_UNROLL_MDFINNERPRODUCT) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + while(len--) + { + register float acc0, acc1; + + acc0 = (*x++) * (*y++); + acc1 = (*x++) * (*y++); + + sum += acc0 + acc1; + } +#if (TM_UNROLL && TM_UNROLL_MDFINNERPRODUCT) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + MDFINNERPROD_STOP(); + + return sum; +} + +#define OVERRIDE_SPECTRAL_MUL_ACCUM +void spectral_mul_accum( + const float * restrict X, + const float * restrict Y, + float * restrict acc, + int N, int M +) +{ + register int i, j; + register float Xi, Yi, Xii, Yii; + register int _N; + + SPECTRALMULACCUM_START(); + + acc[0] = X[0] * Y[0]; + _N = N-1; + + for ( i=1 ; i<_N ; i+=2 ) + { + Xi = X[i]; + Yi = Y[i]; + Xii = X[i+1]; + Yii = Y[i+1]; + + acc[i] = (Xi * Yi - Xii * Yii); + acc[i+1]= (Xii * Yi + Xi * Yii); + } + + acc[_N] = X[_N] * Y[_N]; + + for ( j=1,X+=N,Y+=N ; j<M ; j++ ) + { + acc[0] += X[0] * Y[0]; + + for ( i=1 ; i<N-1 ; i+=2 ) + { + Xi = X[i]; + Yi = Y[i]; + Xii = X[i+1]; + Yii = Y[i+1]; + + acc[i] += (Xi * Yi - Xii * Yii); + acc[i+1]+= (Xii * Yi + Xi * Yii); + } + + acc[_N] += X[_N] * Y[_N]; + X += N; + Y += N; + } + + SPECTRALMULACCUM_STOP(); +} + +#define OVERRIDE_WEIGHTED_SPECTRAL_MUL_CONJ +void weighted_spectral_mul_conj( + const float * restrict w, + const float p, + const float * restrict X, + const float * restrict Y, + float * restrict prod, + int N +) +{ + register int i, j; + register int _N; + + WEIGHTEDSPECTRALMULCONJ_START(); + + prod[0] = p * w[0] * X[0] * Y[0]; + _N = N-1; + + for (i=1,j=1;i<_N;i+=2,j++) + { + register float W; + register float Xi, Yi, Xii, Yii; + + Xi = X[i]; + Yi = Y[i]; + Xii = X[i+1]; + Yii = Y[i+1]; + W = p * w[j]; + + + prod[i] = W * (Xi * Yi + Xii * Yii); + prod[i+1]= W * (Xi * Yii - Xii * Yi); + } + + prod[_N] = p * w[j] * X[_N] * Y[_N]; + + WEIGHTEDSPECTRALMULCONJ_STOP(); +} + +#define OVERRIDE_MDF_ADJUST_PROP +void mdf_adjust_prop( + const float * restrict W, + int N, + int M, + float * restrict prop +) +{ + register int i, j; + register float max_sum = 1; + register float prop_sum = 1; + + MDFADJUSTPROP_START(); + + for ( i=0 ; i<M ; ++i ) + { + register float tmp = 1; + register int k = i * N; + register int l = k + N; + register float propi; + +#if (TM_UNROLL && TM_UNROLL_MDFADJUSTPROP) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( j=k ; j<l ; ++j ) + { + register float wi = W[j]; + + tmp += wi * wi; + } +#if (TM_UNROLL && TM_UNROLL_MDFADJUSTPROP) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + propi = spx_sqrt(tmp); + prop[i]= propi; + max_sum= fmux(propi > max_sum, propi, max_sum); + } + + for ( i=0 ; i<M ; ++i ) + { + register float propi = prop[i]; + + propi += .1f * max_sum; + prop_sum += propi; + prop[i] = propi; + } + + prop_sum = 0.99f / prop_sum; + for ( i=0 ; i<M ; ++i ) + { prop[i] = prop_sum * prop[i]; + } + + MDFADJUSTPROP_STOP(); +} + + +#define OVERRIDE_SPEEX_ECHO_GET_RESIDUAL +void speex_echo_get_residual( + SpeexEchoState * restrict st, + float * restrict residual_echo, + int len +) +{ + register int i; + register float leak2, leake; + register int N; + register float * restrict window; + register float * restrict last_y; + register float * restrict y; + + SPEEXECHOGETRESIDUAL_START(); + + window = st->window; + last_y = st->last_y; + y = st->y; + N = st->window_size; + + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOGETRESIDUAL) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for (i=0;i<N;i++) + { y[i] = window[i] * last_y[i]; + } +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOGETRESIDUAL) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + spx_fft(st->fft_table, st->y, st->Y); + power_spectrum(st->Y, residual_echo, N); + + leake = st->leak_estimate; + leak2 = fmux(leake > .5, 1, 2 * leake); + N = st->frame_size; + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOGETRESIDUAL) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<N ; ++i ) + { residual_echo[i] *= leak2; + } +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOGETRESIDUAL) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + residual_echo[N] *= leak2; + +#ifndef NO_REMARK + (void)len; +#endif + + SPEEXECHOGETRESIDUAL_STOP(); +} +#endif + + +void mdf_preemph( + SpeexEchoState * restrict st, + spx_word16_t * restrict x, + const spx_int16_t * restrict far_end, + int framesize +) +{ + register spx_word16_t preemph = st->preemph; + register spx_word16_t memX = st->memX; + register spx_word16_t memD = st->memD; + register spx_word16_t * restrict input = st->input; + register int i; +#ifdef FIXED_POINT + register int saturated = st->saturated; +#endif + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<framesize ; ++i ) + { + register spx_int16_t far_endi = far_end[i]; + register spx_word32_t tmp32; + register spx_word16_t inputi = input[i]; + + tmp32 = SUB32(EXTEND32(far_endi), EXTEND32(MULT16_16_P15(preemph,memX))); + +#ifdef FIXED_POINT + saturated = mux(iabs(tmp32) > 32767, M+1, saturated); + tmp32 = iclipi(tmp32,32767); +#endif + + x[i] = EXTRACT16(tmp32); + memX = far_endi; + tmp32 = SUB32(EXTEND32(inputi), EXTEND32(MULT16_16_P15(preemph, memD))); + +#ifdef FIXED_POINT + saturated = mux( ((tmp32 > 32767) && (saturated == 0)), 1, + mux( ((tmp32 <-32767) && (saturated == 0)), 1, saturated )); + tmp32 = iclipi(tmp32,32767); +#endif + memD = inputi; + input[i] = tmp32; + } +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + st->memD = memD; + st->memX = memX; + +#ifdef FIXED_POINT + st->saturated = saturated; +#endif +} + +void mdf_sub( + spx_word16_t * restrict dest, + const spx_word16_t * restrict src1, + const spx_word16_t * restrict src2, + int framesize +) +{ + register int i; + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + +#ifdef FIXED_POINT + for ( i=0,framesize<<=1 ; i<framesize ; i+=4 ) + { register int src1i, src2i, desti; + + src1i = ld32d(src1,i); + src2i = ld32d(src2,i); + desti = dspidualsub(src1i,src2i); + st32d(i, dest, desti); + } +#else + for ( i=0 ; i<framesize ; ++i ) + { dest[i] = src1[i] - src2[i]; + } +#endif + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif +} + +void mdf_sub_int( + spx_word16_t * restrict dest, + const spx_int16_t * restrict src1, + const spx_int16_t * restrict src2, + int framesize +) +{ + register int i, j; + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + +#ifdef FIXED_POINT + for ( i=0,framesize<<=1 ; i<framesize ; i+=4 ) + { register int src1i, src2i, desti; + + src1i = ld32d(src1,i); + src2i = ld32d(src2,i); + desti = dspidualsub(src1i,src2i); + st32d(i, dest, desti); + } +#else + for ( i=0,j=0 ; i<framesize ; i+=2,++j ) + { register int src1i, src2i, desti; + + + src1i = ld32d(src1,j); + src2i = ld32d(src2,j); + desti = dspidualsub(src1i,src2i); + + dest[i] = sex16(desti); + dest[i+1] = asri(16,desti); + } +#endif + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif +} + +void mdf_compute_weight_gradient( + SpeexEchoState * restrict st, + spx_word16_t * restrict X, + int N, + int M +) +{ + register int i, j; + register spx_word32_t * restrict PHI = st->PHI; + + for (j=M-1;j>=0;j--) + { + register spx_word32_t * restrict W = &(st->W[j*N]); + + weighted_spectral_mul_conj( + st->power_1, + FLOAT_SHL(PSEUDOFLOAT(st->prop[j]),-15), + &X[(j+1)*N], + st->E, + st->PHI, + N); +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for (i=0;i<N;i++) + { W[i] = ADD32(W[i],PHI[i]); + } +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + } +} + +void mdf_update_weight( + SpeexEchoState * restrict st, + int N, + int M, + int framesize +) +{ + register int j; + register int cancel_count = st->cancel_count; + register spx_word16_t * restrict wtmp = st->wtmp; +#ifdef FIXED_POINT + register spx_word16_t * restrict wtmp2 = st->wtmp2; + register int i; +#endif + + for ( j=0 ; j<M ; j++ ) + { + register spx_word32_t * restrict W = &(st->W[j*N]); + + if (j==0 || cancel_count%(M-1) == j-1) + { +#ifdef FIXED_POINT + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<N ; i++ ) + wtmp2[i] = EXTRACT16(PSHR32(W[i],NORMALIZE_SCALEDOWN+16)); +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + spx_ifft(st->fft_table, wtmp2, wtmp); + memset(wtmp, 0, framesize * sizeof(spx_word16_t)); + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for (j=framesize; j<N ; ++j) + { wtmp[j]=SHL16(wtmp[j],NORMALIZE_SCALEUP); + } +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + spx_fft(st->fft_table, wtmp, wtmp2); + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for (i=0;i<N;i++) + { W[i] -= SHL32(EXTEND32(wtmp2[i]),16+NORMALIZE_SCALEDOWN-NORMALIZE_SCALEUP-1); + } +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + +#else + spx_ifft(st->fft_table, W, wtmp); + memset(&wtmp[framesize], 0, (N-framesize) * sizeof(spx_word16_t)); + spx_fft(st->fft_table, wtmp, W); +#endif + } + } +} + +#ifdef TWO_PATH +// first four parameters is passed by registers +// generate faster performance with 4 parameters functions +spx_word32_t mdf_update_foreground( + SpeexEchoState * restrict st, + spx_word32_t Dbf, + spx_word32_t Sff, + spx_word32_t See +) +{ + register spx_word32_t Davg1 = st->Davg1; + register spx_word32_t Davg2 = st->Davg2; + register spx_word32_t Dvar1 = st->Dvar1; + register spx_word32_t Dvar2 = st->Dvar2; + register spx_word16_t * restrict input = st->input; + register int framesize = st->frame_size; + register spx_word16_t * restrict xx = st->x + framesize; + register spx_word16_t * restrict y = st->y + framesize; + register spx_word16_t * restrict ee = st->e + framesize; + register int update_foreground; + register int i; + register int N = st->window_size; + register int M = st->M; + +#ifdef FIXED_POINT + register spx_word32_t sc0 = SUB32(Sff,See); + register spx_float_t sc1 = FLOAT_MUL32U(Sff,Dbf); + + Davg1 = ADD32(MULT16_32_Q15(QCONST16(.6f,15),Davg1), MULT16_32_Q15(QCONST16(.4f,15),sc0)); + Davg2 = ADD32(MULT16_32_Q15(QCONST16(.85f,15),Davg2), MULT16_32_Q15(QCONST16(.15f,15),sc0)); + Dvar1 = FLOAT_ADD( + FLOAT_MULT(VAR1_SMOOTH,Dvar1), + FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.4f,15),Sff), + MULT16_32_Q15(QCONST16(.4f,15),Dbf))); + Dvar2 = FLOAT_ADD( + FLOAT_MULT(VAR2_SMOOTH,Dvar2), + FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.15f,15),Sff), + MULT16_32_Q15(QCONST16(.15f,15),Dbf))); +#else + register spx_word32_t sc0 = Sff - See; + register spx_word32_t sc1 = Sff * Dbf; + + Davg1 = .6*Davg1 + .4*sc0; + Davg2 = .85*Davg2 + .15*sc0; + Dvar1 = VAR1_SMOOTH*Dvar1 + .16*sc1; + Dvar2 = VAR2_SMOOTH*Dvar2 + .0225*sc1; +#endif + + update_foreground = + mux( FLOAT_GT(FLOAT_MUL32U(sc0, VABS(sc0)), sc1), 1, + mux( FLOAT_GT(FLOAT_MUL32U(Davg1, VABS(Davg1)), FLOAT_MULT(VAR1_UPDATE,(Dvar1))), 1, + mux( FLOAT_GT(FLOAT_MUL32U(Davg2, VABS(Davg2)), FLOAT_MULT(VAR2_UPDATE,(Dvar2))), 1, 0))); + + if ( update_foreground ) + { + register spx_word16_t * restrict windowf = st->window + framesize; + register spx_word16_t * restrict window = st->window; + + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; + + memcpy(st->foreground, st->W, N*M*sizeof(spx_word32_t)); + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<framesize ; ++i) + { register spx_word16_t wi = window[i]; + register spx_word16_t wfi = windowf[i]; + register spx_word16_t ei = ee[i]; + register spx_word16_t yi = y[i]; + + ee[i] = MULT16_16_Q15(wfi,ei) + MULT16_16_Q15(wi,yi); + } +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + } else + { + register int reset_background; + + reset_background = + mux( FLOAT_GT(FLOAT_MUL32U(-(sc0),VABS(sc0)), FLOAT_MULT(VAR_BACKTRACK,sc1)), 1, + mux( FLOAT_GT(FLOAT_MUL32U(-(Davg1), VABS(Davg1)), FLOAT_MULT(VAR_BACKTRACK,Dvar1)), 1, + mux( FLOAT_GT(FLOAT_MUL32U(-(Davg2), VABS(Davg2)), FLOAT_MULT(VAR_BACKTRACK,Dvar2)), 1, 0))); + + if ( reset_background ) + { + memcpy(st->W, st->foreground, N*M*sizeof(spx_word32_t)); + memcpy(y, ee, framesize * sizeof(spx_word16_t)); + mdf_sub(xx,input,y,framesize); + See = Sff; + st->Davg1 = st->Davg2 = 0; + st->Dvar1 = st->Dvar2 = FLOAT_ZERO; + } else + { + st->Davg1 = Davg1; + st->Davg2 = Davg2; + st->Dvar1 = Dvar1; + st->Dvar2 = Dvar2; + } + } + + return See; +} +#endif + +void mdf_compute_error_signal( + SpeexEchoState * restrict st, + const spx_int16_t * restrict in, + spx_int16_t * restrict out, + int framesize +) +{ + register spx_word16_t preemph = st->preemph; + register spx_word16_t memE = st->memE; + register int saturated = st->saturated; + register spx_word16_t * restrict e = st->e; + register spx_word16_t * restrict ee = st->e + framesize; + register spx_word16_t * restrict input = st->input; + register spx_word16_t * restrict xx = st->x + framesize; + register int i; + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<framesize ; ++i ) + { + register spx_word32_t tmp_out; + register spx_int16_t ini = in[i]; + register int flg; + +#ifdef FIXED_POINT + +#ifdef TWO_PATH + tmp_out = SUB32(EXTEND32(input[i]), EXTEND32(ee[i])); + tmp_out = iclipi(tmp_out,32767); +#else + tmp_out = SUB32(EXTEND32(input[i]), EXTEND32(y[i])); + tmp_out = iclipi(tmp_out,32767); +#endif + +#else +#ifdef TWO_PATH + tmp_out = SUB32(EXTEND32(input[i]), EXTEND32(ee[i])); +#else + tmp_out = SUB32(EXTEND32(input[i]), EXTEND32(y[i])); +#endif + tmp_out = + fmux( tmp_out > 32767, 32767, + fmux( tmp_out < -32768, -32768, tmp_out)); +#endif + + tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(preemph,memE))); + flg = iabs(ini) >= 32000; + tmp_out = VMUX( flg, 0, tmp_out); + saturated = mux( flg && (saturated == 0), 1, saturated); + + out[i] = (spx_int16_t)tmp_out; + memE = tmp_out; + } +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + st->memE = memE; + st->saturated = saturated; + memset(e, 0, framesize * sizeof(spx_word16_t)); + memcpy(ee, xx, framesize * sizeof(spx_word16_t)); +} + +inline int mdf_check( + SpeexEchoState * restrict st, + spx_int16_t * out, + spx_word32_t Syy, + spx_word32_t Sxx, + spx_word32_t See, + spx_word32_t Sff, + spx_word32_t Sdd +) +{ + register int N = st->window_size; + register spx_word32_t N1e9 = N * 1e9; + register int screwed_up = st->screwed_up; + register int framesize = st->frame_size; + + if (!(Syy>=0 && Sxx>=0 && See >= 0) +#ifndef FIXED_POINT + || !(Sff < N1e9 && Syy < N1e9 && Sxx < N1e9 ) +#endif + ) + { + screwed_up += 50; + memset(out, 0, framesize * sizeof(spx_int16_t)); + + } else + { screwed_up = mux( SHR32(Sff, 2) > ADD32(Sdd, SHR32(MULT16_16(N, 10000),6)), screwed_up+1, 0); + } + + st->screwed_up = screwed_up; + + return screwed_up; +} + +void mdf_smooth( + spx_word32_t * restrict power, + spx_word32_t * restrict Xf, + int framesize, + int M +) +{ + register spx_word16_t ss, ss_1, pf, xff; + register int j; + +#ifdef FIXED_POINT + ss=DIV32_16(11469,M); + ss_1 = SUB16(32767,ss); +#else + ss=.35/M; + ss_1 = 1-ss; +#endif + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( j=0 ; j<framesize ; ++j ) + { register spx_word32_t pi = power[j]; + register spx_word32_t xfi = Xf[j]; + + power[j] = MULT16_32_Q15(ss_1,pi) + 1 + MULT16_32_Q15(ss,xfi); + } +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + pf = power[framesize]; + xff = Xf[framesize]; + power[framesize] = MULT16_32_Q15(ss_1,pf) + 1 + MULT16_32_Q15(ss,xff); +} + +void mdf_compute_filtered_spectra_crosscorrelations( + SpeexEchoState * restrict st, + spx_word32_t Syy, + spx_word32_t See, + int framesize +) +{ + register spx_float_t Pey = FLOAT_ONE; + register spx_float_t Pyy = FLOAT_ONE; + register spx_word16_t spec_average = st->spec_average; + register spx_word32_t * restrict pRf = st->Rf; + register spx_word32_t * restrict pYf = st->Yf; + register spx_word32_t * restrict pEh = st->Eh; + register spx_word32_t * restrict pYh = st->Yh; + register spx_word16_t beta0 = st->beta0; + register spx_word16_t beta_max = st->beta_max; + register spx_float_t alpha, alpha_1; + register spx_word32_t tmp32, tmpx; + register spx_float_t sPey = st->Pey; + register spx_float_t sPyy = st->Pyy; + register spx_float_t tmp; + register spx_word16_t leak_estimate; + register int j; + register spx_float_t Eh, Yh; + register spx_word32_t _Ehj, _Rfj, _Yfj, _Yhj; + +#ifdef FIXED_POINT + register spx_word16_t spec_average1 = SUB16(32767,spec_average); +#else + register spx_word16_t spec_average1 = 1 - spec_average; +#endif + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for (j=framesize; j>0 ; --j) + { + _Ehj = pEh[j]; + _Rfj = pRf[j]; + _Yfj = pYf[j]; + _Yhj = pYh[j]; + + Eh = PSEUDOFLOAT(_Rfj - _Ehj); + Yh = PSEUDOFLOAT(_Yfj - _Yhj); + + Pey = FLOAT_ADD(Pey,FLOAT_MULT(Eh,Yh)); + Pyy = FLOAT_ADD(Pyy,FLOAT_MULT(Yh,Yh)); + + pEh[j] = MAC16_32_Q15(MULT16_32_Q15(spec_average1, _Ehj), spec_average, _Rfj); + pYh[j] = MAC16_32_Q15(MULT16_32_Q15(spec_average1, _Yhj), spec_average, _Yfj); + } +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + _Ehj = pEh[0]; + _Rfj = pRf[0]; + _Yfj = pYf[0]; + _Yhj = pYh[0]; + + Eh = PSEUDOFLOAT(_Rfj - _Ehj); + Yh = PSEUDOFLOAT(_Yfj - _Yhj); + + Pey = FLOAT_ADD(Pey,FLOAT_MULT(Eh,Yh)); + Pyy = FLOAT_ADD(Pyy,FLOAT_MULT(Yh,Yh)); + + pEh[0] = MAC16_32_Q15(MULT16_32_Q15(spec_average1, _Ehj), spec_average, _Rfj); + pYh[0] = MAC16_32_Q15(MULT16_32_Q15(spec_average1, _Yhj), spec_average, _Yfj); + + Pyy = FLOAT_SQRT(Pyy); + Pey = FLOAT_DIVU(Pey,Pyy); + + tmp32 = MULT16_32_Q15(beta0,Syy); + tmpx = MULT16_32_Q15(beta_max,See); + tmp32 = VMUX(tmp32 > tmpx, tmpx, tmp32); + alpha = FLOAT_DIV32(tmp32, See); + alpha_1 = FLOAT_SUB(FLOAT_ONE, alpha); + + sPey = FLOAT_ADD(FLOAT_MULT(alpha_1,sPey) , FLOAT_MULT(alpha,Pey)); + sPyy = FLOAT_ADD(FLOAT_MULT(alpha_1,sPyy) , FLOAT_MULT(alpha,Pyy)); + tmp = FLOAT_MULT(MIN_LEAK,sPyy); + +#ifndef FIXED_POINT + sPyy = VMUX(FLOAT_LT(sPyy, FLOAT_ONE), FLOAT_ONE, sPyy); + sPey = VMUX(FLOAT_LT(sPey, tmp), tmp, sPey); + sPey = VMUX(FLOAT_LT(sPey, sPyy), sPey, sPyy); +#else + sPyy = FLOAT_LT(sPyy, FLOAT_ONE) ? FLOAT_ONE : sPyy; + sPey = FLOAT_LT(sPey, tmp) ? tmp : sPey; + sPey = FLOAT_LT(sPey, sPyy) ? sPey : sPyy; +#endif + + leak_estimate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIVU(sPey, sPyy),14)); + + leak_estimate = VMUX( leak_estimate > 16383, 32767, SHL16(leak_estimate,1)); + st->Pey = sPey; + st->Pyy = sPyy; + st->leak_estimate = leak_estimate; +} + +inline spx_word16_t mdf_compute_RER( + spx_word32_t See, + spx_word32_t Syy, + spx_word32_t Sey, + spx_word32_t Sxx, + spx_word16_t leake +) +{ + register spx_word16_t RER; + +#ifdef FIXED_POINT + register spx_word32_t tmp32; + register spx_word32_t tmp; + spx_float_t bound = PSEUDOFLOAT(Sey); + + tmp32 = MULT16_32_Q15(leake,Syy); + tmp32 = ADD32(SHR32(Sxx,13), ADD32(tmp32, SHL32(tmp32,1))); + + bound = FLOAT_DIVU(FLOAT_MULT(bound, bound), PSEUDOFLOAT(ADD32(1,Syy))); + tmp = FLOAT_EXTRACT32(bound); + tmp32 = imux( FLOAT_GT(bound, PSEUDOFLOAT(See)), See, + imux( tmp32 < tmp, tmp, tmp32)); + + tmp = SHR32(See,1); + tmp32 = imux(tmp32 > tmp, tmp, tmp32); + RER = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32,See),15)); +#else + register spx_word32_t r0; + + r0 = (Sey * Sey)/(1 + See * Syy); + + RER = (.0001*Sxx + 3.* MULT16_32_Q15(leake,Syy)) / See; + RER = fmux( RER < r0, r0, RER); + RER = fmux( RER > .5, .5, RER); +#endif + + return RER; +} + +void mdf_adapt( + SpeexEchoState * restrict st, + spx_word16_t RER, + spx_word32_t Syy, + spx_word32_t See, + spx_word32_t Sxx +) +{ + register spx_float_t * restrict power_1 = st->power_1; + register spx_word32_t * restrict power = st->power; + register int adapted = st->adapted; + register spx_word32_t sum_adapt = st->sum_adapt; + register spx_word16_t leake = st->leak_estimate; + register int framesize = st->frame_size; + register int i; + register int M = st->M; + + adapted = mux( !adapted && sum_adapt > QCONST32(M,15) && + MULT16_32_Q15(leake,Syy) > MULT16_32_Q15(QCONST16(.03f,15),Syy), 1, adapted); + + if ( adapted ) + { register spx_word32_t * restrict Yf = st->Yf; + register spx_word32_t * restrict Rf = st->Rf; + register spx_word32_t r, e, e2; + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<framesize ; ++i ) + { + r = SHL32(Yf[i],3); + r = MULT16_32_Q15(leake,r); + e = SHL32(Rf[i],3)+1; + +#ifdef FIXED_POINT + e2 = SHR32(e,1); + r = mux( r > e2, e2, r); +#else + e2 = e * .5; + r = fmux( r > e2, e2, r); +#endif + + r = MULT16_32_Q15(QCONST16(.7,15),r) + + MULT16_32_Q15(QCONST16(.3,15),(spx_word32_t)(MULT16_32_Q15(RER,e))); + + power_1[i] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,power[i]+10)),WEIGHT_SHIFT+16); + } +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + r = SHL32(Yf[framesize],3); + r = MULT16_32_Q15(leake,r); + e = SHL32(Rf[framesize],3)+1; + +#ifdef FIXED_POINT + e2 = SHR32(e,1); + r = mux( r > e2, e2, r); +#else + e2 = e * .5; + r = fmux( r > e2, e2, r); +#endif + + r = MULT16_32_Q15(QCONST16(.7,15),r) + + MULT16_32_Q15(QCONST16(.3,15),(spx_word32_t)(MULT16_32_Q15(RER,e))); + + power_1[framesize] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,power[framesize]+10)),WEIGHT_SHIFT+16); + + } else + { + register spx_word16_t adapt_rate=0; + register int N = st->window_size; + + if ( Sxx > SHR32(MULT16_16(N, 1000),6) ) + { register spx_word32_t tmp32, tmp32q; + + tmp32 = MULT16_32_Q15(QCONST16(.25f, 15), Sxx); +#ifdef FIXED_POINT + tmp32q = SHR32(See,2); + tmp32 = mux(tmp32 > tmp32q, tmp32q, tmp32); +#else + tmp32q = 0.25 * See; + tmp32 = fmux(tmp32 > tmp32q, tmp32q, tmp32); +#endif + adapt_rate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32, See),15)); + } + +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for (i=0;i<framesize;i++) + power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(power[i],10)),WEIGHT_SHIFT+1); +#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + power_1[framesize] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(power[framesize],10)),WEIGHT_SHIFT+1); + sum_adapt = ADD32(sum_adapt,adapt_rate); + } + + st->sum_adapt = sum_adapt; + st->adapted = adapted; +} + +#define OVERRIDE_ECHO_CANCELLATION +void speex_echo_cancellation( + SpeexEchoState * restrict st, + const spx_int16_t * restrict in, + const spx_int16_t * restrict far_end, + spx_int16_t * restrict out +) +{ + register int framesize = st->frame_size; + register spx_word16_t * restrict x = st->x; + register spx_word16_t * restrict xx = st->x + framesize; + register spx_word16_t * restrict yy = st->y + framesize; + register spx_word16_t * restrict ee = st->e + framesize; + register spx_word32_t Syy, See, Sxx, Sdd, Sff; + register spx_word16_t RER; + register spx_word32_t Sey; + register int j; + register int N,M; +#ifdef TWO_PATH + register spx_word32_t Dbf; +#endif + + N = st->window_size; + M = st->M; + st->cancel_count++; + + filter_dc_notch16(in, st->notch_radius, st->input, framesize, st->notch_mem); + mdf_preemph(st, xx, far_end, framesize); + + { + + register spx_word16_t * restrict X = st->X; + + for ( j=M-1 ; j>=0 ; j-- ) + { register spx_word16_t * restrict Xdes = &(X[(j+1)*N]); + register spx_word16_t * restrict Xsrc = &(X[j*N]); + + memcpy(Xdes, Xsrc, N * sizeof(spx_word16_t)); + } + + spx_fft(st->fft_table, x, X); + memcpy(st->last_y, st->x, N * sizeof(spx_word16_t)); + Sxx = mdf_inner_prod(xx, xx, framesize); + memcpy(x, xx, framesize * sizeof(spx_word16_t)); + +#ifdef TWO_PATH + spectral_mul_accum(st->X, st->foreground, st->Y, N, M); + spx_ifft(st->fft_table, st->Y, st->e); + mdf_sub(xx, st->input, ee, framesize); + Sff = mdf_inner_prod(xx, xx, framesize); +#endif + + mdf_adjust_prop (st->W, N, M, st->prop); + + if (st->saturated == 0) + { mdf_compute_weight_gradient(st, X, N, M); + } else + { st->saturated--; + } + } + + mdf_update_weight(st, N, M, framesize); + spectral_mul_accum(st->X, st->W, st->Y, N, M); + spx_ifft(st->fft_table, st->Y, st->y); + +#ifdef TWO_PATH + mdf_sub(xx, ee, yy, framesize); + Dbf = 10+mdf_inner_prod(xx, xx, framesize); +#endif + + mdf_sub(xx, st->input, yy, framesize); + See = mdf_inner_prod(xx, xx, framesize); + +#ifndef TWO_PATH + Sff = See; +#else + See = mdf_update_foreground(st,Dbf,Sff,See); +#endif + + + mdf_compute_error_signal(st, in, out, framesize); + Sey = mdf_inner_prod(ee, yy, framesize); + Syy = mdf_inner_prod(yy, yy, framesize); + Sdd = mdf_inner_prod(st->input, st->input, framesize); + + if ( mdf_check(st,out,Syy,Sxx,See,Sff,Sdd) >= 50 ) + { speex_warning("The echo canceller started acting funny and got slapped (reset). It swears it will behave now."); + speex_echo_state_reset(st); + return; + } + + See = MAX32(See, SHR32(MULT16_16(N, 100),6)); + spx_fft(st->fft_table, st->e, st->E); + memset(st->y, 0, framesize * sizeof(spx_word16_t)); + spx_fft(st->fft_table, st->y, st->Y); + power_spectrum(st->E, st->Rf, N); + power_spectrum(st->Y, st->Yf, N); + power_spectrum(st->X, st->Xf, N); + + mdf_smooth(st->power,st->Xf,framesize, M); + mdf_compute_filtered_spectra_crosscorrelations(st,Syy,See,framesize); + RER = mdf_compute_RER(See,Syy,Sey,Sxx,st->leak_estimate); + mdf_adapt(st, RER, Syy, See, Sxx); + + if ( st->adapted ) + { register spx_word16_t * restrict last_yy = st->last_y + framesize; + + memcpy(st->last_y, last_yy, framesize * sizeof(spx_word16_t)); + mdf_sub_int(last_yy, in, out, framesize); + + } +} + + + diff --git a/src/libs/speexdsp/tmv/misc_tm.h b/src/libs/speexdsp/tmv/misc_tm.h new file mode 100644 index 00000000..6dd12ed9 --- /dev/null +++ b/src/libs/speexdsp/tmv/misc_tm.h @@ -0,0 +1,92 @@ +/* Copyright (C) 2007 Hong Zhiqian */ +/** + @file misc_tm.h + @author Hong Zhiqian + @brief Various compatibility routines for Speex (TriMedia version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#include <tmml.h> + + +#if TM_PROFILE +int __profile_begin; +int __profile_end; +#endif + +#define OVERRIDE_SPEEX_ALLOC +void *speex_alloc (int size) +{ + void *ptr; + + if ( tmmlMalloc(0, size, (pVoid*)&ptr, tmmlMallocCacheAligned | tmmlMallocCleared) != TM_OK ) + { return NULL; + } + + return ptr; +} + + +#define OVERRIDE_SPEEX_ALLOC_SCRATCH +void *speex_alloc_scratch (int size) +{ + void *ptr; + + if ( tmmlMalloc(0, size, (pVoid*)&ptr, tmmlMallocCacheAligned | tmmlMallocCleared) != TM_OK ) + { return NULL; + } + + return ptr; +} + + +#define OVERRIDE_SPEEX_REALLOC +void *speex_realloc (void *ptr, int size) +{ + if ( tmmlRealloc(0, size, (pVoid)ptr, (pVoid*)&ptr, tmmlMallocCacheAligned | tmmlMallocCleared) != TM_OK ) + { return NULL; + } + + return ptr; +} + + +#define OVERRIDE_SPEEX_FREE +void speex_free (void *ptr) +{ + tmmlFree(ptr); +} + + +#define OVERRIDE_SPEEX_FREE_SCRATCH +void speex_free_scratch (void *ptr) +{ + tmmlFree(ptr); +} + diff --git a/src/libs/speexdsp/tmv/preprocess_tm.h b/src/libs/speexdsp/tmv/preprocess_tm.h new file mode 100644 index 00000000..16e02123 --- /dev/null +++ b/src/libs/speexdsp/tmv/preprocess_tm.h @@ -0,0 +1,1135 @@ +/* Copyright (C) 2007 Hong Zhiqian */ +/** + @file preprocess_tm.h + @author Hong Zhiqian + @brief Various compatibility routines for Speex (TriMedia version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#include <ops/custom_defs.h> +#include "profile_tm.h" + +#ifdef FIXED_POINT +#define OVERRIDE_PREPROCESS_ANALYSIS +static void preprocess_analysis(SpeexPreprocessState * restrict st, spx_int16_t * restrict x) +{ + register int i, j, framesize = st->frame_size; + register int N = st->ps_size; + register int N3 = 2*N - framesize; + register int N4 = framesize - N3; + register int * restrict ps = st->ps; + register int * restrict frame; + register int * restrict inbuf; + register int * restrict ptr; + register int max_val; + + frame = (int*)(st->frame); + inbuf = (int*)(st->inbuf); + ptr = (int*)(st->frame+N3); + + TMDEBUG_ALIGNMEM(x); + TMDEBUG_ALIGNMEM(frame); + TMDEBUG_ALIGNMEM(inbuf); + + PREPROCESSANAYLSIS_START(); + + N3 >>= 1; + framesize >>= 1; + max_val = 0; + + for ( i=0,j=0 ; i<N3 ; i+=2,j+=8 ) + { register int r1, r2; + + r1 = ld32x(inbuf,i); + r2 = ld32x(inbuf,i+1); + + st32d(j, frame, r1); + st32d(j+4, frame, r2); + } + + for ( i=0,j=0 ; i<framesize ; i+=2,j+=8 ) + { register int r1, r2; + + r1 = ld32x(x, i); + r2 = ld32x(x, i+1); + + st32d(j, ptr, r1); + st32d(j+4,ptr, r2); + } + + for ( i=0,j=0,ptr=(int*)(x+N4) ; i<N3 ; i+=2,j+=8 ) + { register int r1, r2; + + r1 = ld32x(ptr, i); + r2 = ld32x(ptr, i+1); + + st32d(j, inbuf, r1); + st32d(j+4,inbuf, r2); + } +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unroll=2 +#pragma TCS_unrollexact=1 +#endif + for ( i=0,j=0,ptr=(int*)st->window ; i<N ; ++i,j+=4 ) + { register int f10, w10, r0, r1; + + f10 = ld32x(frame, i); + w10 = ld32x(ptr, i); + + r0 = (sex16(f10) * sex16(w10)) >> 15; + r1 = (asri(16,f10) * asri(16,w10)) >> 15; + + max_val = imax(iabs(sex16(r0)), max_val); + max_val = imax(iabs(sex16(r1)), max_val); + + r0 = pack16lsb(r1, r0); + st32d(j, frame, r0); + } +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + max_val = 14 - spx_ilog2(max_val); + st->frame_shift = max_val; + + if ( max_val != 0 ) + { +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0,j=0 ; i<N ; ++i,j+=4 ) + { register int f10; + + f10 = ld32x(frame, i); + f10 = dualasl(f10, max_val); + st32d(j, frame, f10); + + } +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + } + + spx_fft(st->fft_lookup, st->frame, st->ft); + power_spectrum(st->ft, ps, N << 1); + +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0,ptr=(int*)st->ps,max_val<<=1,j=((1<<((max_val))>>1)) ;i<N ; ++i ) + { + ps[i] = (ps[i] + j) >> max_val; + } +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + filterbank_compute_bank32(st->bank, ps, ps+N); + + PREPROCESSANAYLSIS_STOP(); +} + +#define _MULT16_32_Q15(a,b,c) ADD32(MULT16_16((a),(b)), SHR(MULT16_16((a),(c)),15)) + +#define OVERRIDE_UPDATE_NOISE_PROB +static void update_noise_prob(SpeexPreprocessState * restrict st) +{ + register int i; + register int min_range, nb_adapt; + register int N = st->ps_size; + register int * restrict Smin = (int*)st->Smin; + register int * restrict Stmp = (int*)st->Stmp; + register int * restrict S = (int*)st->S; + + UPDATENOISEPROB_START(); + + { + register int psi_lsb, psi_msb, ips_lsb, ips_msb, psii_lsb, psii_msb; + register int psiii_lsb, psiii_msb; + register int q8, q05, q2, q1; + register int *ps = (int*)st->ps; + register int si_lsb, si_msb, sii_lsb, sii_msb; + + q8 = QCONST16(.8f,15); + q05 = QCONST16(.05f,15); + q2 = QCONST16(.2f,15); + q1 = QCONST16(.1f,15); + + ips_lsb = ps[0]; + psi_lsb = ps[1]; + si_lsb = S[0]; + ips_msb = ips_lsb >> 15; + psi_msb = psi_lsb >> 15; + si_msb = si_lsb >> 15; + + ips_lsb &= 0x00007fff; + psi_lsb &= 0x00007fff; + si_lsb &= 0x00007fff; + + S[0] = _MULT16_32_Q15(q8,si_msb,si_lsb) + _MULT16_32_Q15(q2,ips_msb,ips_lsb); + + for ( i=1 ; i<N-1 ; i+=2 ) + { + psii_lsb = ps[i+1]; + si_lsb = S[i]; + + psii_msb = psii_lsb >> 15; + si_msb = si_lsb >> 15; + si_lsb &= 0x00007fff; + psii_lsb &= 0x00007fff; + + S[i]= _MULT16_32_Q15(q8,si_msb,si_lsb) + + _MULT16_32_Q15(q05,ips_msb,ips_lsb) + + _MULT16_32_Q15(q1,psi_msb,psi_lsb) + + _MULT16_32_Q15(q05,psii_msb,psii_lsb); + + psiii_lsb = ps[i+2]; + sii_lsb = S[i+1]; + + sii_msb = sii_lsb >> 15; + psiii_msb= psiii_lsb >> 15; + sii_lsb &= 0x00007fff; + psiii_lsb&= 0x00007fff; + + S[i+1]= _MULT16_32_Q15(q8,sii_msb,sii_lsb) + + _MULT16_32_Q15(q05,psi_msb,psi_lsb) + + _MULT16_32_Q15(q1,psii_msb,psii_lsb) + + _MULT16_32_Q15(q05,psiii_msb,psiii_lsb); + + ips_lsb = psii_lsb; + ips_msb = psii_msb; + psi_lsb = psiii_lsb; + psi_msb = psiii_msb; + } + + S[N-1] = MULT16_32_Q15(q8,S[N-1]) + MULT16_32_Q15(q2,ps[N-1]); + } + + nb_adapt = st->nb_adapt; + + if ( nb_adapt==1 ) + { for ( i=0 ; i<N ; ++i ) + Smin[i] = Stmp[i] = 0; + + } + + min_range = mux(nb_adapt < 100, 15, + mux(nb_adapt < 1000, 50, + mux(nb_adapt < 10000, 150, 300))); + + if ( st->min_count > min_range ) + { + st->min_count = 0; + +#if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB) +#pragma TCS_unroll=2 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<N ; ++i ) + { register int si, stmpi; + + si = S[i]; + stmpi = Stmp[i]; + + Smin[i] = imin(stmpi,si); + Stmp[i] = si; + } +#if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + } else + { + +#if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB) +#pragma TCS_unroll=2 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<N ; ++i ) + { register int si, stmpi, smini; + + si = S[i]; + stmpi = Stmp[i]; + smini = Smin[i]; + + Smin[i] = imin(smini,si); + Stmp[i] = imin(stmpi,si); + } +#if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + } + + + { + register int q4; + register int * restrict update_prob = (int*)st->update_prob; + + q4 = QCONST16(.4f,15); + +#if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<N ; ++i ) + { register int si; + register int smini; + + si = S[i]; + smini = Smin[i]; + update_prob[i] = mux(MULT16_32_Q15(q4,si) > ADD32(smini,20), 1, 0); + } +#if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + } + + UPDATENOISEPROB_STOP(); +} + +#else + +#define OVERRIDE_PREPROCESS_ANALYSIS +static void preprocess_analysis(SpeexPreprocessState * restrict st, spx_int16_t * restrict x) +{ + register int i; + register int framesize = st->frame_size; + register int N = st->ps_size; + register int N3 = 2*N - framesize; + register int N4 = framesize - N3; + register float * restrict ps = st->ps; + register float * restrict frame = st->frame; + register float * restrict inbuf = st->inbuf; + + PREPROCESSANAYLSIS_START(); + +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<N3 ; ++i ) + { + frame[i] = inbuf[i]; + } +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<framesize ; ++i ) + { frame[N3+i] = x[i]; + } +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0,x+=N4 ; i<N3 ; ++i ) + { inbuf[i] = x[i]; + } +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + inbuf = st->window; + +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<2*N ; ++i ) + { + frame[i] = frame[i] * inbuf[i]; + } +#if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + spx_fft(st->fft_lookup, frame, st->ft); + power_spectrum(st->ft, ps, N << 1); + filterbank_compute_bank32(st->bank, ps, ps+N); + + PREPROCESSANAYLSIS_STOP(); +} + + +#define OVERRIDE_UPDATE_NOISE_PROB +static void update_noise_prob(SpeexPreprocessState * restrict st) +{ + + register float * restrict S = st->S; + register float * restrict ps = st->ps; + register int N = st->ps_size; + register int min_range; + register int i; + register int nb_adapt; + register float * restrict Smin = st->Smin; + register float * restrict Stmp = st->Stmp; + + UPDATENOISEPROB_START(); + + { + register float ips, psi; + + ips = ps[0]; + psi = ps[1]; + + S[0] = .8f * S[0] + .2f * ips; + + for ( i=1 ; i<N-1 ; i+=2 ) + { + register float psii, psiii; + + psii = ps[i+1]; + psiii = ps[i+2]; + S[i] = .8f * S[i] + .05f * ips + .1f * psi + .05f * psii; + S[i+1] = .8f * S[i+1] + .05f * psi + .1f * psii + .05f * psiii; + ips = psii; + psi = psiii; + } + + S[N-1] = .8f * S[N-1] + .2f * ps[N-1]; + } + + nb_adapt = st->nb_adapt; + + if ( nb_adapt==1 ) + { + for (i=0;i<N;i++) + Smin[i] = st->Stmp[i] = 0; + } + + min_range = mux(nb_adapt < 100, 15, + mux(nb_adapt < 1000, 50, + mux(nb_adapt < 10000, 150, 300))); + + + if ( st->min_count > min_range ) + { + st->min_count = 0; +#if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<N ; ++i ) + { + register float stmpi, si; + + stmpi = Stmp[i]; + si = S[i]; + + Smin[i] = fmin(stmpi,si); + Stmp[i] = si; + } +#if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + } else + { + register float * restrict Smin = st->Smin; + +#if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<N ; ++i ) + { + register float stmpi, si, smini; + + stmpi = Stmp[i]; + si = S[i]; + smini = Smin[i]; + + Smin[i] = fmin(smini,si); + Stmp[i] = fmin(stmpi,si); + } +#if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + } + + { + register int * restrict update_prob = (int*)st->update_prob; + +#if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for (i=0;i<N;i++) + { register float si; + register float smini; + + si = S[i]; + smini = Smin[i]; + update_prob[i] = mux( (.4 * si) > (smini + 20.f), 1, 0); + + } +#if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + } + + UPDATENOISEPROB_STOP(); +} + + +#define OVERRIDE_COMPUTE_GAIN_FLOOR +static void compute_gain_floor( + int noise_suppress, + int effective_echo_suppress, + float * restrict noise, + float * restrict echo, + float * gain_floor, + int len +) +{ + register int i; + register float echo_floor; + register float noise_floor; + + COMPUTEGAINFLOOR_START(); + + noise_floor = exp(.2302585f*noise_suppress); + echo_floor = exp(.2302585f*effective_echo_suppress); + +#if (TM_UNROLL && TM_UNROLL_COMPUTEGAINFLOOR) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for (i=0;i<len;i++) + { register float noisei, echoi; + + noisei = noise[i]; + echoi = echo[i]; + + gain_floor[i] = FRAC_SCALING * sqrt(noise_floor * noisei + echo_floor * echoi) / sqrt(1+noisei+echoi); + + } +#if (TM_UNROLL && TM_UNROLL_COMPUTEGAINFLOOR) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + COMPUTEGAINFLOOR_STOP(); +} + +#endif + +static inline spx_word32_t hypergeom_gain(spx_word32_t xx); +static inline spx_word16_t qcurve(spx_word16_t x); +static void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len); +void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len); + +#ifndef FIXED_POINT +static void speex_compute_agc(SpeexPreprocessState *st, spx_word16_t Pframe, spx_word16_t *ft); +#endif + +void preprocess_residue_echo( + SpeexPreprocessState * restrict st, + int N, + int NM +) +{ + if (st->echo_state) + { + register spx_word32_t * restrict r_echo = st->residual_echo; + register spx_word32_t * restrict e_noise = st->echo_noise; + register int i; + +#ifndef FIXED_POINT + register spx_word32_t r; +#endif + + speex_echo_get_residual(st->echo_state, r_echo, N); + +#ifndef FIXED_POINT + r = r_echo[0]; + if (!(r >=0 && r < N*1e9f) ) + { + memset(r_echo, 0, N * sizeof(spx_word32_t)); + } +#endif + +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for (i=0;i<N;i++) + { register spx_word32_t eni = e_noise[i]; + e_noise[i] = MAX32(MULT16_32_Q15(QCONST16(.6f,15),eni), r_echo[i]); + } +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + filterbank_compute_bank32(st->bank, e_noise, e_noise+N); + + } else + { memset(st->echo_noise, 0, (NM) * sizeof(spx_word32_t)); + } +} + +void preprocess_update_noise( + SpeexPreprocessState * restrict st, + spx_word32_t * restrict ps, + int N +) +{ + register spx_word16_t beta, beta_1; + register int * restrict up = st->update_prob; + register spx_word32_t * restrict noise = st->noise; + register int i; + + beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt)); + beta_1 = Q15_ONE-beta; + +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for (i=0;i<N;i++) + { register spx_word32_t ni = noise[i]; + register spx_word32_t psi = ps[i]; + + if ( !up[i] || psi < PSHR32(ni, NOISE_SHIFT) ) + { noise[i] = MAX32(EXTEND32(0),MULT16_32_Q15(beta_1,ni) + + MULT16_32_Q15(beta,SHL32(psi,NOISE_SHIFT))); + } + } +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + filterbank_compute_bank32(st->bank, noise, noise+N); +} + +void preprocess_compute_SNR( + SpeexPreprocessState * restrict st, + spx_word32_t * restrict ps, + int NM +) +{ + register spx_word32_t * restrict noise = st->noise; + register spx_word32_t * restrict echo = st->echo_noise; + register spx_word32_t * restrict reverb = st->reverb_estimate; + register spx_word16_t * restrict post = st->post; + register spx_word32_t * restrict old_ps = st->old_ps; + register spx_word16_t * restrict prior = st->prior; + register int i; + +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<NM ; i++) + { + register spx_word16_t gamma; + register spx_word32_t tot_noise; + register spx_word16_t posti; + register spx_word32_t opsi; + register spx_word16_t priori; + + tot_noise = ADD32(ADD32(ADD32(EXTEND32(1), PSHR32(noise[i],NOISE_SHIFT)), echo[i]) , reverb[i]); + + posti = SUB16(DIV32_16_Q8(ps[i],tot_noise), QCONST16(1.f,SNR_SHIFT)); + posti = MIN16(posti, QCONST16(100.f,SNR_SHIFT)); + post[i] = posti; + + opsi = old_ps[i]; + + gamma = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.89f,15),SQR16_Q15(DIV32_16_Q15(opsi,ADD32(opsi,tot_noise)))); + + priori = EXTRACT16(PSHR32(ADD32(MULT16_16(gamma,MAX16(0,posti)), MULT16_16(Q15_ONE-gamma,DIV32_16_Q8(opsi,tot_noise))), 15)); + prior[i]=MIN16(priori, QCONST16(100.f,SNR_SHIFT)); + } +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif +} + +spx_word32_t preprocess_smooth_SNR( + SpeexPreprocessState * restrict st, + int N, + int NM +) +{ + register spx_word16_t * restrict zeta = st->zeta; + register spx_word16_t * restrict prior = st->prior; + register spx_word32_t Zframe; + register spx_word16_t iprior, priori; + register int _N = N-1; + register int i; + + iprior = prior[0]; + priori = prior[1]; + zeta[0] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),zeta[0]), MULT16_16(QCONST16(.3f,15),iprior)),15); + +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unroll=2 +#pragma TCS_unrollexact=1 +#endif + for ( i=1 ; i<_N ; i++) + { register spx_word16_t zetai = zeta[i]; + register spx_word16_t priorii = prior[i+1]; + + zeta[i] = PSHR32(ADD32(ADD32(ADD32(MULT16_16(QCONST16(.7f,15),zetai), MULT16_16(QCONST16(.15f,15),priori)), + MULT16_16(QCONST16(.075f,15),iprior)), MULT16_16(QCONST16(.075f,15),priorii)),15); + + iprior = priori; + priori = priorii; + } +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + for (i=_N; i<NM ; i++) + { register spx_word16_t zetai = zeta[i]; + + priori = prior[i]; + zeta[i] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),zetai), MULT16_16(QCONST16(.3f,15),priori)),15); + } + + Zframe = 0; + +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=N ; i<NM ; i++ ) + { Zframe = ADD32(Zframe, EXTEND32(zeta[i])); + } +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + return Zframe; +} + +void preprocess_compute_emgain( + SpeexPreprocessState * restrict st, + spx_word32_t * restrict ps, + spx_word16_t Pframe, + int NM +) +{ + register spx_word16_t * restrict zeta = st->zeta; + register spx_word16_t * restrict prior = st->prior; + register spx_word16_t * restrict gain = st->gain; + register spx_word32_t * restrict old_ps = st->old_ps; + register spx_word16_t * restrict post = st->post; + register spx_word16_t * restrict gain2 = st->gain2; + register int i; + register int N=st->ps_size; + + for ( i=N ; i<NM ; ++i ) + { + register spx_word32_t theta; + register spx_word32_t MM; + register spx_word16_t prior_ratio; + register spx_word16_t P1; + register spx_word16_t q; + +#ifdef FIXED_POINT + register spx_word16_t tmp; +#endif + register spx_word16_t priori = prior[i]; + + prior_ratio = PDIV32_16(SHL32(EXTEND32(priori), 15), ADD16(priori, SHL32(1,SNR_SHIFT))); + theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(post[i]),EXPIN_SHIFT-SNR_SHIFT)); + + MM = hypergeom_gain(theta); + gain[i] = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM))); + old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(gain[i])),ps[i]); + + P1 = QCONST16(.199f,15)+MULT16_16_Q15(QCONST16(.8f,15),qcurve (zeta[i])); + q = Q15_ONE-MULT16_16_Q15(Pframe,P1); + +#ifdef FIXED_POINT + theta = MIN32(theta, EXTEND32(32767)); + tmp = MULT16_16_Q15((SHL32(1,SNR_SHIFT)+priori),EXTRACT16(MIN32(Q15ONE,SHR32(spx_exp(-EXTRACT16(theta)),1)))); + tmp = MIN16(QCONST16(3.,SNR_SHIFT), tmp); + tmp = EXTRACT16(PSHR32(MULT16_16(PDIV32_16(SHL32(EXTEND32(q),8),(Q15_ONE-q)),tmp),8)); + gain2[i]=DIV32_16(SHL32(EXTEND32(32767),SNR_SHIFT), ADD16(256,tmp)); +#else + gain2[i]=1/(1.f + (q/(1.f-q))*(1+priori)*exp(-theta)); +#endif + } + + filterbank_compute_psd16(st->bank,gain2+N, gain2); + filterbank_compute_psd16(st->bank,gain+N, gain); +} + +void preprocess_compute_linear_gain( + SpeexPreprocessState * restrict st, + spx_word32_t * restrict ps, + int N +) +{ + register spx_word16_t * restrict gain_floor = st->gain_floor; + register spx_word16_t * restrict prior = st->prior; + register spx_word16_t * restrict gain = st->gain; + register spx_word32_t * restrict old_ps = st->old_ps; + register spx_word16_t * restrict post = st->post; + register spx_word16_t * restrict gain2 = st->gain2; + register int i; + + filterbank_compute_psd16(st->bank,gain_floor+N,gain_floor); + +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for (i=0;i<N;i++) + { + register spx_word32_t MM; + register spx_word32_t theta; + register spx_word16_t prior_ratio; + register spx_word16_t tmp; + register spx_word16_t p; + register spx_word16_t g; + register spx_word16_t gfi = gain_floor[i]; + + prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(prior[i], SHL32(1,SNR_SHIFT))); + theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(post[i]),EXPIN_SHIFT-SNR_SHIFT)); + MM = hypergeom_gain(theta); + + g = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM))); + p = gain2[i]; + + g = VMUX( MULT16_16_Q15(QCONST16(.333f,15),g) > gain[i], MULT16_16(3,gain[i]), g); + + old_ps[i]= MULT16_32_P15(QCONST16(.2f,15),old_ps[i]) + + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(g)),ps[i]); + + g = VMUX( g < gfi, gfi, g ); + gain[i] = g; + + tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(g),15))) + + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(gfi),15))); + + gain2[i]=SQR16_Q15(tmp); + + /* Use this if you want a log-domain MMSE estimator instead */ + /* gain2[i] = pow(g, p) * pow(gfi,1.f-p);*/ + } +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif +} + + +#if 0 +void preprocess_compute_bark_gain( + SpeexPreprocessState * restrict st, + int N, + int NM +) +{ + register spx_word16_t * restrict gain_floor = st->gain_floor; + register spx_word16_t * restrict gain = st->gain; + register spx_word16_t * restrict gain2 = st->gain2; + register int i; + + for (i=N;i<NM;i++) + { + register spx_word16_t tmp; + register spx_word16_t p = gain2[i]; + register spx_word16_t gaini; + register spx_word16_t gfi = gain_floor[i]; + + gaini = MAX16(gain[i], gfi); + + gain[i] = gaini; + + tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(gaini),15))) + + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(gfi),15))); + + gain2[i]=SQR16_Q15(tmp); + } + + filterbank_compute_psd16(st->bank,gain2+N, gain2); +} +#endif + +void preprocess_apply_gain( + SpeexPreprocessState * restrict st, + int N +) +{ + register spx_word16_t * restrict ft = st->ft; + register spx_word16_t * restrict gain2 = st->gain2; + register int j, i; + + ft[0] = MULT16_16_P15(gain2[0],ft[0]); + + for (i=1,j=1; i<N ; i++,j+=2) + { + register spx_word16_t gain2i = gain2[i]; + register spx_word16_t ftj = ft[j]; + register spx_word16_t ftjj = ft[j+1]; + + ft[j] = MULT16_16_P15(gain2i,ftj); + ft[j+1] = MULT16_16_P15(gain2i,ftjj); + } + + ft[(N<<1)-1] = MULT16_16_P15(gain2[N-1],ft[(N<<1)-1]); +} + +#ifdef FIXED_POINT +void preprocess_scale( + SpeexPreprocessState * restrict st, + int N +) +{ + register spx_word16_t * restrict frame = st->frame; + register int shift = st->frame_shift; + register int i; + register int N2 = N << 1; + +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<N2 ;i++) + { register spx_word16_t framei = frame[i]; + + frame[i] = PSHR16(framei,shift); + } +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif +} + +#else + +void preprocess_apply_agc( + SpeexPreprocessState * restrict st, + int N +) +{ + register spx_word16_t max_sample=0; + register spx_word16_t * restrict frame = st->frame; + register int i; + register int N2 = N << 1; + +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for (i=0;i<N2;i++) + { register spx_word16_t framei = VABS(frame[i]); + + max_sample = VMUX( framei > max_sample, framei, max_sample); + } +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + if ( max_sample > 28000.f ) + { + float damp = 28000.f/max_sample; + +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i< N2 ; i++ ) + { frame[i] *= damp; + } +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + } +} +#endif + + +void preprocess_update( + SpeexPreprocessState * restrict st, + spx_int16_t * restrict x, + int N +) +{ + register spx_word16_t * restrict frame = st->frame; + register spx_word16_t * restrict window = st->window; + register spx_word16_t * restrict outbuf = st->outbuf; + register int framesize = st->frame_size; + register int N2 = N << 1; + register int N3 = N2 - framesize; + register int N4 = (framesize) - N3; + register int i; + +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<N2 ; i++) + { register spx_word16_t fi = frame[i]; + register spx_word16_t wi = window[i]; + + frame[i] = MULT16_16_Q15(fi, wi); + } + for (i=0;i<N3;i++) + { x[i] = outbuf[i] + frame[i]; + } +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + + for ( i=0;i<N4;i++) + { x[N3+i] = frame[N3+i]; + } + + memcpy(outbuf, frame+framesize, (N3) * sizeof(spx_word16_t)); +} + +#define OVERRIDE_SPEEX_PREPROCESS_RUN +int speex_preprocess_run(SpeexPreprocessState * restrict st, spx_int16_t * restrict x) +{ + register int i, N, M, NM; + register spx_word32_t * restrict ps=st->ps; + register spx_word32_t Zframe; + register spx_word16_t Pframe; + + st->nb_adapt++; + st->min_count++; + N = st->ps_size; + M = st->nbands; + NM = N + M; + + preprocess_residue_echo(st, N, NM); + preprocess_analysis(st, x); + update_noise_prob(st); + preprocess_update_noise(st, ps, N); + + if ( st->nb_adapt == 1 ) + { memcpy(st->old_ps, ps, (NM) * sizeof(spx_word32_t)); + } + + preprocess_compute_SNR(st, ps, NM); + Zframe = preprocess_smooth_SNR(st, N, NM); + + + { + register spx_word16_t effective_echo_suppress; + + Pframe = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.899f,15),qcurve(DIV32_16(Zframe,M))); + effective_echo_suppress = EXTRACT16(PSHR32(ADD32(MULT16_16(SUB16(Q15_ONE,Pframe), st->echo_suppress), + MULT16_16(Pframe, st->echo_suppress_active)),15)); + compute_gain_floor(st->noise_suppress, effective_echo_suppress, st->noise+N, st->echo_noise+N, st->gain_floor+N, M); + + } + + preprocess_compute_emgain(st, ps, Pframe, NM); + preprocess_compute_linear_gain(st, ps, N); + + + if (!st->denoise_enabled) + { + register spx_word16_t * restrict gain2 = st->gain2; + +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unroll=4 +#pragma TCS_unrollexact=1 +#endif + for ( i=0 ; i<NM ; i++ ) + { gain2[i] = Q15_ONE; + } +#if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN) +#pragma TCS_unrollexact=0 +#pragma TCS_unroll=0 +#endif + } + + preprocess_apply_gain(st, N); + +#ifndef FIXED_POINT + if (st->agc_enabled) + { speex_compute_agc(st, Pframe, st->ft); + } +#endif + + + spx_ifft(st->fft_lookup, st->ft, st->frame); + +#ifdef FIXED_POINT + preprocess_scale(st, N); +#endif + +#ifndef FIXED_POINT + if ( st->agc_enabled ) + { preprocess_apply_agc(st, N); + } +#endif + + preprocess_update(st, x, N); + + if ( st->vad_enabled ) + { + if (Pframe > st->speech_prob_start || (st->was_speech && Pframe > st->speech_prob_continue)) + { st->was_speech=1; + return 1; + + } else + { st->was_speech=0; + return 0; + } + } else + { return 1; + } +} diff --git a/src/libs/speexdsp/tmv/profile_tm.h b/src/libs/speexdsp/tmv/profile_tm.h new file mode 100644 index 00000000..2ecafb72 --- /dev/null +++ b/src/libs/speexdsp/tmv/profile_tm.h @@ -0,0 +1,407 @@ +/* Copyright (C) 2007 Hong Zhiqian */ +/** + @file profile_tm.h + @author Hong Zhiqian + @brief Various compatibility routines for Speex (TriMedia version) +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/** +* @remarks This file provide some capabilities to measure clock cycles. +* Use this if unable to compile with TriMedia profile options +*/ + +extern int __profile_begin; +extern int __profile_end; + +#if TM_PROFILE +#define PROFILE_START() \ + { \ + __profile_begin = cycles(); \ + } \ + +#define PROFILE_STOP() \ + { \ + __profile_end = cycles(); \ + printf("%s\t%d\n", __FUNCTION__, end - begin); \ + } \ + +#else +#define PROFILE_START() +#define PROFILE_STOP() +#endif + +#if TM_PROFILE_SPXAUTOCORR +#define _SPX_AUTOCORR_START() PROFILE_START() +#define _SPX_AUTOCORR_STOP() PROFILE_STOP() +#else +#define _SPX_AUTOCORR_START() +#define _SPX_AUTOCORR_STOP() +#endif + +#if TM_PROFILE_INNERPROD +#define INNERPROD_START() PROFILE_START() +#define INNERPROD_STOP() PROFILE_STOP() +#else +#define INNERPROD_START() +#define INNERPROD_STOP() +#endif + +#if TM_PROFILE_PITCHXCORR +#define PITCHXCORR_START() PROFILE_START() +#define PITCHXCORR_STOP() PROFILE_STOP() +#else +#define PITCHXCORR_START() +#define PITCHXCORR_STOP() +#endif + +#if TM_PROFILE_COMPUTEPITCHERROR +#define COMPUTEPITCHERROR_START() PROFILE_START() +#define COMPUTEPITCHERROR_STOP() PROFILE_STOP() +#else +#define COMPUTEPITCHERROR_START() +#define COMPUTEPITCHERROR_STOP() +#endif + +#if TM_PROFILE_PITCHGAINSEARCH3TAPVQ +#define PITCHGAINSEARCH3TAPVQ_START() PROFILE_START() +#define PITCHGAINSEARCH3TAPVQ_STOP() PROFILE_STOP() +#else +#define PITCHGAINSEARCH3TAPVQ_START() +#define PITCHGAINSEARCH3TAPVQ_STOP() +#endif + +#if TM_PROFILE_OPENLOOPNBESTPITCH +#define OPENLOOPNBESTPITCH_START() PROFILE_START() +#define OPENLOOPNBESTPITCH_STOP() PROFILE_STOP() +#else +#define OPENLOOPNBESTPITCH_START() +#define OPENLOOPNBESTPITCH_STOP() +#endif + + +#if TM_PROFILE_LSP_INTERPOLATE +#define LSPINTERPOLATE_START() PROFILE_START() +#define LSPINTERPOLATE_STOP() PROFILE_STOP() +#else +#define LSPINTERPOLATE_START() +#define LSPINTERPOLATE_STOP() +#endif + +#if TM_PROFILE_CHEBPOLYEVA +#define CHEBPOLYEVA_START() PROFILE_START() +#define CHEBPOLYEVA_STOP() PROFILE_STOP() +#else +#define CHEBPOLYEVA_START() +#define CHEBPOLYEVA_STOP() +#endif + + +#if TM_PROFILE_COMPUTEQUANTWEIGHTS +#define COMPUTEQUANTWEIGHTS_START() PROFILE_START() +#define COMPUTEQUANTWEIGHTS_STOP() PROFILE_STOP() +#else +#define COMPUTEQUANTWEIGHTS_START() +#define COMPUTEQUANTWEIGHTS_STOP() +#endif + +#if TM_PROFILE_LSPQUANT +#define LSPQUANT_START() PROFILE_START() +#define LSPQUANT_STOP() PROFILE_STOP() +#else +#define LSPQUANT_START() +#define LSPQUANT_STOP() +#endif + +#if TM_PROFILE_LSPWEIGHTQUANT +#define LSPWEIGHTQUANT_START() PROFILE_START() +#define LSPWEIGHTQUANT_STOP() PROFILE_STOP() +#else +#define LSPWEIGHTQUANT_START() +#define LSPWEIGHTQUANT_STOP() +#endif + +#if TM_PROFILE_FIRMEM16 +#define FIRMEM16_START() PROFILE_START() +#define FIRMEM16_STOP() PROFILE_STOP() +#else +#define FIRMEM16_START() +#define FIRMEM16_STOP() +#endif + +#if TM_PROFILE_IIRMEM16 +#define IIRMEM16_START() PROFILE_START() +#define IIRMEM16_STOP() PROFILE_STOP() +#else +#define IIRMEM16_START() +#define IIRMEM16_STOP() +#endif + +#if TM_PROFILE_FILTERMEM16 +#define FILTERMEM16_START() PROFILE_START() +#define FILTERMEM16_STOP() PROFILE_STOP() +#else +#define FILTERMEM16_START() +#define FILTERMEM16_STOP() +#endif + +#if TM_PROFILE_COMPUTERMS16 +#define COMPUTERMS16_START() PROFILE_START() +#define COMPUTERMS16_STOP() PROFILE_STOP() +#else +#define COMPUTERMS16_START() +#define COMPUTERMS16_STOP() +#endif + +#if TM_PROFILE_NORMALIZE16 +#define NORMALIZE16_START() PROFILE_START() +#define NORMALIZE16_STOP() PROFILE_STOP() +#else +#define NORMALIZE16_START() +#define NORMALIZE16_STOP() +#endif + +#if TM_PROFILE_BWLPC +#define BWLPC_START() PROFILE_START() +#define BWLPC_STOP() PROFILE_STOP() +#else +#define BWLPC_START() +#define BWLPC_STOP() +#endif + +#if TM_PROFILE_HIGHPASS +#define HIGHPASS_START() PROFILE_START() +#define HIGHPASS_STOP() PROFILE_STOP() +#else +#define HIGHPASS_START() +#define HIGHPASS_STOP() +#endif + +#if TM_PROFILE_SIGNALMUL +#define SIGNALMUL_START() PROFILE_START() +#define SIGNALMUL_STOP() PROFILE_STOP() +#else +#define SIGNALMUL_START() +#define SIGNALMUL_STOP() +#endif + +#if TM_PROFILE_SIGNALDIV +#define SIGNALDIV_START() PROFILE_START() +#define SIGNALDIV_STOP() PROFILE_STOP() +#else +#define SIGNALDIV_START() +#define SIGNALDIV_STOP() +#endif + +#if TM_PROFILE_COMPUTEIMPULSERESPONSE +#define COMPUTEIMPULSERESPONSE_START() PROFILE_START() +#define COMPUTEIMPULSERESPONSE_STOP() PROFILE_STOP() +#else +#define COMPUTEIMPULSERESPONSE_START() +#define COMPUTEIMPULSERESPONSE_STOP() +#endif + +#if TM_PROFILE_COMPUTEWEIGHTEDCODEBOOK +#define COMPUTEWEIGHTEDCODEBOOK_START() PROFILE_START() +#define COMPUTEWEIGHTEDCODEBOOK_STOP() PROFILE_STOP() +#else +#define COMPUTEWEIGHTEDCODEBOOK_START() +#define COMPUTEWEIGHTEDCODEBOOK_STOP() +#endif + +#if TM_PROFILE_TARGETUPDATE +#define TARGETUPDATE_START() PROFILE_START() +#define TARGETUPDATE_STOP() PROFILE_STOP() +#else +#define TARGETUPDATE_START() +#define TARGETUPDATE_STOP() +#endif + + +#if TM_PROFILE_VQNBEST +#define VQNBEST_START() PROFILE_START() +#define VQNBEST_STOP() PROFILE_STOP() +#else +#define VQNBEST_START() +#define VQNBEST_STOP() +#endif + +#if TM_PROFILE_VQNBESTSIGN +#define VQNBESTSIGN_START() PROFILE_START() +#define VQNBESTSIGN_STOP() PROFILE_STOP() +#else +#define VQNBESTSIGN_START() +#define VQNBESTSIGN_STOP() +#endif + +#if TM_PROFILE_PREPROCESSANALYSIS +#define PREPROCESSANAYLSIS_START() PROFILE_START() +#define PREPROCESSANAYLSIS_STOP() PROFILE_STOP() +#else +#define PREPROCESSANAYLSIS_START() +#define PREPROCESSANAYLSIS_STOP() +#endif + +#if TM_PROFILE_UPDATENOISEPROB +#define UPDATENOISEPROB_START() PROFILE_START() +#define UPDATENOISEPROB_STOP() PROFILE_STOP() +#else +#define UPDATENOISEPROB_START() +#define UPDATENOISEPROB_STOP() +#endif + +#if TM_PROFILE_COMPUTEGAINFLOOR +#define COMPUTEGAINFLOOR_START() PROFILE_START() +#define COMPUTEGAINFLOOR_STOP() PROFILE_STOP() +#else +#define COMPUTEGAINFLOOR_START() +#define COMPUTEGAINFLOOR_STOP() +#endif + +#if TM_PROFILE_FILTERDCNOTCH16 +#define FILTERDCNOTCH16_START() PROFILE_START() +#define FILTERDCNOTCH16_STOP() PROFILE_STOP() +#else +#define FILTERDCNOTCH16_START() +#define FILTERDCNOTCH16_STOP() +#endif + +#if TM_PROFILE_MDFINNERPROD +#define MDFINNERPROD_START() PROFILE_START() +#define MDFINNERPROD_STOP() PROFILE_STOP() +#else +#define MDFINNERPROD_START() +#define MDFINNERPROD_STOP() +#endif + +#if TM_PROFILE_SPECTRALMULACCUM +#define SPECTRALMULACCUM_START() PROFILE_START() +#define SPECTRALMULACCUM_STOP() PROFILE_STOP() +#else +#define SPECTRALMULACCUM_START() +#define SPECTRALMULACCUM_STOP() +#endif + +#if TM_PROFILE_WEIGHTEDSPECTRALMULCONJ +#define WEIGHTEDSPECTRALMULCONJ_START() PROFILE_START() +#define WEIGHTEDSPECTRALMULCONJ_STOP() PROFILE_STOP() +#else +#define WEIGHTEDSPECTRALMULCONJ_START() +#define WEIGHTEDSPECTRALMULCONJ_STOP() +#endif + +#if TM_PROFILE_MDFADJUSTPROP +#define MDFADJUSTPROP_START() PROFILE_START() +#define MDFADJUSTPROP_STOP() PROFILE_STOP() +#else +#define MDFADJUSTPROP_START() +#define MDFADJUSTPROP_STOP() +#endif + +#if TM_PROFILE_SPEEXECHOGETRESIDUAL +#define SPEEXECHOGETRESIDUAL_START() PROFILE_START() +#define SPEEXECHOGETRESIDUAL_STOP() PROFILE_STOP() +#else +#define SPEEXECHOGETRESIDUAL_START() +#define SPEEXECHOGETRESIDUAL_STOP() +#endif + +#if TM_PROFILE_LSPENFORCEMARGIN +#define LSPENFORCEMARGIN_START() PROFILE_START() +#define LSPENFORCEMARGIN_STOP() PROFILE_STOP() +#else +#define LSPENFORCEMARGIN_START() +#define LSPENFORCEMARGIN_STOP() +#endif + +#if TM_PROFILE_LSPTOLPC +#define LSPTOLPC_START() PROFILE_START() +#define LSPTOLPC_STOP() PROFILE_STOP() +#else +#define LSPTOLPC_START() +#define LSPTOLPC_STOP() +#endif + +#if TM_PROFILE_MAXIMIZERANGE +#define MAXIMIZERANGE_START() PROFILE_START() +#define MAXIMIZERANGE_STOP() PROFILE_STOP() +#else +#define MAXIMIZERANGE_START() +#define MAXIMIZERANGE_STOP() +#endif + +#if TM_PROFILE_RENORMRANGE +#define RENORMRANGE_START() PROFILE_START() +#define RENORMRANGE_STOP() PROFILE_STOP() +#else +#define RENORMRANGE_START() +#define RENORMRANGE_STOP() +#endif + +#if TM_PROFILE_POWERSPECTRUM +#define POWERSPECTRUM_START() PROFILE_START() +#define POWERSPECTRUM_STOP() PROFILE_STOP() +#else +#define POWERSPECTRUM_START() +#define POWERSPECTRUM_STOP() +#endif + +#if TM_PROFILE_QMFSYNTH +#define QMFSYNTH_START() PROFILE_START() +#define QMFSYNTH_STOP() PROFILE_STOP() +#else +#define QMFSYNTH_START() +#define QMFSYNTH_STOP() +#endif + +#if TM_PROFILE_QMFDECOMP +#define QMFDECOMP_START() PROFILE_START() +#define QMFDECOMP_STOP() PROFILE_STOP() +#else +#define QMFDECOMP_START() +#define QMFDECOMP_STOP() +#endif + +#if TM_PROFILE_FILTERBANKCOMPUTEBANK32 +#define FILTERBANKCOMPUTEBANK32_START() PROFILE_START() +#define FILTERBANKCOMPUTEBANK32_STOP() PROFILE_STOP() +#else +#define FILTERBANKCOMPUTEBANK32_START() +#define FILTERBANKCOMPUTEBANK32_STOP() +#endif + +#if TM_PROFILE_FILTERBANKCOMPUTEPSD16 +#define FILTERBANKCOMPUTEPSD16_START() PROFILE_START() +#define FILTERBANKCOMPUTEPSD16_STOP() PROFILE_STOP() +#else +#define FILTERBANKCOMPUTEPSD16_START() +#define FILTERBANKCOMPUTEPSD16_STOP() +#endif + + diff --git a/src/libs/speexdsp/tmv/speex_config_types.h b/src/libs/speexdsp/tmv/speex_config_types.h new file mode 100644 index 00000000..3166f6c1 --- /dev/null +++ b/src/libs/speexdsp/tmv/speex_config_types.h @@ -0,0 +1,31 @@ +#ifndef __SPEEX_TYPES_H__ +#define __SPEEX_TYPES_H__ + +#ifdef __TCS__ + +#include <tmNxTypes.h> + + + +typedef Int16 spx_int16_t; +typedef UInt16 spx_uint16_t; +typedef Int32 spx_int32_t; +typedef UInt32 spx_uint32_t; + +#ifdef FIXED_POINT +#define VMUX(a,b,c) mux((a),(b),(c)) +#define VABS(a) iabs((a)) +#define VMAX(a,b) imax((a),(b)) +#define VMIN(a,b) imin((a),(b)) +#else +#define VMUX(a,b,c) fmux((a),(b),(c)) +#define VABS(a) fabs((a)) +#define VMAX(a,b) fmax((a),(b)) +#define VMIN(a,b) fmin((a),(b)) +#endif + +#endif + + +#endif + diff --git a/src/libs/speexdsp/win32/Makefile.am b/src/libs/speexdsp/win32/Makefile.am new file mode 100644 index 00000000..63388316 --- /dev/null +++ b/src/libs/speexdsp/win32/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +SUBDIRS = libspeexdsp VS2003 VS2005 VS2008 + +EXTRA_DIST = speex.iss config.h libspeexdsp.def diff --git a/src/libs/speexdsp/win32/VS2003/Makefile.am b/src/libs/speexdsp/win32/VS2003/Makefile.am new file mode 100644 index 00000000..02f81d7b --- /dev/null +++ b/src/libs/speexdsp/win32/VS2003/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +SUBDIRS = libspeexdsp tests + +EXTRA_DIST = libspeexdsp.sln diff --git a/src/libs/speexdsp/win32/VS2003/libspeexdsp.sln b/src/libs/speexdsp/win32/VS2003/libspeexdsp.sln new file mode 100644 index 00000000..7697f749 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2003/libspeexdsp.sln @@ -0,0 +1,116 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testdenoise", "tests\testdenoise.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}" + ProjectSection(ProjectDependencies) = postProject + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testecho", "tests\testecho.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}" + ProjectSection(ProjectDependencies) = postProject + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testresample", "tests\testresample.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}" + ProjectSection(ProjectDependencies) = postProject + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeexdsp", "libspeexdsp\libspeexdsp.vcproj", "{03207781-0D1C-4DB3-A71D-45C608F28DBD}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + Release_Dynamic_SSE = Release_Dynamic_SSE + Release_Static_SSE = Release_Static_SSE + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug.ActiveCfg = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug.Build.0 = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release.ActiveCfg = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release.Build.0 = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE.ActiveCfg = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE.Build.0 = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Static_SSE.ActiveCfg = Release_Static_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Static_SSE.Build.0 = Release_Static_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Static_SSE.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Static_SSE.Build.0 = Release_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug.Build.0 = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release.ActiveCfg = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release.Build.0 = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Dynamic_SSE.ActiveCfg = Release_Dynamic_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Dynamic_SSE.Build.0 = Release_Dynamic_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Static_SSE.ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Static_SSE.Build.0 = Release_Static_SSE|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/libs/speexdsp/win32/VS2003/libspeexdsp/Makefile.am b/src/libs/speexdsp/win32/VS2003/libspeexdsp/Makefile.am new file mode 100644 index 00000000..9f72976d --- /dev/null +++ b/src/libs/speexdsp/win32/VS2003/libspeexdsp/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = libspeexdsp.vcproj + + diff --git a/src/libs/speexdsp/win32/VS2003/libspeexdsp/libspeexdsp.vcproj b/src/libs/speexdsp/win32/VS2003/libspeexdsp/libspeexdsp.vcproj new file mode 100644 index 00000000..751e86a7 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2003/libspeexdsp/libspeexdsp.vcproj @@ -0,0 +1,345 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="libspeexdsp" + ProjectGUID="{03207781-0D1C-4DB3-A71D-45C608F28DBD}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4" + CompileAs="1"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="2" + WholeProgramOptimization="TRUE"> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + GlobalOptimizations="TRUE" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="TRUE" + FavorSizeOrSpeed="1" + OptimizeForProcessor="2" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="TRUE" + ExceptionHandling="FALSE" + RuntimeLibrary="2" + BufferSecurityCheck="FALSE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release_Dynamic_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="2" + WholeProgramOptimization="TRUE"> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + GlobalOptimizations="TRUE" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="TRUE" + FavorSizeOrSpeed="1" + OptimizeForProcessor="3" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H" + StringPooling="TRUE" + ExceptionHandling="FALSE" + RuntimeLibrary="0" + BufferSecurityCheck="FALSE" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + OutputFile="../../../bin/libspeexdsp.dll" + ModuleDefinitionFile="..\..\libspeexdsp.def" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + ImportLibrary="../../../lib/libspeexdsp.lib" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release_Static_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="2" + WholeProgramOptimization="TRUE"> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + GlobalOptimizations="TRUE" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="TRUE" + FavorSizeOrSpeed="1" + OptimizeForProcessor="3" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H" + StringPooling="TRUE" + ExceptionHandling="FALSE" + RuntimeLibrary="2" + BufferSecurityCheck="FALSE" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath="..\..\..\libspeex\buffer.c"> + </File> + <File + RelativePath="..\..\..\libspeex\fftwrap.c"> + </File> + <File + RelativePath="..\..\..\libspeex\filterbank.c"> + </File> + <File + RelativePath="..\..\..\libspeex\jitter.c"> + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fft.c"> + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fftr.c"> + </File> + <File + RelativePath="..\..\..\libspeex\mdf.c"> + </File> + <File + RelativePath="..\..\..\libspeex\preprocess.c"> + </File> + <File + RelativePath="..\..\..\libspeex\resample.c"> + </File> + <File + RelativePath="..\..\..\libspeex\scal.c"> + </File> + <File + RelativePath="..\..\..\libspeex\smallft.c"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath="..\..\..\libspeex\_kiss_fft_guts.h"> + </File> + <File + RelativePath="..\..\..\libspeex\arch.h"> + </File> + <File + RelativePath="..\..\..\libspeex\fftwrap.h"> + </File> + <File + RelativePath="..\..\..\libspeex\filterbank.h"> + </File> + <File + RelativePath="..\..\..\libspeex\fixed_debug.h"> + </File> + <File + RelativePath="..\..\..\libspeex\fixed_generic.h"> + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fft.h"> + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fftr.h"> + </File> + <File + RelativePath="..\..\..\libspeex\math_approx.h"> + </File> + <File + RelativePath="..\..\..\libspeex\os_support.h"> + </File> + <File + RelativePath="..\..\..\libspeex\pseudofloat.h"> + </File> + <File + RelativePath="..\..\..\libspeex\smallft.h"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + <Filter + Name="Public Header Files" + Filter=""> + <File + RelativePath="..\..\..\include\speex\speex.h"> + </File> + <File + RelativePath="..\..\..\include\speex\speex_bits.h"> + </File> + <File + RelativePath="..\..\..\include\speex\speex_buffer.h"> + </File> + <File + RelativePath="..\..\..\include\speex\speex_echo.h"> + </File> + <File + RelativePath="..\..\..\include\speex\speex_jitter.h"> + </File> + <File + RelativePath="..\..\..\include\speex\speex_preprocess.h"> + </File> + <File + RelativePath="..\..\..\include\speex\speex_resampler.h"> + </File> + <File + RelativePath="..\..\..\include\speex\speex_types.h"> + </File> + </Filter> + <File + RelativePath="..\..\config.h"> + </File> + <File + RelativePath="..\..\libspeexdsp.def"> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speexdsp/win32/VS2003/tests/Makefile.am b/src/libs/speexdsp/win32/VS2003/tests/Makefile.am new file mode 100644 index 00000000..38caed80 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2003/tests/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = testdenoise.vcproj testecho.vcproj testresample.vcproj + + diff --git a/src/libs/speexdsp/win32/VS2003/tests/testdenoise.vcproj b/src/libs/speexdsp/win32/VS2003/tests/testdenoise.vcproj new file mode 100644 index 00000000..82cfa41c --- /dev/null +++ b/src/libs/speexdsp/win32/VS2003/tests/testdenoise.vcproj @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="testdenoise" + ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4" + CompileAs="1"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testdenoise.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/speexenc.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + CharacterSet="2" + WholeProgramOptimization="TRUE"> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + GlobalOptimizations="TRUE" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="TRUE" + FavorSizeOrSpeed="1" + OptimizeForProcessor="2" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="TRUE" + ExceptionHandling="FALSE" + RuntimeLibrary="2" + BufferSecurityCheck="FALSE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3" + CompileAs="1"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testdenoise.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="2" + WholeProgramOptimization="TRUE"> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + GlobalOptimizations="TRUE" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="TRUE" + FavorSizeOrSpeed="1" + OptimizeForProcessor="2" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="TRUE" + ExceptionHandling="FALSE" + RuntimeLibrary="2" + BufferSecurityCheck="FALSE" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3" + CompileAs="1"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testdenoise.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath="..\..\..\libspeex\testdenoise.c"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speexdsp/win32/VS2003/tests/testecho.vcproj b/src/libs/speexdsp/win32/VS2003/tests/testecho.vcproj new file mode 100644 index 00000000..4405f24a --- /dev/null +++ b/src/libs/speexdsp/win32/VS2003/tests/testecho.vcproj @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="testecho" + ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4" + CompileAs="1"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testecho.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/speexenc.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + CharacterSet="2" + WholeProgramOptimization="TRUE"> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + GlobalOptimizations="TRUE" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="TRUE" + FavorSizeOrSpeed="1" + OptimizeForProcessor="2" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="TRUE" + ExceptionHandling="FALSE" + RuntimeLibrary="2" + BufferSecurityCheck="FALSE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3" + CompileAs="1"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testecho.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="2" + WholeProgramOptimization="TRUE"> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + GlobalOptimizations="TRUE" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="TRUE" + FavorSizeOrSpeed="1" + OptimizeForProcessor="2" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="TRUE" + ExceptionHandling="FALSE" + RuntimeLibrary="2" + BufferSecurityCheck="FALSE" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3" + CompileAs="1"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testecho.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath="..\..\..\libspeex\testecho.c"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speexdsp/win32/VS2003/tests/testresample.vcproj b/src/libs/speexdsp/win32/VS2003/tests/testresample.vcproj new file mode 100644 index 00000000..f512ca64 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2003/tests/testresample.vcproj @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="testresample" + ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4" + CompileAs="1"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testresample.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/speexenc.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + CharacterSet="2" + WholeProgramOptimization="TRUE"> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + GlobalOptimizations="TRUE" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="TRUE" + FavorSizeOrSpeed="1" + OptimizeForProcessor="2" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="TRUE" + ExceptionHandling="FALSE" + RuntimeLibrary="2" + BufferSecurityCheck="FALSE" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3" + CompileAs="1"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testresample.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="2" + WholeProgramOptimization="TRUE"> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + GlobalOptimizations="TRUE" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="TRUE" + FavorSizeOrSpeed="1" + OptimizeForProcessor="2" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="TRUE" + ExceptionHandling="FALSE" + RuntimeLibrary="2" + BufferSecurityCheck="FALSE" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3" + CompileAs="1"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testresample.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath="..\..\..\libspeex\testresample.c"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speexdsp/win32/VS2005/Makefile.am b/src/libs/speexdsp/win32/VS2005/Makefile.am new file mode 100644 index 00000000..02f81d7b --- /dev/null +++ b/src/libs/speexdsp/win32/VS2005/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +SUBDIRS = libspeexdsp tests + +EXTRA_DIST = libspeexdsp.sln diff --git a/src/libs/speexdsp/win32/VS2005/libspeexdsp.sln b/src/libs/speexdsp/win32/VS2005/libspeexdsp.sln new file mode 100644 index 00000000..52c8206c --- /dev/null +++ b/src/libs/speexdsp/win32/VS2005/libspeexdsp.sln @@ -0,0 +1,231 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeexdsp", "libspeexdsp\libspeexdsp.vcproj", "{E42FDC95-7243-4219-9EA4-ACCE4AB97197}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testdenoise", "tests\testdenoise.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}" + ProjectSection(ProjectDependencies) = postProject + {E42FDC95-7243-4219-9EA4-ACCE4AB97197} = {E42FDC95-7243-4219-9EA4-ACCE4AB97197} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testecho", "tests\testecho.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}" + ProjectSection(ProjectDependencies) = postProject + {E42FDC95-7243-4219-9EA4-ACCE4AB97197} = {E42FDC95-7243-4219-9EA4-ACCE4AB97197} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testresample", "tests\testresample.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}" + ProjectSection(ProjectDependencies) = postProject + {E42FDC95-7243-4219-9EA4-ACCE4AB97197} = {E42FDC95-7243-4219-9EA4-ACCE4AB97197} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_RTL_dll|Win32 = Debug_RTL_dll|Win32 + Debug_WM5_PPC_ARM|Win32 = Debug_WM5_PPC_ARM|Win32 + Debug|Win32 = Debug|Win32 + Release_Dynamic_SSE|Win32 = Release_Dynamic_SSE|Win32 + Release_Dynamic|Win32 = Release_Dynamic|Win32 + Release_RTL_dll|Win32 = Release_RTL_dll|Win32 + Release_SSE|Win32 = Release_SSE|Win32 + Release_SSE2|Win32 = Release_SSE2|Win32 + Release_WM5_PPC_ARM|Win32 = Release_WM5_PPC_ARM|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Win32.ActiveCfg = Debug_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Win32.Build.0 = Debug_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.ActiveCfg = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.Build.0 = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE|Win32.Build.0 = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Win32.ActiveCfg = Release_Dynamic|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Win32.Build.0 = Release_Dynamic|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Win32.ActiveCfg = Release_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Win32.Build.0 = Release_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Win32.ActiveCfg = Release_SSE2|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Win32.Build.0 = Release_SSE2|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.ActiveCfg = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.Build.0 = Release|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Debug_RTL_dll|Win32.ActiveCfg = Debug_RTL_dll|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Debug_RTL_dll|Win32.Build.0 = Debug_RTL_dll|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug_WM5_PPC_ARM|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug_WM5_PPC_ARM|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Debug|Win32.ActiveCfg = Debug|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Debug|Win32.Build.0 = Debug|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_Dynamic_SSE|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_Dynamic_SSE|Win32.Build.0 = Release_Dynamic_SSE|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_Dynamic|Win32.ActiveCfg = Release_Dynamic|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_Dynamic|Win32.Build.0 = Release_Dynamic|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_RTL_dll|Win32.ActiveCfg = Release_RTL_dll|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_RTL_dll|Win32.Build.0 = Release_RTL_dll|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_SSE2|Win32.ActiveCfg = Release_SSE2|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_SSE2|Win32.Build.0 = Release_SSE2|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release_WM5_PPC_ARM|Win32.Build.0 = Release|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release|Win32.ActiveCfg = Release|Win32 + {E42FDC95-7243-4219-9EA4-ACCE4AB97197}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release|Win32.Build.0 = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug|Win32.ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug|Win32.Build.0 = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release|Win32.ActiveCfg = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_RTL_dll|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_RTL_dll|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/speexdsp/win32/VS2005/libspeexdsp/Makefile.am b/src/libs/speexdsp/win32/VS2005/libspeexdsp/Makefile.am new file mode 100644 index 00000000..9f72976d --- /dev/null +++ b/src/libs/speexdsp/win32/VS2005/libspeexdsp/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = libspeexdsp.vcproj + + diff --git a/src/libs/speexdsp/win32/VS2005/libspeexdsp/libspeexdsp.vcproj b/src/libs/speexdsp/win32/VS2005/libspeexdsp/libspeexdsp.vcproj new file mode 100644 index 00000000..c9e33b3c --- /dev/null +++ b/src/libs/speexdsp/win32/VS2005/libspeexdsp/libspeexdsp.vcproj @@ -0,0 +1,1628 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="libspeexdsp" + ProjectGUID="{E42FDC95-7243-4219-9EA4-ACCE4AB97197}" + RootNamespace="libspeexdsp" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="Release" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_SSE2|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="2" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_Dynamic|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + FloatingPointModel="2" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="..\..\..\bin\libspeexdsp.dll" + ModuleDefinitionFile="..\..\libspeexdsp.def" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + ImportLibrary="..\..\..\lib\libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_RTL_dll|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_RTL_dll|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_WM5_PPC_ARM|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_WM5_PPC_ARM|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_Dynamic_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="_USE_SSE;WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + FloatingPointModel="2" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="..\..\..\bin\libspeexdsp.dll" + ModuleDefinitionFile="..\..\libspeexdsp.def" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + ImportLibrary="..\..\..\lib\libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="0" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + ModuleDefinitionFile="libspeexdsp.def" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;FIXED_POINT;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;$(ARCHFAM);$(_ARCHFAM_)" + MinimalRebuild="true" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="0" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + <Configuration + Name="Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)" + OutputDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + IntermediateDirectory="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="1" + /> + <Tool + Name="VCCLCompilerTool" + ExecutionBucket="7" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;FIXED_POINT;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;$(ARCHFAM);$(_ARCHFAM_)" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="0" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCCodeSignTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + <DeploymentTool + ForceDirty="-1" + RemoteDirectory="" + RegisterOutput="0" + AdditionalFiles="" + /> + <DebuggerTool + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\..\..\libspeex\buffer.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\fftwrap.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\filterbank.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\jitter.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fft.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fftr.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\mdf.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\preprocess.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\resample.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\scal.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\smallft.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\..\..\libspeex\_kiss_fft_guts.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\arch.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\fftwrap.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\filterbank.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\fixed_debug.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\fixed_generic.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fft.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fftr.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\math_approx.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\os_support.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\pseudofloat.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\smallft.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <Filter + Name="Public Header Files" + Filter="h" + > + <File + RelativePath="..\..\..\include\speex\speex.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_bits.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_buffer.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_echo.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_jitter.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_preprocess.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_resampler.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_types.h" + > + </File> + </Filter> + <File + RelativePath="..\..\config.h" + > + </File> + <File + RelativePath="..\..\libspeexdsp.def" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speexdsp/win32/VS2005/tests/Makefile.am b/src/libs/speexdsp/win32/VS2005/tests/Makefile.am new file mode 100644 index 00000000..38caed80 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2005/tests/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = testdenoise.vcproj testecho.vcproj testresample.vcproj + + diff --git a/src/libs/speexdsp/win32/VS2005/tests/testdenoise.vcproj b/src/libs/speexdsp/win32/VS2005/tests/testdenoise.vcproj new file mode 100644 index 00000000..dfab1a24 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2005/tests/testdenoise.vcproj @@ -0,0 +1,307 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="testdenoise" + ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testdenoise.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/speexenc.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testdenoise.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testdenoise.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\..\..\libspeex\testdenoise.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speexdsp/win32/VS2005/tests/testecho.vcproj b/src/libs/speexdsp/win32/VS2005/tests/testecho.vcproj new file mode 100644 index 00000000..f2e7240d --- /dev/null +++ b/src/libs/speexdsp/win32/VS2005/tests/testecho.vcproj @@ -0,0 +1,307 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="testecho" + ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testecho.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/speexenc.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testecho.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testecho.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\..\..\libspeex\testecho.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speexdsp/win32/VS2005/tests/testresample.vcproj b/src/libs/speexdsp/win32/VS2005/tests/testresample.vcproj new file mode 100644 index 00000000..9bb7c28f --- /dev/null +++ b/src/libs/speexdsp/win32/VS2005/tests/testresample.vcproj @@ -0,0 +1,307 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="testresample" + ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testresample.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/speexenc.pdb" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testresample.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testresample.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\..\..\libspeex\testresample.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speexdsp/win32/VS2008/Makefile.am b/src/libs/speexdsp/win32/VS2008/Makefile.am new file mode 100644 index 00000000..02f81d7b --- /dev/null +++ b/src/libs/speexdsp/win32/VS2008/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +SUBDIRS = libspeexdsp tests + +EXTRA_DIST = libspeexdsp.sln diff --git a/src/libs/speexdsp/win32/VS2008/libspeexdsp.sln b/src/libs/speexdsp/win32/VS2008/libspeexdsp.sln new file mode 100644 index 00000000..f1c70cb7 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2008/libspeexdsp.sln @@ -0,0 +1,411 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testdenoise", "tests\testdenoise.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}" + ProjectSection(ProjectDependencies) = postProject + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testecho", "tests\testecho.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}" + ProjectSection(ProjectDependencies) = postProject + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testresample", "tests\testresample.vcproj", "{961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}" + ProjectSection(ProjectDependencies) = postProject + {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspeexdsp", "libspeexdsp\libspeexdsp.vcproj", "{03207781-0D1C-4DB3-A71D-45C608F28DBD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_RTL_dll|Win32 = Debug_RTL_dll|Win32 + Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Debug_WM5_PPC_ARM|Win32 = Debug_WM5_PPC_ARM|Win32 + Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Debug|Win32 = Debug|Win32 + Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_Dynamic_SSE|Win32 = Release_Dynamic_SSE|Win32 + Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_Dynamic|Win32 = Release_Dynamic|Win32 + Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_RTL_dll|Win32 = Release_RTL_dll|Win32 + Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_SSE|Win32 = Release_SSE|Win32 + Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_SSE2|Win32 = Release_SSE2|Win32 + Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_Static_SSE|Win32 = Release_Static_SSE|Win32 + Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release_WM5_PPC_ARM|Win32 = Release_WM5_PPC_ARM|Win32 + Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + Release|Win32 = Release|Win32 + Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Win32.ActiveCfg = Debug_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Win32.Build.0 = Debug_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.ActiveCfg = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Win32.Build.0 = Debug|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE|Win32.Build.0 = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_Dynamic_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Win32.ActiveCfg = Release_Dynamic|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Win32.Build.0 = Release_Dynamic|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Win32.ActiveCfg = Release_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Win32.Build.0 = Release_RTL_dll|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Win32.ActiveCfg = Release_SSE2|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Win32.Build.0 = Release_SSE2|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Static_SSE|Win32.ActiveCfg = Release_Static_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Static_SSE|Win32.Build.0 = Release_Static_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Static_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_Static_SSE|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_WM5_PPC_ARM|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.ActiveCfg = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Win32.Build.0 = Release|Win32 + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {E972C52F-9E85-4D65-B19C-031E511E9DB4}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic|Win32.ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic|Win32.Build.0 = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_RTL_dll|Win32.Build.0 = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE2|Win32.ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE2|Win32.Build.0 = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA8}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug|Win32.ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic|Win32.ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic|Win32.Build.0 = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_RTL_dll|Win32.Build.0 = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE2|Win32.ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE2|Win32.Build.0 = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE2|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release|Win32.ActiveCfg = Release|Win32 + {CD6043D1-D5E7-46D0-854F-00BB1BC308FC}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_RTL_dll|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_RTL_dll|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_RTL_dll|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAE}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_RTL_dll|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAC}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_RTL_dll|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAD}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_RTL_dll|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_WM5_PPC_ARM|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug|Win32.ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug|Win32.Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_RTL_dll|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_RTL_dll|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE2|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE2|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Static_SSE|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Static_SSE|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_WM5_PPC_ARM|Win32.Build.0 = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_SSE|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release|Win32.ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release|Win32.Build.0 = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + {961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug_RTL_dll|Win32.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug_WM5_PPC_ARM|Win32.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug|Win32.ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Dynamic_SSE|Win32.ActiveCfg = Release_Dynamic_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Dynamic_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Dynamic_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Dynamic|Win32.ActiveCfg = Release_Dynamic_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Dynamic_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_RTL_dll|Win32.ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_RTL_dll|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_SSE|Win32.ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_SSE2|Win32.ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_SSE2|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Static_SSE|Win32.ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_Static_SSE|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_WM5_PPC_ARM|Win32.ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release_WM5_PPC_ARM|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release_Static_SSE|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release|Win32.ActiveCfg = Release|Win32 + {03207781-0D1C-4DB3-A71D-45C608F28DBD}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/libspeexdsp.log b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/libspeexdsp.log new file mode 100644 index 00000000..440556a1 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/libspeexdsp.log @@ -0,0 +1,32 @@ +Build started 10/26/2015 9:42:06 AM. + 1>Project "C:\works\sevana\pvqa\lib\rtphone\libs\speexdsp\win32\VS2008\libspeexdsp\libspeexdsp.vcxproj" on node 2 (Build target(s)). + 1>ClCompile: + C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\CL.exe /c /I..\..\..\include /I..\.. /ZI /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D _LIB /D HAVE_CONFIG_H /D _VC80_UPGRADE=0x0710 /D _MBCS /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"Debug\\" /Fd"Debug\speexdsp.pdb" /Gd /TC /analyze- /errorReport:prompt ..\..\..\libspeex\buffer.c ..\..\..\libspeex\fftwrap.c ..\..\..\libspeex\filterbank.c ..\..\..\libspeex\jitter.c ..\..\..\libspeex\kiss_fft.c ..\..\..\libspeex\kiss_fftr.c ..\..\..\libspeex\mdf.c ..\..\..\libspeex\preprocess.c ..\..\..\libspeex\resample.c ..\..\..\libspeex\scal.c ..\..\..\libspeex\smallft.c + smallft.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\..\libspeex\smallft.c': No such file or directory + scal.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\..\libspeex\scal.c': No such file or directory + resample.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\..\libspeex\resample.c': No such file or directory + preprocess.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\..\libspeex\preprocess.c': No such file or directory + mdf.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\..\libspeex\mdf.c': No such file or directory + kiss_fftr.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\..\libspeex\kiss_fftr.c': No such file or directory + kiss_fft.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\..\libspeex\kiss_fft.c': No such file or directory + jitter.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\..\libspeex\jitter.c': No such file or directory + filterbank.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\..\libspeex\filterbank.c': No such file or directory + fftwrap.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\..\libspeex\fftwrap.c': No such file or directory + buffer.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\..\libspeex\buffer.c': No such file or directory + Generating Code... + 1>Done Building Project "C:\works\sevana\pvqa\lib\rtphone\libs\speexdsp\win32\VS2008\libspeexdsp\libspeexdsp.vcxproj" (Build target(s)) -- FAILED. + +Build FAILED. + +Time Elapsed 00:00:01.40 diff --git a/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.idb b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.idb new file mode 100644 index 00000000..46fabfce Binary files /dev/null and b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.idb differ diff --git a/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.tlog/CL.command.1.tlog b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.tlog/CL.command.1.tlog new file mode 100644 index 00000000..c9bc325d Binary files /dev/null and b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.tlog/CL.command.1.tlog differ diff --git a/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.tlog/CL.write.1.tlog b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.tlog/CL.write.1.tlog new file mode 100644 index 00000000..c1b62de0 Binary files /dev/null and b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.tlog/CL.write.1.tlog differ diff --git a/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.tlog/speexdsp.lastbuildstate b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.tlog/speexdsp.lastbuildstate new file mode 100644 index 00000000..41676b46 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.tlog/speexdsp.lastbuildstate @@ -0,0 +1,2 @@ +#TargetFrameworkVersion=v4.0:PlatformToolSet=v140:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit +Debug|Win32|C:\works\sevana\pvqa\src\| diff --git a/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.tlog/unsuccessfulbuild b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Debug/speexdsp.tlog/unsuccessfulbuild new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/speexdsp/win32/VS2008/libspeexdsp/Makefile.am b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Makefile.am new file mode 100644 index 00000000..9f72976d --- /dev/null +++ b/src/libs/speexdsp/win32/VS2008/libspeexdsp/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = libspeexdsp.vcproj + + diff --git a/src/libs/speexdsp/win32/VS2008/libspeexdsp/libspeexdsp.vcproj b/src/libs/speexdsp/win32/VS2008/libspeexdsp/libspeexdsp.vcproj new file mode 100644 index 00000000..eb25e669 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2008/libspeexdsp/libspeexdsp.vcproj @@ -0,0 +1,474 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="libspeexdsp" + ProjectGUID="{03207781-0D1C-4DB3-A71D-45C608F28DBD}" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_Dynamic_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="../../../bin/libspeexdsp.dll" + ModuleDefinitionFile="..\..\libspeexdsp.def" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + ImportLibrary="../../../lib/libspeexdsp.lib" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_Static_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + CompileAs="1" + DisableSpecificWarnings="4244;4305;4311;4100;4127" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="../../../lib/libspeexdsp.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\..\..\libspeex\buffer.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\fftwrap.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\filterbank.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\jitter.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fft.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fftr.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\mdf.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\preprocess.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\resample.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\scal.c" + > + </File> + <File + RelativePath="..\..\..\libspeex\smallft.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\..\..\libspeex\_kiss_fft_guts.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\arch.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\fftwrap.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\filterbank.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\fixed_debug.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\fixed_generic.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fft.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\kiss_fftr.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\math_approx.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\os_support.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\pseudofloat.h" + > + </File> + <File + RelativePath="..\..\..\libspeex\smallft.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <Filter + Name="Public Header Files" + > + <File + RelativePath="..\..\..\include\speex\speex.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_bits.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_buffer.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_echo.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_jitter.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_preprocess.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_resampler.h" + > + </File> + <File + RelativePath="..\..\..\include\speex\speex_types.h" + > + </File> + </Filter> + <File + RelativePath="..\..\config.h" + > + </File> + <File + RelativePath="..\..\libspeexdsp.def" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speexdsp/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj b/src/libs/speexdsp/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj new file mode 100644 index 00000000..f21989a3 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj @@ -0,0 +1,224 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release_Dynamic_SSE|Win32"> + <Configuration>Release_Dynamic_SSE</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release_Static_SSE|Win32"> + <Configuration>Release_Static_SSE</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{03207781-0D1C-4DB3-A71D-45C608F28DBD}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <ProjectName>speexdsp</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>Debug\</OutDir> + <IntDir>Debug\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|Win32'"> + <OutDir>$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|Win32'"> + <OutDir>$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <CompileAs>CompileAsC</CompileAs> + </ClCompile> + <Lib> + <OutputFile>../../../lib/libspeexdsp.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>Full</Optimization> + <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> + <IntrinsicFunctions>true</IntrinsicFunctions> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <ExceptionHandling /> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <CompileAs>CompileAsC</CompileAs> + <DisableSpecificWarnings>4244;4305;4311;4100;4127;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <Lib> + <OutputFile>../../../lib/libspeexdsp.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|Win32'"> + <ClCompile> + <Optimization>Full</Optimization> + <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> + <IntrinsicFunctions>true</IntrinsicFunctions> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <ExceptionHandling /> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <CompileAs>CompileAsC</CompileAs> + <DisableSpecificWarnings>4244;4305;4311;4100;4127;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <Link> + <OutputFile>../../../bin/libspeexdsp.dll</OutputFile> + <ModuleDefinitionFile>..\..\libspeexdsp.def</ModuleDefinitionFile> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention /> + <ImportLibrary>../../../lib/libspeexdsp.lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|Win32'"> + <ClCompile> + <Optimization>Full</Optimization> + <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> + <IntrinsicFunctions>true</IntrinsicFunctions> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <ExceptionHandling /> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <CompileAs>CompileAsC</CompileAs> + <DisableSpecificWarnings>4244;4305;4311;4100;4127;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <Lib> + <OutputFile>../../../lib/libspeexdsp.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\libspeex\buffer.c" /> + <ClCompile Include="..\..\..\libspeex\fftwrap.c" /> + <ClCompile Include="..\..\..\libspeex\filterbank.c" /> + <ClCompile Include="..\..\..\libspeex\jitter.c" /> + <ClCompile Include="..\..\..\libspeex\kiss_fft.c" /> + <ClCompile Include="..\..\..\libspeex\kiss_fftr.c" /> + <ClCompile Include="..\..\..\libspeex\mdf.c" /> + <ClCompile Include="..\..\..\libspeex\preprocess.c" /> + <ClCompile Include="..\..\..\libspeex\resample.c" /> + <ClCompile Include="..\..\..\libspeex\scal.c" /> + <ClCompile Include="..\..\..\libspeex\smallft.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\libspeex\_kiss_fft_guts.h" /> + <ClInclude Include="..\..\..\libspeex\arch.h" /> + <ClInclude Include="..\..\..\libspeex\fftwrap.h" /> + <ClInclude Include="..\..\..\libspeex\filterbank.h" /> + <ClInclude Include="..\..\..\libspeex\fixed_debug.h" /> + <ClInclude Include="..\..\..\libspeex\fixed_generic.h" /> + <ClInclude Include="..\..\..\libspeex\kiss_fft.h" /> + <ClInclude Include="..\..\..\libspeex\kiss_fftr.h" /> + <ClInclude Include="..\..\..\libspeex\math_approx.h" /> + <ClInclude Include="..\..\..\libspeex\os_support.h" /> + <ClInclude Include="..\..\..\libspeex\pseudofloat.h" /> + <ClInclude Include="..\..\..\libspeex\smallft.h" /> + <ClInclude Include="..\..\..\include\speex\speex.h" /> + <ClInclude Include="..\..\..\include\speex\speex_bits.h" /> + <ClInclude Include="..\..\..\include\speex\speex_buffer.h" /> + <ClInclude Include="..\..\..\include\speex\speex_echo.h" /> + <ClInclude Include="..\..\..\include\speex\speex_jitter.h" /> + <ClInclude Include="..\..\..\include\speex\speex_preprocess.h" /> + <ClInclude Include="..\..\..\include\speex\speex_resampler.h" /> + <ClInclude Include="..\..\..\include\speex\speex_types.h" /> + <ClInclude Include="..\..\config.h" /> + </ItemGroup> + <ItemGroup> + <None Include="..\..\libspeexdsp.def" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/speexdsp/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj.filters b/src/libs/speexdsp/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj.filters new file mode 100644 index 00000000..87d9d625 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2008/libspeexdsp/libspeexdsp.vcxproj.filters @@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + <Filter Include="Public Header Files"> + <UniqueIdentifier>{28b2f159-a775-48ec-ae58-bc2897aba022}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\..\libspeex\buffer.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\fftwrap.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\filterbank.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\jitter.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\kiss_fft.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\kiss_fftr.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\mdf.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\preprocess.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\resample.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\scal.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\..\libspeex\smallft.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\libspeex\_kiss_fft_guts.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\arch.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\fftwrap.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\filterbank.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\fixed_debug.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\fixed_generic.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\kiss_fft.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\kiss_fftr.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\math_approx.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\os_support.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\pseudofloat.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\libspeex\smallft.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_bits.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_buffer.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_echo.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_jitter.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_preprocess.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_resampler.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\include\speex\speex_types.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\config.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="..\..\libspeexdsp.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/speexdsp/win32/VS2008/tests/Makefile.am b/src/libs/speexdsp/win32/VS2008/tests/Makefile.am new file mode 100644 index 00000000..38caed80 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2008/tests/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = testdenoise.vcproj testecho.vcproj testresample.vcproj + + diff --git a/src/libs/speexdsp/win32/VS2008/tests/testdenoise.vcproj b/src/libs/speexdsp/win32/VS2008/tests/testdenoise.vcproj new file mode 100644 index 00000000..61c1b5e7 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2008/tests/testdenoise.vcproj @@ -0,0 +1,305 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="testdenoise" + ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DA9}" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testdenoise.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/speexenc.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testdenoise.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testdenoise.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\..\..\libspeex\testdenoise.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speexdsp/win32/VS2008/tests/testecho.vcproj b/src/libs/speexdsp/win32/VS2008/tests/testecho.vcproj new file mode 100644 index 00000000..50c1edb3 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2008/tests/testecho.vcproj @@ -0,0 +1,305 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="testecho" + ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DAA}" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testecho.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/speexenc.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testecho.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testecho.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\..\..\libspeex\testecho.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speexdsp/win32/VS2008/tests/testresample.vcproj b/src/libs/speexdsp/win32/VS2008/tests/testresample.vcproj new file mode 100644 index 00000000..5c4953c3 --- /dev/null +++ b/src/libs/speexdsp/win32/VS2008/tests/testresample.vcproj @@ -0,0 +1,305 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="testresample" + ProjectGUID="{961B8359-1393-4EF7-B8E0-67B6FE1C6DAB}" + Keyword="Win32Proj" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_CONFIG_H" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testresample.exe" + LinkIncremental="2" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)/speexenc.pdb" + SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testresample.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_SSE|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="3" + InlineFunctionExpansion="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories="..\..\..\include;..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_CONFIG_H" + StringPooling="true" + ExceptionHandling="0" + RuntimeLibrary="2" + BufferSecurityCheck="false" + EnableEnhancedInstructionSet="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + CompileAs="1" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="../../../bin/testresample.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + OptimizeForWindows98="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\..\..\libspeex\testresample.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/speexdsp/win32/libspeexdsp.def b/src/libs/speexdsp/win32/libspeexdsp.def new file mode 100644 index 00000000..45fc69d9 --- /dev/null +++ b/src/libs/speexdsp/win32/libspeexdsp.def @@ -0,0 +1,76 @@ +LIBRARY libspeexdsp +EXPORTS + + +; +; speex_buffer.h +; +speex_buffer_init +speex_buffer_destroy +speex_buffer_write +speex_buffer_writezeros +speex_buffer_read +speex_buffer_get_available +speex_buffer_resize + +; +; speex_echo.h +; +speex_echo_state_init +speex_echo_state_init_mc +speex_echo_state_destroy +speex_echo_cancellation +speex_echo_cancel +speex_echo_capture +speex_echo_playback +speex_echo_state_reset +speex_echo_ctl +speex_decorrelate_new +speex_decorrelate +speex_decorrelate_destroy + +; +; speex_jitter.h +; +jitter_buffer_init +jitter_buffer_reset +jitter_buffer_destroy +jitter_buffer_put +jitter_buffer_get +jitter_buffer_get_pointer_timestamp +jitter_buffer_tick +jitter_buffer_update_delay + +; +; speex_preprocess.h +; +speex_preprocess_state_init +speex_preprocess_state_destroy +speex_preprocess_run +speex_preprocess +speex_preprocess_estimate_update +speex_preprocess_ctl + +; +; speex_resampler.h +; +speex_resampler_init +speex_resampler_init_frac +speex_resampler_destroy +speex_resampler_process_float +speex_resampler_process_int +speex_resampler_process_interleaved_float +speex_resampler_process_interleaved_int +speex_resampler_set_rate +speex_resampler_get_rate +speex_resampler_set_rate_frac +speex_resampler_get_ratio +speex_resampler_set_quality +speex_resampler_get_quality +speex_resampler_set_input_stride +speex_resampler_get_input_stride +speex_resampler_set_output_stride +speex_resampler_get_output_stride +speex_resampler_skip_zeros +speex_resampler_reset_mem +speex_resampler_strerror diff --git a/src/libs/speexdsp/win32/libspeexdsp/Makefile.am b/src/libs/speexdsp/win32/libspeexdsp/Makefile.am new file mode 100644 index 00000000..b35b4685 --- /dev/null +++ b/src/libs/speexdsp/win32/libspeexdsp/Makefile.am @@ -0,0 +1,6 @@ +## Process this file with automake to produce Makefile.in. -*-Makefile-*- + +# Disable automatic dependency tracking if using other tools than gcc and gmake +#AUTOMAKE_OPTIONS = no-dependencies + +EXTRA_DIST = libspeexdsp.dsw libspeexdsp.dsp libspeexdsp_dynamic.dsp diff --git a/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp.dsp b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp.dsp new file mode 100644 index 00000000..10f2c1aa --- /dev/null +++ b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp.dsp @@ -0,0 +1,228 @@ +# Microsoft Developer Studio Project File - Name="libspeexdsp" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=libspeexdsp - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libspeexdsp.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libspeexdsp.mak" CFG="libspeexdsp - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libspeexdsp - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libspeexdsp - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libspeexdsp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +F90=df.exe +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MD /W1 /GX- /O2 /I "../../include" /I "../" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_CONFIG_H" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\..\lib\libspeexdsp.lib" + +!ELSEIF "$(CFG)" == "libspeexdsp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "libspeexdsp___Win32_Debug" +# PROP BASE Intermediate_Dir "libspeexdsp___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "libspeexdsp___Win32_Debug" +# PROP Intermediate_Dir "libspeexdsp___Win32_Debug" +# PROP Target_Dir "" +F90=df.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm- /GX- /Zi /Od /I "../../include" /I "../" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_CONFIG_H" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\..\lib\libspeexdsp.lib" + +!ENDIF + +# Begin Target + +# Name "libspeexdsp - Win32 Release" +# Name "libspeexdsp - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\libspeex\buffer.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fftwrap.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\filterbank.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\jitter.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fft.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fftr.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\mdf.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\preprocess.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\resample.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\scal.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\smallft.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\libspeex\_kiss_fft_guts.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\arch.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fftwrap.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\filterbank.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fixed_debug.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fixed_generic.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fft.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fftr.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\math_approx.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\os_support.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\pseudofloat.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\smallft.h +# End Source File +# End Group +# Begin Group "Public Header Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\include\speex\speex.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_bits.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_echo.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_jitter.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_preprocess.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_resampler.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_types.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\config.h +# End Source File +# End Target +# End Project diff --git a/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp.dsw b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp.dsw new file mode 100644 index 00000000..814f2ae9 --- /dev/null +++ b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "libspeexdsp"=.\libspeexdsp.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "libspeexdsp_dynamic"=.\libspeexdsp_dynamic.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp.vcxproj b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp.vcxproj new file mode 100644 index 00000000..ed59ba98 --- /dev/null +++ b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp.vcxproj @@ -0,0 +1,149 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <SccProjectName /> + <SccLocalPath /> + <ProjectGuid>{CEC85390-03B2-4A8D-BFD3-EF71F382FDBD}</ProjectGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\libspeexdsp___Win32_Debug\</OutDir> + <IntDir>.\libspeexdsp___Win32_Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <AdditionalIncludeDirectories>../../include;../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\libspeexdsp.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <ResourceCompile> + <Culture>0x0809</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\libspeexdsp.bsc</OutputFile> + </Bscmake> + <Lib> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>..\..\lib\libspeexdsp.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../include;../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\libspeexdsp___Win32_Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\libspeexdsp___Win32_Debug\libspeexdsp.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\libspeexdsp___Win32_Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\libspeexdsp___Win32_Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <ResourceCompile> + <Culture>0x0809</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\libspeexdsp___Win32_Debug\libspeexdsp.bsc</OutputFile> + </Bscmake> + <Lib> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>..\..\lib\libspeexdsp.lib</OutputFile> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\libspeex\buffer.c" /> + <ClCompile Include="..\..\libspeex\fftwrap.c" /> + <ClCompile Include="..\..\libspeex\filterbank.c" /> + <ClCompile Include="..\..\libspeex\jitter.c" /> + <ClCompile Include="..\..\libspeex\kiss_fft.c" /> + <ClCompile Include="..\..\libspeex\kiss_fftr.c" /> + <ClCompile Include="..\..\libspeex\mdf.c" /> + <ClCompile Include="..\..\libspeex\preprocess.c" /> + <ClCompile Include="..\..\libspeex\resample.c" /> + <ClCompile Include="..\..\libspeex\scal.c" /> + <ClCompile Include="..\..\libspeex\smallft.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\libspeex\_kiss_fft_guts.h" /> + <ClInclude Include="..\..\libspeex\arch.h" /> + <ClInclude Include="..\..\libspeex\fftwrap.h" /> + <ClInclude Include="..\..\libspeex\filterbank.h" /> + <ClInclude Include="..\..\libspeex\fixed_debug.h" /> + <ClInclude Include="..\..\libspeex\fixed_generic.h" /> + <ClInclude Include="..\..\libspeex\kiss_fft.h" /> + <ClInclude Include="..\..\libspeex\kiss_fftr.h" /> + <ClInclude Include="..\..\libspeex\math_approx.h" /> + <ClInclude Include="..\..\libspeex\os_support.h" /> + <ClInclude Include="..\..\libspeex\pseudofloat.h" /> + <ClInclude Include="..\..\libspeex\smallft.h" /> + <ClInclude Include="..\..\include\speex\speex.h" /> + <ClInclude Include="..\..\include\speex\speex_bits.h" /> + <ClInclude Include="..\..\include\speex\speex_buffer.h" /> + <ClInclude Include="..\..\include\speex\speex_echo.h" /> + <ClInclude Include="..\..\include\speex\speex_jitter.h" /> + <ClInclude Include="..\..\include\speex\speex_preprocess.h" /> + <ClInclude Include="..\..\include\speex\speex_resampler.h" /> + <ClInclude Include="..\..\include\speex\speex_types.h" /> + <ClInclude Include="..\config.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp.vcxproj.filters b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp.vcxproj.filters new file mode 100644 index 00000000..d0204c7d --- /dev/null +++ b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp.vcxproj.filters @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{12a4539b-56a3-487e-a042-52d13dd1409b}</UniqueIdentifier> + <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{69a29ff5-49f8-46b5-af11-1563ff357521}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl</Extensions> + </Filter> + <Filter Include="Public Header Files"> + <UniqueIdentifier>{5f165e9b-df76-4e7d-934c-84174b34f2cc}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\libspeex\buffer.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libspeex\fftwrap.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libspeex\filterbank.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libspeex\jitter.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libspeex\kiss_fft.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libspeex\kiss_fftr.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libspeex\mdf.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libspeex\preprocess.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libspeex\resample.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libspeex\scal.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libspeex\smallft.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\libspeex\_kiss_fft_guts.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\libspeex\arch.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\libspeex\fftwrap.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\libspeex\filterbank.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\libspeex\fixed_debug.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\libspeex\fixed_generic.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\libspeex\kiss_fft.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\libspeex\kiss_fftr.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\libspeex\math_approx.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\libspeex\os_support.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\libspeex\pseudofloat.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\libspeex\smallft.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\speex\speex.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\speex\speex_bits.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\speex\speex_buffer.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\speex\speex_echo.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\speex\speex_jitter.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\speex\speex_preprocess.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\speex\speex_resampler.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\include\speex\speex_types.h"> + <Filter>Public Header Files</Filter> + </ClInclude> + <ClInclude Include="..\config.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp___Win32_Debug/libspeexdsp.log b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp___Win32_Debug/libspeexdsp.log new file mode 100644 index 00000000..5d263e31 --- /dev/null +++ b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp___Win32_Debug/libspeexdsp.log @@ -0,0 +1,32 @@ +Build started 10/26/2015 9:41:29 AM. + 1>Project "C:\works\sevana\pvqa\lib\rtphone\libs\speexdsp\win32\libspeexdsp\libspeexdsp.vcxproj" on node 2 (Build target(s)). + 1>ClCompile: + C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\CL.exe /c /I../../include /I../ /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D _LIB /D HAVE_CONFIG_H /D _VC80_UPGRADE=0x0600 /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /Gy- /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo".\libspeexdsp___Win32_Debug\\" /Fd".\libspeexdsp___Win32_Debug\libspeexdsp.pdb" /Gd /TC /analyze- /errorReport:prompt ..\..\libspeex\buffer.c ..\..\libspeex\fftwrap.c ..\..\libspeex\filterbank.c ..\..\libspeex\jitter.c ..\..\libspeex\kiss_fft.c ..\..\libspeex\kiss_fftr.c ..\..\libspeex\mdf.c ..\..\libspeex\preprocess.c ..\..\libspeex\resample.c ..\..\libspeex\scal.c ..\..\libspeex\smallft.c + buffer.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\libspeex\buffer.c': No such file or directory + fftwrap.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\libspeex\fftwrap.c': No such file or directory + filterbank.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\libspeex\filterbank.c': No such file or directory + jitter.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\libspeex\jitter.c': No such file or directory + kiss_fft.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\libspeex\kiss_fft.c': No such file or directory + kiss_fftr.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\libspeex\kiss_fftr.c': No such file or directory + mdf.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\libspeex\mdf.c': No such file or directory + preprocess.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\libspeex\preprocess.c': No such file or directory + resample.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\libspeex\resample.c': No such file or directory + scal.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\libspeex\scal.c': No such file or directory + smallft.c + 1>c1 : fatal error C1083: Cannot open source file: '..\..\libspeex\smallft.c': No such file or directory + Generating Code... + 1>Done Building Project "C:\works\sevana\pvqa\lib\rtphone\libs\speexdsp\win32\libspeexdsp\libspeexdsp.vcxproj" (Build target(s)) -- FAILED. + +Build FAILED. + +Time Elapsed 00:00:01.10 diff --git a/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp___Win32_Debug/libspeexdsp.tlog/CL.command.1.tlog b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp___Win32_Debug/libspeexdsp.tlog/CL.command.1.tlog new file mode 100644 index 00000000..46b134b1 --- /dev/null +++ b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp___Win32_Debug/libspeexdsp.tlog/CL.command.1.tlog @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp___Win32_Debug/libspeexdsp.tlog/libspeexdsp.lastbuildstate b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp___Win32_Debug/libspeexdsp.tlog/libspeexdsp.lastbuildstate new file mode 100644 index 00000000..41676b46 --- /dev/null +++ b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp___Win32_Debug/libspeexdsp.tlog/libspeexdsp.lastbuildstate @@ -0,0 +1,2 @@ +#TargetFrameworkVersion=v4.0:PlatformToolSet=v140:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit +Debug|Win32|C:\works\sevana\pvqa\src\| diff --git a/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp___Win32_Debug/libspeexdsp.tlog/unsuccessfulbuild b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp___Win32_Debug/libspeexdsp.tlog/unsuccessfulbuild new file mode 100644 index 00000000..e69de29b diff --git a/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp_dynamic.dsp b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp_dynamic.dsp new file mode 100644 index 00000000..28096619 --- /dev/null +++ b/src/libs/speexdsp/win32/libspeexdsp/libspeexdsp_dynamic.dsp @@ -0,0 +1,237 @@ +# Microsoft Developer Studio Project File - Name="libspeexdsp_dynamic" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=libspeexdsp_dynamic - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libspeexdsp_dynamic.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libspeexdsp_dynamic.mak" CFG="libspeexdsp_dynamic - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libspeexdsp_dynamic - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libspeexdsp_dynamic - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libspeexdsp_dynamic - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "libspeexdsp_dynamic___Win32_Release" +# PROP BASE Intermediate_Dir "libspeexdsp_dynamic___Win32_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Dynamic_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBSPEEX_DYNAMIC_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_CONFIG_H" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\bin\libspeexdsp.dll" /implib:"..\..\lib\libspeexdsp.lib" + +!ELSEIF "$(CFG)" == "libspeexdsp_dynamic - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "libspeexdsp_dynamic___Win32_Debug" +# PROP BASE Intermediate_Dir "libspeexdsp_dynamic___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Dynamic_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBSPEEX_DYNAMIC_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_CONFIG_H" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\bin\libspeexdsp.dll" /implib:"..\..\lib\libspeexdsp.lib" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "libspeexdsp_dynamic - Win32 Release" +# Name "libspeexdsp_dynamic - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\libspeex\buffer.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fftwrap.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\filterbank.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\jitter.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fft.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fftr.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\mdf.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\preprocess.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\resample.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\scal.c +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\smallft.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\libspeex\_kiss_fft_guts.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\arch.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fftwrap.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\filterbank.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fixed_debug.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\fixed_generic.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fft.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\kiss_fftr.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\math_approx.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\os_support.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\pseudofloat.h +# End Source File +# Begin Source File + +SOURCE=..\..\libspeex\smallft.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_buffer.h +# End Source File +# End Group +# Begin Group "Public Header Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\include\speex\speex.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_bits.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_echo.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_jitter.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_preprocess.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_resampler.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\speex\speex_types.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\config.h +# End Source File +# Begin Source File + +SOURCE=..\libspeexdsp.def +# End Source File +# End Target +# End Project diff --git a/src/libs/speexdsp/win32/speex.iss b/src/libs/speexdsp/win32/speex.iss new file mode 100644 index 00000000..6700cfe2 --- /dev/null +++ b/src/libs/speexdsp/win32/speex.iss @@ -0,0 +1,47 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +[Setup] +AppName=Speex +AppVerName=Speex V1.1.6 +AppPublisherURL=http://www.speex.org +AppSupportURL=http://www.speex.org +AppUpdatesURL=http://www.speex.org +DefaultDirName={pf}\Speex +DefaultGroupName=Speex +AllowNoIcons=yes +LicenseFile=..\COPYING +InfoAfterFile=..\README +OutputDir=. +OutputBaseFilename=speex_win32_1.1.6_setup +; uncomment the following line if you want your installation to run on NT 3.51 too. +; MinVersion=4,3.51 + +[Tasks] +;Name: "desktopicon"; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:"; MinVersion: 4,4 + +[Dirs] +Name: "{app}" +Name: "{app}\doc" +Name: "{app}\html" +Name: "{app}\libspeex" +Name: "{app}\libspeex\include" + +[Files] +Source: "speexdec\Release\speexdec.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "speexenc\Release\speexenc.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "libspeex\Release\libspeex.lib"; DestDir: "{app}\libspeex"; Flags: ignoreversion +Source: "libspeex\Release\libspeex.exp"; DestDir: "{app}\libspeex"; Flags: ignoreversion +Source: "libspeex\Release\libspeex.dll"; DestDir: "{app}\libspeex"; Flags: ignoreversion +Source: "..\include\speex\speex.h"; DestDir: "{app}\libspeex\include"; Flags: ignoreversion +Source: "..\include\speex\speex_bits.h"; DestDir: "{app}\libspeex\include"; Flags: ignoreversion +Source: "..\include\speex\speex_callbacks.h"; DestDir: "{app}\libspeex\include"; Flags: ignoreversion +Source: "..\include\speex\speex_echo.h"; DestDir: "{app}\libspeex\include"; Flags: ignoreversion +Source: "..\include\speex\speex_header.h"; DestDir: "{app}\libspeex\include"; Flags: ignoreversion +Source: "..\include\speex\speex_jitter.h"; DestDir: "{app}\libspeex\include"; Flags: ignoreversion +Source: "..\include\speex\speex_preprocess.h"; DestDir: "{app}\libspeex\include"; Flags: ignoreversion +Source: "..\include\speex\speex_stereo.h"; DestDir: "{app}\libspeex\include"; Flags: ignoreversion +Source: "..\doc\manual.pdf"; DestDir: "{app}\doc"; Flags: ignoreversion + +[Run] + diff --git a/src/libs/srtp/CHANGES b/src/libs/srtp/CHANGES new file mode 100644 index 00000000..949c3893 --- /dev/null +++ b/src/libs/srtp/CHANGES @@ -0,0 +1,223 @@ +Changelog + +1.3.20 + + Lots of changes. Thanks to Jeff Chan for catching a memory leak and + helping track down the endian issues with the SSRCs. + +1.3.8 + + This is an interim release. Several little-endian bugs were identified + and fixed; this means that we can use intel/linux for development again. + + Cleaned up sha1 and hmac code significantly, got rid of some excess + functions and properly documented the fuctions in the .h files. + + Eliminated some vestigial files. + + There is a SIGBUS error in the AES encrypt function on sparc + (observed on both solaris and openbsd) with gcc 2.95. Was unable to + find bad pointer anywhere, so I'm wondering if it isn't a compiler + problem (there's a known problem whose profile it fits). It doesn't + appear on any other platform, even in the cipher_driver stress + tests. + + Planned changes + + Change interface to nonces (xtd_seq_num_t) so that it uses + network byte ordering, and is consistent with other arguments. + + +1.3.6 + + Changed /dev/random (in configure.in and crypto/rng/rand_source.c) to + /dev/urandom; the latter is non-blocking on all known platforms (which + corrects some programs that seem to hang) and is actually present on + Open BSD (unlike /dev/random, which only works in the presence of + hardware supported random number generation). + + Added machine/types.h case in include/integers.h. + +1.3.5 + + Removing srtp_t::template and stream_clone(). + + Adding a new policy structure, which will reflect a complete SRTP + policy (including SRTCP). + + This version is *incomplete* and will undergo more changes. It is + provided only as a basis for discussion. + +1.3.4 + + Removed tmmh.c and tmmh.h, which implemented version one of TMMH. + + Changed srtp_get_trailer_length() to act on streams rather than + sessions, and documented the macro SRTP_MAX_TRAILER_LEN, which should + usually be used rather than that function. + + Removed 'salt' from cipher input. + + Changed rdbx to use err.h error codes. + + Changed malloc() and free() to xalloc() and xfree; these functions + are defined in crypto/kernel/alloc.c and declared in + include/alloc.h. + + Added 'output' functions to cipher, in addition to 'encrypt' + functions. It is no longer necessary to zeroize a buffer before + encrypting in order to get keystream. + + Changed octet_string_hex_string() so that "times two" isn't needed + in its input. + + Added crypto_kernel_init() prior to command-line parsing, so that + kernel can be passed command-line arguments, such as "-d + debug_module". This was done to for the applications + test/srtp-driver, test/kernel-driver, and test/ust-driver. + + Improved srtp_init_aes_128_prf - wrote key derivation function + (srtp_kdf_t). + + Add the tag_len as an argument to the auth_compute() function, but + not the corresponding macro. This change allows the tag length for + a given auth func to be set to different values at initialization + time. Previously, the structure auth_t contained the + output_length, but that value was inaccessible from hmac_compute() + and other functions. + + Re-named files from a-b.c to a_b.c. in order to help portability. + + Re-named rijndael to aes (or aes_128 as appropriate). + + +1.2.1 + + Changes so that 1.2.0 compiles on cygwin-win2k. + + Added better error reporting system. If syslog is present on the + OS, then it is used. + + +1.2.0 Many improvements and additions, and a fex fixes + + Fixed endian issues in RTP header construction in the function + rtp_sendto() in srtp/rtp.c. + + Implemented RIJNDAEL decryption operation, adding the functions + rijndael_decrypt() and rijndael_expand_decryption_key(). Also + re-named rijndael_expand_key() to rijndael_expand_encryption_key() + for consistency. + + Implemented random number source using /dev/random, in the files + crypto/rng/rand_source.c and include/rand_source.h. + + Added index check to SEAL cipher (only values less than 2^32 are + allowed) + + Added test case for null_auth authentication function. + + Added a timing test which tests the effect of CPU cache thrash on + cipher throughput. The test is done by the function + cipher_test_throughput_array(); the function + cipher_array_alloc_init() creates an array of ciphers for use in + this test. This test can be accessed by using the -a flag to + the application cipher-driver in the test subdirectory. + + Added argument processing to ust-driver.c, and added that app to + the 'runtest' target in Makefile.in. + + A minor auth_t API change: last argument of auth_init() eliminated. + + +1.0.6 A small but important fix + + Fixed srtp_init_aes_128_prf() by adding octet_string_set_to_zero() + after buffer allocation. + + Eliminated references to no-longer-existing variables in debugging + code in srtp/srtp.c. This fixes the compilation failure that + occured when using PRINT_DEBUG in that file. + + Corrected spelling of Richard Priestley's name in credits. Sorry + Richard! + + +1.0.5 Many little fixes + + Fixed octet_string_set_to_zero(), which was writing one + more zero octet than it should. This bug caused srtp_protect() + and srtp_unprotect() to overwrite the byte that followed the + srtp packet. + + Changed sizeof(uint32_t) to srtp_get_trailer_length() in + srtp-driver.c. This is just defensive coding. + + Added NULL check to malloc in srtp_alloc(). + + +1.0.4 Many minor fixes and two big ones (thanks for the bug reports!) + + Removed 'ssrc' from the srtp_init_aes_128_prf() function argument + list. This is so that applications which do not a priori know the + ssrc which they will be receiving can still use libsrtp. Now the + SSRC value is gleaned from the rtp header and exored into the + counter mode offset in the srtp_protect() and srtp_unprotect() + functions, if that cipher is used. This change cascaed through + many other functions, including srtp_init_from_hex(), + srtp_sender_init() and srtp_receiver_init() in rtp.c, and also + changing the CLI to test/rtpw. In the future, another function + call will be added to the library that enables multiple ssrc/key + pairs to be installed into the same srtp session, so that libsrtp + works with multiple srtp senders. For now, this functionality is + lacking. + + Removed the GDOI interface to the rtpw demo program. This will be + added again at a later date, after the SRTP and GDOI distributions + stabilize. For now, I've left in the GDOI #defines and autoconf + definitions so that they'll be in place when needed. + + Updated tmmhv2_compute() so that it didn't assume any particular + alginment of the output tag. + + Changed bit field variables in srtp.h to unsigned char from + unsigned int in order to avoid a potential endianness issue. + + Fixed rdbx_estimate_index() to handle all input cases. This solves + the now notorious "abaft" bug in the rtpw demo app on linux/intel, + in which spurious replay protection failures happen after that word + is received. + + Added ntohs(hdr->seq) to srtp_protect and srtp_unprotect, removed + from rijndael_icm_set_segment(). + + Added error checking and handling to srtp_sender_init() and + srtp_receiver_init(). + + Changed srtp_alloc() so that it does what you'd expect: allocate an + srtp_ctx_t structure. This hides the library internals. + + +1.0.1 Many minor fixes + + Added cipher_driver_buffer_test(...) to test/cipher-driver.c. This + function checks that the byte-buffering functions used by a cipher + are correct. + + Fixed SunOS/Solaris build problems: added HAVE_SYS_INT_TYPES_H and + changed index_t to xtd_seq_num_t (see include/rdbx.h). + + Fixed SEAL3.0 output byte buffering, added byte-buffering test to + cipher/cipher-driver.c. + + Fixed roc-driver so that the non-sequential insertion test + automatically recovers from bad estimates. This was required to + prevent spurious failures. + + Made rdbx_estimate_index(...) function smarter, so that initial RTP + sequence numbers greater than 32,768 don't cause it to estimate the + rollover counter of 0xffffffff. + + +1.0.0 Initial release + diff --git a/src/libs/srtp/CMakeLists.txt b/src/libs/srtp/CMakeLists.txt new file mode 100644 index 00000000..d5307d3f --- /dev/null +++ b/src/libs/srtp/CMakeLists.txt @@ -0,0 +1,35 @@ +project (srtp) + +# Rely on C++ 11 +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +set (SRTP_SOURCES + srtp/srtp.c + srtp/ekt.c + crypto/rng/rand_source.c + crypto/rng/prng.c + crypto/rng/ctr_prng.c + crypto/replay/ut_sim.c + crypto/replay/rdbx.c + crypto/replay/rdb.c + crypto/math/stat.c + crypto/math/gf2_8.c + crypto/kernel/key.c + crypto/kernel/err.c + crypto/kernel/crypto_kernel.c + crypto/kernel/alloc.c + crypto/hash/sha1.c + crypto/hash/null_auth.c + crypto/hash/hmac.c + crypto/cipher/null_cipher.c + crypto/cipher/cipher.c + crypto/cipher/aes.c + crypto/cipher/aes_icm.c + crypto/cipher/aes_cbc.c + crypto/ae_xfm/xfm.c + crypto/hash/srtp_auth.c + crypto/math/datatypes.c +) + +add_library(srtp ${SRTP_SOURCES}) diff --git a/src/libs/srtp/LICENSE b/src/libs/srtp/LICENSE new file mode 100644 index 00000000..dd43240c --- /dev/null +++ b/src/libs/srtp/LICENSE @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ diff --git a/src/libs/srtp/Makefile.in b/src/libs/srtp/Makefile.in new file mode 100644 index 00000000..e88090a6 --- /dev/null +++ b/src/libs/srtp/Makefile.in @@ -0,0 +1,237 @@ +# Makefile for secure rtp +# +# David A. McGrew +# Cisco Systems, Inc. + +# targets: +# +# runtest runs test applications +# test builds test applications +# libcrypt.a static library implementing crypto engine +# libsrtp.a static library implementing srtp +# clean removes objects, libs, and executables +# distribution cleans and builds a .tgz +# tags builds etags file from all .c and .h files + +.PHONY: all test build_table_apps + +all: test + +runtest: build_table_apps test + @echo "running libsrtp test applications..." + crypto/test/cipher_driver$(EXE) -v >/dev/null + crypto/test/kernel_driver$(EXE) -v >/dev/null + test/rdbx_driver$(EXE) -v >/dev/null + test/srtp_driver$(EXE) -v >/dev/null + test/roc_driver$(EXE) -v >/dev/null + test/replay_driver$(EXE) -v >/dev/null + test/dtls_srtp_driver$(EXE) >/dev/null + cd test; $(abspath $(srcdir))/test/rtpw_test.sh >/dev/null + @echo "libsrtp test applications passed." + $(MAKE) -C crypto runtest + +# makefile variables + +CC = @CC@ +INCDIR = -Icrypto/include -I$(srcdir)/include -I$(srcdir)/crypto/include +DEFS = @DEFS@ +CPPFLAGS= @CPPFLAGS@ +CFLAGS = @CFLAGS@ +LIBS = @LIBS@ +LDFLAGS = @LDFLAGS@ -L. +COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS) +SRTPLIB = -lsrtp + +RANLIB = @RANLIB@ +INSTALL = @INSTALL@ + +# EXE defines the suffix on executables - it's .exe for Windows, and +# null on linux, bsd, and OS X and other OSes. +EXE = @EXE@ +# gdoi is the group domain of interpretation for isakmp, a group key +# management system which can provide keys for srtp +gdoi = @GDOI_OBJS@ +# Random source. +RNG_OBJS = @RNG_OBJS@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +includedir = @includedir@ +libdir = @libdir@ + + +# implicit rules for object files and test apps + +%.o: %.c + $(COMPILE) -c $< -o $@ + +%$(EXE): %.c + $(COMPILE) $(LDFLAGS) $< -o $@ $(SRTPLIB) $(LIBS) + + +# libcrypt.a (the crypto engine) +ciphers = crypto/cipher/cipher.o crypto/cipher/null_cipher.o \ + crypto/cipher/aes.o crypto/cipher/aes_icm.o \ + crypto/cipher/aes_cbc.o + +hashes = crypto/hash/null_auth.o crypto/hash/sha1.o \ + crypto/hash/hmac.o crypto/hash/auth.o # crypto/hash/tmmhv2.o + +replay = crypto/replay/rdb.o crypto/replay/rdbx.o \ + crypto/replay/ut_sim.o + +math = crypto/math/datatypes.o crypto/math/stat.o + +ust = crypto/ust/ust.o + +rng = crypto/rng/$(RNG_OBJS) crypto/rng/prng.o crypto/rng/ctr_prng.o + +err = crypto/kernel/err.o + +kernel = crypto/kernel/crypto_kernel.o crypto/kernel/alloc.o \ + crypto/kernel/key.o $(rng) $(err) # $(ust) + +cryptobj = $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(replay) + +# libsrtp.a (implements srtp processing) + +srtpobj = srtp/srtp.o srtp/ekt.o + +libsrtp.a: $(srtpobj) $(cryptobj) $(gdoi) + ar cr libsrtp.a $^ + $(RANLIB) libsrtp.a + +# libcryptomath.a contains general-purpose routines that are used to +# generate tables and verify cryptoalgorithm implementations - this +# library is not meant to be included in production code + +cryptomath = crypto/math/math.o crypto/math/gf2_8.o + +libcryptomath.a: $(cryptomath) + ar cr libcryptomath.a $(cryptomath) + $(RANLIB) libcryptomath.a + + +# test applications + +crypto_testapp = crypto/test/aes_calc$(EXE) crypto/test/cipher_driver$(EXE) \ + crypto/test/datatypes_driver$(EXE) crypto/test/kernel_driver$(EXE) \ + crypto/test/rand_gen$(EXE) crypto/test/sha1_driver$(EXE) \ + crypto/test/stat_driver$(EXE) + +testapp = $(crypto_testapp) test/srtp_driver$(EXE) test/replay_driver$(EXE) \ + test/roc_driver$(EXE) test/rdbx_driver$(EXE) test/rtpw$(EXE) \ + test/dtls_srtp_driver$(EXE) + +$(testapp): libsrtp.a + +test/rtpw$(EXE): test/rtpw.c test/rtp.c test/getopt_s.c + $(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB) + +test/srtp_driver$(EXE): test/srtp_driver.c test/getopt_s.c + $(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB) + +test/rdbx_driver$(EXE): test/rdbx_driver.c test/getopt_s.c + $(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB) + +test/dtls_srtp_driver$(EXE): test/dtls_srtp_driver.c test/getopt_s.c + $(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB) + +test: $(testapp) + @echo "Build done. Please run '$(MAKE) runtest' to run self tests." + +memtest: test/srtp_driver + @test/srtp_driver -v -d "alloc" > tmp + @grep freed tmp | wc -l > freed + @grep allocated tmp | wc -l > allocated + @echo "checking for memory leaks (only works with --enable-stdout)" + cmp -s allocated freed + @echo "passed (same number of alloc() and dealloc() calls found)" + @rm freed allocated tmp + +# tables_apps are used to generate the tables used in the crypto +# implementations; these need only be generated during porting, not +# for building libsrtp or the test applications + +table_apps = tables/aes_tables + +build_table_apps: $(table_apps) + +# in the tables/ subdirectory, we use libcryptomath instead of libsrtp + +tables/%: tables/%.c libcryptomath.a + $(COMPILE) $(LDFLAGS) $< -o $@ $(LIBS) libcryptomath.a + +# the target 'plot' runs the timing test (test/srtp_driver -t) then +# uses gnuplot to produce plots of the results - see the script file +# 'timing' + +plot: test/srtp_driver + test/srtp_driver -t > timing.dat + + +# bookkeeping: tags, clean, and distribution + +tags: + etags */*.[ch] */*/*.[ch] + + +# documentation - the target libsrtpdoc builds a PDF file documenting +# libsrtp + +libsrtpdoc: + $(MAKE) -C doc + +.PHONY: clean superclean distclean install + +install: + @if [ -r $(DESTDIR)$(includedir)/srtp/srtp.h ]; then \ + echo "you should run 'make uninstall' first"; exit 1; \ + fi + $(INSTALL) -d $(DESTDIR)$(includedir)/srtp + $(INSTALL) -d $(DESTDIR)$(libdir) + cp $(srcdir)/include/*.h $(DESTDIR)$(includedir)/srtp + cp $(srcdir)/crypto/include/*.h $(DESTDIR)$(includedir)/srtp + if [ "$(srcdir)" != "." ]; then cp crypto/include/*.h $(DESTDIR)$(includedir)/srtp; fi + if [ -f libsrtp.a ]; then cp libsrtp.a $(DESTDIR)$(libdir)/; fi + +uninstall: + rm -f $(DESTDIR)$(includedir)/srtp/*.h + rm -f $(DESTDIR)$(libdir)/libsrtp.a + -rmdir $(DESTDIR)$(includedir)/srtp + +clean: + rm -rf $(cryptobj) $(srtpobj) $(cryptomath) TAGS \ + libcryptomath.a libsrtp.a core *.core test/core + for a in * */* */*/*; do \ + if [ -f "$$a~" ] ; then rm -f $$a~; fi; \ + done; + for a in $(testapp) $(table_apps); do rm -rf $$a$(EXE); done + rm -rf *.pict *.jpg *.dat + rm -rf freed allocated tmp + $(MAKE) -C doc clean + $(MAKE) -C crypto clean + + +superclean: clean + rm -rf crypto/include/config.h config.log config.cache config.status \ + Makefile crypto/Makefile doc/Makefile \ + .gdb_history test/.gdb_history .DS_Store + rm -rf autom4te.cache + +distclean: superclean + +distname = srtp-$(shell cat VERSION) + +distribution: runtest superclean + if ! [ -f VERSION ]; then exit 1; fi + if [ -f ../$(distname).tgz ]; then \ + mv ../$(distname).tgz ../$(distname).tgz.bak; \ + fi + cd ..; tar cvzf $(distname).tgz srtp + +# EOF diff --git a/src/libs/srtp/README b/src/libs/srtp/README new file mode 100644 index 00000000..08fafaed --- /dev/null +++ b/src/libs/srtp/README @@ -0,0 +1,174 @@ +Secure RTP (SRTP) Reference Implementation +David A. McGrew +Cisco Systems, Inc. +mcgrew@cisco.com + + +This package provides an implementation of the Secure Real-time +Transport Protocol (SRTP), the Universal Security Transform (UST), and +a supporting cryptographic kernel. These mechanisms are documented in +the Internet Drafts in the doc/ subdirectory. The SRTP API is +documented in include/srtp.h, and the library is in libsrtp.a (after +compilation). An overview and reference manual is available in +doc/libsrtp.pdf. The PDF documentation is more up to date than this +file. + + +Installation: + +./configure [ options ] # GNU autoconf script +make # or gmake if needed; use GNU make + +The configure script accepts the following options: + + --help provides a usage summary + --disable-debug compile without the runtime debugging system + --enable-syslog use syslog for error reporting + --disable-stdout use stdout for error reporting + --enable-console use /dev/console for error reporting + --gdoi use GDOI key management (disabled at present) + +By default, debbuging is enabled and stdout is used for debugging. +You can use the above configure options to have the debugging output +sent to syslog or the system console. Alternatively, you can define +ERR_REPORTING_FILE in include/conf.h to be any other file that can be +opened by libSRTP, and debug messages will be sent to it. + +This package has been tested on Mac OS X (powerpc-apple-darwin1.4), +Cygwin (i686-pc-cygwin), and Sparc (sparc-sun-solaris2.6). Previous +versions have been tested on Linux and OpenBSD on both x86 and sparc +platforms. + +A quick tour of this package: + +Makefile targets: all, clean, ... +README this file +CHANGES change log +VERSION version number of this package +LICENSE legal details (it's a BSD-like license) +crypto/ciphers/ ciphers (null, aes_icm, ...) +crypto/math/ crypto math routines +crypto/hash/ crypto hashing (hmac, tmmhv2, ...) +crypto/replay/ replay protection +doc/ documentation: rfcs, apis, and suchlike +include/ include files for all code in distribution +srtp/ secure real-time transport protocol implementation +tables/ apps for generating tables (useful in porting) +test/ test drivers + + +Applications + + Several test drivers and a simple and portable srtp application + are included in the test/ subdirectory. + + test driver function tested + ------------------------------------------------------------- + kernel_driver crypto kernel (ciphers, auth funcs, rng) + srtp_driver srtp in-memory tests (does not use the network) + rdbx_driver rdbx (extended replay database) + roc_driver extended sequence number functions + replay_driver replay database (n.b. not used in libsrtp) + cipher_driver ciphers + auth_driver hash functions + + The app rtpw is a simple rtp application which reads words from + /usr/dict/words and then sends them out one at a time using [s]rtp. + Manual srtp keying uses the -k option; automated key management + using gdoi will be added later. + +usage: rtpw [-d <debug>]* [-k <key> [-a][-e]] [-s | -r] dest_ip dest_port +or rtpw -l + + Either the -s (sender) or -r (receiver) option must be chosen. + + The values dest_ip, dest_port are the ip address and udp port to + which the dictionary will be sent, respectively. + + options: + + -s (s)rtp sender - causes app to send words + + -r (s)rtp receive - causes app to receve words + + -k <key> use srtp master key <key>, where the + key is a hexadecimal value (without the + leading "0x") + + -e encrypt/decrypt (for data confidentiality) + (requires use of -k option as well) + + -a message authentication + (requires use of -k option as well) + + -l list debug modules + + -d <debug> turn on debugging for module <debug> + + +In order to get random 30-byte values for use as key/salt pairs , you +can use the following bash function to format the output of +/dev/random (where that device is available). + +function randhex() { + cat /dev/random | od --read-bytes=32 --width=32 -x | awk '{ print $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 }' +} + + +An example of an SRTP session using two rtpw programs follows: + +set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451 + +[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999 +Security services: confidentiality message authentication +set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451 +setting SSRC to 2078917053 +sending word: A +sending word: a +sending word: aa +sending word: aal +... + +[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999 +security services: confidentiality message authentication +set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451 +19 octets received from SSRC 2078917053 word: A +19 octets received from SSRC 2078917053 word: a +20 octets received from SSRC 2078917053 word: aa +21 octets received from SSRC 2078917053 word: aal +... + +Implementation Notes + + * The srtp_protect() function assumes that the buffer holding the + rtp packet has enough storage allocated that the authentication + tag can be written to the end of that packet. If this assumption + is not valid, memory corruption will ensue. + + * Automated tests for the crypto functions are provided through + the cipher_type_self_test() and auth_type_self_test() functions. + These functions should be used to test each port of this code + to a new platform. + + * Replay protection is contained in the crypto engine, and + tests for it are provided. + + * This implementation provides calls to initialize, protect, and + unprotect RTP packets, and makes as few as possible assumptions + about how these functions will be called. For example, the + caller is not expected to provide packets in order (though if + they're called more than 65k out of sequence, synchronization + will be lost). + + * The sequence number in the rtp packet is used as the low 16 bits + of the sender's local packet index. Note that RTP will start its + sequence number in a random place, and the SRTP layer just jumps + forward to that number at its first invocation. An earlier + version of this library used initial sequence numbers that are + less than 32,768; this trick is no longer required as the + rdbx_estimate_index(...) function has been made smarter. + + * The replay window is 128 bits in length, and is hard-coded to this + value for now. + + diff --git a/src/libs/srtp/ReadMe.txt b/src/libs/srtp/ReadMe.txt new file mode 100644 index 00000000..d06adbdf --- /dev/null +++ b/src/libs/srtp/ReadMe.txt @@ -0,0 +1,22 @@ +======================================================================== + STATIC LIBRARY : srtp Project Overview +======================================================================== + +AppWizard has created this srtp library project for you. + +No source files were created as part of your project. + + +srtp.vcproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/src/libs/srtp/TODO b/src/libs/srtp/TODO new file mode 100644 index 00000000..18846e8a --- /dev/null +++ b/src/libs/srtp/TODO @@ -0,0 +1,66 @@ +TODO List + +1.4.1 + + - document which fields are in NBO/HBO, and check for consistency. + + - move HAVE_U_LONG_LONG inside of datatypes.c, or some other + separate file + + - re-write configure.in to make cross-compilation easier + + - eliminate GENERIC_AESICM by generalizing the code a bit + +Older comments + + - add tests for key_limit_t datatype + + - move octet_get_weight() from datatypes.c to math.c (any other + funcs?) + +Changes and additions planned + + Make cipher and auth dealloc() functions zeroize the key-storage + areas before calling free(). + + Eliminate key_len from auth_init() + + Doucument internal APIs (cipher, auth, srtp_protect, ...) + + +SRTP options not (yet) included in this libaray: + + - the aes-f8-mode cipher + - the Master Key Index + - re-keying using the key derivation function (only the initial + use of the PRF has been implemented, as it's sufficient + for most uses) + + +(OLD) PLANNED CHANGES + + strip out test/lfsr.c + + Write new documentation!!! + + Fix the x86 assembly code in aes.c. + + Eliminate /* DAM */ - there's one in srtp.c + + Change debugging so that it can print more than one line. Or perhaps + just change it so that a single check of the debug-enabled flag is + needed. + + Improve interface between cipher and rdbx - perhaps generalize rdbx + into 'nonce' datatype. + + Make rijndael_icm accept variable sized keys. + + Add rdbx functions that allow different-sized explicit sequence + numbers to be used. + + Write uniform byte-buffering code for PRFs, preferably as macros. + + Consider eliminating low-level alloc functions in favor of len() + functions, so that there need not be multiple allocations within a + particular alloc() function. diff --git a/src/libs/srtp/VERSION b/src/libs/srtp/VERSION new file mode 100644 index 00000000..1c99cf0e --- /dev/null +++ b/src/libs/srtp/VERSION @@ -0,0 +1 @@ +1.4.4 diff --git a/src/libs/srtp/config.guess b/src/libs/srtp/config.guess new file mode 100644 index 00000000..b02565c7 --- /dev/null +++ b/src/libs/srtp/config.guess @@ -0,0 +1,1517 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +timestamp='2011-06-03' + +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to <config-patches@gnu.org> and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free +Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include <sys/param.h> +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +and + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/libs/srtp/config.h_win32vc7 b/src/libs/srtp/config.h_win32vc7 new file mode 100644 index 00000000..44e6696c --- /dev/null +++ b/src/libs/srtp/config.h_win32vc7 @@ -0,0 +1,174 @@ +/* Hacked config.h for Windows XP 32-bit & VC7 */ + +#ifdef (_MSC_VER >= 1400) +# define HAVE_RAND_S 1 +#endif + +/* Define if building for a CISC machine (e.g. Intel). */ +#define CPU_CISC 1 + +/* Define if building for a RISC machine (assume slow byte access). */ +#undef CPU_RISC + +/* Path to random device */ +#undef DEV_URANDOM + +/* Define to compile in dynamic debugging system. */ +#undef ENABLE_DEBUGGING + +/* Report errors to this file. */ +#undef ERR_REPORTING_FILE + +/* Define to use logging to stdout. */ +#undef ERR_REPORTING_STDOUT + +/* Define this to use ISMAcryp code. */ +#undef GENERIC_AESICM + +/* Define to 1 if you have the <arpa/inet.h> header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the <byteswap.h> header file. */ +#undef HAVE_BYTESWAP_H + +/* Define to 1 if you have the `inet_aton' function. */ +#define HAVE_INET_ATON 1 + +/* Define to 1 if the system has the type `int16_t'. */ +#undef HAVE_INT16_T + +/* Define to 1 if the system has the type `int32_t'. */ +#undef HAVE_INT32_T + +/* Define to 1 if the system has the type `int8_t'. */ +#undef HAVE_INT8_T + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the <machine/types.h> header file. */ +#undef HAVE_MACHINE_TYPES_H + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the <netinet/in.h> header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <syslog.h> header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the <sys/int_types.h> header file. */ +#undef HAVE_SYS_INT_TYPES_H + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <sys/uio.h> header file. */ +#undef HAVE_SYS_UIO_H + +/* Define to 1 if the system has the type `uint16_t'. */ +#undef HAVE_UINT16_T + +/* Define to 1 if the system has the type `uint32_t'. */ +#undef HAVE_UINT32_T + +/* Define to 1 if the system has the type `uint64_t'. */ +#undef HAVE_UINT64_T + +/* Define to 1 if the system has the type `uint8_t'. */ +#undef HAVE_UINT8_T + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `usleep' function. */ +#define HAVE_USLEEP 1 + +/* Define to 1 if you have the <windows.h> header file. */ +#define HAVE_WINDOWS_H 1 + +/* Define to 1 if you have the <winsock2.h> header file. */ +#define HAVE_WINSOCK2_H 1 + +/* Define to use X86 inlined assembly code */ +#undef HAVE_X86 + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of a `unsigned long', as computed by sizeof. */ +#define SIZEOF_UNSIGNED_LONG 4 + +/* The size of a `unsigned long long', as computed by sizeof. */ +#define SIZEOF_UNSIGNED_LONG_LONG 8 + +/* Define to use GDOI. */ +#undef SRTP_GDOI + +/* Define to compile for kernel contexts. */ +#undef SRTP_KERNEL + +/* Define to compile for Linux kernel context. */ +#undef SRTP_KERNEL_LINUX + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Write errors to this file */ +#undef USE_ERR_REPORTING_FILE + +/* Define to use syslog logging. */ +#undef USE_SYSLOG + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define to empty if `const' does not conform to ANSI C. */ +//#undef const +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +//#ifndef __cplusplus +//#undef inline +//#endif +#define inline __inline + +/* Define to `unsigned' if <sys/types.h> does not define. */ +//#undef size_t diff --git a/src/libs/srtp/config.hw b/src/libs/srtp/config.hw new file mode 100644 index 00000000..39d4e073 --- /dev/null +++ b/src/libs/srtp/config.hw @@ -0,0 +1,196 @@ +/* crypto/include/config.h. Generated by configure. */ +/* config_in.h. Generated from configure.in by autoheader. */ + +#if (_MSC_VER >= 1400) +# define HAVE_RAND_S 1 +#endif + +/* Define if building for a CISC machine (e.g. Intel). */ +#define CPU_CISC 1 + +/* Define if building for a RISC machine (assume slow byte access). */ +/* #undef CPU_RISC */ + +/* Path to random device */ +/* #define DEV_URANDOM "/dev/urandom" */ + +/* Define to compile in dynamic debugging system. */ +#define ENABLE_DEBUGGING 1 + +/* Report errors to this file. */ +/* #undef ERR_REPORTING_FILE */ + +/* Define to use logging to stdout. */ +#define ERR_REPORTING_STDOUT 1 + +/* Define this to use ISMAcryp code. */ +/* #undef GENERIC_AESICM */ + +/* Define to 1 if you have the <arpa/inet.h> header file. */ +/* #undef HAVE_ARPA_INET_H */ + +/* Define to 1 if you have the <byteswap.h> header file. */ +/* #undef HAVE_BYTESWAP_H */ + +/* Define to 1 if you have the `inet_aton' function. */ +/* #undef HAVE_INET_ATON */ + +/* Define to 1 if the system has the type `int16_t'. */ +#define HAVE_INT16_T 1 + +/* Define to 1 if the system has the type `int32_t'. */ +#define HAVE_INT32_T 1 + +/* Define to 1 if the system has the type `int8_t'. */ +#define HAVE_INT8_T 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +/* #undef HAVE_INTTYPES_H */ + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the <machine/types.h> header file. */ +/* #undef HAVE_MACHINE_TYPES_H */ + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the <netinet/in.h> header file. */ +/* #undef HAVE_NETINET_IN_H */ + +/* Define to 1 if you have the `socket' function. */ +/* #undef HAVE_SOCKET */ + +/* Define to 1 if you have the <stdint.h> header file. */ +/* #undef HAVE_STDINT_H */ + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <syslog.h> header file. */ +/* #undef HAVE_SYSLOG_H */ + +/* Define to 1 if you have the <sys/int_types.h> header file. */ +/* #undef HAVE_SYS_INT_TYPES_H */ + +/* Define to 1 if you have the <sys/socket.h> header file. */ +/* #undef HAVE_SYS_SOCKET_H */ + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <sys/uio.h> header file. */ +/* #undef HAVE_SYS_UIO_H */ + +/* Define to 1 if the system has the type `uint16_t'. */ +#define HAVE_UINT16_T 1 + +/* Define to 1 if the system has the type `uint32_t'. */ +#define HAVE_UINT32_T 1 + +/* Define to 1 if the system has the type `uint64_t'. */ +#define HAVE_UINT64_T 1 + +/* Define to 1 if the system has the type `uint8_t'. */ +#define HAVE_UINT8_T 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +/* #undef HAVE_UNISTD_H */ + +/* Define to 1 if you have the `usleep' function. */ +/* #undef HAVE_USLEEP */ + +/* Define to 1 if you have the <windows.h> header file. */ +#define HAVE_WINDOWS_H 1 + +/* Define to 1 if you have the <winsock2.h> header file. */ +#define HAVE_WINSOCK2_H 1 + +/* Define to use X86 inlined assembly code */ +/* #undef HAVE_X86 */ + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* The size of a `unsigned long', as computed by sizeof. */ +#define SIZEOF_UNSIGNED_LONG 4 + +/* The size of a `unsigned long long', as computed by sizeof. */ +#define SIZEOF_UNSIGNED_LONG_LONG 8 + +/* Define to use GDOI. */ +/* #undef SRTP_GDOI */ + +/* Define to compile for kernel contexts. */ +/* #undef SRTP_KERNEL */ + +/* Define to compile for Linux kernel context. */ +/* #undef SRTP_KERNEL_LINUX */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Write errors to this file */ +/* #undef USE_ERR_REPORTING_FILE */ + +/* Define to use syslog logging. */ +/* #undef USE_SYSLOG */ + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define 'inline' to nothing, since the MSVC compiler doesn't support it. */ +#define inline + +/* Define to `unsigned' if <sys/types.h> does not define. */ +/* #undef size_t */ + +#if (_MSC_VER >= 1400) // VC8+ +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE +#endif +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE +#endif +#endif // VC8+ + +#ifndef uint32_t +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +#endif + +#ifdef _MSC_VER +#pragma warning(disable:4311) +#endif diff --git a/src/libs/srtp/config.sub b/src/libs/srtp/config.sub new file mode 100644 index 00000000..f9fcdc87 --- /dev/null +++ b/src/libs/srtp/config.sub @@ -0,0 +1,1756 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +timestamp='2011-06-03' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free +Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/libs/srtp/config_in.h b/src/libs/srtp/config_in.h new file mode 100644 index 00000000..be3459be --- /dev/null +++ b/src/libs/srtp/config_in.h @@ -0,0 +1,173 @@ +/* config_in.h. Generated from configure.in by autoheader. */ + +/* Define if building for a CISC machine (e.g. Intel). */ +#undef CPU_CISC + +/* Define if building for a RISC machine (assume slow byte access). */ +#undef CPU_RISC + +/* Path to random device */ +#undef DEV_URANDOM + +/* Define to compile in dynamic debugging system. */ +#undef ENABLE_DEBUGGING + +/* Report errors to this file. */ +#undef ERR_REPORTING_FILE + +/* Define to use logging to stdout. */ +#undef ERR_REPORTING_STDOUT + +/* Define this to use ISMAcryp code. */ +#undef GENERIC_AESICM + +/* Define to 1 if you have the <arpa/inet.h> header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the <byteswap.h> header file. */ +#undef HAVE_BYTESWAP_H + +/* Define to 1 if you have the `inet_aton' function. */ +#undef HAVE_INET_ATON + +/* Define to 1 if the system has the type `int16_t'. */ +#undef HAVE_INT16_T + +/* Define to 1 if the system has the type `int32_t'. */ +#undef HAVE_INT32_T + +/* Define to 1 if the system has the type `int8_t'. */ +#undef HAVE_INT8_T + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the <machine/types.h> header file. */ +#undef HAVE_MACHINE_TYPES_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the <netinet/in.h> header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <syslog.h> header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the <sys/int_types.h> header file. */ +#undef HAVE_SYS_INT_TYPES_H + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <sys/uio.h> header file. */ +#undef HAVE_SYS_UIO_H + +/* Define to 1 if the system has the type `uint16_t'. */ +#undef HAVE_UINT16_T + +/* Define to 1 if the system has the type `uint32_t'. */ +#undef HAVE_UINT32_T + +/* Define to 1 if the system has the type `uint64_t'. */ +#undef HAVE_UINT64_T + +/* Define to 1 if the system has the type `uint8_t'. */ +#undef HAVE_UINT8_T + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `usleep' function. */ +#undef HAVE_USLEEP + +/* Define to 1 if you have the <windows.h> header file. */ +#undef HAVE_WINDOWS_H + +/* Define to 1 if you have the <winsock2.h> header file. */ +#undef HAVE_WINSOCK2_H + +/* Define to use X86 inlined assembly code */ +#undef HAVE_X86 + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of a `unsigned long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG + +/* The size of a `unsigned long long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG_LONG + +/* Define to use GDOI. */ +#undef SRTP_GDOI + +/* Define to compile for kernel contexts. */ +#undef SRTP_KERNEL + +/* Define to compile for Linux kernel context. */ +#undef SRTP_KERNEL_LINUX + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Write errors to this file */ +#undef USE_ERR_REPORTING_FILE + +/* Define to use syslog logging. */ +#undef USE_SYSLOG + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `unsigned' if <sys/types.h> does not define. */ +#undef size_t diff --git a/src/libs/srtp/configure b/src/libs/srtp/configure new file mode 100644 index 00000000..68d2355d --- /dev/null +++ b/src/libs/srtp/configure @@ -0,0 +1,8607 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59. +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="srtp" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#if HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#if HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#if STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# if HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#if HAVE_STRINGS_H +# include <strings.h> +#endif +#if HAVE_INTTYPES_H +# include <inttypes.h> +#else +# if HAVE_STDINT_H +# include <stdint.h> +# endif +#endif +#if HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS RANLIB ac_ct_RANLIB CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA build build_cpu build_vendor build_os host host_cpu host_vendor host_os EXE RNG_OBJS CPP EGREP GDOI_OBJS LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-kernel-linux build library to run in Linux kernel context + --disable-debug do not compile in dynamic debugging system + --enable-generic-aesicm compile in changes for ISMAcryp + --enable-syslog use syslog for error reporting + --disable-stdout don't use stdout for error reporting + --enable-console use /dev/console for error reporting + --enable-gdoi enable GDOI key management + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have + headers in a nonstandard directory <include dir> + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + +if test -z "$CFLAGS"; then + CFLAGS="-Wall -O4 -fexpensive-optimizations -funroll-loops" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5 + (eval $ac_compiler --version </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5 + (eval $ac_compiler -v </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5 + (eval $ac_compiler -V </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include <stdlib.h> +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + + +echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/types.h> +#include <sys/param.h> + +int +main () +{ +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/types.h> +#include <sys/param.h> + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_bigendian=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +# It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then + ac_cv_c_bigendian=yes +fi +if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int +main () +{ + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long l; + char c[sizeof (long)]; + } u; + u.l = 1; + exit (u.c[sizeof (long) - 1] == 1); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6 +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + + +case $host_cpu in + i*86 ) + +cat >>confdefs.h <<\_ACEOF +#define CPU_CISC 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_X86 1 +_ACEOF +;; + * ) + # CPU_RISC is only supported for big endian machines. + if test "$ac_cv_c_bigendian" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define CPU_RISC 1 +_ACEOF + + else + cat >>confdefs.h <<\_ACEOF +#define CPU_CISC 1 +_ACEOF + + fi + ;; +esac + +case $host_os in + *cygwin*|*mingw* ) + EXE=.exe + HOST_IS_WINDOWS=yes + ;; + * ) + EXE="" + ;; +esac + # define executable suffix; this is needed for `make clean' + + +# Check whether --enable-kernel-linux or --disable-kernel-linux was given. +if test "${enable_kernel_linux+set}" = set; then + enableval="$enable_kernel_linux" + +else + enable_kernel_linux=no +fi; +echo "$as_me:$LINENO: checking whether to build for Linux kernel context" >&5 +echo $ECHO_N "checking whether to build for Linux kernel context... $ECHO_C" >&6 +if test "$enable_kernel_linux" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define SRTP_KERNEL 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define SRTP_KERNEL_LINUX 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: $enable_kernel_linux" >&5 +echo "${ECHO_T}$enable_kernel_linux" >&6 + +if test "$cross_compiling" != yes -a "$HOST_IS_WINDOWS" != yes; then + echo "$as_me:$LINENO: checking for /dev/urandom" >&5 +echo $ECHO_N "checking for /dev/urandom... $ECHO_C" >&6 +if test "${ac_cv_file__dev_urandom+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + test "$cross_compiling" = yes && + { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 +echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} + { (exit 1); exit 1; }; } +if test -r "/dev/urandom"; then + ac_cv_file__dev_urandom=yes +else + ac_cv_file__dev_urandom=no +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_file__dev_urandom" >&5 +echo "${ECHO_T}$ac_cv_file__dev_urandom" >&6 +if test $ac_cv_file__dev_urandom = yes; then + DEV_URANDOM=/dev/urandom +else + echo "$as_me:$LINENO: checking for /dev/random" >&5 +echo $ECHO_N "checking for /dev/random... $ECHO_C" >&6 +if test "${ac_cv_file__dev_random+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + test "$cross_compiling" = yes && + { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 +echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} + { (exit 1); exit 1; }; } +if test -r "/dev/random"; then + ac_cv_file__dev_random=yes +else + ac_cv_file__dev_random=no +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_file__dev_random" >&5 +echo "${ECHO_T}$ac_cv_file__dev_random" >&6 +if test $ac_cv_file__dev_random = yes; then + DEV_URANDOM=/dev/random +fi + +fi + +fi + +echo "$as_me:$LINENO: checking which random device to use" >&5 +echo $ECHO_N "checking which random device to use... $ECHO_C" >&6 +if test "$enable_kernel_linux" = "yes"; then + RNG_OBJS=rand_linux_kernel.o + echo "$as_me:$LINENO: result: Linux kernel builtin" >&5 +echo "${ECHO_T}Linux kernel builtin" >&6 +else + RNG_OBJS=rand_source.o + if test -n "$DEV_URANDOM"; then + +cat >>confdefs.h <<_ACEOF +#define DEV_URANDOM "$DEV_URANDOM" +_ACEOF + + echo "$as_me:$LINENO: result: $DEV_URANDOM" >&5 +echo "${ECHO_T}$DEV_URANDOM" >&6 + else + echo "$as_me:$LINENO: result: standard rand() function..." >&5 +echo "${ECHO_T}standard rand() function..." >&6 + fi +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ctype.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in stdlib.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in byteswap.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in stdint.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/uio.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in inttypes.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/types.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in machine/types.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/int_types.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + +for ac_header in sys/socket.h netinet/in.h arpa/inet.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in windows.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +for ac_header in winsock2.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +fi + +done + + + +for ac_header in syslog.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +echo "$as_me:$LINENO: checking for int8_t" >&5 +echo $ECHO_N "checking for int8_t... $ECHO_C" >&6 +if test "${ac_cv_type_int8_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((int8_t *) 0) + return 0; +if (sizeof (int8_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_int8_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_int8_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_int8_t" >&5 +echo "${ECHO_T}$ac_cv_type_int8_t" >&6 +if test $ac_cv_type_int8_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT8_T 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for uint8_t" >&5 +echo $ECHO_N "checking for uint8_t... $ECHO_C" >&6 +if test "${ac_cv_type_uint8_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((uint8_t *) 0) + return 0; +if (sizeof (uint8_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uint8_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_uint8_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uint8_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint8_t" >&6 +if test $ac_cv_type_uint8_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT8_T 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for int16_t" >&5 +echo $ECHO_N "checking for int16_t... $ECHO_C" >&6 +if test "${ac_cv_type_int16_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((int16_t *) 0) + return 0; +if (sizeof (int16_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_int16_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_int16_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_int16_t" >&5 +echo "${ECHO_T}$ac_cv_type_int16_t" >&6 +if test $ac_cv_type_int16_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT16_T 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for uint16_t" >&5 +echo $ECHO_N "checking for uint16_t... $ECHO_C" >&6 +if test "${ac_cv_type_uint16_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((uint16_t *) 0) + return 0; +if (sizeof (uint16_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uint16_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_uint16_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uint16_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint16_t" >&6 +if test $ac_cv_type_uint16_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT16_T 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for int32_t" >&5 +echo $ECHO_N "checking for int32_t... $ECHO_C" >&6 +if test "${ac_cv_type_int32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((int32_t *) 0) + return 0; +if (sizeof (int32_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_int32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_int32_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_int32_t" >&5 +echo "${ECHO_T}$ac_cv_type_int32_t" >&6 +if test $ac_cv_type_int32_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT32_T 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for uint32_t" >&5 +echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6 +if test "${ac_cv_type_uint32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((uint32_t *) 0) + return 0; +if (sizeof (uint32_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uint32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_uint32_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint32_t" >&6 +if test $ac_cv_type_uint32_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT32_T 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for uint64_t" >&5 +echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6 +if test "${ac_cv_type_uint64_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((uint64_t *) 0) + return 0; +if (sizeof (uint64_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uint64_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_uint64_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint64_t" >&6 +if test $ac_cv_type_uint64_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT64_T 1 +_ACEOF + + +fi + +echo "$as_me:$LINENO: checking for unsigned long" >&5 +echo $ECHO_N "checking for unsigned long... $ECHO_C" >&6 +if test "${ac_cv_type_unsigned_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((unsigned long *) 0) + return 0; +if (sizeof (unsigned long)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_unsigned_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_unsigned_long=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long" >&5 +echo "${ECHO_T}$ac_cv_type_unsigned_long" >&6 + +echo "$as_me:$LINENO: checking size of unsigned long" >&5 +echo $ECHO_N "checking size of unsigned long... $ECHO_C" >&6 +if test "${ac_cv_sizeof_unsigned_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_unsigned_long" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo= ac_hi= +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_unsigned_long=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (unsigned long), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +long longval () { return (long) (sizeof (unsigned long)); } +unsigned long ulongval () { return (long) (sizeof (unsigned long)); } +#include <stdio.h> +#include <stdlib.h> +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (unsigned long))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (unsigned long)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (unsigned long)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_unsigned_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (unsigned long), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_unsigned_long=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_unsigned_long" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long +_ACEOF + + +echo "$as_me:$LINENO: checking for unsigned long long" >&5 +echo $ECHO_N "checking for unsigned long long... $ECHO_C" >&6 +if test "${ac_cv_type_unsigned_long_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((unsigned long long *) 0) + return 0; +if (sizeof (unsigned long long)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_unsigned_long_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_unsigned_long_long=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long_long" >&5 +echo "${ECHO_T}$ac_cv_type_unsigned_long_long" >&6 + +echo "$as_me:$LINENO: checking size of unsigned long long" >&5 +echo $ECHO_N "checking size of unsigned long long... $ECHO_C" >&6 +if test "${ac_cv_sizeof_unsigned_long_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_unsigned_long_long" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo= ac_hi= +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (unsigned long long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_unsigned_long_long=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long long), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (unsigned long long), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +long longval () { return (long) (sizeof (unsigned long long)); } +unsigned long ulongval () { return (long) (sizeof (unsigned long long)); } +#include <stdio.h> +#include <stdlib.h> +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (unsigned long long))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (unsigned long long)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (unsigned long long)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_unsigned_long_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long long), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (unsigned long long), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_unsigned_long_long=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_long_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_unsigned_long_long" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long +_ACEOF + + + +echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_const=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6 +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_inline=$ac_kw; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6 + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6 +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((size_t *) 0) + return 0; +if (sizeof (size_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_size_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6 +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned +_ACEOF + +fi + + + + + + +for ac_func in socket inet_aton usleep sigaction +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +if test "x$ac_cv_func_socket" = "xno"; then + +echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 +echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_socket+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_socket=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_socket_socket=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6 +if test $ac_cv_lib_socket_socket = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + + echo "$as_me:$LINENO: checking for socket in -lwsock32" >&5 +echo $ECHO_N "checking for socket in -lwsock32... $ECHO_C" >&6 + SAVELIBS="$LIBS" + LIBS="$LIBS -lwsock32" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include <winsock2.h> + +int +main () +{ + +socket(0, 0, 0); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_socket=yes + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +LIBS="$SAVELIBS" + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +echo "$as_me:$LINENO: checking whether to compile in debugging" >&5 +echo $ECHO_N "checking whether to compile in debugging... $ECHO_C" >&6 +# Check whether --enable-debug or --disable-debug was given. +if test "${enable_debug+set}" = set; then + enableval="$enable_debug" + +else + enable_debug=yes +fi; +if test "$enable_debug" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define ENABLE_DEBUGGING 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: $enable_debug" >&5 +echo "${ECHO_T}$enable_debug" >&6 + +echo "$as_me:$LINENO: checking whether to use ISMAcryp code" >&5 +echo $ECHO_N "checking whether to use ISMAcryp code... $ECHO_C" >&6 +# Check whether --enable-generic-aesicm or --disable-generic-aesicm was given. +if test "${enable_generic_aesicm+set}" = set; then + enableval="$enable_generic_aesicm" + +else + enable_generic_aesicm=no +fi; +if test "$enable_generic_aesicm" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define GENERIC_AESICM 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: $enable_generic_aesicm" >&5 +echo "${ECHO_T}$enable_generic_aesicm" >&6 + +echo "$as_me:$LINENO: checking whether to use syslog for error reporting" >&5 +echo $ECHO_N "checking whether to use syslog for error reporting... $ECHO_C" >&6 +# Check whether --enable-syslog or --disable-syslog was given. +if test "${enable_syslog+set}" = set; then + enableval="$enable_syslog" + +else + enable_syslog=no +fi; +if test "$enable_syslog" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define USE_SYSLOG 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: $enable_syslog" >&5 +echo "${ECHO_T}$enable_syslog" >&6 + +echo "$as_me:$LINENO: checking whether to use stdout for error reporting" >&5 +echo $ECHO_N "checking whether to use stdout for error reporting... $ECHO_C" >&6 +# Check whether --enable-stdout or --disable-stdout was given. +if test "${enable_stdout+set}" = set; then + enableval="$enable_stdout" + +else + enable_stdout=yes +fi; +if test "$enable_stdout" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define ERR_REPORTING_STDOUT 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: $enable_stdout" >&5 +echo "${ECHO_T}$enable_stdout" >&6 + +echo "$as_me:$LINENO: checking whether to use /dev/console for error reporting" >&5 +echo $ECHO_N "checking whether to use /dev/console for error reporting... $ECHO_C" >&6 +# Check whether --enable-console or --disable-console was given. +if test "${enable_console+set}" = set; then + enableval="$enable_console" + +else + enable_console=no +fi; +if test "$enable_console" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define USE_ERR_REPORTING_FILE 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define ERR_REPORTING_FILE "/dev/console" +_ACEOF + +fi +echo "$as_me:$LINENO: result: $enable_console" >&5 +echo "${ECHO_T}$enable_console" >&6 + +echo "$as_me:$LINENO: checking whether to use GDOI key management" >&5 +echo $ECHO_N "checking whether to use GDOI key management... $ECHO_C" >&6 +# Check whether --enable-gdoi or --disable-gdoi was given. +if test "${enable_gdoi+set}" = set; then + enableval="$enable_gdoi" + +else + enable_gdoi=no +fi; +if test "$enable_gdoi" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define SRTP_GDOI 1 +_ACEOF + + GDOI_OBJS=gdoi/srtp+gdoi.o + +fi +echo "$as_me:$LINENO: result: $enable_gdoi" >&5 +echo "${ECHO_T}$enable_gdoi" >&6 + + ac_config_headers="$ac_config_headers crypto/include/config.h:config_in.h" + + + ac_config_files="$ac_config_files Makefile crypto/Makefile doc/Makefile" +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to <bug-autoconf@gnu.org>." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "crypto/Makefile" ) CONFIG_FILES="$CONFIG_FILES crypto/Makefile" ;; + "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "crypto/include/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS crypto/include/config.h:config_in.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@EXE@,$EXE,;t t +s,@RNG_OBJS@,$RNG_OBJS,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@GDOI_OBJS@,$GDOI_OBJS,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + + +# This is needed when building outside the source dir. +{ if $as_mkdir_p; then + mkdir -p crypto/ae_xfm + else + as_dir=crypto/ae_xfm + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/ae_xfm" >&5 +echo "$as_me: error: cannot create directory crypto/ae_xfm" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/cipher + else + as_dir=crypto/cipher + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/cipher" >&5 +echo "$as_me: error: cannot create directory crypto/cipher" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/hash + else + as_dir=crypto/hash + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/hash" >&5 +echo "$as_me: error: cannot create directory crypto/hash" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/kernel + else + as_dir=crypto/kernel + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/kernel" >&5 +echo "$as_me: error: cannot create directory crypto/kernel" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/math + else + as_dir=crypto/math + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/math" >&5 +echo "$as_me: error: cannot create directory crypto/math" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/replay + else + as_dir=crypto/replay + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/replay" >&5 +echo "$as_me: error: cannot create directory crypto/replay" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/rng + else + as_dir=crypto/rng + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/rng" >&5 +echo "$as_me: error: cannot create directory crypto/rng" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p crypto/test + else + as_dir=crypto/test + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory crypto/test" >&5 +echo "$as_me: error: cannot create directory crypto/test" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p doc + else + as_dir=doc + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory doc" >&5 +echo "$as_me: error: cannot create directory doc" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p srtp + else + as_dir=srtp + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory srtp" >&5 +echo "$as_me: error: cannot create directory srtp" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p tables + else + as_dir=tables + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory tables" >&5 +echo "$as_me: error: cannot create directory tables" >&2;} + { (exit 1); exit 1; }; }; } + +{ if $as_mkdir_p; then + mkdir -p test + else + as_dir=test + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory test" >&5 +echo "$as_me: error: cannot create directory test" >&2;} + { (exit 1); exit 1; }; }; } + diff --git a/src/libs/srtp/configure.in b/src/libs/srtp/configure.in new file mode 100644 index 00000000..8256e3af --- /dev/null +++ b/src/libs/srtp/configure.in @@ -0,0 +1,209 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(srtp) + +dnl Must come before AC_PROG_CC +if test -z "$CFLAGS"; then + dnl Default value for CFLAGS if not specified. + CFLAGS="-Wall -O4 -fexpensive-optimizations -funroll-loops" +fi + +dnl Checks for programs. +AC_PROG_RANLIB +AC_PROG_CC +AC_PROG_INSTALL + +dnl Check the byte order +AC_C_BIGENDIAN + +AC_CANONICAL_HOST + +dnl check host_cpu type, set defines appropriately +case $host_cpu in + i*86 ) + AC_DEFINE(CPU_CISC, 1, + [Define if building for a CISC machine (e.g. Intel).]) + AC_DEFINE(HAVE_X86, 1, + [Define to use X86 inlined assembly code]);; + * ) + # CPU_RISC is only supported for big endian machines. + if test "$ac_cv_c_bigendian" = "yes"; then + AC_DEFINE(CPU_RISC, 1, + [Define if building for a RISC machine (assume slow byte access).]) + else + AC_DEFINE(CPU_CISC, 1) + fi + ;; +esac + +dnl Check if we are on a Windows platform. +case $host_os in + *cygwin*|*mingw* ) + EXE=.exe + HOST_IS_WINDOWS=yes + ;; + * ) + EXE="" + ;; +esac +AC_SUBST(EXE) # define executable suffix; this is needed for `make clean' + + +AC_ARG_ENABLE(kernel-linux, + [AS_HELP_STRING([--enable-kernel-linux], + [build library to run in Linux kernel context])], + [], enable_kernel_linux=no) +AC_MSG_CHECKING(whether to build for Linux kernel context) +if test "$enable_kernel_linux" = "yes"; then + AC_DEFINE(SRTP_KERNEL, 1, + [Define to compile for kernel contexts.]) + AC_DEFINE(SRTP_KERNEL_LINUX, 1, + [Define to compile for Linux kernel context.]) +fi +AC_MSG_RESULT($enable_kernel_linux) + +if test "$cross_compiling" != yes -a "$HOST_IS_WINDOWS" != yes; then + dnl Check for /dev/urandom + AC_CHECK_FILE(/dev/urandom, DEV_URANDOM=/dev/urandom, + [AC_CHECK_FILE(/dev/random, DEV_URANDOM=/dev/random)]) +fi + +AC_MSG_CHECKING(which random device to use) +if test "$enable_kernel_linux" = "yes"; then + RNG_OBJS=rand_linux_kernel.o + AC_MSG_RESULT([Linux kernel builtin]) +else + RNG_OBJS=rand_source.o + if test -n "$DEV_URANDOM"; then + AC_DEFINE_UNQUOTED(DEV_URANDOM, "$DEV_URANDOM",[Path to random device]) + AC_MSG_RESULT([$DEV_URANDOM]) + else + AC_MSG_RESULT([standard rand() function...]) + fi +fi +AC_SUBST(RNG_OBJS) + + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(stdlib.h) +AC_CHECK_HEADERS(unistd.h) +AC_CHECK_HEADERS(byteswap.h) +AC_CHECK_HEADERS(stdint.h) +AC_CHECK_HEADERS(sys/uio.h) +AC_CHECK_HEADERS(inttypes.h) +AC_CHECK_HEADERS(sys/types.h) +AC_CHECK_HEADERS(machine/types.h) +AC_CHECK_HEADERS(sys/int_types.h) + +dnl socket() and friends +AC_CHECK_HEADERS(sys/socket.h netinet/in.h arpa/inet.h) +AC_CHECK_HEADERS(windows.h, [AC_CHECK_HEADERS(winsock2.h)]) + +AC_CHECK_HEADERS(syslog.h) + +AC_CHECK_TYPES([int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,uint64_t]) +AC_CHECK_SIZEOF(unsigned long) +AC_CHECK_SIZEOF(unsigned long long) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIZE_T + +dnl Checks for library functions. +AC_CHECK_FUNCS(socket inet_aton usleep sigaction) + +dnl Find socket function if not found yet. +if test "x$ac_cv_func_socket" = "xno"; then + AC_CHECK_LIB(socket, socket) + AC_MSG_CHECKING([for socket in -lwsock32]) + SAVELIBS="$LIBS" + LIBS="$LIBS -lwsock32" + AC_TRY_LINK([ +#include <winsock2.h> +],[ +socket(0, 0, 0); +], + ac_cv_func_socket=yes + AC_MSG_RESULT(yes), + LIBS="$SAVELIBS" + AC_MSG_RESULT(no)) +fi + +AC_MSG_CHECKING(whether to compile in debugging) +AC_ARG_ENABLE(debug, + [AS_HELP_STRING([--disable-debug], + [do not compile in dynamic debugging system])], + [], enable_debug=yes) +if test "$enable_debug" = "yes"; then + AC_DEFINE(ENABLE_DEBUGGING, 1, + [Define to compile in dynamic debugging system.]) +fi +AC_MSG_RESULT($enable_debug) + +AC_MSG_CHECKING(whether to use ISMAcryp code) +AC_ARG_ENABLE(generic-aesicm, + [AS_HELP_STRING([--enable-generic-aesicm], + [compile in changes for ISMAcryp])], + [], enable_generic_aesicm=no) +if test "$enable_generic_aesicm" = "yes"; then + AC_DEFINE(GENERIC_AESICM, 1, [Define this to use ISMAcryp code.]) +fi +AC_MSG_RESULT($enable_generic_aesicm) + +AC_MSG_CHECKING(whether to use syslog for error reporting) +AC_ARG_ENABLE(syslog, + [AS_HELP_STRING([--enable-syslog], [use syslog for error reporting])], + [], enable_syslog=no) +if test "$enable_syslog" = "yes"; then + AC_DEFINE(USE_SYSLOG, 1, [Define to use syslog logging.]) +fi +AC_MSG_RESULT($enable_syslog) + +AC_MSG_CHECKING(whether to use stdout for error reporting) +AC_ARG_ENABLE(stdout, + [AS_HELP_STRING([--disable-stdout], [don't use stdout for error reporting])], + [], enable_stdout=yes) +if test "$enable_stdout" = "yes"; then + AC_DEFINE(ERR_REPORTING_STDOUT, 1, [Define to use logging to stdout.]) +fi +AC_MSG_RESULT($enable_stdout) + +AC_MSG_CHECKING(whether to use /dev/console for error reporting) +AC_ARG_ENABLE(console, + [AS_HELP_STRING([--enable-console], [use /dev/console for error reporting])], + [], enable_console=no) +if test "$enable_console" = "yes"; then + AC_DEFINE(USE_ERR_REPORTING_FILE, 1, [Write errors to this file]) + AC_DEFINE(ERR_REPORTING_FILE, "/dev/console", [Report errors to this file.]) +fi +AC_MSG_RESULT($enable_console) + +AC_MSG_CHECKING(whether to use GDOI key management) +AC_ARG_ENABLE(gdoi, + [AS_HELP_STRING([--enable-gdoi], [enable GDOI key management])], + [], enable_gdoi=no) +if test "$enable_gdoi" = "yes"; then + AC_DEFINE(SRTP_GDOI, 1, [Define to use GDOI.]) + GDOI_OBJS=gdoi/srtp+gdoi.o + AC_SUBST(GDOI_OBJS) +fi +AC_MSG_RESULT($enable_gdoi) + +AC_CONFIG_HEADER(crypto/include/config.h:config_in.h) + +AC_OUTPUT(Makefile crypto/Makefile doc/Makefile) + +# This is needed when building outside the source dir. +AS_MKDIR_P(crypto/ae_xfm) +AS_MKDIR_P(crypto/cipher) +AS_MKDIR_P(crypto/hash) +AS_MKDIR_P(crypto/kernel) +AS_MKDIR_P(crypto/math) +AS_MKDIR_P(crypto/replay) +AS_MKDIR_P(crypto/rng) +AS_MKDIR_P(crypto/test) +AS_MKDIR_P(doc) +AS_MKDIR_P(srtp) +AS_MKDIR_P(tables) +AS_MKDIR_P(test) diff --git a/src/libs/srtp/crypto/Makefile b/src/libs/srtp/crypto/Makefile new file mode 100644 index 00000000..d7ac61fb --- /dev/null +++ b/src/libs/srtp/crypto/Makefile @@ -0,0 +1,130 @@ +# Makefile for libcryptomodule.a +# +# David A. McGrew +# Cisco Systems, Inc. + +srcdir = . +top_srcdir = .. +top_builddir = ../ + + +CC = gcc +INCDIR = -Iinclude -I$(srcdir)/include +DEFS = -DHAVE_CONFIG_H +CPPFLAGS= +CFLAGS = -Wall -O4 -fexpensive-optimizations -funroll-loops +LIBS = +LDFLAGS = -L. +COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS) +CRYPTOLIB = -lcryptomodule + +RANLIB = ranlib + +# EXE defines the suffix on executables - it's .exe for cygwin, and +# null on linux, bsd, and OS X and other OSes. we define this so that +# `make clean` will work on the cygwin platform +EXE = +# Random source. +RNG_OBJS = rand_source.o + +ifdef ARCH + DEFS += -D$(ARCH)=1 +endif + +ifdef sysname + DEFS += -D$(sysname)=1 +endif + +.PHONY: dummy all runtest clean superclean + +dummy : all runtest + +# test applications + +testapp = test/cipher_driver$(EXE) test/datatypes_driver$(EXE) \ + test/stat_driver$(EXE) test/sha1_driver$(EXE) \ + test/kernel_driver$(EXE) test/aes_calc$(EXE) test/rand_gen$(EXE) \ + test/env$(EXE) + +# data values used to test the aes_calc application + +k=000102030405060708090a0b0c0d0e0f +p=00112233445566778899aabbccddeeff +c=69c4e0d86a7b0430d8cdb78070b4c55a + +runtest: libcryptomodule.a $(testapp) + test/env$(EXE) # print out information on the build environment + @echo "running libcryptomodule test applications..." + test `test/aes_calc $k $p` = $c + test/cipher_driver$(EXE) -v >/dev/null + test/datatypes_driver$(EXE) -v >/dev/null + test/stat_driver$(EXE) >/dev/null + test/sha1_driver$(EXE) -v >/dev/null + test/kernel_driver$(EXE) -v >/dev/null + test/rand_gen$(EXE) -n 256 >/dev/null + @echo "libcryptomodule test applications passed." + +# libcryptomodule.a (the crypto engine) + +ciphers = cipher/cipher.o cipher/null_cipher.o \ + cipher/aes.o cipher/aes_icm.o \ + cipher/aes_cbc.o + +hashes = hash/null_auth.o hash/sha1.o \ + hash/hmac.o hash/auth.o + +math = math/datatypes.o math/stat.o + +rng = rng/$(RNG_OBJS) rng/rand_source.o rng/prng.o rng/ctr_prng.o + +err = kernel/err.o + +kernel = kernel/crypto_kernel.o kernel/alloc.o \ + kernel/key.o $(rng) $(err) + +xfm = ae_xfm/xfm.o + +cryptobj = $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(xfm) + +# the rule for making object files and test apps + +%.o: %.c + $(COMPILE) -c $< -o $@ + +%$(EXE): %.c libcryptomodule.a + $(COMPILE) $(LDFLAGS) $< -o $@ $(CRYPTOLIB) $(LIBS) + +ifndef AR + AR=ar +endif + +# and the crypto module library itself + +libcryptomodule.a: $(cryptobj) + $(AR) cr libcryptomodule.a $(cryptobj) + $(RANLIB) libcryptomodule.a + +all: libcryptomodule.a $(testapp) + +# housekeeping functions + +clean: + rm -f libcryptomodule.a + rm -f $(testapp) *.o */*.o + for a in * .* */*; do if [ -f "$$a~" ] ; then rm $$a~; fi; done; + rm -f `find . -name "*.[ch]~*~"` + rm -rf latex + +superclean: clean + rm -f *core TAGS ktrace.out + + +# the target 'package' builds a compressed tar archive of the source code + +distname = crypto-$(shell cat VERSION) + +package: superclean + cd ..; tar cvzf $(distname).tgz crypto/ + + +# EOF diff --git a/src/libs/srtp/crypto/Makefile.in b/src/libs/srtp/crypto/Makefile.in new file mode 100644 index 00000000..842d08e6 --- /dev/null +++ b/src/libs/srtp/crypto/Makefile.in @@ -0,0 +1,137 @@ +# Makefile for libcryptomodule.a +# +# David A. McGrew +# Cisco Systems, Inc. + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ +VPATH = @srcdir@ + +CC = @CC@ +INCDIR = -Iinclude -I$(srcdir)/include +DEFS = @DEFS@ +CPPFLAGS= @CPPFLAGS@ +CFLAGS = @CFLAGS@ +LIBS = @LIBS@ +LDFLAGS = @LDFLAGS@ -L. +COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS) +CRYPTOLIB = -lcryptomodule + +RANLIB = @RANLIB@ + +# EXE defines the suffix on executables - it's .exe for cygwin, and +# null on linux, bsd, and OS X and other OSes. we define this so that +# `make clean` will work on the cygwin platform +EXE = @EXE@ +# Random source. +RNG_OBJS = @RNG_OBJS@ + +ifdef ARCH + DEFS += -D$(ARCH)=1 +endif + +ifdef sysname + DEFS += -D$(sysname)=1 +endif + +.PHONY: dummy all runtest clean superclean + +dummy : all runtest + +# test applications + +testapp = test/cipher_driver$(EXE) test/datatypes_driver$(EXE) \ + test/stat_driver$(EXE) test/sha1_driver$(EXE) \ + test/kernel_driver$(EXE) test/aes_calc$(EXE) test/rand_gen$(EXE) \ + test/env$(EXE) + +# data values used to test the aes_calc application for AES-128 +k128=000102030405060708090a0b0c0d0e0f +p128=00112233445566778899aabbccddeeff +c128=69c4e0d86a7b0430d8cdb78070b4c55a + + +# data values used to test the aes_calc application for AES-256 +k256=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +p256=00112233445566778899aabbccddeeff +c256=8ea2b7ca516745bfeafc49904b496089 + + +runtest: libcryptomodule.a $(testapp) + test/env$(EXE) # print out information on the build environment + @echo "running libcryptomodule test applications..." + test `test/aes_calc $(k128) $(p128)` = $(c128) + test `test/aes_calc $(k256) $(p256)` = $(c256) + test/cipher_driver$(EXE) -v >/dev/null + test/datatypes_driver$(EXE) -v >/dev/null + test/stat_driver$(EXE) >/dev/null + test/sha1_driver$(EXE) -v >/dev/null + test/kernel_driver$(EXE) -v >/dev/null + test/rand_gen$(EXE) -n 256 >/dev/null + @echo "libcryptomodule test applications passed." + +# libcryptomodule.a (the crypto engine) + +ciphers = cipher/cipher.o cipher/null_cipher.o \ + cipher/aes.o cipher/aes_icm.o \ + cipher/aes_cbc.o + +hashes = hash/null_auth.o hash/sha1.o \ + hash/hmac.o hash/auth.o + +math = math/datatypes.o math/stat.o + +rng = rng/$(RNG_OBJS) rng/rand_source.o rng/prng.o rng/ctr_prng.o + +err = kernel/err.o + +kernel = kernel/crypto_kernel.o kernel/alloc.o \ + kernel/key.o $(rng) $(err) + +xfm = ae_xfm/xfm.o + +cryptobj = $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(xfm) + +# the rule for making object files and test apps + +%.o: %.c + $(COMPILE) -c $< -o $@ + +%$(EXE): %.c libcryptomodule.a + $(COMPILE) $(LDFLAGS) $< -o $@ $(CRYPTOLIB) $(LIBS) + +ifndef AR + AR=ar +endif + +# and the crypto module library itself + +libcryptomodule.a: $(cryptobj) + $(AR) cr libcryptomodule.a $(cryptobj) + $(RANLIB) libcryptomodule.a + +all: libcryptomodule.a $(testapp) + +# housekeeping functions + +clean: + rm -f libcryptomodule.a + rm -f $(testapp) *.o */*.o + for a in * .* */*; do if [ -f "$$a~" ] ; then rm $$a~; fi; done; + rm -f `find . -name "*.[ch]~*~"` + rm -rf latex + +superclean: clean + rm -f *core TAGS ktrace.out + + +# the target 'package' builds a compressed tar archive of the source code + +distname = crypto-$(shell cat VERSION) + +package: superclean + cd ..; tar cvzf $(distname).tgz crypto/ + + +# EOF diff --git a/src/libs/srtp/crypto/VERSION b/src/libs/srtp/crypto/VERSION new file mode 100644 index 00000000..3eefcb9d --- /dev/null +++ b/src/libs/srtp/crypto/VERSION @@ -0,0 +1 @@ +1.0.0 diff --git a/src/libs/srtp/crypto/ae_xfm/xfm.c b/src/libs/srtp/crypto/ae_xfm/xfm.c new file mode 100644 index 00000000..7aa33883 --- /dev/null +++ b/src/libs/srtp/crypto/ae_xfm/xfm.c @@ -0,0 +1,570 @@ +/* + * xfm.c + * + * Crypto transform implementation + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +#include "cryptoalg.h" +#include "aes_cbc.h" +#include "hmac.h" +#include "crypto_kernel.h" /* for crypto_get_random() */ + +#define KEY_LEN 16 +#define ENC_KEY_LEN 16 +#define MAC_KEY_LEN 16 +#define IV_LEN 16 +#define TAG_LEN 12 +#define MAX_EXPAND 27 + +err_status_t +aes_128_cbc_hmac_sha1_96_func(void *key, + void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len, + void *auth_tag) { + aes_cbc_ctx_t aes_ctx; + hmac_ctx_t hmac_ctx; + unsigned char enc_key[ENC_KEY_LEN]; + unsigned char mac_key[MAC_KEY_LEN]; + err_status_t status; + + /* check if we're doing authentication only */ + if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { + + /* perform authentication only */ + + } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { + + /* + * bad parameter - we expect either all three pointers to be NULL, + * or none of those pointers to be NULL + */ + return err_status_fail; + + } else { + + /* derive encryption and authentication keys from the input key */ + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); + if (status) return status; + + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); + if (status) return status; + + + /* perform encryption and authentication */ + + /* set aes key */ + status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_encrypt); + if (status) return status; + + /* set iv */ + status = crypto_get_random(iv, IV_LEN); + if (status) return status; + status = aes_cbc_set_iv(&aes_ctx, iv); + + /* encrypt the opaque data */ + status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len); + if (status) return status; + + /* authenticate clear and opaque data */ + status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); + if (status) return status; + + status = hmac_start(&hmac_ctx); + if (status) return status; + + status = hmac_update(&hmac_ctx, clear, clear_len); + if (status) return status; + + status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag); + if (status) return status; + + } + + return err_status_ok; +} + +err_status_t +aes_128_cbc_hmac_sha1_96_inv(void *key, + void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len, + void *auth_tag) { + aes_cbc_ctx_t aes_ctx; + hmac_ctx_t hmac_ctx; + unsigned char enc_key[ENC_KEY_LEN]; + unsigned char mac_key[MAC_KEY_LEN]; + unsigned char tmp_tag[TAG_LEN]; + unsigned char *tag = auth_tag; + err_status_t status; + int i; + + /* check if we're doing authentication only */ + if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { + + /* perform authentication only */ + + } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { + + /* + * bad parameter - we expect either all three pointers to be NULL, + * or none of those pointers to be NULL + */ + return err_status_fail; + + } else { + + /* derive encryption and authentication keys from the input key */ + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); + if (status) return status; + + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); + if (status) return status; + + /* perform encryption and authentication */ + + /* set aes key */ + status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_decrypt); + if (status) return status; + + /* set iv */ + status = rand_source_get_octet_string(iv, IV_LEN); + if (status) return status; + status = aes_cbc_set_iv(&aes_ctx, iv); + + /* encrypt the opaque data */ + status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len); + if (status) return status; + + /* authenticate clear and opaque data */ + status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); + if (status) return status; + + status = hmac_start(&hmac_ctx); + if (status) return status; + + status = hmac_update(&hmac_ctx, clear, clear_len); + if (status) return status; + + status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag); + if (status) return status; + + /* compare the computed tag with the one provided as input */ + for (i=0; i < TAG_LEN; i++) + if (tmp_tag[i] != tag[i]) + return err_status_auth_fail; + + } + + return err_status_ok; +} + + +#define ENC 1 + +#define DEBUG 0 + +err_status_t +aes_128_cbc_hmac_sha1_96_enc(void *key, + const void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len) { + aes_cbc_ctx_t aes_ctx; + hmac_ctx_t hmac_ctx; + unsigned char enc_key[ENC_KEY_LEN]; + unsigned char mac_key[MAC_KEY_LEN]; + unsigned char *auth_tag; + err_status_t status; + + /* check if we're doing authentication only */ + if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { + + /* perform authentication only */ + + } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { + + /* + * bad parameter - we expect either all three pointers to be NULL, + * or none of those pointers to be NULL + */ + return err_status_fail; + + } else { + +#if DEBUG + printf("ENC using key %s\n", octet_string_hex_string(key, KEY_LEN)); +#endif + + /* derive encryption and authentication keys from the input key */ + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); + if (status) return status; + + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); + if (status) return status; + + + /* perform encryption and authentication */ + + /* set aes key */ + status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_encrypt); + if (status) return status; + + /* set iv */ + status = rand_source_get_octet_string(iv, IV_LEN); + if (status) return status; + status = aes_cbc_set_iv(&aes_ctx, iv); + if (status) return status; + +#if DEBUG + printf("plaintext len: %d\n", *opaque_len); + printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); + printf("plaintext: %s\n", octet_string_hex_string(opaque, *opaque_len)); +#endif + +#if ENC + /* encrypt the opaque data */ + status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len); + if (status) return status; +#endif + +#if DEBUG + printf("ciphertext len: %d\n", *opaque_len); + printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len)); +#endif + + /* + * authenticate clear and opaque data, then write the + * authentication tag to the location immediately following the + * ciphertext + */ + status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); + if (status) return status; + + status = hmac_start(&hmac_ctx); + if (status) return status; + + status = hmac_update(&hmac_ctx, clear, clear_len); + if (status) return status; +#if DEBUG + printf("hmac input: %s\n", + octet_string_hex_string(clear, clear_len)); +#endif + auth_tag = (unsigned char *)opaque; + auth_tag += *opaque_len; + status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag); + if (status) return status; +#if DEBUG + printf("hmac input: %s\n", + octet_string_hex_string(opaque, *opaque_len)); +#endif + /* bump up the opaque_len to reflect the authentication tag */ + *opaque_len += TAG_LEN; + +#if DEBUG + printf("prot data len: %d\n", *opaque_len); + printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len)); +#endif + } + + return err_status_ok; +} + +err_status_t +aes_128_cbc_hmac_sha1_96_dec(void *key, + const void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len) { + aes_cbc_ctx_t aes_ctx; + hmac_ctx_t hmac_ctx; + unsigned char enc_key[ENC_KEY_LEN]; + unsigned char mac_key[MAC_KEY_LEN]; + unsigned char tmp_tag[TAG_LEN]; + unsigned char *auth_tag; + unsigned ciphertext_len; + err_status_t status; + int i; + + /* check if we're doing authentication only */ + if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { + + /* perform authentication only */ + + } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { + + /* + * bad parameter - we expect either all three pointers to be NULL, + * or none of those pointers to be NULL + */ + return err_status_fail; + + } else { +#if DEBUG + printf("DEC using key %s\n", octet_string_hex_string(key, KEY_LEN)); +#endif + + /* derive encryption and authentication keys from the input key */ + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); + if (status) return status; + + status = hmac_init(&hmac_ctx, key, KEY_LEN); + if (status) return status; + status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); + if (status) return status; + +#if DEBUG + printf("prot data len: %d\n", *opaque_len); + printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len)); +#endif + + /* + * set the protected data length to that of the ciphertext, by + * subtracting out the length of the authentication tag + */ + ciphertext_len = *opaque_len - TAG_LEN; + +#if DEBUG + printf("ciphertext len: %d\n", ciphertext_len); +#endif + /* verify the authentication tag */ + + /* + * compute the authentication tag for the clear and opaque data, + * and write it to a temporary location + */ + status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); + if (status) return status; + + status = hmac_start(&hmac_ctx); + if (status) return status; + + status = hmac_update(&hmac_ctx, clear, clear_len); + if (status) return status; + +#if DEBUG + printf("hmac input: %s\n", + octet_string_hex_string(clear, clear_len)); +#endif + + status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag); + if (status) return status; + +#if DEBUG + printf("hmac input: %s\n", + octet_string_hex_string(opaque, ciphertext_len)); +#endif + + /* + * compare the computed tag with the one provided as input (which + * immediately follows the ciphertext) + */ + auth_tag = (unsigned char *)opaque; + auth_tag += ciphertext_len; +#if DEBUG + printf("auth_tag: %s\n", octet_string_hex_string(auth_tag, TAG_LEN)); + printf("tmp_tag: %s\n", octet_string_hex_string(tmp_tag, TAG_LEN)); +#endif + for (i=0; i < TAG_LEN; i++) { + if (tmp_tag[i] != auth_tag[i]) + return err_status_auth_fail; + } + + /* bump down the opaque_len to reflect the authentication tag */ + *opaque_len -= TAG_LEN; + + /* decrypt the confidential data */ + status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_decrypt); + if (status) return status; + status = aes_cbc_set_iv(&aes_ctx, iv); + if (status) return status; + +#if DEBUG + printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len)); + printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); +#endif + +#if ENC + status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len); + if (status) return status; +#endif + +#if DEBUG + printf("plaintext len: %d\n", ciphertext_len); + printf("plaintext: %s\n", + octet_string_hex_string(opaque, ciphertext_len)); +#endif + + /* indicate the length of the plaintext */ + *opaque_len = ciphertext_len; + } + + return err_status_ok; +} + +cryptoalg_ctx_t cryptoalg_ctx = { + aes_128_cbc_hmac_sha1_96_enc, + aes_128_cbc_hmac_sha1_96_dec, + KEY_LEN, + IV_LEN, + TAG_LEN, + MAX_EXPAND, +}; + +cryptoalg_t cryptoalg = &cryptoalg_ctx; + +#define NULL_TAG_LEN 12 + +err_status_t +null_enc(void *key, + const void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len) { + int i; + unsigned char *auth_tag; + unsigned char *init_vec = iv; + + /* check if we're doing authentication only */ + if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { + + /* perform authentication only */ + + } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { + + /* + * bad parameter - we expect either all three pointers to be NULL, + * or none of those pointers to be NULL + */ + return err_status_fail; + + } else { + +#if DEBUG + printf("NULL ENC using key %s\n", octet_string_hex_string(key, KEY_LEN)); + printf("NULL_TAG_LEN: %d\n", NULL_TAG_LEN); + printf("plaintext len: %d\n", *opaque_len); +#endif + for (i=0; i < IV_LEN; i++) + init_vec[i] = i + (i * 16); +#if DEBUG + printf("iv: %s\n", + octet_string_hex_string(iv, IV_LEN)); + printf("plaintext: %s\n", + octet_string_hex_string(opaque, *opaque_len)); +#endif + auth_tag = opaque; + auth_tag += *opaque_len; + for (i=0; i < NULL_TAG_LEN; i++) + auth_tag[i] = i + (i * 16); + *opaque_len += NULL_TAG_LEN; +#if DEBUG + printf("protected data len: %d\n", *opaque_len); + printf("protected data: %s\n", + octet_string_hex_string(opaque, *opaque_len)); +#endif + + } + + return err_status_ok; +} + +err_status_t +null_dec(void *key, + const void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len) { + unsigned char *auth_tag; + + /* check if we're doing authentication only */ + if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { + + /* perform authentication only */ + + } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { + + /* + * bad parameter - we expect either all three pointers to be NULL, + * or none of those pointers to be NULL + */ + return err_status_fail; + + } else { + +#if DEBUG + printf("NULL DEC using key %s\n", octet_string_hex_string(key, KEY_LEN)); + + printf("protected data len: %d\n", *opaque_len); + printf("protected data: %s\n", + octet_string_hex_string(opaque, *opaque_len)); +#endif + auth_tag = opaque; + auth_tag += (*opaque_len - NULL_TAG_LEN); +#if DEBUG + printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); +#endif + *opaque_len -= NULL_TAG_LEN; +#if DEBUG + printf("plaintext len: %d\n", *opaque_len); + printf("plaintext: %s\n", + octet_string_hex_string(opaque, *opaque_len)); +#endif + } + + return err_status_ok; +} + +cryptoalg_ctx_t null_cryptoalg_ctx = { + null_enc, + null_dec, + KEY_LEN, + IV_LEN, + NULL_TAG_LEN, + MAX_EXPAND, +}; + +cryptoalg_t null_cryptoalg = &null_cryptoalg_ctx; + +int +cryptoalg_get_id(cryptoalg_t c) { + if (c == cryptoalg) + return 1; + return 0; +} + +cryptoalg_t +cryptoalg_find_by_id(int id) { + switch(id) { + case 1: + return cryptoalg; + default: + break; + } + return 0; +} diff --git a/src/libs/srtp/crypto/cipher/aes.c b/src/libs/srtp/crypto/cipher/aes.c new file mode 100644 index 00000000..a17b9e49 --- /dev/null +++ b/src/libs/srtp/crypto/cipher/aes.c @@ -0,0 +1,2065 @@ +/* + * aes.c + * + * An implemnetation of the AES block cipher. + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "aes.h" +#include "err.h" + +/* + * we use the tables T0, T1, T2, T3, and T4 to compute AES, and + * the tables U0, U1, U2, and U4 to compute its inverse + * + * different tables are used on little-endian (Intel, VMS) and + * big-endian processors (everything else) + * + * these tables are computed using the program tables/aes_tables; use + * this program to generate different tables for porting or + * optimization on a different platform + */ + +#ifndef WORDS_BIGENDIAN + +static uint32_t T0[256] = { + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, + 0xdf2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, + 0x50303060, 0x3010102, 0xa96767ce, 0x7d2b2b56, + 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, + 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, + 0x15fafaef, 0xeb5959b2, 0xc947478e, 0xbf0f0fb, + 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, + 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, + 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, + 0x5a36366c, 0x413f3f7e, 0x2f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x8f1f1f9, + 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, + 0xc040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, + 0x28181830, 0xa1969637, 0xf05050a, 0xb59a9a2f, + 0x907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, + 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, + 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, + 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, + 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, + 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x0, 0x2cededc1, + 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, + 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, + 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, + 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, + 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, + 0xcf45458a, 0x10f9f9e9, 0x6020204, 0x817f7ffe, + 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, + 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, + 0xad92923f, 0xbc9d9d21, 0x48383870, 0x4f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, + 0x30101020, 0x1affffe5, 0xef3f3fd, 0x6dd2d2bf, + 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, + 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, + 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, + 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, + 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, + 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, + 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, + 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, + 0xdb494992, 0xa06060c, 0x6c242448, 0xe45c5cb8, + 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, + 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, + 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, + 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, + 0xb46c6cd8, 0xfa5656ac, 0x7f4f4f3, 0x25eaeacf, + 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, + 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, + 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, + 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, + 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, + 0xd8484890, 0x5030306, 0x1f6f6f7, 0x120e0e1c, + 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, + 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, + 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, + 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, + 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, + 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, + 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, + 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, + 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c, +}; + +static uint32_t T1[256] = { + 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, + 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, + 0x30306050, 0x1010203, 0x6767cea9, 0x2b2b567d, + 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, + 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, + 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, + 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, + 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, + 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, + 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, + 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, + 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, + 0x404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, + 0x18183028, 0x969637a1, 0x5050a0f, 0x9a9a2fb5, + 0x7070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, + 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, + 0x909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, + 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, + 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, + 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, + 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, + 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, + 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, + 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, + 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, + 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, + 0x45458acf, 0xf9f9e910, 0x2020406, 0x7f7ffe81, + 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, + 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, + 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, + 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, + 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, + 0xcdcd814c, 0xc0c1814, 0x13132635, 0xececc32f, + 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, + 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, + 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, + 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, + 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, + 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, + 0xdedea779, 0x5e5ebce2, 0xb0b161d, 0xdbdbad76, + 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0xa0a141e, + 0x494992db, 0x6060c0a, 0x2424486c, 0x5c5cb8e4, + 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, + 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, + 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, + 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, + 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, + 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x8081018, + 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, + 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, + 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, + 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, + 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, + 0x484890d8, 0x3030605, 0xf6f6f701, 0xe0e1c12, + 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, + 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, + 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, + 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, + 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, + 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, + 0x8c8c038f, 0xa1a159f8, 0x89890980, 0xd0d1a17, + 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, + 0x414182c3, 0x999929b0, 0x2d2d5a77, 0xf0f1e11, + 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a, +}; + +static uint32_t T2[256] = { + 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, + 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, + 0x30605030, 0x1020301, 0x67cea967, 0x2b567d2b, + 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, + 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, + 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, + 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, + 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, + 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, + 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, + 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, + 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, + 0x4080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, + 0x18302818, 0x9637a196, 0x50a0f05, 0x9a2fb59a, + 0x70e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, + 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, + 0x9121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, + 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, + 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, + 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, + 0x53a6f553, 0xd1b968d1, 0x0, 0xedc12ced, + 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, + 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, + 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, + 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, + 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, + 0x458acf45, 0xf9e910f9, 0x2040602, 0x7ffe817f, + 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, + 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, + 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, + 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, + 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, + 0xcd814ccd, 0xc18140c, 0x13263513, 0xecc32fec, + 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, + 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, + 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, + 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, + 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, + 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, + 0xdea779de, 0x5ebce25e, 0xb161d0b, 0xdbad76db, + 0xe0db3be0, 0x32645632, 0x3a744e3a, 0xa141e0a, + 0x4992db49, 0x60c0a06, 0x24486c24, 0x5cb8e45c, + 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, + 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, + 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, + 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, + 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, + 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x8101808, + 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, + 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, + 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, + 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, + 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, + 0x4890d848, 0x3060503, 0xf6f701f6, 0xe1c120e, + 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, + 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, + 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, + 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, + 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, + 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, + 0x8c038f8c, 0xa159f8a1, 0x89098089, 0xd1a170d, + 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, + 0x4182c341, 0x9929b099, 0x2d5a772d, 0xf1e110f, + 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16, +}; + +static uint32_t T3[256] = { + 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, + 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, + 0x60503030, 0x2030101, 0xcea96767, 0x567d2b2b, + 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, + 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, + 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, + 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, + 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, + 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, + 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, + 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, + 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, + 0x80c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, + 0x30281818, 0x37a19696, 0xa0f0505, 0x2fb59a9a, + 0xe090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, + 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, + 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, + 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, + 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, + 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, + 0xa6f55353, 0xb968d1d1, 0x0, 0xc12ceded, + 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, + 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, + 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, + 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, + 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, + 0x8acf4545, 0xe910f9f9, 0x4060202, 0xfe817f7f, + 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, + 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x58a8f8f, + 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, + 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, + 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, + 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, + 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, + 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, + 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, + 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, + 0x44662222, 0x547e2a2a, 0x3bab9090, 0xb838888, + 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, + 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, + 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, + 0x92db4949, 0xc0a0606, 0x486c2424, 0xb8e45c5c, + 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, + 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, + 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, + 0x18c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, + 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, + 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, + 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, + 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, + 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, + 0x96dd4b4b, 0x61dcbdbd, 0xd868b8b, 0xf858a8a, + 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, + 0x90d84848, 0x6050303, 0xf701f6f6, 0x1c120e0e, + 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, + 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, + 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, + 0xd2bb6969, 0xa970d9d9, 0x7898e8e, 0x33a79494, + 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, + 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, + 0x38f8c8c, 0x59f8a1a1, 0x9808989, 0x1a170d0d, + 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, + 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, + 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616, +}; + +static uint32_t U0[256] = { + 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, + 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, + 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, + 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, + 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, + 0x2752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, + 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, + 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, + 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, + 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, + 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, + 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, + 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, + 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, + 0x728ebb2, 0x3c2b52f, 0x9a7bc586, 0xa50837d3, + 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, + 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, + 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, + 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, + 0x39ec830b, 0xaaef6040, 0x69f715e, 0x51106ebd, + 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, + 0xb58d5491, 0x55dc471, 0x6fd40604, 0xff155060, + 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, + 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, + 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x0, + 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, + 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, + 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, + 0xb1670a0c, 0xfe75793, 0xd296eeb4, 0x9e919b1b, + 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, + 0xaba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, + 0xb0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, + 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, + 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, + 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, + 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, + 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, + 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, + 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, + 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, + 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, + 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, + 0xe49d3a2c, 0xd927850, 0x9bcc5f6a, 0x62467e54, + 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, + 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, + 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, + 0x97826cd, 0xf418596e, 0x1b79aec, 0xa89a4f83, + 0x656e95e6, 0x7ee6ffaa, 0x8cfbc21, 0xe6e815ef, + 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, + 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, + 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, + 0x4a9804f1, 0xf7daec41, 0xe50cd7f, 0x2ff69117, + 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, + 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, + 0x4ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, + 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, + 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, + 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, + 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, + 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, + 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, + 0x72c31d16, 0xc25e2bc, 0x8b493c28, 0x41950dff, + 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, + 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0, +}; + +static uint32_t U1[256] = { + 0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, + 0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x3e34b93, + 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, + 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, + 0x5ab1de49, 0x1bba2567, 0xeea4598, 0xc0fe5de1, + 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, + 0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, + 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, + 0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, + 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, + 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, + 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, + 0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, + 0xd373ab23, 0x24b72e2, 0x8f1fe357, 0xab55662a, + 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x837d3a5, + 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, + 0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, + 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a, + 0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, + 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, + 0x8a213ef9, 0x6dd963d, 0x53eddae, 0xbde64d46, + 0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, + 0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, + 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db, + 0xa7ca147, 0xf427ce9, 0x1e84f8c9, 0x0, + 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, + 0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, + 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, + 0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, + 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, + 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, + 0xd090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, + 0x19f15785, 0x775af4c, 0xdd99eebb, 0x607fa3fd, + 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, + 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, + 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, + 0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, + 0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0, + 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, + 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, + 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0xbd49836, + 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, + 0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, + 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, + 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, + 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, + 0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, + 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, + 0x9be7bad9, 0x366f4ace, 0x99fead4, 0x7cb029d6, + 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, + 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, + 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, + 0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x496e4df, + 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, + 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, + 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, + 0x61d79a8c, 0xca1377a, 0x14f8598e, 0x3c13eb89, + 0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, + 0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, + 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, + 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, + 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, + 0x1a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, + 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042, +}; + +static uint32_t U2[256] = { + 0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, + 0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303, + 0x302055fa, 0x76adf66d, 0xcc889176, 0x2f5254c, + 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, + 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, + 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, + 0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, + 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, + 0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, + 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, + 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, + 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x8f9942b, + 0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, + 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, + 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, + 0x2830f287, 0xbf23b2a5, 0x302ba6a, 0x16ed5c82, + 0xcf8a2b1c, 0x79a792b4, 0x7f3f0f2, 0x694ea1e2, + 0xda65cdf4, 0x506d5be, 0x34d11f62, 0xa6c48afe, + 0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, + 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, + 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, + 0x5491b58d, 0xc471055d, 0x6046fd4, 0x5060ff15, + 0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, + 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee, + 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x0, + 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, + 0xefdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, + 0xf0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, + 0xa0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, + 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, + 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, + 0x90e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, + 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, + 0x1f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, + 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, + 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, + 0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, + 0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3, + 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, + 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, + 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, + 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf, + 0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, + 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, + 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, + 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, + 0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, + 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, + 0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, + 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, + 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, + 0x4f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, + 0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, + 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, + 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0xbfb2e41, + 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, + 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, + 0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, + 0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, + 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, + 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, + 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0xdff4195, + 0xa8397101, 0xc08deb3, 0xb4d89ce4, 0x566490c1, + 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257, +}; + +static uint32_t U3[256] = { + 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, + 0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3, + 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, + 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, + 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, + 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, + 0x3e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, + 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, + 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, + 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, + 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, + 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, + 0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, + 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, + 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, + 0x30f28728, 0x23b2a5bf, 0x2ba6a03, 0xed5c8216, + 0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, + 0x65cdf4da, 0x6d5be05, 0xd11f6234, 0xc48afea6, + 0x349d532e, 0xa2a055f3, 0x532e18a, 0xa475ebf6, + 0xb39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, + 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, + 0x91b58d54, 0x71055dc4, 0x46fd406, 0x60ff1550, + 0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, + 0xb0bd42e8, 0x7888b89, 0xe7385b19, 0x79dbeec8, + 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x0, + 0x9838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, + 0xfdfbff0e, 0xf563885, 0x3d1ed5ae, 0x3627392d, + 0xa64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, + 0xcb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, + 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, + 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, + 0xe0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, + 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, + 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, + 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, + 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, + 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, + 0x1d4b2f9e, 0xdcf330b2, 0xdec5286, 0x77d0e3c1, + 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, + 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, + 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, + 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad, + 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, + 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, + 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, + 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, + 0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, + 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, + 0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, + 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, + 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, + 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, + 0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, + 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165, + 0x9d04ea5e, 0x15d358c, 0xfa737487, 0xfb2e410b, + 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, + 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, + 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, + 0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, + 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, + 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, + 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, + 0x397101a8, 0x8deb30c, 0xd89ce4b4, 0x6490c156, + 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8, +}; + +#else /* assume big endian */ + +static uint32_t T0[256] = { + 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, + 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, + 0x60303050, 0x2010103, 0xce6767a9, 0x562b2b7d, + 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, + 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, + 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, + 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, + 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, + 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, + 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, + 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, + 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, + 0x804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, + 0x30181828, 0x379696a1, 0xa05050f, 0x2f9a9ab5, + 0xe070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, + 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, + 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, + 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, + 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, + 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, + 0xa65353f5, 0xb9d1d168, 0x0, 0xc1eded2c, + 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, + 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, + 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, + 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, + 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, + 0x8a4545cf, 0xe9f9f910, 0x4020206, 0xfe7f7f81, + 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, + 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x58f8f8a, + 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, + 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, + 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, + 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, + 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, + 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, + 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, + 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, + 0x44222266, 0x542a2a7e, 0x3b9090ab, 0xb888883, + 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, + 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, + 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, + 0x924949db, 0xc06060a, 0x4824246c, 0xb85c5ce4, + 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, + 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, + 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, + 0x18d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, + 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, + 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, + 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, + 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, + 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, + 0x964b4bdd, 0x61bdbddc, 0xd8b8b86, 0xf8a8a85, + 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, + 0x904848d8, 0x6030305, 0xf7f6f601, 0x1c0e0e12, + 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, + 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, + 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, + 0xd26969bb, 0xa9d9d970, 0x78e8e89, 0x339494a7, + 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, + 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, + 0x38c8c8f, 0x59a1a1f8, 0x9898980, 0x1a0d0d17, + 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, + 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, + 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a, +}; + +static uint32_t T1[256] = { + 0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, + 0xdfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5, + 0x50603030, 0x3020101, 0xa9ce6767, 0x7d562b2b, + 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, + 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, + 0x15effafa, 0xebb25959, 0xc98e4747, 0xbfbf0f0, + 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, + 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0, + 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, + 0x5a6c3636, 0x417e3f3f, 0x2f5f7f7, 0x4f83cccc, + 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x8f9f1f1, + 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, + 0xc080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, + 0x28301818, 0xa1379696, 0xf0a0505, 0xb52f9a9a, + 0x90e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, + 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, + 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, + 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, + 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, + 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484, + 0xf5a65353, 0x68b9d1d1, 0x0, 0x2cc1eded, + 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, + 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, + 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, + 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, + 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585, + 0xcf8a4545, 0x10e9f9f9, 0x6040202, 0x81fe7f7f, + 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, + 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, + 0xad3f9292, 0xbc219d9d, 0x48703838, 0x4f1f5f5, + 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, + 0x30201010, 0x1ae5ffff, 0xefdf3f3, 0x6dbfd2d2, + 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, + 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, + 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, + 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, + 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, + 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888, + 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, + 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, + 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, + 0xdb924949, 0xa0c0606, 0x6c482424, 0xe4b85c5c, + 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, + 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979, + 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, + 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, + 0xb4d86c6c, 0xfaac5656, 0x7f3f4f4, 0x25cfeaea, + 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, + 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, + 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6, + 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, + 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, + 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, + 0xd8904848, 0x5060303, 0x1f7f6f6, 0x121c0e0e, + 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, + 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e, + 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, + 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, + 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, + 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, + 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, + 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868, + 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, + 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616, +}; + +static uint32_t T2[256] = { + 0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, + 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5, + 0x30506030, 0x1030201, 0x67a9ce67, 0x2b7d562b, + 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, + 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, + 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, + 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, + 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0, + 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, + 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, + 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, + 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, + 0x40c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, + 0x18283018, 0x96a13796, 0x50f0a05, 0x9ab52f9a, + 0x7090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, + 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, + 0x91b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, + 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, + 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, + 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384, + 0x53f5a653, 0xd168b9d1, 0x0, 0xed2cc1ed, + 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, + 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, + 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, + 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, + 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185, + 0x45cf8a45, 0xf910e9f9, 0x2060402, 0x7f81fe7f, + 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, + 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, + 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, + 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, + 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2, + 0xcd4c81cd, 0xc14180c, 0x13352613, 0xec2fc3ec, + 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, + 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, + 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, + 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, + 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88, + 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, + 0xde79a7de, 0x5ee2bc5e, 0xb1d160b, 0xdb76addb, + 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0xa1e140a, + 0x49db9249, 0x60a0c06, 0x246c4824, 0x5ce4b85c, + 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, + 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279, + 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, + 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, + 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, + 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x8181008, + 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, + 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6, + 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, + 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, + 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, + 0x48d89048, 0x3050603, 0xf601f7f6, 0xe121c0e, + 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, + 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e, + 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, + 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, + 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, + 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, + 0x8c8f038c, 0xa1f859a1, 0x89800989, 0xd171a0d, + 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068, + 0x41c38241, 0x99b02999, 0x2d775a2d, 0xf111e0f, + 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16, +}; + +static uint32_t T3[256] = { + 0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, + 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491, + 0x30305060, 0x1010302, 0x6767a9ce, 0x2b2b7d56, + 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, + 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, + 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, + 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, + 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b, + 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, + 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, + 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, + 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, + 0x4040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, + 0x18182830, 0x9696a137, 0x5050f0a, 0x9a9ab52f, + 0x707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, + 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, + 0x9091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, + 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, + 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, + 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713, + 0x5353f5a6, 0xd1d168b9, 0x0, 0xeded2cc1, + 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, + 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, + 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, + 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, + 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411, + 0x4545cf8a, 0xf9f910e9, 0x2020604, 0x7f7f81fe, + 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, + 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, + 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, + 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, + 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf, + 0xcdcd4c81, 0xc0c1418, 0x13133526, 0xecec2fc3, + 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, + 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, + 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, + 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, + 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b, + 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, + 0xdede79a7, 0x5e5ee2bc, 0xb0b1d16, 0xdbdb76ad, + 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0xa0a1e14, + 0x4949db92, 0x6060a0c, 0x24246c48, 0x5c5ce4b8, + 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, + 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2, + 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, + 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, + 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, + 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x8081810, + 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, + 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197, + 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, + 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, + 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, + 0x4848d890, 0x3030506, 0xf6f601f7, 0xe0e121c, + 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, + 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927, + 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, + 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, + 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, + 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, + 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0xd0d171a, + 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0, + 0x4141c382, 0x9999b029, 0x2d2d775a, 0xf0f111e, + 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c, +}; + +static uint32_t U0[256] = { + 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, + 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, + 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, + 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, + 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, + 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, + 0x38f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, + 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, + 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, + 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, + 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, + 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, + 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, + 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, + 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, + 0x302887f2, 0x23bfa5b2, 0x2036aba, 0xed16825c, + 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, + 0x65daf4cd, 0x605bed5, 0xd134621f, 0xc4a6fe8a, + 0x342e539d, 0xa2f355a0, 0x58ae132, 0xa4f6eb75, + 0xb83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, + 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, + 0x91548db5, 0x71c45d05, 0x406d46f, 0x605015ff, + 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, + 0xb0e842bd, 0x7898b88, 0xe7195b38, 0x79c8eedb, + 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x0, + 0x9808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, + 0xfd0efffb, 0xf853856, 0x3daed51e, 0x362d3927, + 0xa0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, + 0xc0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, + 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, + 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, + 0xe090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, + 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, + 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, + 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, + 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, + 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, + 0x1d9e2f4b, 0xdcb230f3, 0xd8652ec, 0x77c1e3d0, + 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, + 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, + 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, + 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, + 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, + 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, + 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, + 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, + 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, + 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, + 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, + 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, + 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, + 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, + 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, + 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, + 0x9d5eea04, 0x18c355d, 0xfa877473, 0xfb0b412e, + 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, + 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, + 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, + 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, + 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, + 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, + 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, + 0x39a80171, 0x80cb3de, 0xd8b4e49c, 0x6456c190, + 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742 +}; + +static uint32_t U1[256] = { + 0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, + 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303, + 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, + 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, + 0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, + 0x2c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9, + 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, + 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8, + 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, + 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, + 0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, + 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b, + 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, + 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab, + 0x7b2eb28, 0x32fb5c2, 0x9a86c57b, 0xa5d33708, + 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, + 0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, + 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe, + 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, + 0x390b83ec, 0xaa4060ef, 0x65e719f, 0x51bd6e10, + 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, + 0xb591548d, 0x571c45d, 0x6f0406d4, 0xff605015, + 0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, + 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee, + 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x0, + 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72, + 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, + 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, + 0xb10c0a67, 0xf9357e7, 0xd2b4ee96, 0x9e1b9b91, + 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a, + 0xae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, + 0xb0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9, + 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, + 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, + 0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, + 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611, + 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, + 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3, + 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, + 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, + 0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, + 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf, + 0xe42c3a9d, 0xd507892, 0x9b6a5fcc, 0x62547e46, + 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af, + 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, + 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, + 0x9cd2678, 0xf46e5918, 0x1ec9ab7, 0xa8834f9a, + 0x65e6956e, 0x7eaaffe6, 0x821bccf, 0xe6ef15e8, + 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, + 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266, + 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, + 0x4af10498, 0xf741ecda, 0xe7fcd50, 0x2f1791f6, + 0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, + 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551, + 0x49d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, + 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647, + 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, + 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, + 0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, + 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db, + 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, + 0x72161dc3, 0xcbce225, 0x8b283c49, 0x41ff0d95, + 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, + 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857 +}; + +static uint32_t U2[256] = { + 0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, + 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x3934be3, + 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, + 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, + 0x5a49deb1, 0x1b6725ba, 0xe9845ea, 0xc0e15dfe, + 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3, + 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, + 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9, + 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, + 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, + 0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, + 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908, + 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, + 0xd323ab73, 0x2e2724b, 0x8f57e31f, 0xab2a6655, + 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x8a5d337, + 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, + 0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, + 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6, + 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, + 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e, + 0x8af93e21, 0x63d96dd, 0x5aedd3e, 0xbd464de6, + 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, + 0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, + 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8, + 0xa47a17c, 0xfe97c42, 0x1ec9f884, 0x0, + 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a, + 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, + 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, + 0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, + 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12, + 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, + 0xd0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e, + 0x198557f1, 0x74caf75, 0xddbbee99, 0x60fda37f, + 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, + 0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, + 0xdccad731, 0x85104263, 0x22401397, 0x112084c6, + 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, + 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1, + 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, + 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, + 0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0xb3698d4, + 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad, + 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, + 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3, + 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, + 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, + 0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, + 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15, + 0x9bd9bae7, 0x36ce4a6f, 0x9d4ea9f, 0x7cd629b0, + 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2, + 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, + 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, + 0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x4dfe496, + 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665, + 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, + 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6, + 0x618c9ad7, 0xc7a37a1, 0x148e59f8, 0x3c89eb13, + 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, + 0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, + 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844, + 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, + 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d, + 0x17139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, + 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8 +}; + +static uint32_t U3[256] = { + 0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, + 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b, + 0x30fa5520, 0x766df6ad, 0xcc769188, 0x24c25f5, + 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, + 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, + 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, + 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, + 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e, + 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, + 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, + 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, + 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x82b94f9, + 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, + 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66, + 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, + 0x2887f230, 0xbfa5b223, 0x36aba02, 0x16825ced, + 0xcf1c2b8a, 0x79b492a7, 0x7f2f0f3, 0x69e2a14e, + 0xdaf4cd65, 0x5bed506, 0x34621fd1, 0xa6fe8ac4, + 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, + 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd, + 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, + 0x548db591, 0xc45d0571, 0x6d46f04, 0x5015ff60, + 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, + 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, + 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x0, + 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c, + 0xefffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, + 0xfd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, + 0xa67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, + 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, + 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, + 0x90d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814, + 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, + 0x1269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, + 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, + 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, + 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, + 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077, + 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, + 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, + 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, + 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, + 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, + 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582, + 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, + 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, + 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, + 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, + 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, + 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035, + 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, + 0x4984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, + 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, + 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, + 0x5eea049d, 0x8c355d01, 0x877473fa, 0xb412efb, + 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d, + 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, + 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, + 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, + 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, + 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, + 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0xd9541ff, + 0xa8017139, 0xcb3de08, 0xb4e49cd8, 0x56c19064, + 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0 +}; + +#endif + +/* + * the following tables (aes_sbox, aes_inv_sbox, T4, U4) are + * endian-neutral + */ + +static uint8_t +aes_sbox[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +}; + +#ifndef CPU_RISC +static uint8_t +aes_inv_sbox[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, + 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, + 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, + 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, + 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, + 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, + 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, + 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, + 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, + 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, + 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +}; +#endif /* ! CPU_RISC */ + +#ifdef CPU_RISC +static uint32_t +T4[256] = { + 0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b, + 0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5, + 0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b, + 0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676, + 0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d, + 0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0, + 0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf, + 0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0, + 0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626, + 0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc, + 0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1, + 0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515, + 0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3, + 0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a, + 0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2, + 0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575, + 0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a, + 0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0, + 0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3, + 0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484, + 0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed, + 0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b, + 0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939, + 0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf, + 0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb, + 0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585, + 0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f, + 0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8, + 0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f, + 0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5, + 0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121, + 0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2, + 0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec, + 0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717, + 0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d, + 0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373, + 0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc, + 0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888, + 0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414, + 0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb, + 0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a, + 0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c, + 0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262, + 0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979, + 0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d, + 0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9, + 0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea, + 0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808, + 0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e, + 0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6, + 0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f, + 0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a, + 0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666, + 0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e, + 0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9, + 0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e, + 0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111, + 0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494, + 0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9, + 0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf, + 0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d, + 0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868, + 0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f, + 0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616 +}; + +static uint32_t U4[256] = { + 0x52525252, 0x9090909, 0x6a6a6a6a, 0xd5d5d5d5, + 0x30303030, 0x36363636, 0xa5a5a5a5, 0x38383838, + 0xbfbfbfbf, 0x40404040, 0xa3a3a3a3, 0x9e9e9e9e, + 0x81818181, 0xf3f3f3f3, 0xd7d7d7d7, 0xfbfbfbfb, + 0x7c7c7c7c, 0xe3e3e3e3, 0x39393939, 0x82828282, + 0x9b9b9b9b, 0x2f2f2f2f, 0xffffffff, 0x87878787, + 0x34343434, 0x8e8e8e8e, 0x43434343, 0x44444444, + 0xc4c4c4c4, 0xdededede, 0xe9e9e9e9, 0xcbcbcbcb, + 0x54545454, 0x7b7b7b7b, 0x94949494, 0x32323232, + 0xa6a6a6a6, 0xc2c2c2c2, 0x23232323, 0x3d3d3d3d, + 0xeeeeeeee, 0x4c4c4c4c, 0x95959595, 0xb0b0b0b, + 0x42424242, 0xfafafafa, 0xc3c3c3c3, 0x4e4e4e4e, + 0x8080808, 0x2e2e2e2e, 0xa1a1a1a1, 0x66666666, + 0x28282828, 0xd9d9d9d9, 0x24242424, 0xb2b2b2b2, + 0x76767676, 0x5b5b5b5b, 0xa2a2a2a2, 0x49494949, + 0x6d6d6d6d, 0x8b8b8b8b, 0xd1d1d1d1, 0x25252525, + 0x72727272, 0xf8f8f8f8, 0xf6f6f6f6, 0x64646464, + 0x86868686, 0x68686868, 0x98989898, 0x16161616, + 0xd4d4d4d4, 0xa4a4a4a4, 0x5c5c5c5c, 0xcccccccc, + 0x5d5d5d5d, 0x65656565, 0xb6b6b6b6, 0x92929292, + 0x6c6c6c6c, 0x70707070, 0x48484848, 0x50505050, + 0xfdfdfdfd, 0xedededed, 0xb9b9b9b9, 0xdadadada, + 0x5e5e5e5e, 0x15151515, 0x46464646, 0x57575757, + 0xa7a7a7a7, 0x8d8d8d8d, 0x9d9d9d9d, 0x84848484, + 0x90909090, 0xd8d8d8d8, 0xabababab, 0x0, + 0x8c8c8c8c, 0xbcbcbcbc, 0xd3d3d3d3, 0xa0a0a0a, + 0xf7f7f7f7, 0xe4e4e4e4, 0x58585858, 0x5050505, + 0xb8b8b8b8, 0xb3b3b3b3, 0x45454545, 0x6060606, + 0xd0d0d0d0, 0x2c2c2c2c, 0x1e1e1e1e, 0x8f8f8f8f, + 0xcacacaca, 0x3f3f3f3f, 0xf0f0f0f, 0x2020202, + 0xc1c1c1c1, 0xafafafaf, 0xbdbdbdbd, 0x3030303, + 0x1010101, 0x13131313, 0x8a8a8a8a, 0x6b6b6b6b, + 0x3a3a3a3a, 0x91919191, 0x11111111, 0x41414141, + 0x4f4f4f4f, 0x67676767, 0xdcdcdcdc, 0xeaeaeaea, + 0x97979797, 0xf2f2f2f2, 0xcfcfcfcf, 0xcececece, + 0xf0f0f0f0, 0xb4b4b4b4, 0xe6e6e6e6, 0x73737373, + 0x96969696, 0xacacacac, 0x74747474, 0x22222222, + 0xe7e7e7e7, 0xadadadad, 0x35353535, 0x85858585, + 0xe2e2e2e2, 0xf9f9f9f9, 0x37373737, 0xe8e8e8e8, + 0x1c1c1c1c, 0x75757575, 0xdfdfdfdf, 0x6e6e6e6e, + 0x47474747, 0xf1f1f1f1, 0x1a1a1a1a, 0x71717171, + 0x1d1d1d1d, 0x29292929, 0xc5c5c5c5, 0x89898989, + 0x6f6f6f6f, 0xb7b7b7b7, 0x62626262, 0xe0e0e0e, + 0xaaaaaaaa, 0x18181818, 0xbebebebe, 0x1b1b1b1b, + 0xfcfcfcfc, 0x56565656, 0x3e3e3e3e, 0x4b4b4b4b, + 0xc6c6c6c6, 0xd2d2d2d2, 0x79797979, 0x20202020, + 0x9a9a9a9a, 0xdbdbdbdb, 0xc0c0c0c0, 0xfefefefe, + 0x78787878, 0xcdcdcdcd, 0x5a5a5a5a, 0xf4f4f4f4, + 0x1f1f1f1f, 0xdddddddd, 0xa8a8a8a8, 0x33333333, + 0x88888888, 0x7070707, 0xc7c7c7c7, 0x31313131, + 0xb1b1b1b1, 0x12121212, 0x10101010, 0x59595959, + 0x27272727, 0x80808080, 0xecececec, 0x5f5f5f5f, + 0x60606060, 0x51515151, 0x7f7f7f7f, 0xa9a9a9a9, + 0x19191919, 0xb5b5b5b5, 0x4a4a4a4a, 0xd0d0d0d, + 0x2d2d2d2d, 0xe5e5e5e5, 0x7a7a7a7a, 0x9f9f9f9f, + 0x93939393, 0xc9c9c9c9, 0x9c9c9c9c, 0xefefefef, + 0xa0a0a0a0, 0xe0e0e0e0, 0x3b3b3b3b, 0x4d4d4d4d, + 0xaeaeaeae, 0x2a2a2a2a, 0xf5f5f5f5, 0xb0b0b0b0, + 0xc8c8c8c8, 0xebebebeb, 0xbbbbbbbb, 0x3c3c3c3c, + 0x83838383, 0x53535353, 0x99999999, 0x61616161, + 0x17171717, 0x2b2b2b2b, 0x4040404, 0x7e7e7e7e, + 0xbabababa, 0x77777777, 0xd6d6d6d6, 0x26262626, + 0xe1e1e1e1, 0x69696969, 0x14141414, 0x63636363, + 0x55555555, 0x21212121, 0xc0c0c0c, 0x7d7d7d7d +}; +#endif /* CPU_RISC */ + + +/* aes internals */ + +extern debug_module_t mod_aes_icm; + +static void +aes_128_expand_encryption_key(const uint8_t *key, + aes_expanded_key_t *expanded_key) { + int i; + gf2_8 rc; + + /* initialize round constant */ + rc = 1; + + expanded_key->num_rounds = 10; + + v128_copy_octet_string(&expanded_key->round[0], key); + +#if 0 + debug_print(mod_aes_icm, + "expanded key[0]: %s", v128_hex_string(&expanded_key->round[0])); +#endif + + /* loop over round keys */ + for (i=1; i < 11; i++) { + + /* munge first word of round key */ + expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i-1].v8[13]] ^ rc; + expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i-1].v8[14]]; + expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i-1].v8[15]]; + expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i-1].v8[12]]; + + expanded_key->round[i].v32[0] ^= expanded_key->round[i-1].v32[0]; + + /* set remaining 32 bit words to the exor of the one previous with + * the one four words previous */ + + expanded_key->round[i].v32[1] = + expanded_key->round[i].v32[0] ^ expanded_key->round[i-1].v32[1]; + + expanded_key->round[i].v32[2] = + expanded_key->round[i].v32[1] ^ expanded_key->round[i-1].v32[2]; + + expanded_key->round[i].v32[3] = + expanded_key->round[i].v32[2] ^ expanded_key->round[i-1].v32[3]; + +#if 0 + debug_print2(mod_aes_icm, + "expanded key[%d]: %s", i,v128_hex_string(&expanded_key->round[i])); +#endif + + /* modify round constant */ + rc = gf2_8_shift(rc); + + } +} + +static void +aes_256_expand_encryption_key(const unsigned char *key, + aes_expanded_key_t *expanded_key) { + int i; + gf2_8 rc; + + /* initialize round constant */ + rc = 1; + + expanded_key->num_rounds = 14; + + v128_copy_octet_string(&expanded_key->round[0], key); + v128_copy_octet_string(&expanded_key->round[1], key+16); + +#if 0 + debug_print(mod_aes_icm, + "expanded key[0]: %s", v128_hex_string(&expanded_key->round[0])); + debug_print(mod_aes_icm, + "expanded key[1]: %s", v128_hex_string(&expanded_key->round[1])); +#endif + + /* loop over rest of round keys */ + for (i=2; i < 15; i++) { + + /* munge first word of round key */ + if ((i & 1) == 0) { + expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i-1].v8[13]] ^ rc; + expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i-1].v8[14]]; + expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i-1].v8[15]]; + expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i-1].v8[12]]; + + /* modify round constant */ + rc = gf2_8_shift(rc); + } + else { + expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i-1].v8[12]]; + expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i-1].v8[13]]; + expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i-1].v8[14]]; + expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i-1].v8[15]]; + } + + expanded_key->round[i].v32[0] ^= expanded_key->round[i-2].v32[0]; + + /* set remaining 32 bit words to the exor of the one previous with + * the one eight words previous */ + + expanded_key->round[i].v32[1] = + expanded_key->round[i].v32[0] ^ expanded_key->round[i-2].v32[1]; + + expanded_key->round[i].v32[2] = + expanded_key->round[i].v32[1] ^ expanded_key->round[i-2].v32[2]; + + expanded_key->round[i].v32[3] = + expanded_key->round[i].v32[2] ^ expanded_key->round[i-2].v32[3]; + +#if 0 + debug_print2(mod_aes_icm, + "expanded key[%d]: %s", i,v128_hex_string(&expanded_key->round[i])); +#endif + + } +} + +err_status_t +aes_expand_encryption_key(const uint8_t *key, + int key_len, + aes_expanded_key_t *expanded_key) { + if (key_len == 16) { + aes_128_expand_encryption_key(key, expanded_key); + return err_status_ok; + } + else if (key_len == 24) { + /* AES-192 not yet supported */ + return err_status_bad_param; + } + else if (key_len == 32) { + aes_256_expand_encryption_key(key, expanded_key); + return err_status_ok; + } + else + return err_status_bad_param; +} + +err_status_t +aes_expand_decryption_key(const uint8_t *key, + int key_len, + aes_expanded_key_t *expanded_key) { + int i; + err_status_t status; + int num_rounds = expanded_key->num_rounds; + + status = aes_expand_encryption_key(key, key_len, expanded_key); + if (status) + return status; + + /* invert the order of the round keys */ + for (i=0; i < num_rounds/2; i++) { + v128_t tmp; + v128_copy(&tmp, &expanded_key->round[num_rounds-i]); + v128_copy(&expanded_key->round[num_rounds-i], &expanded_key->round[i]); + v128_copy(&expanded_key->round[i], &tmp); + } + + /* + * apply the inverse mixColumn transform to the round keys (except + * for the first and the last) + * + * mixColumn is implemented by using the tables U0, U1, U2, U3, + * followed by the T4 table (which cancels out the use of the sbox + * in the U-tables) + */ + for (i=1; i < num_rounds; i++) { +#ifdef CPU_RISC + uint32_t tmp; + + tmp = expanded_key->round[i].v32[0]; + expanded_key->round[i].v32[0] = + U0[T4[(tmp >> 24) ] & 0xff] ^ + U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ + U2[T4[(tmp >> 8) & 0xff] & 0xff] ^ + U3[T4[(tmp) & 0xff] & 0xff]; + + tmp = expanded_key->round[i].v32[1]; + expanded_key->round[i].v32[1] = + U0[T4[(tmp >> 24) ] & 0xff] ^ + U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ + U2[T4[(tmp >> 8) & 0xff] & 0xff] ^ + U3[T4[(tmp) & 0xff] & 0xff]; + + tmp = expanded_key->round[i].v32[2]; + expanded_key->round[i].v32[2] = + U0[T4[(tmp >> 24) ] & 0xff] ^ + U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ + U2[T4[(tmp >> 8) & 0xff] & 0xff] ^ + U3[T4[(tmp) & 0xff] & 0xff]; + + tmp = expanded_key->round[i].v32[3]; + expanded_key->round[i].v32[3] = + U0[T4[(tmp >> 24) ] & 0xff] ^ + U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ + U2[T4[(tmp >> 8) & 0xff] & 0xff] ^ + U3[T4[(tmp) & 0xff] & 0xff]; +#else /* assume CPU_CISC */ + + uint32_t c0, c1, c2, c3; + + c0 = U0[aes_sbox[expanded_key->round[i].v8[0]]] + ^ U1[aes_sbox[expanded_key->round[i].v8[1]]] + ^ U2[aes_sbox[expanded_key->round[i].v8[2]]] + ^ U3[aes_sbox[expanded_key->round[i].v8[3]]]; + + c1 = U0[aes_sbox[expanded_key->round[i].v8[4]]] + ^ U1[aes_sbox[expanded_key->round[i].v8[5]]] + ^ U2[aes_sbox[expanded_key->round[i].v8[6]]] + ^ U3[aes_sbox[expanded_key->round[i].v8[7]]]; + + c2 = U0[aes_sbox[expanded_key->round[i].v8[8]]] + ^ U1[aes_sbox[expanded_key->round[i].v8[9]]] + ^ U2[aes_sbox[expanded_key->round[i].v8[10]]] + ^ U3[aes_sbox[expanded_key->round[i].v8[11]]]; + + c3 = U0[aes_sbox[expanded_key->round[i].v8[12]]] + ^ U1[aes_sbox[expanded_key->round[i].v8[13]]] + ^ U2[aes_sbox[expanded_key->round[i].v8[14]]] + ^ U3[aes_sbox[expanded_key->round[i].v8[15]]]; + + expanded_key->round[i].v32[0] = c0; + expanded_key->round[i].v32[1] = c1; + expanded_key->round[i].v32[2] = c2; + expanded_key->round[i].v32[3] = c3; + +#endif + } + + return err_status_ok; +} + +#ifdef CPU_CISC + + +static inline void +aes_round(v128_t *state, const v128_t *round_key) { + uint32_t column0, column1, column2, column3; + + /* compute the columns of the output square in terms of the octets + of state, using the tables T0, T1, T2, T3 */ + + column0 = T0[state->v8[0]] ^ T1[state->v8[5]] + ^ T2[state->v8[10]] ^ T3[state->v8[15]]; + + column1 = T0[state->v8[4]] ^ T1[state->v8[9]] + ^ T2[state->v8[14]] ^ T3[state->v8[3]]; + + column2 = T0[state->v8[8]] ^ T1[state->v8[13]] + ^ T2[state->v8[2]] ^ T3[state->v8[7]]; + + column3 = T0[state->v8[12]] ^ T1[state->v8[1]] + ^ T2[state->v8[6]] ^ T3[state->v8[11]]; + + state->v32[0] = column0 ^ round_key->v32[0]; + state->v32[1] = column1 ^ round_key->v32[1]; + state->v32[2] = column2 ^ round_key->v32[2]; + state->v32[3] = column3 ^ round_key->v32[3]; + +} + + +static inline void +aes_inv_round(v128_t *state, const v128_t *round_key) { + uint32_t column0, column1, column2, column3; + + /* compute the columns of the output square in terms of the octets + of state, using the tables U0, U1, U2, U3 */ + + column0 = U0[state->v8[0]] ^ U1[state->v8[13]] + ^ U2[state->v8[10]] ^ U3[state->v8[7]]; + + column1 = U0[state->v8[4]] ^ U1[state->v8[1]] + ^ U2[state->v8[14]] ^ U3[state->v8[11]]; + + column2 = U0[state->v8[8]] ^ U1[state->v8[5]] + ^ U2[state->v8[2]] ^ U3[state->v8[15]]; + + column3 = U0[state->v8[12]] ^ U1[state->v8[9]] + ^ U2[state->v8[6]] ^ U3[state->v8[3]]; + + state->v32[0] = column0 ^ round_key->v32[0]; + state->v32[1] = column1 ^ round_key->v32[1]; + state->v32[2] = column2 ^ round_key->v32[2]; + state->v32[3] = column3 ^ round_key->v32[3]; + +} + +static inline void +aes_final_round(v128_t *state, const v128_t *round_key) { + uint8_t tmp; + + /* byte substitutions and row shifts */ + /* first row - no shift */ + state->v8[0] = aes_sbox[state->v8[0]]; + state->v8[4] = aes_sbox[state->v8[4]]; + state->v8[8] = aes_sbox[state->v8[8]]; + state->v8[12] = aes_sbox[state->v8[12]]; + + /* second row - shift one left */ + tmp = aes_sbox[state->v8[1]]; + state->v8[1] = aes_sbox[state->v8[5]]; + state->v8[5] = aes_sbox[state->v8[9]]; + state->v8[9] = aes_sbox[state->v8[13]]; + state->v8[13] = tmp; + + /* third row - shift two left */ + tmp = aes_sbox[state->v8[10]]; + state->v8[10] = aes_sbox[state->v8[2]]; + state->v8[2] = tmp; + tmp = aes_sbox[state->v8[14]]; + state->v8[14] = aes_sbox[state->v8[6]]; + state->v8[6] = tmp; + + /* fourth row - shift three left */ + tmp = aes_sbox[state->v8[15]]; + state->v8[15] = aes_sbox[state->v8[11]]; + state->v8[11] = aes_sbox[state->v8[7]]; + state->v8[7] = aes_sbox[state->v8[3]]; + state->v8[3] = tmp; + + v128_xor_eq(state, round_key); +} + +static inline void +aes_inv_final_round(v128_t *state, const v128_t *round_key) { + uint8_t tmp; + + /* byte substitutions and row shifts */ + /* first row - no shift */ + state->v8[0] = aes_inv_sbox[state->v8[0]]; + state->v8[4] = aes_inv_sbox[state->v8[4]]; + state->v8[8] = aes_inv_sbox[state->v8[8]]; + state->v8[12] = aes_inv_sbox[state->v8[12]]; + + /* second row - shift one right */ + tmp = aes_inv_sbox[state->v8[13]]; + state->v8[13] = aes_inv_sbox[state->v8[9]]; + state->v8[9] = aes_inv_sbox[state->v8[5]]; + state->v8[5] = aes_inv_sbox[state->v8[1]]; + state->v8[1] = tmp; + + /* third row - shift two right */ + tmp = aes_inv_sbox[state->v8[2]]; + state->v8[2] = aes_inv_sbox[state->v8[10]]; + state->v8[10] = tmp; + tmp = aes_inv_sbox[state->v8[6]]; + state->v8[6] = aes_inv_sbox[state->v8[14]]; + state->v8[14] = tmp; + + /* fourth row - shift three right */ + tmp = aes_inv_sbox[state->v8[3]]; + state->v8[3] = aes_inv_sbox[state->v8[7]]; + state->v8[7] = aes_inv_sbox[state->v8[11]]; + state->v8[11] = aes_inv_sbox[state->v8[15]]; + state->v8[15] = tmp; + + v128_xor_eq(state, round_key); +} + + +#elif CPU_RISC + +static inline void +aes_round(v128_t *state, const v128_t *round_key) { + uint32_t column0, column1, column2, column3; + + /* compute the columns of the output square in terms of the octets + of state, using the tables T0, T1, T2, T3 */ +#ifdef WORDS_BIGENDIAN + column0 = T0[state->v32[0] >> 24] ^ T1[(state->v32[1] >> 16) & 0xff] + ^ T2[(state->v32[2] >> 8) & 0xff] ^ T3[state->v32[3] & 0xff]; + + column1 = T0[state->v32[1] >> 24] ^ T1[(state->v32[2] >> 16) & 0xff] + ^ T2[(state->v32[3] >> 8) & 0xff] ^ T3[state->v32[0] & 0xff]; + + column2 = T0[state->v32[2] >> 24] ^ T1[(state->v32[3] >> 16) & 0xff] + ^ T2[(state->v32[0] >> 8) & 0xff] ^ T3[state->v32[1] & 0xff]; + + column3 = T0[state->v32[3] >> 24] ^ T1[(state->v32[0] >> 16) & 0xff] + ^ T2[(state->v32[1] >> 8) & 0xff] ^ T3[state->v32[2] & 0xff]; +#else + column0 = T0[state->v32[0] & 0xff] ^ T1[(state->v32[1] >> 8) & 0xff] + ^ T2[(state->v32[2] >> 16) & 0xff] ^ T3[state->v32[3] >> 24]; + + column1 = T0[state->v32[1] & 0xff] ^ T1[(state->v32[2] >> 8) & 0xff] + ^ T2[(state->v32[3] >> 16) & 0xff] ^ T3[state->v32[0] >> 24]; + + column2 = T0[state->v32[2] & 0xff] ^ T1[(state->v32[3] >> 8) & 0xff] + ^ T2[(state->v32[0] >> 16) & 0xff] ^ T3[state->v32[1] >> 24]; + + column3 = T0[state->v32[3] & 0xff] ^ T1[(state->v32[0] >> 8) & 0xff] + ^ T2[(state->v32[1] >> 16) & 0xff] ^ T3[state->v32[2] >> 24]; +#endif /* WORDS_BIGENDIAN */ + + state->v32[0] = column0 ^ round_key->v32[0]; + state->v32[1] = column1 ^ round_key->v32[1]; + state->v32[2] = column2 ^ round_key->v32[2]; + state->v32[3] = column3 ^ round_key->v32[3]; + +} + +static inline void +aes_inv_round(v128_t *state, const v128_t *round_key) { + uint32_t column0, column1, column2, column3; + + /* compute the columns of the output square in terms of the octets + of state, using the tables U0, U1, U2, U3 */ + +#ifdef WORDS_BIGENDIAN + /* FIX! WRong indexes */ + column0 = U0[state->v32[0] >> 24] ^ U1[(state->v32[3] >> 16) & 0xff] + ^ U2[(state->v32[2] >> 8) & 0xff] ^ U3[state->v32[1] & 0xff]; + + column1 = U0[state->v32[1] >> 24] ^ U1[(state->v32[0] >> 16) & 0xff] + ^ U2[(state->v32[3] >> 8) & 0xff] ^ U3[state->v32[2] & 0xff]; + + column2 = U0[state->v32[2] >> 24] ^ U1[(state->v32[1] >> 16) & 0xff] + ^ U2[(state->v32[0] >> 8) & 0xff] ^ U3[state->v32[3] & 0xff]; + + column3 = U0[state->v32[3] >> 24] ^ U1[(state->v32[2] >> 16) & 0xff] + ^ U2[(state->v32[1] >> 8) & 0xff] ^ U3[state->v32[0] & 0xff]; +#else + column0 = U0[state->v32[0] & 0xff] ^ U1[(state->v32[1] >> 8) & 0xff] + ^ U2[(state->v32[2] >> 16) & 0xff] ^ U3[state->v32[3] >> 24]; + + column1 = U0[state->v32[1] & 0xff] ^ U1[(state->v32[2] >> 8) & 0xff] + ^ U2[(state->v32[3] >> 16) & 0xff] ^ U3[state->v32[0] >> 24]; + + column2 = U0[state->v32[2] & 0xff] ^ U1[(state->v32[3] >> 8) & 0xff] + ^ U2[(state->v32[0] >> 16) & 0xff] ^ U3[state->v32[1] >> 24]; + + column3 = U0[state->v32[3] & 0xff] ^ U1[(state->v32[0] >> 8) & 0xff] + ^ U2[(state->v32[1] >> 16) & 0xff] ^ U3[state->v32[2] >> 24]; +#endif /* WORDS_BIGENDIAN */ + + state->v32[0] = column0 ^ round_key->v32[0]; + state->v32[1] = column1 ^ round_key->v32[1]; + state->v32[2] = column2 ^ round_key->v32[2]; + state->v32[3] = column3 ^ round_key->v32[3]; + +} + +static inline void +aes_final_round(v128_t *state, const v128_t *round_key) { + uint32_t tmp0, tmp1, tmp2, tmp3; + + tmp0 = (T4[(state->v32[0] >> 24)] & 0xff000000) + ^ (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) + ^ (T4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00) + ^ (T4[(state->v32[3] ) & 0xff] & 0x000000ff) + ^ round_key->v32[0]; + + tmp1 = (T4[(state->v32[1] >> 24)] & 0xff000000) + ^ (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) + ^ (T4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00) + ^ (T4[(state->v32[0] ) & 0xff] & 0x000000ff) + ^ round_key->v32[1]; + + tmp2 = (T4[(state->v32[2] >> 24)] & 0xff000000) + ^ (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) + ^ (T4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00) + ^ (T4[(state->v32[1] ) & 0xff] & 0x000000ff) + ^ round_key->v32[2]; + + tmp3 = (T4[(state->v32[3] >> 24)] & 0xff000000) + ^ (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) + ^ (T4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00) + ^ (T4[(state->v32[2] ) & 0xff] & 0x000000ff) + ^ round_key->v32[3]; + + state->v32[0] = tmp0; + state->v32[1] = tmp1; + state->v32[2] = tmp2; + state->v32[3] = tmp3; + +} + +static inline void +aes_inv_final_round(v128_t *state, const v128_t *round_key) { + uint32_t tmp0, tmp1, tmp2, tmp3; + + tmp0 = (U4[(state->v32[0] >> 24)] & 0xff000000) + ^ (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) + ^ (U4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00) + ^ (U4[(state->v32[1] ) & 0xff] & 0x000000ff) + ^ round_key->v32[0]; + + tmp1 = (U4[(state->v32[1] >> 24)] & 0xff000000) + ^ (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) + ^ (U4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00) + ^ (U4[(state->v32[2] ) & 0xff] & 0x000000ff) + ^ round_key->v32[1]; + + tmp2 = (U4[(state->v32[2] >> 24)] & 0xff000000) + ^ (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) + ^ (U4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00) + ^ (U4[(state->v32[3] ) & 0xff] & 0x000000ff) + ^ round_key->v32[2]; + + tmp3 = (U4[(state->v32[3] >> 24)] & 0xff000000) + ^ (U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) + ^ (U4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00) + ^ (U4[(state->v32[0] ) & 0xff] & 0x000000ff) + ^ round_key->v32[3]; + + state->v32[0] = tmp0; + state->v32[1] = tmp1; + state->v32[2] = tmp2; + state->v32[3] = tmp3; + +} + +#elif CPU_16 /* assume 16-bit word size on processor */ + +static inline void +aes_round(v128_t *state, const v128_t *round_key) { + uint32_t column0, column1, column2, column3; + uint16_t c + /* compute the columns of the output square in terms of the octets + of state, using the tables T0, T1, T2, T3 */ + + column0 = T0[state->v8[0]] ^ T1[state->v8[5]] + ^ T2[state->v8[10]] ^ T3[state->v8[15]]; + + column1 = T0[state->v8[4]] ^ T1[state->v8[9]] + ^ T2[state->v8[14]] ^ T3[state->v8[3]]; + + column2 = T0[state->v8[8]] ^ T1[state->v8[13]] + ^ T2[state->v8[2]] ^ T3[state->v8[7]]; + + column3 = T0[state->v8[12]] ^ T1[state->v8[1]] + ^ T2[state->v8[6]] ^ T3[state->v8[11]]; + + state->v32[0] = column0 ^ round_key->v32[0]; + state->v32[1] = column1 ^ round_key->v32[1]; + state->v32[2] = column2 ^ round_key->v32[2]; + state->v32[3] = column3 ^ round_key->v32[3]; + +} + + +static inline void +aes_inv_round(v128_t *state, const v128_t *round_key) { + uint32_t column0, column1, column2, column3; + + /* compute the columns of the output square in terms of the octets + of state, using the tables U0, U1, U2, U3 */ + + column0 = U0[state->v8[0]] ^ U1[state->v8[5]] + ^ U2[state->v8[10]] ^ U3[state->v8[15]]; + + column1 = U0[state->v8[4]] ^ U1[state->v8[9]] + ^ U2[state->v8[14]] ^ U3[state->v8[3]]; + + column2 = U0[state->v8[8]] ^ U1[state->v8[13]] + ^ U2[state->v8[2]] ^ U3[state->v8[7]]; + + column3 = U0[state->v8[12]] ^ U1[state->v8[1]] + ^ U2[state->v8[6]] ^ U3[state->v8[11]]; + + state->v32[0] = column0 ^ round_key->v32[0]; + state->v32[1] = column1 ^ round_key->v32[1]; + state->v32[2] = column2 ^ round_key->v32[2]; + state->v32[3] = column3 ^ round_key->v32[3]; + +} + +static inline void +aes_final_round(v128_t *state, const v128_t *round_key) { + uint8_t tmp; + + /* byte substitutions and row shifts */ + /* first row - no shift */ + state->v8[0] = aes_sbox[state->v8[0]]; + state->v8[4] = aes_sbox[state->v8[4]]; + state->v8[8] = aes_sbox[state->v8[8]]; + state->v8[12] = aes_sbox[state->v8[12]]; + + /* second row - shift one left */ + tmp = aes_sbox[state->v8[1]]; + state->v8[1] = aes_sbox[state->v8[5]]; + state->v8[5] = aes_sbox[state->v8[9]]; + state->v8[9] = aes_sbox[state->v8[13]]; + state->v8[13] = tmp; + + /* third row - shift two left */ + tmp = aes_sbox[state->v8[10]]; + state->v8[10] = aes_sbox[state->v8[2]]; + state->v8[2] = tmp; + tmp = aes_sbox[state->v8[14]]; + state->v8[14] = aes_sbox[state->v8[6]]; + state->v8[6] = tmp; + + /* fourth row - shift three left */ + tmp = aes_sbox[state->v8[15]]; + state->v8[15] = aes_sbox[state->v8[11]]; + state->v8[11] = aes_sbox[state->v8[7]]; + state->v8[7] = aes_sbox[state->v8[3]]; + state->v8[3] = tmp; + + v128_xor_eq(state, round_key); +} + +static inline void +aes_inv_final_round(v128_t *state, const v128_t *round_key) { + uint8_t tmp; + + /* byte substitutions and row shifts */ + /* first row - no shift */ + state->v8[0] = aes_inv_sbox[state->v8[0]]; + state->v8[4] = aes_inv_sbox[state->v8[4]]; + state->v8[8] = aes_inv_sbox[state->v8[8]]; + state->v8[12] = aes_inv_sbox[state->v8[12]]; + + /* second row - shift one left */ + tmp = aes_inv_sbox[state->v8[1]]; + state->v8[1] = aes_inv_sbox[state->v8[5]]; + state->v8[5] = aes_inv_sbox[state->v8[9]]; + state->v8[9] = aes_inv_sbox[state->v8[13]]; + state->v8[13] = tmp; + + /* third row - shift two left */ + tmp = aes_inv_sbox[state->v8[10]]; + state->v8[10] = aes_inv_sbox[state->v8[2]]; + state->v8[2] = tmp; + tmp = aes_inv_sbox[state->v8[14]]; + state->v8[14] = aes_inv_sbox[state->v8[6]]; + state->v8[6] = tmp; + + /* fourth row - shift three left */ + tmp = aes_inv_sbox[state->v8[15]]; + state->v8[15] = aes_inv_sbox[state->v8[11]]; + state->v8[11] = aes_inv_sbox[state->v8[7]]; + state->v8[7] = aes_inv_sbox[state->v8[3]]; + state->v8[3] = tmp; + + v128_xor_eq(state, round_key); +} + +#endif /* CPU type */ + + +void +aes_encrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key) { + + /* add in the subkey */ + v128_xor_eq(plaintext, &exp_key->round[0]); + + /* now do the rounds */ + aes_round(plaintext, &exp_key->round[1]); + aes_round(plaintext, &exp_key->round[2]); + aes_round(plaintext, &exp_key->round[3]); + aes_round(plaintext, &exp_key->round[4]); + aes_round(plaintext, &exp_key->round[5]); + aes_round(plaintext, &exp_key->round[6]); + aes_round(plaintext, &exp_key->round[7]); + aes_round(plaintext, &exp_key->round[8]); + aes_round(plaintext, &exp_key->round[9]); + if (exp_key->num_rounds == 10) { + aes_final_round(plaintext, &exp_key->round[10]); + } + else if (exp_key->num_rounds == 12) { + aes_round(plaintext, &exp_key->round[10]); + aes_round(plaintext, &exp_key->round[11]); + aes_final_round(plaintext, &exp_key->round[12]); + } + else if (exp_key->num_rounds == 14) { + aes_round(plaintext, &exp_key->round[10]); + aes_round(plaintext, &exp_key->round[11]); + aes_round(plaintext, &exp_key->round[12]); + aes_round(plaintext, &exp_key->round[13]); + aes_final_round(plaintext, &exp_key->round[14]); + } +} + +void +aes_decrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key) { + + /* add in the subkey */ + v128_xor_eq(plaintext, &exp_key->round[0]); + + /* now do the rounds */ + aes_inv_round(plaintext, &exp_key->round[1]); + aes_inv_round(plaintext, &exp_key->round[2]); + aes_inv_round(plaintext, &exp_key->round[3]); + aes_inv_round(plaintext, &exp_key->round[4]); + aes_inv_round(plaintext, &exp_key->round[5]); + aes_inv_round(plaintext, &exp_key->round[6]); + aes_inv_round(plaintext, &exp_key->round[7]); + aes_inv_round(plaintext, &exp_key->round[8]); + aes_inv_round(plaintext, &exp_key->round[9]); + if (exp_key->num_rounds == 10) { + aes_inv_final_round(plaintext, &exp_key->round[10]); + } + else if (exp_key->num_rounds == 12) { + aes_inv_round(plaintext, &exp_key->round[10]); + aes_inv_round(plaintext, &exp_key->round[11]); + aes_inv_final_round(plaintext, &exp_key->round[12]); + } + else if (exp_key->num_rounds == 14) { + aes_inv_round(plaintext, &exp_key->round[10]); + aes_inv_round(plaintext, &exp_key->round[11]); + aes_inv_round(plaintext, &exp_key->round[12]); + aes_inv_round(plaintext, &exp_key->round[13]); + aes_inv_final_round(plaintext, &exp_key->round[14]); + } +} diff --git a/src/libs/srtp/crypto/cipher/aes_cbc.c b/src/libs/srtp/crypto/cipher/aes_cbc.c new file mode 100644 index 00000000..ed33f5b0 --- /dev/null +++ b/src/libs/srtp/crypto/cipher/aes_cbc.c @@ -0,0 +1,540 @@ +/* + * aes_cbc.c + * + * AES Cipher Block Chaining Mode + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "aes_cbc.h" +#include "alloc.h" + +debug_module_t mod_aes_cbc = { + 0, /* debugging is off by default */ + "aes cbc" /* printable module name */ +}; + + + +err_status_t +aes_cbc_alloc(cipher_t **c, int key_len) { + extern cipher_type_t aes_cbc; + uint8_t *pointer; + int tmp; + + debug_print(mod_aes_cbc, + "allocating cipher with key length %d", key_len); + + if (key_len != 16 && key_len != 24 && key_len != 32) + return err_status_bad_param; + + /* allocate memory a cipher of type aes_cbc */ + tmp = (sizeof(aes_cbc_ctx_t) + sizeof(cipher_t)); + pointer = (uint8_t*)crypto_alloc(tmp); + if (pointer == NULL) + return err_status_alloc_fail; + + /* set pointers */ + *c = (cipher_t *)pointer; + (*c)->type = &aes_cbc; + (*c)->state = pointer + sizeof(cipher_t); + + /* increment ref_count */ + aes_cbc.ref_count++; + + /* set key size */ + (*c)->key_len = key_len; + + return err_status_ok; +} + +err_status_t +aes_cbc_dealloc(cipher_t *c) { + extern cipher_type_t aes_cbc; + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t *)c, + sizeof(aes_cbc_ctx_t) + sizeof(cipher_t)); + + /* free memory */ + crypto_free(c); + + /* decrement ref_count */ + aes_cbc.ref_count--; + + return err_status_ok; +} + +err_status_t +aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, int key_len, + cipher_direction_t dir) { + err_status_t status; + + debug_print(mod_aes_cbc, + "key: %s", octet_string_hex_string(key, key_len)); + + /* expand key for the appropriate direction */ + switch (dir) { + case (direction_encrypt): + status = aes_expand_encryption_key(key, key_len, &c->expanded_key); + if (status) + return status; + break; + case (direction_decrypt): + status = aes_expand_decryption_key(key, key_len, &c->expanded_key); + if (status) + return status; + break; + default: + return err_status_bad_param; + } + + + return err_status_ok; +} + + +err_status_t +aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv) { + int i; +/* v128_t *input = iv; */ + uint8_t *input = (uint8_t*) iv; + + /* set state and 'previous' block to iv */ + for (i=0; i < 16; i++) + c->previous.v8[i] = c->state.v8[i] = input[i]; + + debug_print(mod_aes_cbc, "setting iv: %s", v128_hex_string(&c->state)); + + return err_status_ok; +} + +err_status_t +aes_cbc_encrypt(aes_cbc_ctx_t *c, + unsigned char *data, + unsigned int *bytes_in_data) { + int i; + unsigned char *input = data; /* pointer to data being read */ + unsigned char *output = data; /* pointer to data being written */ + int bytes_to_encr = *bytes_in_data; + + /* + * verify that we're 16-octet aligned + */ + if (*bytes_in_data & 0xf) + return err_status_bad_param; + + /* + * note that we assume that the initialization vector has already + * been set, e.g. by calling aes_cbc_set_iv() + */ + debug_print(mod_aes_cbc, "iv: %s", + v128_hex_string(&c->state)); + + /* + * loop over plaintext blocks, exoring state into plaintext then + * encrypting and writing to output + */ + while (bytes_to_encr > 0) { + + /* exor plaintext into state */ + for (i=0; i < 16; i++) + c->state.v8[i] ^= *input++; + + debug_print(mod_aes_cbc, "inblock: %s", + v128_hex_string(&c->state)); + + aes_encrypt(&c->state, &c->expanded_key); + + debug_print(mod_aes_cbc, "outblock: %s", + v128_hex_string(&c->state)); + + /* copy ciphertext to output */ + for (i=0; i < 16; i++) + *output++ = c->state.v8[i]; + + bytes_to_encr -= 16; + } + + return err_status_ok; +} + +err_status_t +aes_cbc_decrypt(aes_cbc_ctx_t *c, + unsigned char *data, + unsigned int *bytes_in_data) { + int i; + v128_t state, previous; + unsigned char *input = data; /* pointer to data being read */ + unsigned char *output = data; /* pointer to data being written */ + int bytes_to_encr = *bytes_in_data; + uint8_t tmp; + + /* + * verify that we're 16-octet aligned + */ + if (*bytes_in_data & 0x0f) + return err_status_bad_param; + + /* set 'previous' block to iv*/ + for (i=0; i < 16; i++) { + previous.v8[i] = c->previous.v8[i]; + } + + debug_print(mod_aes_cbc, "iv: %s", + v128_hex_string(&previous)); + + /* + * loop over ciphertext blocks, decrypting then exoring with state + * then writing plaintext to output + */ + while (bytes_to_encr > 0) { + + /* set state to ciphertext input block */ + for (i=0; i < 16; i++) { + state.v8[i] = *input++; + } + + debug_print(mod_aes_cbc, "inblock: %s", + v128_hex_string(&state)); + + /* decrypt state */ + aes_decrypt(&state, &c->expanded_key); + + debug_print(mod_aes_cbc, "outblock: %s", + v128_hex_string(&state)); + + /* + * exor previous ciphertext block out of plaintext, and write new + * plaintext block to output, while copying old ciphertext block + * to the 'previous' block + */ + for (i=0; i < 16; i++) { + tmp = *output; + *output++ = state.v8[i] ^ previous.v8[i]; + previous.v8[i] = tmp; + } + + bytes_to_encr -= 16; + } + + return err_status_ok; +} + + +err_status_t +aes_cbc_nist_encrypt(aes_cbc_ctx_t *c, + unsigned char *data, + unsigned int *bytes_in_data) { + int i; + unsigned char *pad_start; + int num_pad_bytes; + err_status_t status; + + /* + * determine the number of padding bytes that we need to add - + * this value is always between 1 and 16, inclusive. + */ + num_pad_bytes = 16 - (*bytes_in_data & 0xf); + pad_start = data; + pad_start += *bytes_in_data; + *pad_start++ = 0xa0; + for (i=0; i < num_pad_bytes; i++) + *pad_start++ = 0x00; + + /* + * increment the data size + */ + *bytes_in_data += num_pad_bytes; + + /* + * now cbc encrypt the padded data + */ + status = aes_cbc_encrypt(c, data, bytes_in_data); + if (status) + return status; + + return err_status_ok; +} + + +err_status_t +aes_cbc_nist_decrypt(aes_cbc_ctx_t *c, + unsigned char *data, + unsigned int *bytes_in_data) { + unsigned char *pad_end; + int num_pad_bytes; + err_status_t status; + + /* + * cbc decrypt the padded data + */ + status = aes_cbc_decrypt(c, data, bytes_in_data); + if (status) + return status; + + /* + * determine the number of padding bytes in the decrypted plaintext + * - this value is always between 1 and 16, inclusive. + */ + num_pad_bytes = 1; + pad_end = data + (*bytes_in_data - 1); + while (*pad_end != 0xa0) { /* note: should check padding correctness */ + pad_end--; + num_pad_bytes++; + } + + /* decrement data size */ + *bytes_in_data -= num_pad_bytes; + + return err_status_ok; +} + + +char +aes_cbc_description[] = "aes cipher block chaining (cbc) mode"; + +/* + * Test case 0 is derived from FIPS 197 Appendix C; it uses an + * all-zero IV, so that the first block encryption matches the test + * case in that appendix. This property provides a check of the base + * AES encryption and decryption algorithms; if CBC fails on some + * particular platform, then you should print out AES intermediate + * data and compare with the detailed info provided in that appendix. + * + */ + + +uint8_t aes_cbc_test_case_0_key[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f +}; + +uint8_t aes_cbc_test_case_0_plaintext[64] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff +}; + +uint8_t aes_cbc_test_case_0_ciphertext[80] = { + 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a, + 0x03, 0x35, 0xed, 0x27, 0x67, 0xf2, 0x6d, 0xf1, + 0x64, 0x83, 0x2e, 0x23, 0x44, 0x38, 0x70, 0x8b + +}; + +uint8_t aes_cbc_test_case_0_iv[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + +cipher_test_case_t aes_cbc_test_case_0 = { + 16, /* octets in key */ + aes_cbc_test_case_0_key, /* key */ + aes_cbc_test_case_0_iv, /* initialization vector */ + 16, /* octets in plaintext */ + aes_cbc_test_case_0_plaintext, /* plaintext */ + 32, /* octets in ciphertext */ + aes_cbc_test_case_0_ciphertext, /* ciphertext */ + NULL /* pointer to next testcase */ +}; + + +/* + * this test case is taken directly from Appendix F.2 of NIST Special + * Publication SP 800-38A + */ + +uint8_t aes_cbc_test_case_1_key[16] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +uint8_t aes_cbc_test_case_1_plaintext[64] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 +}; + +uint8_t aes_cbc_test_case_1_ciphertext[80] = { + 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, + 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, + 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, + 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, + 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, + 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, + 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, + 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7, + 0x39, 0x34, 0x07, 0x03, 0x36, 0xd0, 0x77, 0x99, + 0xe0, 0xc4, 0x2f, 0xdd, 0xa8, 0xdf, 0x4c, 0xa3 +}; + +uint8_t aes_cbc_test_case_1_iv[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f +}; + +cipher_test_case_t aes_cbc_test_case_1 = { + 16, /* octets in key */ + aes_cbc_test_case_1_key, /* key */ + aes_cbc_test_case_1_iv, /* initialization vector */ + 64, /* octets in plaintext */ + aes_cbc_test_case_1_plaintext, /* plaintext */ + 80, /* octets in ciphertext */ + aes_cbc_test_case_1_ciphertext, /* ciphertext */ + &aes_cbc_test_case_0 /* pointer to next testcase */ +}; + +/* + * Test case 2 is like test case 0, but for 256-bit keys. (FIPS 197 + * appendix C.3). + */ + + +uint8_t aes_cbc_test_case_2_key[32] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f +}; + +uint8_t aes_cbc_test_case_2_plaintext[64] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff +}; + +uint8_t aes_cbc_test_case_2_ciphertext[80] = { + 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, + 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89, + 0x72, 0x72, 0x6e, 0xe7, 0x71, 0x39, 0xbf, 0x11, + 0xe5, 0x40, 0xe2, 0x7c, 0x54, 0x65, 0x1d, 0xee +}; + +uint8_t aes_cbc_test_case_2_iv[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +cipher_test_case_t aes_cbc_test_case_2 = { + 32, /* octets in key */ + aes_cbc_test_case_2_key, /* key */ + aes_cbc_test_case_2_iv, /* initialization vector */ + 16, /* octets in plaintext */ + aes_cbc_test_case_2_plaintext, /* plaintext */ + 32, /* octets in ciphertext */ + aes_cbc_test_case_2_ciphertext, /* ciphertext */ + &aes_cbc_test_case_1 /* pointer to next testcase */ +}; + + +/* + * this test case is taken directly from Appendix F.2 of NIST Special + * Publication SP 800-38A + */ + +uint8_t aes_cbc_test_case_3_key[32] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 +}; + +uint8_t aes_cbc_test_case_3_plaintext[64] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 +}; + +uint8_t aes_cbc_test_case_3_ciphertext[80] = { + 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, + 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6, + 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d, + 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d, + 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf, + 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61, + 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc, + 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b, + 0xfb, 0x98, 0x20, 0x2c, 0x45, 0xb2, 0xe4, 0xa0, + 0x63, 0xc4, 0x68, 0xba, 0x84, 0x39, 0x16, 0x5a +}; + +uint8_t aes_cbc_test_case_3_iv[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f +}; + +cipher_test_case_t aes_cbc_test_case_3 = { + 32, /* octets in key */ + aes_cbc_test_case_3_key, /* key */ + aes_cbc_test_case_3_iv, /* initialization vector */ + 64, /* octets in plaintext */ + aes_cbc_test_case_3_plaintext, /* plaintext */ + 80, /* octets in ciphertext */ + aes_cbc_test_case_3_ciphertext, /* ciphertext */ + &aes_cbc_test_case_2 /* pointer to next testcase */ +}; + +cipher_type_t aes_cbc = { + (cipher_alloc_func_t) aes_cbc_alloc, + (cipher_dealloc_func_t) aes_cbc_dealloc, + (cipher_init_func_t) aes_cbc_context_init, + (cipher_encrypt_func_t) aes_cbc_nist_encrypt, + (cipher_decrypt_func_t) aes_cbc_nist_decrypt, + (cipher_set_iv_func_t) aes_cbc_set_iv, + (char *) aes_cbc_description, + (int) 0, /* instance count */ + (cipher_test_case_t *) &aes_cbc_test_case_3, + (debug_module_t *) &mod_aes_cbc, + (cipher_type_id_t) AES_CBC +}; + + diff --git a/src/libs/srtp/crypto/cipher/aes_icm.c b/src/libs/srtp/crypto/cipher/aes_icm.c new file mode 100644 index 00000000..1f9bcbd9 --- /dev/null +++ b/src/libs/srtp/crypto/cipher/aes_icm.c @@ -0,0 +1,561 @@ +/* + * aes_icm.c + * + * AES Integer Counter Mode + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#define ALIGN_32 0 + +#include "aes_icm.h" +#include "alloc.h" + + +debug_module_t mod_aes_icm = { + 0, /* debugging is off by default */ + "aes icm" /* printable module name */ +}; + +/* + * integer counter mode works as follows: + * + * 16 bits + * <-----> + * +------+------+------+------+------+------+------+------+ + * | nonce | pakcet index | ctr |---+ + * +------+------+------+------+------+------+------+------+ | + * | + * +------+------+------+------+------+------+------+------+ v + * | salt |000000|->(+) + * +------+------+------+------+------+------+------+------+ | + * | + * +---------+ + * | encrypt | + * +---------+ + * | + * +------+------+------+------+------+------+------+------+ | + * | keystream block |<--+ + * +------+------+------+------+------+------+------+------+ + * + * All fields are big-endian + * + * ctr is the block counter, which increments from zero for + * each packet (16 bits wide) + * + * packet index is distinct for each packet (48 bits wide) + * + * nonce can be distinct across many uses of the same key, or + * can be a fixed value per key, or can be per-packet randomness + * (64 bits) + * + */ + +err_status_t +aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) { + extern cipher_type_t aes_icm; + uint8_t *pointer; + int tmp; + + debug_print(mod_aes_icm, + "allocating cipher with key length %d", key_len); + + /* + * Ismacryp, for example, uses 16 byte key + 8 byte + * salt so this function is called with key_len = 24. + * The check for key_len = 30/38/46 does not apply. Our usage + * of aes functions with key_len = values other than 30 + * has not broken anything. Don't know what would be the + * effect of skipping this check for srtp in general. + */ + if (!(forIsmacryp && key_len > 16 && key_len < 30) && + key_len != 30 && key_len != 38 && key_len != 46) + return err_status_bad_param; + + /* allocate memory a cipher of type aes_icm */ + tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t)); + pointer = (uint8_t*)crypto_alloc(tmp); + if (pointer == NULL) + return err_status_alloc_fail; + + /* set pointers */ + *c = (cipher_t *)pointer; + (*c)->type = &aes_icm; + (*c)->state = pointer + sizeof(cipher_t); + + /* increment ref_count */ + aes_icm.ref_count++; + + /* set key size */ + (*c)->key_len = key_len; + + return err_status_ok; +} + +err_status_t aes_icm_alloc(cipher_t **c, int key_len, int forIsmacryp) { + return aes_icm_alloc_ismacryp(c, key_len, 0); +} + +err_status_t +aes_icm_dealloc(cipher_t *c) { + extern cipher_type_t aes_icm; + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t *)c, + sizeof(aes_icm_ctx_t) + sizeof(cipher_t)); + + /* free memory */ + crypto_free(c); + + /* decrement ref_count */ + aes_icm.ref_count--; + + return err_status_ok; +} + + +/* + * aes_icm_context_init(...) initializes the aes_icm_context + * using the value in key[]. + * + * the key is the secret key + * + * the salt is unpredictable (but not necessarily secret) data which + * randomizes the starting point in the keystream + */ + +err_status_t +aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key, int key_len) { + err_status_t status; + int base_key_len; + + if (key_len > 16 && key_len < 30) /* Ismacryp */ + base_key_len = 16; + else if (key_len == 30 || key_len == 38 || key_len == 46) + base_key_len = key_len - 14; + else + return err_status_bad_param; + + /* set counter and initial values to 'offset' value */ + /* Note this copies past the end of the 'key' array by 2 bytes! */ + v128_copy_octet_string(&c->counter, key + base_key_len); + v128_copy_octet_string(&c->offset, key + base_key_len); + + /* force last two octets of the offset to zero (for srtp compatibility) */ + c->offset.v8[14] = c->offset.v8[15] = 0; + c->counter.v8[14] = c->counter.v8[15] = 0; + + debug_print(mod_aes_icm, + "key: %s", octet_string_hex_string(key, base_key_len)); + debug_print(mod_aes_icm, + "offset: %s", v128_hex_string(&c->offset)); + + /* expand key */ + status = aes_expand_encryption_key(key, base_key_len, &c->expanded_key); + if (status) { + v128_set_to_zero(&c->counter); + v128_set_to_zero(&c->offset); + return status; + } + + /* indicate that the keystream_buffer is empty */ + c->bytes_in_buffer = 0; + + return err_status_ok; +} + +/* + * aes_icm_set_octet(c, i) sets the counter of the context which it is + * passed so that the next octet of keystream that will be generated + * is the ith octet + */ + +err_status_t +aes_icm_set_octet(aes_icm_ctx_t *c, + uint64_t octet_num) { + +#ifdef NO_64BIT_MATH + int tail_num = low32(octet_num) & 0x0f; + /* 64-bit right-shift 4 */ + uint64_t block_num = make64(high32(octet_num) >> 4, + ((high32(octet_num) & 0x0f)<<(32-4)) | + (low32(octet_num) >> 4)); +#else + int tail_num = (int)(octet_num % 16); + uint64_t block_num = octet_num / 16; +#endif + + + /* set counter value */ + /* FIX - There's no way this is correct */ + c->counter.v64[0] = c->offset.v64[0]; +#ifdef NO_64BIT_MATH + c->counter.v64[0] = make64(high32(c->offset.v64[0]) ^ high32(block_num), + low32(c->offset.v64[0]) ^ low32(block_num)); +#else + c->counter.v64[0] = c->offset.v64[0] ^ block_num; +#endif + + debug_print(mod_aes_icm, + "set_octet: %s", v128_hex_string(&c->counter)); + + /* fill keystream buffer, if needed */ + if (tail_num) { + v128_copy(&c->keystream_buffer, &c->counter); + aes_encrypt(&c->keystream_buffer, &c->expanded_key); + c->bytes_in_buffer = sizeof(v128_t); + + debug_print(mod_aes_icm, "counter: %s", + v128_hex_string(&c->counter)); + debug_print(mod_aes_icm, "ciphertext: %s", + v128_hex_string(&c->keystream_buffer)); + + /* indicate number of bytes in keystream_buffer */ + c->bytes_in_buffer = sizeof(v128_t) - tail_num; + + } else { + + /* indicate that keystream_buffer is empty */ + c->bytes_in_buffer = 0; + } + + return err_status_ok; +} + +/* + * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with + * the offset + */ + +err_status_t +aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) { + v128_t *nonce = (v128_t *) iv; + + debug_print(mod_aes_icm, + "setting iv: %s", v128_hex_string(nonce)); + + v128_xor(&c->counter, &c->offset, nonce); + + debug_print(mod_aes_icm, + "set_counter: %s", v128_hex_string(&c->counter)); + + /* indicate that the keystream_buffer is empty */ + c->bytes_in_buffer = 0; + + return err_status_ok; +} + + + +/* + * aes_icm_advance(...) refills the keystream_buffer and + * advances the block index of the sicm_context forward by one + * + * this is an internal, hopefully inlined function + */ + +static inline void +aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) { + /* fill buffer with new keystream */ + v128_copy(&c->keystream_buffer, &c->counter); + aes_encrypt(&c->keystream_buffer, &c->expanded_key); + c->bytes_in_buffer = sizeof(v128_t); + + debug_print(mod_aes_icm, "counter: %s", + v128_hex_string(&c->counter)); + debug_print(mod_aes_icm, "ciphertext: %s", + v128_hex_string(&c->keystream_buffer)); + + /* clock counter forward */ + + if (forIsmacryp) { + uint32_t temp; + //alex's clock counter forward + temp = ntohl(c->counter.v32[3]); + c->counter.v32[3] = htonl(++temp); + } else { + if (!++(c->counter.v8[15])) + ++(c->counter.v8[14]); + } +} + +static inline void aes_icm_advance(aes_icm_ctx_t *c) { + aes_icm_advance_ismacryp(c, 0); +} + + +/*e + * icm_encrypt deals with the following cases: + * + * bytes_to_encr < bytes_in_buffer + * - add keystream into data + * + * bytes_to_encr > bytes_in_buffer + * - add keystream into data until keystream_buffer is depleted + * - loop over blocks, filling keystream_buffer and then + * adding keystream into data + * - fill buffer then add in remaining (< 16) bytes of keystream + */ + +err_status_t +aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c, + unsigned char *buf, unsigned int *enc_len, + int forIsmacryp) { + unsigned int bytes_to_encr = *enc_len; + unsigned int i; + uint32_t *b; + + /* check that there's enough segment left but not for ismacryp*/ + if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff) + return err_status_terminus; + + debug_print(mod_aes_icm, "block index: %d", + htons(c->counter.v16[7])); + if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) { + + /* deal with odd case of small bytes_to_encr */ + for (i = (sizeof(v128_t) - c->bytes_in_buffer); + i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++) + { + *buf++ ^= c->keystream_buffer.v8[i]; + } + + c->bytes_in_buffer -= bytes_to_encr; + + /* return now to avoid the main loop */ + return err_status_ok; + + } else { + + /* encrypt bytes until the remaining data is 16-byte aligned */ + for (i=(sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++) + *buf++ ^= c->keystream_buffer.v8[i]; + + bytes_to_encr -= c->bytes_in_buffer; + c->bytes_in_buffer = 0; + + } + + /* now loop over entire 16-byte blocks of keystream */ + for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) { + + /* fill buffer with new keystream */ + aes_icm_advance_ismacryp(c, forIsmacryp); + + /* + * add keystream into the data buffer (this would be a lot faster + * if we could assume 32-bit alignment!) + */ + +#if ALIGN_32 + b = (uint32_t *)buf; + *b++ ^= c->keystream_buffer.v32[0]; + *b++ ^= c->keystream_buffer.v32[1]; + *b++ ^= c->keystream_buffer.v32[2]; + *b++ ^= c->keystream_buffer.v32[3]; + buf = (uint8_t *)b; +#else + if ((((unsigned long) buf) & 0x03) != 0) { + *buf++ ^= c->keystream_buffer.v8[0]; + *buf++ ^= c->keystream_buffer.v8[1]; + *buf++ ^= c->keystream_buffer.v8[2]; + *buf++ ^= c->keystream_buffer.v8[3]; + *buf++ ^= c->keystream_buffer.v8[4]; + *buf++ ^= c->keystream_buffer.v8[5]; + *buf++ ^= c->keystream_buffer.v8[6]; + *buf++ ^= c->keystream_buffer.v8[7]; + *buf++ ^= c->keystream_buffer.v8[8]; + *buf++ ^= c->keystream_buffer.v8[9]; + *buf++ ^= c->keystream_buffer.v8[10]; + *buf++ ^= c->keystream_buffer.v8[11]; + *buf++ ^= c->keystream_buffer.v8[12]; + *buf++ ^= c->keystream_buffer.v8[13]; + *buf++ ^= c->keystream_buffer.v8[14]; + *buf++ ^= c->keystream_buffer.v8[15]; + } else { + b = (uint32_t *)buf; + *b++ ^= c->keystream_buffer.v32[0]; + *b++ ^= c->keystream_buffer.v32[1]; + *b++ ^= c->keystream_buffer.v32[2]; + *b++ ^= c->keystream_buffer.v32[3]; + buf = (uint8_t *)b; + } +#endif /* #if ALIGN_32 */ + + } + + /* if there is a tail end of the data, process it */ + if ((bytes_to_encr & 0xf) != 0) { + + /* fill buffer with new keystream */ + aes_icm_advance_ismacryp(c, forIsmacryp); + + for (i=0; i < (bytes_to_encr & 0xf); i++) + *buf++ ^= c->keystream_buffer.v8[i]; + + /* reset the keystream buffer size to right value */ + c->bytes_in_buffer = sizeof(v128_t) - i; + } else { + + /* no tail, so just reset the keystream buffer size to zero */ + c->bytes_in_buffer = 0; + + } + + return err_status_ok; +} + +err_status_t +aes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) { + return aes_icm_encrypt_ismacryp(c, buf, enc_len, 0); +} + +err_status_t +aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) { + unsigned int len = num_octets_to_output; + + /* zeroize the buffer */ + octet_string_set_to_zero(buffer, num_octets_to_output); + + /* exor keystream into buffer */ + return aes_icm_encrypt(c, buffer, &len); +} + + +char +aes_icm_description[] = "aes integer counter mode"; + +uint8_t aes_icm_test_case_0_key[30] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd +}; + +uint8_t aes_icm_test_case_0_nonce[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8_t aes_icm_test_case_0_plaintext[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t aes_icm_test_case_0_ciphertext[32] = { + 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80, + 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4, + 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7, + 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab +}; + +cipher_test_case_t aes_icm_test_case_0 = { + 30, /* octets in key */ + aes_icm_test_case_0_key, /* key */ + aes_icm_test_case_0_nonce, /* packet index */ + 32, /* octets in plaintext */ + aes_icm_test_case_0_plaintext, /* plaintext */ + 32, /* octets in ciphertext */ + aes_icm_test_case_0_ciphertext, /* ciphertext */ + NULL /* pointer to next testcase */ +}; + +uint8_t aes_icm_test_case_1_key[46] = { + 0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70, + 0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92, + 0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82, + 0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd +}; + +uint8_t aes_icm_test_case_1_nonce[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8_t aes_icm_test_case_1_plaintext[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t aes_icm_test_case_1_ciphertext[32] = { + 0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25, + 0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4, + 0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6, + 0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac +}; + +cipher_test_case_t aes_icm_test_case_1 = { + 46, /* octets in key */ + aes_icm_test_case_1_key, /* key */ + aes_icm_test_case_1_nonce, /* packet index */ + 32, /* octets in plaintext */ + aes_icm_test_case_1_plaintext, /* plaintext */ + 32, /* octets in ciphertext */ + aes_icm_test_case_1_ciphertext, /* ciphertext */ + &aes_icm_test_case_0 /* pointer to next testcase */ +}; + + + +/* + * note: the encrypt function is identical to the decrypt function + */ + +cipher_type_t aes_icm = { + (cipher_alloc_func_t) aes_icm_alloc, + (cipher_dealloc_func_t) aes_icm_dealloc, + (cipher_init_func_t) aes_icm_context_init, + (cipher_encrypt_func_t) aes_icm_encrypt, + (cipher_decrypt_func_t) aes_icm_encrypt, + (cipher_set_iv_func_t) aes_icm_set_iv, + (char *) aes_icm_description, + (int) 0, /* instance count */ + (cipher_test_case_t *) &aes_icm_test_case_1, + (debug_module_t *) &mod_aes_icm, + (cipher_type_id_t) AES_ICM +}; + diff --git a/src/libs/srtp/crypto/cipher/cipher.c b/src/libs/srtp/crypto/cipher/cipher.c new file mode 100644 index 00000000..27da651c --- /dev/null +++ b/src/libs/srtp/crypto/cipher/cipher.c @@ -0,0 +1,421 @@ +/* + * cipher.c + * + * cipher meta-functions + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "cipher.h" +#include "rand_source.h" /* used in invertibiltiy tests */ +#include "alloc.h" /* for crypto_alloc(), crypto_free() */ + +debug_module_t mod_cipher = { + 0, /* debugging is off by default */ + "cipher" /* printable module name */ +}; + +err_status_t +cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output) { + + /* zeroize the buffer */ + octet_string_set_to_zero(buffer, num_octets_to_output); + + /* exor keystream into buffer */ + return cipher_encrypt(c, buffer, (unsigned int *) &num_octets_to_output); +} + +/* some bookkeeping functions */ + +int +cipher_get_key_length(const cipher_t *c) { + return c->key_len; +} + +/* + * cipher_type_test(ct, test_data) tests a cipher of type ct against + * test cases provided in a list test_data of values of key, salt, iv, + * plaintext, and ciphertext that is known to be good + */ + +#define SELF_TEST_BUF_OCTETS 128 +#define NUM_RAND_TESTS 128 +#define MAX_KEY_LEN 64 + +err_status_t +cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) { + const cipher_test_case_t *test_case = test_data; + cipher_t *c; + err_status_t status; + uint8_t buffer[SELF_TEST_BUF_OCTETS]; + uint8_t buffer2[SELF_TEST_BUF_OCTETS]; + unsigned int len; + int i, j, case_num = 0; + + debug_print(mod_cipher, "running self-test for cipher %s", + ct->description); + + /* + * check to make sure that we have at least one test case, and + * return an error if we don't - we need to be paranoid here + */ + if (test_case == NULL) + return err_status_cant_check; + + /* + * loop over all test cases, perform known-answer tests of both the + * encryption and decryption functions + */ + while (test_case != NULL) { + + /* allocate cipher */ + status = cipher_type_alloc(ct, &c, test_case->key_length_octets); + if (status) + return status; + + /* + * test the encrypt function + */ + debug_print(mod_cipher, "testing encryption", NULL); + + /* initialize cipher */ + status = cipher_init(c, test_case->key, direction_encrypt); + if (status) { + cipher_dealloc(c); + return status; + } + + /* copy plaintext into test buffer */ + if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) { + cipher_dealloc(c); + return err_status_bad_param; + } + for (i=0; i < test_case->plaintext_length_octets; i++) + buffer[i] = test_case->plaintext[i]; + + debug_print(mod_cipher, "plaintext: %s", + octet_string_hex_string(buffer, + test_case->plaintext_length_octets)); + + /* set the initialization vector */ + status = cipher_set_iv(c, test_case->idx); + if (status) { + cipher_dealloc(c); + return status; + } + + /* encrypt */ + len = test_case->plaintext_length_octets; + status = cipher_encrypt(c, buffer, &len); + if (status) { + cipher_dealloc(c); + return status; + } + + debug_print(mod_cipher, "ciphertext: %s", + octet_string_hex_string(buffer, + test_case->ciphertext_length_octets)); + + /* compare the resulting ciphertext with that in the test case */ + if (len != test_case->ciphertext_length_octets) + return err_status_algo_fail; + status = err_status_ok; + for (i=0; i < test_case->ciphertext_length_octets; i++) + if (buffer[i] != test_case->ciphertext[i]) { + status = err_status_algo_fail; + debug_print(mod_cipher, "test case %d failed", case_num); + debug_print(mod_cipher, "(failure at byte %d)", i); + break; + } + if (status) { + + debug_print(mod_cipher, "c computed: %s", + octet_string_hex_string(buffer, + 2*test_case->plaintext_length_octets)); + debug_print(mod_cipher, "c expected: %s", + octet_string_hex_string(test_case->ciphertext, + 2*test_case->plaintext_length_octets)); + + cipher_dealloc(c); + return err_status_algo_fail; + } + + /* + * test the decrypt function + */ + debug_print(mod_cipher, "testing decryption", NULL); + + /* re-initialize cipher for decryption */ + status = cipher_init(c, test_case->key, direction_decrypt); + if (status) { + cipher_dealloc(c); + return status; + } + + /* copy ciphertext into test buffer */ + if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) { + cipher_dealloc(c); + return err_status_bad_param; + } + for (i=0; i < test_case->ciphertext_length_octets; i++) + buffer[i] = test_case->ciphertext[i]; + + debug_print(mod_cipher, "ciphertext: %s", + octet_string_hex_string(buffer, + test_case->plaintext_length_octets)); + + /* set the initialization vector */ + status = cipher_set_iv(c, test_case->idx); + if (status) { + cipher_dealloc(c); + return status; + } + + /* decrypt */ + len = test_case->ciphertext_length_octets; + status = cipher_decrypt(c, buffer, &len); + if (status) { + cipher_dealloc(c); + return status; + } + + debug_print(mod_cipher, "plaintext: %s", + octet_string_hex_string(buffer, + test_case->plaintext_length_octets)); + + /* compare the resulting plaintext with that in the test case */ + if (len != test_case->plaintext_length_octets) + return err_status_algo_fail; + status = err_status_ok; + for (i=0; i < test_case->plaintext_length_octets; i++) + if (buffer[i] != test_case->plaintext[i]) { + status = err_status_algo_fail; + debug_print(mod_cipher, "test case %d failed", case_num); + debug_print(mod_cipher, "(failure at byte %d)", i); + } + if (status) { + + debug_print(mod_cipher, "p computed: %s", + octet_string_hex_string(buffer, + 2*test_case->plaintext_length_octets)); + debug_print(mod_cipher, "p expected: %s", + octet_string_hex_string(test_case->plaintext, + 2*test_case->plaintext_length_octets)); + + cipher_dealloc(c); + return err_status_algo_fail; + } + + /* deallocate the cipher */ + status = cipher_dealloc(c); + if (status) + return status; + + /* + * the cipher passed the test case, so move on to the next test + * case in the list; if NULL, we'l proceed to the next test + */ + test_case = test_case->next_test_case; + ++case_num; + } + + /* now run some random invertibility tests */ + + /* allocate cipher, using paramaters from the first test case */ + test_case = test_data; + status = cipher_type_alloc(ct, &c, test_case->key_length_octets); + if (status) + return status; + + rand_source_init(); + + for (j=0; j < NUM_RAND_TESTS; j++) { + unsigned length; + int plaintext_len; + uint8_t key[MAX_KEY_LEN]; + uint8_t iv[MAX_KEY_LEN]; + + /* choose a length at random (leaving room for IV and padding) */ + length = rand() % (SELF_TEST_BUF_OCTETS - 64); + debug_print(mod_cipher, "random plaintext length %d\n", length); + status = rand_source_get_octet_string(buffer, length); + if (status) return status; + + debug_print(mod_cipher, "plaintext: %s", + octet_string_hex_string(buffer, length)); + + /* copy plaintext into second buffer */ + for (i=0; (unsigned int)i < length; i++) + buffer2[i] = buffer[i]; + + /* choose a key at random */ + if (test_case->key_length_octets > MAX_KEY_LEN) + return err_status_cant_check; + status = rand_source_get_octet_string(key, test_case->key_length_octets); + if (status) return status; + + /* chose a random initialization vector */ + status = rand_source_get_octet_string(iv, MAX_KEY_LEN); + if (status) return status; + + /* initialize cipher */ + status = cipher_init(c, key, direction_encrypt); + if (status) { + cipher_dealloc(c); + return status; + } + + /* set initialization vector */ + status = cipher_set_iv(c, test_case->idx); + if (status) { + cipher_dealloc(c); + return status; + } + + /* encrypt buffer with cipher */ + plaintext_len = length; + status = cipher_encrypt(c, buffer, &length); + if (status) { + cipher_dealloc(c); + return status; + } + debug_print(mod_cipher, "ciphertext: %s", + octet_string_hex_string(buffer, length)); + + /* + * re-initialize cipher for decryption, re-set the iv, then + * decrypt the ciphertext + */ + status = cipher_init(c, key, direction_decrypt); + if (status) { + cipher_dealloc(c); + return status; + } + status = cipher_set_iv(c, test_case->idx); + if (status) { + cipher_dealloc(c); + return status; + } + status = cipher_decrypt(c, buffer, &length); + if (status) { + cipher_dealloc(c); + return status; + } + + debug_print(mod_cipher, "plaintext[2]: %s", + octet_string_hex_string(buffer, length)); + + /* compare the resulting plaintext with the original one */ + if (length != plaintext_len) + return err_status_algo_fail; + status = err_status_ok; + for (i=0; i < plaintext_len; i++) + if (buffer[i] != buffer2[i]) { + status = err_status_algo_fail; + debug_print(mod_cipher, "random test case %d failed", case_num); + debug_print(mod_cipher, "(failure at byte %d)", i); + } + if (status) { + cipher_dealloc(c); + return err_status_algo_fail; + } + + } + + status = cipher_dealloc(c); + if (status) + return status; + + return err_status_ok; +} + + +/* + * cipher_type_self_test(ct) performs cipher_type_test on ct's internal + * list of test data. + */ + +err_status_t +cipher_type_self_test(const cipher_type_t *ct) { + return cipher_type_test(ct, ct->test_data); +} + +/* + * cipher_bits_per_second(c, l, t) computes (an estimate of) the + * number of bits that a cipher implementation can encrypt in a second + * + * c is a cipher (which MUST be allocated and initialized already), l + * is the length in octets of the test data to be encrypted, and t is + * the number of trials + * + * if an error is encountered, the value 0 is returned + */ + +uint64_t +cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials) { + int i; + v128_t nonce; + clock_t timer; + unsigned char *enc_buf; + unsigned int len = octets_in_buffer; + + enc_buf = (unsigned char*) crypto_alloc(octets_in_buffer); + if (enc_buf == NULL) + return 0; /* indicate bad parameters by returning null */ + + /* time repeated trials */ + v128_set_to_zero(&nonce); + timer = clock(); + for(i=0; i < num_trials; i++, nonce.v32[3] = i) { + cipher_set_iv(c, &nonce); + cipher_encrypt(c, enc_buf, &len); + } + timer = clock() - timer; + + crypto_free(enc_buf); + + if (timer == 0) { + /* Too fast! */ + return 0; + } + + return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer; +} diff --git a/src/libs/srtp/crypto/cipher/null_cipher.c b/src/libs/srtp/crypto/cipher/null_cipher.c new file mode 100644 index 00000000..724f4df3 --- /dev/null +++ b/src/libs/srtp/crypto/cipher/null_cipher.c @@ -0,0 +1,153 @@ +/* + * null_cipher.c + * + * A null cipher implementation. This cipher leaves the plaintext + * unchanged. + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "datatypes.h" +#include "null_cipher.h" +#include "alloc.h" + +/* the null_cipher uses the cipher debug module */ + +extern debug_module_t mod_cipher; + +err_status_t +null_cipher_alloc(cipher_t **c, int key_len) { + extern cipher_type_t null_cipher; + uint8_t *pointer; + + debug_print(mod_cipher, + "allocating cipher with key length %d", key_len); + + /* allocate memory a cipher of type null_cipher */ + pointer = (uint8_t*)crypto_alloc(sizeof(null_cipher_ctx_t) + sizeof(cipher_t)); + if (pointer == NULL) + return err_status_alloc_fail; + + /* set pointers */ + *c = (cipher_t *)pointer; + (*c)->type = &null_cipher; + (*c)->state = pointer + sizeof(cipher_t); + + /* set key size */ + (*c)->key_len = key_len; + + /* increment ref_count */ + null_cipher.ref_count++; + + return err_status_ok; + +} + +err_status_t +null_cipher_dealloc(cipher_t *c) { + extern cipher_type_t null_cipher; + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t *)c, + sizeof(null_cipher_ctx_t) + sizeof(cipher_t)); + + /* free memory of type null_cipher */ + crypto_free(c); + + /* decrement reference count */ + null_cipher.ref_count--; + + return err_status_ok; + +} + +err_status_t +null_cipher_init(null_cipher_ctx_t *ctx, const uint8_t *key, int key_len) { + + debug_print(mod_cipher, "initializing null cipher", NULL); + + return err_status_ok; +} + +err_status_t +null_cipher_set_iv(null_cipher_ctx_t *c, void *iv) { + return err_status_ok; +} + +err_status_t +null_cipher_encrypt(null_cipher_ctx_t *c, + unsigned char *buf, unsigned int *bytes_to_encr) { + return err_status_ok; +} + +char +null_cipher_description[] = "null cipher"; + +cipher_test_case_t +null_cipher_test_0 = { + 0, /* octets in key */ + NULL, /* key */ + 0, /* packet index */ + 0, /* octets in plaintext */ + NULL, /* plaintext */ + 0, /* octets in plaintext */ + NULL, /* ciphertext */ + NULL /* pointer to next testcase */ +}; + + +/* + * note: the decrypt function is idential to the encrypt function + */ + +cipher_type_t null_cipher = { + (cipher_alloc_func_t) null_cipher_alloc, + (cipher_dealloc_func_t) null_cipher_dealloc, + (cipher_init_func_t) null_cipher_init, + (cipher_encrypt_func_t) null_cipher_encrypt, + (cipher_decrypt_func_t) null_cipher_encrypt, + (cipher_set_iv_func_t) null_cipher_set_iv, + (char *) null_cipher_description, + (int) 0, + (cipher_test_case_t *) &null_cipher_test_0, + (debug_module_t *) NULL, + (cipher_type_id_t) NULL_CIPHER +}; + diff --git a/src/libs/srtp/crypto/hash/hmac.c b/src/libs/srtp/crypto/hash/hmac.c new file mode 100644 index 00000000..4f389fe1 --- /dev/null +++ b/src/libs/srtp/crypto/hash/hmac.c @@ -0,0 +1,268 @@ +/* + * hmac.c + * + * implementation of hmac auth_type_t + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "hmac.h" +#include "alloc.h" + +/* the debug module for authentiation */ + +debug_module_t mod_hmac = { + 0, /* debugging is off by default */ + "hmac sha-1" /* printable name for module */ +}; + + +err_status_t +hmac_alloc(auth_t **a, int key_len, int out_len) { + extern auth_type_t hmac; + uint8_t *pointer; + + debug_print(mod_hmac, "allocating auth func with key length %d", key_len); + debug_print(mod_hmac, " tag length %d", out_len); + + /* + * check key length - note that we don't support keys larger + * than 20 bytes yet + */ + if (key_len > 20) + return err_status_bad_param; + + /* check output length - should be less than 20 bytes */ + if (out_len > 20) + return err_status_bad_param; + + /* allocate memory for auth and hmac_ctx_t structures */ + pointer = (uint8_t*)crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t)); + if (pointer == NULL) + return err_status_alloc_fail; + + /* set pointers */ + *a = (auth_t *)pointer; + (*a)->type = &hmac; + (*a)->state = pointer + sizeof(auth_t); + (*a)->out_len = out_len; + (*a)->key_len = key_len; + (*a)->prefix_len = 0; + + /* increment global count of all hmac uses */ + hmac.ref_count++; + + return err_status_ok; +} + +err_status_t +hmac_dealloc(auth_t *a) { + extern auth_type_t hmac; + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t *)a, + sizeof(hmac_ctx_t) + sizeof(auth_t)); + + /* free memory */ + crypto_free(a); + + /* decrement global count of all hmac uses */ + hmac.ref_count--; + + return err_status_ok; +} + +err_status_t +hmac_init(hmac_ctx_t *state, const uint8_t *key, int key_len) { + int i; + uint8_t ipad[64]; + + /* + * check key length - note that we don't support keys larger + * than 20 bytes yet + */ + if (key_len > 20) + return err_status_bad_param; + + /* + * set values of ipad and opad by exoring the key into the + * appropriate constant values + */ + for (i=0; i < key_len; i++) { + ipad[i] = key[i] ^ 0x36; + state->opad[i] = key[i] ^ 0x5c; + } + /* set the rest of ipad, opad to constant values */ + for ( ; i < 64; i++) { + ipad[i] = 0x36; + ((uint8_t *)state->opad)[i] = 0x5c; + } + + debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, 64)); + + /* initialize sha1 context */ + sha1_init(&state->init_ctx); + + /* hash ipad ^ key */ + sha1_update(&state->init_ctx, ipad, 64); + memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t)); + + return err_status_ok; +} + +err_status_t +hmac_start(hmac_ctx_t *state) { + + memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t)); + + return err_status_ok; +} + +err_status_t +hmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets) { + + debug_print(mod_hmac, "input: %s", + octet_string_hex_string(message, msg_octets)); + + /* hash message into sha1 context */ + sha1_update(&state->ctx, message, msg_octets); + + return err_status_ok; +} + +err_status_t +hmac_compute(hmac_ctx_t *state, const void *message, + int msg_octets, int tag_len, uint8_t *result) { + uint32_t hash_value[5]; + uint32_t H[5]; + int i; + + /* check tag length, return error if we can't provide the value expected */ + if (tag_len > 20) + return err_status_bad_param; + + /* hash message, copy output into H */ + hmac_update(state, (const uint8_t*)message, msg_octets); + sha1_final(&state->ctx, H); + + /* + * note that we don't need to debug_print() the input, since the + * function hmac_update() already did that for us + */ + debug_print(mod_hmac, "intermediate state: %s", + octet_string_hex_string((uint8_t *)H, 20)); + + /* re-initialize hash context */ + sha1_init(&state->ctx); + + /* hash opad ^ key */ + sha1_update(&state->ctx, (uint8_t *)state->opad, 64); + + /* hash the result of the inner hash */ + sha1_update(&state->ctx, (uint8_t *)H, 20); + + /* the result is returned in the array hash_value[] */ + sha1_final(&state->ctx, hash_value); + + /* copy hash_value to *result */ + for (i=0; i < tag_len; i++) + result[i] = ((uint8_t *)hash_value)[i]; + + debug_print(mod_hmac, "output: %s", + octet_string_hex_string((uint8_t *)hash_value, tag_len)); + + return err_status_ok; +} + + +/* begin test case 0 */ + +uint8_t +hmac_test_case_0_key[20] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b +}; + +uint8_t +hmac_test_case_0_data[8] = { + 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */ +}; + +uint8_t +hmac_test_case_0_tag[20] = { + 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, + 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, + 0xf1, 0x46, 0xbe, 0x00 +}; + +auth_test_case_t +hmac_test_case_0 = { + 20, /* octets in key */ + hmac_test_case_0_key, /* key */ + 8, /* octets in data */ + hmac_test_case_0_data, /* data */ + 20, /* octets in tag */ + hmac_test_case_0_tag, /* tag */ + NULL /* pointer to next testcase */ +}; + +/* end test case 0 */ + +char hmac_description[] = "hmac sha-1 authentication function"; + +/* + * auth_type_t hmac is the hmac metaobject + */ + +auth_type_t +hmac = { + (auth_alloc_func) hmac_alloc, + (auth_dealloc_func) hmac_dealloc, + (auth_init_func) hmac_init, + (auth_compute_func) hmac_compute, + (auth_update_func) hmac_update, + (auth_start_func) hmac_start, + (char *) hmac_description, + (int) 0, /* instance count */ + (auth_test_case_t *) &hmac_test_case_0, + (debug_module_t *) &mod_hmac, + (auth_type_id_t) HMAC_SHA1 +}; + diff --git a/src/libs/srtp/crypto/hash/null_auth.c b/src/libs/srtp/crypto/hash/null_auth.c new file mode 100644 index 00000000..103444bc --- /dev/null +++ b/src/libs/srtp/crypto/hash/null_auth.c @@ -0,0 +1,162 @@ +/* + * null_auth.c + * + * implements the do-nothing auth algorithm + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "null_auth.h" +#include "alloc.h" + +/* null_auth uses the auth debug module */ + +extern debug_module_t mod_auth; + +err_status_t +null_auth_alloc(auth_t **a, int key_len, int out_len) { + extern auth_type_t null_auth; + uint8_t *pointer; + + debug_print(mod_auth, "allocating auth func with key length %d", key_len); + debug_print(mod_auth, " tag length %d", out_len); + + /* allocate memory for auth and null_auth_ctx_t structures */ + pointer = (uint8_t*)crypto_alloc(sizeof(null_auth_ctx_t) + sizeof(auth_t)); + if (pointer == NULL) + return err_status_alloc_fail; + + /* set pointers */ + *a = (auth_t *)pointer; + (*a)->type = &null_auth; + (*a)->state = pointer + sizeof (auth_t); + (*a)->out_len = out_len; + (*a)->prefix_len = out_len; + (*a)->key_len = key_len; + + /* increment global count of all null_auth uses */ + null_auth.ref_count++; + + return err_status_ok; +} + +err_status_t +null_auth_dealloc(auth_t *a) { + extern auth_type_t null_auth; + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t *)a, + sizeof(null_auth_ctx_t) + sizeof(auth_t)); + + /* free memory */ + crypto_free(a); + + /* decrement global count of all null_auth uses */ + null_auth.ref_count--; + + return err_status_ok; +} + +err_status_t +null_auth_init(null_auth_ctx_t *state, const uint8_t *key, int key_len) { + + /* accept any length of key, and do nothing */ + + return err_status_ok; +} + +err_status_t +null_auth_compute(null_auth_ctx_t *state, uint8_t *message, + int msg_octets, int tag_len, uint8_t *result) { + + return err_status_ok; +} + +err_status_t +null_auth_update(null_auth_ctx_t *state, uint8_t *message, + int msg_octets) { + + return err_status_ok; +} + +err_status_t +null_auth_start(null_auth_ctx_t *state) { + return err_status_ok; +} + +/* + * auth_type_t - defines description, test case, and null_auth + * metaobject + */ + +/* begin test case 0 */ + +auth_test_case_t +null_auth_test_case_0 = { + 0, /* octets in key */ + NULL, /* key */ + 0, /* octets in data */ + NULL, /* data */ + 0, /* octets in tag */ + NULL, /* tag */ + NULL /* pointer to next testcase */ +}; + +/* end test case 0 */ + +char null_auth_description[] = "null authentication function"; + +auth_type_t +null_auth = { + (auth_alloc_func) null_auth_alloc, + (auth_dealloc_func) null_auth_dealloc, + (auth_init_func) null_auth_init, + (auth_compute_func) null_auth_compute, + (auth_update_func) null_auth_update, + (auth_start_func) null_auth_start, + (char *) null_auth_description, + (int) 0, /* instance count */ + (auth_test_case_t *) &null_auth_test_case_0, + (debug_module_t *) NULL, + (auth_type_id_t) NULL_AUTH +}; + diff --git a/src/libs/srtp/crypto/hash/sha1.c b/src/libs/srtp/crypto/hash/sha1.c new file mode 100644 index 00000000..b9a8d105 --- /dev/null +++ b/src/libs/srtp/crypto/hash/sha1.c @@ -0,0 +1,405 @@ +/* + * sha1.c + * + * an implementation of the Secure Hash Algorithm v.1 (SHA-1), + * specified in FIPS 180-1 + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "sha1.h" + +debug_module_t mod_sha1 = { + 0, /* debugging is off by default */ + "sha-1" /* printable module name */ +}; + +/* SN == Rotate left N bits */ +#define S1(X) ((X << 1) | (X >> 31)) +#define S5(X) ((X << 5) | (X >> 27)) +#define S30(X) ((X << 30) | (X >> 2)) + +#define f0(B,C,D) ((B & C) | (~B & D)) +#define f1(B,C,D) (B ^ C ^ D) +#define f2(B,C,D) ((B & C) | (B & D) | (C & D)) +#define f3(B,C,D) (B ^ C ^ D) + +/* + * nota bene: the variable K0 appears in the curses library, so we + * give longer names to these variables to avoid spurious warnings + * on systems that uses curses + */ + +uint32_t SHA_K0 = 0x5A827999; /* Kt for 0 <= t <= 19 */ +uint32_t SHA_K1 = 0x6ED9EBA1; /* Kt for 20 <= t <= 39 */ +uint32_t SHA_K2 = 0x8F1BBCDC; /* Kt for 40 <= t <= 59 */ +uint32_t SHA_K3 = 0xCA62C1D6; /* Kt for 60 <= t <= 79 */ + +void +sha1(const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5]) { + sha1_ctx_t ctx; + + sha1_init(&ctx); + sha1_update(&ctx, msg, octets_in_msg); + sha1_final(&ctx, hash_value); + +} + +/* + * sha1_core(M, H) computes the core compression function, where M is + * the next part of the message (in network byte order) and H is the + * intermediate state { H0, H1, ...} (in host byte order) + * + * this function does not do any of the padding required in the + * complete SHA1 function + * + * this function is used in the SEAL 3.0 key setup routines + * (crypto/cipher/seal.c) + */ + +void +sha1_core(const uint32_t M[16], uint32_t hash_value[5]) { + uint32_t H0; + uint32_t H1; + uint32_t H2; + uint32_t H3; + uint32_t H4; + uint32_t W[80]; + uint32_t A, B, C, D, E, TEMP; + int t; + + /* copy hash_value into H0, H1, H2, H3, H4 */ + H0 = hash_value[0]; + H1 = hash_value[1]; + H2 = hash_value[2]; + H3 = hash_value[3]; + H4 = hash_value[4]; + + /* copy/xor message into array */ + + W[0] = be32_to_cpu(M[0]); + W[1] = be32_to_cpu(M[1]); + W[2] = be32_to_cpu(M[2]); + W[3] = be32_to_cpu(M[3]); + W[4] = be32_to_cpu(M[4]); + W[5] = be32_to_cpu(M[5]); + W[6] = be32_to_cpu(M[6]); + W[7] = be32_to_cpu(M[7]); + W[8] = be32_to_cpu(M[8]); + W[9] = be32_to_cpu(M[9]); + W[10] = be32_to_cpu(M[10]); + W[11] = be32_to_cpu(M[11]); + W[12] = be32_to_cpu(M[12]); + W[13] = be32_to_cpu(M[13]); + W[14] = be32_to_cpu(M[14]); + W[15] = be32_to_cpu(M[15]); + TEMP = W[13] ^ W[8] ^ W[2] ^ W[0]; W[16] = S1(TEMP); + TEMP = W[14] ^ W[9] ^ W[3] ^ W[1]; W[17] = S1(TEMP); + TEMP = W[15] ^ W[10] ^ W[4] ^ W[2]; W[18] = S1(TEMP); + TEMP = W[16] ^ W[11] ^ W[5] ^ W[3]; W[19] = S1(TEMP); + TEMP = W[17] ^ W[12] ^ W[6] ^ W[4]; W[20] = S1(TEMP); + TEMP = W[18] ^ W[13] ^ W[7] ^ W[5]; W[21] = S1(TEMP); + TEMP = W[19] ^ W[14] ^ W[8] ^ W[6]; W[22] = S1(TEMP); + TEMP = W[20] ^ W[15] ^ W[9] ^ W[7]; W[23] = S1(TEMP); + TEMP = W[21] ^ W[16] ^ W[10] ^ W[8]; W[24] = S1(TEMP); + TEMP = W[22] ^ W[17] ^ W[11] ^ W[9]; W[25] = S1(TEMP); + TEMP = W[23] ^ W[18] ^ W[12] ^ W[10]; W[26] = S1(TEMP); + TEMP = W[24] ^ W[19] ^ W[13] ^ W[11]; W[27] = S1(TEMP); + TEMP = W[25] ^ W[20] ^ W[14] ^ W[12]; W[28] = S1(TEMP); + TEMP = W[26] ^ W[21] ^ W[15] ^ W[13]; W[29] = S1(TEMP); + TEMP = W[27] ^ W[22] ^ W[16] ^ W[14]; W[30] = S1(TEMP); + TEMP = W[28] ^ W[23] ^ W[17] ^ W[15]; W[31] = S1(TEMP); + + /* process the remainder of the array */ + for (t=32; t < 80; t++) { + TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]; + W[t] = S1(TEMP); + } + + A = H0; B = H1; C = H2; D = H3; E = H4; + + for (t=0; t < 20; t++) { + TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 40; t++) { + TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 60; t++) { + TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 80; t++) { + TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + + hash_value[0] = H0 + A; + hash_value[1] = H1 + B; + hash_value[2] = H2 + C; + hash_value[3] = H3 + D; + hash_value[4] = H4 + E; + + return; +} + +void +sha1_init(sha1_ctx_t *ctx) { + + /* initialize state vector */ + ctx->H[0] = 0x67452301; + ctx->H[1] = 0xefcdab89; + ctx->H[2] = 0x98badcfe; + ctx->H[3] = 0x10325476; + ctx->H[4] = 0xc3d2e1f0; + + /* indicate that message buffer is empty */ + ctx->octets_in_buffer = 0; + + /* reset message bit-count to zero */ + ctx->num_bits_in_msg = 0; + +} + +void +sha1_update(sha1_ctx_t *ctx, const uint8_t *msg, int octets_in_msg) { + int i; + uint8_t *buf = (uint8_t *)ctx->M; + + /* update message bit-count */ + ctx->num_bits_in_msg += octets_in_msg * 8; + + /* loop over 16-word blocks of M */ + while (octets_in_msg > 0) { + + if (octets_in_msg + ctx->octets_in_buffer >= 64) { + + /* + * copy words of M into msg buffer until that buffer is full, + * converting them into host byte order as needed + */ + octets_in_msg -= (64 - ctx->octets_in_buffer); + for (i=ctx->octets_in_buffer; i < 64; i++) + buf[i] = *msg++; + ctx->octets_in_buffer = 0; + + /* process a whole block */ + + debug_print(mod_sha1, "(update) running sha1_core()", NULL); + + sha1_core(ctx->M, ctx->H); + + } else { + + debug_print(mod_sha1, "(update) not running sha1_core()", NULL); + + for (i=ctx->octets_in_buffer; + i < (ctx->octets_in_buffer + octets_in_msg); i++) + buf[i] = *msg++; + ctx->octets_in_buffer += octets_in_msg; + octets_in_msg = 0; + } + + } + +} + +/* + * sha1_final(ctx, output) computes the result for ctx and copies it + * into the twenty octets located at *output + */ + +void +sha1_final(sha1_ctx_t *ctx, uint32_t *output) { + uint32_t A, B, C, D, E, TEMP; + uint32_t W[80]; + int i, t; + + /* + * process the remaining octets_in_buffer, padding and terminating as + * necessary + */ + { + int tail = ctx->octets_in_buffer % 4; + + /* copy/xor message into array */ + for (i=0; i < (ctx->octets_in_buffer+3)/4; i++) + W[i] = be32_to_cpu(ctx->M[i]); + + /* set the high bit of the octet immediately following the message */ + switch (tail) { + case (3): + W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xffffff00) | 0x80; + W[i] = 0x0; + break; + case (2): + W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xffff0000) | 0x8000; + W[i] = 0x0; + break; + case (1): + W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xff000000) | 0x800000; + W[i] = 0x0; + break; + case (0): + W[i] = 0x80000000; + break; + } + + /* zeroize remaining words */ + for (i++ ; i < 15; i++) + W[i] = 0x0; + + /* + * if there is room at the end of the word array, then set the + * last word to the bit-length of the message; otherwise, set that + * word to zero and then we need to do one more run of the + * compression algo. + */ + if (ctx->octets_in_buffer < 56) + W[15] = ctx->num_bits_in_msg; + else if (ctx->octets_in_buffer < 60) + W[15] = 0x0; + + /* process the word array */ + for (t=16; t < 80; t++) { + TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]; + W[t] = S1(TEMP); + } + + A = ctx->H[0]; + B = ctx->H[1]; + C = ctx->H[2]; + D = ctx->H[3]; + E = ctx->H[4]; + + for (t=0; t < 20; t++) { + TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 40; t++) { + TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 60; t++) { + TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 80; t++) { + TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + + ctx->H[0] += A; + ctx->H[1] += B; + ctx->H[2] += C; + ctx->H[3] += D; + ctx->H[4] += E; + + } + + debug_print(mod_sha1, "(final) running sha1_core()", NULL); + + if (ctx->octets_in_buffer >= 56) { + + debug_print(mod_sha1, "(final) running sha1_core() again", NULL); + + /* we need to do one final run of the compression algo */ + + /* + * set initial part of word array to zeros, and set the + * final part to the number of bits in the message + */ + for (i=0; i < 15; i++) + W[i] = 0x0; + W[15] = ctx->num_bits_in_msg; + + /* process the word array */ + for (t=16; t < 80; t++) { + TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]; + W[t] = S1(TEMP); + } + + A = ctx->H[0]; + B = ctx->H[1]; + C = ctx->H[2]; + D = ctx->H[3]; + E = ctx->H[4]; + + for (t=0; t < 20; t++) { + TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 40; t++) { + TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 60; t++) { + TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + for ( ; t < 80; t++) { + TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3; + E = D; D = C; C = S30(B); B = A; A = TEMP; + } + + ctx->H[0] += A; + ctx->H[1] += B; + ctx->H[2] += C; + ctx->H[3] += D; + ctx->H[4] += E; + } + + /* copy result into output buffer */ + output[0] = be32_to_cpu(ctx->H[0]); + output[1] = be32_to_cpu(ctx->H[1]); + output[2] = be32_to_cpu(ctx->H[2]); + output[3] = be32_to_cpu(ctx->H[3]); + output[4] = be32_to_cpu(ctx->H[4]); + + /* indicate that message buffer in context is empty */ + ctx->octets_in_buffer = 0; + + return; +} + + + diff --git a/src/libs/srtp/crypto/hash/srtp_auth.c b/src/libs/srtp/crypto/hash/srtp_auth.c new file mode 100644 index 00000000..aaf0269c --- /dev/null +++ b/src/libs/srtp/crypto/hash/srtp_auth.c @@ -0,0 +1,183 @@ +/* + * auth.c + * + * some bookkeeping functions for authentication functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "auth.h" + +/* the debug module for authentiation */ + +debug_module_t mod_auth = { + 0, /* debugging is off by default */ + "auth func" /* printable name for module */ +}; + + +int +auth_get_key_length(const auth_t *a) { + return a->key_len; +} + +int +auth_get_tag_length(const auth_t *a) { + return a->out_len; +} + +int +auth_get_prefix_length(const auth_t *a) { + return a->prefix_len; +} + +int +auth_type_get_ref_count(const auth_type_t *at) { + return at->ref_count; +} + +/* + * auth_type_test() tests an auth function of type ct against + * test cases provided in a list test_data of values of key, data, and tag + * that is known to be good + */ + +/* should be big enough for most occasions */ +#define SELF_TEST_TAG_BUF_OCTETS 32 + +err_status_t +auth_type_test(const auth_type_t *at, const auth_test_case_t *test_data) { + const auth_test_case_t *test_case = test_data; + auth_t *a; + err_status_t status; + uint8_t tag[SELF_TEST_TAG_BUF_OCTETS]; + int i, case_num = 0; + + debug_print(mod_auth, "running self-test for auth function %s", + at->description); + + /* + * check to make sure that we have at least one test case, and + * return an error if we don't - we need to be paranoid here + */ + if (test_case == NULL) + return err_status_cant_check; + + /* loop over all test cases */ + while (test_case != NULL) { + + /* check test case parameters */ + if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS) + return err_status_bad_param; + + /* allocate auth */ + status = auth_type_alloc(at, &a, test_case->key_length_octets, + test_case->tag_length_octets); + if (status) + return status; + + /* initialize auth */ + status = auth_init(a, test_case->key); + if (status) { + auth_dealloc(a); + return status; + } + + /* zeroize tag then compute */ + octet_string_set_to_zero(tag, test_case->tag_length_octets); + status = auth_compute(a, test_case->data, + test_case->data_length_octets, tag); + if (status) { + auth_dealloc(a); + return status; + } + + debug_print(mod_auth, "key: %s", + octet_string_hex_string(test_case->key, + test_case->key_length_octets)); + debug_print(mod_auth, "data: %s", + octet_string_hex_string(test_case->data, + test_case->data_length_octets)); + debug_print(mod_auth, "tag computed: %s", + octet_string_hex_string(tag, test_case->tag_length_octets)); + debug_print(mod_auth, "tag expected: %s", + octet_string_hex_string(test_case->tag, + test_case->tag_length_octets)); + + /* check the result */ + status = err_status_ok; + for (i=0; i < test_case->tag_length_octets; i++) + if (tag[i] != test_case->tag[i]) { + status = err_status_algo_fail; + debug_print(mod_auth, "test case %d failed", case_num); + debug_print(mod_auth, " (mismatch at octet %d)", i); + } + if (status) { + auth_dealloc(a); + return err_status_algo_fail; + } + + /* deallocate the auth function */ + status = auth_dealloc(a); + if (status) + return status; + + /* + * the auth function passed the test case, so move on to the next test + * case in the list; if NULL, we'll quit and return an OK + */ + test_case = test_case->next_test_case; + ++case_num; + } + + return err_status_ok; +} + + +/* + * auth_type_self_test(at) performs auth_type_test on at's internal + * list of test data. + */ + +err_status_t +auth_type_self_test(const auth_type_t *at) { + return auth_type_test(at, at->test_data); +} + diff --git a/src/libs/srtp/crypto/include/aes.h b/src/libs/srtp/crypto/include/aes.h new file mode 100644 index 00000000..28813374 --- /dev/null +++ b/src/libs/srtp/crypto/include/aes.h @@ -0,0 +1,90 @@ +/* + * aes.h + * + * header file for the AES block cipher + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _AES_H +#define _AES_H + +#include "config.h" + +#include "datatypes.h" +#include "gf2_8.h" +#include "err.h" + +/* aes internals */ + +typedef struct { + v128_t round[15]; + int num_rounds; +} aes_expanded_key_t; + +err_status_t +aes_expand_encryption_key(const uint8_t *key, + int key_len, + aes_expanded_key_t *expanded_key); + +err_status_t +aes_expand_decryption_key(const uint8_t *key, + int key_len, + aes_expanded_key_t *expanded_key); + +void +aes_encrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key); + +void +aes_decrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key); + +#if 0 +/* + * internal functions + */ + +void +aes_init_sbox(void); + +void +aes_compute_tables(void); +#endif + +#endif /* _AES_H */ diff --git a/src/libs/srtp/crypto/include/aes_cbc.h b/src/libs/srtp/crypto/include/aes_cbc.h new file mode 100644 index 00000000..bc4e41a4 --- /dev/null +++ b/src/libs/srtp/crypto/include/aes_cbc.h @@ -0,0 +1,50 @@ +/* + * aes_cbc.h + * + * Header for AES Cipher Blobk Chaining Mode. + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ + +#ifndef AES_CBC_H +#define AES_CBC_H + +#include "aes.h" +#include "cipher.h" + +typedef struct { + v128_t state; /* cipher chaining state */ + v128_t previous; /* previous ciphertext block */ + aes_expanded_key_t expanded_key; /* the cipher key */ +} aes_cbc_ctx_t; + +err_status_t +aes_cbc_set_key(aes_cbc_ctx_t *c, + const unsigned char *key); + +err_status_t +aes_cbc_encrypt(aes_cbc_ctx_t *c, + unsigned char *buf, + unsigned int *bytes_in_data); + +err_status_t +aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, + int key_len, cipher_direction_t dir); + +err_status_t +aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv); + +err_status_t +aes_cbc_nist_encrypt(aes_cbc_ctx_t *c, + unsigned char *data, + unsigned int *bytes_in_data); + +err_status_t +aes_cbc_nist_decrypt(aes_cbc_ctx_t *c, + unsigned char *data, + unsigned int *bytes_in_data); + +#endif /* AES_CBC_H */ + diff --git a/src/libs/srtp/crypto/include/aes_icm.h b/src/libs/srtp/crypto/include/aes_icm.h new file mode 100644 index 00000000..dac0cdcc --- /dev/null +++ b/src/libs/srtp/crypto/include/aes_icm.h @@ -0,0 +1,57 @@ +/* + * aes_icm.h + * + * Header for AES Integer Counter Mode. + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ + +#ifndef AES_ICM_H +#define AES_ICM_H + +#include "aes.h" +#include "cipher.h" + +typedef struct { + v128_t counter; /* holds the counter value */ + v128_t offset; /* initial offset value */ + v128_t keystream_buffer; /* buffers bytes of keystream */ + aes_expanded_key_t expanded_key; /* the cipher key */ + int bytes_in_buffer; /* number of unused bytes in buffer */ +} aes_icm_ctx_t; + + +err_status_t +aes_icm_context_init(aes_icm_ctx_t *c, + const unsigned char *key, + int key_len); + +err_status_t +aes_icm_set_iv(aes_icm_ctx_t *c, void *iv); + +err_status_t +aes_icm_encrypt(aes_icm_ctx_t *c, + unsigned char *buf, unsigned int *bytes_to_encr); + +err_status_t +aes_icm_output(aes_icm_ctx_t *c, + unsigned char *buf, int bytes_to_output); + +err_status_t +aes_icm_dealloc(cipher_t *c); + +err_status_t +aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c, + unsigned char *buf, + unsigned int *enc_len, + int forIsmacryp); + +err_status_t +aes_icm_alloc_ismacryp(cipher_t **c, + int key_len, + int forIsmacryp); + +#endif /* AES_ICM_H */ + diff --git a/src/libs/srtp/crypto/include/alloc.h b/src/libs/srtp/crypto/include/alloc.h new file mode 100644 index 00000000..5980eed6 --- /dev/null +++ b/src/libs/srtp/crypto/include/alloc.h @@ -0,0 +1,57 @@ +/* + * alloc.h + * + * interface to memory allocation and deallocation, with optional debugging + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef CRYPTO_ALLOC_H +#define CRYPTO_ALLOC_H + +#include "datatypes.h" + +void * +crypto_alloc(size_t size); + +void +crypto_free(void *ptr); + +#endif /* CRYPTO_ALLOC_H */ diff --git a/src/libs/srtp/crypto/include/auth.h b/src/libs/srtp/crypto/include/auth.h new file mode 100644 index 00000000..5b5e4b21 --- /dev/null +++ b/src/libs/srtp/crypto/include/auth.h @@ -0,0 +1,171 @@ +/* + * auth.h + * + * common interface to authentication functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef AUTH_H +#define AUTH_H + +#include "datatypes.h" +#include "err.h" /* error codes */ +#include "crypto.h" /* for auth_type_id_t */ +#include "crypto_types.h" /* for values of auth_type_id_t */ + +typedef struct auth_type_t *auth_type_pointer; +typedef struct auth_t *auth_pointer_t; + +typedef err_status_t (*auth_alloc_func) + (auth_pointer_t *ap, int key_len, int out_len); + +typedef err_status_t (*auth_init_func) + (void *state, const uint8_t *key, int key_len); + +typedef err_status_t (*auth_dealloc_func)(auth_pointer_t ap); + +typedef err_status_t (*auth_compute_func) + (void *state, uint8_t *buffer, int octets_to_auth, + int tag_len, uint8_t *tag); + +typedef err_status_t (*auth_update_func) + (void *state, uint8_t *buffer, int octets_to_auth); + +typedef err_status_t (*auth_start_func)(void *state); + +/* some syntactic sugar on these function types */ + +#define auth_type_alloc(at, a, klen, outlen) \ + ((at)->alloc((a), (klen), (outlen))) + +#define auth_init(a, key) \ + (((a)->type)->init((a)->state, (key), ((a)->key_len))) + +#define auth_compute(a, buf, len, res) \ + (((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res))) + +#define auth_update(a, buf, len) \ + (((a)->type)->update((a)->state, (buf), (len))) + +#define auth_start(a)(((a)->type)->start((a)->state)) + +#define auth_dealloc(c) (((c)->type)->dealloc(c)) + +/* functions to get information about a particular auth_t */ + +int +auth_get_key_length(const struct auth_t *a); + +int +auth_get_tag_length(const struct auth_t *a); + +int +auth_get_prefix_length(const struct auth_t *a); + +/* + * auth_test_case_t is a (list of) key/message/tag values that are + * known to be correct for a particular cipher. this data can be used + * to test an implementation in an on-the-fly self test of the + * correcness of the implementation. (see the auth_type_self_test() + * function below) + */ + +typedef struct auth_test_case_t { + int key_length_octets; /* octets in key */ + uint8_t *key; /* key */ + int data_length_octets; /* octets in data */ + uint8_t *data; /* data */ + int tag_length_octets; /* octets in tag */ + uint8_t *tag; /* tag */ + struct auth_test_case_t *next_test_case; /* pointer to next testcase */ +} auth_test_case_t; + +/* auth_type_t */ + +typedef struct auth_type_t { + auth_alloc_func alloc; + auth_dealloc_func dealloc; + auth_init_func init; + auth_compute_func compute; + auth_update_func update; + auth_start_func start; + char *description; + int ref_count; + auth_test_case_t *test_data; + debug_module_t *debug; + auth_type_id_t id; +} auth_type_t; + +typedef struct auth_t { + auth_type_t *type; + void *state; + int out_len; /* length of output tag in octets */ + int key_len; /* length of key in octets */ + int prefix_len; /* length of keystream prefix */ +} auth_t; + +/* + * auth_type_self_test() tests an auth_type against test cases + * provided in an array of values of key/message/tag that is known to + * be good + */ + +err_status_t +auth_type_self_test(const auth_type_t *at); + +/* + * auth_type_test() tests an auth_type against external test cases + * provided in an array of values of key/message/tag that is known to + * be good + */ + +err_status_t +auth_type_test(const auth_type_t *at, const auth_test_case_t *test_data); + +/* + * auth_type_get_ref_count(at) returns the reference count (the number + * of instantiations) of the auth_type_t at + */ + +int +auth_type_get_ref_count(const auth_type_t *at); + +#endif /* AUTH_H */ diff --git a/src/libs/srtp/crypto/include/cipher.h b/src/libs/srtp/crypto/include/cipher.h new file mode 100644 index 00000000..eff6dd15 --- /dev/null +++ b/src/libs/srtp/crypto/include/cipher.h @@ -0,0 +1,230 @@ +/* + * cipher.h + * + * common interface to ciphers + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef CIPHER_H +#define CIPHER_H + +#include "datatypes.h" +#include "rdbx.h" /* for xtd_seq_num_t */ +#include "err.h" /* for error codes */ +#include "crypto.h" /* for cipher_type_id_t */ +#include "crypto_types.h" /* for values of cipher_type_id_t */ + + +/** + * @brief cipher_direction_t defines a particular cipher operation. + * + * A cipher_direction_t is an enum that describes a particular cipher + * operation, i.e. encryption or decryption. For some ciphers, this + * distinction does not matter, but for others, it is essential. + */ + +typedef enum { + direction_encrypt, /**< encryption (convert plaintext to ciphertext) */ + direction_decrypt, /**< decryption (convert ciphertext to plaintext) */ + direction_any /**< encryption or decryption */ +} cipher_direction_t; + +/* + * the cipher_pointer and cipher_type_pointer definitions are needed + * as cipher_t and cipher_type_t are not yet defined + */ + +typedef struct cipher_type_t *cipher_type_pointer_t; +typedef struct cipher_t *cipher_pointer_t; + +/* + * a cipher_alloc_func_t allocates (but does not initialize) a cipher_t + */ + +typedef err_status_t (*cipher_alloc_func_t) + (cipher_pointer_t *cp, int key_len); + +/* + * a cipher_init_func_t [re-]initializes a cipher_t with a given key + * and direction (i.e., encrypt or decrypt) + */ + +typedef err_status_t (*cipher_init_func_t) +(void *state, const uint8_t *key, int key_len, cipher_direction_t dir); + +/* a cipher_dealloc_func_t de-allocates a cipher_t */ + +typedef err_status_t (*cipher_dealloc_func_t)(cipher_pointer_t cp); + +/* a cipher_set_segment_func_t sets the segment index of a cipher_t */ + +typedef err_status_t (*cipher_set_segment_func_t) + (void *state, xtd_seq_num_t idx); + +/* a cipher_encrypt_func_t encrypts data in-place */ + +typedef err_status_t (*cipher_encrypt_func_t) + (void *state, uint8_t *buffer, unsigned int *octets_to_encrypt); + +/* a cipher_decrypt_func_t decrypts data in-place */ + +typedef err_status_t (*cipher_decrypt_func_t) + (void *state, uint8_t *buffer, unsigned int *octets_to_decrypt); + +/* + * a cipher_set_iv_func_t function sets the current initialization vector + */ + +typedef err_status_t (*cipher_set_iv_func_t) + (cipher_pointer_t cp, void *iv); + +/* + * cipher_test_case_t is a (list of) key, salt, xtd_seq_num_t, + * plaintext, and ciphertext values that are known to be correct for a + * particular cipher. this data can be used to test an implementation + * in an on-the-fly self test of the correcness of the implementation. + * (see the cipher_type_self_test() function below) + */ + +typedef struct cipher_test_case_t { + int key_length_octets; /* octets in key */ + uint8_t *key; /* key */ + uint8_t *idx; /* packet index */ + int plaintext_length_octets; /* octets in plaintext */ + uint8_t *plaintext; /* plaintext */ + int ciphertext_length_octets; /* octets in plaintext */ + uint8_t *ciphertext; /* ciphertext */ + struct cipher_test_case_t *next_test_case; /* pointer to next testcase */ +} cipher_test_case_t; + +/* cipher_type_t defines the 'metadata' for a particular cipher type */ + +typedef struct cipher_type_t { + cipher_alloc_func_t alloc; + cipher_dealloc_func_t dealloc; + cipher_init_func_t init; + cipher_encrypt_func_t encrypt; + cipher_encrypt_func_t decrypt; + cipher_set_iv_func_t set_iv; + char *description; + int ref_count; + cipher_test_case_t *test_data; + debug_module_t *debug; + cipher_type_id_t id; +} cipher_type_t; + +/* + * cipher_t defines an instantiation of a particular cipher, with fixed + * key length, key and salt values + */ + +typedef struct cipher_t { + cipher_type_t *type; + void *state; + int key_len; +#ifdef FORCE_64BIT_ALIGN + int pad; +#endif +} cipher_t; + +/* some syntactic sugar on these function types */ + +#define cipher_type_alloc(ct, c, klen) ((ct)->alloc((c), (klen))) + +#define cipher_dealloc(c) (((c)->type)->dealloc(c)) + +#define cipher_init(c, k, dir) (((c)->type)->init(((c)->state), (k), ((c)->key_len), (dir))) + +#define cipher_encrypt(c, buf, len) \ + (((c)->type)->encrypt(((c)->state), (buf), (len))) + +#define cipher_decrypt(c, buf, len) \ + (((c)->type)->decrypt(((c)->state), (buf), (len))) + +#define cipher_set_iv(c, n) \ + ((c) ? (((c)->type)->set_iv(((cipher_pointer_t)(c)->state), (n))) : \ + err_status_no_such_op) + +err_status_t +cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output); + + +/* some bookkeeping functions */ + +int +cipher_get_key_length(const cipher_t *c); + + +/* + * cipher_type_self_test() tests a cipher against test cases provided in + * an array of values of key/xtd_seq_num_t/plaintext/ciphertext + * that is known to be good + */ + +err_status_t +cipher_type_self_test(const cipher_type_t *ct); + + +/* + * cipher_type_test() tests a cipher against external test cases provided in + * an array of values of key/xtd_seq_num_t/plaintext/ciphertext + * that is known to be good + */ + +err_status_t +cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data); + + +/* + * cipher_bits_per_second(c, l, t) computes (and estimate of) the + * number of bits that a cipher implementation can encrypt in a second + * + * c is a cipher (which MUST be allocated and initialized already), l + * is the length in octets of the test data to be encrypted, and t is + * the number of trials + * + * if an error is encountered, then the value 0 is returned + */ + +uint64_t +cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials); + +#endif /* CIPHER_H */ diff --git a/src/libs/srtp/crypto/include/config.h b/src/libs/srtp/crypto/include/config.h new file mode 100644 index 00000000..93c91148 --- /dev/null +++ b/src/libs/srtp/crypto/include/config.h @@ -0,0 +1,16 @@ +#ifndef SRTP_CONFIG_H +#define SRTP_CONFIG_H + +#define HAVE_STDLIB_H + +#ifdef WIN32 +# define inline __inline +#endif + +#ifdef WIN32 +#define HAVE_WINSOCK2_H 1 +#define CPU_CISC 1 +#else +#endif + +#endif diff --git a/src/libs/srtp/crypto/include/crypto.h b/src/libs/srtp/crypto/include/crypto.h new file mode 100644 index 00000000..0e9667da --- /dev/null +++ b/src/libs/srtp/crypto/include/crypto.h @@ -0,0 +1,43 @@ +/* + * crypto.h + * + * API for libcrypto + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +#ifndef CRYPTO_H +#define CRYPTO_H + +/** + * @brief A cipher_type_id_t is an identifier for a particular cipher + * type. + * + * A cipher_type_id_t is an integer that represents a particular + * cipher type, e.g. the Advanced Encryption Standard (AES). A + * NULL_CIPHER is avaliable; this cipher leaves the data unchanged, + * and can be selected to indicate that no encryption is to take + * place. + * + * @ingroup Ciphers + */ +typedef uint32_t cipher_type_id_t; + +/** + * @brief An auth_type_id_t is an identifier for a particular authentication + * function. + * + * An auth_type_id_t is an integer that represents a particular + * authentication function type, e.g. HMAC-SHA1. A NULL_AUTH is + * avaliable; this authentication function performs no computation, + * and can be selected to indicate that no authentication is to take + * place. + * + * @ingroup Authentication + */ +typedef uint32_t auth_type_id_t; + +#endif /* CRYPTO_H */ + + diff --git a/src/libs/srtp/crypto/include/crypto_kernel.h b/src/libs/srtp/crypto/include/crypto_kernel.h new file mode 100644 index 00000000..1acf4978 --- /dev/null +++ b/src/libs/srtp/crypto/include/crypto_kernel.h @@ -0,0 +1,280 @@ +/* + * crypto_kernel.h + * + * header for the cryptographic kernel + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef CRYPTO_KERNEL +#define CRYPTO_KERNEL + +#include "rand_source.h" +#include "prng.h" +#include "cipher.h" +#include "auth.h" +#include "cryptoalg.h" +#include "stat.h" +#include "err.h" +#include "crypto_types.h" +#include "key.h" +#include "crypto.h" + +/* + * crypto_kernel_state_t defines the possible states: + * + * insecure - not yet initialized + * secure - initialized and passed self-tests + */ + +typedef enum { + crypto_kernel_state_insecure, + crypto_kernel_state_secure +} crypto_kernel_state_t; + +/* + * linked list of cipher types + */ + +typedef struct kernel_cipher_type { + cipher_type_id_t id; + cipher_type_t *cipher_type; + struct kernel_cipher_type *next; +} kernel_cipher_type_t; + +/* + * linked list of auth types + */ + +typedef struct kernel_auth_type { + auth_type_id_t id; + auth_type_t *auth_type; + struct kernel_auth_type *next; +} kernel_auth_type_t; + +/* + * linked list of debug modules + */ + +typedef struct kernel_debug_module { + debug_module_t *mod; + struct kernel_debug_module *next; +} kernel_debug_module_t; + + +/* + * crypto_kernel_t is the data structure for the crypto kernel + * + * note that there is *exactly one* instance of this data type, + * a global variable defined in crypto_kernel.c + */ + +typedef struct { + crypto_kernel_state_t state; /* current state of kernel */ + kernel_cipher_type_t *cipher_type_list; /* list of all cipher types */ + kernel_auth_type_t *auth_type_list; /* list of all auth func types */ + kernel_debug_module_t *debug_module_list; /* list of all debug modules */ +} crypto_kernel_t; + + +/* + * crypto_kernel_t external api + */ + + +/* + * The function crypto_kernel_init() initialized the crypto kernel and + * runs the self-test operations on the random number generators and + * crypto algorithms. Possible return values are: + * + * err_status_ok initialization successful + * <other> init failure + * + * If any value other than err_status_ok is returned, the + * crypto_kernel MUST NOT be used. + */ + +err_status_t +crypto_kernel_init(void); + + +/* + * The function crypto_kernel_shutdown() de-initializes the + * crypto_kernel, zeroizes keys and other cryptographic material, and + * deallocates any dynamically allocated memory. Possible return + * values are: + * + * err_status_ok shutdown successful + * <other> shutdown failure + * + */ + +err_status_t +crypto_kernel_shutdown(void); + +/* + * The function crypto_kernel_stats() checks the the crypto_kernel, + * running tests on the ciphers, auth funcs, and rng, and prints out a + * status report. Possible return values are: + * + * err_status_ok all tests were passed + * <other> a test failed + * + */ + +err_status_t +crypto_kernel_status(void); + + +/* + * crypto_kernel_list_debug_modules() outputs a list of debugging modules + * + */ + +err_status_t +crypto_kernel_list_debug_modules(void); + +/* + * crypto_kernel_load_cipher_type() + * + */ + +err_status_t +crypto_kernel_load_cipher_type(cipher_type_t *ct, cipher_type_id_t id); + +err_status_t +crypto_kernel_load_auth_type(auth_type_t *ct, auth_type_id_t id); + +/* + * crypto_kernel_replace_cipher_type(ct, id) + * + * replaces the crypto kernel's existing cipher for the cipher_type id + * with a new one passed in externally. The new cipher must pass all the + * existing cipher_type's self tests as well as its own. + */ +err_status_t +crypto_kernel_replace_cipher_type(cipher_type_t *ct, cipher_type_id_t id); + + +/* + * crypto_kernel_replace_auth_type(ct, id) + * + * replaces the crypto kernel's existing cipher for the auth_type id + * with a new one passed in externally. The new auth type must pass all the + * existing auth_type's self tests as well as its own. + */ +err_status_t +crypto_kernel_replace_auth_type(auth_type_t *ct, auth_type_id_t id); + + +err_status_t +crypto_kernel_load_debug_module(debug_module_t *new_dm); + +/* + * crypto_kernel_alloc_cipher(id, cp, key_len); + * + * allocates a cipher of type id at location *cp, with key length + * key_len octets. Return values are: + * + * err_status_ok no problems + * err_status_alloc_fail an allocation failure occured + * err_status_fail couldn't find cipher with identifier 'id' + */ + +err_status_t +crypto_kernel_alloc_cipher(cipher_type_id_t id, + cipher_pointer_t *cp, + int key_len); + +/* + * crypto_kernel_alloc_auth(id, ap, key_len, tag_len); + * + * allocates an auth function of type id at location *ap, with key + * length key_len octets and output tag length of tag_len. Return + * values are: + * + * err_status_ok no problems + * err_status_alloc_fail an allocation failure occured + * err_status_fail couldn't find auth with identifier 'id' + */ + +err_status_t +crypto_kernel_alloc_auth(auth_type_id_t id, + auth_pointer_t *ap, + int key_len, + int tag_len); + + +/* + * crypto_kernel_set_debug_module(mod_name, v) + * + * sets dynamic debugging to the value v (0 for off, 1 for on) for the + * debug module with the name mod_name + * + * returns err_status_ok on success, err_status_fail otherwise + */ + +err_status_t +crypto_kernel_set_debug_module(char *mod_name, int v); + +/** + * @brief writes a random octet string. + * + * The function call crypto_get_random(dest, len) writes len octets of + * random data to the location to which dest points, and returns an + * error code. This error code @b must be checked, and if a failure is + * reported, the data in the buffer @b must @b not be used. + * + * @warning If the return code is not checked, then non-random + * data may be in the buffer. This function will fail + * unless it is called after crypto_kernel_init(). + * + * @return + * - err_status_ok if no problems occured. + * - [other] a problem occured, and no assumptions should + * be made about the contents of the destination + * buffer. + * + * @ingroup SRTP + */ +err_status_t +crypto_get_random(unsigned char *buffer, unsigned int length); + +#endif /* CRYPTO_KERNEL */ diff --git a/src/libs/srtp/crypto/include/crypto_math.h b/src/libs/srtp/crypto/include/crypto_math.h new file mode 100644 index 00000000..52f08372 --- /dev/null +++ b/src/libs/srtp/crypto/include/crypto_math.h @@ -0,0 +1,239 @@ +/* + * math.h + * + * crypto math operations and data types + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef MATH_H +#define MATH_H + +#include "datatypes.h" + +unsigned char +v32_weight(v32_t a); + +unsigned char +v32_distance(v32_t x, v32_t y); + +unsigned int +v32_dot_product(v32_t a, v32_t b); + +char * +v16_bit_string(v16_t x); + +char * +v32_bit_string(v32_t x); + +char * +v64_bit_string(const v64_t *x); + +char * +octet_hex_string(uint8_t x); + +char * +v16_hex_string(v16_t x); + +char * +v32_hex_string(v32_t x); + +char * +v64_hex_string(const v64_t *x); + +int +hex_char_to_nibble(uint8_t c); + +int +is_hex_string(char *s); + +v16_t +hex_string_to_v16(char *s); + +v32_t +hex_string_to_v32(char *s); + +v64_t +hex_string_to_v64(char *s); + +/* the matrix A[] is stored in column format, i.e., A[i] is + the ith column of the matrix */ + +uint8_t +A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b); + +void +v16_copy_octet_string(v16_t *x, const uint8_t s[2]); + +void +v32_copy_octet_string(v32_t *x, const uint8_t s[4]); + +void +v64_copy_octet_string(v64_t *x, const uint8_t s[8]); + +void +v128_add(v128_t *z, v128_t *x, v128_t *y); + +int +octet_string_is_eq(uint8_t *a, uint8_t *b, int len); + +void +octet_string_set_to_zero(uint8_t *s, int len); + + + +/* + * the matrix A[] is stored in column format, i.e., A[i] is the ith + * column of the matrix +*/ +uint8_t +A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b); + + +#if 0 +#if WORDS_BIGENDIAN + +#define _v128_add(z, x, y) { \ + uint64_t tmp; \ + \ + tmp = x->v32[3] + y->v32[3]; \ + z->v32[3] = (uint32_t) tmp; \ + \ + tmp = x->v32[2] + y->v32[2] + (tmp >> 32); \ + z->v32[2] = (uint32_t) tmp; \ + \ + tmp = x->v32[1] + y->v32[1] + (tmp >> 32); \ + z->v32[1] = (uint32_t) tmp; \ + \ + tmp = x->v32[0] + y->v32[0] + (tmp >> 32); \ + z->v32[0] = (uint32_t) tmp; \ +} + +#else /* assume little endian architecture */ + +#define _v128_add(z, x, y) { \ + uint64_t tmp; \ + \ + tmp = htonl(x->v32[3]) + htonl(y->v32[3]); \ + z->v32[3] = ntohl((uint32_t) tmp); \ + \ + tmp = htonl(x->v32[2]) + htonl(y->v32[2]) \ + + htonl(tmp >> 32); \ + z->v32[2] = ntohl((uint32_t) tmp); \ + \ + tmp = htonl(x->v32[1]) + htonl(y->v32[1]) \ + + htonl(tmp >> 32); \ + z->v32[1] = ntohl((uint32_t) tmp); \ + \ + tmp = htonl(x->v32[0]) + htonl(y->v32[0]) \ + + htonl(tmp >> 32); \ + z->v32[0] = ntohl((uint32_t) tmp); \ +} + +#endif /* WORDS_BIGENDIAN */ +#endif + +#ifdef DATATYPES_USE_MACROS /* little functions are really macros */ + +#define v128_set_to_zero(z) _v128_set_to_zero(z) +#define v128_copy(z, x) _v128_copy(z, x) +#define v128_xor(z, x, y) _v128_xor(z, x, y) +#define v128_and(z, x, y) _v128_and(z, x, y) +#define v128_or(z, x, y) _v128_or(z, x, y) +#define v128_complement(x) _v128_complement(x) +#define v128_is_eq(x, y) _v128_is_eq(x, y) +#define v128_xor_eq(x, y) _v128_xor_eq(x, y) +#define v128_get_bit(x, i) _v128_get_bit(x, i) +#define v128_set_bit(x, i) _v128_set_bit(x, i) +#define v128_clear_bit(x, i) _v128_clear_bit(x, i) +#define v128_set_bit_to(x, i, y) _v128_set_bit_to(x, i, y) + +#else + +void +v128_set_to_zero(v128_t *x); + +int +v128_is_eq(const v128_t *x, const v128_t *y); + +void +v128_copy(v128_t *x, const v128_t *y); + +void +v128_xor(v128_t *z, v128_t *x, v128_t *y); + +void +v128_and(v128_t *z, v128_t *x, v128_t *y); + +void +v128_or(v128_t *z, v128_t *x, v128_t *y); + +void +v128_complement(v128_t *x); + +int +v128_get_bit(const v128_t *x, int i); + +void +v128_set_bit(v128_t *x, int i) ; + +void +v128_clear_bit(v128_t *x, int i); + +void +v128_set_bit_to(v128_t *x, int i, int y); + +#endif /* DATATYPES_USE_MACROS */ + +/* + * octet_string_is_eq(a,b, len) returns 1 if the length len strings a + * and b are not equal, returns 0 otherwise + */ + +int +octet_string_is_eq(uint8_t *a, uint8_t *b, int len); + +void +octet_string_set_to_zero(uint8_t *s, int len); + + +#endif /* MATH_H */ + + + diff --git a/src/libs/srtp/crypto/include/crypto_types.h b/src/libs/srtp/crypto/include/crypto_types.h new file mode 100644 index 00000000..35317108 --- /dev/null +++ b/src/libs/srtp/crypto/include/crypto_types.h @@ -0,0 +1,220 @@ +/* + * crypto_types.h + * + * constants for cipher types and auth func types + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef CRYPTO_TYPES_H +#define CRYPTO_TYPES_H + +/** + * @defgroup Algos Cryptographic Algorithms + * + * + * This library provides several different cryptographic algorithms, + * each of which can be selected by using the cipher_type_id_t and + * auth_type_id_t. These algorithms are documented below. + * + * Authentication functions that use the Universal Security Transform + * (UST) must be used in conjunction with a cipher other than the null + * cipher. These functions require a per-message pseudorandom input + * that is generated by the cipher. + * + * The identifiers STRONGHOLD_AUTH and STRONGHOLD_CIPHER identify the + * strongest available authentication function and cipher, + * respectively. They are resolved at compile time to the strongest + * available algorithm. The stronghold algorithms can serve as did + * the keep of a medieval fortification; they provide the strongest + * defense (or the last refuge). + * + * @{ + */ + +/** + * @defgroup Ciphers Cipher Types + * + * @brief Each cipher type is identified by an unsigned integer. The + * cipher types available in this edition of libSRTP are given + * by the #defines below. + * + * A cipher_type_id_t is an identifier for a cipher_type; only values + * given by the #defines above (or those present in the file + * crypto_types.h) should be used. + * + * The identifier STRONGHOLD_CIPHER indicates the strongest available + * cipher, allowing an application to choose the strongest available + * algorithm without any advance knowledge about the avaliable + * algorithms. + * + * @{ + */ + +/** + * @brief The null cipher performs no encryption. + * + * The NULL_CIPHER leaves its inputs unaltered, during both the + * encryption and decryption operations. This cipher can be chosen + * to indicate that no encryption is to be performed. + */ +#define NULL_CIPHER 0 + +/** + * @brief AES Integer Counter Mode (AES ICM) + * + * AES ICM is the variant of counter mode that is used by Secure RTP. + * This cipher uses a 16-, 24-, or 32-octet key concatenated with a + * 14-octet offset (or salt) value. + */ +#define AES_ICM 1 + +/** + * @brief AES-128 Integer Counter Mode (AES ICM) + * AES-128 ICM is a deprecated alternate name for AES ICM. + */ +#define AES_128_ICM AES_ICM + +/** + * @brief SEAL 3.0 + * + * SEAL is the Software-Optimized Encryption Algorithm of Coppersmith + * and Rogaway. Nota bene: this cipher is IBM proprietary. + */ +#define SEAL 2 + +/** + * @brief AES Cipher Block Chaining mode (AES CBC) + * + * AES CBC is the AES Cipher Block Chaining mode. + * This cipher uses a 16-, 24-, or 32-octet key. + */ +#define AES_CBC 3 + +/** + * @brief AES-128 Cipher Block Chaining mode (AES CBC) + * + * AES-128 CBC is a deprecated alternate name for AES CBC. + */ +#define AES_128_CBC AES_CBC + +/** + * @brief Strongest available cipher. + * + * This identifier resolves to the strongest cipher type available. + */ +#define STRONGHOLD_CIPHER AES_ICM + +/** + * @} + */ + + + +/** + * @defgroup Authentication Authentication Function Types + * + * @brief Each authentication function type is identified by an + * unsigned integer. The authentication function types available in + * this edition of libSRTP are given by the #defines below. + * + * An auth_type_id_t is an identifier for an authentication function type; + * only values given by the #defines above (or those present in the + * file crypto_types.h) should be used. + * + * The identifier STRONGHOLD_AUTH indicates the strongest available + * authentication function, allowing an application to choose the + * strongest available algorithm without any advance knowledge about + * the avaliable algorithms. The stronghold algorithms can serve as + * did the keep of a medieval fortification; they provide the + * strongest defense (or the last refuge). + * + * @{ + */ + +/** + * @brief The null authentication function performs no authentication. + * + * The NULL_AUTH function does nothing, and can be selected to indicate + * that authentication should not be performed. + */ +#define NULL_AUTH 0 + +/** + * @brief UST with TMMH Version 2 + * + * UST_TMMHv2 implements the Truncated Multi-Modular Hash using + * UST. This function must be used in conjunction with a cipher other + * than the null cipher. + * with a cipher. + */ +#define UST_TMMHv2 1 + +/** + * @brief (UST) AES-128 XORMAC + * + * UST_AES_128_XMAC implements AES-128 XORMAC, using UST. Nota bene: + * the XORMAC algorithm is IBM proprietary. + */ +#define UST_AES_128_XMAC 2 + +/** + * @brief HMAC-SHA1 + * + * HMAC_SHA1 implements the Hash-based MAC using the NIST Secure + * Hash Algorithm version 1 (SHA1). + */ +#define HMAC_SHA1 3 + +/** + * @brief Strongest available authentication function. + * + * This identifier resolves to the strongest available authentication + * function. + */ +#define STRONGHOLD_AUTH HMAC_SHA1 + +/** + * @} + */ +/** + * @} + */ + +#endif /* CRYPTO_TYPES_H */ diff --git a/src/libs/srtp/crypto/include/cryptoalg.h b/src/libs/srtp/crypto/include/cryptoalg.h new file mode 100644 index 00000000..d9f0441e --- /dev/null +++ b/src/libs/srtp/crypto/include/cryptoalg.h @@ -0,0 +1,133 @@ +/* + * cryptoalg.h + * + * API for authenticated encryption crypto algorithms + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef CRYPTOALG_H +#define CRYPTOALG_H + +#include "err.h" + +/** + * @defgroup Crypto Cryptography + * + * Zed uses a simple interface to a cryptographic transform. + * + * @{ + */ + +/** + * @brief applies a crypto algorithm + * + * The function pointer cryptoalg_func_t points to a function that + * implements a crypto transform, and provides a uniform API for + * accessing crypto mechanisms. + * + * @param key location of secret key + * + * @param clear data to be authenticated but not encrypted + * + * @param clear_len length of data to be authenticated but not encrypted + * + * @param iv location to write the Initialization Vector (IV) + * + * @param protect location of the data to be encrypted and + * authenticated (before the function call), and the ciphertext + * and authentication tag (after the call) + * + * @param protected_len location of the length of the data to be + * encrypted and authenticated (before the function call), and the + * length of the ciphertext (after the call) + * + */ + +typedef err_status_t (*cryptoalg_func_t) + (void *key, + const void *clear, + unsigned clear_len, + void *iv, + void *protect, + unsigned *protected_len); + +typedef +err_status_t (*cryptoalg_inv_t) + (void *key, /* location of secret key */ + const void *clear, /* data to be authenticated only */ + unsigned clear_len, /* length of data to be authenticated only */ + void *iv, /* location of iv */ + void *opaque, /* data to be decrypted and authenticated */ + unsigned *opaque_len /* location of the length of data to be + * decrypted and authd (before and after) + */ + ); + +typedef struct cryptoalg_ctx_t { + cryptoalg_func_t enc; + cryptoalg_inv_t dec; + unsigned key_len; + unsigned iv_len; + unsigned auth_tag_len; + unsigned max_expansion; +} cryptoalg_ctx_t; + +typedef cryptoalg_ctx_t *cryptoalg_t; + +#define cryptoalg_get_key_len(cryptoalg) ((cryptoalg)->key_len) + +#define cryptoalg_get_iv_len(cryptoalg) ((cryptoalg)->iv_len) + +#define cryptoalg_get_auth_tag_len(cryptoalg) ((cryptoalg)->auth_tag_len) + +int +cryptoalg_get_id(cryptoalg_t c); + +cryptoalg_t +cryptoalg_find_by_id(int id); + + +/** + * @} + */ + +#endif /* CRYPTOALG_H */ + + diff --git a/src/libs/srtp/crypto/include/datatypes.h b/src/libs/srtp/crypto/include/datatypes.h new file mode 100644 index 00000000..e16d895b --- /dev/null +++ b/src/libs/srtp/crypto/include/datatypes.h @@ -0,0 +1,506 @@ +/* + * datatypes.h + * + * data types for bit vectors and finite fields + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef _DATATYPES_H +#define _DATATYPES_H + +#include "integers.h" /* definitions of uint32_t, et cetera */ +#include "alloc.h" + +#include <stdarg.h> + +#ifndef SRTP_KERNEL +# include <stdio.h> +# include <string.h> +# include <time.h> +# ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +# elif defined HAVE_WINSOCK2_H +# include <winsock2.h> +# endif +#endif + + +/* if DATATYPES_USE_MACROS is defined, then little functions are macros */ +#define DATATYPES_USE_MACROS + +typedef union { + uint8_t v8[2]; + uint16_t value; +} v16_t; + +typedef union { + uint8_t v8[4]; + uint16_t v16[2]; + uint32_t value; +} v32_t; + +typedef union { + uint8_t v8[8]; + uint16_t v16[4]; + uint32_t v32[2]; + uint64_t value; +} v64_t; + +typedef union { + uint8_t v8[16]; + uint16_t v16[8]; + uint32_t v32[4]; + uint64_t v64[2]; +} v128_t; + + + +/* some useful and simple math functions */ + +#define pow_2(X) ( (unsigned int)1 << (X) ) /* 2^X */ + +#define pow_minus_one(X) ( (X) ? -1 : 1 ) /* (-1)^X */ + + +/* + * octet_get_weight(x) returns the hamming weight (number of bits equal to + * one) in the octet x + */ + +int +octet_get_weight(uint8_t octet); + +char * +octet_bit_string(uint8_t x); + +#define MAX_PRINT_STRING_LEN 1024 + +char * +octet_string_hex_string(const void *str, int length); + +char * +v128_bit_string(v128_t *x); + +char * +v128_hex_string(v128_t *x); + +uint8_t +nibble_to_hex_char(uint8_t nibble); + +char * +char_to_hex_string(char *x, int num_char); + +uint8_t +hex_string_to_octet(char *s); + +/* + * hex_string_to_octet_string(raw, hex, len) converts the hexadecimal + * string at *hex (of length len octets) to the equivalent raw data + * and writes it to *raw. + * + * if a character in the hex string that is not a hexadeciaml digit + * (0123456789abcdefABCDEF) is encountered, the function stops writing + * data to *raw + * + * the number of hex digits copied (which is two times the number of + * octets in *raw) is returned + */ + +int +hex_string_to_octet_string(char *raw, char *hex, int len); + +v128_t +hex_string_to_v128(char *s); + +void +v128_copy_octet_string(v128_t *x, const uint8_t s[16]); + +void +v128_left_shift(v128_t *x, int shift_index); + +void +v128_right_shift(v128_t *x, int shift_index); + +/* + * the following macros define the data manipulation functions + * + * If DATATYPES_USE_MACROS is defined, then these macros are used + * directly (and function call overhead is avoided). Otherwise, + * the macros are used through the functions defined in datatypes.c + * (and the compiler provides better warnings). + */ + +#define _v128_set_to_zero(x) \ +( \ + (x)->v32[0] = 0, \ + (x)->v32[1] = 0, \ + (x)->v32[2] = 0, \ + (x)->v32[3] = 0 \ +) + +#define _v128_copy(x, y) \ +( \ + (x)->v32[0] = (y)->v32[0], \ + (x)->v32[1] = (y)->v32[1], \ + (x)->v32[2] = (y)->v32[2], \ + (x)->v32[3] = (y)->v32[3] \ +) + +#define _v128_xor(z, x, y) \ +( \ + (z)->v32[0] = (x)->v32[0] ^ (y)->v32[0], \ + (z)->v32[1] = (x)->v32[1] ^ (y)->v32[1], \ + (z)->v32[2] = (x)->v32[2] ^ (y)->v32[2], \ + (z)->v32[3] = (x)->v32[3] ^ (y)->v32[3] \ +) + +#define _v128_and(z, x, y) \ +( \ + (z)->v32[0] = (x)->v32[0] & (y)->v32[0], \ + (z)->v32[1] = (x)->v32[1] & (y)->v32[1], \ + (z)->v32[2] = (x)->v32[2] & (y)->v32[2], \ + (z)->v32[3] = (x)->v32[3] & (y)->v32[3] \ +) + +#define _v128_or(z, x, y) \ +( \ + (z)->v32[0] = (x)->v32[0] | (y)->v32[0], \ + (z)->v32[1] = (x)->v32[1] | (y)->v32[1], \ + (z)->v32[2] = (x)->v32[2] | (y)->v32[2], \ + (z)->v32[3] = (x)->v32[3] | (y)->v32[3] \ +) + +#define _v128_complement(x) \ +( \ + (x)->v32[0] = ~(x)->v32[0], \ + (x)->v32[1] = ~(x)->v32[1], \ + (x)->v32[2] = ~(x)->v32[2], \ + (x)->v32[3] = ~(x)->v32[3] \ +) + +/* ok for NO_64BIT_MATH if it can compare uint64_t's (even as structures) */ +#define _v128_is_eq(x, y) \ + (((x)->v64[0] == (y)->v64[0]) && ((x)->v64[1] == (y)->v64[1])) + + +#ifdef NO_64BIT_MATH +#define _v128_xor_eq(z, x) \ +( \ + (z)->v32[0] ^= (x)->v32[0], \ + (z)->v32[1] ^= (x)->v32[1], \ + (z)->v32[2] ^= (x)->v32[2], \ + (z)->v32[3] ^= (x)->v32[3] \ +) +#else +#define _v128_xor_eq(z, x) \ +( \ + (z)->v64[0] ^= (x)->v64[0], \ + (z)->v64[1] ^= (x)->v64[1] \ +) +#endif + +/* NOTE! This assumes an odd ordering! */ +/* This will not be compatible directly with math on some processors */ +/* bit 0 is first 32-bit word, low order bit. in little-endian, that's + the first byte of the first 32-bit word. In big-endian, that's + the 3rd byte of the first 32-bit word */ +/* The get/set bit code is used by the replay code ONLY, and it doesn't + really care which bit is which. AES does care which bit is which, but + doesn't use the 128-bit get/set or 128-bit shifts */ + +#define _v128_get_bit(x, bit) \ +( \ + ((((x)->v32[(bit) >> 5]) >> ((bit) & 31)) & 1) \ +) + +#define _v128_set_bit(x, bit) \ +( \ + (((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit) & 31))) \ +) + +#define _v128_clear_bit(x, bit) \ +( \ + (((x)->v32[(bit) >> 5]) &= ~((uint32_t)1 << ((bit) & 31))) \ +) + +#define _v128_set_bit_to(x, bit, value) \ +( \ + (value) ? _v128_set_bit(x, bit) : \ + _v128_clear_bit(x, bit) \ +) + + +#if 0 +/* nothing uses this */ +#ifdef WORDS_BIGENDIAN + +#define _v128_add(z, x, y) { \ + uint64_t tmp; \ + \ + tmp = x->v32[3] + y->v32[3]; \ + z->v32[3] = (uint32_t) tmp; \ + \ + tmp = x->v32[2] + y->v32[2] + (tmp >> 32); \ + z->v32[2] = (uint32_t) tmp; \ + \ + tmp = x->v32[1] + y->v32[1] + (tmp >> 32); \ + z->v32[1] = (uint32_t) tmp; \ + \ + tmp = x->v32[0] + y->v32[0] + (tmp >> 32); \ + z->v32[0] = (uint32_t) tmp; \ +} + +#else /* assume little endian architecture */ + +#define _v128_add(z, x, y) { \ + uint64_t tmp; \ + \ + tmp = htonl(x->v32[3]) + htonl(y->v32[3]); \ + z->v32[3] = ntohl((uint32_t) tmp); \ + \ + tmp = htonl(x->v32[2]) + htonl(y->v32[2]) \ + + htonl(tmp >> 32); \ + z->v32[2] = ntohl((uint32_t) tmp); \ + \ + tmp = htonl(x->v32[1]) + htonl(y->v32[1]) \ + + htonl(tmp >> 32); \ + z->v32[1] = ntohl((uint32_t) tmp); \ + \ + tmp = htonl(x->v32[0]) + htonl(y->v32[0]) \ + + htonl(tmp >> 32); \ + z->v32[0] = ntohl((uint32_t) tmp); \ +} +#endif /* WORDS_BIGENDIAN */ +#endif /* 0 */ + + +#ifdef DATATYPES_USE_MACROS /* little functions are really macros */ + +#define v128_set_to_zero(z) _v128_set_to_zero(z) +#define v128_copy(z, x) _v128_copy(z, x) +#define v128_xor(z, x, y) _v128_xor(z, x, y) +#define v128_and(z, x, y) _v128_and(z, x, y) +#define v128_or(z, x, y) _v128_or(z, x, y) +#define v128_complement(x) _v128_complement(x) +#define v128_is_eq(x, y) _v128_is_eq(x, y) +#define v128_xor_eq(x, y) _v128_xor_eq(x, y) +#define v128_get_bit(x, i) _v128_get_bit(x, i) +#define v128_set_bit(x, i) _v128_set_bit(x, i) +#define v128_clear_bit(x, i) _v128_clear_bit(x, i) +#define v128_set_bit_to(x, i, y) _v128_set_bit_to(x, i, y) + +#else + +void +v128_set_to_zero(v128_t *x); + +int +v128_is_eq(const v128_t *x, const v128_t *y); + +void +v128_copy(v128_t *x, const v128_t *y); + +void +v128_xor(v128_t *z, v128_t *x, v128_t *y); + +void +v128_and(v128_t *z, v128_t *x, v128_t *y); + +void +v128_or(v128_t *z, v128_t *x, v128_t *y); + +void +v128_complement(v128_t *x); + +int +v128_get_bit(const v128_t *x, int i); + +void +v128_set_bit(v128_t *x, int i) ; + +void +v128_clear_bit(v128_t *x, int i); + +void +v128_set_bit_to(v128_t *x, int i, int y); + +#endif /* DATATYPES_USE_MACROS */ + +/* + * octet_string_is_eq(a,b, len) returns 1 if the length len strings a + * and b are not equal, returns 0 otherwise + */ + +int +octet_string_is_eq(uint8_t *a, uint8_t *b, int len); + +void +octet_string_set_to_zero(uint8_t *s, int len); + + +#ifndef SRTP_KERNEL_LINUX + +/* + * Convert big endian integers to CPU byte order. + */ +#ifdef WORDS_BIGENDIAN +/* Nothing to do. */ +# define be32_to_cpu(x) (x) +# define be64_to_cpu(x) (x) +#elif defined(HAVE_BYTESWAP_H) +/* We have (hopefully) optimized versions in byteswap.h */ +# include <byteswap.h> +# define be32_to_cpu(x) bswap_32((x)) +# define be64_to_cpu(x) bswap_64((x)) +#else + +#if defined(__GNUC__) && defined(HAVE_X86) +/* Fall back. */ +static inline uint32_t be32_to_cpu(uint32_t v) { + /* optimized for x86. */ + asm("bswap %0" : "=r" (v) : "0" (v)); + return v; +} +# else /* HAVE_X86 */ +# ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +# elif defined HAVE_WINSOCK2_H +# include <winsock2.h> +# endif +# define be32_to_cpu(x) ntohl((x)) +# endif /* HAVE_X86 */ + +static inline uint64_t be64_to_cpu(uint64_t v) { +# ifdef NO_64BIT_MATH + /* use the make64 functions to do 64-bit math */ + v = make64(htonl(low32(v)),htonl(high32(v))); +# else + /* use the native 64-bit math */ + v= (uint64_t)((be32_to_cpu((uint32_t)(v >> 32))) | (((uint64_t)be32_to_cpu((uint32_t)v)) << 32)); +# endif + return v; +} + +#endif /* ! SRTP_KERNEL_LINUX */ + +#endif /* WORDS_BIGENDIAN */ + +/* + * functions manipulating bitvector_t + * + * A bitvector_t consists of an array of words and an integer + * representing the number of significant bits stored in the array. + * The bits are packed as follows: the least significant bit is that + * of word[0], while the most significant bit is the nth most + * significant bit of word[m], where length = bits_per_word * m + n. + * + */ + +#define bits_per_word 32 +#define bytes_per_word 4 + +typedef struct { + uint32_t length; + uint32_t *word; +} bitvector_t; + + +#define _bitvector_get_bit(v, bit_index) \ +( \ + ((((v)->word[((bit_index) >> 5)]) >> ((bit_index) & 31)) & 1) \ +) + + +#define _bitvector_set_bit(v, bit_index) \ +( \ + (((v)->word[((bit_index) >> 5)] |= ((uint32_t)1 << ((bit_index) & 31)))) \ +) + +#define _bitvector_clear_bit(v, bit_index) \ +( \ + (((v)->word[((bit_index) >> 5)] &= ~((uint32_t)1 << ((bit_index) & 31)))) \ +) + +#define _bitvector_get_length(v) \ +( \ + ((v)->length) \ +) + +#ifdef DATATYPES_USE_MACROS /* little functions are really macros */ + +#define bitvector_get_bit(v, bit_index) _bitvector_get_bit(v, bit_index) +#define bitvector_set_bit(v, bit_index) _bitvector_set_bit(v, bit_index) +#define bitvector_clear_bit(v, bit_index) _bitvector_clear_bit(v, bit_index) +#define bitvector_get_length(v) _bitvector_get_length(v) + +#else + +int +bitvector_get_bit(const bitvector_t *v, int bit_index); + +void +bitvector_set_bit(bitvector_t *v, int bit_index); + +void +bitvector_clear_bit(bitvector_t *v, int bit_index); + +unsigned long +bitvector_get_length(const bitvector_t *v); + +#endif + +int +bitvector_alloc(bitvector_t *v, unsigned long length); + +void +bitvector_dealloc(bitvector_t *v); + +void +bitvector_set_to_zero(bitvector_t *x); + +void +bitvector_left_shift(bitvector_t *x, int index); + +char * +bitvector_bit_string(bitvector_t *x, char* buf, int len); + +#endif /* _DATATYPES_H */ diff --git a/src/libs/srtp/crypto/include/err.h b/src/libs/srtp/crypto/include/err.h new file mode 100644 index 00000000..1a6e1701 --- /dev/null +++ b/src/libs/srtp/crypto/include/err.h @@ -0,0 +1,174 @@ +/* + * err.h + * + * error status codes + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef ERR_H +#define ERR_H + +#include "datatypes.h" + +/** + * @defgroup Error Error Codes + * + * Error status codes are represented by the enumeration err_status_t. + * + * @{ + */ + + +/* + * @brief err_status_t defines error codes. + * + * The enumeration err_status_t defines error codes. Note that the + * value of err_status_ok is equal to zero, which can simplify error + * checking somewhat. + * + */ +typedef enum { + err_status_ok = 0, /**< nothing to report */ + err_status_fail = 1, /**< unspecified failure */ + err_status_bad_param = 2, /**< unsupported parameter */ + err_status_alloc_fail = 3, /**< couldn't allocate memory */ + err_status_dealloc_fail = 4, /**< couldn't deallocate properly */ + err_status_init_fail = 5, /**< couldn't initialize */ + err_status_terminus = 6, /**< can't process as much data as requested */ + err_status_auth_fail = 7, /**< authentication failure */ + err_status_cipher_fail = 8, /**< cipher failure */ + err_status_replay_fail = 9, /**< replay check failed (bad index) */ + err_status_replay_old = 10, /**< replay check failed (index too old) */ + err_status_algo_fail = 11, /**< algorithm failed test routine */ + err_status_no_such_op = 12, /**< unsupported operation */ + err_status_no_ctx = 13, /**< no appropriate context found */ + err_status_cant_check = 14, /**< unable to perform desired validation */ + err_status_key_expired = 15, /**< can't use key any more */ + err_status_socket_err = 16, /**< error in use of socket */ + err_status_signal_err = 17, /**< error in use POSIX signals */ + err_status_nonce_bad = 18, /**< nonce check failed */ + err_status_read_fail = 19, /**< couldn't read data */ + err_status_write_fail = 20, /**< couldn't write data */ + err_status_parse_err = 21, /**< error pasring data */ + err_status_encode_err = 22, /**< error encoding data */ + err_status_semaphore_err = 23,/**< error while using semaphores */ + err_status_pfkey_err = 24 /**< error while using pfkey */ +} err_status_t; + +/** + * @} + */ + +typedef enum { + err_level_emergency = 0, + err_level_alert, + err_level_critical, + err_level_error, + err_level_warning, + err_level_notice, + err_level_info, + err_level_debug, + err_level_none +} err_reporting_level_t; + +/* + * err_reporting_init prepares the error system. If + * ERR_REPORTING_SYSLOG is defined, it will open syslog. + * + * The ident argument is a string that will be prepended to + * all syslog messages. It is conventionally argv[0]. + */ + +err_status_t +err_reporting_init(char *ident); + +#ifdef SRTP_KERNEL_LINUX +extern err_reporting_level_t err_level; +#else + +/* + * keydaemon_report_error reports a 'printf' formatted error + * string, followed by a an arg list. The priority argument + * is equivalent to that defined for syslog. + * + * Errors will be reported to ERR_REPORTING_FILE, if defined, and to + * syslog, if ERR_REPORTING_SYSLOG is defined. + * + */ + +void +err_report(int priority, char *format, ...); +#endif /* ! SRTP_KERNEL_LINUX */ + + +/* + * debug_module_t defines a debug module + */ + +typedef struct { + int on; /* 1 if debugging is on, 0 if it is off */ + char *name; /* printable name for debug module */ +} debug_module_t; + +#ifdef ENABLE_DEBUGGING + +#define debug_on(mod) (mod).on = 1 + +#define debug_off(mod) (mod).on = 0 + +/* use err_report() to report debug message */ +#define debug_print(mod, format, arg) \ + if (mod.on) err_report(err_level_debug, ("%s: " format "\n"), mod.name, arg) +#define debug_print2(mod, format, arg1,arg2) \ + if (mod.on) err_report(err_level_debug, ("%s: " format "\n"), mod.name, arg1,arg2) + +#else + +/* define macros to do nothing */ +#define debug_print(mod, format, arg) + +#define debug_on(mod) + +#define debug_off(mod) + +#endif + +#endif /* ERR_H */ diff --git a/src/libs/srtp/crypto/include/gf2_8.h b/src/libs/srtp/crypto/include/gf2_8.h new file mode 100644 index 00000000..098d37c9 --- /dev/null +++ b/src/libs/srtp/crypto/include/gf2_8.h @@ -0,0 +1,79 @@ +/* + * gf2_8.h + * + * GF(256) implementation + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef GF2_8_H +#define GF2_8_H + +#include "datatypes.h" /* for uint8_t definition */ + +typedef uint8_t gf2_8; + +#define gf2_8_field_polynomial 0x1B + +/* + * gf2_8_shift(x) returns + */ + +/* + * gf2_8_shift(z) returns the result of the GF(2^8) 'multiply by x' + * operation, using the field representation from AES; that is, the + * next gf2_8 value in the cyclic representation of that field. The + * value z should be an uint8_t. + */ + +#define gf2_8_shift(z) (((z) & 128) ? \ + (((z) << 1) ^ gf2_8_field_polynomial) : ((z) << 1)) + +gf2_8 +gf2_8_compute_inverse(gf2_8 x); + +void +test_gf2_8(void); + +gf2_8 +gf2_8_multiply(gf2_8 x, gf2_8 y); + +#endif /* GF2_8_H */ diff --git a/src/libs/srtp/crypto/include/hmac.h b/src/libs/srtp/crypto/include/hmac.h new file mode 100644 index 00000000..262c0e2d --- /dev/null +++ b/src/libs/srtp/crypto/include/hmac.h @@ -0,0 +1,78 @@ +/* + * hmac.h + * + * interface to hmac auth_type_t + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef HMAC_H +#define HMAC_H + +#include "auth.h" +#include "sha1.h" + +typedef struct { + uint8_t opad[64]; + sha1_ctx_t ctx; + sha1_ctx_t init_ctx; +} hmac_ctx_t; + +err_status_t +hmac_alloc(auth_t **a, int key_len, int out_len); + +err_status_t +hmac_dealloc(auth_t *a); + +err_status_t +hmac_init(hmac_ctx_t *state, const uint8_t *key, int key_len); + +err_status_t +hmac_start(hmac_ctx_t *state); + +err_status_t +hmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets); + +err_status_t +hmac_compute(hmac_ctx_t *state, const void *message, + int msg_octets, int tag_len, uint8_t *result); + + +#endif /* HMAC_H */ diff --git a/src/libs/srtp/crypto/include/integers.h b/src/libs/srtp/crypto/include/integers.h new file mode 100644 index 00000000..e64be174 --- /dev/null +++ b/src/libs/srtp/crypto/include/integers.h @@ -0,0 +1,155 @@ +/* + * integers.h + * + * defines integer types (or refers to their definitions) + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef INTEGERS_H +#define INTEGERS_H + +#include "config.h" /* configuration file, using autoconf */ + +#ifdef SRTP_KERNEL + +#include "kernel_compat.h" + +#else /* SRTP_KERNEL */ + +/* use standard integer definitions, if they're available */ +#ifdef HAVE_STDLIB_H +# include <stdlib.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_INT_TYPES_H +# include <sys/int_types.h> /* this exists on Sun OS */ +#endif +#ifdef HAVE_MACHINE_TYPES_H +# include <machine/types.h> +#endif + +#ifndef WIN32 +# define SIZEOF_UNSIGNED_LONG_LONG 8 +#endif + +/* Can we do 64 bit integers? */ +#ifndef HAVE_UINT64_T +# if SIZEOF_UNSIGNED_LONG == 8 +typedef unsigned long uint64_t; +# elif SIZEOF_UNSIGNED_LONG_LONG == 8 +typedef unsigned long long uint64_t; +# else +# ifdef _WIN32 +typedef unsigned __int64 uint64_t; +# else +# define NO_64BIT_MATH 1 +# endif +# endif +#endif + +/* Reasonable defaults for 32 bit machines - you may need to + * edit these definitions for your own machine. */ +#ifndef HAVE_UINT8_T +typedef unsigned char uint8_t; +#endif +#ifndef HAVE_UINT16_T +typedef unsigned short int uint16_t; +#endif +#ifndef HAVE_UINT32_T +typedef unsigned int uint32_t; +#endif + + +#ifdef NO_64BIT_MATH +typedef double uint64_t; +/* assert that sizeof(double) == 8 */ +extern uint64_t make64(uint32_t high, uint32_t low); +extern uint32_t high32(uint64_t value); +extern uint32_t low32(uint64_t value); +#endif + +#endif /* SRTP_KERNEL */ + +/* These macros are to load and store 32-bit values from un-aligned + addresses. This is required for processors that do not allow unaligned + loads. */ +#ifdef ALIGNMENT_32BIT_REQUIRED +/* Note that if it's in a variable, you can memcpy it */ +#ifdef WORDS_BIGENDIAN +#define PUT_32(addr,value) \ + { \ + ((unsigned char *) (addr))[0] = (value >> 24); \ + ((unsigned char *) (addr))[1] = (value >> 16) & 0xff; \ + ((unsigned char *) (addr))[2] = (value >> 8) & 0xff; \ + ((unsigned char *) (addr))[3] = (value) & 0xff; \ + } +#define GET_32(addr) ((((unsigned char *) (addr))[0] << 24) | \ + (((unsigned char *) (addr))[1] << 16) | \ + (((unsigned char *) (addr))[2] << 8) | \ + (((unsigned char *) (addr))[3])) +#else +#define PUT_32(addr,value) \ + { \ + ((unsigned char *) (addr))[3] = (value >> 24); \ + ((unsigned char *) (addr))[2] = (value >> 16) & 0xff; \ + ((unsigned char *) (addr))[1] = (value >> 8) & 0xff; \ + ((unsigned char *) (addr))[0] = (value) & 0xff; \ + } +#define GET_32(addr) ((((unsigned char *) (addr))[3] << 24) | \ + (((unsigned char *) (addr))[2] << 16) | \ + (((unsigned char *) (addr))[1] << 8) | \ + (((unsigned char *) (addr))[0])) +#endif // WORDS_BIGENDIAN +#else +#define PUT_32(addr,value) *(((uint32_t *) (addr)) = (value) +#define GET_32(addr) (*(((uint32_t *) (addr))) +#endif + +#endif /* INTEGERS_H */ diff --git a/src/libs/srtp/crypto/include/kernel_compat.h b/src/libs/srtp/crypto/include/kernel_compat.h new file mode 100644 index 00000000..59d1898e --- /dev/null +++ b/src/libs/srtp/crypto/include/kernel_compat.h @@ -0,0 +1,84 @@ +/* + * kernel_compat.h + * + * Compatibility stuff for building in kernel context where standard + * C headers and library are not available. + * + * Marcus Sundberg + * Ingate Systems AB + */ +/* + * + * Copyright(c) 2005 Ingate Systems AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the author(s) nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef KERNEL_COMPAT_H +#define KERNEL_COMPAT_H + +#ifdef SRTP_KERNEL_LINUX + +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include <linux/random.h> +#include <linux/byteorder/generic.h> + + +#define err_report(priority, ...) \ + do {\ + if (priority <= err_level) {\ + printk(__VA_ARGS__);\ + }\ + }while(0) + +#define clock() (jiffies) +#define time(x) (jiffies) + +/* rand() implementation. */ +#define RAND_MAX 32767 + +static inline int rand(void) +{ + uint32_t temp; + get_random_bytes(&temp, sizeof(temp)); + return temp % (RAND_MAX+1); +} + +/* stdio/stdlib implementation. */ +#define printf(...) printk(__VA_ARGS__) +#define exit(n) panic("%s:%d: exit(%d)\n", __FILE__, __LINE__, (n)) + +#endif /* SRTP_KERNEL_LINUX */ + +#endif /* KERNEL_COMPAT_H */ diff --git a/src/libs/srtp/crypto/include/key.h b/src/libs/srtp/crypto/include/key.h new file mode 100644 index 00000000..e7e07448 --- /dev/null +++ b/src/libs/srtp/crypto/include/key.h @@ -0,0 +1,82 @@ +/* + * key.h + * + * key usage limits enforcement + * + * David A. Mcgrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef KEY_H +#define KEY_H + +#include "rdbx.h" /* for xtd_seq_num_t */ +#include "err.h" + +typedef struct key_limit_ctx_t *key_limit_t; + +typedef enum { + key_event_normal, + key_event_soft_limit, + key_event_hard_limit +} key_event_t; + +err_status_t +key_limit_set(key_limit_t key, const xtd_seq_num_t s); + +err_status_t +key_limit_clone(key_limit_t original, key_limit_t *new_key); + +err_status_t +key_limit_check(const key_limit_t key); + +key_event_t +key_limit_update(key_limit_t key); + +typedef enum { + key_state_normal, + key_state_past_soft_limit, + key_state_expired +} key_state_t; + +typedef struct key_limit_ctx_t { + xtd_seq_num_t num_left; + key_state_t state; +} key_limit_ctx_t; + +#endif /* KEY_H */ diff --git a/src/libs/srtp/crypto/include/null_auth.h b/src/libs/srtp/crypto/include/null_auth.h new file mode 100644 index 00000000..44f9a4a2 --- /dev/null +++ b/src/libs/srtp/crypto/include/null_auth.h @@ -0,0 +1,68 @@ +/* + * null-auth.h + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef NULL_AUTH_H +#define NULL_AUTH_H + +#include "auth.h" + +typedef struct { + char foo; +} null_auth_ctx_t; + +err_status_t +null_auth_alloc(auth_t **a, int key_len, int out_len); + +err_status_t +null_auth_dealloc(auth_t *a); + +err_status_t +null_auth_init(null_auth_ctx_t *state, const uint8_t *key, int key_len); + +err_status_t +null_auth_compute (null_auth_ctx_t *state, uint8_t *message, + int msg_octets, int tag_len, uint8_t *result); + + +#endif /* NULL_AUTH_H */ diff --git a/src/libs/srtp/crypto/include/null_cipher.h b/src/libs/srtp/crypto/include/null_cipher.h new file mode 100644 index 00000000..39da59a8 --- /dev/null +++ b/src/libs/srtp/crypto/include/null_cipher.h @@ -0,0 +1,80 @@ +/* + * null-cipher.h + * + * header file for the null cipher + * + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef NULL_CIPHER_H +#define NULL_CIPHER_H + +#include "datatypes.h" +#include "cipher.h" + +typedef struct { + char foo ;/* empty, for now */ +} null_cipher_ctx_t; + + +/* + * none of these functions do anything (though future versions may keep + * track of bytes encrypted, number of instances, and/or other info). + */ + +err_status_t +null_cipher_init(null_cipher_ctx_t *c, const uint8_t *key, int key_len); + +err_status_t +null_cipher_set_segment(null_cipher_ctx_t *c, + unsigned long segment_index); + +err_status_t +null_cipher_encrypt(null_cipher_ctx_t *c, + unsigned char *buf, unsigned int *bytes_to_encr); + + +err_status_t +null_cipher_encrypt_aligned(null_cipher_ctx_t *c, + unsigned char *buf, int bytes_to_encr); + +#endif /* NULL_CIPHER_H */ diff --git a/src/libs/srtp/crypto/include/prng.h b/src/libs/srtp/crypto/include/prng.h new file mode 100644 index 00000000..fb96b5eb --- /dev/null +++ b/src/libs/srtp/crypto/include/prng.h @@ -0,0 +1,54 @@ +/* + * prng.h + * + * pseudorandom source + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +#ifndef PRNG_H +#define PRNG_H + +#include "rand_source.h" /* for rand_source_func_t definition */ +#include "aes.h" /* for aes */ +#include "aes_icm.h" /* for aes ctr */ + +#define MAX_PRNG_OUT_LEN 0xffffffffU + +/* + * x917_prng is an ANSI X9.17-like AES-based PRNG + */ + +typedef struct { + v128_t state; /* state data */ + aes_expanded_key_t key; /* secret key */ + uint32_t octet_count; /* number of octets output since last init */ + rand_source_func_t rand; /* random source for re-initialization */ +} x917_prng_t; + +err_status_t +x917_prng_init(rand_source_func_t random_source); + +err_status_t +x917_prng_get_octet_string(uint8_t *dest, uint32_t len); + + +/* + * ctr_prng is an AES-CTR based PRNG + */ + +typedef struct { + uint32_t octet_count; /* number of octets output since last init */ + aes_icm_ctx_t state; /* state data */ + rand_source_func_t rand; /* random source for re-initialization */ +} ctr_prng_t; + +err_status_t +ctr_prng_init(rand_source_func_t random_source); + +err_status_t +ctr_prng_get_octet_string(void *dest, uint32_t len); + + +#endif diff --git a/src/libs/srtp/crypto/include/rand_source.h b/src/libs/srtp/crypto/include/rand_source.h new file mode 100644 index 00000000..b4c21103 --- /dev/null +++ b/src/libs/srtp/crypto/include/rand_source.h @@ -0,0 +1,91 @@ +/* + * rand_source.h + * + * implements a random source based on /dev/random + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef RAND_SOURCE +#define RAND_SOURCE + +#include "err.h" +#include "datatypes.h" + +err_status_t +rand_source_init(void); + +/* + * rand_source_get_octet_string() writes a random octet string. + * + * The function call rand_source_get_octet_string(dest, len) writes + * len octets of random data to the location to which dest points, + * and returns an error code. This error code should be checked, + * and if a failure is reported, the data in the buffer MUST NOT + * be used. + * + * warning: If the return code is not checked, then non-random + * data may inadvertently be used. + * + * returns: + * - err_status_ok if no problems occured. + * - [other] a problem occured, and no assumptions should + * be made about the contents of the destination + * buffer. + */ + +err_status_t +rand_source_get_octet_string(void *dest, uint32_t length); + +err_status_t +rand_source_deinit(void); + +/* + * function prototype for a random source function + * + * A rand_source_func_t writes num_octets at the location indicated by + * dest and returns err_status_ok. Any other return value indicates + * failure. + */ + +typedef err_status_t (*rand_source_func_t) + (void *dest, uint32_t num_octets); + +#endif /* RAND_SOURCE */ diff --git a/src/libs/srtp/crypto/include/rdb.h b/src/libs/srtp/crypto/include/rdb.h new file mode 100644 index 00000000..2ccb1448 --- /dev/null +++ b/src/libs/srtp/crypto/include/rdb.h @@ -0,0 +1,94 @@ +/* + * replay-database.h + * + * interface for a replay database for packet security + * + * David A. McGrew + * Cisco Systems, Inc. + */ + + +#ifndef REPLAY_DB_H +#define REPLAY_DB_H + +#include "integers.h" /* for uint32_t */ +#include "datatypes.h" /* for v128_t */ +#include "err.h" /* for err_status_t */ + +/* + * if the ith least significant bit is one, then the packet index + * window_end-i is in the database + */ + +typedef struct { + uint32_t window_start; /* packet index of the first bit in bitmask */ + v128_t bitmask; +} rdb_t; + +#define rdb_bits_in_bitmask (8*sizeof(v128_t)) + +/* + * rdb init + * + * initalizes rdb + * + * returns err_status_ok on success, err_status_t_fail otherwise + */ + +err_status_t +rdb_init(rdb_t *rdb); + + +/* + * rdb_check + * + * checks to see if index appears in rdb + * + * returns err_status_fail if the index already appears in rdb, + * returns err_status_ok otherwise + */ + +err_status_t +rdb_check(const rdb_t *rdb, uint32_t rdb_index); + +/* + * rdb_add_index + * + * adds index to rdb_t (and does *not* check if index appears in db) + * + * returns err_status_ok on success, err_status_fail otherwise + * + */ + +err_status_t +rdb_add_index(rdb_t *rdb, uint32_t rdb_index); + +/* + * the functions rdb_increment() and rdb_get_value() are for use by + * senders, not receivers - DO NOT use these functions on the same + * rdb_t upon which rdb_add_index is used! + */ + + +/* + * rdb_increment(db) increments the sequence number in db, if it is + * not too high + * + * return values: + * + * err_status_ok no problem + * err_status_key_expired sequence number too high + * + */ +err_status_t +rdb_increment(rdb_t *rdb); + +/* + * rdb_get_value(db) returns the current sequence number of db + */ + +uint32_t +rdb_get_value(const rdb_t *rdb); + + +#endif /* REPLAY_DB_H */ diff --git a/src/libs/srtp/crypto/include/rdbx.h b/src/libs/srtp/crypto/include/rdbx.h new file mode 100644 index 00000000..146fb42f --- /dev/null +++ b/src/libs/srtp/crypto/include/rdbx.h @@ -0,0 +1,186 @@ +/* + * rdbx.h + * + * replay database with extended packet indices, using a rollover counter + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ + +#ifndef RDBX_H +#define RDBX_H + +#include "datatypes.h" +#include "err.h" + +/* #define ROC_TEST */ + +#ifndef ROC_TEST + +typedef uint16_t sequence_number_t; /* 16 bit sequence number */ +typedef uint32_t rollover_counter_t; /* 32 bit rollover counter */ + +#else /* use small seq_num and roc datatypes for testing purposes */ + +typedef unsigned char sequence_number_t; /* 8 bit sequence number */ +typedef uint16_t rollover_counter_t; /* 16 bit rollover counter */ + +#endif + +#define seq_num_median (1 << (8*sizeof(sequence_number_t) - 1)) +#define seq_num_max (1 << (8*sizeof(sequence_number_t))) + +/* + * An xtd_seq_num_t is a 64-bit unsigned integer used as an 'extended' + * sequence number. + */ + +typedef uint64_t xtd_seq_num_t; + + +/* + * An rdbx_t is a replay database with extended range; it uses an + * xtd_seq_num_t and a bitmask of recently received indices. + */ + +typedef struct { + xtd_seq_num_t index; + bitvector_t bitmask; +} rdbx_t; + + +/* + * rdbx_init(rdbx_ptr, ws) + * + * initializes the rdbx pointed to by its argument with the window size ws, + * setting the rollover counter and sequence number to zero + */ + +err_status_t +rdbx_init(rdbx_t *rdbx, unsigned long ws); + + +/* + * rdbx_dealloc(rdbx_ptr) + * + * frees memory associated with the rdbx + */ + +err_status_t +rdbx_dealloc(rdbx_t *rdbx); + + +/* + * rdbx_estimate_index(rdbx, guess, s) + * + * given an rdbx and a sequence number s (from a newly arrived packet), + * sets the contents of *guess to contain the best guess of the packet + * index to which s corresponds, and returns the difference between + * *guess and the locally stored synch info + */ + +int +rdbx_estimate_index(const rdbx_t *rdbx, + xtd_seq_num_t *guess, + sequence_number_t s); + +/* + * rdbx_check(rdbx, delta); + * + * rdbx_check(&r, delta) checks to see if the xtd_seq_num_t + * which is at rdbx->window_start + delta is in the rdb + * + */ + +err_status_t +rdbx_check(const rdbx_t *rdbx, int difference); + +/* + * replay_add_index(rdbx, delta) + * + * adds the xtd_seq_num_t at rdbx->window_start + delta to replay_db + * (and does *not* check if that xtd_seq_num_t appears in db) + * + * this function should be called *only* after replay_check has + * indicated that the index does not appear in the rdbx, and a mutex + * should protect the rdbx between these calls if necessary. + */ + +err_status_t +rdbx_add_index(rdbx_t *rdbx, int delta); + + +/* + * rdbx_set_roc(rdbx, roc) initalizes the rdbx_t at the location rdbx + * to have the rollover counter value roc. If that value is less than + * the current rollover counter value, then the function returns + * err_status_replay_old; otherwise, err_status_ok is returned. + * + */ + +err_status_t +rdbx_set_roc(rdbx_t *rdbx, uint32_t roc); + +/* + * rdbx_get_roc(rdbx) returns the value of the rollover counter for + * the rdbx_t pointed to by rdbx + * + */ + +xtd_seq_num_t +rdbx_get_packet_index(const rdbx_t *rdbx); + +/* + * xtd_seq_num_t functions - these are *internal* functions of rdbx, and + * shouldn't be used to manipulate rdbx internal values. use the rdbx + * api instead! + */ + +/* + * rdbx_get_ws(rdbx_ptr) + * + * gets the window size which was used to initialize the rdbx + */ + +unsigned long +rdbx_get_window_size(const rdbx_t *rdbx); + + +/* index_init(&pi) initializes a packet index pi (sets it to zero) */ + +void +index_init(xtd_seq_num_t *pi); + +/* index_advance(&pi, s) advances a xtd_seq_num_t forward by s */ + +void +index_advance(xtd_seq_num_t *pi, sequence_number_t s); + + +/* + * index_guess(local, guess, s) + * + * given a xtd_seq_num_t local (which represents the highest + * known-to-be-good index) and a sequence number s (from a newly + * arrived packet), sets the contents of *guess to contain the best + * guess of the packet index to which s corresponds, and returns the + * difference between *guess and *local + */ + +int +index_guess(const xtd_seq_num_t *local, + xtd_seq_num_t *guess, + sequence_number_t s); + + +#endif /* RDBX_H */ + + + + + + + + + diff --git a/src/libs/srtp/crypto/include/sha1.h b/src/libs/srtp/crypto/include/sha1.h new file mode 100644 index 00000000..e3af4d4b --- /dev/null +++ b/src/libs/srtp/crypto/include/sha1.h @@ -0,0 +1,108 @@ +/* + * sha1.h + * + * interface to the Secure Hash Algorithm v.1 (SHA-1), specified in + * FIPS 180-1 + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef SHA1_H +#define SHA1_H + +#include "err.h" +#include "datatypes.h" + +typedef struct { + uint32_t H[5]; /* state vector */ + uint32_t M[16]; /* message buffer */ + int octets_in_buffer; /* octets of message in buffer */ + uint32_t num_bits_in_msg; /* total number of bits in message */ +} sha1_ctx_t; + +/* + * sha1(&ctx, msg, len, output) hashes the len octets starting at msg + * into the SHA1 context, then writes the result to the 20 octets at + * output + * + */ + +void +sha1(const uint8_t *message, int octets_in_msg, uint32_t output[5]); + +/* + * sha1_init(&ctx) initializes the SHA1 context ctx + * + * sha1_update(&ctx, msg, len) hashes the len octets starting at msg + * into the SHA1 context + * + * sha1_final(&ctx, output) performs the final processing of the SHA1 + * context and writes the result to the 20 octets at output + * + */ + +void +sha1_init(sha1_ctx_t *ctx); + +void +sha1_update(sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg); + +void +sha1_final(sha1_ctx_t *ctx, uint32_t output[5]); + +/* + * The sha1_core function is INTERNAL to SHA-1, but it is declared + * here because it is also used by the cipher SEAL 3.0 in its key + * setup algorithm. + */ + +/* + * sha1_core(M, H) computes the core sha1 compression function, where M is + * the next part of the message and H is the intermediate state {H0, + * H1, ...} + * + * this function does not do any of the padding required in the + * complete sha1 function + */ + +void +sha1_core(const uint32_t M[16], uint32_t hash_value[5]); + +#endif /* SHA1_H */ diff --git a/src/libs/srtp/crypto/include/stat.h b/src/libs/srtp/crypto/include/stat.h new file mode 100644 index 00000000..e28b1314 --- /dev/null +++ b/src/libs/srtp/crypto/include/stat.h @@ -0,0 +1,69 @@ +/* + * stats.h + * + * interface to statistical test functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright(c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef STAT_H +#define STAT_H + +#include "datatypes.h" /* for uint8_t */ +#include "err.h" /* for err_status_t */ +#include "rand_source.h" /* for rand_source_func_t definition */ + +err_status_t +stat_test_monobit(uint8_t *data); + +err_status_t +stat_test_poker(uint8_t *data); + +err_status_t +stat_test_runs(uint8_t *data); + +err_status_t +stat_test_rand_source(rand_source_func_t rs); + +err_status_t +stat_test_rand_source_with_repetition(rand_source_func_t source, unsigned num_trials); + +#endif /* STAT_H */ diff --git a/src/libs/srtp/crypto/include/xfm.h b/src/libs/srtp/crypto/include/xfm.h new file mode 100644 index 00000000..5837149b --- /dev/null +++ b/src/libs/srtp/crypto/include/xfm.h @@ -0,0 +1,139 @@ +/* + * xfm.h + * + * interface for abstract crypto transform + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +#ifndef XFM_H +#define XFM_H + +#include "crypto_kernel.h" +#include "err.h" + +/** + * @defgroup Crypto Cryptography + * + * A simple interface to an abstract cryptographic transform that + * provides both confidentiality and message authentication. + * + * @{ + */ + +/** + * @brief applies a crypto transform + * + * The function pointer xfm_func_t points to a function that + * implements a crypto transform, and provides a uniform API for + * accessing crypto mechanisms. + * + * @param key location of secret key + * + * @param clear data to be authenticated only + * + * @param clear_len length of data to be authenticated only + * + * @param iv location to write the Initialization Vector (IV) + * + * @param protect location of the data to be encrypted and + * authenticated (before the function call), and the ciphertext + * and authentication tag (after the call) + * + * @param protected_len location of the length of the data to be + * encrypted and authenticated (before the function call), and the + * length of the ciphertext (after the call) + * + * @param auth_tag location to write auth tag + */ + +typedef err_status_t (*xfm_func_t) + (void *key, + void *clear, + unsigned clear_len, + void *iv, + void *protect, + unsigned *protected_len, + void *auth_tag + ); + +typedef +err_status_t (*xfm_inv_t) + (void *key, /* location of secret key */ + void *clear, /* data to be authenticated only */ + unsigned clear_len, /* length of data to be authenticated only */ + void *iv, /* location of iv */ + void *opaque, /* data to be decrypted and authenticated */ + unsigned *opaque_len, /* location of the length of data to be + * decrypted and authd (before and after) + */ + void *auth_tag /* location of auth tag */ + ); + +typedef struct xfm_ctx_t { + xfm_func_t func; + xfm_inv_t inv; + unsigned key_len; + unsigned iv_len; + unsigned auth_tag_len; +} xfm_ctx_t; + +typedef xfm_ctx_t *xfm_t; + +#define xfm_get_key_len(xfm) ((xfm)->key_len) + +#define xfm_get_iv_len(xfm) ((xfm)->iv_len) + +#define xfm_get_auth_tag_len(xfm) ((xfm)->auth_tag_len) + + +/* cryptoalgo - 5/28 */ + +typedef err_status_t (*cryptoalg_func_t) + (void *key, + void *clear, + unsigned clear_len, + void *iv, + void *opaque, + unsigned *opaque_len + ); + +typedef +err_status_t (*cryptoalg_inv_t) + (void *key, /* location of secret key */ + void *clear, /* data to be authenticated only */ + unsigned clear_len, /* length of data to be authenticated only */ + void *iv, /* location of iv */ + void *opaque, /* data to be decrypted and authenticated */ + unsigned *opaque_len /* location of the length of data to be + * decrypted and authd (before and after) + */ + ); + +typedef struct cryptoalg_ctx_t { + cryptoalg_func_t enc; + cryptoalg_inv_t dec; + unsigned key_len; + unsigned iv_len; + unsigned auth_tag_len; + unsigned max_expansion; +} cryptoalg_ctx_t; + +typedef cryptoalg_ctx_t *cryptoalg_t; + +#define cryptoalg_get_key_len(cryptoalg) ((cryptoalg)->key_len) + +#define cryptoalg_get_iv_len(cryptoalg) ((cryptoalg)->iv_len) + +#define cryptoalg_get_auth_tag_len(cryptoalg) ((cryptoalg)->auth_tag_len) + + + +/** + * @} + */ + +#endif /* XFM_H */ + + diff --git a/src/libs/srtp/crypto/kernel/alloc.c b/src/libs/srtp/crypto/kernel/alloc.c new file mode 100644 index 00000000..5dd09474 --- /dev/null +++ b/src/libs/srtp/crypto/kernel/alloc.c @@ -0,0 +1,119 @@ +/* + * alloc.c + * + * memory allocation and deallocation + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "alloc.h" +#include "crypto_kernel.h" + +/* the debug module for memory allocation */ + +debug_module_t mod_alloc = { + 0, /* debugging is off by default */ + "alloc" /* printable name for module */ +}; + +/* + * Nota bene: the debugging statements for crypto_alloc() and + * crypto_free() have identical prefixes, which include the addresses + * of the memory locations on which they are operating. This fact can + * be used to locate memory leaks, by turning on memory debugging, + * grepping for 'alloc', then matching alloc and free calls by + * address. + */ + +#ifdef SRTP_KERNEL_LINUX + +#include <linux/interrupt.h> + +void * +crypto_alloc(size_t size) { + void *ptr; + + ptr = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + + if (ptr) { + debug_print(mod_alloc, "(location: %p) allocated", ptr); + } else + debug_print(mod_alloc, "allocation failed (asked for %d bytes)\n", size); + + return ptr; +} + +void +crypto_free(void *ptr) { + + debug_print(mod_alloc, "(location: %p) freed", ptr); + + kfree(ptr); +} + + +#elif defined(HAVE_STDLIB_H) + +void * +crypto_alloc(size_t size) { + void *ptr; + + ptr = malloc(size); + + if (ptr) { + debug_print(mod_alloc, "(location: %p) allocated", ptr); + } else + debug_print(mod_alloc, "allocation failed (asked for %d bytes)\n", size); + + return ptr; +} + +void +crypto_free(void *ptr) { + + debug_print(mod_alloc, "(location: %p) freed", ptr); + + free(ptr); +} + +#else /* we need to define our own memory allocation routines */ + +#error no memory allocation defined yet + +#endif diff --git a/src/libs/srtp/crypto/kernel/crypto_kernel.c b/src/libs/srtp/crypto/kernel/crypto_kernel.c new file mode 100644 index 00000000..ad4a02f0 --- /dev/null +++ b/src/libs/srtp/crypto/kernel/crypto_kernel.c @@ -0,0 +1,573 @@ +/* + * crypto_kernel.c + * + * header for the cryptographic kernel + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "alloc.h" + +#include "crypto_kernel.h" + +/* the debug module for the crypto_kernel */ + +debug_module_t mod_crypto_kernel = { + 0, /* debugging is off by default */ + "crypto kernel" /* printable name for module */ +}; + +/* + * other debug modules that can be included in the kernel + */ + +extern debug_module_t mod_auth; +extern debug_module_t mod_cipher; +extern debug_module_t mod_stat; +extern debug_module_t mod_alloc; + +/* + * cipher types that can be included in the kernel + */ + +extern cipher_type_t null_cipher; +extern cipher_type_t aes_icm; +extern cipher_type_t aes_cbc; + + +/* + * auth func types that can be included in the kernel + */ + +extern auth_type_t null_auth; +extern auth_type_t hmac; + +/* crypto_kernel is a global variable, the only one of its datatype */ + +crypto_kernel_t +crypto_kernel = { + crypto_kernel_state_insecure, /* start off in insecure state */ + NULL, /* no cipher types yet */ + NULL, /* no auth types yet */ + NULL /* no debug modules yet */ +}; + +#define MAX_RNG_TRIALS 25 + +err_status_t +crypto_kernel_init() { + err_status_t status; + + /* check the security state */ + if (crypto_kernel.state == crypto_kernel_state_secure) { + + /* + * we're already in the secure state, but we've been asked to + * re-initialize, so we just re-run the self-tests and then return + */ + return crypto_kernel_status(); + } + + /* initialize error reporting system */ + status = err_reporting_init("crypto"); + if (status) + return status; + + /* load debug modules */ + status = crypto_kernel_load_debug_module(&mod_crypto_kernel); + if (status) + return status; + status = crypto_kernel_load_debug_module(&mod_auth); + if (status) + return status; + status = crypto_kernel_load_debug_module(&mod_cipher); + if (status) + return status; + status = crypto_kernel_load_debug_module(&mod_stat); + if (status) + return status; + status = crypto_kernel_load_debug_module(&mod_alloc); + if (status) + return status; + + /* initialize random number generator */ + status = rand_source_init(); + if (status) + return status; + + /* run FIPS-140 statistical tests on rand_source */ + status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS); + if (status) + return status; + + /* initialize pseudorandom number generator */ + status = ctr_prng_init(rand_source_get_octet_string); + if (status) + return status; + + /* run FIPS-140 statistical tests on ctr_prng */ + status = stat_test_rand_source_with_repetition(ctr_prng_get_octet_string, MAX_RNG_TRIALS); + if (status) + return status; + + /* load cipher types */ + status = crypto_kernel_load_cipher_type(&null_cipher, NULL_CIPHER); + if (status) + return status; + status = crypto_kernel_load_cipher_type(&aes_icm, AES_ICM); + if (status) + return status; + status = crypto_kernel_load_cipher_type(&aes_cbc, AES_CBC); + if (status) + return status; + + /* load auth func types */ + status = crypto_kernel_load_auth_type(&null_auth, NULL_AUTH); + if (status) + return status; + status = crypto_kernel_load_auth_type(&hmac, HMAC_SHA1); + if (status) + return status; + + /* change state to secure */ + crypto_kernel.state = crypto_kernel_state_secure; + + return err_status_ok; +} + +err_status_t +crypto_kernel_status() { + err_status_t status; + kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list; + kernel_auth_type_t *atype = crypto_kernel.auth_type_list; + kernel_debug_module_t *dm = crypto_kernel.debug_module_list; + + /* run FIPS-140 statistical tests on rand_source */ + printf("testing rand_source..."); + status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS); + if (status) { + printf("failed\n"); + crypto_kernel.state = crypto_kernel_state_insecure; + return status; + } + printf("passed\n"); + + /* for each cipher type, describe and test */ + while(ctype != NULL) { + printf("cipher: %s\n", ctype->cipher_type->description); + printf(" instance count: %d\n", ctype->cipher_type->ref_count); + printf(" self-test: "); + status = cipher_type_self_test(ctype->cipher_type); + if (status) { + printf("failed with error code %d\n", status); + exit(status); + } + printf("passed\n"); + ctype = ctype->next; + } + + /* for each auth type, describe and test */ + while(atype != NULL) { + printf("auth func: %s\n", atype->auth_type->description); + printf(" instance count: %d\n", atype->auth_type->ref_count); + printf(" self-test: "); + status = auth_type_self_test(atype->auth_type); + if (status) { + printf("failed with error code %d\n", status); + exit(status); + } + printf("passed\n"); + atype = atype->next; + } + + /* describe each debug module */ + printf("debug modules loaded:\n"); + while (dm != NULL) { + printf(" %s ", dm->mod->name); + if (dm->mod->on) + printf("(on)\n"); + else + printf("(off)\n"); + dm = dm->next; + } + + return err_status_ok; +} + +err_status_t +crypto_kernel_list_debug_modules() { + kernel_debug_module_t *dm = crypto_kernel.debug_module_list; + + /* describe each debug module */ + printf("debug modules loaded:\n"); + while (dm != NULL) { + printf(" %s ", dm->mod->name); + if (dm->mod->on) + printf("(on)\n"); + else + printf("(off)\n"); + dm = dm->next; + } + + return err_status_ok; +} + +err_status_t +crypto_kernel_shutdown() { + err_status_t status; + + /* + * free dynamic memory used in crypto_kernel at present + */ + + /* walk down cipher type list, freeing memory */ + while (crypto_kernel.cipher_type_list != NULL) { + kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list; + crypto_kernel.cipher_type_list = ctype->next; + debug_print(mod_crypto_kernel, + "freeing memory for cipher %s", + ctype->cipher_type->description); + crypto_free(ctype); + } + + /* walk down authetication module list, freeing memory */ + while (crypto_kernel.auth_type_list != NULL) { + kernel_auth_type_t *atype = crypto_kernel.auth_type_list; + crypto_kernel.auth_type_list = atype->next; + debug_print(mod_crypto_kernel, + "freeing memory for authentication %s", + atype->auth_type->description); + crypto_free(atype); + } + + /* walk down debug module list, freeing memory */ + while (crypto_kernel.debug_module_list != NULL) { + kernel_debug_module_t *kdm = crypto_kernel.debug_module_list; + crypto_kernel.debug_module_list = kdm->next; + debug_print(mod_crypto_kernel, + "freeing memory for debug module %s", + kdm->mod->name); + crypto_free(kdm); + } + + /* de-initialize random number generator */ status = rand_source_deinit(); + if (status) + return status; + + /* return to insecure state */ + crypto_kernel.state = crypto_kernel_state_insecure; + + return err_status_ok; +} + +static inline err_status_t +crypto_kernel_do_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id, + int replace) { + kernel_cipher_type_t *ctype, *new_ctype; + err_status_t status; + + /* defensive coding */ + if (new_ct == NULL) + return err_status_bad_param; + + if (new_ct->id != id) + return err_status_bad_param; + + /* check cipher type by running self-test */ + /*status = cipher_type_self_test(new_ct); + if (status) { + return status; + }*/ + + /* walk down list, checking if this type is in the list already */ + ctype = crypto_kernel.cipher_type_list; + while (ctype != NULL) { + if (id == ctype->id) { + if (!replace) + return err_status_bad_param; + status = cipher_type_test(new_ct, ctype->cipher_type->test_data); + if (status) + return status; + new_ctype = ctype; + break; + } + else if (new_ct == ctype->cipher_type) + return err_status_bad_param; + ctype = ctype->next; + } + + /* if not found, put new_ct at the head of the list */ + if (ctype == NULL) { + /* allocate memory */ + new_ctype = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_t)); + if (new_ctype == NULL) + return err_status_alloc_fail; + new_ctype->next = crypto_kernel.cipher_type_list; + + /* set head of list to new cipher type */ + crypto_kernel.cipher_type_list = new_ctype; + } + + /* set fields */ + new_ctype->cipher_type = new_ct; + new_ctype->id = id; + + /* load debug module, if there is one present */ + if (new_ct->debug != NULL) + crypto_kernel_load_debug_module(new_ct->debug); + /* we could check for errors here */ + + return err_status_ok; +} + +err_status_t +crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) { + return crypto_kernel_do_load_cipher_type(new_ct, id, 0); +} + +err_status_t +crypto_kernel_replace_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) { + return crypto_kernel_do_load_cipher_type(new_ct, id, 1); +} + +err_status_t +crypto_kernel_do_load_auth_type(auth_type_t *new_at, auth_type_id_t id, + int replace) { + kernel_auth_type_t *atype, *new_atype; + err_status_t status; + + /* defensive coding */ + if (new_at == NULL) + return err_status_bad_param; + + if (new_at->id != id) + return err_status_bad_param; + + /* check auth type by running self-test */ + status = auth_type_self_test(new_at); + if (status) { + return status; + } + + /* walk down list, checking if this type is in the list already */ + atype = crypto_kernel.auth_type_list; + while (atype != NULL) { + if (id == atype->id) { + if (!replace) + return err_status_bad_param; + status = auth_type_test(new_at, atype->auth_type->test_data); + if (status) + return status; + new_atype = atype; + break; + } + else if (new_at == atype->auth_type) + return err_status_bad_param; + atype = atype->next; + } + + /* if not found, put new_at at the head of the list */ + if (atype == NULL) { + /* allocate memory */ + new_atype = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t)); + if (new_atype == NULL) + return err_status_alloc_fail; + + new_atype->next = crypto_kernel.auth_type_list; + /* set head of list to new auth type */ + crypto_kernel.auth_type_list = new_atype; + } + + /* set fields */ + new_atype->auth_type = new_at; + new_atype->id = id; + + /* load debug module, if there is one present */ + if (new_at->debug != NULL) + crypto_kernel_load_debug_module(new_at->debug); + /* we could check for errors here */ + + return err_status_ok; + +} + +err_status_t +crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) { + return crypto_kernel_do_load_auth_type(new_at, id, 0); +} + +err_status_t +crypto_kernel_replace_auth_type(auth_type_t *new_at, auth_type_id_t id) { + return crypto_kernel_do_load_auth_type(new_at, id, 1); +} + + +cipher_type_t * +crypto_kernel_get_cipher_type(cipher_type_id_t id) { + kernel_cipher_type_t *ctype; + + /* walk down list, looking for id */ + ctype = crypto_kernel.cipher_type_list; + while (ctype != NULL) { + if (id == ctype->id) + return ctype->cipher_type; + ctype = ctype->next; + } + + /* haven't found the right one, indicate failure by returning NULL */ + return NULL; +} + + +err_status_t +crypto_kernel_alloc_cipher(cipher_type_id_t id, + cipher_pointer_t *cp, + int key_len) { + cipher_type_t *ct; + + /* + * if the crypto_kernel is not yet initialized, we refuse to allocate + * any ciphers - this is a bit extra-paranoid + */ + if (crypto_kernel.state != crypto_kernel_state_secure) + return err_status_init_fail; + + ct = crypto_kernel_get_cipher_type(id); + if (!ct) + return err_status_fail; + + return ((ct)->alloc(cp, key_len)); +} + + + +auth_type_t * +crypto_kernel_get_auth_type(auth_type_id_t id) { + kernel_auth_type_t *atype; + + /* walk down list, looking for id */ + atype = crypto_kernel.auth_type_list; + while (atype != NULL) { + if (id == atype->id) + return atype->auth_type; + atype = atype->next; + } + + /* haven't found the right one, indicate failure by returning NULL */ + return NULL; +} + +err_status_t +crypto_kernel_alloc_auth(auth_type_id_t id, + auth_pointer_t *ap, + int key_len, + int tag_len) { + auth_type_t *at; + + /* + * if the crypto_kernel is not yet initialized, we refuse to allocate + * any auth functions - this is a bit extra-paranoid + */ + if (crypto_kernel.state != crypto_kernel_state_secure) + return err_status_init_fail; + + at = crypto_kernel_get_auth_type(id); + if (!at) + return err_status_fail; + + return ((at)->alloc(ap, key_len, tag_len)); +} + +err_status_t +crypto_kernel_load_debug_module(debug_module_t *new_dm) { + kernel_debug_module_t *kdm, *new; + + /* defensive coding */ + if (new_dm == NULL) + return err_status_bad_param; + + /* walk down list, checking if this type is in the list already */ + kdm = crypto_kernel.debug_module_list; + while (kdm != NULL) { + if (strncmp(new_dm->name, kdm->mod->name, 64) == 0) + return err_status_bad_param; + kdm = kdm->next; + } + + /* put new_dm at the head of the list */ + /* allocate memory */ + new = (kernel_debug_module_t *)crypto_alloc(sizeof(kernel_debug_module_t)); + if (new == NULL) + return err_status_alloc_fail; + + /* set fields */ + new->mod = new_dm; + new->next = crypto_kernel.debug_module_list; + + /* set head of list to new cipher type */ + crypto_kernel.debug_module_list = new; + + return err_status_ok; +} + +err_status_t +crypto_kernel_set_debug_module(char *name, int on) { + kernel_debug_module_t *kdm; + + /* walk down list, checking if this type is in the list already */ + kdm = crypto_kernel.debug_module_list; + while (kdm != NULL) { + if (strncmp(name, kdm->mod->name, 64) == 0) { + kdm->mod->on = on; + return err_status_ok; + } + kdm = kdm->next; + } + + return err_status_fail; +} + +err_status_t +crypto_get_random(unsigned char *buffer, unsigned int length) { + if (crypto_kernel.state == crypto_kernel_state_secure) + return ctr_prng_get_octet_string(buffer, length); + else + return err_status_fail; +} diff --git a/src/libs/srtp/crypto/kernel/err.c b/src/libs/srtp/crypto/kernel/err.c new file mode 100644 index 00000000..4a3a8589 --- /dev/null +++ b/src/libs/srtp/crypto/kernel/err.c @@ -0,0 +1,148 @@ +/* + * err.c + * + * error status reporting functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "err.h" + +#ifdef ERR_REPORTING_SYSLOG +# ifdef HAVE_SYSLOG_H +# include <syslog.h> +# endif +#endif + + +/* err_level reflects the level of errors that are reported */ + +err_reporting_level_t err_level = err_level_none; + +#ifdef SRTP_KERNEL_LINUX +err_status_t +err_reporting_init(char *ident) { + + return err_status_ok; +} + +#else /* SRTP_KERNEL_LINUX */ + +/* err_file is the FILE to which errors are reported */ + +static FILE *err_file = NULL; + +err_status_t +err_reporting_init(char *ident) { +#ifdef ERR_REPORTING_SYSLOG + openlog(ident, LOG_PID, LOG_AUTHPRIV); +#endif + + /* + * Believe it or not, openlog doesn't return an error on failure. + * But then, neither does the syslog() call... + */ + +#ifdef ERR_REPORTING_STDOUT + err_file = stdout; +#elif defined(USE_ERR_REPORTING_FILE) + /* open file for error reporting */ + err_file = fopen(ERR_REPORTING_FILE, "w"); + if (err_file == NULL) + return err_status_init_fail; +#endif + + return err_status_ok; +} + +void +err_report(int priority, char *format, ...) { + va_list args; + + if (priority <= err_level) { + + va_start(args, format); + if (err_file != NULL) { + vfprintf(err_file, format, args); + /* fprintf(err_file, "\n"); */ + } +#ifdef ERR_REPORTING_SYSLOG + if (1) { /* FIXME: Make this a runtime option. */ + int syslogpri; + + switch (priority) { + case err_level_emergency: + syslogpri = LOG_EMERG; + break; + case err_level_alert: + syslogpri = LOG_ALERT; + break; + case err_level_critical: + syslogpri = LOG_CRIT; + break; + case err_level_error: + syslogpri = LOG_ERR; + break; + case err_level_warning: + syslogpri = LOG_WARNING; + break; + case err_level_notice: + syslogpri = LOG_NOTICE; + break; + case err_level_info: + syslogpri = LOG_INFO; + break; + case err_level_debug: + case err_level_none: + default: + syslogpri = LOG_DEBUG; + break; + } + + vsyslog(syslogpri, format, args); +#endif + va_end(args); + } +} +#endif /* SRTP_KERNEL_LINUX */ + +void +err_reporting_set_level(err_reporting_level_t lvl) { + err_level = lvl; +} diff --git a/src/libs/srtp/crypto/kernel/key.c b/src/libs/srtp/crypto/kernel/key.c new file mode 100644 index 00000000..9f63b22c --- /dev/null +++ b/src/libs/srtp/crypto/kernel/key.c @@ -0,0 +1,115 @@ +/* + * key.c + * + * key usage limits enforcement + * + * David A. Mcgrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "key.h" + +#define soft_limit 0x10000 + +err_status_t +key_limit_set(key_limit_t key, const xtd_seq_num_t s) { +#ifdef NO_64BIT_MATH + if (high32(s) == 0 && low32(s) < soft_limit) + return err_status_bad_param; +#else + if (s < soft_limit) + return err_status_bad_param; +#endif + key->num_left = s; + key->state = key_state_normal; + return err_status_ok; +} + +err_status_t +key_limit_clone(key_limit_t original, key_limit_t *new_key) { + if (original == NULL) + return err_status_bad_param; + *new_key = original; + return err_status_ok; +} + +err_status_t +key_limit_check(const key_limit_t key) { + if (key->state == key_state_expired) + return err_status_key_expired; + return err_status_ok; +} + +key_event_t +key_limit_update(key_limit_t key) { +#ifdef NO_64BIT_MATH + if (low32(key->num_left) == 0) + { + // carry + key->num_left = make64(high32(key->num_left)-1,low32(key->num_left) - 1); + } + else + { + // no carry + key->num_left = make64(high32(key->num_left),low32(key->num_left) - 1); + } + if (high32(key->num_left) != 0 || low32(key->num_left) >= soft_limit) { + return key_event_normal; /* we're above the soft limit */ + } +#else + key->num_left--; + if (key->num_left >= soft_limit) { + return key_event_normal; /* we're above the soft limit */ + } +#endif + if (key->state == key_state_normal) { + /* we just passed the soft limit, so change the state */ + key->state = key_state_past_soft_limit; + } +#ifdef NO_64BIT_MATH + if (low32(key->num_left) == 0 && high32(key->num_left == 0)) +#else + if (key->num_left < 1) +#endif + { /* we just hit the hard limit */ + key->state = key_state_expired; + return key_event_hard_limit; + } + return key_event_soft_limit; +} + diff --git a/src/libs/srtp/crypto/math/datatypes.c b/src/libs/srtp/crypto/math/datatypes.c new file mode 100644 index 00000000..21c0dc07 --- /dev/null +++ b/src/libs/srtp/crypto/math/datatypes.c @@ -0,0 +1,718 @@ +/* + * datatypes.c + * + * data types for finite fields and functions for input, output, and + * manipulation + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "datatypes.h" + +int +octet_weight[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, + 5, 6, 6, 7, 6, 7, 7, 8 +}; + +int +octet_get_weight(uint8_t octet) { + extern int octet_weight[256]; + + return octet_weight[octet]; +} + +/* + * bit_string is a buffer that is used to hold output strings, e.g. + * for printing. + */ + +/* the value MAX_PRINT_STRING_LEN is defined in datatypes.h */ + +char bit_string[MAX_PRINT_STRING_LEN]; + +uint8_t +nibble_to_hex_char(uint8_t nibble) { + char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + return buf[nibble & 0xF]; +} + +char * +octet_string_hex_string(const void *s, int length) { + const uint8_t *str = (const uint8_t *)s; + int i; + + /* double length, since one octet takes two hex characters */ + length *= 2; + + /* truncate string if it would be too long */ + if (length > MAX_PRINT_STRING_LEN) + length = MAX_PRINT_STRING_LEN-1; + + for (i=0; i < length; i+=2) { + bit_string[i] = nibble_to_hex_char(*str >> 4); + bit_string[i+1] = nibble_to_hex_char(*str++ & 0xF); + } + bit_string[i] = 0; /* null terminate string */ + return bit_string; +} + +static inline int +hex_char_to_nibble(uint8_t c) { + switch(c) { + case ('0'): return 0x0; + case ('1'): return 0x1; + case ('2'): return 0x2; + case ('3'): return 0x3; + case ('4'): return 0x4; + case ('5'): return 0x5; + case ('6'): return 0x6; + case ('7'): return 0x7; + case ('8'): return 0x8; + case ('9'): return 0x9; + case ('a'): return 0xa; + case ('A'): return 0xa; + case ('b'): return 0xb; + case ('B'): return 0xb; + case ('c'): return 0xc; + case ('C'): return 0xc; + case ('d'): return 0xd; + case ('D'): return 0xd; + case ('e'): return 0xe; + case ('E'): return 0xe; + case ('f'): return 0xf; + case ('F'): return 0xf; + default: return -1; /* this flags an error */ + } + /* NOTREACHED */ + return -1; /* this keeps compilers from complaining */ +} + +int +is_hex_string(char *s) { + while(*s != 0) + if (hex_char_to_nibble(*s++) == -1) + return 0; + return 1; +} + +/* + * hex_string_to_octet_string converts a hexadecimal string + * of length 2 * len to a raw octet string of length len + */ + +int +hex_string_to_octet_string(char *raw, char *hex, int len) { + uint8_t x; + int tmp; + int hex_len; + + hex_len = 0; + while (hex_len < len) { + tmp = hex_char_to_nibble(hex[0]); + if (tmp == -1) + return hex_len; + x = (tmp << 4); + hex_len++; + tmp = hex_char_to_nibble(hex[1]); + if (tmp == -1) + return hex_len; + x |= (tmp & 0xff); + hex_len++; + *raw++ = x; + hex += 2; + } + return hex_len; +} + +char * +v128_hex_string(v128_t *x) { + int i, j; + + for (i=j=0; i < 16; i++) { + bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4); + bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF); + } + + bit_string[j] = 0; /* null terminate string */ + return bit_string; +} + +char * +v128_bit_string(v128_t *x) { + int j, i; + uint32_t mask; + + for (j=i=0; j < 4; j++) { + for (mask=0x80000000; mask > 0; mask >>= 1) { + if (x->v32[j] & mask) + bit_string[i] = '1'; + else + bit_string[i] = '0'; + ++i; + } + } + bit_string[128] = 0; /* null terminate string */ + + return bit_string; +} + +void +v128_copy_octet_string(v128_t *x, const uint8_t s[16]) { +#ifdef ALIGNMENT_32BIT_REQUIRED + if ((((uint32_t) &s[0]) & 0x3) != 0) +#endif + { + x->v8[0] = s[0]; + x->v8[1] = s[1]; + x->v8[2] = s[2]; + x->v8[3] = s[3]; + x->v8[4] = s[4]; + x->v8[5] = s[5]; + x->v8[6] = s[6]; + x->v8[7] = s[7]; + x->v8[8] = s[8]; + x->v8[9] = s[9]; + x->v8[10] = s[10]; + x->v8[11] = s[11]; + x->v8[12] = s[12]; + x->v8[13] = s[13]; + x->v8[14] = s[14]; + x->v8[15] = s[15]; + } +#ifdef ALIGNMENT_32BIT_REQUIRED + else + { + v128_t *v = (v128_t *) &s[0]; + + v128_copy(x,v); + } +#endif +} + +#ifndef DATATYPES_USE_MACROS /* little functions are not macros */ + +void +v128_set_to_zero(v128_t *x) { + _v128_set_to_zero(x); +} + +void +v128_copy(v128_t *x, const v128_t *y) { + _v128_copy(x, y); +} + +void +v128_xor(v128_t *z, v128_t *x, v128_t *y) { + _v128_xor(z, x, y); +} + +void +v128_and(v128_t *z, v128_t *x, v128_t *y) { + _v128_and(z, x, y); +} + +void +v128_or(v128_t *z, v128_t *x, v128_t *y) { + _v128_or(z, x, y); +} + +void +v128_complement(v128_t *x) { + _v128_complement(x); +} + +int +v128_is_eq(const v128_t *x, const v128_t *y) { + return _v128_is_eq(x, y); +} + +int +v128_xor_eq(v128_t *x, const v128_t *y) { + return _v128_xor_eq(x, y); +} + +int +v128_get_bit(const v128_t *x, int i) { + return _v128_get_bit(x, i); +} + +void +v128_set_bit(v128_t *x, int i) { + _v128_set_bit(x, i); +} + +void +v128_clear_bit(v128_t *x, int i){ + _v128_clear_bit(x, i); +} + +void +v128_set_bit_to(v128_t *x, int i, int y){ + _v128_set_bit_to(x, i, y); +} + + +#endif /* DATATYPES_USE_MACROS */ + +void +v128_right_shift(v128_t *x, int shift) { + const int base_index = shift >> 5; + const int bit_index = shift & 31; + int i, from; + uint32_t b; + + if (shift > 127) { + v128_set_to_zero(x); + return; + } + + if (bit_index == 0) { + + /* copy each word from left size to right side */ + x->v32[4-1] = x->v32[4-1-base_index]; + for (i=4-1; i > base_index; i--) + x->v32[i-1] = x->v32[i-1-base_index]; + + } else { + + /* set each word to the "or" of the two bit-shifted words */ + for (i = 4; i > base_index; i--) { + from = i-1 - base_index; + b = x->v32[from] << bit_index; + if (from > 0) + b |= x->v32[from-1] >> (32-bit_index); + x->v32[i-1] = b; + } + + } + + /* now wrap up the final portion */ + for (i=0; i < base_index; i++) + x->v32[i] = 0; + +} + +void +v128_left_shift(v128_t *x, int shift) { + int i; + const int base_index = shift >> 5; + const int bit_index = shift & 31; + + if (shift > 127) { + v128_set_to_zero(x); + return; + } + + if (bit_index == 0) { + for (i=0; i < 4 - base_index; i++) + x->v32[i] = x->v32[i+base_index]; + } else { + for (i=0; i < 4 - base_index - 1; i++) + x->v32[i] = (x->v32[i+base_index] >> bit_index) ^ + (x->v32[i+base_index+1] << (32 - bit_index)); + x->v32[4 - base_index-1] = x->v32[4-1] >> bit_index; + } + + /* now wrap up the final portion */ + for (i = 4 - base_index; i < 4; i++) + x->v32[i] = 0; + +} + +/* functions manipulating bitvector_t */ + +#ifndef DATATYPES_USE_MACROS /* little functions are not macros */ + +int +bitvector_get_bit(const bitvector_t *v, int bit_index) +{ + return _bitvector_get_bit(v, bit_index); +} + +void +bitvector_set_bit(bitvector_t *v, int bit_index) +{ + _bitvector_set_bit(v, bit_index); +} + +void +bitvector_clear_bit(bitvector_t *v, int bit_index) +{ + _bitvector_clear_bit(v, bit_index); +} + + +#endif /* DATATYPES_USE_MACROS */ + +int +bitvector_alloc(bitvector_t *v, unsigned long length) { + unsigned long l; + + /* Round length up to a multiple of bits_per_word */ + length = (length + bits_per_word - 1) & ~(unsigned long)((bits_per_word - 1)); + + l = length / bits_per_word * bytes_per_word; + + /* allocate memory, then set parameters */ + if (l == 0) + v->word = NULL; + else { + v->word = (uint32_t*)crypto_alloc(l); + if (v->word == NULL) { + v->word = NULL; + v->length = 0; + return -1; + } + } + v->length = length; + + /* initialize bitvector to zero */ + bitvector_set_to_zero(v); + + return 0; +} + + +void +bitvector_dealloc(bitvector_t *v) { + if (v->word != NULL) + crypto_free(v->word); + v->word = NULL; + v->length = 0; +} + +void +bitvector_set_to_zero(bitvector_t *x) +{ + /* C99 guarantees that memset(0) will set the value 0 for uint32_t */ + memset(x->word, 0, x->length >> 3); +} + +char * +bitvector_bit_string(bitvector_t *x, char* buf, int len) { + int j, i; + uint32_t mask; + + for (j=i=0; j < (int)(x->length>>5) && i < len-1; j++) { + for (mask=0x80000000; mask > 0; mask >>= 1) { + if (x->word[j] & mask) + buf[i] = '1'; + else + buf[i] = '0'; + ++i; + if (i >= len-1) + break; + } + } + buf[i] = 0; /* null terminate string */ + + return buf; +} + +void +bitvector_left_shift(bitvector_t *x, int shift) { + int i; + const int base_index = shift >> 5; + const int bit_index = shift & 31; + const int word_length = x->length >> 5; + + if (shift >= (int)x->length) { + bitvector_set_to_zero(x); + return; + } + + if (bit_index == 0) { + for (i=0; i < word_length - base_index; i++) + x->word[i] = x->word[i+base_index]; + } else { + for (i=0; i < word_length - base_index - 1; i++) + x->word[i] = (x->word[i+base_index] >> bit_index) ^ + (x->word[i+base_index+1] << (32 - bit_index)); + x->word[word_length - base_index-1] = x->word[word_length-1] >> bit_index; + } + + /* now wrap up the final portion */ + for (i = word_length - base_index; i < word_length; i++) + x->word[i] = 0; + +} + + +int +octet_string_is_eq(uint8_t *a, uint8_t *b, int len) { + uint8_t *end = b + len; + while (b < end) + if (*a++ != *b++) + return 1; + return 0; +} + +void +octet_string_set_to_zero(uint8_t *s, int len) { + uint8_t *end = s + len; + + do { + *s = 0; + } while (++s < end); + +} + + +/* + * From RFC 1521: The Base64 Alphabet + * + * Value Encoding Value Encoding Value Encoding Value Encoding + * 0 A 17 R 34 i 51 z + * 1 B 18 S 35 j 52 0 + * 2 C 19 T 36 k 53 1 + * 3 D 20 U 37 l 54 2 + * 4 E 21 V 38 m 55 3 + * 5 F 22 W 39 n 56 4 + * 6 G 23 X 40 o 57 5 + * 7 H 24 Y 41 p 58 6 + * 8 I 25 Z 42 q 59 7 + * 9 J 26 a 43 r 60 8 + * 10 K 27 b 44 s 61 9 + * 11 L 28 c 45 t 62 + + * 12 M 29 d 46 u 63 / + * 13 N 30 e 47 v + * 14 O 31 f 48 w (pad) = + * 15 P 32 g 49 x + * 16 Q 33 h 50 y + */ + +int +base64_char_to_sextet(uint8_t c) { + switch(c) { + case 'A': + return 0; + case 'B': + return 1; + case 'C': + return 2; + case 'D': + return 3; + case 'E': + return 4; + case 'F': + return 5; + case 'G': + return 6; + case 'H': + return 7; + case 'I': + return 8; + case 'J': + return 9; + case 'K': + return 10; + case 'L': + return 11; + case 'M': + return 12; + case 'N': + return 13; + case 'O': + return 14; + case 'P': + return 15; + case 'Q': + return 16; + case 'R': + return 17; + case 'S': + return 18; + case 'T': + return 19; + case 'U': + return 20; + case 'V': + return 21; + case 'W': + return 22; + case 'X': + return 23; + case 'Y': + return 24; + case 'Z': + return 25; + case 'a': + return 26; + case 'b': + return 27; + case 'c': + return 28; + case 'd': + return 29; + case 'e': + return 30; + case 'f': + return 31; + case 'g': + return 32; + case 'h': + return 33; + case 'i': + return 34; + case 'j': + return 35; + case 'k': + return 36; + case 'l': + return 37; + case 'm': + return 38; + case 'n': + return 39; + case 'o': + return 40; + case 'p': + return 41; + case 'q': + return 42; + case 'r': + return 43; + case 's': + return 44; + case 't': + return 45; + case 'u': + return 46; + case 'v': + return 47; + case 'w': + return 48; + case 'x': + return 49; + case 'y': + return 50; + case 'z': + return 51; + case '0': + return 52; + case '1': + return 53; + case '2': + return 54; + case '3': + return 55; + case '4': + return 56; + case '5': + return 57; + case '6': + return 58; + case '7': + return 59; + case '8': + return 60; + case '9': + return 61; + case '+': + return 62; + case '/': + return 63; + case '=': + return 64; + default: + break; + } + return -1; +} + +/* + * base64_string_to_octet_string converts a hexadecimal string + * of length 2 * len to a raw octet string of length len + */ + +int +base64_string_to_octet_string(char *raw, char *base64, int len) { + uint8_t x; + int tmp; + int base64_len; + + base64_len = 0; + while (base64_len < len) { + tmp = base64_char_to_sextet(base64[0]); + if (tmp == -1) + return base64_len; + x = (tmp << 6); + base64_len++; + tmp = base64_char_to_sextet(base64[1]); + if (tmp == -1) + return base64_len; + x |= (tmp & 0xffff); + base64_len++; + *raw++ = x; + base64 += 2; + } + return base64_len; +} diff --git a/src/libs/srtp/crypto/math/gf2_8.c b/src/libs/srtp/crypto/math/gf2_8.c new file mode 100644 index 00000000..f1f45bdd --- /dev/null +++ b/src/libs/srtp/crypto/math/gf2_8.c @@ -0,0 +1,83 @@ +/* + * gf2_8.c + * + * GF(256) finite field implementation, with the representation used + * in the AES cipher. + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "datatypes.h" +#include "gf2_8.h" + +/* gf2_8_shift() moved to gf2_8.h as an inline function */ + +gf2_8 +gf2_8_multiply(gf2_8 x, gf2_8 y) { + gf2_8 z = 0; + + if (y & 1) z ^= x; x = gf2_8_shift(x); + if (y & 2) z ^= x; x = gf2_8_shift(x); + if (y & 4) z ^= x; x = gf2_8_shift(x); + if (y & 8) z ^= x; x = gf2_8_shift(x); + if (y & 16) z ^= x; x = gf2_8_shift(x); + if (y & 32) z ^= x; x = gf2_8_shift(x); + if (y & 64) z ^= x; x = gf2_8_shift(x); + if (y & 128) z ^= x; + + return z; +} + + +/* this should use the euclidean algorithm */ + +gf2_8 +gf2_8_compute_inverse(gf2_8 x) { + unsigned int i; + + if (x == 0) return 0; /* zero is a special case */ + for (i=0; i < 256; i++) + if (gf2_8_multiply((gf2_8) i, x) == 1) + return (gf2_8) i; + + return 0; +} + diff --git a/src/libs/srtp/crypto/math/math.c b/src/libs/srtp/crypto/math/math.c new file mode 100644 index 00000000..b78f77d0 --- /dev/null +++ b/src/libs/srtp/crypto/math/math.c @@ -0,0 +1,802 @@ +/* + * math.c + * + * crypto math operations and data types + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "crypto_math.h" + +int +octet_weight[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, + 5, 6, 6, 7, 6, 7, 7, 8 +}; + +int +low_bit[256] = { + -1, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 7, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0 +}; + + +int +high_bit[256] = { + -1, 0, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7 +}; + +static int +octet_get_weight(uint8_t octet) { + extern int octet_weight[256]; + + return octet_weight[octet]; +} + +unsigned char +v32_weight(v32_t a) { + unsigned int wt = 0; + + wt += octet_weight[a.v8[0]]; /* note: endian-ness makes no difference */ + wt += octet_weight[a.v8[1]]; + wt += octet_weight[a.v8[2]]; + wt += octet_weight[a.v8[3]]; + + return wt; +} + +unsigned char +v32_distance(v32_t x, v32_t y) { + x.value ^= y.value; + return v32_weight(x); +} + +unsigned int +v32_dot_product(v32_t a, v32_t b) { + a.value &= b.value; + return v32_weight(a) & 1; +} + +/* + * _bit_string returns a NULL-terminated character string suitable for + * printing + */ + +#define MAX_STRING_LENGTH 1024 + +char bit_string[MAX_STRING_LENGTH]; + +char * +octet_bit_string(uint8_t x) { + int mask, index; + + for (mask = 1, index = 0; mask < 256; mask <<= 1) + if ((x & mask) == 0) + bit_string[index++] = '0'; + else + bit_string[index++] = '1'; + + bit_string[index++] = 0; /* NULL terminate string */ + + return bit_string; +} + +char * +v16_bit_string(v16_t x) { + int i, mask, index; + + for (i = index = 0; i < 2; i++) { + for (mask = 1; mask < 256; mask <<= 1) + if ((x.v8[i] & mask) == 0) + bit_string[index++] = '0'; + else + bit_string[index++] = '1'; + } + bit_string[index++] = 0; /* NULL terminate string */ + return bit_string; +} + +char * +v32_bit_string(v32_t x) { + int i, mask, index; + + for (i = index = 0; i < 4; i++) { + for (mask = 128; mask > 0; mask >>= 1) + if ((x.v8[i] & mask) == 0) + bit_string[index++] = '0'; + else + bit_string[index++] = '1'; + } + bit_string[index++] = 0; /* NULL terminate string */ + return bit_string; +} + +char * +v64_bit_string(const v64_t *x) { + int i, mask, index; + + for (i = index = 0; i < 8; i++) { + for (mask = 1; mask < 256; mask <<= 1) + if ((x->v8[i] & mask) == 0) + bit_string[index++] = '0'; + else + bit_string[index++] = '1'; + } + bit_string[index++] = 0; /* NULL terminate string */ + return bit_string; +} + +char * +v128_bit_string(v128_t *x) { + int j, index; + uint32_t mask; + + for (j=index=0; j < 4; j++) { + for (mask=0x80000000; mask > 0; mask >>= 1) { + if (x->v32[j] & mask) + bit_string[index] = '1'; + else + bit_string[index] = '0'; + ++index; + } + } + bit_string[128] = 0; /* null terminate string */ + + return bit_string; +} + +static uint8_t +nibble_to_hex_char(uint8_t nibble) { + char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + return buf[nibble & 0xF]; +} + +char * +octet_hex_string(uint8_t x) { + + bit_string[0] = nibble_to_hex_char(x >> 4); + bit_string[1] = nibble_to_hex_char(x & 0xF); + + bit_string[2] = 0; /* null terminate string */ + return bit_string; +} + +char * +octet_string_hex_string(const void *str, int length) { + const uint8_t *s = str; + int i; + + /* double length, since one octet takes two hex characters */ + length *= 2; + + /* truncate string if it would be too long */ + if (length > MAX_STRING_LENGTH) + length = MAX_STRING_LENGTH-1; + + for (i=0; i < length; i+=2) { + bit_string[i] = nibble_to_hex_char(*s >> 4); + bit_string[i+1] = nibble_to_hex_char(*s++ & 0xF); + } + bit_string[i] = 0; /* null terminate string */ + return bit_string; +} + +char * +v16_hex_string(v16_t x) { + int i, j; + + for (i=j=0; i < 2; i++) { + bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4); + bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF); + } + + bit_string[j] = 0; /* null terminate string */ + return bit_string; +} + +char * +v32_hex_string(v32_t x) { + int i, j; + + for (i=j=0; i < 4; i++) { + bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4); + bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF); + } + + bit_string[j] = 0; /* null terminate string */ + return bit_string; +} + +char * +v64_hex_string(const v64_t *x) { + int i, j; + + for (i=j=0; i < 8; i++) { + bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4); + bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF); + } + + bit_string[j] = 0; /* null terminate string */ + return bit_string; +} + +char * +v128_hex_string(v128_t *x) { + int i, j; + + for (i=j=0; i < 16; i++) { + bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4); + bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF); + } + + bit_string[j] = 0; /* null terminate string */ + return bit_string; +} + +char * +char_to_hex_string(char *x, int num_char) { + int i, j; + + if (num_char >= 16) + num_char = 16; + for (i=j=0; i < num_char; i++) { + bit_string[j++] = nibble_to_hex_char(x[i] >> 4); + bit_string[j++] = nibble_to_hex_char(x[i] & 0xF); + } + + bit_string[j] = 0; /* null terminate string */ + return bit_string; +} + +int +hex_char_to_nibble(uint8_t c) { + switch(c) { + case ('0'): return 0x0; + case ('1'): return 0x1; + case ('2'): return 0x2; + case ('3'): return 0x3; + case ('4'): return 0x4; + case ('5'): return 0x5; + case ('6'): return 0x6; + case ('7'): return 0x7; + case ('8'): return 0x8; + case ('9'): return 0x9; + case ('a'): return 0xa; + case ('A'): return 0xa; + case ('b'): return 0xb; + case ('B'): return 0xb; + case ('c'): return 0xc; + case ('C'): return 0xc; + case ('d'): return 0xd; + case ('D'): return 0xd; + case ('e'): return 0xe; + case ('E'): return 0xe; + case ('f'): return 0xf; + case ('F'): return 0xf; + default: return -1; /* this flags an error */ + } + /* NOTREACHED */ + return -1; /* this keeps compilers from complaining */ +} + +int +is_hex_string(char *s) { + while(*s != 0) + if (hex_char_to_nibble(*s++) == -1) + return 0; + return 1; +} + +uint8_t +hex_string_to_octet(char *s) { + uint8_t x; + + x = (hex_char_to_nibble(s[0]) << 4) + | hex_char_to_nibble(s[1] & 0xFF); + + return x; +} + +/* + * hex_string_to_octet_string converts a hexadecimal string + * of length 2 * len to a raw octet string of length len + */ + +static int +hex_string_to_octet_string(char *raw, char *hex, int len) { + uint8_t x; + int tmp; + int hex_len; + + hex_len = 0; + while (hex_len < len) { + tmp = hex_char_to_nibble(hex[0]); + if (tmp == -1) + return hex_len; + x = (tmp << 4); + hex_len++; + tmp = hex_char_to_nibble(hex[1]); + if (tmp == -1) + return hex_len; + x |= (tmp & 0xff); + hex_len++; + *raw++ = x; + hex += 2; + } + return hex_len; +} + +v16_t +hex_string_to_v16(char *s) { + v16_t x; + int i, j; + + for (i=j=0; i < 4; i += 2, j++) { + x.v8[j] = (hex_char_to_nibble(s[i]) << 4) + | hex_char_to_nibble(s[i+1] & 0xFF); + } + return x; +} + +v32_t +hex_string_to_v32(char *s) { + v32_t x; + int i, j; + + for (i=j=0; i < 8; i += 2, j++) { + x.v8[j] = (hex_char_to_nibble(s[i]) << 4) + | hex_char_to_nibble(s[i+1] & 0xFF); + } + return x; +} + +v64_t +hex_string_to_v64(char *s) { + v64_t x; + int i, j; + + for (i=j=0; i < 16; i += 2, j++) { + x.v8[j] = (hex_char_to_nibble(s[i]) << 4) + | hex_char_to_nibble(s[i+1] & 0xFF); + } + return x; +} + +v128_t +hex_string_to_v128(char *s) { + v128_t x; + int i, j; + + for (i=j=0; i < 32; i += 2, j++) { + x.v8[j] = (hex_char_to_nibble(s[i]) << 4) + | hex_char_to_nibble(s[i+1] & 0xFF); + } + return x; +} + + + +/* + * the matrix A[] is stored in column format, i.e., A[i] is the ith + * column of the matrix + */ + +uint8_t +A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b) { + int index = 0; + unsigned mask; + + for (mask=1; mask < 256; mask *= 2) { + if (x & mask) + b^= A[index]; + ++index; + } + + return b; +} + +void +v16_copy_octet_string(v16_t *x, const uint8_t s[2]) { + x->v8[0] = s[0]; + x->v8[1] = s[1]; +} + +void +v32_copy_octet_string(v32_t *x, const uint8_t s[4]) { + x->v8[0] = s[0]; + x->v8[1] = s[1]; + x->v8[2] = s[2]; + x->v8[3] = s[3]; +} + +void +v64_copy_octet_string(v64_t *x, const uint8_t s[8]) { + x->v8[0] = s[0]; + x->v8[1] = s[1]; + x->v8[2] = s[2]; + x->v8[3] = s[3]; + x->v8[4] = s[4]; + x->v8[5] = s[5]; + x->v8[6] = s[6]; + x->v8[7] = s[7]; +} + +void +v128_copy_octet_string(v128_t *x, const uint8_t s[16]) { + x->v8[0] = s[0]; + x->v8[1] = s[1]; + x->v8[2] = s[2]; + x->v8[3] = s[3]; + x->v8[4] = s[4]; + x->v8[5] = s[5]; + x->v8[6] = s[6]; + x->v8[7] = s[7]; + x->v8[8] = s[8]; + x->v8[9] = s[9]; + x->v8[10] = s[10]; + x->v8[11] = s[11]; + x->v8[12] = s[12]; + x->v8[13] = s[13]; + x->v8[14] = s[14]; + x->v8[15] = s[15]; + +} + +#ifndef DATATYPES_USE_MACROS /* little functions are not macros */ + +void +v128_set_to_zero(v128_t *x) { + _v128_set_to_zero(x); +} + +void +v128_copy(v128_t *x, const v128_t *y) { + _v128_copy(x, y); +} + +void +v128_xor(v128_t *z, v128_t *x, v128_t *y) { + _v128_xor(z, x, y); +} + +void +v128_and(v128_t *z, v128_t *x, v128_t *y) { + _v128_and(z, x, y); +} + +void +v128_or(v128_t *z, v128_t *x, v128_t *y) { + _v128_or(z, x, y); +} + +void +v128_complement(v128_t *x) { + _v128_complement(x); +} + +int +v128_is_eq(const v128_t *x, const v128_t *y) { + return _v128_is_eq(x, y); +} + +int +v128_get_bit(const v128_t *x, int i) { + return _v128_get_bit(x, i); +} + +void +v128_set_bit(v128_t *x, int i) { + _v128_set_bit(x, i); +} + +void +v128_clear_bit(v128_t *x, int i){ + _v128_clear_bit(x, i); +} + +void +v128_set_bit_to(v128_t *x, int i, int y){ + _v128_set_bit_to(x, i, y); +} + + +#endif /* DATATYPES_USE_MACROS */ + + +static inline void +v128_left_shift2(v128_t *x, int num_bits) { + int i; + int word_shift = num_bits >> 5; + int bit_shift = num_bits & 31; + + for (i=0; i < (4-word_shift); i++) { + x->v32[i] = x->v32[i+word_shift] << bit_shift; + } + + for ( ; i < word_shift; i++) { + x->v32[i] = 0; + } + +} + +static void +v128_right_shift(v128_t *x, int index) { + const int base_index = index >> 5; + const int bit_index = index & 31; + int i, from; + uint32_t b; + + if (index > 127) { + v128_set_to_zero(x); + return; + } + + if (bit_index == 0) { + + /* copy each word from left size to right side */ + x->v32[4-1] = x->v32[4-1-base_index]; + for (i=4-1; i > base_index; i--) + x->v32[i-1] = x->v32[i-1-base_index]; + + } else { + + /* set each word to the "or" of the two bit-shifted words */ + for (i = 4; i > base_index; i--) { + from = i-1 - base_index; + b = x->v32[from] << bit_index; + if (from > 0) + b |= x->v32[from-1] >> (32-bit_index); + x->v32[i-1] = b; + } + + } + + /* now wrap up the final portion */ + for (i=0; i < base_index; i++) + x->v32[i] = 0; + +} + +static void +v128_left_shift(v128_t *x, int index) { + int i; + const int base_index = index >> 5; + const int bit_index = index & 31; + + if (index > 127) { + v128_set_to_zero(x); + return; + } + + if (bit_index == 0) { + for (i=0; i < 4 - base_index; i++) + x->v32[i] = x->v32[i+base_index]; + } else { + for (i=0; i < 4 - base_index - 1; i++) + x->v32[i] = (x->v32[i+base_index] << bit_index) ^ + (x->v32[i+base_index+1] >> (32 - bit_index)); + x->v32[4 - base_index-1] = x->v32[4-1] << bit_index; + } + + /* now wrap up the final portion */ + for (i = 4 - base_index; i < 4; i++) + x->v32[i] = 0; + +} + + +#if 0 +void +v128_add(v128_t *z, v128_t *x, v128_t *y) { + /* integer addition modulo 2^128 */ + +#ifdef WORDS_BIGENDIAN + uint64_t tmp; + + tmp = x->v32[3] + y->v32[3]; + z->v32[3] = (uint32_t) tmp; + + tmp = x->v32[2] + y->v32[2] + (tmp >> 32); + z->v32[2] = (uint32_t) tmp; + + tmp = x->v32[1] + y->v32[1] + (tmp >> 32); + z->v32[1] = (uint32_t) tmp; + + tmp = x->v32[0] + y->v32[0] + (tmp >> 32); + z->v32[0] = (uint32_t) tmp; + +#else /* assume little endian architecture */ + uint64_t tmp; + + tmp = htonl(x->v32[3]) + htonl(y->v32[3]); + z->v32[3] = ntohl((uint32_t) tmp); + + tmp = htonl(x->v32[2]) + htonl(y->v32[2]) + htonl(tmp >> 32); + z->v32[2] = ntohl((uint32_t) tmp); + + tmp = htonl(x->v32[1]) + htonl(y->v32[1]) + htonl(tmp >> 32); + z->v32[1] = ntohl((uint32_t) tmp); + + tmp = htonl(x->v32[0]) + htonl(y->v32[0]) + htonl(tmp >> 32); + z->v32[0] = ntohl((uint32_t) tmp); + +#endif /* WORDS_BIGENDIAN */ + +} +#endif + +static int +octet_string_is_eq(uint8_t *a, uint8_t *b, int len) { + uint8_t *end = b + len; + while (b < end) + if (*a++ != *b++) + return 1; + return 0; +} + +static void +octet_string_set_to_zero(uint8_t *s, int len) { + uint8_t *end = s + len; + + do { + *s = 0; + } while (++s < end); + +} + + +/* functions below not yet tested! */ + +int +v32_low_bit(v32_t *w) { + int value; + + value = low_bit[w->v8[0]]; + if (value != -1) + return value; + value = low_bit[w->v8[1]]; + if (value != -1) + return value + 8; + value = low_bit[w->v8[2]]; + if (value != -1) + return value + 16; + value = low_bit[w->v8[3]]; + if (value == -1) + return -1; + return value + 24; +} + +/* high_bit not done yet */ + + + + + diff --git a/src/libs/srtp/crypto/math/stat.c b/src/libs/srtp/crypto/math/stat.c new file mode 100644 index 00000000..5e46c209 --- /dev/null +++ b/src/libs/srtp/crypto/math/stat.c @@ -0,0 +1,367 @@ +/* + * stats.c + * + * statistical tests for randomness (FIPS 140-2, Section 4.9) + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +#include "stat.h" + +debug_module_t mod_stat = { + 0, /* debugging is off by default */ + (char *)"stat test" /* printable module name */ +}; + +/* + * each test assumes that 20,000 bits (2500 octets) of data is + * provided as input + */ + +#define STAT_TEST_DATA_LEN 2500 + +err_status_t +stat_test_monobit(uint8_t *data) { + uint8_t *data_end = data + STAT_TEST_DATA_LEN; + uint16_t ones_count; + + ones_count = 0; + while (data < data_end) { + ones_count += octet_get_weight(*data); + data++; + } + + debug_print(mod_stat, "bit count: %d", ones_count); + + if ((ones_count < 9725) || (ones_count > 10275)) + return err_status_algo_fail; + + return err_status_ok; +} + +err_status_t +stat_test_poker(uint8_t *data) { + int i; + uint8_t *data_end = data + STAT_TEST_DATA_LEN; + double poker; + uint16_t f[16] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }; + + while (data < data_end) { + f[*data & 0x0f]++; /* increment freq. count for low nibble */ + f[(*data) >> 4]++; /* increment freq. count for high nibble */ + data++; + } + + poker = 0.0; + for (i=0; i < 16; i++) + poker += (double) f[i] * f[i]; + + poker *= (16.0 / 5000.0); + poker -= 5000.0; + + debug_print(mod_stat, "poker test: %f\n", poker); + + if ((poker < 2.16) || (poker > 46.17)) + return err_status_algo_fail; + + return err_status_ok; +} + + +/* + * runs[i] holds the number of runs of size (i-1) + */ + +err_status_t +stat_test_runs(uint8_t *data) { + uint8_t *data_end = data + STAT_TEST_DATA_LEN; + uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 }; + uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 }; + uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 }; + uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 }; + int state = 0; + uint16_t mask; + int i; + + /* + * the state variable holds the number of bits in the + * current run (or gap, if negative) + */ + + while (data < data_end) { + + /* loop over the bits of this byte */ + for (mask = 1; mask < 256; mask <<= 1) { + if (*data & mask) { + + /* next bit is a one */ + if (state > 0) { + + /* prefix is a run, so increment the run-count */ + state++; + + /* check for long runs */ + if (state > 25) { + debug_print(mod_stat, ">25 runs: %d", state); + return err_status_algo_fail; + } + + } else if (state < 0) { + + /* prefix is a gap */ + if (state < -25) { + debug_print(mod_stat, ">25 gaps: %d", state); + return err_status_algo_fail; /* long-runs test failed */ + } + if (state < -6) { + state = -6; /* group together gaps > 5 */ + } + gaps[-1-state]++; /* increment gap count */ + state = 1; /* set state at one set bit */ + } else { + + /* state is zero; this happens only at initialization */ + state = 1; + } + } else { + + /* next bit is a zero */ + if (state > 0) { + + /* prefix is a run */ + if (state > 25) { + debug_print(mod_stat, ">25 runs (2): %d", state); + return err_status_algo_fail; /* long-runs test failed */ + } + if (state > 6) { + state = 6; /* group together runs > 5 */ + } + runs[state-1]++; /* increment run count */ + state = -1; /* set state at one zero bit */ + } else if (state < 0) { + + /* prefix is a gap, so increment gap-count (decrement state) */ + state--; + + /* check for long gaps */ + if (state < -25) { + debug_print(mod_stat, ">25 gaps (2): %d", state); + return err_status_algo_fail; + } + + } else { + + /* state is zero; this happens only at initialization */ + state = -1; + } + } + } + + /* move along to next octet */ + data++; + } + + if (mod_stat.on) { + debug_print(mod_stat, "runs test", NULL); + for (i=0; i < 6; i++) + debug_print(mod_stat, " runs[]: %d", runs[i]); + for (i=0; i < 6; i++) + debug_print(mod_stat, " gaps[]: %d", gaps[i]); + } + + /* check run and gap counts against the fixed limits */ + for (i=0; i < 6; i++) + if ( (runs[i] < lo_value[i] ) || (runs[i] > hi_value[i]) + || (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i])) + return err_status_algo_fail; + + + return err_status_ok; +} + + +/* + * the function stat_test_rand_source applys the FIPS-140-2 statistical + * tests to the random source defined by rs + * + */ + +#define RAND_SRC_BUF_OCTETS 50 /* this value MUST divide 2500! */ + +err_status_t +stat_test_rand_source(rand_source_func_t get_rand_bytes) { + int i; + double poker; + uint8_t *data, *data_end; + uint16_t f[16] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }; + uint8_t buffer[RAND_SRC_BUF_OCTETS]; + err_status_t status; + int ones_count = 0; + uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 }; + uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 }; + uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 }; + uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 }; + int state = 0; + uint16_t mask; + + /* counters for monobit, poker, and runs tests are initialized above */ + + /* main loop: fill buffer, update counters for stat tests */ + for (i=0; i < 2500; i+=RAND_SRC_BUF_OCTETS) { + + /* fill data buffer */ + status = get_rand_bytes(buffer, RAND_SRC_BUF_OCTETS); + if (status) { + debug_print(mod_stat, "couldn't get rand bytes: %d",status); + return status; + } + +#if 0 + debug_print(mod_stat, "%s", + octet_string_hex_string(buffer, RAND_SRC_BUF_OCTETS)); +#endif + + data = buffer; + data_end = data + RAND_SRC_BUF_OCTETS; + while (data < data_end) { + + /* update monobit test counter */ + ones_count += octet_get_weight(*data); + + /* update poker test counters */ + f[*data & 0x0f]++; /* increment freq. count for low nibble */ + f[(*data) >> 4]++; /* increment freq. count for high nibble */ + + /* update runs test counters */ + /* loop over the bits of this byte */ + for (mask = 1; mask < 256; mask <<= 1) { + if (*data & mask) { + + /* next bit is a one */ + if (state > 0) { + + /* prefix is a run, so increment the run-count */ + state++; + + /* check for long runs */ + if (state > 25) { + debug_print(mod_stat, ">25 runs (3): %d", state); + return err_status_algo_fail; + } + + } else if (state < 0) { + + /* prefix is a gap */ + if (state < -25) { + debug_print(mod_stat, ">25 gaps (3): %d", state); + return err_status_algo_fail; /* long-runs test failed */ + } + if (state < -6) { + state = -6; /* group together gaps > 5 */ + } + gaps[-1-state]++; /* increment gap count */ + state = 1; /* set state at one set bit */ + } else { + + /* state is zero; this happens only at initialization */ + state = 1; + } + } else { + + /* next bit is a zero */ + if (state > 0) { + + /* prefix is a run */ + if (state > 25) { + debug_print(mod_stat, ">25 runs (4): %d", state); + return err_status_algo_fail; /* long-runs test failed */ + } + if (state > 6) { + state = 6; /* group together runs > 5 */ + } + runs[state-1]++; /* increment run count */ + state = -1; /* set state at one zero bit */ + } else if (state < 0) { + + /* prefix is a gap, so increment gap-count (decrement state) */ + state--; + + /* check for long gaps */ + if (state < -25) { + debug_print(mod_stat, ">25 gaps (4): %d", state); + return err_status_algo_fail; + } + + } else { + + /* state is zero; this happens only at initialization */ + state = -1; + } + } + } + + /* advance data pointer */ + data++; + } + } + + /* check to see if test data is within bounds */ + + /* check monobit test data */ + + debug_print(mod_stat, "stat: bit count: %d", ones_count); + + if ((ones_count < 9725) || (ones_count > 10275)) { + debug_print(mod_stat, "stat: failed monobit test %d", ones_count); + return err_status_algo_fail; + } + + /* check poker test data */ + poker = 0.0; + for (i=0; i < 16; i++) + poker += (double) f[i] * f[i]; + + poker *= (16.0 / 5000.0); + poker -= 5000.0; + + debug_print(mod_stat, "stat: poker test: %f", poker); + + if ((poker < 2.16) || (poker > 46.17)) { + debug_print(mod_stat, "stat: failed poker test", NULL); + return err_status_algo_fail; + } + + /* check run and gap counts against the fixed limits */ + for (i=0; i < 6; i++) + if ((runs[i] < lo_value[i] ) || (runs[i] > hi_value[i]) + || (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i])) { + debug_print(mod_stat, "stat: failed run/gap test", NULL); + return err_status_algo_fail; + } + + debug_print(mod_stat, "passed random stat test", NULL); + return err_status_ok; +} + +err_status_t +stat_test_rand_source_with_repetition(rand_source_func_t source, unsigned num_trials) { + unsigned int i; + err_status_t err = err_status_algo_fail; + + for (i=0; i < num_trials; i++) { + err = stat_test_rand_source(source); + if (err == err_status_ok) { + return err_status_ok; + } + debug_print(mod_stat, "failed stat test (try number %d)\n", i); + } + + return err; +} diff --git a/src/libs/srtp/crypto/replay/rdb.c b/src/libs/srtp/crypto/replay/rdb.c new file mode 100644 index 00000000..5d204ec0 --- /dev/null +++ b/src/libs/srtp/crypto/replay/rdb.c @@ -0,0 +1,137 @@ +/* + * rdb.c + * + * Implements a replay database for packet security + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "rdb.h" + + +/* + * this implementation of a replay database works as follows: + * + * window_start is the index of the first packet in the window + * bitmask a bit-buffer, containing the most recently entered + * index as the leftmost bit + * + */ + +/* rdb_init initalizes rdb */ + +err_status_t +rdb_init(rdb_t *rdb) { + v128_set_to_zero(&rdb->bitmask); + rdb->window_start = 0; + return err_status_ok; +} + +/* + * rdb_check checks to see if index appears in rdb + */ + +err_status_t +rdb_check(const rdb_t *rdb, uint32_t p_index) { + + /* if the index appears after (or at very end of) the window, its good */ + if (p_index >= rdb->window_start + rdb_bits_in_bitmask) + return err_status_ok; + + /* if the index appears before the window, its bad */ + if (p_index < rdb->window_start) + return err_status_replay_old; + + /* otherwise, the index appears within the window, so check the bitmask */ + if (v128_get_bit(&rdb->bitmask, (p_index - rdb->window_start)) == 1) + return err_status_replay_fail; + + /* otherwise, the index is okay */ + return err_status_ok; +} + +/* + * rdb_add_index adds index to rdb_t (and does *not* check if + * index appears in db) + * + * this function should be called only after rdb_check has + * indicated that the index does not appear in the rdb, e.g., a mutex + * should protect the rdb between these calls + */ + +err_status_t +rdb_add_index(rdb_t *rdb, uint32_t p_index) { + int delta; + + /* here we *assume* that p_index > rdb->window_start */ + + delta = (p_index - rdb->window_start); + if (delta < rdb_bits_in_bitmask) { + + /* if the p_index is within the window, set the appropriate bit */ + v128_set_bit(&rdb->bitmask, delta); + + } else { + + delta -= rdb_bits_in_bitmask - 1; + + /* shift the window forward by delta bits*/ + v128_left_shift(&rdb->bitmask, delta); + v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask-1); + rdb->window_start += delta; + + } + + return err_status_ok; +} + +err_status_t +rdb_increment(rdb_t *rdb) { + + if (rdb->window_start++ > 0x7fffffff) + return err_status_key_expired; + return err_status_ok; +} + +uint32_t +rdb_get_value(const rdb_t *rdb) { + return rdb->window_start; +} diff --git a/src/libs/srtp/crypto/replay/rdbx.c b/src/libs/srtp/crypto/replay/rdbx.c new file mode 100644 index 00000000..15d52b5f --- /dev/null +++ b/src/libs/srtp/crypto/replay/rdbx.c @@ -0,0 +1,352 @@ +/* + * rdbx.c + * + * a replay database with extended range, using a rollover counter + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "rdbx.h" + + +/* + * from RFC 3711: + * + * A receiver reconstructs the index i of a packet with sequence + * number SEQ using the estimate + * + * i = 2^16 * v + SEQ, + * + * where v is chosen from the set { ROC-1, ROC, ROC+1 } such that i is + * closest to the value 2^16 * ROC + s_l. If the value r+1 is used, + * then the rollover counter r in the cryptographic context is + * incremented by one (if the packet containing s is authentic). + */ + + + +/* + * rdbx implementation notes + * + * A xtd_seq_num_t is essentially a sequence number for which some of + * the data on the wire are implicit. It logically consists of a + * rollover counter and a sequence number; the sequence number is the + * explicit part, and the rollover counter is the implicit part. + * + * Upon receiving a sequence_number (e.g. in a newly received SRTP + * packet), the complete xtd_seq_num_t can be estimated by using a + * local xtd_seq_num_t as a basis. This is done using the function + * index_guess(&local, &guess, seq_from_packet). This function + * returns the difference of the guess and the local value. The local + * xtd_seq_num_t can be moved forward to the guess using the function + * index_advance(&guess, delta), where delta is the difference. + * + * + * A rdbx_t consists of a xtd_seq_num_t and a bitmask. The index is highest + * sequence number that has been received, and the bitmask indicates + * which of the recent indicies have been received as well. The + * highest bit in the bitmask corresponds to the index in the bitmask. + */ + + +void +index_init(xtd_seq_num_t *pi) { +#ifdef NO_64BIT_MATH + *pi = make64(0,0); +#else + *pi = 0; +#endif +} + +void +index_advance(xtd_seq_num_t *pi, sequence_number_t s) { +#ifdef NO_64BIT_MATH + /* a > ~b means a+b will generate a carry */ + /* s is uint16 here */ + *pi = make64(high32(*pi) + (s > ~low32(*pi) ? 1 : 0),low32(*pi) + s); +#else + *pi += s; +#endif +} + + +/* + * index_guess(local, guess, s) + * + * given a xtd_seq_num_t local (which represents the last + * known-to-be-good received xtd_seq_num_t) and a sequence number s + * (from a newly arrived packet), sets the contents of *guess to + * contain the best guess of the packet index to which s corresponds, + * and returns the difference between *guess and *local + * + * nota bene - the output is a signed integer, DON'T cast it to a + * unsigned integer! + */ + +int +index_guess(const xtd_seq_num_t *local, + xtd_seq_num_t *guess, + sequence_number_t s) { +#ifdef NO_64BIT_MATH + uint32_t local_roc = ((high32(*local) << 16) | + (low32(*local) >> 16)); + uint16_t local_seq = (uint16_t) (low32(*local)); +#else + uint32_t local_roc = (uint32_t)(*local >> 16); + uint16_t local_seq = (uint16_t) *local; +#endif +#ifdef NO_64BIT_MATH + uint32_t guess_roc = ((high32(*guess) << 16) | + (low32(*guess) >> 16)); + uint16_t guess_seq = (uint16_t) (low32(*guess)); +#else + uint32_t guess_roc = (uint32_t)(*guess >> 16); + uint16_t guess_seq = (uint16_t) *guess; +#endif + int difference; + + if (local_seq < seq_num_median) { + if (s - local_seq > seq_num_median) { + guess_roc = local_roc - 1; + difference = seq_num_max - s + local_seq; + } else { + guess_roc = local_roc; + difference = s - local_seq; + } + } else { + if (local_seq - seq_num_median > s) { + guess_roc = local_roc+1; + difference = seq_num_max - local_seq + s; + } else { + difference = s - local_seq; + guess_roc = local_roc; + } + } + guess_seq = s; + + /* Note: guess_roc is 32 bits, so this generates a 48-bit result! */ +#ifdef NO_64BIT_MATH + *guess = make64(guess_roc >> 16, + (guess_roc << 16) | guess_seq); +#else + *guess = (((uint64_t) guess_roc) << 16) | guess_seq; +#endif + + return difference; +} + +/* + * rdbx + * + */ + + +/* + * rdbx_init(&r, ws) initializes the rdbx_t pointed to by r with window size ws + */ + +err_status_t +rdbx_init(rdbx_t *rdbx, unsigned long ws) { + if (ws == 0) + return err_status_bad_param; + + if (bitvector_alloc(&rdbx->bitmask, ws) != 0) + return err_status_alloc_fail; + + index_init(&rdbx->index); + + return err_status_ok; +} + +/* + * rdbx_dealloc(&r) frees memory for the rdbx_t pointed to by r + */ + +err_status_t +rdbx_dealloc(rdbx_t *rdbx) { + bitvector_dealloc(&rdbx->bitmask); + + return err_status_ok; +} + +/* + * rdbx_set_roc(rdbx, roc) initalizes the rdbx_t at the location rdbx + * to have the rollover counter value roc. If that value is less than + * the current rollover counter value, then the function returns + * err_status_replay_old; otherwise, err_status_ok is returned. + * + */ + +err_status_t +rdbx_set_roc(rdbx_t *rdbx, uint32_t roc) { + bitvector_set_to_zero(&rdbx->bitmask); + +#ifdef NO_64BIT_MATH + #error not yet implemented +#else + + /* make sure that we're not moving backwards */ + if (roc < (rdbx->index >> 16)) + return err_status_replay_old; + + rdbx->index &= 0xffff; /* retain lowest 16 bits */ + rdbx->index |= ((uint64_t)roc) << 16; /* set ROC */ +#endif + + return err_status_ok; +} + +/* + * rdbx_get_packet_index(rdbx) returns the value of the packet index + * for the rdbx_t pointed to by rdbx + * + */ + +xtd_seq_num_t +rdbx_get_packet_index(const rdbx_t *rdbx) { + return rdbx->index; +} + +/* + * rdbx_get_window_size(rdbx) returns the value of the window size + * for the rdbx_t pointed to by rdbx + * + */ + +unsigned long +rdbx_get_window_size(const rdbx_t *rdbx) { + return bitvector_get_length(&rdbx->bitmask); +} + +/* + * rdbx_check(&r, delta) checks to see if the xtd_seq_num_t + * which is at rdbx->index + delta is in the rdb + */ + +err_status_t +rdbx_check(const rdbx_t *rdbx, int delta) { + + if (delta > 0) { /* if delta is positive, it's good */ + return err_status_ok; + } else if ((int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta < 0) { + /* if delta is lower than the bitmask, it's bad */ + return err_status_replay_old; + } else if (bitvector_get_bit(&rdbx->bitmask, + (int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta) == 1) { + /* delta is within the window, so check the bitmask */ + return err_status_replay_fail; + } + /* otherwise, the index is okay */ + + return err_status_ok; +} + +/* + * rdbx_add_index adds the xtd_seq_num_t at rdbx->window_start + d to + * replay_db (and does *not* check if that xtd_seq_num_t appears in db) + * + * this function should be called only after replay_check has + * indicated that the index does not appear in the rdbx, e.g., a mutex + * should protect the rdbx between these calls if need be + */ + +err_status_t +rdbx_add_index(rdbx_t *rdbx, int delta) { + + if (delta > 0) { + /* shift forward by delta */ + index_advance(&rdbx->index, delta); + bitvector_left_shift(&rdbx->bitmask, delta); + bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) - 1); + } else { + /* delta is in window */ + bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) -1 + delta); + } + + /* note that we need not consider the case that delta == 0 */ + + return err_status_ok; +} + + + +/* + * rdbx_estimate_index(rdbx, guess, s) + * + * given an rdbx and a sequence number s (from a newly arrived packet), + * sets the contents of *guess to contain the best guess of the packet + * index to which s corresponds, and returns the difference between + * *guess and the locally stored synch info + */ + +int +rdbx_estimate_index(const rdbx_t *rdbx, + xtd_seq_num_t *guess, + sequence_number_t s) { + + /* + * if the sequence number and rollover counter in the rdbx are + * non-zero, then use the index_guess(...) function, otherwise, just + * set the rollover counter to zero (since the index_guess(...) + * function might incorrectly guess that the rollover counter is + * 0xffffffff) + */ + +#ifdef NO_64BIT_MATH + /* seq_num_median = 0x8000 */ + if (high32(rdbx->index) > 0 || + low32(rdbx->index) > seq_num_median) +#else + if (rdbx->index > seq_num_median) +#endif + return index_guess(&rdbx->index, guess, s); + +#ifdef NO_64BIT_MATH + *guess = make64(0,(uint32_t) s); +#else + *guess = s; +#endif + +#ifdef NO_64BIT_MATH + return s - (uint16_t) low32(rdbx->index); +#else + return s - (uint16_t) rdbx->index; +#endif +} diff --git a/src/libs/srtp/crypto/replay/ut_sim.c b/src/libs/srtp/crypto/replay/ut_sim.c new file mode 100644 index 00000000..43c411e4 --- /dev/null +++ b/src/libs/srtp/crypto/replay/ut_sim.c @@ -0,0 +1,105 @@ +/* + * ut_sim.c + * + * an unreliable transport simulator + * (for testing replay databases and suchlike) + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "ut_sim.h" + + +int +ut_compar(const void *a, const void *b) { + return rand() > (RAND_MAX/2) ? -1 : 1; +} + +void +ut_init(ut_connection *utc) { + int i; + utc->index = 0; + + for (i=0; i < UT_BUF; i++) + utc->buffer[i] = i; + + qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar); + + utc->index = UT_BUF - 1; +} + +uint32_t +ut_next_index(ut_connection *utc) { + uint32_t tmp; + + tmp = utc->buffer[0]; + utc->index++; + utc->buffer[0] = utc->index; + + qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar); + + return tmp; +} + + + +#ifdef UT_TEST + +#include <stdio.h> + +int +main() { + uint32_t i, irecvd, idiff; + ut_connection utc; + + ut_init(&utc); + + for (i=0; i < 1000; i++) { + irecvd = ut_next_index(&utc); + idiff = i - irecvd; + printf("%lu\t%lu\t%d\n", i, irecvd, idiff); + } + + return 0; +} + + +#endif diff --git a/src/libs/srtp/crypto/rng/ctr_prng.c b/src/libs/srtp/crypto/rng/ctr_prng.c new file mode 100644 index 00000000..41d46a8f --- /dev/null +++ b/src/libs/srtp/crypto/rng/ctr_prng.c @@ -0,0 +1,108 @@ +/* + * ctr_prng.c + * + * counter mode based pseudorandom source + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "prng.h" + +/* single, global prng structure */ + +ctr_prng_t ctr_prng; + +err_status_t +ctr_prng_init(rand_source_func_t random_source) { + uint8_t tmp_key[32]; + err_status_t status; + + /* initialize output count to zero */ + ctr_prng.octet_count = 0; + + /* set random source */ + ctr_prng.rand = random_source; + + /* initialize secret key from random source */ + status = random_source(tmp_key, 32); + if (status) + return status; + + /* initialize aes ctr context with random key */ + status = aes_icm_context_init(&ctr_prng.state, tmp_key, 30); + if (status) + return status; + + return err_status_ok; +} + +err_status_t +ctr_prng_get_octet_string(void *dest, uint32_t len) { + err_status_t status; + + /* + * if we need to re-initialize the prng, do so now + * + * avoid 32-bit overflows by subtracting instead of adding + */ + if (ctr_prng.octet_count > MAX_PRNG_OUT_LEN - len) { + status = ctr_prng_init(ctr_prng.rand); + if (status) + return status; + } + ctr_prng.octet_count += len; + + /* + * write prng output + */ + status = aes_icm_output(&ctr_prng.state, (uint8_t*)dest, len); + if (status) + return status; + + return err_status_ok; +} + +err_status_t +ctr_prng_deinit(void) { + + /* nothing */ + + return err_status_ok; +} diff --git a/src/libs/srtp/crypto/rng/prng.c b/src/libs/srtp/crypto/rng/prng.c new file mode 100644 index 00000000..62b5e11d --- /dev/null +++ b/src/libs/srtp/crypto/rng/prng.c @@ -0,0 +1,180 @@ +/* + * prng.c + * + * pseudorandom source + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "prng.h" + +/* single, global prng structure */ + +x917_prng_t x917_prng; + +err_status_t +x917_prng_init(rand_source_func_t random_source) { + uint8_t tmp_key[16]; + err_status_t status; + + /* initialize output count to zero */ + x917_prng.octet_count = 0; + + /* set random source */ + x917_prng.rand = random_source; + + /* initialize secret key from random source */ + status = random_source(tmp_key, 16); + if (status) + return status; + + /* expand aes key */ + aes_expand_encryption_key(tmp_key, 16, &x917_prng.key); + + /* initialize prng state from random source */ + status = x917_prng.rand((uint8_t *)&x917_prng.state, 16); + if (status) + return status; + + return err_status_ok; +} + +err_status_t +x917_prng_get_octet_string(uint8_t *dest, uint32_t len) { + uint32_t t; + v128_t buffer; + uint32_t i, tail_len; + err_status_t status; + + /* + * if we need to re-initialize the prng, do so now + * + * avoid overflows by subtracting instead of adding + */ + if (x917_prng.octet_count > MAX_PRNG_OUT_LEN - len) { + status = x917_prng_init(x917_prng.rand); + if (status) + return status; + } + x917_prng.octet_count += len; + + /* find out the time */ + t = (uint32_t)time(NULL); + + /* loop until we have output enough data */ + for (i=0; i < len/16; i++) { + + /* exor time into state */ + x917_prng.state.v32[0] ^= t; + + /* copy state into buffer */ + v128_copy(&buffer, &x917_prng.state); + + /* apply aes to buffer */ + aes_encrypt(&buffer, &x917_prng.key); + + /* write data to output */ + *dest++ = buffer.v8[0]; + *dest++ = buffer.v8[1]; + *dest++ = buffer.v8[2]; + *dest++ = buffer.v8[3]; + *dest++ = buffer.v8[4]; + *dest++ = buffer.v8[5]; + *dest++ = buffer.v8[6]; + *dest++ = buffer.v8[7]; + *dest++ = buffer.v8[8]; + *dest++ = buffer.v8[9]; + *dest++ = buffer.v8[10]; + *dest++ = buffer.v8[11]; + *dest++ = buffer.v8[12]; + *dest++ = buffer.v8[13]; + *dest++ = buffer.v8[14]; + *dest++ = buffer.v8[15]; + + /* exor time into buffer */ + buffer.v32[0] ^= t; + + /* encrypt buffer */ + aes_encrypt(&buffer, &x917_prng.key); + + /* copy buffer into state */ + v128_copy(&x917_prng.state, &buffer); + + } + + /* if we need to output any more octets, we'll do so now */ + tail_len = len % 16; + if (tail_len) { + + /* exor time into state */ + x917_prng.state.v32[0] ^= t; + + /* copy value into buffer */ + v128_copy(&buffer, &x917_prng.state); + + /* apply aes to buffer */ + aes_encrypt(&buffer, &x917_prng.key); + + /* write data to output */ + for (i=0; i < tail_len; i++) { + *dest++ = buffer.v8[i]; + } + + /* now update the state one more time */ + + /* exor time into buffer */ + buffer.v32[0] ^= t; + + /* encrypt buffer */ + aes_encrypt(&buffer, &x917_prng.key); + + /* copy buffer into state */ + v128_copy(&x917_prng.state, &buffer); + + } + + return err_status_ok; +} + +err_status_t +x917_prng_deinit(void) { + + return err_status_ok; +} diff --git a/src/libs/srtp/crypto/rng/rand_linux_kernel.c b/src/libs/srtp/crypto/rng/rand_linux_kernel.c new file mode 100644 index 00000000..c51978e5 --- /dev/null +++ b/src/libs/srtp/crypto/rng/rand_linux_kernel.c @@ -0,0 +1,65 @@ +/* + * rand_linux_kernel.c + * + * implements a random source using Linux kernel functions + * + * Marcus Sundberg + * Ingate Systems AB + */ +/* + * + * Copyright(c) 2005 Ingate Systems AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the author(s) nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "config.h" +#include "rand_source.h" + + +err_status_t +rand_source_init(void) { + return err_status_ok; +} + +err_status_t +rand_source_get_octet_string(void *dest, uint32_t len) { + + get_random_bytes(dest, len); + + return err_status_ok; +} + +err_status_t +rand_source_deinit(void) { + return err_status_ok; +} diff --git a/src/libs/srtp/crypto/rng/rand_source.c b/src/libs/srtp/crypto/rng/rand_source.c new file mode 100644 index 00000000..a7f872e6 --- /dev/null +++ b/src/libs/srtp/crypto/rng/rand_source.c @@ -0,0 +1,158 @@ +/* + * rand_source.c + * + * implements a random source based on /dev/random + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "config.h" + +#ifdef DEV_URANDOM +# include <fcntl.h> /* for open() */ +# include <unistd.h> /* for close() */ +#elif defined(HAVE_RAND_S) +# define _CRT_RAND_S +# include <stdlib.h> +#else +# include <stdio.h> +#endif + +#include "rand_source.h" + + +/* + * global dev_rand_fdes is file descriptor for /dev/random + * + * This variable is also used to indicate that the random source has + * been initialized. When this variable is set to the value of the + * #define RAND_SOURCE_NOT_READY, it indicates that the random source + * is not ready to be used. The value of the #define + * RAND_SOURCE_READY is for use whenever that variable is used as an + * indicator of the state of the random source, but not as a file + * descriptor. + */ + +#define RAND_SOURCE_NOT_READY (-1) +#define RAND_SOURCE_READY (17) + +static int dev_random_fdes = RAND_SOURCE_NOT_READY; + + +err_status_t +rand_source_init(void) { + if (dev_random_fdes >= 0) { + /* already open */ + return err_status_ok; + } +#ifdef DEV_URANDOM + /* open random source for reading */ + dev_random_fdes = open(DEV_URANDOM, O_RDONLY); + if (dev_random_fdes < 0) + return err_status_init_fail; +#elif defined(HAVE_RAND_S) + dev_random_fdes = RAND_SOURCE_READY; +#else + /* no random source available; let the user know */ + //fprintf(stderr, "WARNING: no real random source present!\n"); + dev_random_fdes = RAND_SOURCE_READY; +#endif + return err_status_ok; +} + +err_status_t +rand_source_get_octet_string(void *dest, uint32_t len) { + + /* + * read len octets from /dev/random to dest, and + * check return value to make sure enough octets were + * written + */ +#ifdef DEV_URANDOM + uint8_t *dst = (uint8_t *)dest; + while (len) + { + ssize_t num_read = read(dev_random_fdes, dst, len); + if (num_read <= 0 || num_read > len) + return err_status_fail; + len -= num_read; + dst += num_read; + } +#elif defined(HAVE_RAND_S) + uint8_t *dst = (uint8_t *)dest; + while (len) + { + unsigned int val; + errno_t err = rand_s(&val); + + if (err != 0) + return err_status_fail; + + *dst++ = val & 0xff; + len--; + } +#else + /* Generic C-library (rand()) version */ + /* This is a random source of last resort */ + uint8_t *dst = (uint8_t *)dest; + while (len) + { + int val = rand(); + /* rand() returns 0-32767 (ugh) */ + /* Is this a good enough way to get random bytes? + It is if it passes FIPS-140... */ + *dst++ = val & 0xff; + len--; + } +#endif + return err_status_ok; +} + +err_status_t +rand_source_deinit(void) { + if (dev_random_fdes < 0) + return err_status_dealloc_fail; /* well, we haven't really failed, * + * but there is something wrong */ +#ifdef DEV_URANDOM + close(dev_random_fdes); +#endif + dev_random_fdes = RAND_SOURCE_NOT_READY; + + return err_status_ok; +} diff --git a/src/libs/srtp/crypto/test/aes_calc.c b/src/libs/srtp/crypto/test/aes_calc.c new file mode 100644 index 00000000..fe3c6ad0 --- /dev/null +++ b/src/libs/srtp/crypto/test/aes_calc.c @@ -0,0 +1,119 @@ +/* + * aes_calc.c + * + * A simple AES calculator for generating AES encryption values + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + + Example usage (with first NIST FIPS 197 test case): + +[sh]$ test/aes_calc 000102030405060708090a0b0c0d0e0f 00112233445566778899aabbccddeeff -v + plaintext: 00112233445566778899aabbccddeeff + key: 000102030405060708090a0b0c0d0e0f + ciphertext: 69c4e0d86a7b0430d8cdb78070b4c55a + + */ + +#include "aes.h" +#include <stdio.h> +#include <string.h> + +void +usage(char *prog_name) { + printf("usage: %s <key> <plaintext> [-v]\n", prog_name); + exit(255); +} + +#define AES_MAX_KEY_LEN 32 + +int +main (int argc, char *argv[]) { + v128_t data; + uint8_t key[AES_MAX_KEY_LEN]; + aes_expanded_key_t exp_key; + int key_len, len; + int verbose; + err_status_t status; + + if (argc == 3) { + /* we're not in verbose mode */ + verbose = 0; + } else if (argc == 4) { + if (strncmp(argv[3], "-v", 2) == 0) { + /* we're in verbose mode */ + verbose = 1; + } else { + /* unrecognized flag, complain and exit */ + usage(argv[0]); + } + } else { + /* we've been fed the wrong number of arguments - compain and exit */ + usage(argv[0]); + } + + /* read in key, checking length */ + if (strlen(argv[1]) > AES_MAX_KEY_LEN*2) { + fprintf(stderr, + "error: too many digits in key " + "(should be at most %d hexadecimal digits, found %u)\n", + AES_MAX_KEY_LEN*2, (unsigned)strlen(argv[1])); + exit(1); + } + len = hex_string_to_octet_string((char*)key, argv[1], AES_MAX_KEY_LEN*2); + /* check that hex string is the right length */ + if (len != 32 && len != 48 && len != 64) { + fprintf(stderr, + "error: bad number of digits in key " + "(should be 32/48/64 hexadecimal digits, found %d)\n", + len); + exit(1); + } + key_len = len/2; + + /* read in plaintext, checking length */ + if (strlen(argv[2]) > 16*2) { + fprintf(stderr, + "error: too many digits in plaintext " + "(should be %d hexadecimal digits, found %u)\n", + 16*2, (unsigned)strlen(argv[2])); + exit(1); + } + len = hex_string_to_octet_string((char *)(&data), argv[2], 16*2); + /* check that hex string is the right length */ + if (len < 16*2) { + fprintf(stderr, + "error: too few digits in plaintext " + "(should be %d hexadecimal digits, found %d)\n", + 16*2, len); + exit(1); + } + + if (verbose) { + /* print out plaintext */ + printf("plaintext:\t%s\n", octet_string_hex_string((uint8_t *)&data, 16)); + } + + /* encrypt plaintext */ + status = aes_expand_encryption_key(key, key_len, &exp_key); + if (status) { + fprintf(stderr, + "error: AES key expansion failed.\n"); + exit(1); + } + + aes_encrypt(&data, &exp_key); + + /* write ciphertext to output */ + if (verbose) { + printf("key:\t\t%s\n", octet_string_hex_string(key, key_len)); + printf("ciphertext:\t"); + } + printf("%s\n", v128_hex_string(&data)); + + return 0; +} + diff --git a/src/libs/srtp/crypto/test/auth_driver.c b/src/libs/srtp/crypto/test/auth_driver.c new file mode 100644 index 00000000..cd8a75dd --- /dev/null +++ b/src/libs/srtp/crypto/test/auth_driver.c @@ -0,0 +1,200 @@ +/* + * auth_driver.c + * + * a driver for auth functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include <stdio.h> /* for printf() */ +#include <stdlib.h> /* for xalloc() */ +#include <unistd.h> /* for getopt() */ + +#include "auth.h" +#include "null_auth.h" + +#define PRINT_DEBUG_DATA 0 + +extern auth_type_t tmmhv2; + +const uint16_t msg0[9] = { + 0x6015, 0xf141, 0x5ba1, 0x29a0, 0xf604, 0xd1c, 0x2d9, 0xaa8a, 0x7931 +}; + +/* key1 is for TAG_WORDS = 2 */ + +const uint16_t key1[47] = { + 0xe627, 0x6a01, 0x5ea7, 0xf27a, 0xc536, 0x2192, 0x11be, 0xea35, + 0xdb9d, 0x63d6, 0xfa8a, 0xfc45, 0xe08b, 0xd216, 0xced2, 0x7853, + 0x1a82, 0x22f5, 0x90fb, 0x1c29, 0x708e, 0xd06f, 0x82c3, 0xbee6, + 0x4f21, 0x6f33, 0x65c0, 0xd211, 0xc25e, 0x9138, 0x4fa3, 0x7c1f, + 0x61ac, 0x3489, 0x2976, 0x8c19, 0x8252, 0xddbf, 0xcad3, 0xc28f, + 0x68d6, 0x58dd, 0x504f, 0x2bbf, 0x0278, 0x70b7, 0xcfca +}; + +double +auth_bits_per_second(auth_t *h, int msg_len); + + +void +usage(char *prog_name) { + printf("usage: %s [ -t | -v ]\n", prog_name); + exit(255); +} + +#define MAX_MSG_LEN 2048 + +int +main (int argc, char *argv[]) { + auth_t *a = NULL; + err_status_t status; + int i; + int c; + unsigned do_timing_test = 0; + unsigned do_validation = 0; + + /* process input arguments */ + while (1) { + c = getopt(argc, argv, "tv"); + if (c == -1) + break; + switch (c) { + case 't': + do_timing_test = 1; + break; + case 'v': + do_validation = 1; + break; + default: + usage(argv[0]); + } + } + + printf("auth driver\nDavid A. McGrew\nCisco Systems, Inc.\n"); + + if (!do_validation && !do_timing_test) + usage(argv[0]); + + if (do_validation) { + printf("running self-test for %s...", tmmhv2.description); + status = tmmhv2_add_big_test(); + if (status) { + printf("tmmhv2_add_big_test failed with error code %d\n", status); + exit(status); + } + status = auth_type_self_test(&tmmhv2); + if (status) { + printf("failed with error code %d\n", status); + exit(status); + } + printf("passed\n"); + } + + if (do_timing_test) { + + /* tmmhv2 timing test */ + status = auth_type_alloc(&tmmhv2, &a, 94, 4); + if (status) { + fprintf(stderr, "can't allocate tmmhv2\n"); + exit(status); + } + status = auth_init(a, (uint8_t *)key1); + if (status) { + printf("error initializaing auth function\n"); + exit(status); + } + + printf("timing %s (tag length %d)\n", + tmmhv2.description, auth_get_tag_length(a)); + for (i=8; i <= MAX_MSG_LEN; i *= 2) + printf("msg len: %d\tgigabits per second: %f\n", + i, auth_bits_per_second(a, i) / 1E9); + + status = auth_dealloc(a); + if (status) { + printf("error deallocating auth function\n"); + exit(status); + } + + } + + return 0; +} + +#define NUM_TRIALS 100000 + +#include <time.h> + +double +auth_bits_per_second(auth_t *a, int msg_len_octets) { + int i; + clock_t timer; + uint8_t *result; + int msg_len = (msg_len_octets + 1)/2; + uint16_t *msg_string; + + /* create random message */ + msg_string = (uint16_t *) crypto_alloc(msg_len_octets); + if (msg_string == NULL) + return 0.0; /* indicate failure */ + for (i=0; i < msg_len; i++) + msg_string[i] = (uint16_t) random(); + + /* allocate temporary storage for authentication tag */ + result = crypto_alloc(auth_get_tag_length(a)); + if (result == NULL) { + free(msg_string); + return 0.0; /* indicate failure */ + } + + timer = clock(); + for (i=0; i < NUM_TRIALS; i++) { + auth_compute(a, (uint8_t *)msg_string, msg_len_octets, (uint8_t *)result); + } + timer = clock() - timer; + + free(msg_string); + free(result); + + return (double) NUM_TRIALS * 8 * msg_len_octets * CLOCKS_PER_SEC / timer; +} + + diff --git a/src/libs/srtp/crypto/test/cipher_driver.c b/src/libs/srtp/crypto/test/cipher_driver.c new file mode 100644 index 00000000..ea41ff5a --- /dev/null +++ b/src/libs/srtp/crypto/test/cipher_driver.c @@ -0,0 +1,531 @@ +/* + * cipher_driver.c + * + * A driver for the generic cipher type + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> /* for printf() */ +#include <stdlib.h> /* for rand() */ +#include <string.h> /* for memset() */ +#include <unistd.h> /* for getopt() */ +#include "cipher.h" +#include "aes_icm.h" +#include "null_cipher.h" + +#define PRINT_DEBUG 0 + +void +cipher_driver_test_throughput(cipher_t *c); + +err_status_t +cipher_driver_self_test(cipher_type_t *ct); + + +/* + * cipher_driver_test_buffering(ct) tests the cipher's output + * buffering for correctness by checking the consistency of succesive + * calls + */ + +err_status_t +cipher_driver_test_buffering(cipher_t *c); + + +/* + * functions for testing cipher cache thrash + */ +err_status_t +cipher_driver_test_array_throughput(cipher_type_t *ct, + int klen, int num_cipher); + +void +cipher_array_test_throughput(cipher_t *ca[], int num_cipher); + +uint64_t +cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, + unsigned octets_in_buffer, int num_trials); + +err_status_t +cipher_array_delete(cipher_t *cipher_array[], int num_cipher); + +err_status_t +cipher_array_alloc_init(cipher_t ***cipher_array, int num_ciphers, + cipher_type_t *ctype, int klen); + +void +usage(char *prog_name) { + printf("usage: %s [ -t | -v | -a ]\n", prog_name); + exit(255); +} + +void +check_status(err_status_t s) { + if (s) { + printf("error (code %d)\n", s); + exit(s); + } + return; +} + +/* + * null_cipher, aes_icm, and aes_cbc are the cipher meta-objects + * defined in the files in crypto/cipher subdirectory. these are + * declared external so that we can use these cipher types here + */ + +extern cipher_type_t null_cipher; +extern cipher_type_t aes_icm; +extern cipher_type_t aes_cbc; + +int +main(int argc, char *argv[]) { + cipher_t *c = NULL; + err_status_t status; + unsigned char test_key[48] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + }; + int q; + unsigned do_timing_test = 0; + unsigned do_validation = 0; + unsigned do_array_timing_test = 0; + + /* process input arguments */ + while (1) { + q = getopt(argc, argv, "tva"); + if (q == -1) + break; + switch (q) { + case 't': + do_timing_test = 1; + break; + case 'v': + do_validation = 1; + break; + case 'a': + do_array_timing_test = 1; + break; + default: + usage(argv[0]); + } + } + + printf("cipher test driver\n" + "David A. McGrew\n" + "Cisco Systems, Inc.\n"); + + if (!do_validation && !do_timing_test && !do_array_timing_test) + usage(argv[0]); + + /* arry timing (cache thrash) test */ + if (do_array_timing_test) { + int max_num_cipher = 1 << 16; /* number of ciphers in cipher_array */ + int num_cipher; + + for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) + cipher_driver_test_array_throughput(&null_cipher, 0, num_cipher); + + for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) + cipher_driver_test_array_throughput(&aes_icm, 30, num_cipher); + + for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) + cipher_driver_test_array_throughput(&aes_icm, 46, num_cipher); + + for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) + cipher_driver_test_array_throughput(&aes_cbc, 16, num_cipher); + + for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) + cipher_driver_test_array_throughput(&aes_cbc, 32, num_cipher); + } + + if (do_validation) { + cipher_driver_self_test(&null_cipher); + cipher_driver_self_test(&aes_icm); + cipher_driver_self_test(&aes_cbc); + } + + /* do timing and/or buffer_test on null_cipher */ + status = cipher_type_alloc(&null_cipher, &c, 0); + check_status(status); + + status = cipher_init(c, NULL, direction_encrypt); + check_status(status); + + if (do_timing_test) + cipher_driver_test_throughput(c); + if (do_validation) { + status = cipher_driver_test_buffering(c); + check_status(status); + } + status = cipher_dealloc(c); + check_status(status); + + + /* run the throughput test on the aes_icm cipher (128-bit key) */ + status = cipher_type_alloc(&aes_icm, &c, 30); + if (status) { + fprintf(stderr, "error: can't allocate cipher\n"); + exit(status); + } + + status = cipher_init(c, test_key, direction_encrypt); + check_status(status); + + if (do_timing_test) + cipher_driver_test_throughput(c); + + if (do_validation) { + status = cipher_driver_test_buffering(c); + check_status(status); + } + + status = cipher_dealloc(c); + check_status(status); + + /* repeat the tests with 256-bit keys */ + status = cipher_type_alloc(&aes_icm, &c, 46); + if (status) { + fprintf(stderr, "error: can't allocate cipher\n"); + exit(status); + } + + status = cipher_init(c, test_key, direction_encrypt); + check_status(status); + + if (do_timing_test) + cipher_driver_test_throughput(c); + + if (do_validation) { + status = cipher_driver_test_buffering(c); + check_status(status); + } + + status = cipher_dealloc(c); + check_status(status); + + return 0; +} + +void +cipher_driver_test_throughput(cipher_t *c) { + int i; + int min_enc_len = 32; + int max_enc_len = 2048; /* should be a power of two */ + int num_trials = 1000000; + + printf("timing %s throughput, key length %d:\n", c->type->description, c->key_len); + fflush(stdout); + for (i=min_enc_len; i <= max_enc_len; i = i * 2) + printf("msg len: %d\tgigabits per second: %f\n", + i, cipher_bits_per_second(c, i, num_trials) / 1e9); + +} + +err_status_t +cipher_driver_self_test(cipher_type_t *ct) { + err_status_t status; + + printf("running cipher self-test for %s...", ct->description); + status = cipher_type_self_test(ct); + if (status) { + printf("failed with error code %d\n", status); + exit(status); + } + printf("passed\n"); + + return err_status_ok; +} + +/* + * cipher_driver_test_buffering(ct) tests the cipher's output + * buffering for correctness by checking the consistency of succesive + * calls + */ + +err_status_t +cipher_driver_test_buffering(cipher_t *c) { + int i, j, num_trials = 1000; + unsigned len, buflen = 1024; + uint8_t buffer0[buflen], buffer1[buflen], *current, *end; + uint8_t idx[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34 + }; + err_status_t status; + + printf("testing output buffering for cipher %s...", + c->type->description); + + for (i=0; i < num_trials; i++) { + + /* set buffers to zero */ + for (j=0; j < buflen; j++) + buffer0[j] = buffer1[j] = 0; + + /* initialize cipher */ + status = cipher_set_iv(c, idx); + if (status) + return status; + + /* generate 'reference' value by encrypting all at once */ + status = cipher_encrypt(c, buffer0, &buflen); + if (status) + return status; + + /* re-initialize cipher */ + status = cipher_set_iv(c, idx); + if (status) + return status; + + /* now loop over short lengths until buffer1 is encrypted */ + current = buffer1; + end = buffer1 + buflen; + while (current < end) { + + /* choose a short length */ + len = rand() & 0x01f; + + /* make sure that len doesn't cause us to overreach the buffer */ + if (current + len > end) + len = end - current; + + status = cipher_encrypt(c, current, &len); + if (status) + return status; + + /* advance pointer into buffer1 to reflect encryption */ + current += len; + + /* if buffer1 is all encrypted, break out of loop */ + if (current == end) + break; + } + + /* compare buffers */ + for (j=0; j < buflen; j++) + if (buffer0[j] != buffer1[j]) { +#if PRINT_DEBUG + printf("test case %d failed at byte %d\n", i, j); + printf("computed: %s\n", octet_string_hex_string(buffer1, buflen)); + printf("expected: %s\n", octet_string_hex_string(buffer0, buflen)); +#endif + return err_status_algo_fail; + } + } + + printf("passed\n"); + + return err_status_ok; +} + + +/* + * The function cipher_test_throughput_array() tests the effect of CPU + * cache thrash on cipher throughput. + * + * cipher_array_alloc_init(ctype, array, num_ciphers) creates an array + * of cipher_t of type ctype + */ + +err_status_t +cipher_array_alloc_init(cipher_t ***ca, int num_ciphers, + cipher_type_t *ctype, int klen) { + int i, j; + err_status_t status; + uint8_t *key; + cipher_t **cipher_array; + /* pad klen allocation, to handle aes_icm reading 16 bytes for the + 14-byte salt */ + int klen_pad = ((klen + 15) >> 4) << 4; + + /* allocate array of pointers to ciphers */ + cipher_array = (cipher_t **) malloc(sizeof(cipher_t *) * num_ciphers); + if (cipher_array == NULL) + return err_status_alloc_fail; + + /* set ca to location of cipher_array */ + *ca = cipher_array; + + /* allocate key */ + key = crypto_alloc(klen_pad); + if (key == NULL) { + free(cipher_array); + return err_status_alloc_fail; + } + + /* allocate and initialize an array of ciphers */ + for (i=0; i < num_ciphers; i++) { + + /* allocate cipher */ + status = cipher_type_alloc(ctype, cipher_array, klen); + if (status) + return status; + + /* generate random key and initialize cipher */ + for (j=0; j < klen; j++) + key[j] = (uint8_t) rand(); + for (; j < klen_pad; j++) + key[j] = 0; + status = cipher_init(*cipher_array, key, direction_encrypt); + if (status) + return status; + +/* printf("%dth cipher is at %p\n", i, *cipher_array); */ +/* printf("%dth cipher description: %s\n", i, */ +/* (*cipher_array)->type->description); */ + + /* advance cipher array pointer */ + cipher_array++; + } + + crypto_free(key); + + return err_status_ok; +} + +err_status_t +cipher_array_delete(cipher_t *cipher_array[], int num_cipher) { + int i; + + for (i=0; i < num_cipher; i++) { + cipher_dealloc(cipher_array[i]); + } + + free(cipher_array); + + return err_status_ok; +} + + +/* + * cipher_array_bits_per_second(c, l, t) computes (an estimate of) the + * number of bits that a cipher implementation can encrypt in a second + * when distinct keys are used to encrypt distinct messages + * + * c is a cipher (which MUST be allocated an initialized already), l + * is the length in octets of the test data to be encrypted, and t is + * the number of trials + * + * if an error is encountered, the value 0 is returned + */ + +uint64_t +cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, + unsigned octets_in_buffer, int num_trials) { + int i; + v128_t nonce; + clock_t timer; + unsigned char *enc_buf; + int cipher_index = rand() % num_cipher; + + /* Over-alloc, for NIST CBC padding */ + enc_buf = crypto_alloc(octets_in_buffer+17); + if (enc_buf == NULL) + return 0; /* indicate bad parameters by returning null */ + memset(enc_buf, 0, octets_in_buffer); + + /* time repeated trials */ + v128_set_to_zero(&nonce); + timer = clock(); + for(i=0; i < num_trials; i++, nonce.v32[3] = i) { + /* length parameter to cipher_encrypt is in/out -- out is total, padded + * length -- so reset it each time. */ + unsigned octets_to_encrypt = octets_in_buffer; + + /* encrypt buffer with cipher */ + cipher_set_iv(cipher_array[cipher_index], &nonce); + cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_to_encrypt); + + /* choose a cipher at random from the array*/ + cipher_index = (*((uint32_t *)enc_buf)) % num_cipher; + } + timer = clock() - timer; + + free(enc_buf); + + if (timer == 0) { + /* Too fast! */ + return 0; + } + + return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer; +} + +void +cipher_array_test_throughput(cipher_t *ca[], int num_cipher) { + int i; + int min_enc_len = 16; + int max_enc_len = 2048; /* should be a power of two */ + int num_trials = 1000000; + + printf("timing %s throughput with key length %d, array size %d:\n", + (ca[0])->type->description, (ca[0])->key_len, num_cipher); + fflush(stdout); + for (i=min_enc_len; i <= max_enc_len; i = i * 4) + printf("msg len: %d\tgigabits per second: %f\n", i, + cipher_array_bits_per_second(ca, num_cipher, i, num_trials) / 1e9); + +} + +err_status_t +cipher_driver_test_array_throughput(cipher_type_t *ct, + int klen, int num_cipher) { + cipher_t **ca = NULL; + err_status_t status; + + status = cipher_array_alloc_init(&ca, num_cipher, ct, klen); + if (status) { + printf("error: cipher_array_alloc_init() failed with error code %d\n", + status); + return status; + } + + cipher_array_test_throughput(ca, num_cipher); + + cipher_array_delete(ca, num_cipher); + + return err_status_ok; +} diff --git a/src/libs/srtp/crypto/test/datatypes_driver.c b/src/libs/srtp/crypto/test/datatypes_driver.c new file mode 100644 index 00000000..f1866524 --- /dev/null +++ b/src/libs/srtp/crypto/test/datatypes_driver.c @@ -0,0 +1,237 @@ +/* + * datatypes_driver.c + * + * a test driver for crypto/math datatypes + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include <stdio.h> /* for printf() */ +#include <string.h> /* for strlen() */ +#include "datatypes.h" + +void +byte_order(void); + +void +test_hex_string_funcs(void); + +void +print_string(char *s); + +void +test_bswap(void); + +int +main (void) { + + /* + * this program includes various and sundry tests for fundamental + * datatypes. it's a grab-bag of throwaway code, retained only in + * case of future problems + */ + + int i, j; + v128_t x; + char *r = + "The Moving Finger writes; and, having writ,\n" + "Moves on: nor all thy Piety nor Wit\n" + "Shall lure it back to cancel half a Line,\n" + "Nor all thy Tears wash out a Word of it."; + char *s = "incomplet"; + + print_string(r); + print_string(s); + + byte_order(); + test_hex_string_funcs(); + + for (j=0; j < 128; j++) { + v128_set_to_zero(&x); + /* x.v32[0] = (1 << j); */ + v128_set_bit(&x, j); + printf("%s\n", v128_bit_string(&x)); + v128_clear_bit(&x, j); + printf("%s\n", v128_bit_string(&x)); + + } + + printf("----------------------------------------------\n"); + v128_set_to_zero(&x); + for (i=0; i < 128; i++) { + v128_set_bit(&x, i); + } + printf("%s\n", v128_bit_string(&x)); + + printf("----------------------------------------------\n"); + v128_set_to_zero(&x); + v128_set_bit(&x, 0); + for (i=0; i < 128; i++) { + printf("%s\n", v128_bit_string(&x)); + v128_right_shift(&x, 1); + } + printf("----------------------------------------------\n"); + v128_set_to_zero(&x); + v128_set_bit(&x, 127); + for (i=0; i < 128; i++) { + printf("%s\n", v128_bit_string(&x)); + v128_left_shift(&x, 1); + } + printf("----------------------------------------------\n"); + for (i=0; i < 128; i++) { + v128_set_to_zero(&x); + v128_set_bit(&x, 127); + v128_left_shift(&x, i); + printf("%s\n", v128_bit_string(&x)); + } + printf("----------------------------------------------\n"); + v128_set_to_zero(&x); + for (i=0; i < 128; i+=2) { + v128_set_bit(&x, i); + } + printf("bit_string: { %s }\n", v128_bit_string(&x)); + printf("get_bit: { "); + for (i=0; i < 128; i++) { + if (v128_get_bit(&x, i) == 1) + printf("1"); + else + printf("0"); + } + printf(" } \n"); + + test_bswap(); + + return 0; +} + + +/* byte_order() prints out byte ordering of datatypes */ + +void +byte_order(void) { + int i; + v128_t e; +#if 0 + v16_t b; + v32_t c; + v64_t d; + + for (i=0; i < sizeof(b); i++) + b.octet[i] = i; + for (i=0; i < sizeof(c); i++) + c.octet[i] = i; + for (i=0; i < sizeof(d); i++) + d.octet[i] = i; + + printf("v128_t:\t%s\n", v128_hex_string(&e)); + printf("v64_t:\t%s\n", v64_hex_string(&d)); + printf("v32_t:\t%s\n", v32_hex_string(c)); + printf("v16_t:\t%s\n", v16_hex_string(b)); + + c.value = 0x01020304; + printf("v32_t:\t%s\n", v32_hex_string(c)); + b.value = 0x0102; + printf("v16_t:\t%s\n", v16_hex_string(b)); + + printf("uint16_t ordering:\n"); + + c.value = 0x00010002; + printf("v32_t:\t%x%x\n", c.v16[0], c.v16[1]); +#endif + + printf("byte ordering of crypto/math datatypes:\n"); + for (i=0; i < sizeof(e); i++) + e.v8[i] = i; + printf("v128_t: %s\n", v128_hex_string(&e)); + +} + +void +test_hex_string_funcs(void) { + char hex1[] = "abadcafe"; + char hex2[] = "0123456789abcdefqqqqq"; + char raw[10]; + int len; + + len = hex_string_to_octet_string(raw, hex1, strlen(hex1)); + printf("computed length: %d\tstring: %s\n", len, + octet_string_hex_string(raw, len/2)); + printf("expected length: %u\tstring: %s\n", (unsigned)strlen(hex1), hex1); + + len = hex_string_to_octet_string(raw, hex2, strlen(hex2)); + printf("computed length: %d\tstring: %s\n", len, + octet_string_hex_string(raw, len/2)); + printf("expected length: %d\tstring: %s\n", 16, "0123456789abcdef"); + +} + +void +print_string(char *s) { + int i; + printf("%s\n", s); + printf("strlen(s) = %u\n", (unsigned)strlen(s)); + printf("{ "); + for (i=0; i < strlen(s); i++) { + printf("0x%x, ", s[i]); + if (((i+1) % 8) == 0) + printf("\n "); + } + printf("}\n"); +} + +void +test_bswap(void) { + uint32_t x = 0x11223344; + uint64_t y = 0x1122334455667788LL; + + printf("before: %0x\nafter: %0x\n", x, be32_to_cpu(x)); + printf("before: %0llx\nafter: %0llx\n", (unsigned long long)y, + (unsigned long long)be64_to_cpu(y)); + + y = 1234; + + printf("1234: %0llx\n", (unsigned long long)y); + printf("as octet string: %s\n", + octet_string_hex_string((uint8_t *) &y, 8)); + y = be64_to_cpu(y); + printf("bswapped octet string: %s\n", + octet_string_hex_string((uint8_t *) &y, 8)); +} diff --git a/src/libs/srtp/crypto/test/env.c b/src/libs/srtp/crypto/test/env.c new file mode 100644 index 00000000..37a6e273 --- /dev/null +++ b/src/libs/srtp/crypto/test/env.c @@ -0,0 +1,99 @@ +/* + * env.c + * + * prints out a brief report on the build environment + * + * David McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> +#include <string.h> /* for srtcmp() */ +#include "config.h" + +int +main(void) { + int err_count = 0; + char *str; + +#ifdef WORDS_BIGENDIAN + printf("CPU set to big-endian\t\t\t(WORDS_BIGENDIAN == 1)\n"); +#else + printf("CPU set to little-endian\t\t(WORDS_BIGENDIAN == 0)\n"); +#endif + +#ifdef CPU_RISC + printf("CPU set to RISC\t\t\t\t(CPU_RISC == 1)\n"); +#elif defined(CPU_CISC) + printf("CPU set to CISC\t\t\t\t(CPU_CISC == 1)\n"); +#else + printf("CPU set to an unknown type, probably due to a configuration error\n"); + err_count++; +#endif + +#ifdef CPU_ALTIVEC + printf("CPU set to ALTIVEC\t\t\t\t(CPU_ALTIVEC == 0)\n"); +#endif + +#ifndef NO_64BIT_MATH + printf("using native 64-bit type\t\t(NO_64_BIT_MATH == 0)\n"); +#else + printf("using built-in 64-bit math\t\t(NO_64_BIT_MATH == 1)\n"); +#endif + +#ifdef ERR_REPORTING_STDOUT + printf("using stdout for error reporting\t(ERR_REPORTING_STDOUT == 1)\n"); +#endif + +#ifdef DEV_URANDOM + str = DEV_URANDOM; +#else + str = ""; +#endif + printf("using %s as a random source\t(DEV_URANDOM == %s)\n", + str, str); + if (strcmp("", str) == 0) { + err_count++; + } + + if (err_count) + printf("warning: configuration is probably in error " + "(found %d problems)\n", err_count); + + return err_count; +} diff --git a/src/libs/srtp/crypto/test/kernel_driver.c b/src/libs/srtp/crypto/test/kernel_driver.c new file mode 100644 index 00000000..8ef8a5f4 --- /dev/null +++ b/src/libs/srtp/crypto/test/kernel_driver.c @@ -0,0 +1,126 @@ +/* + * kernel_driver.c + * + * a test driver for the crypto_kernel + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include <stdio.h> /* for printf() */ +#include <unistd.h> /* for getopt() */ +#include "crypto_kernel.h" + +void +usage(char *prog_name) { + printf("usage: %s [ -v ][ -d debug_module ]*\n", prog_name); + exit(255); +} + +int +main (int argc, char *argv[]) { + extern char *optarg; + int q; + int do_validation = 0; + err_status_t status; + + if (argc == 1) + usage(argv[0]); + + /* initialize kernel - we need to do this before anything else */ + status = crypto_kernel_init(); + if (status) { + printf("error: crypto_kernel init failed\n"); + exit(1); + } + printf("crypto_kernel successfully initalized\n"); + + /* process input arguments */ + while (1) { + q = getopt(argc, argv, "vd:"); + if (q == -1) + break; + switch (q) { + case 'v': + do_validation = 1; + break; + case 'd': + status = crypto_kernel_set_debug_module(optarg, 1); + if (status) { + printf("error: set debug module (%s) failed\n", optarg); + exit(1); + } + break; + default: + usage(argv[0]); + } + } + + if (do_validation) { + printf("checking crypto_kernel status...\n"); + status = crypto_kernel_status(); + if (status) { + printf("failed\n"); + exit(1); + } + printf("crypto_kernel passed self-tests\n"); + } + + status = crypto_kernel_shutdown(); + if (status) { + printf("error: crypto_kernel shutdown failed\n"); + exit(1); + } + printf("crypto_kernel successfully shut down\n"); + + return 0; +} + +/* + * crypto_kernel_cipher_test() is a test of the cipher interface + * of the crypto_kernel + */ + +err_status_t +crypto_kernel_cipher_test(void) { + + /* not implemented yet! */ + + return err_status_ok; +} diff --git a/src/libs/srtp/crypto/test/rand_gen.c b/src/libs/srtp/crypto/test/rand_gen.c new file mode 100644 index 00000000..ccea097f --- /dev/null +++ b/src/libs/srtp/crypto/test/rand_gen.c @@ -0,0 +1,140 @@ +/* + * rand_gen.c + * + * a random source (random number generator) + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include <stdio.h> /* for printf() */ +#include <unistd.h> /* for getopt() */ +#include "crypto_kernel.h" + +/* + * MAX_PRINT_STRING_LEN is defined in datatypes.h, and is the length + * of the largest hexadecimal string that can be generated by the + * function octet_string_hex_string(). + */ + +#define BUF_LEN (MAX_PRINT_STRING_LEN/2) + +void +usage(char *prog_name) { + printf("usage: %s -n <num_bytes> [-l][ -d debug_module ]*\n" + " -n <num> output <num> random bytes, where <num>" + " is between zero and %d\n" + " -l list the avaliable debug modules\n" + " -d <mod> turn on debugging module <mod>\n", + prog_name, BUF_LEN); + exit(255); +} + +int +main (int argc, char *argv[]) { + extern char *optarg; + int q; + int num_octets = 0; + unsigned do_list_mods = 0; + err_status_t status; + + if (argc == 1) + usage(argv[0]); + + /* initialize kernel - we need to do this before anything else */ + status = crypto_kernel_init(); + if (status) { + printf("error: crypto_kernel init failed\n"); + exit(1); + } + + /* process input arguments */ + while (1) { + q = getopt(argc, argv, "ld:n:"); + if (q == -1) + break; + switch (q) { + case 'd': + status = crypto_kernel_set_debug_module(optarg, 1); + if (status) { + printf("error: set debug module (%s) failed\n", optarg); + exit(1); + } + break; + case 'l': + do_list_mods = 1; + break; + case 'n': + num_octets = atoi(optarg); + if (num_octets < 0 || num_octets > BUF_LEN) + usage(argv[0]); + break; + default: + usage(argv[0]); + } + } + + if (do_list_mods) { + status = crypto_kernel_list_debug_modules(); + if (status) { + printf("error: list of debug modules failed\n"); + exit(1); + } + } + + if (num_octets > 0) { + uint8_t buffer[BUF_LEN]; + + status = crypto_get_random(buffer, num_octets); + if (status) { + printf("error: failure in random source\n"); + } else { + printf("%s\n", octet_string_hex_string(buffer, num_octets)); + } + } + + status = crypto_kernel_shutdown(); + if (status) { + printf("error: crypto_kernel shutdown failed\n"); + exit(1); + } + + return 0; +} + diff --git a/src/libs/srtp/crypto/test/sha1_driver.c b/src/libs/srtp/crypto/test/sha1_driver.c new file mode 100644 index 00000000..6036022e --- /dev/null +++ b/src/libs/srtp/crypto/test/sha1_driver.c @@ -0,0 +1,550 @@ +/* + * sha1_driver.c + * + * a test driver for SHA-1 + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> +#include "sha1.h" + +#define SHA_PASS 0 +#define SHA_FAIL 1 + +#define MAX_HASH_DATA_LEN 1024 +#define MAX_HASH_OUT_LEN 20 + +typedef struct hash_test_case_t { + unsigned data_len; /* number of octets in data */ + unsigned hash_len; /* number of octets output by hash */ + uint8_t data[MAX_HASH_DATA_LEN]; /* message data */ + uint8_t hash[MAX_HASH_OUT_LEN]; /* expected hash output */ + struct hash_test_case_t *next_test_case; +} hash_test_case_t; + +hash_test_case_t *sha1_test_case_list; + +err_status_t +hash_test_case_add(hash_test_case_t **list_ptr, + char *hex_data, + unsigned data_len, + char *hex_hash, + unsigned hash_len) { + hash_test_case_t *list_head = *list_ptr; + hash_test_case_t *test_case; + unsigned tmp_len; + + test_case = malloc(sizeof(hash_test_case_t)); + if (test_case == NULL) + return err_status_alloc_fail; + + tmp_len = hex_string_to_octet_string((char *)test_case->data, hex_data, data_len*2); + if (tmp_len != data_len*2) + return err_status_parse_err; + + tmp_len = hex_string_to_octet_string((char *)test_case->hash, hex_hash, hash_len*2); + if (tmp_len != hash_len*2) + return err_status_parse_err; + + test_case->data_len = data_len; + test_case->hash_len = hash_len; + + /* add the new test case to the head of the list */ + test_case->next_test_case = list_head; + *list_ptr = test_case; + + return err_status_ok; +} + +err_status_t +sha1_test_case_validate(const hash_test_case_t *test_case) { + sha1_ctx_t ctx; + uint32_t hash_value[5]; + + if (test_case == NULL) + return err_status_bad_param; + + if (test_case->hash_len != 20) + return err_status_bad_param; + if (test_case->data_len > MAX_HASH_DATA_LEN) + return err_status_bad_param; + + sha1_init(&ctx); + sha1_update(&ctx, test_case->data, test_case->data_len); + sha1_final(&ctx, hash_value); + if (0 == memcmp(test_case->hash, hash_value, 20)) { +#if VERBOSE + printf("PASSED: reference value: %s\n", + octet_string_hex_string((const uint8_t *)test_case->hash, 20)); + printf("PASSED: computed value: %s\n", + octet_string_hex_string((const uint8_t *)hash_value, 20)); +#endif + return err_status_ok; + } + + printf("reference value: %s\n", + octet_string_hex_string((const uint8_t *)test_case->hash, 20)); + printf("computed value: %s\n", + octet_string_hex_string((const uint8_t *)hash_value, 20)); + + return err_status_algo_fail; + +} + +struct hex_sha1_test_case_t { + unsigned bit_len; + char hex_data[MAX_HASH_DATA_LEN*2]; + char hex_hash[40]; +}; + +err_status_t +sha1_add_test_cases(void) { + int i; + err_status_t err; + + /* + * these test cases are taken from the "SHA-1 Sample Vectors" + * provided by NIST at http://csrc.nist.gov/cryptval/shs.html + */ + + struct hex_sha1_test_case_t tc[] = { + { + 0, + "", + "da39a3ee5e6b4b0d3255bfef95601890afd80709" + }, + { + 8, + "a8", + "99f2aa95e36f95c2acb0eaf23998f030638f3f15" + }, + { + 16, + "3000", + "f944dcd635f9801f7ac90a407fbc479964dec024" + }, + { + 24, + "42749e", + "a444319e9b6cc1e8464c511ec0969c37d6bb2619" + }, + { + 32, + "9fc3fe08", + "16a0ff84fcc156fd5d3ca3a744f20a232d172253" + }, + { + 40, + "b5c1c6f1af", + "fec9deebfcdedaf66dda525e1be43597a73a1f93" + }, + { + 48, + "e47571e5022e", + "8ce051181f0ed5e9d0c498f6bc4caf448d20deb5" + }, + { + 56, + "3e1b28839fb758", + "67da53837d89e03bf652ef09c369a3415937cfd3" + }, + { + 64, + "a81350cbb224cb90", + "305e4ff9888ad855a78573cddf4c5640cce7e946" + }, + { + 72, "c243d167923dec3ce1", + "5902b77b3265f023f9bbc396ba1a93fa3509bde7" + }, + { + 80, + "50ac18c59d6a37a29bf4", + "fcade5f5d156bf6f9af97bdfa9c19bccfb4ff6ab" + }, + { + 88, + "98e2b611ad3b1cccf634f6", + "1d20fbe00533c10e3cbd6b27088a5de0c632c4b5" + }, + { + 96, + "73fe9afb68e1e8712e5d4eec", + "7e1b7e0f7a8f3455a9c03e9580fd63ae205a2d93" + }, + { + 104, + "9e701ed7d412a9226a2a130e66", + "706f0677146307b20bb0e8d6311e329966884d13" + }, + { + 112, + "6d3ee90413b0a7cbf69e5e6144ca", + "a7241a703aaf0d53fe142f86bf2e849251fa8dff" + }, + { + 120, + "fae24d56514efcb530fd4802f5e71f", + "400f53546916d33ad01a5e6df66822dfbdc4e9e6" + }, + { + 128, + "c5a22dd6eda3fe2bdc4ddb3ce6b35fd1", + "fac8ab93c1ae6c16f0311872b984f729dc928ccd" + }, + { + 136, + "d98cded2adabf08fda356445c781802d95", + "fba6d750c18da58f6e2aab10112b9a5ef3301b3b" + }, + { + 144, + "bcc6d7087a84f00103ccb32e5f5487a751a2", + "29d27c2d44c205c8107f0351b05753ac708226b6" + }, + { + 152, + "36ecacb1055434190dbbc556c48bafcb0feb0d", + "b971bfc1ebd6f359e8d74cb7ecfe7f898d0ba845" + }, + { + 160, + "5ff9edb69e8f6bbd498eb4537580b7fba7ad31d0", + "96d08c430094b9fcc164ad2fb6f72d0a24268f68" + }, + { + 168, "c95b441d8270822a46a798fae5defcf7b26abace36", + "a287ea752a593d5209e287881a09c49fa3f0beb1" + }, + { + 176, + "83104c1d8a55b28f906f1b72cb53f68cbb097b44f860", + "a06c713779cbd88519ed4a585ac0cb8a5e9d612b" + }, + { + 184, + "755175528d55c39c56493d697b790f099a5ce741f7754b", + "bff7d52c13a3688132a1d407b1ab40f5b5ace298" + }, + { + 192, + "088fc38128bbdb9fd7d65228b3184b3faac6c8715f07272f", + "c7566b91d7b6f56bdfcaa9781a7b6841aacb17e9" + }, + { + 200, + "a4a586eb9245a6c87e3adf1009ac8a49f46c07e14185016895", + "ffa30c0b5c550ea4b1e34f8a60ec9295a1e06ac1" + }, + { + 208, + "8e7c555270c006092c2a3189e2a526b873e2e269f0fb28245256", + "29e66ed23e914351e872aa761df6e4f1a07f4b81" + }, + { + 216, + "a5f3bfa6bb0ba3b59f6b9cbdef8a558ec565e8aa3121f405e7f2f0", + "b28cf5e5b806a01491d41f69bd9248765c5dc292" + }, + { + 224, + "589054f0d2bd3c2c85b466bfd8ce18e6ec3e0b87d944cd093ba36469", + "60224fb72c46069652cd78bcd08029ef64da62f3" + }, + { + 232, + "a0abb12083b5bbc78128601bf1cbdbc0fdf4b862b24d899953d8da0ff3", + "b72c4a86f72608f24c05f3b9088ef92fba431df7" + }, + { + 240, + "82143f4cea6fadbf998e128a8811dc75301cf1db4f079501ea568da68eeb", + "73779ad5d6b71b9b8328ef7220ff12eb167076ac" + }, + { + 248, + "9f1231dd6df1ff7bc0b0d4f989d048672683ce35d956d2f57913046267e6f3", + "a09671d4452d7cf50015c914a1e31973d20cc1a0" + }, + { + 256, + "041c512b5eed791f80d3282f3a28df263bb1df95e1239a7650e5670fc2187919", + "e88cdcd233d99184a6fd260b8fca1b7f7687aee0" + }, + { + 264, + "17e81f6ae8c2e5579d69dafa6e070e7111461552d314b691e7a3e7a4feb3fae418", + "010def22850deb1168d525e8c84c28116cb8a269" + }, + { + 272, + "d15976b23a1d712ad28fad04d805f572026b54dd64961fda94d5355a0cc98620cf77", + "aeaa40ba1717ed5439b1e6ea901b294ba500f9ad" + }, + { + 280, + "09fce4d434f6bd32a44e04b848ff50ec9f642a8a85b37a264dc73f130f22838443328f", + "c6433791238795e34f080a5f1f1723f065463ca0" + }, + { + 288, "f17af27d776ec82a257d8d46d2b46b639462c56984cc1be9c1222eadb8b26594a25c709d", + "e21e22b89c1bb944a32932e6b2a2f20d491982c3" + }, + { + 296, + "b13ce635d6f8758143ffb114f2f601cb20b6276951416a2f94fbf4ad081779d79f4f195b22", + "575323a9661f5d28387964d2ba6ab92c17d05a8a" + }, + { + 304, + "5498793f60916ff1c918dde572cdea76da8629ba4ead6d065de3dfb48de94d234cc1c5002910", + "feb44494af72f245bfe68e86c4d7986d57c11db7" + }, + { + 312, + "498a1e0b39fa49582ae688cd715c86fbaf8a81b8b11b4d1594c49c902d197c8ba8a621fd6e3be5", + "cff2290b3648ba2831b98dde436a72f9ebf51eee" + }, + { + 320, + "3a36ae71521f9af628b3e34dcb0d4513f84c78ee49f10416a98857150b8b15cb5c83afb4b570376e", + "9b4efe9d27b965905b0c3dab67b8d7c9ebacd56c" + }, + { + 328, + "dcc76b40ae0ea3ba253e92ac50fcde791662c5b6c948538cffc2d95e9de99cac34dfca38910db2678f", + "afedb0ff156205bcd831cbdbda43db8b0588c113" + }, + { + 336, + "5b5ec6ec4fd3ad9c4906f65c747fd4233c11a1736b6b228b92e90cddabb0c7c2fcf9716d3fad261dff33", + "8deb1e858f88293a5e5e4d521a34b2a4efa70fc4" + }, + { + 344, + "df48a37b29b1d6de4e94717d60cdb4293fcf170bba388bddf7a9035a15d433f20fd697c3e4c8b8c5f590ab", + "95cbdac0f74afa69cebd0e5c7defbc6faf0cbeaf" + }, + { + 352, + "1f179b3b82250a65e1b0aee949e218e2f45c7a8dbfd6ba08de05c55acfc226b48c68d7f7057e5675cd96fcfc", + "f0307bcb92842e5ae0cd4f4f14f3df7f877fbef2" + }, + { + 360, + "ee3d72da3a44d971578972a8e6780ce64941267e0f7d0179b214fa97855e1790e888e09fbe3a70412176cb3b54", + "7b13bb0dbf14964bd63b133ac85e22100542ef55" + }, + { + 368, + "d4d4c7843d312b30f610b3682254c8be96d5f6684503f8fbfbcd15774fc1b084d3741afb8d24aaa8ab9c104f7258", + "c314d2b6cf439be678d2a74e890d96cfac1c02ed" + }, + { + 376, + "32c094944f5936a190a0877fb9178a7bf60ceae36fd530671c5b38c5dbd5e6a6c0d615c2ac8ad04b213cc589541cf6", + "4d0be361e410b47a9d67d8ce0bb6a8e01c53c078" + }, + { + 384, + "e5d3180c14bf27a5409fa12b104a8fd7e9639609bfde6ee82bbf9648be2546d29688a65e2e3f3da47a45ac14343c9c02", + "e5353431ffae097f675cbf498869f6fbb6e1c9f2" + }, + { + 392, + "e7b6e4b69f724327e41e1188a37f4fe38b1dba19cbf5a7311d6e32f1038e97ab506ee05aebebc1eed09fc0e357109818b9", + "b8720a7068a085c018ab18961de2765aa6cd9ac4" + }, + { + 400, + "bc880cb83b8ac68ef2fedc2da95e7677ce2aa18b0e2d8b322701f67af7d5e7a0d96e9e33326ccb7747cfff0852b961bfd475", + "b0732181568543ba85f2b6da602b4b065d9931aa" + }, + { + 408, + "235ea9c2ba7af25400f2e98a47a291b0bccdaad63faa2475721fda5510cc7dad814bce8dabb611790a6abe56030b798b75c944", + "9c22674cf3222c3ba921672694aafee4ce67b96b" + }, + { + 416, + "07e3e29fed63104b8410f323b975fd9fba53f636af8c4e68a53fb202ca35dd9ee07cb169ec5186292e44c27e5696a967f5e67709", + "d128335f4cecca9066cdae08958ce656ff0b4cfc" + }, + { + 424, + "65d2a1dd60a517eb27bfbf530cf6a5458f9d5f4730058bd9814379547f34241822bf67e6335a6d8b5ed06abf8841884c636a25733f", + "0b67c57ac578de88a2ae055caeaec8bb9b0085a0" + }, + { + 432, + "dcc86b3bd461615bab739d8daafac231c0f462e819ad29f9f14058f3ab5b75941d4241ea2f17ebb8a458831b37a9b16dead4a76a9b0e", + "c766f912a89d4ccda88e0cce6a713ef5f178b596" + }, + { + 440, + "4627d54f0568dc126b62a8c35fb46a9ac5024400f2995e51635636e1afc4373dbb848eb32df23914230560b82477e9c3572647a7f2bb92", + "9aa3925a9dcb177b15ccff9b78e70cf344858779" + }, + { + 448, + "ba531affd4381168ef24d8b275a84d9254c7f5cc55fded53aa8024b2c5c5c8aa7146fe1d1b83d62b70467e9a2e2cb67b3361830adbab28d7", + "4811fa30042fc076acf37c8e2274d025307e5943" + }, + { + 456, + "8764dcbcf89dcf4282eb644e3d568bdccb4b13508bfa7bfe0ffc05efd1390be22109969262992d377691eb4f77f3d59ea8466a74abf57b2ef4", + "6743018450c9730761ee2b130df9b91c1e118150" + }, + { + 464, + "497d9df9ddb554f3d17870b1a31986c1be277bc44feff713544217a9f579623d18b5ffae306c25a45521d2759a72c0459b58957255ab592f3be4", + "71ad4a19d37d92a5e6ef3694ddbeb5aa61ada645" + }, + { + 472, + "72c3c2e065aefa8d9f7a65229e818176eef05da83f835107ba90ec2e95472e73e538f783b416c04654ba8909f26a12db6e5c4e376b7615e4a25819", + "a7d9dc68dacefb7d6116186048cb355cc548e11d" + }, + { + 480, + "7cc9894454d0055ab5069a33984e2f712bef7e3124960d33559f5f3b81906bb66fe64da13c153ca7f5cabc89667314c32c01036d12ecaf5f9a78de98", + "142e429f0522ba5abf5131fa81df82d355b96909" + }, + { + 488, + "74e8404d5a453c5f4d306f2cfa338ca65501c840ddab3fb82117933483afd6913c56aaf8a0a0a6b2a342fc3d9dc7599f4a850dfa15d06c61966d74ea59", + "ef72db70dcbcab991e9637976c6faf00d22caae9" + }, + { + 496, + "46fe5ed326c8fe376fcc92dc9e2714e2240d3253b105adfbb256ff7a19bc40975c604ad7c0071c4fd78a7cb64786e1bece548fa4833c04065fe593f6fb10", + "f220a7457f4588d639dc21407c942e9843f8e26b" + }, + { + 504, + "836dfa2524d621cf07c3d2908835de859e549d35030433c796b81272fd8bc0348e8ddbc7705a5ad1fdf2155b6bc48884ac0cd376925f069a37849c089c8645", + "ddd2117b6e309c233ede85f962a0c2fc215e5c69" + }, + { + 512, + "7e3a4c325cb9c52b88387f93d01ae86d42098f5efa7f9457388b5e74b6d28b2438d42d8b64703324d4aa25ab6aad153ae30cd2b2af4d5e5c00a8a2d0220c6116", + "a3054427cdb13f164a610b348702724c808a0dcc" + } + }; + + + for (i=0; i < 65; i++) { + err = hash_test_case_add(&sha1_test_case_list, + tc[i].hex_data, + tc[i].bit_len/8, + tc[i].hex_hash, 20); + if (err) { + printf("error adding hash test case (code %d)\n", err); + return err; + } + } + + return err_status_ok; +} + +err_status_t +sha1_dealloc_test_cases(void) { + hash_test_case_t *t, *next; + + for (t = sha1_test_case_list; t != NULL; t = next) { + next = t->next_test_case; + free(t); + } + + sha1_test_case_list = NULL; + + return err_status_ok; +} + + + +err_status_t +sha1_validate(void) { + hash_test_case_t *test_case; + err_status_t err; + + err = sha1_add_test_cases(); + if (err) { + printf("error adding SHA1 test cases (error code %d)\n", err); + return err; + } + + if (sha1_test_case_list == NULL) + return err_status_cant_check; + + test_case = sha1_test_case_list; + while (test_case != NULL) { + err = sha1_test_case_validate(test_case); + if (err) { + printf("error validating hash test case (error code %d)\n", err); + return err; + } + test_case = test_case->next_test_case; + } + + sha1_dealloc_test_cases(); + + return err_status_ok; +} + + + +int +main (void) { + err_status_t err; + + printf("sha1 test driver\n"); + + err = sha1_validate(); + if (err) { + printf("SHA1 did not pass validation testing\n"); + return 1; + } + printf("SHA1 passed validation tests\n"); + + return 0; + +} diff --git a/src/libs/srtp/crypto/test/stat_driver.c b/src/libs/srtp/crypto/test/stat_driver.c new file mode 100644 index 00000000..f9d75b76 --- /dev/null +++ b/src/libs/srtp/crypto/test/stat_driver.c @@ -0,0 +1,139 @@ +/* + * stat-driver.c + * + * test driver for the stat_test functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ + + +#include <stdio.h> /* for printf() */ + +#include "err.h" +#include "stat.h" + +#include "cipher.h" + +typedef struct { + void *state; +} random_source_t; + +err_status_t +random_source_alloc(void); + +void +err_check(err_status_t s) { + if (s) { + printf("error (code %d)\n", s); + exit(1); + } +} + +int +main (int argc, char *argv[]) { + uint8_t buffer[2500]; + unsigned int buf_len = 2500; + int i, j; + extern cipher_type_t aes_icm; + cipher_t *c; + uint8_t key[46] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 + }; + v128_t nonce; + int num_trials = 500; + int num_fail; + + printf("statistical tests driver\n"); + + for (i=0; i < 2500; i++) + buffer[i] = 0; + + /* run tests */ + printf("running stat_tests on all-null buffer, expecting failure\n"); + printf("monobit %d\n", stat_test_monobit(buffer)); + printf("poker %d\n", stat_test_poker(buffer)); + printf("runs %d\n", stat_test_runs(buffer)); + + for (i=0; i < 2500; i++) + buffer[i] = rand(); + printf("running stat_tests on rand(), expecting success\n"); + printf("monobit %d\n", stat_test_monobit(buffer)); + printf("poker %d\n", stat_test_poker(buffer)); + printf("runs %d\n", stat_test_runs(buffer)); + + printf("running stat_tests on AES-128-ICM, expecting success\n"); + /* set buffer to cipher output */ + for (i=0; i < 2500; i++) + buffer[i] = 0; + err_check(cipher_type_alloc(&aes_icm, &c, 30)); + err_check(cipher_init(c, key, direction_encrypt)); + err_check(cipher_set_iv(c, &nonce)); + err_check(cipher_encrypt(c, buffer, &buf_len)); + /* run tests on cipher outout */ + printf("monobit %d\n", stat_test_monobit(buffer)); + printf("poker %d\n", stat_test_poker(buffer)); + printf("runs %d\n", stat_test_runs(buffer)); + + printf("runs test (please be patient): "); + fflush(stdout); + num_fail = 0; + v128_set_to_zero(&nonce); + for(j=0; j < num_trials; j++) { + for (i=0; i < 2500; i++) + buffer[i] = 0; + nonce.v32[3] = i; + err_check(cipher_set_iv(c, &nonce)); + err_check(cipher_encrypt(c, buffer, &buf_len)); + if (stat_test_runs(buffer)) { + num_fail++; + } + } + + printf("%d failures in %d tests\n", num_fail, num_trials); + printf("(nota bene: a small fraction of stat_test failures does not \n" + "indicate that the random source is invalid)\n"); + + err_check(cipher_dealloc(c)); + + printf("running stat_tests on AES-256-ICM, expecting success\n"); + /* set buffer to cipher output */ + for (i=0; i < 2500; i++) + buffer[i] = 0; + err_check(cipher_type_alloc(&aes_icm, &c, 46)); + err_check(cipher_init(c, key, direction_encrypt)); + err_check(cipher_set_iv(c, &nonce)); + err_check(cipher_encrypt(c, buffer, &buf_len)); + /* run tests on cipher outout */ + printf("monobit %d\n", stat_test_monobit(buffer)); + printf("poker %d\n", stat_test_poker(buffer)); + printf("runs %d\n", stat_test_runs(buffer)); + + printf("runs test (please be patient): "); + fflush(stdout); + num_fail = 0; + v128_set_to_zero(&nonce); + for(j=0; j < num_trials; j++) { + for (i=0; i < 2500; i++) + buffer[i] = 0; + nonce.v32[3] = i; + err_check(cipher_set_iv(c, &nonce)); + err_check(cipher_encrypt(c, buffer, &buf_len)); + if (stat_test_runs(buffer)) { + num_fail++; + } + } + + printf("%d failures in %d tests\n", num_fail, num_trials); + printf("(nota bene: a small fraction of stat_test failures does not \n" + "indicate that the random source is invalid)\n"); + + err_check(cipher_dealloc(c)); + + return 0; +} diff --git a/src/libs/srtp/doc/Doxyfile b/src/libs/srtp/doc/Doxyfile new file mode 100644 index 00000000..c6e6a6d2 --- /dev/null +++ b/src/libs/srtp/doc/Doxyfile @@ -0,0 +1,1042 @@ +# Doxyfile 1.3-rc3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = libSRTP + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.3.22 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = NO + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show +# all inherited members of a class in the documentation of that class +# as if those members were ordinary class members. Constructors, +# destructors and assignment operators of the base classes will not be +# shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are adviced to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 3 + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consist of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = intro.txt ../include/srtp.h ../crypto/include/crypto_types.h ../crypto/include/err.h ../crypto/include/crypto.h crypto_kernel.txt + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = NO + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output dir. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non empty doxygen will try to run +# the html help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the Html help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = letter + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = header.tex + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_XML = NO + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superceded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yield more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermedate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = /usr/local/bin/ + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/src/libs/srtp/doc/Makefile b/src/libs/srtp/doc/Makefile new file mode 100644 index 00000000..d4c0845e --- /dev/null +++ b/src/libs/srtp/doc/Makefile @@ -0,0 +1,44 @@ +# Makefile for libSRTP documentation +# +# David A. McGrew +# Cisco Systems, Inc. +# +# This makefile does not use the autoconf system; we don't really need +# it. We just run doxygen then latex. If you don't have either of +# these, then there is no way that you can make your own +# documentation. Of course, you can just go online at pick up the +# documentation from http://srtp.sourceforge.net. + +srcdir = . +top_srcdir = .. +top_builddir = ../ + + +# Determine the version of the library + +version = $(shell cat $(top_srcdir)/VERSION) + + +.PHONY: libsrtpdoc cryptodoc clean +libsrtpdoc: + @if test ! -e Doxyfile; then \ + echo "*** Sorry, can't build doc outside source dir"; exit 1; \ + fi + sed 's/LIBSRTPVERSION/$(version)/' header.template > header.tex + doxygen + sed 's/\subsection/\section/' latex/index.tex > latex/index.tmp + mv latex/index.tmp latex/index.tex + cd latex; make + cp latex/refman.pdf libsrtp.pdf + + +cryptodoc: clean + doxygen crypto.dox + cd latex; make + cp latex/refman.pdf crypto.pdf + +clean: + rm -rf latex/ header.tex + for a in * ; do \ + if [ -f "$$a~" ] ; then rm -f $$a~; fi; \ + done; diff --git a/src/libs/srtp/doc/Makefile.in b/src/libs/srtp/doc/Makefile.in new file mode 100644 index 00000000..5b4b6bd1 --- /dev/null +++ b/src/libs/srtp/doc/Makefile.in @@ -0,0 +1,44 @@ +# Makefile for libSRTP documentation +# +# David A. McGrew +# Cisco Systems, Inc. +# +# This makefile does not use the autoconf system; we don't really need +# it. We just run doxygen then latex. If you don't have either of +# these, then there is no way that you can make your own +# documentation. Of course, you can just go online at pick up the +# documentation from http://srtp.sourceforge.net. + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ +VPATH = @srcdir@ + +# Determine the version of the library + +version = $(shell cat $(top_srcdir)/VERSION) + + +.PHONY: libsrtpdoc cryptodoc clean +libsrtpdoc: + @if test ! -e Doxyfile; then \ + echo "*** Sorry, can't build doc outside source dir"; exit 1; \ + fi + sed 's/LIBSRTPVERSION/$(version)/' header.template > header.tex + doxygen + sed 's/\subsection/\section/' latex/index.tex > latex/index.tmp + mv latex/index.tmp latex/index.tex + cd latex; make + cp latex/refman.pdf libsrtp.pdf + + +cryptodoc: clean + doxygen crypto.dox + cd latex; make + cp latex/refman.pdf crypto.pdf + +clean: + rm -rf latex/ header.tex + for a in * ; do \ + if [ -f "$$a~" ] ; then rm -f $$a~; fi; \ + done; diff --git a/src/libs/srtp/doc/crypto_kernel.txt b/src/libs/srtp/doc/crypto_kernel.txt new file mode 100644 index 00000000..b0d033ff --- /dev/null +++ b/src/libs/srtp/doc/crypto_kernel.txt @@ -0,0 +1,76 @@ +/** + +@defgroup CryptoKernel Cryptographic Kernel + +All of the cryptographic functions are contained in a kernel. + +*/ + +/** + +@defgroup CipherImplementations Ciphers +@ingroup CryptoKernel + +@brief A generic cipher type enables cipher agility, that is, the +ability to write code that runs with multiple cipher types. +Ciphers can be used through the crypto kernel, or can be accessed +directly, if need be. + +@{ + +*/ + +/** + * @brief Allocates a cipher of a particular type. + * @warning May be implemented as a macro. + */ +err_status_t +cipher_type_alloc(cipher_type_t *ctype, cipher_t **cipher, + unsigned key_len); + +/** + * @brief Initialized a cipher to use a particular key. May + * be invoked more than once on the same cipher. + * @warning May be implemented as a macro. + */ + +err_status_t +cipher_init(cipher_t *cipher, const uint8_t *key); + +/** + * @brief Sets the initialization vector of a given cipher. + * @warning May be implemented as a macro. + */ + +err_status_t +cipher_set_iv(cipher_t *cipher, void *iv); + +/** + * @brief Encrypts a buffer with a given cipher. + * @warning May be implemented as a macro. + */ + +err_status_t +cipher_encrypt(cipher_t *cipher, void *buf, unsigned int *len); + +/** + * @brief Sets a buffer to the keystream generated by the cipher. + * @warning May be implemented as a macro. + */ +err_status_t +cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output); + +/** + * @brief Deallocates a cipher. + * @warning May be implemented as a macro. + */ +err_status_t +cipher_dealloc(cipher_t *cipher); + + + +/** + * @} + */ + + */ \ No newline at end of file diff --git a/src/libs/srtp/doc/draft-irtf-cfrg-icm-00.txt b/src/libs/srtp/doc/draft-irtf-cfrg-icm-00.txt new file mode 100644 index 00000000..ddfce338 --- /dev/null +++ b/src/libs/srtp/doc/draft-irtf-cfrg-icm-00.txt @@ -0,0 +1 @@ + Crypto Forum Research Group David A. McGrew Internet Draft Cisco Systems, Inc. Expires April, 2003 October, 2002 Integer Counter Mode <draft-irtf-cfrg-icm-00.txt> Status of this Memo This document is an Internet Draft and is in full conformance with all provisions of Section 10 of RFC-2026. Internet Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and working groups. Note that other groups may also distribute working documents as Internet Drafts. Internet Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet Drafts as reference material or to cite them other than as "work in progress." The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html. 1. Abstract This document specifies Integer Counter Mode (ICM), a mode of operation of a block cipher which defines an indexed keystream generator (which generates a keystream segment given an index). This mode is efficient, parallelizable, and has been proven secure given realistic assumptions about the block cipher. Test vectors are provided for AES. Counter Mode admits many variations. The variant specified in this document is secure and flexible, yet it enables a single implementation of a keystream generator to suffice in different application domains. McGrew [Page 1] Internet Draft Integer Counter Mode October, 2002 2. Notational Conventions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC-2119 [B97]. 3. Introduction Counter Mode is a way to define a pseudorandom keystream generator using a block cipher [CTR]. The keystream can be used for additive encryption, key derivation, or any other application requiring pseudorandom data. In ICM, the keystream is logically broken into segments. Each segment is identified with a segment index, and the segments have equal lengths. This segmentation makes ICM especially appropriate for securing packet-based protocols. 4. ICM In this section, ICM keystream generation and encryption are defined. 4.1. ICM Parameters The following parameters are used in ICM. These parameters MUST remain fixed for any given use of a key. Parameter Meaning ----------------------------------------------------------------- BLOCK_LENGTH the number of octets in the cipher block KEY_LENGTH the number of octets in the cipher key OFFSET_LENGTH the number of octets in the offset SEGMENT_INDEX_LENGTH the number of octets in the segment index BLOCK_INDEX_LENGTH the number of octets in the block index 4.2. Keystream Segments Conceptually, ICM is a keystream generator that takes a secret key and a segment index as an input and then outputs a keystream segment. The segmentation lends itself to packet encryption, as each keystream segment can be used to encrypt a distinct packet. A counter is a value containing BLOCK_LENGTH octets which is McGrew [Page 2] Internet Draft Integer Counter Mode October, 2002 incremented using an increment function based on integer addition, to produce a sequence of distinct values which are used as inputs to the block cipher. (In the context of this specification, an integer is an octet string, the most significant of which is the first.) The output blocks of the cipher are concatenated to form the keystream segment. The first octet of the segment is the first octet of the first output block, and so on. A schematic of this process is shown in Figure 1. Figure 1. The generation of a keystream segment given a segment index and a block cipher key K. Here C[i] and S[i] denote the ith counter and keystream block, respectively. segment index | v C[0] -----> C[1] -----> C[2] -----> ... | | | v v v +---+ +---+ +---+ K->| E | K->| E | K->| E | ... +---+ +---+ +---+ | | | v v v S[0] S[1] S[2] ... The ith counter C[i] of the keystream segment with segment index s is defined as C[i] = (i + s * (256^BLOCK_INDEX_LENGTH)) (+) r where r denotes the shifted Offset, which is defined as the Offset times 256^(BLOCK_LENGTH - OFFSET_LENGTH). (This multiplication left-shifts the Offset so that it is aligned with the leftmost edge of the block.) Here ^ denotes exponentiation and (+) denotes the bitwise exclusive-or operation. The number of blocks in any segment MUST NOT exceed 256^BLOCK_INDEX_LENGTH. The number of segments MUST NOT exceed 256^SEGMENT_INDEX_LENGTH. These restrictions ensure the uniqueness of each block cipher input. They also imply that each segment contains no more than (256^BLOCK_INDEX_LENGTH)*BLOCK_LENGTH octets. The sum of SEGMENT_INDEX_LENGTH and BLOCK_INDEX_LENGTH MUST NOT exceed BLOCK_LENGTH / 2. This requirement protects the ICM keystream generator from potentially failing to be pseudorandom (see McGrew [Page 3] Internet Draft Integer Counter Mode October, 2002 the rationale). Figure 2. An illustration of the structure of a counter with BLOCK_LENGTH = 8, SEGMENT_INDEX_LENGTH = 2, and BLOCK_INDEX_LENGTH = 2. The field marked `null' is not part of either the block or segment indices. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | null | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | segment index | block index | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4.3. ICM Encryption Unless otherwise specified, ICM encryption consists of bitwise exclusive-oring the keystream into the plaintext to produce the ciphertext. 4.4 ICM KEY An ICM key consists of the block cipher key and an Offset. The Offset is an integer with OFFSET_LENGTH octets, which is used to `randomize' the logical starting point of keystream. The Offset is crucial to providing security; see the rationale. The value of OFFSET_LENGTH SHOULD be at least half that of BLOCK_LENGTH. For the purposes of transporting an ICM key, e.g. in a signaling protocol, that key SHOULD be considered a sequence of octets in which the block cipher key precedes the Offset. 5. Implementation Considerations Implementation of the `add one modulo 2^m' operation is simple. For example, with BLOCK_LENGTH = 8 (m=64), it can be implemented in C as if (!++x) ++y; where x and y are 32-bit unsigned integers in network byte order. The implementation of general purpose addition modulo 2^m is slightly more complicated. The fact that the Offset is left-aligned enables an implementation McGrew [Page 4] Internet Draft Integer Counter Mode October, 2002 to avoid propagating carry values outside of the block index and/or the segment index. Choosing an OFFSET_LENGTH value equal to half that of BLOCK_LENGTH avoids all of these carries, since the Offset is then shifted so that it occupies the most significant octets of the block, while the block and segment indices occupy the least significant ones. 6. Parameters and Test Vectors for AES This section provides ICM parameters and test vectors for AES with a 128 bit block size and 128 bit key (that is, with a BLOCK_LENGTH and KEY_LENGTH of 16). All integers are expressed in hexadecimal. Each consecutive pair of hex digits corresponds to an octet, so that the integer 000102030405060708090A0B0C0D0E0F corresponds to the octet sequence { 00, 01, 02, 02 ... }. BLOCK_LENGTH 16 KEY_LENGTH 16 OFFSET_LENGTH 14 SEGMENT_INDEX_LENGTH 6 BLOCK_INDEX_LENGTH 2 Block Cipher Key: 2b7e151628aed2a6abf7158809cf4f3c Offset: f0f1f2f3f4f5f6f7f8f9fafbfcfd Segment Index: 000000000000 Keystream: e03ead0935c95e80e166b16dd92b4eb4 d23513162b02d0f72a43a2fe4a5f97ab ... The counter values that correspond to the keystream blocks are outlined below. Counter Keystream f0f1f2f3f4f5f6f7f8f9fafbfcfd0000 e03ead0935c95e80e166b16dd92b4eb4 f0f1f2f3f4f5f6f7f8f9fafbfcfd0001 d23513162b02d0f72a43a2fe4a5f97ab f0f1f2f3f4f5f6f7f8f9fafbfcfd0002 41e95b3bb0a2e8dd477901e4fca894c0 ... ... 7. Security Considerations Each block cipher input is distinct for any segment and any block index. To see this fact, subtract any two counter values with distinct segment or block indices; the result is non-zero. McGrew [Page 5] Internet Draft Integer Counter Mode October, 2002 The limitation on the number of segments which can be generated ensures that the probability with which an adversary can distinguish the keystream generator from random is negligible. For a theoretical justification of this fact, see Bellare et. al. [BR98]. Their analysis shows that if the block cipher cannot be distinguished from a random permutation, then the keystream generated by ICM cannot be distinguished from keystream generated by a truly random process, as long as the length of keystream which is generated is kept below some threshold. The threshold defined in Section 4.2 is sufficient for most uses of ICM for encryption. This specification refrains from dictating a lower threshold in order to refrain from dictating a particular policy, and to avoid a complicated digression. The use of the Offset, a key-dependent value which randomizes the starting position of the keystream, is essential for security. The omission of this mechanism leaves the door open for practical attacks, such as the key collision attack and Hellman's time-memory tradeoff attack; see McGrew and Fluhrer [MF00] for a description of these attacks which is applicable to ICM. Several counter mode proposals do not include an offset, and are thus vulnerable to these attacks. 8. Rationale This speficiation includes input from implementation experience with several counter mode variants. The goals of ICM are to provide: o a secure keystream generator and cipher, and o a definition flexible enough that a single implementation can be used for a variety of applications (e.g., Secure RTP [SRTP], IPsec ESP [KA96]). The Offset slightly increases the key management overhead, but this minor disadvantage is well outweighed by other savings. The Offset is no larger than a CBC mode IV, and ICM enables the use of an explicit IV (as is commonly used with CBC [MD98]) to be avoided. 9. History This draft is based on draft-mcgrew-saag-icm-00.txt, which was submitted to SAAG on November, 2001 and which expired in May, 2002. The current definition of ICM has changed from the earlier one; the counter formation is different and the specifications are McGrew [Page 6] Internet Draft Integer Counter Mode October, 2002 unfortunately not interoperable. This change was motivated by a considerable amount of feedback on the desirability of admitting optimizations of the sort described in Section 5, in which the carry operations of counter addition need not be propagated across a large register. The current definition of ICM is interoperable with that defined in Secure RTP [SRTP]. 10. Acknowledgements Thanks are due to Helger Lipmaa, Jerome Etienne, Scott Fluhrer and Mats Naslund for their helpful discussion and comments. 11. Contact Information Questions and comments on this draft SHOULD be sent to: David A. McGrew Cisco Systems, Inc. mcgrew@cisco.com and copied to the Crypto Forum Research Group at: cfrg@ietf.org. 12. References [BR98] M. Bellare, A. Desai, E. Lokipii and P. Rogaway, A Concrete Security Treatment of Symmetric Encryption: Analysis of DES Modes of Operation, Proceedings of the 38th Symposium on Foundations of Computer Science, IEEE, 1997. [B97] S. Bradner, Key words for use in RFCs to Indicate Requirement Levels, RFC 2119, March 1997. [AES] The Advanced Encryption Standard, United States National Institute for Standards and Technology (NIST), http://www.nist.gov/aes/. [CTR] M. Dworkin, NIST Special Publication 800-38A, "Recommendation for Block Cipher Modes of Operation: Methods and Techniques", 2001. Online at McGrew [Page 7] Internet Draft Integer Counter Mode October, 2002 http://csrc.nist.gov/publications/nistpubs/800-38a/sp800- 38a.pdf. [MD98] Madson, C., and Doraswamy, N., "The ESP DES-CBC Cipher Algorithm With Explicit IV", RFC 2405, November 1998. [MF00] D. McGrew and S. Fluhrer, Attacks on Additive Encryption and Implications on Internet Security, Selected Areas in Cryptography 2000. [SRTP] The Secure Real-time Transport Protocol, Baugher et. al., Internet Draft, draft-ietf-avt-srtp-05.txt. McGrew [Page 8] \ No newline at end of file diff --git a/src/libs/srtp/doc/header.template b/src/libs/srtp/doc/header.template new file mode 100644 index 00000000..2c0b96d4 --- /dev/null +++ b/src/libs/srtp/doc/header.template @@ -0,0 +1,115 @@ +% header.tex +% +% header file for the libSRTP documentation - based on the header +% file generated by doxygen, with the initial chapters of the +% original libSRTP documentation tacked on +% +\documentclass[letterpaper]{book} +\usepackage{makeidx} +\usepackage{fancyhdr} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{times} +\usepackage{graphicx} +\ifx\pdfoutput\undefined +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue + ]{hyperref} +\else +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue + ]{hyperref} +\fi +\usepackage{doxygen} +\makeindex +\setcounter{tocdepth}{1} +\renewcommand{\footrulewidth}{0.4pt} + +% these lengths are from DAM +\textwidth = 6.5 in +%\textheight = 9 in +\oddsidemargin = 0.0 in +\evensidemargin = 0.0 in +\topmargin = 0.0 in +\headheight = 0.0 in +%\headsep = 0.0 in +\parskip = 0.2in +\parindent = 0.0in + +% these header and footer definitions from DAM +\lhead{libSRTP} +\chead{} +\rhead{\rightmark} +%\rhead{\slshape } +\lfoot{} +\cfoot{ \thepage } +\rfoot{} +%\fancyhead[LE,RO]{\rightmark } +%\fancyhead[LO,RE]{\slshape } + +% let's use the palatino font +\fontfamily{ppl} +\selectfont + + +\begin{document} +\begin{titlepage} +\vspace*{4cm} +%\begin{center} +{\Huge +libSRTP LIBSRTPVERSION Overview and Reference Manual\\ + \hrulefill +}\\ +\vspace*{0cm} +\begin{flushright} +{\Large David A. McGrew \\ \texttt{mcgrew@cisco.com} }\\ +\vspace*{0.5cm} +\end{flushright} +%\end{center} + +%\includegraphics[scale=.8]{phone} + +\end{titlepage} + + +\clearemptydoublepage +\vspace*{3cm} +{\LARGE Preface} +\vspace{1cm} + +The original implementation and documentation of libSRTP was written +by David McGrew of Cisco Systems, Inc. in order to promote the use, +understanding, and interoperability of Secure RTP. Michael Jerris +contributed support for building under MSVC. Andris Pavenis +contributed many important fixes. Brian West contributed changes to +enable dynamic linking. Yves Shumann reported documentation bugs. +Randell Jesup contributed a working SRTCP implementation and other +fixes. Alex Vanzella and Will Clark contributed changes so that the +AES ICM implementation can be used for ISMA media encryption. Steve +Underwood contributed x86\_64 portability changes. We also give +thanks to Fredrik Thulin, Brian Weis, Mark Baugher, Jeff Chan, Bill +Simon, Douglas Smith, Bill May, Richard Preistley, Joe Tardo and +others for contributions, comments, and corrections. + +This reference material in this documenation was generated using the +\texttt{doxygen} utility for automatic documentation of source code. + +\copyright 2001-2005 by David A. McGrew, Cisco Systems, Inc. +\thispagestyle{empty} + +\clearemptydoublepage +\pagenumbering{roman} +\tableofcontents +%\clearemptydoublepage + +\clearemptydoublepage +\pagenumbering{arabic} + + diff --git a/src/libs/srtp/doc/intro.txt b/src/libs/srtp/doc/intro.txt new file mode 100644 index 00000000..e8607d1c --- /dev/null +++ b/src/libs/srtp/doc/intro.txt @@ -0,0 +1,395 @@ +/** + +@mainpage Introduction to libSRTP + +This document describes libSRTP, the Open Source Secure RTP library +from Cisco Systems, Inc. RTP is the Real-time Transport Protocol, an +IETF standard for the transport of real-time data such as telephony, +audio, and video, defined by RFC 3550. Secure RTP (SRTP) is an RTP +profile for providing confidentiality to RTP data and authentication +to the RTP header and payload. SRTP is an IETF Proposed Standard, +defined in RFC 3711, and was developed in the IETF Audio/Video +Transport (AVT) Working Group. This library supports all of the +mandatory features of SRTP, but not all of the optional features. See +the @ref Features section for more detailed information. + +This document is organized as follows. The first chapter provides +background material on SRTP and overview of libSRTP. The following +chapters provide a detailed reference to the libSRTP API and related +functions. The reference material is created automatically (using the +doxygen utility) from comments embedded in some of the C header +files. The documentation is organized into modules in order to improve +its clarity. These modules do not directly correspond to files. An +underlying cryptographic kernel provides much of the basic +functionality of libSRTP, but is mostly undocumented because it does +its work behind the scenes. + +@section LICENSE License and Disclaimer + +libSRTP is distributed under the following license, which is included +in the source code distribution. It is reproduced in the manual in +case you got the library from another source. + +@latexonly +\begin{quote} +Copyright (c) 2001-2005 Cisco Systems, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +\begin{itemize} +\item Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +\item Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. +\item Neither the name of the Cisco Systems, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. +\end{itemize} +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. +\end{quote} +@endlatexonly + +@section Features Supported Features + +This library supports all of the mandatory-to-implement features of +SRTP (as defined by the most recent Internet Draft). Some of these +features can be selected (or de-selected) at run time by setting an +appropriate policy; this is done using the structure srtp_policy_t. +Some other behaviors of the protocol can be adapted by defining an +approriate event handler for the exceptional events; see the @ref +SRTPevents section. + +Some options that are not included in the specification are supported. +Most notably, the TMMH authentication function is included, though it +was removed from the SRTP Internet Draft during the summer of 2002. + + +@latexonly +Some options that are described in the SRTP specification are not +supported. This includes +\begin{itemize} +\item the Master Key Index (MKI), +\item key derivation rates other than zero, +\item the cipher F8, +\item anti-replay lists with sizes other than 128, +\item the use of the packet index to select between master keys. +\end{itemize} +@endlatexonly + +The user should be aware that it is possible to misuse this libary, +and that the result may be that the security level it provides is +inadequate. If you are implementing a feature using this library, you +will want to read the Security Considerations section of the Internet +Draft. In addition, it is important that you read and understand the +terms outlined in the @ref LICENSE section. + + +@section Installing Installing and Building libSRTP + +@latexonly + +To install libSRTP, download the latest release of the distribution +from \texttt{srtp.sourceforge.net}. The format of the names of the +distributions are \texttt{srtp-A.B.C.tgz}, where \texttt{A} is the +version number, \texttt{B} is the major release number, \texttt{C} is +the minor release number, and \texttt{tgz} is the file +extension\footnote{The extension \texttt{.tgz} is identical to +\texttt{tar.gz}, and indicates a compressed tar file.} You probably +want to get the most recent release. Unpack the distribution and +extract the source files; the directory into which the source files +will go is named \texttt{srtp}. + +libSRTP uses the GNU \texttt{autoconf} and \texttt{make} +utilities\footnote{BSD make will not work; if both versions of make +are on your platform, you can invoke GNU make as \texttt{gmake}.}. In +the \texttt{srtp} directory, run the configure script and then make: +\begin{verbatim} + ./configure [ options ] + make +\end{verbatim} +The configure script accepts the following options: +\begin{quote} +\begin{description} +\item[--help] provides a usage summary. +\item[--disable-debug] compiles libSRTP without the runtime + dynamic debugging system. +\item[--enable-generic-aesicm] compile in changes for ismacryp +\item[--enable-syslog] use syslog for error reporting. +\item[--disable-stdout] diables stdout for error reporting. +\item[--enable-console] use \texttt{/dev/console} for error reporting +\item[--gdoi] use GDOI key management (disabled at present). +\end{description} +\end{quote} + +By default, dynamic debugging is enabled and stdout is used for +debugging. You can use the configure options to have the debugging +output sent to syslog or the system console. Alternatively, you can +define ERR\_REPORTING\_FILE in \texttt{include/conf.h} to be any other +file that can be opened by libSRTP, and debug messages will be sent to +it. + +This package has been tested on the following platforms: Mac OS X +(powerpc-apple-darwin1.4), Cygwin (i686-pc-cygwin), Solaris +(sparc-sun-solaris2.6), RedHat Linux 7.1 and 9 (i686-pc-linux), and +OpenBSD (sparc-unknown-openbsd2.7). + + +@endlatexonly + +@section Applications Applications + +@latexonly + +Several test drivers and a simple and portable srtp application are +included in the \texttt{test/} subdirectory. + +\begin{center} +\begin{tabular}{ll} +\hline +Test driver & Function tested \\ +\hline +kernel\_driver & crypto kernel (ciphers, auth funcs, rng) \\ +srtp\_driver & srtp in-memory tests (does not use the network) \\ +rdbx\_driver & rdbx (extended replay database) \\ +roc\_driver & extended sequence number functions \\ +replay\_driver & replay database \\ +cipher\_driver & ciphers \\ +auth\_driver & hash functions \\ +\hline +\end{tabular} +\end{center} + +The app rtpw is a simple rtp application which reads words from +/usr/dict/words and then sends them out one at a time using [s]rtp. +Manual srtp keying uses the -k option; automated key management +using gdoi will be added later. + +The usage for rtpw is + +\texttt{rtpw [[-d $<$debug$>$]* [-k $<$key$>$ [-a][-e]] [-s | -r] dest\_ip +dest\_port] | [-l]} + +Either the -s (sender) or -r (receiver) option must be chosen. The +values dest\_ip, dest\_port are the IP address and UDP port to which +the dictionary will be sent, respectively. The options are: +\begin{center} +\begin{tabular}{ll} + -s & (S)RTP sender - causes app to send words \\ + -r & (S)RTP receive - causes app to receive words \\ + -k $<$key$>$ & use SRTP master key $<$key$>$, where the + key is a hexadecimal value (without the + leading "0x") \\ + -e & encrypt/decrypt (for data confidentiality) + (requires use of -k option as well)\\ + -a & message authentication + (requires use of -k option as well) \\ + -l & list the available debug modules \\ + -d $<$debug$>$ & turn on debugging for module $<$debug$>$ \\ +\end{tabular} +\end{center} + +In order to get a random 30-byte value for use as a key/salt pair, you +can use the \texttt{rand\_gen} utility in the \texttt{test/} +subdirectory. + +An example of an SRTP session using two rtpw programs follows: + +\begin{verbatim} +[sh1] set k=`test/rand_gen -n 30` +[sh1] echo $k +c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451 +[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999 +Security services: confidentiality message authentication +set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451 +setting SSRC to 2078917053 +sending word: A +sending word: a +sending word: aa +sending word: aal +sending word: aalii +sending word: aam +sending word: Aani +sending word: aardvark +... + +[sh2] set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451 +[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999 +security services: confidentiality message authentication +set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451 +19 octets received from SSRC 2078917053 word: A +19 octets received from SSRC 2078917053 word: a +20 octets received from SSRC 2078917053 word: aa +21 octets received from SSRC 2078917053 word: aal +... +\end{verbatim} + + +@endlatexonly + + +@section Review Secure RTP Background + +In this section we review SRTP and introduce some terms that are used +in libSRTP. An RTP session is defined by a pair of destination +transport addresses, that is, a network address plus a pair of UDP +ports for RTP and RTCP. RTCP, the RTP control protocol, is used to +coordinate between the participants in an RTP session, e.g. to provide +feedback from receivers to senders. An @e SRTP @e session is +similarly defined; it is just an RTP session for which the SRTP +profile is being used. An SRTP session consists of the traffic sent +to the SRTP or SRTCP destination transport addresses. Each +participant in a session is identified by a synchronization source +(SSRC) identifier. Some participants may not send any SRTP traffic; +they are called receivers, even though they send out SRTCP traffic, +such as receiver reports. + +RTP allows multiple sources to send RTP and RTCP traffic during the +same session. The synchronization source identifier (SSRC) is used to +distinguish these sources. In libSRTP, we call the SRTP and SRTCP +traffic from a particular source a @e stream. Each stream has its own +SSRC, sequence number, rollover counter, and other data. A particular +choice of options, cryptographic mechanisms, and keys is called a @e +policy. Each stream within a session can have a distinct policy +applied to it. A session policy is a collection of stream policies. + +A single policy can be used for all of the streams in a given session, +though the case in which a single @e key is shared across multiple +streams requires care. When key sharing is used, the SSRC values that +identify the streams @b must be distinct. This requirement can be +enforced by using the convention that each SRTP and SRTCP key is used +for encryption by only a single sender. In other words, the key is +shared only across streams that originate from a particular device (of +course, other SRTP participants will need to use the key for +decryption). libSRTP supports this enforcement by detecting the case +in which a key is used for both inbound and outbound data. + + +@section Overview libSRTP Overview + +libSRTP provides functions for protecting RTP and RTCP. RTP packets +can be encrypted and authenticated (using the srtp_protect() +function), turning them into SRTP packets. Similarly, SRTP packets +can be decrypted and have their authentication verified (using the +srtp_unprotect() function), turning them into RTP packets. Similar +functions apply security to RTCP packets. + +The typedef srtp_stream_t points to a structure holding all of the +state associated with an SRTP stream, including the keys and +parameters for cipher and message authentication functions and the +anti-replay data. A particular srtp_stream_t holds the information +needed to protect a particular RTP and RTCP stream. This datatype +is intentionally opaque in order to better seperate the libSRTP +API from its implementation. + +Within an SRTP session, there can be multiple streams, each +originating from a particular sender. Each source uses a distinct +stream context to protect the RTP and RTCP stream that it is +originating. The typedef srtp_t points to a structure holding all of +the state associated with an SRTP session. There can be multiple +stream contexts associated with a single srtp_t. A stream context +cannot exist indepent from an srtp_t, though of course an srtp_t can +be created that contains only a single stream context. A device +participating in an SRTP session must have a stream context for each +source in that session, so that it can process the data that it +receives from each sender. + + +In libSRTP, a session is created using the function srtp_create(). +The policy to be implemented in the session is passed into this +function as an srtp_policy_t structure. A single one of these +structures describes the policy of a single stream. These structures +can also be linked together to form an entire session policy. A linked +list of srtp_policy_t structures is equivalent to a session policy. +In such a policy, we refer to a single srtp_policy_t as an @e element. + +An srtp_policy_t strucutre contains two crypto_policy_t structures +that describe the cryptograhic policies for RTP and RTCP, as well as +the SRTP master key and the SSRC value. The SSRC describes what to +protect (e.g. which stream), and the crypto_policy_t structures +describe how to protect it. The key is contained in a policy element +because it simplifies the interface to the library. In many cases, it +is desirable to use the same cryptographic policies across all of the +streams in a session, but to use a distinct key for each stream. A +crypto_policy_t structure can be initialized by using either the +crypto_policy_set_rtp_default() or crypto_policy_set_rtcp_default() +functions, which set a crypto policy structure to the default policies +for RTP and RTCP protection, respectively. + +@section Example Example Code + +This section provides a simple example of how to use libSRTP. The +example code lacks error checking, but is functional. Here we assume +that the value ssrc is already set to describe the SSRC of the stream +that we are sending, and that the functions get_rtp_packet() and +send_srtp_packet() are available to us. The former puts an RTP packet +into the buffer and returns the number of octets written to that +buffer. The latter sends the RTP packet in the buffer, given the +length as its second argument. + +@verbatim + srtp_t session; + srtp_policy_t policy; + uint8_t key[30]; + + // initialize libSRTP + srtp_init(); + + // set policy to describe a policy for an SRTP stream + crypto_policy_set_rtp_default(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + policy.ssrc = ssrc; + policy.key = key; + policy.next = NULL; + + // set key to random value + crypto_get_random(key, 30); + + // allocate and initialize the SRTP session + srtp_create(&session, &policy); + + // main loop: get rtp packets, send srtp packets + while (1) { + char rtp_buffer[2048]; + unsigned len; + + len = get_rtp_packet(rtp_buffer); + srtp_protect(session, rtp_buffer, &len); + send_srtp_packet(rtp_buffer, len); + } +@endverbatim + +@section ISMAcryp ISMA Encryption Support + +The Internet Streaming Media Alliance (ISMA) specifies a way +to pre-encrypt a media file prior to streaming. This method +is an alternative to SRTP encryption, which is potentially +useful when a particular media file will be streamed +multiple times. The specification is available online +at http://www.isma.tv/specreq.nsf/SpecRequest. + +libSRTP provides the encryption and decryption functions needed for ISMAcryp +in the library @t libaesicm.a, which is included in the default +Makefile target. This library is used by the MPEG4IP project; see +http://mpeg4ip.sourceforge.net/. + +Note that ISMAcryp does not provide authentication for +RTP nor RTCP, nor confidentiality for RTCP. +ISMAcryp RECOMMENDS the use of SRTP message authentication for ISMAcryp +streams while using ISMAcryp encryption to protect the media itself. + + + */ diff --git a/src/libs/srtp/doc/libsrtp.pdf b/src/libs/srtp/doc/libsrtp.pdf new file mode 100644 index 00000000..05f7cf4a Binary files /dev/null and b/src/libs/srtp/doc/libsrtp.pdf differ diff --git a/src/libs/srtp/doc/references.txt b/src/libs/srtp/doc/references.txt new file mode 100644 index 00000000..2ec9d437 --- /dev/null +++ b/src/libs/srtp/doc/references.txt @@ -0,0 +1,21 @@ +SRTP and ICM References +September, 2005 + +This document provides references for the various cryptographic +functions used in libSRTP and libaesicm. + +Secure RTP is defined in RFC 3711, which is included in this +distribution for convenience. The counter mode definition is in +Section 4.1.1 of the SRTP draft. + +SHA-1 is defined in FIPS-180-1, available online at the NIST website. + +HMAC is defined in RFC2104, and HMAC-SHA1 test vectors are available +in RFC2202, which are available online at http://www.ietf.org/rfc/ + +ICM is defined by draft-irtf-cfrg-icm-00.txt, and its application in +ISMAcryp (the Internet Streaming Media Alliance 1.0 Encryption and +Authentication) is defined in that specification. It is available +from http://www.isma.tv/. + + diff --git a/src/libs/srtp/doc/rfc3711.txt b/src/libs/srtp/doc/rfc3711.txt new file mode 100644 index 00000000..ecc0648a --- /dev/null +++ b/src/libs/srtp/doc/rfc3711.txt @@ -0,0 +1,3139 @@ + + + + + + +Network Working Group M. Baugher +Request for Comments: 3711 D. McGrew +Category: Standards Track Cisco Systems, Inc. + M. Naslund + E. Carrara + K. Norrman + Ericsson Research + March 2004 + + + The Secure Real-time Transport Protocol (SRTP) + +Status of this Memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2004). All Rights Reserved. + +Abstract + + This document describes the Secure Real-time Transport Protocol + (SRTP), a profile of the Real-time Transport Protocol (RTP), which + can provide confidentiality, message authentication, and replay + protection to the RTP traffic and to the control traffic for RTP, the + Real-time Transport Control Protocol (RTCP). + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 3 + 2. Goals and Features . . . . . . . . . . . . . . . . . . . . . . 4 + 2.1. Features . . . . . . . . . . . . . . . . . . . . . . . . 5 + 3. SRTP Framework . . . . . . . . . . . . . . . . . . . . . . . . 5 + 3.1. Secure RTP . . . . . . . . . . . . . . . . . . . . . . . 6 + 3.2. SRTP Cryptographic Contexts. . . . . . . . . . . . . . . 7 + 3.2.1. Transform-independent parameters . . . . . . . . 8 + 3.2.2. Transform-dependent parameters . . . . . . . . . 10 + 3.2.3. Mapping SRTP Packets to Cryptographic Contexts . 10 + 3.3. SRTP Packet Processing . . . . . . . . . . . . . . . . . 11 + 3.3.1. Packet Index Determination, and ROC, s_l Update. 13 + 3.3.2. Replay Protection. . . . . . . . . . . . . . . . 15 + 3.4. Secure RTCP . . . . . . . . . . . . . . . . . . . . . . . 15 + + + +Baugher, et al. Standards Track [Page 1] + +RFC 3711 SRTP March 2004 + + + 4. Pre-Defined Cryptographic Transforms . . . . . . . . . . . . . 19 + 4.1. Encryption . . . . . . . . . . . . . . . . . . . . . . . 19 + 4.1.1. AES in Counter Mode. . . . . . . . . . . . . . . 21 + 4.1.2. AES in f8-mode . . . . . . . . . . . . . . . . . 22 + 4.1.3. NULL Cipher. . . . . . . . . . . . . . . . . . . 25 + 4.2. Message Authentication and Integrity . . . . . . . . . . 25 + 4.2.1. HMAC-SHA1. . . . . . . . . . . . . . . . . . . . 25 + 4.3. Key Derivation . . . . . . . . . . . . . . . . . . . . . 26 + 4.3.1. Key Derivation Algorithm . . . . . . . . . . . . 26 + 4.3.2. SRTCP Key Derivation . . . . . . . . . . . . . . 28 + 4.3.3. AES-CM PRF . . . . . . . . . . . . . . . . . . . 28 + 5. Default and mandatory-to-implement Transforms. . . . . . . . . 28 + 5.1. Encryption: AES-CM and NULL. . . . . . . . . . . . . . . 29 + 5.2. Message Authentication/Integrity: HMAC-SHA1. . . . . . . 29 + 5.3. Key Derivation: AES-CM PRF . . . . . . . . . . . . . . . 29 + 6. Adding SRTP Transforms . . . . . . . . . . . . . . . . . . . . 29 + 7. Rationale. . . . . . . . . . . . . . . . . . . . . . . . . . . 30 + 7.1. Key derivation . . . . . . . . . . . . . . . . . . . . . 30 + 7.2. Salting key. . . . . . . . . . . . . . . . . . . . . . . 30 + 7.3. Message Integrity from Universal Hashing . . . . . . . . 31 + 7.4. Data Origin Authentication Considerations. . . . . . . . 31 + 7.5. Short and Zero-length Message Authentication . . . . . . 32 + 8. Key Management Considerations. . . . . . . . . . . . . . . . . 33 + 8.1. Re-keying . . . . . . . . . . . . . . . . . . . . . . . 34 + 8.1.1. Use of the <From, To> for re-keying. . . . . . . 34 + 8.2. Key Management parameters. . . . . . . . . . . . . . . . 35 + 9. Security Considerations. . . . . . . . . . . . . . . . . . . . 37 + 9.1. SSRC collision and two-time pad. . . . . . . . . . . . . 37 + 9.2. Key Usage. . . . . . . . . . . . . . . . . . . . . . . . 38 + 9.3. Confidentiality of the RTP Payload . . . . . . . . . . . 39 + 9.4. Confidentiality of the RTP Header. . . . . . . . . . . . 40 + 9.5. Integrity of the RTP payload and header. . . . . . . . . 40 + 9.5.1. Risks of Weak or Null Message Authentication. . . 42 + 9.5.2. Implicit Header Authentication . . . . . . . . . 43 + 10. Interaction with Forward Error Correction mechanisms. . . . . 43 + 11. Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . 43 + 11.1. Unicast. . . . . . . . . . . . . . . . . . . . . . . . . 43 + 11.2. Multicast (one sender) . . . . . . . . . . . . . . . . . 44 + 11.3. Re-keying and access control . . . . . . . . . . . . . . 45 + 11.4. Summary of basic scenarios . . . . . . . . . . . . . . . 46 + 12. IANA Considerations. . . . . . . . . . . . . . . . . . . . . . 46 + 13. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 47 + 14. References . . . . . . . . . . . . . . . . . . . . . . . . . . 47 + 14.1. Normative References . . . . . . . . . . . . . . . . . . 47 + 14.2. Informative References . . . . . . . . . . . . . . . . . 48 + Appendix A: Pseudocode for Index Determination . . . . . . . . . . 51 + Appendix B: Test Vectors . . . . . . . . . . . . . . . . . . . . . 51 + B.1. AES-f8 Test Vectors. . . . . . . . . . . . . . . . . . . 51 + + + +Baugher, et al. Standards Track [Page 2] + +RFC 3711 SRTP March 2004 + + + B.2. AES-CM Test Vectors. . . . . . . . . . . . . . . . . . . 52 + B.3. Key Derivation Test Vectors. . . . . . . . . . . . . . . 53 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 55 + Full Copyright Statement . . . . . . . . . . . . . . . . . . . . . 56 + +1. Introduction + + This document describes the Secure Real-time Transport Protocol + (SRTP), a profile of the Real-time Transport Protocol (RTP), which + can provide confidentiality, message authentication, and replay + protection to the RTP traffic and to the control traffic for RTP, + RTCP (the Real-time Transport Control Protocol) [RFC3350]. + + SRTP provides a framework for encryption and message authentication + of RTP and RTCP streams (Section 3). SRTP defines a set of default + cryptographic transforms (Sections 4 and 5), and it allows new + transforms to be introduced in the future (Section 6). With + appropriate key management (Sections 7 and 8), SRTP is secure + (Sections 9) for unicast and multicast RTP applications (Section 11). + + SRTP can achieve high throughput and low packet expansion. SRTP + proves to be a suitable protection for heterogeneous environments + (mix of wired and wireless networks). To get such features, default + transforms are described, based on an additive stream cipher for + encryption, a keyed-hash based function for message authentication, + and an "implicit" index for sequencing/synchronization based on the + RTP sequence number for SRTP and an index number for Secure RTCP + (SRTCP). + +1.1. Notational Conventions + + The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in [RFC2119]. The + terminology conforms to [RFC2828] with the following exception. For + simplicity we use the term "random" throughout the document to denote + randomly or pseudo-randomly generated values. Large amounts of + random bits may be difficult to obtain, and for the security of SRTP, + pseudo-randomness is sufficient [RFC1750]. + + By convention, the adopted representation is the network byte order, + i.e., the left most bit (octet) is the most significant one. By XOR + we mean bitwise addition modulo 2 of binary strings, and || denotes + concatenation. In other words, if C = A || B, then the most + significant bits of C are the bits of A, and the least significant + bits of C equal the bits of B. Hexadecimal numbers are prefixed by + 0x. + + + + +Baugher, et al. Standards Track [Page 3] + +RFC 3711 SRTP March 2004 + + + The word "encryption" includes also use of the NULL algorithm (which + in practice does leave the data in the clear). + + With slight abuse of notation, we use the terms "message + authentication" and "authentication tag" as is common practice, even + though in some circumstances, e.g., group communication, the service + provided is actually only integrity protection and not data origin + authentication. + +2. Goals and Features + + The security goals for SRTP are to ensure: + + * the confidentiality of the RTP and RTCP payloads, and + + * the integrity of the entire RTP and RTCP packets, together with + protection against replayed packets. + + These security services are optional and independent from each other, + except that SRTCP integrity protection is mandatory (malicious or + erroneous alteration of RTCP messages could otherwise disrupt the + processing of the RTP stream). + + Other, functional, goals for the protocol are: + + * a framework that permits upgrading with new cryptographic + transforms, + + * low bandwidth cost, i.e., a framework preserving RTP header + compression efficiency, + + and, asserted by the pre-defined transforms: + + * a low computational cost, + + * a small footprint (i.e., small code size and data memory for + keying information and replay lists), + + * limited packet expansion to support the bandwidth economy goal, + + * independence from the underlying transport, network, and physical + layers used by RTP, in particular high tolerance to packet loss + and re-ordering. + + These properties ensure that SRTP is a suitable protection scheme for + RTP/RTCP in both wired and wireless scenarios. + + + + + +Baugher, et al. Standards Track [Page 4] + +RFC 3711 SRTP March 2004 + + +2.1. Features + + Besides the above mentioned direct goals, SRTP provides for some + additional features. They have been introduced to lighten the burden + on key management and to further increase security. They include: + + * A single "master key" can provide keying material for + confidentiality and integrity protection, both for the SRTP stream + and the corresponding SRTCP stream. This is achieved with a key + derivation function (see Section 4.3), providing "session keys" + for the respective security primitive, securely derived from the + master key. + + * In addition, the key derivation can be configured to periodically + refresh the session keys, which limits the amount of ciphertext + produced by a fixed key, available for an adversary to + cryptanalyze. + + * "Salting keys" are used to protect against pre-computation and + time-memory tradeoff attacks [MF00] [BS00]. + + Detailed rationale for these features can be found in Section 7. + +3. SRTP Framework + + RTP is the Real-time Transport Protocol [RFC3550]. We define SRTP as + a profile of RTP. This profile is an extension to the RTP + Audio/Video Profile [RFC3551]. Except where explicitly noted, all + aspects of that profile apply, with the addition of the SRTP security + features. Conceptually, we consider SRTP to be a "bump in the stack" + implementation which resides between the RTP application and the + transport layer. SRTP intercepts RTP packets and then forwards an + equivalent SRTP packet on the sending side, and intercepts SRTP + packets and passes an equivalent RTP packet up the stack on the + receiving side. + + Secure RTCP (SRTCP) provides the same security services to RTCP as + SRTP does to RTP. SRTCP message authentication is MANDATORY and + thereby protects the RTCP fields to keep track of membership, provide + feedback to RTP senders, or maintain packet sequence counters. SRTCP + is described in Section 3.4. + + + + + + + + + + +Baugher, et al. Standards Track [Page 5] + +RFC 3711 SRTP March 2004 + + +3.1. Secure RTP + + The format of an SRTP packet is illustrated in Figure 1. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+ + |V=2|P|X| CC |M| PT | sequence number | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | timestamp | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | synchronization source (SSRC) identifier | | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | + | contributing source (CSRC) identifiers | | + | .... | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | RTP extension (OPTIONAL) | | + +>+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | | payload ... | | + | | +-------------------------------+ | + | | | RTP padding | RTP pad count | | + +>+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+ + | ~ SRTP MKI (OPTIONAL) ~ | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | : authentication tag (RECOMMENDED) : | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | | + +- Encrypted Portion* Authenticated Portion ---+ + + Figure 1. The format of an SRTP packet. *Encrypted Portion is the + same size as the plaintext for the Section 4 pre-defined transforms. + + The "Encrypted Portion" of an SRTP packet consists of the encryption + of the RTP payload (including RTP padding when present) of the + equivalent RTP packet. The Encrypted Portion MAY be the exact size + of the plaintext or MAY be larger. Figure 1 shows the RTP payload + including any possible padding for RTP [RFC3550]. + + None of the pre-defined encryption transforms uses any padding; for + these, the RTP and SRTP payload sizes match exactly. New transforms + added to SRTP (following Section 6) may require padding, and may + hence produce larger payloads. RTP provides its own padding format + (as seen in Fig. 1), which due to the padding indicator in the RTP + header has merits in terms of compactness relative to paddings using + prefix-free codes. This RTP padding SHALL be the default method for + transforms requiring padding. Transforms MAY specify other padding + methods, and MUST then specify the amount, format, and processing of + their padding. It is important to note that encryption transforms + + + +Baugher, et al. Standards Track [Page 6] + +RFC 3711 SRTP March 2004 + + + that use padding are vulnerable to subtle attacks, especially when + message authentication is not used [V02]. Each specification for a + new encryption transform needs to carefully consider and describe the + security implications of the padding that it uses. Message + authentication codes define their own padding, so this default does + not apply to authentication transforms. + + The OPTIONAL MKI and the RECOMMENDED authentication tag are the only + fields defined by SRTP that are not in RTP. Only 8-bit alignment is + assumed. + + MKI (Master Key Identifier): configurable length, OPTIONAL. The + MKI is defined, signaled, and used by key management. The + MKI identifies the master key from which the session + key(s) were derived that authenticate and/or encrypt the + particular packet. Note that the MKI SHALL NOT identify + the SRTP cryptographic context, which is identified + according to Section 3.2.3. The MKI MAY be used by key + management for the purposes of re-keying, identifying a + particular master key within the cryptographic context + (Section 3.2.1). + + Authentication tag: configurable length, RECOMMENDED. The + authentication tag is used to carry message authentication + data. The Authenticated Portion of an SRTP packet + consists of the RTP header followed by the Encrypted + Portion of the SRTP packet. Thus, if both encryption and + authentication are applied, encryption SHALL be applied + before authentication on the sender side and conversely on + the receiver side. The authentication tag provides + authentication of the RTP header and payload, and it + indirectly provides replay protection by authenticating + the sequence number. Note that the MKI is not integrity + protected as this does not provide any extra protection. + +3.2. SRTP Cryptographic Contexts + + Each SRTP stream requires the sender and receiver to maintain + cryptographic state information. This information is called the + "cryptographic context". + + SRTP uses two types of keys: session keys and master keys. By a + "session key", we mean a key which is used directly in a + cryptographic transform (e.g., encryption or message authentication), + and by a "master key", we mean a random bit string (given by the key + management protocol) from which session keys are derived in a + + + + + +Baugher, et al. Standards Track [Page 7] + +RFC 3711 SRTP March 2004 + + + cryptographically secure way. The master key(s) and other parameters + in the cryptographic context are provided by key management + mechanisms external to SRTP, see Section 8. + +3.2.1. Transform-independent parameters + + Transform-independent parameters are present in the cryptographic + context independently of the particular encryption or authentication + transforms that are used. The transform-independent parameters of + the cryptographic context for SRTP consist of: + + * a 32-bit unsigned rollover counter (ROC), which records how many + times the 16-bit RTP sequence number has been reset to zero after + passing through 65,535. Unlike the sequence number (SEQ), which + SRTP extracts from the RTP packet header, the ROC is maintained by + SRTP as described in Section 3.3.1. + + We define the index of the SRTP packet corresponding to a given + ROC and RTP sequence number to be the 48-bit quantity + + i = 2^16 * ROC + SEQ. + + * for the receiver only, a 16-bit sequence number s_l, which can be + thought of as the highest received RTP sequence number (see + Section 3.3.1 for its handling), which SHOULD be authenticated + since message authentication is RECOMMENDED, + + * an identifier for the encryption algorithm, i.e., the cipher and + its mode of operation, + + * an identifier for the message authentication algorithm, + + * a replay list, maintained by the receiver only (when + authentication and replay protection are provided), containing + indices of recently received and authenticated SRTP packets, + + * an MKI indicator (0/1) as to whether an MKI is present in SRTP and + SRTCP packets, + + * if the MKI indicator is set to one, the length (in octets) of the + MKI field, and (for the sender) the actual value of the currently + active MKI (the value of the MKI indicator and length MUST be kept + fixed for the lifetime of the context), + + * the master key(s), which MUST be random and kept secret, + + + + + + +Baugher, et al. Standards Track [Page 8] + +RFC 3711 SRTP March 2004 + + + * for each master key, there is a counter of the number of SRTP + packets that have been processed (sent) with that master key + (essential for security, see Sections 3.3.1 and 9), + + * non-negative integers n_e, and n_a, determining the length of the + session keys for encryption, and message authentication. + + In addition, for each master key, an SRTP stream MAY use the + following associated values: + + * a master salt, to be used in the key derivation of session keys. + This value, when used, MUST be random, but MAY be public. Use of + master salt is strongly RECOMMENDED, see Section 9.2. A "NULL" + salt is treated as 00...0. + + * an integer in the set {1,2,4,...,2^24}, the "key_derivation_rate", + where an unspecified value is treated as zero. The constraint to + be a power of 2 simplifies the session-key derivation + implementation, see Section 4.3. + + * an MKI value, + + * <From, To> values, specifying the lifetime for a master key, + expressed in terms of the two 48-bit index values inside whose + range (including the range end-points) the master key is valid. + For the use of <From, To>, see Section 8.1.1. <From, To> is an + alternative to the MKI and assumes that a master key is in one- + to-one correspondence with the SRTP session key on which the + <From, To> range is defined. + + SRTCP SHALL by default share the crypto context with SRTP, except: + + * no rollover counter and s_l-value need to be maintained as the + RTCP index is explicitly carried in each SRTCP packet, + + * a separate replay list is maintained (when replay protection is + provided), + + * SRTCP maintains a separate counter for its master key (even if the + master key is the same as that for SRTP, see below), as a means to + maintain a count of the number of SRTCP packets that have been + processed with that key. + + Note in particular that the master key(s) MAY be shared between SRTP + and the corresponding SRTCP, if the pre-defined transforms (including + the key derivation) are used but the session key(s) MUST NOT be so + shared. + + + + +Baugher, et al. Standards Track [Page 9] + +RFC 3711 SRTP March 2004 + + + In addition, there can be cases (see Sections 8 and 9.1) where + several SRTP streams within a given RTP session, identified by their + synchronization source (SSRCs, which is part of the RTP header), + share most of the crypto context parameters (including possibly + master and session keys). In such cases, just as in the normal + SRTP/SRTCP parameter sharing above, separate replay lists and packet + counters for each stream (SSRC) MUST still be maintained. Also, + separate SRTP indices MUST then be maintained. + + A summary of parameters, pre-defined transforms, and default values + for the above parameters (and other SRTP parameters) can be found in + Sections 5 and 8.2. + +3.2.2. Transform-dependent parameters + + All encryption, authentication/integrity, and key derivation + parameters are defined in the transforms section (Section 4). + Typical examples of such parameters are block size of ciphers, + session keys, data for the Initialization Vector (IV) formation, etc. + Future SRTP transform specifications MUST include a section to list + the additional cryptographic context's parameters for that transform, + if any. + +3.2.3. Mapping SRTP Packets to Cryptographic Contexts + + Recall that an RTP session for each participant is defined [RFC3550] + by a pair of destination transport addresses (one network address + plus a port pair for RTP and RTCP), and that a multimedia session is + defined as a collection of RTP sessions. For example, a particular + multimedia session could include an audio RTP session, a video RTP + session, and a text RTP session. + + A cryptographic context SHALL be uniquely identified by the triplet + context identifier: + + context id = <SSRC, destination network address, destination + transport port number> + + where the destination network address and the destination transport + port are the ones in the SRTP packet. It is assumed that, when + presented with this information, the key management returns a context + with the information as described in Section 3.2. + + As noted above, SRTP and SRTCP by default share the bulk of the + parameters in the cryptographic context. Thus, retrieving the crypto + context parameters for an SRTCP stream in practice may imply a + binding to the correspondent SRTP crypto context. It is up to the + implementation to assure such binding, since the RTCP port may not be + + + +Baugher, et al. Standards Track [Page 10] + +RFC 3711 SRTP March 2004 + + + directly deducible from the RTP port only. Alternatively, the key + management may choose to provide separate SRTP- and SRTCP- contexts, + duplicating the common parameters (such as master key(s)). The + latter approach then also enables SRTP and SRTCP to use, e.g., + distinct transforms, if so desired. Similar considerations arise + when multiple SRTP streams, forming part of one single RTP session, + share keys and other parameters. + + If no valid context can be found for a packet corresponding to a + certain context identifier, that packet MUST be discarded. + +3.3. SRTP Packet Processing + + The following applies to SRTP. SRTCP is described in Section 3.4. + + Assuming initialization of the cryptographic context(s) has taken + place via key management, the sender SHALL do the following to + construct an SRTP packet: + + 1. Determine which cryptographic context to use as described in + Section 3.2.3. + + 2. Determine the index of the SRTP packet using the rollover counter, + the highest sequence number in the cryptographic context, and the + sequence number in the RTP packet, as described in Section 3.3.1. + + 3. Determine the master key and master salt. This is done using the + index determined in the previous step or the current MKI in the + cryptographic context, according to Section 8.1. + + 4. Determine the session keys and session salt (if they are used by + the transform) as described in Section 4.3, using master key, + master salt, key_derivation_rate, and session key-lengths in the + cryptographic context with the index, determined in Steps 2 and 3. + + 5. Encrypt the RTP payload to produce the Encrypted Portion of the + packet (see Section 4.1, for the defined ciphers). This step uses + the encryption algorithm indicated in the cryptographic context, + the session encryption key and the session salt (if used) found in + Step 4 together with the index found in Step 2. + + 6. If the MKI indicator is set to one, append the MKI to the packet. + + 7. For message authentication, compute the authentication tag for the + Authenticated Portion of the packet, as described in Section 4.2. + This step uses the current rollover counter, the authentication + + + + + +Baugher, et al. Standards Track [Page 11] + +RFC 3711 SRTP March 2004 + + + algorithm indicated in the cryptographic context, and the session + authentication key found in Step 4. Append the authentication tag + to the packet. + + 8. If necessary, update the ROC as in Section 3.3.1, using the packet + index determined in Step 2. + + To authenticate and decrypt an SRTP packet, the receiver SHALL do the + following: + + 1. Determine which cryptographic context to use as described in + Section 3.2.3. + + 2. Run the algorithm in Section 3.3.1 to get the index of the SRTP + packet. The algorithm uses the rollover counter and highest + sequence number in the cryptographic context with the sequence + number in the SRTP packet, as described in Section 3.3.1. + + 3. Determine the master key and master salt. If the MKI indicator in + the context is set to one, use the MKI in the SRTP packet, + otherwise use the index from the previous step, according to + Section 8.1. + + 4. Determine the session keys, and session salt (if used by the + transform) as described in Section 4.3, using master key, master + salt, key_derivation_rate and session key-lengths in the + cryptographic context with the index, determined in Steps 2 and 3. + + 5. For message authentication and replay protection, first check if + the packet has been replayed (Section 3.3.2), using the Replay + List and the index as determined in Step 2. If the packet is + judged to be replayed, then the packet MUST be discarded, and the + event SHOULD be logged. + + Next, perform verification of the authentication tag, using the + rollover counter from Step 2, the authentication algorithm + indicated in the cryptographic context, and the session + authentication key from Step 4. If the result is "AUTHENTICATION + FAILURE" (see Section 4.2), the packet MUST be discarded from + further processing and the event SHOULD be logged. + + 6. Decrypt the Encrypted Portion of the packet (see Section 4.1, for + the defined ciphers), using the decryption algorithm indicated in + the cryptographic context, the session encryption key and salt (if + used) found in Step 4 with the index from Step 2. + + + + + + +Baugher, et al. Standards Track [Page 12] + +RFC 3711 SRTP March 2004 + + + 7. Update the rollover counter and highest sequence number, s_l, in + the cryptographic context as in Section 3.3.1, using the packet + index estimated in Step 2. If replay protection is provided, also + update the Replay List as described in Section 3.3.2. + + 8. When present, remove the MKI and authentication tag fields from + the packet. + +3.3.1. Packet Index Determination, and ROC, s_l Update + + SRTP implementations use an "implicit" packet index for sequencing, + i.e., not all of the index is explicitly carried in the SRTP packet. + For the pre-defined transforms, the index i is used in replay + protection (Section 3.3.2), encryption (Section 4.1), message + authentication (Section 4.2), and for the key derivation (Section + 4.3). + + When the session starts, the sender side MUST set the rollover + counter, ROC, to zero. Each time the RTP sequence number, SEQ, wraps + modulo 2^16, the sender side MUST increment ROC by one, modulo 2^32 + (see security aspects below). The sender's packet index is then + defined as + + i = 2^16 * ROC + SEQ. + + Receiver-side implementations use the RTP sequence number to + determine the correct index of a packet, which is the location of the + packet in the sequence of all SRTP packets. A robust approach for + the proper use of a rollover counter requires its handling and use to + be well defined. In particular, out-of-order RTP packets with + sequence numbers close to 2^16 or zero must be properly handled. + + The index estimate is based on the receiver's locally maintained ROC + and s_l values. At the setup of the session, the ROC MUST be set to + zero. Receivers joining an on-going session MUST be given the + current ROC value using out-of-band signaling such as key-management + signaling. Furthermore, the receiver SHALL initialize s_l to the RTP + sequence number (SEQ) of the first observed SRTP packet (unless the + initial value is provided by out of band signaling such as key + management). + + On consecutive SRTP packets, the receiver SHOULD estimate the index + as + i = 2^16 * v + SEQ, + + where v is chosen from the set { ROC-1, ROC, ROC+1 } (modulo 2^32) + such that i is closest (in modulo 2^48 sense) to the value 2^16 * ROC + + s_l (see Appendix A for pseudocode). + + + +Baugher, et al. Standards Track [Page 13] + +RFC 3711 SRTP March 2004 + + + After the packet has been processed and authenticated (when enabled + for SRTP packets for the session), the receiver MUST use v to + conditionally update its s_l and ROC variables as follows. If + v=(ROC-1) mod 2^32, then there is no update to s_l or ROC. If v=ROC, + then s_l is set to SEQ if and only if SEQ is larger than the current + s_l; there is no change to ROC. If v=(ROC+1) mod 2^32, then s_l is + set to SEQ and ROC is set to v. + + After a re-keying occurs (changing to a new master key), the rollover + counter always maintains its sequence of values, i.e., it MUST NOT be + reset to zero. + + As the rollover counter is 32 bits long and the sequence number is 16 + bits long, the maximum number of packets belonging to a given SRTP + stream that can be secured with the same key is 2^48 using the pre- + defined transforms. After that number of SRTP packets have been sent + with a given (master or session) key, the sender MUST NOT send any + more packets with that key. (There exists a similar limit for SRTCP, + which in practice may be more restrictive, see Section 9.2.) This + limitation enforces a security benefit by providing an upper bound on + the amount of traffic that can pass before cryptographic keys are + changed. Re-keying (see Section 8.1) MUST be triggered, before this + amount of traffic, and MAY be triggered earlier, e.g., for increased + security and access control to media. Recurring key derivation by + means of a non-zero key_derivation_rate (see Section 4.3), also gives + stronger security but does not change the above absolute maximum + value. + + On the receiver side, there is a caveat to updating s_l and ROC: if + message authentication is not present, neither the initialization of + s_l, nor the ROC update can be made completely robust. The + receiver's "implicit index" approach works for the pre-defined + transforms as long as the reorder and loss of the packets are not too + great and bit-errors do not occur in unfortunate ways. In + particular, 2^15 packets would need to be lost, or a packet would + need to be 2^15 packets out of sequence before synchronization is + lost. Such drastic loss or reorder is likely to disrupt the RTP + application itself. + + The algorithm for the index estimate and ROC update is a matter of + implementation, and should take into consideration the environment + (e.g., packet loss rate) and the cases when synchronization is likely + to be lost, e.g., when the initial sequence number (randomly chosen + by RTP) is not known in advance (not sent in the key management + protocol) but may be near to wrap modulo 2^16. + + + + + + +Baugher, et al. Standards Track [Page 14] + +RFC 3711 SRTP March 2004 + + + A more elaborate and more robust scheme than the one given above is + the handling of RTP's own "rollover counter", see Appendix A.1 of + [RFC3550]. + +3.3.2. Replay Protection + + Secure replay protection is only possible when integrity protection + is present. It is RECOMMENDED to use replay protection, both for RTP + and RTCP, as integrity protection alone cannot assure security + against replay attacks. + + A packet is "replayed" when it is stored by an adversary, and then + re-injected into the network. When message authentication is + provided, SRTP protects against such attacks through a Replay List. + Each SRTP receiver maintains a Replay List, which conceptually + contains the indices of all of the packets which have been received + and authenticated. In practice, the list can use a "sliding window" + approach, so that a fixed amount of storage suffices for replay + protection. Packet indices which lag behind the packet index in the + context by more than SRTP-WINDOW-SIZE can be assumed to have been + received, where SRTP-WINDOW-SIZE is a receiver-side, implementation- + dependent parameter and MUST be at least 64, but which MAY be set to + a higher value. + + The receiver checks the index of an incoming packet against the + replay list and the window. Only packets with index ahead of the + window, or, inside the window but not already received, SHALL be + accepted. + + After the packet has been authenticated (if necessary the window is + first moved ahead), the replay list SHALL be updated with the new + index. + + The Replay List can be efficiently implemented by using a bitmap to + represent which packets have been received, as described in the + Security Architecture for IP [RFC2401]. + +3.4. Secure RTCP + + Secure RTCP follows the definition of Secure RTP. SRTCP adds three + mandatory new fields (the SRTCP index, an "encrypt-flag", and the + authentication tag) and one optional field (the MKI) to the RTCP + packet definition. The three mandatory fields MUST be appended to an + RTCP packet in order to form an equivalent SRTCP packet. The added + fields follow any other profile-specific extensions. + + + + + + +Baugher, et al. Standards Track [Page 15] + +RFC 3711 SRTP March 2004 + + + According to Section 6.1 of [RFC3550], there is a REQUIRED packet + format for compound packets. SRTCP MUST be given packets according + to that requirement in the sense that the first part MUST be a sender + report or a receiver report. However, the RTCP encryption prefix (a + random 32-bit quantity) specified in that Section MUST NOT be used + since, as is stated there, it is only applicable to the encryption + method specified in [RFC3550] and is not needed by the cryptographic + mechanisms used in SRTP. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+ + |V=2|P| RC | PT=SR or RR | length | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | SSRC of sender | | + +>+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | + | ~ sender info ~ | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | ~ report block 1 ~ | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | ~ report block 2 ~ | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | ~ ... ~ | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | |V=2|P| SC | PT=SDES=202 | length | | + | +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | + | | SSRC/CSRC_1 | | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | ~ SDES items ~ | + | +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | + | ~ ... ~ | + +>+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | + | |E| SRTCP index | | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+ + | ~ SRTCP MKI (OPTIONAL) ~ | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | : authentication tag : | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | + | | + +-- Encrypted Portion Authenticated Portion -----+ + + + Figure 2. An example of the format of a Secure RTCP packet, + consisting of an underlying RTCP compound packet with a Sender Report + and SDES packet. + + + + + + +Baugher, et al. Standards Track [Page 16] + +RFC 3711 SRTP March 2004 + + + The Encrypted Portion of an SRTCP packet consists of the encryption + (Section 4.1) of the RTCP payload of the equivalent compound RTCP + packet, from the first RTCP packet, i.e., from the ninth (9) octet to + the end of the compound packet. The Authenticated Portion of an + SRTCP packet consists of the entire equivalent (eventually compound) + RTCP packet, the E flag, and the SRTCP index (after any encryption + has been applied to the payload). + + The added fields are: + + E-flag: 1 bit, REQUIRED + The E-flag indicates if the current SRTCP packet is + encrypted or unencrypted. Section 9.1 of [RFC3550] allows + the split of a compound RTCP packet into two lower-layer + packets, one to be encrypted and one to be sent in the + clear. The E bit set to "1" indicates encrypted packet, and + "0" indicates non-encrypted packet. + + SRTCP index: 31 bits, REQUIRED + The SRTCP index is a 31-bit counter for the SRTCP packet. + The index is explicitly included in each packet, in contrast + to the "implicit" index approach used for SRTP. The SRTCP + index MUST be set to zero before the first SRTCP packet is + sent, and MUST be incremented by one, modulo 2^31, after + each SRTCP packet is sent. In particular, after a re-key, + the SRTCP index MUST NOT be reset to zero again. + + Authentication Tag: configurable length, REQUIRED + The authentication tag is used to carry message + authentication data. + + MKI: configurable length, OPTIONAL + The MKI is the Master Key Indicator, and functions according + to the MKI definition in Section 3. + + SRTCP uses the cryptographic context parameters and packet processing + of SRTP by default, with the following changes: + + * The receiver does not need to "estimate" the index, as it is + explicitly signaled in the packet. + + * Pre-defined SRTCP encryption is as specified in Section 4.1, but + using the definition of the SRTCP Encrypted Portion given in this + section, and using the SRTCP index as the index i. The encryption + transform and related parameters SHALL by default be the same + selected for the protection of the associated SRTP stream(s), + while the NULL algorithm SHALL be applied to the RTCP packets not + to be encrypted. SRTCP may have a different encryption transform + + + +Baugher, et al. Standards Track [Page 17] + +RFC 3711 SRTP March 2004 + + + than the one used by the corresponding SRTP. The expected use for + this feature is when the former has NULL-encryption and the latter + has a non NULL-encryption. + + The E-flag is assigned a value by the sender depending on whether the + packet was encrypted or not. + + * SRTCP decryption is performed as in Section 4, but only if the E + flag is equal to 1. If so, the Encrypted Portion is decrypted, + using the SRTCP index as the index i. In case the E-flag is 0, + the payload is simply left unmodified. + + * SRTCP replay protection is as defined in Section 3.3.2, but using + the SRTCP index as the index i and a separate Replay List that is + specific to SRTCP. + + * The pre-defined SRTCP authentication tag is specified as in + Section 4.2, but with the Authenticated Portion of the SRTCP + packet given in this section (which includes the index). The + authentication transform and related parameters (e.g., key size) + SHALL by default be the same as selected for the protection of the + associated SRTP stream(s). + + * In the last step of the processing, only the sender needs to + update the value of the SRTCP index by incrementing it modulo 2^31 + and for security reasons the sender MUST also check the number of + SRTCP packets processed, see Section 9.2. + + Message authentication for RTCP is REQUIRED, as it is the control + protocol (e.g., it has a BYE packet) for RTP. + + Precautions must be taken so that the packet expansion in SRTCP (due + to the added fields) does not cause SRTCP messages to use more than + their share of RTCP bandwidth. To avoid this, the following two + measures MUST be taken: + + 1. When initializing the RTCP variable "avg_rtcp_size" defined in + chapter 6.3 of [RFC3550], it MUST include the size of the fields + that will be added by SRTCP (index, E-bit, authentication tag, and + when present, the MKI). + + 2. When updating the "avg_rtcp_size" using the variable "packet_size" + (section 6.3.3 of [RFC3550]), the value of "packet_size" MUST + include the size of the additional fields added by SRTCP. + + + + + + + +Baugher, et al. Standards Track [Page 18] + +RFC 3711 SRTP March 2004 + + + With these measures in place the SRTCP messages will not use more + than the allotted bandwidth. The effect of the size of the added + fields on the SRTCP traffic will be that messages will be sent with + longer packet intervals. The increase in the intervals will be + directly proportional to size of the added fields. For the pre- + defined transforms, the size of the added fields will be at least 14 + octets, and upper bounded depending on MKI and the authentication tag + sizes. + +4. Pre-Defined Cryptographic Transforms + + While there are numerous encryption and message authentication + algorithms that can be used in SRTP, below we define default + algorithms in order to avoid the complexity of specifying the + encodings for the signaling of algorithm and parameter identifiers. + The defined algorithms have been chosen as they fulfill the goals + listed in Section 2. Recommendations on how to extend SRTP with new + transforms are given in Section 6. + +4.1. Encryption + + The following parameters are common to both pre-defined, non-NULL, + encryption transforms specified in this section. + + * BLOCK_CIPHER-MODE indicates the block cipher used and its mode of + operation + * n_b is the bit-size of the block for the block cipher + * k_e is the session encryption key + * n_e is the bit-length of k_e + * k_s is the session salting key + * n_s is the bit-length of k_s + * SRTP_PREFIX_LENGTH is the octet length of the keystream prefix, a + non-negative integer, specified by the message authentication code + in use. + + The distinct session keys and salts for SRTP/SRTCP are by default + derived as specified in Section 4.3. + + The encryption transforms defined in SRTP map the SRTP packet index + and secret key into a pseudo-random keystream segment. Each + keystream segment encrypts a single RTP packet. The process of + encrypting a packet consists of generating the keystream segment + corresponding to the packet, and then bitwise exclusive-oring that + keystream segment onto the payload of the RTP packet to produce the + Encrypted Portion of the SRTP packet. In case the payload size is + not an integer multiple of n_b bits, the excess (least significant) + bits of the keystream are simply discarded. Decryption is done the + same way, but swapping the roles of the plaintext and ciphertext. + + + +Baugher, et al. Standards Track [Page 19] + +RFC 3711 SRTP March 2004 + + + +----+ +------------------+---------------------------------+ + | KG |-->| Keystream Prefix | Keystream Suffix |---+ + +----+ +------------------+---------------------------------+ | + | + +---------------------------------+ v + | Payload of RTP Packet |->(*) + +---------------------------------+ | + | + +---------------------------------+ | + | Encrypted Portion of SRTP Packet|<--+ + +---------------------------------+ + + Figure 3: Default SRTP Encryption Processing. Here KG denotes the + keystream generator, and (*) denotes bitwise exclusive-or. + + The definition of how the keystream is generated, given the index, + depends on the cipher and its mode of operation. Below, two such + keystream generators are defined. The NULL cipher is also defined, + to be used when encryption of RTP is not required. + + The SRTP definition of the keystream is illustrated in Figure 3. The + initial octets of each keystream segment MAY be reserved for use in a + message authentication code, in which case the keystream used for + encryption starts immediately after the last reserved octet. The + initial reserved octets are called the "keystream prefix" (not to be + confused with the "encryption prefix" of [RFC3550, Section 6.1]), and + the remaining octets are called the "keystream suffix". The + keystream prefix MUST NOT be used for encryption. The process is + illustrated in Figure 3. + + The number of octets in the keystream prefix is denoted as + SRTP_PREFIX_LENGTH. The keystream prefix is indicated by a positive, + non-zero value of SRTP_PREFIX_LENGTH. This means that, even if + confidentiality is not to be provided, the keystream generator output + may still need to be computed for packet authentication, in which + case the default keystream generator (mode) SHALL be used. + + The default cipher is the Advanced Encryption Standard (AES) [AES], + and we define two modes of running AES, (1) Segmented Integer Counter + Mode AES and (2) AES in f8-mode. In the remainder of this section, + let E(k,x) be AES applied to key k and input block x. + + + + + + + + + + +Baugher, et al. Standards Track [Page 20] + +RFC 3711 SRTP March 2004 + + +4.1.1. AES in Counter Mode + + Conceptually, counter mode [AES-CTR] consists of encrypting + successive integers. The actual definition is somewhat more + complicated, in order to randomize the starting point of the integer + sequence. Each packet is encrypted with a distinct keystream + segment, which SHALL be computed as follows. + + A keystream segment SHALL be the concatenation of the 128-bit output + blocks of the AES cipher in the encrypt direction, using key k = k_e, + in which the block indices are in increasing order. Symbolically, + each keystream segment looks like + + E(k, IV) || E(k, IV + 1 mod 2^128) || E(k, IV + 2 mod 2^128) ... + + where the 128-bit integer value IV SHALL be defined by the SSRC, the + SRTP packet index i, and the SRTP session salting key k_s, as below. + + IV = (k_s * 2^16) XOR (SSRC * 2^64) XOR (i * 2^16) + + Each of the three terms in the XOR-sum above is padded with as many + leading zeros as needed to make the operation well-defined, + considered as a 128-bit value. + + The inclusion of the SSRC allows the use of the same key to protect + distinct SRTP streams within the same RTP session, see the security + caveats in Section 9.1. + + In the case of SRTCP, the SSRC of the first header of the compound + packet MUST be used, i SHALL be the 31-bit SRTCP index and k_e, k_s + SHALL be replaced by the SRTCP encryption session key and salt. + + Note that the initial value, IV, is fixed for each packet and is + formed by "reserving" 16 zeros in the least significant bits for the + purpose of the counter. The number of blocks of keystream generated + for any fixed value of IV MUST NOT exceed 2^16 to avoid keystream + re-use, see below. The AES has a block size of 128 bits, so 2^16 + output blocks are sufficient to generate the 2^23 bits of keystream + needed to encrypt the largest possible RTP packet (except for IPv6 + "jumbograms" [RFC2675], which are not likely to be used for RTP-based + multimedia traffic). This restriction on the maximum bit-size of the + packet that can be encrypted ensures the security of the encryption + method by limiting the effectiveness of probabilistic attacks [BDJR]. + + For a particular Counter Mode key, each IV value used as an input + MUST be distinct, in order to avoid the security exposure of a two- + time pad situation (Section 9.1). To satisfy this constraint, an + implementation MUST ensure that the combination of the SRTP packet + + + +Baugher, et al. Standards Track [Page 21] + +RFC 3711 SRTP March 2004 + + + index of ROC || SEQ, and the SSRC used in the construction of the IV + are distinct for any particular key. The failure to ensure this + uniqueness could be catastrophic for Secure RTP. This is in contrast + to the situation for RTP itself, which may be able to tolerate such + failures. It is RECOMMENDED that, if a dedicated security module is + present, the RTP sequence numbers and SSRC either be generated or + checked by that module (i.e., sequence-number and SSRC processing in + an SRTP system needs to be protected as well as the key). + +4.1.2. AES in f8-mode + + To encrypt UMTS (Universal Mobile Telecommunications System, as 3G + networks) data, a solution (see [f8-a] [f8-b]) known as the f8- + algorithm has been developed. On a high level, the proposed scheme + is a variant of Output Feedback Mode (OFB) [HAC], with a more + elaborate initialization and feedback function. As in normal OFB, + the core consists of a block cipher. We also define here the use of + AES as a block cipher to be used in what we shall call "f8-mode of + operation" RTP encryption. The AES f8-mode SHALL use the same + default sizes for session key and salt as AES counter mode. + + Figure 4 shows the structure of block cipher, E, running in f8-mode. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Baugher, et al. Standards Track [Page 22] + +RFC 3711 SRTP March 2004 + + + IV + | + v + +------+ + | | + +--->| E | + | +------+ + | | + m -> (*) +-----------+-------------+-- ... ------+ + | IV' | | | | + | | j=1 -> (*) j=2 -> (*) ... j=L-1 ->(*) + | | | | | + | | +-> (*) +-> (*) ... +-> (*) + | | | | | | | | + | v | v | v | v + | +------+ | +------+ | +------+ | +------+ + k_e ---+--->| E | | | E | | | E | | | E | + | | | | | | | | | | | + +------+ | +------+ | +------+ | +------+ + | | | | | | | + +------+ +--------+ +-- ... ----+ | + | | | | + v v v v + S(0) S(1) S(2) . . . S(L-1) + + Figure 4. f8-mode of operation (asterisk, (*), denotes bitwise XOR). + The figure represents the KG in Figure 3, when AES-f8 is used. + +4.1.2.1. f8 Keystream Generation + + The Initialization Vector (IV) SHALL be determined as described in + Section 4.1.2.2 (and in Section 4.1.2.3 for SRTCP). + + Let IV', S(j), and m denote n_b-bit blocks. The keystream, + S(0) ||... || S(L-1), for an N-bit message SHALL be defined by + setting IV' = E(k_e XOR m, IV), and S(-1) = 00..0. For + j = 0,1,..,L-1 where L = N/n_b (rounded up to nearest integer if it + is not already an integer) compute + + S(j) = E(k_e, IV' XOR j XOR S(j-1)) + + Notice that the IV is not used directly. Instead it is fed through E + under another key to produce an internal, "masked" value (denoted + IV') to prevent an attacker from gaining known input/output pairs. + + + + + + + +Baugher, et al. Standards Track [Page 23] + +RFC 3711 SRTP March 2004 + + + The role of the internal counter, j, is to prevent short keystream + cycles. The value of the key mask m SHALL be + + m = k_s || 0x555..5, + + i.e., the session salting key, appended by the binary pattern 0101.. + to fill out the entire desired key size, n_e. + + The sender SHOULD NOT generate more than 2^32 blocks, which is + sufficient to generate 2^39 bits of keystream. Unlike counter mode, + there is no absolute threshold above (below) which f8 is guaranteed + to be insecure (secure). The above bound has been chosen to limit, + with sufficient security margin, the probability of degenerative + behavior in the f8 keystream generation. + +4.1.2.2. f8 SRTP IV Formation + + The purpose of the following IV formation is to provide a feature + which we call implicit header authentication (IHA), see Section 9.5. + + The SRTP IV for 128-bit block AES-f8 SHALL be formed in the following + way: + + IV = 0x00 || M || PT || SEQ || TS || SSRC || ROC + + M, PT, SEQ, TS, SSRC SHALL be taken from the RTP header; ROC is from + the cryptographic context. + + The presence of the SSRC as part of the IV allows AES-f8 to be used + when a master key is shared between multiple streams within the same + RTP session, see Section 9.1. + +4.1.2.3. f8 SRTCP IV Formation + + The SRTCP IV for 128-bit block AES-f8 SHALL be formed in the + following way: + + IV= 0..0 || E || SRTCP index || V || P || RC || PT || length || SSRC + + where V, P, RC, PT, length, SSRC SHALL be taken from the first header + in the RTCP compound packet. E and SRTCP index are the 1-bit and + 31-bit fields added to the packet. + + + + + + + + + +Baugher, et al. Standards Track [Page 24] + +RFC 3711 SRTP March 2004 + + +4.1.3. NULL Cipher + + The NULL cipher is used when no confidentiality for RTP/RTCP is + requested. The keystream can be thought of as "000..0", i.e., the + encryption SHALL simply copy the plaintext input into the ciphertext + output. + +4.2. Message Authentication and Integrity + + Throughout this section, M will denote data to be integrity + protected. In the case of SRTP, M SHALL consist of the Authenticated + Portion of the packet (as specified in Figure 1) concatenated with + the ROC, M = Authenticated Portion || ROC; in the case of SRTCP, M + SHALL consist of the Authenticated Portion (as specified in Figure 2) + only. + + Common parameters: + + * AUTH_ALG is the authentication algorithm + * k_a is the session message authentication key + * n_a is the bit-length of the authentication key + * n_tag is the bit-length of the output authentication tag + * SRTP_PREFIX_LENGTH is the octet length of the keystream prefix as + defined above, a parameter of AUTH_ALG + + The distinct session authentication keys for SRTP/SRTCP are by + default derived as specified in Section 4.3. + + The values of n_a, n_tag, and SRTP_PREFIX_LENGTH MUST be fixed for + any particular fixed value of the key. + + We describe the process of computing authentication tags as follows. + The sender computes the tag of M and appends it to the packet. The + SRTP receiver verifies a message/authentication tag pair by computing + a new authentication tag over M using the selected algorithm and key, + and then compares it to the tag associated with the received message. + If the two tags are equal, then the message/tag pair is valid; + otherwise, it is invalid and the error audit message "AUTHENTICATION + FAILURE" MUST be returned. + +4.2.1. HMAC-SHA1 + + The pre-defined authentication transform for SRTP is HMAC-SHA1 + [RFC2104]. With HMAC-SHA1, the SRTP_PREFIX_LENGTH (Figure 3) SHALL + be 0. For SRTP (respectively SRTCP), the HMAC SHALL be applied to + the session authentication key and M as specified above, i.e., + HMAC(k_a, M). The HMAC output SHALL then be truncated to the n_tag + left-most bits. + + + +Baugher, et al. Standards Track [Page 25] + +RFC 3711 SRTP March 2004 + + +4.3. Key Derivation + +4.3.1. Key Derivation Algorithm + + Regardless of the encryption or message authentication transform that + is employed (it may be an SRTP pre-defined transform or newly + introduced according to Section 6), interoperable SRTP + implementations MUST use the SRTP key derivation to generate session + keys. Once the key derivation rate is properly signaled at the start + of the session, there is no need for extra communication between the + parties that use SRTP key derivation. + + packet index ---+ + | + v + +-----------+ master +--------+ session encr_key + | ext | key | |----------> + | key mgmt |-------->| key | session auth_key + | (optional | | deriv |----------> + | rekey) |-------->| | session salt_key + | | master | |----------> + +-----------+ salt +--------+ + + Figure 5: SRTP key derivation. + + At least one initial key derivation SHALL be performed by SRTP, i.e., + the first key derivation is REQUIRED. Further applications of the + key derivation MAY be performed, according to the + "key_derivation_rate" value in the cryptographic context. The key + derivation function SHALL initially be invoked before the first + packet and then, when r > 0, a key derivation is performed whenever + index mod r equals zero. This can be thought of as "refreshing" the + session keys. The value of "key_derivation_rate" MUST be kept fixed + for the lifetime of the associated master key. + + Interoperable SRTP implementations MAY also derive session salting + keys for encryption transforms, as is done in both of the pre- + defined transforms. + + Let m and n be positive integers. A pseudo-random function family is + a set of keyed functions {PRF_n(k,x)} such that for the (secret) + random key k, given m-bit x, PRF_n(k,x) is an n-bit string, + computationally indistinguishable from random n-bit strings, see + [HAC]. For the purpose of key derivation in SRTP, a secure PRF with + m = 128 (or more) MUST be used, and a default PRF transform is + defined in Section 4.3.3. + + + + + +Baugher, et al. Standards Track [Page 26] + +RFC 3711 SRTP March 2004 + + + Let "a DIV t" denote integer division of a by t, rounded down, and + with the convention that "a DIV 0 = 0" for all a. We also make the + convention of treating "a DIV t" as a bit string of the same length + as a, and thus "a DIV t" will in general have leading zeros. + + Key derivation SHALL be defined as follows in terms of <label>, an + 8-bit constant (see below), master_salt and key_derivation_rate, as + determined in the cryptographic context, and index, the packet index + (i.e., the 48-bit ROC || SEQ for SRTP): + + * Let r = index DIV key_derivation_rate (with DIV as defined above). + + * Let key_id = <label> || r. + + * Let x = key_id XOR master_salt, where key_id and master_salt are + aligned so that their least significant bits agree (right- + alignment). + + <label> MUST be unique for each type of key to be derived. We + currently define <label> 0x00 to 0x05 (see below), and future + extensions MAY specify new values in the range 0x06 to 0xff for other + purposes. The n-bit SRTP key (or salt) for this packet SHALL then be + derived from the master key, k_master as follows: + + PRF_n(k_master, x). + + (The PRF may internally specify additional formatting and padding of + x, see e.g., Section 4.3.3 for the default PRF.) + + The session keys and salt SHALL now be derived using: + + - k_e (SRTP encryption): <label> = 0x00, n = n_e. + + - k_a (SRTP message authentication): <label> = 0x01, n = n_a. + + - k_s (SRTP salting key): <label> = 0x02, n = n_s. + + where n_e, n_s, and n_a are from the cryptographic context. + + The master key and master salt MUST be random, but the master salt + MAY be public. + + Note that for a key_derivation_rate of 0, the application of the key + derivation SHALL take place exactly once. + + The definition of DIV above is purely for notational convenience. + For a non-zero t among the set of allowed key derivation rates, "a + DIV t" can be implemented as a right-shift by the base-2 logarithm of + + + +Baugher, et al. Standards Track [Page 27] + +RFC 3711 SRTP March 2004 + + + t. The derivation operation is further facilitated if the rates are + chosen to be powers of 256, but that granularity was considered too + coarse to be a requirement of this specification. + + The upper limit on the number of packets that can be secured using + the same master key (see Section 9.2) is independent of the key + derivation. + +4.3.2. SRTCP Key Derivation + + SRTCP SHALL by default use the same master key (and master salt) as + SRTP. To do this securely, the following changes SHALL be done to + the definitions in Section 4.3.1 when applying session key derivation + for SRTCP. + + Replace the SRTP index by the 32-bit quantity: 0 || SRTCP index + (i.e., excluding the E-bit, replacing it with a fixed 0-bit), and use + <label> = 0x03 for the SRTCP encryption key, <label> = 0x04 for the + SRTCP authentication key, and, <label> = 0x05 for the SRTCP salting + key. + +4.3.3. AES-CM PRF + + The currently defined PRF, keyed by 128, 192, or 256 bit master key, + has input block size m = 128 and can produce n-bit outputs for n up + to 2^23. PRF_n(k_master,x) SHALL be AES in Counter Mode as described + in Section 4.1.1, applied to key k_master, and IV equal to (x*2^16), + and with the output keystream truncated to the n first (left-most) + bits. (Requiring n/128, rounded up, applications of AES.) + +5. Default and mandatory-to-implement Transforms + + The default transforms also are mandatory-to-implement transforms in + SRTP. Of course, "mandatory-to-implement" does not imply + "mandatory-to-use". Table 1 summarizes the pre-defined transforms. + The default values below are valid for the pre-defined transforms. + + mandatory-to-impl. optional default + + encryption AES-CM, NULL AES-f8 AES-CM + message integrity HMAC-SHA1 - HMAC-SHA1 + key derivation (PRF) AES-CM - AES-CM + + Table 1: Mandatory-to-implement, optional and default transforms in + SRTP and SRTCP. + + + + + + +Baugher, et al. Standards Track [Page 28] + +RFC 3711 SRTP March 2004 + + +5.1. Encryption: AES-CM and NULL + + AES running in Segmented Integer Counter Mode, as defined in Section + 4.1.1, SHALL be the default encryption algorithm. The default key + lengths SHALL be 128-bit for the session encryption key (n_e). The + default session salt key-length (n_s) SHALL be 112 bits. + + The NULL cipher SHALL also be mandatory-to-implement. + +5.2. Message Authentication/Integrity: HMAC-SHA1 + + HMAC-SHA1, as defined in Section 4.2.1, SHALL be the default message + authentication code. The default session authentication key-length + (n_a) SHALL be 160 bits, the default authentication tag length + (n_tag) SHALL be 80 bits, and the SRTP_PREFIX_LENGTH SHALL be zero + for HMAC-SHA1. In addition, for SRTCP, the pre-defined HMAC-SHA1 + MUST NOT be applied with a value of n_tag, nor n_a, that are smaller + than these defaults. For SRTP, smaller values are NOT RECOMMENDED, + but MAY be used after careful consideration of the issues in Section + 7.5 and 9.5. + +5.3. Key Derivation: AES-CM PRF + + The AES Counter Mode based key derivation and PRF defined in Sections + 4.3.1 to 4.3.3, using a 128-bit master key, SHALL be the default + method for generating session keys. The default master salt length + SHALL be 112 bits and the default key-derivation rate SHALL be zero. + +6. Adding SRTP Transforms + + Section 4 provides examples of the level of detail needed for + defining transforms. Whenever a new transform is to be added to + SRTP, a companion standard track RFC MUST be written to exactly + define how the new transform can be used with SRTP (and SRTCP). Such + a companion RFC SHOULD avoid overlap with the SRTP protocol document. + Note however, that it MAY be necessary to extend the SRTP or SRTCP + cryptographic context definition with new parameters (including fixed + or default values), add steps to the packet processing, or even add + fields to the SRTP/SRTCP packets. The companion RFC SHALL explain + any known issues regarding interactions between the transform and + other aspects of SRTP. + + Each new transform document SHOULD specify its key attributes, e.g., + size of keys (minimum, maximum, recommended), format of keys, + recommended/required processing of input keying material, + requirements/recommendations on key lifetime, re-keying and key + derivation, whether sharing of keys between SRTP and SRTCP is allowed + or not, etc. + + + +Baugher, et al. Standards Track [Page 29] + +RFC 3711 SRTP March 2004 + + + An added message integrity transform SHOULD define a minimum + acceptable key/tag size for SRTCP, equivalent in strength to the + minimum values as defined in Section 5.2. + +7. Rationale + + This section explains the rationale behind several important features + of SRTP. + +7.1. Key derivation + + Key derivation reduces the burden on the key establishment. As many + as six different keys are needed per crypto context (SRTP and SRTCP + encryption keys and salts, SRTP and SRTCP authentication keys), but + these are derived from a single master key in a cryptographically + secure way. Thus, the key management protocol needs to exchange only + one master key (plus master salt when required), and then SRTP itself + derives all the necessary session keys (via the first, mandatory + application of the key derivation function). + + Multiple applications of the key derivation function are optional, + but will give security benefits when enabled. They prevent an + attacker from obtaining large amounts of ciphertext produced by a + single fixed session key. If the attacker was able to collect a + large amount of ciphertext for a certain session key, he might be + helped in mounting certain attacks. + + Multiple applications of the key derivation function provide + backwards and forward security in the sense that a compromised + session key does not compromise other session keys derived from the + same master key. This means that the attacker who is able to recover + a certain session key, is anyway not able to have access to messages + secured under previous and later session keys (derived from the same + master key). (Note that, of course, a leaked master key reveals all + the session keys derived from it.) + + Considerations arise with high-rate key refresh, especially in large + multicast settings, see Section 11. + +7.2. Salting key + + The master salt guarantees security against off-line key-collision + attacks on the key derivation that might otherwise reduce the + effective key size [MF00]. + + + + + + + +Baugher, et al. Standards Track [Page 30] + +RFC 3711 SRTP March 2004 + + + The derived session salting key used in the encryption, has been + introduced to protect against some attacks on additive stream + ciphers, see Section 9.2. The explicit inclusion method of the salt + in the IV has been selected for ease of hardware implementation. + +7.3. Message Integrity from Universal Hashing + + The particular definition of the keystream given in Section 4.1 (the + keystream prefix) is to give provision for particular universal hash + functions, suitable for message authentication in the Wegman-Carter + paradigm [WC81]. Such functions are provably secure, simple, quick, + and especially appropriate for Digital Signal Processors and other + processors with a fast multiply operation. + + No authentication transforms are currently provided in SRTP other + than HMAC-SHA1. Future transforms, like the above mentioned + universal hash functions, MAY be added following the guidelines in + Section 6. + +7.4. Data Origin Authentication Considerations + + Note that in pair-wise communications, integrity and data origin + authentication are provided together. However, in group scenarios + where the keys are shared between members, the MAC tag only proves + that a member of the group sent the packet, but does not prevent + against a member impersonating another. Data origin authentication + (DOA) for multicast and group RTP sessions is a hard problem that + needs a solution; while some promising proposals are being + investigated [PCST1] [PCST2], more work is needed to rigorously + specify these technologies. Thus SRTP data origin authentication in + groups is for further study. + + DOA can be done otherwise using signatures. However, this has high + impact in terms of bandwidth and processing time, therefore we do not + offer this form of authentication in the pre-defined packet-integrity + transform. + + The presence of mixers and translators does not allow data origin + authentication in case the RTP payload and/or the RTP header are + manipulated. Note that these types of middle entities also disrupt + end-to-end confidentiality (as the IV formation depends e.g., on the + RTP header preservation). A certain trust model may choose to trust + the mixers/translators to decrypt/re-encrypt the media (this would + imply breaking the end-to-end security, with related security + implications). + + + + + + +Baugher, et al. Standards Track [Page 31] + +RFC 3711 SRTP March 2004 + + +7.5. Short and Zero-length Message Authentication + + As shown in Figure 1, the authentication tag is RECOMMENDED in SRTP. + A full 80-bit authentication-tag SHOULD be used, but a shorter tag or + even a zero-length tag (i.e., no message authentication) MAY be used + under certain conditions to support either of the following two + application environments. + + 1. Strong authentication can be impractical in environments where + bandwidth preservation is imperative. An important special + case is wireless communication systems, in which bandwidth is a + scarce and expensive resource. Studies have shown that for + certain applications and link technologies, additional bytes + may result in a significant decrease in spectrum efficiency + [SWO]. Considerable effort has been made to design IP header + compression techniques to improve spectrum efficiency + [RFC3095]. A typical voice application produces 20 byte + samples, and the RTP, UDP and IP headers need to be jointly + compressed to one or two bytes on average in order to obtain + acceptable wireless bandwidth economy [RFC3095]. In this case, + strong authentication would impose nearly fifty percent + overhead. + + 2. Authentication is impractical for applications that use data + links with fixed-width fields that cannot accommodate the + expansion due to the authentication tag. This is the case for + some important existing wireless channels. For example, zero- + byte header compression is used to adapt EVRC/SMV voice with + the legacy IS-95 bearer channel in CDMA2000 VoIP services. It + was found that not a single additional octet could be added to + the data, which motivated the creation of a zero-byte profile + for ROHC [RFC3242]. + + A short tag is secure for a restricted set of applications. Consider + a voice telephony application, for example, such as a G.729 audio + codec with a 20-millisecond packetization interval, protected by a + 32-bit message authentication tag. The likelihood of any given + packet being successfully forged is only one in 2^32. Thus an + adversary can control no more than 20 milliseconds of audio output + during a 994-day period, on average. In contrast, the effect of a + single forged packet can be much larger if the application is + stateful. A codec that uses relative or predictive compression + across packets will propagate the maliciously generated state, + affecting a longer duration of output. + + + + + + + +Baugher, et al. Standards Track [Page 32] + +RFC 3711 SRTP March 2004 + + + Certainly not all SRTP or telephony applications meet the criteria + for short or zero-length authentication tags. Section 9.5.1 + discusses the risks of weak or no message authentication, and section + 9.5 describes the circumstances when it is acceptable and when it is + unacceptable. + +8. Key Management Considerations + + There are emerging key management standards [MIKEY] [KEYMGT] [SDMS] + for establishing an SRTP cryptographic context (e.g., an SRTP master + key). Both proprietary and open-standard key management methods are + likely to be used for telephony applications [MIKEY] [KINK] and + multicast applications [GDOI]. This section provides guidance for + key management systems that service SRTP session. + + For initialization, an interoperable SRTP implementation SHOULD be + given the SSRC and MAY be given the initial RTP sequence number for + the RTP stream by key management (thus, key management has a + dependency on RTP operational parameters). Sending the RTP sequence + number in the key management may be useful e.g., when the initial + sequence number is close to wrapping (to avoid synchronization + problems), and to communicate the current sequence number to a + joining endpoint (to properly initialize its replay list). + + If the pre-defined transforms are used, SRTP allows sharing of the + same master key between SRTP/SRTCP streams belonging to the same RTP + session. + + First, sharing between SRTP streams belonging to the same RTP session + is secure if the design of the synchronization mechanism, i.e., the + IV, avoids keystream re-use (the two-time pad, Section 9.1). This is + taken care of by the fact that RTP provides for unique SSRCs for + streams belonging to the same RTP session. See Section 9.1 for + further discussion. + + Second, sharing between SRTP and the corresponding SRTCP is secure. + The fact that an SRTP stream and its associated SRTCP stream both + carry the same SSRC does not constitute a problem for the two-time + pad due to the key derivation. Thus, SRTP and SRTCP corresponding to + one RTP session MAY share master keys (as they do by default). + + Note that message authentication also has a dependency on SSRC + uniqueness that is unrelated to the problem of keystream reuse: SRTP + streams authenticated under the same key MUST have a distinct SSRC in + order to identify the sender of the message. This requirement is + needed because the SSRC is the cryptographically authenticated field + + + + + +Baugher, et al. Standards Track [Page 33] + +RFC 3711 SRTP March 2004 + + + used to distinguish between different SRTP streams. Were two streams + to use identical SSRC values, then an adversary could substitute + messages from one stream into the other without detection. + + SRTP/SRTCP MUST NOT share master keys under any other circumstances + than the ones given above, i.e., between SRTP and its corresponding + SRTCP, and, between streams belonging to the same RTP session. + +8.1. Re-keying + + The recommended way for a particular key management system to provide + re-key within SRTP is by associating a master key in a crypto context + with an MKI. + + This provides for easy master key retrieval (see Scenarios in Section + 11), but has the disadvantage of adding extra bits to each packet. + As noted in Section 7.5, some wireless links do not cater for added + bits, therefore SRTP also defines a more economic way of triggering + re-keying, via use of <From, To>, which works in some specific, + simple scenarios (see Section 8.1.1). + + SRTP senders SHALL count the amount of SRTP and SRTCP traffic being + used for a master key and invoke key management to re-key if needed + (Section 9.2). These interactions are defined by the key management + interface to SRTP and are not defined by this protocol specification. + +8.1.1. Use of the <From, To> for re-keying + + In addition to the use of the MKI, SRTP defines another optional + mechanism for master key retrieval, the <From, To>. The <From, To> + specifies the range of SRTP indices (a pair of sequence number and + ROC) within which a certain master key is valid, and is (when used) + part of the crypto context. By looking at the 48-bit SRTP index of + the current SRTP packet, the corresponding master key can be found by + determining which From-To interval it belongs to. For SRTCP, the + most recently observed/used SRTP index (which can be obtained from + the cryptographic context) is used for this purpose, even though + SRTCP has its own (31-bit) index (see caveat below). + + This method, compared to the MKI, has the advantage of identifying + the master key and defining its lifetime without adding extra bits to + each packet. This could be useful, as already noted, for some + wireless links that do not cater for added bits. However, its use + SHOULD be limited to specific, very simple scenarios. We recommend + to limit its use when the RTP session is a simple unidirectional or + bi-directional stream. This is because in case of multiple streams, + it is difficult to trigger the re-key based on the <From, To> of a + single RTP stream. For example, if several streams share a master + + + +Baugher, et al. Standards Track [Page 34] + +RFC 3711 SRTP March 2004 + + + key, there is no simple one-to-one correspondence between the index + sequence space of a certain stream, and the index sequence space on + which the <From, To> values are based. Consequently, when a master + key is shared between streams, one of these streams MUST be + designated by key management as the one whose index space defines the + re-keying points. Also, the re-key triggering on SRTCP is based on + the correspondent SRTP stream, i.e., when the SRTP stream changes the + master key, so does the correspondent SRTCP. This becomes obviously + more and more complex with multiple streams. + + The default values for the <From, To> are "from the first observed + packet" and "until further notice". However, the maximum limit of + SRTP/SRTCP packets that are sent under each given master/session key + (Section 9.2) MUST NOT be exceeded. + + In case the <From, To> is used as key retrieval, then the MKI is not + inserted in the packet (and its indicator in the crypto context is + zero). However, using the MKI does not exclude using <From, To> key + lifetime simultaneously. This can for instance be useful to signal + at the sender side at which point in time an MKI is to be made + active. + +8.2. Key Management parameters + + The table below lists all SRTP parameters that key management can + supply. For reference, it also provides a summary of the default and + mandatory-to-support values for an SRTP implementation as described + in Section 5. + + + + + + + + + + + + + + + + + + + + + + + +Baugher, et al. Standards Track [Page 35] + +RFC 3711 SRTP March 2004 + + + Parameter Mandatory-to-support Default + --------- -------------------- ------- + + SRTP and SRTCP encr transf. AES_CM, NULL AES_CM + (Other possible values: AES_f8) + + SRTP and SRTCP auth transf. HMAC-SHA1 HMAC-SHA1 + + SRTP and SRTCP auth params: + n_tag (tag length) 80 80 + SRTP prefix_length 0 0 + + Key derivation PRF AES_CM AES_CM + + Key material params + (for each master key): + master key length 128 128 + n_e (encr session key length) 128 128 + n_a (auth session key length) 160 160 + master salt key + length of the master salt 112 112 + n_s (session salt key length) 112 112 + key derivation rate 0 0 + + key lifetime + SRTP-packets-max-lifetime 2^48 2^48 + SRTCP-packets-max-lifetime 2^31 2^31 + from-to-lifetime <From, To> + MKI indicator 0 0 + length of the MKI 0 0 + value of the MKI + + Crypto context index params: + SSRC value + ROC + SEQ + SRTCP Index + Transport address + Port number + + Relation to other RTP profiles: + sender's order between FEC and SRTP FEC-SRTP FEC-SRTP + (see Section 10) + + + + + + + + +Baugher, et al. Standards Track [Page 36] + +RFC 3711 SRTP March 2004 + + +9. Security Considerations + +9.1. SSRC collision and two-time pad + + Any fixed keystream output, generated from the same key and index + MUST only be used to encrypt once. Re-using such keystream (jokingly + called a "two-time pad" system by cryptographers), can seriously + compromise security. The NSA's VENONA project [C99] provides a + historical example of such a compromise. It is REQUIRED that + automatic key management be used for establishing and maintaining + SRTP and SRTCP keying material; this requirement is to avoid + keystream reuse, which is more likely to occur with manual key + management. Furthermore, in SRTP, a "two-time pad" is avoided by + requiring the key, or some other parameter of cryptographic + significance, to be unique per RTP/RTCP stream and packet. The pre- + defined SRTP transforms accomplish packet-uniqueness by including the + packet index and stream-uniqueness by inclusion of the SSRC. + + The pre-defined transforms (AES-CM and AES-f8) allow master keys to + be shared across streams belonging to the same RTP session by the + inclusion of the SSRC in the IV. A master key MUST NOT be shared + among different RTP sessions. + + Thus, the SSRC MUST be unique between all the RTP streams within the + same RTP session that share the same master key. RTP itself provides + an algorithm for detecting SSRC collisions within the same RTP + session. Thus, temporary collisions could lead to temporary two-time + pad, in the unfortunate event that SSRCs collide at a point in time + when the streams also have identical sequence numbers (occurring with + probability roughly 2^(-48)). Therefore, the key management SHOULD + take care of avoiding such SSRC collisions by including the SSRCs to + be used in the session as negotiation parameters, proactively + assuring their uniqueness. This is a strong requirements in + scenarios where for example, there are multiple senders that can + start to transmit simultaneously, before SSRC collision are detected + at the RTP level. + + Note also that even with distinct SSRCs, extensive use of the same + key might improve chances of probabilistic collision and time- + memory-tradeoff attacks succeeding. + + As described, master keys MAY be shared between streams belonging to + the same RTP session, but it is RECOMMENDED that each SSRC have its + own master key. When master keys are shared among SSRC participants + and SSRCs are managed by a key management module as recommended + above, the RECOMMENDED policy for an SSRC collision error is for the + participant to leave the SRTP session as it is a sign of malfunction. + + + + +Baugher, et al. Standards Track [Page 37] + +RFC 3711 SRTP March 2004 + + +9.2. Key Usage + + The effective key size is determined (upper bounded) by the size of + the master key and, for encryption, the size of the salting key. Any + additive stream cipher is vulnerable to attacks that use statistical + knowledge about the plaintext source to enable key collision and + time-memory tradeoff attacks [MF00] [H80] [BS00]. These attacks take + advantage of commonalities among plaintexts, and provide a way for a + cryptanalyst to amortize the computational effort of decryption over + many keys, or over many bytes of output, thus reducing the effective + key size of the cipher. A detailed analysis of these attacks and + their applicability to the encryption of Internet traffic is provided + in [MF00]. In summary, the effective key size of SRTP when used in a + security system in which m distinct keys are used, is equal to the + key size of the cipher less the logarithm (base two) of m. + Protection against such attacks can be provided simply by increasing + the size of the keys used, which here can be accomplished by the use + of the salting key. Note that the salting key MUST be random but MAY + be public. A salt size of (the suggested) size 112 bits protects + against attacks in scenarios where at most 2^112 keys are in use. + This is sufficient for all practical purposes. + + Implementations SHOULD use keys that are as large as possible. + Please note that in many cases increasing the key size of a cipher + does not affect the throughput of that cipher. + + The use of the SRTP and SRTCP indices in the pre-defined transforms + fixes the maximum number of packets that can be secured with the same + key. This limit is fixed to 2^48 SRTP packets for an SRTP stream, + and 2^31 SRTCP packets, when SRTP and SRTCP are considered + independently. Due to for example re-keying, reaching this limit may + or may not coincide with wrapping of the indices, and thus the sender + MUST keep packet counts. However, when the session keys for related + SRTP and SRTCP streams are derived from the same master key (the + default behavior, Section 4.3), the upper bound that has to be + considered is in practice the minimum of the two quantities. That + is, when 2^48 SRTP packets or 2^31 SRTCP packets have been secured + with the same key (whichever occurs before), the key management MUST + be called to provide new master key(s) (previously stored and used + keys MUST NOT be used again), or the session MUST be terminated. If + a sender of RTCP discovers that the sender of SRTP (or SRTCP) has not + updated the master or session key prior to sending 2^48 SRTP (or 2^31 + SRTCP) packets belonging to the same SRTP (SRTCP) stream, it is up to + the security policy of the RTCP sender how to behave, e.g., whether + an RTCP BYE-packet should be sent and/or if the event should be + logged. + + + + + +Baugher, et al. Standards Track [Page 38] + +RFC 3711 SRTP March 2004 + + + Note: in most typical applications (assuming at least one RTCP packet + for every 128,000 RTP packets), it will be the SRTCP index that first + reaches the upper limit, although the time until this occurs is very + long: even at 200 SRTCP packets/sec, the 2^31 index space of SRTCP is + enough to secure approximately 4 months of communication. + + Note that if the master key is to be shared between SRTP streams + within the same RTP session (Section 9.1), although the above bounds + are on a per stream (i.e., per SSRC) basis, the sender MUST base re- + key decision on the stream whose sequence number space is the first + to be exhausted. + + Key derivation limits the amount of plaintext that is encrypted with + a fixed session key, and made available to an attacker for analysis, + but key derivation does not extend the master key's lifetime. To see + this, simply consider our requirements to avoid two-time pad: two + distinct packets MUST either be processed with distinct IVs, or with + distinct session keys, and both the distinctness of IV and of the + session keys are (for the pre-defined transforms) dependent on the + distinctness of the packet indices. + + Note that with the key derivation, the effective key size is at most + that of the master key, even if the derived session key is + considerably longer. With the pre-defined authentication transform, + the session authentication key is 160 bits, but the master key by + default is only 128 bits. This design choice was made to comply with + certain recommendations in [RFC2104] so that an existing HMAC + implementation can be plugged into SRTP without problems. Since the + default tag size is 80 bits, it is, for the applications in mind, + also considered acceptable from security point of view. Users having + concerns about this are RECOMMENDED to instead use a 192 bit master + key in the key derivation. It was, however, chosen not to mandate + 192-bit keys since existing AES implementations to be used in the + key-derivation may not always support key-lengths other than 128 + bits. Since AES is not defined (or properly analyzed) for use with + 160 bit keys it is NOT RECOMMENDED that ad-hoc key-padding schemes + are used to pad shorter keys to 192 or 256 bits. + +9.3. Confidentiality of the RTP Payload + + SRTP's pre-defined ciphers are "seekable" stream ciphers, i.e., + ciphers able to efficiently seek to arbitrary locations in their + keystream (so that the encryption or decryption of one packet does + not depend on preceding packets). By using seekable stream ciphers, + SRTP avoids the denial of service attacks that are possible on stream + ciphers that lack this property. It is important to be aware that, + as with any stream cipher, the exact length of the payload is + revealed by the encryption. This means that it may be possible to + + + +Baugher, et al. Standards Track [Page 39] + +RFC 3711 SRTP March 2004 + + + deduce certain "formatting bits" of the payload, as the length of the + codec output might vary due to certain parameter settings etc. This, + in turn, implies that the corresponding bit of the keystream can be + deduced. However, if the stream cipher is secure (counter mode and + f8 are provably secure under certain assumptions [BDJR] [KSYH] [IK]), + knowledge of a few bits of the keystream will not aid an attacker in + predicting subsequent keystream bits. Thus, the payload length (and + information deducible from this) will leak, but nothing else. + + As some RTP packet could contain highly predictable data, e.g., SID, + it is important to use a cipher designed to resist known plaintext + attacks (which is the current practice). + +9.4. Confidentiality of the RTP Header + + In SRTP, RTP headers are sent in the clear to allow for header + compression. This means that data such as payload type, + synchronization source identifier, and timestamp are available to an + eavesdropper. Moreover, since RTP allows for future extensions of + headers, we cannot foresee what kind of possibly sensitive + information might also be "leaked". + + SRTP is a low-cost method, which allows header compression to reduce + bandwidth. It is up to the endpoints' policies to decide about the + security protocol to employ. If one really needs to protect headers, + and is allowed to do so by the surrounding environment, then one + should also look at alternatives, e.g., IPsec [RFC2401]. + +9.5. Integrity of the RTP payload and header + + SRTP messages are subject to attacks on their integrity and source + identification, and these risks are discussed in Section 9.5.1. To + protect against these attacks, each SRTP stream SHOULD be protected + by HMAC-SHA1 [RFC2104] with an 80-bit output tag and a 160-bit key, + or a message authentication code with equivalent strength. Secure + RTP SHOULD NOT be used without message authentication, except under + the circumstances described in this section. It is important to note + that encryption algorithms, including AES Counter Mode and f8, do not + provide message authentication. SRTCP MUST NOT be used with weak (or + NULL) authentication. + + SRTP MAY be used with weak authentication (e.g., a 32-bit + authentication tag), or with no authentication (the NULL + authentication algorithm). These options allow SRTP to be used to + provide confidentiality in situations where + + * weak or null authentication is an acceptable security risk, and + * it is impractical to provide strong message authentication. + + + +Baugher, et al. Standards Track [Page 40] + +RFC 3711 SRTP March 2004 + + + These conditions are described below and in Section 7.5. Note that + both conditions MUST hold in order for weak or null authentication to + be used. The risks associated with exercising the weak or null + authentication options need to be considered by a security audit + prior to their use for a particular application or environment given + the risks, which are discussed in Section 9.5.1. + + Weak authentication is acceptable when the RTP application is such + that the effect of a small fraction of successful forgeries is + negligible. If the application is stateless, then the effect of a + single forged RTP packet is limited to the decoding of that + particular packet. Under this condition, the size of the + authentication tag MUST ensure that only a negligible fraction of the + packets passed to the RTP application by the SRTP receiver can be + forgeries. This fraction is negligible when an adversary, if given + control of the forged packets, is not able to make a significant + impact on the output of the RTP application (see the example of + Section 7.5). + + Weak or null authentication MAY be acceptable when it is unlikely + that an adversary can modify ciphertext so that it decrypts to an + intelligible value. One important case is when it is difficult for + an adversary to acquire the RTP plaintext data, since for many + codecs, an adversary that does not know the input signal cannot + manipulate the output signal in a controlled way. In many cases it + may be difficult for the adversary to determine the actual value of + the plaintext. For example, a hidden snooping device might be + required in order to know a live audio or video signal. The + adversary's signal must have a quality equivalent to or greater than + that of the signal under attack, since otherwise the adversary would + not have enough information to encode that signal with the codec used + by the victim. Plaintext prediction may also be especially difficult + for an interactive application such as a telephone call. + + Weak or null authentication MUST NOT be used when the RTP application + makes data forwarding or access control decisions based on the RTP + data. In such a case, an attacker may be able to subvert + confidentiality by causing the receiver to forward data to an + attacker. See Section 3 of [B96] for a real-life example of such + attacks. + + Null authentication MUST NOT be used when a replay attack, in which + an adversary stores packets then replays them later in the session, + could have a non-negligible impact on the receiver. An example of a + successful replay attack is the storing of the output of a + surveillance camera for a period of time, later followed by the + + + + + +Baugher, et al. Standards Track [Page 41] + +RFC 3711 SRTP March 2004 + + + injection of that output to the monitoring station to avoid + surveillance. Encryption does not protect against this attack, and + non-null authentication is REQUIRED in order to defeat it. + + If existential message forgery is an issue, i.e., when the accuracy + of the received data is of non-negligible importance, null + authentication MUST NOT be used. + +9.5.1. Risks of Weak or Null Message Authentication + + During a security audit considering the use of weak or null + authentication, it is important to keep in mind the following attacks + which are possible when no message authentication algorithm is used. + + An attacker who cannot predict the plaintext is still always able to + modify the message sent between the sender and the receiver so that + it decrypts to a random plaintext value, or to send a stream of bogus + packets to the receiver that will decrypt to random plaintext values. + This attack is essentially a denial of service attack, though in the + absence of message authentication, the RTP application will have + inputs that are bit-wise correlated with the true value. Some + multimedia codecs and common operating systems will crash when such + data are accepted as valid video data. This denial of service attack + may be a much larger threat than that due to an attacker dropping, + delaying, or re-ordering packets. + + An attacker who cannot predict the plaintext can still replay a + previous message with certainty that the receiver will accept it. + Applications with stateless codecs might be robust against this type + of attack, but for other, more complex applications these attacks may + be far more grave. + + An attacker who can predict the plaintext can modify the ciphertext + so that it will decrypt to any value of her choosing. With an + additive stream cipher, an attacker will always be able to change + individual bits. + + An attacker may be able to subvert confidentiality due to the lack of + authentication when a data forwarding or access control decision is + made on decrypted but unauthenticated plaintext. This is because the + receiver may be fooled into forwarding data to an attacker, leading + to an indirect breach of confidentiality (see Section 3 of [B96]). + This is because data-forwarding decisions are made on the decrypted + plaintext; information in the plaintext will determine to what subnet + (or process) the plaintext is forwarded in ESP [RFC2401] tunnel mode + (respectively, transport mode). When Secure RTP is used without + + + + + +Baugher, et al. Standards Track [Page 42] + +RFC 3711 SRTP March 2004 + + + message authentication, it should be verified that the application + does not make data forwarding or access control decisions based on + the decrypted plaintext. + + Some cipher modes of operation that require padding, e.g., standard + cipher block chaining (CBC) are very sensitive to attacks on + confidentiality if certain padding types are used in the absence of + integrity. The attack [V02] shows that this is indeed the case for + the standard RTP padding as discussed in reference to Figure 1, when + used together with CBC mode. Later transform additions to SRTP MUST + therefore carefully consider the risk of using this padding without + proper integrity protection. + +9.5.2. Implicit Header Authentication + + The IV formation of the f8-mode gives implicit authentication (IHA) + of the RTP header, even when message authentication is not used. + When IHA is used, an attacker that modifies the value of the RTP + header will cause the decryption process at the receiver to produce + random plaintext values. While this protection is not equivalent to + message authentication, it may be useful for some applications. + +10. Interaction with Forward Error Correction mechanisms + + The default processing when using Forward Error Correction (e.g., RFC + 2733) processing with SRTP SHALL be to perform FEC processing prior + to SRTP processing on the sender side and to perform SRTP processing + prior to FEC processing on the receiver side. Any change to this + ordering (reversing it, or, placing FEC between SRTP encryption and + SRTP authentication) SHALL be signaled out of band. + +11. Scenarios + + SRTP can be used as security protocol for the RTP/RTCP traffic in + many different scenarios. SRTP has a number of configuration + options, in particular regarding key usage, and can have impact on + the total performance of the application according to the way it is + used. Hence, the use of SRTP is dependent on the kind of scenario + and application it is used with. In the following, we briefly + illustrate some use cases for SRTP, and give some guidelines for + recommended setting of its options. + +11.1. Unicast + + A typical example would be a voice call or video-on-demand + application. + + + + + +Baugher, et al. Standards Track [Page 43] + +RFC 3711 SRTP March 2004 + + + Consider one bi-directional RTP stream, as one RTP session. It is + possible for the two parties to share the same master key in the two + directions according to the principles of Section 9.1. The first + round of the key derivation splits the master key into any or all of + the following session keys (according to the provided security + functions): + + SRTP_encr_key, SRTP_auth_key, SRTCP_encr_key, and SRTCP_auth key. + + (For simplicity, we omit discussion of the salts, which are also + derived.) In this scenario, it will in most cases suffice to have a + single master key with the default lifetime. This guarantees + sufficiently long lifetime of the keys and a minimum set of keys in + place for most practical purposes. Also, in this case RTCP + protection can be applied smoothly. Under these assumptions, use of + the MKI can be omitted. As the key-derivation in combination with + large difference in the packet rate in the respective directions may + require simultaneous storage of several session keys, if storage is + an issue, we recommended to use low-rate key derivation. + + The same considerations can be extended to the unicast scenario with + multiple RTP sessions, where each session would have a distinct + master key. + +11.2. Multicast (one sender) + + Just as with (unprotected) RTP, a scalability issue arises in big + groups due to the possibly very large amount of SRTCP Receiver + Reports that the sender might need to process. In SRTP, the sender + may have to keep state (the cryptographic context) for each receiver, + or more precisely, for the SRTCP used to protect Receiver Reports. + The overhead increases proportionally to the size of the group. In + particular, re-keying requires special concern, see below. + + Consider first a small group of receivers. There are a few possible + setups with the distribution of master keys among the receivers. + Given a single RTP session, one possibility is that the receivers + share the same master key as per Section 9.1 to secure all their + respective RTCP traffic. This shared master key could then be the + same one used by the sender to protect its outbound SRTP traffic. + Alternatively, it could be a master key shared only among the + receivers and used solely for their SRTCP traffic. Both alternatives + require the receivers to trust each other. + + Considering SRTCP and key storage, it is recommended to use low-rate + (or zero) key_derivation (except the mandatory initial one), so that + the sender does not need to store too many session keys (each SRTCP + stream might otherwise have a different session key at a given point + + + +Baugher, et al. Standards Track [Page 44] + +RFC 3711 SRTP March 2004 + + + in time, as the SRTCP sources send at different times). Thus, in + case key derivation is wanted for SRTP, the cryptographic context for + SRTP can be kept separate from the SRTCP crypto context, so that it + is possible to have a key_derivation_rate of 0 for SRTCP and a non- + zero value for SRTP. + + Use of the MKI for re-keying is RECOMMENDED for most applications + (see Section 8.1). + + If there are more than one SRTP/SRTCP stream (within the same RTP + session) that share the master key, the upper limit of 2^48 SRTP + packets / 2^31 SRTCP packets means that, before one of the streams + reaches its maximum number of packets, re-keying MUST be triggered on + ALL streams sharing the master key. (From strict security point of + view, only the stream reaching the maximum would need to be re-keyed, + but then the streams would no longer be sharing master key, which is + the intention.) A local policy at the sender side should force + rekeying in a way that the maximum packet limit is not reached on any + of the streams. Use of the MKI for re-keying is RECOMMENDED. + + In large multicast with one sender, the same considerations as for + the small group multicast hold. The biggest issue in this scenario + is the additional load placed at the sender side, due to the state + (cryptographic contexts) that has to be maintained for each receiver, + sending back RTCP Receiver Reports. At minimum, a replay window + might need to be maintained for each RTCP source. + +11.3. Re-keying and access control + + Re-keying may occur due to access control (e.g., when a member is + removed during a multicast RTP session), or for pure cryptographic + reasons (e.g., the key is at the end of its lifetime). When using + SRTP default transforms, the master key MUST be replaced before any + of the index spaces are exhausted for any of the streams protected by + one and the same master key. + + How key management re-keys SRTP implementations is out of scope, but + it is clear that there are straightforward ways to manage keys for a + multicast group. In one-sender multicast, for example, it is + typically the responsibility of the sender to determine when a new + key is needed. The sender is the one entity that can keep track of + when the maximum number of packets has been sent, as receivers may + join and leave the session at any time, there may be packet loss and + delay etc. In scenarios other than one-sender multicast, other + methods can be used. Here, one must take into consideration that key + exchange can be a costly operation, taking several seconds for a + single exchange. Hence, some time before the master key is + exhausted/expires, out-of-band key management is initiated, resulting + + + +Baugher, et al. Standards Track [Page 45] + +RFC 3711 SRTP March 2004 + + + in a new master key that is shared with the receiver(s). In any + event, to maintain synchronization when switching to the new key, + group policy might choose between using the MKI and the <From, To>, + as described in Section 8.1. + + For access control purposes, the <From, To> periods are set at the + desired granularity, dependent on the packet rate. High rate re- + keying can be problematic for SRTCP in some large-group scenarios. + As mentioned, there are potential problems in using the SRTP index, + rather than the SRTCP index, for determining the master key. In + particular, for short periods during switching of master keys, it may + be the case that SRTCP packets are not under the current master key + of the correspondent SRTP. Therefore, using the MKI for re-keying in + such scenarios will produce better results. + +11.4. Summary of basic scenarios + + The description of these scenarios highlights some recommendations on + the use of SRTP, mainly related to re-keying and large scale + multicast: + + - Do not use fast re-keying with the <From, To> feature. It may, in + particular, give problems in retrieving the correct SRTCP key, if + an SRTCP packet arrives close to the re-keying time. The MKI + SHOULD be used in this case. + + - If multiple SRTP streams in the same RTP session share the same + master key, also moderate rate re-keying MAY have the same + problems, and the MKI SHOULD be used. + + - Though offering increased security, a non-zero key_derivation_rate + is NOT RECOMMENDED when trying to minimize the number of keys in + use with multiple streams. + +12. IANA Considerations + + The RTP specification establishes a registry of profile names for use + by higher-level control protocols, such as the Session Description + Protocol (SDP), to refer to transport methods. This profile + registers the name "RTP/SAVP". + + SRTP uses cryptographic transforms which a key management protocol + signals. It is the task of each particular key management protocol + to register the cryptographic transforms or suites of transforms with + IANA. The key management protocol conveys these protocol numbers, + not SRTP, and each key management protocol chooses the numbering + scheme and syntax that it requires. + + + + +Baugher, et al. Standards Track [Page 46] + +RFC 3711 SRTP March 2004 + + + Specification of a key management protocol for SRTP is out of scope + here. Section 8.2, however, provides guidance on the parameters that + need to be defined for the default and mandatory transforms. + +13. Acknowledgements + + David Oran (Cisco) and Rolf Blom (Ericsson) are co-authors of this + document but their valuable contributions are acknowledged here to + keep the length of the author list down. + + The authors would in addition like to thank Magnus Westerlund, Brian + Weis, Ghyslain Pelletier, Morgan Lindqvist, Robert Fairlie- + Cuninghame, Adrian Perrig, the AVT WG and in particular the chairmen + Colin Perkins and Stephen Casner, the Transport and Security Area + Directors, and Eric Rescorla for their reviews and support. + +14. References + +14.1. Normative References + + [AES] NIST, "Advanced Encryption Standard (AES)", FIPS PUB 197, + http://www.nist.gov/aes/ + + [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed- + Hashing for Message Authentication", RFC 2104, February + 1997. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC2401] Kent, S. and R. Atkinson, "Security Architecture for + Internet Protocol", RFC 2401, November 1998. + + [RFC2828] Shirey, R., "Internet Security Glossary", FYI 36, RFC 2828, + May 2000. + + [RFC3550] Schulzrinne, H., Casner, S., Frederick, R. and V. Jacobson, + "RTP: A Transport Protocol for Real-time Applications", RFC + 3550, July 2003. + + [RFC3551] Schulzrinne, H. and S. Casner, "RTP Profile for Audio and + Video Conferences with Minimal Control", RFC 3551, July + 2003. + + + + + + + + +Baugher, et al. Standards Track [Page 47] + +RFC 3711 SRTP March 2004 + + +14.2. Informative References + + [AES-CTR] Lipmaa, H., Rogaway, P. and D. Wagner, "CTR-Mode + Encryption", NIST, http://csrc.nist.gov/encryption/modes/ + workshop1/papers/lipmaa-ctr.pdf + + [B96] Bellovin, S., "Problem Areas for the IP Security + Protocols," in Proceedings of the Sixth Usenix Unix + Security Symposium, pp. 1-16, San Jose, CA, July 1996 + (http://www.research.att.com/~smb/papers/index.html). + + [BDJR] Bellare, M., Desai, A., Jokipii, E. and P. Rogaway, "A + Concrete Treatment of Symmetric Encryption: Analysis of DES + Modes of Operation", Proceedings 38th IEEE FOCS, pp. 394- + 403, 1997. + + [BS00] Biryukov, A. and A. Shamir, "Cryptanalytic Time/Memory/Data + Tradeoffs for Stream Ciphers", Proceedings, ASIACRYPT 2000, + LNCS 1976, pp. 1-13, Springer Verlag. + + [C99] Crowell, W. P., "Introduction to the VENONA Project", + http://www.nsa.gov:8080/docs/venona/index.html. + + [CTR] Dworkin, M., NIST Special Publication 800-38A, + "Recommendation for Block Cipher Modes of Operation: + Methods and Techniques", 2001. + http://csrc.nist.gov/publications/nistpubs/800-38a/sp800- + 38a.pdf. + + [f8-a] 3GPP TS 35.201 V4.1.0 (2001-12) Technical Specification 3rd + Generation Partnership Project; Technical Specification + Group Services and System Aspects; 3G Security; + Specification of the 3GPP Confidentiality and Integrity + Algorithms; Document 1: f8 and f9 Specification (Release + 4). + + [f8-b] 3GPP TR 33.908 V4.0.0 (2001-09) Technical Report 3rd + Generation Partnership Project; Technical Specification + Group Services and System Aspects; 3G Security; General + Report on the Design, Specification and Evaluation of 3GPP + Standard Confidentiality and Integrity Algorithms (Release + 4). + + [GDOI] Baugher, M., Weis, B., Hardjono, T. and H. Harney, "The + Group Domain of Interpretation, RFC 3547, July 2003. + + + + + + +Baugher, et al. Standards Track [Page 48] + +RFC 3711 SRTP March 2004 + + + [HAC] Menezes, A., Van Oorschot, P. and S. Vanstone, "Handbook + of Applied Cryptography", CRC Press, 1997, ISBN 0-8493- + 8523-7. + + [H80] Hellman, M. E., "A cryptanalytic time-memory trade-off", + IEEE Transactions on Information Theory, July 1980, pp. + 401-406. + + [IK] T. Iwata and T. Kohno: "New Security Proofs for the 3GPP + Confidentiality and Integrity Algorithms", Proceedings of + FSE 2004. + + [KINK] Thomas, M. and J. Vilhuber, "Kerberized Internet + Negotiation of Keys (KINK)", Work in Progress. + + [KEYMGT] Arrko, J., et al., "Key Management Extensions for Session + Description Protocol (SDP) and Real Time Streaming Protocol + (RTSP)", Work in Progress. + + [KSYH] Kang, J-S., Shin, S-U., Hong, D. and O. Yi, "Provable + Security of KASUMI and 3GPP Encryption Mode f8", + Proceedings Asiacrypt 2001, Springer Verlag LNCS 2248, pp. + 255-271, 2001. + + [MIKEY] Arrko, J., et. al., "MIKEY: Multimedia Internet KEYing", + Work in Progress. + + [MF00] McGrew, D. and S. Fluhrer, "Attacks on Encryption of + Redundant Plaintext and Implications on Internet Security", + the Proceedings of the Seventh Annual Workshop on Selected + Areas in Cryptography (SAC 2000), Springer-Verlag. + + [PCST1] Perrig, A., Canetti, R., Tygar, D. and D. Song, "Efficient + and Secure Source Authentication for Multicast", in Proc. + of Network and Distributed System Security Symposium NDSS + 2001, pp. 35-46, 2001. + + [PCST2] Perrig, A., Canetti, R., Tygar, D. and D. Song, "Efficient + Authentication and Signing of Multicast Streams over Lossy + Channels", in Proc. of IEEE Security and Privacy Symposium + S&P2000, pp. 56-73, 2000. + + [RFC1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness + Recommendations for Security", RFC 1750, December 1994. + + [RFC2675] Borman, D., Deering, S. and R. Hinden, "IPv6 Jumbograms", + RFC 2675, August 1999. + + + + +Baugher, et al. Standards Track [Page 49] + +RFC 3711 SRTP March 2004 + + + [RFC3095] Bormann, C., Burmeister, C., Degermark, M., Fukuhsima, H., + Hannu, H., Jonsson, L-E., Hakenberg, R., Koren, T., Le, K., + Liu, Z., Martensson, A., Miyazaki, A., Svanbro, K., Wiebke, + T., Yoshimura, T. and H. Zheng, "RObust Header Compression: + Framework and Four Profiles: RTP, UDP, ESP, and + uncompressed (ROHC)", RFC 3095, July 2001. + + [RFC3242] Jonsson, L-E. and G. Pelletier, "RObust Header Compression + (ROHC): A Link-Layer Assisted Profile for IP/UDP/RTP ", RFC + 3242, April 2002. + + [SDMS] Andreasen, F., Baugher, M. and D. Wing, "Session + Description Protocol Security Descriptions for Media + Streams", Work in Progress. + + [SWO] Svanbro, K., Wiorek, J. and B. Olin, "Voice-over-IP-over- + wireless", Proc. PIMRC 2000, London, Sept. 2000. + + [V02] Vaudenay, S., "Security Flaws Induced by CBC Padding - + Application to SSL, IPsec, WTLS...", Advances in + Cryptology, EUROCRYPT'02, LNCS 2332, pp. 534-545. + + [WC81] Wegman, M. N., and J.L. Carter, "New Hash Functions and + Their Use in Authentication and Set Equality", JCSS 22, + 265-279, 1981. + + + + + + + + + + + + + + + + + + + + + + + + + + +Baugher, et al. Standards Track [Page 50] + +RFC 3711 SRTP March 2004 + + +Appendix A: Pseudocode for Index Determination + + The following is an example of pseudo-code for the algorithm to + determine the index i of an SRTP packet with sequence number SEQ. In + the following, signed arithmetic is assumed. + + if (s_l < 32,768) + if (SEQ - s_l > 32,768) + set v to (ROC-1) mod 2^32 + else + set v to ROC + endif + else + if (s_l - 32,768 > SEQ) + set v to (ROC+1) mod 2^32 + else + set v to ROC + endif + endif + return SEQ + v*65,536 + +Appendix B: Test Vectors + + All values are in hexadecimal. + +B.1. AES-f8 Test Vectors + + SRTP PREFIX LENGTH : 0 + + RTP packet header : 806e5cba50681de55c621599 + + RTP packet payload : 70736575646f72616e646f6d6e657373 + 20697320746865206e65787420626573 + 74207468696e67 + + ROC : d462564a + key : 234829008467be186c3de14aae72d62c + salt key : 32f2870d + key-mask (m) : 32f2870d555555555555555555555555 + key XOR key-mask : 11baae0dd132eb4d3968b41ffb278379 + + IV : 006e5cba50681de55c621599d462564a + IV' : 595b699bbd3bc0df26062093c1ad8f73 + + + + + + + + +Baugher, et al. Standards Track [Page 51] + +RFC 3711 SRTP March 2004 + + + j = 0 + IV' xor j : 595b699bbd3bc0df26062093c1ad8f73 + S(-1) : 00000000000000000000000000000000 + IV' xor S(-1) xor j : 595b699bbd3bc0df26062093c1ad8f73 + S(0) : 71ef82d70a172660240709c7fbb19d8e + plaintext : 70736575646f72616e646f6d6e657373 + ciphertext : 019ce7a26e7854014a6366aa95d4eefd + + j = 1 + IV' xor j : 595b699bbd3bc0df26062093c1ad8f72 + S(0) : 71ef82d70a172660240709c7fbb19d8e + IV' xor S(0) xor j : 28b4eb4cb72ce6bf020129543a1c12fc + S(1) : 3abd640a60919fd43bd289a09649b5fc + plaintext : 20697320746865206e65787420626573 + ciphertext : 1ad4172a14f9faf455b7f1d4b62bd08f + + j = 2 + IV' xor j : 595b699bbd3bc0df26062093c1ad8f71 + S(1) : 3abd640a60919fd43bd289a09649b5fc + IV' xor S(1) xor j : 63e60d91ddaa5f0b1dd4a93357e43a8d + S(2) : 220c7a8715266565b09ecc8a2a62b11b + plaintext : 74207468696e67 + ciphertext : 562c0eef7c4802 + +B.2. AES-CM Test Vectors + + Keystream segment length: 1044512 octets (65282 AES blocks) + Session Key: 2B7E151628AED2A6ABF7158809CF4F3C + Rollover Counter: 00000000 + Sequence Number: 0000 + SSRC: 00000000 + Session Salt: F0F1F2F3F4F5F6F7F8F9FAFBFCFD0000 (already shifted) + Offset: F0F1F2F3F4F5F6F7F8F9FAFBFCFD0000 + + Counter Keystream + + F0F1F2F3F4F5F6F7F8F9FAFBFCFD0000 E03EAD0935C95E80E166B16DD92B4EB4 + F0F1F2F3F4F5F6F7F8F9FAFBFCFD0001 D23513162B02D0F72A43A2FE4A5F97AB + F0F1F2F3F4F5F6F7F8F9FAFBFCFD0002 41E95B3BB0A2E8DD477901E4FCA894C0 + ... ... + F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF EC8CDF7398607CB0F2D21675EA9EA1E4 + F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF00 362B7C3C6773516318A077D7FC5073AE + F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF01 6A2CC3787889374FBEB4C81B17BA6C44 + + Nota Bene: this test case is contrived so that the latter part of the + keystream segment coincides with the test case in Section F.5.1 of + [CTR]. + + + + +Baugher, et al. Standards Track [Page 52] + +RFC 3711 SRTP March 2004 + + +B.3. Key Derivation Test Vectors + + This section provides test data for the default key derivation + function, which uses AES-128 in Counter Mode. In the following, we + walk through the initial key derivation for the AES-128 Counter Mode + cipher, which requires a 16 octet session encryption key and a 14 + octet session salt, and an authentication function which requires a + 94-octet session authentication key. These values are called the + cipher key, the cipher salt, and the auth key in the following. + Since this is the initial key derivation and the key derivation rate + is equal to zero, the value of (index DIV key_derivation_rate) is + zero (actually, a six-octet string of zeros). In the following, we + shorten key_derivation_rate to kdr. + + The inputs to the key derivation function are the 16 octet master key + and the 14 octet master salt: + + master key: E1F97A0D3E018BE0D64FA32C06DE4139 + master salt: 0EC675AD498AFEEBB6960B3AABE6 + + We first show how the cipher key is generated. The input block for + AES-CM is generated by exclusive-oring the master salt with the + concatenation of the encryption key label 0x00 with (index DIV kdr), + then padding on the right with two null octets (which implements the + multiply-by-2^16 operation, see Section 4.3.3). The resulting value + is then AES-CM- encrypted using the master key to get the cipher key. + + index DIV kdr: 000000000000 + label: 00 + master salt: 0EC675AD498AFEEBB6960B3AABE6 + ----------------------------------------------- + xor: 0EC675AD498AFEEBB6960B3AABE6 (x, PRF input) + + x*2^16: 0EC675AD498AFEEBB6960B3AABE60000 (AES-CM input) + + cipher key: C61E7A93744F39EE10734AFE3FF7A087 (AES-CM output) + + + + + + + + + + + + + + + +Baugher, et al. Standards Track [Page 53] + +RFC 3711 SRTP March 2004 + + + Next, we show how the cipher salt is generated. The input block for + AES-CM is generated by exclusive-oring the master salt with the + concatenation of the encryption salt label. That value is padded and + encrypted as above. + + index DIV kdr: 000000000000 + label: 02 + master salt: 0EC675AD498AFEEBB6960B3AABE6 + + ---------------------------------------------- + xor: 0EC675AD498AFEE9B6960B3AABE6 (x, PRF input) + + x*2^16: 0EC675AD498AFEE9B6960B3AABE60000 (AES-CM input) + + 30CBBC08863D8C85D49DB34A9AE17AC6 (AES-CM ouptut) + + cipher salt: 30CBBC08863D8C85D49DB34A9AE1 + + We now show how the auth key is generated. The input block for AES- + CM is generated as above, but using the authentication key label. + + index DIV kdr: 000000000000 + label: 01 + master salt: 0EC675AD498AFEEBB6960B3AABE6 + ----------------------------------------------- + xor: 0EC675AD498AFEEAB6960B3AABE6 (x, PRF input) + + x*2^16: 0EC675AD498AFEEAB6960B3AABE60000 (AES-CM input) + + Below, the auth key is shown on the left, while the corresponding AES + input blocks are shown on the right. + + auth key AES input blocks + CEBE321F6FF7716B6FD4AB49AF256A15 0EC675AD498AFEEAB6960B3AABE60000 + 6D38BAA48F0A0ACF3C34E2359E6CDBCE 0EC675AD498AFEEAB6960B3AABE60001 + E049646C43D9327AD175578EF7227098 0EC675AD498AFEEAB6960B3AABE60002 + 6371C10C9A369AC2F94A8C5FBCDDDC25 0EC675AD498AFEEAB6960B3AABE60003 + 6D6E919A48B610EF17C2041E47403576 0EC675AD498AFEEAB6960B3AABE60004 + 6B68642C59BBFC2F34DB60DBDFB2 0EC675AD498AFEEAB6960B3AABE60005 + + + + + + + + + + + + +Baugher, et al. Standards Track [Page 54] + +RFC 3711 SRTP March 2004 + + +Authors' Addresses + + Questions and comments should be directed to the authors and + avt@ietf.org: + + Mark Baugher + Cisco Systems, Inc. + 5510 SW Orchid Street + Portland, OR 97219 USA + + Phone: +1 408-853-4418 + EMail: mbaugher@cisco.com + + + Elisabetta Carrara + Ericsson Research + SE-16480 Stockholm + Sweden + + Phone: +46 8 50877040 + EMail: elisabetta.carrara@ericsson.com + + + David A. McGrew + Cisco Systems, Inc. + San Jose, CA 95134-1706 + USA + + Phone: +1 301-349-5815 + EMail: mcgrew@cisco.com + + + Mats Naslund + Ericsson Research + SE-16480 Stockholm + Sweden + + Phone: +46 8 58533739 + EMail: mats.naslund@ericsson.com + + + Karl Norrman + Ericsson Research + SE-16480 Stockholm + Sweden + + Phone: +46 8 4044502 + EMail: karl.norrman@ericsson.com + + + +Baugher, et al. Standards Track [Page 55] + +RFC 3711 SRTP March 2004 + + +Full Copyright Statement + + Copyright (C) The Internet Society (2004). This document is subject + to the rights, licenses and restrictions contained in BCP 78 and + except as set forth therein, the authors retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE + INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at ietf- + ipr@ietf.org. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + + + +Baugher, et al. Standards Track [Page 56] + diff --git a/src/libs/srtp/include/ekt.h b/src/libs/srtp/include/ekt.h new file mode 100644 index 00000000..b0d888ba --- /dev/null +++ b/src/libs/srtp/include/ekt.h @@ -0,0 +1,201 @@ +/* + * ekt.h + * + * interface to Encrypted Key Transport for SRTP + * + * David McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2005 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + + +/* + * EKT implementation strategy + * + * use stream_template approach + * + * in srtp_unprotect, when a new stream appears, check if template has + * EKT defined, and if it does, then apply EKT processing + * + * question: will we want to allow key-sharing templates in addition + * to EKT templates? could define a new ssrc_type_t that's associated + * with an EKT, e.g. ssrc_any_ekt. + * + * + */ + +#ifndef EKT_H +#define EKT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "srtp_priv.h" + +#define EKT_CIPHER_DEFAULT 1 +#define EKT_CIPHER_AES_128_ECB 1 +#define EKT_CIPHER_AES_192_KEY_WRAP 2 +#define EKT_CIPHER_AES_256_KEY_WRAP 3 + +typedef uint16_t ekt_spi_t; + + +unsigned +ekt_octets_after_base_tag(ekt_stream_t ekt); + +/* + * an srtp_policy_t structure can contain a pointer to an + * ekt_policy_t structure + * + * this structure holds all of the high level EKT information, and it + * is passed into libsrtp to indicate what policy should be in effect + */ + +typedef struct ekt_policy_ctx_t { + ekt_spi_t spi; /* security parameter index */ + uint8_t ekt_cipher_type; + uint8_t *ekt_key; + struct ekt_policy_ctx_t *next_ekt_policy; +} ekt_policy_ctx_t; + + +/* + * an ekt_data_t structure holds the data corresponding to an ekt key, + * spi, and so on + */ + +typedef struct ekt_data_t { + ekt_spi_t spi; + uint8_t ekt_cipher_type; + aes_expanded_key_t ekt_enc_key; + aes_expanded_key_t ekt_dec_key; + struct ekt_data_t *next_ekt_data; +} ekt_data_t; + +/* + * an srtp_stream_ctx_t can contain an ekt_stream_ctx_t + * + * an ekt_stream_ctx_t structure holds all of the EKT information for + * a specific SRTP stream + */ + +typedef struct ekt_stream_ctx_t { + ekt_data_t *data; + uint16_t isn; /* initial sequence number */ + uint8_t encrypted_master_key[SRTP_MAX_KEY_LEN]; +} ekt_stream_ctx_t; + + + +err_status_t +ekt_alloc(ekt_stream_t *stream_data, ekt_policy_t policy); + +err_status_t +ekt_stream_init(ekt_stream_t e, + ekt_spi_t spi, + void *ekt_key, + unsigned ekt_cipher_type); + +err_status_t +ekt_stream_init_from_policy(ekt_stream_t e, ekt_policy_t p); + + + +err_status_t +srtp_stream_init_from_ekt(srtp_stream_t stream, + const void *srtcp_hdr, + unsigned pkt_octet_len); + + +void +ekt_write_data(ekt_stream_t ekt, + uint8_t *base_tag, + unsigned base_tag_len, + int *packet_len, + xtd_seq_num_t pkt_index); + +/* + * We handle EKT by performing some additional steps before + * authentication (copying the auth tag into a temporary location, + * zeroizing the "base tag" field in the packet) + * + * With EKT, the tag_len parameter is actually the base tag + * length + */ + +err_status_t +ekt_tag_verification_preproces(uint8_t *pkt_tag, + uint8_t *pkt_tag_copy, + unsigned tag_len); + +err_status_t +ekt_tag_verification_postproces(uint8_t *pkt_tag, + uint8_t *pkt_tag_copy, + unsigned tag_len); + + +/* + * @brief EKT pre-processing for srtcp tag generation + * + * This function does the pre-processing of the SRTCP authentication + * tag format. When EKT is used, it consists of writing the Encrypted + * Master Key, the SRTP ROC, the Initial Sequence Number, and SPI + * fields. The Base Authentication Tag field is set to the all-zero + * value + * + * When EKT is not used, this function is a no-op. + * + */ + +err_status_t +srtp_stream_srtcp_auth_tag_generation_preprocess(const srtp_stream_t *s, + uint8_t *pkt_tag, + unsigned pkt_octet_len); + +/* it's not clear that a tag_generation_postprocess function is needed */ + +err_status_t +srtcp_auth_tag_generation_postprocess(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* EKT_H */ diff --git a/src/libs/srtp/include/getopt_s.h b/src/libs/srtp/include/getopt_s.h new file mode 100644 index 00000000..2a6ece34 --- /dev/null +++ b/src/libs/srtp/include/getopt_s.h @@ -0,0 +1,60 @@ +/* + * getopt.h + * + * interface to a minimal implementation of the getopt() function, + * written so that test applications that use that function can run on + * non-POSIX platforms + * + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GETOPT_S_H +#define GETOPT_S_H + +/* + * getopt_s(), optarg_s, and optind_s are small, locally defined + * versions of the POSIX standard getopt() interface. + */ + +int +getopt_s(int argc, char * const argv[], const char *optstring); + +extern char *optarg_s; /* defined in getopt.c */ + +extern int optind_s; /* defined in getopt.c */ + +#endif /* GETOPT_S_H */ diff --git a/src/libs/srtp/include/rtp.h b/src/libs/srtp/include/rtp.h new file mode 100644 index 00000000..0e0119cf --- /dev/null +++ b/src/libs/srtp/include/rtp.h @@ -0,0 +1,139 @@ +/* + * rtp.h + * + * rtp interface for srtp reference implementation + * + * David A. McGrew + * Cisco Systems, Inc. + * + * data types: + * + * rtp_msg_t an rtp message (the data that goes on the wire) + * rtp_sender_t sender side socket and rtp info + * rtp_receiver_t receiver side socket and rtp info + * + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef RTP_H +#define RTP_H + +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#elif defined HAVE_WINSOCK2_H +# include <winsock2.h> +#endif + +#include "srtp.h" + +typedef struct rtp_sender_ctx_t *rtp_sender_t; + +typedef struct rtp_receiver_ctx_t *rtp_receiver_t; + +int +rtp_sendto(rtp_sender_t sender, const void* msg, int len); + +int +rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len); + +int +rtp_receiver_init(rtp_receiver_t rcvr, int sock, + struct sockaddr_in addr, unsigned int ssrc); + +int +rtp_sender_init(rtp_sender_t sender, int sock, + struct sockaddr_in addr, unsigned int ssrc); + +/* + * srtp_sender_init(...) initializes an rtp_sender_t + */ + +int +srtp_sender_init(rtp_sender_t rtp_ctx, /* structure to be init'ed */ + struct sockaddr_in name, /* socket name */ + sec_serv_t security_services, /* sec. servs. to be used */ + unsigned char *input_key /* master key/salt in hex */ + ); + +int +srtp_receiver_init(rtp_receiver_t rtp_ctx, /* structure to be init'ed */ + struct sockaddr_in name, /* socket name */ + sec_serv_t security_services, /* sec. servs. to be used */ + unsigned char *input_key /* master key/salt in hex */ + ); + + +int +rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy); + +int +rtp_sender_deinit_srtp(rtp_sender_t sender); + +int +rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy); + +int +rtp_receiver_deinit_srtp(rtp_receiver_t sender); + + +rtp_sender_t +rtp_sender_alloc(void); + +void +rtp_sender_dealloc(rtp_sender_t rtp_ctx); + +rtp_receiver_t +rtp_receiver_alloc(void); + +void +rtp_receiver_dealloc(rtp_receiver_t rtp_ctx); + + +/* + * RTP_HEADER_LEN indicates the size of an RTP header + */ +#define RTP_HEADER_LEN 12 + +/* + * RTP_MAX_BUF_LEN defines the largest RTP packet in the rtp.c implementation + */ +#define RTP_MAX_BUF_LEN 16384 + + +#endif /* RTP_H */ diff --git a/src/libs/srtp/include/rtp_priv.h b/src/libs/srtp/include/rtp_priv.h new file mode 100644 index 00000000..14213866 --- /dev/null +++ b/src/libs/srtp/include/rtp_priv.h @@ -0,0 +1,74 @@ +/* + * rtp_priv.h + * + * private, internal header file for RTP + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef RTP_PRIV_H +#define RTP_PRIV_H + +#include "srtp_priv.h" +#include "rtp.h" + +typedef srtp_hdr_t rtp_hdr_t; + +typedef struct { + srtp_hdr_t header; + char body[RTP_MAX_BUF_LEN]; +} rtp_msg_t; + +typedef struct rtp_sender_ctx_t { + rtp_msg_t message; + int socket; + srtp_ctx_t *srtp_ctx; + struct sockaddr_in addr; /* reciever's address */ +} rtp_sender_ctx_t; + +typedef struct rtp_receiver_ctx_t { + rtp_msg_t message; + int socket; + srtp_ctx_t *srtp_ctx; + struct sockaddr_in addr; /* receiver's address */ +} rtp_receiver_ctx_t; + + +#endif /* RTP_PRIV_H */ diff --git a/src/libs/srtp/include/srtp.h b/src/libs/srtp/include/srtp.h new file mode 100644 index 00000000..eb95e7d4 --- /dev/null +++ b/src/libs/srtp/include/srtp.h @@ -0,0 +1,1006 @@ +/* + * srtp.h + * + * interface to libsrtp + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef SRTP_H +#define SRTP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "crypto_kernel.h" + +/** + * @defgroup SRTP Secure RTP + * + * @brief libSRTP provides functions for protecting RTP and RTCP. See + * Section @ref Overview for an introduction to the use of the library. + * + * @{ + */ + +/* + * SRTP_MASTER_KEY_LEN is the nominal master key length supported by libSRTP + */ + +#define SRTP_MASTER_KEY_LEN 30 + +/* + * SRTP_MAX_KEY_LEN is the maximum key length supported by libSRTP + */ +#define SRTP_MAX_KEY_LEN 64 + +/* + * SRTP_MAX_TAG_LEN is the maximum tag length supported by libSRTP + */ + +#define SRTP_MAX_TAG_LEN 12 + +/** + * SRTP_MAX_TRAILER_LEN is the maximum length of the SRTP trailer + * (authentication tag and MKI) supported by libSRTP. This value is + * the maximum number of octets that will be added to an RTP packet by + * srtp_protect(). + * + * @brief the maximum number of octets added by srtp_protect(). + */ +#define SRTP_MAX_TRAILER_LEN SRTP_MAX_TAG_LEN + +/* + * nota bene: since libSRTP doesn't support the use of the MKI, the + * SRTP_MAX_TRAILER_LEN value is just the maximum tag length + */ + +/** + * @brief sec_serv_t describes a set of security services. + * + * A sec_serv_t enumeration is used to describe the particular + * security services that will be applied by a particular crypto + * policy (or other mechanism). + */ + +typedef enum { + sec_serv_none = 0, /**< no services */ + sec_serv_conf = 1, /**< confidentiality */ + sec_serv_auth = 2, /**< authentication */ + sec_serv_conf_and_auth = 3 /**< confidentiality and authentication */ +} sec_serv_t; + +/** + * @brief crypto_policy_t describes a particular crypto policy that + * can be applied to an SRTP stream. + * + * A crypto_policy_t describes a particular cryptographic policy that + * can be applied to an SRTP or SRTCP stream. An SRTP session policy + * consists of a list of these policies, one for each SRTP stream + * in the session. + */ + +typedef struct crypto_policy_t { + cipher_type_id_t cipher_type; /**< An integer representing + * the type of cipher. */ + int cipher_key_len; /**< The length of the cipher key + * in octets. */ + auth_type_id_t auth_type; /**< An integer representing the + * authentication function. */ + int auth_key_len; /**< The length of the authentication + * function key in octets. */ + int auth_tag_len; /**< The length of the authentication + * tag in octets. */ + sec_serv_t sec_serv; /**< The flag indicating the security + * services to be applied. */ +} crypto_policy_t; + + +/** + * @brief ssrc_type_t describes the type of an SSRC. + * + * An ssrc_type_t enumeration is used to indicate a type of SSRC. See + * @ref srtp_policy_t for more informataion. + */ + +typedef enum { + ssrc_undefined = 0, /**< Indicates an undefined SSRC type. */ + ssrc_specific = 1, /**< Indicates a specific SSRC value */ + ssrc_any_inbound = 2, /**< Indicates any inbound SSRC value + (i.e. a value that is used in the + function srtp_unprotect()) */ + ssrc_any_outbound = 3 /**< Indicates any outbound SSRC value + (i.e. a value that is used in the + function srtp_protect()) */ +} ssrc_type_t; + +/** + * @brief An ssrc_t represents a particular SSRC value, or a `wildcard' SSRC. + * + * An ssrc_t represents a particular SSRC value (if its type is + * ssrc_specific), or a wildcard SSRC value that will match all + * outbound SSRCs (if its type is ssrc_any_outbound) or all inbound + * SSRCs (if its type is ssrc_any_inbound). + * + */ + +typedef struct { + ssrc_type_t type; /**< The type of this particular SSRC */ + unsigned int value; /**< The value of this SSRC, if it is not a wildcard */ +} ssrc_t; + + +/** + * @brief points to an EKT policy + */ +typedef struct ekt_policy_ctx_t *ekt_policy_t; + + +/** + * @brief points to EKT stream data + */ +typedef struct ekt_stream_ctx_t *ekt_stream_t; + + +/** + * @brief represents the policy for an SRTP session. + * + * A single srtp_policy_t struct represents the policy for a single + * SRTP stream, and a linked list of these elements represents the + * policy for an entire SRTP session. Each element contains the SRTP + * and SRTCP crypto policies for that stream, a pointer to the SRTP + * master key for that stream, the SSRC describing that stream, or a + * flag indicating a `wildcard' SSRC value, and a `next' field that + * holds a pointer to the next element in the list of policy elements, + * or NULL if it is the last element. + * + * The wildcard value SSRC_ANY_INBOUND matches any SSRC from an + * inbound stream that for which there is no explicit SSRC entry in + * another policy element. Similarly, the value SSRC_ANY_OUTBOUND + * will matches any SSRC from an outbound stream that does not appear + * in another policy element. Note that wildcard SSRCs &b cannot be + * used to match both inbound and outbound traffic. This restriction + * is intentional, and it allows libSRTP to ensure that no security + * lapses result from accidental re-use of SSRC values during key + * sharing. + * + * + * @warning The final element of the list @b must have its `next' pointer + * set to NULL. + */ + +typedef struct srtp_policy_t { + ssrc_t ssrc; /**< The SSRC value of stream, or the + * flags SSRC_ANY_INBOUND or + * SSRC_ANY_OUTBOUND if key sharing + * is used for this policy element. + */ + crypto_policy_t rtp; /**< SRTP crypto policy. */ + crypto_policy_t rtcp; /**< SRTCP crypto policy. */ + unsigned char *key; /**< Pointer to the SRTP master key for + * this stream. */ + ekt_policy_t ekt; /**< Pointer to the EKT policy structure + * for this stream (if any) */ + unsigned long window_size; /**< The window size to use for replay + * protection. */ + int allow_repeat_tx; /**< Whether retransmissions of + * packets with the same sequence number + * are allowed. (Note that such repeated + * transmissions must have the same RTP + * payload, or a severe security weakness + * is introduced!) */ + struct srtp_policy_t *next; /**< Pointer to next stream policy. */ +} srtp_policy_t; + + + + +/** + * @brief An srtp_t points to an SRTP session structure. + * + * The typedef srtp_t is a pointer to a structure that represents + * an SRTP session. This datatype is intentially opaque in + * order to separate the interface from the implementation. + * + * An SRTP session consists of all of the traffic sent to the RTP and + * RTCP destination transport addresses, using the RTP/SAVP (Secure + * Audio/Video Profile). A session can be viewed as a set of SRTP + * streams, each of which originates with a different participant. + */ + +typedef struct srtp_ctx_t *srtp_t; + + +/** + * @brief An srtp_stream_t points to an SRTP stream structure. + * + * The typedef srtp_stream_t is a pointer to a structure that + * represents an SRTP stream. This datatype is intentionally + * opaque in order to separate the interface from the implementation. + * + * An SRTP stream consists of all of the traffic sent to an SRTP + * session by a single participant. A session can be viewed as + * a set of streams. + * + */ +typedef struct srtp_stream_ctx_t *srtp_stream_t; + + + +/** + * @brief srtp_init() initializes the srtp library. + * + * @warning This function @b must be called before any other srtp + * functions. + */ + +err_status_t +srtp_init(void); + +/** + * @brief srtp_shutdown() de-initializes the srtp library. + * + * @warning No srtp functions may be called after calling this function. + */ + +err_status_t +srtp_shutdown(void); + +/** + * @brief srtp_protect() is the Secure RTP sender-side packet processing + * function. + * + * The function call srtp_protect(ctx, rtp_hdr, len_ptr) applies SRTP + * protection to the RTP packet rtp_hdr (which has length *len_ptr) using + * the SRTP context ctx. If err_status_ok is returned, then rtp_hdr + * points to the resulting SRTP packet and *len_ptr is the number of + * octets in that packet; otherwise, no assumptions should be made + * about the value of either data elements. + * + * The sequence numbers of the RTP packets presented to this function + * need not be consecutive, but they @b must be out of order by less + * than 2^15 = 32,768 packets. + * + * @warning This function assumes that it can write the authentication + * tag into the location in memory immediately following the RTP + * packet, and assumes that the RTP packet is aligned on a 32-bit + * boundary. + * + * @param ctx is the SRTP context to use in processing the packet. + * + * @param rtp_hdr is a pointer to the RTP packet (before the call); after + * the function returns, it points to the srtp packet. + * + * @param len_ptr is a pointer to the length in octets of the complete + * RTP packet (header and body) before the function call, and of the + * complete SRTP packet after the call, if err_status_ok was returned. + * Otherwise, the value of the data to which it points is undefined. + * + * @return + * - err_status_ok no problems + * - err_status_replay_fail rtp sequence number was non-increasing + * - @e other failure in cryptographic mechanisms + */ + +err_status_t +srtp_protect(srtp_t ctx, void *rtp_hdr, int *len_ptr); + +/** + * @brief srtp_unprotect() is the Secure RTP receiver-side packet + * processing function. + * + * The function call srtp_unprotect(ctx, srtp_hdr, len_ptr) verifies + * the Secure RTP protection of the SRTP packet pointed to by srtp_hdr + * (which has length *len_ptr), using the SRTP context ctx. If + * err_status_ok is returned, then srtp_hdr points to the resulting + * RTP packet and *len_ptr is the number of octets in that packet; + * otherwise, no assumptions should be made about the value of either + * data elements. + * + * The sequence numbers of the RTP packets presented to this function + * need not be consecutive, but they @b must be out of order by less + * than 2^15 = 32,768 packets. + * + * @warning This function assumes that the SRTP packet is aligned on a + * 32-bit boundary. + * + * @param ctx is a pointer to the srtp_t which applies to the + * particular packet. + * + * @param srtp_hdr is a pointer to the header of the SRTP packet + * (before the call). after the function returns, it points to the + * rtp packet if err_status_ok was returned; otherwise, the value of + * the data to which it points is undefined. + * + * @param len_ptr is a pointer to the length in octets of the complete + * srtp packet (header and body) before the function call, and of the + * complete rtp packet after the call, if err_status_ok was returned. + * Otherwise, the value of the data to which it points is undefined. + * + * @return + * - err_status_ok if the RTP packet is valid. + * - err_status_auth_fail if the SRTP packet failed the message + * authentication check. + * - err_status_replay_fail if the SRTP packet is a replay (e.g. packet has + * already been processed and accepted). + * - [other] if there has been an error in the cryptographic mechanisms. + * + */ + +err_status_t +srtp_unprotect(srtp_t ctx, void *srtp_hdr, int *len_ptr); + + +/** + * @brief srtp_create() allocates and initializes an SRTP session. + + * The function call srtp_create(session, policy, key) allocates and + * initializes an SRTP session context, applying the given policy and + * key. + * + * @param session is the SRTP session to which the policy is to be added. + * + * @param policy is the srtp_policy_t struct that describes the policy + * for the session. The struct may be a single element, or it may be + * the head of a list, in which case each element of the list is + * processed. It may also be NULL, in which case streams should be added + * later using srtp_add_stream(). The final element of the list @b must + * have its `next' field set to NULL. + * + * @return + * - err_status_ok if creation succeded. + * - err_status_alloc_fail if allocation failed. + * - err_status_init_fail if initialization failed. + */ + +err_status_t +srtp_create(srtp_t *session, const srtp_policy_t *policy); + + +/** + * @brief srtp_add_stream() allocates and initializes an SRTP stream + * within a given SRTP session. + * + * The function call srtp_add_stream(session, policy) allocates and + * initializes a new SRTP stream within a given, previously created + * session, applying the policy given as the other argument to that + * stream. + * + * @return values: + * - err_status_ok if stream creation succeded. + * - err_status_alloc_fail if stream allocation failed + * - err_status_init_fail if stream initialization failed. + */ + +err_status_t +srtp_add_stream(srtp_t session, + const srtp_policy_t *policy); + + +/** + * @brief srtp_remove_stream() deallocates an SRTP stream. + * + * The function call srtp_remove_stream(session, ssrc) removes + * the SRTP stream with the SSRC value ssrc from the SRTP session + * context given by the argument session. + * + * @param session is the SRTP session from which the stream + * will be removed. + * + * @param ssrc is the SSRC value of the stream to be removed. + * + * @warning Wildcard SSRC values cannot be removed from a + * session. + * + * @return + * - err_status_ok if the stream deallocation succeded. + * - [other] otherwise. + * + */ + +err_status_t +srtp_remove_stream(srtp_t session, unsigned int ssrc); + +/** + * @brief crypto_policy_set_rtp_default() sets a crypto policy + * structure to the SRTP default policy for RTP protection. + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_rtp_default(&p) sets the + * crypto_policy_t at location p to the SRTP default policy for RTP + * protection, as defined in the specification. This function is a + * convenience that helps to avoid dealing directly with the policy + * data structure. You are encouraged to initialize policy elements + * with this function call. Doing so may allow your code to be + * forward compatible with later versions of libSRTP that include more + * elements in the crypto_policy_t datatype. + * + * @return void. + * + */ + +void +crypto_policy_set_rtp_default(crypto_policy_t *p); + +/** + * @brief crypto_policy_set_rtcp_default() sets a crypto policy + * structure to the SRTP default policy for RTCP protection. + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_rtcp_default(&p) sets the + * crypto_policy_t at location p to the SRTP default policy for RTCP + * protection, as defined in the specification. This function is a + * convenience that helps to avoid dealing directly with the policy + * data structure. You are encouraged to initialize policy elements + * with this function call. Doing so may allow your code to be + * forward compatible with later versions of libSRTP that include more + * elements in the crypto_policy_t datatype. + * + * @return void. + * + */ + +void +crypto_policy_set_rtcp_default(crypto_policy_t *p); + +/** + * @brief crypto_policy_set_aes_cm_128_hmac_sha1_80() sets a crypto + * policy structure to the SRTP default policy for RTP protection. + * + * @param p is a pointer to the policy structure to be set + * + * The function crypto_policy_set_aes_cm_128_hmac_sha1_80() is a + * synonym for crypto_policy_set_rtp_default(). It conforms to the + * naming convention used in RFC 4568 (SDP Security Descriptions for + * Media Streams). + * + * @return void. + * + */ + +#define crypto_policy_set_aes_cm_128_hmac_sha1_80(p) crypto_policy_set_rtp_default(p) + + +/** + * @brief crypto_policy_set_aes_cm_128_hmac_sha1_32() sets a crypto + * policy structure to a short-authentication tag policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_aes_cm_128_hmac_sha1_32(&p) + * sets the crypto_policy_t at location p to use policy + * AES_CM_128_HMAC_SHA1_32 as defined in RFC 4568. + * This policy uses AES-128 + * Counter Mode encryption and HMAC-SHA1 authentication, with an + * authentication tag that is only 32 bits long. This length is + * considered adequate only for protecting audio and video media that + * use a stateless playback function. See Section 7.5 of RFC 3711 + * (http://www.ietf.org/rfc/rfc3711.txt). + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the crypto_policy_t datatype. + * + * @warning This crypto policy is intended for use in SRTP, but not in + * SRTCP. It is recommended that a policy that uses longer + * authentication tags be used for SRTCP. See Section 7.5 of RFC 3711 + * (http://www.ietf.org/rfc/rfc3711.txt). + * + * @return void. + * + */ + +void +crypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p); + + + +/** + * @brief crypto_policy_set_aes_cm_128_null_auth() sets a crypto + * policy structure to an encryption-only policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_aes_cm_128_null_auth(&p) sets + * the crypto_policy_t at location p to use the SRTP default cipher + * (AES-128 Counter Mode), but to use no authentication method. This + * policy is NOT RECOMMENDED unless it is unavoidable; see Section 7.5 + * of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt). + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the crypto_policy_t datatype. + * + * @warning This policy is NOT RECOMMENDED for SRTP unless it is + * unavoidable, and it is NOT RECOMMENDED at all for SRTCP; see + * Section 7.5 of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt). + * + * @return void. + * + */ + +void +crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p); + + +/** + * @brief crypto_policy_set_null_cipher_hmac_sha1_80() sets a crypto + * policy structure to an authentication-only policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_null_cipher_hmac_sha1_80(&p) + * sets the crypto_policy_t at location p to use HMAC-SHA1 with an 80 + * bit authentication tag to provide message authentication, but to + * use no encryption. This policy is NOT RECOMMENDED for SRTP unless + * there is a requirement to forego encryption. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the crypto_policy_t datatype. + * + * @warning This policy is NOT RECOMMENDED for SRTP unless there is a + * requirement to forego encryption. + * + * @return void. + * + */ + +void +crypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p); + + +/** + * @brief crypto_policy_set_aes_cm_256_hmac_sha1_80() sets a crypto + * policy structure to a encryption and authentication policy using AES-256 + * for RTP protection. + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_aes_cm_256_hmac_sha1_80(&p) + * sets the crypto_policy_t at location p to use policy + * AES_CM_256_HMAC_SHA1_80 as defined in + * draft-ietf-avt-srtp-big-aes-03.txt. This policy uses AES-256 + * Counter Mode encryption and HMAC-SHA1 authentication, with an 80 bit + * authentication tag. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the crypto_policy_t datatype. + * + * @return void. + * + */ + +void crypto_policy_set_aes_cm_256_hmac_sha1_80(crypto_policy_t *p); + + +/** + * @brief crypto_policy_set_aes_cm_256_hmac_sha1_32() sets a crypto + * policy structure to a short-authentication tag policy using AES-256 + * encryption. + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_aes_cm_256_hmac_sha1_32(&p) + * sets the crypto_policy_t at location p to use policy + * AES_CM_256_HMAC_SHA1_32 as defined in + * draft-ietf-avt-srtp-big-aes-03.txt. This policy uses AES-256 + * Counter Mode encryption and HMAC-SHA1 authentication, with an + * authentication tag that is only 32 bits long. This length is + * considered adequate only for protecting audio and video media that + * use a stateless playback function. See Section 7.5 of RFC 3711 + * (http://www.ietf.org/rfc/rfc3711.txt). + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the crypto_policy_t datatype. + * + * @warning This crypto policy is intended for use in SRTP, but not in + * SRTCP. It is recommended that a policy that uses longer + * authentication tags be used for SRTCP. See Section 7.5 of RFC 3711 + * (http://www.ietf.org/rfc/rfc3711.txt). + * + * @return void. + * + */ + +void +crypto_policy_set_aes_cm_256_hmac_sha1_32(crypto_policy_t *p); + + +/** + * @brief srtp_dealloc() deallocates storage for an SRTP session + * context. + * + * The function call srtp_dealloc(s) deallocates storage for the + * SRTP session context s. This function should be called no more + * than one time for each of the contexts allocated by the function + * srtp_create(). + * + * @param s is the srtp_t for the session to be deallocated. + * + * @return + * - err_status_ok if there no problems. + * - err_status_dealloc_fail a memory deallocation failure occured. + */ + +err_status_t +srtp_dealloc(srtp_t s); + + +/* + * @brief identifies a particular SRTP profile + * + * An srtp_profile_t enumeration is used to identify a particular SRTP + * profile (that is, a set of algorithms and parameters). These + * profiles are defined in the DTLS-SRTP draft. + */ + +typedef enum { + srtp_profile_reserved = 0, + srtp_profile_aes128_cm_sha1_80 = 1, + srtp_profile_aes128_cm_sha1_32 = 2, + srtp_profile_aes256_cm_sha1_80 = 3, + srtp_profile_aes256_cm_sha1_32 = 4, + srtp_profile_null_sha1_80 = 5, + srtp_profile_null_sha1_32 = 6, +} srtp_profile_t; + + +/** + * @brief crypto_policy_set_from_profile_for_rtp() sets a crypto policy + * structure to the appropriate value for RTP based on an srtp_profile_t + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_rtp_default(&policy, profile) + * sets the crypto_policy_t at location policy to the policy for RTP + * protection, as defined by the srtp_profile_t profile. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the crypto_policy_t datatype. + * + * @return values + * - err_status_ok no problems were encountered + * - err_status_bad_param the profile is not supported + * + */ +err_status_t +crypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy, + srtp_profile_t profile); + + + + +/** + * @brief crypto_policy_set_from_profile_for_rtcp() sets a crypto policy + * structure to the appropriate value for RTCP based on an srtp_profile_t + * + * @param p is a pointer to the policy structure to be set + * + * The function call crypto_policy_set_rtcp_default(&policy, profile) + * sets the crypto_policy_t at location policy to the policy for RTCP + * protection, as defined by the srtp_profile_t profile. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the crypto_policy_t datatype. + * + * @return values + * - err_status_ok no problems were encountered + * - err_status_bad_param the profile is not supported + * + */ +err_status_t +crypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy, + srtp_profile_t profile); + +/** + * @brief returns the master key length for a given SRTP profile + */ +unsigned int +srtp_profile_get_master_key_length(srtp_profile_t profile); + + +/** + * @brief returns the master salt length for a given SRTP profile + */ +unsigned int +srtp_profile_get_master_salt_length(srtp_profile_t profile); + +/** + * @brief appends the salt to the key + * + * The function call append_salt_to_key(k, klen, s, slen) + * copies the string s to the location at klen bytes following + * the location k. + * + * @warning There must be at least bytes_in_salt + bytes_in_key bytes + * available at the location pointed to by key. + * + */ + +void +append_salt_to_key(unsigned char *key, unsigned int bytes_in_key, + unsigned char *salt, unsigned int bytes_in_salt); + + + +/** + * @} + */ + + + +/** + * @defgroup SRTCP Secure RTCP + * @ingroup SRTP + * + * @brief Secure RTCP functions are used to protect RTCP traffic. + * + * RTCP is the control protocol for RTP. libSRTP protects RTCP + * traffic in much the same way as it does RTP traffic. The function + * srtp_protect_rtcp() applies cryptographic protections to outbound + * RTCP packets, and srtp_unprotect_rtcp() verifies the protections on + * inbound RTCP packets. + * + * A note on the naming convention: srtp_protect_rtcp() has an srtp_t + * as its first argument, and thus has `srtp_' as its prefix. The + * trailing `_rtcp' indicates the protocol on which it acts. + * + * @{ + */ + +/** + * @brief srtp_protect_rtcp() is the Secure RTCP sender-side packet + * processing function. + * + * The function call srtp_protect_rtcp(ctx, rtp_hdr, len_ptr) applies + * SRTCP protection to the RTCP packet rtcp_hdr (which has length + * *len_ptr) using the SRTP session context ctx. If err_status_ok is + * returned, then rtp_hdr points to the resulting SRTCP packet and + * *len_ptr is the number of octets in that packet; otherwise, no + * assumptions should be made about the value of either data elements. + * + * @warning This function assumes that it can write the authentication + * tag into the location in memory immediately following the RTCP + * packet, and assumes that the RTCP packet is aligned on a 32-bit + * boundary. + * + * @param ctx is the SRTP context to use in processing the packet. + * + * @param rtcp_hdr is a pointer to the RTCP packet (before the call); after + * the function returns, it points to the srtp packet. + * + * @param pkt_octet_len is a pointer to the length in octets of the + * complete RTCP packet (header and body) before the function call, + * and of the complete SRTCP packet after the call, if err_status_ok + * was returned. Otherwise, the value of the data to which it points + * is undefined. + * + * @return + * - err_status_ok if there were no problems. + * - [other] if there was a failure in + * the cryptographic mechanisms. + */ + + +err_status_t +srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len); + +/** + * @brief srtp_unprotect_rtcp() is the Secure RTCP receiver-side packet + * processing function. + * + * The function call srtp_unprotect_rtcp(ctx, srtp_hdr, len_ptr) + * verifies the Secure RTCP protection of the SRTCP packet pointed to + * by srtcp_hdr (which has length *len_ptr), using the SRTP session + * context ctx. If err_status_ok is returned, then srtcp_hdr points + * to the resulting RTCP packet and *len_ptr is the number of octets + * in that packet; otherwise, no assumptions should be made about the + * value of either data elements. + * + * @warning This function assumes that the SRTCP packet is aligned on a + * 32-bit boundary. + * + * @param ctx is a pointer to the srtp_t which applies to the + * particular packet. + * + * @param srtcp_hdr is a pointer to the header of the SRTCP packet + * (before the call). After the function returns, it points to the + * rtp packet if err_status_ok was returned; otherwise, the value of + * the data to which it points is undefined. + * + * @param pkt_octet_len is a pointer to the length in octets of the + * complete SRTCP packet (header and body) before the function call, + * and of the complete rtp packet after the call, if err_status_ok was + * returned. Otherwise, the value of the data to which it points is + * undefined. + * + * @return + * - err_status_ok if the RTCP packet is valid. + * - err_status_auth_fail if the SRTCP packet failed the message + * authentication check. + * - err_status_replay_fail if the SRTCP packet is a replay (e.g. has + * already been processed and accepted). + * - [other] if there has been an error in the cryptographic mechanisms. + * + */ + +err_status_t +srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len); + +/** + * @} + */ + +/** + * @defgroup SRTPevents SRTP events and callbacks + * @ingroup SRTP + * + * @brief libSRTP can use a user-provided callback function to + * handle events. + * + * + * libSRTP allows a user to provide a callback function to handle + * events that need to be dealt with outside of the data plane (see + * the enum srtp_event_t for a description of these events). Dealing + * with these events is not a strict necessity; they are not + * security-critical, but the application may suffer if they are not + * handled. The function srtp_set_event_handler() is used to provide + * the callback function. + * + * A default event handler that merely reports on the events as they + * happen is included. It is also possible to set the event handler + * function to NULL, in which case all events will just be silently + * ignored. + * + * @{ + */ + +/** + * @brief srtp_event_t defines events that need to be handled + * + * The enum srtp_event_t defines events that need to be handled + * outside the `data plane', such as SSRC collisions and + * key expirations. + * + * When a key expires or the maximum number of packets has been + * reached, an SRTP stream will enter an `expired' state in which no + * more packets can be protected or unprotected. When this happens, + * it is likely that you will want to either deallocate the stream + * (using srtp_stream_dealloc()), and possibly allocate a new one. + * + * When an SRTP stream expires, the other streams in the same session + * are unaffected, unless key sharing is used by that stream. In the + * latter case, all of the streams in the session will expire. + */ + +typedef enum { + event_ssrc_collision, /**< + * An SSRC collision occured. + */ + event_key_soft_limit, /**< An SRTP stream reached the soft key + * usage limit and will expire soon. + */ + event_key_hard_limit, /**< An SRTP stream reached the hard + * key usage limit and has expired. + */ + event_packet_index_limit /**< An SRTP stream reached the hard + * packet limit (2^48 packets). + */ +} srtp_event_t; + +/** + * @brief srtp_event_data_t is the structure passed as a callback to + * the event handler function + * + * The struct srtp_event_data_t holds the data passed to the event + * handler function. + */ + +typedef struct srtp_event_data_t { + srtp_t session; /**< The session in which the event happend. */ + srtp_stream_t stream; /**< The stream in which the event happend. */ + srtp_event_t event; /**< An enum indicating the type of event. */ +} srtp_event_data_t; + +/** + * @brief srtp_event_handler_func_t is the function prototype for + * the event handler. + * + * The typedef srtp_event_handler_func_t is the prototype for the + * event handler function. It has as its only argument an + * srtp_event_data_t which describes the event that needs to be handled. + * There can only be a single, global handler for all events in + * libSRTP. + */ + +typedef void (srtp_event_handler_func_t)(srtp_event_data_t *data); + +/** + * @brief sets the event handler to the function supplied by the caller. + * + * The function call srtp_install_event_handler(func) sets the event + * handler function to the value func. The value NULL is acceptable + * as an argument; in this case, events will be ignored rather than + * handled. + * + * @param func is a pointer to a fuction that takes an srtp_event_data_t + * pointer as an argument and returns void. This function + * will be used by libSRTP to handle events. + */ + +err_status_t +srtp_install_event_handler(srtp_event_handler_func_t func); + +/** + * @} + */ +/* in host order, so outside the #if */ +#define SRTCP_E_BIT 0x80000000 +/* for byte-access */ +#define SRTCP_E_BYTE_BIT 0x80 +#define SRTCP_INDEX_MASK 0x7fffffff + +#ifdef __cplusplus +} +#endif + +#endif /* SRTP_H */ diff --git a/src/libs/srtp/include/srtp_priv.h b/src/libs/srtp/include/srtp_priv.h new file mode 100644 index 00000000..cf2274eb --- /dev/null +++ b/src/libs/srtp/include/srtp_priv.h @@ -0,0 +1,256 @@ +/* + * srtp_priv.h + * + * private internal data structures and functions for libSRTP + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef SRTP_PRIV_H +#define SRTP_PRIV_H + +#include "srtp.h" +#include "rdbx.h" +#include "rdb.h" +#include "integers.h" + +/* + * an srtp_hdr_t represents the srtp header + * + * in this implementation, an srtp_hdr_t is assumed to be 32-bit aligned + * + * (note that this definition follows that of RFC 1889 Appendix A, but + * is not identical) + */ + +#ifndef WORDS_BIGENDIAN + +/* + * srtp_hdr_t represents an RTP or SRTP header. The bit-fields in + * this structure should be declared "unsigned int" instead of + * "unsigned char", but doing so causes the MS compiler to not + * fully pack the bit fields. + */ + +typedef struct { + unsigned char cc:4; /* CSRC count */ + unsigned char x:1; /* header extension flag */ + unsigned char p:1; /* padding flag */ + unsigned char version:2; /* protocol version */ + unsigned char pt:7; /* payload type */ + unsigned char m:1; /* marker bit */ + uint16_t seq; /* sequence number */ + uint32_t ts; /* timestamp */ + uint32_t ssrc; /* synchronization source */ +} srtp_hdr_t; + +#else /* BIG_ENDIAN */ + +typedef struct { + unsigned char version:2; /* protocol version */ + unsigned char p:1; /* padding flag */ + unsigned char x:1; /* header extension flag */ + unsigned char cc:4; /* CSRC count */ + unsigned char m:1; /* marker bit */ + unsigned pt:7; /* payload type */ + uint16_t seq; /* sequence number */ + uint32_t ts; /* timestamp */ + uint32_t ssrc; /* synchronization source */ +} srtp_hdr_t; + +#endif + +typedef struct { + uint16_t profile_specific; /* profile-specific info */ + uint16_t length; /* number of 32-bit words in extension */ +} srtp_hdr_xtnd_t; + + +/* + * srtcp_hdr_t represents a secure rtcp header + * + * in this implementation, an srtcp header is assumed to be 32-bit + * alinged + */ + +#ifndef WORDS_BIGENDIAN + +typedef struct { + unsigned char rc:5; /* reception report count */ + unsigned char p:1; /* padding flag */ + unsigned char version:2; /* protocol version */ + unsigned char pt:8; /* payload type */ + uint16_t len; /* length */ + uint32_t ssrc; /* synchronization source */ +} srtcp_hdr_t; + +typedef struct { + unsigned int index:31; /* srtcp packet index in network order! */ + unsigned int e:1; /* encrypted? 1=yes */ + /* optional mikey/etc go here */ + /* and then the variable-length auth tag */ +} srtcp_trailer_t; + + +#else /* BIG_ENDIAN */ + +typedef struct { + unsigned char version:2; /* protocol version */ + unsigned char p:1; /* padding flag */ + unsigned char rc:5; /* reception report count */ + unsigned char pt:8; /* payload type */ + uint16_t len; /* length */ + uint32_t ssrc; /* synchronization source */ +} srtcp_hdr_t; + +typedef struct { + unsigned int version:2; /* protocol version */ + unsigned int p:1; /* padding flag */ + unsigned int count:5; /* varies by packet type */ + unsigned int pt:8; /* payload type */ + uint16_t length; /* len of uint32s of packet less header */ +} rtcp_common_t; + +typedef struct { + unsigned int e:1; /* encrypted? 1=yes */ + unsigned int index:31; /* srtcp packet index */ + /* optional mikey/etc go here */ + /* and then the variable-length auth tag */ +} srtcp_trailer_t; + +#endif + + +/* + * the following declarations are libSRTP internal functions + */ + +/* + * srtp_get_stream(ssrc) returns a pointer to the stream corresponding + * to ssrc, or NULL if no stream exists for that ssrc + */ + +srtp_stream_t +srtp_get_stream(srtp_t srtp, uint32_t ssrc); + + +/* + * srtp_stream_init_keys(s, k) (re)initializes the srtp_stream_t s by + * deriving all of the needed keys using the KDF and the key k. + */ + + +err_status_t +srtp_stream_init_keys(srtp_stream_t srtp, const void *key); + +/* + * srtp_stream_init(s, p) initializes the srtp_stream_t s to + * use the policy at the location p + */ +err_status_t +srtp_stream_init(srtp_stream_t srtp, + const srtp_policy_t *p); + + +/* + * libsrtp internal datatypes + */ + +typedef enum direction_t { + dir_unknown = 0, + dir_srtp_sender = 1, + dir_srtp_receiver = 2 +} direction_t; + +/* + * an srtp_stream_t has its own SSRC, encryption key, authentication + * key, sequence number, and replay database + * + * note that the keys might not actually be unique, in which case the + * cipher_t and auth_t pointers will point to the same structures + */ + +typedef struct srtp_stream_ctx_t { + uint32_t ssrc; + cipher_t *rtp_cipher; + auth_t *rtp_auth; + rdbx_t rtp_rdbx; + sec_serv_t rtp_services; + cipher_t *rtcp_cipher; + auth_t *rtcp_auth; + rdb_t rtcp_rdb; + sec_serv_t rtcp_services; + key_limit_ctx_t *limit; + direction_t direction; + int allow_repeat_tx; + ekt_stream_t ekt; + struct srtp_stream_ctx_t *next; /* linked list of streams */ +} srtp_stream_ctx_t; + + +/* + * an srtp_ctx_t holds a stream list and a service description + */ + +typedef struct srtp_ctx_t { + srtp_stream_ctx_t *stream_list; /* linked list of streams */ + srtp_stream_ctx_t *stream_template; /* act as template for other streams */ +} srtp_ctx_t; + + + +/* + * srtp_handle_event(srtp, srtm, evnt) calls the event handling + * function, if there is one. + * + * This macro is not included in the documentation as it is + * an internal-only function. + */ + +#define srtp_handle_event(srtp, strm, evnt) \ + if(srtp_event_handler) { \ + srtp_event_data_t data; \ + data.session = srtp; \ + data.stream = strm; \ + data.event = evnt; \ + srtp_event_handler(&data); \ +} + + +#endif /* SRTP_PRIV_H */ diff --git a/src/libs/srtp/include/ut_sim.h b/src/libs/srtp/include/ut_sim.h new file mode 100644 index 00000000..c25feeb6 --- /dev/null +++ b/src/libs/srtp/include/ut_sim.h @@ -0,0 +1,80 @@ +/* + * ut-sim.h + * + * an unreliable transport simulator + * (for testing replay databases and suchlike) + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + + +#ifndef UT_SIM_H +#define UT_SIM_H + +#include "integers.h" /* for uint32_t */ + +#define UT_BUF 160 /* maximum amount of packet reorder */ + +typedef struct { + uint32_t index; + uint32_t buffer[UT_BUF]; +} ut_connection; + +/* + * ut_init(&u) initializes the ut_connection + * + * this function should always be the first one called on a new + * ut_connection + */ + +void +ut_init(ut_connection *utc); + +/* + * ut_next_index(&u) returns the next index from the simulated + * unreliable connection + */ + +uint32_t +ut_next_index(ut_connection *utc); + + +#endif /* UT_SIM_H */ diff --git a/src/libs/srtp/install-sh b/src/libs/srtp/install-sh new file mode 100644 index 00000000..e9de2384 --- /dev/null +++ b/src/libs/srtp/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/src/libs/srtp/install-win.bat b/src/libs/srtp/install-win.bat new file mode 100644 index 00000000..d95d6d9f --- /dev/null +++ b/src/libs/srtp/install-win.bat @@ -0,0 +1,31 @@ +:: Installs from srtp windows build directory to directory specified on +:: command line + + +@if "%1"=="" ( + echo "Usage: %~nx0 destdir" + exit /b 1 +) else ( + set destdir=%1 +) + +@if not exist %destdir% ( + echo %destdir% not found + exit /b 1 +) + +@for %%d in (include\srtp.h crypto\include\crypto.h Debug\srtp.lib Release\srtp.lib) do ( + if not exist "%%d" ( + echo "%%d not found: are you in the right directory?" + exit /b 1 + ) +) + +mkdir %destdir%\include +mkdir %destdir%\include\srtp +mkdir %destdir%\lib + +copy include\*.h %destdir%\include\srtp +copy crypto\include\*.h %destdir%\include\srtp +copy Release\srtp.lib %destdir%\lib\srtp.lib +copy Debug\srtp.lib %destdir%\lib\srtpd.lib diff --git a/src/libs/srtp/srtp.vcproj b/src/libs/srtp/srtp.vcproj new file mode 100644 index 00000000..136ce34e --- /dev/null +++ b/src/libs/srtp/srtp.vcproj @@ -0,0 +1,265 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="srtp" + ProjectGUID="{C12A2037-3000-49A1-A007-A7E641D4FC38}" + RootNamespace="srtp" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="crypto\include;include;" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + TreatWChar_tAsBuiltInType="false" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + WholeProgramOptimization="false" + AdditionalIncludeDirectories="crypto\include;include;" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath=".\crypto\cipher\aes.c" + > + </File> + <File + RelativePath=".\crypto\cipher\aes_cbc.c" + > + </File> + <File + RelativePath=".\crypto\cipher\aes_icm.c" + > + </File> + <File + RelativePath=".\crypto\kernel\alloc.c" + > + </File> + <File + RelativePath=".\crypto\cipher\cipher.c" + > + </File> + <File + RelativePath=".\crypto\kernel\crypto_kernel.c" + > + </File> + <File + RelativePath=".\crypto\rng\ctr_prng.c" + > + </File> + <File + RelativePath=".\crypto\math\datatypes.c" + > + </File> + <File + RelativePath=".\srtp\ekt.c" + > + </File> + <File + RelativePath=".\crypto\kernel\err.c" + > + </File> + <File + RelativePath=".\crypto\math\gf2_8.c" + > + </File> + <File + RelativePath=".\crypto\hash\hmac.c" + > + </File> + <File + RelativePath=".\crypto\kernel\key.c" + > + </File> + <File + RelativePath=".\crypto\math\math.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\crypto\hash\null_auth.c" + > + </File> + <File + RelativePath=".\crypto\cipher\null_cipher.c" + > + </File> + <File + RelativePath=".\crypto\rng\prng.c" + > + </File> + <File + RelativePath=".\crypto\rng\rand_source.c" + > + </File> + <File + RelativePath=".\crypto\replay\rdb.c" + > + </File> + <File + RelativePath=".\crypto\replay\rdbx.c" + > + </File> + <File + RelativePath=".\crypto\hash\sha1.c" + > + </File> + <File + RelativePath=".\srtp\srtp.c" + > + </File> + <File + RelativePath=".\crypto\hash\srtp_auth.c" + > + </File> + <File + RelativePath=".\crypto\math\stat.c" + > + </File> + <File + RelativePath=".\crypto\replay\ut_sim.c" + > + </File> + <File + RelativePath=".\crypto\ae_xfm\xfm.c" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/srtp/srtp.vcxproj b/src/libs/srtp/srtp.vcxproj new file mode 100644 index 00000000..9e49c4f3 --- /dev/null +++ b/src/libs/srtp/srtp.vcxproj @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{C12A2037-3000-49A1-A007-A7E641D4FC38}</ProjectGuid> + <RootNamespace>srtp</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140_xp</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>crypto\include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <WholeProgramOptimization>false</WholeProgramOptimization> + <AdditionalIncludeDirectories>crypto\include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="crypto\cipher\aes.c" /> + <ClCompile Include="crypto\cipher\aes_cbc.c" /> + <ClCompile Include="crypto\cipher\aes_icm.c" /> + <ClCompile Include="crypto\kernel\alloc.c" /> + <ClCompile Include="crypto\cipher\cipher.c" /> + <ClCompile Include="crypto\kernel\crypto_kernel.c" /> + <ClCompile Include="crypto\rng\ctr_prng.c" /> + <ClCompile Include="crypto\math\datatypes.c" /> + <ClCompile Include="srtp\ekt.c" /> + <ClCompile Include="crypto\kernel\err.c" /> + <ClCompile Include="crypto\math\gf2_8.c" /> + <ClCompile Include="crypto\hash\hmac.c" /> + <ClCompile Include="crypto\kernel\key.c" /> + <ClCompile Include="crypto\math\math.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="crypto\hash\null_auth.c" /> + <ClCompile Include="crypto\cipher\null_cipher.c" /> + <ClCompile Include="crypto\rng\prng.c" /> + <ClCompile Include="crypto\rng\rand_source.c" /> + <ClCompile Include="crypto\replay\rdb.c" /> + <ClCompile Include="crypto\replay\rdbx.c" /> + <ClCompile Include="crypto\hash\sha1.c" /> + <ClCompile Include="srtp\srtp.c" /> + <ClCompile Include="crypto\hash\srtp_auth.c" /> + <ClCompile Include="crypto\math\stat.c" /> + <ClCompile Include="crypto\replay\ut_sim.c" /> + <ClCompile Include="crypto\ae_xfm\xfm.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/srtp/srtp.vcxproj.user b/src/libs/srtp/srtp.vcxproj.user new file mode 100644 index 00000000..abe8dd89 --- /dev/null +++ b/src/libs/srtp/srtp.vcxproj.user @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup /> +</Project> \ No newline at end of file diff --git a/src/libs/srtp/srtp/ekt.c b/src/libs/srtp/srtp/ekt.c new file mode 100644 index 00000000..9ae7f7e5 --- /dev/null +++ b/src/libs/srtp/srtp/ekt.c @@ -0,0 +1,278 @@ +/* + * ekt.c + * + * Encrypted Key Transport for SRTP + * + * David McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "err.h" +#include "srtp_priv.h" +#include "ekt.h" + +extern debug_module_t mod_srtp; + +/* + * The EKT Authentication Tag format. + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * : Base Authentication Tag : + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * : Encrypted Master Key : + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Rollover Counter | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Initial Sequence Number | Security Parameter Index | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define EKT_OCTETS_AFTER_BASE_TAG 24 +#define EKT_OCTETS_AFTER_EMK 8 +#define EKT_OCTETS_AFTER_ROC 4 +#define EKT_SPI_LEN 2 + +unsigned +ekt_octets_after_base_tag(ekt_stream_t ekt) { + /* + * if the pointer ekt is NULL, then EKT is not in effect, so we + * indicate this by returning zero + */ + if (!ekt) + return 0; + + switch(ekt->data->ekt_cipher_type) { + case EKT_CIPHER_AES_128_ECB: + return 16 + EKT_OCTETS_AFTER_EMK; + break; + default: + break; + } + return 0; +} + +static inline ekt_spi_t +srtcp_packet_get_ekt_spi(const uint8_t *packet_start, unsigned pkt_octet_len) { + const uint8_t *spi_location; + + spi_location = packet_start + (pkt_octet_len - EKT_SPI_LEN); + + return *((const ekt_spi_t *)spi_location); +} + +static inline uint32_t +srtcp_packet_get_ekt_roc(const uint8_t *packet_start, unsigned pkt_octet_len) { + const uint8_t *roc_location; + + roc_location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_ROC); + + return *((const uint32_t *)roc_location); +} + +static inline const uint8_t * +srtcp_packet_get_emk_location(const uint8_t *packet_start, + unsigned pkt_octet_len) { + const uint8_t *location; + + location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_BASE_TAG); + + return location; +} + + +err_status_t +ekt_alloc(ekt_stream_t *stream_data, ekt_policy_t policy) { + + /* + * if the policy pointer is NULL, then EKT is not in use + * so we just set the EKT stream data pointer to NULL + */ + if (!policy) { + *stream_data = NULL; + return err_status_ok; + } + + /* TODO */ + *stream_data = NULL; + + return err_status_ok; +} + +err_status_t +ekt_stream_init_from_policy(ekt_stream_t stream_data, ekt_policy_t policy) { + if (!stream_data) + return err_status_ok; + + return err_status_ok; +} + + +void +aes_decrypt_with_raw_key(void *ciphertext, const void *key, int key_len) { + aes_expanded_key_t expanded_key; + + aes_expand_decryption_key(key, key_len, &expanded_key); + aes_decrypt(ciphertext, &expanded_key); +} + +/* + * The function srtp_stream_init_from_ekt() initializes a stream using + * the EKT data from an SRTCP trailer. + */ + +err_status_t +srtp_stream_init_from_ekt(srtp_stream_t stream, + const void *srtcp_hdr, + unsigned pkt_octet_len) { + err_status_t err; + const uint8_t *master_key; + srtp_policy_t srtp_policy; + unsigned master_key_len; + uint32_t roc; + + /* + * NOTE: at present, we only support a single ekt_policy at a time. + */ + if (stream->ekt->data->spi != + srtcp_packet_get_ekt_spi(srtcp_hdr, pkt_octet_len)) + return err_status_no_ctx; + + if (stream->ekt->data->ekt_cipher_type != EKT_CIPHER_AES_128_ECB) + return err_status_bad_param; + master_key_len = 16; + + /* decrypt the Encrypted Master Key field */ + master_key = srtcp_packet_get_emk_location(srtcp_hdr, pkt_octet_len); + /* FIX!? This decrypts the master key in-place, and never uses it */ + /* FIX!? It's also passing to ekt_dec_key (which is an aes_expanded_key_t) + * to a function which expects a raw (unexpanded) key */ + aes_decrypt_with_raw_key((void*)master_key, &stream->ekt->data->ekt_dec_key, 16); + + /* set the SRTP ROC */ + roc = srtcp_packet_get_ekt_roc(srtcp_hdr, pkt_octet_len); + err = rdbx_set_roc(&stream->rtp_rdbx, roc); + if (err) return err; + + err = srtp_stream_init(stream, &srtp_policy); + if (err) return err; + + return err_status_ok; +} + +void +ekt_write_data(ekt_stream_t ekt, + uint8_t *base_tag, + unsigned base_tag_len, + int *packet_len, + xtd_seq_num_t pkt_index) { + uint32_t roc; + uint16_t isn; + unsigned emk_len; + uint8_t *packet; + + /* if the pointer ekt is NULL, then EKT is not in effect */ + if (!ekt) { + debug_print(mod_srtp, "EKT not in use", NULL); + return; + } + + /* write zeros into the location of the base tag */ + octet_string_set_to_zero(base_tag, base_tag_len); + packet = base_tag + base_tag_len; + + /* copy encrypted master key into packet */ + emk_len = ekt_octets_after_base_tag(ekt); + memcpy(packet, ekt->encrypted_master_key, emk_len); + debug_print(mod_srtp, "writing EKT EMK: %s,", + octet_string_hex_string(packet, emk_len)); + packet += emk_len; + + /* copy ROC into packet */ + roc = (uint32_t)(pkt_index >> 16); + *((uint32_t *)packet) = be32_to_cpu(roc); + debug_print(mod_srtp, "writing EKT ROC: %s,", + octet_string_hex_string(packet, sizeof(roc))); + packet += sizeof(roc); + + /* copy ISN into packet */ + isn = (uint16_t)pkt_index; + *((uint16_t *)packet) = htons(isn); + debug_print(mod_srtp, "writing EKT ISN: %s,", + octet_string_hex_string(packet, sizeof(isn))); + packet += sizeof(isn); + + /* copy SPI into packet */ + *((uint16_t *)packet) = htons(ekt->data->spi); + debug_print(mod_srtp, "writing EKT SPI: %s,", + octet_string_hex_string(packet, sizeof(ekt->data->spi))); + + /* increase packet length appropriately */ + *packet_len += EKT_OCTETS_AFTER_EMK + emk_len; +} + + +/* + * The function call srtcp_ekt_trailer(ekt, auth_len, auth_tag ) + * + * If the pointer ekt is NULL, then the other inputs are unaffected. + * + * auth_tag is a pointer to the pointer to the location of the + * authentication tag in the packet. If EKT is in effect, then the + * auth_tag pointer is set to the location + */ + +void +srtcp_ekt_trailer(ekt_stream_t ekt, + unsigned *auth_len, + void **auth_tag, + void *tag_copy) { + + /* + * if there is no EKT policy, then the other inputs are unaffected + */ + if (!ekt) + return; + + /* copy auth_tag into temporary location */ + +} + diff --git a/src/libs/srtp/srtp/srtp.c b/src/libs/srtp/srtp/srtp.c new file mode 100644 index 00000000..cdb05b8c --- /dev/null +++ b/src/libs/srtp/srtp/srtp.c @@ -0,0 +1,2163 @@ +/* + * srtp.c + * + * the secure real-time transport protocol + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "srtp.h" +#include "ekt.h" /* for SRTP Encrypted Key Transport */ +#include "alloc.h" /* for crypto_alloc() */ + +#ifndef SRTP_KERNEL +# include <limits.h> +# ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +# elif defined(HAVE_WINSOCK2_H) +# include <winsock2.h> +# endif +#endif /* ! SRTP_KERNEL */ + + +/* the debug module for srtp */ + +debug_module_t mod_srtp = { + 0, /* debugging is off by default */ + "srtp" /* printable name for module */ +}; + +#define octets_in_rtp_header 12 +#define uint32s_in_rtp_header 3 +#define octets_in_rtcp_header 8 +#define uint32s_in_rtcp_header 2 + + +err_status_t +srtp_stream_alloc(srtp_stream_ctx_t **str_ptr, + const srtp_policy_t *p) { + srtp_stream_ctx_t *str; + err_status_t stat; + + /* + * This function allocates the stream context, rtp and rtcp ciphers + * and auth functions, and key limit structure. If there is a + * failure during allocation, we free all previously allocated + * memory and return a failure code. The code could probably + * be improved, but it works and should be clear. + */ + + /* allocate srtp stream and set str_ptr */ + str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t)); + if (str == NULL) + return err_status_alloc_fail; + *str_ptr = str; + + /* allocate cipher */ + stat = crypto_kernel_alloc_cipher(p->rtp.cipher_type, + &str->rtp_cipher, + p->rtp.cipher_key_len); + if (stat) { + crypto_free(str); + return stat; + } + + /* allocate auth function */ + stat = crypto_kernel_alloc_auth(p->rtp.auth_type, + &str->rtp_auth, + p->rtp.auth_key_len, + p->rtp.auth_tag_len); + if (stat) { + cipher_dealloc(str->rtp_cipher); + crypto_free(str); + return stat; + } + + /* allocate key limit structure */ + str->limit = (key_limit_ctx_t*) crypto_alloc(sizeof(key_limit_ctx_t)); + if (str->limit == NULL) { + auth_dealloc(str->rtp_auth); + cipher_dealloc(str->rtp_cipher); + crypto_free(str); + return err_status_alloc_fail; + } + + /* + * ...and now the RTCP-specific initialization - first, allocate + * the cipher + */ + stat = crypto_kernel_alloc_cipher(p->rtcp.cipher_type, + &str->rtcp_cipher, + p->rtcp.cipher_key_len); + if (stat) { + auth_dealloc(str->rtp_auth); + cipher_dealloc(str->rtp_cipher); + crypto_free(str->limit); + crypto_free(str); + return stat; + } + + /* allocate auth function */ + stat = crypto_kernel_alloc_auth(p->rtcp.auth_type, + &str->rtcp_auth, + p->rtcp.auth_key_len, + p->rtcp.auth_tag_len); + if (stat) { + cipher_dealloc(str->rtcp_cipher); + auth_dealloc(str->rtp_auth); + cipher_dealloc(str->rtp_cipher); + crypto_free(str->limit); + crypto_free(str); + return stat; + } + + /* allocate ekt data associated with stream */ + stat = ekt_alloc(&str->ekt, p->ekt); + if (stat) { + auth_dealloc(str->rtcp_auth); + cipher_dealloc(str->rtcp_cipher); + auth_dealloc(str->rtp_auth); + cipher_dealloc(str->rtp_cipher); + crypto_free(str->limit); + crypto_free(str); + return stat; + } + + return err_status_ok; +} + +err_status_t +srtp_stream_dealloc(srtp_t session, srtp_stream_ctx_t *stream) { + err_status_t status; + + /* + * we use a conservative deallocation strategy - if any deallocation + * fails, then we report that fact without trying to deallocate + * anything else + */ + + /* deallocate cipher, if it is not the same as that in template */ + if (session->stream_template + && stream->rtp_cipher == session->stream_template->rtp_cipher) { + /* do nothing */ + } else { + status = cipher_dealloc(stream->rtp_cipher); + if (status) + return status; + } + + /* deallocate auth function, if it is not the same as that in template */ + if (session->stream_template + && stream->rtp_auth == session->stream_template->rtp_auth) { + /* do nothing */ + } else { + status = auth_dealloc(stream->rtp_auth); + if (status) + return status; + } + + /* deallocate key usage limit, if it is not the same as that in template */ + if (session->stream_template + && stream->limit == session->stream_template->limit) { + /* do nothing */ + } else { + crypto_free(stream->limit); + } + + /* + * deallocate rtcp cipher, if it is not the same as that in + * template + */ + if (session->stream_template + && stream->rtcp_cipher == session->stream_template->rtcp_cipher) { + /* do nothing */ + } else { + status = cipher_dealloc(stream->rtcp_cipher); + if (status) + return status; + } + + /* + * deallocate rtcp auth function, if it is not the same as that in + * template + */ + if (session->stream_template + && stream->rtcp_auth == session->stream_template->rtcp_auth) { + /* do nothing */ + } else { + status = auth_dealloc(stream->rtcp_auth); + if (status) + return status; + } + + status = rdbx_dealloc(&stream->rtp_rdbx); + if (status) + return status; + + /* DAM - need to deallocate EKT here */ + + /* deallocate srtp stream context */ + crypto_free(stream); + + return err_status_ok; +} + + +/* + * srtp_stream_clone(stream_template, new) allocates a new stream and + * initializes it using the cipher and auth of the stream_template + * + * the only unique data in a cloned stream is the replay database and + * the SSRC + */ + +err_status_t +srtp_stream_clone(const srtp_stream_ctx_t *stream_template, + uint32_t ssrc, + srtp_stream_ctx_t **str_ptr) { + err_status_t status; + srtp_stream_ctx_t *str; + + debug_print(mod_srtp, "cloning stream (SSRC: 0x%08x)", ssrc); + + /* allocate srtp stream and set str_ptr */ + str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t)); + if (str == NULL) + return err_status_alloc_fail; + *str_ptr = str; + + /* set cipher and auth pointers to those of the template */ + str->rtp_cipher = stream_template->rtp_cipher; + str->rtp_auth = stream_template->rtp_auth; + str->rtcp_cipher = stream_template->rtcp_cipher; + str->rtcp_auth = stream_template->rtcp_auth; + + /* set key limit to point to that of the template */ + status = key_limit_clone(stream_template->limit, &str->limit); + if (status) + return status; + + /* initialize replay databases */ + status = rdbx_init(&str->rtp_rdbx, + rdbx_get_window_size(&stream_template->rtp_rdbx)); + if (status) + return status; + rdb_init(&str->rtcp_rdb); + str->allow_repeat_tx = stream_template->allow_repeat_tx; + + /* set ssrc to that provided */ + str->ssrc = ssrc; + + /* set direction and security services */ + str->direction = stream_template->direction; + str->rtp_services = stream_template->rtp_services; + str->rtcp_services = stream_template->rtcp_services; + + /* set pointer to EKT data associated with stream */ + str->ekt = stream_template->ekt; + + /* defensive coding */ + str->next = NULL; + + return err_status_ok; +} + + +/* + * key derivation functions, internal to libSRTP + * + * srtp_kdf_t is a key derivation context + * + * srtp_kdf_init(&kdf, cipher_id, k, keylen) initializes kdf to use cipher + * described by cipher_id, with the master key k with length in octets keylen. + * + * srtp_kdf_generate(&kdf, l, kl, keylen) derives the key + * corresponding to label l and puts it into kl; the length + * of the key in octets is provided as keylen. this function + * should be called once for each subkey that is derived. + * + * srtp_kdf_clear(&kdf) zeroizes and deallocates the kdf state + */ + +typedef enum { + label_rtp_encryption = 0x00, + label_rtp_msg_auth = 0x01, + label_rtp_salt = 0x02, + label_rtcp_encryption = 0x03, + label_rtcp_msg_auth = 0x04, + label_rtcp_salt = 0x05 +} srtp_prf_label; + + +/* + * srtp_kdf_t represents a key derivation function. The SRTP + * default KDF is the only one implemented at present. + */ + +typedef struct { + cipher_t *cipher; /* cipher used for key derivation */ +} srtp_kdf_t; + +err_status_t +srtp_kdf_init(srtp_kdf_t *kdf, cipher_type_id_t cipher_id, const uint8_t *key, int length) { + + err_status_t stat; + stat = crypto_kernel_alloc_cipher(cipher_id, &kdf->cipher, length); + if (stat) + return stat; + + stat = cipher_init(kdf->cipher, key, direction_encrypt); + if (stat) { + cipher_dealloc(kdf->cipher); + return stat; + } + + return err_status_ok; +} + +err_status_t +srtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label, + uint8_t *key, unsigned length) { + + v128_t nonce; + err_status_t status; + + /* set eigth octet of nonce to <label>, set the rest of it to zero */ + v128_set_to_zero(&nonce); + nonce.v8[7] = label; + + status = cipher_set_iv(kdf->cipher, &nonce); + if (status) + return status; + + /* generate keystream output */ + octet_string_set_to_zero(key, length); + status = cipher_encrypt(kdf->cipher, key, &length); + if (status) + return status; + + return err_status_ok; +} + +err_status_t +srtp_kdf_clear(srtp_kdf_t *kdf) { + err_status_t status; + status = cipher_dealloc(kdf->cipher); + if (status) + return status; + kdf->cipher = NULL; + + return err_status_ok; +} + +/* + * end of key derivation functions + */ + +#define MAX_SRTP_KEY_LEN 256 + + +/* Get the base key length corresponding to a given combined key+salt + * length for the given cipher. + * Assumption is that for AES-ICM a key length < 30 is Ismacryp using + * AES-128 and short salts; everything else uses a salt length of 14. + * TODO: key and salt lengths should be separate fields in the policy. */ +static inline int base_key_length(const cipher_type_t *cipher, int key_length) +{ + if (cipher->id != AES_ICM) + return key_length; + else if (key_length > 16 && key_length < 30) + return 16; + return key_length - 14; +} + +err_status_t +srtp_stream_init_keys(srtp_stream_ctx_t *srtp, const void *key) { + err_status_t stat; + srtp_kdf_t kdf; + uint8_t tmp_key[MAX_SRTP_KEY_LEN]; + int kdf_keylen = 30, rtp_keylen, rtcp_keylen; + int rtp_base_key_len, rtp_salt_len; + int rtcp_base_key_len, rtcp_salt_len; + + /* If RTP or RTCP have a key length > AES-128, assume matching kdf. */ + /* TODO: kdf algorithm, master key length, and master salt length should + * be part of srtp_policy_t. */ + rtp_keylen = cipher_get_key_length(srtp->rtp_cipher); + if (rtp_keylen > kdf_keylen) + kdf_keylen = rtp_keylen; + + rtcp_keylen = cipher_get_key_length(srtp->rtcp_cipher); + if (rtcp_keylen > kdf_keylen) + kdf_keylen = rtcp_keylen; + + /* initialize KDF state */ + stat = srtp_kdf_init(&kdf, AES_ICM, (const uint8_t *)key, kdf_keylen); + if (stat) { + return err_status_init_fail; + } + + rtp_base_key_len = base_key_length(srtp->rtp_cipher->type, rtp_keylen); + rtp_salt_len = rtp_keylen - rtp_base_key_len; + + /* generate encryption key */ + stat = srtp_kdf_generate(&kdf, label_rtp_encryption, + tmp_key, rtp_base_key_len); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + + /* + * if the cipher in the srtp context uses a salt, then we need + * to generate the salt value + */ + if (rtp_salt_len > 0) { + debug_print(mod_srtp, "found rtp_salt_len > 0, generating salt", NULL); + + /* generate encryption salt, put after encryption key */ + stat = srtp_kdf_generate(&kdf, label_rtp_salt, + tmp_key + rtp_base_key_len, rtp_salt_len); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + } + debug_print(mod_srtp, "cipher key: %s", + octet_string_hex_string(tmp_key, rtp_keylen)); + + /* initialize cipher */ + stat = cipher_init(srtp->rtp_cipher, tmp_key, direction_any); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + + /* generate authentication key */ + stat = srtp_kdf_generate(&kdf, label_rtp_msg_auth, + tmp_key, auth_get_key_length(srtp->rtp_auth)); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + debug_print(mod_srtp, "auth key: %s", + octet_string_hex_string(tmp_key, + auth_get_key_length(srtp->rtp_auth))); + + /* initialize auth function */ + stat = auth_init(srtp->rtp_auth, tmp_key); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + + /* + * ...now initialize SRTCP keys + */ + + rtcp_base_key_len = base_key_length(srtp->rtcp_cipher->type, rtcp_keylen); + rtcp_salt_len = rtcp_keylen - rtcp_base_key_len; + + /* generate encryption key */ + stat = srtp_kdf_generate(&kdf, label_rtcp_encryption, + tmp_key, rtcp_base_key_len); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + + /* + * if the cipher in the srtp context uses a salt, then we need + * to generate the salt value + */ + if (rtcp_salt_len > 0) { + debug_print(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt", + NULL); + + /* generate encryption salt, put after encryption key */ + stat = srtp_kdf_generate(&kdf, label_rtcp_salt, + tmp_key + rtcp_base_key_len, rtcp_salt_len); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + } + debug_print(mod_srtp, "rtcp cipher key: %s", + octet_string_hex_string(tmp_key, rtcp_keylen)); + + /* initialize cipher */ + stat = cipher_init(srtp->rtcp_cipher, tmp_key, direction_any); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + + /* generate authentication key */ + stat = srtp_kdf_generate(&kdf, label_rtcp_msg_auth, + tmp_key, auth_get_key_length(srtp->rtcp_auth)); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + + debug_print(mod_srtp, "rtcp auth key: %s", + octet_string_hex_string(tmp_key, + auth_get_key_length(srtp->rtcp_auth))); + + /* initialize auth function */ + stat = auth_init(srtp->rtcp_auth, tmp_key); + if (stat) { + /* zeroize temp buffer */ + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + return err_status_init_fail; + } + + /* clear memory then return */ + stat = srtp_kdf_clear(&kdf); + octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); + if (stat) + return err_status_init_fail; + + return err_status_ok; +} + +err_status_t +srtp_stream_init(srtp_stream_ctx_t *srtp, + const srtp_policy_t *p) { + err_status_t err; + + debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)", + p->ssrc.value); + + /* initialize replay database */ + /* window size MUST be at least 64. MAY be larger. Values more than + * 2^15 aren't meaningful due to how extended sequence numbers are + * calculated. Let a window size of 0 imply the default value. */ + + if (p->window_size != 0 && (p->window_size < 64 || p->window_size >= 0x8000)) + return err_status_bad_param; + + if (p->window_size != 0) + err = rdbx_init(&srtp->rtp_rdbx, p->window_size); + else + err = rdbx_init(&srtp->rtp_rdbx, 128); + if (err) return err; + + /* initialize key limit to maximum value */ +#ifdef NO_64BIT_MATH +{ + uint64_t temp; + temp = make64(UINT_MAX,UINT_MAX); + key_limit_set(srtp->limit, temp); +} +#else + key_limit_set(srtp->limit, 0xffffffffffffLL); +#endif + + /* set the SSRC value */ + srtp->ssrc = htonl(p->ssrc.value); + + /* set the security service flags */ + srtp->rtp_services = p->rtp.sec_serv; + srtp->rtcp_services = p->rtcp.sec_serv; + + /* + * set direction to unknown - this flag gets checked in srtp_protect(), + * srtp_unprotect(), srtp_protect_rtcp(), and srtp_unprotect_rtcp(), and + * gets set appropriately if it is set to unknown. + */ + srtp->direction = dir_unknown; + + /* initialize SRTCP replay database */ + rdb_init(&srtp->rtcp_rdb); + + /* initialize allow_repeat_tx */ + /* guard against uninitialized memory: allow only 0 or 1 here */ + if (p->allow_repeat_tx != 0 && p->allow_repeat_tx != 1) { + rdbx_dealloc(&srtp->rtp_rdbx); + return err_status_bad_param; + } + srtp->allow_repeat_tx = p->allow_repeat_tx; + + /* DAM - no RTCP key limit at present */ + + /* initialize keys */ + err = srtp_stream_init_keys(srtp, p->key); + if (err) { + rdbx_dealloc(&srtp->rtp_rdbx); + return err; + } + + /* + * if EKT is in use, then initialize the EKT data associated with + * the stream + */ + err = ekt_stream_init_from_policy(srtp->ekt, p->ekt); + if (err) { + rdbx_dealloc(&srtp->rtp_rdbx); + return err; + } + + return err_status_ok; + } + + + /* + * srtp_event_reporter is an event handler function that merely + * reports the events that are reported by the callbacks + */ + + void + srtp_event_reporter(srtp_event_data_t *data) { + + err_report(err_level_warning, "srtp: in stream 0x%x: ", + data->stream->ssrc); + + switch(data->event) { + case event_ssrc_collision: + err_report(err_level_warning, "\tSSRC collision\n"); + break; + case event_key_soft_limit: + err_report(err_level_warning, "\tkey usage soft limit reached\n"); + break; + case event_key_hard_limit: + err_report(err_level_warning, "\tkey usage hard limit reached\n"); + break; + case event_packet_index_limit: + err_report(err_level_warning, "\tpacket index limit reached\n"); + break; + default: + err_report(err_level_warning, "\tunknown event reported to handler\n"); + } + } + + /* + * srtp_event_handler is a global variable holding a pointer to the + * event handler function; this function is called for any unexpected + * event that needs to be handled out of the SRTP data path. see + * srtp_event_t in srtp.h for more info + * + * it is okay to set srtp_event_handler to NULL, but we set + * it to the srtp_event_reporter. + */ + + static srtp_event_handler_func_t *srtp_event_handler = srtp_event_reporter; + + err_status_t + srtp_install_event_handler(srtp_event_handler_func_t func) { + + /* + * note that we accept NULL arguments intentionally - calling this + * function with a NULL arguments removes an event handler that's + * been previously installed + */ + + /* set global event handling function */ + srtp_event_handler = func; + return err_status_ok; + } + + err_status_t + srtp_protect(srtp_ctx_t *ctx, void *rtp_hdr, int *pkt_octet_len) { + srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr; + uint32_t *enc_start; /* pointer to start of encrypted portion */ + uint32_t *auth_start; /* pointer to start of auth. portion */ + unsigned enc_octet_len = 0; /* number of octets in encrypted portion */ + xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */ + int delta; /* delta of local pkt idx and that in hdr */ + uint8_t *auth_tag = NULL; /* location of auth_tag within packet */ + err_status_t status; + int tag_len; + srtp_stream_ctx_t *stream; + int prefix_len; + + debug_print(mod_srtp, "function srtp_protect", NULL); + + /* we assume the hdr is 32-bit aligned to start */ + + /* check the packet length - it must at least contain a full header */ + if (*pkt_octet_len < octets_in_rtp_header) + return err_status_bad_param; + + /* + * look up ssrc in srtp_stream list, and process the packet with + * the appropriate stream. if we haven't seen this stream before, + * there's a template key for this srtp_session, and the cipher + * supports key-sharing, then we assume that a new stream using + * that key has just started up + */ + stream = srtp_get_stream(ctx, hdr->ssrc); + if (stream == NULL) { + if (ctx->stream_template != NULL) { + srtp_stream_ctx_t *new_stream; + + /* allocate and initialize a new stream */ + status = srtp_stream_clone(ctx->stream_template, + hdr->ssrc, &new_stream); + if (status) + return status; + + /* add new stream to the head of the stream_list */ + new_stream->next = ctx->stream_list; + ctx->stream_list = new_stream; + + /* set direction to outbound */ + new_stream->direction = dir_srtp_sender; + + /* set stream (the pointer used in this function) */ + stream = new_stream; + } else { + /* no template stream, so we return an error */ + return err_status_no_ctx; + } + } + + /* + * verify that stream is for sending traffic - this check will + * detect SSRC collisions, since a stream that appears in both + * srtp_protect() and srtp_unprotect() will fail this test in one of + * those functions. + */ + if (stream->direction != dir_srtp_sender) { + if (stream->direction == dir_unknown) { + stream->direction = dir_srtp_sender; + } else { + srtp_handle_event(ctx, stream, event_ssrc_collision); + } + } + + /* + * update the key usage limit, and check it to make sure that we + * didn't just hit either the soft limit or the hard limit, and call + * the event handler if we hit either. + */ + switch(key_limit_update(stream->limit)) { + case key_event_normal: + break; + case key_event_soft_limit: + srtp_handle_event(ctx, stream, event_key_soft_limit); + break; + case key_event_hard_limit: + srtp_handle_event(ctx, stream, event_key_hard_limit); + return err_status_key_expired; + default: + break; + } + + /* get tag length from stream */ + tag_len = auth_get_tag_length(stream->rtp_auth); + + /* + * find starting point for encryption and length of data to be + * encrypted - the encrypted portion starts after the rtp header + * extension, if present; otherwise, it starts after the last csrc, + * if any are present + * + * if we're not providing confidentiality, set enc_start to NULL + */ + if (stream->rtp_services & sec_serv_conf) { + enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; + if (hdr->x == 1) { + srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start; + enc_start += (ntohs(xtn_hdr->length) + 1); + } + enc_octet_len = (unsigned int)(*pkt_octet_len + - ((enc_start - (uint32_t *)hdr) << 2)); + } else { + enc_start = NULL; + } + + /* + * if we're providing authentication, set the auth_start and auth_tag + * pointers to the proper locations; otherwise, set auth_start to NULL + * to indicate that no authentication is needed + */ + if (stream->rtp_services & sec_serv_auth) { + auth_start = (uint32_t *)hdr; + auth_tag = (uint8_t *)hdr + *pkt_octet_len; + } else { + auth_start = NULL; + auth_tag = NULL; + } + + /* + * estimate the packet index using the start of the replay window + * and the sequence number from the header + */ + delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq)); + status = rdbx_check(&stream->rtp_rdbx, delta); + if (status) { + if (status != err_status_replay_fail || !stream->allow_repeat_tx) + return status; /* we've been asked to reuse an index */ + } + else + rdbx_add_index(&stream->rtp_rdbx, delta); + +#ifdef NO_64BIT_MATH + debug_print2(mod_srtp, "estimated packet index: %08x%08x", + high32(est),low32(est)); +#else + debug_print(mod_srtp, "estimated packet index: %016llx", est); +#endif + + /* + * if we're using rindael counter mode, set nonce and seq + */ + if (stream->rtp_cipher->type->id == AES_ICM) { + v128_t iv; + + iv.v32[0] = 0; + iv.v32[1] = hdr->ssrc; +#ifdef NO_64BIT_MATH + iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16), + low32(est) << 16)); +#else + iv.v64[1] = be64_to_cpu(est << 16); +#endif + status = cipher_set_iv(stream->rtp_cipher, &iv); + + } else { + v128_t iv; + + /* otherwise, set the index to est */ +#ifdef NO_64BIT_MATH + iv.v32[0] = 0; + iv.v32[1] = 0; +#else + iv.v64[0] = 0; +#endif + iv.v64[1] = be64_to_cpu(est); + status = cipher_set_iv(stream->rtp_cipher, &iv); + } + if (status) + return err_status_cipher_fail; + + /* shift est, put into network byte order */ +#ifdef NO_64BIT_MATH + est = be64_to_cpu(make64((high32(est) << 16) | + (low32(est) >> 16), + low32(est) << 16)); +#else + est = be64_to_cpu(est << 16); +#endif + + /* + * if we're authenticating using a universal hash, put the keystream + * prefix into the authentication tag + */ + if (auth_start) { + + prefix_len = auth_get_prefix_length(stream->rtp_auth); + if (prefix_len) { + status = cipher_output(stream->rtp_cipher, auth_tag, prefix_len); + if (status) + return err_status_cipher_fail; + debug_print(mod_srtp, "keystream prefix: %s", + octet_string_hex_string(auth_tag, prefix_len)); + } + } + + /* if we're encrypting, exor keystream into the message */ + if (enc_start) { + status = cipher_encrypt(stream->rtp_cipher, + (uint8_t *)enc_start, &enc_octet_len); + if (status) + return err_status_cipher_fail; + } + + /* + * if we're authenticating, run authentication function and put result + * into the auth_tag + */ + if (auth_start) { + + /* initialize auth func context */ + status = auth_start(stream->rtp_auth); + if (status) return status; + + /* run auth func over packet */ + status = auth_update(stream->rtp_auth, + (uint8_t *)auth_start, *pkt_octet_len); + if (status) return status; + + /* run auth func over ROC, put result into auth_tag */ + debug_print(mod_srtp, "estimated packet index: %016llx", est); + status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, auth_tag); + debug_print(mod_srtp, "srtp auth tag: %s", + octet_string_hex_string(auth_tag, tag_len)); + if (status) + return err_status_auth_fail; + + } + + if (auth_tag) { + + /* increase the packet length by the length of the auth tag */ + *pkt_octet_len += tag_len; + } + + return err_status_ok; +} + + +err_status_t +srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) { + srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr; + uint32_t *enc_start; /* pointer to start of encrypted portion */ + uint32_t *auth_start; /* pointer to start of auth. portion */ + unsigned enc_octet_len = 0;/* number of octets in encrypted portion */ + uint8_t *auth_tag = NULL; /* location of auth_tag within packet */ + xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */ + int delta; /* delta of local pkt idx and that in hdr */ + v128_t iv; + err_status_t status; + srtp_stream_ctx_t *stream; + uint8_t tmp_tag[SRTP_MAX_TAG_LEN]; + int tag_len, prefix_len; + + debug_print(mod_srtp, "function srtp_unprotect", NULL); + + /* we assume the hdr is 32-bit aligned to start */ + + /* check the packet length - it must at least contain a full header */ + if (*pkt_octet_len < octets_in_rtp_header) + return err_status_bad_param; + + /* + * look up ssrc in srtp_stream list, and process the packet with + * the appropriate stream. if we haven't seen this stream before, + * there's only one key for this srtp_session, and the cipher + * supports key-sharing, then we assume that a new stream using + * that key has just started up + */ + stream = srtp_get_stream(ctx, hdr->ssrc); + if (stream == NULL) { + if (ctx->stream_template != NULL) { + stream = ctx->stream_template; + debug_print(mod_srtp, "using provisional stream (SSRC: 0x%08x)", + hdr->ssrc); + + /* + * set estimated packet index to sequence number from header, + * and set delta equal to the same value + */ +#ifdef NO_64BIT_MATH + est = (xtd_seq_num_t) make64(0,ntohs(hdr->seq)); + delta = low32(est); +#else + est = (xtd_seq_num_t) ntohs(hdr->seq); + delta = (int)est; +#endif + } else { + + /* + * no stream corresponding to SSRC found, and we don't do + * key-sharing, so return an error + */ + return err_status_no_ctx; + } + } else { + + /* estimate packet index from seq. num. in header */ + delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq)); + + /* check replay database */ + status = rdbx_check(&stream->rtp_rdbx, delta); + if (status) + return status; + } + +#ifdef NO_64BIT_MATH + debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),low32(est)); +#else + debug_print(mod_srtp, "estimated u_packet index: %016llx", est); +#endif + + /* get tag length from stream */ + tag_len = auth_get_tag_length(stream->rtp_auth); + + /* + * set the cipher's IV properly, depending on whatever cipher we + * happen to be using + */ + if (stream->rtp_cipher->type->id == AES_ICM) { + + /* aes counter mode */ + iv.v32[0] = 0; + iv.v32[1] = hdr->ssrc; /* still in network order */ +#ifdef NO_64BIT_MATH + iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16), + low32(est) << 16)); +#else + iv.v64[1] = be64_to_cpu(est << 16); +#endif + status = cipher_set_iv(stream->rtp_cipher, &iv); + } else { + + /* no particular format - set the iv to the pakcet index */ +#ifdef NO_64BIT_MATH + iv.v32[0] = 0; + iv.v32[1] = 0; +#else + iv.v64[0] = 0; +#endif + iv.v64[1] = be64_to_cpu(est); + status = cipher_set_iv(stream->rtp_cipher, &iv); + } + if (status) + return err_status_cipher_fail; + + /* shift est, put into network byte order */ +#ifdef NO_64BIT_MATH + est = be64_to_cpu(make64((high32(est) << 16) | + (low32(est) >> 16), + low32(est) << 16)); +#else + est = be64_to_cpu(est << 16); +#endif + + /* + * find starting point for decryption and length of data to be + * decrypted - the encrypted portion starts after the rtp header + * extension, if present; otherwise, it starts after the last csrc, + * if any are present + * + * if we're not providing confidentiality, set enc_start to NULL + */ + if (stream->rtp_services & sec_serv_conf) { + enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; + if (hdr->x == 1) { + srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start; + enc_start += (ntohs(xtn_hdr->length) + 1); + } + enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len + - ((enc_start - (uint32_t *)hdr) << 2)); + } else { + enc_start = NULL; + } + + /* + * if we're providing authentication, set the auth_start and auth_tag + * pointers to the proper locations; otherwise, set auth_start to NULL + * to indicate that no authentication is needed + */ + if (stream->rtp_services & sec_serv_auth) { + auth_start = (uint32_t *)hdr; + auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len; + } else { + auth_start = NULL; + auth_tag = NULL; + } + + /* + * if we expect message authentication, run the authentication + * function and compare the result with the value of the auth_tag + */ + if (auth_start) { + + /* + * if we're using a universal hash, then we need to compute the + * keystream prefix for encrypting the universal hash output + * + * if the keystream prefix length is zero, then we know that + * the authenticator isn't using a universal hash function + */ + if (stream->rtp_auth->prefix_len != 0) { + + prefix_len = auth_get_prefix_length(stream->rtp_auth); + status = cipher_output(stream->rtp_cipher, tmp_tag, prefix_len); + debug_print(mod_srtp, "keystream prefix: %s", + octet_string_hex_string(tmp_tag, prefix_len)); + if (status) + return err_status_cipher_fail; + } + + /* initialize auth func context */ + status = auth_start(stream->rtp_auth); + if (status) return status; + + /* now compute auth function over packet */ + status = auth_update(stream->rtp_auth, (uint8_t *)auth_start, + *pkt_octet_len - tag_len); + + /* run auth func over ROC, then write tmp tag */ + status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag); + + debug_print(mod_srtp, "computed auth tag: %s", + octet_string_hex_string(tmp_tag, tag_len)); + debug_print(mod_srtp, "packet auth tag: %s", + octet_string_hex_string(auth_tag, tag_len)); + if (status) + return err_status_auth_fail; + + if (octet_string_is_eq(tmp_tag, auth_tag, tag_len)) + return err_status_auth_fail; + } + + /* + * update the key usage limit, and check it to make sure that we + * didn't just hit either the soft limit or the hard limit, and call + * the event handler if we hit either. + */ + switch(key_limit_update(stream->limit)) { + case key_event_normal: + break; + case key_event_soft_limit: + srtp_handle_event(ctx, stream, event_key_soft_limit); + break; + case key_event_hard_limit: + srtp_handle_event(ctx, stream, event_key_hard_limit); + return err_status_key_expired; + default: + break; + } + + /* if we're decrypting, add keystream into ciphertext */ + if (enc_start) { + status = cipher_decrypt(stream->rtp_cipher, + (uint8_t *)enc_start, &enc_octet_len); + if (status) + return err_status_cipher_fail; + } + + /* + * verify that stream is for received traffic - this check will + * detect SSRC collisions, since a stream that appears in both + * srtp_protect() and srtp_unprotect() will fail this test in one of + * those functions. + * + * we do this check *after* the authentication check, so that the + * latter check will catch any attempts to fool us into thinking + * that we've got a collision + */ + if (stream->direction != dir_srtp_receiver) { + if (stream->direction == dir_unknown) { + stream->direction = dir_srtp_receiver; + } else { + srtp_handle_event(ctx, stream, event_ssrc_collision); + } + } + + /* + * if the stream is a 'provisional' one, in which the template context + * is used, then we need to allocate a new stream at this point, since + * the authentication passed + */ + if (stream == ctx->stream_template) { + srtp_stream_ctx_t *new_stream; + + /* + * allocate and initialize a new stream + * + * note that we indicate failure if we can't allocate the new + * stream, and some implementations will want to not return + * failure here + */ + status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); + if (status) + return status; + + /* add new stream to the head of the stream_list */ + new_stream->next = ctx->stream_list; + ctx->stream_list = new_stream; + + /* set stream (the pointer used in this function) */ + stream = new_stream; + } + + /* + * the message authentication function passed, so add the packet + * index into the replay database + */ + rdbx_add_index(&stream->rtp_rdbx, delta); + + /* decrease the packet length by the length of the auth tag */ + *pkt_octet_len -= tag_len; + + return err_status_ok; +} + +err_status_t +srtp_init() { + err_status_t status; + + /* initialize crypto kernel */ + status = crypto_kernel_init(); + if (status) + return status; + + /* load srtp debug module into the kernel */ + status = crypto_kernel_load_debug_module(&mod_srtp); + if (status) + return status; + + return err_status_ok; +} + +err_status_t +srtp_shutdown() { + err_status_t status; + + /* shut down crypto kernel */ + status = crypto_kernel_shutdown(); + if (status) + return status; + + /* shutting down crypto kernel frees the srtp debug module as well */ + + return err_status_ok; +} + + +/* + * The following code is under consideration for removal. See + * SRTP_MAX_TRAILER_LEN + */ +#if 0 + +/* + * srtp_get_trailer_length(&a) returns the number of octets that will + * be added to an RTP packet by the SRTP processing. This value + * is constant for a given srtp_stream_t (i.e. between initializations). + */ + +int +srtp_get_trailer_length(const srtp_stream_t s) { + return auth_get_tag_length(s->rtp_auth); +} + +#endif + +/* + * srtp_get_stream(ssrc) returns a pointer to the stream corresponding + * to ssrc, or NULL if no stream exists for that ssrc + * + * this is an internal function + */ + +srtp_stream_ctx_t * +srtp_get_stream(srtp_t srtp, uint32_t ssrc) { + srtp_stream_ctx_t *stream; + + /* walk down list until ssrc is found */ + stream = srtp->stream_list; + while (stream != NULL) { + if (stream->ssrc == ssrc) + return stream; + stream = stream->next; + } + + /* we haven't found our ssrc, so return a null */ + return NULL; +} + +err_status_t +srtp_dealloc(srtp_t session) { + srtp_stream_ctx_t *stream; + err_status_t status; + + /* + * we take a conservative deallocation strategy - if we encounter an + * error deallocating a stream, then we stop trying to deallocate + * memory and just return an error + */ + + /* walk list of streams, deallocating as we go */ + stream = session->stream_list; + while (stream != NULL) { + srtp_stream_t next = stream->next; + status = srtp_stream_dealloc(session, stream); + if (status) + return status; + stream = next; + } + + /* deallocate stream template, if there is one */ + if (session->stream_template != NULL) { + status = auth_dealloc(session->stream_template->rtcp_auth); + if (status) + return status; + status = cipher_dealloc(session->stream_template->rtcp_cipher); + if (status) + return status; + crypto_free(session->stream_template->limit); + status = cipher_dealloc(session->stream_template->rtp_cipher); + if (status) + return status; + status = auth_dealloc(session->stream_template->rtp_auth); + if (status) + return status; + status = rdbx_dealloc(&session->stream_template->rtp_rdbx); + if (status) + return status; + crypto_free(session->stream_template); + } + + /* deallocate session context */ + crypto_free(session); + + return err_status_ok; +} + + +err_status_t +srtp_add_stream(srtp_t session, + const srtp_policy_t *policy) { + err_status_t status; + srtp_stream_t tmp; + + /* sanity check arguments */ + if ((session == NULL) || (policy == NULL) || (policy->key == NULL)) + return err_status_bad_param; + + /* allocate stream */ + status = srtp_stream_alloc(&tmp, policy); + if (status) { + return status; + } + + /* initialize stream */ + status = srtp_stream_init(tmp, policy); + if (status) { + crypto_free(tmp); + return status; + } + + /* + * set the head of the stream list or the template to point to the + * stream that we've just alloced and init'ed, depending on whether + * or not it has a wildcard SSRC value or not + * + * if the template stream has already been set, then the policy is + * inconsistent, so we return a bad_param error code + */ + switch (policy->ssrc.type) { + case (ssrc_any_outbound): + if (session->stream_template) { + return err_status_bad_param; + } + session->stream_template = tmp; + session->stream_template->direction = dir_srtp_sender; + break; + case (ssrc_any_inbound): + if (session->stream_template) { + return err_status_bad_param; + } + session->stream_template = tmp; + session->stream_template->direction = dir_srtp_receiver; + break; + case (ssrc_specific): + tmp->next = session->stream_list; + session->stream_list = tmp; + break; + case (ssrc_undefined): + default: + crypto_free(tmp); + return err_status_bad_param; + } + + return err_status_ok; +} + + +err_status_t +srtp_create(srtp_t *session, /* handle for session */ + const srtp_policy_t *policy) { /* SRTP policy (list) */ + err_status_t stat; + srtp_ctx_t *ctx; + + /* sanity check arguments */ + if (session == NULL) + return err_status_bad_param; + + /* allocate srtp context and set ctx_ptr */ + ctx = (srtp_ctx_t *) crypto_alloc(sizeof(srtp_ctx_t)); + if (ctx == NULL) + return err_status_alloc_fail; + *session = ctx; + + /* + * loop over elements in the policy list, allocating and + * initializing a stream for each element + */ + ctx->stream_template = NULL; + ctx->stream_list = NULL; + while (policy != NULL) { + + stat = srtp_add_stream(ctx, policy); + if (stat) { + /* clean up everything */ + srtp_dealloc(*session); + return stat; + } + + /* set policy to next item in list */ + policy = policy->next; + } + + return err_status_ok; +} + + +err_status_t +srtp_remove_stream(srtp_t session, uint32_t ssrc) { + srtp_stream_ctx_t *stream, *last_stream; + err_status_t status; + + /* sanity check arguments */ + if (session == NULL) + return err_status_bad_param; + + /* find stream in list; complain if not found */ + last_stream = stream = session->stream_list; + while ((stream != NULL) && (ssrc != stream->ssrc)) { + last_stream = stream; + stream = stream->next; + } + if (stream == NULL) + return err_status_no_ctx; + + /* remove stream from the list */ + if (last_stream == stream) + /* stream was first in list */ + session->stream_list = stream->next; + else + last_stream->next = stream->next; + + /* deallocate the stream */ + status = srtp_stream_dealloc(session, stream); + if (status) + return status; + + return err_status_ok; +} + + +/* + * the default policy - provides a convenient way for callers to use + * the default security policy + * + * this policy is that defined in the current SRTP internet draft. + * + */ + +/* + * NOTE: cipher_key_len is really key len (128 bits) plus salt len + * (112 bits) + */ +/* There are hard-coded 16's for base_key_len in the key generation code */ + +void +crypto_policy_set_rtp_default(crypto_policy_t *p) { + + p->cipher_type = AES_ICM; + p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */ + p->auth_type = HMAC_SHA1; + p->auth_key_len = 20; /* default 160 bits per RFC 3711 */ + p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */ + p->sec_serv = sec_serv_conf_and_auth; + +} + +void +crypto_policy_set_rtcp_default(crypto_policy_t *p) { + + p->cipher_type = AES_ICM; + p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */ + p->auth_type = HMAC_SHA1; + p->auth_key_len = 20; /* default 160 bits per RFC 3711 */ + p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */ + p->sec_serv = sec_serv_conf_and_auth; + +} + +void +crypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p) { + + /* + * corresponds to RFC 4568 + * + * note that this crypto policy is intended for SRTP, but not SRTCP + */ + + p->cipher_type = AES_ICM; + p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */ + p->auth_type = HMAC_SHA1; + p->auth_key_len = 20; /* 160 bit key */ + p->auth_tag_len = 4; /* 32 bit tag */ + p->sec_serv = sec_serv_conf_and_auth; + +} + + +void +crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p) { + + /* + * corresponds to RFC 4568 + * + * note that this crypto policy is intended for SRTP, but not SRTCP + */ + + p->cipher_type = AES_ICM; + p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */ + p->auth_type = NULL_AUTH; + p->auth_key_len = 0; + p->auth_tag_len = 0; + p->sec_serv = sec_serv_conf; + +} + + +void +crypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p) { + + /* + * corresponds to RFC 4568 + */ + + p->cipher_type = NULL_CIPHER; + p->cipher_key_len = 0; + p->auth_type = HMAC_SHA1; + p->auth_key_len = 20; + p->auth_tag_len = 10; + p->sec_serv = sec_serv_auth; + +} + + +void +crypto_policy_set_aes_cm_256_hmac_sha1_80(crypto_policy_t *p) { + + /* + * corresponds to draft-ietf-avt-big-aes-03.txt + */ + + p->cipher_type = AES_ICM; + p->cipher_key_len = 46; + p->auth_type = HMAC_SHA1; + p->auth_key_len = 20; /* default 160 bits per RFC 3711 */ + p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */ + p->sec_serv = sec_serv_conf_and_auth; +} + + +void +crypto_policy_set_aes_cm_256_hmac_sha1_32(crypto_policy_t *p) { + + /* + * corresponds to draft-ietf-avt-big-aes-03.txt + * + * note that this crypto policy is intended for SRTP, but not SRTCP + */ + + p->cipher_type = AES_ICM; + p->cipher_key_len = 46; + p->auth_type = HMAC_SHA1; + p->auth_key_len = 20; /* default 160 bits per RFC 3711 */ + p->auth_tag_len = 4; /* default 80 bits per RFC 3711 */ + p->sec_serv = sec_serv_conf_and_auth; +} + + +/* + * secure rtcp functions + */ + +err_status_t +srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) { + srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr; + uint32_t *enc_start; /* pointer to start of encrypted portion */ + uint32_t *auth_start; /* pointer to start of auth. portion */ + uint32_t *trailer; /* pointer to start of trailer */ + unsigned enc_octet_len = 0;/* number of octets in encrypted portion */ + uint8_t *auth_tag = NULL; /* location of auth_tag within packet */ + err_status_t status; + int tag_len; + srtp_stream_ctx_t *stream; + int prefix_len; + uint32_t seq_num; + + /* we assume the hdr is 32-bit aligned to start */ + /* + * look up ssrc in srtp_stream list, and process the packet with + * the appropriate stream. if we haven't seen this stream before, + * there's only one key for this srtp_session, and the cipher + * supports key-sharing, then we assume that a new stream using + * that key has just started up + */ + stream = srtp_get_stream(ctx, hdr->ssrc); + if (stream == NULL) { + if (ctx->stream_template != NULL) { + srtp_stream_ctx_t *new_stream; + + /* allocate and initialize a new stream */ + status = srtp_stream_clone(ctx->stream_template, + hdr->ssrc, &new_stream); + if (status) + return status; + + /* add new stream to the head of the stream_list */ + new_stream->next = ctx->stream_list; + ctx->stream_list = new_stream; + + /* set stream (the pointer used in this function) */ + stream = new_stream; + } else { + /* no template stream, so we return an error */ + return err_status_no_ctx; + } + } + + /* + * verify that stream is for sending traffic - this check will + * detect SSRC collisions, since a stream that appears in both + * srtp_protect() and srtp_unprotect() will fail this test in one of + * those functions. + */ + if (stream->direction != dir_srtp_sender) { + if (stream->direction == dir_unknown) { + stream->direction = dir_srtp_sender; + } else { + srtp_handle_event(ctx, stream, event_ssrc_collision); + } + } + + /* get tag length from stream context */ + tag_len = auth_get_tag_length(stream->rtcp_auth); + + /* + * set encryption start and encryption length - if we're not + * providing confidentiality, set enc_start to NULL + */ + enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header; + enc_octet_len = *pkt_octet_len - octets_in_rtcp_header; + + /* all of the packet, except the header, gets encrypted */ + /* NOTE: hdr->length is not usable - it refers to only the first + RTCP report in the compound packet! */ + /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always + multiples of 32-bits (RFC 3550 6.1) */ + trailer = (uint32_t *) ((char *)enc_start + enc_octet_len); + + if (stream->rtcp_services & sec_serv_conf) { + *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */ + } else { + enc_start = NULL; + enc_octet_len = 0; + /* 0 is network-order independant */ + *trailer = 0x00000000; /* set encrypt bit */ + } + + /* + * set the auth_start and auth_tag pointers to the proper locations + * (note that srtpc *always* provides authentication, unlike srtp) + */ + /* Note: This would need to change for optional mikey data */ + auth_start = (uint32_t *)hdr; + auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t); + + /* perform EKT processing if needed */ + ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len, + rdbx_get_packet_index(&stream->rtp_rdbx)); + + /* + * check sequence number for overruns, and copy it into the packet + * if its value isn't too big + */ + status = rdb_increment(&stream->rtcp_rdb); + if (status) + return status; + seq_num = rdb_get_value(&stream->rtcp_rdb); + *trailer |= htonl(seq_num); + debug_print(mod_srtp, "srtcp index: %x", seq_num); + + /* + * if we're using rindael counter mode, set nonce and seq + */ + if (stream->rtcp_cipher->type->id == AES_ICM) { + v128_t iv; + + iv.v32[0] = 0; + iv.v32[1] = hdr->ssrc; /* still in network order! */ + iv.v32[2] = htonl(seq_num >> 16); + iv.v32[3] = htonl(seq_num << 16); + status = cipher_set_iv(stream->rtcp_cipher, &iv); + + } else { + v128_t iv; + + /* otherwise, just set the index to seq_num */ + iv.v32[0] = 0; + iv.v32[1] = 0; + iv.v32[2] = 0; + iv.v32[3] = htonl(seq_num); + status = cipher_set_iv(stream->rtcp_cipher, &iv); + } + if (status) + return err_status_cipher_fail; + + /* + * if we're authenticating using a universal hash, put the keystream + * prefix into the authentication tag + */ + + /* if auth_start is non-null, then put keystream into tag */ + if (auth_start) { + + /* put keystream prefix into auth_tag */ + prefix_len = auth_get_prefix_length(stream->rtcp_auth); + status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len); + + debug_print(mod_srtp, "keystream prefix: %s", + octet_string_hex_string(auth_tag, prefix_len)); + + if (status) + return err_status_cipher_fail; + } + + /* if we're encrypting, exor keystream into the message */ + if (enc_start) { + status = cipher_encrypt(stream->rtcp_cipher, + (uint8_t *)enc_start, &enc_octet_len); + if (status) + return err_status_cipher_fail; + } + + /* initialize auth func context */ + auth_start(stream->rtcp_auth); + + /* + * run auth func over packet (including trailer), and write the + * result at auth_tag + */ + status = auth_compute(stream->rtcp_auth, + (uint8_t *)auth_start, + (*pkt_octet_len) + sizeof(srtcp_trailer_t), + auth_tag); + debug_print(mod_srtp, "srtcp auth tag: %s", + octet_string_hex_string(auth_tag, tag_len)); + if (status) + return err_status_auth_fail; + + /* increase the packet length by the length of the auth tag and seq_num*/ + *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t)); + + return err_status_ok; +} + + +err_status_t +srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) { + srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr; + uint32_t *enc_start; /* pointer to start of encrypted portion */ + uint32_t *auth_start; /* pointer to start of auth. portion */ + uint32_t *trailer; /* pointer to start of trailer */ + unsigned enc_octet_len = 0;/* number of octets in encrypted portion */ + uint8_t *auth_tag = NULL; /* location of auth_tag within packet */ + uint8_t tmp_tag[SRTP_MAX_TAG_LEN]; + uint8_t tag_copy[SRTP_MAX_TAG_LEN]; + err_status_t status; + unsigned auth_len; + int tag_len; + srtp_stream_ctx_t *stream; + int prefix_len; + uint32_t seq_num; + + /* we assume the hdr is 32-bit aligned to start */ + /* + * look up ssrc in srtp_stream list, and process the packet with + * the appropriate stream. if we haven't seen this stream before, + * there's only one key for this srtp_session, and the cipher + * supports key-sharing, then we assume that a new stream using + * that key has just started up + */ + stream = srtp_get_stream(ctx, hdr->ssrc); + if (stream == NULL) { + if (ctx->stream_template != NULL) { + stream = ctx->stream_template; + + /* + * check to see if stream_template has an EKT data structure, in + * which case we initialize the template using the EKT policy + * referenced by that data (which consists of decrypting the + * master key from the EKT field) + * + * this function initializes a *provisional* stream, and this + * stream should not be accepted until and unless the packet + * passes its authentication check + */ + if (stream->ekt != NULL) { + status = srtp_stream_init_from_ekt(stream, srtcp_hdr, *pkt_octet_len); + if (status) + return status; + } + + debug_print(mod_srtp, "srtcp using provisional stream (SSRC: 0x%08x)", + hdr->ssrc); + } else { + /* no template stream, so we return an error */ + return err_status_no_ctx; + } + } + + /* get tag length from stream context */ + tag_len = auth_get_tag_length(stream->rtcp_auth); + + /* + * set encryption start, encryption length, and trailer + */ + enc_octet_len = *pkt_octet_len - + (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t)); + /* index & E (encryption) bit follow normal data. hdr->len + is the number of words (32-bit) in the normal packet minus 1 */ + /* This should point trailer to the word past the end of the + normal data. */ + /* This would need to be modified for optional mikey data */ + /* + * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always + * multiples of 32-bits (RFC 3550 6.1) + */ + trailer = (uint32_t *) ((char *) hdr + + *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t))); + if (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT) { + enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header; + } else { + enc_octet_len = 0; + enc_start = NULL; /* this indicates that there's no encryption */ + } + + /* + * set the auth_start and auth_tag pointers to the proper locations + * (note that srtcp *always* uses authentication, unlike srtp) + */ + auth_start = (uint32_t *)hdr; + auth_len = *pkt_octet_len - tag_len; + auth_tag = (uint8_t *)hdr + auth_len; + + /* + * if EKT is in use, then we make a copy of the tag from the packet, + * and then zeroize the location of the base tag + * + * we first re-position the auth_tag pointer so that it points to + * the base tag + */ + if (stream->ekt) { + auth_tag -= ekt_octets_after_base_tag(stream->ekt); + memcpy(tag_copy, auth_tag, tag_len); + octet_string_set_to_zero(auth_tag, tag_len); + auth_tag = tag_copy; + auth_len += tag_len; + } + + /* + * check the sequence number for replays + */ + /* this is easier than dealing with bitfield access */ + seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK; + debug_print(mod_srtp, "srtcp index: %x", seq_num); + status = rdb_check(&stream->rtcp_rdb, seq_num); + if (status) + return status; + + /* + * if we're using aes counter mode, set nonce and seq + */ + if (stream->rtcp_cipher->type->id == AES_ICM) { + v128_t iv; + + iv.v32[0] = 0; + iv.v32[1] = hdr->ssrc; /* still in network order! */ + iv.v32[2] = htonl(seq_num >> 16); + iv.v32[3] = htonl(seq_num << 16); + status = cipher_set_iv(stream->rtcp_cipher, &iv); + + } else { + v128_t iv; + + /* otherwise, just set the index to seq_num */ + iv.v32[0] = 0; + iv.v32[1] = 0; + iv.v32[2] = 0; + iv.v32[3] = htonl(seq_num); + status = cipher_set_iv(stream->rtcp_cipher, &iv); + + } + if (status) + return err_status_cipher_fail; + + /* initialize auth func context */ + auth_start(stream->rtcp_auth); + + /* run auth func over packet, put result into tmp_tag */ + status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start, + auth_len, tmp_tag); + debug_print(mod_srtp, "srtcp computed tag: %s", + octet_string_hex_string(tmp_tag, tag_len)); + if (status) + return err_status_auth_fail; + + /* compare the tag just computed with the one in the packet */ + debug_print(mod_srtp, "srtcp tag from packet: %s", + octet_string_hex_string(auth_tag, tag_len)); + if (octet_string_is_eq(tmp_tag, auth_tag, tag_len)) + return err_status_auth_fail; + + /* + * if we're authenticating using a universal hash, put the keystream + * prefix into the authentication tag + */ + prefix_len = auth_get_prefix_length(stream->rtcp_auth); + if (prefix_len) { + status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len); + debug_print(mod_srtp, "keystream prefix: %s", + octet_string_hex_string(auth_tag, prefix_len)); + if (status) + return err_status_cipher_fail; + } + + /* if we're decrypting, exor keystream into the message */ + if (enc_start) { + status = cipher_decrypt(stream->rtcp_cipher, + (uint8_t *)enc_start, &enc_octet_len); + if (status) + return err_status_cipher_fail; + } + + /* decrease the packet length by the length of the auth tag and seq_num */ + *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t)); + + /* + * if EKT is in effect, subtract the EKT data out of the packet + * length + */ + *pkt_octet_len -= ekt_octets_after_base_tag(stream->ekt); + + /* + * verify that stream is for received traffic - this check will + * detect SSRC collisions, since a stream that appears in both + * srtp_protect() and srtp_unprotect() will fail this test in one of + * those functions. + * + * we do this check *after* the authentication check, so that the + * latter check will catch any attempts to fool us into thinking + * that we've got a collision + */ + if (stream->direction != dir_srtp_receiver) { + if (stream->direction == dir_unknown) { + stream->direction = dir_srtp_receiver; + } else { + srtp_handle_event(ctx, stream, event_ssrc_collision); + } + } + + /* + * if the stream is a 'provisional' one, in which the template context + * is used, then we need to allocate a new stream at this point, since + * the authentication passed + */ + if (stream == ctx->stream_template) { + srtp_stream_ctx_t *new_stream; + + /* + * allocate and initialize a new stream + * + * note that we indicate failure if we can't allocate the new + * stream, and some implementations will want to not return + * failure here + */ + status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); + if (status) + return status; + + /* add new stream to the head of the stream_list */ + new_stream->next = ctx->stream_list; + ctx->stream_list = new_stream; + + /* set stream (the pointer used in this function) */ + stream = new_stream; + } + + /* we've passed the authentication check, so add seq_num to the rdb */ + rdb_add_index(&stream->rtcp_rdb, seq_num); + + + return err_status_ok; +} + + + +/* + * dtls keying for srtp + */ + +err_status_t +crypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy, + srtp_profile_t profile) { + + /* set SRTP policy from the SRTP profile in the key set */ + switch(profile) { + case srtp_profile_aes128_cm_sha1_80: + crypto_policy_set_aes_cm_128_hmac_sha1_80(policy); + crypto_policy_set_aes_cm_128_hmac_sha1_80(policy); + break; + case srtp_profile_aes128_cm_sha1_32: + crypto_policy_set_aes_cm_128_hmac_sha1_32(policy); + crypto_policy_set_aes_cm_128_hmac_sha1_80(policy); + break; + case srtp_profile_null_sha1_80: + crypto_policy_set_null_cipher_hmac_sha1_80(policy); + crypto_policy_set_null_cipher_hmac_sha1_80(policy); + break; + case srtp_profile_aes256_cm_sha1_80: + crypto_policy_set_aes_cm_256_hmac_sha1_80(policy); + crypto_policy_set_aes_cm_256_hmac_sha1_80(policy); + break; + case srtp_profile_aes256_cm_sha1_32: + crypto_policy_set_aes_cm_256_hmac_sha1_32(policy); + crypto_policy_set_aes_cm_256_hmac_sha1_80(policy); + break; + /* the following profiles are not (yet) supported */ + case srtp_profile_null_sha1_32: + default: + return err_status_bad_param; + } + + return err_status_ok; +} + +err_status_t +crypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy, + srtp_profile_t profile) { + + /* set SRTP policy from the SRTP profile in the key set */ + switch(profile) { + case srtp_profile_aes128_cm_sha1_80: + crypto_policy_set_aes_cm_128_hmac_sha1_80(policy); + break; + case srtp_profile_aes128_cm_sha1_32: + crypto_policy_set_aes_cm_128_hmac_sha1_80(policy); + break; + case srtp_profile_null_sha1_80: + crypto_policy_set_null_cipher_hmac_sha1_80(policy); + break; + case srtp_profile_aes256_cm_sha1_80: + crypto_policy_set_aes_cm_256_hmac_sha1_80(policy); + break; + case srtp_profile_aes256_cm_sha1_32: + crypto_policy_set_aes_cm_256_hmac_sha1_80(policy); + break; + /* the following profiles are not (yet) supported */ + case srtp_profile_null_sha1_32: + default: + return err_status_bad_param; + } + + return err_status_ok; +} + +void +append_salt_to_key(uint8_t *key, unsigned int bytes_in_key, + uint8_t *salt, unsigned int bytes_in_salt) { + + memcpy(key + bytes_in_key, salt, bytes_in_salt); + +} + +unsigned int +srtp_profile_get_master_key_length(srtp_profile_t profile) { + + switch(profile) { + case srtp_profile_aes128_cm_sha1_80: + return 16; + break; + case srtp_profile_aes128_cm_sha1_32: + return 16; + break; + case srtp_profile_null_sha1_80: + return 16; + break; + case srtp_profile_aes256_cm_sha1_80: + return 32; + break; + case srtp_profile_aes256_cm_sha1_32: + return 32; + break; + /* the following profiles are not (yet) supported */ + case srtp_profile_null_sha1_32: + default: + return 0; /* indicate error by returning a zero */ + } +} + +unsigned int +srtp_profile_get_master_salt_length(srtp_profile_t profile) { + + switch(profile) { + case srtp_profile_aes128_cm_sha1_80: + return 14; + break; + case srtp_profile_aes128_cm_sha1_32: + return 14; + break; + case srtp_profile_null_sha1_80: + return 14; + break; + case srtp_profile_aes256_cm_sha1_80: + return 14; + break; + case srtp_profile_aes256_cm_sha1_32: + return 14; + break; + /* the following profiles are not (yet) supported */ + case srtp_profile_null_sha1_32: + default: + return 0; /* indicate error by returning a zero */ + } +} diff --git a/src/libs/srtp/srtp7.sln b/src/libs/srtp/srtp7.sln new file mode 100644 index 00000000..0a9c51d4 --- /dev/null +++ b/src/libs/srtp/srtp7.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libSRTP", "srtp7.vcproj", "{7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Debug.ActiveCfg = Debug|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Debug.Build.0 = Debug|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Release.ActiveCfg = Release|Win32 + {7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/libs/srtp/srtp7.vcproj b/src/libs/srtp/srtp7.vcproj new file mode 100644 index 00000000..3bdd15d8 --- /dev/null +++ b/src/libs/srtp/srtp7.vcproj @@ -0,0 +1,298 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="libSRTP" + ProjectGUID="{7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + InlineFunctionExpansion="0" + AdditionalIncludeDirectories="C:\dev\foo\srtp;&quot;$(SolutionDir)&quot;;.\include;.\crypto\include;&quot;..\..\OpenSSL\openssl-0.9.7i\inc32&quot;;&quot;C:Library\OpenSSL\openssl-0.9.8\inc32&quot;" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;DEBUG" + ExceptionHandling="FALSE" + BasicRuntimeChecks="0" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4" + CompileAs="1"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Ws2_32.lib libeay32.lib ssleay32.lib" + AdditionalLibraryDirectories="&quot;Library\OpenSSL\openssl-0.9.8\libs&quot;" + GenerateDebugInformation="TRUE"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="&quot;.\include&quot;;&quot;.\crypto\include&quot;;&quot;..\..\OpenSSL\openssl-0.9.7i\inc32&quot;" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + BasicRuntimeChecks="0" + RuntimeLibrary="0" + UsePrecompiledHeader="0" + ObjectFile="$(IntDir)/" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath=".\test\getopt.c"> + </File> + <File + RelativePath=".\srtp\srtp.c"> + </File> + <File + RelativePath=".\test\srtp_driver.c"> + </File> + <Filter + Name="Kernel"> + <File + RelativePath=".\crypto\kernel\alloc.c"> + </File> + <File + RelativePath=".\crypto\kernel\crypto_kernel.c"> + </File> + <File + RelativePath=".\crypto\rng\ctr_prng.c"> + </File> + <File + RelativePath=".\crypto\kernel\err.c"> + </File> + <File + RelativePath=".\crypto\kernel\key.c"> + </File> + <File + RelativePath=".\crypto\rng\prng.c"> + </File> + <File + RelativePath=".\crypto\rng\rand_source.c"> + </File> + </Filter> + <Filter + Name="Ciphers"> + <File + RelativePath=".\crypto\cipher\aes.c"> + </File> + <File + RelativePath=".\crypto\cipher\aes_cbc.c"> + </File> + <File + RelativePath=".\crypto\cipher\aes_icm.c"> + </File> + <File + RelativePath=".\crypto\cipher\cipher.c"> + </File> + <File + RelativePath=".\crypto\cipher\null_cipher.c"> + </File> + </Filter> + <Filter + Name="Hashes"> + <File + RelativePath=".\crypto\hash\auth.c"> + </File> + <File + RelativePath=".\crypto\hash\hmac.c"> + </File> + <File + RelativePath=".\crypto\hash\null_auth.c"> + </File> + <File + RelativePath=".\crypto\hash\sha1.c"> + </File> + </Filter> + <Filter + Name="Replay"> + <File + RelativePath=".\crypto\replay\rdb.c"> + </File> + <File + RelativePath=".\crypto\replay\rdbx.c"> + </File> + <File + RelativePath=".\crypto\replay\ut_sim.c"> + </File> + </Filter> + <Filter + Name="Math"> + <File + RelativePath=".\crypto\math\datatypes.c"> + </File> + <File + RelativePath=".\crypto\math\stat.c"> + </File> + </Filter> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath=".\crypto\include\aes.h"> + </File> + <File + RelativePath=".\crypto\include\aes_cbc.h"> + </File> + <File + RelativePath=".\crypto\include\aes_icm.h"> + </File> + <File + RelativePath=".\crypto\include\alloc.h"> + </File> + <File + RelativePath=".\crypto\include\auth.h"> + </File> + <File + RelativePath=".\crypto\include\cipher.h"> + </File> + <File + RelativePath=".\crypto\include\config.h"> + </File> + <File + RelativePath=".\crypto\include\crypto.h"> + </File> + <File + RelativePath=".\crypto\include\crypto_kernel.h"> + </File> + <File + RelativePath=".\crypto\include\crypto_math.h"> + </File> + <File + RelativePath=".\crypto\include\crypto_types.h"> + </File> + <File + RelativePath=".\crypto\include\cryptoalg.h"> + </File> + <File + RelativePath=".\crypto\include\datatypes.h"> + </File> + <File + RelativePath=".\crypto\include\err.h"> + </File> + <File + RelativePath=".\crypto\include\gf2_8.h"> + </File> + <File + RelativePath=".\crypto\include\hmac.h"> + </File> + <File + RelativePath=".\crypto\include\integers.h"> + </File> + <File + RelativePath=".\crypto\include\kernel_compat.h"> + </File> + <File + RelativePath=".\crypto\include\key.h"> + </File> + <File + RelativePath=".\crypto\include\null_auth.h"> + </File> + <File + RelativePath=".\crypto\include\null_cipher.h"> + </File> + <File + RelativePath=".\crypto\include\prng.h"> + </File> + <File + RelativePath=".\crypto\include\rand_source.h"> + </File> + <File + RelativePath=".\crypto\include\rdb.h"> + </File> + <File + RelativePath=".\crypto\include\rdbx.h"> + </File> + <File + RelativePath=".\include\rtp.h"> + </File> + <File + RelativePath=".\crypto\include\sha1.h"> + </File> + <File + RelativePath=".\include\srtp.h"> + </File> + <File + RelativePath=".\crypto\include\stat.h"> + </File> + <File + RelativePath=".\include\ut_sim.h"> + </File> + <File + RelativePath=".\crypto\include\xfm.h"> + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/srtp/srtp7.vcxproj b/src/libs/srtp/srtp7.vcxproj new file mode 100644 index 00000000..a9d89617 --- /dev/null +++ b/src/libs/srtp/srtp7.vcxproj @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>libSRTP</ProjectName> + <ProjectGuid>{7E1E1308-F82E-4DD3-B25C-CD12756A1DD9}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>Debug\</OutDir> + <IntDir>Debug\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>Release\</OutDir> + <IntDir>Release\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <AdditionalIncludeDirectories>C:\dev\foo\srtp;$(SolutionDir);.\include;.\crypto\include;..\..\OpenSSL\openssl-0.9.7i\inc32;C:Library\OpenSSL\openssl-0.9.8\inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ExceptionHandling /> + <BasicRuntimeChecks>Default</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <CompileAs>CompileAsC</CompileAs> + </ClCompile> + <Link> + <AdditionalDependencies>Ws2_32.lib;libeay32.lib;ssleay32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>Library\OpenSSL\openssl-0.9.8\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>.\include;.\crypto\include;..\..\OpenSSL\openssl-0.9.7i\inc32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <BasicRuntimeChecks>Default</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <PrecompiledHeader /> + <ObjectFileName>$(IntDir)</ObjectFileName> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="test\getopt.c" /> + <ClCompile Include="srtp\srtp.c" /> + <ClCompile Include="test\srtp_driver.c" /> + <ClCompile Include="crypto\kernel\alloc.c" /> + <ClCompile Include="crypto\kernel\crypto_kernel.c" /> + <ClCompile Include="crypto\rng\ctr_prng.c" /> + <ClCompile Include="crypto\kernel\err.c" /> + <ClCompile Include="crypto\kernel\key.c" /> + <ClCompile Include="crypto\rng\prng.c" /> + <ClCompile Include="crypto\rng\rand_source.c" /> + <ClCompile Include="crypto\cipher\aes.c" /> + <ClCompile Include="crypto\cipher\aes_cbc.c" /> + <ClCompile Include="crypto\cipher\aes_icm.c" /> + <ClCompile Include="crypto\cipher\cipher.c" /> + <ClCompile Include="crypto\cipher\null_cipher.c" /> + <ClCompile Include="crypto\hash\auth.c" /> + <ClCompile Include="crypto\hash\hmac.c" /> + <ClCompile Include="crypto\hash\null_auth.c" /> + <ClCompile Include="crypto\hash\sha1.c" /> + <ClCompile Include="crypto\replay\rdb.c" /> + <ClCompile Include="crypto\replay\rdbx.c" /> + <ClCompile Include="crypto\replay\ut_sim.c" /> + <ClCompile Include="crypto\math\datatypes.c" /> + <ClCompile Include="crypto\math\stat.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="crypto\include\aes.h" /> + <ClInclude Include="crypto\include\aes_cbc.h" /> + <ClInclude Include="crypto\include\aes_icm.h" /> + <ClInclude Include="crypto\include\alloc.h" /> + <ClInclude Include="crypto\include\auth.h" /> + <ClInclude Include="crypto\include\cipher.h" /> + <ClInclude Include="crypto\include\config.h" /> + <ClInclude Include="crypto\include\crypto.h" /> + <ClInclude Include="crypto\include\crypto_kernel.h" /> + <ClInclude Include="crypto\include\crypto_math.h" /> + <ClInclude Include="crypto\include\crypto_types.h" /> + <ClInclude Include="crypto\include\cryptoalg.h" /> + <ClInclude Include="crypto\include\datatypes.h" /> + <ClInclude Include="crypto\include\err.h" /> + <ClInclude Include="crypto\include\gf2_8.h" /> + <ClInclude Include="crypto\include\hmac.h" /> + <ClInclude Include="crypto\include\integers.h" /> + <ClInclude Include="crypto\include\kernel_compat.h" /> + <ClInclude Include="crypto\include\key.h" /> + <ClInclude Include="crypto\include\null_auth.h" /> + <ClInclude Include="crypto\include\null_cipher.h" /> + <ClInclude Include="crypto\include\prng.h" /> + <ClInclude Include="crypto\include\rand_source.h" /> + <ClInclude Include="crypto\include\rdb.h" /> + <ClInclude Include="crypto\include\rdbx.h" /> + <ClInclude Include="include\rtp.h" /> + <ClInclude Include="crypto\include\sha1.h" /> + <ClInclude Include="include\srtp.h" /> + <ClInclude Include="crypto\include\stat.h" /> + <ClInclude Include="include\ut_sim.h" /> + <ClInclude Include="crypto\include\xfm.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/srtp/srtp7.vcxproj.filters b/src/libs/srtp/srtp7.vcxproj.filters new file mode 100644 index 00000000..eff4fbc1 --- /dev/null +++ b/src/libs/srtp/srtp7.vcxproj.filters @@ -0,0 +1,197 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Source Files\Kernel"> + <UniqueIdentifier>{4ea46c0f-d6f6-4b35-86e2-ba837dbe3e1b}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Ciphers"> + <UniqueIdentifier>{0933114f-0a66-436e-990d-ac7d1a7715e8}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Hashes"> + <UniqueIdentifier>{b0669cda-f145-43bf-b77d-94fcca038e8b}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Replay"> + <UniqueIdentifier>{da567fba-20a4-4fd2-a260-cfbd2d8d4e55}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Math"> + <UniqueIdentifier>{eac83b01-a82f-49c3-b993-251090349cd7}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="test\getopt.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="srtp\srtp.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="test\srtp_driver.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="crypto\kernel\alloc.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\kernel\crypto_kernel.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\rng\ctr_prng.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\kernel\err.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\kernel\key.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\rng\prng.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\rng\rand_source.c"> + <Filter>Source Files\Kernel</Filter> + </ClCompile> + <ClCompile Include="crypto\cipher\aes.c"> + <Filter>Source Files\Ciphers</Filter> + </ClCompile> + <ClCompile Include="crypto\cipher\aes_cbc.c"> + <Filter>Source Files\Ciphers</Filter> + </ClCompile> + <ClCompile Include="crypto\cipher\aes_icm.c"> + <Filter>Source Files\Ciphers</Filter> + </ClCompile> + <ClCompile Include="crypto\cipher\cipher.c"> + <Filter>Source Files\Ciphers</Filter> + </ClCompile> + <ClCompile Include="crypto\cipher\null_cipher.c"> + <Filter>Source Files\Ciphers</Filter> + </ClCompile> + <ClCompile Include="crypto\hash\auth.c"> + <Filter>Source Files\Hashes</Filter> + </ClCompile> + <ClCompile Include="crypto\hash\hmac.c"> + <Filter>Source Files\Hashes</Filter> + </ClCompile> + <ClCompile Include="crypto\hash\null_auth.c"> + <Filter>Source Files\Hashes</Filter> + </ClCompile> + <ClCompile Include="crypto\hash\sha1.c"> + <Filter>Source Files\Hashes</Filter> + </ClCompile> + <ClCompile Include="crypto\replay\rdb.c"> + <Filter>Source Files\Replay</Filter> + </ClCompile> + <ClCompile Include="crypto\replay\rdbx.c"> + <Filter>Source Files\Replay</Filter> + </ClCompile> + <ClCompile Include="crypto\replay\ut_sim.c"> + <Filter>Source Files\Replay</Filter> + </ClCompile> + <ClCompile Include="crypto\math\datatypes.c"> + <Filter>Source Files\Math</Filter> + </ClCompile> + <ClCompile Include="crypto\math\stat.c"> + <Filter>Source Files\Math</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="crypto\include\aes.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\aes_cbc.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\aes_icm.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\alloc.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\auth.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\cipher.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\config.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\crypto.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\crypto_kernel.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\crypto_math.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\crypto_types.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\cryptoalg.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\datatypes.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\err.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\gf2_8.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\hmac.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\integers.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\kernel_compat.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\key.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\null_auth.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\null_cipher.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\prng.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\rand_source.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\rdb.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\rdbx.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="include\rtp.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\sha1.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="include\srtp.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\stat.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="include\ut_sim.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="crypto\include\xfm.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/srtp/tables/aes_tables.c b/src/libs/srtp/tables/aes_tables.c new file mode 100644 index 00000000..b2bc1d78 --- /dev/null +++ b/src/libs/srtp/tables/aes_tables.c @@ -0,0 +1,346 @@ +/* + * aes_tables.c + * + * generate tables for the AES cipher + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> +#include "gf2_8.h" +#include "crypto_math.h" + + +unsigned char aes_sbox[256]; + +unsigned char aes_inv_sbox[256]; + +uint32_t T0[256], T1[256], T2[256], T3[256], T4[256]; + + +#define AES_INVERSE_TEST 0 /* set to 1 to test forward/backwards aes */ + +/* functions for precomputing AES values */ + +/* + * A[] is the 8 x 8 binary matrix (represented as an array of columns, + * where each column is an octet) which defines the affine + * transformation used in the AES substitution table (Section + * 4.2.1 of the spec). + */ + +uint8_t A[8] = { 31, 62, 124, 248, 241, 227, 199, 143 }; + +/* + * b is the 8 bit vector (represented as an octet) used in the affine + * transform described above. + */ + +uint8_t b = 99; + + +void +aes_init_sbox(void) { + unsigned int i; + uint8_t x; + + for (i=0; i < 256; i++) { + x = gf2_8_compute_inverse((gf2_8)i); + x = A_times_x_plus_b(A, x, b); + aes_sbox[i] = x; + aes_inv_sbox[x] = i; + } +} + +void +aes_compute_tables(void) { + int i; + uint32_t x1, x2, x3; + v32_t tmp; + + /* initialize substitution table */ + aes_init_sbox(); + + /* combine sbox with linear operations to form 8-bit to 32-bit tables */ + for (i=0; i < 256; i++) { + x1 = aes_sbox[i]; + x2 = gf2_8_shift(x1); + x3 = x2 ^ x1; + + tmp.v8[0] = x2; + tmp.v8[1] = x1; + tmp.v8[2] = x1; + tmp.v8[3] = x3; + T0[i] = tmp.value; + + tmp.v8[0] = x3; + tmp.v8[1] = x2; + tmp.v8[2] = x1; + tmp.v8[3] = x1; + T1[i] = tmp.value; + + tmp.v8[0] = x1; + tmp.v8[1] = x3; + tmp.v8[2] = x2; + tmp.v8[3] = x1; + T2[i] = tmp.value; + + tmp.v8[0] = x1; + tmp.v8[1] = x1; + tmp.v8[2] = x3; + tmp.v8[3] = x2; + T3[i] = tmp.value; + + } +} + + +/* + * the tables U0, U1, U2, U3 implement the aes operations invSubBytes, + * invMixColumns, and invShiftRows + */ + +uint32_t U0[256], U1[256], U2[256], U3[256], U4[256]; + +extern uint8_t aes_inv_sbox[256]; + +void +aes_compute_inv_tables(void) { + int i; + uint8_t x, xe, x9, xd, xb; + v32_t tmp; + + /* combine sbox with linear operations to form 8-bit to 32-bit tables */ + for (i=0; i < 256; i++) { + x = aes_inv_sbox[i]; + + xe = gf2_8_multiply(0x0e, x); + x9 = gf2_8_multiply(0x09, x); + xd = gf2_8_multiply(0x0d, x); + xb = gf2_8_multiply(0x0b, x); + + tmp.v8[0] = xe; + tmp.v8[1] = x9; + tmp.v8[2] = xd; + tmp.v8[3] = xb; + U0[i] = tmp.value; + + tmp.v8[0] = xb; + tmp.v8[1] = xe; + tmp.v8[2] = x9; + tmp.v8[3] = xd; + U1[i] = tmp.value; + + tmp.v8[0] = xd; + tmp.v8[1] = xb; + tmp.v8[2] = xe; + tmp.v8[3] = x9; + U2[i] = tmp.value; + + tmp.v8[0] = x9; + tmp.v8[1] = xd; + tmp.v8[2] = xb; + tmp.v8[3] = xe; + U3[i] = tmp.value; + + tmp.v8[0] = tmp.v8[1] = tmp.v8[2] = tmp.v8[3] = x; + U4[i] = tmp.value; + } +} + + +/* + * aes_test_inverse() returns err_status_ok if aes + * encryption and decryption are true inverses of each other, and + * returns err_status_algo_fail otherwise + */ + +#include "err.h" + +err_status_t +aes_test_inverse(void); + +#define TABLES_32BIT 1 + +int +main(void) { + int i; + + aes_init_sbox(); + aes_compute_inv_tables(); + +#if TABLES_32BIT + printf("uint32_t U0 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%0x, ", U0[i]); + } + printf("\n}\n"); + + printf("uint32_t U1 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%x, ", U1[i]); + } + printf("\n}\n"); + + printf("uint32_t U2 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%x, ", U2[i]); + } + printf("\n}\n"); + + printf("uint32_t U3 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%x, ", U3[i]); + } + printf("\n}\n"); + + printf("uint32_t U4 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%x, ", U4[i]); + } + printf("\n}\n"); + +#else + + printf("uint32_t U0 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%lx, ", U0[i]); + } + printf("\n}\n"); + + printf("uint32_t U1 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%lx, ", U1[i]); + } + printf("\n}\n"); + + printf("uint32_t U2 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%lx, ", U2[i]); + } + printf("\n}\n"); + + printf("uint32_t U3 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%lx, ", U3[i]); + } + printf("\n}\n"); + + printf("uint32_t U4 = {"); + for (i=0; i < 256; i++) { + if ((i % 4) == 0) + printf("\n"); + printf("0x%lx, ", U4[i]); + } + printf("\n}\n"); + + +#endif /* TABLES_32BIT */ + + +#if AES_INVERSE_TEST + /* + * test that aes_encrypt and aes_decrypt are actually + * inverses of each other + */ + + printf("aes inverse test: "); + if (aes_test_inverse() == err_status_ok) + printf("passed\n"); + else { + printf("failed\n"); + exit(1); + } +#endif + + return 0; +} + +#if AES_INVERSE_TEST + +err_status_t +aes_test_inverse(void) { + v128_t x, y; + aes_expanded_key_t expanded_key, decrypt_key; + uint8_t plaintext[16] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff + }; + uint8_t key[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + }; + v128_t k; + v128_set_to_zero(&x); + + v128_copy_octet_string(&k, key); + v128_copy_octet_string(&x, plaintext); + aes_expand_encryption_key(k, expanded_key); + aes_expand_decryption_key(k, decrypt_key); + aes_encrypt(&x, expanded_key); + aes_decrypt(&x, decrypt_key); + + /* compare to expected value then report */ + v128_copy_octet_string(&y, plaintext); + + if (v128_is_eq(&x, &y)) + return err_status_ok; + return err_status_algo_fail; + +} + +#endif diff --git a/src/libs/srtp/test/dtls_srtp_driver.c b/src/libs/srtp/test/dtls_srtp_driver.c new file mode 100644 index 00000000..48e72fbf --- /dev/null +++ b/src/libs/srtp/test/dtls_srtp_driver.c @@ -0,0 +1,261 @@ +/* + * dtls_srtp_driver.c + * + * test driver for DTLS-SRTP functions + * + * David McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> /* for printf() */ +#include "getopt_s.h" /* for local getopt() */ +#include "srtp_priv.h" + +err_status_t +test_dtls_srtp(void); + +srtp_hdr_t * +srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc); + +void +usage(char *prog_name) { + printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n" + " -d <mod> turn on debugging module <mod>\n" + " -l list debugging modules\n", prog_name); + exit(1); +} + +int +main(int argc, char *argv[]) { + unsigned do_list_mods = 0; + int q; + err_status_t err; + + printf("dtls_srtp_driver\n"); + + /* initialize srtp library */ + err = srtp_init(); + if (err) { + printf("error: srtp init failed with error code %d\n", err); + exit(1); + } + + /* process input arguments */ + while (1) { + q = getopt_s(argc, argv, "ld:"); + if (q == -1) + break; + switch (q) { + case 'l': + do_list_mods = 1; + break; + case 'd': + err = crypto_kernel_set_debug_module(optarg_s, 1); + if (err) { + printf("error: set debug module (%s) failed\n", optarg_s); + exit(1); + } + break; + default: + usage(argv[0]); + } + } + + if (do_list_mods) { + err = crypto_kernel_list_debug_modules(); + if (err) { + printf("error: list of debug modules failed\n"); + exit(1); + } + } + + printf("testing dtls_srtp..."); + err = test_dtls_srtp(); + if (err) { + printf("\nerror (code %d)\n", err); + exit(1); + } + printf("passed\n"); + + /* shut down srtp library */ + err = srtp_shutdown(); + if (err) { + printf("error: srtp shutdown failed with error code %d\n", err); + exit(1); + } + + return 0; +} + + +err_status_t +test_dtls_srtp(void) { + srtp_hdr_t *test_packet; + int test_packet_len = 80; + srtp_t s; + srtp_policy_t policy; + uint8_t key[SRTP_MAX_KEY_LEN]; + uint8_t salt[SRTP_MAX_KEY_LEN]; + unsigned int key_len, salt_len; + srtp_profile_t profile; + err_status_t err; + + /* create a 'null' SRTP session */ + err = srtp_create(&s, NULL); + if (err) + return err; + + /* + * verify that packet-processing functions behave properly - we + * expect that these functions will return err_status_no_ctx + */ + test_packet = srtp_create_test_packet(80, 0xa5a5a5a5); + if (test_packet == NULL) + return err_status_alloc_fail; + err = srtp_protect(s, test_packet, &test_packet_len); + if (err != err_status_no_ctx) { + printf("wrong return value from srtp_protect() (got code %d)\n", + err); + return err_status_fail; + } + err = srtp_unprotect(s, test_packet, &test_packet_len); + if (err != err_status_no_ctx) { + printf("wrong return value from srtp_unprotect() (got code %d)\n", + err); + return err_status_fail; + } + err = srtp_protect_rtcp(s, test_packet, &test_packet_len); + if (err != err_status_no_ctx) { + printf("wrong return value from srtp_protect_rtcp() (got code %d)\n", + err); + return err_status_fail; + } + err = srtp_unprotect_rtcp(s, test_packet, &test_packet_len); + if (err != err_status_no_ctx) { + printf("wrong return value from srtp_unprotect_rtcp() (got code %d)\n", + err); + return err_status_fail; + } + + + /* + * set keys to known values for testing + */ + profile = srtp_profile_aes128_cm_sha1_80; + key_len = srtp_profile_get_master_key_length(profile); + salt_len = srtp_profile_get_master_salt_length(profile); + memset(key, 0xff, key_len); + memset(salt, 0xee, salt_len); + append_salt_to_key(key, key_len, salt, salt_len); + policy.key = key; + + /* initialize SRTP policy from profile */ + err = crypto_policy_set_from_profile_for_rtp(&policy.rtp, profile); + if (err) return err; + err = crypto_policy_set_from_profile_for_rtcp(&policy.rtcp, profile); + if (err) return err; + policy.ssrc.type = ssrc_any_inbound; + policy.ekt = NULL; + policy.window_size = 128; + policy.allow_repeat_tx = 0; + policy.next = NULL; + + err = srtp_add_stream(s, &policy); + if (err) + return err; + + err = srtp_dealloc(s); + if (err) + return err; + + free(test_packet); + + return err_status_ok; +} + + + +/* + * srtp_create_test_packet(len, ssrc) returns a pointer to a + * (malloced) example RTP packet whose data field has the length given + * by pkt_octet_len and the SSRC value ssrc. The total length of the + * packet is twelve octets longer, since the header is at the + * beginning. There is room at the end of the packet for a trailer, + * and the four octets following the packet are filled with 0xff + * values to enable testing for overwrites. + * + * note that the location of the test packet can (and should) be + * deallocated with the free() call once it is no longer needed. + */ + +srtp_hdr_t * +srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) { + int i; + uint8_t *buffer; + srtp_hdr_t *hdr; + int bytes_in_hdr = 12; + + /* allocate memory for test packet */ + hdr = malloc(pkt_octet_len + bytes_in_hdr + + SRTP_MAX_TRAILER_LEN + 4); + if (!hdr) + return NULL; + + hdr->version = 2; /* RTP version two */ + hdr->p = 0; /* no padding needed */ + hdr->x = 0; /* no header extension */ + hdr->cc = 0; /* no CSRCs */ + hdr->m = 0; /* marker bit */ + hdr->pt = 0xf; /* payload type */ + hdr->seq = htons(0x1234); /* sequence number */ + hdr->ts = htonl(0xdecafbad); /* timestamp */ + hdr->ssrc = htonl(ssrc); /* synch. source */ + + buffer = (uint8_t *)hdr; + buffer += bytes_in_hdr; + + /* set RTP data to 0xab */ + for (i=0; i < pkt_octet_len; i++) + *buffer++ = 0xab; + + /* set post-data value to 0xffff to enable overrun checking */ + for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++) + *buffer++ = 0xff; + + return hdr; +} diff --git a/src/libs/srtp/test/getopt_s.c b/src/libs/srtp/test/getopt_s.c new file mode 100644 index 00000000..243ad6e3 --- /dev/null +++ b/src/libs/srtp/test/getopt_s.c @@ -0,0 +1,112 @@ +/* + * getopt.c + * + * a minimal implementation of the getopt() function, written so that + * test applications that use that function can run on non-POSIX + * platforms + * + */ +/* + * + * Copyright (c) 2001-2006 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdlib.h> /* for NULL */ + +int optind_s = 0; + +char *optarg_s; + +#define GETOPT_FOUND_WITHOUT_ARGUMENT 2 +#define GETOPT_FOUND_WITH_ARGUMENT 1 +#define GETOPT_NOT_FOUND 0 + +static int +getopt_check_character(char c, const char *string) { + unsigned int max_string_len = 128; + + while (*string != 0) { + if (max_string_len == 0) { + return '?'; + } + if (*string++ == c) { + if (*string == ':') { + return GETOPT_FOUND_WITH_ARGUMENT; + } else { + return GETOPT_FOUND_WITHOUT_ARGUMENT; + } + } + } + return GETOPT_NOT_FOUND; +} + +int +getopt_s(int argc, + char * const argv[], + const char *optstring) { + + + while (optind_s + 1 < argc) { + char *string; + + /* move 'string' on to next argument */ + optind_s++; + string = argv[optind_s]; + + if (string == NULL) + return '?'; /* NULL argument string */ + + if (string[0] != '-') + return -1; /* found an unexpected character */ + + switch(getopt_check_character(string[1], optstring)) { + case GETOPT_FOUND_WITH_ARGUMENT: + if (optind_s + 1 < argc) { + optind_s++; + optarg_s = argv[optind_s]; + return string[1]; + } else { + return '?'; /* argument missing */ + } + case GETOPT_FOUND_WITHOUT_ARGUMENT: + return string[1]; + case GETOPT_NOT_FOUND: + default: + return '?'; /* didn't find expected character */ + break; + } + } + + return -1; +} diff --git a/src/libs/srtp/test/lfsr.c b/src/libs/srtp/test/lfsr.c new file mode 100644 index 00000000..28ea02eb --- /dev/null +++ b/src/libs/srtp/test/lfsr.c @@ -0,0 +1,310 @@ +/* + * lfsr.c + * + */ + + +#include <stdio.h> +#include "datatypes.h" + +uint32_t +parity(uint32_t x) { + + x ^= (x >> 16); + x ^= (x >> 8); + x ^= (x >> 4); + x ^= (x >> 2); + x ^= (x >> 1); + + return x & 1; +} + + +/* typedef struct { */ +/* uint32_t register[8]; */ +/* } lfsr_t; */ + +void +compute_period(uint32_t feedback_polynomial) { + int i; + v32_t lfsr; + v32_t mask; + + mask.value = feedback_polynomial; + lfsr.value = 1; + + printf("polynomial: %s\t", v32_bit_string(mask)); + + for (i=0; i < 256; i++) { +/* printf("%s\n", v32_bit_string(lfsr)); */ + if (parity(mask.value & lfsr.value)) + lfsr.value = ((lfsr.value << 1) | 1) & 0xff; + else + lfsr.value = (lfsr.value << 1) & 0xff; + + /* now halt if we're back at the initial state */ + if (lfsr.value == 1) { + printf("period: %d\n", i); + break; + } + } +} + +uint32_t poly0 = 223; + + +uint32_t polynomials[39] = { +31, +47, +55, +59, +61, +79, +87, +91, +103, +107, +109, +115, +117, +121, +143, +151, +157, +167, +171, +173, +179, +181, +185, +199, +203, +205, +211, +213, +227, +229, +233, +241, +127, +191, +223, +239, +247, +251, +253 +}; + +char binary_string[32]; + +char * +u32_bit_string(uint32_t x, unsigned int length) { + unsigned int mask; + int index; + + mask = 1 << length; + index = 0; + for (; mask > 0; mask >>= 1) + if ((x & mask) == 0) + binary_string[index++] = '0'; + else + binary_string[index++] = '1'; + + binary_string[index++] = 0; /* NULL terminate string */ + return binary_string; +} + +extern int octet_weight[256]; + +unsigned int +weight(uint32_t poly) { + int wt = 0; + + /* note: endian-ness makes no difference */ + wt += octet_weight[poly & 0xff]; + wt += octet_weight[(poly >> 8) & 0xff]; + wt += octet_weight[(poly >> 16) & 0xff]; + wt += octet_weight[(poly >> 24)]; + + return wt; +} + +#define MAX_PERIOD 65535 + +#define debug_print 0 + +int +period(uint32_t poly) { + int i; + uint32_t x; + + + /* set lfsr to 1 */ + x = 1; +#if debug_print + printf("%d:\t%s\n", 0, u32_bit_string(x,8)); +#endif + for (i=1; i < MAX_PERIOD; i++) { + if (x & 1) + x = (x >> 1) ^ poly; + else + x = (x >> 1); + +#if debug_print + /* print for a sanity check */ + printf("%d:\t%s\n", i, u32_bit_string(x,8)); +#endif + + /* check for return to original value */ + if (x == 1) + return i; + } + return i; +} + +/* + * weight distribution computes the weight distribution of the + * code generated by the polynomial poly + */ + +#define MAX_LEN 8 +#define MAX_WEIGHT (1 << MAX_LEN) + +int A[MAX_WEIGHT+1]; + +void +weight_distribution2(uint32_t poly, int *A) { + int i; + uint32_t x; + + /* zeroize array */ + for (i=0; i < MAX_WEIGHT+1; i++) + A[i] = 0; + + /* loop over all input sequences */ + + + /* set lfsr to 1 */ + x = 1; +#if debug_print + printf("%d:\t%s\n", 0, u32_bit_string(x,8)); +#endif + for (i=1; i < MAX_PERIOD; i++) { + if (x & 1) + x = (x >> 1) ^ poly; + else + x = (x >> 1); + +#if debug_print + /* print for a sanity check */ + printf("%d:\t%s\n", i, u32_bit_string(x,8)); +#endif + + /* increment weight */ + wt += (x & 1); + + /* check for return to original value */ + if (x == 1) + break; + } + + /* set zero */ + A[0] = 0; +} + + +void +weight_distribution(uint32_t poly, int *A) { + int i; + uint32_t x; + + /* zeroize array */ + for (i=0; i < MAX_WEIGHT+1; i++) + A[i] = 0; + + /* set lfsr to 1 */ + x = 1; +#if debug_print + printf("%d:\t%s\n", 0, u32_bit_string(x,8)); +#endif + for (i=1; i < MAX_PERIOD; i++) { + if (x & 1) + x = (x >> 1) ^ poly; + else + x = (x >> 1); + +#if debug_print + /* print for a sanity check */ + printf("%d:\t%s\n", i, u32_bit_string(x,8)); +#endif + + /* compute weight, increment proper element */ + A[weight(x)]++; + + /* check for return to original value */ + if (x == 1) + break; + } + + /* set zero */ + A[0] = 0; +} + + + + +int +main () { + + int i,j; + v32_t x; + v32_t p; + + /* originally 0xaf */ + p.value = 0x9; + + printf("polynomial: %s\tperiod: %d\n", + u32_bit_string(p.value,8), period(p.value)); + + /* compute weight distribution */ + weight_distribution(p.value, A); + + /* print weight distribution */ + for (i=0; i <= 8; i++) { + printf("A[%d]: %d\n", i, A[i]); + } + +#if 0 + for (i=0; i < 39; i++) { + printf("polynomial: %s\tperiod: %d\n", + u32_bit_string(polynomials[i],8), period(polynomials[i])); + + /* compute weight distribution */ + weight_distribution(p.value, A); + + /* print weight distribution */ + for (j=0; j <= 8; j++) { + printf("A[%d]: %d\n", j, A[j]); + } + } +#endif + + { + int bits = 8; + uint32_t y; + for (y=0; y < (1 << bits); y++) { + printf("polynomial: %s\tweight: %d\tperiod: %d\n", + u32_bit_string(y,bits), weight(y), period(y)); + + /* compute weight distribution */ + weight_distribution(y, A); + + /* print weight distribution */ + for (j=0; j <= 8; j++) { + printf("A[%d]: %d\n", j, A[j]); + } + } + } + + return 0; +} diff --git a/src/libs/srtp/test/rdbx_driver.c b/src/libs/srtp/test/rdbx_driver.c new file mode 100644 index 00000000..838cc43a --- /dev/null +++ b/src/libs/srtp/test/rdbx_driver.c @@ -0,0 +1,362 @@ +/* + * rdbx_driver.c + * + * driver for the rdbx implementation (replay database with extended range) + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> /* for printf() */ +#include "getopt_s.h" /* for local getopt() */ + +#include "rdbx.h" + +#ifdef ROC_TEST +#error "rdbx_t won't work with ROC_TEST - bitmask same size as seq_median" +#endif + +#include "ut_sim.h" + +err_status_t +test_replay_dbx(int num_trials, unsigned long ws); + +double +rdbx_check_adds_per_second(int num_trials, unsigned long ws); + +void +usage(char *prog_name) { + printf("usage: %s [ -t | -v ]\n", prog_name); + exit(255); +} + +int +main (int argc, char *argv[]) { + double rate; + err_status_t status; + int q; + unsigned do_timing_test = 0; + unsigned do_validation = 0; + + /* process input arguments */ + while (1) { + q = getopt_s(argc, argv, "tv"); + if (q == -1) + break; + switch (q) { + case 't': + do_timing_test = 1; + break; + case 'v': + do_validation = 1; + break; + default: + usage(argv[0]); + } + } + + printf("rdbx (replay database w/ extended range) test driver\n" + "David A. McGrew\n" + "Cisco Systems, Inc.\n"); + + if (!do_validation && !do_timing_test) + usage(argv[0]); + + if (do_validation) { + printf("testing rdbx_t (ws=128)...\n"); + + status = test_replay_dbx(1 << 12, 128); + if (status) { + printf("failed\n"); + exit(1); + } + printf("passed\n"); + + printf("testing rdbx_t (ws=1024)...\n"); + + status = test_replay_dbx(1 << 12, 1024); + if (status) { + printf("failed\n"); + exit(1); + } + printf("passed\n"); + } + + if (do_timing_test) { + rate = rdbx_check_adds_per_second(1 << 18, 128); + printf("rdbx_check/replay_adds per second (ws=128): %e\n", rate); + rate = rdbx_check_adds_per_second(1 << 18, 1024); + printf("rdbx_check/replay_adds per second (ws=1024): %e\n", rate); + } + + return 0; +} + +void +print_rdbx(rdbx_t *rdbx) { + char buf[2048]; + printf("rdbx: {%llu, %s}\n", + (unsigned long long)(rdbx->index), + bitvector_bit_string(&rdbx->bitmask, buf, sizeof(buf)) +); +} + + +/* + * rdbx_check_add(rdbx, idx) checks a known-to-be-good idx against + * rdbx, then adds it. if a failure is detected (i.e., the check + * indicates that the value is already in rdbx) then + * err_status_algo_fail is returned. + * + */ + +err_status_t +rdbx_check_add(rdbx_t *rdbx, uint32_t idx) { + int delta; + xtd_seq_num_t est; + + delta = index_guess(&rdbx->index, &est, idx); + + if (rdbx_check(rdbx, delta) != err_status_ok) { + printf("replay_check failed at index %u\n", idx); + return err_status_algo_fail; + } + + /* + * in practice, we'd authenticate the packet containing idx, using + * the estimated value est, at this point + */ + + if (rdbx_add_index(rdbx, delta) != err_status_ok) { + printf("rdbx_add_index failed at index %u\n", idx); + return err_status_algo_fail; + } + + return err_status_ok; +} + +/* + * rdbx_check_expect_failure(rdbx_t *rdbx, uint32_t idx) + * + * checks that a sequence number idx is in the replay database + * and thus will be rejected + */ + +err_status_t +rdbx_check_expect_failure(rdbx_t *rdbx, uint32_t idx) { + int delta; + xtd_seq_num_t est; + err_status_t status; + + delta = index_guess(&rdbx->index, &est, idx); + + status = rdbx_check(rdbx, delta); + if (status == err_status_ok) { + printf("delta: %d ", delta); + printf("replay_check failed at index %u (false positive)\n", idx); + return err_status_algo_fail; + } + + return err_status_ok; +} + +err_status_t +rdbx_check_add_unordered(rdbx_t *rdbx, uint32_t idx) { + int delta; + xtd_seq_num_t est; + err_status_t rstat; + + delta = index_guess(&rdbx->index, &est, idx); + + rstat = rdbx_check(rdbx, delta); + if ((rstat != err_status_ok) && (rstat != err_status_replay_old)) { + printf("replay_check_add_unordered failed at index %u\n", idx); + return err_status_algo_fail; + } + if (rstat == err_status_replay_old) { + return err_status_ok; + } + if (rdbx_add_index(rdbx, delta) != err_status_ok) { + printf("rdbx_add_index failed at index %u\n", idx); + return err_status_algo_fail; + } + + return err_status_ok; +} + +err_status_t +test_replay_dbx(int num_trials, unsigned long ws) { + rdbx_t rdbx; + uint32_t idx, ircvd; + ut_connection utc; + err_status_t status; + int num_fp_trials; + + status = rdbx_init(&rdbx, ws); + if (status) { + printf("replay_init failed with error code %d\n", status); + exit(1); + } + + /* + * test sequential insertion + */ + printf("\ttesting sequential insertion..."); + for (idx=0; idx < num_trials; idx++) { + status = rdbx_check_add(&rdbx, idx); + if (status) + return status; + } + printf("passed\n"); + + /* + * test for false positives by checking all of the index + * values which we've just added + * + * note that we limit the number of trials here, since allowing the + * rollover counter to roll over would defeat this test + */ + num_fp_trials = num_trials % 0x10000; + if (num_fp_trials == 0) { + printf("warning: no false positive tests performed\n"); + } + printf("\ttesting for false positives..."); + for (idx=0; idx < num_fp_trials; idx++) { + status = rdbx_check_expect_failure(&rdbx, idx); + if (status) + return status; + } + printf("passed\n"); + + /* re-initialize */ + rdbx_dealloc(&rdbx); + + if (rdbx_init(&rdbx, ws) != err_status_ok) { + printf("replay_init failed\n"); + return err_status_init_fail; + } + + /* + * test non-sequential insertion + * + * this test covers only fase negatives, since the values returned + * by ut_next_index(...) are distinct + */ + ut_init(&utc); + + printf("\ttesting non-sequential insertion..."); + for (idx=0; idx < num_trials; idx++) { + ircvd = ut_next_index(&utc); + status = rdbx_check_add_unordered(&rdbx, ircvd); + if (status) + return status; + status = rdbx_check_expect_failure(&rdbx, ircvd); + if (status) + return status; + } + printf("passed\n"); + + /* re-initialize */ + rdbx_dealloc(&rdbx); + + if (rdbx_init(&rdbx, ws) != err_status_ok) { + printf("replay_init failed\n"); + return err_status_init_fail; + } + + /* + * test insertion with large gaps. + * check for false positives for each insertion. + */ + printf("\ttesting insertion with large gaps..."); + for (idx=0, ircvd=0; idx < num_trials; idx++, ircvd += (1 << (rand() % 12))) { + status = rdbx_check_add(&rdbx, ircvd); + if (status) + return status; + status = rdbx_check_expect_failure(&rdbx, ircvd); + if (status) + return status; + } + printf("passed\n"); + + rdbx_dealloc(&rdbx); + + return err_status_ok; +} + + + +#include <time.h> /* for clock() */ +#include <stdlib.h> /* for random() */ + +double +rdbx_check_adds_per_second(int num_trials, unsigned long ws) { + uint32_t i; + int delta; + rdbx_t rdbx; + xtd_seq_num_t est; + clock_t timer; + int failures; /* count number of failures */ + + if (rdbx_init(&rdbx, ws) != err_status_ok) { + printf("replay_init failed\n"); + exit(1); + } + + failures = 0; + timer = clock(); + for(i=0; i < num_trials; i++) { + + delta = index_guess(&rdbx.index, &est, i); + + if (rdbx_check(&rdbx, delta) != err_status_ok) + ++failures; + else + if (rdbx_add_index(&rdbx, delta) != err_status_ok) + ++failures; + } + timer = clock() - timer; + + printf("number of failures: %d \n", failures); + + rdbx_dealloc(&rdbx); + + return (double) CLOCKS_PER_SEC * num_trials / timer; +} + diff --git a/src/libs/srtp/test/replay_driver.c b/src/libs/srtp/test/replay_driver.c new file mode 100644 index 00000000..b11a68ca --- /dev/null +++ b/src/libs/srtp/test/replay_driver.c @@ -0,0 +1,257 @@ +/* + * replay_driver.c + * + * A driver for the replay_database implementation + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> + +#include "rdb.h" +#include "ut_sim.h" + +/* + * num_trials defines the number of trials that are used in the + * validation functions below + */ + +unsigned num_trials = 1 << 16; + +err_status_t +test_rdb_db(void); + +double +rdb_check_adds_per_second(void); + +int +main (void) { + err_status_t err; + + printf("testing anti-replay database (rdb_t)...\n"); + err = test_rdb_db(); + if (err) { + printf("failed\n"); + exit(1); + } + printf("done\n"); + + printf("rdb_check/rdb_adds per second: %e\n", + rdb_check_adds_per_second()); + + return 0; +} + + +void +print_rdb(rdb_t *rdb) { + printf("rdb: {%u, %s}\n", rdb->window_start, v128_bit_string(&rdb->bitmask)); +} + +err_status_t +rdb_check_add(rdb_t *rdb, uint32_t idx) { + + if (rdb_check(rdb, idx) != err_status_ok) { + printf("rdb_check failed at index %u\n", idx); + return err_status_fail; + } + if (rdb_add_index(rdb, idx) != err_status_ok) { + printf("rdb_add_index failed at index %u\n", idx); + return err_status_fail; + } + + return err_status_ok; +} + +err_status_t +rdb_check_expect_failure(rdb_t *rdb, uint32_t idx) { + err_status_t err; + + err = rdb_check(rdb, idx); + if ((err != err_status_replay_old) && (err != err_status_replay_fail)) { + printf("rdb_check failed at index %u (false positive)\n", idx); + return err_status_fail; + } + + return err_status_ok; +} + +err_status_t +rdb_check_add_unordered(rdb_t *rdb, uint32_t idx) { + err_status_t rstat; + + /* printf("index: %u\n", idx); */ + rstat = rdb_check(rdb, idx); + if ((rstat != err_status_ok) && (rstat != err_status_replay_old)) { + printf("rdb_check_add_unordered failed at index %u\n", idx); + return rstat; + } + if (rstat == err_status_replay_old) { + return err_status_ok; + } + if (rdb_add_index(rdb, idx) != err_status_ok) { + printf("rdb_add_index failed at index %u\n", idx); + return err_status_fail; + } + + return err_status_ok; +} + +err_status_t +test_rdb_db() { + rdb_t rdb; + uint32_t idx, ircvd; + ut_connection utc; + err_status_t err; + + if (rdb_init(&rdb) != err_status_ok) { + printf("rdb_init failed\n"); + return err_status_init_fail; + } + + /* test sequential insertion */ + for (idx=0; idx < num_trials; idx++) { + err = rdb_check_add(&rdb, idx); + if (err) + return err; + } + + /* test for false positives */ + for (idx=0; idx < num_trials; idx++) { + err = rdb_check_expect_failure(&rdb, idx); + if (err) + return err; + } + + /* re-initialize */ + if (rdb_init(&rdb) != err_status_ok) { + printf("rdb_init failed\n"); + return err_status_fail; + } + + /* test non-sequential insertion */ + ut_init(&utc); + + for (idx=0; idx < num_trials; idx++) { + ircvd = ut_next_index(&utc); + err = rdb_check_add_unordered(&rdb, ircvd); + if (err) + return err; + err = rdb_check_expect_failure(&rdb, ircvd); + if (err) + return err; + } + + /* re-initialize */ + if (rdb_init(&rdb) != err_status_ok) { + printf("rdb_init failed\n"); + return err_status_fail; + } + + /* test insertion with large gaps */ + for (idx=0, ircvd=0; idx < num_trials; idx++, ircvd += (1 << (rand() % 10))) { + err = rdb_check_add(&rdb, ircvd); + if (err) + return err; + err = rdb_check_expect_failure(&rdb, ircvd); + if (err) + return err; + } + + /* re-initialize */ + if (rdb_init(&rdb) != err_status_ok) { + printf("rdb_init failed\n"); + return err_status_fail; + } + + /* test loss of first 513 packets */ + for (idx=0; idx < num_trials; idx++) { + err = rdb_check_add(&rdb, idx + 513); + if (err) + return err; + } + + /* test for false positives */ + for (idx=0; idx < num_trials + 513; idx++) { + err = rdb_check_expect_failure(&rdb, idx); + if (err) + return err; + } + + + return err_status_ok; +} + +#include <time.h> /* for clock() */ +#include <stdlib.h> /* for random() */ + +#define REPLAY_NUM_TRIALS 10000000 + +double +rdb_check_adds_per_second(void) { + uint32_t i; + rdb_t rdb; + clock_t timer; + int failures; /* count number of failures */ + + if (rdb_init(&rdb) != err_status_ok) { + printf("rdb_init failed\n"); + exit(1); + } + + timer = clock(); + for(i=0; i < REPLAY_NUM_TRIALS; i+=3) { + if (rdb_check(&rdb, i+2) != err_status_ok) + ++failures; + if (rdb_add_index(&rdb, i+2) != err_status_ok) + ++failures; + if (rdb_check(&rdb, i+1) != err_status_ok) + ++failures; + if (rdb_add_index(&rdb, i+1) != err_status_ok) + ++failures; + if (rdb_check(&rdb, i) != err_status_ok) + ++failures; + if (rdb_add_index(&rdb, i) != err_status_ok) + ++failures; + } + timer = clock() - timer; + + return (double) CLOCKS_PER_SEC * REPLAY_NUM_TRIALS / timer; +} diff --git a/src/libs/srtp/test/roc_driver.c b/src/libs/srtp/test/roc_driver.c new file mode 100644 index 00000000..396c9a79 --- /dev/null +++ b/src/libs/srtp/test/roc_driver.c @@ -0,0 +1,165 @@ +/* + * roc_driver.c + * + * test driver for rollover counter replay implementation + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include <stdio.h> + +/* + * defining ROC_TEST causes small datatypes to be used in + * xtd_seq_num_t - this allows the functions to be exhaustively tested. + */ +#if ROC_NEEDS_TO_BE_TESTED +#define ROC_TEST +#endif + +#include "rdbx.h" +#include "ut_sim.h" + +err_status_t +roc_test(int num_trials); + +int +main (void) { + err_status_t status; + + printf("rollover counter test driver\n" + "David A. McGrew\n" + "Cisco Systems, Inc.\n"); + + printf("testing index functions..."); + status = roc_test(1 << 18); + if (status) { + printf("failed\n"); + exit(status); + } + printf("passed\n"); + return 0; +} + + +#define ROC_VERBOSE 0 + +err_status_t +roc_test(int num_trials) { + xtd_seq_num_t local, est, ref; + ut_connection utc; + int i, num_bad_est = 0; + int delta; + uint32_t ircvd; + double failure_rate; + + index_init(&local); + index_init(&ref); + index_init(&est); + + printf("\n\ttesting sequential insertion..."); + for (i=0; i < 2048; i++) { + delta = index_guess(&local, &est, (uint16_t) ref); +#if ROC_VERBOSE + printf("%lld, %lld, %d\n", ref, est, i); +#endif + if (ref != est) { +#if ROC_VERBOSE + printf(" *bad estimate*\n"); +#endif + ++num_bad_est; + } + index_advance(&ref, 1); + } + failure_rate = (double) num_bad_est / num_trials; + if (failure_rate > 0.01) { + printf("error: failure rate too high (%d bad estimates in %d trials)\n", + num_bad_est, num_trials); + return err_status_algo_fail; + } + printf("done\n"); + + + printf("\ttesting non-sequential insertion..."); + index_init(&local); + index_init(&ref); + index_init(&est); + ut_init(&utc); + + for (i=0; i < num_trials; i++) { + + /* get next seq num from unreliable transport simulator */ + ircvd = ut_next_index(&utc); + + /* set ref to value of ircvd */ + ref = ircvd; + + /* estimate index based on low bits of ircvd */ + delta = index_guess(&local, &est, (uint16_t) ref); +#if ROC_VERBOSE + printf("ref: %lld, local: %lld, est: %lld, ircvd: %d, delta: %d\n", + ref, local, est, ircvd, delta); +#endif + + /* now update local xtd_seq_num_t as necessary */ + if (delta > 0) + index_advance(&local, delta); + + if (ref != est) { +#if ROC_VERBOSE + printf(" *bad estimate*\n"); +#endif + /* record failure event */ + ++num_bad_est; + + /* reset local value to correct value */ + local = ref; + } + } + failure_rate = (double) num_bad_est / num_trials; + if (failure_rate > 0.01) { + printf("error: failure rate too high (%d bad estimates in %d trials)\n", + num_bad_est, num_trials); + return err_status_algo_fail; + } + printf("done\n"); + + return err_status_ok; +} diff --git a/src/libs/srtp/test/rtp.c b/src/libs/srtp/test/rtp.c new file mode 100644 index 00000000..8f656983 --- /dev/null +++ b/src/libs/srtp/test/rtp.c @@ -0,0 +1,192 @@ +/* + * rtp.c + * + * library functions for the real-time transport protocol + * + * David A. McGrew + * Cisco Systems, Inc. + */ + + +#include "rtp_priv.h" + +#include <stdio.h> +#include <string.h> + +#include <sys/types.h> +#ifdef HAVE_SYS_SOCKET_H +# include <sys/socket.h> +#endif + +#define PRINT_DEBUG 0 /* set to 1 to print out debugging data */ +#define VERBOSE_DEBUG 0 /* set to 1 to print out more data */ + +int +rtp_sendto(rtp_sender_t sender, const void* msg, int len) { + int octets_sent; + err_status_t stat; + int pkt_len = len + RTP_HEADER_LEN; + + /* marshal data */ + strncpy(sender->message.body, msg, len); + + /* update header */ + sender->message.header.seq = ntohs(sender->message.header.seq) + 1; + sender->message.header.seq = htons(sender->message.header.seq); + sender->message.header.ts = ntohl(sender->message.header.ts) + 1; + sender->message.header.ts = htonl(sender->message.header.ts); + + /* apply srtp */ + stat = srtp_protect(sender->srtp_ctx, &sender->message.header, &pkt_len); + if (stat) { +#if PRINT_DEBUG + fprintf(stderr, "error: srtp protection failed with code %d\n", stat); +#endif + return -1; + } +#if VERBOSE_DEBUG + srtp_print_packet(&sender->message.header, pkt_len); +#endif + octets_sent = sendto(sender->socket, (void*)&sender->message, + pkt_len, 0, (struct sockaddr *)&sender->addr, + sizeof (struct sockaddr_in)); + + if (octets_sent != pkt_len) { +#if PRINT_DEBUG + fprintf(stderr, "error: couldn't send message %s", (char *)msg); + perror(""); +#endif + } + + return octets_sent; +} + +int +rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len) { + int octets_recvd; + err_status_t stat; + + octets_recvd = recvfrom(receiver->socket, (void *)&receiver->message, + *len, 0, (struct sockaddr *) NULL, 0); + + if (octets_recvd == -1) { + *len = 0; + return -1; + } + + /* verify rtp header */ + if (receiver->message.header.version != 2) { + *len = 0; + return -1; + } + +#if PRINT_DEBUG + fprintf(stderr, "%d octets received from SSRC %u\n", + octets_recvd, receiver->message.header.ssrc); +#endif +#if VERBOSE_DEBUG + srtp_print_packet(&receiver->message.header, octets_recvd); +#endif + + /* apply srtp */ + stat = srtp_unprotect(receiver->srtp_ctx, + &receiver->message.header, &octets_recvd); + if (stat) { + fprintf(stderr, + "error: srtp unprotection failed with code %d%s\n", stat, + stat == err_status_replay_fail ? " (replay check failed)" : + stat == err_status_auth_fail ? " (auth check failed)" : ""); + return -1; + } + strncpy(msg, receiver->message.body, octets_recvd); + + return octets_recvd; +} + +int +rtp_sender_init(rtp_sender_t sender, + int sock, + struct sockaddr_in addr, + unsigned int ssrc) { + + /* set header values */ + sender->message.header.ssrc = htonl(ssrc); + sender->message.header.ts = 0; + sender->message.header.seq = (uint16_t) rand(); + sender->message.header.m = 0; + sender->message.header.pt = 0x1; + sender->message.header.version = 2; + sender->message.header.p = 0; + sender->message.header.x = 0; + sender->message.header.cc = 0; + + /* set other stuff */ + sender->socket = sock; + sender->addr = addr; + + return 0; +} + +int +rtp_receiver_init(rtp_receiver_t rcvr, + int sock, + struct sockaddr_in addr, + unsigned int ssrc) { + + /* set header values */ + rcvr->message.header.ssrc = htonl(ssrc); + rcvr->message.header.ts = 0; + rcvr->message.header.seq = 0; + rcvr->message.header.m = 0; + rcvr->message.header.pt = 0x1; + rcvr->message.header.version = 2; + rcvr->message.header.p = 0; + rcvr->message.header.x = 0; + rcvr->message.header.cc = 0; + + /* set other stuff */ + rcvr->socket = sock; + rcvr->addr = addr; + + return 0; +} + +int +rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy) { + return srtp_create(&sender->srtp_ctx, policy); +} + +int +rtp_sender_deinit_srtp(rtp_sender_t sender) { + return srtp_dealloc(sender->srtp_ctx); +} + +int +rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy) { + return srtp_create(&sender->srtp_ctx, policy); +} + +int +rtp_receiver_deinit_srtp(rtp_receiver_t sender) { + return srtp_dealloc(sender->srtp_ctx); +} + +rtp_sender_t +rtp_sender_alloc(void) { + return (rtp_sender_t)malloc(sizeof(rtp_sender_ctx_t)); +} + +void +rtp_sender_dealloc(rtp_sender_t rtp_ctx) { + free(rtp_ctx); +} + +rtp_receiver_t +rtp_receiver_alloc(void) { + return (rtp_receiver_t)malloc(sizeof(rtp_receiver_ctx_t)); +} + +void +rtp_receiver_dealloc(rtp_receiver_t rtp_ctx) { + return free(rtp_ctx); +} diff --git a/src/libs/srtp/test/rtpw.c b/src/libs/srtp/test/rtpw.c new file mode 100644 index 00000000..f18d4204 --- /dev/null +++ b/src/libs/srtp/test/rtpw.c @@ -0,0 +1,605 @@ +/* + * rtpw.c + * + * rtp word sender/receiver + * + * David A. McGrew + * Cisco Systems, Inc. + * + * This app is a simple RTP application intended only for testing + * libsrtp. It reads one word at a time from /usr/dict/words (or + * whatever file is specified as DICT_FILE), and sends one word out + * each USEC_RATE microseconds. Secure RTP protections can be + * applied. See the usage() function for more details. + * + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "datatypes.h" +#include "getopt_s.h" /* for local getopt() */ + +#include <stdio.h> /* for printf, fprintf */ +#include <stdlib.h> /* for atoi() */ +#include <errno.h> +#include <signal.h> /* for signal() */ + +#include <string.h> /* for strncpy() */ +#include <time.h> /* for usleep() */ + +#ifdef HAVE_UNISTD_H +#include <unistd.h> /* for close() */ +#endif +#ifdef HAVE_SYS_SOCKET_H +# include <sys/socket.h> +#endif +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#elif defined HAVE_WINSOCK2_H +# include <winsock2.h> +# include <ws2tcpip.h> +# define RTPW_USE_WINSOCK2 1 +#endif +#ifdef HAVE_ARPA_INET_H +# include <arpa/inet.h> +#endif + +#include "srtp.h" +#include "rtp.h" + +#ifdef RTPW_USE_WINSOCK2 +# define DICT_FILE "words.txt" +#else +# define DICT_FILE "/usr/share/dict/words" +#endif +#define USEC_RATE (5e5) +#define MAX_WORD_LEN 128 +#define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a)) +#define MAX_KEY_LEN 64 +#define MASTER_KEY_LEN 30 + + +#ifndef HAVE_USLEEP +# ifdef HAVE_WINDOWS_H +# define usleep(us) Sleep((us)/1000) +# else +# define usleep(us) sleep((us)/1000000) +# endif +#endif + + +/* + * the function usage() prints an error message describing how this + * program should be called, then calls exit() + */ + +void +usage(char *prog_name); + +/* + * leave_group(...) de-registers from a multicast group + */ + +void +leave_group(int sock, struct ip_mreq mreq, char *name); + + +/* + * setup_signal_handler() sets up a signal handler to trigger + * cleanups after an interrupt + */ +int setup_signal_handler(char* name); + +/* + * handle_signal(...) handles interrupt signal to trigger cleanups + */ + +volatile int interrupted = 0; + +/* + * program_type distinguishes the [s]rtp sender and receiver cases + */ + +typedef enum { sender, receiver, unknown } program_type; + +int +main (int argc, char *argv[]) { + char *dictfile = DICT_FILE; + FILE *dict; + char word[MAX_WORD_LEN]; + int sock, ret; + struct in_addr rcvr_addr; + struct sockaddr_in name; + struct ip_mreq mreq; +#if BEW + struct sockaddr_in local; +#endif + program_type prog_type = unknown; + sec_serv_t sec_servs = sec_serv_none; + unsigned char ttl = 5; + int c; + char *input_key = NULL; + char *address = NULL; + char key[MAX_KEY_LEN]; + unsigned short port = 0; + rtp_sender_t snd; + srtp_policy_t policy; + err_status_t status; + int len; + int do_list_mods = 0; + uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */ +#ifdef RTPW_USE_WINSOCK2 + WORD wVersionRequested = MAKEWORD(2, 0); + WSADATA wsaData; + + ret = WSAStartup(wVersionRequested, &wsaData); + if (ret != 0) { + fprintf(stderr, "error: WSAStartup() failed: %d\n", ret); + exit(1); + } +#endif + + if (setup_signal_handler(argv[0]) != 0) { + exit(1); + } + + /* initialize srtp library */ + status = srtp_init(); + if (status) { + printf("error: srtp initialization failed with error code %d\n", status); + exit(1); + } + + /* check args */ + while (1) { + c = getopt_s(argc, argv, "k:rsaeld:"); + if (c == -1) { + break; + } + switch (c) { + case 'k': + input_key = optarg_s; + break; + case 'e': + sec_servs |= sec_serv_conf; + break; + case 'a': + sec_servs |= sec_serv_auth; + break; + case 'r': + prog_type = receiver; + break; + case 's': + prog_type = sender; + break; + case 'd': + status = crypto_kernel_set_debug_module(optarg_s, 1); + if (status) { + printf("error: set debug module (%s) failed\n", optarg_s); + exit(1); + } + break; + case 'l': + do_list_mods = 1; + break; + default: + usage(argv[0]); + } + } + + if (prog_type == unknown) { + if (do_list_mods) { + status = crypto_kernel_list_debug_modules(); + if (status) { + printf("error: list of debug modules failed\n"); + exit(1); + } + return 0; + } else { + printf("error: neither sender [-s] nor receiver [-r] specified\n"); + usage(argv[0]); + } + } + + if ((sec_servs && !input_key) || (!sec_servs && input_key)) { + /* + * a key must be provided if and only if security services have + * been requested + */ + usage(argv[0]); + } + + if (argc != optind_s + 2) { + /* wrong number of arguments */ + usage(argv[0]); + } + + /* get address from arg */ + address = argv[optind_s++]; + + /* get port from arg */ + port = atoi(argv[optind_s++]); + + /* set address */ +#ifdef HAVE_INET_ATON + if (0 == inet_aton(address, &rcvr_addr)) { + fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0], address); + exit(1); + } + if (rcvr_addr.s_addr == INADDR_NONE) { + fprintf(stderr, "%s: address error", argv[0]); + exit(1); + } +#else + rcvr_addr.s_addr = inet_addr(address); + if (0xffffffff == rcvr_addr.s_addr) { + fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0], address); + exit(1); + } +#endif + + /* open socket */ + sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) { + int err; +#ifdef RTPW_USE_WINSOCK2 + err = WSAGetLastError(); +#else + err = errno; +#endif + fprintf(stderr, "%s: couldn't open socket: %d\n", argv[0], err); + exit(1); + } + + name.sin_addr = rcvr_addr; + name.sin_family = PF_INET; + name.sin_port = htons(port); + + if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) { + if (prog_type == sender) { + ret = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, + sizeof(ttl)); + if (ret < 0) { + fprintf(stderr, "%s: Failed to set TTL for multicast group", argv[0]); + perror(""); + exit(1); + } + } + + mreq.imr_multiaddr.s_addr = rcvr_addr.s_addr; + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&mreq, + sizeof(mreq)); + if (ret < 0) { + fprintf(stderr, "%s: Failed to join multicast group", argv[0]); + perror(""); + exit(1); + } + } + + /* report security services selected on the command line */ + printf("security services: "); + if (sec_servs & sec_serv_conf) + printf("confidentiality "); + if (sec_servs & sec_serv_auth) + printf("message authentication"); + if (sec_servs == sec_serv_none) + printf("none"); + printf("\n"); + + /* set up the srtp policy and master key */ + if (sec_servs) { + /* + * create policy structure, using the default mechanisms but + * with only the security services requested on the command line, + * using the right SSRC value + */ + switch (sec_servs) { + case sec_serv_conf_and_auth: + crypto_policy_set_rtp_default(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + break; + case sec_serv_conf: + crypto_policy_set_aes_cm_128_null_auth(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + break; + case sec_serv_auth: + crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + break; + default: + printf("error: unknown security service requested\n"); + return -1; + } + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = ssrc; + policy.key = (uint8_t *) key; + policy.ekt = NULL; + policy.next = NULL; + policy.window_size = 128; + policy.allow_repeat_tx = 0; + policy.rtp.sec_serv = sec_servs; + policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */ + + /* + * read key from hexadecimal on command line into an octet string + */ + len = hex_string_to_octet_string(key, input_key, MASTER_KEY_LEN*2); + + /* check that hex string is the right length */ + if (len < MASTER_KEY_LEN*2) { + fprintf(stderr, + "error: too few digits in key/salt " + "(should be %d hexadecimal digits, found %d)\n", + MASTER_KEY_LEN*2, len); + exit(1); + } + if (strlen(input_key) > MASTER_KEY_LEN*2) { + fprintf(stderr, + "error: too many digits in key/salt " + "(should be %d hexadecimal digits, found %u)\n", + MASTER_KEY_LEN*2, (unsigned)strlen(input_key)); + exit(1); + } + + printf("set master key/salt to %s/", octet_string_hex_string(key, 16)); + printf("%s\n", octet_string_hex_string(key+16, 14)); + + } else { + /* + * we're not providing security services, so set the policy to the + * null policy + * + * Note that this policy does not conform to the SRTP + * specification, since RTCP authentication is required. However, + * the effect of this policy is to turn off SRTP, so that this + * application is now a vanilla-flavored RTP application. + */ + policy.key = (uint8_t *)key; + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = ssrc; + policy.rtp.cipher_type = NULL_CIPHER; + policy.rtp.cipher_key_len = 0; + policy.rtp.auth_type = NULL_AUTH; + policy.rtp.auth_key_len = 0; + policy.rtp.auth_tag_len = 0; + policy.rtp.sec_serv = sec_serv_none; + policy.rtcp.cipher_type = NULL_CIPHER; + policy.rtcp.cipher_key_len = 0; + policy.rtcp.auth_type = NULL_AUTH; + policy.rtcp.auth_key_len = 0; + policy.rtcp.auth_tag_len = 0; + policy.rtcp.sec_serv = sec_serv_none; + policy.window_size = 0; + policy.allow_repeat_tx = 0; + policy.ekt = NULL; + policy.next = NULL; + } + + if (prog_type == sender) { + +#if BEW + /* bind to local socket (to match crypto policy, if need be) */ + memset(&local, 0, sizeof(struct sockaddr_in)); + local.sin_addr.s_addr = htonl(INADDR_ANY); + local.sin_port = htons(port); + ret = bind(sock, (struct sockaddr *) &local, sizeof(struct sockaddr_in)); + if (ret < 0) { + fprintf(stderr, "%s: bind failed\n", argv[0]); + perror(""); + exit(1); + } +#endif /* BEW */ + + /* initialize sender's rtp and srtp contexts */ + snd = rtp_sender_alloc(); + if (snd == NULL) { + fprintf(stderr, "error: malloc() failed\n"); + exit(1); + } + rtp_sender_init(snd, sock, name, ssrc); + status = rtp_sender_init_srtp(snd, &policy); + if (status) { + fprintf(stderr, + "error: srtp_create() failed with code %d\n", + status); + exit(1); + } + + /* open dictionary */ + dict = fopen (dictfile, "r"); + if (dict == NULL) { + fprintf(stderr, "%s: couldn't open file %s\n", argv[0], dictfile); + if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) { + leave_group(sock, mreq, argv[0]); + } + exit(1); + } + + /* read words from dictionary, then send them off */ + while (!interrupted && fgets(word, MAX_WORD_LEN, dict) != NULL) { + len = strlen(word) + 1; /* plus one for null */ + + if (len > MAX_WORD_LEN) + printf("error: word %s too large to send\n", word); + else { + rtp_sendto(snd, word, len); + printf("sending word: %s", word); + } + usleep(USEC_RATE); + } + + rtp_sender_deinit_srtp(snd); + rtp_sender_dealloc(snd); + + fclose(dict); + } else { /* prog_type == receiver */ + rtp_receiver_t rcvr; + + if (bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0) { + close(sock); + fprintf(stderr, "%s: socket bind error\n", argv[0]); + perror(NULL); + if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) { + leave_group(sock, mreq, argv[0]); + } + exit(1); + } + + rcvr = rtp_receiver_alloc(); + if (rcvr == NULL) { + fprintf(stderr, "error: malloc() failed\n"); + exit(1); + } + rtp_receiver_init(rcvr, sock, name, ssrc); + status = rtp_receiver_init_srtp(rcvr, &policy); + if (status) { + fprintf(stderr, + "error: srtp_create() failed with code %d\n", + status); + exit(1); + } + + /* get next word and loop */ + while (!interrupted) { + len = MAX_WORD_LEN; + if (rtp_recvfrom(rcvr, word, &len) > -1) + printf("\tword: %s\n", word); + } + + rtp_receiver_deinit_srtp(rcvr); + rtp_receiver_dealloc(rcvr); + } + + if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) { + leave_group(sock, mreq, argv[0]); + } + +#ifdef RTPW_USE_WINSOCK2 + ret = closesocket(sock); +#else + ret = close(sock); +#endif + if (ret < 0) { + fprintf(stderr, "%s: Failed to close socket", argv[0]); + perror(""); + } + + status = srtp_shutdown(); + if (status) { + printf("error: srtp shutdown failed with error code %d\n", status); + exit(1); + } + +#ifdef RTPW_USE_WINSOCK2 + WSACleanup(); +#endif + + return 0; +} + + +void +usage(char *string) { + + printf("usage: %s [-d <debug>]* [-k <key> [-a][-e]] " + "[-s | -r] dest_ip dest_port\n" + "or %s -l\n" + "where -a use message authentication\n" + " -e use encryption\n" + " -k <key> sets the srtp master key\n" + " -s act as rtp sender\n" + " -r act as rtp receiver\n" + " -l list debug modules\n" + " -d <debug> turn on debugging for module <debug>\n", + string, string); + exit(1); + +} + + +void +leave_group(int sock, struct ip_mreq mreq, char *name) { + int ret; + + ret = setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void*)&mreq, + sizeof(mreq)); + if (ret < 0) { + fprintf(stderr, "%s: Failed to leave multicast group", name); + perror(""); + } +} + +void handle_signal(int signum) +{ + interrupted = 1; + /* Reset handler explicitly, in case we don't have sigaction() (and signal() + has BSD semantics), or we don't have SA_RESETHAND */ + signal(signum, SIG_DFL); +} + +int setup_signal_handler(char* name) +{ +#if HAVE_SIGACTION + struct sigaction act; + memset(&act, 0, sizeof(act)); + + act.sa_handler = handle_signal; + sigemptyset(&act.sa_mask); +#if defined(SA_RESETHAND) + act.sa_flags = SA_RESETHAND; +#else + act.sa_flags = 0; +#endif + /* Note that we're not setting SA_RESTART; we want recvfrom to return + * EINTR when we signal the receiver. */ + + if (sigaction(SIGTERM, &act, NULL) != 0) { + fprintf(stderr, "%s: error setting up signal handler", name); + perror(""); + return -1; + } +#else + if (signal(SIGTERM, handle_signal) == SIG_ERR) { + fprintf(stderr, "%s: error setting up signal handler", name); + perror(""); + return -1; + } +#endif + return 0; +} diff --git a/src/libs/srtp/test/rtpw_test.sh b/src/libs/srtp/test/rtpw_test.sh new file mode 100644 index 00000000..b5d66ee0 --- /dev/null +++ b/src/libs/srtp/test/rtpw_test.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# +# usage: rtpw_test <rtpw_commands> +# +# tests the rtpw sender and receiver functions + +RTPW=./rtpw +DEST_PORT=9999 +DURATION=3 + +key=2b2edc5034f61a72345ca5986d7bfd0189aa6dc2ecab32fd9af74df6dfc6 + +ARGS="-k $key -ae" + +# First, we run "killall" to get rid of all existing rtpw processes. +# This step also enables this script to clean up after itself; if this +# script is interrupted after the rtpw processes are started but before +# they are killed, those processes will linger. Re-running the script +# will get rid of them. + +killall rtpw 2>/dev/null + +if test -x $RTPW; then + +echo $0 ": starting rtpw receiver process... " + +$RTPW $* $ARGS -r 0.0.0.0 $DEST_PORT & + +receiver_pid=$! + +echo $0 ": receiver PID = $receiver_pid" + +sleep 1 + +# verify that the background job is running +ps | grep -q $receiver_pid +retval=$? +echo $retval +if [ $retval != 0 ]; then + echo $0 ": error" + exit 254 +fi + +echo $0 ": starting rtpw sender process..." + +$RTPW $* $ARGS -s 127.0.0.1 $DEST_PORT & + +sender_pid=$! + +echo $0 ": sender PID = $sender_pid" + +# verify that the background job is running +ps | grep -q $sender_pid +retval=$? +echo $retval +if [ $retval != 0 ]; then + echo $0 ": error" + exit 255 +fi + +sleep $DURATION + +kill $receiver_pid +kill $sender_pid + +wait $receiver_pid +wait $sender_pid + +echo $0 ": done (test passed)" + +else + +echo "error: can't find executable" $RTPW +exit 1 + +fi + +# EOF + + diff --git a/src/libs/srtp/test/srtp_driver.c b/src/libs/srtp/test/srtp_driver.c new file mode 100644 index 00000000..a1b48661 --- /dev/null +++ b/src/libs/srtp/test/srtp_driver.c @@ -0,0 +1,1815 @@ +/* + * srtp_driver.c + * + * a test driver for libSRTP + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include <string.h> /* for memcpy() */ +#include <time.h> /* for clock() */ +#include <stdlib.h> /* for malloc(), free() */ +#include <stdio.h> /* for print(), fflush() */ +#include "getopt_s.h" /* for local getopt() */ + +#include "srtp_priv.h" + +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#elif defined HAVE_WINSOCK2_H +# include <winsock2.h> +#endif + +#define PRINT_REFERENCE_PACKET 1 + +err_status_t +srtp_validate(void); + +err_status_t +srtp_validate_aes_256(void); + +err_status_t +srtp_create_big_policy(srtp_policy_t **list); + +err_status_t +srtp_dealloc_big_policy(srtp_policy_t *list); + +err_status_t +srtp_test_remove_stream(void); + +double +srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy); + +double +srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy); + +void +srtp_do_timing(const srtp_policy_t *policy); + +void +srtp_do_rejection_timing(const srtp_policy_t *policy); + +err_status_t +srtp_test(const srtp_policy_t *policy); + +err_status_t +srtcp_test(const srtp_policy_t *policy); + +err_status_t +srtp_session_print_policy(srtp_t srtp); + +err_status_t +srtp_print_policy(const srtp_policy_t *policy); + +char * +srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len); + +double +mips_estimate(int num_trials, int *ignore); + +extern uint8_t test_key[30]; + +void +usage(char *prog_name) { + printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n" + " -t run timing test\n" + " -r run rejection timing test\n" + " -c run codec timing test\n" + " -v run validation tests\n" + " -d <mod> turn on debugging module <mod>\n" + " -l list debugging modules\n", prog_name); + exit(1); +} + +/* + * The policy_array is a null-terminated array of policy structs. it + * is declared at the end of this file + */ + +extern const srtp_policy_t *policy_array[]; + + +/* the wildcard_policy is declared below; it has a wildcard ssrc */ + +extern const srtp_policy_t wildcard_policy; + +/* + * mod_driver debug module - debugging module for this test driver + * + * we use the crypto_kernel debugging system in this driver, which + * makes the interface uniform and increases portability + */ + +debug_module_t mod_driver = { + 0, /* debugging is off by default */ + "driver" /* printable name for module */ +}; + +int +main (int argc, char *argv[]) { + int q; + unsigned do_timing_test = 0; + unsigned do_rejection_test = 0; + unsigned do_codec_timing = 0; + unsigned do_validation = 0; + unsigned do_list_mods = 0; + err_status_t status; + + /* + * verify that the compiler has interpreted the header data + * structure srtp_hdr_t correctly + */ + if (sizeof(srtp_hdr_t) != 12) { + printf("error: srtp_hdr_t has incorrect size" + "(size is %ld bytes, expected 12)\n", + (long)sizeof(srtp_hdr_t)); + exit(1); + } + + /* initialize srtp library */ + status = srtp_init(); + if (status) { + printf("error: srtp init failed with error code %d\n", status); + exit(1); + } + + /* load srtp_driver debug module */ + status = crypto_kernel_load_debug_module(&mod_driver); + if (status) { + printf("error: load of srtp_driver debug module failed " + "with error code %d\n", status); + exit(1); + } + + /* process input arguments */ + while (1) { + q = getopt_s(argc, argv, "trcvld:"); + if (q == -1) + break; + switch (q) { + case 't': + do_timing_test = 1; + break; + case 'r': + do_rejection_test = 1; + break; + case 'c': + do_codec_timing = 1; + break; + case 'v': + do_validation = 1; + break; + case 'l': + do_list_mods = 1; + break; + case 'd': + status = crypto_kernel_set_debug_module(optarg_s, 1); + if (status) { + printf("error: set debug module (%s) failed\n", optarg_s); + exit(1); + } + break; + default: + usage(argv[0]); + } + } + + if (!do_validation && !do_timing_test && !do_codec_timing + && !do_list_mods && !do_rejection_test) + usage(argv[0]); + + if (do_list_mods) { + status = crypto_kernel_list_debug_modules(); + if (status) { + printf("error: list of debug modules failed\n"); + exit(1); + } + } + + if (do_validation) { + const srtp_policy_t **policy = policy_array; + srtp_policy_t *big_policy; + + /* loop over policy array, testing srtp and srtcp for each policy */ + while (*policy != NULL) { + printf("testing srtp_protect and srtp_unprotect\n"); + if (srtp_test(*policy) == err_status_ok) + printf("passed\n\n"); + else { + printf("failed\n"); + exit(1); + } + printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n"); + if (srtcp_test(*policy) == err_status_ok) + printf("passed\n\n"); + else { + printf("failed\n"); + exit(1); + } + policy++; + } + + /* create a big policy list and run tests on it */ + status = srtp_create_big_policy(&big_policy); + if (status) { + printf("unexpected failure with error code %d\n", status); + exit(1); + } + printf("testing srtp_protect and srtp_unprotect with big policy\n"); + if (srtp_test(big_policy) == err_status_ok) + printf("passed\n\n"); + else { + printf("failed\n"); + exit(1); + } + status = srtp_dealloc_big_policy(big_policy); + if (status) { + printf("unexpected failure with error code %d\n", status); + exit(1); + } + + /* run test on wildcard policy */ + printf("testing srtp_protect and srtp_unprotect on " + "wildcard ssrc policy\n"); + if (srtp_test(&wildcard_policy) == err_status_ok) + printf("passed\n\n"); + else { + printf("failed\n"); + exit(1); + } + + /* + * run validation test against the reference packets - note + * that this test only covers the default policy + */ + printf("testing srtp_protect and srtp_unprotect against " + "reference packets\n"); + if (srtp_validate() == err_status_ok) + printf("passed\n\n"); + else { + printf("failed\n"); + exit(1); + } + + /* + * run validation test against the reference packets for + * AES-256 + */ + printf("testing srtp_protect and srtp_unprotect against " + "reference packets (AES-256)\n"); + if (srtp_validate_aes_256() == err_status_ok) + printf("passed\n\n"); + else { + printf("failed\n"); + exit(1); + } + + /* + * test the function srtp_remove_stream() + */ + printf("testing srtp_remove_stream()..."); + if (srtp_test_remove_stream() == err_status_ok) + printf("passed\n"); + else { + printf("failed\n"); + exit(1); + } + } + + if (do_timing_test) { + const srtp_policy_t **policy = policy_array; + + /* loop over policies, run timing test for each */ + while (*policy != NULL) { + srtp_print_policy(*policy); + srtp_do_timing(*policy); + policy++; + } + } + + if (do_rejection_test) { + const srtp_policy_t **policy = policy_array; + + /* loop over policies, run rejection timing test for each */ + while (*policy != NULL) { + srtp_print_policy(*policy); + srtp_do_rejection_timing(*policy); + policy++; + } + } + + if (do_codec_timing) { + srtp_policy_t policy; + int ignore; + double mips = mips_estimate(1000000000, &ignore); + + crypto_policy_set_rtp_default(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = 0xdecafbad; + policy.key = test_key; + policy.ekt = NULL; + policy.window_size = 128; + policy.allow_repeat_tx = 0; + policy.next = NULL; + + printf("mips estimate: %e\n", mips); + + printf("testing srtp processing time for voice codecs:\n"); + printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n"); + printf("G.711\t\t%d\t\t\t%e\n", 80, + (double) mips * (80 * 8) / + srtp_bits_per_second(80, &policy) / .01 ); + printf("G.711\t\t%d\t\t\t%e\n", 160, + (double) mips * (160 * 8) / + srtp_bits_per_second(160, &policy) / .02); + printf("G.726-32\t%d\t\t\t%e\n", 40, + (double) mips * (40 * 8) / + srtp_bits_per_second(40, &policy) / .01 ); + printf("G.726-32\t%d\t\t\t%e\n", 80, + (double) mips * (80 * 8) / + srtp_bits_per_second(80, &policy) / .02); + printf("G.729\t\t%d\t\t\t%e\n", 10, + (double) mips * (10 * 8) / + srtp_bits_per_second(10, &policy) / .01 ); + printf("G.729\t\t%d\t\t\t%e\n", 20, + (double) mips * (20 * 8) / + srtp_bits_per_second(20, &policy) / .02 ); + printf("Wideband\t%d\t\t\t%e\n", 320, + (double) mips * (320 * 8) / + srtp_bits_per_second(320, &policy) / .01 ); + printf("Wideband\t%d\t\t\t%e\n", 640, + (double) mips * (640 * 8) / + srtp_bits_per_second(640, &policy) / .02 ); + } + + status = srtp_shutdown(); + if (status) { + printf("error: srtp shutdown failed with error code %d\n", status); + exit(1); + } + + return 0; +} + + + +/* + * srtp_create_test_packet(len, ssrc) returns a pointer to a + * (malloced) example RTP packet whose data field has the length given + * by pkt_octet_len and the SSRC value ssrc. The total length of the + * packet is twelve octets longer, since the header is at the + * beginning. There is room at the end of the packet for a trailer, + * and the four octets following the packet are filled with 0xff + * values to enable testing for overwrites. + * + * note that the location of the test packet can (and should) be + * deallocated with the free() call once it is no longer needed. + */ + +srtp_hdr_t * +srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) { + int i; + uint8_t *buffer; + srtp_hdr_t *hdr; + int bytes_in_hdr = 12; + + /* allocate memory for test packet */ + hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr + + SRTP_MAX_TRAILER_LEN + 4); + if (!hdr) + return NULL; + + hdr->version = 2; /* RTP version two */ + hdr->p = 0; /* no padding needed */ + hdr->x = 0; /* no header extension */ + hdr->cc = 0; /* no CSRCs */ + hdr->m = 0; /* marker bit */ + hdr->pt = 0xf; /* payload type */ + hdr->seq = htons(0x1234); /* sequence number */ + hdr->ts = htonl(0xdecafbad); /* timestamp */ + hdr->ssrc = htonl(ssrc); /* synch. source */ + + buffer = (uint8_t *)hdr; + buffer += bytes_in_hdr; + + /* set RTP data to 0xab */ + for (i=0; i < pkt_octet_len; i++) + *buffer++ = 0xab; + + /* set post-data value to 0xffff to enable overrun checking */ + for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++) + *buffer++ = 0xff; + + return hdr; +} + +void +srtp_do_timing(const srtp_policy_t *policy) { + int len; + + /* + * note: the output of this function is formatted so that it + * can be used in gnuplot. '#' indicates a comment, and "\r\n" + * terminates a record + */ + + printf("# testing srtp throughput:\r\n"); + printf("# mesg length (octets)\tthroughput (megabits per second)\r\n"); + + for (len=16; len <= 2048; len *= 2) + printf("%d\t\t\t%f\r\n", len, + srtp_bits_per_second(len, policy) / 1.0E6); + + /* these extra linefeeds let gnuplot know that a dataset is done */ + printf("\r\n\r\n"); + +} + +void +srtp_do_rejection_timing(const srtp_policy_t *policy) { + int len; + + /* + * note: the output of this function is formatted so that it + * can be used in gnuplot. '#' indicates a comment, and "\r\n" + * terminates a record + */ + + printf("# testing srtp rejection throughput:\r\n"); + printf("# mesg length (octets)\trejections per second\r\n"); + + for (len=8; len <= 2048; len *= 2) + printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy)); + + /* these extra linefeeds let gnuplot know that a dataset is done */ + printf("\r\n\r\n"); + +} + + +#define MAX_MSG_LEN 1024 + +double +srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) { + srtp_t srtp; + srtp_hdr_t *mesg; + int i; + clock_t timer; + int num_trials = 100000; + int len; + uint32_t ssrc; + err_status_t status; + + /* + * allocate and initialize an srtp session + */ + status = srtp_create(&srtp, policy); + if (status) { + printf("error: srtp_create() failed with error code %d\n", status); + exit(1); + } + + /* + * if the ssrc is unspecified, use a predetermined one + */ + if (policy->ssrc.type != ssrc_specific) { + ssrc = 0xdeadbeef; + } else { + ssrc = policy->ssrc.value; + } + + /* + * create a test packet + */ + mesg = srtp_create_test_packet(msg_len_octets, ssrc); + if (mesg == NULL) + return 0.0; /* indicate failure by returning zero */ + + timer = clock(); + for (i=0; i < num_trials; i++) { + len = msg_len_octets + 12; /* add in rtp header length */ + + /* srtp protect message */ + status = srtp_protect(srtp, mesg, &len); + if (status) { + printf("error: srtp_protect() failed with error code %d\n", status); + exit(1); + } + + /* increment message number */ + { + /* hack sequence to avoid problems with macros for htons/ntohs on some systems */ + short new_seq = ntohs(mesg->seq) + 1; + mesg->seq = htons(new_seq); + } + } + timer = clock() - timer; + + free(mesg); + + status = srtp_dealloc(srtp); + if (status) { + printf("error: srtp_dealloc() failed with error code %d\n", status); + exit(1); + } + + return (double) (msg_len_octets) * 8 * + num_trials * CLOCKS_PER_SEC / timer; +} + +double +srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) { + srtp_ctx_t *srtp; + srtp_hdr_t *mesg; + int i; + int len; + clock_t timer; + int num_trials = 1000000; + uint32_t ssrc = policy->ssrc.value; + err_status_t status; + + /* + * allocate and initialize an srtp session + */ + status = srtp_create(&srtp, policy); + if (status) { + printf("error: srtp_create() failed with error code %d\n", status); + exit(1); + } + + mesg = srtp_create_test_packet(msg_len_octets, ssrc); + if (mesg == NULL) + return 0.0; /* indicate failure by returning zero */ + + len = msg_len_octets; + srtp_protect(srtp, (srtp_hdr_t *)mesg, &len); + + timer = clock(); + for (i=0; i < num_trials; i++) { + len = msg_len_octets; + srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len); + } + timer = clock() - timer; + + free(mesg); + + status = srtp_dealloc(srtp); + if (status) { + printf("error: srtp_dealloc() failed with error code %d\n", status); + exit(1); + } + + return (double) num_trials * CLOCKS_PER_SEC / timer; +} + + +void +err_check(err_status_t s) { + if (s == err_status_ok) + return; + else + fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s); + exit (1); +} + +err_status_t +srtp_test(const srtp_policy_t *policy) { + int i; + srtp_t srtp_sender; + srtp_t srtp_rcvr; + err_status_t status = err_status_ok; + srtp_hdr_t *hdr, *hdr2; + uint8_t hdr_enc[64]; + uint8_t *pkt_end; + int msg_len_octets, msg_len_enc; + int len; + int tag_length = policy->rtp.auth_tag_len; + uint32_t ssrc; + srtp_policy_t *rcvr_policy; + + err_check(srtp_create(&srtp_sender, policy)); + + /* print out policy */ + err_check(srtp_session_print_policy(srtp_sender)); + + /* + * initialize data buffer, using the ssrc in the policy unless that + * value is a wildcard, in which case we'll just use an arbitrary + * one + */ + if (policy->ssrc.type != ssrc_specific) + ssrc = 0xdecafbad; + else + ssrc = policy->ssrc.value; + msg_len_octets = 28; + hdr = srtp_create_test_packet(msg_len_octets, ssrc); + + if (hdr == NULL) + return err_status_alloc_fail; + hdr2 = srtp_create_test_packet(msg_len_octets, ssrc); + if (hdr2 == NULL) { + free(hdr); + return err_status_alloc_fail; + } + + /* set message length */ + len = msg_len_octets; + + debug_print(mod_driver, "before protection:\n%s", + srtp_packet_to_string(hdr, len)); + +#if PRINT_REFERENCE_PACKET + debug_print(mod_driver, "reference packet before protection:\n%s", + octet_string_hex_string((uint8_t *)hdr, len)); +#endif + err_check(srtp_protect(srtp_sender, hdr, &len)); + + debug_print(mod_driver, "after protection:\n%s", + srtp_packet_to_string(hdr, len)); +#if PRINT_REFERENCE_PACKET + debug_print(mod_driver, "after protection:\n%s", + octet_string_hex_string((uint8_t *)hdr, len)); +#endif + + /* save protected message and length */ + memcpy(hdr_enc, hdr, len); + msg_len_enc = len; + + /* + * check for overrun of the srtp_protect() function + * + * The packet is followed by a value of 0xfffff; if the value of the + * data following the packet is different, then we know that the + * protect function is overwriting the end of the packet. + */ + pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t) + + msg_len_octets + tag_length; + for (i = 0; i < 4; i++) + if (pkt_end[i] != 0xff) { + fprintf(stdout, "overwrite in srtp_protect() function " + "(expected %x, found %x in trailing octet %d)\n", + 0xff, ((uint8_t *)hdr)[i], i); + free(hdr); + free(hdr2); + return err_status_algo_fail; + } + + /* + * if the policy includes confidentiality, check that ciphertext is + * different than plaintext + * + * Note that this check will give false negatives, with some small + * probability, especially if the packets are short. For that + * reason, we skip this check if the plaintext is less than four + * octets long. + */ + if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) { + printf("testing that ciphertext is distinct from plaintext..."); + status = err_status_algo_fail; + for (i=12; i < msg_len_octets+12; i++) + if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { + status = err_status_ok; + } + if (status) { + printf("failed\n"); + free(hdr); + free(hdr2); + return status; + } + printf("passed\n"); + } + + /* + * if the policy uses a 'wildcard' ssrc, then we need to make a copy + * of the policy that changes the direction to inbound + * + * we always copy the policy into the rcvr_policy, since otherwise + * the compiler would fret about the constness of the policy + */ + rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t)); + if (rcvr_policy == NULL) { + free(hdr); + free(hdr2); + return err_status_alloc_fail; + } + memcpy(rcvr_policy, policy, sizeof(srtp_policy_t)); + if (policy->ssrc.type == ssrc_any_outbound) { + rcvr_policy->ssrc.type = ssrc_any_inbound; + } + + err_check(srtp_create(&srtp_rcvr, rcvr_policy)); + + err_check(srtp_unprotect(srtp_rcvr, hdr, &len)); + + debug_print(mod_driver, "after unprotection:\n%s", + srtp_packet_to_string(hdr, len)); + + /* verify that the unprotected packet matches the origial one */ + for (i=0; i < msg_len_octets; i++) + if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { + fprintf(stdout, "mismatch at octet %d\n", i); + status = err_status_algo_fail; + } + if (status) { + free(hdr); + free(hdr2); + free(rcvr_policy); + return status; + } + + /* + * if the policy includes authentication, then test for false positives + */ + if (policy->rtp.sec_serv & sec_serv_auth) { + char *data = ((char *)hdr) + 12; + + printf("testing for false positives in replay check..."); + + /* set message length */ + len = msg_len_enc; + + /* unprotect a second time - should fail with a replay error */ + status = srtp_unprotect(srtp_rcvr, hdr_enc, &len); + if (status != err_status_replay_fail) { + printf("failed with error code %d\n", status); + free(hdr); + free(hdr2); + free(rcvr_policy); + return status; + } else { + printf("passed\n"); + } + + printf("testing for false positives in auth check..."); + + /* increment sequence number in header */ + hdr->seq++; + + /* set message length */ + len = msg_len_octets; + + /* apply protection */ + err_check(srtp_protect(srtp_sender, hdr, &len)); + + /* flip bits in packet */ + data[0] ^= 0xff; + + /* unprotect, and check for authentication failure */ + status = srtp_unprotect(srtp_rcvr, hdr, &len); + if (status != err_status_auth_fail) { + printf("failed\n"); + free(hdr); + free(hdr2); + free(rcvr_policy); + return status; + } else { + printf("passed\n"); + } + + } + + err_check(srtp_dealloc(srtp_sender)); + err_check(srtp_dealloc(srtp_rcvr)); + + free(hdr); + free(hdr2); + free(rcvr_policy); + return err_status_ok; +} + + +err_status_t +srtcp_test(const srtp_policy_t *policy) { + int i; + srtp_t srtcp_sender; + srtp_t srtcp_rcvr; + err_status_t status = err_status_ok; + srtp_hdr_t *hdr, *hdr2; + uint8_t hdr_enc[64]; + uint8_t *pkt_end; + int msg_len_octets, msg_len_enc; + int len; + int tag_length = policy->rtp.auth_tag_len; + uint32_t ssrc; + srtp_policy_t *rcvr_policy; + + err_check(srtp_create(&srtcp_sender, policy)); + + /* print out policy */ + err_check(srtp_session_print_policy(srtcp_sender)); + + /* + * initialize data buffer, using the ssrc in the policy unless that + * value is a wildcard, in which case we'll just use an arbitrary + * one + */ + if (policy->ssrc.type != ssrc_specific) + ssrc = 0xdecafbad; + else + ssrc = policy->ssrc.value; + msg_len_octets = 28; + hdr = srtp_create_test_packet(msg_len_octets, ssrc); + + if (hdr == NULL) + return err_status_alloc_fail; + hdr2 = srtp_create_test_packet(msg_len_octets, ssrc); + if (hdr2 == NULL) { + free(hdr); + return err_status_alloc_fail; + } + + /* set message length */ + len = msg_len_octets; + + debug_print(mod_driver, "before protection:\n%s", + srtp_packet_to_string(hdr, len)); + +#if PRINT_REFERENCE_PACKET + debug_print(mod_driver, "reference packet before protection:\n%s", + octet_string_hex_string((uint8_t *)hdr, len)); +#endif + err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len)); + + debug_print(mod_driver, "after protection:\n%s", + srtp_packet_to_string(hdr, len)); +#if PRINT_REFERENCE_PACKET + debug_print(mod_driver, "after protection:\n%s", + octet_string_hex_string((uint8_t *)hdr, len)); +#endif + + /* save protected message and length */ + memcpy(hdr_enc, hdr, len); + msg_len_enc = len; + + /* + * check for overrun of the srtp_protect() function + * + * The packet is followed by a value of 0xfffff; if the value of the + * data following the packet is different, then we know that the + * protect function is overwriting the end of the packet. + */ + pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t) + + msg_len_octets + tag_length; + for (i = 0; i < 4; i++) + if (pkt_end[i] != 0xff) { + fprintf(stdout, "overwrite in srtp_protect_rtcp() function " + "(expected %x, found %x in trailing octet %d)\n", + 0xff, ((uint8_t *)hdr)[i], i); + free(hdr); + free(hdr2); + return err_status_algo_fail; + } + + /* + * if the policy includes confidentiality, check that ciphertext is + * different than plaintext + * + * Note that this check will give false negatives, with some small + * probability, especially if the packets are short. For that + * reason, we skip this check if the plaintext is less than four + * octets long. + */ + if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) { + printf("testing that ciphertext is distinct from plaintext..."); + status = err_status_algo_fail; + for (i=12; i < msg_len_octets+12; i++) + if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { + status = err_status_ok; + } + if (status) { + printf("failed\n"); + free(hdr); + free(hdr2); + return status; + } + printf("passed\n"); + } + + /* + * if the policy uses a 'wildcard' ssrc, then we need to make a copy + * of the policy that changes the direction to inbound + * + * we always copy the policy into the rcvr_policy, since otherwise + * the compiler would fret about the constness of the policy + */ + rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t)); + if (rcvr_policy == NULL) + return err_status_alloc_fail; + memcpy(rcvr_policy, policy, sizeof(srtp_policy_t)); + if (policy->ssrc.type == ssrc_any_outbound) { + rcvr_policy->ssrc.type = ssrc_any_inbound; + } + + err_check(srtp_create(&srtcp_rcvr, rcvr_policy)); + + err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len)); + + debug_print(mod_driver, "after unprotection:\n%s", + srtp_packet_to_string(hdr, len)); + + /* verify that the unprotected packet matches the origial one */ + for (i=0; i < msg_len_octets; i++) + if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { + fprintf(stdout, "mismatch at octet %d\n", i); + status = err_status_algo_fail; + } + if (status) { + free(hdr); + free(hdr2); + free(rcvr_policy); + return status; + } + + /* + * if the policy includes authentication, then test for false positives + */ + if (policy->rtp.sec_serv & sec_serv_auth) { + char *data = ((char *)hdr) + 12; + + printf("testing for false positives in replay check..."); + + /* set message length */ + len = msg_len_enc; + + /* unprotect a second time - should fail with a replay error */ + status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len); + if (status != err_status_replay_fail) { + printf("failed with error code %d\n", status); + free(hdr); + free(hdr2); + free(rcvr_policy); + return status; + } else { + printf("passed\n"); + } + + printf("testing for false positives in auth check..."); + + /* increment sequence number in header */ + hdr->seq++; + + /* set message length */ + len = msg_len_octets; + + /* apply protection */ + err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len)); + + /* flip bits in packet */ + data[0] ^= 0xff; + + /* unprotect, and check for authentication failure */ + status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len); + if (status != err_status_auth_fail) { + printf("failed\n"); + free(hdr); + free(hdr2); + free(rcvr_policy); + return status; + } else { + printf("passed\n"); + } + + } + + err_check(srtp_dealloc(srtcp_sender)); + err_check(srtp_dealloc(srtcp_rcvr)); + + free(hdr); + free(hdr2); + free(rcvr_policy); + return err_status_ok; +} + + +err_status_t +srtp_session_print_policy(srtp_t srtp) { + char *serv_descr[4] = { + "none", + "confidentiality", + "authentication", + "confidentiality and authentication" + }; + char *direction[3] = { + "unknown", + "outbound", + "inbound" + }; + srtp_stream_t stream; + + /* sanity checking */ + if (srtp == NULL) + return err_status_fail; + + /* if there's a template stream, print it out */ + if (srtp->stream_template != NULL) { + stream = srtp->stream_template; + printf("# SSRC: any %s\r\n" + "# rtp cipher: %s\r\n" + "# rtp auth: %s\r\n" + "# rtp services: %s\r\n" + "# rtcp cipher: %s\r\n" + "# rtcp auth: %s\r\n" + "# rtcp services: %s\r\n" + "# window size: %lu\r\n" + "# tx rtx allowed:%s\r\n", + direction[stream->direction], + stream->rtp_cipher->type->description, + stream->rtp_auth->type->description, + serv_descr[stream->rtp_services], + stream->rtcp_cipher->type->description, + stream->rtcp_auth->type->description, + serv_descr[stream->rtcp_services], + rdbx_get_window_size(&stream->rtp_rdbx), + stream->allow_repeat_tx ? "true" : "false"); + } + + /* loop over streams in session, printing the policy of each */ + stream = srtp->stream_list; + while (stream != NULL) { + if (stream->rtp_services > sec_serv_conf_and_auth) + return err_status_bad_param; + + printf("# SSRC: 0x%08x\r\n" + "# rtp cipher: %s\r\n" + "# rtp auth: %s\r\n" + "# rtp services: %s\r\n" + "# rtcp cipher: %s\r\n" + "# rtcp auth: %s\r\n" + "# rtcp services: %s\r\n" + "# window size: %lu\r\n" + "# tx rtx allowed:%s\r\n", + stream->ssrc, + stream->rtp_cipher->type->description, + stream->rtp_auth->type->description, + serv_descr[stream->rtp_services], + stream->rtcp_cipher->type->description, + stream->rtcp_auth->type->description, + serv_descr[stream->rtcp_services], + rdbx_get_window_size(&stream->rtp_rdbx), + stream->allow_repeat_tx ? "true" : "false"); + + /* advance to next stream in the list */ + stream = stream->next; + } + return err_status_ok; +} + +err_status_t +srtp_print_policy(const srtp_policy_t *policy) { + err_status_t status; + srtp_t session; + + status = srtp_create(&session, policy); + if (status) + return status; + status = srtp_session_print_policy(session); + if (status) + return status; + status = srtp_dealloc(session); + if (status) + return status; + return err_status_ok; +} + +/* + * srtp_print_packet(...) is for debugging only + * it prints an RTP packet to the stdout + * + * note that this function is *not* threadsafe + */ + +#include <stdio.h> + +#define MTU 2048 + +char packet_string[MTU]; + +char * +srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) { + int octets_in_rtp_header = 12; + uint8_t *data = ((uint8_t *)hdr)+octets_in_rtp_header; + int hex_len = pkt_octet_len-octets_in_rtp_header; + + /* sanity checking */ + if ((hdr == NULL) || (pkt_octet_len > MTU)) + return NULL; + + /* write packet into string */ + sprintf(packet_string, + "(s)rtp packet: {\n" + " version:\t%d\n" + " p:\t\t%d\n" + " x:\t\t%d\n" + " cc:\t\t%d\n" + " m:\t\t%d\n" + " pt:\t\t%x\n" + " seq:\t\t%x\n" + " ts:\t\t%x\n" + " ssrc:\t%x\n" + " data:\t%s\n" + "} (%d octets in total)\n", + hdr->version, + hdr->p, + hdr->x, + hdr->cc, + hdr->m, + hdr->pt, + hdr->seq, + hdr->ts, + hdr->ssrc, + octet_string_hex_string(data, hex_len), + pkt_octet_len); + + return packet_string; +} + +/* + * mips_estimate() is a simple function to estimate the number of + * instructions per second that the host can perform. note that this + * function can be grossly wrong; you may want to have a manual sanity + * check of its output! + * + * the 'ignore' pointer is there to convince the compiler to not just + * optimize away the function + */ + +double +mips_estimate(int num_trials, int *ignore) { + clock_t t; + volatile int i, sum; + + sum = 0; + t = clock(); + for (i=0; i<num_trials; i++) + sum += i; + t = clock() - t; + +/* printf("%d\n", sum); */ + *ignore = sum; + + return (double) num_trials * CLOCKS_PER_SEC / t; +} + + +/* + * srtp_validate() verifies the correctness of libsrtp by comparing + * some computed packets against some pre-computed reference values. + * These packets were made with the default SRTP policy. + */ + + +err_status_t +srtp_validate() { + uint8_t srtp_plaintext_ref[28] = { + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab + }; + uint8_t srtp_plaintext[38] = { + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + uint8_t srtp_ciphertext[38] = { + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c, + 0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15, + 0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc, + 0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb + }; + srtp_t srtp_snd, srtp_recv; + err_status_t status; + int len; + srtp_policy_t policy; + + /* + * create a session with a single stream using the default srtp + * policy and with the SSRC value 0xcafebabe + */ + crypto_policy_set_rtp_default(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = 0xcafebabe; + policy.key = test_key; + policy.ekt = NULL; + policy.window_size = 128; + policy.allow_repeat_tx = 0; + policy.next = NULL; + + status = srtp_create(&srtp_snd, &policy); + if (status) + return status; + + /* + * protect plaintext, then compare with ciphertext + */ + len = 28; + status = srtp_protect(srtp_snd, srtp_plaintext, &len); + if (status || (len != 38)) + return err_status_fail; + + debug_print(mod_driver, "ciphertext:\n %s", + octet_string_hex_string(srtp_plaintext, len)); + debug_print(mod_driver, "ciphertext reference:\n %s", + octet_string_hex_string(srtp_ciphertext, len)); + + if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) + return err_status_fail; + + /* + * create a receiver session context comparable to the one created + * above - we need to do this so that the replay checking doesn't + * complain + */ + status = srtp_create(&srtp_recv, &policy); + if (status) + return status; + + /* + * unprotect ciphertext, then compare with plaintext + */ + status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len); + if (status || (len != 28)) + return status; + + if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) + return err_status_fail; + + status = srtp_dealloc(srtp_snd); + if (status) + return status; + + status = srtp_dealloc(srtp_recv); + if (status) + return status; + + return err_status_ok; +} + + +/* + * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing + * some computed packets against some pre-computed reference values. + * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy. + */ + + +err_status_t +srtp_validate_aes_256() { + unsigned char aes_256_test_key[46] = { + 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76, + 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29, + 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1, + 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6, + + 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9, + 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2 + }; + uint8_t srtp_plaintext_ref[28] = { + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab + }; + uint8_t srtp_plaintext[38] = { + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + uint8_t srtp_ciphertext[38] = { + 0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, + 0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17, + 0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74, + 0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a, + 0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b + }; + srtp_t srtp_snd, srtp_recv; + err_status_t status; + int len; + srtp_policy_t policy; + + /* + * create a session with a single stream using the default srtp + * policy and with the SSRC value 0xcafebabe + */ + crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp); + crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp); + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = 0xcafebabe; + policy.key = aes_256_test_key; + policy.ekt = NULL; + policy.window_size = 128; + policy.allow_repeat_tx = 0; + policy.next = NULL; + + status = srtp_create(&srtp_snd, &policy); + if (status) + return status; + + /* + * protect plaintext, then compare with ciphertext + */ + len = 28; + status = srtp_protect(srtp_snd, srtp_plaintext, &len); + if (status || (len != 38)) + return err_status_fail; + + debug_print(mod_driver, "ciphertext:\n %s", + octet_string_hex_string(srtp_plaintext, len)); + debug_print(mod_driver, "ciphertext reference:\n %s", + octet_string_hex_string(srtp_ciphertext, len)); + + if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) + return err_status_fail; + + /* + * create a receiver session context comparable to the one created + * above - we need to do this so that the replay checking doesn't + * complain + */ + status = srtp_create(&srtp_recv, &policy); + if (status) + return status; + + /* + * unprotect ciphertext, then compare with plaintext + */ + status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len); + if (status || (len != 28)) + return status; + + if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) + return err_status_fail; + + status = srtp_dealloc(srtp_snd); + if (status) + return status; + + status = srtp_dealloc(srtp_recv); + if (status) + return status; + + return err_status_ok; +} + + +err_status_t +srtp_create_big_policy(srtp_policy_t **list) { + extern const srtp_policy_t *policy_array[]; + srtp_policy_t *p, *tmp; + int i = 0; + uint32_t ssrc = 0; + + /* sanity checking */ + if ((list == NULL) || (policy_array[0] == NULL)) + return err_status_bad_param; + + /* + * loop over policy list, mallocing a new list and copying values + * into it (and incrementing the SSRC value as we go along) + */ + tmp = NULL; + while (policy_array[i] != NULL) { + p = (srtp_policy_t*) malloc(sizeof(srtp_policy_t)); + if (p == NULL) + return err_status_bad_param; + memcpy(p, policy_array[i], sizeof(srtp_policy_t)); + p->ssrc.type = ssrc_specific; + p->ssrc.value = ssrc++; + p->next = tmp; + tmp = p; + i++; + } + *list = p; + + return err_status_ok; +} + +err_status_t +srtp_dealloc_big_policy(srtp_policy_t *list) { + srtp_policy_t *p, *next; + + for (p = list; p != NULL; p = next) { + next = p->next; + free(p); + } + + return err_status_ok; +} + + +err_status_t +srtp_test_remove_stream() { + err_status_t status; + srtp_policy_t *policy_list, policy; + srtp_t session; + srtp_stream_t stream; + /* + * srtp_get_stream() is a libSRTP internal function that we declare + * here so that we can use it to verify the correct operation of the + * library + */ + extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc); + + + status = srtp_create_big_policy(&policy_list); + if (status) + return status; + + status = srtp_create(&session, policy_list); + if (status) + return status; + + /* + * check for false positives by trying to remove a stream that's not + * in the session + */ + status = srtp_remove_stream(session, htonl(0xaaaaaaaa)); + if (status != err_status_no_ctx) + return err_status_fail; + + /* + * check for false negatives by removing stream 0x1, then + * searching for streams 0x0 and 0x2 + */ + status = srtp_remove_stream(session, htonl(0x1)); + if (status != err_status_ok) + return err_status_fail; + stream = srtp_get_stream(session, htonl(0x0)); + if (stream == NULL) + return err_status_fail; + stream = srtp_get_stream(session, htonl(0x2)); + if (stream == NULL) + return err_status_fail; + + status = srtp_dealloc(session); + if (status != err_status_ok) + return status; + + status = srtp_dealloc_big_policy(policy_list); + if (status != err_status_ok) + return status; + + /* Now test adding and removing a single stream */ + crypto_policy_set_rtp_default(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = 0xcafebabe; + policy.key = test_key; + policy.ekt = NULL; + policy.window_size = 128; + policy.allow_repeat_tx = 0; + policy.next = NULL; + + status = srtp_create(&session, NULL); + if (status != err_status_ok) + return status; + + status = srtp_add_stream(session, &policy); + if (status != err_status_ok) + return status; + + status = srtp_remove_stream(session, htonl(0xcafebabe)); + if (status != err_status_ok) + return status; + + status = srtp_dealloc(session); + if (status != err_status_ok) + return status; + + return err_status_ok; +} + +/* + * srtp policy definitions - these definitions are used above + */ + +unsigned char test_key[30] = { + 0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0, + 0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39, + 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb, + 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6 +}; + + +const srtp_policy_t default_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { /* SRTP policy */ + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 16, /* auth key length in octets */ + 10, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + { /* SRTCP policy */ + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 16, /* auth key length in octets */ + 10, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + test_key, + NULL, /* indicates that EKT is not in use */ + 128, /* replay window size */ + 0, /* retransmission not allowed */ + NULL +}; + +const srtp_policy_t aes_tmmh_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + UST_TMMHv2, /* authentication func type */ + 94, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + { + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + UST_TMMHv2, /* authentication func type */ + 94, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + test_key, + NULL, /* indicates that EKT is not in use */ + 128, /* replay window size */ + 0, /* retransmission not allowed */ + NULL +}; + +const srtp_policy_t tmmh_only_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + UST_TMMHv2, /* authentication func type */ + 94, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_auth /* security services flag */ + }, + { + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + UST_TMMHv2, /* authentication func type */ + 94, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_auth /* security services flag */ + }, + test_key, + NULL, /* indicates that EKT is not in use */ + 128, /* replay window size */ + 0, /* retransmission not allowed */ + NULL +}; + +const srtp_policy_t aes_only_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + NULL_AUTH, /* authentication func type */ + 0, /* auth key length in octets */ + 0, /* auth tag length in octets */ + sec_serv_conf /* security services flag */ + }, + { + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + NULL_AUTH, /* authentication func type */ + 0, /* auth key length in octets */ + 0, /* auth tag length in octets */ + sec_serv_conf /* security services flag */ + }, + test_key, + NULL, /* indicates that EKT is not in use */ + 128, /* replay window size */ + 0, /* retransmission not allowed */ + NULL +}; + +const srtp_policy_t hmac_only_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { + NULL_CIPHER, /* cipher type */ + 0, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 20, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_auth /* security services flag */ + }, + { + NULL_CIPHER, /* cipher type */ + 0, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 20, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_auth /* security services flag */ + }, + test_key, + NULL, /* indicates that EKT is not in use */ + 128, /* replay window size */ + 0, /* retransmission not allowed */ + NULL +}; + +const srtp_policy_t null_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { + NULL_CIPHER, /* cipher type */ + 0, /* cipher key length in octets */ + NULL_AUTH, /* authentication func type */ + 0, /* auth key length in octets */ + 0, /* auth tag length in octets */ + sec_serv_none /* security services flag */ + }, + { + NULL_CIPHER, /* cipher type */ + 0, /* cipher key length in octets */ + NULL_AUTH, /* authentication func type */ + 0, /* auth key length in octets */ + 0, /* auth tag length in octets */ + sec_serv_none /* security services flag */ + }, + test_key, + NULL, /* indicates that EKT is not in use */ + 128, /* replay window size */ + 0, /* retransmission not allowed */ + NULL +}; + +unsigned char test_256_key[46] = { + 0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76, + 0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29, + 0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1, + 0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6, + + 0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9, + 0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2 +}; + +const srtp_policy_t aes_256_hmac_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { /* SRTP policy */ + AES_ICM, /* cipher type */ + 46, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 20, /* auth key length in octets */ + 10, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + { /* SRTCP policy */ + AES_ICM, /* cipher type */ + 46, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 20, /* auth key length in octets */ + 10, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + test_256_key, + NULL, /* indicates that EKT is not in use */ + 128, /* replay window size */ + 0, /* retransmission not allowed */ + NULL +}; + +uint8_t ekt_test_key[16] = { + 0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca, + 0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b +}; + +#include "ekt.h" + +ekt_policy_ctx_t ekt_test_policy = { + 0xa5a5, /* SPI */ + EKT_CIPHER_AES_128_ECB, + ekt_test_key, + NULL +}; + +const srtp_policy_t hmac_only_with_ekt_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { + NULL_CIPHER, /* cipher type */ + 0, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 20, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_auth /* security services flag */ + }, + { + NULL_CIPHER, /* cipher type */ + 0, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 20, /* auth key length in octets */ + 4, /* auth tag length in octets */ + sec_serv_auth /* security services flag */ + }, + test_key, + &ekt_test_policy, /* indicates that EKT is not in use */ + 128, /* replay window size */ + 0, /* retransmission not allowed */ + NULL +}; + + +/* + * an array of pointers to the policies listed above + * + * This array is used to test various aspects of libSRTP for + * different cryptographic policies. The order of the elements + * matters - the timing test generates output that can be used + * in a plot (see the gnuplot script file 'timing'). If you + * add to this list, you should do it at the end. + */ + +#define USE_TMMH 0 + +const srtp_policy_t * +policy_array[] = { + &hmac_only_policy, +#if USE_TMMH + &tmmh_only_policy, +#endif + &aes_only_policy, +#if USE_TMMH + &aes_tmmh_policy, +#endif + &default_policy, + &null_policy, + &aes_256_hmac_policy, + &hmac_only_with_ekt_policy, + NULL +}; + +const srtp_policy_t wildcard_policy = { + { ssrc_any_outbound, 0 }, /* SSRC */ + { /* SRTP policy */ + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 16, /* auth key length in octets */ + 10, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + { /* SRTCP policy */ + AES_128_ICM, /* cipher type */ + 30, /* cipher key length in octets */ + HMAC_SHA1, /* authentication func type */ + 16, /* auth key length in octets */ + 10, /* auth tag length in octets */ + sec_serv_conf_and_auth /* security services flag */ + }, + test_key, + NULL, + 128, /* replay window size */ + 0, /* retransmission not allowed */ + NULL +}; diff --git a/src/libs/srtp/timing b/src/libs/srtp/timing new file mode 100644 index 00000000..66b00c45 --- /dev/null +++ b/src/libs/srtp/timing @@ -0,0 +1 @@ +# timing.plt # # gnuplot script file for plotting the output generated by srtp_driver -t # # David A. McGrew # Cisco Systems, Inc. # set xrange [0:2500] set term pict "Times-Roman" 9 # # plot authentication-only data # set title "Authentication Only" set ylabel "Megabits per second" set xlabel "Octets in packet" set yrange [0:2000] set output "plot-auth.pict" plot "timing.dat" index 0 title "HMAC SHA1" with lines, "timing.dat" index 1 title "TMMH/AES" with lines, "timing.dat" index 2 title "TMMH/SEAL" with lines # # plot encryption-only data # set title "Encryption Only" set ylabel "Megabits per second" set xlabel "Octets in packet" set output "plot-enc.pict" set yrange [0:1200] plot "timing.dat" index 3 title "SEAL" with lines, "timing.dat" index 4 title "AES ICM" with lines # # plot encryption and authentication data # set title "Encryption and Authentication" set ylabel "Megabits per second" set xlabel "Octets in packet" set yrange [0:1000] set output "plot-enc-auth.pict" plot "timing.dat" index 5 title "TMMH/SEAL" with lines, "timing.dat" index 6 title "TMMH/AES" with lines, "timing.dat" index 7 title "HMAC/AES" with lines \ No newline at end of file diff --git a/src/libs/srtp/undos.sh b/src/libs/srtp/undos.sh new file mode 100644 index 00000000..db120649 --- /dev/null +++ b/src/libs/srtp/undos.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# +# usage: undos <file> +# +# strips CRs from a file - useful when moving DOS-created files +# onto UN*X machines + +cat $1 | tr -d "\r" > $1.tmp +mv $1.tmp $1 + diff --git a/src/libs/srtp/update.sh b/src/libs/srtp/update.sh new file mode 100644 index 00000000..595b647f --- /dev/null +++ b/src/libs/srtp/update.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# +# update.sh +# +# update copyright dates in files + +a=`find . -name "*.[ch]"` +for x in $a; do + sed 's/(c) 2001-2005/(c) 2001-2006/' $x > $x.tmp; + mv $x.tmp $x; +done + + + + diff --git a/src/libs/stb_image.c b/src/libs/stb_image.c new file mode 100644 index 00000000..540ad183 --- /dev/null +++ b/src/libs/stb_image.c @@ -0,0 +1,4954 @@ +/* stbi-1.29 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c + when you control the images you're loading + no warranty implied; use at your own risk + + QUICK NOTES: + Primarily of interest to game developers and other people who can + avoid problematic images and only need the trivial interface + + JPEG baseline (no JPEG progressive) + PNG 8-bit only + + TGA (not sure what subset, if a subset) + BMP non-1bpp, non-RLE + PSD (composited view only, no extra channels) + + GIF (*comp always reports as 4-channel) + HDR (radiance rgbE format) + PIC (Softimage PIC) + + - decoded from memory or through stdio FILE (define STBI_NO_STDIO to remove code) + - supports installable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD) + + Latest revisions: + 1.29 (2010-08-16) various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) cast-to-uint8 to fix warnings (Laurent Gomila) + allow trailing 0s at end of image data (Laurent Gomila) + 1.26 (2010-07-24) fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) refix trans_data warning (Won Chun) + 1.24 (2010-07-12) perf improvements reading from files + minor perf improvements for jpeg + deprecated type-specific functions in hope of feedback + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) removed image *writing* support to stb_image_write.h + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva + 1.21 fix use of 'uint8' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + + See end of file for full revision history. + + TODO: + stbi_info support for BMP,PSD,HDR,PIC + rewrite stbi_info and load_file variations to share file handling code + (current system allows individual functions to be called directly, + since each does all the work, but I doubt anyone uses this in practice) + + + ============================ Contributors ========================= + + Image formats Optimizations & bugfixes + Sean Barrett (jpeg, png, bmp) Fabian "ryg" Giesen + Nicolas Schulz (hdr, psd) + Jonathan Dummer (tga) Bug fixes & warning fixes + Jean-Marc Lienher (gif) Marc LeBlanc + Tom Seddon (pic) Christpher Lloyd + Thatcher Ulrich (psd) Dave Moore + Won Chun + the Horde3D community + Extensions, features Janez Zemva + Jetro Lauha (stbi_info) Jonathan Blow + James "moose2000" Brown (iPhone PNG) Laurent Gomila + Aruelien Pocheville + + If your name should be here but isn't, let Sean know. + +*/ + +#ifndef STBI_INCLUDE_STB_IMAGE_H +#define STBI_INCLUDE_STB_IMAGE_H + +// To get a header file for this, either cut and paste the header, +// or create stb_image.h, #define STBI_HEADER_FILE_ONLY, and +// then include stb_image.c from it. + +//// begin header file //////////////////////////////////////////////////// +// +// Limitations: +// - no jpeg progressive support +// - non-HDR formats support 8-bit samples only (jpeg, png) +// - no delayed line count (jpeg) -- IJG doesn't support either +// - no 1-bit BMP +// - GIF always returns *comp=4 +// +// Basic usage (see HDR discussion below): +// int x,y,n; +// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); +// // ... process data if not NULL ... +// // ... x = width, y = height, n = # 8-bit components per pixel ... +// // ... replace '0' with '1'..'4' to force that many components per pixel +// stbi_image_free(data) +// +// Standard parameters: +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *comp -- outputs # of image components in image file +// int req_comp -- if non-zero, # of image components requested in result +// +// The return value from an image loader is an 'unsigned char *' which points +// to the pixel data. The pixel data consists of *y scanlines of *x pixels, +// with each pixel consisting of N interleaved 8-bit components; the first +// pixel pointed to is top-left-most in the image. There is no padding between +// image scanlines or between pixels, regardless of format. The number of +// components N is 'req_comp' if req_comp is non-zero, or *comp otherwise. +// If req_comp is non-zero, *comp has the number of components that _would_ +// have been output otherwise. E.g. if you set req_comp to 4, you will always +// get RGBA output, but you can check *comp to easily see if it's opaque. +// +// An output image with N components has the following components interleaved +// in this order in each pixel: +// +// N=#comp components +// 1 grey +// 2 grey, alpha +// 3 red, green, blue +// 4 red, green, blue, alpha +// +// If image loading fails for any reason, the return value will be NULL, +// and *x, *y, *comp will be unchanged. The function stbi_failure_reason() +// can be queried for an extremely brief, end-user unfriendly explanation +// of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid +// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly +// more user-friendly ones. +// +// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. +// +// =========================================================================== +// +// iPhone PNG support: +// +// By default we convert iphone-formatted PNGs back to RGB; nominally they +// would silently load as BGR, except the existing code should have just +// failed on such iPhone PNGs. But you can disable this conversion by +// by calling stbi_convert_iphone_png_to_rgb(0), in which case +// you will always just get the native iphone "format" through. +// +// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per +// pixel to remove any premultiplied alpha *only* if the image file explicitly +// says there's premultiplied data (currently only happens in iPhone images, +// and only if iPhone convert-to-rgb processing is on). +// +// =========================================================================== +// +// HDR image support (disable by defining STBI_NO_HDR) +// +// stb_image now supports loading HDR images in general, and currently +// the Radiance .HDR file format, although the support is provided +// generically. You can still load any file through the existing interface; +// if you attempt to load an HDR file, it will be automatically remapped to +// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// both of these constants can be reconfigured through this interface: +// +// stbi_hdr_to_ldr_gamma(2.2f); +// stbi_hdr_to_ldr_scale(1.0f); +// +// (note, do not use _inverse_ constants; stbi_image will invert them +// appropriately). +// +// Additionally, there is a new, parallel interface for loading files as +// (linear) floats to preserve the full dynamic range: +// +// float *data = stbi_loadf(filename, &x, &y, &n, 0); +// +// If you load LDR images through this interface, those images will +// be promoted to floating point values, run through the inverse of +// constants corresponding to the above: +// +// stbi_ldr_to_hdr_scale(1.0f); +// stbi_ldr_to_hdr_gamma(2.2f); +// +// Finally, given a filename (or an open file or memory block--see header +// file for details) containing image data, you can query for the "most +// appropriate" interface to use (that is, whether the image is HDR or +// not), using: +// +// stbi_is_hdr(char *filename); + +#ifndef STBI_NO_STDIO +#include <stdio.h> +#endif + +#define STBI_VERSION 1 + +enum +{ + STBI_default = 0, // only used for req_comp + + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 +}; + +typedef unsigned char stbi_uc; + +#ifdef __cplusplus +extern "C" { +#endif + +// PRIMARY API - works on images of any type + +// load image by filename, open file, or memory buffer +extern stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); + +#ifndef STBI_NO_STDIO +extern stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +// for stbi_load_from_file, file pointer is left pointing immediately after image +#endif + +#ifndef STBI_NO_HDR + extern float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); + + #ifndef STBI_NO_STDIO + extern float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp); + extern float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); + #endif + + extern void stbi_hdr_to_ldr_gamma(float gamma); + extern void stbi_hdr_to_ldr_scale(float scale); + + extern void stbi_ldr_to_hdr_gamma(float gamma); + extern void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_HDR + +// get a VERY brief reason for failure +// NOT THREADSAFE +extern const char *stbi_failure_reason (void); + +// free the loaded image -- this is just free() +extern void stbi_image_free (void *retval_from_stbi_load); + +// get image dimensions & components without fully decoding +extern int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); +extern int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); + +#ifndef STBI_NO_STDIO +extern int stbi_info (char const *filename, int *x, int *y, int *comp); +extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); + +extern int stbi_is_hdr (char const *filename); +extern int stbi_is_hdr_from_file(FILE *f); +#endif + +// for image formats that explicitly notate that they have premultiplied alpha, +// we just return the colors as stored in the file. set this flag to force +// unpremultiplication. results are undefined if the unpremultiply overflow. +extern void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + +// indicate whether we should process iphone images back to canonical format, +// or just pass them through "as-is" +extern void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + + +// ZLIB client - used by PNG, available for other purposes + +extern char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); +extern char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); +extern int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + +extern char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); +extern int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + +// define new loaders +typedef struct +{ + int (*test_memory)(stbi_uc const *buffer, int len); + stbi_uc * (*load_from_memory)(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); + #ifndef STBI_NO_STDIO + int (*test_file)(FILE *f); + stbi_uc * (*load_from_file)(FILE *f, int *x, int *y, int *comp, int req_comp); + #endif +} stbi_loader; + +// register a loader by filling out the above structure (you must define ALL functions) +// returns 1 if added or already added, 0 if not added (too many loaders) +// NOT THREADSAFE +extern int stbi_register_loader(stbi_loader *loader); + +// define faster low-level operations (typically SIMD support) +#ifdef STBI_SIMD +typedef void (*stbi_idct_8x8)(stbi_uc *out, int out_stride, short data[64], unsigned short *dequantize); +// compute an integer IDCT on "input" +// input[x] = data[x] * dequantize[x] +// write results to 'out': 64 samples, each run of 8 spaced by 'out_stride' +// CLAMP results to 0..255 +typedef void (*stbi_YCbCr_to_RGB_run)(stbi_uc *output, stbi_uc const *y, stbi_uc const *cb, stbi_uc const *cr, int count, int step); +// compute a conversion from YCbCr to RGB +// 'count' pixels +// write pixels to 'output'; each pixel is 'step' bytes (either 3 or 4; if 4, write '255' as 4th), order R,G,B +// y: Y input channel +// cb: Cb input channel; scale/biased to be 0..255 +// cr: Cr input channel; scale/biased to be 0..255 + +extern void stbi_install_idct(stbi_idct_8x8 func); +extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func); +#endif // STBI_SIMD + + + + +// TYPE-SPECIFIC ACCESS + +#ifdef STBI_TYPE_SPECIFIC_FUNCTIONS + +// is it a jpeg? +extern int stbi_jpeg_test_memory (stbi_uc const *buffer, int len); +extern stbi_uc *stbi_jpeg_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +extern int stbi_jpeg_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); + +#ifndef STBI_NO_STDIO +extern stbi_uc *stbi_jpeg_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern int stbi_jpeg_test_file (FILE *f); +extern stbi_uc *stbi_jpeg_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); + +extern int stbi_jpeg_info (char const *filename, int *x, int *y, int *comp); +extern int stbi_jpeg_info_from_file (FILE *f, int *x, int *y, int *comp); +#endif + +// is it a png? +extern int stbi_png_test_memory (stbi_uc const *buffer, int len); +extern stbi_uc *stbi_png_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +extern int stbi_png_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp); + +#ifndef STBI_NO_STDIO +extern stbi_uc *stbi_png_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern int stbi_png_info (char const *filename, int *x, int *y, int *comp); +extern int stbi_png_test_file (FILE *f); +extern stbi_uc *stbi_png_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +extern int stbi_png_info_from_file (FILE *f, int *x, int *y, int *comp); +#endif + +// is it a bmp? +extern int stbi_bmp_test_memory (stbi_uc const *buffer, int len); + +extern stbi_uc *stbi_bmp_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern stbi_uc *stbi_bmp_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +#ifndef STBI_NO_STDIO +extern int stbi_bmp_test_file (FILE *f); +extern stbi_uc *stbi_bmp_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +#endif + +// is it a tga? +extern int stbi_tga_test_memory (stbi_uc const *buffer, int len); + +extern stbi_uc *stbi_tga_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern stbi_uc *stbi_tga_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +#ifndef STBI_NO_STDIO +extern int stbi_tga_test_file (FILE *f); +extern stbi_uc *stbi_tga_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +#endif + +// is it a psd? +extern int stbi_psd_test_memory (stbi_uc const *buffer, int len); + +extern stbi_uc *stbi_psd_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern stbi_uc *stbi_psd_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +#ifndef STBI_NO_STDIO +extern int stbi_psd_test_file (FILE *f); +extern stbi_uc *stbi_psd_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +#endif + +// is it an hdr? +extern int stbi_hdr_test_memory (stbi_uc const *buffer, int len); + +extern float * stbi_hdr_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern float * stbi_hdr_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +#ifndef STBI_NO_STDIO +extern int stbi_hdr_test_file (FILE *f); +extern float * stbi_hdr_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +#endif + +// is it a pic? +extern int stbi_pic_test_memory (stbi_uc const *buffer, int len); + +extern stbi_uc *stbi_pic_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern stbi_uc *stbi_pic_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +#ifndef STBI_NO_STDIO +extern int stbi_pic_test_file (FILE *f); +extern stbi_uc *stbi_pic_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +#endif + +// is it a gif? +extern int stbi_gif_test_memory (stbi_uc const *buffer, int len); + +extern stbi_uc *stbi_gif_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern stbi_uc *stbi_gif_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +extern int stbi_gif_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp); + +#ifndef STBI_NO_STDIO +extern int stbi_gif_test_file (FILE *f); +extern stbi_uc *stbi_gif_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +extern int stbi_gif_info (char const *filename, int *x, int *y, int *comp); +extern int stbi_gif_info_from_file (FILE *f, int *x, int *y, int *comp); +#endif + +#endif//STBI_TYPE_SPECIFIC_FUNCTIONS + + + + +#ifdef __cplusplus +} +#endif + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBI_INCLUDE_STB_IMAGE_H + +#ifndef STBI_HEADER_FILE_ONLY + +#ifndef STBI_NO_HDR +#include <math.h> // ldexp +#include <string.h> // strcmp +#endif + +#ifndef STBI_NO_STDIO +#include <stdio.h> +#endif +#include <stdlib.h> +#include <memory.h> +#include <assert.h> +#include <stdarg.h> + +#ifndef _MSC_VER + #ifdef __cplusplus + #define __forceinline inline + #else + #define __forceinline + #endif +#endif + + +// implementation: +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef signed short int16; +typedef unsigned int uint32; +typedef signed int int32; +typedef unsigned int uint; + +// should produce compiler error if size is wrong +typedef unsigned char validate_uint32[sizeof(uint32)==4 ? 1 : -1]; + +#if defined(STBI_NO_STDIO) && !defined(STBI_NO_WRITE) +#define STBI_NO_WRITE +#endif + +#define STBI_NOTUSED(v) v=v + +#ifdef _MSC_VER +#define STBI_HAS_LRTOL +#endif + +#ifdef STBI_HAS_LRTOL + #define stbi_lrot(x,y) _lrotl(x,y) +#else + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// Generic API that works on all image types +// + +// deprecated functions + +// is it a jpeg? +extern int stbi_jpeg_test_memory (stbi_uc const *buffer, int len); +extern stbi_uc *stbi_jpeg_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +extern int stbi_jpeg_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); + +#ifndef STBI_NO_STDIO +extern stbi_uc *stbi_jpeg_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern int stbi_jpeg_test_file (FILE *f); +extern stbi_uc *stbi_jpeg_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); + +extern int stbi_jpeg_info (char const *filename, int *x, int *y, int *comp); +extern int stbi_jpeg_info_from_file (FILE *f, int *x, int *y, int *comp); +#endif + +// is it a png? +extern int stbi_png_test_memory (stbi_uc const *buffer, int len); +extern stbi_uc *stbi_png_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +extern int stbi_png_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp); + +#ifndef STBI_NO_STDIO +extern stbi_uc *stbi_png_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern int stbi_png_info (char const *filename, int *x, int *y, int *comp); +extern int stbi_png_test_file (FILE *f); +extern stbi_uc *stbi_png_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +extern int stbi_png_info_from_file (FILE *f, int *x, int *y, int *comp); +#endif + +// is it a bmp? +extern int stbi_bmp_test_memory (stbi_uc const *buffer, int len); + +extern stbi_uc *stbi_bmp_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern stbi_uc *stbi_bmp_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +#ifndef STBI_NO_STDIO +extern int stbi_bmp_test_file (FILE *f); +extern stbi_uc *stbi_bmp_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +#endif + +// is it a tga? +extern int stbi_tga_test_memory (stbi_uc const *buffer, int len); + +extern stbi_uc *stbi_tga_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern stbi_uc *stbi_tga_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +#ifndef STBI_NO_STDIO +extern int stbi_tga_test_file (FILE *f); +extern stbi_uc *stbi_tga_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +#endif + +// is it a psd? +extern int stbi_psd_test_memory (stbi_uc const *buffer, int len); + +extern stbi_uc *stbi_psd_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern stbi_uc *stbi_psd_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +#ifndef STBI_NO_STDIO +extern int stbi_psd_test_file (FILE *f); +extern stbi_uc *stbi_psd_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +#endif + +// is it an hdr? +extern int stbi_hdr_test_memory (stbi_uc const *buffer, int len); + +extern float * stbi_hdr_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern float * stbi_hdr_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +#ifndef STBI_NO_STDIO +extern int stbi_hdr_test_file (FILE *f); +extern float * stbi_hdr_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +#endif + +// is it a pic? +extern int stbi_pic_test_memory (stbi_uc const *buffer, int len); + +extern stbi_uc *stbi_pic_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern stbi_uc *stbi_pic_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +#ifndef STBI_NO_STDIO +extern int stbi_pic_test_file (FILE *f); +extern stbi_uc *stbi_pic_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +#endif + +// is it a gif? +extern int stbi_gif_test_memory (stbi_uc const *buffer, int len); + +extern stbi_uc *stbi_gif_load (char const *filename, int *x, int *y, int *comp, int req_comp); +extern stbi_uc *stbi_gif_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); +extern int stbi_gif_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp); + +#ifndef STBI_NO_STDIO +extern int stbi_gif_test_file (FILE *f); +extern stbi_uc *stbi_gif_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +extern int stbi_gif_info (char const *filename, int *x, int *y, int *comp); +extern int stbi_gif_info_from_file (FILE *f, int *x, int *y, int *comp); +#endif + + +// this is not threadsafe +static const char *failure_reason; + +const char *stbi_failure_reason(void) +{ + return failure_reason; +} + +static int e(const char *str) +{ + failure_reason = str; + return 0; +} + +#ifdef STBI_NO_FAILURE_STRINGS + #define e(x,y) 0 +#elif defined(STBI_FAILURE_USERMSG) + #define e(x,y) e(y) +#else + #define e(x,y) e(x) +#endif + +#define epf(x,y) ((float *) (e(x,y)?NULL:NULL)) +#define epuc(x,y) ((unsigned char *) (e(x,y)?NULL:NULL)) + +void stbi_image_free(void *retval_from_stbi_load) +{ + free(retval_from_stbi_load); +} + +#define MAX_LOADERS 32 +stbi_loader *loaders[MAX_LOADERS]; +static int max_loaders = 0; + +int stbi_register_loader(stbi_loader *loader) +{ + int i; + for (i=0; i < MAX_LOADERS; ++i) { + // already present? + if (loaders[i] == loader) + return 1; + // end of the list? + if (loaders[i] == NULL) { + loaders[i] = loader; + max_loaders = i+1; + return 1; + } + } + // no room for it + return 0; +} + +#ifndef STBI_NO_HDR +static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp); +#endif + +#ifndef STBI_NO_STDIO +unsigned char *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = fopen(filename, "rb"); + unsigned char *result; + if (!f) return epuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +unsigned char *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + int i; + if (stbi_jpeg_test_file(f)) return stbi_jpeg_load_from_file(f,x,y,comp,req_comp); + if (stbi_png_test_file(f)) return stbi_png_load_from_file(f,x,y,comp,req_comp); + if (stbi_bmp_test_file(f)) return stbi_bmp_load_from_file(f,x,y,comp,req_comp); + if (stbi_gif_test_file(f)) return stbi_gif_load_from_file(f,x,y,comp,req_comp); + if (stbi_psd_test_file(f)) return stbi_psd_load_from_file(f,x,y,comp,req_comp); + if (stbi_pic_test_file(f)) return stbi_pic_load_from_file(f,x,y,comp,req_comp); + + #ifndef STBI_NO_HDR + if (stbi_hdr_test_file(f)) { + float *hdr = stbi_hdr_load_from_file(f, x,y,comp,req_comp); + return hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } + #endif + + for (i=0; i < max_loaders; ++i) + if (loaders[i]->test_file(f)) + return loaders[i]->load_from_file(f,x,y,comp,req_comp); + // test tga last because it's a crappy test! + if (stbi_tga_test_file(f)) + return stbi_tga_load_from_file(f,x,y,comp,req_comp); + return epuc("unknown image type", "Image not of any known type, or corrupt"); +} +#endif + +unsigned char *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + int i; + if (stbi_jpeg_test_memory(buffer,len)) return stbi_jpeg_load_from_memory(buffer,len,x,y,comp,req_comp); + if (stbi_png_test_memory(buffer,len)) return stbi_png_load_from_memory(buffer,len,x,y,comp,req_comp); + if (stbi_bmp_test_memory(buffer,len)) return stbi_bmp_load_from_memory(buffer,len,x,y,comp,req_comp); + if (stbi_gif_test_memory(buffer,len)) return stbi_gif_load_from_memory(buffer,len,x,y,comp,req_comp); + if (stbi_psd_test_memory(buffer,len)) return stbi_psd_load_from_memory(buffer,len,x,y,comp,req_comp); + if (stbi_pic_test_memory(buffer,len)) return stbi_pic_load_from_memory(buffer,len,x,y,comp,req_comp); + + #ifndef STBI_NO_HDR + if (stbi_hdr_test_memory(buffer, len)) { + float *hdr = stbi_hdr_load_from_memory(buffer, len,x,y,comp,req_comp); + return hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } + #endif + + for (i=0; i < max_loaders; ++i) + if (loaders[i]->test_memory(buffer,len)) + return loaders[i]->load_from_memory(buffer,len,x,y,comp,req_comp); + // test tga last because it's a crappy test! + if (stbi_tga_test_memory(buffer,len)) + return stbi_tga_load_from_memory(buffer,len,x,y,comp,req_comp); + return epuc("unknown image type", "Image not of any known type, or corrupt"); +} + +#ifndef STBI_NO_HDR + +#ifndef STBI_NO_STDIO +float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = fopen(filename, "rb"); + float *result; + if (!f) return epf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + #ifndef STBI_NO_HDR + if (stbi_hdr_test_file(f)) + return stbi_hdr_load_from_file(f,x,y,comp,req_comp); + #endif + data = stbi_load_from_file(f, x, y, comp, req_comp); + if (data) + return ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return epf("unknown image type", "Image not of any known type, or corrupt"); +} +#endif + +float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *data; + #ifndef STBI_NO_HDR + if (stbi_hdr_test_memory(buffer, len)) + return stbi_hdr_load_from_memory(buffer, len,x,y,comp,req_comp); + #endif + data = stbi_load_from_memory(buffer, len, x, y, comp, req_comp); + if (data) + return ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return epf("unknown image type", "Image not of any known type, or corrupt"); +} +#endif + +// these is-hdr-or-not is defined independent of whether STBI_NO_HDR is +// defined, for API simplicity; if STBI_NO_HDR is defined, it always +// reports false! + +int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) +{ + #ifndef STBI_NO_HDR + return stbi_hdr_test_memory(buffer, len); + #else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; + #endif +} + +#ifndef STBI_NO_STDIO +extern int stbi_is_hdr (char const *filename) +{ + FILE *f = fopen(filename, "rb"); + int result=0; + if (f) { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; +} + +extern int stbi_is_hdr_from_file(FILE *f) +{ + #ifndef STBI_NO_HDR + return stbi_hdr_test_file(f); + #else + return 0; + #endif +} + +#endif + +#ifndef STBI_NO_HDR +static float h2l_gamma_i=1.0f/2.2f, h2l_scale_i=1.0f; +static float l2h_gamma=2.2f, l2h_scale=1.0f; + +void stbi_hdr_to_ldr_gamma(float gamma) { h2l_gamma_i = 1/gamma; } +void stbi_hdr_to_ldr_scale(float scale) { h2l_scale_i = 1/scale; } + +void stbi_ldr_to_hdr_gamma(float gamma) { l2h_gamma = gamma; } +void stbi_ldr_to_hdr_scale(float scale) { l2h_scale = scale; } +#endif + + +////////////////////////////////////////////////////////////////////////////// +// +// Common code used by all image loaders +// + +enum +{ + SCAN_load=0, + SCAN_type, + SCAN_header +}; + +typedef struct +{ + uint32 img_x, img_y; + int img_n, img_out_n; + + #ifndef STBI_NO_STDIO + FILE *img_file; + int buflen; + uint8 buffer_start[128]; + int from_file; + #endif + uint8 *img_buffer, *img_buffer_end; +} stbi; + +#ifndef STBI_NO_STDIO +static void start_file(stbi *s, FILE *f) +{ + s->img_file = f; + s->buflen = sizeof(s->buffer_start); + s->img_buffer_end = s->buffer_start + s->buflen; + s->img_buffer = s->img_buffer_end; + s->from_file = 1; +} +#endif + +static void start_mem(stbi *s, uint8 const *buffer, int len) +{ +#ifndef STBI_NO_STDIO + s->img_file = NULL; + s->from_file = 0; +#endif + s->img_buffer = (uint8 *) buffer; + s->img_buffer_end = (uint8 *) buffer+len; +} + +#ifndef STBI_NO_STDIO +static void refill_buffer(stbi *s) +{ + int n = fread(s->buffer_start, 1, s->buflen, s->img_file); + if (n == 0) { + s->from_file = 0; + s->img_buffer = s->img_buffer_end-1; + *s->img_buffer = 0; + } else { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} +#endif + +__forceinline static int get8(stbi *s) +{ + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; +#ifndef STBI_NO_STDIO + if (s->from_file) { + refill_buffer(s); + return *s->img_buffer++; + } +#endif + return 0; +} + +__forceinline static int at_eof(stbi *s) +{ +#ifndef STBI_NO_STDIO + if (s->img_file) { + if (!feof(s->img_file)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if (s->from_file == 0) return 1; + } +#endif + return s->img_buffer >= s->img_buffer_end; +} + +__forceinline static uint8 get8u(stbi *s) +{ + return (uint8) get8(s); +} + +static void skip(stbi *s, int n) +{ +#ifndef STBI_NO_STDIO + if (s->img_file) { + int blen = s->img_buffer_end - s->img_buffer; + if (blen < n) { + s->img_buffer = s->img_buffer_end; + fseek(s->img_file, n - blen, SEEK_CUR); + return; + } + } +#endif + s->img_buffer += n; +} + +static int getn(stbi *s, stbi_uc *buffer, int n) +{ +#ifndef STBI_NO_STDIO + if (s->img_file) { + int blen = s->img_buffer_end - s->img_buffer; + if (blen < n) { + int res; + memcpy(buffer, s->img_buffer, blen); + res = ((int) fread(buffer + blen, 1, n - blen, s->img_file) == (n-blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } +#endif + if (s->img_buffer+n <= s->img_buffer_end) { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } else + return 0; +} + +static int get16(stbi *s) +{ + int z = get8(s); + return (z << 8) + get8(s); +} + +static uint32 get32(stbi *s) +{ + uint32 z = get16(s); + return (z << 16) + get16(s); +} + +static int get16le(stbi *s) +{ + int z = get8(s); + return z + (get8(s) << 8); +} + +static uint32 get32le(stbi *s) +{ + uint32 z = get16le(s); + return z + (get16le(s) << 16); +} + +////////////////////////////////////////////////////////////////////////////// +// +// generic converter from built-in img_n to req_comp +// individual types do this automatically as much as possible (e.g. jpeg +// does all cases internally since it needs to colorspace convert anyway, +// and it never has alpha, so very few cases ). png can automatically +// interleave an alpha=255 channel, but falls back to this for other cases +// +// assume data buffer is malloced, so malloc a new one and free that one +// only failure mode is malloc failing + +static uint8 compute_y(int r, int g, int b) +{ + return (uint8) (((r*77) + (g*150) + (29*b)) >> 8); +} + +static unsigned char *convert_format(unsigned char *data, int img_n, int req_comp, uint x, uint y) +{ + int i,j; + unsigned char *good; + + if (req_comp == img_n) return data; + assert(req_comp >= 1 && req_comp <= 4); + + good = (unsigned char *) malloc(req_comp * x * y); + if (good == NULL) { + free(data); + return epuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + unsigned char *src = data + j * x * img_n ; + unsigned char *dest = good + j * x * req_comp; + + #define COMBO(a,b) ((a)*8+(b)) + #define CASE(a,b) case COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (COMBO(img_n, req_comp)) { + CASE(1,2) dest[0]=src[0], dest[1]=255; break; + CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; + CASE(2,1) dest[0]=src[0]; break; + CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; + CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; + CASE(3,1) dest[0]=compute_y(src[0],src[1],src[2]); break; + CASE(3,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = 255; break; + CASE(4,1) dest[0]=compute_y(src[0],src[1],src[2]); break; + CASE(4,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; + CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; + default: assert(0); + } + #undef CASE + } + + free(data); + return good; +} + +#ifndef STBI_NO_HDR +static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +{ + int i,k,n; + float *output = (float *) malloc(x * y * comp * sizeof(float)); + if (output == NULL) { free(data); return epf("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + output[i*comp + k] = (float) pow(data[i*comp+k]/255.0f, l2h_gamma) * l2h_scale; + } + if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; + } + free(data); + return output; +} + +#define float2int(x) ((int) (x)) +static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp) +{ + int i,k,n; + stbi_uc *output = (stbi_uc *) malloc(x * y * comp); + if (output == NULL) { free(data); return epuc("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + float z = (float) pow(data[i*comp+k]*h2l_scale_i, h2l_gamma_i) * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (uint8) float2int(z); + } + if (k < comp) { + float z = data[i*comp+k] * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (uint8) float2int(z); + } + } + free(data); + return output; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// "baseline" JPEG/JFIF decoder (not actually fully baseline implementation) +// +// simple implementation +// - channel subsampling of at most 2 in each dimension +// - doesn't support delayed output of y-dimension +// - simple interface (only one output format: 8-bit interleaved RGB) +// - doesn't try to recover corrupt jpegs +// - doesn't allow partial loading, loading multiple at once +// - still fast on x86 (copying globals into locals doesn't help x86) +// - allocates lots of intermediate memory (full size of all components) +// - non-interleaved case requires this anyway +// - allows good upsampling (see next) +// high-quality +// - upsampled channels are bilinearly interpolated, even across blocks +// - quality integer IDCT derived from IJG's 'slow' +// performance +// - fast huffman; reasonable integer IDCT +// - uses a lot of intermediate memory, could cache poorly +// - load http://nothings.org/remote/anemones.jpg 3 times on 2.8Ghz P4 +// stb_jpeg: 1.34 seconds (MSVC6, default release build) +// stb_jpeg: 1.06 seconds (MSVC6, processor = Pentium Pro) +// IJL11.dll: 1.08 seconds (compiled by intel) +// IJG 1998: 0.98 seconds (MSVC6, makefile provided by IJG) +// IJG 1998: 0.95 seconds (MSVC6, makefile + proc=PPro) + +// huffman decoding acceleration +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache + +typedef struct +{ + uint8 fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + uint16 code[256]; + uint8 values[256]; + uint8 size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' +} huffman; + +typedef struct +{ + #ifdef STBI_SIMD + unsigned short dequant2[4][64]; + #endif + stbi s; + huffman huff_dc[4]; + huffman huff_ac[4]; + uint8 dequant[4][64]; + +// sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + +// definition of jpeg image component + struct + { + int id; + int h,v; + int tq; + int hd,ha; + int dc_pred; + + int x,y,w2,h2; + uint8 *data; + void *raw_data; + uint8 *linebuf; + } img_comp[4]; + + uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop + + int scan_n, order[4]; + int restart_interval, todo; +} jpeg; + +static int build_huffman(huffman *h, int *count) +{ + int i,j,k=0,code; + // build size list for each symbol (from JPEG spec) + for (i=0; i < 16; ++i) + for (j=0; j < count[i]; ++j) + h->size[k++] = (uint8) (i+1); + h->size[k] = 0; + + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for(j=1; j <= 16; ++j) { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if (h->size[k] == j) { + while (h->size[k] == j) + h->code[k++] = (uint16) (code++); + if (code-1 >= (1 << j)) return e("bad code lengths","Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16-j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for (i=0; i < k; ++i) { + int s = h->size[i]; + if (s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS-s); + int m = 1 << (FAST_BITS-s); + for (j=0; j < m; ++j) { + h->fast[c+j] = (uint8) i; + } + } + } + return 1; +} + +static void grow_buffer_unsafe(jpeg *j) +{ + do { + int b = j->nomore ? 0 : get8(&j->s); + if (b == 0xff) { + int c = get8(&j->s); + if (c != 0) { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); +} + +// (1 << n) - 1 +static uint32 bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; + +// decode a jpeg huffman value from the bitstream +__forceinline static int decode(jpeg *j, huffman *h) +{ + unsigned int temp; + int c,k; + + if (j->code_bits < 16) grow_buffer_unsafe(j); + + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + k = h->fast[c]; + if (k < 255) { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for (k=FAST_BITS+1 ; ; ++k) + if (temp < h->maxcode[k]) + break; + if (k == 17) { + // error! code not found + j->code_bits -= 16; + return -1; + } + + if (k > j->code_bits) + return -1; + + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & bmask[k]) + h->delta[k]; + assert((((j->code_buffer) >> (32 - h->size[c])) & bmask[h->size[c]]) == h->code[c]); + + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +// combined JPEG 'receive' and JPEG 'extend', since baseline +// always extends everything it receives. +__forceinline static int extend_receive(jpeg *j, int n) +{ + unsigned int m = 1 << (n-1); + unsigned int k; + if (j->code_bits < n) grow_buffer_unsafe(j); + + #if 1 + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~bmask[n]; + k &= bmask[n]; + j->code_bits -= n; + #else + k = (j->code_buffer >> (32 - n)) & bmask[n]; + j->code_bits -= n; + j->code_buffer <<= n; + #endif + // the following test is probably a random branch that won't + // predict well. I tried to table accelerate it but failed. + // maybe it's compiling as a conditional move? + if (k < m) + return (-1 << n) + k + 1; + else + return k; +} + +// given a value that's at position X in the zigzag stream, +// where does it appear in the 8x8 matrix coded as row-major? +static uint8 dezigzag[64+15] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +// decode one 64-entry block-- +static int decode_block(jpeg *j, short data[64], huffman *hdc, huffman *hac, int b) +{ + int diff,dc,k; + int t = decode(j, hdc); + if (t < 0) return e("bad huffman code","Corrupt JPEG"); + + // 0 all the ac values now so we can do it 32-bits at a time + memset(data,0,64*sizeof(data[0])); + + diff = t ? extend_receive(j, t) : 0; + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) dc; + + // decode AC components, see JPEG spec + k = 1; + do { + int r,s; + int rs = decode(j, hac); + if (rs < 0) return e("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (rs != 0xf0) break; // end block + k += 16; + } else { + k += r; + // decode into unzigzag'd location + data[dezigzag[k++]] = (short) extend_receive(j,s); + } + } while (k < 64); + return 1; +} + +// take a -128..127 value and clamp it and convert to 0..255 +__forceinline static uint8 clamp(int x) +{ + // trick to use a single test to catch both cases + if ((unsigned int) x > 255) { + if (x < 0) return 0; + if (x > 255) return 255; + } + return (uint8) x; +} + +#define f2f(x) (int) (((x) * 4096 + 0.5)) +#define fsh(x) ((x) << 12) + +// derived from jidctint -- DCT_ISLOW +#define IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * f2f(0.5411961f); \ + t2 = p1 + p3*f2f(-1.847759065f); \ + t3 = p1 + p2*f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = fsh(p2+p3); \ + t1 = fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*f2f( 1.175875602f); \ + t0 = t0*f2f( 0.298631336f); \ + t1 = t1*f2f( 2.053119869f); \ + t2 = t2*f2f( 3.072711026f); \ + t3 = t3*f2f( 1.501321110f); \ + p1 = p5 + p1*f2f(-0.899976223f); \ + p2 = p5 + p2*f2f(-2.562915447f); \ + p3 = p3*f2f(-1.961570560f); \ + p4 = p4*f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +#ifdef STBI_SIMD +typedef unsigned short stbi_dequantize_t; +#else +typedef uint8 stbi_dequantize_t; +#endif + +// .344 seconds on 3*anemones.jpg +static void idct_block(uint8 *out, int out_stride, short data[64], stbi_dequantize_t *dequantize) +{ + int i,val[64],*v=val; + stbi_dequantize_t *dq = dequantize; + uint8 *o; + short *d = data; + + // columns + for (i=0; i < 8; ++i,++d,++dq, ++v) { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 + && d[40]==0 && d[48]==0 && d[56]==0) { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0] * dq[0] << 2; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } else { + IDCT_1D(d[ 0]*dq[ 0],d[ 8]*dq[ 8],d[16]*dq[16],d[24]*dq[24], + d[32]*dq[32],d[40]*dq[40],d[48]*dq[48],d[56]*dq[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; x1 += 512; x2 += 512; x3 += 512; + v[ 0] = (x0+t3) >> 10; + v[56] = (x0-t3) >> 10; + v[ 8] = (x1+t2) >> 10; + v[48] = (x1-t2) >> 10; + v[16] = (x2+t1) >> 10; + v[40] = (x2-t1) >> 10; + v[24] = (x3+t0) >> 10; + v[32] = (x3-t0) >> 10; + } + } + + for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { + // no fast case since the first 1D IDCT spread components out + IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128<<17); + x1 += 65536 + (128<<17); + x2 += 65536 + (128<<17); + x3 += 65536 + (128<<17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = clamp((x0+t3) >> 17); + o[7] = clamp((x0-t3) >> 17); + o[1] = clamp((x1+t2) >> 17); + o[6] = clamp((x1-t2) >> 17); + o[2] = clamp((x2+t1) >> 17); + o[5] = clamp((x2-t1) >> 17); + o[3] = clamp((x3+t0) >> 17); + o[4] = clamp((x3-t0) >> 17); + } +} + +#ifdef STBI_SIMD +static stbi_idct_8x8 stbi_idct_installed = idct_block; + +extern void stbi_install_idct(stbi_idct_8x8 func) +{ + stbi_idct_installed = func; +} +#endif + +#define MARKER_none 0xff +// if there's a pending marker from the entropy stream, return that +// otherwise, fetch from the stream and get a marker. if there's no +// marker, return 0xff, which is never a valid marker value +static uint8 get_marker(jpeg *j) +{ + uint8 x; + if (j->marker != MARKER_none) { x = j->marker; j->marker = MARKER_none; return x; } + x = get8u(&j->s); + if (x != 0xff) return MARKER_none; + while (x == 0xff) + x = get8u(&j->s); + return x; +} + +// in each scan, we'll have scan_n components, and the order +// of the components is specified by order[] +#define RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// after a restart interval, reset the entropy decoder and +// the dc prediction +static void reset(jpeg *j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; + j->marker = MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels +} + +static int parse_entropy_coded_data(jpeg *z) +{ + reset(z); + if (z->scan_n == 1) { + int i,j; + #ifdef STBI_SIMD + __declspec(align(16)) + #endif + short data[64]; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0; + #ifdef STBI_SIMD + stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); + #else + idct_block(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); + #endif + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!RESTART(z->marker)) return 1; + reset(z); + } + } + } + } else { // interleaved! + int i,j,k,x,y; + short data[64]; + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x)*8; + int y2 = (j*z->img_comp[n].v + y)*8; + if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0; + #ifdef STBI_SIMD + stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); + #else + idct_block(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); + #endif + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!RESTART(z->marker)) return 1; + reset(z); + } + } + } + } + return 1; +} + +static int process_marker(jpeg *z, int m) +{ + int L; + switch (m) { + case MARKER_none: // no marker found + return e("expected marker","Corrupt JPEG"); + + case 0xC2: // SOF - progressive + return e("progressive jpeg","JPEG format not supported (progressive)"); + + case 0xDD: // DRI - specify restart interval + if (get16(&z->s) != 4) return e("bad DRI len","Corrupt JPEG"); + z->restart_interval = get16(&z->s); + return 1; + + case 0xDB: // DQT - define quantization table + L = get16(&z->s)-2; + while (L > 0) { + int q = get8(&z->s); + int p = q >> 4; + int t = q & 15,i; + if (p != 0) return e("bad DQT type","Corrupt JPEG"); + if (t > 3) return e("bad DQT table","Corrupt JPEG"); + for (i=0; i < 64; ++i) + z->dequant[t][dezigzag[i]] = get8u(&z->s); + #ifdef STBI_SIMD + for (i=0; i < 64; ++i) + z->dequant2[t][i] = z->dequant[t][i]; + #endif + L -= 65; + } + return L==0; + + case 0xC4: // DHT - define huffman table + L = get16(&z->s)-2; + while (L > 0) { + uint8 *v; + int sizes[16],i,m=0; + int q = get8(&z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) return e("bad DHT header","Corrupt JPEG"); + for (i=0; i < 16; ++i) { + sizes[i] = get8(&z->s); + m += sizes[i]; + } + L -= 17; + if (tc == 0) { + if (!build_huffman(z->huff_dc+th, sizes)) return 0; + v = z->huff_dc[th].values; + } else { + if (!build_huffman(z->huff_ac+th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for (i=0; i < m; ++i) + v[i] = get8u(&z->s); + L -= m; + } + return L==0; + } + // check for comment block or APP blocks + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + skip(&z->s, get16(&z->s)-2); + return 1; + } + return 0; +} + +// after we see SOS +static int process_scan_header(jpeg *z) +{ + int i; + int Ls = get16(&z->s); + z->scan_n = get8(&z->s); + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s.img_n) return e("bad SOS component count","Corrupt JPEG"); + if (Ls != 6+2*z->scan_n) return e("bad SOS len","Corrupt JPEG"); + for (i=0; i < z->scan_n; ++i) { + int id = get8(&z->s), which; + int q = get8(&z->s); + for (which = 0; which < z->s.img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s.img_n) return 0; + z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return e("bad DC huff","Corrupt JPEG"); + z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return e("bad AC huff","Corrupt JPEG"); + z->order[i] = which; + } + if (get8(&z->s) != 0) return e("bad SOS","Corrupt JPEG"); + get8(&z->s); // should be 63, but might be 0 + if (get8(&z->s) != 0) return e("bad SOS","Corrupt JPEG"); + + return 1; +} + +static int process_frame_header(jpeg *z, int scan) +{ + stbi *s = &z->s; + int Lf,p,i,q, h_max=1,v_max=1,c; + Lf = get16(s); if (Lf < 11) return e("bad SOF len","Corrupt JPEG"); // JPEG + p = get8(s); if (p != 8) return e("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = get16(s); if (s->img_y == 0) return e("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = get16(s); if (s->img_x == 0) return e("0 width","Corrupt JPEG"); // JPEG requires + c = get8(s); + if (c != 3 && c != 1) return e("bad component count","Corrupt JPEG"); // JFIF requires + s->img_n = c; + for (i=0; i < c; ++i) { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if (Lf != 8+3*s->img_n) return e("bad SOF len","Corrupt JPEG"); + + for (i=0; i < s->img_n; ++i) { + z->img_comp[i].id = get8(s); + if (z->img_comp[i].id != i+1) // JFIF requires + if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files! + return e("bad component ID","Corrupt JPEG"); + q = get8(s); + z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return e("bad H","Corrupt JPEG"); + z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return e("bad V","Corrupt JPEG"); + z->img_comp[i].tq = get8(s); if (z->img_comp[i].tq > 3) return e("bad TQ","Corrupt JPEG"); + } + + if (scan != SCAN_load) return 1; + + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); + + for (i=0; i < s->img_n; ++i) { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + + for (i=0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].raw_data = malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); + if (z->img_comp[i].raw_data == NULL) { + for(--i; i >= 0; --i) { + free(z->img_comp[i].raw_data); + z->img_comp[i].data = NULL; + } + return e("outofmem", "Out of memory"); + } + // align blocks for installable-idct using mmx/sse + z->img_comp[i].data = (uint8*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); + z->img_comp[i].linebuf = NULL; + } + + return 1; +} + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define DNL(x) ((x) == 0xdc) +#define SOI(x) ((x) == 0xd8) +#define EOI(x) ((x) == 0xd9) +#define SOF(x) ((x) == 0xc0 || (x) == 0xc1) +#define SOS(x) ((x) == 0xda) + +static int decode_jpeg_header(jpeg *z, int scan) +{ + int m; + z->marker = MARKER_none; // initialize cached marker to empty + m = get_marker(z); + if (!SOI(m)) return e("no SOI","Corrupt JPEG"); + if (scan == SCAN_type) return 1; + m = get_marker(z); + while (!SOF(m)) { + if (!process_marker(z,m)) return 0; + m = get_marker(z); + while (m == MARKER_none) { + // some files have extra padding after their blocks, so ok, we'll scan + if (at_eof(&z->s)) return e("no SOF", "Corrupt JPEG"); + m = get_marker(z); + } + } + if (!process_frame_header(z, scan)) return 0; + return 1; +} + +static int decode_jpeg_image(jpeg *j) +{ + int m; + j->restart_interval = 0; + if (!decode_jpeg_header(j, SCAN_load)) return 0; + m = get_marker(j); + while (!EOI(m)) { + if (SOS(m)) { + if (!process_scan_header(j)) return 0; + if (!parse_entropy_coded_data(j)) return 0; + if (j->marker == MARKER_none ) { + // handle 0s at the end of image data from IP Kamera 9060 + while (!at_eof(&j->s)) { + int x = get8(&j->s); + if (x == 255) { + j->marker = get8u(&j->s); + break; + } else if (x != 0) { + return 0; + } + } + // if we reach eof without hitting a marker, get_marker() below will fail and we'll eventually return 0 + } + } else { + if (!process_marker(j, m)) return 0; + } + m = get_marker(j); + } + return 1; +} + +// static jfif-centered resampling (across block boundaries) + +typedef uint8 *(*resample_row_func)(uint8 *out, uint8 *in0, uint8 *in1, + int w, int hs); + +#define div4(x) ((uint8) ((x) >> 2)) + +static uint8 *resample_row_1(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; +} + +static uint8* resample_row_v_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for (i=0; i < w; ++i) + out[i] = div4(3*in_near[i] + in_far[i] + 2); + return out; +} + +static uint8* resample_row_h_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + // need to generate two samples horizontally for every one in input + int i; + uint8 *input = in_near; + + if (w == 1) { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = div4(input[0]*3 + input[1] + 2); + for (i=1; i < w-1; ++i) { + int n = 3*input[i]+2; + out[i*2+0] = div4(n+input[i-1]); + out[i*2+1] = div4(n+input[i+1]); + } + out[i*2+0] = div4(input[w-2]*3 + input[w-1] + 2); + out[i*2+1] = input[w-1]; + + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); + + return out; +} + +#define div16(x) ((uint8) ((x) >> 4)) + +static uint8 *resample_row_hv_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i,t0,t1; + if (w == 1) { + out[0] = out[1] = div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + out[0] = div4(t1+2); + for (i=1; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = div16(3*t0 + t1 + 8); + out[i*2 ] = div16(3*t1 + t0 + 8); + } + out[w*2-1] = div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} + +static uint8 *resample_row_generic(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +{ + // resample with nearest-neighbor + int i,j; + in_far = in_far; + for (i=0; i < w; ++i) + for (j=0; j < hs; ++j) + out[i*hs+j] = in_near[i]; + return out; +} + +#define float2fixed(x) ((int) ((x) * 65536 + 0.5)) + +// 0.38 seconds on 3*anemones.jpg (0.25 with processor = Pro) +// VC6 without processor=Pro is generating multiple LEAs per multiply! +static void YCbCr_to_RGB_row(uint8 *out, const uint8 *y, const uint8 *pcb, const uint8 *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 16) + 32768; // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr*float2fixed(1.40200f); + g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f); + b = y_fixed + cb*float2fixed(1.77200f); + r >>= 16; + g >>= 16; + b >>= 16; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (uint8)r; + out[1] = (uint8)g; + out[2] = (uint8)b; + out[3] = 255; + out += step; + } +} + +#ifdef STBI_SIMD +static stbi_YCbCr_to_RGB_run stbi_YCbCr_installed = YCbCr_to_RGB_row; + +void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func) +{ + stbi_YCbCr_installed = func; +} +#endif + + +// clean up the temporary component buffers +static void cleanup_jpeg(jpeg *j) +{ + int i; + for (i=0; i < j->s.img_n; ++i) { + if (j->img_comp[i].data) { + free(j->img_comp[i].raw_data); + j->img_comp[i].data = NULL; + } + if (j->img_comp[i].linebuf) { + free(j->img_comp[i].linebuf); + j->img_comp[i].linebuf = NULL; + } + } +} + +typedef struct +{ + resample_row_func resample; + uint8 *line0,*line1; + int hs,vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on +} stbi_resample; + +static uint8 *load_jpeg_image(jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) +{ + int n, decode_n; + // validate req_comp + if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); + z->s.img_n = 0; + + // load a jpeg image from whichever source + if (!decode_jpeg_image(z)) { cleanup_jpeg(z); return NULL; } + + // determine actual number of components to generate + n = req_comp ? req_comp : z->s.img_n; + + if (z->s.img_n == 3 && n < 3) + decode_n = 1; + else + decode_n = z->s.img_n; + + // resample and color-convert + { + int k; + uint i,j; + uint8 *output; + uint8 *coutput[4]; + + stbi_resample res_comp[4]; + + for (k=0; k < decode_n; ++k) { + stbi_resample *r = &res_comp[k]; + + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (uint8 *) malloc(z->s.img_x + 3); + if (!z->img_comp[k].linebuf) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s.img_x + r->hs-1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + + if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) r->resample = resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) r->resample = resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) r->resample = resample_row_hv_2; + else r->resample = resample_row_generic; + } + + // can't error after this so, this is safe + output = (uint8 *) malloc(n * z->s.img_x * z->s.img_y + 1); + if (!output) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); } + + // now go ahead and resample + for (j=0; j < z->s.img_y; ++j) { + uint8 *out = output + n * z->s.img_x * j; + for (k=0; k < decode_n; ++k) { + stbi_resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if (++r->ystep >= r->vs) { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if (n >= 3) { + uint8 *y = coutput[0]; + if (z->s.img_n == 3) { + #ifdef STBI_SIMD + stbi_YCbCr_installed(out, y, coutput[1], coutput[2], z->s.img_x, n); + #else + YCbCr_to_RGB_row(out, y, coutput[1], coutput[2], z->s.img_x, n); + #endif + } else + for (i=0; i < z->s.img_x; ++i) { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } else { + uint8 *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s.img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s.img_x; ++i) *out++ = y[i], *out++ = 255; + } + } + cleanup_jpeg(z); + *out_x = z->s.img_x; + *out_y = z->s.img_y; + if (comp) *comp = z->s.img_n; // report original components, not output + return output; + } +} + +#ifndef STBI_NO_STDIO +unsigned char *stbi_jpeg_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + jpeg j; + start_file(&j.s, f); + return load_jpeg_image(&j, x,y,comp,req_comp); +} + +unsigned char *stbi_jpeg_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + FILE *f = fopen(filename, "rb"); + if (!f) return NULL; + data = stbi_jpeg_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return data; +} +#endif + +unsigned char *stbi_jpeg_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + #ifdef STBI_SMALL_STACK + unsigned char *result; + jpeg *j = (jpeg *) malloc(sizeof(*j)); + start_mem(&j->s, buffer, len); + result = load_jpeg_image(j,x,y,comp,req_comp); + free(j); + return result; + #else + jpeg j; + start_mem(&j.s, buffer,len); + return load_jpeg_image(&j, x,y,comp,req_comp); + #endif +} + +static int stbi_jpeg_info_raw(jpeg *j, int *x, int *y, int *comp) +{ + if (!decode_jpeg_header(j, SCAN_header)) + return 0; + if (x) *x = j->s.img_x; + if (y) *y = j->s.img_y; + if (comp) *comp = j->s.img_n; + return 1; +} + +#ifndef STBI_NO_STDIO +int stbi_jpeg_test_file(FILE *f) +{ + int n,r; + jpeg j; + n = ftell(f); + start_file(&j.s, f); + r = decode_jpeg_header(&j, SCAN_type); + fseek(f,n,SEEK_SET); + return r; +} + +int stbi_jpeg_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + jpeg j; + long n = ftell(f); + int res; + start_file(&j.s, f); + res = stbi_jpeg_info_raw(&j, x, y, comp); + fseek(f, n, SEEK_SET); + return res; +} + +int stbi_jpeg_info(char const *filename, int *x, int *y, int *comp) +{ + FILE *f = fopen(filename, "rb"); + int result; + if (!f) return e("can't fopen", "Unable to open file"); + result = stbi_jpeg_info_from_file(f, x, y, comp); + fclose(f); + return result; +} +#endif + +int stbi_jpeg_test_memory(stbi_uc const *buffer, int len) +{ + jpeg j; + start_mem(&j.s, buffer,len); + return decode_jpeg_header(&j, SCAN_type); +} + +int stbi_jpeg_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + jpeg j; + start_mem(&j.s, buffer, len); + return stbi_jpeg_info_raw(&j, x, y, comp); +} + +#ifndef STBI_NO_STDIO +extern int stbi_jpeg_info (char const *filename, int *x, int *y, int *comp); +extern int stbi_jpeg_info_from_file (FILE *f, int *x, int *y, int *comp); +#endif +extern int stbi_jpeg_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); + +// public domain zlib decode v0.2 Sean Barrett 2006-11-18 +// simple implementation +// - all input must be provided in an upfront buffer +// - all output is written to a single output buffer (can malloc/realloc) +// performance +// - fast huffman + +// fast-way is faster to check than jpeg huffman, but slow way is slower +#define ZFAST_BITS 9 // accelerate all cases in default tables +#define ZFAST_MASK ((1 << ZFAST_BITS) - 1) + +// zlib-style huffman encoding +// (jpegs packs from left, zlib from right, so can't share code) +typedef struct +{ + uint16 fast[1 << ZFAST_BITS]; + uint16 firstcode[16]; + int maxcode[17]; + uint16 firstsymbol[16]; + uint8 size[288]; + uint16 value[288]; +} zhuffman; + +__forceinline static int bitreverse16(int n) +{ + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; +} + +__forceinline static int bit_reverse(int v, int bits) +{ + assert(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return bitreverse16(v) >> (16-bits); +} + +static int zbuild_huffman(zhuffman *z, uint8 *sizelist, int num) +{ + int i,k=0; + int code, next_code[16], sizes[17]; + + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 255, sizeof(z->fast)); + for (i=0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for (i=1; i < 16; ++i) + assert(sizes[i] <= (1 << i)); + code = 0; + for (i=1; i < 16; ++i) { + next_code[i] = code; + z->firstcode[i] = (uint16) code; + z->firstsymbol[i] = (uint16) k; + code = (code + sizes[i]); + if (sizes[i]) + if (code-1 >= (1 << i)) return e("bad codelengths","Corrupt JPEG"); + z->maxcode[i] = code << (16-i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for (i=0; i < num; ++i) { + int s = sizelist[i]; + if (s) { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + z->size[c] = (uint8)s; + z->value[c] = (uint16)i; + if (s <= ZFAST_BITS) { + int k = bit_reverse(next_code[s],s); + while (k < (1 << ZFAST_BITS)) { + z->fast[k] = (uint16) c; + k += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; +} + +// zlib-from-memory implementation for PNG reading +// because PNG allows splitting the zlib stream arbitrarily, +// and it's annoying structurally to have PNG call ZLIB call PNG, +// we require PNG read all the IDATs and combine them into a single +// memory buffer + +typedef struct +{ + uint8 *zbuffer, *zbuffer_end; + int num_bits; + uint32 code_buffer; + + char *zout; + char *zout_start; + char *zout_end; + int z_expandable; + + zhuffman z_length, z_distance; +} zbuf; + +__forceinline static int zget8(zbuf *z) +{ + if (z->zbuffer >= z->zbuffer_end) return 0; + return *z->zbuffer++; +} + +static void fill_bits(zbuf *z) +{ + do { + assert(z->code_buffer < (1U << z->num_bits)); + z->code_buffer |= zget8(z) << z->num_bits; + z->num_bits += 8; + } while (z->num_bits <= 24); +} + +__forceinline static unsigned int zreceive(zbuf *z, int n) +{ + unsigned int k; + if (z->num_bits < n) fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; +} + +__forceinline static int zhuffman_decode(zbuf *a, zhuffman *z) +{ + int b,s,k; + if (a->num_bits < 16) fill_bits(a); + b = z->fast[a->code_buffer & ZFAST_MASK]; + if (b < 0xffff) { + s = z->size[b]; + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; + } + + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = bit_reverse(a->code_buffer, 16); + for (s=ZFAST_BITS+1; ; ++s) + if (k < z->maxcode[s]) + break; + if (s == 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; + assert(z->size[b] == s); + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; +} + +static int expand(zbuf *z, int n) // need to make room for n bytes +{ + char *q; + int cur, limit; + if (!z->z_expandable) return e("output buffer limit","Corrupt PNG"); + cur = (int) (z->zout - z->zout_start); + limit = (int) (z->zout_end - z->zout_start); + while (cur + n > limit) + limit *= 2; + q = (char *) realloc(z->zout_start, limit); + if (q == NULL) return e("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; +} + +static int length_base[31] = { + 3,4,5,6,7,8,9,10,11,13, + 15,17,19,23,27,31,35,43,51,59, + 67,83,99,115,131,163,195,227,258,0,0 }; + +static int length_extra[31]= +{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + +static int dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, +257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + +static int dist_extra[32] = +{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +static int parse_huffman_block(zbuf *a) +{ + for(;;) { + int z = zhuffman_decode(a, &a->z_length); + if (z < 256) { + if (z < 0) return e("bad huffman code","Corrupt PNG"); // error in huffman codes + if (a->zout >= a->zout_end) if (!expand(a, 1)) return 0; + *a->zout++ = (char) z; + } else { + uint8 *p; + int len,dist; + if (z == 256) return 1; + z -= 257; + len = length_base[z]; + if (length_extra[z]) len += zreceive(a, length_extra[z]); + z = zhuffman_decode(a, &a->z_distance); + if (z < 0) return e("bad huffman code","Corrupt PNG"); + dist = dist_base[z]; + if (dist_extra[z]) dist += zreceive(a, dist_extra[z]); + if (a->zout - a->zout_start < dist) return e("bad dist","Corrupt PNG"); + if (a->zout + len > a->zout_end) if (!expand(a, len)) return 0; + p = (uint8 *) (a->zout - dist); + while (len--) + *a->zout++ = *p++; + } + } +} + +static int compute_huffman_codes(zbuf *a) +{ + static uint8 length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + zhuffman z_codelength; + uint8 lencodes[286+32+137];//padding for maximum single op + uint8 codelength_sizes[19]; + int i,n; + + int hlit = zreceive(a,5) + 257; + int hdist = zreceive(a,5) + 1; + int hclen = zreceive(a,4) + 4; + + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for (i=0; i < hclen; ++i) { + int s = zreceive(a,3); + codelength_sizes[length_dezigzag[i]] = (uint8) s; + } + if (!zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + + n = 0; + while (n < hlit + hdist) { + int c = zhuffman_decode(a, &z_codelength); + assert(c >= 0 && c < 19); + if (c < 16) + lencodes[n++] = (uint8) c; + else if (c == 16) { + c = zreceive(a,2)+3; + memset(lencodes+n, lencodes[n-1], c); + n += c; + } else if (c == 17) { + c = zreceive(a,3)+3; + memset(lencodes+n, 0, c); + n += c; + } else { + assert(c == 18); + c = zreceive(a,7)+11; + memset(lencodes+n, 0, c); + n += c; + } + } + if (n != hlit+hdist) return e("bad codelengths","Corrupt PNG"); + if (!zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if (!zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; + return 1; +} + +static int parse_uncompressed_block(zbuf *a) +{ + uint8 header[4]; + int len,nlen,k; + if (a->num_bits & 7) + zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while (a->num_bits > 0) { + header[k++] = (uint8) (a->code_buffer & 255); // wtf this warns? + a->code_buffer >>= 8; + a->num_bits -= 8; + } + assert(a->num_bits == 0); + // now fill header the normal way + while (k < 4) + header[k++] = (uint8) zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if (nlen != (len ^ 0xffff)) return e("zlib corrupt","Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) return e("read past buffer","Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!expand(a, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; +} + +static int parse_zlib_header(zbuf *a) +{ + int cmf = zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = zget8(a); + if ((cmf*256+flg) % 31 != 0) return e("bad zlib header","Corrupt PNG"); // zlib spec + if (flg & 32) return e("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) return e("bad compression","Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; +} + +// @TODO: should statically initialize these for optimal thread safety +static uint8 default_length[288], default_distance[32]; +static void init_defaults(void) +{ + int i; // use <= to match clearly with spec + for (i=0; i <= 143; ++i) default_length[i] = 8; + for ( ; i <= 255; ++i) default_length[i] = 9; + for ( ; i <= 279; ++i) default_length[i] = 7; + for ( ; i <= 287; ++i) default_length[i] = 8; + + for (i=0; i <= 31; ++i) default_distance[i] = 5; +} + +int stbi_png_partial; // a quick hack to only allow decoding some of a PNG... I should implement real streaming support instead +static int parse_zlib(zbuf *a, int parse_header) +{ + int final, type; + if (parse_header) + if (!parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + do { + final = zreceive(a,1); + type = zreceive(a,2); + if (type == 0) { + if (!parse_uncompressed_block(a)) return 0; + } else if (type == 3) { + return 0; + } else { + if (type == 1) { + // use fixed code lengths + if (!default_distance[31]) init_defaults(); + if (!zbuild_huffman(&a->z_length , default_length , 288)) return 0; + if (!zbuild_huffman(&a->z_distance, default_distance, 32)) return 0; + } else { + if (!compute_huffman_codes(a)) return 0; + } + if (!parse_huffman_block(a)) return 0; + } + if (stbi_png_partial && a->zout - a->zout_start > 65536) + break; + } while (!final); + return 1; +} + +static int do_zlib(zbuf *a, char *obuf, int olen, int exp, int parse_header) +{ + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; + + return parse_zlib(a, parse_header); +} + +char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) +{ + zbuf a; + char *p = (char *) malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (uint8 *) buffer; + a.zbuffer_end = (uint8 *) buffer + len; + if (do_zlib(&a, p, initial_size, 1, 1)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + free(a.zout_start); + return NULL; + } +} + +char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) +{ + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); +} + +char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) +{ + zbuf a; + char *p = (char *) malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (uint8 *) buffer; + a.zbuffer_end = (uint8 *) buffer + len; + if (do_zlib(&a, p, initial_size, 1, parse_header)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + free(a.zout_start); + return NULL; + } +} + +int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) +{ + zbuf a; + a.zbuffer = (uint8 *) ibuffer; + a.zbuffer_end = (uint8 *) ibuffer + ilen; + if (do_zlib(&a, obuffer, olen, 0, 1)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) +{ + zbuf a; + char *p = (char *) malloc(16384); + if (p == NULL) return NULL; + a.zbuffer = (uint8 *) buffer; + a.zbuffer_end = (uint8 *) buffer+len; + if (do_zlib(&a, p, 16384, 1, 0)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + free(a.zout_start); + return NULL; + } +} + +int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) +{ + zbuf a; + a.zbuffer = (uint8 *) ibuffer; + a.zbuffer_end = (uint8 *) ibuffer + ilen; + if (do_zlib(&a, obuffer, olen, 0, 0)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 +// simple implementation +// - only 8-bit samples +// - no CRC checking +// - allocates lots of intermediate memory +// - avoids problem of streaming data between subsystems +// - avoids explicit window management +// performance +// - uses stb_zlib, a PD zlib implementation with fast huffman decoding + + +typedef struct +{ + uint32 length; + uint32 type; +} chunk; + +#define PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) + +static chunk get_chunk_header(stbi *s) +{ + chunk c; + c.length = get32(s); + c.type = get32(s); + return c; +} + +static int check_png_header(stbi *s) +{ + static uint8 png_sig[8] = { 137,80,78,71,13,10,26,10 }; + int i; + for (i=0; i < 8; ++i) + if (get8(s) != png_sig[i]) return e("bad png sig","Not a PNG"); + return 1; +} + +typedef struct +{ + stbi s; + uint8 *idata, *expanded, *out; +} png; + + +enum { + F_none=0, F_sub=1, F_up=2, F_avg=3, F_paeth=4, + F_avg_first, F_paeth_first +}; + +static uint8 first_row_filter[5] = +{ + F_none, F_sub, F_none, F_avg_first, F_paeth_first +}; + +static int paeth(int a, int b, int c) +{ + int p = a + b - c; + int pa = abs(p-a); + int pb = abs(p-b); + int pc = abs(p-c); + if (pa <= pb && pa <= pc) return a; + if (pb <= pc) return b; + return c; +} + +// create the png data from post-deflated data +static int create_png_image_raw(png *a, uint8 *raw, uint32 raw_len, int out_n, uint32 x, uint32 y) +{ + stbi *s = &a->s; + uint32 i,j,stride = x*out_n; + int k; + int img_n = s->img_n; // copy it into a local for later + assert(out_n == s->img_n || out_n == s->img_n+1); + if (stbi_png_partial) y = 1; + a->out = (uint8 *) malloc(x * y * out_n); + if (!a->out) return e("outofmem", "Out of memory"); + if (!stbi_png_partial) { + if (s->img_x == x && s->img_y == y) { + if (raw_len != (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); + } else { // interlaced: + if (raw_len < (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); + } + } + for (j=0; j < y; ++j) { + uint8 *cur = a->out + stride*j; + uint8 *prior = cur - stride; + int filter = *raw++; + if (filter > 4) return e("invalid filter","Corrupt PNG"); + // if first row, use special filter that doesn't sample previous row + if (j == 0) filter = first_row_filter[filter]; + // handle first pixel explicitly + for (k=0; k < img_n; ++k) { + switch (filter) { + case F_none : cur[k] = raw[k]; break; + case F_sub : cur[k] = raw[k]; break; + case F_up : cur[k] = raw[k] + prior[k]; break; + case F_avg : cur[k] = raw[k] + (prior[k]>>1); break; + case F_paeth : cur[k] = (uint8) (raw[k] + paeth(0,prior[k],0)); break; + case F_avg_first : cur[k] = raw[k]; break; + case F_paeth_first: cur[k] = raw[k]; break; + } + } + if (img_n != out_n) cur[img_n] = 255; + raw += img_n; + cur += out_n; + prior += out_n; + // this is a little gross, so that we don't switch per-pixel or per-component + if (img_n == out_n) { + #define CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \ + for (k=0; k < img_n; ++k) + switch (filter) { + CASE(F_none) cur[k] = raw[k]; break; + CASE(F_sub) cur[k] = raw[k] + cur[k-img_n]; break; + CASE(F_up) cur[k] = raw[k] + prior[k]; break; + CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-img_n])>>1); break; + CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],prior[k],prior[k-img_n])); break; + CASE(F_avg_first) cur[k] = raw[k] + (cur[k-img_n] >> 1); break; + CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],0,0)); break; + } + #undef CASE + } else { + assert(img_n+1 == out_n); + #define CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \ + for (k=0; k < img_n; ++k) + switch (filter) { + CASE(F_none) cur[k] = raw[k]; break; + CASE(F_sub) cur[k] = raw[k] + cur[k-out_n]; break; + CASE(F_up) cur[k] = raw[k] + prior[k]; break; + CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-out_n])>>1); break; + CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],prior[k],prior[k-out_n])); break; + CASE(F_avg_first) cur[k] = raw[k] + (cur[k-out_n] >> 1); break; + CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],0,0)); break; + } + #undef CASE + } + } + return 1; +} + +static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n, int interlaced) +{ + uint8 *final; + int p; + int save; + if (!interlaced) + return create_png_image_raw(a, raw, raw_len, out_n, a->s.img_x, a->s.img_y); + save = stbi_png_partial; + stbi_png_partial = 0; + + // de-interlacing + final = (uint8 *) malloc(a->s.img_x * a->s.img_y * out_n); + for (p=0; p < 7; ++p) { + int xorig[] = { 0,4,0,2,0,1,0 }; + int yorig[] = { 0,0,4,0,2,0,1 }; + int xspc[] = { 8,8,4,4,2,2,1 }; + int yspc[] = { 8,8,8,4,4,2,2 }; + int i,j,x,y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s.img_x - xorig[p] + xspc[p]-1) / xspc[p]; + y = (a->s.img_y - yorig[p] + yspc[p]-1) / yspc[p]; + if (x && y) { + if (!create_png_image_raw(a, raw, raw_len, out_n, x, y)) { + free(final); + return 0; + } + for (j=0; j < y; ++j) + for (i=0; i < x; ++i) + memcpy(final + (j*yspc[p]+yorig[p])*a->s.img_x*out_n + (i*xspc[p]+xorig[p])*out_n, + a->out + (j*x+i)*out_n, out_n); + free(a->out); + raw += (x*out_n+1)*y; + raw_len -= (x*out_n+1)*y; + } + } + a->out = final; + + stbi_png_partial = save; + return 1; +} + +static int compute_transparency(png *z, uint8 tc[3], int out_n) +{ + stbi *s = &z->s; + uint32 i, pixel_count = s->img_x * s->img_y; + uint8 *p = z->out; + + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + assert(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i=0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } else { + for (i=0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int expand_palette(png *a, uint8 *palette, int len, int pal_img_n) +{ + uint32 i, pixel_count = a->s.img_x * a->s.img_y; + uint8 *p, *temp_out, *orig = a->out; + + p = (uint8 *) malloc(pixel_count * pal_img_n); + if (p == NULL) return e("outofmem", "Out of memory"); + + // between here and free(out) below, exitting would leak + temp_out = p; + + if (pal_img_n == 3) { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p += 3; + } + } else { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p[3] = palette[n+3]; + p += 4; + } + } + free(a->out); + a->out = temp_out; + + STBI_NOTUSED(len); + + return 1; +} + +static int stbi_unpremultiply_on_load = 0; +static int stbi_de_iphone_flag = 0; + +void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) +{ + stbi_unpremultiply_on_load = flag_true_if_should_unpremultiply; +} +void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) +{ + stbi_de_iphone_flag = flag_true_if_should_convert; +} + +static void stbi_de_iphone(png *z) +{ + stbi *s = &z->s; + uint32 i, pixel_count = s->img_x * s->img_y; + uint8 *p = z->out; + + if (s->img_out_n == 3) { // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + uint8 t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } else { + assert(s->img_out_n == 4); + if (stbi_unpremultiply_on_load) { + // convert bgr to rgb and unpremultiply + for (i=0; i < pixel_count; ++i) { + uint8 a = p[3]; + uint8 t = p[0]; + if (a) { + p[0] = p[2] * 255 / a; + p[1] = p[1] * 255 / a; + p[2] = t * 255 / a; + } else { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } else { + // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + uint8 t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } +} + +static int parse_png_file(png *z, int scan, int req_comp) +{ + uint8 palette[1024], pal_img_n=0; + uint8 has_trans=0, tc[3]; + uint32 ioff=0, idata_limit=0, i, pal_len=0; + int first=1,k,interlace=0, iphone=0; + stbi *s = &z->s; + + if (!check_png_header(s)) return 0; + + if (scan == SCAN_type) return 1; + + for (;;) { + chunk c = get_chunk_header(s); + switch (c.type) { + case PNG_TYPE('C','g','B','I'): + iphone = stbi_de_iphone_flag; + skip(s, c.length); + break; + case PNG_TYPE('I','H','D','R'): { + int depth,color,comp,filter; + if (!first) return e("multiple IHDR","Corrupt PNG"); + first = 0; + if (c.length != 13) return e("bad IHDR len","Corrupt PNG"); + s->img_x = get32(s); if (s->img_x > (1 << 24)) return e("too large","Very large image (corrupt?)"); + s->img_y = get32(s); if (s->img_y > (1 << 24)) return e("too large","Very large image (corrupt?)"); + depth = get8(s); if (depth != 8) return e("8bit only","PNG not supported: 8-bit only"); + color = get8(s); if (color > 6) return e("bad ctype","Corrupt PNG"); + if (color == 3) pal_img_n = 3; else if (color & 1) return e("bad ctype","Corrupt PNG"); + comp = get8(s); if (comp) return e("bad comp method","Corrupt PNG"); + filter= get8(s); if (filter) return e("bad filter method","Corrupt PNG"); + interlace = get8(s); if (interlace>1) return e("bad interlace method","Corrupt PNG"); + if (!s->img_x || !s->img_y) return e("0-pixel image","Corrupt PNG"); + if (!pal_img_n) { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); + if (scan == SCAN_header) return 1; + } else { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) return e("too large","Corrupt PNG"); + // if SCAN_header, have to scan to see if we have a tRNS + } + break; + } + + case PNG_TYPE('P','L','T','E'): { + if (first) return e("first not IHDR", "Corrupt PNG"); + if (c.length > 256*3) return e("invalid PLTE","Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) return e("invalid PLTE","Corrupt PNG"); + for (i=0; i < pal_len; ++i) { + palette[i*4+0] = get8u(s); + palette[i*4+1] = get8u(s); + palette[i*4+2] = get8u(s); + palette[i*4+3] = 255; + } + break; + } + + case PNG_TYPE('t','R','N','S'): { + if (first) return e("first not IHDR", "Corrupt PNG"); + if (z->idata) return e("tRNS after IDAT","Corrupt PNG"); + if (pal_img_n) { + if (scan == SCAN_header) { s->img_n = 4; return 1; } + if (pal_len == 0) return e("tRNS before PLTE","Corrupt PNG"); + if (c.length > pal_len) return e("bad tRNS len","Corrupt PNG"); + pal_img_n = 4; + for (i=0; i < c.length; ++i) + palette[i*4+3] = get8u(s); + } else { + if (!(s->img_n & 1)) return e("tRNS with alpha","Corrupt PNG"); + if (c.length != (uint32) s->img_n*2) return e("bad tRNS len","Corrupt PNG"); + has_trans = 1; + for (k=0; k < s->img_n; ++k) + tc[k] = (uint8) get16(s); // non 8-bit images will be larger + } + break; + } + + case PNG_TYPE('I','D','A','T'): { + if (first) return e("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) return e("no PLTE","Corrupt PNG"); + if (scan == SCAN_header) { s->img_n = pal_img_n; return 1; } + if (ioff + c.length > idata_limit) { + uint8 *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + p = (uint8 *) realloc(z->idata, idata_limit); if (p == NULL) return e("outofmem", "Out of memory"); + z->idata = p; + } + if (!getn(s, z->idata+ioff,c.length)) return e("outofdata","Corrupt PNG"); + ioff += c.length; + break; + } + + case PNG_TYPE('I','E','N','D'): { + uint32 raw_len; + if (first) return e("first not IHDR", "Corrupt PNG"); + if (scan != SCAN_load) return 1; + if (z->idata == NULL) return e("no IDAT","Corrupt PNG"); + z->expanded = (uint8 *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, 16384, (int *) &raw_len, !iphone); + if (z->expanded == NULL) return 0; // zlib should set error + free(z->idata); z->idata = NULL; + if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n+1; + else + s->img_out_n = s->img_n; + if (!create_png_image(z, z->expanded, raw_len, s->img_out_n, interlace)) return 0; + if (has_trans) + if (!compute_transparency(z, tc, s->img_out_n)) return 0; + if (iphone && s->img_out_n > 2) + stbi_de_iphone(z); + if (pal_img_n) { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) s->img_out_n = req_comp; + if (!expand_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } + free(z->expanded); z->expanded = NULL; + return 1; + } + + default: + // if critical, fail + if (first) return e("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) { + #ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX chunk not known"; + invalid_chunk[0] = (uint8) (c.type >> 24); + invalid_chunk[1] = (uint8) (c.type >> 16); + invalid_chunk[2] = (uint8) (c.type >> 8); + invalid_chunk[3] = (uint8) (c.type >> 0); + #endif + return e(invalid_chunk, "PNG not supported: unknown chunk type"); + } + skip(s, c.length); + break; + } + // end of chunk, read and skip CRC + get32(s); + } +} + +static unsigned char *do_png(png *p, int *x, int *y, int *n, int req_comp) +{ + unsigned char *result=NULL; + p->expanded = NULL; + p->idata = NULL; + p->out = NULL; + if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); + if (parse_png_file(p, SCAN_load, req_comp)) { + result = p->out; + p->out = NULL; + if (req_comp && req_comp != p->s.img_out_n) { + result = convert_format(result, p->s.img_out_n, req_comp, p->s.img_x, p->s.img_y); + p->s.img_out_n = req_comp; + if (result == NULL) return result; + } + *x = p->s.img_x; + *y = p->s.img_y; + if (n) *n = p->s.img_n; + } + free(p->out); p->out = NULL; + free(p->expanded); p->expanded = NULL; + free(p->idata); p->idata = NULL; + + return result; +} + +#ifndef STBI_NO_STDIO +unsigned char *stbi_png_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + png p; + start_file(&p.s, f); + return do_png(&p, x,y,comp,req_comp); +} + +unsigned char *stbi_png_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + FILE *f = fopen(filename, "rb"); + if (!f) return NULL; + data = stbi_png_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return data; +} +#endif + +unsigned char *stbi_png_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + png p; + start_mem(&p.s, buffer,len); + return do_png(&p, x,y,comp,req_comp); +} + +#ifndef STBI_NO_STDIO +int stbi_png_test_file(FILE *f) +{ + png p; + int n,r; + n = ftell(f); + start_file(&p.s, f); + r = parse_png_file(&p, SCAN_type,STBI_default); + fseek(f,n,SEEK_SET); + return r; +} +#endif + +int stbi_png_test_memory(stbi_uc const *buffer, int len) +{ + png p; + start_mem(&p.s, buffer, len); + return parse_png_file(&p, SCAN_type,STBI_default); +} + +static int stbi_png_info_raw(png *p, int *x, int *y, int *comp) +{ + if (!parse_png_file(p, SCAN_header, 0)) + return 0; + if (x) *x = p->s.img_x; + if (y) *y = p->s.img_y; + if (comp) *comp = p->s.img_n; + return 1; +} + +#ifndef STBI_NO_STDIO +int stbi_png_info (char const *filename, int *x, int *y, int *comp) +{ + int res; + FILE *f = fopen(filename, "rb"); + if (!f) return 0; + res = stbi_png_info_from_file(f, x, y, comp); + fclose(f); + return res; +} + +int stbi_png_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + png p; + int res; + long n = ftell(f); + start_file(&p.s, f); + res = stbi_png_info_raw(&p, x, y, comp); + fseek(f, n, SEEK_SET); + return res; +} +#endif // !STBI_NO_STDIO + +int stbi_png_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + png p; + start_mem(&p.s, buffer, len); + return stbi_png_info_raw(&p, x, y, comp); +} + +// Microsoft/Windows BMP image + +static int bmp_test(stbi *s) +{ + int sz; + if (get8(s) != 'B') return 0; + if (get8(s) != 'M') return 0; + get32le(s); // discard filesize + get16le(s); // discard reserved + get16le(s); // discard reserved + get32le(s); // discard data offset + sz = get32le(s); + if (sz == 12 || sz == 40 || sz == 56 || sz == 108) return 1; + return 0; +} + +#ifndef STBI_NO_STDIO +int stbi_bmp_test_file (FILE *f) +{ + stbi s; + int r,n = ftell(f); + start_file(&s,f); + r = bmp_test(&s); + fseek(f,n,SEEK_SET); + return r; +} +#endif + +int stbi_bmp_test_memory (stbi_uc const *buffer, int len) +{ + stbi s; + start_mem(&s, buffer, len); + return bmp_test(&s); +} + +// returns 0..31 for the highest set bit +static int high_bit(unsigned int z) +{ + int n=0; + if (z == 0) return -1; + if (z >= 0x10000) n += 16, z >>= 16; + if (z >= 0x00100) n += 8, z >>= 8; + if (z >= 0x00010) n += 4, z >>= 4; + if (z >= 0x00004) n += 2, z >>= 2; + if (z >= 0x00002) n += 1, z >>= 1; + return n; +} + +static int bitcount(unsigned int a) +{ + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; +} + +static int shiftsigned(int v, int shift, int bits) +{ + int result; + int z=0; + + if (shift < 0) v <<= -shift; + else v >>= shift; + result = v; + + z = bits; + while (z < 8) { + result += v >> z; + z += bits; + } + return result; +} + +static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + uint8 *out; + unsigned int mr=0,mg=0,mb=0,ma=0, fake_a=0; + stbi_uc pal[256][4]; + int psize=0,i,j,compress=0,width; + int bpp, flip_vertically, pad, target, offset, hsz; + if (get8(s) != 'B' || get8(s) != 'M') return epuc("not BMP", "Corrupt BMP"); + get32le(s); // discard filesize + get16le(s); // discard reserved + get16le(s); // discard reserved + offset = get32le(s); + hsz = get32le(s); + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) return epuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) { + s->img_x = get16le(s); + s->img_y = get16le(s); + } else { + s->img_x = get32le(s); + s->img_y = get32le(s); + } + if (get16le(s) != 1) return epuc("bad BMP", "bad BMP"); + bpp = get16le(s); + if (bpp == 1) return epuc("monochrome", "BMP type not supported: 1-bit"); + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + if (hsz == 12) { + if (bpp < 24) + psize = (offset - 14 - 24) / 3; + } else { + compress = get32le(s); + if (compress == 1 || compress == 2) return epuc("BMP RLE", "BMP type not supported: RLE"); + get32le(s); // discard sizeof + get32le(s); // discard hres + get32le(s); // discard vres + get32le(s); // discard colorsused + get32le(s); // discard max important + if (hsz == 40 || hsz == 56) { + if (hsz == 56) { + get32le(s); + get32le(s); + get32le(s); + get32le(s); + } + if (bpp == 16 || bpp == 32) { + mr = mg = mb = 0; + if (compress == 0) { + if (bpp == 32) { + mr = 0xffu << 16; + mg = 0xffu << 8; + mb = 0xffu << 0; + ma = 0xffu << 24; + fake_a = 1; // @TODO: check for cases like alpha value is all 0 and switch it to 255 + } else { + mr = 31u << 10; + mg = 31u << 5; + mb = 31u << 0; + } + } else if (compress == 3) { + mr = get32le(s); + mg = get32le(s); + mb = get32le(s); + // not documented, but generated by photoshop and handled by mspaint + if (mr == mg && mg == mb) { + // ?!?!? + return epuc("bad BMP", "bad BMP"); + } + } else + return epuc("bad BMP", "bad BMP"); + } + } else { + assert(hsz == 108); + mr = get32le(s); + mg = get32le(s); + mb = get32le(s); + ma = get32le(s); + get32le(s); // discard color space + for (i=0; i < 12; ++i) + get32le(s); // discard color space parameters + } + if (bpp < 16) + psize = (offset - 14 - hsz) >> 2; + } + s->img_n = ma ? 4 : 3; + if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + out = (stbi_uc *) malloc(target * s->img_x * s->img_y); + if (!out) return epuc("outofmem", "Out of memory"); + if (bpp < 16) { + int z=0; + if (psize == 0 || psize > 256) { free(out); return epuc("invalid", "Corrupt BMP"); } + for (i=0; i < psize; ++i) { + pal[i][2] = get8u(s); + pal[i][1] = get8u(s); + pal[i][0] = get8u(s); + if (hsz != 12) get8(s); + pal[i][3] = 255; + } + skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4)); + if (bpp == 4) width = (s->img_x + 1) >> 1; + else if (bpp == 8) width = s->img_x; + else { free(out); return epuc("bad bpp", "Corrupt BMP"); } + pad = (-width)&3; + for (j=0; j < (int) s->img_y; ++j) { + for (i=0; i < (int) s->img_x; i += 2) { + int v=get8(s),v2=0; + if (bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + v = (bpp == 8) ? get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + skip(s, pad); + } + } else { + int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; + int z = 0; + int easy=0; + skip(s, offset - 14 - hsz); + if (bpp == 24) width = 3 * s->img_x; + else if (bpp == 16) width = 2*s->img_x; + else /* bpp = 32 and pad = 0 */ width=0; + pad = (-width) & 3; + if (bpp == 24) { + easy = 1; + } else if (bpp == 32) { + if (mb == 0xff && mg == 0xff00 && mr == 0xff000000 && ma == 0xff000000) + easy = 2; + } + if (!easy) { + if (!mr || !mg || !mb) return epuc("bad masks", "Corrupt BMP"); + // right shift amt to put high bit in position #7 + rshift = high_bit(mr)-7; rcount = bitcount(mr); + gshift = high_bit(mg)-7; gcount = bitcount(mr); + bshift = high_bit(mb)-7; bcount = bitcount(mr); + ashift = high_bit(ma)-7; acount = bitcount(mr); + } + for (j=0; j < (int) s->img_y; ++j) { + if (easy) { + for (i=0; i < (int) s->img_x; ++i) { + int a; + out[z+2] = get8u(s); + out[z+1] = get8u(s); + out[z+0] = get8u(s); + z += 3; + a = (easy == 2 ? get8(s) : 255); + if (target == 4) out[z++] = (uint8) a; + } + } else { + for (i=0; i < (int) s->img_x; ++i) { + uint32 v = (bpp == 16 ? get16le(s) : get32le(s)); + int a; + out[z++] = (uint8) shiftsigned(v & mr, rshift, rcount); + out[z++] = (uint8) shiftsigned(v & mg, gshift, gcount); + out[z++] = (uint8) shiftsigned(v & mb, bshift, bcount); + a = (ma ? shiftsigned(v & ma, ashift, acount) : 255); + if (target == 4) out[z++] = (uint8) a; + } + } + skip(s, pad); + } + } + if (flip_vertically) { + stbi_uc t; + for (j=0; j < (int) s->img_y>>1; ++j) { + stbi_uc *p1 = out + j *s->img_x*target; + stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; + for (i=0; i < (int) s->img_x*target; ++i) { + t = p1[i], p1[i] = p2[i], p2[i] = t; + } + } + } + + if (req_comp && req_comp != target) { + out = convert_format(out, target, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // convert_format frees input on failure + } + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = target; + return out; +} + +#ifndef STBI_NO_STDIO +stbi_uc *stbi_bmp_load (char const *filename, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *data; + FILE *f = fopen(filename, "rb"); + if (!f) return NULL; + data = stbi_bmp_load_from_file(f, x,y,comp,req_comp); + fclose(f); + return data; +} + +stbi_uc *stbi_bmp_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_file(&s, f); + return bmp_load(&s, x,y,comp,req_comp); +} +#endif + +stbi_uc *stbi_bmp_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_mem(&s, buffer, len); + return bmp_load(&s, x,y,comp,req_comp); +} + +// Targa Truevision - TGA +// by Jonathan Dummer + +static int tga_info(stbi *s, int *x, int *y, int *comp) +{ + int tga_w, tga_h, tga_comp; + int sz; + get8u(s); // discard Offset + sz = get8u(s); // color type + if( sz > 1 ) return 0; // only RGB or indexed allowed + sz = get8u(s); // image type + // only RGB or grey allowed, +/- RLE + if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0; + get16le(s); // discard palette start + get16le(s); // discard palette length + get8(s); // discard bits per palette color entry + get16le(s); // discard x origin + get16le(s); // discard y origin + tga_w = get16le(s); + if( tga_w < 1 ) return 0; // test width + tga_h = get16le(s); + if( tga_h < 1 ) return 0; // test height + sz = get8(s); // bits per pixel + // only RGB or RGBA or grey allowed + if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) return 0; + tga_comp = sz; + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp / 8; + return 1; // seems to have passed everything +} + +#ifndef STBI_NO_STDIO +int stbi_tga_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + stbi s; + int r; + long n = ftell(f); + start_file(&s, f); + r = tga_info(&s, x, y, comp); + fseek(f, n, SEEK_SET); + return r; +} +#endif + +int stbi_tga_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + stbi s; + start_mem(&s, buffer, len); + return tga_info(&s, x, y, comp); +} + +static int tga_test(stbi *s) +{ + int sz; + get8u(s); // discard Offset + sz = get8u(s); // color type + if ( sz > 1 ) return 0; // only RGB or indexed allowed + sz = get8u(s); // image type + if ( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE + get16(s); // discard palette start + get16(s); // discard palette length + get8(s); // discard bits per palette color entry + get16(s); // discard x origin + get16(s); // discard y origin + if ( get16(s) < 1 ) return 0; // test width + if ( get16(s) < 1 ) return 0; // test height + sz = get8(s); // bits per pixel + if ( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) ) return 0; // only RGB or RGBA or grey allowed + return 1; // seems to have passed everything +} + +#ifndef STBI_NO_STDIO +int stbi_tga_test_file (FILE *f) +{ + stbi s; + int r,n = ftell(f); + start_file(&s, f); + r = tga_test(&s); + fseek(f,n,SEEK_SET); + return r; +} +#endif + +int stbi_tga_test_memory (stbi_uc const *buffer, int len) +{ + stbi s; + start_mem(&s, buffer, len); + return tga_test(&s); +} + +static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + // read in the TGA header stuff + int tga_offset = get8u(s); + int tga_indexed = get8u(s); + int tga_image_type = get8u(s); + int tga_is_RLE = 0; + int tga_palette_start = get16le(s); + int tga_palette_len = get16le(s); + int tga_palette_bits = get8u(s); + int tga_x_origin = get16le(s); + int tga_y_origin = get16le(s); + int tga_width = get16le(s); + int tga_height = get16le(s); + int tga_bits_per_pixel = get8u(s); + int tga_inverted = get8u(s); + // image data + unsigned char *tga_data; + unsigned char *tga_palette = NULL; + int i, j; + unsigned char raw_data[4]; + unsigned char trans_data[4]; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; + + // do a tiny bit of precessing + if ( tga_image_type >= 8 ) + { + tga_image_type -= 8; + tga_is_RLE = 1; + } + /* int tga_alpha_bits = tga_inverted & 15; */ + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // error check + if ( //(tga_indexed) || + (tga_width < 1) || (tga_height < 1) || + (tga_image_type < 1) || (tga_image_type > 3) || + ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) && + (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32)) + ) + { + return NULL; + } + + // If I'm paletted, then I'll use the number of bits from the palette + if ( tga_indexed ) + { + tga_bits_per_pixel = tga_palette_bits; + } + + // tga info + *x = tga_width; + *y = tga_height; + if ( (req_comp < 1) || (req_comp > 4) ) + { + // just use whatever the file was + req_comp = tga_bits_per_pixel / 8; + *comp = req_comp; + } else + { + // force a new number of components + *comp = tga_bits_per_pixel/8; + } + tga_data = (unsigned char*)malloc( tga_width * tga_height * req_comp ); + + // skip to the data's starting position (offset usually = 0) + skip(s, tga_offset ); + // do I need to load a palette? + if ( tga_indexed ) + { + // any data to skip? (offset usually = 0) + skip(s, tga_palette_start ); + // load the palette + tga_palette = (unsigned char*)malloc( tga_palette_len * tga_palette_bits / 8 ); + if (!getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 )) + return NULL; + } + // load the data + trans_data[0] = trans_data[1] = trans_data[2] = trans_data[3] = 0; + for (i=0; i < tga_width * tga_height; ++i) + { + // if I'm in RLE mode, do I need to get a RLE chunk? + if ( tga_is_RLE ) + { + if ( RLE_count == 0 ) + { + // yep, get the next byte as a RLE command + int RLE_cmd = get8u(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } else if ( !RLE_repeating ) + { + read_next_pixel = 1; + } + } else + { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if ( read_next_pixel ) + { + // load however much data we did have + if ( tga_indexed ) + { + // read in 1 byte, then perform the lookup + int pal_idx = get8u(s); + if ( pal_idx >= tga_palette_len ) + { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_bits_per_pixel / 8; + for (j = 0; j*8 < tga_bits_per_pixel; ++j) + { + raw_data[j] = tga_palette[pal_idx+j]; + } + } else + { + // read in the data raw + for (j = 0; j*8 < tga_bits_per_pixel; ++j) + { + raw_data[j] = get8u(s); + } + } + // convert raw to the intermediate format + switch (tga_bits_per_pixel) + { + case 8: + // Luminous => RGBA + trans_data[0] = raw_data[0]; + trans_data[1] = raw_data[0]; + trans_data[2] = raw_data[0]; + trans_data[3] = 255; + break; + case 16: + // Luminous,Alpha => RGBA + trans_data[0] = raw_data[0]; + trans_data[1] = raw_data[0]; + trans_data[2] = raw_data[0]; + trans_data[3] = raw_data[1]; + break; + case 24: + // BGR => RGBA + trans_data[0] = raw_data[2]; + trans_data[1] = raw_data[1]; + trans_data[2] = raw_data[0]; + trans_data[3] = 255; + break; + case 32: + // BGRA => RGBA + trans_data[0] = raw_data[2]; + trans_data[1] = raw_data[1]; + trans_data[2] = raw_data[0]; + trans_data[3] = raw_data[3]; + break; + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + // convert to final format + switch (req_comp) + { + case 1: + // RGBA => Luminance + tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]); + break; + case 2: + // RGBA => Luminance,Alpha + tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]); + tga_data[i*req_comp+1] = trans_data[3]; + break; + case 3: + // RGBA => RGB + tga_data[i*req_comp+0] = trans_data[0]; + tga_data[i*req_comp+1] = trans_data[1]; + tga_data[i*req_comp+2] = trans_data[2]; + break; + case 4: + // RGBA => RGBA + tga_data[i*req_comp+0] = trans_data[0]; + tga_data[i*req_comp+1] = trans_data[1]; + tga_data[i*req_comp+2] = trans_data[2]; + tga_data[i*req_comp+3] = trans_data[3]; + break; + } + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if ( tga_inverted ) + { + for (j = 0; j*2 < tga_height; ++j) + { + int index1 = j * tga_width * req_comp; + int index2 = (tga_height - 1 - j) * tga_width * req_comp; + for (i = tga_width * req_comp; i > 0; --i) + { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if ( tga_palette != NULL ) + { + free( tga_palette ); + } + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + // OK, done + return tga_data; +} + +#ifndef STBI_NO_STDIO +stbi_uc *stbi_tga_load (char const *filename, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *data; + FILE *f = fopen(filename, "rb"); + if (!f) return NULL; + data = stbi_tga_load_from_file(f, x,y,comp,req_comp); + fclose(f); + return data; +} + +stbi_uc *stbi_tga_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_file(&s, f); + return tga_load(&s, x,y,comp,req_comp); +} +#endif + +stbi_uc *stbi_tga_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_mem(&s, buffer, len); + return tga_load(&s, x,y,comp,req_comp); +} + + +// ************************************************************************************************* +// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB + +static int psd_test(stbi *s) +{ + if (get32(s) != 0x38425053) return 0; // "8BPS" + else return 1; +} + +#ifndef STBI_NO_STDIO +int stbi_psd_test_file(FILE *f) +{ + stbi s; + int r,n = ftell(f); + start_file(&s, f); + r = psd_test(&s); + fseek(f,n,SEEK_SET); + return r; +} +#endif + +int stbi_psd_test_memory(stbi_uc const *buffer, int len) +{ + stbi s; + start_mem(&s, buffer, len); + return psd_test(&s); +} + +static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + int pixelCount; + int channelCount, compression; + int channel, i, count, len; + int w,h; + uint8 *out; + + // Check identifier + if (get32(s) != 0x38425053) // "8BPS" + return epuc("not PSD", "Corrupt PSD image"); + + // Check file type version. + if (get16(s) != 1) + return epuc("wrong version", "Unsupported version of PSD image"); + + // Skip 6 reserved bytes. + skip(s, 6 ); + + // Read the number of channels (R, G, B, A, etc). + channelCount = get16(s); + if (channelCount < 0 || channelCount > 16) + return epuc("wrong channel count", "Unsupported number of channels in PSD image"); + + // Read the rows and columns of the image. + h = get32(s); + w = get32(s); + + // Make sure the depth is 8 bits. + if (get16(s) != 8) + return epuc("unsupported bit depth", "PSD bit depth is not 8 bit"); + + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if (get16(s) != 3) + return epuc("wrong color format", "PSD is not in RGB color format"); + + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + skip(s,get32(s) ); + + // Skip the image resources. (resolution, pen tool paths, etc) + skip(s, get32(s) ); + + // Skip the reserved data. + skip(s, get32(s) ); + + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = get16(s); + if (compression > 1) + return epuc("bad compression", "PSD has an unknown compression format"); + + // Create the destination image. + out = (stbi_uc *) malloc(4 * w*h); + if (!out) return epuc("outofmem", "Out of memory"); + pixelCount = w*h; + + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); + + // Finally, the image data. + if (compression) { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop + + // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, + // which we're going to just skip. + skip(s, h * channelCount * 2 ); + + // Read the RLE data by channel. + for (channel = 0; channel < 4; channel++) { + uint8 *p; + + p = out+channel; + if (channel >= channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++) *p = (channel == 3 ? 255 : 0), p += 4; + } else { + // Read the RLE data. + count = 0; + while (count < pixelCount) { + len = get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + count += len; + while (len) { + *p = get8u(s); + p += 4; + len--; + } + } else if (len > 128) { + uint8 val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len ^= 0x0FF; + len += 2; + val = get8u(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + } + } + + } else { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit value for each pixel in the image. + + // Read the data by channel. + for (channel = 0; channel < 4; channel++) { + uint8 *p; + + p = out + channel; + if (channel > channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++) *p = channel == 3 ? 255 : 0, p += 4; + } else { + // Read the data. + for (i = 0; i < pixelCount; i++) + *p = get8u(s), p += 4; + } + } + } + + if (req_comp && req_comp != 4) { + out = convert_format(out, 4, req_comp, w, h); + if (out == NULL) return out; // convert_format frees input on failure + } + + if (comp) *comp = channelCount; + *y = h; + *x = w; + + return out; +} + +#ifndef STBI_NO_STDIO +stbi_uc *stbi_psd_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *data; + FILE *f = fopen(filename, "rb"); + if (!f) return NULL; + data = stbi_psd_load_from_file(f, x,y,comp,req_comp); + fclose(f); + return data; +} + +stbi_uc *stbi_psd_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_file(&s, f); + return psd_load(&s, x,y,comp,req_comp); +} +#endif + +stbi_uc *stbi_psd_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_mem(&s, buffer, len); + return psd_load(&s, x,y,comp,req_comp); +} + +// ************************************************************************************************* +// Softimage PIC loader +// by Tom Seddon +// +// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format +// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ + +static int pic_is4(stbi *s,const char *str) +{ + int i; + for (i=0; i<4; ++i) + if (get8(s) != (stbi_uc)str[i]) + return 0; + + return 1; +} + +static int pic_test(stbi *s) +{ + int i; + + if (!pic_is4(s,"\x53\x80\xF6\x34")) + return 0; + + for(i=0;i<84;++i) + get8(s); + + if (!pic_is4(s,"PICT")) + return 0; + + return 1; +} + +typedef struct +{ + stbi_uc size,type,channel; +} pic_packet_t; + +static stbi_uc *pic_readval(stbi *s, int channel, stbi_uc *dest) +{ + int mask=0x80, i; + + for (i=0; i<4; ++i, mask>>=1) { + if (channel & mask) { + if (at_eof(s)) return epuc("bad file","PIC file too short"); + dest[i]=get8u(s); + } + } + + return dest; +} + +static void pic_copyval(int channel,stbi_uc *dest,const stbi_uc *src) +{ + int mask=0x80,i; + + for (i=0;i<4; ++i, mask>>=1) + if (channel&mask) + dest[i]=src[i]; +} + +static stbi_uc *pic_load2(stbi *s,int width,int height,int *comp, stbi_uc *result) +{ + int act_comp=0,num_packets=0,y,chained; + pic_packet_t packets[10]; + + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do { + pic_packet_t *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return epuc("bad format","too many packets"); + + packet = &packets[num_packets++]; + + chained = get8(s); + packet->size = get8u(s); + packet->type = get8u(s); + packet->channel = get8u(s); + + act_comp |= packet->channel; + + if (at_eof(s)) return epuc("bad file","file too short (reading packets)"); + if (packet->size != 8) return epuc("bad format","packet isn't 8bpp"); + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + + for(y=0; y<height; ++y) { + int packet_idx; + + for(packet_idx=0; packet_idx < num_packets; ++packet_idx) { + pic_packet_t *packet = &packets[packet_idx]; + stbi_uc *dest = result+y*width*4; + + switch (packet->type) { + default: + return epuc("bad format","packet has bad compression type"); + + case 0: {//uncompressed + int x; + + for(x=0;x<width;++x, dest+=4) + if (!pic_readval(s,packet->channel,dest)) + return 0; + break; + } + + case 1://Pure RLE + { + int left=width, i; + + while (left>0) { + stbi_uc count,value[4]; + + count=get8u(s); + if (at_eof(s)) return epuc("bad file","file too short (pure read count)"); + + if (count > left) + count = (uint8) left; + + if (!pic_readval(s,packet->channel,value)) return 0; + + for(i=0; i<count; ++i,dest+=4) + pic_copyval(packet->channel,dest,value); + left -= count; + } + } + break; + + case 2: {//Mixed RLE + int left=width; + while (left>0) { + int count = get8(s), i; + if (at_eof(s)) return epuc("bad file","file too short (mixed read count)"); + + if (count >= 128) { // Repeated + stbi_uc value[4]; + int i; + + if (count==128) + count = get16(s); + else + count -= 127; + if (count > left) + return epuc("bad file","scanline overrun"); + + if (!pic_readval(s,packet->channel,value)) + return 0; + + for(i=0;i<count;++i, dest += 4) + pic_copyval(packet->channel,dest,value); + } else { // Raw + ++count; + if (count>left) return epuc("bad file","scanline overrun"); + + for(i=0;i<count;++i, dest+=4) + if (!pic_readval(s,packet->channel,dest)) + return 0; + } + left-=count; + } + break; + } + } + } + } + + return result; +} + +static stbi_uc *pic_load(stbi *s,int *px,int *py,int *comp,int req_comp) +{ + stbi_uc *result; + int i, x,y; + + for (i=0; i<92; ++i) + get8(s); + + x = get16(s); + y = get16(s); + if (at_eof(s)) return epuc("bad file","file too short (pic header)"); + if ((1 << 28) / x < y) return epuc("too large", "Image too large to decode"); + + get32(s); //skip `ratio' + get16(s); //skip `fields' + get16(s); //skip `pad' + + // intermediate buffer is RGBA + result = (stbi_uc *) malloc(x*y*4); + memset(result, 0xff, x*y*4); + + if (!pic_load2(s,x,y,comp, result)) { + free(result); + result=0; + } + *px = x; + *py = y; + if (req_comp == 0) req_comp = *comp; + result=convert_format(result,4,req_comp,x,y); + + return result; +} + +int stbi_pic_test_memory(stbi_uc const *buffer, int len) +{ + stbi s; + start_mem(&s,buffer,len); + return pic_test(&s); +} + +stbi_uc *stbi_pic_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_mem(&s,buffer,len); + return pic_load(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_STDIO +int stbi_pic_test_file(FILE *f) +{ + int result; + long l = ftell(f); + stbi s; + start_file(&s,f); + result = pic_test(&s); + fseek(f,l,SEEK_SET); + return result; +} + +stbi_uc *stbi_pic_load(char const *filename,int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *result; + FILE *f=fopen(filename,"rb"); + if (!f) return 0; + result = stbi_pic_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +stbi_uc *stbi_pic_load_from_file(FILE *f,int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_file(&s,f); + return pic_load(&s,x,y,comp,req_comp); +} +#endif + +// ************************************************************************************************* +// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb +typedef struct stbi_gif_lzw_struct { + int16 prefix; + uint8 first; + uint8 suffix; +} stbi_gif_lzw; + +typedef struct stbi_gif_struct +{ + int w,h; + stbi_uc *out; // output buffer (always 4 components) + int flags, bgindex, ratio, transparent, eflags; + uint8 pal[256][4]; + uint8 lpal[256][4]; + stbi_gif_lzw codes[4096]; + uint8 *color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; +} stbi_gif; + +static int gif_test(stbi *s) +{ + int sz; + if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') return 0; + sz = get8(s); + if (sz != '9' && sz != '7') return 0; + if (get8(s) != 'a') return 0; + return 1; +} + +#ifndef STBI_NO_STDIO +int stbi_gif_test_file (FILE *f) +{ + stbi s; + int r,n = ftell(f); + start_file(&s,f); + r = gif_test(&s); + fseek(f,n,SEEK_SET); + return r; +} +#endif + +int stbi_gif_test_memory (stbi_uc const *buffer, int len) +{ + stbi s; + start_mem(&s, buffer, len); + return gif_test(&s); +} + +static void stbi_gif_parse_colortable(stbi *s, uint8 pal[256][4], int num_entries, int transp) +{ + int i; + for (i=0; i < num_entries; ++i) { + pal[i][2] = get8u(s); + pal[i][1] = get8u(s); + pal[i][0] = get8u(s); + pal[i][3] = transp ? 0 : 255; + } +} + +static int stbi_gif_header(stbi *s, stbi_gif *g, int *comp, int is_info) +{ + uint8 version; + if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') + return e("not GIF", "Corrupt GIF"); + + version = get8u(s); + if (version != '7' && version != '9') return e("not GIF", "Corrupt GIF"); + if (get8(s) != 'a') return e("not GIF", "Corrupt GIF"); + + failure_reason = ""; + g->w = get16le(s); + g->h = get16le(s); + g->flags = get8(s); + g->bgindex = get8(s); + g->ratio = get8(s); + g->transparent = -1; + + if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + + if (is_info) return 1; + + if (g->flags & 0x80) + stbi_gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + + return 1; +} + +static int stbi_gif_info_raw(stbi *s, int *x, int *y, int *comp) +{ + stbi_gif g; + if (!stbi_gif_header(s, &g, comp, 1)) return 0; + if (x) *x = g.w; + if (y) *y = g.h; + return 1; +} + +static void stbi_out_gif_code(stbi_gif *g, uint16 code) +{ + uint8 *p, *c; + + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if (g->codes[code].prefix >= 0) + stbi_out_gif_code(g, g->codes[code].prefix); + + if (g->cur_y >= g->max_y) return; + + p = &g->out[g->cur_x + g->cur_y]; + c = &g->color_table[g->codes[code].suffix * 4]; + + if (c[3] >= 128) { + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; + + if (g->cur_x >= g->max_x) { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while (g->cur_y >= g->max_y && g->parse > 0) { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } +} + +static uint8 *stbi_process_gif_raster(stbi *s, stbi_gif *g) +{ + uint8 lzw_cs; + int32 len, code; + uint32 first; + int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi_gif_lzw *p; + + lzw_cs = get8u(s); + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for (code = 0; code < clear; code++) { + g->codes[code].prefix = -1; + g->codes[code].first = (uint8) code; + g->codes[code].suffix = (uint8) code; + } + + // support no starting clear code + avail = clear+2; + oldcode = -1; + + len = 0; + for(;;) { + if (valid_bits < codesize) { + if (len == 0) { + len = get8(s); // start new block + if (len == 0) + return g->out; + } + --len; + bits |= (int32) get8(s) << valid_bits; + valid_bits += 8; + } else { + int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if (code == clear) { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } else if (code == clear + 1) { // end of stream code + skip(s, len); + while ((len = get8(s)) > 0) + skip(s,len); + return g->out; + } else if (code <= avail) { + if (first) return epuc("no clear code", "Corrupt GIF"); + + if (oldcode >= 0) { + p = &g->codes[avail++]; + if (avail > 4096) return epuc("too many codes", "Corrupt GIF"); + p->prefix = (int16) oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } else if (code == avail) + return epuc("illegal code in raster", "Corrupt GIF"); + + stbi_out_gif_code(g, (uint16) code); + + if ((avail & codemask) == 0 && avail <= 0x0FFF) { + codesize++; + codemask = (1 << codesize) - 1; + } + + oldcode = code; + } else { + return epuc("illegal code in raster", "Corrupt GIF"); + } + } + } +} + +static void stbi_fill_gif_background(stbi_gif *g) +{ + int i; + uint8 *c = g->pal[g->bgindex]; + // @OPTIMIZE: write a dword at a time + for (i = 0; i < g->w * g->h * 4; i += 4) { + uint8 *p = &g->out[i]; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } +} + +// this function is designed to support animated gifs, although stb_image doesn't support it +static uint8 *stbi_gif_load_next(stbi *s, stbi_gif *g, int *comp, int req_comp) +{ + int i; + uint8 *old_out = 0; + + if (g->out == 0) { + if (!stbi_gif_header(s, g, comp,0)) return 0; // failure_reason set by stbi_gif_header + g->out = (uint8 *) malloc(4 * g->w * g->h); + if (g->out == 0) return epuc("outofmem", "Out of memory"); + stbi_fill_gif_background(g); + } else { + // animated-gif-only path + if (((g->eflags & 0x1C) >> 2) == 3) { + old_out = g->out; + g->out = (uint8 *) malloc(4 * g->w * g->h); + if (g->out == 0) return epuc("outofmem", "Out of memory"); + memcpy(g->out, old_out, g->w*g->h*4); + } + } + + for (;;) { + switch (get8(s)) { + case 0x2C: /* Image Descriptor */ + { + int32 x, y, w, h; + uint8 *o; + + x = get16le(s); + y = get16le(s); + w = get16le(s); + h = get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return epuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + g->lflags = get8(s); + + if (g->lflags & 0x40) { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } else { + g->step = g->line_size; + g->parse = 0; + } + + if (g->lflags & 0x80) { + stbi_gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (uint8 *) g->lpal; + } else if (g->flags & 0x80) { + for (i=0; i < 256; ++i) // @OPTIMIZE: reset only the previous transparent + g->pal[i][3] = 255; + if (g->transparent >= 0 && (g->eflags & 0x01)) + g->pal[g->transparent][3] = 0; + g->color_table = (uint8 *) g->pal; + } else + return epuc("missing color table", "Corrupt GIF"); + + o = stbi_process_gif_raster(s, g); + if (o == NULL) return NULL; + + if (req_comp && req_comp != 4) + o = convert_format(o, 4, req_comp, g->w, g->h); + return o; + } + + case 0x21: // Comment Extension. + { + int len; + if (get8(s) == 0xF9) { // Graphic Control Extension. + len = get8(s); + if (len == 4) { + g->eflags = get8(s); + get16le(s); // delay + g->transparent = get8(s); + } else { + skip(s, len); + break; + } + } + while ((len = get8(s)) != 0) + skip(s, len); + break; + } + + case 0x3B: // gif stream termination code + return (uint8 *) 1; + + default: + return epuc("unknown code", "Corrupt GIF"); + } + } +} + +#ifndef STBI_NO_STDIO +stbi_uc *stbi_gif_load (char const *filename, int *x, int *y, int *comp, int req_comp) +{ + uint8 *data; + FILE *f = fopen(filename, "rb"); + if (!f) return NULL; + data = stbi_gif_load_from_file(f, x,y,comp,req_comp); + fclose(f); + return data; +} + +stbi_uc *stbi_gif_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp) +{ + uint8 *u = 0; + stbi s; + stbi_gif g={0}; + start_file(&s, f); + + u = stbi_gif_load_next(&s, &g, comp, req_comp); + if (u == (void *) 1) u = 0; // end of animated gif marker + if (u) { + *x = g.w; + *y = g.h; + } + + return u; +} +#endif + +stbi_uc *stbi_gif_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + uint8 *u = 0; + stbi s; + stbi_gif g={0}; + start_mem(&s, buffer, len); + u = stbi_gif_load_next(&s, &g, comp, req_comp); + if (u == (void *) 1) u = 0; // end of animated gif marker + if (u) { + *x = g.w; + *y = g.h; + } + return u; +} + +#ifndef STBI_NO_STDIO +int stbi_gif_info (char const *filename, int *x, int *y, int *comp) +{ + int res; + FILE *f = fopen(filename, "rb"); + if (!f) return 0; + res = stbi_gif_info_from_file(f, x, y, comp); + fclose(f); + return res; +} + +int stbi_gif_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + stbi s; + int res; + long n = ftell(f); + start_file(&s, f); + res = stbi_gif_info_raw(&s, x, y, comp); + fseek(f, n, SEEK_SET); + return res; +} +#endif // !STBI_NO_STDIO + +int stbi_gif_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + stbi s; + start_mem(&s, buffer, len); + return stbi_gif_info_raw(&s, x, y, comp); +} + + + + +// ************************************************************************************************* +// Radiance RGBE HDR loader +// originally by Nicolas Schulz +#ifndef STBI_NO_HDR +static int hdr_test(stbi *s) +{ + const char *signature = "#?RADIANCE\n"; + int i; + for (i=0; signature[i]; ++i) + if (get8(s) != signature[i]) + return 0; + return 1; +} + +int stbi_hdr_test_memory(stbi_uc const *buffer, int len) +{ + stbi s; + start_mem(&s, buffer, len); + return hdr_test(&s); +} + +#ifndef STBI_NO_STDIO +int stbi_hdr_test_file(FILE *f) +{ + stbi s; + int r,n = ftell(f); + start_file(&s, f); + r = hdr_test(&s); + fseek(f,n,SEEK_SET); + return r; +} +#endif + +#define HDR_BUFLEN 1024 +static char *hdr_gettoken(stbi *z, char *buffer) +{ + int len=0; + char c = '\0'; + + c = (char) get8(z); + + while (!at_eof(z) && c != '\n') { + buffer[len++] = c; + if (len == HDR_BUFLEN-1) { + // flush to end of line + while (!at_eof(z) && get8(z) != '\n') + ; + break; + } + c = (char) get8(z); + } + + buffer[len] = 0; + return buffer; +} + +static void hdr_convert(float *output, stbi_uc *input, int req_comp) +{ + if ( input[3] != 0 ) { + float f1; + // Exponent + f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + if (req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if (req_comp == 2) output[1] = 1; + if (req_comp == 4) output[3] = 1; + } else { + switch (req_comp) { + case 4: output[3] = 1; /* fallthrough */ + case 3: output[0] = output[1] = output[2] = 0; + break; + case 2: output[1] = 1; /* fallthrough */ + case 1: output[0] = 0; + break; + } + } +} + + +static float *hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp) +{ + char buffer[HDR_BUFLEN]; + char *token; + int valid = 0; + int width, height; + stbi_uc *scanline; + float *hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1,c2, z; + + + // Check identifier + if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) + return epf("not HDR", "Corrupt HDR image"); + + // Parse header + for(;;) { + token = hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) return epf("unsupported format", "Unsupported HDR format"); + + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) return epf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) return epf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = strtol(token, NULL, 10); + + *x = width; + *y = height; + + *comp = 3; + if (req_comp == 0) req_comp = 3; + + // Read data + hdr_data = (float *) malloc(height * width * req_comp * sizeof(float)); + + // Load image data + // image data is stored as some number of sca + if ( width < 8 || width >= 32768) { + // Read flat data + for (j=0; j < height; ++j) { + for (i=0; i < width; ++i) { + stbi_uc rgbe[4]; + main_decode_loop: + getn(s, rgbe, 4); + hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } else { + // Read RLE-encoded data + scanline = NULL; + + for (j = 0; j < height; ++j) { + c1 = get8(s); + c2 = get8(s); + len = get8(s); + if (c1 != 2 || c2 != 2 || (len & 0x80)) { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + uint8 rgbe[4]; + rgbe[0] = (uint8) c1; + rgbe[1] = (uint8) c2; + rgbe[2] = (uint8) len; + rgbe[3] = (uint8) get8u(s); + hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + free(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= get8(s); + if (len != width) { free(hdr_data); free(scanline); return epf("invalid decoded scanline length", "corrupt HDR"); } + if (scanline == NULL) scanline = (stbi_uc *) malloc(width * 4); + + for (k = 0; k < 4; ++k) { + i = 0; + while (i < width) { + count = get8u(s); + if (count > 128) { + // Run + value = get8u(s); + count -= 128; + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } else { + // Dump + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = get8u(s); + } + } + } + for (i=0; i < width; ++i) + hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); + } + free(scanline); + } + + return hdr_data; +} + +#ifndef STBI_NO_STDIO +float *stbi_hdr_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_file(&s,f); + return hdr_load(&s,x,y,comp,req_comp); +} +#endif + +float *stbi_hdr_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi s; + start_mem(&s,buffer, len); + return hdr_load(&s,x,y,comp,req_comp); +} + +#endif // STBI_NO_HDR + + +#ifndef STBI_NO_STDIO +int stbi_info(char const *filename, int *x, int *y, int *comp) +{ + FILE *f = fopen(filename, "rb"); + int result; + if (!f) return e("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; +} + +int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + if (stbi_jpeg_info_from_file(f, x, y, comp)) + return 1; + if (stbi_png_info_from_file(f, x, y, comp)) + return 1; + if (stbi_gif_info_from_file(f, x, y, comp)) + return 1; + // @TODO: stbi_bmp_info_from_file + // @TODO: stbi_psd_info_from_file + #ifndef STBI_NO_HDR + // @TODO: stbi_hdr_info_from_file + #endif + // test tga last because it's a crappy test! + if (stbi_tga_info_from_file(f, x, y, comp)) + return 1; + return e("unknown image type", "Image not of any known type, or corrupt"); +} +#endif // !STBI_NO_STDIO + +int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + if (stbi_jpeg_info_from_memory(buffer, len, x, y, comp)) + return 1; + if (stbi_png_info_from_memory(buffer, len, x, y, comp)) + return 1; + if (stbi_gif_info_from_memory(buffer, len, x, y, comp)) + return 1; + // @TODO: stbi_bmp_info_from_memory + // @TODO: stbi_psd_info_from_memory + #ifndef STBI_NO_HDR + // @TODO: stbi_hdr_info_from_memory + #endif + // test tga last because it's a crappy test! + if (stbi_tga_info_from_memory(buffer, len, x, y, comp)) + return 1; + return e("unknown image type", "Image not of any known type, or corrupt"); +} + +#endif // STBI_HEADER_FILE_ONLY + +/* + revision history: + 1.29 (2010-08-16) various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) + cast-to-uint8 to fix warnings + 1.26 (2010-07-24) + fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) + refix trans_data warning (Won Chun) + 1.24 (2010-07-12) + perf improvements reading from files on platforms with lock-heavy fgetc() + minor perf improvements for jpeg + deprecated type-specific functions so we'll get feedback if they're needed + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) + removed image *writing* support + removed image *writing* support + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva (i.e. Janez (U+017D)emva) + 1.21 fix use of 'uint8' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + 1.19 bug in interlaced PNG corruption check (found by ryg) + 1.18 2008-08-02 + fix a threading bug (local mutable static) + 1.17 support interlaced PNG + 1.16 major bugfix - convert_format converted one too many pixels + 1.15 initialize some fields for thread safety + 1.14 fix threadsafe conversion bug + header-file-only version (#define STBI_HEADER_FILE_ONLY before including) + 1.13 threadsafe + 1.12 const qualifiers in the API + 1.11 Support installable IDCT, colorspace conversion routines + 1.10 Fixes for 64-bit (don't use "unsigned long") + optimized upsampling by Fabian "ryg" Giesen + 1.09 Fix format-conversion for PSD code (bad global variables!) + 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz + 1.07 attempt to fix C++ warning/errors again + 1.06 attempt to fix C++ warning/errors again + 1.05 fix TGA loading to return correct *comp and use good luminance calc + 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free + 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR + 1.02 support for (subset of) HDR files, float interface for preferred access to them + 1.01 fix bug: possible bug in handling right-side up bmps... not sure + fix bug: the stbi_bmp_load() and stbi_tga_load() functions didn't work at all + 1.00 interface to zlib that skips zlib header + 0.99 correct handling of alpha in palette + 0.98 TGA loader by lonesock; dynamically add loaders (untested) + 0.97 jpeg errors on too large a file; also catch another malloc failure + 0.96 fix detection of invalid v value - particleman@mollyrocket forum + 0.95 during header scan, seek to markers in case of padding + 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same + 0.93 handle jpegtran output; verbose errors + 0.92 read 4,8,16,24,32-bit BMP files of several formats + 0.91 output 24-bit Windows 3.0 BMP files + 0.90 fix a few more warnings; bump version number to approach 1.0 + 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd + 0.60 fix compiling as c++ + 0.59 fix warnings: merge Dave Moore's -Wall fixes + 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian + 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less + than 16 available + 0.56 fix bug: zlib uncompressed mode len vs. nlen + 0.55 fix bug: restart_interval not initialized to 0 + 0.54 allow NULL for 'int *comp' + 0.53 fix bug in png 3->4; speedup png decoding + 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments + 0.51 obey req_comp requests, 1-component jpegs return as 1-component, + on 'test' only check type, not whether we support this variant +*/ diff --git a/src/libs/webrtc/CMakeLists.txt b/src/libs/webrtc/CMakeLists.txt new file mode 100644 index 00000000..01e7f0f1 --- /dev/null +++ b/src/libs/webrtc/CMakeLists.txt @@ -0,0 +1,173 @@ +project (webrtc) + +# Rely on C++ 11 +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +set (WEBRTC_SOURCES + ilbcfix/xcorr_coef.c + ilbcfix/window32_w32.c + ilbcfix/vq4.c + ilbcfix/vq3.c + ilbcfix/unpack_bits.c + ilbcfix/swap_bytes.c + ilbcfix/state_search.c + ilbcfix/state_construct.c + ilbcfix/split_vq.c + ilbcfix/sort_sq.c + ilbcfix/smooth.c + ilbcfix/smooth_out_data.c + ilbcfix/simple_lsf_quant.c + ilbcfix/simple_lsf_dequant.c + ilbcfix/simple_lpc_analysis.c + ilbcfix/simple_interpolate_lsf.c + ilbcfix/refiner.c + ilbcfix/poly_to_lsp.c + ilbcfix/poly_to_lsf.c + ilbcfix/pack_bits.c + ilbcfix/nearest_neighbor.c + ilbcfix/my_corr.c + ilbcfix/lsp_to_lsf.c + ilbcfix/lsf_to_poly.c + ilbcfix/lsf_to_lsp.c + ilbcfix/lsf_interpolate_to_poly_enc.c + ilbcfix/lsf_interpolate_to_poly_dec.c + ilbcfix/lsf_check.c + ilbcfix/lpc_encode.c + ilbcfix/interpolate.c + ilbcfix/interpolate_samples.c + ilbcfix/init_encode.c + ilbcfix/init_decode.c + ilbcfix/index_conv_enc.c + ilbcfix/index_conv_dec.c + ilbcfix/ilbc.c + ilbcfix/ilbc_encode.c + ilbcfix/ilbc_decode.c + ilbcfix/ilbc_constants.c + ilbcfix/ilbc_cb_search.c + ilbcfix/hp_output.c + ilbcfix/hp_input.c + ilbcfix/get_sync_seq.c + ilbcfix/get_lsp_poly.c + ilbcfix/get_cd_vec.c + ilbcfix/gain_quant.c + ilbcfix/gain_dequant.c + ilbcfix/frame_classify.c + ilbcfix/filtered_cb_vecs.c + ilbcfix/enhancer.c + ilbcfix/enhancer_interface.c + ilbcfix/enh_upsample.c + ilbcfix/energy_inverse.c + ilbcfix/do_plc.c + ilbcfix/decoder_interpolate_lsf.c + ilbcfix/decode_residual.c + ilbcfix/create_augmented_vec.c + ilbcfix/comp_corr.c + ilbcfix/chebyshev.c + ilbcfix/cb_update_best_index.c + ilbcfix/cb_search_core.c + ilbcfix/cb_mem_energy.c + ilbcfix/cb_mem_energy_calc.c + ilbcfix/cb_mem_energy_augmentation.c + ilbcfix/cb_construct.c + ilbcfix/bw_expand.c + ilbcfix/augmented_cb_corr.c + ilbcfix/abs_quant.c + ilbcfix/abs_quant_loop.c + cng/webrtc_cng.c + cng/cng_helpfuns.c + aecm/echo_control_mobile.c + aecm/aecm_core.c + aec/resampler.c + aec/echo_cancellation.c + aec/aec_core.c + aec/aec_core_sse2.c + aec/aec_core_rdft.c + vad/webrtc_vad.c + vad/vad_sp.c + vad/vad_gmm.c + vad/vad_filterbank.c + vad/vad_core.c + vad/vad_const.c + isac/transform.c + isac/spectrum_ar_model_tables.c + isac/pitch_lag_tables.c + isac/pitch_gain_tables.c + isac/pitch_filter.c + isac/pitch_estimator.c + isac/lpc_tables.c + isac/lpc_masking_model.c + isac/lattice.c + isac/isacfix.c + isac/isac_filters.c + isac/isac_decode.c + isac/initialize.c + isac/filterbanks.c + isac/filterbank_tables.c + isac/fft.c + isac/entropy_coding.c + isac/encode.c + isac/decode_plc.c + isac/decode_bwe.c + isac/bandwidth_estimator.c + isac/arith_routines.c + isac/arith_routines_logist.c + isac/arith_routines_hist.c + g711/g711.c + g711/g711_interface.c + ns/nsx_core.c + ns/ns_core.c + ns/noise_suppression.c + ns/noise_suppression_x.c + signal_processing_library/energy.c + signal_processing_library/downsample_fast.c + signal_processing_library/dot_product_with_scale.c + signal_processing_library/division_operations.c + signal_processing_library/cross_correlation.c + signal_processing_library/cos_table.c + signal_processing_library/copy_set_operations.c + signal_processing_library/complex_ifft.c + signal_processing_library/complex_fft.c + signal_processing_library/complex_bit_reverse.c + signal_processing_library/auto_correlation.c + signal_processing_library/auto_corr_to_refl_coef.c + signal_processing_library/add_sat_w32.c + signal_processing_library/add_sat_w16.c + signal_processing_library/webrtc_fft_t_rad.c + signal_processing_library/webrtc_fft_t_1024_8.c + signal_processing_library/vector_scaling_operations.c + signal_processing_library/sub_sat_w32.c + signal_processing_library/sub_sat_w16.c + signal_processing_library/sqrt_of_one_minus_x_squared.c + signal_processing_library/splitting_filter.c + signal_processing_library/spl_version.c + signal_processing_library/spl_sqrt.c + signal_processing_library/sin_table.c + signal_processing_library/sin_table_1024.c + signal_processing_library/resample.c + signal_processing_library/resample_fractional.c + signal_processing_library/resample_by_2.c + signal_processing_library/resample_by_2_internal.c + signal_processing_library/resample_48khz.c + signal_processing_library/refl_coef_to_lpc.c + signal_processing_library/randomization_functions.c + signal_processing_library/randn_table.c + signal_processing_library/norm_w32.c + signal_processing_library/norm_w16.c + signal_processing_library/norm_u32.c + signal_processing_library/min_max_operations.c + signal_processing_library/lpc_to_refl_coef.c + signal_processing_library/levinson_durbin.c + signal_processing_library/ilbc_specific_functions.c + signal_processing_library/hanning_table.c + signal_processing_library/get_size_in_bits.c + signal_processing_library/get_scaling_square.c + signal_processing_library/get_hanning_window.c + signal_processing_library/filter_ma_fast_q12.c + signal_processing_library/filter_ar.c + signal_processing_library/filter_ar_fast_q12.c + utility/ring_buffer.c + utility/fft4g.c +) + +add_library(webrtc ${WEBRTC_SOURCES}) diff --git a/src/libs/webrtc/aec/aec_core.c b/src/libs/webrtc/aec/aec_core.c new file mode 100644 index 00000000..b62c2077 --- /dev/null +++ b/src/libs/webrtc/aec/aec_core.c @@ -0,0 +1,1460 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * The core AEC algorithm, which is presented with time-aligned signals. + */ + +#include <math.h> +#include <stdlib.h> +#include <string.h> + +#include "aec_core.h" +#include "ring_buffer.h" +#include "system_wrappers/cpu_features_wrapper.h" + +// Noise suppression +static const int converged = 250; + +// Metrics +static const int subCountLen = 4; +static const int countLen = 50; + +// Quantities to control H band scaling for SWB input +static const int flagHbandCn = 1; // flag for adding comfort noise in H band +static const float cnScaleHband = (float)0.4; // scale for comfort noise in H band +// Initial bin for averaging nlp gain in low band +static const int freqAvgIc = PART_LEN / 2; + +/* Matlab code to produce table: +win = sqrt(hanning(63)); win = [0 ; win(1:32)]; +fprintf(1, '\t%.14f, %.14f, %.14f,\n', win); +*/ +/* +static const float sqrtHanning[33] = { + 0.00000000000000, 0.04906767432742, 0.09801714032956, + 0.14673047445536, 0.19509032201613, 0.24298017990326, + 0.29028467725446, 0.33688985339222, 0.38268343236509, + 0.42755509343028, 0.47139673682600, 0.51410274419322, + 0.55557023301960, 0.59569930449243, 0.63439328416365, + 0.67155895484702, 0.70710678118655, 0.74095112535496, + 0.77301045336274, 0.80320753148064, 0.83146961230255, + 0.85772861000027, 0.88192126434835, 0.90398929312344, + 0.92387953251129, 0.94154406518302, 0.95694033573221, + 0.97003125319454, 0.98078528040323, 0.98917650996478, + 0.99518472667220, 0.99879545620517, 1.00000000000000 +}; +*/ + +static const float sqrtHanning[65] = { + 0.00000000000000f, 0.02454122852291f, 0.04906767432742f, + 0.07356456359967f, 0.09801714032956f, 0.12241067519922f, + 0.14673047445536f, 0.17096188876030f, 0.19509032201613f, + 0.21910124015687f, 0.24298017990326f, 0.26671275747490f, + 0.29028467725446f, 0.31368174039889f, 0.33688985339222f, + 0.35989503653499f, 0.38268343236509f, 0.40524131400499f, + 0.42755509343028f, 0.44961132965461f, 0.47139673682600f, + 0.49289819222978f, 0.51410274419322f, 0.53499761988710f, + 0.55557023301960f, 0.57580819141785f, 0.59569930449243f, + 0.61523159058063f, 0.63439328416365f, 0.65317284295378f, + 0.67155895484702f, 0.68954054473707f, 0.70710678118655f, + 0.72424708295147f, 0.74095112535496f, 0.75720884650648f, + 0.77301045336274f, 0.78834642762661f, 0.80320753148064f, + 0.81758481315158f, 0.83146961230255f, 0.84485356524971f, + 0.85772861000027f, 0.87008699110871f, 0.88192126434835f, + 0.89322430119552f, 0.90398929312344f, 0.91420975570353f, + 0.92387953251129f, 0.93299279883474f, 0.94154406518302f, + 0.94952818059304f, 0.95694033573221f, 0.96377606579544f, + 0.97003125319454f, 0.97570213003853f, 0.98078528040323f, + 0.98527764238894f, 0.98917650996478f, 0.99247953459871f, + 0.99518472667220f, 0.99729045667869f, 0.99879545620517f, + 0.99969881869620f, 1.00000000000000f +}; + +/* Matlab code to produce table: +weightCurve = [0 ; 0.3 * sqrt(linspace(0,1,64))' + 0.1]; +fprintf(1, '\t%.4f, %.4f, %.4f, %.4f, %.4f, %.4f,\n', weightCurve); +*/ +const float WebRtcAec_weightCurve[65] = { + 0.0000f, 0.1000f, 0.1378f, 0.1535f, 0.1655f, 0.1756f, + 0.1845f, 0.1926f, 0.2000f, 0.2069f, 0.2134f, 0.2195f, + 0.2254f, 0.2309f, 0.2363f, 0.2414f, 0.2464f, 0.2512f, + 0.2558f, 0.2604f, 0.2648f, 0.2690f, 0.2732f, 0.2773f, + 0.2813f, 0.2852f, 0.2890f, 0.2927f, 0.2964f, 0.3000f, + 0.3035f, 0.3070f, 0.3104f, 0.3138f, 0.3171f, 0.3204f, + 0.3236f, 0.3268f, 0.3299f, 0.3330f, 0.3360f, 0.3390f, + 0.3420f, 0.3449f, 0.3478f, 0.3507f, 0.3535f, 0.3563f, + 0.3591f, 0.3619f, 0.3646f, 0.3673f, 0.3699f, 0.3726f, + 0.3752f, 0.3777f, 0.3803f, 0.3828f, 0.3854f, 0.3878f, + 0.3903f, 0.3928f, 0.3952f, 0.3976f, 0.4000f +}; + +/* Matlab code to produce table: +overDriveCurve = [sqrt(linspace(0,1,65))' + 1]; +fprintf(1, '\t%.4f, %.4f, %.4f, %.4f, %.4f, %.4f,\n', overDriveCurve); +*/ +const float WebRtcAec_overDriveCurve[65] = { + 1.0000f, 1.1250f, 1.1768f, 1.2165f, 1.2500f, 1.2795f, + 1.3062f, 1.3307f, 1.3536f, 1.3750f, 1.3953f, 1.4146f, + 1.4330f, 1.4507f, 1.4677f, 1.4841f, 1.5000f, 1.5154f, + 1.5303f, 1.5449f, 1.5590f, 1.5728f, 1.5863f, 1.5995f, + 1.6124f, 1.6250f, 1.6374f, 1.6495f, 1.6614f, 1.6731f, + 1.6847f, 1.6960f, 1.7071f, 1.7181f, 1.7289f, 1.7395f, + 1.7500f, 1.7603f, 1.7706f, 1.7806f, 1.7906f, 1.8004f, + 1.8101f, 1.8197f, 1.8292f, 1.8385f, 1.8478f, 1.8570f, + 1.8660f, 1.8750f, 1.8839f, 1.8927f, 1.9014f, 1.9100f, + 1.9186f, 1.9270f, 1.9354f, 1.9437f, 1.9520f, 1.9601f, + 1.9682f, 1.9763f, 1.9843f, 1.9922f, 2.0000f +}; + +// "Private" function prototypes. +static void ProcessBlock(aec_t *aec, const short *farend, + const short *nearend, const short *nearendH, + short *out, short *outH); + +static void BufferFar(aec_t *aec, const short *farend, int farLen); +static void FetchFar(aec_t *aec, short *farend, int farLen, int knownDelay); + +static void NonLinearProcessing(aec_t *aec, int *ip, float *wfft, short *output, + short *outputH); + +static void GetHighbandGain(const float *lambda, float *nlpGainHband); + +// Comfort_noise also computes noise for H band returned in comfortNoiseHband +static void ComfortNoise(aec_t *aec, float efw[2][PART_LEN1], + complex_t *comfortNoiseHband, + const float *noisePow, const float *lambda); + +static void WebRtcAec_InitLevel(power_level_t *level); +static void WebRtcAec_InitStats(stats_t *stats); +static void UpdateLevel(power_level_t *level, const short *in); +static void UpdateMetrics(aec_t *aec); + +__inline static float MulRe(float aRe, float aIm, float bRe, float bIm) +{ + return aRe * bRe - aIm * bIm; +} + +__inline static float MulIm(float aRe, float aIm, float bRe, float bIm) +{ + return aRe * bIm + aIm * bRe; +} + +static int CmpFloat(const void *a, const void *b) +{ + const float *da = (const float *)a; + const float *db = (const float *)b; + + return (*da > *db) - (*da < *db); +} + +int WebRtcAec_CreateAec(aec_t **aecInst) +{ + aec_t *aec = malloc(sizeof(aec_t)); + *aecInst = aec; + if (aec == NULL) { + return -1; + } + + if (WebRtcApm_CreateBuffer(&aec->farFrBuf, FRAME_LEN + PART_LEN) == -1) { + WebRtcAec_FreeAec(aec); + aec = NULL; + return -1; + } + + if (WebRtcApm_CreateBuffer(&aec->nearFrBuf, FRAME_LEN + PART_LEN) == -1) { + WebRtcAec_FreeAec(aec); + aec = NULL; + return -1; + } + + if (WebRtcApm_CreateBuffer(&aec->outFrBuf, FRAME_LEN + PART_LEN) == -1) { + WebRtcAec_FreeAec(aec); + aec = NULL; + return -1; + } + + if (WebRtcApm_CreateBuffer(&aec->nearFrBufH, FRAME_LEN + PART_LEN) == -1) { + WebRtcAec_FreeAec(aec); + aec = NULL; + return -1; + } + + if (WebRtcApm_CreateBuffer(&aec->outFrBufH, FRAME_LEN + PART_LEN) == -1) { + WebRtcAec_FreeAec(aec); + aec = NULL; + return -1; + } + + return 0; +} + +int WebRtcAec_FreeAec(aec_t *aec) +{ + if (aec == NULL) { + return -1; + } + + WebRtcApm_FreeBuffer(aec->farFrBuf); + WebRtcApm_FreeBuffer(aec->nearFrBuf); + WebRtcApm_FreeBuffer(aec->outFrBuf); + + WebRtcApm_FreeBuffer(aec->nearFrBufH); + WebRtcApm_FreeBuffer(aec->outFrBufH); + + free(aec); + return 0; +} + +static void FilterFar(aec_t *aec, float yf[2][PART_LEN1]) +{ + int i; + for (i = 0; i < NR_PART; i++) { + int j; + int xPos = (i + aec->xfBufBlockPos) * PART_LEN1; + int pos = i * PART_LEN1; + // Check for wrap + if (i + aec->xfBufBlockPos >= NR_PART) { + xPos -= NR_PART*(PART_LEN1); + } + + for (j = 0; j < PART_LEN1; j++) { + yf[0][j] += MulRe(aec->xfBuf[0][xPos + j], aec->xfBuf[1][xPos + j], + aec->wfBuf[0][ pos + j], aec->wfBuf[1][ pos + j]); + yf[1][j] += MulIm(aec->xfBuf[0][xPos + j], aec->xfBuf[1][xPos + j], + aec->wfBuf[0][ pos + j], aec->wfBuf[1][ pos + j]); + } + } +} + +static void ScaleErrorSignal(aec_t *aec, float ef[2][PART_LEN1]) +{ + int i; + float absEf; + for (i = 0; i < (PART_LEN1); i++) { + ef[0][i] /= (aec->xPow[i] + 1e-10f); + ef[1][i] /= (aec->xPow[i] + 1e-10f); + absEf = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]); + + if (absEf > aec->errThresh) { + absEf = aec->errThresh / (absEf + 1e-10f); + ef[0][i] *= absEf; + ef[1][i] *= absEf; + } + + // Stepsize factor + ef[0][i] *= aec->mu; + ef[1][i] *= aec->mu; + } +} + +static void FilterAdaptation(aec_t *aec, float *fft, float ef[2][PART_LEN1], + int ip[IP_LEN], float wfft[W_LEN]) { + int i, j; + for (i = 0; i < NR_PART; i++) { + int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1); + int pos; + // Check for wrap + if (i + aec->xfBufBlockPos >= NR_PART) { + xPos -= NR_PART * PART_LEN1; + } + + pos = i * PART_LEN1; + +#ifdef UNCONSTR + for (j = 0; j < PART_LEN1; j++) { + aec->wfBuf[pos + j][0] += MulRe(aec->xfBuf[xPos + j][0], + -aec->xfBuf[xPos + j][1], + ef[j][0], ef[j][1]); + aec->wfBuf[pos + j][1] += MulIm(aec->xfBuf[xPos + j][0], + -aec->xfBuf[xPos + j][1], + ef[j][0], ef[j][1]); + } +#else + for (j = 0; j < PART_LEN; j++) { + + fft[2 * j] = MulRe(aec->xfBuf[0][xPos + j], + -aec->xfBuf[1][xPos + j], + ef[0][j], ef[1][j]); + fft[2 * j + 1] = MulIm(aec->xfBuf[0][xPos + j], + -aec->xfBuf[1][xPos + j], + ef[0][j], ef[1][j]); + } + fft[1] = MulRe(aec->xfBuf[0][xPos + PART_LEN], + -aec->xfBuf[1][xPos + PART_LEN], + ef[0][PART_LEN], ef[1][PART_LEN]); + + aec_rdft_128(-1, fft, ip, wfft); + memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN); + + // fft scaling + { + float scale = 2.0f / PART_LEN2; + for (j = 0; j < PART_LEN; j++) { + fft[j] *= scale; + } + } + aec_rdft_128(1, fft, ip, wfft); + + aec->wfBuf[0][pos] += fft[0]; + aec->wfBuf[0][pos + PART_LEN] += fft[1]; + + for (j = 1; j < PART_LEN; j++) { + aec->wfBuf[0][pos + j] += fft[2 * j]; + aec->wfBuf[1][pos + j] += fft[2 * j + 1]; + } +#endif // UNCONSTR + } +} + +static void OverdriveAndSuppress(aec_t *aec, float hNl[PART_LEN1], + const float hNlFb, + float efw[2][PART_LEN1]) { + int i; + for (i = 0; i < PART_LEN1; i++) { + // Weight subbands + if (hNl[i] > hNlFb) { + hNl[i] = WebRtcAec_weightCurve[i] * hNlFb + + (1 - WebRtcAec_weightCurve[i]) * hNl[i]; + } + hNl[i] = powf(hNl[i], aec->overDriveSm * WebRtcAec_overDriveCurve[i]); + + // Suppress error signal + efw[0][i] *= hNl[i]; + efw[1][i] *= hNl[i]; + + // Ooura fft returns incorrect sign on imaginary component. It matters here + // because we are making an additive change with comfort noise. + efw[1][i] *= -1; + } +} + +WebRtcAec_FilterFar_t WebRtcAec_FilterFar; +WebRtcAec_ScaleErrorSignal_t WebRtcAec_ScaleErrorSignal; +WebRtcAec_FilterAdaptation_t WebRtcAec_FilterAdaptation; +WebRtcAec_OverdriveAndSuppress_t WebRtcAec_OverdriveAndSuppress; + +int WebRtcAec_InitAec(aec_t *aec, int sampFreq) +{ + int i; + + aec->sampFreq = sampFreq; + + if (sampFreq == 8000) { + aec->mu = 0.6f; + aec->errThresh = 2e-6f; + } + else { + aec->mu = 0.5f; + aec->errThresh = 1.5e-6f; + } + + if (WebRtcApm_InitBuffer(aec->farFrBuf) == -1) { + return -1; + } + + if (WebRtcApm_InitBuffer(aec->nearFrBuf) == -1) { + return -1; + } + + if (WebRtcApm_InitBuffer(aec->outFrBuf) == -1) { + return -1; + } + + if (WebRtcApm_InitBuffer(aec->nearFrBufH) == -1) { + return -1; + } + + if (WebRtcApm_InitBuffer(aec->outFrBufH) == -1) { + return -1; + } + + // Default target suppression level + aec->targetSupp = -11.5; + aec->minOverDrive = 2.0; + + // Sampling frequency multiplier + // SWB is processed as 160 frame size + if (aec->sampFreq == 32000) { + aec->mult = (short)aec->sampFreq / 16000; + } + else { + aec->mult = (short)aec->sampFreq / 8000; + } + + aec->farBufWritePos = 0; + aec->farBufReadPos = 0; + + aec->inSamples = 0; + aec->outSamples = 0; + aec->knownDelay = 0; + + // Initialize buffers + memset(aec->farBuf, 0, sizeof(aec->farBuf)); + memset(aec->xBuf, 0, sizeof(aec->xBuf)); + memset(aec->dBuf, 0, sizeof(aec->dBuf)); + memset(aec->eBuf, 0, sizeof(aec->eBuf)); + // For H band + memset(aec->dBufH, 0, sizeof(aec->dBufH)); + + memset(aec->xPow, 0, sizeof(aec->xPow)); + memset(aec->dPow, 0, sizeof(aec->dPow)); + memset(aec->dInitMinPow, 0, sizeof(aec->dInitMinPow)); + aec->noisePow = aec->dInitMinPow; + aec->noiseEstCtr = 0; + + // Initial comfort noise power + for (i = 0; i < PART_LEN1; i++) { + aec->dMinPow[i] = 1.0e6f; + } + + // Holds the last block written to + aec->xfBufBlockPos = 0; + // TODO: Investigate need for these initializations. Deleting them doesn't + // change the output at all and yields 0.4% overall speedup. + memset(aec->xfBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1); + memset(aec->wfBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1); + memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); + memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); + memset(aec->xfwBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1); + memset(aec->se, 0, sizeof(float) * PART_LEN1); + + // To prevent numerical instability in the first block. + for (i = 0; i < PART_LEN1; i++) { + aec->sd[i] = 1; + } + for (i = 0; i < PART_LEN1; i++) { + aec->sx[i] = 1; + } + + memset(aec->hNs, 0, sizeof(aec->hNs)); + memset(aec->outBuf, 0, sizeof(float) * PART_LEN); + + aec->hNlFbMin = 1; + aec->hNlFbLocalMin = 1; + aec->hNlXdAvgMin = 1; + aec->hNlNewMin = 0; + aec->hNlMinCtr = 0; + aec->overDrive = 2; + aec->overDriveSm = 2; + aec->delayIdx = 0; + aec->stNearState = 0; + aec->echoState = 0; + aec->divergeState = 0; + + aec->seed = 777; + aec->delayEstCtr = 0; + + // Features on by default (G.167) +#ifdef G167 + aec->adaptToggle = 1; + aec->nlpToggle = 1; + aec->cnToggle = 1; +#endif + + // Metrics disabled by default + aec->metricsMode = 0; + WebRtcAec_InitMetrics(aec); + + // Assembly optimization + WebRtcAec_FilterFar = FilterFar; + WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; + WebRtcAec_FilterAdaptation = FilterAdaptation; + WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; + /*if (WebRtc_GetCPUInfo(kSSE2)) { +#if defined(__SSE2__) + WebRtcAec_InitAec_SSE2(); +#endif + }*/ + + return 0; +} + +void WebRtcAec_InitMetrics(aec_t *aec) +{ + aec->stateCounter = 0; + WebRtcAec_InitLevel(&aec->farlevel); + WebRtcAec_InitLevel(&aec->nearlevel); + WebRtcAec_InitLevel(&aec->linoutlevel); + WebRtcAec_InitLevel(&aec->nlpoutlevel); + + WebRtcAec_InitStats(&aec->erl); + WebRtcAec_InitStats(&aec->erle); + WebRtcAec_InitStats(&aec->aNlp); + WebRtcAec_InitStats(&aec->rerl); +} + + +void WebRtcAec_ProcessFrame(aec_t *aec, const short *farend, + const short *nearend, const short *nearendH, + short *out, short *outH, + int knownDelay) +{ + short farBl[PART_LEN], nearBl[PART_LEN], outBl[PART_LEN]; + short farFr[FRAME_LEN]; + // For H band + short nearBlH[PART_LEN], outBlH[PART_LEN]; + + int size = 0; + + // initialize: only used for SWB + memset(nearBlH, 0, sizeof(nearBlH)); + memset(outBlH, 0, sizeof(outBlH)); + + // Buffer the current frame. + // Fetch an older one corresponding to the delay. + BufferFar(aec, farend, FRAME_LEN); + FetchFar(aec, farFr, FRAME_LEN, knownDelay); + + // Buffer the synchronized far and near frames, + // to pass the smaller blocks individually. + WebRtcApm_WriteBuffer(aec->farFrBuf, farFr, FRAME_LEN); + WebRtcApm_WriteBuffer(aec->nearFrBuf, nearend, FRAME_LEN); + // For H band + if (aec->sampFreq == 32000) { + WebRtcApm_WriteBuffer(aec->nearFrBufH, nearendH, FRAME_LEN); + } + + // Process as many blocks as possible. + while (WebRtcApm_get_buffer_size(aec->farFrBuf) >= PART_LEN) { + + WebRtcApm_ReadBuffer(aec->farFrBuf, farBl, PART_LEN); + WebRtcApm_ReadBuffer(aec->nearFrBuf, nearBl, PART_LEN); + + // For H band + if (aec->sampFreq == 32000) { + WebRtcApm_ReadBuffer(aec->nearFrBufH, nearBlH, PART_LEN); + } + + ProcessBlock(aec, farBl, nearBl, nearBlH, outBl, outBlH); + + WebRtcApm_WriteBuffer(aec->outFrBuf, outBl, PART_LEN); + // For H band + if (aec->sampFreq == 32000) { + WebRtcApm_WriteBuffer(aec->outFrBufH, outBlH, PART_LEN); + } + } + + // Stuff the out buffer if we have less than a frame to output. + // This should only happen for the first frame. + size = WebRtcApm_get_buffer_size(aec->outFrBuf); + if (size < FRAME_LEN) { + WebRtcApm_StuffBuffer(aec->outFrBuf, FRAME_LEN - size); + if (aec->sampFreq == 32000) { + WebRtcApm_StuffBuffer(aec->outFrBufH, FRAME_LEN - size); + } + } + + // Obtain an output frame. + WebRtcApm_ReadBuffer(aec->outFrBuf, out, FRAME_LEN); + // For H band + if (aec->sampFreq == 32000) { + WebRtcApm_ReadBuffer(aec->outFrBufH, outH, FRAME_LEN); + } +} + +static void ProcessBlock(aec_t *aec, const short *farend, + const short *nearend, const short *nearendH, + short *output, short *outputH) +{ + int i; + float d[PART_LEN], y[PART_LEN], e[PART_LEN], dH[PART_LEN]; + short eInt16[PART_LEN]; + float scale; + + float fft[PART_LEN2]; + float xf[2][PART_LEN1], yf[2][PART_LEN1], ef[2][PART_LEN1]; + complex_t df[PART_LEN1]; + int ip[IP_LEN]; + float wfft[W_LEN]; + + const float gPow[2] = {0.9f, 0.1f}; + + // Noise estimate constants. + const int noiseInitBlocks = 500 * aec->mult; + const float step = 0.1f; + const float ramp = 1.0002f; + const float gInitNoise[2] = {0.999f, 0.001f}; + +#ifdef AEC_DEBUG + fwrite(farend, sizeof(short), PART_LEN, aec->farFile); + fwrite(nearend, sizeof(short), PART_LEN, aec->nearFile); +#endif + + memset(dH, 0, sizeof(dH)); + + // ---------- Ooura fft ---------- + // Concatenate old and new farend blocks. + for (i = 0; i < PART_LEN; i++) { + aec->xBuf[i + PART_LEN] = (float)farend[i]; + d[i] = (float)nearend[i]; + } + + if (aec->sampFreq == 32000) { + for (i = 0; i < PART_LEN; i++) { + dH[i] = (float)nearendH[i]; + } + } + + + memcpy(fft, aec->xBuf, sizeof(float) * PART_LEN2); + memcpy(aec->dBuf + PART_LEN, d, sizeof(float) * PART_LEN); + // For H band + if (aec->sampFreq == 32000) { + memcpy(aec->dBufH + PART_LEN, dH, sizeof(float) * PART_LEN); + } + + // Setting this on the first call initializes work arrays. + ip[0] = 0; + aec_rdft_128(1, fft, ip, wfft); + + // Far fft + xf[1][0] = 0; + xf[1][PART_LEN] = 0; + xf[0][0] = fft[0]; + xf[0][PART_LEN] = fft[1]; + + for (i = 1; i < PART_LEN; i++) { + xf[0][i] = fft[2 * i]; + xf[1][i] = fft[2 * i + 1]; + } + + // Near fft + memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); + aec_rdft_128(1, fft, ip, wfft); + df[0][1] = 0; + df[PART_LEN][1] = 0; + df[0][0] = fft[0]; + df[PART_LEN][0] = fft[1]; + + for (i = 1; i < PART_LEN; i++) { + df[i][0] = fft[2 * i]; + df[i][1] = fft[2 * i + 1]; + } + + // Power smoothing + for (i = 0; i < PART_LEN1; i++) { + aec->xPow[i] = gPow[0] * aec->xPow[i] + gPow[1] * NR_PART * + (xf[0][i] * xf[0][i] + xf[1][i] * xf[1][i]); + aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * + (df[i][0] * df[i][0] + df[i][1] * df[i][1]); + } + + // Estimate noise power. Wait until dPow is more stable. + if (aec->noiseEstCtr > 50) { + for (i = 0; i < PART_LEN1; i++) { + if (aec->dPow[i] < aec->dMinPow[i]) { + aec->dMinPow[i] = (aec->dPow[i] + step * (aec->dMinPow[i] - + aec->dPow[i])) * ramp; + } + else { + aec->dMinPow[i] *= ramp; + } + } + } + + // Smooth increasing noise power from zero at the start, + // to avoid a sudden burst of comfort noise. + if (aec->noiseEstCtr < noiseInitBlocks) { + aec->noiseEstCtr++; + for (i = 0; i < PART_LEN1; i++) { + if (aec->dMinPow[i] > aec->dInitMinPow[i]) { + aec->dInitMinPow[i] = gInitNoise[0] * aec->dInitMinPow[i] + + gInitNoise[1] * aec->dMinPow[i]; + } + else { + aec->dInitMinPow[i] = aec->dMinPow[i]; + } + } + aec->noisePow = aec->dInitMinPow; + } + else { + aec->noisePow = aec->dMinPow; + } + + + // Update the xfBuf block position. + aec->xfBufBlockPos--; + if (aec->xfBufBlockPos == -1) { + aec->xfBufBlockPos = NR_PART - 1; + } + + // Buffer xf + memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, xf[0], + sizeof(float) * PART_LEN1); + memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, xf[1], + sizeof(float) * PART_LEN1); + + memset(yf[0], 0, sizeof(float) * (PART_LEN1 * 2)); + + // Filter far + WebRtcAec_FilterFar(aec, yf); + + // Inverse fft to obtain echo estimate and error. + fft[0] = yf[0][0]; + fft[1] = yf[0][PART_LEN]; + for (i = 1; i < PART_LEN; i++) { + fft[2 * i] = yf[0][i]; + fft[2 * i + 1] = yf[1][i]; + } + aec_rdft_128(-1, fft, ip, wfft); + + scale = 2.0f / PART_LEN2; + for (i = 0; i < PART_LEN; i++) { + y[i] = fft[PART_LEN + i] * scale; // fft scaling + } + + for (i = 0; i < PART_LEN; i++) { + e[i] = d[i] - y[i]; + } + + // Error fft + memcpy(aec->eBuf + PART_LEN, e, sizeof(float) * PART_LEN); + memset(fft, 0, sizeof(float) * PART_LEN); + memcpy(fft + PART_LEN, e, sizeof(float) * PART_LEN); + aec_rdft_128(1, fft, ip, wfft); + + ef[1][0] = 0; + ef[1][PART_LEN] = 0; + ef[0][0] = fft[0]; + ef[0][PART_LEN] = fft[1]; + for (i = 1; i < PART_LEN; i++) { + ef[0][i] = fft[2 * i]; + ef[1][i] = fft[2 * i + 1]; + } + + // Scale error signal inversely with far power. + WebRtcAec_ScaleErrorSignal(aec, ef); +#ifdef G167 + if (aec->adaptToggle) { +#endif + // Filter adaptation + WebRtcAec_FilterAdaptation(aec, fft, ef, ip, wfft); +#ifdef G167 + } +#endif + + NonLinearProcessing(aec, ip, wfft, output, outputH); + +#if defined(AEC_DEBUG) || defined(G167) + for (i = 0; i < PART_LEN; i++) { + eInt16[i] = (short)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, e[i], + WEBRTC_SPL_WORD16_MIN); + } +#endif +#ifdef G167 + if (aec->nlpToggle == 0) { + memcpy(output, eInt16, sizeof(eInt16)); + } +#endif + + if (aec->metricsMode == 1) { + for (i = 0; i < PART_LEN; i++) { + eInt16[i] = (short)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, e[i], + WEBRTC_SPL_WORD16_MIN); + } + + // Update power levels and echo metrics + UpdateLevel(&aec->farlevel, farend); + UpdateLevel(&aec->nearlevel, nearend); + UpdateLevel(&aec->linoutlevel, eInt16); + UpdateLevel(&aec->nlpoutlevel, output); + UpdateMetrics(aec); + } + +#ifdef AEC_DEBUG + fwrite(eInt16, sizeof(short), PART_LEN, aec->outLpFile); + fwrite(output, sizeof(short), PART_LEN, aec->outFile); +#endif +} + +static void NonLinearProcessing(aec_t *aec, int *ip, float *wfft, short *output, short *outputH) +{ + float efw[2][PART_LEN1], dfw[2][PART_LEN1]; + complex_t xfw[PART_LEN1]; + complex_t comfortNoiseHband[PART_LEN1]; + float fft[PART_LEN2]; + float scale, dtmp; + float nlpGainHband; + int i, j, pos; + + // Coherence and non-linear filter + float cohde[PART_LEN1], cohxd[PART_LEN1]; + float hNlDeAvg, hNlXdAvg; + float hNl[PART_LEN1]; + float hNlPref[PREF_BAND_SIZE]; + float hNlFb = 0, hNlFbLow = 0; + const float prefBandQuant = 0.75f, prefBandQuantLow = 0.5f; + const int prefBandSize = PREF_BAND_SIZE / aec->mult; + const int minPrefBand = 4 / aec->mult; + + // Near and error power sums + float sdSum = 0, seSum = 0; + + // Power estimate smoothing coefficients + const float gCoh[2][2] = {{0.9f, 0.1f}, {0.93f, 0.07f}}; + const float *ptrGCoh = gCoh[aec->mult - 1]; + + // Filter energey + float wfEnMax = 0, wfEn = 0; + const int delayEstInterval = 10 * aec->mult; + + aec->delayEstCtr++; + if (aec->delayEstCtr == delayEstInterval) { + aec->delayEstCtr = 0; + } + + // initialize comfort noise for H band + memset(comfortNoiseHband, 0, sizeof(comfortNoiseHband)); + nlpGainHband = (float)0.0; + dtmp = (float)0.0; + + // Measure energy in each filter partition to determine delay. + // TODO: Spread by computing one partition per block? + if (aec->delayEstCtr == 0) { + wfEnMax = 0; + aec->delayIdx = 0; + for (i = 0; i < NR_PART; i++) { + pos = i * PART_LEN1; + wfEn = 0; + for (j = 0; j < PART_LEN1; j++) { + wfEn += aec->wfBuf[0][pos + j] * aec->wfBuf[0][pos + j] + + aec->wfBuf[1][pos + j] * aec->wfBuf[1][pos + j]; + } + + if (wfEn > wfEnMax) { + wfEnMax = wfEn; + aec->delayIdx = i; + } + } + } + + // NLP + // Windowed far fft + for (i = 0; i < PART_LEN; i++) { + fft[i] = aec->xBuf[i] * sqrtHanning[i]; + fft[PART_LEN + i] = aec->xBuf[PART_LEN + i] * sqrtHanning[PART_LEN - i]; + } + aec_rdft_128(1, fft, ip, wfft); + + xfw[0][1] = 0; + xfw[PART_LEN][1] = 0; + xfw[0][0] = fft[0]; + xfw[PART_LEN][0] = fft[1]; + for (i = 1; i < PART_LEN; i++) { + xfw[i][0] = fft[2 * i]; + xfw[i][1] = fft[2 * i + 1]; + } + + // Buffer far. + memcpy(aec->xfwBuf, xfw, sizeof(xfw)); + + // Use delayed far. + memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1, sizeof(xfw)); + + // Windowed near fft + for (i = 0; i < PART_LEN; i++) { + fft[i] = aec->dBuf[i] * sqrtHanning[i]; + fft[PART_LEN + i] = aec->dBuf[PART_LEN + i] * sqrtHanning[PART_LEN - i]; + } + aec_rdft_128(1, fft, ip, wfft); + + dfw[1][0] = 0; + dfw[1][PART_LEN] = 0; + dfw[0][0] = fft[0]; + dfw[0][PART_LEN] = fft[1]; + for (i = 1; i < PART_LEN; i++) { + dfw[0][i] = fft[2 * i]; + dfw[1][i] = fft[2 * i + 1]; + } + + // Windowed error fft + for (i = 0; i < PART_LEN; i++) { + fft[i] = aec->eBuf[i] * sqrtHanning[i]; + fft[PART_LEN + i] = aec->eBuf[PART_LEN + i] * sqrtHanning[PART_LEN - i]; + } + aec_rdft_128(1, fft, ip, wfft); + efw[1][0] = 0; + efw[1][PART_LEN] = 0; + efw[0][0] = fft[0]; + efw[0][PART_LEN] = fft[1]; + for (i = 1; i < PART_LEN; i++) { + efw[0][i] = fft[2 * i]; + efw[1][i] = fft[2 * i + 1]; + } + + // Smoothed PSD + for (i = 0; i < PART_LEN1; i++) { + aec->sd[i] = ptrGCoh[0] * aec->sd[i] + ptrGCoh[1] * + (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]); + aec->se[i] = ptrGCoh[0] * aec->se[i] + ptrGCoh[1] * + (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]); + // We threshold here to protect against the ill-effects of a zero farend. + // The threshold is not arbitrarily chosen, but balances protection and + // adverse interaction with the algorithm's tuning. + // TODO: investigate further why this is so sensitive. + aec->sx[i] = ptrGCoh[0] * aec->sx[i] + ptrGCoh[1] * + WEBRTC_SPL_MAX(xfw[i][0] * xfw[i][0] + xfw[i][1] * xfw[i][1], 15); + + aec->sde[i][0] = ptrGCoh[0] * aec->sde[i][0] + ptrGCoh[1] * + (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]); + aec->sde[i][1] = ptrGCoh[0] * aec->sde[i][1] + ptrGCoh[1] * + (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]); + + aec->sxd[i][0] = ptrGCoh[0] * aec->sxd[i][0] + ptrGCoh[1] * + (dfw[0][i] * xfw[i][0] + dfw[1][i] * xfw[i][1]); + aec->sxd[i][1] = ptrGCoh[0] * aec->sxd[i][1] + ptrGCoh[1] * + (dfw[0][i] * xfw[i][1] - dfw[1][i] * xfw[i][0]); + + sdSum += aec->sd[i]; + seSum += aec->se[i]; + } + + // Divergent filter safeguard. + if (aec->divergeState == 0) { + if (seSum > sdSum) { + aec->divergeState = 1; + } + } + else { + if (seSum * 1.05f < sdSum) { + aec->divergeState = 0; + } + } + + if (aec->divergeState == 1) { + memcpy(efw, dfw, sizeof(efw)); + } + + // Reset if error is significantly larger than nearend (13 dB). + if (seSum > (19.95f * sdSum)) { + memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); + } + + // Subband coherence + for (i = 0; i < PART_LEN1; i++) { + cohde[i] = (aec->sde[i][0] * aec->sde[i][0] + aec->sde[i][1] * aec->sde[i][1]) / + (aec->sd[i] * aec->se[i] + 1e-10f); + cohxd[i] = (aec->sxd[i][0] * aec->sxd[i][0] + aec->sxd[i][1] * aec->sxd[i][1]) / + (aec->sx[i] * aec->sd[i] + 1e-10f); + } + + hNlXdAvg = 0; + for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { + hNlXdAvg += cohxd[i]; + } + hNlXdAvg /= prefBandSize; + hNlXdAvg = 1 - hNlXdAvg; + + hNlDeAvg = 0; + for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { + hNlDeAvg += cohde[i]; + } + hNlDeAvg /= prefBandSize; + + if (hNlXdAvg < 0.75f && hNlXdAvg < aec->hNlXdAvgMin) { + aec->hNlXdAvgMin = hNlXdAvg; + } + + if (hNlDeAvg > 0.98f && hNlXdAvg > 0.9f) { + aec->stNearState = 1; + } + else if (hNlDeAvg < 0.95f || hNlXdAvg < 0.8f) { + aec->stNearState = 0; + } + + if (aec->hNlXdAvgMin == 1) { + aec->echoState = 0; + aec->overDrive = aec->minOverDrive; + + if (aec->stNearState == 1) { + memcpy(hNl, cohde, sizeof(hNl)); + hNlFb = hNlDeAvg; + hNlFbLow = hNlDeAvg; + } + else { + for (i = 0; i < PART_LEN1; i++) { + hNl[i] = 1 - cohxd[i]; + } + hNlFb = hNlXdAvg; + hNlFbLow = hNlXdAvg; + } + } + else { + + if (aec->stNearState == 1) { + aec->echoState = 0; + memcpy(hNl, cohde, sizeof(hNl)); + hNlFb = hNlDeAvg; + hNlFbLow = hNlDeAvg; + } + else { + aec->echoState = 1; + for (i = 0; i < PART_LEN1; i++) { + hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]); + } + + // Select an order statistic from the preferred bands. + // TODO: Using quicksort now, but a selection algorithm may be preferred. + memcpy(hNlPref, &hNl[minPrefBand], sizeof(float) * prefBandSize); + qsort(hNlPref, prefBandSize, sizeof(float), CmpFloat); + hNlFb = hNlPref[(int)floor(prefBandQuant * (prefBandSize - 1))]; + hNlFbLow = hNlPref[(int)floor(prefBandQuantLow * (prefBandSize - 1))]; + } + } + + // Track the local filter minimum to determine suppression overdrive. + if (hNlFbLow < 0.6f && hNlFbLow < aec->hNlFbLocalMin) { + aec->hNlFbLocalMin = hNlFbLow; + aec->hNlFbMin = hNlFbLow; + aec->hNlNewMin = 1; + aec->hNlMinCtr = 0; + } + aec->hNlFbLocalMin = WEBRTC_SPL_MIN(aec->hNlFbLocalMin + 0.0008f / aec->mult, 1); + aec->hNlXdAvgMin = WEBRTC_SPL_MIN(aec->hNlXdAvgMin + 0.0006f / aec->mult, 1); + + if (aec->hNlNewMin == 1) { + aec->hNlMinCtr++; + } + if (aec->hNlMinCtr == 2) { + aec->hNlNewMin = 0; + aec->hNlMinCtr = 0; + aec->overDrive = WEBRTC_SPL_MAX(aec->targetSupp / + ((float)log(aec->hNlFbMin + 1e-10f) + 1e-10f), aec->minOverDrive); + } + + // Smooth the overdrive. + if (aec->overDrive < aec->overDriveSm) { + aec->overDriveSm = 0.99f * aec->overDriveSm + 0.01f * aec->overDrive; + } + else { + aec->overDriveSm = 0.9f * aec->overDriveSm + 0.1f * aec->overDrive; + } + + WebRtcAec_OverdriveAndSuppress(aec, hNl, hNlFb, efw); + +#ifdef G167 + if (aec->cnToggle) { + ComfortNoise(aec, efw, comfortNoiseHband, aec->noisePow, hNl); + } +#else + // Add comfort noise. + ComfortNoise(aec, efw, comfortNoiseHband, aec->noisePow, hNl); +#endif + + // Inverse error fft. + fft[0] = efw[0][0]; + fft[1] = efw[0][PART_LEN]; + for (i = 1; i < PART_LEN; i++) { + fft[2*i] = efw[0][i]; + // Sign change required by Ooura fft. + fft[2*i + 1] = -efw[1][i]; + } + aec_rdft_128(-1, fft, ip, wfft); + + // Overlap and add to obtain output. + scale = 2.0f / PART_LEN2; + for (i = 0; i < PART_LEN; i++) { + fft[i] *= scale; // fft scaling + fft[i] = fft[i]*sqrtHanning[i] + aec->outBuf[i]; + + // Saturation protection + output[i] = (short)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, fft[i], + WEBRTC_SPL_WORD16_MIN); + + fft[PART_LEN + i] *= scale; // fft scaling + aec->outBuf[i] = fft[PART_LEN + i] * sqrtHanning[PART_LEN - i]; + } + + // For H band + if (aec->sampFreq == 32000) { + + // H band gain + // average nlp over low band: average over second half of freq spectrum + // (4->8khz) + GetHighbandGain(hNl, &nlpGainHband); + + // Inverse comfort_noise + if (flagHbandCn == 1) { + fft[0] = comfortNoiseHband[0][0]; + fft[1] = comfortNoiseHband[PART_LEN][0]; + for (i = 1; i < PART_LEN; i++) { + fft[2*i] = comfortNoiseHband[i][0]; + fft[2*i + 1] = comfortNoiseHband[i][1]; + } + aec_rdft_128(-1, fft, ip, wfft); + scale = 2.0f / PART_LEN2; + } + + // compute gain factor + for (i = 0; i < PART_LEN; i++) { + dtmp = (float)aec->dBufH[i]; + dtmp = (float)dtmp * nlpGainHband; // for variable gain + + // add some comfort noise where Hband is attenuated + if (flagHbandCn == 1) { + fft[i] *= scale; // fft scaling + dtmp += cnScaleHband * fft[i]; + } + + // Saturation protection + outputH[i] = (short)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, dtmp, + WEBRTC_SPL_WORD16_MIN); + } + } + + // Copy the current block to the old position. + memcpy(aec->xBuf, aec->xBuf + PART_LEN, sizeof(float) * PART_LEN); + memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN); + memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN); + + // Copy the current block to the old position for H band + if (aec->sampFreq == 32000) { + memcpy(aec->dBufH, aec->dBufH + PART_LEN, sizeof(float) * PART_LEN); + } + + memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf, sizeof(aec->xfwBuf) - + sizeof(complex_t) * PART_LEN1); +} + +static void GetHighbandGain(const float *lambda, float *nlpGainHband) +{ + int i; + + nlpGainHband[0] = (float)0.0; + for (i = freqAvgIc; i < PART_LEN1 - 1; i++) { + nlpGainHband[0] += lambda[i]; + } + nlpGainHband[0] /= (float)(PART_LEN1 - 1 - freqAvgIc); +} + +static void ComfortNoise(aec_t *aec, float efw[2][PART_LEN1], + complex_t *comfortNoiseHband, const float *noisePow, const float *lambda) +{ + int i, num; + float rand[PART_LEN]; + float noise, noiseAvg, tmp, tmpAvg; + WebRtc_Word16 randW16[PART_LEN]; + complex_t u[PART_LEN1]; + + const float pi2 = 6.28318530717959f; + + // Generate a uniform random array on [0 1] + WebRtcSpl_RandUArray(randW16, PART_LEN, &aec->seed); + for (i = 0; i < PART_LEN; i++) { + rand[i] = ((float)randW16[i]) / 32768; + } + + // Reject LF noise + u[0][0] = 0; + u[0][1] = 0; + for (i = 1; i < PART_LEN1; i++) { + tmp = pi2 * rand[i - 1]; + + noise = sqrtf(noisePow[i]); + u[i][0] = noise * (float)cos(tmp); + u[i][1] = -noise * (float)sin(tmp); + } + u[PART_LEN][1] = 0; + + for (i = 0; i < PART_LEN1; i++) { + // This is the proper weighting to match the background noise power + tmp = sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); + //tmp = 1 - lambda[i]; + efw[0][i] += tmp * u[i][0]; + efw[1][i] += tmp * u[i][1]; + } + + // For H band comfort noise + // TODO: don't compute noise and "tmp" twice. Use the previous results. + noiseAvg = 0.0; + tmpAvg = 0.0; + num = 0; + if (aec->sampFreq == 32000 && flagHbandCn == 1) { + + // average noise scale + // average over second half of freq spectrum (i.e., 4->8khz) + // TODO: we shouldn't need num. We know how many elements we're summing. + for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { + num++; + noiseAvg += sqrtf(noisePow[i]); + } + noiseAvg /= (float)num; + + // average nlp scale + // average over second half of freq spectrum (i.e., 4->8khz) + // TODO: we shouldn't need num. We know how many elements we're summing. + num = 0; + for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { + num++; + tmpAvg += sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); + } + tmpAvg /= (float)num; + + // Use average noise for H band + // TODO: we should probably have a new random vector here. + // Reject LF noise + u[0][0] = 0; + u[0][1] = 0; + for (i = 1; i < PART_LEN1; i++) { + tmp = pi2 * rand[i - 1]; + + // Use average noise for H band + u[i][0] = noiseAvg * (float)cos(tmp); + u[i][1] = -noiseAvg * (float)sin(tmp); + } + u[PART_LEN][1] = 0; + + for (i = 0; i < PART_LEN1; i++) { + // Use average NLP weight for H band + comfortNoiseHband[i][0] = tmpAvg * u[i][0]; + comfortNoiseHband[i][1] = tmpAvg * u[i][1]; + } + } +} + +// Buffer the farend to account for knownDelay +static void BufferFar(aec_t *aec, const short *farend, int farLen) +{ + int writeLen = farLen, writePos = 0; + + // Check if the write position must be wrapped. + while (aec->farBufWritePos + writeLen > FAR_BUF_LEN) { + + // Write to remaining buffer space before wrapping. + writeLen = FAR_BUF_LEN - aec->farBufWritePos; + memcpy(aec->farBuf + aec->farBufWritePos, farend + writePos, + sizeof(short) * writeLen); + aec->farBufWritePos = 0; + writePos = writeLen; + writeLen = farLen - writeLen; + } + + memcpy(aec->farBuf + aec->farBufWritePos, farend + writePos, + sizeof(short) * writeLen); + aec->farBufWritePos += writeLen; +} + +static void FetchFar(aec_t *aec, short *farend, int farLen, int knownDelay) +{ + int readLen = farLen, readPos = 0, delayChange = knownDelay - aec->knownDelay; + + aec->farBufReadPos -= delayChange; + + // Check if delay forces a read position wrap. + while(aec->farBufReadPos < 0) { + aec->farBufReadPos += FAR_BUF_LEN; + } + while(aec->farBufReadPos > FAR_BUF_LEN - 1) { + aec->farBufReadPos -= FAR_BUF_LEN; + } + + aec->knownDelay = knownDelay; + + // Check if read position must be wrapped. + while (aec->farBufReadPos + readLen > FAR_BUF_LEN) { + + // Read from remaining buffer space before wrapping. + readLen = FAR_BUF_LEN - aec->farBufReadPos; + memcpy(farend + readPos, aec->farBuf + aec->farBufReadPos, + sizeof(short) * readLen); + aec->farBufReadPos = 0; + readPos = readLen; + readLen = farLen - readLen; + } + memcpy(farend + readPos, aec->farBuf + aec->farBufReadPos, + sizeof(short) * readLen); + aec->farBufReadPos += readLen; +} + +static void WebRtcAec_InitLevel(power_level_t *level) +{ + const float bigFloat = 1E17f; + + level->averagelevel = 0; + level->framelevel = 0; + level->minlevel = bigFloat; + level->frsum = 0; + level->sfrsum = 0; + level->frcounter = 0; + level->sfrcounter = 0; +} + +static void WebRtcAec_InitStats(stats_t *stats) +{ + stats->instant = offsetLevel; + stats->average = offsetLevel; + stats->max = offsetLevel; + stats->min = offsetLevel * (-1); + stats->sum = 0; + stats->hisum = 0; + stats->himean = offsetLevel; + stats->counter = 0; + stats->hicounter = 0; +} + +static void UpdateLevel(power_level_t *level, const short *in) +{ + int k; + + for (k = 0; k < PART_LEN; k++) { + level->sfrsum += in[k] * in[k]; + } + level->sfrcounter++; + + if (level->sfrcounter > subCountLen) { + level->framelevel = level->sfrsum / (subCountLen * PART_LEN); + level->sfrsum = 0; + level->sfrcounter = 0; + + if (level->framelevel > 0) { + if (level->framelevel < level->minlevel) { + level->minlevel = level->framelevel; // New minimum + } else { + level->minlevel *= (1 + 0.001f); // Small increase + } + } + level->frcounter++; + level->frsum += level->framelevel; + + if (level->frcounter > countLen) { + level->averagelevel = level->frsum / countLen; + level->frsum = 0; + level->frcounter = 0; + } + + } +} + +static void UpdateMetrics(aec_t *aec) +{ + float dtmp, dtmp2, dtmp3; + + const float actThresholdNoisy = 8.0f; + const float actThresholdClean = 40.0f; + const float safety = 0.99995f; + const float noisyPower = 300000.0f; + + float actThreshold; + float echo, suppressedEcho; + + if (aec->echoState) { // Check if echo is likely present + aec->stateCounter++; + } + + if (aec->farlevel.frcounter == countLen) { + + if (aec->farlevel.minlevel < noisyPower) { + actThreshold = actThresholdClean; + } + else { + actThreshold = actThresholdNoisy; + } + + if ((aec->stateCounter > (0.5f * countLen * subCountLen)) + && (aec->farlevel.sfrcounter == 0) + + // Estimate in active far-end segments only + && (aec->farlevel.averagelevel > (actThreshold * aec->farlevel.minlevel)) + ) { + + // Subtract noise power + echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel; + + // ERL + dtmp = 10 * (float)log10(aec->farlevel.averagelevel / + aec->nearlevel.averagelevel + 1e-10f); + dtmp2 = 10 * (float)log10(aec->farlevel.averagelevel / echo + 1e-10f); + + aec->erl.instant = dtmp; + if (dtmp > aec->erl.max) { + aec->erl.max = dtmp; + } + + if (dtmp < aec->erl.min) { + aec->erl.min = dtmp; + } + + aec->erl.counter++; + aec->erl.sum += dtmp; + aec->erl.average = aec->erl.sum / aec->erl.counter; + + // Upper mean + if (dtmp > aec->erl.average) { + aec->erl.hicounter++; + aec->erl.hisum += dtmp; + aec->erl.himean = aec->erl.hisum / aec->erl.hicounter; + } + + // A_NLP + dtmp = 10 * (float)log10(aec->nearlevel.averagelevel / + aec->linoutlevel.averagelevel + 1e-10f); + + // subtract noise power + suppressedEcho = aec->linoutlevel.averagelevel - safety * aec->linoutlevel.minlevel; + + dtmp2 = 10 * (float)log10(echo / suppressedEcho + 1e-10f); + dtmp3 = 10 * (float)log10(aec->nearlevel.averagelevel / suppressedEcho + 1e-10f); + + aec->aNlp.instant = dtmp2; + if (dtmp > aec->aNlp.max) { + aec->aNlp.max = dtmp; + } + + if (dtmp < aec->aNlp.min) { + aec->aNlp.min = dtmp; + } + + aec->aNlp.counter++; + aec->aNlp.sum += dtmp; + aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter; + + // Upper mean + if (dtmp > aec->aNlp.average) { + aec->aNlp.hicounter++; + aec->aNlp.hisum += dtmp; + aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter; + } + + // ERLE + + // subtract noise power + suppressedEcho = aec->nlpoutlevel.averagelevel - safety * aec->nlpoutlevel.minlevel; + + dtmp = 10 * (float)log10(aec->nearlevel.averagelevel / + aec->nlpoutlevel.averagelevel + 1e-10f); + dtmp2 = 10 * (float)log10(echo / suppressedEcho + 1e-10f); + + dtmp = dtmp2; + aec->erle.instant = dtmp; + if (dtmp > aec->erle.max) { + aec->erle.max = dtmp; + } + + if (dtmp < aec->erle.min) { + aec->erle.min = dtmp; + } + + aec->erle.counter++; + aec->erle.sum += dtmp; + aec->erle.average = aec->erle.sum / aec->erle.counter; + + // Upper mean + if (dtmp > aec->erle.average) { + aec->erle.hicounter++; + aec->erle.hisum += dtmp; + aec->erle.himean = aec->erle.hisum / aec->erle.hicounter; + } + } + + aec->stateCounter = 0; + } +} + diff --git a/src/libs/webrtc/aec/aec_core.h b/src/libs/webrtc/aec/aec_core.h new file mode 100644 index 00000000..2a619085 --- /dev/null +++ b/src/libs/webrtc/aec/aec_core.h @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Specifies the interface for the AEC core. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_ + +#include <stdio.h> +#include "typedefs.h" +#include "signal_processing_library.h" + +//#define G167 // for running G167 tests +//#define UNCONSTR // time-unconstrained filter +//#define AEC_DEBUG // for recording files + +#define FRAME_LEN 80 +#define PART_LEN 64 // Length of partition +#define PART_LEN1 (PART_LEN + 1) // Unique fft coefficients +#define PART_LEN2 (PART_LEN * 2) // Length of partition * 2 +#define NR_PART 12 // Number of partitions +#define FILT_LEN (PART_LEN * NR_PART) // Filter length +#define FILT_LEN2 (FILT_LEN * 2) // Double filter length +#define FAR_BUF_LEN (FILT_LEN2 * 2) +#define PREF_BAND_SIZE 24 + +#define BLOCKL_MAX FRAME_LEN + +typedef float complex_t[2]; +// For performance reasons, some arrays of complex numbers are replaced by twice +// as long arrays of float, all the real parts followed by all the imaginary +// ones (complex_t[SIZE] -> float[2][SIZE]). This allows SIMD optimizations and +// is better than two arrays (one for the real parts and one for the imaginary +// parts) as this other way would require two pointers instead of one and cause +// extra register spilling. This also allows the offsets to be calculated at +// compile time. + +// Metrics +enum {offsetLevel = -100}; + +typedef struct { + float sfrsum; + int sfrcounter; + float framelevel; + float frsum; + int frcounter; + float minlevel; + float averagelevel; +} power_level_t; + +typedef struct { + float instant; + float average; + float min; + float max; + float sum; + float hisum; + float himean; + int counter; + int hicounter; +} stats_t; + +typedef struct { + int farBufWritePos, farBufReadPos; + + int knownDelay; + int inSamples, outSamples; + int delayEstCtr; + + void *farFrBuf, *nearFrBuf, *outFrBuf; + + void *nearFrBufH; + void *outFrBufH; + + float xBuf[PART_LEN2]; // farend + float dBuf[PART_LEN2]; // nearend + float eBuf[PART_LEN2]; // error + + float dBufH[PART_LEN2]; // nearend + + float xPow[PART_LEN1]; + float dPow[PART_LEN1]; + float dMinPow[PART_LEN1]; + float dInitMinPow[PART_LEN1]; + float *noisePow; +#ifdef FFTW + float fftR[PART_LEN2]; + fftw_complex fftC[PART_LEN2]; + fftw_plan fftPlan, ifftPlan; + + fftw_complex xfBuf[NR_PART * PART_LEN1]; + fftw_complex wfBuf[NR_PART * PART_LEN1]; + fftw_complex sde[PART_LEN1]; +#else + float xfBuf[2][NR_PART * PART_LEN1]; // farend fft buffer + float wfBuf[2][NR_PART * PART_LEN1]; // filter fft + complex_t sde[PART_LEN1]; // cross-psd of nearend and error + complex_t sxd[PART_LEN1]; // cross-psd of farend and nearend + complex_t xfwBuf[NR_PART * PART_LEN1]; // farend windowed fft buffer +#endif + float sx[PART_LEN1], sd[PART_LEN1], se[PART_LEN1]; // far, near and error psd + float hNs[PART_LEN1]; + float hNlFbMin, hNlFbLocalMin; + float hNlXdAvgMin; + int hNlNewMin, hNlMinCtr; + float overDrive, overDriveSm; + float targetSupp, minOverDrive; + float outBuf[PART_LEN]; + int delayIdx; + + short stNearState, echoState; + short divergeState; + + int xfBufBlockPos; + + short farBuf[FILT_LEN2 * 2]; + + short mult; // sampling frequency multiple + int sampFreq; + WebRtc_UWord32 seed; + + float mu; // stepsize + float errThresh; // error threshold + + int noiseEstCtr; + + // Toggles for G.167 testing +#ifdef G167 + short adaptToggle; // Filter adaptation + short nlpToggle; // Nonlinear processing + short cnToggle; // Comfort noise +#endif + + power_level_t farlevel; + power_level_t nearlevel; + power_level_t linoutlevel; + power_level_t nlpoutlevel; + + int metricsMode; + int stateCounter; + stats_t erl; + stats_t erle; + stats_t aNlp; + stats_t rerl; + + // Quantities to control H band scaling for SWB input + int freq_avg_ic; //initial bin for averaging nlp gain + int flag_Hband_cn; //for comfort noise + float cn_scale_Hband; //scale for comfort noise in H band + +#ifdef AEC_DEBUG + FILE *farFile; + FILE *nearFile; + FILE *outFile; + FILE *outLpFile; +#endif +} aec_t; + +typedef void (*WebRtcAec_FilterFar_t)(aec_t *aec, float yf[2][PART_LEN1]); +extern WebRtcAec_FilterFar_t WebRtcAec_FilterFar; +typedef void (*WebRtcAec_ScaleErrorSignal_t)(aec_t *aec, float ef[2][PART_LEN1]); +extern WebRtcAec_ScaleErrorSignal_t WebRtcAec_ScaleErrorSignal; +#define IP_LEN PART_LEN // this must be at least ceil(2 + sqrt(PART_LEN)) +#define W_LEN PART_LEN +typedef void (*WebRtcAec_FilterAdaptation_t) + (aec_t *aec, float *fft, float ef[2][PART_LEN1], int ip[IP_LEN], + float wfft[W_LEN]); +extern WebRtcAec_FilterAdaptation_t WebRtcAec_FilterAdaptation; +typedef void (*WebRtcAec_OverdriveAndSuppress_t) + (aec_t *aec, float hNl[PART_LEN1], const float hNlFb, float efw[2][PART_LEN1]); +extern WebRtcAec_OverdriveAndSuppress_t WebRtcAec_OverdriveAndSuppress; + +int WebRtcAec_CreateAec(aec_t **aec); +int WebRtcAec_FreeAec(aec_t *aec); +int WebRtcAec_InitAec(aec_t *aec, int sampFreq); +void WebRtcAec_InitAec_SSE2(void); + +void WebRtcAec_InitMetrics(aec_t *aec); +void WebRtcAec_ProcessFrame(aec_t *aec, const short *farend, + const short *nearend, const short *nearendH, + short *out, short *outH, + int knownDelay); + +// aec_core_rdft.c +void aec_rdft_128(int, float *, int *, float *); + + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_ + diff --git a/src/libs/webrtc/aec/aec_core_rdft.c b/src/libs/webrtc/aec/aec_core_rdft.c new file mode 100644 index 00000000..3f4d3004 --- /dev/null +++ b/src/libs/webrtc/aec/aec_core_rdft.c @@ -0,0 +1,511 @@ +/* + * http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html + * Copyright Takuya OOURA, 1996-2001 + * + * You may use, copy, modify and distribute this code for any purpose (include + * commercial use) and without fee. Please refer to this package when you modify + * this code. + * + * Changes by the WebRTC authors: + * - Trivial type modifications. + * - Minimal code subset to do rdft of length 128. + * - Optimizations because of known length. + * + * All changes are covered by the WebRTC license and IP grant: + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <math.h> + +#include "aec_core.h" + +static void bitrv2_32or128(int n, int *ip, float *a) { + // n is 32 or 128 + int j, j1, k, k1, m, m2; + float xr, xi, yr, yi; + + ip[0] = 0; + { + int l = n; + m = 1; + while ((m << 3) < l) { + l >>= 1; + for (j = 0; j < m; j++) { + ip[m + j] = ip[j] + l; + } + m <<= 1; + } + } + m2 = 2 * m; + for (k = 0; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 2 * j + ip[k]; + k1 = 2 * k + ip[j]; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += 2 * m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 -= m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += 2 * m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + j1 = 2 * k + m2 + ip[k]; + k1 = j1 + m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } +} + +static void makewt(int *ip, float *w) { + const int nw = 32; + int j, nwh; + float delta, x, y; + + ip[0] = nw; + ip[1] = 1; + nwh = nw >> 1; + delta = atanf(1.0f) / nwh; + w[0] = 1; + w[1] = 0; + w[nwh] = cosf(delta * nwh); + w[nwh + 1] = w[nwh]; + for (j = 2; j < nwh; j += 2) { + x = cosf(delta * j); + y = sinf(delta * j); + w[j] = x; + w[j + 1] = y; + w[nw - j] = y; + w[nw - j + 1] = x; + } + bitrv2_32or128(nw, ip + 2, w); +} + +static void makect_32(int *ip, float *c) { + const int nc = 32; + int j, nch; + float delta; + + ip[1] = nc; + nch = nc >> 1; + delta = atanf(1.0f) / nch; + c[0] = cosf(delta * nch); + c[nch] = 0.5f * c[0]; + for (j = 1; j < nch; j++) { + c[j] = 0.5f * cosf(delta * j); + c[nc - j] = 0.5f * sinf(delta * j); + } +} + +static void cft1st_128(float *a, float *w) { + const int n = 128; + int j, k1, k2; + float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + x0r = a[0] + a[2]; + x0i = a[1] + a[3]; + x1r = a[0] - a[2]; + x1i = a[1] - a[3]; + x2r = a[4] + a[6]; + x2i = a[5] + a[7]; + x3r = a[4] - a[6]; + x3i = a[5] - a[7]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[4] = x0r - x2r; + a[5] = x0i - x2i; + a[2] = x1r - x3i; + a[3] = x1i + x3r; + a[6] = x1r + x3i; + a[7] = x1i - x3r; + wk1r = w[2]; + x0r = a[8] + a[10]; + x0i = a[9] + a[11]; + x1r = a[8] - a[10]; + x1i = a[9] - a[11]; + x2r = a[12] + a[14]; + x2i = a[13] + a[15]; + x3r = a[12] - a[14]; + x3i = a[13] - a[15]; + a[8] = x0r + x2r; + a[9] = x0i + x2i; + a[12] = x2i - x0i; + a[13] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[10] = wk1r * (x0r - x0i); + a[11] = wk1r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[14] = wk1r * (x0i - x0r); + a[15] = wk1r * (x0i + x0r); + k1 = 0; + for (j = 16; j < n; j += 16) { + k1 += 2; + k2 = 2 * k1; + wk2r = w[k1]; + wk2i = w[k1 + 1]; + wk1r = w[k2]; + wk1i = w[k2 + 1]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + x0r = a[j] + a[j + 2]; + x0i = a[j + 1] + a[j + 3]; + x1r = a[j] - a[j + 2]; + x1i = a[j + 1] - a[j + 3]; + x2r = a[j + 4] + a[j + 6]; + x2i = a[j + 5] + a[j + 7]; + x3r = a[j + 4] - a[j + 6]; + x3i = a[j + 5] - a[j + 7]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j + 4] = wk2r * x0r - wk2i * x0i; + a[j + 5] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j + 2] = wk1r * x0r - wk1i * x0i; + a[j + 3] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j + 6] = wk3r * x0r - wk3i * x0i; + a[j + 7] = wk3r * x0i + wk3i * x0r; + wk1r = w[k2 + 2]; + wk1i = w[k2 + 3]; + wk3r = wk1r - 2 * wk2r * wk1i; + wk3i = 2 * wk2r * wk1r - wk1i; + x0r = a[j + 8] + a[j + 10]; + x0i = a[j + 9] + a[j + 11]; + x1r = a[j + 8] - a[j + 10]; + x1i = a[j + 9] - a[j + 11]; + x2r = a[j + 12] + a[j + 14]; + x2i = a[j + 13] + a[j + 15]; + x3r = a[j + 12] - a[j + 14]; + x3i = a[j + 13] - a[j + 15]; + a[j + 8] = x0r + x2r; + a[j + 9] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j + 12] = -wk2i * x0r - wk2r * x0i; + a[j + 13] = -wk2i * x0i + wk2r * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j + 10] = wk1r * x0r - wk1i * x0i; + a[j + 11] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j + 14] = wk3r * x0r - wk3i * x0i; + a[j + 15] = wk3r * x0i + wk3i * x0r; + } +} + +static void cftmdl_128(int l, float *a, float *w) { + const int n = 128; + int j, j1, j2, j3, k, k1, k2, m, m2; + float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + m = l << 2; + for (j = 0; j < l; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i - x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + } + wk1r = w[2]; + for (j = m; j < l + m; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x2i - x0i; + a[j2 + 1] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * (x0r - x0i); + a[j1 + 1] = wk1r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[j3] = wk1r * (x0i - x0r); + a[j3 + 1] = wk1r * (x0i + x0r); + } + k1 = 0; + m2 = 2 * m; + for (k = m2; k < n; k += m2) { + k1 += 2; + k2 = 2 * k1; + wk2r = w[k1]; + wk2i = w[k1 + 1]; + wk1r = w[k2]; + wk1i = w[k2 + 1]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for (j = k; j < l + k; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2] = wk2r * x0r - wk2i * x0i; + a[j2 + 1] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * x0r - wk1i * x0i; + a[j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r - wk3i * x0i; + a[j3 + 1] = wk3r * x0i + wk3i * x0r; + } + wk1r = w[k2 + 2]; + wk1i = w[k2 + 3]; + wk3r = wk1r - 2 * wk2r * wk1i; + wk3i = 2 * wk2r * wk1r - wk1i; + for (j = k + m; j < l + (k + m); j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2] = -wk2i * x0r - wk2r * x0i; + a[j2 + 1] = -wk2i * x0i + wk2r * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * x0r - wk1i * x0i; + a[j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r - wk3i * x0i; + a[j3 + 1] = wk3r * x0i + wk3i * x0r; + } + } +} + +static void cftfsub_128(float *a, float *w) { + int j, j1, j2, j3, l; + float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + cft1st_128(a, w); + cftmdl_128(8, a, w); + l = 32; + for (j = 0; j < l; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i - x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + } +} + +static void cftbsub_128(float *a, float *w) { + int j, j1, j2, j3, l; + float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + cft1st_128(a, w); + cftmdl_128(8, a, w); + l = 32; + + for (j = 0; j < l; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = -a[j + 1] - a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = -a[j + 1] + a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i - x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i + x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i - x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i + x3r; + } +} + +static void rftfsub_128(float *a, int nc, float *c) { + const int n = 128; + int j, k, kk, ks, m; + float wkr, wki, xr, xi, yr, yi; + + m = n >> 1; + ks = 2 * nc / m; + kk = 0; + for (j = 2; j < m; j += 2) { + k = n - j; + kk += ks; + wkr = 0.5f - c[nc - kk]; + wki = c[kk]; + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr - wki * xi; + yi = wkr * xi + wki * xr; + a[j] -= yr; + a[j + 1] -= yi; + a[k] += yr; + a[k + 1] -= yi; + } +} + +static void rftbsub_128(float *a, int nc, float *c) { + const int n = 128; + int j, k, kk, ks, m; + float wkr, wki, xr, xi, yr, yi; + + a[1] = -a[1]; + m = n >> 1; + ks = 2 * nc / m; + kk = 0; + for (j = 2; j < m; j += 2) { + k = n - j; + kk += ks; + wkr = 0.5f - c[nc - kk]; + wki = c[kk]; + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr + wki * xi; + yi = wkr * xi - wki * xr; + a[j] -= yr; + a[j + 1] = yi - a[j + 1]; + a[k] += yr; + a[k + 1] = yi - a[k + 1]; + } + a[m + 1] = -a[m + 1]; +} + +void aec_rdft_128(int isgn, float *a, int *ip, float *w) +{ + const int n = 128; + int nw, nc; + float xi; + + nw = ip[0]; + if (n > (nw << 2)) { + nw = n >> 2; + makewt(ip, w); + } + nc = ip[1]; + if (n > (nc << 2)) { + nc = n >> 2; + makect_32(ip, w + nw); + } + if (isgn >= 0) { + bitrv2_32or128(n, ip + 2, a); + cftfsub_128(a, w); + rftfsub_128(a, nc, w + nw); + xi = a[0] - a[1]; + a[0] += a[1]; + a[1] = xi; + } else { + a[1] = 0.5f * (a[0] - a[1]); + a[0] -= a[1]; + rftbsub_128(a, nc, w + nw); + bitrv2_32or128(n, ip + 2, a); + cftbsub_128(a, w); + } +} diff --git a/src/libs/webrtc/aec/aec_core_sse2.c b/src/libs/webrtc/aec/aec_core_sse2.c new file mode 100644 index 00000000..c020e7bb --- /dev/null +++ b/src/libs/webrtc/aec/aec_core_sse2.c @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * The core AEC algorithm, SSE2 version of speed-critical functions. + */ + +#if defined(__SSE2__) +#include <emmintrin.h> +#include <math.h> + +#include "aec_core.h" + +__inline static float MulRe(float aRe, float aIm, float bRe, float bIm) +{ + return aRe * bRe - aIm * bIm; +} + +__inline static float MulIm(float aRe, float aIm, float bRe, float bIm) +{ + return aRe * bIm + aIm * bRe; +} + +static void FilterFarSSE2(aec_t *aec, float yf[2][PART_LEN1]) +{ + int i; + for (i = 0; i < NR_PART; i++) { + int j; + int xPos = (i + aec->xfBufBlockPos) * PART_LEN1; + int pos = i * PART_LEN1; + // Check for wrap + if (i + aec->xfBufBlockPos >= NR_PART) { + xPos -= NR_PART*(PART_LEN1); + } + + // vectorized code (four at once) + for (j = 0; j + 3 < PART_LEN1; j += 4) { + const __m128 xfBuf_re = _mm_loadu_ps(&aec->xfBuf[0][xPos + j]); + const __m128 xfBuf_im = _mm_loadu_ps(&aec->xfBuf[1][xPos + j]); + const __m128 wfBuf_re = _mm_loadu_ps(&aec->wfBuf[0][pos + j]); + const __m128 wfBuf_im = _mm_loadu_ps(&aec->wfBuf[1][pos + j]); + const __m128 yf_re = _mm_loadu_ps(&yf[0][j]); + const __m128 yf_im = _mm_loadu_ps(&yf[1][j]); + const __m128 a = _mm_mul_ps(xfBuf_re, wfBuf_re); + const __m128 b = _mm_mul_ps(xfBuf_im, wfBuf_im); + const __m128 c = _mm_mul_ps(xfBuf_re, wfBuf_im); + const __m128 d = _mm_mul_ps(xfBuf_im, wfBuf_re); + const __m128 e = _mm_sub_ps(a, b); + const __m128 f = _mm_add_ps(c, d); + const __m128 g = _mm_add_ps(yf_re, e); + const __m128 h = _mm_add_ps(yf_im, f); + _mm_storeu_ps(&yf[0][j], g); + _mm_storeu_ps(&yf[1][j], h); + } + // scalar code for the remaining items. + for (; j < PART_LEN1; j++) { + yf[0][j] += MulRe(aec->xfBuf[0][xPos + j], aec->xfBuf[1][xPos + j], + aec->wfBuf[0][ pos + j], aec->wfBuf[1][ pos + j]); + yf[1][j] += MulIm(aec->xfBuf[0][xPos + j], aec->xfBuf[1][xPos + j], + aec->wfBuf[0][ pos + j], aec->wfBuf[1][ pos + j]); + } + } +} + +static void ScaleErrorSignalSSE2(aec_t *aec, float ef[2][PART_LEN1]) +{ + const __m128 k1e_10f = _mm_set1_ps(1e-10f); + const __m128 kThresh = _mm_set1_ps(aec->errThresh); + const __m128 kMu = _mm_set1_ps(aec->mu); + + int i; + // vectorized code (four at once) + for (i = 0; i + 3 < PART_LEN1; i += 4) { + const __m128 xPow = _mm_loadu_ps(&aec->xPow[i]); + const __m128 ef_re_base = _mm_loadu_ps(&ef[0][i]); + const __m128 ef_im_base = _mm_loadu_ps(&ef[1][i]); + + const __m128 xPowPlus = _mm_add_ps(xPow, k1e_10f); + __m128 ef_re = _mm_div_ps(ef_re_base, xPowPlus); + __m128 ef_im = _mm_div_ps(ef_im_base, xPowPlus); + const __m128 ef_re2 = _mm_mul_ps(ef_re, ef_re); + const __m128 ef_im2 = _mm_mul_ps(ef_im, ef_im); + const __m128 ef_sum2 = _mm_add_ps(ef_re2, ef_im2); + const __m128 absEf = _mm_sqrt_ps(ef_sum2); + const __m128 bigger = _mm_cmpgt_ps(absEf, kThresh); + __m128 absEfPlus = _mm_add_ps(absEf, k1e_10f); + const __m128 absEfInv = _mm_div_ps(kThresh, absEfPlus); + __m128 ef_re_if = _mm_mul_ps(ef_re, absEfInv); + __m128 ef_im_if = _mm_mul_ps(ef_im, absEfInv); + ef_re_if = _mm_and_ps(bigger, ef_re_if); + ef_im_if = _mm_and_ps(bigger, ef_im_if); + ef_re = _mm_andnot_ps(bigger, ef_re); + ef_im = _mm_andnot_ps(bigger, ef_im); + ef_re = _mm_or_ps(ef_re, ef_re_if); + ef_im = _mm_or_ps(ef_im, ef_im_if); + ef_re = _mm_mul_ps(ef_re, kMu); + ef_im = _mm_mul_ps(ef_im, kMu); + + _mm_storeu_ps(&ef[0][i], ef_re); + _mm_storeu_ps(&ef[1][i], ef_im); + } + // scalar code for the remaining items. + for (; i < (PART_LEN1); i++) { + float absEf; + ef[0][i] /= (aec->xPow[i] + 1e-10f); + ef[1][i] /= (aec->xPow[i] + 1e-10f); + absEf = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]); + + if (absEf > aec->errThresh) { + absEf = aec->errThresh / (absEf + 1e-10f); + ef[0][i] *= absEf; + ef[1][i] *= absEf; + } + + // Stepsize factor + ef[0][i] *= aec->mu; + ef[1][i] *= aec->mu; + } +} + +static void FilterAdaptationSSE2(aec_t *aec, float *fft, float ef[2][PART_LEN1], + int ip[IP_LEN], float wfft[W_LEN]) { + int i, j; + for (i = 0; i < NR_PART; i++) { + int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1); + int pos = i * PART_LEN1; + // Check for wrap + if (i + aec->xfBufBlockPos >= NR_PART) { + xPos -= NR_PART * PART_LEN1; + } + +#ifdef UNCONSTR + for (j = 0; j < PART_LEN1; j++) { + aec->wfBuf[pos + j][0] += MulRe(aec->xfBuf[xPos + j][0], + -aec->xfBuf[xPos + j][1], + ef[j][0], ef[j][1]); + aec->wfBuf[pos + j][1] += MulIm(aec->xfBuf[xPos + j][0], + -aec->xfBuf[xPos + j][1], + ef[j][0], ef[j][1]); + } +#else + // Process the whole array... + for (j = 0; j < PART_LEN; j+= 4) { + // Load xfBuf and ef. + const __m128 xfBuf_re = _mm_loadu_ps(&aec->xfBuf[0][xPos + j]); + const __m128 xfBuf_im = _mm_loadu_ps(&aec->xfBuf[1][xPos + j]); + const __m128 ef_re = _mm_loadu_ps(&ef[0][j]); + const __m128 ef_im = _mm_loadu_ps(&ef[1][j]); + // Calculate the product of conjugate(xfBuf) by ef. + // re(conjugate(a) * b) = aRe * bRe + aIm * bIm + // im(conjugate(a) * b)= aRe * bIm - aIm * bRe + const __m128 a = _mm_mul_ps(xfBuf_re, ef_re); + const __m128 b = _mm_mul_ps(xfBuf_im, ef_im); + const __m128 c = _mm_mul_ps(xfBuf_re, ef_im); + const __m128 d = _mm_mul_ps(xfBuf_im, ef_re); + const __m128 e = _mm_add_ps(a, b); + const __m128 f = _mm_sub_ps(c, d); + // Interleave real and imaginary parts. + const __m128 g = _mm_unpacklo_ps(e, f); + const __m128 h = _mm_unpackhi_ps(e, f); + // Store + _mm_storeu_ps(&fft[2*j + 0], g); + _mm_storeu_ps(&fft[2*j + 4], h); + } + // ... and fixup the first imaginary entry. + fft[1] = MulRe(aec->xfBuf[0][xPos + PART_LEN], + -aec->xfBuf[1][xPos + PART_LEN], + ef[0][PART_LEN], ef[1][PART_LEN]); + + aec_rdft_128(-1, fft, ip, wfft); + memset(fft + PART_LEN, 0, sizeof(float)*PART_LEN); + + // fft scaling + { + float scale = 2.0f / PART_LEN2; + const __m128 scale_ps = _mm_load_ps1(&scale); + for (j = 0; j < PART_LEN; j+=4) { + const __m128 fft_ps = _mm_loadu_ps(&fft[j]); + const __m128 fft_scale = _mm_mul_ps(fft_ps, scale_ps); + _mm_storeu_ps(&fft[j], fft_scale); + } + } + aec_rdft_128(1, fft, ip, wfft); + + { + float wt1 = aec->wfBuf[1][pos]; + aec->wfBuf[0][pos + PART_LEN] += fft[1]; + for (j = 0; j < PART_LEN; j+= 4) { + __m128 wtBuf_re = _mm_loadu_ps(&aec->wfBuf[0][pos + j]); + __m128 wtBuf_im = _mm_loadu_ps(&aec->wfBuf[1][pos + j]); + const __m128 fft0 = _mm_loadu_ps(&fft[2 * j + 0]); + const __m128 fft4 = _mm_loadu_ps(&fft[2 * j + 4]); + const __m128 fft_re = _mm_shuffle_ps(fft0, fft4, _MM_SHUFFLE(2, 0, 2 ,0)); + const __m128 fft_im = _mm_shuffle_ps(fft0, fft4, _MM_SHUFFLE(3, 1, 3 ,1)); + wtBuf_re = _mm_add_ps(wtBuf_re, fft_re); + wtBuf_im = _mm_add_ps(wtBuf_im, fft_im); + _mm_storeu_ps(&aec->wfBuf[0][pos + j], wtBuf_re); + _mm_storeu_ps(&aec->wfBuf[1][pos + j], wtBuf_im); + } + aec->wfBuf[1][pos] = wt1; + } +#endif // UNCONSTR + } +} + +#ifdef _MSC_VER /* visual c++ */ +# define ALIGN16_BEG __declspec(align(16)) +# define ALIGN16_END +#else /* gcc or icc */ +# define ALIGN16_BEG +# define ALIGN16_END __attribute__((aligned(16))) +#endif + +static __m128 mm_pow_ps(__m128 a, __m128 b) +{ + // a^b = exp2(b * log2(a)) + // exp2(x) and log2(x) are calculated using polynomial approximations. + __m128 log2_a, b_log2_a, a_exp_b; + + // Calculate log2(x), x = a. + { + // To calculate log2(x), we decompose x like this: + // x = y * 2^n + // n is an integer + // y is in the [1.0, 2.0) range + // + // log2(x) = log2(y) + n + // n can be evaluated by playing with float representation. + // log2(y) in a small range can be approximated, this code uses an order + // five polynomial approximation. The coefficients have been + // estimated with the Remez algorithm and the resulting + // polynomial has a maximum relative error of 0.00086%. + + // Compute n. + // This is done by masking the exponent, shifting it into the top bit of + // the mantissa, putting eight into the biased exponent (to shift/ + // compensate the fact that the exponent has been shifted in the top/ + // fractional part and finally getting rid of the implicit leading one + // from the mantissa by substracting it out. + static const ALIGN16_BEG int float_exponent_mask[4] ALIGN16_END = + {0x7F800000, 0x7F800000, 0x7F800000, 0x7F800000}; + static const ALIGN16_BEG int eight_biased_exponent[4] ALIGN16_END = + {0x43800000, 0x43800000, 0x43800000, 0x43800000}; + static const ALIGN16_BEG int implicit_leading_one[4] ALIGN16_END = + {0x43BF8000, 0x43BF8000, 0x43BF8000, 0x43BF8000}; + static const int shift_exponent_into_top_mantissa = 8; + const __m128 two_n = _mm_and_ps(a, *((__m128 *)float_exponent_mask)); + const __m128 n_1 = (__m128)_mm_srli_epi32((__m128i)two_n, + shift_exponent_into_top_mantissa); + const __m128 n_0 = _mm_or_ps( + (__m128)n_1, *((__m128 *)eight_biased_exponent)); + const __m128 n = _mm_sub_ps(n_0, *((__m128 *)implicit_leading_one)); + + // Compute y. + static const ALIGN16_BEG int mantissa_mask[4] ALIGN16_END = + {0x007FFFFF, 0x007FFFFF, 0x007FFFFF, 0x007FFFFF}; + static const ALIGN16_BEG int zero_biased_exponent_is_one[4] ALIGN16_END = + {0x3F800000, 0x3F800000, 0x3F800000, 0x3F800000}; + const __m128 mantissa = _mm_and_ps(a, *((__m128 *)mantissa_mask)); + const __m128 y = _mm_or_ps( + mantissa, *((__m128 *)zero_biased_exponent_is_one)); + + // Approximate log2(y) ~= (y - 1) * pol5(y). + // pol5(y) = C5 * y^5 + C4 * y^4 + C3 * y^3 + C2 * y^2 + C1 * y + C0 + static const ALIGN16_BEG float ALIGN16_END C5[4] = + {-3.4436006e-2f, -3.4436006e-2f, -3.4436006e-2f, -3.4436006e-2f}; + static const ALIGN16_BEG float ALIGN16_END C4[4] = + {3.1821337e-1f, 3.1821337e-1f, 3.1821337e-1f, 3.1821337e-1f}; + static const ALIGN16_BEG float ALIGN16_END C3[4] = + {-1.2315303f, -1.2315303f, -1.2315303f, -1.2315303f}; + static const ALIGN16_BEG float ALIGN16_END C2[4] = + {2.5988452f, 2.5988452f, 2.5988452f, 2.5988452f}; + static const ALIGN16_BEG float ALIGN16_END C1[4] = + {-3.3241990f, -3.3241990f, -3.3241990f, -3.3241990f}; + static const ALIGN16_BEG float ALIGN16_END C0[4] = + {3.1157899f, 3.1157899f, 3.1157899f, 3.1157899f}; + const __m128 pol5_y_0 = _mm_mul_ps(y, *((__m128 *)C5)); + const __m128 pol5_y_1 = _mm_add_ps(pol5_y_0, *((__m128 *)C4)); + const __m128 pol5_y_2 = _mm_mul_ps(pol5_y_1, y); + const __m128 pol5_y_3 = _mm_add_ps(pol5_y_2, *((__m128 *)C3)); + const __m128 pol5_y_4 = _mm_mul_ps(pol5_y_3, y); + const __m128 pol5_y_5 = _mm_add_ps(pol5_y_4, *((__m128 *)C2)); + const __m128 pol5_y_6 = _mm_mul_ps(pol5_y_5, y); + const __m128 pol5_y_7 = _mm_add_ps(pol5_y_6, *((__m128 *)C1)); + const __m128 pol5_y_8 = _mm_mul_ps(pol5_y_7, y); + const __m128 pol5_y = _mm_add_ps(pol5_y_8, *((__m128 *)C0)); + const __m128 y_minus_one = _mm_sub_ps( + y, *((__m128 *)zero_biased_exponent_is_one)); + const __m128 log2_y = _mm_mul_ps(y_minus_one , pol5_y); + + // Combine parts. + log2_a = _mm_add_ps(n, log2_y); + } + + // b * log2(a) + b_log2_a = _mm_mul_ps(b, log2_a); + + // Calculate exp2(x), x = b * log2(a). + { + // To calculate 2^x, we decompose x like this: + // x = n + y + // n is an integer, the value of x - 0.5 rounded down, therefore + // y is in the [0.5, 1.5) range + // + // 2^x = 2^n * 2^y + // 2^n can be evaluated by playing with float representation. + // 2^y in a small range can be approximated, this code uses an order two + // polynomial approximation. The coefficients have been estimated + // with the Remez algorithm and the resulting polynomial has a + // maximum relative error of 0.17%. + + // To avoid over/underflow, we reduce the range of input to ]-127, 129]. + static const ALIGN16_BEG float max_input[4] ALIGN16_END = + {129.f, 129.f, 129.f, 129.f}; + static const ALIGN16_BEG float min_input[4] ALIGN16_END = + {-126.99999f, -126.99999f, -126.99999f, -126.99999f}; + const __m128 x_min = _mm_min_ps(b_log2_a, *((__m128 *)max_input)); + const __m128 x_max = _mm_max_ps(x_min, *((__m128 *)min_input)); + // Compute n. + static const ALIGN16_BEG float half[4] ALIGN16_END = + {0.5f, 0.5f, 0.5f, 0.5f}; + const __m128 x_minus_half = _mm_sub_ps(x_max, *((__m128 *)half)); + const __m128i x_minus_half_floor = _mm_cvtps_epi32(x_minus_half); + // Compute 2^n. + static const ALIGN16_BEG int float_exponent_bias[4] ALIGN16_END = + {127, 127, 127, 127}; + static const int float_exponent_shift = 23; + const __m128i two_n_exponent = _mm_add_epi32( + x_minus_half_floor, *((__m128i *)float_exponent_bias)); + const __m128 two_n = (__m128)_mm_slli_epi32( + two_n_exponent, float_exponent_shift); + // Compute y. + const __m128 y = _mm_sub_ps(x_max, _mm_cvtepi32_ps(x_minus_half_floor)); + // Approximate 2^y ~= C2 * y^2 + C1 * y + C0. + static const ALIGN16_BEG float C2[4] ALIGN16_END = + {3.3718944e-1f, 3.3718944e-1f, 3.3718944e-1f, 3.3718944e-1f}; + static const ALIGN16_BEG float C1[4] ALIGN16_END = + {6.5763628e-1f, 6.5763628e-1f, 6.5763628e-1f, 6.5763628e-1f}; + static const ALIGN16_BEG float C0[4] ALIGN16_END = + {1.0017247f, 1.0017247f, 1.0017247f, 1.0017247f}; + const __m128 exp2_y_0 = _mm_mul_ps(y, *((__m128 *)C2)); + const __m128 exp2_y_1 = _mm_add_ps(exp2_y_0, *((__m128 *)C1)); + const __m128 exp2_y_2 = _mm_mul_ps(exp2_y_1, y); + const __m128 exp2_y = _mm_add_ps(exp2_y_2, *((__m128 *)C0)); + + // Combine parts. + a_exp_b = _mm_mul_ps(exp2_y, two_n); + } + return a_exp_b; +} + +extern const float WebRtcAec_weightCurve[65]; +extern const float WebRtcAec_overDriveCurve[65]; + +static void OverdriveAndSuppressSSE2(aec_t *aec, float hNl[PART_LEN1], + const float hNlFb, + float efw[2][PART_LEN1]) { + int i; + const __m128 vec_hNlFb = _mm_set1_ps(hNlFb); + const __m128 vec_one = _mm_set1_ps(1.0f); + const __m128 vec_minus_one = _mm_set1_ps(-1.0f); + const __m128 vec_overDriveSm = _mm_set1_ps(aec->overDriveSm); + // vectorized code (four at once) + for (i = 0; i + 3 < PART_LEN1; i+=4) { + // Weight subbands + __m128 vec_hNl = _mm_loadu_ps(&hNl[i]); + const __m128 vec_weightCurve = _mm_loadu_ps(&WebRtcAec_weightCurve[i]); + const __m128 bigger = _mm_cmpgt_ps(vec_hNl, vec_hNlFb); + const __m128 vec_weightCurve_hNlFb = _mm_mul_ps( + vec_weightCurve, vec_hNlFb); + const __m128 vec_one_weightCurve = _mm_sub_ps(vec_one, vec_weightCurve); + const __m128 vec_one_weightCurve_hNl = _mm_mul_ps( + vec_one_weightCurve, vec_hNl); + const __m128 vec_if0 = _mm_andnot_ps(bigger, vec_hNl); + const __m128 vec_if1 = _mm_and_ps( + bigger, _mm_add_ps(vec_weightCurve_hNlFb, vec_one_weightCurve_hNl)); + vec_hNl = _mm_or_ps(vec_if0, vec_if1); + + { + const __m128 vec_overDriveCurve = _mm_loadu_ps( + &WebRtcAec_overDriveCurve[i]); + const __m128 vec_overDriveSm_overDriveCurve = _mm_mul_ps( + vec_overDriveSm, vec_overDriveCurve); + vec_hNl = mm_pow_ps(vec_hNl, vec_overDriveSm_overDriveCurve); + _mm_storeu_ps(&hNl[i], vec_hNl); + } + + // Suppress error signal + { + __m128 vec_efw_re = _mm_loadu_ps(&efw[0][i]); + __m128 vec_efw_im = _mm_loadu_ps(&efw[1][i]); + vec_efw_re = _mm_mul_ps(vec_efw_re, vec_hNl); + vec_efw_im = _mm_mul_ps(vec_efw_im, vec_hNl); + + // Ooura fft returns incorrect sign on imaginary component. It matters + // here because we are making an additive change with comfort noise. + vec_efw_im = _mm_mul_ps(vec_efw_im, vec_minus_one); + _mm_storeu_ps(&efw[0][i], vec_efw_re); + _mm_storeu_ps(&efw[1][i], vec_efw_im); + } + } + // scalar code for the remaining items. + for (; i < PART_LEN1; i++) { + // Weight subbands + if (hNl[i] > hNlFb) { + hNl[i] = WebRtcAec_weightCurve[i] * hNlFb + + (1 - WebRtcAec_weightCurve[i]) * hNl[i]; + } + hNl[i] = powf(hNl[i], aec->overDriveSm * WebRtcAec_overDriveCurve[i]); + + // Suppress error signal + efw[0][i] *= hNl[i]; + efw[1][i] *= hNl[i]; + + // Ooura fft returns incorrect sign on imaginary component. It matters + // here because we are making an additive change with comfort noise. + efw[1][i] *= -1; + } +} + +void WebRtcAec_InitAec_SSE2(void) { + WebRtcAec_FilterFar = FilterFarSSE2; + WebRtcAec_ScaleErrorSignal = ScaleErrorSignalSSE2; + WebRtcAec_FilterAdaptation = FilterAdaptationSSE2; + WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppressSSE2; +} + +#endif //__SSE2__ diff --git a/src/libs/webrtc/aec/echo_cancellation.c b/src/libs/webrtc/aec/echo_cancellation.c new file mode 100644 index 00000000..1313e358 --- /dev/null +++ b/src/libs/webrtc/aec/echo_cancellation.c @@ -0,0 +1,821 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Contains the API functions for the AEC. + */ +#include <stdlib.h> +#include <string.h> + +#include "echo_cancellation.h" +#include "aec_core.h" +#include "ring_buffer.h" +#include "resampler.h" +#ifdef AEC_DEBUG + #include <stdio.h> +#endif + +#define BUF_SIZE_FRAMES 50 // buffer size (frames) +// Maximum length of resampled signal. Must be an integer multiple of frames +// (ceil(1/(1 + MIN_SKEW)*2) + 1)*FRAME_LEN +// The factor of 2 handles wb, and the + 1 is as a safety margin +#define MAX_RESAMP_LEN (5 * FRAME_LEN) + +static const int bufSizeSamp = BUF_SIZE_FRAMES * FRAME_LEN; // buffer size (samples) +static const int sampMsNb = 8; // samples per ms in nb +// Target suppression levels for nlp modes +// log{0.001, 0.00001, 0.00000001} +static const float targetSupp[3] = {-6.9f, -11.5f, -18.4f}; +static const float minOverDrive[3] = {1.0f, 2.0f, 5.0f}; +static const int initCheck = 42; + +typedef struct { + int delayCtr; + int sampFreq; + int splitSampFreq; + int scSampFreq; + float sampFactor; // scSampRate / sampFreq + short nlpMode; + short autoOnOff; + short activity; + short skewMode; + short bufSizeStart; + //short bufResetCtr; // counts number of noncausal frames + int knownDelay; + + // Stores the last frame added to the farend buffer + short farendOld[2][FRAME_LEN]; + short initFlag; // indicates if AEC has been initialized + + // Variables used for averaging far end buffer size + short counter; + short sum; + short firstVal; + short checkBufSizeCtr; + + // Variables used for delay shifts + short msInSndCardBuf; + short filtDelay; + int timeForDelayChange; + int ECstartup; + int checkBuffSize; + int delayChange; + short lastDelayDiff; + +#ifdef AEC_DEBUG + FILE *bufFile; + FILE *delayFile; + FILE *skewFile; + FILE *preCompFile; + FILE *postCompFile; +#endif // AEC_DEBUG + + // Structures + void *farendBuf; + void *resampler; + + int skewFrCtr; + int resample; // if the skew is small enough we don't resample + int highSkewCtr; + float skew; + + int lastError; + + aec_t *aec; +} aecpc_t; + +// Estimates delay to set the position of the farend buffer read pointer +// (controlled by knownDelay) +static int EstBufDelay(aecpc_t *aecInst, short msInSndCardBuf); + +// Stuffs the farend buffer if the estimated delay is too large +static int DelayComp(aecpc_t *aecInst); + +WebRtc_Word32 WebRtcAec_Create(void **aecInst) +{ + aecpc_t *aecpc; + if (aecInst == NULL) { + return -1; + } + + aecpc = malloc(sizeof(aecpc_t)); + *aecInst = aecpc; + if (aecpc == NULL) { + return -1; + } + + if (WebRtcAec_CreateAec(&aecpc->aec) == -1) { + WebRtcAec_Free(aecpc); + aecpc = NULL; + return -1; + } + + if (WebRtcApm_CreateBuffer(&aecpc->farendBuf, bufSizeSamp) == -1) { + WebRtcAec_Free(aecpc); + aecpc = NULL; + return -1; + } + + if (WebRtcAec_CreateResampler(&aecpc->resampler) == -1) { + WebRtcAec_Free(aecpc); + aecpc = NULL; + return -1; + } + + aecpc->initFlag = 0; + aecpc->lastError = 0; + +#ifdef AEC_DEBUG + aecpc->aec->farFile = fopen("aecFar.pcm","wb"); + aecpc->aec->nearFile = fopen("aecNear.pcm","wb"); + aecpc->aec->outFile = fopen("aecOut.pcm","wb"); + aecpc->aec->outLpFile = fopen("aecOutLp.pcm","wb"); + + aecpc->bufFile = fopen("aecBuf.dat", "wb"); + aecpc->skewFile = fopen("aecSkew.dat", "wb"); + aecpc->delayFile = fopen("aecDelay.dat", "wb"); + aecpc->preCompFile = fopen("preComp.pcm", "wb"); + aecpc->postCompFile = fopen("postComp.pcm", "wb"); +#endif // AEC_DEBUG + + return 0; +} + +WebRtc_Word32 WebRtcAec_Free(void *aecInst) +{ + aecpc_t *aecpc = aecInst; + + if (aecpc == NULL) { + return -1; + } + +#ifdef AEC_DEBUG + fclose(aecpc->aec->farFile); + fclose(aecpc->aec->nearFile); + fclose(aecpc->aec->outFile); + fclose(aecpc->aec->outLpFile); + + fclose(aecpc->bufFile); + fclose(aecpc->skewFile); + fclose(aecpc->delayFile); + fclose(aecpc->preCompFile); + fclose(aecpc->postCompFile); +#endif // AEC_DEBUG + + WebRtcAec_FreeAec(aecpc->aec); + WebRtcApm_FreeBuffer(aecpc->farendBuf); + WebRtcAec_FreeResampler(aecpc->resampler); + free(aecpc); + + return 0; +} + +WebRtc_Word32 WebRtcAec_Init(void *aecInst, WebRtc_Word32 sampFreq, WebRtc_Word32 scSampFreq) +{ + aecpc_t *aecpc = aecInst; + AecConfig aecConfig; + + if (aecpc == NULL) { + return -1; + } + + if (sampFreq != 8000 && sampFreq != 16000 && sampFreq != 32000) { + aecpc->lastError = AEC_BAD_PARAMETER_ERROR; + return -1; + } + aecpc->sampFreq = sampFreq; + + if (scSampFreq < 1 || scSampFreq > 96000) { + aecpc->lastError = AEC_BAD_PARAMETER_ERROR; + return -1; + } + aecpc->scSampFreq = scSampFreq; + + // Initialize echo canceller core + if (WebRtcAec_InitAec(aecpc->aec, aecpc->sampFreq) == -1) { + aecpc->lastError = AEC_UNSPECIFIED_ERROR; + return -1; + } + + // Initialize farend buffer + if (WebRtcApm_InitBuffer(aecpc->farendBuf) == -1) { + aecpc->lastError = AEC_UNSPECIFIED_ERROR; + return -1; + } + + if (WebRtcAec_InitResampler(aecpc->resampler, aecpc->scSampFreq) == -1) { + aecpc->lastError = AEC_UNSPECIFIED_ERROR; + return -1; + } + + aecpc->initFlag = initCheck; // indicates that initilisation has been done + + if (aecpc->sampFreq == 32000) { + aecpc->splitSampFreq = 16000; + } + else { + aecpc->splitSampFreq = sampFreq; + } + + aecpc->skewFrCtr = 0; + aecpc->activity = 0; + + aecpc->delayChange = 1; + aecpc->delayCtr = 0; + + aecpc->sum = 0; + aecpc->counter = 0; + aecpc->checkBuffSize = 1; + aecpc->firstVal = 0; + + aecpc->ECstartup = 1; + aecpc->bufSizeStart = 0; + aecpc->checkBufSizeCtr = 0; + aecpc->filtDelay = 0; + aecpc->timeForDelayChange =0; + aecpc->knownDelay = 0; + aecpc->lastDelayDiff = 0; + + aecpc->skew = 0; + aecpc->resample = kAecFalse; + aecpc->highSkewCtr = 0; + aecpc->sampFactor = (aecpc->scSampFreq * 1.0f) / aecpc->splitSampFreq; + + memset(&aecpc->farendOld[0][0], 0, 160); + + // Default settings. + aecConfig.nlpMode = kAecNlpModerate; + aecConfig.skewMode = kAecFalse; + aecConfig.metricsMode = kAecFalse; + + if (WebRtcAec_set_config(aecpc, aecConfig) == -1) { + aecpc->lastError = AEC_UNSPECIFIED_ERROR; + return -1; + } + + return 0; +} + +// only buffer L band for farend +WebRtc_Word32 WebRtcAec_BufferFarend(void *aecInst, const WebRtc_Word16 *farend, + WebRtc_Word16 nrOfSamples) +{ + aecpc_t *aecpc = aecInst; + WebRtc_Word32 retVal = 0; + short newNrOfSamples; + short newFarend[MAX_RESAMP_LEN]; + float skew; + + if (aecpc == NULL) { + return -1; + } + + if (farend == NULL) { + aecpc->lastError = AEC_NULL_POINTER_ERROR; + return -1; + } + + if (aecpc->initFlag != initCheck) { + aecpc->lastError = AEC_UNINITIALIZED_ERROR; + return -1; + } + + // number of samples == 160 for SWB input + if (nrOfSamples != 80 && nrOfSamples != 160) { + aecpc->lastError = AEC_BAD_PARAMETER_ERROR; + return -1; + } + + skew = aecpc->skew; + + // TODO: Is this really a good idea? + if (!aecpc->ECstartup) { + DelayComp(aecpc); + } + + if (aecpc->skewMode == kAecTrue && aecpc->resample == kAecTrue) { + // Resample and get a new number of samples + newNrOfSamples = WebRtcAec_ResampleLinear(aecpc->resampler, + farend, + nrOfSamples, + skew, + newFarend); + WebRtcApm_WriteBuffer(aecpc->farendBuf, newFarend, newNrOfSamples); + +#ifdef AEC_DEBUG + fwrite(farend, 2, nrOfSamples, aecpc->preCompFile); + fwrite(newFarend, 2, newNrOfSamples, aecpc->postCompFile); +#endif + } + else { + WebRtcApm_WriteBuffer(aecpc->farendBuf, farend, nrOfSamples); + } + + return retVal; +} + +WebRtc_Word32 WebRtcAec_Process(void *aecInst, const WebRtc_Word16 *nearend, + const WebRtc_Word16 *nearendH, WebRtc_Word16 *out, WebRtc_Word16 *outH, + WebRtc_Word16 nrOfSamples, WebRtc_Word16 msInSndCardBuf, WebRtc_Word32 skew) +{ + aecpc_t *aecpc = aecInst; + WebRtc_Word32 retVal = 0; + short i; + short farend[FRAME_LEN]; + short nmbrOfFilledBuffers; + short nBlocks10ms; + short nFrames; +#ifdef AEC_DEBUG + short msInAECBuf; +#endif + // Limit resampling to doubling/halving of signal + const float minSkewEst = -0.5f; + const float maxSkewEst = 1.0f; + + if (aecpc == NULL) { + return -1; + } + + if (nearend == NULL) { + aecpc->lastError = AEC_NULL_POINTER_ERROR; + return -1; + } + + if (out == NULL) { + aecpc->lastError = AEC_NULL_POINTER_ERROR; + return -1; + } + + if (aecpc->initFlag != initCheck) { + aecpc->lastError = AEC_UNINITIALIZED_ERROR; + return -1; + } + + // number of samples == 160 for SWB input + if (nrOfSamples != 80 && nrOfSamples != 160) { + aecpc->lastError = AEC_BAD_PARAMETER_ERROR; + return -1; + } + + // Check for valid pointers based on sampling rate + if (aecpc->sampFreq == 32000 && nearendH == NULL) { + aecpc->lastError = AEC_NULL_POINTER_ERROR; + return -1; + } + + if (msInSndCardBuf < 0) { + msInSndCardBuf = 0; + aecpc->lastError = AEC_BAD_PARAMETER_WARNING; + retVal = -1; + } + else if (msInSndCardBuf > 500) { + msInSndCardBuf = 500; + aecpc->lastError = AEC_BAD_PARAMETER_WARNING; + retVal = -1; + } + msInSndCardBuf += 10; + aecpc->msInSndCardBuf = msInSndCardBuf; + + if (aecpc->skewMode == kAecTrue) { + if (aecpc->skewFrCtr < 25) { + aecpc->skewFrCtr++; + } + else { + retVal = WebRtcAec_GetSkew(aecpc->resampler, skew, &aecpc->skew); + if (retVal == -1) { + aecpc->skew = 0; + aecpc->lastError = AEC_BAD_PARAMETER_WARNING; + } + + aecpc->skew /= aecpc->sampFactor*nrOfSamples; + + if (aecpc->skew < 1.0e-3 && aecpc->skew > -1.0e-3) { + aecpc->resample = kAecFalse; + } + else { + aecpc->resample = kAecTrue; + } + + if (aecpc->skew < minSkewEst) { + aecpc->skew = minSkewEst; + } + else if (aecpc->skew > maxSkewEst) { + aecpc->skew = maxSkewEst; + } + +#ifdef AEC_DEBUG + fwrite(&aecpc->skew, sizeof(aecpc->skew), 1, aecpc->skewFile); +#endif + } + } + + nFrames = nrOfSamples / FRAME_LEN; + nBlocks10ms = nFrames / aecpc->aec->mult; + + if (aecpc->ECstartup) { + memcpy(out, nearend, sizeof(short) * nrOfSamples); + nmbrOfFilledBuffers = WebRtcApm_get_buffer_size(aecpc->farendBuf) / FRAME_LEN; + + // The AEC is in the start up mode + // AEC is disabled until the soundcard buffer and farend buffers are OK + + // Mechanism to ensure that the soundcard buffer is reasonably stable. + if (aecpc->checkBuffSize) { + + aecpc->checkBufSizeCtr++; + // Before we fill up the far end buffer we require the amount of data on the + // sound card to be stable (+/-8 ms) compared to the first value. This + // comparison is made during the following 4 consecutive frames. If it seems + // to be stable then we start to fill up the far end buffer. + + if (aecpc->counter == 0) { + aecpc->firstVal = aecpc->msInSndCardBuf; + aecpc->sum = 0; + } + + if (abs(aecpc->firstVal - aecpc->msInSndCardBuf) < + WEBRTC_SPL_MAX(0.2 * aecpc->msInSndCardBuf, sampMsNb)) { + aecpc->sum += aecpc->msInSndCardBuf; + aecpc->counter++; + } + else { + aecpc->counter = 0; + } + + if (aecpc->counter*nBlocks10ms >= 6) { + // The farend buffer size is determined in blocks of 80 samples + // Use 75% of the average value of the soundcard buffer + aecpc->bufSizeStart = WEBRTC_SPL_MIN((int) (0.75 * (aecpc->sum * + aecpc->aec->mult) / (aecpc->counter * 10)), BUF_SIZE_FRAMES); + // buffersize has now been determined + aecpc->checkBuffSize = 0; + } + + if (aecpc->checkBufSizeCtr * nBlocks10ms > 50) { + // for really bad sound cards, don't disable echocanceller for more than 0.5 sec + aecpc->bufSizeStart = WEBRTC_SPL_MIN((int) (0.75 * (aecpc->msInSndCardBuf * + aecpc->aec->mult) / 10), BUF_SIZE_FRAMES); + aecpc->checkBuffSize = 0; + } + } + + // if checkBuffSize changed in the if-statement above + if (!aecpc->checkBuffSize) { + // soundcard buffer is now reasonably stable + // When the far end buffer is filled with approximately the same amount of + // data as the amount on the sound card we end the start up phase and start + // to cancel echoes. + + if (nmbrOfFilledBuffers == aecpc->bufSizeStart) { + aecpc->ECstartup = 0; // Enable the AEC + } + else if (nmbrOfFilledBuffers > aecpc->bufSizeStart) { + WebRtcApm_FlushBuffer(aecpc->farendBuf, WebRtcApm_get_buffer_size(aecpc->farendBuf) - + aecpc->bufSizeStart * FRAME_LEN); + aecpc->ECstartup = 0; + } + } + + } + else { + // AEC is enabled + + // Note only 1 block supported for nb and 2 blocks for wb + for (i = 0; i < nFrames; i++) { + nmbrOfFilledBuffers = WebRtcApm_get_buffer_size(aecpc->farendBuf) / FRAME_LEN; + + // Check that there is data in the far end buffer + if (nmbrOfFilledBuffers > 0) { + // Get the next 80 samples from the farend buffer + WebRtcApm_ReadBuffer(aecpc->farendBuf, farend, FRAME_LEN); + + // Always store the last frame for use when we run out of data + memcpy(&(aecpc->farendOld[i][0]), farend, FRAME_LEN * sizeof(short)); + } + else { + // We have no data so we use the last played frame + memcpy(farend, &(aecpc->farendOld[i][0]), FRAME_LEN * sizeof(short)); + } + + // Call buffer delay estimator when all data is extracted, + // i.e. i = 0 for NB and i = 1 for WB or SWB + if ((i == 0 && aecpc->splitSampFreq == 8000) || + (i == 1 && (aecpc->splitSampFreq == 16000))) { + EstBufDelay(aecpc, aecpc->msInSndCardBuf); + } + + // Call the AEC + WebRtcAec_ProcessFrame(aecpc->aec, farend, &nearend[FRAME_LEN * i], &nearendH[FRAME_LEN * i], + &out[FRAME_LEN * i], &outH[FRAME_LEN * i], aecpc->knownDelay); + } + } + +#ifdef AEC_DEBUG + msInAECBuf = WebRtcApm_get_buffer_size(aecpc->farendBuf) / (sampMsNb*aecpc->aec->mult); + fwrite(&msInAECBuf, 2, 1, aecpc->bufFile); + fwrite(&(aecpc->knownDelay), sizeof(aecpc->knownDelay), 1, aecpc->delayFile); +#endif + + return retVal; +} + +WebRtc_Word32 WebRtcAec_set_config(void *aecInst, AecConfig config) +{ + aecpc_t *aecpc = aecInst; + + if (aecpc == NULL) { + return -1; + } + + if (aecpc->initFlag != initCheck) { + aecpc->lastError = AEC_UNINITIALIZED_ERROR; + return -1; + } + + if (config.skewMode != kAecFalse && config.skewMode != kAecTrue) { + aecpc->lastError = AEC_BAD_PARAMETER_ERROR; + return -1; + } + aecpc->skewMode = config.skewMode; + + if (config.nlpMode != kAecNlpConservative && config.nlpMode != + kAecNlpModerate && config.nlpMode != kAecNlpAggressive) { + aecpc->lastError = AEC_BAD_PARAMETER_ERROR; + return -1; + } + aecpc->nlpMode = config.nlpMode; + aecpc->aec->targetSupp = targetSupp[aecpc->nlpMode]; + aecpc->aec->minOverDrive = minOverDrive[aecpc->nlpMode]; + + if (config.metricsMode != kAecFalse && config.metricsMode != kAecTrue) { + aecpc->lastError = AEC_BAD_PARAMETER_ERROR; + return -1; + } + aecpc->aec->metricsMode = config.metricsMode; + if (aecpc->aec->metricsMode == kAecTrue) { + WebRtcAec_InitMetrics(aecpc->aec); + } + + return 0; +} + +WebRtc_Word32 WebRtcAec_get_config(void *aecInst, AecConfig *config) +{ + aecpc_t *aecpc = aecInst; + + if (aecpc == NULL) { + return -1; + } + + if (config == NULL) { + aecpc->lastError = AEC_NULL_POINTER_ERROR; + return -1; + } + + if (aecpc->initFlag != initCheck) { + aecpc->lastError = AEC_UNINITIALIZED_ERROR; + return -1; + } + + config->nlpMode = aecpc->nlpMode; + config->skewMode = aecpc->skewMode; + config->metricsMode = aecpc->aec->metricsMode; + + return 0; +} + +WebRtc_Word32 WebRtcAec_get_echo_status(void *aecInst, WebRtc_Word16 *status) +{ + aecpc_t *aecpc = aecInst; + + if (aecpc == NULL) { + return -1; + } + + if (status == NULL) { + aecpc->lastError = AEC_NULL_POINTER_ERROR; + return -1; + } + + if (aecpc->initFlag != initCheck) { + aecpc->lastError = AEC_UNINITIALIZED_ERROR; + return -1; + } + + *status = aecpc->aec->echoState; + + return 0; +} + +WebRtc_Word32 WebRtcAec_GetMetrics(void *aecInst, AecMetrics *metrics) +{ + const float upweight = 0.7f; + float dtmp; + short stmp; + aecpc_t *aecpc = aecInst; + + if (aecpc == NULL) { + return -1; + } + + if (metrics == NULL) { + aecpc->lastError = AEC_NULL_POINTER_ERROR; + return -1; + } + + if (aecpc->initFlag != initCheck) { + aecpc->lastError = AEC_UNINITIALIZED_ERROR; + return -1; + } + + // ERL + metrics->erl.instant = (short) aecpc->aec->erl.instant; + + if ((aecpc->aec->erl.himean > offsetLevel) && (aecpc->aec->erl.average > offsetLevel)) { + // Use a mix between regular average and upper part average + dtmp = upweight * aecpc->aec->erl.himean + (1 - upweight) * aecpc->aec->erl.average; + metrics->erl.average = (short) dtmp; + } + else { + metrics->erl.average = offsetLevel; + } + + metrics->erl.max = (short) aecpc->aec->erl.max; + + if (aecpc->aec->erl.min < (offsetLevel * (-1))) { + metrics->erl.min = (short) aecpc->aec->erl.min; + } + else { + metrics->erl.min = offsetLevel; + } + + // ERLE + metrics->erle.instant = (short) aecpc->aec->erle.instant; + + if ((aecpc->aec->erle.himean > offsetLevel) && (aecpc->aec->erle.average > offsetLevel)) { + // Use a mix between regular average and upper part average + dtmp = upweight * aecpc->aec->erle.himean + (1 - upweight) * aecpc->aec->erle.average; + metrics->erle.average = (short) dtmp; + } + else { + metrics->erle.average = offsetLevel; + } + + metrics->erle.max = (short) aecpc->aec->erle.max; + + if (aecpc->aec->erle.min < (offsetLevel * (-1))) { + metrics->erle.min = (short) aecpc->aec->erle.min; + } else { + metrics->erle.min = offsetLevel; + } + + // RERL + if ((metrics->erl.average > offsetLevel) && (metrics->erle.average > offsetLevel)) { + stmp = metrics->erl.average + metrics->erle.average; + } + else { + stmp = offsetLevel; + } + metrics->rerl.average = stmp; + + // No other statistics needed, but returned for completeness + metrics->rerl.instant = stmp; + metrics->rerl.max = stmp; + metrics->rerl.min = stmp; + + // A_NLP + metrics->aNlp.instant = (short) aecpc->aec->aNlp.instant; + + if ((aecpc->aec->aNlp.himean > offsetLevel) && (aecpc->aec->aNlp.average > offsetLevel)) { + // Use a mix between regular average and upper part average + dtmp = upweight * aecpc->aec->aNlp.himean + (1 - upweight) * aecpc->aec->aNlp.average; + metrics->aNlp.average = (short) dtmp; + } + else { + metrics->aNlp.average = offsetLevel; + } + + metrics->aNlp.max = (short) aecpc->aec->aNlp.max; + + if (aecpc->aec->aNlp.min < (offsetLevel * (-1))) { + metrics->aNlp.min = (short) aecpc->aec->aNlp.min; + } + else { + metrics->aNlp.min = offsetLevel; + } + + return 0; +} + +WebRtc_Word32 WebRtcAec_get_version(WebRtc_Word8 *versionStr, WebRtc_Word16 len) +{ + const char version[] = "AEC 2.5.0"; + const short versionLen = (short)strlen(version) + 1; // +1 for null-termination + + if (versionStr == NULL) { + return -1; + } + + if (versionLen > len) { + return -1; + } + + strncpy(versionStr, version, versionLen); + return 0; +} + +WebRtc_Word32 WebRtcAec_get_error_code(void *aecInst) +{ + aecpc_t *aecpc = aecInst; + + if (aecpc == NULL) { + return -1; + } + + return aecpc->lastError; +} + +static int EstBufDelay(aecpc_t *aecpc, short msInSndCardBuf) +{ + short delayNew, nSampFar, nSampSndCard; + short diff; + + nSampFar = WebRtcApm_get_buffer_size(aecpc->farendBuf); + nSampSndCard = msInSndCardBuf * sampMsNb * aecpc->aec->mult; + + delayNew = nSampSndCard - nSampFar; + + // Account for resampling frame delay + if (aecpc->skewMode == kAecTrue && aecpc->resample == kAecTrue) { + delayNew -= kResamplingDelay; + } + + if (delayNew < FRAME_LEN) { + WebRtcApm_FlushBuffer(aecpc->farendBuf, FRAME_LEN); + delayNew += FRAME_LEN; + } + + aecpc->filtDelay = WEBRTC_SPL_MAX(0, (short)(0.8*aecpc->filtDelay + 0.2*delayNew)); + + diff = aecpc->filtDelay - aecpc->knownDelay; + if (diff > 224) { + if (aecpc->lastDelayDiff < 96) { + aecpc->timeForDelayChange = 0; + } + else { + aecpc->timeForDelayChange++; + } + } + else if (diff < 96 && aecpc->knownDelay > 0) { + if (aecpc->lastDelayDiff > 224) { + aecpc->timeForDelayChange = 0; + } + else { + aecpc->timeForDelayChange++; + } + } + else { + aecpc->timeForDelayChange = 0; + } + aecpc->lastDelayDiff = diff; + + if (aecpc->timeForDelayChange > 25) { + aecpc->knownDelay = WEBRTC_SPL_MAX((int)aecpc->filtDelay - 160, 0); + } + return 0; +} + +static int DelayComp(aecpc_t *aecpc) +{ + int nSampFar, nSampSndCard, delayNew, nSampAdd; + const int maxStuffSamp = 10 * FRAME_LEN; + + nSampFar = WebRtcApm_get_buffer_size(aecpc->farendBuf); + nSampSndCard = aecpc->msInSndCardBuf * sampMsNb * aecpc->aec->mult; + delayNew = nSampSndCard - nSampFar; + + // Account for resampling frame delay + if (aecpc->skewMode == kAecTrue && aecpc->resample == kAecTrue) { + delayNew -= kResamplingDelay; + } + + if (delayNew > FAR_BUF_LEN - FRAME_LEN*aecpc->aec->mult) { + // The difference of the buffersizes is larger than the maximum + // allowed known delay. Compensate by stuffing the buffer. + nSampAdd = (int)(WEBRTC_SPL_MAX((int)(0.5 * nSampSndCard - nSampFar), + FRAME_LEN)); + nSampAdd = WEBRTC_SPL_MIN(nSampAdd, maxStuffSamp); + + WebRtcApm_StuffBuffer(aecpc->farendBuf, nSampAdd); + aecpc->delayChange = 1; // the delay needs to be updated + } + + return 0; +} diff --git a/src/libs/webrtc/aec/echo_cancellation.h b/src/libs/webrtc/aec/echo_cancellation.h new file mode 100644 index 00000000..883357da --- /dev/null +++ b/src/libs/webrtc/aec/echo_cancellation.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_INTERFACE_ECHO_CANCELLATION_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_INTERFACE_ECHO_CANCELLATION_H_ + +#include "typedefs.h" + +// Errors +#define AEC_UNSPECIFIED_ERROR 12000 +#define AEC_UNSUPPORTED_FUNCTION_ERROR 12001 +#define AEC_UNINITIALIZED_ERROR 12002 +#define AEC_NULL_POINTER_ERROR 12003 +#define AEC_BAD_PARAMETER_ERROR 12004 + +// Warnings +#define AEC_BAD_PARAMETER_WARNING 12050 + +enum { + kAecNlpConservative = 0, + kAecNlpModerate, + kAecNlpAggressive +}; + +enum { + kAecFalse = 0, + kAecTrue +}; + +typedef struct { + WebRtc_Word16 nlpMode; // default kAecNlpModerate + WebRtc_Word16 skewMode; // default kAecFalse + WebRtc_Word16 metricsMode; // default kAecFalse + //float realSkew; +} AecConfig; + +typedef struct { + WebRtc_Word16 instant; + WebRtc_Word16 average; + WebRtc_Word16 max; + WebRtc_Word16 min; +} AecLevel; + +typedef struct { + AecLevel rerl; + AecLevel erl; + AecLevel erle; + AecLevel aNlp; +} AecMetrics; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Allocates the memory needed by the AEC. The memory needs to be initialized + * separately using the WebRtcAec_Init() function. + * + * Inputs Description + * ------------------------------------------------------------------- + * void **aecInst Pointer to the AEC instance to be created + * and initilized + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAec_Create(void **aecInst); + +/* + * This function releases the memory allocated by WebRtcAec_Create(). + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecInst Pointer to the AEC instance + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAec_Free(void *aecInst); + +/* + * Initializes an AEC instance. + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecInst Pointer to the AEC instance + * WebRtc_Word32 sampFreq Sampling frequency of data + * WebRtc_Word32 scSampFreq Soundcard sampling frequency + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAec_Init(void *aecInst, + WebRtc_Word32 sampFreq, + WebRtc_Word32 scSampFreq); + +/* + * Inserts an 80 or 160 sample block of data into the farend buffer. + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecInst Pointer to the AEC instance + * WebRtc_Word16 *farend In buffer containing one frame of + * farend signal for L band + * WebRtc_Word16 nrOfSamples Number of samples in farend buffer + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAec_BufferFarend(void *aecInst, + const WebRtc_Word16 *farend, + WebRtc_Word16 nrOfSamples); + +/* + * Runs the echo canceller on an 80 or 160 sample blocks of data. + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecInst Pointer to the AEC instance + * WebRtc_Word16 *nearend In buffer containing one frame of + * nearend+echo signal for L band + * WebRtc_Word16 *nearendH In buffer containing one frame of + * nearend+echo signal for H band + * WebRtc_Word16 nrOfSamples Number of samples in nearend buffer + * WebRtc_Word16 msInSndCardBuf Delay estimate for sound card and + * system buffers + * WebRtc_Word16 skew Difference between number of samples played + * and recorded at the soundcard (for clock skew + * compensation) + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word16 *out Out buffer, one frame of processed nearend + * for L band + * WebRtc_Word16 *outH Out buffer, one frame of processed nearend + * for H band + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAec_Process(void *aecInst, + const WebRtc_Word16 *nearend, + const WebRtc_Word16 *nearendH, + WebRtc_Word16 *out, + WebRtc_Word16 *outH, + WebRtc_Word16 nrOfSamples, + WebRtc_Word16 msInSndCardBuf, + WebRtc_Word32 skew); + +/* + * This function enables the user to set certain parameters on-the-fly. + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecInst Pointer to the AEC instance + * AecConfig config Config instance that contains all + * properties to be set + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAec_set_config(void *aecInst, AecConfig config); + +/* + * Gets the on-the-fly paramters. + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecInst Pointer to the AEC instance + * + * Outputs Description + * ------------------------------------------------------------------- + * AecConfig *config Pointer to the config instance that + * all properties will be written to + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAec_get_config(void *aecInst, AecConfig *config); + +/* + * Gets the current echo status of the nearend signal. + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecInst Pointer to the AEC instance + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word16 *status 0: Almost certainly nearend single-talk + * 1: Might not be neared single-talk + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAec_get_echo_status(void *aecInst, WebRtc_Word16 *status); + +/* + * Gets the current echo metrics for the session. + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecInst Pointer to the AEC instance + * + * Outputs Description + * ------------------------------------------------------------------- + * AecMetrics *metrics Struct which will be filled out with the + * current echo metrics. + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAec_GetMetrics(void *aecInst, AecMetrics *metrics); + +/* + * Gets the last error code. + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecInst Pointer to the AEC instance + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word32 return 11000-11100: error code + */ +WebRtc_Word32 WebRtcAec_get_error_code(void *aecInst); + +/* + * Gets a version string. + * + * Inputs Description + * ------------------------------------------------------------------- + * char *versionStr Pointer to a string array + * WebRtc_Word16 len The maximum length of the string + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word8 *versionStr Pointer to a string array + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAec_get_version(WebRtc_Word8 *versionStr, WebRtc_Word16 len); + +#ifdef __cplusplus +} +#endif +#endif /* WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_INTERFACE_ECHO_CANCELLATION_H_ */ diff --git a/src/libs/webrtc/aec/resampler.c b/src/libs/webrtc/aec/resampler.c new file mode 100644 index 00000000..4caa6f4c --- /dev/null +++ b/src/libs/webrtc/aec/resampler.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* Resamples a signal to an arbitrary rate. Used by the AEC to compensate for clock + * skew by resampling the farend signal. + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "resampler.h" +#include "aec_core.h" + +enum { kFrameBufferSize = FRAME_LEN * 4 }; +enum { kEstimateLengthFrames = 400 }; + +typedef struct { + short buffer[kFrameBufferSize]; + float position; + + int deviceSampleRateHz; + int skewData[kEstimateLengthFrames]; + int skewDataIndex; + float skewEstimate; +} resampler_t; + +static int EstimateSkew(const int* rawSkew, + int size, + int absLimit, + float *skewEst); + +int WebRtcAec_CreateResampler(void **resampInst) +{ + resampler_t *obj = malloc(sizeof(resampler_t)); + *resampInst = obj; + if (obj == NULL) { + return -1; + } + + return 0; +} + +int WebRtcAec_InitResampler(void *resampInst, int deviceSampleRateHz) +{ + resampler_t *obj = (resampler_t*) resampInst; + memset(obj->buffer, 0, sizeof(obj->buffer)); + obj->position = 0.0; + + obj->deviceSampleRateHz = deviceSampleRateHz; + memset(obj->skewData, 0, sizeof(obj->skewData)); + obj->skewDataIndex = 0; + obj->skewEstimate = 0.0; + + return 0; +} + +int WebRtcAec_FreeResampler(void *resampInst) +{ + resampler_t *obj = (resampler_t*) resampInst; + free(obj); + + return 0; +} + +int WebRtcAec_ResampleLinear(void *resampInst, + const short *inspeech, + int size, + float skew, + short *outspeech) +{ + resampler_t *obj = (resampler_t*) resampInst; + + short *y; + float be, tnew, interp; + int tn, outsize, mm; + + if (size < 0 || size > 2 * FRAME_LEN) { + return -1; + } + + // Add new frame data in lookahead + memcpy(&obj->buffer[FRAME_LEN + kResamplingDelay], + inspeech, + size * sizeof(short)); + + // Sample rate ratio + be = 1 + skew; + + // Loop over input frame + mm = 0; + y = &obj->buffer[FRAME_LEN]; // Point at current frame + + tnew = be * mm + obj->position; + tn = (int) tnew; + + while (tn < size) { + + // Interpolation + interp = y[tn] + (tnew - tn) * (y[tn+1] - y[tn]); + + if (interp > 32767) { + interp = 32767; + } + else if (interp < -32768) { + interp = -32768; + } + + outspeech[mm] = (short) interp; + mm++; + + tnew = be * mm + obj->position; + tn = (int) tnew; + } + + outsize = mm; + obj->position += outsize * be - size; + + // Shift buffer + memmove(obj->buffer, + &obj->buffer[size], + (kFrameBufferSize - size) * sizeof(short)); + + return outsize; +} + +int WebRtcAec_GetSkew(void *resampInst, int rawSkew, float *skewEst) +{ + resampler_t *obj = (resampler_t*)resampInst; + int err = 0; + + if (obj->skewDataIndex < kEstimateLengthFrames) { + obj->skewData[obj->skewDataIndex] = rawSkew; + obj->skewDataIndex++; + } + else if (obj->skewDataIndex == kEstimateLengthFrames) { + err = EstimateSkew(obj->skewData, + kEstimateLengthFrames, + obj->deviceSampleRateHz, + skewEst); + obj->skewEstimate = *skewEst; + obj->skewDataIndex++; + } + else { + *skewEst = obj->skewEstimate; + } + + return err; +} + +int EstimateSkew(const int* rawSkew, + const int size, + const int deviceSampleRateHz, + float *skewEst) +{ + const int absLimitOuter = (int)(0.04f * deviceSampleRateHz); + const int absLimitInner = (int)(0.0025f * deviceSampleRateHz); + int i = 0; + int n = 0; + float rawAvg = 0; + float err = 0; + float rawAbsDev = 0; + int upperLimit = 0; + int lowerLimit = 0; + float cumSum = 0; + float x = 0; + float x2 = 0; + float y = 0; + float xy = 0; + float xAvg = 0; + float yAvg = 0; + float denom = 0; + float skew = 0; + + *skewEst = 0; // Set in case of error below. + for (i = 0; i < size; i++) { + if ((rawSkew[i] < absLimitOuter && rawSkew[i] > -absLimitOuter)) { + n++; + rawAvg += rawSkew[i]; + } + } + + if (n == 0) { + return -1; + } + assert(n > 0); + rawAvg /= n; + + for (i = 0; i < size; i++) { + if ((rawSkew[i] < absLimitOuter && rawSkew[i] > -absLimitOuter)) { + err = rawSkew[i] - rawAvg; + rawAbsDev += err >= 0 ? err : -err; + } + } + assert(n > 0); + rawAbsDev /= n; + upperLimit = (int)(rawAvg + 5 * rawAbsDev + 1); // +1 for ceiling. + lowerLimit = (int)(rawAvg - 5 * rawAbsDev - 1); // -1 for floor. + + n = 0; + for (i = 0; i < size; i++) { + if ((rawSkew[i] < absLimitInner && rawSkew[i] > -absLimitInner) || + (rawSkew[i] < upperLimit && rawSkew[i] > lowerLimit)) { + n++; + cumSum += rawSkew[i]; + x += n; + x2 += n*n; + y += cumSum; + xy += n * cumSum; + } + } + + if (n == 0) { + return -1; + } + assert(n > 0); + xAvg = x / n; + yAvg = y / n; + denom = x2 - xAvg*x; + + if (denom != 0) { + skew = (xy - xAvg*y) / denom; + } + + *skewEst = skew; + return 0; +} diff --git a/src/libs/webrtc/aec/resampler.h b/src/libs/webrtc/aec/resampler.h new file mode 100644 index 00000000..9cb28372 --- /dev/null +++ b/src/libs/webrtc/aec/resampler.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_RESAMPLER_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_RESAMPLER_H_ + +enum { kResamplingDelay = 1 }; + +// Unless otherwise specified, functions return 0 on success and -1 on error +int WebRtcAec_CreateResampler(void **resampInst); +int WebRtcAec_InitResampler(void *resampInst, int deviceSampleRateHz); +int WebRtcAec_FreeResampler(void *resampInst); + +// Estimates skew from raw measurement. +int WebRtcAec_GetSkew(void *resampInst, int rawSkew, float *skewEst); + +// Resamples input using linear interpolation. +// Returns size of resampled array. +int WebRtcAec_ResampleLinear(void *resampInst, + const short *inspeech, + int size, + float skew, + short *outspeech); + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_RESAMPLER_H_ diff --git a/src/libs/webrtc/aecm/aecm_core.c b/src/libs/webrtc/aecm/aecm_core.c new file mode 100644 index 00000000..032aa4c0 --- /dev/null +++ b/src/libs/webrtc/aecm/aecm_core.c @@ -0,0 +1,2452 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <stdlib.h> + +#include "aecm_core.h" +#include "ring_buffer.h" +#include "echo_control_mobile.h" +#include "typedefs.h" + +#ifdef ARM_WINM_LOG +#include <stdio.h> +#include <windows.h> +#endif + +// BANDLAST - BANDFIRST must be < 32 +#define BANDFIRST 12 // Only bit BANDFIRST through bit BANDLAST are processed +#define BANDLAST 43 + +#ifdef ARM_WINM +#define WebRtcSpl_AddSatW32(a,b) _AddSatInt(a,b) +#define WebRtcSpl_SubSatW32(a,b) _SubSatInt(a,b) +#endif +// 16 instructions on most risc machines for 32-bit bitcount ! + +#ifdef AEC_DEBUG +FILE *dfile; +FILE *testfile; +#endif + +#ifdef AECM_SHORT + +// Square root of Hanning window in Q14 +static const WebRtc_Word16 kSqrtHanning[] = +{ + 0, 804, 1606, 2404, 3196, 3981, 4756, 5520, + 6270, 7005, 7723, 8423, 9102, 9760, 10394, 11003, + 11585, 12140, 12665, 13160, 13623, 14053, 14449, 14811, + 15137, 15426, 15679, 15893, 16069, 16207, 16305, 16364, + 16384 +}; + +#else + +// Square root of Hanning window in Q14 +static const WebRtc_Word16 kSqrtHanning[] = {0, 399, 798, 1196, 1594, 1990, 2386, 2780, 3172, + 3562, 3951, 4337, 4720, 5101, 5478, 5853, 6224, 6591, 6954, 7313, 7668, 8019, 8364, + 8705, 9040, 9370, 9695, 10013, 10326, 10633, 10933, 11227, 11514, 11795, 12068, 12335, + 12594, 12845, 13089, 13325, 13553, 13773, 13985, 14189, 14384, 14571, 14749, 14918, + 15079, 15231, 15373, 15506, 15631, 15746, 15851, 15947, 16034, 16111, 16179, 16237, + 16286, 16325, 16354, 16373, 16384}; + +#endif + +//Q15 alpha = 0.99439986968132 const Factor for magnitude approximation +static const WebRtc_UWord16 kAlpha1 = 32584; +//Q15 beta = 0.12967166976970 const Factor for magnitude approximation +static const WebRtc_UWord16 kBeta1 = 4249; +//Q15 alpha = 0.94234827210087 const Factor for magnitude approximation +static const WebRtc_UWord16 kAlpha2 = 30879; +//Q15 beta = 0.33787806009150 const Factor for magnitude approximation +static const WebRtc_UWord16 kBeta2 = 11072; +//Q15 alpha = 0.82247698684306 const Factor for magnitude approximation +static const WebRtc_UWord16 kAlpha3 = 26951; +//Q15 beta = 0.57762063060713 const Factor for magnitude approximation +static const WebRtc_UWord16 kBeta3 = 18927; + +#ifdef ARM_WINM_LOG +HANDLE logFile = NULL; +#endif + +static void WebRtcAecm_ComfortNoise(AecmCore_t* const aecm, const WebRtc_UWord16 * const dfa, + WebRtc_Word16 * const outReal, + WebRtc_Word16 * const outImag, + const WebRtc_Word16 * const lambda); + +static __inline WebRtc_UWord32 WebRtcAecm_SetBit(WebRtc_UWord32 in, WebRtc_Word32 pos) +{ + WebRtc_UWord32 mask, out; + + mask = WEBRTC_SPL_SHIFT_W32(1, pos); + out = (in | mask); + + return out; +} + +// WebRtcAecm_Hisser(...) +// +// This function compares the binary vector specvec with all rows of the binary matrix specmat +// and counts per row the number of times they have the same value. +// Input: +// - specvec : binary "vector" that is stored in a long +// - specmat : binary "matrix" that is stored as a vector of long +// Output: +// - bcount : "Vector" stored as a long, containing for each row the number of times +// the matrix row and the input vector have the same value +// +// +void WebRtcAecm_Hisser(const WebRtc_UWord32 specvec, const WebRtc_UWord32 * const specmat, + WebRtc_UWord32 * const bcount) +{ + int n, sum; + WebRtc_UWord32 a, b; + register WebRtc_UWord32 tmp; + + a = specvec; + // compare binary vector specvec with all rows of the binary matrix specmat + for (n = 0; n < MAX_DELAY; n++) + { + sum = 0; + b = specmat[n]; + a = (specvec ^ b); + // Returns bit counts in tmp + tmp = a - ((a >> 1) & 033333333333) - ((a >> 2) & 011111111111); + tmp = ((tmp + (tmp >> 3)) & 030707070707); + tmp = (tmp + (tmp >> 6)); + tmp = (tmp + (tmp >> 12) + (tmp >> 24)) & 077; + + bcount[n] = tmp; + } +} + +// WebRtcAecm_BSpectrum(...) +// +// Computes the binary spectrum by comparing the input spectrum with a threshold spectrum. +// +// Input: +// - spectrum : Spectrum of which the binary spectrum should be calculated. +// - thresvec : Threshold spectrum with which the input spectrum is compared. +// Return: +// - out : Binary spectrum +// +WebRtc_UWord32 WebRtcAecm_BSpectrum(const WebRtc_UWord16 * const spectrum, + const WebRtc_UWord16 * const thresvec) +{ + int k; + WebRtc_UWord32 out; + + out = 0; + for (k = BANDFIRST; k <= BANDLAST; k++) + { + if (spectrum[k] > thresvec[k]) + { + out = WebRtcAecm_SetBit(out, k - BANDFIRST); + } + } + + return out; +} + +// WebRtcAecm_MedianEstimator(...) +// +// Calculates the median recursively. +// +// Input: +// - newVal : new additional value +// - medianVec : vector with current medians +// - factor : factor for smoothing +// +// Output: +// - medianVec : vector with updated median +// +int WebRtcAecm_MedianEstimator(const WebRtc_UWord16 newVal, WebRtc_UWord16 * const medianVec, + const int factor) +{ + WebRtc_Word32 median; + WebRtc_Word32 diff; + + median = (WebRtc_Word32)medianVec[0]; + + //median = median + ((newVal-median)>>factor); + diff = (WebRtc_Word32)newVal - median; + diff = WEBRTC_SPL_SHIFT_W32(diff, -factor); + median = median + diff; + + medianVec[0] = (WebRtc_UWord16)median; + + return 0; +} + +int WebRtcAecm_CreateCore(AecmCore_t **aecmInst) +{ + AecmCore_t *aecm = malloc(sizeof(AecmCore_t)); + *aecmInst = aecm; + if (aecm == NULL) + { + return -1; + } + + if (WebRtcApm_CreateBuffer(&aecm->farFrameBuf, FRAME_LEN + PART_LEN) == -1) + { + WebRtcAecm_FreeCore(aecm); + aecm = NULL; + return -1; + } + + if (WebRtcApm_CreateBuffer(&aecm->nearNoisyFrameBuf, FRAME_LEN + PART_LEN) == -1) + { + WebRtcAecm_FreeCore(aecm); + aecm = NULL; + return -1; + } + + if (WebRtcApm_CreateBuffer(&aecm->nearCleanFrameBuf, FRAME_LEN + PART_LEN) == -1) + { + WebRtcAecm_FreeCore(aecm); + aecm = NULL; + return -1; + } + + if (WebRtcApm_CreateBuffer(&aecm->outFrameBuf, FRAME_LEN + PART_LEN) == -1) + { + WebRtcAecm_FreeCore(aecm); + aecm = NULL; + return -1; + } + + return 0; +} + +// WebRtcAecm_InitCore(...) +// +// This function initializes the AECM instant created with WebRtcAecm_CreateCore(...) +// Input: +// - aecm : Pointer to the Echo Suppression instance +// - samplingFreq : Sampling Frequency +// +// Output: +// - aecm : Initialized instance +// +// Return value : 0 - Ok +// -1 - Error +// +int WebRtcAecm_InitCore(AecmCore_t * const aecm, int samplingFreq) +{ + int retVal = 0; + WebRtc_Word16 i; + WebRtc_Word16 tmp16; + + if (samplingFreq != 8000 && samplingFreq != 16000) + { + samplingFreq = 8000; + retVal = -1; + } + // sanity check of sampling frequency + aecm->mult = (WebRtc_Word16)samplingFreq / 8000; + + aecm->farBufWritePos = 0; + aecm->farBufReadPos = 0; + aecm->knownDelay = 0; + aecm->lastKnownDelay = 0; + + WebRtcApm_InitBuffer(aecm->farFrameBuf); + WebRtcApm_InitBuffer(aecm->nearNoisyFrameBuf); + WebRtcApm_InitBuffer(aecm->nearCleanFrameBuf); + WebRtcApm_InitBuffer(aecm->outFrameBuf); + + memset(aecm->xBuf, 0, sizeof(aecm->xBuf)); + memset(aecm->dBufClean, 0, sizeof(aecm->dBufClean)); + memset(aecm->dBufNoisy, 0, sizeof(aecm->dBufNoisy)); + memset(aecm->outBuf, 0, sizeof(WebRtc_Word16) * PART_LEN); + + aecm->seed = 666; + aecm->totCount = 0; + + memset(aecm->xfaHistory, 0, sizeof(WebRtc_UWord16) * (PART_LEN1) * MAX_DELAY); + + aecm->delHistoryPos = MAX_DELAY; + + memset(aecm->medianYlogspec, 0, sizeof(WebRtc_UWord16) * PART_LEN1); + memset(aecm->medianXlogspec, 0, sizeof(WebRtc_UWord16) * PART_LEN1); + memset(aecm->medianBCount, 0, sizeof(WebRtc_UWord16) * MAX_DELAY); + memset(aecm->bxHistory, 0, sizeof(aecm->bxHistory)); + + // Initialize to reasonable values + aecm->currentDelay = 8; + aecm->previousDelay = 8; + aecm->delayAdjust = 0; + + aecm->nlpFlag = 1; + aecm->fixedDelay = -1; + + memset(aecm->xfaQDomainBuf, 0, sizeof(WebRtc_Word16) * MAX_DELAY); + aecm->dfaCleanQDomain = 0; + aecm->dfaCleanQDomainOld = 0; + aecm->dfaNoisyQDomain = 0; + aecm->dfaNoisyQDomainOld = 0; + + memset(aecm->nearLogEnergy, 0, sizeof(WebRtc_Word16) * MAX_BUF_LEN); + memset(aecm->farLogEnergy, 0, sizeof(WebRtc_Word16) * MAX_BUF_LEN); + memset(aecm->echoAdaptLogEnergy, 0, sizeof(WebRtc_Word16) * MAX_BUF_LEN); + memset(aecm->echoStoredLogEnergy, 0, sizeof(WebRtc_Word16) * MAX_BUF_LEN); + + memset(aecm->channelAdapt16, 0, sizeof(WebRtc_Word16) * PART_LEN1); + memset(aecm->channelAdapt32, 0, sizeof(WebRtc_Word32) * PART_LEN1); + memset(aecm->channelStored, 0, sizeof(WebRtc_Word16) * PART_LEN1); + memset(aecm->echoFilt, 0, sizeof(WebRtc_Word32) * PART_LEN1); + memset(aecm->nearFilt, 0, sizeof(WebRtc_Word16) * PART_LEN1); + aecm->noiseEstCtr = 0; + + aecm->cngMode = AecmTrue; + + // Increase the noise Q domain with increasing frequency, to correspond to the + // expected energy levels. + // Also shape the initial noise level with this consideration. +#if (!defined ARM_WINM) && (!defined ARM9E_GCC) && (!defined ANDROID_AECOPT) + for (i = 0; i < PART_LEN1; i++) + { + if (i < PART_LEN1 >> 2) + { + aecm->noiseEstQDomain[i] = 10; + tmp16 = PART_LEN1 - i; + aecm->noiseEst[i] = (tmp16 * tmp16) << 4; + } else if (i < PART_LEN1 >> 1) + { + aecm->noiseEstQDomain[i] = 11; + tmp16 = PART_LEN1 - i; + aecm->noiseEst[i] = ((tmp16 * tmp16) << 4) << 1; + } else + { + aecm->noiseEstQDomain[i] = 12; + aecm->noiseEst[i] = aecm->noiseEst[(PART_LEN1 >> 1) - 1] << 1; + } + } +#else + for (i = 0; i < PART_LEN1 >> 2; i++) + { + aecm->noiseEstQDomain[i] = 10; + tmp16 = PART_LEN1 - i; + aecm->noiseEst[i] = (tmp16 * tmp16) << 4; + } + for (; i < PART_LEN1 >> 1; i++) + { + aecm->noiseEstQDomain[i] = 11; + tmp16 = PART_LEN1 - i; + aecm->noiseEst[i] = ((tmp16 * tmp16) << 4) << 1; + } + for (; i < PART_LEN1; i++) + { + aecm->noiseEstQDomain[i] = 12; + aecm->noiseEst[i] = aecm->noiseEst[(PART_LEN1 >> 1) - 1] << 1; + } +#endif + + aecm->mseAdaptOld = 1000; + aecm->mseStoredOld = 1000; + aecm->mseThreshold = WEBRTC_SPL_WORD32_MAX; + + aecm->farEnergyMin = WEBRTC_SPL_WORD16_MAX; + aecm->farEnergyMax = WEBRTC_SPL_WORD16_MIN; + aecm->farEnergyMaxMin = 0; + aecm->farEnergyVAD = 0; + aecm->farEnergyMSE = 0; + aecm->currentVADValue = 0; + aecm->vadUpdateCount = 0; + + aecm->delayCount = 0; + aecm->newDelayCorrData = 0; + aecm->lastDelayUpdateCount = 0; + memset(aecm->delayCorrelation, 0, sizeof(WebRtc_Word16) * ((CORR_MAX << 1) + 1)); + + aecm->startupState = 0; + aecm->mseChannelCount = 0; + aecm->supGain = SUPGAIN_DEFAULT; + aecm->supGainOld = SUPGAIN_DEFAULT; + aecm->delayOffsetFlag = 0; + + memset(aecm->delayHistogram, 0, sizeof(aecm->delayHistogram)); + aecm->delayVadCount = 0; + aecm->maxDelayHistIdx = 0; + aecm->lastMinPos = 0; + + aecm->supGainErrParamA = SUPGAIN_ERROR_PARAM_A; + aecm->supGainErrParamD = SUPGAIN_ERROR_PARAM_D; + aecm->supGainErrParamDiffAB = SUPGAIN_ERROR_PARAM_A - SUPGAIN_ERROR_PARAM_B; + aecm->supGainErrParamDiffBD = SUPGAIN_ERROR_PARAM_B - SUPGAIN_ERROR_PARAM_D; + + return 0; +} + +int WebRtcAecm_Control(AecmCore_t *aecm, int delay, int nlpFlag, int delayOffsetFlag) +{ + aecm->nlpFlag = nlpFlag; + aecm->fixedDelay = delay; + aecm->delayOffsetFlag = delayOffsetFlag; + + return 0; +} + +// WebRtcAecm_GetNewDelPos(...) +// +// Moves the pointer to the next entry. Returns to zero if max position reached. +// +// Input: +// - aecm : Pointer to the AECM instance +// Return: +// - pos : New position in the history. +// +// +WebRtc_Word16 WebRtcAecm_GetNewDelPos(AecmCore_t * const aecm) +{ + WebRtc_Word16 pos; + + pos = aecm->delHistoryPos; + pos++; + if (pos >= MAX_DELAY) + { + pos = 0; + } + aecm->delHistoryPos = pos; + + return pos; +} + +// WebRtcAecm_EstimateDelay(...) +// +// Estimate the delay of the echo signal. +// +// Inputs: +// - aecm : Pointer to the AECM instance +// - farSpec : Delayed farend magnitude spectrum +// - nearSpec : Nearend magnitude spectrum +// - stages : Q-domain of xxFIX and yyFIX (without dynamic Q-domain) +// - xfaQ : normalization factor, i.e., Q-domain before FFT +// Return: +// - delay : Estimated delay +// +WebRtc_Word16 WebRtcAecm_EstimateDelay(AecmCore_t * const aecm, + const WebRtc_UWord16 * const farSpec, + const WebRtc_UWord16 * const nearSpec, + const WebRtc_Word16 xfaQ) +{ + WebRtc_UWord32 bxspectrum, byspectrum; + WebRtc_UWord32 bcount[MAX_DELAY]; + + int i, res; + + WebRtc_UWord16 xmean[PART_LEN1], ymean[PART_LEN1]; + WebRtc_UWord16 dtmp1; + WebRtc_Word16 fcount[MAX_DELAY]; + + //WebRtc_Word16 res; + WebRtc_Word16 histpos; + WebRtc_Word16 maxHistLvl; + WebRtc_UWord16 *state; + WebRtc_Word16 minpos = -1; + + enum + { + kVadCountThreshold = 25 + }; + enum + { + kMaxHistogram = 600 + }; + + histpos = WebRtcAecm_GetNewDelPos(aecm); + + for (i = 0; i < PART_LEN1; i++) + { + aecm->xfaHistory[i][histpos] = farSpec[i]; + + state = &(aecm->medianXlogspec[i]); + res = WebRtcAecm_MedianEstimator(farSpec[i], state, 6); + + state = &(aecm->medianYlogspec[i]); + res = WebRtcAecm_MedianEstimator(nearSpec[i], state, 6); + + // Mean: + // FLOAT: + // ymean = dtmp2/MAX_DELAY + // + // FIX: + // input: dtmp2FIX in Q0 + // output: ymeanFIX in Q8 + // 20 = 1/MAX_DELAY in Q13 = 1/MAX_DELAY * 2^13 + xmean[i] = (aecm->medianXlogspec[i]); + ymean[i] = (aecm->medianYlogspec[i]); + + } + // Update Q-domain buffer + aecm->xfaQDomainBuf[histpos] = xfaQ; + + // Get binary spectra + // FLOAT: + // bxspectrum = bspectrum(xlogspec, xmean); + // + // FIX: + // input: xlogspecFIX,ylogspecFIX in Q8 + // xmeanFIX, ymeanFIX in Q8 + // output: unsigned long bxspectrum, byspectrum in Q0 + bxspectrum = WebRtcAecm_BSpectrum(farSpec, xmean); + byspectrum = WebRtcAecm_BSpectrum(nearSpec, ymean); + + // Shift binary spectrum history + memmove(&(aecm->bxHistory[1]), &(aecm->bxHistory[0]), + (MAX_DELAY - 1) * sizeof(WebRtc_UWord32)); + + aecm->bxHistory[0] = bxspectrum; + + // Compare with delayed spectra + WebRtcAecm_Hisser(byspectrum, aecm->bxHistory, bcount); + + for (i = 0; i < MAX_DELAY; i++) + { + // Update sum + // bcount is constrained to [0, 32], meaning we can smooth with a factor up to 2^11. + dtmp1 = (WebRtc_UWord16)bcount[i]; + dtmp1 = WEBRTC_SPL_LSHIFT_W16(dtmp1, 9); + state = &(aecm->medianBCount[i]); + res = WebRtcAecm_MedianEstimator(dtmp1, state, 9); + fcount[i] = (aecm->medianBCount[i]); + } + + // Find minimum + minpos = WebRtcSpl_MinIndexW16(fcount, MAX_DELAY); + + // If the farend has been active sufficiently long, begin accumulating a histogram + // of the minimum positions. Search for the maximum bin to determine the delay. + if (aecm->currentVADValue == 1) + { + if (aecm->delayVadCount >= kVadCountThreshold) + { + // Increment the histogram at the current minimum position. + if (aecm->delayHistogram[minpos] < kMaxHistogram) + { + aecm->delayHistogram[minpos] += 3; + } + +#if (!defined ARM_WINM) && (!defined ARM9E_GCC) && (!defined ANDROID_AECOPT) + // Decrement the entire histogram. + for (i = 0; i < MAX_DELAY; i++) + { + if (aecm->delayHistogram[i] > 0) + { + aecm->delayHistogram[i]--; + } + } + + // Select the histogram index corresponding to the maximum bin as the delay. + maxHistLvl = 0; + aecm->maxDelayHistIdx = 0; + for (i = 0; i < MAX_DELAY; i++) + { + if (aecm->delayHistogram[i] > maxHistLvl) + { + maxHistLvl = aecm->delayHistogram[i]; + aecm->maxDelayHistIdx = i; + } + } +#else + maxHistLvl = 0; + aecm->maxDelayHistIdx = 0; + + for (i = 0; i < MAX_DELAY; i++) + { + WebRtc_Word16 tempVar = aecm->delayHistogram[i]; + + // Decrement the entire histogram. + if (tempVar > 0) + { + tempVar--; + aecm->delayHistogram[i] = tempVar; + + // Select the histogram index corresponding to the maximum bin as the delay. + if (tempVar > maxHistLvl) + { + maxHistLvl = tempVar; + aecm->maxDelayHistIdx = i; + } + } + } +#endif + } else + { + aecm->delayVadCount++; + } + } else + { + aecm->delayVadCount = 0; + } + + return aecm->maxDelayHistIdx; +} + +int WebRtcAecm_FreeCore(AecmCore_t *aecm) +{ + if (aecm == NULL) + { + return -1; + } + + WebRtcApm_FreeBuffer(aecm->farFrameBuf); + WebRtcApm_FreeBuffer(aecm->nearNoisyFrameBuf); + WebRtcApm_FreeBuffer(aecm->nearCleanFrameBuf); + WebRtcApm_FreeBuffer(aecm->outFrameBuf); + + free(aecm); + + return 0; +} + +void WebRtcAecm_ProcessFrame(AecmCore_t * const aecm, const WebRtc_Word16 * const farend, + const WebRtc_Word16 * const nearendNoisy, + const WebRtc_Word16 * const nearendClean, + WebRtc_Word16 * const out) +{ + WebRtc_Word16 farBlock[PART_LEN]; + WebRtc_Word16 nearNoisyBlock[PART_LEN]; + WebRtc_Word16 nearCleanBlock[PART_LEN]; + WebRtc_Word16 outBlock[PART_LEN]; + WebRtc_Word16 farFrame[FRAME_LEN]; + int size = 0; + + // Buffer the current frame. + // Fetch an older one corresponding to the delay. + WebRtcAecm_BufferFarFrame(aecm, farend, FRAME_LEN); + WebRtcAecm_FetchFarFrame(aecm, farFrame, FRAME_LEN, aecm->knownDelay); + + // Buffer the synchronized far and near frames, + // to pass the smaller blocks individually. + WebRtcApm_WriteBuffer(aecm->farFrameBuf, farFrame, FRAME_LEN); + WebRtcApm_WriteBuffer(aecm->nearNoisyFrameBuf, nearendNoisy, FRAME_LEN); + if (nearendClean != NULL) + { + WebRtcApm_WriteBuffer(aecm->nearCleanFrameBuf, nearendClean, FRAME_LEN); + } + + // Process as many blocks as possible. + while (WebRtcApm_get_buffer_size(aecm->farFrameBuf) >= PART_LEN) + { + WebRtcApm_ReadBuffer(aecm->farFrameBuf, farBlock, PART_LEN); + WebRtcApm_ReadBuffer(aecm->nearNoisyFrameBuf, nearNoisyBlock, PART_LEN); + if (nearendClean != NULL) + { + WebRtcApm_ReadBuffer(aecm->nearCleanFrameBuf, nearCleanBlock, PART_LEN); + WebRtcAecm_ProcessBlock(aecm, farBlock, nearNoisyBlock, nearCleanBlock, outBlock); + } else + { + WebRtcAecm_ProcessBlock(aecm, farBlock, nearNoisyBlock, NULL, outBlock); + } + + WebRtcApm_WriteBuffer(aecm->outFrameBuf, outBlock, PART_LEN); + } + + // Stuff the out buffer if we have less than a frame to output. + // This should only happen for the first frame. + size = WebRtcApm_get_buffer_size(aecm->outFrameBuf); + if (size < FRAME_LEN) + { + WebRtcApm_StuffBuffer(aecm->outFrameBuf, FRAME_LEN - size); + } + + // Obtain an output frame. + WebRtcApm_ReadBuffer(aecm->outFrameBuf, out, FRAME_LEN); +} + +// WebRtcAecm_AsymFilt(...) +// +// Performs asymmetric filtering. +// +// Inputs: +// - filtOld : Previous filtered value. +// - inVal : New input value. +// - stepSizePos : Step size when we have a positive contribution. +// - stepSizeNeg : Step size when we have a negative contribution. +// +// Output: +// +// Return: - Filtered value. +// +WebRtc_Word16 WebRtcAecm_AsymFilt(const WebRtc_Word16 filtOld, const WebRtc_Word16 inVal, + const WebRtc_Word16 stepSizePos, + const WebRtc_Word16 stepSizeNeg) +{ + WebRtc_Word16 retVal; + + if ((filtOld == WEBRTC_SPL_WORD16_MAX) | (filtOld == WEBRTC_SPL_WORD16_MIN)) + { + return inVal; + } + retVal = filtOld; + if (filtOld > inVal) + { + retVal -= WEBRTC_SPL_RSHIFT_W16(filtOld - inVal, stepSizeNeg); + } else + { + retVal += WEBRTC_SPL_RSHIFT_W16(inVal - filtOld, stepSizePos); + } + + return retVal; +} + +// WebRtcAecm_CalcEnergies(...) +// +// This function calculates the log of energies for nearend, farend and estimated +// echoes. There is also an update of energy decision levels, i.e. internl VAD. +// +// +// @param aecm [i/o] Handle of the AECM instance. +// @param delayDiff [in] Delay position in farend buffer. +// @param nearEner [in] Near end energy for current block (Q[aecm->dfaQDomain]). +// @param echoEst [i/o] Estimated echo +// (Q[aecm->xfaQDomain[delayDiff]+RESOLUTION_CHANNEL16]). +// +void WebRtcAecm_CalcEnergies(AecmCore_t * const aecm, const WebRtc_Word16 delayDiff, + const WebRtc_UWord32 nearEner, WebRtc_Word32 * const echoEst) +{ + // Local variables + WebRtc_UWord32 tmpAdapt, tmpStored, tmpFar; + + int i; + + WebRtc_Word16 zeros, frac; + WebRtc_Word16 tmp16; + + // Get log of near end energy and store in buffer + + // Shift buffer + memmove(aecm->nearLogEnergy + 1, aecm->nearLogEnergy, + sizeof(WebRtc_Word16) * (MAX_BUF_LEN - 1)); + + // Logarithm of integrated magnitude spectrum (nearEner) + if (nearEner) + { + zeros = WebRtcSpl_NormU32(nearEner); + frac + = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32((WEBRTC_SPL_LSHIFT_U32(nearEner, zeros) & 0x7FFFFFFF), 23); + // log2 in Q8 + aecm->nearLogEnergy[0] = WEBRTC_SPL_LSHIFT_W16((31 - zeros), 8) + frac; + aecm->nearLogEnergy[0] -= WEBRTC_SPL_LSHIFT_W16(aecm->dfaNoisyQDomain, 8); + } else + { + aecm->nearLogEnergy[0] = 0; + } + aecm->nearLogEnergy[0] += WEBRTC_SPL_LSHIFT_W16(PART_LEN_SHIFT, 7); + // END: Get log of near end energy + + // Get energy for the delayed far end signal and estimated + // echo using both stored and adapted channels. + tmpAdapt = 0; + tmpStored = 0; + tmpFar = 0; + + for (i = 0; i < PART_LEN1; i++) + { + tmpFar += (WebRtc_UWord32)aecm->xfaHistory[i][delayDiff]; + // Get estimated echo energies for adaptive channel and stored channel + echoEst[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], + aecm->xfaHistory[i][delayDiff]); + tmpFar += (WebRtc_UWord32)(aecm->xfaHistory[i][delayDiff]); + tmpAdapt += WEBRTC_SPL_UMUL_16_16(aecm->channelAdapt16[i], + aecm->xfaHistory[i][delayDiff]); + tmpStored += (WebRtc_UWord32)echoEst[i]; + } + // Shift buffers + memmove(aecm->farLogEnergy + 1, aecm->farLogEnergy, + sizeof(WebRtc_Word16) * (MAX_BUF_LEN - 1)); + memmove(aecm->echoAdaptLogEnergy + 1, aecm->echoAdaptLogEnergy, + sizeof(WebRtc_Word16) * (MAX_BUF_LEN - 1)); + memmove(aecm->echoStoredLogEnergy + 1, aecm->echoStoredLogEnergy, + sizeof(WebRtc_Word16) * (MAX_BUF_LEN - 1)); + + // Logarithm of delayed far end energy + if (tmpFar) + { + zeros = WebRtcSpl_NormU32(tmpFar); + frac = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32((WEBRTC_SPL_LSHIFT_U32(tmpFar, zeros) + & 0x7FFFFFFF), 23); + // log2 in Q8 + aecm->farLogEnergy[0] = WEBRTC_SPL_LSHIFT_W16((31 - zeros), 8) + frac; + aecm->farLogEnergy[0] -= WEBRTC_SPL_LSHIFT_W16(aecm->xfaQDomainBuf[delayDiff], 8); + } else + { + aecm->farLogEnergy[0] = 0; + } + aecm->farLogEnergy[0] += WEBRTC_SPL_LSHIFT_W16(PART_LEN_SHIFT, 7); + + // Logarithm of estimated echo energy through adapted channel + if (tmpAdapt) + { + zeros = WebRtcSpl_NormU32(tmpAdapt); + frac = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32((WEBRTC_SPL_LSHIFT_U32(tmpAdapt, zeros) + & 0x7FFFFFFF), 23); + //log2 in Q8 + aecm->echoAdaptLogEnergy[0] = WEBRTC_SPL_LSHIFT_W16((31 - zeros), 8) + frac; + aecm->echoAdaptLogEnergy[0] + -= WEBRTC_SPL_LSHIFT_W16(RESOLUTION_CHANNEL16 + aecm->xfaQDomainBuf[delayDiff], 8); + } else + { + aecm->echoAdaptLogEnergy[0] = 0; + } + aecm->echoAdaptLogEnergy[0] += WEBRTC_SPL_LSHIFT_W16(PART_LEN_SHIFT, 7); + + // Logarithm of estimated echo energy through stored channel + if (tmpStored) + { + zeros = WebRtcSpl_NormU32(tmpStored); + frac = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32((WEBRTC_SPL_LSHIFT_U32(tmpStored, zeros) + & 0x7FFFFFFF), 23); + //log2 in Q8 + aecm->echoStoredLogEnergy[0] = WEBRTC_SPL_LSHIFT_W16((31 - zeros), 8) + frac; + aecm->echoStoredLogEnergy[0] + -= WEBRTC_SPL_LSHIFT_W16(RESOLUTION_CHANNEL16 + aecm->xfaQDomainBuf[delayDiff], 8); + } else + { + aecm->echoStoredLogEnergy[0] = 0; + } + aecm->echoStoredLogEnergy[0] += WEBRTC_SPL_LSHIFT_W16(PART_LEN_SHIFT, 7); + + // Update farend energy levels (min, max, vad, mse) + if (aecm->farLogEnergy[0] > FAR_ENERGY_MIN) + { + tmp16 = 11; + if (aecm->startupState == 0) + { + tmp16 = 8; + } + + aecm->farEnergyMin = WebRtcAecm_AsymFilt(aecm->farEnergyMin, aecm->farLogEnergy[0], + tmp16, 3); + aecm->farEnergyMax = WebRtcAecm_AsymFilt(aecm->farEnergyMax, aecm->farLogEnergy[0], 4, + 11); + aecm->farEnergyMaxMin = (aecm->farEnergyMax - aecm->farEnergyMin); + + // Dynamic VAD region size + tmp16 = 2560 - aecm->farEnergyMin; + if (tmp16 > 0) + { + tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16, FAR_ENERGY_VAD_REGION, 9); + } else + { + tmp16 = 0; + } + tmp16 += FAR_ENERGY_VAD_REGION; + + if ((aecm->startupState == 0) | (aecm->vadUpdateCount > 1024)) + { + // In startup phase or VAD update halted + aecm->farEnergyVAD = aecm->farEnergyMin + tmp16; + } else + { + if (aecm->farEnergyVAD > aecm->farLogEnergy[0]) + { + aecm->farEnergyVAD += WEBRTC_SPL_RSHIFT_W16(aecm->farLogEnergy[0] + tmp16 + - aecm->farEnergyVAD, 6); + aecm->vadUpdateCount = 0; + } else + { + aecm->vadUpdateCount++; + } + } + // Put MSE threshold higher than VAD + aecm->farEnergyMSE = aecm->farEnergyVAD + (1 << 8); + } + + // Update VAD variables + if (aecm->farLogEnergy[0] > aecm->farEnergyVAD) + { + if ((aecm->startupState == 0) | (aecm->farEnergyMaxMin > FAR_ENERGY_DIFF)) + { + // We are in startup or have significant dynamics in input speech level + aecm->currentVADValue = 1; + } + } else + { + aecm->currentVADValue = 0; + } + // END: Energies of delayed far, echo estimates +} + +// WebRtcAecm_CalcStepSize(...) +// +// This function calculates the step size used in channel estimation +// +// +// @param aecm [in] Handle of the AECM instance. +// @param mu [out] (Return value) Stepsize in log2(), i.e. number of shifts. +// +// +WebRtc_Word16 WebRtcAecm_CalcStepSize(AecmCore_t * const aecm) +{ + + WebRtc_Word32 tmp32; + WebRtc_Word16 tmp16; + WebRtc_Word16 mu; + + // Here we calculate the step size mu used in the + // following NLMS based Channel estimation algorithm + mu = MU_MAX; + if (!aecm->currentVADValue) + { + // Far end energy level too low, no channel update + mu = 0; + } else if (aecm->startupState > 0) + { + if (aecm->farEnergyMin >= aecm->farEnergyMax) + { + mu = MU_MIN; + } else + { + tmp16 = (aecm->farLogEnergy[0] - aecm->farEnergyMin); + tmp32 = WEBRTC_SPL_MUL_16_16(tmp16, MU_DIFF); + tmp32 = WebRtcSpl_DivW32W16(tmp32, aecm->farEnergyMaxMin); + mu = MU_MIN - 1 - (WebRtc_Word16)(tmp32); + // The -1 is an alternative to rounding. This way we get a larger + // stepsize, so we in some sense compensate for truncation in NLMS + } + if (mu < MU_MAX) + { + mu = MU_MAX; // Equivalent with maximum step size of 2^-MU_MAX + } + } + // END: Update step size + + return mu; +} + +// WebRtcAecm_UpdateChannel(...) +// +// This function performs channel estimation. NLMS and decision on channel storage. +// +// +// @param aecm [i/o] Handle of the AECM instance. +// @param dfa [in] Absolute value of the nearend signal (Q[aecm->dfaQDomain]) +// @param delayDiff [in] Delay position in farend buffer. +// @param mu [in] NLMS step size. +// @param echoEst [i/o] Estimated echo +// (Q[aecm->xfaQDomain[delayDiff]+RESOLUTION_CHANNEL16]). +// +void WebRtcAecm_UpdateChannel(AecmCore_t * const aecm, const WebRtc_UWord16 * const dfa, + const WebRtc_Word16 delayDiff, const WebRtc_Word16 mu, + WebRtc_Word32 * const echoEst) +{ + + WebRtc_UWord32 tmpU32no1, tmpU32no2; + WebRtc_Word32 tmp32no1, tmp32no2; + WebRtc_Word32 mseStored; + WebRtc_Word32 mseAdapt; + + int i; + + WebRtc_Word16 zerosFar, zerosNum, zerosCh, zerosDfa; + WebRtc_Word16 shiftChFar, shiftNum, shift2ResChan; + WebRtc_Word16 tmp16no1; + WebRtc_Word16 xfaQ, dfaQ; + + // This is the channel estimation algorithm. It is base on NLMS but has a variable step + // length, which was calculated above. + if (mu) + { + for (i = 0; i < PART_LEN1; i++) + { + // Determine norm of channel and farend to make sure we don't get overflow in + // multiplication + zerosCh = WebRtcSpl_NormU32(aecm->channelAdapt32[i]); + zerosFar = WebRtcSpl_NormU32((WebRtc_UWord32)aecm->xfaHistory[i][delayDiff]); + if (zerosCh + zerosFar > 31) + { + // Multiplication is safe + tmpU32no1 = WEBRTC_SPL_UMUL_32_16(aecm->channelAdapt32[i], + aecm->xfaHistory[i][delayDiff]); + shiftChFar = 0; + } else + { + // We need to shift down before multiplication + shiftChFar = 32 - zerosCh - zerosFar; + tmpU32no1 + = WEBRTC_SPL_UMUL_32_16(WEBRTC_SPL_RSHIFT_W32(aecm->channelAdapt32[i], + shiftChFar), + aecm->xfaHistory[i][delayDiff]); + } + // Determine Q-domain of numerator + zerosNum = WebRtcSpl_NormU32(tmpU32no1); + if (dfa[i]) + { + zerosDfa = WebRtcSpl_NormU32((WebRtc_UWord32)dfa[i]); + } else + { + zerosDfa = 32; + } + tmp16no1 = zerosDfa - 2 + aecm->dfaNoisyQDomain - RESOLUTION_CHANNEL32 + - aecm->xfaQDomainBuf[delayDiff] + shiftChFar; + if (zerosNum > tmp16no1 + 1) + { + xfaQ = tmp16no1; + dfaQ = zerosDfa - 2; + } else + { + xfaQ = zerosNum - 2; + dfaQ = RESOLUTION_CHANNEL32 + aecm->xfaQDomainBuf[delayDiff] + - aecm->dfaNoisyQDomain - shiftChFar + xfaQ; + } + // Add in the same Q-domain + tmpU32no1 = WEBRTC_SPL_SHIFT_W32(tmpU32no1, xfaQ); + tmpU32no2 = WEBRTC_SPL_SHIFT_W32((WebRtc_UWord32)dfa[i], dfaQ); + tmp32no1 = (WebRtc_Word32)tmpU32no2 - (WebRtc_Word32)tmpU32no1; + zerosNum = WebRtcSpl_NormW32(tmp32no1); + if ((tmp32no1) && (aecm->xfaHistory[i][delayDiff] > (CHANNEL_VAD + << aecm->xfaQDomainBuf[delayDiff]))) + { + // + // Update is needed + // + // This is what we would like to compute + // + // tmp32no1 = dfa[i] - (aecm->channelAdapt[i] * aecm->xfaHistory[i][delayDiff]) + // tmp32norm = (i + 1) + // aecm->channelAdapt[i] += (2^mu) * tmp32no1 + // / (tmp32norm * aecm->xfaHistory[i][delayDiff]) + // + + // Make sure we don't get overflow in multiplication. + if (zerosNum + zerosFar > 31) + { + if (tmp32no1 > 0) + { + tmp32no2 = (WebRtc_Word32)WEBRTC_SPL_UMUL_32_16(tmp32no1, + aecm->xfaHistory[i][delayDiff]); + } else + { + tmp32no2 = -(WebRtc_Word32)WEBRTC_SPL_UMUL_32_16(-tmp32no1, + aecm->xfaHistory[i][delayDiff]); + } + shiftNum = 0; + } else + { + shiftNum = 32 - (zerosNum + zerosFar); + if (tmp32no1 > 0) + { + tmp32no2 = (WebRtc_Word32)WEBRTC_SPL_UMUL_32_16( + WEBRTC_SPL_RSHIFT_W32(tmp32no1, shiftNum), + aecm->xfaHistory[i][delayDiff]); + } else + { + tmp32no2 = -(WebRtc_Word32)WEBRTC_SPL_UMUL_32_16( + WEBRTC_SPL_RSHIFT_W32(-tmp32no1, shiftNum), + aecm->xfaHistory[i][delayDiff]); + } + } + // Normalize with respect to frequency bin + tmp32no2 = WebRtcSpl_DivW32W16(tmp32no2, i + 1); + // Make sure we are in the right Q-domain + shift2ResChan = shiftNum + shiftChFar - xfaQ - mu - ((30 - zerosFar) << 1); + if (WebRtcSpl_NormW32(tmp32no2) < shift2ResChan) + { + tmp32no2 = WEBRTC_SPL_WORD32_MAX; + } else + { + tmp32no2 = WEBRTC_SPL_SHIFT_W32(tmp32no2, shift2ResChan); + } + aecm->channelAdapt32[i] = WEBRTC_SPL_ADD_SAT_W32(aecm->channelAdapt32[i], + tmp32no2); + if (aecm->channelAdapt32[i] < 0) + { + // We can never have negative channel gain + aecm->channelAdapt32[i] = 0; + } + aecm->channelAdapt16[i] + = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(aecm->channelAdapt32[i], 16); + } + } + } + // END: Adaptive channel update + + // Determine if we should store or restore the channel + if ((aecm->startupState == 0) & (aecm->currentVADValue)) + { + // During startup we store the channel every block. + memcpy(aecm->channelStored, aecm->channelAdapt16, sizeof(WebRtc_Word16) * PART_LEN1); + // Recalculate echo estimate +#if (!defined ARM_WINM) && (!defined ARM9E_GCC) && (!defined ANDROID_AECOPT) + for (i = 0; i < PART_LEN1; i++) + { + echoEst[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], + aecm->xfaHistory[i][delayDiff]); + } +#else + for (i = 0; i < PART_LEN; ) //assume PART_LEN is 4's multiples + + { + echoEst[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], + aecm->xfaHistory[i][delayDiff]); + i++; + echoEst[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], + aecm->xfaHistory[i][delayDiff]); + i++; + echoEst[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], + aecm->xfaHistory[i][delayDiff]); + i++; + echoEst[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], + aecm->xfaHistory[i][delayDiff]); + i++; + } + echoEst[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], + aecm->xfaHistory[i][delayDiff]); +#endif + } else + { + if (aecm->farLogEnergy[0] < aecm->farEnergyMSE) + { + aecm->mseChannelCount = 0; + aecm->delayCount = 0; + } else + { + aecm->mseChannelCount++; + aecm->delayCount++; + } + // Enough data for validation. Store channel if we can. + if (aecm->mseChannelCount >= (MIN_MSE_COUNT + 10)) + { + // We have enough data. + // Calculate MSE of "Adapt" and "Stored" versions. + // It is actually not MSE, but average absolute error. + mseStored = 0; + mseAdapt = 0; + for (i = 0; i < MIN_MSE_COUNT; i++) + { + tmp32no1 = ((WebRtc_Word32)aecm->echoStoredLogEnergy[i] + - (WebRtc_Word32)aecm->nearLogEnergy[i]); + tmp32no2 = WEBRTC_SPL_ABS_W32(tmp32no1); + mseStored += tmp32no2; + + tmp32no1 = ((WebRtc_Word32)aecm->echoAdaptLogEnergy[i] + - (WebRtc_Word32)aecm->nearLogEnergy[i]); + tmp32no2 = WEBRTC_SPL_ABS_W32(tmp32no1); + mseAdapt += tmp32no2; + } + if (((mseStored << MSE_RESOLUTION) < (MIN_MSE_DIFF * mseAdapt)) + & ((aecm->mseStoredOld << MSE_RESOLUTION) < (MIN_MSE_DIFF + * aecm->mseAdaptOld))) + { + // The stored channel has a significantly lower MSE than the adaptive one for + // two consecutive calculations. Reset the adaptive channel. + memcpy(aecm->channelAdapt16, aecm->channelStored, + sizeof(WebRtc_Word16) * PART_LEN1); + // Restore the W32 channel +#if (!defined ARM_WINM) && (!defined ARM9E_GCC) && (!defined ANDROID_AECOPT) + for (i = 0; i < PART_LEN1; i++) + { + aecm->channelAdapt32[i] + = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)aecm->channelStored[i], 16); + } +#else + for (i = 0; i < PART_LEN; ) //assume PART_LEN is 4's multiples + + { + aecm->channelAdapt32[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)aecm->channelStored[i], 16); + i++; + aecm->channelAdapt32[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)aecm->channelStored[i], 16); + i++; + aecm->channelAdapt32[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)aecm->channelStored[i], 16); + i++; + aecm->channelAdapt32[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)aecm->channelStored[i], 16); + i++; + } + aecm->channelAdapt32[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)aecm->channelStored[i], 16); +#endif + + } else if (((MIN_MSE_DIFF * mseStored) > (mseAdapt << MSE_RESOLUTION)) & (mseAdapt + < aecm->mseThreshold) & (aecm->mseAdaptOld < aecm->mseThreshold)) + { + // The adaptive channel has a significantly lower MSE than the stored one. + // The MSE for the adaptive channel has also been low for two consecutive + // calculations. Store the adaptive channel. + memcpy(aecm->channelStored, aecm->channelAdapt16, + sizeof(WebRtc_Word16) * PART_LEN1); + // Recalculate echo estimate +#if (!defined ARM_WINM) && (!defined ARM9E_GCC) && (!defined ANDROID_AECOPT) + for (i = 0; i < PART_LEN1; i++) + { + echoEst[i] + = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], aecm->xfaHistory[i][delayDiff]); + } +#else + for (i = 0; i < PART_LEN; ) //assume PART_LEN is 4's multiples + + { + echoEst[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], aecm->xfaHistory[i][delayDiff]); + i++; + echoEst[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], aecm->xfaHistory[i][delayDiff]); + i++; + echoEst[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], aecm->xfaHistory[i][delayDiff]); + i++; + echoEst[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], aecm->xfaHistory[i][delayDiff]); + i++; + } + echoEst[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i], aecm->xfaHistory[i][delayDiff]); +#endif + // Update threshold + if (aecm->mseThreshold == WEBRTC_SPL_WORD32_MAX) + { + aecm->mseThreshold = (mseAdapt + aecm->mseAdaptOld); + } else + { + aecm->mseThreshold += WEBRTC_SPL_MUL_16_16_RSFT(mseAdapt + - WEBRTC_SPL_MUL_16_16_RSFT(aecm->mseThreshold, 5, 3), 205, 8); + } + + } + + // Reset counter + aecm->mseChannelCount = 0; + + // Store the MSE values. + aecm->mseStoredOld = mseStored; + aecm->mseAdaptOld = mseAdapt; + } + } + // END: Determine if we should store or reset channel estimate. +} + +// WebRtcAecm_CalcSuppressionGain(...) +// +// This function calculates the suppression gain that is used in the Wiener filter. +// +// +// @param aecm [i/n] Handle of the AECM instance. +// @param supGain [out] (Return value) Suppression gain with which to scale the noise +// level (Q14). +// +// +WebRtc_Word16 WebRtcAecm_CalcSuppressionGain(AecmCore_t * const aecm) +{ + WebRtc_Word32 tmp32no1; + + WebRtc_Word16 supGain; + WebRtc_Word16 tmp16no1; + WebRtc_Word16 dE = 0; + + // Determine suppression gain used in the Wiener filter. The gain is based on a mix of far + // end energy and echo estimation error. + supGain = SUPGAIN_DEFAULT; + // Adjust for the far end signal level. A low signal level indicates no far end signal, + // hence we set the suppression gain to 0 + if (!aecm->currentVADValue) + { + supGain = 0; + } else + { + // Adjust for possible double talk. If we have large variations in estimation error we + // likely have double talk (or poor channel). + tmp16no1 = (aecm->nearLogEnergy[0] - aecm->echoStoredLogEnergy[0] - ENERGY_DEV_OFFSET); + dE = WEBRTC_SPL_ABS_W16(tmp16no1); + + if (dE < ENERGY_DEV_TOL) + { + // Likely no double talk. The better estimation, the more we can suppress signal. + // Update counters + if (dE < SUPGAIN_EPC_DT) + { + tmp32no1 = WEBRTC_SPL_MUL_16_16(aecm->supGainErrParamDiffAB, dE); + tmp32no1 += (SUPGAIN_EPC_DT >> 1); + tmp16no1 = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32no1, SUPGAIN_EPC_DT); + supGain = aecm->supGainErrParamA - tmp16no1; + } else + { + tmp32no1 = WEBRTC_SPL_MUL_16_16(aecm->supGainErrParamDiffBD, + (ENERGY_DEV_TOL - dE)); + tmp32no1 += ((ENERGY_DEV_TOL - SUPGAIN_EPC_DT) >> 1); + tmp16no1 = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32no1, (ENERGY_DEV_TOL + - SUPGAIN_EPC_DT)); + supGain = aecm->supGainErrParamD + tmp16no1; + } + } else + { + // Likely in double talk. Use default value + supGain = aecm->supGainErrParamD; + } + } + + if (supGain > aecm->supGainOld) + { + tmp16no1 = supGain; + } else + { + tmp16no1 = aecm->supGainOld; + } + aecm->supGainOld = supGain; + if (tmp16no1 < aecm->supGain) + { + aecm->supGain += (WebRtc_Word16)((tmp16no1 - aecm->supGain) >> 4); + } else + { + aecm->supGain += (WebRtc_Word16)((tmp16no1 - aecm->supGain) >> 4); + } + + // END: Update suppression gain + + return aecm->supGain; +} + +// WebRtcAecm_DelayCompensation(...) +// +// Secondary delay estimation that can be used as a backup or for validation. This function is +// still under construction and not activated in current version. +// +// +// @param aecm [i/o] Handle of the AECM instance. +// +// +void WebRtcAecm_DelayCompensation(AecmCore_t * const aecm) +{ + int i, j; + WebRtc_Word32 delayMeanEcho[CORR_BUF_LEN]; + WebRtc_Word32 delayMeanNear[CORR_BUF_LEN]; + WebRtc_Word16 sumBitPattern, bitPatternEcho, bitPatternNear, maxPos, maxValue, + maxValueLeft, maxValueRight; + + // Check delay (calculate the delay offset (if we can)). + if ((aecm->startupState > 0) & (aecm->delayCount >= CORR_MAX_BUF) & aecm->delayOffsetFlag) + { + // Calculate mean values + for (i = 0; i < CORR_BUF_LEN; i++) + { + delayMeanEcho[i] = 0; + delayMeanNear[i] = 0; +#if (!defined ARM_WINM) && (!defined ARM9E_GCC) && (!defined ANDROID_AECOPT) + for (j = 0; j < CORR_WIDTH; j++) + { + delayMeanEcho[i] += (WebRtc_Word32)aecm->echoStoredLogEnergy[i + j]; + delayMeanNear[i] += (WebRtc_Word32)aecm->nearLogEnergy[i + j]; + } +#else + for (j = 0; j < CORR_WIDTH -1; ) + { + delayMeanEcho[i] += (WebRtc_Word32)aecm->echoStoredLogEnergy[i + j]; + delayMeanNear[i] += (WebRtc_Word32)aecm->nearLogEnergy[i + j]; + j++; + delayMeanEcho[i] += (WebRtc_Word32)aecm->echoStoredLogEnergy[i + j]; + delayMeanNear[i] += (WebRtc_Word32)aecm->nearLogEnergy[i + j]; + j++; + } + delayMeanEcho[i] += (WebRtc_Word32)aecm->echoStoredLogEnergy[i + j]; + delayMeanNear[i] += (WebRtc_Word32)aecm->nearLogEnergy[i + j]; +#endif + } + // Calculate correlation values + for (i = 0; i < CORR_BUF_LEN; i++) + { + sumBitPattern = 0; +#if (!defined ARM_WINM) && (!defined ARM9E_GCC) && (!defined ANDROID_AECOPT) + for (j = 0; j < CORR_WIDTH; j++) + { + bitPatternEcho = (WebRtc_Word16)((WebRtc_Word32)aecm->echoStoredLogEnergy[i + + j] * CORR_WIDTH > delayMeanEcho[i]); + bitPatternNear = (WebRtc_Word16)((WebRtc_Word32)aecm->nearLogEnergy[CORR_MAX + + j] * CORR_WIDTH > delayMeanNear[CORR_MAX]); + sumBitPattern += !(bitPatternEcho ^ bitPatternNear); + } +#else + for (j = 0; j < CORR_WIDTH -1; ) + { + bitPatternEcho = (WebRtc_Word16)((WebRtc_Word32)aecm->echoStoredLogEnergy[i + + j] * CORR_WIDTH > delayMeanEcho[i]); + bitPatternNear = (WebRtc_Word16)((WebRtc_Word32)aecm->nearLogEnergy[CORR_MAX + + j] * CORR_WIDTH > delayMeanNear[CORR_MAX]); + sumBitPattern += !(bitPatternEcho ^ bitPatternNear); + j++; + bitPatternEcho = (WebRtc_Word16)((WebRtc_Word32)aecm->echoStoredLogEnergy[i + + j] * CORR_WIDTH > delayMeanEcho[i]); + bitPatternNear = (WebRtc_Word16)((WebRtc_Word32)aecm->nearLogEnergy[CORR_MAX + + j] * CORR_WIDTH > delayMeanNear[CORR_MAX]); + sumBitPattern += !(bitPatternEcho ^ bitPatternNear); + j++; + } + bitPatternEcho = (WebRtc_Word16)((WebRtc_Word32)aecm->echoStoredLogEnergy[i + j] + * CORR_WIDTH > delayMeanEcho[i]); + bitPatternNear = (WebRtc_Word16)((WebRtc_Word32)aecm->nearLogEnergy[CORR_MAX + j] + * CORR_WIDTH > delayMeanNear[CORR_MAX]); + sumBitPattern += !(bitPatternEcho ^ bitPatternNear); +#endif + aecm->delayCorrelation[i] = sumBitPattern; + } + aecm->newDelayCorrData = 1; // Indicate we have new correlation data to evaluate + } + if ((aecm->startupState == 2) & (aecm->lastDelayUpdateCount > (CORR_WIDTH << 1)) + & aecm->newDelayCorrData) + { + // Find maximum value and maximum position as well as values on the sides. + maxPos = 0; + maxValue = aecm->delayCorrelation[0]; + maxValueLeft = maxValue; + maxValueRight = aecm->delayCorrelation[CORR_DEV]; + for (i = 1; i < CORR_BUF_LEN; i++) + { + if (aecm->delayCorrelation[i] > maxValue) + { + maxValue = aecm->delayCorrelation[i]; + maxPos = i; + if (maxPos < CORR_DEV) + { + maxValueLeft = aecm->delayCorrelation[0]; + maxValueRight = aecm->delayCorrelation[i + CORR_DEV]; + } else if (maxPos > (CORR_MAX << 1) - CORR_DEV) + { + maxValueLeft = aecm->delayCorrelation[i - CORR_DEV]; + maxValueRight = aecm->delayCorrelation[(CORR_MAX << 1)]; + } else + { + maxValueLeft = aecm->delayCorrelation[i - CORR_DEV]; + maxValueRight = aecm->delayCorrelation[i + CORR_DEV]; + } + } + } + if ((maxPos > 0) & (maxPos < (CORR_MAX << 1))) + { + // Avoid maximum at boundaries. The maximum peak has to be higher than + // CORR_MAX_LEVEL. It also has to be sharp, i.e. the value CORR_DEV bins off should + // be CORR_MAX_LOW lower than the maximum. + if ((maxValue > CORR_MAX_LEVEL) & (maxValueLeft < maxValue - CORR_MAX_LOW) + & (maxValueRight < maxValue - CORR_MAX_LOW)) + { + aecm->delayAdjust += CORR_MAX - maxPos; + aecm->newDelayCorrData = 0; + aecm->lastDelayUpdateCount = 0; + } + } + } + // END: "Check delay" +} + +void WebRtcAecm_ProcessBlock(AecmCore_t * const aecm, const WebRtc_Word16 * const farend, + const WebRtc_Word16 * const nearendNoisy, + const WebRtc_Word16 * const nearendClean, + WebRtc_Word16 * const output) +{ + int i, j; + + WebRtc_UWord32 xfaSum; + WebRtc_UWord32 dfaNoisySum; + WebRtc_UWord32 echoEst32Gained; + WebRtc_UWord32 tmpU32; + + WebRtc_Word32 tmp32no1; + WebRtc_Word32 tmp32no2; + WebRtc_Word32 echoEst32[PART_LEN1]; + + WebRtc_UWord16 xfa[PART_LEN1]; + WebRtc_UWord16 dfaNoisy[PART_LEN1]; + WebRtc_UWord16 dfaClean[PART_LEN1]; + WebRtc_UWord16* ptrDfaClean = dfaClean; + + int outCFFT; + + WebRtc_Word16 fft[PART_LEN4]; +#if (defined ARM_WINM) || (defined ARM9E_GCC) || (defined ANDROID_AECOPT) + WebRtc_Word16 postFft[PART_LEN4]; +#else + WebRtc_Word16 postFft[PART_LEN2]; +#endif + WebRtc_Word16 dfwReal[PART_LEN1]; + WebRtc_Word16 dfwImag[PART_LEN1]; + WebRtc_Word16 xfwReal[PART_LEN1]; + WebRtc_Word16 xfwImag[PART_LEN1]; + WebRtc_Word16 efwReal[PART_LEN1]; + WebRtc_Word16 efwImag[PART_LEN1]; + WebRtc_Word16 hnl[PART_LEN1]; + WebRtc_Word16 numPosCoef; + WebRtc_Word16 nlpGain; + WebRtc_Word16 delay, diff, diffMinusOne; + WebRtc_Word16 tmp16no1; + WebRtc_Word16 tmp16no2; +#ifdef AECM_WITH_ABS_APPROX + WebRtc_Word16 maxValue; + WebRtc_Word16 minValue; +#endif + WebRtc_Word16 mu; + WebRtc_Word16 supGain; + WebRtc_Word16 zeros32, zeros16; + WebRtc_Word16 zerosDBufNoisy, zerosDBufClean, zerosXBuf; + WebRtc_Word16 resolutionDiff, qDomainDiff; + +#ifdef ARM_WINM_LOG_ + DWORD temp; + static int flag0 = 0; + __int64 freq, start, end, diff__; + unsigned int milliseconds; +#endif + +#ifdef AECM_WITH_ABS_APPROX + WebRtc_UWord16 alpha, beta; +#endif + + // Determine startup state. There are three states: + // (0) the first CONV_LEN blocks + // (1) another CONV_LEN blocks + // (2) the rest + + if (aecm->startupState < 2) + { + aecm->startupState = (aecm->totCount >= CONV_LEN) + (aecm->totCount >= CONV_LEN2); + } + // END: Determine startup state + + // Buffer near and far end signals + memcpy(aecm->xBuf + PART_LEN, farend, sizeof(WebRtc_Word16) * PART_LEN); + memcpy(aecm->dBufNoisy + PART_LEN, nearendNoisy, sizeof(WebRtc_Word16) * PART_LEN); + if (nearendClean != NULL) + { + memcpy(aecm->dBufClean + PART_LEN, nearendClean, sizeof(WebRtc_Word16) * PART_LEN); + } + +#ifdef AECM_DYNAMIC_Q + tmp16no1 = WebRtcSpl_MaxAbsValueW16(aecm->dBufNoisy, PART_LEN2); + tmp16no2 = WebRtcSpl_MaxAbsValueW16(aecm->xBuf, PART_LEN2); + zerosDBufNoisy = WebRtcSpl_NormW16(tmp16no1); + zerosXBuf = WebRtcSpl_NormW16(tmp16no2); +#else + zerosDBufNoisy = 0; + zerosXBuf = 0; +#endif + aecm->dfaNoisyQDomainOld = aecm->dfaNoisyQDomain; + aecm->dfaNoisyQDomain = zerosDBufNoisy; + + if (nearendClean != NULL) + { +#ifdef AECM_DYNAMIC_Q + tmp16no1 = WebRtcSpl_MaxAbsValueW16(aecm->dBufClean, PART_LEN2); + zerosDBufClean = WebRtcSpl_NormW16(tmp16no1); +#else + zerosDBufClean = 0; +#endif + aecm->dfaCleanQDomainOld = aecm->dfaCleanQDomain; + aecm->dfaCleanQDomain = zerosDBufClean; + } else + { + zerosDBufClean = zerosDBufNoisy; + aecm->dfaCleanQDomainOld = aecm->dfaNoisyQDomainOld; + aecm->dfaCleanQDomain = aecm->dfaNoisyQDomain; + } + +#ifdef ARM_WINM_LOG_ + // measure tick start + QueryPerformanceFrequency((LARGE_INTEGER*)&freq); + QueryPerformanceCounter((LARGE_INTEGER*)&start); +#endif + + // FFT of noisy near end signal + for (i = 0; i < PART_LEN; i++) + { + j = WEBRTC_SPL_LSHIFT_W32(i, 1); + // Window near end + fft[j] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((aecm->dBufNoisy[i] + << zerosDBufNoisy), kSqrtHanning[i], 14); + fft[PART_LEN2 + j] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( + (aecm->dBufNoisy[PART_LEN + i] << zerosDBufNoisy), + kSqrtHanning[PART_LEN - i], 14); + // Inserting zeros in imaginary parts + fft[j + 1] = 0; + fft[PART_LEN2 + j + 1] = 0; + } + + // Fourier transformation of near end signal. + // The result is scaled with 1/PART_LEN2, that is, the result is in Q(-6) for PART_LEN = 32 + +#if (defined ARM_WINM) || (defined ARM9E_GCC) || (defined ANDROID_AECOPT) + outCFFT = WebRtcSpl_ComplexFFT2(fft, postFft, PART_LEN_SHIFT, 1); + + // The imaginary part has to switch sign + for(i = 1; i < PART_LEN2-1;) + { + postFft[i] = -postFft[i]; + i += 2; + postFft[i] = -postFft[i]; + i += 2; + } +#else + WebRtcSpl_ComplexBitReverse(fft, PART_LEN_SHIFT); + outCFFT = WebRtcSpl_ComplexFFT(fft, PART_LEN_SHIFT, 1); + + // Take only the first PART_LEN2 samples + for (i = 0; i < PART_LEN2; i++) + { + postFft[i] = fft[i]; + } + // The imaginary part has to switch sign + for (i = 1; i < PART_LEN2;) + { + postFft[i] = -postFft[i]; + i += 2; + } +#endif + + // Extract imaginary and real part, calculate the magnitude for all frequency bins + dfwImag[0] = 0; + dfwImag[PART_LEN] = 0; + dfwReal[0] = postFft[0]; +#if (defined ARM_WINM) || (defined ARM9E_GCC) || (defined ANDROID_AECOPT) + dfwReal[PART_LEN] = postFft[PART_LEN2]; +#else + dfwReal[PART_LEN] = fft[PART_LEN2]; +#endif + dfaNoisy[0] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(dfwReal[0]); + dfaNoisy[PART_LEN] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(dfwReal[PART_LEN]); + dfaNoisySum = (WebRtc_UWord32)(dfaNoisy[0]); + dfaNoisySum += (WebRtc_UWord32)(dfaNoisy[PART_LEN]); + + for (i = 1; i < PART_LEN; i++) + { + j = WEBRTC_SPL_LSHIFT_W32(i, 1); + dfwReal[i] = postFft[j]; + dfwImag[i] = postFft[j + 1]; + + if (dfwReal[i] == 0 || dfwImag[i] == 0) + { + dfaNoisy[i] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(dfwReal[i] + dfwImag[i]); + } else + { + // Approximation for magnitude of complex fft output + // magn = sqrt(real^2 + imag^2) + // magn ~= alpha * max(|imag|,|real|) + beta * min(|imag|,|real|) + // + // The parameters alpha and beta are stored in Q15 + + tmp16no1 = WEBRTC_SPL_ABS_W16(postFft[j]); + tmp16no2 = WEBRTC_SPL_ABS_W16(postFft[j + 1]); + +#ifdef AECM_WITH_ABS_APPROX + if(tmp16no1 > tmp16no2) + { + maxValue = tmp16no1; + minValue = tmp16no2; + } else + { + maxValue = tmp16no2; + minValue = tmp16no1; + } + + // Magnitude in Q-6 + if ((maxValue >> 2) > minValue) + { + alpha = kAlpha1; + beta = kBeta1; + } else if ((maxValue >> 1) > minValue) + { + alpha = kAlpha2; + beta = kBeta2; + } else + { + alpha = kAlpha3; + beta = kBeta3; + } + tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(maxValue, alpha, 15); + tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(minValue, beta, 15); + dfaNoisy[i] = (WebRtc_UWord16)tmp16no1 + (WebRtc_UWord16)tmp16no2; +#else + tmp32no1 = WEBRTC_SPL_MUL_16_16(tmp16no1, tmp16no1); + tmp32no2 = WEBRTC_SPL_MUL_16_16(tmp16no2, tmp16no2); + tmp32no2 = WEBRTC_SPL_ADD_SAT_W32(tmp32no1, tmp32no2); + tmp32no1 = WebRtcSpl_Sqrt(tmp32no2); + dfaNoisy[i] = (WebRtc_UWord16)tmp32no1; +#endif + } + dfaNoisySum += (WebRtc_UWord32)dfaNoisy[i]; + } + // END: FFT of noisy near end signal + + if (nearendClean == NULL) + { + ptrDfaClean = dfaNoisy; + } else + { + // FFT of clean near end signal + for (i = 0; i < PART_LEN; i++) + { + j = WEBRTC_SPL_LSHIFT_W32(i, 1); + // Window near end + fft[j] + = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((aecm->dBufClean[i] << zerosDBufClean), kSqrtHanning[i], 14); + fft[PART_LEN2 + j] + = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((aecm->dBufClean[PART_LEN + i] << zerosDBufClean), kSqrtHanning[PART_LEN - i], 14); + // Inserting zeros in imaginary parts + fft[j + 1] = 0; + fft[PART_LEN2 + j + 1] = 0; + } + + // Fourier transformation of near end signal. + // The result is scaled with 1/PART_LEN2, that is, in Q(-6) for PART_LEN = 32 + +#if (defined ARM_WINM) || (defined ARM9E_GCC) || (defined ANDROID_AECOPT) + outCFFT = WebRtcSpl_ComplexFFT2(fft, postFft, PART_LEN_SHIFT, 1); + + // The imaginary part has to switch sign + for(i = 1; i < PART_LEN2-1;) + { + postFft[i] = -postFft[i]; + i += 2; + postFft[i] = -postFft[i]; + i += 2; + } +#else + WebRtcSpl_ComplexBitReverse(fft, PART_LEN_SHIFT); + outCFFT = WebRtcSpl_ComplexFFT(fft, PART_LEN_SHIFT, 1); + + // Take only the first PART_LEN2 samples + for (i = 0; i < PART_LEN2; i++) + { + postFft[i] = fft[i]; + } + // The imaginary part has to switch sign + for (i = 1; i < PART_LEN2;) + { + postFft[i] = -postFft[i]; + i += 2; + } +#endif + + // Extract imaginary and real part, calculate the magnitude for all frequency bins + dfwImag[0] = 0; + dfwImag[PART_LEN] = 0; + dfwReal[0] = postFft[0]; +#if (defined ARM_WINM) || (defined ARM9E_GCC) || (defined ANDROID_AECOPT) + dfwReal[PART_LEN] = postFft[PART_LEN2]; +#else + dfwReal[PART_LEN] = fft[PART_LEN2]; +#endif + dfaClean[0] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(dfwReal[0]); + dfaClean[PART_LEN] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(dfwReal[PART_LEN]); + + for (i = 1; i < PART_LEN; i++) + { + j = WEBRTC_SPL_LSHIFT_W32(i, 1); + dfwReal[i] = postFft[j]; + dfwImag[i] = postFft[j + 1]; + + if (dfwReal[i] == 0 || dfwImag[i] == 0) + { + dfaClean[i] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(dfwReal[i] + dfwImag[i]); + } else + { + // Approximation for magnitude of complex fft output + // magn = sqrt(real^2 + imag^2) + // magn ~= alpha * max(|imag|,|real|) + beta * min(|imag|,|real|) + // + // The parameters alpha and beta are stored in Q15 + + tmp16no1 = WEBRTC_SPL_ABS_W16(postFft[j]); + tmp16no2 = WEBRTC_SPL_ABS_W16(postFft[j + 1]); + +#ifdef AECM_WITH_ABS_APPROX + if(tmp16no1 > tmp16no2) + { + maxValue = tmp16no1; + minValue = tmp16no2; + } else + { + maxValue = tmp16no2; + minValue = tmp16no1; + } + + // Magnitude in Q-6 + if ((maxValue >> 2) > minValue) + { + alpha = kAlpha1; + beta = kBeta1; + } else if ((maxValue >> 1) > minValue) + { + alpha = kAlpha2; + beta = kBeta2; + } else + { + alpha = kAlpha3; + beta = kBeta3; + } + tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(maxValue, alpha, 15); + tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(minValue, beta, 15); + dfaClean[i] = (WebRtc_UWord16)tmp16no1 + (WebRtc_UWord16)tmp16no2; +#else + tmp32no1 = WEBRTC_SPL_MUL_16_16(tmp16no1, tmp16no1); + tmp32no2 = WEBRTC_SPL_MUL_16_16(tmp16no2, tmp16no2); + tmp32no2 = WEBRTC_SPL_ADD_SAT_W32(tmp32no1, tmp32no2); + tmp32no1 = WebRtcSpl_Sqrt(tmp32no2); + dfaClean[i] = (WebRtc_UWord16)tmp32no1; +#endif + } + } + } + // END: FFT of clean near end signal + + // FFT of far end signal + for (i = 0; i < PART_LEN; i++) + { + j = WEBRTC_SPL_LSHIFT_W32(i, 1); + // Window farend + fft[j] + = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((aecm->xBuf[i] << zerosXBuf), kSqrtHanning[i], 14); + fft[PART_LEN2 + j] + = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((aecm->xBuf[PART_LEN + i] << zerosXBuf), kSqrtHanning[PART_LEN - i], 14); + // Inserting zeros in imaginary parts + fft[j + 1] = 0; + fft[PART_LEN2 + j + 1] = 0; + } + // Fourier transformation of far end signal. + // The result is scaled with 1/PART_LEN2, that is the result is in Q(-6) for PART_LEN = 32 +#if (defined ARM_WINM) || (defined ARM9E_GCC) || (defined ANDROID_AECOPT) + outCFFT = WebRtcSpl_ComplexFFT2(fft, postFft, PART_LEN_SHIFT, 1); + + // The imaginary part has to switch sign + for(i = 1; i < PART_LEN2-1;) + { + postFft[i] = -postFft[i]; + i += 2; + postFft[i] = -postFft[i]; + i += 2; + } +#else + WebRtcSpl_ComplexBitReverse(fft, PART_LEN_SHIFT); + outCFFT = WebRtcSpl_ComplexFFT(fft, PART_LEN_SHIFT, 1); + + // Take only the first PART_LEN2 samples + for (i = 0; i < PART_LEN2; i++) + { + postFft[i] = fft[i]; + } + // The imaginary part has to switch sign + for (i = 1; i < PART_LEN2;) + { + postFft[i] = -postFft[i]; + i += 2; + } +#endif + + // Extract imaginary and real part, calculate the magnitude for all frequency bins + xfwImag[0] = 0; + xfwImag[PART_LEN] = 0; + xfwReal[0] = postFft[0]; +#if (defined ARM_WINM) || (defined ARM9E_GCC) || (defined ANDROID_AECOPT) + xfwReal[PART_LEN] = postFft[PART_LEN2]; +#else + xfwReal[PART_LEN] = fft[PART_LEN2]; +#endif + xfa[0] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(xfwReal[0]); + xfa[PART_LEN] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(xfwReal[PART_LEN]); + xfaSum = (WebRtc_UWord32)(xfa[0]) + (WebRtc_UWord32)(xfa[PART_LEN]); + + for (i = 1; i < PART_LEN; i++) + { + j = WEBRTC_SPL_LSHIFT_W32(i,1); + xfwReal[i] = postFft[j]; + xfwImag[i] = postFft[j + 1]; + + if (xfwReal[i] == 0 || xfwImag[i] == 0) + { + xfa[i] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(xfwReal[i] + xfwImag[i]); + } else + { + // Approximation for magnitude of complex fft output + // magn = sqrt(real^2 + imag^2) + // magn ~= alpha * max(|imag|,|real|) + beta * min(|imag|,|real|) + // + // The parameters alpha and beta are stored in Q15 + + tmp16no1 = WEBRTC_SPL_ABS_W16(postFft[j]); + tmp16no2 = WEBRTC_SPL_ABS_W16(postFft[j + 1]); + +#ifdef AECM_WITH_ABS_APPROX + if(tmp16no1 > xfwImag[i]) + { + maxValue = tmp16no1; + minValue = tmp16no2; + } else + { + maxValue = tmp16no2; + minValue = tmp16no1; + } + // Magnitude in Q-6 + if ((maxValue >> 2) > minValue) + { + alpha = kAlpha1; + beta = kBeta1; + } else if ((maxValue >> 1) > minValue) + { + alpha = kAlpha2; + beta = kBeta2; + } else + { + alpha = kAlpha3; + beta = kBeta3; + } + tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(maxValue, alpha, 15); + tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(minValue, beta, 15); + xfa[i] = (WebRtc_UWord16)tmp16no1 + (WebRtc_UWord16)tmp16no2; +#else + tmp32no1 = WEBRTC_SPL_MUL_16_16(tmp16no1, tmp16no1); + tmp32no2 = WEBRTC_SPL_MUL_16_16(tmp16no2, tmp16no2); + tmp32no2 = WEBRTC_SPL_ADD_SAT_W32(tmp32no1, tmp32no2); + tmp32no1 = WebRtcSpl_Sqrt(tmp32no2); + xfa[i] = (WebRtc_UWord16)tmp32no1; +#endif + } + xfaSum += (WebRtc_UWord32)xfa[i]; + } + +#ifdef ARM_WINM_LOG_ + // measure tick end + QueryPerformanceCounter((LARGE_INTEGER*)&end); + diff__ = ((end - start) * 1000) / (freq/1000); + milliseconds = (unsigned int)(diff__ & 0xffffffff); + WriteFile (logFile, &milliseconds, sizeof(unsigned int), &temp, NULL); +#endif + // END: FFT of far end signal + + // Get the delay + + // Fixed delay estimation + // input: dfaFIX, xfaFIX in Q-stages + // output: delay in Q0 + // + // comment on the fixed point accuracy of estimate_delayFIX + // -> due to rounding the fixed point variables xfa and dfa contain a lot more zeros + // than the corresponding floating point variables this results in big differences + // between the floating point and the fixed point logarithmic spectra for small values +#ifdef ARM_WINM_LOG_ + // measure tick start + QueryPerformanceCounter((LARGE_INTEGER*)&start); +#endif + + // Save far-end history and estimate delay + delay = WebRtcAecm_EstimateDelay(aecm, xfa, dfaNoisy, zerosXBuf); + + if (aecm->fixedDelay >= 0) + { + // Use fixed delay + delay = aecm->fixedDelay; + } + + aecm->currentDelay = delay; + + if ((aecm->delayOffsetFlag) & (aecm->startupState > 0)) // If delay compensation is on + { + // If the delay estimate changed from previous block, update the offset + if ((aecm->currentDelay != aecm->previousDelay) & !aecm->currentDelay + & !aecm->previousDelay) + { + aecm->delayAdjust += (aecm->currentDelay - aecm->previousDelay); + } + // Compensate with the offset estimate + aecm->currentDelay -= aecm->delayAdjust; + aecm->previousDelay = delay; + } + + diff = aecm->delHistoryPos - aecm->currentDelay; + if (diff < 0) + { + diff = diff + MAX_DELAY; + } + +#ifdef ARM_WINM_LOG_ + // measure tick end + QueryPerformanceCounter((LARGE_INTEGER*)&end); + diff__ = ((end - start) * 1000) / (freq/1000); + milliseconds = (unsigned int)(diff__ & 0xffffffff); + WriteFile (logFile, &milliseconds, sizeof(unsigned int), &temp, NULL); +#endif + + // END: Get the delay + +#ifdef ARM_WINM_LOG_ + // measure tick start + QueryPerformanceCounter((LARGE_INTEGER*)&start); +#endif + // Calculate log(energy) and update energy threshold levels + WebRtcAecm_CalcEnergies(aecm, diff, dfaNoisySum, echoEst32); + + // Calculate stepsize + mu = WebRtcAecm_CalcStepSize(aecm); + + // END: Update step size + + // Update counters + aecm->totCount++; + aecm->lastDelayUpdateCount++; + + // This is the channel estimation algorithm. + // It is base on NLMS but has a variable step length, which was calculated above. + WebRtcAecm_UpdateChannel(aecm, dfaNoisy, diff, mu, echoEst32); + WebRtcAecm_DelayCompensation(aecm); + supGain = WebRtcAecm_CalcSuppressionGain(aecm); + +#ifdef ARM_WINM_LOG_ + // measure tick end + QueryPerformanceCounter((LARGE_INTEGER*)&end); + diff__ = ((end - start) * 1000) / (freq/1000); + milliseconds = (unsigned int)(diff__ & 0xffffffff); + WriteFile (logFile, &milliseconds, sizeof(unsigned int), &temp, NULL); +#endif + + // END: Update suppression gain + +#ifdef ARM_WINM_LOG_ + // measure tick start + QueryPerformanceCounter((LARGE_INTEGER*)&start); +#endif + + // Calculate Wiener filter hnl[] + numPosCoef = 0; + diffMinusOne = diff - 1; + if (diff == 0) + { + diffMinusOne = MAX_DELAY; + } + for (i = 0; i < PART_LEN1; i++) + { + // Far end signal through channel estimate in Q8 + // How much can we shift right to preserve resolution + tmp32no1 = echoEst32[i] - aecm->echoFilt[i]; + aecm->echoFilt[i] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_32_16(tmp32no1, 50), 8); + + zeros32 = WebRtcSpl_NormW32(aecm->echoFilt[i]) + 1; + zeros16 = WebRtcSpl_NormW16(supGain) + 1; + if (zeros32 + zeros16 > 16) + { + // Multiplication is safe + // Result in Q(RESOLUTION_CHANNEL+RESOLUTION_SUPGAIN+aecm->xfaQDomainBuf[diff]) + echoEst32Gained = WEBRTC_SPL_UMUL_32_16((WebRtc_UWord32)aecm->echoFilt[i], + (WebRtc_UWord16)supGain); + resolutionDiff = 14 - RESOLUTION_CHANNEL16 - RESOLUTION_SUPGAIN; + resolutionDiff += (aecm->dfaCleanQDomain - aecm->xfaQDomainBuf[diff]); + } else + { + tmp16no1 = 17 - zeros32 - zeros16; + resolutionDiff = 14 + tmp16no1 - RESOLUTION_CHANNEL16 - RESOLUTION_SUPGAIN; + resolutionDiff += (aecm->dfaCleanQDomain - aecm->xfaQDomainBuf[diff]); + if (zeros32 > tmp16no1) + { + echoEst32Gained = WEBRTC_SPL_UMUL_32_16((WebRtc_UWord32)aecm->echoFilt[i], + (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_W16(supGain, + tmp16no1)); // Q-(RESOLUTION_CHANNEL+RESOLUTION_SUPGAIN-16) + } else + { + // Result in Q-(RESOLUTION_CHANNEL+RESOLUTION_SUPGAIN-16) + echoEst32Gained = WEBRTC_SPL_UMUL_32_16( + (WebRtc_UWord32)WEBRTC_SPL_RSHIFT_W32(aecm->echoFilt[i], tmp16no1), + (WebRtc_UWord16)supGain); + } + } + + zeros16 = WebRtcSpl_NormW16(aecm->nearFilt[i]); + if ((zeros16 < (aecm->dfaCleanQDomain - aecm->dfaCleanQDomainOld)) + & (aecm->nearFilt[i])) + { + tmp16no1 = WEBRTC_SPL_SHIFT_W16(aecm->nearFilt[i], zeros16); + qDomainDiff = zeros16 - aecm->dfaCleanQDomain + aecm->dfaCleanQDomainOld; + } else + { + tmp16no1 = WEBRTC_SPL_SHIFT_W16(aecm->nearFilt[i], aecm->dfaCleanQDomain + - aecm->dfaCleanQDomainOld); + qDomainDiff = 0; + } + tmp16no2 = WEBRTC_SPL_SHIFT_W16(ptrDfaClean[i], qDomainDiff); + tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16no2 - tmp16no1, 1, 4); + tmp16no2 += tmp16no1; + zeros16 = WebRtcSpl_NormW16(tmp16no2); + if ((tmp16no2) & (-qDomainDiff > zeros16)) + { + aecm->nearFilt[i] = WEBRTC_SPL_WORD16_MAX; + } else + { + aecm->nearFilt[i] = WEBRTC_SPL_SHIFT_W16(tmp16no2, -qDomainDiff); + } + + // Wiener filter coefficients, resulting hnl in Q14 + if (echoEst32Gained == 0) + { + hnl[i] = ONE_Q14; + } else if (aecm->nearFilt[i] == 0) + { + hnl[i] = 0; + } else + { + // Multiply the suppression gain + // Rounding + echoEst32Gained += (WebRtc_UWord32)(aecm->nearFilt[i] >> 1); + tmpU32 = WebRtcSpl_DivU32U16(echoEst32Gained, (WebRtc_UWord16)aecm->nearFilt[i]); + + // Current resolution is + // Q-(RESOLUTION_CHANNEL + RESOLUTION_SUPGAIN - max(0, 17 - zeros16 - zeros32)) + // Make sure we are in Q14 + tmp32no1 = (WebRtc_Word32)WEBRTC_SPL_SHIFT_W32(tmpU32, resolutionDiff); + if (tmp32no1 > ONE_Q14) + { + hnl[i] = 0; + } else if (tmp32no1 < 0) + { + hnl[i] = ONE_Q14; + } else + { + // 1-echoEst/dfa +#if (!defined ARM_WINM) && (!defined ARM9E_GCC) && (!defined ANDROID_AECOPT) + hnl[i] = ONE_Q14 - (WebRtc_Word16)tmp32no1; + if (hnl[i] < 0) + { + hnl[i] = 0; + } +#else + hnl[i] = ((ONE_Q14 - (WebRtc_Word16)tmp32no1) > 0) ? (ONE_Q14 - (WebRtc_Word16)tmp32no1) : 0; +#endif + } + } + if (hnl[i]) + { + numPosCoef++; + } + } + +#ifdef ARM_WINM_LOG_ + // measure tick end + QueryPerformanceCounter((LARGE_INTEGER*)&end); + diff__ = ((end - start) * 1000) / (freq/1000); + milliseconds = (unsigned int)(diff__ & 0xffffffff); + WriteFile (logFile, &milliseconds, sizeof(unsigned int), &temp, NULL); +#endif + +#ifdef ARM_WINM_LOG_ + // measure tick start + QueryPerformanceCounter((LARGE_INTEGER*)&start); +#endif + + // Calculate NLP gain, result is in Q14 + for (i = 0; i < PART_LEN1; i++) + { + if (aecm->nlpFlag) + { + // Truncate values close to zero and one. + if (hnl[i] > NLP_COMP_HIGH) + { + hnl[i] = ONE_Q14; + } else if (hnl[i] < NLP_COMP_LOW) + { + hnl[i] = 0; + } + + // Remove outliers + if (numPosCoef < 3) + { + nlpGain = 0; + } else + { + nlpGain = ONE_Q14; + } + // NLP + if ((hnl[i] == ONE_Q14) && (nlpGain == ONE_Q14)) + { + hnl[i] = ONE_Q14; + } else + { + hnl[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(hnl[i], nlpGain, 14); + } + } + + // multiply with Wiener coefficients + efwReal[i] = (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfwReal[i], hnl[i], + 14)); + efwImag[i] = (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfwImag[i], hnl[i], + 14)); + } + + if (aecm->cngMode == AecmTrue) + { + WebRtcAecm_ComfortNoise(aecm, ptrDfaClean, efwReal, efwImag, hnl); + } + +#ifdef ARM_WINM_LOG_ + // measure tick end + QueryPerformanceCounter((LARGE_INTEGER*)&end); + diff__ = ((end - start) * 1000) / (freq/1000); + milliseconds = (unsigned int)(diff__ & 0xffffffff); + WriteFile (logFile, &milliseconds, sizeof(unsigned int), &temp, NULL); +#endif + +#ifdef ARM_WINM_LOG_ + // measure tick start + QueryPerformanceCounter((LARGE_INTEGER*)&start); +#endif + + // Synthesis + for (i = 1; i < PART_LEN; i++) + { + j = WEBRTC_SPL_LSHIFT_W32(i, 1); + fft[j] = efwReal[i]; + + // mirrored data, even + fft[PART_LEN4 - j] = efwReal[i]; + fft[j + 1] = -efwImag[i]; + + //mirrored data, odd + fft[PART_LEN4 - (j - 1)] = efwImag[i]; + } + fft[0] = efwReal[0]; + fft[1] = -efwImag[0]; + + fft[PART_LEN2] = efwReal[PART_LEN]; + fft[PART_LEN2 + 1] = -efwImag[PART_LEN]; + +#if (!defined ARM_WINM) && (!defined ARM9E_GCC) && (!defined ANDROID_AECOPT) + // inverse FFT, result should be scaled with outCFFT + WebRtcSpl_ComplexBitReverse(fft, PART_LEN_SHIFT); + outCFFT = WebRtcSpl_ComplexIFFT(fft, PART_LEN_SHIFT, 1); + + //take only the real values and scale with outCFFT + for (i = 0; i < PART_LEN2; i++) + { + j = WEBRTC_SPL_LSHIFT_W32(i, 1); + fft[i] = fft[j]; + } +#else + outCFFT = WebRtcSpl_ComplexIFFT2(fft, postFft, PART_LEN_SHIFT, 1); + + //take only the real values and scale with outCFFT + for(i = 0, j = 0; i < PART_LEN2;) + { + fft[i] = postFft[j]; + i += 1; + j += 2; + fft[i] = postFft[j]; + i += 1; + j += 2; + } +#endif + + for (i = 0; i < PART_LEN; i++) + { + fft[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND( + fft[i], + kSqrtHanning[i], + 14); + tmp32no1 = WEBRTC_SPL_SHIFT_W32((WebRtc_Word32)fft[i], + outCFFT - aecm->dfaCleanQDomain); + fft[i] = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, + tmp32no1 + aecm->outBuf[i], + WEBRTC_SPL_WORD16_MIN); + output[i] = fft[i]; + + tmp32no1 = WEBRTC_SPL_MUL_16_16_RSFT( + fft[PART_LEN + i], + kSqrtHanning[PART_LEN - i], + 14); + tmp32no1 = WEBRTC_SPL_SHIFT_W32(tmp32no1, + outCFFT - aecm->dfaCleanQDomain); + aecm->outBuf[i] = (WebRtc_Word16)WEBRTC_SPL_SAT( + WEBRTC_SPL_WORD16_MAX, + tmp32no1, + WEBRTC_SPL_WORD16_MIN); + } + +#ifdef ARM_WINM_LOG_ + // measure tick end + QueryPerformanceCounter((LARGE_INTEGER*)&end); + diff__ = ((end - start) * 1000) / (freq/1000); + milliseconds = (unsigned int)(diff__ & 0xffffffff); + WriteFile (logFile, &milliseconds, sizeof(unsigned int), &temp, NULL); +#endif + // Copy the current block to the old position (outBuf is shifted elsewhere) + memcpy(aecm->xBuf, aecm->xBuf + PART_LEN, sizeof(WebRtc_Word16) * PART_LEN); + memcpy(aecm->dBufNoisy, aecm->dBufNoisy + PART_LEN, sizeof(WebRtc_Word16) * PART_LEN); + if (nearendClean != NULL) + { + memcpy(aecm->dBufClean, aecm->dBufClean + PART_LEN, sizeof(WebRtc_Word16) * PART_LEN); + } +} + +// Generate comfort noise and add to output signal. +// +// \param[in] aecm Handle of the AECM instance. +// \param[in] dfa Absolute value of the nearend signal (Q[aecm->dfaQDomain]). +// \param[in,out] outReal Real part of the output signal (Q[aecm->dfaQDomain]). +// \param[in,out] outImag Imaginary part of the output signal (Q[aecm->dfaQDomain]). +// \param[in] lambda Suppression gain with which to scale the noise level (Q14). +// +static void WebRtcAecm_ComfortNoise(AecmCore_t * const aecm, const WebRtc_UWord16 * const dfa, + WebRtc_Word16 * const outReal, + WebRtc_Word16 * const outImag, + const WebRtc_Word16 * const lambda) +{ + WebRtc_Word16 i; + WebRtc_Word16 tmp16; + WebRtc_Word32 tmp32; + + WebRtc_Word16 randW16[PART_LEN]; + WebRtc_Word16 uReal[PART_LEN1]; + WebRtc_Word16 uImag[PART_LEN1]; + WebRtc_Word32 outLShift32[PART_LEN1]; + WebRtc_Word16 noiseRShift16[PART_LEN1]; + + WebRtc_Word16 shiftFromNearToNoise[PART_LEN1]; + WebRtc_Word16 minTrackShift; + WebRtc_Word32 upper32; + WebRtc_Word32 lower32; + + if (aecm->noiseEstCtr < 100) + { + // Track the minimum more quickly initially. + aecm->noiseEstCtr++; + minTrackShift = 7; + } else + { + minTrackShift = 9; + } + + // Estimate noise power. + for (i = 0; i < PART_LEN1; i++) + { + shiftFromNearToNoise[i] = aecm->noiseEstQDomain[i] - aecm->dfaCleanQDomain; + + // Shift to the noise domain. + tmp32 = (WebRtc_Word32)dfa[i]; + outLShift32[i] = WEBRTC_SPL_SHIFT_W32(tmp32, shiftFromNearToNoise[i]); + + if (outLShift32[i] < aecm->noiseEst[i]) + { + // Track the minimum. + aecm->noiseEst[i] += ((outLShift32[i] - aecm->noiseEst[i]) >> minTrackShift); + } else + { + // Ramp slowly upwards until we hit the minimum again. + + // Avoid overflow. + if (aecm->noiseEst[i] < 2146435583) + { + // Store the fractional portion. + upper32 = (aecm->noiseEst[i] & 0xffff0000) >> 16; + lower32 = aecm->noiseEst[i] & 0x0000ffff; + upper32 = ((upper32 * 2049) >> 11); + lower32 = ((lower32 * 2049) >> 11); + aecm->noiseEst[i] = WEBRTC_SPL_ADD_SAT_W32(upper32 << 16, lower32); + } + } + } + + for (i = 0; i < PART_LEN1; i++) + { + tmp32 = WEBRTC_SPL_SHIFT_W32(aecm->noiseEst[i], -shiftFromNearToNoise[i]); + if (tmp32 > 32767) + { + tmp32 = 32767; + aecm->noiseEst[i] = WEBRTC_SPL_SHIFT_W32(tmp32, shiftFromNearToNoise[i]); + } + noiseRShift16[i] = (WebRtc_Word16)tmp32; + + tmp16 = ONE_Q14 - lambda[i]; + noiseRShift16[i] + = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16, noiseRShift16[i], 14); + } + + // Generate a uniform random array on [0 2^15-1]. + WebRtcSpl_RandUArray(randW16, PART_LEN, &aecm->seed); + + // Generate noise according to estimated energy. + uReal[0] = 0; // Reject LF noise. + uImag[0] = 0; + for (i = 1; i < PART_LEN1; i++) + { + // Get a random index for the cos and sin tables over [0 359]. + tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(359, randW16[i - 1], 15); + + // Tables are in Q13. + uReal[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(noiseRShift16[i], + WebRtcSpl_kCosTable[tmp16], 13); + uImag[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(-noiseRShift16[i], + WebRtcSpl_kSinTable[tmp16], 13); + } + uImag[PART_LEN] = 0; + +#if (!defined ARM_WINM) && (!defined ARM9E_GCC) && (!defined ANDROID_AECOPT) + for (i = 0; i < PART_LEN1; i++) + { + outReal[i] = WEBRTC_SPL_ADD_SAT_W16(outReal[i], uReal[i]); + outImag[i] = WEBRTC_SPL_ADD_SAT_W16(outImag[i], uImag[i]); + } +#else + for (i = 0; i < PART_LEN1 -1; ) + { + outReal[i] = WEBRTC_SPL_ADD_SAT_W16(outReal[i], uReal[i]); + outImag[i] = WEBRTC_SPL_ADD_SAT_W16(outImag[i], uImag[i]); + i++; + + outReal[i] = WEBRTC_SPL_ADD_SAT_W16(outReal[i], uReal[i]); + outImag[i] = WEBRTC_SPL_ADD_SAT_W16(outImag[i], uImag[i]); + i++; + } + outReal[i] = WEBRTC_SPL_ADD_SAT_W16(outReal[i], uReal[i]); + outImag[i] = WEBRTC_SPL_ADD_SAT_W16(outImag[i], uImag[i]); +#endif +} + +void WebRtcAecm_BufferFarFrame(AecmCore_t * const aecm, const WebRtc_Word16 * const farend, + const int farLen) +{ + int writeLen = farLen, writePos = 0; + + // Check if the write position must be wrapped + while (aecm->farBufWritePos + writeLen > FAR_BUF_LEN) + { + // Write to remaining buffer space before wrapping + writeLen = FAR_BUF_LEN - aecm->farBufWritePos; + memcpy(aecm->farBuf + aecm->farBufWritePos, farend + writePos, + sizeof(WebRtc_Word16) * writeLen); + aecm->farBufWritePos = 0; + writePos = writeLen; + writeLen = farLen - writeLen; + } + + memcpy(aecm->farBuf + aecm->farBufWritePos, farend + writePos, + sizeof(WebRtc_Word16) * writeLen); + aecm->farBufWritePos += writeLen; +} + +void WebRtcAecm_FetchFarFrame(AecmCore_t * const aecm, WebRtc_Word16 * const farend, + const int farLen, const int knownDelay) +{ + int readLen = farLen; + int readPos = 0; + int delayChange = knownDelay - aecm->lastKnownDelay; + + aecm->farBufReadPos -= delayChange; + + // Check if delay forces a read position wrap + while (aecm->farBufReadPos < 0) + { + aecm->farBufReadPos += FAR_BUF_LEN; + } + while (aecm->farBufReadPos > FAR_BUF_LEN - 1) + { + aecm->farBufReadPos -= FAR_BUF_LEN; + } + + aecm->lastKnownDelay = knownDelay; + + // Check if read position must be wrapped + while (aecm->farBufReadPos + readLen > FAR_BUF_LEN) + { + + // Read from remaining buffer space before wrapping + readLen = FAR_BUF_LEN - aecm->farBufReadPos; + memcpy(farend + readPos, aecm->farBuf + aecm->farBufReadPos, + sizeof(WebRtc_Word16) * readLen); + aecm->farBufReadPos = 0; + readPos = readLen; + readLen = farLen - readLen; + } + memcpy(farend + readPos, aecm->farBuf + aecm->farBufReadPos, + sizeof(WebRtc_Word16) * readLen); + aecm->farBufReadPos += readLen; +} diff --git a/src/libs/webrtc/aecm/aecm_core.h b/src/libs/webrtc/aecm/aecm_core.h new file mode 100644 index 00000000..a85b3ff4 --- /dev/null +++ b/src/libs/webrtc/aecm/aecm_core.h @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// Performs echo control (suppression) with fft routines in fixed-point + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AECM_MAIN_SOURCE_AECM_CORE_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_AECM_MAIN_SOURCE_AECM_CORE_H_ + +#define AECM_DYNAMIC_Q // turn on/off dynamic Q-domain +//#define AECM_WITH_ABS_APPROX +//#define AECM_SHORT // for 32 sample partition length (otherwise 64) + +#include "typedefs.h" +#include "signal_processing_library.h" +#include "typedefs.h" + +// Algorithm parameters + +#define FRAME_LEN 80 // Total frame length, 10 ms +#ifdef AECM_SHORT + +#define PART_LEN 32 // Length of partition +#define PART_LEN_SHIFT 6 // Length of (PART_LEN * 2) in base 2 + +#else + +#define PART_LEN 64 // Length of partition +#define PART_LEN_SHIFT 7 // Length of (PART_LEN * 2) in base 2 + +#endif + +#define PART_LEN1 (PART_LEN + 1) // Unique fft coefficients +#define PART_LEN2 (PART_LEN << 1) // Length of partition * 2 +#define PART_LEN4 (PART_LEN << 2) // Length of partition * 4 +#define FAR_BUF_LEN PART_LEN4 // Length of buffers +#define MAX_DELAY 100 + +// Counter parameters +#ifdef AECM_SHORT + +#define CONV_LEN 1024 // Convergence length used at startup +#else + +#define CONV_LEN 512 // Convergence length used at startup +#endif + +#define CONV_LEN2 (CONV_LEN << 1) // Convergence length * 2 used at startup +// Energy parameters +#define MAX_BUF_LEN 64 // History length of energy signals +#define FAR_ENERGY_MIN 1025 // Lowest Far energy level: At least 2 in energy +#define FAR_ENERGY_DIFF 511 // Difference between max and min should be at least 2 (Q8) +#define ENERGY_DEV_OFFSET 0 // The energy error offset in Q8 +#define ENERGY_DEV_TOL 400 // The energy estimation tolerance in Q8 +#define FAR_ENERGY_VAD_REGION 230 // Far VAD tolerance region +// Stepsize parameters +#define MU_MIN 10 // Min stepsize 2^-MU_MIN (far end energy dependent) +#define MU_MAX 1 // Max stepsize 2^-MU_MAX (far end energy dependent) +#define MU_DIFF 9 // MU_MIN - MU_MAX +// Channel parameters +#define MIN_MSE_COUNT 20 // Min number of consecutive blocks with enough far end + // energy to compare channel estimates +#define MIN_MSE_DIFF 29 // The ratio between adapted and stored channel to + // accept a new storage (0.8 in Q-MSE_RESOLUTION) +#define MSE_RESOLUTION 5 // MSE parameter resolution +#define RESOLUTION_CHANNEL16 12 // W16 Channel in Q-RESOLUTION_CHANNEL16 +#define RESOLUTION_CHANNEL32 28 // W32 Channel in Q-RESOLUTION_CHANNEL +#define CHANNEL_VAD 16 // Minimum energy in frequency band to update channel +// Suppression gain parameters: SUPGAIN_ parameters in Q-(RESOLUTION_SUPGAIN) +#define RESOLUTION_SUPGAIN 8 // Channel in Q-(RESOLUTION_SUPGAIN) +#define SUPGAIN_DEFAULT (1 << RESOLUTION_SUPGAIN) // Default suppression gain +#define SUPGAIN_ERROR_PARAM_A 3072 // Estimation error parameter (Maximum gain) (8 in Q8) +#define SUPGAIN_ERROR_PARAM_B 1536 // Estimation error parameter (Gain before going down) +#define SUPGAIN_ERROR_PARAM_D SUPGAIN_DEFAULT // Estimation error parameter + // (Should be the same as Default) (1 in Q8) +#define SUPGAIN_EPC_DT 200 // = SUPGAIN_ERROR_PARAM_C * ENERGY_DEV_TOL +// Defines for "check delay estimation" +#define CORR_WIDTH 31 // Number of samples to correlate over. +#define CORR_MAX 16 // Maximum correlation offset +#define CORR_MAX_BUF 63 +#define CORR_DEV 4 +#define CORR_MAX_LEVEL 20 +#define CORR_MAX_LOW 4 +#define CORR_BUF_LEN (CORR_MAX << 1) + 1 +// Note that CORR_WIDTH + 2*CORR_MAX <= MAX_BUF_LEN + +#define ONE_Q14 (1 << 14) + +// NLP defines +#define NLP_COMP_LOW 3277 // 0.2 in Q14 +#define NLP_COMP_HIGH ONE_Q14 // 1 in Q14 + +typedef struct +{ + int farBufWritePos; + int farBufReadPos; + int knownDelay; + int lastKnownDelay; + + void *farFrameBuf; + void *nearNoisyFrameBuf; + void *nearCleanFrameBuf; + void *outFrameBuf; + + WebRtc_Word16 xBuf[PART_LEN2]; // farend + WebRtc_Word16 dBufClean[PART_LEN2]; // nearend + WebRtc_Word16 dBufNoisy[PART_LEN2]; // nearend + WebRtc_Word16 outBuf[PART_LEN]; + + WebRtc_Word16 farBuf[FAR_BUF_LEN]; + + WebRtc_Word16 mult; + WebRtc_UWord32 seed; + + // Delay estimation variables + WebRtc_UWord16 medianYlogspec[PART_LEN1]; + WebRtc_UWord16 medianXlogspec[PART_LEN1]; + WebRtc_UWord16 medianBCount[MAX_DELAY]; + WebRtc_UWord16 xfaHistory[PART_LEN1][MAX_DELAY]; + WebRtc_Word16 delHistoryPos; + WebRtc_UWord32 bxHistory[MAX_DELAY]; + WebRtc_UWord16 currentDelay; + WebRtc_UWord16 previousDelay; + WebRtc_Word16 delayAdjust; + + WebRtc_Word16 nlpFlag; + WebRtc_Word16 fixedDelay; + + WebRtc_UWord32 totCount; + + WebRtc_Word16 xfaQDomainBuf[MAX_DELAY]; + WebRtc_Word16 dfaCleanQDomain; + WebRtc_Word16 dfaCleanQDomainOld; + WebRtc_Word16 dfaNoisyQDomain; + WebRtc_Word16 dfaNoisyQDomainOld; + + WebRtc_Word16 nearLogEnergy[MAX_BUF_LEN]; + WebRtc_Word16 farLogEnergy[MAX_BUF_LEN]; + WebRtc_Word16 echoAdaptLogEnergy[MAX_BUF_LEN]; + WebRtc_Word16 echoStoredLogEnergy[MAX_BUF_LEN]; + + WebRtc_Word16 channelAdapt16[PART_LEN1]; + WebRtc_Word32 channelAdapt32[PART_LEN1]; + WebRtc_Word16 channelStored[PART_LEN1]; + WebRtc_Word32 echoFilt[PART_LEN1]; + WebRtc_Word16 nearFilt[PART_LEN1]; + WebRtc_Word32 noiseEst[PART_LEN1]; + WebRtc_Word16 noiseEstQDomain[PART_LEN1]; + WebRtc_Word16 noiseEstCtr; + WebRtc_Word16 cngMode; + + WebRtc_Word32 mseAdaptOld; + WebRtc_Word32 mseStoredOld; + WebRtc_Word32 mseThreshold; + + WebRtc_Word16 farEnergyMin; + WebRtc_Word16 farEnergyMax; + WebRtc_Word16 farEnergyMaxMin; + WebRtc_Word16 farEnergyVAD; + WebRtc_Word16 farEnergyMSE; + WebRtc_Word16 currentVADValue; + WebRtc_Word16 vadUpdateCount; + + WebRtc_Word16 delayHistogram[MAX_DELAY]; + WebRtc_Word16 delayVadCount; + WebRtc_Word16 maxDelayHistIdx; + WebRtc_Word16 lastMinPos; + + WebRtc_Word16 startupState; + WebRtc_Word16 mseChannelCount; + WebRtc_Word16 delayCount; + WebRtc_Word16 newDelayCorrData; + WebRtc_Word16 lastDelayUpdateCount; + WebRtc_Word16 delayCorrelation[CORR_BUF_LEN]; + WebRtc_Word16 supGain; + WebRtc_Word16 supGainOld; + WebRtc_Word16 delayOffsetFlag; + + WebRtc_Word16 supGainErrParamA; + WebRtc_Word16 supGainErrParamD; + WebRtc_Word16 supGainErrParamDiffAB; + WebRtc_Word16 supGainErrParamDiffBD; + +#ifdef AEC_DEBUG + FILE *farFile; + FILE *nearFile; + FILE *outFile; +#endif +} AecmCore_t; + +/////////////////////////////////////////////////////////////////////////////////////////////// +// WebRtcAecm_CreateCore(...) +// +// Allocates the memory needed by the AECM. The memory needs to be +// initialized separately using the WebRtcAecm_InitCore() function. +// +// Input: +// - aecm : Instance that should be created +// +// Output: +// - aecm : Created instance +// +// Return value : 0 - Ok +// -1 - Error +// +int WebRtcAecm_CreateCore(AecmCore_t **aecm); + +/////////////////////////////////////////////////////////////////////////////////////////////// +// WebRtcAecm_InitCore(...) +// +// This function initializes the AECM instant created with WebRtcAecm_CreateCore(...) +// Input: +// - aecm : Pointer to the AECM instance +// - samplingFreq : Sampling Frequency +// +// Output: +// - aecm : Initialized instance +// +// Return value : 0 - Ok +// -1 - Error +// +int WebRtcAecm_InitCore(AecmCore_t * const aecm, int samplingFreq); + +/////////////////////////////////////////////////////////////////////////////////////////////// +// WebRtcAecm_FreeCore(...) +// +// This function releases the memory allocated by WebRtcAecm_CreateCore() +// Input: +// - aecm : Pointer to the AECM instance +// +// Return value : 0 - Ok +// -1 - Error +// 11001-11016: Error +// +int WebRtcAecm_FreeCore(AecmCore_t *aecm); + +int WebRtcAecm_Control(AecmCore_t *aecm, int delay, int nlpFlag, int delayOffsetFlag); + +/////////////////////////////////////////////////////////////////////////////////////////////// +// WebRtcAecm_ProcessFrame(...) +// +// This function processes frames and sends blocks to WebRtcAecm_ProcessBlock(...) +// +// Inputs: +// - aecm : Pointer to the AECM instance +// - farend : In buffer containing one frame of echo signal +// - nearendNoisy : In buffer containing one frame of nearend+echo signal without NS +// - nearendClean : In buffer containing one frame of nearend+echo signal with NS +// +// Output: +// - out : Out buffer, one frame of nearend signal : +// +// +void WebRtcAecm_ProcessFrame(AecmCore_t * const aecm, const WebRtc_Word16 * const farend, + const WebRtc_Word16 * const nearendNoisy, + const WebRtc_Word16 * const nearendClean, + WebRtc_Word16 * const out); + +/////////////////////////////////////////////////////////////////////////////////////////////// +// WebRtcAecm_ProcessBlock(...) +// +// This function is called for every block within one frame +// This function is called by WebRtcAecm_ProcessFrame(...) +// +// Inputs: +// - aecm : Pointer to the AECM instance +// - farend : In buffer containing one block of echo signal +// - nearendNoisy : In buffer containing one frame of nearend+echo signal without NS +// - nearendClean : In buffer containing one frame of nearend+echo signal with NS +// +// Output: +// - out : Out buffer, one block of nearend signal : +// +// +void WebRtcAecm_ProcessBlock(AecmCore_t * const aecm, const WebRtc_Word16 * const farend, + const WebRtc_Word16 * const nearendNoisy, + const WebRtc_Word16 * const noisyClean, + WebRtc_Word16 * const out); + +/////////////////////////////////////////////////////////////////////////////////////////////// +// WebRtcAecm_BufferFarFrame() +// +// Inserts a frame of data into farend buffer. +// +// Inputs: +// - aecm : Pointer to the AECM instance +// - farend : In buffer containing one frame of farend signal +// - farLen : Length of frame +// +void WebRtcAecm_BufferFarFrame(AecmCore_t * const aecm, const WebRtc_Word16 * const farend, + const int farLen); + +/////////////////////////////////////////////////////////////////////////////////////////////// +// WebRtcAecm_FetchFarFrame() +// +// Read the farend buffer to account for known delay +// +// Inputs: +// - aecm : Pointer to the AECM instance +// - farend : In buffer containing one frame of farend signal +// - farLen : Length of frame +// - knownDelay : known delay +// +void WebRtcAecm_FetchFarFrame(AecmCore_t * const aecm, WebRtc_Word16 * const farend, + const int farLen, const int knownDelay); + +#endif diff --git a/src/libs/webrtc/aecm/echo_control_mobile.c b/src/libs/webrtc/aecm/echo_control_mobile.c new file mode 100644 index 00000000..f9d84f0c --- /dev/null +++ b/src/libs/webrtc/aecm/echo_control_mobile.c @@ -0,0 +1,733 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <stdlib.h> +//#include <string.h> + +#include "echo_control_mobile.h" +#include "aecm_core.h" +#include "ring_buffer.h" +#ifdef AEC_DEBUG +#include <stdio.h> +#endif +#ifdef MAC_IPHONE_PRINT +#include <time.h> +#include <stdio.h> +#elif defined ARM_WINM_LOG +#include "windows.h" +extern HANDLE logFile; +#endif + +#define BUF_SIZE_FRAMES 50 // buffer size (frames) +// Maximum length of resampled signal. Must be an integer multiple of frames +// (ceil(1/(1 + MIN_SKEW)*2) + 1)*FRAME_LEN +// The factor of 2 handles wb, and the + 1 is as a safety margin +#define MAX_RESAMP_LEN (5 * FRAME_LEN) + +static const int kBufSizeSamp = BUF_SIZE_FRAMES * FRAME_LEN; // buffer size (samples) +static const int kSampMsNb = 8; // samples per ms in nb +// Target suppression levels for nlp modes +// log{0.001, 0.00001, 0.00000001} +static const int kInitCheck = 42; + +typedef struct +{ + int sampFreq; + int scSampFreq; + short bufSizeStart; + int knownDelay; + + // Stores the last frame added to the farend buffer + short farendOld[2][FRAME_LEN]; + short initFlag; // indicates if AEC has been initialized + + // Variables used for averaging far end buffer size + short counter; + short sum; + short firstVal; + short checkBufSizeCtr; + + // Variables used for delay shifts + short msInSndCardBuf; + short filtDelay; + int timeForDelayChange; + int ECstartup; + int checkBuffSize; + int delayChange; + short lastDelayDiff; + + WebRtc_Word16 echoMode; + +#ifdef AEC_DEBUG + FILE *bufFile; + FILE *delayFile; + FILE *preCompFile; + FILE *postCompFile; +#endif // AEC_DEBUG + // Structures + void *farendBuf; + + int lastError; + + AecmCore_t *aecmCore; +} aecmob_t; + +// Estimates delay to set the position of the farend buffer read pointer +// (controlled by knownDelay) +static int WebRtcAecm_EstBufDelay(aecmob_t *aecmInst, short msInSndCardBuf); + +// Stuffs the farend buffer if the estimated delay is too large +static int WebRtcAecm_DelayComp(aecmob_t *aecmInst); + +WebRtc_Word32 WebRtcAecm_Create(void **aecmInst) +{ + aecmob_t *aecm; + if (aecmInst == NULL) + { + return -1; + } + + aecm = malloc(sizeof(aecmob_t)); + *aecmInst = aecm; + if (aecm == NULL) + { + return -1; + } + + if (WebRtcAecm_CreateCore(&aecm->aecmCore) == -1) + { + WebRtcAecm_Free(aecm); + aecm = NULL; + return -1; + } + + if (WebRtcApm_CreateBuffer(&aecm->farendBuf, kBufSizeSamp) == -1) + { + WebRtcAecm_Free(aecm); + aecm = NULL; + return -1; + } + + aecm->initFlag = 0; + aecm->lastError = 0; + +#ifdef AEC_DEBUG + aecm->aecmCore->farFile = fopen("aecFar.pcm","wb"); + aecm->aecmCore->nearFile = fopen("aecNear.pcm","wb"); + aecm->aecmCore->outFile = fopen("aecOut.pcm","wb"); + //aecm->aecmCore->outLpFile = fopen("aecOutLp.pcm","wb"); + + aecm->bufFile = fopen("aecBuf.dat", "wb"); + aecm->delayFile = fopen("aecDelay.dat", "wb"); + aecm->preCompFile = fopen("preComp.pcm", "wb"); + aecm->postCompFile = fopen("postComp.pcm", "wb"); +#endif // AEC_DEBUG + return 0; +} + +WebRtc_Word32 WebRtcAecm_Free(void *aecmInst) +{ + aecmob_t *aecm = aecmInst; + + if (aecm == NULL) + { + return -1; + } + +#ifdef AEC_DEBUG + fclose(aecm->aecmCore->farFile); + fclose(aecm->aecmCore->nearFile); + fclose(aecm->aecmCore->outFile); + //fclose(aecm->aecmCore->outLpFile); + + fclose(aecm->bufFile); + fclose(aecm->delayFile); + fclose(aecm->preCompFile); + fclose(aecm->postCompFile); +#endif // AEC_DEBUG + WebRtcAecm_FreeCore(aecm->aecmCore); + WebRtcApm_FreeBuffer(aecm->farendBuf); + free(aecm); + + return 0; +} + +WebRtc_Word32 WebRtcAecm_Init(void *aecmInst, WebRtc_Word32 sampFreq, WebRtc_Word32 scSampFreq) +{ + aecmob_t *aecm = aecmInst; + AecmConfig aecConfig; + + if (aecm == NULL) + { + return -1; + } + + if (sampFreq != 8000 && sampFreq != 16000) + { + aecm->lastError = AECM_BAD_PARAMETER_ERROR; + return -1; + } + aecm->sampFreq = sampFreq; + + if (scSampFreq < 1 || scSampFreq > 96000) + { + aecm->lastError = AECM_BAD_PARAMETER_ERROR; + return -1; + } + aecm->scSampFreq = scSampFreq; + + // Initialize AECM core + if (WebRtcAecm_InitCore(aecm->aecmCore, aecm->sampFreq) == -1) + { + aecm->lastError = AECM_UNSPECIFIED_ERROR; + return -1; + } + + // Initialize farend buffer + if (WebRtcApm_InitBuffer(aecm->farendBuf) == -1) + { + aecm->lastError = AECM_UNSPECIFIED_ERROR; + return -1; + } + + aecm->initFlag = kInitCheck; // indicates that initialization has been done + + aecm->delayChange = 1; + + aecm->sum = 0; + aecm->counter = 0; + aecm->checkBuffSize = 1; + aecm->firstVal = 0; + + aecm->ECstartup = 1; + aecm->bufSizeStart = 0; + aecm->checkBufSizeCtr = 0; + aecm->filtDelay = 0; + aecm->timeForDelayChange = 0; + aecm->knownDelay = 0; + aecm->lastDelayDiff = 0; + + memset(&aecm->farendOld[0][0], 0, 160); + + // Default settings. + aecConfig.cngMode = AecmTrue; + aecConfig.echoMode = 3; + + if (WebRtcAecm_set_config(aecm, aecConfig) == -1) + { + aecm->lastError = AECM_UNSPECIFIED_ERROR; + return -1; + } + + return 0; +} + +WebRtc_Word32 WebRtcAecm_BufferFarend(void *aecmInst, const WebRtc_Word16 *farend, + WebRtc_Word16 nrOfSamples) +{ + aecmob_t *aecm = aecmInst; + WebRtc_Word32 retVal = 0; + + if (aecm == NULL) + { + return -1; + } + + if (farend == NULL) + { + aecm->lastError = AECM_NULL_POINTER_ERROR; + return -1; + } + + if (aecm->initFlag != kInitCheck) + { + aecm->lastError = AECM_UNINITIALIZED_ERROR; + return -1; + } + + if (nrOfSamples != 80 && nrOfSamples != 160) + { + aecm->lastError = AECM_BAD_PARAMETER_ERROR; + return -1; + } + + // TODO: Is this really a good idea? + if (!aecm->ECstartup) + { + WebRtcAecm_DelayComp(aecm); + } + + WebRtcApm_WriteBuffer(aecm->farendBuf, farend, nrOfSamples); + + return retVal; +} + +WebRtc_Word32 WebRtcAecm_Process(void *aecmInst, const WebRtc_Word16 *nearendNoisy, + const WebRtc_Word16 *nearendClean, WebRtc_Word16 *out, + WebRtc_Word16 nrOfSamples, WebRtc_Word16 msInSndCardBuf) +{ + aecmob_t *aecm = aecmInst; + WebRtc_Word32 retVal = 0; + short i; + short farend[FRAME_LEN]; + short nmbrOfFilledBuffers; + short nBlocks10ms; + short nFrames; +#ifdef AEC_DEBUG + short msInAECBuf; +#endif + +#ifdef ARM_WINM_LOG + __int64 freq, start, end, diff; + unsigned int milliseconds; + DWORD temp; +#elif defined MAC_IPHONE_PRINT + // double endtime = 0, starttime = 0; + struct timeval starttime; + struct timeval endtime; + static long int timeused = 0; + static int timecount = 0; +#endif + + if (aecm == NULL) + { + return -1; + } + + if (nearendNoisy == NULL) + { + aecm->lastError = AECM_NULL_POINTER_ERROR; + return -1; + } + + if (out == NULL) + { + aecm->lastError = AECM_NULL_POINTER_ERROR; + return -1; + } + + if (aecm->initFlag != kInitCheck) + { + aecm->lastError = AECM_UNINITIALIZED_ERROR; + return -1; + } + + if (nrOfSamples != 80 && nrOfSamples != 160) + { + aecm->lastError = AECM_BAD_PARAMETER_ERROR; + return -1; + } + + if (msInSndCardBuf < 0) + { + msInSndCardBuf = 0; + aecm->lastError = AECM_BAD_PARAMETER_WARNING; + retVal = -1; + } else if (msInSndCardBuf > 500) + { + msInSndCardBuf = 500; + aecm->lastError = AECM_BAD_PARAMETER_WARNING; + retVal = -1; + } + msInSndCardBuf += 10; + aecm->msInSndCardBuf = msInSndCardBuf; + + nFrames = nrOfSamples / FRAME_LEN; + nBlocks10ms = nFrames / aecm->aecmCore->mult; + + if (aecm->ECstartup) + { + if (nearendClean == NULL) + { + memcpy(out, nearendNoisy, sizeof(short) * nrOfSamples); + } else + { + memcpy(out, nearendClean, sizeof(short) * nrOfSamples); + } + + nmbrOfFilledBuffers = WebRtcApm_get_buffer_size(aecm->farendBuf) / FRAME_LEN; + // The AECM is in the start up mode + // AECM is disabled until the soundcard buffer and farend buffers are OK + + // Mechanism to ensure that the soundcard buffer is reasonably stable. + if (aecm->checkBuffSize) + { + aecm->checkBufSizeCtr++; + // Before we fill up the far end buffer we require the amount of data on the + // sound card to be stable (+/-8 ms) compared to the first value. This + // comparison is made during the following 4 consecutive frames. If it seems + // to be stable then we start to fill up the far end buffer. + + if (aecm->counter == 0) + { + aecm->firstVal = aecm->msInSndCardBuf; + aecm->sum = 0; + } + + if (abs(aecm->firstVal - aecm->msInSndCardBuf) + < WEBRTC_SPL_MAX(0.2 * aecm->msInSndCardBuf, kSampMsNb)) + { + aecm->sum += aecm->msInSndCardBuf; + aecm->counter++; + } else + { + aecm->counter = 0; + } + + if (aecm->counter * nBlocks10ms >= 6) + { + // The farend buffer size is determined in blocks of 80 samples + // Use 75% of the average value of the soundcard buffer + aecm->bufSizeStart + = WEBRTC_SPL_MIN((3 * aecm->sum + * aecm->aecmCore->mult) / (aecm->counter * 40), BUF_SIZE_FRAMES); + // buffersize has now been determined + aecm->checkBuffSize = 0; + } + + if (aecm->checkBufSizeCtr * nBlocks10ms > 50) + { + // for really bad sound cards, don't disable echocanceller for more than 0.5 sec + aecm->bufSizeStart = WEBRTC_SPL_MIN((3 * aecm->msInSndCardBuf + * aecm->aecmCore->mult) / 40, BUF_SIZE_FRAMES); + aecm->checkBuffSize = 0; + } + } + + // if checkBuffSize changed in the if-statement above + if (!aecm->checkBuffSize) + { + // soundcard buffer is now reasonably stable + // When the far end buffer is filled with approximately the same amount of + // data as the amount on the sound card we end the start up phase and start + // to cancel echoes. + + if (nmbrOfFilledBuffers == aecm->bufSizeStart) + { + aecm->ECstartup = 0; // Enable the AECM + } else if (nmbrOfFilledBuffers > aecm->bufSizeStart) + { + WebRtcApm_FlushBuffer( + aecm->farendBuf, + WebRtcApm_get_buffer_size(aecm->farendBuf) + - aecm->bufSizeStart * FRAME_LEN); + aecm->ECstartup = 0; + } + } + + } else + { + // AECM is enabled + + // Note only 1 block supported for nb and 2 blocks for wb + for (i = 0; i < nFrames; i++) + { + nmbrOfFilledBuffers = WebRtcApm_get_buffer_size(aecm->farendBuf) / FRAME_LEN; + + // Check that there is data in the far end buffer + if (nmbrOfFilledBuffers > 0) + { + // Get the next 80 samples from the farend buffer + WebRtcApm_ReadBuffer(aecm->farendBuf, farend, FRAME_LEN); + + // Always store the last frame for use when we run out of data + memcpy(&(aecm->farendOld[i][0]), farend, FRAME_LEN * sizeof(short)); + } else + { + // We have no data so we use the last played frame + memcpy(farend, &(aecm->farendOld[i][0]), FRAME_LEN * sizeof(short)); + } + + // Call buffer delay estimator when all data is extracted, + // i,e. i = 0 for NB and i = 1 for WB + if ((i == 0 && aecm->sampFreq == 8000) || (i == 1 && aecm->sampFreq == 16000)) + { + WebRtcAecm_EstBufDelay(aecm, aecm->msInSndCardBuf); + } + +#ifdef ARM_WINM_LOG + // measure tick start + QueryPerformanceFrequency((LARGE_INTEGER*)&freq); + QueryPerformanceCounter((LARGE_INTEGER*)&start); +#elif defined MAC_IPHONE_PRINT + // starttime = clock()/(double)CLOCKS_PER_SEC; + gettimeofday(&starttime, NULL); +#endif + // Call the AECM + /*WebRtcAecm_ProcessFrame(aecm->aecmCore, farend, &nearend[FRAME_LEN * i], + &out[FRAME_LEN * i], aecm->knownDelay);*/ + if (nearendClean == NULL) + { + WebRtcAecm_ProcessFrame(aecm->aecmCore, farend, &nearendNoisy[FRAME_LEN * i], + NULL, &out[FRAME_LEN * i]); + } else + { + WebRtcAecm_ProcessFrame(aecm->aecmCore, farend, &nearendNoisy[FRAME_LEN * i], + &nearendClean[FRAME_LEN * i], &out[FRAME_LEN * i]); + } + +#ifdef ARM_WINM_LOG + + // measure tick end + QueryPerformanceCounter((LARGE_INTEGER*)&end); + + if(end > start) + { + diff = ((end - start) * 1000) / (freq/1000); + milliseconds = (unsigned int)(diff & 0xffffffff); + WriteFile (logFile, &milliseconds, sizeof(unsigned int), &temp, NULL); + } +#elif defined MAC_IPHONE_PRINT + // endtime = clock()/(double)CLOCKS_PER_SEC; + // printf("%f\n", endtime - starttime); + + gettimeofday(&endtime, NULL); + + if( endtime.tv_usec > starttime.tv_usec) + { + timeused += endtime.tv_usec - starttime.tv_usec; + } else + { + timeused += endtime.tv_usec + 1000000 - starttime.tv_usec; + } + + if(++timecount == 1000) + { + timecount = 0; + printf("AEC: %ld\n", timeused); + timeused = 0; + } +#endif + + } + } + +#ifdef AEC_DEBUG + msInAECBuf = WebRtcApm_get_buffer_size(aecm->farendBuf) / (kSampMsNb*aecm->aecmCore->mult); + fwrite(&msInAECBuf, 2, 1, aecm->bufFile); + fwrite(&(aecm->knownDelay), sizeof(aecm->knownDelay), 1, aecm->delayFile); +#endif + + return retVal; +} + +WebRtc_Word32 WebRtcAecm_set_config(void *aecmInst, AecmConfig config) +{ + aecmob_t *aecm = aecmInst; + + if (aecm == NULL) + { + return -1; + } + + if (aecm->initFlag != kInitCheck) + { + aecm->lastError = AECM_UNINITIALIZED_ERROR; + return -1; + } + + if (config.cngMode != AecmFalse && config.cngMode != AecmTrue) + { + aecm->lastError = AECM_BAD_PARAMETER_ERROR; + return -1; + } + aecm->aecmCore->cngMode = config.cngMode; + + if (config.echoMode < 0 || config.echoMode > 4) + { + aecm->lastError = AECM_BAD_PARAMETER_ERROR; + return -1; + } + aecm->echoMode = config.echoMode; + + if (aecm->echoMode == 0) + { + aecm->aecmCore->supGain = SUPGAIN_DEFAULT >> 3; + aecm->aecmCore->supGainOld = SUPGAIN_DEFAULT >> 3; + aecm->aecmCore->supGainErrParamA = SUPGAIN_ERROR_PARAM_A >> 3; + aecm->aecmCore->supGainErrParamD = SUPGAIN_ERROR_PARAM_D >> 3; + aecm->aecmCore->supGainErrParamDiffAB = (SUPGAIN_ERROR_PARAM_A >> 3) + - (SUPGAIN_ERROR_PARAM_B >> 3); + aecm->aecmCore->supGainErrParamDiffBD = (SUPGAIN_ERROR_PARAM_B >> 3) + - (SUPGAIN_ERROR_PARAM_D >> 3); + } else if (aecm->echoMode == 1) + { + aecm->aecmCore->supGain = SUPGAIN_DEFAULT >> 2; + aecm->aecmCore->supGainOld = SUPGAIN_DEFAULT >> 2; + aecm->aecmCore->supGainErrParamA = SUPGAIN_ERROR_PARAM_A >> 2; + aecm->aecmCore->supGainErrParamD = SUPGAIN_ERROR_PARAM_D >> 2; + aecm->aecmCore->supGainErrParamDiffAB = (SUPGAIN_ERROR_PARAM_A >> 2) + - (SUPGAIN_ERROR_PARAM_B >> 2); + aecm->aecmCore->supGainErrParamDiffBD = (SUPGAIN_ERROR_PARAM_B >> 2) + - (SUPGAIN_ERROR_PARAM_D >> 2); + } else if (aecm->echoMode == 2) + { + aecm->aecmCore->supGain = SUPGAIN_DEFAULT >> 1; + aecm->aecmCore->supGainOld = SUPGAIN_DEFAULT >> 1; + aecm->aecmCore->supGainErrParamA = SUPGAIN_ERROR_PARAM_A >> 1; + aecm->aecmCore->supGainErrParamD = SUPGAIN_ERROR_PARAM_D >> 1; + aecm->aecmCore->supGainErrParamDiffAB = (SUPGAIN_ERROR_PARAM_A >> 1) + - (SUPGAIN_ERROR_PARAM_B >> 1); + aecm->aecmCore->supGainErrParamDiffBD = (SUPGAIN_ERROR_PARAM_B >> 1) + - (SUPGAIN_ERROR_PARAM_D >> 1); + } else if (aecm->echoMode == 3) + { + aecm->aecmCore->supGain = SUPGAIN_DEFAULT; + aecm->aecmCore->supGainOld = SUPGAIN_DEFAULT; + aecm->aecmCore->supGainErrParamA = SUPGAIN_ERROR_PARAM_A; + aecm->aecmCore->supGainErrParamD = SUPGAIN_ERROR_PARAM_D; + aecm->aecmCore->supGainErrParamDiffAB = SUPGAIN_ERROR_PARAM_A - SUPGAIN_ERROR_PARAM_B; + aecm->aecmCore->supGainErrParamDiffBD = SUPGAIN_ERROR_PARAM_B - SUPGAIN_ERROR_PARAM_D; + } else if (aecm->echoMode == 4) + { + aecm->aecmCore->supGain = SUPGAIN_DEFAULT << 1; + aecm->aecmCore->supGainOld = SUPGAIN_DEFAULT << 1; + aecm->aecmCore->supGainErrParamA = SUPGAIN_ERROR_PARAM_A << 1; + aecm->aecmCore->supGainErrParamD = SUPGAIN_ERROR_PARAM_D << 1; + aecm->aecmCore->supGainErrParamDiffAB = (SUPGAIN_ERROR_PARAM_A << 1) + - (SUPGAIN_ERROR_PARAM_B << 1); + aecm->aecmCore->supGainErrParamDiffBD = (SUPGAIN_ERROR_PARAM_B << 1) + - (SUPGAIN_ERROR_PARAM_D << 1); + } + + return 0; +} + +WebRtc_Word32 WebRtcAecm_get_config(void *aecmInst, AecmConfig *config) +{ + aecmob_t *aecm = aecmInst; + + if (aecm == NULL) + { + return -1; + } + + if (config == NULL) + { + aecm->lastError = AECM_NULL_POINTER_ERROR; + return -1; + } + + if (aecm->initFlag != kInitCheck) + { + aecm->lastError = AECM_UNINITIALIZED_ERROR; + return -1; + } + + config->cngMode = aecm->aecmCore->cngMode; + config->echoMode = aecm->echoMode; + + return 0; +} + +WebRtc_Word32 WebRtcAecm_get_version(WebRtc_Word8 *versionStr, WebRtc_Word16 len) +{ + const char version[] = "AECM 1.2.0"; + const short versionLen = (short)strlen(version) + 1; // +1 for null-termination + + if (versionStr == NULL) + { + return -1; + } + + if (versionLen > len) + { + return -1; + } + + strncpy(versionStr, version, versionLen); + return 0; +} + +WebRtc_Word32 WebRtcAecm_get_error_code(void *aecmInst) +{ + aecmob_t *aecm = aecmInst; + + if (aecm == NULL) + { + return -1; + } + + return aecm->lastError; +} + +static int WebRtcAecm_EstBufDelay(aecmob_t *aecm, short msInSndCardBuf) +{ + short delayNew, nSampFar, nSampSndCard; + short diff; + + nSampFar = WebRtcApm_get_buffer_size(aecm->farendBuf); + nSampSndCard = msInSndCardBuf * kSampMsNb * aecm->aecmCore->mult; + + delayNew = nSampSndCard - nSampFar; + + if (delayNew < FRAME_LEN) + { + WebRtcApm_FlushBuffer(aecm->farendBuf, FRAME_LEN); + delayNew += FRAME_LEN; + } + + aecm->filtDelay = WEBRTC_SPL_MAX(0, (8 * aecm->filtDelay + 2 * delayNew) / 10); + + diff = aecm->filtDelay - aecm->knownDelay; + if (diff > 224) + { + if (aecm->lastDelayDiff < 96) + { + aecm->timeForDelayChange = 0; + } else + { + aecm->timeForDelayChange++; + } + } else if (diff < 96 && aecm->knownDelay > 0) + { + if (aecm->lastDelayDiff > 224) + { + aecm->timeForDelayChange = 0; + } else + { + aecm->timeForDelayChange++; + } + } else + { + aecm->timeForDelayChange = 0; + } + aecm->lastDelayDiff = diff; + + if (aecm->timeForDelayChange > 25) + { + aecm->knownDelay = WEBRTC_SPL_MAX((int)aecm->filtDelay - 160, 0); + } + return 0; +} + +static int WebRtcAecm_DelayComp(aecmob_t *aecm) +{ + int nSampFar, nSampSndCard, delayNew, nSampAdd; + const int maxStuffSamp = 10 * FRAME_LEN; + + nSampFar = WebRtcApm_get_buffer_size(aecm->farendBuf); + nSampSndCard = aecm->msInSndCardBuf * kSampMsNb * aecm->aecmCore->mult; + delayNew = nSampSndCard - nSampFar; + + if (delayNew > FAR_BUF_LEN - FRAME_LEN * aecm->aecmCore->mult) + { + // The difference of the buffer sizes is larger than the maximum + // allowed known delay. Compensate by stuffing the buffer. + nSampAdd = (int)(WEBRTC_SPL_MAX(((nSampSndCard >> 1) - nSampFar), + FRAME_LEN)); + nSampAdd = WEBRTC_SPL_MIN(nSampAdd, maxStuffSamp); + + WebRtcApm_StuffBuffer(aecm->farendBuf, nSampAdd); + aecm->delayChange = 1; // the delay needs to be updated + } + + return 0; +} diff --git a/src/libs/webrtc/aecm/echo_control_mobile.h b/src/libs/webrtc/aecm/echo_control_mobile.h new file mode 100644 index 00000000..26b11727 --- /dev/null +++ b/src/libs/webrtc/aecm/echo_control_mobile.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AECM_MAIN_INTERFACE_ECHO_CONTROL_MOBILE_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_AECM_MAIN_INTERFACE_ECHO_CONTROL_MOBILE_H_ + +#include "typedefs.h" + +enum { + AecmFalse = 0, + AecmTrue +}; + +// Errors +#define AECM_UNSPECIFIED_ERROR 12000 +#define AECM_UNSUPPORTED_FUNCTION_ERROR 12001 +#define AECM_UNINITIALIZED_ERROR 12002 +#define AECM_NULL_POINTER_ERROR 12003 +#define AECM_BAD_PARAMETER_ERROR 12004 + +// Warnings +#define AECM_BAD_PARAMETER_WARNING 12100 + +typedef struct { + WebRtc_Word16 cngMode; // AECM_FALSE, AECM_TRUE (default) + WebRtc_Word16 echoMode; // 0, 1, 2, 3 (default), 4 +} AecmConfig; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Allocates the memory needed by the AECM. The memory needs to be + * initialized separately using the WebRtcAecm_Init() function. + * + * Inputs Description + * ------------------------------------------------------------------- + * void **aecmInst Pointer to the AECM instance to be + * created and initialized + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAecm_Create(void **aecmInst); + +/* + * This function releases the memory allocated by WebRtcAecm_Create() + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecmInst Pointer to the AECM instance + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAecm_Free(void *aecmInst); + +/* + * Initializes an AECM instance. + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecmInst Pointer to the AECM instance + * WebRtc_Word32 sampFreq Sampling frequency of data + * WebRtc_Word32 scSampFreq Soundcard sampling frequency + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAecm_Init(void* aecmInst, + WebRtc_Word32 sampFreq, + WebRtc_Word32 scSampFreq); + +/* + * Inserts an 80 or 160 sample block of data into the farend buffer. + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecmInst Pointer to the AECM instance + * WebRtc_Word16 *farend In buffer containing one frame of + * farend signal + * WebRtc_Word16 nrOfSamples Number of samples in farend buffer + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAecm_BufferFarend(void* aecmInst, + const WebRtc_Word16* farend, + WebRtc_Word16 nrOfSamples); + +/* + * Runs the AECM on an 80 or 160 sample blocks of data. + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecmInst Pointer to the AECM instance + * WebRtc_Word16 *nearendNoisy In buffer containing one frame of + * reference nearend+echo signal. If + * noise reduction is active, provide + * the noisy signal here. + * WebRtc_Word16 *nearendClean In buffer containing one frame of + * nearend+echo signal. If noise + * reduction is active, provide the + * clean signal here. Otherwise pass a + * NULL pointer. + * WebRtc_Word16 nrOfSamples Number of samples in nearend buffer + * WebRtc_Word16 msInSndCardBuf Delay estimate for sound card and + * system buffers + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word16 *out Out buffer, one frame of processed nearend + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAecm_Process(void* aecmInst, + const WebRtc_Word16* nearendNoisy, + const WebRtc_Word16* nearendClean, + WebRtc_Word16* out, + WebRtc_Word16 nrOfSamples, + WebRtc_Word16 msInSndCardBuf); + +/* + * This function enables the user to set certain parameters on-the-fly + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecmInst Pointer to the AECM instance + * AecmConfig config Config instance that contains all + * properties to be set + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAecm_set_config(void* aecmInst, + AecmConfig config); + +/* + * This function enables the user to set certain parameters on-the-fly + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecmInst Pointer to the AECM instance + * + * Outputs Description + * ------------------------------------------------------------------- + * AecmConfig *config Pointer to the config instance that + * all properties will be written to + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAecm_get_config(void *aecmInst, + AecmConfig *config); + +/* + * Gets the last error code. + * + * Inputs Description + * ------------------------------------------------------------------- + * void *aecmInst Pointer to the AECM instance + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word32 return 11000-11100: error code + */ +WebRtc_Word32 WebRtcAecm_get_error_code(void *aecmInst); + +/* + * Gets a version string + * + * Inputs Description + * ------------------------------------------------------------------- + * char *versionStr Pointer to a string array + * WebRtc_Word16 len The maximum length of the string + * + * Outputs Description + * ------------------------------------------------------------------- + * WebRtc_Word8 *versionStr Pointer to a string array + * WebRtc_Word32 return 0: OK + * -1: error + */ +WebRtc_Word32 WebRtcAecm_get_version(WebRtc_Word8 *versionStr, + WebRtc_Word16 len); + +#ifdef __cplusplus +} +#endif +#endif /* WEBRTC_MODULES_AUDIO_PROCESSING_AECM_MAIN_INTERFACE_ECHO_CONTROL_MOBILE_H_ */ diff --git a/src/libs/webrtc/agc/analog_agc.c b/src/libs/webrtc/agc/analog_agc.c new file mode 100644 index 00000000..dfb7adc6 --- /dev/null +++ b/src/libs/webrtc/agc/analog_agc.c @@ -0,0 +1,1700 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* analog_agc.c + * + * Using a feedback system, determines an appropriate analog volume level + * given an input signal and current volume level. Targets a conservative + * signal level and is intended for use with a digital AGC to apply + * additional gain. + * + */ + +#include <assert.h> +#include <stdlib.h> +#ifdef AGC_DEBUG //test log +#include <stdio.h> +#endif +#include "analog_agc.h" + +/* The slope of in Q13*/ +static const WebRtc_Word16 kSlope1[8] = {21793, 12517, 7189, 4129, 2372, 1362, 472, 78}; + +/* The offset in Q14 */ +static const WebRtc_Word16 kOffset1[8] = {25395, 23911, 22206, 20737, 19612, 18805, 17951, + 17367}; + +/* The slope of in Q13*/ +static const WebRtc_Word16 kSlope2[8] = {2063, 1731, 1452, 1218, 1021, 857, 597, 337}; + +/* The offset in Q14 */ +static const WebRtc_Word16 kOffset2[8] = {18432, 18379, 18290, 18177, 18052, 17920, 17670, + 17286}; + +static const WebRtc_Word16 kMuteGuardTimeMs = 8000; +static const WebRtc_Word16 kInitCheck = 42; + +/* Default settings if config is not used */ +#define AGC_DEFAULT_TARGET_LEVEL 3 +#define AGC_DEFAULT_COMP_GAIN 9 +/* This is the target level for the analog part in ENV scale. To convert to RMS scale you + * have to add OFFSET_ENV_TO_RMS. + */ +#define ANALOG_TARGET_LEVEL 11 +#define ANALOG_TARGET_LEVEL_2 5 // ANALOG_TARGET_LEVEL / 2 +/* Offset between RMS scale (analog part) and ENV scale (digital part). This value actually + * varies with the FIXED_ANALOG_TARGET_LEVEL, hence we should in the future replace it with + * a table. + */ +#define OFFSET_ENV_TO_RMS 9 +/* The reference input level at which the digital part gives an output of targetLevelDbfs + * (desired level) if we have no compression gain. This level should be set high enough not + * to compress the peaks due to the dynamics. + */ +#define DIGITAL_REF_AT_0_COMP_GAIN 4 +/* Speed of reference level decrease. + */ +#define DIFF_REF_TO_ANALOG 5 + +#ifdef MIC_LEVEL_FEEDBACK +#define NUM_BLOCKS_IN_SAT_BEFORE_CHANGE_TARGET 7 +#endif +/* Size of analog gain table */ +#define GAIN_TBL_LEN 32 +/* Matlab code: + * fprintf(1, '\t%i, %i, %i, %i,\n', round(10.^(linspace(0,10,32)/20) * 2^12)); + */ +/* Q12 */ +static const WebRtc_UWord16 kGainTableAnalog[GAIN_TBL_LEN] = {4096, 4251, 4412, 4579, 4752, + 4932, 5118, 5312, 5513, 5722, 5938, 6163, 6396, 6638, 6889, 7150, 7420, 7701, 7992, + 8295, 8609, 8934, 9273, 9623, 9987, 10365, 10758, 11165, 11587, 12025, 12480, 12953}; + +/* Gain/Suppression tables for virtual Mic (in Q10) */ +static const WebRtc_UWord16 kGainTableVirtualMic[128] = {1052, 1081, 1110, 1141, 1172, 1204, + 1237, 1271, 1305, 1341, 1378, 1416, 1454, 1494, 1535, 1577, 1620, 1664, 1710, 1757, + 1805, 1854, 1905, 1957, 2010, 2065, 2122, 2180, 2239, 2301, 2364, 2428, 2495, 2563, + 2633, 2705, 2779, 2855, 2933, 3013, 3096, 3180, 3267, 3357, 3449, 3543, 3640, 3739, + 3842, 3947, 4055, 4166, 4280, 4397, 4517, 4640, 4767, 4898, 5032, 5169, 5311, 5456, + 5605, 5758, 5916, 6078, 6244, 6415, 6590, 6770, 6956, 7146, 7341, 7542, 7748, 7960, + 8178, 8402, 8631, 8867, 9110, 9359, 9615, 9878, 10148, 10426, 10711, 11004, 11305, + 11614, 11932, 12258, 12593, 12938, 13292, 13655, 14029, 14412, 14807, 15212, 15628, + 16055, 16494, 16945, 17409, 17885, 18374, 18877, 19393, 19923, 20468, 21028, 21603, + 22194, 22801, 23425, 24065, 24724, 25400, 26095, 26808, 27541, 28295, 29069, 29864, + 30681, 31520, 32382}; +static const WebRtc_UWord16 kSuppressionTableVirtualMic[128] = {1024, 1006, 988, 970, 952, + 935, 918, 902, 886, 870, 854, 839, 824, 809, 794, 780, 766, 752, 739, 726, 713, 700, + 687, 675, 663, 651, 639, 628, 616, 605, 594, 584, 573, 563, 553, 543, 533, 524, 514, + 505, 496, 487, 478, 470, 461, 453, 445, 437, 429, 421, 414, 406, 399, 392, 385, 378, + 371, 364, 358, 351, 345, 339, 333, 327, 321, 315, 309, 304, 298, 293, 288, 283, 278, + 273, 268, 263, 258, 254, 249, 244, 240, 236, 232, 227, 223, 219, 215, 211, 208, 204, + 200, 197, 193, 190, 186, 183, 180, 176, 173, 170, 167, 164, 161, 158, 155, 153, 150, + 147, 145, 142, 139, 137, 134, 132, 130, 127, 125, 123, 121, 118, 116, 114, 112, 110, + 108, 106, 104, 102}; + +/* Table for target energy levels. Values in Q(-7) + * Matlab code + * targetLevelTable = fprintf('%d,\t%d,\t%d,\t%d,\n', round((32767*10.^(-(0:63)'/20)).^2*16/2^7) */ + +static const WebRtc_Word32 kTargetLevelTable[64] = {134209536, 106606424, 84680493, 67264106, + 53429779, 42440782, 33711911, 26778323, 21270778, 16895980, 13420954, 10660642, + 8468049, 6726411, 5342978, 4244078, 3371191, 2677832, 2127078, 1689598, 1342095, + 1066064, 846805, 672641, 534298, 424408, 337119, 267783, 212708, 168960, 134210, + 106606, 84680, 67264, 53430, 42441, 33712, 26778, 21271, 16896, 13421, 10661, 8468, + 6726, 5343, 4244, 3371, 2678, 2127, 1690, 1342, 1066, 847, 673, 534, 424, 337, 268, + 213, 169, 134, 107, 85, 67}; + +int WebRtcAgc_AddMic(void *state, WebRtc_Word16 *in_mic, WebRtc_Word16 *in_mic_H, + WebRtc_Word16 samples) +{ + WebRtc_Word32 nrg, max_nrg, sample, tmp32; + WebRtc_Word32 *ptr; + WebRtc_UWord16 targetGainIdx, gain; + WebRtc_Word16 i, n, L, M, subFrames, tmp16, tmp_speech[16]; + Agc_t *stt; + stt = (Agc_t *)state; + + //default/initial values corresponding to 10ms for wb and swb + M = 10; + L = 16; + subFrames = 160; + + if (stt->fs == 8000) + { + if (samples == 80) + { + subFrames = 80; + M = 10; + L = 8; + } else if (samples == 160) + { + subFrames = 80; + M = 20; + L = 8; + } else + { +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "AGC->add_mic, frame %d: Invalid number of samples\n\n", + (stt->fcount + 1)); +#endif + return -1; + } + } else if (stt->fs == 16000) + { + if (samples == 160) + { + subFrames = 160; + M = 10; + L = 16; + } else if (samples == 320) + { + subFrames = 160; + M = 20; + L = 16; + } else + { +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "AGC->add_mic, frame %d: Invalid number of samples\n\n", + (stt->fcount + 1)); +#endif + return -1; + } + } else if (stt->fs == 32000) + { + /* SWB is processed as 160 sample for L and H bands */ + if (samples == 160) + { + subFrames = 160; + M = 10; + L = 16; + } else + { +#ifdef AGC_DEBUG + fprintf(stt->fpt, + "AGC->add_mic, frame %d: Invalid sample rate\n\n", + (stt->fcount + 1)); +#endif + return -1; + } + } + + /* Check for valid pointers based on sampling rate */ + if ((stt->fs == 32000) && (in_mic_H == NULL)) + { + return -1; + } + /* Check for valid pointer for low band */ + if (in_mic == NULL) + { + return -1; + } + + /* apply slowly varying digital gain */ + if (stt->micVol > stt->maxAnalog) + { + /* Q1 */ + tmp16 = (WebRtc_Word16)(stt->micVol - stt->maxAnalog); + tmp32 = WEBRTC_SPL_MUL_16_16(GAIN_TBL_LEN - 1, tmp16); + tmp16 = (WebRtc_Word16)(stt->maxLevel - stt->maxAnalog); + targetGainIdx = (WebRtc_UWord16)WEBRTC_SPL_DIV(tmp32, tmp16); + assert(targetGainIdx < GAIN_TBL_LEN); + + /* Increment through the table towards the target gain. + * If micVol drops below maxAnalog, we allow the gain + * to be dropped immediately. */ + if (stt->gainTableIdx < targetGainIdx) + { + stt->gainTableIdx++; + } else if (stt->gainTableIdx > targetGainIdx) + { + stt->gainTableIdx--; + } + + /* Q12 */ + gain = kGainTableAnalog[stt->gainTableIdx]; + + for (i = 0; i < samples; i++) + { + // For lower band + tmp32 = WEBRTC_SPL_MUL_16_U16(in_mic[i], gain); + sample = WEBRTC_SPL_RSHIFT_W32(tmp32, 12); + if (sample > 32767) + { + in_mic[i] = 32767; + } else if (sample < -32768) + { + in_mic[i] = -32768; + } else + { + in_mic[i] = (WebRtc_Word16)sample; + } + + // For higher band + if (stt->fs == 32000) + { + tmp32 = WEBRTC_SPL_MUL_16_U16(in_mic_H[i], gain); + sample = WEBRTC_SPL_RSHIFT_W32(tmp32, 12); + if (sample > 32767) + { + in_mic_H[i] = 32767; + } else if (sample < -32768) + { + in_mic_H[i] = -32768; + } else + { + in_mic_H[i] = (WebRtc_Word16)sample; + } + } + } + } else + { + stt->gainTableIdx = 0; + } + + /* compute envelope */ + if ((M == 10) && (stt->inQueue > 0)) + { + ptr = stt->env[1]; + } else + { + ptr = stt->env[0]; + } + + for (i = 0; i < M; i++) + { + /* iterate over samples */ + max_nrg = 0; + for (n = 0; n < L; n++) + { + nrg = WEBRTC_SPL_MUL_16_16(in_mic[i * L + n], in_mic[i * L + n]); + if (nrg > max_nrg) + { + max_nrg = nrg; + } + } + ptr[i] = max_nrg; + } + + /* compute energy */ + if ((M == 10) && (stt->inQueue > 0)) + { + ptr = stt->Rxx16w32_array[1]; + } else + { + ptr = stt->Rxx16w32_array[0]; + } + + for (i = 0; i < WEBRTC_SPL_RSHIFT_W16(M, 1); i++) + { + if (stt->fs == 16000) + { + WebRtcSpl_DownsampleBy2(&in_mic[i * 32], 32, tmp_speech, stt->filterState); + } else + { + memcpy(tmp_speech, &in_mic[i * 16], 16 * sizeof(short)); + } + /* Compute energy in blocks of 16 samples */ + ptr[i] = WebRtcSpl_DotProductWithScale(tmp_speech, tmp_speech, 16, 4); + } + + /* update queue information */ + if ((stt->inQueue == 0) && (M == 10)) + { + stt->inQueue = 1; + } else + { + stt->inQueue = 2; + } + + /* call VAD (use low band only) */ + for (i = 0; i < samples; i += subFrames) + { + WebRtcAgc_ProcessVad(&stt->vadMic, &in_mic[i], subFrames); + } + + return 0; +} + +int WebRtcAgc_AddFarend(void *state, const WebRtc_Word16 *in_far, WebRtc_Word16 samples) +{ + WebRtc_Word32 errHandle = 0; + WebRtc_Word16 i, subFrames; + Agc_t *stt; + stt = (Agc_t *)state; + + if (stt == NULL) + { + return -1; + } + + if (stt->fs == 8000) + { + if ((samples != 80) && (samples != 160)) + { +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "AGC->add_far_end, frame %d: Invalid number of samples\n\n", + stt->fcount); +#endif + return -1; + } + subFrames = 80; + } else if (stt->fs == 16000) + { + if ((samples != 160) && (samples != 320)) + { +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "AGC->add_far_end, frame %d: Invalid number of samples\n\n", + stt->fcount); +#endif + return -1; + } + subFrames = 160; + } else if (stt->fs == 32000) + { + if ((samples != 160) && (samples != 320)) + { +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "AGC->add_far_end, frame %d: Invalid number of samples\n\n", + stt->fcount); +#endif + return -1; + } + subFrames = 160; + } else + { +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "AGC->add_far_end, frame %d: Invalid sample rate\n\n", + stt->fcount + 1); +#endif + return -1; + } + + for (i = 0; i < samples; i += subFrames) + { + errHandle += WebRtcAgc_AddFarendToDigital(&stt->digitalAgc, &in_far[i], subFrames); + } + + return errHandle; +} + +int WebRtcAgc_VirtualMic(void *agcInst, WebRtc_Word16 *in_near, WebRtc_Word16 *in_near_H, + WebRtc_Word16 samples, WebRtc_Word32 micLevelIn, + WebRtc_Word32 *micLevelOut) +{ + WebRtc_Word32 tmpFlt, micLevelTmp, gainIdx; + WebRtc_UWord16 gain; + WebRtc_Word16 ii; + Agc_t *stt; + + WebRtc_UWord32 nrg; + WebRtc_Word16 sampleCntr; + WebRtc_UWord32 frameNrg = 0; + WebRtc_UWord32 frameNrgLimit = 5500; + WebRtc_Word16 numZeroCrossing = 0; + const WebRtc_Word16 kZeroCrossingLowLim = 15; + const WebRtc_Word16 kZeroCrossingHighLim = 20; + + stt = (Agc_t *)agcInst; + + /* + * Before applying gain decide if this is a low-level signal. + * The idea is that digital AGC will not adapt to low-level + * signals. + */ + if (stt->fs != 8000) + { + frameNrgLimit = frameNrgLimit << 1; + } + + frameNrg = WEBRTC_SPL_MUL_16_16(in_near[0], in_near[0]); + for (sampleCntr = 1; sampleCntr < samples; sampleCntr++) + { + + // increment frame energy if it is less than the limit + // the correct value of the energy is not important + if (frameNrg < frameNrgLimit) + { + nrg = WEBRTC_SPL_MUL_16_16(in_near[sampleCntr], in_near[sampleCntr]); + frameNrg += nrg; + } + + // Count the zero crossings + numZeroCrossing += ((in_near[sampleCntr] ^ in_near[sampleCntr - 1]) < 0); + } + + if ((frameNrg < 500) || (numZeroCrossing <= 5)) + { + stt->lowLevelSignal = 1; + } else if (numZeroCrossing <= kZeroCrossingLowLim) + { + stt->lowLevelSignal = 0; + } else if (frameNrg <= frameNrgLimit) + { + stt->lowLevelSignal = 1; + } else if (numZeroCrossing >= kZeroCrossingHighLim) + { + stt->lowLevelSignal = 1; + } else + { + stt->lowLevelSignal = 0; + } + + micLevelTmp = WEBRTC_SPL_LSHIFT_W32(micLevelIn, stt->scale); + /* Set desired level */ + gainIdx = stt->micVol; + if (stt->micVol > stt->maxAnalog) + { + gainIdx = stt->maxAnalog; + } + if (micLevelTmp != stt->micRef) + { + /* Something has happened with the physical level, restart. */ + stt->micRef = micLevelTmp; + stt->micVol = 127; + *micLevelOut = 127; + stt->micGainIdx = 127; + gainIdx = 127; + } + /* Pre-process the signal to emulate the microphone level. */ + /* Take one step at a time in the gain table. */ + if (gainIdx > 127) + { + gain = kGainTableVirtualMic[gainIdx - 128]; + } else + { + gain = kSuppressionTableVirtualMic[127 - gainIdx]; + } + for (ii = 0; ii < samples; ii++) + { + tmpFlt = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_U16(in_near[ii], gain), 10); + if (tmpFlt > 32767) + { + tmpFlt = 32767; + gainIdx--; + if (gainIdx >= 127) + { + gain = kGainTableVirtualMic[gainIdx - 127]; + } else + { + gain = kSuppressionTableVirtualMic[127 - gainIdx]; + } + } + if (tmpFlt < -32768) + { + tmpFlt = -32768; + gainIdx--; + if (gainIdx >= 127) + { + gain = kGainTableVirtualMic[gainIdx - 127]; + } else + { + gain = kSuppressionTableVirtualMic[127 - gainIdx]; + } + } + in_near[ii] = (WebRtc_Word16)tmpFlt; + if (stt->fs == 32000) + { + tmpFlt = WEBRTC_SPL_MUL_16_U16(in_near_H[ii], gain); + tmpFlt = WEBRTC_SPL_RSHIFT_W32(tmpFlt, 10); + if (tmpFlt > 32767) + { + tmpFlt = 32767; + } + if (tmpFlt < -32768) + { + tmpFlt = -32768; + } + in_near_H[ii] = (WebRtc_Word16)tmpFlt; + } + } + /* Set the level we (finally) used */ + stt->micGainIdx = gainIdx; +// *micLevelOut = stt->micGainIdx; + *micLevelOut = WEBRTC_SPL_RSHIFT_W32(stt->micGainIdx, stt->scale); + /* Add to Mic as if it was the output from a true microphone */ + if (WebRtcAgc_AddMic(agcInst, in_near, in_near_H, samples) != 0) + { + return -1; + } + return 0; +} + +void WebRtcAgc_UpdateAgcThresholds(Agc_t *stt) +{ + + WebRtc_Word16 tmp16; +#ifdef MIC_LEVEL_FEEDBACK + int zeros; + + if (stt->micLvlSat) + { + /* Lower the analog target level since we have reached its maximum */ + zeros = WebRtcSpl_NormW32(stt->Rxx160_LPw32); + stt->targetIdxOffset = WEBRTC_SPL_RSHIFT_W16((3 * zeros) - stt->targetIdx - 2, 2); + } +#endif + + /* Set analog target level in envelope dBOv scale */ + tmp16 = (DIFF_REF_TO_ANALOG * stt->compressionGaindB) + ANALOG_TARGET_LEVEL_2; + tmp16 = WebRtcSpl_DivW32W16ResW16((WebRtc_Word32)tmp16, ANALOG_TARGET_LEVEL); + stt->analogTarget = DIGITAL_REF_AT_0_COMP_GAIN + tmp16; + if (stt->analogTarget < DIGITAL_REF_AT_0_COMP_GAIN) + { + stt->analogTarget = DIGITAL_REF_AT_0_COMP_GAIN; + } + if (stt->agcMode == kAgcModeFixedDigital) + { + /* Adjust for different parameter interpretation in FixedDigital mode */ + stt->analogTarget = stt->compressionGaindB; + } +#ifdef MIC_LEVEL_FEEDBACK + stt->analogTarget += stt->targetIdxOffset; +#endif + /* Since the offset between RMS and ENV is not constant, we should make this into a + * table, but for now, we'll stick with a constant, tuned for the chosen analog + * target level. + */ + stt->targetIdx = ANALOG_TARGET_LEVEL + OFFSET_ENV_TO_RMS; +#ifdef MIC_LEVEL_FEEDBACK + stt->targetIdx += stt->targetIdxOffset; +#endif + /* Analog adaptation limits */ + /* analogTargetLevel = round((32767*10^(-targetIdx/20))^2*16/2^7) */ + stt->analogTargetLevel = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx]; /* ex. -20 dBov */ + stt->startUpperLimit = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx - 1];/* -19 dBov */ + stt->startLowerLimit = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx + 1];/* -21 dBov */ + stt->upperPrimaryLimit = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx - 2];/* -18 dBov */ + stt->lowerPrimaryLimit = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx + 2];/* -22 dBov */ + stt->upperSecondaryLimit = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx - 5];/* -15 dBov */ + stt->lowerSecondaryLimit = RXX_BUFFER_LEN * kTargetLevelTable[stt->targetIdx + 5];/* -25 dBov */ + stt->upperLimit = stt->startUpperLimit; + stt->lowerLimit = stt->startLowerLimit; +} + +void WebRtcAgc_SaturationCtrl(Agc_t *stt, WebRtc_UWord8 *saturated, WebRtc_Word32 *env) +{ + WebRtc_Word16 i, tmpW16; + + /* Check if the signal is saturated */ + for (i = 0; i < 10; i++) + { + tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(env[i], 20); + if (tmpW16 > 875) + { + stt->envSum += tmpW16; + } + } + + if (stt->envSum > 25000) + { + *saturated = 1; + stt->envSum = 0; + } + + /* stt->envSum *= 0.99; */ + stt->envSum = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(stt->envSum, + (WebRtc_Word16)32440, 15); +} + +void WebRtcAgc_ZeroCtrl(Agc_t *stt, WebRtc_Word32 *inMicLevel, WebRtc_Word32 *env) +{ + WebRtc_Word16 i; + WebRtc_Word32 tmp32 = 0; + WebRtc_Word32 midVal; + + /* Is the input signal zero? */ + for (i = 0; i < 10; i++) + { + tmp32 += env[i]; + } + + /* Each block is allowed to have a few non-zero + * samples. + */ + if (tmp32 < 500) + { + stt->msZero += 10; + } else + { + stt->msZero = 0; + } + + if (stt->muteGuardMs > 0) + { + stt->muteGuardMs -= 10; + } + + if (stt->msZero > 500) + { + stt->msZero = 0; + + /* Increase microphone level only if it's less than 50% */ + midVal = WEBRTC_SPL_RSHIFT_W32(stt->maxAnalog + stt->minLevel + 1, 1); + if (*inMicLevel < midVal) + { + /* *inMicLevel *= 1.1; */ + tmp32 = WEBRTC_SPL_MUL(1126, *inMicLevel); + *inMicLevel = WEBRTC_SPL_RSHIFT_W32(tmp32, 10); + /* Reduces risk of a muted mic repeatedly triggering excessive levels due + * to zero signal detection. */ + *inMicLevel = WEBRTC_SPL_MIN(*inMicLevel, stt->zeroCtrlMax); + stt->micVol = *inMicLevel; + } + +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "\t\tAGC->zeroCntrl, frame %d: 500 ms under threshold, micVol:\n", + stt->fcount, stt->micVol); +#endif + + stt->activeSpeech = 0; + stt->Rxx16_LPw32Max = 0; + + /* The AGC has a tendency (due to problems with the VAD parameters), to + * vastly increase the volume after a muting event. This timer prevents + * upwards adaptation for a short period. */ + stt->muteGuardMs = kMuteGuardTimeMs; + } +} + +void WebRtcAgc_SpeakerInactiveCtrl(Agc_t *stt) +{ + /* Check if the near end speaker is inactive. + * If that is the case the VAD threshold is + * increased since the VAD speech model gets + * more sensitive to any sound after a long + * silence. + */ + + WebRtc_Word32 tmp32; + WebRtc_Word16 vadThresh; + + if (stt->vadMic.stdLongTerm < 2500) + { + stt->vadThreshold = 1500; + } else + { + vadThresh = kNormalVadThreshold; + if (stt->vadMic.stdLongTerm < 4500) + { + /* Scale between min and max threshold */ + vadThresh += WEBRTC_SPL_RSHIFT_W16(4500 - stt->vadMic.stdLongTerm, 1); + } + + /* stt->vadThreshold = (31 * stt->vadThreshold + vadThresh) / 32; */ + tmp32 = (WebRtc_Word32)vadThresh; + tmp32 += WEBRTC_SPL_MUL_16_16((WebRtc_Word16)31, stt->vadThreshold); + stt->vadThreshold = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 5); + } +} + +void WebRtcAgc_ExpCurve(WebRtc_Word16 volume, WebRtc_Word16 *index) +{ + // volume in Q14 + // index in [0-7] + /* 8 different curves */ + if (volume > 5243) + { + if (volume > 7864) + { + if (volume > 12124) + { + *index = 7; + } else + { + *index = 6; + } + } else + { + if (volume > 6554) + { + *index = 5; + } else + { + *index = 4; + } + } + } else + { + if (volume > 2621) + { + if (volume > 3932) + { + *index = 3; + } else + { + *index = 2; + } + } else + { + if (volume > 1311) + { + *index = 1; + } else + { + *index = 0; + } + } + } +} + +WebRtc_Word32 WebRtcAgc_ProcessAnalog(void *state, WebRtc_Word32 inMicLevel, + WebRtc_Word32 *outMicLevel, + WebRtc_Word16 vadLogRatio, + WebRtc_Word16 echo, WebRtc_UWord8 *saturationWarning) +{ + WebRtc_UWord32 tmpU32; + WebRtc_Word32 Rxx16w32, tmp32; + WebRtc_Word32 inMicLevelTmp, lastMicVol; + WebRtc_Word16 i; + WebRtc_UWord8 saturated = 0; + Agc_t *stt; + + stt = (Agc_t *)state; + inMicLevelTmp = WEBRTC_SPL_LSHIFT_W32(inMicLevel, stt->scale); + + if (inMicLevelTmp > stt->maxAnalog) + { +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, "\tAGC->ProcessAnalog, frame %d: micLvl > maxAnalog\n", stt->fcount); +#endif + return -1; + } else if (inMicLevelTmp < stt->minLevel) + { +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, "\tAGC->ProcessAnalog, frame %d: micLvl < minLevel\n", stt->fcount); +#endif + return -1; + } + + if (stt->firstCall == 0) + { + WebRtc_Word32 tmpVol; + stt->firstCall = 1; + tmp32 = WEBRTC_SPL_RSHIFT_W32((stt->maxLevel - stt->minLevel) * (WebRtc_Word32)51, 9); + tmpVol = (stt->minLevel + tmp32); + + /* If the mic level is very low at start, increase it! */ + if ((inMicLevelTmp < tmpVol) && (stt->agcMode == kAgcModeAdaptiveAnalog)) + { + inMicLevelTmp = tmpVol; + } + stt->micVol = inMicLevelTmp; + } + + /* Set the mic level to the previous output value if there is digital input gain */ + if ((inMicLevelTmp == stt->maxAnalog) && (stt->micVol > stt->maxAnalog)) + { + inMicLevelTmp = stt->micVol; + } + + /* If the mic level was manually changed to a very low value raise it! */ + if ((inMicLevelTmp != stt->micVol) && (inMicLevelTmp < stt->minOutput)) + { + tmp32 = WEBRTC_SPL_RSHIFT_W32((stt->maxLevel - stt->minLevel) * (WebRtc_Word32)51, 9); + inMicLevelTmp = (stt->minLevel + tmp32); + stt->micVol = inMicLevelTmp; +#ifdef MIC_LEVEL_FEEDBACK + //stt->numBlocksMicLvlSat = 0; +#endif +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "\tAGC->ProcessAnalog, frame %d: micLvl < minLevel by manual decrease, raise vol\n", + stt->fcount); +#endif + } + + if (inMicLevelTmp != stt->micVol) + { + // Incoming level mismatch; update our level. + // This could be the case if the volume is changed manually, or if the + // sound device has a low volume resolution. + stt->micVol = inMicLevelTmp; + } + + if (inMicLevelTmp > stt->maxLevel) + { + // Always allow the user to raise the volume above the maxLevel. + stt->maxLevel = inMicLevelTmp; + } + + // Store last value here, after we've taken care of manual updates etc. + lastMicVol = stt->micVol; + + /* Checks if the signal is saturated. Also a check if individual samples + * are larger than 12000 is done. If they are the counter for increasing + * the volume level is set to -100ms + */ + WebRtcAgc_SaturationCtrl(stt, &saturated, stt->env[0]); + + /* The AGC is always allowed to lower the level if the signal is saturated */ + if (saturated == 1) + { + /* Lower the recording level + * Rxx160_LP is adjusted down because it is so slow it could + * cause the AGC to make wrong decisions. */ + /* stt->Rxx160_LPw32 *= 0.875; */ + stt->Rxx160_LPw32 = WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(stt->Rxx160_LPw32, 3), 7); + + stt->zeroCtrlMax = stt->micVol; + + /* stt->micVol *= 0.903; */ + tmp32 = inMicLevelTmp - stt->minLevel; + tmpU32 = WEBRTC_SPL_UMUL(29591, (WebRtc_UWord32)(tmp32)); + stt->micVol = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(tmpU32, 15) + stt->minLevel; + if (stt->micVol > lastMicVol - 2) + { + stt->micVol = lastMicVol - 2; + } + inMicLevelTmp = stt->micVol; + +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "\tAGC->ProcessAnalog, frame %d: saturated, micVol = %d\n", + stt->fcount, stt->micVol); +#endif + + if (stt->micVol < stt->minOutput) + { + *saturationWarning = 1; + } + + /* Reset counter for decrease of volume level to avoid + * decreasing too much. The saturation control can still + * lower the level if needed. */ + stt->msTooHigh = -100; + + /* Enable the control mechanism to ensure that our measure, + * Rxx160_LP, is in the correct range. This must be done since + * the measure is very slow. */ + stt->activeSpeech = 0; + stt->Rxx16_LPw32Max = 0; + + /* Reset to initial values */ + stt->msecSpeechInnerChange = kMsecSpeechInner; + stt->msecSpeechOuterChange = kMsecSpeechOuter; + stt->changeToSlowMode = 0; + + stt->muteGuardMs = 0; + + stt->upperLimit = stt->startUpperLimit; + stt->lowerLimit = stt->startLowerLimit; +#ifdef MIC_LEVEL_FEEDBACK + //stt->numBlocksMicLvlSat = 0; +#endif + } + + /* Check if the input speech is zero. If so the mic volume + * is increased. On some computers the input is zero up as high + * level as 17% */ + WebRtcAgc_ZeroCtrl(stt, &inMicLevelTmp, stt->env[0]); + + /* Check if the near end speaker is inactive. + * If that is the case the VAD threshold is + * increased since the VAD speech model gets + * more sensitive to any sound after a long + * silence. + */ + WebRtcAgc_SpeakerInactiveCtrl(stt); + + for (i = 0; i < 5; i++) + { + /* Computed on blocks of 16 samples */ + + Rxx16w32 = stt->Rxx16w32_array[0][i]; + + /* Rxx160w32 in Q(-7) */ + tmp32 = WEBRTC_SPL_RSHIFT_W32(Rxx16w32 - stt->Rxx16_vectorw32[stt->Rxx16pos], 3); + stt->Rxx160w32 = stt->Rxx160w32 + tmp32; + stt->Rxx16_vectorw32[stt->Rxx16pos] = Rxx16w32; + + /* Circular buffer */ + stt->Rxx16pos = stt->Rxx16pos++; + if (stt->Rxx16pos == RXX_BUFFER_LEN) + { + stt->Rxx16pos = 0; + } + + /* Rxx16_LPw32 in Q(-4) */ + tmp32 = WEBRTC_SPL_RSHIFT_W32(Rxx16w32 - stt->Rxx16_LPw32, kAlphaShortTerm); + stt->Rxx16_LPw32 = (stt->Rxx16_LPw32) + tmp32; + + if (vadLogRatio > stt->vadThreshold) + { + /* Speech detected! */ + + /* Check if Rxx160_LP is in the correct range. If + * it is too high/low then we set it to the maximum of + * Rxx16_LPw32 during the first 200ms of speech. + */ + if (stt->activeSpeech < 250) + { + stt->activeSpeech += 2; + + if (stt->Rxx16_LPw32 > stt->Rxx16_LPw32Max) + { + stt->Rxx16_LPw32Max = stt->Rxx16_LPw32; + } + } else if (stt->activeSpeech == 250) + { + stt->activeSpeech += 2; + tmp32 = WEBRTC_SPL_RSHIFT_W32(stt->Rxx16_LPw32Max, 3); + stt->Rxx160_LPw32 = WEBRTC_SPL_MUL(tmp32, RXX_BUFFER_LEN); + } + + tmp32 = WEBRTC_SPL_RSHIFT_W32(stt->Rxx160w32 - stt->Rxx160_LPw32, kAlphaLongTerm); + stt->Rxx160_LPw32 = stt->Rxx160_LPw32 + tmp32; + + if (stt->Rxx160_LPw32 > stt->upperSecondaryLimit) + { + stt->msTooHigh += 2; + stt->msTooLow = 0; + stt->changeToSlowMode = 0; + + if (stt->msTooHigh > stt->msecSpeechOuterChange) + { + stt->msTooHigh = 0; + + /* Lower the recording level */ + /* Multiply by 0.828125 which corresponds to decreasing ~0.8dB */ + tmp32 = WEBRTC_SPL_RSHIFT_W32(stt->Rxx160_LPw32, 6); + stt->Rxx160_LPw32 = WEBRTC_SPL_MUL(tmp32, 53); + + /* Reduce the max gain to avoid excessive oscillation + * (but never drop below the maximum analog level). + * stt->maxLevel = (15 * stt->maxLevel + stt->micVol) / 16; + */ + tmp32 = (15 * stt->maxLevel) + stt->micVol; + stt->maxLevel = WEBRTC_SPL_RSHIFT_W32(tmp32, 4); + stt->maxLevel = WEBRTC_SPL_MAX(stt->maxLevel, stt->maxAnalog); + + stt->zeroCtrlMax = stt->micVol; + + /* 0.95 in Q15 */ + tmp32 = inMicLevelTmp - stt->minLevel; + tmpU32 = WEBRTC_SPL_UMUL(31130, (WebRtc_UWord32)(tmp32)); + stt->micVol = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(tmpU32, 15) + stt->minLevel; + if (stt->micVol > lastMicVol - 1) + { + stt->micVol = lastMicVol - 1; + } + inMicLevelTmp = stt->micVol; + + /* Enable the control mechanism to ensure that our measure, + * Rxx160_LP, is in the correct range. + */ + stt->activeSpeech = 0; + stt->Rxx16_LPw32Max = 0; +#ifdef MIC_LEVEL_FEEDBACK + //stt->numBlocksMicLvlSat = 0; +#endif +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "\tAGC->ProcessAnalog, frame %d: measure > 2ndUpperLim, micVol = %d, maxLevel = %d\n", + stt->fcount, stt->micVol, stt->maxLevel); +#endif + } + } else if (stt->Rxx160_LPw32 > stt->upperLimit) + { + stt->msTooHigh += 2; + stt->msTooLow = 0; + stt->changeToSlowMode = 0; + + if (stt->msTooHigh > stt->msecSpeechInnerChange) + { + /* Lower the recording level */ + stt->msTooHigh = 0; + /* Multiply by 0.828125 which corresponds to decreasing ~0.8dB */ + tmp32 = WEBRTC_SPL_RSHIFT_W32(stt->Rxx160_LPw32, 6); + stt->Rxx160_LPw32 = WEBRTC_SPL_MUL(tmp32, 53); + + /* Reduce the max gain to avoid excessive oscillation + * (but never drop below the maximum analog level). + * stt->maxLevel = (15 * stt->maxLevel + stt->micVol) / 16; + */ + tmp32 = (15 * stt->maxLevel) + stt->micVol; + stt->maxLevel = WEBRTC_SPL_RSHIFT_W32(tmp32, 4); + stt->maxLevel = WEBRTC_SPL_MAX(stt->maxLevel, stt->maxAnalog); + + stt->zeroCtrlMax = stt->micVol; + + /* 0.965 in Q15 */ + tmp32 = inMicLevelTmp - stt->minLevel; + tmpU32 = WEBRTC_SPL_UMUL(31621, (WebRtc_UWord32)(inMicLevelTmp - stt->minLevel)); + stt->micVol = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(tmpU32, 15) + stt->minLevel; + if (stt->micVol > lastMicVol - 1) + { + stt->micVol = lastMicVol - 1; + } + inMicLevelTmp = stt->micVol; + +#ifdef MIC_LEVEL_FEEDBACK + //stt->numBlocksMicLvlSat = 0; +#endif +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "\tAGC->ProcessAnalog, frame %d: measure > UpperLim, micVol = %d, maxLevel = %d\n", + stt->fcount, stt->micVol, stt->maxLevel); +#endif + } + } else if (stt->Rxx160_LPw32 < stt->lowerSecondaryLimit) + { + stt->msTooHigh = 0; + stt->changeToSlowMode = 0; + stt->msTooLow += 2; + + if (stt->msTooLow > stt->msecSpeechOuterChange) + { + /* Raise the recording level */ + WebRtc_Word16 index, weightFIX; + WebRtc_Word16 volNormFIX = 16384; // =1 in Q14. + + stt->msTooLow = 0; + + /* Normalize the volume level */ + tmp32 = WEBRTC_SPL_LSHIFT_W32(inMicLevelTmp - stt->minLevel, 14); + if (stt->maxInit != stt->minLevel) + { + volNormFIX = (WebRtc_Word16)WEBRTC_SPL_DIV(tmp32, + (stt->maxInit - stt->minLevel)); + } + + /* Find correct curve */ + WebRtcAgc_ExpCurve(volNormFIX, &index); + + /* Compute weighting factor for the volume increase, 32^(-2*X)/2+1.05 */ + weightFIX = kOffset1[index] + - (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(kSlope1[index], + volNormFIX, 13); + + /* stt->Rxx160_LPw32 *= 1.047 [~0.2 dB]; */ + tmp32 = WEBRTC_SPL_RSHIFT_W32(stt->Rxx160_LPw32, 6); + stt->Rxx160_LPw32 = WEBRTC_SPL_MUL(tmp32, 67); + + tmp32 = inMicLevelTmp - stt->minLevel; + tmpU32 = ((WebRtc_UWord32)weightFIX * (WebRtc_UWord32)(inMicLevelTmp - stt->minLevel)); + stt->micVol = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(tmpU32, 14) + stt->minLevel; + if (stt->micVol < lastMicVol + 2) + { + stt->micVol = lastMicVol + 2; + } + + inMicLevelTmp = stt->micVol; + +#ifdef MIC_LEVEL_FEEDBACK + /* Count ms in level saturation */ + //if (stt->micVol > stt->maxAnalog) { + if (stt->micVol > 150) + { + /* mic level is saturated */ + stt->numBlocksMicLvlSat++; + fprintf(stderr, "Sat mic Level: %d\n", stt->numBlocksMicLvlSat); + } +#endif +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "\tAGC->ProcessAnalog, frame %d: measure < 2ndLowerLim, micVol = %d\n", + stt->fcount, stt->micVol); +#endif + } + } else if (stt->Rxx160_LPw32 < stt->lowerLimit) + { + stt->msTooHigh = 0; + stt->changeToSlowMode = 0; + stt->msTooLow += 2; + + if (stt->msTooLow > stt->msecSpeechInnerChange) + { + /* Raise the recording level */ + WebRtc_Word16 index, weightFIX; + WebRtc_Word16 volNormFIX = 16384; // =1 in Q14. + + stt->msTooLow = 0; + + /* Normalize the volume level */ + tmp32 = WEBRTC_SPL_LSHIFT_W32(inMicLevelTmp - stt->minLevel, 14); + if (stt->maxInit != stt->minLevel) + { + volNormFIX = (WebRtc_Word16)WEBRTC_SPL_DIV(tmp32, + (stt->maxInit - stt->minLevel)); + } + + /* Find correct curve */ + WebRtcAgc_ExpCurve(volNormFIX, &index); + + /* Compute weighting factor for the volume increase, (3.^(-2.*X))/8+1 */ + weightFIX = kOffset2[index] + - (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(kSlope2[index], + volNormFIX, 13); + + /* stt->Rxx160_LPw32 *= 1.047 [~0.2 dB]; */ + tmp32 = WEBRTC_SPL_RSHIFT_W32(stt->Rxx160_LPw32, 6); + stt->Rxx160_LPw32 = WEBRTC_SPL_MUL(tmp32, 67); + + tmp32 = inMicLevelTmp - stt->minLevel; + tmpU32 = ((WebRtc_UWord32)weightFIX * (WebRtc_UWord32)(inMicLevelTmp - stt->minLevel)); + stt->micVol = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(tmpU32, 14) + stt->minLevel; + if (stt->micVol < lastMicVol + 1) + { + stt->micVol = lastMicVol + 1; + } + + inMicLevelTmp = stt->micVol; + +#ifdef MIC_LEVEL_FEEDBACK + /* Count ms in level saturation */ + //if (stt->micVol > stt->maxAnalog) { + if (stt->micVol > 150) + { + /* mic level is saturated */ + stt->numBlocksMicLvlSat++; + fprintf(stderr, "Sat mic Level: %d\n", stt->numBlocksMicLvlSat); + } +#endif +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "\tAGC->ProcessAnalog, frame %d: measure < LowerLim, micVol = %d\n", + stt->fcount, stt->micVol); +#endif + + } + } else + { + /* The signal is inside the desired range which is: + * lowerLimit < Rxx160_LP/640 < upperLimit + */ + if (stt->changeToSlowMode > 4000) + { + stt->msecSpeechInnerChange = 1000; + stt->msecSpeechOuterChange = 500; + stt->upperLimit = stt->upperPrimaryLimit; + stt->lowerLimit = stt->lowerPrimaryLimit; + } else + { + stt->changeToSlowMode += 2; // in milliseconds + } + stt->msTooLow = 0; + stt->msTooHigh = 0; + + stt->micVol = inMicLevelTmp; + + } +#ifdef MIC_LEVEL_FEEDBACK + if (stt->numBlocksMicLvlSat > NUM_BLOCKS_IN_SAT_BEFORE_CHANGE_TARGET) + { + stt->micLvlSat = 1; + fprintf(stderr, "target before = %d (%d)\n", stt->analogTargetLevel, stt->targetIdx); + WebRtcAgc_UpdateAgcThresholds(stt); + WebRtcAgc_CalculateGainTable(&(stt->digitalAgc.gainTable[0]), + stt->compressionGaindB, stt->targetLevelDbfs, stt->limiterEnable, + stt->analogTarget); + stt->numBlocksMicLvlSat = 0; + stt->micLvlSat = 0; + fprintf(stderr, "target offset = %d\n", stt->targetIdxOffset); + fprintf(stderr, "target after = %d (%d)\n", stt->analogTargetLevel, stt->targetIdx); + } +#endif + } + } + + /* Ensure gain is not increased in presence of echo or after a mute event + * (but allow the zeroCtrl() increase on the frame of a mute detection). + */ + if (echo == 1 || (stt->muteGuardMs > 0 && stt->muteGuardMs < kMuteGuardTimeMs)) + { + if (stt->micVol > lastMicVol) + { + stt->micVol = lastMicVol; + } + } + + /* limit the gain */ + if (stt->micVol > stt->maxLevel) + { + stt->micVol = stt->maxLevel; + } else if (stt->micVol < stt->minOutput) + { + stt->micVol = stt->minOutput; + } + + *outMicLevel = WEBRTC_SPL_RSHIFT_W32(stt->micVol, stt->scale); + if (*outMicLevel > WEBRTC_SPL_RSHIFT_W32(stt->maxAnalog, stt->scale)) + { + *outMicLevel = WEBRTC_SPL_RSHIFT_W32(stt->maxAnalog, stt->scale); + } + + return 0; +} + +int WebRtcAgc_Process(void *agcInst, const WebRtc_Word16 *in_near, + const WebRtc_Word16 *in_near_H, WebRtc_Word16 samples, + WebRtc_Word16 *out, WebRtc_Word16 *out_H, WebRtc_Word32 inMicLevel, + WebRtc_Word32 *outMicLevel, WebRtc_Word16 echo, + WebRtc_UWord8 *saturationWarning) +{ + Agc_t *stt; + WebRtc_Word32 inMicLevelTmp; + WebRtc_Word16 subFrames, i; + WebRtc_UWord8 satWarningTmp = 0; + + stt = (Agc_t *)agcInst; + + // + if (stt == NULL) + { + return -1; + } + // + + + if (stt->fs == 8000) + { + if ((samples != 80) && (samples != 160)) + { +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "AGC->Process, frame %d: Invalid number of samples\n\n", stt->fcount); +#endif + return -1; + } + subFrames = 80; + } else if (stt->fs == 16000) + { + if ((samples != 160) && (samples != 320)) + { +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "AGC->Process, frame %d: Invalid number of samples\n\n", stt->fcount); +#endif + return -1; + } + subFrames = 160; + } else if (stt->fs == 32000) + { + if ((samples != 160) && (samples != 320)) + { +#ifdef AGC_DEBUG //test log + fprintf(stt->fpt, + "AGC->Process, frame %d: Invalid number of samples\n\n", stt->fcount); +#endif + return -1; + } + subFrames = 160; + } else + { +#ifdef AGC_DEBUG// test log + fprintf(stt->fpt, + "AGC->Process, frame %d: Invalid sample rate\n\n", stt->fcount); +#endif + return -1; + } + + /* Check for valid pointers based on sampling rate */ + if (stt->fs == 32000 && in_near_H == NULL) + { + return -1; + } + /* Check for valid pointers for low band */ + if (in_near == NULL) + { + return -1; + } + + *saturationWarning = 0; + //TODO: PUT IN RANGE CHECKING FOR INPUT LEVELS + *outMicLevel = inMicLevel; + inMicLevelTmp = inMicLevel; + + memcpy(out, in_near, samples * sizeof(WebRtc_Word16)); + if (stt->fs == 32000) + { + memcpy(out_H, in_near_H, samples * sizeof(WebRtc_Word16)); + } + +#ifdef AGC_DEBUG//test log + stt->fcount++; +#endif + + for (i = 0; i < samples; i += subFrames) + { + if (WebRtcAgc_ProcessDigital(&stt->digitalAgc, &in_near[i], &in_near_H[i], &out[i], &out_H[i], + stt->fs, stt->lowLevelSignal) == -1) + { +#ifdef AGC_DEBUG//test log + fprintf(stt->fpt, "AGC->Process, frame %d: Error from DigAGC\n\n", stt->fcount); +#endif + return -1; + } + if ((stt->agcMode < kAgcModeFixedDigital) && ((stt->lowLevelSignal == 0) + || (stt->agcMode != kAgcModeAdaptiveDigital))) + { + if (WebRtcAgc_ProcessAnalog(agcInst, inMicLevelTmp, outMicLevel, + stt->vadMic.logRatio, echo, saturationWarning) == -1) + { + return -1; + } + } +#ifdef AGC_DEBUG//test log + fprintf(stt->agcLog, "%5d\t%d\t%d\t%d\n", stt->fcount, inMicLevelTmp, *outMicLevel, stt->maxLevel, stt->micVol); +#endif + + /* update queue */ + if (stt->inQueue > 1) + { + memcpy(stt->env[0], stt->env[1], 10 * sizeof(WebRtc_Word32)); + memcpy(stt->Rxx16w32_array[0], stt->Rxx16w32_array[1], 5 * sizeof(WebRtc_Word32)); + } + + if (stt->inQueue > 0) + { + stt->inQueue--; + } + + /* If 20ms frames are used the input mic level must be updated so that + * the analog AGC does not think that there has been a manual volume + * change. */ + inMicLevelTmp = *outMicLevel; + + /* Store a positive saturation warning. */ + if (*saturationWarning == 1) + { + satWarningTmp = 1; + } + } + + /* Trigger the saturation warning if displayed by any of the frames. */ + *saturationWarning = satWarningTmp; + + return 0; +} + +int WebRtcAgc_set_config(void *agcInst, WebRtcAgc_config_t agcConfig) +{ + Agc_t *stt; + stt = (Agc_t *)agcInst; + + if (stt == NULL) + { + return -1; + } + + if (stt->initFlag != kInitCheck) + { + stt->lastError = AGC_UNINITIALIZED_ERROR; + return -1; + } + + if (agcConfig.limiterEnable != kAgcFalse && agcConfig.limiterEnable != kAgcTrue) + { + stt->lastError = AGC_BAD_PARAMETER_ERROR; + return -1; + } + stt->limiterEnable = agcConfig.limiterEnable; + stt->compressionGaindB = agcConfig.compressionGaindB; + if ((agcConfig.targetLevelDbfs < 0) || (agcConfig.targetLevelDbfs > 31)) + { + stt->lastError = AGC_BAD_PARAMETER_ERROR; + return -1; + } + stt->targetLevelDbfs = agcConfig.targetLevelDbfs; + + if (stt->agcMode == kAgcModeFixedDigital) + { + /* Adjust for different parameter interpretation in FixedDigital mode */ + stt->compressionGaindB += agcConfig.targetLevelDbfs; + } + + /* Update threshold levels for analog adaptation */ + WebRtcAgc_UpdateAgcThresholds(stt); + + /* Recalculate gain table */ + if (WebRtcAgc_CalculateGainTable(&(stt->digitalAgc.gainTable[0]), stt->compressionGaindB, + stt->targetLevelDbfs, stt->limiterEnable, stt->analogTarget) == -1) + { +#ifdef AGC_DEBUG//test log + fprintf(stt->fpt, "AGC->set_config, frame %d: Error from calcGainTable\n\n", stt->fcount); +#endif + return -1; + } + /* Store the config in a WebRtcAgc_config_t */ + stt->usedConfig.compressionGaindB = agcConfig.compressionGaindB; + stt->usedConfig.limiterEnable = agcConfig.limiterEnable; + stt->usedConfig.targetLevelDbfs = agcConfig.targetLevelDbfs; + + return 0; +} + +int WebRtcAgc_get_config(void *agcInst, WebRtcAgc_config_t *config) +{ + Agc_t *stt; + stt = (Agc_t *)agcInst; + + if (stt == NULL) + { + return -1; + } + + if (config == NULL) + { + stt->lastError = AGC_NULL_POINTER_ERROR; + return -1; + } + + if (stt->initFlag != kInitCheck) + { + stt->lastError = AGC_UNINITIALIZED_ERROR; + return -1; + } + + config->limiterEnable = stt->usedConfig.limiterEnable; + config->targetLevelDbfs = stt->usedConfig.targetLevelDbfs; + config->compressionGaindB = stt->usedConfig.compressionGaindB; + + return 0; +} + +int WebRtcAgc_Create(void **agcInst) +{ + Agc_t *stt; + if (agcInst == NULL) + { + return -1; + } + stt = (Agc_t *)malloc(sizeof(Agc_t)); + + *agcInst = stt; + if (stt == NULL) + { + return -1; + } + +#ifdef AGC_DEBUG + stt->fpt = fopen("./agc_test_log.txt", "wt"); + stt->agcLog = fopen("./agc_debug_log.txt", "wt"); + stt->digitalAgc.logFile = fopen("./agc_log.txt", "wt"); +#endif + + stt->initFlag = 0; + stt->lastError = 0; + + return 0; +} + +int WebRtcAgc_Free(void *state) +{ + Agc_t *stt; + + stt = (Agc_t *)state; +#ifdef AGC_DEBUG + fclose(stt->fpt); + fclose(stt->agcLog); + fclose(stt->digitalAgc.logFile); +#endif + free(stt); + + return 0; +} + +/* minLevel - Minimum volume level + * maxLevel - Maximum volume level + */ +int WebRtcAgc_Init(void *agcInst, WebRtc_Word32 minLevel, WebRtc_Word32 maxLevel, + WebRtc_Word16 agcMode, WebRtc_UWord32 fs) +{ + WebRtc_Word32 max_add, tmp32; + WebRtc_Word16 i; + int tmpNorm; + Agc_t *stt; + + /* typecast state pointer */ + stt = (Agc_t *)agcInst; + + if (WebRtcAgc_InitDigital(&stt->digitalAgc, agcMode) != 0) + { + stt->lastError = AGC_UNINITIALIZED_ERROR; + return -1; + } + + /* Analog AGC variables */ + stt->envSum = 0; + + /* mode = 0 - Only saturation protection + * 1 - Analog Automatic Gain Control [-targetLevelDbfs (default -3 dBOv)] + * 2 - Digital Automatic Gain Control [-targetLevelDbfs (default -3 dBOv)] + * 3 - Fixed Digital Gain [compressionGaindB (default 8 dB)] + */ +#ifdef AGC_DEBUG//test log + stt->fcount = 0; + fprintf(stt->fpt, "AGC->Init\n"); +#endif + if (agcMode < kAgcModeUnchanged || agcMode > kAgcModeFixedDigital) + { +#ifdef AGC_DEBUG//test log + fprintf(stt->fpt, "AGC->Init: error, incorrect mode\n\n"); +#endif + return -1; + } + stt->agcMode = agcMode; + stt->fs = fs; + + /* initialize input VAD */ + WebRtcAgc_InitVad(&stt->vadMic); + + /* If the volume range is smaller than 0-256 then + * the levels are shifted up to Q8-domain */ + tmpNorm = WebRtcSpl_NormU32((WebRtc_UWord32)maxLevel); + stt->scale = tmpNorm - 23; + if (stt->scale < 0) + { + stt->scale = 0; + } + // TODO(bjornv): Investigate if we really need to scale up a small range now when we have + // a guard against zero-increments. For now, we do not support scale up (scale = 0). + stt->scale = 0; + maxLevel = WEBRTC_SPL_LSHIFT_W32(maxLevel, stt->scale); + minLevel = WEBRTC_SPL_LSHIFT_W32(minLevel, stt->scale); + + /* Make minLevel and maxLevel static in AdaptiveDigital */ + if (stt->agcMode == kAgcModeAdaptiveDigital) + { + minLevel = 0; + maxLevel = 255; + stt->scale = 0; + } + /* The maximum supplemental volume range is based on a vague idea + * of how much lower the gain will be than the real analog gain. */ + max_add = WEBRTC_SPL_RSHIFT_W32(maxLevel - minLevel, 2); + + /* Minimum/maximum volume level that can be set */ + stt->minLevel = minLevel; + stt->maxAnalog = maxLevel; + stt->maxLevel = maxLevel + max_add; + stt->maxInit = stt->maxLevel; + + stt->zeroCtrlMax = stt->maxAnalog; + + /* Initialize micVol parameter */ + stt->micVol = stt->maxAnalog; + if (stt->agcMode == kAgcModeAdaptiveDigital) + { + stt->micVol = 127; /* Mid-point of mic level */ + } + stt->micRef = stt->micVol; + stt->micGainIdx = 127; +#ifdef MIC_LEVEL_FEEDBACK + stt->numBlocksMicLvlSat = 0; + stt->micLvlSat = 0; +#endif +#ifdef AGC_DEBUG//test log + fprintf(stt->fpt, + "AGC->Init: minLevel = %d, maxAnalog = %d, maxLevel = %d\n", + stt->minLevel, stt->maxAnalog, stt->maxLevel); +#endif + + /* Minimum output volume is 4% higher than the available lowest volume level */ + tmp32 = WEBRTC_SPL_RSHIFT_W32((stt->maxLevel - stt->minLevel) * (WebRtc_Word32)10, 8); + stt->minOutput = (stt->minLevel + tmp32); + + stt->msTooLow = 0; + stt->msTooHigh = 0; + stt->changeToSlowMode = 0; + stt->firstCall = 0; + stt->msZero = 0; + stt->muteGuardMs = 0; + stt->gainTableIdx = 0; + + stt->msecSpeechInnerChange = kMsecSpeechInner; + stt->msecSpeechOuterChange = kMsecSpeechOuter; + + stt->activeSpeech = 0; + stt->Rxx16_LPw32Max = 0; + + stt->vadThreshold = kNormalVadThreshold; + stt->inActive = 0; + + for (i = 0; i < RXX_BUFFER_LEN; i++) + { + stt->Rxx16_vectorw32[i] = (WebRtc_Word32)1000; /* -54dBm0 */ + } + stt->Rxx160w32 = 125 * RXX_BUFFER_LEN; /* (stt->Rxx16_vectorw32[0]>>3) = 125 */ + + stt->Rxx16pos = 0; + stt->Rxx16_LPw32 = (WebRtc_Word32)16284; /* Q(-4) */ + + for (i = 0; i < 5; i++) + { + stt->Rxx16w32_array[0][i] = 0; + } + for (i = 0; i < 20; i++) + { + stt->env[0][i] = 0; + } + stt->inQueue = 0; + +#ifdef MIC_LEVEL_FEEDBACK + stt->targetIdxOffset = 0; +#endif + + WebRtcSpl_MemSetW32(stt->filterState, 0, 8); + + stt->initFlag = kInitCheck; + // Default config settings. + stt->defaultConfig.limiterEnable = kAgcTrue; + stt->defaultConfig.targetLevelDbfs = AGC_DEFAULT_TARGET_LEVEL; + stt->defaultConfig.compressionGaindB = AGC_DEFAULT_COMP_GAIN; + + if (WebRtcAgc_set_config(stt, stt->defaultConfig) == -1) + { + stt->lastError = AGC_UNSPECIFIED_ERROR; + return -1; + } + stt->Rxx160_LPw32 = stt->analogTargetLevel; // Initialize rms value + + stt->lowLevelSignal = 0; + + /* Only positive values are allowed that are not too large */ + if ((minLevel >= maxLevel) || (maxLevel & 0xFC000000)) + { +#ifdef AGC_DEBUG//test log + fprintf(stt->fpt, "minLevel, maxLevel value(s) are invalid\n\n"); +#endif + return -1; + } else + { +#ifdef AGC_DEBUG//test log + fprintf(stt->fpt, "\n"); +#endif + return 0; + } +} + +int WebRtcAgc_Version(WebRtc_Word8 *versionStr, WebRtc_Word16 length) +{ + const WebRtc_Word8 version[] = "AGC 1.7.0"; + const WebRtc_Word16 versionLen = (WebRtc_Word16)strlen(version) + 1; + + if (versionStr == NULL) + { + return -1; + } + + if (versionLen > length) + { + return -1; + } + + strncpy(versionStr, version, versionLen); + return 0; +} diff --git a/src/libs/webrtc/agc/analog_agc.h b/src/libs/webrtc/agc/analog_agc.h new file mode 100644 index 00000000..b32ac658 --- /dev/null +++ b/src/libs/webrtc/agc/analog_agc.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_ANALOG_AGC_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_ANALOG_AGC_H_ + +#include "typedefs.h" +#include "gain_control.h" +#include "digital_agc.h" + +//#define AGC_DEBUG +//#define MIC_LEVEL_FEEDBACK +#ifdef AGC_DEBUG +#include <stdio.h> +#endif + +/* Analog Automatic Gain Control variables: + * Constant declarations (inner limits inside which no changes are done) + * In the beginning the range is narrower to widen as soon as the measure + * 'Rxx160_LP' is inside it. Currently the starting limits are -22.2+/-1dBm0 + * and the final limits -22.2+/-2.5dBm0. These levels makes the speech signal + * go towards -25.4dBm0 (-31.4dBov). Tuned with wbfile-31.4dBov.pcm + * The limits are created by running the AGC with a file having the desired + * signal level and thereafter plotting Rxx160_LP in the dBm0-domain defined + * by out=10*log10(in/260537279.7); Set the target level to the average level + * of our measure Rxx160_LP. Remember that the levels are in blocks of 16 in + * Q(-7). (Example matlab code: round(db2pow(-21.2)*16/2^7) ) + */ +#define RXX_BUFFER_LEN 10 + +static const WebRtc_Word16 kMsecSpeechInner = 520; +static const WebRtc_Word16 kMsecSpeechOuter = 340; + +static const WebRtc_Word16 kNormalVadThreshold = 400; + +static const WebRtc_Word16 kAlphaShortTerm = 6; // 1 >> 6 = 0.0156 +static const WebRtc_Word16 kAlphaLongTerm = 10; // 1 >> 10 = 0.000977 + +typedef struct +{ + // Configurable parameters/variables + WebRtc_UWord32 fs; // Sampling frequency + WebRtc_Word16 compressionGaindB; // Fixed gain level in dB + WebRtc_Word16 targetLevelDbfs; // Target level in -dBfs of envelope (default -3) + WebRtc_Word16 agcMode; // Hard coded mode (adaptAna/adaptDig/fixedDig) + WebRtc_UWord8 limiterEnable; // Enabling limiter (on/off (default off)) + WebRtcAgc_config_t defaultConfig; + WebRtcAgc_config_t usedConfig; + + // General variables + WebRtc_Word16 initFlag; + WebRtc_Word16 lastError; + + // Target level parameters + // Based on the above: analogTargetLevel = round((32767*10^(-22/20))^2*16/2^7) + WebRtc_Word32 analogTargetLevel; // = RXX_BUFFER_LEN * 846805; -22 dBfs + WebRtc_Word32 startUpperLimit; // = RXX_BUFFER_LEN * 1066064; -21 dBfs + WebRtc_Word32 startLowerLimit; // = RXX_BUFFER_LEN * 672641; -23 dBfs + WebRtc_Word32 upperPrimaryLimit; // = RXX_BUFFER_LEN * 1342095; -20 dBfs + WebRtc_Word32 lowerPrimaryLimit; // = RXX_BUFFER_LEN * 534298; -24 dBfs + WebRtc_Word32 upperSecondaryLimit;// = RXX_BUFFER_LEN * 2677832; -17 dBfs + WebRtc_Word32 lowerSecondaryLimit;// = RXX_BUFFER_LEN * 267783; -27 dBfs + WebRtc_UWord16 targetIdx; // Table index for corresponding target level +#ifdef MIC_LEVEL_FEEDBACK + WebRtc_UWord16 targetIdxOffset; // Table index offset for level compensation +#endif + WebRtc_Word16 analogTarget; // Digital reference level in ENV scale + + // Analog AGC specific variables + WebRtc_Word32 filterState[8]; // For downsampling wb to nb + WebRtc_Word32 upperLimit; // Upper limit for mic energy + WebRtc_Word32 lowerLimit; // Lower limit for mic energy + WebRtc_Word32 Rxx160w32; // Average energy for one frame + WebRtc_Word32 Rxx16_LPw32; // Low pass filtered subframe energies + WebRtc_Word32 Rxx160_LPw32; // Low pass filtered frame energies + WebRtc_Word32 Rxx16_LPw32Max; // Keeps track of largest energy subframe + WebRtc_Word32 Rxx16_vectorw32[RXX_BUFFER_LEN];// Array with subframe energies + WebRtc_Word32 Rxx16w32_array[2][5];// Energy values of microphone signal + WebRtc_Word32 env[2][10]; // Envelope values of subframes + + WebRtc_Word16 Rxx16pos; // Current position in the Rxx16_vectorw32 + WebRtc_Word16 envSum; // Filtered scaled envelope in subframes + WebRtc_Word16 vadThreshold; // Threshold for VAD decision + WebRtc_Word16 inActive; // Inactive time in milliseconds + WebRtc_Word16 msTooLow; // Milliseconds of speech at a too low level + WebRtc_Word16 msTooHigh; // Milliseconds of speech at a too high level + WebRtc_Word16 changeToSlowMode; // Change to slow mode after some time at target + WebRtc_Word16 firstCall; // First call to the process-function + WebRtc_Word16 msZero; // Milliseconds of zero input + WebRtc_Word16 msecSpeechOuterChange;// Min ms of speech between volume changes + WebRtc_Word16 msecSpeechInnerChange;// Min ms of speech between volume changes + WebRtc_Word16 activeSpeech; // Milliseconds of active speech + WebRtc_Word16 muteGuardMs; // Counter to prevent mute action + WebRtc_Word16 inQueue; // 10 ms batch indicator + + // Microphone level variables + WebRtc_Word32 micRef; // Remember ref. mic level for virtual mic + WebRtc_UWord16 gainTableIdx; // Current position in virtual gain table + WebRtc_Word32 micGainIdx; // Gain index of mic level to increase slowly + WebRtc_Word32 micVol; // Remember volume between frames + WebRtc_Word32 maxLevel; // Max possible vol level, incl dig gain + WebRtc_Word32 maxAnalog; // Maximum possible analog volume level + WebRtc_Word32 maxInit; // Initial value of "max" + WebRtc_Word32 minLevel; // Minimum possible volume level + WebRtc_Word32 minOutput; // Minimum output volume level + WebRtc_Word32 zeroCtrlMax; // Remember max gain => don't amp low input + + WebRtc_Word16 scale; // Scale factor for internal volume levels +#ifdef MIC_LEVEL_FEEDBACK + WebRtc_Word16 numBlocksMicLvlSat; + WebRtc_UWord8 micLvlSat; +#endif + // Structs for VAD and digital_agc + AgcVad_t vadMic; + DigitalAgc_t digitalAgc; + +#ifdef AGC_DEBUG + FILE* fpt; + FILE* agcLog; + WebRtc_Word32 fcount; +#endif + + WebRtc_Word16 lowLevelSignal; +} Agc_t; + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_ANALOG_AGC_H_ diff --git a/src/libs/webrtc/agc/digital_agc.c b/src/libs/webrtc/agc/digital_agc.c new file mode 100644 index 00000000..2966586e --- /dev/null +++ b/src/libs/webrtc/agc/digital_agc.c @@ -0,0 +1,780 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* digital_agc.c + * + */ + +#include <string.h> +#ifdef AGC_DEBUG +#include <stdio.h> +#endif +#include "digital_agc.h" +#include "gain_control.h" + +// To generate the gaintable, copy&paste the following lines to a Matlab window: +// MaxGain = 6; MinGain = 0; CompRatio = 3; Knee = 1; +// zeros = 0:31; lvl = 2.^(1-zeros); +// A = -10*log10(lvl) * (CompRatio - 1) / CompRatio; +// B = MaxGain - MinGain; +// gains = round(2^16*10.^(0.05 * (MinGain + B * ( log(exp(-Knee*A)+exp(-Knee*B)) - log(1+exp(-Knee*B)) ) / log(1/(1+exp(Knee*B)))))); +// fprintf(1, '\t%i, %i, %i, %i,\n', gains); +// % Matlab code for plotting the gain and input/output level characteristic (copy/paste the following 3 lines): +// in = 10*log10(lvl); out = 20*log10(gains/65536); +// subplot(121); plot(in, out); axis([-30, 0, -5, 20]); grid on; xlabel('Input (dB)'); ylabel('Gain (dB)'); +// subplot(122); plot(in, in+out); axis([-30, 0, -30, 5]); grid on; xlabel('Input (dB)'); ylabel('Output (dB)'); +// zoom on; + +// Generator table for y=log2(1+e^x) in Q8. +static const WebRtc_UWord16 kGenFuncTable[128] = { + 256, 485, 786, 1126, 1484, 1849, 2217, 2586, + 2955, 3324, 3693, 4063, 4432, 4801, 5171, 5540, + 5909, 6279, 6648, 7017, 7387, 7756, 8125, 8495, + 8864, 9233, 9603, 9972, 10341, 10711, 11080, 11449, + 11819, 12188, 12557, 12927, 13296, 13665, 14035, 14404, + 14773, 15143, 15512, 15881, 16251, 16620, 16989, 17359, + 17728, 18097, 18466, 18836, 19205, 19574, 19944, 20313, + 20682, 21052, 21421, 21790, 22160, 22529, 22898, 23268, + 23637, 24006, 24376, 24745, 25114, 25484, 25853, 26222, + 26592, 26961, 27330, 27700, 28069, 28438, 28808, 29177, + 29546, 29916, 30285, 30654, 31024, 31393, 31762, 32132, + 32501, 32870, 33240, 33609, 33978, 34348, 34717, 35086, + 35456, 35825, 36194, 36564, 36933, 37302, 37672, 38041, + 38410, 38780, 39149, 39518, 39888, 40257, 40626, 40996, + 41365, 41734, 42104, 42473, 42842, 43212, 43581, 43950, + 44320, 44689, 45058, 45428, 45797, 46166, 46536, 46905 +}; + +static const WebRtc_Word16 kAvgDecayTime = 250; // frames; < 3000 + +WebRtc_Word32 WebRtcAgc_CalculateGainTable(WebRtc_Word32 *gainTable, // Q16 + WebRtc_Word16 digCompGaindB, // Q0 + WebRtc_Word16 targetLevelDbfs,// Q0 + WebRtc_UWord8 limiterEnable, + WebRtc_Word16 analogTarget) // Q0 +{ + // This function generates the compressor gain table used in the fixed digital part. + WebRtc_UWord32 tmpU32no1, tmpU32no2, absInLevel, logApprox; + WebRtc_Word32 inLevel, limiterLvl; + WebRtc_Word32 tmp32, tmp32no1, tmp32no2, numFIX, den, y32; + const WebRtc_UWord16 kLog10 = 54426; // log2(10) in Q14 + const WebRtc_UWord16 kLog10_2 = 49321; // 10*log10(2) in Q14 + const WebRtc_UWord16 kLogE_1 = 23637; // log2(e) in Q14 + WebRtc_UWord16 constMaxGain; + WebRtc_UWord16 tmpU16, intPart, fracPart; + const WebRtc_Word16 kCompRatio = 3; + const WebRtc_Word16 kSoftLimiterLeft = 1; + WebRtc_Word16 limiterOffset = 0; // Limiter offset + WebRtc_Word16 limiterIdx, limiterLvlX; + WebRtc_Word16 constLinApprox, zeroGainLvl, maxGain, diffGain; + WebRtc_Word16 i, tmp16, tmp16no1; + int zeros, zerosScale; + + // Constants +// kLogE_1 = 23637; // log2(e) in Q14 +// kLog10 = 54426; // log2(10) in Q14 +// kLog10_2 = 49321; // 10*log10(2) in Q14 + + // Calculate maximum digital gain and zero gain level + tmp32no1 = WEBRTC_SPL_MUL_16_16(digCompGaindB - analogTarget, kCompRatio - 1); + tmp16no1 = analogTarget - targetLevelDbfs; + tmp16no1 += WebRtcSpl_DivW32W16ResW16(tmp32no1 + (kCompRatio >> 1), kCompRatio); + maxGain = WEBRTC_SPL_MAX(tmp16no1, (analogTarget - targetLevelDbfs)); + tmp32no1 = WEBRTC_SPL_MUL_16_16(maxGain, kCompRatio); + zeroGainLvl = digCompGaindB; + zeroGainLvl -= WebRtcSpl_DivW32W16ResW16(tmp32no1 + ((kCompRatio - 1) >> 1), + kCompRatio - 1); + if ((digCompGaindB <= analogTarget) && (limiterEnable)) + { + zeroGainLvl += (analogTarget - digCompGaindB + kSoftLimiterLeft); + limiterOffset = 0; + } + + // Calculate the difference between maximum gain and gain at 0dB0v: + // diffGain = maxGain + (compRatio-1)*zeroGainLvl/compRatio + // = (compRatio-1)*digCompGaindB/compRatio + tmp32no1 = WEBRTC_SPL_MUL_16_16(digCompGaindB, kCompRatio - 1); + diffGain = WebRtcSpl_DivW32W16ResW16(tmp32no1 + (kCompRatio >> 1), kCompRatio); + if (diffGain < 0) + { + return -1; + } + + // Calculate the limiter level and index: + // limiterLvlX = analogTarget - limiterOffset + // limiterLvl = targetLevelDbfs + limiterOffset/compRatio + limiterLvlX = analogTarget - limiterOffset; + limiterIdx = 2 + + WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)limiterLvlX, 13), + WEBRTC_SPL_RSHIFT_U16(kLog10_2, 1)); + tmp16no1 = WebRtcSpl_DivW32W16ResW16(limiterOffset + (kCompRatio >> 1), kCompRatio); + limiterLvl = targetLevelDbfs + tmp16no1; + + // Calculate (through table lookup): + // constMaxGain = log2(1+2^(log2(e)*diffGain)); (in Q8) + constMaxGain = kGenFuncTable[diffGain]; // in Q8 + + // Calculate a parameter used to approximate the fractional part of 2^x with a + // piecewise linear function in Q14: + // constLinApprox = round(3/2*(4*(3-2*sqrt(2))/(log(2)^2)-0.5)*2^14); + constLinApprox = 22817; // in Q14 + + // Calculate a denominator used in the exponential part to convert from dB to linear scale: + // den = 20*constMaxGain (in Q8) + den = WEBRTC_SPL_MUL_16_U16(20, constMaxGain); // in Q8 + + for (i = 0; i < 32; i++) + { + // Calculate scaled input level (compressor): + // inLevel = fix((-constLog10_2*(compRatio-1)*(1-i)+fix(compRatio/2))/compRatio) + tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(kCompRatio - 1, i - 1); // Q0 + tmp32 = WEBRTC_SPL_MUL_16_U16(tmp16, kLog10_2) + 1; // Q14 + inLevel = WebRtcSpl_DivW32W16(tmp32, kCompRatio); // Q14 + + // Calculate diffGain-inLevel, to map using the genFuncTable + inLevel = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)diffGain, 14) - inLevel; // Q14 + + // Make calculations on abs(inLevel) and compensate for the sign afterwards. + absInLevel = (WebRtc_UWord32)WEBRTC_SPL_ABS_W32(inLevel); // Q14 + + // LUT with interpolation + intPart = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32(absInLevel, 14); + fracPart = (WebRtc_UWord16)(absInLevel & 0x00003FFF); // extract the fractional part + tmpU16 = kGenFuncTable[intPart + 1] - kGenFuncTable[intPart]; // Q8 + tmpU32no1 = WEBRTC_SPL_UMUL_16_16(tmpU16, fracPart); // Q22 + tmpU32no1 += WEBRTC_SPL_LSHIFT_U32((WebRtc_UWord32)kGenFuncTable[intPart], 14); // Q22 + logApprox = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 8); // Q14 + // Compensate for negative exponent using the relation: + // log2(1 + 2^-x) = log2(1 + 2^x) - x + if (inLevel < 0) + { + zeros = WebRtcSpl_NormU32(absInLevel); + zerosScale = 0; + if (zeros < 15) + { + // Not enough space for multiplication + tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(absInLevel, 15 - zeros); // Q(zeros-1) + tmpU32no2 = WEBRTC_SPL_UMUL_32_16(tmpU32no2, kLogE_1); // Q(zeros+13) + if (zeros < 9) + { + tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 9 - zeros); // Q(zeros+13) + zerosScale = 9 - zeros; + } else + { + tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(tmpU32no2, zeros - 9); // Q22 + } + } else + { + tmpU32no2 = WEBRTC_SPL_UMUL_32_16(absInLevel, kLogE_1); // Q28 + tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(tmpU32no2, 6); // Q22 + } + logApprox = 0; + if (tmpU32no2 < tmpU32no1) + { + logApprox = WEBRTC_SPL_RSHIFT_U32(tmpU32no1 - tmpU32no2, 8 - zerosScale); //Q14 + } + } + numFIX = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_U16(maxGain, constMaxGain), 6); // Q14 + numFIX -= WEBRTC_SPL_MUL_32_16((WebRtc_Word32)logApprox, diffGain); // Q14 + + // Calculate ratio + // Shift numFIX as much as possible + zeros = WebRtcSpl_NormW32(numFIX); + numFIX = WEBRTC_SPL_LSHIFT_W32(numFIX, zeros); // Q(14+zeros) + + // Shift den so we end up in Qy1 + tmp32no1 = WEBRTC_SPL_SHIFT_W32(den, zeros - 8); // Q(zeros) + if (numFIX < 0) + { + numFIX -= WEBRTC_SPL_RSHIFT_W32(tmp32no1, 1); + } else + { + numFIX += WEBRTC_SPL_RSHIFT_W32(tmp32no1, 1); + } + y32 = WEBRTC_SPL_DIV(numFIX, tmp32no1); // in Q14 + if (limiterEnable && (i < limiterIdx)) + { + tmp32 = WEBRTC_SPL_MUL_16_U16(i - 1, kLog10_2); // Q14 + tmp32 -= WEBRTC_SPL_LSHIFT_W32(limiterLvl, 14); // Q14 + y32 = WebRtcSpl_DivW32W16(tmp32 + 10, 20); + } + if (y32 > 39000) + { + tmp32 = WEBRTC_SPL_MUL(y32 >> 1, kLog10) + 4096; // in Q27 + tmp32 = WEBRTC_SPL_RSHIFT_W32(tmp32, 13); // in Q14 + } else + { + tmp32 = WEBRTC_SPL_MUL(y32, kLog10) + 8192; // in Q28 + tmp32 = WEBRTC_SPL_RSHIFT_W32(tmp32, 14); // in Q14 + } + tmp32 += WEBRTC_SPL_LSHIFT_W32(16, 14); // in Q14 (Make sure final output is in Q16) + + // Calculate power + if (tmp32 > 0) + { + intPart = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 14); + fracPart = (WebRtc_UWord16)(tmp32 & 0x00003FFF); // in Q14 + if (WEBRTC_SPL_RSHIFT_W32(fracPart, 13)) + { + tmp16 = WEBRTC_SPL_LSHIFT_W16(2, 14) - constLinApprox; + tmp32no2 = WEBRTC_SPL_LSHIFT_W32(1, 14) - fracPart; + tmp32no2 = WEBRTC_SPL_MUL_32_16(tmp32no2, tmp16); + tmp32no2 = WEBRTC_SPL_RSHIFT_W32(tmp32no2, 13); + tmp32no2 = WEBRTC_SPL_LSHIFT_W32(1, 14) - tmp32no2; + } else + { + tmp16 = constLinApprox - WEBRTC_SPL_LSHIFT_W16(1, 14); + tmp32no2 = WEBRTC_SPL_MUL_32_16(fracPart, tmp16); + tmp32no2 = WEBRTC_SPL_RSHIFT_W32(tmp32no2, 13); + } + fracPart = (WebRtc_UWord16)tmp32no2; + gainTable[i] = WEBRTC_SPL_LSHIFT_W32(1, intPart) + + WEBRTC_SPL_SHIFT_W32(fracPart, intPart - 14); + } else + { + gainTable[i] = 0; + } + } + + return 0; +} + +WebRtc_Word32 WebRtcAgc_InitDigital(DigitalAgc_t *stt, WebRtc_Word16 agcMode) +{ + + if (agcMode == kAgcModeFixedDigital) + { + // start at minimum to find correct gain faster + stt->capacitorSlow = 0; + } else + { + // start out with 0 dB gain + stt->capacitorSlow = 134217728; // (WebRtc_Word32)(0.125f * 32768.0f * 32768.0f); + } + stt->capacitorFast = 0; + stt->gain = 65536; + stt->gatePrevious = 0; + stt->agcMode = agcMode; +#ifdef AGC_DEBUG + stt->frameCounter = 0; +#endif + + // initialize VADs + WebRtcAgc_InitVad(&stt->vadNearend); + WebRtcAgc_InitVad(&stt->vadFarend); + + return 0; +} + +WebRtc_Word32 WebRtcAgc_AddFarendToDigital(DigitalAgc_t *stt, const WebRtc_Word16 *in_far, + WebRtc_Word16 nrSamples) +{ + // Check for valid pointer + if (&stt->vadFarend == NULL) + { + return -1; + } + + // VAD for far end + WebRtcAgc_ProcessVad(&stt->vadFarend, in_far, nrSamples); + + return 0; +} + +WebRtc_Word32 WebRtcAgc_ProcessDigital(DigitalAgc_t *stt, const WebRtc_Word16 *in_near, + const WebRtc_Word16 *in_near_H, WebRtc_Word16 *out, + WebRtc_Word16 *out_H, WebRtc_UWord32 FS, + WebRtc_Word16 lowlevelSignal) +{ + // array for gains (one value per ms, incl start & end) + WebRtc_Word32 gains[11]; + + WebRtc_Word32 out_tmp, tmp32; + WebRtc_Word32 env[10]; + WebRtc_Word32 nrg, max_nrg; + WebRtc_Word32 cur_level; + WebRtc_Word32 gain32, delta; + WebRtc_Word16 logratio; + WebRtc_Word16 lower_thr, upper_thr; + WebRtc_Word16 zeros, zeros_fast, frac; + WebRtc_Word16 decay; + WebRtc_Word16 gate, gain_adj; + WebRtc_Word16 k, n; + WebRtc_Word16 L, L2; // samples/subframe + + // determine number of samples per ms + if (FS == 8000) + { + L = 8; + L2 = 3; + } else if (FS == 16000) + { + L = 16; + L2 = 4; + } else if (FS == 32000) + { + L = 16; + L2 = 4; + } else + { + return -1; + } + + memcpy(out, in_near, 10 * L * sizeof(WebRtc_Word16)); + if (FS == 32000) + { + memcpy(out_H, in_near_H, 10 * L * sizeof(WebRtc_Word16)); + } + // VAD for near end + logratio = WebRtcAgc_ProcessVad(&stt->vadNearend, out, L * 10); + + // Account for far end VAD + if (stt->vadFarend.counter > 10) + { + tmp32 = WEBRTC_SPL_MUL_16_16(3, logratio); + logratio = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32 - stt->vadFarend.logRatio, 2); + } + + // Determine decay factor depending on VAD + // upper_thr = 1.0f; + // lower_thr = 0.25f; + upper_thr = 1024; // Q10 + lower_thr = 0; // Q10 + if (logratio > upper_thr) + { + // decay = -2^17 / DecayTime; -> -65 + decay = -65; + } else if (logratio < lower_thr) + { + decay = 0; + } else + { + // decay = (WebRtc_Word16)(((lower_thr - logratio) + // * (2^27/(DecayTime*(upper_thr-lower_thr)))) >> 10); + // SUBSTITUTED: 2^27/(DecayTime*(upper_thr-lower_thr)) -> 65 + tmp32 = WEBRTC_SPL_MUL_16_16((lower_thr - logratio), 65); + decay = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 10); + } + + // adjust decay factor for long silence (detected as low standard deviation) + // This is only done in the adaptive modes + if (stt->agcMode != kAgcModeFixedDigital) + { + if (stt->vadNearend.stdLongTerm < 4000) + { + decay = 0; + } else if (stt->vadNearend.stdLongTerm < 8096) + { + // decay = (WebRtc_Word16)(((stt->vadNearend.stdLongTerm - 4000) * decay) >> 12); + tmp32 = WEBRTC_SPL_MUL_16_16((stt->vadNearend.stdLongTerm - 4000), decay); + decay = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 12); + } + + if (lowlevelSignal != 0) + { + decay = 0; + } + } +#ifdef AGC_DEBUG + stt->frameCounter++; + fprintf(stt->logFile, "%5.2f\t%d\t%d\t%d\t", (float)(stt->frameCounter) / 100, logratio, decay, stt->vadNearend.stdLongTerm); +#endif + // Find max amplitude per sub frame + // iterate over sub frames + for (k = 0; k < 10; k++) + { + // iterate over samples + max_nrg = 0; + for (n = 0; n < L; n++) + { + nrg = WEBRTC_SPL_MUL_16_16(out[k * L + n], out[k * L + n]); + if (nrg > max_nrg) + { + max_nrg = nrg; + } + } + env[k] = max_nrg; + } + + // Calculate gain per sub frame + gains[0] = stt->gain; + for (k = 0; k < 10; k++) + { + // Fast envelope follower + // decay time = -131000 / -1000 = 131 (ms) + stt->capacitorFast = AGC_SCALEDIFF32(-1000, stt->capacitorFast, stt->capacitorFast); + if (env[k] > stt->capacitorFast) + { + stt->capacitorFast = env[k]; + } + // Slow envelope follower + if (env[k] > stt->capacitorSlow) + { + // increase capacitorSlow + stt->capacitorSlow + = AGC_SCALEDIFF32(500, (env[k] - stt->capacitorSlow), stt->capacitorSlow); + } else + { + // decrease capacitorSlow + stt->capacitorSlow + = AGC_SCALEDIFF32(decay, stt->capacitorSlow, stt->capacitorSlow); + } + + // use maximum of both capacitors as current level + if (stt->capacitorFast > stt->capacitorSlow) + { + cur_level = stt->capacitorFast; + } else + { + cur_level = stt->capacitorSlow; + } + // Translate signal level into gain, using a piecewise linear approximation + // find number of leading zeros + zeros = WebRtcSpl_NormU32((WebRtc_UWord32)cur_level); + if (cur_level == 0) + { + zeros = 31; + } + tmp32 = (WEBRTC_SPL_LSHIFT_W32(cur_level, zeros) & 0x7FFFFFFF); + frac = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 19); // Q12 + tmp32 = WEBRTC_SPL_MUL((stt->gainTable[zeros-1] - stt->gainTable[zeros]), frac); + gains[k + 1] = stt->gainTable[zeros] + WEBRTC_SPL_RSHIFT_W32(tmp32, 12); +#ifdef AGC_DEBUG + if (k == 0) + { + fprintf(stt->logFile, "%d\t%d\t%d\t%d\t%d\n", env[0], cur_level, stt->capacitorFast, stt->capacitorSlow, zeros); + } +#endif + } + + // Gate processing (lower gain during absence of speech) + zeros = WEBRTC_SPL_LSHIFT_W16(zeros, 9) - WEBRTC_SPL_RSHIFT_W16(frac, 3); + // find number of leading zeros + zeros_fast = WebRtcSpl_NormU32((WebRtc_UWord32)stt->capacitorFast); + if (stt->capacitorFast == 0) + { + zeros_fast = 31; + } + tmp32 = (WEBRTC_SPL_LSHIFT_W32(stt->capacitorFast, zeros_fast) & 0x7FFFFFFF); + zeros_fast = WEBRTC_SPL_LSHIFT_W16(zeros_fast, 9); + zeros_fast -= (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 22); + + gate = 1000 + zeros_fast - zeros - stt->vadNearend.stdShortTerm; + + if (gate < 0) + { + stt->gatePrevious = 0; + } else + { + tmp32 = WEBRTC_SPL_MUL_16_16(stt->gatePrevious, 7); + gate = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)gate + tmp32, 3); + stt->gatePrevious = gate; + } + // gate < 0 -> no gate + // gate > 2500 -> max gate + if (gate > 0) + { + if (gate < 2500) + { + gain_adj = WEBRTC_SPL_RSHIFT_W16(2500 - gate, 5); + } else + { + gain_adj = 0; + } + for (k = 0; k < 10; k++) + { + if ((gains[k + 1] - stt->gainTable[0]) > 8388608) + { + // To prevent wraparound + tmp32 = WEBRTC_SPL_RSHIFT_W32((gains[k+1] - stt->gainTable[0]), 8); + tmp32 = WEBRTC_SPL_MUL(tmp32, (178 + gain_adj)); + } else + { + tmp32 = WEBRTC_SPL_MUL((gains[k+1] - stt->gainTable[0]), (178 + gain_adj)); + tmp32 = WEBRTC_SPL_RSHIFT_W32(tmp32, 8); + } + gains[k + 1] = stt->gainTable[0] + tmp32; + } + } + + // Limit gain to avoid overload distortion + for (k = 0; k < 10; k++) + { + // To prevent wrap around + zeros = 10; + if (gains[k + 1] > 47453132) + { + zeros = 16 - WebRtcSpl_NormW32(gains[k + 1]); + } + gain32 = WEBRTC_SPL_RSHIFT_W32(gains[k+1], zeros) + 1; + gain32 = WEBRTC_SPL_MUL(gain32, gain32); + // check for overflow + while (AGC_MUL32(WEBRTC_SPL_RSHIFT_W32(env[k], 12) + 1, gain32) + > WEBRTC_SPL_SHIFT_W32((WebRtc_Word32)32767, 2 * (1 - zeros + 10))) + { + // multiply by 253/256 ==> -0.1 dB + if (gains[k + 1] > 8388607) + { + // Prevent wrap around + gains[k + 1] = WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(gains[k+1], 8), 253); + } else + { + gains[k + 1] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(gains[k+1], 253), 8); + } + gain32 = WEBRTC_SPL_RSHIFT_W32(gains[k+1], zeros) + 1; + gain32 = WEBRTC_SPL_MUL(gain32, gain32); + } + } + // gain reductions should be done 1 ms earlier than gain increases + for (k = 1; k < 10; k++) + { + if (gains[k] > gains[k + 1]) + { + gains[k] = gains[k + 1]; + } + } + // save start gain for next frame + stt->gain = gains[10]; + + // Apply gain + // handle first sub frame separately + delta = WEBRTC_SPL_LSHIFT_W32(gains[1] - gains[0], (4 - L2)); + gain32 = WEBRTC_SPL_LSHIFT_W32(gains[0], 4); + // iterate over samples + for (n = 0; n < L; n++) + { + // For lower band + tmp32 = WEBRTC_SPL_MUL((WebRtc_Word32)out[n], WEBRTC_SPL_RSHIFT_W32(gain32 + 127, 7)); + out_tmp = WEBRTC_SPL_RSHIFT_W32(tmp32 , 16); + if (out_tmp > 4095) + { + out[n] = (WebRtc_Word16)32767; + } else if (out_tmp < -4096) + { + out[n] = (WebRtc_Word16)-32768; + } else + { + tmp32 = WEBRTC_SPL_MUL((WebRtc_Word32)out[n], WEBRTC_SPL_RSHIFT_W32(gain32, 4)); + out[n] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32 , 16); + } + // For higher band + if (FS == 32000) + { + tmp32 = WEBRTC_SPL_MUL((WebRtc_Word32)out_H[n], + WEBRTC_SPL_RSHIFT_W32(gain32 + 127, 7)); + out_tmp = WEBRTC_SPL_RSHIFT_W32(tmp32 , 16); + if (out_tmp > 4095) + { + out_H[n] = (WebRtc_Word16)32767; + } else if (out_tmp < -4096) + { + out_H[n] = (WebRtc_Word16)-32768; + } else + { + tmp32 = WEBRTC_SPL_MUL((WebRtc_Word32)out_H[n], + WEBRTC_SPL_RSHIFT_W32(gain32, 4)); + out_H[n] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32 , 16); + } + } + // + + gain32 += delta; + } + // iterate over subframes + for (k = 1; k < 10; k++) + { + delta = WEBRTC_SPL_LSHIFT_W32(gains[k+1] - gains[k], (4 - L2)); + gain32 = WEBRTC_SPL_LSHIFT_W32(gains[k], 4); + // iterate over samples + for (n = 0; n < L; n++) + { + // For lower band + tmp32 = WEBRTC_SPL_MUL((WebRtc_Word32)out[k * L + n], + WEBRTC_SPL_RSHIFT_W32(gain32, 4)); + out[k * L + n] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32 , 16); + // For higher band + if (FS == 32000) + { + tmp32 = WEBRTC_SPL_MUL((WebRtc_Word32)out_H[k * L + n], + WEBRTC_SPL_RSHIFT_W32(gain32, 4)); + out_H[k * L + n] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32 , 16); + } + gain32 += delta; + } + } + + return 0; +} + +void WebRtcAgc_InitVad(AgcVad_t *state) +{ + WebRtc_Word16 k; + + state->HPstate = 0; // state of high pass filter + state->logRatio = 0; // log( P(active) / P(inactive) ) + // average input level (Q10) + state->meanLongTerm = WEBRTC_SPL_LSHIFT_W16(15, 10); + + // variance of input level (Q8) + state->varianceLongTerm = WEBRTC_SPL_LSHIFT_W32(500, 8); + + state->stdLongTerm = 0; // standard deviation of input level in dB + // short-term average input level (Q10) + state->meanShortTerm = WEBRTC_SPL_LSHIFT_W16(15, 10); + + // short-term variance of input level (Q8) + state->varianceShortTerm = WEBRTC_SPL_LSHIFT_W32(500, 8); + + state->stdShortTerm = 0; // short-term standard deviation of input level in dB + state->counter = 3; // counts updates + for (k = 0; k < 8; k++) + { + // downsampling filter + state->downState[k] = 0; + } +} + +WebRtc_Word16 WebRtcAgc_ProcessVad(AgcVad_t *state, // (i) VAD state + const WebRtc_Word16 *in, // (i) Speech signal + WebRtc_Word16 nrSamples) // (i) number of samples +{ + WebRtc_Word32 out, nrg, tmp32, tmp32b; + WebRtc_UWord16 tmpU16; + WebRtc_Word16 k, subfr, tmp16; + WebRtc_Word16 buf1[8]; + WebRtc_Word16 buf2[4]; + WebRtc_Word16 HPstate; + WebRtc_Word16 zeros, dB; + WebRtc_Word16 *buf1_ptr; + + // process in 10 sub frames of 1 ms (to save on memory) + nrg = 0; + buf1_ptr = &buf1[0]; + HPstate = state->HPstate; + for (subfr = 0; subfr < 10; subfr++) + { + // downsample to 4 kHz + if (nrSamples == 160) + { + for (k = 0; k < 8; k++) + { + tmp32 = (WebRtc_Word32)in[2 * k] + (WebRtc_Word32)in[2 * k + 1]; + tmp32 = WEBRTC_SPL_RSHIFT_W32(tmp32, 1); + buf1[k] = (WebRtc_Word16)tmp32; + } + in += 16; + + WebRtcSpl_DownsampleBy2(buf1, 8, buf2, state->downState); + } else + { + WebRtcSpl_DownsampleBy2(in, 8, buf2, state->downState); + in += 8; + } + + // high pass filter and compute energy + for (k = 0; k < 4; k++) + { + out = buf2[k] + HPstate; + tmp32 = WEBRTC_SPL_MUL(600, out); + HPstate = (WebRtc_Word16)(WEBRTC_SPL_RSHIFT_W32(tmp32, 10) - buf2[k]); + tmp32 = WEBRTC_SPL_MUL(out, out); + nrg += WEBRTC_SPL_RSHIFT_W32(tmp32, 6); + } + } + state->HPstate = HPstate; + + // find number of leading zeros + if (!(0xFFFF0000 & nrg)) + { + zeros = 16; + } else + { + zeros = 0; + } + if (!(0xFF000000 & (nrg << zeros))) + { + zeros += 8; + } + if (!(0xF0000000 & (nrg << zeros))) + { + zeros += 4; + } + if (!(0xC0000000 & (nrg << zeros))) + { + zeros += 2; + } + if (!(0x80000000 & (nrg << zeros))) + { + zeros += 1; + } + + // energy level (range {-32..30}) (Q10) + dB = WEBRTC_SPL_LSHIFT_W16(15 - zeros, 11); + + // Update statistics + + if (state->counter < kAvgDecayTime) + { + // decay time = AvgDecTime * 10 ms + state->counter++; + } + + // update short-term estimate of mean energy level (Q10) + tmp32 = (WEBRTC_SPL_MUL_16_16(state->meanShortTerm, 15) + (WebRtc_Word32)dB); + state->meanShortTerm = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 4); + + // update short-term estimate of variance in energy level (Q8) + tmp32 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(dB, dB), 12); + tmp32 += WEBRTC_SPL_MUL(state->varianceShortTerm, 15); + state->varianceShortTerm = WEBRTC_SPL_RSHIFT_W32(tmp32, 4); + + // update short-term estimate of standard deviation in energy level (Q10) + tmp32 = WEBRTC_SPL_MUL_16_16(state->meanShortTerm, state->meanShortTerm); + tmp32 = WEBRTC_SPL_LSHIFT_W32(state->varianceShortTerm, 12) - tmp32; + state->stdShortTerm = (WebRtc_Word16)WebRtcSpl_Sqrt(tmp32); + + // update long-term estimate of mean energy level (Q10) + tmp32 = WEBRTC_SPL_MUL_16_16(state->meanLongTerm, state->counter) + (WebRtc_Word32)dB; + state->meanLongTerm = WebRtcSpl_DivW32W16ResW16(tmp32, + WEBRTC_SPL_ADD_SAT_W16(state->counter, 1)); + + // update long-term estimate of variance in energy level (Q8) + tmp32 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(dB, dB), 12); + tmp32 += WEBRTC_SPL_MUL(state->varianceLongTerm, state->counter); + state->varianceLongTerm = WebRtcSpl_DivW32W16(tmp32, + WEBRTC_SPL_ADD_SAT_W16(state->counter, 1)); + + // update long-term estimate of standard deviation in energy level (Q10) + tmp32 = WEBRTC_SPL_MUL_16_16(state->meanLongTerm, state->meanLongTerm); + tmp32 = WEBRTC_SPL_LSHIFT_W32(state->varianceLongTerm, 12) - tmp32; + state->stdLongTerm = (WebRtc_Word16)WebRtcSpl_Sqrt(tmp32); + + // update voice activity measure (Q10) + tmp16 = WEBRTC_SPL_LSHIFT_W16(3, 12); + tmp32 = WEBRTC_SPL_MUL_16_16(tmp16, (dB - state->meanLongTerm)); + tmp32 = WebRtcSpl_DivW32W16(tmp32, state->stdLongTerm); + tmpU16 = WEBRTC_SPL_LSHIFT_U16((WebRtc_UWord16)13, 12); + tmp32b = WEBRTC_SPL_MUL_16_U16(state->logRatio, tmpU16); + tmp32 += WEBRTC_SPL_RSHIFT_W32(tmp32b, 10); + + state->logRatio = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 6); + + // limit + if (state->logRatio > 2048) + { + state->logRatio = 2048; + } + if (state->logRatio < -2048) + { + state->logRatio = -2048; + } + + return state->logRatio; // Q10 +} diff --git a/src/libs/webrtc/agc/digital_agc.h b/src/libs/webrtc/agc/digital_agc.h new file mode 100644 index 00000000..240b2206 --- /dev/null +++ b/src/libs/webrtc/agc/digital_agc.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_DIGITAL_AGC_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_DIGITAL_AGC_H_ + +#ifdef AGC_DEBUG +#include <stdio.h> +#endif +#include "typedefs.h" +#include "signal_processing_library.h" + +// the 32 most significant bits of A(19) * B(26) >> 13 +#define AGC_MUL32(A, B) (((B)>>13)*(A) + ( ((0x00001FFF & (B))*(A)) >> 13 )) +// C + the 32 most significant bits of A * B +#define AGC_SCALEDIFF32(A, B, C) ((C) + ((B)>>16)*(A) + ( ((0x0000FFFF & (B))*(A)) >> 16 )) + +typedef struct +{ + WebRtc_Word32 downState[8]; + WebRtc_Word16 HPstate; + WebRtc_Word16 counter; + WebRtc_Word16 logRatio; // log( P(active) / P(inactive) ) (Q10) + WebRtc_Word16 meanLongTerm; // Q10 + WebRtc_Word32 varianceLongTerm; // Q8 + WebRtc_Word16 stdLongTerm; // Q10 + WebRtc_Word16 meanShortTerm; // Q10 + WebRtc_Word32 varianceShortTerm; // Q8 + WebRtc_Word16 stdShortTerm; // Q10 +} AgcVad_t; // total = 54 bytes + +typedef struct +{ + WebRtc_Word32 capacitorSlow; + WebRtc_Word32 capacitorFast; + WebRtc_Word32 gain; + WebRtc_Word32 gainTable[32]; + WebRtc_Word16 gatePrevious; + WebRtc_Word16 agcMode; + AgcVad_t vadNearend; + AgcVad_t vadFarend; +#ifdef AGC_DEBUG + FILE* logFile; + int frameCounter; +#endif +} DigitalAgc_t; + +WebRtc_Word32 WebRtcAgc_InitDigital(DigitalAgc_t *digitalAgcInst, WebRtc_Word16 agcMode); + +WebRtc_Word32 WebRtcAgc_ProcessDigital(DigitalAgc_t *digitalAgcInst, const WebRtc_Word16 *inNear, + const WebRtc_Word16 *inNear_H, WebRtc_Word16 *out, + WebRtc_Word16 *out_H, WebRtc_UWord32 FS, + WebRtc_Word16 lowLevelSignal); + +WebRtc_Word32 WebRtcAgc_AddFarendToDigital(DigitalAgc_t *digitalAgcInst, const WebRtc_Word16 *inFar, + WebRtc_Word16 nrSamples); + +void WebRtcAgc_InitVad(AgcVad_t *vadInst); + +WebRtc_Word16 WebRtcAgc_ProcessVad(AgcVad_t *vadInst, // (i) VAD state + const WebRtc_Word16 *in, // (i) Speech signal + WebRtc_Word16 nrSamples); // (i) number of samples + +WebRtc_Word32 WebRtcAgc_CalculateGainTable(WebRtc_Word32 *gainTable, // Q16 + WebRtc_Word16 compressionGaindB, // Q0 (in dB) + WebRtc_Word16 targetLevelDbfs,// Q0 (in dB) + WebRtc_UWord8 limiterEnable, WebRtc_Word16 analogTarget); + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_ANALOG_AGC_H_ diff --git a/src/libs/webrtc/agc/gain_control.h b/src/libs/webrtc/agc/gain_control.h new file mode 100644 index 00000000..2893331f --- /dev/null +++ b/src/libs/webrtc/agc/gain_control.h @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_INTERFACE_GAIN_CONTROL_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_INTERFACE_GAIN_CONTROL_H_ + +#include "typedefs.h" + +// Errors +#define AGC_UNSPECIFIED_ERROR 18000 +#define AGC_UNSUPPORTED_FUNCTION_ERROR 18001 +#define AGC_UNINITIALIZED_ERROR 18002 +#define AGC_NULL_POINTER_ERROR 18003 +#define AGC_BAD_PARAMETER_ERROR 18004 + +// Warnings +#define AGC_BAD_PARAMETER_WARNING 18050 + +enum +{ + kAgcModeUnchanged, + kAgcModeAdaptiveAnalog, + kAgcModeAdaptiveDigital, + kAgcModeFixedDigital +}; + +enum +{ + kAgcFalse = 0, + kAgcTrue +}; + +typedef struct +{ + WebRtc_Word16 targetLevelDbfs; // default 3 (-3 dBOv) + WebRtc_Word16 compressionGaindB; // default 9 dB + WebRtc_UWord8 limiterEnable; // default kAgcTrue (on) +} WebRtcAgc_config_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* + * This function processes a 10/20ms frame of far-end speech to determine + * if there is active speech. Far-end speech length can be either 10ms or + * 20ms. The length of the input speech vector must be given in samples + * (80/160 when FS=8000, and 160/320 when FS=16000 or FS=32000). + * + * Input: + * - agcInst : AGC instance. + * - inFar : Far-end input speech vector (10 or 20ms) + * - samples : Number of samples in input vector + * + * Return value: + * : 0 - Normal operation. + * : -1 - Error + */ +int WebRtcAgc_AddFarend(void* agcInst, + const WebRtc_Word16* inFar, + WebRtc_Word16 samples); + +/* + * This function processes a 10/20ms frame of microphone speech to determine + * if there is active speech. Microphone speech length can be either 10ms or + * 20ms. The length of the input speech vector must be given in samples + * (80/160 when FS=8000, and 160/320 when FS=16000 or FS=32000). For very low + * input levels, the input signal is increased in level by multiplying and + * overwriting the samples in inMic[]. + * + * This function should be called before any further processing of the + * near-end microphone signal. + * + * Input: + * - agcInst : AGC instance. + * - inMic : Microphone input speech vector (10 or 20 ms) for + * L band + * - inMic_H : Microphone input speech vector (10 or 20 ms) for + * H band + * - samples : Number of samples in input vector + * + * Return value: + * : 0 - Normal operation. + * : -1 - Error + */ +int WebRtcAgc_AddMic(void* agcInst, + WebRtc_Word16* inMic, + WebRtc_Word16* inMic_H, + WebRtc_Word16 samples); + +/* + * This function replaces the analog microphone with a virtual one. + * It is a digital gain applied to the input signal and is used in the + * agcAdaptiveDigital mode where no microphone level is adjustable. + * Microphone speech length can be either 10ms or 20ms. The length of the + * input speech vector must be given in samples (80/160 when FS=8000, and + * 160/320 when FS=16000 or FS=32000). + * + * Input: + * - agcInst : AGC instance. + * - inMic : Microphone input speech vector for (10 or 20 ms) + * L band + * - inMic_H : Microphone input speech vector for (10 or 20 ms) + * H band + * - samples : Number of samples in input vector + * - micLevelIn : Input level of microphone (static) + * + * Output: + * - inMic : Microphone output after processing (L band) + * - inMic_H : Microphone output after processing (H band) + * - micLevelOut : Adjusted microphone level after processing + * + * Return value: + * : 0 - Normal operation. + * : -1 - Error + */ +int WebRtcAgc_VirtualMic(void* agcInst, + WebRtc_Word16* inMic, + WebRtc_Word16* inMic_H, + WebRtc_Word16 samples, + WebRtc_Word32 micLevelIn, + WebRtc_Word32* micLevelOut); + +/* + * This function processes a 10/20ms frame and adjusts (normalizes) the gain + * both analog and digitally. The gain adjustments are done only during + * active periods of speech. The input speech length can be either 10ms or + * 20ms and the output is of the same length. The length of the speech + * vectors must be given in samples (80/160 when FS=8000, and 160/320 when + * FS=16000 or FS=32000). The echo parameter can be used to ensure the AGC will + * not adjust upward in the presence of echo. + * + * This function should be called after processing the near-end microphone + * signal, in any case after any echo cancellation. + * + * Input: + * - agcInst : AGC instance + * - inNear : Near-end input speech vector (10 or 20 ms) for + * L band + * - inNear_H : Near-end input speech vector (10 or 20 ms) for + * H band + * - samples : Number of samples in input/output vector + * - inMicLevel : Current microphone volume level + * - echo : Set to 0 if the signal passed to add_mic is + * almost certainly free of echo; otherwise set + * to 1. If you have no information regarding echo + * set to 0. + * + * Output: + * - outMicLevel : Adjusted microphone volume level + * - out : Gain-adjusted near-end speech vector (L band) + * : May be the same vector as the input. + * - out_H : Gain-adjusted near-end speech vector (H band) + * - saturationWarning : A returned value of 1 indicates a saturation event + * has occurred and the volume cannot be further + * reduced. Otherwise will be set to 0. + * + * Return value: + * : 0 - Normal operation. + * : -1 - Error + */ +int WebRtcAgc_Process(void* agcInst, + const WebRtc_Word16* inNear, + const WebRtc_Word16* inNear_H, + WebRtc_Word16 samples, + WebRtc_Word16* out, + WebRtc_Word16* out_H, + WebRtc_Word32 inMicLevel, + WebRtc_Word32* outMicLevel, + WebRtc_Word16 echo, + WebRtc_UWord8* saturationWarning); + +/* + * This function sets the config parameters (targetLevelDbfs, + * compressionGaindB and limiterEnable). + * + * Input: + * - agcInst : AGC instance + * - config : config struct + * + * Output: + * + * Return value: + * : 0 - Normal operation. + * : -1 - Error + */ +int WebRtcAgc_set_config(void* agcInst, WebRtcAgc_config_t config); + +/* + * This function returns the config parameters (targetLevelDbfs, + * compressionGaindB and limiterEnable). + * + * Input: + * - agcInst : AGC instance + * + * Output: + * - config : config struct + * + * Return value: + * : 0 - Normal operation. + * : -1 - Error + */ +int WebRtcAgc_get_config(void* agcInst, WebRtcAgc_config_t* config); + +/* + * This function creates an AGC instance, which will contain the state + * information for one (duplex) channel. + * + * Return value : AGC instance if successful + * : 0 (i.e., a NULL pointer) if unsuccessful + */ +int WebRtcAgc_Create(void **agcInst); + +/* + * This function frees the AGC instance created at the beginning. + * + * Input: + * - agcInst : AGC instance. + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcAgc_Free(void *agcInst); + +/* + * This function initializes an AGC instance. + * + * Input: + * - agcInst : AGC instance. + * - minLevel : Minimum possible mic level + * - maxLevel : Maximum possible mic level + * - agcMode : 0 - Unchanged + * : 1 - Adaptive Analog Automatic Gain Control -3dBOv + * : 2 - Adaptive Digital Automatic Gain Control -3dBOv + * : 3 - Fixed Digital Gain 0dB + * - fs : Sampling frequency + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcAgc_Init(void *agcInst, + WebRtc_Word32 minLevel, + WebRtc_Word32 maxLevel, + WebRtc_Word16 agcMode, + WebRtc_UWord32 fs); + +/* + * This function returns a text string containing the version. + * + * Input: + * - length : Length of the char array pointed to by version + * Output: + * - version : Pointer to a char array of to which the version + * : string will be copied. + * + * Return value : 0 - OK + * -1 - Error + */ +int WebRtcAgc_Version(WebRtc_Word8 *versionStr, WebRtc_Word16 length); + +#if defined(__cplusplus) +} +#endif + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_INTERFACE_GAIN_CONTROL_H_ diff --git a/src/libs/webrtc/cng/cng_helpfuns.c b/src/libs/webrtc/cng/cng_helpfuns.c new file mode 100644 index 00000000..2e9029f0 --- /dev/null +++ b/src/libs/webrtc/cng/cng_helpfuns.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +#include "webrtc_cng.h" +#include "signal_processing_library.h" +#include "typedefs.h" +#include "cng_helpfuns.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +void WebRtcCng_K2a16( + WebRtc_Word16 *k, /* Q15. */ + int useOrder, + WebRtc_Word16 *a /* Q12. */ +) +{ + WebRtc_Word16 any[WEBRTC_SPL_MAX_LPC_ORDER+1]; + WebRtc_Word16 *aptr, *aptr2, *anyptr; + G_CONST WebRtc_Word16 *kptr; + int m, i; + + kptr = k; + *a = 4096; /* i.e., (Word16_MAX >> 3)+1 */ + *any = *a; + a[1] = (*k+4) >> 3; + for( m=1; m<useOrder; m++ ) + { + kptr++; + aptr = a; + aptr++; + aptr2 = &a[m]; + anyptr = any; + anyptr++; + + any[m+1] = (*kptr+4) >> 3; + for( i=0; i<m; i++ ) { + *anyptr++ = (*aptr++) + (WebRtc_Word16)( (( (WebRtc_Word32)(*aptr2--) * (WebRtc_Word32)*kptr )+16384) >> 15); + } + + aptr = a; + anyptr = any; + for( i=0; i<(m+2); i++ ){ + *aptr++ = *anyptr++; + } + } +} + + +#ifdef __cplusplus +} +#endif + diff --git a/src/libs/webrtc/cng/cng_helpfuns.h b/src/libs/webrtc/cng/cng_helpfuns.h new file mode 100644 index 00000000..fd8d6dcb --- /dev/null +++ b/src/libs/webrtc/cng/cng_helpfuns.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_MAIN_SOURCE_CNG_HELPFUNS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_MAIN_SOURCE_CNG_HELPFUNS_H_ + +extern WebRtc_Word32 lpc_lagwinTbl_fixw32[WEBRTC_CNG_MAX_LPC_ORDER + 1]; + +#ifdef __cplusplus +extern "C" { +#endif + + +void WebRtcCng_K2a16(WebRtc_Word16 *k, int useOrder, WebRtc_Word16 *a); + +#ifdef __cplusplus +} +#endif + +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_MAIN_SOURCE_CNG_HELPFUNS_H_ diff --git a/src/libs/webrtc/cng/webrtc_cng.c b/src/libs/webrtc/cng/webrtc_cng.c new file mode 100644 index 00000000..41893e6d --- /dev/null +++ b/src/libs/webrtc/cng/webrtc_cng.c @@ -0,0 +1,735 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +#include <string.h> +#include <stdlib.h> + +#include "webrtc_cng.h" +#include "signal_processing_library.h" +#include "cng_helpfuns.h" +#include "stdio.h" + + +typedef struct WebRtcCngDecInst_t_ { + + WebRtc_UWord32 dec_seed; + WebRtc_Word32 dec_target_energy; + WebRtc_Word32 dec_used_energy; + WebRtc_Word16 dec_target_reflCoefs[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word16 dec_used_reflCoefs[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word16 dec_filtstate[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word16 dec_filtstateLow[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word16 dec_Efiltstate[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word16 dec_EfiltstateLow[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word16 dec_order; + WebRtc_Word16 dec_target_scale_factor; /*Q29*/ + WebRtc_Word16 dec_used_scale_factor; /*Q29*/ + WebRtc_Word16 target_scale_factor; /* Q13 */ + WebRtc_Word16 errorcode; + WebRtc_Word16 initflag; + +} WebRtcCngDecInst_t; + + +typedef struct WebRtcCngEncInst_t_ { + + WebRtc_Word16 enc_nrOfCoefs; + WebRtc_Word16 enc_sampfreq; + WebRtc_Word16 enc_interval; + WebRtc_Word16 enc_msSinceSID; + WebRtc_Word32 enc_Energy; + WebRtc_Word16 enc_reflCoefs[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word32 enc_corrVector[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word16 enc_filtstate[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word16 enc_filtstateLow[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_UWord32 enc_seed; + WebRtc_Word16 errorcode; + WebRtc_Word16 initflag; + +} WebRtcCngEncInst_t; + +const WebRtc_Word32 WebRtcCng_kDbov[94]={ + 1081109975, 858756178, 682134279, 541838517, 430397633, 341876992, + 271562548, 215709799, 171344384, 136103682, 108110997, 85875618, + 68213428, 54183852, 43039763, 34187699, 27156255, 21570980, + 17134438, 13610368, 10811100, 8587562, 6821343, 5418385, + 4303976, 3418770, 2715625, 2157098, 1713444, 1361037, + 1081110, 858756, 682134, 541839, 430398, 341877, + 271563, 215710, 171344, 136104, 108111, 85876, + 68213, 54184, 43040, 34188, 27156, 21571, + 17134, 13610, 10811, 8588, 6821, 5418, + 4304, 3419, 2716, 2157, 1713, 1361, + 1081, 859, 682, 542, 430, 342, + 272, 216, 171, 136, 108, 86, + 68, 54, 43, 34, 27, 22, + 17, 14, 11, 9, 7, 5, + 4, 3, 3, 2, 2, 1, + 1, 1, 1, 1 +}; +const WebRtc_Word16 WebRtcCng_kCorrWindow[WEBRTC_CNG_MAX_LPC_ORDER] = { + 32702, 32636, 32570, 32505, 32439, 32374, + 32309, 32244, 32179, 32114, 32049, 31985 +}; + +/**************************************************************************** + * WebRtcCng_Version(...) + * + * These functions returns the version name (string must be at least + * 500 characters long) + * + * Output: + * - version : Pointer to character string + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcCng_Version(WebRtc_Word8 *version) +{ + strcpy((char*)version,(const char*)"1.2.0\n"); + return(0); +} + + +/**************************************************************************** + * WebRtcCng_AssignSizeEnc/Dec(...) + * + * These functions get the size needed for storing the instance for encoder + * and decoder, respectively + * + * Input/Output: + * - sizeinbytes : Pointer to integer where the size is returned + * + * Return value : 0 + */ + +WebRtc_Word16 WebRtcCng_AssignSizeEnc(int *sizeinbytes) +{ + *sizeinbytes=sizeof(WebRtcCngEncInst_t)*2/sizeof(WebRtc_Word16); + return(0); +} + +WebRtc_Word16 WebRtcCng_AssignSizeDec(int *sizeinbytes) +{ + *sizeinbytes=sizeof(WebRtcCngDecInst_t)*2/sizeof(WebRtc_Word16); + return(0); +} + + +/**************************************************************************** + * WebRtcCng_AssignEnc/Dec(...) + * + * These functions Assignes memory for the instances. + * + * Input: + * - CNG_inst_Addr : Adress to where to assign memory + * Output: + * - inst : Pointer to the instance that should be created + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcCng_AssignEnc(CNG_enc_inst **inst, void *CNG_inst_Addr) +{ + if (CNG_inst_Addr!=NULL) { + *inst = (CNG_enc_inst*)CNG_inst_Addr; + (*(WebRtcCngEncInst_t**) inst)->errorcode = 0; + (*(WebRtcCngEncInst_t**) inst)->initflag = 0; + return(0); + } else { + /* The memory could not be allocated */ + return(-1); + } +} + +WebRtc_Word16 WebRtcCng_AssignDec(CNG_dec_inst **inst, void *CNG_inst_Addr) +{ + if (CNG_inst_Addr!=NULL) { + *inst = (CNG_dec_inst*)CNG_inst_Addr; + (*(WebRtcCngDecInst_t**) inst)->errorcode = 0; + (*(WebRtcCngDecInst_t**) inst)->initflag = 0; + return(0); + } else { + /* The memory could not be allocated */ + return(-1); + } +} + + +/**************************************************************************** + * WebRtcCng_CreateEnc/Dec(...) + * + * These functions create an instance to the specified structure + * + * Input: + * - XXX_inst : Pointer to created instance that should be created + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcCng_CreateEnc(CNG_enc_inst **cng_inst) +{ + *cng_inst=(CNG_enc_inst*)malloc(sizeof(WebRtcCngEncInst_t)); + if(cng_inst!=NULL) { + (*(WebRtcCngEncInst_t**) cng_inst)->errorcode = 0; + (*(WebRtcCngEncInst_t**) cng_inst)->initflag = 0; + return(0); + } + else { + /* The memory could not be allocated */ + return(-1); + } +} + +WebRtc_Word16 WebRtcCng_CreateDec(CNG_dec_inst **cng_inst) +{ + *cng_inst=(CNG_dec_inst*)malloc(sizeof(WebRtcCngDecInst_t)); + if(cng_inst!=NULL) { + (*(WebRtcCngDecInst_t**) cng_inst)->errorcode = 0; + (*(WebRtcCngDecInst_t**) cng_inst)->initflag = 0; + return(0); + } + else { + /* The memory could not be allocated */ + return(-1); + } +} + + +/**************************************************************************** + * WebRtcCng_InitEnc/Dec(...) + * + * This function initializes a instance + * + * Input: + * - cng_inst : Instance that should be initialized + * + * - fs : 8000 for narrowband and 16000 for wideband + * - interval : generate SID data every interval ms + * - quality : TBD + * + * Output: + * - cng_inst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ + + +WebRtc_Word16 WebRtcCng_InitEnc(CNG_enc_inst *cng_inst, + WebRtc_Word16 fs, + WebRtc_Word16 interval, + WebRtc_Word16 quality) +{ + int i; + + WebRtcCngEncInst_t* inst=(WebRtcCngEncInst_t*)cng_inst; + + memset(inst, 0, sizeof(WebRtcCngEncInst_t)); + + /* Check LPC order */ + + if (quality>WEBRTC_CNG_MAX_LPC_ORDER) { + inst->errorcode = CNG_DISALLOWED_LPC_ORDER; + return (-1); + } + + if (fs<=0) { + inst->errorcode = CNG_DISALLOWED_SAMPLING_FREQUENCY; + return (-1); + } + + inst->enc_sampfreq=fs; + inst->enc_interval=interval; + inst->enc_nrOfCoefs=quality; + inst->enc_msSinceSID=0; + inst->enc_seed=7777; /*For debugging only*/ + inst->enc_Energy=0; + for(i=0;i<(WEBRTC_CNG_MAX_LPC_ORDER+1);i++){ + inst->enc_reflCoefs[i]=0; + inst->enc_corrVector[i]=0; + } + inst->initflag=1; + + return(0); +} + +WebRtc_Word16 WebRtcCng_InitDec(CNG_dec_inst *cng_inst) +{ + int i; + + WebRtcCngDecInst_t* inst=(WebRtcCngDecInst_t*)cng_inst; + + memset(inst, 0, sizeof(WebRtcCngDecInst_t)); + inst->dec_seed=7777; /*For debugging only*/ + inst->dec_order=5; + inst->dec_target_scale_factor=0; + inst->dec_used_scale_factor=0; + for(i=0;i<(WEBRTC_CNG_MAX_LPC_ORDER+1);i++){ + inst->dec_filtstate[i]=0; + inst->dec_target_reflCoefs[i]=0; + inst->dec_used_reflCoefs[i]=0; + } + inst->dec_target_reflCoefs[0]=0; + inst->dec_used_reflCoefs[0]=0; + inst ->dec_used_energy=0; + inst->initflag=1; + + return(0); +} + +/**************************************************************************** + * WebRtcCng_FreeEnc/Dec(...) + * + * These functions frees the dynamic memory of a specified instance + * + * Input: + * - cng_inst : Pointer to created instance that should be freed + * + * Return value : 0 - Ok + * -1 - Error + */ + + +WebRtc_Word16 WebRtcCng_FreeEnc(CNG_enc_inst *cng_inst) +{ + free(cng_inst); + return(0); +} + +WebRtc_Word16 WebRtcCng_FreeDec(CNG_dec_inst *cng_inst) +{ + free(cng_inst); + return(0); +} + + + +/**************************************************************************** + * WebRtcCng_Encode(...) + * + * These functions analyzes background noise + * + * Input: + * - cng_inst : Pointer to created instance + * - speech : Signal (noise) to be analyzed + * - nrOfSamples : Size of speech vector + * - bytesOut : Nr of bytes to transmit, might be 0 + * + * Return value : 0 - Ok + * -1 - Error + */ +WebRtc_Word16 WebRtcCng_Encode(CNG_enc_inst *cng_inst, + WebRtc_Word16 *speech, + WebRtc_Word16 nrOfSamples, + WebRtc_UWord8* SIDdata, + WebRtc_Word16* bytesOut, + WebRtc_Word16 forceSID) +{ + WebRtcCngEncInst_t* inst=(WebRtcCngEncInst_t*)cng_inst; + + WebRtc_Word16 arCoefs[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word32 corrVector[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word16 refCs[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word16 hanningW[WEBRTC_CNG_MAX_OUTSIZE_ORDER]; + WebRtc_Word16 ReflBeta=19661; /*0.6 in q15*/ + WebRtc_Word16 ReflBetaComp=13107; /*0.4 in q15*/ + WebRtc_Word32 outEnergy; + int outShifts; + int i, stab; + int acorrScale; + int index; + WebRtc_Word32 diff; + WebRtc_Word16 ind,factor; + WebRtc_Word32 *bptr, blo, bhi; + WebRtc_Word16 negate; + const WebRtc_Word16 *aptr; + + WebRtc_Word16 speechBuf[WEBRTC_CNG_MAX_OUTSIZE_ORDER]; + + + /* check if encoder initiated */ + if (inst->initflag != 1) { + inst->errorcode = CNG_ENCODER_NOT_INITIATED; + return (-1); + } + + + /* check framesize */ + if (nrOfSamples>WEBRTC_CNG_MAX_OUTSIZE_ORDER) { + inst->errorcode = CNG_DISALLOWED_FRAME_SIZE; + return (-1); + } + + + for(i=0;i<nrOfSamples;i++){ + speechBuf[i]=speech[i]; + } + + factor=nrOfSamples; + + /* Calculate energy and a coefficients */ + outEnergy =WebRtcSpl_Energy(speechBuf, nrOfSamples, &outShifts); + while(outShifts>0){ + if(outShifts>5){ /*We can only do 5 shifts without destroying accuracy in division factor*/ + outEnergy<<=(outShifts-5); + outShifts=5; + } + else{ + factor/=2; + outShifts--; + } + } + outEnergy=WebRtcSpl_DivW32W16(outEnergy,factor); + + if (outEnergy > 1){ + /* Create Hanning Window */ + WebRtcSpl_GetHanningWindow(hanningW, nrOfSamples/2); + for( i=0;i<(nrOfSamples/2);i++ ) + hanningW[nrOfSamples-i-1]=hanningW[i]; + + WebRtcSpl_ElementwiseVectorMult(speechBuf, hanningW, speechBuf, nrOfSamples, 14); + + WebRtcSpl_AutoCorrelation( speechBuf, nrOfSamples, inst->enc_nrOfCoefs, corrVector, &acorrScale ); + + if( *corrVector==0 ) + *corrVector = WEBRTC_SPL_WORD16_MAX; + + /* Adds the bandwidth expansion */ + aptr = WebRtcCng_kCorrWindow; + bptr = corrVector; + + // (zzz) lpc16_1 = 17+1+820+2+2 = 842 (ordo2=700) + for( ind=0; ind<inst->enc_nrOfCoefs; ind++ ) + { + // The below code multiplies the 16 b corrWindow values (Q15) with + // the 32 b corrvector (Q0) and shifts the result down 15 steps. + + negate = *bptr<0; + if( negate ) + *bptr = -*bptr; + + blo = (WebRtc_Word32)*aptr * (*bptr & 0xffff); + bhi = ((blo >> 16) & 0xffff) + ((WebRtc_Word32)(*aptr++) * ((*bptr >> 16) & 0xffff)); + blo = (blo & 0xffff) | ((bhi & 0xffff) << 16); + + *bptr = (( (bhi>>16) & 0x7fff) << 17) | ((WebRtc_UWord32)blo >> 15); + if( negate ) + *bptr = -*bptr; + bptr++; + } + + // end of bandwidth expansion + + stab=WebRtcSpl_LevinsonDurbin(corrVector, arCoefs, refCs, inst->enc_nrOfCoefs); + + if(!stab){ + // disregard from this frame + *bytesOut=0; + return(0); + } + + } + else { + for(i=0;i<inst->enc_nrOfCoefs; i++) + refCs[i]=0; + } + + if(forceSID){ + /*Read instantaneous values instead of averaged*/ + for(i=0;i<inst->enc_nrOfCoefs;i++) + inst->enc_reflCoefs[i]=refCs[i]; + inst->enc_Energy=outEnergy; + } + else{ + /*Average history with new values*/ + for(i=0;i<(inst->enc_nrOfCoefs);i++){ + inst->enc_reflCoefs[i]=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->enc_reflCoefs[i],ReflBeta,15); + inst->enc_reflCoefs[i]+=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(refCs[i],ReflBetaComp,15); + } + inst->enc_Energy=(outEnergy>>2)+(inst->enc_Energy>>1)+(inst->enc_Energy>>2); + } + + + if(inst->enc_Energy<1){ + inst->enc_Energy=1; + } + + if((inst->enc_msSinceSID>(inst->enc_interval-1))||forceSID){ + + /* Search for best dbov value */ + /* Clumsy linear search that can be optimized since database is sorted */ + index=0; + diff=WEBRTC_SPL_ABS_W32(inst->enc_Energy-WebRtcCng_kDbov[index]); + for(i=1;i<93;i++){ + /* Always round downwards */ + if((inst->enc_Energy-WebRtcCng_kDbov[i])>0){ + index=i; + break; + } + } + if((i==93)&&(index==0)) + index=94; + SIDdata[0]=index; + + + /* Quantize coefs with tweak for WebRtc implementation of RFC3389 */ + if(inst->enc_nrOfCoefs==WEBRTC_CNG_MAX_LPC_ORDER){ + for(i=0;i<inst->enc_nrOfCoefs;i++){ + SIDdata[i+1]=((inst->enc_reflCoefs[i]+128)>>8); /* Q15 to Q7*/ /* +127 */ + } + }else{ + for(i=0;i<inst->enc_nrOfCoefs;i++){ + SIDdata[i+1]=(127+((inst->enc_reflCoefs[i]+128)>>8)); /* Q15 to Q7*/ /* +127 */ + } + } + + inst->enc_msSinceSID=0; + *bytesOut=inst->enc_nrOfCoefs+1; + + inst->enc_msSinceSID+=(1000*nrOfSamples)/inst->enc_sampfreq; + return(inst->enc_nrOfCoefs+1); + }else{ + inst->enc_msSinceSID+=(1000*nrOfSamples)/inst->enc_sampfreq; + *bytesOut=0; + return(0); + } +} + + +/**************************************************************************** + * WebRtcCng_UpdateSid(...) + * + * These functions updates the CN state, when a new SID packet arrives + * + * Input: + * - cng_inst : Pointer to created instance that should be freed + * - SID : SID packet, all headers removed + * - length : Length in bytes of SID packet + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcCng_UpdateSid(CNG_dec_inst *cng_inst, + WebRtc_UWord8 *SID, + WebRtc_Word16 length) +{ + + WebRtcCngDecInst_t* inst=(WebRtcCngDecInst_t*)cng_inst; + WebRtc_Word16 refCs[WEBRTC_CNG_MAX_LPC_ORDER]; + WebRtc_Word32 targetEnergy; + int i; + + if (inst->initflag != 1) { + inst->errorcode = CNG_DECODER_NOT_INITIATED; + return (-1); + } + + /*Throw away reflection coefficients of higher order than we can handle*/ + if(length> (WEBRTC_CNG_MAX_LPC_ORDER+1)) + length=WEBRTC_CNG_MAX_LPC_ORDER+1; + + inst->dec_order=length-1; + + if(SID[0]>93) + SID[0]=93; + targetEnergy=WebRtcCng_kDbov[SID[0]]; + /* Take down target energy to 75% */ + targetEnergy=targetEnergy>>1; + targetEnergy+=targetEnergy>>2; + + inst->dec_target_energy=targetEnergy; + + /* Reconstruct coeffs with tweak for WebRtc implementation of RFC3389 */ + if(inst->dec_order==WEBRTC_CNG_MAX_LPC_ORDER){ + for(i=0;i<(inst->dec_order);i++){ + refCs[i]=SID[i+1]<<8; /* Q7 to Q15*/ + inst->dec_target_reflCoefs[i]=refCs[i]; + } + }else{ + for(i=0;i<(inst->dec_order);i++){ + refCs[i]=(SID[i+1]-127)<<8; /* Q7 to Q15*/ + inst->dec_target_reflCoefs[i]=refCs[i]; + } + } + + for(i=(inst->dec_order);i<WEBRTC_CNG_MAX_LPC_ORDER;i++){ + refCs[i]=0; + inst->dec_target_reflCoefs[i]=refCs[i]; + } + + return(0); +} + + +/**************************************************************************** + * WebRtcCng_Generate(...) + * + * These functions generates CN data when needed + * + * Input: + * - cng_inst : Pointer to created instance that should be freed + * - outData : pointer to area to write CN data + * - nrOfSamples : How much data to generate + * + * Return value : 0 - Ok + * -1 - Error + */ +WebRtc_Word16 WebRtcCng_Generate(CNG_dec_inst *cng_inst, + WebRtc_Word16 *outData, + WebRtc_Word16 nrOfSamples, + WebRtc_Word16 new_period) +{ + WebRtcCngDecInst_t* inst=(WebRtcCngDecInst_t*)cng_inst; + + int i; + WebRtc_Word16 excitation[WEBRTC_CNG_MAX_OUTSIZE_ORDER]; + WebRtc_Word16 low[WEBRTC_CNG_MAX_OUTSIZE_ORDER]; + WebRtc_Word16 lpPoly[WEBRTC_CNG_MAX_LPC_ORDER+1]; + WebRtc_Word16 ReflBetaStd=26214; /*0.8 in q15*/ + WebRtc_Word16 ReflBetaCompStd=6553; /*0.2in q15*/ + WebRtc_Word16 ReflBetaNewP=19661; /*0.6 in q15*/ + WebRtc_Word16 ReflBetaCompNewP=13107; /*0.4 in q15*/ + WebRtc_Word16 Beta,BetaC, tmp1, tmp2, tmp3; + WebRtc_Word32 targetEnergy; + WebRtc_Word16 En; + WebRtc_Word16 temp16; + + if (nrOfSamples>WEBRTC_CNG_MAX_OUTSIZE_ORDER) { + inst->errorcode = CNG_DISALLOWED_FRAME_SIZE; + return (-1); + } + + + if (new_period) { + inst->dec_used_scale_factor=inst->dec_target_scale_factor; + Beta=ReflBetaNewP; + BetaC=ReflBetaCompNewP; + } else { + Beta=ReflBetaStd; + BetaC=ReflBetaCompStd; + } + + /*Here we use a 0.5 weighting, should possibly be modified to 0.6*/ + tmp1=inst->dec_used_scale_factor<<2; /* Q13->Q15 */ + tmp2=inst->dec_target_scale_factor<<2; /* Q13->Q15 */ + tmp3=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp1,Beta,15); + tmp3+=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp2,BetaC,15); + inst->dec_used_scale_factor=tmp3>>2; /* Q15->Q13 */ + + inst->dec_used_energy=inst->dec_used_energy>>1; + inst->dec_used_energy+=inst->dec_target_energy>>1; + + + /* Do the same for the reflection coeffs */ + for (i=0;i<WEBRTC_CNG_MAX_LPC_ORDER;i++) { + inst->dec_used_reflCoefs[i]=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->dec_used_reflCoefs[i],Beta,15); + inst->dec_used_reflCoefs[i]+=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->dec_target_reflCoefs[i],BetaC,15); + } + + /* Compute the polynomial coefficients */ + WebRtcCng_K2a16(inst->dec_used_reflCoefs, WEBRTC_CNG_MAX_LPC_ORDER, lpPoly); + + /***/ + + targetEnergy=inst->dec_used_energy; + + // Calculate scaling factor based on filter energy + En=8192; //1.0 in Q13 + for (i=0; i<(WEBRTC_CNG_MAX_LPC_ORDER); i++) { + + // Floating point value for reference + // E*=1.0-((float)inst->dec_used_reflCoefs[i]/32768.0)*((float)inst->dec_used_reflCoefs[i]/32768.0); + + // Same in fixed point + temp16=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->dec_used_reflCoefs[i],inst->dec_used_reflCoefs[i],15); // K(i).^2 in Q15 + temp16=0x7fff - temp16; // 1 - K(i).^2 in Q15 + En=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(En,temp16,15); + + } + + //float scaling= sqrt(E*inst->dec_target_energy/((1<<24))); + + //Calculate sqrt(En*target_energy/exctiation energy) + + targetEnergy=WebRtcSpl_Sqrt(inst->dec_used_energy); + + En=(WebRtc_Word16)WebRtcSpl_Sqrt(En)<<6; //We are missing a factor sqrt(2) here + En=(En*3)>>1; //1.5 estimates sqrt(2) + + inst->dec_used_scale_factor=(WebRtc_Word16)((En*targetEnergy)>>12); + + + /***/ + + /*Generate excitation*/ + /*Excitation energy per sample is 2.^24 - Q13 N(0,1) */ + for(i=0;i<nrOfSamples;i++){ + excitation[i]=WebRtcSpl_RandN(&inst->dec_seed)>>1; + } + + /*Scale to correct energy*/ + WebRtcSpl_ScaleVector(excitation, excitation, inst->dec_used_scale_factor, nrOfSamples, 13); + + WebRtcSpl_FilterAR( + lpPoly, /* Coefficients in Q12 */ + WEBRTC_CNG_MAX_LPC_ORDER+1, + excitation, /* Speech samples */ + nrOfSamples, + inst->dec_filtstate, /* State preservation */ + WEBRTC_CNG_MAX_LPC_ORDER, + inst->dec_filtstateLow, /* State preservation */ + WEBRTC_CNG_MAX_LPC_ORDER, + outData, /* Filtered speech samples */ + low, + nrOfSamples + ); + + return(0); + +} + + + +/**************************************************************************** + * WebRtcCng_GetErrorCodeEnc/Dec(...) + * + * This functions can be used to check the error code of a CNG instance. When + * a function returns -1 a error code will be set for that instance. The + * function below extract the code of the last error that occured in the + * specified instance. + * + * Input: + * - CNG_inst : CNG enc/dec instance + * + * Return value : Error code + */ + +WebRtc_Word16 WebRtcCng_GetErrorCodeEnc(CNG_enc_inst *cng_inst) +{ + + /* typecast pointer to real structure */ + WebRtcCngEncInst_t* inst=(WebRtcCngEncInst_t*)cng_inst; + + return inst->errorcode; +} + +WebRtc_Word16 WebRtcCng_GetErrorCodeDec(CNG_dec_inst *cng_inst) +{ + + /* typecast pointer to real structure */ + WebRtcCngDecInst_t* inst=(WebRtcCngDecInst_t*)cng_inst; + + return inst->errorcode; +} diff --git a/src/libs/webrtc/cng/webrtc_cng.h b/src/libs/webrtc/cng/webrtc_cng.h new file mode 100644 index 00000000..d6e81578 --- /dev/null +++ b/src/libs/webrtc/cng/webrtc_cng.h @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_MAIN_INTERFACE_WEBRTC_CNG_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_MAIN_INTERFACE_WEBRTC_CNG_H_ + +#include "typedefs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define WEBRTC_CNG_MAX_LPC_ORDER 12 +#define WEBRTC_CNG_MAX_OUTSIZE_ORDER 640 + +/* Define Error codes */ + +/* 6100 Encoder */ +#define CNG_ENCODER_MEMORY_ALLOCATION_FAILED 6110 +#define CNG_ENCODER_NOT_INITIATED 6120 +#define CNG_DISALLOWED_LPC_ORDER 6130 +#define CNG_DISALLOWED_FRAME_SIZE 6140 +#define CNG_DISALLOWED_SAMPLING_FREQUENCY 6150 +/* 6200 Decoder */ +#define CNG_DECODER_MEMORY_ALLOCATION_FAILED 6210 +#define CNG_DECODER_NOT_INITIATED 6220 + + +typedef struct WebRtcCngEncInst CNG_enc_inst; +typedef struct WebRtcCngDecInst CNG_dec_inst; + + +/**************************************************************************** + * WebRtcCng_Version(...) + * + * These functions returns the version name (string must be at least + * 500 characters long) + * + * Output: + * - version : Pointer to character string + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcCng_Version(WebRtc_Word8 *version); + +/**************************************************************************** + * WebRtcCng_AssignSizeEnc/Dec(...) + * + * These functions get the size needed for storing the instance for encoder + * and decoder, respectively + * + * Input/Output: + * - sizeinbytes : Pointer to integer where the size is returned + * + * Return value : 0 + */ + +WebRtc_Word16 WebRtcCng_AssignSizeEnc(int *sizeinbytes); +WebRtc_Word16 WebRtcCng_AssignSizeDec(int *sizeinbytes); + + +/**************************************************************************** + * WebRtcCng_AssignEnc/Dec(...) + * + * These functions Assignes memory for the instances. + * + * Input: + * - CNG_inst_Addr : Adress to where to assign memory + * Output: + * - inst : Pointer to the instance that should be created + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcCng_AssignEnc(CNG_enc_inst **inst, void *CNG_inst_Addr); +WebRtc_Word16 WebRtcCng_AssignDec(CNG_dec_inst **inst, void *CNG_inst_Addr); + + +/**************************************************************************** + * WebRtcCng_CreateEnc/Dec(...) + * + * These functions create an instance to the specified structure + * + * Input: + * - XXX_inst : Pointer to created instance that should be created + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcCng_CreateEnc(CNG_enc_inst **cng_inst); +WebRtc_Word16 WebRtcCng_CreateDec(CNG_dec_inst **cng_inst); + + +/**************************************************************************** + * WebRtcCng_InitEnc/Dec(...) + * + * This function initializes a instance + * + * Input: + * - cng_inst : Instance that should be initialized + * + * - fs : 8000 for narrowband and 16000 for wideband + * - interval : generate SID data every interval ms + * - quality : Number of refl. coefs, maximum allowed is 12 + * + * Output: + * - cng_inst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcCng_InitEnc(CNG_enc_inst *cng_inst, + WebRtc_Word16 fs, + WebRtc_Word16 interval, + WebRtc_Word16 quality); +WebRtc_Word16 WebRtcCng_InitDec(CNG_dec_inst *cng_dec_inst); + + +/**************************************************************************** + * WebRtcCng_FreeEnc/Dec(...) + * + * These functions frees the dynamic memory of a specified instance + * + * Input: + * - cng_inst : Pointer to created instance that should be freed + * + * Return value : 0 - Ok + * -1 - Error + */ + + +WebRtc_Word16 WebRtcCng_FreeEnc(CNG_enc_inst *cng_inst); +WebRtc_Word16 WebRtcCng_FreeDec(CNG_dec_inst *cng_inst); + + + +/**************************************************************************** + * WebRtcCng_Encode(...) + * + * These functions analyzes background noise + * + * Input: + * - cng_inst : Pointer to created instance + * - speech : Signal to be analyzed + * - nrOfSamples : Size of speech vector + * - forceSID : not zero to force SID frame and reset + * + * Output: + * - bytesOut : Nr of bytes to transmit, might be 0 + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcCng_Encode(CNG_enc_inst *cng_inst, + WebRtc_Word16 *speech, + WebRtc_Word16 nrOfSamples, + WebRtc_UWord8* SIDdata, + WebRtc_Word16 *bytesOut, + WebRtc_Word16 forceSID); + + +/**************************************************************************** + * WebRtcCng_UpdateSid(...) + * + * These functions updates the CN state, when a new SID packet arrives + * + * Input: + * - cng_inst : Pointer to created instance that should be freed + * - SID : SID packet, all headers removed + * - length : Length in bytes of SID packet + * + * Return value : 0 - Ok + * -1 - Error + */ +WebRtc_Word16 WebRtcCng_UpdateSid(CNG_dec_inst *cng_inst, + WebRtc_UWord8 *SID, + WebRtc_Word16 length); + + +/**************************************************************************** + * WebRtcCng_Generate(...) + * + * These functions generates CN data when needed + * + * Input: + * - cng_inst : Pointer to created instance that should be freed + * - outData : pointer to area to write CN data + * - nrOfSamples : How much data to generate + * - new_period : >0 if a new period of CNG, will reset history + * + * Return value : 0 - Ok + * -1 - Error + */ +WebRtc_Word16 WebRtcCng_Generate(CNG_dec_inst *cng_inst, + WebRtc_Word16 * outData, + WebRtc_Word16 nrOfSamples, + WebRtc_Word16 new_period); + + +/***************************************************************************** + * WebRtcCng_GetErrorCodeEnc/Dec(...) + * + * This functions can be used to check the error code of a CNG instance. When + * a function returns -1 a error code will be set for that instance. The + * function below extract the code of the last error that occurred in the + * specified instance. + * + * Input: + * - CNG_inst : CNG enc/dec instance + * + * Return value : Error code + */ + +WebRtc_Word16 WebRtcCng_GetErrorCodeEnc(CNG_enc_inst *cng_inst); +WebRtc_Word16 WebRtcCng_GetErrorCodeDec(CNG_dec_inst *cng_inst); + + +#ifdef __cplusplus +} +#endif + +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_MAIN_INTERFACE_WEBRTC_CNG_H_ diff --git a/src/libs/webrtc/common_types.h b/src/libs/webrtc/common_types.h new file mode 100644 index 00000000..8b0b8a59 --- /dev/null +++ b/src/libs/webrtc/common_types.h @@ -0,0 +1,595 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_COMMON_TYPES_H +#define WEBRTC_COMMON_TYPES_H + +#include "typedefs.h" + +#ifdef WEBRTC_EXPORT + #define WEBRTC_DLLEXPORT _declspec(dllexport) +#elif WEBRTC_DLL + #define WEBRTC_DLLEXPORT _declspec(dllimport) +#else + #define WEBRTC_DLLEXPORT +#endif + +#ifndef NULL + #define NULL 0 +#endif + +namespace webrtc { + +class InStream +{ +public: + virtual int Read(void *buf,int len) = 0; + virtual int Rewind() {return -1;} + virtual ~InStream() {} +protected: + InStream() {} +}; + +class OutStream +{ +public: + virtual bool Write(const void *buf,int len) = 0; + virtual int Rewind() {return -1;} + virtual ~OutStream() {} +protected: + OutStream() {} +}; + +enum TraceModule +{ + // not a module, triggered from the engine code + kTraceVoice = 0x0001, + // not a module, triggered from the engine code + kTraceVideo = 0x0002, + // not a module, triggered from the utility code + kTraceUtility = 0x0003, + kTraceRtpRtcp = 0x0004, + kTraceTransport = 0x0005, + kTraceSrtp = 0x0006, + kTraceAudioCoding = 0x0007, + kTraceAudioMixerServer = 0x0008, + kTraceAudioMixerClient = 0x0009, + kTraceFile = 0x000a, + kTraceAudioProcessing = 0x000b, + kTraceVideoCoding = 0x0010, + kTraceVideoMixer = 0x0011, + kTraceAudioDevice = 0x0012, + kTraceVideoRenderer = 0x0014, + kTraceVideoCapture = 0x0015, + kTraceVideoPreocessing = 0x0016 +}; + +enum TraceLevel +{ + kTraceNone = 0x0000, // no trace + kTraceStateInfo = 0x0001, + kTraceWarning = 0x0002, + kTraceError = 0x0004, + kTraceCritical = 0x0008, + kTraceApiCall = 0x0010, + kTraceDefault = 0x00ff, + + kTraceModuleCall = 0x0020, + kTraceMemory = 0x0100, // memory info + kTraceTimer = 0x0200, // timing info + kTraceStream = 0x0400, // "continuous" stream of data + + // used for debug purposes + kTraceDebug = 0x0800, // debug + kTraceInfo = 0x1000, // debug info + + kTraceAll = 0xffff +}; + +// External Trace API +class TraceCallback +{ +public: + virtual void Print(const TraceLevel level, + const char *traceString, + const int length) = 0; +protected: + virtual ~TraceCallback() {} + TraceCallback() {} +}; + + +enum FileFormats +{ + kFileFormatWavFile = 1, + kFileFormatCompressedFile = 2, + kFileFormatAviFile = 3, + kFileFormatPreencodedFile = 4, + kFileFormatPcm16kHzFile = 7, + kFileFormatPcm8kHzFile = 8, + kFileFormatPcm32kHzFile = 9 +}; + + +enum ProcessingTypes +{ + kPlaybackPerChannel = 0, + kPlaybackAllChannelsMixed, + kRecordingPerChannel, + kRecordingAllChannelsMixed +}; + +// Encryption enums +enum CipherTypes +{ + kCipherNull = 0, + kCipherAes128CounterMode = 1 +}; + +enum AuthenticationTypes +{ + kAuthNull = 0, + kAuthHmacSha1 = 3 +}; + +enum SecurityLevels +{ + kNoProtection = 0, + kEncryption = 1, + kAuthentication = 2, + kEncryptionAndAuthentication = 3 +}; + +class Encryption +{ +public: + virtual void encrypt( + int channel_no, + unsigned char* in_data, + unsigned char* out_data, + int bytes_in, + int* bytes_out) = 0; + + virtual void decrypt( + int channel_no, + unsigned char* in_data, + unsigned char* out_data, + int bytes_in, + int* bytes_out) = 0; + + virtual void encrypt_rtcp( + int channel_no, + unsigned char* in_data, + unsigned char* out_data, + int bytes_in, + int* bytes_out) = 0; + + virtual void decrypt_rtcp( + int channel_no, + unsigned char* in_data, + unsigned char* out_data, + int bytes_in, + int* bytes_out) = 0; + +protected: + virtual ~Encryption() {} + Encryption() {} +}; + +// External transport callback interface +class Transport +{ +public: + virtual int SendPacket(int channel, const void *data, int len) = 0; + virtual int SendRTCPPacket(int channel, const void *data, int len) = 0; + +protected: + virtual ~Transport() {} + Transport() {} +}; + +// ================================================================== +// Voice specific types +// ================================================================== + +// Each codec supported can be described by this structure. +struct CodecInst +{ + int pltype; + char plname[32]; + int plfreq; + int pacsize; + int channels; + int rate; +}; + +enum FrameType +{ + kFrameEmpty = 0, + kAudioFrameSpeech = 1, + kAudioFrameCN = 2, + kVideoFrameKey = 3, // independent frame + kVideoFrameDelta = 4, // depends on the previus frame + kVideoFrameGolden = 5, // depends on a old known previus frame + kVideoFrameAltRef = 6 +}; + +// RTP +enum {kRtpCsrcSize = 15}; // RFC 3550 page 13 + +enum RTPDirections +{ + kRtpIncoming = 0, + kRtpOutgoing +}; + +enum PayloadFrequencies +{ + kFreq8000Hz = 8000, + kFreq16000Hz = 16000, + kFreq32000Hz = 32000 +}; + +enum VadModes // degree of bandwidth reduction +{ + kVadConventional = 0, // lowest reduction + kVadAggressiveLow, + kVadAggressiveMid, + kVadAggressiveHigh // highest reduction +}; + +struct NetworkStatistics // NETEQ statistics +{ + // current jitter buffer size in ms + WebRtc_UWord16 currentBufferSize; + // preferred (optimal) buffer size in ms + WebRtc_UWord16 preferredBufferSize; + // loss rate (network + late) in percent (in Q14) + WebRtc_UWord16 currentPacketLossRate; + // late loss rate in percent (in Q14) + WebRtc_UWord16 currentDiscardRate; + // fraction (of original stream) of synthesized speech inserted through + // expansion (in Q14) + WebRtc_UWord16 currentExpandRate; + // fraction of synthesized speech inserted through pre-emptive expansion + // (in Q14) + WebRtc_UWord16 currentPreemptiveRate; + // fraction of data removed through acceleration (in Q14) + WebRtc_UWord16 currentAccelerateRate; +}; + +struct JitterStatistics +{ + // smallest Jitter Buffer size during call in ms + WebRtc_UWord32 jbMinSize; + // largest Jitter Buffer size during call in ms + WebRtc_UWord32 jbMaxSize; + // the average JB size, measured over time - ms + WebRtc_UWord32 jbAvgSize; + // number of times the Jitter Buffer changed (using Accelerate or + // Pre-emptive Expand) + WebRtc_UWord32 jbChangeCount; + // amount (in ms) of audio data received late + WebRtc_UWord32 lateLossMs; + // milliseconds removed to reduce jitter buffer size + WebRtc_UWord32 accelerateMs; + // milliseconds discarded through buffer flushing + WebRtc_UWord32 flushedMs; + // milliseconds of generated silence + WebRtc_UWord32 generatedSilentMs; + // milliseconds of synthetic audio data (non-background noise) + WebRtc_UWord32 interpolatedVoiceMs; + // milliseconds of synthetic audio data (background noise level) + WebRtc_UWord32 interpolatedSilentMs; + // count of tiny expansions in output audio + WebRtc_UWord32 countExpandMoreThan120ms; + // count of small expansions in output audio + WebRtc_UWord32 countExpandMoreThan250ms; + // count of medium expansions in output audio + WebRtc_UWord32 countExpandMoreThan500ms; + // count of long expansions in output audio + WebRtc_UWord32 countExpandMoreThan2000ms; + // duration of longest audio drop-out + WebRtc_UWord32 longestExpandDurationMs; + // count of times we got small network outage (inter-arrival time in + // [500, 1000) ms) + WebRtc_UWord32 countIAT500ms; + // count of times we got medium network outage (inter-arrival time in + // [1000, 2000) ms) + WebRtc_UWord32 countIAT1000ms; + // count of times we got large network outage (inter-arrival time >= + // 2000 ms) + WebRtc_UWord32 countIAT2000ms; + // longest packet inter-arrival time in ms + WebRtc_UWord32 longestIATms; + // min time incoming Packet "waited" to be played + WebRtc_UWord32 minPacketDelayMs; + // max time incoming Packet "waited" to be played + WebRtc_UWord32 maxPacketDelayMs; + // avg time incoming Packet "waited" to be played + WebRtc_UWord32 avgPacketDelayMs; +}; + +typedef struct +{ + int min; // minumum + int max; // maximum + int average; // average +} StatVal; + +typedef struct // All levels are reported in dBm0 +{ + StatVal speech_rx; // long-term speech levels on receiving side + StatVal speech_tx; // long-term speech levels on transmitting side + StatVal noise_rx; // long-term noise/silence levels on receiving side + StatVal noise_tx; // long-term noise/silence levels on transmitting side +} LevelStatistics; + +typedef struct // All levels are reported in dB +{ + StatVal erl; // Echo Return Loss + StatVal erle; // Echo Return Loss Enhancement + StatVal rerl; // RERL = ERL + ERLE + // Echo suppression inside EC at the point just before its NLP + StatVal a_nlp; +} EchoStatistics; + +enum TelephoneEventDetectionMethods +{ + kInBand = 0, + kOutOfBand = 1, + kInAndOutOfBand = 2 +}; + +enum NsModes // type of Noise Suppression +{ + kNsUnchanged = 0, // previously set mode + kNsDefault, // platform default + kNsConference, // conferencing default + kNsLowSuppression, // lowest suppression + kNsModerateSuppression, + kNsHighSuppression, + kNsVeryHighSuppression, // highest suppression +}; + +enum AgcModes // type of Automatic Gain Control +{ + kAgcUnchanged = 0, // previously set mode + kAgcDefault, // platform default + // adaptive mode for use when analog volume control exists (e.g. for + // PC softphone) + kAgcAdaptiveAnalog, + // scaling takes place in the digital domain (e.g. for conference servers + // and embedded devices) + kAgcAdaptiveDigital, + // can be used on embedded devices where the the capture signal is level + // is predictable + kAgcFixedDigital +}; + +// EC modes +enum EcModes // type of Echo Control +{ + kEcUnchanged = 0, // previously set mode + kEcDefault, // platform default + kEcConference, // conferencing default (aggressive AEC) + kEcAec, // Acoustic Echo Cancellation + kEcAecm, // AEC mobile +}; + +// AECM modes +enum AecmModes // mode of AECM +{ + kAecmQuietEarpieceOrHeadset = 0, + // Quiet earpiece or headset use + kAecmEarpiece, // most earpiece use + kAecmLoudEarpiece, // Loud earpiece or quiet speakerphone use + kAecmSpeakerphone, // most speakerphone use (default) + kAecmLoudSpeakerphone // Loud speakerphone +}; + +// AGC configuration +typedef struct +{ + unsigned short targetLeveldBOv; + unsigned short digitalCompressionGaindB; + bool limiterEnable; +} AgcConfig; // AGC configuration parameters + +enum StereoChannel +{ + kStereoLeft = 0, + kStereoRight, + kStereoBoth +}; + +// Audio device layers +enum AudioLayers +{ + kAudioPlatformDefault = 0, + kAudioWindowsWave = 1, + kAudioWindowsCore = 2, + kAudioLinuxAlsa = 3, + kAudioLinuxPulse = 4 +}; + +enum NetEqModes // NetEQ playout configurations +{ + // Optimized trade-off between low delay and jitter robustness for two-way + // communication. + kNetEqDefault = 0, + // Improved jitter robustness at the cost of increased delay. Can be + // used in one-way communication. + kNetEqStreaming = 1, + // Optimzed for decodability of fax signals rather than for perceived audio + // quality. + kNetEqFax = 2, +}; + +enum NetEqBgnModes // NetEQ Background Noise (BGN) configurations +{ + // BGN is always on and will be generated when the incoming RTP stream + // stops (default). + kBgnOn = 0, + // The BGN is faded to zero (complete silence) after a few seconds. + kBgnFade = 1, + // BGN is not used at all. Silence is produced after speech extrapolation + // has faded. + kBgnOff = 2, +}; + +enum OnHoldModes // On Hold direction +{ + kHoldSendAndPlay = 0, // Put both sending and playing in on-hold state. + kHoldSendOnly, // Put only sending in on-hold state. + kHoldPlayOnly // Put only playing in on-hold state. +}; + +enum AmrMode +{ + kRfc3267BwEfficient = 0, + kRfc3267OctetAligned = 1, + kRfc3267FileStorage = 2, +}; + +// ================================================================== +// Video specific types +// ================================================================== + +// Raw video types +enum RawVideoType +{ + kVideoI420 = 0, + kVideoYV12 = 1, + kVideoYUY2 = 2, + kVideoUYVY = 3, + kVideoIYUV = 4, + kVideoARGB = 5, + kVideoRGB24 = 6, + kVideoRGB565 = 7, + kVideoARGB4444 = 8, + kVideoARGB1555 = 9, + kVideoMJPEG = 10, + kVideoNV12 = 11, + kVideoNV21 = 12, + kVideoUnknown = 99 +}; + +// Video codec +enum { kConfigParameterSize = 128}; +enum { kPayloadNameSize = 32}; + +// H.263 specific +struct VideoCodecH263 +{ + char quality; +}; + +// H.264 specific +enum H264Packetization +{ + kH264SingleMode = 0, + kH264NonInterleavedMode = 1 +}; + +enum VideoCodecComplexity +{ + kComplexityNormal = 0, + kComplexityHigh = 1, + kComplexityHigher = 2, + kComplexityMax = 3 +}; + +enum VideoCodecProfile +{ + kProfileBase = 0x00, + kProfileMain = 0x01 +}; + +struct VideoCodecH264 +{ + H264Packetization packetization; + VideoCodecComplexity complexity; + VideoCodecProfile profile; + char level; + char quality; + + bool useFMO; + + unsigned char configParameters[kConfigParameterSize]; + unsigned char configParametersSize; +}; + +// VP8 specific +struct VideoCodecVP8 +{ + bool pictureLossIndicationOn; + bool feedbackModeOn; + VideoCodecComplexity complexity; +}; + +// MPEG-4 specific +struct VideoCodecMPEG4 +{ + unsigned char configParameters[kConfigParameterSize]; + unsigned char configParametersSize; + char level; +}; + +// Unknown specific +struct VideoCodecGeneric +{ +}; + +// Video codec types +enum VideoCodecType +{ + kVideoCodecH263, + kVideoCodecH264, + kVideoCodecVP8, + kVideoCodecMPEG4, + kVideoCodecI420, + kVideoCodecRED, + kVideoCodecULPFEC, + kVideoCodecUnknown +}; + +union VideoCodecUnion +{ + VideoCodecH263 H263; + VideoCodecH264 H264; + VideoCodecVP8 VP8; + VideoCodecMPEG4 MPEG4; + VideoCodecGeneric Generic; +}; + +// Common video codec properties +struct VideoCodec +{ + VideoCodecType codecType; + char plName[kPayloadNameSize]; + unsigned char plType; + + unsigned short width; + unsigned short height; + + unsigned int startBitrate; + unsigned int maxBitrate; + unsigned int minBitrate; + unsigned char maxFramerate; + + VideoCodecUnion codecSpecific; + + unsigned int qpMax; +}; + +} // namespace webrtc + +#endif // WEBRTC_COMMON_TYPES_H diff --git a/src/libs/webrtc/engine_configurations.h b/src/libs/webrtc/engine_configurations.h new file mode 100644 index 00000000..c24e3d2c --- /dev/null +++ b/src/libs/webrtc/engine_configurations.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_ENGINE_CONFIGURATIONS_H_ +#define WEBRTC_ENGINE_CONFIGURATIONS_H_ + +// ============================================================================ +// Voice and Video +// ============================================================================ + +// #define WEBRTC_EXTERNAL_TRANSPORT + +// ---------------------------------------------------------------------------- +// [Voice] Codec settings +// ---------------------------------------------------------------------------- + +#define WEBRTC_CODEC_ILBC +#define WEBRTC_CODEC_ISAC // floating-point iSAC implementation (default) +// #define WEBRTC_CODEC_ISACFX // fix-point iSAC implementation +#define WEBRTC_CODEC_G722 +#define WEBRTC_CODEC_PCM16 +#define WEBRTC_CODEC_RED +#define WEBRTC_CODEC_AVT + +// ---------------------------------------------------------------------------- +// [Video] Codec settings +// ---------------------------------------------------------------------------- + +#define VIDEOCODEC_I420 +#define VIDEOCODEC_VP8 + +// ============================================================================ +// VoiceEngine +// ============================================================================ + +// ---------------------------------------------------------------------------- +// Settings for VoiceEngine +// ---------------------------------------------------------------------------- + +#define WEBRTC_VOICE_ENGINE_AGC // Near-end AGC +#define WEBRTC_VOICE_ENGINE_ECHO // Near-end AEC +#define WEBRTC_VOICE_ENGINE_NR // Near-end NS +#define WEBRTC_VOICE_ENGINE_TYPING_DETECTION +#define WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT + +// ---------------------------------------------------------------------------- +// VoiceEngine sub-APIs +// ---------------------------------------------------------------------------- + +#define WEBRTC_VOICE_ENGINE_AUDIO_PROCESSING_API +#define WEBRTC_VOICE_ENGINE_CALL_REPORT_API +#define WEBRTC_VOICE_ENGINE_CODEC_API +#define WEBRTC_VOICE_ENGINE_DTMF_API +#define WEBRTC_VOICE_ENGINE_ENCRYPTION_API +#define WEBRTC_VOICE_ENGINE_EXTERNAL_MEDIA_API +#define WEBRTC_VOICE_ENGINE_FILE_API +#define WEBRTC_VOICE_ENGINE_HARDWARE_API +#define WEBRTC_VOICE_ENGINE_NETEQ_STATS_API +#define WEBRTC_VOICE_ENGINE_NETWORK_API +#define WEBRTC_VOICE_ENGINE_RTP_RTCP_API +#define WEBRTC_VOICE_ENGINE_VIDEO_SYNC_API +#define WEBRTC_VOICE_ENGINE_VOLUME_CONTROL_API + +// ============================================================================ +// VideoEngine +// ============================================================================ + +// ---------------------------------------------------------------------------- +// Settings for special VideoEngine configurations +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// VideoEngine sub-API:s +// ---------------------------------------------------------------------------- + +#define WEBRTC_VIDEO_ENGINE_CAPTURE_API +#define WEBRTC_VIDEO_ENGINE_CODEC_API +#define WEBRTC_VIDEO_ENGINE_ENCRYPTION_API +#define WEBRTC_VIDEO_ENGINE_FILE_API +#define WEBRTC_VIDEO_ENGINE_IMAGE_PROCESS_API +#define WEBRTC_VIDEO_ENGINE_NETWORK_API +#define WEBRTC_VIDEO_ENGINE_RENDER_API +#define WEBRTC_VIDEO_ENGINE_RTP_RTCP_API +// #define WEBRTC_VIDEO_ENGINE_EXTERNAL_CODEC_API + +// ============================================================================ +// Platform specific configurations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// VideoEngine Windows +// ---------------------------------------------------------------------------- + +#if defined(_WIN32) + // #define DIRECTDRAW_RENDERING + #define DIRECT3D9_RENDERING // Requires DirectX 9. +#endif + +// ---------------------------------------------------------------------------- +// VideoEngine MAC +// ---------------------------------------------------------------------------- + +#if defined(WEBRTC_MAC) && !defined(MAC_IPHONE) + // #define CARBON_RENDERING + #define COCOA_RENDERING +#endif + +// ---------------------------------------------------------------------------- +// VideoEngine Mobile iPhone +// ---------------------------------------------------------------------------- + +#if defined(MAC_IPHONE) + #define EAGL_RENDERING +#endif + +// ---------------------------------------------------------------------------- +// Deprecated +// ---------------------------------------------------------------------------- + +// #define WEBRTC_CODEC_G729 +// #define WEBRTC_DTMF_DETECTION +// #define WEBRTC_SRTP +// #define WEBRTC_SRTP_ALLOW_ROC_ITERATION + +#endif // WEBRTC_ENGINE_CONFIGURATIONS_H_ diff --git a/src/libs/webrtc/g711/g711.c b/src/libs/webrtc/g711/g711.c new file mode 100644 index 00000000..954f3772 --- /dev/null +++ b/src/libs/webrtc/g711/g711.c @@ -0,0 +1,83 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * g711.c - A-law and u-law transcoding routines + * + * Written by Steve Underwood <steveu@coppice.org> + * + * Copyright (C) 2006 Steve Underwood + * + * Despite my general liking of the GPL, I place this code in the + * public domain for the benefit of all mankind - even the slimy + * ones who might try to proprietize my work and use it to my + * detriment. + * + * $Id: g711.c,v 1.1 2006/06/07 15:46:39 steveu Exp $ + * + * Modifications for WebRtc, 2011/04/28, by tlegrand: + * -Removed unused include files + * -Changed to use WebRtc types + * -Added option to run encoder bitexact with ITU-T reference implementation + */ + +/*! \file */ + +#include "g711.h" +#include "typedefs.h" + +/* Copied from the CCITT G.711 specification */ +static const WebRtc_UWord8 ulaw_to_alaw_table[256] = +{ + 42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37, + 58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53, + 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 26, + 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, 106, + 104, 105, 110, 111, 108, 109, 98, 99, 96, 97, 102, 103, 100, 101, 122, 120, + 126, 127, 124, 125, 114, 115, 112, 113, 118, 119, 116, 117, 75, 73, 79, 77, + 66, 67, 64, 65, 70, 71, 68, 69, 90, 91, 88, 89, 94, 95, 92, 93, + 82, 82, 83, 83, 80, 80, 81, 81, 86, 86, 87, 87, 84, 84, 85, 85, + 170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165, + 186, 187, 184, 185, 190, 191, 188, 189, 178, 179, 176, 177, 182, 183, 180, 181, + 138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154, + 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234, + 232, 233, 238, 239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248, + 254, 255, 252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205, + 194, 195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221, + 210, 210, 211, 211, 208, 208, 209, 209, 214, 214, 215, 215, 212, 212, 213, 213 +}; + +/* These transcoding tables are copied from the CCITT G.711 specification. To achieve + optimal results, do not change them. */ + +static const WebRtc_UWord8 alaw_to_ulaw_table[256] = +{ + 42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37, + 57, 58, 55, 56, 61, 62, 59, 60, 49, 50, 47, 48, 53, 54, 51, 52, + 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 5, + 26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, + 98, 99, 96, 97, 102, 103, 100, 101, 93, 93, 92, 92, 95, 95, 94, 94, + 116, 118, 112, 114, 124, 126, 120, 122, 106, 107, 104, 105, 110, 111, 108, 109, + 72, 73, 70, 71, 76, 77, 74, 75, 64, 65, 63, 63, 68, 69, 66, 67, + 86, 87, 84, 85, 90, 91, 88, 89, 79, 79, 78, 78, 82, 83, 80, 81, + 170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165, + 185, 186, 183, 184, 189, 190, 187, 188, 177, 178, 175, 176, 181, 182, 179, 180, + 138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133, + 154, 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, + 226, 227, 224, 225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222, + 244, 246, 240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237, + 200, 201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195, + 214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208, 209 +}; + +WebRtc_UWord8 alaw_to_ulaw(WebRtc_UWord8 alaw) +{ + return alaw_to_ulaw_table[alaw]; +} +/*- End of function --------------------------------------------------------*/ + +WebRtc_UWord8 ulaw_to_alaw(WebRtc_UWord8 ulaw) +{ + return ulaw_to_alaw_table[ulaw]; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/src/libs/webrtc/g711/g711.h b/src/libs/webrtc/g711/g711.h new file mode 100644 index 00000000..cd5e3d79 --- /dev/null +++ b/src/libs/webrtc/g711/g711.h @@ -0,0 +1,382 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * g711.h - In line A-law and u-law conversion routines + * + * Written by Steve Underwood <steveu@coppice.org> + * + * Copyright (C) 2001 Steve Underwood + * + * Despite my general liking of the GPL, I place this code in the + * public domain for the benefit of all mankind - even the slimy + * ones who might try to proprietize my work and use it to my + * detriment. + * + * $Id: g711.h,v 1.1 2006/06/07 15:46:39 steveu Exp $ + * + * Modifications for WebRtc, 2011/04/28, by tlegrand: + * -Changed to use WebRtc types + * -Changed __inline__ to __inline + * -Two changes to make implementation bitexact with ITU-T reference implementation + */ + +/*! \file */ + +/*! \page g711_page A-law and mu-law handling +Lookup tables for A-law and u-law look attractive, until you consider the impact +on the CPU cache. If it causes a substantial area of your processor cache to get +hit too often, cache sloshing will severely slow things down. The main reason +these routines are slow in C, is the lack of direct access to the CPU's "find +the first 1" instruction. A little in-line assembler fixes that, and the +conversion routines can be faster than lookup tables, in most real world usage. +A "find the first 1" instruction is available on most modern CPUs, and is a +much underused feature. + +If an assembly language method of bit searching is not available, these routines +revert to a method that can be a little slow, so the cache thrashing might not +seem so bad :( + +Feel free to submit patches to add fast "find the first 1" support for your own +favourite processor. + +Look up tables are used for transcoding between A-law and u-law, since it is +difficult to achieve the precise transcoding procedure laid down in the G.711 +specification by other means. +*/ + +#if !defined(_G711_H_) +#define _G711_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "typedefs.h" + +#if defined(__i386__) +/*! \brief Find the bit position of the highest set bit in a word + \param bits The word to be searched + \return The bit number of the highest set bit, or -1 if the word is zero. */ +static __inline__ int top_bit(unsigned int bits) +{ + int res; + + __asm__ __volatile__(" movl $-1,%%edx;\n" + " bsrl %%eax,%%edx;\n" + : "=d" (res) + : "a" (bits)); + return res; +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Find the bit position of the lowest set bit in a word + \param bits The word to be searched + \return The bit number of the lowest set bit, or -1 if the word is zero. */ +static __inline__ int bottom_bit(unsigned int bits) +{ + int res; + + __asm__ __volatile__(" movl $-1,%%edx;\n" + " bsfl %%eax,%%edx;\n" + : "=d" (res) + : "a" (bits)); + return res; +} +/*- End of function --------------------------------------------------------*/ +#elif defined(__x86_64__) +static __inline__ int top_bit(unsigned int bits) +{ + int res; + + __asm__ __volatile__(" movq $-1,%%rdx;\n" + " bsrq %%rax,%%rdx;\n" + : "=d" (res) + : "a" (bits)); + return res; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int bottom_bit(unsigned int bits) +{ + int res; + + __asm__ __volatile__(" movq $-1,%%rdx;\n" + " bsfq %%rax,%%rdx;\n" + : "=d" (res) + : "a" (bits)); + return res; +} +/*- End of function --------------------------------------------------------*/ +#else +static __inline int top_bit(unsigned int bits) +{ + int i; + + if (bits == 0) + return -1; + i = 0; + if (bits & 0xFFFF0000) + { + bits &= 0xFFFF0000; + i += 16; + } + if (bits & 0xFF00FF00) + { + bits &= 0xFF00FF00; + i += 8; + } + if (bits & 0xF0F0F0F0) + { + bits &= 0xF0F0F0F0; + i += 4; + } + if (bits & 0xCCCCCCCC) + { + bits &= 0xCCCCCCCC; + i += 2; + } + if (bits & 0xAAAAAAAA) + { + bits &= 0xAAAAAAAA; + i += 1; + } + return i; +} +/*- End of function --------------------------------------------------------*/ + +static __inline int bottom_bit(unsigned int bits) +{ + int i; + + if (bits == 0) + return -1; + i = 32; + if (bits & 0x0000FFFF) + { + bits &= 0x0000FFFF; + i -= 16; + } + if (bits & 0x00FF00FF) + { + bits &= 0x00FF00FF; + i -= 8; + } + if (bits & 0x0F0F0F0F) + { + bits &= 0x0F0F0F0F; + i -= 4; + } + if (bits & 0x33333333) + { + bits &= 0x33333333; + i -= 2; + } + if (bits & 0x55555555) + { + bits &= 0x55555555; + i -= 1; + } + return i; +} +/*- End of function --------------------------------------------------------*/ +#endif + +/* N.B. It is tempting to use look-up tables for A-law and u-law conversion. + * However, you should consider the cache footprint. + * + * A 64K byte table for linear to x-law and a 512 byte table for x-law to + * linear sound like peanuts these days, and shouldn't an array lookup be + * real fast? No! When the cache sloshes as badly as this one will, a tight + * calculation may be better. The messiest part is normally finding the + * segment, but a little inline assembly can fix that on an i386, x86_64 and + * many other modern processors. + */ + +/* + * Mu-law is basically as follows: + * + * Biased Linear Input Code Compressed Code + * ------------------------ --------------- + * 00000001wxyza 000wxyz + * 0000001wxyzab 001wxyz + * 000001wxyzabc 010wxyz + * 00001wxyzabcd 011wxyz + * 0001wxyzabcde 100wxyz + * 001wxyzabcdef 101wxyz + * 01wxyzabcdefg 110wxyz + * 1wxyzabcdefgh 111wxyz + * + * Each biased linear code has a leading 1 which identifies the segment + * number. The value of the segment number is equal to 7 minus the number + * of leading 0's. The quantization interval is directly available as the + * four bits wxyz. * The trailing bits (a - h) are ignored. + * + * Ordinarily the complement of the resulting code word is used for + * transmission, and so the code word is complemented before it is returned. + * + * For further information see John C. Bellamy's Digital Telephony, 1982, + * John Wiley & Sons, pps 98-111 and 472-476. + */ + +//#define ULAW_ZEROTRAP /* turn on the trap as per the MIL-STD */ +#define ULAW_BIAS 0x84 /* Bias for linear code. */ + +/*! \brief Encode a linear sample to u-law + \param linear The sample to encode. + \return The u-law value. +*/ +static __inline WebRtc_UWord8 linear_to_ulaw(int linear) +{ + WebRtc_UWord8 u_val; + int mask; + int seg; + + /* Get the sign and the magnitude of the value. */ + if (linear < 0) + { + /* WebRtc, tlegrand: -1 added to get bitexact to reference implementation */ + linear = ULAW_BIAS - linear - 1; + mask = 0x7F; + } + else + { + linear = ULAW_BIAS + linear; + mask = 0xFF; + } + + seg = top_bit(linear | 0xFF) - 7; + + /* + * Combine the sign, segment, quantization bits, + * and complement the code word. + */ + if (seg >= 8) + u_val = (WebRtc_UWord8) (0x7F ^ mask); + else + u_val = (WebRtc_UWord8) (((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask); +#ifdef ULAW_ZEROTRAP + /* Optional ITU trap */ + if (u_val == 0) + u_val = 0x02; +#endif + return u_val; +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Decode an u-law sample to a linear value. + \param ulaw The u-law sample to decode. + \return The linear value. +*/ +static __inline WebRtc_Word16 ulaw_to_linear(WebRtc_UWord8 ulaw) +{ + int t; + + /* Complement to obtain normal u-law value. */ + ulaw = ~ulaw; + /* + * Extract and bias the quantization bits. Then + * shift up by the segment number and subtract out the bias. + */ + t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4); + return (WebRtc_Word16) ((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS)); +} +/*- End of function --------------------------------------------------------*/ + +/* + * A-law is basically as follows: + * + * Linear Input Code Compressed Code + * ----------------- --------------- + * 0000000wxyza 000wxyz + * 0000001wxyza 001wxyz + * 000001wxyzab 010wxyz + * 00001wxyzabc 011wxyz + * 0001wxyzabcd 100wxyz + * 001wxyzabcde 101wxyz + * 01wxyzabcdef 110wxyz + * 1wxyzabcdefg 111wxyz + * + * For further information see John C. Bellamy's Digital Telephony, 1982, + * John Wiley & Sons, pps 98-111 and 472-476. + */ + +#define ALAW_AMI_MASK 0x55 + +/*! \brief Encode a linear sample to A-law + \param linear The sample to encode. + \return The A-law value. +*/ +static __inline WebRtc_UWord8 linear_to_alaw(int linear) +{ + int mask; + int seg; + + if (linear >= 0) + { + /* Sign (bit 7) bit = 1 */ + mask = ALAW_AMI_MASK | 0x80; + } + else + { + /* Sign (bit 7) bit = 0 */ + mask = ALAW_AMI_MASK; + /* WebRtc, tlegrand: Changed from -8 to -1 to get bitexact to reference + * implementation */ + linear = -linear - 1; + } + + /* Convert the scaled magnitude to segment number. */ + seg = top_bit(linear | 0xFF) - 7; + if (seg >= 8) + { + if (linear >= 0) + { + /* Out of range. Return maximum value. */ + return (WebRtc_UWord8) (0x7F ^ mask); + } + /* We must be just a tiny step below zero */ + return (WebRtc_UWord8) (0x00 ^ mask); + } + /* Combine the sign, segment, and quantization bits. */ + return (WebRtc_UWord8) (((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask); +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Decode an A-law sample to a linear value. + \param alaw The A-law sample to decode. + \return The linear value. +*/ +static __inline WebRtc_Word16 alaw_to_linear(WebRtc_UWord8 alaw) +{ + int i; + int seg; + + alaw ^= ALAW_AMI_MASK; + i = ((alaw & 0x0F) << 4); + seg = (((int) alaw & 0x70) >> 4); + if (seg) + i = (i + 0x108) << (seg - 1); + else + i += 8; + return (WebRtc_Word16) ((alaw & 0x80) ? i : -i); +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Transcode from A-law to u-law, using the procedure defined in G.711. + \param alaw The A-law sample to transcode. + \return The best matching u-law value. +*/ +WebRtc_UWord8 alaw_to_ulaw(WebRtc_UWord8 alaw); + +/*! \brief Transcode from u-law to A-law, using the procedure defined in G.711. + \param alaw The u-law sample to transcode. + \return The best matching A-law value. +*/ +WebRtc_UWord8 ulaw_to_alaw(WebRtc_UWord8 ulaw); + +#ifdef __cplusplus +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/src/libs/webrtc/g711/g711_interface.c b/src/libs/webrtc/g711/g711_interface.c new file mode 100644 index 00000000..a49abdbe --- /dev/null +++ b/src/libs/webrtc/g711/g711_interface.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include <string.h> +#include "g711.h" +#include "g711_interface.h" +#include "typedefs.h" + +WebRtc_Word16 WebRtcG711_EncodeA(void *state, + WebRtc_Word16 *speechIn, + WebRtc_Word16 len, + WebRtc_Word16 *encoded) +{ + int n; + WebRtc_UWord16 tempVal, tempVal2; + + // Set and discard to avoid getting warnings + (void)(state = NULL); + + // Sanity check of input length + if (len < 0) { + return (-1); + } + + // Loop over all samples + for (n = 0; n < len; n++) { + tempVal = (WebRtc_UWord16)linear_to_alaw(speechIn[n]); + +#ifdef WEBRTC_BIG_ENDIAN + if ((n & 0x1) == 1) { + encoded[n>>1]|=((WebRtc_UWord16)tempVal); + } else { + encoded[n>>1]=((WebRtc_UWord16)tempVal)<<8; + } +#else + if ((n & 0x1) == 1) { + tempVal2 |= ((WebRtc_UWord16) tempVal) << 8; + encoded[n >> 1] |= ((WebRtc_UWord16) tempVal) << 8; + } else { + tempVal2 = ((WebRtc_UWord16) tempVal); + encoded[n >> 1] = ((WebRtc_UWord16) tempVal); + } +#endif + } + return (len); +} + +WebRtc_Word16 WebRtcG711_EncodeU(void *state, + WebRtc_Word16 *speechIn, + WebRtc_Word16 len, + WebRtc_Word16 *encoded) +{ + int n; + WebRtc_UWord16 tempVal; + + // Set and discard to avoid getting warnings + (void)(state = NULL); + + // Sanity check of input length + if (len < 0) { + return (-1); + } + + // Loop over all samples + for (n = 0; n < len; n++) { + tempVal = (WebRtc_UWord16)linear_to_ulaw(speechIn[n]); + + #ifdef WEBRTC_BIG_ENDIAN + if ((n & 0x1) == 1) { + encoded[n>>1]|=((WebRtc_UWord16)tempVal); + } else { + encoded[n>>1]=((WebRtc_UWord16)tempVal)<<8; + } + #else + if ((n & 0x1) == 1) { + encoded[n >> 1] |= ((WebRtc_UWord16) tempVal) << 8; + } else { + encoded[n >> 1] = ((WebRtc_UWord16) tempVal); + } + #endif + } + return (len); +} + +WebRtc_Word16 WebRtcG711_DecodeA(void *state, + WebRtc_Word16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType) +{ + int n; + WebRtc_UWord16 tempVal; + + // Set and discard to avoid getting warnings + (void)(state = NULL); + + // Sanity check of input length + if (len < 0) { + return (-1); + } + + for (n = 0; n < len; n++) { + #ifdef WEBRTC_BIG_ENDIAN + if ((n & 0x1) == 1) { + tempVal=((WebRtc_UWord16)encoded[n>>1] & 0xFF); + } else { + tempVal=((WebRtc_UWord16)encoded[n>>1] >> 8); + } + #else + if ((n & 0x1) == 1) { + tempVal = (encoded[n >> 1] >> 8); + } else { + tempVal = (encoded[n >> 1] & 0xFF); + } + #endif + decoded[n] = (WebRtc_Word16) alaw_to_linear(tempVal); + } + + *speechType = 1; + return (len); +} + +WebRtc_Word16 WebRtcG711_DecodeU(void *state, + WebRtc_Word16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType) +{ + int n; + WebRtc_UWord16 tempVal; + + // Set and discard to avoid getting warnings + (void)(state = NULL); + + // Sanity check of input length + if (len < 0) { + return (-1); + } + + for (n = 0; n < len; n++) { + #ifdef WEBRTC_BIG_ENDIAN + if ((n & 0x1) == 1) { + tempVal=((WebRtc_UWord16)encoded[n>>1] & 0xFF); + } else { + tempVal=((WebRtc_UWord16)encoded[n>>1] >> 8); + } + #else + if ((n & 0x1) == 1) { + tempVal = (encoded[n >> 1] >> 8); + } else { + tempVal = (encoded[n >> 1] & 0xFF); + } + #endif + decoded[n] = (WebRtc_Word16) ulaw_to_linear(tempVal); + } + + *speechType = 1; + return (len); +} + +WebRtc_Word16 WebRtcG711_Version(char* version, WebRtc_Word16 lenBytes) +{ + strncpy(version, "2.0.0", lenBytes); + return 0; +} diff --git a/src/libs/webrtc/g711/g711_interface.h b/src/libs/webrtc/g711/g711_interface.h new file mode 100644 index 00000000..25a99033 --- /dev/null +++ b/src/libs/webrtc/g711/g711_interface.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef MODULES_AUDIO_CODING_CODECS_G711_MAIN_INTERFACE_G711_INTERFACE_H_ +#define MODULES_AUDIO_CODING_CODECS_G711_MAIN_INTERFACE_G711_INTERFACE_H_ + +#include "typedefs.h" + +// Comfort noise constants +#define G711_WEBRTC_SPEECH 1 +#define G711_WEBRTC_CNG 2 + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************************************************************** + * WebRtcG711_EncodeA(...) + * + * This function encodes a G711 A-law frame and inserts it into a packet. + * Input speech length has be of any length. + * + * Input: + * - state : Dummy state to make this codec look more like + * other codecs + * - speechIn : Input speech vector + * - len : Samples in speechIn + * + * Output: + * - encoded : The encoded data vector + * + * Return value : >0 - Length (in bytes) of coded data + * -1 - Error + */ + +WebRtc_Word16 WebRtcG711_EncodeA(void *state, + WebRtc_Word16 *speechIn, + WebRtc_Word16 len, + WebRtc_Word16 *encoded); + +/**************************************************************************** + * WebRtcG711_EncodeU(...) + * + * This function encodes a G711 U-law frame and inserts it into a packet. + * Input speech length has be of any length. + * + * Input: + * - state : Dummy state to make this codec look more like + * other codecs + * - speechIn : Input speech vector + * - len : Samples in speechIn + * + * Output: + * - encoded : The encoded data vector + * + * Return value : >0 - Length (in bytes) of coded data + * -1 - Error + */ + +WebRtc_Word16 WebRtcG711_EncodeU(void *state, + WebRtc_Word16 *speechIn, + WebRtc_Word16 len, + WebRtc_Word16 *encoded); + +/**************************************************************************** + * WebRtcG711_DecodeA(...) + * + * This function decodes a packet G711 A-law frame. + * + * Input: + * - state : Dummy state to make this codec look more like + * other codecs + * - encoded : Encoded data + * - len : Bytes in encoded vector + * + * Output: + * - decoded : The decoded vector + * - speechType : 1 normal, 2 CNG (for G711 it should + * always return 1 since G711 does not have a + * built-in DTX/CNG scheme) + * + * Return value : >0 - Samples in decoded vector + * -1 - Error + */ + +WebRtc_Word16 WebRtcG711_DecodeA(void *state, + WebRtc_Word16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType); + +/**************************************************************************** + * WebRtcG711_DecodeU(...) + * + * This function decodes a packet G711 U-law frame. + * + * Input: + * - state : Dummy state to make this codec look more like + * other codecs + * - encoded : Encoded data + * - len : Bytes in encoded vector + * + * Output: + * - decoded : The decoded vector + * - speechType : 1 normal, 2 CNG (for G711 it should + * always return 1 since G711 does not have a + * built-in DTX/CNG scheme) + * + * Return value : >0 - Samples in decoded vector + * -1 - Error + */ + +WebRtc_Word16 WebRtcG711_DecodeU(void *state, + WebRtc_Word16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType); + +/********************************************************************** +* WebRtcG711_Version(...) +* +* This function gives the version string of the G.711 codec. +* +* Input: +* - lenBytes: the size of Allocated space (in Bytes) where +* the version number is written to (in string format). +* +* Output: +* - version: Pointer to a buffer where the version number is +* written to. +* +*/ + +WebRtc_Word16 WebRtcG711_Version(char* version, WebRtc_Word16 lenBytes); + +#ifdef __cplusplus +} +#endif + + +#endif /* MODULES_AUDIO_CODING_CODECS_G711_MAIN_INTERFACE_G711_INTERFACE_H_ */ diff --git a/src/libs/webrtc/ilbcfix/abs_quant.c b/src/libs/webrtc/ilbcfix/abs_quant.c new file mode 100644 index 00000000..4a70c8b4 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/abs_quant.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_AbsQuant.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "abs_quant_loop.h" + + +/*----------------------------------------------------------------* + * predictive noise shaping encoding of scaled start state + * (subrutine for WebRtcIlbcfix_StateSearch) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_AbsQuant( + iLBC_Enc_Inst_t *iLBCenc_inst, + /* (i) Encoder instance */ + iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits (outputs idxForMax + and idxVec, uses state_first as + input) */ + WebRtc_Word16 *in, /* (i) vector to encode */ + WebRtc_Word16 *weightDenum /* (i) denominator of synthesis filter */ + ) { + WebRtc_Word16 *syntOut; + WebRtc_Word16 quantLen[2]; + + /* Stack based */ + WebRtc_Word16 syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN_30MS]; + WebRtc_Word16 in_weightedVec[STATE_SHORT_LEN_30MS+LPC_FILTERORDER]; + WebRtc_Word16 *in_weighted = &in_weightedVec[LPC_FILTERORDER]; + + /* Initialize the buffers */ + WebRtcSpl_MemSetW16(syntOutBuf, 0, LPC_FILTERORDER+STATE_SHORT_LEN_30MS); + syntOut = &syntOutBuf[LPC_FILTERORDER]; + /* Start with zero state */ + WebRtcSpl_MemSetW16(in_weightedVec, 0, LPC_FILTERORDER); + + /* Perform the quantization loop in two sections of length quantLen[i], + where the perceptual weighting filter is updated at the subframe + border */ + + if (iLBC_encbits->state_first) { + quantLen[0]=SUBL; + quantLen[1]=iLBCenc_inst->state_short_len-SUBL; + } else { + quantLen[0]=iLBCenc_inst->state_short_len-SUBL; + quantLen[1]=SUBL; + } + + /* Calculate the weighted residual, switch perceptual weighting + filter at the subframe border */ + WebRtcSpl_FilterARFastQ12( + in, in_weighted, + weightDenum, LPC_FILTERORDER+1, quantLen[0]); + WebRtcSpl_FilterARFastQ12( + &in[quantLen[0]], &in_weighted[quantLen[0]], + &weightDenum[LPC_FILTERORDER+1], LPC_FILTERORDER+1, quantLen[1]); + + WebRtcIlbcfix_AbsQuantLoop( + syntOut, + in_weighted, + weightDenum, + quantLen, + iLBC_encbits->idxVec); + +} diff --git a/src/libs/webrtc/ilbcfix/abs_quant.h b/src/libs/webrtc/ilbcfix/abs_quant.h new file mode 100644 index 00000000..fa59593c --- /dev/null +++ b/src/libs/webrtc/ilbcfix/abs_quant.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_AbsQuant.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ABS_QUANT_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ABS_QUANT_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * predictive noise shaping encoding of scaled start state + * (subrutine for WebRtcIlbcfix_StateSearch) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_AbsQuant( + iLBC_Enc_Inst_t *iLBCenc_inst, + /* (i) Encoder instance */ + iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits (outputs idxForMax + and idxVec, uses state_first as + input) */ + WebRtc_Word16 *in, /* (i) vector to encode */ + WebRtc_Word16 *weightDenum /* (i) denominator of synthesis filter */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/abs_quant_loop.c b/src/libs/webrtc/ilbcfix/abs_quant_loop.c new file mode 100644 index 00000000..4eebc3e2 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/abs_quant_loop.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_AbsQuantLoop.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "sort_sq.h" + +void WebRtcIlbcfix_AbsQuantLoop( + WebRtc_Word16 *syntOutIN, + WebRtc_Word16 *in_weightedIN, + WebRtc_Word16 *weightDenumIN, + WebRtc_Word16 *quantLenIN, + WebRtc_Word16 *idxVecIN + ) +{ + int n, k1, k2; + WebRtc_Word16 index; + WebRtc_Word32 toQW32; + WebRtc_Word32 toQ32; + WebRtc_Word16 tmp16a; + WebRtc_Word16 xq; + + WebRtc_Word16 *syntOut = syntOutIN; + WebRtc_Word16 *in_weighted = in_weightedIN; + WebRtc_Word16 *weightDenum = weightDenumIN; + WebRtc_Word16 *quantLen = quantLenIN; + WebRtc_Word16 *idxVec = idxVecIN; + + n=0; + + for(k1=0;k1<2;k1++) { + for(k2=0;k2<quantLen[k1];k2++){ + + /* Filter to get the predicted value */ + WebRtcSpl_FilterARFastQ12( + syntOut, syntOut, + weightDenum, LPC_FILTERORDER+1, 1); + + /* the quantizer */ + toQW32 = (WebRtc_Word32)(*in_weighted) - (WebRtc_Word32)(*syntOut); + + toQ32 = (((WebRtc_Word32)toQW32)<<2); + + if (toQ32 > 32767) { + toQ32 = (WebRtc_Word32) 32767; + } else if (toQ32 < -32768) { + toQ32 = (WebRtc_Word32) -32768; + } + + /* Quantize the state */ + if (toQW32<(-7577)) { + /* To prevent negative overflow */ + index=0; + } else if (toQW32>8151) { + /* To prevent positive overflow */ + index=7; + } else { + /* Find the best quantization index + (state_sq3Tbl is in Q13 and toQ is in Q11) + */ + WebRtcIlbcfix_SortSq(&xq, &index, + (WebRtc_Word16)toQ32, + WebRtcIlbcfix_kStateSq3, 8); + } + + /* Store selected index */ + (*idxVec++) = index; + + /* Compute decoded sample and update of the prediction filter */ + tmp16a = ((WebRtcIlbcfix_kStateSq3[index] + 2 ) >> 2); + + *syntOut = (WebRtc_Word16) (tmp16a + (WebRtc_Word32)(*in_weighted) - toQW32); + + n++; + syntOut++; in_weighted++; + } + /* Update perceptual weighting filter at subframe border */ + weightDenum += 11; + } +} diff --git a/src/libs/webrtc/ilbcfix/abs_quant_loop.h b/src/libs/webrtc/ilbcfix/abs_quant_loop.h new file mode 100644 index 00000000..f506e8e6 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/abs_quant_loop.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_AbsQuantLoop.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ABS_QUANT_LOOP_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ABS_QUANT_LOOP_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * predictive noise shaping encoding of scaled start state + * (subrutine for WebRtcIlbcfix_StateSearch) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_AbsQuantLoop( + WebRtc_Word16 *syntOutIN, + WebRtc_Word16 *in_weightedIN, + WebRtc_Word16 *weightDenumIN, + WebRtc_Word16 *quantLenIN, + WebRtc_Word16 *idxVecIN + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/augmented_cb_corr.c b/src/libs/webrtc/ilbcfix/augmented_cb_corr.c new file mode 100644 index 00000000..6011e921 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/augmented_cb_corr.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_AugmentedCbCorr.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "augmented_cb_corr.h" + +void WebRtcIlbcfix_AugmentedCbCorr( + WebRtc_Word16 *target, /* (i) Target vector */ + WebRtc_Word16 *buffer, /* (i) Memory buffer */ + WebRtc_Word16 *interpSamples, /* (i) buffer with + interpolated samples */ + WebRtc_Word32 *crossDot, /* (o) The cross correlation between + the target and the Augmented + vector */ + WebRtc_Word16 low, /* (i) Lag to start from (typically + 20) */ + WebRtc_Word16 high, /* (i) Lag to end at (typically 39) */ + WebRtc_Word16 scale) /* (i) Scale factor to use for + the crossDot */ +{ + int lagcount; + WebRtc_Word16 ilow; + WebRtc_Word16 *targetPtr; + WebRtc_Word32 *crossDotPtr; + WebRtc_Word16 *iSPtr=interpSamples; + + /* Calculate the correlation between the target and the + interpolated codebook. The correlation is calculated in + 3 sections with the interpolated part in the middle */ + crossDotPtr=crossDot; + for (lagcount=low; lagcount<=high; lagcount++) { + + ilow = (WebRtc_Word16) (lagcount-4); + + /* Compute dot product for the first (lagcount-4) samples */ + (*crossDotPtr) = WebRtcSpl_DotProductWithScale(target, buffer-lagcount, ilow, scale); + + /* Compute dot product on the interpolated samples */ + (*crossDotPtr) += WebRtcSpl_DotProductWithScale(target+ilow, iSPtr, 4, scale); + targetPtr = target + lagcount; + iSPtr += lagcount-ilow; + + /* Compute dot product for the remaining samples */ + (*crossDotPtr) += WebRtcSpl_DotProductWithScale(targetPtr, buffer-lagcount, SUBL-lagcount, scale); + crossDotPtr++; + } +} diff --git a/src/libs/webrtc/ilbcfix/augmented_cb_corr.h b/src/libs/webrtc/ilbcfix/augmented_cb_corr.h new file mode 100644 index 00000000..8e097fe1 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/augmented_cb_corr.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_AugmentedCbCorr.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_AUGMENTED_CB_CORR_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_AUGMENTED_CB_CORR_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Calculate correlation between target and Augmented codebooks + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_AugmentedCbCorr( + WebRtc_Word16 *target, /* (i) Target vector */ + WebRtc_Word16 *buffer, /* (i) Memory buffer */ + WebRtc_Word16 *interpSamples, /* (i) buffer with + interpolated samples */ + WebRtc_Word32 *crossDot, /* (o) The cross correlation between + the target and the Augmented + vector */ + WebRtc_Word16 low, /* (i) Lag to start from (typically + 20) */ + WebRtc_Word16 high, /* (i) Lag to end at (typically 39 */ + WebRtc_Word16 scale); /* (i) Scale factor to use for + the crossDot */ + +#endif diff --git a/src/libs/webrtc/ilbcfix/bw_expand.c b/src/libs/webrtc/ilbcfix/bw_expand.c new file mode 100644 index 00000000..a2287aaa --- /dev/null +++ b/src/libs/webrtc/ilbcfix/bw_expand.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_BwExpand.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * lpc bandwidth expansion + *---------------------------------------------------------------*/ + +/* The output is in the same domain as the input */ +void WebRtcIlbcfix_BwExpand( + WebRtc_Word16 *out, /* (o) the bandwidth expanded lpc coefficients */ + WebRtc_Word16 *in, /* (i) the lpc coefficients before bandwidth + expansion */ + WebRtc_Word16 *coef, /* (i) the bandwidth expansion factor Q15 */ + WebRtc_Word16 length /* (i) the length of lpc coefficient vectors */ + ) { + int i; + + out[0] = in[0]; + for (i = 1; i < length; i++) { + /* out[i] = coef[i] * in[i] with rounding. + in[] and out[] are in Q12 and coef[] is in Q15 + */ + out[i] = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16(coef[i], in[i])+16384)>>15); + } +} diff --git a/src/libs/webrtc/ilbcfix/bw_expand.h b/src/libs/webrtc/ilbcfix/bw_expand.h new file mode 100644 index 00000000..c9f3fabe --- /dev/null +++ b/src/libs/webrtc/ilbcfix/bw_expand.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_BwExpand.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_BW_EXPAND_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_BW_EXPAND_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * lpc bandwidth expansion + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_BwExpand( + WebRtc_Word16 *out, /* (o) the bandwidth expanded lpc coefficients */ + WebRtc_Word16 *in, /* (i) the lpc coefficients before bandwidth + expansion */ + WebRtc_Word16 *coef, /* (i) the bandwidth expansion factor Q15 */ + WebRtc_Word16 length /* (i) the length of lpc coefficient vectors */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/cb_construct.c b/src/libs/webrtc/ilbcfix/cb_construct.c new file mode 100644 index 00000000..094a7e40 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_construct.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbConstruct.c + +******************************************************************/ + +#include "defines.h" +#include "gain_dequant.h" +#include "get_cd_vec.h" + +/*----------------------------------------------------------------* + * Construct decoded vector from codebook and gains. + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_CbConstruct( + WebRtc_Word16 *decvector, /* (o) Decoded vector */ + WebRtc_Word16 *index, /* (i) Codebook indices */ + WebRtc_Word16 *gain_index, /* (i) Gain quantization indices */ + WebRtc_Word16 *mem, /* (i) Buffer for codevector construction */ + WebRtc_Word16 lMem, /* (i) Length of buffer */ + WebRtc_Word16 veclen /* (i) Length of vector */ + ){ + int j; + WebRtc_Word16 gain[CB_NSTAGES]; + /* Stack based */ + WebRtc_Word16 cbvec0[SUBL]; + WebRtc_Word16 cbvec1[SUBL]; + WebRtc_Word16 cbvec2[SUBL]; + WebRtc_Word32 a32; + WebRtc_Word16 *gainPtr; + + /* gain de-quantization */ + + gain[0] = WebRtcIlbcfix_GainDequant(gain_index[0], 16384, 0); + gain[1] = WebRtcIlbcfix_GainDequant(gain_index[1], gain[0], 1); + gain[2] = WebRtcIlbcfix_GainDequant(gain_index[2], gain[1], 2); + + /* codebook vector construction and construction of total vector */ + + /* Stack based */ + WebRtcIlbcfix_GetCbVec(cbvec0, mem, index[0], lMem, veclen); + WebRtcIlbcfix_GetCbVec(cbvec1, mem, index[1], lMem, veclen); + WebRtcIlbcfix_GetCbVec(cbvec2, mem, index[2], lMem, veclen); + + gainPtr = &gain[0]; + for (j=0;j<veclen;j++) { + a32 = WEBRTC_SPL_MUL_16_16(*gainPtr++, cbvec0[j]); + a32 += WEBRTC_SPL_MUL_16_16(*gainPtr++, cbvec1[j]); + a32 += WEBRTC_SPL_MUL_16_16(*gainPtr, cbvec2[j]); + gainPtr -= 2; + decvector[j] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(a32 + 8192, 14); + } + + return; +} diff --git a/src/libs/webrtc/ilbcfix/cb_construct.h b/src/libs/webrtc/ilbcfix/cb_construct.h new file mode 100644 index 00000000..bec759f2 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_construct.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbConstruct.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_CONSTRUCT_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_CONSTRUCT_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Construct decoded vector from codebook and gains. + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_CbConstruct( + WebRtc_Word16 *decvector, /* (o) Decoded vector */ + WebRtc_Word16 *index, /* (i) Codebook indices */ + WebRtc_Word16 *gain_index, /* (i) Gain quantization indices */ + WebRtc_Word16 *mem, /* (i) Buffer for codevector construction */ + WebRtc_Word16 lMem, /* (i) Length of buffer */ + WebRtc_Word16 veclen /* (i) Length of vector */ + ); + + +#endif diff --git a/src/libs/webrtc/ilbcfix/cb_mem_energy.c b/src/libs/webrtc/ilbcfix/cb_mem_energy.c new file mode 100644 index 00000000..8613fa2f --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_mem_energy.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbMemEnergy.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "cb_mem_energy_calc.h" + +/*----------------------------------------------------------------* + * Function WebRtcIlbcfix_CbMemEnergy computes the energy of all + * the vectors in the codebook memory that will be used in the + * following search for the best match. + *----------------------------------------------------------------*/ + +void WebRtcIlbcfix_CbMemEnergy( + WebRtc_Word16 range, + WebRtc_Word16 *CB, /* (i) The CB memory (1:st section) */ + WebRtc_Word16 *filteredCB, /* (i) The filtered CB memory (2:nd section) */ + WebRtc_Word16 lMem, /* (i) Length of the CB memory */ + WebRtc_Word16 lTarget, /* (i) Length of the target vector */ + WebRtc_Word16 *energyW16, /* (o) Energy in the CB vectors */ + WebRtc_Word16 *energyShifts, /* (o) Shift value of the energy */ + WebRtc_Word16 scale, /* (i) The scaling of all energy values */ + WebRtc_Word16 base_size /* (i) Index to where the energy values should be stored */ + ) { + WebRtc_Word16 *ppi, *ppo, *pp; + WebRtc_Word32 energy, tmp32; + + /* Compute the energy and store it in a vector. Also the + * corresponding shift values are stored. The energy values + * are reused in all three stages. */ + + /* Calculate the energy in the first block of 'lTarget' sampels. */ + ppi = CB+lMem-lTarget-1; + ppo = CB+lMem-1; + + pp=CB+lMem-lTarget; + energy = WebRtcSpl_DotProductWithScale( pp, pp, lTarget, scale); + + /* Normalize the energy and store the number of shifts */ + energyShifts[0] = (WebRtc_Word16)WebRtcSpl_NormW32(energy); + tmp32 = WEBRTC_SPL_LSHIFT_W32(energy, energyShifts[0]); + energyW16[0] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 16); + + /* Compute the energy of the rest of the cb memory + * by step wise adding and subtracting the next + * sample and the last sample respectively. */ + WebRtcIlbcfix_CbMemEnergyCalc(energy, range, ppi, ppo, energyW16, energyShifts, scale, 0); + + /* Next, precompute the energy values for the filtered cb section */ + energy=0; + pp=filteredCB+lMem-lTarget; + + energy = WebRtcSpl_DotProductWithScale( pp, pp, lTarget, scale); + + /* Normalize the energy and store the number of shifts */ + energyShifts[base_size] = (WebRtc_Word16)WebRtcSpl_NormW32(energy); + tmp32 = WEBRTC_SPL_LSHIFT_W32(energy, energyShifts[base_size]); + energyW16[base_size] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 16); + + ppi = filteredCB + lMem - 1 - lTarget; + ppo = filteredCB + lMem - 1; + + WebRtcIlbcfix_CbMemEnergyCalc(energy, range, ppi, ppo, energyW16, energyShifts, scale, base_size); +} diff --git a/src/libs/webrtc/ilbcfix/cb_mem_energy.h b/src/libs/webrtc/ilbcfix/cb_mem_energy.h new file mode 100644 index 00000000..1aa2b7b7 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_mem_energy.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbMemEnergy.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_MEM_ENERGY_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_MEM_ENERGY_H_ + +void WebRtcIlbcfix_CbMemEnergy( + WebRtc_Word16 range, + WebRtc_Word16 *CB, /* (i) The CB memory (1:st section) */ + WebRtc_Word16 *filteredCB, /* (i) The filtered CB memory (2:nd section) */ + WebRtc_Word16 lMem, /* (i) Length of the CB memory */ + WebRtc_Word16 lTarget, /* (i) Length of the target vector */ + WebRtc_Word16 *energyW16, /* (o) Energy in the CB vectors */ + WebRtc_Word16 *energyShifts, /* (o) Shift value of the energy */ + WebRtc_Word16 scale, /* (i) The scaling of all energy values */ + WebRtc_Word16 base_size /* (i) Index to where the energy values should be stored */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/cb_mem_energy_augmentation.c b/src/libs/webrtc/ilbcfix/cb_mem_energy_augmentation.c new file mode 100644 index 00000000..0c6f479e --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_mem_energy_augmentation.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbMemEnergyAugmentation.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +void WebRtcIlbcfix_CbMemEnergyAugmentation( + WebRtc_Word16 *interpSamples, /* (i) The interpolated samples */ + WebRtc_Word16 *CBmem, /* (i) The CB memory */ + WebRtc_Word16 scale, /* (i) The scaling of all energy values */ + WebRtc_Word16 base_size, /* (i) Index to where the energy values should be stored */ + WebRtc_Word16 *energyW16, /* (o) Energy in the CB vectors */ + WebRtc_Word16 *energyShifts /* (o) Shift value of the energy */ + ){ + WebRtc_Word32 energy, tmp32; + WebRtc_Word16 *ppe, *pp, *interpSamplesPtr; + WebRtc_Word16 *CBmemPtr, lagcount; + WebRtc_Word16 *enPtr=&energyW16[base_size-20]; + WebRtc_Word16 *enShPtr=&energyShifts[base_size-20]; + WebRtc_Word32 nrjRecursive; + + CBmemPtr = CBmem+147; + interpSamplesPtr = interpSamples; + + /* Compute the energy for the first (low-5) noninterpolated samples */ + nrjRecursive = WebRtcSpl_DotProductWithScale( CBmemPtr-19, CBmemPtr-19, 15, scale); + ppe = CBmemPtr - 20; + + for (lagcount=20; lagcount<=39; lagcount++) { + + /* Update the energy recursively to save complexity */ + nrjRecursive = nrjRecursive + + WEBRTC_SPL_MUL_16_16_RSFT(*ppe, *ppe, scale); + ppe--; + energy = nrjRecursive; + + /* interpolation */ + energy += WebRtcSpl_DotProductWithScale(interpSamplesPtr, interpSamplesPtr, 4, scale); + interpSamplesPtr += 4; + + /* Compute energy for the remaining samples */ + pp = CBmemPtr - lagcount; + energy += WebRtcSpl_DotProductWithScale(pp, pp, SUBL-lagcount, scale); + + /* Normalize the energy and store the number of shifts */ + (*enShPtr) = (WebRtc_Word16)WebRtcSpl_NormW32(energy); + tmp32 = WEBRTC_SPL_LSHIFT_W32(energy, (*enShPtr)); + (*enPtr) = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 16); + enShPtr++; + enPtr++; + } +} diff --git a/src/libs/webrtc/ilbcfix/cb_mem_energy_augmentation.h b/src/libs/webrtc/ilbcfix/cb_mem_energy_augmentation.h new file mode 100644 index 00000000..938b87e8 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_mem_energy_augmentation.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbMemEnergyAugmentation.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_MEM_ENERGY_AUGMENTATION_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_MEM_ENERGY_AUGMENTATION_H_ + +void WebRtcIlbcfix_CbMemEnergyAugmentation( + WebRtc_Word16 *interpSamples, /* (i) The interpolated samples */ + WebRtc_Word16 *CBmem, /* (i) The CB memory */ + WebRtc_Word16 scale, /* (i) The scaling of all energy values */ + WebRtc_Word16 base_size, /* (i) Index to where the energy values should be stored */ + WebRtc_Word16 *energyW16, /* (o) Energy in the CB vectors */ + WebRtc_Word16 *energyShifts /* (o) Shift value of the energy */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/cb_mem_energy_calc.c b/src/libs/webrtc/ilbcfix/cb_mem_energy_calc.c new file mode 100644 index 00000000..40bb708c --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_mem_energy_calc.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbMemEnergyCalc.c + +******************************************************************/ + +#include "defines.h" + +/* Compute the energy of the rest of the cb memory + * by step wise adding and subtracting the next + * sample and the last sample respectively */ +void WebRtcIlbcfix_CbMemEnergyCalc( + WebRtc_Word32 energy, /* (i) input start energy */ + WebRtc_Word16 range, /* (i) number of iterations */ + WebRtc_Word16 *ppi, /* (i) input pointer 1 */ + WebRtc_Word16 *ppo, /* (i) input pointer 2 */ + WebRtc_Word16 *energyW16, /* (o) Energy in the CB vectors */ + WebRtc_Word16 *energyShifts, /* (o) Shift value of the energy */ + WebRtc_Word16 scale, /* (i) The scaling of all energy values */ + WebRtc_Word16 base_size /* (i) Index to where the energy values should be stored */ + ) +{ + WebRtc_Word16 j,shft; + WebRtc_Word32 tmp; + WebRtc_Word16 *eSh_ptr; + WebRtc_Word16 *eW16_ptr; + + + eSh_ptr = &energyShifts[1+base_size]; + eW16_ptr = &energyW16[1+base_size]; + + for(j=0;j<range-1;j++) { + + /* Calculate next energy by a +/- + operation on the edge samples */ + tmp = WEBRTC_SPL_MUL_16_16(*ppi, *ppi); + tmp -= WEBRTC_SPL_MUL_16_16(*ppo, *ppo); + energy += WEBRTC_SPL_RSHIFT_W32(tmp, scale); + energy = WEBRTC_SPL_MAX(energy, 0); + + ppi--; + ppo--; + + /* Normalize the energy into a WebRtc_Word16 and store + the number of shifts */ + + shft = (WebRtc_Word16)WebRtcSpl_NormW32(energy); + *eSh_ptr++ = shft; + + tmp = WEBRTC_SPL_LSHIFT_W32(energy, shft); + *eW16_ptr++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp, 16); + } +} diff --git a/src/libs/webrtc/ilbcfix/cb_mem_energy_calc.h b/src/libs/webrtc/ilbcfix/cb_mem_energy_calc.h new file mode 100644 index 00000000..ee2e285b --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_mem_energy_calc.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbMemEnergyCalc.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_MEM_ENERGY_CALC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_MEM_ENERGY_CALC_H_ + +void WebRtcIlbcfix_CbMemEnergyCalc( + WebRtc_Word32 energy, /* (i) input start energy */ + WebRtc_Word16 range, /* (i) number of iterations */ + WebRtc_Word16 *ppi, /* (i) input pointer 1 */ + WebRtc_Word16 *ppo, /* (i) input pointer 2 */ + WebRtc_Word16 *energyW16, /* (o) Energy in the CB vectors */ + WebRtc_Word16 *energyShifts, /* (o) Shift value of the energy */ + WebRtc_Word16 scale, /* (i) The scaling of all energy values */ + WebRtc_Word16 base_size /* (i) Index to where the energy values should be stored */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/cb_search.h b/src/libs/webrtc/ilbcfix/cb_search.h new file mode 100644 index 00000000..e4ad4b5b --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_search.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbSearch.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_SEARCH_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_SEARCH_H_ + +void WebRtcIlbcfix_CbSearch( + iLBC_Enc_Inst_t *iLBCenc_inst, + /* (i) the encoder state structure */ + WebRtc_Word16 *index, /* (o) Codebook indices */ + WebRtc_Word16 *gain_index, /* (o) Gain quantization indices */ + WebRtc_Word16 *intarget, /* (i) Target vector for encoding */ + WebRtc_Word16 *decResidual,/* (i) Decoded residual for codebook construction */ + WebRtc_Word16 lMem, /* (i) Length of buffer */ + WebRtc_Word16 lTarget, /* (i) Length of vector */ + WebRtc_Word16 *weightDenum,/* (i) weighting filter coefficients in Q12 */ + WebRtc_Word16 block /* (i) the subblock number */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/cb_search_core.c b/src/libs/webrtc/ilbcfix/cb_search_core.c new file mode 100644 index 00000000..711e2df4 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_search_core.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbSearchCore.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +void WebRtcIlbcfix_CbSearchCore( + WebRtc_Word32 *cDot, /* (i) Cross Correlation */ + WebRtc_Word16 range, /* (i) Search range */ + WebRtc_Word16 stage, /* (i) Stage of this search */ + WebRtc_Word16 *inverseEnergy, /* (i) Inversed energy */ + WebRtc_Word16 *inverseEnergyShift, /* (i) Shifts of inversed energy + with the offset 2*16-29 */ + WebRtc_Word32 *Crit, /* (o) The criteria */ + WebRtc_Word16 *bestIndex, /* (o) Index that corresponds to + maximum criteria (in this + vector) */ + WebRtc_Word32 *bestCrit, /* (o) Value of critera for the + chosen index */ + WebRtc_Word16 *bestCritSh) /* (o) The domain of the chosen + criteria */ +{ + WebRtc_Word32 maxW32, tmp32; + WebRtc_Word16 max, sh, tmp16; + int i; + WebRtc_Word32 *cDotPtr; + WebRtc_Word16 cDotSqW16; + WebRtc_Word16 *inverseEnergyPtr; + WebRtc_Word32 *critPtr; + WebRtc_Word16 *inverseEnergyShiftPtr; + + /* Don't allow negative values for stage 0 */ + if (stage==0) { + cDotPtr=cDot; + for (i=0;i<range;i++) { + *cDotPtr=WEBRTC_SPL_MAX(0, (*cDotPtr)); + cDotPtr++; + } + } + + /* Normalize cDot to WebRtc_Word16, calculate the square of cDot and store the upper WebRtc_Word16 */ + maxW32 = WebRtcSpl_MaxAbsValueW32(cDot, range); + + sh = (WebRtc_Word16)WebRtcSpl_NormW32(maxW32); + cDotPtr = cDot; + inverseEnergyPtr = inverseEnergy; + critPtr = Crit; + inverseEnergyShiftPtr=inverseEnergyShift; + max=WEBRTC_SPL_WORD16_MIN; + + for (i=0;i<range;i++) { + /* Calculate cDot*cDot and put the result in a WebRtc_Word16 */ + tmp32 = WEBRTC_SPL_LSHIFT_W32(*cDotPtr,sh); + tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32,16); + cDotSqW16 = (WebRtc_Word16)(((WebRtc_Word32)(tmp16)*(tmp16))>>16); + + /* Calculate the criteria (cDot*cDot/energy) */ + *critPtr=WEBRTC_SPL_MUL_16_16(cDotSqW16, (*inverseEnergyPtr)); + + /* Extract the maximum shift value under the constraint + that the criteria is not zero */ + if ((*critPtr)!=0) { + max = WEBRTC_SPL_MAX((*inverseEnergyShiftPtr), max); + } + + inverseEnergyPtr++; + inverseEnergyShiftPtr++; + critPtr++; + cDotPtr++; + } + + /* If no max shifts still at initialization value, set shift to zero */ + if (max==WEBRTC_SPL_WORD16_MIN) { + max = 0; + } + + /* Modify the criterias, so that all of them use the same Q domain */ + critPtr=Crit; + inverseEnergyShiftPtr=inverseEnergyShift; + for (i=0;i<range;i++) { + /* Guarantee that the shift value is less than 16 + in order to simplify for DSP's (and guard against >31) */ + tmp16 = WEBRTC_SPL_MIN(16, max-(*inverseEnergyShiftPtr)); + + (*critPtr)=WEBRTC_SPL_SHIFT_W32((*critPtr),-tmp16); + critPtr++; + inverseEnergyShiftPtr++; + } + + /* Find the index of the best value */ + *bestIndex = WebRtcSpl_MaxIndexW32(Crit, range); + *bestCrit = Crit[*bestIndex]; + + /* Calculate total shifts of this criteria */ + *bestCritSh = 32 - 2*sh + max; + + return; +} diff --git a/src/libs/webrtc/ilbcfix/cb_search_core.h b/src/libs/webrtc/ilbcfix/cb_search_core.h new file mode 100644 index 00000000..e074c526 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_search_core.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbSearchCore.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_SEARCH_CORE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_SEARCH_CORE_H_ + +#include "defines.h" + +void WebRtcIlbcfix_CbSearchCore( + WebRtc_Word32 *cDot, /* (i) Cross Correlation */ + WebRtc_Word16 range, /* (i) Search range */ + WebRtc_Word16 stage, /* (i) Stage of this search */ + WebRtc_Word16 *inverseEnergy, /* (i) Inversed energy */ + WebRtc_Word16 *inverseEnergyShift, /* (i) Shifts of inversed energy + with the offset 2*16-29 */ + WebRtc_Word32 *Crit, /* (o) The criteria */ + WebRtc_Word16 *bestIndex, /* (o) Index that corresponds to + maximum criteria (in this + vector) */ + WebRtc_Word32 *bestCrit, /* (o) Value of critera for the + chosen index */ + WebRtc_Word16 *bestCritSh); /* (o) The domain of the chosen + criteria */ + +#endif diff --git a/src/libs/webrtc/ilbcfix/cb_update_best_index.c b/src/libs/webrtc/ilbcfix/cb_update_best_index.c new file mode 100644 index 00000000..bf854085 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_update_best_index.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbUpdateBestIndex.c + +******************************************************************/ + +#include "defines.h" +#include "cb_update_best_index.h" +#include "constants.h" + +void WebRtcIlbcfix_CbUpdateBestIndex( + WebRtc_Word32 CritNew, /* (i) New Potentially best Criteria */ + WebRtc_Word16 CritNewSh, /* (i) Shift value of above Criteria */ + WebRtc_Word16 IndexNew, /* (i) Index of new Criteria */ + WebRtc_Word32 cDotNew, /* (i) Cross dot of new index */ + WebRtc_Word16 invEnergyNew, /* (i) Inversed energy new index */ + WebRtc_Word16 energyShiftNew, /* (i) Energy shifts of new index */ + WebRtc_Word32 *CritMax, /* (i/o) Maximum Criteria (so far) */ + WebRtc_Word16 *shTotMax, /* (i/o) Shifts of maximum criteria */ + WebRtc_Word16 *bestIndex, /* (i/o) Index that corresponds to + maximum criteria */ + WebRtc_Word16 *bestGain) /* (i/o) Gain in Q14 that corresponds + to maximum criteria */ +{ + WebRtc_Word16 shOld, shNew, tmp16; + WebRtc_Word16 scaleTmp; + WebRtc_Word32 gainW32; + + /* Normalize the new and old Criteria to the same domain */ + if (CritNewSh>(*shTotMax)) { + shOld=WEBRTC_SPL_MIN(31,CritNewSh-(*shTotMax)); + shNew=0; + } else { + shOld=0; + shNew=WEBRTC_SPL_MIN(31,(*shTotMax)-CritNewSh); + } + + /* Compare the two criterias. If the new one is better, + calculate the gain and store this index as the new best one + */ + + if (WEBRTC_SPL_RSHIFT_W32(CritNew, shNew)> + WEBRTC_SPL_RSHIFT_W32((*CritMax),shOld)) { + + tmp16 = (WebRtc_Word16)WebRtcSpl_NormW32(cDotNew); + tmp16 = 16 - tmp16; + + /* Calculate the gain in Q14 + Compensate for inverseEnergyshift in Q29 and that the energy + value was stored in a WebRtc_Word16 (shifted down 16 steps) + => 29-14+16 = 31 */ + + scaleTmp = -energyShiftNew-tmp16+31; + scaleTmp = WEBRTC_SPL_MIN(31, scaleTmp); + + gainW32 = WEBRTC_SPL_MUL_16_16_RSFT( + ((WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(cDotNew, -tmp16)), invEnergyNew, scaleTmp); + + /* Check if criteria satisfies Gain criteria (max 1.3) + if it is larger set the gain to 1.3 + (slightly different from FLP version) + */ + if (gainW32>21299) { + *bestGain=21299; + } else if (gainW32<-21299) { + *bestGain=-21299; + } else { + *bestGain=(WebRtc_Word16)gainW32; + } + + *CritMax=CritNew; + *shTotMax=CritNewSh; + *bestIndex = IndexNew; + } + + return; +} diff --git a/src/libs/webrtc/ilbcfix/cb_update_best_index.h b/src/libs/webrtc/ilbcfix/cb_update_best_index.h new file mode 100644 index 00000000..90151876 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/cb_update_best_index.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbUpdateBestIndex.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_UPDATE_BEST_INDEX_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_UPDATE_BEST_INDEX_H_ + +#include "defines.h" + +void WebRtcIlbcfix_CbUpdateBestIndex( + WebRtc_Word32 CritNew, /* (i) New Potentially best Criteria */ + WebRtc_Word16 CritNewSh, /* (i) Shift value of above Criteria */ + WebRtc_Word16 IndexNew, /* (i) Index of new Criteria */ + WebRtc_Word32 cDotNew, /* (i) Cross dot of new index */ + WebRtc_Word16 invEnergyNew, /* (i) Inversed energy new index */ + WebRtc_Word16 energyShiftNew, /* (i) Energy shifts of new index */ + WebRtc_Word32 *CritMax, /* (i/o) Maximum Criteria (so far) */ + WebRtc_Word16 *shTotMax, /* (i/o) Shifts of maximum criteria */ + WebRtc_Word16 *bestIndex, /* (i/o) Index that corresponds to + maximum criteria */ + WebRtc_Word16 *bestGain); /* (i/o) Gain in Q14 that corresponds + to maximum criteria */ + +#endif diff --git a/src/libs/webrtc/ilbcfix/chebyshev.c b/src/libs/webrtc/ilbcfix/chebyshev.c new file mode 100644 index 00000000..90108ffd --- /dev/null +++ b/src/libs/webrtc/ilbcfix/chebyshev.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Chebyshev.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*------------------------------------------------------------------* + * Calculate the Chevyshev polynomial series + * F(w) = 2*exp(-j5w)*C(x) + * C(x) = (T_0(x) + f(1)T_1(x) + ... + f(4)T_1(x) + f(5)/2) + * T_i(x) is the i:th order Chebyshev polynomial + *------------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_Chebyshev( + /* (o) Result of C(x) */ + WebRtc_Word16 x, /* (i) Value to the Chevyshev polynomial */ + WebRtc_Word16 *f /* (i) The coefficients in the polynomial */ + ) { + WebRtc_Word16 b1_high, b1_low; /* Use the high, low format to increase the accuracy */ + WebRtc_Word32 b2; + WebRtc_Word32 tmp1W32; + WebRtc_Word32 tmp2W32; + int i; + + b2 = (WebRtc_Word32)0x1000000; /* b2 = 1.0 (Q23) */ + /* Calculate b1 = 2*x + f[1] */ + tmp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)x, 10); + tmp1W32 += WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)f[1], 14); + + for (i = 2; i < 5; i++) { + tmp2W32 = tmp1W32; + + /* Split b1 (in tmp1W32) into a high and low part */ + b1_high = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp1W32, 16); + b1_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp1W32-WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)b1_high),16), 1); + + /* Calculate 2*x*b1-b2+f[i] */ + tmp1W32 = WEBRTC_SPL_LSHIFT_W32( (WEBRTC_SPL_MUL_16_16(b1_high, x) + + WEBRTC_SPL_MUL_16_16_RSFT(b1_low, x, 15)), 2); + + tmp1W32 -= b2; + tmp1W32 += WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)f[i], 14); + + /* Update b2 for next round */ + b2 = tmp2W32; + } + + /* Split b1 (in tmp1W32) into a high and low part */ + b1_high = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp1W32, 16); + b1_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp1W32-WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)b1_high),16), 1); + + /* tmp1W32 = x*b1 - b2 + f[i]/2 */ + tmp1W32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(b1_high, x), 1) + + WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16_RSFT(b1_low, x, 15), 1); + + tmp1W32 -= b2; + tmp1W32 += WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)f[i], 13); + + /* Handle overflows and set to maximum or minimum WebRtc_Word16 instead */ + if (tmp1W32>((WebRtc_Word32)33553408)) { + return(WEBRTC_SPL_WORD16_MAX); + } else if (tmp1W32<((WebRtc_Word32)-33554432)) { + return(WEBRTC_SPL_WORD16_MIN); + } else { + return((WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp1W32, 10)); + } +} diff --git a/src/libs/webrtc/ilbcfix/chebyshev.h b/src/libs/webrtc/ilbcfix/chebyshev.h new file mode 100644 index 00000000..57aab99e --- /dev/null +++ b/src/libs/webrtc/ilbcfix/chebyshev.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Chebyshev.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CHEBYSHEV_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CHEBYSHEV_H_ + +#include "defines.h" + +/*------------------------------------------------------------------* + * Calculate the Chevyshev polynomial series + * F(w) = 2*exp(-j5w)*C(x) + * C(x) = (T_0(x) + f(1)T_1(x) + ... + f(4)T_1(x) + f(5)/2) + * T_i(x) is the i:th order Chebyshev polynomial + *------------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_Chebyshev( + /* (o) Result of C(x) */ + WebRtc_Word16 x, /* (i) Value to the Chevyshev polynomial */ + WebRtc_Word16 *f /* (i) The coefficients in the polynomial */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/comp_corr.c b/src/libs/webrtc/ilbcfix/comp_corr.c new file mode 100644 index 00000000..3d7f93ea --- /dev/null +++ b/src/libs/webrtc/ilbcfix/comp_corr.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CompCorr.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Compute cross correlation and pitch gain for pitch prediction + * of last subframe at given lag. + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_CompCorr( + WebRtc_Word32 *corr, /* (o) cross correlation */ + WebRtc_Word32 *ener, /* (o) energy */ + WebRtc_Word16 *buffer, /* (i) signal buffer */ + WebRtc_Word16 lag, /* (i) pitch lag */ + WebRtc_Word16 bLen, /* (i) length of buffer */ + WebRtc_Word16 sRange, /* (i) correlation search length */ + WebRtc_Word16 scale /* (i) number of rightshifts to use */ + ){ + WebRtc_Word16 *w16ptr; + + w16ptr=&buffer[bLen-sRange-lag]; + + /* Calculate correlation and energy */ + (*corr)=WebRtcSpl_DotProductWithScale(&buffer[bLen-sRange], w16ptr, sRange, scale); + (*ener)=WebRtcSpl_DotProductWithScale(w16ptr, w16ptr, sRange, scale); + + /* For zero energy set the energy to 0 in order to avoid potential + problems for coming divisions */ + if (*ener == 0) { + *corr = 0; + *ener = 1; + } +} diff --git a/src/libs/webrtc/ilbcfix/comp_corr.h b/src/libs/webrtc/ilbcfix/comp_corr.h new file mode 100644 index 00000000..cd465322 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/comp_corr.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CompCorr.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_COMP_CORR_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_COMP_CORR_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Compute cross correlation and pitch gain for pitch prediction + * of last subframe at given lag. + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_CompCorr( + WebRtc_Word32 *corr, /* (o) cross correlation */ + WebRtc_Word32 *ener, /* (o) energy */ + WebRtc_Word16 *buffer, /* (i) signal buffer */ + WebRtc_Word16 lag, /* (i) pitch lag */ + WebRtc_Word16 bLen, /* (i) length of buffer */ + WebRtc_Word16 sRange, /* (i) correlation search length */ + WebRtc_Word16 scale /* (i) number of rightshifts to use */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/complexityMeasures.m b/src/libs/webrtc/ilbcfix/complexityMeasures.m new file mode 100644 index 00000000..f7681945 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/complexityMeasures.m @@ -0,0 +1,49 @@ +clear; +pack; +% +% Enter the path to YOUR executable and remember to define the perprocessor +% variable PRINT_MIPS te get the instructions printed to the screen. +% +command = '!iLBCtest.exe 30 speechAndBGnoise.pcm out1.bit out1.pcm tlm10_30ms.dat'; +cout=' > st.txt'; %saves to matlab variable 'st' +eval(strcat(command,cout)); +if(length(cout)>3) + load st.txt +else + disp('No cout file to load') +end + +% initialize vector to zero +index = find(st(1:end,1)==-1); +indexnonzero = find(st(1:end,1)>0); +frames = length(index)-indexnonzero(1)+1; +start = indexnonzero(1) - 1; +functionOrder=max(st(:,2)); +new=zeros(frames,functionOrder); + +for i = 1:frames, + for j = index(start-1+i)+1:(index(start+i)-1), + new(i,st(j,2)) = new(i,st(j,2)) + st(j,1); + end +end + +result=zeros(functionOrder,3); +for i=1:functionOrder + nonzeroelements = find(new(1:end,i)>0); + result(i,1)=i; + + % Compute each function's mean complexity + % result(i,2)=(sum(new(nonzeroelements,i))/(length(nonzeroelements)*0.03))/1000000; + + % Compute each function's maximum complexity in encoding + % and decoding respectively and then add it together: + % result(i,3)=(max(new(1:end,i))/0.03)/1000000; + result(i,3)=(max(new(1:size(new,1)/2,i))/0.03)/1000000 + (max(new(size(new,1)/2+1:end,i))/0.03)/1000000; +end + +result + +% Compute maximum complexity for a single frame (enc/dec separately and together) +maxEncComplexityInAFrame = (max(sum(new(1:size(new,1)/2,:),2))/0.03)/1000000 +maxDecComplexityInAFrame = (max(sum(new(size(new,1)/2+1:end,:),2))/0.03)/1000000 +totalComplexity = maxEncComplexityInAFrame + maxDecComplexityInAFrame \ No newline at end of file diff --git a/src/libs/webrtc/ilbcfix/constants.h b/src/libs/webrtc/ilbcfix/constants.h new file mode 100644 index 00000000..f787f743 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/constants.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + constants.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CONSTANTS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CONSTANTS_H_ + +#include "defines.h" +#include "typedefs.h" + +/* high pass filters */ + +extern const WebRtc_Word16 WebRtcIlbcfix_kHpInCoefs[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kHpOutCoefs[]; + +/* Window for start state decision */ +extern const WebRtc_Word16 WebRtcIlbcfix_kStartSequenceEnrgWin[]; + +/* low pass filter used for downsampling */ +extern const WebRtc_Word16 WebRtcIlbcfix_kLpFiltCoefs[]; + +/* LPC analysis and quantization */ + +extern const WebRtc_Word16 WebRtcIlbcfix_kLpcWin[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kLpcAsymWin[]; +extern const WebRtc_Word32 WebRtcIlbcfix_kLpcLagWin[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kLpcChirpSyntDenum[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kLpcChirpWeightDenum[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kLsfDimCb[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kLsfSizeCb[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kLsfCb[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kLsfWeight20ms[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kLsfWeight30ms[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kLsfMean[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kLspMean[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kCos[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kCosDerivative[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kCosGrid[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kAcosDerivative[]; + +/* state quantization tables */ + +extern const WebRtc_Word16 WebRtcIlbcfix_kStateSq3[]; +extern const WebRtc_Word32 WebRtcIlbcfix_kChooseFrgQuant[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kScale[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kFrgQuantMod[]; + +/* Ranges for search and filters at different subframes */ + +extern const WebRtc_Word16 WebRtcIlbcfix_kSearchRange[5][CB_NSTAGES]; +extern const WebRtc_Word16 WebRtcIlbcfix_kFilterRange[]; + +/* gain quantization tables */ + +extern const WebRtc_Word16 WebRtcIlbcfix_kGainSq3[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kGainSq4[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kGainSq5[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kGainSq5Sq[]; +extern const WebRtc_Word16* const WebRtcIlbcfix_kGain[]; + +/* adaptive codebook definitions */ + +extern const WebRtc_Word16 WebRtcIlbcfix_kCbFiltersRev[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kAlpha[]; + +/* enhancer definitions */ + +extern const WebRtc_Word16 WebRtcIlbcfix_kEnhPolyPhaser[ENH_UPS0][ENH_FLO_MULT2_PLUS1]; +extern const WebRtc_Word16 WebRtcIlbcfix_kEnhWt[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kEnhPlocs[]; + +/* PLC tables */ + +extern const WebRtc_Word16 WebRtcIlbcfix_kPlcPerSqr[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kPlcPitchFact[]; +extern const WebRtc_Word16 WebRtcIlbcfix_kPlcPfSlope[]; + +#endif diff --git a/src/libs/webrtc/ilbcfix/create_augmented_vec.c b/src/libs/webrtc/ilbcfix/create_augmented_vec.c new file mode 100644 index 00000000..f021c4d5 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/create_augmented_vec.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CreateAugmentedVec.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * Recreate a specific codebook vector from the augmented part. + * + *----------------------------------------------------------------*/ + +void WebRtcIlbcfix_CreateAugmentedVec( + WebRtc_Word16 index, /* (i) Index for the augmented vector to be created */ + WebRtc_Word16 *buffer, /* (i) Pointer to the end of the codebook memory that + is used for creation of the augmented codebook */ + WebRtc_Word16 *cbVec /* (o) The construced codebook vector */ + ) { + WebRtc_Word16 ilow; + WebRtc_Word16 *ppo, *ppi; + WebRtc_Word16 cbVecTmp[4]; + + ilow = index-4; + + /* copy the first noninterpolated part */ + ppo = buffer-index; + WEBRTC_SPL_MEMCPY_W16(cbVec, ppo, index); + + /* interpolation */ + ppo = buffer - 4; + ppi = buffer - index - 4; + + /* perform cbVec[ilow+k] = ((ppi[k]*alphaTbl[k])>>15) + ((ppo[k]*alphaTbl[3-k])>>15); + for k = 0..3 + */ + WebRtcSpl_ElementwiseVectorMult(&cbVec[ilow], ppi, WebRtcIlbcfix_kAlpha, 4, 15); + WebRtcSpl_ReverseOrderMultArrayElements(cbVecTmp, ppo, &WebRtcIlbcfix_kAlpha[3], 4, 15); + WebRtcSpl_AddVectorsAndShift(&cbVec[ilow], &cbVec[ilow], cbVecTmp, 4, 0); + + /* copy the second noninterpolated part */ + ppo = buffer - index; + WEBRTC_SPL_MEMCPY_W16(cbVec+index,ppo,(SUBL-index)); +} diff --git a/src/libs/webrtc/ilbcfix/create_augmented_vec.h b/src/libs/webrtc/ilbcfix/create_augmented_vec.h new file mode 100644 index 00000000..970a9bef --- /dev/null +++ b/src/libs/webrtc/ilbcfix/create_augmented_vec.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CreateAugmentedVec.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CREATE_AUGMENTED_VEC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CREATE_AUGMENTED_VEC_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Recreate a specific codebook vector from the augmented part. + * + *----------------------------------------------------------------*/ + +void WebRtcIlbcfix_CreateAugmentedVec( + WebRtc_Word16 index, /* (i) Index for the augmented vector to be created */ + WebRtc_Word16 *buffer, /* (i) Pointer to the end of the codebook memory that + is used for creation of the augmented codebook */ + WebRtc_Word16 *cbVec /* (o) The construced codebook vector */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/decode.h b/src/libs/webrtc/ilbcfix/decode.h new file mode 100644 index 00000000..0252d9c4 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/decode.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Decode.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * main decoder function + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_DecodeImpl( + WebRtc_Word16 *decblock, /* (o) decoded signal block */ + WebRtc_UWord16 *bytes, /* (i) encoded signal bits */ + iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state + structure */ + WebRtc_Word16 mode /* (i) 0: bad packet, PLC, + 1: normal */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/decode_residual.c b/src/libs/webrtc/ilbcfix/decode_residual.c new file mode 100644 index 00000000..4bc1cd3c --- /dev/null +++ b/src/libs/webrtc/ilbcfix/decode_residual.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_DecodeResidual.c + +******************************************************************/ + +#include "defines.h" +#include "state_construct.h" +#include "cb_construct.h" +#include "index_conv_dec.h" +#include "do_plc.h" +#include "constants.h" +#include "enhancer_interface.h" +#include "xcorr_coef.h" +#include "lsf_check.h" + + +/*----------------------------------------------------------------* + * frame residual decoder function (subrutine to iLBC_decode) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_DecodeResidual( + iLBC_Dec_Inst_t *iLBCdec_inst, + /* (i/o) the decoder state structure */ + iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits, which are used + for the decoding */ + WebRtc_Word16 *decresidual, /* (o) decoded residual frame */ + WebRtc_Word16 *syntdenum /* (i) the decoded synthesis filter + coefficients */ + ) { + WebRtc_Word16 meml_gotten, Nfor, Nback, diff, start_pos; + WebRtc_Word16 subcount, subframe; + WebRtc_Word16 *reverseDecresidual = iLBCdec_inst->enh_buf; /* Reversed decoded data, used for decoding backwards in time (reuse memory in state) */ + WebRtc_Word16 *memVec = iLBCdec_inst->prevResidual; /* Memory for codebook and filter state (reuse memory in state) */ + WebRtc_Word16 *mem = &memVec[CB_HALFFILTERLEN]; /* Memory for codebook */ + + diff = STATE_LEN - iLBCdec_inst->state_short_len; + + if (iLBC_encbits->state_first == 1) { + start_pos = (iLBC_encbits->startIdx-1)*SUBL; + } else { + start_pos = (iLBC_encbits->startIdx-1)*SUBL + diff; + } + + /* decode scalar part of start state */ + + WebRtcIlbcfix_StateConstruct(iLBC_encbits->idxForMax, + iLBC_encbits->idxVec, &syntdenum[(iLBC_encbits->startIdx-1)*(LPC_FILTERORDER+1)], + &decresidual[start_pos], iLBCdec_inst->state_short_len + ); + + if (iLBC_encbits->state_first) { /* put adaptive part in the end */ + + /* setup memory */ + + WebRtcSpl_MemSetW16(mem, 0, (WebRtc_Word16)(CB_MEML-iLBCdec_inst->state_short_len)); + WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-iLBCdec_inst->state_short_len, decresidual+start_pos, + iLBCdec_inst->state_short_len); + + /* construct decoded vector */ + + WebRtcIlbcfix_CbConstruct( + &decresidual[start_pos+iLBCdec_inst->state_short_len], + iLBC_encbits->cb_index, iLBC_encbits->gain_index, + mem+CB_MEML-ST_MEM_L_TBL, + ST_MEM_L_TBL, (WebRtc_Word16)diff + ); + + } + else {/* put adaptive part in the beginning */ + + /* create reversed vectors for prediction */ + + WebRtcSpl_MemCpyReversedOrder(reverseDecresidual+diff, + &decresidual[(iLBC_encbits->startIdx+1)*SUBL-1-STATE_LEN], diff); + + /* setup memory */ + + meml_gotten = iLBCdec_inst->state_short_len; + WebRtcSpl_MemCpyReversedOrder(mem+CB_MEML-1, + decresidual+start_pos, meml_gotten); + WebRtcSpl_MemSetW16(mem, 0, (WebRtc_Word16)(CB_MEML-meml_gotten)); + + /* construct decoded vector */ + + WebRtcIlbcfix_CbConstruct( + reverseDecresidual, + iLBC_encbits->cb_index, iLBC_encbits->gain_index, + mem+CB_MEML-ST_MEM_L_TBL, + ST_MEM_L_TBL, diff + ); + + /* get decoded residual from reversed vector */ + + WebRtcSpl_MemCpyReversedOrder(&decresidual[start_pos-1], + reverseDecresidual, diff); + } + + /* counter for predicted subframes */ + + subcount=1; + + /* forward prediction of subframes */ + + Nfor = iLBCdec_inst->nsub-iLBC_encbits->startIdx-1; + + if( Nfor > 0 ) { + + /* setup memory */ + WebRtcSpl_MemSetW16(mem, 0, CB_MEML-STATE_LEN); + WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-STATE_LEN, + decresidual+(iLBC_encbits->startIdx-1)*SUBL, STATE_LEN); + + /* loop over subframes to encode */ + + for (subframe=0; subframe<Nfor; subframe++) { + + /* construct decoded vector */ + WebRtcIlbcfix_CbConstruct( + &decresidual[(iLBC_encbits->startIdx+1+subframe)*SUBL], + iLBC_encbits->cb_index+subcount*CB_NSTAGES, + iLBC_encbits->gain_index+subcount*CB_NSTAGES, + mem, MEM_LF_TBL, SUBL + ); + + /* update memory */ + WEBRTC_SPL_MEMMOVE_W16(mem, mem+SUBL, CB_MEML-SUBL); + WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL, + &decresidual[(iLBC_encbits->startIdx+1+subframe)*SUBL], SUBL); + + subcount++; + } + + } + + /* backward prediction of subframes */ + + Nback = iLBC_encbits->startIdx-1; + + if( Nback > 0 ){ + + /* setup memory */ + + meml_gotten = SUBL*(iLBCdec_inst->nsub+1-iLBC_encbits->startIdx); + if( meml_gotten > CB_MEML ) { + meml_gotten=CB_MEML; + } + + WebRtcSpl_MemCpyReversedOrder(mem+CB_MEML-1, + decresidual+(iLBC_encbits->startIdx-1)*SUBL, meml_gotten); + WebRtcSpl_MemSetW16(mem, 0, (WebRtc_Word16)(CB_MEML-meml_gotten)); + + /* loop over subframes to decode */ + + for (subframe=0; subframe<Nback; subframe++) { + + /* construct decoded vector */ + WebRtcIlbcfix_CbConstruct( + &reverseDecresidual[subframe*SUBL], + iLBC_encbits->cb_index+subcount*CB_NSTAGES, + iLBC_encbits->gain_index+subcount*CB_NSTAGES, + mem, MEM_LF_TBL, SUBL + ); + + /* update memory */ + WEBRTC_SPL_MEMMOVE_W16(mem, mem+SUBL, CB_MEML-SUBL); + WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL, + &reverseDecresidual[subframe*SUBL], SUBL); + + subcount++; + } + + /* get decoded residual from reversed vector */ + WebRtcSpl_MemCpyReversedOrder(decresidual+SUBL*Nback-1, + reverseDecresidual, SUBL*Nback); + } +} diff --git a/src/libs/webrtc/ilbcfix/decode_residual.h b/src/libs/webrtc/ilbcfix/decode_residual.h new file mode 100644 index 00000000..ea7208a1 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/decode_residual.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_DecodeResidual.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_RESIDUAL_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_RESIDUAL_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * frame residual decoder function (subrutine to iLBC_decode) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_DecodeResidual( + iLBC_Dec_Inst_t *iLBCdec_inst, + /* (i/o) the decoder state structure */ + iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits, which are used + for the decoding */ + WebRtc_Word16 *decresidual, /* (o) decoded residual frame */ + WebRtc_Word16 *syntdenum /* (i) the decoded synthesis filter + coefficients */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/decoder_interpolate_lsf.c b/src/libs/webrtc/ilbcfix/decoder_interpolate_lsf.c new file mode 100644 index 00000000..eee3105c --- /dev/null +++ b/src/libs/webrtc/ilbcfix/decoder_interpolate_lsf.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_DecoderInterpolateLsp.c + +******************************************************************/ + +#include "lsf_interpolate_to_poly_dec.h" +#include "bw_expand.h" +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * obtain synthesis and weighting filters form lsf coefficients + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_DecoderInterpolateLsp( + WebRtc_Word16 *syntdenum, /* (o) synthesis filter coefficients */ + WebRtc_Word16 *weightdenum, /* (o) weighting denumerator + coefficients */ + WebRtc_Word16 *lsfdeq, /* (i) dequantized lsf coefficients */ + WebRtc_Word16 length, /* (i) length of lsf coefficient vector */ + iLBC_Dec_Inst_t *iLBCdec_inst + /* (i) the decoder state structure */ + ){ + int i, pos, lp_length; + WebRtc_Word16 lp[LPC_FILTERORDER + 1], *lsfdeq2; + + lsfdeq2 = lsfdeq + length; + lp_length = length + 1; + + if (iLBCdec_inst->mode==30) { + /* subframe 1: Interpolation between old and first LSF */ + + WebRtcIlbcfix_LspInterpolate2PolyDec(lp, (*iLBCdec_inst).lsfdeqold, lsfdeq, + WebRtcIlbcfix_kLsfWeight30ms[0], length); + WEBRTC_SPL_MEMCPY_W16(syntdenum,lp,lp_length); + WebRtcIlbcfix_BwExpand(weightdenum, lp, (WebRtc_Word16*)WebRtcIlbcfix_kLpcChirpSyntDenum, (WebRtc_Word16)lp_length); + + /* subframes 2 to 6: interpolation between first and last LSF */ + + pos = lp_length; + for (i = 1; i < 6; i++) { + WebRtcIlbcfix_LspInterpolate2PolyDec(lp, lsfdeq, lsfdeq2, + WebRtcIlbcfix_kLsfWeight30ms[i], length); + WEBRTC_SPL_MEMCPY_W16(syntdenum + pos,lp,lp_length); + WebRtcIlbcfix_BwExpand(weightdenum + pos, lp, + (WebRtc_Word16*)WebRtcIlbcfix_kLpcChirpSyntDenum, (WebRtc_Word16)lp_length); + pos += lp_length; + } + } else { /* iLBCdec_inst->mode=20 */ + /* subframes 1 to 4: interpolation between old and new LSF */ + pos = 0; + for (i = 0; i < iLBCdec_inst->nsub; i++) { + WebRtcIlbcfix_LspInterpolate2PolyDec(lp, iLBCdec_inst->lsfdeqold, lsfdeq, + WebRtcIlbcfix_kLsfWeight20ms[i], length); + WEBRTC_SPL_MEMCPY_W16(syntdenum+pos,lp,lp_length); + WebRtcIlbcfix_BwExpand(weightdenum+pos, lp, + (WebRtc_Word16*)WebRtcIlbcfix_kLpcChirpSyntDenum, (WebRtc_Word16)lp_length); + pos += lp_length; + } + } + + /* update memory */ + + if (iLBCdec_inst->mode==30) { + WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->lsfdeqold, lsfdeq2, length); + } else { + WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->lsfdeqold, lsfdeq, length); + } +} diff --git a/src/libs/webrtc/ilbcfix/decoder_interpolate_lsf.h b/src/libs/webrtc/ilbcfix/decoder_interpolate_lsf.h new file mode 100644 index 00000000..3896ca97 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/decoder_interpolate_lsf.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_DecoderInterpolateLsp.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODER_INTERPOLATE_LSF_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODER_INTERPOLATE_LSF_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * obtain synthesis and weighting filters form lsf coefficients + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_DecoderInterpolateLsp( + WebRtc_Word16 *syntdenum, /* (o) synthesis filter coefficients */ + WebRtc_Word16 *weightdenum, /* (o) weighting denumerator + coefficients */ + WebRtc_Word16 *lsfdeq, /* (i) dequantized lsf coefficients */ + WebRtc_Word16 length, /* (i) length of lsf coefficient vector */ + iLBC_Dec_Inst_t *iLBCdec_inst + /* (i) the decoder state structure */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/defines.h b/src/libs/webrtc/ilbcfix/defines.h new file mode 100644 index 00000000..bdeba019 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/defines.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + define.h + +******************************************************************/ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DEFINES_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DEFINES_H_ + +#include "typedefs.h" +#include "signal_processing_library.h" +#include <string.h> + +/* general codec settings */ + +#define FS 8000 +#define BLOCKL_20MS 160 +#define BLOCKL_30MS 240 +#define BLOCKL_MAX 240 +#define NSUB_20MS 4 +#define NSUB_30MS 6 +#define NSUB_MAX 6 +#define NASUB_20MS 2 +#define NASUB_30MS 4 +#define NASUB_MAX 4 +#define SUBL 40 +#define STATE_LEN 80 +#define STATE_SHORT_LEN_30MS 58 +#define STATE_SHORT_LEN_20MS 57 + +/* LPC settings */ + +#define LPC_FILTERORDER 10 +#define LPC_LOOKBACK 60 +#define LPC_N_20MS 1 +#define LPC_N_30MS 2 +#define LPC_N_MAX 2 +#define LPC_ASYMDIFF 20 +#define LSF_NSPLIT 3 +#define LSF_NUMBER_OF_STEPS 4 +#define LPC_HALFORDER 5 +#define COS_GRID_POINTS 60 + +/* cb settings */ + +#define CB_NSTAGES 3 +#define CB_EXPAND 2 +#define CB_MEML 147 +#define CB_FILTERLEN (2*4) +#define CB_HALFFILTERLEN 4 +#define CB_RESRANGE 34 +#define CB_MAXGAIN_FIXQ6 83 /* error = -0.24% */ +#define CB_MAXGAIN_FIXQ14 21299 + +/* enhancer */ + +#define ENH_BLOCKL 80 /* block length */ +#define ENH_BLOCKL_HALF (ENH_BLOCKL/2) +#define ENH_HL 3 /* 2*ENH_HL+1 is number blocks + in said second sequence */ +#define ENH_SLOP 2 /* max difference estimated and + correct pitch period */ +#define ENH_PLOCSL 8 /* pitch-estimates and + pitch-locations buffer length */ +#define ENH_OVERHANG 2 +#define ENH_UPS0 4 /* upsampling rate */ +#define ENH_FL0 3 /* 2*FLO+1 is the length of each filter */ +#define ENH_FLO_MULT2_PLUS1 7 +#define ENH_VECTL (ENH_BLOCKL+2*ENH_FL0) +#define ENH_CORRDIM (2*ENH_SLOP+1) +#define ENH_NBLOCKS (BLOCKL/ENH_BLOCKL) +#define ENH_NBLOCKS_EXTRA 5 +#define ENH_NBLOCKS_TOT 8 /* ENH_NBLOCKS+ENH_NBLOCKS_EXTRA */ +#define ENH_BUFL (ENH_NBLOCKS_TOT)*ENH_BLOCKL +#define ENH_BUFL_FILTEROVERHEAD 3 +#define ENH_A0 819 /* Q14 */ +#define ENH_A0_MINUS_A0A0DIV4 848256041 /* Q34 */ +#define ENH_A0DIV2 26843546 /* Q30 */ + +/* PLC */ + +/* Down sampling */ + +#define FILTERORDER_DS_PLUS1 7 +#define DELAY_DS 3 +#define FACTOR_DS 2 + +/* bit stream defs */ + +#define NO_OF_BYTES_20MS 38 +#define NO_OF_BYTES_30MS 50 +#define NO_OF_WORDS_20MS 19 +#define NO_OF_WORDS_30MS 25 +#define STATE_BITS 3 +#define BYTE_LEN 8 +#define ULP_CLASSES 3 + +/* help parameters */ + +#define TWO_PI_FIX 25736 /* Q12 */ + +/* Constants for codebook search and creation */ + +#define ST_MEM_L_TBL 85 +#define MEM_LF_TBL 147 + + +/* Struct for the bits */ +typedef struct iLBC_bits_t_ { + WebRtc_Word16 lsf[LSF_NSPLIT*LPC_N_MAX]; + WebRtc_Word16 cb_index[CB_NSTAGES*(NASUB_MAX+1)]; /* First CB_NSTAGES values contains extra CB index */ + WebRtc_Word16 gain_index[CB_NSTAGES*(NASUB_MAX+1)]; /* First CB_NSTAGES values contains extra CB gain */ + WebRtc_Word16 idxForMax; + WebRtc_Word16 state_first; + WebRtc_Word16 idxVec[STATE_SHORT_LEN_30MS]; + WebRtc_Word16 firstbits; + WebRtc_Word16 startIdx; +} iLBC_bits; + +/* type definition encoder instance */ +typedef struct iLBC_Enc_Inst_t_ { + + /* flag for frame size mode */ + WebRtc_Word16 mode; + + /* basic parameters for different frame sizes */ + WebRtc_Word16 blockl; + WebRtc_Word16 nsub; + WebRtc_Word16 nasub; + WebRtc_Word16 no_of_bytes, no_of_words; + WebRtc_Word16 lpc_n; + WebRtc_Word16 state_short_len; + + /* analysis filter state */ + WebRtc_Word16 anaMem[LPC_FILTERORDER]; + + /* Fix-point old lsf parameters for interpolation */ + WebRtc_Word16 lsfold[LPC_FILTERORDER]; + WebRtc_Word16 lsfdeqold[LPC_FILTERORDER]; + + /* signal buffer for LP analysis */ + WebRtc_Word16 lpc_buffer[LPC_LOOKBACK + BLOCKL_MAX]; + + /* state of input HP filter */ + WebRtc_Word16 hpimemx[2]; + WebRtc_Word16 hpimemy[4]; + +#ifdef SPLIT_10MS + WebRtc_Word16 weightdenumbuf[66]; + WebRtc_Word16 past_samples[160]; + WebRtc_UWord16 bytes[25]; + WebRtc_Word16 section; + WebRtc_Word16 Nfor_flag; + WebRtc_Word16 Nback_flag; + WebRtc_Word16 start_pos; + WebRtc_Word16 diff; +#endif + +} iLBC_Enc_Inst_t; + +/* type definition decoder instance */ +typedef struct iLBC_Dec_Inst_t_ { + + /* flag for frame size mode */ + WebRtc_Word16 mode; + + /* basic parameters for different frame sizes */ + WebRtc_Word16 blockl; + WebRtc_Word16 nsub; + WebRtc_Word16 nasub; + WebRtc_Word16 no_of_bytes, no_of_words; + WebRtc_Word16 lpc_n; + WebRtc_Word16 state_short_len; + + /* synthesis filter state */ + WebRtc_Word16 syntMem[LPC_FILTERORDER]; + + /* old LSF for interpolation */ + WebRtc_Word16 lsfdeqold[LPC_FILTERORDER]; + + /* pitch lag estimated in enhancer and used in PLC */ + int last_lag; + + /* PLC state information */ + int consPLICount, prev_enh_pl; + WebRtc_Word16 perSquare; + + WebRtc_Word16 prevScale, prevPLI; + WebRtc_Word16 prevLag, prevLpc[LPC_FILTERORDER+1]; + WebRtc_Word16 prevResidual[NSUB_MAX*SUBL]; + WebRtc_Word16 seed; + + /* previous synthesis filter parameters */ + + WebRtc_Word16 old_syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX]; + + /* state of output HP filter */ + WebRtc_Word16 hpimemx[2]; + WebRtc_Word16 hpimemy[4]; + + /* enhancer state information */ + int use_enhancer; + WebRtc_Word16 enh_buf[ENH_BUFL+ENH_BUFL_FILTEROVERHEAD]; + WebRtc_Word16 enh_period[ENH_NBLOCKS_TOT]; + +} iLBC_Dec_Inst_t; + +#endif diff --git a/src/libs/webrtc/ilbcfix/do_plc.c b/src/libs/webrtc/ilbcfix/do_plc.c new file mode 100644 index 00000000..0dfae2bd --- /dev/null +++ b/src/libs/webrtc/ilbcfix/do_plc.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_DoThePlc.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "comp_corr.h" +#include "bw_expand.h" + +/*----------------------------------------------------------------* + * Packet loss concealment routine. Conceals a residual signal + * and LP parameters. If no packet loss, update state. + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_DoThePlc( + WebRtc_Word16 *PLCresidual, /* (o) concealed residual */ + WebRtc_Word16 *PLClpc, /* (o) concealed LP parameters */ + WebRtc_Word16 PLI, /* (i) packet loss indicator + 0 - no PL, 1 = PL */ + WebRtc_Word16 *decresidual, /* (i) decoded residual */ + WebRtc_Word16 *lpc, /* (i) decoded LPC (only used for no PL) */ + WebRtc_Word16 inlag, /* (i) pitch lag */ + iLBC_Dec_Inst_t *iLBCdec_inst + /* (i/o) decoder instance */ + ){ + WebRtc_Word16 i, pick; + WebRtc_Word32 cross, ener, cross_comp, ener_comp = 0; + WebRtc_Word32 measure, maxMeasure, energy; + WebRtc_Word16 max, crossSquareMax, crossSquare; + WebRtc_Word16 j, lag, tmp1, tmp2, randlag; + WebRtc_Word16 shift1, shift2, shift3, shiftMax; + WebRtc_Word16 scale3; + WebRtc_Word16 corrLen; + WebRtc_Word32 tmpW32, tmp2W32; + WebRtc_Word16 use_gain; + WebRtc_Word16 tot_gain; + WebRtc_Word16 max_perSquare; + WebRtc_Word16 scale1, scale2; + WebRtc_Word16 totscale; + WebRtc_Word32 nom; + WebRtc_Word16 denom; + WebRtc_Word16 pitchfact; + WebRtc_Word16 use_lag; + int ind; + WebRtc_Word16 randvec[BLOCKL_MAX]; + + /* Packet Loss */ + if (PLI == 1) { + + (*iLBCdec_inst).consPLICount += 1; + + /* if previous frame not lost, + determine pitch pred. gain */ + + if (iLBCdec_inst->prevPLI != 1) { + + /* Maximum 60 samples are correlated, preserve as high accuracy + as possible without getting overflow */ + max = WebRtcSpl_MaxAbsValueW16((*iLBCdec_inst).prevResidual, (WebRtc_Word16)iLBCdec_inst->blockl); + scale3 = (WebRtcSpl_GetSizeInBits(max)<<1) - 25; + if (scale3 < 0) { + scale3 = 0; + } + + /* Store scale for use when interpolating between the + * concealment and the received packet */ + iLBCdec_inst->prevScale = scale3; + + /* Search around the previous lag +/-3 to find the + best pitch period */ + lag = inlag - 3; + + /* Guard against getting outside the frame */ + corrLen = WEBRTC_SPL_MIN(60, iLBCdec_inst->blockl-(inlag+3)); + + WebRtcIlbcfix_CompCorr( &cross, &ener, + iLBCdec_inst->prevResidual, lag, iLBCdec_inst->blockl, corrLen, scale3); + + /* Normalize and store cross^2 and the number of shifts */ + shiftMax = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_ABS_W32(cross))-15; + crossSquareMax = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(WEBRTC_SPL_SHIFT_W32(cross, -shiftMax), + WEBRTC_SPL_SHIFT_W32(cross, -shiftMax), 15); + + for (j=inlag-2;j<=inlag+3;j++) { + WebRtcIlbcfix_CompCorr( &cross_comp, &ener_comp, + iLBCdec_inst->prevResidual, j, iLBCdec_inst->blockl, corrLen, scale3); + + /* Use the criteria (corr*corr)/energy to compare if + this lag is better or not. To avoid the division, + do a cross multiplication */ + shift1 = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_ABS_W32(cross_comp))-15; + crossSquare = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(WEBRTC_SPL_SHIFT_W32(cross_comp, -shift1), + WEBRTC_SPL_SHIFT_W32(cross_comp, -shift1), 15); + + shift2 = WebRtcSpl_GetSizeInBits(ener)-15; + measure = WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_SHIFT_W32(ener, -shift2), + crossSquare); + + shift3 = WebRtcSpl_GetSizeInBits(ener_comp)-15; + maxMeasure = WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_SHIFT_W32(ener_comp, -shift3), + crossSquareMax); + + /* Calculate shift value, so that the two measures can + be put in the same Q domain */ + if(((shiftMax<<1)+shift3) > ((shift1<<1)+shift2)) { + tmp1 = WEBRTC_SPL_MIN(31, (shiftMax<<1)+shift3-(shift1<<1)-shift2); + tmp2 = 0; + } else { + tmp1 = 0; + tmp2 = WEBRTC_SPL_MIN(31, (shift1<<1)+shift2-(shiftMax<<1)-shift3); + } + + if ((measure>>tmp1) > (maxMeasure>>tmp2)) { + /* New lag is better => record lag, measure and domain */ + lag = j; + crossSquareMax = crossSquare; + cross = cross_comp; + shiftMax = shift1; + ener = ener_comp; + } + } + + /* Calculate the periodicity for the lag with the maximum correlation. + + Definition of the periodicity: + abs(corr(vec1, vec2))/(sqrt(energy(vec1))*sqrt(energy(vec2))) + + Work in the Square domain to simplify the calculations + max_perSquare is less than 1 (in Q15) + */ + tmp2W32=WebRtcSpl_DotProductWithScale(&iLBCdec_inst->prevResidual[iLBCdec_inst->blockl-corrLen], + &iLBCdec_inst->prevResidual[iLBCdec_inst->blockl-corrLen], + corrLen, scale3); + + if ((tmp2W32>0)&&(ener_comp>0)) { + /* norm energies to WebRtc_Word16, compute the product of the energies and + use the upper WebRtc_Word16 as the denominator */ + + scale1=(WebRtc_Word16)WebRtcSpl_NormW32(tmp2W32)-16; + tmp1=(WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(tmp2W32, scale1); + + scale2=(WebRtc_Word16)WebRtcSpl_NormW32(ener)-16; + tmp2=(WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(ener, scale2); + denom=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp1, tmp2, 16); /* denom in Q(scale1+scale2-16) */ + + /* Square the cross correlation and norm it such that max_perSquare + will be in Q15 after the division */ + + totscale = scale1+scale2-1; + tmp1 = (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(cross, (totscale>>1)); + tmp2 = (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(cross, totscale-(totscale>>1)); + + nom = WEBRTC_SPL_MUL_16_16(tmp1, tmp2); + max_perSquare = (WebRtc_Word16)WebRtcSpl_DivW32W16(nom, denom); + + } else { + max_perSquare = 0; + } + } + + /* previous frame lost, use recorded lag and gain */ + + else { + lag = iLBCdec_inst->prevLag; + max_perSquare = iLBCdec_inst->perSquare; + } + + /* Attenuate signal and scale down pitch pred gain if + several frames lost consecutively */ + + use_gain = 32767; /* 1.0 in Q15 */ + + if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>320) { + use_gain = 29491; /* 0.9 in Q15 */ + } else if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>640) { + use_gain = 22938; /* 0.7 in Q15 */ + } else if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>960) { + use_gain = 16384; /* 0.5 in Q15 */ + } else if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>1280) { + use_gain = 0; /* 0.0 in Q15 */ + } + + /* Compute mixing factor of picth repeatition and noise: + for max_per>0.7 set periodicity to 1.0 + 0.4<max_per<0.7 set periodicity to (maxper-0.4)/0.7-0.4) + max_per<0.4 set periodicity to 0.0 + */ + + if (max_perSquare>7868) { /* periodicity > 0.7 (0.7^4=0.2401 in Q15) */ + pitchfact = 32767; + } else if (max_perSquare>839) { /* 0.4 < periodicity < 0.7 (0.4^4=0.0256 in Q15) */ + /* find best index and interpolate from that */ + ind = 5; + while ((max_perSquare<WebRtcIlbcfix_kPlcPerSqr[ind])&&(ind>0)) { + ind--; + } + /* pitch fact is approximated by first order */ + tmpW32 = (WebRtc_Word32)WebRtcIlbcfix_kPlcPitchFact[ind] + + WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIlbcfix_kPlcPfSlope[ind], (max_perSquare-WebRtcIlbcfix_kPlcPerSqr[ind]), 11); + + pitchfact = (WebRtc_Word16)WEBRTC_SPL_MIN(tmpW32, 32767); /* guard against overflow */ + + } else { /* periodicity < 0.4 */ + pitchfact = 0; + } + + /* avoid repetition of same pitch cycle (buzzyness) */ + use_lag = lag; + if (lag<80) { + use_lag = 2*lag; + } + + /* compute concealed residual */ + energy = 0; + + for (i=0; i<iLBCdec_inst->blockl; i++) { + + /* noise component - 52 < randlagFIX < 117 */ + iLBCdec_inst->seed = (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16(iLBCdec_inst->seed, 31821)+(WebRtc_Word32)13849); + randlag = 53 + (WebRtc_Word16)(iLBCdec_inst->seed & 63); + + pick = i - randlag; + + if (pick < 0) { + randvec[i] = iLBCdec_inst->prevResidual[iLBCdec_inst->blockl+pick]; + } else { + randvec[i] = iLBCdec_inst->prevResidual[pick]; + } + + /* pitch repeatition component */ + pick = i - use_lag; + + if (pick < 0) { + PLCresidual[i] = iLBCdec_inst->prevResidual[iLBCdec_inst->blockl+pick]; + } else { + PLCresidual[i] = PLCresidual[pick]; + } + + /* Attinuate total gain for each 10 ms */ + if (i<80) { + tot_gain=use_gain; + } else if (i<160) { + tot_gain=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(31130, use_gain, 15); /* 0.95*use_gain */ + } else { + tot_gain=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(29491, use_gain, 15); /* 0.9*use_gain */ + } + + + /* mix noise and pitch repeatition */ + + PLCresidual[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tot_gain, + (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( (WEBRTC_SPL_MUL_16_16(pitchfact, PLCresidual[i]) + + WEBRTC_SPL_MUL_16_16((32767-pitchfact), randvec[i]) + 16384), + 15), + 15); + + /* Shifting down the result one step extra to ensure that no overflow + will occur */ + energy += WEBRTC_SPL_MUL_16_16_RSFT(PLCresidual[i], + PLCresidual[i], (iLBCdec_inst->prevScale+1)); + + } + + /* less than 30 dB, use only noise */ + if (energy < (WEBRTC_SPL_SHIFT_W32(((WebRtc_Word32)iLBCdec_inst->blockl*900),-(iLBCdec_inst->prevScale+1)))) { + energy = 0; + for (i=0; i<iLBCdec_inst->blockl; i++) { + PLCresidual[i] = randvec[i]; + } + } + + /* use the old LPC */ + WEBRTC_SPL_MEMCPY_W16(PLClpc, (*iLBCdec_inst).prevLpc, LPC_FILTERORDER+1); + + /* Update state in case there are multiple frame losses */ + iLBCdec_inst->prevLag = lag; + iLBCdec_inst->perSquare = max_perSquare; + } + + /* no packet loss, copy input */ + + else { + WEBRTC_SPL_MEMCPY_W16(PLCresidual, decresidual, iLBCdec_inst->blockl); + WEBRTC_SPL_MEMCPY_W16(PLClpc, lpc, (LPC_FILTERORDER+1)); + iLBCdec_inst->consPLICount = 0; + } + + /* update state */ + iLBCdec_inst->prevPLI = PLI; + WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->prevLpc, PLClpc, (LPC_FILTERORDER+1)); + WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->prevResidual, PLCresidual, iLBCdec_inst->blockl); + + return; +} diff --git a/src/libs/webrtc/ilbcfix/do_plc.h b/src/libs/webrtc/ilbcfix/do_plc.h new file mode 100644 index 00000000..c5bcc522 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/do_plc.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_DoThePlc.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DO_PLC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DO_PLC_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Packet loss concealment routine. Conceals a residual signal + * and LP parameters. If no packet loss, update state. + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_DoThePlc( + WebRtc_Word16 *PLCresidual, /* (o) concealed residual */ + WebRtc_Word16 *PLClpc, /* (o) concealed LP parameters */ + WebRtc_Word16 PLI, /* (i) packet loss indicator + 0 - no PL, 1 = PL */ + WebRtc_Word16 *decresidual, /* (i) decoded residual */ + WebRtc_Word16 *lpc, /* (i) decoded LPC (only used for no PL) */ + WebRtc_Word16 inlag, /* (i) pitch lag */ + iLBC_Dec_Inst_t *iLBCdec_inst + /* (i/o) decoder instance */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/encode.h b/src/libs/webrtc/ilbcfix/encode.h new file mode 100644 index 00000000..b553f0ce --- /dev/null +++ b/src/libs/webrtc/ilbcfix/encode.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Encode.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENCODE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENCODE_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * main encoder function + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_EncodeImpl( + WebRtc_UWord16 *bytes, /* (o) encoded data bits iLBC */ + WebRtc_Word16 *block, /* (i) speech vector to encode */ + iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder + state */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/energy_inverse.c b/src/libs/webrtc/ilbcfix/energy_inverse.c new file mode 100644 index 00000000..d56069b0 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/energy_inverse.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_EnergyInverse.c + +******************************************************************/ + +/* Inverses the in vector in into Q29 domain */ + +#include "energy_inverse.h" + +void WebRtcIlbcfix_EnergyInverse( + WebRtc_Word16 *energy, /* (i/o) Energy and inverse + energy (in Q29) */ + int noOfEnergies) /* (i) The length of the energy + vector */ +{ + WebRtc_Word32 Nom=(WebRtc_Word32)0x1FFFFFFF; + WebRtc_Word16 *energyPtr; + int i; + + /* Set the minimum energy value to 16384 to avoid overflow */ + energyPtr=energy; + for (i=0; i<noOfEnergies; i++) { + (*energyPtr)=WEBRTC_SPL_MAX((*energyPtr),16384); + energyPtr++; + } + + /* Calculate inverse energy in Q29 */ + energyPtr=energy; + for (i=0; i<noOfEnergies; i++) { + (*energyPtr) = (WebRtc_Word16)WebRtcSpl_DivW32W16(Nom, (*energyPtr)); + energyPtr++; + } +} diff --git a/src/libs/webrtc/ilbcfix/energy_inverse.h b/src/libs/webrtc/ilbcfix/energy_inverse.h new file mode 100644 index 00000000..db135898 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/energy_inverse.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_EnergyInverse.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENERGY_INVERSE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENERGY_INVERSE_H_ + +#include "defines.h" + +/* Inverses the in vector in into Q29 domain */ + +void WebRtcIlbcfix_EnergyInverse( + WebRtc_Word16 *energy, /* (i/o) Energy and inverse + energy (in Q29) */ + int noOfEnergies); /* (i) The length of the energy + vector */ + +#endif diff --git a/src/libs/webrtc/ilbcfix/enh_upsample.c b/src/libs/webrtc/ilbcfix/enh_upsample.c new file mode 100644 index 00000000..33438163 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/enh_upsample.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_EnhUpsample.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * upsample finite array assuming zeros outside bounds + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_EnhUpsample( + WebRtc_Word32 *useq1, /* (o) upsampled output sequence */ + WebRtc_Word16 *seq1 /* (i) unupsampled sequence */ + ){ + int j; + WebRtc_Word32 *pu1, *pu11; + WebRtc_Word16 *ps, *w16tmp; + const WebRtc_Word16 *pp; + + /* filtering: filter overhangs left side of sequence */ + pu1=useq1; + for (j=0;j<ENH_UPS0; j++) { + pu11=pu1; + /* i = 2 */ + pp=WebRtcIlbcfix_kEnhPolyPhaser[j]+1; + ps=seq1+2; + (*pu11) = WEBRTC_SPL_MUL_16_16(*ps--,*pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++); + pu11+=ENH_UPS0; + /* i = 3 */ + pp=WebRtcIlbcfix_kEnhPolyPhaser[j]+1; + ps=seq1+3; + (*pu11) = WEBRTC_SPL_MUL_16_16(*ps--,*pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++); + pu11+=ENH_UPS0; + /* i = 4 */ + pp=WebRtcIlbcfix_kEnhPolyPhaser[j]+1; + ps=seq1+4; + (*pu11) = WEBRTC_SPL_MUL_16_16(*ps--,*pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++); + pu1++; + } + + /* filtering: simple convolution=inner products + (not needed since the sequence is so short) + */ + + /* filtering: filter overhangs right side of sequence */ + + /* Code with loops, which is equivivalent to the expanded version below + + filterlength = 5; + hf1 = 2; + for(j=0;j<ENH_UPS0; j++){ + pu = useq1 + (filterlength-hfl)*ENH_UPS0 + j; + for(i=1; i<=hfl; i++){ + *pu=0; + pp = polyp[j]+i; + ps = seq1+dim1-1; + for(k=0;k<filterlength-i;k++) { + *pu += WEBRTC_SPL_MUL_16_16(*ps--, *pp++); + } + pu+=ENH_UPS0; + } + } + */ + pu1 = useq1 + 12; + w16tmp = seq1+4; + for (j=0;j<ENH_UPS0; j++) { + pu11 = pu1; + /* i = 1 */ + pp = WebRtcIlbcfix_kEnhPolyPhaser[j]+2; + ps = w16tmp; + (*pu11) = WEBRTC_SPL_MUL_16_16(*ps--, *pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--, *pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--, *pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--, *pp++); + pu11+=ENH_UPS0; + /* i = 2 */ + pp = WebRtcIlbcfix_kEnhPolyPhaser[j]+3; + ps = w16tmp; + (*pu11) = WEBRTC_SPL_MUL_16_16(*ps--, *pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--, *pp++); + (*pu11) += WEBRTC_SPL_MUL_16_16(*ps--, *pp++); + pu11+=ENH_UPS0; + + pu1++; + } +} diff --git a/src/libs/webrtc/ilbcfix/enh_upsample.h b/src/libs/webrtc/ilbcfix/enh_upsample.h new file mode 100644 index 00000000..53534ccc --- /dev/null +++ b/src/libs/webrtc/ilbcfix/enh_upsample.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_EnhUpsample.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENH_UPSAMPLE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENH_UPSAMPLE_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * upsample finite array assuming zeros outside bounds + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_EnhUpsample( + WebRtc_Word32 *useq1, /* (o) upsampled output sequence */ + WebRtc_Word16 *seq1 /* (i) unupsampled sequence */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/enhancer.c b/src/libs/webrtc/ilbcfix/enhancer.c new file mode 100644 index 00000000..e8f4ef33 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/enhancer.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Enhancer.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "get_sync_seq.h" +#include "smooth.h" + +/*----------------------------------------------------------------* + * perform enhancement on idata+centerStartPos through + * idata+centerStartPos+ENH_BLOCKL-1 + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Enhancer( + iLBC_Dec_Inst_t *iLBCdec_inst, + /* (i) Decoder state */ + WebRtc_Word16 *odata, /* (o) smoothed block, dimension blockl */ + WebRtc_Word16 *idata, /* (i) data buffer used for enhancing */ + WebRtc_Word16 idatal, /* (i) dimension idata */ + WebRtc_Word16 centerStartPos, /* (i) first sample current block within idata */ + WebRtc_Word16 *period, /* (i) pitch period array (pitch bward-in time) */ + WebRtc_Word16 *plocs, /* (i) locations where period array values valid */ + WebRtc_Word16 periodl /* (i) dimension of period and plocs */ + ){ + /* Stack based */ + WebRtc_Word16 surround[ENH_BLOCKL]; + + WebRtcSpl_MemSetW16(surround, 0, ENH_BLOCKL); + + /* get said second sequence of segments */ + + WebRtcIlbcfix_GetSyncSeq(iLBCdec_inst, idata,idatal,centerStartPos,period,plocs,periodl,ENH_HL,surround); + + /* compute the smoothed output from said second sequence */ + + WebRtcIlbcfix_Smooth(odata, idata+centerStartPos, surround); +} diff --git a/src/libs/webrtc/ilbcfix/enhancer.h b/src/libs/webrtc/ilbcfix/enhancer.h new file mode 100644 index 00000000..5feb6ecd --- /dev/null +++ b/src/libs/webrtc/ilbcfix/enhancer.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Enhancer.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENHANCER_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENHANCER_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * perform enhancement on idata+centerStartPos through + * idata+centerStartPos+ENH_BLOCKL-1 + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Enhancer( + iLBC_Dec_Inst_t *iLBCdec_inst, + /* (i) Decoder state */ + WebRtc_Word16 *odata, /* (o) smoothed block, dimension blockl */ + WebRtc_Word16 *idata, /* (i) data buffer used for enhancing */ + WebRtc_Word16 idatal, /* (i) dimension idata */ + WebRtc_Word16 centerStartPos, /* (i) first sample current block within idata */ + WebRtc_Word16 *period, /* (i) pitch period array (pitch bward-in time) */ + WebRtc_Word16 *plocs, /* (i) locations where period array values valid */ + WebRtc_Word16 periodl /* (i) dimension of period and plocs */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/enhancer_interface.c b/src/libs/webrtc/ilbcfix/enhancer_interface.c new file mode 100644 index 00000000..9d6cf89c --- /dev/null +++ b/src/libs/webrtc/ilbcfix/enhancer_interface.c @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_EnhancerInterface.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "xcorr_coef.h" +#include "enhancer.h" +#include "hp_output.h" + + + +/*----------------------------------------------------------------* + * interface for enhancer + *---------------------------------------------------------------*/ + +int WebRtcIlbcfix_EnhancerInterface( /* (o) Estimated lag in end of in[] */ + WebRtc_Word16 *out, /* (o) enhanced signal */ + WebRtc_Word16 *in, /* (i) unenhanced signal */ + iLBC_Dec_Inst_t *iLBCdec_inst /* (i) buffers etc */ + ){ + int iblock; + int lag=20, tlag=20; + int inLen=iLBCdec_inst->blockl+120; + WebRtc_Word16 scale, scale1, plc_blockl; + WebRtc_Word16 *enh_buf, *enh_period; + WebRtc_Word32 tmp1, tmp2, max, new_blocks; + WebRtc_Word16 *enh_bufPtr1; + int i, k; + WebRtc_Word16 EnChange; + WebRtc_Word16 SqrtEnChange; + WebRtc_Word16 inc; + WebRtc_Word16 win; + WebRtc_Word16 *tmpW16ptr; + WebRtc_Word16 startPos; + WebRtc_Word16 *plc_pred; + WebRtc_Word16 *target, *regressor; + WebRtc_Word16 max16; + int shifts; + WebRtc_Word32 ener; + WebRtc_Word16 enerSh; + WebRtc_Word16 corrSh; + WebRtc_Word16 ind, sh; + WebRtc_Word16 start, stop; + /* Stack based */ + WebRtc_Word16 totsh[3]; + WebRtc_Word16 downsampled[(BLOCKL_MAX+120)>>1]; /* length 180 */ + WebRtc_Word32 corr32[50]; + WebRtc_Word32 corrmax[3]; + WebRtc_Word16 corr16[3]; + WebRtc_Word16 en16[3]; + WebRtc_Word16 lagmax[3]; + + plc_pred = downsampled; /* Reuse memory since plc_pred[ENH_BLOCKL] and downsampled are non overlapping */ + enh_buf=iLBCdec_inst->enh_buf; + enh_period=iLBCdec_inst->enh_period; + + /* Copy in the new data into the enhancer buffer */ + + WEBRTC_SPL_MEMMOVE_W16(enh_buf, &enh_buf[iLBCdec_inst->blockl], + ENH_BUFL-iLBCdec_inst->blockl); + + WEBRTC_SPL_MEMCPY_W16(&enh_buf[ENH_BUFL-iLBCdec_inst->blockl], in, + iLBCdec_inst->blockl); + + /* Set variables that are dependent on frame size */ + if (iLBCdec_inst->mode==30) { + plc_blockl=ENH_BLOCKL; + new_blocks=3; + startPos=320; /* Start position for enhancement (640-new_blocks*ENH_BLOCKL-80) */ + } else { + plc_blockl=40; + new_blocks=2; + startPos=440; /* Start position for enhancement (640-new_blocks*ENH_BLOCKL-40) */ + } + + /* Update the pitch prediction for each enhancer block, move the old ones */ + WEBRTC_SPL_MEMMOVE_W16(enh_period, &enh_period[new_blocks], (ENH_NBLOCKS_TOT-new_blocks)); + + k=WebRtcSpl_DownsampleFast( + enh_buf+ENH_BUFL-inLen, /* Input samples */ + (WebRtc_Word16)(inLen+ENH_BUFL_FILTEROVERHEAD), + downsampled, + (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(inLen, 1), + (WebRtc_Word16*)WebRtcIlbcfix_kLpFiltCoefs, /* Coefficients in Q12 */ + FILTERORDER_DS_PLUS1, /* Length of filter (order-1) */ + FACTOR_DS, + DELAY_DS); + + /* Estimate the pitch in the down sampled domain. */ + for(iblock = 0; iblock<new_blocks; iblock++){ + + /* references */ + i=60+WEBRTC_SPL_MUL_16_16(iblock,ENH_BLOCKL_HALF); + target=downsampled+i; + regressor=downsampled+i-10; + + /* scaling */ + max16=WebRtcSpl_MaxAbsValueW16(&regressor[-50], (WebRtc_Word16)(ENH_BLOCKL_HALF+50-1)); + shifts = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_MUL_16_16(max16, max16)) - 25; + shifts = WEBRTC_SPL_MAX(0, shifts); + + /* compute cross correlation */ + WebRtcSpl_CrossCorrelation(corr32, target, regressor, + ENH_BLOCKL_HALF, 50, (WebRtc_Word16)shifts, -1); + + /* Find 3 highest correlations that should be compared for the + highest (corr*corr)/ener */ + + for (i=0;i<2;i++) { + lagmax[i] = WebRtcSpl_MaxIndexW32(corr32, 50); + corrmax[i] = corr32[lagmax[i]]; + start = lagmax[i] - 2; + stop = lagmax[i] + 2; + start = WEBRTC_SPL_MAX(0, start); + stop = WEBRTC_SPL_MIN(49, stop); + for (k=start; k<=stop; k++) { + corr32[k] = 0; + } + } + lagmax[2] = WebRtcSpl_MaxIndexW32(corr32, 50); + corrmax[2] = corr32[lagmax[2]]; + + /* Calculate normalized corr^2 and ener */ + for (i=0;i<3;i++) { + corrSh = 15-WebRtcSpl_GetSizeInBits(corrmax[i]); + ener = WebRtcSpl_DotProductWithScale(&regressor[-lagmax[i]], &regressor[-lagmax[i]], ENH_BLOCKL_HALF, shifts); + enerSh = 15-WebRtcSpl_GetSizeInBits(ener); + corr16[i] = (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(corrmax[i], corrSh); + corr16[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(corr16[i], corr16[i], 16); + en16[i] = (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(ener, enerSh); + totsh[i] = enerSh - WEBRTC_SPL_LSHIFT_W32(corrSh, 1); + } + + /* Compare lagmax[0..3] for the (corr^2)/ener criteria */ + ind = 0; + for (i=1; i<3; i++) { + if (totsh[ind] > totsh[i]) { + sh = WEBRTC_SPL_MIN(31, totsh[ind]-totsh[i]); + if ( WEBRTC_SPL_MUL_16_16(corr16[ind], en16[i]) < WEBRTC_SPL_MUL_16_16_RSFT(corr16[i], en16[ind], sh)) { + ind = i; + } + } else { + sh = WEBRTC_SPL_MIN(31, totsh[i]-totsh[ind]); + if (WEBRTC_SPL_MUL_16_16_RSFT(corr16[ind], en16[i], sh) < WEBRTC_SPL_MUL_16_16(corr16[i], en16[ind])) { + ind = i; + } + } + } + + lag = lagmax[ind] + 10; + + /* Store the estimated lag in the non-downsampled domain */ + enh_period[ENH_NBLOCKS_TOT-new_blocks+iblock] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(lag, 8); + + /* Store the estimated lag for backward PLC */ + if (iLBCdec_inst->prev_enh_pl==1) { + if (!iblock) { + tlag = WEBRTC_SPL_MUL_16_16(lag, 2); + } + } else { + if (iblock==1) { + tlag = WEBRTC_SPL_MUL_16_16(lag, 2); + } + } + + lag = WEBRTC_SPL_MUL_16_16(lag, 2); + } + + if ((iLBCdec_inst->prev_enh_pl==1)||(iLBCdec_inst->prev_enh_pl==2)) { + + /* Calculate the best lag of the new frame + This is used to interpolate backwards and mix with the PLC'd data + */ + + /* references */ + target=in; + regressor=in+tlag-1; + + /* scaling */ + max16=WebRtcSpl_MaxAbsValueW16(regressor, (WebRtc_Word16)(plc_blockl+3-1)); + if (max16>5000) + shifts=2; + else + shifts=0; + + /* compute cross correlation */ + WebRtcSpl_CrossCorrelation(corr32, target, regressor, + plc_blockl, 3, (WebRtc_Word16)shifts, 1); + + /* find lag */ + lag=WebRtcSpl_MaxIndexW32(corr32, 3); + lag+=tlag-1; + + /* Copy the backward PLC to plc_pred */ + + if (iLBCdec_inst->prev_enh_pl==1) { + if (lag>plc_blockl) { + WEBRTC_SPL_MEMCPY_W16(plc_pred, &in[lag-plc_blockl], plc_blockl); + } else { + WEBRTC_SPL_MEMCPY_W16(&plc_pred[plc_blockl-lag], in, lag); + WEBRTC_SPL_MEMCPY_W16(plc_pred, &enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl+lag], (plc_blockl-lag)); + } + } else { + int pos; + + pos = plc_blockl; + + while (lag<pos) { + WEBRTC_SPL_MEMCPY_W16(&plc_pred[pos-lag], in, lag); + pos = pos - lag; + } + WEBRTC_SPL_MEMCPY_W16(plc_pred, &in[lag-pos], pos); + + } + + if (iLBCdec_inst->prev_enh_pl==1) { + /* limit energy change + if energy in backward PLC is more than 4 times higher than the forward PLC, + then reduce the energy in the backward PLC vector: + sample 1...len-16 set energy of the to 4 times forward PLC + sample len-15..len interpolate between 4 times fw PLC and bw PLC energy + + Note: Compared to floating point code there is a slight change, + the window is 16 samples long instead of 10 samples to simplify the calculations + */ + + max=WebRtcSpl_MaxAbsValueW16(&enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl], plc_blockl); + max16=WebRtcSpl_MaxAbsValueW16(plc_pred, plc_blockl); + max = WEBRTC_SPL_MAX(max, max16); + scale=22-(WebRtc_Word16)WebRtcSpl_NormW32(max); + scale=WEBRTC_SPL_MAX(scale,0); + + tmp2 = WebRtcSpl_DotProductWithScale(&enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl], &enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl], plc_blockl, scale); + tmp1 = WebRtcSpl_DotProductWithScale(plc_pred, plc_pred, plc_blockl, scale); + + /* Check the energy difference */ + if ((tmp1>0)&&((tmp1>>2)>tmp2)) { + /* EnChange is now guaranteed to be <0.5 + Calculate EnChange=tmp2/tmp1 in Q16 + */ + + scale1=(WebRtc_Word16)WebRtcSpl_NormW32(tmp1); + tmp1=WEBRTC_SPL_SHIFT_W32(tmp1, (scale1-16)); /* using 15 bits */ + + tmp2=WEBRTC_SPL_SHIFT_W32(tmp2, (scale1)); + EnChange = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp2, (WebRtc_Word16)tmp1); + + /* Calculate the Sqrt of the energy in Q15 ((14+16)/2) */ + SqrtEnChange = (WebRtc_Word16)WebRtcSpl_Sqrt(WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)EnChange, 14)); + + /* Multiply first part of vector with 2*SqrtEnChange */ + WebRtcSpl_ScaleVector(plc_pred, plc_pred, SqrtEnChange, (WebRtc_Word16)(plc_blockl-16), 14); + + /* Calculate increase parameter for window part (16 last samples) */ + inc=(2048-WEBRTC_SPL_RSHIFT_W16(SqrtEnChange, 3)); /* (1-2*SqrtEnChange)/16 in Q15 */ + + win=0; + tmpW16ptr=&plc_pred[plc_blockl-16]; + + for (i=16;i>0;i--) { + (*tmpW16ptr)=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((*tmpW16ptr), + (SqrtEnChange+(win>>1)), 14); /* multiply by (2.0*SqrtEnChange+win) */ + + win += inc; + tmpW16ptr++; + } + } + + /* Make the linear interpolation between the forward PLC'd data + and the backward PLC'd data (from the new frame) + */ + + if (plc_blockl==40) { + inc=400; /* 1/41 in Q14 */ + } else { /* plc_blockl==80 */ + inc=202; /* 1/81 in Q14 */ + } + win=0; + enh_bufPtr1=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl]; + for (i=0; i<plc_blockl; i++) { + win+=inc; + *enh_bufPtr1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((*enh_bufPtr1), win, 14); + *enh_bufPtr1 += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((16384-win), plc_pred[plc_blockl-1-i], 14); + enh_bufPtr1--; + } + } else { + WebRtc_Word16 *synt = &downsampled[LPC_FILTERORDER]; + + enh_bufPtr1=&enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl]; + WEBRTC_SPL_MEMCPY_W16(enh_bufPtr1, plc_pred, plc_blockl); + + /* Clear fileter memory */ + WebRtcSpl_MemSetW16(iLBCdec_inst->syntMem, 0, LPC_FILTERORDER); + WebRtcSpl_MemSetW16(iLBCdec_inst->hpimemy, 0, 4); + WebRtcSpl_MemSetW16(iLBCdec_inst->hpimemx, 0, 2); + + /* Initialize filter memory by filtering through 2 lags */ + WEBRTC_SPL_MEMCPY_W16(&synt[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER); + WebRtcSpl_FilterARFastQ12( + enh_bufPtr1, synt, + &iLBCdec_inst->old_syntdenum[(iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1)], LPC_FILTERORDER+1, (WebRtc_Word16)lag); + + WEBRTC_SPL_MEMCPY_W16(&synt[-LPC_FILTERORDER], &synt[lag-LPC_FILTERORDER], LPC_FILTERORDER); + WebRtcIlbcfix_HpOutput(synt, (WebRtc_Word16*)WebRtcIlbcfix_kHpOutCoefs, + iLBCdec_inst->hpimemy, iLBCdec_inst->hpimemx, + (WebRtc_Word16)lag); + WebRtcSpl_FilterARFastQ12( + enh_bufPtr1, synt, + &iLBCdec_inst->old_syntdenum[(iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1)], LPC_FILTERORDER+1, (WebRtc_Word16)lag); + + WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &synt[lag-LPC_FILTERORDER], LPC_FILTERORDER); + WebRtcIlbcfix_HpOutput(synt, (WebRtc_Word16*)WebRtcIlbcfix_kHpOutCoefs, + iLBCdec_inst->hpimemy, iLBCdec_inst->hpimemx, + (WebRtc_Word16)lag); + } + } + + + /* Perform enhancement block by block */ + + for (iblock = 0; iblock<new_blocks; iblock++) { + WebRtcIlbcfix_Enhancer(iLBCdec_inst, out+WEBRTC_SPL_MUL_16_16(iblock, ENH_BLOCKL), enh_buf, + ENH_BUFL, (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16(iblock, ENH_BLOCKL)+startPos), + enh_period, (WebRtc_Word16*)WebRtcIlbcfix_kEnhPlocs, ENH_NBLOCKS_TOT); + } + + return (lag); +} diff --git a/src/libs/webrtc/ilbcfix/enhancer_interface.h b/src/libs/webrtc/ilbcfix/enhancer_interface.h new file mode 100644 index 00000000..37b27e2f --- /dev/null +++ b/src/libs/webrtc/ilbcfix/enhancer_interface.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_EnhancerInterface.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENHANCER_INTERFACE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENHANCER_INTERFACE_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * interface for enhancer + *---------------------------------------------------------------*/ + +int WebRtcIlbcfix_EnhancerInterface( /* (o) Estimated lag in end of in[] */ + WebRtc_Word16 *out, /* (o) enhanced signal */ + WebRtc_Word16 *in, /* (i) unenhanced signal */ + iLBC_Dec_Inst_t *iLBCdec_inst /* (i) buffers etc */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/filtered_cb_vecs.c b/src/libs/webrtc/ilbcfix/filtered_cb_vecs.c new file mode 100644 index 00000000..7cece268 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/filtered_cb_vecs.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_FilteredCbVecs.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * Construct an additional codebook vector by filtering the + * initial codebook buffer. This vector is then used to expand + * the codebook with an additional section. + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_FilteredCbVecs( + WebRtc_Word16 *cbvectors, /* (o) Codebook vector for the higher section */ + WebRtc_Word16 *CBmem, /* (i) Codebook memory that is filtered to create a + second CB section */ + int lMem, /* (i) Length of codebook memory */ + WebRtc_Word16 samples /* (i) Number of samples to filter */ + ) { + + /* Set up the memory, start with zero state */ + WebRtcSpl_MemSetW16(CBmem+lMem, 0, CB_HALFFILTERLEN); + WebRtcSpl_MemSetW16(CBmem-CB_HALFFILTERLEN, 0, CB_HALFFILTERLEN); + WebRtcSpl_MemSetW16(cbvectors, 0, lMem-samples); + + /* Filter to obtain the filtered CB memory */ + + WebRtcSpl_FilterMAFastQ12( + CBmem+CB_HALFFILTERLEN+lMem-samples, cbvectors+lMem-samples, + (WebRtc_Word16*)WebRtcIlbcfix_kCbFiltersRev, CB_FILTERLEN, samples); + + return; +} diff --git a/src/libs/webrtc/ilbcfix/filtered_cb_vecs.h b/src/libs/webrtc/ilbcfix/filtered_cb_vecs.h new file mode 100644 index 00000000..c502e8f3 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/filtered_cb_vecs.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_FilteredCbVecs.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_FILTERED_CB_VECS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_FILTERED_CB_VECS_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Construct an additional codebook vector by filtering the + * initial codebook buffer. This vector is then used to expand + * the codebook with an additional section. + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_FilteredCbVecs( + WebRtc_Word16 *cbvectors, /* (o) Codebook vector for the higher section */ + WebRtc_Word16 *CBmem, /* (i) Codebook memory that is filtered to create a + second CB section */ + int lMem, /* (i) Length of codebook memory */ + WebRtc_Word16 samples /* (i) Number of samples to filter */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/frame_classify.c b/src/libs/webrtc/ilbcfix/frame_classify.c new file mode 100644 index 00000000..ea3675e1 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/frame_classify.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_FrameClassify.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * Classification of subframes to localize start state + *---------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_FrameClassify( + /* (o) Index to the max-energy sub frame */ + iLBC_Enc_Inst_t *iLBCenc_inst, + /* (i/o) the encoder state structure */ + WebRtc_Word16 *residualFIX /* (i) lpc residual signal */ + ){ + WebRtc_Word16 max, scale; + WebRtc_Word32 ssqEn[NSUB_MAX-1]; + WebRtc_Word16 *ssqPtr; + WebRtc_Word32 *seqEnPtr; + WebRtc_Word32 maxW32; + WebRtc_Word16 scale1; + WebRtc_Word16 pos; + int n; + + /* + Calculate the energy of each of the 80 sample blocks + in the draft the 4 first and last samples are windowed with 1/5...4/5 + and 4/5...1/5 respectively. To simplify for the fixpoint we have changed + this to 0 0 1 1 and 1 1 0 0 + */ + + max = WebRtcSpl_MaxAbsValueW16(residualFIX, iLBCenc_inst->blockl); + scale=WebRtcSpl_GetSizeInBits(WEBRTC_SPL_MUL_16_16(max,max)); + + /* Scale to maximum 24 bits so that it won't overflow for 76 samples */ + scale = scale-24; + scale1 = WEBRTC_SPL_MAX(0, scale); + + /* Calculate energies */ + ssqPtr=residualFIX + 2; + seqEnPtr=ssqEn; + for (n=(iLBCenc_inst->nsub-1); n>0; n--) { + (*seqEnPtr) = WebRtcSpl_DotProductWithScale(ssqPtr, ssqPtr, 76, scale1); + ssqPtr += 40; + seqEnPtr++; + } + + /* Scale to maximum 20 bits in order to allow for the 11 bit window */ + maxW32 = WebRtcSpl_MaxValueW32(ssqEn, (WebRtc_Word16)(iLBCenc_inst->nsub-1)); + scale = WebRtcSpl_GetSizeInBits(maxW32) - 20; + scale1 = WEBRTC_SPL_MAX(0, scale); + + /* Window each 80 block with the ssqEn_winTbl window to give higher probability for + the blocks in the middle + */ + seqEnPtr=ssqEn; + if (iLBCenc_inst->mode==20) { + ssqPtr=(WebRtc_Word16*)WebRtcIlbcfix_kStartSequenceEnrgWin+1; + } else { + ssqPtr=(WebRtc_Word16*)WebRtcIlbcfix_kStartSequenceEnrgWin; + } + for (n=(iLBCenc_inst->nsub-1); n>0; n--) { + (*seqEnPtr)=WEBRTC_SPL_MUL(((*seqEnPtr)>>scale1), (*ssqPtr)); + seqEnPtr++; + ssqPtr++; + } + + /* Extract the best choise of start state */ + pos = WebRtcSpl_MaxIndexW32(ssqEn, (WebRtc_Word16)(iLBCenc_inst->nsub-1)) + 1; + + return(pos); +} diff --git a/src/libs/webrtc/ilbcfix/frame_classify.h b/src/libs/webrtc/ilbcfix/frame_classify.h new file mode 100644 index 00000000..faf46666 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/frame_classify.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_FrameClassify.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_FRAME_CLASSIFY_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_FRAME_CLASSIFY_H_ + +WebRtc_Word16 WebRtcIlbcfix_FrameClassify( + /* (o) Index to the max-energy sub frame */ + iLBC_Enc_Inst_t *iLBCenc_inst, + /* (i/o) the encoder state structure */ + WebRtc_Word16 *residualFIX /* (i) lpc residual signal */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/gain_dequant.c b/src/libs/webrtc/ilbcfix/gain_dequant.c new file mode 100644 index 00000000..9450a800 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/gain_dequant.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_GainDequant.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * decoder for quantized gains in the gain-shape coding of + * residual + *---------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_GainDequant( + /* (o) quantized gain value (Q14) */ + WebRtc_Word16 index, /* (i) quantization index */ + WebRtc_Word16 maxIn, /* (i) maximum of unquantized gain (Q14) */ + WebRtc_Word16 stage /* (i) The stage of the search */ + ){ + WebRtc_Word16 scale; + const WebRtc_Word16 *gain; + + /* obtain correct scale factor */ + + scale=WEBRTC_SPL_ABS_W16(maxIn); + scale = WEBRTC_SPL_MAX(1638, scale); /* if lower than 0.1, set it to 0.1 */ + + /* select the quantization table and return the decoded value */ + gain = WebRtcIlbcfix_kGain[stage]; + + return((WebRtc_Word16)((WEBRTC_SPL_MUL_16_16(scale, gain[index])+8192)>>14)); +} diff --git a/src/libs/webrtc/ilbcfix/gain_dequant.h b/src/libs/webrtc/ilbcfix/gain_dequant.h new file mode 100644 index 00000000..28f2ceb2 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/gain_dequant.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_GainDequant.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GAIN_DEQUANT_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GAIN_DEQUANT_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * decoder for quantized gains in the gain-shape coding of + * residual + *---------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_GainDequant( + /* (o) quantized gain value (Q14) */ + WebRtc_Word16 index, /* (i) quantization index */ + WebRtc_Word16 maxIn, /* (i) maximum of unquantized gain (Q14) */ + WebRtc_Word16 stage /* (i) The stage of the search */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/gain_quant.c b/src/libs/webrtc/ilbcfix/gain_quant.c new file mode 100644 index 00000000..bdf88a5c --- /dev/null +++ b/src/libs/webrtc/ilbcfix/gain_quant.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_GainQuant.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * quantizer for the gain in the gain-shape coding of residual + *---------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_GainQuant( /* (o) quantized gain value */ + WebRtc_Word16 gain, /* (i) gain value Q14 */ + WebRtc_Word16 maxIn, /* (i) maximum of gain value Q14 */ + WebRtc_Word16 stage, /* (i) The stage of the search */ + WebRtc_Word16 *index /* (o) quantization index */ + ) { + + WebRtc_Word16 scale, returnVal, cblen; + WebRtc_Word32 gainW32, measure1, measure2; + const WebRtc_Word16 *cbPtr, *cb; + int loc, noMoves, noChecks, i; + + /* ensure a lower bound (0.1) on the scaling factor */ + + scale = WEBRTC_SPL_MAX(1638, maxIn); + + /* select the quantization table and calculate + the length of the table and the number of + steps in the binary search that are needed */ + cb = WebRtcIlbcfix_kGain[stage]; + cblen = 32>>stage; + noChecks = 4-stage; + + /* Multiply the gain with 2^14 to make the comparison + easier and with higher precision */ + gainW32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)gain, 14); + + /* Do a binary search, starting in the middle of the CB + loc - defines the current position in the table + noMoves - defines the number of steps to move in the CB in order + to get next CB location + */ + + loc = cblen>>1; + noMoves = loc; + cbPtr = cb + loc; /* Centre of CB */ + + for (i=noChecks;i>0;i--) { + noMoves>>=1; + measure1=WEBRTC_SPL_MUL_16_16(scale, (*cbPtr)); + + /* Move up if gain is larger, otherwise move down in table */ + measure1 = measure1 - gainW32; + + if (0>measure1) { + cbPtr+=noMoves; + loc+=noMoves; + } else { + cbPtr-=noMoves; + loc-=noMoves; + } + } + + /* Check which value is the closest one: loc-1, loc or loc+1 */ + + measure1=WEBRTC_SPL_MUL_16_16(scale, (*cbPtr)); + if (gainW32>measure1) { + /* Check against value above loc */ + measure2=WEBRTC_SPL_MUL_16_16(scale, (*(cbPtr+1))); + if ((measure2-gainW32)<(gainW32-measure1)) { + loc+=1; + } + } else { + /* Check against value below loc */ + measure2=WEBRTC_SPL_MUL_16_16(scale, (*(cbPtr-1))); + if ((gainW32-measure2)<=(measure1-gainW32)) { + loc-=1; + } + } + + /* Guard against getting outside the table. The calculation above can give a location + which is one above the maximum value (in very rare cases) */ + loc=WEBRTC_SPL_MIN(loc, (cblen-1)); + *index=loc; + + /* Calculate the quantized gain value (in Q14) */ + returnVal=(WebRtc_Word16)((WEBRTC_SPL_MUL_16_16(scale, cb[loc])+8192)>>14); + + /* return the quantized value */ + return(returnVal); +} diff --git a/src/libs/webrtc/ilbcfix/gain_quant.h b/src/libs/webrtc/ilbcfix/gain_quant.h new file mode 100644 index 00000000..a2f05969 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/gain_quant.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_GainQuant.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GAIN_QUANT_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GAIN_QUANT_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * quantizer for the gain in the gain-shape coding of residual + *---------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_GainQuant( /* (o) quantized gain value */ + WebRtc_Word16 gain, /* (i) gain value Q14 */ + WebRtc_Word16 maxIn, /* (i) maximum of gain value Q14 */ + WebRtc_Word16 stage, /* (i) The stage of the search */ + WebRtc_Word16 *index /* (o) quantization index */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/get_cd_vec.c b/src/libs/webrtc/ilbcfix/get_cd_vec.c new file mode 100644 index 00000000..aba3e31f --- /dev/null +++ b/src/libs/webrtc/ilbcfix/get_cd_vec.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_GetCbVec.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "create_augmented_vec.h" + +/*----------------------------------------------------------------* + * Construct codebook vector for given index. + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_GetCbVec( + WebRtc_Word16 *cbvec, /* (o) Constructed codebook vector */ + WebRtc_Word16 *mem, /* (i) Codebook buffer */ + WebRtc_Word16 index, /* (i) Codebook index */ + WebRtc_Word16 lMem, /* (i) Length of codebook buffer */ + WebRtc_Word16 cbveclen /* (i) Codebook vector length */ + ){ + WebRtc_Word16 k, base_size; + WebRtc_Word16 lag; + /* Stack based */ + WebRtc_Word16 tempbuff2[SUBL+5]; + + /* Determine size of codebook sections */ + + base_size=lMem-cbveclen+1; + + if (cbveclen==SUBL) { + base_size+=WEBRTC_SPL_RSHIFT_W16(cbveclen,1); + } + + /* No filter -> First codebook section */ + + if (index<lMem-cbveclen+1) { + + /* first non-interpolated vectors */ + + k=index+cbveclen; + /* get vector */ + WEBRTC_SPL_MEMCPY_W16(cbvec, mem+lMem-k, cbveclen); + + } else if (index < base_size) { + + /* Calculate lag */ + + k=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16(2, (index-(lMem-cbveclen+1)))+cbveclen; + + lag=WEBRTC_SPL_RSHIFT_W16(k, 1); + + WebRtcIlbcfix_CreateAugmentedVec(lag, mem+lMem, cbvec); + + } + + /* Higher codebbok section based on filtering */ + + else { + + WebRtc_Word16 memIndTest; + + /* first non-interpolated vectors */ + + if (index-base_size<lMem-cbveclen+1) { + + /* Set up filter memory, stuff zeros outside memory buffer */ + + memIndTest = lMem-(index-base_size+cbveclen); + + WebRtcSpl_MemSetW16(mem-CB_HALFFILTERLEN, 0, CB_HALFFILTERLEN); + WebRtcSpl_MemSetW16(mem+lMem, 0, CB_HALFFILTERLEN); + + /* do filtering to get the codebook vector */ + + WebRtcSpl_FilterMAFastQ12( + &mem[memIndTest+4], cbvec, (WebRtc_Word16*)WebRtcIlbcfix_kCbFiltersRev, + CB_FILTERLEN, cbveclen); + } + + /* interpolated vectors */ + + else { + /* Stuff zeros outside memory buffer */ + memIndTest = lMem-cbveclen-CB_FILTERLEN; + WebRtcSpl_MemSetW16(mem+lMem, 0, CB_HALFFILTERLEN); + + /* do filtering */ + WebRtcSpl_FilterMAFastQ12( + &mem[memIndTest+7], tempbuff2, (WebRtc_Word16*)WebRtcIlbcfix_kCbFiltersRev, + CB_FILTERLEN, (WebRtc_Word16)(cbveclen+5)); + + /* Calculate lag index */ + lag = (cbveclen<<1)-20+index-base_size-lMem-1; + + WebRtcIlbcfix_CreateAugmentedVec(lag, tempbuff2+SUBL+5, cbvec); + } + } +} diff --git a/src/libs/webrtc/ilbcfix/get_cd_vec.h b/src/libs/webrtc/ilbcfix/get_cd_vec.h new file mode 100644 index 00000000..99b5d4e5 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/get_cd_vec.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_GetCbVec.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_CD_VEC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_CD_VEC_H_ + +void WebRtcIlbcfix_GetCbVec( + WebRtc_Word16 *cbvec, /* (o) Constructed codebook vector */ + WebRtc_Word16 *mem, /* (i) Codebook buffer */ + WebRtc_Word16 index, /* (i) Codebook index */ + WebRtc_Word16 lMem, /* (i) Length of codebook buffer */ + WebRtc_Word16 cbveclen /* (i) Codebook vector length */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/get_lsp_poly.c b/src/libs/webrtc/ilbcfix/get_lsp_poly.c new file mode 100644 index 00000000..c55e9181 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/get_lsp_poly.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_GetLspPoly.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Construct the polynomials F1(z) and F2(z) from the LSP + * (Computations are done in Q24) + * + * The expansion is performed using the following recursion: + * + * f[0] = 1; + * tmp = -2.0 * lsp[0]; + * f[1] = tmp; + * for (i=2; i<=5; i++) { + * b = -2.0 * lsp[2*i-2]; + * f[i] = tmp*f[i-1] + 2.0*f[i-2]; + * for (j=i; j>=2; j--) { + * f[j] = f[j] + tmp*f[j-1] + f[j-2]; + * } + * f[i] = f[i] + tmp; + * } + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_GetLspPoly( + WebRtc_Word16 *lsp, /* (i) LSP in Q15 */ + WebRtc_Word32 *f) /* (o) polonymial in Q24 */ +{ + WebRtc_Word32 tmpW32; + int i, j; + WebRtc_Word16 high, low; + WebRtc_Word16 *lspPtr; + WebRtc_Word32 *fPtr; + + lspPtr = lsp; + fPtr = f; + /* f[0] = 1.0 (Q24) */ + (*fPtr) = (WebRtc_Word32)16777216; + fPtr++; + + (*fPtr) = WEBRTC_SPL_MUL((*lspPtr), -1024); + fPtr++; + lspPtr+=2; + + for(i=2; i<=5; i++) + { + (*fPtr) = fPtr[-2]; + + for(j=i; j>1; j--) + { + /* Compute f[j] = f[j] + tmp*f[j-1] + f[j-2]; */ + high = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(fPtr[-1], 16); + low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(fPtr[-1]-WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)high),16), 1); + + tmpW32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(high, (*lspPtr)), 2) + + WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16_RSFT(low, (*lspPtr), 15), 2); + + (*fPtr) += fPtr[-2]; + (*fPtr) -= tmpW32; + fPtr--; + } + (*fPtr) -= (WebRtc_Word32)WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)(*lspPtr), 10); + + fPtr+=i; + lspPtr+=2; + } + return; +} diff --git a/src/libs/webrtc/ilbcfix/get_lsp_poly.h b/src/libs/webrtc/ilbcfix/get_lsp_poly.h new file mode 100644 index 00000000..b0520b4c --- /dev/null +++ b/src/libs/webrtc/ilbcfix/get_lsp_poly.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_GetLspPoly.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_LSP_POLY_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_LSP_POLY_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Construct the polynomials F1(z) and F2(z) from the LSP + * (Computations are done in Q24) + * + * The expansion is performed using the following recursion: + * + * f[0] = 1; + * tmp = -2.0 * lsp[0]; + * f[1] = tmp; + * for (i=2; i<=5; i++) { + * b = -2.0 * lsp[2*i-2]; + * f[i] = tmp*f[i-1] + 2.0*f[i-2]; + * for (j=i; j>=2; j--) { + * f[j] = f[j] + tmp*f[j-1] + f[j-2]; + * } + * f[i] = f[i] + tmp; + * } + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_GetLspPoly( + WebRtc_Word16 *lsp, /* (i) LSP in Q15 */ + WebRtc_Word32 *f); /* (o) polonymial in Q24 */ + +#endif diff --git a/src/libs/webrtc/ilbcfix/get_sync_seq.c b/src/libs/webrtc/ilbcfix/get_sync_seq.c new file mode 100644 index 00000000..4f13cf3d --- /dev/null +++ b/src/libs/webrtc/ilbcfix/get_sync_seq.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_GetSyncSeq.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "refiner.h" +#include "nearest_neighbor.h" + +/*----------------------------------------------------------------* + * get the pitch-synchronous sample sequence + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_GetSyncSeq( + iLBC_Dec_Inst_t *iLBCdec_inst, + /* (i) Decoder state */ + WebRtc_Word16 *idata, /* (i) original data */ + WebRtc_Word16 idatal, /* (i) dimension of data */ + WebRtc_Word16 centerStartPos, /* (i) where current block starts */ + WebRtc_Word16 *period, /* (i) rough-pitch-period array (Q-2) */ + WebRtc_Word16 *plocs, /* (i) where periods of period array are taken (Q-2) */ + WebRtc_Word16 periodl, /* (i) dimension period array */ + WebRtc_Word16 hl, /* (i) 2*hl+1 is the number of sequences */ + WebRtc_Word16 *surround /* (i/o) The contribution from this sequence + summed with earlier contributions */ + ){ + WebRtc_Word16 i,centerEndPos,q; + /* Stack based */ + WebRtc_Word16 lagBlock[2*ENH_HL+1]; + WebRtc_Word16 blockStartPos[2*ENH_HL+1]; /* Defines the position to search around (Q2) */ + WebRtc_Word16 plocs2[ENH_PLOCSL]; + + centerEndPos=centerStartPos+ENH_BLOCKL-1; + + /* present (find predicted lag from this position) */ + + WebRtcIlbcfix_NearestNeighbor(iLBCdec_inst, lagBlock+hl,plocs, + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(2, (centerStartPos+centerEndPos)), + periodl); + + blockStartPos[hl]=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16(4, centerStartPos); + + /* past (find predicted position and perform a refined + search to find the best sequence) */ + + for(q=hl-1;q>=0;q--) { + blockStartPos[q]=blockStartPos[q+1]-period[lagBlock[q+1]]; + + WebRtcIlbcfix_NearestNeighbor(iLBCdec_inst, lagBlock+q, plocs, + (WebRtc_Word16)(blockStartPos[q] + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(4, ENH_BLOCKL_HALF)-period[lagBlock[q+1]]), + periodl); + + if((blockStartPos[q]-(WebRtc_Word16)WEBRTC_SPL_MUL_16_16(4, ENH_OVERHANG))>=0) { + + /* Find the best possible sequence in the 4 times upsampled + domain around blockStartPos+q */ + WebRtcIlbcfix_Refiner(iLBCdec_inst, blockStartPos+q,idata,idatal, + centerStartPos,blockStartPos[q],surround,WebRtcIlbcfix_kEnhWt[q]); + + } else { + /* Don't add anything since this sequence would + be outside the buffer */ + } + } + + /* future (find predicted position and perform a refined + search to find the best sequence) */ + + for(i=0;i<periodl;i++) { + plocs2[i]=(plocs[i]-period[i]); + } + + for(q=hl+1;q<=WEBRTC_SPL_MUL_16_16(2, hl);q++) { + + WebRtcIlbcfix_NearestNeighbor(iLBCdec_inst, lagBlock+q,plocs2, + (WebRtc_Word16)(blockStartPos[q-1]+ + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(4, ENH_BLOCKL_HALF)),periodl); + + blockStartPos[q]=blockStartPos[q-1]+period[lagBlock[q]]; + + if( (blockStartPos[q]+(WebRtc_Word16)WEBRTC_SPL_MUL_16_16(4, (ENH_BLOCKL+ENH_OVERHANG))) + < + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(4, idatal)) { + + /* Find the best possible sequence in the 4 times upsampled + domain around blockStartPos+q */ + WebRtcIlbcfix_Refiner(iLBCdec_inst, blockStartPos+q, idata, idatal, + centerStartPos,blockStartPos[q],surround,WebRtcIlbcfix_kEnhWt[2*hl-q]); + + } + else { + /* Don't add anything since this sequence would + be outside the buffer */ + } + } +} diff --git a/src/libs/webrtc/ilbcfix/get_sync_seq.h b/src/libs/webrtc/ilbcfix/get_sync_seq.h new file mode 100644 index 00000000..c2d79458 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/get_sync_seq.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_GetSyncSeq.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_SYNC_SEQ_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_SYNC_SEQ_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * get the pitch-synchronous sample sequence + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_GetSyncSeq( + iLBC_Dec_Inst_t *iLBCdec_inst, + /* (i) Decoder state */ + WebRtc_Word16 *idata, /* (i) original data */ + WebRtc_Word16 idatal, /* (i) dimension of data */ + WebRtc_Word16 centerStartPos, /* (i) where current block starts */ + WebRtc_Word16 *period, /* (i) rough-pitch-period array (Q-2) */ + WebRtc_Word16 *plocs, /* (i) where periods of period array are taken (Q-2) */ + WebRtc_Word16 periodl, /* (i) dimension period array */ + WebRtc_Word16 hl, /* (i) 2*hl+1 is the number of sequences */ + WebRtc_Word16 *surround /* (i/o) The contribution from this sequence + summed with earlier contributions */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/hp_input.c b/src/libs/webrtc/ilbcfix/hp_input.c new file mode 100644 index 00000000..f202f62a --- /dev/null +++ b/src/libs/webrtc/ilbcfix/hp_input.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_HpInput.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * high-pass filter of input with *0.5 and saturation + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_HpInput( + WebRtc_Word16 *signal, /* (i/o) signal vector */ + WebRtc_Word16 *ba, /* (i) B- and A-coefficients (2:nd order) + {b[0] b[1] b[2] -a[1] -a[2]} a[0] + is assumed to be 1.0 */ + WebRtc_Word16 *y, /* (i/o) Filter state yhi[n-1] ylow[n-1] + yhi[n-2] ylow[n-2] */ + WebRtc_Word16 *x, /* (i/o) Filter state x[n-1] x[n-2] */ + WebRtc_Word16 len) /* (i) Number of samples to filter */ +{ + int i; + WebRtc_Word32 tmpW32; + WebRtc_Word32 tmpW32b; + + for (i=0; i<len; i++) { + + /* + y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] + + (-a[1])*y[i-1] + (-a[2])*y[i-2]; + */ + + tmpW32 = WEBRTC_SPL_MUL_16_16(y[1], ba[3]); /* (-a[1])*y[i-1] (low part) */ + tmpW32 += WEBRTC_SPL_MUL_16_16(y[3], ba[4]); /* (-a[2])*y[i-2] (low part) */ + tmpW32 = (tmpW32>>15); + tmpW32 += WEBRTC_SPL_MUL_16_16(y[0], ba[3]); /* (-a[1])*y[i-1] (high part) */ + tmpW32 += WEBRTC_SPL_MUL_16_16(y[2], ba[4]); /* (-a[2])*y[i-2] (high part) */ + tmpW32 = (tmpW32<<1); + + tmpW32 += WEBRTC_SPL_MUL_16_16(signal[i], ba[0]); /* b[0]*x[0] */ + tmpW32 += WEBRTC_SPL_MUL_16_16(x[0], ba[1]); /* b[1]*x[i-1] */ + tmpW32 += WEBRTC_SPL_MUL_16_16(x[1], ba[2]); /* b[2]*x[i-2] */ + + /* Update state (input part) */ + x[1] = x[0]; + x[0] = signal[i]; + + /* Rounding in Q(12+1), i.e. add 2^12 */ + tmpW32b = tmpW32 + 4096; + + /* Saturate (to 2^28) so that the HP filtered signal does not overflow */ + tmpW32b = WEBRTC_SPL_SAT((WebRtc_Word32)268435455, tmpW32b, (WebRtc_Word32)-268435456); + + /* Convert back to Q0 and multiply with 0.5 */ + signal[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32b, 13); + + /* Update state (filtered part) */ + y[2] = y[0]; + y[3] = y[1]; + + /* upshift tmpW32 by 3 with saturation */ + if (tmpW32>268435455) { + tmpW32 = WEBRTC_SPL_WORD32_MAX; + } else if (tmpW32<-268435456) { + tmpW32 = WEBRTC_SPL_WORD32_MIN; + } else { + tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3); + } + + y[0] = (WebRtc_Word16)(tmpW32 >> 16); + y[1] = (WebRtc_Word16)((tmpW32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)y[0], 16))>>1); + } + + return; +} diff --git a/src/libs/webrtc/ilbcfix/hp_input.h b/src/libs/webrtc/ilbcfix/hp_input.h new file mode 100644 index 00000000..f56c4f73 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/hp_input.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_HpInput.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_HP_INPUT_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_HP_INPUT_H_ + +#include "defines.h" + +void WebRtcIlbcfix_HpInput( + WebRtc_Word16 *signal, /* (i/o) signal vector */ + WebRtc_Word16 *ba, /* (i) B- and A-coefficients (2:nd order) + {b[0] b[1] b[2] -a[1] -a[2]} a[0] + is assumed to be 1.0 */ + WebRtc_Word16 *y, /* (i/o) Filter state yhi[n-1] ylow[n-1] + yhi[n-2] ylow[n-2] */ + WebRtc_Word16 *x, /* (i/o) Filter state x[n-1] x[n-2] */ + WebRtc_Word16 len); /* (i) Number of samples to filter */ + +#endif diff --git a/src/libs/webrtc/ilbcfix/hp_output.c b/src/libs/webrtc/ilbcfix/hp_output.c new file mode 100644 index 00000000..8e1c9191 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/hp_output.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_HpOutput.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * high-pass filter of output and *2 with saturation + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_HpOutput( + WebRtc_Word16 *signal, /* (i/o) signal vector */ + WebRtc_Word16 *ba, /* (i) B- and A-coefficients (2:nd order) + {b[0] b[1] b[2] -a[1] -a[2]} a[0] + is assumed to be 1.0 */ + WebRtc_Word16 *y, /* (i/o) Filter state yhi[n-1] ylow[n-1] + yhi[n-2] ylow[n-2] */ + WebRtc_Word16 *x, /* (i/o) Filter state x[n-1] x[n-2] */ + WebRtc_Word16 len) /* (i) Number of samples to filter */ +{ + int i; + WebRtc_Word32 tmpW32; + WebRtc_Word32 tmpW32b; + + for (i=0; i<len; i++) { + + /* + y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] + + (-a[1])*y[i-1] + (-a[2])*y[i-2]; + */ + + tmpW32 = WEBRTC_SPL_MUL_16_16(y[1], ba[3]); /* (-a[1])*y[i-1] (low part) */ + tmpW32 += WEBRTC_SPL_MUL_16_16(y[3], ba[4]); /* (-a[2])*y[i-2] (low part) */ + tmpW32 = (tmpW32>>15); + tmpW32 += WEBRTC_SPL_MUL_16_16(y[0], ba[3]); /* (-a[1])*y[i-1] (high part) */ + tmpW32 += WEBRTC_SPL_MUL_16_16(y[2], ba[4]); /* (-a[2])*y[i-2] (high part) */ + tmpW32 = (tmpW32<<1); + + tmpW32 += WEBRTC_SPL_MUL_16_16(signal[i], ba[0]); /* b[0]*x[0] */ + tmpW32 += WEBRTC_SPL_MUL_16_16(x[0], ba[1]); /* b[1]*x[i-1] */ + tmpW32 += WEBRTC_SPL_MUL_16_16(x[1], ba[2]); /* b[2]*x[i-2] */ + + /* Update state (input part) */ + x[1] = x[0]; + x[0] = signal[i]; + + /* Rounding in Q(12-1), i.e. add 2^10 */ + tmpW32b = tmpW32 + 1024; + + /* Saturate (to 2^26) so that the HP filtered signal does not overflow */ + tmpW32b = WEBRTC_SPL_SAT((WebRtc_Word32)67108863, tmpW32b, (WebRtc_Word32)-67108864); + + /* Convert back to Q0 and multiply with 2 */ + signal[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32b, 11); + + /* Update state (filtered part) */ + y[2] = y[0]; + y[3] = y[1]; + + /* upshift tmpW32 by 3 with saturation */ + if (tmpW32>268435455) { + tmpW32 = WEBRTC_SPL_WORD32_MAX; + } else if (tmpW32<-268435456) { + tmpW32 = WEBRTC_SPL_WORD32_MIN; + } else { + tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3); + } + + y[0] = (WebRtc_Word16)(tmpW32 >> 16); + y[1] = (WebRtc_Word16)((tmpW32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)y[0], 16))>>1); + + } + + return; +} diff --git a/src/libs/webrtc/ilbcfix/hp_output.h b/src/libs/webrtc/ilbcfix/hp_output.h new file mode 100644 index 00000000..c9a7426e --- /dev/null +++ b/src/libs/webrtc/ilbcfix/hp_output.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_HpOutput.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_HP_OUTPUT_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_HP_OUTPUT_H_ + +#include "defines.h" + +void WebRtcIlbcfix_HpOutput( + WebRtc_Word16 *signal, /* (i/o) signal vector */ + WebRtc_Word16 *ba, /* (i) B- and A-coefficients (2:nd order) + {b[0] b[1] b[2] -a[1] -a[2]} a[0] + is assumed to be 1.0 */ + WebRtc_Word16 *y, /* (i/o) Filter state yhi[n-1] ylow[n-1] + yhi[n-2] ylow[n-2] */ + WebRtc_Word16 *x, /* (i/o) Filter state x[n-1] x[n-2] */ + WebRtc_Word16 len); /* (i) Number of samples to filter */ + +#endif diff --git a/src/libs/webrtc/ilbcfix/ilbc.c b/src/libs/webrtc/ilbcfix/ilbc.c new file mode 100644 index 00000000..e479d3e0 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/ilbc.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + iLBCInterface.c + +******************************************************************/ + +#include "ilbc.h" +#include "defines.h" +#include "init_encode.h" +#include "encode.h" +#include "init_decode.h" +#include "decode.h" +#include <stdlib.h> + + +WebRtc_Word16 WebRtcIlbcfix_EncoderAssign(iLBC_encinst_t **iLBC_encinst, WebRtc_Word16 *ILBCENC_inst_Addr, WebRtc_Word16 *size) { + *iLBC_encinst=(iLBC_encinst_t*)ILBCENC_inst_Addr; + *size=sizeof(iLBC_Enc_Inst_t)/sizeof(WebRtc_Word16); + if (*iLBC_encinst!=NULL) { + return(0); + } else { + return(-1); + } +} + +WebRtc_Word16 WebRtcIlbcfix_DecoderAssign(iLBC_decinst_t **iLBC_decinst, WebRtc_Word16 *ILBCDEC_inst_Addr, WebRtc_Word16 *size) { + *iLBC_decinst=(iLBC_decinst_t*)ILBCDEC_inst_Addr; + *size=sizeof(iLBC_Dec_Inst_t)/sizeof(WebRtc_Word16); + if (*iLBC_decinst!=NULL) { + return(0); + } else { + return(-1); + } +} + +WebRtc_Word16 WebRtcIlbcfix_EncoderCreate(iLBC_encinst_t **iLBC_encinst) { + *iLBC_encinst=(iLBC_encinst_t*)malloc(sizeof(iLBC_Enc_Inst_t)); + if (*iLBC_encinst!=NULL) { + return(0); + } else { + return(-1); + } +} + +WebRtc_Word16 WebRtcIlbcfix_DecoderCreate(iLBC_decinst_t **iLBC_decinst) { + *iLBC_decinst=(iLBC_decinst_t*)malloc(sizeof(iLBC_Dec_Inst_t)); + if (*iLBC_decinst!=NULL) { + return(0); + } else { + return(-1); + } +} + +WebRtc_Word16 WebRtcIlbcfix_EncoderFree(iLBC_encinst_t *iLBC_encinst) { + free(iLBC_encinst); + return(0); +} + +WebRtc_Word16 WebRtcIlbcfix_DecoderFree(iLBC_decinst_t *iLBC_decinst) { + free(iLBC_decinst); + return(0); +} + + +WebRtc_Word16 WebRtcIlbcfix_EncoderInit(iLBC_encinst_t *iLBCenc_inst, WebRtc_Word16 mode) +{ + if ((mode==20)||(mode==30)) { + WebRtcIlbcfix_InitEncode((iLBC_Enc_Inst_t*) iLBCenc_inst, mode); + return(0); + } else { + return(-1); + } +} + +WebRtc_Word16 WebRtcIlbcfix_Encode(iLBC_encinst_t *iLBCenc_inst, WebRtc_Word16 *speechIn, WebRtc_Word16 len, WebRtc_Word16 *encoded) { + + WebRtc_Word16 pos = 0; + WebRtc_Word16 encpos = 0; + + if ((len != ((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl) && +#ifdef SPLIT_10MS + (len != 80) && +#endif + (len != 2*((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl) && + (len != 3*((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl)) + { + /* A maximum of 3 frames/packet is allowed */ + return(-1); + } else { + + /* call encoder */ + while (pos<len) { + WebRtcIlbcfix_EncodeImpl((WebRtc_UWord16*) &encoded[encpos], &speechIn[pos], (iLBC_Enc_Inst_t*) iLBCenc_inst); +#ifdef SPLIT_10MS + pos += 80; + if(((iLBC_Enc_Inst_t*)iLBCenc_inst)->section == 0) +#else + pos += ((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl; +#endif + encpos += ((iLBC_Enc_Inst_t*)iLBCenc_inst)->no_of_words; + } + return (encpos*2); + } +} + +WebRtc_Word16 WebRtcIlbcfix_DecoderInit(iLBC_decinst_t *iLBCdec_inst, WebRtc_Word16 mode) { + if ((mode==20)||(mode==30)) { + WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, mode, 1); + return(0); + } else { + return(-1); + } +} +WebRtc_Word16 WebRtcIlbcfix_DecoderInit20Ms(iLBC_decinst_t *iLBCdec_inst) { + WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, 20, 1); + return(0); +} +WebRtc_Word16 WebRtcIlbcfix_Decoderinit30Ms(iLBC_decinst_t *iLBCdec_inst) { + WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, 30, 1); + return(0); +} + + +WebRtc_Word16 WebRtcIlbcfix_Decode(iLBC_decinst_t *iLBCdec_inst, + WebRtc_Word16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType) +{ + int i=0; + /* Allow for automatic switching between the frame sizes + (although you do get some discontinuity) */ + if ((len==((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)|| + (len==2*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)|| + (len==3*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)) { + /* ok, do nothing */ + } else { + /* Test if the mode has changed */ + if (((iLBC_Dec_Inst_t*)iLBCdec_inst)->mode==20) { + if ((len==NO_OF_BYTES_30MS)|| + (len==2*NO_OF_BYTES_30MS)|| + (len==3*NO_OF_BYTES_30MS)) { + WebRtcIlbcfix_InitDecode(((iLBC_Dec_Inst_t*)iLBCdec_inst), 30, ((iLBC_Dec_Inst_t*)iLBCdec_inst)->use_enhancer); + } else { + /* Unsupported frame length */ + return(-1); + } + } else { + if ((len==NO_OF_BYTES_20MS)|| + (len==2*NO_OF_BYTES_20MS)|| + (len==3*NO_OF_BYTES_20MS)) { + WebRtcIlbcfix_InitDecode(((iLBC_Dec_Inst_t*)iLBCdec_inst), 20, ((iLBC_Dec_Inst_t*)iLBCdec_inst)->use_enhancer); + } else { + /* Unsupported frame length */ + return(-1); + } + } + } + + while ((i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)<len) { + WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], (WebRtc_UWord16*) &encoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_words], (iLBC_Dec_Inst_t*) iLBCdec_inst, 1); + i++; + } + /* iLBC does not support VAD/CNG yet */ + *speechType=1; + return(i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl); +} + +WebRtc_Word16 WebRtcIlbcfix_Decode20Ms(iLBC_decinst_t *iLBCdec_inst, + WebRtc_Word16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType) +{ + int i=0; + if ((len==((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)|| + (len==2*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)|| + (len==3*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)) { + /* ok, do nothing */ + } else { + return(-1); + } + + while ((i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)<len) { + WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], (WebRtc_UWord16*) &encoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_words], (iLBC_Dec_Inst_t*) iLBCdec_inst, 1); + i++; + } + /* iLBC does not support VAD/CNG yet */ + *speechType=1; + return(i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl); +} + +WebRtc_Word16 WebRtcIlbcfix_Decode30Ms(iLBC_decinst_t *iLBCdec_inst, + WebRtc_Word16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType) +{ + int i=0; + if ((len==((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)|| + (len==2*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)|| + (len==3*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)) { + /* ok, do nothing */ + } else { + return(-1); + } + + while ((i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)<len) { + WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], (WebRtc_UWord16*) &encoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_words], (iLBC_Dec_Inst_t*) iLBCdec_inst, 1); + i++; + } + /* iLBC does not support VAD/CNG yet */ + *speechType=1; + return(i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl); +} + +WebRtc_Word16 WebRtcIlbcfix_DecodePlc(iLBC_decinst_t *iLBCdec_inst, WebRtc_Word16 *decoded, WebRtc_Word16 noOfLostFrames) { + int i; + WebRtc_UWord16 dummy; + + for (i=0;i<noOfLostFrames;i++) { + /* call decoder */ + WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], &dummy, (iLBC_Dec_Inst_t*) iLBCdec_inst, 0); + } + return (noOfLostFrames*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl); +} + +WebRtc_Word16 WebRtcIlbcfix_NetEqPlc(iLBC_decinst_t *iLBCdec_inst, WebRtc_Word16 *decoded, WebRtc_Word16 noOfLostFrames) { + + /* Two input parameters not used, but needed for function pointers in NetEQ */ + decoded = decoded; + noOfLostFrames = noOfLostFrames; + + WebRtcSpl_MemSetW16(((iLBC_Dec_Inst_t*)iLBCdec_inst)->enh_buf, 0, ENH_BUFL); + ((iLBC_Dec_Inst_t*)iLBCdec_inst)->prev_enh_pl = 2; + + return (0); +} + +void WebRtcIlbcfix_version(WebRtc_Word8 *version) +{ + strcpy((char*)version, "1.1.0"); +} diff --git a/src/libs/webrtc/ilbcfix/ilbc.gyp b/src/libs/webrtc/ilbcfix/ilbc.gyp new file mode 100644 index 00000000..bcd5f817 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/ilbc.gyp @@ -0,0 +1,177 @@ +# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +{ + 'includes': [ + '../../../../../../common_settings.gypi', # Common settings + ], + 'targets': [ + { + 'target_name': 'iLBC', + 'type': '<(library)', + 'dependencies': [ + '../../../../../../common_audio/signal_processing_library/main/source/spl.gyp:spl', + ], + 'include_dirs': [ + '../interface', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '../interface', + ], + }, + 'sources': [ + '../interface/ilbc.h', + 'abs_quant.c', + 'abs_quant_loop.c', + 'augmented_cb_corr.c', + 'bw_expand.c', + 'cb_construct.c', + 'cb_mem_energy.c', + 'cb_mem_energy_augmentation.c', + 'cb_mem_energy_calc.c', + 'cb_search.c', + 'cb_search_core.c', + 'cb_update_best_index.c', + 'chebyshev.c', + 'comp_corr.c', + 'constants.c', + 'create_augmented_vec.c', + 'decode.c', + 'decode_residual.c', + 'decoder_interpolate_lsf.c', + 'do_plc.c', + 'encode.c', + 'energy_inverse.c', + 'enh_upsample.c', + 'enhancer.c', + 'enhancer_interface.c', + 'filtered_cb_vecs.c', + 'frame_classify.c', + 'gain_dequant.c', + 'gain_quant.c', + 'get_cd_vec.c', + 'get_lsp_poly.c', + 'get_sync_seq.c', + 'hp_input.c', + 'hp_output.c', + 'ilbc.c', + 'index_conv_dec.c', + 'index_conv_enc.c', + 'init_decode.c', + 'init_encode.c', + 'interpolate.c', + 'interpolate_samples.c', + 'lpc_encode.c', + 'lsf_check.c', + 'lsf_interpolate_to_poly_dec.c', + 'lsf_interpolate_to_poly_enc.c', + 'lsf_to_lsp.c', + 'lsf_to_poly.c', + 'lsp_to_lsf.c', + 'my_corr.c', + 'nearest_neighbor.c', + 'pack_bits.c', + 'poly_to_lsf.c', + 'poly_to_lsp.c', + 'refiner.c', + 'simple_interpolate_lsf.c', + 'simple_lpc_analysis.c', + 'simple_lsf_dequant.c', + 'simple_lsf_quant.c', + 'smooth.c', + 'smooth_out_data.c', + 'sort_sq.c', + 'split_vq.c', + 'state_construct.c', + 'state_search.c', + 'swap_bytes.c', + 'unpack_bits.c', + 'vq3.c', + 'vq4.c', + 'window32_w32.c', + 'xcorr_coef.c', + 'abs_quant.h', + 'abs_quant_loop.h', + 'augmented_cb_corr.h', + 'bw_expand.h', + 'cb_construct.h', + 'cb_mem_energy.h', + 'cb_mem_energy_augmentation.h', + 'cb_mem_energy_calc.h', + 'cb_search.h', + 'cb_search_core.h', + 'cb_update_best_index.h', + 'chebyshev.h', + 'comp_corr.h', + 'constants.h', + 'create_augmented_vec.h', + 'decode.h', + 'decode_residual.h', + 'decoder_interpolate_lsf.h', + 'do_plc.h', + 'encode.h', + 'energy_inverse.h', + 'enh_upsample.h', + 'enhancer.h', + 'enhancer_interface.h', + 'filtered_cb_vecs.h', + 'frame_classify.h', + 'gain_dequant.h', + 'gain_quant.h', + 'get_cd_vec.h', + 'get_lsp_poly.h', + 'get_sync_seq.h', + 'hp_input.h', + 'hp_output.h', + 'defines.h', + 'index_conv_dec.h', + 'index_conv_enc.h', + 'init_decode.h', + 'init_encode.h', + 'interpolate.h', + 'interpolate_samples.h', + 'lpc_encode.h', + 'lsf_check.h', + 'lsf_interpolate_to_poly_dec.h', + 'lsf_interpolate_to_poly_enc.h', + 'lsf_to_lsp.h', + 'lsf_to_poly.h', + 'lsp_to_lsf.h', + 'my_corr.h', + 'nearest_neighbor.h', + 'pack_bits.h', + 'poly_to_lsf.h', + 'poly_to_lsp.h', + 'refiner.h', + 'simple_interpolate_lsf.h', + 'simple_lpc_analysis.h', + 'simple_lsf_dequant.h', + 'simple_lsf_quant.h', + 'smooth.h', + 'smooth_out_data.h', + 'sort_sq.h', + 'split_vq.h', + 'state_construct.h', + 'state_search.h', + 'swap_bytes.h', + 'unpack_bits.h', + 'vq3.h', + 'vq4.h', + 'window32_w32.h', + 'xcorr_coef.h', + ], + }, + ], +} + +# Local Variables: +# tab-width:2 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/src/libs/webrtc/ilbcfix/ilbc.h b/src/libs/webrtc/ilbcfix/ilbc.h new file mode 100644 index 00000000..919f722a --- /dev/null +++ b/src/libs/webrtc/ilbcfix/ilbc.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * ilbc.h + * + * This header file contains all of the API's for iLBC. + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_INTERFACE_ILBC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_INTERFACE_ILBC_H_ + +/* + * Define the fixpoint numeric formats + */ + +#include "typedefs.h" + +/* + * Solution to support multiple instances + * Customer has to cast instance to proper type + */ + +typedef struct iLBC_encinst_t_ iLBC_encinst_t; + +typedef struct iLBC_decinst_t_ iLBC_decinst_t; + +/* + * Comfort noise constants + */ + +#define ILBC_SPEECH 1 +#define ILBC_CNG 2 + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************************** + * WebRtcIlbcfix_XxxAssign(...) + * + * These functions assigns the encoder/decoder instance to the specified + * memory location + * + * Input: + * - XXX_xxxinst : Pointer to created instance that should be + * assigned + * - ILBCXXX_inst_Addr : Pointer to the desired memory space + * - size : The size that this structure occupies (in Word16) + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIlbcfix_EncoderAssign(iLBC_encinst_t **iLBC_encinst, + WebRtc_Word16 *ILBCENC_inst_Addr, + WebRtc_Word16 *size); + WebRtc_Word16 WebRtcIlbcfix_DecoderAssign(iLBC_decinst_t **iLBC_decinst, + WebRtc_Word16 *ILBCDEC_inst_Addr, + WebRtc_Word16 *size); + + + /**************************************************************************** + * WebRtcIlbcfix_XxxAssign(...) + * + * These functions create a instance to the specified structure + * + * Input: + * - XXX_inst : Pointer to created instance that should be created + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIlbcfix_EncoderCreate(iLBC_encinst_t **iLBC_encinst); + WebRtc_Word16 WebRtcIlbcfix_DecoderCreate(iLBC_decinst_t **iLBC_decinst); + + /**************************************************************************** + * WebRtcIlbcfix_XxxFree(...) + * + * These functions frees the dynamic memory of a specified instance + * + * Input: + * - XXX_inst : Pointer to created instance that should be freed + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIlbcfix_EncoderFree(iLBC_encinst_t *iLBC_encinst); + WebRtc_Word16 WebRtcIlbcfix_DecoderFree(iLBC_decinst_t *iLBC_decinst); + + + /**************************************************************************** + * WebRtcIlbcfix_EncoderInit(...) + * + * This function initializes a iLBC instance + * + * Input: + * - iLBCenc_inst : iLBC instance, i.e. the user that should receive + * be initialized + * - frameLen : The frame length of the codec 20/30 (ms) + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIlbcfix_EncoderInit(iLBC_encinst_t *iLBCenc_inst, + WebRtc_Word16 frameLen); + + /**************************************************************************** + * WebRtcIlbcfix_Encode(...) + * + * This function encodes one iLBC frame. Input speech length has be a + * multiple of the frame length. + * + * Input: + * - iLBCenc_inst : iLBC instance, i.e. the user that should encode + * a package + * - speechIn : Input speech vector + * - len : Samples in speechIn (160, 240, 320 or 480) + * + * Output: + * - encoded : The encoded data vector + * + * Return value : >0 - Length (in bytes) of coded data + * -1 - Error + */ + + WebRtc_Word16 WebRtcIlbcfix_Encode(iLBC_encinst_t *iLBCenc_inst, + WebRtc_Word16 *speechIn, + WebRtc_Word16 len, + WebRtc_Word16 *encoded); + + /**************************************************************************** + * WebRtcIlbcfix_DecoderInit(...) + * + * This function initializes a iLBC instance with either 20 or 30 ms frames + * Alternatively the WebRtcIlbcfix_DecoderInit_XXms can be used. Then it's + * not needed to specify the frame length with a variable. + * + * Input: + * - iLBC_decinst_t : iLBC instance, i.e. the user that should receive + * be initialized + * - frameLen : The frame length of the codec 20/30 (ms) + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIlbcfix_DecoderInit(iLBC_decinst_t *iLBCdec_inst, + WebRtc_Word16 frameLen); + WebRtc_Word16 WebRtcIlbcfix_DecoderInit20Ms(iLBC_decinst_t *iLBCdec_inst); + WebRtc_Word16 WebRtcIlbcfix_Decoderinit30Ms(iLBC_decinst_t *iLBCdec_inst); + + /**************************************************************************** + * WebRtcIlbcfix_Decode(...) + * + * This function decodes a packet with iLBC frame(s). Output speech length + * will be a multiple of 160 or 240 samples ((160 or 240)*frames/packet). + * + * Input: + * - iLBCdec_inst : iLBC instance, i.e. the user that should decode + * a packet + * - encoded : Encoded iLBC frame(s) + * - len : Bytes in encoded vector + * + * Output: + * - decoded : The decoded vector + * - speechType : 1 normal, 2 CNG + * + * Return value : >0 - Samples in decoded vector + * -1 - Error + */ + + WebRtc_Word16 WebRtcIlbcfix_Decode(iLBC_decinst_t *iLBCdec_inst, + WebRtc_Word16* encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType); + WebRtc_Word16 WebRtcIlbcfix_Decode20Ms(iLBC_decinst_t *iLBCdec_inst, + WebRtc_Word16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType); + WebRtc_Word16 WebRtcIlbcfix_Decode30Ms(iLBC_decinst_t *iLBCdec_inst, + WebRtc_Word16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType); + + /**************************************************************************** + * WebRtcIlbcfix_DecodePlc(...) + * + * This function conducts PLC for iLBC frame(s). Output speech length + * will be a multiple of 160 or 240 samples. + * + * Input: + * - iLBCdec_inst : iLBC instance, i.e. the user that should perform + * a PLC + * - noOfLostFrames : Number of PLC frames to produce + * + * Output: + * - decoded : The "decoded" vector + * + * Return value : >0 - Samples in decoded PLC vector + * -1 - Error + */ + + WebRtc_Word16 WebRtcIlbcfix_DecodePlc(iLBC_decinst_t *iLBCdec_inst, + WebRtc_Word16 *decoded, + WebRtc_Word16 noOfLostFrames); + + /**************************************************************************** + * WebRtcIlbcfix_NetEqPlc(...) + * + * This function updates the decoder when a packet loss has occured, but it + * does not produce any PLC data. Function can be used if another PLC method + * is used (i.e NetEq). + * + * Input: + * - iLBCdec_inst : iLBC instance that should be updated + * - noOfLostFrames : Number of lost frames + * + * Output: + * - decoded : The "decoded" vector (nothing in this case) + * + * Return value : >0 - Samples in decoded PLC vector + * -1 - Error + */ + + WebRtc_Word16 WebRtcIlbcfix_NetEqPlc(iLBC_decinst_t *iLBCdec_inst, + WebRtc_Word16 *decoded, + WebRtc_Word16 noOfLostFrames); + + /**************************************************************************** + * WebRtcIlbcfix_version(...) + * + * This function returns the version number of iLBC + * + * Output: + * - version : Version number of iLBC (maximum 20 char) + */ + + void WebRtcIlbcfix_version(WebRtc_Word8 *version); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/libs/webrtc/ilbcfix/ilbc_cb_search.c b/src/libs/webrtc/ilbcfix/ilbc_cb_search.c new file mode 100644 index 00000000..c51ccf7c --- /dev/null +++ b/src/libs/webrtc/ilbcfix/ilbc_cb_search.c @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_CbSearch.c + +******************************************************************/ + +#include "defines.h" +#include "gain_quant.h" +#include "filtered_cb_vecs.h" +#include "constants.h" +#include "cb_mem_energy.h" +#include "interpolate_samples.h" +#include "cb_mem_energy_augmentation.h" +#include "cb_search_core.h" +#include "energy_inverse.h" +#include "augmented_cb_corr.h" +#include "cb_update_best_index.h" +#include "create_augmented_vec.h" + +/*----------------------------------------------------------------* + * Search routine for codebook encoding and gain quantization. + *----------------------------------------------------------------*/ + +void WebRtcIlbcfix_CbSearch( + iLBC_Enc_Inst_t *iLBCenc_inst, + /* (i) the encoder state structure */ + WebRtc_Word16 *index, /* (o) Codebook indices */ + WebRtc_Word16 *gain_index, /* (o) Gain quantization indices */ + WebRtc_Word16 *intarget, /* (i) Target vector for encoding */ + WebRtc_Word16 *decResidual,/* (i) Decoded residual for codebook construction */ + WebRtc_Word16 lMem, /* (i) Length of buffer */ + WebRtc_Word16 lTarget, /* (i) Length of vector */ + WebRtc_Word16 *weightDenum,/* (i) weighting filter coefficients in Q12 */ + WebRtc_Word16 block /* (i) the subblock number */ + ) { + WebRtc_Word16 i, j, stage, range; + WebRtc_Word16 *pp, scale, tmp; + WebRtc_Word16 bits, temp1, temp2; + WebRtc_Word16 base_size; + WebRtc_Word32 codedEner, targetEner; + WebRtc_Word16 gains[CB_NSTAGES+1]; + WebRtc_Word16 *cb_vecPtr; + WebRtc_Word16 indexOffset, sInd, eInd; + WebRtc_Word32 CritMax=0; + WebRtc_Word16 shTotMax=WEBRTC_SPL_WORD16_MIN; + WebRtc_Word16 bestIndex=0; + WebRtc_Word16 bestGain=0; + WebRtc_Word16 indexNew, CritNewSh; + WebRtc_Word32 CritNew; + WebRtc_Word32 *cDotPtr; + WebRtc_Word16 noOfZeros; + WebRtc_Word16 *gainPtr; + WebRtc_Word32 t32, tmpW32; + WebRtc_Word16 *WebRtcIlbcfix_kGainSq5_ptr; + /* Stack based */ + WebRtc_Word16 CBbuf[CB_MEML+LPC_FILTERORDER+CB_HALFFILTERLEN]; + WebRtc_Word32 cDot[128]; + WebRtc_Word32 Crit[128]; + WebRtc_Word16 targetVec[SUBL+LPC_FILTERORDER]; + WebRtc_Word16 cbvectors[CB_MEML]; + WebRtc_Word16 codedVec[SUBL]; + WebRtc_Word16 interpSamples[20*4]; + WebRtc_Word16 interpSamplesFilt[20*4]; + WebRtc_Word16 energyW16[CB_EXPAND*128]; + WebRtc_Word16 energyShifts[CB_EXPAND*128]; + WebRtc_Word16 *inverseEnergy=energyW16; /* Reuse memory */ + WebRtc_Word16 *inverseEnergyShifts=energyShifts; /* Reuse memory */ + WebRtc_Word16 *buf = &CBbuf[LPC_FILTERORDER]; + WebRtc_Word16 *target = &targetVec[LPC_FILTERORDER]; + WebRtc_Word16 *aug_vec = (WebRtc_Word16*)cDot; /* length [SUBL], reuse memory */ + + /* Determine size of codebook sections */ + + base_size=lMem-lTarget+1; + if (lTarget==SUBL) { + base_size=lMem-19; + } + + /* weighting of the CB memory */ + noOfZeros=lMem-WebRtcIlbcfix_kFilterRange[block]; + WebRtcSpl_MemSetW16(&buf[-LPC_FILTERORDER], 0, noOfZeros+LPC_FILTERORDER); + WebRtcSpl_FilterARFastQ12( + decResidual+noOfZeros, buf+noOfZeros, + weightDenum, LPC_FILTERORDER+1, WebRtcIlbcfix_kFilterRange[block]); + + /* weighting of the target vector */ + WEBRTC_SPL_MEMCPY_W16(&target[-LPC_FILTERORDER], buf+noOfZeros+WebRtcIlbcfix_kFilterRange[block]-LPC_FILTERORDER, LPC_FILTERORDER); + WebRtcSpl_FilterARFastQ12( + intarget, target, + weightDenum, LPC_FILTERORDER+1, lTarget); + + /* Store target, towards the end codedVec is calculated as + the initial target minus the remaining target */ + WEBRTC_SPL_MEMCPY_W16(codedVec, target, lTarget); + + /* Find the highest absolute value to calculate proper + vector scale factor (so that it uses 12 bits) */ + temp1 = WebRtcSpl_MaxAbsValueW16(buf, (WebRtc_Word16)lMem); + temp2 = WebRtcSpl_MaxAbsValueW16(target, (WebRtc_Word16)lTarget); + + if ((temp1>0)&&(temp2>0)) { + temp1 = WEBRTC_SPL_MAX(temp1, temp2); + scale = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_MUL_16_16(temp1, temp1)); + } else { + /* temp1 or temp2 is negative (maximum was -32768) */ + scale = 30; + } + + /* Scale to so that a mul-add 40 times does not overflow */ + scale = scale - 25; + scale = WEBRTC_SPL_MAX(0, scale); + + /* Compute energy of the original target */ + targetEner = WebRtcSpl_DotProductWithScale(target, target, lTarget, scale); + + /* Prepare search over one more codebook section. This section + is created by filtering the original buffer with a filter. */ + WebRtcIlbcfix_FilteredCbVecs(cbvectors, buf, lMem, WebRtcIlbcfix_kFilterRange[block]); + + range = WebRtcIlbcfix_kSearchRange[block][0]; + + if(lTarget == SUBL) { + /* Create the interpolated samples and store them for use in all stages */ + + /* First section, non-filtered half of the cb */ + WebRtcIlbcfix_InterpolateSamples(interpSamples, buf, lMem); + + /* Second section, filtered half of the cb */ + WebRtcIlbcfix_InterpolateSamples(interpSamplesFilt, cbvectors, lMem); + + /* Compute the CB vectors' energies for the first cb section (non-filtered) */ + WebRtcIlbcfix_CbMemEnergyAugmentation(interpSamples, buf, + scale, 20, energyW16, energyShifts); + + /* Compute the CB vectors' energies for the second cb section (filtered cb) */ + WebRtcIlbcfix_CbMemEnergyAugmentation(interpSamplesFilt, cbvectors, + scale, (WebRtc_Word16)(base_size+20), energyW16, energyShifts); + + /* Compute the CB vectors' energies and store them in the vector + * energyW16. Also the corresponding shift values are stored. The + * energy values are used in all three stages. */ + WebRtcIlbcfix_CbMemEnergy(range, buf, cbvectors, lMem, + lTarget, energyW16+20, energyShifts+20, scale, base_size); + + } else { + /* Compute the CB vectors' energies and store them in the vector + * energyW16. Also the corresponding shift values are stored. The + * energy values are used in all three stages. */ + WebRtcIlbcfix_CbMemEnergy(range, buf, cbvectors, lMem, + lTarget, energyW16, energyShifts, scale, base_size); + + /* Set the energy positions 58-63 and 122-127 to zero + (otherwise they are uninitialized) */ + WebRtcSpl_MemSetW16(energyW16+range, 0, (base_size-range)); + WebRtcSpl_MemSetW16(energyW16+range+base_size, 0, (base_size-range)); + } + + /* Calculate Inverse Energy (energyW16 is already normalized + and will contain the inverse energy in Q29 after this call */ + WebRtcIlbcfix_EnergyInverse(energyW16, base_size*CB_EXPAND); + + /* The gain value computed in the previous stage is used + * as an upper limit to what the next stage gain value + * is allowed to be. In stage 0, 16384 (1.0 in Q14) is used as + * the upper limit. */ + gains[0] = 16384; + + for (stage=0; stage<CB_NSTAGES; stage++) { + + /* Set up memories */ + range = WebRtcIlbcfix_kSearchRange[block][stage]; + + /* initialize search measures */ + CritMax=0; + shTotMax=-100; + bestIndex=0; + bestGain=0; + + /* loop over lags 40+ in the first codebook section, full search */ + cb_vecPtr = buf+lMem-lTarget; + + /* Calculate all the cross correlations (augmented part of CB) */ + if (lTarget==SUBL) { + WebRtcIlbcfix_AugmentedCbCorr(target, buf+lMem, + interpSamples, cDot, + 20, 39, scale); + cDotPtr=&cDot[20]; + } else { + cDotPtr=cDot; + } + /* Calculate all the cross correlations (main part of CB) */ + WebRtcSpl_CrossCorrelation(cDotPtr, target, cb_vecPtr, lTarget, range, scale, -1); + + /* Adjust the search range for the augmented vectors */ + if (lTarget==SUBL) { + range=WebRtcIlbcfix_kSearchRange[block][stage]+20; + } else { + range=WebRtcIlbcfix_kSearchRange[block][stage]; + } + + indexOffset=0; + + /* Search for best index in this part of the vector */ + WebRtcIlbcfix_CbSearchCore( + cDot, range, stage, inverseEnergy, + inverseEnergyShifts, Crit, + &indexNew, &CritNew, &CritNewSh); + + /* Update the global best index and the corresponding gain */ + WebRtcIlbcfix_CbUpdateBestIndex( + CritNew, CritNewSh, (WebRtc_Word16)(indexNew+indexOffset), cDot[indexNew+indexOffset], + inverseEnergy[indexNew+indexOffset], inverseEnergyShifts[indexNew+indexOffset], + &CritMax, &shTotMax, &bestIndex, &bestGain); + + sInd=bestIndex-(WebRtc_Word16)(CB_RESRANGE>>1); + eInd=sInd+CB_RESRANGE; + if (sInd<0) { + eInd-=sInd; + sInd=0; + } + if (eInd>=range) { + eInd=range-1; + sInd=eInd-CB_RESRANGE; + } + + range = WebRtcIlbcfix_kSearchRange[block][stage]; + + if (lTarget==SUBL) { + i=sInd; + if (sInd<20) { + WebRtcIlbcfix_AugmentedCbCorr(target, cbvectors+lMem, + interpSamplesFilt, cDot, + (WebRtc_Word16)(sInd+20), (WebRtc_Word16)(WEBRTC_SPL_MIN(39, (eInd+20))), scale); + i=20; + } + + cDotPtr=&cDot[WEBRTC_SPL_MAX(0,(20-sInd))]; + cb_vecPtr = cbvectors+lMem-20-i; + + /* Calculate the cross correlations (main part of the filtered CB) */ + WebRtcSpl_CrossCorrelation(cDotPtr, target, cb_vecPtr, lTarget, (WebRtc_Word16)(eInd-i+1), scale, -1); + + } else { + cDotPtr = cDot; + cb_vecPtr = cbvectors+lMem-lTarget-sInd; + + /* Calculate the cross correlations (main part of the filtered CB) */ + WebRtcSpl_CrossCorrelation(cDotPtr, target, cb_vecPtr, lTarget, (WebRtc_Word16)(eInd-sInd+1), scale, -1); + + } + + /* Adjust the search range for the augmented vectors */ + indexOffset=base_size+sInd; + + /* Search for best index in this part of the vector */ + WebRtcIlbcfix_CbSearchCore( + cDot, (WebRtc_Word16)(eInd-sInd+1), stage, inverseEnergy+indexOffset, + inverseEnergyShifts+indexOffset, Crit, + &indexNew, &CritNew, &CritNewSh); + + /* Update the global best index and the corresponding gain */ + WebRtcIlbcfix_CbUpdateBestIndex( + CritNew, CritNewSh, (WebRtc_Word16)(indexNew+indexOffset), cDot[indexNew], + inverseEnergy[indexNew+indexOffset], inverseEnergyShifts[indexNew+indexOffset], + &CritMax, &shTotMax, &bestIndex, &bestGain); + + index[stage] = bestIndex; + + + bestGain = WebRtcIlbcfix_GainQuant(bestGain, + (WebRtc_Word16)WEBRTC_SPL_ABS_W16(gains[stage]), stage, &gain_index[stage]); + + /* Extract the best (according to measure) codebook vector + Also adjust the index, so that the augmented vectors are last. + Above these vectors were first... + */ + + if(lTarget==(STATE_LEN-iLBCenc_inst->state_short_len)) { + + if(index[stage]<base_size) { + pp=buf+lMem-lTarget-index[stage]; + } else { + pp=cbvectors+lMem-lTarget- + index[stage]+base_size; + } + + } else { + + if (index[stage]<base_size) { + if (index[stage]>=20) { + /* Adjust index and extract vector */ + index[stage]-=20; + pp=buf+lMem-lTarget-index[stage]; + } else { + /* Adjust index and extract vector */ + index[stage]+=(base_size-20); + + WebRtcIlbcfix_CreateAugmentedVec((WebRtc_Word16)(index[stage]-base_size+40), + buf+lMem, aug_vec); + pp = aug_vec; + + } + } else { + + if ((index[stage] - base_size) >= 20) { + /* Adjust index and extract vector */ + index[stage]-=20; + pp=cbvectors+lMem-lTarget- + index[stage]+base_size; + } else { + /* Adjust index and extract vector */ + index[stage]+=(base_size-20); + WebRtcIlbcfix_CreateAugmentedVec((WebRtc_Word16)(index[stage]-2*base_size+40), + cbvectors+lMem, aug_vec); + pp = aug_vec; + } + } + } + + /* Subtract the best codebook vector, according + to measure, from the target vector */ + + WebRtcSpl_AddAffineVectorToVector(target, pp, (WebRtc_Word16)(-bestGain), (WebRtc_Word32)8192, (WebRtc_Word16)14, (int)lTarget); + + /* record quantized gain */ + gains[stage+1] = bestGain; + + } /* end of Main Loop. for (stage=0;... */ + + /* Calculte the coded vector (original target - what's left) */ + for (i=0;i<lTarget;i++) { + codedVec[i]-=target[i]; + } + + /* Gain adjustment for energy matching */ + codedEner = WebRtcSpl_DotProductWithScale(codedVec, codedVec, lTarget, scale); + + j=gain_index[0]; + + temp1 = (WebRtc_Word16)WebRtcSpl_NormW32(codedEner); + temp2 = (WebRtc_Word16)WebRtcSpl_NormW32(targetEner); + + if(temp1 < temp2) { + bits = 16 - temp1; + } else { + bits = 16 - temp2; + } + + tmp = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(gains[1],gains[1], 14); + + targetEner = WEBRTC_SPL_MUL_16_16( + WEBRTC_SPL_SHIFT_W32(targetEner, -bits), tmp); + + tmpW32 = ((WebRtc_Word32)(gains[1]-1))<<1; + + /* Pointer to the table that contains + gain_sq5TblFIX * gain_sq5TblFIX in Q14 */ + gainPtr=(WebRtc_Word16*)WebRtcIlbcfix_kGainSq5Sq+gain_index[0]; + temp1 = (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(codedEner, -bits); + + WebRtcIlbcfix_kGainSq5_ptr = (WebRtc_Word16*)&WebRtcIlbcfix_kGainSq5[j]; + + /* targetEner and codedEner are in Q(-2*scale) */ + for (i=gain_index[0];i<32;i++) { + + /* Change the index if + (codedEnergy*gainTbl[i]*gainTbl[i])<(targetEn*gain[0]*gain[0]) AND + gainTbl[i] < 2*gain[0] + */ + + t32 = WEBRTC_SPL_MUL_16_16(temp1, (*gainPtr)); + t32 = t32 - targetEner; + if (t32 < 0) { + if ((*WebRtcIlbcfix_kGainSq5_ptr) < tmpW32) { + j=i; + WebRtcIlbcfix_kGainSq5_ptr = (WebRtc_Word16*)&WebRtcIlbcfix_kGainSq5[i]; + } + } + gainPtr++; + } + gain_index[0]=j; + + return; +} diff --git a/src/libs/webrtc/ilbcfix/ilbc_constants.c b/src/libs/webrtc/ilbcfix/ilbc_constants.c new file mode 100644 index 00000000..5ebe9be5 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/ilbc_constants.c @@ -0,0 +1,666 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + constants.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/* HP Filters {b[0] b[1] b[2] -a[1] -a[2]} */ + +const WebRtc_Word16 WebRtcIlbcfix_kHpInCoefs[5] = {3798, -7596, 3798, 7807, -3733}; +const WebRtc_Word16 WebRtcIlbcfix_kHpOutCoefs[5] = {3849, -7699, 3849, 7918, -3833}; + +/* Window in Q11 to window the energies of the 5 choises (3 for 20ms) in the choise for + the 80 sample start state +*/ +const WebRtc_Word16 WebRtcIlbcfix_kStartSequenceEnrgWin[NSUB_MAX-1]= { + 1638, 1843, 2048, 1843, 1638 +}; + +/* LP Filter coeffs used for downsampling */ +const WebRtc_Word16 WebRtcIlbcfix_kLpFiltCoefs[FILTERORDER_DS_PLUS1]= { + -273, 512, 1297, 1696, 1297, 512, -273 +}; + +/* Constants used in the LPC calculations */ + +/* Hanning LPC window (in Q15) */ +const WebRtc_Word16 WebRtcIlbcfix_kLpcWin[BLOCKL_MAX] = { + 6, 22, 50, 89, 139, 200, 272, 355, 449, 554, 669, 795, + 932, 1079, 1237, 1405, 1583, 1771, 1969, 2177, 2395, 2622, 2858, 3104, + 3359, 3622, 3894, 4175, 4464, 4761, 5066, 5379, 5699, 6026, 6361, 6702, + 7050, 7404, 7764, 8130, 8502, 8879, 9262, 9649, 10040, 10436, 10836, 11240, + 11647, 12058, 12471, 12887, 13306, 13726, 14148, 14572, 14997, 15423, 15850, 16277, + 16704, 17131, 17558, 17983, 18408, 18831, 19252, 19672, 20089, 20504, 20916, 21325, + 21730, 22132, 22530, 22924, 23314, 23698, 24078, 24452, 24821, 25185, 25542, 25893, + 26238, 26575, 26906, 27230, 27547, 27855, 28156, 28450, 28734, 29011, 29279, 29538, + 29788, 30029, 30261, 30483, 30696, 30899, 31092, 31275, 31448, 31611, 31764, 31906, + 32037, 32158, 32268, 32367, 32456, 32533, 32600, 32655, 32700, 32733, 32755, 32767, + 32767, 32755, 32733, 32700, 32655, 32600, 32533, 32456, 32367, 32268, 32158, 32037, + 31906, 31764, 31611, 31448, 31275, 31092, 30899, 30696, 30483, 30261, 30029, 29788, + 29538, 29279, 29011, 28734, 28450, 28156, 27855, 27547, 27230, 26906, 26575, 26238, + 25893, 25542, 25185, 24821, 24452, 24078, 23698, 23314, 22924, 22530, 22132, 21730, + 21325, 20916, 20504, 20089, 19672, 19252, 18831, 18408, 17983, 17558, 17131, 16704, + 16277, 15850, 15423, 14997, 14572, 14148, 13726, 13306, 12887, 12471, 12058, 11647, + 11240, 10836, 10436, 10040, 9649, 9262, 8879, 8502, 8130, 7764, 7404, 7050, + 6702, 6361, 6026, 5699, 5379, 5066, 4761, 4464, 4175, 3894, 3622, 3359, + 3104, 2858, 2622, 2395, 2177, 1969, 1771, 1583, 1405, 1237, 1079, 932, + 795, 669, 554, 449, 355, 272, 200, 139, 89, 50, 22, 6 +}; + +/* Asymmetric LPC window (in Q15)*/ +const WebRtc_Word16 WebRtcIlbcfix_kLpcAsymWin[BLOCKL_MAX] = { + 2, 7, 15, 27, 42, 60, 81, 106, 135, 166, 201, 239, + 280, 325, 373, 424, 478, 536, 597, 661, 728, 798, 872, 949, + 1028, 1111, 1197, 1287, 1379, 1474, 1572, 1674, 1778, 1885, 1995, 2108, + 2224, 2343, 2465, 2589, 2717, 2847, 2980, 3115, 3254, 3395, 3538, 3684, + 3833, 3984, 4138, 4295, 4453, 4615, 4778, 4944, 5112, 5283, 5456, 5631, + 5808, 5987, 6169, 6352, 6538, 6725, 6915, 7106, 7300, 7495, 7692, 7891, + 8091, 8293, 8497, 8702, 8909, 9118, 9328, 9539, 9752, 9966, 10182, 10398, + 10616, 10835, 11055, 11277, 11499, 11722, 11947, 12172, 12398, 12625, 12852, 13080, + 13309, 13539, 13769, 14000, 14231, 14463, 14695, 14927, 15160, 15393, 15626, 15859, + 16092, 16326, 16559, 16792, 17026, 17259, 17492, 17725, 17957, 18189, 18421, 18653, + 18884, 19114, 19344, 19573, 19802, 20030, 20257, 20483, 20709, 20934, 21157, 21380, + 21602, 21823, 22042, 22261, 22478, 22694, 22909, 23123, 23335, 23545, 23755, 23962, + 24168, 24373, 24576, 24777, 24977, 25175, 25371, 25565, 25758, 25948, 26137, 26323, + 26508, 26690, 26871, 27049, 27225, 27399, 27571, 27740, 27907, 28072, 28234, 28394, + 28552, 28707, 28860, 29010, 29157, 29302, 29444, 29584, 29721, 29855, 29987, 30115, + 30241, 30364, 30485, 30602, 30717, 30828, 30937, 31043, 31145, 31245, 31342, 31436, + 31526, 31614, 31699, 31780, 31858, 31933, 32005, 32074, 32140, 32202, 32261, 32317, + 32370, 32420, 32466, 32509, 32549, 32585, 32618, 32648, 32675, 32698, 32718, 32734, + 32748, 32758, 32764, 32767, 32767, 32667, 32365, 31863, 31164, 30274, 29197, 27939, + 26510, 24917, 23170, 21281, 19261, 17121, 14876, 12540, 10126, 7650, 5126, 2571 +}; + +/* Lag window for LPC (Q31) */ +const WebRtc_Word32 WebRtcIlbcfix_kLpcLagWin[LPC_FILTERORDER + 1]={ + 2147483647, 2144885453, 2137754373, 2125918626, 2109459810, + 2088483140, 2063130336, 2033564590, 1999977009, 1962580174, + 1921610283}; + +/* WebRtcIlbcfix_kLpcChirpSyntDenum vector in Q15 corresponding + * floating point vector {1 0.9025 0.9025^2 0.9025^3 ...} + */ +const WebRtc_Word16 WebRtcIlbcfix_kLpcChirpSyntDenum[LPC_FILTERORDER + 1] = { + 32767, 29573, 26690, 24087, + 21739, 19619, 17707, 15980, + 14422, 13016, 11747}; + +/* WebRtcIlbcfix_kLpcChirpWeightDenum in Q15 corresponding to + * floating point vector {1 0.4222 0.4222^2... } + */ +const WebRtc_Word16 WebRtcIlbcfix_kLpcChirpWeightDenum[LPC_FILTERORDER + 1] = { + 32767, 13835, 5841, 2466, 1041, 440, + 186, 78, 33, 14, 6}; + +/* LSF quantization Q13 domain */ +const WebRtc_Word16 WebRtcIlbcfix_kLsfCb[64 * 3 + 128 * 3 + 128 * 4] = { + 1273, 2238, 3696, + 3199, 5309, 8209, + 3606, 5671, 7829, + 2815, 5262, 8778, + 2608, 4027, 5493, + 1582, 3076, 5945, + 2983, 4181, 5396, + 2437, 4322, 6902, + 1861, 2998, 4613, + 2007, 3250, 5214, + 1388, 2459, 4262, + 2563, 3805, 5269, + 2036, 3522, 5129, + 1935, 4025, 6694, + 2744, 5121, 7338, + 2810, 4248, 5723, + 3054, 5405, 7745, + 1449, 2593, 4763, + 3411, 5128, 6596, + 2484, 4659, 7496, + 1668, 2879, 4818, + 1812, 3072, 5036, + 1638, 2649, 3900, + 2464, 3550, 4644, + 1853, 2900, 4158, + 2458, 4163, 5830, + 2556, 4036, 6254, + 2703, 4432, 6519, + 3062, 4953, 7609, + 1725, 3703, 6187, + 2221, 3877, 5427, + 2339, 3579, 5197, + 2021, 4633, 7037, + 2216, 3328, 4535, + 2961, 4739, 6667, + 2807, 3955, 5099, + 2788, 4501, 6088, + 1642, 2755, 4431, + 3341, 5282, 7333, + 2414, 3726, 5727, + 1582, 2822, 5269, + 2259, 3447, 4905, + 3117, 4986, 7054, + 1825, 3491, 5542, + 3338, 5736, 8627, + 1789, 3090, 5488, + 2566, 3720, 4923, + 2846, 4682, 7161, + 1950, 3321, 5976, + 1834, 3383, 6734, + 3238, 4769, 6094, + 2031, 3978, 5903, + 1877, 4068, 7436, + 2131, 4644, 8296, + 2764, 5010, 8013, + 2194, 3667, 6302, + 2053, 3127, 4342, + 3523, 6595, 10010, + 3134, 4457, 5748, + 3142, 5819, 9414, + 2223, 4334, 6353, + 2022, 3224, 4822, + 2186, 3458, 5544, + 2552, 4757, 6870, + 10905, 12917, 14578, + 9503, 11485, 14485, + 9518, 12494, 14052, + 6222, 7487, 9174, + 7759, 9186, 10506, + 8315, 12755, 14786, + 9609, 11486, 13866, + 8909, 12077, 13643, + 7369, 9054, 11520, + 9408, 12163, 14715, + 6436, 9911, 12843, + 7109, 9556, 11884, + 7557, 10075, 11640, + 6482, 9202, 11547, + 6463, 7914, 10980, + 8611, 10427, 12752, + 7101, 9676, 12606, + 7428, 11252, 13172, + 10197, 12955, 15842, + 7487, 10955, 12613, + 5575, 7858, 13621, + 7268, 11719, 14752, + 7476, 11744, 13795, + 7049, 8686, 11922, + 8234, 11314, 13983, + 6560, 11173, 14984, + 6405, 9211, 12337, + 8222, 12054, 13801, + 8039, 10728, 13255, + 10066, 12733, 14389, + 6016, 7338, 10040, + 6896, 8648, 10234, + 7538, 9170, 12175, + 7327, 12608, 14983, + 10516, 12643, 15223, + 5538, 7644, 12213, + 6728, 12221, 14253, + 7563, 9377, 12948, + 8661, 11023, 13401, + 7280, 8806, 11085, + 7723, 9793, 12333, + 12225, 14648, 16709, + 8768, 13389, 15245, + 10267, 12197, 13812, + 5301, 7078, 11484, + 7100, 10280, 11906, + 8716, 12555, 14183, + 9567, 12464, 15434, + 7832, 12305, 14300, + 7608, 10556, 12121, + 8913, 11311, 12868, + 7414, 9722, 11239, + 8666, 11641, 13250, + 9079, 10752, 12300, + 8024, 11608, 13306, + 10453, 13607, 16449, + 8135, 9573, 10909, + 6375, 7741, 10125, + 10025, 12217, 14874, + 6985, 11063, 14109, + 9296, 13051, 14642, + 8613, 10975, 12542, + 6583, 10414, 13534, + 6191, 9368, 13430, + 5742, 6859, 9260, + 7723, 9813, 13679, + 8137, 11291, 12833, + 6562, 8973, 10641, + 6062, 8462, 11335, + 6928, 8784, 12647, + 7501, 8784, 10031, + 8372, 10045, 12135, + 8191, 9864, 12746, + 5917, 7487, 10979, + 5516, 6848, 10318, + 6819, 9899, 11421, + 7882, 12912, 15670, + 9558, 11230, 12753, + 7752, 9327, 11472, + 8479, 9980, 11358, + 11418, 14072, 16386, + 7968, 10330, 14423, + 8423, 10555, 12162, + 6337, 10306, 14391, + 8850, 10879, 14276, + 6750, 11885, 15710, + 7037, 8328, 9764, + 6914, 9266, 13476, + 9746, 13949, 15519, + 11032, 14444, 16925, + 8032, 10271, 11810, + 10962, 13451, 15833, + 10021, 11667, 13324, + 6273, 8226, 12936, + 8543, 10397, 13496, + 7936, 10302, 12745, + 6769, 8138, 10446, + 6081, 7786, 11719, + 8637, 11795, 14975, + 8790, 10336, 11812, + 7040, 8490, 10771, + 7338, 10381, 13153, + 6598, 7888, 9358, + 6518, 8237, 12030, + 9055, 10763, 12983, + 6490, 10009, 12007, + 9589, 12023, 13632, + 6867, 9447, 10995, + 7930, 9816, 11397, + 10241, 13300, 14939, + 5830, 8670, 12387, + 9870, 11915, 14247, + 9318, 11647, 13272, + 6721, 10836, 12929, + 6543, 8233, 9944, + 8034, 10854, 12394, + 9112, 11787, 14218, + 9302, 11114, 13400, + 9022, 11366, 13816, + 6962, 10461, 12480, + 11288, 13333, 15222, + 7249, 8974, 10547, + 10566, 12336, 14390, + 6697, 11339, 13521, + 11851, 13944, 15826, + 6847, 8381, 11349, + 7509, 9331, 10939, + 8029, 9618, 11909, + 13973, 17644, 19647, 22474, + 14722, 16522, 20035, 22134, + 16305, 18179, 21106, 23048, + 15150, 17948, 21394, 23225, + 13582, 15191, 17687, 22333, + 11778, 15546, 18458, 21753, + 16619, 18410, 20827, 23559, + 14229, 15746, 17907, 22474, + 12465, 15327, 20700, 22831, + 15085, 16799, 20182, 23410, + 13026, 16935, 19890, 22892, + 14310, 16854, 19007, 22944, + 14210, 15897, 18891, 23154, + 14633, 18059, 20132, 22899, + 15246, 17781, 19780, 22640, + 16396, 18904, 20912, 23035, + 14618, 17401, 19510, 21672, + 15473, 17497, 19813, 23439, + 18851, 20736, 22323, 23864, + 15055, 16804, 18530, 20916, + 16490, 18196, 19990, 21939, + 11711, 15223, 21154, 23312, + 13294, 15546, 19393, 21472, + 12956, 16060, 20610, 22417, + 11628, 15843, 19617, 22501, + 14106, 16872, 19839, 22689, + 15655, 18192, 20161, 22452, + 12953, 15244, 20619, 23549, + 15322, 17193, 19926, 21762, + 16873, 18676, 20444, 22359, + 14874, 17871, 20083, 21959, + 11534, 14486, 19194, 21857, + 17766, 19617, 21338, 23178, + 13404, 15284, 19080, 23136, + 15392, 17527, 19470, 21953, + 14462, 16153, 17985, 21192, + 17734, 19750, 21903, 23783, + 16973, 19096, 21675, 23815, + 16597, 18936, 21257, 23461, + 15966, 17865, 20602, 22920, + 15416, 17456, 20301, 22972, + 18335, 20093, 21732, 23497, + 15548, 17217, 20679, 23594, + 15208, 16995, 20816, 22870, + 13890, 18015, 20531, 22468, + 13211, 15377, 19951, 22388, + 12852, 14635, 17978, 22680, + 16002, 17732, 20373, 23544, + 11373, 14134, 19534, 22707, + 17329, 19151, 21241, 23462, + 15612, 17296, 19362, 22850, + 15422, 19104, 21285, 23164, + 13792, 17111, 19349, 21370, + 15352, 17876, 20776, 22667, + 15253, 16961, 18921, 22123, + 14108, 17264, 20294, 23246, + 15785, 17897, 20010, 21822, + 17399, 19147, 20915, 22753, + 13010, 15659, 18127, 20840, + 16826, 19422, 22218, 24084, + 18108, 20641, 22695, 24237, + 18018, 20273, 22268, 23920, + 16057, 17821, 21365, 23665, + 16005, 17901, 19892, 23016, + 13232, 16683, 21107, 23221, + 13280, 16615, 19915, 21829, + 14950, 18575, 20599, 22511, + 16337, 18261, 20277, 23216, + 14306, 16477, 21203, 23158, + 12803, 17498, 20248, 22014, + 14327, 17068, 20160, 22006, + 14402, 17461, 21599, 23688, + 16968, 18834, 20896, 23055, + 15070, 17157, 20451, 22315, + 15419, 17107, 21601, 23946, + 16039, 17639, 19533, 21424, + 16326, 19261, 21745, 23673, + 16489, 18534, 21658, 23782, + 16594, 18471, 20549, 22807, + 18973, 21212, 22890, 24278, + 14264, 18674, 21123, 23071, + 15117, 16841, 19239, 23118, + 13762, 15782, 20478, 23230, + 14111, 15949, 20058, 22354, + 14990, 16738, 21139, 23492, + 13735, 16971, 19026, 22158, + 14676, 17314, 20232, 22807, + 16196, 18146, 20459, 22339, + 14747, 17258, 19315, 22437, + 14973, 17778, 20692, 23367, + 15715, 17472, 20385, 22349, + 15702, 18228, 20829, 23410, + 14428, 16188, 20541, 23630, + 16824, 19394, 21365, 23246, + 13069, 16392, 18900, 21121, + 12047, 16640, 19463, 21689, + 14757, 17433, 19659, 23125, + 15185, 16930, 19900, 22540, + 16026, 17725, 19618, 22399, + 16086, 18643, 21179, 23472, + 15462, 17248, 19102, 21196, + 17368, 20016, 22396, 24096, + 12340, 14475, 19665, 23362, + 13636, 16229, 19462, 22728, + 14096, 16211, 19591, 21635, + 12152, 14867, 19943, 22301, + 14492, 17503, 21002, 22728, + 14834, 16788, 19447, 21411, + 14650, 16433, 19326, 22308, + 14624, 16328, 19659, 23204, + 13888, 16572, 20665, 22488, + 12977, 16102, 18841, 22246, + 15523, 18431, 21757, 23738, + 14095, 16349, 18837, 20947, + 13266, 17809, 21088, 22839, + 15427, 18190, 20270, 23143, + 11859, 16753, 20935, 22486, + 12310, 17667, 21736, 23319, + 14021, 15926, 18702, 22002, + 12286, 15299, 19178, 21126, + 15703, 17491, 21039, 23151, + 12272, 14018, 18213, 22570, + 14817, 16364, 18485, 22598, + 17109, 19683, 21851, 23677, + 12657, 14903, 19039, 22061, + 14713, 16487, 20527, 22814, + 14635, 16726, 18763, 21715, + 15878, 18550, 20718, 22906 +}; + +const WebRtc_Word16 WebRtcIlbcfix_kLsfDimCb[LSF_NSPLIT] = {3, 3, 4}; +const WebRtc_Word16 WebRtcIlbcfix_kLsfSizeCb[LSF_NSPLIT] = {64,128,128}; + +const WebRtc_Word16 WebRtcIlbcfix_kLsfMean[LPC_FILTERORDER] = { + 2308, 3652, 5434, 7885, + 10255, 12559, 15160, 17513, + 20328, 22752}; + +const WebRtc_Word16 WebRtcIlbcfix_kLspMean[LPC_FILTERORDER] = { + 31476, 29565, 25819, 18725, 10276, + 1236, -9049, -17600, -25884, -30618 +}; + +/* Q14 */ +const WebRtc_Word16 WebRtcIlbcfix_kLsfWeight20ms[4] = {12288, 8192, 4096, 0}; +const WebRtc_Word16 WebRtcIlbcfix_kLsfWeight30ms[6] = {8192, 16384, 10923, 5461, 0, 0}; + +/* + cos(x) in Q15 + WebRtcIlbcfix_kCos[i] = cos(pi*i/64.0) + used in WebRtcIlbcfix_Lsp2Lsf() +*/ + +const WebRtc_Word16 WebRtcIlbcfix_kCos[64] = { + 32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853, + 30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279, + 23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010, + 12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608, + 0, -1608, -3212, -4808, -6393, -7962, -9512, -11039, + -12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006, + -23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622, + -30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729 +}; + +/* + Derivative in Q19, used to interpolate between the + WebRtcIlbcfix_kCos[] values to get a more exact y = cos(x) +*/ +const WebRtc_Word16 WebRtcIlbcfix_kCosDerivative[64] = { + -632, -1893, -3150, -4399, -5638, -6863, -8072, -9261, + -10428, -11570, -12684, -13767, -14817, -15832, -16808, -17744, + -18637, -19486, -20287, -21039, -21741, -22390, -22986, -23526, + -24009, -24435, -24801, -25108, -25354, -25540, -25664, -25726, + -25726, -25664, -25540, -25354, -25108, -24801, -24435, -24009, + -23526, -22986, -22390, -21741, -21039, -20287, -19486, -18637, + -17744, -16808, -15832, -14817, -13767, -12684, -11570, -10428, + -9261, -8072, -6863, -5638, -4399, -3150, -1893, -632}; + +/* + Table in Q15, used for a2lsf conversion + WebRtcIlbcfix_kCosGrid[i] = cos((2*pi*i)/(float)(2*COS_GRID_POINTS)); +*/ + +const WebRtc_Word16 WebRtcIlbcfix_kCosGrid[COS_GRID_POINTS + 1] = { + 32760, 32723, 32588, 32364, 32051, 31651, 31164, 30591, + 29935, 29196, 28377, 27481, 26509, 25465, 24351, 23170, + 21926, 20621, 19260, 17846, 16384, 14876, 13327, 11743, + 10125, 8480, 6812, 5126, 3425, 1714, 0, -1714, -3425, + -5126, -6812, -8480, -10125, -11743, -13327, -14876, + -16384, -17846, -19260, -20621, -21926, -23170, -24351, + -25465, -26509, -27481, -28377, -29196, -29935, -30591, + -31164, -31651, -32051, -32364, -32588, -32723, -32760 +}; + +/* + Derivative of y = acos(x) in Q12 + used in WebRtcIlbcfix_Lsp2Lsf() +*/ + +const WebRtc_Word16 WebRtcIlbcfix_kAcosDerivative[64] = { + -26887, -8812, -5323, -3813, -2979, -2444, -2081, -1811, + -1608, -1450, -1322, -1219, -1132, -1059, -998, -946, + -901, -861, -827, -797, -772, -750, -730, -713, + -699, -687, -677, -668, -662, -657, -654, -652, + -652, -654, -657, -662, -668, -677, -687, -699, + -713, -730, -750, -772, -797, -827, -861, -901, + -946, -998, -1059, -1132, -1219, -1322, -1450, -1608, + -1811, -2081, -2444, -2979, -3813, -5323, -8812, -26887 +}; + + +/* Tables for quantization of start state */ + +/* State quantization tables */ +const WebRtc_Word16 WebRtcIlbcfix_kStateSq3[8] = { /* Values in Q13 */ + -30473, -17838, -9257, -2537, + 3639, 10893, 19958, 32636 +}; + +/* This table defines the limits for the selection of the freqg + less or equal than value 0 => index = 0 + less or equal than value k => index = k +*/ +const WebRtc_Word32 WebRtcIlbcfix_kChooseFrgQuant[64] = { + 118, 163, 222, 305, 425, 604, + 851, 1174, 1617, 2222, 3080, 4191, + 5525, 7215, 9193, 11540, 14397, 17604, + 21204, 25209, 29863, 35720, 42531, 50375, + 59162, 68845, 80108, 93754, 110326, 129488, + 150654, 174328, 201962, 233195, 267843, 308239, + 354503, 405988, 464251, 531550, 608652, 697516, + 802526, 928793, 1080145, 1258120, 1481106, 1760881, + 2111111, 2546619, 3078825, 3748642, 4563142, 5573115, + 6887601, 8582108, 10797296, 14014513, 18625760, 25529599, + 37302935, 58819185, 109782723, WEBRTC_SPL_WORD32_MAX +}; + +const WebRtc_Word16 WebRtcIlbcfix_kScale[64] = { + /* Values in Q16 */ + 29485, 25003, 21345, 18316, 15578, 13128, 10973, 9310, 7955, + 6762, 5789, 4877, 4255, 3699, 3258, 2904, 2595, 2328, + 2123, 1932, 1785, 1631, 1493, 1370, 1260, 1167, 1083, + /* Values in Q21 */ + 32081, 29611, 27262, 25229, 23432, 21803, 20226, 18883, 17609, + 16408, 15311, 14327, 13390, 12513, 11693, 10919, 10163, 9435, + 8739, 8100, 7424, 6813, 6192, 5648, 5122, 4639, 4207, 3798, + 3404, 3048, 2706, 2348, 2036, 1713, 1393, 1087, 747 +}; + +/*frgq in fixpoint, but already computed like this: + for(i=0; i<64; i++){ + a = (pow(10,frgq[i])/4.5); + WebRtcIlbcfix_kFrgQuantMod[i] = round(a); + } + + Value 0 :36 in Q8 + 37:58 in Q5 + 59:63 in Q3 +*/ +const WebRtc_Word16 WebRtcIlbcfix_kFrgQuantMod[64] = { + /* First 37 values in Q8 */ + 569, 671, 786, 916, 1077, 1278, + 1529, 1802, 2109, 2481, 2898, 3440, + 3943, 4535, 5149, 5778, 6464, 7208, + 7904, 8682, 9397, 10285, 11240, 12246, + 13313, 14382, 15492, 16735, 18131, 19693, + 21280, 22912, 24624, 26544, 28432, 30488, + 32720, + /* 22 values in Q5 */ + 4383, 4684, 5012, 5363, 5739, 6146, + 6603, 7113, 7679, 8285, 9040, 9850, + 10838, 11882, 13103, 14467, 15950, 17669, + 19712, 22016, 24800, 28576, + /* 5 values in Q3 */ + 8240, 9792, 12040, 15440, 22472 +}; + +/* Constants for codebook search and creation */ + +/* Expansion filter to get additional cb section. + * Q12 and reversed compared to flp + */ +const WebRtc_Word16 WebRtcIlbcfix_kCbFiltersRev[CB_FILTERLEN]={ + -140, 446, -755, 3302, 2922, -590, 343, -138}; + +/* Weighting coefficients for short lags. + * [0.2 0.4 0.6 0.8] in Q15 */ +const WebRtc_Word16 WebRtcIlbcfix_kAlpha[4]={ + 6554, 13107, 19661, 26214}; + +/* Ranges for search and filters at different subframes */ + +const WebRtc_Word16 WebRtcIlbcfix_kSearchRange[5][CB_NSTAGES]={ + {58,58,58}, {108,44,44}, {108,108,108}, {108,108,108}, {108,108,108}}; + +const WebRtc_Word16 WebRtcIlbcfix_kFilterRange[5]={63, 85, 125, 147, 147}; + +/* Gain Quantization for the codebook gains of the 3 stages */ + +/* Q14 (one extra value (max WebRtc_Word16) to simplify for the search) */ +const WebRtc_Word16 WebRtcIlbcfix_kGainSq3[9]={ + -16384, -10813, -5407, 0, 4096, 8192, + 12288, 16384, 32767}; + +/* Q14 (one extra value (max WebRtc_Word16) to simplify for the search) */ +const WebRtc_Word16 WebRtcIlbcfix_kGainSq4[17]={ + -17203, -14746, -12288, -9830, -7373, -4915, + -2458, 0, 2458, 4915, 7373, 9830, + 12288, 14746, 17203, 19661, 32767}; + +/* Q14 (one extra value (max WebRtc_Word16) to simplify for the search) */ +const WebRtc_Word16 WebRtcIlbcfix_kGainSq5[33]={ + 614, 1229, 1843, 2458, 3072, 3686, + 4301, 4915, 5530, 6144, 6758, 7373, + 7987, 8602, 9216, 9830, 10445, 11059, + 11674, 12288, 12902, 13517, 14131, 14746, + 15360, 15974, 16589, 17203, 17818, 18432, + 19046, 19661, 32767}; + +/* Q14 gain_sq5Tbl squared in Q14 */ +const WebRtc_Word16 WebRtcIlbcfix_kGainSq5Sq[32] = { + 23, 92, 207, 368, 576, 829, + 1129, 1474, 1866, 2304, 2787, 3317, + 3893, 4516, 5184, 5897, 6658, 7464, + 8318, 9216, 10160, 11151, 12187, 13271, + 14400, 15574, 16796, 18062, 19377, 20736, + 22140, 23593 +}; + +const WebRtc_Word16* const WebRtcIlbcfix_kGain[3] = +{WebRtcIlbcfix_kGainSq5, WebRtcIlbcfix_kGainSq4, WebRtcIlbcfix_kGainSq3}; + + +/* Tables for the Enhancer, using upsamling factor 4 (ENH_UPS0 = 4) */ + +const WebRtc_Word16 WebRtcIlbcfix_kEnhPolyPhaser[ENH_UPS0][ENH_FLO_MULT2_PLUS1]={ + {0, 0, 0, 4096, 0, 0, 0}, + {64, -315, 1181, 3531, -436, 77, -64}, + {97, -509, 2464, 2464, -509, 97, -97}, + {77, -436, 3531, 1181, -315, 64, -77} +}; + +const WebRtc_Word16 WebRtcIlbcfix_kEnhWt[3] = { + 4800, 16384, 27968 /* Q16 */ +}; + +const WebRtc_Word16 WebRtcIlbcfix_kEnhPlocs[ENH_NBLOCKS_TOT] = { + 160, 480, 800, 1120, 1440, 1760, 2080, 2400 /* Q(-2) */ +}; + +/* PLC table */ + +const WebRtc_Word16 WebRtcIlbcfix_kPlcPerSqr[6] = { /* Grid points for square of periodiciy in Q15 */ + 839, 1343, 2048, 2998, 4247, 5849 +}; + +const WebRtc_Word16 WebRtcIlbcfix_kPlcPitchFact[6] = { /* Value of y=(x^4-0.4)/(0.7-0.4) in grid points in Q15 */ + 0, 5462, 10922, 16384, 21846, 27306 +}; + +const WebRtc_Word16 WebRtcIlbcfix_kPlcPfSlope[6] = { /* Slope of y=(x^4-0.4)/(0.7-0.4) in Q11 */ + 26667, 18729, 13653, 10258, 7901, 6214 +}; diff --git a/src/libs/webrtc/ilbcfix/ilbc_decode.c b/src/libs/webrtc/ilbcfix/ilbc_decode.c new file mode 100644 index 00000000..827532c5 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/ilbc_decode.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Decode.c + +******************************************************************/ + +#include "defines.h" +#include "simple_lsf_dequant.h" +#include "decoder_interpolate_lsf.h" +#include "index_conv_dec.h" +#include "do_plc.h" +#include "constants.h" +#include "enhancer_interface.h" +#include "xcorr_coef.h" +#include "lsf_check.h" +#include "decode_residual.h" +#include "unpack_bits.h" +#include "hp_output.h" +#ifndef WEBRTC_BIG_ENDIAN +#include "swap_bytes.h" +#endif + +/*----------------------------------------------------------------* + * main decoder function + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_DecodeImpl( + WebRtc_Word16 *decblock, /* (o) decoded signal block */ + WebRtc_UWord16 *bytes, /* (i) encoded signal bits */ + iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state + structure */ + WebRtc_Word16 mode /* (i) 0: bad packet, PLC, + 1: normal */ + ) { + int i; + WebRtc_Word16 order_plus_one; + + WebRtc_Word16 last_bit; + WebRtc_Word16 *data; + /* Stack based */ + WebRtc_Word16 decresidual[BLOCKL_MAX]; + WebRtc_Word16 PLCresidual[BLOCKL_MAX + LPC_FILTERORDER]; + WebRtc_Word16 syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)]; + WebRtc_Word16 PLClpc[LPC_FILTERORDER + 1]; + iLBC_bits *iLBCbits_inst = (iLBC_bits*)PLCresidual; + + /* Reuse some buffers that are non overlapping in order to save stack memory */ + data = &PLCresidual[LPC_FILTERORDER]; + + if (mode>0) { /* the data are good */ + + /* decode data */ + +#ifndef WEBRTC_BIG_ENDIAN + WebRtcIlbcfix_SwapBytes((WebRtc_UWord16*)bytes, iLBCdec_inst->no_of_words); +#endif + + /* Unpacketize bits into parameters */ + + last_bit = WebRtcIlbcfix_UnpackBits(bytes, iLBCbits_inst, iLBCdec_inst->mode); + +#ifndef WEBRTC_BIG_ENDIAN + /* Swap back so that the the input vector "bytes" is unchanged */ + WebRtcIlbcfix_SwapBytes((WebRtc_UWord16*)bytes, iLBCdec_inst->no_of_words); +#endif + + /* Check for bit errors */ + if (iLBCbits_inst->startIdx<1) + mode = 0; + if ((iLBCdec_inst->mode==20) && (iLBCbits_inst->startIdx>3)) + mode = 0; + if ((iLBCdec_inst->mode==30) && (iLBCbits_inst->startIdx>5)) + mode = 0; + if (last_bit==1) + mode = 0; + + if (mode==1) { /* No bit errors was detected, continue decoding */ + /* Stack based */ + WebRtc_Word16 lsfdeq[LPC_FILTERORDER*LPC_N_MAX]; + WebRtc_Word16 weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX]; + + /* adjust index */ + WebRtcIlbcfix_IndexConvDec(iLBCbits_inst->cb_index); + + /* decode the lsf */ + WebRtcIlbcfix_SimpleLsfDeQ(lsfdeq, (WebRtc_Word16*)(iLBCbits_inst->lsf), iLBCdec_inst->lpc_n); + WebRtcIlbcfix_LsfCheck(lsfdeq, LPC_FILTERORDER, iLBCdec_inst->lpc_n); + WebRtcIlbcfix_DecoderInterpolateLsp(syntdenum, weightdenum, + lsfdeq, LPC_FILTERORDER, iLBCdec_inst); + + /* Decode the residual using the cb and gain indexes */ + WebRtcIlbcfix_DecodeResidual(iLBCdec_inst, iLBCbits_inst, decresidual, syntdenum); + + /* preparing the plc for a future loss! */ + WebRtcIlbcfix_DoThePlc( PLCresidual, PLClpc, 0, + decresidual, syntdenum + (LPC_FILTERORDER + 1)*(iLBCdec_inst->nsub - 1), + (WebRtc_Word16)(iLBCdec_inst->last_lag), iLBCdec_inst); + + /* Use the output from doThePLC */ + WEBRTC_SPL_MEMCPY_W16(decresidual, PLCresidual, iLBCdec_inst->blockl); + } + + } + + if (mode == 0) { + /* the data is bad (either a PLC call + * was made or a bit error was detected) + */ + + /* packet loss conceal */ + + WebRtcIlbcfix_DoThePlc( PLCresidual, PLClpc, 1, + decresidual, syntdenum, (WebRtc_Word16)(iLBCdec_inst->last_lag), iLBCdec_inst); + + WEBRTC_SPL_MEMCPY_W16(decresidual, PLCresidual, iLBCdec_inst->blockl); + + order_plus_one = LPC_FILTERORDER + 1; + + for (i = 0; i < iLBCdec_inst->nsub; i++) { + WEBRTC_SPL_MEMCPY_W16(syntdenum+(i*order_plus_one), + PLClpc, order_plus_one); + } + } + + if ((*iLBCdec_inst).use_enhancer == 1) { /* Enhancer activated */ + + /* Update the filter and filter coefficients if there was a packet loss */ + if (iLBCdec_inst->prev_enh_pl==2) { + for (i=0;i<iLBCdec_inst->nsub;i++) { + WEBRTC_SPL_MEMCPY_W16(&(iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)]), + syntdenum, (LPC_FILTERORDER+1)); + } + } + + /* post filtering */ + (*iLBCdec_inst).last_lag = + WebRtcIlbcfix_EnhancerInterface(data, decresidual, iLBCdec_inst); + + /* synthesis filtering */ + + /* Set up the filter state */ + WEBRTC_SPL_MEMCPY_W16(&data[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER); + + if (iLBCdec_inst->mode==20) { + /* Enhancer has 40 samples delay */ + i=0; + WebRtcSpl_FilterARFastQ12( + data, data, + iLBCdec_inst->old_syntdenum + (i+iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1), + LPC_FILTERORDER+1, SUBL); + + for (i=1; i < iLBCdec_inst->nsub; i++) { + WebRtcSpl_FilterARFastQ12( + data+i*SUBL, data+i*SUBL, + syntdenum+(i-1)*(LPC_FILTERORDER+1), + LPC_FILTERORDER+1, SUBL); + } + + } else if (iLBCdec_inst->mode==30) { + /* Enhancer has 80 samples delay */ + for (i=0; i < 2; i++) { + WebRtcSpl_FilterARFastQ12( + data+i*SUBL, data+i*SUBL, + iLBCdec_inst->old_syntdenum + (i+4)*(LPC_FILTERORDER+1), + LPC_FILTERORDER+1, SUBL); + } + for (i=2; i < iLBCdec_inst->nsub; i++) { + WebRtcSpl_FilterARFastQ12( + data+i*SUBL, data+i*SUBL, + syntdenum+(i-2)*(LPC_FILTERORDER+1), + LPC_FILTERORDER+1, SUBL); + } + } + + /* Save the filter state */ + WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &data[iLBCdec_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER); + + } else { /* Enhancer not activated */ + WebRtc_Word16 lag; + + /* Find last lag (since the enhancer is not called to give this info) */ + lag = 20; + if (iLBCdec_inst->mode==20) { + lag = (WebRtc_Word16)WebRtcIlbcfix_XcorrCoef( + &decresidual[iLBCdec_inst->blockl-60], + &decresidual[iLBCdec_inst->blockl-60-lag], + 60, + 80, lag, -1); + } else { + lag = (WebRtc_Word16)WebRtcIlbcfix_XcorrCoef( + &decresidual[iLBCdec_inst->blockl-ENH_BLOCKL], + &decresidual[iLBCdec_inst->blockl-ENH_BLOCKL-lag], + ENH_BLOCKL, + 100, lag, -1); + } + + /* Store lag (it is needed if next packet is lost) */ + (*iLBCdec_inst).last_lag = (int)lag; + + /* copy data and run synthesis filter */ + WEBRTC_SPL_MEMCPY_W16(data, decresidual, iLBCdec_inst->blockl); + + /* Set up the filter state */ + WEBRTC_SPL_MEMCPY_W16(&data[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER); + + for (i=0; i < iLBCdec_inst->nsub; i++) { + WebRtcSpl_FilterARFastQ12( + data+i*SUBL, data+i*SUBL, + syntdenum + i*(LPC_FILTERORDER+1), + LPC_FILTERORDER+1, SUBL); + } + + /* Save the filter state */ + WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &data[iLBCdec_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER); + } + + WEBRTC_SPL_MEMCPY_W16(decblock,data,iLBCdec_inst->blockl); + + /* High pass filter the signal (with upscaling a factor 2 and saturation) */ + WebRtcIlbcfix_HpOutput(decblock, (WebRtc_Word16*)WebRtcIlbcfix_kHpOutCoefs, + iLBCdec_inst->hpimemy, iLBCdec_inst->hpimemx, + iLBCdec_inst->blockl); + + WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->old_syntdenum, + syntdenum, iLBCdec_inst->nsub*(LPC_FILTERORDER+1)); + + iLBCdec_inst->prev_enh_pl=0; + + if (mode==0) { /* PLC was used */ + iLBCdec_inst->prev_enh_pl=1; + } +} diff --git a/src/libs/webrtc/ilbcfix/ilbc_encode.c b/src/libs/webrtc/ilbcfix/ilbc_encode.c new file mode 100644 index 00000000..64e9eab3 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/ilbc_encode.c @@ -0,0 +1,518 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Encode.c + +******************************************************************/ + +#include "defines.h" +#include "lpc_encode.h" +#include "frame_classify.h" +#include "state_search.h" +#include "state_construct.h" +#include "constants.h" +#include "cb_search.h" +#include "cb_construct.h" +#include "index_conv_enc.h" +#include "pack_bits.h" +#include "hp_input.h" + +#ifdef SPLIT_10MS +#include "unpack_bits.h" +#include "index_conv_dec.h" +#endif +#ifndef WEBRTC_BIG_ENDIAN +#include "swap_bytes.h" +#endif + +/*----------------------------------------------------------------* + * main encoder function + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_EncodeImpl( + WebRtc_UWord16 *bytes, /* (o) encoded data bits iLBC */ + WebRtc_Word16 *block, /* (i) speech vector to encode */ + iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder + state */ + ){ + int n, meml_gotten, Nfor, Nback; + WebRtc_Word16 diff, start_pos; + int index; + int subcount, subframe; + WebRtc_Word16 start_count, end_count; + WebRtc_Word16 *residual; + WebRtc_Word32 en1, en2; + WebRtc_Word16 scale, max; + WebRtc_Word16 *syntdenum; + WebRtc_Word16 *decresidual; + WebRtc_Word16 *reverseResidual; + WebRtc_Word16 *reverseDecresidual; + /* Stack based */ + WebRtc_Word16 weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX]; + WebRtc_Word16 dataVec[BLOCKL_MAX + LPC_FILTERORDER]; + WebRtc_Word16 memVec[CB_MEML+CB_FILTERLEN]; + WebRtc_Word16 bitsMemory[sizeof(iLBC_bits)/sizeof(WebRtc_Word16)]; + iLBC_bits *iLBCbits_inst = (iLBC_bits*)bitsMemory; + + +#ifdef SPLIT_10MS + WebRtc_Word16 *weightdenumbuf = iLBCenc_inst->weightdenumbuf; + WebRtc_Word16 last_bit; +#endif + + WebRtc_Word16 *data = &dataVec[LPC_FILTERORDER]; + WebRtc_Word16 *mem = &memVec[CB_HALFFILTERLEN]; + + /* Reuse som buffers to save stack memory */ + residual = &iLBCenc_inst->lpc_buffer[LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl]; + syntdenum = mem; /* syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX] and mem are used non overlapping in the code */ + decresidual = residual; /* Already encoded residual is overwritten by the decoded version */ + reverseResidual = data; /* data and reverseResidual are used non overlapping in the code */ + reverseDecresidual = reverseResidual; /* Already encoded residual is overwritten by the decoded version */ + +#ifdef SPLIT_10MS + + WebRtcSpl_MemSetW16 ( (WebRtc_Word16 *) iLBCbits_inst, 0, + (WebRtc_Word16) (sizeof(iLBC_bits) / sizeof(WebRtc_Word16)) ); + + start_pos = iLBCenc_inst->start_pos; + diff = iLBCenc_inst->diff; + + if (iLBCenc_inst->section != 0){ + WEBRTC_SPL_MEMCPY_W16 (weightdenum, weightdenumbuf, + SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM); + /* Un-Packetize the frame into parameters */ + last_bit = WebRtcIlbcfix_UnpackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode); + if (last_bit) + return; + /* adjust index */ + WebRtcIlbcfix_IndexConvDec (iLBCbits_inst->cb_index); + + if (iLBCenc_inst->section == 1){ + /* Save first 80 samples of a 160/240 sample frame for 20/30msec */ + WEBRTC_SPL_MEMCPY_W16 (iLBCenc_inst->past_samples, block, 80); + } + else{ // iLBCenc_inst->section == 2 AND mode = 30ms + /* Save second 80 samples of a 240 sample frame for 30msec */ + WEBRTC_SPL_MEMCPY_W16 (iLBCenc_inst->past_samples + 80, block, 80); + } + } + else{ // iLBCenc_inst->section == 0 + /* form a complete frame of 160/240 for 20msec/30msec mode */ + WEBRTC_SPL_MEMCPY_W16 (data + (iLBCenc_inst->mode * 8) - 80, block, 80); + WEBRTC_SPL_MEMCPY_W16 (data, iLBCenc_inst->past_samples, + (iLBCenc_inst->mode * 8) - 80); + iLBCenc_inst->Nfor_flag = 0; + iLBCenc_inst->Nback_flag = 0; +#else + /* copy input block to data*/ + WEBRTC_SPL_MEMCPY_W16(data,block,iLBCenc_inst->blockl); +#endif + + /* high pass filtering of input signal and scale down the residual (*0.5) */ + WebRtcIlbcfix_HpInput(data, (WebRtc_Word16*)WebRtcIlbcfix_kHpInCoefs, + iLBCenc_inst->hpimemy, iLBCenc_inst->hpimemx, + iLBCenc_inst->blockl); + + /* LPC of hp filtered input data */ + WebRtcIlbcfix_LpcEncode(syntdenum, weightdenum, iLBCbits_inst->lsf, data, + iLBCenc_inst); + + /* Set up state */ + WEBRTC_SPL_MEMCPY_W16(dataVec, iLBCenc_inst->anaMem, LPC_FILTERORDER); + + /* inverse filter to get residual */ + for (n=0; n<iLBCenc_inst->nsub; n++ ) { + WebRtcSpl_FilterMAFastQ12( + &data[n*SUBL], &residual[n*SUBL], + &syntdenum[n*(LPC_FILTERORDER+1)], + LPC_FILTERORDER+1, SUBL); + } + + /* Copy the state for next frame */ + WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->anaMem, &data[iLBCenc_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER); + + /* find state location */ + + iLBCbits_inst->startIdx = WebRtcIlbcfix_FrameClassify(iLBCenc_inst,residual); + + /* check if state should be in first or last part of the + two subframes */ + + index = (iLBCbits_inst->startIdx-1)*SUBL; + max=WebRtcSpl_MaxAbsValueW16(&residual[index], 2*SUBL); + scale=WebRtcSpl_GetSizeInBits(WEBRTC_SPL_MUL_16_16(max,max)); + + /* Scale to maximum 25 bits so that the MAC won't cause overflow */ + scale = scale - 25; + if(scale < 0) { + scale = 0; + } + + diff = STATE_LEN - iLBCenc_inst->state_short_len; + en1=WebRtcSpl_DotProductWithScale(&residual[index], &residual[index], + iLBCenc_inst->state_short_len, scale); + index += diff; + en2=WebRtcSpl_DotProductWithScale(&residual[index], &residual[index], + iLBCenc_inst->state_short_len, scale); + if (en1 > en2) { + iLBCbits_inst->state_first = 1; + start_pos = (iLBCbits_inst->startIdx-1)*SUBL; + } else { + iLBCbits_inst->state_first = 0; + start_pos = (iLBCbits_inst->startIdx-1)*SUBL + diff; + } + + /* scalar quantization of state */ + + WebRtcIlbcfix_StateSearch(iLBCenc_inst, iLBCbits_inst, &residual[start_pos], + &syntdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)], + &weightdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)]); + + WebRtcIlbcfix_StateConstruct(iLBCbits_inst->idxForMax, iLBCbits_inst->idxVec, + &syntdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)], + &decresidual[start_pos], iLBCenc_inst->state_short_len + ); + + /* predictive quantization in state */ + + if (iLBCbits_inst->state_first) { /* put adaptive part in the end */ + + /* setup memory */ + + WebRtcSpl_MemSetW16(mem, 0, (WebRtc_Word16)(CB_MEML-iLBCenc_inst->state_short_len)); + WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-iLBCenc_inst->state_short_len, + decresidual+start_pos, iLBCenc_inst->state_short_len); + + /* encode subframes */ + + WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index, iLBCbits_inst->gain_index, + &residual[start_pos+iLBCenc_inst->state_short_len], + mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, diff, + &weightdenum[iLBCbits_inst->startIdx*(LPC_FILTERORDER+1)], 0); + + /* construct decoded vector */ + + WebRtcIlbcfix_CbConstruct(&decresidual[start_pos+iLBCenc_inst->state_short_len], + iLBCbits_inst->cb_index, iLBCbits_inst->gain_index, + mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, + diff + ); + + } + else { /* put adaptive part in the beginning */ + + /* create reversed vectors for prediction */ + + WebRtcSpl_MemCpyReversedOrder(&reverseResidual[diff-1], + &residual[(iLBCbits_inst->startIdx+1)*SUBL-STATE_LEN], diff); + + /* setup memory */ + + meml_gotten = iLBCenc_inst->state_short_len; + WebRtcSpl_MemCpyReversedOrder(&mem[CB_MEML-1], &decresidual[start_pos], meml_gotten); + WebRtcSpl_MemSetW16(mem, 0, (WebRtc_Word16)(CB_MEML-iLBCenc_inst->state_short_len)); + + /* encode subframes */ + WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index, iLBCbits_inst->gain_index, + reverseResidual, mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, diff, + &weightdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)], + 0); + + /* construct decoded vector */ + + WebRtcIlbcfix_CbConstruct(reverseDecresidual, + iLBCbits_inst->cb_index, iLBCbits_inst->gain_index, + mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, + diff + ); + + /* get decoded residual from reversed vector */ + + WebRtcSpl_MemCpyReversedOrder(&decresidual[start_pos-1], reverseDecresidual, diff); + } + +#ifdef SPLIT_10MS + iLBCenc_inst->start_pos = start_pos; + iLBCenc_inst->diff = diff; + iLBCenc_inst->section++; + /* adjust index */ + WebRtcIlbcfix_IndexConvEnc (iLBCbits_inst->cb_index); + /* Packetize the parameters into the frame */ + WebRtcIlbcfix_PackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode); + WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum, + SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM); + return; + } +#endif + + /* forward prediction of subframes */ + + Nfor = iLBCenc_inst->nsub-iLBCbits_inst->startIdx-1; + + /* counter for predicted subframes */ +#ifdef SPLIT_10MS + if (iLBCenc_inst->mode == 20) + { + subcount = 1; + } + if (iLBCenc_inst->mode == 30) + { + if (iLBCenc_inst->section == 1) + { + subcount = 1; + } + if (iLBCenc_inst->section == 2) + { + subcount = 3; + } + } +#else + subcount=1; +#endif + + if( Nfor > 0 ){ + + /* setup memory */ + + WebRtcSpl_MemSetW16(mem, 0, CB_MEML-STATE_LEN); + WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-STATE_LEN, + decresidual+(iLBCbits_inst->startIdx-1)*SUBL, STATE_LEN); + +#ifdef SPLIT_10MS + if (iLBCenc_inst->Nfor_flag > 0) + { + for (subframe = 0; subframe < WEBRTC_SPL_MIN (Nfor, 2); subframe++) + { + /* update memory */ + WEBRTC_SPL_MEMCPY_W16 (mem, mem + SUBL, (CB_MEML - SUBL)); + WEBRTC_SPL_MEMCPY_W16 (mem + CB_MEML - SUBL, + &decresidual[(iLBCbits_inst->startIdx + 1 + + subframe) * SUBL], SUBL); + } + } + + iLBCenc_inst->Nfor_flag++; + + if (iLBCenc_inst->mode == 20) + { + start_count = 0; + end_count = Nfor; + } + if (iLBCenc_inst->mode == 30) + { + if (iLBCenc_inst->section == 1) + { + start_count = 0; + end_count = WEBRTC_SPL_MIN (Nfor, 2); + } + if (iLBCenc_inst->section == 2) + { + start_count = WEBRTC_SPL_MIN (Nfor, 2); + end_count = Nfor; + } + } +#else + start_count = 0; + end_count = (WebRtc_Word16)Nfor; +#endif + + /* loop over subframes to encode */ + + for (subframe = start_count; subframe < end_count; subframe++){ + + /* encode subframe */ + + WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index+subcount*CB_NSTAGES, + iLBCbits_inst->gain_index+subcount*CB_NSTAGES, + &residual[(iLBCbits_inst->startIdx+1+subframe)*SUBL], + mem, MEM_LF_TBL, SUBL, + &weightdenum[(iLBCbits_inst->startIdx+1+subframe)*(LPC_FILTERORDER+1)], + (WebRtc_Word16)subcount); + + /* construct decoded vector */ + + WebRtcIlbcfix_CbConstruct(&decresidual[(iLBCbits_inst->startIdx+1+subframe)*SUBL], + iLBCbits_inst->cb_index+subcount*CB_NSTAGES, + iLBCbits_inst->gain_index+subcount*CB_NSTAGES, + mem, MEM_LF_TBL, + SUBL + ); + + /* update memory */ + + WEBRTC_SPL_MEMMOVE_W16(mem, mem+SUBL, (CB_MEML-SUBL)); + WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL, + &decresidual[(iLBCbits_inst->startIdx+1+subframe)*SUBL], SUBL); + + subcount++; + } + } + +#ifdef SPLIT_10MS + if ((iLBCenc_inst->section == 1) && + (iLBCenc_inst->mode == 30) && (Nfor > 0) && (end_count == 2)) + { + iLBCenc_inst->section++; + /* adjust index */ + WebRtcIlbcfix_IndexConvEnc (iLBCbits_inst->cb_index); + /* Packetize the parameters into the frame */ + WebRtcIlbcfix_PackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode); + WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum, + SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM); + return; + } +#endif + + /* backward prediction of subframes */ + + Nback = iLBCbits_inst->startIdx-1; + + if( Nback > 0 ){ + + /* create reverse order vectors + (The decresidual does not need to be copied since it is + contained in the same vector as the residual) + */ + + WebRtcSpl_MemCpyReversedOrder(&reverseResidual[Nback*SUBL-1], residual, Nback*SUBL); + + /* setup memory */ + + meml_gotten = SUBL*(iLBCenc_inst->nsub+1-iLBCbits_inst->startIdx); + if( meml_gotten > CB_MEML ) { + meml_gotten=CB_MEML; + } + + WebRtcSpl_MemCpyReversedOrder(&mem[CB_MEML-1], &decresidual[Nback*SUBL], meml_gotten); + WebRtcSpl_MemSetW16(mem, 0, (WebRtc_Word16)(CB_MEML-meml_gotten)); + +#ifdef SPLIT_10MS + if (iLBCenc_inst->Nback_flag > 0) + { + for (subframe = 0; subframe < WEBRTC_SPL_MAX (2 - Nfor, 0); subframe++) + { + /* update memory */ + WEBRTC_SPL_MEMCPY_W16 (mem, mem + SUBL, (CB_MEML - SUBL)); + WEBRTC_SPL_MEMCPY_W16 (mem + CB_MEML - SUBL, + &reverseDecresidual[subframe * SUBL], SUBL); + } + } + + iLBCenc_inst->Nback_flag++; + + + if (iLBCenc_inst->mode == 20) + { + start_count = 0; + end_count = Nback; + } + if (iLBCenc_inst->mode == 30) + { + if (iLBCenc_inst->section == 1) + { + start_count = 0; + end_count = WEBRTC_SPL_MAX (2 - Nfor, 0); + } + if (iLBCenc_inst->section == 2) + { + start_count = WEBRTC_SPL_MAX (2 - Nfor, 0); + end_count = Nback; + } + } +#else + start_count = 0; + end_count = (WebRtc_Word16)Nback; +#endif + + /* loop over subframes to encode */ + + for (subframe = start_count; subframe < end_count; subframe++){ + + /* encode subframe */ + + WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index+subcount*CB_NSTAGES, + iLBCbits_inst->gain_index+subcount*CB_NSTAGES, &reverseResidual[subframe*SUBL], + mem, MEM_LF_TBL, SUBL, + &weightdenum[(iLBCbits_inst->startIdx-2-subframe)*(LPC_FILTERORDER+1)], + (WebRtc_Word16)subcount); + + /* construct decoded vector */ + + WebRtcIlbcfix_CbConstruct(&reverseDecresidual[subframe*SUBL], + iLBCbits_inst->cb_index+subcount*CB_NSTAGES, + iLBCbits_inst->gain_index+subcount*CB_NSTAGES, + mem, MEM_LF_TBL, SUBL + ); + + /* update memory */ + + WEBRTC_SPL_MEMMOVE_W16(mem, mem+SUBL, (CB_MEML-SUBL)); + WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL, + &reverseDecresidual[subframe*SUBL], SUBL); + + subcount++; + + } + + /* get decoded residual from reversed vector */ + + WebRtcSpl_MemCpyReversedOrder(&decresidual[SUBL*Nback-1], reverseDecresidual, SUBL*Nback); + } + /* end encoding part */ + + /* adjust index */ + + WebRtcIlbcfix_IndexConvEnc(iLBCbits_inst->cb_index); + + /* Packetize the parameters into the frame */ + +#ifdef SPLIT_10MS + if( (iLBCenc_inst->mode==30) && (iLBCenc_inst->section==1) ){ + WebRtcIlbcfix_PackBits(iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode); + } + else{ + WebRtcIlbcfix_PackBits(bytes, iLBCbits_inst, iLBCenc_inst->mode); + } +#else + WebRtcIlbcfix_PackBits(bytes, iLBCbits_inst, iLBCenc_inst->mode); +#endif + +#ifndef WEBRTC_BIG_ENDIAN + /* Swap bytes for LITTLE ENDIAN since the packbits() + function assumes BIG_ENDIAN machine */ +#ifdef SPLIT_10MS + if (( (iLBCenc_inst->section == 1) && (iLBCenc_inst->mode == 20) ) || + ( (iLBCenc_inst->section == 2) && (iLBCenc_inst->mode == 30) )){ + WebRtcIlbcfix_SwapBytes(bytes, iLBCenc_inst->no_of_words); + } +#else + WebRtcIlbcfix_SwapBytes(bytes, iLBCenc_inst->no_of_words); +#endif +#endif + +#ifdef SPLIT_10MS + if (subcount == (iLBCenc_inst->nsub - 1)) + { + iLBCenc_inst->section = 0; + } + else + { + iLBCenc_inst->section++; + WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum, + SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM); + } +#endif + +} diff --git a/src/libs/webrtc/ilbcfix/index_conv_dec.c b/src/libs/webrtc/ilbcfix/index_conv_dec.c new file mode 100644 index 00000000..0d6346a9 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/index_conv_dec.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_IndexConvDec.c + +******************************************************************/ + +#include "defines.h" + +void WebRtcIlbcfix_IndexConvDec( + WebRtc_Word16 *index /* (i/o) Codebook indexes */ + ){ + int k; + + for (k=4;k<6;k++) { + /* Readjust the second and third codebook index for the first 40 sample + so that they look the same as the first (in terms of lag) + */ + if ((index[k]>=44)&&(index[k]<108)) { + index[k]+=64; + } else if ((index[k]>=108)&&(index[k]<128)) { + index[k]+=128; + } else { + /* ERROR */ + } + } +} diff --git a/src/libs/webrtc/ilbcfix/index_conv_dec.h b/src/libs/webrtc/ilbcfix/index_conv_dec.h new file mode 100644 index 00000000..f29ee230 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/index_conv_dec.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_IndexConvDec.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INDEX_CONV_DEC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INDEX_CONV_DEC_H_ + +#include "defines.h" + +void WebRtcIlbcfix_IndexConvDec( + WebRtc_Word16 *index /* (i/o) Codebook indexes */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/index_conv_enc.c b/src/libs/webrtc/ilbcfix/index_conv_enc.c new file mode 100644 index 00000000..cbc04b62 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/index_conv_enc.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + IiLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_IndexConvEnc.c + +******************************************************************/ + +#include "defines.h" +/*----------------------------------------------------------------* + * Convert the codebook indexes to make the search easier + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_IndexConvEnc( + WebRtc_Word16 *index /* (i/o) Codebook indexes */ + ){ + int k; + + for (k=4;k<6;k++) { + /* Readjust the second and third codebook index so that it is + packetized into 7 bits (before it was put in lag-wise the same + way as for the first codebook which uses 8 bits) + */ + if ((index[k]>=108)&&(index[k]<172)) { + index[k]-=64; + } else if (index[k]>=236) { + index[k]-=128; + } else { + /* ERROR */ + } + } +} diff --git a/src/libs/webrtc/ilbcfix/index_conv_enc.h b/src/libs/webrtc/ilbcfix/index_conv_enc.h new file mode 100644 index 00000000..d28a6e2a --- /dev/null +++ b/src/libs/webrtc/ilbcfix/index_conv_enc.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_IndexConvEnc.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INDEX_CONV_ENC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INDEX_CONV_ENC_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Convert the codebook indexes to make the search easier + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_IndexConvEnc( + WebRtc_Word16 *index /* (i/o) Codebook indexes */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/init_decode.c b/src/libs/webrtc/ilbcfix/init_decode.c new file mode 100644 index 00000000..b654f1ec --- /dev/null +++ b/src/libs/webrtc/ilbcfix/init_decode.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_InitDecode.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * Initiation of decoder instance. + *---------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_InitDecode( /* (o) Number of decoded samples */ + iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ + WebRtc_Word16 mode, /* (i) frame size mode */ + int use_enhancer /* (i) 1 to use enhancer + 0 to run without enhancer */ + ) { + int i; + + iLBCdec_inst->mode = mode; + + /* Set all the variables that are dependent on the frame size mode */ + if (mode==30) { + iLBCdec_inst->blockl = BLOCKL_30MS; + iLBCdec_inst->nsub = NSUB_30MS; + iLBCdec_inst->nasub = NASUB_30MS; + iLBCdec_inst->lpc_n = LPC_N_30MS; + iLBCdec_inst->no_of_bytes = NO_OF_BYTES_30MS; + iLBCdec_inst->no_of_words = NO_OF_WORDS_30MS; + iLBCdec_inst->state_short_len=STATE_SHORT_LEN_30MS; + } + else if (mode==20) { + iLBCdec_inst->blockl = BLOCKL_20MS; + iLBCdec_inst->nsub = NSUB_20MS; + iLBCdec_inst->nasub = NASUB_20MS; + iLBCdec_inst->lpc_n = LPC_N_20MS; + iLBCdec_inst->no_of_bytes = NO_OF_BYTES_20MS; + iLBCdec_inst->no_of_words = NO_OF_WORDS_20MS; + iLBCdec_inst->state_short_len=STATE_SHORT_LEN_20MS; + } + else { + return(-1); + } + + /* Reset all the previous LSF to mean LSF */ + WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->lsfdeqold, WebRtcIlbcfix_kLsfMean, LPC_FILTERORDER); + + /* Clear the synthesis filter memory */ + WebRtcSpl_MemSetW16(iLBCdec_inst->syntMem, 0, LPC_FILTERORDER); + + /* Set the old synthesis filter to {1.0 0.0 ... 0.0} */ + WebRtcSpl_MemSetW16(iLBCdec_inst->old_syntdenum, 0, ((LPC_FILTERORDER + 1)*NSUB_MAX)); + for (i=0; i<NSUB_MAX; i++) { + iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)] = 4096; + } + + /* Clear the variables that are used for the PLC */ + iLBCdec_inst->last_lag = 20; + iLBCdec_inst->consPLICount = 0; + iLBCdec_inst->prevPLI = 0; + iLBCdec_inst->perSquare = 0; + iLBCdec_inst->prevLag = 120; + iLBCdec_inst->prevLpc[0] = 4096; + WebRtcSpl_MemSetW16(iLBCdec_inst->prevLpc+1, 0, LPC_FILTERORDER); + WebRtcSpl_MemSetW16(iLBCdec_inst->prevResidual, 0, BLOCKL_MAX); + + /* Initialize the seed for the random number generator */ + iLBCdec_inst->seed = 777; + + /* Set the filter state of the HP filter to 0 */ + WebRtcSpl_MemSetW16(iLBCdec_inst->hpimemx, 0, 2); + WebRtcSpl_MemSetW16(iLBCdec_inst->hpimemy, 0, 4); + + /* Set the variables that are used in the ehnahcer */ + iLBCdec_inst->use_enhancer = use_enhancer; + WebRtcSpl_MemSetW16(iLBCdec_inst->enh_buf, 0, (ENH_BUFL+ENH_BUFL_FILTEROVERHEAD)); + for (i=0;i<ENH_NBLOCKS_TOT;i++) { + iLBCdec_inst->enh_period[i]=160; /* Q(-4) */ + } + + iLBCdec_inst->prev_enh_pl = 0; + + return (iLBCdec_inst->blockl); +} diff --git a/src/libs/webrtc/ilbcfix/init_decode.h b/src/libs/webrtc/ilbcfix/init_decode.h new file mode 100644 index 00000000..3452f34a --- /dev/null +++ b/src/libs/webrtc/ilbcfix/init_decode.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_InitDecode.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INIT_DECODE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INIT_DECODE_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Initiation of decoder instance. + *---------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_InitDecode( /* (o) Number of decoded samples */ + iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ + WebRtc_Word16 mode, /* (i) frame size mode */ + int use_enhancer /* (i) 1 to use enhancer + 0 to run without enhancer */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/init_encode.c b/src/libs/webrtc/ilbcfix/init_encode.c new file mode 100644 index 00000000..e034bb0d --- /dev/null +++ b/src/libs/webrtc/ilbcfix/init_encode.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_InitEncode.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * Initiation of encoder instance. + *---------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_InitEncode( /* (o) Number of bytes encoded */ + iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) Encoder instance */ + WebRtc_Word16 mode /* (i) frame size mode */ + ){ + iLBCenc_inst->mode = mode; + + /* Set all the variables that are dependent on the frame size mode */ + if (mode==30) { + iLBCenc_inst->blockl = BLOCKL_30MS; + iLBCenc_inst->nsub = NSUB_30MS; + iLBCenc_inst->nasub = NASUB_30MS; + iLBCenc_inst->lpc_n = LPC_N_30MS; + iLBCenc_inst->no_of_bytes = NO_OF_BYTES_30MS; + iLBCenc_inst->no_of_words = NO_OF_WORDS_30MS; + iLBCenc_inst->state_short_len=STATE_SHORT_LEN_30MS; + } + else if (mode==20) { + iLBCenc_inst->blockl = BLOCKL_20MS; + iLBCenc_inst->nsub = NSUB_20MS; + iLBCenc_inst->nasub = NASUB_20MS; + iLBCenc_inst->lpc_n = LPC_N_20MS; + iLBCenc_inst->no_of_bytes = NO_OF_BYTES_20MS; + iLBCenc_inst->no_of_words = NO_OF_WORDS_20MS; + iLBCenc_inst->state_short_len=STATE_SHORT_LEN_20MS; + } + else { + return(-1); + } + + /* Clear the buffers and set the previous LSF and LSP to the mean value */ + WebRtcSpl_MemSetW16(iLBCenc_inst->anaMem, 0, LPC_FILTERORDER); + WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->lsfold, WebRtcIlbcfix_kLsfMean, LPC_FILTERORDER); + WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->lsfdeqold, WebRtcIlbcfix_kLsfMean, LPC_FILTERORDER); + WebRtcSpl_MemSetW16(iLBCenc_inst->lpc_buffer, 0, LPC_LOOKBACK + BLOCKL_MAX); + + /* Set the filter state of the HP filter to 0 */ + WebRtcSpl_MemSetW16(iLBCenc_inst->hpimemx, 0, 2); + WebRtcSpl_MemSetW16(iLBCenc_inst->hpimemy, 0, 4); + +#ifdef SPLIT_10MS + /*Zeroing the past samples for 10msec Split*/ + WebRtcSpl_MemSetW16(iLBCenc_inst->past_samples,0,160); + iLBCenc_inst->section = 0; +#endif + + return (iLBCenc_inst->no_of_bytes); +} diff --git a/src/libs/webrtc/ilbcfix/init_encode.h b/src/libs/webrtc/ilbcfix/init_encode.h new file mode 100644 index 00000000..f1d18583 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/init_encode.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_InitEncode.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INIT_ENCODE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INIT_ENCODE_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Initiation of encoder instance. + *---------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_InitEncode( /* (o) Number of bytes encoded */ + iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) Encoder instance */ + WebRtc_Word16 mode /* (i) frame size mode */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/interpolate.c b/src/libs/webrtc/ilbcfix/interpolate.c new file mode 100644 index 00000000..11cb33c7 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/interpolate.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Interpolate.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * interpolation between vectors + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Interpolate( + WebRtc_Word16 *out, /* (o) output vector */ + WebRtc_Word16 *in1, /* (i) first input vector */ + WebRtc_Word16 *in2, /* (i) second input vector */ + WebRtc_Word16 coef, /* (i) weight coefficient in Q14 */ + WebRtc_Word16 length) /* (i) number of sample is vectors */ +{ + int i; + WebRtc_Word16 invcoef; + + /* + Performs the operation out[i] = in[i]*coef + (1-coef)*in2[i] (with rounding) + */ + + invcoef = 16384 - coef; /* 16384 = 1.0 (Q14)*/ + for (i = 0; i < length; i++) { + out[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32( + (WEBRTC_SPL_MUL_16_16(coef, in1[i]) + WEBRTC_SPL_MUL_16_16(invcoef, in2[i]))+8192, + 14); + } + + return; +} diff --git a/src/libs/webrtc/ilbcfix/interpolate.h b/src/libs/webrtc/ilbcfix/interpolate.h new file mode 100644 index 00000000..a12021c7 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/interpolate.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Interpolate.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INTERPOLATE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INTERPOLATE_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * interpolation between vectors + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Interpolate( + WebRtc_Word16 *out, /* (o) output vector */ + WebRtc_Word16 *in1, /* (i) first input vector */ + WebRtc_Word16 *in2, /* (i) second input vector */ + WebRtc_Word16 coef, /* (i) weight coefficient in Q14 */ + WebRtc_Word16 length); /* (i) number of sample is vectors */ + +#endif diff --git a/src/libs/webrtc/ilbcfix/interpolate_samples.c b/src/libs/webrtc/ilbcfix/interpolate_samples.c new file mode 100644 index 00000000..31eb52e3 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/interpolate_samples.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_InterpolateSamples.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +void WebRtcIlbcfix_InterpolateSamples( + WebRtc_Word16 *interpSamples, /* (o) The interpolated samples */ + WebRtc_Word16 *CBmem, /* (i) The CB memory */ + WebRtc_Word16 lMem /* (i) Length of the CB memory */ + ) { + WebRtc_Word16 *ppi, *ppo, i, j, temp1, temp2; + WebRtc_Word16 *tmpPtr; + + /* Calculate the 20 vectors of interpolated samples (4 samples each) + that are used in the codebooks for lag 20 to 39 */ + tmpPtr = interpSamples; + for (j=0; j<20; j++) { + temp1 = 0; + temp2 = 3; + ppo = CBmem+lMem-4; + ppi = CBmem+lMem-j-24; + for (i=0; i<4; i++) { + + *tmpPtr++ = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIlbcfix_kAlpha[temp2],*ppo, 15) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIlbcfix_kAlpha[temp1], *ppi, 15); + + ppo++; + ppi++; + temp1++; + temp2--; + } + } + + return; +} diff --git a/src/libs/webrtc/ilbcfix/interpolate_samples.h b/src/libs/webrtc/ilbcfix/interpolate_samples.h new file mode 100644 index 00000000..5c98aafa --- /dev/null +++ b/src/libs/webrtc/ilbcfix/interpolate_samples.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_InterpolateSamples.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INTERPOLATE_SAMPLES_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INTERPOLATE_SAMPLES_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Construct the interpolated samples for the Augmented CB + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_InterpolateSamples( + WebRtc_Word16 *interpSamples, /* (o) The interpolated samples */ + WebRtc_Word16 *CBmem, /* (i) The CB memory */ + WebRtc_Word16 lMem /* (i) Length of the CB memory */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/lpc_encode.c b/src/libs/webrtc/ilbcfix/lpc_encode.c new file mode 100644 index 00000000..73d67a04 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lpc_encode.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_LpcEncode.c + +******************************************************************/ + +#include "defines.h" +#include "simple_lpc_analysis.h" +#include "simple_interpolate_lsf.h" +#include "simple_lsf_quant.h" +#include "lsf_check.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * lpc encoder + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_LpcEncode( + WebRtc_Word16 *syntdenum, /* (i/o) synthesis filter coefficients + before/after encoding */ + WebRtc_Word16 *weightdenum, /* (i/o) weighting denumerator coefficients + before/after encoding */ + WebRtc_Word16 *lsf_index, /* (o) lsf quantization index */ + WebRtc_Word16 *data, /* (i) Speech to do LPC analysis on */ + iLBC_Enc_Inst_t *iLBCenc_inst + /* (i/o) the encoder state structure */ + ) { + /* Stack based */ + WebRtc_Word16 lsf[LPC_FILTERORDER * LPC_N_MAX]; + WebRtc_Word16 lsfdeq[LPC_FILTERORDER * LPC_N_MAX]; + + /* Calculate LSF's from the input speech */ + WebRtcIlbcfix_SimpleLpcAnalysis(lsf, data, iLBCenc_inst); + + /* Quantize the LSF's */ + WebRtcIlbcfix_SimpleLsfQ(lsfdeq, lsf_index, lsf, iLBCenc_inst->lpc_n); + + /* Stableize the LSF's if needed */ + WebRtcIlbcfix_LsfCheck(lsfdeq, LPC_FILTERORDER, iLBCenc_inst->lpc_n); + + /* Calculate the synthesis and weighting filter coefficients from + the optimal LSF and the dequantized LSF */ + WebRtcIlbcfix_SimpleInterpolateLsf(syntdenum, weightdenum, + lsf, lsfdeq, iLBCenc_inst->lsfold, + iLBCenc_inst->lsfdeqold, LPC_FILTERORDER, iLBCenc_inst); + + return; +} diff --git a/src/libs/webrtc/ilbcfix/lpc_encode.h b/src/libs/webrtc/ilbcfix/lpc_encode.h new file mode 100644 index 00000000..36967a30 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lpc_encode.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_LpcEncode.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LPC_ENCODE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LPC_ENCODE_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * lpc encoder + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_LpcEncode( + WebRtc_Word16 *syntdenum, /* (i/o) synthesis filter coefficients + before/after encoding */ + WebRtc_Word16 *weightdenum, /* (i/o) weighting denumerator coefficients + before/after encoding */ + WebRtc_Word16 *lsf_index, /* (o) lsf quantization index */ + WebRtc_Word16 *data, /* (i) Speech to do LPC analysis on */ + iLBC_Enc_Inst_t *iLBCenc_inst + /* (i/o) the encoder state structure */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/lsf_check.c b/src/libs/webrtc/ilbcfix/lsf_check.c new file mode 100644 index 00000000..7097d748 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lsf_check.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_LsfCheck.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * check for stability of lsf coefficients + *---------------------------------------------------------------*/ + +int WebRtcIlbcfix_LsfCheck( + WebRtc_Word16 *lsf, /* LSF parameters */ + int dim, /* dimension of LSF */ + int NoAn) /* No of analysis per frame */ +{ + int k,n,m, Nit=2, change=0,pos; + const WebRtc_Word16 eps=319; /* 0.039 in Q13 (50 Hz)*/ + const WebRtc_Word16 eps2=160; /* eps/2.0 in Q13;*/ + const WebRtc_Word16 maxlsf=25723; /* 3.14; (4000 Hz)*/ + const WebRtc_Word16 minlsf=82; /* 0.01; (0 Hz)*/ + + /* LSF separation check*/ + for (n=0;n<Nit;n++) { /* Run through a 2 times */ + for (m=0;m<NoAn;m++) { /* Number of analyses per frame */ + for (k=0;k<(dim-1);k++) { + pos=m*dim+k; + + /* Seperate coefficients with a safety margin of 50 Hz */ + if ((lsf[pos+1]-lsf[pos])<eps) { + + if (lsf[pos+1]<lsf[pos]) { + lsf[pos+1]= lsf[pos]+eps2; + lsf[pos]= lsf[pos+1]-eps2; + } else { + lsf[pos]-=eps2; + lsf[pos+1]+=eps2; + } + change=1; + } + + /* Limit minimum and maximum LSF */ + if (lsf[pos]<minlsf) { + lsf[pos]=minlsf; + change=1; + } + + if (lsf[pos]>maxlsf) { + lsf[pos]=maxlsf; + change=1; + } + } + } + } + + return change; +} diff --git a/src/libs/webrtc/ilbcfix/lsf_check.h b/src/libs/webrtc/ilbcfix/lsf_check.h new file mode 100644 index 00000000..830bbed6 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lsf_check.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_LsfCheck.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LSF_CHECK_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LSF_CHECK_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * check for stability of lsf coefficients + *---------------------------------------------------------------*/ + +int WebRtcIlbcfix_LsfCheck( + WebRtc_Word16 *lsf, /* LSF parameters */ + int dim, /* dimension of LSF */ + int NoAn); /* No of analysis per frame */ + +#endif diff --git a/src/libs/webrtc/ilbcfix/lsf_interpolate_to_poly_dec.c b/src/libs/webrtc/ilbcfix/lsf_interpolate_to_poly_dec.c new file mode 100644 index 00000000..3bb23d00 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lsf_interpolate_to_poly_dec.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_LspInterpolate2PolyDec.c + +******************************************************************/ + +#include "interpolate.h" +#include "lsf_to_poly.h" +#include "defines.h" + +/*----------------------------------------------------------------* + * interpolation of lsf coefficients for the decoder + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_LspInterpolate2PolyDec( + WebRtc_Word16 *a, /* (o) lpc coefficients Q12 */ + WebRtc_Word16 *lsf1, /* (i) first set of lsf coefficients Q13 */ + WebRtc_Word16 *lsf2, /* (i) second set of lsf coefficients Q13 */ + WebRtc_Word16 coef, /* (i) weighting coefficient to use between + lsf1 and lsf2 Q14 */ + WebRtc_Word16 length /* (i) length of coefficient vectors */ + ){ + WebRtc_Word16 lsftmp[LPC_FILTERORDER]; + + /* interpolate LSF */ + WebRtcIlbcfix_Interpolate(lsftmp, lsf1, lsf2, coef, length); + + /* Compute the filter coefficients from the LSF */ + WebRtcIlbcfix_Lsf2Poly(a, lsftmp); +} diff --git a/src/libs/webrtc/ilbcfix/lsf_interpolate_to_poly_dec.h b/src/libs/webrtc/ilbcfix/lsf_interpolate_to_poly_dec.h new file mode 100644 index 00000000..23fe3a72 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lsf_interpolate_to_poly_dec.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_LspInterpolate2PolyDec.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LSF_INTERPOLATE_TO_POLY_DEC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LSF_INTERPOLATE_TO_POLY_DEC_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * interpolation of lsf coefficients for the decoder + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_LspInterpolate2PolyDec( + WebRtc_Word16 *a, /* (o) lpc coefficients Q12 */ + WebRtc_Word16 *lsf1, /* (i) first set of lsf coefficients Q13 */ + WebRtc_Word16 *lsf2, /* (i) second set of lsf coefficients Q13 */ + WebRtc_Word16 coef, /* (i) weighting coefficient to use between + lsf1 and lsf2 Q14 */ + WebRtc_Word16 length /* (i) length of coefficient vectors */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/lsf_interpolate_to_poly_enc.c b/src/libs/webrtc/ilbcfix/lsf_interpolate_to_poly_enc.c new file mode 100644 index 00000000..dae5780e --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lsf_interpolate_to_poly_enc.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_LsfInterpolate2PloyEnc.c + +******************************************************************/ + +#include "defines.h" +#include "interpolate.h" +#include "lsf_to_poly.h" + +/*----------------------------------------------------------------* + * lsf interpolator and conversion from lsf to a coefficients + * (subrutine to SimpleInterpolateLSF) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_LsfInterpolate2PloyEnc( + iLBC_Enc_Inst_t *iLBCenc_inst, + /* (i) the encoder state structure */ + WebRtc_Word16 *a, /* (o) lpc coefficients Q12 */ + WebRtc_Word16 *lsf1, /* (i) first set of lsf coefficients Q13 */ + WebRtc_Word16 *lsf2, /* (i) second set of lsf coefficients Q13 */ + WebRtc_Word16 coef, /* (i) weighting coefficient to use between + lsf1 and lsf2 Q14 */ + WebRtc_Word16 length /* (i) length of coefficient vectors */ + ) { + /* Stack based */ + WebRtc_Word16 lsftmp[LPC_FILTERORDER]; + + /* Input parameter not used if not using scratch memory */ + iLBCenc_inst = iLBCenc_inst; + /* interpolate LSF */ + WebRtcIlbcfix_Interpolate(lsftmp, lsf1, lsf2, coef, length); + + /* Compute the filter coefficients from the LSF */ + WebRtcIlbcfix_Lsf2Poly(a, lsftmp); + + return; +} diff --git a/src/libs/webrtc/ilbcfix/lsf_interpolate_to_poly_enc.h b/src/libs/webrtc/ilbcfix/lsf_interpolate_to_poly_enc.h new file mode 100644 index 00000000..d83835d1 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lsf_interpolate_to_poly_enc.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_LsfInterpolate2PloyEnc.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LSF_INTERPOLATE_TO_POLY_ENC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LSF_INTERPOLATE_TO_POLY_ENC_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * lsf interpolator and conversion from lsf to a coefficients + * (subrutine to SimpleInterpolateLSF) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_LsfInterpolate2PloyEnc( + iLBC_Enc_Inst_t *iLBCenc_inst, + /* (i) the encoder state structure */ + WebRtc_Word16 *a, /* (o) lpc coefficients Q12 */ + WebRtc_Word16 *lsf1, /* (i) first set of lsf coefficients Q13 */ + WebRtc_Word16 *lsf2, /* (i) second set of lsf coefficients Q13 */ + WebRtc_Word16 coef, /* (i) weighting coefficient to use between + lsf1 and lsf2 Q14 */ + WebRtc_Word16 length /* (i) length of coefficient vectors */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/lsf_to_lsp.c b/src/libs/webrtc/ilbcfix/lsf_to_lsp.c new file mode 100644 index 00000000..84278a43 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lsf_to_lsp.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Lsf2Lsp.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * conversion from lsf to lsp coefficients + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Lsf2Lsp( + WebRtc_Word16 *lsf, /* (i) lsf in Q13 values between 0 and pi */ + WebRtc_Word16 *lsp, /* (o) lsp in Q15 values between -1 and 1 */ + WebRtc_Word16 m /* (i) number of coefficients */ + ) { + WebRtc_Word16 i, k; + WebRtc_Word16 diff; /* difference, which is used for the + linear approximation (Q8) */ + WebRtc_Word16 freq; /* normalized frequency in Q15 (0..1) */ + WebRtc_Word32 tmpW32; + + for(i=0; i<m; i++) + { + freq = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(lsf[i], 20861, 15); + /* 20861: 1.0/(2.0*PI) in Q17 */ + /* + Upper 8 bits give the index k and + Lower 8 bits give the difference, which needs + to be approximated linearly + */ + k = WEBRTC_SPL_RSHIFT_W16(freq, 8); + diff = (freq&0x00ff); + + /* Guard against getting outside table */ + + if (k>63) { + k = 63; + } + + /* Calculate linear approximation */ + tmpW32 = WEBRTC_SPL_MUL_16_16(WebRtcIlbcfix_kCosDerivative[k], diff); + lsp[i] = WebRtcIlbcfix_kCos[k]+(WebRtc_Word16)(WEBRTC_SPL_RSHIFT_W32(tmpW32, 12)); + } + + return; +} diff --git a/src/libs/webrtc/ilbcfix/lsf_to_lsp.h b/src/libs/webrtc/ilbcfix/lsf_to_lsp.h new file mode 100644 index 00000000..db6549be --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lsf_to_lsp.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Lsf2Lsp.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LSF_TO_LSP_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LSF_TO_LSP_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * conversion from lsf to lsp coefficients + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Lsf2Lsp( + WebRtc_Word16 *lsf, /* (i) lsf in Q13 values between 0 and pi */ + WebRtc_Word16 *lsp, /* (o) lsp in Q15 values between -1 and 1 */ + WebRtc_Word16 m /* (i) number of coefficients */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/lsf_to_poly.c b/src/libs/webrtc/ilbcfix/lsf_to_poly.c new file mode 100644 index 00000000..f1c4a9ee --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lsf_to_poly.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Lsf2Poly.c + +******************************************************************/ + +#include "defines.h" +#include "lsf_to_lsp.h" +#include "get_lsp_poly.h" +#include "constants.h" + +void WebRtcIlbcfix_Lsf2Poly( + WebRtc_Word16 *a, /* (o) predictor coefficients (order = 10) in Q12 */ + WebRtc_Word16 *lsf /* (i) line spectral frequencies in Q13 */ + ) { + WebRtc_Word32 f[2][6]; /* f[0][] and f[1][] corresponds to + F1(z) and F2(z) respectivly */ + WebRtc_Word32 *f1ptr, *f2ptr; + WebRtc_Word16 *a1ptr, *a2ptr; + WebRtc_Word32 tmpW32; + WebRtc_Word16 lsp[10]; + int i; + + /* Convert lsf to lsp */ + WebRtcIlbcfix_Lsf2Lsp(lsf, lsp, LPC_FILTERORDER); + + /* Get F1(z) and F2(z) from the lsp */ + f1ptr=f[0]; + f2ptr=f[1]; + WebRtcIlbcfix_GetLspPoly(&lsp[0],f1ptr); + WebRtcIlbcfix_GetLspPoly(&lsp[1],f2ptr); + + /* for i = 5 down to 1 + Compute f1[i] += f1[i-1]; + and f2[i] += f2[i-1]; + */ + f1ptr=&f[0][5]; + f2ptr=&f[1][5]; + for (i=5; i>0; i--) + { + (*f1ptr) += (*(f1ptr-1)); + (*f2ptr) -= (*(f2ptr-1)); + f1ptr--; + f2ptr--; + } + + /* Get the A(z) coefficients + a[0] = 1.0 + for i = 1 to 5 + a[i] = (f1[i] + f2[i] + round)>>13; + for i = 1 to 5 + a[11-i] = (f1[i] - f2[i] + round)>>13; + */ + a[0]=4096; + a1ptr=&a[1]; + a2ptr=&a[10]; + f1ptr=&f[0][1]; + f2ptr=&f[1][1]; + for (i=5; i>0; i--) + { + tmpW32 = (*f1ptr) + (*f2ptr); + (*a1ptr) = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32+4096),13); + + tmpW32 = (*f1ptr) - (*f2ptr); + (*a2ptr) = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32+4096),13); + + a1ptr++; + a2ptr--; + f1ptr++; + f2ptr++; + } + + return; +} diff --git a/src/libs/webrtc/ilbcfix/lsf_to_poly.h b/src/libs/webrtc/ilbcfix/lsf_to_poly.h new file mode 100644 index 00000000..a00693b5 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lsf_to_poly.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Lsf2Poly.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LSF_TO_POLY_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LSF_TO_POLY_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Convert from LSF coefficients to A coefficients + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Lsf2Poly( + WebRtc_Word16 *a, /* (o) predictor coefficients (order = 10) in Q12 */ + WebRtc_Word16 *lsf /* (i) line spectral frequencies in Q13 */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/lsp_to_lsf.c b/src/libs/webrtc/ilbcfix/lsp_to_lsf.c new file mode 100644 index 00000000..134afbb5 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lsp_to_lsf.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Lsp2Lsf.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * conversion from LSP coefficients to LSF coefficients + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Lsp2Lsf( + WebRtc_Word16 *lsp, /* (i) lsp vector -1...+1 in Q15 */ + WebRtc_Word16 *lsf, /* (o) Lsf vector 0...Pi in Q13 + (ordered, so that lsf[i]<lsf[i+1]) */ + WebRtc_Word16 m /* (i) Number of coefficients */ + ) +{ + WebRtc_Word16 i, k; + WebRtc_Word16 diff; /* diff between table value and desired value (Q15) */ + WebRtc_Word16 freq; /* lsf/(2*pi) (Q16) */ + WebRtc_Word16 *lspPtr, *lsfPtr, *cosTblPtr; + WebRtc_Word16 tmp; + + /* set the index to maximum index value in WebRtcIlbcfix_kCos */ + k = 63; + + /* + Start with the highest LSP and then work the way down + For each LSP the lsf is calculated by first order approximation + of the acos(x) function + */ + lspPtr = &lsp[9]; + lsfPtr = &lsf[9]; + cosTblPtr=(WebRtc_Word16*)&WebRtcIlbcfix_kCos[k]; + for(i=m-1; i>=0; i--) + { + /* + locate value in the table, which is just above lsp[i], + basically an approximation to acos(x) + */ + while( (((WebRtc_Word32)(*cosTblPtr)-(*lspPtr)) < 0)&&(k>0) ) + { + k-=1; + cosTblPtr--; + } + + /* Calculate diff, which is used in the linear approximation of acos(x) */ + diff = (*lspPtr)-(*cosTblPtr); + + /* + The linear approximation of acos(lsp[i]) : + acos(lsp[i])= k*512 + (WebRtcIlbcfix_kAcosDerivative[ind]*offset >> 11) + */ + + /* tmp (linear offset) in Q16 */ + tmp = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIlbcfix_kAcosDerivative[k],diff, 11); + + /* freq in Q16 */ + freq = (WebRtc_Word16)WEBRTC_SPL_LSHIFT_W16(k,9)+tmp; + + /* lsf = freq*2*pi */ + (*lsfPtr) = (WebRtc_Word16)(((WebRtc_Word32)freq*25736)>>15); + + lsfPtr--; + lspPtr--; + } + + return; +} diff --git a/src/libs/webrtc/ilbcfix/lsp_to_lsf.h b/src/libs/webrtc/ilbcfix/lsp_to_lsf.h new file mode 100644 index 00000000..97ba7e4b --- /dev/null +++ b/src/libs/webrtc/ilbcfix/lsp_to_lsf.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Lsp2Lsf.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LSP_TO_LSF_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_LSP_TO_LSF_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * conversion from LSP coefficients to LSF coefficients + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Lsp2Lsf( + WebRtc_Word16 *lsp, /* (i) lsp vector -1...+1 in Q15 */ + WebRtc_Word16 *lsf, /* (o) Lsf vector 0...Pi in Q13 + (ordered, so that lsf[i]<lsf[i+1]) */ + WebRtc_Word16 m /* (i) Number of coefficients */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/my_corr.c b/src/libs/webrtc/ilbcfix/my_corr.c new file mode 100644 index 00000000..21622059 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/my_corr.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_MyCorr.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * compute cross correlation between sequences + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_MyCorr( + WebRtc_Word32 *corr, /* (o) correlation of seq1 and seq2 */ + WebRtc_Word16 *seq1, /* (i) first sequence */ + WebRtc_Word16 dim1, /* (i) dimension first seq1 */ + const WebRtc_Word16 *seq2, /* (i) second sequence */ + WebRtc_Word16 dim2 /* (i) dimension seq2 */ + ){ + WebRtc_Word16 max, scale, loops; + + /* Calculate correlation between the two sequences. Scale the + result of the multiplcication to maximum 26 bits in order + to avoid overflow */ + max=WebRtcSpl_MaxAbsValueW16(seq1, dim1); + scale=WebRtcSpl_GetSizeInBits(max); + + scale = (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16(2,scale)-26); + if (scale<0) { + scale=0; + } + + loops=dim1-dim2+1; + + /* Calculate the cross correlations */ + WebRtcSpl_CrossCorrelation(corr, (WebRtc_Word16*)seq2, seq1, dim2, loops, scale, 1); + + return; +} diff --git a/src/libs/webrtc/ilbcfix/my_corr.h b/src/libs/webrtc/ilbcfix/my_corr.h new file mode 100644 index 00000000..f588c530 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/my_corr.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_MyCorr.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_MY_CORR_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_MY_CORR_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * compute cross correlation between sequences + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_MyCorr( + WebRtc_Word32 *corr, /* (o) correlation of seq1 and seq2 */ + WebRtc_Word16 *seq1, /* (i) first sequence */ + WebRtc_Word16 dim1, /* (i) dimension first seq1 */ + const WebRtc_Word16 *seq2, /* (i) second sequence */ + WebRtc_Word16 dim2 /* (i) dimension seq2 */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/nearest_neighbor.c b/src/libs/webrtc/ilbcfix/nearest_neighbor.c new file mode 100644 index 00000000..ed79c8ff --- /dev/null +++ b/src/libs/webrtc/ilbcfix/nearest_neighbor.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_NearestNeighbor.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Find index in array such that the array element with said + * index is the element of said array closest to "value" + * according to the squared-error criterion + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_NearestNeighbor( + iLBC_Dec_Inst_t *iLBCdec_inst, + /* (i) Decoder state */ + WebRtc_Word16 *index, /* (o) index of array element closest to value */ + WebRtc_Word16 *array, /* (i) data array (Q2) */ + WebRtc_Word16 value, /* (i) value (Q2) */ + WebRtc_Word16 arlength /* (i) dimension of data array (==8) */ + ){ + int i; + WebRtc_Word16 diff; + /* Stack based */ + WebRtc_Word32 crit[8]; + /* The input variable iLBCdec_inst is unused if not using scratch memory */ + iLBCdec_inst = iLBCdec_inst; + + /* Calculate square distance */ + for(i=0;i<arlength;i++){ + diff=array[i]-value; + crit[i]=WEBRTC_SPL_MUL_16_16(diff, diff); + } + + /* Find the minimum square distance */ + *index=WebRtcSpl_MinIndexW32(crit, (WebRtc_Word16)arlength); +} diff --git a/src/libs/webrtc/ilbcfix/nearest_neighbor.h b/src/libs/webrtc/ilbcfix/nearest_neighbor.h new file mode 100644 index 00000000..864c80e5 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/nearest_neighbor.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_NearestNeighbor.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_NEAREST_NEIGHBOR_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_NEAREST_NEIGHBOR_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Find index in array such that the array element with said + * index is the element of said array closest to "value" + * according to the squared-error criterion + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_NearestNeighbor( + iLBC_Dec_Inst_t *iLBCdec_inst, + /* (i) Decoder state */ + WebRtc_Word16 *index, /* (o) index of array element closest to value */ + WebRtc_Word16 *array, /* (i) data array (Q2) */ + WebRtc_Word16 value, /* (i) value (Q2) */ + WebRtc_Word16 arlength /* (i) dimension of data array (==8) */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/pack_bits.c b/src/libs/webrtc/ilbcfix/pack_bits.c new file mode 100644 index 00000000..3990fbeb --- /dev/null +++ b/src/libs/webrtc/ilbcfix/pack_bits.c @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_PackBits.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * unpacking of bits from bitstream, i.e., vector of bytes + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_PackBits( + WebRtc_UWord16 *bitstream, /* (o) The packetized bitstream */ + iLBC_bits *enc_bits, /* (i) Encoded bits */ + WebRtc_Word16 mode /* (i) Codec mode (20 or 30) */ + ){ + WebRtc_UWord16 *bitstreamPtr; + int i, k; + WebRtc_Word16 *tmpPtr; + + bitstreamPtr=bitstream; + + /* Class 1 bits of ULP */ + /* First WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)enc_bits->lsf[0])<<10; /* Bit 0..5 */ + (*bitstreamPtr) |= (enc_bits->lsf[1])<<3; /* Bit 6..12 */ + (*bitstreamPtr) |= (enc_bits->lsf[2]&0x70)>>4; /* Bit 13..15 */ + bitstreamPtr++; + /* Second WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)enc_bits->lsf[2]&0xF)<<12; /* Bit 0..3 */ + + if (mode==20) { + (*bitstreamPtr) |= (enc_bits->startIdx)<<10; /* Bit 4..5 */ + (*bitstreamPtr) |= (enc_bits->state_first)<<9; /* Bit 6 */ + (*bitstreamPtr) |= (enc_bits->idxForMax)<<3; /* Bit 7..12 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[0])&0x70)>>4; /* Bit 13..15 */ + bitstreamPtr++; + /* Third WebRtc_Word16 */ + (*bitstreamPtr) = ((enc_bits->cb_index[0])&0xE)<<12; /* Bit 0..2 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[0])&0x18)<<8; /* Bit 3..4 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[1])&0x8)<<7; /* Bit 5 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[3])&0xFE)<<2; /* Bit 6..12 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[3])&0x10)>>2; /* Bit 13 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[4])&0x8)>>2; /* Bit 14 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[6])&0x10)>>4; /* Bit 15 */ + } else { /* mode==30 */ + (*bitstreamPtr) |= (enc_bits->lsf[3])<<6; /* Bit 4..9 */ + (*bitstreamPtr) |= (enc_bits->lsf[4]&0x7E)>>1; /* Bit 10..15 */ + bitstreamPtr++; + /* Third WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)enc_bits->lsf[4]&0x1)<<15; /* Bit 0 */ + (*bitstreamPtr) |= (enc_bits->lsf[5])<<8; /* Bit 1..7 */ + (*bitstreamPtr) |= (enc_bits->startIdx)<<5; /* Bit 8..10 */ + (*bitstreamPtr) |= (enc_bits->state_first)<<4; /* Bit 11 */ + (*bitstreamPtr) |= ((enc_bits->idxForMax)&0x3C)>>2; /* Bit 12..15 */ + bitstreamPtr++; + /* 4:th WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)enc_bits->idxForMax&0x3)<<14; /* Bit 0..1 */ + (*bitstreamPtr) |= (enc_bits->cb_index[0]&0x78)<<7; /* Bit 2..5 */ + (*bitstreamPtr) |= (enc_bits->gain_index[0]&0x10)<<5; /* Bit 6 */ + (*bitstreamPtr) |= (enc_bits->gain_index[1]&0x8)<<5; /* Bit 7 */ + (*bitstreamPtr) |= (enc_bits->cb_index[3]&0xFC); /* Bit 8..13 */ + (*bitstreamPtr) |= (enc_bits->gain_index[3]&0x10)>>3; /* Bit 14 */ + (*bitstreamPtr) |= (enc_bits->gain_index[4]&0x8)>>3; /* Bit 15 */ + } + /* Class 2 bits of ULP */ + /* 4:th to 6:th WebRtc_Word16 for 20 ms case + 5:th to 7:th WebRtc_Word16 for 30 ms case */ + bitstreamPtr++; + tmpPtr=enc_bits->idxVec; + for (k=0; k<3; k++) { + (*bitstreamPtr) = 0; + for (i=15; i>=0; i--) { + (*bitstreamPtr) |= ((WebRtc_UWord16)((*tmpPtr)&0x4)>>2)<<i; + /* Bit 15-i */ + tmpPtr++; + } + bitstreamPtr++; + } + + if (mode==20) { + /* 7:th WebRtc_Word16 */ + (*bitstreamPtr) = 0; + for (i=15; i>6; i--) { + (*bitstreamPtr) |= ((WebRtc_UWord16)((*tmpPtr)&0x4)>>2)<<i; + /* Bit 15-i */ + tmpPtr++; + } + (*bitstreamPtr) |= (enc_bits->gain_index[1]&0x4)<<4; /* Bit 9 */ + (*bitstreamPtr) |= (enc_bits->gain_index[3]&0xC)<<2; /* Bit 10..11 */ + (*bitstreamPtr) |= (enc_bits->gain_index[4]&0x4)<<1; /* Bit 12 */ + (*bitstreamPtr) |= (enc_bits->gain_index[6]&0x8)>>1; /* Bit 13 */ + (*bitstreamPtr) |= (enc_bits->gain_index[7]&0xC)>>2; /* Bit 14..15 */ + + } else { /* mode==30 */ + /* 8:th WebRtc_Word16 */ + (*bitstreamPtr) = 0; + for (i=15; i>5; i--) { + (*bitstreamPtr) |= ((WebRtc_UWord16)((*tmpPtr)&0x4)>>2)<<i; + /* Bit 15-i */ + tmpPtr++; + } + (*bitstreamPtr) |= (enc_bits->cb_index[0]&0x6)<<3; /* Bit 10..11 */ + (*bitstreamPtr) |= (enc_bits->gain_index[0]&0x8); /* Bit 12 */ + (*bitstreamPtr) |= (enc_bits->gain_index[1]&0x4); /* Bit 13 */ + (*bitstreamPtr) |= (enc_bits->cb_index[3]&0x2); /* Bit 14 */ + (*bitstreamPtr) |= (enc_bits->cb_index[6]&0x80)>>7; /* Bit 15 */ + bitstreamPtr++; + /* 9:th WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)enc_bits->cb_index[6]&0x7E)<<9;/* Bit 0..5 */ + (*bitstreamPtr) |= (enc_bits->cb_index[9]&0xFE)<<2; /* Bit 6..12 */ + (*bitstreamPtr) |= (enc_bits->cb_index[12]&0xE0)>>5; /* Bit 13..15 */ + bitstreamPtr++; + /* 10:th WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)enc_bits->cb_index[12]&0x1E)<<11;/* Bit 0..3 */ + (*bitstreamPtr) |= (enc_bits->gain_index[3]&0xC)<<8; /* Bit 4..5 */ + (*bitstreamPtr) |= (enc_bits->gain_index[4]&0x6)<<7; /* Bit 6..7 */ + (*bitstreamPtr) |= (enc_bits->gain_index[6]&0x18)<<3; /* Bit 8..9 */ + (*bitstreamPtr) |= (enc_bits->gain_index[7]&0xC)<<2; /* Bit 10..11 */ + (*bitstreamPtr) |= (enc_bits->gain_index[9]&0x10)>>1; /* Bit 12 */ + (*bitstreamPtr) |= (enc_bits->gain_index[10]&0x8)>>1; /* Bit 13 */ + (*bitstreamPtr) |= (enc_bits->gain_index[12]&0x10)>>3; /* Bit 14 */ + (*bitstreamPtr) |= (enc_bits->gain_index[13]&0x8)>>3; /* Bit 15 */ + } + bitstreamPtr++; + /* Class 3 bits of ULP */ + /* 8:th to 14:th WebRtc_Word16 for 20 ms case + 11:th to 17:th WebRtc_Word16 for 30 ms case */ + tmpPtr=enc_bits->idxVec; + for (k=0; k<7; k++) { + (*bitstreamPtr) = 0; + for (i=14; i>=0; i-=2) { + (*bitstreamPtr) |= ((WebRtc_UWord16)((*tmpPtr)&0x3))<<i; /* Bit 15-i..14-i*/ + tmpPtr++; + } + bitstreamPtr++; + } + + if (mode==20) { + /* 15:th WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)((enc_bits->idxVec[56])&0x3))<<14;/* Bit 0..1 */ + (*bitstreamPtr) |= (((enc_bits->cb_index[0])&1))<<13; /* Bit 2 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[1]))<<6; /* Bit 3..9 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[2])&0x7E)>>1; /* Bit 10..15 */ + bitstreamPtr++; + /* 16:th WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)((enc_bits->cb_index[2])&0x1))<<15; + /* Bit 0 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[0])&0x7)<<12; /* Bit 1..3 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[1])&0x3)<<10; /* Bit 4..5 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[2]))<<7; /* Bit 6..8 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[3])&0x1)<<6; /* Bit 9 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[4])&0x7E)>>1; /* Bit 10..15 */ + bitstreamPtr++; + /* 17:th WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)((enc_bits->cb_index[4])&0x1))<<15; + /* Bit 0 */ + (*bitstreamPtr) |= (enc_bits->cb_index[5])<<8; /* Bit 1..7 */ + (*bitstreamPtr) |= (enc_bits->cb_index[6]); /* Bit 8..15 */ + bitstreamPtr++; + /* 18:th WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)(enc_bits->cb_index[7]))<<8; /* Bit 0..7 */ + (*bitstreamPtr) |= (enc_bits->cb_index[8]); /* Bit 8..15 */ + bitstreamPtr++; + /* 19:th WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)((enc_bits->gain_index[3])&0x3))<<14; + /* Bit 0..1 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[4])&0x3)<<12; /* Bit 2..3 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[5]))<<9; /* Bit 4..6 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[6])&0x7)<<6; /* Bit 7..9 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[7])&0x3)<<4; /* Bit 10..11 */ + (*bitstreamPtr) |= (enc_bits->gain_index[8])<<1; /* Bit 12..14 */ + } else { /* mode==30 */ + /* 18:th WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)((enc_bits->idxVec[56])&0x3))<<14;/* Bit 0..1 */ + (*bitstreamPtr) |= (((enc_bits->idxVec[57])&0x3))<<12; /* Bit 2..3 */ + (*bitstreamPtr) |= (((enc_bits->cb_index[0])&1))<<11; /* Bit 4 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[1]))<<4; /* Bit 5..11 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[2])&0x78)>>3; /* Bit 12..15 */ + bitstreamPtr++; + /* 19:th WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)(enc_bits->cb_index[2])&0x7)<<13; + /* Bit 0..2 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[0])&0x7)<<10; /* Bit 3..5 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[1])&0x3)<<8; /* Bit 6..7 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[2])&0x7)<<5; /* Bit 8..10 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[3])&0x1)<<4; /* Bit 11 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[4])&0x78)>>3; /* Bit 12..15 */ + bitstreamPtr++; + /* 20:th WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)(enc_bits->cb_index[4])&0x7)<<13; + /* Bit 0..2 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[5]))<<6; /* Bit 3..9 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[6])&0x1)<<5; /* Bit 10 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[7])&0xF8)>>3; /* Bit 11..15 */ + bitstreamPtr++; + /* 21:st WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)(enc_bits->cb_index[7])&0x7)<<13; + /* Bit 0..2 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[8]))<<5; /* Bit 3..10 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[9])&0x1)<<4; /* Bit 11 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[10])&0xF0)>>4; /* Bit 12..15 */ + bitstreamPtr++; + /* 22:nd WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)(enc_bits->cb_index[10])&0xF)<<12; + /* Bit 0..3 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[11]))<<4; /* Bit 4..11 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[12])&0x1)<<3; /* Bit 12 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[13])&0xE0)>>5; /* Bit 13..15 */ + bitstreamPtr++; + /* 23:rd WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)(enc_bits->cb_index[13])&0x1F)<<11; + /* Bit 0..4 */ + (*bitstreamPtr) |= ((enc_bits->cb_index[14]))<<3; /* Bit 5..12 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[3])&0x3)<<1; /* Bit 13..14 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[4])&0x1); /* Bit 15 */ + bitstreamPtr++; + /* 24:rd WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)(enc_bits->gain_index[5]))<<13; + /* Bit 0..2 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[6])&0x7)<<10; /* Bit 3..5 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[7])&0x3)<<8; /* Bit 6..7 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[8]))<<5; /* Bit 8..10 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[9])&0xF)<<1; /* Bit 11..14 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[10])&0x4)>>2; /* Bit 15 */ + bitstreamPtr++; + /* 25:rd WebRtc_Word16 */ + (*bitstreamPtr) = ((WebRtc_UWord16)(enc_bits->gain_index[10])&0x3)<<14; + /* Bit 0..1 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[11]))<<11; /* Bit 2..4 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[12])&0xF)<<7; /* Bit 5..8 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[13])&0x7)<<4; /* Bit 9..11 */ + (*bitstreamPtr) |= ((enc_bits->gain_index[14]))<<1; /* Bit 12..14 */ + } + /* Last bit is automatically zero */ + + return; +} diff --git a/src/libs/webrtc/ilbcfix/pack_bits.h b/src/libs/webrtc/ilbcfix/pack_bits.h new file mode 100644 index 00000000..ed3f2246 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/pack_bits.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_PackBits.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_PACK_BITS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_PACK_BITS_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * unpacking of bits from bitstream, i.e., vector of bytes + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_PackBits( + WebRtc_UWord16 *bitstream, /* (o) The packetized bitstream */ + iLBC_bits *enc_bits, /* (i) Encoded bits */ + WebRtc_Word16 mode /* (i) Codec mode (20 or 30) */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/poly_to_lsf.c b/src/libs/webrtc/ilbcfix/poly_to_lsf.c new file mode 100644 index 00000000..fe91851b --- /dev/null +++ b/src/libs/webrtc/ilbcfix/poly_to_lsf.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Poly2Lsf.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "poly_to_lsp.h" +#include "lsp_to_lsf.h" + +void WebRtcIlbcfix_Poly2Lsf( + WebRtc_Word16 *lsf, /* (o) lsf coefficients (Q13) */ + WebRtc_Word16 *a /* (i) A coefficients (Q12) */ + ) { + WebRtc_Word16 lsp[10]; + WebRtcIlbcfix_Poly2Lsp(a, lsp, (WebRtc_Word16*)WebRtcIlbcfix_kLspMean); + WebRtcIlbcfix_Lsp2Lsf(lsp, lsf, 10); +} diff --git a/src/libs/webrtc/ilbcfix/poly_to_lsf.h b/src/libs/webrtc/ilbcfix/poly_to_lsf.h new file mode 100644 index 00000000..0ea595ee --- /dev/null +++ b/src/libs/webrtc/ilbcfix/poly_to_lsf.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Poly2Lsf.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_POLY_TO_LSF_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_POLY_TO_LSF_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * conversion from lpc coefficients to lsf coefficients + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Poly2Lsf( + WebRtc_Word16 *lsf, /* (o) lsf coefficients (Q13) */ + WebRtc_Word16 *a /* (i) A coefficients (Q12) */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/poly_to_lsp.c b/src/libs/webrtc/ilbcfix/poly_to_lsp.c new file mode 100644 index 00000000..29b4213c --- /dev/null +++ b/src/libs/webrtc/ilbcfix/poly_to_lsp.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Poly2Lsp.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "chebyshev.h" + +/*----------------------------------------------------------------* + * conversion from lpc coefficients to lsp coefficients + * function is only for 10:th order LPC + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Poly2Lsp( + WebRtc_Word16 *a, /* (o) A coefficients in Q12 */ + WebRtc_Word16 *lsp, /* (i) LSP coefficients in Q15 */ + WebRtc_Word16 *old_lsp /* (i) old LSP coefficients that are used if the new + coefficients turn out to be unstable */ + ) { + WebRtc_Word16 f[2][6]; /* f[0][] represents f1 and f[1][] represents f2 */ + WebRtc_Word16 *a_i_ptr, *a_10mi_ptr; + WebRtc_Word16 *f1ptr, *f2ptr; + WebRtc_Word32 tmpW32; + WebRtc_Word16 x, y, xlow, ylow, xmid, ymid, xhigh, yhigh, xint; + WebRtc_Word16 shifts, sign; + int i, j; + int foundFreqs; + int fi_select; + + /* + Calculate the two polynomials f1(z) and f2(z) + (the sum and the diff polynomial) + f1[0] = f2[0] = 1.0; + f1[i+1] = a[i+1] + a[10-i] - f1[i]; + f2[i+1] = a[i+1] - a[10-i] - f1[i]; + */ + + a_i_ptr = a + 1; + a_10mi_ptr = a + 10; + f1ptr = f[0]; + f2ptr = f[1]; + (*f1ptr) = 1024; /* 1.0 in Q10 */ + (*f2ptr) = 1024; /* 1.0 in Q10 */ + for (i = 0; i < 5; i++) { + (*(f1ptr+1)) = (WebRtc_Word16)(WEBRTC_SPL_RSHIFT_W32(((WebRtc_Word32)(*a_i_ptr)+(*a_10mi_ptr)), 2) - (*f1ptr)); + (*(f2ptr+1)) = (WebRtc_Word16)(WEBRTC_SPL_RSHIFT_W32(((WebRtc_Word32)(*a_i_ptr)-(*a_10mi_ptr)), 2) + (*f2ptr)); + a_i_ptr++; + a_10mi_ptr--; + f1ptr++; + f2ptr++; + } + + /* + find the LSPs using the Chebychev pol. evaluation + */ + + fi_select = 0; /* selector between f1 and f2, start with f1 */ + + foundFreqs = 0; + + xlow = WebRtcIlbcfix_kCosGrid[0]; + ylow = WebRtcIlbcfix_Chebyshev(xlow, f[fi_select]); + + /* + Iterate until all the 10 LSP's have been found or + all the grid points have been tried. If the 10 LSP's can + not be found, set the LSP vector to previous LSP + */ + + for (j = 1; j < COS_GRID_POINTS && foundFreqs < 10; j++) { + xhigh = xlow; + yhigh = ylow; + xlow = WebRtcIlbcfix_kCosGrid[j]; + ylow = WebRtcIlbcfix_Chebyshev(xlow, f[fi_select]); + + if (WEBRTC_SPL_MUL_16_16(ylow, yhigh) <= 0) { + /* Run 4 times to reduce the interval */ + for (i = 0; i < 4; i++) { + /* xmid =(xlow + xhigh)/2 */ + xmid = WEBRTC_SPL_RSHIFT_W16(xlow, 1) + WEBRTC_SPL_RSHIFT_W16(xhigh, 1); + ymid = WebRtcIlbcfix_Chebyshev(xmid, f[fi_select]); + + if (WEBRTC_SPL_MUL_16_16(ylow, ymid) <= 0) { + yhigh = ymid; + xhigh = xmid; + } else { + ylow = ymid; + xlow = xmid; + } + } + + /* + Calculater xint by linear interpolation: + xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow); + */ + + x = xhigh - xlow; + y = yhigh - ylow; + + if (y == 0) { + xint = xlow; + } else { + sign = y; + y = WEBRTC_SPL_ABS_W16(y); + shifts = (WebRtc_Word16)WebRtcSpl_NormW32(y)-16; + y = WEBRTC_SPL_LSHIFT_W16(y, shifts); + y = (WebRtc_Word16)WebRtcSpl_DivW32W16(536838144, y); /* 1/(yhigh-ylow) */ + + tmpW32 = WEBRTC_SPL_MUL_16_16_RSFT(x, y, (19-shifts)); + + /* y=(xhigh-xlow)/(yhigh-ylow) */ + y = (WebRtc_Word16)(tmpW32&0xFFFF); + + if (sign < 0) { + y = -y; + } + /* tmpW32 = ylow*(xhigh-xlow)/(yhigh-ylow) */ + tmpW32 = WEBRTC_SPL_MUL_16_16_RSFT(ylow, y, 10); + xint = xlow-(WebRtc_Word16)(tmpW32&0xFFFF); + } + + /* Store the calculated lsp */ + lsp[foundFreqs] = (WebRtc_Word16)xint; + foundFreqs++; + + /* if needed, set xlow and ylow for next recursion */ + if (foundFreqs<10) { + xlow = xint; + /* Swap between f1 and f2 (f[0][] and f[1][]) */ + fi_select = ((fi_select+1)&0x1); + + ylow = WebRtcIlbcfix_Chebyshev(xlow, f[fi_select]); + } + } + } + + /* Check if M roots found, if not then use the old LSP */ + if (foundFreqs < 10) { + WEBRTC_SPL_MEMCPY_W16(lsp, old_lsp, 10); + } + return; +} diff --git a/src/libs/webrtc/ilbcfix/poly_to_lsp.h b/src/libs/webrtc/ilbcfix/poly_to_lsp.h new file mode 100644 index 00000000..7eebb25d --- /dev/null +++ b/src/libs/webrtc/ilbcfix/poly_to_lsp.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Poly2Lsp.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_POLY_TO_LSP_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_POLY_TO_LSP_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * conversion from lpc coefficients to lsp coefficients + * function is only for 10:th order LPC + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Poly2Lsp( + WebRtc_Word16 *a, /* (o) A coefficients in Q12 */ + WebRtc_Word16 *lsp, /* (i) LSP coefficients in Q15 */ + WebRtc_Word16 *old_lsp /* (i) old LSP coefficients that are used if the new + coefficients turn out to be unstable */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/refiner.c b/src/libs/webrtc/ilbcfix/refiner.c new file mode 100644 index 00000000..e57fa920 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/refiner.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Refiner.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "enh_upsample.h" +#include "my_corr.h" + +/*----------------------------------------------------------------* + * find segment starting near idata+estSegPos that has highest + * correlation with idata+centerStartPos through + * idata+centerStartPos+ENH_BLOCKL-1 segment is found at a + * resolution of ENH_UPSO times the original of the original + * sampling rate + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Refiner( + iLBC_Dec_Inst_t *iLBCdec_inst, + /* (i) Decoder state */ + WebRtc_Word16 *updStartPos, /* (o) updated start point (Q-2) */ + WebRtc_Word16 *idata, /* (i) original data buffer */ + WebRtc_Word16 idatal, /* (i) dimension of idata */ + WebRtc_Word16 centerStartPos, /* (i) beginning center segment */ + WebRtc_Word16 estSegPos, /* (i) estimated beginning other segment (Q-2) */ + WebRtc_Word16 *surround, /* (i/o) The contribution from this sequence + summed with earlier contributions */ + WebRtc_Word16 gain /* (i) Gain to use for this sequence */ + ){ + WebRtc_Word16 estSegPosRounded,searchSegStartPos,searchSegEndPos,corrdim; + WebRtc_Word16 tloc,tloc2,i,st,en,fraction; + + WebRtc_Word32 maxtemp, scalefact; + WebRtc_Word16 *filtStatePtr, *polyPtr; + /* Stack based */ + WebRtc_Word16 filt[7]; + WebRtc_Word32 corrVecUps[ENH_CORRDIM*ENH_UPS0]; + WebRtc_Word32 corrVecTemp[ENH_CORRDIM]; + WebRtc_Word16 vect[ENH_VECTL]; + WebRtc_Word16 corrVec[ENH_CORRDIM]; + + /* The input parameter iLBCdec_inst is unused unless using scratch memory */ + iLBCdec_inst = iLBCdec_inst; + + /* defining array bounds */ + + estSegPosRounded=WEBRTC_SPL_RSHIFT_W16((estSegPos - 2),2); + + searchSegStartPos=estSegPosRounded-ENH_SLOP; + + if (searchSegStartPos<0) { + searchSegStartPos=0; + } + searchSegEndPos=estSegPosRounded+ENH_SLOP; + + if(searchSegEndPos+ENH_BLOCKL >= idatal) { + searchSegEndPos=idatal-ENH_BLOCKL-1; + } + corrdim=searchSegEndPos-searchSegStartPos+1; + + /* compute upsampled correlation and find + location of max */ + + WebRtcIlbcfix_MyCorr(corrVecTemp,idata+searchSegStartPos, + (WebRtc_Word16)(corrdim+ENH_BLOCKL-1),idata+centerStartPos,ENH_BLOCKL); + + /* Calculate the rescaling factor for the correlation in order to + put the correlation in a WebRtc_Word16 vector instead */ + maxtemp=WebRtcSpl_MaxAbsValueW32(corrVecTemp, (WebRtc_Word16)corrdim); + + scalefact=WebRtcSpl_GetSizeInBits(maxtemp)-15; + + if (scalefact>0) { + for (i=0;i<corrdim;i++) { + corrVec[i]=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(corrVecTemp[i], scalefact); + } + } else { + for (i=0;i<corrdim;i++) { + corrVec[i]=(WebRtc_Word16)corrVecTemp[i]; + } + } + /* In order to guarantee that all values are initialized */ + for (i=corrdim;i<ENH_CORRDIM;i++) { + corrVec[i]=0; + } + + /* Upsample the correlation */ + WebRtcIlbcfix_EnhUpsample(corrVecUps,corrVec); + + /* Find maximum */ + tloc=WebRtcSpl_MaxIndexW32(corrVecUps, (WebRtc_Word16) (ENH_UPS0*corrdim)); + + /* make vector can be upsampled without ever running outside + bounds */ + *updStartPos = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(searchSegStartPos,4) + tloc + 4; + + tloc2 = WEBRTC_SPL_RSHIFT_W16((tloc+3), 2); + + st=searchSegStartPos+tloc2-ENH_FL0; + + /* initialize the vector to be filtered, stuff with zeros + when data is outside idata buffer */ + if(st<0){ + WebRtcSpl_MemSetW16(vect, 0, (WebRtc_Word16)(-st)); + WEBRTC_SPL_MEMCPY_W16(&vect[-st], idata, (ENH_VECTL+st)); + } + else{ + en=st+ENH_VECTL; + + if(en>idatal){ + WEBRTC_SPL_MEMCPY_W16(vect, &idata[st], + (ENH_VECTL-(en-idatal))); + WebRtcSpl_MemSetW16(&vect[ENH_VECTL-(en-idatal)], 0, + (WebRtc_Word16)(en-idatal)); + } + else { + WEBRTC_SPL_MEMCPY_W16(vect, &idata[st], ENH_VECTL); + } + } + /* Calculate which of the 4 fractions to use */ + fraction=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16(tloc2,ENH_UPS0)-tloc; + + /* compute the segment (this is actually a convolution) */ + + filtStatePtr = filt + 6; + polyPtr = (WebRtc_Word16*)WebRtcIlbcfix_kEnhPolyPhaser[fraction]; + for (i=0;i<7;i++) { + *filtStatePtr-- = *polyPtr++; + } + + WebRtcSpl_FilterMAFastQ12( + &vect[6], vect, filt, + ENH_FLO_MULT2_PLUS1, ENH_BLOCKL); + + /* Add the contribution from this vector (scaled with gain) to the total surround vector */ + WebRtcSpl_AddAffineVectorToVector( + surround, vect, gain, + (WebRtc_Word32)32768, 16, ENH_BLOCKL); + + return; +} diff --git a/src/libs/webrtc/ilbcfix/refiner.h b/src/libs/webrtc/ilbcfix/refiner.h new file mode 100644 index 00000000..02ad6321 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/refiner.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Refiner.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_REFINER_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_REFINER_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * find segment starting near idata+estSegPos that has highest + * correlation with idata+centerStartPos through + * idata+centerStartPos+ENH_BLOCKL-1 segment is found at a + * resolution of ENH_UPSO times the original of the original + * sampling rate + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Refiner( + iLBC_Dec_Inst_t *iLBCdec_inst, + /* (i) Decoder state */ + WebRtc_Word16 *updStartPos, /* (o) updated start point (Q-2) */ + WebRtc_Word16 *idata, /* (i) original data buffer */ + WebRtc_Word16 idatal, /* (i) dimension of idata */ + WebRtc_Word16 centerStartPos, /* (i) beginning center segment */ + WebRtc_Word16 estSegPos, /* (i) estimated beginning other segment (Q-2) */ + WebRtc_Word16 *surround, /* (i/o) The contribution from this sequence + summed with earlier contributions */ + WebRtc_Word16 gain /* (i) Gain to use for this sequence */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/simple_interpolate_lsf.c b/src/libs/webrtc/ilbcfix/simple_interpolate_lsf.c new file mode 100644 index 00000000..d094087e --- /dev/null +++ b/src/libs/webrtc/ilbcfix/simple_interpolate_lsf.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SimpleInterpolateLsf.c + +******************************************************************/ + +#include "defines.h" +#include "lsf_interpolate_to_poly_enc.h" +#include "bw_expand.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * lsf interpolator (subrutine to LPCencode) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SimpleInterpolateLsf( + WebRtc_Word16 *syntdenum, /* (o) the synthesis filter denominator + resulting from the quantized + interpolated lsf Q12 */ + WebRtc_Word16 *weightdenum, /* (o) the weighting filter denominator + resulting from the unquantized + interpolated lsf Q12 */ + WebRtc_Word16 *lsf, /* (i) the unquantized lsf coefficients Q13 */ + WebRtc_Word16 *lsfdeq, /* (i) the dequantized lsf coefficients Q13 */ + WebRtc_Word16 *lsfold, /* (i) the unquantized lsf coefficients of + the previous signal frame Q13 */ + WebRtc_Word16 *lsfdeqold, /* (i) the dequantized lsf coefficients of the + previous signal frame Q13 */ + WebRtc_Word16 length, /* (i) should equate FILTERORDER */ + iLBC_Enc_Inst_t *iLBCenc_inst + /* (i/o) the encoder state structure */ + ) { + int i, pos, lp_length; + + WebRtc_Word16 *lsf2, *lsfdeq2; + /* Stack based */ + WebRtc_Word16 lp[LPC_FILTERORDER + 1]; + + lsf2 = lsf + length; + lsfdeq2 = lsfdeq + length; + lp_length = length + 1; + + if (iLBCenc_inst->mode==30) { + /* subframe 1: Interpolation between old and first set of + lsf coefficients */ + + /* Calculate Analysis/Syntehsis filter from quantized LSF */ + WebRtcIlbcfix_LsfInterpolate2PloyEnc(iLBCenc_inst, lp, lsfdeqold, lsfdeq, + WebRtcIlbcfix_kLsfWeight30ms[0], length); + WEBRTC_SPL_MEMCPY_W16(syntdenum, lp, lp_length); + + /* Calculate Weighting filter from quantized LSF */ + WebRtcIlbcfix_LsfInterpolate2PloyEnc(iLBCenc_inst, lp, lsfold, lsf, WebRtcIlbcfix_kLsfWeight30ms[0], length); + WebRtcIlbcfix_BwExpand(weightdenum, lp, (WebRtc_Word16*)WebRtcIlbcfix_kLpcChirpWeightDenum, (WebRtc_Word16)lp_length); + + /* subframe 2 to 6: Interpolation between first and second + set of lsf coefficients */ + + pos = lp_length; + for (i = 1; i < iLBCenc_inst->nsub; i++) { + + /* Calculate Analysis/Syntehsis filter from quantized LSF */ + WebRtcIlbcfix_LsfInterpolate2PloyEnc(iLBCenc_inst, lp, lsfdeq, lsfdeq2, + WebRtcIlbcfix_kLsfWeight30ms[i], length); + WEBRTC_SPL_MEMCPY_W16(syntdenum + pos, lp, lp_length); + + /* Calculate Weighting filter from quantized LSF */ + WebRtcIlbcfix_LsfInterpolate2PloyEnc(iLBCenc_inst, lp, lsf, lsf2, + WebRtcIlbcfix_kLsfWeight30ms[i], length); + WebRtcIlbcfix_BwExpand(weightdenum + pos, lp, + (WebRtc_Word16*)WebRtcIlbcfix_kLpcChirpWeightDenum, (WebRtc_Word16)lp_length); + + pos += lp_length; + } + + /* update memory */ + + WEBRTC_SPL_MEMCPY_W16(lsfold, lsf2, length); + WEBRTC_SPL_MEMCPY_W16(lsfdeqold, lsfdeq2, length); + + } else { /* iLBCenc_inst->mode==20 */ + pos = 0; + for (i = 0; i < iLBCenc_inst->nsub; i++) { + + /* Calculate Analysis/Syntehsis filter from quantized LSF */ + WebRtcIlbcfix_LsfInterpolate2PloyEnc(iLBCenc_inst, lp, lsfdeqold, lsfdeq, + WebRtcIlbcfix_kLsfWeight20ms[i], length); + WEBRTC_SPL_MEMCPY_W16(syntdenum + pos, lp, lp_length); + + /* Calculate Weighting filter from quantized LSF */ + WebRtcIlbcfix_LsfInterpolate2PloyEnc(iLBCenc_inst, lp, lsfold, lsf, + WebRtcIlbcfix_kLsfWeight20ms[i], length); + WebRtcIlbcfix_BwExpand(weightdenum+pos, lp, + (WebRtc_Word16*)WebRtcIlbcfix_kLpcChirpWeightDenum, (WebRtc_Word16)lp_length); + + pos += lp_length; + } + + /* update memory */ + + WEBRTC_SPL_MEMCPY_W16(lsfold, lsf, length); + WEBRTC_SPL_MEMCPY_W16(lsfdeqold, lsfdeq, length); + + } + + return; +} diff --git a/src/libs/webrtc/ilbcfix/simple_interpolate_lsf.h b/src/libs/webrtc/ilbcfix/simple_interpolate_lsf.h new file mode 100644 index 00000000..8cdd7da5 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/simple_interpolate_lsf.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SimpleInterpolateLsf.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SIMPLE_INTERPOLATE_LSF_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SIMPLE_INTERPOLATE_LSF_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * lsf interpolator (subrutine to LPCencode) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SimpleInterpolateLsf( + WebRtc_Word16 *syntdenum, /* (o) the synthesis filter denominator + resulting from the quantized + interpolated lsf Q12 */ + WebRtc_Word16 *weightdenum, /* (o) the weighting filter denominator + resulting from the unquantized + interpolated lsf Q12 */ + WebRtc_Word16 *lsf, /* (i) the unquantized lsf coefficients Q13 */ + WebRtc_Word16 *lsfdeq, /* (i) the dequantized lsf coefficients Q13 */ + WebRtc_Word16 *lsfold, /* (i) the unquantized lsf coefficients of + the previous signal frame Q13 */ + WebRtc_Word16 *lsfdeqold, /* (i) the dequantized lsf coefficients of the + previous signal frame Q13 */ + WebRtc_Word16 length, /* (i) should equate FILTERORDER */ + iLBC_Enc_Inst_t *iLBCenc_inst + /* (i/o) the encoder state structure */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/simple_lpc_analysis.c b/src/libs/webrtc/ilbcfix/simple_lpc_analysis.c new file mode 100644 index 00000000..2d19eddf --- /dev/null +++ b/src/libs/webrtc/ilbcfix/simple_lpc_analysis.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SimpleLpcAnalysis.c + +******************************************************************/ + +#include "defines.h" +#include "window32_w32.h" +#include "bw_expand.h" +#include "poly_to_lsf.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * lpc analysis (subrutine to LPCencode) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SimpleLpcAnalysis( + WebRtc_Word16 *lsf, /* (o) lsf coefficients */ + WebRtc_Word16 *data, /* (i) new block of speech */ + iLBC_Enc_Inst_t *iLBCenc_inst + /* (i/o) the encoder state structure */ + ) { + int k; + int scale; + WebRtc_Word16 is; + WebRtc_Word16 stability; + /* Stack based */ + WebRtc_Word16 A[LPC_FILTERORDER + 1]; + WebRtc_Word32 R[LPC_FILTERORDER + 1]; + WebRtc_Word16 windowedData[BLOCKL_MAX]; + WebRtc_Word16 rc[LPC_FILTERORDER]; + + is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl; + WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->lpc_buffer+is,data,iLBCenc_inst->blockl); + + /* No lookahead, last window is asymmetric */ + + for (k = 0; k < iLBCenc_inst->lpc_n; k++) { + + is = LPC_LOOKBACK; + + if (k < (iLBCenc_inst->lpc_n - 1)) { + + /* Hanning table WebRtcIlbcfix_kLpcWin[] is in Q15-domain so the output is right-shifted 15 */ + WebRtcSpl_ElementwiseVectorMult(windowedData, iLBCenc_inst->lpc_buffer, WebRtcIlbcfix_kLpcWin, BLOCKL_MAX, 15); + } else { + + /* Hanning table WebRtcIlbcfix_kLpcAsymWin[] is in Q15-domain so the output is right-shifted 15 */ + WebRtcSpl_ElementwiseVectorMult(windowedData, iLBCenc_inst->lpc_buffer+is, WebRtcIlbcfix_kLpcAsymWin, BLOCKL_MAX, 15); + } + + /* Compute autocorrelation */ + WebRtcSpl_AutoCorrelation(windowedData, BLOCKL_MAX, LPC_FILTERORDER, R, &scale); + + /* Window autocorrelation vector */ + WebRtcIlbcfix_Window32W32(R, R, WebRtcIlbcfix_kLpcLagWin, LPC_FILTERORDER + 1 ); + + /* Calculate the A coefficients from the Autocorrelation using Levinson Durbin algorithm */ + stability=WebRtcSpl_LevinsonDurbin(R, A, rc, LPC_FILTERORDER); + + /* + Set the filter to {1.0, 0.0, 0.0,...} if filter from Levinson Durbin algorithm is unstable + This should basically never happen... + */ + if (stability!=1) { + A[0]=4096; + WebRtcSpl_MemSetW16(&A[1], 0, LPC_FILTERORDER); + } + + /* Bandwidth expand the filter coefficients */ + WebRtcIlbcfix_BwExpand(A, A, (WebRtc_Word16*)WebRtcIlbcfix_kLpcChirpSyntDenum, LPC_FILTERORDER+1); + + /* Convert from A to LSF representation */ + WebRtcIlbcfix_Poly2Lsf(lsf + k*LPC_FILTERORDER, A); + } + + is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl; + WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->lpc_buffer, + iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is, is); + + return; +} diff --git a/src/libs/webrtc/ilbcfix/simple_lpc_analysis.h b/src/libs/webrtc/ilbcfix/simple_lpc_analysis.h new file mode 100644 index 00000000..83c1e5b6 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/simple_lpc_analysis.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SimpleLpcAnalysis.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SIMPLE_LPC_ANALYSIS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SIMPLE_LPC_ANALYSIS_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * lpc analysis (subrutine to LPCencode) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SimpleLpcAnalysis( + WebRtc_Word16 *lsf, /* (o) lsf coefficients */ + WebRtc_Word16 *data, /* (i) new block of speech */ + iLBC_Enc_Inst_t *iLBCenc_inst + /* (i/o) the encoder state structure */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/simple_lsf_dequant.c b/src/libs/webrtc/ilbcfix/simple_lsf_dequant.c new file mode 100644 index 00000000..7b5efa07 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/simple_lsf_dequant.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SimpleLsfDeQ.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * obtain dequantized lsf coefficients from quantization index + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SimpleLsfDeQ( + WebRtc_Word16 *lsfdeq, /* (o) dequantized lsf coefficients */ + WebRtc_Word16 *index, /* (i) quantization index */ + WebRtc_Word16 lpc_n /* (i) number of LPCs */ + ){ + int i, j, pos, cb_pos; + + /* decode first LSF */ + + pos = 0; + cb_pos = 0; + for (i = 0; i < LSF_NSPLIT; i++) { + for (j = 0; j < WebRtcIlbcfix_kLsfDimCb[i]; j++) { + lsfdeq[pos + j] = WebRtcIlbcfix_kLsfCb[cb_pos + + WEBRTC_SPL_MUL_16_16(index[i], WebRtcIlbcfix_kLsfDimCb[i]) + j]; + } + pos += WebRtcIlbcfix_kLsfDimCb[i]; + cb_pos += WEBRTC_SPL_MUL_16_16(WebRtcIlbcfix_kLsfSizeCb[i], WebRtcIlbcfix_kLsfDimCb[i]); + } + + if (lpc_n>1) { + /* decode last LSF */ + pos = 0; + cb_pos = 0; + for (i = 0; i < LSF_NSPLIT; i++) { + for (j = 0; j < WebRtcIlbcfix_kLsfDimCb[i]; j++) { + lsfdeq[LPC_FILTERORDER + pos + j] = WebRtcIlbcfix_kLsfCb[cb_pos + + WEBRTC_SPL_MUL_16_16(index[LSF_NSPLIT + i], WebRtcIlbcfix_kLsfDimCb[i]) + j]; + } + pos += WebRtcIlbcfix_kLsfDimCb[i]; + cb_pos += WEBRTC_SPL_MUL_16_16(WebRtcIlbcfix_kLsfSizeCb[i], WebRtcIlbcfix_kLsfDimCb[i]); + } + } + return; +} diff --git a/src/libs/webrtc/ilbcfix/simple_lsf_dequant.h b/src/libs/webrtc/ilbcfix/simple_lsf_dequant.h new file mode 100644 index 00000000..efd31030 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/simple_lsf_dequant.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SimpleLsfDeQ.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SIMPLE_LSF_DEQUANT_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SIMPLE_LSF_DEQUANT_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * obtain dequantized lsf coefficients from quantization index + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SimpleLsfDeQ( + WebRtc_Word16 *lsfdeq, /* (o) dequantized lsf coefficients */ + WebRtc_Word16 *index, /* (i) quantization index */ + WebRtc_Word16 lpc_n /* (i) number of LPCs */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/simple_lsf_quant.c b/src/libs/webrtc/ilbcfix/simple_lsf_quant.c new file mode 100644 index 00000000..aa27fb4e --- /dev/null +++ b/src/libs/webrtc/ilbcfix/simple_lsf_quant.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SimpleLsfQ.c + +******************************************************************/ + +#include "defines.h" +#include "split_vq.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * lsf quantizer (subrutine to LPCencode) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SimpleLsfQ( + WebRtc_Word16 *lsfdeq, /* (o) dequantized lsf coefficients + (dimension FILTERORDER) Q13 */ + WebRtc_Word16 *index, /* (o) quantization index */ + WebRtc_Word16 *lsf, /* (i) the lsf coefficient vector to be + quantized (dimension FILTERORDER) Q13 */ + WebRtc_Word16 lpc_n /* (i) number of lsf sets to quantize */ + ){ + + /* Quantize first LSF with memoryless split VQ */ + WebRtcIlbcfix_SplitVq( lsfdeq, index, lsf, + (WebRtc_Word16*)WebRtcIlbcfix_kLsfCb, (WebRtc_Word16*)WebRtcIlbcfix_kLsfDimCb, (WebRtc_Word16*)WebRtcIlbcfix_kLsfSizeCb); + + if (lpc_n==2) { + /* Quantize second LSF with memoryless split VQ */ + WebRtcIlbcfix_SplitVq( lsfdeq + LPC_FILTERORDER, index + LSF_NSPLIT, + lsf + LPC_FILTERORDER, (WebRtc_Word16*)WebRtcIlbcfix_kLsfCb, + (WebRtc_Word16*)WebRtcIlbcfix_kLsfDimCb, (WebRtc_Word16*)WebRtcIlbcfix_kLsfSizeCb); + } + return; +} diff --git a/src/libs/webrtc/ilbcfix/simple_lsf_quant.h b/src/libs/webrtc/ilbcfix/simple_lsf_quant.h new file mode 100644 index 00000000..fd17b2ea --- /dev/null +++ b/src/libs/webrtc/ilbcfix/simple_lsf_quant.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SimpleLsfQ.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SIMPLE_LSF_QUANT_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SIMPLE_LSF_QUANT_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * lsf quantizer (subrutine to LPCencode) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SimpleLsfQ( + WebRtc_Word16 *lsfdeq, /* (o) dequantized lsf coefficients + (dimension FILTERORDER) Q13 */ + WebRtc_Word16 *index, /* (o) quantization index */ + WebRtc_Word16 *lsf, /* (i) the lsf coefficient vector to be + quantized (dimension FILTERORDER) Q13 */ + WebRtc_Word16 lpc_n /* (i) number of lsf sets to quantize */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/smooth.c b/src/libs/webrtc/ilbcfix/smooth.c new file mode 100644 index 00000000..207de6d5 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/smooth.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Smooth.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "smooth_out_data.h" + +/*----------------------------------------------------------------* + * find the smoothed output data + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Smooth( + WebRtc_Word16 *odata, /* (o) smoothed output */ + WebRtc_Word16 *current, /* (i) the un enhanced residual for + this block */ + WebRtc_Word16 *surround /* (i) The approximation from the + surrounding sequences */ + ) { + WebRtc_Word16 maxtot, scale, scale1, scale2; + WebRtc_Word16 A, B, C, denomW16; + WebRtc_Word32 B_W32, denom, num; + WebRtc_Word32 errs; + WebRtc_Word32 w00,w10,w11, endiff, crit; + WebRtc_Word32 w00prim, w10prim, w11_div_w00; + WebRtc_Word16 w11prim; + WebRtc_Word16 bitsw00, bitsw10, bitsw11; + WebRtc_Word32 w11w00, w10w10, w00w00; + WebRtc_Word16 max1, max2; + + /* compute some inner products (ensure no overflow by first calculating proper scale factor) */ + + w00 = w10 = w11 = 0; + current=current; + + max1=WebRtcSpl_MaxAbsValueW16(current, ENH_BLOCKL); + max2=WebRtcSpl_MaxAbsValueW16(surround, ENH_BLOCKL); + maxtot=WEBRTC_SPL_MAX(max1, max2); + + scale=WebRtcSpl_GetSizeInBits(maxtot); + scale = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(2,scale)-26; + scale=WEBRTC_SPL_MAX(0, scale); + + w00=WebRtcSpl_DotProductWithScale(current,current,ENH_BLOCKL,scale); + w11=WebRtcSpl_DotProductWithScale(surround,surround,ENH_BLOCKL,scale); + w10=WebRtcSpl_DotProductWithScale(surround,current,ENH_BLOCKL,scale); + + if (w00<0) w00 = WEBRTC_SPL_WORD32_MAX; + if (w11<0) w11 = WEBRTC_SPL_WORD32_MAX; + + /* Rescale w00 and w11 to w00prim and w11prim, so that w00prim/w11prim + is in Q16 */ + + bitsw00 = WebRtcSpl_GetSizeInBits(w00); + bitsw11 = WebRtcSpl_GetSizeInBits(w11); + bitsw10 = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_ABS_W32(w10)); + scale1 = 31 - bitsw00; + scale2 = 15 - bitsw11; + + if (scale2>(scale1-16)) { + scale2 = scale1 - 16; + } else { + scale1 = scale2 + 16; + } + + w00prim = WEBRTC_SPL_LSHIFT_W32(w00, scale1); + w11prim = (WebRtc_Word16) WEBRTC_SPL_SHIFT_W32(w11, scale2); + + /* Perform C = sqrt(w11/w00) (C is in Q11 since (16+6)/2=11) */ + if (w11prim>64) { + endiff = WEBRTC_SPL_LSHIFT_W32( + (WebRtc_Word32)WebRtcSpl_DivW32W16(w00prim, w11prim), 6); + C = (WebRtc_Word16)WebRtcSpl_Sqrt(endiff); /* C is in Q11 */ + } else { + C = 1; + } + + /* first try enhancement without power-constraint */ + + errs = WebRtcIlbcfix_Smooth_odata(odata, current, surround, C); + + + + /* if constraint violated by first try, add constraint */ + + if ( (6-scale+scale1) > 31) { + crit=0; + } else { + /* crit = 0.05 * w00 (Result in Q-6) */ + crit = WEBRTC_SPL_SHIFT_W32( + WEBRTC_SPL_MUL(ENH_A0, WEBRTC_SPL_RSHIFT_W32(w00prim, 14)), + -(6-scale+scale1)); + } + + if (errs > crit) { + + if( w00 < 1) { + w00=1; + } + + /* Calculate w11*w00, w10*w10 and w00*w00 in the same Q domain */ + + scale1 = bitsw00-15; + scale2 = bitsw11-15; + + if (scale2>scale1) { + scale = scale2; + } else { + scale = scale1; + } + + w11w00 = WEBRTC_SPL_MUL_16_16( + (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(w11, -scale), + (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(w00, -scale)); + + w10w10 = WEBRTC_SPL_MUL_16_16( + (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(w10, -scale), + (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(w10, -scale)); + + w00w00 = WEBRTC_SPL_MUL_16_16( + (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(w00, -scale), + (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(w00, -scale)); + + /* Calculate (w11*w00-w10*w10)/(w00*w00) in Q16 */ + if (w00w00>65536) { + endiff = (w11w00-w10w10); + endiff = WEBRTC_SPL_MAX(0, endiff); + /* denom is in Q16 */ + denom = WebRtcSpl_DivW32W16(endiff, (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(w00w00, 16)); + } else { + denom = 65536; + } + + if( denom > 7){ /* eliminates numerical problems + for if smooth */ + + scale=WebRtcSpl_GetSizeInBits(denom)-15; + + if (scale>0) { + /* denomW16 is in Q(16+scale) */ + denomW16=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(denom, scale); + + /* num in Q(34-scale) */ + num=WEBRTC_SPL_RSHIFT_W32(ENH_A0_MINUS_A0A0DIV4, scale); + } else { + /* denomW16 is in Q16 */ + denomW16=(WebRtc_Word16)denom; + + /* num in Q34 */ + num=ENH_A0_MINUS_A0A0DIV4; + } + + /* A sqrt( (ENH_A0-(ENH_A0^2)/4)*(w00*w00)/(w11*w00 + w10*w10) ) in Q9 */ + A = (WebRtc_Word16)WebRtcSpl_Sqrt(WebRtcSpl_DivW32W16(num, denomW16)); + + /* B_W32 is in Q30 ( B = 1 - ENH_A0/2 - A * w10/w00 ) */ + scale1 = 31-bitsw10; + scale2 = 21-scale1; + w10prim = WEBRTC_SPL_LSHIFT_W32(w10, scale1); + w00prim = WEBRTC_SPL_SHIFT_W32(w00, -scale2); + scale = bitsw00-scale2-15; + + if (scale>0) { + w10prim=WEBRTC_SPL_RSHIFT_W32(w10prim, scale); + w00prim=WEBRTC_SPL_RSHIFT_W32(w00prim, scale); + } + + if ((w00prim>0)&&(w10prim>0)) { + w11_div_w00=WebRtcSpl_DivW32W16(w10prim, (WebRtc_Word16)w00prim); + + if (WebRtcSpl_GetSizeInBits(w11_div_w00)+WebRtcSpl_GetSizeInBits(A)>31) { + B_W32 = 0; + } else { + B_W32 = (WebRtc_Word32)1073741824 - (WebRtc_Word32)ENH_A0DIV2 - + WEBRTC_SPL_MUL(A, w11_div_w00); + } + B = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(B_W32, 16); /* B in Q14 */ + } else { + /* No smoothing */ + A = 0; + B = 16384; /* 1 in Q14 */ + } + } + else{ /* essentially no difference between cycles; + smoothing not needed */ + + A = 0; + B = 16384; /* 1 in Q14 */ + } + + /* create smoothed sequence */ + + WebRtcSpl_ScaleAndAddVectors(surround, A, 9, + current, B, 14, + odata, ENH_BLOCKL); + } + return; +} diff --git a/src/libs/webrtc/ilbcfix/smooth.h b/src/libs/webrtc/ilbcfix/smooth.h new file mode 100644 index 00000000..88ce805d --- /dev/null +++ b/src/libs/webrtc/ilbcfix/smooth.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Smooth.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SMOOTH_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SMOOTH_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * find the smoothed output data + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Smooth( + WebRtc_Word16 *odata, /* (o) smoothed output */ + WebRtc_Word16 *current, /* (i) the un enhanced residual for + this block */ + WebRtc_Word16 *surround /* (i) The approximation from the + surrounding sequences */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/smooth_out_data.c b/src/libs/webrtc/ilbcfix/smooth_out_data.c new file mode 100644 index 00000000..9bacd85e --- /dev/null +++ b/src/libs/webrtc/ilbcfix/smooth_out_data.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Smooth_odata.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +WebRtc_Word32 WebRtcIlbcfix_Smooth_odata( + WebRtc_Word16 *odata, + WebRtc_Word16 *psseq, + WebRtc_Word16 *surround, + WebRtc_Word16 C) +{ + int i; + + WebRtc_Word16 err; + WebRtc_Word32 errs; + + for(i=0;i<80;i++) { + odata[i]= (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( + (WEBRTC_SPL_MUL_16_16(C, surround[i])+1024), 11); + } + + errs=0; + for(i=0;i<80;i++) { + err=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16((psseq[i]-odata[i]), 3); + errs+=WEBRTC_SPL_MUL_16_16(err, err); /* errs in Q-6 */ + } + + return errs; +} diff --git a/src/libs/webrtc/ilbcfix/smooth_out_data.h b/src/libs/webrtc/ilbcfix/smooth_out_data.h new file mode 100644 index 00000000..6fbe694f --- /dev/null +++ b/src/libs/webrtc/ilbcfix/smooth_out_data.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Smooth_odata.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SMOOTH_OUT_DATA_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SMOOTH_OUT_DATA_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * help function to WebRtcIlbcfix_Smooth() + *---------------------------------------------------------------*/ + +WebRtc_Word32 WebRtcIlbcfix_Smooth_odata( + WebRtc_Word16 *odata, + WebRtc_Word16 *psseq, + WebRtc_Word16 *surround, + WebRtc_Word16 C); + + +#endif diff --git a/src/libs/webrtc/ilbcfix/sort_sq.c b/src/libs/webrtc/ilbcfix/sort_sq.c new file mode 100644 index 00000000..9276a7ba --- /dev/null +++ b/src/libs/webrtc/ilbcfix/sort_sq.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SortSq.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * scalar quantization + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SortSq( + WebRtc_Word16 *xq, /* (o) the quantized value */ + WebRtc_Word16 *index, /* (o) the quantization index */ + WebRtc_Word16 x, /* (i) the value to quantize */ + const WebRtc_Word16 *cb, /* (i) the quantization codebook */ + WebRtc_Word16 cb_size /* (i) the size of the quantization codebook */ + ){ + int i; + + if (x <= cb[0]) { + *index = 0; + *xq = cb[0]; + } else { + i = 0; + while ((x > cb[i]) && (i < (cb_size-1))) { + i++; + } + + if (x > WEBRTC_SPL_RSHIFT_W32(( (WebRtc_Word32)cb[i] + cb[i - 1] + 1),1)) { + *index = i; + *xq = cb[i]; + } else { + *index = i - 1; + *xq = cb[i - 1]; + } + } +} diff --git a/src/libs/webrtc/ilbcfix/sort_sq.h b/src/libs/webrtc/ilbcfix/sort_sq.h new file mode 100644 index 00000000..2863dc52 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/sort_sq.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SortSq.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SORT_SQ_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SORT_SQ_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * scalar quantization + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SortSq( + WebRtc_Word16 *xq, /* (o) the quantized value */ + WebRtc_Word16 *index, /* (o) the quantization index */ + WebRtc_Word16 x, /* (i) the value to quantize */ + const WebRtc_Word16 *cb, /* (i) the quantization codebook */ + WebRtc_Word16 cb_size /* (i) the size of the quantization codebook */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/split_vq.c b/src/libs/webrtc/ilbcfix/split_vq.c new file mode 100644 index 00000000..d908fa22 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/split_vq.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SplitVq.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "vq3.h" +#include "vq4.h" + +/*----------------------------------------------------------------* + * split vector quantization + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SplitVq( + WebRtc_Word16 *qX, /* (o) the quantized vector in Q13 */ + WebRtc_Word16 *index, /* (o) a vector of indexes for all vector + codebooks in the split */ + WebRtc_Word16 *X, /* (i) the vector to quantize */ + WebRtc_Word16 *CB, /* (i) the quantizer codebook in Q13 */ + WebRtc_Word16 *dim, /* (i) the dimension of X and qX */ + WebRtc_Word16 *cbsize /* (i) the number of vectors in the codebook */ + ) { + + WebRtc_Word16 *qXPtr, *indexPtr, *CBPtr, *XPtr; + + /* Quantize X with the 3 vectror quantization tables */ + + qXPtr=qX; + indexPtr=index; + CBPtr=CB; + XPtr=X; + WebRtcIlbcfix_Vq3(qXPtr, indexPtr, CBPtr, XPtr, cbsize[0]); + + qXPtr+=3; + indexPtr+=1; + CBPtr+=(dim[0]*cbsize[0]); + XPtr+=3; + WebRtcIlbcfix_Vq3(qXPtr, indexPtr, CBPtr, XPtr, cbsize[1]); + + qXPtr+=3; + indexPtr+=1; + CBPtr+=(dim[1]*cbsize[1]); + XPtr+=3; + WebRtcIlbcfix_Vq4(qXPtr, indexPtr, CBPtr, XPtr, cbsize[2]); + + return; +} diff --git a/src/libs/webrtc/ilbcfix/split_vq.h b/src/libs/webrtc/ilbcfix/split_vq.h new file mode 100644 index 00000000..7264a212 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/split_vq.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SplitVq.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SPLIT_VQ_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SPLIT_VQ_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * split vector quantization + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SplitVq( + WebRtc_Word16 *qX, /* (o) the quantized vector in Q13 */ + WebRtc_Word16 *index, /* (o) a vector of indexes for all vector + codebooks in the split */ + WebRtc_Word16 *X, /* (i) the vector to quantize */ + WebRtc_Word16 *CB, /* (i) the quantizer codebook in Q13 */ + WebRtc_Word16 *dim, /* (i) the dimension of X and qX */ + WebRtc_Word16 *cbsize /* (i) the number of vectors in the codebook */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/state_construct.c b/src/libs/webrtc/ilbcfix/state_construct.c new file mode 100644 index 00000000..9d03cc36 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/state_construct.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_StateConstruct.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * decoding of the start state + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_StateConstruct( + WebRtc_Word16 idxForMax, /* (i) 6-bit index for the quantization of + max amplitude */ + WebRtc_Word16 *idxVec, /* (i) vector of quantization indexes */ + WebRtc_Word16 *syntDenum, /* (i) synthesis filter denumerator */ + WebRtc_Word16 *Out_fix, /* (o) the decoded state vector */ + WebRtc_Word16 len /* (i) length of a state vector */ + ) { + int k; + WebRtc_Word16 maxVal; + WebRtc_Word16 *tmp1, *tmp2, *tmp3; + /* Stack based */ + WebRtc_Word16 numerator[1+LPC_FILTERORDER]; + WebRtc_Word16 sampleValVec[2*STATE_SHORT_LEN_30MS+LPC_FILTERORDER]; + WebRtc_Word16 sampleMaVec[2*STATE_SHORT_LEN_30MS+LPC_FILTERORDER]; + WebRtc_Word16 *sampleVal = &sampleValVec[LPC_FILTERORDER]; + WebRtc_Word16 *sampleMa = &sampleMaVec[LPC_FILTERORDER]; + WebRtc_Word16 *sampleAr = &sampleValVec[LPC_FILTERORDER]; + + /* initialization of coefficients */ + + for (k=0; k<LPC_FILTERORDER+1; k++){ + numerator[k] = syntDenum[LPC_FILTERORDER-k]; + } + + /* decoding of the maximum value */ + + maxVal = WebRtcIlbcfix_kFrgQuantMod[idxForMax]; + + /* decoding of the sample values */ + tmp1 = sampleVal; + tmp2 = &idxVec[len-1]; + + if (idxForMax<37) { + for(k=0; k<len; k++){ + /*the shifting is due to the Q13 in sq4_fixQ13[i], also the adding of 2097152 (= 0.5 << 22) + maxVal is in Q8 and result is in Q(-1) */ + (*tmp1) = (WebRtc_Word16) ((WEBRTC_SPL_MUL_16_16(maxVal,WebRtcIlbcfix_kStateSq3[(*tmp2)])+(WebRtc_Word32)2097152) >> 22); + tmp1++; + tmp2--; + } + } else if (idxForMax<59) { + for(k=0; k<len; k++){ + /*the shifting is due to the Q13 in sq4_fixQ13[i], also the adding of 262144 (= 0.5 << 19) + maxVal is in Q5 and result is in Q(-1) */ + (*tmp1) = (WebRtc_Word16) ((WEBRTC_SPL_MUL_16_16(maxVal,WebRtcIlbcfix_kStateSq3[(*tmp2)])+(WebRtc_Word32)262144) >> 19); + tmp1++; + tmp2--; + } + } else { + for(k=0; k<len; k++){ + /*the shifting is due to the Q13 in sq4_fixQ13[i], also the adding of 65536 (= 0.5 << 17) + maxVal is in Q3 and result is in Q(-1) */ + (*tmp1) = (WebRtc_Word16) ((WEBRTC_SPL_MUL_16_16(maxVal,WebRtcIlbcfix_kStateSq3[(*tmp2)])+(WebRtc_Word32)65536) >> 17); + tmp1++; + tmp2--; + } + } + + /* Set the rest of the data to zero */ + WebRtcSpl_MemSetW16(&sampleVal[len], 0, len); + + /* circular convolution with all-pass filter */ + + /* Set the state to zero */ + WebRtcSpl_MemSetW16(sampleValVec, 0, (LPC_FILTERORDER)); + + /* Run MA filter + AR filter */ + WebRtcSpl_FilterMAFastQ12( + sampleVal, sampleMa, + numerator, LPC_FILTERORDER+1, (WebRtc_Word16)(len + LPC_FILTERORDER)); + WebRtcSpl_MemSetW16(&sampleMa[len + LPC_FILTERORDER], 0, (len - LPC_FILTERORDER)); + WebRtcSpl_FilterARFastQ12( + sampleMa, sampleAr, + syntDenum, LPC_FILTERORDER+1, (WebRtc_Word16)(2*len)); + + tmp1 = &sampleAr[len-1]; + tmp2 = &sampleAr[2*len-1]; + tmp3 = Out_fix; + for(k=0;k<len;k++){ + (*tmp3) = (*tmp1) + (*tmp2); + tmp1--; + tmp2--; + tmp3++; + } +} diff --git a/src/libs/webrtc/ilbcfix/state_construct.h b/src/libs/webrtc/ilbcfix/state_construct.h new file mode 100644 index 00000000..465699b7 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/state_construct.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_StateConstruct.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_STATE_CONSTRUCT_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_STATE_CONSTRUCT_H_ + +/*----------------------------------------------------------------* + * Generate the start state from the quantized indexes + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_StateConstruct( + WebRtc_Word16 idxForMax, /* (i) 6-bit index for the quantization of + max amplitude */ + WebRtc_Word16 *idxVec, /* (i) vector of quantization indexes */ + WebRtc_Word16 *syntDenum, /* (i) synthesis filter denumerator */ + WebRtc_Word16 *Out_fix, /* (o) the decoded state vector */ + WebRtc_Word16 len /* (i) length of a state vector */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/state_search.c b/src/libs/webrtc/ilbcfix/state_search.c new file mode 100644 index 00000000..824a0ba6 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/state_search.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_StateSearch.c + +******************************************************************/ + +#include "defines.h" +#include "constants.h" +#include "abs_quant.h" + +/*----------------------------------------------------------------* + * encoding of start state + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_StateSearch( + iLBC_Enc_Inst_t *iLBCenc_inst, + /* (i) Encoder instance */ + iLBC_bits *iLBC_encbits,/* (i/o) Encoded bits (output idxForMax + and idxVec, input state_first) */ + WebRtc_Word16 *residual, /* (i) target residual vector */ + WebRtc_Word16 *syntDenum, /* (i) lpc synthesis filter */ + WebRtc_Word16 *weightDenum /* (i) weighting filter denuminator */ + ) { + WebRtc_Word16 k, index; + WebRtc_Word16 maxVal; + WebRtc_Word16 scale, shift; + WebRtc_Word32 maxValsq; + WebRtc_Word16 scaleRes; + WebRtc_Word16 max; + int i; + /* Stack based */ + WebRtc_Word16 numerator[1+LPC_FILTERORDER]; + WebRtc_Word16 residualLongVec[2*STATE_SHORT_LEN_30MS+LPC_FILTERORDER]; + WebRtc_Word16 sampleMa[2*STATE_SHORT_LEN_30MS]; + WebRtc_Word16 *residualLong = &residualLongVec[LPC_FILTERORDER]; + WebRtc_Word16 *sampleAr = residualLong; + + /* Scale to maximum 12 bits to avoid saturation in circular convolution filter */ + max = WebRtcSpl_MaxAbsValueW16(residual, iLBCenc_inst->state_short_len); + scaleRes = WebRtcSpl_GetSizeInBits(max)-12; + scaleRes = WEBRTC_SPL_MAX(0, scaleRes); + /* Set up the filter coefficients for the circular convolution */ + for (i=0; i<LPC_FILTERORDER+1; i++) { + numerator[i] = (syntDenum[LPC_FILTERORDER-i]>>scaleRes); + } + + /* Copy the residual to a temporary buffer that we can filter + * and set the remaining samples to zero. + */ + WEBRTC_SPL_MEMCPY_W16(residualLong, residual, iLBCenc_inst->state_short_len); + WebRtcSpl_MemSetW16(residualLong + iLBCenc_inst->state_short_len, 0, iLBCenc_inst->state_short_len); + + /* Run the Zero-Pole filter (Ciurcular convolution) */ + WebRtcSpl_MemSetW16(residualLongVec, 0, LPC_FILTERORDER); + WebRtcSpl_FilterMAFastQ12( + residualLong, sampleMa, + numerator, LPC_FILTERORDER+1, (WebRtc_Word16)(iLBCenc_inst->state_short_len + LPC_FILTERORDER)); + WebRtcSpl_MemSetW16(&sampleMa[iLBCenc_inst->state_short_len + LPC_FILTERORDER], 0, iLBCenc_inst->state_short_len - LPC_FILTERORDER); + + WebRtcSpl_FilterARFastQ12( + sampleMa, sampleAr, + syntDenum, LPC_FILTERORDER+1, (WebRtc_Word16)(2*iLBCenc_inst->state_short_len)); + + for(k=0;k<iLBCenc_inst->state_short_len;k++){ + sampleAr[k] += sampleAr[k+iLBCenc_inst->state_short_len]; + } + + /* Find maximum absolute value in the vector */ + maxVal=WebRtcSpl_MaxAbsValueW16(sampleAr, iLBCenc_inst->state_short_len); + + /* Find the best index */ + + if ((((WebRtc_Word32)maxVal)<<scaleRes)<23170) { + maxValsq=((WebRtc_Word32)maxVal*maxVal)<<(2+2*scaleRes); + } else { + maxValsq=(WebRtc_Word32)WEBRTC_SPL_WORD32_MAX; + } + + index=0; + for (i=0;i<63;i++) { + + if (maxValsq>=WebRtcIlbcfix_kChooseFrgQuant[i]) { + index=i+1; + } else { + i=63; + } + } + iLBC_encbits->idxForMax=index; + + /* Rescale the vector before quantization */ + scale=WebRtcIlbcfix_kScale[index]; + + if (index<27) { /* scale table is in Q16, fout[] is in Q(-1) and we want the result to be in Q11 */ + shift=4; + } else { /* scale table is in Q21, fout[] is in Q(-1) and we want the result to be in Q11 */ + shift=9; + } + + /* Set up vectors for AbsQuant and rescale it with the scale factor */ + WebRtcSpl_ScaleVectorWithSat(sampleAr, sampleAr, scale, + iLBCenc_inst->state_short_len, (WebRtc_Word16)(shift-scaleRes)); + + /* Quantize the values in fout[] */ + WebRtcIlbcfix_AbsQuant(iLBCenc_inst, iLBC_encbits, sampleAr, weightDenum); + + return; +} diff --git a/src/libs/webrtc/ilbcfix/state_search.h b/src/libs/webrtc/ilbcfix/state_search.h new file mode 100644 index 00000000..8b7f2987 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/state_search.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_StateSearch.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_STATE_SEARCH_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_STATE_SEARCH_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * encoding of start state + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_StateSearch( + iLBC_Enc_Inst_t *iLBCenc_inst, + /* (i) Encoder instance */ + iLBC_bits *iLBC_encbits,/* (i/o) Encoded bits (output idxForMax + and idxVec, input state_first) */ + WebRtc_Word16 *residual, /* (i) target residual vector */ + WebRtc_Word16 *syntDenum, /* (i) lpc synthesis filter */ + WebRtc_Word16 *weightDenum /* (i) weighting filter denuminator */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/swap_bytes.c b/src/libs/webrtc/ilbcfix/swap_bytes.c new file mode 100644 index 00000000..61b8b7bd --- /dev/null +++ b/src/libs/webrtc/ilbcfix/swap_bytes.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SwapBytes.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Swap bytes (to simplify operations on Little Endian machines) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SwapBytes( + WebRtc_UWord16 *sequence, /* (i/o) the sequence to swap */ + WebRtc_Word16 wordLength /* (i) number or WebRtc_UWord16 to swap */ + ) { + int k; + WebRtc_UWord16 temp=0; + for( k=wordLength; k>0; k-- ) { + temp = (*sequence >> 8)|(*sequence << 8); + *sequence++ = temp; + //*sequence++ = (*sequence >> 8) | (*sequence << 8); + } +} diff --git a/src/libs/webrtc/ilbcfix/swap_bytes.h b/src/libs/webrtc/ilbcfix/swap_bytes.h new file mode 100644 index 00000000..2f2b3eb1 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/swap_bytes.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_SwapBytes.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SWAP_BYTES_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_SWAP_BYTES_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * Swap bytes (to simplify operations on Little Endian machines) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_SwapBytes( + WebRtc_UWord16 *sequence, /* (i/o) the sequence to swap */ + WebRtc_Word16 wordLength /* (i) number or WebRtc_UWord16 to swap */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/unpack_bits.c b/src/libs/webrtc/ilbcfix/unpack_bits.c new file mode 100644 index 00000000..6c883a7b --- /dev/null +++ b/src/libs/webrtc/ilbcfix/unpack_bits.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_UnpackBits.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * unpacking of bits from bitstream, i.e., vector of bytes + *---------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_UnpackBits( /* (o) "Empty" frame indicator */ + WebRtc_UWord16 *bitstream, /* (i) The packatized bitstream */ + iLBC_bits *enc_bits, /* (o) Paramerers from bitstream */ + WebRtc_Word16 mode /* (i) Codec mode (20 or 30) */ + ) { + WebRtc_UWord16 *bitstreamPtr; + int i, k; + WebRtc_Word16 *tmpPtr; + + bitstreamPtr=bitstream; + + /* First WebRtc_Word16 */ + enc_bits->lsf[0] = (*bitstreamPtr)>>10; /* Bit 0..5 */ + enc_bits->lsf[1] = ((*bitstreamPtr)>>3)&0x7F; /* Bit 6..12 */ + enc_bits->lsf[2] = ((*bitstreamPtr)&0x7)<<4; /* Bit 13..15 */ + bitstreamPtr++; + /* Second WebRtc_Word16 */ + enc_bits->lsf[2] |= ((*bitstreamPtr)>>12)&0xF; /* Bit 0..3 */ + + if (mode==20) { + enc_bits->startIdx = ((*bitstreamPtr)>>10)&0x3; /* Bit 4..5 */ + enc_bits->state_first = ((*bitstreamPtr)>>9)&0x1; /* Bit 6 */ + enc_bits->idxForMax = ((*bitstreamPtr)>>3)&0x3F; /* Bit 7..12 */ + enc_bits->cb_index[0] = ((*bitstreamPtr)&0x7)<<4; /* Bit 13..15 */ + bitstreamPtr++; + /* Third WebRtc_Word16 */ + enc_bits->cb_index[0] |= ((*bitstreamPtr)>>12)&0xE; /* Bit 0..2 */ + enc_bits->gain_index[0] = ((*bitstreamPtr)>>8)&0x18; /* Bit 3..4 */ + enc_bits->gain_index[1] = ((*bitstreamPtr)>>7)&0x8; /* Bit 5 */ + enc_bits->cb_index[3] = ((*bitstreamPtr)>>2)&0xFE; /* Bit 6..12 */ + enc_bits->gain_index[3] = ((*bitstreamPtr)<<2)&0x10; /* Bit 13 */ + enc_bits->gain_index[4] = ((*bitstreamPtr)<<2)&0x8; /* Bit 14 */ + enc_bits->gain_index[6] = ((*bitstreamPtr)<<4)&0x10; /* Bit 15 */ + } else { /* mode==30 */ + enc_bits->lsf[3] = ((*bitstreamPtr)>>6)&0x3F; /* Bit 4..9 */ + enc_bits->lsf[4] = ((*bitstreamPtr)<<1)&0x7E; /* Bit 10..15 */ + bitstreamPtr++; + /* Third WebRtc_Word16 */ + enc_bits->lsf[4] |= ((*bitstreamPtr)>>15)&0x1; /* Bit 0 */ + enc_bits->lsf[5] = ((*bitstreamPtr)>>8)&0x7F; /* Bit 1..7 */ + enc_bits->startIdx = ((*bitstreamPtr)>>5)&0x7; /* Bit 8..10 */ + enc_bits->state_first = ((*bitstreamPtr)>>4)&0x1; /* Bit 11 */ + enc_bits->idxForMax = ((*bitstreamPtr)<<2)&0x3C; /* Bit 12..15 */ + bitstreamPtr++; + /* 4:th WebRtc_Word16 */ + enc_bits->idxForMax |= ((*bitstreamPtr)>>14)&0x3; /* Bit 0..1 */ + enc_bits->cb_index[0] = ((*bitstreamPtr)>>7)&0x78; /* Bit 2..5 */ + enc_bits->gain_index[0] = ((*bitstreamPtr)>>5)&0x10; /* Bit 6 */ + enc_bits->gain_index[1] = ((*bitstreamPtr)>>5)&0x8; /* Bit 7 */ + enc_bits->cb_index[3] = ((*bitstreamPtr))&0xFC; /* Bit 8..13 */ + enc_bits->gain_index[3] = ((*bitstreamPtr)<<3)&0x10; /* Bit 14 */ + enc_bits->gain_index[4] = ((*bitstreamPtr)<<3)&0x8; /* Bit 15 */ + } + /* Class 2 bits of ULP */ + /* 4:th to 6:th WebRtc_Word16 for 20 ms case + 5:th to 7:th WebRtc_Word16 for 30 ms case */ + bitstreamPtr++; + tmpPtr=enc_bits->idxVec; + for (k=0; k<3; k++) { + for (i=15; i>=0; i--) { + (*tmpPtr) = (((*bitstreamPtr)>>i)<<2)&0x4; + /* Bit 15-i */ + tmpPtr++; + } + bitstreamPtr++; + } + + if (mode==20) { + /* 7:th WebRtc_Word16 */ + for (i=15; i>6; i--) { + (*tmpPtr) = (((*bitstreamPtr)>>i)<<2)&0x4; + /* Bit 15-i */ + tmpPtr++; + } + enc_bits->gain_index[1] |= ((*bitstreamPtr)>>4)&0x4; /* Bit 9 */ + enc_bits->gain_index[3] |= ((*bitstreamPtr)>>2)&0xC; /* Bit 10..11 */ + enc_bits->gain_index[4] |= ((*bitstreamPtr)>>1)&0x4; /* Bit 12 */ + enc_bits->gain_index[6] |= ((*bitstreamPtr)<<1)&0x8; /* Bit 13 */ + enc_bits->gain_index[7] = ((*bitstreamPtr)<<2)&0xC; /* Bit 14..15 */ + + } else { /* mode==30 */ + /* 8:th WebRtc_Word16 */ + for (i=15; i>5; i--) { + (*tmpPtr) = (((*bitstreamPtr)>>i)<<2)&0x4; + /* Bit 15-i */ + tmpPtr++; + } + enc_bits->cb_index[0] |= ((*bitstreamPtr)>>3)&0x6; /* Bit 10..11 */ + enc_bits->gain_index[0] |= ((*bitstreamPtr))&0x8; /* Bit 12 */ + enc_bits->gain_index[1] |= ((*bitstreamPtr))&0x4; /* Bit 13 */ + enc_bits->cb_index[3] |= ((*bitstreamPtr))&0x2; /* Bit 14 */ + enc_bits->cb_index[6] = ((*bitstreamPtr)<<7)&0x80; /* Bit 15 */ + bitstreamPtr++; + /* 9:th WebRtc_Word16 */ + enc_bits->cb_index[6] |= ((*bitstreamPtr)>>9)&0x7E; /* Bit 0..5 */ + enc_bits->cb_index[9] = ((*bitstreamPtr)>>2)&0xFE; /* Bit 6..12 */ + enc_bits->cb_index[12] = ((*bitstreamPtr)<<5)&0xE0; /* Bit 13..15 */ + bitstreamPtr++; + /* 10:th WebRtc_Word16 */ + enc_bits->cb_index[12] |= ((*bitstreamPtr)>>11)&0x1E;/* Bit 0..3 */ + enc_bits->gain_index[3] |= ((*bitstreamPtr)>>8)&0xC; /* Bit 4..5 */ + enc_bits->gain_index[4] |= ((*bitstreamPtr)>>7)&0x6; /* Bit 6..7 */ + enc_bits->gain_index[6] = ((*bitstreamPtr)>>3)&0x18; /* Bit 8..9 */ + enc_bits->gain_index[7] = ((*bitstreamPtr)>>2)&0xC; /* Bit 10..11 */ + enc_bits->gain_index[9] = ((*bitstreamPtr)<<1)&0x10; /* Bit 12 */ + enc_bits->gain_index[10] = ((*bitstreamPtr)<<1)&0x8; /* Bit 13 */ + enc_bits->gain_index[12] = ((*bitstreamPtr)<<3)&0x10; /* Bit 14 */ + enc_bits->gain_index[13] = ((*bitstreamPtr)<<3)&0x8; /* Bit 15 */ + } + bitstreamPtr++; + /* Class 3 bits of ULP */ + /* 8:th to 14:th WebRtc_Word16 for 20 ms case + 11:th to 17:th WebRtc_Word16 for 30 ms case */ + tmpPtr=enc_bits->idxVec; + for (k=0; k<7; k++) { + for (i=14; i>=0; i-=2) { + (*tmpPtr) |= ((*bitstreamPtr)>>i)&0x3; /* Bit 15-i..14-i*/ + tmpPtr++; + } + bitstreamPtr++; + } + + if (mode==20) { + /* 15:th WebRtc_Word16 */ + enc_bits->idxVec[56] |= ((*bitstreamPtr)>>14)&0x3; /* Bit 0..1 */ + enc_bits->cb_index[0] |= ((*bitstreamPtr)>>13)&0x1; /* Bit 2 */ + enc_bits->cb_index[1] = ((*bitstreamPtr)>>6)&0x7F; /* Bit 3..9 */ + enc_bits->cb_index[2] = ((*bitstreamPtr)<<1)&0x7E; /* Bit 10..15 */ + bitstreamPtr++; + /* 16:th WebRtc_Word16 */ + enc_bits->cb_index[2] |= ((*bitstreamPtr)>>15)&0x1; /* Bit 0 */ + enc_bits->gain_index[0] |= ((*bitstreamPtr)>>12)&0x7; /* Bit 1..3 */ + enc_bits->gain_index[1] |= ((*bitstreamPtr)>>10)&0x3; /* Bit 4..5 */ + enc_bits->gain_index[2] = ((*bitstreamPtr)>>7)&0x7; /* Bit 6..8 */ + enc_bits->cb_index[3] |= ((*bitstreamPtr)>>6)&0x1; /* Bit 9 */ + enc_bits->cb_index[4] = ((*bitstreamPtr)<<1)&0x7E; /* Bit 10..15 */ + bitstreamPtr++; + /* 17:th WebRtc_Word16 */ + enc_bits->cb_index[4] |= ((*bitstreamPtr)>>15)&0x1; /* Bit 0 */ + enc_bits->cb_index[5] = ((*bitstreamPtr)>>8)&0x7F; /* Bit 1..7 */ + enc_bits->cb_index[6] = ((*bitstreamPtr))&0xFF; /* Bit 8..15 */ + bitstreamPtr++; + /* 18:th WebRtc_Word16 */ + enc_bits->cb_index[7] = (*bitstreamPtr)>>8; /* Bit 0..7 */ + enc_bits->cb_index[8] = (*bitstreamPtr)&0xFF; /* Bit 8..15 */ + bitstreamPtr++; + /* 19:th WebRtc_Word16 */ + enc_bits->gain_index[3] |= ((*bitstreamPtr)>>14)&0x3; /* Bit 0..1 */ + enc_bits->gain_index[4] |= ((*bitstreamPtr)>>12)&0x3; /* Bit 2..3 */ + enc_bits->gain_index[5] = ((*bitstreamPtr)>>9)&0x7; /* Bit 4..6 */ + enc_bits->gain_index[6] |= ((*bitstreamPtr)>>6)&0x7; /* Bit 7..9 */ + enc_bits->gain_index[7] |= ((*bitstreamPtr)>>4)&0x3; /* Bit 10..11 */ + enc_bits->gain_index[8] = ((*bitstreamPtr)>>1)&0x7; /* Bit 12..14 */ + } else { /* mode==30 */ + /* 18:th WebRtc_Word16 */ + enc_bits->idxVec[56] |= ((*bitstreamPtr)>>14)&0x3; /* Bit 0..1 */ + enc_bits->idxVec[57] |= ((*bitstreamPtr)>>12)&0x3; /* Bit 2..3 */ + enc_bits->cb_index[0] |= ((*bitstreamPtr)>>11)&1; /* Bit 4 */ + enc_bits->cb_index[1] = ((*bitstreamPtr)>>4)&0x7F; /* Bit 5..11 */ + enc_bits->cb_index[2] = ((*bitstreamPtr)<<3)&0x78; /* Bit 12..15 */ + bitstreamPtr++; + /* 19:th WebRtc_Word16 */ + enc_bits->cb_index[2] |= ((*bitstreamPtr)>>13)&0x7; /* Bit 0..2 */ + enc_bits->gain_index[0] |= ((*bitstreamPtr)>>10)&0x7; /* Bit 3..5 */ + enc_bits->gain_index[1] |= ((*bitstreamPtr)>>8)&0x3; /* Bit 6..7 */ + enc_bits->gain_index[2] = ((*bitstreamPtr)>>5)&0x7; /* Bit 8..10 */ + enc_bits->cb_index[3] |= ((*bitstreamPtr)>>4)&0x1; /* Bit 11 */ + enc_bits->cb_index[4] = ((*bitstreamPtr)<<3)&0x78; /* Bit 12..15 */ + bitstreamPtr++; + /* 20:th WebRtc_Word16 */ + enc_bits->cb_index[4] |= ((*bitstreamPtr)>>13)&0x7; /* Bit 0..2 */ + enc_bits->cb_index[5] = ((*bitstreamPtr)>>6)&0x7F; /* Bit 3..9 */ + enc_bits->cb_index[6] |= ((*bitstreamPtr)>>5)&0x1; /* Bit 10 */ + enc_bits->cb_index[7] = ((*bitstreamPtr)<<3)&0xF8; /* Bit 11..15 */ + bitstreamPtr++; + /* 21:st WebRtc_Word16 */ + enc_bits->cb_index[7] |= ((*bitstreamPtr)>>13)&0x7; /* Bit 0..2 */ + enc_bits->cb_index[8] = ((*bitstreamPtr)>>5)&0xFF; /* Bit 3..10 */ + enc_bits->cb_index[9] |= ((*bitstreamPtr)>>4)&0x1; /* Bit 11 */ + enc_bits->cb_index[10] = ((*bitstreamPtr)<<4)&0xF0; /* Bit 12..15 */ + bitstreamPtr++; + /* 22:nd WebRtc_Word16 */ + enc_bits->cb_index[10] |= ((*bitstreamPtr)>>12)&0xF; /* Bit 0..3 */ + enc_bits->cb_index[11] = ((*bitstreamPtr)>>4)&0xFF; /* Bit 4..11 */ + enc_bits->cb_index[12] |= ((*bitstreamPtr)>>3)&0x1; /* Bit 12 */ + enc_bits->cb_index[13] = ((*bitstreamPtr)<<5)&0xE0; /* Bit 13..15 */ + bitstreamPtr++; + /* 23:rd WebRtc_Word16 */ + enc_bits->cb_index[13] |= ((*bitstreamPtr)>>11)&0x1F;/* Bit 0..4 */ + enc_bits->cb_index[14] = ((*bitstreamPtr)>>3)&0xFF; /* Bit 5..12 */ + enc_bits->gain_index[3] |= ((*bitstreamPtr)>>1)&0x3; /* Bit 13..14 */ + enc_bits->gain_index[4] |= ((*bitstreamPtr)&0x1); /* Bit 15 */ + bitstreamPtr++; + /* 24:rd WebRtc_Word16 */ + enc_bits->gain_index[5] = ((*bitstreamPtr)>>13)&0x7; /* Bit 0..2 */ + enc_bits->gain_index[6] |= ((*bitstreamPtr)>>10)&0x7; /* Bit 3..5 */ + enc_bits->gain_index[7] |= ((*bitstreamPtr)>>8)&0x3; /* Bit 6..7 */ + enc_bits->gain_index[8] = ((*bitstreamPtr)>>5)&0x7; /* Bit 8..10 */ + enc_bits->gain_index[9] |= ((*bitstreamPtr)>>1)&0xF; /* Bit 11..14 */ + enc_bits->gain_index[10] |= ((*bitstreamPtr)<<2)&0x4; /* Bit 15 */ + bitstreamPtr++; + /* 25:rd WebRtc_Word16 */ + enc_bits->gain_index[10] |= ((*bitstreamPtr)>>14)&0x3; /* Bit 0..1 */ + enc_bits->gain_index[11] = ((*bitstreamPtr)>>11)&0x7; /* Bit 2..4 */ + enc_bits->gain_index[12] |= ((*bitstreamPtr)>>7)&0xF; /* Bit 5..8 */ + enc_bits->gain_index[13] |= ((*bitstreamPtr)>>4)&0x7; /* Bit 9..11 */ + enc_bits->gain_index[14] = ((*bitstreamPtr)>>1)&0x7; /* Bit 12..14 */ + } + /* Last bit should be zero, otherwise it's an "empty" frame */ + if (((*bitstreamPtr)&0x1) == 1) { + return(1); + } else { + return(0); + } +} diff --git a/src/libs/webrtc/ilbcfix/unpack_bits.h b/src/libs/webrtc/ilbcfix/unpack_bits.h new file mode 100644 index 00000000..864865f0 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/unpack_bits.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_UnpackBits.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_UNPACK_BITS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_UNPACK_BITS_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * unpacking of bits from bitstream, i.e., vector of bytes + *---------------------------------------------------------------*/ + +WebRtc_Word16 WebRtcIlbcfix_UnpackBits( /* (o) "Empty" frame indicator */ + WebRtc_UWord16 *bitstream, /* (i) The packatized bitstream */ + iLBC_bits *enc_bits, /* (o) Paramerers from bitstream */ + WebRtc_Word16 mode /* (i) Codec mode (20 or 30) */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/vq3.c b/src/libs/webrtc/ilbcfix/vq3.c new file mode 100644 index 00000000..81d1bfa5 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/vq3.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Vq3.c + +******************************************************************/ + +#include "vq3.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * vector quantization + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Vq3( + WebRtc_Word16 *Xq, /* quantized vector (Q13) */ + WebRtc_Word16 *index, + WebRtc_Word16 *CB, /* codebook in Q13 */ + WebRtc_Word16 *X, /* vector to quantize (Q13) */ + WebRtc_Word16 n_cb + ){ + WebRtc_Word16 i, j; + WebRtc_Word16 pos, minindex=0; + WebRtc_Word16 tmp; + WebRtc_Word32 dist, mindist; + + pos = 0; + mindist = WEBRTC_SPL_WORD32_MAX; /* start value */ + + /* Find the codebook with the lowest square distance */ + for (j = 0; j < n_cb; j++) { + tmp = X[0] - CB[pos]; + dist = WEBRTC_SPL_MUL_16_16(tmp, tmp); + for (i = 1; i < 3; i++) { + tmp = X[i] - CB[pos + i]; + dist += WEBRTC_SPL_MUL_16_16(tmp, tmp); + } + + if (dist < mindist) { + mindist = dist; + minindex = j; + } + pos += 3; + } + + /* Store the quantized codebook and the index */ + for (i = 0; i < 3; i++) { + Xq[i] = CB[minindex*3 + i]; + } + *index = minindex; + +} diff --git a/src/libs/webrtc/ilbcfix/vq3.h b/src/libs/webrtc/ilbcfix/vq3.h new file mode 100644 index 00000000..f2628e0d --- /dev/null +++ b/src/libs/webrtc/ilbcfix/vq3.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Vq3.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_VQ3_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_VQ3_H_ + +#include "typedefs.h" + +/*----------------------------------------------------------------* + * Vector quantization of order 3 (based on MSE) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Vq3( + WebRtc_Word16 *Xq, /* (o) the quantized vector (Q13) */ + WebRtc_Word16 *index, /* (o) the quantization index */ + WebRtc_Word16 *CB, /* (i) the vector quantization codebook (Q13) */ + WebRtc_Word16 *X, /* (i) the vector to quantize (Q13) */ + WebRtc_Word16 n_cb /* (i) the number of vectors in the codebook */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/vq4.c b/src/libs/webrtc/ilbcfix/vq4.c new file mode 100644 index 00000000..3d4c26d6 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/vq4.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Vq4.c + +******************************************************************/ + +#include "vq4.h" +#include "constants.h" + +/*----------------------------------------------------------------* + * vector quantization + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Vq4( + WebRtc_Word16 *Xq, /* quantized vector (Q13) */ + WebRtc_Word16 *index, + WebRtc_Word16 *CB, /* codebook in Q13 */ + WebRtc_Word16 *X, /* vector to quantize (Q13) */ + WebRtc_Word16 n_cb + ){ + WebRtc_Word16 i, j; + WebRtc_Word16 pos, minindex=0; + WebRtc_Word16 tmp; + WebRtc_Word32 dist, mindist; + + pos = 0; + mindist = WEBRTC_SPL_WORD32_MAX; /* start value */ + + /* Find the codebook with the lowest square distance */ + for (j = 0; j < n_cb; j++) { + tmp = X[0] - CB[pos]; + dist = WEBRTC_SPL_MUL_16_16(tmp, tmp); + for (i = 1; i < 4; i++) { + tmp = X[i] - CB[pos + i]; + dist += WEBRTC_SPL_MUL_16_16(tmp, tmp); + } + + if (dist < mindist) { + mindist = dist; + minindex = j; + } + pos += 4; + } + + /* Store the quantized codebook and the index */ + for (i = 0; i < 4; i++) { + Xq[i] = CB[minindex*4 + i]; + } + *index = minindex; +} diff --git a/src/libs/webrtc/ilbcfix/vq4.h b/src/libs/webrtc/ilbcfix/vq4.h new file mode 100644 index 00000000..1b8cff25 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/vq4.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Vq4.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_VQ4_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_VQ4_H_ + +#include "typedefs.h" + +/*----------------------------------------------------------------* + * Vector quantization of order 4 (based on MSE) + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Vq4( + WebRtc_Word16 *Xq, /* (o) the quantized vector (Q13) */ + WebRtc_Word16 *index, /* (o) the quantization index */ + WebRtc_Word16 *CB, /* (i) the vector quantization codebook (Q13) */ + WebRtc_Word16 *X, /* (i) the vector to quantize (Q13) */ + WebRtc_Word16 n_cb /* (i) the number of vectors in the codebook */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/window32_w32.c b/src/libs/webrtc/ilbcfix/window32_w32.c new file mode 100644 index 00000000..b0e84067 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/window32_w32.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Window32W32.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * window multiplication + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Window32W32( + WebRtc_Word32 *z, /* Output */ + WebRtc_Word32 *x, /* Input (same domain as Output)*/ + const WebRtc_Word32 *y, /* Q31 Window */ + WebRtc_Word16 N /* length to process */ + ) { + WebRtc_Word16 i; + WebRtc_Word16 x_low, x_hi, y_low, y_hi; + WebRtc_Word16 left_shifts; + WebRtc_Word32 temp; + + left_shifts = (WebRtc_Word16)WebRtcSpl_NormW32(x[0]); + WebRtcSpl_VectorBitShiftW32(x, N, x, (WebRtc_Word16)(-left_shifts)); + + + /* The double precision numbers use a special representation: + * w32 = hi<<16 + lo<<1 + */ + for (i = 0; i < N; i++) { + /* Extract higher bytes */ + x_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(x[i], 16); + y_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(y[i], 16); + + /* Extract lower bytes, defined as (w32 - hi<<16)>>1 */ + temp = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)x_hi, 16); + x_low = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32((x[i] - temp), 1); + + temp = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)y_hi, 16); + y_low = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32((y[i] - temp), 1); + + /* Calculate z by a 32 bit multiplication using both low and high from x and y */ + temp = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(x_hi, y_hi), 1); + temp = (temp + (WEBRTC_SPL_MUL_16_16_RSFT(x_hi, y_low, 14))); + + z[i] = (temp + (WEBRTC_SPL_MUL_16_16_RSFT(x_low, y_hi, 14))); + } + + WebRtcSpl_VectorBitShiftW32(z, N, z, left_shifts); + + return; +} diff --git a/src/libs/webrtc/ilbcfix/window32_w32.h b/src/libs/webrtc/ilbcfix/window32_w32.h new file mode 100644 index 00000000..121188ab --- /dev/null +++ b/src/libs/webrtc/ilbcfix/window32_w32.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_Window32W32.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_WINDOW32_W32_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_WINDOW32_W32_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * window multiplication + *---------------------------------------------------------------*/ + +void WebRtcIlbcfix_Window32W32( + WebRtc_Word32 *z, /* Output */ + WebRtc_Word32 *x, /* Input (same domain as Output)*/ + const WebRtc_Word32 *y, /* Q31 Window */ + WebRtc_Word16 N /* length to process */ + ); + +#endif diff --git a/src/libs/webrtc/ilbcfix/xcorr_coef.c b/src/libs/webrtc/ilbcfix/xcorr_coef.c new file mode 100644 index 00000000..04170adb --- /dev/null +++ b/src/libs/webrtc/ilbcfix/xcorr_coef.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_XcorrCoef.c + +******************************************************************/ + +#include "defines.h" + +/*----------------------------------------------------------------* + * cross correlation which finds the optimal lag for the + * crossCorr*crossCorr/(energy) criteria + *---------------------------------------------------------------*/ + +int WebRtcIlbcfix_XcorrCoef( + WebRtc_Word16 *target, /* (i) first array */ + WebRtc_Word16 *regressor, /* (i) second array */ + WebRtc_Word16 subl, /* (i) dimension arrays */ + WebRtc_Word16 searchLen, /* (i) the search lenght */ + WebRtc_Word16 offset, /* (i) samples offset between arrays */ + WebRtc_Word16 step /* (i) +1 or -1 */ + ){ + int k; + WebRtc_Word16 maxlag; + WebRtc_Word16 pos; + WebRtc_Word16 max; + WebRtc_Word16 crossCorrScale, Energyscale; + WebRtc_Word16 crossCorrSqMod, crossCorrSqMod_Max; + WebRtc_Word32 crossCorr, Energy; + WebRtc_Word16 crossCorrmod, EnergyMod, EnergyMod_Max; + WebRtc_Word16 *tp, *rp; + WebRtc_Word16 *rp_beg, *rp_end; + WebRtc_Word16 totscale, totscale_max; + WebRtc_Word16 scalediff; + WebRtc_Word32 newCrit, maxCrit; + int shifts; + + /* Initializations, to make sure that the first one is selected */ + crossCorrSqMod_Max=0; + EnergyMod_Max=WEBRTC_SPL_WORD16_MAX; + totscale_max=-500; + maxlag=0; + pos=0; + + /* Find scale value and start position */ + if (step==1) { + max=WebRtcSpl_MaxAbsValueW16(regressor, (WebRtc_Word16)(subl+searchLen-1)); + rp_beg = regressor; + rp_end = &regressor[subl]; + } else { /* step==-1 */ + max=WebRtcSpl_MaxAbsValueW16(&regressor[-searchLen], (WebRtc_Word16)(subl+searchLen-1)); + rp_beg = &regressor[-1]; + rp_end = &regressor[subl-1]; + } + + /* Introduce a scale factor on the Energy in WebRtc_Word32 in + order to make sure that the calculation does not + overflow */ + + if (max>5000) { + shifts=2; + } else { + shifts=0; + } + + /* Calculate the first energy, then do a +/- to get the other energies */ + Energy=WebRtcSpl_DotProductWithScale(regressor, regressor, subl, shifts); + + for (k=0;k<searchLen;k++) { + tp = target; + rp = &regressor[pos]; + + crossCorr=WebRtcSpl_DotProductWithScale(tp, rp, subl, shifts); + + if ((Energy>0)&&(crossCorr>0)) { + + /* Put cross correlation and energy on 16 bit word */ + crossCorrScale=(WebRtc_Word16)WebRtcSpl_NormW32(crossCorr)-16; + crossCorrmod=(WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(crossCorr, crossCorrScale); + Energyscale=(WebRtc_Word16)WebRtcSpl_NormW32(Energy)-16; + EnergyMod=(WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(Energy, Energyscale); + + /* Square cross correlation and store upper WebRtc_Word16 */ + crossCorrSqMod=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(crossCorrmod, crossCorrmod, 16); + + /* Calculate the total number of (dynamic) right shifts that have + been performed on (crossCorr*crossCorr)/energy + */ + totscale=Energyscale-(crossCorrScale<<1); + + /* Calculate the shift difference in order to be able to compare the two + (crossCorr*crossCorr)/energy in the same domain + */ + scalediff=totscale-totscale_max; + scalediff=WEBRTC_SPL_MIN(scalediff,31); + scalediff=WEBRTC_SPL_MAX(scalediff,-31); + + /* Compute the cross multiplication between the old best criteria + and the new one to be able to compare them without using a + division */ + + if (scalediff<0) { + newCrit = ((WebRtc_Word32)crossCorrSqMod*EnergyMod_Max)>>(-scalediff); + maxCrit = ((WebRtc_Word32)crossCorrSqMod_Max*EnergyMod); + } else { + newCrit = ((WebRtc_Word32)crossCorrSqMod*EnergyMod_Max); + maxCrit = ((WebRtc_Word32)crossCorrSqMod_Max*EnergyMod)>>scalediff; + } + + /* Store the new lag value if the new criteria is larger + than previous largest criteria */ + + if (newCrit > maxCrit) { + crossCorrSqMod_Max = crossCorrSqMod; + EnergyMod_Max = EnergyMod; + totscale_max = totscale; + maxlag = k; + } + } + pos+=step; + + /* Do a +/- to get the next energy */ + Energy += step*(WEBRTC_SPL_RSHIFT_W32( + ((WebRtc_Word32)(*rp_end)*(*rp_end)) - ((WebRtc_Word32)(*rp_beg)*(*rp_beg)), + shifts)); + rp_beg+=step; + rp_end+=step; + } + + return(maxlag+offset); +} diff --git a/src/libs/webrtc/ilbcfix/xcorr_coef.h b/src/libs/webrtc/ilbcfix/xcorr_coef.h new file mode 100644 index 00000000..ac885c43 --- /dev/null +++ b/src/libs/webrtc/ilbcfix/xcorr_coef.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + WebRtcIlbcfix_XcorrCoef.h + +******************************************************************/ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_XCORR_COEF_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_XCORR_COEF_H_ + +#include "defines.h" + +/*----------------------------------------------------------------* + * cross correlation which finds the optimal lag for the + * crossCorr*crossCorr/(energy) criteria + *---------------------------------------------------------------*/ + +int WebRtcIlbcfix_XcorrCoef( + WebRtc_Word16 *target, /* (i) first array */ + WebRtc_Word16 *regressor, /* (i) second array */ + WebRtc_Word16 subl, /* (i) dimension arrays */ + WebRtc_Word16 searchLen, /* (i) the search lenght */ + WebRtc_Word16 offset, /* (i) samples offset between arrays */ + WebRtc_Word16 step /* (i) +1 or -1 */ + ); + +#endif diff --git a/src/libs/webrtc/isac/arith_routines.c b/src/libs/webrtc/isac/arith_routines.c new file mode 100644 index 00000000..ee62bad5 --- /dev/null +++ b/src/libs/webrtc/isac/arith_routines.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * arith_routins.c + * + * This C file contains a function for finalizing the bitstream + * after arithmetic coding. + * + */ + +#include "arith_routins.h" + + +/**************************************************************************** + * WebRtcIsacfix_EncTerminate(...) + * + * Final call to the arithmetic coder for an encoder call. This function + * terminates and return byte stream. + * + * Input: + * - streamData : in-/output struct containing bitstream + * + * Return value : number of bytes in the stream + */ +WebRtc_Word16 WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData) +{ + WebRtc_UWord16 *streamPtr; + WebRtc_UWord16 negCarry; + + /* point to the right place in the stream buffer */ + streamPtr = streamData->stream + streamData->stream_index; + + /* find minimum length (determined by current interval width) */ + if ( streamData->W_upper > 0x01FFFFFF ) + { + streamData->streamval += 0x01000000; + + /* if result is less than the added value we must take care of the carry */ + if (streamData->streamval < 0x01000000) + { + /* propagate carry */ + if (streamData->full == 0) { + /* Add value to current value */ + negCarry = *streamPtr; + negCarry += 0x0100; + *streamPtr = negCarry; + + /* if value is too big, propagate carry to next byte, and so on */ + while (!(negCarry)) + { + negCarry = *--streamPtr; + negCarry++; + *streamPtr = negCarry; + } + } else { + /* propagate carry by adding one to the previous byte in the + * stream if that byte is 0xFFFF we need to propagate the carry + * furhter back in the stream */ + while ( !(++(*--streamPtr)) ); + } + + /* put pointer back to the old value */ + streamPtr = streamData->stream + streamData->stream_index; + } + /* write remaining data to bitstream, if "full == 0" first byte has data */ + if (streamData->full == 0) { + *streamPtr++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24); + streamData->full = 1; + } else { + *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_W32( + WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24), 8); + streamData->full = 0; + } + } + else + { + streamData->streamval += 0x00010000; + + /* if result is less than the added value we must take care of the carry */ + if (streamData->streamval < 0x00010000) + { + /* propagate carry */ + if (streamData->full == 0) { + /* Add value to current value */ + negCarry = *streamPtr; + negCarry += 0x0100; + *streamPtr = negCarry; + + /* if value to big, propagate carry to next byte, and so on */ + while (!(negCarry)) + { + negCarry = *--streamPtr; + negCarry++; + *streamPtr = negCarry; + } + } else { + /* Add carry to previous byte */ + while ( !(++(*--streamPtr)) ); + } + + /* put pointer back to the old value */ + streamPtr = streamData->stream + streamData->stream_index; + } + /* write remaining data (2 bytes) to bitstream */ + if (streamData->full) { + *streamPtr++ = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 16); + } else { + *streamPtr++ |= (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24); + *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 8) + & 0xFF00; + } + } + + /* calculate stream length in bytes */ + return (((streamPtr - streamData->stream)<<1) + !(streamData->full)); +} diff --git a/src/libs/webrtc/isac/arith_routines_hist.c b/src/libs/webrtc/isac/arith_routines_hist.c new file mode 100644 index 00000000..14f1adda --- /dev/null +++ b/src/libs/webrtc/isac/arith_routines_hist.c @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * arith_routinshist.c + * + * This C file contains arithmetic encoding and decoding. + * + */ + +#include "arith_routins.h" + + +/**************************************************************************** + * WebRtcIsacfix_EncHistMulti(...) + * + * Encode the histogram interval + * + * Input: + * - streamData : in-/output struct containing bitstream + * - data : data vector + * - cdf : array of cdf arrays + * - lenData : data vector length + * + * Return value : 0 if ok + * <0 if error detected + */ +int WebRtcIsacfix_EncHistMulti(Bitstr_enc *streamData, + const WebRtc_Word16 *data, + const WebRtc_UWord16 **cdf, + const WebRtc_Word16 lenData) +{ + WebRtc_UWord32 W_lower; + WebRtc_UWord32 W_upper; + WebRtc_UWord32 W_upper_LSB; + WebRtc_UWord32 W_upper_MSB; + WebRtc_UWord16 *streamPtr; + WebRtc_UWord16 negCarry; + WebRtc_UWord16 *maxStreamPtr; + WebRtc_UWord16 *streamPtrCarry; + WebRtc_UWord32 cdfLo; + WebRtc_UWord32 cdfHi; + int k; + + + /* point to beginning of stream buffer + * and set maximum streamPtr value */ + streamPtr = streamData->stream + streamData->stream_index; + maxStreamPtr = streamData->stream + STREAM_MAXW16_60MS - 1; + + W_upper = streamData->W_upper; + + for (k = lenData; k > 0; k--) + { + /* fetch cdf_lower and cdf_upper from cdf tables */ + cdfLo = (WebRtc_UWord32) *(*cdf + (WebRtc_UWord32)*data); + cdfHi = (WebRtc_UWord32) *(*cdf++ + (WebRtc_UWord32)*data++ + 1); + + /* update interval */ + W_upper_LSB = W_upper & 0x0000FFFF; + W_upper_MSB = WEBRTC_SPL_RSHIFT_W32(W_upper, 16); + W_lower = WEBRTC_SPL_UMUL(W_upper_MSB, cdfLo); + W_lower += WEBRTC_SPL_UMUL_RSFT16(W_upper_LSB, cdfLo); + W_upper = WEBRTC_SPL_UMUL(W_upper_MSB, cdfHi); + W_upper += WEBRTC_SPL_UMUL_RSFT16(W_upper_LSB, cdfHi); + + /* shift interval such that it begins at zero */ + W_upper -= ++W_lower; + + /* add integer to bitstream */ + streamData->streamval += W_lower; + + /* handle carry */ + if (streamData->streamval < W_lower) + { + /* propagate carry */ + streamPtrCarry = streamPtr; + if (streamData->full == 0) { + negCarry = *streamPtrCarry; + negCarry += 0x0100; + *streamPtrCarry = negCarry; + while (!(negCarry)) + { + negCarry = *--streamPtrCarry; + negCarry++; + *streamPtrCarry = negCarry; + } + } else { + while ( !(++(*--streamPtrCarry)) ); + } + } + + /* renormalize interval, store most significant byte of streamval and update streamval + * W_upper < 2^24 */ + while ( !(W_upper & 0xFF000000) ) + { + W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8); + if (streamData->full == 0) { + *streamPtr++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24); + streamData->full = 1; + } else { + *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_W32( + WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24), 8); + streamData->full = 0; + } + + if( streamPtr > maxStreamPtr ) { + return -ISAC_DISALLOWED_BITSTREAM_LENGTH; + } + streamData->streamval = WEBRTC_SPL_LSHIFT_W32(streamData->streamval, 8); + } + } + + /* calculate new stream_index */ + streamData->stream_index = streamPtr - streamData->stream; + streamData->W_upper = W_upper; + + return 0; +} + + +/**************************************************************************** + * WebRtcIsacfix_DecHistBisectMulti(...) + * + * Function to decode more symbols from the arithmetic bytestream, using + * method of bisection cdf tables should be of size 2^k-1 (which corresponds + * to an alphabet size of 2^k-2) + * + * Input: + * - streamData : in-/output struct containing bitstream + * - cdf : array of cdf arrays + * - cdfSize : array of cdf table sizes+1 (power of two: 2^k) + * - lenData : data vector length + * + * Output: + * - data : data vector + * + * Return value : number of bytes in the stream + * <0 if error detected + */ +WebRtc_Word16 WebRtcIsacfix_DecHistBisectMulti(WebRtc_Word16 *data, + Bitstr_dec *streamData, + const WebRtc_UWord16 **cdf, + const WebRtc_UWord16 *cdfSize, + const WebRtc_Word16 lenData) +{ + WebRtc_UWord32 W_lower = 0; + WebRtc_UWord32 W_upper; + WebRtc_UWord32 W_tmp; + WebRtc_UWord32 W_upper_LSB; + WebRtc_UWord32 W_upper_MSB; + WebRtc_UWord32 streamval; + const WebRtc_UWord16 *streamPtr; + const WebRtc_UWord16 *cdfPtr; + WebRtc_Word16 sizeTmp; + int k; + + + streamPtr = streamData->stream + streamData->stream_index; + W_upper = streamData->W_upper; + + /* Error check: should not be possible in normal operation */ + if (W_upper == 0) { + return -2; + } + + /* first time decoder is called for this stream */ + if (streamData->stream_index == 0) + { + /* read first word from bytestream */ + streamval = WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)*streamPtr++, 16); + streamval |= *streamPtr++; + } else { + streamval = streamData->streamval; + } + + for (k = lenData; k > 0; k--) + { + /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */ + W_upper_LSB = W_upper & 0x0000FFFF; + W_upper_MSB = WEBRTC_SPL_RSHIFT_W32(W_upper, 16); + + /* start halfway the cdf range */ + sizeTmp = WEBRTC_SPL_RSHIFT_W16(*cdfSize++, 1); + cdfPtr = *cdf + (sizeTmp - 1); + + /* method of bisection */ + for ( ;; ) + { + W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr); + W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr); + sizeTmp = WEBRTC_SPL_RSHIFT_W16(sizeTmp, 1); + if (sizeTmp == 0) { + break; + } + + if (streamval > W_tmp) + { + W_lower = W_tmp; + cdfPtr += sizeTmp; + } else { + W_upper = W_tmp; + cdfPtr -= sizeTmp; + } + } + if (streamval > W_tmp) + { + W_lower = W_tmp; + *data++ = cdfPtr - *cdf++; + } else { + W_upper = W_tmp; + *data++ = cdfPtr - *cdf++ - 1; + } + + /* shift interval to start at zero */ + W_upper -= ++W_lower; + + /* add integer to bitstream */ + streamval -= W_lower; + + /* renormalize interval and update streamval */ + /* W_upper < 2^24 */ + while ( !(W_upper & 0xFF000000) ) + { + /* read next byte from stream */ + if (streamData->full == 0) { + streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) | + (*streamPtr++ & 0x00FF); + streamData->full = 1; + } else { + streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) | + WEBRTC_SPL_RSHIFT_W16(*streamPtr, 8); + streamData->full = 0; + } + W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8); + } + + + /* Error check: should not be possible in normal operation */ + if (W_upper == 0) { + return -2; + } + + } + + streamData->stream_index = streamPtr - streamData->stream; + streamData->W_upper = W_upper; + streamData->streamval = streamval; + + if ( W_upper > 0x01FFFFFF ) { + return (streamData->stream_index*2 - 3 + !streamData->full); + } else { + return (streamData->stream_index*2 - 2 + !streamData->full); + } +} + + +/**************************************************************************** + * WebRtcIsacfix_DecHistOneStepMulti(...) + * + * Function to decode more symbols from the arithmetic bytestream, taking + * single step up or down at a time. + * cdf tables can be of arbitrary size, but large tables may take a lot of + * iterations. + * + * Input: + * - streamData : in-/output struct containing bitstream + * - cdf : array of cdf arrays + * - initIndex : vector of initial cdf table search entries + * - lenData : data vector length + * + * Output: + * - data : data vector + * + * Return value : number of bytes in original stream + * <0 if error detected + */ +WebRtc_Word16 WebRtcIsacfix_DecHistOneStepMulti(WebRtc_Word16 *data, + Bitstr_dec *streamData, + const WebRtc_UWord16 **cdf, + const WebRtc_UWord16 *initIndex, + const WebRtc_Word16 lenData) +{ + WebRtc_UWord32 W_lower; + WebRtc_UWord32 W_upper; + WebRtc_UWord32 W_tmp; + WebRtc_UWord32 W_upper_LSB; + WebRtc_UWord32 W_upper_MSB; + WebRtc_UWord32 streamval; + const WebRtc_UWord16 *streamPtr; + const WebRtc_UWord16 *cdfPtr; + int k; + + + streamPtr = streamData->stream + streamData->stream_index; + W_upper = streamData->W_upper; + /* Error check: Should not be possible in normal operation */ + if (W_upper == 0) { + return -2; + } + + /* Check if it is the first time decoder is called for this stream */ + if (streamData->stream_index == 0) + { + /* read first word from bytestream */ + streamval = WEBRTC_SPL_LSHIFT_U32(*streamPtr++, 16); + streamval |= *streamPtr++; + } else { + streamval = streamData->streamval; + } + + for (k = lenData; k > 0; k--) + { + /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */ + W_upper_LSB = W_upper & 0x0000FFFF; + W_upper_MSB = WEBRTC_SPL_RSHIFT_U32(W_upper, 16); + + /* start at the specified table entry */ + cdfPtr = *cdf + (*initIndex++); + W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr); + W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr); + + if (streamval > W_tmp) + { + for ( ;; ) + { + W_lower = W_tmp; + + /* range check */ + if (cdfPtr[0] == 65535) { + return -3; + } + + W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *++cdfPtr); + W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr); + + if (streamval <= W_tmp) { + break; + } + } + W_upper = W_tmp; + *data++ = cdfPtr - *cdf++ - 1; + } else { + for ( ;; ) + { + W_upper = W_tmp; + --cdfPtr; + + /* range check */ + if (cdfPtr < *cdf) { + return -3; + } + + W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr); + W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr); + + if (streamval > W_tmp) { + break; + } + } + W_lower = W_tmp; + *data++ = cdfPtr - *cdf++; + } + + /* shift interval to start at zero */ + W_upper -= ++W_lower; + + /* add integer to bitstream */ + streamval -= W_lower; + + /* renormalize interval and update streamval */ + /* W_upper < 2^24 */ + while ( !(W_upper & 0xFF000000) ) + { + /* read next byte from stream */ + if (streamData->full == 0) { + streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) | (*streamPtr++ & 0x00FF); + streamData->full = 1; + } else { + streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) | (*streamPtr >> 8); + streamData->full = 0; + } + W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8); + } + } + + streamData->stream_index = streamPtr - streamData->stream; + streamData->W_upper = W_upper; + streamData->streamval = streamval; + + /* find number of bytes in original stream (determined by current interval width) */ + if ( W_upper > 0x01FFFFFF ) { + return (streamData->stream_index*2 - 3 + !streamData->full); + } else { + return (streamData->stream_index*2 - 2 + !streamData->full); + } +} diff --git a/src/libs/webrtc/isac/arith_routines_logist.c b/src/libs/webrtc/isac/arith_routines_logist.c new file mode 100644 index 00000000..39c437e5 --- /dev/null +++ b/src/libs/webrtc/isac/arith_routines_logist.c @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * arith_routinslogist.c + * + * This C file contains arithmetic encode and decode logistic + * + */ + +#include "arith_routins.h" + + +/* Tables for piecewise linear cdf functions: y = k*x */ + +/* x Points for function piecewise() in Q15 */ +static const WebRtc_Word32 kHistEdges[51] = { + -327680, -314573, -301466, -288359, -275252, -262144, -249037, -235930, -222823, -209716, + -196608, -183501, -170394, -157287, -144180, -131072, -117965, -104858, -91751, -78644, + -65536, -52429, -39322, -26215, -13108, 0, 13107, 26214, 39321, 52428, + 65536, 78643, 91750, 104857, 117964, 131072, 144179, 157286, 170393, 183500, + 196608, 209715, 222822, 235929, 249036, 262144, 275251, 288358, 301465, 314572, + 327680 +}; + + +/* k Points for function piecewise() in Q0 */ +static const WebRtc_UWord16 kCdfSlope[51] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 13, 23, 47, 87, 154, 315, 700, 1088, + 2471, 6064, 14221, 21463, 36634, 36924, 19750, 13270, 5806, 2312, + 1095, 660, 316, 145, 86, 41, 32, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, + 0 +}; + +/* y Points for function piecewise() in Q0 */ +static const WebRtc_UWord16 kCdfLogistic[51] = { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, + 20, 22, 24, 29, 38, 57, 92, 153, 279, 559, + 994, 1983, 4408, 10097, 18682, 33336, 48105, 56005, 61313, 63636, + 64560, 64998, 65262, 65389, 65447, 65481, 65497, 65510, 65512, 65514, + 65516, 65518, 65520, 65522, 65524, 65526, 65528, 65530, 65532, 65534, + 65535 +}; + + +/**************************************************************************** + * WebRtcIsacfix_Piecewise(...) + * + * Piecewise linear function + * + * Input: + * - xinQ15 : input value x in Q15 + * + * Return value : korresponding y-value in Q0 + */ + + +static __inline WebRtc_UWord16 WebRtcIsacfix_Piecewise(WebRtc_Word32 xinQ15) { + WebRtc_Word32 ind; + WebRtc_Word32 qtmp1; + WebRtc_UWord16 qtmp2; + + /* Find index for x-value */ + qtmp1 = WEBRTC_SPL_SAT(kHistEdges[50],xinQ15,kHistEdges[0]); + ind = WEBRTC_SPL_MUL(5, qtmp1 - kHistEdges[0]); + ind = WEBRTC_SPL_RSHIFT_W32(ind, 16); + + /* Calculate corresponding y-value ans return*/ + qtmp1 = qtmp1 - kHistEdges[ind]; + qtmp2 = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32( + WEBRTC_SPL_UMUL_32_16(qtmp1,kCdfSlope[ind]), 15); + return (kCdfLogistic[ind] + qtmp2); +} + +/**************************************************************************** + * WebRtcIsacfix_EncLogisticMulti2(...) + * + * Arithmetic coding of spectrum. + * + * Input: + * - streamData : in-/output struct containing bitstream + * - dataQ7 : data vector in Q7 + * - envQ8 : side info vector defining the width of the pdf + * in Q8 + * - lenData : data vector length + * + * Return value : 0 if ok, + * <0 otherwise. + */ +int WebRtcIsacfix_EncLogisticMulti2(Bitstr_enc *streamData, + WebRtc_Word16 *dataQ7, + const WebRtc_UWord16 *envQ8, + const WebRtc_Word16 lenData) +{ + WebRtc_UWord32 W_lower; + WebRtc_UWord32 W_upper; + WebRtc_UWord16 W_upper_LSB; + WebRtc_UWord16 W_upper_MSB; + WebRtc_UWord16 *streamPtr; + WebRtc_UWord16 *maxStreamPtr; + WebRtc_UWord16 *streamPtrCarry; + WebRtc_UWord16 negcarry; + WebRtc_UWord32 cdfLo; + WebRtc_UWord32 cdfHi; + int k; + + /* point to beginning of stream buffer + * and set maximum streamPtr value */ + streamPtr = streamData->stream + streamData->stream_index; + maxStreamPtr = streamData->stream + STREAM_MAXW16_60MS - 1; + W_upper = streamData->W_upper; + + for (k = 0; k < lenData; k++) + { + /* compute cdf_lower and cdf_upper by evaluating the + * WebRtcIsacfix_Piecewise linear cdf */ + cdfLo = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(*dataQ7 - 64, *envQ8)); + cdfHi = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(*dataQ7 + 64, *envQ8)); + + /* test and clip if probability gets too small */ + while ((cdfLo + 1) >= cdfHi) { + /* clip */ + if (*dataQ7 > 0) { + *dataQ7 -= 128; + cdfHi = cdfLo; + cdfLo = WebRtcIsacfix_Piecewise( + WEBRTC_SPL_MUL_16_U16(*dataQ7 - 64, *envQ8)); + } else { + *dataQ7 += 128; + cdfLo = cdfHi; + cdfHi = WebRtcIsacfix_Piecewise( + WEBRTC_SPL_MUL_16_U16(*dataQ7 + 64, *envQ8)); + } + } + + dataQ7++; + /* increment only once per 4 iterations */ + envQ8 += (k & 1) & (k >> 1); + + + /* update interval */ + W_upper_LSB = (WebRtc_UWord16)W_upper; + W_upper_MSB = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32(W_upper, 16); + W_lower = WEBRTC_SPL_UMUL_32_16(cdfLo, W_upper_MSB); + W_lower += WEBRTC_SPL_UMUL_32_16_RSFT16(cdfLo, W_upper_LSB); + W_upper = WEBRTC_SPL_UMUL_32_16(cdfHi, W_upper_MSB); + W_upper += WEBRTC_SPL_UMUL_32_16_RSFT16(cdfHi, W_upper_LSB); + + /* shift interval such that it begins at zero */ + W_upper -= ++W_lower; + + /* add integer to bitstream */ + streamData->streamval += W_lower; + + /* handle carry */ + if (streamData->streamval < W_lower) + { + /* propagate carry */ + streamPtrCarry = streamPtr; + if (streamData->full == 0) { + negcarry = *streamPtrCarry; + negcarry += 0x0100; + *streamPtrCarry = negcarry; + while (!(negcarry)) + { + negcarry = *--streamPtrCarry; + negcarry++; + *streamPtrCarry = negcarry; + } + } else { + while (!(++(*--streamPtrCarry))); + } + } + + /* renormalize interval, store most significant byte of streamval and update streamval + * W_upper < 2^24 */ + while ( !(W_upper & 0xFF000000) ) + { + W_upper = WEBRTC_SPL_LSHIFT_U32(W_upper, 8); + if (streamData->full == 0) { + *streamPtr++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_U32( + streamData->streamval, 24); + streamData->full = 1; + } else { + *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_U32( + WEBRTC_SPL_RSHIFT_U32(streamData->streamval, 24), 8); + streamData->full = 0; + } + + if( streamPtr > maxStreamPtr ) + return -ISAC_DISALLOWED_BITSTREAM_LENGTH; + + streamData->streamval = WEBRTC_SPL_LSHIFT_U32(streamData->streamval, 8); + } + } + + /* calculate new stream_index */ + streamData->stream_index = streamPtr - streamData->stream; + streamData->W_upper = W_upper; + + return 0; +} + + +/**************************************************************************** + * WebRtcIsacfix_DecLogisticMulti2(...) + * + * Arithmetic decoding of spectrum. + * + * Input: + * - streamData : in-/output struct containing bitstream + * - envQ8 : side info vector defining the width of the pdf + * in Q8 + * - lenData : data vector length + * + * Input/Output: + * - dataQ7 : input: dither vector, output: data vector + * + * Return value : number of bytes in the stream so far + * -1 if error detected + */ +WebRtc_Word16 WebRtcIsacfix_DecLogisticMulti2(WebRtc_Word16 *dataQ7, + Bitstr_dec *streamData, + const WebRtc_Word32 *envQ8, + const WebRtc_Word16 lenData) +{ + WebRtc_UWord32 W_lower; + WebRtc_UWord32 W_upper; + WebRtc_UWord32 W_tmp; + WebRtc_UWord16 W_upper_LSB; + WebRtc_UWord16 W_upper_MSB; + WebRtc_UWord32 streamVal; + WebRtc_UWord16 cdfTmp; + WebRtc_Word32 res; + WebRtc_Word32 inSqrt; + WebRtc_Word32 newRes; + const WebRtc_UWord16 *streamPtr; + WebRtc_Word16 candQ7; + WebRtc_Word16 envCount; + WebRtc_UWord16 tmpARSpecQ8 = 0; + int k, i; + + + /* point to beginning of stream buffer */ + streamPtr = streamData->stream + streamData->stream_index; + W_upper = streamData->W_upper; + + /* Check if it is first time decoder is called for this stream */ + if (streamData->stream_index == 0) + { + /* read first word from bytestream */ + streamVal = WEBRTC_SPL_LSHIFT_U32(*streamPtr++, 16); + streamVal |= *streamPtr++; + + } else { + streamVal = streamData->streamval; + } + + + res = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, + WEBRTC_SPL_RSHIFT_W16(WebRtcSpl_GetSizeInBits(envQ8[0]), 1)); + envCount = 0; + + /* code assumes lenData%4 == 0 */ + for (k = 0; k < lenData; k += 4) + { + int k4; + + /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ + inSqrt = envQ8[envCount]; + i = 10; + + /* For safty reasons */ + if (inSqrt < 0) + inSqrt=-inSqrt; + + newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(inSqrt, res) + res, 1); + do + { + res = newRes; + newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(inSqrt, res) + res, 1); + } while (newRes != res && i-- > 0); + + tmpARSpecQ8 = (WebRtc_UWord16)newRes; + + for(k4 = 0; k4 < 4; k4++) + { + /* find the integer *data for which streamVal lies in [W_lower+1, W_upper] */ + W_upper_LSB = (WebRtc_UWord16) (W_upper & 0x0000FFFF); + W_upper_MSB = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_U32(W_upper, 16); + + /* find first candidate by inverting the logistic cdf + * Input dither value collected from io-stream */ + candQ7 = - *dataQ7 + 64; + cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8)); + + W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB); + W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB); + + if (streamVal > W_tmp) + { + W_lower = W_tmp; + candQ7 += 128; + cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8)); + + W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB); + W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB); + + while (streamVal > W_tmp) + { + W_lower = W_tmp; + candQ7 += 128; + cdfTmp = WebRtcIsacfix_Piecewise( + WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8)); + + W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB); + W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB); + + /* error check */ + if (W_lower == W_tmp) { + return -1; + } + } + W_upper = W_tmp; + + /* Output value put in dataQ7: another sample decoded */ + *dataQ7 = candQ7 - 64; + } + else + { + W_upper = W_tmp; + candQ7 -= 128; + cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8)); + + W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB); + W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB); + + while ( !(streamVal > W_tmp) ) + { + W_upper = W_tmp; + candQ7 -= 128; + cdfTmp = WebRtcIsacfix_Piecewise( + WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8)); + + W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB); + W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB); + + /* error check */ + if (W_upper == W_tmp){ + return -1; + } + } + W_lower = W_tmp; + + /* Output value put in dataQ7: another sample decoded */ + *dataQ7 = candQ7 + 64; + } + + dataQ7++; + + /* shift interval to start at zero */ + W_upper -= ++W_lower; + + /* add integer to bitstream */ + streamVal -= W_lower; + + /* renormalize interval and update streamVal + * W_upper < 2^24 */ + while ( !(W_upper & 0xFF000000) ) + { + /* read next byte from stream */ + if (streamData->full == 0) { + streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8) | (*streamPtr++ & 0x00FF); + streamData->full = 1; + } else { + streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8) | + WEBRTC_SPL_RSHIFT_U16(*streamPtr, 8); + streamData->full = 0; + } + W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8); + } + } + envCount++; + } + + streamData->stream_index = streamPtr - streamData->stream; + streamData->W_upper = W_upper; + streamData->streamval = streamVal; + + /* find number of bytes in original stream (determined by current interval width) */ + if ( W_upper > 0x01FFFFFF ) + return (streamData->stream_index*2 - 3 + !streamData->full); + else + return (streamData->stream_index*2 - 2 + !streamData->full); +} diff --git a/src/libs/webrtc/isac/arith_routins.h b/src/libs/webrtc/isac/arith_routins.h new file mode 100644 index 00000000..9aa49dac --- /dev/null +++ b/src/libs/webrtc/isac/arith_routins.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * arith_routins.h + * + * Functions for arithmetic coding. + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ARITH_ROUTINS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ARITH_ROUTINS_H_ + +#include "structs.h" + + +/**************************************************************************** + * WebRtcIsacfix_EncLogisticMulti2(...) + * + * Arithmetic coding of spectrum. + * + * Input: + * - streamData : in-/output struct containing bitstream + * - dataQ7 : data vector in Q7 + * - envQ8 : side info vector defining the width of the pdf + * in Q8 + * - lenData : data vector length + * + * Return value : 0 if ok, + * <0 otherwise. + */ +int WebRtcIsacfix_EncLogisticMulti2( + Bitstr_enc *streamData, + WebRtc_Word16 *dataQ7, + const WebRtc_UWord16 *env, + const WebRtc_Word16 lenData); + + +/**************************************************************************** + * WebRtcIsacfix_EncTerminate(...) + * + * Final call to the arithmetic coder for an encoder call. This function + * terminates and return byte stream. + * + * Input: + * - streamData : in-/output struct containing bitstream + * + * Return value : number of bytes in the stream + */ +WebRtc_Word16 WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData); + + +/**************************************************************************** + * WebRtcIsacfix_DecLogisticMulti2(...) + * + * Arithmetic decoding of spectrum. + * + * Input: + * - streamData : in-/output struct containing bitstream + * - envQ8 : side info vector defining the width of the pdf + * in Q8 + * - lenData : data vector length + * + * Input/Output: + * - dataQ7 : input: dither vector, output: data vector, in Q7 + * + * Return value : number of bytes in the stream so far + * <0 if error detected + */ +WebRtc_Word16 WebRtcIsacfix_DecLogisticMulti2( + WebRtc_Word16 *data, + Bitstr_dec *streamData, + const WebRtc_Word32 *env, + const WebRtc_Word16 lenData); + + +/**************************************************************************** + * WebRtcIsacfix_EncHistMulti(...) + * + * Encode the histogram interval + * + * Input: + * - streamData : in-/output struct containing bitstream + * - data : data vector + * - cdf : array of cdf arrays + * - lenData : data vector length + * + * Return value : 0 if ok + * <0 if error detected + */ +int WebRtcIsacfix_EncHistMulti( + Bitstr_enc *streamData, + const WebRtc_Word16 *data, + const WebRtc_UWord16 **cdf, + const WebRtc_Word16 lenData); + + +/**************************************************************************** + * WebRtcIsacfix_DecHistBisectMulti(...) + * + * Function to decode more symbols from the arithmetic bytestream, using + * method of bisection. + * C df tables should be of size 2^k-1 (which corresponds to an + * alphabet size of 2^k-2) + * + * Input: + * - streamData : in-/output struct containing bitstream + * - cdf : array of cdf arrays + * - cdfSize : array of cdf table sizes+1 (power of two: 2^k) + * - lenData : data vector length + * + * Output: + * - data : data vector + * + * Return value : number of bytes in the stream + * <0 if error detected + */ +WebRtc_Word16 WebRtcIsacfix_DecHistBisectMulti( + WebRtc_Word16 *data, + Bitstr_dec *streamData, + const WebRtc_UWord16 **cdf, + const WebRtc_UWord16 *cdfSize, + const WebRtc_Word16 lenData); + + +/**************************************************************************** + * WebRtcIsacfix_DecHistOneStepMulti(...) + * + * Function to decode more symbols from the arithmetic bytestream, taking + * single step up or down at a time. + * cdf tables can be of arbitrary size, but large tables may take a lot of + * iterations. + * + * Input: + * - streamData : in-/output struct containing bitstream + * - cdf : array of cdf arrays + * - initIndex : vector of initial cdf table search entries + * - lenData : data vector length + * + * Output: + * - data : data vector + * + * Return value : number of bytes in original stream + * <0 if error detected + */ +WebRtc_Word16 WebRtcIsacfix_DecHistOneStepMulti( + WebRtc_Word16 *data, + Bitstr_dec *streamData, + const WebRtc_UWord16 **cdf, + const WebRtc_UWord16 *initIndex, + const WebRtc_Word16 lenData); + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ARITH_ROUTINS_H_ */ diff --git a/src/libs/webrtc/isac/bandwidth_estimator.c b/src/libs/webrtc/isac/bandwidth_estimator.c new file mode 100644 index 00000000..a274b667 --- /dev/null +++ b/src/libs/webrtc/isac/bandwidth_estimator.c @@ -0,0 +1,1022 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * bandwidth_estimator.c + * + * This file contains the code for the Bandwidth Estimator designed + * for iSAC. + * + * NOTE! Castings needed for C55, do not remove! + * + */ + +#include "bandwidth_estimator.h" +#include "settings.h" + + +/* array of quantization levels for bottle neck info; Matlab code: */ +/* sprintf('%4.1ff, ', logspace(log10(5000), log10(40000), 12)) */ +static const WebRtc_Word16 kQRateTable[12] = { + 10000, 11115, 12355, 13733, 15265, 16967, + 18860, 20963, 23301, 25900, 28789, 32000 +}; + +/* 0.1 times the values in the table kQRateTable */ +/* values are in Q16 */ +static const WebRtc_Word32 KQRate01[12] = { + 65536000, 72843264, 80969728, 90000589, 100040704, 111194931, + 123600896, 137383117, 152705434, 169738240, 188671590, 209715200 +}; + +/* Bits per Bytes Seconds + * 8 bits/byte * 1000 msec/sec * 1/framelength (in msec)->bits/byte*sec + * frame length will either be 30 or 60 msec. 8738 is 1/60 in Q19 and 1/30 in Q18 + * The following number is either in Q15 or Q14 depending on the current frame length */ +static const WebRtc_Word32 kBitsByteSec = 4369000; + +/* Received header rate. First value is for 30 ms packets and second for 60 ms */ +static const WebRtc_Word16 kRecHeaderRate[2] = { + 9333, 4666 +}; + +/* Inverted minimum and maximum bandwidth in Q30. + minBwInv 30 ms, maxBwInv 30 ms, + minBwInv 60 ms, maxBwInv 69 ms +*/ +static const WebRtc_Word32 kInvBandwidth[4] = { + 55539, 25978, + 73213, 29284 +}; + +/* Number of samples in 25 msec */ +static const WebRtc_Word32 kSamplesIn25msec = 400; + + +/**************************************************************************** + * WebRtcIsacfix_InitBandwidthEstimator(...) + * + * This function initializes the struct for the bandwidth estimator + * + * Input/Output: + * - bweStr : Struct containing bandwidth information. + * + * Return value : 0 + */ +WebRtc_Word32 WebRtcIsacfix_InitBandwidthEstimator(BwEstimatorstr *bweStr) +{ + bweStr->prevFrameSizeMs = INIT_FRAME_LEN; + bweStr->prevRtpNumber = 0; + bweStr->prevSendTime = 0; + bweStr->prevArrivalTime = 0; + bweStr->prevRtpRate = 1; + bweStr->lastUpdate = 0; + bweStr->lastReduction = 0; + bweStr->countUpdates = -9; + + /* INIT_BN_EST = 20000 + * INIT_BN_EST_Q7 = 2560000 + * INIT_HDR_RATE = 4666 + * INIT_REC_BN_EST_Q5 = 789312 + * + * recBwInv = 1/(INIT_BN_EST + INIT_HDR_RATE) in Q30 + * recBwAvg = INIT_BN_EST + INIT_HDR_RATE in Q5 + */ + bweStr->recBwInv = 43531; + bweStr->recBw = INIT_BN_EST; + bweStr->recBwAvgQ = INIT_BN_EST_Q7; + bweStr->recBwAvg = INIT_REC_BN_EST_Q5; + bweStr->recJitter = (WebRtc_Word32) 327680; /* 10 in Q15 */ + bweStr->recJitterShortTerm = 0; + bweStr->recJitterShortTermAbs = (WebRtc_Word32) 40960; /* 5 in Q13 */ + bweStr->recMaxDelay = (WebRtc_Word32) 10; + bweStr->recMaxDelayAvgQ = (WebRtc_Word32) 5120; /* 10 in Q9 */ + bweStr->recHeaderRate = INIT_HDR_RATE; + bweStr->countRecPkts = 0; + bweStr->sendBwAvg = INIT_BN_EST_Q7; + bweStr->sendMaxDelayAvg = (WebRtc_Word32) 5120; /* 10 in Q9 */ + + bweStr->countHighSpeedRec = 0; + bweStr->highSpeedRec = 0; + bweStr->countHighSpeedSent = 0; + bweStr->highSpeedSend = 0; + bweStr->inWaitPeriod = 0; + + /* Find the inverse of the max bw and min bw in Q30 + * (1 / (MAX_ISAC_BW + INIT_HDR_RATE) in Q30 + * (1 / (MIN_ISAC_BW + INIT_HDR_RATE) in Q30 + */ + bweStr->maxBwInv = kInvBandwidth[3]; + bweStr->minBwInv = kInvBandwidth[2]; + + return 0; +} + +/**************************************************************************** + * WebRtcIsacfix_UpdateUplinkBwImpl(...) + * + * This function updates bottle neck rate received from other side in payload + * and calculates a new bottle neck to send to the other side. + * + * Input/Output: + * - bweStr : struct containing bandwidth information. + * - rtpNumber : value from RTP packet, from NetEq + * - frameSize : length of signal frame in ms, from iSAC decoder + * - sendTime : value in RTP header giving send time in samples + * - arrivalTime : value given by timeGetTime() time of arrival in + * samples of packet from NetEq + * - pksize : size of packet in bytes, from NetEq + * - Index : integer (range 0...23) indicating bottle neck & + * jitter as estimated by other side + * + * Return value : 0 if everything went fine, + * -1 otherwise + */ +WebRtc_Word32 WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr, + const WebRtc_UWord16 rtpNumber, + const WebRtc_Word16 frameSize, + const WebRtc_UWord32 sendTime, + const WebRtc_UWord32 arrivalTime, + const WebRtc_Word16 pksize, + const WebRtc_UWord16 Index) +{ + WebRtc_UWord16 weight = 0; + WebRtc_UWord32 currBwInv = 0; + WebRtc_UWord16 recRtpRate; + WebRtc_UWord32 arrTimeProj; + WebRtc_Word32 arrTimeDiff; + WebRtc_Word32 arrTimeNoise; + WebRtc_Word32 arrTimeNoiseAbs; + WebRtc_Word32 sendTimeDiff; + + WebRtc_Word32 delayCorrFactor = DELAY_CORRECTION_MED; + WebRtc_Word32 lateDiff = 0; + WebRtc_Word16 immediateSet = 0; + WebRtc_Word32 frameSizeSampl; + + WebRtc_Word32 temp; + WebRtc_Word32 msec; + WebRtc_UWord32 exponent; + WebRtc_UWord32 reductionFactor; + WebRtc_UWord32 numBytesInv; + WebRtc_Word32 sign; + + WebRtc_UWord32 byteSecondsPerBit; + WebRtc_UWord32 tempLower; + WebRtc_UWord32 tempUpper; + WebRtc_Word32 recBwAvgInv; + WebRtc_Word32 numPktsExpected; + + WebRtc_Word16 errCode; + + /* UPDATE ESTIMATES FROM OTHER SIDE */ + + /* The function also checks if Index has a valid value */ + errCode = WebRtcIsacfix_UpdateUplinkBwRec(bweStr, Index); + if (errCode <0) { + return(errCode); + } + + + /* UPDATE ESTIMATES ON THIS SIDE */ + + /* Bits per second per byte * 1/30 or 1/60 */ + if (frameSize == 60) { + /* If frameSize changed since last call, from 30 to 60, recalculate some values */ + if ( (frameSize != bweStr->prevFrameSizeMs) && (bweStr->countUpdates > 0)) { + bweStr->countUpdates = 10; + bweStr->recHeaderRate = kRecHeaderRate[1]; + + bweStr->maxBwInv = kInvBandwidth[3]; + bweStr->minBwInv = kInvBandwidth[2]; + bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, (bweStr->recBw + bweStr->recHeaderRate)); + } + + /* kBitsByteSec is in Q15 */ + recRtpRate = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(kBitsByteSec, + (WebRtc_Word32)pksize), 15) + bweStr->recHeaderRate; + + } else { + /* If frameSize changed since last call, from 60 to 30, recalculate some values */ + if ( (frameSize != bweStr->prevFrameSizeMs) && (bweStr->countUpdates > 0)) { + bweStr->countUpdates = 10; + bweStr->recHeaderRate = kRecHeaderRate[0]; + + bweStr->maxBwInv = kInvBandwidth[1]; + bweStr->minBwInv = kInvBandwidth[0]; + bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, (bweStr->recBw + bweStr->recHeaderRate)); + } + + /* kBitsByteSec is in Q14 */ + recRtpRate = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(kBitsByteSec, + (WebRtc_Word32)pksize), 14) + bweStr->recHeaderRate; + } + + + /* Check for timer wrap-around */ + if (arrivalTime < bweStr->prevArrivalTime) { + bweStr->prevArrivalTime = arrivalTime; + bweStr->lastUpdate = arrivalTime; + bweStr->lastReduction = arrivalTime + FS3; + + bweStr->countRecPkts = 0; + + /* store frame size */ + bweStr->prevFrameSizeMs = frameSize; + + /* store far-side transmission rate */ + bweStr->prevRtpRate = recRtpRate; + + /* store far-side RTP time stamp */ + bweStr->prevRtpNumber = rtpNumber; + + return 0; + } + + bweStr->countRecPkts++; + + /* Calculate framesize in msec */ + frameSizeSampl = WEBRTC_SPL_MUL_16_16((WebRtc_Word16)SAMPLES_PER_MSEC, frameSize); + + /* Check that it's not one of the first 9 packets */ + if ( bweStr->countUpdates > 0 ) { + + /* Stay in Wait Period for 1.5 seconds (no updates in wait period) */ + if(bweStr->inWaitPeriod) { + if ((arrivalTime - bweStr->startWaitPeriod)> FS_1_HALF) { + bweStr->inWaitPeriod = 0; + } + } + + /* If not been updated for a long time, reduce the BN estimate */ + + /* Check send time difference between this packet and previous received */ + sendTimeDiff = sendTime - bweStr->prevSendTime; + if (sendTimeDiff <= WEBRTC_SPL_LSHIFT_W32(frameSizeSampl, 1)) { + + /* Only update if 3 seconds has past since last update */ + if ((arrivalTime - bweStr->lastUpdate) > FS3) { + + /* Calculate expected number of received packets since last update */ + numPktsExpected = WEBRTC_SPL_UDIV(arrivalTime - bweStr->lastUpdate, frameSizeSampl); + + /* If received number of packets is more than 90% of expected (922 = 0.9 in Q10): */ + /* do the update, else not */ + if(WEBRTC_SPL_LSHIFT_W32(bweStr->countRecPkts, 10) > WEBRTC_SPL_MUL_16_16(922, numPktsExpected)) { + /* Q4 chosen to approx dividing by 16 */ + msec = (arrivalTime - bweStr->lastReduction); + + /* the number below represents 13 seconds, highly unlikely + but to insure no overflow when reduction factor is multiplied by recBw inverse */ + if (msec > 208000) { + msec = 208000; + } + + /* Q20 2^(negative number: - 76/1048576) = .99995 + product is Q24 */ + exponent = WEBRTC_SPL_UMUL(0x0000004C, msec); + + /* do the approx with positive exponent so that value is actually rf^-1 + and multiply by bw inverse */ + reductionFactor = WEBRTC_SPL_RSHIFT_U32(0x01000000 | (exponent & 0x00FFFFFF), + WEBRTC_SPL_RSHIFT_U32(exponent, 24)); + + /* reductionFactor in Q13 */ + reductionFactor = WEBRTC_SPL_RSHIFT_U32(reductionFactor, 11); + + if ( reductionFactor != 0 ) { + bweStr->recBwInv = WEBRTC_SPL_MUL((WebRtc_Word32)bweStr->recBwInv, (WebRtc_Word32)reductionFactor); + bweStr->recBwInv = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)bweStr->recBwInv, 13); + + } else { + /* recBwInv = 1 / (INIT_BN_EST + INIT_HDR_RATE) in Q26 (Q30??)*/ + bweStr->recBwInv = WEBRTC_SPL_DIV((1073741824 + + WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)INIT_BN_EST + INIT_HDR_RATE), 1)), INIT_BN_EST + INIT_HDR_RATE); + } + + /* reset time-since-update counter */ + bweStr->lastReduction = arrivalTime; + } else { + /* Delay last reduction with 3 seconds */ + bweStr->lastReduction = arrivalTime + FS3; + bweStr->lastUpdate = arrivalTime; + bweStr->countRecPkts = 0; + } + } + } else { + bweStr->lastReduction = arrivalTime + FS3; + bweStr->lastUpdate = arrivalTime; + bweStr->countRecPkts = 0; + } + + + /* update only if previous packet was not lost */ + if ( rtpNumber == bweStr->prevRtpNumber + 1 ) { + arrTimeDiff = arrivalTime - bweStr->prevArrivalTime; + + if (!(bweStr->highSpeedSend && bweStr->highSpeedRec)) { + if (arrTimeDiff > frameSizeSampl) { + if (sendTimeDiff > 0) { + lateDiff = arrTimeDiff - sendTimeDiff - + WEBRTC_SPL_LSHIFT_W32(frameSizeSampl, 1); + } else { + lateDiff = arrTimeDiff - frameSizeSampl; + } + + /* 8000 is 1/2 second (in samples at FS) */ + if (lateDiff > 8000) { + delayCorrFactor = (WebRtc_Word32) DELAY_CORRECTION_MAX; + bweStr->inWaitPeriod = 1; + bweStr->startWaitPeriod = arrivalTime; + immediateSet = 1; + } else if (lateDiff > 5120) { + delayCorrFactor = (WebRtc_Word32) DELAY_CORRECTION_MED; + immediateSet = 1; + bweStr->inWaitPeriod = 1; + bweStr->startWaitPeriod = arrivalTime; + } + } + } + + if ((bweStr->prevRtpRate > WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32) bweStr->recBwAvg, 5)) && + (recRtpRate > WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)bweStr->recBwAvg, 5)) && + !bweStr->inWaitPeriod) { + + /* test if still in initiation period and increment counter */ + if (bweStr->countUpdates++ > 99) { + /* constant weight after initiation part, 0.01 in Q13 */ + weight = (WebRtc_UWord16) 82; + } else { + /* weight decreases with number of updates, 1/countUpdates in Q13 */ + weight = (WebRtc_UWord16) WebRtcSpl_DivW32W16( + (WebRtc_Word32)(8192 + WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32) bweStr->countUpdates, 1)), + (WebRtc_Word16)bweStr->countUpdates); + } + + /* Bottle Neck Estimation */ + + /* limit outliers, if more than 25 ms too much */ + if (arrTimeDiff > frameSizeSampl + kSamplesIn25msec) { + arrTimeDiff = frameSizeSampl + kSamplesIn25msec; + } + + /* don't allow it to be less than frame rate - 10 ms */ + if (arrTimeDiff < frameSizeSampl - FRAMESAMPLES_10ms) { + arrTimeDiff = frameSizeSampl - FRAMESAMPLES_10ms; + } + + /* compute inverse receiving rate for last packet, in Q19 */ + numBytesInv = (WebRtc_UWord16) WebRtcSpl_DivW32W16( + (WebRtc_Word32)(524288 + WEBRTC_SPL_RSHIFT_W32(((WebRtc_Word32)pksize + HEADER_SIZE), 1)), + (WebRtc_Word16)(pksize + HEADER_SIZE)); + + /* 8389 is ~ 1/128000 in Q30 */ + byteSecondsPerBit = WEBRTC_SPL_MUL_16_16(arrTimeDiff, 8389); + + /* get upper N bits */ + tempUpper = WEBRTC_SPL_RSHIFT_U32(byteSecondsPerBit, 15); + + /* get lower 15 bits */ + tempLower = byteSecondsPerBit & 0x00007FFF; + + tempUpper = WEBRTC_SPL_MUL(tempUpper, numBytesInv); + tempLower = WEBRTC_SPL_MUL(tempLower, numBytesInv); + tempLower = WEBRTC_SPL_RSHIFT_U32(tempLower, 15); + + currBwInv = tempUpper + tempLower; + currBwInv = WEBRTC_SPL_RSHIFT_U32(currBwInv, 4); + + /* Limit inv rate. Note that minBwInv > maxBwInv! */ + if(currBwInv < bweStr->maxBwInv) { + currBwInv = bweStr->maxBwInv; + } else if(currBwInv > bweStr->minBwInv) { + currBwInv = bweStr->minBwInv; + } + + /* update bottle neck rate estimate */ + bweStr->recBwInv = WEBRTC_SPL_UMUL(weight, currBwInv) + + WEBRTC_SPL_UMUL((WebRtc_UWord32) 8192 - weight, bweStr->recBwInv); + + /* Shift back to Q30 from Q40 (actual used bits shouldn't be more than 27 based on minBwInv) + up to 30 bits used with Q13 weight */ + bweStr->recBwInv = WEBRTC_SPL_RSHIFT_U32(bweStr->recBwInv, 13); + + /* reset time-since-update counter */ + bweStr->lastUpdate = arrivalTime; + bweStr->lastReduction = arrivalTime + FS3; + bweStr->countRecPkts = 0; + + /* to save resolution compute the inverse of recBwAvg in Q26 by left shifting numerator to 2^31 + and NOT right shifting recBwAvg 5 bits to an integer + At max 13 bits are used + shift to Q5 */ + recBwAvgInv = WEBRTC_SPL_UDIV((WebRtc_UWord32)(0x80000000 + WEBRTC_SPL_RSHIFT_U32(bweStr->recBwAvg, 1)), + bweStr->recBwAvg); + + /* Calculate Projected arrival time difference */ + + /* The numerator of the quotient can be 22 bits so right shift inv by 4 to avoid overflow + result in Q22 */ + arrTimeProj = WEBRTC_SPL_MUL((WebRtc_Word32)8000, recBwAvgInv); + /* shift to Q22 */ + arrTimeProj = WEBRTC_SPL_RSHIFT_U32(arrTimeProj, 4); + /* complete calulation */ + arrTimeProj = WEBRTC_SPL_MUL(((WebRtc_Word32)pksize + HEADER_SIZE), arrTimeProj); + /* shift to Q10 */ + arrTimeProj = WEBRTC_SPL_RSHIFT_U32(arrTimeProj, 12); + + /* difference between projected and actual arrival time differences */ + /* Q9 (only shift arrTimeDiff by 5 to simulate divide by 16 (need to revisit if change sampling rate) DH */ + if (WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6) > (WebRtc_Word32)arrTimeProj) { + arrTimeNoise = WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6) - arrTimeProj; + sign = 1; + } else { + arrTimeNoise = arrTimeProj - WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6); + sign = -1; + } + + /* Q9 */ + arrTimeNoiseAbs = arrTimeNoise; + + /* long term averaged absolute jitter, Q15 */ + weight = WEBRTC_SPL_RSHIFT_W32(weight, 3); + bweStr->recJitter = WEBRTC_SPL_MUL(weight, WEBRTC_SPL_LSHIFT_W32(arrTimeNoiseAbs, 5)) + + WEBRTC_SPL_MUL(1024 - weight, bweStr->recJitter); + + /* remove the fractional portion */ + bweStr->recJitter = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitter, 10); + + /* Maximum jitter is 10 msec in Q15 */ + if (bweStr->recJitter > (WebRtc_Word32)327680) { + bweStr->recJitter = (WebRtc_Word32)327680; + } + + /* short term averaged absolute jitter */ + /* Calculation in Q13 products in Q23 */ + bweStr->recJitterShortTermAbs = WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32(arrTimeNoiseAbs, 3)) + + WEBRTC_SPL_MUL(973, bweStr->recJitterShortTermAbs); + bweStr->recJitterShortTermAbs = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTermAbs , 10); + + /* short term averaged jitter */ + /* Calculation in Q13 products in Q23 */ + bweStr->recJitterShortTerm = WEBRTC_SPL_MUL(205, WEBRTC_SPL_LSHIFT_W32(arrTimeNoise, 3)) * sign + + WEBRTC_SPL_MUL(3891, bweStr->recJitterShortTerm); + + if (bweStr->recJitterShortTerm < 0) { + temp = -bweStr->recJitterShortTerm; + temp = WEBRTC_SPL_RSHIFT_W32(temp, 12); + bweStr->recJitterShortTerm = -temp; + } else { + bweStr->recJitterShortTerm = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTerm, 12); + } + } + } + } else { + /* reset time-since-update counter when receiving the first 9 packets */ + bweStr->lastUpdate = arrivalTime; + bweStr->lastReduction = arrivalTime + FS3; + bweStr->countRecPkts = 0; + bweStr->countUpdates++; + } + + /* Limit to minimum or maximum bottle neck rate (in Q30) */ + if (bweStr->recBwInv > bweStr->minBwInv) { + bweStr->recBwInv = bweStr->minBwInv; + } else if (bweStr->recBwInv < bweStr->maxBwInv) { + bweStr->recBwInv = bweStr->maxBwInv; + } + + + /* store frame length */ + bweStr->prevFrameSizeMs = frameSize; + + /* store far-side transmission rate */ + bweStr->prevRtpRate = recRtpRate; + + /* store far-side RTP time stamp */ + bweStr->prevRtpNumber = rtpNumber; + + /* Replace bweStr->recMaxDelay by the new value (atomic operation) */ + if (bweStr->prevArrivalTime != 0xffffffff) { + bweStr->recMaxDelay = WEBRTC_SPL_MUL(3, bweStr->recJitter); + } + + /* store arrival time stamp */ + bweStr->prevArrivalTime = arrivalTime; + bweStr->prevSendTime = sendTime; + + /* Replace bweStr->recBw by the new value */ + bweStr->recBw = WEBRTC_SPL_UDIV(1073741824, bweStr->recBwInv) - bweStr->recHeaderRate; + + if (immediateSet) { + /* delay correction factor is in Q10 */ + bweStr->recBw = WEBRTC_SPL_UMUL(delayCorrFactor, bweStr->recBw); + bweStr->recBw = WEBRTC_SPL_RSHIFT_U32(bweStr->recBw, 10); + + if (bweStr->recBw < (WebRtc_Word32) MIN_ISAC_BW) { + bweStr->recBw = (WebRtc_Word32) MIN_ISAC_BW; + } + + bweStr->recBwAvg = WEBRTC_SPL_LSHIFT_U32(bweStr->recBw + bweStr->recHeaderRate, 5); + + bweStr->recBwAvgQ = WEBRTC_SPL_LSHIFT_U32(bweStr->recBw, 7); + + bweStr->recJitterShortTerm = 0; + + bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, bweStr->recBw + bweStr->recHeaderRate); + + immediateSet = 0; + } + + + return 0; +} + +/* This function updates the send bottle neck rate */ +/* Index - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */ +/* returns 0 if everything went fine, -1 otherwise */ +WebRtc_Word16 WebRtcIsacfix_UpdateUplinkBwRec(BwEstimatorstr *bweStr, + const WebRtc_Word16 Index) +{ + WebRtc_UWord16 RateInd; + + if ( (Index < 0) || (Index > 23) ) { + return -ISAC_RANGE_ERROR_BW_ESTIMATOR; + } + + /* UPDATE ESTIMATES FROM OTHER SIDE */ + + if ( Index > 11 ) { + RateInd = Index - 12; + /* compute the jitter estimate as decoded on the other side in Q9 */ + /* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MAX_ISAC_MD */ + bweStr->sendMaxDelayAvg = WEBRTC_SPL_MUL(461, bweStr->sendMaxDelayAvg) + + WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)MAX_ISAC_MD, 9)); + bweStr->sendMaxDelayAvg = WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9); + + } else { + RateInd = Index; + /* compute the jitter estimate as decoded on the other side in Q9 */ + /* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MIN_ISAC_MD */ + bweStr->sendMaxDelayAvg = WEBRTC_SPL_MUL(461, bweStr->sendMaxDelayAvg) + + WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)MIN_ISAC_MD,9)); + bweStr->sendMaxDelayAvg = WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9); + + } + + + /* compute the BN estimate as decoded on the other side */ + /* sendBwAvg = 0.9 * sendBwAvg + 0.1 * kQRateTable[RateInd]; */ + bweStr->sendBwAvg = WEBRTC_SPL_UMUL(461, bweStr->sendBwAvg) + + WEBRTC_SPL_UMUL(51, WEBRTC_SPL_LSHIFT_U32(kQRateTable[RateInd], 7)); + bweStr->sendBwAvg = WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 9); + + + if (WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 7) > 28000 && !bweStr->highSpeedSend) { + bweStr->countHighSpeedSent++; + + /* approx 2 seconds with 30ms frames */ + if (bweStr->countHighSpeedSent >= 66) { + bweStr->highSpeedSend = 1; + } + } else if (!bweStr->highSpeedSend) { + bweStr->countHighSpeedSent = 0; + } + + return 0; +} + +/**************************************************************************** + * WebRtcIsacfix_GetDownlinkBwIndexImpl(...) + * + * This function calculates and returns the bandwidth/jitter estimation code + * (integer 0...23) to put in the sending iSAC payload. + * + * Input: + * - bweStr : BWE struct + * + * Return: + * bandwith and jitter index (0..23) + */ +WebRtc_UWord16 WebRtcIsacfix_GetDownlinkBwIndexImpl(BwEstimatorstr *bweStr) +{ + WebRtc_Word32 rate; + WebRtc_Word32 maxDelay; + WebRtc_UWord16 rateInd; + WebRtc_UWord16 maxDelayBit; + WebRtc_Word32 tempTerm1; + WebRtc_Word32 tempTerm2; + WebRtc_Word32 tempTermX; + WebRtc_Word32 tempTermY; + WebRtc_Word32 tempMin; + WebRtc_Word32 tempMax; + + /* Get Rate Index */ + + /* Get unquantized rate. Always returns 10000 <= rate <= 32000 */ + rate = WebRtcIsacfix_GetDownlinkBandwidth(bweStr); + + /* Compute the averaged BN estimate on this side */ + + /* recBwAvg = 0.9 * recBwAvg + 0.1 * (rate + bweStr->recHeaderRate), 0.9 and 0.1 in Q9 */ + bweStr->recBwAvg = WEBRTC_SPL_UMUL(922, bweStr->recBwAvg) + + WEBRTC_SPL_UMUL(102, WEBRTC_SPL_LSHIFT_U32((WebRtc_UWord32)rate + bweStr->recHeaderRate, 5)); + bweStr->recBwAvg = WEBRTC_SPL_RSHIFT_U32(bweStr->recBwAvg, 10); + + /* find quantization index that gives the closest rate after averaging */ + for (rateInd = 1; rateInd < 12; rateInd++) { + if (rate <= kQRateTable[rateInd]){ + break; + } + } + + /* find closest quantization index, and update quantized average by taking: */ + /* 0.9*recBwAvgQ + 0.1*kQRateTable[rateInd] */ + + /* 0.9 times recBwAvgQ in Q16 */ + /* 461/512 - 25/65536 =0.900009 */ + tempTerm1 = WEBRTC_SPL_MUL(bweStr->recBwAvgQ, 25); + tempTerm1 = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 7); + tempTermX = WEBRTC_SPL_UMUL(461, bweStr->recBwAvgQ) - tempTerm1; + + /* rate in Q16 */ + tempTermY = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)rate, 16); + + /* 0.1 * kQRateTable[rateInd] = KQRate01[rateInd] */ + tempTerm1 = tempTermX + KQRate01[rateInd] - tempTermY; + tempTerm2 = tempTermY - tempTermX - KQRate01[rateInd-1]; + + /* Compare (0.9 * recBwAvgQ + 0.1 * kQRateTable[rateInd] - rate) > + (rate - 0.9 * recBwAvgQ - 0.1 * kQRateTable[rateInd-1]) */ + if (tempTerm1 > tempTerm2) { + rateInd--; + } + + /* Update quantized average by taking: */ + /* 0.9*recBwAvgQ + 0.1*kQRateTable[rateInd] */ + + /* Add 0.1 times kQRateTable[rateInd], in Q16 */ + tempTermX += KQRate01[rateInd]; + + /* Shift back to Q7 */ + bweStr->recBwAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTermX, 9); + + /* Count consecutive received bandwidth above 28000 kbps (28000 in Q7 = 3584000) */ + /* If 66 high estimates in a row, set highSpeedRec to one */ + /* 66 corresponds to ~2 seconds in 30 msec mode */ + if ((bweStr->recBwAvgQ > 3584000) && !bweStr->highSpeedRec) { + bweStr->countHighSpeedRec++; + if (bweStr->countHighSpeedRec >= 66) { + bweStr->highSpeedRec = 1; + } + } else if (!bweStr->highSpeedRec) { + bweStr->countHighSpeedRec = 0; + } + + /* Get Max Delay Bit */ + + /* get unquantized max delay */ + maxDelay = WebRtcIsacfix_GetDownlinkMaxDelay(bweStr); + + /* Update quantized max delay average */ + tempMax = 652800; /* MAX_ISAC_MD * 0.1 in Q18 */ + tempMin = 130560; /* MIN_ISAC_MD * 0.1 in Q18 */ + tempTermX = WEBRTC_SPL_MUL((WebRtc_Word32)bweStr->recMaxDelayAvgQ, (WebRtc_Word32)461); + tempTermY = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)maxDelay, 18); + + tempTerm1 = tempTermX + tempMax - tempTermY; + tempTerm2 = tempTermY - tempTermX - tempMin; + + if ( tempTerm1 > tempTerm2) { + maxDelayBit = 0; + tempTerm1 = tempTermX + tempMin; + + /* update quantized average, shift back to Q9 */ + bweStr->recMaxDelayAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 9); + } else { + maxDelayBit = 12; + tempTerm1 = tempTermX + tempMax; + + /* update quantized average, shift back to Q9 */ + bweStr->recMaxDelayAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 9); + } + + /* Return bandwitdh and jitter index (0..23) */ + return (WebRtc_UWord16)(rateInd + maxDelayBit); +} + +/* get the bottle neck rate from far side to here, as estimated on this side */ +WebRtc_UWord16 WebRtcIsacfix_GetDownlinkBandwidth(const BwEstimatorstr *bweStr) +{ + WebRtc_UWord32 recBw; + WebRtc_Word32 jitter_sign; /* Q8 */ + WebRtc_Word32 bw_adjust; /* Q16 */ + WebRtc_Word32 rec_jitter_short_term_abs_inv; /* Q18 */ + WebRtc_Word32 temp; + + /* Q18 rec jitter short term abs is in Q13, multiply it by 2^13 to save precision + 2^18 then needs to be shifted 13 bits to 2^31 */ + rec_jitter_short_term_abs_inv = WEBRTC_SPL_UDIV(0x80000000, bweStr->recJitterShortTermAbs); + + /* Q27 = 9 + 18 */ + jitter_sign = WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTerm, 4), (WebRtc_Word32)rec_jitter_short_term_abs_inv); + + if (jitter_sign < 0) { + temp = -jitter_sign; + temp = WEBRTC_SPL_RSHIFT_W32(temp, 19); + jitter_sign = -temp; + } else { + jitter_sign = WEBRTC_SPL_RSHIFT_W32(jitter_sign, 19); + } + + /* adjust bw proportionally to negative average jitter sign */ + //bw_adjust = 1.0f - jitter_sign * (0.15f + 0.15f * jitter_sign * jitter_sign); + //Q8 -> Q16 .15 +.15 * jitter^2 first term is .15 in Q16 latter term is Q8*Q8*Q8 + //38 in Q8 ~.15 9830 in Q16 ~.15 + temp = 9830 + WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL(38, WEBRTC_SPL_MUL(jitter_sign, jitter_sign))), 8); + + if (jitter_sign < 0) { + temp = WEBRTC_SPL_MUL(jitter_sign, temp); + temp = -temp; + temp = WEBRTC_SPL_RSHIFT_W32(temp, 8); + bw_adjust = (WebRtc_UWord32)65536 + temp; /* (1 << 16) + temp; */ + } else { + bw_adjust = (WebRtc_UWord32)65536 - WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(jitter_sign, temp), 8);/* (1 << 16) - ((jitter_sign * temp) >> 8); */ + } + + //make sure following multiplication won't overflow + //bw adjust now Q14 + bw_adjust = WEBRTC_SPL_RSHIFT_W32(bw_adjust, 2);//see if good resolution is maintained + + /* adjust Rate if jitter sign is mostly constant */ + recBw = WEBRTC_SPL_UMUL(bweStr->recBw, bw_adjust); + + recBw = WEBRTC_SPL_RSHIFT_W32(recBw, 14); + + /* limit range of bottle neck rate */ + if (recBw < MIN_ISAC_BW) { + recBw = MIN_ISAC_BW; + } else if (recBw > MAX_ISAC_BW) { + recBw = MAX_ISAC_BW; + } + + return (WebRtc_UWord16) recBw; +} + +/* Returns the mmax delay (in ms) */ +WebRtc_Word16 WebRtcIsacfix_GetDownlinkMaxDelay(const BwEstimatorstr *bweStr) +{ + WebRtc_Word16 recMaxDelay; + + recMaxDelay = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(bweStr->recMaxDelay, 15); + + /* limit range of jitter estimate */ + if (recMaxDelay < MIN_ISAC_MD) { + recMaxDelay = MIN_ISAC_MD; + } else if (recMaxDelay > MAX_ISAC_MD) { + recMaxDelay = MAX_ISAC_MD; + } + + return recMaxDelay; +} + +/* get the bottle neck rate from here to far side, as estimated by far side */ +WebRtc_Word16 WebRtcIsacfix_GetUplinkBandwidth(const BwEstimatorstr *bweStr) +{ + WebRtc_Word16 send_bw; + + send_bw = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 7); + + /* limit range of bottle neck rate */ + if (send_bw < MIN_ISAC_BW) { + send_bw = MIN_ISAC_BW; + } else if (send_bw > MAX_ISAC_BW) { + send_bw = MAX_ISAC_BW; + } + + return send_bw; +} + + + +/* Returns the max delay value from the other side in ms */ +WebRtc_Word16 WebRtcIsacfix_GetUplinkMaxDelay(const BwEstimatorstr *bweStr) +{ + WebRtc_Word16 send_max_delay; + + send_max_delay = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9); + + /* limit range of jitter estimate */ + if (send_max_delay < MIN_ISAC_MD) { + send_max_delay = MIN_ISAC_MD; + } else if (send_max_delay > MAX_ISAC_MD) { + send_max_delay = MAX_ISAC_MD; + } + + return send_max_delay; +} + + + + +/* + * update long-term average bitrate and amount of data in buffer + * returns minimum payload size (bytes) + */ +WebRtc_UWord16 WebRtcIsacfix_GetMinBytes(RateModel *State, + WebRtc_Word16 StreamSize, /* bytes in bitstream */ + const WebRtc_Word16 FrameSamples, /* samples per frame */ + const WebRtc_Word16 BottleNeck, /* bottle neck rate; excl headers (bps) */ + const WebRtc_Word16 DelayBuildUp) /* max delay from bottle neck buffering (ms) */ +{ + WebRtc_Word32 MinRate = 0; + WebRtc_UWord16 MinBytes; + WebRtc_Word16 TransmissionTime; + WebRtc_Word32 inv_Q12; + WebRtc_Word32 den; + + + /* first 10 packets @ low rate, then INIT_BURST_LEN packets @ fixed rate of INIT_RATE bps */ + if (State->InitCounter > 0) { + if (State->InitCounter-- <= INIT_BURST_LEN) { + MinRate = INIT_RATE; + } else { + MinRate = 0; + } + } else { + /* handle burst */ + if (State->BurstCounter) { + if (State->StillBuffered < WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL((512 - WEBRTC_SPL_DIV(512, BURST_LEN)), DelayBuildUp), 9)) { + /* max bps derived from BottleNeck and DelayBuildUp values */ + inv_Q12 = WEBRTC_SPL_DIV(4096, WEBRTC_SPL_MUL(BURST_LEN, FrameSamples)); + MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp, inv_Q12), 3)), BottleNeck); + } else { + /* max bps derived from StillBuffered and DelayBuildUp values */ + inv_Q12 = WEBRTC_SPL_DIV(4096, FrameSamples); + if (DelayBuildUp > State->StillBuffered) { + MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp - State->StillBuffered, inv_Q12), 3)), BottleNeck); + } else if ((den = WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, (State->StillBuffered - DelayBuildUp))) >= FrameSamples) { + /* MinRate will be negative here */ + MinRate = 0; + } else { + MinRate = WEBRTC_SPL_MUL((512 - WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(den, inv_Q12), 3)), BottleNeck); + } + //if (MinRate < 1.04 * BottleNeck) + // MinRate = 1.04 * BottleNeck; + //Q9 + if (MinRate < WEBRTC_SPL_MUL(532, BottleNeck)) { + MinRate += WEBRTC_SPL_MUL(22, BottleNeck); + } + } + + State->BurstCounter--; + } + } + + + /* convert rate from bits/second to bytes/packet */ + //round and shift before conversion + MinRate += 256; + MinRate = WEBRTC_SPL_RSHIFT_W32(MinRate, 9); + MinBytes = (WebRtc_UWord16)WEBRTC_SPL_UDIV(WEBRTC_SPL_MUL(MinRate, FrameSamples), FS8); + + /* StreamSize will be adjusted if less than MinBytes */ + if (StreamSize < MinBytes) { + StreamSize = MinBytes; + } + + /* keep track of when bottle neck was last exceeded by at least 1% */ + //517/512 ~ 1.01 + if (WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(StreamSize, FS8), FrameSamples) > (WEBRTC_SPL_MUL(517, BottleNeck) >> 9)) { + if (State->PrevExceed) { + /* bottle_neck exceded twice in a row, decrease ExceedAgo */ + State->ExceedAgo -= WEBRTC_SPL_DIV(BURST_INTERVAL, BURST_LEN - 1); + if (State->ExceedAgo < 0) { + State->ExceedAgo = 0; + } + } else { + State->ExceedAgo += (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4); /* ms */ + State->PrevExceed = 1; + } + } else { + State->PrevExceed = 0; + State->ExceedAgo += (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4); /* ms */ + } + + /* set burst flag if bottle neck not exceeded for long time */ + if ((State->ExceedAgo > BURST_INTERVAL) && (State->BurstCounter == 0)) { + if (State->PrevExceed) { + State->BurstCounter = BURST_LEN - 1; + } else { + State->BurstCounter = BURST_LEN; + } + } + + + /* Update buffer delay */ + TransmissionTime = (WebRtc_Word16)WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(StreamSize, 8000), BottleNeck); /* ms */ + State->StillBuffered += TransmissionTime; + State->StillBuffered -= (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4); //>>4 = SAMPLES_PER_MSEC /* ms */ + if (State->StillBuffered < 0) { + State->StillBuffered = 0; + } + + if (State->StillBuffered > 2000) { + State->StillBuffered = 2000; + } + + return MinBytes; +} + + +/* + * update long-term average bitrate and amount of data in buffer + */ +void WebRtcIsacfix_UpdateRateModel(RateModel *State, + WebRtc_Word16 StreamSize, /* bytes in bitstream */ + const WebRtc_Word16 FrameSamples, /* samples per frame */ + const WebRtc_Word16 BottleNeck) /* bottle neck rate; excl headers (bps) */ +{ + WebRtc_Word16 TransmissionTime; + + /* avoid the initial "high-rate" burst */ + State->InitCounter = 0; + + /* Update buffer delay */ + TransmissionTime = (WebRtc_Word16)WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(WEBRTC_SPL_MUL(StreamSize, 8), 1000), BottleNeck); /* ms */ + State->StillBuffered += TransmissionTime; + State->StillBuffered -= (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4); /* ms */ + if (State->StillBuffered < 0) { + State->StillBuffered = 0; + } + +} + + +void WebRtcIsacfix_InitRateModel(RateModel *State) +{ + State->PrevExceed = 0; /* boolean */ + State->ExceedAgo = 0; /* ms */ + State->BurstCounter = 0; /* packets */ + State->InitCounter = INIT_BURST_LEN + 10; /* packets */ + State->StillBuffered = 1; /* ms */ +} + + + + + +WebRtc_Word16 WebRtcIsacfix_GetNewFrameLength(WebRtc_Word16 bottle_neck, WebRtc_Word16 current_framesamples) +{ + WebRtc_Word16 new_framesamples; + + new_framesamples = current_framesamples; + + /* find new framelength */ + switch(current_framesamples) { + case 480: + if (bottle_neck < Thld_30_60) { + new_framesamples = 960; + } + break; + case 960: + if (bottle_neck >= Thld_60_30) { + new_framesamples = 480; + } + break; + default: + new_framesamples = -1; /* Error */ + } + + return new_framesamples; +} + +WebRtc_Word16 WebRtcIsacfix_GetSnr(WebRtc_Word16 bottle_neck, WebRtc_Word16 framesamples) +{ + WebRtc_Word16 s2nr = 0; + + /* find new SNR value */ + //consider BottleNeck to be in Q10 ( * 1 in Q10) + switch(framesamples) { + case 480: + /*s2nr = -1*(a_30 << 10) + ((b_30 * bottle_neck) >> 10);*/ + s2nr = -22500 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(500, bottle_neck, 10); //* 0.001; //+ c_30 * bottle_neck * bottle_neck * 0.000001; + break; + case 960: + /*s2nr = -1*(a_60 << 10) + ((b_60 * bottle_neck) >> 10);*/ + s2nr = -22500 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(500, bottle_neck, 10); //* 0.001; //+ c_30 * bottle_neck * bottle_neck * 0.000001; + break; + default: + s2nr = -1; /* Error */ + } + + return s2nr; //return in Q10 + +} diff --git a/src/libs/webrtc/isac/bandwidth_estimator.h b/src/libs/webrtc/isac/bandwidth_estimator.h new file mode 100644 index 00000000..76a50f82 --- /dev/null +++ b/src/libs/webrtc/isac/bandwidth_estimator.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * bandwidth_estimator.h + * + * This header file contains the API for the Bandwidth Estimator + * designed for iSAC. + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_BANDWIDTH_ESTIMATOR_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_BANDWIDTH_ESTIMATOR_H_ + +#include "structs.h" + + +/**************************************************************************** + * WebRtcIsacfix_InitBandwidthEstimator(...) + * + * This function initializes the struct for the bandwidth estimator + * + * Input/Output: + * - bwest_str : Struct containing bandwidth information. + * + * Return value : 0 + */ + +WebRtc_Word32 WebRtcIsacfix_InitBandwidthEstimator(BwEstimatorstr *bwest_str); + + +/**************************************************************************** + * WebRtcIsacfix_UpdateUplinkBwImpl(...) + * + * This function updates bottle neck rate received from other side in payload + * and calculates a new bottle neck to send to the other side. + * + * Input/Output: + * - bweStr : struct containing bandwidth information. + * - rtpNumber : value from RTP packet, from NetEq + * - frameSize : length of signal frame in ms, from iSAC decoder + * - sendTime : value in RTP header giving send time in samples + * - arrivalTime : value given by timeGetTime() time of arrival in + * samples of packet from NetEq + * - pksize : size of packet in bytes, from NetEq + * - Index : integer (range 0...23) indicating bottle neck & + * jitter as estimated by other side + * + * Return value : 0 if everything went fine, + * -1 otherwise + */ + +WebRtc_Word32 WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bwest_str, + const WebRtc_UWord16 rtp_number, + const WebRtc_Word16 frameSize, + const WebRtc_UWord32 send_ts, + const WebRtc_UWord32 arr_ts, + const WebRtc_Word16 pksize, + const WebRtc_UWord16 Index); + +/* Update receiving estimates. Used when we only receive BWE index, no iSAC data packet. */ +WebRtc_Word16 WebRtcIsacfix_UpdateUplinkBwRec(BwEstimatorstr *bwest_str, + const WebRtc_Word16 Index); + +/**************************************************************************** + * WebRtcIsacfix_GetDownlinkBwIndexImpl(...) + * + * This function calculates and returns the bandwidth/jitter estimation code + * (integer 0...23) to put in the sending iSAC payload. + * + * Input: + * - bweStr : BWE struct + * + * Return: + * bandwith and jitter index (0..23) + */ +WebRtc_UWord16 WebRtcIsacfix_GetDownlinkBwIndexImpl(BwEstimatorstr *bwest_str); + +/* Returns the bandwidth estimation (in bps) */ +WebRtc_UWord16 WebRtcIsacfix_GetDownlinkBandwidth(const BwEstimatorstr *bwest_str); + +/* Returns the bandwidth that iSAC should send with in bps */ +WebRtc_Word16 WebRtcIsacfix_GetUplinkBandwidth(const BwEstimatorstr *bwest_str); + +/* Returns the max delay (in ms) */ +WebRtc_Word16 WebRtcIsacfix_GetDownlinkMaxDelay(const BwEstimatorstr *bwest_str); + +/* Returns the max delay value from the other side in ms */ +WebRtc_Word16 WebRtcIsacfix_GetUplinkMaxDelay(const BwEstimatorstr *bwest_str); + +/* + * update amount of data in bottle neck buffer and burst handling + * returns minimum payload size (bytes) + */ +WebRtc_UWord16 WebRtcIsacfix_GetMinBytes(RateModel *State, + WebRtc_Word16 StreamSize, /* bytes in bitstream */ + const WebRtc_Word16 FrameLen, /* ms per frame */ + const WebRtc_Word16 BottleNeck, /* bottle neck rate; excl headers (bps) */ + const WebRtc_Word16 DelayBuildUp); /* max delay from bottle neck buffering (ms) */ + +/* + * update long-term average bitrate and amount of data in buffer + */ +void WebRtcIsacfix_UpdateRateModel(RateModel *State, + WebRtc_Word16 StreamSize, /* bytes in bitstream */ + const WebRtc_Word16 FrameSamples, /* samples per frame */ + const WebRtc_Word16 BottleNeck); /* bottle neck rate; excl headers (bps) */ + + +void WebRtcIsacfix_InitRateModel(RateModel *State); + +/* Returns the new framelength value (input argument: bottle_neck) */ +WebRtc_Word16 WebRtcIsacfix_GetNewFrameLength(WebRtc_Word16 bottle_neck, WebRtc_Word16 current_framelength); + +/* Returns the new SNR value (input argument: bottle_neck) */ +//returns snr in Q10 +WebRtc_Word16 WebRtcIsacfix_GetSnr(WebRtc_Word16 bottle_neck, WebRtc_Word16 framesamples); + + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_BANDWIDTH_ESTIMATOR_H_ */ diff --git a/src/libs/webrtc/isac/codec.h b/src/libs/webrtc/isac/codec.h new file mode 100644 index 00000000..d86bd107 --- /dev/null +++ b/src/libs/webrtc/isac/codec.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * codec.h + * + * This header file contains the calls to the internal encoder + * and decoder functions. + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_CODEC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_CODEC_H_ + +#include "structs.h" + + +int WebRtcIsacfix_EstimateBandwidth(BwEstimatorstr *bwest_str, + Bitstr_dec *streamdata, + WebRtc_Word32 packet_size, + WebRtc_UWord16 rtp_seq_number, + WebRtc_UWord32 send_ts, + WebRtc_UWord32 arr_ts); + +WebRtc_Word16 WebRtcIsacfix_DecodeImpl(WebRtc_Word16 *signal_out16, + ISACFIX_DecInst_t *ISACdec_obj, + WebRtc_Word16 *current_framesamples); + +WebRtc_Word16 WebRtcIsacfix_DecodePlcImpl(WebRtc_Word16 *decoded, + ISACFIX_DecInst_t *ISACdec_obj, + WebRtc_Word16 *current_framesample ); + +int WebRtcIsacfix_EncodeImpl(WebRtc_Word16 *in, + ISACFIX_EncInst_t *ISACenc_obj, + BwEstimatorstr *bw_estimatordata, + WebRtc_Word16 CodingMode); + +int WebRtcIsacfix_EncodeStoredData(ISACFIX_EncInst_t *ISACenc_obj, + int BWnumber, + float scale); + +/************************** initialization functions *************************/ + +void WebRtcIsacfix_InitMaskingEnc(MaskFiltstr_enc *maskdata); +void WebRtcIsacfix_InitMaskingDec(MaskFiltstr_dec *maskdata); + +void WebRtcIsacfix_InitPreFilterbank(PreFiltBankstr *prefiltdata); + +void WebRtcIsacfix_InitPostFilterbank(PostFiltBankstr *postfiltdata); + +void WebRtcIsacfix_InitPitchFilter(PitchFiltstr *pitchfiltdata); + +void WebRtcIsacfix_InitPitchAnalysis(PitchAnalysisStruct *State); + +void WebRtcIsacfix_InitPlc( PLCstr *State ); + + +/**************************** transform functions ****************************/ + +void WebRtcIsacfix_InitTransform(); + + +void WebRtcIsacfix_Time2Spec(WebRtc_Word16 *inre1Q9, + WebRtc_Word16 *inre2Q9, + WebRtc_Word16 *outre, + WebRtc_Word16 *outim); + + + +void WebRtcIsacfix_Spec2Time(WebRtc_Word16 *inreQ7, + WebRtc_Word16 *inimQ7, + WebRtc_Word32 *outre1Q16, + WebRtc_Word32 *outre2Q16); + + + + +/***************************** filterbank functions **************************/ + + + +void WebRtcIsacfix_SplitAndFilter1(WebRtc_Word16 *in, + WebRtc_Word16 *LP16, + WebRtc_Word16 *HP16, + PreFiltBankstr *prefiltdata); + +void WebRtcIsacfix_FilterAndCombine1(WebRtc_Word16 *tempin_ch1, + WebRtc_Word16 *tempin_ch2, + WebRtc_Word16 *out16, + PostFiltBankstr *postfiltdata); + +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED + +void WebRtcIsacfix_SplitAndFilter2(WebRtc_Word16 *in, + WebRtc_Word16 *LP16, + WebRtc_Word16 *HP16, + PreFiltBankstr *prefiltdata); + +void WebRtcIsacfix_FilterAndCombine2(WebRtc_Word16 *tempin_ch1, + WebRtc_Word16 *tempin_ch2, + WebRtc_Word16 *out16, + PostFiltBankstr *postfiltdata, + WebRtc_Word16 len); + +#endif + +/************************* normalized lattice filters ************************/ + + +void WebRtcIsacfix_NormLatticeFilterMa(WebRtc_Word16 orderCoef, + WebRtc_Word32 *stateGQ15, + WebRtc_Word16 *lat_inQ0, + WebRtc_Word16 *filt_coefQ15, + WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 lo_hi, + WebRtc_Word16 *lat_outQ9); + + +void WebRtcIsacfix_NormLatticeFilterAr(WebRtc_Word16 orderCoef, + WebRtc_Word16 *stateGQ0, + WebRtc_Word32 *lat_inQ25, + WebRtc_Word16 *filt_coefQ15, + WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 lo_hi, + WebRtc_Word16 *lat_outQ0); + +int WebRtcIsacfix_AutocorrFix(WebRtc_Word32 *r, + const WebRtc_Word16 *x, + WebRtc_Word16 N, + WebRtc_Word16 order, + WebRtc_Word16 *scale); + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_CODEC_H_ */ diff --git a/src/libs/webrtc/isac/decode_bwe.c b/src/libs/webrtc/isac/decode_bwe.c new file mode 100644 index 00000000..68c60030 --- /dev/null +++ b/src/libs/webrtc/isac/decode_bwe.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * decode_bwe.c + * + * This C file contains the internal decode bandwidth estimate function. + * + */ + + +#include "bandwidth_estimator.h" +#include "codec.h" +#include "entropy_coding.h" +#include "structs.h" + + + + +int WebRtcIsacfix_EstimateBandwidth(BwEstimatorstr *bwest_str, + Bitstr_dec *streamdata, + WebRtc_Word32 packet_size, + WebRtc_UWord16 rtp_seq_number, + WebRtc_UWord32 send_ts, + WebRtc_UWord32 arr_ts) +{ + WebRtc_Word16 index; + WebRtc_Word16 frame_samples; + int err; + + /* decode framelength */ + err = WebRtcIsacfix_DecodeFrameLen(streamdata, &frame_samples); + /* error check */ + if (err<0) { + return err; + } + + /* decode BW estimation */ + err = WebRtcIsacfix_DecodeSendBandwidth(streamdata, &index); + /* error check */ + if (err<0) { + return err; + } + + /* Update BWE with received data */ + err = WebRtcIsacfix_UpdateUplinkBwImpl( + bwest_str, + rtp_seq_number, + (WebRtc_UWord16)WEBRTC_SPL_UDIV(WEBRTC_SPL_UMUL(frame_samples,1000), FS), + send_ts, + arr_ts, + (WebRtc_Word16) packet_size, /* in bytes */ + index); + + /* error check */ + if (err<0) { + return err; + } + + /* Succesful */ + return 0; +} diff --git a/src/libs/webrtc/isac/decode_plc.c b/src/libs/webrtc/isac/decode_plc.c new file mode 100644 index 00000000..8a96b359 --- /dev/null +++ b/src/libs/webrtc/isac/decode_plc.c @@ -0,0 +1,830 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * decode_plc.c + * + * Packet Loss Concealment. + * + */ + +#include <string.h> + +#include "settings.h" +#include "entropy_coding.h" +#include "pitch_estimator.h" +#include "bandwidth_estimator.h" +#include "structs.h" +#include "codec.h" + + +#define NO_OF_PRIMES 8 +#define NOISE_FILTER_LEN 30 + +/* + * function to decode the bitstream + * returns the total number of bytes in the stream + */ + +WebRtc_Word16 plc_filterma_Fast( + WebRtc_Word16 *In, /* (i) Vector to be filtered. InOut[-orderCoef+1] + to InOut[-1] contains state */ + WebRtc_Word16 *Out, /* (o) Filtered vector */ + WebRtc_Word16 *B, /* (i) The filter coefficients (in Q0) */ + WebRtc_Word16 Blen, /* (i) Number of B coefficients */ + WebRtc_Word16 len, /* (i) Number of samples to be filtered */ + WebRtc_Word16 reduceDecay, + WebRtc_Word16 decay, + WebRtc_Word16 rshift ) +{ + int i, j; + WebRtc_Word32 o; + WebRtc_Word32 lim; + + lim = WEBRTC_SPL_LSHIFT_W32( (WebRtc_Word32)1, 15 + rshift )-1; + + for (i = 0; i < len; i++) + { + G_CONST WebRtc_Word16 *b_ptr = &B[0]; + G_CONST WebRtc_Word16 *x_ptr = &In[i]; + + o = (WebRtc_Word32)0; + + for (j = 0;j < Blen; j++) + { + o = WEBRTC_SPL_ADD_SAT_W32( o, WEBRTC_SPL_MUL_16_16( *b_ptr, *x_ptr) ); + b_ptr++; + x_ptr--; + } + + /* to round off correctly */ + o = WEBRTC_SPL_ADD_SAT_W32( o, WEBRTC_SPL_LSHIFT_W32( 1, (rshift-1) ) ); + + /* saturate according to the domain of the filter coefficients */ + o = WEBRTC_SPL_SAT((WebRtc_Word32)lim, o, (WebRtc_Word32)-lim); + + /* o should be in the range of WebRtc_Word16 */ + o = WEBRTC_SPL_RSHIFT_W32( o, rshift ); + + /* decay the output signal; this is specific to plc */ + *Out++ = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16)o, decay, 15); // ((o + (WebRtc_Word32)2048) >> 12); + + /* change the decay */ + decay -= reduceDecay; + if( decay < 0 ) + decay = 0; + } + return( decay ); +} + + + + + + + + +static __inline WebRtc_Word32 log2_Q8_T( WebRtc_UWord32 x ) { + + WebRtc_Word32 zeros, lg2; + WebRtc_Word16 frac; + + zeros=WebRtcSpl_NormU32(x); + frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(((WebRtc_UWord32)WEBRTC_SPL_LSHIFT_W32(x, zeros)&0x7FFFFFFF), 23); + /* log2(magn(i)) */ + + lg2= (WEBRTC_SPL_LSHIFT_W16((31-zeros), 8)+frac); + return lg2; + +} + +static __inline WebRtc_Word16 exp2_Q10_T(WebRtc_Word16 x) { // Both in and out in Q10 + + WebRtc_Word16 tmp16_1, tmp16_2; + + tmp16_2=(WebRtc_Word16)(0x0400|(x&0x03FF)); + tmp16_1=-(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(x,10); + if(tmp16_1>0) + return (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1); + else + return (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1); + +} + + +/* + This is a fixed-point version of the above code with limLow = 700 and limHigh = 5000, + hard-coded. The values 700 and 5000 were experimentally obtained. + + The function implements membership values for two sets. The mebership functions are + of second orders corresponding to half-bell-shapped pulses. +*/ +static void MemshipValQ15( WebRtc_Word16 in, WebRtc_Word16 *A, WebRtc_Word16 *B ) +{ + WebRtc_Word16 x; + + in -= 700; /* translate the lowLim to 0, limHigh = 5000 - 700, M = 2150 */ + + if( in <= 2150 ) + { + if( in > 0 ) + { + /* b = in^2 / (2 * M^2), a = 1 - b in Q0. + We have to compute in Q15 */ + + /* x = in / 2150 {in Q15} = x * 15.2409 {in Q15} = + x*15 + (x*983)/(2^12); note that 983/2^12 = 0.23999 */ + + /* we are sure that x is in the range of WebRtc_Word16 */ + x = (WebRtc_Word16)( WEBRTC_SPL_MUL_16_16( in, 15 ) + + WEBRTC_SPL_MUL_16_16_RSFT( in, 983, 12) ); + /* b = x^2 / 2 {in Q15} so a shift of 16 is required to + be in correct domain and one more for the division by 2 */ + *B = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( WEBRTC_SPL_MUL_16_16( x, x ) + 0x00010000, 17 ); + *A = WEBRTC_SPL_WORD16_MAX - *B; + } + else + { + *B = 0; + *A = WEBRTC_SPL_WORD16_MAX; + } + } + else + { + if( in < 4300 ) + { + /* This is a mirror case of the above */ + in = 4300 - in; + x = (WebRtc_Word16)( WEBRTC_SPL_MUL_16_16( in, 15 ) + + WEBRTC_SPL_MUL_16_16_RSFT( in, 983, 12) ); + /* b = x^2 / 2 {in Q15} so a shift of 16 is required to + be in correct domain and one more for the division by 2 */ + *A = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( WEBRTC_SPL_MUL_16_16( x, x ) + 0x00010000, 17 ); + *B = WEBRTC_SPL_WORD16_MAX - *A; + + } + else + { + *A = 0; + *B = WEBRTC_SPL_WORD16_MAX; + } + } +} + + + + +static void LinearResampler( WebRtc_Word16 *in, WebRtc_Word16 *out, WebRtc_Word16 lenIn, WebRtc_Word16 lenOut ) +{ + WebRtc_Word32 n; + WebRtc_Word16 resOut, i, j, relativePos, diff; /* */ + WebRtc_UWord16 udiff; + + if( lenIn == lenOut ) + { + WEBRTC_SPL_MEMCPY_W16( out, in, lenIn ); + return; + } + + n = WEBRTC_SPL_MUL_16_16( (WebRtc_Word16)(lenIn-1), RESAMP_RES ); + resOut = WebRtcSpl_DivW32W16ResW16( n, (WebRtc_Word16)(lenOut-1) ); + + out[0] = in[0]; + for( i = 1, j = 0, relativePos = 0; i < lenOut; i++ ) + { + + relativePos += resOut; + while( relativePos > RESAMP_RES ) + { + j++; + relativePos -= RESAMP_RES; + } + + + /* an overflow may happen and the differce in sample values may + * require more than 16 bits. We like to avoid 32 bit arithmatic + * as much as possible */ + + if( (in[ j ] > 0) && (in[j + 1] < 0) ) + { + udiff = (WebRtc_UWord16)(in[ j ] - in[j + 1]); + out[ i ] = in[ j ] - (WebRtc_UWord16)( ((WebRtc_Word32)( udiff * relativePos )) >> RESAMP_RES_BIT); + } + else + { + if( (in[j] < 0) && (in[j+1] > 0) ) + { + udiff = (WebRtc_UWord16)( in[j + 1] - in[ j ] ); + out[ i ] = in[ j ] + (WebRtc_UWord16)( ((WebRtc_Word32)( udiff * relativePos )) >> RESAMP_RES_BIT); + } + else + { + diff = in[ j + 1 ] - in[ j ]; + out[ i ] = in[ j ] + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( diff, relativePos, RESAMP_RES_BIT ); + } + } + } +} + + + + + +WebRtc_Word16 WebRtcIsacfix_DecodePlcImpl(WebRtc_Word16 *signal_out16, + ISACFIX_DecInst_t *ISACdec_obj, + WebRtc_Word16 *current_framesamples ) +{ + int subframecnt; + WebRtc_Word16 len = 0; + + WebRtc_Word16* Vector_Word16_1; + WebRtc_Word16 Vector_Word16_Extended_1[FRAMESAMPLES_HALF + NOISE_FILTER_LEN]; + WebRtc_Word16* Vector_Word16_2; + WebRtc_Word16 Vector_Word16_Extended_2[FRAMESAMPLES_HALF + NOISE_FILTER_LEN]; + + WebRtc_Word32 Vector_Word32_1[FRAMESAMPLES_HALF]; + WebRtc_Word32 Vector_Word32_2[FRAMESAMPLES_HALF]; + + WebRtc_Word16 lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs + WebRtc_Word16 hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs + + WebRtc_Word16 pitchLags_Q7[PITCH_SUBFRAMES]; + WebRtc_Word16 pitchGains_Q12[PITCH_SUBFRAMES]; + + WebRtc_Word16 tmp_1, tmp_2; + WebRtc_Word32 tmp32a, tmp32b; + WebRtc_Word16 gainQ13; + + WebRtc_Word16 myDecayRate; + + /* ---------- PLC variables ------------ */ + WebRtc_Word16 lag0, i, k, noiseIndex; + WebRtc_Word16 stretchPitchLP[PITCH_MAX_LAG + 10], stretchPitchLP1[PITCH_MAX_LAG + 10]; + + WebRtc_Word32 gain_lo_hiQ17[2*SUBFRAMES]; + + WebRtc_Word16 nLP, pLP, wNoisyLP, wPriodicLP, tmp16, minIdx; + WebRtc_Word32 nHP, pHP, wNoisyHP, wPriodicHP, corr, minCorr, maxCoeff; + WebRtc_Word16 noise1, rshift; + + + WebRtc_Word16 ltpGain, pitchGain, myVoiceIndicator, myAbs, maxAbs; + WebRtc_Word32 varIn, varOut, logVarIn, logVarOut, Q, logMaxAbs; + int rightShiftIn, rightShiftOut; + + + /* ------------------------------------- */ + + + myDecayRate = (DECAY_RATE); + Vector_Word16_1 = &Vector_Word16_Extended_1[NOISE_FILTER_LEN]; + Vector_Word16_2 = &Vector_Word16_Extended_2[NOISE_FILTER_LEN]; + + + /* ----- Simply Copy Previous LPC parameters ------ */ + for( subframecnt = 0; subframecnt < SUBFRAMES; subframecnt++ ) + { + /* lower Band */ + WEBRTC_SPL_MEMCPY_W16(&lofilt_coefQ15[ subframecnt * ORDERLO ], + (ISACdec_obj->plcstr_obj).lofilt_coefQ15, ORDERLO); + gain_lo_hiQ17[2*subframecnt] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0]; + + /* Upper Band */ + WEBRTC_SPL_MEMCPY_W16(&hifilt_coefQ15[ subframecnt * ORDERHI ], + (ISACdec_obj->plcstr_obj).hifilt_coefQ15, ORDERHI); + gain_lo_hiQ17[2*subframecnt + 1] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1]; + } + + + + + lag0 = WEBRTC_SPL_RSHIFT_W16( + (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 + 64, 7 ) + 1; + + + if( (ISACdec_obj->plcstr_obj).used != PLC_WAS_USED ) + { + (ISACdec_obj->plcstr_obj).pitchCycles = 0; + + (ISACdec_obj->plcstr_obj).lastPitchLP = + &((ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0]); + minCorr = WEBRTC_SPL_WORD32_MAX; + + if ( (FRAMESAMPLES_HALF - 2*lag0 - 10) > 0 ) + { + minIdx = 11; + for( i = 0; i < 21; i++ ) + { + corr = 0; + for( k = 0; k < lag0; k++ ) + { + corr = WEBRTC_SPL_ADD_SAT_W32( corr, WEBRTC_SPL_ABS_W32( + WEBRTC_SPL_SUB_SAT_W16( + (ISACdec_obj->plcstr_obj).lastPitchLP[k], + (ISACdec_obj->plcstr_obj).prevPitchInvIn[ + FRAMESAMPLES_HALF - 2*lag0 - 10 + i + k ] ) ) ); + } + if( corr < minCorr ) + { + minCorr = corr; + minIdx = i; + } + } + (ISACdec_obj->plcstr_obj).prevPitchLP = + &( (ISACdec_obj->plcstr_obj).prevPitchInvIn[ + FRAMESAMPLES_HALF - lag0*2 - 10 + minIdx] ); + } + else + { + (ISACdec_obj->plcstr_obj).prevPitchLP = + (ISACdec_obj->plcstr_obj).lastPitchLP; + } + pitchGain = (ISACdec_obj->plcstr_obj).lastPitchGain_Q12; + + WebRtcSpl_AutoCorrelation( + &(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0], + lag0, 0, &varIn, &rightShiftIn); + WebRtcSpl_AutoCorrelation( + &(ISACdec_obj->plcstr_obj).prevPitchInvOut[PITCH_MAX_LAG + 10 - lag0], + lag0, 0, &varOut, &rightShiftOut); + + maxAbs = 0; + for( i = 0; i< lag0; i++) + { + myAbs = WEBRTC_SPL_ABS_W16( + (ISACdec_obj->plcstr_obj).prevPitchInvOut[ + PITCH_MAX_LAG + 10 - lag0 + i] ); + maxAbs = (myAbs > maxAbs)? myAbs:maxAbs; + } + logVarIn = log2_Q8_T( (WebRtc_UWord32)( varIn ) ) + + (WebRtc_Word32)(rightShiftIn << 8); + logVarOut = log2_Q8_T( (WebRtc_UWord32)( varOut ) ) + + (WebRtc_Word32)(rightShiftOut << 8); + logMaxAbs = log2_Q8_T( (WebRtc_UWord32)( maxAbs ) ); + + ltpGain = (WebRtc_Word16)(logVarOut - logVarIn); + Q = 2 * logMaxAbs - ( logVarOut - 1512 ); + + /* + * --- + * We are computing sqrt( (VarIn/lag0) / var( noise ) ) + * var( noise ) is almost 256. we have already computed log2( VarIn ) in Q8 + * so we actually compute 2^( 0.5*(log2( VarIn ) - log2( lag0 ) - log2( var(noise ) ) ). + * Note that put log function is in Q8 but the exponential function is in Q10. + * -- + */ + + logVarIn -= log2_Q8_T( (WebRtc_UWord32)( lag0 ) ); + tmp16 = (WebRtc_Word16)((logVarIn<<1) - (4<<10) ); + rightShiftIn = 0; + if( tmp16 > 4096 ) + { + tmp16 -= 4096; + tmp16 = exp2_Q10_T( tmp16 ); + tmp16 >>= 6; + } + else + tmp16 = exp2_Q10_T( tmp16 )>>10; + + (ISACdec_obj->plcstr_obj).std = tmp16 - 4; + + if( (ltpGain < 110) || (ltpGain > 230) ) + { + if( ltpGain < 100 && (pitchGain < 1800) ) + { + (ISACdec_obj->plcstr_obj).A = WEBRTC_SPL_WORD16_MAX; + } + else + { + (ISACdec_obj->plcstr_obj).A = ((ltpGain < 110) && (Q < 800) + )? WEBRTC_SPL_WORD16_MAX:0; + } + (ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX - + (ISACdec_obj->plcstr_obj).A; + } + else + { + if( (pitchGain < 450) || (pitchGain > 1600) ) + { + (ISACdec_obj->plcstr_obj).A = ((pitchGain < 450) + )? WEBRTC_SPL_WORD16_MAX:0; + (ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX - + (ISACdec_obj->plcstr_obj).A; + } + else + { + myVoiceIndicator = ltpGain * 2 + pitchGain; + MemshipValQ15( myVoiceIndicator, + &(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B ); + } + } + + + + myVoiceIndicator = ltpGain * 16 + pitchGain * 2 + (pitchGain >> 8); + MemshipValQ15( myVoiceIndicator, + &(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B ); + + + + (ISACdec_obj->plcstr_obj).stretchLag = lag0; + (ISACdec_obj->plcstr_obj).pitchIndex = 0; + + } + else + { + myDecayRate = (DECAY_RATE<<2); + } + + if( (ISACdec_obj->plcstr_obj).B < 1000 ) + { + myDecayRate += (DECAY_RATE<<3); + } + + /* ------------ reconstructing the residual signal ------------------ */ + + LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP, + stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); + /* inverse pitch filter */ + + pitchLags_Q7[0] = pitchLags_Q7[1] = pitchLags_Q7[2] = pitchLags_Q7[3] = + ((ISACdec_obj->plcstr_obj).stretchLag<<7); + pitchGains_Q12[3] = ( (ISACdec_obj->plcstr_obj).lastPitchGain_Q12); + pitchGains_Q12[2] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( + pitchGains_Q12[3], 1010, 10 ); + pitchGains_Q12[1] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( + pitchGains_Q12[2], 1010, 10 ); + pitchGains_Q12[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( + pitchGains_Q12[1], 1010, 10 ); + + + /* most of the time either B or A are zero so seperating */ + if( (ISACdec_obj->plcstr_obj).B == 0 ) + { + for( i = 0; i < FRAMESAMPLES_HALF; i++ ) + { + /* --- Low Pass */ + (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( + (ISACdec_obj->plcstr_obj).seed ); + Vector_Word16_1[i] = WEBRTC_SPL_RSHIFT_W16( + (ISACdec_obj->plcstr_obj).seed, 10 ) - 16; + + /* --- Highpass */ + (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( + (ISACdec_obj->plcstr_obj).seed ); + Vector_Word16_2[i] = WEBRTC_SPL_RSHIFT_W16( + (ISACdec_obj->plcstr_obj).seed, 10 ) - 16; + + } + for( i = 1; i < NOISE_FILTER_LEN; i++ ) + { + (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( + (ISACdec_obj->plcstr_obj).seed ); + Vector_Word16_Extended_1[ i ] = WEBRTC_SPL_RSHIFT_W16( + (ISACdec_obj->plcstr_obj).seed, 10 ) - 16; + + (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( + (ISACdec_obj->plcstr_obj).seed ); + Vector_Word16_Extended_2[ i ] = WEBRTC_SPL_RSHIFT_W16( + (ISACdec_obj->plcstr_obj).seed, 10 ) - 16; + } + plc_filterma_Fast(Vector_Word16_1, Vector_Word16_Extended_1, + &(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - + NOISE_FILTER_LEN], (WebRtc_Word16) NOISE_FILTER_LEN, + (WebRtc_Word16) FRAMESAMPLES_HALF, (WebRtc_Word16)(5), + (ISACdec_obj->plcstr_obj).decayCoeffNoise, (WebRtc_Word16)(6)); + + maxCoeff = WebRtcSpl_MaxAbsValueW32( + &(ISACdec_obj->plcstr_obj).prevHP[ + PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN], NOISE_FILTER_LEN ); + + rshift = 0; + while( maxCoeff > WEBRTC_SPL_WORD16_MAX ) + { + maxCoeff = WEBRTC_SPL_RSHIFT_W32(maxCoeff, 1); + rshift++; + } + for( i = 0; i < NOISE_FILTER_LEN; i++ ) { + Vector_Word16_1[ FRAMESAMPLES_HALF - NOISE_FILTER_LEN + i] = + (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( + (ISACdec_obj->plcstr_obj).prevHP[ + PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN + i], rshift); + } + (ISACdec_obj->plcstr_obj).decayCoeffNoise = plc_filterma_Fast( + Vector_Word16_2, + Vector_Word16_Extended_2, + &Vector_Word16_1[FRAMESAMPLES_HALF - NOISE_FILTER_LEN], + (WebRtc_Word16) NOISE_FILTER_LEN, + (WebRtc_Word16) FRAMESAMPLES_HALF, + (WebRtc_Word16) (5), + (ISACdec_obj->plcstr_obj).decayCoeffNoise, + (WebRtc_Word16) (7) ); + + for( i = 0; i < FRAMESAMPLES_HALF; i++ ) + Vector_Word32_2[i] = WEBRTC_SPL_LSHIFT_W32( + (WebRtc_Word32)Vector_Word16_Extended_2[i], rshift ); + + Vector_Word16_1 = Vector_Word16_Extended_1; + } + else + { + if( (ISACdec_obj->plcstr_obj).A == 0 ) + { + /* ------ Periodic Vector --- */ + for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ ) + { + /* --- Lowpass */ + pLP = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( + stretchPitchLP[(ISACdec_obj->plcstr_obj).pitchIndex], + (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 15 ); + + /* --- Highpass */ + pHP = (WebRtc_Word32)WEBRTC_SPL_MUL_16_32_RSFT15( + (ISACdec_obj->plcstr_obj).decayCoeffPriodic, + (ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 - + (ISACdec_obj->plcstr_obj).stretchLag + + (ISACdec_obj->plcstr_obj).pitchIndex] ); + + /* --- lower the muliplier (more decay at next sample) --- */ + (ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate); + if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 ) + (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0; + + (ISACdec_obj->plcstr_obj).pitchIndex++; + + if( (ISACdec_obj->plcstr_obj).pitchIndex == + (ISACdec_obj->plcstr_obj).stretchLag ) + { + (ISACdec_obj->plcstr_obj).pitchIndex = 0; + (ISACdec_obj->plcstr_obj).pitchCycles++; + + if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) ) + { + (ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1; + } + else + { + (ISACdec_obj->plcstr_obj).stretchLag = lag0; + } + + (ISACdec_obj->plcstr_obj).stretchLag = ( + (ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG + )? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag; + + LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP, + stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); + + LinearResampler( (ISACdec_obj->plcstr_obj).prevPitchLP, + stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); + + switch( (ISACdec_obj->plcstr_obj).pitchCycles ) + { + case 1: + { + for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) + { + stretchPitchLP[k] = (WebRtc_Word16)(( + (WebRtc_Word32)stretchPitchLP[k]* 3 + + (WebRtc_Word32)stretchPitchLP1[k])>>2); + } + break; + } + case 2: + { + for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) + { + stretchPitchLP[k] = (WebRtc_Word16)(( + (WebRtc_Word32)stretchPitchLP[k] + + (WebRtc_Word32)stretchPitchLP1[k] )>>1); + } + break; + } + case 3: + { + for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) + { + stretchPitchLP[k] = (WebRtc_Word16)((stretchPitchLP[k] + + (WebRtc_Word32)stretchPitchLP1[k]*3 )>>2); + } + break; + } + } + + if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 ) + { + myDecayRate += 35; //(myDecayRate>>1); + (ISACdec_obj->plcstr_obj).pitchCycles = 0; + } + + } + + /* ------ Sum the noisy and periodic signals ------ */ + Vector_Word16_1[i] = pLP; + Vector_Word32_2[i] = pHP; + } + } + else + { + for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ ) + { + + (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( + (ISACdec_obj->plcstr_obj).seed ); + + noise1 = WEBRTC_SPL_RSHIFT_W16( + (ISACdec_obj->plcstr_obj).seed, 10 ) - 16; + + nLP = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( + (WebRtc_Word16)((noise1)*(ISACdec_obj->plcstr_obj).std), + (ISACdec_obj->plcstr_obj).decayCoeffNoise, 15 ); + + /* --- Highpass */ + (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( + (ISACdec_obj->plcstr_obj).seed ); + noise1 = WEBRTC_SPL_RSHIFT_W16( + (ISACdec_obj->plcstr_obj).seed, 11 ) - 8; + + nHP = (WebRtc_Word32)WEBRTC_SPL_MUL_16_32_RSFT15( + (ISACdec_obj->plcstr_obj).decayCoeffNoise, + (WebRtc_Word32)(noise1*(ISACdec_obj->plcstr_obj).std) ); + + /* --- lower the muliplier (more decay at next sample) --- */ + (ISACdec_obj->plcstr_obj).decayCoeffNoise -= (myDecayRate); + if( (ISACdec_obj->plcstr_obj).decayCoeffNoise < 0 ) + (ISACdec_obj->plcstr_obj).decayCoeffNoise = 0; + + /* ------ Periodic Vector --- */ + /* --- Lowpass */ + pLP = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( + stretchPitchLP[(ISACdec_obj->plcstr_obj).pitchIndex], + (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 15 ); + + /* --- Highpass */ + pHP = (WebRtc_Word32)WEBRTC_SPL_MUL_16_32_RSFT15( + (ISACdec_obj->plcstr_obj).decayCoeffPriodic, + (ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 - + (ISACdec_obj->plcstr_obj).stretchLag + + (ISACdec_obj->plcstr_obj).pitchIndex] ); + + /* --- lower the muliplier (more decay at next sample) --- */ + (ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate); + if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 ) + { + (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0; + } + + /* ------ Weighting the noisy and periodic vectors ------- */ + wNoisyLP = (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16_RSFT( + (ISACdec_obj->plcstr_obj).A, nLP, 15 ) ); + wNoisyHP = (WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT15( + (ISACdec_obj->plcstr_obj).A, (nHP) ) ); + + wPriodicLP = (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16_RSFT( + (ISACdec_obj->plcstr_obj).B, pLP, 15)); + wPriodicHP = (WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT15( + (ISACdec_obj->plcstr_obj).B, pHP)); + + (ISACdec_obj->plcstr_obj).pitchIndex++; + + if((ISACdec_obj->plcstr_obj).pitchIndex == + (ISACdec_obj->plcstr_obj).stretchLag) + { + (ISACdec_obj->plcstr_obj).pitchIndex = 0; + (ISACdec_obj->plcstr_obj).pitchCycles++; + + if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) ) + (ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1; + else + (ISACdec_obj->plcstr_obj).stretchLag = lag0; + + (ISACdec_obj->plcstr_obj).stretchLag = ( + (ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG + )? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag; + LinearResampler( + (ISACdec_obj->plcstr_obj).lastPitchLP, + stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); + + LinearResampler((ISACdec_obj->plcstr_obj).prevPitchLP, + stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); + + switch((ISACdec_obj->plcstr_obj).pitchCycles) + { + case 1: + { + for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) + { + stretchPitchLP[k] = (WebRtc_Word16)(( + (WebRtc_Word32)stretchPitchLP[k]* 3 + + (WebRtc_Word32)stretchPitchLP1[k] )>>2); + } + break; + } + case 2: + { + for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) + { + stretchPitchLP[k] = (WebRtc_Word16)(( + (WebRtc_Word32)stretchPitchLP[k] + + (WebRtc_Word32)stretchPitchLP1[k])>>1); + } + break; + } + case 3: + { + for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) + { + stretchPitchLP[k] = (WebRtc_Word16)( + (stretchPitchLP[k] + + (WebRtc_Word32)stretchPitchLP1[k]*3 )>>2); + } + break; + } + } + + if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 ) + { + myDecayRate += 55; //(myDecayRate>>1); + (ISACdec_obj->plcstr_obj).pitchCycles = 0; + } + } + + /* ------ Sum the noisy and periodic signals ------ */ + Vector_Word16_1[i] = (WebRtc_Word16)WEBRTC_SPL_ADD_SAT_W16( + wNoisyLP, wPriodicLP ); + Vector_Word32_2[i] = (WebRtc_Word32)WEBRTC_SPL_ADD_SAT_W32( + wNoisyHP, wPriodicHP ); + } + } + } + /* ----------------- residual signal is reconstructed ------------------ */ + + k = (ISACdec_obj->plcstr_obj).pitchIndex; + /* --- Write one pitch cycle for recovery block --- */ + + for( i = 0; i < RECOVERY_OVERLAP; i++ ) + { + (ISACdec_obj->plcstr_obj).overlapLP[i] = (WebRtc_Word16)( + WEBRTC_SPL_MUL_16_16_RSFT(stretchPitchLP[k], + (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 15) ); + k = ( k < ((ISACdec_obj->plcstr_obj).stretchLag - 1) )? (k+1):0; + } + + (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = (ISACdec_obj->plcstr_obj).stretchLag << 7; + + + /* --- Inverse Pitch Filter --- */ + WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2, + &ISACdec_obj->pitchfiltstr_obj, pitchLags_Q7, pitchGains_Q12, 4); + + /* reduce gain to compensate for pitch enhancer */ + /* gain = 1.0f - 0.45f * AvgPitchGain; */ + tmp32a = WEBRTC_SPL_MUL_16_16_RSFT((ISACdec_obj->plcstr_obj).AvgPitchGain_Q12, + 29, 0); // Q18 + tmp32b = 262144 - tmp32a; // Q18 + gainQ13 = (WebRtc_Word16) (tmp32b >> 5); // Q13 + + /* perceptual post-filtering (using normalized lattice filter) */ + for (k = 0; k < FRAMESAMPLES_HALF; k++) + Vector_Word32_1[k] = (WebRtc_Word32) WEBRTC_SPL_MUL_16_16( + Vector_Word16_2[k], gainQ13) << 3; // Q25 + + + WebRtcIsacfix_NormLatticeFilterAr(ORDERLO, + (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0, + Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1); + + WebRtcIsacfix_NormLatticeFilterAr(ORDERHI, + (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0, + Vector_Word32_2, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2); + + /* recombine the 2 bands */ + + /* Form the polyphase signals, and compensate for DC offset */ + for (k=0;k<FRAMESAMPLES_HALF;k++) + { + /* Construct a new upper channel signal*/ + tmp_1 = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, + (((WebRtc_Word32)Vector_Word16_1[k]+Vector_Word16_2[k] + 1)), -32768); + /* Construct a new lower channel signal*/ + tmp_2 = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, + (((WebRtc_Word32)Vector_Word16_1[k]-Vector_Word16_2[k])), -32768); + Vector_Word16_1[k] = tmp_1; + Vector_Word16_2[k] = tmp_2; + } + + + WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1, + Vector_Word16_2, signal_out16, &ISACdec_obj->postfiltbankstr_obj); + + (ISACdec_obj->plcstr_obj).used = PLC_WAS_USED; + *current_framesamples = 480; + + return len; +} diff --git a/src/libs/webrtc/isac/encode.c b/src/libs/webrtc/isac/encode.c new file mode 100644 index 00000000..cb531e5a --- /dev/null +++ b/src/libs/webrtc/isac/encode.c @@ -0,0 +1,626 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * encode.c + * + * Encoding function for the iSAC coder. + * + */ + +#include "arith_routins.h" +#include "bandwidth_estimator.h" +#include "codec.h" +#include "pitch_gain_tables.h" +#include "pitch_lag_tables.h" +#include "entropy_coding.h" +#include "lpc_tables.h" +#include "lpc_masking_model.h" +#include "pitch_estimator.h" +#include "structs.h" +#include <stdio.h> + + +int WebRtcIsacfix_EncodeImpl(WebRtc_Word16 *in, + ISACFIX_EncInst_t *ISACenc_obj, + BwEstimatorstr *bw_estimatordata, + WebRtc_Word16 CodingMode) +{ + WebRtc_Word16 stream_length = 0; + WebRtc_Word16 usefulstr_len = 0; + int k; + WebRtc_Word16 BWno; + + WebRtc_Word16 lofilt_coefQ15[(ORDERLO)*SUBFRAMES]; + WebRtc_Word16 hifilt_coefQ15[(ORDERHI)*SUBFRAMES]; + WebRtc_Word32 gain_lo_hiQ17[2*SUBFRAMES]; + + WebRtc_Word16 LPandHP[FRAMESAMPLES/2 + QLOOKAHEAD]; + WebRtc_Word16 LP16a[FRAMESAMPLES/2 + QLOOKAHEAD]; + WebRtc_Word16 HP16a[FRAMESAMPLES/2 + QLOOKAHEAD]; + + WebRtc_Word16 PitchLags_Q7[PITCH_SUBFRAMES]; + WebRtc_Word16 PitchGains_Q12[PITCH_SUBFRAMES]; + WebRtc_Word16 AvgPitchGain_Q12; + + WebRtc_Word16 frame_mode; /* 0 for 30ms, 1 for 60ms */ + WebRtc_Word16 processed_samples; + int status; + + WebRtc_Word32 bits_gainsQ11; + WebRtc_Word16 MinBytes; + WebRtc_Word16 bmodel; + + transcode_obj transcodingParam; + WebRtc_Word16 payloadLimitBytes; + WebRtc_Word16 arithLenBeforeEncodingDFT; + WebRtc_Word16 iterCntr; + + /* copy new frame length and bottle neck rate only for the first 10 ms data */ + if (ISACenc_obj->buffer_index == 0) { + /* set the framelength for the next packet */ + ISACenc_obj->current_framesamples = ISACenc_obj->new_framelength; + } + + frame_mode = ISACenc_obj->current_framesamples/MAX_FRAMESAMPLES; /* 0 (30 ms) or 1 (60 ms) */ + processed_samples = ISACenc_obj->current_framesamples/(frame_mode+1); /* 480 (30, 60 ms) */ + + /* buffer speech samples (by 10ms packet) until the framelength is reached (30 or 60 ms) */ + /**************************************************************************************/ + /* fill the buffer with 10ms input data */ + for(k=0; k<FRAMESAMPLES_10ms; k++) { + ISACenc_obj->data_buffer_fix[k + ISACenc_obj->buffer_index] = in[k]; + } + /* if buffersize is not equal to current framesize, and end of file is not reached yet, */ + /* increase index and go back to main to get more speech samples */ + if (ISACenc_obj->buffer_index + FRAMESAMPLES_10ms != processed_samples) { + ISACenc_obj->buffer_index = ISACenc_obj->buffer_index + FRAMESAMPLES_10ms; + return 0; + } + /* if buffer reached the right size, reset index and continue with encoding the frame */ + ISACenc_obj->buffer_index = 0; + + /* end of buffer function */ + /**************************/ + + /* encoding */ + /************/ + + if (frame_mode == 0 || ISACenc_obj->frame_nb == 0 ) + { + /* reset bitstream */ + ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF; + ISACenc_obj->bitstr_obj.streamval = 0; + ISACenc_obj->bitstr_obj.stream_index = 0; + ISACenc_obj->bitstr_obj.full = 1; + + if (CodingMode == 0) { + ISACenc_obj->BottleNeck = WebRtcIsacfix_GetUplinkBandwidth(bw_estimatordata); + ISACenc_obj->MaxDelay = WebRtcIsacfix_GetUplinkMaxDelay(bw_estimatordata); + } + if (CodingMode == 0 && frame_mode == 0 && (ISACenc_obj->enforceFrameSize == 0)) { + ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck, + ISACenc_obj->current_framesamples); + } + + // multiply the bottleneck by 0.88 before computing SNR, 0.88 is tuned by experimenting on TIMIT + // 901/1024 is 0.87988281250000 + ISACenc_obj->s2nr = WebRtcIsacfix_GetSnr((WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ISACenc_obj->BottleNeck, 901, 10), + ISACenc_obj->current_framesamples); + + /* encode frame length */ + status = WebRtcIsacfix_EncodeFrameLen(ISACenc_obj->current_framesamples, &ISACenc_obj->bitstr_obj); + if (status < 0) + { + /* Wrong frame size */ + if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) + { + // If this is the second 30ms of a 60ms frame reset this such that in the next call + // encoder starts fresh. + ISACenc_obj->frame_nb = 0; + } + return status; + } + + /* Save framelength for multiple packets memory */ + if (ISACenc_obj->SaveEnc_ptr != NULL) { + (ISACenc_obj->SaveEnc_ptr)->framelength=ISACenc_obj->current_framesamples; + } + + /* bandwidth estimation and coding */ + BWno = WebRtcIsacfix_GetDownlinkBwIndexImpl(bw_estimatordata); + status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj); + if (status < 0) + { + if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) + { + // If this is the second 30ms of a 60ms frame reset this such that in the next call + // encoder starts fresh. + ISACenc_obj->frame_nb = 0; + } + return status; + } + } + + /* split signal in two bands */ + WebRtcIsacfix_SplitAndFilter1(ISACenc_obj->data_buffer_fix, LP16a, HP16a, &ISACenc_obj->prefiltbankstr_obj ); + + /* estimate pitch parameters and pitch-filter lookahead signal */ + WebRtcIsacfix_PitchAnalysis(LP16a+QLOOKAHEAD, LPandHP, + &ISACenc_obj->pitchanalysisstr_obj, PitchLags_Q7, PitchGains_Q12); /* LPandHP = LP_lookahead_pfQ0, */ + + /* Set where to store data in multiple packets memory */ + if (ISACenc_obj->SaveEnc_ptr != NULL) { + if (frame_mode == 0 || ISACenc_obj->frame_nb == 0) + { + (ISACenc_obj->SaveEnc_ptr)->startIdx = 0; + } + else + { + (ISACenc_obj->SaveEnc_ptr)->startIdx = 1; + } + } + + /* quantize & encode pitch parameters */ + status = WebRtcIsacfix_EncodePitchGain(PitchGains_Q12, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr); + if (status < 0) + { + if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) + { + // If this is the second 30ms of a 60ms frame reset this such that in the next call + // encoder starts fresh. + ISACenc_obj->frame_nb = 0; + } + return status; + } + status = WebRtcIsacfix_EncodePitchLag(PitchLags_Q7 , PitchGains_Q12, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr); + if (status < 0) + { + if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) + { + // If this is the second 30ms of a 60ms frame reset this such that in the next call + // encoder starts fresh. + ISACenc_obj->frame_nb = 0; + } + return status; + } + AvgPitchGain_Q12 = WEBRTC_SPL_RSHIFT_W32(PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3], 2); + + /* find coefficients for perceptual pre-filters */ + WebRtcIsacfix_GetLpcCoef(LPandHP, HP16a+QLOOKAHEAD, &ISACenc_obj->maskfiltstr_obj, + ISACenc_obj->s2nr, PitchGains_Q12, + gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15); /*LPandHP = LP_lookahead_pfQ0*/ + + // record LPC Gains for possible bit-rate reduction + for(k = 0; k < KLT_ORDER_GAIN; k++) + { + transcodingParam.lpcGains[k] = gain_lo_hiQ17[k]; + } + + /* code LPC model and shape - gains not quantized yet */ + status = WebRtcIsacfix_EncodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15, + &bmodel, &bits_gainsQ11, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr, &transcodingParam); + if (status < 0) + { + if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) + { + // If this is the second 30ms of a 60ms frame reset this such that in the next call + // encoder starts fresh. + ISACenc_obj->frame_nb = 0; + } + return status; + } + arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full); + + /* low-band filtering */ + WebRtcIsacfix_NormLatticeFilterMa(ORDERLO, ISACenc_obj->maskfiltstr_obj.PreStateLoGQ15, + LP16a, lofilt_coefQ15, gain_lo_hiQ17, 0, LPandHP);/* LPandHP = LP16b */ + + /* pitch filter */ + WebRtcIsacfix_PitchFilter(LPandHP, LP16a, &ISACenc_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 1);/* LPandHP = LP16b */ + + /* high-band filtering */ + WebRtcIsacfix_NormLatticeFilterMa(ORDERHI, ISACenc_obj->maskfiltstr_obj.PreStateHiGQ15, + HP16a, hifilt_coefQ15, gain_lo_hiQ17, 1, LPandHP);/*LPandHP = HP16b*/ + + /* transform */ + WebRtcIsacfix_Time2Spec(LP16a, LPandHP, LP16a, LPandHP); /*LPandHP = HP16b*/ + + /* Save data for multiple packets memory */ + if (ISACenc_obj->SaveEnc_ptr != NULL) { + for (k = 0; k < FRAMESAMPLES_HALF; k++) { + (ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k]; + (ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k]; + } + (ISACenc_obj->SaveEnc_ptr)->AvgPitchGain[(ISACenc_obj->SaveEnc_ptr)->startIdx] = AvgPitchGain_Q12; + } + + /* quantization and lossless coding */ + status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12); + if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/ + { + if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) + { + // If this is the second 30ms of a 60ms frame reset this such that in the next call + // encoder starts fresh. + ISACenc_obj->frame_nb = 0; + } + return status; + } + + if((frame_mode == 1) && (ISACenc_obj->frame_nb == 0)) + { + // it is a 60ms and we are in the first 30ms + // then the limit at this point should be half of the assigned value + payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 >> 1; + } + else if (frame_mode == 0) + { + // it is a 30ms frame + payloadLimitBytes = (ISACenc_obj->payloadLimitBytes30) - 3; + } + else + { + // this is the second half of a 60ms frame. + payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 - 3; // subract 3 because termination process may add 3 bytes + } + + iterCntr = 0; + while((((ISACenc_obj->bitstr_obj.stream_index) << 1) > payloadLimitBytes) || + (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) + { + WebRtc_Word16 arithLenDFTByte; + WebRtc_Word16 bytesLeftQ5; + WebRtc_Word16 ratioQ5[8] = {0, 6, 9, 12, 16, 19, 22, 25}; + + // According to experiments on TIMIT the following is proper for audio, but it is not agressive enough for tonal inputs + // such as DTMF, sweep-sine, ... + // + // (0.55 - (0.8 - ratio[i]/32) * 5 / 6) * 2^14 + // WebRtc_Word16 scaleQ14[8] = {0, 648, 1928, 3208, 4915, 6195, 7475, 8755}; + + + // This is a supper-agressive scaling passed the tests (tonal inputs) tone with one iteration for payload limit + // of 120 (32kbps bottleneck), number of frames needed a rate-reduction was 58403 + // + WebRtc_Word16 scaleQ14[8] = {0, 348, 828, 1408, 2015, 3195, 3500, 3500}; + WebRtc_Word16 idx; + + if(iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) + { + // We were not able to limit the payload size + + if((frame_mode == 1) && (ISACenc_obj->frame_nb == 0)) + { + // This was the first 30ms of a 60ms frame. Although the payload is larger than it + // should be but we let the second 30ms be encoded. Maybe togetehr we won't exceed + // the limit. + ISACenc_obj->frame_nb = 1; + return 0; + } + else if((frame_mode == 1) && (ISACenc_obj->frame_nb == 1)) + { + ISACenc_obj->frame_nb = 0; + } + + if(status != -ISAC_DISALLOWED_BITSTREAM_LENGTH) + { + return -ISAC_PAYLOAD_LARGER_THAN_LIMIT; + } + else + { + return status; + } + } + if(status != -ISAC_DISALLOWED_BITSTREAM_LENGTH) + { + arithLenDFTByte = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full) - arithLenBeforeEncodingDFT; + bytesLeftQ5 = (payloadLimitBytes - arithLenBeforeEncodingDFT) << 5; + + // bytesLeft / arithLenDFTBytes indicates how much scaling is required a rough estimate (agressive) + // scale = 0.55 - (0.8 - bytesLeft / arithLenDFTBytes) * 5 / 6 + // bytesLeft / arithLenDFTBytes below 0.2 will have a scale of zero and above 0.8 are treated as 0.8 + // to avoid division we do more simplification. + // + // values of (bytesLeft / arithLenDFTBytes)*32 between ratioQ5[i] and ratioQ5[i+1] are rounded to ratioQ5[i] + // and the corresponding scale is chosen + + // we compare bytesLeftQ5 with ratioQ5[]*arithLenDFTByte; + idx = 4; + idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 2:-2; + idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 1:-1; + idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 0:-1; + } + else + { + // we are here because the bit-stream did not fit into the buffer, in this case, the stream_index is not + // trustable, especially if the is the first 30ms of a packet. Thereforem, we will go for the most agressive + // case. + idx = 0; + } + // scale FFT coefficients to reduce the bit-rate + for(k = 0; k < FRAMESAMPLES_HALF; k++) + { + LP16a[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(LP16a[k], scaleQ14[idx], 14); + LPandHP[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(LPandHP[k], scaleQ14[idx], 14); + } + + // Save data for multiple packets memory + if (ISACenc_obj->SaveEnc_ptr != NULL) + { + for(k = 0; k < FRAMESAMPLES_HALF; k++) + { + (ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k]; + (ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k]; + } + } + + // scale the unquantized LPC gains and save the scaled version for the future use + for(k = 0; k < KLT_ORDER_GAIN; k++) + { + gain_lo_hiQ17[k] = WEBRTC_SPL_MUL_16_32_RSFT14(scaleQ14[idx], transcodingParam.lpcGains[k]);//transcodingParam.lpcGains[k]; // + transcodingParam.lpcGains[k] = gain_lo_hiQ17[k]; + } + + // reset the bit-stream object to the state which it had before encoding LPC Gains + ISACenc_obj->bitstr_obj.full = transcodingParam.full; + ISACenc_obj->bitstr_obj.stream_index = transcodingParam.stream_index; + ISACenc_obj->bitstr_obj.streamval = transcodingParam.streamval; + ISACenc_obj->bitstr_obj.W_upper = transcodingParam.W_upper; + ISACenc_obj->bitstr_obj.stream[transcodingParam.stream_index-1] = transcodingParam.beforeLastWord; + ISACenc_obj->bitstr_obj.stream[transcodingParam.stream_index] = transcodingParam.lastWord; + + + // quantize and encode LPC gain + WebRtcIsacfix_EstCodeLpcGain(gain_lo_hiQ17, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr); + arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full); + status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12); + if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/ + { + if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) + { + // If this is the second 30ms of a 60ms frame reset this such that in the next call + // encoder starts fresh. + ISACenc_obj->frame_nb = 0; + } + return status; + } + iterCntr++; + } + + if (frame_mode == 1 && ISACenc_obj->frame_nb == 0) + /* i.e. 60 ms framesize and just processed the first 30ms, */ + /* go back to main function to buffer the other 30ms speech frame */ + { + ISACenc_obj->frame_nb = 1; + return 0; + } + else if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) + { + ISACenc_obj->frame_nb = 0; + /* also update the framelength for next packet, in Adaptive mode only */ + if (CodingMode == 0 && (ISACenc_obj->enforceFrameSize == 0)) { + ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck, + ISACenc_obj->current_framesamples); + } + } + + + /* complete arithmetic coding */ + stream_length = WebRtcIsacfix_EncTerminate(&ISACenc_obj->bitstr_obj); + /* can this be negative? */ + + if(CodingMode == 0) + { + + /* update rate model and get minimum number of bytes in this packet */ + MinBytes = WebRtcIsacfix_GetMinBytes(&ISACenc_obj->rate_data_obj, (WebRtc_Word16) stream_length, + ISACenc_obj->current_framesamples, ISACenc_obj->BottleNeck, ISACenc_obj->MaxDelay); + + /* if bitstream is too short, add garbage at the end */ + + /* Store length of coded data */ + usefulstr_len = stream_length; + + /* Make sure MinBytes does not exceed packet size limit */ + if ((ISACenc_obj->frame_nb == 0) && (MinBytes > ISACenc_obj->payloadLimitBytes30)) { + MinBytes = ISACenc_obj->payloadLimitBytes30; + } else if ((ISACenc_obj->frame_nb == 1) && (MinBytes > ISACenc_obj->payloadLimitBytes60)) { + MinBytes = ISACenc_obj->payloadLimitBytes60; + } + + /* Make sure we don't allow more than 255 bytes of garbage data. + We store the length of the garbage data in 8 bits in the bitstream, + 255 is the max garbage lenght we can signal using 8 bits. */ + if( MinBytes > usefulstr_len + 255 ) { + MinBytes = usefulstr_len + 255; + } + + /* Save data for creation of multiple bitstreams */ + if (ISACenc_obj->SaveEnc_ptr != NULL) { + (ISACenc_obj->SaveEnc_ptr)->minBytes = MinBytes; + } + + while (stream_length < MinBytes) + { + if (stream_length & 0x0001){ + ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed ); + ISACenc_obj->bitstr_obj.stream[ WEBRTC_SPL_RSHIFT_W16(stream_length, 1) ] |= (WebRtc_UWord16)(ISACenc_obj->bitstr_seed & 0xFF); + } else { + ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed ); + ISACenc_obj->bitstr_obj.stream[ WEBRTC_SPL_RSHIFT_W16(stream_length, 1) ] = WEBRTC_SPL_LSHIFT_U16(ISACenc_obj->bitstr_seed, 8); + } + stream_length++; + } + + /* to get the real stream_length, without garbage */ + if (usefulstr_len & 0x0001) { + ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] &= 0xFF00; + ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] += (MinBytes - usefulstr_len) & 0x00FF; + } + else { + ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] &= 0x00FF; + ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] += WEBRTC_SPL_LSHIFT_U16((MinBytes - usefulstr_len) & 0x00FF, 8); + } + } + else + { + /* update rate model */ + WebRtcIsacfix_UpdateRateModel(&ISACenc_obj->rate_data_obj, (WebRtc_Word16) stream_length, + ISACenc_obj->current_framesamples, ISACenc_obj->BottleNeck); + } + return stream_length; +} + +/* This function is used to create a new bitstream with new BWE. + The same data as previously encoded with the fucntion WebRtcIsacfix_EncodeImpl() + is used. The data needed is taken from the struct, where it was stored + when calling the encoder. */ +int WebRtcIsacfix_EncodeStoredData(ISACFIX_EncInst_t *ISACenc_obj, + int BWnumber, + float scale) +{ + int ii; + int status; + WebRtc_Word16 BWno = BWnumber; + int stream_length = 0; + + WebRtc_Word16 model; + const WebRtc_UWord16 *Q_PitchGain_cdf_ptr[1]; + const WebRtc_UWord16 **cdf; + const ISAC_SaveEncData_t *SaveEnc_str; + WebRtc_Word32 tmpLPCcoeffs_g[KLT_ORDER_GAIN<<1]; + WebRtc_Word16 tmpLPCindex_g[KLT_ORDER_GAIN<<1]; + WebRtc_Word16 tmp_fre[FRAMESAMPLES]; + WebRtc_Word16 tmp_fim[FRAMESAMPLES]; + + SaveEnc_str = ISACenc_obj->SaveEnc_ptr; + + /* Check if SaveEnc memory exists */ + if (SaveEnc_str == NULL) { + return (-1); + } + + /* Sanity Check - possible values for BWnumber is 0 - 23 */ + if ((BWnumber < 0) || (BWnumber > 23)) { + return -ISAC_RANGE_ERROR_BW_ESTIMATOR; + } + + /* reset bitstream */ + ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF; + ISACenc_obj->bitstr_obj.streamval = 0; + ISACenc_obj->bitstr_obj.stream_index = 0; + ISACenc_obj->bitstr_obj.full = 1; + + /* encode frame length */ + status = WebRtcIsacfix_EncodeFrameLen(SaveEnc_str->framelength, &ISACenc_obj->bitstr_obj); + if (status < 0) { + /* Wrong frame size */ + return status; + } + + /* encode bandwidth estimate */ + status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj); + if (status < 0) { + return status; + } + + /* Transcoding */ + /* If scale < 1, rescale data to produce lower bitrate signal */ + if ((0.0 < scale) && (scale < 1.0)) { + /* Compensate LPC gain */ + for (ii = 0; ii < (KLT_ORDER_GAIN*(1+SaveEnc_str->startIdx)); ii++) { + tmpLPCcoeffs_g[ii] = (WebRtc_Word32) ((scale) * (float) SaveEnc_str->LPCcoeffs_g[ii]); + } + + /* Scale DFT */ + for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) { + tmp_fre[ii] = (WebRtc_Word16) ((scale) * (float) SaveEnc_str->fre[ii]) ; + tmp_fim[ii] = (WebRtc_Word16) ((scale) * (float) SaveEnc_str->fim[ii]) ; + } + } else { + for (ii = 0; ii < (KLT_ORDER_GAIN*(1+SaveEnc_str->startIdx)); ii++) { + tmpLPCindex_g[ii] = SaveEnc_str->LPCindex_g[ii]; + } + + for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) { + tmp_fre[ii] = SaveEnc_str->fre[ii]; + tmp_fim[ii] = SaveEnc_str->fim[ii]; + } + } + + /* Loop over number of 30 msec */ + for (ii = 0; ii <= SaveEnc_str->startIdx; ii++) + { + + /* encode pitch gains */ + *Q_PitchGain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf; + status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &SaveEnc_str->pitchGain_index[ii], + Q_PitchGain_cdf_ptr, 1); + if (status < 0) { + return status; + } + + /* entropy coding of quantization pitch lags */ + /* voicing classificiation */ + if (SaveEnc_str->meanGain[ii] <= 819) { + cdf = WebRtcIsacfix_kPitchLagPtrLo; + } else if (SaveEnc_str->meanGain[ii] <= 1638) { + cdf = WebRtcIsacfix_kPitchLagPtrMid; + } else { + cdf = WebRtcIsacfix_kPitchLagPtrHi; + } + status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, + &SaveEnc_str->pitchIndex[PITCH_SUBFRAMES*ii], cdf, PITCH_SUBFRAMES); + if (status < 0) { + return status; + } + + /* LPC */ + /* entropy coding of model number */ + model = 0; + status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &model, + WebRtcIsacfix_kModelCdfPtr, 1); + if (status < 0) { + return status; + } + + /* entropy coding of quantization indices - LPC shape only */ + status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &SaveEnc_str->LPCindex_s[KLT_ORDER_SHAPE*ii], + WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE); + if (status < 0) { + return status; + } + + /* If transcoding, get new LPC gain indices */ + if (scale < 1.0) { + WebRtcIsacfix_TranscodeLpcCoef(&tmpLPCcoeffs_g[KLT_ORDER_GAIN*ii], &tmpLPCindex_g[KLT_ORDER_GAIN*ii]); + } + + /* entropy coding of quantization indices - LPC gain */ + status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN*ii], + WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN); + if (status < 0) { + return status; + } + + /* quantization and lossless coding */ + status = WebRtcIsacfix_EncodeSpec(&tmp_fre[ii*FRAMESAMPLES_HALF], &tmp_fim[ii*FRAMESAMPLES_HALF], + &ISACenc_obj->bitstr_obj, SaveEnc_str->AvgPitchGain[ii]); + if (status < 0) { + return status; + } + } + + /* complete arithmetic coding */ + stream_length = WebRtcIsacfix_EncTerminate(&ISACenc_obj->bitstr_obj); + + return stream_length; +} diff --git a/src/libs/webrtc/isac/entropy_coding.c b/src/libs/webrtc/isac/entropy_coding.c new file mode 100644 index 00000000..0b64d835 --- /dev/null +++ b/src/libs/webrtc/isac/entropy_coding.c @@ -0,0 +1,2072 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * entropy_coding.c + * + * This file contains all functions used to arithmetically + * encode the iSAC bistream. + * + */ + +#include <stddef.h> + +#include "arith_routins.h" +#include "spectrum_ar_model_tables.h" +#include "pitch_gain_tables.h" +#include "pitch_lag_tables.h" +#include "entropy_coding.h" +#include "lpc_tables.h" +#include "settings.h" +#include "signal_processing_library.h" + + +/* + This function implements the fix-point correspondant function to lrint. + + FLP: (WebRtc_Word32)floor(flt+.499999999999) + FIP: (fixVal+roundVal)>>qDomain + + where roundVal = 2^(qDomain-1) = 1<<(qDomain-1) + +*/ +static __inline WebRtc_Word32 CalcLrIntQ(WebRtc_Word32 fixVal, WebRtc_Word16 qDomain) { + WebRtc_Word32 intgr; + WebRtc_Word32 roundVal; + + roundVal = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, qDomain-1); + intgr = WEBRTC_SPL_RSHIFT_W32(fixVal+roundVal, qDomain); + + return intgr; +} + +/* + __inline WebRtc_UWord32 stepwise(WebRtc_Word32 dinQ10) { + + WebRtc_Word32 ind, diQ10, dtQ10; + + diQ10 = dinQ10; + if (diQ10 < DPMIN_Q10) + diQ10 = DPMIN_Q10; + if (diQ10 >= DPMAX_Q10) + diQ10 = DPMAX_Q10 - 1; + + dtQ10 = diQ10 - DPMIN_Q10;*/ /* Q10 + Q10 = Q10 */ +/* ind = (dtQ10 * 5) >> 10; */ /* 2^10 / 5 = 0.2 in Q10 */ +/* Q10 -> Q0 */ + +/* return rpointsFIX_Q10[ind]; + + } +*/ + +/* logN(x) = logN(2)*log2(x) = 0.6931*log2(x). Output in Q8. */ +/* The input argument X to logN(X) is 2^17 times higher than the + input floating point argument Y to log(Y), since the X value + is a Q17 value. This can be compensated for after the call, by + subraction a value Z for each Q-step. One Q-step means that + X gets 2 thimes higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = + 177.445678 should be subtracted (since logN() returns a Q8 value). + For a X value in Q17, the value 177.445678*17 = 3017 should be + subtracted */ +static WebRtc_Word16 CalcLogN(WebRtc_Word32 arg) { + WebRtc_Word16 zeros, log2, frac, logN; + + zeros=WebRtcSpl_NormU32(arg); + frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(WEBRTC_SPL_LSHIFT_W32(arg, zeros)&0x7FFFFFFF, 23); + log2=(WebRtc_Word16)(WEBRTC_SPL_LSHIFT_W32(31-zeros, 8)+frac); // log2(x) in Q8 + logN=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(log2,22713,15); //Q8*Q15 log(2) = 0.693147 = 22713 in Q15 + logN=logN+11; //Scalar compensation which minimizes the (log(x)-logN(x))^2 error over all x. + + return logN; +} + + +/* + expN(x) = 2^(a*x), where a = log2(e) ~= 1.442695 + + Input: Q8 (WebRtc_Word16) + Output: Q17 (WebRtc_Word32) + + a = log2(e) = log2(exp(1)) ~= 1.442695 ==> a = 23637 in Q14 (1.442688) + To this value, 700 is added or subtracted in order to get an average error + nearer zero, instead of always same-sign. +*/ + +static WebRtc_Word32 CalcExpN(WebRtc_Word16 x) { + WebRtc_Word16 ax, axINT, axFRAC; + WebRtc_Word16 exp16; + WebRtc_Word32 exp; + + if (x>=0) { + // ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637-700, 14); //Q8 + ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637, 14); //Q8 + axINT = WEBRTC_SPL_RSHIFT_W16(ax, 8); //Q0 + axFRAC = ax&0x00FF; + exp16 = WEBRTC_SPL_LSHIFT_W32(1, axINT); //Q0 + axFRAC = axFRAC+256; //Q8 + exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q0*Q8 = Q8 + exp = WEBRTC_SPL_LSHIFT_W32(exp, 9); //Q17 + } else { + // ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637+700, 14); //Q8 + ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637, 14); //Q8 + ax = -ax; + axINT = 1 + WEBRTC_SPL_RSHIFT_W16(ax, 8); //Q0 + axFRAC = 0x00FF - (ax&0x00FF); + exp16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(32768, axINT); //Q15 + axFRAC = axFRAC+256; //Q8 + exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q15*Q8 = Q23 + exp = WEBRTC_SPL_RSHIFT_W32(exp, 6); //Q17 + } + + return exp; +} + + +/* compute correlation from power spectrum */ +static void CalcCorrelation(WebRtc_Word32 *PSpecQ12, WebRtc_Word32 *CorrQ7) +{ + WebRtc_Word32 summ[FRAMESAMPLES/8]; + WebRtc_Word32 diff[FRAMESAMPLES/8]; + WebRtc_Word32 sum; + int k, n; + + for (k = 0; k < FRAMESAMPLES/8; k++) { + summ[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] + PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5); + diff[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] - PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5); + } + + sum = 2; + for (n = 0; n < FRAMESAMPLES/8; n++) + sum += summ[n]; + CorrQ7[0] = sum; + + for (k = 0; k < AR_ORDER; k += 2) { + sum = 0; + for (n = 0; n < FRAMESAMPLES/8; n++) + sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], diff[n]) + 256, 9); + CorrQ7[k+1] = sum; + } + + for (k=1; k<AR_ORDER; k+=2) { + sum = 0; + for (n = 0; n < FRAMESAMPLES/8; n++) + sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], summ[n]) + 256, 9); + CorrQ7[k+1] = sum; + } +} + + +/* compute inverse AR power spectrum */ +static void CalcInvArSpec(const WebRtc_Word16 *ARCoefQ12, + const WebRtc_Word32 gainQ10, + WebRtc_Word32 *CurveQ16) +{ + WebRtc_Word32 CorrQ11[AR_ORDER+1]; + WebRtc_Word32 sum, tmpGain; + WebRtc_Word32 diffQ16[FRAMESAMPLES/8]; + const WebRtc_Word16 *CS_ptrQ9; + int k, n; + WebRtc_Word16 round, shftVal = 0, sh; + + sum = 0; + for (n = 0; n < AR_ORDER+1; n++) + sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */ + sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16); /* result in Q8 */ + CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9); + + /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */ + if(gainQ10>400000){ + tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3); + round = 32; + shftVal = 6; + } else { + tmpGain = gainQ10; + round = 256; + shftVal = 9; + } + + for (k = 1; k < AR_ORDER+1; k++) { + sum = 16384; + for (n = k; n < AR_ORDER+1; n++) + sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */ + sum = WEBRTC_SPL_RSHIFT_W32(sum, 15); + CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal); + } + sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7); + for (n = 0; n < FRAMESAMPLES/8; n++) + CurveQ16[n] = sum; + + for (k = 1; k < AR_ORDER; k += 2) { + for (n = 0; n < FRAMESAMPLES/8; n++) + CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], CorrQ11[k+1]) + 2, 2); + } + + CS_ptrQ9 = WebRtcIsacfix_kCos[0]; + + /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */ + sh=WebRtcSpl_NormW32(CorrQ11[1]); + if (CorrQ11[1]==0) /* Use next correlation */ + sh=WebRtcSpl_NormW32(CorrQ11[2]); + + if (sh<9) + shftVal = 9 - sh; + else + shftVal = 0; + + for (n = 0; n < FRAMESAMPLES/8; n++) + diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2); + for (k = 2; k < AR_ORDER; k += 2) { + CS_ptrQ9 = WebRtcIsacfix_kCos[k]; + for (n = 0; n < FRAMESAMPLES/8; n++) + diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2); + } + + for (k=0; k<FRAMESAMPLES/8; k++) { + CurveQ16[FRAMESAMPLES/4-1 - k] = CurveQ16[k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal); + CurveQ16[k] += WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal); + } +} + +static void CalcRootInvArSpec(const WebRtc_Word16 *ARCoefQ12, + const WebRtc_Word32 gainQ10, + WebRtc_UWord16 *CurveQ8) +{ + WebRtc_Word32 CorrQ11[AR_ORDER+1]; + WebRtc_Word32 sum, tmpGain; + WebRtc_Word32 summQ16[FRAMESAMPLES/8]; + WebRtc_Word32 diffQ16[FRAMESAMPLES/8]; + + const WebRtc_Word16 *CS_ptrQ9; + int k, n, i; + WebRtc_Word16 round, shftVal = 0, sh; + WebRtc_Word32 res, in_sqrt, newRes; + + sum = 0; + for (n = 0; n < AR_ORDER+1; n++) + sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */ + sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16); /* result in Q8 */ + CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9); + + /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */ + if(gainQ10>400000){ + tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3); + round = 32; + shftVal = 6; + } else { + tmpGain = gainQ10; + round = 256; + shftVal = 9; + } + + for (k = 1; k < AR_ORDER+1; k++) { + sum = 16384; + for (n = k; n < AR_ORDER+1; n++) + sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */ + sum = WEBRTC_SPL_RSHIFT_W32(sum, 15); + CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal); + } + sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7); + for (n = 0; n < FRAMESAMPLES/8; n++) + summQ16[n] = sum; + + for (k = 1; k < (AR_ORDER); k += 2) { + for (n = 0; n < FRAMESAMPLES/8; n++) + summQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_32_16(CorrQ11[k+1],WebRtcIsacfix_kCos[k][n]) + 2, 2); + } + + CS_ptrQ9 = WebRtcIsacfix_kCos[0]; + + /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */ + sh=WebRtcSpl_NormW32(CorrQ11[1]); + if (CorrQ11[1]==0) /* Use next correlation */ + sh=WebRtcSpl_NormW32(CorrQ11[2]); + + if (sh<9) + shftVal = 9 - sh; + else + shftVal = 0; + + for (n = 0; n < FRAMESAMPLES/8; n++) + diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2); + for (k = 2; k < AR_ORDER; k += 2) { + CS_ptrQ9 = WebRtcIsacfix_kCos[k]; + for (n = 0; n < FRAMESAMPLES/8; n++) + diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2); + } + + in_sqrt = summQ16[0] + WEBRTC_SPL_LSHIFT_W32(diffQ16[0], shftVal); + + /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ + res = WEBRTC_SPL_LSHIFT_W32(1, WEBRTC_SPL_RSHIFT_W16(WebRtcSpl_GetSizeInBits(in_sqrt), 1)); + + for (k = 0; k < FRAMESAMPLES/8; k++) + { + in_sqrt = summQ16[k] + WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal); + i = 10; + + /* make in_sqrt positive to prohibit sqrt of negative values */ + if(in_sqrt<0) + in_sqrt=-in_sqrt; + + newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1); + do + { + res = newRes; + newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1); + } while (newRes != res && i-- > 0); + + CurveQ8[k] = (WebRtc_Word16)newRes; + } + for (k = FRAMESAMPLES/8; k < FRAMESAMPLES/4; k++) { + + in_sqrt = summQ16[FRAMESAMPLES/4-1 - k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[FRAMESAMPLES/4-1 - k], shftVal); + i = 10; + + /* make in_sqrt positive to prohibit sqrt of negative values */ + if(in_sqrt<0) + in_sqrt=-in_sqrt; + + newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1); + do + { + res = newRes; + newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1); + } while (newRes != res && i-- > 0); + + CurveQ8[k] = (WebRtc_Word16)newRes; + } + +} + + + +/* generate array of dither samples in Q7 */ +static void GenerateDitherQ7(WebRtc_Word16 *bufQ7, + WebRtc_UWord32 seed, + WebRtc_Word16 length, + WebRtc_Word16 AvgPitchGain_Q12) +{ + int k; + WebRtc_Word16 dither1_Q7, dither2_Q7, dither_gain_Q14, shft; + + if (AvgPitchGain_Q12 < 614) /* this threshold should be equal to that in decode_spec() */ + { + for (k = 0; k < length-2; k += 3) + { + /* new random unsigned WebRtc_Word32 */ + seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; + + /* fixed-point dither sample between -64 and 64 (Q7) */ + dither1_Q7 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)seed + 16777216, 25); // * 128/4294967295 + + /* new random unsigned WebRtc_Word32 */ + seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; + + /* fixed-point dither sample between -64 and 64 */ + dither2_Q7 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(seed + 16777216, 25); + + shft = (WebRtc_Word16)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 15); + if (shft < 5) + { + bufQ7[k] = dither1_Q7; + bufQ7[k+1] = dither2_Q7; + bufQ7[k+2] = 0; + } + else if (shft < 10) + { + bufQ7[k] = dither1_Q7; + bufQ7[k+1] = 0; + bufQ7[k+2] = dither2_Q7; + } + else + { + bufQ7[k] = 0; + bufQ7[k+1] = dither1_Q7; + bufQ7[k+2] = dither2_Q7; + } + } + } + else + { + dither_gain_Q14 = (WebRtc_Word16)(22528 - WEBRTC_SPL_MUL(10, AvgPitchGain_Q12)); + + /* dither on half of the coefficients */ + for (k = 0; k < length-1; k += 2) + { + /* new random unsigned WebRtc_Word32 */ + seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515; + + /* fixed-point dither sample between -64 and 64 */ + dither1_Q7 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)seed + 16777216, 25); + + /* dither sample is placed in either even or odd index */ + shft = (WebRtc_Word16)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 1); /* either 0 or 1 */ + + bufQ7[k + shft] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(dither_gain_Q14, dither1_Q7) + 8192, 14); + bufQ7[k + 1 - shft] = 0; + } + } +} + + + + +/* + * function to decode the complex spectrum from the bitstream + * returns the total number of bytes in the stream + */ +WebRtc_Word16 WebRtcIsacfix_DecodeSpec(Bitstr_dec *streamdata, + WebRtc_Word16 *frQ7, + WebRtc_Word16 *fiQ7, + WebRtc_Word16 AvgPitchGain_Q12) +{ + WebRtc_Word16 data[FRAMESAMPLES]; + WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES/4]; + WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; + WebRtc_Word16 RCQ15[AR_ORDER]; + WebRtc_Word16 gainQ10; + WebRtc_Word32 gain2_Q10; + WebRtc_Word16 len; + int k; + + /* create dither signal */ + GenerateDitherQ7(data, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); /* Dither is output in vector 'Data' */ + + /* decode model parameters */ + if (WebRtcIsacfix_DecodeRcCoef(streamdata, RCQ15) < 0) + return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; + + + WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); + + if (WebRtcIsacfix_DecodeGain2(streamdata, &gain2_Q10) < 0) + return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; + + /* compute inverse AR power spectrum */ + CalcInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); + + /* arithmetic decoding of spectrum */ + /* 'data' input and output. Input = Dither */ + len = WebRtcIsacfix_DecLogisticMulti2(data, streamdata, invARSpec2_Q16, (WebRtc_Word16)FRAMESAMPLES); + + if (len<1) + return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; + + /* subtract dither and scale down spectral samples with low SNR */ + if (AvgPitchGain_Q12 <= 614) + { + for (k = 0; k < FRAMESAMPLES; k += 4) + { + gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)30, 10), + (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (WebRtc_UWord32)2195456, 16)); + *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10); + *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10); + *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10); + *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10); + } + } + else + { + for (k = 0; k < FRAMESAMPLES; k += 4) + { + gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)36, 10), + (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (WebRtc_UWord32)2654208, 16)); + *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10); + *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10); + *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10); + *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10); + } + } + + return len; +} + + +int WebRtcIsacfix_EncodeSpec(const WebRtc_Word16 *fr, + const WebRtc_Word16 *fi, + Bitstr_enc *streamdata, + WebRtc_Word16 AvgPitchGain_Q12) +{ + WebRtc_Word16 dataQ7[FRAMESAMPLES]; + WebRtc_Word32 PSpec[FRAMESAMPLES/4]; + WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES/4]; + WebRtc_Word32 CorrQ7[AR_ORDER+1]; + WebRtc_Word32 CorrQ7_norm[AR_ORDER+1]; + WebRtc_Word16 RCQ15[AR_ORDER]; + WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; + WebRtc_Word32 gain2_Q10; + WebRtc_Word16 val; + WebRtc_Word32 nrg; + WebRtc_UWord32 sum; + WebRtc_Word16 lft_shft; + WebRtc_Word16 status; + int k, n, j; + + + /* create dither_float signal */ + GenerateDitherQ7(dataQ7, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); + + /* add dither and quantize, and compute power spectrum */ + /* Vector dataQ7 contains Dither in Q7 */ + for (k = 0; k < FRAMESAMPLES; k += 4) + { + val = ((*fr++ + dataQ7[k] + 64) & 0xFF80) - dataQ7[k]; /* Data = Dither */ + dataQ7[k] = val; /* New value in Data */ + sum = WEBRTC_SPL_UMUL(val, val); + + val = ((*fi++ + dataQ7[k+1] + 64) & 0xFF80) - dataQ7[k+1]; /* Data = Dither */ + dataQ7[k+1] = val; /* New value in Data */ + sum += WEBRTC_SPL_UMUL(val, val); + + val = ((*fr++ + dataQ7[k+2] + 64) & 0xFF80) - dataQ7[k+2]; /* Data = Dither */ + dataQ7[k+2] = val; /* New value in Data */ + sum += WEBRTC_SPL_UMUL(val, val); + + val = ((*fi++ + dataQ7[k+3] + 64) & 0xFF80) - dataQ7[k+3]; /* Data = Dither */ + dataQ7[k+3] = val; /* New value in Data */ + sum += WEBRTC_SPL_UMUL(val, val); + + PSpec[k>>2] = WEBRTC_SPL_RSHIFT_U32(sum, 2); + } + + /* compute correlation from power spectrum */ + CalcCorrelation(PSpec, CorrQ7); + + + /* find AR coefficients */ + /* number of bit shifts to 14-bit normalize CorrQ7[0] (leaving room for sign) */ + lft_shft = WebRtcSpl_NormW32(CorrQ7[0]) - 18; + + if (lft_shft > 0) { + for (k=0; k<AR_ORDER+1; k++) + CorrQ7_norm[k] = WEBRTC_SPL_LSHIFT_W32(CorrQ7[k], lft_shft); + } else { + for (k=0; k<AR_ORDER+1; k++) + CorrQ7_norm[k] = WEBRTC_SPL_RSHIFT_W32(CorrQ7[k], -lft_shft); + } + + /* find RC coefficients */ + WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15); + + /* quantize & code RC Coef */ + status = WebRtcIsacfix_EncodeRcCoef(RCQ15, streamdata); + if (status < 0) { + return status; + } + + /* RC -> AR coefficients */ + WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); + + /* compute ARCoef' * Corr * ARCoef in Q19 */ + nrg = 0; + for (j = 0; j <= AR_ORDER; j++) { + for (n = 0; n <= j; n++) + nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[j-n], ARCoefQ12[n]) + 256, 9)) + 4, 3); + for (n = j+1; n <= AR_ORDER; n++) + nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[n-j], ARCoefQ12[n]) + 256, 9)) + 4, 3); + } + + if (lft_shft > 0) + nrg = WEBRTC_SPL_RSHIFT_W32(nrg, lft_shft); + else + nrg = WEBRTC_SPL_LSHIFT_W32(nrg, -lft_shft); + + if(nrg>131072) + gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES >> 2, nrg); /* also shifts 31 bits to the left! */ + else + gain2_Q10 = WEBRTC_SPL_RSHIFT_W32(FRAMESAMPLES, 2); + + /* quantize & code gain2_Q10 */ + if (WebRtcIsacfix_EncodeGain2(&gain2_Q10, streamdata)) + return -1; + + /* compute inverse AR magnitude spectrum */ + CalcRootInvArSpec(ARCoefQ12, gain2_Q10, invARSpecQ8); + + + /* arithmetic coding of spectrum */ + status = WebRtcIsacfix_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, (WebRtc_Word16)FRAMESAMPLES); + if ( status ) + return( status ); + + return 0; +} + + +/* Matlab's LAR definition */ +static void Rc2LarFix(const WebRtc_Word16 *rcQ15, WebRtc_Word32 *larQ17, WebRtc_Word16 order) { + + /* + + This is a piece-wise implemenetation of a rc2lar-function (all values in the comment + are Q15 values and are based on [0 24956/32768 30000/32768 32500/32768], i.e. + [0.76159667968750 0.91552734375000 0.99182128906250] + + x0 x1 a k x0(again) b + ================================================================================== + 0.00 0.76: 0 2.625997508581 0 0 + 0.76 0.91: 2.000012018559 7.284502668663 0.761596679688 -3.547841027073 + 0.91 0.99: 3.121320351712 31.115835041229 0.915527343750 -25.366077452148 + 0.99 1.00: 5.495270168700 686.663805654056 0.991821289063 -675.552510708011 + + The implementation is y(x)= a + (x-x0)*k, but this can be simplified to + + y(x) = a-x0*k + x*k = b + x*k, where b = a-x0*k + + akx=[0 2.625997508581 0 + 2.000012018559 7.284502668663 0.761596679688 + 3.121320351712 31.115835041229 0.915527343750 + 5.495270168700 686.663805654056 0.991821289063]; + + b = akx(:,1) - akx(:,3).*akx(:,2) + + [ 0.0 + -3.547841027073 + -25.366077452148 + -675.552510708011] + + */ + + int k; + WebRtc_Word16 rc; + WebRtc_Word32 larAbsQ17; + + for (k = 0; k < order; k++) { + + rc = WEBRTC_SPL_ABS_W16(rcQ15[k]); //Q15 + + /* Calculate larAbsQ17 in Q17 from rc in Q15 */ + + if (rc<24956) { //0.7615966 in Q15 + // (Q15*Q13)>>11 = Q17 + larAbsQ17 = WEBRTC_SPL_MUL_16_16_RSFT(rc, 21512, 11); + } else if (rc<30000) { //0.91552734375 in Q15 + // Q17 + (Q15*Q12)>>10 = Q17 + larAbsQ17 = -465024 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 29837, 10); + } else if (rc<32500) { //0.99182128906250 in Q15 + // Q17 + (Q15*Q10)>>8 = Q17 + larAbsQ17 = -3324784 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 31863, 8); + } else { + // Q17 + (Q15*Q5)>>3 = Q17 + larAbsQ17 = -88546020 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 21973, 3); + } + + if (rcQ15[k]>0) { + larQ17[k] = larAbsQ17; + } else { + larQ17[k] = -larAbsQ17; + } + } +} + + +static void Lar2RcFix(const WebRtc_Word32 *larQ17, WebRtc_Word16 *rcQ15, WebRtc_Word16 order) { + + /* + This is a piece-wise implemenetation of a lar2rc-function + See comment in Rc2LarFix() about details. + */ + + int k; + WebRtc_Word16 larAbsQ11; + WebRtc_Word32 rc; + + for (k = 0; k < order; k++) { + + larAbsQ11 = (WebRtc_Word16) WEBRTC_SPL_ABS_W32(WEBRTC_SPL_RSHIFT_W32(larQ17[k]+32,6)); //Q11 + + if (larAbsQ11<4097) { //2.000012018559 in Q11 + // Q11*Q16>>12 = Q15 + rc = WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24957, 12); + } else if (larAbsQ11<6393) { //3.121320351712 in Q11 + // (Q11*Q17 + Q13)>>13 = Q15 + rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 17993) + 130738688), 13); + } else if (larAbsQ11<11255) { //5.495270168700 in Q11 + // (Q11*Q19 + Q30)>>15 = Q15 + rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 16850) + 875329820), 15); + } else { + // (Q11*Q24>>16 + Q19)>>4 = Q15 + rc = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24433, 16)) + 515804), 4); + } + + if (larQ17[k]<=0) { + rc = -rc; + } + + rcQ15[k] = (WebRtc_Word16) rc; // Q15 + } +} + +static void Poly2LarFix(WebRtc_Word16 *lowbandQ15, + WebRtc_Word16 orderLo, + WebRtc_Word16 *hibandQ15, + WebRtc_Word16 orderHi, + WebRtc_Word16 Nsub, + WebRtc_Word32 *larsQ17) { + + int k, n; + WebRtc_Word32 *outpQ17; + WebRtc_Word16 orderTot; + WebRtc_Word32 larQ17[MAX_ORDER]; // Size 7+6 is enough + + orderTot = (orderLo + orderHi); + outpQ17 = larsQ17; + for (k = 0; k < Nsub; k++) { + + Rc2LarFix(lowbandQ15, larQ17, orderLo); + + for (n = 0; n < orderLo; n++) + outpQ17[n] = larQ17[n]; //Q17 + + Rc2LarFix(hibandQ15, larQ17, orderHi); + + for (n = 0; n < orderHi; n++) + outpQ17[n + orderLo] = larQ17[n]; //Q17; + + outpQ17 += orderTot; + lowbandQ15 += orderLo; + hibandQ15 += orderHi; + } +} + + +static void Lar2polyFix(WebRtc_Word32 *larsQ17, + WebRtc_Word16 *lowbandQ15, + WebRtc_Word16 orderLo, + WebRtc_Word16 *hibandQ15, + WebRtc_Word16 orderHi, + WebRtc_Word16 Nsub) { + + int k, n; + WebRtc_Word16 orderTot; + WebRtc_Word16 *outplQ15, *outphQ15; + WebRtc_Word32 *inpQ17; + WebRtc_Word16 rcQ15[7+6]; + + orderTot = (orderLo + orderHi); + outplQ15 = lowbandQ15; + outphQ15 = hibandQ15; + inpQ17 = larsQ17; + for (k = 0; k < Nsub; k++) { + + /* gains not handled here as in the FLP version */ + + /* Low band */ + Lar2RcFix(&inpQ17[0], rcQ15, orderLo); + for (n = 0; n < orderLo; n++) + outplQ15[n] = rcQ15[n]; // Refl. coeffs + + /* High band */ + Lar2RcFix(&inpQ17[orderLo], rcQ15, orderHi); + for (n = 0; n < orderHi; n++) + outphQ15[n] = rcQ15[n]; // Refl. coeffs + + inpQ17 += orderTot; + outplQ15 += orderLo; + outphQ15 += orderHi; + } +} + +int WebRtcIsacfix_DecodeLpc(WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 *LPCCoef_loQ15, + WebRtc_Word16 *LPCCoef_hiQ15, + Bitstr_dec *streamdata, + WebRtc_Word16 *outmodel) { + + WebRtc_Word32 larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_GAIN+KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES + int err; + + err = WebRtcIsacfix_DecodeLpcCoef(streamdata, larsQ17, gain_lo_hiQ17, outmodel); + if (err<0) // error check + return -ISAC_RANGE_ERROR_DECODE_LPC; + + Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES); + + return 0; +} + +/* decode & dequantize LPC Coef */ +int WebRtcIsacfix_DecodeLpcCoef(Bitstr_dec *streamdata, + WebRtc_Word32 *LPCCoefQ17, + WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 *outmodel) +{ + int j, k, n; + int err; + WebRtc_Word16 pos, pos2, posg, poss, offsg, offss, offs2; + WebRtc_Word16 gainpos; + WebRtc_Word16 model; + WebRtc_Word16 index_QQ[KLT_ORDER_SHAPE]; + WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN]; + WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; + WebRtc_Word16 tmpcoeffs_sQ10[KLT_ORDER_SHAPE]; + WebRtc_Word32 tmpcoeffs_sQ17[KLT_ORDER_SHAPE]; + WebRtc_Word32 tmpcoeffs2_sQ18[KLT_ORDER_SHAPE]; + WebRtc_Word32 sumQQ; + WebRtc_Word16 sumQQ16; + WebRtc_Word32 tmp32; + + + + /* entropy decoding of model number */ + err = WebRtcIsacfix_DecHistOneStepMulti(&model, streamdata, WebRtcIsacfix_kModelCdfPtr, WebRtcIsacfix_kModelInitIndex, 1); + if (err<0) // error check + return err; + + /* entropy decoding of quantization indices */ + err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfShapePtr[model], WebRtcIsacfix_kInitIndexShape[model], KLT_ORDER_SHAPE); + if (err<0) // error check + return err; + /* find quantization levels for coefficients */ + for (k=0; k<KLT_ORDER_SHAPE; k++) { + tmpcoeffs_sQ10[WebRtcIsacfix_kSelIndShape[k]] = WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[model]+WebRtcIsacfix_kOffsetShape[model][k] + index_QQ[k]]; + } + + err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfGainPtr[model], WebRtcIsacfix_kInitIndexGain[model], KLT_ORDER_GAIN); + if (err<0) // error check + return err; + /* find quantization levels for coefficients */ + for (k=0; k<KLT_ORDER_GAIN; k++) { + tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[model]+ WebRtcIsacfix_kOffsetGain[model][k] + index_QQ[k]]; + } + + + /* inverse KLT */ + + /* left transform */ // Transpose matrix! + offsg = 0; + offss = 0; + posg = 0; + poss = 0; + for (j=0; j<SUBFRAMES; j++) { + offs2 = 0; + for (k=0; k<2; k++) { + sumQQ = 0; + pos = offsg; + pos2 = offs2; + for (n=0; n<2; n++) { + sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[model][pos2], tmpcoeffs_gQ17[pos]<<5)); // (Q15*Q17)>>(16-5) = Q21 + pos++; + pos2++; + } + tmpcoeffs2_gQ21[posg] = sumQQ; //Q21 + posg++; + offs2 += 2; + } + offs2 = 0; + + for (k=0; k<LPC_SHAPE_ORDER; k++) { + sumQQ = 0; + pos = offss; + pos2 = offs2; + for (n=0; n<LPC_SHAPE_ORDER; n++) { + sumQQ += WEBRTC_SPL_MUL_16_16_RSFT(tmpcoeffs_sQ10[pos], WebRtcIsacfix_kT1ShapeQ15[model][pos2], 7); // (Q10*Q15)>>7 = Q18 + pos++; + pos2++; + } + tmpcoeffs2_sQ18[poss] = sumQQ; //Q18 + poss++; + offs2 += LPC_SHAPE_ORDER; + } + offsg += 2; + offss += LPC_SHAPE_ORDER; + } + + /* right transform */ // Transpose matrix + offsg = 0; + offss = 0; + posg = 0; + poss = 0; + for (j=0; j<SUBFRAMES; j++) { + posg = offsg; + for (k=0; k<2; k++) { + sumQQ = 0; + pos = k; + pos2 = j; + for (n=0; n<SUBFRAMES; n++) { + sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[model][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21 + pos += 2; + pos2 += SUBFRAMES; + + } + tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4); + posg++; + } + poss = offss; + for (k=0; k<LPC_SHAPE_ORDER; k++) { + sumQQ = 0; + pos = k; + pos2 = j; + for (n=0; n<SUBFRAMES; n++) { + sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2ShapeQ15[model][pos2], tmpcoeffs2_sQ18[pos])); // (Q15*Q18)>>16 = Q17 + pos += LPC_SHAPE_ORDER; + pos2 += SUBFRAMES; + } + tmpcoeffs_sQ17[poss] = sumQQ; + poss++; + } + offsg += 2; + offss += LPC_SHAPE_ORDER; + } + + /* scaling, mean addition, and gain restoration */ + gainpos = 0; + posg = 0;poss = 0;pos=0; + for (k=0; k<SUBFRAMES; k++) { + + /* log gains */ + sumQQ16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9 + sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg]; + sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out + gain_lo_hiQ17[gainpos] = sumQQ; //Q17 + gainpos++; + posg++; + + sumQQ16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9 + sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg]; + sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out + gain_lo_hiQ17[gainpos] = sumQQ; //Q17 + gainpos++; + posg++; + + /* lo band LAR coeffs */ + for (n=0; n<ORDERLO; n++, pos++, poss++) { + tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(31208, tmpcoeffs_sQ17[poss]); // (Q16*Q17)>>16 = Q17, with 1/2.1 = 0.47619047619 ~= 31208 in Q16 + tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17 + LPCCoefQ17[pos] = tmp32; + } + + /* hi band LAR coeffs */ + for (n=0; n<ORDERHI; n++, pos++, poss++) { + tmp32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]), 3); // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13 + tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17 + LPCCoefQ17[pos] = tmp32; + } + } + + + *outmodel=model; + + return 0; +} + +/* estimate codel length of LPC Coef */ +static int EstCodeLpcCoef(WebRtc_Word32 *LPCCoefQ17, + WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 *model, + WebRtc_Word32 *sizeQ11, + Bitstr_enc *streamdata, + ISAC_SaveEncData_t* encData, + transcode_obj *transcodingParam) { + int j, k, n; + WebRtc_Word16 posQQ, pos2QQ, gainpos; + WebRtc_Word16 pos, pos2, poss, posg, offsg, offss, offs2; + WebRtc_Word16 index_gQQ[KLT_ORDER_GAIN], index_sQQ[KLT_ORDER_SHAPE]; + WebRtc_Word16 index_ovr_gQQ[KLT_ORDER_GAIN], index_ovr_sQQ[KLT_ORDER_SHAPE]; + WebRtc_Word32 BitsQQ; + + WebRtc_Word16 tmpcoeffs_gQ6[KLT_ORDER_GAIN]; + WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN]; + WebRtc_Word32 tmpcoeffs_sQ17[KLT_ORDER_SHAPE]; + WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; + WebRtc_Word32 tmpcoeffs2_sQ17[KLT_ORDER_SHAPE]; + WebRtc_Word32 sumQQ; + WebRtc_Word32 tmp32; + WebRtc_Word16 sumQQ16; + int status = 0; + + /* write LAR coefficients to statistics file */ + /* Save data for creation of multiple bitstreams (and transcoding) */ + if (encData != NULL) { + for (k=0; k<KLT_ORDER_GAIN; k++) { + encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k]; + } + } + + /* log gains, mean removal and scaling */ + posg = 0;poss = 0;pos=0; gainpos=0; + + for (k=0; k<SUBFRAMES; k++) { + /* log gains */ + + /* The input argument X to logN(X) is 2^17 times higher than the + input floating point argument Y to log(Y), since the X value + is a Q17 value. This can be compensated for after the call, by + subraction a value Z for each Q-step. One Q-step means that + X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = + 177.445678 should be subtracted (since logN() returns a Q8 value). + For a X value in Q17, the value 177.445678*17 = 3017 should be + subtracted */ + tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 + tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 + posg++; gainpos++; + + tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 + tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 + posg++; gainpos++; + + /* lo band LAR coeffs */ + for (n=0; n<ORDERLO; n++, poss++, pos++) { + tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17 + tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(17203, tmp32<<3); // tmp32 = 2.1*tmp32 + tmpcoeffs_sQ17[poss] = tmp32; //Q17 + } + + /* hi band LAR coeffs */ + for (n=0; n<ORDERHI; n++, poss++, pos++) { + tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17 + tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(14746, tmp32<<1); // tmp32 = 0.45*tmp32 + tmpcoeffs_sQ17[poss] = tmp32; //Q17 + } + + } + + + /* KLT */ + + /* left transform */ + offsg = 0; + offss = 0; + for (j=0; j<SUBFRAMES; j++) { + posg = offsg; + for (k=0; k<2; k++) { + sumQQ = 0; + pos = offsg; + pos2 = k; + for (n=0; n<2; n++) { + sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[pos], WebRtcIsacfix_kT1GainQ15[0][pos2]); //Q21 = Q6*Q15 + pos++; + pos2 += 2; + } + tmpcoeffs2_gQ21[posg] = sumQQ; + posg++; + } + poss = offss; + for (k=0; k<LPC_SHAPE_ORDER; k++) { + sumQQ = 0; + pos = offss; + pos2 = k; + for (n=0; n<LPC_SHAPE_ORDER; n++) { + sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1ShapeQ15[0][pos2], tmpcoeffs_sQ17[pos]<<1)); // (Q15*Q17)>>(16-1) = Q17 + pos++; + pos2 += LPC_SHAPE_ORDER; + } + tmpcoeffs2_sQ17[poss] = sumQQ; //Q17 + poss++; + } + offsg += 2; + offss += LPC_SHAPE_ORDER; + } + + /* right transform */ + offsg = 0; + offss = 0; + offs2 = 0; + for (j=0; j<SUBFRAMES; j++) { + posg = offsg; + for (k=0; k<2; k++) { + sumQQ = 0; + pos = k; + pos2 = offs2; + for (n=0; n<SUBFRAMES; n++) { + sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[0][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21 + pos += 2; + pos2++; + } + tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4); + posg++; + } + poss = offss; + for (k=0; k<LPC_SHAPE_ORDER; k++) { + sumQQ = 0; + pos = k; + pos2 = offs2; + for (n=0; n<SUBFRAMES; n++) { + sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2ShapeQ15[0][pos2], tmpcoeffs2_sQ17[pos]<<1)); // (Q15*Q17)>>(16-1) = Q17 + pos += LPC_SHAPE_ORDER; + pos2++; + } + tmpcoeffs_sQ17[poss] = sumQQ; + poss++; + } + offs2 += SUBFRAMES; + offsg += 2; + offss += LPC_SHAPE_ORDER; + } + + /* quantize coefficients */ + + BitsQQ = 0; + for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? + { + posQQ = WebRtcIsacfix_kSelIndGain[k]; + pos2QQ= (WebRtc_Word16)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); + + index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? + if (index_gQQ[k] < 0) { + index_gQQ[k] = 0; + } + else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { + index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; + } + index_ovr_gQQ[k] = WebRtcIsacfix_kOffsetGain[0][k]+index_gQQ[k]; + posQQ = WebRtcIsacfix_kOfLevelsGain[0] + index_ovr_gQQ[k]; + + /* Save data for creation of multiple bitstreams */ + if (encData != NULL) { + encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k]; + } + + /* determine number of bits */ + sumQQ = WebRtcIsacfix_kCodeLenGainQ11[posQQ]; //Q11 + BitsQQ += sumQQ; + } + + for (k=0; k<KLT_ORDER_SHAPE; k++) //ATTN: ok? + { + index_sQQ[k] = (WebRtc_Word16)(CalcLrIntQ(tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]], 17) + WebRtcIsacfix_kQuantMinShape[k]); //ATTN: ok? + + if (index_sQQ[k] < 0) + index_sQQ[k] = 0; + else if (index_sQQ[k] > WebRtcIsacfix_kMaxIndShape[k]) + index_sQQ[k] = WebRtcIsacfix_kMaxIndShape[k]; + index_ovr_sQQ[k] = WebRtcIsacfix_kOffsetShape[0][k]+index_sQQ[k]; + + posQQ = WebRtcIsacfix_kOfLevelsShape[0] + index_ovr_sQQ[k]; + sumQQ = WebRtcIsacfix_kCodeLenShapeQ11[posQQ]; //Q11 + BitsQQ += sumQQ; + } + + + + *model = 0; + *sizeQ11=BitsQQ; + + /* entropy coding of model number */ + status = WebRtcIsacfix_EncHistMulti(streamdata, model, WebRtcIsacfix_kModelCdfPtr, 1); + if (status < 0) { + return status; + } + + /* entropy coding of quantization indices - shape only */ + status = WebRtcIsacfix_EncHistMulti(streamdata, index_sQQ, WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE); + if (status < 0) { + return status; + } + + /* Save data for creation of multiple bitstreams */ + if (encData != NULL) { + for (k=0; k<KLT_ORDER_SHAPE; k++) + { + encData->LPCindex_s[KLT_ORDER_SHAPE*encData->startIdx + k] = index_sQQ[k]; + } + } + /* save the state of the bitstream object 'streamdata' for the possible bit-rate reduction */ + transcodingParam->full = streamdata->full; + transcodingParam->stream_index = streamdata->stream_index; + transcodingParam->streamval = streamdata->streamval; + transcodingParam->W_upper = streamdata->W_upper; + transcodingParam->beforeLastWord = streamdata->stream[streamdata->stream_index-1]; + transcodingParam->lastWord = streamdata->stream[streamdata->stream_index]; + + /* entropy coding of index */ + status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN); + if (status < 0) { + return status; + } + + /* find quantization levels for shape coefficients */ + for (k=0; k<KLT_ORDER_SHAPE; k++) { + tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]] = WEBRTC_SPL_MUL(128, WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[0]+index_ovr_sQQ[k]]); + + } + /* inverse KLT */ + + /* left transform */ // Transpose matrix! + offss = 0; + poss = 0; + for (j=0; j<SUBFRAMES; j++) { + offs2 = 0; + for (k=0; k<LPC_SHAPE_ORDER; k++) { + sumQQ = 0; + pos = offss; + pos2 = offs2; + for (n=0; n<LPC_SHAPE_ORDER; n++) { + sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1ShapeQ15[0][pos2], tmpcoeffs_sQ17[pos]<<1)); // (Q15*Q17)>>(16-1) = Q17 + pos++; + pos2++; + } + tmpcoeffs2_sQ17[poss] = sumQQ; + + poss++; + offs2 += LPC_SHAPE_ORDER; + } + offss += LPC_SHAPE_ORDER; + } + + + /* right transform */ // Transpose matrix + offss = 0; + poss = 0; + for (j=0; j<SUBFRAMES; j++) { + poss = offss; + for (k=0; k<LPC_SHAPE_ORDER; k++) { + sumQQ = 0; + pos = k; + pos2 = j; + for (n=0; n<SUBFRAMES; n++) { + sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2ShapeQ15[0][pos2], tmpcoeffs2_sQ17[pos]<<1)); // (Q15*Q17)>>(16-1) = Q17 + pos += LPC_SHAPE_ORDER; + pos2 += SUBFRAMES; + } + tmpcoeffs_sQ17[poss] = sumQQ; + poss++; + } + offss += LPC_SHAPE_ORDER; + } + + /* scaling, mean addition, and gain restoration */ + poss = 0;pos=0; + for (k=0; k<SUBFRAMES; k++) { + + /* lo band LAR coeffs */ + for (n=0; n<ORDERLO; n++, pos++, poss++) { + tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(31208, tmpcoeffs_sQ17[poss]); // (Q16*Q17)>>16 = Q17, with 1/2.1 = 0.47619047619 ~= 31208 in Q16 + tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17 + LPCCoefQ17[pos] = tmp32; + } + + /* hi band LAR coeffs */ + for (n=0; n<ORDERHI; n++, pos++, poss++) { + tmp32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]), 3); // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13 + tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17 + LPCCoefQ17[pos] = tmp32; + } + + } + + //to update tmpcoeffs_gQ17 to the proper state + for (k=0; k<KLT_ORDER_GAIN; k++) { + tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[0]+index_ovr_gQQ[k]]; + } + + + + /* find quantization levels for coefficients */ + + /* left transform */ + offsg = 0; + posg = 0; + for (j=0; j<SUBFRAMES; j++) { + offs2 = 0; + for (k=0; k<2; k++) { + sumQQ = 0; + pos = offsg; + pos2 = offs2; + for (n=0; n<2; n++) { + sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][pos2], tmpcoeffs_gQ17[pos])<<1); // (Q15*Q17)>>(16-1) = Q17 + pos++; + pos2++; + } + tmpcoeffs2_gQ21[posg] = WEBRTC_SPL_LSHIFT_W32(sumQQ, 4); //Q17<<4 = Q21 + posg++; + offs2 += 2; + } + offsg += 2; + } + + /* right transform */ // Transpose matrix + offsg = 0; + posg = 0; + for (j=0; j<SUBFRAMES; j++) { + posg = offsg; + for (k=0; k<2; k++) { + sumQQ = 0; + pos = k; + pos2 = j; + for (n=0; n<SUBFRAMES; n++) { + sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[0][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21 + pos += 2; + pos2 += SUBFRAMES; + } + tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4); + posg++; + } + offsg += 2; + } + + /* scaling, mean addition, and gain restoration */ + posg = 0; + gainpos = 0; + for (k=0; k<2*SUBFRAMES; k++) { + + sumQQ16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9 + sumQQ16 += WebRtcIsacfix_kMeansGainQ8[0][posg]; + sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out + gain_lo_hiQ17[gainpos] = sumQQ; //Q17 + + gainpos++; + pos++;posg++; + } + + return 0; +} + +int WebRtcIsacfix_EstCodeLpcGain(WebRtc_Word32 *gain_lo_hiQ17, + Bitstr_enc *streamdata, + ISAC_SaveEncData_t* encData) { + int j, k, n; + WebRtc_Word16 posQQ, pos2QQ, gainpos; + WebRtc_Word16 pos, pos2, posg, offsg, offs2; + WebRtc_Word16 index_gQQ[KLT_ORDER_GAIN]; + + WebRtc_Word16 tmpcoeffs_gQ6[KLT_ORDER_GAIN]; + WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN]; + WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; + WebRtc_Word32 sumQQ; + int status = 0; + + /* write LAR coefficients to statistics file */ + /* Save data for creation of multiple bitstreams (and transcoding) */ + if (encData != NULL) { + for (k=0; k<KLT_ORDER_GAIN; k++) { + encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k]; + } + } + + /* log gains, mean removal and scaling */ + posg = 0; pos = 0; gainpos = 0; + + for (k=0; k<SUBFRAMES; k++) { + /* log gains */ + + /* The input argument X to logN(X) is 2^17 times higher than the + input floating point argument Y to log(Y), since the X value + is a Q17 value. This can be compensated for after the call, by + subraction a value Z for each Q-step. One Q-step means that + X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = + 177.445678 should be subtracted (since logN() returns a Q8 value). + For a X value in Q17, the value 177.445678*17 = 3017 should be + subtracted */ + tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 + tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 + posg++; gainpos++; + + tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 + tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 + posg++; gainpos++; + } + + + /* KLT */ + + /* left transform */ + offsg = 0; + for (j=0; j<SUBFRAMES; j++) { + posg = offsg; + for (k=0; k<2; k++) { + sumQQ = 0; + pos = offsg; + pos2 = k; + for (n=0; n<2; n++) { + sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[pos], WebRtcIsacfix_kT1GainQ15[0][pos2]); //Q21 = Q6*Q15 + pos++; + pos2 += 2; + } + tmpcoeffs2_gQ21[posg] = sumQQ; + posg++; + } + offsg += 2; + } + + /* right transform */ + offsg = 0; + offs2 = 0; + for (j=0; j<SUBFRAMES; j++) { + posg = offsg; + for (k=0; k<2; k++) { + sumQQ = 0; + pos = k; + pos2 = offs2; + for (n=0; n<SUBFRAMES; n++) { + sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[0][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21 + pos += 2; + pos2++; + } + tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4); + posg++; + } + offsg += 2; + offs2 += SUBFRAMES; + } + + /* quantize coefficients */ + + for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? + { + posQQ = WebRtcIsacfix_kSelIndGain[k]; + pos2QQ= (WebRtc_Word16)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); + + index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? + if (index_gQQ[k] < 0) { + index_gQQ[k] = 0; + } + else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { + index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; + } + + /* Save data for creation of multiple bitstreams */ + if (encData != NULL) { + encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k]; + } + } + + /* entropy coding of index */ + status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN); + if (status < 0) { + return status; + } + + return 0; +} + + +int WebRtcIsacfix_EncodeLpc(WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 *LPCCoef_loQ15, + WebRtc_Word16 *LPCCoef_hiQ15, + WebRtc_Word16 *model, + WebRtc_Word32 *sizeQ11, + Bitstr_enc *streamdata, + ISAC_SaveEncData_t* encData, + transcode_obj *transcodeParam) +{ + int status = 0; + WebRtc_Word32 larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES + // = (6+12)*6 == 108 + + Poly2LarFix(LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES, larsQ17); + + status = EstCodeLpcCoef(larsQ17, gain_lo_hiQ17, model, sizeQ11, streamdata, encData, transcodeParam); + if (status < 0) { + return (status); + } + + Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES); + + return 0; +} + + +/* decode & dequantize RC */ +int WebRtcIsacfix_DecodeRcCoef(Bitstr_dec *streamdata, WebRtc_Word16 *RCQ15) +{ + int k, err; + WebRtc_Word16 index[AR_ORDER]; + + /* entropy decoding of quantization indices */ + err = WebRtcIsacfix_DecHistOneStepMulti(index, streamdata, WebRtcIsacfix_kRcCdfPtr, WebRtcIsacfix_kRcInitInd, AR_ORDER); + if (err<0) // error check + return err; + + /* find quantization levels for reflection coefficients */ + for (k=0; k<AR_ORDER; k++) + { + RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]); + } + + return 0; +} + + + +/* quantize & code RC */ +int WebRtcIsacfix_EncodeRcCoef(WebRtc_Word16 *RCQ15, Bitstr_enc *streamdata) +{ + int k; + WebRtc_Word16 index[AR_ORDER]; + int status; + + /* quantize reflection coefficients (add noise feedback?) */ + for (k=0; k<AR_ORDER; k++) + { + index[k] = WebRtcIsacfix_kRcInitInd[k]; + + if (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k]]) + { + while (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k] + 1]) + index[k]++; + } + else + { + while (RCQ15[k] < WebRtcIsacfix_kRcBound[--index[k]]) ; + } + + RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]); + } + + + /* entropy coding of quantization indices */ + status = WebRtcIsacfix_EncHistMulti(streamdata, index, WebRtcIsacfix_kRcCdfPtr, AR_ORDER); + + /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ + return status; +} + + +/* decode & dequantize squared Gain */ +int WebRtcIsacfix_DecodeGain2(Bitstr_dec *streamdata, WebRtc_Word32 *gainQ10) +{ + int err; + WebRtc_Word16 index; + + /* entropy decoding of quantization index */ + err = WebRtcIsacfix_DecHistOneStepMulti( + &index, + streamdata, + WebRtcIsacfix_kGainPtr, + WebRtcIsacfix_kGainInitInd, + 1); + /* error check */ + if (err<0) { + return err; + } + + /* find quantization level */ + *gainQ10 = WebRtcIsacfix_kGain2Lev[index]; + + return 0; +} + + + +/* quantize & code squared Gain */ +int WebRtcIsacfix_EncodeGain2(WebRtc_Word32 *gainQ10, Bitstr_enc *streamdata) +{ + WebRtc_Word16 index; + int status = 0; + + /* find quantization index */ + index = WebRtcIsacfix_kGainInitInd[0]; + if (*gainQ10 > WebRtcIsacfix_kGain2Bound[index]) + { + while (*gainQ10 > WebRtcIsacfix_kGain2Bound[index + 1]) + index++; + } + else + { + while (*gainQ10 < WebRtcIsacfix_kGain2Bound[--index]) ; + } + + /* dequantize */ + *gainQ10 = WebRtcIsacfix_kGain2Lev[index]; + + /* entropy coding of quantization index */ + status = WebRtcIsacfix_EncHistMulti(streamdata, &index, WebRtcIsacfix_kGainPtr, 1); + + /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ + return status; +} + + +/* code and decode Pitch Gains and Lags functions */ + +/* decode & dequantize Pitch Gains */ +int WebRtcIsacfix_DecodePitchGain(Bitstr_dec *streamdata, WebRtc_Word16 *PitchGains_Q12) +{ + int err; + WebRtc_Word16 index_comb; + const WebRtc_UWord16 *pitch_gain_cdf_ptr[1]; + + /* entropy decoding of quantization indices */ + *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf; + err = WebRtcIsacfix_DecHistBisectMulti(&index_comb, streamdata, pitch_gain_cdf_ptr, WebRtcIsacfix_kCdfTableSizeGain, 1); + /* error check, Q_mean_Gain.. tables are of size 144 */ + if ((err<0) || (index_comb<0) || (index_comb>144)) + return -ISAC_RANGE_ERROR_DECODE_PITCH_GAIN; + + /* unquantize back to pitch gains by table look-up */ + PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb]; + PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb]; + PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb]; + PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb]; + + return 0; +} + + +/* quantize & code Pitch Gains */ +int WebRtcIsacfix_EncodePitchGain(WebRtc_Word16 *PitchGains_Q12, Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData) +{ + int k,j; + WebRtc_Word16 SQ15[PITCH_SUBFRAMES]; + WebRtc_Word16 index[3]; + WebRtc_Word16 index_comb; + const WebRtc_UWord16 *pitch_gain_cdf_ptr[1]; + WebRtc_Word32 CQ17; + int status = 0; + + + /* get the approximate arcsine (almost linear)*/ + for (k=0; k<PITCH_SUBFRAMES; k++) + SQ15[k] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(PitchGains_Q12[k],33,2); //Q15 + + + /* find quantization index; only for the first three transform coefficients */ + for (k=0; k<3; k++) + { + /* transform */ + CQ17=0; + for (j=0; j<PITCH_SUBFRAMES; j++) { + CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], SQ15[j],10); // Q17 + } + + index[k] = (WebRtc_Word16)((CQ17 + 8192)>>14); // Rounding and scaling with stepsize (=1/0.125=8) + + /* check that the index is not outside the boundaries of the table */ + if (index[k] < WebRtcIsacfix_kLowerlimiGain[k]) index[k] = WebRtcIsacfix_kLowerlimiGain[k]; + else if (index[k] > WebRtcIsacfix_kUpperlimitGain[k]) index[k] = WebRtcIsacfix_kUpperlimitGain[k]; + index[k] -= WebRtcIsacfix_kLowerlimiGain[k]; + } + + /* calculate unique overall index */ + index_comb = (WebRtc_Word16)(WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[0], index[0]) + + WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[1], index[1]) + index[2]); + + /* unquantize back to pitch gains by table look-up */ + // (Y) + PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb]; + PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb]; + PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb]; + PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb]; + + + /* entropy coding of quantization pitch gains */ + *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf; + status = WebRtcIsacfix_EncHistMulti(streamdata, &index_comb, pitch_gain_cdf_ptr, 1); + if (status < 0) { + return status; + } + + /* Save data for creation of multiple bitstreams */ + if (encData != NULL) { + encData->pitchGain_index[encData->startIdx] = index_comb; + } + + return 0; +} + + + +/* Pitch LAG */ + + +/* decode & dequantize Pitch Lags */ +int WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata, + WebRtc_Word16 *PitchGain_Q12, + WebRtc_Word16 *PitchLags_Q7) +{ + int k, err; + WebRtc_Word16 index[PITCH_SUBFRAMES]; + const WebRtc_Word16 *mean_val2Q10, *mean_val4Q10; + + const WebRtc_Word16 *lower_limit; + const WebRtc_UWord16 *init_index; + const WebRtc_UWord16 *cdf_size; + const WebRtc_UWord16 **cdf; + + WebRtc_Word32 meangainQ12; + WebRtc_Word32 CQ11, CQ10,tmp32a,tmp32b; + WebRtc_Word16 shft,tmp16a,tmp16c; + + meangainQ12=0; + for (k = 0; k < 4; k++) + meangainQ12 += PitchGain_Q12[k]; + + meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2); // Get average + + /* voicing classificiation */ + if (meangainQ12 <= 819) { // mean_gain < 0.2 + shft = -1; // StepSize=2.0; + cdf = WebRtcIsacfix_kPitchLagPtrLo; + cdf_size = WebRtcIsacfix_kPitchLagSizeLo; + mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo; + mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo; + lower_limit = WebRtcIsacfix_kLowerLimitLo; + init_index = WebRtcIsacfix_kInitIndLo; + } else if (meangainQ12 <= 1638) { // mean_gain < 0.4 + shft = 0; // StepSize=1.0; + cdf = WebRtcIsacfix_kPitchLagPtrMid; + cdf_size = WebRtcIsacfix_kPitchLagSizeMid; + mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid; + mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid; + lower_limit = WebRtcIsacfix_kLowerLimitMid; + init_index = WebRtcIsacfix_kInitIndMid; + } else { + shft = 1; // StepSize=0.5; + cdf = WebRtcIsacfix_kPitchLagPtrHi; + cdf_size = WebRtcIsacfix_kPitchLagSizeHi; + mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi; + mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi; + lower_limit = WebRtcIsacfix_kLowerLimitHi; + init_index = WebRtcIsacfix_kInitIndHi; + } + + /* entropy decoding of quantization indices */ + err = WebRtcIsacfix_DecHistBisectMulti(index, streamdata, cdf, cdf_size, 1); + if ((err<0) || (index[0]<0)) // error check + return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG; + + err = WebRtcIsacfix_DecHistOneStepMulti(index+1, streamdata, cdf+1, init_index, 3); + if (err<0) // error check + return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG; + + + /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */ + CQ11 = ((WebRtc_Word32)index[0] + lower_limit[0]); // Q0 + CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11 + for (k=0; k<PITCH_SUBFRAMES; k++) { + tmp32a = WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11); + tmp16a = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5); + PitchLags_Q7[k] = tmp16a; + } + + CQ10 = mean_val2Q10[index[1]]; + for (k=0; k<PITCH_SUBFRAMES; k++) { + tmp32b = (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[1][k], (WebRtc_Word16) CQ10,10); + tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); + PitchLags_Q7[k] += tmp16c; + } + + CQ10 = mean_val4Q10[index[3]]; + for (k=0; k<PITCH_SUBFRAMES; k++) { + tmp32b = (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[3][k], (WebRtc_Word16) CQ10,10); + tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); + PitchLags_Q7[k] += tmp16c; + } + + return 0; +} + + + +/* quantize & code Pitch Lags */ +int WebRtcIsacfix_EncodePitchLag(WebRtc_Word16 *PitchLagsQ7,WebRtc_Word16 *PitchGain_Q12, + Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData) +{ + int k, j; + WebRtc_Word16 index[PITCH_SUBFRAMES]; + WebRtc_Word32 meangainQ12, CQ17; + WebRtc_Word32 CQ11, CQ10,tmp32a; + + const WebRtc_Word16 *mean_val2Q10,*mean_val4Q10; + const WebRtc_Word16 *lower_limit, *upper_limit; + const WebRtc_UWord16 **cdf; + WebRtc_Word16 shft, tmp16a, tmp16b, tmp16c; + WebRtc_Word32 tmp32b; + int status = 0; + + /* compute mean pitch gain */ + meangainQ12=0; + for (k = 0; k < 4; k++) + meangainQ12 += PitchGain_Q12[k]; + + meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2); + + /* Save data for creation of multiple bitstreams */ + if (encData != NULL) { + encData->meanGain[encData->startIdx] = meangainQ12; + } + + /* voicing classificiation */ + if (meangainQ12 <= 819) { // mean_gain < 0.2 + shft = -1; // StepSize=2.0; + cdf = WebRtcIsacfix_kPitchLagPtrLo; + mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo; + mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo; + lower_limit = WebRtcIsacfix_kLowerLimitLo; + upper_limit = WebRtcIsacfix_kUpperLimitLo; + } else if (meangainQ12 <= 1638) { // mean_gain < 0.4 + shft = 0; // StepSize=1.0; + cdf = WebRtcIsacfix_kPitchLagPtrMid; + mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid; + mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid; + lower_limit = WebRtcIsacfix_kLowerLimitMid; + upper_limit = WebRtcIsacfix_kUpperLimitMid; + } else { + shft = 1; // StepSize=0.5; + cdf = WebRtcIsacfix_kPitchLagPtrHi; + mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi; + mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi; + lower_limit = WebRtcIsacfix_kLowerLimitHi; + upper_limit = WebRtcIsacfix_kUpperLimitHi; + } + + /* find quantization index */ + for (k=0; k<4; k++) + { + /* transform */ + CQ17=0; + for (j=0; j<PITCH_SUBFRAMES; j++) + CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], PitchLagsQ7[j],2); // Q17 + + CQ17 = WEBRTC_SPL_SHIFT_W32(CQ17,shft); // Scale with StepSize + + /* quantize */ + tmp16b = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(CQ17 + 65536, 17 ); + index[k] = tmp16b; + + /* check that the index is not outside the boundaries of the table */ + if (index[k] < lower_limit[k]) index[k] = lower_limit[k]; + else if (index[k] > upper_limit[k]) index[k] = upper_limit[k]; + index[k] -= lower_limit[k]; + + /* Save data for creation of multiple bitstreams */ + if(encData != NULL) { + encData->pitchIndex[PITCH_SUBFRAMES*encData->startIdx + k] = index[k]; + } + } + + /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */ + CQ11 = (index[0] + lower_limit[0]); // Q0 + CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11 + + for (k=0; k<PITCH_SUBFRAMES; k++) { + tmp32a = WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11); // Q12 + tmp16a = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5);// Q7 + PitchLagsQ7[k] = tmp16a; + } + + CQ10 = mean_val2Q10[index[1]]; + for (k=0; k<PITCH_SUBFRAMES; k++) { + tmp32b = (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[1][k], (WebRtc_Word16) CQ10,10); + tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7 + PitchLagsQ7[k] += tmp16c; + } + + CQ10 = mean_val4Q10[index[3]]; + for (k=0; k<PITCH_SUBFRAMES; k++) { + tmp32b = (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[3][k], (WebRtc_Word16) CQ10,10); + tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7 + PitchLagsQ7[k] += tmp16c; + } + + /* entropy coding of quantization pitch lags */ + status = WebRtcIsacfix_EncHistMulti(streamdata, index, cdf, PITCH_SUBFRAMES); + + /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */ + return status; +} + + + +/* Routines for inband signaling of bandwitdh estimation */ +/* Histograms based on uniform distribution of indices */ +/* Move global variables later! */ + + +/* cdf array for frame length indicator */ +const WebRtc_UWord16 kFrameLenCdf[4] = { + 0, 21845, 43690, 65535}; + +/* pointer to cdf array for frame length indicator */ +const WebRtc_UWord16 *kFrameLenCdfPtr[1] = {kFrameLenCdf}; + +/* initial cdf index for decoder of frame length indicator */ +const WebRtc_UWord16 kFrameLenInitIndex[1] = {1}; + + +int WebRtcIsacfix_DecodeFrameLen(Bitstr_dec *streamdata, + WebRtc_Word16 *framesamples) +{ + + int err; + WebRtc_Word16 frame_mode; + + err = 0; + /* entropy decoding of frame length [1:30ms,2:60ms] */ + err = WebRtcIsacfix_DecHistOneStepMulti(&frame_mode, streamdata, kFrameLenCdfPtr, kFrameLenInitIndex, 1); + if (err<0) // error check + return -ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH; + + switch(frame_mode) { + case 1: + *framesamples = 480; /* 30ms */ + break; + case 2: + *framesamples = 960; /* 60ms */ + break; + default: + err = -ISAC_DISALLOWED_FRAME_MODE_DECODER; + } + + return err; +} + + +int WebRtcIsacfix_EncodeFrameLen(WebRtc_Word16 framesamples, Bitstr_enc *streamdata) { + + int status; + WebRtc_Word16 frame_mode; + + status = 0; + frame_mode = 0; + /* entropy coding of frame length [1:480 samples,2:960 samples] */ + switch(framesamples) { + case 480: + frame_mode = 1; + break; + case 960: + frame_mode = 2; + break; + default: + status = - ISAC_DISALLOWED_FRAME_MODE_ENCODER; + } + + if (status < 0) + return status; + + status = WebRtcIsacfix_EncHistMulti(streamdata, &frame_mode, kFrameLenCdfPtr, 1); + + return status; +} + +/* cdf array for estimated bandwidth */ +const WebRtc_UWord16 kBwCdf[25] = { + 0, 2731, 5461, 8192, 10923, 13653, 16384, 19114, 21845, 24576, 27306, 30037, + 32768, 35498, 38229, 40959, 43690, 46421, 49151, 51882, 54613, 57343, 60074, + 62804, 65535}; + +/* pointer to cdf array for estimated bandwidth */ +const WebRtc_UWord16 *kBwCdfPtr[1] = {kBwCdf}; + +/* initial cdf index for decoder of estimated bandwidth*/ +const WebRtc_UWord16 kBwInitIndex[1] = {7}; + + +int WebRtcIsacfix_DecodeSendBandwidth(Bitstr_dec *streamdata, WebRtc_Word16 *BWno) { + + int err; + WebRtc_Word16 BWno32; + + /* entropy decoding of sender's BW estimation [0..23] */ + err = WebRtcIsacfix_DecHistOneStepMulti(&BWno32, streamdata, kBwCdfPtr, kBwInitIndex, 1); + if (err<0) // error check + return -ISAC_RANGE_ERROR_DECODE_BANDWIDTH; + *BWno = (WebRtc_Word16)BWno32; + return err; + +} + + +int WebRtcIsacfix_EncodeReceiveBandwidth(WebRtc_Word16 *BWno, Bitstr_enc *streamdata) +{ + int status = 0; + /* entropy encoding of receiver's BW estimation [0..23] */ + status = WebRtcIsacfix_EncHistMulti(streamdata, BWno, kBwCdfPtr, 1); + + return status; +} + +/* estimate codel length of LPC Coef */ +void WebRtcIsacfix_TranscodeLpcCoef(WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 *index_gQQ) { + int j, k, n; + WebRtc_Word16 posQQ, pos2QQ; + WebRtc_Word16 pos, pos2, posg, offsg, offs2, gainpos; + WebRtc_Word32 tmpcoeffs_gQ6[KLT_ORDER_GAIN]; + WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN]; + WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN]; + WebRtc_Word32 sumQQ; + + + /* log gains, mean removal and scaling */ + posg = 0;pos=0; gainpos=0; + + for (k=0; k<SUBFRAMES; k++) { + /* log gains */ + + /* The input argument X to logN(X) is 2^17 times higher than the + input floating point argument Y to log(Y), since the X value + is a Q17 value. This can be compensated for after the call, by + subraction a value Z for each Q-step. One Q-step means that + X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 = + 177.445678 should be subtracted (since logN() returns a Q8 value). + For a X value in Q17, the value 177.445678*17 = 3017 should be + subtracted */ + tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 + tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 + posg++; gainpos++; + + tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8 + tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4 + posg++; gainpos++; + + } + + + /* KLT */ + + /* left transform */ + offsg = 0; + for (j=0; j<SUBFRAMES; j++) { + posg = offsg; + for (k=0; k<2; k++) { + sumQQ = 0; + pos = offsg; + pos2 = k; + for (n=0; n<2; n++) { + sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[pos], WebRtcIsacfix_kT1GainQ15[0][pos2]); //Q21 = Q6*Q15 + pos++; + pos2 += 2; + } + tmpcoeffs2_gQ21[posg] = sumQQ; + posg++; + } + + offsg += 2; + } + + /* right transform */ + offsg = 0; + offs2 = 0; + for (j=0; j<SUBFRAMES; j++) { + posg = offsg; + for (k=0; k<2; k++) { + sumQQ = 0; + pos = k; + pos2 = offs2; + for (n=0; n<SUBFRAMES; n++) { + sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[0][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21 + pos += 2; + pos2++; + } + tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4); + posg++; + } + offsg += 2; + offs2 += SUBFRAMES; + } + + /* quantize coefficients */ + for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok? + { + posQQ = WebRtcIsacfix_kSelIndGain[k]; + pos2QQ= (WebRtc_Word16)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17); + + index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? + if (index_gQQ[k] < 0) { + index_gQQ[k] = 0; + } + else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { + index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; + } + } +} diff --git a/src/libs/webrtc/isac/entropy_coding.h b/src/libs/webrtc/isac/entropy_coding.h new file mode 100644 index 00000000..298ea223 --- /dev/null +++ b/src/libs/webrtc/isac/entropy_coding.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * entropy_coding.h + * + * This header file contains all of the functions used to arithmetically + * encode the iSAC bistream + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ENTROPY_CODING_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ENTROPY_CODING_H_ + +#include "structs.h" + +/* decode complex spectrum (return number of bytes in stream) */ +WebRtc_Word16 WebRtcIsacfix_DecodeSpec(Bitstr_dec *streamdata, + WebRtc_Word16 *frQ7, + WebRtc_Word16 *fiQ7, + WebRtc_Word16 AvgPitchGain_Q12); + +/* encode complex spectrum */ +int WebRtcIsacfix_EncodeSpec(const WebRtc_Word16 *fr, + const WebRtc_Word16 *fi, + Bitstr_enc *streamdata, + WebRtc_Word16 AvgPitchGain_Q12); + + +/* decode & dequantize LPC Coef */ +int WebRtcIsacfix_DecodeLpcCoef(Bitstr_dec *streamdata, + WebRtc_Word32 *LPCCoefQ17, + WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 *outmodel); + +int WebRtcIsacfix_DecodeLpc(WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 *LPCCoef_loQ15, + WebRtc_Word16 *LPCCoef_hiQ15, + Bitstr_dec *streamdata, + WebRtc_Word16 *outmodel); + +/* quantize & code LPC Coef */ +int WebRtcIsacfix_EncodeLpc(WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 *LPCCoef_loQ15, + WebRtc_Word16 *LPCCoef_hiQ15, + WebRtc_Word16 *model, + WebRtc_Word32 *sizeQ11, + Bitstr_enc *streamdata, + ISAC_SaveEncData_t* encData, + transcode_obj *transcodeParam); + +int WebRtcIsacfix_EstCodeLpcGain(WebRtc_Word32 *gain_lo_hiQ17, + Bitstr_enc *streamdata, + ISAC_SaveEncData_t* encData); +/* decode & dequantize RC */ +int WebRtcIsacfix_DecodeRcCoef(Bitstr_dec *streamdata, + WebRtc_Word16 *RCQ15); + +/* quantize & code RC */ +int WebRtcIsacfix_EncodeRcCoef(WebRtc_Word16 *RCQ15, + Bitstr_enc *streamdata); + +/* decode & dequantize squared Gain */ +int WebRtcIsacfix_DecodeGain2(Bitstr_dec *streamdata, + WebRtc_Word32 *Gain2); + +/* quantize & code squared Gain (input is squared gain) */ +int WebRtcIsacfix_EncodeGain2(WebRtc_Word32 *gain2, + Bitstr_enc *streamdata); + +int WebRtcIsacfix_EncodePitchGain(WebRtc_Word16 *PitchGains_Q12, + Bitstr_enc *streamdata, + ISAC_SaveEncData_t* encData); + +int WebRtcIsacfix_EncodePitchLag(WebRtc_Word16 *PitchLagQ7, + WebRtc_Word16 *PitchGain_Q12, + Bitstr_enc *streamdata, + ISAC_SaveEncData_t* encData); + +int WebRtcIsacfix_DecodePitchGain(Bitstr_dec *streamdata, + WebRtc_Word16 *PitchGain_Q12); + +int WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata, + WebRtc_Word16 *PitchGain_Q12, + WebRtc_Word16 *PitchLagQ7); + +int WebRtcIsacfix_DecodeFrameLen(Bitstr_dec *streamdata, + WebRtc_Word16 *framelength); + + +int WebRtcIsacfix_EncodeFrameLen(WebRtc_Word16 framelength, + Bitstr_enc *streamdata); + +int WebRtcIsacfix_DecodeSendBandwidth(Bitstr_dec *streamdata, + WebRtc_Word16 *BWno); + + +int WebRtcIsacfix_EncodeReceiveBandwidth(WebRtc_Word16 *BWno, + Bitstr_enc *streamdata); + +void WebRtcIsacfix_TranscodeLpcCoef(WebRtc_Word32 *tmpcoeffs_gQ6, + WebRtc_Word16 *index_gQQ); + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ENTROPY_CODING_H_ */ diff --git a/src/libs/webrtc/isac/fft.c b/src/libs/webrtc/isac/fft.c new file mode 100644 index 00000000..fff35c4f --- /dev/null +++ b/src/libs/webrtc/isac/fft.c @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * fft.c + * + * Fast Fourier Transform + * + */ + + +#include "fft.h" + +const WebRtc_Word16 kSortTabFft[240] = { + 0, 60, 120, 180, 20, 80, 140, 200, 40, 100, 160, 220, + 4, 64, 124, 184, 24, 84, 144, 204, 44, 104, 164, 224, + 8, 68, 128, 188, 28, 88, 148, 208, 48, 108, 168, 228, + 12, 72, 132, 192, 32, 92, 152, 212, 52, 112, 172, 232, + 16, 76, 136, 196, 36, 96, 156, 216, 56, 116, 176, 236, + 1, 61, 121, 181, 21, 81, 141, 201, 41, 101, 161, 221, + 5, 65, 125, 185, 25, 85, 145, 205, 45, 105, 165, 225, + 9, 69, 129, 189, 29, 89, 149, 209, 49, 109, 169, 229, + 13, 73, 133, 193, 33, 93, 153, 213, 53, 113, 173, 233, + 17, 77, 137, 197, 37, 97, 157, 217, 57, 117, 177, 237, + 2, 62, 122, 182, 22, 82, 142, 202, 42, 102, 162, 222, + 6, 66, 126, 186, 26, 86, 146, 206, 46, 106, 166, 226, + 10, 70, 130, 190, 30, 90, 150, 210, 50, 110, 170, 230, + 14, 74, 134, 194, 34, 94, 154, 214, 54, 114, 174, 234, + 18, 78, 138, 198, 38, 98, 158, 218, 58, 118, 178, 238, + 3, 63, 123, 183, 23, 83, 143, 203, 43, 103, 163, 223, + 7, 67, 127, 187, 27, 87, 147, 207, 47, 107, 167, 227, + 11, 71, 131, 191, 31, 91, 151, 211, 51, 111, 171, 231, + 15, 75, 135, 195, 35, 95, 155, 215, 55, 115, 175, 235, + 19, 79, 139, 199, 39, 99, 159, 219, 59, 119, 179, 239 +}; + +/* Cosine table in Q14 */ +const WebRtc_Word16 kCosTabFfftQ14[240] = { + 16384, 16378, 16362, 16333, 16294, 16244, 16182, 16110, 16026, 15931, 15826, 15709, + 15582, 15444, 15296, 15137, 14968, 14788, 14598, 14399, 14189, 13970, 13741, 13502, + 13255, 12998, 12733, 12458, 12176, 11885, 11585, 11278, 10963, 10641, 10311, 9974, + 9630, 9280, 8923, 8561, 8192, 7818, 7438, 7053, 6664, 6270, 5872, 5469, + 5063, 4653, 4240, 3825, 3406, 2986, 2563, 2139, 1713, 1285, 857, 429, + 0, -429, -857, -1285, -1713, -2139, -2563, -2986, -3406, -3825, -4240, -4653, + -5063, -5469, -5872, -6270, -6664, -7053, -7438, -7818, -8192, -8561, -8923, -9280, + -9630, -9974, -10311, -10641, -10963, -11278, -11585, -11885, -12176, -12458, -12733, -12998, + -13255, -13502, -13741, -13970, -14189, -14399, -14598, -14788, -14968, -15137, -15296, -15444, + -15582, -15709, -15826, -15931, -16026, -16110, -16182, -16244, -16294, -16333, -16362, -16378, + -16384, -16378, -16362, -16333, -16294, -16244, -16182, -16110, -16026, -15931, -15826, -15709, + -15582, -15444, -15296, -15137, -14968, -14788, -14598, -14399, -14189, -13970, -13741, -13502, + -13255, -12998, -12733, -12458, -12176, -11885, -11585, -11278, -10963, -10641, -10311, -9974, + -9630, -9280, -8923, -8561, -8192, -7818, -7438, -7053, -6664, -6270, -5872, -5469, + -5063, -4653, -4240, -3825, -3406, -2986, -2563, -2139, -1713, -1285, -857, -429, + 0, 429, 857, 1285, 1713, 2139, 2563, 2986, 3406, 3825, 4240, 4653, + 5063, 5469, 5872, 6270, 6664, 7053, 7438, 7818, 8192, 8561, 8923, 9280, + 9630, 9974, 10311, 10641, 10963, 11278, 11585, 11885, 12176, 12458, 12733, 12998, + 13255, 13502, 13741, 13970, 14189, 14399, 14598, 14788, 14968, 15137, 15296, 15444, + 15582, 15709, 15826, 15931, 16026, 16110, 16182, 16244, 16294, 16333, 16362, 16378 +}; + + + +/* Uses 16x16 mul, without rounding, which is faster. Uses WEBRTC_SPL_MUL_16_16_RSFT */ +WebRtc_Word16 WebRtcIsacfix_FftRadix16Fastest(WebRtc_Word16 RexQx[], WebRtc_Word16 ImxQx[], WebRtc_Word16 iSign) { + + WebRtc_Word16 dd, ee, ff, gg, hh, ii; + WebRtc_Word16 k0, k1, k2, k3, k4, kk; + WebRtc_Word16 tmp116, tmp216; + + WebRtc_Word16 ccc1Q14, ccc2Q14, ccc3Q14, sss1Q14, sss2Q14, sss3Q14; + WebRtc_Word16 sss60Q14, ccc72Q14, sss72Q14; + WebRtc_Word16 aaQx, ajQx, akQx, ajmQx, ajpQx, akmQx, akpQx; + WebRtc_Word16 bbQx, bjQx, bkQx, bjmQx, bjpQx, bkmQx, bkpQx; + + WebRtc_Word16 ReDATAQx[240], ImDATAQx[240]; + + sss60Q14 = kCosTabFfftQ14[20]; + ccc72Q14 = kCosTabFfftQ14[48]; + sss72Q14 = kCosTabFfftQ14[12]; + + if (iSign < 0) { + sss72Q14 = -sss72Q14; + sss60Q14 = -sss60Q14; + } + /* Complexity is: 10 cycles */ + + /* compute fourier transform */ + + // transform for factor of 4 + for (kk=0; kk<60; kk++) { + k0 = kk; + k1 = k0 + 60; + k2 = k1 + 60; + k3 = k2 + 60; + + akpQx = RexQx[k0] + RexQx[k2]; + akmQx = RexQx[k0] - RexQx[k2]; + ajpQx = RexQx[k1] + RexQx[k3]; + ajmQx = RexQx[k1] - RexQx[k3]; + bkpQx = ImxQx[k0] + ImxQx[k2]; + bkmQx = ImxQx[k0] - ImxQx[k2]; + bjpQx = ImxQx[k1] + ImxQx[k3]; + bjmQx = ImxQx[k1] - ImxQx[k3]; + + RexQx[k0] = akpQx + ajpQx; + ImxQx[k0] = bkpQx + bjpQx; + ajpQx = akpQx - ajpQx; + bjpQx = bkpQx - bjpQx; + if (iSign < 0) { + akpQx = akmQx + bjmQx; + bkpQx = bkmQx - ajmQx; + akmQx -= bjmQx; + bkmQx += ajmQx; + } else { + akpQx = akmQx - bjmQx; + bkpQx = bkmQx + ajmQx; + akmQx += bjmQx; + bkmQx -= ajmQx; + } + + ccc1Q14 = kCosTabFfftQ14[kk]; + ccc2Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(2, kk)]; + ccc3Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(3, kk)]; + sss1Q14 = kCosTabFfftQ14[kk+60]; + sss2Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(2, kk)+60]; + sss3Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(3, kk)+60]; + if (iSign==1) { + sss1Q14 = -sss1Q14; + sss2Q14 = -sss2Q14; + sss3Q14 = -sss3Q14; + } + + //Do several multiplications like Q14*Q16>>14 = Q16 + // RexQ16[k1] = akpQ16 * ccc1Q14 - bkpQ16 * sss1Q14; + // RexQ16[k2] = ajpQ16 * ccc2Q14 - bjpQ16 * sss2Q14; + // RexQ16[k3] = akmQ16 * ccc3Q14 - bkmQ16 * sss3Q14; + // ImxQ16[k1] = akpQ16 * sss1Q14 + bkpQ16 * ccc1Q14; + // ImxQ16[k2] = ajpQ16 * sss2Q14 + bjpQ16 * ccc2Q14; + // ImxQ16[k3] = akmQ16 * sss3Q14 + bkmQ16 * ccc3Q14; + + RexQx[k1] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc1Q14, akpQx, 14) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss1Q14, bkpQx, 14); // 6 non-mul + 2 mul cycles, i.e. 8 cycles (6+2*7=20 cycles if 16x32mul) + RexQx[k2] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, ajpQx, 14) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bjpQx, 14); + RexQx[k3] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc3Q14, akmQx, 14) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss3Q14, bkmQx, 14); + ImxQx[k1] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss1Q14, akpQx, 14) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc1Q14, bkpQx, 14); + ImxQx[k2] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, ajpQx, 14) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bjpQx, 14); + ImxQx[k3] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss3Q14, akmQx, 14) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc3Q14, bkmQx, 14); + //This mul segment needs 6*8 = 48 cycles for 16x16 muls, but 6*20 = 120 cycles for 16x32 muls + + + } + /* Complexity is: 51+48 = 99 cycles for 16x16 muls, but 51+120 = 171 cycles for 16x32 muls*/ + + // transform for factor of 3 + kk=0; + k1=20; + k2=40; + + for (hh=0; hh<4; hh++) { + for (ii=0; ii<20; ii++) { + akQx = RexQx[kk]; + bkQx = ImxQx[kk]; + ajQx = RexQx[k1] + RexQx[k2]; + bjQx = ImxQx[k1] + ImxQx[k2]; + RexQx[kk] = akQx + ajQx; + ImxQx[kk] = bkQx + bjQx; + tmp116 = WEBRTC_SPL_RSHIFT_W16(ajQx, 1); + tmp216 = WEBRTC_SPL_RSHIFT_W16(bjQx, 1); + akQx = akQx - tmp116; + bkQx = bkQx - tmp216; + tmp116 = RexQx[k1] - RexQx[k2]; + tmp216 = ImxQx[k1] - ImxQx[k2]; + + ajQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss60Q14, tmp116, 14); // Q14*Qx>>14 = Qx + bjQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss60Q14, tmp216, 14); // Q14*Qx>>14 = Qx + RexQx[k1] = akQx - bjQx; + RexQx[k2] = akQx + bjQx; + ImxQx[k1] = bkQx + ajQx; + ImxQx[k2] = bkQx - ajQx; + + kk++; + k1++; + k2++; + } + /* Complexity : (31+6)*20 = 740 cycles for 16x16 muls, but (31+18)*20 = 980 cycles for 16x32 muls*/ + kk=kk+40; + k1=k1+40; + k2=k2+40; + } + /* Complexity : 4*(740+3) = 2972 cycles for 16x16 muls, but 4*(980+3) = 3932 cycles for 16x32 muls*/ + + /* multiply by rotation factor for odd factor 3 or 5 (not for 4) + Same code (duplicated) for both ii=2 and ii=3 */ + kk = 1; + ee = 0; + ff = 0; + + for (gg=0; gg<19; gg++) { + kk += 20; + ff = ff+4; + for (hh=0; hh<2; hh++) { + ee = ff + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(hh, ff); + dd = ee + 60; + ccc2Q14 = kCosTabFfftQ14[ee]; + sss2Q14 = kCosTabFfftQ14[dd]; + if (iSign==1) { + sss2Q14 = -sss2Q14; + } + for (ii=0; ii<4; ii++) { + akQx = RexQx[kk]; + bkQx = ImxQx[kk]; + RexQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akQx, 14) - // Q14*Qx>>14 = Qx + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkQx, 14); + ImxQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akQx, 14) + // Q14*Qx>>14 = Qx + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkQx, 14); + + + kk += 60; + } + kk = kk - 220; + } + // Complexity: 2*(13+5+4*13+2) = 144 for 16x16 muls, but 2*(13+5+4*33+2) = 304 cycles for 16x32 muls + kk = kk - 59; + } + // Complexity: 19*144 = 2736 for 16x16 muls, but 19*304 = 5776 cycles for 16x32 muls + + // transform for factor of 5 + kk = 0; + ccc2Q14 = kCosTabFfftQ14[96]; + sss2Q14 = kCosTabFfftQ14[84]; + if (iSign==1) { + sss2Q14 = -sss2Q14; + } + + for (hh=0; hh<4; hh++) { + for (ii=0; ii<12; ii++) { + k1 = kk + 4; + k2 = k1 + 4; + k3 = k2 + 4; + k4 = k3 + 4; + + akpQx = RexQx[k1] + RexQx[k4]; + akmQx = RexQx[k1] - RexQx[k4]; + bkpQx = ImxQx[k1] + ImxQx[k4]; + bkmQx = ImxQx[k1] - ImxQx[k4]; + ajpQx = RexQx[k2] + RexQx[k3]; + ajmQx = RexQx[k2] - RexQx[k3]; + bjpQx = ImxQx[k2] + ImxQx[k3]; + bjmQx = ImxQx[k2] - ImxQx[k3]; + aaQx = RexQx[kk]; + bbQx = ImxQx[kk]; + RexQx[kk] = aaQx + akpQx + ajpQx; + ImxQx[kk] = bbQx + bkpQx + bjpQx; + + akQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, akpQx, 14) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, ajpQx, 14) + aaQx; + bkQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, bkpQx, 14) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bjpQx, 14) + bbQx; + ajQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, akmQx, 14) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, ajmQx, 14); + bjQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, bkmQx, 14) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bjmQx, 14); + // 32+4*8=64 or 32+4*20=112 + + RexQx[k1] = akQx - bjQx; + RexQx[k4] = akQx + bjQx; + ImxQx[k1] = bkQx + ajQx; + ImxQx[k4] = bkQx - ajQx; + + akQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akpQx, 14) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, ajpQx, 14) + aaQx; + bkQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkpQx, 14) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, bjpQx, 14) + bbQx; + ajQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akmQx, 14) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, ajmQx, 14); + bjQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkmQx, 14) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, bjmQx, 14); + // 8+4*8=40 or 8+4*20=88 + + RexQx[k2] = akQx - bjQx; + RexQx[k3] = akQx + bjQx; + ImxQx[k2] = bkQx + ajQx; + ImxQx[k3] = bkQx - ajQx; + + kk = k4 + 4; + } + // Complexity: 12*(64+40+10) = 1368 for 16x16 muls, but 12*(112+88+10) = 2520 cycles for 16x32 muls + kk -= 239; + } + // Complexity: 4*1368 = 5472 for 16x16 muls, but 4*2520 = 10080 cycles for 16x32 muls + + /* multiply by rotation factor for odd factor 3 or 5 (not for 4) + Same code (duplicated) for both ii=2 and ii=3 */ + kk = 1; + ee=0; + + for (gg=0; gg<3; gg++) { + kk += 4; + dd = 12 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(12, gg); + ff = 0; + for (hh=0; hh<4; hh++) { + ff = ff+dd; + ee = ff+60; + for (ii=0; ii<12; ii++) { + akQx = RexQx[kk]; + bkQx = ImxQx[kk]; + + ccc2Q14 = kCosTabFfftQ14[ff]; + sss2Q14 = kCosTabFfftQ14[ee]; + + if (iSign==1) { + sss2Q14 = -sss2Q14; + } + + RexQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akQx, 14) - + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkQx, 14); + ImxQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akQx, 14) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkQx, 14); + + kk += 20; + } + kk = kk - 236; + // Complexity: 12*(12+12) = 288 for 16x16 muls, but 12*(12+32) = 528 cycles for 16x32 muls + } + kk = kk - 19; + // Complexity: 4*288+6 for 16x16 muls, but 4*528+6 cycles for 16x32 muls + } + // Complexity: 3*4*288+6 = 3462 for 16x16 muls, but 3*4*528+6 = 6342 cycles for 16x32 muls + + + // last transform for factor of 4 */ + for (kk=0; kk<240; kk=kk+4) { + k1 = kk + 1; + k2 = k1 + 1; + k3 = k2 + 1; + + akpQx = RexQx[kk] + RexQx[k2]; + akmQx = RexQx[kk] - RexQx[k2]; + ajpQx = RexQx[k1] + RexQx[k3]; + ajmQx = RexQx[k1] - RexQx[k3]; + bkpQx = ImxQx[kk] + ImxQx[k2]; + bkmQx = ImxQx[kk] - ImxQx[k2]; + bjpQx = ImxQx[k1] + ImxQx[k3]; + bjmQx = ImxQx[k1] - ImxQx[k3]; + RexQx[kk] = akpQx + ajpQx; + ImxQx[kk] = bkpQx + bjpQx; + ajpQx = akpQx - ajpQx; + bjpQx = bkpQx - bjpQx; + if (iSign < 0) { + akpQx = akmQx + bjmQx; + bkpQx = bkmQx - ajmQx; + akmQx -= bjmQx; + bkmQx += ajmQx; + } else { + akpQx = akmQx - bjmQx; + bkpQx = bkmQx + ajmQx; + akmQx += bjmQx; + bkmQx -= ajmQx; + } + RexQx[k1] = akpQx; + RexQx[k2] = ajpQx; + RexQx[k3] = akmQx; + ImxQx[k1] = bkpQx; + ImxQx[k2] = bjpQx; + ImxQx[k3] = bkmQx; + } + // Complexity: 60*45 = 2700 for 16x16 muls, but 60*45 = 2700 cycles for 16x32 muls + + /* permute the results to normal order */ + for (ii=0; ii<240; ii++) { + ReDATAQx[ii]=RexQx[ii]; + ImDATAQx[ii]=ImxQx[ii]; + } + // Complexity: 240*2=480 cycles + + for (ii=0; ii<240; ii++) { + RexQx[ii]=ReDATAQx[kSortTabFft[ii]]; + ImxQx[ii]=ImDATAQx[kSortTabFft[ii]]; + } + // Complexity: 240*2*2=960 cycles + + // Total complexity: + // 16x16 16x32 + // Complexity: 10 10 + // Complexity: 99 171 + // Complexity: 2972 3932 + // Complexity: 2736 5776 + // Complexity: 5472 10080 + // Complexity: 3462 6342 + // Complexity: 2700 2700 + // Complexity: 480 480 + // Complexity: 960 960 + // ======================= + // 18891 30451 + // + // If this FFT is called 2 time each frame, i.e. 67 times per second, it will correspond to + // a C54 complexity of 67*18891/1000000 = 1.27 MIPS with 16x16-muls, and 67*30451/1000000 = + // = 2.04 MIPS with 16x32-muls. Note that this routine somtimes is called 6 times during the + // encoding of a frame, i.e. the max complexity would be 7/2*1.27 = 4.4 MIPS for the 16x16 mul case. + + + return 0; +} diff --git a/src/libs/webrtc/isac/fft.h b/src/libs/webrtc/isac/fft.h new file mode 100644 index 00000000..efa116e7 --- /dev/null +++ b/src/libs/webrtc/isac/fft.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/*--------------------------------*-C-*---------------------------------* + * File: + * fft.h + * ---------------------------------------------------------------------* + * Re[]: real value array + * Im[]: imaginary value array + * nTotal: total number of complex values + * nPass: number of elements involved in this pass of transform + * nSpan: nspan/nPass = number of bytes to increment pointer + * in Re[] and Im[] + * isign: exponent: +1 = forward -1 = reverse + * scaling: normalizing constant by which the final result is *divided* + * scaling == -1, normalize by total dimension of the transform + * scaling < -1, normalize by the square-root of the total dimension + * + * ---------------------------------------------------------------------- + * See the comments in the code for correct usage! + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FFT_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FFT_H_ + + +#include "structs.h" + + +WebRtc_Word16 WebRtcIsacfix_FftRadix16Fastest(WebRtc_Word16 RexQx[], WebRtc_Word16 ImxQx[], WebRtc_Word16 iSign); + + + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FFT_H_ */ diff --git a/src/libs/webrtc/isac/filterbank_tables.c b/src/libs/webrtc/isac/filterbank_tables.c new file mode 100644 index 00000000..87c62aab --- /dev/null +++ b/src/libs/webrtc/isac/filterbank_tables.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * filterbank_tables.c + * + * This file contains variables that are used in + * filterbanks.c + * + */ + +#include "filterbank_tables.h" +#include "settings.h" + + +/* HPstcoeff_in_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; + * In float, they are: + * {-1.94895953203325f, 0.94984516000000f, -0.05101826139794f, 0.05015484000000f}; + */ +const WebRtc_Word16 WebRtcIsacfix_kHpStCoeffInQ30[8] = { + -31932, 16189, /* Q30 hi/lo pair */ + 15562, 17243, /* Q30 hi/lo pair */ + -26748, -17186, /* Q35 hi/lo pair */ + 26296, -27476 /* Q35 hi/lo pair */ +}; + +/* HPstcoeff_out_1_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; + * In float, they are: + * {-1.99701049409000f, 0.99714204490000f, 0.01701049409000f, -0.01704204490000f}; + */ +const WebRtc_Word16 WebRtcIsacfix_kHPStCoeffOut1Q30[8] = { + -32719, -1306, /* Q30 hi/lo pair */ + 16337, 11486, /* Q30 hi/lo pair */ + 8918, 26078, /* Q35 hi/lo pair */ + -8935, 3956 /* Q35 hi/lo pair */ +}; + +/* HPstcoeff_out_2_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; + * In float, they are: + * {-1.98645294509837f, 0.98672435560000f, 0.00645294509837f, -0.00662435560000f}; + */ +const WebRtc_Word16 WebRtcIsacfix_kHPStCoeffOut2Q30[8] = { + -32546, -2953, /* Q30 hi/lo pair */ + 16166, 32233, /* Q30 hi/lo pair */ + 3383, 13217, /* Q35 hi/lo pair */ + -3473, -4597 /* Q35 hi/lo pair */ +}; + +/* The upper channel all-pass filter factors */ +const WebRtc_Word16 WebRtcIsacfix_kUpperApFactorsQ15[2] = { + 1137, 12537 +}; + +/* The lower channel all-pass filter factors */ +const WebRtc_Word16 WebRtcIsacfix_kLowerApFactorsQ15[2] = { + 5059, 24379 +}; diff --git a/src/libs/webrtc/isac/filterbank_tables.h b/src/libs/webrtc/isac/filterbank_tables.h new file mode 100644 index 00000000..b6be4f09 --- /dev/null +++ b/src/libs/webrtc/isac/filterbank_tables.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * filterbank_tables.h + * + * Header file for variables that are defined in + * filterbank_tables.c. + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_TABLES_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_TABLES_H_ + +#include "typedefs.h" + +/********************* Coefficient Tables ************************/ + +/* HPstcoeff_in_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */ +extern const WebRtc_Word16 WebRtcIsacfix_kHpStCoeffInQ30[8]; /* [Q30hi Q30lo Q30hi Q30lo Q35hi Q35lo Q35hi Q35lo] */ + +/* HPstcoeff_out_1_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */ +extern const WebRtc_Word16 WebRtcIsacfix_kHPStCoeffOut1Q30[8]; /* [Q30hi Q30lo Q30hi Q30lo Q35hi Q35lo Q35hi Q35lo] */ + +/* HPstcoeff_out_2_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */ +extern const WebRtc_Word16 WebRtcIsacfix_kHPStCoeffOut2Q30[8]; /* [Q30hi Q30lo Q30hi Q30lo Q35hi Q35lo Q35hi Q35lo] */ + +/* The upper channel all-pass filter factors */ +extern const WebRtc_Word16 WebRtcIsacfix_kUpperApFactorsQ15[2]; + +/* The lower channel all-pass filter factors */ +extern const WebRtc_Word16 WebRtcIsacfix_kLowerApFactorsQ15[2]; + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_TABLES_H_ */ diff --git a/src/libs/webrtc/isac/filterbanks.c b/src/libs/webrtc/isac/filterbanks.c new file mode 100644 index 00000000..09a1b9fa --- /dev/null +++ b/src/libs/webrtc/isac/filterbanks.c @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * filterbanks.c + * + * This file contains function + * WebRtcIsacfix_SplitAndFilter, and WebRtcIsacfix_FilterAndCombine + * which implement filterbanks that produce decimated lowpass and + * highpass versions of a signal, and performs reconstruction. + * + */ + +#include "codec.h" +#include "filterbank_tables.h" +#include "settings.h" + + +static void AllpassFilter2FixDec16(WebRtc_Word16 *InOut16, //Q0 + const WebRtc_Word16 *APSectionFactors, //Q15 + WebRtc_Word16 lengthInOut, + WebRtc_Word16 NumberOfSections, + WebRtc_Word32 *FilterState) //Q16 +{ + int n, j; + WebRtc_Word32 a, b; + + for (j=0; j<NumberOfSections; j++) { + for (n=0;n<lengthInOut;n++) { + + + a = WEBRTC_SPL_MUL_16_16(APSectionFactors[j], InOut16[n]); //Q15*Q0=Q15 + a = WEBRTC_SPL_LSHIFT_W32(a, 1); // Q15 -> Q16 + b = WEBRTC_SPL_ADD_SAT_W32(a, FilterState[j]); //Q16+Q16=Q16 + a = WEBRTC_SPL_MUL_16_16_RSFT(-APSectionFactors[j], (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16), 0); //Q15*Q0=Q15 + FilterState[j] = WEBRTC_SPL_ADD_SAT_W32(WEBRTC_SPL_LSHIFT_W32(a,1), WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)InOut16[n],16)); // Q15<<1 + Q0<<16 = Q16 + Q16 = Q16 + InOut16[n] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16); //Save as Q0 + + } + } + +} + + +static void HighpassFilterFixDec32( + WebRtc_Word16 *io, /* Q0:input Q0: Output */ + WebRtc_Word16 len, /* length of input, Input */ + const WebRtc_Word16 *coeff, /* Coeff: [Q30hi Q30lo Q30hi Q30lo Q35hi Q35lo Q35hi Q35lo] */ + WebRtc_Word32 *state) /* Q4:filter state Input/Output */ +{ + int k; + WebRtc_Word32 a, b, c, in; + + + + for (k=0; k<len; k++) { + in = (WebRtc_Word32)io[k]; + /* Q35 * Q4 = Q39 ; shift 32 bit => Q7 */ + a = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[2*2], coeff[2*2+1], state[0]); + b = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[2*3], coeff[2*3+1], state[1]); + + c = ((WebRtc_Word32)in) + WEBRTC_SPL_RSHIFT_W32(a+b, 7); // Q0 + //c = WEBRTC_SPL_RSHIFT_W32(c, 1); // Q-1 + io[k] = (WebRtc_Word16)WEBRTC_SPL_SAT((WebRtc_Word32)32767, c, (WebRtc_Word32)-32768); // Write output as Q0 + + /* Q30 * Q4 = Q34 ; shift 32 bit => Q2 */ + a = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[2*0], coeff[2*0+1], state[0]); + b = WEBRTC_SPL_MUL_32_32_RSFT32(coeff[2*1], coeff[2*1+1], state[1]); + + c = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in, 2) - a - b; // New state in Q2 + c= (WebRtc_Word32)WEBRTC_SPL_SAT((WebRtc_Word32)536870911, c, (WebRtc_Word32)-536870912); // Check for wrap-around + + state[1] = state[0]; + state[0] = WEBRTC_SPL_LSHIFT_W32(c, 2); // Write state as Q4 + + } +} + + +void WebRtcIsacfix_SplitAndFilter1(WebRtc_Word16 *pin, + WebRtc_Word16 *LP16, + WebRtc_Word16 *HP16, + PreFiltBankstr *prefiltdata) +{ + /* Function WebRtcIsacfix_SplitAndFilter */ + /* This function creates low-pass and high-pass decimated versions of part of + the input signal, and part of the signal in the input 'lookahead buffer'. */ + + int k; + + WebRtc_Word16 tempin_ch1[FRAMESAMPLES/2 + QLOOKAHEAD]; + WebRtc_Word16 tempin_ch2[FRAMESAMPLES/2 + QLOOKAHEAD]; + WebRtc_Word32 tmpState[WEBRTC_SPL_MUL_16_16(2,(QORDER-1))]; /* 4 */ + + + /* High pass filter */ + HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix); + + + /* First Channel */ + for (k=0;k<FRAMESAMPLES/2;k++) { + tempin_ch1[QLOOKAHEAD + k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)]; + } + for (k=0;k<QLOOKAHEAD;k++) { + tempin_ch1[k]=prefiltdata->INLABUF1_fix[k]; + prefiltdata->INLABUF1_fix[k]=pin[FRAMESAMPLES+1-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)]; + } + + /* Second Channel. This is exactly like the first channel, except that the + even samples are now filtered instead (lower channel). */ + for (k=0;k<FRAMESAMPLES/2;k++) { + tempin_ch2[QLOOKAHEAD+k] = pin[WEBRTC_SPL_MUL_16_16(2, k)]; + } + for (k=0;k<QLOOKAHEAD;k++) { + tempin_ch2[k]=prefiltdata->INLABUF2_fix[k]; + prefiltdata->INLABUF2_fix[k]=pin[FRAMESAMPLES-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)]; + } + + + /*obtain polyphase components by forward all-pass filtering through each channel */ + /* The all pass filtering automatically updates the filter states which are exported in the + prefiltdata structure */ + AllpassFilter2FixDec16(tempin_ch1,WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_fix); + AllpassFilter2FixDec16(tempin_ch2,WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_fix); + + for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++) + tmpState[k] = prefiltdata->INSTAT1_fix[k]; + AllpassFilter2FixDec16(tempin_ch1 + FRAMESAMPLES/2,WebRtcIsacfix_kUpperApFactorsQ15, QLOOKAHEAD , NUMBEROFCHANNELAPSECTIONS, tmpState); + for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++) + tmpState[k] = prefiltdata->INSTAT2_fix[k]; + AllpassFilter2FixDec16(tempin_ch2 + FRAMESAMPLES/2,WebRtcIsacfix_kLowerApFactorsQ15, QLOOKAHEAD , NUMBEROFCHANNELAPSECTIONS, tmpState); + + + /* Now Construct low-pass and high-pass signals as combinations of polyphase components */ + for (k=0; k<FRAMESAMPLES/2 + QLOOKAHEAD; k++) { + WebRtc_Word32 tmp1, tmp2, tmp3; + tmp1 = (WebRtc_Word32)tempin_ch1[k]; // Q0 -> Q0 + tmp2 = (WebRtc_Word32)tempin_ch2[k]; // Q0 -> Q0 + tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/ + LP16[k] = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, tmp3, -32768); /*low pass */ + tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/ + HP16[k] = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, tmp3, -32768); /*high pass */ + } + +}/*end of WebRtcIsacfix_SplitAndFilter */ + + +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED + +/* Without lookahead */ +void WebRtcIsacfix_SplitAndFilter2(WebRtc_Word16 *pin, + WebRtc_Word16 *LP16, + WebRtc_Word16 *HP16, + PreFiltBankstr *prefiltdata) +{ + /* Function WebRtcIsacfix_SplitAndFilter2 */ + /* This function creates low-pass and high-pass decimated versions of part of + the input signal. */ + + int k; + + WebRtc_Word16 tempin_ch1[FRAMESAMPLES/2]; + WebRtc_Word16 tempin_ch2[FRAMESAMPLES/2]; + + + /* High pass filter */ + HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix); + + + /* First Channel */ + for (k=0;k<FRAMESAMPLES/2;k++) { + tempin_ch1[k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)]; + } + + /* Second Channel. This is exactly like the first channel, except that the + even samples are now filtered instead (lower channel). */ + for (k=0;k<FRAMESAMPLES/2;k++) { + tempin_ch2[k] = pin[WEBRTC_SPL_MUL_16_16(2, k)]; + } + + + /*obtain polyphase components by forward all-pass filtering through each channel */ + /* The all pass filtering automatically updates the filter states which are exported in the + prefiltdata structure */ + AllpassFilter2FixDec16(tempin_ch1,WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_fix); + AllpassFilter2FixDec16(tempin_ch2,WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_fix); + + + /* Now Construct low-pass and high-pass signals as combinations of polyphase components */ + for (k=0; k<FRAMESAMPLES/2; k++) { + WebRtc_Word32 tmp1, tmp2, tmp3; + tmp1 = (WebRtc_Word32)tempin_ch1[k]; // Q0 -> Q0 + tmp2 = (WebRtc_Word32)tempin_ch2[k]; // Q0 -> Q0 + tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/ + LP16[k] = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, tmp3, -32768); /*low pass */ + tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/ + HP16[k] = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, tmp3, -32768); /*high pass */ + } + +}/*end of WebRtcIsacfix_SplitAndFilter */ + +#endif + + + +////////////////////////////////////////////////////////// +////////// Combining +/* Function WebRtcIsacfix_FilterAndCombine */ +/* This is a decoder function that takes the decimated + length FRAMESAMPLES/2 input low-pass and + high-pass signals and creates a reconstructed fullband + output signal of length FRAMESAMPLES. WebRtcIsacfix_FilterAndCombine + is the sibling function of WebRtcIsacfix_SplitAndFilter */ +/* INPUTS: + inLP: a length FRAMESAMPLES/2 array of input low-pass + samples. + inHP: a length FRAMESAMPLES/2 array of input high-pass + samples. + postfiltdata: input data structure containing the filterbank + states from the previous decoding iteration. + OUTPUTS: + Out: a length FRAMESAMPLES array of output reconstructed + samples (fullband) based on the input low-pass and + high-pass signals. + postfiltdata: the input data structure containing the filterbank + states is updated for the next decoding iteration */ +void WebRtcIsacfix_FilterAndCombine1(WebRtc_Word16 *tempin_ch1, + WebRtc_Word16 *tempin_ch2, + WebRtc_Word16 *out16, + PostFiltBankstr *postfiltdata) +{ + int k; + WebRtc_Word16 in[FRAMESAMPLES]; + + /* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors + that were used as a lower channel at the encoding side. So at the decoder, the + corresponding all-pass filter factors for each channel are swapped.*/ + + AllpassFilter2FixDec16(tempin_ch1, WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_fix); + + /* Now, all-pass filter the new lower channel signal. But since all-pass filter factors + at the decoder are swapped from the ones at the encoder, the 'upper' channel + all-pass filter factors (kUpperApFactors) are used to filter this new lower channel signal */ + + AllpassFilter2FixDec16(tempin_ch2, WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_fix); + + /* Merge outputs to form the full length output signal.*/ + for (k=0;k<FRAMESAMPLES/2;k++) { + in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k]; + in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k]; + } + + /* High pass filter */ + HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix); + HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix); + + for (k=0;k<FRAMESAMPLES;k++) { + out16[k] = in[k]; + } +} + + +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED +/* Function WebRtcIsacfix_FilterAndCombine */ +/* This is a decoder function that takes the decimated + length len/2 input low-pass and + high-pass signals and creates a reconstructed fullband + output signal of length len. WebRtcIsacfix_FilterAndCombine + is the sibling function of WebRtcIsacfix_SplitAndFilter */ +/* INPUTS: + inLP: a length len/2 array of input low-pass + samples. + inHP: a length len/2 array of input high-pass + samples. + postfiltdata: input data structure containing the filterbank + states from the previous decoding iteration. + OUTPUTS: + Out: a length len array of output reconstructed + samples (fullband) based on the input low-pass and + high-pass signals. + postfiltdata: the input data structure containing the filterbank + states is updated for the next decoding iteration */ +void WebRtcIsacfix_FilterAndCombine2(WebRtc_Word16 *tempin_ch1, + WebRtc_Word16 *tempin_ch2, + WebRtc_Word16 *out16, + PostFiltBankstr *postfiltdata, + WebRtc_Word16 len) +{ + int k; + WebRtc_Word16 in[FRAMESAMPLES]; + + /* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors + that were used as a lower channel at the encoding side. So at the decoder, the + corresponding all-pass filter factors for each channel are swapped.*/ + + AllpassFilter2FixDec16(tempin_ch1, WebRtcIsacfix_kLowerApFactorsQ15,(WebRtc_Word16) (len/2), NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_fix); + + /* Now, all-pass filter the new lower channel signal. But since all-pass filter factors + at the decoder are swapped from the ones at the encoder, the 'upper' channel + all-pass filter factors (kUpperApFactors) are used to filter this new lower channel signal */ + + AllpassFilter2FixDec16(tempin_ch2, WebRtcIsacfix_kUpperApFactorsQ15, (WebRtc_Word16) (len/2), NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_fix); + + /* Merge outputs to form the full length output signal.*/ + for (k=0;k<len/2;k++) { + in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k]; + in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k]; + } + + /* High pass filter */ + HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix); + HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix); + + for (k=0;k<len;k++) { + out16[k] = in[k]; + } +} + +#endif diff --git a/src/libs/webrtc/isac/initialize.c b/src/libs/webrtc/isac/initialize.c new file mode 100644 index 00000000..4d11af53 --- /dev/null +++ b/src/libs/webrtc/isac/initialize.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * initialize.c + * + * Internal initfunctions + * + */ + +#include "codec.h" +#include "structs.h" +#include "pitch_estimator.h" + + +void WebRtcIsacfix_InitMaskingEnc(MaskFiltstr_enc *maskdata) { + + int k; + + for (k = 0; k < WINLEN; k++) { + maskdata->DataBufferLoQ0[k] = (WebRtc_Word16) 0; + maskdata->DataBufferHiQ0[k] = (WebRtc_Word16) 0; + } + for (k = 0; k < ORDERLO+1; k++) { + maskdata->CorrBufLoQQ[k] = (WebRtc_Word32) 0; + maskdata->CorrBufLoQdom[k] = 0; + + maskdata->PreStateLoGQ15[k] = 0; + + } + for (k = 0; k < ORDERHI+1; k++) { + maskdata->CorrBufHiQQ[k] = (WebRtc_Word32) 0; + maskdata->CorrBufHiQdom[k] = 0; + maskdata->PreStateHiGQ15[k] = 0; + } + + maskdata->OldEnergy = 10; + + return; +} + +void WebRtcIsacfix_InitMaskingDec(MaskFiltstr_dec *maskdata) { + + int k; + + for (k = 0; k < ORDERLO+1; k++) + { + maskdata->PostStateLoGQ0[k] = 0; + } + for (k = 0; k < ORDERHI+1; k++) + { + maskdata->PostStateHiGQ0[k] = 0; + } + + maskdata->OldEnergy = 10; + + return; +} + + + + + + + +void WebRtcIsacfix_InitPreFilterbank(PreFiltBankstr *prefiltdata) +{ + int k; + + for (k = 0; k < QLOOKAHEAD; k++) { + prefiltdata->INLABUF1_fix[k] = 0; + prefiltdata->INLABUF2_fix[k] = 0; + } + for (k = 0; k < WEBRTC_SPL_MUL_16_16(2,(QORDER-1)); k++) { + + prefiltdata->INSTAT1_fix[k] = 0; + prefiltdata->INSTAT2_fix[k] = 0; + } + + /* High pass filter states */ + prefiltdata->HPstates_fix[0] = 0; + prefiltdata->HPstates_fix[1] = 0; + + return; +} + +void WebRtcIsacfix_InitPostFilterbank(PostFiltBankstr *postfiltdata) +{ + int k; + + for (k = 0; k < WEBRTC_SPL_MUL_16_16(2, POSTQORDER); k++) { + + postfiltdata->STATE_0_LOWER_fix[k] = 0; + postfiltdata->STATE_0_UPPER_fix[k] = 0; + } + + /* High pass filter states */ + + postfiltdata->HPstates1_fix[0] = 0; + postfiltdata->HPstates1_fix[1] = 0; + + postfiltdata->HPstates2_fix[0] = 0; + postfiltdata->HPstates2_fix[1] = 0; + + return; +} + + +void WebRtcIsacfix_InitPitchFilter(PitchFiltstr *pitchfiltdata) +{ + int k; + + for (k = 0; k < PITCH_BUFFSIZE; k++) + pitchfiltdata->ubufQQ[k] = 0; + for (k = 0; k < (PITCH_DAMPORDER); k++) + pitchfiltdata->ystateQQ[k] = 0; + + pitchfiltdata->oldlagQ7 = 6400; /* 50.0 in Q7 */ + pitchfiltdata->oldgainQ12 = 0; +} + +void WebRtcIsacfix_InitPitchAnalysis(PitchAnalysisStruct *State) +{ + int k; + + for (k = 0; k < PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2; k++) { + State->dec_buffer16[k] = 0; + } + for (k = 0; k < WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)+1; k++) { + State->decimator_state32[k] = 0; + } + + for (k = 0; k < QLOOKAHEAD; k++) + State->inbuf[k] = 0; + + WebRtcIsacfix_InitPitchFilter(&(State->PFstr_wght)); + + WebRtcIsacfix_InitPitchFilter(&(State->PFstr)); +} + + +void WebRtcIsacfix_InitPlc( PLCstr *State ) +{ + State->decayCoeffPriodic = WEBRTC_SPL_WORD16_MAX; + State->decayCoeffNoise = WEBRTC_SPL_WORD16_MAX; + + State->used = PLC_WAS_USED; + + WebRtcSpl_ZerosArrayW16(State->overlapLP, RECOVERY_OVERLAP); + WebRtcSpl_ZerosArrayW16(State->lofilt_coefQ15, ORDERLO); + WebRtcSpl_ZerosArrayW16(State->hifilt_coefQ15, ORDERHI ); + + State->AvgPitchGain_Q12 = 0; + State->lastPitchGain_Q12 = 0; + State->lastPitchLag_Q7 = 0; + State->gain_lo_hiQ17[0]=State->gain_lo_hiQ17[1] = 0; + WebRtcSpl_ZerosArrayW16(State->prevPitchInvIn, FRAMESAMPLES/2); + WebRtcSpl_ZerosArrayW16(State->prevPitchInvOut, PITCH_MAX_LAG + 10 ); + WebRtcSpl_ZerosArrayW32(State->prevHP, PITCH_MAX_LAG + 10 ); + State->pitchCycles = 0; + State->A = 0; + State->B = 0; + State->pitchIndex = 0; + State->stretchLag = 240; + State->seed = 4447; + + +} diff --git a/src/libs/webrtc/isac/isac_decode.c b/src/libs/webrtc/isac/isac_decode.c new file mode 100644 index 00000000..89d46ce3 --- /dev/null +++ b/src/libs/webrtc/isac/isac_decode.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * decode.c + * + * This C file contains the internal decoding function. + * + */ + +#include <string.h> + +#include "bandwidth_estimator.h" +#include "codec.h" +#include "entropy_coding.h" +#include "pitch_estimator.h" +#include "settings.h" +#include "structs.h" + + + + +WebRtc_Word16 WebRtcIsacfix_DecodeImpl(WebRtc_Word16 *signal_out16, + ISACFIX_DecInst_t *ISACdec_obj, + WebRtc_Word16 *current_framesamples) +{ + int k; + int err; + WebRtc_Word16 BWno; + WebRtc_Word16 len = 0; + + WebRtc_Word16 model; + + + WebRtc_Word16 Vector_Word16_1[FRAMESAMPLES/2]; + WebRtc_Word16 Vector_Word16_2[FRAMESAMPLES/2]; + + WebRtc_Word32 Vector_Word32_1[FRAMESAMPLES/2]; + WebRtc_Word32 Vector_Word32_2[FRAMESAMPLES/2]; + + WebRtc_Word16 lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs + WebRtc_Word16 hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs + WebRtc_Word32 gain_lo_hiQ17[2*SUBFRAMES]; + + WebRtc_Word16 PitchLags_Q7[PITCH_SUBFRAMES]; + WebRtc_Word16 PitchGains_Q12[PITCH_SUBFRAMES]; + WebRtc_Word16 AvgPitchGain_Q12; + + WebRtc_Word16 tmp_1, tmp_2; + WebRtc_Word32 tmp32a, tmp32b; + WebRtc_Word16 gainQ13; + + + WebRtc_Word16 frame_nb; /* counter */ + WebRtc_Word16 frame_mode; /* 0 for 20ms and 30ms, 1 for 60ms */ + WebRtc_Word16 processed_samples; + + /* PLC */ + WebRtc_Word16 overlapWin[ 240 ]; + + (ISACdec_obj->bitstr_obj).W_upper = 0xFFFFFFFF; + (ISACdec_obj->bitstr_obj).streamval = 0; + (ISACdec_obj->bitstr_obj).stream_index = 0; + (ISACdec_obj->bitstr_obj).full = 1; + + + /* decode framelength and BW estimation - not used, only for stream pointer*/ + err = WebRtcIsacfix_DecodeFrameLen(&ISACdec_obj->bitstr_obj, current_framesamples); + if (err<0) // error check + return err; + + frame_mode = (WebRtc_Word16)WEBRTC_SPL_DIV(*current_framesamples, MAX_FRAMESAMPLES); /* 0, or 1 */ + processed_samples = (WebRtc_Word16)WEBRTC_SPL_DIV(*current_framesamples, frame_mode+1); /* either 320 (20ms) or 480 (30, 60 ms) */ + + err = WebRtcIsacfix_DecodeSendBandwidth(&ISACdec_obj->bitstr_obj, &BWno); + if (err<0) // error check + return err; + + /* one loop if it's one frame (20 or 30ms), 2 loops if 2 frames bundled together (60ms) */ + for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) { + + /* decode & dequantize pitch parameters */ + err = WebRtcIsacfix_DecodePitchGain(&(ISACdec_obj->bitstr_obj), PitchGains_Q12); + if (err<0) // error check + return err; + + err = WebRtcIsacfix_DecodePitchLag(&ISACdec_obj->bitstr_obj, PitchGains_Q12, PitchLags_Q7); + if (err<0) // error check + return err; + + AvgPitchGain_Q12 = (WebRtc_Word16)(((WebRtc_Word32)PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3])>>2); + + /* decode & dequantize FiltCoef */ + err = WebRtcIsacfix_DecodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15, + &ISACdec_obj->bitstr_obj, &model); + + if (err<0) // error check + return err; + + /* decode & dequantize spectrum */ + len = WebRtcIsacfix_DecodeSpec(&ISACdec_obj->bitstr_obj, Vector_Word16_1, Vector_Word16_2, AvgPitchGain_Q12); + if (len < 0) // error check + return len; + + // Why does this need Q16 in and out? /JS + WebRtcIsacfix_Spec2Time(Vector_Word16_1, Vector_Word16_2, Vector_Word32_1, Vector_Word32_2); + + for (k=0; k<FRAMESAMPLES/2; k++) { + Vector_Word16_1[k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(Vector_Word32_1[k]+64, 7); //Q16 -> Q9 + } + + /* ---- If this is recovery frame ---- */ + if( (ISACdec_obj->plcstr_obj).used == PLC_WAS_USED ) + { + (ISACdec_obj->plcstr_obj).used = PLC_NOT_USED; + if( (ISACdec_obj->plcstr_obj).B < 1000 ) + { + (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 4000; + } + + ISACdec_obj->plcstr_obj.decayCoeffPriodic = WEBRTC_SPL_WORD16_MAX; /* DECAY_RATE is in Q15 */ + ISACdec_obj->plcstr_obj.decayCoeffNoise = WEBRTC_SPL_WORD16_MAX; /* DECAY_RATE is in Q15 */ + ISACdec_obj->plcstr_obj.pitchCycles = 0; + + PitchGains_Q12[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(PitchGains_Q12[0], 700, 10 ); + + /* ---- Add-overlap ---- */ + WebRtcSpl_GetHanningWindow( overlapWin, RECOVERY_OVERLAP ); + for( k = 0; k < RECOVERY_OVERLAP; k++ ) + Vector_Word16_1[k] = WEBRTC_SPL_ADD_SAT_W16( + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( (ISACdec_obj->plcstr_obj).overlapLP[k], overlapWin[RECOVERY_OVERLAP - k - 1], 14), + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( Vector_Word16_1[k], overlapWin[k], 14) ); + + + + } + + /* --- Store side info --- */ + if( frame_nb == frame_mode ) + { + /* --- LPC info */ + WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).lofilt_coefQ15, &lofilt_coefQ15[(SUBFRAMES-1)*ORDERLO], ORDERLO ); + WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).hifilt_coefQ15, &hifilt_coefQ15[(SUBFRAMES-1)*ORDERHI], ORDERHI ); + (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0] = gain_lo_hiQ17[(SUBFRAMES-1) * 2]; + (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1] = gain_lo_hiQ17[(SUBFRAMES-1) * 2 + 1]; + + /* --- LTP info */ + (ISACdec_obj->plcstr_obj).AvgPitchGain_Q12 = PitchGains_Q12[3]; + (ISACdec_obj->plcstr_obj).lastPitchGain_Q12 = PitchGains_Q12[3]; + (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = PitchLags_Q7[3]; + + if( PitchLags_Q7[3] < 3000 ) + (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 += PitchLags_Q7[3]; + + WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvIn, Vector_Word16_1, FRAMESAMPLES/2 ); + + } + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + /* inverse pitch filter */ + WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2, &ISACdec_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 4); + + if( frame_nb == frame_mode ) + { + WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvOut, &(Vector_Word16_2[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10)]), PITCH_MAX_LAG ); + } + + + /* reduce gain to compensate for pitch enhancer */ + /* gain = 1.0f - 0.45f * AvgPitchGain; */ + tmp32a = WEBRTC_SPL_MUL_16_16_RSFT(AvgPitchGain_Q12, 29, 0); // Q18 + tmp32b = 262144 - tmp32a; // Q18 + gainQ13 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q13 + + for (k = 0; k < FRAMESAMPLES/2; k++) + { + Vector_Word32_1[k] = (WebRtc_Word32) WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(Vector_Word16_2[k], gainQ13), 3); // Q25 + } + + + /* perceptual post-filtering (using normalized lattice filter) */ + WebRtcIsacfix_NormLatticeFilterAr(ORDERLO, (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0, + Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1); + + /* --- Store Highpass Residual --- */ + for (k = 0; k < FRAMESAMPLES/2; k++) + Vector_Word32_1[k] = WEBRTC_SPL_LSHIFT_W32(Vector_Word32_2[k], 9); // Q16 -> Q25 + + for( k = 0; k < PITCH_MAX_LAG + 10; k++ ) + (ISACdec_obj->plcstr_obj).prevHP[k] = Vector_Word32_1[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10) + k]; + + + WebRtcIsacfix_NormLatticeFilterAr(ORDERHI, (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0, + Vector_Word32_1, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2); + + /* recombine the 2 bands */ + + /* Form the polyphase signals, and compensate for DC offset */ + for (k=0;k<FRAMESAMPLES/2;k++) { + tmp_1 = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, (((WebRtc_Word32)Vector_Word16_1[k]+Vector_Word16_2[k] + 1)), -32768); /* Construct a new upper channel signal*/ + tmp_2 = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, (((WebRtc_Word32)Vector_Word16_1[k]-Vector_Word16_2[k])), -32768); /* Construct a new lower channel signal*/ + Vector_Word16_1[k] = tmp_1; + Vector_Word16_2[k] = tmp_2; + } + + WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1, Vector_Word16_2, signal_out16 + frame_nb * processed_samples, &ISACdec_obj->postfiltbankstr_obj); + + } + return len; +} diff --git a/src/libs/webrtc/isac/isac_filters.c b/src/libs/webrtc/isac/isac_filters.c new file mode 100644 index 00000000..8f138253 --- /dev/null +++ b/src/libs/webrtc/isac/isac_filters.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * filters.c + * + * This file contains function WebRtcIsacfix_AutocorrFix, + * AllpassFilterForDec32, and WebRtcIsacfix_DecimateAllpass32 + * + */ + +#include <string.h> + +#include "pitch_estimator.h" +#include "lpc_masking_model.h" +#include "codec.h" + + +/* Autocorrelation function in fixed point. NOTE! Different from SPLIB-version in how it scales the signal. */ +int WebRtcIsacfix_AutocorrFix( + WebRtc_Word32 *r, + const WebRtc_Word16 *x, + WebRtc_Word16 N, + WebRtc_Word16 order, + WebRtc_Word16 *scale) +{ + int j, i; + WebRtc_Word16 scaling; + WebRtc_Word32 sum, prod, newsum; + G_CONST WebRtc_Word16 *xptr1; + G_CONST WebRtc_Word16 *xptr2; + + sum=0; + scaling=0; + /* Calculate r[0] and how much scaling is needed */ + for (i=0; i < N; i++) { + prod = WEBRTC_SPL_MUL_16_16_RSFT(x[i],x[i],scaling); + newsum = sum+prod; + /* If sum gets less than 0 we have overflow and need to scale the signal */ + if(newsum<0) { + scaling++; + sum=WEBRTC_SPL_RSHIFT_W32(sum, 1); + prod=WEBRTC_SPL_RSHIFT_W32(prod, 1); + } + sum += prod; + } + r[0]=sum; + + /* Perform the actual correlation calculation */ + for (i = 1; i < order + 1; i++) + { + int loops=(N-i); + sum = 0; + xptr1=(G_CONST WebRtc_Word16 *)x; + xptr2=(G_CONST WebRtc_Word16 *)&x[i]; + + for (j = loops;j > 0; j--) + { + sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1++,*xptr2++,scaling); + } + + r[i] = sum; + } + + *scale = scaling; + + return(order + 1); +} + +static const WebRtc_Word32 kApUpperQ15[ALLPASSSECTIONS] = { 1137, 12537 }; +static const WebRtc_Word32 kApLowerQ15[ALLPASSSECTIONS] = { 5059, 24379 }; + + +static void AllpassFilterForDec32(WebRtc_Word16 *InOut16, //Q0 + const WebRtc_Word32 *APSectionFactors, //Q15 + WebRtc_Word16 lengthInOut, + WebRtc_Word32 *FilterState) //Q16 +{ + int n, j; + WebRtc_Word32 a, b; + + for (j=0; j<ALLPASSSECTIONS; j++) { + for (n=0;n<lengthInOut;n+=2){ + a = WEBRTC_SPL_MUL_16_32_RSFT16(InOut16[n], APSectionFactors[j]); //Q0*Q31=Q31 shifted 16 gives Q15 + a = WEBRTC_SPL_LSHIFT_W32(a, 1); // Q15 -> Q16 + b = WEBRTC_SPL_ADD_SAT_W32(a, FilterState[j]); //Q16+Q16=Q16 + a = WEBRTC_SPL_MUL_16_32_RSFT16( + (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16), + -APSectionFactors[j]); //Q0*Q31=Q31 shifted 16 gives Q15 + FilterState[j] = WEBRTC_SPL_ADD_SAT_W32( + WEBRTC_SPL_LSHIFT_W32(a,1), + WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)InOut16[n], 16)); // Q15<<1 + Q0<<16 = Q16 + Q16 = Q16 + InOut16[n] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16); //Save as Q0 + } + } +} + + + + +void WebRtcIsacfix_DecimateAllpass32(const WebRtc_Word16 *in, + WebRtc_Word32 *state_in, /* array of size: 2*ALLPASSSECTIONS+1 */ + WebRtc_Word16 N, /* number of input samples */ + WebRtc_Word16 *out) /* array of size N/2 */ +{ + int n; + WebRtc_Word16 data_vec[PITCH_FRAME_LEN]; + + /* copy input */ + memcpy(data_vec+1, in, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), (N-1))); + + + data_vec[0] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(state_in[WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)],16); //the z^(-1) state + state_in[WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)] = WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)in[N-1],16); + + + + AllpassFilterForDec32(data_vec+1, kApUpperQ15, N, state_in); + AllpassFilterForDec32(data_vec, kApLowerQ15, N, state_in+ALLPASSSECTIONS); + + for (n=0;n<N/2;n++) { + out[n]=WEBRTC_SPL_ADD_SAT_W16(data_vec[WEBRTC_SPL_MUL_16_16(2, n)], data_vec[WEBRTC_SPL_MUL_16_16(2, n)+1]); + } +} diff --git a/src/libs/webrtc/isac/isacfix.c b/src/libs/webrtc/isac/isacfix.c new file mode 100644 index 00000000..a8c55e1a --- /dev/null +++ b/src/libs/webrtc/isac/isacfix.c @@ -0,0 +1,1522 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * isacfix.c + * + * This C file contains the functions for the ISAC API + * + */ + +#include <stdlib.h> +#include <string.h> + +#include "isacfix.h" +#include "bandwidth_estimator.h" +#include "codec.h" +#include "entropy_coding.h" +#include "structs.h" + + +/************************************************************************** + * WebRtcIsacfix_AssignSize(...) + * + * Functions used when malloc is not allowed + * Returns number of bytes needed to allocate for iSAC struct. + * + */ + +WebRtc_Word16 WebRtcIsacfix_AssignSize(int *sizeinbytes) { + *sizeinbytes=sizeof(ISACFIX_SubStruct)*2/sizeof(WebRtc_Word16); + return(0); +} + +/*************************************************************************** + * WebRtcIsacfix_Assign(...) + * + * Functions used when malloc is not allowed + * Place struct at given address + * + * If successful, Return 0, else Return -1 + */ + +WebRtc_Word16 WebRtcIsacfix_Assign(ISACFIX_MainStruct **inst, void *ISACFIX_inst_Addr) { + if (ISACFIX_inst_Addr!=NULL) { + *inst = (ISACFIX_MainStruct*)ISACFIX_inst_Addr; + (*(ISACFIX_SubStruct**)inst)->errorcode = 0; + (*(ISACFIX_SubStruct**)inst)->initflag = 0; + (*(ISACFIX_SubStruct**)inst)->ISACenc_obj.SaveEnc_ptr = NULL; + return(0); + } else { + return(-1); + } +} + + +#ifndef ISACFIX_NO_DYNAMIC_MEM + +/**************************************************************************** + * WebRtcIsacfix_Create(...) + * + * This function creates a ISAC instance, which will contain the state + * information for one coding/decoding channel. + * + * Input: + * - *ISAC_main_inst : a pointer to the coder instance. + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_Create(ISACFIX_MainStruct **ISAC_main_inst) +{ + ISACFIX_SubStruct *tempo; + tempo = malloc(1 * sizeof(ISACFIX_SubStruct)); + *ISAC_main_inst = (ISACFIX_MainStruct *)tempo; + if (*ISAC_main_inst!=NULL) { + (*(ISACFIX_SubStruct**)ISAC_main_inst)->errorcode = 0; + (*(ISACFIX_SubStruct**)ISAC_main_inst)->initflag = 0; + (*(ISACFIX_SubStruct**)ISAC_main_inst)->ISACenc_obj.SaveEnc_ptr = NULL; + return(0); + } else { + return(-1); + } +} + + +/**************************************************************************** + * WebRtcIsacfix_CreateInternal(...) + * + * This function creates the memory that is used to store data in the encoder + * + * Input: + * - *ISAC_main_inst : a pointer to the coder instance. + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_CreateInternal(ISACFIX_MainStruct *ISAC_main_inst) +{ + ISACFIX_SubStruct *ISAC_inst; + + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* Allocate memory for storing encoder data */ + ISAC_inst->ISACenc_obj.SaveEnc_ptr = malloc(1 * sizeof(ISAC_SaveEncData_t)); + + if (ISAC_inst->ISACenc_obj.SaveEnc_ptr!=NULL) { + return(0); + } else { + return(-1); + } +} + + +#endif + + + +/**************************************************************************** + * WebRtcIsacfix_Free(...) + * + * This function frees the ISAC instance created at the beginning. + * + * Input: + * - ISAC_main_inst : a ISAC instance. + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_Free(ISACFIX_MainStruct *ISAC_main_inst) +{ + free(ISAC_main_inst); + return(0); +} + +/**************************************************************************** + * WebRtcIsacfix_FreeInternal(...) + * + * This function frees the internal memory for storing encoder data. + * + * Input: + * - ISAC_main_inst : a ISAC instance. + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct *ISAC_main_inst) +{ + ISACFIX_SubStruct *ISAC_inst; + + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* Release memory */ + free(ISAC_inst->ISACenc_obj.SaveEnc_ptr); + + return(0); +} + +/**************************************************************************** + * WebRtcIsacfix_EncoderInit(...) + * + * This function initializes a ISAC instance prior to the encoder calls. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - CodingMode : 0 -> Bit rate and frame length are automatically + * adjusted to available bandwidth on + * transmission channel. + * 1 -> User sets a frame length and a target bit + * rate which is taken as the maximum short-term + * average bit rate. + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 CodingMode) +{ + int k; + WebRtc_Word16 statusInit; + ISACFIX_SubStruct *ISAC_inst; + + statusInit = 0; + /* typecast pointer to rela structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* flag encoder init */ + ISAC_inst->initflag |= 2; + + if (CodingMode == 0) + /* Adaptive mode */ + ISAC_inst->ISACenc_obj.new_framelength = INITIAL_FRAMESAMPLES; + else if (CodingMode == 1) + /* Instantaneous mode */ + ISAC_inst->ISACenc_obj.new_framelength = 480; /* default for I-mode */ + else { + ISAC_inst->errorcode = ISAC_DISALLOWED_CODING_MODE; + statusInit = -1; + } + + ISAC_inst->CodingMode = CodingMode; + + WebRtcIsacfix_InitMaskingEnc(&ISAC_inst->ISACenc_obj.maskfiltstr_obj); + WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACenc_obj.prefiltbankstr_obj); + WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACenc_obj.pitchfiltstr_obj); + WebRtcIsacfix_InitPitchAnalysis(&ISAC_inst->ISACenc_obj.pitchanalysisstr_obj); + + + WebRtcIsacfix_InitBandwidthEstimator(&ISAC_inst->bwestimator_obj); + WebRtcIsacfix_InitRateModel(&ISAC_inst->ISACenc_obj.rate_data_obj); + + + ISAC_inst->ISACenc_obj.buffer_index = 0; + ISAC_inst->ISACenc_obj.frame_nb = 0; + ISAC_inst->ISACenc_obj.BottleNeck = 32000; /* default for I-mode */ + ISAC_inst->ISACenc_obj.MaxDelay = 10; /* default for I-mode */ + ISAC_inst->ISACenc_obj.current_framesamples = 0; + ISAC_inst->ISACenc_obj.s2nr = 0; + ISAC_inst->ISACenc_obj.MaxBits = 0; + ISAC_inst->ISACenc_obj.bitstr_seed = 4447; + ISAC_inst->ISACenc_obj.payloadLimitBytes30 = STREAM_MAXW16_30MS << 1; + ISAC_inst->ISACenc_obj.payloadLimitBytes60 = STREAM_MAXW16_60MS << 1; + ISAC_inst->ISACenc_obj.maxPayloadBytes = STREAM_MAXW16_60MS << 1; + ISAC_inst->ISACenc_obj.maxRateInBytes = STREAM_MAXW16_30MS << 1; + ISAC_inst->ISACenc_obj.enforceFrameSize = 0; + + /* Init the bistream data area to zero */ + for (k=0; k<STREAM_MAXW16_60MS; k++){ + ISAC_inst->ISACenc_obj.bitstr_obj.stream[k] = 0; + } + +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED + WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACenc_obj.interpolatorstr_obj); +#endif + + + return statusInit; +} + + +/**************************************************************************** + * WebRtcIsacfix_Encode(...) + * + * This function encodes 10ms frame(s) and inserts it into a package. + * Input speech length has to be 160 samples (10ms). The encoder buffers those + * 10ms frames until it reaches the chosen Framesize (480 or 960 samples + * corresponding to 30 or 60 ms frames), and then proceeds to the encoding. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - speechIn : input speech vector. + * + * Output: + * - encoded : the encoded data vector + * + * Return value: + * : >0 - Length (in bytes) of coded data + * : 0 - The buffer didn't reach the chosen framesize + * so it keeps buffering speech samples. + * : -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst, + const WebRtc_Word16 *speechIn, + WebRtc_Word16 *encoded) +{ + ISACFIX_SubStruct *ISAC_inst; + WebRtc_Word16 stream_len; +#ifndef WEBRTC_BIG_ENDIAN + int k; +#endif + + /* typecast pointer to rela structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + + /* check if encoder initiated */ + if ((ISAC_inst->initflag & 2) != 2) { + ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED; + return (-1); + } + + stream_len = WebRtcIsacfix_EncodeImpl((WebRtc_Word16*)speechIn, + &ISAC_inst->ISACenc_obj, + &ISAC_inst->bwestimator_obj, + ISAC_inst->CodingMode); + if (stream_len<0) { + ISAC_inst->errorcode = - stream_len; + return -1; + } + + + /* convert from bytes to WebRtc_Word16 */ +#ifndef WEBRTC_BIG_ENDIAN + for (k=0;k<(stream_len+1)>>1;k++) { + encoded[k] = (WebRtc_Word16)( ( (WebRtc_UWord16)(ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] >> 8 ) + | (((ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] & 0x00FF) << 8)); + } + +#else + WEBRTC_SPL_MEMCPY_W16(encoded, (ISAC_inst->ISACenc_obj.bitstr_obj).stream, (stream_len + 1)>>1); +#endif + + + + return stream_len; + +} + + + + +/**************************************************************************** + * WebRtcIsacfix_EncodeNb(...) + * + * This function encodes 10ms narrow band (8 kHz sampling) frame(s) and inserts + * it into a package. Input speech length has to be 80 samples (10ms). The encoder + * interpolates into wide-band (16 kHz sampling) buffers those + * 10ms frames until it reaches the chosen Framesize (480 or 960 wide-band samples + * corresponding to 30 or 60 ms frames), and then proceeds to the encoding. + * + * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - speechIn : input speech vector. + * + * Output: + * - encoded : the encoded data vector + * + * Return value: + * : >0 - Length (in bytes) of coded data + * : 0 - The buffer didn't reach the chosen framesize + * so it keeps buffering speech samples. + * : -1 - Error + */ +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED +WebRtc_Word16 WebRtcIsacfix_EncodeNb(ISACFIX_MainStruct *ISAC_main_inst, + const WebRtc_Word16 *speechIn, + WebRtc_Word16 *encoded) +{ + ISACFIX_SubStruct *ISAC_inst; + WebRtc_Word16 stream_len; + WebRtc_Word16 speechInWB[FRAMESAMPLES_10ms]; + WebRtc_Word16 Vector_Word16_1[FRAMESAMPLES_10ms/2]; + WebRtc_Word16 Vector_Word16_2[FRAMESAMPLES_10ms/2]; + + int k; + + + /* typecast pointer to rela structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + + /* check if encoder initiated */ + if ((ISAC_inst->initflag & 2) != 2) { + ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED; + return (-1); + } + + + /* Oversample to WB */ + + /* Form polyphase signals, and compensate for DC offset */ + for (k=0;k<FRAMESAMPLES_10ms/2;k++) { + Vector_Word16_1[k] = speechIn[k] + 1; + Vector_Word16_2[k] = speechIn[k]; + } + WebRtcIsacfix_FilterAndCombine2(Vector_Word16_1, Vector_Word16_2, speechInWB, &ISAC_inst->ISACenc_obj.interpolatorstr_obj, FRAMESAMPLES_10ms); + + + /* Encode WB signal */ + stream_len = WebRtcIsacfix_EncodeImpl((WebRtc_Word16*)speechInWB, + &ISAC_inst->ISACenc_obj, + &ISAC_inst->bwestimator_obj, + ISAC_inst->CodingMode); + if (stream_len<0) { + ISAC_inst->errorcode = - stream_len; + return -1; + } + + + /* convert from bytes to WebRtc_Word16 */ +#ifndef WEBRTC_BIG_ENDIAN + for (k=0;k<(stream_len+1)>>1;k++) { + encoded[k] = (WebRtc_Word16)(((WebRtc_UWord16)(ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] >> 8) + | (((ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] & 0x00FF) << 8)); + } + +#else + WEBRTC_SPL_MEMCPY_W16(encoded, (ISAC_inst->ISACenc_obj.bitstr_obj).stream, (stream_len + 1)>>1); +#endif + + + + return stream_len; +} +#endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */ + + +/**************************************************************************** + * WebRtcIsacfix_GetNewBitStream(...) + * + * This function returns encoded data, with the recieved bwe-index in the + * stream. It should always return a complete packet, i.e. only called once + * even for 60 msec frames + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - bweIndex : index of bandwidth estimate to put in new bitstream + * + * Output: + * - encoded : the encoded data vector + * + * Return value: + * : >0 - Length (in bytes) of coded data + * : -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 bweIndex, + float scale, + WebRtc_Word16 *encoded) +{ + ISACFIX_SubStruct *ISAC_inst; + WebRtc_Word16 stream_len; +#ifndef WEBRTC_BIG_ENDIAN + int k; +#endif + + /* typecast pointer to rela structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + + /* check if encoder initiated */ + if ((ISAC_inst->initflag & 2) != 2) { + ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED; + return (-1); + } + + stream_len = WebRtcIsacfix_EncodeStoredData(&ISAC_inst->ISACenc_obj, + bweIndex, + scale); + if (stream_len<0) { + ISAC_inst->errorcode = - stream_len; + return -1; + } + +#ifndef WEBRTC_BIG_ENDIAN + for (k=0;k<(stream_len+1)>>1;k++) { + encoded[k] = (WebRtc_Word16)( ( (WebRtc_UWord16)(ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] >> 8 ) + | (((ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] & 0x00FF) << 8)); + } + +#else + WEBRTC_SPL_MEMCPY_W16(encoded, (ISAC_inst->ISACenc_obj.bitstr_obj).stream, (stream_len + 1)>>1); +#endif + + return stream_len; + +} + + + +/**************************************************************************** + * WebRtcIsacfix_DecoderInit(...) + * + * This function initializes a ISAC instance prior to the decoder calls. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * + * Return value + * : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct *ISAC_main_inst) +{ + ISACFIX_SubStruct *ISAC_inst; + + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* flag decoder init */ + ISAC_inst->initflag |= 1; + + + WebRtcIsacfix_InitMaskingDec(&ISAC_inst->ISACdec_obj.maskfiltstr_obj); + WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACdec_obj.postfiltbankstr_obj); + WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACdec_obj.pitchfiltstr_obj); + + /* TS */ + WebRtcIsacfix_InitPlc( &ISAC_inst->ISACdec_obj.plcstr_obj ); + + +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED + WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACdec_obj.decimatorstr_obj); +#endif + + return 0; +} + + +/**************************************************************************** + * WebRtcIsacfix_UpdateBwEstimate1(...) + * + * This function updates the estimate of the bandwidth. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - encoded : encoded ISAC frame(s). + * - packet_size : size of the packet. + * - rtp_seq_number : the RTP number of the packet. + * - arr_ts : the arrival time of the packet (from NetEq) + * in samples. + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst, + const WebRtc_UWord16 *encoded, + WebRtc_Word32 packet_size, + WebRtc_UWord16 rtp_seq_number, + WebRtc_UWord32 arr_ts) +{ + ISACFIX_SubStruct *ISAC_inst; + Bitstr_dec streamdata; + WebRtc_UWord16 partOfStream[5]; +#ifndef WEBRTC_BIG_ENDIAN + int k; +#endif + WebRtc_Word16 err; + + /* Set stream pointer to point at partOfStream */ + streamdata.stream = (WebRtc_UWord16 *)partOfStream; + + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* Sanity check of packet length */ + if (packet_size <= 0) { + /* return error code if the packet length is null or less */ + ISAC_inst->errorcode = ISAC_EMPTY_PACKET; + return -1; + } else if (packet_size > (STREAM_MAXW16<<1)) { + /* return error code if length of stream is too long */ + ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH; + return -1; + } + + /* check if decoder initiated */ + if ((ISAC_inst->initflag & 1) != 1) { + ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED; + return (-1); + } + + streamdata.W_upper = 0xFFFFFFFF; + streamdata.streamval = 0; + streamdata.stream_index = 0; + streamdata.full = 1; + +#ifndef WEBRTC_BIG_ENDIAN + for (k=0; k<5; k++) { + streamdata.stream[k] = (WebRtc_UWord16) (((WebRtc_UWord16)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8)); + } +#else + memcpy(streamdata.stream, encoded, 5); +#endif + + if (packet_size == 0) + { + /* return error code if the packet length is null */ + ISAC_inst->errorcode = ISAC_EMPTY_PACKET; + return -1; + } + + err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj, + &streamdata, + packet_size, + rtp_seq_number, + 0, + arr_ts); + + + if (err < 0) + { + /* return error code if something went wrong */ + ISAC_inst->errorcode = -err; + return -1; + } + + + return 0; +} + +/**************************************************************************** + * WebRtcIsacfix_UpdateBwEstimate(...) + * + * This function updates the estimate of the bandwidth. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - encoded : encoded ISAC frame(s). + * - packet_size : size of the packet. + * - rtp_seq_number : the RTP number of the packet. + * - send_ts : Send Time Stamp from RTP header + * - arr_ts : the arrival time of the packet (from NetEq) + * in samples. + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst, + const WebRtc_UWord16 *encoded, + WebRtc_Word32 packet_size, + WebRtc_UWord16 rtp_seq_number, + WebRtc_UWord32 send_ts, + WebRtc_UWord32 arr_ts) +{ + ISACFIX_SubStruct *ISAC_inst; + Bitstr_dec streamdata; + WebRtc_UWord16 partOfStream[5]; +#ifndef WEBRTC_BIG_ENDIAN + int k; +#endif + WebRtc_Word16 err; + + /* Set stream pointer to point at partOfStream */ + streamdata.stream = (WebRtc_UWord16 *)partOfStream; + + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* Sanity check of packet length */ + if (packet_size <= 0) { + /* return error code if the packet length is null or less */ + ISAC_inst->errorcode = ISAC_EMPTY_PACKET; + return -1; + } else if (packet_size > (STREAM_MAXW16<<1)) { + /* return error code if length of stream is too long */ + ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH; + return -1; + } + + /* check if decoder initiated */ + if ((ISAC_inst->initflag & 1) != 1) { + ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED; + return (-1); + } + + streamdata.W_upper = 0xFFFFFFFF; + streamdata.streamval = 0; + streamdata.stream_index = 0; + streamdata.full = 1; + +#ifndef WEBRTC_BIG_ENDIAN + for (k=0; k<5; k++) { + streamdata.stream[k] = (WebRtc_UWord16) ((encoded[k] >> 8)|((encoded[k] & 0xFF)<<8)); + } +#else + memcpy(streamdata.stream, encoded, 5); +#endif + + if (packet_size == 0) + { + /* return error code if the packet length is null */ + ISAC_inst->errorcode = ISAC_EMPTY_PACKET; + return -1; + } + + err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj, + &streamdata, + packet_size, + rtp_seq_number, + send_ts, + arr_ts); + + if (err < 0) + { + /* return error code if something went wrong */ + ISAC_inst->errorcode = -err; + return -1; + } + + + return 0; +} + +/**************************************************************************** + * WebRtcIsacfix_Decode(...) + * + * This function decodes a ISAC frame. Output speech length + * will be a multiple of 480 samples: 480 or 960 samples, + * depending on the framesize (30 or 60 ms). + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - encoded : encoded ISAC frame(s) + * - len : bytes in encoded vector + * + * Output: + * - decoded : The decoded vector + * + * Return value : >0 - number of samples in decoded vector + * -1 - Error + */ + + +WebRtc_Word16 WebRtcIsacfix_Decode(ISACFIX_MainStruct *ISAC_main_inst, + const WebRtc_UWord16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType) +{ + ISACFIX_SubStruct *ISAC_inst; + /* number of samples (480 or 960), output from decoder */ + /* that were actually used in the encoder/decoder (determined on the fly) */ + WebRtc_Word16 number_of_samples; +#ifndef WEBRTC_BIG_ENDIAN + int k; +#endif + WebRtc_Word16 declen = 0; + + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* check if decoder initiated */ + if ((ISAC_inst->initflag & 1) != 1) { + ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED; + return (-1); + } + + /* Sanity check of packet length */ + if (len <= 0) { + /* return error code if the packet length is null or less */ + ISAC_inst->errorcode = ISAC_EMPTY_PACKET; + return -1; + } else if (len > (STREAM_MAXW16<<1)) { + /* return error code if length of stream is too long */ + ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH; + return -1; + } + + (ISAC_inst->ISACdec_obj.bitstr_obj).stream = (WebRtc_UWord16 *)encoded; + + /* convert bitstream from WebRtc_Word16 to bytes */ +#ifndef WEBRTC_BIG_ENDIAN + for (k=0; k<(len>>1); k++) { + (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (WebRtc_UWord16) ((encoded[k] >> 8)|((encoded[k] & 0xFF)<<8)); + } + if (len & 0x0001) + (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (WebRtc_UWord16) ((encoded[k] & 0xFF)<<8); +#endif + + /* added for NetEq purposes (VAD/DTX related) */ + *speechType=1; + + declen = WebRtcIsacfix_DecodeImpl(decoded,&ISAC_inst->ISACdec_obj, &number_of_samples); + + if (declen < 0) { + /* Some error inside the decoder */ + ISAC_inst->errorcode = -declen; + memset(decoded, 0, sizeof(WebRtc_Word16) * MAX_FRAMESAMPLES); + return -1; + } + + /* error check */ + + if (declen & 0x0001) { + if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) & 0x00FF) ) { + ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH; + memset(decoded, 0, sizeof(WebRtc_Word16) * number_of_samples); + return -1; + } + } else { + if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) >> 8) ) { + ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH; + memset(decoded, 0, sizeof(WebRtc_Word16) * number_of_samples); + return -1; + } + } + + return number_of_samples; +} + + + + + +/**************************************************************************** + * WebRtcIsacfix_DecodeNb(...) + * + * This function decodes a ISAC frame in narrow-band (8 kHz sampling). + * Output speech length will be a multiple of 240 samples: 240 or 480 samples, + * depending on the framesize (30 or 60 ms). + * + * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - encoded : encoded ISAC frame(s) + * - len : bytes in encoded vector + * + * Output: + * - decoded : The decoded vector + * + * Return value : >0 - number of samples in decoded vector + * -1 - Error + */ + +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED +WebRtc_Word16 WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst, + const WebRtc_UWord16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType) +{ + ISACFIX_SubStruct *ISAC_inst; + /* twice the number of samples (480 or 960), output from decoder */ + /* that were actually used in the encoder/decoder (determined on the fly) */ + WebRtc_Word16 number_of_samples; +#ifndef WEBRTC_BIG_ENDIAN + int k; +#endif + WebRtc_Word16 declen = 0; + WebRtc_Word16 dummy[FRAMESAMPLES/2]; + + + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* check if decoder initiated */ + if ((ISAC_inst->initflag & 1) != 1) { + ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED; + return (-1); + } + + if (len == 0) + { /* return error code if the packet length is null */ + + ISAC_inst->errorcode = ISAC_EMPTY_PACKET; + return -1; + } + + (ISAC_inst->ISACdec_obj.bitstr_obj).stream = (WebRtc_UWord16 *)encoded; + + /* convert bitstream from WebRtc_Word16 to bytes */ +#ifndef WEBRTC_BIG_ENDIAN + for (k=0; k<(len>>1); k++) { + (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (WebRtc_UWord16) ((encoded[k] >> 8)|((encoded[k] & 0xFF)<<8)); + } + if (len & 0x0001) + (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (WebRtc_UWord16) ((encoded[k] & 0xFF)<<8); +#endif + + /* added for NetEq purposes (VAD/DTX related) */ + *speechType=1; + + declen = WebRtcIsacfix_DecodeImpl(decoded,&ISAC_inst->ISACdec_obj, &number_of_samples); + + if (declen < 0) { + /* Some error inside the decoder */ + ISAC_inst->errorcode = -declen; + memset(decoded, 0, sizeof(WebRtc_Word16) * FRAMESAMPLES); + return -1; + } + + /* error check */ + + if (declen & 0x0001) { + if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) & 0x00FF) ) { + ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH; + memset(decoded, 0, sizeof(WebRtc_Word16) * number_of_samples); + return -1; + } + } else { + if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) >> 8) ) { + ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH; + memset(decoded, 0, sizeof(WebRtc_Word16) * number_of_samples); + return -1; + } + } + + WebRtcIsacfix_SplitAndFilter2(decoded, decoded, dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj); + + if (number_of_samples>FRAMESAMPLES) { + WebRtcIsacfix_SplitAndFilter2(decoded + FRAMESAMPLES, decoded + FRAMESAMPLES/2, + dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj); + } + + return number_of_samples/2; +} +#endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */ + + +/**************************************************************************** + * WebRtcIsacfix_DecodePlcNb(...) + * + * This function conducts PLC for ISAC frame(s) in narrow-band (8kHz sampling). + * Output speech length will be "240*noOfLostFrames" samples + * that is equevalent of "30*noOfLostFrames" millisecond. + * + * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - noOfLostFrames : Number of PLC frames (240 sample=30ms) to produce + * + * Output: + * - decoded : The decoded vector + * + * Return value : >0 - number of samples in decoded PLC vector + * -1 - Error + */ + +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED +WebRtc_Word16 WebRtcIsacfix_DecodePlcNb(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 *decoded, + WebRtc_Word16 noOfLostFrames ) +{ + WebRtc_Word16 no_of_samples, declen, k, ok; + WebRtc_Word16 outframeNB[FRAMESAMPLES]; + WebRtc_Word16 outframeWB[FRAMESAMPLES]; + WebRtc_Word16 dummy[FRAMESAMPLES/2]; + + + ISACFIX_SubStruct *ISAC_inst; + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */ + if (noOfLostFrames > 2){ + noOfLostFrames = 2; + } + + k = 0; + declen = 0; + while( noOfLostFrames > 0 ) + { + ok = WebRtcIsacfix_DecodePlcImpl( outframeWB, &ISAC_inst->ISACdec_obj, &no_of_samples ); + if(ok) + return -1; + + WebRtcIsacfix_SplitAndFilter2(outframeWB, &(outframeNB[k*240]), dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj); + + declen += no_of_samples; + noOfLostFrames--; + k++; + } + + declen>>=1; + + for (k=0;k<declen;k++) { + decoded[k] = outframeNB[k]; + } + + return declen; +} +#endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */ + + + + +/**************************************************************************** + * WebRtcIsacfix_DecodePlc(...) + * + * This function conducts PLC for ISAC frame(s) in wide-band (16kHz sampling). + * Output speech length will be "480*noOfLostFrames" samples + * that is equevalent of "30*noOfLostFrames" millisecond. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - noOfLostFrames : Number of PLC frames (480sample = 30ms) + * to produce + * + * Output: + * - decoded : The decoded vector + * + * Return value : >0 - number of samples in decoded PLC vector + * -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_DecodePlc(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 *decoded, + WebRtc_Word16 noOfLostFrames) +{ + + WebRtc_Word16 no_of_samples, declen, k, ok; + WebRtc_Word16 outframe16[MAX_FRAMESAMPLES]; + + ISACFIX_SubStruct *ISAC_inst; + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */ + if (noOfLostFrames > 2) { + noOfLostFrames = 2; + } + k = 0; + declen = 0; + while( noOfLostFrames > 0 ) + { + ok = WebRtcIsacfix_DecodePlcImpl( &(outframe16[k*480]), &ISAC_inst->ISACdec_obj, &no_of_samples ); + if(ok) + return -1; + declen += no_of_samples; + noOfLostFrames--; + k++; + } + + for (k=0;k<declen;k++) { + decoded[k] = outframe16[k]; + } + + return declen; +} + + +/**************************************************************************** + * WebRtcIsacfix_Control(...) + * + * This function sets the limit on the short-term average bit rate and the + * frame length. Should be used only in Instantaneous mode. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - rate : limit on the short-term average bit rate, + * in bits/second (between 10000 and 32000) + * - framesize : number of milliseconds per frame (30 or 60) + * + * Return value : 0 - ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_Control(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 rate, + WebRtc_Word16 framesize) +{ + ISACFIX_SubStruct *ISAC_inst; + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + if (ISAC_inst->CodingMode == 0) + { + /* in adaptive mode */ + ISAC_inst->errorcode = ISAC_MODE_MISMATCH; + return -1; + } + + + if (rate >= 10000 && rate <= 32000) + ISAC_inst->ISACenc_obj.BottleNeck = rate; + else { + ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK; + return -1; + } + + + + if (framesize == 30 || framesize == 60) + ISAC_inst->ISACenc_obj.new_framelength = (FS/1000) * framesize; + else { + ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH; + return -1; + } + + return 0; +} + + +/**************************************************************************** + * WebRtcIsacfix_ControlBwe(...) + * + * This function sets the initial values of bottleneck and frame-size if + * iSAC is used in channel-adaptive mode. Through this API, users can + * enforce a frame-size for all values of bottleneck. Then iSAC will not + * automatically change the frame-size. + * + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - rateBPS : initial value of bottleneck in bits/second + * 10000 <= rateBPS <= 32000 is accepted + * For default bottleneck set rateBPS = 0 + * - frameSizeMs : number of milliseconds per frame (30 or 60) + * - enforceFrameSize : 1 to enforce the given frame-size through out + * the adaptation process, 0 to let iSAC change + * the frame-size if required. + * + * Return value : 0 - ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcIsacfix_ControlBwe(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 rateBPS, + WebRtc_Word16 frameSizeMs, + WebRtc_Word16 enforceFrameSize) +{ + ISACFIX_SubStruct *ISAC_inst; + /* Typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* check if encoder initiated */ + if ((ISAC_inst->initflag & 2) != 2) { + ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED; + return (-1); + } + + /* Check that we are in channel-adaptive mode, otherwise, return -1 */ + if (ISAC_inst->CodingMode != 0) { + ISAC_inst->errorcode = ISAC_MODE_MISMATCH; + return (-1); + } + + /* Set struct variable if enforceFrameSize is set. ISAC will then keep the */ + /* chosen frame size. */ + ISAC_inst->ISACenc_obj.enforceFrameSize = (enforceFrameSize != 0)? 1:0; + + /* Set initial rate, if value between 10000 and 32000, */ + /* if rateBPS is 0, keep the default initial bottleneck value (15000) */ + if ((rateBPS >= 10000) && (rateBPS <= 32000)) { + ISAC_inst->bwestimator_obj.sendBwAvg = (((WebRtc_UWord32)rateBPS) << 7); + } else if (rateBPS != 0) { + ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK; + return -1; + } + + /* Set initial framesize. If enforceFrameSize is set the frame size will not change */ + if ((frameSizeMs == 30) || (frameSizeMs == 60)) { + ISAC_inst->ISACenc_obj.new_framelength = (FS/1000) * frameSizeMs; + } else { + ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH; + return -1; + } + + return 0; +} + + + + + +/**************************************************************************** + * WebRtcIsacfix_GetDownLinkBwIndex(...) + * + * This function returns index representing the Bandwidth estimate from + * other side to this side. + * + * Input: + * - ISAC_main_inst: iSAC struct + * + * Output: + * - rateIndex : Bandwidth estimate to transmit to other side. + * + */ + +WebRtc_Word16 WebRtcIsacfix_GetDownLinkBwIndex(ISACFIX_MainStruct* ISAC_main_inst, + WebRtc_Word16* rateIndex) +{ + ISACFIX_SubStruct *ISAC_inst; + + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* Call function to get Bandwidth Estimate */ + *rateIndex = WebRtcIsacfix_GetDownlinkBwIndexImpl(&ISAC_inst->bwestimator_obj); + + return 0; +} + + +/**************************************************************************** + * WebRtcIsacfix_UpdateUplinkBw(...) + * + * This function takes an index representing the Bandwidth estimate from + * this side to other side and updates BWE. + * + * Input: + * - ISAC_main_inst: iSAC struct + * - rateIndex : Bandwidth estimate from other side. + * + */ + +WebRtc_Word16 WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct* ISAC_main_inst, + WebRtc_Word16 rateIndex) +{ + WebRtc_Word16 err = 0; + ISACFIX_SubStruct *ISAC_inst; + + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + /* Call function to update BWE with received Bandwidth Estimate */ + err = WebRtcIsacfix_UpdateUplinkBwRec(&ISAC_inst->bwestimator_obj, rateIndex); + if (err < 0) { + ISAC_inst->errorcode = -err; + return (-1); + } + + return 0; +} + +/**************************************************************************** + * WebRtcIsacfix_ReadFrameLen(...) + * + * This function returns the length of the frame represented in the packet. + * + * Input: + * - encoded : Encoded bitstream + * + * Output: + * - frameLength : Length of frame in packet (in samples) + * + */ + +WebRtc_Word16 WebRtcIsacfix_ReadFrameLen(const WebRtc_Word16* encoded, + WebRtc_Word16* frameLength) +{ + Bitstr_dec streamdata; + WebRtc_UWord16 partOfStream[5]; +#ifndef WEBRTC_BIG_ENDIAN + int k; +#endif + WebRtc_Word16 err; + + /* Set stream pointer to point at partOfStream */ + streamdata.stream = (WebRtc_UWord16 *)partOfStream; + + streamdata.W_upper = 0xFFFFFFFF; + streamdata.streamval = 0; + streamdata.stream_index = 0; + streamdata.full = 1; + +#ifndef WEBRTC_BIG_ENDIAN + for (k=0; k<5; k++) { + streamdata.stream[k] = (WebRtc_UWord16) (((WebRtc_UWord16)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8)); + } +#else + memcpy(streamdata.stream, encoded, 5); +#endif + + /* decode frame length */ + err = WebRtcIsacfix_DecodeFrameLen(&streamdata, frameLength); + if (err<0) // error check + return err; + + return 0; +} + + +/**************************************************************************** + * WebRtcIsacfix_ReadBwIndex(...) + * + * This function returns the index of the Bandwidth estimate from the bitstream. + * + * Input: + * - encoded : Encoded bitstream + * + * Output: + * - frameLength : Length of frame in packet (in samples) + * - rateIndex : Bandwidth estimate in bitstream + * + */ + +WebRtc_Word16 WebRtcIsacfix_ReadBwIndex(const WebRtc_Word16* encoded, + WebRtc_Word16* rateIndex) +{ + Bitstr_dec streamdata; + WebRtc_UWord16 partOfStream[5]; +#ifndef WEBRTC_BIG_ENDIAN + int k; +#endif + WebRtc_Word16 err; + + /* Set stream pointer to point at partOfStream */ + streamdata.stream = (WebRtc_UWord16 *)partOfStream; + + streamdata.W_upper = 0xFFFFFFFF; + streamdata.streamval = 0; + streamdata.stream_index = 0; + streamdata.full = 1; + +#ifndef WEBRTC_BIG_ENDIAN + for (k=0; k<5; k++) { + streamdata.stream[k] = (WebRtc_UWord16) (((WebRtc_UWord16)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8)); + } +#else + memcpy(streamdata.stream, encoded, 5); +#endif + + /* decode frame length, needed to get to the rateIndex in the bitstream */ + err = WebRtcIsacfix_DecodeFrameLen(&streamdata, rateIndex); + if (err<0) // error check + return err; + + /* decode BW estimation */ + err = WebRtcIsacfix_DecodeSendBandwidth(&streamdata, rateIndex); + if (err<0) // error check + return err; + + return 0; +} + + + + +/**************************************************************************** + * WebRtcIsacfix_GetErrorCode(...) + * + * This function can be used to check the error code of an iSAC instance. When + * a function returns -1 a error code will be set for that instance. The + * function below extract the code of the last error that occured in the + * specified instance. + * + * Input: + * - ISAC_main_inst : ISAC instance + * + * Return value : Error code + */ + +WebRtc_Word16 WebRtcIsacfix_GetErrorCode(ISACFIX_MainStruct *ISAC_main_inst) +{ + ISACFIX_SubStruct *ISAC_inst; + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + return ISAC_inst->errorcode; +} + + + +/**************************************************************************** + * WebRtcIsacfix_GetUplinkBw(...) + * + * This function returns the inst quantized iSAC send bitrate + * + * Input: + * - ISAC_main_inst : iSAC instance + * + * Return value : bitrate + */ + +WebRtc_Word32 WebRtcIsacfix_GetUplinkBw(ISACFIX_MainStruct *ISAC_main_inst) +{ + ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + BwEstimatorstr * bw = (BwEstimatorstr*)&(ISAC_inst->bwestimator_obj); + + return (WebRtc_Word32) WebRtcIsacfix_GetUplinkBandwidth(bw); +} + +/**************************************************************************** + * WebRtcIsacfix_GetNewFrameLen(...) + * + * This function return the next frame length (in samples) of iSAC. + * + * Input: + * - ISAC_main_inst : iSAC instance + * + * Return value : frame lenght in samples + */ + +WebRtc_Word16 WebRtcIsacfix_GetNewFrameLen(ISACFIX_MainStruct *ISAC_main_inst) +{ + ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + return ISAC_inst->ISACenc_obj.new_framelength; +} + + +/**************************************************************************** + * WebRtcIsacfix_SetMaxPayloadSize(...) + * + * This function sets a limit for the maximum payload size of iSAC. The same + * value is used both for 30 and 60 msec packets. + * The absolute max will be valid until next time the function is called. + * NOTE! This function may override the function WebRtcIsacfix_SetMaxRate() + * + * Input: + * - ISAC_main_inst : iSAC instance + * - maxPayloadBytes : maximum size of the payload in bytes + * valid values are between 100 and 400 bytes + * + * + * Return value : 0 if sucessful + * -1 if error happens + */ + +WebRtc_Word16 WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 maxPayloadBytes) +{ + ISACFIX_SubStruct *ISAC_inst; + + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + if((maxPayloadBytes < 100) || (maxPayloadBytes > 400)) + { + /* maxPayloadBytes is out of valid range */ + return -1; + } + else + { + /* Set new absolute max, which will not change unless this function + is called again with a new value */ + ISAC_inst->ISACenc_obj.maxPayloadBytes = maxPayloadBytes; + + /* Set new maximum values for 30 and 60 msec packets */ + if (maxPayloadBytes < ISAC_inst->ISACenc_obj.maxRateInBytes) { + ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxPayloadBytes; + } else { + ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxRateInBytes; + } + + if ( maxPayloadBytes < (ISAC_inst->ISACenc_obj.maxRateInBytes << 1)) { + ISAC_inst->ISACenc_obj.payloadLimitBytes60 = maxPayloadBytes; + } else { + ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (ISAC_inst->ISACenc_obj.maxRateInBytes << 1); + } + } + return 0; +} + + +/**************************************************************************** + * WebRtcIsacfix_SetMaxRate(...) + * + * This function sets the maximum rate which the codec may not exceed for a + * singel packet. The maximum rate is set in bits per second. + * The codec has an absolute maximum rate of 53400 bits per second (200 bytes + * per 30 msec). + * It is possible to set a maximum rate between 32000 and 53400 bits per second. + * + * The rate limit is valid until next time the function is called. + * + * NOTE! Packet size will never go above the value set if calling + * WebRtcIsacfix_SetMaxPayloadSize() (default max packet size is 400 bytes). + * + * Input: + * - ISAC_main_inst : iSAC instance + * - maxRateInBytes : maximum rate in bits per second, + * valid values are 32000 to 53400 bits + * + * Return value : 0 if sucessful + * -1 if error happens + */ + +WebRtc_Word16 WebRtcIsacfix_SetMaxRate(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word32 maxRate) +{ + ISACFIX_SubStruct *ISAC_inst; + WebRtc_Word16 maxRateInBytes; + + /* typecast pointer to real structure */ + ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst; + + if((maxRate < 32000) || (maxRate > 53400)) + { + /* maxRate is out of valid range */ + return -1; + } + else + { + /* Calculate maximum number of bytes per 30 msec packets for the given + maximum rate. Multiply with 30/1000 to get number of bits per 30 msec, + divide by 8 to get number of bytes per 30 msec: + maxRateInBytes = floor((maxRate * 30/1000) / 8); */ + maxRateInBytes = (WebRtc_Word16)( WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_MUL(maxRate, 3), 800) ); + + /* Store the value for usage in the WebRtcIsacfix_SetMaxPayloadSize-function */ + ISAC_inst->ISACenc_obj.maxRateInBytes = maxRateInBytes; + + /* For 30 msec packets: if the new limit is below the maximum + payload size, set a new limit */ + if (maxRateInBytes < ISAC_inst->ISACenc_obj.maxPayloadBytes) { + ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxRateInBytes; + } else { + ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxPayloadBytes; + } + + /* For 60 msec packets: if the new limit (times 2) is below the + maximum payload size, set a new limit */ + if ( (maxRateInBytes << 1) < ISAC_inst->ISACenc_obj.maxPayloadBytes) { + ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (maxRateInBytes << 1); + } else { + ISAC_inst->ISACenc_obj.payloadLimitBytes60 = ISAC_inst->ISACenc_obj.maxPayloadBytes; + } + } + + return 0; +} + + + +/**************************************************************************** + * WebRtcIsacfix_version(...) + * + * This function returns the version number. + * + * Output: + * - version : Pointer to character string + * + */ + +void WebRtcIsacfix_version(char *version) +{ + strcpy(version, "3.6.0"); +} diff --git a/src/libs/webrtc/isac/isacfix.h b/src/libs/webrtc/isac/isacfix.h new file mode 100644 index 00000000..28e94294 --- /dev/null +++ b/src/libs/webrtc/isac/isacfix.h @@ -0,0 +1,633 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_INTERFACE_ISACFIX_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_INTERFACE_ISACFIX_H_ + +/* + * Define the fixpoint numeric formats + */ +#include "typedefs.h" + + +typedef struct { + void *dummy; +} ISACFIX_MainStruct; + + +#if defined(__cplusplus) +extern "C" { +#endif + + + /************************************************************************** + * WebRtcIsacfix_AssignSize(...) + * + * Functions used when malloc is not allowed + * Output the number of bytes needed to allocate for iSAC struct. + * + */ + + WebRtc_Word16 WebRtcIsacfix_AssignSize(int *sizeinbytes); + + /************************************************************************** + * WebRtcIsacfix_Assign(...) + * + * Functions used when malloc is not allowed, it + * places a struct at the given address. + * + * Input: + * - *ISAC_main_inst : a pointer to the coder instance. + * - ISACFIX_inst_Addr : address of the memory where a space is + * for iSAC structure. + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_Assign(ISACFIX_MainStruct **inst, + void *ISACFIX_inst_Addr); + + /**************************************************************************** + * WebRtcIsacfix_Create(...) + * + * This function creates an ISAC instance, which will contain the state + * information for one coding/decoding channel. + * + * Input: + * - *ISAC_main_inst : a pointer to the coder instance. + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_Create(ISACFIX_MainStruct **ISAC_main_inst); + + + /**************************************************************************** + * WebRtcIsacfix_Free(...) + * + * This function frees the ISAC instance created at the beginning. + * + * Input: + * - ISAC_main_inst : a ISAC instance. + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_Free(ISACFIX_MainStruct *ISAC_main_inst); + + + /**************************************************************************** + * WebRtcIsacfix_EncoderInit(...) + * + * This function initializes an ISAC instance prior to the encoder calls. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - CodingMode : 0 - Bit rate and frame length are automatically + * adjusted to available bandwidth on + * transmission channel. + * 1 - User sets a frame length and a target bit + * rate which is taken as the maximum short-term + * average bit rate. + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 CodingMode); + + + /**************************************************************************** + * WebRtcIsacfix_Encode(...) + * + * This function encodes 10ms frame(s) and inserts it into a package. + * Input speech length has to be 160 samples (10ms). The encoder buffers those + * 10ms frames until it reaches the chosen Framesize (480 or 960 samples + * corresponding to 30 or 60 ms frames), and then proceeds to the encoding. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - speechIn : input speech vector. + * + * Output: + * - encoded : the encoded data vector + * + * Return value : >0 - Length (in bytes) of coded data + * 0 - The buffer didn't reach the chosen framesize + * so it keeps buffering speech samples. + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst, + const WebRtc_Word16 *speechIn, + WebRtc_Word16 *encoded); + + + + /**************************************************************************** + * WebRtcIsacfix_EncodeNb(...) + * + * This function encodes 10ms narrow band (8 kHz sampling) frame(s) and inserts + * it into a package. Input speech length has to be 80 samples (10ms). The encoder + * interpolates into wide-band (16 kHz sampling) buffers those + * 10ms frames until it reaches the chosen Framesize (480 or 960 wide-band samples + * corresponding to 30 or 60 ms frames), and then proceeds to the encoding. + * + * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - speechIn : input speech vector. + * + * Output: + * - encoded : the encoded data vector + * + * Return value : >0 - Length (in bytes) of coded data + * 0 - The buffer didn't reach the chosen framesize + * so it keeps buffering speech samples. + * -1 - Error + */ + + +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED + WebRtc_Word16 WebRtcIsacfix_EncodeNb(ISACFIX_MainStruct *ISAC_main_inst, + const WebRtc_Word16 *speechIn, + WebRtc_Word16 *encoded); +#endif // WEBRTC_ISAC_FIX_NB_CALLS_ENABLED + + + + /**************************************************************************** + * WebRtcIsacfix_DecoderInit(...) + * + * This function initializes an ISAC instance prior to the decoder calls. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * + * Return value + * : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct *ISAC_main_inst); + + + /**************************************************************************** + * WebRtcIsacfix_UpdateBwEstimate1(...) + * + * This function updates the estimate of the bandwidth. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - encoded : encoded ISAC frame(s). + * - packet_size : size of the packet. + * - rtp_seq_number : the RTP number of the packet. + * - arr_ts : the arrival time of the packet (from NetEq) + * in samples. + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst, + const WebRtc_UWord16 *encoded, + WebRtc_Word32 packet_size, + WebRtc_UWord16 rtp_seq_number, + WebRtc_UWord32 arr_ts); + + /**************************************************************************** + * WebRtcIsacfix_UpdateBwEstimate(...) + * + * This function updates the estimate of the bandwidth. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - encoded : encoded ISAC frame(s). + * - packet_size : size of the packet. + * - rtp_seq_number : the RTP number of the packet. + * - send_ts : the send time of the packet from RTP header, + * in samples. + * - arr_ts : the arrival time of the packet (from NetEq) + * in samples. + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst, + const WebRtc_UWord16 *encoded, + WebRtc_Word32 packet_size, + WebRtc_UWord16 rtp_seq_number, + WebRtc_UWord32 send_ts, + WebRtc_UWord32 arr_ts); + + /**************************************************************************** + * WebRtcIsacfix_Decode(...) + * + * This function decodes an ISAC frame. Output speech length + * will be a multiple of 480 samples: 480 or 960 samples, + * depending on the framesize (30 or 60 ms). + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - encoded : encoded ISAC frame(s) + * - len : bytes in encoded vector + * + * Output: + * - decoded : The decoded vector + * + * Return value : >0 - number of samples in decoded vector + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_Decode(ISACFIX_MainStruct *ISAC_main_inst, + const WebRtc_UWord16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType); + + + /**************************************************************************** + * WebRtcIsacfix_DecodeNb(...) + * + * This function decodes a ISAC frame in narrow-band (8 kHz sampling). + * Output speech length will be a multiple of 240 samples: 240 or 480 samples, + * depending on the framesize (30 or 60 ms). + * + * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - encoded : encoded ISAC frame(s) + * - len : bytes in encoded vector + * + * Output: + * - decoded : The decoded vector + * + * Return value : >0 - number of samples in decoded vector + * -1 - Error + */ + +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED + WebRtc_Word16 WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst, + const WebRtc_UWord16 *encoded, + WebRtc_Word16 len, + WebRtc_Word16 *decoded, + WebRtc_Word16 *speechType); +#endif // WEBRTC_ISAC_FIX_NB_CALLS_ENABLED + + + /**************************************************************************** + * WebRtcIsacfix_DecodePlcNb(...) + * + * This function conducts PLC for ISAC frame(s) in narrow-band (8kHz sampling). + * Output speech length will be "240*noOfLostFrames" samples + * that equevalent of "30*noOfLostFrames" millisecond. + * + * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - noOfLostFrames : Number of PLC frames (240 sample=30ms) to produce + * NOTE! Maximum number is 2 (480 samples = 60ms) + * + * Output: + * - decoded : The decoded vector + * + * Return value : >0 - number of samples in decoded PLC vector + * -1 - Error + */ + +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED + WebRtc_Word16 WebRtcIsacfix_DecodePlcNb(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 *decoded, + WebRtc_Word16 noOfLostFrames ); +#endif // WEBRTC_ISAC_FIX_NB_CALLS_ENABLED + + + + + /**************************************************************************** + * WebRtcIsacfix_DecodePlc(...) + * + * This function conducts PLC for ISAC frame(s) in wide-band (16kHz sampling). + * Output speech length will be "480*noOfLostFrames" samples + * that is equevalent of "30*noOfLostFrames" millisecond. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - noOfLostFrames : Number of PLC frames (480sample = 30ms) + * to produce + * NOTE! Maximum number is 2 (960 samples = 60ms) + * + * Output: + * - decoded : The decoded vector + * + * Return value : >0 - number of samples in decoded PLC vector + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_DecodePlc(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 *decoded, + WebRtc_Word16 noOfLostFrames ); + + + /**************************************************************************** + * WebRtcIsacfix_ReadFrameLen(...) + * + * This function returns the length of the frame represented in the packet. + * + * Input: + * - encoded : Encoded bitstream + * + * Output: + * - frameLength : Length of frame in packet (in samples) + * + */ + + WebRtc_Word16 WebRtcIsacfix_ReadFrameLen(const WebRtc_Word16* encoded, + WebRtc_Word16* frameLength); + + /**************************************************************************** + * WebRtcIsacfix_Control(...) + * + * This function sets the limit on the short-term average bit rate and the + * frame length. Should be used only in Instantaneous mode. + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - rate : limit on the short-term average bit rate, + * in bits/second (between 10000 and 32000) + * - framesize : number of milliseconds per frame (30 or 60) + * + * Return value : 0 - ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_Control(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 rate, + WebRtc_Word16 framesize); + + + + /**************************************************************************** + * WebRtcIsacfix_ControlBwe(...) + * + * This function sets the initial values of bottleneck and frame-size if + * iSAC is used in channel-adaptive mode. Through this API, users can + * enforce a frame-size for all values of bottleneck. Then iSAC will not + * automatically change the frame-size. + * + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - rateBPS : initial value of bottleneck in bits/second + * 10000 <= rateBPS <= 32000 is accepted + * - frameSizeMs : number of milliseconds per frame (30 or 60) + * - enforceFrameSize : 1 to enforce the given frame-size through out + * the adaptation process, 0 to let iSAC change + * the frame-size if required. + * + * Return value : 0 - ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_ControlBwe(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 rateBPS, + WebRtc_Word16 frameSizeMs, + WebRtc_Word16 enforceFrameSize); + + + + /**************************************************************************** + * WebRtcIsacfix_version(...) + * + * This function returns the version number. + * + * Output: + * - version : Pointer to character string + * + */ + + void WebRtcIsacfix_version(char *version); + + + /**************************************************************************** + * WebRtcIsacfix_GetErrorCode(...) + * + * This function can be used to check the error code of an iSAC instance. When + * a function returns -1 a error code will be set for that instance. The + * function below extract the code of the last error that occured in the + * specified instance. + * + * Input: + * - ISAC_main_inst : ISAC instance + * + * Return value : Error code + */ + + WebRtc_Word16 WebRtcIsacfix_GetErrorCode(ISACFIX_MainStruct *ISAC_main_inst); + + + /**************************************************************************** + * WebRtcIsacfix_GetUplinkBw(...) + * + * This function return iSAC send bitrate + * + * Input: + * - ISAC_main_inst : iSAC instance + * + * Return value : <0 Error code + * else bitrate + */ + + WebRtc_Word32 WebRtcIsacfix_GetUplinkBw(ISACFIX_MainStruct *ISAC_main_inst); + + + /**************************************************************************** + * WebRtcIsacfix_SetMaxPayloadSize(...) + * + * This function sets a limit for the maximum payload size of iSAC. The same + * value is used both for 30 and 60 msec packets. + * The absolute max will be valid until next time the function is called. + * NOTE! This function may override the function WebRtcIsacfix_SetMaxRate() + * + * Input: + * - ISAC_main_inst : iSAC instance + * - maxPayloadBytes : maximum size of the payload in bytes + * valid values are between 100 and 400 bytes + * + * + * Return value : 0 if sucessful + * -1 if error happens + */ + + WebRtc_Word16 WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 maxPayloadBytes); + + + /**************************************************************************** + * WebRtcIsacfix_SetMaxRate(...) + * + * This function sets the maximum rate which the codec may not exceed for a + * singel packet. The maximum rate is set in bits per second. + * The codec has an absolute maximum rate of 53400 bits per second (200 bytes + * per 30 msec). + * It is possible to set a maximum rate between 32000 and 53400 bits per second. + * + * The rate limit is valid until next time the function is called. + * + * NOTE! Packet size will never go above the value set if calling + * WebRtcIsacfix_SetMaxPayloadSize() (default max packet size is 400 bytes). + * + * Input: + * - ISAC_main_inst : iSAC instance + * - maxRateInBytes : maximum rate in bits per second, + * valid values are 32000 to 53400 bits + * + * Return value : 0 if sucessful + * -1 if error happens + */ + + WebRtc_Word16 WebRtcIsacfix_SetMaxRate(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word32 maxRate); + + /**************************************************************************** + * WebRtcIsacfix_CreateInternal(...) + * + * This function creates the memory that is used to store data in the encoder + * + * Input: + * - *ISAC_main_inst : a pointer to the coder instance. + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_CreateInternal(ISACFIX_MainStruct *ISAC_main_inst); + + + /**************************************************************************** + * WebRtcIsacfix_FreeInternal(...) + * + * This function frees the internal memory for storing encoder data. + * + * Input: + * - ISAC_main_inst : an ISAC instance. + * + * Return value : 0 - Ok + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct *ISAC_main_inst); + + + /**************************************************************************** + * WebRtcIsacfix_GetNewBitStream(...) + * + * This function returns encoded data, with the recieved bwe-index in the + * stream. It should always return a complete packet, i.e. only called once + * even for 60 msec frames + * + * Input: + * - ISAC_main_inst : ISAC instance. + * - bweIndex : index of bandwidth estimate to put in new bitstream + * - scale : factor for rate change (0.4 ~=> half the rate, 1 no change). + * + * Output: + * - encoded : the encoded data vector + * + * Return value : >0 - Length (in bytes) of coded data + * -1 - Error + */ + + WebRtc_Word16 WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct *ISAC_main_inst, + WebRtc_Word16 bweIndex, + float scale, + WebRtc_Word16 *encoded); + + + /**************************************************************************** + * WebRtcIsacfix_GetDownLinkBwIndex(...) + * + * This function returns index representing the Bandwidth estimate from + * other side to this side. + * + * Input: + * - ISAC_main_inst : iSAC struct + * + * Output: + * - rateIndex : Bandwidth estimate to transmit to other side. + * + */ + + WebRtc_Word16 WebRtcIsacfix_GetDownLinkBwIndex(ISACFIX_MainStruct* ISAC_main_inst, + WebRtc_Word16* rateIndex); + + + /**************************************************************************** + * WebRtcIsacfix_UpdateUplinkBw(...) + * + * This function takes an index representing the Bandwidth estimate from + * this side to other side and updates BWE. + * + * Input: + * - ISAC_main_inst : iSAC struct + * - rateIndex : Bandwidth estimate from other side. + * + */ + + WebRtc_Word16 WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct* ISAC_main_inst, + WebRtc_Word16 rateIndex); + + + /**************************************************************************** + * WebRtcIsacfix_ReadBwIndex(...) + * + * This function returns the index of the Bandwidth estimate from the bitstream. + * + * Input: + * - encoded : Encoded bitstream + * + * Output: + * - rateIndex : Bandwidth estimate in bitstream + * + */ + + WebRtc_Word16 WebRtcIsacfix_ReadBwIndex(const WebRtc_Word16* encoded, + WebRtc_Word16* rateIndex); + + + /**************************************************************************** + * WebRtcIsacfix_GetNewFrameLen(...) + * + * This function return the next frame length (in samples) of iSAC. + * + * Input: + * -ISAC_main_inst : iSAC instance + * + * Return value : frame lenght in samples + */ + + WebRtc_Word16 WebRtcIsacfix_GetNewFrameLen(ISACFIX_MainStruct *ISAC_main_inst); + + +#if defined(__cplusplus) +} +#endif + + + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_INTERFACE_ISACFIX_H_ */ diff --git a/src/libs/webrtc/isac/lattice.c b/src/libs/webrtc/isac/lattice.c new file mode 100644 index 00000000..78e454ee --- /dev/null +++ b/src/libs/webrtc/isac/lattice.c @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * lattice.c + * + * Contains the normalized lattice filter routines (MA and AR) for iSAC codec + * + */ + +#include "codec.h" +#include "settings.h" + +/* filter the signal using normalized lattice filter */ +/* MA filter */ +void WebRtcIsacfix_NormLatticeFilterMa(WebRtc_Word16 orderCoef, + WebRtc_Word32 *stateGQ15, + WebRtc_Word16 *lat_inQ0, + WebRtc_Word16 *filt_coefQ15, + WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 lo_hi, + WebRtc_Word16 *lat_outQ9) +{ + WebRtc_Word16 sthQ15[MAX_AR_MODEL_ORDER]; + WebRtc_Word16 cthQ15[MAX_AR_MODEL_ORDER]; + + int u, i, ii, k, n; + WebRtc_Word16 temp2,temp3; + WebRtc_Word16 ord_1 = orderCoef+1; + WebRtc_Word32 inv_cthQ16[MAX_AR_MODEL_ORDER]; + + WebRtc_Word32 gain32, fQtmp; + WebRtc_Word16 gain16; + WebRtc_Word16 gain_sh; + + WebRtc_Word32 tmp32, tmp32b; + WebRtc_Word32 fQ15vec[HALF_SUBFRAMELEN]; + WebRtc_Word32 gQ15[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN]; + WebRtc_Word16 sh; + WebRtc_Word16 t16a; + WebRtc_Word16 t16b; + +#define LATTICE_MUL_32_32_RSFT16(a32a, a32b, b32) \ + ((WebRtc_Word32)(WEBRTC_SPL_MUL(a32a, b32) + (WEBRTC_SPL_MUL_16_32_RSFT16(a32b, b32)))) + /* This macro is FORBIDDEN to use elsewhere than in two places in this file + since it might give unpredictable results, since a general WebRtc_Word32*WebRtc_Word32 + multiplication results in a 64 bit value. The result is then shifted just + 16 steps to the right, giving need for 48 bits, i.e. in the generel case, + it will NOT fit in a WebRtc_Word32. In the cases used in here, the WebRtc_Word32 will be + enough, since (FOR SOME REASON!!!) the involved multiplicands aren't big + enough to overflow a WebRtc_Word32 after shifting right 16 bits. I have compared + the result of a multiplication between t32 and tmp32, done in two ways: + + 1) Using (WebRtc_Word32) (((float)(tmp32))*((float)(tmp32b))/65536.0); + + 2) Using LATTICE_MUL_32_32_RSFT16(t16a, t16b, tmp32b); + + By running 25 files, I haven't found any bigger diff than 64 - this was in the + case when method 1) gave 650235648 and 2) gave 650235712. + + It might be good to investigate this further, in order to PROVE why it seems to + work without any problems. This might be done, by using the properties of + all reflection coefficients etc. + + */ + + for (u=0;u<SUBFRAMES;u++) + { + /* set the Direct Form coefficients */ + temp2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(u, orderCoef); + temp3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(2, u)+lo_hi; + + /* compute lattice filter coefficients */ + for (ii=0; ii<orderCoef; ii++) { + sthQ15[ii] = filt_coefQ15[temp2+ii]; + } + + WebRtcSpl_SqrtOfOneMinusXSquared(sthQ15, orderCoef, cthQ15); + + /* compute the gain */ + gain32 = gain_lo_hiQ17[temp3]; + gain_sh = WebRtcSpl_NormW32(gain32); + gain32 = WEBRTC_SPL_LSHIFT_W32(gain32, gain_sh); //Q(17+gain_sh) + + for (k=0;k<orderCoef;k++) + { + gain32 = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[k], gain32); //Q15*Q(17+gain_sh)>>15 = Q(17+gain_sh) + inv_cthQ16[k] = WebRtcSpl_DivW32W16((WebRtc_Word32)2147483647, cthQ15[k]); // 1/cth[k] in Q31/Q15 = Q16 + } + gain16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(gain32, 16); //Q(1+gain_sh) + + /* normalized lattice filter */ + /*****************************/ + + /* initial conditions */ + for (i=0;i<HALF_SUBFRAMELEN;i++) + { + fQ15vec[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)lat_inQ0[i + WEBRTC_SPL_MUL_16_16(u, HALF_SUBFRAMELEN)], 15); //Q15 + gQ15[0][i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)lat_inQ0[i + WEBRTC_SPL_MUL_16_16(u, HALF_SUBFRAMELEN)], 15); //Q15 + } + + + fQtmp = fQ15vec[0]; + + /* get the state of f&g for the first input, for all orders */ + for (i=1;i<ord_1;i++) + { + // Calculate f[i][0] = inv_cth[i-1]*(f[i-1][0] + sth[i-1]*stateG[i-1]); + tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(sthQ15[i-1], stateGQ15[i-1]);//Q15*Q15>>15 = Q15 + tmp32b= fQtmp + tmp32; //Q15+Q15=Q15 + tmp32 = inv_cthQ16[i-1]; //Q16 + t16a = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32, 16); + t16b = (WebRtc_Word16) (tmp32-WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)t16a), 16)); + if (t16b<0) t16a++; + tmp32 = LATTICE_MUL_32_32_RSFT16(t16a, t16b, tmp32b); + fQtmp = tmp32; // Q15 + + // Calculate g[i][0] = cth[i-1]*stateG[i-1] + sth[i-1]* f[i][0]; + tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[i-1], stateGQ15[i-1]); //Q15*Q15>>15 = Q15 + tmp32b = WEBRTC_SPL_MUL_16_32_RSFT15(sthQ15[i-1], fQtmp); //Q15*Q15>>15 = Q15 + tmp32 = tmp32 + tmp32b;//Q15+Q15 = Q15 + gQ15[i][0] = tmp32; // Q15 + } + + /* filtering */ + /* save the states */ + for(k=0;k<orderCoef;k++) + { + for(n=0;n<HALF_SUBFRAMELEN-1;n++) + { + // Calculate f[k+1][n+1] = inv_cth[k]*(f[k][n+1] + sth[k]*g[k][n]); + tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(sthQ15[k], gQ15[k][n]);//Q15*Q15>>15 = Q15 + tmp32b= fQ15vec[n+1] + tmp32; //Q15+Q15=Q15 + tmp32 = inv_cthQ16[k]; //Q16 + t16a = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32, 16); + t16b = (WebRtc_Word16) (tmp32-WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)t16a), 16)); + if (t16b<0) t16a++; + tmp32 = LATTICE_MUL_32_32_RSFT16(t16a, t16b, tmp32b); + fQ15vec[n+1] = tmp32; // Q15 + + // Calculate g[k+1][n+1] = cth[k]*g[k][n] + sth[k]* f[k+1][n+1]; + tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[k], gQ15[k][n]); //Q15*Q15>>15 = Q15 + tmp32b = WEBRTC_SPL_MUL_16_32_RSFT15(sthQ15[k], fQ15vec[n+1]); //Q15*Q15>>15 = Q15 + tmp32 = tmp32 + tmp32b;//Q15+Q15 = Q15 + gQ15[k+1][n+1] = tmp32; // Q15 + } + } + + fQ15vec[0] = fQtmp; + + for(n=0;n<HALF_SUBFRAMELEN;n++) + { + //gain32 = WEBRTC_SPL_RSHIFT_W32(gain32, gain_sh); // Q(17+gain_sh) -> Q17 + tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(gain16, fQ15vec[n]); //Q(1+gain_sh)*Q15>>16 = Q(gain_sh) + sh = 9-gain_sh; //number of needed shifts to reach Q9 + t16a = (WebRtc_Word16) WEBRTC_SPL_SHIFT_W32(tmp32, sh); + lat_outQ9[n + WEBRTC_SPL_MUL_16_16(u, HALF_SUBFRAMELEN)] = t16a; + } + + /* save the states */ + for (i=0;i<ord_1;i++) + { + stateGQ15[i] = gQ15[i][HALF_SUBFRAMELEN-1]; + } + //process next frame + } + + return; +} + + + + + +/* ----------------AR filter-------------------------*/ +/* filter the signal using normalized lattice filter */ +void WebRtcIsacfix_NormLatticeFilterAr(WebRtc_Word16 orderCoef, + WebRtc_Word16 *stateGQ0, + WebRtc_Word32 *lat_inQ25, + WebRtc_Word16 *filt_coefQ15, + WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 lo_hi, + WebRtc_Word16 *lat_outQ0) +{ + int ii,n,k,i,u; + WebRtc_Word16 sthQ15[MAX_AR_MODEL_ORDER]; + WebRtc_Word16 cthQ15[MAX_AR_MODEL_ORDER]; + WebRtc_Word32 tmp32, tmp32_2; + + + WebRtc_Word16 tmpAR; + WebRtc_Word16 ARfQ0vec[HALF_SUBFRAMELEN]; + WebRtc_Word16 ARgQ0vec[MAX_AR_MODEL_ORDER+1]; + + WebRtc_Word32 inv_gain32; + WebRtc_Word16 inv_gain16; + WebRtc_Word16 den16; + WebRtc_Word16 sh; + + WebRtc_Word16 temp2,temp3; + WebRtc_Word16 ord_1 = orderCoef+1; + + for (u=0;u<SUBFRAMES;u++) + { + //set the denominator and numerator of the Direct Form + temp2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(u, orderCoef); + temp3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(2, u) + lo_hi; + + for (ii=0; ii<orderCoef; ii++) { + sthQ15[ii] = filt_coefQ15[temp2+ii]; + } + + WebRtcSpl_SqrtOfOneMinusXSquared(sthQ15, orderCoef, cthQ15); + + /* Simulation of the 25 files shows that maximum value in + the vector gain_lo_hiQ17[] is 441344, which means that + it is log2((2^31)/441344) = 12.2 shifting bits from + saturation. Therefore, it should be safe to use Q27 instead + of Q17. */ + + tmp32 = WEBRTC_SPL_LSHIFT_W32(gain_lo_hiQ17[temp3], 10); // Q27 + + for (k=0;k<orderCoef;k++) { + tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[k], tmp32); // Q15*Q27>>15 = Q27 + } + + sh = WebRtcSpl_NormW32(tmp32); // tmp32 is the gain + den16 = (WebRtc_Word16) WEBRTC_SPL_SHIFT_W32(tmp32, sh-16); //Q(27+sh-16) = Q(sh+11) (all 16 bits are value bits) + inv_gain32 = WebRtcSpl_DivW32W16((WebRtc_Word32)2147483647, den16); // 1/gain in Q31/Q(sh+11) = Q(20-sh) + + //initial conditions + inv_gain16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(inv_gain32, 2); // 1/gain in Q(20-sh-2) = Q(18-sh) + + for (i=0;i<HALF_SUBFRAMELEN;i++) + { + + tmp32 = WEBRTC_SPL_LSHIFT_W32(lat_inQ25[i + WEBRTC_SPL_MUL_16_16(u, HALF_SUBFRAMELEN)], 1); //Q25->Q26 + tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(inv_gain16, tmp32); //lat_in[]*inv_gain in (Q(18-sh)*Q26)>>16 = Q(28-sh) + tmp32 = WEBRTC_SPL_SHIFT_W32(tmp32, -(28-sh)); // lat_in[]*inv_gain in Q0 + + ARfQ0vec[i] = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, tmp32, -32768); // Q0 + } + + for (i=orderCoef-1;i>=0;i--) //get the state of f&g for the first input, for all orders + { + tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(cthQ15[i],ARfQ0vec[0])) - (WEBRTC_SPL_MUL_16_16(sthQ15[i],stateGQ0[i])) + 16384), 15); + tmpAR = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, tmp32, -32768); // Q0 + + tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(sthQ15[i],ARfQ0vec[0])) + (WEBRTC_SPL_MUL_16_16(cthQ15[i], stateGQ0[i])) + 16384), 15); + ARgQ0vec[i+1] = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, tmp32, -32768); // Q0 + ARfQ0vec[0] = tmpAR; + } + ARgQ0vec[0] = ARfQ0vec[0]; + + for(n=0;n<HALF_SUBFRAMELEN-1;n++) + { + tmpAR = ARfQ0vec[n+1]; + for(k=orderCoef-1;k>=0;k--) + { + tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(cthQ15[k], tmpAR)) - (WEBRTC_SPL_MUL_16_16(sthQ15[k], ARgQ0vec[k])) + 16384), 15); + tmp32_2 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(sthQ15[k], tmpAR)) + (WEBRTC_SPL_MUL_16_16(cthQ15[k], ARgQ0vec[k])) + 16384), 15); + tmpAR = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, tmp32, -32768); // Q0 + + ARgQ0vec[k+1] = (WebRtc_Word16) WEBRTC_SPL_SAT(32767, tmp32_2, -32768); // Q0 + + } + ARfQ0vec[n+1] = tmpAR; + ARgQ0vec[0] = tmpAR; + } + + for(n=0;n<HALF_SUBFRAMELEN;n++) + { + lat_outQ0[n + WEBRTC_SPL_MUL_16_16(u, HALF_SUBFRAMELEN)] = ARfQ0vec[n]; + } + + + /* cannot use memcpy in the following */ + + for (i=0;i<ord_1;i++) + { + stateGQ0[i] = ARgQ0vec[i]; + } + } + + return; +} diff --git a/src/libs/webrtc/isac/lpc_masking_model.c b/src/libs/webrtc/isac/lpc_masking_model.c new file mode 100644 index 00000000..ab7c3ca4 --- /dev/null +++ b/src/libs/webrtc/isac/lpc_masking_model.c @@ -0,0 +1,1034 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * lpc_masking_model.c + * + * LPC analysis and filtering functions + * + */ + +#include "codec.h" +#include "entropy_coding.h" +#include "settings.h" + + +/* The conversion is implemented by the step-down algorithm */ +void WebRtcSpl_AToK_JSK( + WebRtc_Word16 *a16, /* Q11 */ + WebRtc_Word16 useOrder, + WebRtc_Word16 *k16 /* Q15 */ + ) +{ + int m, k; + WebRtc_Word32 tmp32[MAX_AR_MODEL_ORDER]; + WebRtc_Word32 tmp32b; + WebRtc_Word32 tmp_inv_denum32; + WebRtc_Word16 tmp_inv_denum16; + + k16[useOrder-1]= WEBRTC_SPL_LSHIFT_W16(a16[useOrder], 4); //Q11<<4 => Q15 + + for (m=useOrder-1; m>0; m--) { + tmp_inv_denum32 = ((WebRtc_Word32) 1073741823) - WEBRTC_SPL_MUL_16_16(k16[m], k16[m]); // (1 - k^2) in Q30 + tmp_inv_denum16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp_inv_denum32, 15); // (1 - k^2) in Q15 + + for (k=1; k<=m; k++) { + tmp32b = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)a16[k], 16) - + WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(k16[m], a16[m-k+1]), 1); + + tmp32[k] = WebRtcSpl_DivW32W16(tmp32b, tmp_inv_denum16); //Q27/Q15 = Q12 + } + + for (k=1; k<m; k++) { + a16[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32[k], 1); //Q12>>1 => Q11 + } + + tmp32[m] = WEBRTC_SPL_SAT(4092, tmp32[m], -4092); + k16[m-1] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(tmp32[m], 3); //Q12<<3 => Q15 + } + + return; +} + + + + + +WebRtc_Word16 WebRtcSpl_LevinsonW32_JSK( + WebRtc_Word32 *R, /* (i) Autocorrelation of length >= order+1 */ + WebRtc_Word16 *A, /* (o) A[0..order] LPC coefficients (Q11) */ + WebRtc_Word16 *K, /* (o) K[0...order-1] Reflection coefficients (Q15) */ + WebRtc_Word16 order /* (i) filter order */ + ) { + WebRtc_Word16 i, j; + WebRtc_Word16 R_hi[LEVINSON_MAX_ORDER+1], R_low[LEVINSON_MAX_ORDER+1]; + /* Aurocorr coefficients in high precision */ + WebRtc_Word16 A_hi[LEVINSON_MAX_ORDER+1], A_low[LEVINSON_MAX_ORDER+1]; + /* LPC coefficients in high precicion */ + WebRtc_Word16 A_upd_hi[LEVINSON_MAX_ORDER+1], A_upd_low[LEVINSON_MAX_ORDER+1]; + /* LPC coefficients for next iteration */ + WebRtc_Word16 K_hi, K_low; /* reflection coefficient in high precision */ + WebRtc_Word16 Alpha_hi, Alpha_low, Alpha_exp; /* Prediction gain Alpha in high precision + and with scale factor */ + WebRtc_Word16 tmp_hi, tmp_low; + WebRtc_Word32 temp1W32, temp2W32, temp3W32; + WebRtc_Word16 norm; + + /* Normalize the autocorrelation R[0]...R[order+1] */ + + norm = WebRtcSpl_NormW32(R[0]); + + for (i=order;i>=0;i--) { + temp1W32 = WEBRTC_SPL_LSHIFT_W32(R[i], norm); + /* Put R in hi and low format */ + R_hi[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + R_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16)), 1); + } + + /* K = A[1] = -R[1] / R[0] */ + + temp2W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[1],16) + + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[1],1); /* R[1] in Q31 */ + temp3W32 = WEBRTC_SPL_ABS_W32(temp2W32); /* abs R[1] */ + temp1W32 = WebRtcSpl_DivW32HiLow(temp3W32, R_hi[0], R_low[0]); /* abs(R[1])/R[0] in Q31 */ + /* Put back the sign on R[1] */ + if (temp2W32 > 0) { + temp1W32 = -temp1W32; + } + + /* Put K in hi and low format */ + K_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1); + + /* Store first reflection coefficient */ + K[0] = K_hi; + + temp1W32 = WEBRTC_SPL_RSHIFT_W32(temp1W32, 4); /* A[1] in Q27 */ + + /* Put A[1] in hi and low format */ + A_hi[1] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + A_low[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[1], 16)), 1); + + /* Alpha = R[0] * (1-K^2) */ + + temp1W32 = WEBRTC_SPL_LSHIFT_W32((WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(K_hi, K_low), 14) + + WEBRTC_SPL_MUL_16_16(K_hi, K_hi)), 1); /* temp1W32 = k^2 in Q31 */ + + temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); /* Guard against <0 */ + temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; /* temp1W32 = (1 - K[0]*K[0]) in Q31 */ + + /* Store temp1W32 = 1 - K[0]*K[0] on hi and low format */ + tmp_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); + + /* Calculate Alpha in Q31 */ + temp1W32 = WEBRTC_SPL_LSHIFT_W32((WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_hi) + + WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_low), 15) + + WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_low[0], tmp_hi), 15) ), 1); + + /* Normalize Alpha and put it in hi and low format */ + + Alpha_exp = WebRtcSpl_NormW32(temp1W32); + temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp); + Alpha_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1); + + /* Perform the iterative calculations in the + Levinson Durbin algorithm */ + + for (i=2; i<=order; i++) + { + + /* ---- + \ + temp1W32 = R[i] + > R[j]*A[i-j] + / + ---- + j=1..i-1 + */ + + temp1W32 = 0; + + for(j=1; j<i; j++) { + /* temp1W32 is in Q31 */ + temp1W32 += (WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_hi[j], A_hi[i-j]), 1) + + WEBRTC_SPL_LSHIFT_W32(( WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_hi[j], A_low[i-j]), 15) + + WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_low[j], A_hi[i-j]), 15) ), 1)); + } + + temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, 4); + temp1W32 += (WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16) + + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[i], 1)); + + /* K = -temp1W32 / Alpha */ + temp2W32 = WEBRTC_SPL_ABS_W32(temp1W32); /* abs(temp1W32) */ + temp3W32 = WebRtcSpl_DivW32HiLow(temp2W32, Alpha_hi, Alpha_low); /* abs(temp1W32)/Alpha */ + + /* Put the sign of temp1W32 back again */ + if (temp1W32 > 0) { + temp3W32 = -temp3W32; + } + + /* Use the Alpha shifts from earlier to denormalize */ + norm = WebRtcSpl_NormW32(temp3W32); + if ((Alpha_exp <= norm)||(temp3W32==0)) { + temp3W32 = WEBRTC_SPL_LSHIFT_W32(temp3W32, Alpha_exp); + } else { + if (temp3W32 > 0) + { + temp3W32 = (WebRtc_Word32)0x7fffffffL; + } else + { + temp3W32 = (WebRtc_Word32)0x80000000L; + } + } + + /* Put K on hi and low format */ + K_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp3W32, 16); + K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1); + + /* Store Reflection coefficient in Q15 */ + K[i-1] = K_hi; + + /* Test for unstable filter. If unstable return 0 and let the + user decide what to do in that case + */ + + if ((WebRtc_Word32)WEBRTC_SPL_ABS_W16(K_hi) > (WebRtc_Word32)32740) { + return(-i); /* Unstable filter */ + } + + /* + Compute updated LPC coefficient: Anew[i] + Anew[j]= A[j] + K*A[i-j] for j=1..i-1 + Anew[i]= K + */ + + for(j=1; j<i; j++) + { + temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[j],16) + + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[j],1); /* temp1W32 = A[j] in Q27 */ + + temp1W32 += WEBRTC_SPL_LSHIFT_W32(( WEBRTC_SPL_MUL_16_16(K_hi, A_hi[i-j]) + + WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(K_hi, A_low[i-j]), 15) + + WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(K_low, A_hi[i-j]), 15) ), 1); /* temp1W32 += K*A[i-j] in Q27 */ + + /* Put Anew in hi and low format */ + A_upd_hi[j] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + A_upd_low[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[j], 16)), 1); + } + + temp3W32 = WEBRTC_SPL_RSHIFT_W32(temp3W32, 4); /* temp3W32 = K in Q27 (Convert from Q31 to Q27) */ + + /* Store Anew in hi and low format */ + A_upd_hi[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp3W32, 16); + A_upd_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[i], 16)), 1); + + /* Alpha = Alpha * (1-K^2) */ + + temp1W32 = WEBRTC_SPL_LSHIFT_W32((WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(K_hi, K_low), 14) + + WEBRTC_SPL_MUL_16_16(K_hi, K_hi)), 1); /* K*K in Q31 */ + + temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); /* Guard against <0 */ + temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; /* 1 - K*K in Q31 */ + + /* Convert 1- K^2 in hi and low format */ + tmp_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); + + /* Calculate Alpha = Alpha * (1-K^2) in Q31 */ + temp1W32 = WEBRTC_SPL_LSHIFT_W32(( WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_hi) + + WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_low), 15) + + WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(Alpha_low, tmp_hi), 15)), 1); + + /* Normalize Alpha and store it on hi and low format */ + + norm = WebRtcSpl_NormW32(temp1W32); + temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm); + + Alpha_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1); + + /* Update the total nomalization of Alpha */ + Alpha_exp = Alpha_exp + norm; + + /* Update A[] */ + + for(j=1; j<=i; j++) + { + A_hi[j] =A_upd_hi[j]; + A_low[j] =A_upd_low[j]; + } + } + + /* + Set A[0] to 1.0 and store the A[i] i=1...order in Q12 + (Convert from Q27 and use rounding) + */ + + A[0] = 2048; + + for(i=1; i<=order; i++) { + /* temp1W32 in Q27 */ + temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[i], 16) + + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[i], 1); + /* Round and store upper word */ + A[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32+(WebRtc_Word32)32768, 16); + } + return(1); /* Stable filters */ +} + + + + + +/* window */ +/* Matlab generation of floating point code: + * t = (1:256)/257; r = 1-(1-t).^.45; w = sin(r*pi).^3; w = w/sum(w); plot((1:256)/8, w); grid; + * for k=1:16, fprintf(1, '%.8f, ', w(k*16 + (-15:0))); fprintf(1, '\n'); end + * All values are multiplyed with 2^21 in fixed point code. + */ +static const WebRtc_Word16 kWindowAutocorr[WINLEN] = { + 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 5, 6, + 8, 10, 12, 14, 17, 20, 24, 28, 33, 38, 43, 49, + 56, 63, 71, 79, 88, 98, 108, 119, 131, 143, 157, 171, + 186, 202, 219, 237, 256, 275, 296, 318, 341, 365, 390, 416, + 444, 472, 502, 533, 566, 600, 635, 671, 709, 748, 789, 831, + 875, 920, 967, 1015, 1065, 1116, 1170, 1224, 1281, 1339, 1399, 1461, + 1525, 1590, 1657, 1726, 1797, 1870, 1945, 2021, 2100, 2181, 2263, 2348, + 2434, 2523, 2614, 2706, 2801, 2898, 2997, 3099, 3202, 3307, 3415, 3525, + 3637, 3751, 3867, 3986, 4106, 4229, 4354, 4481, 4611, 4742, 4876, 5012, + 5150, 5291, 5433, 5578, 5725, 5874, 6025, 6178, 6333, 6490, 6650, 6811, + 6974, 7140, 7307, 7476, 7647, 7820, 7995, 8171, 8349, 8529, 8711, 8894, + 9079, 9265, 9453, 9642, 9833, 10024, 10217, 10412, 10607, 10803, 11000, 11199, + 11398, 11597, 11797, 11998, 12200, 12401, 12603, 12805, 13008, 13210, 13412, 13614, + 13815, 14016, 14216, 14416, 14615, 14813, 15009, 15205, 15399, 15591, 15782, 15971, + 16157, 16342, 16524, 16704, 16881, 17056, 17227, 17395, 17559, 17720, 17877, 18030, + 18179, 18323, 18462, 18597, 18727, 18851, 18970, 19082, 19189, 19290, 19384, 19471, + 19551, 19623, 19689, 19746, 19795, 19835, 19867, 19890, 19904, 19908, 19902, 19886, + 19860, 19823, 19775, 19715, 19644, 19561, 19465, 19357, 19237, 19102, 18955, 18793, + 18618, 18428, 18223, 18004, 17769, 17518, 17252, 16970, 16672, 16357, 16025, 15677, + 15311, 14929, 14529, 14111, 13677, 13225, 12755, 12268, 11764, 11243, 10706, 10152, + 9583, 8998, 8399, 7787, 7162, 6527, 5883, 5231, 4576, 3919, 3265, 2620, + 1990, 1386, 825, 333 +}; + + +/* By using a hearing threshold level in dB of -28 dB (higher value gives more noise), + the H_T_H (in float) can be calculated as: + H_T_H = pow(10.0, 0.05 * (-28.0)) = 0.039810717055350 + In Q19, H_T_H becomes round(0.039810717055350*2^19) ~= 20872, i.e. + H_T_H = 20872/524288.0, and H_T_HQ19 = 20872; +*/ + + +/* The bandwidth expansion vectors are created from: + kPolyVecLo=[0.900000,0.810000,0.729000,0.656100,0.590490,0.531441,0.478297,0.430467,0.387420,0.348678,0.313811,0.282430]; + kPolyVecHi=[0.800000,0.640000,0.512000,0.409600,0.327680,0.262144]; + round(kPolyVecLo*32768) + round(kPolyVecHi*32768) +*/ +static const WebRtc_Word16 kPolyVecLo[12] = { + 29491, 26542, 23888, 21499, 19349, 17414, 15673, 14106, 12695, 11425, 10283, 9255 +}; +static const WebRtc_Word16 kPolyVecHi[6] = { + 26214, 20972, 16777, 13422, 10737, 8590 +}; + +static __inline WebRtc_Word32 log2_Q8_LPC( WebRtc_UWord32 x ) { + + WebRtc_Word32 zeros, lg2; + WebRtc_Word16 frac; + + zeros=WebRtcSpl_NormU32(x); + frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(((WebRtc_UWord32)WEBRTC_SPL_LSHIFT_W32(x, zeros)&0x7FFFFFFF), 23); + + /* log2(x) */ + + lg2= (WEBRTC_SPL_LSHIFT_W16((31-zeros), 8)+frac); + return lg2; + +} + +static const WebRtc_Word16 kMulPitchGain = -25; /* 200/256 in Q5 */ +static const WebRtc_Word16 kChngFactor = 3523; /* log10(2)*10/4*0.4/1.4=log10(2)/1.4= 0.2150 in Q14 */ +static const WebRtc_Word16 kExp2 = 11819; /* 1/log(2) */ + +void WebRtcIsacfix_GetVars(const WebRtc_Word16 *input, const WebRtc_Word16 *pitchGains_Q12, + WebRtc_UWord32 *oldEnergy, WebRtc_Word16 *varscale) +{ + int k; + WebRtc_UWord32 nrgQ[4]; + WebRtc_Word16 nrgQlog[4]; + WebRtc_Word16 tmp16, chng1, chng2, chng3, chng4, tmp, chngQ, oldNrgQlog, pgQ, pg3; + WebRtc_Word32 expPg32; + WebRtc_Word16 expPg, divVal; + WebRtc_Word16 tmp16_1, tmp16_2; + + /* Calculate energies of first and second frame halfs */ + nrgQ[0]=0; + for (k = QLOOKAHEAD/2; k < (FRAMESAMPLES/4 + QLOOKAHEAD) / 2; k++) { + nrgQ[0] +=WEBRTC_SPL_MUL_16_16(input[k],input[k]); + } + nrgQ[1]=0; + for ( ; k < (FRAMESAMPLES/2 + QLOOKAHEAD) / 2; k++) { + nrgQ[1] +=WEBRTC_SPL_MUL_16_16(input[k],input[k]); + } + nrgQ[2]=0; + for ( ; k < (WEBRTC_SPL_MUL_16_16(FRAMESAMPLES, 3)/4 + QLOOKAHEAD) / 2; k++) { + nrgQ[2] +=WEBRTC_SPL_MUL_16_16(input[k],input[k]); + } + nrgQ[3]=0; + for ( ; k < (FRAMESAMPLES + QLOOKAHEAD) / 2; k++) { + nrgQ[3] +=WEBRTC_SPL_MUL_16_16(input[k],input[k]); + } + + for ( k=0; k<4; k++) { + nrgQlog[k] = (WebRtc_Word16)log2_Q8_LPC(nrgQ[k]); /* log2(nrgQ) */ + } + oldNrgQlog = (WebRtc_Word16)log2_Q8_LPC(*oldEnergy); + + /* Calculate average level change */ + chng1 = WEBRTC_SPL_ABS_W16(nrgQlog[3]-nrgQlog[2]); + chng2 = WEBRTC_SPL_ABS_W16(nrgQlog[2]-nrgQlog[1]); + chng3 = WEBRTC_SPL_ABS_W16(nrgQlog[1]-nrgQlog[0]); + chng4 = WEBRTC_SPL_ABS_W16(nrgQlog[0]-oldNrgQlog); + tmp = chng1+chng2+chng3+chng4; + chngQ = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp, kChngFactor, 10); /* Q12 */ + chngQ += 2926; /* + 1.0/1.4 in Q12 */ + + /* Find average pitch gain */ + pgQ = 0; + for (k=0; k<4; k++) + { + pgQ += pitchGains_Q12[k]; + } + + pg3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(pgQ, pgQ,11); /* pgQ in Q(12+2)=Q14. Q14*Q14>>11 => Q17 */ + pg3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(pgQ, pg3,13); /* Q17*Q14>>13 =>Q18 */ + pg3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(pg3, kMulPitchGain ,5); /* Q10 kMulPitchGain = -25 = -200 in Q-3. */ + + tmp16=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(kExp2,pg3,13);/* Q13*Q10>>13 => Q10*/ + if (tmp16<0) { + tmp16_2 = (0x0400 | (tmp16 & 0x03FF)); + tmp16_1 = (WEBRTC_SPL_RSHIFT_W16((WebRtc_UWord16)(tmp16 ^ 0xFFFF), 10)-3); /* Gives result in Q14 */ + if (tmp16_1<0) + expPg=(WebRtc_Word16) -WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1); + else + expPg=(WebRtc_Word16) -WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1); + } else + expPg = (WebRtc_Word16) -16384; /* 1 in Q14, since 2^0=1 */ + + expPg32 = (WebRtc_Word32)WEBRTC_SPL_LSHIFT_W16((WebRtc_Word32)expPg, 8); /* Q22 */ + divVal = WebRtcSpl_DivW32W16ResW16(expPg32, chngQ); /* Q22/Q12=Q10 */ + + tmp16=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(kExp2,divVal,13);/* Q13*Q10>>13 => Q10*/ + if (tmp16<0) { + tmp16_2 = (0x0400 | (tmp16 & 0x03FF)); + tmp16_1 = (WEBRTC_SPL_RSHIFT_W16((WebRtc_UWord16)(tmp16 ^ 0xFFFF), 10)-3); /* Gives result in Q14 */ + if (tmp16_1<0) + expPg=(WebRtc_Word16) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1); + else + expPg=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1); + } else + expPg = (WebRtc_Word16) 16384; /* 1 in Q14, since 2^0=1 */ + + *varscale = expPg-1; + *oldEnergy = nrgQ[3]; +} + + + +static __inline WebRtc_Word16 exp2_Q10_T(WebRtc_Word16 x) { // Both in and out in Q10 + + WebRtc_Word16 tmp16_1, tmp16_2; + + tmp16_2=(WebRtc_Word16)(0x0400|(x&0x03FF)); + tmp16_1=-(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(x,10); + if(tmp16_1>0) + return (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1); + else + return (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1); + +} + + + + +void WebRtcIsacfix_GetLpcCoef(WebRtc_Word16 *inLoQ0, + WebRtc_Word16 *inHiQ0, + MaskFiltstr_enc *maskdata, + WebRtc_Word16 snrQ10, + const WebRtc_Word16 *pitchGains_Q12, + WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 *lo_coeffQ15, + WebRtc_Word16 *hi_coeffQ15) +{ + int k, n, j, ii; + WebRtc_Word16 pos1, pos2; + WebRtc_Word16 sh_lo, sh_hi, sh, ssh, shMem; + WebRtc_Word16 varscaleQ14; + + WebRtc_Word16 tmpQQlo, tmpQQhi; + WebRtc_Word32 tmp32; + WebRtc_Word16 tmp16,tmp16b; + + WebRtc_Word16 polyHI[ORDERHI+1]; + WebRtc_Word16 rcQ15_lo[ORDERLO], rcQ15_hi[ORDERHI]; + + + WebRtc_Word16 DataLoQ6[WINLEN], DataHiQ6[WINLEN]; + WebRtc_Word32 corrloQQ[ORDERLO+2]; + WebRtc_Word32 corrhiQQ[ORDERHI+1]; + WebRtc_Word32 corrlo2QQ[ORDERLO+1]; + WebRtc_Word16 scale; + WebRtc_Word16 QdomLO, QdomHI, newQdomHI, newQdomLO; + + WebRtc_Word32 round; + WebRtc_Word32 res_nrgQQ; + WebRtc_Word32 sqrt_nrg; + + WebRtc_Word32 aSQR32; + + /* less-noise-at-low-frequencies factor */ + WebRtc_Word16 aaQ14; + + /* Multiplication with 1/sqrt(12) ~= 0.28901734104046 can be done by convertion to + Q15, i.e. round(0.28901734104046*32768) = 9471, and use 9471/32768.0 ~= 0.289032 + */ + WebRtc_Word16 snrq, shft; + + WebRtc_Word16 tmp16a; + WebRtc_Word32 tmp32a, tmp32b, tmp32c; + + WebRtc_Word16 a_LOQ11[ORDERLO+1]; + WebRtc_Word16 k_vecloQ15[ORDERLO]; + WebRtc_Word16 a_HIQ12[ORDERHI+1]; + WebRtc_Word16 k_vechiQ15[ORDERHI]; + + WebRtc_Word16 stab; + + snrq=snrQ10; + + /* SNR= C * 2 ^ (D * snrq) ; C=0.289, D=0.05*log2(10)=0.166 (~=172 in Q10)*/ + tmp16 = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(snrq, 172, 10); // Q10 + tmp16b = exp2_Q10_T(tmp16); // Q10 + snrq = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(tmp16b, 285, 10); // Q10 + + /* change quallevel depending on pitch gains and level fluctuations */ + WebRtcIsacfix_GetVars(inLoQ0, pitchGains_Q12, &(maskdata->OldEnergy), &varscaleQ14); + + /* less-noise-at-low-frequencies factor */ + /* Calculation of 0.35 * (0.5 + 0.5 * varscale) in fixpoint: + With 0.35 in Q16 (0.35 ~= 22938/65536.0 = 0.3500061) and varscaleQ14 in Q14, + we get Q16*Q14>>16 = Q14 + */ + aaQ14 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32( + (WEBRTC_SPL_MUL_16_16(22938, (8192 + WEBRTC_SPL_RSHIFT_W32(varscaleQ14, 1))) + + ((WebRtc_Word32)32768)), 16); + + /* Calculate tmp = (1.0 + aa*aa); in Q12 */ + tmp16 = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(aaQ14, aaQ14, 15); //Q14*Q14>>15 = Q13 + tmpQQlo = 4096 + WEBRTC_SPL_RSHIFT_W16(tmp16, 1); // Q12 + Q13>>1 = Q12 + + /* Calculate tmp = (1.0+aa) * (1.0+aa); */ + tmp16 = 8192 + WEBRTC_SPL_RSHIFT_W16(aaQ14, 1); // 1+a in Q13 + tmpQQhi = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(tmp16, tmp16, 14); //Q13*Q13>>14 = Q12 + + /* replace data in buffer by new look-ahead data */ + for (pos1 = 0; pos1 < QLOOKAHEAD; pos1++) { + maskdata->DataBufferLoQ0[pos1 + WINLEN - QLOOKAHEAD] = inLoQ0[pos1]; + } + + for (k = 0; k < SUBFRAMES; k++) { + + /* Update input buffer and multiply signal with window */ + for (pos1 = 0; pos1 < WINLEN - UPDATE/2; pos1++) { + maskdata->DataBufferLoQ0[pos1] = maskdata->DataBufferLoQ0[pos1 + UPDATE/2]; + maskdata->DataBufferHiQ0[pos1] = maskdata->DataBufferHiQ0[pos1 + UPDATE/2]; + DataLoQ6[pos1] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT( + maskdata->DataBufferLoQ0[pos1], kWindowAutocorr[pos1], 15); // Q0*Q21>>15 = Q6 + DataHiQ6[pos1] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT( + maskdata->DataBufferHiQ0[pos1], kWindowAutocorr[pos1], 15); // Q0*Q21>>15 = Q6 + } + pos2 = (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16(k, UPDATE)/2); + for (n = 0; n < UPDATE/2; n++, pos1++) { + maskdata->DataBufferLoQ0[pos1] = inLoQ0[QLOOKAHEAD + pos2]; + maskdata->DataBufferHiQ0[pos1] = inHiQ0[pos2++]; + DataLoQ6[pos1] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT( + maskdata->DataBufferLoQ0[pos1], kWindowAutocorr[pos1], 15); // Q0*Q21>>15 = Q6 + DataHiQ6[pos1] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT( + maskdata->DataBufferHiQ0[pos1], kWindowAutocorr[pos1], 15); // Q0*Q21>>15 = Q6 + } + + /* Get correlation coefficients */ + /* The highest absolute value measured inside DataLo in the test set + For DataHi, corresponding value was 160. + + This means that it should be possible to represent the input values + to WebRtcSpl_AutoCorrelation() as Q6 values (since 307*2^6 = + 19648). Of course, Q0 will also work, but due to the low energy in + DataLo and DataHi, the outputted autocorrelation will be more accurate + and mimic the floating point code better, by being in an high as possible + Q-domain. + */ + + WebRtcIsacfix_AutocorrFix(corrloQQ,DataLoQ6,WINLEN, ORDERLO+1, &scale); + QdomLO = 12-scale; // QdomLO is the Q-domain of corrloQQ + sh_lo = WebRtcSpl_NormW32(corrloQQ[0]); + QdomLO += sh_lo; + for (ii=0; ii<ORDERLO+2; ii++) { + corrloQQ[ii] = WEBRTC_SPL_LSHIFT_W32(corrloQQ[ii], sh_lo); + } + /* It is investigated whether it was possible to use 16 bits for the + 32-bit vector corrloQQ, but it didn't work. */ + + WebRtcIsacfix_AutocorrFix(corrhiQQ,DataHiQ6,WINLEN, ORDERHI, &scale); + + QdomHI = 12-scale; // QdomHI is the Q-domain of corrhiQQ + sh_hi = WebRtcSpl_NormW32(corrhiQQ[0]); + QdomHI += sh_hi; + for (ii=0; ii<ORDERHI+1; ii++) { + corrhiQQ[ii] = WEBRTC_SPL_LSHIFT_W32(corrhiQQ[ii], sh_hi); + } + + /* less noise for lower frequencies, by filtering/scaling autocorrelation sequences */ + + /* Calculate corrlo2[0] = tmpQQlo * corrlo[0] - 2.0*tmpQQlo * corrlo[1];*/ + corrlo2QQ[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(tmpQQlo, corrloQQ[0]), 1)- // Q(12+QdomLO-16)>>1 = Q(QdomLO-5) + WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(aaQ14, corrloQQ[1]), 2); // 2*Q(14+QdomLO-16)>>3 = Q(QdomLO-2)>>2 = Q(QdomLO-5) + + /* Calculate corrlo2[n] = tmpQQlo * corrlo[n] - tmpQQlo * (corrlo[n-1] + corrlo[n+1]);*/ + for (n = 1; n <= ORDERLO; n++) { + + tmp32 = WEBRTC_SPL_RSHIFT_W32(corrloQQ[n-1], 1) + WEBRTC_SPL_RSHIFT_W32(corrloQQ[n+1], 1); // Q(QdomLO-1) + corrlo2QQ[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(tmpQQlo, corrloQQ[n]), 1)- // Q(12+QdomLO-16)>>1 = Q(QdomLO-5) + WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(aaQ14, tmp32), 2); // Q(14+QdomLO-1-16)>>2 = Q(QdomLO-3)>>2 = Q(QdomLO-5) + + } + QdomLO -= 5; + + /* Calculate corrhi[n] = tmpQQhi * corrhi[n]; */ + for (n = 0; n <= ORDERHI; n++) { + corrhiQQ[n] = WEBRTC_SPL_MUL_16_32_RSFT16(tmpQQhi, corrhiQQ[n]); // Q(12+QdomHI-16) = Q(QdomHI-4) + } + QdomHI -= 4; + + /* add white noise floor */ + /* corrlo2QQ is in Q(QdomLO) and corrhiQQ is in Q(QdomHI) */ + /* Calculate corrlo2[0] += 9.5367431640625e-7; and + corrhi[0] += 9.5367431640625e-7, where the constant is 1/2^20 */ + + tmp32 = WEBRTC_SPL_SHIFT_W32((WebRtc_Word32) 1, QdomLO-20); + corrlo2QQ[0] += tmp32; + tmp32 = WEBRTC_SPL_SHIFT_W32((WebRtc_Word32) 1, QdomHI-20); + corrhiQQ[0] += tmp32; + + /* corrlo2QQ is in Q(QdomLO) and corrhiQQ is in Q(QdomHI) before the following + code segment, where we want to make sure we get a 1-bit margin */ + for (n = 0; n <= ORDERLO; n++) { + corrlo2QQ[n] = WEBRTC_SPL_RSHIFT_W32(corrlo2QQ[n], 1); // Make sure we have a 1-bit margin + } + QdomLO -= 1; // Now, corrlo2QQ is in Q(QdomLO), with a 1-bit margin + + for (n = 0; n <= ORDERHI; n++) { + corrhiQQ[n] = WEBRTC_SPL_RSHIFT_W32(corrhiQQ[n], 1); // Make sure we have a 1-bit margin + } + QdomHI -= 1; // Now, corrhiQQ is in Q(QdomHI), with a 1-bit margin + + + newQdomLO = QdomLO; + + for (n = 0; n <= ORDERLO; n++) { + WebRtc_Word32 tmp, tmpB, tmpCorr; + WebRtc_Word16 alpha=328; //0.01 in Q15 + WebRtc_Word16 beta=324; //(1-0.01)*0.01=0.0099 in Q15 + WebRtc_Word16 gamma=32440; //(1-0.01)=0.99 in Q15 + + if (maskdata->CorrBufLoQQ[n] != 0) { + shMem=WebRtcSpl_NormW32(maskdata->CorrBufLoQQ[n]); + sh = QdomLO - maskdata->CorrBufLoQdom[n]; + if (sh<=shMem) { + tmp = WEBRTC_SPL_SHIFT_W32(maskdata->CorrBufLoQQ[n], sh); // Get CorrBufLoQQ to same domain as corrlo2 + tmp = WEBRTC_SPL_MUL_16_32_RSFT15(alpha, tmp); + } else if ((sh-shMem)<7){ + tmp = WEBRTC_SPL_SHIFT_W32(maskdata->CorrBufLoQQ[n], shMem); // Shift up CorrBufLoQQ as much as possible + tmp = WEBRTC_SPL_MUL_16_32_RSFT15(WEBRTC_SPL_LSHIFT_W16(alpha, (sh-shMem)), tmp); // Shift alpha the number of times required to get tmp in QdomLO + } else { + tmp = WEBRTC_SPL_SHIFT_W32(maskdata->CorrBufLoQQ[n], shMem); // Shift up CorrBufHiQQ as much as possible + tmp = WEBRTC_SPL_MUL_16_32_RSFT15(WEBRTC_SPL_LSHIFT_W16(alpha, 6), tmp); // Shift alpha as much as possible without overflow the number of times required to get tmp in QdomHI + tmpCorr = WEBRTC_SPL_RSHIFT_W32(corrloQQ[n], sh-shMem-6); + tmp = tmp + tmpCorr; + maskdata->CorrBufLoQQ[n] = tmp; + newQdomLO = QdomLO-(sh-shMem-6); + maskdata->CorrBufLoQdom[n] = newQdomLO; + } + } else + tmp = 0; + + tmp = tmp + corrlo2QQ[n]; + + maskdata->CorrBufLoQQ[n] = tmp; + maskdata->CorrBufLoQdom[n] = QdomLO; + + tmp=WEBRTC_SPL_MUL_16_32_RSFT15(beta, tmp); + tmpB=WEBRTC_SPL_MUL_16_32_RSFT15(gamma, corrlo2QQ[n]); + corrlo2QQ[n] = tmp + tmpB; + } + if( newQdomLO!=QdomLO) { + for (n = 0; n <= ORDERLO; n++) { + if (maskdata->CorrBufLoQdom[n] != newQdomLO) + corrloQQ[n] = WEBRTC_SPL_RSHIFT_W32(corrloQQ[n], maskdata->CorrBufLoQdom[n]-newQdomLO); + } + QdomLO = newQdomLO; + } + + + newQdomHI = QdomHI; + + for (n = 0; n <= ORDERHI; n++) { + WebRtc_Word32 tmp, tmpB, tmpCorr; + WebRtc_Word16 alpha=328; //0.01 in Q15 + WebRtc_Word16 beta=324; //(1-0.01)*0.01=0.0099 in Q15 + WebRtc_Word16 gamma=32440; //(1-0.01)=0.99 in Q1 + if (maskdata->CorrBufHiQQ[n] != 0) { + shMem=WebRtcSpl_NormW32(maskdata->CorrBufHiQQ[n]); + sh = QdomHI - maskdata->CorrBufHiQdom[n]; + if (sh<=shMem) { + tmp = WEBRTC_SPL_SHIFT_W32(maskdata->CorrBufHiQQ[n], sh); // Get CorrBufHiQQ to same domain as corrhi + tmp = WEBRTC_SPL_MUL_16_32_RSFT15(alpha, tmp); + tmpCorr = corrhiQQ[n]; + tmp = tmp + tmpCorr; + maskdata->CorrBufHiQQ[n] = tmp; + maskdata->CorrBufHiQdom[n] = QdomHI; + } else if ((sh-shMem)<7) { + tmp = WEBRTC_SPL_SHIFT_W32(maskdata->CorrBufHiQQ[n], shMem); // Shift up CorrBufHiQQ as much as possible + tmp = WEBRTC_SPL_MUL_16_32_RSFT15(WEBRTC_SPL_LSHIFT_W16(alpha, (sh-shMem)), tmp); // Shift alpha the number of times required to get tmp in QdomHI + tmpCorr = corrhiQQ[n]; + tmp = tmp + tmpCorr; + maskdata->CorrBufHiQQ[n] = tmp; + maskdata->CorrBufHiQdom[n] = QdomHI; + } else { + tmp = WEBRTC_SPL_SHIFT_W32(maskdata->CorrBufHiQQ[n], shMem); // Shift up CorrBufHiQQ as much as possible + tmp = WEBRTC_SPL_MUL_16_32_RSFT15(WEBRTC_SPL_LSHIFT_W16(alpha, 6), tmp); // Shift alpha as much as possible without overflow the number of times required to get tmp in QdomHI + tmpCorr = WEBRTC_SPL_RSHIFT_W32(corrhiQQ[n], sh-shMem-6); + tmp = tmp + tmpCorr; + maskdata->CorrBufHiQQ[n] = tmp; + newQdomHI = QdomHI-(sh-shMem-6); + maskdata->CorrBufHiQdom[n] = newQdomHI; + } + } else { + tmp = corrhiQQ[n]; + tmpCorr = tmp; + maskdata->CorrBufHiQQ[n] = tmp; + maskdata->CorrBufHiQdom[n] = QdomHI; + } + + tmp=WEBRTC_SPL_MUL_16_32_RSFT15(beta, tmp); + tmpB=WEBRTC_SPL_MUL_16_32_RSFT15(gamma, tmpCorr); + corrhiQQ[n] = tmp + tmpB; + } + + if( newQdomHI!=QdomHI) { + for (n = 0; n <= ORDERHI; n++) { + if (maskdata->CorrBufHiQdom[n] != newQdomHI) + corrhiQQ[n] = WEBRTC_SPL_RSHIFT_W32(corrhiQQ[n], maskdata->CorrBufHiQdom[n]-newQdomHI); + } + QdomHI = newQdomHI; + } + + stab=WebRtcSpl_LevinsonW32_JSK(corrlo2QQ, a_LOQ11, k_vecloQ15, ORDERLO); + + if (stab<0) { // If unstable use lower order + a_LOQ11[0]=2048; + for (n = 1; n <= ORDERLO; n++) { + a_LOQ11[n]=0; + } + + stab=WebRtcSpl_LevinsonW32_JSK(corrlo2QQ, a_LOQ11, k_vecloQ15, 8); + } + + + WebRtcSpl_LevinsonDurbin(corrhiQQ, a_HIQ12, k_vechiQ15, ORDERHI); + + /* bandwidth expansion */ + for (n = 1; n <= ORDERLO; n++) { + a_LOQ11[n] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT_WITH_FIXROUND(kPolyVecLo[n-1], a_LOQ11[n]); + } + + + polyHI[0] = a_HIQ12[0]; + for (n = 1; n <= ORDERHI; n++) { + a_HIQ12[n] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT_WITH_FIXROUND(kPolyVecHi[n-1], a_HIQ12[n]); + polyHI[n] = a_HIQ12[n]; + } + + /* Normalize the corrlo2 vector */ + sh = WebRtcSpl_NormW32(corrlo2QQ[0]); + for (n = 0; n <= ORDERLO; n++) { + corrlo2QQ[n] = WEBRTC_SPL_LSHIFT_W32(corrlo2QQ[n], sh); + } + QdomLO += sh; /* Now, corrlo2QQ is still in Q(QdomLO) */ + + + /* residual energy */ + + sh_lo = 31; + res_nrgQQ = 0; + for (j = 0; j <= ORDERLO; j++) + { + for (n = 0; n < j; n++) + { + WebRtc_Word16 index, diff, sh_corr; + + index = j - n; //WEBRTC_SPL_ABS_W16(j-n); + + /* Calculation of res_nrg += a_LO[j] * corrlo2[j-n] * a_LO[n]; */ + /* corrlo2QQ is in Q(QdomLO) */ + tmp32 = ((WebRtc_Word32) WEBRTC_SPL_MUL_16_16(a_LOQ11[j], a_LOQ11[n])); // Q11*Q11 = Q22 + // multiply by 2 as loop only on half of the matrix. a_LOQ11 gone through bandwidth + // expation so the following shift is safe. + tmp32 = WEBRTC_SPL_LSHIFT_W32(tmp32, 1); + sh = WebRtcSpl_NormW32(tmp32); + aSQR32 = WEBRTC_SPL_LSHIFT_W32(tmp32, sh); // Q(22+sh) + sh_corr = WebRtcSpl_NormW32(corrlo2QQ[index]); + tmp32 = WEBRTC_SPL_LSHIFT_W32(corrlo2QQ[index], sh_corr); + tmp32 = (WebRtc_Word32) WEBRTC_SPL_MUL_32_32_RSFT32BI(aSQR32, tmp32); // Q(22+sh)*Q(QdomLO+sh_corr)>>32 = Q(22+sh+QdomLO+sh_corr-32) = Q(sh+QdomLO+sh_corr-10) + sh = sh+QdomLO+sh_corr-10; + + diff = sh_lo-sh; + + round = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, (WEBRTC_SPL_ABS_W32(diff)-1)); + if (diff==0) + round = 0; + if (diff>=31) { + res_nrgQQ = tmp32; + sh_lo = sh; + } else if (diff>0) { + res_nrgQQ = WEBRTC_SPL_RSHIFT_W32((res_nrgQQ+round), (diff+1)) + WEBRTC_SPL_RSHIFT_W32(tmp32, 1); + sh_lo = sh-1; + } else if (diff>-31){ + res_nrgQQ = WEBRTC_SPL_RSHIFT_W32(res_nrgQQ, 1) + WEBRTC_SPL_SHIFT_W32((tmp32+round), -(-diff+1)); + sh_lo = sh_lo-1; + } + sh = WebRtcSpl_NormW32(res_nrgQQ); + res_nrgQQ = WEBRTC_SPL_LSHIFT_W32(res_nrgQQ, sh); + sh_lo += sh; + } + n = j; + { + WebRtc_Word16 index, diff, sh_corr; + + index = 0; //WEBRTC_SPL_ABS_W16(j-n); + + /* Calculation of res_nrg += a_LO[j] * corrlo2[j-n] * a_LO[n]; */ + /* corrlo2QQ is in Q(QdomLO) */ + tmp32 = (WebRtc_Word32) WEBRTC_SPL_MUL_16_16(a_LOQ11[j], a_LOQ11[n]); // Q11*Q11 = Q22 + sh = WebRtcSpl_NormW32(tmp32); + aSQR32 = WEBRTC_SPL_LSHIFT_W32(tmp32, sh); // Q(22+sh) + sh_corr = WebRtcSpl_NormW32(corrlo2QQ[index]); + tmp32 = WEBRTC_SPL_LSHIFT_W32(corrlo2QQ[index], sh_corr); + tmp32 = (WebRtc_Word32) WEBRTC_SPL_MUL_32_32_RSFT32BI(aSQR32, tmp32); // Q(22+sh)*Q(QdomLO+sh_corr)>>32 = Q(22+sh+QdomLO+sh_corr-32) = Q(sh+QdomLO+sh_corr-10) + sh = sh+QdomLO+sh_corr-10; + diff = sh_lo-sh; + + round = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, (WEBRTC_SPL_ABS_W32(diff)-1)); + if (diff==0) + round = 0; + if (diff>=31) { + res_nrgQQ = tmp32; + sh_lo = sh; + } else if (diff>0) { + res_nrgQQ = WEBRTC_SPL_RSHIFT_W32((res_nrgQQ+round), (diff+1)) + WEBRTC_SPL_RSHIFT_W32(tmp32, 1); + sh_lo = sh-1; + } else if (diff>-31){ + res_nrgQQ = WEBRTC_SPL_RSHIFT_W32(res_nrgQQ, 1) + WEBRTC_SPL_SHIFT_W32((tmp32+round), -(-diff+1)); + sh_lo = sh_lo-1; + } + sh = WebRtcSpl_NormW32(res_nrgQQ); + res_nrgQQ = WEBRTC_SPL_LSHIFT_W32(res_nrgQQ, sh); + sh_lo += sh; + } + } + /* Convert to reflection coefficients */ + + + WebRtcSpl_AToK_JSK(a_LOQ11, ORDERLO, rcQ15_lo); + + if (sh_lo & 0x0001) { + res_nrgQQ=WEBRTC_SPL_RSHIFT_W32(res_nrgQQ, 1); + sh_lo-=1; + } + + + if( res_nrgQQ > 0 ) + { + sqrt_nrg=WebRtcSpl_Sqrt(res_nrgQQ); + + /* add hearing threshold and compute the gain */ + /* lo_coeff = varscale * S_N_R / (sqrt_nrg + varscale * H_T_H); */ + + + //tmp32a=WEBRTC_SPL_MUL_16_16_RSFT(varscaleQ14, H_T_HQ19, 17); // Q14 + tmp32a=WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32) varscaleQ14,1); // H_T_HQ19=65536 (16-17=-1) ssh= WEBRTC_SPL_RSHIFT_W16(sh_lo, 1); // sqrt_nrg is in Qssh + ssh= WEBRTC_SPL_RSHIFT_W16(sh_lo, 1); // sqrt_nrg is in Qssh + sh = ssh - 14; + tmp32b = WEBRTC_SPL_SHIFT_W32(tmp32a, sh); // Q14->Qssh + tmp32c = sqrt_nrg + tmp32b; // Qssh (denominator) + tmp32a = WEBRTC_SPL_MUL_16_16_RSFT(varscaleQ14, snrq, 0); //Q24 (numerator) + + sh = WebRtcSpl_NormW32(tmp32c); + shft = 16 - sh; + tmp16a = (WebRtc_Word16) WEBRTC_SPL_SHIFT_W32(tmp32c, -shft); // Q(ssh-shft) (denominator) + + tmp32b = WebRtcSpl_DivW32W16(tmp32a, tmp16a); // Q(24-ssh+shft) + sh = ssh-shft-7; + *gain_lo_hiQ17 = WEBRTC_SPL_SHIFT_W32(tmp32b, sh); // Gains in Q17 + } + else + { + *gain_lo_hiQ17 = 100; //(WebRtc_Word32)WEBRTC_SPL_LSHIFT_W32( (WebRtc_Word32)1, 17); // Gains in Q17 + } + gain_lo_hiQ17++; + + /* copy coefficients to output array */ + for (n = 0; n < ORDERLO; n++) { + *lo_coeffQ15 = (WebRtc_Word16) (rcQ15_lo[n]); + lo_coeffQ15++; + } + /* residual energy */ + res_nrgQQ = 0; + sh_hi = 31; + + + for (j = 0; j <= ORDERHI; j++) + { + for (n = 0; n < j; n++) + { + WebRtc_Word16 index, diff, sh_corr; + + index = j-n; //WEBRTC_SPL_ABS_W16(j-n); + + /* Calculation of res_nrg += a_HI[j] * corrhi[j-n] * a_HI[n] * 2; for j != n */ + /* corrhiQQ is in Q(QdomHI) */ + tmp32 = ((WebRtc_Word32) WEBRTC_SPL_MUL_16_16(a_HIQ12[j], a_HIQ12[n])); // Q12*Q12 = Q24 + tmp32 = WEBRTC_SPL_LSHIFT_W32(tmp32, 1); + sh = WebRtcSpl_NormW32(tmp32); + aSQR32 = WEBRTC_SPL_LSHIFT_W32(tmp32, sh); // Q(24+sh) + sh_corr = WebRtcSpl_NormW32(corrhiQQ[index]); + tmp32 = WEBRTC_SPL_LSHIFT_W32(corrhiQQ[index],sh_corr); + tmp32 = (WebRtc_Word32) WEBRTC_SPL_MUL_32_32_RSFT32BI(aSQR32, tmp32); // Q(24+sh)*Q(QdomHI+sh_corr)>>32 = Q(24+sh+QdomHI+sh_corr-32) = Q(sh+QdomHI+sh_corr-8) + sh = sh+QdomHI+sh_corr-8; + diff = sh_hi-sh; + + round = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, (WEBRTC_SPL_ABS_W32(diff)-1)); + if (diff==0) + round = 0; + if (diff>=31) { + res_nrgQQ = tmp32; + sh_hi = sh; + } else if (diff>0) { + res_nrgQQ = WEBRTC_SPL_RSHIFT_W32((res_nrgQQ+round), (diff+1)) + WEBRTC_SPL_RSHIFT_W32(tmp32, 1); + sh_hi = sh-1; + } else if (diff>-31){ + res_nrgQQ = WEBRTC_SPL_RSHIFT_W32(res_nrgQQ, 1) + WEBRTC_SPL_SHIFT_W32((tmp32+round), -(-diff+1)); + sh_hi = sh_hi-1; + } + + sh = WebRtcSpl_NormW32(res_nrgQQ); + res_nrgQQ = WEBRTC_SPL_LSHIFT_W32(res_nrgQQ, sh); + sh_hi += sh; + } + + n = j; + { + WebRtc_Word16 index, diff, sh_corr; + + index = 0; //n-j; //WEBRTC_SPL_ABS_W16(j-n); + + /* Calculation of res_nrg += a_HI[j] * corrhi[j-n] * a_HI[n];*/ + /* corrhiQQ is in Q(QdomHI) */ + tmp32 = ((WebRtc_Word32) WEBRTC_SPL_MUL_16_16(a_HIQ12[j], a_HIQ12[n])); // Q12*Q12 = Q24 + sh = WebRtcSpl_NormW32(tmp32); + aSQR32 = WEBRTC_SPL_LSHIFT_W32(tmp32, sh); // Q(24+sh) + sh_corr = WebRtcSpl_NormW32(corrhiQQ[index]); + tmp32 = WEBRTC_SPL_LSHIFT_W32(corrhiQQ[index],sh_corr); + tmp32 = (WebRtc_Word32) WEBRTC_SPL_MUL_32_32_RSFT32BI(aSQR32, tmp32); // Q(24+sh)*Q(QdomHI+sh_corr)>>32 = Q(24+sh+QdomHI+sh_corr-32) = Q(sh+QdomHI+sh_corr-8) + sh = sh+QdomHI+sh_corr-8; + diff = sh_hi-sh; + + round = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, (WEBRTC_SPL_ABS_W32(diff)-1)); + if (diff==0) + round = 0; + if (diff>=31) { + res_nrgQQ = tmp32; + sh_hi = sh; + } else if (diff>0) { + res_nrgQQ = WEBRTC_SPL_RSHIFT_W32((res_nrgQQ+round), (diff+1)) + WEBRTC_SPL_RSHIFT_W32(tmp32, 1); + sh_hi = sh-1; + } else if (diff>-31){ + res_nrgQQ = WEBRTC_SPL_RSHIFT_W32(res_nrgQQ, 1) + WEBRTC_SPL_SHIFT_W32((tmp32+round), -(-diff+1)); + sh_hi = sh_hi-1; + } + + sh = WebRtcSpl_NormW32(res_nrgQQ); + res_nrgQQ = WEBRTC_SPL_LSHIFT_W32(res_nrgQQ, sh); + sh_hi += sh; + } + } + + /* Convert to reflection coefficients */ + WebRtcSpl_LpcToReflCoef(polyHI, ORDERHI, rcQ15_hi); + + if (sh_hi & 0x0001) { + res_nrgQQ=WEBRTC_SPL_RSHIFT_W32(res_nrgQQ, 1); + sh_hi-=1; + } + + + if( res_nrgQQ > 0 ) + { + sqrt_nrg=WebRtcSpl_Sqrt(res_nrgQQ); + + + /* add hearing threshold and compute the gain */ + /* hi_coeff = varscale * S_N_R / (sqrt_nrg + varscale * H_T_H); */ + + //tmp32a=WEBRTC_SPL_MUL_16_16_RSFT(varscaleQ14, H_T_HQ19, 17); // Q14 + tmp32a=WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32) varscaleQ14,1); // H_T_HQ19=65536 (16-17=-1) + + ssh= WEBRTC_SPL_RSHIFT_W32(sh_hi, 1); // sqrt_nrg is in Qssh + sh = ssh - 14; + tmp32b = WEBRTC_SPL_SHIFT_W32(tmp32a, sh); // Q14->Qssh + tmp32c = sqrt_nrg + tmp32b; // Qssh (denominator) + tmp32a = WEBRTC_SPL_MUL_16_16_RSFT(varscaleQ14, snrq, 0); //Q24 (numerator) + + sh = WebRtcSpl_NormW32(tmp32c); + shft = 16 - sh; + tmp16a = (WebRtc_Word16) WEBRTC_SPL_SHIFT_W32(tmp32c, -shft); // Q(ssh-shft) (denominator) + + tmp32b = WebRtcSpl_DivW32W16(tmp32a, tmp16a); // Q(24-ssh+shft) + sh = ssh-shft-7; + *gain_lo_hiQ17 = WEBRTC_SPL_SHIFT_W32(tmp32b, sh); // Gains in Q17 + } + else + { + *gain_lo_hiQ17 = 100; //(WebRtc_Word32)WEBRTC_SPL_LSHIFT_W32( (WebRtc_Word32)1, 17); // Gains in Q17 + } + gain_lo_hiQ17++; + + + /* copy coefficients to output array */ + for (n = 0; n < ORDERHI; n++) { + *hi_coeffQ15 = rcQ15_hi[n]; + hi_coeffQ15++; + } + } +} diff --git a/src/libs/webrtc/isac/lpc_masking_model.h b/src/libs/webrtc/isac/lpc_masking_model.h new file mode 100644 index 00000000..9a64844b --- /dev/null +++ b/src/libs/webrtc/isac/lpc_masking_model.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * lpc_masking_model.h + * + * LPC functions + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_MASKING_MODEL_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_MASKING_MODEL_H_ + +#include "structs.h" + +void WebRtcIsacfix_GetVars(const WebRtc_Word16 *input, + const WebRtc_Word16 *pitchGains_Q12, + WebRtc_UWord32 *oldEnergy, + WebRtc_Word16 *varscale); + +void WebRtcIsacfix_GetLpcCoef(WebRtc_Word16 *inLoQ0, + WebRtc_Word16 *inHiQ0, + MaskFiltstr_enc *maskdata, + WebRtc_Word16 snrQ10, + const WebRtc_Word16 *pitchGains_Q12, + WebRtc_Word32 *gain_lo_hiQ17, + WebRtc_Word16 *lo_coeffQ15, + WebRtc_Word16 *hi_coeffQ15); + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_MASKING_MODEL_H_ */ diff --git a/src/libs/webrtc/isac/lpc_tables.c b/src/libs/webrtc/isac/lpc_tables.c new file mode 100644 index 00000000..90cc9af4 --- /dev/null +++ b/src/libs/webrtc/isac/lpc_tables.c @@ -0,0 +1,1280 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * lpc_tables.c + * + * Coding tables for the KLT coefficients + * + */ + + +#include "settings.h" +#include "lpc_tables.h" + +/* indices of KLT coefficients used */ +const WebRtc_UWord16 WebRtcIsacfix_kSelIndGain[12] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11}; + +const WebRtc_UWord16 WebRtcIsacfix_kSelIndShape[108] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107 +}; + +/* cdf array for model indicator */ +const WebRtc_UWord16 WebRtcIsacfix_kModelCdf[4] = { + 0, 15434, 37548, 65535 +}; + +/* pointer to cdf array for model indicator */ +const WebRtc_UWord16 *WebRtcIsacfix_kModelCdfPtr[1] = { + WebRtcIsacfix_kModelCdf +}; + +/* initial cdf index for decoder of model indicator */ +const WebRtc_UWord16 WebRtcIsacfix_kModelInitIndex[1] = { + 1 +}; + +/* offset to go from rounded value to quantization index */ +const WebRtc_Word16 WebRtcIsacfix_kQuantMinGain[12] ={ + 3, 6, 4, 6, 6, 9, 5, 16, 11, 34, 32, 47 +}; + +const WebRtc_Word16 WebRtcIsacfix_kQuantMinShape[108] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 2, 2, 2, 3, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 2, 2, 3, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 4, 3, 5, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 2, 1, 2, 2, 3, 4, + 4, 7, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 2, 3, 2, 3, 4, 4, 5, 7, 13, + 0, 1, 1, 2, 3, 2, 2, 2, 4, 4, + 5, 6, 7, 11, 9, 13, 12, 26 +}; + +/* maximum quantization index */ +const WebRtc_UWord16 WebRtcIsacfix_kMaxIndGain[12] = { + 6, 12, 8, 14, 10, 19, 12, 31, 22, 56, 52, 138 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kMaxIndShape[108] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 2, 2, 2, 2, 4, 4, 5, 6, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, 2, 2, + 2, 2, 3, 4, 5, 7, 0, 0, 0, 0, + 2, 0, 2, 2, 2, 2, 3, 2, 2, 4, + 4, 6, 6, 9, 0, 0, 0, 0, 2, 2, + 2, 2, 2, 2, 3, 2, 4, 4, 7, 7, + 9, 13, 0, 0, 2, 2, 2, 2, 2, 2, + 3, 4, 5, 4, 6, 8, 8, 10, 16, 25, + 0, 2, 2, 4, 5, 4, 4, 4, 7, 8, + 9, 10, 13, 19, 17, 23, 25, 49 +}; + +/* index offset */ +const WebRtc_UWord16 WebRtcIsacfix_kOffsetGain[3][12] = { + { 0, 7, 20, 29, 44, 55, 75, 88, 120, 143, 200, 253}, + { 0, 7, 19, 27, 42, 53, 73, 86, 117, 140, 197, 249}, + { 0, 7, 20, 28, 44, 55, 75, 89, 121, 145, 202, 257} +}; + +const WebRtc_UWord16 WebRtcIsacfix_kOffsetShape[3][108] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 11, 14, 17, 20, 23, 28, 33, 39, 46, 47, + 48, 49, 50, 52, 53, 54, 55, 56, 58, 61, + 64, 67, 70, 74, 79, 85, 93, 94, 95, 96, + 97, 100, 101, 104, 107, 110, 113, 117, 120, 123, + 128, 133, 140, 147, 157, 158, 159, 160, 161, 164, + 167, 170, 173, 176, 179, 183, 186, 191, 196, 204, + 212, 222, 236, 237, 238, 241, 244, 247, 250, 253, + 256, 260, 265, 271, 276, 283, 292, 301, 312, 329, + 355, 356, 359, 362, 367, 373, 378, 383, 388, 396, + 405, 415, 426, 440, 460, 478, 502, 528 + }, + { + 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, + 13, 16, 19, 22, 26, 29, 34, 39, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 55, 57, 60, + 63, 66, 70, 73, 78, 84, 91, 92, 93, 94, + 95, 96, 97, 99, 102, 105, 108, 111, 114, 118, + 123, 128, 134, 141, 151, 152, 153, 154, 156, 159, + 162, 165, 168, 171, 174, 177, 181, 186, 194, 200, + 208, 218, 233, 234, 235, 236, 239, 242, 245, 248, + 251, 254, 258, 263, 270, 277, 288, 297, 308, 324, + 349, 351, 354, 357, 361, 366, 372, 378, 383, 390, + 398, 407, 420, 431, 450, 472, 496, 524 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, + 14, 17, 20, 23, 26, 29, 34, 40, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 58, 61, 64, + 67, 70, 73, 77, 82, 88, 96, 97, 98, 99, + 101, 102, 104, 107, 110, 113, 116, 119, 122, 125, + 129, 134, 141, 150, 160, 161, 162, 163, 166, 168, + 171, 174, 177, 180, 183, 186, 190, 195, 201, 208, + 216, 226, 243, 244, 245, 248, 251, 254, 257, 260, + 263, 268, 273, 278, 284, 291, 299, 310, 323, 340, + 366, 368, 371, 374, 379, 383, 389, 394, 399, 406, + 414, 422, 433, 445, 461, 480, 505, 533 + } +}; + +/* initial cdf index for KLT coefficients */ +const WebRtc_UWord16 WebRtcIsacfix_kInitIndexGain[3][12] = { + { 3, 6, 4, 7, 5, 10, 6, 16, 11, 28, 26, 69}, + { 3, 6, 4, 7, 5, 10, 6, 15, 11, 28, 26, 69}, + { 3, 6, 4, 8, 5, 10, 7, 16, 12, 28, 27, 70} +}; + +const WebRtc_UWord16 WebRtcIsacfix_kInitIndexShape[3][108] = { + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 2, 2, 3, 3, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 2, 2, 3, 4, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 1, 2, 1, 1, 2, + 2, 3, 3, 5, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 2, 1, 2, 2, 4, 4, + 5, 7, 0, 0, 1, 1, 1, 1, 1, 1, + 2, 2, 3, 2, 3, 4, 4, 5, 8, 13, + 0, 1, 1, 2, 3, 2, 2, 2, 4, 4, + 5, 5, 7, 10, 9, 12, 13, 25 + }, + { + 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 1, 1, 1, 2, 1, 2, 2, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 2, 1, 2, 3, 3, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, + 2, 3, 3, 5, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 2, 4, 3, 4, + 5, 7, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 2, 2, 3, 3, 5, 4, 5, 8, 12, + 1, 1, 1, 2, 2, 3, 3, 2, 3, 4, + 4, 6, 5, 9, 11, 12, 14, 25 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 2, 3, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 2, 2, 3, 4, 0, 0, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 3, 4, 5, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 2, 3, 3, 4, + 5, 8, 0, 0, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 3, 3, 4, 5, 6, 8, 13, + 1, 1, 1, 2, 2, 3, 2, 2, 3, 4, + 4, 5, 6, 8, 9, 12, 14, 25 + } +}; + +/* offsets for quantizer representation levels*/ +const WebRtc_UWord16 WebRtcIsacfix_kOfLevelsGain[3] = { + 0, 392, 779 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kOfLevelsShape[3] = { + 0, 578, 1152 +}; + +/* quantizer representation levels */ + + + +const WebRtc_Word32 WebRtcIsacfix_kLevelsGainQ17[1176] = { + -364547,-231664,-102123,-573,104807,238257,368823,-758583,-640135,-510291 + ,-377662,-252785,-113177,2627,112906,248601,389461,522691,644517,763974 + ,-538963,-368179,-245823,-106095,-890,104299,241111,350730,493190,-800763 + ,-646230,-510239,-382115,-248623,-111829,-2983,113852,251105,388114,519757 + ,644048,774712,896334,1057931,-770009,-635310,-503690,-375087,-248106,-108525 + ,-105,108259,243472,377948,519271,-1160885,-1032044,-914636,-777593,-647891 + ,-518408,-388028,-254321,-115293,-598,117849,251296,385367,515510,652727 + ,777432,920363,1038625,1153637,1316836,-632287,-505430,-379430,-248458,-118013 + ,-888,118762,250266,381650,513327,652169,766471,932113,-2107480,-1971030 + ,-1827020,-1698263,-1558670,-1436314,-1305377,-1172252,-1047355,-914202,-779651,-651001 + ,-520999,-390394,-255761,-123490,-1893,126839,256703,385493,518607,651760 + ,782750,908693,1044131,1163865,1311066,1424177,1582628,1709823,1831740,1955391 + ,-1423044,-1288917,-1181281,-1043222,-911770,-780354,-646799,-522664,-386721,-258266 + ,-128060,-1101,128233,259996,390336,519590,649290,778701,908010,1040796 + ,1161235,1306889,1441882,-4446002,-4301031,-4194304,-4080591,-3947740,-3808975,-3686530 + ,-3567839,-3383251,-3287089,-3136577,-3017405,-2869860,-2751321,-2619984,-2482932,-2354790 + ,-2223147,-2090669,-1964135,-1831208,-1706697,-1570817,-1446008,-1305386,-1175773,-1046066 + ,-915356,-785120,-653614,-524331,-393767,-260442,-130187,-799,128841,261466 + ,393616,520542,652117,784613,914159,1045399,1181072,1308971,1442502,1570346 + ,1693912,1843986,1966014,2090474,2224869,2364593,2475934,2628403,2752512,2856640 + ,-4192441,-4063232,-3917821,-3799195,-3666233,-3519199,-3411021,-3269192,-3135684,-3008826 + ,-2880875,-2747342,-2620981,-2494872,-2354979,-2229718,-2098939,-1964971,-1835399,-1703452 + ,-1572806,-1440482,-1311794,-1179338,-1046521,-919823,-785914,-655335,-523416,-395507 + ,-264833,-132184,-2546,131698,256217,391372,522688,651248,789964,909618 + ,1035305,1179145,1313824,1436934,1552353,1693722,1815508,1972826,2096328,2228224 + ,2359296,2490368,2598848,-6160384,-6029312,-5881382,-5767168,-5636096,-5505024,-5373952 + ,-5228418,-5110384,-4954923,-4880576,-4710990,-4587364,-4471340,-4333905,-4211513,-4051293 + ,-3907927,-3800105,-3675961,-3538640,-3413663,-3271148,-3152105,-3019103,-2869647,-2744015 + ,-2620639,-2479385,-2364211,-2227611,-2095427,-1974497,-1834168,-1703561,-1568961,-1439826 + ,-1309192,-1174050,-1050191,-917836,-786015,-656943,-518934,-394831,-257708,-128041 + ,1610,128991,264442,393977,521383,653849,788164,918641,1049122,1181971 + ,1308934,1439505,1571808,1706305,1836318,1966235,2097269,2228990,2357005,2490292 + ,2617400,2749680,2881234,3014880,3145637,3276467,3409099,3536637,3671493,3802918 + ,3929740,4065036,4194143,4325999,4456126,4586857,4717194,4843923,4978676,5110913 + ,5245281,5371394,5499780,5633779,5762611,5897682,6028688,6167546,6296465,6421682 + ,6548882,6682074,6809432,6941956,7078143,7204509,7334296,7475137,7609896,7732044 + ,7861604,8002039,8131670,8259222,8390299,8522399,8650037,8782348,8908402,9037815 + ,9164594,9300338,9434679,9574500,9699702,9833934,9948152,10083972,10244937,10332822 + ,10485760,10600122,10760754,10892964,11010048,11111004,11272192,11403264,11525091,11624984 + ,11796480,11915146,-393216,-262144,-101702,-740,100568,262144,393216,-786432 + ,-655360,-524288,-383907,-243301,-94956,-156,95547,269629,416691,524288 + ,655360,-393216,-262144,-88448,-37,87318,262144,393216,524288,-917504 + ,-786432,-655360,-495894,-373308,-267503,-93211,4119,91308,250895,393216 + ,526138,655360,786432,917504,-786432,-655360,-524288,-393216,-262144,-83497 + ,222,86893,240922,393216,524288,-1048576,-917504,-790472,-655360,-508639 + ,-383609,-262016,-95550,-3775,96692,256797,364847,534906,655360,786432 + ,889679,1048576,1179648,1310720,1441792,-655360,-524288,-377684,-248408,-93690 + ,1261,95441,227519,393216,524288,655360,786432,917504,-2097152,-1966080 + ,-1809470,-1703936,-1572864,-1441792,-1314289,-1195149,-1056205,-917504,-809951,-657769 + ,-521072,-383788,-248747,-106350,-2944,105550,243408,388548,521064,628732 + ,786432,885456,1064548,1179648,1310720,1441792,1572864,1703936,1835008,-1441792 + ,-1310720,-1179648,-1037570,-888492,-767774,-646634,-519935,-373458,-248029,-111915 + ,760,111232,247735,379432,507672,672699,786432,917504,1048576,1179648 + ,1310720,1441792,-4456448,-4325376,-4194304,-4063232,-3932160,-3801088,-3670016,-3538944 + ,-3407872,-3276800,-3145728,-3014656,-2883584,-2752512,-2647002,-2490368,-2359296,-2228224 + ,-2097152,-1951753,-1835008,-1703936,-1594177,-1462001,-1289150,-1160774,-1025917,-924928 + ,-782509,-641294,-516191,-386630,-251910,-118886,5210,121226,253949,386008 + ,517973,649374,780064,917783,1052462,1183856,1290593,1419389,1556641,1699884 + ,1835008,1988314,2090470,2228224,2359296,2490368,2621440,2752512,2883584,-3801088 + ,-3643514,-3539937,-3409931,-3263294,-3145658,-3012952,-2879230,-2752359,-2622556,-2483471 + ,-2357556,-2226500,-2093112,-1965892,-1833664,-1701035,-1567767,-1440320,-1310556,-1178339 + ,-1049625,-916812,-786477,-655277,-525050,-393773,-264828,-130696,-480,132126 + ,260116,394197,527846,652294,785563,917183,1049511,1175958,1308161,1438759 + ,1572253,1698835,1828535,1967072,2089391,2212798,2348901,2461547,2621440,2752512 + ,2883584,-7309870,-7203780,-7062699,-6939106,-6790819,-6672036,-6553600,-6422317,-6288422 + ,-6164694,-6026456,-5901410,-5754168,-5621459,-5502710,-5369686,-5240454,-5120712,-4976140 + ,-4847970,-4723070,-4589083,-4450923,-4324680,-4189892,-4065551,-3931803,-3800209,-3668539 + ,-3539395,-3404801,-3277470,-3141389,-3016710,-2885724,-2752612,-2618541,-2486762,-2354153 + ,-2225059,-2094984,-1968194,-1830895,-1699508,-1575743,-1444516,-1308683,-1179714,-1053088 + ,-917981,-783707,-653900,-524980,-395409,-260309,-131948,-3452,132113,263241 + ,392185,522597,654134,788288,919810,1045795,1179210,1314201,1444235,1574447 + ,1705193,1834009,1967332,2098102,2229019,2359147,2489859,2619878,2754966,2879671 + ,3014438,3146143,3276733,3405958,3542196,3667493,3798815,3932961,4062458,4187125 + ,4322346,4454875,4587752,4716809,4848274,4975027,5111957,5242215,5373085,5501158 + ,5640140,5762918,5895358,6024008,6157906,6290628,6422713,6546339,6675888,6815606 + ,6955288,7077501,7211630,7337893,7473635,7607175,7728310,7866475,7999658,8127888 + ,8241758,8386483,8522550,8641582,8771915,8922139,9038632,9179385,9313426,9437184 + ,9568256,9699328,9830400,9952933,10120004,10223616,10354688,10474645,10616832,-393216 + ,-262144,-85425,-121,82533,262144,393216,-786432,-655360,-524288,-379928 + ,-222821,-95200,287,95541,227093,393216,493567,655360,786432,-393216 + ,-262144,-86805,510,86722,262144,393216,524288,-1048576,-917504,-786432 + ,-624456,-529951,-395071,-241627,-101168,81,99975,241605,393216,524288 + ,655360,786432,917504,-786432,-655360,-524288,-393216,-230359,-95619,-137 + ,94425,226222,393216,524288,-1179648,-1048576,-917504,-773841,-655360,-492258 + ,-379715,-244707,-103621,-434,104523,242680,381575,523659,650565,786432 + ,917504,1048576,1179648,1310720,-786432,-629344,-524288,-376757,-242858,-101932 + ,-2715,107155,239212,366480,514943,655360,786432,917504,-2228224,-2097152 + ,-1966080,-1835008,-1703936,-1572864,-1441792,-1284584,-1179648,-1048819,-934658,-777181 + ,-626371,-515660,-377493,-248975,-113036,436,113584,248354,379718,512475 + ,653932,796494,917504,1048576,1179648,1310720,1441792,1572864,1703936,1835008 + ,-1572864,-1441792,-1297608,-1161159,-1032316,-917092,-779770,-647384,-515529,-384269 + ,-250003,-119252,1053,118111,249512,380545,512039,648101,770656,907003 + ,1021725,1178082,1310720,1441792,-4587520,-4456448,-4325376,-4194304,-4063232,-3932160 + ,-3801088,-3670016,-3538944,-3407872,-3276800,-3145728,-2999335,-2883584,-2752512,-2621440 + ,-2490368,-2359296,-2228224,-2112691,-1966080,-1848781,-1709830,-1566109,-1438427,-1303530 + ,-1176124,-1040936,-913876,-784585,-652025,-518361,-385267,-256342,-127297,-2733 + ,125422,257792,389363,519911,651106,783805,909407,1044143,1174156,1309267 + ,1436173,1553771,1708958,1814083,1967036,2095386,2255169,2359296,2478303,2621440 + ,2752512,-4456448,-4325376,-4194304,-4063232,-3932160,-3797524,-3670016,-3560250,-3413217 + ,-3257719,-3166416,-2986626,-2878000,-2781144,-2625383,-2495465,-2346792,-2230930,-2077063 + ,-1949225,-1819274,-1697261,-1568664,-1443074,-1304302,-1175289,-1043794,-913423,-785561 + ,-652104,-522835,-392667,-260517,-130088,-2,129509,260990,391931,522470 + ,655770,784902,917093,1046445,1176951,1303121,1441362,1565401,1702022,1822856 + ,1952852,2090384,2214607,2338436,2457483,2621440,-8781824,-8650752,-8519680,-8388608 + ,-8260828,-8126464,-8003337,-7859030,-7750057,-7602176,-7471104,-7340032,-7193045,-7090588 + ,-6946816,-6843344,-6676635,-6557575,-6447804,-6277614,-6159736,-6035729,-5884723,-5739567 + ,-5634818,-5489867,-5372864,-5243300,-5098939,-4988639,-4856258,-4728494,-4591717,-4447428 + ,-4322409,-4192918,-4062638,-3934141,-3797545,-3673373,-3531587,-3407391,-3277404,-3147797 + ,-3013578,-2886548,-2749811,-2616428,-2490949,-2361301,-2228482,-2096883,-1964343,-1831754 + ,-1702201,-1572495,-1442012,-1309242,-1182451,-1048996,-916905,-786510,-657079,-524730 + ,-393672,-261313,-128743,166,130678,261334,393287,524155,655570,786839 + ,917353,1052167,1179013,1309360,1442634,1571153,1703961,1832027,1965014,2097912 + ,2224861,2355341,2490455,2623051,2753484,2877015,3015783,3144157,3273705,3405255 + ,3542006,3669580,3802417,3935413,4065088,4190896,4333521,4456355,4579781,4713832 + ,4845707,4978625,5113278,5243817,5382318,5500592,5638135,5761179,5900822,6029270 + ,6186398,6297816,6436435,6559163,6666389,6806548,6950461,7086078,7195777,7350973 + ,7480132,7614852,7743514,7847288,8014762,8126464,8257536,8388608,8519680,8650752 + ,8781824,8912896,9043968,9175040,9306112,9437184 +}; + + + +const WebRtc_Word16 WebRtcIsacfix_kLevelsShapeQ10[1735] = { + 0, 0, -1, 0, 0, 1, 0, 1, 0, -821 + , 1, -763, -1, 656, -620, 0, 633, -636, 4, 615 + , -630, 1, 649, -1773, -670, 5, 678, 1810, -1876, -676 + , 0, 691, 1843, -1806, -743, -1, 749, 1795, 2920, -2872 + , -1761, -772, -3, 790, 1763, 2942, 0, 0, 0, 0 + , -792, 2, 0, 0, 1, 0, -854, 0, -702, -1 + , 662, -624, -5, 638, -611, -6, 638, -647, 0, 651 + , -685, -4, 679, 2123, -1814, -693, 0, 664, 1791, -1735 + , -737, 0, 771, 1854, 2873, -2867, -1842, -793, -1, 821 + , 1826, 2805, 3922, 0, 0, 0, -1, -779, 1, 786 + , 1, -708, 0, 789, -799, 1, 797, -663, 2, 646 + , -600, 3, 609, -600, 1, 658, 1807, -627, -3, 612 + , -625, 3, 632, -1732, -674, 1, 672, 2048, -1768, -715 + , 0, 724, 1784, -3881, -3072, -1774, -719, -1, 730, 1811 + , -2963, -1829, -806, -1, 816, 1795, 3050, -5389, -3784, -2942 + , -1893, -865, -12, 867, 1885, 2945, 3928, -2, 1, 4 + , 0, -694, 2, 665, -598, 5, 587, -599, -1, 661 + , -656, -7, 611, -607, 5, 603, -618, -4, 620, -1794 + , -645, -2, 654, -655, -1, 658, -1801, -700, 5, 707 + , 1927, -1752, -745, -8, 752, 1843, -2838, -1781, -801, 11 + , 796, 1811, 2942, 3866, -3849, -3026, -1848, -819, 2, 827 + , 1825, 2963, -3873, -2904, -1869, -910, -6, 903, 1902, 2885 + , 3978, 5286, -7168, -6081, -4989, -3968, -2963, -1970, -943, -2 + , 953, 1951, 2968, 3974, 5009, 6032, -2, 3, -1024, 2 + , 1024, -637, 1, 669, -613, -7, 630, -603, 4, 612 + , -612, 0, 590, -645, -11, 627, -657, -2, 671, 1849 + , -1853, -694, 2, 702, 1838, -3304, -1780, -736, -8, 732 + , 1772, -1709, -755, -6, 760, 1780, -2994, -1780, -800, 8 + , 819, 1830, 2816, -4096, -2822, -1881, -851, -4, 855, 1872 + , 2840, 3899, -3908, -2904, -1878, -887, 6, 897, 1872, 2942 + , 4008, -4992, -3881, -2933, -1915, -928, 1, 937, 1919, 2900 + , 4009, 4881, -6848, -6157, -5065, -3981, -2983, -1972, -978, -1 + , 968, 1979, 2988, 4008, 5007, 6108, 7003, 8051, 9027,-13272 + ,-12012,-11228,-10213, -9261, -8084, -7133, -6075, -5052, -4050, -3036 + , -2014, -996, -4, 1007, 2031, 3038, 4049, 5074, 6134, 7069 + , 8094, 9069, 10212, 11049, 12104, 51, -1024, -13, 1024, -609 + , -107, 613, -2048, -687, -95, 667, 2048, -3072, -1724, -785 + , -34, 732, 1819, -2048, -703, -26, 681, 2048, -2048, -686 + , -9, 665, 2048, -2048, -702, 37, 748, 1723, -4096, -2786 + , -1844, -837, 37, 811, 1742, 3072, -4096, -2783, -1848, -881 + , 39, 898, 1843, 2792, 3764, -5120, -4096, -2923, -1833, -852 + , -14, 862, 1824, 2834, 4096, -6144, -5120, -3914, -2842, -1870 + , -886, -27, 888, 1929, 2931, 4051, -7168, -6144, -5120, -3866 + , -2933, -1915, -927, 64, 933, 1902, 2929, 3912, 5063, 6144 + ,-11264,-10240, -9216, -8192, -7086, -6144, -5039, -3972, -2943, -1929 + , -941, 3, 938, 1942, 2959, 3933, 4905, 6088, 6983, 8192 + , -9216, -8192, -7202, -6088, -4983, -4019, -2955, -1975, -966, 17 + , 997, 1981, 2967, 3990, 4948, 6022, 6967, 8192,-13312,-12288 + ,-11264,-10240, -9216, -8049, -6997, -6040, -5026, -4043, -3029, -2034 + , -1015, -23, 984, 1997, 3010, 4038, 5002, 6015, 6946, 8061 + , 9216, 10240,-12381,-11264,-10240, -9060, -8058, -7153, -6085, -5075 + , -4051, -3042, -2037, -1017, -5, 1007, 2028, 3035, 4050, 5088 + , 6111, 7160, 8156, 9215, 10095, 11229, 12202, 13016,-26624,-25600 + ,-24582,-23671,-22674,-21400,-20355,-19508,-18315,-17269,-16361,-15299 + ,-14363,-13294,-12262,-11237,-10203, -9227, -8165, -7156, -6116, -5122 + , -4076, -3056, -2043, -1020, -8, 1027, 2047, 3065, 4110, 5130 + , 6125, 7168, 8195, 9206, 10230, 11227, 12256, 13304, 14281, 15316 + , 16374, 17382, 18428, 19388, 20361, 21468, 22448, 23781, 0, 0 + , -1, 0, -2, 1024, 0, 0, 0, -1, 1024, -1024 + , 1, -1024, 4, 1024, -1024, 2, 1024, -1024, 2, 1024 + , -2048, -1024, -4, 1024, -1024, 2, 1024, -2048, -1024, -3 + , 1024, 2048, -2048, -1024, 4, 1024, 2048, -3072, -2048, -1024 + , -1, 662, 2048, 0, 1, 0, 0, 1, -2, -2 + , 0, 2, 1024, -1, 1024, -1024, 4, 1024, -1024, 1 + , 1024, -1024, 1, 1024, -2048, -781, -4, 844, -807, -5 + , 866, -2048, -726, -13, 777, 2048, -2048, -643, -4, 617 + , 2048, 3072, -3072, -2048, -629, 1, 630, 2048, 3072, 0 + , -1, 1, -2, 2, 1, -1024, 5, -1024, 6, 1024 + , -1024, 4, 1024, -1024, 1, 1024, -1024, -9, 1024, -673 + , -7, 655, -2048, -665, -15, 716, -2048, -647, 4, 640 + , 2048, -2048, -615, -1, 635, 2048, -2048, -613, 10, 637 + , 2048, 3072, -3072, -2048, -647, -3, 641, 2048, 3072, -5120 + , -4096, -3072, -2048, -681, 6, 685, 2048, 3072, 4096, 1 + , 1, 0, -1, 1024, -1024, -3, 1024, -1024, 6, 1024 + , -1024, -1, 769, -733, 0, 1024, -876, -2, 653, -1024 + , -4, 786, -596, -13, 595, -634, -2, 638, 2048, -2048 + , -620, -5, 620, 2048, -4096, -3072, -2048, -639, 11, 655 + , 2048, 3072, -3072, -2048, -659, 5, 663, 2048, -3072, -1823 + , -687, 22, 695, 2048, 3072, 4096, -4096, -3072, -1848, -715 + , -3, 727, 1816, 3072, 4096, 5120, -8192, -7168, -6144, -5120 + , -4096, -2884, -1771, -756, -14, 775, 1844, 3072, 4096, 5120 + , 6144, -1, 1, 0, -1024, 2, 815, -768, 2, 708 + , -1024, -3, 693, -661, -7, 607, -643, -5, 609, -624 + , 3, 631, -682, -3, 691, 2048, -2048, -640, 5, 650 + , 2048, -3072, -2048, -701, 9, 704, 2048, 3072, -3072, -2048 + , -670, 10, 674, 2048, 3072, -5120, -4096, -3072, -1749, -738 + , 0, 733, 1811, 3072, 4096, 5120, -4096, -3072, -1873, -753 + , 0, 756, 1874, 3072, 4096, -5120, -4096, -2900, -1838, -793 + , -6, 793, 1868, 2837, 4096, 5120, -7168, -6144, -5120, -4096 + , -2832, -1891, -828, 1, 828, 1901, 2823, 3912, 5120, 6144 + , 7168, 8192,-13312,-12288,-11264,-10240, -9216, -8192, -7168, -6144 + , -5120, -3976, -3004, -1911, -869, 7, 869, 1932, 3024, 3992 + , 5009, 6144, 7168, 8192, 9216, 10240, 11264, -4, 1024, -629 + , -22, 609, -623, 9, 640, -2048, -768, 1, 682, -2048 + , -741, 49, 722, 2048, -3072, -1706, -808, -20, 768, 1750 + , -1684, -727, -29, 788, 1840, 3033, -1758, -784, 0, 801 + , 1702, -3072, -1813, -814, 38, 820, 1884, 2927, -4096, -3241 + , -1839, -922, 25, 882, 1886, 2812, -4096, -2982, -1923, -894 + , 84, 912, 1869, 2778, 4096, -4928, -3965, -2902, -1920, -883 + , 3, 917, 1953, 2921, 3957, 4922, 6144, 7168, -5120, -3916 + , -2897, -1949, -930, 31, 959, 1934, 2901, 3851, 5120, -9216 + , -8192, -7046, -6029, -5030, -4034, -2980, -1969, -1013, -76, 963 + , 1963, 2901, 3929, 4893, 6270, 7168, 8192, 9216,-12288,-11264 + ,-10240, -9216, -8192, -6846, -6123, -5108, -4008, -3000, -1963, -954 + , -6, 958, 1992, 3009, 4020, 5085, 6097, 7168, 8192, 9216 + ,-11264,-10139, -9194, -8127, -7156, -6102, -5053, -4049, -3036, -2025 + , -1009, -34, 974, 1984, 3034, 4028, 5138, 6000, 7057, 8166 + , 9070, 10033, 11360, 12288,-13312,-12288,-10932,-10190, -9120, -8123 + , -7128, -6103, -5074, -4081, -3053, -2029, -989, -4, 1010, 2028 + , 3051, 4073, 5071, 6099, 7132, 8147, 9295, 10159, 11023, 12263 + , 13312, 14336,-25600,-24576,-23552,-22529,-21504,-20480,-19456,-18637 + ,-17425,-16165,-15316,-14327,-13606,-12135,-11182,-10107, -9153, -8144 + , -7146, -6160, -5129, -4095, -3064, -2038, -1025, 1, 1031, 2072 + , 3074, 4088, 5123, 6149, 7157, 8173, 9198, 10244, 11250, 12268 + , 13263, 14289, 15351, 16370, 17402, 18413, 19474, 20337, 21386, 22521 + , 23367, 24350, 0, 0, 0, 0, 0, 0, 0, 0 + , -1024, 0, 1024, -1024, 0, 1024, -1024, 0, 1024, -1024 + , 0, 1024, -1024, 0, 1024, -773, 0, 1024, -674, 0 + , 645, -2048, -745, 0, 628, 2048, -2048, -712, 0, 681 + , 2048, 3072, -3072, -2048, -673, 0, 682, 1964, 3257, 0 + , 0, 0, 0, 0, 0, 0, 0, -1024, 0, 1024 + , -1024, 0, 1024, -1024, 0, 1024, -705, 0, 623, -771 + , 0, 1024, -786, 0, 688, -631, 0, 652, 2048, -2048 + , -627, -1, 666, 2048, -3072, -1756, -694, 0, 674, 2048 + , -3098, -1879, -720, 5, 694, 1886, 2958, 4096, 0, 0 + , 0, 0, 1024, 0, 0, 1024, -769, 0, 1024, -1024 + , 0, 1024, -1024, 0, 1024, -817, 0, 734, -786, 0 + , 651, -638, 0, 637, -623, 0, 671, -652, 0, 619 + , 2048, -2048, -670, -1, 663, 2048, -1908, -680, 1, 686 + , 2048, 3072, 4096, -4096, -3072, -1833, -711, 0, 727, 1747 + , 3072, 4096, -4096, -2971, -1826, -762, 2, 766, 1832, 2852 + , 3928, 5079, 0, 0, 0, -1024, 0, 1024, -1024, 0 + , -656, 0, 1024, -599, 0, 620, -1024, 0, 1024, -603 + , 0, 622, -643, 0, 660, -599, 0, 611, -641, -1 + , 651, 2048, -2048, -648, -2, 647, 1798, -3072, -2048, -672 + , 2, 670, 2048, -3072, -1780, -694, -1, 706, 1751, 3072 + , -3072, -1862, -757, 7, 739, 1798, 3072, 4096, -5120, -4096 + , -3253, -1811, -787, 3, 782, 1887, 3123, 4096, -7252, -6144 + , -5354, -4060, -2864, -1863, -820, -11, 847, 1903, 2970, 3851 + , 4921, 5957, 7168, 8192, 9306, 0, 0, -1024, 0, 1024 + , -726, 0, 706, -692, 0, 593, -598, 0, 616, -624 + , 0, 616, -605, 0, 613, -2048, -652, 1, 635, 2048 + , -2048, -647, -1, 660, 2048, -1811, -668, -2, 685, 2048 + , -1796, -731, -2, 730, 1702, 3072, -3072, -1766, -747, -4 + , 756, 1770, 3072, -4096, -3024, -1762, -783, 4, 771, 1781 + , 3072, -5120, -4057, -2807, -1832, -822, 0, 816, 1804, 2851 + , 3949, 5120, -6144, -4899, -3927, -2920, -1893, -874, -2, 868 + , 1881, 2905, 3960, 4912, 6144, -9216, -8192, -7168, -6225, -4963 + , -3943, -2956, -1890, -902, 0, 897, 1914, 2916, 3984, 4990 + , 6050, 7168,-11264,-10217, -9114, -8132, -7035, -5988, -4984, -4000 + , -2980, -1962, -927, 7, 931, 1956, 2981, 4031, 4972, 6213 + , 7227, 8192, 9216, 10240, 11170, 12288, 13312, 14336, 0, 1024 + , -557, 1, 571, -606, -4, 612, -1676, -707, 10, 673 + , 2048, -2048, -727, 5, 686, -3072, -1772, -755, 12, 716 + , 1877, -1856, -786, 2, 786, 1712, -1685, -818, -16, 863 + , 1729, -3072, -1762, -857, 3, 866, 1838, 2841, -3862, -2816 + , -1864, -925, -2, 923, 1897, 2779, -2782, -1838, -920, -28 + , 931, 1951, 2835, 3804, -4815, -4001, -2940, -1934, -959, -22 + , 975, 1957, 2904, 3971, 4835, -5148, -3892, -2944, -1953, -986 + , -11, 989, 1968, 2939, 3949, 4947, 5902, -9216, -8192, -6915 + , -6004, -4965, -4013, -3009, -1977, -987, -1, 982, 1972, 3000 + , 3960, 4939, 5814, -8976, -7888, -7084, -5955, -5043, -4009, -2991 + , -2002, -1000, -8, 993, 2011, 3023, 4026, 5028, 6023, 7052 + , 8014, 9216,-11240,-10036, -9125, -8118, -7105, -6062, -5048, -4047 + , -3044, -2025, -1009, -1, 1011, 2023, 3042, 4074, 5085, 6108 + , 7119, 8142, 9152, 10114, 11141, 12250, 13307,-15360,-14099,-13284 + ,-12291,-11223,-10221, -9152, -8147, -7128, -6104, -5077, -4072, -3062 + , -2033, -1020, 7, 1018, 2038, 3059, 4081, 5084, 6109, 7102 + , 8128, 9134, 10125, 11239, 12080,-23552,-22528,-21504,-20480,-19456 + ,-18159,-17240,-16291,-15364,-14285,-13305,-12271,-11233,-10217, -9198 + , -8175, -7157, -6134, -5122, -4089, -3071, -2047, -1018, 3, 1026 + , 2041, 3077, 4090, 5108, 6131, 7150, 8172, 9175, 10196, 11272 + , 12303, 13273, 14328, 15332, 16334, 17381, 18409, 19423, 20423, 21451 + , 22679, 23391, 24568, 25600, 26589 +}; + +/* cdf tables for quantizer indices */ +const WebRtc_UWord16 WebRtcIsacfix_kCdfGain[1212] = { + 0, 13, 301, 3730, 61784, 65167, 65489, 65535, 0, 17, + 142, 314, 929, 2466, 7678, 56450, 63463, 64740, 65204, 65426, + 65527, 65535, 0, 8, 100, 724, 6301, 60105, 65125, 65510, + 65531, 65535, 0, 13, 117, 368, 1068, 3010, 11928, 53603, + 61177, 63404, 64505, 65108, 65422, 65502, 65531, 65535, 0, 4, + 17, 96, 410, 1859, 12125, 54361, 64103, 65305, 65497, 65535, + 0, 4, 88, 230, 469, 950, 1746, 3228, 6092, 16592, + 44756, 56848, 61256, 63308, 64325, 64920, 65309, 65460, 65502, 65522, + 65535, 0, 88, 352, 1675, 6339, 20749, 46686, 59284, 63525, + 64949, 65359, 65502, 65527, 65535, 0, 13, 38, 63, 117, + 234, 381, 641, 929, 1407, 2043, 2809, 4032, 5753, 8792, + 14407, 24308, 38941, 48947, 55403, 59293, 61411, 62688, 63630, 64329, + 64840, 65188, 65376, 65472, 65506, 65527, 65531, 65535, 0, 8, + 29, 75, 222, 615, 1327, 2801, 5623, 9931, 16094, 24966, + 34419, 43458, 50676, 56186, 60055, 62500, 63936, 64765, 65225, 65435, + 65514, 65535, 0, 8, 13, 15, 17, 21, 33, 59, + 71, 92, 151, 243, 360, 456, 674, 934, 1223, 1583, + 1989, 2504, 3031, 3617, 4354, 5154, 6163, 7411, 8780, 10747, + 12874, 15591, 18974, 23027, 27436, 32020, 36948, 41830, 46205, 49797, + 53042, 56094, 58418, 60360, 61763, 62818, 63559, 64103, 64509, 64798, + 65045, 65162, 65288, 65363, 65447, 65506, 65522, 65531, 65533, 65535, + 0, 4, 6, 25, 38, 71, 138, 264, 519, 808, + 1227, 1825, 2516, 3408, 4279, 5560, 7092, 9197, 11420, 14108, + 16947, 20300, 23926, 27459, 31164, 34827, 38575, 42178, 45540, 48747, + 51444, 54090, 56426, 58460, 60080, 61595, 62734, 63668, 64275, 64673, + 64936, 65112, 65217, 65334, 65426, 65464, 65477, 65489, 65518, 65527, + 65529, 65531, 65533, 65535, 0, 2, 4, 8, 10, 12, + 14, 16, 21, 33, 50, 71, 84, 92, 105, 138, + 180, 255, 318, 377, 435, 473, 511, 590, 682, 758, + 913, 1097, 1256, 1449, 1671, 1884, 2169, 2445, 2772, 3157, + 3563, 3944, 4375, 4848, 5334, 5820, 6448, 7101, 7716, 8378, + 9102, 9956, 10752, 11648, 12707, 13670, 14758, 15910, 17187, 18472, + 19627, 20649, 21951, 23169, 24283, 25552, 26862, 28227, 29391, 30764, + 31882, 33213, 34432, 35600, 36910, 38116, 39464, 40729, 41872, 43144, + 44371, 45514, 46762, 47813, 48968, 50069, 51032, 51974, 52908, 53737, + 54603, 55445, 56282, 56990, 57572, 58191, 58840, 59410, 59887, 60264, + 60607, 60946, 61269, 61516, 61771, 61960, 62198, 62408, 62558, 62776, + 62985, 63207, 63408, 63546, 63739, 63906, 64070, 64237, 64371, 64551, + 64677, 64836, 64999, 65095, 65213, 65284, 65338, 65380, 65426, 65447, + 65472, 65485, 65487, 65489, 65502, 65510, 65512, 65514, 65516, 65518, + 65522, 65531, 65533, 65535, 0, 2, 4, 6, 65528, 65531, + 65533, 65535, 0, 2, 4, 6, 8, 10, 222, 65321, + 65513, 65528, 65531, 65533, 65535, 0, 2, 4, 50, 65476, + 65529, 65531, 65533, 65535, 0, 2, 4, 6, 8, 12, + 38, 544, 64936, 65509, 65523, 65525, 65529, 65531, 65533, 65535, + 0, 2, 4, 6, 8, 10, 1055, 64508, 65528, 65531, + 65533, 65535, 0, 2, 4, 6, 8, 10, 12, 123, + 3956, 62999, 65372, 65495, 65515, 65521, 65523, 65525, 65527, 65529, + 65531, 65533, 65535, 0, 2, 4, 12, 53, 4707, 59445, + 65467, 65525, 65527, 65529, 65531, 65533, 65535, 0, 2, 4, + 6, 8, 10, 12, 14, 16, 38, 40, 50, 67, + 96, 234, 929, 14345, 55750, 64866, 65389, 65462, 65514, 65517, + 65519, 65521, 65523, 65525, 65527, 65529, 65531, 65533, 65535, 0, + 2, 4, 6, 8, 10, 15, 35, 91, 377, 1946, + 13618, 52565, 63714, 65184, 65465, 65520, 65523, 65525, 65527, 65529, + 65531, 65533, 65535, 0, 2, 4, 6, 8, 10, 12, + 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, + 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, + 54, 82, 149, 362, 751, 1701, 4239, 12893, 38627, 55072, + 60875, 63071, 64158, 64702, 65096, 65283, 65412, 65473, 65494, 65505, + 65508, 65517, 65519, 65521, 65523, 65525, 65527, 65529, 65531, 65533, + 65535, 0, 2, 15, 23, 53, 143, 260, 418, 698, + 988, 1353, 1812, 2411, 3144, 4015, 5143, 6401, 7611, 8999, + 10653, 12512, 14636, 16865, 19404, 22154, 24798, 27521, 30326, 33102, + 35790, 38603, 41415, 43968, 46771, 49435, 52152, 54715, 57143, 59481, + 61178, 62507, 63603, 64489, 64997, 65257, 65427, 65473, 65503, 65520, + 65529, 65531, 65533, 65535, 0, 3, 6, 9, 26, 32, + 44, 46, 64, 94, 111, 164, 205, 254, 327, 409, + 506, 608, 733, 885, 1093, 1292, 1482, 1742, 1993, 2329, + 2615, 3029, 3374, 3798, 4257, 4870, 5405, 5992, 6618, 7225, + 7816, 8418, 9051, 9761, 10532, 11380, 12113, 13010, 13788, 14594, + 15455, 16361, 17182, 18088, 18997, 20046, 20951, 21968, 22947, 24124, + 25296, 26547, 27712, 28775, 29807, 30835, 31709, 32469, 33201, 34014, + 34876, 35773, 36696, 37620, 38558, 39547, 40406, 41277, 42367, 43290, + 44445, 45443, 46510, 47684, 48973, 50157, 51187, 52242, 53209, 54083, + 55006, 55871, 56618, 57293, 57965, 58556, 59222, 59722, 60180, 60554, + 60902, 61250, 61554, 61837, 62100, 62372, 62631, 62856, 63078, 63324, + 63557, 63768, 63961, 64089, 64235, 64352, 64501, 64633, 64770, 64887, + 65001, 65059, 65121, 65188, 65246, 65302, 65346, 65390, 65428, 65463, + 65477, 65506, 65515, 65517, 65519, 65521, 65523, 65525, 65527, 65529, + 65531, 65533, 65535, 0, 2, 4, 109, 65332, 65531, 65533, + 65535, 0, 2, 4, 6, 8, 25, 1817, 63874, 65511, + 65527, 65529, 65531, 65533, 65535, 0, 2, 4, 907, 65014, + 65529, 65531, 65533, 65535, 0, 2, 4, 6, 8, 10, + 12, 132, 2743, 62708, 65430, 65525, 65527, 65529, 65531, 65533, + 65535, 0, 2, 4, 6, 8, 35, 3743, 61666, 65485, + 65531, 65533, 65535, 0, 2, 4, 6, 8, 10, 23, + 109, 683, 6905, 58417, 64911, 65398, 65497, 65518, 65525, 65527, + 65529, 65531, 65533, 65535, 0, 2, 4, 6, 53, 510, + 10209, 55212, 64573, 65441, 65522, 65529, 65531, 65533, 65535, 0, + 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, + 22, 32, 90, 266, 1037, 3349, 14468, 50488, 62394, 64685, + 65341, 65480, 65514, 65519, 65521, 65523, 65525, 65527, 65529, 65531, + 65533, 65535, 0, 2, 4, 6, 9, 16, 37, 106, + 296, 748, 1868, 5733, 18897, 45553, 60165, 63949, 64926, 65314, + 65441, 65508, 65524, 65529, 65531, 65533, 65535, 0, 2, 4, + 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, + 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, + 46, 48, 50, 83, 175, 344, 667, 1293, 2337, 4357, + 8033, 14988, 28600, 43244, 52011, 57042, 59980, 61779, 63065, 63869, + 64390, 64753, 64988, 65164, 65326, 65422, 65462, 65492, 65506, 65522, + 65524, 65526, 65531, 65533, 65535, 0, 2, 4, 6, 8, + 10, 12, 14, 16, 25, 39, 48, 55, 62, 65, + 85, 106, 139, 169, 194, 252, 323, 485, 688, 1074, + 1600, 2544, 3863, 5733, 8303, 11397, 15529, 20273, 25734, 31455, + 36853, 41891, 46410, 50306, 53702, 56503, 58673, 60479, 61880, 62989, + 63748, 64404, 64852, 65124, 65309, 65424, 65480, 65524, 65528, 65533, + 65535, 0, 2, 4, 6, 8, 10, 12, 14, 21, + 23, 25, 27, 29, 31, 39, 41, 43, 48, 60, + 72, 79, 106, 136, 166, 187, 224, 252, 323, 381, + 427, 478, 568, 660, 783, 912, 1046, 1175, 1365, 1567, + 1768, 2024, 2347, 2659, 3049, 3529, 4033, 4623, 5281, 5925, + 6726, 7526, 8417, 9468, 10783, 12141, 13571, 15222, 16916, 18659, + 20350, 22020, 23725, 25497, 27201, 29026, 30867, 32632, 34323, 36062, + 37829, 39466, 41144, 42654, 43981, 45343, 46579, 47759, 49013, 50171, + 51249, 52283, 53245, 54148, 54938, 55669, 56421, 57109, 57791, 58464, + 59092, 59674, 60105, 60653, 61083, 61407, 61757, 62095, 62388, 62649, + 62873, 63157, 63358, 63540, 63725, 63884, 64046, 64155, 64278, 64426, + 64548, 64654, 64806, 64906, 64994, 65077, 65137, 65215, 65277, 65324, + 65354, 65409, 65437, 65455, 65462, 65490, 65495, 65499, 65508, 65511, + 65513, 65515, 65517, 65519, 65521, 65523, 65525, 65527, 65529, 65531, + 65533, 65535 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kCdfShape[2059] = { + 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65535, + 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, 4, + 65535, 0, 8, 65514, 65535, 0, 29, 65481, 65535, 0, + 121, 65439, 65535, 0, 239, 65284, 65535, 0, 8, 779, + 64999, 65527, 65535, 0, 8, 888, 64693, 65522, 65535, 0, + 29, 2604, 62843, 65497, 65531, 65535, 0, 25, 176, 4576, + 61164, 65275, 65527, 65535, 0, 65535, 0, 65535, 0, 65535, + 0, 65535, 0, 4, 65535, 0, 65535, 0, 65535, 0, + 65535, 0, 65535, 0, 4, 65535, 0, 33, 65502, 65535, + 0, 54, 65481, 65535, 0, 251, 65309, 65535, 0, 611, + 65074, 65535, 0, 1273, 64292, 65527, 65535, 0, 4, 1809, + 63940, 65518, 65535, 0, 88, 4392, 60603, 65426, 65531, 65535, + 0, 25, 419, 7046, 57756, 64961, 65514, 65531, 65535, 0, + 65535, 0, 65535, 0, 65535, 0, 65535, 0, 4, 65531, + 65535, 0, 65535, 0, 8, 65531, 65535, 0, 4, 65527, + 65535, 0, 17, 65510, 65535, 0, 42, 65481, 65535, 0, + 197, 65342, 65531, 65535, 0, 385, 65154, 65535, 0, 1005, + 64522, 65535, 0, 8, 1985, 63469, 65533, 65535, 0, 38, + 3119, 61884, 65514, 65535, 0, 4, 6, 67, 4961, 60804, + 65472, 65535, 0, 17, 565, 9182, 56538, 65087, 65514, 65535, + 0, 8, 63, 327, 2118, 14490, 52774, 63839, 65376, 65522, + 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, + 17, 65522, 65535, 0, 59, 65489, 65535, 0, 50, 65522, + 65535, 0, 54, 65489, 65535, 0, 310, 65179, 65535, 0, + 615, 64836, 65535, 0, 4, 1503, 63965, 65535, 0, 2780, + 63383, 65535, 0, 21, 3919, 61051, 65527, 65535, 0, 84, + 6674, 59929, 65435, 65535, 0, 4, 255, 7976, 55784, 65150, + 65518, 65531, 65535, 0, 4, 8, 582, 10726, 53465, 64949, + 65518, 65535, 0, 29, 339, 3006, 17555, 49517, 62956, 65200, + 65497, 65531, 65535, 0, 2, 33, 138, 565, 2324, 7670, + 22089, 45966, 58949, 63479, 64966, 65380, 65518, 65535, 0, 65535, + 0, 65535, 0, 2, 65533, 65535, 0, 46, 65514, 65535, + 0, 414, 65091, 65535, 0, 540, 64911, 65535, 0, 419, + 65162, 65535, 0, 976, 64790, 65535, 0, 2977, 62495, 65531, + 65535, 0, 4, 3852, 61034, 65527, 65535, 0, 4, 29, + 6021, 60243, 65468, 65535, 0, 84, 6711, 58066, 65418, 65535, + 0, 13, 281, 9550, 54917, 65125, 65506, 65535, 0, 2, + 63, 984, 12108, 52644, 64342, 65435, 65527, 65535, 0, 29, + 251, 2014, 14871, 47553, 62881, 65229, 65518, 65535, 0, 13, + 142, 749, 4220, 18497, 45200, 60913, 64823, 65426, 65527, 65535, + 0, 13, 71, 264, 1176, 3789, 10500, 24480, 43488, 56324, + 62315, 64493, 65242, 65464, 65514, 65522, 65531, 65535, 0, 4, + 13, 38, 109, 205, 448, 850, 1708, 3429, 6276, 11371, + 19221, 29734, 40955, 49391, 55411, 59460, 62102, 63793, 64656, 65150, + 65401, 65485, 65522, 65531, 65535, 0, 65535, 0, 2, 65533, + 65535, 0, 1160, 65476, 65535, 0, 2, 6640, 64763, 65533, + 65535, 0, 2, 38, 9923, 61009, 65527, 65535, 0, 2, + 4949, 63092, 65533, 65535, 0, 2, 3090, 63398, 65533, 65535, + 0, 2, 2520, 58744, 65510, 65535, 0, 2, 13, 544, + 8784, 51403, 65148, 65533, 65535, 0, 2, 25, 1017, 10412, + 43550, 63651, 65489, 65527, 65535, 0, 2, 4, 29, 783, + 13377, 52462, 64524, 65495, 65533, 65535, 0, 2, 4, 6, + 100, 1817, 18451, 52590, 63559, 65376, 65531, 65535, 0, 2, + 4, 6, 46, 385, 2562, 11225, 37416, 60488, 65026, 65487, + 65529, 65533, 65535, 0, 2, 4, 6, 8, 10, 12, + 42, 222, 971, 5221, 19811, 45048, 60312, 64486, 65294, 65474, + 65525, 65529, 65533, 65535, 0, 2, 4, 8, 71, 167, + 666, 2533, 7875, 19622, 38082, 54359, 62108, 64633, 65290, 65495, + 65529, 65533, 65535, 0, 2, 4, 6, 8, 10, 13, + 109, 586, 1930, 4949, 11600, 22641, 36125, 48312, 56899, 61495, + 63927, 64932, 65389, 65489, 65518, 65531, 65533, 65535, 0, 4, + 6, 8, 67, 209, 712, 1838, 4195, 8432, 14432, 22834, + 31723, 40523, 48139, 53929, 57865, 60657, 62403, 63584, 64363, 64907, + 65167, 65372, 65472, 65514, 65535, 0, 2, 4, 13, 25, + 42, 46, 50, 75, 113, 147, 281, 448, 657, 909, + 1185, 1591, 1976, 2600, 3676, 5317, 7398, 9914, 12941, 16169, + 19477, 22885, 26464, 29851, 33360, 37228, 41139, 44802, 48654, 52058, + 55181, 57676, 59581, 61022, 62190, 63107, 63676, 64199, 64547, 64924, + 65158, 65313, 65430, 65481, 65518, 65535, 0, 65535, 0, 65535, + 0, 65535, 0, 65535, 0, 65533, 65535, 0, 65535, 0, + 65535, 0, 65535, 0, 65533, 65535, 0, 2, 65535, 0, + 2, 65533, 65535, 0, 2, 65533, 65535, 0, 2, 65533, + 65535, 0, 2, 4, 65533, 65535, 0, 2, 65533, 65535, + 0, 2, 4, 65531, 65533, 65535, 0, 2, 4, 65531, + 65533, 65535, 0, 2, 4, 6, 65524, 65533, 65535, 0, + 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, + 65535, 0, 65535, 0, 65535, 0, 65533, 65535, 0, 65533, + 65535, 0, 2, 65533, 65535, 0, 2, 65533, 65535, 0, + 2, 65533, 65535, 0, 2, 4, 65532, 65535, 0, 6, + 65523, 65535, 0, 2, 15, 65530, 65533, 65535, 0, 2, + 35, 65493, 65531, 65533, 65535, 0, 2, 4, 158, 65382, + 65531, 65533, 65535, 0, 65535, 0, 65535, 0, 65535, 0, + 65535, 0, 65535, 0, 65535, 0, 2, 65535, 0, 2, + 65533, 65535, 0, 2, 65533, 65535, 0, 2, 65533, 65535, + 0, 2, 65533, 65535, 0, 9, 65512, 65535, 0, 2, + 12, 65529, 65535, 0, 2, 73, 65434, 65533, 65535, 0, + 2, 240, 65343, 65533, 65535, 0, 2, 476, 65017, 65531, + 65533, 65535, 0, 2, 4, 1046, 64686, 65531, 65533, 65535, + 0, 2, 4, 6, 8, 1870, 63898, 65529, 65531, 65533, + 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65533, 65535, + 0, 2, 65533, 65535, 0, 2, 65533, 65535, 0, 2, + 65532, 65535, 0, 6, 65533, 65535, 0, 6, 65523, 65535, + 0, 2, 65532, 65535, 0, 137, 65439, 65535, 0, 576, + 64899, 65533, 65535, 0, 2, 289, 65299, 65533, 65535, 0, + 2, 4, 6, 880, 64134, 65531, 65533, 65535, 0, 2, + 4, 1853, 63347, 65533, 65535, 0, 2, 6, 2516, 61762, + 65529, 65531, 65533, 65535, 0, 2, 4, 9, 3980, 61380, + 65503, 65529, 65531, 65533, 65535, 0, 2, 4, 6, 8, + 10, 12, 61, 6393, 59859, 65466, 65527, 65529, 65531, 65533, + 65535, 0, 65535, 0, 65535, 0, 65535, 0, 2, 65532, + 65535, 0, 3, 65529, 65535, 0, 2, 65529, 65535, 0, + 61, 65453, 65535, 0, 234, 65313, 65535, 0, 503, 65138, + 65535, 0, 155, 65402, 65533, 65535, 0, 2, 1058, 64554, + 65533, 65535, 0, 2, 4, 3138, 62109, 65531, 65533, 65535, + 0, 2, 4, 2031, 63339, 65531, 65533, 65535, 0, 2, + 4, 6, 9, 4155, 60778, 65523, 65529, 65531, 65533, 65535, + 0, 2, 4, 41, 6189, 59269, 65490, 65531, 65533, 65535, + 0, 2, 4, 6, 210, 8789, 57043, 65400, 65528, 65531, + 65533, 65535, 0, 2, 4, 6, 8, 26, 453, 10086, + 55499, 64948, 65483, 65524, 65527, 65529, 65531, 65533, 65535, 0, + 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, + 114, 1014, 11202, 52670, 64226, 65356, 65503, 65514, 65523, 65525, + 65527, 65529, 65531, 65533, 65535, 0, 65533, 65535, 0, 15, + 65301, 65535, 0, 152, 64807, 65535, 0, 2, 3328, 63308, + 65535, 0, 2, 4050, 59730, 65533, 65535, 0, 2, 164, + 10564, 61894, 65529, 65535, 0, 15, 6712, 59831, 65076, 65532, + 65535, 0, 32, 7712, 57449, 65459, 65535, 0, 2, 210, + 7849, 53110, 65021, 65523, 65535, 0, 2, 12, 1081, 13883, + 48262, 62870, 65477, 65535, 0, 2, 88, 847, 6145, 37852, + 62012, 65454, 65533, 65535, 0, 9, 47, 207, 1823, 14522, + 45521, 61069, 64891, 65481, 65528, 65531, 65533, 65535, 0, 2, + 9, 488, 2881, 12758, 38703, 58412, 64420, 65410, 65533, 65535, + 0, 2, 4, 6, 61, 333, 1891, 6486, 19720, 43188, + 57547, 62472, 64796, 65421, 65497, 65523, 65529, 65531, 65533, 65535, + 0, 2, 4, 6, 8, 10, 12, 29, 117, 447, + 1528, 6138, 21242, 43133, 56495, 62432, 64746, 65362, 65500, 65529, + 65531, 65533, 65535, 0, 2, 18, 105, 301, 760, 1490, + 3472, 7568, 15002, 26424, 40330, 53029, 60048, 62964, 64274, 64890, + 65337, 65445, 65489, 65513, 65527, 65530, 65533, 65535, 0, 2, + 4, 6, 41, 102, 409, 853, 2031, 4316, 7302, 11328, + 16869, 24825, 34926, 43481, 50877, 56126, 59874, 62103, 63281, 63857, + 64166, 64675, 65382, 65522, 65531, 65533, 65535, 0, 2, 4, + 6, 8, 10, 12, 14, 16, 18, 29, 38, 53, + 58, 96, 181, 503, 1183, 2849, 5590, 8600, 11379, 13942, + 16478, 19453, 22638, 26039, 29411, 32921, 37596, 41433, 44998, 48560, + 51979, 55106, 57666, 59892, 61485, 62616, 63484, 64018, 64375, 64685, + 64924, 65076, 65278, 65395, 65471, 65509, 65529, 65535, 0, 65535, + 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65535, + 0, 65535, 0, 65535, 0, 2, 65533, 65535, 0, 2, + 65533, 65535, 0, 2, 65533, 65535, 0, 2, 65533, 65535, + 0, 2, 65533, 65535, 0, 2, 65533, 65535, 0, 7, + 65519, 65535, 0, 2, 14, 65491, 65533, 65535, 0, 2, + 81, 65427, 65531, 65533, 65535, 0, 2, 4, 312, 65293, + 65528, 65533, 65535, 0, 65535, 0, 65535, 0, 65535, 0, + 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, + 2, 65533, 65535, 0, 2, 65533, 65535, 0, 2, 65533, + 65535, 0, 5, 65523, 65535, 0, 2, 65533, 65535, 0, + 7, 65526, 65535, 0, 46, 65464, 65533, 65535, 0, 2, + 120, 65309, 65533, 65535, 0, 2, 5, 362, 65097, 65533, + 65535, 0, 2, 18, 1164, 64785, 65528, 65531, 65533, 65535, + 0, 65535, 0, 65535, 0, 65535, 0, 65533, 65535, 0, + 65535, 0, 65533, 65535, 0, 2, 65533, 65535, 0, 2, + 65533, 65535, 0, 2, 65533, 65535, 0, 2, 65530, 65535, + 0, 2, 65523, 65535, 0, 69, 65477, 65535, 0, 141, + 65459, 65535, 0, 194, 65325, 65533, 65535, 0, 2, 543, + 64912, 65533, 65535, 0, 5, 1270, 64301, 65529, 65531, 65533, + 65535, 0, 2, 4, 12, 2055, 63538, 65508, 65531, 65533, + 65535, 0, 2, 7, 102, 3775, 61970, 65429, 65526, 65528, + 65533, 65535, 0, 65535, 0, 65535, 0, 65535, 0, 2, + 65533, 65535, 0, 2, 65535, 0, 9, 65533, 65535, 0, + 25, 65512, 65535, 0, 2, 65533, 65535, 0, 44, 65480, + 65535, 0, 48, 65475, 65535, 0, 162, 65373, 65535, 0, + 637, 64806, 65533, 65535, 0, 2, 935, 64445, 65533, 65535, + 0, 2, 4, 1662, 64083, 65533, 65535, 0, 2, 12, + 3036, 62469, 65521, 65533, 65535, 0, 2, 120, 5405, 60468, + 65469, 65531, 65533, 65535, 0, 2, 4, 18, 254, 6663, + 58999, 65272, 65528, 65533, 65535, 0, 2, 4, 9, 12, + 67, 591, 8981, 56781, 64564, 65365, 65508, 65524, 65526, 65529, + 65531, 65533, 65535, 0, 65535, 0, 65535, 0, 2, 65533, + 65535, 0, 9, 65526, 65535, 0, 14, 65503, 65535, 0, + 127, 65390, 65535, 0, 517, 64990, 65535, 0, 178, 65330, + 65535, 0, 2, 1055, 64533, 65533, 65535, 0, 2, 1558, + 63942, 65533, 65535, 0, 2, 2205, 63173, 65533, 65535, 0, + 25, 4493, 60862, 65505, 65533, 65535, 0, 2, 48, 5890, + 59442, 65482, 65533, 65535, 0, 2, 4, 127, 7532, 58191, + 65394, 65533, 65535, 0, 2, 5, 32, 550, 10388, 54924, + 65046, 65510, 65531, 65533, 65535, 0, 2, 4, 30, 150, + 1685, 14340, 51375, 63619, 65288, 65503, 65528, 65533, 65535, 0, + 2, 4, 6, 8, 28, 97, 473, 2692, 15407, 50020, + 62880, 65064, 65445, 65508, 65531, 65533, 65535, 0, 2, 4, + 12, 32, 79, 150, 372, 907, 2184, 5868, 18207, 45431, + 59856, 64031, 65096, 65401, 65481, 65507, 65521, 65523, 65525, 65527, + 65529, 65531, 65533, 65535, 0, 65533, 65535, 0, 182, 65491, + 65535, 0, 877, 64286, 65535, 0, 9, 2708, 63612, 65533, + 65535, 0, 2, 6038, 59532, 65535, 0, 2, 92, 5500, + 60539, 65533, 65535, 0, 268, 8908, 56512, 65385, 65535, 0, + 129, 13110, 52742, 65036, 65535, 0, 2, 806, 14003, 51929, + 64732, 65523, 65535, 0, 7, 92, 2667, 18159, 47678, 62610, + 65355, 65535, 0, 32, 1836, 19676, 48237, 61677, 64960, 65526, + 65535, 0, 21, 159, 967, 5668, 22782, 44709, 58317, 64020, + 65406, 65528, 65535, 0, 7, 162, 1838, 8328, 23929, 43014, + 56394, 63374, 65216, 65484, 65521, 65535, 0, 2, 4, 6, + 28, 268, 1120, 3613, 10688, 24185, 40989, 54917, 61684, 64510, + 65403, 65530, 65535, 0, 2, 16, 44, 139, 492, 1739, + 5313, 13558, 26766, 41566, 52446, 58937, 62815, 64480, 65201, 65454, + 65524, 65533, 65535, 0, 7, 25, 76, 263, 612, 1466, + 3325, 6832, 12366, 20152, 29466, 39255, 47360, 53506, 57740, 60726, + 62845, 64131, 64882, 65260, 65459, 65521, 65528, 65530, 65535, 0, + 2, 4, 14, 48, 136, 312, 653, 1240, 2369, 4327, + 7028, 10759, 15449, 21235, 28027, 35386, 42938, 49562, 54990, 59119, + 62086, 63916, 64863, 65249, 65445, 65493, 65523, 65535, 0, 2, + 4, 6, 8, 10, 12, 21, 83, 208, 409, 723, + 1152, 1868, 2951, 4463, 6460, 8979, 11831, 15195, 18863, 22657, + 26762, 30881, 34963, 39098, 43054, 47069, 50620, 53871, 56821, 59386, + 61340, 62670, 63512, 64023, 64429, 64750, 64944, 65126, 65279, 65366, + 65413, 65445, 65473, 65505, 65510, 65521, 65528, 65530, 65535 +}; + +/* pointers to cdf tables for quantizer indices */ +const WebRtc_UWord16 *WebRtcIsacfix_kCdfGainPtr[3][12] = { + { WebRtcIsacfix_kCdfGain +0 +0, WebRtcIsacfix_kCdfGain +0 +8, WebRtcIsacfix_kCdfGain +0 +22, + WebRtcIsacfix_kCdfGain +0 +32, WebRtcIsacfix_kCdfGain +0 +48, WebRtcIsacfix_kCdfGain +0 +60, + WebRtcIsacfix_kCdfGain +0 +81, WebRtcIsacfix_kCdfGain +0 +95, WebRtcIsacfix_kCdfGain +0 +128, + WebRtcIsacfix_kCdfGain +0 +152, WebRtcIsacfix_kCdfGain +0 +210, WebRtcIsacfix_kCdfGain +0 +264 + }, + { WebRtcIsacfix_kCdfGain +404 +0, WebRtcIsacfix_kCdfGain +404 +8, WebRtcIsacfix_kCdfGain +404 +21, + WebRtcIsacfix_kCdfGain +404 +30, WebRtcIsacfix_kCdfGain +404 +46, WebRtcIsacfix_kCdfGain +404 +58, + WebRtcIsacfix_kCdfGain +404 +79, WebRtcIsacfix_kCdfGain +404 +93, WebRtcIsacfix_kCdfGain +404 +125, + WebRtcIsacfix_kCdfGain +404 +149, WebRtcIsacfix_kCdfGain +404 +207, WebRtcIsacfix_kCdfGain +404 +260 + }, + { WebRtcIsacfix_kCdfGain +803 +0, WebRtcIsacfix_kCdfGain +803 +8, WebRtcIsacfix_kCdfGain +803 +22, + WebRtcIsacfix_kCdfGain +803 +31, WebRtcIsacfix_kCdfGain +803 +48, WebRtcIsacfix_kCdfGain +803 +60, + WebRtcIsacfix_kCdfGain +803 +81, WebRtcIsacfix_kCdfGain +803 +96, WebRtcIsacfix_kCdfGain +803 +129, + WebRtcIsacfix_kCdfGain +803 +154, WebRtcIsacfix_kCdfGain +803 +212, WebRtcIsacfix_kCdfGain +803 +268 + } +}; + +const WebRtc_UWord16 *WebRtcIsacfix_kCdfShapePtr[3][108] = { + { WebRtcIsacfix_kCdfShape +0 +0, WebRtcIsacfix_kCdfShape +0 +2, WebRtcIsacfix_kCdfShape +0 +4, + WebRtcIsacfix_kCdfShape +0 +6, WebRtcIsacfix_kCdfShape +0 +8, WebRtcIsacfix_kCdfShape +0 +10, + WebRtcIsacfix_kCdfShape +0 +12, WebRtcIsacfix_kCdfShape +0 +14, WebRtcIsacfix_kCdfShape +0 +16, + WebRtcIsacfix_kCdfShape +0 +18, WebRtcIsacfix_kCdfShape +0 +21, WebRtcIsacfix_kCdfShape +0 +25, + WebRtcIsacfix_kCdfShape +0 +29, WebRtcIsacfix_kCdfShape +0 +33, WebRtcIsacfix_kCdfShape +0 +37, + WebRtcIsacfix_kCdfShape +0 +43, WebRtcIsacfix_kCdfShape +0 +49, WebRtcIsacfix_kCdfShape +0 +56, + WebRtcIsacfix_kCdfShape +0 +64, WebRtcIsacfix_kCdfShape +0 +66, WebRtcIsacfix_kCdfShape +0 +68, + WebRtcIsacfix_kCdfShape +0 +70, WebRtcIsacfix_kCdfShape +0 +72, WebRtcIsacfix_kCdfShape +0 +75, + WebRtcIsacfix_kCdfShape +0 +77, WebRtcIsacfix_kCdfShape +0 +79, WebRtcIsacfix_kCdfShape +0 +81, + WebRtcIsacfix_kCdfShape +0 +83, WebRtcIsacfix_kCdfShape +0 +86, WebRtcIsacfix_kCdfShape +0 +90, + WebRtcIsacfix_kCdfShape +0 +94, WebRtcIsacfix_kCdfShape +0 +98, WebRtcIsacfix_kCdfShape +0 +102, + WebRtcIsacfix_kCdfShape +0 +107, WebRtcIsacfix_kCdfShape +0 +113, WebRtcIsacfix_kCdfShape +0 +120, + WebRtcIsacfix_kCdfShape +0 +129, WebRtcIsacfix_kCdfShape +0 +131, WebRtcIsacfix_kCdfShape +0 +133, + WebRtcIsacfix_kCdfShape +0 +135, WebRtcIsacfix_kCdfShape +0 +137, WebRtcIsacfix_kCdfShape +0 +141, + WebRtcIsacfix_kCdfShape +0 +143, WebRtcIsacfix_kCdfShape +0 +147, WebRtcIsacfix_kCdfShape +0 +151, + WebRtcIsacfix_kCdfShape +0 +155, WebRtcIsacfix_kCdfShape +0 +159, WebRtcIsacfix_kCdfShape +0 +164, + WebRtcIsacfix_kCdfShape +0 +168, WebRtcIsacfix_kCdfShape +0 +172, WebRtcIsacfix_kCdfShape +0 +178, + WebRtcIsacfix_kCdfShape +0 +184, WebRtcIsacfix_kCdfShape +0 +192, WebRtcIsacfix_kCdfShape +0 +200, + WebRtcIsacfix_kCdfShape +0 +211, WebRtcIsacfix_kCdfShape +0 +213, WebRtcIsacfix_kCdfShape +0 +215, + WebRtcIsacfix_kCdfShape +0 +217, WebRtcIsacfix_kCdfShape +0 +219, WebRtcIsacfix_kCdfShape +0 +223, + WebRtcIsacfix_kCdfShape +0 +227, WebRtcIsacfix_kCdfShape +0 +231, WebRtcIsacfix_kCdfShape +0 +235, + WebRtcIsacfix_kCdfShape +0 +239, WebRtcIsacfix_kCdfShape +0 +243, WebRtcIsacfix_kCdfShape +0 +248, + WebRtcIsacfix_kCdfShape +0 +252, WebRtcIsacfix_kCdfShape +0 +258, WebRtcIsacfix_kCdfShape +0 +264, + WebRtcIsacfix_kCdfShape +0 +273, WebRtcIsacfix_kCdfShape +0 +282, WebRtcIsacfix_kCdfShape +0 +293, + WebRtcIsacfix_kCdfShape +0 +308, WebRtcIsacfix_kCdfShape +0 +310, WebRtcIsacfix_kCdfShape +0 +312, + WebRtcIsacfix_kCdfShape +0 +316, WebRtcIsacfix_kCdfShape +0 +320, WebRtcIsacfix_kCdfShape +0 +324, + WebRtcIsacfix_kCdfShape +0 +328, WebRtcIsacfix_kCdfShape +0 +332, WebRtcIsacfix_kCdfShape +0 +336, + WebRtcIsacfix_kCdfShape +0 +341, WebRtcIsacfix_kCdfShape +0 +347, WebRtcIsacfix_kCdfShape +0 +354, + WebRtcIsacfix_kCdfShape +0 +360, WebRtcIsacfix_kCdfShape +0 +368, WebRtcIsacfix_kCdfShape +0 +378, + WebRtcIsacfix_kCdfShape +0 +388, WebRtcIsacfix_kCdfShape +0 +400, WebRtcIsacfix_kCdfShape +0 +418, + WebRtcIsacfix_kCdfShape +0 +445, WebRtcIsacfix_kCdfShape +0 +447, WebRtcIsacfix_kCdfShape +0 +451, + WebRtcIsacfix_kCdfShape +0 +455, WebRtcIsacfix_kCdfShape +0 +461, WebRtcIsacfix_kCdfShape +0 +468, + WebRtcIsacfix_kCdfShape +0 +474, WebRtcIsacfix_kCdfShape +0 +480, WebRtcIsacfix_kCdfShape +0 +486, + WebRtcIsacfix_kCdfShape +0 +495, WebRtcIsacfix_kCdfShape +0 +505, WebRtcIsacfix_kCdfShape +0 +516, + WebRtcIsacfix_kCdfShape +0 +528, WebRtcIsacfix_kCdfShape +0 +543, WebRtcIsacfix_kCdfShape +0 +564, + WebRtcIsacfix_kCdfShape +0 +583, WebRtcIsacfix_kCdfShape +0 +608, WebRtcIsacfix_kCdfShape +0 +635 + }, + { WebRtcIsacfix_kCdfShape +686 +0, WebRtcIsacfix_kCdfShape +686 +2, WebRtcIsacfix_kCdfShape +686 +4, + WebRtcIsacfix_kCdfShape +686 +6, WebRtcIsacfix_kCdfShape +686 +8, WebRtcIsacfix_kCdfShape +686 +11, + WebRtcIsacfix_kCdfShape +686 +13, WebRtcIsacfix_kCdfShape +686 +15, WebRtcIsacfix_kCdfShape +686 +17, + WebRtcIsacfix_kCdfShape +686 +20, WebRtcIsacfix_kCdfShape +686 +23, WebRtcIsacfix_kCdfShape +686 +27, + WebRtcIsacfix_kCdfShape +686 +31, WebRtcIsacfix_kCdfShape +686 +35, WebRtcIsacfix_kCdfShape +686 +40, + WebRtcIsacfix_kCdfShape +686 +44, WebRtcIsacfix_kCdfShape +686 +50, WebRtcIsacfix_kCdfShape +686 +56, + WebRtcIsacfix_kCdfShape +686 +63, WebRtcIsacfix_kCdfShape +686 +65, WebRtcIsacfix_kCdfShape +686 +67, + WebRtcIsacfix_kCdfShape +686 +69, WebRtcIsacfix_kCdfShape +686 +71, WebRtcIsacfix_kCdfShape +686 +73, + WebRtcIsacfix_kCdfShape +686 +75, WebRtcIsacfix_kCdfShape +686 +77, WebRtcIsacfix_kCdfShape +686 +79, + WebRtcIsacfix_kCdfShape +686 +82, WebRtcIsacfix_kCdfShape +686 +85, WebRtcIsacfix_kCdfShape +686 +89, + WebRtcIsacfix_kCdfShape +686 +93, WebRtcIsacfix_kCdfShape +686 +97, WebRtcIsacfix_kCdfShape +686 +102, + WebRtcIsacfix_kCdfShape +686 +106, WebRtcIsacfix_kCdfShape +686 +112, WebRtcIsacfix_kCdfShape +686 +119, + WebRtcIsacfix_kCdfShape +686 +127, WebRtcIsacfix_kCdfShape +686 +129, WebRtcIsacfix_kCdfShape +686 +131, + WebRtcIsacfix_kCdfShape +686 +133, WebRtcIsacfix_kCdfShape +686 +135, WebRtcIsacfix_kCdfShape +686 +137, + WebRtcIsacfix_kCdfShape +686 +139, WebRtcIsacfix_kCdfShape +686 +142, WebRtcIsacfix_kCdfShape +686 +146, + WebRtcIsacfix_kCdfShape +686 +150, WebRtcIsacfix_kCdfShape +686 +154, WebRtcIsacfix_kCdfShape +686 +158, + WebRtcIsacfix_kCdfShape +686 +162, WebRtcIsacfix_kCdfShape +686 +167, WebRtcIsacfix_kCdfShape +686 +173, + WebRtcIsacfix_kCdfShape +686 +179, WebRtcIsacfix_kCdfShape +686 +186, WebRtcIsacfix_kCdfShape +686 +194, + WebRtcIsacfix_kCdfShape +686 +205, WebRtcIsacfix_kCdfShape +686 +207, WebRtcIsacfix_kCdfShape +686 +209, + WebRtcIsacfix_kCdfShape +686 +211, WebRtcIsacfix_kCdfShape +686 +214, WebRtcIsacfix_kCdfShape +686 +218, + WebRtcIsacfix_kCdfShape +686 +222, WebRtcIsacfix_kCdfShape +686 +226, WebRtcIsacfix_kCdfShape +686 +230, + WebRtcIsacfix_kCdfShape +686 +234, WebRtcIsacfix_kCdfShape +686 +238, WebRtcIsacfix_kCdfShape +686 +242, + WebRtcIsacfix_kCdfShape +686 +247, WebRtcIsacfix_kCdfShape +686 +253, WebRtcIsacfix_kCdfShape +686 +262, + WebRtcIsacfix_kCdfShape +686 +269, WebRtcIsacfix_kCdfShape +686 +278, WebRtcIsacfix_kCdfShape +686 +289, + WebRtcIsacfix_kCdfShape +686 +305, WebRtcIsacfix_kCdfShape +686 +307, WebRtcIsacfix_kCdfShape +686 +309, + WebRtcIsacfix_kCdfShape +686 +311, WebRtcIsacfix_kCdfShape +686 +315, WebRtcIsacfix_kCdfShape +686 +319, + WebRtcIsacfix_kCdfShape +686 +323, WebRtcIsacfix_kCdfShape +686 +327, WebRtcIsacfix_kCdfShape +686 +331, + WebRtcIsacfix_kCdfShape +686 +335, WebRtcIsacfix_kCdfShape +686 +340, WebRtcIsacfix_kCdfShape +686 +346, + WebRtcIsacfix_kCdfShape +686 +354, WebRtcIsacfix_kCdfShape +686 +362, WebRtcIsacfix_kCdfShape +686 +374, + WebRtcIsacfix_kCdfShape +686 +384, WebRtcIsacfix_kCdfShape +686 +396, WebRtcIsacfix_kCdfShape +686 +413, + WebRtcIsacfix_kCdfShape +686 +439, WebRtcIsacfix_kCdfShape +686 +442, WebRtcIsacfix_kCdfShape +686 +446, + WebRtcIsacfix_kCdfShape +686 +450, WebRtcIsacfix_kCdfShape +686 +455, WebRtcIsacfix_kCdfShape +686 +461, + WebRtcIsacfix_kCdfShape +686 +468, WebRtcIsacfix_kCdfShape +686 +475, WebRtcIsacfix_kCdfShape +686 +481, + WebRtcIsacfix_kCdfShape +686 +489, WebRtcIsacfix_kCdfShape +686 +498, WebRtcIsacfix_kCdfShape +686 +508, + WebRtcIsacfix_kCdfShape +686 +522, WebRtcIsacfix_kCdfShape +686 +534, WebRtcIsacfix_kCdfShape +686 +554, + WebRtcIsacfix_kCdfShape +686 +577, WebRtcIsacfix_kCdfShape +686 +602, WebRtcIsacfix_kCdfShape +686 +631 + }, + { WebRtcIsacfix_kCdfShape +1368 +0, WebRtcIsacfix_kCdfShape +1368 +2, WebRtcIsacfix_kCdfShape +1368 +4, + WebRtcIsacfix_kCdfShape +1368 +6, WebRtcIsacfix_kCdfShape +1368 +8, WebRtcIsacfix_kCdfShape +1368 +10, + WebRtcIsacfix_kCdfShape +1368 +12, WebRtcIsacfix_kCdfShape +1368 +14, WebRtcIsacfix_kCdfShape +1368 +16, + WebRtcIsacfix_kCdfShape +1368 +20, WebRtcIsacfix_kCdfShape +1368 +24, WebRtcIsacfix_kCdfShape +1368 +28, + WebRtcIsacfix_kCdfShape +1368 +32, WebRtcIsacfix_kCdfShape +1368 +36, WebRtcIsacfix_kCdfShape +1368 +40, + WebRtcIsacfix_kCdfShape +1368 +44, WebRtcIsacfix_kCdfShape +1368 +50, WebRtcIsacfix_kCdfShape +1368 +57, + WebRtcIsacfix_kCdfShape +1368 +65, WebRtcIsacfix_kCdfShape +1368 +67, WebRtcIsacfix_kCdfShape +1368 +69, + WebRtcIsacfix_kCdfShape +1368 +71, WebRtcIsacfix_kCdfShape +1368 +73, WebRtcIsacfix_kCdfShape +1368 +75, + WebRtcIsacfix_kCdfShape +1368 +77, WebRtcIsacfix_kCdfShape +1368 +79, WebRtcIsacfix_kCdfShape +1368 +81, + WebRtcIsacfix_kCdfShape +1368 +85, WebRtcIsacfix_kCdfShape +1368 +89, WebRtcIsacfix_kCdfShape +1368 +93, + WebRtcIsacfix_kCdfShape +1368 +97, WebRtcIsacfix_kCdfShape +1368 +101, WebRtcIsacfix_kCdfShape +1368 +105, + WebRtcIsacfix_kCdfShape +1368 +110, WebRtcIsacfix_kCdfShape +1368 +116, WebRtcIsacfix_kCdfShape +1368 +123, + WebRtcIsacfix_kCdfShape +1368 +132, WebRtcIsacfix_kCdfShape +1368 +134, WebRtcIsacfix_kCdfShape +1368 +136, + WebRtcIsacfix_kCdfShape +1368 +138, WebRtcIsacfix_kCdfShape +1368 +141, WebRtcIsacfix_kCdfShape +1368 +143, + WebRtcIsacfix_kCdfShape +1368 +146, WebRtcIsacfix_kCdfShape +1368 +150, WebRtcIsacfix_kCdfShape +1368 +154, + WebRtcIsacfix_kCdfShape +1368 +158, WebRtcIsacfix_kCdfShape +1368 +162, WebRtcIsacfix_kCdfShape +1368 +166, + WebRtcIsacfix_kCdfShape +1368 +170, WebRtcIsacfix_kCdfShape +1368 +174, WebRtcIsacfix_kCdfShape +1368 +179, + WebRtcIsacfix_kCdfShape +1368 +185, WebRtcIsacfix_kCdfShape +1368 +193, WebRtcIsacfix_kCdfShape +1368 +203, + WebRtcIsacfix_kCdfShape +1368 +214, WebRtcIsacfix_kCdfShape +1368 +216, WebRtcIsacfix_kCdfShape +1368 +218, + WebRtcIsacfix_kCdfShape +1368 +220, WebRtcIsacfix_kCdfShape +1368 +224, WebRtcIsacfix_kCdfShape +1368 +227, + WebRtcIsacfix_kCdfShape +1368 +231, WebRtcIsacfix_kCdfShape +1368 +235, WebRtcIsacfix_kCdfShape +1368 +239, + WebRtcIsacfix_kCdfShape +1368 +243, WebRtcIsacfix_kCdfShape +1368 +247, WebRtcIsacfix_kCdfShape +1368 +251, + WebRtcIsacfix_kCdfShape +1368 +256, WebRtcIsacfix_kCdfShape +1368 +262, WebRtcIsacfix_kCdfShape +1368 +269, + WebRtcIsacfix_kCdfShape +1368 +277, WebRtcIsacfix_kCdfShape +1368 +286, WebRtcIsacfix_kCdfShape +1368 +297, + WebRtcIsacfix_kCdfShape +1368 +315, WebRtcIsacfix_kCdfShape +1368 +317, WebRtcIsacfix_kCdfShape +1368 +319, + WebRtcIsacfix_kCdfShape +1368 +323, WebRtcIsacfix_kCdfShape +1368 +327, WebRtcIsacfix_kCdfShape +1368 +331, + WebRtcIsacfix_kCdfShape +1368 +335, WebRtcIsacfix_kCdfShape +1368 +339, WebRtcIsacfix_kCdfShape +1368 +343, + WebRtcIsacfix_kCdfShape +1368 +349, WebRtcIsacfix_kCdfShape +1368 +355, WebRtcIsacfix_kCdfShape +1368 +361, + WebRtcIsacfix_kCdfShape +1368 +368, WebRtcIsacfix_kCdfShape +1368 +376, WebRtcIsacfix_kCdfShape +1368 +385, + WebRtcIsacfix_kCdfShape +1368 +397, WebRtcIsacfix_kCdfShape +1368 +411, WebRtcIsacfix_kCdfShape +1368 +429, + WebRtcIsacfix_kCdfShape +1368 +456, WebRtcIsacfix_kCdfShape +1368 +459, WebRtcIsacfix_kCdfShape +1368 +463, + WebRtcIsacfix_kCdfShape +1368 +467, WebRtcIsacfix_kCdfShape +1368 +473, WebRtcIsacfix_kCdfShape +1368 +478, + WebRtcIsacfix_kCdfShape +1368 +485, WebRtcIsacfix_kCdfShape +1368 +491, WebRtcIsacfix_kCdfShape +1368 +497, + WebRtcIsacfix_kCdfShape +1368 +505, WebRtcIsacfix_kCdfShape +1368 +514, WebRtcIsacfix_kCdfShape +1368 +523, + WebRtcIsacfix_kCdfShape +1368 +535, WebRtcIsacfix_kCdfShape +1368 +548, WebRtcIsacfix_kCdfShape +1368 +565, + WebRtcIsacfix_kCdfShape +1368 +585, WebRtcIsacfix_kCdfShape +1368 +611, WebRtcIsacfix_kCdfShape +1368 +640 + } +}; + +/* code length for all coefficients using different models */ + +const WebRtc_Word16 WebRtcIsacfix_kCodeLenGainQ11[392] = { + 25189, 16036, 8717, 358, 8757, 15706, 21456, 24397, 18502, 17559 + , 13794, 11088, 7480, 873, 6603, 11636, 14627, 16805, 19132, 26624 + , 26624, 19408, 13751, 7280, 583, 7591, 15178, 23773, 28672, 25189 + , 19045, 16442, 13412, 10397, 5893, 1338, 6376, 9992, 12074, 13853 + , 15781, 19821, 22819, 28672, 28672, 25189, 19858, 15781, 11262, 5477 + , 1298, 5632, 11814, 17234, 22020, 28672, 19677, 18125, 16587, 14521 + , 13032, 11196, 9249, 5411, 2495, 4994, 7975, 10234, 12308, 13892 + , 15148, 17944, 21725, 23917, 25189, 19539, 16293, 11531, 7808, 4475 + , 2739, 4872, 8089, 11314, 14992, 18105, 23257, 26624, 25189, 23257 + , 23257, 20982, 18697, 18023, 16338, 16036, 14539, 13695, 13146, 11763 + , 10754, 9074, 7260, 5584, 4430, 5553, 6848, 8344, 10141, 11636 + , 12535, 13416, 14342, 15477, 17296, 19282, 22349, 23773, 28672, 28672 + , 26624, 23773, 21456, 18023, 15118, 13362, 11212, 9293, 8043, 6985 + , 5908, 5721, 5853, 6518, 7316, 8360, 9716, 11289, 12912, 14652 + , 16969, 19858, 23773, 26624, 28013, 30720, 30720, 28672, 25426, 23141 + , 25426, 23773, 20720, 19408, 18697, 19282, 16859, 16338, 16026, 15377 + , 15021, 14319, 14251, 13937, 13260, 13017, 12332, 11703, 11430, 10359 + , 10128, 9405, 8757, 8223, 7974, 7859, 7646, 7673, 7997, 8580 + , 8880, 9061, 9866, 10397, 11358, 12200, 13244, 14157, 15021, 16026 + , 16490, 18697, 18479, 20011, 19677, 20720, 24576, 26276, 30720, 30720 + , 28672, 30720, 24068, 25189, 22437, 20345, 18479, 16396, 16026, 14928 + , 13877, 13450, 12696, 12766, 11626, 11098, 10159, 9998, 9437, 9275 + , 8783, 8552, 8629, 8488, 8522, 8454, 8571, 8775, 8915, 9427 + , 9483, 9851, 10260, 10933, 11131, 11974, 12560, 13833, 15080, 16304 + , 17491, 19017, 18697, 19408, 22020, 25189, 25426, 22819, 26276, 30720 + , 30720, 30720, 30720, 30720, 30720, 28672, 30720, 30720, 30720, 30720 + , 28013, 25426, 24397, 23773, 25189, 26624, 25189, 22437, 21725, 20011 + , 20527, 20720, 20771, 22020, 22020, 19858, 19408, 19972, 17866, 17360 + , 17791, 17219, 16805, 16927, 16067, 16162, 15661, 15178, 15021, 15209 + , 14845, 14570, 14490, 14490, 13733, 13617, 13794, 13577, 13312, 12824 + , 13032, 12683, 12189, 12469, 12109, 11940, 11636, 11617, 11932, 12294 + , 11578, 11775, 12039, 11654, 11560, 11439, 11909, 11421, 12029, 11513 + , 11773, 11899, 11560, 11805, 11476, 11664, 11963, 11647, 11754, 11963 + , 11703, 12211, 11932, 12074, 12469, 12535, 12560, 12912, 12783, 12866 + , 12884, 13378, 13957, 13775, 13635, 14019, 14545, 15240, 15520, 15554 + , 15697, 16490, 16396, 17281, 16599, 16969, 17963, 16859, 16983, 16805 + , 17099, 18210, 17219, 17646, 17700, 17646, 18297, 17425, 18479, 17791 + , 17718, 19282, 18672, 20173, 20982, 21725, 21456, 23773, 23257, 25189 + , 30720, 30720, 25189, 26624, 30720, 30720, 30720, 30720, 28672, 26276 + , 30720, 30720 +}; + +const WebRtc_Word16 WebRtcIsacfix_kCodeLenShapeQ11[577] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 28672 + , 0, 26624, 1, 23773, 22819, 4, 20982, 18598, 10, 19282 + , 16587, 22, 16442, 26624, 13126, 60, 14245, 26624, 26624, 12736 + , 79, 12912, 25189, 22819, 9563, 249, 9474, 22349, 28672, 23257 + , 17944, 7980, 434, 8181, 16431, 26624, 0, 0, 0, 0 + , 28672, 0, 0, 0, 0, 0, 28672, 0, 22437, 3 + , 22437, 20982, 5, 20982, 16442, 22, 16752, 13814, 49, 14646 + , 11645, 116, 11734, 26624, 28672, 10613, 158, 11010, 24397, 19539 + , 8046, 453, 7709, 19017, 28672, 23257, 15110, 6770, 758, 6523 + , 14108, 24397, 28672, 0, 0, 0, 0, 28672, 0, 28672 + , 0, 26624, 1, 28672, 28672, 1, 26624, 24397, 2, 23257 + , 21725, 4, 20982, 17158, 18, 17281, 28672, 15178, 35, 15209 + , 12343, 92, 12320, 26624, 10344, 189, 10217, 30720, 22020, 9033 + , 322, 8549, 23773, 28672, 30720, 20622, 7666, 473, 7806, 20527 + , 24397, 14135, 5995, 960, 6018, 14872, 23773, 26624, 20928, 16293 + , 10636, 4926, 1588, 5256, 11088, 18043, 25189, 0, 0, 0 + , 0, 24397, 1, 25189, 20720, 5, 21456, 21209, 3, 25189 + , 20982, 5, 21456, 15818, 30, 15410, 13794, 60, 13416, 28672 + , 11162, 142, 11025, 9337, 231, 10094, 23773, 8338, 405, 7930 + , 26624, 19677, 6787, 613, 7318, 19161, 28672, 16442, 6319, 932 + , 5748, 15312, 25189, 28672, 28672, 28672, 13998, 5513, 1263, 5146 + , 14024, 24397, 22819, 15818, 9460, 4447, 2122, 4681, 9970, 15945 + , 22349, 28672, 30720, 22622, 19017, 14872, 10689, 7405, 4473, 2983 + , 4783, 7894, 11186, 14964, 18210, 24397, 0, 0, 30720, 0 + , 30720, 21456, 3, 23773, 14964, 39, 14757, 14179, 53, 13751 + , 14928, 36, 15272, 12430, 79, 13228, 9135, 285, 9077, 28672 + , 28672, 8377, 403, 7919, 26624, 28672, 23257, 7068, 560, 7473 + , 20345, 19677, 6770, 720, 6464, 18697, 25189, 16249, 5779, 1087 + , 5494, 15209, 22819, 30720, 20622, 12601, 5240, 1419, 5091, 12095 + , 19408, 26624, 22819, 16805, 10683, 4812, 2056, 4293, 9836, 16026 + , 24397, 25189, 18409, 13833, 8681, 4503, 2653, 4220, 8329, 13853 + , 19132, 26624, 25189, 20771, 17219, 12630, 9520, 6733, 4565, 3657 + , 4817, 7069, 10058, 13212, 16805, 21209, 26624, 26276, 28672, 28672 + , 26276, 23257, 20173, 19282, 16538, 15051, 12811, 10754, 9267, 7547 + , 6270, 5407, 5214, 6057, 7054, 8226, 9488, 10806, 12793, 14442 + , 16442, 19677, 22099, 26276, 28672, 0, 30720, 0, 30720, 11920 + , 56, 20720, 30720, 6766, 355, 13130, 30720, 30720, 22180, 5589 + , 736, 7902, 26624, 30720, 7634, 354, 9721, 30720, 30720, 9027 + , 246, 10117, 30720, 30720, 9630, 453, 6709, 23257, 30720, 25683 + , 14228, 6127, 1271, 4615, 15178, 30720, 30720, 23504, 12382, 5739 + , 2015, 3492, 10560, 22020, 26624, 30720, 30720, 23257, 13192, 4873 + , 1527, 5001, 12445, 22020, 30720, 30720, 30720, 30720, 19344, 10761 + , 4051, 1927, 5281, 10594, 17866, 28672, 30720, 30720, 30720, 21869 + , 15554, 10060, 5979, 2710, 3085, 7889, 14646, 21725, 28672, 30720 + , 30720, 30720, 30720, 30720, 30720, 30720, 22719, 17425, 13212, 8083 + , 4439, 2820, 4305, 8136, 12988, 17425, 21151, 28672, 28672, 30720 + , 30720, 30720, 28672, 20527, 19282, 14412, 10513, 7407, 5079, 3744 + , 4115, 6308, 9621, 13599, 17040, 22349, 28672, 30720, 30720, 30720 + , 30720, 30720, 30720, 29522, 19282, 14545, 11485, 9093, 6760, 5262 + , 4672, 4970, 6005, 7852, 9732, 12343, 14672, 19161, 22819, 25189 + , 30720, 30720, 28672, 30720, 30720, 20720, 18125, 14388, 12007, 9825 + , 8092, 7064, 6069, 5903, 5932, 6359, 7169, 8310, 9324, 10711 + , 11867, 13096, 14157, 16338, 17040, 19161, 21725, 23773, 30720, 30720 + , 26276, 25426, 24397, 28672, 28672, 23257, 22020, 22349, 18297, 17646 + , 16983, 16431, 16162, 15021, 15178, 13751, 12142, 10895, 10193, 9632 + , 9086, 8896, 8823, 8735, 8591, 8754, 8649, 8361, 8329, 8522 + , 8373, 8739, 8993, 9657, 10454, 11279, 11899, 12614, 14024, 14273 + , 15477, 15240, 16649, 17866, 18697, 21151, 22099 +}; + +/* left KLT transforms */ +const WebRtc_Word16 WebRtcIsacfix_kT1GainQ15[3][4] = { + { -26130, 19773, 19773, 26130 }, + { -26664, 19046, 19046, 26664 }, + { -23538, 22797, 22797, 23538 } +}; + + + +const WebRtc_Word16 WebRtcIsacfix_kT1ShapeQ15[3][324] = { + { 52,16,168,7,439,-138,-89,306,671,882, + 157,1301,291,1598,-3571,-1943,-1119,32404,96,-12, + 379,-64,-307,345,-836,539,1045,2541,-2865,-992, + 1683,-4717,5808,7427,30599,2319,183,-73,451,481, + 933,-198,781,-397,1244,-777,3690,-2414,149,-1356, + -2593,-31140,8289,-1737,-202,-14,-214,360,501,450, + -245,-7,797,3638,-2804,3042,-337,22137,-22103,2264, + 6838,-3381,305,172,263,-195,-355,351,179,513, + 2234,3343,5509,7531,19075,-17740,-16836,2244,-629,-1505, + -153,108,124,-324,2694,-124,1492,-850,5347,4285, + 7439,-10229,-22822,-12467,-12891,3645,822,-232,131,13, + 374,565,536,4681,1294,-1935,1926,-5734,-10643,26462, + -12480,-5589,-1038,-2468,964,-704,-247,-106,186,-558, + -4050,3760,2972,2141,-7393,6294,26740,11991,-3251,5461, + 5341,1574,2208,-51,-552,-297,-753,-154,2068,-5371, + 3578,4106,28043,-10533,8041,2353,2389,4609,3410,1906, + 351,-249,18,-15,1117,539,2870,9084,17585,-24528, + -366,-6490,2009,-3170,2942,1116,-232,1672,1065,606, + -399,-388,-518,38,3728,28948,-11936,4543,4104,-4441, + 1545,-4044,1485,622,-68,186,-473,135,-280,125, + -546,-1813,6989,6606,23711,19376,-2636,2870,-4553,-1687, + 878,-375,205,-208,-409,-108,-200,-45,-1670,-337, + 8213,-5524,-2334,5240,-12939,-26205,5937,-1582,-592,-959, + -5374,2449,3400,559,349,-492,668,12379,-27684,3419, + 5117,4415,-297,-8270,-1252,-3490,-1272,-1199,-3159,191, + 630,488,-797,-3071,12912,-27783,-10249,1047,647,619, + 111,-3722,-915,-1055,-502,5,-1384,-306,221,68, + 5219,13173,-26474,-11663,-5626,927,806,-1127,236,-589, + -522,-230,-312,-315,-428,-573,426,192,-11830,-26883, + -14121,-2785,-1429,-109,410,-832,-302,539,-459,104, + 1,-530,-202,-289,153,116,30082,-12944,-671,20, + 649,98,103,215,234,0,280,-51,-169,298, + 31,230,-73,-51 + }, + { -154,-7,-192,61,-739,-389,-947,-162,-60,94, + 511,-716,1520,-1428,4168,-2214,1816,32270,-123,-77, + -199,-99,-42,-588,203,-240,-930,-35,1580,234, + 3206,-5507,-1495,-10946,30000,-2667,-136,-176,-240,-175, + -204,-661,-1796,-1039,-1271,498,3143,734,2663,2699, + -8127,29333,10495,2356,-72,113,-91,118,-2840,-723, + -1733,-1158,-389,-2116,-3054,-3,-5179,8071,29546,6308, + 5657,-3178,-186,-294,-473,-635,1213,-983,-1437,-1715, + -1094,1280,-92,-9573,948,29576,-7060,-5921,2954,1349, + -337,-108,-1099,962,418,-413,-1149,-334,1241,3975, + -6825,26725,-14377,7051,-4772,-1707,2335,2008,-150,570, + 1371,42,-1649,-619,2039,3369,-1225,1583,-2755,-15207, + -27504,-4855,-4304,1495,2733,1324,15,-448,403,353, + 3016,-1242,2338,2673,2064,-7496,-30447,-3686,5833,-1301, + -2455,2122,1519,608,43,-653,773,-3072,912,-1537, + 4505,10284,30237,1549,3200,-691,205,1702,658,1014, + 1499,148,79,-322,-1162,-4639,-813,7536,3204,29109, + -10747,-26,1611,2286,2114,2561,1022,372,348,207, + 1062,-1088,-443,-9849,2381,5671,29097,-7612,-2927,3853, + 194,1155,275,1438,1438,1312,581,888,-784,906, + 112,-11103,25104,14438,-9311,-3068,1210,368,370,-940, + -2434,-1148,1925,392,657,258,-526,1475,-2281,-4265, + -1880,1534,2185,-1472,959,-30934,6306,3114,-4109,1768, + -2612,-703,45,644,2185,2033,5670,7211,19114,-22427, + 6432,5150,-4090,-2694,3860,1245,-596,293,1829,369, + -319,229,-3256,2170,-6374,-26216,-4570,-16053,-5766,-262, + -2006,2873,-1477,147,378,-1544,-344,-544,-985,-481, + 4210,4542,30757,-7291,-4863,1529,-2079,-628,-603,-783, + -408,1646,697,808,-620,-292,181,158,-13313,-29173, + 5984,-1262,859,-1776,-558,-24,-883,-1421,739,210, + -531,-285,131,-160,-246,-56,29345,-13706,-2859,-2966, + -300,-970,-2382,-268,-103,-636,-12,-62,-691,-253, + -147,-127,27,66 + }, + { 55,-212,-198,489,-274,81,682,399,328,-934, + -389,-37,1357,-3632,5276,6581,-9493,-29921,29,-45, + 2,190,172,-15,311,-130,-1085,-25,324,-684, + 3223,-6580,4485,-5280,-29521,9933,82,-320,-530,229, + -705,-533,-414,848,-1842,-4473,1390,-857,6717,-6692, + 4648,29397,576,8339,-68,-85,238,-330,264,-1012, + -381,-203,-3384,-3329,3906,6810,3790,-6250,28312,-8078, + 8089,1565,160,-569,-612,-613,-1063,-1928,-1125,3421, + -7481,-7484,4942,-6984,4330,-25591,-10574,-6982,5682,-1781, + -308,89,178,-1715,-420,-3530,-5776,1219,-8617,-7137, + 7015,4981,24875,12657,-5408,-3356,-785,-1972,326,-858, + -506,-3382,-986,-6258,-2259,4015,-8374,-10482,3127,23826, + -14126,-514,-5417,2178,-2912,-17,-587,80,67,-5881, + -1702,-5351,-4481,398,-10156,-225,20727,-15460,-11603,7752, + 3660,1714,-2001,-359,499,-527,-1225,-7820,-1297,-6326, + -8526,7900,-18328,13311,-17488,-2926,-196,-17,2281,873, + 480,-160,-624,471,780,-8729,1707,-14262,-20647,1721, + 18590,-2206,-1214,-1066,312,-2602,783,-412,-113,49, + -119,1305,-2371,-15132,-1833,-18252,20295,-8316,2227,341, + -2074,-702,3082,-262,-465,-198,430,30,-70,-788, + 2342,-25132,-4863,19783,-484,2137,2811,-1906,799,1586, + 962,-734,-191,-30,-129,-93,-1126,1729,5860,-2030, + 8953,603,-3338,-10869,-1144,22070,12130,10513,3191,-6881, + -3514,2090,711,-666,1843,-5997,-5681,2921,-17641,-2801, + 4969,18590,7169,12214,8587,4405,3008,-1074,-371,-77, + 253,331,-5611,5014,13152,-1985,18483,-1696,8043,20463, + 2381,-393,1688,-1205,618,1220,457,248,-83,176, + 7920,-13676,-22139,-3038,17402,2036,844,3258,994,719, + 2087,-44,426,494,12,-91,46,5,-14204,22912, + -18156,-361,442,2298,-829,2229,386,1433,1335,1323, + 55,-592,-139,49,-12,-57,27783,17134,350,-282, + 552,158,142,2488,465,329,1087,118,143,10, + 56,65,-15,-31 + } +}; + +/* right KLT transforms */ +const WebRtc_Word16 WebRtcIsacfix_kT2GainQ15[3][36] = { + { 4775, -14892, 20313, -17104, 10533, -3613, -6782, 16044, -8889, + -11019, 21330, -10720, 13193, -15678, -11101, 14461, 12250, -13096, + -16951, 2167, 16066, 15569, -702, -16754, -19195, -12823, -4321, + 5128, 13348, 17825, 13232, 13404, 13494, 13490, 13383, 13261 + }, + { -3725, 11408, -18493, 20031, -13097, 3865, 9344, -19294, 10740, + 8856, -18432, 8982, 13975, -14444, -11930, 11774, 14285, -13594, + -16323, -4, 16340, 15609, 359, -17220, -18401, -13471, -4643, + 5225, 13375, 18053, 13124, 13463, 13621, 13583, 13393, 13072 + }, + { -3513, 11402, -17883, 19504, -14399, 4885, 8702, -19513, 12046, + 8533, -18110, 8447, 12778, -14838, -12444, 13177, 14107, -12759, + -17268, 914, 15822, 15661, 838, -16686, -18907, -12936, -4820, + 4175, 12398, 18830, 12913, 13215, 13433, 13572, 13601, 13518 + } +}; + +const WebRtc_Word16 WebRtcIsacfix_kT2ShapeQ15[3][36] = { + { 4400, -11512, 17205, -19470, 14770, -5345, 9784, -19222, 11228, + 6842, -18371, 9909, 14191, -13496, -11563, 14015, 11827, -14839, + -15439, 948, 17802, 14827, -2053, -17132, 18723, 14516, 4135, + -6822, -13869, -16016, 12975, 13341, 13563, 13603, 13478, 13296 + }, + { 5420, -14215, 19060, -18073, 11709, -3911, 9645, -18335, 7717, + 10842, -19283, 9777, 14898, -12555, -13661, 11668, 13520, -13733, + -15936, -1358, 15671, 16728, 328, -17100, 17527, 13973, 5587, + -5194, -14165, -17677, 12970, 13446, 13693, 13660, 13462, 13015 + }, + { 4386, -12426, 18019, -18895, 13894, -5034, 9713, -19270, 10283, + 8692, -18439, 9317, 13992, -13454, -13241, 12850, 13366, -13336, + -16334, -498, 15976, 16213, -114, -16987, 18191, 13659, 4958, + -5116, -13444, -18021, 12911, 13424, 13718, 13674, 13464, 13054 + } +}; + +/* means of log gains and LAR coefficients*/ +const WebRtc_Word16 WebRtcIsacfix_kMeansGainQ8[3][12] = { + { -1758, -1370, -1758, -1373, -1757, -1375, + -1758, -1374, -1758, -1373, -1755, -1370 + }, + { -1569, -1224, -1569, -1225, -1569, -1227, + -1569, -1226, -1567, -1225, -1565, -1224 + }, + { -1452, -957, -1447, -951, -1438, -944, + -1431, -938, -1419, -931, -1406, -926 + } +}; + + +const WebRtc_Word32 WebRtcIsacfix_kMeansShapeQ17[3][108] = { + { -119581, 34418, -44193, 11112, -4428, 18906, 9222, 8068, 1953, 5425, + 1871, 1689, 109933, 33751, 10471, -2566, 1090, 2320, -119219, 33728, + -43759, 11450, -4870, 19117, 9174, 8037, 1972, 5331, 1872, 1843, + 109899, 34301, 10629, -2316, 1272, 2562, -118608, 32318, -44012, 11591, + -4914, 18932, 9456, 8088, 1900, 5419, 1723, 1853, 109963, 35059, + 10745, -2335, 1161, 2520, -119174, 32107, -44462, 11635, -4694, 18611, + 9757, 8108, 1969, 5486, 1673, 1777, 109636, 34907, 10643, -2406, + 1034, 2420, -118597, 32320, -44590, 10854, -4569, 18821, 9701, 7866, + 2003, 5577, 1732, 1626, 109913, 34448, 10714, -2752, 990, 2228, + -118138, 32996, -44352, 10334, -3772, 18488, 9464, 7865, 2208, 5540, + 1745, 1664, 109880, 33381, 10640, -2779, 980, 2054 + }, + { -146328, 46370, 1047, 26431, 10035, 13933, 6415, 14359, -2368, 6661, + 2269, 1764, 96623, 7802, 4163, 10742, 1643, 2954, -146871, 46561, 1127, + 26225, 10113, 14096, 6771, 14323, -2037, 6788, 2297, 1761, 96324, 8382, + 4309, 10450, 1695, 3016, -146502, 46475, 1580, 26118, 10487, 14179, 6622, + 14439, -2034, 6757, 2342, 1761, 95869, 8966, 4347, 10358, 1999, 2855, + -146958, 47717, 826, 25952, 10263, 14061, 5266, 13681, -2417, 6582, 2047, + 1608, 96257, 9107, 4452, 10301, 1792, 2676, -146992, 47123, 446, 25822, + 10405, 14292, 5140, 13804, -2403, 6496, 1834, 1735, 97489, 9253, 4414, + 10684, 1549, 2721, -145811, 46182, 901, 26482, 10241, 14524, 6075, 14514, + -2147, 6691, 2196, 1899, 97011, 8178, 4102, 10758, 1638, 2869 + }, + { -166617, 46969, -43908, 17726, 6330, 25615, 6913, 5450, -2301, 1984, + 507, 2883, 149998, 28709, 19333, 16703, 11093, 8965, -168254, 46604, + -44315, 17862, 6474, 25746, 7018, 5373, -2343, 1930, 513, 2819, 150391, + 28627, 19194, 16678, 10998, 8929, -169093, 46084, -44767, 17427, 6401, + 25674, 7147, 5472, -2336, 1820, 491, 2802, 149860, 28430, 19064, 16524, + 10898, 8875, -170205, 46189, -44877, 17403, 6190, 25209, 7035, 5673, -2173, + 1894, 574, 2756, 148830, 28230, 18819, 16418, 10789, 8811, -171263, 45045, + -44834, 16858, 6103, 24726, 7014, 5713, -2103, 1877, 518, 2729, 147073, + 27744, 18629, 16277, 10690, 8703, -171720, 44153, -45062, 15951, 5872, + 24429, 7044, 5585, -2082, 1807, 519, 2769, 144791, 27402, 18490, 16126, + 10548, 8635 + } +}; diff --git a/src/libs/webrtc/isac/lpc_tables.h b/src/libs/webrtc/isac/lpc_tables.h new file mode 100644 index 00000000..4f2e0e7f --- /dev/null +++ b/src/libs/webrtc/isac/lpc_tables.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * lpc_tables.h + * + * header file for coding tables for the LPC coefficients + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_TABLES_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_TABLES_H_ + +#include "typedefs.h" + + +/* indices of KLT coefficients used */ +extern const WebRtc_UWord16 WebRtcIsacfix_kSelIndGain[12]; + +extern const WebRtc_UWord16 WebRtcIsacfix_kSelIndShape[108]; + +/* cdf array for model indicator */ +extern const WebRtc_UWord16 WebRtcIsacfix_kModelCdf[KLT_NUM_MODELS+1]; + +/* pointer to cdf array for model indicator */ +extern const WebRtc_UWord16 *WebRtcIsacfix_kModelCdfPtr[1]; + +/* initial cdf index for decoder of model indicator */ +extern const WebRtc_UWord16 WebRtcIsacfix_kModelInitIndex[1]; + +/* offset to go from rounded value to quantization index */ +extern const WebRtc_Word16 WebRtcIsacfix_kQuantMinGain[12]; + +extern const WebRtc_Word16 WebRtcIsacfix_kQuantMinShape[108]; + +/* maximum quantization index */ +extern const WebRtc_UWord16 WebRtcIsacfix_kMaxIndGain[12]; + +extern const WebRtc_UWord16 WebRtcIsacfix_kMaxIndShape[108]; + +/* index offset */ +extern const WebRtc_UWord16 WebRtcIsacfix_kOffsetGain[KLT_NUM_MODELS][12]; + +extern const WebRtc_UWord16 WebRtcIsacfix_kOffsetShape[KLT_NUM_MODELS][108]; + +/* initial cdf index for KLT coefficients */ +extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndexGain[KLT_NUM_MODELS][12]; + +extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndexShape[KLT_NUM_MODELS][108]; + +/* offsets for quantizer representation levels */ +extern const WebRtc_UWord16 WebRtcIsacfix_kOfLevelsGain[3]; + +extern const WebRtc_UWord16 WebRtcIsacfix_kOfLevelsShape[3]; + +/* quantizer representation levels */ +extern const WebRtc_Word32 WebRtcIsacfix_kLevelsGainQ17[1176]; + +extern const WebRtc_Word16 WebRtcIsacfix_kLevelsShapeQ10[1735]; + +/* cdf tables for quantizer indices */ +extern const WebRtc_UWord16 WebRtcIsacfix_kCdfGain[1212]; + +extern const WebRtc_UWord16 WebRtcIsacfix_kCdfShape[2059]; + +/* pointers to cdf tables for quantizer indices */ +extern const WebRtc_UWord16 *WebRtcIsacfix_kCdfGainPtr[KLT_NUM_MODELS][12]; + +extern const WebRtc_UWord16 *WebRtcIsacfix_kCdfShapePtr[KLT_NUM_MODELS][108]; + +/* code length for all coefficients using different models */ +extern const WebRtc_Word16 WebRtcIsacfix_kCodeLenGainQ11[392]; + +extern const WebRtc_Word16 WebRtcIsacfix_kCodeLenShapeQ11[577]; + +/* left KLT transforms */ +extern const WebRtc_Word16 WebRtcIsacfix_kT1GainQ15[KLT_NUM_MODELS][4]; + +extern const WebRtc_Word16 WebRtcIsacfix_kT1ShapeQ15[KLT_NUM_MODELS][324]; + +/* right KLT transforms */ +extern const WebRtc_Word16 WebRtcIsacfix_kT2GainQ15[KLT_NUM_MODELS][36]; + +extern const WebRtc_Word16 WebRtcIsacfix_kT2ShapeQ15[KLT_NUM_MODELS][36]; + +/* means of log gains and LAR coefficients */ +extern const WebRtc_Word16 WebRtcIsacfix_kMeansGainQ8[KLT_NUM_MODELS][12]; + +extern const WebRtc_Word32 WebRtcIsacfix_kMeansShapeQ17[3][108]; + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_TABLES_H_ */ diff --git a/src/libs/webrtc/isac/pitch_estimator.c b/src/libs/webrtc/isac/pitch_estimator.c new file mode 100644 index 00000000..1702098e --- /dev/null +++ b/src/libs/webrtc/isac/pitch_estimator.c @@ -0,0 +1,519 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * pitch_estimator.c + * + * Pitch filter functions + * + */ + +#include <string.h> + +#include "signal_processing_library.h" +#include "pitch_estimator.h" + +/* log2[0.2, 0.5, 0.98] in Q8 */ +static const WebRtc_Word16 kLogLagWinQ8[3] = { + -594, -256, -7 +}; + +/* [1 -0.75 0.25] in Q12 */ +static const WebRtc_Word16 kACoefQ12[3] = { + 4096, -3072, 1024 +}; + + + +static __inline WebRtc_Word32 Log2Q8( WebRtc_UWord32 x ) { + + WebRtc_Word32 zeros, lg2; + WebRtc_Word16 frac; + + zeros=WebRtcSpl_NormU32(x); + frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(((WebRtc_UWord32)(WEBRTC_SPL_LSHIFT_W32(x, zeros))&0x7FFFFFFF), 23); + /* log2(magn(i)) */ + + lg2= (WEBRTC_SPL_LSHIFT_W32((31-zeros), 8)+frac); + return lg2; + +} + +static __inline WebRtc_Word16 Exp2Q10(WebRtc_Word16 x) { // Both in and out in Q10 + + WebRtc_Word16 tmp16_1, tmp16_2; + + tmp16_2=(WebRtc_Word16)(0x0400|(x&0x03FF)); + tmp16_1=-(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(x,10); + if(tmp16_1>0) + return (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1); + else + return (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1); + +} + + + +/* 1D parabolic interpolation . All input and output values are in Q8 */ +static __inline void Intrp1DQ8(WebRtc_Word32 *x, WebRtc_Word32 *fx, WebRtc_Word32 *y, WebRtc_Word32 *fy) { + + WebRtc_Word16 sign1=1, sign2=1; + WebRtc_Word32 r32, q32, t32, nom32, den32; + WebRtc_Word16 t16, tmp16, tmp16_1; + + if ((fx[0]>0) && (fx[2]>0)) { + r32=fx[1]-fx[2]; + q32=fx[0]-fx[1]; + nom32=q32+r32; + den32=WEBRTC_SPL_MUL_32_16((q32-r32), 2); + if (nom32<0) + sign1=-1; + if (den32<0) + sign2=-1; + + /* t = (q32+r32)/(2*(q32-r32)) = (fx[0]-fx[1] + fx[1]-fx[2])/(2 * fx[0]-fx[1] - (fx[1]-fx[2]))*/ + /* (Signs are removed because WebRtcSpl_DivResultInQ31 can't handle negative numbers) */ + t32=WebRtcSpl_DivResultInQ31(WEBRTC_SPL_MUL_32_16(nom32, sign1),WEBRTC_SPL_MUL_32_16(den32, sign2)); /* t in Q31, without signs */ + + t16=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(t32, 23); /* Q8 */ + t16=t16*sign1*sign2; /* t in Q8 with signs */ + + *y = x[0]+t16; /* Q8 */ + // *y = x[1]+t16; /* Q8 */ + + /* The following code calculates fy in three steps */ + /* fy = 0.5 * t * (t-1) * fx[0] + (1-t*t) * fx[1] + 0.5 * t * (t+1) * fx[2]; */ + + /* Part I: 0.5 * t * (t-1) * fx[0] */ + tmp16_1=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16(t16,t16); /* Q8*Q8=Q16 */ + tmp16_1 = WEBRTC_SPL_RSHIFT_W16(tmp16_1,2); /* Q16>>2 = Q14 */ + t16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(t16, 64); /* Q8<<6 = Q14 */ + tmp16 = tmp16_1-t16; + *fy = WEBRTC_SPL_MUL_16_32_RSFT15(tmp16, fx[0]); /* (Q14 * Q8 >>15)/2 = Q8 */ + + /* Part II: (1-t*t) * fx[1] */ + tmp16 = 16384-tmp16_1; /* 1 in Q14 - Q14 */ + *fy += WEBRTC_SPL_MUL_16_32_RSFT14(tmp16, fx[1]);/* Q14 * Q8 >> 14 = Q8 */ + + /* Part III: 0.5 * t * (t+1) * fx[2] */ + tmp16 = tmp16_1+t16; + *fy += WEBRTC_SPL_MUL_16_32_RSFT15(tmp16, fx[2]);/* (Q14 * Q8 >>15)/2 = Q8 */ + } else { + *y = x[0]; + *fy= fx[1]; + } +} + + +static void FindFour32(WebRtc_Word32 *in, WebRtc_Word16 length, WebRtc_Word16 *bestind) +{ + WebRtc_Word32 best[4]= {-100, -100, -100, -100}; + WebRtc_Word16 k; + + for (k=0; k<length; k++) { + if (in[k] > best[3]) { + if (in[k] > best[2]) { + if (in[k] > best[1]) { + if (in[k] > best[0]) { // The Best + best[3] = best[2]; + bestind[3] = bestind[2]; + best[2] = best[1]; + bestind[2] = bestind[1]; + best[1] = best[0]; + bestind[1] = bestind[0]; + best[0] = in[k]; + bestind[0] = k; + } else { // 2nd best + best[3] = best[2]; + bestind[3] = bestind[2]; + best[2] = best[1]; + bestind[2] = bestind[1]; + best[1] = in[k]; + bestind[1] = k; + } + } else { // 3rd best + best[3] = best[2]; + bestind[3] = bestind[2]; + best[2] = in[k]; + bestind[2] = k; + } + } else { // 4th best + best[3] = in[k]; + bestind[3] = k; + } + } + } +} + + + + + +static void PCorr2Q32(const WebRtc_Word16 *in, WebRtc_Word32 *logcorQ8) +{ + WebRtc_Word16 scaling,n,k; + WebRtc_Word32 ysum32,csum32, lys, lcs; + WebRtc_Word32 prod32, oneQ8; + + + const WebRtc_Word16 *x, *inptr; + + oneQ8 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, 8); // 1.00 in Q8 + + x = in + PITCH_MAX_LAG/2 + 2; + scaling = WebRtcSpl_GetScalingSquare ((WebRtc_Word16 *) in, PITCH_CORR_LEN2, PITCH_CORR_LEN2); + ysum32 = 1; + csum32 = 0; + x = in + PITCH_MAX_LAG/2 + 2; + for (n = 0; n < PITCH_CORR_LEN2; n++) { + ysum32 += WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) in[n],(WebRtc_Word16) in[n], scaling); // Q0 + csum32 += WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) x[n],(WebRtc_Word16) in[n], scaling); // Q0 + } + + logcorQ8 += PITCH_LAG_SPAN2 - 1; + + lys=Log2Q8((WebRtc_UWord32) ysum32); // Q8 + lys=WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum); + + if (csum32>0) { + + lcs=Log2Q8((WebRtc_UWord32) csum32); // 2log(csum) in Q8 + + if (lcs>(lys + oneQ8) ){ // csum/sqrt(ysum) > 2 in Q8 + *logcorQ8 = lcs - lys; // log2(csum/sqrt(ysum)) + } else { + *logcorQ8 = oneQ8; // 1.00 + } + + } else { + *logcorQ8 = 0; + } + + + for (k = 1; k < PITCH_LAG_SPAN2; k++) { + inptr = &in[k]; + ysum32 -= WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) in[k-1],(WebRtc_Word16) in[k-1], scaling); + ysum32 += WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) in[PITCH_CORR_LEN2 + k - 1],(WebRtc_Word16) in[PITCH_CORR_LEN2 + k - 1], scaling); + csum32 = 0; + prod32 = WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) x[0],(WebRtc_Word16) inptr[0], scaling); + + for (n = 1; n < PITCH_CORR_LEN2; n++) { + csum32 += prod32; + prod32 = WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) x[n],(WebRtc_Word16) inptr[n], scaling); + } + + csum32 += prod32; + logcorQ8--; + + lys=Log2Q8((WebRtc_UWord32)ysum32); // Q8 + lys=WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum); + + if (csum32>0) { + + lcs=Log2Q8((WebRtc_UWord32) csum32); // 2log(csum) in Q8 + + if (lcs>(lys + oneQ8) ){ // csum/sqrt(ysum) > 2 + *logcorQ8 = lcs - lys; // log2(csum/sqrt(ysum)) + } else { + *logcorQ8 = oneQ8; // 1.00 + } + + } else { + *logcorQ8 = 0; + } + } +} + + + +void WebRtcIsacfix_InitialPitch(const WebRtc_Word16 *in, /* Q0 */ + PitchAnalysisStruct *State, + WebRtc_Word16 *lagsQ7 /* Q7 */ + ) +{ + WebRtc_Word16 buf_dec16[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2+2]; + WebRtc_Word32 *crrvecQ8_1,*crrvecQ8_2; + WebRtc_Word32 cv1q[PITCH_LAG_SPAN2+2],cv2q[PITCH_LAG_SPAN2+2], peakvq[PITCH_LAG_SPAN2+2]; + int k; + WebRtc_Word16 peaks_indq; + WebRtc_Word16 peakiq[PITCH_LAG_SPAN2]; + WebRtc_Word32 corr; + WebRtc_Word32 corr32, corr_max32, corr_max_o32; + WebRtc_Word16 npkq; + WebRtc_Word16 best4q[4]={0,0,0,0}; + WebRtc_Word32 xq[3],yq[1],fyq[1]; + WebRtc_Word32 *fxq; + WebRtc_Word32 best_lag1q, best_lag2q; + WebRtc_Word32 tmp32a,tmp32b,lag32,ratq; + WebRtc_Word16 start; + WebRtc_Word16 oldgQ12, tmp16a, tmp16b, gain_bias16,tmp16c, tmp16d, bias16; + WebRtc_Word32 tmp32c,tmp32d, tmp32e; + WebRtc_Word16 old_lagQ; + WebRtc_Word32 old_lagQ8; + WebRtc_Word32 lagsQ8[4]; + + old_lagQ = State->PFstr_wght.oldlagQ7; // Q7 + old_lagQ8= WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)old_lagQ,1); //Q8 + + oldgQ12= State->PFstr_wght.oldgainQ12; + + crrvecQ8_1=&cv1q[1]; + crrvecQ8_2=&cv2q[1]; + + + /* copy old values from state buffer */ + memcpy(buf_dec16, State->dec_buffer16, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), (PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2))); + + /* decimation; put result after the old values */ + WebRtcIsacfix_DecimateAllpass32(in, State->decimator_state32, PITCH_FRAME_LEN, + &buf_dec16[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2]); + + /* low-pass filtering */ + start= PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2; + WebRtcSpl_FilterARFastQ12(&buf_dec16[start],&buf_dec16[start],(WebRtc_Word16*)kACoefQ12,3, PITCH_FRAME_LEN/2); + + /* copy end part back into state buffer */ + for (k = 0; k < (PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2); k++) + State->dec_buffer16[k] = buf_dec16[k+PITCH_FRAME_LEN/2]; + + + /* compute correlation for first and second half of the frame */ + PCorr2Q32(buf_dec16, crrvecQ8_1); + PCorr2Q32(buf_dec16 + PITCH_CORR_STEP2, crrvecQ8_2); + + + /* bias towards pitch lag of previous frame */ + tmp32a = Log2Q8((WebRtc_UWord32) old_lagQ8) - 2304; // log2(0.5*oldlag) in Q8 + tmp32b = WEBRTC_SPL_MUL_16_16_RSFT(oldgQ12,oldgQ12, 10); //Q12 & * 4.0; + gain_bias16 = (WebRtc_Word16) tmp32b; //Q12 + if (gain_bias16 > 3276) gain_bias16 = 3276; // 0.8 in Q12 + + + for (k = 0; k < PITCH_LAG_SPAN2; k++) + { + if (crrvecQ8_1[k]>0) { + tmp32b = Log2Q8((WebRtc_UWord32) (k + (PITCH_MIN_LAG/2-2))); + tmp16a = (WebRtc_Word16) (tmp32b - tmp32a); // Q8 & fabs(ratio)<4 + tmp32c = WEBRTC_SPL_MUL_16_16_RSFT(tmp16a,tmp16a, 6); //Q10 + tmp16b = (WebRtc_Word16) tmp32c; // Q10 & <8 + tmp32d = WEBRTC_SPL_MUL_16_16_RSFT(tmp16b, 177 , 8); // mult with ln2 in Q8 + tmp16c = (WebRtc_Word16) tmp32d; // Q10 & <4 + tmp16d = Exp2Q10((WebRtc_Word16) -tmp16c); //Q10 + tmp32c = WEBRTC_SPL_MUL_16_16_RSFT(gain_bias16,tmp16d,13); // Q10 & * 0.5 + bias16 = (WebRtc_Word16) (1024 + tmp32c); // Q10 + tmp32b = Log2Q8((WebRtc_UWord32) bias16) - 2560; // Q10 in -> Q8 out with 10*2^8 offset + crrvecQ8_1[k] += tmp32b ; // -10*2^8 offset + } + } + + /* taper correlation functions */ + for (k = 0; k < 3; k++) { + crrvecQ8_1[k] += kLogLagWinQ8[k]; + crrvecQ8_2[k] += kLogLagWinQ8[k]; + + crrvecQ8_1[PITCH_LAG_SPAN2-1-k] += kLogLagWinQ8[k]; + crrvecQ8_2[PITCH_LAG_SPAN2-1-k] += kLogLagWinQ8[k]; + } + + + /* Make zeropadded corr vectors */ + cv1q[0]=0; + cv2q[0]=0; + cv1q[PITCH_LAG_SPAN2+1]=0; + cv2q[PITCH_LAG_SPAN2+1]=0; + corr_max32 = 0; + + for (k = 1; k <= PITCH_LAG_SPAN2; k++) + { + + + corr32=crrvecQ8_1[k-1]; + if (corr32 > corr_max32) + corr_max32 = corr32; + + corr32=crrvecQ8_2[k-1]; + corr32 += -4; // Compensate for later (log2(0.99)) + + if (corr32 > corr_max32) + corr_max32 = corr32; + + } + + /* threshold value to qualify as a peak */ + // corr_max32 += -726; // log(0.14)/log(2.0) in Q8 + corr_max32 += -1000; // log(0.14)/log(2.0) in Q8 + corr_max_o32 = corr_max32; + + + /* find peaks in corr1 */ + peaks_indq = 0; + for (k = 1; k <= PITCH_LAG_SPAN2; k++) + { + corr32=cv1q[k]; + if (corr32>corr_max32) { // Disregard small peaks + if ((corr32>=cv1q[k-1]) && (corr32>cv1q[k+1])) { // Peak? + peakvq[peaks_indq] = corr32; + peakiq[peaks_indq++] = k; + } + } + } + + + /* find highest interpolated peak */ + corr_max32=0; + best_lag1q =0; + if (peaks_indq > 0) { + FindFour32(peakvq, (WebRtc_Word16) peaks_indq, best4q); + npkq = WEBRTC_SPL_MIN(peaks_indq, 4); + + for (k=0;k<npkq;k++) { + + lag32 = peakiq[best4q[k]]; + fxq = &cv1q[peakiq[best4q[k]]-1]; + xq[0]= lag32; + xq[0] = WEBRTC_SPL_LSHIFT_W32(xq[0], 8); + Intrp1DQ8(xq, fxq, yq, fyq); + + tmp32a= Log2Q8((WebRtc_UWord32) *yq) - 2048; // offset 8*2^8 + /* Bias towards short lags */ + /* log(pow(0.8, log(2.0 * *y )))/log(2.0) */ + tmp32b= WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) tmp32a, -42, 8); + tmp32c= tmp32b + 256; + *fyq += tmp32c; + if (*fyq > corr_max32) { + corr_max32 = *fyq; + best_lag1q = *yq; + } + } + tmp32a = best_lag1q - OFFSET_Q8; + tmp32b = WEBRTC_SPL_LSHIFT_W32(tmp32a, 1); + lagsQ8[0] = tmp32b + PITCH_MIN_LAG_Q8; + lagsQ8[1] = lagsQ8[0]; + } else { + lagsQ8[0] = old_lagQ8; + lagsQ8[1] = lagsQ8[0]; + } + + /* Bias towards constant pitch */ + tmp32a = lagsQ8[0] - PITCH_MIN_LAG_Q8; + ratq = WEBRTC_SPL_RSHIFT_W32(tmp32a, 1) + OFFSET_Q8; + + for (k = 1; k <= PITCH_LAG_SPAN2; k++) + { + tmp32a = WEBRTC_SPL_LSHIFT_W32(k, 7); // 0.5*k Q8 + tmp32b = (WebRtc_Word32) (WEBRTC_SPL_LSHIFT_W32(tmp32a, 1)) - ratq; // Q8 + tmp32c = WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) tmp32b, (WebRtc_Word16) tmp32b, 8); // Q8 + + tmp32b = (WebRtc_Word32) tmp32c + (WebRtc_Word32) WEBRTC_SPL_RSHIFT_W32(ratq, 1); // (k-r)^2 + 0.5 * r Q8 + tmp32c = Log2Q8((WebRtc_UWord32) tmp32a) - 2048; // offset 8*2^8 , log2(0.5*k) Q8 + tmp32d = Log2Q8((WebRtc_UWord32) tmp32b) - 2048; // offset 8*2^8 , log2(0.5*k) Q8 + tmp32e = tmp32c -tmp32d; + + cv2q[k] += WEBRTC_SPL_RSHIFT_W32(tmp32e, 1); + + } + + /* find peaks in corr2 */ + corr_max32 = corr_max_o32; + peaks_indq = 0; + + for (k = 1; k <= PITCH_LAG_SPAN2; k++) + { + corr=cv2q[k]; + if (corr>corr_max32) { // Disregard small peaks + if ((corr>=cv2q[k-1]) && (corr>cv2q[k+1])) { // Peak? + peakvq[peaks_indq] = corr; + peakiq[peaks_indq++] = k; + } + } + } + + + + /* find highest interpolated peak */ + corr_max32 = 0; + best_lag2q =0; + if (peaks_indq > 0) { + + FindFour32(peakvq, (WebRtc_Word16) peaks_indq, best4q); + npkq = WEBRTC_SPL_MIN(peaks_indq, 4); + for (k=0;k<npkq;k++) { + + lag32 = peakiq[best4q[k]]; + fxq = &cv2q[peakiq[best4q[k]]-1]; + + xq[0]= lag32; + xq[0] = WEBRTC_SPL_LSHIFT_W32(xq[0], 8); + Intrp1DQ8(xq, fxq, yq, fyq); + + /* Bias towards short lags */ + /* log(pow(0.8, log(2.0f * *y )))/log(2.0f) */ + tmp32a= Log2Q8((WebRtc_UWord32) *yq) - 2048; // offset 8*2^8 + tmp32b= WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) tmp32a, -82, 8); + tmp32c= tmp32b + 256; + *fyq += tmp32c; + if (*fyq > corr_max32) { + corr_max32 = *fyq; + best_lag2q = *yq; + } + } + + tmp32a = best_lag2q - OFFSET_Q8; + tmp32b = WEBRTC_SPL_LSHIFT_W32(tmp32a, 1); + lagsQ8[2] = tmp32b + PITCH_MIN_LAG_Q8; + lagsQ8[3] = lagsQ8[2]; + } else { + lagsQ8[2] = lagsQ8[0]; + lagsQ8[3] = lagsQ8[0]; + } + + lagsQ7[0]=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(lagsQ8[0], 1); + lagsQ7[1]=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(lagsQ8[1], 1); + lagsQ7[2]=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(lagsQ8[2], 1); + lagsQ7[3]=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(lagsQ8[3], 1); + + +} + + + +void WebRtcIsacfix_PitchAnalysis(const WebRtc_Word16 *inn, /* PITCH_FRAME_LEN samples */ + WebRtc_Word16 *outQ0, /* PITCH_FRAME_LEN+QLOOKAHEAD samples */ + PitchAnalysisStruct *State, + WebRtc_Word16 *PitchLags_Q7, + WebRtc_Word16 *PitchGains_Q12) +{ + WebRtc_Word16 inbufQ0[PITCH_FRAME_LEN + QLOOKAHEAD]; + WebRtc_Word16 k; + + /* inital pitch estimate */ + WebRtcIsacfix_InitialPitch(inn, State, PitchLags_Q7); + + + /* Calculate gain */ + WebRtcIsacfix_PitchFilterGains(inn, &(State->PFstr_wght), PitchLags_Q7, PitchGains_Q12); + + /* concatenate previous input's end and current input */ + for (k = 0; k < QLOOKAHEAD; k++) { + inbufQ0[k] = State->inbuf[k]; + } + for (k = 0; k < PITCH_FRAME_LEN; k++) { + inbufQ0[k+QLOOKAHEAD] = (WebRtc_Word16) inn[k]; + } + + /* lookahead pitch filtering for masking analysis */ + WebRtcIsacfix_PitchFilter(inbufQ0, outQ0, &(State->PFstr), PitchLags_Q7,PitchGains_Q12, 2); + + + /* store last part of input */ + for (k = 0; k < QLOOKAHEAD; k++) { + State->inbuf[k] = inbufQ0[k + PITCH_FRAME_LEN]; + } +} diff --git a/src/libs/webrtc/isac/pitch_estimator.h b/src/libs/webrtc/isac/pitch_estimator.h new file mode 100644 index 00000000..afdc9785 --- /dev/null +++ b/src/libs/webrtc/isac/pitch_estimator.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * pitch_estimator.h + * + * Pitch functions + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_ESTIMATOR_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_ESTIMATOR_H_ + +#include "structs.h" + + + +void WebRtcIsacfix_PitchAnalysis(const WebRtc_Word16 *in, /* PITCH_FRAME_LEN samples */ + WebRtc_Word16 *outQ0, /* PITCH_FRAME_LEN+QLOOKAHEAD samples */ + PitchAnalysisStruct *State, + WebRtc_Word16 *lagsQ7, + WebRtc_Word16 *PitchGains_Q12); + + +void WebRtcIsacfix_InitialPitch(const WebRtc_Word16 *in, + PitchAnalysisStruct *State, + WebRtc_Word16 *qlags); + +void WebRtcIsacfix_PitchFilter(WebRtc_Word16 *indatFix, + WebRtc_Word16 *outdatQQ, + PitchFiltstr *pfp, + WebRtc_Word16 *lagsQ7, + WebRtc_Word16 *gainsQ12, + WebRtc_Word16 type); + +void WebRtcIsacfix_PitchFilterGains(const WebRtc_Word16 *indatQ0, + PitchFiltstr *pfp, + WebRtc_Word16 *lagsQ7, + WebRtc_Word16 *gainsQ12); + + + +void WebRtcIsacfix_DecimateAllpass32(const WebRtc_Word16 *in, + WebRtc_Word32 *state_in, /* array of size: 2*ALLPASSSECTIONS+1 */ + WebRtc_Word16 N, /* number of input samples */ + WebRtc_Word16 *out); /* array of size N/2 */ + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_ESTIMATOR_H_ */ diff --git a/src/libs/webrtc/isac/pitch_filter.c b/src/libs/webrtc/isac/pitch_filter.c new file mode 100644 index 00000000..cf11084b --- /dev/null +++ b/src/libs/webrtc/isac/pitch_filter.c @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * pitch_estimatorfilter.c + * + * Pitch filter functions + * + */ + +#include <string.h> + +#include "pitch_estimator.h" + + +/* Filter coefficicients in Q15 */ +static const WebRtc_Word16 kDampFilter[PITCH_DAMPORDER] = { + -2294, 8192, 20972, 8192, -2294 +}; + +/* Interpolation coefficients; generated by design_pitch_filter.m. + * Coefficients are stored in Q14. + */ +static const WebRtc_Word16 kIntrpCoef[PITCH_FRACS][PITCH_FRACORDER] = { + {-367, 1090, -2706, 9945, 10596, -3318, 1626, -781, 287}, + {-325, 953, -2292, 7301, 12963, -3320, 1570, -743, 271}, + {-240, 693, -1622, 4634, 14809, -2782, 1262, -587, 212}, + {-125, 358, -817, 2144, 15982, -1668, 721, -329, 118}, + { 0, 0, -1, 1, 16380, 1, -1, 0, 0}, + { 118, -329, 721, -1668, 15982, 2144, -817, 358, -125}, + { 212, -587, 1262, -2782, 14809, 4634, -1622, 693, -240}, + { 271, -743, 1570, -3320, 12963, 7301, -2292, 953, -325} +}; + + + + +static __inline WebRtc_Word32 CalcLrIntQ(WebRtc_Word32 fixVal, WebRtc_Word16 qDomain) { + WebRtc_Word32 intgr; + WebRtc_Word32 roundVal; + + roundVal = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, qDomain-1); + intgr = WEBRTC_SPL_RSHIFT_W32(fixVal+roundVal, qDomain); + + return intgr; +} + +void WebRtcIsacfix_PitchFilter(WebRtc_Word16 *indatQQ, /* Q10 if type is 1 or 4, Q0 if type is 2 */ + WebRtc_Word16 *outdatQQ, + PitchFiltstr *pfp, + WebRtc_Word16 *lagsQ7, + WebRtc_Word16 *gainsQ12, + WebRtc_Word16 type) +{ + int k, n, m, ind; + WebRtc_Word16 sign = 1; + WebRtc_Word16 inystateQQ[PITCH_DAMPORDER]; + WebRtc_Word16 ubufQQ[PITCH_INTBUFFSIZE+QLOOKAHEAD]; + WebRtc_Word16 Gain = 21299; /* 1.3 in Q14 */ + WebRtc_Word16 DivFactor = 6553; /* 0.2 in Q15 */ + WebRtc_Word16 oldLagQ7, oldGainQ12, + lagdeltaQ7, curLagQ7, + gaindeltaQ12, curGainQ12; + WebRtc_Word16 tmpW16, indW16=0, frcQQ, cnt=0, pos, pos2; + const WebRtc_Word16 *fracoeffQQ=NULL; + WebRtc_Word32 tmpW32; + + if (type==4) + sign = -1; + + /* Set up buffer and states */ + memcpy(ubufQQ, pfp->ubufQQ, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_BUFFSIZE)); + memcpy(inystateQQ, pfp->ystateQQ, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_DAMPORDER)); + + /* Get old lag and gain value from memory */ + oldLagQ7 = pfp->oldlagQ7; + oldGainQ12 = pfp->oldgainQ12; + + if (type==4) { + /* make output more periodic */ + /* Fixed 1.3 = 21299 in Q14 */ + for (k=0;k<PITCH_SUBFRAMES;k++) + gainsQ12[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gainsQ12[k], Gain, 14); + } + + /* No interpolation if pitch lag step is big */ + if ((WEBRTC_SPL_RSHIFT_W16(WEBRTC_SPL_MUL_16_16(lagsQ7[0], 3), 1) < oldLagQ7) || + (lagsQ7[0] > WEBRTC_SPL_RSHIFT_W16(WEBRTC_SPL_MUL_16_16(oldLagQ7, 3), 1))) { + oldLagQ7 = lagsQ7[0]; + oldGainQ12 = gainsQ12[0]; + } + + ind=0; + for (k=0;k<PITCH_SUBFRAMES;k++) { + + /* Calculate interpolation steps */ + lagdeltaQ7 = lagsQ7[k]-oldLagQ7; + lagdeltaQ7 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(lagdeltaQ7,DivFactor,15); + curLagQ7 = oldLagQ7; + gaindeltaQ12 = gainsQ12[k]-oldGainQ12; + gaindeltaQ12 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gaindeltaQ12,DivFactor,15); + + curGainQ12 = oldGainQ12; + oldLagQ7 = lagsQ7[k]; + oldGainQ12 = gainsQ12[k]; + + + for (n=0;n<PITCH_SUBFRAME_LEN;n++) { + + if (cnt == 0) { /* Update parameters */ + + curGainQ12 += gaindeltaQ12; + curLagQ7 += lagdeltaQ7; + indW16 = (WebRtc_Word16)CalcLrIntQ(curLagQ7,7); + tmpW16 = WEBRTC_SPL_LSHIFT_W16(indW16,7); + tmpW16 -= curLagQ7; + frcQQ = WEBRTC_SPL_RSHIFT_W16(tmpW16,4); + frcQQ += 4; + + if(frcQQ==PITCH_FRACS) + frcQQ=0; + fracoeffQQ = kIntrpCoef[frcQQ]; + + cnt=12; + } + + /* shift low pass filter state */ + for (m=PITCH_DAMPORDER-1;m>0;m--) + inystateQQ[m] = inystateQQ[m-1]; + + /* Filter to get fractional pitch */ + pos = ind + PITCH_BUFFSIZE; + pos2 = pos - (indW16 + 2); + + tmpW32=0; + for (m=0;m<PITCH_FRACORDER;m++) + tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQ[pos2+m], fracoeffQQ[m]); + + /* Saturate to avoid overflow in tmpW16 */ + tmpW32 = WEBRTC_SPL_SAT(536862719, tmpW32, -536879104); + tmpW32 += 8192; + tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,14); + + inystateQQ[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(curGainQ12, tmpW16,12); /* Multiply with gain */ + + /* Low pass filter */ + tmpW32=0; + for (m=0;m<PITCH_DAMPORDER;m++) + tmpW32 += WEBRTC_SPL_MUL_16_16(inystateQQ[m], kDampFilter[m]); + + /* Saturate to avoid overflow in tmpW16 */ + tmpW32 = WEBRTC_SPL_SAT(1073725439, tmpW32, -1073758208); + tmpW32 += 16384; + tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,15); + + /* Subtract from input and update buffer */ + tmpW32 = indatQQ[ind] - WEBRTC_SPL_MUL_16_16(sign, tmpW16); + outdatQQ[ind] = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmpW32, -32768); + tmpW32 = indatQQ[ind] + (WebRtc_Word32)outdatQQ[ind]; + ubufQQ[pos] = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmpW32, -32768); + + ind++; + cnt--; + } + } + + + /* Export buffer and states */ + memcpy(pfp->ubufQQ, ubufQQ+PITCH_FRAME_LEN, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_BUFFSIZE)); + memcpy(pfp->ystateQQ, inystateQQ, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_DAMPORDER)); + + pfp->oldlagQ7 = oldLagQ7; + pfp->oldgainQ12 = oldGainQ12; + + if (type==2) { + /* Filter look-ahead segment */ + for (n=0;n<QLOOKAHEAD;n++) { + /* shift low pass filter state */ + for (m=PITCH_DAMPORDER-1;m>0;m--) + inystateQQ[m] = inystateQQ[m-1]; + + /* Filter to get fractional pitch */ + pos = ind + PITCH_BUFFSIZE; + pos2= pos - (indW16 + 2); + + tmpW32=0; + for (m=0;m<PITCH_FRACORDER;m++) + tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQ[pos2+m], fracoeffQQ[m]); + + if (tmpW32<536862720) {//536870912) + tmpW32 += 8192; + tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,14); + } else + tmpW16= 32767; + inystateQQ[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(curGainQ12, tmpW16,12); /* Multiply with gain */ + + /* Low pass filter */ + tmpW32=0; + for (m=0;m<PITCH_DAMPORDER;m++) + tmpW32 += WEBRTC_SPL_MUL_16_16(inystateQQ[m], kDampFilter[m]); + if (tmpW32<1073725440) { //1073741824) + tmpW32 += 16384; + tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,15); + } else + tmpW16 = 32767; + + /* Subtract from input and update buffer */ + tmpW32 = indatQQ[ind] - (WebRtc_Word32)tmpW16; + outdatQQ[ind] = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmpW32, -32768); + tmpW32 = indatQQ[ind] + (WebRtc_Word32)outdatQQ[ind]; + ubufQQ[pos] = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmpW32, -32768); + + ind++; + } + + } + + +} + + +void WebRtcIsacfix_PitchFilterGains(const WebRtc_Word16 *indatQ0, + PitchFiltstr *pfp, + WebRtc_Word16 *lagsQ7, + WebRtc_Word16 *gainsQ12) +{ + int k, n, m, ind; + + WebRtc_Word16 ubufQQ[PITCH_INTBUFFSIZE]; + WebRtc_Word16 oldLagQ7,lagdeltaQ7, curLagQ7; + WebRtc_Word16 DivFactor = 6553; + const WebRtc_Word16 *fracoeffQQ = NULL; + WebRtc_Word16 scale; + WebRtc_Word16 cnt=0, pos, pos3QQ, frcQQ, indW16 = 0, tmpW16; + WebRtc_Word32 tmpW32, tmp2W32, csum1QQ, esumxQQ; + + /* Set up buffer and states */ + memcpy(ubufQQ, pfp->ubufQQ, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_BUFFSIZE)); + oldLagQ7 = pfp->oldlagQ7; + + /* No interpolation if pitch lag step is big */ + if ((WEBRTC_SPL_RSHIFT_W16(WEBRTC_SPL_MUL_16_16(lagsQ7[0], 3), 1) < oldLagQ7) || + (lagsQ7[0] > WEBRTC_SPL_RSHIFT_W16(WEBRTC_SPL_MUL_16_16(oldLagQ7, 3), 1))) { + oldLagQ7 = lagsQ7[0]; + } + + ind=0; + scale=0; + for (k=0;k<PITCH_SUBFRAMES;k++) { + + /* Calculate interpolation steps */ + lagdeltaQ7 = lagsQ7[k]-oldLagQ7; + lagdeltaQ7 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(lagdeltaQ7,DivFactor,15); + curLagQ7 = oldLagQ7; + oldLagQ7 = lagsQ7[k]; + + csum1QQ=1; + esumxQQ=1; + + for (n=0;n<PITCH_SUBFRAME_LEN;n++) { + + if (cnt == 0) { /* Update parameters */ + curLagQ7 += lagdeltaQ7; + indW16 = (WebRtc_Word16)CalcLrIntQ(curLagQ7,7); + tmpW16 = WEBRTC_SPL_LSHIFT_W16(indW16,7); + tmpW16 -= curLagQ7; + frcQQ = WEBRTC_SPL_RSHIFT_W16(tmpW16,4); + frcQQ += 4; + + if(frcQQ==PITCH_FRACS) + frcQQ=0; + fracoeffQQ = kIntrpCoef[frcQQ]; + + cnt=12; + } + + /* Filter to get fractional pitch */ + pos = ind + PITCH_BUFFSIZE; + pos3QQ = pos - (indW16 + 4); + + tmpW32=0; + for (m=0;m<PITCH_FRACORDER;m++){ + tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQ[pos3QQ+m], fracoeffQQ[m]); + } + + /* Subtract from input and update buffer */ + ubufQQ[pos] = indatQ0[ind]; + + tmp2W32 = WEBRTC_SPL_MUL_16_32_RSFT14(indatQ0[ind], tmpW32); + tmpW32 += 8192; + tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,14); + tmpW32 = WEBRTC_SPL_MUL_16_16(tmpW16, tmpW16); + + if ((tmp2W32>1073700000) || (csum1QQ>1073700000) || (tmpW32>1073700000) || (esumxQQ>1073700000)) {//2^30 + scale++; + csum1QQ = WEBRTC_SPL_RSHIFT_W32(csum1QQ,1); + esumxQQ = WEBRTC_SPL_RSHIFT_W32(esumxQQ,1); + } + tmp2W32 = WEBRTC_SPL_RSHIFT_W32(tmp2W32,scale); + csum1QQ += tmp2W32; + tmpW32 = WEBRTC_SPL_RSHIFT_W32(tmpW32,scale); + esumxQQ += tmpW32; + + ind++; + cnt--; + } + + if (csum1QQ<esumxQQ) { + tmp2W32=WebRtcSpl_DivResultInQ31(csum1QQ,esumxQQ); + + /* Gain should be half the correlation */ + tmpW32=WEBRTC_SPL_RSHIFT_W32(tmp2W32,20); + } else + tmpW32=4096; + gainsQ12[k]=(WebRtc_Word16)WEBRTC_SPL_SAT(PITCH_MAX_GAIN_Q12, tmpW32, 0); + + } + + /* Export buffer and states */ + memcpy(pfp->ubufQQ, ubufQQ+PITCH_FRAME_LEN, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_BUFFSIZE)); + pfp->oldlagQ7 = lagsQ7[PITCH_SUBFRAMES-1]; + pfp->oldgainQ12 = gainsQ12[PITCH_SUBFRAMES-1]; + +} diff --git a/src/libs/webrtc/isac/pitch_gain_tables.c b/src/libs/webrtc/isac/pitch_gain_tables.c new file mode 100644 index 00000000..50ea6583 --- /dev/null +++ b/src/libs/webrtc/isac/pitch_gain_tables.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * pitch_gain_tables.c + * + * This file contains tables for the pitch filter side-info in the entropy coder. + * + */ + +#include "pitch_gain_tables.h" + + +/********************* Pitch Filter Gain Coefficient Tables ************************/ + +/* cdf for quantized pitch filter gains */ +const WebRtc_UWord16 WebRtcIsacfix_kPitchGainCdf[255] = { + 0, 2, 4, 6, 64, 901, 903, 905, 16954, 16956, + 16961, 17360, 17362, 17364, 17366, 17368, 17370, 17372, 17374, 17411, + 17514, 17516, 17583, 18790, 18796, 18802, 20760, 20777, 20782, 21722, + 21724, 21728, 21738, 21740, 21742, 21744, 21746, 21748, 22224, 22227, + 22230, 23214, 23229, 23239, 25086, 25108, 25120, 26088, 26094, 26098, + 26175, 26177, 26179, 26181, 26183, 26185, 26484, 26507, 26522, 27705, + 27731, 27750, 29767, 29799, 29817, 30866, 30883, 30885, 31025, 31029, + 31031, 31033, 31035, 31037, 31114, 31126, 31134, 32687, 32722, 32767, + 35718, 35742, 35757, 36943, 36952, 36954, 37115, 37128, 37130, 37132, + 37134, 37136, 37143, 37145, 37152, 38843, 38863, 38897, 47458, 47467, + 47474, 49040, 49061, 49063, 49145, 49157, 49159, 49161, 49163, 49165, + 49167, 49169, 49171, 49757, 49770, 49782, 61333, 61344, 61346, 62860, + 62883, 62885, 62887, 62889, 62891, 62893, 62895, 62897, 62899, 62901, + 62903, 62905, 62907, 62909, 65496, 65498, 65500, 65521, 65523, 65525, + 65527, 65529, 65531, 65533, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535 +}; + +/* index limits and ranges */ +const WebRtc_Word16 WebRtcIsacfix_kLowerlimiGain[3] = { + -7, -2, -1 +}; + +const WebRtc_Word16 WebRtcIsacfix_kUpperlimitGain[3] = { + 0, 3, 1 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kMultsGain[2] = { + 18, 3 +}; + +/* size of cdf table */ +const WebRtc_UWord16 WebRtcIsacfix_kCdfTableSizeGain[1] = { + 256 +}; + +/* mean values of pitch filter gains in FIXED point Q12 */ +const WebRtc_Word16 WebRtcIsacfix_kPitchGain1[144] = { + 843, 1092, 1336, 1222, 1405, 1656, 1500, 1815, 1843, 1838, 1839, + 1843, 1843, 1843, 1843, 1843, 1843, 1843, 814, 846, 1092, 1013, + 1174, 1383, 1391, 1511, 1584, 1734, 1753, 1843, 1843, 1843, 1843, + 1843, 1843, 1843, 524, 689, 777, 845, 947, 1069, 1090, 1263, + 1380, 1447, 1559, 1676, 1645, 1749, 1843, 1843, 1843, 1843, 81, + 477, 563, 611, 706, 806, 849, 1012, 1192, 1128, 1330, 1489, + 1425, 1576, 1826, 1741, 1843, 1843, 0, 290, 305, 356, 488, + 575, 602, 741, 890, 835, 1079, 1196, 1182, 1376, 1519, 1506, + 1680, 1843, 0, 47, 97, 69, 289, 381, 385, 474, 617, + 664, 803, 1079, 935, 1160, 1269, 1265, 1506, 1741, 0, 0, + 0, 0, 112, 120, 190, 283, 442, 343, 526, 809, 684, + 935, 1134, 1020, 1265, 1506, 0, 0, 0, 0, 0, 0, + 0, 111, 256, 87, 373, 597, 430, 684, 935, 770, 1020, + 1265 +}; + +const WebRtc_Word16 WebRtcIsacfix_kPitchGain2[144] = { + 1760, 1525, 1285, 1747, 1671, 1393, 1843, 1826, 1555, 1843, 1784, + 1606, 1843, 1843, 1711, 1843, 1843, 1814, 1389, 1275, 1040, 1564, + 1414, 1252, 1610, 1495, 1343, 1753, 1592, 1405, 1804, 1720, 1475, + 1843, 1814, 1581, 1208, 1061, 856, 1349, 1148, 994, 1390, 1253, + 1111, 1495, 1343, 1178, 1770, 1465, 1234, 1814, 1581, 1342, 1040, + 793, 713, 1053, 895, 737, 1128, 1003, 861, 1277, 1094, 981, + 1475, 1192, 1019, 1581, 1342, 1098, 855, 570, 483, 833, 648, + 540, 948, 744, 572, 1009, 844, 636, 1234, 934, 685, 1342, + 1217, 984, 537, 318, 124, 603, 423, 350, 687, 479, 322, + 791, 581, 430, 987, 671, 488, 1098, 849, 597, 283, 27, + 0, 397, 222, 38, 513, 271, 124, 624, 325, 157, 737, + 484, 233, 849, 597, 343, 27, 0, 0, 141, 0, 0, + 256, 69, 0, 370, 87, 0, 484, 229, 0, 597, 343, + 87 +}; + +const WebRtc_Word16 WebRtcIsacfix_kPitchGain3[144] = { + 1843, 1843, 1711, 1843, 1818, 1606, 1843, 1827, 1511, 1814, 1639, + 1393, 1760, 1525, 1285, 1656, 1419, 1176, 1835, 1718, 1475, 1841, + 1650, 1387, 1648, 1498, 1287, 1600, 1411, 1176, 1522, 1299, 1040, + 1419, 1176, 928, 1773, 1461, 1128, 1532, 1355, 1202, 1429, 1260, + 1115, 1398, 1151, 1025, 1172, 1080, 790, 1176, 928, 677, 1475, + 1147, 1019, 1276, 1096, 922, 1214, 1010, 901, 1057, 893, 800, + 1040, 796, 734, 928, 677, 424, 1137, 897, 753, 1120, 830, + 710, 875, 751, 601, 795, 642, 583, 790, 544, 475, 677, + 474, 140, 987, 750, 482, 697, 573, 450, 691, 487, 303, + 661, 394, 332, 537, 303, 220, 424, 168, 0, 737, 484, + 229, 624, 348, 153, 441, 261, 136, 397, 166, 51, 283, + 27, 0, 168, 0, 0, 484, 229, 0, 370, 57, 0, + 256, 43, 0, 141, 0, 0, 27, 0, 0, 0, 0, + 0 +}; + + +const WebRtc_Word16 WebRtcIsacfix_kPitchGain4[144] = { + 1843, 1843, 1843, 1843, 1841, 1843, 1500, 1821, 1843, 1222, 1434, + 1656, 843, 1092, 1336, 504, 757, 1007, 1843, 1843, 1843, 1838, + 1791, 1843, 1265, 1505, 1599, 965, 1219, 1425, 730, 821, 1092, + 249, 504, 757, 1783, 1819, 1843, 1351, 1567, 1727, 1096, 1268, + 1409, 805, 961, 1131, 444, 670, 843, 0, 249, 504, 1425, + 1655, 1743, 1096, 1324, 1448, 822, 1019, 1199, 490, 704, 867, + 81, 450, 555, 0, 0, 249, 1247, 1428, 1530, 881, 1073, + 1283, 610, 759, 939, 278, 464, 645, 0, 200, 270, 0, + 0, 0, 935, 1163, 1410, 528, 790, 1068, 377, 499, 717, + 173, 240, 274, 0, 43, 62, 0, 0, 0, 684, 935, + 1182, 343, 551, 735, 161, 262, 423, 0, 55, 27, 0, + 0, 0, 0, 0, 0, 430, 684, 935, 87, 377, 597, + 0, 46, 256, 0, 0, 0, 0, 0, 0, 0, 0, + 0 +}; + + + +/* transform matrix in Q12*/ +const WebRtc_Word16 WebRtcIsacfix_kTransform[4][4] = { + { -2048, -2048, -2048, -2048 }, + { 2748, 916, -916, -2748 }, + { 2048, -2048, -2048, 2048 }, + { 916, -2748, 2748, -916 } +}; diff --git a/src/libs/webrtc/isac/pitch_gain_tables.h b/src/libs/webrtc/isac/pitch_gain_tables.h new file mode 100644 index 00000000..788e5536 --- /dev/null +++ b/src/libs/webrtc/isac/pitch_gain_tables.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * pitch_gain_tables.h + * + * This file contains tables for the pitch filter side-info in the entropy coder. + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_GAIN_TABLES_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_GAIN_TABLES_H_ + +#include "typedefs.h" + + +/********************* Pitch Filter Gain Coefficient Tables ************************/ +/* cdf for quantized pitch filter gains */ +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchGainCdf[255]; + +/* index limits and ranges */ +extern const WebRtc_Word16 WebRtcIsacfix_kLowerlimiGain[3]; +extern const WebRtc_Word16 WebRtcIsacfix_kUpperlimitGain[3]; +extern const WebRtc_UWord16 WebRtcIsacfix_kMultsGain[2]; + +/* mean values of pitch filter gains in Q12*/ +extern const WebRtc_Word16 WebRtcIsacfix_kPitchGain1[144]; +extern const WebRtc_Word16 WebRtcIsacfix_kPitchGain2[144]; +extern const WebRtc_Word16 WebRtcIsacfix_kPitchGain3[144]; +extern const WebRtc_Word16 WebRtcIsacfix_kPitchGain4[144]; + +/* size of cdf table */ +extern const WebRtc_UWord16 WebRtcIsacfix_kCdfTableSizeGain[1]; + +/* transform matrix */ +extern const WebRtc_Word16 WebRtcIsacfix_kTransform[4][4]; + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_GAIN_TABLES_H_ */ diff --git a/src/libs/webrtc/isac/pitch_lag_tables.c b/src/libs/webrtc/isac/pitch_lag_tables.c new file mode 100644 index 00000000..81700e47 --- /dev/null +++ b/src/libs/webrtc/isac/pitch_lag_tables.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * pitch_lag_tables.c + * + * This file contains tables for the pitch filter side-info in the entropy coder. + * + */ + +#include "settings.h" +#include "pitch_lag_tables.h" + + +/********************* Pitch Filter Gain Coefficient Tables ************************/ + +/* tables for use with small pitch gain */ + +/* cdf for quantized pitch filter lags */ +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Lo[127] = { + 0, 134, 336, 549, 778, 998, 1264, 1512, 1777, 2070, + 2423, 2794, 3051, 3361, 3708, 3979, 4315, 4610, 4933, 5269, + 5575, 5896, 6155, 6480, 6816, 7129, 7477, 7764, 8061, 8358, + 8718, 9020, 9390, 9783, 10177, 10543, 10885, 11342, 11795, 12213, + 12680, 13096, 13524, 13919, 14436, 14903, 15349, 15795, 16267, 16734, + 17266, 17697, 18130, 18632, 19080, 19447, 19884, 20315, 20735, 21288, + 21764, 22264, 22723, 23193, 23680, 24111, 24557, 25022, 25537, 26082, + 26543, 27090, 27620, 28139, 28652, 29149, 29634, 30175, 30692, 31273, + 31866, 32506, 33059, 33650, 34296, 34955, 35629, 36295, 36967, 37726, + 38559, 39458, 40364, 41293, 42256, 43215, 44231, 45253, 46274, 47359, + 48482, 49678, 50810, 51853, 53016, 54148, 55235, 56263, 57282, 58363, + 59288, 60179, 61076, 61806, 62474, 63129, 63656, 64160, 64533, 64856, + 65152, 65535, 65535, 65535, 65535, 65535, 65535 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Lo[20] = { + 0, 429, 3558, 5861, 8558, 11639, 15210, 19502, 24773, 31983, + 42602, 48567, 52601, 55676, 58160, 60172, 61889, 63235, 65383, 65535 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Lo[2] = { + 0, 65535 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Lo[10] = { + 0, 2966, 6368, 11182, 19431, 37793, 48532, 55353, 60626, 65535 +}; + +const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrLo[4] = { + WebRtcIsacfix_kPitchLagCdf1Lo, + WebRtcIsacfix_kPitchLagCdf2Lo, + WebRtcIsacfix_kPitchLagCdf3Lo, + WebRtcIsacfix_kPitchLagCdf4Lo +}; + +/* size of first cdf table */ +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeLo[1] = { + 128 +}; + +/* index limits and ranges */ +const WebRtc_Word16 WebRtcIsacfix_kLowerLimitLo[4] = { + -140, -9, 0, -4 +}; + +const WebRtc_Word16 WebRtcIsacfix_kUpperLimitLo[4] = { + -20, 9, 0, 4 +}; + +/* initial index for arithmetic decoder */ +const WebRtc_UWord16 WebRtcIsacfix_kInitIndLo[3] = { + 10, 1, 5 +}; + +/* mean values of pitch filter lags in Q10 */ + +const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Lo[19] = { + -17627, -16207, -14409, -12319, -10253, -8200, -6054, -3986, -1948, -19, + 1937, 3974, 6064, 8155, 10229, 12270, 14296, 16127, 17520 +}; + +const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Lo[9] = { + -7949, -6063, -4036, -1941, 38, 1977, 4060, 6059 +}; + + + +/* tables for use with medium pitch gain */ + +/* cdf for quantized pitch filter lags */ +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Mid[255] = { + 0, 28, 61, 88, 121, 149, 233, 331, 475, 559, + 624, 661, 689, 712, 745, 791, 815, 843, 866, 922, + 959, 1024, 1061, 1117, 1178, 1238, 1280, 1350, 1453, 1513, + 1564, 1625, 1671, 1741, 1788, 1904, 2072, 2421, 2626, 2770, + 2840, 2900, 2942, 3012, 3068, 3115, 3147, 3194, 3254, 3319, + 3366, 3520, 3678, 3780, 3850, 3911, 3957, 4032, 4106, 4185, + 4292, 4474, 4683, 4842, 5019, 5191, 5321, 5428, 5540, 5675, + 5763, 5847, 5959, 6127, 6304, 6564, 6839, 7090, 7263, 7421, + 7556, 7728, 7872, 7984, 8142, 8361, 8580, 8743, 8938, 9227, + 9409, 9539, 9674, 9795, 9930, 10060, 10177, 10382, 10614, 10861, + 11038, 11271, 11415, 11629, 11792, 12044, 12193, 12416, 12574, 12821, + 13007, 13235, 13445, 13654, 13901, 14134, 14488, 15000, 15703, 16285, + 16504, 16797, 17086, 17328, 17579, 17807, 17998, 18268, 18538, 18836, + 19087, 19274, 19474, 19716, 19935, 20270, 20833, 21303, 21532, 21741, + 21978, 22207, 22523, 22770, 23054, 23613, 23943, 24204, 24399, 24651, + 24832, 25074, 25270, 25549, 25759, 26015, 26150, 26424, 26713, 27048, + 27342, 27504, 27681, 27854, 28021, 28207, 28412, 28664, 28859, 29064, + 29278, 29548, 29748, 30107, 30377, 30656, 30856, 31164, 31452, 31755, + 32011, 32328, 32626, 32919, 33319, 33789, 34329, 34925, 35396, 35973, + 36443, 36964, 37551, 38156, 38724, 39357, 40023, 40908, 41587, 42602, + 43924, 45037, 45810, 46597, 47421, 48291, 49092, 50051, 51448, 52719, + 53440, 54241, 54944, 55977, 56676, 57299, 57872, 58389, 59059, 59688, + 60237, 60782, 61094, 61573, 61890, 62290, 62658, 63030, 63217, 63454, + 63622, 63882, 64003, 64273, 64427, 64529, 64581, 64697, 64758, 64902, + 65414, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Mid[36] = { + 0, 71, 335, 581, 836, 1039, 1323, 1795, 2258, 2608, + 3005, 3591, 4243, 5344, 7163, 10583, 16848, 28078, 49448, 57007, + 60357, 61850, 62837, 63437, 63872, 64188, 64377, 64614, 64774, 64949, + 65039, 65115, 65223, 65360, 65474, 65535 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Mid[2] = { + 0, 65535 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Mid[20] = { + 0, 28, 246, 459, 667, 1045, 1523, 2337, 4337, 11347, + 44231, 56709, 60781, 62243, 63161, 63969, 64608, 65062, 65502, 65535 +}; + +const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrMid[4] = { + WebRtcIsacfix_kPitchLagCdf1Mid, + WebRtcIsacfix_kPitchLagCdf2Mid, + WebRtcIsacfix_kPitchLagCdf3Mid, + WebRtcIsacfix_kPitchLagCdf4Mid +}; + +/* size of first cdf table */ +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeMid[1] = { + 256 +}; + +/* index limits and ranges */ +const WebRtc_Word16 WebRtcIsacfix_kLowerLimitMid[4] = { + -280, -17, 0, -9 +}; + +const WebRtc_Word16 WebRtcIsacfix_kUpperLimitMid[4] = { + -40, 17, 0, 9 +}; + +/* initial index for arithmetic decoder */ +const WebRtc_UWord16 WebRtcIsacfix_kInitIndMid[3] = { + 18, 1, 10 +}; + +/* mean values of pitch filter lags in Q10 */ + +const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Mid[35] = { + -17297, -16250, -15416, -14343, -13341, -12363, -11270, + -10355, -9122, -8217, -7172, -6083, -5102, -4004, -3060, + -1982, -952, -18, 935, 1976, 3040, 4032, + 5082, 6065, 7257, 8202, 9264, 10225, 11242, + 12234, 13337, 14336, 15374, 16187, 17347 +}; + + +const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Mid[19] = { + -8811, -8081, -7203, -6003, -5057, -4025, -2983, -1964, + -891, 29, 921, 1920, 2988, 4064, 5187, 6079, 7173, 8074, 8849 +}; + + +/* tables for use with large pitch gain */ + +/* cdf for quantized pitch filter lags */ +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Hi[511] = { + 0, 7, 18, 33, 69, 105, 156, 228, 315, 612, + 680, 691, 709, 724, 735, 738, 742, 746, 749, 753, + 756, 760, 764, 774, 782, 785, 789, 796, 800, 803, + 807, 814, 818, 822, 829, 832, 847, 854, 858, 869, + 876, 883, 898, 908, 934, 977, 1010, 1050, 1060, 1064, + 1075, 1078, 1086, 1089, 1093, 1104, 1111, 1122, 1133, 1136, + 1151, 1162, 1183, 1209, 1252, 1281, 1339, 1364, 1386, 1401, + 1411, 1415, 1426, 1430, 1433, 1440, 1448, 1455, 1462, 1477, + 1487, 1495, 1502, 1506, 1509, 1516, 1524, 1531, 1535, 1542, + 1553, 1556, 1578, 1589, 1611, 1625, 1639, 1643, 1654, 1665, + 1672, 1687, 1694, 1705, 1708, 1719, 1730, 1744, 1752, 1759, + 1791, 1795, 1820, 1867, 1886, 1915, 1936, 1943, 1965, 1987, + 2041, 2099, 2161, 2175, 2200, 2211, 2226, 2233, 2244, 2251, + 2266, 2280, 2287, 2298, 2309, 2316, 2331, 2342, 2356, 2378, + 2403, 2418, 2447, 2497, 2544, 2602, 2863, 2895, 2903, 2935, + 2950, 2971, 3004, 3011, 3018, 3029, 3040, 3062, 3087, 3127, + 3152, 3170, 3199, 3243, 3293, 3322, 3340, 3377, 3402, 3427, + 3474, 3518, 3543, 3579, 3601, 3637, 3659, 3706, 3731, 3760, + 3818, 3847, 3869, 3901, 3920, 3952, 4068, 4169, 4220, 4271, + 4524, 4571, 4604, 4632, 4672, 4730, 4777, 4806, 4857, 4904, + 4951, 5002, 5031, 5060, 5107, 5150, 5212, 5266, 5331, 5382, + 5432, 5490, 5544, 5610, 5700, 5762, 5812, 5874, 5972, 6022, + 6091, 6163, 6232, 6305, 6402, 6540, 6685, 6880, 7090, 7271, + 7379, 7452, 7542, 7625, 7687, 7770, 7843, 7911, 7966, 8024, + 8096, 8190, 8252, 8320, 8411, 8501, 8585, 8639, 8751, 8842, + 8918, 8986, 9066, 9127, 9203, 9269, 9345, 9406, 9464, 9536, + 9612, 9667, 9735, 9844, 9931, 10036, 10119, 10199, 10260, 10358, + 10441, 10514, 10666, 10734, 10872, 10951, 11053, 11125, 11223, 11324, + 11516, 11664, 11737, 11816, 11892, 12008, 12120, 12200, 12280, 12392, + 12490, 12576, 12685, 12812, 12917, 13003, 13108, 13210, 13300, 13384, + 13470, 13579, 13673, 13771, 13879, 13999, 14136, 14201, 14368, 14614, + 14759, 14867, 14958, 15030, 15121, 15189, 15280, 15385, 15461, 15555, + 15653, 15768, 15884, 15971, 16069, 16145, 16210, 16279, 16380, 16463, + 16539, 16615, 16688, 16818, 16919, 17017, 18041, 18338, 18523, 18649, + 18790, 18917, 19047, 19167, 19315, 19460, 19601, 19731, 19858, 20068, + 20173, 20318, 20466, 20625, 20741, 20911, 21045, 21201, 21396, 21588, + 21816, 22022, 22305, 22547, 22786, 23072, 23322, 23600, 23879, 24168, + 24433, 24769, 25120, 25511, 25895, 26289, 26792, 27219, 27683, 28077, + 28566, 29094, 29546, 29977, 30491, 30991, 31573, 32105, 32594, 33173, + 33788, 34497, 35181, 35833, 36488, 37255, 37921, 38645, 39275, 39894, + 40505, 41167, 41790, 42431, 43096, 43723, 44385, 45134, 45858, 46607, + 47349, 48091, 48768, 49405, 49955, 50555, 51167, 51985, 52611, 53078, + 53494, 53965, 54435, 54996, 55601, 56125, 56563, 56838, 57244, 57566, + 57967, 58297, 58771, 59093, 59419, 59647, 59886, 60143, 60461, 60693, + 60917, 61170, 61416, 61634, 61891, 62122, 62310, 62455, 62632, 62839, + 63103, 63436, 63639, 63805, 63906, 64015, 64192, 64355, 64475, 64558, + 64663, 64742, 64811, 64865, 64916, 64956, 64981, 65025, 65068, 65115, + 65195, 65314, 65419, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Hi[68] = { + 0, 7, 11, 22, 37, 52, 56, 59, 81, 85, + 89, 96, 115, 130, 137, 152, 170, 181, 193, 200, + 207, 233, 237, 259, 289, 318, 363, 433, 592, 992, + 1607, 3062, 6149, 12206, 25522, 48368, 58223, 61918, 63640, 64584, + 64943, 65098, 65206, 65268, 65294, 65335, 65350, 65372, 65387, 65402, + 65413, 65420, 65428, 65435, 65439, 65450, 65454, 65468, 65472, 65476, + 65483, 65491, 65498, 65505, 65516, 65520, 65528, 65535 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Hi[2] = { + 0, 65535 +}; + +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Hi[35] = { + 0, 7, 19, 30, 41, 48, 63, 74, 82, 96, + 122, 152, 215, 330, 701, 2611, 10931, 48106, 61177, 64341, + 65112, 65238, 65309, 65338, 65364, 65379, 65401, 65427, 65453, + 65465, 65476, 65490, 65509, 65528, 65535 +}; + +const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrHi[4] = { + WebRtcIsacfix_kPitchLagCdf1Hi, + WebRtcIsacfix_kPitchLagCdf2Hi, + WebRtcIsacfix_kPitchLagCdf3Hi, + WebRtcIsacfix_kPitchLagCdf4Hi +}; + +/* size of first cdf table */ +const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeHi[1] = { + 512 +}; + +/* index limits and ranges */ +const WebRtc_Word16 WebRtcIsacfix_kLowerLimitHi[4] = { + -552, -34, 0, -16 +}; + +const WebRtc_Word16 WebRtcIsacfix_kUpperLimitHi[4] = { + -80, 32, 0, 17 +}; + +/* initial index for arithmetic decoder */ +const WebRtc_UWord16 WebRtcIsacfix_kInitIndHi[3] = { + 34, 1, 18 +}; + +/* mean values of pitch filter lags */ + +const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Hi[67] = { + -17482, -16896, -16220, -15929, -15329, -14848, -14336, -13807, -13312, -12800, -12218, -11720, + -11307, -10649, -10396, -9742, -9148, -8668, -8297, -7718, -7155, -6656, -6231, -5600, -5129, + -4610, -4110, -3521, -3040, -2525, -2016, -1506, -995, -477, -5, 469, 991, 1510, 2025, 2526, 3079, + 3555, 4124, 4601, 5131, 5613, 6194, 6671, 7140, 7645, 8207, 8601, 9132, 9728, 10359, 10752, 11302, + 11776, 12288, 12687, 13204, 13759, 14295, 14810, 15360, 15764, 16350 +}; + + +const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Hi[34] = { + -8175, -7659, -7205, -6684, -6215, -5651, -5180, -4566, -4087, -3536, -3096, + -2532, -1990, -1482, -959, -440, 11, 451, 954, 1492, 2020, 2562, 3059, + 3577, 4113, 4618, 5134, 5724, 6060, 6758, 7015, 7716, 8066, 8741 +}; diff --git a/src/libs/webrtc/isac/pitch_lag_tables.h b/src/libs/webrtc/isac/pitch_lag_tables.h new file mode 100644 index 00000000..9517c29b --- /dev/null +++ b/src/libs/webrtc/isac/pitch_lag_tables.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * pitch_lag_tables.h + * + * This file contains tables for the pitch filter side-info in the entropy coder. + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_LAG_TABLES_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_LAG_TABLES_H_ + + +#include "typedefs.h" + + +/********************* Pitch Filter Lag Coefficient Tables ************************/ + +/* tables for use with small pitch gain */ + +/* cdfs for quantized pitch lags */ +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Lo[127]; +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Lo[20]; +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Lo[2]; +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Lo[10]; + +extern const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrLo[4]; + +/* size of first cdf table */ +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeLo[1]; + +/* index limits and ranges */ +extern const WebRtc_Word16 WebRtcIsacfix_kLowerLimitLo[4]; +extern const WebRtc_Word16 WebRtcIsacfix_kUpperLimitLo[4]; + +/* initial index for arithmetic decoder */ +extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndLo[3]; + +/* mean values of pitch filter lags */ +extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Lo[19]; +extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Lo[9]; + + + +/* tables for use with medium pitch gain */ + +/* cdfs for quantized pitch lags */ +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Mid[255]; +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Mid[36]; +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Mid[2]; +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Mid[20]; + +extern const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrMid[4]; + +/* size of first cdf table */ +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeMid[1]; + +/* index limits and ranges */ +extern const WebRtc_Word16 WebRtcIsacfix_kLowerLimitMid[4]; +extern const WebRtc_Word16 WebRtcIsacfix_kUpperLimitMid[4]; + +/* initial index for arithmetic decoder */ +extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndMid[3]; + +/* mean values of pitch filter lags */ +extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Mid[35]; +extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Mid[19]; + + +/* tables for use with large pitch gain */ + +/* cdfs for quantized pitch lags */ +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Hi[511]; +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Hi[68]; +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Hi[2]; +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Hi[35]; + +extern const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrHi[4]; + +/* size of first cdf table */ +extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeHi[1]; + +/* index limits and ranges */ +extern const WebRtc_Word16 WebRtcIsacfix_kLowerLimitHi[4]; +extern const WebRtc_Word16 WebRtcIsacfix_kUpperLimitHi[4]; + +/* initial index for arithmetic decoder */ +extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndHi[3]; + +/* mean values of pitch filter lags */ +extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Hi[67]; +extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Hi[34]; + + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_LAG_TABLES_H_ */ diff --git a/src/libs/webrtc/isac/settings.h b/src/libs/webrtc/isac/settings.h new file mode 100644 index 00000000..da88ba25 --- /dev/null +++ b/src/libs/webrtc/isac/settings.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * settings.h + * + * Declaration of #defines used in the iSAC codec + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SETTINGS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SETTINGS_H_ + + +/* sampling frequency (Hz) */ +#define FS 16000 +/* 1.5 times Sampling frequency */ +#define FS_1_HALF (WebRtc_UWord32) 24000 +/* Three times Sampling frequency */ +#define FS3 (WebRtc_UWord32) 48000 +/* Eight times Sampling frequency */ +#define FS8 (WebRtc_UWord32) 128000 + +/* number of samples per frame (either 480 (30ms) or 960 (60ms)) */ +#define INITIAL_FRAMESAMPLES 960 + +/* miliseconds */ +#define FRAMESIZE 30 +/* number of samples per frame processed in the encoder (30ms) */ +#define FRAMESAMPLES 480 /* ((FRAMESIZE*FS)/1000) */ +#define FRAMESAMPLES_HALF 240 +/* max number of samples per frame (= 60 ms frame) */ +#define MAX_FRAMESAMPLES 960 +/* number of samples per 10ms frame */ +#define FRAMESAMPLES_10ms 160 /* ((10*FS)/1000) */ +/* Number of samples per 1 ms */ +#define SAMPLES_PER_MSEC 16 +/* number of subframes */ +#define SUBFRAMES 6 +/* length of a subframe */ +#define UPDATE 80 +/* length of half a subframe (low/high band) */ +#define HALF_SUBFRAMELEN 40 /* (UPDATE/2) */ +/* samples of look ahead (in a half-band, so actually half the samples of look ahead @ FS) */ +#define QLOOKAHEAD 24 /* 3 ms */ + +/* order of AR model in spectral entropy coder */ +#define AR_ORDER 6 +#define MAX_ORDER 13 +#define LEVINSON_MAX_ORDER 12 + +/* window length (masking analysis) */ +#define WINLEN 256 +/* order of low-band pole filter used to approximate masking curve */ +#define ORDERLO 12 +/* order of hi-band pole filter used to approximate masking curve */ +#define ORDERHI 6 + +#define KLT_NUM_AVG_GAIN 0 +#define KLT_NUM_AVG_SHAPE 0 +#define KLT_NUM_MODELS 3 +#define LPC_SHAPE_ORDER 18 /* (ORDERLO + ORDERHI) */ + +#define KLT_ORDER_GAIN 12 /* (2 * SUBFRAMES) */ +#define KLT_ORDER_SHAPE 108 /* (LPC_SHAPE_ORDER * SUBFRAMES) */ + + + +/* order for post_filter_bank */ +#define POSTQORDER 3 +/* order for pre-filterbank */ +#define QORDER 3 +/* for decimator */ +#define ALLPASSSECTIONS 2 +/* The number of composite all-pass filter factors */ +#define NUMBEROFCOMPOSITEAPSECTIONS 4 + +/* The number of all-pass filter factors in an upper or lower channel*/ +#define NUMBEROFCHANNELAPSECTIONS 2 + + + +#define DPMIN_Q10 -10240 /* -10.00 in Q10 */ +#define DPMAX_Q10 10240 /* 10.00 in Q10 */ +#define MINBITS_Q10 10240 /* 10.0 in Q10 */ + + +/* array size for byte stream in number of Word16. */ +#define STREAM_MAXW16 300 /* The old maximum size still needed for the decoding */ +#define STREAM_MAXW16_30MS 100 /* 100 Word16 = 200 bytes = 53.4 kbit/s @ 30 ms.framelength */ +#define STREAM_MAXW16_60MS 200 /* 200 Word16 = 400 bytes = 53.4 kbit/s @ 60 ms.framelength */ + + +/* storage size for bit counts */ +//#define BIT_COUNTER_SIZE 30 +/* maximum order of any AR model or filter */ +#define MAX_AR_MODEL_ORDER 12 + +/* Maximum number of iterations allowed to limit payload size */ +#define MAX_PAYLOAD_LIMIT_ITERATION 1 + +/* Bandwidth estimator */ + +#define MIN_ISAC_BW 10000 /* Minimum bandwidth in bits per sec */ +#define MAX_ISAC_BW 32000 /* Maxmum bandwidth in bits per sec */ +#define MIN_ISAC_MD 5 /* Minimum Max Delay in ?? */ +#define MAX_ISAC_MD 25 /* Maxmum Max Delay in ?? */ +#define DELAY_CORRECTION_MAX 717 +#define DELAY_CORRECTION_MED 819 +#define Thld_30_60 18000 +#define Thld_60_30 27000 + +/* assumed header size; we don't know the exact number (header compression may be used) */ +#define HEADER_SIZE 35 /* bytes */ +#define INIT_FRAME_LEN 60 +#define INIT_BN_EST 20000 +#define INIT_BN_EST_Q7 2560000 /* 20 kbps in Q7 */ +#define INIT_REC_BN_EST_Q5 789312 /* INIT_BN_EST + INIT_HDR_RATE in Q5 */ + +/* 8738 in Q18 is ~ 1/30 */ +/* #define INIT_HDR_RATE (((HEADER_SIZE * 8 * 1000) * 8738) >> NUM_BITS_TO_SHIFT (INIT_FRAME_LEN)) */ +#define INIT_HDR_RATE 4666 +/* number of packets in a row for a high rate burst */ +#define BURST_LEN 3 +/* ms, max time between two full bursts */ +#define BURST_INTERVAL 800 +/* number of packets in a row for initial high rate burst */ +#define INIT_BURST_LEN 5 +/* bits/s, rate for the first BURST_LEN packets */ +#define INIT_RATE 10240000 /* INIT_BN_EST in Q9 */ + + +/* For pitch analysis */ +#define PITCH_FRAME_LEN 240 /* (FRAMESAMPLES/2) 30 ms */ +#define PITCH_MAX_LAG 140 /* 57 Hz */ +#define PITCH_MIN_LAG 20 /* 400 Hz */ +#define PITCH_MIN_LAG_Q8 5120 /* 256 * PITCH_MIN_LAG */ +#define OFFSET_Q8 768 /* 256 * 3 */ + +#define PITCH_MAX_GAIN_Q12 1843 /* 0.45 */ +#define PITCH_LAG_SPAN2 65 /* (PITCH_MAX_LAG/2-PITCH_MIN_LAG/2+5) */ +#define PITCH_CORR_LEN2 60 /* 15 ms */ +#define PITCH_CORR_STEP2 60 /* (PITCH_FRAME_LEN/4) */ +#define PITCH_SUBFRAMES 4 +#define PITCH_SUBFRAME_LEN 60 /* (PITCH_FRAME_LEN/PITCH_SUBFRAMES) */ + +/* For pitch filter */ +#define PITCH_BUFFSIZE 190 /* (PITCH_MAX_LAG + 50) Extra 50 for fraction and LP filters */ +#define PITCH_INTBUFFSIZE 430 /* (PITCH_FRAME_LEN+PITCH_BUFFSIZE) */ +#define PITCH_FRACS 8 +#define PITCH_FRACORDER 9 +#define PITCH_DAMPORDER 5 + + +/* Order of high pass filter */ +#define HPORDER 2 + + +/* PLC */ +#define DECAY_RATE 10 /* Q15, 20% of decay every lost frame apllied linearly sample by sample*/ +#define PLC_WAS_USED 1 +#define PLC_NOT_USED 3 +#define RECOVERY_OVERLAP 80 +#define RESAMP_RES 256 +#define RESAMP_RES_BIT 8 + + + +/* Define Error codes */ +/* 6000 General */ +#define ISAC_MEMORY_ALLOCATION_FAILED 6010 +#define ISAC_MODE_MISMATCH 6020 +#define ISAC_DISALLOWED_BOTTLENECK 6030 +#define ISAC_DISALLOWED_FRAME_LENGTH 6040 +/* 6200 Bandwidth estimator */ +#define ISAC_RANGE_ERROR_BW_ESTIMATOR 6240 +/* 6400 Encoder */ +#define ISAC_ENCODER_NOT_INITIATED 6410 +#define ISAC_DISALLOWED_CODING_MODE 6420 +#define ISAC_DISALLOWED_FRAME_MODE_ENCODER 6430 +#define ISAC_DISALLOWED_BITSTREAM_LENGTH 6440 +#define ISAC_PAYLOAD_LARGER_THAN_LIMIT 6450 +/* 6600 Decoder */ +#define ISAC_DECODER_NOT_INITIATED 6610 +#define ISAC_EMPTY_PACKET 6620 +#define ISAC_DISALLOWED_FRAME_MODE_DECODER 6630 +#define ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH 6640 +#define ISAC_RANGE_ERROR_DECODE_BANDWIDTH 6650 +#define ISAC_RANGE_ERROR_DECODE_PITCH_GAIN 6660 +#define ISAC_RANGE_ERROR_DECODE_PITCH_LAG 6670 +#define ISAC_RANGE_ERROR_DECODE_LPC 6680 +#define ISAC_RANGE_ERROR_DECODE_SPECTRUM 6690 +#define ISAC_LENGTH_MISMATCH 6730 +/* 6800 Call setup formats */ +#define ISAC_INCOMPATIBLE_FORMATS 6810 + + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SETTINGS_H_ */ diff --git a/src/libs/webrtc/isac/spectrum_ar_model_tables.c b/src/libs/webrtc/isac/spectrum_ar_model_tables.c new file mode 100644 index 00000000..81b932fd --- /dev/null +++ b/src/libs/webrtc/isac/spectrum_ar_model_tables.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * spectrum_ar_model_tables.c + * + * This file contains tables with AR coefficients, Gain coefficients + * and cosine tables. + * + */ + +#include "spectrum_ar_model_tables.h" +#include "settings.h" + +/********************* AR Coefficient Tables ************************/ + +/* cdf for quantized reflection coefficient 1 */ +const WebRtc_UWord16 WebRtcIsacfix_kRc1Cdf[12] = { + 0, 2, 4, 129, 7707, 57485, 65495, 65527, 65529, 65531, + 65533, 65535 +}; + +/* cdf for quantized reflection coefficient 2 */ +const WebRtc_UWord16 WebRtcIsacfix_kRc2Cdf[12] = { + 0, 2, 4, 7, 531, 25298, 64525, 65526, 65529, 65531, + 65533, 65535 +}; + +/* cdf for quantized reflection coefficient 3 */ +const WebRtc_UWord16 WebRtcIsacfix_kRc3Cdf[12] = { + 0, 2, 4, 6, 620, 22898, 64843, 65527, 65529, 65531, + 65533, 65535 +}; + +/* cdf for quantized reflection coefficient 4 */ +const WebRtc_UWord16 WebRtcIsacfix_kRc4Cdf[12] = { + 0, 2, 4, 6, 35, 10034, 60733, 65506, 65529, 65531, + 65533, 65535 +}; + +/* cdf for quantized reflection coefficient 5 */ +const WebRtc_UWord16 WebRtcIsacfix_kRc5Cdf[12] = { + 0, 2, 4, 6, 36, 7567, 56727, 65385, 65529, 65531, + 65533, 65535 +}; + +/* cdf for quantized reflection coefficient 6 */ +const WebRtc_UWord16 WebRtcIsacfix_kRc6Cdf[12] = { + 0, 2, 4, 6, 14, 6579, 57360, 65409, 65529, 65531, + 65533, 65535 +}; + +/* representation levels for quantized reflection coefficient 1 */ +const WebRtc_Word16 WebRtcIsacfix_kRc1Levels[11] = { + -32104, -29007, -23202, -15496, -9279, -2577, 5934, 17535, 24512, 29503, 32104 +}; + +/* representation levels for quantized reflection coefficient 2 */ +const WebRtc_Word16 WebRtcIsacfix_kRc2Levels[11] = { + -32104, -29503, -23494, -15261, -7309, -1399, 6158, 16381, 24512, 29503, 32104 +}; + +/* representation levels for quantized reflection coefficient 3 */ +const WebRtc_Word16 WebRtcIsacfix_kRc3Levels[11] = { + -32104, -29503, -23157, -15186, -7347, -1359, 5829, 17535, 24512, 29503, 32104 +}; + +/* representation levels for quantized reflection coefficient 4 */ +const WebRtc_Word16 WebRtcIsacfix_kRc4Levels[11] = { + -32104, -29503, -24512, -15362, -6665, -342, 6596, 14585, 24512, 29503, 32104 +}; + +/* representation levels for quantized reflection coefficient 5 */ +const WebRtc_Word16 WebRtcIsacfix_kRc5Levels[11] = { + -32104, -29503, -24512, -15005, -6564, -106, 7123, 14920, 24512, 29503, 32104 +}; + +/* representation levels for quantized reflection coefficient 6 */ +const WebRtc_Word16 WebRtcIsacfix_kRc6Levels[11] = { + -32104, -29503, -24512, -15096, -6656, -37, 7036, 14847, 24512, 29503, 32104 +}; + +/* quantization boundary levels for reflection coefficients */ +const WebRtc_Word16 WebRtcIsacfix_kRcBound[12] = { + -32768, -31441, -27566, -21458, -13612, -4663, + 4663, 13612, 21458, 27566, 31441, 32767 +}; + +/* initial index for AR reflection coefficient quantizer and cdf table search */ +const WebRtc_UWord16 WebRtcIsacfix_kRcInitInd[6] = { + 5, 5, 5, 5, 5, 5 +}; + +/* pointers to AR cdf tables */ +const WebRtc_UWord16 *WebRtcIsacfix_kRcCdfPtr[AR_ORDER] = { + WebRtcIsacfix_kRc1Cdf, + WebRtcIsacfix_kRc2Cdf, + WebRtcIsacfix_kRc3Cdf, + WebRtcIsacfix_kRc4Cdf, + WebRtcIsacfix_kRc5Cdf, + WebRtcIsacfix_kRc6Cdf +}; + +/* pointers to AR representation levels tables */ +const WebRtc_Word16 *WebRtcIsacfix_kRcLevPtr[AR_ORDER] = { + WebRtcIsacfix_kRc1Levels, + WebRtcIsacfix_kRc2Levels, + WebRtcIsacfix_kRc3Levels, + WebRtcIsacfix_kRc4Levels, + WebRtcIsacfix_kRc5Levels, + WebRtcIsacfix_kRc6Levels +}; + + +/******************** GAIN Coefficient Tables ***********************/ + +/* cdf for Gain coefficient */ +const WebRtc_UWord16 WebRtcIsacfix_kGainCdf[19] = { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 1172, + 11119, 29411, 51699, 64445, 65527, 65529, 65531, 65533, 65535 +}; + +/* representation levels for quantized squared Gain coefficient */ +const WebRtc_Word32 WebRtcIsacfix_kGain2Lev[18] = { + 128, 128, 128, 128, 128, 215, 364, 709, 1268, + 1960, 3405, 6078, 11286, 17827, 51918, 134498, 487432, 2048000 +}; + +/* quantization boundary levels for squared Gain coefficient */ +const WebRtc_Word32 WebRtcIsacfix_kGain2Bound[19] = { + 0, 21, 35, 59, 99, 166, 280, 475, 815, 1414, + 2495, 4505, 8397, 16405, 34431, 81359, 240497, 921600, 0x7FFFFFFF +}; + +/* pointers to Gain cdf table */ +const WebRtc_UWord16 *WebRtcIsacfix_kGainPtr[1] = { + WebRtcIsacfix_kGainCdf +}; + +/* gain initial index for gain quantizer and cdf table search */ +const WebRtc_UWord16 WebRtcIsacfix_kGainInitInd[1] = { + 11 +}; + + +/************************* Cosine Tables ****************************/ + +/* cosine table */ +const WebRtc_Word16 WebRtcIsacfix_kCos[6][60] = { + { 512, 512, 511, 510, 508, 507, 505, 502, 499, 496, + 493, 489, 485, 480, 476, 470, 465, 459, 453, 447, + 440, 433, 426, 418, 410, 402, 394, 385, 376, 367, + 357, 348, 338, 327, 317, 306, 295, 284, 273, 262, + 250, 238, 226, 214, 202, 190, 177, 165, 152, 139, + 126, 113, 100, 87, 73, 60, 47, 33, 20, 7 }, + { 512, 510, 508, 503, 498, 491, 483, 473, 462, 450, + 437, 422, 406, 389, 371, 352, 333, 312, 290, 268, + 244, 220, 196, 171, 145, 120, 93, 67, 40, 13, + -13, -40, -67, -93, -120, -145, -171, -196, -220, -244, + -268, -290, -312, -333, -352, -371, -389, -406, -422, -437, + -450, -462, -473, -483, -491, -498, -503, -508, -510, -512 }, + { 512, 508, 502, 493, 480, 465, 447, 426, 402, 376, + 348, 317, 284, 250, 214, 177, 139, 100, 60, 20, + -20, -60, -100, -139, -177, -214, -250, -284, -317, -348, + -376, -402, -426, -447, -465, -480, -493, -502, -508, -512, + -512, -508, -502, -493, -480, -465, -447, -426, -402, -376, + -348, -317, -284, -250, -214, -177, -139, -100, -60, -20 }, + { 511, 506, 495, 478, 456, 429, 398, 362, 322, 279, + 232, 183, 133, 80, 27, -27, -80, -133, -183, -232, + -279, -322, -362, -398, -429, -456, -478, -495, -506, -511, + -511, -506, -495, -478, -456, -429, -398, -362, -322, -279, + -232, -183, -133, -80, -27, 27, 80, 133, 183, 232, + 279, 322, 362, 398, 429, 456, 478, 495, 506, 511 }, + { 511, 502, 485, 459, 426, 385, 338, 284, 226, 165, + 100, 33, -33, -100, -165, -226, -284, -338, -385, -426, + -459, -485, -502, -511, -511, -502, -485, -459, -426, -385, + -338, -284, -226, -165, -100, -33, 33, 100, 165, 226, + 284, 338, 385, 426, 459, 485, 502, 511, 511, 502, + 485, 459, 426, 385, 338, 284, 226, 165, 100, 33 }, + { 510, 498, 473, 437, 389, 333, 268, 196, 120, 40, + -40, -120, -196, -268, -333, -389, -437, -473, -498, -510, + -510, -498, -473, -437, -389, -333, -268, -196, -120, -40, + 40, 120, 196, 268, 333, 389, 437, 473, 498, 510, + 510, 498, 473, 437, 389, 333, 268, 196, 120, 40, + -40, -120, -196, -268, -333, -389, -437, -473, -498, -510 } +}; diff --git a/src/libs/webrtc/isac/spectrum_ar_model_tables.h b/src/libs/webrtc/isac/spectrum_ar_model_tables.h new file mode 100644 index 00000000..b506d0e4 --- /dev/null +++ b/src/libs/webrtc/isac/spectrum_ar_model_tables.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * spectrum_ar_model_tables.h + * + * This file contains definitions of tables with AR coefficients, + * Gain coefficients and cosine tables. + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_ + +#include "typedefs.h" +#include "settings.h" + + +/********************* AR Coefficient Tables ************************/ +/* cdf for quantized reflection coefficient 1 */ +extern const WebRtc_UWord16 WebRtcIsacfix_kRc1Cdf[12]; + +/* cdf for quantized reflection coefficient 2 */ +extern const WebRtc_UWord16 WebRtcIsacfix_kRc2Cdf[12]; + +/* cdf for quantized reflection coefficient 3 */ +extern const WebRtc_UWord16 WebRtcIsacfix_kRc3Cdf[12]; + +/* cdf for quantized reflection coefficient 4 */ +extern const WebRtc_UWord16 WebRtcIsacfix_kRc4Cdf[12]; + +/* cdf for quantized reflection coefficient 5 */ +extern const WebRtc_UWord16 WebRtcIsacfix_kRc5Cdf[12]; + +/* cdf for quantized reflection coefficient 6 */ +extern const WebRtc_UWord16 WebRtcIsacfix_kRc6Cdf[12]; + +/* representation levels for quantized reflection coefficient 1 */ +extern const WebRtc_Word16 WebRtcIsacfix_kRc1Levels[11]; + +/* representation levels for quantized reflection coefficient 2 */ +extern const WebRtc_Word16 WebRtcIsacfix_kRc2Levels[11]; + +/* representation levels for quantized reflection coefficient 3 */ +extern const WebRtc_Word16 WebRtcIsacfix_kRc3Levels[11]; + +/* representation levels for quantized reflection coefficient 4 */ +extern const WebRtc_Word16 WebRtcIsacfix_kRc4Levels[11]; + +/* representation levels for quantized reflection coefficient 5 */ +extern const WebRtc_Word16 WebRtcIsacfix_kRc5Levels[11]; + +/* representation levels for quantized reflection coefficient 6 */ +extern const WebRtc_Word16 WebRtcIsacfix_kRc6Levels[11]; + +/* quantization boundary levels for reflection coefficients */ +extern const WebRtc_Word16 WebRtcIsacfix_kRcBound[12]; + +/* initial indices for AR reflection coefficient quantizer and cdf table search */ +extern const WebRtc_UWord16 WebRtcIsacfix_kRcInitInd[AR_ORDER]; + +/* pointers to AR cdf tables */ +extern const WebRtc_UWord16 *WebRtcIsacfix_kRcCdfPtr[AR_ORDER]; + +/* pointers to AR representation levels tables */ +extern const WebRtc_Word16 *WebRtcIsacfix_kRcLevPtr[AR_ORDER]; + + +/******************** GAIN Coefficient Tables ***********************/ +/* cdf for Gain coefficient */ +extern const WebRtc_UWord16 WebRtcIsacfix_kGainCdf[19]; + +/* representation levels for quantized Gain coefficient */ +extern const WebRtc_Word32 WebRtcIsacfix_kGain2Lev[18]; + +/* squared quantization boundary levels for Gain coefficient */ +extern const WebRtc_Word32 WebRtcIsacfix_kGain2Bound[19]; + +/* pointer to Gain cdf table */ +extern const WebRtc_UWord16 *WebRtcIsacfix_kGainPtr[1]; + +/* Gain initial index for gain quantizer and cdf table search */ +extern const WebRtc_UWord16 WebRtcIsacfix_kGainInitInd[1]; + +/************************* Cosine Tables ****************************/ +/* Cosine table */ +extern const WebRtc_Word16 WebRtcIsacfix_kCos[6][60]; + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_ */ diff --git a/src/libs/webrtc/isac/structs.h b/src/libs/webrtc/isac/structs.h new file mode 100644 index 00000000..54dffa92 --- /dev/null +++ b/src/libs/webrtc/isac/structs.h @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * structs.h + * + * This header file contains all the structs used in the ISAC codec + * + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_STRUCTS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_STRUCTS_H_ + + +#include "typedefs.h" +#include "signal_processing_library.h" +#include "settings.h" + +/* Bitstream struct for decoder */ +typedef struct Bitstreamstruct_dec { + + WebRtc_UWord16 *stream; /* Pointer to bytestream to decode */ + WebRtc_UWord32 W_upper; /* Upper boundary of interval W */ + WebRtc_UWord32 streamval; + WebRtc_UWord16 stream_index; /* Index to the current position in bytestream */ + WebRtc_Word16 full; /* 0 - first byte in memory filled, second empty*/ + /* 1 - both bytes are empty (we just filled the previous memory */ + +} Bitstr_dec; + +/* Bitstream struct for encoder */ +typedef struct Bitstreamstruct_enc { + + WebRtc_UWord16 stream[STREAM_MAXW16_60MS]; /* Vector for adding encoded bytestream */ + WebRtc_UWord32 W_upper; /* Upper boundary of interval W */ + WebRtc_UWord32 streamval; + WebRtc_UWord16 stream_index; /* Index to the current position in bytestream */ + WebRtc_Word16 full; /* 0 - first byte in memory filled, second empty*/ + /* 1 - both bytes are empty (we just filled the previous memory */ + +} Bitstr_enc; + + +typedef struct { + + WebRtc_Word16 DataBufferLoQ0[WINLEN]; + WebRtc_Word16 DataBufferHiQ0[WINLEN]; + + WebRtc_Word32 CorrBufLoQQ[ORDERLO+1]; + WebRtc_Word32 CorrBufHiQQ[ORDERHI+1]; + + WebRtc_Word16 CorrBufLoQdom[ORDERLO+1]; + WebRtc_Word16 CorrBufHiQdom[ORDERHI+1]; + + WebRtc_Word32 PreStateLoGQ15[ORDERLO+1]; + WebRtc_Word32 PreStateHiGQ15[ORDERHI+1]; + + WebRtc_UWord32 OldEnergy; + +} MaskFiltstr_enc; + + + +typedef struct { + + WebRtc_Word16 PostStateLoGQ0[ORDERLO+1]; + WebRtc_Word16 PostStateHiGQ0[ORDERHI+1]; + + WebRtc_UWord32 OldEnergy; + +} MaskFiltstr_dec; + + + + + + + + +typedef struct { + + //state vectors for each of the two analysis filters + + WebRtc_Word32 INSTAT1_fix[2*(QORDER-1)]; + WebRtc_Word32 INSTAT2_fix[2*(QORDER-1)]; + WebRtc_Word16 INLABUF1_fix[QLOOKAHEAD]; + WebRtc_Word16 INLABUF2_fix[QLOOKAHEAD]; + + /* High pass filter */ + WebRtc_Word32 HPstates_fix[HPORDER]; + +} PreFiltBankstr; + + +typedef struct { + + //state vectors for each of the two analysis filters + WebRtc_Word32 STATE_0_LOWER_fix[2*POSTQORDER]; + WebRtc_Word32 STATE_0_UPPER_fix[2*POSTQORDER]; + + /* High pass filter */ + + WebRtc_Word32 HPstates1_fix[HPORDER]; + WebRtc_Word32 HPstates2_fix[HPORDER]; + +} PostFiltBankstr; + +typedef struct { + + + /* data buffer for pitch filter */ + WebRtc_Word16 ubufQQ[PITCH_BUFFSIZE]; + + /* low pass state vector */ + WebRtc_Word16 ystateQQ[PITCH_DAMPORDER]; + + /* old lag and gain */ + WebRtc_Word16 oldlagQ7; + WebRtc_Word16 oldgainQ12; + +} PitchFiltstr; + + + +typedef struct { + + //for inital estimator + WebRtc_Word16 dec_buffer16[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2]; + WebRtc_Word32 decimator_state32[2*ALLPASSSECTIONS+1]; + WebRtc_Word16 inbuf[QLOOKAHEAD]; + + PitchFiltstr PFstr_wght; + PitchFiltstr PFstr; + + +} PitchAnalysisStruct; + + +typedef struct { + /* Parameters used in PLC to avoid re-computation */ + + /* --- residual signals --- */ + WebRtc_Word16 prevPitchInvIn[FRAMESAMPLES/2]; + WebRtc_Word16 prevPitchInvOut[PITCH_MAX_LAG + 10]; // [FRAMESAMPLES/2]; save 90 + WebRtc_Word32 prevHP[PITCH_MAX_LAG + 10]; // [FRAMESAMPLES/2]; save 90 + + + WebRtc_Word16 decayCoeffPriodic; /* how much to supress a sample */ + WebRtc_Word16 decayCoeffNoise; + WebRtc_Word16 used; /* if PLC is used */ + + + WebRtc_Word16 *lastPitchLP; // [FRAMESAMPLES/2]; saved 240; + + + /* --- LPC side info --- */ + WebRtc_Word16 lofilt_coefQ15[ ORDERLO ]; + WebRtc_Word16 hifilt_coefQ15[ ORDERHI ]; + WebRtc_Word32 gain_lo_hiQ17[2]; + + /* --- LTP side info --- */ + WebRtc_Word16 AvgPitchGain_Q12; + WebRtc_Word16 lastPitchGain_Q12; + WebRtc_Word16 lastPitchLag_Q7; + + /* --- Add-overlap in recovery packet --- */ + WebRtc_Word16 overlapLP[ RECOVERY_OVERLAP ]; // [FRAMESAMPLES/2]; saved 160 + + WebRtc_Word16 pitchCycles; + WebRtc_Word16 A; + WebRtc_Word16 B; + WebRtc_Word16 pitchIndex; + WebRtc_Word16 stretchLag; + WebRtc_Word16 *prevPitchLP; // [ FRAMESAMPLES/2 ]; saved 240 + WebRtc_Word16 seed; + + WebRtc_Word16 std; +} PLCstr; + + + +/* Have instance of struct together with other iSAC structs */ +typedef struct { + + WebRtc_Word16 prevFrameSizeMs; /* Previous frame size (in ms) */ + WebRtc_UWord16 prevRtpNumber; /* Previous RTP timestamp from received packet */ + /* (in samples relative beginning) */ + WebRtc_UWord32 prevSendTime; /* Send time for previous packet, from RTP header */ + WebRtc_UWord32 prevArrivalTime; /* Arrival time for previous packet (in ms using timeGetTime()) */ + WebRtc_UWord16 prevRtpRate; /* rate of previous packet, derived from RTP timestamps (in bits/s) */ + WebRtc_UWord32 lastUpdate; /* Time since the last update of the Bottle Neck estimate (in samples) */ + WebRtc_UWord32 lastReduction; /* Time sinse the last reduction (in samples) */ + WebRtc_Word32 countUpdates; /* How many times the estimate was update in the beginning */ + + /* The estimated bottle neck rate from there to here (in bits/s) */ + WebRtc_UWord32 recBw; + WebRtc_UWord32 recBwInv; + WebRtc_UWord32 recBwAvg; + WebRtc_UWord32 recBwAvgQ; + + WebRtc_UWord32 minBwInv; + WebRtc_UWord32 maxBwInv; + + /* The estimated mean absolute jitter value, as seen on this side (in ms) */ + WebRtc_Word32 recJitter; + WebRtc_Word32 recJitterShortTerm; + WebRtc_Word32 recJitterShortTermAbs; + WebRtc_Word32 recMaxDelay; + WebRtc_Word32 recMaxDelayAvgQ; + + + WebRtc_Word16 recHeaderRate; /* (assumed) bitrate for headers (bps) */ + + WebRtc_UWord32 sendBwAvg; /* The estimated bottle neck rate from here to there (in bits/s) */ + WebRtc_Word32 sendMaxDelayAvg; /* The estimated mean absolute jitter value, as seen on the other siee (in ms) */ + + + WebRtc_Word16 countRecPkts; /* number of packets received since last update */ + WebRtc_Word16 highSpeedRec; /* flag for marking that a high speed network has been detected downstream */ + + /* number of consecutive pkts sent during which the bwe estimate has + remained at a value greater than the downstream threshold for determining highspeed network */ + WebRtc_Word16 countHighSpeedRec; + + /* flag indicating bwe should not adjust down immediately for very late pckts */ + WebRtc_Word16 inWaitPeriod; + + /* variable holding the time of the start of a window of time when + bwe should not adjust down immediately for very late pckts */ + WebRtc_UWord32 startWaitPeriod; + + /* number of consecutive pkts sent during which the bwe estimate has + remained at a value greater than the upstream threshold for determining highspeed network */ + WebRtc_Word16 countHighSpeedSent; + + /* flag indicated the desired number of packets over threshold rate have been sent and + bwe will assume the connection is over broadband network */ + WebRtc_Word16 highSpeedSend; + + + + +} BwEstimatorstr; + + +typedef struct { + + /* boolean, flags if previous packet exceeded B.N. */ + WebRtc_Word16 PrevExceed; + /* ms */ + WebRtc_Word16 ExceedAgo; + /* packets left to send in current burst */ + WebRtc_Word16 BurstCounter; + /* packets */ + WebRtc_Word16 InitCounter; + /* ms remaining in buffer when next packet will be sent */ + WebRtc_Word16 StillBuffered; + +} RateModel; + +/* The following strutc is used to store data from encoding, to make it + fast and easy to construct a new bitstream with a different Bandwidth + estimate. All values (except framelength and minBytes) is double size to + handle 60 ms of data. +*/ +typedef struct { + + /* Used to keep track of if it is first or second part of 60 msec packet */ + int startIdx; + + /* Frame length in samples */ + WebRtc_Word16 framelength; + + /* Pitch Gain */ + WebRtc_Word16 pitchGain_index[2]; + + /* Pitch Lag */ + WebRtc_Word32 meanGain[2]; + WebRtc_Word16 pitchIndex[PITCH_SUBFRAMES*2]; + + /* LPC */ + WebRtc_Word32 LPCcoeffs_g[12*2]; /* KLT_ORDER_GAIN = 12 */ + WebRtc_Word16 LPCindex_s[108*2]; /* KLT_ORDER_SHAPE = 108 */ + WebRtc_Word16 LPCindex_g[12*2]; /* KLT_ORDER_GAIN = 12 */ + + /* Encode Spec */ + WebRtc_Word16 fre[FRAMESAMPLES]; + WebRtc_Word16 fim[FRAMESAMPLES]; + WebRtc_Word16 AvgPitchGain[2]; + + /* Used in adaptive mode only */ + int minBytes; + +} ISAC_SaveEncData_t; + +typedef struct { + + Bitstr_enc bitstr_obj; + MaskFiltstr_enc maskfiltstr_obj; + PreFiltBankstr prefiltbankstr_obj; + PitchFiltstr pitchfiltstr_obj; + PitchAnalysisStruct pitchanalysisstr_obj; + RateModel rate_data_obj; + + WebRtc_Word16 buffer_index; + WebRtc_Word16 current_framesamples; + + WebRtc_Word16 data_buffer_fix[FRAMESAMPLES]; // the size was MAX_FRAMESAMPLES + + WebRtc_Word16 frame_nb; + WebRtc_Word16 BottleNeck; + WebRtc_Word16 MaxDelay; + WebRtc_Word16 new_framelength; + WebRtc_Word16 s2nr; + WebRtc_UWord16 MaxBits; + + WebRtc_Word16 bitstr_seed; +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED + PostFiltBankstr interpolatorstr_obj; +#endif + + ISAC_SaveEncData_t *SaveEnc_ptr; + WebRtc_Word16 payloadLimitBytes30; /* Maximum allowed number of bits for a 30 msec packet */ + WebRtc_Word16 payloadLimitBytes60; /* Maximum allowed number of bits for a 30 msec packet */ + WebRtc_Word16 maxPayloadBytes; /* Maximum allowed number of bits for both 30 and 60 msec packet */ + WebRtc_Word16 maxRateInBytes; /* Maximum allowed rate in bytes per 30 msec packet */ + WebRtc_Word16 enforceFrameSize; /* If set iSAC will never change packet size */ + +} ISACFIX_EncInst_t; + + +typedef struct { + + Bitstr_dec bitstr_obj; + MaskFiltstr_dec maskfiltstr_obj; + PostFiltBankstr postfiltbankstr_obj; + PitchFiltstr pitchfiltstr_obj; + PLCstr plcstr_obj; /* TS; for packet loss concealment */ + +#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED + PreFiltBankstr decimatorstr_obj; +#endif + +} ISACFIX_DecInst_t; + + + +typedef struct { + + ISACFIX_EncInst_t ISACenc_obj; + ISACFIX_DecInst_t ISACdec_obj; + BwEstimatorstr bwestimator_obj; + WebRtc_Word16 CodingMode; /* 0 = adaptive; 1 = instantaneous */ + WebRtc_Word16 errorcode; + WebRtc_Word16 initflag; /* 0 = nothing initiated; 1 = encoder or decoder */ + /* not initiated; 2 = all initiated */ +} ISACFIX_SubStruct; + + +typedef struct { + WebRtc_Word32 lpcGains[12]; /* 6 lower-band & 6 upper-band we may need to double it for 60*/ + /* */ + WebRtc_UWord32 W_upper; /* Upper boundary of interval W */ + WebRtc_UWord32 streamval; + WebRtc_UWord16 stream_index; /* Index to the current position in bytestream */ + WebRtc_Word16 full; /* 0 - first byte in memory filled, second empty*/ + /* 1 - both bytes are empty (we just filled the previous memory */ + WebRtc_UWord16 beforeLastWord; + WebRtc_UWord16 lastWord; +} transcode_obj; + + +//Bitstr_enc myBitStr; + +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_STRUCTS_H_ */ diff --git a/src/libs/webrtc/isac/transform.c b/src/libs/webrtc/isac/transform.c new file mode 100644 index 00000000..56ef9f2f --- /dev/null +++ b/src/libs/webrtc/isac/transform.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * WebRtcIsacfix_kTransform.c + * + * Transform functions + * + */ + +#include "fft.h" +#include "codec.h" +#include "settings.h" + + +/* Cosine table 1 in Q14 */ +static const WebRtc_Word16 kCosTab1[FRAMESAMPLES/2] = { + 16384, 16383, 16378, 16371, 16362, 16349, 16333, 16315, 16294, 16270, + 16244, 16214, 16182, 16147, 16110, 16069, 16026, 15980, 15931, 15880, + 15826, 15769, 15709, 15647, 15582, 15515, 15444, 15371, 15296, 15218, + 15137, 15053, 14968, 14879, 14788, 14694, 14598, 14500, 14399, 14295, + 14189, 14081, 13970, 13856, 13741, 13623, 13502, 13380, 13255, 13128, + 12998, 12867, 12733, 12597, 12458, 12318, 12176, 12031, 11885, 11736, + 11585, 11433, 11278, 11121, 10963, 10803, 10641, 10477, 10311, 10143, + 9974, 9803, 9630, 9456, 9280, 9102, 8923, 8743, 8561, 8377, + 8192, 8006, 7818, 7629, 7438, 7246, 7053, 6859, 6664, 6467, + 6270, 6071, 5872, 5671, 5469, 5266, 5063, 4859, 4653, 4447, + 4240, 4033, 3825, 3616, 3406, 3196, 2986, 2775, 2563, 2351, + 2139, 1926, 1713, 1499, 1285, 1072, 857, 643, 429, 214, + 0, -214, -429, -643, -857, -1072, -1285, -1499, -1713, -1926, + -2139, -2351, -2563, -2775, -2986, -3196, -3406, -3616, -3825, -4033, + -4240, -4447, -4653, -4859, -5063, -5266, -5469, -5671, -5872, -6071, + -6270, -6467, -6664, -6859, -7053, -7246, -7438, -7629, -7818, -8006, + -8192, -8377, -8561, -8743, -8923, -9102, -9280, -9456, -9630, -9803, + -9974, -10143, -10311, -10477, -10641, -10803, -10963, -11121, -11278, -11433, + -11585, -11736, -11885, -12031, -12176, -12318, -12458, -12597, -12733, -12867, + -12998, -13128, -13255, -13380, -13502, -13623, -13741, -13856, -13970, -14081, + -14189, -14295, -14399, -14500, -14598, -14694, -14788, -14879, -14968, -15053, + -15137, -15218, -15296, -15371, -15444, -15515, -15582, -15647, -15709, -15769, + -15826, -15880, -15931, -15980, -16026, -16069, -16110, -16147, -16182, -16214, + -16244, -16270, -16294, -16315, -16333, -16349, -16362, -16371, -16378, -16383 +}; + + +/* Sine table 1 in Q14 */ +static const WebRtc_Word16 kSinTab1[FRAMESAMPLES/2] = { + 0, 214, 429, 643, 857, 1072, 1285, 1499, 1713, 1926, + 2139, 2351, 2563, 2775, 2986, 3196, 3406, 3616, 3825, 4033, + 4240, 4447, 4653, 4859, 5063, 5266, 5469, 5671, 5872, 6071, + 6270, 6467, 6664, 6859, 7053, 7246, 7438, 7629, 7818, 8006, + 8192, 8377, 8561, 8743, 8923, 9102, 9280, 9456, 9630, 9803, + 9974, 10143, 10311, 10477, 10641, 10803, 10963, 11121, 11278, 11433, + 11585, 11736, 11885, 12031, 12176, 12318, 12458, 12597, 12733, 12867, + 12998, 13128, 13255, 13380, 13502, 13623, 13741, 13856, 13970, 14081, + 14189, 14295, 14399, 14500, 14598, 14694, 14788, 14879, 14968, 15053, + 15137, 15218, 15296, 15371, 15444, 15515, 15582, 15647, 15709, 15769, + 15826, 15880, 15931, 15980, 16026, 16069, 16110, 16147, 16182, 16214, + 16244, 16270, 16294, 16315, 16333, 16349, 16362, 16371, 16378, 16383, + 16384, 16383, 16378, 16371, 16362, 16349, 16333, 16315, 16294, 16270, + 16244, 16214, 16182, 16147, 16110, 16069, 16026, 15980, 15931, 15880, + 15826, 15769, 15709, 15647, 15582, 15515, 15444, 15371, 15296, 15218, + 15137, 15053, 14968, 14879, 14788, 14694, 14598, 14500, 14399, 14295, + 14189, 14081, 13970, 13856, 13741, 13623, 13502, 13380, 13255, 13128, + 12998, 12867, 12733, 12597, 12458, 12318, 12176, 12031, 11885, 11736, + 11585, 11433, 11278, 11121, 10963, 10803, 10641, 10477, 10311, 10143, + 9974, 9803, 9630, 9456, 9280, 9102, 8923, 8743, 8561, 8377, + 8192, 8006, 7818, 7629, 7438, 7246, 7053, 6859, 6664, 6467, + 6270, 6071, 5872, 5671, 5469, 5266, 5063, 4859, 4653, 4447, + 4240, 4033, 3825, 3616, 3406, 3196, 2986, 2775, 2563, 2351, + 2139, 1926, 1713, 1499, 1285, 1072, 857, 643, 429, 214 +}; + + +/* Cosine table 2 in Q14 */ +static const WebRtc_Word16 kCosTab2[FRAMESAMPLES/4] = { + 107, -322, 536, -750, 965, -1179, 1392, -1606, 1819, -2032, + 2245, -2457, 2669, -2880, 3091, -3301, 3511, -3720, 3929, -4137, + 4344, -4550, 4756, -4961, 5165, -5368, 5570, -5771, 5971, -6171, + 6369, -6566, 6762, -6957, 7150, -7342, 7534, -7723, 7912, -8099, + 8285, -8469, 8652, -8833, 9013, -9191, 9368, -9543, 9717, -9889, + 10059, -10227, 10394, -10559, 10722, -10883, 11042, -11200, 11356, -11509, + 11661, -11810, 11958, -12104, 12247, -12389, 12528, -12665, 12800, -12933, + 13063, -13192, 13318, -13441, 13563, -13682, 13799, -13913, 14025, -14135, + 14242, -14347, 14449, -14549, 14647, -14741, 14834, -14924, 15011, -15095, + 15178, -15257, 15334, -15408, 15480, -15549, 15615, -15679, 15739, -15798, + 15853, -15906, 15956, -16003, 16048, -16090, 16129, -16165, 16199, -16229, + 16257, -16283, 16305, -16325, 16342, -16356, 16367, -16375, 16381, -16384 +}; + + +/* Sine table 2 in Q14 */ +static const WebRtc_Word16 kSinTab2[FRAMESAMPLES/4] = { + 16384, -16381, 16375, -16367, 16356, -16342, 16325, -16305, 16283, -16257, + 16229, -16199, 16165, -16129, 16090, -16048, 16003, -15956, 15906, -15853, + 15798, -15739, 15679, -15615, 15549, -15480, 15408, -15334, 15257, -15178, + 15095, -15011, 14924, -14834, 14741, -14647, 14549, -14449, 14347, -14242, + 14135, -14025, 13913, -13799, 13682, -13563, 13441, -13318, 13192, -13063, + 12933, -12800, 12665, -12528, 12389, -12247, 12104, -11958, 11810, -11661, + 11509, -11356, 11200, -11042, 10883, -10722, 10559, -10394, 10227, -10059, + 9889, -9717, 9543, -9368, 9191, -9013, 8833, -8652, 8469, -8285, + 8099, -7912, 7723, -7534, 7342, -7150, 6957, -6762, 6566, -6369, + 6171, -5971, 5771, -5570, 5368, -5165, 4961, -4756, 4550, -4344, + 4137, -3929, 3720, -3511, 3301, -3091, 2880, -2669, 2457, -2245, + 2032, -1819, 1606, -1392, 1179, -965, 750, -536, 322, -107 +}; + + + +void WebRtcIsacfix_Time2Spec(WebRtc_Word16 *inre1Q9, + WebRtc_Word16 *inre2Q9, + WebRtc_Word16 *outreQ7, + WebRtc_Word16 *outimQ7) +{ + + int k; + WebRtc_Word32 tmpreQ16[FRAMESAMPLES/2], tmpimQ16[FRAMESAMPLES/2]; + WebRtc_Word16 tmp1rQ14, tmp1iQ14; + WebRtc_Word32 xrQ16, xiQ16, yrQ16, yiQ16; + WebRtc_Word32 v1Q16, v2Q16; + WebRtc_Word16 factQ19, sh; + + /* Multiply with complex exponentials and combine into one complex vector */ + factQ19 = 16921; // 0.5/sqrt(240) in Q19 is round(.5/sqrt(240)*(2^19)) = 16921 + for (k = 0; k < FRAMESAMPLES/2; k++) { + tmp1rQ14 = kCosTab1[k]; + tmp1iQ14 = kSinTab1[k]; + xrQ16 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(tmp1rQ14, inre1Q9[k]) + WEBRTC_SPL_MUL_16_16(tmp1iQ14, inre2Q9[k]), 7); + xiQ16 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(tmp1rQ14, inre2Q9[k]) - WEBRTC_SPL_MUL_16_16(tmp1iQ14, inre1Q9[k]), 7); + tmpreQ16[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xrQ16)+4, 3); // (Q16*Q19>>16)>>3 = Q16 + tmpimQ16[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xiQ16)+4, 3); // (Q16*Q19>>16)>>3 = Q16 + } + + + xrQ16 = WebRtcSpl_MaxAbsValueW32(tmpreQ16, FRAMESAMPLES/2); + yrQ16 = WebRtcSpl_MaxAbsValueW32(tmpimQ16, FRAMESAMPLES/2); + if (yrQ16>xrQ16) { + xrQ16 = yrQ16; + } + + sh = WebRtcSpl_NormW32(xrQ16); + sh = sh-24; //if sh becomes >=0, then we should shift sh steps to the left, and the domain will become Q(16+sh) + //if sh becomes <0, then we should shift -sh steps to the right, and the domain will become Q(16+sh) + + //"Fastest" vectors + if (sh>=0) { + for (k=0; k<FRAMESAMPLES/2; k++) { + inre1Q9[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(tmpreQ16[k], sh); //Q(16+sh) + inre2Q9[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(tmpimQ16[k], sh); //Q(16+sh) + } + } else { + WebRtc_Word32 round = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, -sh-1); + for (k=0; k<FRAMESAMPLES/2; k++) { + inre1Q9[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpreQ16[k]+round, -sh); //Q(16+sh) + inre2Q9[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpimQ16[k]+round, -sh); //Q(16+sh) + } + } + + /* Get DFT */ + WebRtcIsacfix_FftRadix16Fastest(inre1Q9, inre2Q9, -1); // real call + + //"Fastest" vectors + if (sh>=0) { + for (k=0; k<FRAMESAMPLES/2; k++) { + tmpreQ16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inre1Q9[k], sh); //Q(16+sh) -> Q16 + tmpimQ16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inre2Q9[k], sh); //Q(16+sh) -> Q16 + } + } else { + for (k=0; k<FRAMESAMPLES/2; k++) { + tmpreQ16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inre1Q9[k], -sh); //Q(16+sh) -> Q16 + tmpimQ16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inre2Q9[k], -sh); //Q(16+sh) -> Q16 + } + } + + + /* Use symmetry to separate into two complex vectors and center frames in time around zero */ + for (k = 0; k < FRAMESAMPLES/4; k++) { + xrQ16 = tmpreQ16[k] + tmpreQ16[FRAMESAMPLES/2 - 1 - k]; + yiQ16 = -tmpreQ16[k] + tmpreQ16[FRAMESAMPLES/2 - 1 - k]; + xiQ16 = tmpimQ16[k] - tmpimQ16[FRAMESAMPLES/2 - 1 - k]; + yrQ16 = tmpimQ16[k] + tmpimQ16[FRAMESAMPLES/2 - 1 - k]; + tmp1rQ14 = kCosTab2[k]; + tmp1iQ14 = kSinTab2[k]; + v1Q16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, xrQ16) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, xiQ16); + v2Q16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, xrQ16) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, xiQ16); + outreQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(v1Q16, 9); + outimQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(v2Q16, 9); + v1Q16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, yrQ16) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, yiQ16); + v2Q16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, yrQ16) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, yiQ16); + outreQ7[FRAMESAMPLES/2 - 1 - k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(v1Q16, 9); //CalcLrIntQ(v1Q16, 9); + outimQ7[FRAMESAMPLES/2 - 1 - k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(v2Q16, 9); //CalcLrIntQ(v2Q16, 9); + + } +} + + +void WebRtcIsacfix_Spec2Time(WebRtc_Word16 *inreQ7, WebRtc_Word16 *inimQ7, WebRtc_Word32 *outre1Q16, WebRtc_Word32 *outre2Q16) +{ + + int k; + WebRtc_Word16 tmp1rQ14, tmp1iQ14; + WebRtc_Word32 xrQ16, xiQ16, yrQ16, yiQ16; + WebRtc_Word32 tmpInRe, tmpInIm, tmpInRe2, tmpInIm2; + WebRtc_Word16 factQ11; + WebRtc_Word16 sh; + + for (k = 0; k < FRAMESAMPLES/4; k++) { + /* Move zero in time to beginning of frames */ + tmp1rQ14 = kCosTab2[k]; + tmp1iQ14 = kSinTab2[k]; + + tmpInRe = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inreQ7[k], 9); // Q7 -> Q16 + tmpInIm = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inimQ7[k], 9); // Q7 -> Q16 + tmpInRe2 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inreQ7[FRAMESAMPLES/2 - 1 - k], 9); // Q7 -> Q16 + tmpInIm2 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inimQ7[FRAMESAMPLES/2 - 1 - k], 9); // Q7 -> Q16 + + xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInRe) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInIm); + xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInIm) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInRe); + yrQ16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInIm2) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInRe2); + yiQ16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInRe2) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInIm2); + + /* Combine into one vector, z = x + j * y */ + outre1Q16[k] = xrQ16 - yiQ16; + outre1Q16[FRAMESAMPLES/2 - 1 - k] = xrQ16 + yiQ16; + outre2Q16[k] = xiQ16 + yrQ16; + outre2Q16[FRAMESAMPLES/2 - 1 - k] = -xiQ16 + yrQ16; + } + + /* Get IDFT */ + tmpInRe = WebRtcSpl_MaxAbsValueW32(outre1Q16, 240); + tmpInIm = WebRtcSpl_MaxAbsValueW32(outre2Q16, 240); + if (tmpInIm>tmpInRe) { + tmpInRe = tmpInIm; + } + + sh = WebRtcSpl_NormW32(tmpInRe); + sh = sh-24; //if sh becomes >=0, then we should shift sh steps to the left, and the domain will become Q(16+sh) + //if sh becomes <0, then we should shift -sh steps to the right, and the domain will become Q(16+sh) + + //"Fastest" vectors + if (sh>=0) { + for (k=0; k<240; k++) { + inreQ7[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(outre1Q16[k], sh); //Q(16+sh) + inimQ7[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(outre2Q16[k], sh); //Q(16+sh) + } + } else { + WebRtc_Word32 round = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, -sh-1); + for (k=0; k<240; k++) { + inreQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(outre1Q16[k]+round, -sh); //Q(16+sh) + inimQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(outre2Q16[k]+round, -sh); //Q(16+sh) + } + } + + WebRtcIsacfix_FftRadix16Fastest(inreQ7, inimQ7, 1); // real call + + //"Fastest" vectors + if (sh>=0) { + for (k=0; k<240; k++) { + outre1Q16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inreQ7[k], sh); //Q(16+sh) -> Q16 + outre2Q16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inimQ7[k], sh); //Q(16+sh) -> Q16 + } + } else { + for (k=0; k<240; k++) { + outre1Q16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inreQ7[k], -sh); //Q(16+sh) -> Q16 + outre2Q16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inimQ7[k], -sh); //Q(16+sh) -> Q16 + } + } + + /* Divide through by the normalizing constant: */ + /* scale all values with 1/240, i.e. with 273 in Q16 */ + /* 273/65536 ~= 0.0041656 */ + /* 1/240 ~= 0.0041666 */ + for (k=0; k<240; k++) { + outre1Q16[k] = WEBRTC_SPL_MUL_16_32_RSFT16(273, outre1Q16[k]); + outre2Q16[k] = WEBRTC_SPL_MUL_16_32_RSFT16(273, outre2Q16[k]); + } + + /* Demodulate and separate */ + factQ11 = 31727; // sqrt(240) in Q11 is round(15.49193338482967*2048) = 31727 + for (k = 0; k < FRAMESAMPLES/2; k++) { + tmp1rQ14 = kCosTab1[k]; + tmp1iQ14 = kSinTab1[k]; + xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, outre1Q16[k]) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, outre2Q16[k]); + xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, outre2Q16[k]) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, outre1Q16[k]); + xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xrQ16); + xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xiQ16); + outre2Q16[k] = xiQ16; + outre1Q16[k] = xrQ16; + } +} diff --git a/src/libs/webrtc/neteq/accelerate.c b/src/libs/webrtc/neteq/accelerate.c new file mode 100644 index 00000000..edec9c6e --- /dev/null +++ b/src/libs/webrtc/neteq/accelerate.c @@ -0,0 +1,489 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the Accelerate algorithm that is used to reduce + * the delay by removing a part of the audio stream. + */ + +#include "dsp.h" + +#include "signal_processing_library.h" + +#include "dsp_helpfunctions.h" +#include "neteq_error_codes.h" + +#define ACCELERATE_CORR_LEN 50 +#define ACCELERATE_MIN_LAG 10 +#define ACCELERATE_MAX_LAG 60 +#define ACCELERATE_DOWNSAMPLED_LEN (ACCELERATE_CORR_LEN + ACCELERATE_MAX_LAG) + +/* Scratch usage: + + Type Name size startpos endpos + WebRtc_Word16 pw16_downSampSpeech 110 0 109 + WebRtc_Word32 pw32_corr 2*50 110 209 + WebRtc_Word16 pw16_corr 50 0 49 + + Total: 110+2*50 + */ + +#define SCRATCH_PW16_DS_SPEECH 0 +#define SCRATCH_PW32_CORR ACCELERATE_DOWNSAMPLED_LEN +#define SCRATCH_PW16_CORR 0 + +/**************************************************************************** + * WebRtcNetEQ_Accelerate(...) + * + * This function tries to shorten the audio data by removing one or several + * pitch periods. The operation is only carried out if the correlation is + * strong or if the signal energy is very low. + * + * Input: + * - inst : NetEQ DSP instance + * - scratchPtr : Pointer to scratch vector. + * - decoded : Pointer to newly decoded speech. + * - len : Length of decoded speech. + * - BGNonly : If non-zero, Accelerate will only remove the last + * DEFAULT_TIME_ADJUST seconds of the input. + * No signal matching is done. + * + * Output: + * - inst : Updated instance + * - outData : Pointer to a memory space where the output data + * should be stored + * - pw16_len : Number of samples written to outData. + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_Accelerate(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + const WebRtc_Word16 *pw16_decoded, int len, + WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_len, + WebRtc_Word16 BGNonly) +{ + +#ifdef SCRATCH + /* Use scratch memory for internal temporary vectors */ + WebRtc_Word16 *pw16_downSampSpeech = pw16_scratchPtr + SCRATCH_PW16_DS_SPEECH; + WebRtc_Word32 *pw32_corr = (WebRtc_Word32*) (pw16_scratchPtr + SCRATCH_PW32_CORR); + WebRtc_Word16 *pw16_corr = pw16_scratchPtr + SCRATCH_PW16_CORR; +#else + /* Allocate memory for temporary vectors */ + WebRtc_Word16 pw16_downSampSpeech[ACCELERATE_DOWNSAMPLED_LEN]; + WebRtc_Word32 pw32_corr[ACCELERATE_CORR_LEN]; + WebRtc_Word16 pw16_corr[ACCELERATE_CORR_LEN]; +#endif + WebRtc_Word16 w16_decodedMax = 0; + WebRtc_Word16 w16_tmp; + WebRtc_Word16 w16_tmp2; + WebRtc_Word32 w32_tmp; + WebRtc_Word32 w32_tmp2; + + const WebRtc_Word16 w16_startLag = ACCELERATE_MIN_LAG; + const WebRtc_Word16 w16_endLag = ACCELERATE_MAX_LAG; + const WebRtc_Word16 w16_corrLen = ACCELERATE_CORR_LEN; + const WebRtc_Word16 *pw16_vec1, *pw16_vec2; + WebRtc_Word16 *pw16_vectmp; + WebRtc_Word16 w16_inc, w16_startfact; + WebRtc_Word16 w16_bestIndex, w16_bestVal; + WebRtc_Word16 w16_VAD = 1; + WebRtc_Word16 fsMult; + WebRtc_Word16 fsMult120; + WebRtc_Word32 w32_en1, w32_en2, w32_cc; + WebRtc_Word16 w16_en1, w16_en2; + WebRtc_Word16 w16_en1Scale, w16_en2Scale; + WebRtc_Word16 w16_sqrtEn1En2; + WebRtc_Word16 w16_bestCorr = 0; + int ok; + +#ifdef NETEQ_STEREO + MasterSlaveInfo *msInfo = inst->msInfo; +#endif + + fsMult = WebRtcNetEQ_CalcFsMult(inst->fs); /* Calculate fs/8000 */ + + /* Pre-calculate common multiplication with fsMult */ + fsMult120 = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16(fsMult, 120); /* 15 ms */ + + inst->ExpandInst.w16_consecExp = 0; /* Last was not expand any more */ + + /* Sanity check for len variable; must be (almost) 30 ms + (120*fsMult + max(bestIndex)) */ + if (len < (WebRtc_Word16) WEBRTC_SPL_MUL_16_16((120 + 119), fsMult)) + { + /* Length of decoded data too short */ + inst->w16_mode = MODE_UNSUCCESS_ACCELERATE; + *pw16_len = len; + + /* simply move all data from decoded to outData */ + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, (WebRtc_Word16) len); + + return NETEQ_OTHER_ERROR; + } + + /***********************************/ + /* Special operations for BGN only */ + /***********************************/ + + /* Check if "background noise only" flag is set */ + if (BGNonly) + { + /* special operation for BGN only; simply remove a chunk of data */ + w16_bestIndex = DEFAULT_TIME_ADJUST * WEBRTC_SPL_LSHIFT_W16(fsMult, 3); /* X*fs/1000 */ + + /* Sanity check for bestIndex */ + if (w16_bestIndex > len) + { /* not good, do nothing instead */ + inst->w16_mode = MODE_UNSUCCESS_ACCELERATE; + *pw16_len = len; + + /* simply move all data from decoded to outData */ + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, (WebRtc_Word16) len); + + return NETEQ_OTHER_ERROR; + } + + /* set length parameter */ + *pw16_len = len - w16_bestIndex; /* we remove bestIndex samples */ + + /* copy to output */ + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, *pw16_len); + + /* set mode */ + inst->w16_mode = MODE_LOWEN_ACCELERATE; + + /* update statistics */ + inst->statInst.accelerateLength += w16_bestIndex; + + return 0; + } /* end of special code for BGN mode */ + +#ifdef NETEQ_STEREO + + /* Sanity for msInfo */ + if (msInfo == NULL) + { + /* this should not happen here */ + return MASTER_SLAVE_ERROR; + } + + if (msInfo->msMode != NETEQ_SLAVE) + { + /* Find correlation lag only for non-slave instances */ + +#endif + + /****************************************************************/ + /* Find the strongest correlation lag by downsampling to 4 kHz, */ + /* calculating correlation for downsampled signal and finding */ + /* the strongest correlation peak. */ + /****************************************************************/ + + /* find maximum absolute value */ + w16_decodedMax = WebRtcSpl_MaxAbsValueW16(pw16_decoded, (WebRtc_Word16) len); + + /* downsample the decoded speech to 4 kHz */ + ok = WebRtcNetEQ_DownSampleTo4kHz(pw16_decoded, len, inst->fs, pw16_downSampSpeech, + ACCELERATE_DOWNSAMPLED_LEN, 1 /* compensate delay*/); + if (ok != 0) + { + /* error */ + inst->w16_mode = MODE_UNSUCCESS_ACCELERATE; + *pw16_len = len; + /* simply move all data from decoded to outData */ + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, (WebRtc_Word16) len); + return NETEQ_OTHER_ERROR; + } + + /* + * Set scaling factor for cross correlation to protect against overflow + * (log2(50) => 6) + */ + w16_tmp = 6 - WebRtcSpl_NormW32(WEBRTC_SPL_MUL_16_16(w16_decodedMax, w16_decodedMax)); + w16_tmp = WEBRTC_SPL_MAX(0, w16_tmp); + + /* Perform correlation from lag 10 to lag 60 in 4 kHz domain */ + WebRtcNetEQ_CrossCorr( + pw32_corr, &pw16_downSampSpeech[w16_endLag], + &pw16_downSampSpeech[w16_endLag - w16_startLag], w16_corrLen, + (WebRtc_Word16) (w16_endLag - w16_startLag), w16_tmp, -1); + + /* Normalize correlation to 14 bits and put in a WebRtc_Word16 vector */ + w32_tmp = WebRtcSpl_MaxAbsValueW32(pw32_corr, w16_corrLen); + w16_tmp = 17 - WebRtcSpl_NormW32(w32_tmp); + w16_tmp = WEBRTC_SPL_MAX(0, w16_tmp); + + WebRtcSpl_VectorBitShiftW32ToW16(pw16_corr, w16_corrLen, pw32_corr, w16_tmp); + +#ifdef NETEQ_STEREO + } /* end if (msInfo->msMode != NETEQ_SLAVE) */ + + if ((msInfo->msMode == NETEQ_MASTER) || (msInfo->msMode == NETEQ_MONO)) + { + /* Find the strongest correlation peak by using the parabolic fit method */ + WebRtcNetEQ_PeakDetection(pw16_corr, (WebRtc_Word16) w16_corrLen, 1, fsMult, + &w16_bestIndex, &w16_bestVal); + /* 0 <= bestIndex <= (2*corrLen - 1)*fsMult = 99*fsMult */ + + /* Compensate bestIndex for displaced starting position */ + w16_bestIndex = w16_bestIndex + w16_startLag * WEBRTC_SPL_LSHIFT_W16(fsMult, 1); + /* 20*fsMult <= bestIndex <= 119*fsMult */ + + msInfo->bestIndex = w16_bestIndex; + } + else if (msInfo->msMode == NETEQ_SLAVE) + { + if (msInfo->extraInfo == ACC_FAIL) + { + /* Master has signaled an unsuccessful accelerate */ + w16_bestIndex = 0; + } + else + { + /* Get best index from master */ + w16_bestIndex = msInfo->bestIndex; + } + } + else + { + /* Invalid mode */ + return MASTER_SLAVE_ERROR; + } + +#else /* NETEQ_STEREO */ + + /* Find the strongest correlation peak by using the parabolic fit method */ + WebRtcNetEQ_PeakDetection(pw16_corr, (WebRtc_Word16) w16_corrLen, 1, fsMult, + &w16_bestIndex, &w16_bestVal); + /* 0 <= bestIndex <= (2*corrLen - 1)*fsMult = 99*fsMult */ + + /* Compensate bestIndex for displaced starting position */ + w16_bestIndex = w16_bestIndex + w16_startLag * WEBRTC_SPL_LSHIFT_W16(fsMult, 1); + /* 20*fsMult <= bestIndex <= 119*fsMult */ + +#endif /* NETEQ_STEREO */ + +#ifdef NETEQ_STEREO + + if (msInfo->msMode != NETEQ_SLAVE) + { + /* Calculate correlation only for non-slave instances */ + +#endif /* NETEQ_STEREO */ + + /*****************************************************/ + /* Calculate correlation bestCorr for the found lag. */ + /* Also do a simple VAD decision. */ + /*****************************************************/ + + /* + * Calculate scaling to ensure that bestIndex samples can be square-summed + * without overflowing + */ + w16_tmp = (31 + - WebRtcSpl_NormW32(WEBRTC_SPL_MUL_16_16(w16_decodedMax, w16_decodedMax))); + w16_tmp += (31 - WebRtcSpl_NormW32(w16_bestIndex)); + w16_tmp -= 31; + w16_tmp = WEBRTC_SPL_MAX(0, w16_tmp); + + /* vec1 starts at 15 ms minus one pitch period */ + pw16_vec1 = &pw16_decoded[fsMult120 - w16_bestIndex]; + /* vec2 start at 15 ms */ + pw16_vec2 = &pw16_decoded[fsMult120]; + + /* Calculate energies for vec1 and vec2 */ + w32_en1 = WebRtcNetEQ_DotW16W16((WebRtc_Word16*) pw16_vec1, + (WebRtc_Word16*) pw16_vec1, w16_bestIndex, w16_tmp); + w32_en2 = WebRtcNetEQ_DotW16W16((WebRtc_Word16*) pw16_vec2, + (WebRtc_Word16*) pw16_vec2, w16_bestIndex, w16_tmp); + + /* Calculate cross-correlation at the found lag */ + w32_cc = WebRtcNetEQ_DotW16W16((WebRtc_Word16*) pw16_vec1, (WebRtc_Word16*) pw16_vec2, + w16_bestIndex, w16_tmp); + + /* Check VAD constraint + ((en1+en2)/(2*bestIndex)) <= 8*inst->BGNInst.energy */ + w32_tmp = WEBRTC_SPL_RSHIFT_W32(w32_en1 + w32_en2, 4); /* (en1+en2)/(2*8) */ + if (inst->BGNInst.w16_initialized == 1) + { + w32_tmp2 = inst->BGNInst.w32_energy; + } + else + { + /* if BGN parameters have not been estimated, use a fixed threshold */ + w32_tmp2 = 75000; + } + w16_tmp2 = 16 - WebRtcSpl_NormW32(w32_tmp2); + w16_tmp2 = WEBRTC_SPL_MAX(0, w16_tmp2); + w32_tmp = WEBRTC_SPL_RSHIFT_W32(w32_tmp, w16_tmp2); + w16_tmp2 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(w32_tmp2, w16_tmp2); + w32_tmp2 = WEBRTC_SPL_MUL_16_16(w16_bestIndex, w16_tmp2); + + /* Scale w32_tmp properly before comparing with w32_tmp2 */ + /* (w16_tmp is scaling before energy calculation, thus 2*w16_tmp) */ + if (WebRtcSpl_NormW32(w32_tmp) < WEBRTC_SPL_LSHIFT_W32(w16_tmp,1)) + { + /* Cannot scale only w32_tmp, must scale w32_temp2 too */ + WebRtc_Word16 tempshift = WebRtcSpl_NormW32(w32_tmp); + w32_tmp = WEBRTC_SPL_LSHIFT_W32(w32_tmp, tempshift); + w32_tmp2 = WEBRTC_SPL_RSHIFT_W32(w32_tmp2, + WEBRTC_SPL_LSHIFT_W32(w16_tmp,1) - tempshift); + } + else + { + w32_tmp = WEBRTC_SPL_LSHIFT_W32(w32_tmp, + WEBRTC_SPL_LSHIFT_W32(w16_tmp,1)); + } + + if (w32_tmp <= w32_tmp2) /*((en1+en2)/(2*bestIndex)) <= 8*inst->BGNInst.energy */ + { + /* The signal seems to be passive speech */ + w16_VAD = 0; + w16_bestCorr = 0; /* Correlation does not matter */ + } + else + { + /* The signal is active speech */ + w16_VAD = 1; + + /* Calculate correlation (cc/sqrt(en1*en2)) */ + + /* Start with calculating scale values */ + w16_en1Scale = 16 - WebRtcSpl_NormW32(w32_en1); + w16_en1Scale = WEBRTC_SPL_MAX(0, w16_en1Scale); + w16_en2Scale = 16 - WebRtcSpl_NormW32(w32_en2); + w16_en2Scale = WEBRTC_SPL_MAX(0, w16_en2Scale); + + /* Make sure total scaling is even (to simplify scale factor after sqrt) */ + if ((w16_en1Scale + w16_en2Scale) & 1) + { + w16_en1Scale += 1; + } + + /* Convert energies to WebRtc_Word16 */ + w16_en1 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(w32_en1, w16_en1Scale); + w16_en2 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(w32_en2, w16_en2Scale); + + /* Calculate energy product */ + w32_tmp = WEBRTC_SPL_MUL_16_16(w16_en1, w16_en2); + + /* Calculate square-root of energy product */ + w16_sqrtEn1En2 = (WebRtc_Word16) WebRtcSpl_Sqrt(w32_tmp); + + /* Calculate cc/sqrt(en1*en2) in Q14 */ + w16_tmp = 14 - WEBRTC_SPL_RSHIFT_W16(w16_en1Scale+w16_en2Scale, 1); + w32_cc = WEBRTC_SPL_SHIFT_W32(w32_cc, w16_tmp); + w32_cc = WEBRTC_SPL_MAX(0, w32_cc); /* Don't divide with negative number */ + w16_bestCorr = (WebRtc_Word16) WebRtcSpl_DivW32W16(w32_cc, w16_sqrtEn1En2); + w16_bestCorr = WEBRTC_SPL_MIN(16384, w16_bestCorr); /* set maximum to 1.0 */ + } + +#ifdef NETEQ_STEREO + + } /* end if (msInfo->msMode != NETEQ_SLAVE) */ + +#endif /* NETEQ_STEREO */ + + /************************************************/ + /* Check accelerate criteria and remove samples */ + /************************************************/ + + /* Check for strong correlation (>0.9) or passive speech */ +#ifdef NETEQ_STEREO + if ((((w16_bestCorr > 14746) || (w16_VAD == 0)) && (msInfo->msMode != NETEQ_SLAVE)) + || ((msInfo->msMode == NETEQ_SLAVE) && (msInfo->extraInfo != ACC_FAIL))) +#else + if ((w16_bestCorr > 14746) || (w16_VAD == 0)) +#endif + { + /* Do accelerate operation by overlap add */ + + /* + * Calculate cross-fading slope so that the fading factor goes from + * 1 (16384 in Q14) to 0 in one pitch period (bestIndex). + */ + w16_inc = (WebRtc_Word16) WebRtcSpl_DivW32W16((WebRtc_Word32) 16384, + (WebRtc_Word16) (w16_bestIndex + 1)); /* in Q14 */ + + /* Initiate fading factor */ + w16_startfact = 16384 - w16_inc; + + /* vec1 starts at 15 ms minus one pitch period */ + pw16_vec1 = &pw16_decoded[fsMult120 - w16_bestIndex]; + /* vec2 start at 15 ms */ + pw16_vec2 = &pw16_decoded[fsMult120]; + + /* Copy unmodified part [0 to 15 ms minus 1 pitch period] */ + w16_tmp = (fsMult120 - w16_bestIndex); + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, w16_tmp); + + /* Generate interpolated part of length bestIndex (1 pitch period) */ + pw16_vectmp = pw16_outData + w16_tmp; /* start of interpolation output */ + /* Reuse mixing function from Expand */ + WebRtcNetEQ_MixVoiceUnvoice(pw16_vectmp, (WebRtc_Word16*) pw16_vec1, + (WebRtc_Word16*) pw16_vec2, &w16_startfact, w16_inc, w16_bestIndex); + + /* Move the last part (also unmodified) */ + /* Take from decoded at 15 ms + 1 pitch period */ + pw16_vec2 = &pw16_decoded[fsMult120 + w16_bestIndex]; + WEBRTC_SPL_MEMMOVE_W16(&pw16_outData[fsMult120], pw16_vec2, + (WebRtc_Word16) (len - fsMult120 - w16_bestIndex)); + + /* Set the mode flag */ + if (w16_VAD) + { + inst->w16_mode = MODE_SUCCESS_ACCELERATE; + } + else + { + inst->w16_mode = MODE_LOWEN_ACCELERATE; + } + + /* Calculate resulting length = original length - pitch period */ + *pw16_len = len - w16_bestIndex; + + /* Update in-call statistics */ + inst->statInst.accelerateLength += w16_bestIndex; + + return 0; + } + else + { + /* Accelerate not allowed */ + +#ifdef NETEQ_STEREO + /* Signal to slave(s) that this was unsuccessful */ + if (msInfo->msMode == NETEQ_MASTER) + { + msInfo->extraInfo = ACC_FAIL; + } +#endif + + /* Set mode flag to unsuccessful accelerate */ + inst->w16_mode = MODE_UNSUCCESS_ACCELERATE; + + /* Length is unmodified */ + *pw16_len = len; + + /* Simply move all data from decoded to outData */ + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, (WebRtc_Word16) len); + + return 0; + } +} + +#undef SCRATCH_PW16_DS_SPEECH +#undef SCRATCH_PW32_CORR +#undef SCRATCH_PW16_CORR diff --git a/src/libs/webrtc/neteq/automode.c b/src/libs/webrtc/neteq/automode.c new file mode 100644 index 00000000..7d9f0354 --- /dev/null +++ b/src/libs/webrtc/neteq/automode.c @@ -0,0 +1,717 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the implementation of automatic buffer level optimization. + */ + +#include "automode.h" + +#include "signal_processing_library.h" + +#include "neteq_defines.h" + +#ifdef NETEQ_DELAY_LOGGING +/* special code for offline delay logging */ +#include <stdio.h> +#include "delay_logging.h" + +extern FILE *delay_fid2; /* file pointer to delay log file */ +#endif /* NETEQ_DELAY_LOGGING */ + + +int WebRtcNetEQ_UpdateIatStatistics(AutomodeInst_t *inst, int maxBufLen, + WebRtc_UWord16 seqNumber, WebRtc_UWord32 timeStamp, + WebRtc_Word32 fsHz, int mdCodec, int streamingMode) +{ + WebRtc_UWord32 timeIat; /* inter-arrival time */ + int i; + WebRtc_Word32 tempsum = 0; /* temp summation */ + WebRtc_Word32 tempvar; /* temporary variable */ + int retval = 0; /* return value */ + WebRtc_Word16 packetLenSamp; /* packet speech length in samples */ + + /****************/ + /* Sanity check */ + /****************/ + + if (maxBufLen <= 1 || fsHz <= 0) + { + /* maxBufLen must be at least 2 and fsHz must both be strictly positive */ + return -1; + } + + /****************************/ + /* Update packet statistics */ + /****************************/ + + /* Try calculating packet length from current and previous timestamps */ + if ((timeStamp <= inst->lastTimeStamp) || (seqNumber <= inst->lastSeqNo)) + { + /* Wrong timestamp or sequence order; revert to backup plan */ + packetLenSamp = inst->packetSpeechLenSamp; /* use stored value */ + } + else if (timeStamp > inst->lastTimeStamp) + { + /* calculate timestamps per packet */ + packetLenSamp = (WebRtc_Word16) WebRtcSpl_DivU32U16(timeStamp - inst->lastTimeStamp, + seqNumber - inst->lastSeqNo); + } + + /* Check that the packet size is positive; if not, the statistics cannot be updated. */ + if (packetLenSamp > 0) + { /* packet size ok */ + + /* calculate inter-arrival time in integer packets (rounding down) */ + timeIat = WebRtcSpl_DivW32W16(inst->packetIatCountSamp, packetLenSamp); + + /* Special operations for streaming mode */ + if (streamingMode != 0) + { + /* + * Calculate IAT in Q8, including fractions of a packet (i.e., more accurate + * than timeIat). + */ + WebRtc_Word16 timeIatQ8 = (WebRtc_Word16) WebRtcSpl_DivW32W16( + WEBRTC_SPL_LSHIFT_W32(inst->packetIatCountSamp, 8), packetLenSamp); + + /* + * Calculate cumulative sum iat with sequence number compensation (ideal arrival + * times makes this sum zero). + */ + inst->cSumIatQ8 += (timeIatQ8 + - WEBRTC_SPL_LSHIFT_W32(seqNumber - inst->lastSeqNo, 8)); + + /* subtract drift term */ + inst->cSumIatQ8 -= CSUM_IAT_DRIFT; + + /* ensure not negative */ + inst->cSumIatQ8 = WEBRTC_SPL_MAX(inst->cSumIatQ8, 0); + + /* remember max */ + if (inst->cSumIatQ8 > inst->maxCSumIatQ8) + { + inst->maxCSumIatQ8 = inst->cSumIatQ8; + inst->maxCSumUpdateTimer = 0; + } + + /* too long since the last maximum was observed; decrease max value */ + if (inst->maxCSumUpdateTimer > (WebRtc_UWord32) WEBRTC_SPL_MUL_32_16(fsHz, + MAX_STREAMING_PEAK_PERIOD)) + { + inst->maxCSumIatQ8 -= 4; /* remove 1000*4/256 = 15.6 ms/s */ + } + } /* end of streaming mode */ + + /* check for discontinuous packet sequence and re-ordering */ + if (seqNumber > inst->lastSeqNo + 1) + { + /* Compensate for gap in the sequence numbers. + * Reduce IAT with expected extra time due to lost packets, but ensure that + * the IAT is not negative. + */ + timeIat -= WEBRTC_SPL_MIN(timeIat, + (WebRtc_UWord32) (seqNumber - inst->lastSeqNo - 1)); + } + else if (seqNumber < inst->lastSeqNo) + { + /* compensate for re-ordering */ + timeIat += (WebRtc_UWord32) (inst->lastSeqNo + 1 - seqNumber); + } + + /* saturate IAT at maximum value */ + timeIat = WEBRTC_SPL_MIN( timeIat, MAX_IAT ); + + /* update iatProb = forgetting_factor * iatProb for all elements */ + for (i = 0; i <= MAX_IAT; i++) + { + WebRtc_Word32 tempHi, tempLo; /* Temporary variables */ + + /* + * Multiply iatProbFact (Q15) with iatProb (Q30) and right-shift 15 steps + * to come back to Q30. The operation is done in two steps: + */ + + /* + * 1) Multiply the high 16 bits (15 bits + sign) of iatProb. Shift iatProb + * 16 steps right to get the high 16 bits in a WebRtc_Word16 prior to + * multiplication, and left-shift with 1 afterwards to come back to + * Q30 = (Q15 * (Q30>>16)) << 1. + */ + tempHi = WEBRTC_SPL_MUL_16_16(inst->iatProbFact, + (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(inst->iatProb[i], 16)); + tempHi = WEBRTC_SPL_LSHIFT_W32(tempHi, 1); /* left-shift 1 step */ + + /* + * 2) Isolate and multiply the low 16 bits of iatProb. Right-shift 15 steps + * afterwards to come back to Q30 = (Q15 * Q30) >> 15. + */ + tempLo = inst->iatProb[i] & 0x0000FFFF; /* sift out the 16 low bits */ + tempLo = WEBRTC_SPL_MUL_16_U16(inst->iatProbFact, + (WebRtc_UWord16) tempLo); + tempLo = WEBRTC_SPL_RSHIFT_W32(tempLo, 15); + + /* Finally, add the high and low parts */ + inst->iatProb[i] = tempHi + tempLo; + + /* Sum all vector elements while we are at it... */ + tempsum += inst->iatProb[i]; + } + + /* + * Increase the probability for the currently observed inter-arrival time + * with 1 - iatProbFact. The factor is in Q15, iatProb in Q30; + * hence, left-shift 15 steps to obtain result in Q30. + */ + inst->iatProb[timeIat] += (32768 - inst->iatProbFact) << 15; + + tempsum += (32768 - inst->iatProbFact) << 15; /* add to vector sum */ + + /* + * Update iatProbFact (changes only during the first seconds after reset) + * The factor converges to IAT_PROB_FACT. + */ + inst->iatProbFact += (IAT_PROB_FACT - inst->iatProbFact + 3) >> 2; + + /* iatProb should sum up to 1 (in Q30). */ + tempsum -= 1 << 30; /* should be zero */ + + /* Check if it does, correct if it doesn't. */ + if (tempsum > 0) + { + /* tempsum too large => decrease a few values in the beginning */ + i = 0; + while (i <= MAX_IAT && tempsum > 0) + { + /* Remove iatProb[i] / 16 from iatProb, but not more than tempsum */ + tempvar = WEBRTC_SPL_MIN(tempsum, inst->iatProb[i] >> 4); + inst->iatProb[i++] -= tempvar; + tempsum -= tempvar; + } + } + else if (tempsum < 0) + { + /* tempsum too small => increase a few values in the beginning */ + i = 0; + while (i <= MAX_IAT && tempsum < 0) + { + /* Add iatProb[i] / 16 to iatProb, but not more than tempsum */ + tempvar = WEBRTC_SPL_MIN(-tempsum, inst->iatProb[i] >> 4); + inst->iatProb[i++] += tempvar; + tempsum += tempvar; + } + } + + /* Calculate optimal buffer level based on updated statistics */ + tempvar = (WebRtc_Word32) WebRtcNetEQ_CalcOptimalBufLvl(inst, fsHz, mdCodec, timeIat, + streamingMode); + if (tempvar > 0) + { + inst->optBufLevel = (WebRtc_UWord16) tempvar; + + if (streamingMode != 0) + { + inst->optBufLevel = WEBRTC_SPL_MAX(inst->optBufLevel, + inst->maxCSumIatQ8); + } + + /*********/ + /* Limit */ + /*********/ + + /* Subtract extra delay from maxBufLen */ + if (inst->extraDelayMs > 0 && inst->packetSpeechLenSamp > 0) + { + maxBufLen -= inst->extraDelayMs / inst->packetSpeechLenSamp * fsHz / 1000; + maxBufLen = WEBRTC_SPL_MAX(maxBufLen, 1); // sanity: at least one packet + } + + maxBufLen = WEBRTC_SPL_LSHIFT_W32(maxBufLen, 8); /* shift to Q8 */ + + /* Enforce upper limit; 75% of maxBufLen */ + inst->optBufLevel = (WebRtc_UWord16) WEBRTC_SPL_MIN( inst->optBufLevel, + (maxBufLen >> 1) + (maxBufLen >> 2) ); /* 1/2 + 1/4 = 75% */ + } + else + { + retval = (int) tempvar; + } + + } /* end if */ + + /*******************************/ + /* Update post-call statistics */ + /*******************************/ + + /* Calculate inter-arrival time in ms = packetIatCountSamp / (fsHz / 1000) */ + timeIat = WEBRTC_SPL_UDIV( + WEBRTC_SPL_UMUL_32_16(inst->packetIatCountSamp, (WebRtc_Word16) 1000), + (WebRtc_UWord32) fsHz); + + /* Increase counter corresponding to current inter-arrival time */ + if (timeIat > 2000) + { + inst->countIAT2000ms++; + } + else if (timeIat > 1000) + { + inst->countIAT1000ms++; + } + else if (timeIat > 500) + { + inst->countIAT500ms++; + } + + if (timeIat > inst->longestIATms) + { + /* update maximum value */ + inst->longestIATms = timeIat; + } + + /***********************************/ + /* Prepare for next packet arrival */ + /***********************************/ + + inst->packetIatCountSamp = 0; /* reset inter-arrival time counter */ + + inst->lastSeqNo = seqNumber; /* remember current sequence number */ + + inst->lastTimeStamp = timeStamp; /* remember current timestamp */ + + return retval; +} + + +WebRtc_Word16 WebRtcNetEQ_CalcOptimalBufLvl(AutomodeInst_t *inst, WebRtc_Word32 fsHz, + int mdCodec, WebRtc_UWord32 timeIatPkts, + int streamingMode) +{ + + WebRtc_Word32 sum1 = 1 << 30; /* assign to 1 in Q30 */ + WebRtc_Word16 B; + WebRtc_UWord16 Bopt; + int i; + WebRtc_Word32 betaInv; /* optimization parameter */ + +#ifdef NETEQ_DELAY_LOGGING + /* special code for offline delay logging */ + int temp_var; +#endif + + /****************/ + /* Sanity check */ + /****************/ + + if (fsHz <= 0) + { + /* fsHz must be strictly positive */ + return -1; + } + + /***********************************************/ + /* Get betaInv parameter based on playout mode */ + /***********************************************/ + + if (streamingMode) + { + /* streaming (listen-only) mode */ + betaInv = AUTOMODE_STREAMING_BETA_INV_Q30; + } + else + { + /* normal mode */ + betaInv = AUTOMODE_BETA_INV_Q30; + } + + /*******************************************************************/ + /* Calculate optimal buffer level without considering jitter peaks */ + /*******************************************************************/ + + /* + * Find the B for which the probability of observing an inter-arrival time larger + * than or equal to B is less than or equal to betaInv. + */ + B = 0; /* start from the beginning of iatProb */ + sum1 -= inst->iatProb[B]; /* ensure that optimal level is not less than 1 */ + + do + { + /* + * Subtract the probabilities one by one until the sum is no longer greater + * than betaInv. + */ + sum1 -= inst->iatProb[++B]; + } + while ((sum1 > betaInv) && (B < MAX_IAT)); + + Bopt = B; /* This is our primary value for the optimal buffer level Bopt */ + + if (mdCodec) + { + /* + * Use alternative cost function when multiple description codec is in use. + * Do not have to re-calculate all points, just back off a few steps from + * previous value of B. + */ + WebRtc_Word32 sum2 = sum1; /* copy sum1 */ + + while ((sum2 <= betaInv + inst->iatProb[Bopt]) && (Bopt > 0)) + { + /* Go backwards in the sum until the modified cost function solution is found */ + sum2 += inst->iatProb[Bopt--]; + } + + Bopt++; /* This is the optimal level when using an MD codec */ + + /* Now, Bopt and B can have different values. */ + } + +#ifdef NETEQ_DELAY_LOGGING + /* special code for offline delay logging */ + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_OPTBUF; + fwrite( &temp_var, sizeof(int), 1, delay_fid2 ); + temp_var = (int) (Bopt * inst->packetSpeechLenSamp); +#endif + + /******************************************************************/ + /* Make levelFiltFact adaptive: Larger B <=> larger levelFiltFact */ + /******************************************************************/ + + switch (B) + { + case 0: + case 1: + { + inst->levelFiltFact = 251; + break; + } + case 2: + case 3: + { + inst->levelFiltFact = 252; + break; + } + case 4: + case 5: + case 6: + case 7: + { + inst->levelFiltFact = 253; + break; + } + default: /* B > 7 */ + { + inst->levelFiltFact = 254; + break; + } + } + + /************************/ + /* Peak mode operations */ + /************************/ + + /* Compare current IAT with peak threshold + * + * If IAT > optimal level + threshold (+1 for MD codecs) + * or if IAT > 2 * optimal level (note: optimal level is in Q8): + */ + if (timeIatPkts > (WebRtc_UWord32) (Bopt + inst->peakThresholdPkt + (mdCodec != 0)) + || timeIatPkts > (WebRtc_UWord32) WEBRTC_SPL_LSHIFT_U16(Bopt, 1)) + { + /* A peak is observed */ + + if (inst->peakIndex == -1) + { + /* this is the first peak; prepare for next peak */ + inst->peakIndex = 0; + /* set the mode-disable counter */ + inst->peakModeDisabled = WEBRTC_SPL_LSHIFT_W16(1, NUM_PEAKS_REQUIRED-2); + } + else if (inst->peakIatCountSamp + <= + (WebRtc_UWord32) WEBRTC_SPL_MUL_32_16(fsHz, MAX_PEAK_PERIOD)) + { + /* This is not the first peak and the period time is valid */ + + /* store time elapsed since last peak */ + inst->peakPeriodSamp[inst->peakIndex] = inst->peakIatCountSamp; + + /* saturate height to 16 bits */ + inst->peakHeightPkt[inst->peakIndex] + = + (WebRtc_Word16) WEBRTC_SPL_MIN(timeIatPkts, WEBRTC_SPL_WORD16_MAX); + + /* increment peakIndex and wrap/modulo */ + inst->peakIndex = ++inst->peakIndex & PEAK_INDEX_MASK; + + /* process peak vectors */ + inst->curPeakHeight = 0; + inst->curPeakPeriod = 0; + + for (i = 0; i < NUM_PEAKS; i++) + { + /* Find maximum of peak heights and peak periods */ + inst->curPeakHeight + = WEBRTC_SPL_MAX(inst->curPeakHeight, inst->peakHeightPkt[i]); + inst->curPeakPeriod + = WEBRTC_SPL_MAX(inst->curPeakPeriod, inst->peakPeriodSamp[i]); + + } + + inst->peakModeDisabled >>= 1; /* decrease mode-disable "counter" */ + + } + else if (inst->peakIatCountSamp > (WebRtc_UWord32) WEBRTC_SPL_MUL_32_16(fsHz, + WEBRTC_SPL_LSHIFT_W16(MAX_PEAK_PERIOD, 1))) + { + /* + * More than 2 * MAX_PEAK_PERIOD has elapsed since last peak; + * too long time => reset peak statistics + */ + inst->curPeakHeight = 0; + inst->curPeakPeriod = 0; + for (i = 0; i < NUM_PEAKS; i++) + { + inst->peakHeightPkt[i] = 0; + inst->peakPeriodSamp[i] = 0; + } + + inst->peakIndex = -1; /* Next peak is first peak */ + inst->peakIatCountSamp = 0; + } + + inst->peakIatCountSamp = 0; /* Reset peak interval timer */ + } /* end if peak is observed */ + + /* Evaluate peak mode conditions */ + + /* + * If not disabled (enough peaks have been observed) and + * time since last peak is less than two peak periods. + */ + if ((!inst->peakModeDisabled) && (inst->peakIatCountSamp + <= WEBRTC_SPL_LSHIFT_W32(inst->curPeakPeriod , 1))) + { + /* Engage peak mode */ + + /* Set optimal buffer level to curPeakHeight (if it's not already larger) */ + Bopt = WEBRTC_SPL_MAX(Bopt, inst->curPeakHeight); + +#ifdef NETEQ_DELAY_LOGGING + /* special code for offline delay logging */ + temp_var = (int) -(Bopt * inst->packetSpeechLenSamp); +#endif + } + + /* Scale Bopt to Q8 */ + Bopt = WEBRTC_SPL_LSHIFT_U16(Bopt,8); + +#ifdef NETEQ_DELAY_LOGGING + /* special code for offline delay logging */ + fwrite( &temp_var, sizeof(int), 1, delay_fid2 ); +#endif + + /* Sanity check: Bopt must be strictly positive */ + if (Bopt <= 0) + { + Bopt = WEBRTC_SPL_LSHIFT_W16(1, 8); /* 1 in Q8 */ + } + + return Bopt; /* return value in Q8 */ +} + + +int WebRtcNetEQ_BufferLevelFilter(WebRtc_Word32 curSizeMs8, AutomodeInst_t *inst, + int sampPerCall, WebRtc_Word16 fsMult) +{ + + WebRtc_Word16 curSizeFrames; + + /****************/ + /* Sanity check */ + /****************/ + + if (sampPerCall <= 0 || fsMult <= 0) + { + /* sampPerCall and fsMult must both be strictly positive */ + return -1; + } + + /* Check if packet size has been detected */ + if (inst->packetSpeechLenSamp > 0) + { + /* + * Current buffer level in packet lengths + * = (curSizeMs8 * fsMult) / packetSpeechLenSamp + */ + curSizeFrames = (WebRtc_Word16) WebRtcSpl_DivW32W16( + WEBRTC_SPL_MUL_32_16(curSizeMs8, fsMult), inst->packetSpeechLenSamp); + } + else + { + curSizeFrames = 0; + } + + /* Filter buffer level */ + if (inst->levelFiltFact > 0) /* check that filter factor is set */ + { + /* Filter: + * buffLevelFilt = levelFiltFact * buffLevelFilt + * + (1-levelFiltFact) * curSizeFrames + * + * levelFiltFact is in Q8 + */ + inst->buffLevelFilt = (WebRtc_UWord16) (WEBRTC_SPL_RSHIFT_W32( + WEBRTC_SPL_MUL_16_U16(inst->levelFiltFact, inst->buffLevelFilt), 8) + + WEBRTC_SPL_MUL_16_16(256 - inst->levelFiltFact, curSizeFrames)); + } + + /* Account for time-scale operations (accelerate and pre-emptive expand) */ + if (inst->prevTimeScale) + { + /* + * Time-scaling has been performed since last filter update. + * Subtract the sampleMemory from buffLevelFilt after converting sampleMemory + * from samples to packets in Q8. Make sure that the filtered value is + * non-negative. + */ + inst->buffLevelFilt = (WebRtc_UWord16) WEBRTC_SPL_MAX( inst->buffLevelFilt - + WebRtcSpl_DivW32W16( + WEBRTC_SPL_LSHIFT_W32(inst->sampleMemory, 8), /* sampleMemory in Q8 */ + inst->packetSpeechLenSamp ), /* divide by packetSpeechLenSamp */ + 0); + + /* + * Reset flag and set timescaleHoldOff timer to prevent further time-scaling + * for some time. + */ + inst->prevTimeScale = 0; + inst->timescaleHoldOff = AUTOMODE_TIMESCALE_LIMIT; + } + + /* Update time counters and HoldOff timer */ + inst->packetIatCountSamp += sampPerCall; /* packet inter-arrival time */ + inst->peakIatCountSamp += sampPerCall; /* peak inter-arrival time */ + inst->timescaleHoldOff >>= 1; /* time-scaling limiter */ + inst->maxCSumUpdateTimer += sampPerCall; /* cumulative-sum timer */ + + return 0; + +} + + +int WebRtcNetEQ_SetPacketSpeechLen(AutomodeInst_t *inst, WebRtc_Word16 newLenSamp, + WebRtc_Word32 fsHz) +{ + + /* Sanity check for newLenSamp and fsHz */ + if (newLenSamp <= 0 || fsHz <= 0) + { + return -1; + } + + inst->packetSpeechLenSamp = newLenSamp; /* Store packet size in instance */ + + /* Make NetEQ wait for first regular packet before starting the timer */ + inst->lastPackCNGorDTMF = 1; + + inst->packetIatCountSamp = 0; /* Reset packet time counter */ + + /* + * Calculate peak threshold from packet size. The threshold is defined as + * the (fractional) number of packets that corresponds to PEAK_HEIGHT + * (in Q8 seconds). That is, threshold = PEAK_HEIGHT/256 * fsHz / packLen. + */ + inst->peakThresholdPkt = (WebRtc_UWord16) WebRtcSpl_DivW32W16ResW16( + WEBRTC_SPL_MUL_16_16_RSFT(PEAK_HEIGHT, + (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(fsHz, 6), 2), inst->packetSpeechLenSamp); + + return 0; +} + + +int WebRtcNetEQ_ResetAutomode(AutomodeInst_t *inst, int maxBufLenPackets) +{ + + int i; + WebRtc_UWord16 tempprob = 0x4002; /* 16384 + 2 = 100000000000010 binary; */ + + /* Sanity check for maxBufLenPackets */ + if (maxBufLenPackets <= 1) + { + /* Invalid value; set to 10 instead (arbitary small number) */ + maxBufLenPackets = 10; + } + + /* Reset filtered buffer level */ + inst->buffLevelFilt = 0; + + /* Reset packet size to unknown */ + inst->packetSpeechLenSamp = 0; + + /* + * Flag that last packet was special payload, so that automode will treat the next speech + * payload as the first payload received. + */ + inst->lastPackCNGorDTMF = 1; + + /* Reset peak detection parameters */ + inst->peakModeDisabled = 1; /* disable peak mode */ + inst->peakIatCountSamp = 0; + inst->peakIndex = -1; /* indicates that no peak is registered */ + inst->curPeakHeight = 0; + inst->curPeakPeriod = 0; + for (i = 0; i < NUM_PEAKS; i++) + { + inst->peakHeightPkt[i] = 0; + inst->peakPeriodSamp[i] = 0; + } + + /* + * Set the iatProb PDF vector to an exponentially decaying distribution + * iatProb[i] = 0.5^(i+1), i = 0, 1, 2, ... + * iatProb is in Q30. + */ + for (i = 0; i <= MAX_IAT; i++) + { + /* iatProb[i] = 0.5^(i+1) = iatProb[i-1] / 2 */ + tempprob = WEBRTC_SPL_RSHIFT_U16(tempprob, 1); + /* store in PDF vector */ + inst->iatProb[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) tempprob, 16); + } + + /* + * Calculate the optimal buffer level corresponing to the initial PDF. + * No need to call WebRtcNetEQ_CalcOptimalBufLvl() since we have just hard-coded + * all the variables that the buffer level depends on => we know the result + */ + inst->optBufLevel = WEBRTC_SPL_MIN(4, + (maxBufLenPackets >> 1) + (maxBufLenPackets >> 1)); /* 75% of maxBufLenPackets */ + inst->levelFiltFact = 253; + + /* + * Reset the iat update forgetting factor to 0 to make the impact of the first + * incoming packets greater. + */ + inst->iatProbFact = 0; + + /* Reset packet inter-arrival time counter */ + inst->packetIatCountSamp = 0; + + /* Clear time-scaling related variables */ + inst->prevTimeScale = 0; + inst->timescaleHoldOff = AUTOMODE_TIMESCALE_LIMIT; /* don't allow time-scaling immediately */ + + inst->cSumIatQ8 = 0; + inst->maxCSumIatQ8 = 0; + + return 0; +} + diff --git a/src/libs/webrtc/neteq/automode.h b/src/libs/webrtc/neteq/automode.h new file mode 100644 index 00000000..672098a3 --- /dev/null +++ b/src/libs/webrtc/neteq/automode.h @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the functionality for automatic buffer level optimization. + */ + +#ifndef AUTOMODE_H +#define AUTOMODE_H + +#include "typedefs.h" + +/*************/ +/* Constants */ +/*************/ + +/* The beta parameter defines the trade-off between delay and underrun probability. */ +/* It is defined through its inverse in Q30 */ +#define AUTOMODE_BETA_INV_Q30 53687091 /* 1/20 in Q30 */ +#define AUTOMODE_STREAMING_BETA_INV_Q30 536871 /* 1/2000 in Q30 */ + +/* Forgetting factor for the inter-arrival time statistics */ +#define IAT_PROB_FACT 32745 /* 0.9993 in Q15 */ + +/* Maximum inter-arrival time to register (in "packet-times") */ +#define MAX_IAT 64 +#define PEAK_HEIGHT 20 /* 0.08s in Q8 */ + +/* The value (1<<5) sets maximum accelerate "speed" to about 100 ms/s */ +#define AUTOMODE_TIMESCALE_LIMIT (1<<5) + +/* Peak mode related parameters */ +/* Number of peaks in peak vector; must be a power of 2 */ +#define NUM_PEAKS 8 + +/* Must be NUM_PEAKS-1 */ +#define PEAK_INDEX_MASK 0x0007 + +/* Longest accepted peak distance */ +#define MAX_PEAK_PERIOD 10 +#define MAX_STREAMING_PEAK_PERIOD 600 /* 10 minutes */ + +/* Number of peaks required before peak mode can be engaged */ +#define NUM_PEAKS_REQUIRED 3 + +/* Drift term for cumulative sum */ +#define CSUM_IAT_DRIFT 2 + +/*******************/ +/* Automode struct */ +/*******************/ + +/* The automode struct is a sub-struct of the + bufstats-struct (BufstatsInst_t). */ + +typedef struct +{ + + /* Filtered current buffer level */ + WebRtc_UWord16 levelFiltFact; /* filter forgetting factor in Q8 */ + WebRtc_UWord16 buffLevelFilt; /* filtered buffer level in Q8 */ + + /* Inter-arrival time (iat) statistics */ + WebRtc_Word32 iatProb[MAX_IAT + 1]; /* iat probabilities in Q30 */ + WebRtc_Word16 iatProbFact; /* iat forgetting factor in Q15 */ + WebRtc_UWord32 packetIatCountSamp; /* time (in timestamps) elapsed since last + packet arrival, based on RecOut calls */ + WebRtc_UWord16 optBufLevel; /* current optimal buffer level in Q8 */ + + /* Packet related information */ + WebRtc_Word16 packetSpeechLenSamp; /* speech samples per incoming packet */ + WebRtc_Word16 lastPackCNGorDTMF; /* indicates that the last received packet + contained special information */ + WebRtc_UWord16 lastSeqNo; /* sequence number for last packet received */ + WebRtc_UWord32 lastTimeStamp; /* timestamp for the last packet received */ + WebRtc_Word32 sampleMemory; /* memory position for keeping track of how many + samples we cut during expand */ + WebRtc_Word16 prevTimeScale; /* indicates that the last mode was an accelerate + or pre-emptive expand operation */ + WebRtc_UWord32 timescaleHoldOff; /* counter that is shifted one step right each + RecOut call; time-scaling allowed when it has + reached 0 */ + WebRtc_Word16 extraDelayMs; /* extra delay for sync with video */ + + /* Peak-detection */ + /* vector with the latest peak periods (peak spacing in samples) */ + WebRtc_UWord32 peakPeriodSamp[NUM_PEAKS]; + /* vector with the latest peak heights (in packets) */ + WebRtc_Word16 peakHeightPkt[NUM_PEAKS]; + WebRtc_Word16 peakIndex; /* index for the vectors peakPeriodSamp and peakHeightPkt; + -1 if still waiting for first peak */ + WebRtc_UWord16 peakThresholdPkt; /* definition of peak (in packets); + calculated from PEAK_HEIGHT */ + WebRtc_UWord32 peakIatCountSamp; /* samples elapsed since last peak was observed */ + WebRtc_UWord32 curPeakPeriod; /* current maximum of peakPeriodSamp vector */ + WebRtc_Word16 curPeakHeight; /* derived from peakHeightPkt vector; + used as optimal buffer level in peak mode */ + WebRtc_Word16 peakModeDisabled; /* ==0 if peak mode can be engaged; >0 if not */ + + /* Post-call statistics */ + WebRtc_UWord32 countIAT500ms; /* number of times we got small network outage */ + WebRtc_UWord32 countIAT1000ms; /* number of times we got medium network outage */ + WebRtc_UWord32 countIAT2000ms; /* number of times we got large network outage */ + WebRtc_UWord32 longestIATms; /* mSec duration of longest network outage */ + + WebRtc_Word16 cSumIatQ8; /* cumulative sum of inter-arrival times */ + WebRtc_Word16 maxCSumIatQ8; /* max cumulative sum IAT */ + WebRtc_UWord32 maxCSumUpdateTimer;/* time elapsed since maximum was observed */ + +} AutomodeInst_t; + +/*************/ +/* Functions */ +/*************/ + +/**************************************************************************** + * WebRtcNetEQ_UpdateIatStatistics(...) + * + * Update the packet inter-arrival time statistics when a new packet arrives. + * This function should be called for every arriving packet, with some + * exceptions when using DTX/VAD and DTMF. A new optimal buffer level is + * calculated after the update. + * + * Input: + * - inst : Automode instance + * - maxBufLen : Maximum number of packets the buffer can hold + * - seqNumber : RTP sequence number of incoming packet + * - timeStamp : RTP timestamp of incoming packet + * - fsHz : Sample rate in Hz + * - mdCodec : Non-zero if the current codec is a multiple- + * description codec + * - streamingMode : A non-zero value will increase jitter robustness (and delay) + * + * Output: + * - inst : Updated automode instance + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_UpdateIatStatistics(AutomodeInst_t *inst, int maxBufLen, + WebRtc_UWord16 seqNumber, WebRtc_UWord32 timeStamp, + WebRtc_Word32 fsHz, int mdCodec, int streamingMode); + +/**************************************************************************** + * WebRtcNetEQ_CalcOptimalBufLvl(...) + * + * Calculate the optimal buffer level based on packet inter-arrival time + * statistics. + * + * Input: + * - inst : Automode instance + * - fsHz : Sample rate in Hz + * - mdCodec : Non-zero if the current codec is a multiple- + * description codec + * - timeIatPkts : Currently observed inter-arrival time in packets + * - streamingMode : A non-zero value will increase jitter robustness (and delay) + * + * Output: + * - inst : Updated automode instance + * + * Return value : >0 - Optimal buffer level + * <0 - Error + */ + +WebRtc_Word16 WebRtcNetEQ_CalcOptimalBufLvl(AutomodeInst_t *inst, WebRtc_Word32 fsHz, + int mdCodec, WebRtc_UWord32 timeIatPkts, + int streamingMode); + +/**************************************************************************** + * WebRtcNetEQ_BufferLevelFilter(...) + * + * Update filtered buffer level. The function must be called once for each + * RecOut call, since the timing of automode hinges on counters that are + * updated by this function. + * + * Input: + * - curSizeMs8 : Total length of unused speech data in packet buffer + * and sync buffer, in ms * 8 + * - inst : Automode instance + * - sampPerCall : Number of samples per RecOut call + * - fsMult : Sample rate in Hz divided by 8000 + * + * Output: + * - inst : Updated automode instance + * + * Return value : 0 - Ok + * : <0 - Error + */ + +int WebRtcNetEQ_BufferLevelFilter(WebRtc_Word32 curSizeMs8, AutomodeInst_t *inst, + int sampPerCall, WebRtc_Word16 fsMult); + +/**************************************************************************** + * WebRtcNetEQ_SetPacketSpeechLen(...) + * + * Provide the number of speech samples extracted from a packet to the + * automode instance. Several of the calculations within automode depend + * on knowing the packet size. + * + * + * Input: + * - inst : Automode instance + * - newLenSamp : Number of samples per RecOut call + * - fsHz : Sample rate in Hz + * + * Output: + * - inst : Updated automode instance + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_SetPacketSpeechLen(AutomodeInst_t *inst, WebRtc_Word16 newLenSamp, + WebRtc_Word32 fsHz); + +/**************************************************************************** + * WebRtcNetEQ_ResetAutomode(...) + * + * Reset the automode instance. + * + * + * Input: + * - inst : Automode instance + * - maxBufLenPackets : Maximum number of packets that the packet + * buffer can hold (>1) + * + * Output: + * - inst : Updated automode instance + * + * Return value : 0 - Ok + */ + +int WebRtcNetEQ_ResetAutomode(AutomodeInst_t *inst, int maxBufLenPackets); + +#endif /* AUTOMODE_H */ diff --git a/src/libs/webrtc/neteq/bgn_update.c b/src/libs/webrtc/neteq/bgn_update.c new file mode 100644 index 00000000..115168a0 --- /dev/null +++ b/src/libs/webrtc/neteq/bgn_update.c @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the function for updating the background noise estimate. + */ + +#include "dsp.h" + +#include "signal_processing_library.h" + +#include "dsp_helpfunctions.h" + +/* Scratch usage: + Designed for BGN_LPC_ORDER <= 10 + + Type Name size startpos endpos + WebRtc_Word32 pw32_autoCorr 22 0 21 (Length (BGN_LPC_ORDER + 1)*2) + WebRtc_Word16 pw16_tempVec 10 22 31 (Length BGN_LPC_ORDER) + WebRtc_Word16 pw16_rc 10 32 41 (Length BGN_LPC_ORDER) + WebRtc_Word16 pw16_outVec 74 0 73 (Length BGN_LPC_ORDER + 64) + + Total: 74 + */ + +#if (BGN_LPC_ORDER > 10) && (defined SCRATCH) +#error BGN_LPC_ORDER is too large for current scratch memory allocation +#endif + +#define SCRATCH_PW32_AUTO_CORR 0 +#define SCRATCH_PW16_TEMP_VEC 22 +#define SCRATCH_PW16_RC 32 +#define SCRATCH_PW16_OUT_VEC 0 + +#define NETEQFIX_BGNFRAQINCQ16 229 /* 0.0035 in Q16 */ + +/**************************************************************************** + * WebRtcNetEQ_BGNUpdate(...) + * + * This function updates the background noise parameter estimates. + * + * Input: + * - inst : NetEQ instance, where the speech history is stored. + * - scratchPtr : Pointer to scratch vector. + * + * Output: + * - inst : Updated information about the BGN characteristics. + * + * Return value : No return value + */ + +void WebRtcNetEQ_BGNUpdate( +#ifdef SCRATCH + DSPInst_t *inst, WebRtc_Word16 *pw16_scratchPtr +#else + DSPInst_t *inst +#endif +) +{ + const WebRtc_Word16 w16_vecLen = 256; + BGNInst_t *BGN_Inst = &(inst->BGNInst); +#ifdef SCRATCH + WebRtc_Word32 *pw32_autoCorr = (WebRtc_Word32*) (pw16_scratchPtr + SCRATCH_PW32_AUTO_CORR); + WebRtc_Word16 *pw16_tempVec = pw16_scratchPtr + SCRATCH_PW16_TEMP_VEC; + WebRtc_Word16 *pw16_rc = pw16_scratchPtr + SCRATCH_PW16_RC; + WebRtc_Word16 *pw16_outVec = pw16_scratchPtr + SCRATCH_PW16_OUT_VEC; +#else + WebRtc_Word32 pw32_autoCorr[BGN_LPC_ORDER + 1]; + WebRtc_Word16 pw16_tempVec[BGN_LPC_ORDER]; + WebRtc_Word16 pw16_outVec[BGN_LPC_ORDER + 64]; + WebRtc_Word16 pw16_rc[BGN_LPC_ORDER]; +#endif + WebRtc_Word16 pw16_A[BGN_LPC_ORDER + 1]; + WebRtc_Word32 w32_tmp; + WebRtc_Word16 *pw16_vec; + WebRtc_Word16 w16_maxSample; + WebRtc_Word16 w16_tmp, w16_tmp2; + WebRtc_Word16 w16_enSampleShift; + WebRtc_Word32 w32_en, w32_enBGN; + WebRtc_Word32 w32_enUpdateThreashold; + WebRtc_Word16 stability; + + pw16_vec = inst->pw16_speechHistory + inst->w16_speechHistoryLen - w16_vecLen; + +#ifdef NETEQ_VAD + if( !inst->VADInst.VADEnabled /* we are not using post-decode VAD */ + || inst->VADInst.VADDecision == 0 ) + { /* ... or, post-decode VAD says passive speaker */ +#endif /* NETEQ_VAD */ + + /*Insert zeros to guarantee that boundary values do not distort autocorrelation */ + WEBRTC_SPL_MEMCPY_W16(pw16_tempVec, pw16_vec - BGN_LPC_ORDER, BGN_LPC_ORDER); + WebRtcSpl_MemSetW16(pw16_vec - BGN_LPC_ORDER, 0, BGN_LPC_ORDER); + + w16_maxSample = WebRtcSpl_MaxAbsValueW16(pw16_vec, w16_vecLen); + w16_tmp = 8 /* log2(w16_veclen) = 8 */ + - WebRtcSpl_NormW32(WEBRTC_SPL_MUL_16_16(w16_maxSample, w16_maxSample)); + w16_tmp = WEBRTC_SPL_MAX(0, w16_tmp); + + WebRtcNetEQ_CrossCorr(pw32_autoCorr, pw16_vec, pw16_vec, w16_vecLen, BGN_LPC_ORDER + 1, + w16_tmp, -1); + + /* Copy back data */ + WEBRTC_SPL_MEMCPY_W16(pw16_vec - BGN_LPC_ORDER, pw16_tempVec, BGN_LPC_ORDER); + + w16_enSampleShift = 8 - w16_tmp; /* Number of shifts to get energy/sample */ + /* pw32_autoCorr[0]>>w16_enSampleShift */ + w32_en = WEBRTC_SPL_RSHIFT_W32(pw32_autoCorr[0], w16_enSampleShift); + if ((w32_en < BGN_Inst->w32_energyUpdate +#ifdef NETEQ_VAD + /* post-decode VAD disabled and w32_en sufficiently low */ + && !inst->VADInst.VADEnabled) + /* ... or, post-decode VAD says passive speaker */ + || (inst->VADInst.VADEnabled && inst->VADInst.VADDecision == 0) +#else + ) /* just close the extra parenthesis */ +#endif /* NETEQ_VAD */ + ) + { + /* Generate LPC coefficients */ + if (pw32_autoCorr[0] > 0) + { + /* regardless of whether the filter is actually updated or not, + update energy threshold levels, since we have in fact observed + a low energy signal */ + if (w32_en < BGN_Inst->w32_energyUpdate) + { + /* Never get under 1.0 in average sample energy */ + BGN_Inst->w32_energyUpdate = WEBRTC_SPL_MAX(w32_en, 1); + BGN_Inst->w32_energyUpdateLow = 0; + } + + stability = WebRtcSpl_LevinsonDurbin(pw32_autoCorr, pw16_A, pw16_rc, BGN_LPC_ORDER); + /* Only update BGN if filter is stable */ + if (stability != 1) + { + return; + } + } + else + { + /* Do not update */ + return; + } + /* Generate the CNG gain factor by looking at the energy of the residual */ + WebRtcSpl_FilterMAFastQ12(pw16_vec + w16_vecLen - 64, pw16_outVec, pw16_A, + BGN_LPC_ORDER + 1, 64); + w32_enBGN = WebRtcNetEQ_DotW16W16(pw16_outVec, pw16_outVec, 64, 0); + /* Dot product should never overflow since it is BGN and residual! */ + + /* + * Check spectral flatness + * Comparing the residual variance with the input signal variance tells + * if the spectrum is flat or not. + * (20*w32_enBGN) >= (w32_en<<6) + * Also ensure that the energy is non-zero. + */ + if ((WEBRTC_SPL_MUL_32_16(w32_enBGN, 20) >= WEBRTC_SPL_LSHIFT_W32(w32_en, 6)) + && (w32_en > 0)) + { + /* spectrum is flat enough; save filter parameters */ + + WEBRTC_SPL_MEMCPY_W16(BGN_Inst->pw16_filter, pw16_A, BGN_LPC_ORDER+1); + WEBRTC_SPL_MEMCPY_W16(BGN_Inst->pw16_filterState, + pw16_vec + w16_vecLen - BGN_LPC_ORDER, BGN_LPC_ORDER); + + /* Save energy level */ + BGN_Inst->w32_energy = WEBRTC_SPL_MAX(w32_en, 1); + + /* Update energy threshold levels */ + /* Never get under 1.0 in average sample energy */ + BGN_Inst->w32_energyUpdate = WEBRTC_SPL_MAX(w32_en, 1); + BGN_Inst->w32_energyUpdateLow = 0; + + /* Normalize w32_enBGN to 29 or 30 bits before sqrt */ + w16_tmp2 = WebRtcSpl_NormW32(w32_enBGN) - 1; + if (w16_tmp2 & 0x1) + { + w16_tmp2 -= 1; /* Even number of shifts required */ + } + w32_enBGN = WEBRTC_SPL_SHIFT_W32(w32_enBGN, w16_tmp2); + + /* Calculate scale and shift factor */ + BGN_Inst->w16_scale = (WebRtc_Word16) WebRtcSpl_Sqrt(w32_enBGN); + BGN_Inst->w16_scaleShift = 13 + ((6 + w16_tmp2) >> 1); /* RANDN table is in Q13, */ + /* 6=log2(64) */ + + BGN_Inst->w16_initialized = 1; + } + + } + else + { + /* + * Will only happen if post-decode VAD is disabled and w32_en is not low enough. + * Increase the threshold for update so that it increases by a factor 4 in four + * seconds. + * energy = energy * 1.0035 + */ + w32_tmp = WEBRTC_SPL_MUL_16_16_RSFT(NETEQFIX_BGNFRAQINCQ16, + BGN_Inst->w32_energyUpdateLow, 16); + w32_tmp += WEBRTC_SPL_MUL_16_16(NETEQFIX_BGNFRAQINCQ16, + (WebRtc_Word16)(BGN_Inst->w32_energyUpdate & 0xFF)); + w32_tmp += (WEBRTC_SPL_MUL_16_16(NETEQFIX_BGNFRAQINCQ16, + (WebRtc_Word16)((BGN_Inst->w32_energyUpdate>>8) & 0xFF)) << 8); + BGN_Inst->w32_energyUpdateLow += w32_tmp; + + BGN_Inst->w32_energyUpdate += WEBRTC_SPL_MUL_16_16(NETEQFIX_BGNFRAQINCQ16, + (WebRtc_Word16)(BGN_Inst->w32_energyUpdate>>16)); + BGN_Inst->w32_energyUpdate += BGN_Inst->w32_energyUpdateLow >> 16; + BGN_Inst->w32_energyUpdateLow = (BGN_Inst->w32_energyUpdateLow & 0x0FFFF); + + /* Update maximum energy */ + /* Decrease by a factor 1/1024 each time */ + BGN_Inst->w32_energyMax = BGN_Inst->w32_energyMax - (BGN_Inst->w32_energyMax >> 10); + if (w32_en > BGN_Inst->w32_energyMax) + { + BGN_Inst->w32_energyMax = w32_en; + } + + /* Set update level to at the minimum 60.21dB lower then the maximum energy */ + w32_enUpdateThreashold = (BGN_Inst->w32_energyMax + 524288) >> 20; + if (w32_enUpdateThreashold > BGN_Inst->w32_energyUpdate) + { + BGN_Inst->w32_energyUpdate = w32_enUpdateThreashold; + } + } + +#ifdef NETEQ_VAD +} /* closing initial if-statement */ +#endif /* NETEQ_VAD */ + + return; +} + +#undef SCRATCH_PW32_AUTO_CORR +#undef SCRATCH_PW16_TEMP_VEC +#undef SCRATCH_PW16_RC +#undef SCRATCH_PW16_OUT_VEC + diff --git a/src/libs/webrtc/neteq/buffer_stats.h b/src/libs/webrtc/neteq/buffer_stats.h new file mode 100644 index 00000000..9820519b --- /dev/null +++ b/src/libs/webrtc/neteq/buffer_stats.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Calculates and stores the packet buffer statistics. + */ + +#ifndef BUFFER_STATS_H +#define BUFFER_STATS_H + +#include "automode.h" +#include "webrtc_neteq.h" /* to define enum WebRtcNetEQPlayoutMode */ + +/* NetEQ related decisions */ +#define BUFSTATS_DO_NORMAL 0 +#define BUFSTATS_DO_ACCELERATE 1 +#define BUFSTATS_DO_MERGE 2 +#define BUFSTATS_DO_EXPAND 3 +#define BUFSTAT_REINIT 4 +#define BUFSTATS_DO_RFC3389CNG_PACKET 5 +#define BUFSTATS_DO_RFC3389CNG_NOPACKET 6 +#define BUFSTATS_DO_INTERNAL_CNG_NOPACKET 7 +#define BUFSTATS_DO_PREEMPTIVE_EXPAND 8 +#define BUFSTAT_REINIT_DECODER 9 +#define BUFSTATS_DO_DTMF_ONLY 10 +/* Decisions related to when NetEQ is switched off (or in FAX mode) */ +#define BUFSTATS_DO_ALTERNATIVE_PLC 11 +#define BUFSTATS_DO_ALTERNATIVE_PLC_INC_TS 12 +#define BUFSTATS_DO_AUDIO_REPETITION 13 +#define BUFSTATS_DO_AUDIO_REPETITION_INC_TS 14 + +/* Reinit decoder states after this number of expands (upon arrival of new packet) */ +#define REINIT_AFTER_EXPANDS 100 + +/* Wait no longer than this number of RecOut calls before using an "early" packet */ +#define MAX_WAIT_FOR_PACKET 10 + +/* CNG modes */ +#define CNG_OFF 0 +#define CNG_RFC3389_ON 1 +#define CNG_INTERNAL_ON 2 + +typedef struct +{ + + /* store statistical data here */ + WebRtc_Word16 w16_cngOn; /* remember if CNG is interrupted by other event (e.g. DTMF) */ + WebRtc_Word16 w16_noExpand; + WebRtc_Word32 uw32_CNGplayedTS; + + /* VQmon data */ + WebRtc_UWord16 avgDelayMsQ8; + WebRtc_Word16 maxDelayMs; + + AutomodeInst_t Automode_inst; + +} BufstatsInst_t; + +/**************************************************************************** + * WebRtcNetEQ_BufstatsDecision() + * + * Gives a decision about what action that is currently desired + * + * + * Input: + * inst: The bufstat instance + * cur_size: Current buffer size in ms in Q3 domain + * targetTS: The desired timestamp to start playout from + * availableTS: The closest future value available in buffer + * noPacket 1 if no packet is available, makes availableTS undefined + * prevPlayMode mode of last NetEq playout + * timestampsPerCall number of timestamp for 10ms + * + * Output: + * Returns: A decision, as defined above (see top of file) + * + */ + +WebRtc_UWord16 WebRtcNetEQ_BufstatsDecision(BufstatsInst_t *inst, WebRtc_Word16 frameSize, + WebRtc_Word32 cur_size, WebRtc_UWord32 targetTS, + WebRtc_UWord32 availableTS, int noPacket, + int cngPacket, int prevPlayMode, + enum WebRtcNetEQPlayoutMode playoutMode, + int timestampsPerCall, int NoOfExpandCalls, + WebRtc_Word16 fs_mult, + WebRtc_Word16 lastModeBGNonly, int playDtmf); + +#endif diff --git a/src/libs/webrtc/neteq/bufstats_decision.c b/src/libs/webrtc/neteq/bufstats_decision.c new file mode 100644 index 00000000..9dae3938 --- /dev/null +++ b/src/libs/webrtc/neteq/bufstats_decision.c @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the function where the main decision logic for buffer level + * adaptation happens. + */ + +#include "buffer_stats.h" + +#include <assert.h> + +#include "signal_processing_library.h" + +#include "automode.h" +#include "neteq_defines.h" +#include "neteq_error_codes.h" +#include "webrtc_neteq.h" + +#define NETEQ_BUFSTAT_20MS_Q7 2560 /* = 20 ms in Q7 */ + +WebRtc_UWord16 WebRtcNetEQ_BufstatsDecision(BufstatsInst_t *inst, WebRtc_Word16 frameSize, + WebRtc_Word32 cur_size, WebRtc_UWord32 targetTS, + WebRtc_UWord32 availableTS, int noPacket, + int cngPacket, int prevPlayMode, + enum WebRtcNetEQPlayoutMode playoutMode, + int timestampsPerCall, int NoOfExpandCalls, + WebRtc_Word16 fs_mult, + WebRtc_Word16 lastModeBGNonly, int playDtmf) +{ + + int currentDelayMs; + WebRtc_Word32 currSizeSamples = cur_size; + WebRtc_Word16 extraDelayPacketsQ8 = 0; + + /* Avoid overflow if the buffer size should be really large (cur_size is limited 256ms) */ + WebRtc_Word32 curr_sizeQ7 = WEBRTC_SPL_LSHIFT_W32(cur_size, 4); + WebRtc_UWord16 level_limit_hi, level_limit_lo; + + inst->Automode_inst.prevTimeScale &= (prevPlayMode == MODE_SUCCESS_ACCELERATE + || prevPlayMode == MODE_LOWEN_ACCELERATE || prevPlayMode == MODE_SUCCESS_PREEMPTIVE + || prevPlayMode == MODE_LOWEN_PREEMPTIVE); + + if ((prevPlayMode != MODE_RFC3389CNG) && (prevPlayMode != MODE_CODEC_INTERNAL_CNG)) + { + /* + * Do not update buffer history if currently playing CNG + * since it will bias the filtered buffer level. + */ + WebRtcNetEQ_BufferLevelFilter(cur_size, &(inst->Automode_inst), timestampsPerCall, + fs_mult); + } + else + { + /* only update time counters */ + inst->Automode_inst.packetIatCountSamp += timestampsPerCall; /* packet inter-arrival time */ + inst->Automode_inst.peakIatCountSamp += timestampsPerCall; /* peak inter-arrival time */ + inst->Automode_inst.timescaleHoldOff >>= 1; /* time-scaling limiter */ + } + cur_size = WEBRTC_SPL_MIN(curr_sizeQ7, WEBRTC_SPL_WORD16_MAX); + + /* Calculate VQmon related variables */ + /* avgDelay = avgDelay*(511/512) + currentDelay*(1/512) (sample ms delay in Q8) */ + inst->avgDelayMsQ8 = (WebRtc_Word16) (WEBRTC_SPL_MUL_16_16_RSFT(inst->avgDelayMsQ8,511,9) + + (cur_size >> 9)); + + /* Update maximum delay if needed */ + currentDelayMs = (curr_sizeQ7 >> 7); + if (currentDelayMs > inst->maxDelayMs) + { + inst->maxDelayMs = currentDelayMs; + } + + /* NetEQ is on with normal or steaming mode */ + if (playoutMode == kPlayoutOn || playoutMode == kPlayoutStreaming) + { + /* Guard for errors, so that it should not get stuck in error mode */ + if (prevPlayMode == MODE_ERROR) + { + if (noPacket) + { + return BUFSTATS_DO_EXPAND; + } + else + { + return BUFSTAT_REINIT; + } + } + + if (prevPlayMode != MODE_EXPAND && prevPlayMode != MODE_FADE_TO_BGN) + { + inst->w16_noExpand = 1; + } + else + { + inst->w16_noExpand = 0; + } + + if (cngPacket) + { + /* signed difference between wanted and available TS */ + WebRtc_Word32 diffTS = (inst->uw32_CNGplayedTS + targetTS) - availableTS; + + if ((diffTS) < 0 && (prevPlayMode == MODE_RFC3389CNG)) + { + /* Not time to play this packet yet. Wait another round before using this + * packet. Keep on playing CNG from previous CNG parameters. */ + return BUFSTATS_DO_RFC3389CNG_NOPACKET; + } + + /* otherwise, go for the CNG packet now */ + return BUFSTATS_DO_RFC3389CNG_PACKET; + } + + /*Check for expand/cng */ + if (noPacket) + { + if (inst->w16_cngOn == CNG_RFC3389_ON) + { + /* keep on playing CNG */ + return BUFSTATS_DO_RFC3389CNG_NOPACKET; + } + else if (inst->w16_cngOn == CNG_INTERNAL_ON) + { + /* keep on playing internal CNG */ + return BUFSTATS_DO_INTERNAL_CNG_NOPACKET; + } + else if (playDtmf == 1) + { + /* we have not audio data, but can play DTMF */ + return BUFSTATS_DO_DTMF_ONLY; + } + else + { + /* nothing to play => do Expand */ + return BUFSTATS_DO_EXPAND; + } + } + + /* + * If the expand period was very long, reset NetEQ since it is likely that the + * sender was restarted. + */ + if (NoOfExpandCalls > REINIT_AFTER_EXPANDS) return BUFSTAT_REINIT_DECODER; + + /* Calculate extra delay in Q8 packets */ + if (inst->Automode_inst.extraDelayMs > 0 && inst->Automode_inst.packetSpeechLenSamp + > 0) + { + extraDelayPacketsQ8 = WebRtcSpl_DivW32W16ResW16( + (WEBRTC_SPL_MUL(inst->Automode_inst.extraDelayMs, 8 * fs_mult) << 8), + inst->Automode_inst.packetSpeechLenSamp); + /* (extra delay in samples in Q8) */ + } + + /* Check if needed packet is available */ + if (targetTS == availableTS) + { + + /* If last mode was not expand, and there is no DTMF to play */ + if (inst->w16_noExpand == 1 && playDtmf == 0) + { + /* If so check for accelerate */ + + level_limit_lo = ((inst->Automode_inst.optBufLevel) >> 1) /* 50 % */ + + ((inst->Automode_inst.optBufLevel) >> 2); /* ... + 25% = 75% */ + + /* set upper limit to optBufLevel, but make sure that window is at least 20ms */ + level_limit_hi = WEBRTC_SPL_MAX(inst->Automode_inst.optBufLevel, + level_limit_lo + + WebRtcSpl_DivW32W16ResW16((WEBRTC_SPL_MUL(20*8, fs_mult) << 8), + inst->Automode_inst.packetSpeechLenSamp)); + + /* if extra delay is non-zero, add it */ + if (extraDelayPacketsQ8 > 0) + { + level_limit_hi += extraDelayPacketsQ8; + level_limit_lo += extraDelayPacketsQ8; + } + + if (((inst->Automode_inst.buffLevelFilt >= level_limit_hi) && + (inst->Automode_inst.timescaleHoldOff == 0)) || + (inst->Automode_inst.buffLevelFilt >= level_limit_hi << 2)) + { + /* + * Buffer level higher than limit and time-scaling allowed, + * OR buffer level _really_ high. + */ + return BUFSTATS_DO_ACCELERATE; + } + else if ((inst->Automode_inst.buffLevelFilt < level_limit_lo) + && (inst->Automode_inst.timescaleHoldOff == 0)) + { + return BUFSTATS_DO_PREEMPTIVE_EXPAND; + } + } + return BUFSTATS_DO_NORMAL; + } + + /* Check for Merge */ + else if (availableTS > targetTS) + { + + /* Check that we do not play a packet "too early" */ + if ((prevPlayMode == MODE_EXPAND) + && (availableTS - targetTS + < (WebRtc_UWord32) WEBRTC_SPL_MUL_16_16((WebRtc_Word16)timestampsPerCall, + (WebRtc_Word16)REINIT_AFTER_EXPANDS)) + && (NoOfExpandCalls < MAX_WAIT_FOR_PACKET) + && (availableTS + > targetTS + + WEBRTC_SPL_MUL_16_16((WebRtc_Word16)timestampsPerCall, + (WebRtc_Word16)NoOfExpandCalls)) + && (inst->Automode_inst.buffLevelFilt <= inst->Automode_inst.optBufLevel + + extraDelayPacketsQ8)) + { + if (playDtmf == 1) + { + /* we still have DTMF to play, so do not perform expand */ + return BUFSTATS_DO_DTMF_ONLY; + } + else + { + /* nothing to play */ + return BUFSTATS_DO_EXPAND; + } + } + + /* If previous was CNG period or BGNonly then no merge is needed */ + if ((prevPlayMode == MODE_RFC3389CNG) || (prevPlayMode == MODE_CODEC_INTERNAL_CNG) + || lastModeBGNonly) + { + /* + * Keep the same delay as before the CNG (or maximum 70 ms in buffer as safety + * precaution), but make sure that the number of samples in buffer is no + * higher than 4 times the optimal level. + */ + WebRtc_Word32 diffTS = (inst->uw32_CNGplayedTS + targetTS) - availableTS; + if (diffTS >= 0 + || (WEBRTC_SPL_MUL_16_16_RSFT( inst->Automode_inst.optBufLevel + + extraDelayPacketsQ8, + inst->Automode_inst.packetSpeechLenSamp, 6) < currSizeSamples)) + { + /* it is time to play this new packet */ + return BUFSTATS_DO_NORMAL; + } + else + { + /* it is too early to play this new packet => keep on playing CNG */ + if (prevPlayMode == MODE_RFC3389CNG) + { + return BUFSTATS_DO_RFC3389CNG_NOPACKET; + } + else if (prevPlayMode == MODE_CODEC_INTERNAL_CNG) + { + return BUFSTATS_DO_INTERNAL_CNG_NOPACKET; + } + else if (playDtmf == 1) + { + /* we have not audio data, but can play DTMF */ + return BUFSTATS_DO_DTMF_ONLY; + } + else /* lastModeBGNonly */ + { + /* signal expand, but this will result in BGN again */ + return BUFSTATS_DO_EXPAND; + } + } + } + + /* Do not merge unless we have done a Expand before (for complexity reasons) */ + if ((inst->w16_noExpand == 0) || ((frameSize < timestampsPerCall) && (cur_size + > NETEQ_BUFSTAT_20MS_Q7))) + { + return BUFSTATS_DO_MERGE; + } + else if (playDtmf == 1) + { + /* play DTMF instead of expand */ + return BUFSTATS_DO_DTMF_ONLY; + } + else + { + return BUFSTATS_DO_EXPAND; + } + } + } + else + { /* kPlayoutOff or kPlayoutFax */ + if (cngPacket) + { + if (((WebRtc_Word32) ((inst->uw32_CNGplayedTS + targetTS) - availableTS)) >= 0) + { + /* time to play this packet now */ + return BUFSTATS_DO_RFC3389CNG_PACKET; + } + else + { + /* wait before playing this packet */ + return BUFSTATS_DO_RFC3389CNG_NOPACKET; + } + } + if (noPacket) + { + /* + * No packet => + * 1. If in CNG mode play as usual + * 2. Otherwise use other method to generate data and hold TS value + */ + if (inst->w16_cngOn == CNG_RFC3389_ON) + { + /* keep on playing CNG */ + return BUFSTATS_DO_RFC3389CNG_NOPACKET; + } + else if (inst->w16_cngOn == CNG_INTERNAL_ON) + { + /* keep on playing internal CNG */ + return BUFSTATS_DO_INTERNAL_CNG_NOPACKET; + } + else + { + /* nothing to play => invent some data to play out */ + if (playoutMode == kPlayoutOff) + { + return BUFSTATS_DO_ALTERNATIVE_PLC; + } + else if (playoutMode == kPlayoutFax) + { + return BUFSTATS_DO_AUDIO_REPETITION; + } + else + { + /* UNDEFINED, should not get here... */ + assert(0); + return BUFSTAT_REINIT; + } + } + } + else if (targetTS == availableTS) + { + return BUFSTATS_DO_NORMAL; + } + else + { + if (((WebRtc_Word32) ((inst->uw32_CNGplayedTS + targetTS) - availableTS)) >= 0) + { + return BUFSTATS_DO_NORMAL; + } + else if (playoutMode == kPlayoutOff) + { + /* + * If currently playing CNG, continue with that. Don't increase TS + * since uw32_CNGplayedTS will be increased. + */ + if (inst->w16_cngOn == CNG_RFC3389_ON) + { + return BUFSTATS_DO_RFC3389CNG_NOPACKET; + } + else if (inst->w16_cngOn == CNG_INTERNAL_ON) + { + return BUFSTATS_DO_INTERNAL_CNG_NOPACKET; + } + else + { + /* + * Otherwise, do PLC and increase TS while waiting for the time to + * play this packet. + */ + return BUFSTATS_DO_ALTERNATIVE_PLC_INC_TS; + } + } + else if (playoutMode == kPlayoutFax) + { + /* + * If currently playing CNG, continue with that don't increase TS since + * uw32_CNGplayedTS will be increased. + */ + if (inst->w16_cngOn == CNG_RFC3389_ON) + { + return BUFSTATS_DO_RFC3389CNG_NOPACKET; + } + else if (inst->w16_cngOn == CNG_INTERNAL_ON) + { + return BUFSTATS_DO_INTERNAL_CNG_NOPACKET; + } + else + { + /* + * Otherwise, do audio repetition and increase TS while waiting for the + * time to play this packet. + */ + return BUFSTATS_DO_AUDIO_REPETITION_INC_TS; + } + } + else + { + /* UNDEFINED, should not get here... */ + assert(0); + return BUFSTAT_REINIT; + } + } + } + /* We should not get here (but sometimes we do anyway...) */ + return BUFSTAT_REINIT; +} + diff --git a/src/libs/webrtc/neteq/cng_internal.c b/src/libs/webrtc/neteq/cng_internal.c new file mode 100644 index 00000000..f3a10dcf --- /dev/null +++ b/src/libs/webrtc/neteq/cng_internal.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the function for obtaining comfort noise from noise parameters + * according to IETF RFC 3389. + */ + +#include "dsp.h" + +#include "signal_processing_library.h" +#include "webrtc_cng.h" + +#include "dsp_helpfunctions.h" +#include "neteq_error_codes.h" + +/**************************************************************************** + * WebRtcNetEQ_Cng(...) + * + * This function produces CNG according to RFC 3389. + * + * Input: + * - inst : NetEQ DSP instance + * - len : Number of samples to produce (max 640 or + * 640 - fsHz*5/8000 for first-time CNG, governed by + * the definition of WEBRTC_CNG_MAX_OUTSIZE_ORDER in + * webrtc_cng.h) + * + * Output: + * - pw16_outData : Output CNG + * + * Return value : 0 - Ok + * <0 - Error + */ + +#ifdef NETEQ_CNG_CODEC +/* Must compile NetEQ with CNG support to enable this function */ + +int WebRtcNetEQ_Cng(DSPInst_t *inst, WebRtc_Word16 *pw16_outData, int len) +{ + WebRtc_Word16 w16_winMute = 0; /* mixing factor for overlap data */ + WebRtc_Word16 w16_winUnMute = 0; /* mixing factor for comfort noise */ + WebRtc_Word16 w16_winMuteInc = 0; /* mixing factor increment (negative) */ + WebRtc_Word16 w16_winUnMuteInc = 0; /* mixing factor increment */ + int i; + + /* + * Check if last RecOut call was other than RFC3389, + * that is, this call is the first of a CNG period. + */ + if (inst->w16_mode != MODE_RFC3389CNG) + { + /* Reset generation and overlap slightly with old data */ + + /* Generate len samples + overlap */ + if (WebRtcCng_Generate(inst->CNG_Codec_inst, pw16_outData, + (WebRtc_Word16) (len + inst->ExpandInst.w16_overlap), 1) < 0) + { + /* error returned */ + return -WebRtcCng_GetErrorCodeDec(inst->CNG_Codec_inst); + } + + /* Set windowing parameters depending on sample rate */ + if (inst->fs == 8000) + { + /* Windowing in Q15 */ + w16_winMute = NETEQ_OVERLAP_WINMUTE_8KHZ_START; + w16_winMuteInc = NETEQ_OVERLAP_WINMUTE_8KHZ_INC; + w16_winUnMute = NETEQ_OVERLAP_WINUNMUTE_8KHZ_START; + w16_winUnMuteInc = NETEQ_OVERLAP_WINUNMUTE_8KHZ_INC; +#ifdef NETEQ_WIDEBAND + } + else if (inst->fs == 16000) + { + /* Windowing in Q15 */ + w16_winMute = NETEQ_OVERLAP_WINMUTE_16KHZ_START; + w16_winMuteInc = NETEQ_OVERLAP_WINMUTE_16KHZ_INC; + w16_winUnMute = NETEQ_OVERLAP_WINUNMUTE_16KHZ_START; + w16_winUnMuteInc = NETEQ_OVERLAP_WINUNMUTE_16KHZ_INC; +#endif +#ifdef NETEQ_32KHZ_WIDEBAND + } + else if (inst->fs == 32000) + { + /* Windowing in Q15 */ + w16_winMute = NETEQ_OVERLAP_WINMUTE_32KHZ_START; + w16_winMuteInc = NETEQ_OVERLAP_WINMUTE_32KHZ_INC; + w16_winUnMute = NETEQ_OVERLAP_WINUNMUTE_32KHZ_START; + w16_winUnMuteInc = NETEQ_OVERLAP_WINUNMUTE_32KHZ_INC; +#endif +#ifdef NETEQ_48KHZ_WIDEBAND + } + else if (inst->fs == 48000) + { + /* Windowing in Q15 */ + w16_winMute = NETEQ_OVERLAP_WINMUTE_48KHZ_START; + w16_winMuteInc = NETEQ_OVERLAP_WINMUTE_48KHZ_INC; + w16_winUnMute = NETEQ_OVERLAP_WINUNMUTE_48KHZ_START; + w16_winUnMuteInc = NETEQ_OVERLAP_WINUNMUTE_48KHZ_INC; +#endif + } + else + { + /* Unsupported sample rate (should not be possible) */ + return NETEQ_OTHER_ERROR; + } + + /* Do overlap add between new vector and overlap */ + for (i = 0; i < inst->ExpandInst.w16_overlap; i++) + { + /* overlapVec[i] = WinMute * overlapVec[i] + WinUnMute * outData[i] */ + inst->ExpandInst.pw16_overlapVec[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32( + WEBRTC_SPL_MUL_16_16( + inst->ExpandInst.pw16_overlapVec[i], w16_winMute) + + WEBRTC_SPL_MUL_16_16(pw16_outData[i], w16_winUnMute) + + 16384, 15); /* shift with proper rounding */ + + w16_winMute += w16_winMuteInc; /* decrease mute factor (inc<0) */ + w16_winUnMute += w16_winUnMuteInc; /* increase unmute factor (inc>0) */ + + } + + /* + * Shift the contents of the outData buffer by overlap samples, since we + * already used these first samples in the overlapVec above + */ + + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_outData+inst->ExpandInst.w16_overlap, len); + + } + else + { + /* This is a subsequent CNG call; no special overlap needed */ + + /* Generate len samples */ + if (WebRtcCng_Generate(inst->CNG_Codec_inst, pw16_outData, (WebRtc_Word16) len, 0) < 0) + { + /* error returned */ + return -WebRtcCng_GetErrorCodeDec(inst->CNG_Codec_inst); + } + } + + return 0; + +} + +#endif /* NETEQ_CNG_CODEC */ + diff --git a/src/libs/webrtc/neteq/codec_db.c b/src/libs/webrtc/neteq/codec_db.c new file mode 100644 index 00000000..c15306d3 --- /dev/null +++ b/src/libs/webrtc/neteq/codec_db.c @@ -0,0 +1,737 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Implementation of the codec database. + */ + +#include "codec_db.h" + +#include <string.h> /* to define NULL */ + +#include "signal_processing_library.h" + +#include "neteq_error_codes.h" + +/* + * Resets the codec database. + */ + +int WebRtcNetEQ_DbReset(CodecDbInst_t *inst) +{ + int i; + + WebRtcSpl_MemSetW16((WebRtc_Word16*) inst, 0, + sizeof(CodecDbInst_t) / sizeof(WebRtc_Word16)); + + for (i = 0; i < NUM_TOTAL_CODECS; i++) + { + inst->position[i] = -1; + } + + for (i = 0; i < NUM_CODECS; i++) + { + inst->payloadType[i] = -1; + } + + for (i = 0; i < NUM_CNG_CODECS; i++) + { + inst->CNGpayloadType[i] = -1; + } + + return 0; +} + +/* + * Adds a new codec to the database. + */ + +int WebRtcNetEQ_DbAdd(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec, + WebRtc_Word16 payloadType, FuncDecode funcDecode, + FuncDecode funcDecodeRCU, FuncDecodePLC funcDecodePLC, + FuncDecodeInit funcDecodeInit, FuncAddLatePkt funcAddLatePkt, + FuncGetMDinfo funcGetMDinfo, FuncGetPitchInfo funcGetPitch, + FuncUpdBWEst funcUpdBWEst, FuncGetErrorCode funcGetErrorCode, + void* codec_state, WebRtc_UWord16 codec_fs) +{ + + int temp; + int insertCNGcodec = 0, overwriteCNGcodec = 0, CNGpos = -1; + +#ifndef NETEQ_RED_CODEC + if (codec == kDecoderRED) + { + return CODEC_DB_UNSUPPORTED_CODEC; + } +#endif + if (((int) codec <= (int) kDecoderReservedStart) || ((int) codec + >= (int) kDecoderReservedEnd)) + { + return CODEC_DB_UNSUPPORTED_CODEC; + } + + if ((codec_fs != 8000) +#ifdef NETEQ_WIDEBAND + &&(codec_fs!=16000) +#endif +#ifdef NETEQ_32KHZ_WIDEBAND + &&(codec_fs!=32000) +#endif +#ifdef NETEQ_48KHZ_WIDEBAND + &&(codec_fs!=48000) +#endif + ) + { + return CODEC_DB_UNSUPPORTED_FS; + } + + /* Ensure that the codec type is supported */ + switch (codec) + { +#ifdef NETEQ_PCM16B_CODEC + case kDecoderPCM16B : +#endif +#ifdef NETEQ_G711_CODEC + case kDecoderPCMu : + case kDecoderPCMa : +#endif +#ifdef NETEQ_ILBC_CODEC + case kDecoderILBC : +#endif +#ifdef NETEQ_ISAC_CODEC + case kDecoderISAC : +#endif +#ifdef NETEQ_ISAC_SWB_CODEC + case kDecoderISACswb : +#endif +#ifdef NETEQ_G722_CODEC + case kDecoderG722 : +#endif +#ifdef NETEQ_WIDEBAND + case kDecoderPCM16Bwb : +#endif +#ifdef NETEQ_32KHZ_WIDEBAND + case kDecoderPCM16Bswb32kHz : +#endif +#ifdef NETEQ_CNG_CODEC + case kDecoderCNG : +#endif +#ifdef NETEQ_ATEVENT_DECODE + case kDecoderAVT : +#endif +#ifdef NETEQ_RED_CODEC + case kDecoderRED : +#endif +#ifdef NETEQ_48KHZ_WIDEBAND + case kDecoderPCM16Bswb48kHz : +#endif +#ifdef NETEQ_ARBITRARY_CODEC + case kDecoderArbitrary: +#endif +#ifdef NETEQ_G729_CODEC + case kDecoderG729: +#endif +#ifdef NETEQ_G729_1_CODEC + case kDecoderG729_1 : +#endif +#ifdef NETEQ_G726_CODEC + case kDecoderG726_16 : + case kDecoderG726_24 : + case kDecoderG726_32 : + case kDecoderG726_40 : +#endif +#ifdef NETEQ_G722_1_CODEC + case kDecoderG722_1_16 : + case kDecoderG722_1_24 : + case kDecoderG722_1_32 : +#endif +#ifdef NETEQ_G722_1C_CODEC + case kDecoderG722_1C_24 : + case kDecoderG722_1C_32 : + case kDecoderG722_1C_48 : +#endif +#ifdef NETEQ_SPEEX_CODEC + case kDecoderSPEEX_8 : + case kDecoderSPEEX_16 : +#endif +#ifdef NETEQ_GSMFR_CODEC + case kDecoderGSMFR : +#endif +#ifdef NETEQ_AMR_CODEC + case kDecoderAMR : +#endif +#ifdef NETEQ_AMRWB_CODEC + case kDecoderAMRWB : +#endif + { + /* If we end up here, the inserted codec is supported => Do nothing */ + break; + } + default: + { + /* If we get to this point, the inserted codec is not supported */ + return CODEC_DB_UNSUPPORTED_CODEC; + } + } + + /* Check to see if payload type is taken */ + if (WebRtcNetEQ_DbGetCodec(inst, payloadType) > 0) + { + return CODEC_DB_PAYLOAD_TAKEN; + } + + /* Special case for CNG codecs */ + if (codec == kDecoderCNG) + { + /* check if this is first CNG codec to be registered */ + if (WebRtcNetEQ_DbGetPayload(inst, codec) == CODEC_DB_NOT_EXIST2) + { + /* no other CNG codec found */ + insertCNGcodec = 1; + } + + /* find the appropriate insert position in CNG payload vector */ + switch (codec_fs) + { +#ifdef NETEQ_WIDEBAND + case 16000: + CNGpos = 1; + break; +#endif +#ifdef NETEQ_32KHZ_WIDEBAND + case 32000: + CNGpos = 2; + break; +#endif +#ifdef NETEQ_48KHZ_WIDEBAND + case 48000: + CNGpos = 3; + break; +#endif + default: /* 8000 Hz case */ + CNGpos = 0; + /* + * The 8 kHz CNG payload type is the one associated with the regular codec DB + * should override any other setting. + * Overwrite if this isn't the first CNG + */ + overwriteCNGcodec = !insertCNGcodec; + break; + } + + /* insert CNG payload type */ + inst->CNGpayloadType[CNGpos] = payloadType; + + } + + if ((codec != kDecoderCNG) || (insertCNGcodec == 1) || (overwriteCNGcodec == 1)) + { + /* Check if we have reached the maximum numbers of simultaneous codecs */ + if (inst->nrOfCodecs == NUM_CODECS) return CODEC_DB_FULL; + + /* Check that codec has not already been initialized to DB => + remove it and reinitialize according to new spec */ + if ((inst->position[codec] != -1) && (overwriteCNGcodec != 1)) + { /* if registering multiple CNG codecs, don't remove, just overwrite */ + WebRtcNetEQ_DbRemove(inst, codec); + } + + if (overwriteCNGcodec == 1) + { + temp = inst->position[codec]; + } + else + { + temp = inst->nrOfCodecs; /* Store this codecs position */ + inst->position[codec] = temp; + inst->nrOfCodecs++; + } + + inst->payloadType[temp] = payloadType; + + /* Copy to database */ + inst->codec_state[temp] = codec_state; + inst->funcDecode[temp] = funcDecode; + inst->funcDecodeRCU[temp] = funcDecodeRCU; + inst->funcAddLatePkt[temp] = funcAddLatePkt; + inst->funcDecodeInit[temp] = funcDecodeInit; + inst->funcDecodePLC[temp] = funcDecodePLC; + inst->funcGetMDinfo[temp] = funcGetMDinfo; + inst->funcGetPitch[temp] = funcGetPitch; + inst->funcUpdBWEst[temp] = funcUpdBWEst; + inst->funcGetErrorCode[temp] = funcGetErrorCode; + inst->codec_fs[temp] = codec_fs; + + } + + return 0; +} + +/* + * Removes a codec from the database. + */ + +int WebRtcNetEQ_DbRemove(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec) +{ + int i; + int pos = -1; + +#ifndef NETEQ_RED_CODEC + if (codec == kDecoderRED) + { + return CODEC_DB_UNSUPPORTED_CODEC; + } +#endif + if (((int) codec <= (int) kDecoderReservedStart) || ((int) codec + >= (int) kDecoderReservedEnd)) + { + return CODEC_DB_UNSUPPORTED_CODEC; + } + + pos = inst->position[codec]; + if (pos == -1) + { + return CODEC_DB_NOT_EXIST4; + } + else + { + /* Remove this codec */ + inst->position[codec] = -1; + for (i = pos; i < (inst->nrOfCodecs - 1); i++) + { + inst->payloadType[i] = inst->payloadType[i + 1]; + inst->codec_state[i] = inst->codec_state[i + 1]; + inst->funcDecode[i] = inst->funcDecode[i + 1]; + inst->funcDecodeRCU[i] = inst->funcDecodeRCU[i + 1]; + inst->funcAddLatePkt[i] = inst->funcAddLatePkt[i + 1]; + inst->funcDecodeInit[i] = inst->funcDecodeInit[i + 1]; + inst->funcDecodePLC[i] = inst->funcDecodePLC[i + 1]; + inst->funcGetMDinfo[i] = inst->funcGetMDinfo[i + 1]; + inst->funcGetPitch[i] = inst->funcGetPitch[i + 1]; + inst->funcUpdBWEst[i] = inst->funcUpdBWEst[i + 1]; + inst->funcGetErrorCode[i] = inst->funcGetErrorCode[i + 1]; + inst->codec_fs[i] = inst->codec_fs[i + 1]; + } + inst->payloadType[i] = -1; + inst->codec_state[i] = NULL; + inst->funcDecode[i] = NULL; + inst->funcDecodeRCU[i] = NULL; + inst->funcAddLatePkt[i] = NULL; + inst->funcDecodeInit[i] = NULL; + inst->funcDecodePLC[i] = NULL; + inst->funcGetMDinfo[i] = NULL; + inst->funcGetPitch[i] = NULL; + inst->funcUpdBWEst[i] = NULL; + inst->funcGetErrorCode[i] = NULL; + inst->codec_fs[i] = 0; + /* Move down all the codecs above this one */ + for (i = 0; i < NUM_TOTAL_CODECS; i++) + { + if (inst->position[i] >= pos) + { + inst->position[i] = inst->position[i] - 1; + } + } + inst->nrOfCodecs--; + + if (codec == kDecoderCNG) + { + /* also remove all registered CNG payload types */ + for (i = 0; i < NUM_CNG_CODECS; i++) + { + inst->CNGpayloadType[i] = -1; + } + } + } + return 0; +} + +/* + * Get the decoder function pointers for a codec. + */ + +int WebRtcNetEQ_DbGetPtrs(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec, + CodecFuncInst_t *ptr_inst) +{ + + int pos = inst->position[codec]; + if ((codec <= kDecoderReservedStart) || (codec >= kDecoderReservedEnd) || (codec + > NUM_TOTAL_CODECS)) + { + /* ERROR */ + pos = -1; + } + if (pos >= 0) + { + ptr_inst->codec_state = inst->codec_state[pos]; + ptr_inst->funcAddLatePkt = inst->funcAddLatePkt[pos]; + ptr_inst->funcDecode = inst->funcDecode[pos]; + ptr_inst->funcDecodeRCU = inst->funcDecodeRCU[pos]; + ptr_inst->funcDecodeInit = inst->funcDecodeInit[pos]; + ptr_inst->funcDecodePLC = inst->funcDecodePLC[pos]; + ptr_inst->funcGetMDinfo = inst->funcGetMDinfo[pos]; + ptr_inst->funcUpdBWEst = inst->funcUpdBWEst[pos]; + ptr_inst->funcGetErrorCode = inst->funcGetErrorCode[pos]; + ptr_inst->codec_fs = inst->codec_fs[pos]; + return 0; + } + else + { + WebRtcSpl_MemSetW16((WebRtc_Word16*) ptr_inst, 0, + sizeof(CodecFuncInst_t) / sizeof(WebRtc_Word16)); + return CODEC_DB_NOT_EXIST1; + } +} + +/* + * Returns payload number given a codec identifier. + */ + +int WebRtcNetEQ_DbGetPayload(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codecID) +{ + if (inst->position[codecID] == -1) + return CODEC_DB_NOT_EXIST2; + else + return (inst->payloadType[inst->position[codecID]]); + +} + +/* + * Returns codec identifier given a payload number. + * Returns -1 if the payload type does not exist. + */ + +int WebRtcNetEQ_DbGetCodec(CodecDbInst_t *inst, int payloadType) +{ + int i, pos; + + for (i = 0; i < NUM_TOTAL_CODECS; i++) + { + pos = inst->position[i]; + if (pos != -1) + { + if (inst->payloadType[pos] == payloadType) return i; + } + } + + /* did not find payload type */ + /* check if it's a CNG codec */ + if (WebRtcNetEQ_DbIsCNGPayload(inst, payloadType)) + { + return kDecoderCNG; + } + + /* found no match */ + return CODEC_DB_NOT_EXIST3; +} + +/* + * Extracts the Payload Split information of the codec with the specified payloadType. + */ + +int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecID, + int codedsize) +{ + + switch (codecID) + { +#ifdef NETEQ_ISAC_CODEC + case kDecoderISAC: +#endif +#ifdef NETEQ_ISAC_SWB_CODEC + case kDecoderISACswb: +#endif +#ifdef NETEQ_ARBITRARY_CODEC + case kDecoderArbitrary: +#endif +#ifdef NETEQ_AMR_CODEC + case kDecoderAMR: +#endif +#ifdef NETEQ_AMRWB_CODEC + case kDecoderAMRWB: +#endif +#ifdef NETEQ_G726_CODEC + /* Treat G726 as non-splittable to simplify the implementation */ + case kDecoderG726_16: + case kDecoderG726_24: + case kDecoderG726_32: + case kDecoderG726_40: +#endif +#ifdef NETEQ_SPEEX_CODEC + case kDecoderSPEEX_8: + case kDecoderSPEEX_16: +#endif +#ifdef NETEQ_G729_1_CODEC + case kDecoderG729_1: +#endif + { + /* These codecs' payloads are not splittable */ + inst->deltaBytes = NO_SPLIT; + return 0; + } + + /* + * Sample based coders are a special case. + * In this case, deltaTime signals the number of bytes per timestamp unit times 2 + * in log2 domain. + */ +#if (defined NETEQ_G711_CODEC) + case kDecoderPCMu: + case kDecoderPCMa: + { + inst->deltaBytes = -12; + inst->deltaTime = 1; + return 0; + } +#endif +#if (defined NETEQ_G722_CODEC) + case kDecoderG722: + { + inst->deltaBytes = -14; + inst->deltaTime = 0; + return 0; + } +#endif +#if (defined NETEQ_PCM16B_CODEC) + case kDecoderPCM16B: + { + inst->deltaBytes = -12; + inst->deltaTime = 2; + return 0; + } +#endif +#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_WIDEBAND)) + case kDecoderPCM16Bwb: + { + inst->deltaBytes = -14; + inst->deltaTime = 2; + return 0; + } +#endif +#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_32KHZ_WIDEBAND)) + case kDecoderPCM16Bswb32kHz: + { + inst->deltaBytes = -18; + inst->deltaTime = 2; + return 0; + } +#endif +#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_48KHZ_WIDEBAND)) + case kDecoderPCM16Bswb48kHz: + { + inst->deltaBytes = -22; + inst->deltaTime = 2; + return 0; + } +#endif + + /* Splittable payloads */ +#ifdef NETEQ_G722_1_CODEC + case kDecoderG722_1_16: + { + inst->deltaBytes = 40; + inst->deltaTime = 320; + return 0; + } + case kDecoderG722_1_24: + { + inst->deltaBytes = 60; + inst->deltaTime = 320; + return 0; + } + case kDecoderG722_1_32: + { + inst->deltaBytes = 80; + inst->deltaTime = 320; + return 0; + } +#endif +#ifdef NETEQ_G722_1C_CODEC + case kDecoderG722_1C_24: + { + inst->deltaBytes = 60; + inst->deltaTime = 640; + return 0; + } + case kDecoderG722_1C_32: + { + inst->deltaBytes = 80; + inst->deltaTime = 640; + return 0; + } + case kDecoderG722_1C_48: + { + inst->deltaBytes = 120; + inst->deltaTime = 640; + return 0; + } +#endif +#ifdef NETEQ_G729_CODEC + case kDecoderG729: + { + inst->deltaBytes = 10; + inst->deltaTime = 80; + return 0; + } +#endif +#ifdef NETEQ_ILBC_CODEC + case kDecoderILBC: + { + /* Check for splitting of iLBC packets. + * If payload size is a multiple of 50 bytes it should be split into 30ms frames. + * If payload size is a multiple of 38 bytes it should be split into 20ms frames. + * Least common multiplier between 38 and 50 is 950, so the payload size must be less than + * 950 bytes in order to resolve the frames unambiguously. + * Currently max 12 frames in one bundle. + */ + switch (codedsize) + { + case 50: + case 100: + case 150: + case 200: + case 250: + case 300: + case 350: + case 400: + case 450: + case 500: + case 550: + case 600: + { + inst->deltaBytes = 50; + inst->deltaTime = 240; + break; + } + case 38: + case 76: + case 114: + case 152: + case 190: + case 228: + case 266: + case 304: + case 342: + case 380: + case 418: + case 456: + { + inst->deltaBytes = 38; + inst->deltaTime = 160; + break; + } + default: + { + return AMBIGUOUS_ILBC_FRAME_SIZE; /* Something not supported... */ + } + } + return 0; + } +#endif +#ifdef NETEQ_GSMFR_CODEC + case kDecoderGSMFR: + { + inst->deltaBytes = 33; + inst->deltaTime = 160; + return 0; + } +#endif + default: + { /*Unknown codec */ + inst->deltaBytes = NO_SPLIT; + return CODEC_DB_UNKNOWN_CODEC; + } + } /* end of switch */ +} + +/* + * Returns 1 if codec is multiple description, 0 otherwise. + * NOTE: This function is a stub, since there currently are no MD codecs. + */ +int WebRtcNetEQ_DbIsMDCodec(enum WebRtcNetEQDecoder codecID) +{ + if (0) /* Add test for MD codecs here */ + return 1; + else + return 0; +} + +/* + * Returns 1 if payload type is registered as a CNG codec, 0 otherwise + */ +int WebRtcNetEQ_DbIsCNGPayload(CodecDbInst_t *inst, int payloadType) +{ +#ifdef NETEQ_CNG_CODEC + int i; + + for(i=0; i<NUM_CNG_CODECS; i++) + { + if( (inst->CNGpayloadType[i] != -1) && (inst->CNGpayloadType[i] == payloadType) ) + { + return 1; + } + } +#endif + + return 0; + +} + +/* + * Return the sample rate for the codec with the given payload type, 0 if error + */ +WebRtc_UWord16 WebRtcNetEQ_DbGetSampleRate(CodecDbInst_t *inst, int payloadType) +{ + int i; + CodecFuncInst_t codecInst; + + /* Sanity */ + if (inst == NULL) + { + /* return 0 Hz */ + return 0; + } + + /* Check among CNG payloads */ + for (i = 0; i < NUM_CNG_CODECS; i++) + { + if ((inst->CNGpayloadType[i] != -1) && (inst->CNGpayloadType[i] == payloadType)) + { + switch (i) + { + case 1: + return 16000; + case 2: + return 32000; + case 3: + return 48000; + default: + return 8000; + } + } + } + + /* Not a CNG payload, check the other payloads */ + i = WebRtcNetEQ_DbGetCodec(inst, payloadType); + if (i >= 0) + { + if (WebRtcNetEQ_DbGetPtrs(inst, (enum WebRtcNetEQDecoder) i, &codecInst) != 0) + { + /* Unexpected error, return 0 Hz */ + return 0; + } + return codecInst.codec_fs; + } + + /* If we end up here, we got an error, return 0 Hz */ + return 0; + +} + diff --git a/src/libs/webrtc/neteq/codec_db.h b/src/libs/webrtc/neteq/codec_db.h new file mode 100644 index 00000000..7f429807 --- /dev/null +++ b/src/libs/webrtc/neteq/codec_db.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Interface for the codec database. + */ + +#ifndef CODEC_DB_H +#define CODEC_DB_H + +#include "typedefs.h" + +#include "webrtc_neteq.h" +#include "codec_db_defines.h" +#include "neteq_defines.h" + +#if defined(NETEQ_48KHZ_WIDEBAND) + #define NUM_CNG_CODECS 4 +#elif defined(NETEQ_32KHZ_WIDEBAND) + #define NUM_CNG_CODECS 3 +#elif defined(NETEQ_WIDEBAND) + #define NUM_CNG_CODECS 2 +#else + #define NUM_CNG_CODECS 1 +#endif + +typedef struct +{ + + WebRtc_Word16 position[NUM_TOTAL_CODECS]; + WebRtc_Word16 nrOfCodecs; + + WebRtc_Word16 payloadType[NUM_CODECS]; + FuncDecode funcDecode[NUM_CODECS]; + FuncDecode funcDecodeRCU[NUM_CODECS]; + FuncDecodePLC funcDecodePLC[NUM_CODECS]; + FuncDecodeInit funcDecodeInit[NUM_CODECS]; + FuncAddLatePkt funcAddLatePkt[NUM_CODECS]; + FuncGetMDinfo funcGetMDinfo[NUM_CODECS]; + FuncGetPitchInfo funcGetPitch[NUM_CODECS]; + FuncUpdBWEst funcUpdBWEst[NUM_CODECS]; + FuncGetErrorCode funcGetErrorCode[NUM_CODECS]; + void * codec_state[NUM_CODECS]; + WebRtc_UWord16 codec_fs[NUM_CODECS]; + WebRtc_Word16 CNGpayloadType[NUM_CNG_CODECS]; + +} CodecDbInst_t; + +#define NO_SPLIT -1 /* codec payload cannot be split */ + +typedef struct +{ + WebRtc_Word16 deltaBytes; + WebRtc_Word16 deltaTime; +} SplitInfo_t; + +/* + * Resets the codec database. + */ +int WebRtcNetEQ_DbReset(CodecDbInst_t *inst); + +/* + * Adds a new codec to the database. + */ +int WebRtcNetEQ_DbAdd(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec, + WebRtc_Word16 payloadType, FuncDecode funcDecode, + FuncDecode funcDecodeRCU, FuncDecodePLC funcDecodePLC, + FuncDecodeInit funcDecodeInit, FuncAddLatePkt funcAddLatePkt, + FuncGetMDinfo funcGetMDinfo, FuncGetPitchInfo funcGetPitch, + FuncUpdBWEst funcUpdBWEst, FuncGetErrorCode funcGetErrorCode, + void* codec_state, WebRtc_UWord16 codec_fs); + +/* + * Removes a codec from the database. + */ +int WebRtcNetEQ_DbRemove(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec); + +/* + * Get the decoder function pointers for a codec. + */ +int WebRtcNetEQ_DbGetPtrs(CodecDbInst_t *inst, enum WebRtcNetEQDecoder, + CodecFuncInst_t *ptr_inst); + +/* + * Returns payload number given a codec identifier. + */ + +int WebRtcNetEQ_DbGetPayload(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codecID); + +/* + * Returns codec identifier given a payload number. + */ + +int WebRtcNetEQ_DbGetCodec(CodecDbInst_t *inst, int payloadType); + +/* + * Extracts the Payload Split information of the codec with the specified payloadType. + */ + +int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecID, + int codedsize); + +/* + * Returns 1 if codec is multiple description type, 0 otherwise. + */ +int WebRtcNetEQ_DbIsMDCodec(enum WebRtcNetEQDecoder codecID); + +/* + * Returns 1 if payload type is registered as a CNG codec, 0 otherwise. + */ +int WebRtcNetEQ_DbIsCNGPayload(CodecDbInst_t *inst, int payloadType); + +/* + * Return the sample rate for the codec with the given payload type, 0 if error. + */ +WebRtc_UWord16 WebRtcNetEQ_DbGetSampleRate(CodecDbInst_t *inst, int payloadType); + +#endif + diff --git a/src/libs/webrtc/neteq/codec_db_defines.h b/src/libs/webrtc/neteq/codec_db_defines.h new file mode 100644 index 00000000..9b78b862 --- /dev/null +++ b/src/libs/webrtc/neteq/codec_db_defines.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Some definitions related to the codec database. + */ + +#ifndef CODEC_DB_DEFINES_H +#define CODEC_DB_DEFINES_H + +#include "typedefs.h" + +#define NUM_CODECS 47 /* probably too large with the limited set of supported codecs*/ +#define NUM_TOTAL_CODECS kDecoderReservedEnd + +/* + * Pointer to decoder function. + */ +typedef WebRtc_Word16 (*FuncDecode)(void* state, WebRtc_Word16* encoded, WebRtc_Word16 len, + WebRtc_Word16* decoded, WebRtc_Word16* speechType); + +/* + * Pointer to PLC function. + */ +typedef WebRtc_Word16 (*FuncDecodePLC)(void* state, WebRtc_Word16* decodec, + WebRtc_Word16 frames); + +/* + * Pointer to decoder init function. + */ +typedef WebRtc_Word16 (*FuncDecodeInit)(void* state); + +/* + * Pointer to add late packet function. + */ +typedef WebRtc_Word16 + (*FuncAddLatePkt)(void* state, WebRtc_Word16* encoded, WebRtc_Word16 len); + +/* + * Pointer to get MD infofunction. + */ +typedef WebRtc_Word16 (*FuncGetMDinfo)(void* state); + +/* + * Pointer to pitch info function. + * Return 0 for unvoiced, -1 if pitch not availiable. + */ +typedef WebRtc_Word16 (*FuncGetPitchInfo)(void* state, WebRtc_Word16* encoded, + WebRtc_Word16* length); + +/* + * Pointer to the update bandwidth estimate function + */ +typedef WebRtc_Word16 (*FuncUpdBWEst)(void* state, const WebRtc_UWord16 *encoded, + WebRtc_Word32 packet_size, + WebRtc_UWord16 rtp_seq_number, WebRtc_UWord32 send_ts, + WebRtc_UWord32 arr_ts); + +/* + * Pointer to error code function + */ +typedef WebRtc_Word16 (*FuncGetErrorCode)(void* state); + +typedef struct CodecFuncInst_t_ +{ + + FuncDecode funcDecode; + FuncDecode funcDecodeRCU; + FuncDecodePLC funcDecodePLC; + FuncDecodeInit funcDecodeInit; + FuncAddLatePkt funcAddLatePkt; + FuncGetMDinfo funcGetMDinfo; + FuncUpdBWEst funcUpdBWEst; /* Currently in use for the ISAC family (without LC) only*/ + FuncGetErrorCode funcGetErrorCode; + void * codec_state; + WebRtc_UWord16 codec_fs; + WebRtc_UWord32 timeStamp; + +} CodecFuncInst_t; + +#endif + diff --git a/src/libs/webrtc/neteq/correlator.c b/src/libs/webrtc/neteq/correlator.c new file mode 100644 index 00000000..97c41da8 --- /dev/null +++ b/src/libs/webrtc/neteq/correlator.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "dsp.h" + +#include "signal_processing_library.h" + +#include "dsp_helpfunctions.h" + +/* Scratch usage: + + Type Name size startpos endpos + WebRtc_Word16 pw16_corrVec 62 0 61 + WebRtc_Word16 pw16_data_ds 124 0 123 + WebRtc_Word32 pw32_corr 2*54 124 231 + + Total: 232 + */ + +#define SCRATCH_pw16_corrVec 0 +#define SCRATCH_pw16_data_ds 0 +#define SCRATCH_pw32_corr 124 + +#define NETEQ_CORRELATOR_DSVECLEN 124 /* 124 = 60 + 10 + 54 */ + +WebRtc_Word16 WebRtcNetEQ_Correlator(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + WebRtc_Word16 *pw16_data, + WebRtc_Word16 w16_dataLen, + WebRtc_Word16 *pw16_corrOut, + WebRtc_Word16 *pw16_corrScale) +{ + WebRtc_Word16 w16_corrLen = 60; +#ifdef SCRATCH + WebRtc_Word16 *pw16_data_ds = pw16_scratchPtr + SCRATCH_pw16_corrVec; + WebRtc_Word32 *pw32_corr = (WebRtc_Word32*) (pw16_scratchPtr + SCRATCH_pw32_corr); + /* WebRtc_Word16 *pw16_corrVec = pw16_scratchPtr + SCRATCH_pw16_corrVec;*/ +#else + WebRtc_Word16 pw16_data_ds[NETEQ_CORRELATOR_DSVECLEN]; + WebRtc_Word32 pw32_corr[54]; + /* WebRtc_Word16 pw16_corrVec[4+54+4];*/ +#endif + /* WebRtc_Word16 *pw16_corr=&pw16_corrVec[4];*/ + WebRtc_Word16 w16_maxVal; + WebRtc_Word32 w32_maxVal; + WebRtc_Word16 w16_normVal; + WebRtc_Word16 w16_normVal2; + /* WebRtc_Word16 w16_corrUpsLen;*/ + WebRtc_Word16 *pw16_B = NULL; + WebRtc_Word16 w16_Blen = 0; + WebRtc_Word16 w16_factor = 0; + + /* Set constants depending on frequency used */ + if (inst->fs == 8000) + { + w16_Blen = 3; + w16_factor = 2; + pw16_B = (WebRtc_Word16*) WebRtcNetEQ_kDownsample8kHzTbl; +#ifdef NETEQ_WIDEBAND + } + else if (inst->fs==16000) + { + w16_Blen = 5; + w16_factor = 4; + pw16_B = (WebRtc_Word16*)WebRtcNetEQ_kDownsample16kHzTbl; +#endif +#ifdef NETEQ_32KHZ_WIDEBAND + } + else if (inst->fs==32000) + { + w16_Blen = 7; + w16_factor = 8; + pw16_B = (WebRtc_Word16*)WebRtcNetEQ_kDownsample32kHzTbl; +#endif +#ifdef NETEQ_48KHZ_WIDEBAND + } + else /* if inst->fs==48000 */ + { + w16_Blen = 7; + w16_factor = 12; + pw16_B = (WebRtc_Word16*)WebRtcNetEQ_kDownsample48kHzTbl; +#endif + } + + /* Downsample data in order to work on a 4 kHz sampled signal */ + WebRtcSpl_DownsampleFast( + pw16_data + w16_dataLen - (NETEQ_CORRELATOR_DSVECLEN * w16_factor), + (WebRtc_Word16) (NETEQ_CORRELATOR_DSVECLEN * w16_factor), pw16_data_ds, + NETEQ_CORRELATOR_DSVECLEN, pw16_B, w16_Blen, w16_factor, (WebRtc_Word16) 0); + + /* Normalize downsampled vector to using entire 16 bit */ + w16_maxVal = WebRtcSpl_MaxAbsValueW16(pw16_data_ds, 124); + w16_normVal = 16 - WebRtcSpl_NormW32((WebRtc_Word32) w16_maxVal); + WebRtcSpl_VectorBitShiftW16(pw16_data_ds, NETEQ_CORRELATOR_DSVECLEN, pw16_data_ds, + w16_normVal); + + /* Correlate from lag 10 to lag 60 (20..120 in NB and 40..240 in WB) */ + + WebRtcNetEQ_CrossCorr( + pw32_corr, &pw16_data_ds[NETEQ_CORRELATOR_DSVECLEN - w16_corrLen], + &pw16_data_ds[NETEQ_CORRELATOR_DSVECLEN - w16_corrLen - 10], 60, 54, + 6 /*maxValue... shifts*/, -1); + + /* + * Move data from w32 to w16 vector. + * Normalize downsampled vector to using all 14 bits + */ + w32_maxVal = WebRtcSpl_MaxAbsValueW32(pw32_corr, 54); + w16_normVal2 = 18 - WebRtcSpl_NormW32(w32_maxVal); + w16_normVal2 = WEBRTC_SPL_MAX(w16_normVal2, 0); + + WebRtcSpl_VectorBitShiftW32ToW16(pw16_corrOut, 54, pw32_corr, w16_normVal2); + + /* Total scale factor (right shifts) of correlation value */ + *pw16_corrScale = 2 * w16_normVal + 6 + w16_normVal2; + + return (50 + 1); +} + +#undef SCRATCH_pw16_corrVec +#undef SCRATCH_pw16_data_ds +#undef SCRATCH_pw32_corr + diff --git a/src/libs/webrtc/neteq/delay_logging.h b/src/libs/webrtc/neteq/delay_logging.h new file mode 100644 index 00000000..04b1c401 --- /dev/null +++ b/src/libs/webrtc/neteq/delay_logging.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Contains definitions for the delay logging functionality. Only used for debugging and + * tracing purposes. + */ + +#ifndef DELAY_LOGGING_H +#define DELAY_LOGGING_H + +#define NETEQ_DELAY_LOGGING_VERSION_STRING "2.0" + +#define NETEQ_DELAY_LOGGING_SIGNAL_RECIN 1 +#define NETEQ_DELAY_LOGGING_SIGNAL_FLUSH 2 +#define NETEQ_DELAY_LOGGING_SIGNAL_CLOCK 3 +#define NETEQ_DELAY_LOGGING_SIGNAL_EOF 4 +#define NETEQ_DELAY_LOGGING_SIGNAL_DECODE 5 +#define NETEQ_DELAY_LOGGING_SIGNAL_CHANGE_FS 6 +#define NETEQ_DELAY_LOGGING_SIGNAL_MERGE_INFO 7 +#define NETEQ_DELAY_LOGGING_SIGNAL_EXPAND_INFO 8 +#define NETEQ_DELAY_LOGGING_SIGNAL_ACCELERATE_INFO 9 +#define NETEQ_DELAY_LOGGING_SIGNAL_PREEMPTIVE_INFO 10 +#define NETEQ_DELAY_LOGGING_SIGNAL_OPTBUF 11 +#define NETEQ_DELAY_LOGGING_SIGNAL_DECODE_ONE_DESC 12 + +#endif diff --git a/src/libs/webrtc/neteq/dsp.c b/src/libs/webrtc/neteq/dsp.c new file mode 100644 index 00000000..73396b2f --- /dev/null +++ b/src/libs/webrtc/neteq/dsp.c @@ -0,0 +1,523 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains some DSP initialization functions and + * constant table definitions. + */ + +#include "dsp.h" + +#include "signal_processing_library.h" + +#include "neteq_error_codes.h" + +/* Filter coefficients used when downsampling from the indicated + sample rates (8, 16, 32, 48 kHz) to 4 kHz. + Coefficients are in Q12. */ + +/* {0.3, 0.4, 0.3} */ +const WebRtc_Word16 WebRtcNetEQ_kDownsample8kHzTbl[] = { 1229, 1638, 1229 }; + +#ifdef NETEQ_WIDEBAND +/* {0.15, 0.2, 0.3, 0.2, 0.15} */ +const WebRtc_Word16 WebRtcNetEQ_kDownsample16kHzTbl[] = +{ 614, 819, 1229, 819, 614}; +#endif + +#ifdef NETEQ_32KHZ_WIDEBAND +/* {0.1425, 0.1251, 0.1525, 0.1628, 0.1525, 0.1251, 0.1425} */ +const WebRtc_Word16 WebRtcNetEQ_kDownsample32kHzTbl[] = +{ 584, 512, 625, 667, 625, 512, 584}; +#endif + +#ifdef NETEQ_48KHZ_WIDEBAND +/* {0.2487, 0.0952, 0.1042, 0.1074, 0.1042, 0.0952, 0.2487} */ +const WebRtc_Word16 WebRtcNetEQ_kDownsample48kHzTbl[] = +{ 1019, 390, 427, 440, 427, 390, 1019}; +#endif + +/* Constants used in expand function WebRtcNetEQ_Expand */ + +/* Q12: -1.264421 + 4.8659148*x - 4.0092827*x^2 + 1.4100529*x^3 */ +const WebRtc_Word16 WebRtcNetEQ_kMixFractionFuncTbl[4] = { -5179, 19931, -16422, 5776 }; + +/* Tabulated divisions to save complexity */ +/* 1049/{0, .., 6} */ +const WebRtc_Word16 WebRtcNetEQ_k1049div[7] = { 0, 1049, 524, 349, 262, 209, 174 }; + +/* 2097/{0, .., 6} */ +const WebRtc_Word16 WebRtcNetEQ_k2097div[7] = { 0, 2097, 1048, 699, 524, 419, 349 }; + +/* 5243/{0, .., 6} */ +const WebRtc_Word16 WebRtcNetEQ_k5243div[7] = { 0, 5243, 2621, 1747, 1310, 1048, 873 }; + +#ifdef WEBRTC_NETEQ_40BITACC_TEST +/* + * Run NetEQ with simulated 40-bit accumulator to run bit-exact to a DSP + * implementation where the main (spl and NetEQ) functions have been + * 40-bit optimized. For testing purposes. + */ + +/**************************************************************************** + * WebRtcNetEQ_40BitAccCrossCorr(...) + * + * Calculates the Cross correlation between two sequences seq1 and seq2. Seq1 + * is fixed and seq2 slides as the pointer is increased with step + * + * Input: + * - seq1 : First sequence (fixed throughout the correlation) + * - seq2 : Second sequence (slided step_seq2 for each + * new correlation) + * - dimSeq : Number of samples to use in the cross correlation. + * Should be no larger than 1024 to avoid overflow. + * - dimCrossCorr : Number of CrossCorrelations to calculate (start + * position for seq2 is updated for each new one) + * - rShift : Number of right shifts to use + * - step_seq2 : How many (positive or negative) steps the seq2 + * pointer should be updated for each new cross + * correlation value + * + * Output: + * - crossCorr : The cross correlation in Q-rShift + */ + +void WebRtcNetEQ_40BitAccCrossCorr(WebRtc_Word32 *crossCorr, + WebRtc_Word16 *seq1, + WebRtc_Word16 *seq2, + WebRtc_Word16 dimSeq, + WebRtc_Word16 dimCrossCorr, + WebRtc_Word16 rShift, + WebRtc_Word16 step_seq2) +{ + int i, j; + WebRtc_Word16 *seq1Ptr, *seq2Ptr; + WebRtc_Word64 acc; + + for (i = 0; i < dimCrossCorr; i++) + { + /* Set the pointer to the static vector, set the pointer to + the sliding vector and initialize crossCorr */ + seq1Ptr = seq1; + seq2Ptr = seq2 + (step_seq2 * i); + acc = 0; + + /* Perform the cross correlation */ + for (j = 0; j < dimSeq; j++) + { + acc += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); + seq1Ptr++; + seq2Ptr++; + } + + (*crossCorr) = (WebRtc_Word32) (acc >> rShift); + crossCorr++; + } +} + +/**************************************************************************** + * WebRtcNetEQ_40BitAccDotW16W16(...) + * + * Calculates the dot product between two vectors (WebRtc_Word16) + * + * Input: + * - vector1 : Vector 1 + * - vector2 : Vector 2 + * - len : Number of samples in vector + * Should be no larger than 1024 to avoid overflow. + * - scaling : The number of left shifts required to avoid overflow + * in the dot product + * Return value : The dot product + */ + +WebRtc_Word32 WebRtcNetEQ_40BitAccDotW16W16(WebRtc_Word16 *vector1, + WebRtc_Word16 *vector2, + int len, + int scaling) +{ + WebRtc_Word32 sum; + int i; + WebRtc_Word64 acc; + + acc = 0; + for (i = 0; i < len; i++) + { + acc += WEBRTC_SPL_MUL_16_16(*vector1++, *vector2++); + } + + sum = (WebRtc_Word32) (acc >> scaling); + + return(sum); +} + +#endif /* WEBRTC_NETEQ_40BITACC_TEST */ + +/**************************************************************************** + * WebRtcNetEQ_DSPInit(...) + * + * Initializes DSP side of NetEQ. + * + * Input: + * - inst : NetEq DSP instance + * - fs : Initial sample rate (may change when decoding data) + * + * Output: + * - inst : Updated instance + * + * Return value : 0 - ok + * : non-zero - error + */ + +int WebRtcNetEQ_DSPInit(DSPInst_t *inst, WebRtc_UWord16 fs) +{ + + int res = 0; + WebRtc_Word16 fs_mult; + + /* Pointers and values to save before clearing the instance */ +#ifdef NETEQ_CNG_CODEC + void *savedPtr1 = inst->CNG_Codec_inst; +#endif + void *savedPtr2 = inst->pw16_readAddress; + void *savedPtr3 = inst->pw16_writeAddress; + void *savedPtr4 = inst->main_inst; +#ifdef NETEQ_VAD + void *savedVADptr = inst->VADInst.VADState; + VADInitFunction savedVADinit = inst->VADInst.initFunction; + VADSetmodeFunction savedVADsetmode = inst->VADInst.setmodeFunction; + VADFunction savedVADfunc = inst->VADInst.VADFunction; + WebRtc_Word16 savedVADEnabled = inst->VADInst.VADEnabled; + WebRtc_Word16 savedVADMode = inst->VADInst.VADMode; +#endif /* NETEQ_VAD */ + DSPStats_t saveStats; + WebRtc_Word16 saveMsPerCall = inst->millisecondsPerCall; + enum BGNMode saveBgnMode = inst->BGNInst.bgnMode; +#ifdef NETEQ_STEREO + MasterSlaveInfo saveMSinfo; +#endif + + /* copy contents of statInst to avoid clearing */WEBRTC_SPL_MEMCPY_W16(&saveStats, &(inst->statInst), + sizeof(DSPStats_t)/sizeof(WebRtc_Word16)); + +#ifdef NETEQ_STEREO + /* copy contents of msInfo to avoid clearing */WEBRTC_SPL_MEMCPY_W16(&saveMSinfo, &(inst->msInfo), + sizeof(MasterSlaveInfo)/sizeof(WebRtc_Word16)); +#endif + + /* check that the sample rate is valid */ + if ((fs != 8000) +#ifdef NETEQ_WIDEBAND + &&(fs!=16000) +#endif +#ifdef NETEQ_32KHZ_WIDEBAND + &&(fs!=32000) +#endif +#ifdef NETEQ_48KHZ_WIDEBAND + &&(fs!=48000) +#endif + ) + { + /* invalid rate */ + return (CODEC_DB_UNSUPPORTED_FS); + } + + /* calcualte fs/8000 */ + fs_mult = WebRtcSpl_DivW32W16ResW16(fs, 8000); + + /* Set everything to zero since most variables should be zero at start */ + WebRtcSpl_MemSetW16((WebRtc_Word16 *) inst, 0, sizeof(DSPInst_t) / sizeof(WebRtc_Word16)); + + /* Restore saved pointers */ +#ifdef NETEQ_CNG_CODEC + inst->CNG_Codec_inst = (CNG_dec_inst *)savedPtr1; +#endif + inst->pw16_readAddress = (WebRtc_Word16 *) savedPtr2; + inst->pw16_writeAddress = (WebRtc_Word16 *) savedPtr3; + inst->main_inst = savedPtr4; +#ifdef NETEQ_VAD + inst->VADInst.VADState = savedVADptr; + inst->VADInst.initFunction = savedVADinit; + inst->VADInst.setmodeFunction = savedVADsetmode; + inst->VADInst.VADFunction = savedVADfunc; + inst->VADInst.VADEnabled = savedVADEnabled; + inst->VADInst.VADMode = savedVADMode; +#endif /* NETEQ_VAD */ + + /* Initialize main part */ + inst->fs = fs; + inst->millisecondsPerCall = saveMsPerCall; + inst->timestampsPerCall = inst->millisecondsPerCall * 8 * fs_mult; + inst->ExpandInst.w16_overlap = 5 * fs_mult; + inst->endPosition = 565 * fs_mult; + inst->curPosition = inst->endPosition - inst->ExpandInst.w16_overlap; + inst->w16_seedInc = 1; + inst->uw16_seed = 777; + inst->w16_muteFactor = 16384; /* 1.0 in Q14 */ + inst->w16_frameLen = 3 * inst->timestampsPerCall; /* Dummy initialize to 30ms */ + + inst->w16_speechHistoryLen = 256 * fs_mult; + inst->pw16_speechHistory = &inst->speechBuffer[inst->endPosition + - inst->w16_speechHistoryLen]; + inst->ExpandInst.pw16_overlapVec = &(inst->pw16_speechHistory[inst->w16_speechHistoryLen + - inst->ExpandInst.w16_overlap]); + + /* Reusage of memory in speechBuffer inside Expand */ + inst->ExpandInst.pw16_expVecs[0] = &inst->speechBuffer[0]; + inst->ExpandInst.pw16_expVecs[1] = &inst->speechBuffer[126 * fs_mult]; + inst->ExpandInst.pw16_arState = &inst->speechBuffer[2 * 126 * fs_mult]; + inst->ExpandInst.pw16_arFilter = &inst->speechBuffer[2 * 126 * fs_mult + + UNVOICED_LPC_ORDER]; + /* Ends at 2*126*fs_mult+UNVOICED_LPC_ORDER+(UNVOICED_LPC_ORDER+1) */ + + inst->ExpandInst.w16_expandMuteFactor = 16384; /* 1.0 in Q14 */ + + /* Initialize BGN part */ + inst->BGNInst.pw16_filter[0] = 4096; + inst->BGNInst.w16_scale = 20000; + inst->BGNInst.w16_scaleShift = 24; + inst->BGNInst.w32_energyUpdate = 500000; + inst->BGNInst.w32_energyUpdateLow = 0; + inst->BGNInst.w32_energy = 2500; + inst->BGNInst.w16_initialized = 0; + inst->BGNInst.bgnMode = saveBgnMode; + + /* Recreate statistics counters */WEBRTC_SPL_MEMCPY_W16(&(inst->statInst), &saveStats, + sizeof(DSPStats_t)/sizeof(WebRtc_Word16)); + +#ifdef NETEQ_STEREO + /* Recreate MSinfo */WEBRTC_SPL_MEMCPY_W16(&(inst->msInfo), &saveMSinfo, + sizeof(MasterSlaveInfo)/sizeof(WebRtc_Word16)); +#endif + +#ifdef NETEQ_CNG_CODEC + if (inst->CNG_Codec_inst!=NULL) + { + /* initialize comfort noise generator */ + res |= WebRtcCng_InitDec(inst->CNG_Codec_inst); + } +#endif + +#ifdef NETEQ_VAD + /* initialize PostDecode VAD instance + (don't bother checking for NULL instance, this is done inside init function) */ + res |= WebRtcNetEQ_InitVAD(&inst->VADInst, fs); +#endif /* NETEQ_VAD */ + + return (res); +} + +/**************************************************************************** + * WebRtcNetEQ_AddressInit(...) + * + * Initializes the shared-memory communication on the DSP side. + * + * Input: + * - inst : NetEQ DSP instance + * - data2McuAddress : Pointer to memory where DSP writes / MCU reads + * - data2DspAddress : Pointer to memory where MCU writes / DSP reads + * - mainInst : NetEQ main instance + * + * Output: + * - inst : Updated instance + * + * Return value : 0 - ok + */ + +int WebRtcNetEQ_AddressInit(DSPInst_t *inst, const void *data2McuAddress, + const void *data2DspAddress, const void *mainInst) +{ + + /* set shared-memory addresses in the DSP instance */ + inst->pw16_readAddress = (WebRtc_Word16 *) data2DspAddress; + inst->pw16_writeAddress = (WebRtc_Word16 *) data2McuAddress; + + /* set pointer to main NetEQ instance */ + inst->main_inst = (void *) mainInst; + + /* set output frame size to 10 ms = 80 samples in narrowband */ + inst->millisecondsPerCall = 10; + inst->timestampsPerCall = 80; + + return (0); + +} + +/**************************************************************************** + * NETEQDSP_clearInCallStats(...) + * + * Reset in-call statistics variables on DSP side. + * + * Input: + * - inst : NetEQ DSP instance + * + * Output: + * - inst : Updated instance + * + * Return value : 0 - ok + */ + +int WebRtcNetEQ_ClearInCallStats(DSPInst_t *inst) +{ + + /* Reset statistics counters */ + inst->statInst.accelerateLength = 0; + inst->statInst.expandLength = 0; + inst->statInst.preemptiveLength = 0; + + return (0); +} + +/**************************************************************************** + * WebRtcNetEQ_ClearPostCallStats(...) + * + * Reset post-call statistics variables on DSP side. + * + * Input: + * - inst : NetEQ DSP instance + * + * Output: + * - inst : Updated instance + * + * Return value : 0 - ok + */ + +int WebRtcNetEQ_ClearPostCallStats(DSPInst_t *inst) +{ + + /* Reset statistics counters */ + inst->statInst.expandedVoiceSamples = 0; + inst->statInst.expandedNoiseSamples = 0; + + return (0); +} + +#ifdef NETEQ_VAD + +/**************************************************************************** + * WebRtcNetEQ_InitVAD(...) + * + * Initializes post-decode VAD instance. + * + * Input: + * - VADinst : PostDecodeVAD instance + * - fs : Initial sample rate + * + * Output: + * - VADinst : Updated instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_InitVAD(PostDecodeVAD_t *VADInst, WebRtc_UWord16 fs) +{ + + int res = 0; + + /* initially, disable the post-decode VAD */ + VADInst->VADEnabled = 0; + + if (VADInst->VADState != NULL /* if VAD state is provided */ + && VADInst->initFunction != NULL /* and all function ... */ + && VADInst->setmodeFunction != NULL /* ... pointers ... */ + && VADInst->VADFunction != NULL) /* ... are defined */ + { + res = (int) VADInst->initFunction( VADInst->VADState ); /* call VAD init function */ + res |= WebRtcNetEQ_SetVADModeInternal( VADInst, VADInst->VADMode ); + + if (res!=0) + { + /* something is wrong; play it safe and set the VADstate to NULL */ + VADInst->VADState = NULL; + } + else if (fs<=16000) + { + /* enable VAD if NB or WB (VAD cannot handle SWB) */ + VADInst->VADEnabled = 1; + } + } + + /* reset SID/CNG interval counter */ + VADInst->SIDintervalCounter = 0; + + /* initialize with active-speaker decision */ + VADInst->VADDecision = 1; + + return(res); + +} + +/**************************************************************************** + * WebRtcNetEQ_SetVADModeInternal(...) + * + * Set the VAD mode in the VAD struct, and communicate it to the VAD instance + * if it exists. + * + * Input: + * - VADinst : PostDecodeVAD instance + * - mode : Mode number passed on to the VAD function + * + * Output: + * - VADinst : Updated instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_SetVADModeInternal(PostDecodeVAD_t *VADInst, + WebRtc_Word16 mode) +{ + + int res = 0; + + VADInst->VADMode = mode; + + if (VADInst->VADState != NULL) + { + /* call setmode function */ + res = (int) VADInst->setmodeFunction(VADInst->VADState, mode); + } + + return(res); + +} + +#endif /* NETEQ_VAD */ + +/**************************************************************************** + * WebRtcNetEQ_FlushSpeechBuffer(...) + * + * Flush the speech buffer. + * + * Input: + * - inst : NetEq DSP instance + * + * Output: + * - inst : Updated instance + * + * Return value : 0 - ok + * : non-zero - error + */ + +int WebRtcNetEQ_FlushSpeechBuffer(DSPInst_t *inst) +{ + WebRtc_Word16 fs_mult; + + /* calcualte fs/8000 */ + fs_mult = WebRtcSpl_DivW32W16ResW16(inst->fs, 8000); + + /* clear buffer */ + WebRtcSpl_MemSetW16(inst->speechBuffer, 0, SPEECH_BUF_SIZE); + inst->endPosition = 565 * fs_mult; + inst->curPosition = inst->endPosition - inst->ExpandInst.w16_overlap; + + return 0; +} + diff --git a/src/libs/webrtc/neteq/dsp.h b/src/libs/webrtc/neteq/dsp.h new file mode 100644 index 00000000..0b042293 --- /dev/null +++ b/src/libs/webrtc/neteq/dsp.h @@ -0,0 +1,788 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains some DSP initialization functions, + * constant table definitions and other parameters. + * Also contains definitions of all DSP-side data structures. + */ + + +#ifndef DSP_H +#define DSP_H + +#include "typedefs.h" + +#include "webrtc_cng.h" + +#include "codec_db_defines.h" +#include "neteq_defines.h" +#include "neteq_statistics.h" + +#ifdef NETEQ_ATEVENT_DECODE +#include "dtmf_tonegen.h" +#endif + + + +/*****************************/ +/* Pre-processor definitions */ +/*****************************/ + +/* FSMULT is the sample rate divided by 8000 */ +#if defined(NETEQ_48KHZ_WIDEBAND) + #define FSMULT 6 +#elif defined(NETEQ_32KHZ_WIDEBAND) + #define FSMULT 4 +#elif defined(NETEQ_WIDEBAND) + #define FSMULT 2 +#else + #define FSMULT 1 +#endif + +/* Size of the speech buffer (or synchronization buffer). */ +/* 60 ms decoding + 10 ms syncbuff + 0.625ms lookahead */ +#define SPEECH_BUF_SIZE (565 * FSMULT) + +/* Misc definitions */ +#define BGN_LPC_ORDER (4 + FSMULT) /* 5, 6, 8, or 10 */ +#define UNVOICED_LPC_ORDER 6 +#define RANDVEC_NO_OF_SAMPLES 256 + +/* Number of milliseconds to remove/add during accelerate/pre-emptive expand + under BGNonly operation */ +#define DEFAULT_TIME_ADJUST 8 + +/* Number of RecOut calls without CNG/SID before re-enabling post-decode VAD */ +#define POST_DECODE_VAD_AUTO_ENABLE 3000 + +/* 8kHz windowing in Q15 (over 5 samples) */ +#define NETEQ_OVERLAP_WINMUTE_8KHZ_START 27307 +#define NETEQ_OVERLAP_WINMUTE_8KHZ_INC -5461 +#define NETEQ_OVERLAP_WINUNMUTE_8KHZ_START 5461 +#define NETEQ_OVERLAP_WINUNMUTE_8KHZ_INC 5461 +/* 16kHz windowing in Q15 (over 10 samples) */ +#define NETEQ_OVERLAP_WINMUTE_16KHZ_START 29789 +#define NETEQ_OVERLAP_WINMUTE_16KHZ_INC -2979 +#define NETEQ_OVERLAP_WINUNMUTE_16KHZ_START 2979 +#define NETEQ_OVERLAP_WINUNMUTE_16KHZ_INC 2979 +/* 32kHz windowing in Q15 (over 20 samples) */ +#define NETEQ_OVERLAP_WINMUTE_32KHZ_START 31208 +#define NETEQ_OVERLAP_WINMUTE_32KHZ_INC -1560 +#define NETEQ_OVERLAP_WINUNMUTE_32KHZ_START 1560 +#define NETEQ_OVERLAP_WINUNMUTE_32KHZ_INC 1560 +/* 48kHz windowing in Q15 (over 30 samples) */ +#define NETEQ_OVERLAP_WINMUTE_48KHZ_START 31711 +#define NETEQ_OVERLAP_WINMUTE_48KHZ_INC -1057 +#define NETEQ_OVERLAP_WINUNMUTE_48KHZ_START 1057 +#define NETEQ_OVERLAP_WINUNMUTE_48KHZ_INC 1057 + +/* Fade BGN towards zero after this many Expand calls */ +#define FADE_BGN_TIME 200 + + +/*******************/ +/* Constant tables */ +/*******************/ + +extern const WebRtc_Word16 WebRtcNetEQ_kDownsample8kHzTbl[]; +extern const WebRtc_Word16 WebRtcNetEQ_kDownsample16kHzTbl[]; +extern const WebRtc_Word16 WebRtcNetEQ_kDownsample32kHzTbl[]; +extern const WebRtc_Word16 WebRtcNetEQ_kDownsample48kHzTbl[]; +extern const WebRtc_Word16 WebRtcNetEQ_kRandnTbl[]; +extern const WebRtc_Word16 WebRtcNetEQ_kMixFractionFuncTbl[]; +extern const WebRtc_Word16 WebRtcNetEQ_k1049div[]; +extern const WebRtc_Word16 WebRtcNetEQ_k2097div[]; +extern const WebRtc_Word16 WebRtcNetEQ_k5243div[]; + + + +/************/ +/* Typedefs */ +/************/ + +enum BGNMode +{ + BGN_ON, /* default "normal" behavior with eternal noise */ + BGN_FADE, /* noise fades to zero after some time */ + BGN_OFF /* background noise is always zero */ +}; + +#ifdef NETEQ_STEREO +enum MasterSlaveMode +{ + NETEQ_MONO, /* stand-alone instance */ + NETEQ_MASTER, /* master instance in a spatial/stereo configuration */ + NETEQ_SLAVE /* slave instance in a spatial/stereo configuration */ +}; + +enum MasterSlaveExtraInfo +{ + NO_INFO, /* no info to convey */ + ACC_FAIL, /* signal that accelerate failed */ + PE_EXP_FAIL, /* signal that pre-emptive expand failed */ + DTMF_OVERDUB, /* signal that DTMF overdub is generated */ + DTMF_ONLY /* signal that DTMF only is played */ +}; +#endif + +/****************************/ +/* DSP-side data structures */ +/****************************/ + +/* Background noise (BGN) instance for storing BGN parameters + (sub-instance of NETEQDSP_inst) */ +typedef struct BGNInst_t_ +{ + + WebRtc_Word32 w32_energy; + WebRtc_Word32 w32_energyMax; + WebRtc_Word32 w32_energyUpdate; + WebRtc_Word32 w32_energyUpdateLow; + WebRtc_Word16 pw16_filterState[BGN_LPC_ORDER]; + WebRtc_Word16 pw16_filter[BGN_LPC_ORDER + 1]; + WebRtc_Word16 w16_mutefactor; + WebRtc_Word16 w16_scale; + WebRtc_Word16 w16_scaleShift; + WebRtc_Word16 w16_initialized; + enum BGNMode bgnMode; + +} BGNInst_t; + +/* Expansion instance (sub-instance of NETEQDSP_inst) */ +typedef struct ExpandInst_t_ +{ + + WebRtc_Word16 w16_overlap; /* Constant, 5 for NB and 10 for WB */ + WebRtc_Word16 w16_consecExp; /* Number of consecutive expand calls */ + WebRtc_Word16 *pw16_arFilter; /* length [UNVOICED_LPC_ORDER+1] */ + WebRtc_Word16 *pw16_arState; /* length [UNVOICED_LPC_ORDER] */ + WebRtc_Word16 w16_arGain; + WebRtc_Word16 w16_arGainScale; + WebRtc_Word16 w16_vFraction; /* Q14 */ + WebRtc_Word16 w16_currentVFraction; /* Q14 */ + WebRtc_Word16 *pw16_expVecs[2]; + WebRtc_Word16 w16_lags[3]; + WebRtc_Word16 w16_maxLag; + WebRtc_Word16 *pw16_overlapVec; /* last samples of speech history */ + WebRtc_Word16 w16_lagsDirection; + WebRtc_Word16 w16_lagsPosition; + WebRtc_Word16 w16_expandMuteFactor; /* Q14 */ + WebRtc_Word16 w16_stopMuting; + WebRtc_Word16 w16_onset; + WebRtc_Word16 w16_muteSlope; /* Q20 */ + +} ExpandInst_t; + +#ifdef NETEQ_VAD + +/* + * VAD function pointer types, replicating the typedefs in webrtc_neteq_internal.h. + * These function pointers match the definitions of WebRtc VAD functions WebRtcVad_Init, + * WebRtcVad_set_mode and WebRtcVad_Process, respectively, all found in webrtc_vad.h. + */ +typedef WebRtc_Word16 (*VADInitFunction)(void *VAD_inst); +typedef WebRtc_Word16 (*VADSetmodeFunction)(void *VAD_inst, WebRtc_Word16 mode); +typedef WebRtc_Word16 (*VADFunction)(void *VAD_inst, WebRtc_Word16 fs, WebRtc_Word16 *frame, + WebRtc_Word16 frameLen); + +/* Post-decode VAD instance (sub-instance of NETEQDSP_inst) */ +typedef struct PostDecodeVAD_t_ +{ + + void *VADState; /* pointer to a VAD instance */ + + WebRtc_Word16 VADEnabled; /* 1 if enabled, 0 if disabled */ + WebRtc_Word16 VADMode; /* mode parameter to pass to the VAD function */ + WebRtc_Word16 VADDecision; /* 1 for active, 0 for passive */ + WebRtc_Word16 SIDintervalCounter; /* reset when decoding CNG/SID frame, + increment for each recout call */ + + /* Function pointers */ + VADInitFunction initFunction; /* VAD init function */ + VADSetmodeFunction setmodeFunction; /* VAD setmode function */ + VADFunction VADFunction; /* VAD function */ + +} PostDecodeVAD_t; + +#endif /* NETEQ_VAD */ + +#ifdef NETEQ_STEREO +#define MAX_MS_DECODES 10 + +typedef struct +{ + /* Stand-alone, master, or slave */ + enum MasterSlaveMode msMode; + + enum MasterSlaveExtraInfo extraInfo; + + WebRtc_UWord16 instruction; + WebRtc_Word16 distLag; + WebRtc_Word16 corrLag; + WebRtc_Word16 bestIndex; + + WebRtc_UWord32 endTimestamp; + WebRtc_UWord16 samplesLeftWithOverlap; + +} MasterSlaveInfo; +#endif + + +/* "Main" NetEQ DSP instance */ +typedef struct DSPInst_t_ +{ + + /* MCU/DSP Communication layer */ + WebRtc_Word16 *pw16_readAddress; + WebRtc_Word16 *pw16_writeAddress; + void *main_inst; + + /* Output frame size in ms and samples */ + WebRtc_Word16 millisecondsPerCall; + WebRtc_Word16 timestampsPerCall; + + /* + * Example of speech buffer + * + * ----------------------------------------------------------- + * | History T-60 to T | Future | + * ----------------------------------------------------------- + * ^ ^ + * | | + * curPosition endPosition + * + * History is gradually shifted out to the left when inserting + * new data at the end. + */ + + WebRtc_Word16 speechBuffer[SPEECH_BUF_SIZE]; /* History/future speech buffer */ + int curPosition; /* Next sample to play */ + int endPosition; /* Position that ends future data */ + WebRtc_UWord32 endTimestamp; /* Timestamp value at end of future data */ + WebRtc_UWord32 videoSyncTimestamp; /* (Estimated) timestamp of the last + played sample (usually same as + endTimestamp-(endPosition-curPosition) + except during Expand and CNG) */ + WebRtc_UWord16 fs; /* sample rate in Hz */ + WebRtc_Word16 w16_frameLen; /* decoder frame length in samples */ + WebRtc_Word16 w16_mode; /* operation used during last RecOut call */ + WebRtc_Word16 w16_muteFactor; /* speech mute factor in Q14 */ + WebRtc_Word16 *pw16_speechHistory; /* beginning of speech history during Expand */ + WebRtc_Word16 w16_speechHistoryLen; /* 256 for NB and 512 for WB */ + + /* random noise seed parameters */ + WebRtc_Word16 w16_seedInc; + WebRtc_UWord32 uw16_seed; + + /* VQmon related variable */ + WebRtc_Word16 w16_concealedTS; + + /*****************/ + /* Sub-instances */ + /*****************/ + + /* Decoder data */ + CodecFuncInst_t codec_ptr_inst; + +#ifdef NETEQ_CNG_CODEC + /* CNG "decoder" instance */ + CNG_dec_inst *CNG_Codec_inst; +#endif /* NETEQ_CNG_CODEC */ + +#ifdef NETEQ_ATEVENT_DECODE + /* DTMF generator instance */ + dtmf_tone_inst_t DTMFInst; +#endif /* NETEQ_CNG_CODEC */ + +#ifdef NETEQ_VAD + /* Post-decode VAD instance */ + PostDecodeVAD_t VADInst; +#endif /* NETEQ_VAD */ + + /* Expand instance (defined above) */ + ExpandInst_t ExpandInst; + + /* Background noise instance (defined above) */ + BGNInst_t BGNInst; + + /* Internal statistics instance */ + DSPStats_t statInst; + +#ifdef NETEQ_STEREO + /* Pointer to Master/Slave info */ + MasterSlaveInfo *msInfo; +#endif + +} DSPInst_t; + + +/*************************/ +/* Function declarations */ +/*************************/ + +/**************************************************************************** + * WebRtcNetEQ_DSPInit(...) + * + * Initializes DSP side of NetEQ. + * + * Input: + * - inst : NetEq DSP instance + * - fs : Initial sample rate (may change when decoding data) + * + * Output: + * - inst : Updated instance + * + * Return value : 0 - ok + * : non-zero - error + */ + +int WebRtcNetEQ_DSPInit(DSPInst_t *inst, WebRtc_UWord16 fs); + +/**************************************************************************** + * WebRtcNetEQ_AddressInit(...) + * + * Initializes the shared-memory communication on the DSP side. + * + * Input: + * - inst : NetEQ DSP instance + * - data2McuAddress : Pointer to memory where DSP writes / MCU reads + * - data2DspAddress : Pointer to memory where MCU writes / DSP reads + * - mainInst : NetEQ main instance + * + * Output: + * - inst : Updated instance + * + * Return value : 0 - ok + */ + +int WebRtcNetEQ_AddressInit(DSPInst_t *inst, const void *data2McuAddress, + const void *data2DspAddress, const void *mainInst); + +/**************************************************************************** + * WebRtcNetEQ_ClearInCallStats(...) + * + * Reset in-call statistics variables on DSP side. + * + * Input: + * - inst : NetEQ DSP instance + * + * Output: + * - inst : Updated instance + * + * Return value : 0 - ok + */ + +int WebRtcNetEQ_ClearInCallStats(DSPInst_t *inst); + +/**************************************************************************** + * WebRtcNetEQ_ClearPostCallStats(...) + * + * Reset post-call statistics variables on DSP side. + * + * Input: + * - inst : NetEQ DSP instance + * + * Output: + * - inst : Updated instance + * + * Return value : 0 - ok + */ + +int WebRtcNetEQ_ClearPostCallStats(DSPInst_t *inst); + +/**************************************************************************** + * WebRtcNetEQ_RecOutInternal(...) + * + * This function asks NetEQ for more speech/audio data. + * + * Input: + * - inst : NetEQ instance, i.e. the user that requests more + * speech/audio data. + * - outdata : Pointer to a memory space where the output data + * should be stored. + * - BGNonly : If non-zero, RecOut will only produce background + * noise. It will still draw packets from the packet + * buffer, but they will never be decoded. + * + * Output: + * - inst : Updated user information + * - len : Number of samples that were outputted from NetEq + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_RecOutInternal(DSPInst_t *inst, WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_len, + WebRtc_Word16 BGNonly); + +/**************************************************************************** + * WebRtcNetEQ_Normal(...) + * + * This function has the possibility to modify data that is played out in Normal + * mode, for example adjust the gain of the signal. The length of the signal + * can not be changed. + * + * Input: + * - inst : NetEQ DSP instance + * - scratchPtr : Pointer to scratch vector + * - decoded : Pointer to vector of new data from decoder + * - len : Number of input samples + * + * Output: + * - inst : Updated user information + * - pw16_len : Pointer to varibale where the number of samples + * produced will be written + * + * Return value : >=0 - Number of samples written to outData + * -1 - Error + */ + +int WebRtcNetEQ_Normal(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + WebRtc_Word16 *pw16_decoded, WebRtc_Word16 len, + WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_len); + +/**************************************************************************** + * WebRtcNetEQ_Expand(...) + * + * This function produces one "chunk" of expansion data (PLC audio). The + * lenght of the produced audio depends on the speech history. + * + * Input: + * - inst : NetEQ DSP instance + * - scratchPtr : Pointer to scratch vector + * - BGNonly : If non-zero, Expand will only produce background + * noise. + * - pw16_len : Desired number of samples (only for BGN mode). + * + * Output: + * - inst : Updated user information + * - outdata : Pointer to a memory space where the output data + * should be stored + * - pw16_len : Number of samples that were outputted from NetEq + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_Expand(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_len, + WebRtc_Word16 BGNonly); + +/**************************************************************************** + * WebRtcNetEQ_GenerateBGN(...) + * + * This function generates and writes len samples of background noise to the + * output vector. The Expand function will be called repeteadly until the + * correct number of samples is produced. + * + * Input: + * - inst : NetEQ DSP instance + * - scratchPtr : Pointer to scratch vector + * - len : Desired length of produced BGN. + * + * + * Output: + * - pw16_outData : Pointer to a memory space where the output data + * should be stored + * + * Return value : >=0 - Number of noise samples produced and written + * to output + * -1 - Error + */ + +int WebRtcNetEQ_GenerateBGN(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + WebRtc_Word16 *pw16_outData, WebRtc_Word16 len); + +/**************************************************************************** + * WebRtcNetEQ_PreEmptiveExpand(...) + * + * This function tries to extend the audio data by repeating one or several + * pitch periods. The operation is only carried out if the correlation is + * strong or if the signal energy is very low. The algorithm is the + * reciprocal of the Accelerate algorithm. + * + * Input: + * - inst : NetEQ DSP instance + * - scratchPtr : Pointer to scratch vector. + * - decoded : Pointer to newly decoded speech. + * - len : Length of decoded speech. + * - oldDataLen : Length of the part of decoded that has already been played out. + * - BGNonly : If non-zero, Pre-emptive Expand will only copy + * the first DEFAULT_TIME_ADJUST seconds of the + * input and append to the end. No signal matching is + * done. + * + * Output: + * - inst : Updated instance + * - outData : Pointer to a memory space where the output data + * should be stored. The vector must be at least + * min(len + 120*fs/8000, NETEQ_MAX_OUTPUT_SIZE) + * elements long. + * - pw16_len : Number of samples written to outData. + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_PreEmptiveExpand(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + const WebRtc_Word16 *pw16_decoded, int len, int oldDataLen, + WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_len, + WebRtc_Word16 BGNonly); + +/**************************************************************************** + * WebRtcNetEQ_Accelerate(...) + * + * This function tries to shorten the audio data by removing one or several + * pitch periods. The operation is only carried out if the correlation is + * strong or if the signal energy is very low. + * + * Input: + * - inst : NetEQ DSP instance + * - scratchPtr : Pointer to scratch vector. + * - decoded : Pointer to newly decoded speech. + * - len : Length of decoded speech. + * - BGNonly : If non-zero, Accelerate will only remove the last + * DEFAULT_TIME_ADJUST seconds of the intput. + * No signal matching is done. + * + * + * Output: + * - inst : Updated instance + * - outData : Pointer to a memory space where the output data + * should be stored + * - pw16_len : Number of samples written to outData. + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_Accelerate(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + const WebRtc_Word16 *pw16_decoded, int len, + WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_len, + WebRtc_Word16 BGNonly); + +/**************************************************************************** + * WebRtcNetEQ_Merge(...) + * + * This function is used to merge new data from the decoder to the exisiting + * stream in the synchronization buffer. The merge operation is typically + * done after a packet loss, where the end of the expanded data does not + * fit naturally with the new decoded data. + * + * Input: + * - inst : NetEQ DSP instance + * - scratchPtr : Pointer to scratch vector. + * - decoded : Pointer to new decoded speech. + * - len : Number of samples in pw16_decoded. + * + * + * Output: + * - inst : Updated user information + * - outData : Pointer to a memory space where the output data + * should be stored + * - pw16_len : Number of samples written to pw16_outData + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_Merge(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + WebRtc_Word16 *pw16_decoded, int len, WebRtc_Word16 *pw16_outData, + WebRtc_Word16 *pw16_len); + +/**************************************************************************** + * WebRtcNetEQ_Cng(...) + * + * This function produces CNG according to RFC 3389 + * + * Input: + * - inst : NetEQ DSP instance + * - len : Number of samples to produce + * + * Output: + * - pw16_outData : Output CNG + * + * Return value : 0 - Ok + * <0 - Error + */ + +#ifdef NETEQ_CNG_CODEC +/* Must compile NetEQ with CNG support to enable this function */ + +int WebRtcNetEQ_Cng(DSPInst_t *inst, WebRtc_Word16 *pw16_outData, int len); + +#endif /* NETEQ_CNG_CODEC */ + +/**************************************************************************** + * WebRtcNetEQ_BGNUpdate(...) + * + * This function updates the background noise parameter estimates. + * + * Input: + * - inst : NetEQ instance, where the speech history is stored. + * - scratchPtr : Pointer to scratch vector. + * + * Output: + * - inst : Updated information about the BGN characteristics. + * + * Return value : No return value + */ + +void WebRtcNetEQ_BGNUpdate( +#ifdef SCRATCH + DSPInst_t *inst, WebRtc_Word16 *pw16_scratchPtr +#else + DSPInst_t *inst +#endif + ); + +#ifdef NETEQ_VAD +/* Functions used by post-decode VAD */ + +/**************************************************************************** + * WebRtcNetEQ_InitVAD(...) + * + * Initializes post-decode VAD instance. + * + * Input: + * - VADinst : PostDecodeVAD instance + * - fs : Initial sample rate + * + * Output: + * - VADinst : Updated instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_InitVAD(PostDecodeVAD_t *VADInst, WebRtc_UWord16 fs); + +/**************************************************************************** + * WebRtcNetEQ_SetVADModeInternal(...) + * + * Set the VAD mode in the VAD struct, and communicate it to the VAD instance + * if it exists. + * + * Input: + * - VADinst : PostDecodeVAD instance + * - mode : Mode number passed on to the VAD function + * + * Output: + * - VADinst : Updated instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_SetVADModeInternal(PostDecodeVAD_t *VADInst, WebRtc_Word16 mode); + +#endif /* NETEQ_VAD */ + +/**************************************************************************** + * WebRtcNetEQ_FlushSpeechBuffer(...) + * + * Flush the speech buffer. + * + * Input: + * - inst : NetEq DSP instance + * + * Output: + * - inst : Updated instance + * + * Return value : 0 - ok + * : non-zero - error + */ + +int WebRtcNetEQ_FlushSpeechBuffer(DSPInst_t *inst); + +#ifndef WEBRTC_NETEQ_40BITACC_TEST + +#include "signal_processing_library.h" +/* Map to regular SPL functions */ +#define WebRtcNetEQ_CrossCorr WebRtcSpl_CrossCorrelation +#define WebRtcNetEQ_DotW16W16 WebRtcSpl_DotProductWithScale + +#else /* WEBRTC_NETEQ_40BITACC_TEST defined */ +/* Run NetEQ with simulated 40-bit accumulator to run bit-exact to a DSP + implementation where the main (splib and NetEQ) functions have been + 40-bit optimized. */ + +/* Map to special 40-bit optimized functions, defined below */ +#define WebRtcNetEQ_CrossCorr WebRtcNetEQ_40BitAccCrossCorr +#define WebRtcNetEQ_DotW16W16 WebRtcNetEQ_40BitAccDotW16W16 + +/**************************************************************************** + * WebRtcNetEQ_40BitAccCrossCorr(...) + * + * Calculates the Cross correlation between two sequences seq1 and seq2. Seq1 + * is fixed and seq2 slides as the pointer is increased with step + * + * Input: + * - seq1 : First sequence (fixed throughout the correlation) + * - seq2 : Second sequence (slided step_seq2 for each + * new correlation) + * - dimSeq : Number of samples to use in the cross correlation. + * Should be no larger than 1024 to avoid overflow. + * - dimCrossCorr : Number of CrossCorrelations to calculate (start + * position for seq2 is updated for each new one) + * - rShift : Number of right shifts to use + * - step_seq2 : How many (positive or negative) steps the seq2 + * pointer should be updated for each new cross + * correlation value + * + * Output: + * - crossCorr : The cross correlation in Q-rShift + */ + +void WebRtcNetEQ_40BitAccCrossCorr(WebRtc_Word32 *crossCorr, WebRtc_Word16 *seq1, + WebRtc_Word16 *seq2, WebRtc_Word16 dimSeq, + WebRtc_Word16 dimCrossCorr, WebRtc_Word16 rShift, + WebRtc_Word16 step_seq2); + +/**************************************************************************** + * WebRtcNetEQ_40BitAccDotW16W16(...) + * + * Calculates the dot product between two vectors (WebRtc_Word16) + * + * Input: + * - vector1 : Vector 1 + * - vector2 : Vector 2 + * - len : Number of samples in vector + * Should be no larger than 1024 to avoid overflow. + * - scaling : The number of right shifts (after multiplication) + * required to avoid overflow in the dot product. + * Return value : The dot product + */ + +WebRtc_Word32 WebRtcNetEQ_40BitAccDotW16W16(WebRtc_Word16 *vector1, WebRtc_Word16 *vector2, + int len, int scaling); + +#endif /* WEBRTC_NETEQ_40BITACC_TEST */ + +#endif /* DSP_H */ diff --git a/src/libs/webrtc/neteq/dsp_helpfunctions.c b/src/libs/webrtc/neteq/dsp_helpfunctions.c new file mode 100644 index 00000000..6e9a2831 --- /dev/null +++ b/src/libs/webrtc/neteq/dsp_helpfunctions.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains some help functions that did not fit elsewhere. + */ + +#include "dsp_helpfunctions.h" + + +WebRtc_Word16 WebRtcNetEQ_CalcFsMult(WebRtc_UWord16 fsHz) +{ + switch (fsHz) + { + case 8000: + { + return 1; + } + case 16000: + { + return 2; + } + case 32000: + { + return 4; + } + case 48000: + { + return 6; + } + default: + { + return 1; + } + } +} + + +int WebRtcNetEQ_DownSampleTo4kHz(const WebRtc_Word16 *in, int inLen, WebRtc_UWord16 inFsHz, + WebRtc_Word16 *out, int outLen, int compensateDelay) +{ + WebRtc_Word16 *B; /* filter coefficients */ + WebRtc_Word16 Blen; /* number of coefficients */ + WebRtc_Word16 filterDelay; /* phase delay in samples */ + WebRtc_Word16 factor; /* conversion rate (inFsHz/8000) */ + int ok; + + /* Set constants depending on frequency used */ + /* NOTE: The phase delay values are wrong compared to the true phase delay + of the filters. However, the error is preserved (through the +1 term) + for consistency. */ + switch (inFsHz) + { + case 8000: + { + Blen = 3; + factor = 2; + B = (WebRtc_Word16*) WebRtcNetEQ_kDownsample8kHzTbl; + filterDelay = 1 + 1; + break; + } +#ifdef NETEQ_WIDEBAND + case 16000: + { + Blen = 5; + factor = 4; + B = (WebRtc_Word16*) WebRtcNetEQ_kDownsample16kHzTbl; + filterDelay = 2 + 1; + break; + } +#endif +#ifdef NETEQ_32KHZ_WIDEBAND + case 32000: + { + Blen = 7; + factor = 8; + B = (WebRtc_Word16*) WebRtcNetEQ_kDownsample32kHzTbl; + filterDelay = 3 + 1; + break; + } +#endif +#ifdef NETEQ_48KHZ_WIDEBAND + case 48000: + { + Blen = 7; + factor = 12; + B = (WebRtc_Word16*) WebRtcNetEQ_kDownsample48kHzTbl; + filterDelay = 3 + 1; + break; + } +#endif + default: + { + /* unsupported or wrong sample rate */ + return -1; + } + } + + if (!compensateDelay) + { + /* disregard delay compensation */ + filterDelay = 0; + } + + ok = WebRtcSpl_DownsampleFast((WebRtc_Word16*) &in[Blen - 1], + (WebRtc_Word16) (inLen - (Blen - 1)), /* number of input samples */ + out, (WebRtc_Word16) outLen, /* number of output samples to produce */ + B, Blen, factor, filterDelay); /* filter parameters */ + + return ok; /* return value is -1 if input signal is too short */ + +} + diff --git a/src/libs/webrtc/neteq/dsp_helpfunctions.h b/src/libs/webrtc/neteq/dsp_helpfunctions.h new file mode 100644 index 00000000..f728c097 --- /dev/null +++ b/src/libs/webrtc/neteq/dsp_helpfunctions.h @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Various help functions used by the DSP functions. + */ + +#ifndef DSP_HELPFUNCTIONS_H +#define DSP_HELPFUNCTIONS_H + +#include "typedefs.h" + +#include "dsp.h" + +/**************************************************************************** + * WebRtcNetEQ_Correlator(...) + * + * Calculate signal correlation. + * + * Input: + * - inst : DSP instance + * - data : Speech history to do expand from (older history in data[-4..-1]) + * - dataLen : Length of data + * + * Output: + * - corrOut : CC of downsampled signal + * - corrScale : Scale factor for correlation (-Qdomain) + * + * Return value : Length of correlated data + */ + +WebRtc_Word16 WebRtcNetEQ_Correlator(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + WebRtc_Word16 *pw16_data, WebRtc_Word16 w16_dataLen, + WebRtc_Word16 *pw16_corrOut, + WebRtc_Word16 *pw16_corrScale); + +/**************************************************************************** + * WebRtcNetEQ_PeakDetection(...) + * + * Peak detection with parabolic fit. + * + * Input: + * - data : Data sequence for peak detection + * - dataLen : Length of data + * - nmbPeaks : Number of peaks to detect + * - fs_mult : Sample rate multiplier + * + * Output: + * - corrIndex : Index of the peak + * - winner : Value of the peak + * + * Return value : 0 for ok + */ + +WebRtc_Word16 WebRtcNetEQ_PeakDetection(WebRtc_Word16 *pw16_data, WebRtc_Word16 w16_dataLen, + WebRtc_Word16 w16_nmbPeaks, WebRtc_Word16 fs_mult, + WebRtc_Word16 *pw16_corrIndex, + WebRtc_Word16 *pw16_winners); + +/**************************************************************************** + * WebRtcNetEQ_PrblFit(...) + * + * Three-point parbola fit. + * + * Input: + * - 3pts : Three input samples + * - fs_mult : Sample rate multiplier + * + * Output: + * - Ind : Index of the peak + * - outVal : Value of the peak + * + * Return value : 0 for ok + */ + +WebRtc_Word16 WebRtcNetEQ_PrblFit(WebRtc_Word16 *pw16_3pts, WebRtc_Word16 *pw16_Ind, + WebRtc_Word16 *pw16_outVal, WebRtc_Word16 fs_mult); + +/**************************************************************************** + * WebRtcNetEQ_MinDistortion(...) + * + * Find the lag that results in minimum distortion. + * + * Input: + * - data : Start of speech to perform distortion on, second vector is assumed + * to be data[-Lag] + * - minLag : Start lag + * - maxLag : End lag + * - len : Length to correlate + * + * Output: + * - dist : Distorion value + * + * Return value : Lag for minimum distortion + */ + +WebRtc_Word16 WebRtcNetEQ_MinDistortion(const WebRtc_Word16 *pw16_data, + WebRtc_Word16 w16_minLag, WebRtc_Word16 w16_maxLag, + WebRtc_Word16 len, WebRtc_Word32 *pw16_dist); + +/**************************************************************************** + * WebRtcNetEQ_RandomVec(...) + * + * Generate random vector. + * + * Input: + * - seed : Current seed (input/output) + * - len : Number of samples to generate + * - incVal : Jump step + * + * Output: + * - randVec : Generated random vector + */ + +void WebRtcNetEQ_RandomVec(WebRtc_UWord32 *w32_seed, WebRtc_Word16 *pw16_randVec, + WebRtc_Word16 w16_len, WebRtc_Word16 w16_incval); + +/**************************************************************************** + * WebRtcNetEQ_MixVoiceUnvoice(...) + * + * Mix voiced and unvoiced signal. + * + * Input: + * - voicedVec : Voiced input signal + * - unvoicedVec : Unvoiced input signal + * - current_vfraction : Current mixing factor + * - vfraction_change : Mixing factor change per sample + * - N : Number of samples + * + * Output: + * - outData : Mixed signal + */ + +void WebRtcNetEQ_MixVoiceUnvoice(WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_voicedVec, + WebRtc_Word16 *pw16_unvoicedVec, + WebRtc_Word16 *w16_current_vfraction, + WebRtc_Word16 w16_vfraction_change, WebRtc_Word16 N); + +/**************************************************************************** + * WebRtcNetEQ_UnmuteSignal(...) + * + * Gradually reduce attenuation. + * + * Input: + * - inVec : Input signal + * - startMuteFact : Starting attenuation + * - unmuteFact : Factor to "unmute" with (Q20) + * - N : Number of samples + * + * Output: + * - outVec : Output signal + */ + +void WebRtcNetEQ_UnmuteSignal(WebRtc_Word16 *pw16_inVec, WebRtc_Word16 *startMuteFact, + WebRtc_Word16 *pw16_outVec, WebRtc_Word16 unmuteFact, + WebRtc_Word16 N); + +/**************************************************************************** + * WebRtcNetEQ_MuteSignal(...) + * + * Gradually increase attenuation. + * + * Input: + * - inout : Input/output signal + * - muteSlope : Slope of muting + * - N : Number of samples + */ + +void WebRtcNetEQ_MuteSignal(WebRtc_Word16 *pw16_inout, WebRtc_Word16 muteSlope, + WebRtc_Word16 N); + +/**************************************************************************** + * WebRtcNetEQ_CalcFsMult(...) + * + * Calculate the sample rate divided by 8000. + * + * Input: + * - fsHz : Sample rate in Hz in {8000, 16000, 32000, 48000}. + * + * Return value : fsHz/8000 for the valid values, 1 for other inputs + */ + +WebRtc_Word16 WebRtcNetEQ_CalcFsMult(WebRtc_UWord16 fsHz); + +/**************************************************************************** + * WebRtcNetEQ_DownSampleTo4kHz(...) + * + * Lowpass filter and downsample a signal to 4 kHz sample rate. + * + * Input: + * - in : Input signal samples. + * - inLen : Number of input samples. + * - inFsHz : Input sample rate in Hz. + * - outLen : Desired number of samples in decimated signal. + * - compensateDelay : If non-zero, compensate for the phase delay of + * of the anti-alias filter. + * + * Output: + * - out : Output signal samples. + * + * Return value : 0 - Ok + * -1 - Error + * + */ + +int WebRtcNetEQ_DownSampleTo4kHz(const WebRtc_Word16 *in, int inLen, WebRtc_UWord16 inFsHz, + WebRtc_Word16 *out, int outLen, int compensateDelay); + +#endif + diff --git a/src/libs/webrtc/neteq/dtmf_buffer.c b/src/libs/webrtc/neteq/dtmf_buffer.c new file mode 100644 index 00000000..f00f9c99 --- /dev/null +++ b/src/libs/webrtc/neteq/dtmf_buffer.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Implementation of packet buffer for DTMF messages. + */ + +#include "dtmf_buffer.h" + +#include "typedefs.h" /* to define endianness */ +#include "signal_processing_library.h" + +#include "neteq_error_codes.h" + + +#ifdef NETEQ_ATEVENT_DECODE + +WebRtc_Word16 WebRtcNetEQ_DtmfRemoveEvent(dtmf_inst_t *DTMFdec_inst) +{ + + int i; + for (i = 0; i < 3; i++) + { + DTMFdec_inst->EventQueue[i] = DTMFdec_inst->EventQueue[i + 1]; + DTMFdec_inst->EventQueueVolume[i] = DTMFdec_inst->EventQueueVolume[i + 1]; + DTMFdec_inst->EventQueueEnded[i] = DTMFdec_inst->EventQueueEnded[i + 1]; + DTMFdec_inst->EventQueueStartTime[i] = DTMFdec_inst->EventQueueStartTime[i + 1]; + DTMFdec_inst->EventQueueEndTime[i] = DTMFdec_inst->EventQueueEndTime[i + 1]; + } + DTMFdec_inst->EventBufferSize--; + DTMFdec_inst->EventQueue[3] = -1; + DTMFdec_inst->EventQueueVolume[3] = 0; + DTMFdec_inst->EventQueueEnded[3] = 0; + DTMFdec_inst->EventQueueStartTime[3] = 0; + DTMFdec_inst->EventQueueEndTime[3] = 0; + + return 0; +} + +WebRtc_Word16 WebRtcNetEQ_DtmfDecoderInit(dtmf_inst_t *DTMFdec_inst, WebRtc_UWord16 fs, + WebRtc_Word16 MaxPLCtime) +{ + int i; + if (((fs != 8000) && (fs != 16000) && (fs != 32000) && (fs != 48000)) || (MaxPLCtime < 0)) + { + return DTMF_DEC_PARAMETER_ERROR; + } + if (fs == 8000) + DTMFdec_inst->framelen = 80; + else if (fs == 16000) + DTMFdec_inst->framelen = 160; + else if (fs == 32000) + DTMFdec_inst->framelen = 320; + else + /* fs == 48000 */ + DTMFdec_inst->framelen = 480; + + DTMFdec_inst->MaxPLCtime = MaxPLCtime; + DTMFdec_inst->CurrentPLCtime = 0; + DTMFdec_inst->EventBufferSize = 0; + for (i = 0; i < 4; i++) + { + DTMFdec_inst->EventQueue[i] = -1; + DTMFdec_inst->EventQueueVolume[i] = 0; + DTMFdec_inst->EventQueueEnded[i] = 0; + DTMFdec_inst->EventQueueStartTime[i] = 0; + DTMFdec_inst->EventQueueEndTime[i] = 0; + } + return 0; +} + +WebRtc_Word16 WebRtcNetEQ_DtmfInsertEvent(dtmf_inst_t *DTMFdec_inst, + const WebRtc_Word16 *encoded, WebRtc_Word16 len, + WebRtc_UWord32 timeStamp) +{ + + int i; + WebRtc_Word16 value; + const WebRtc_Word16 *EventStart; + WebRtc_Word16 endEvent; + WebRtc_Word16 Volume; + WebRtc_Word16 Duration; + WebRtc_Word16 position = -1; + + /* Extract event */ + if (len == 4) + { + EventStart = encoded; +#ifdef WEBRTC_BIG_ENDIAN + value=((*EventStart)>>8); + endEvent=((*EventStart)&0x80)>>7; + Volume=((*EventStart)&0x3F); + Duration=EventStart[1]; +#else + value = ((*EventStart) & 0xFF); + endEvent = ((*EventStart) & 0x8000) >> 15; + Volume = ((*EventStart) & 0x3F00) >> 8; + Duration = (((((WebRtc_UWord16) EventStart[1]) >> 8) & 0xFF) + | (((WebRtc_UWord16) (EventStart[1] & 0xFF)) << 8)); +#endif + /* Only events between 0-15 are supported (DTMF tones) */ + if ((value < 0) || (value > 15)) + { + return 0; + } + + /* Discard all DTMF tones with really low volume (<-36dbm0) */ + if (Volume > 36) + { + return 0; + } + + /*Are there any unended events of the same type? */ + for (i = 0; i < DTMFdec_inst->EventBufferSize; i++) + { + /* Going through the whole queue even when we have found a match will + ensure that we add to the latest applicable event */ + if ((DTMFdec_inst->EventQueue[i] == value) && (!DTMFdec_inst->EventQueueEnded[i] + || endEvent)) position = i; + } + if (position > -1) + { + DTMFdec_inst->EventQueueVolume[position] = Volume; + if ((timeStamp + Duration) > DTMFdec_inst->EventQueueEndTime[position]) DTMFdec_inst->EventQueueEndTime[position] + = DTMFdec_inst->EventQueueStartTime[position] + Duration; + if (endEvent) DTMFdec_inst->EventQueueEnded[position] = 1; + } + else + { + if (DTMFdec_inst->EventBufferSize == MAX_DTMF_QUEUE_SIZE) + { /* Buffer full */ + /* Remove one event */ + DTMFdec_inst->EventBufferSize--; + } + /* Store data in the instance on a new position*/ + DTMFdec_inst->EventQueue[DTMFdec_inst->EventBufferSize] = value; + DTMFdec_inst->EventQueueVolume[DTMFdec_inst->EventBufferSize] = Volume; + DTMFdec_inst->EventQueueEnded[DTMFdec_inst->EventBufferSize] = endEvent; + DTMFdec_inst->EventQueueStartTime[DTMFdec_inst->EventBufferSize] = timeStamp; + DTMFdec_inst->EventQueueEndTime[DTMFdec_inst->EventBufferSize] = timeStamp + + Duration; + DTMFdec_inst->EventBufferSize++; + } + return 0; + } + return DTMF_INSERT_ERROR; +} + +WebRtc_Word16 WebRtcNetEQ_DtmfDecode(dtmf_inst_t *DTMFdec_inst, WebRtc_Word16 *event, + WebRtc_Word16 *volume, WebRtc_UWord32 currTimeStamp) +{ + + if (DTMFdec_inst->EventBufferSize < 1) return 0; /* No events to play */ + + /* We have events, is it time to play them? */ + if (currTimeStamp < DTMFdec_inst->EventQueueStartTime[0]) + { + /*No, just return zero */ + return 0; + } + + /* Continue on the event that is currently ongoing */ + *event = DTMFdec_inst->EventQueue[0]; + *volume = DTMFdec_inst->EventQueueVolume[0]; + + if (DTMFdec_inst->EventQueueEndTime[0] >= (currTimeStamp + DTMFdec_inst->framelen)) + { + + /* Still at least framLen to play */ + + DTMFdec_inst->CurrentPLCtime = 0; + if ((DTMFdec_inst->EventQueueEndTime[0] == (currTimeStamp + DTMFdec_inst->framelen)) + && (DTMFdec_inst->EventQueueEnded[0])) + { /* We are done */ + /*Remove the event from Queue*/ + WebRtcNetEQ_DtmfRemoveEvent(DTMFdec_inst); + } + return DTMFdec_inst->framelen; + + } + else + { + if ((DTMFdec_inst->EventQueueEnded[0]) || (DTMFdec_inst->EventQueue[1] > -1)) + { + /* + * Less than frameLen to play and end of event or already received next event. + * Give our a whole frame size of audio to simplify things. + */ + + /*Remove the event from Queue*/ + WebRtcNetEQ_DtmfRemoveEvent(DTMFdec_inst); + DTMFdec_inst->CurrentPLCtime = 0; + + return DTMFdec_inst->framelen; + + } + else + { + /* Less than frameLen to play and not end of event. */ + DTMFdec_inst->CurrentPLCtime = (WebRtc_Word16) (currTimeStamp + - DTMFdec_inst->EventQueueEndTime[0]); + + if ((DTMFdec_inst->CurrentPLCtime > DTMFdec_inst->MaxPLCtime) + || (DTMFdec_inst->CurrentPLCtime < -DTMFdec_inst->MaxPLCtime)) + { + /*Remove the event from queue*/ + WebRtcNetEQ_DtmfRemoveEvent(DTMFdec_inst); + DTMFdec_inst->CurrentPLCtime = 0; + } + + /* If we have a new event that it's time to play */ + if ((DTMFdec_inst->EventQueue[1] > -1) && (DTMFdec_inst->EventQueueStartTime[1] + >= (currTimeStamp + DTMFdec_inst->framelen))) + { + /*Remove the event from queue*/ + WebRtcNetEQ_DtmfRemoveEvent(DTMFdec_inst); + DTMFdec_inst->CurrentPLCtime = 0; + } + + return DTMFdec_inst->framelen; + } + } +} + +#endif diff --git a/src/libs/webrtc/neteq/dtmf_buffer.h b/src/libs/webrtc/neteq/dtmf_buffer.h new file mode 100644 index 00000000..e185411e --- /dev/null +++ b/src/libs/webrtc/neteq/dtmf_buffer.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Packet buffer for DTMF messages. + */ + +#ifndef DTMF_BUFFER_H +#define DTMF_BUFFER_H + +#include "typedefs.h" + +#include "neteq_defines.h" + +/* Include this code only if ATEVENT (DTMF) is defined in */ +#ifdef NETEQ_ATEVENT_DECODE + +#define MAX_DTMF_QUEUE_SIZE 4 + +typedef struct dtmf_inst_t_ +{ + WebRtc_Word16 MaxPLCtime; + WebRtc_Word16 CurrentPLCtime; + WebRtc_Word16 EventQueue[MAX_DTMF_QUEUE_SIZE]; + WebRtc_Word16 EventQueueVolume[MAX_DTMF_QUEUE_SIZE]; + WebRtc_Word16 EventQueueEnded[MAX_DTMF_QUEUE_SIZE]; + WebRtc_UWord32 EventQueueStartTime[MAX_DTMF_QUEUE_SIZE]; + WebRtc_UWord32 EventQueueEndTime[MAX_DTMF_QUEUE_SIZE]; + WebRtc_Word16 EventBufferSize; + WebRtc_Word16 framelen; +} dtmf_inst_t; + +/**************************************************************************** + * WebRtcNetEQ_DtmfDecoderInit(...) + * + * This function initializes a DTMF instance. + * + * Input: + * - DTMF_decinst_t : DTMF instance + * - fs : The sample rate used for the DTMF + * - MaxPLCtime : Maximum length for a PLC before zeros should be inserted + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcNetEQ_DtmfDecoderInit(dtmf_inst_t *DTMFdec_inst, WebRtc_UWord16 fs, + WebRtc_Word16 MaxPLCtime); + +/**************************************************************************** + * WebRtcNetEQ_DtmfInsertEvent(...) + * + * This function decodes a packet with DTMF frames. + * + * Input: + * - DTMFdec_inst : DTMF instance + * - encoded : Encoded DTMF frame(s) + * - len : Bytes in encoded vector + * + * + * Return value : 0 - Ok + * -1 - Error + */ + +WebRtc_Word16 WebRtcNetEQ_DtmfInsertEvent(dtmf_inst_t *DTMFdec_inst, + const WebRtc_Word16 *encoded, WebRtc_Word16 len, + WebRtc_UWord32 timeStamp); + +/**************************************************************************** + * WebRtcNetEQ_DtmfDecode(...) + * + * This function decodes a packet with DTMF frame(s). Output will be the + * event that should be played for next 10 ms. + * + * Input: + * - DTMFdec_inst : DTMF instance + * - currTimeStamp : The current playout timestamp + * + * Output: + * - event : Event number to be played + * - volume : Event volume to be played + * + * Return value : >0 - There is a event to be played + * 0 - No event to be played + * -1 - Error + */ + +WebRtc_Word16 WebRtcNetEQ_DtmfDecode(dtmf_inst_t *DTMFdec_inst, WebRtc_Word16 *event, + WebRtc_Word16 *volume, WebRtc_UWord32 currTimeStamp); + +#endif /* NETEQ_ATEVENT_DECODE */ + +#endif /* DTMF_BUFFER_H */ + diff --git a/src/libs/webrtc/neteq/dtmf_tonegen.c b/src/libs/webrtc/neteq/dtmf_tonegen.c new file mode 100644 index 00000000..a52f9bc6 --- /dev/null +++ b/src/libs/webrtc/neteq/dtmf_tonegen.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the DTMF tone generator and its parameters. + * + * A sinusoid is generated using the recursive oscillator model + * + * y[n] = sin(w*n + phi) = 2*cos(w) * y[n-1] - y[n-2] + * = a * y[n-1] - y[n-2] + * + * initialized with + * y[-2] = 0 + * y[-1] = sin(w) + * + * A DTMF signal is a combination of two sinusoids, depending + * on which event is sent (i.e, which key is pressed). The following + * table maps each key (event codes in parentheses) into two tones: + * + * 1209 Hz 1336 Hz 1477 Hz 1633 Hz + * 697 Hz 1 (ev. 1) 2 (ev. 2) 3 (ev. 3) A (ev. 12) + * 770 Hz 4 (ev. 4) 5 (ev. 5) 6 (ev. 6) B (ev. 13) + * 852 Hz 7 (ev. 7) 8 (ev. 8) 9 (ev. 9) C (ev. 14) + * 941 Hz * (ev. 10) 0 (ev. 0) # (ev. 11) D (ev. 15) + * + * The two tones are added to form the DTMF signal. + * + */ + +#include "dtmf_tonegen.h" + +#include "signal_processing_library.h" + +#include "neteq_error_codes.h" + +#ifdef NETEQ_ATEVENT_DECODE +/* Must compile NetEQ with DTMF support to enable the functionality */ + +/*******************/ +/* Constant tables */ +/*******************/ + +/* + * All tables corresponding to the oscillator model are organized so that + * the coefficients for a specific frequency is found in the same position + * in every table. The positions for the tones follow this layout: + * + * dummyVector[8] = + * { + * 697 Hz, 770 Hz, 852 Hz, 941 Hz, + * 1209 Hz, 1336 Hz, 1477 Hz, 1633 Hz + * }; + */ + +/* + * Tables for the constant a = 2*cos(w) = 2*cos(2*pi*f/fs) + * in the oscillator model, for 8, 16, 32 and 48 kHz sample rate. + * Table values in Q14. + */ + +const WebRtc_Word16 WebRtcNetEQ_dtfm_aTbl8Khz[8] = +{ + 27980, 26956, 25701, 24219, + 19073, 16325, 13085, 9315 +}; + +#ifdef NETEQ_WIDEBAND +const WebRtc_Word16 WebRtcNetEQ_dtfm_aTbl16Khz[8]= +{ + 31548, 31281, 30951, 30556, + 29144, 28361, 27409, 26258 +}; +#endif + +#ifdef NETEQ_32KHZ_WIDEBAND +const WebRtc_Word16 WebRtcNetEQ_dtfm_aTbl32Khz[8]= +{ + 32462, 32394, 32311, 32210, + 31849, 31647, 31400, 31098 +}; +#endif + +#ifdef NETEQ_48KHZ_WIDEBAND +const WebRtc_Word16 WebRtcNetEQ_dtfm_aTbl48Khz[8]= +{ + 32632, 32602, 32564, 32520, + 32359, 32268, 32157, 32022 +}; +#endif + +/* + * Initialization values y[-1] = sin(w) = sin(2*pi*f/fs), for 8, 16, 32 and 48 kHz sample rate. + * Table values in Q14. + */ + +const WebRtc_Word16 WebRtcNetEQ_dtfm_yInitTab8Khz[8] = +{ + 8528, 9315, 10163, 11036, + 13323, 14206,15021, 15708 +}; + +#ifdef NETEQ_WIDEBAND +const WebRtc_Word16 WebRtcNetEQ_dtfm_yInitTab16Khz[8]= +{ + 4429, 4879, 5380, 5918, + 7490, 8207, 8979, 9801 +}; +#endif + +#ifdef NETEQ_32KHZ_WIDEBAND +const WebRtc_Word16 WebRtcNetEQ_dtfm_yInitTab32Khz[8]= +{ + 2235, 2468, 2728, 3010, + 3853, 4249, 4685, 5164 +}; +#endif + +#ifdef NETEQ_48KHZ_WIDEBAND +const WebRtc_Word16 WebRtcNetEQ_dtfm_yInitTab48Khz[8]= +{ + 1493, 1649, 1823, 2013, + 2582, 2851, 3148, 3476 +}; +#endif + +/* Volume in dBm0 from 0 to -63, where 0 is the first table entry. + Everything below -36 is discarded, wherefore the table stops at -36. + Table entries are in Q14. + */ + +const WebRtc_Word16 WebRtcNetEQ_dtfm_dBm0[37] = { 16141, 14386, 12821, 11427, 10184, 9077, 8090, + 7210, 6426, 5727, 5104, 4549, 4054, 3614, + 3221, 2870, 2558, 2280, 2032, 1811, 1614, + 1439, 1282, 1143, 1018, 908, 809, 721, 643, + 573, 510, 455, 405, 361, 322, 287, 256 }; + +/**************************************************************************** + * WebRtcNetEQ_DTMFGenerate(...) + * + * Generate 10 ms DTMF signal according to input parameters. + * + * Input: + * - DTMFdecInst : DTMF instance + * - value : DTMF event number (0-15) + * - volume : Volume of generated signal (0-36) + * Volume is given in negative dBm0, i.e., volume == 0 + * means 0 dBm0 while volume == 36 mean -36 dBm0. + * - sampFreq : Sample rate in Hz + * + * Output: + * - signal : Pointer to vector where DTMF signal is stored; + * Vector must be at least sampFreq/100 samples long. + * - DTMFdecInst : Updated DTMF instance + * + * Return value : >0 - Number of samples written to signal + * : <0 - error + */ + +WebRtc_Word16 WebRtcNetEQ_DTMFGenerate(dtmf_tone_inst_t *DTMFdecInst, WebRtc_Word16 value, + WebRtc_Word16 volume, WebRtc_Word16 *signal, + WebRtc_UWord16 sampFreq, WebRtc_Word16 extFrameLen) +{ + const WebRtc_Word16 *aTbl; /* pointer to a-coefficient table */ + const WebRtc_Word16 *yInitTable; /* pointer to initialization value table */ + WebRtc_Word16 a1 = 0; /* a-coefficient for first tone (low tone) */ + WebRtc_Word16 a2 = 0; /* a-coefficient for second tone (high tone) */ + int i; + int frameLen; /* number of samples to generate */ + int lowIndex; + int highIndex; + WebRtc_Word32 tempVal; + WebRtc_Word16 tempValLow; + WebRtc_Word16 tempValHigh; + + /* Sanity check for volume */ + if ((volume < 0) || (volume > 36)) + { + return DTMF_DEC_PARAMETER_ERROR; + } + + /* Sanity check for extFrameLen */ + if (extFrameLen < -1) + { + return DTMF_DEC_PARAMETER_ERROR; + } + + /* Select oscillator coefficient tables based on sample rate */ + if (sampFreq == 8000) + { + aTbl = WebRtcNetEQ_dtfm_aTbl8Khz; + yInitTable = WebRtcNetEQ_dtfm_yInitTab8Khz; + frameLen = 80; +#ifdef NETEQ_WIDEBAND + } + else if (sampFreq == 16000) + { + aTbl = WebRtcNetEQ_dtfm_aTbl16Khz; + yInitTable = WebRtcNetEQ_dtfm_yInitTab16Khz; + frameLen = 160; +#endif +#ifdef NETEQ_32KHZ_WIDEBAND + } + else if (sampFreq == 32000) + { + aTbl = WebRtcNetEQ_dtfm_aTbl32Khz; + yInitTable = WebRtcNetEQ_dtfm_yInitTab32Khz; + frameLen = 320; +#endif +#ifdef NETEQ_48KHZ_WIDEBAND + } + else if (sampFreq == 48000) + { + aTbl = WebRtcNetEQ_dtfm_aTbl48Khz; + yInitTable = WebRtcNetEQ_dtfm_yInitTab48Khz; + frameLen = 480; +#endif + } + else + { + /* unsupported sample rate */ + return DTMF_GEN_UNKNOWN_SAMP_FREQ; + } + + if (extFrameLen >= 0) + { + frameLen = extFrameLen; + } + + /* select low frequency based on event value */ + switch (value) + { + case 1: + case 2: + case 3: + case 12: /* first row on keypad */ + { + lowIndex = 0; /* low frequency: 697 Hz */ + break; + } + case 4: + case 5: + case 6: + case 13: /* second row on keypad */ + { + lowIndex = 1; /* low frequency: 770 Hz */ + break; + } + case 7: + case 8: + case 9: + case 14: /* third row on keypad */ + { + lowIndex = 2; /* low frequency: 852 Hz */ + break; + } + case 0: + case 10: + case 11: + case 15: /* fourth row on keypad */ + { + lowIndex = 3; /* low frequency: 941 Hz */ + break; + } + default: + { + return DTMF_DEC_PARAMETER_ERROR; + } + } /* end switch */ + + /* select high frequency based on event value */ + switch (value) + { + case 1: + case 4: + case 7: + case 10: /* first column on keypad */ + { + highIndex = 4; /* high frequency: 1209 Hz */ + break; + } + case 2: + case 5: + case 8: + case 0: /* second column on keypad */ + { + highIndex = 5;/* high frequency: 1336 Hz */ + break; + } + case 3: + case 6: + case 9: + case 11: /* third column on keypad */ + { + highIndex = 6;/* high frequency: 1477 Hz */ + break; + } + case 12: + case 13: + case 14: + case 15: /* fourth column on keypad (special) */ + { + highIndex = 7;/* high frequency: 1633 Hz */ + break; + } + default: + { + return DTMF_DEC_PARAMETER_ERROR; + } + } /* end switch */ + + /* select coefficients based on results from switches above */ + a1 = aTbl[lowIndex]; /* coefficient for first (low) tone */ + a2 = aTbl[highIndex]; /* coefficient for second (high) tone */ + + if (DTMFdecInst->reinit) + { + /* set initial values for the recursive model */ + DTMFdecInst->oldOutputLow[0] = yInitTable[lowIndex]; + DTMFdecInst->oldOutputLow[1] = 0; + DTMFdecInst->oldOutputHigh[0] = yInitTable[highIndex]; + DTMFdecInst->oldOutputHigh[1] = 0; + + /* reset reinit flag */ + DTMFdecInst->reinit = 0; + } + + /* generate signal sample by sample */ + for (i = 0; i < frameLen; i++) + { + + /* Use rescursion formula y[n] = a*y[n-1] - y[n-2] */ + tempValLow + = (WebRtc_Word16) (((WEBRTC_SPL_MUL_16_16(a1, DTMFdecInst->oldOutputLow[1]) + + 8192) >> 14) - DTMFdecInst->oldOutputLow[0]); + tempValHigh + = (WebRtc_Word16) (((WEBRTC_SPL_MUL_16_16(a2, DTMFdecInst->oldOutputHigh[1]) + + 8192) >> 14) - DTMFdecInst->oldOutputHigh[0]); + + /* Update recursion memory */ + DTMFdecInst->oldOutputLow[0] = DTMFdecInst->oldOutputLow[1]; + DTMFdecInst->oldOutputLow[1] = tempValLow; + DTMFdecInst->oldOutputHigh[0] = DTMFdecInst->oldOutputHigh[1]; + DTMFdecInst->oldOutputHigh[1] = tempValHigh; + + /* scale high tone with 32768 (15 left shifts) + and low tone with 23171 (3dB lower than high tone) */ + tempVal = WEBRTC_SPL_MUL_16_16(DTMF_AMP_LOW, tempValLow) + + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tempValHigh, 15); + + /* Norm the signal to Q14 (with proper rounding) */ + tempVal = (tempVal + 16384) >> 15; + + /* Scale the signal to correct dbM0 value */ + signal[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32( + (WEBRTC_SPL_MUL_16_16(tempVal, WebRtcNetEQ_dtfm_dBm0[volume]) + + 8192), 14); /* volume value is in Q14; use proper rounding */ + } + + return frameLen; + +} + +#endif /* NETEQ_ATEVENT_DECODE */ + diff --git a/src/libs/webrtc/neteq/dtmf_tonegen.h b/src/libs/webrtc/neteq/dtmf_tonegen.h new file mode 100644 index 00000000..add6eb1d --- /dev/null +++ b/src/libs/webrtc/neteq/dtmf_tonegen.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the DTMF tone generator function. + */ + +#ifndef DTMF_TONEGEN_H +#define DTMF_TONEGEN_H + +#include "typedefs.h" + +#include "neteq_defines.h" + +#ifdef NETEQ_ATEVENT_DECODE +/* Must compile NetEQ with DTMF support to enable the functionality */ + +#define DTMF_AMP_LOW 23171 /* 3 dB lower than the high frequency */ + +/* The DTMF generator struct (part of DSP main struct DSPInst_t) */ +typedef struct dtmf_tone_inst_t_ +{ + + WebRtc_Word16 reinit; /* non-zero if the oscillator model should + be reinitialized for next event */ + WebRtc_Word16 oldOutputLow[2]; /* oscillator recursion history (low tone) */ + WebRtc_Word16 oldOutputHigh[2]; /* oscillator recursion history (high tone) */ + + int lastDtmfSample; /* index to the first non-DTMF sample in the + speech history, if non-negative */ +}dtmf_tone_inst_t; + +/**************************************************************************** + * WebRtcNetEQ_DTMFGenerate(...) + * + * Generate 10 ms DTMF signal according to input parameters. + * + * Input: + * - DTMFdecInst : DTMF instance + * - value : DTMF event number (0-15) + * - volume : Volume of generated signal (0-36) + * Volume is given in negative dBm0, i.e., volume == 0 + * means 0 dBm0 while volume == 36 mean -36 dBm0. + * - sampFreq : Sample rate in Hz + * + * Output: + * - signal : Pointer to vector where DTMF signal is stored; + * Vector must be at least sampFreq/100 samples long. + * - DTMFdecInst : Updated DTMF instance + * + * Return value : >0 - Number of samples written to signal + * : <0 - Error + */ + +WebRtc_Word16 WebRtcNetEQ_DTMFGenerate(dtmf_tone_inst_t *DTMFdecInst, + WebRtc_Word16 value, + WebRtc_Word16 volume, + WebRtc_Word16 *signal, + WebRtc_UWord16 sampFreq, + WebRtc_Word16 frameLen +); + +#endif /* NETEQ_ATEVENT_DECODE */ + +#endif /* DTMF_TONEGEN_H */ + diff --git a/src/libs/webrtc/neteq/expand.c b/src/libs/webrtc/neteq/expand.c new file mode 100644 index 00000000..2520f638 --- /dev/null +++ b/src/libs/webrtc/neteq/expand.c @@ -0,0 +1,1204 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This is the function to expand from the speech history, to produce concealment data or + * increasing delay. + */ + +#include "dsp.h" + +#include "signal_processing_library.h" + +#include "dsp_helpfunctions.h" +#include "neteq_error_codes.h" + +#define CHECK_NO_OF_CORRMAX 3 +#define DISTLEN 20 +#define LPCANALASYSLEN 160 + +/* Scratch usage: + + Type Name size startpos endpos + (First part of first expand) + WebRtc_Word16 pw16_bestCorrIndex 3 0 2 + WebRtc_Word16 pw16_bestCorr 3 3 5 + WebRtc_Word16 pw16_bestDistIndex 3 6 8 + WebRtc_Word16 pw16_bestDist 3 9 11 + WebRtc_Word16 pw16_corrVec 102*fs/8000 12 11+102*fs/8000 + func WebRtcNetEQ_Correlator 232 12+102*fs/8000 243+102*fs/8000 + + (Second part of first expand) + WebRtc_Word32 pw32_corr2 99*fs/8000+1 0 99*fs/8000 + WebRtc_Word32 pw32_autoCorr 2*7 0 13 + WebRtc_Word16 pw16_rc 6 14 19 + + Signal combination: + WebRtc_Word16 pw16_randVec 30+120*fs/8000 0 29+120*fs/8000 + WebRtc_Word16 pw16_scaledRandVec 125*fs/8000 30+120*fs/8000 29+245*fs/8000 + WebRtc_Word16 pw16_unvoicedVecSpace 10+125*fs/8000 30+245*fs/8000 39+370*fs/8000 + + Total: 40+370*fs/8000 (size depends on UNVOICED_LPC_ORDER and BGN_LPC_ORDER) + */ + +#if ((BGN_LPC_ORDER > 10) || (UNVOICED_LPC_ORDER > 10)) && (defined SCRATCH) +#error BGN_LPC_ORDER and/or BGN_LPC_ORDER are too large for current scratch memory allocation +#endif + +#define SCRATCH_PW16_BEST_CORR_INDEX 0 +#define SCRATCH_PW16_BEST_CORR 3 +#define SCRATCH_PW16_BEST_DIST_INDEX 6 +#define SCRATCH_PW16_BEST_DIST 9 +#define SCRATCH_PW16_CORR_VEC 12 +#define SCRATCH_PW16_CORR2 0 +#define SCRATCH_PW32_AUTO_CORR 0 +#define SCRATCH_PW16_RC 14 +#define SCRATCH_PW16_RAND_VEC 0 + +#if (defined(NETEQ_48KHZ_WIDEBAND)) +#define SCRATCH_NETEQDSP_CORRELATOR 624 +#define SCRATCH_PW16_SCALED_RAND_VEC 750 +#define SCRATCH_PW16_UNVOICED_VEC_SPACE 1500 +#elif (defined(NETEQ_32KHZ_WIDEBAND)) +#define SCRATCH_NETEQDSP_CORRELATOR 420 +#define SCRATCH_PW16_SCALED_RAND_VEC 510 +#define SCRATCH_PW16_UNVOICED_VEC_SPACE 1010 +#elif (defined(NETEQ_WIDEBAND)) +#define SCRATCH_NETEQDSP_CORRELATOR 216 +#define SCRATCH_PW16_SCALED_RAND_VEC 270 +#define SCRATCH_PW16_UNVOICED_VEC_SPACE 520 +#else /* NB */ +#define SCRATCH_NETEQDSP_CORRELATOR 114 +#define SCRATCH_PW16_SCALED_RAND_VEC 150 +#define SCRATCH_PW16_UNVOICED_VEC_SPACE 275 +#endif + +/**************************************************************************** + * WebRtcNetEQ_Expand(...) + * + * This function produces one "chunk" of expansion data (PLC audio). The + * length of the produced audio depends on the speech history. + * + * Input: + * - inst : DSP instance + * - scratchPtr : Pointer to scratch vector + * - outdata : Pointer to a memory space where the output data + * should be stored + * - BGNonly : If non-zero, "expand" will only produce background noise. + * - pw16_len : Desired number of samples (only for BGN mode). + * + * Output: + * - inst : Updated instance + * - pw16_len : Number of samples that were output from NetEq + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_Expand(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_len, + WebRtc_Word16 BGNonly) +{ + + WebRtc_Word16 fs_mult; + ExpandInst_t *ExpandState = &(inst->ExpandInst); + BGNInst_t *BGNState = &(inst->BGNInst); + int i; +#ifdef SCRATCH + WebRtc_Word16 *pw16_randVec = pw16_scratchPtr + SCRATCH_PW16_RAND_VEC; + WebRtc_Word16 *pw16_scaledRandVec = pw16_scratchPtr + SCRATCH_PW16_SCALED_RAND_VEC; + WebRtc_Word16 *pw16_unvoicedVecSpace = pw16_scratchPtr + SCRATCH_PW16_UNVOICED_VEC_SPACE; +#else + WebRtc_Word16 pw16_randVec[FSMULT * 120 + 30]; /* 125 for NB and 250 for WB */ + WebRtc_Word16 pw16_scaledRandVec[FSMULT * 125]; /* 125 for NB and 250 for WB */ + WebRtc_Word16 pw16_unvoicedVecSpace[BGN_LPC_ORDER + FSMULT * 125]; +#endif + /* 125 for NB and 250 for WB etc. Reuse pw16_outData[] for this vector */ + WebRtc_Word16 *pw16_voicedVecStorage = pw16_outData; + WebRtc_Word16 *pw16_voicedVec = &pw16_voicedVecStorage[ExpandState->w16_overlap]; + WebRtc_Word16 *pw16_unvoicedVec = pw16_unvoicedVecSpace + UNVOICED_LPC_ORDER; + WebRtc_Word16 *pw16_cngVec = pw16_unvoicedVecSpace + BGN_LPC_ORDER; + WebRtc_Word16 w16_expVecsLen, w16_lag = 0, w16_expVecPos; + WebRtc_Word16 w16_randLen; + WebRtc_Word16 w16_vfractionChange; /* in Q14 */ + WebRtc_Word16 w16_winMute = 0, w16_winMuteInc = 0, w16_winUnMute = 0, w16_winUnMuteInc = 0; + WebRtc_Word32 w32_tmp; + WebRtc_Word16 w16_tmp, w16_tmp2; + WebRtc_Word16 stability; + enum BGNMode bgnMode = inst->BGNInst.bgnMode; + + /* Pre-calculate common multiplications with fs_mult */ + WebRtc_Word16 fsMult4; + WebRtc_Word16 fsMult20; + WebRtc_Word16 fsMult120; + WebRtc_Word16 fsMultDistLen; + WebRtc_Word16 fsMultLPCAnalasysLen; + +#ifdef NETEQ_STEREO + MasterSlaveInfo *msInfo = inst->msInfo; +#endif + + /* fs is WebRtc_UWord16 (to hold fs=48000) */ + fs_mult = WebRtcNetEQ_CalcFsMult(inst->fs); /* calculate fs/8000 */ + + /* Pre-calculate common multiplications with fs_mult */ + fsMult4 = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16(fs_mult, 4); + fsMult20 = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16(fs_mult, 20); + fsMult120 = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16(fs_mult, 120); + fsMultDistLen = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16(fs_mult, DISTLEN); + fsMultLPCAnalasysLen = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16(fs_mult, LPCANALASYSLEN); + + /* + * Perform all the initial setup if it's the first expansion. + * If background noise (BGN) only, this setup is not needed. + */ + if (ExpandState->w16_consecExp == 0 && !BGNonly) + { + /* Setup more variables */ +#ifdef SCRATCH + WebRtc_Word32 *pw32_autoCorr = (WebRtc_Word32*) (pw16_scratchPtr + + SCRATCH_PW32_AUTO_CORR); + WebRtc_Word16 *pw16_rc = pw16_scratchPtr + SCRATCH_PW16_RC; + WebRtc_Word16 *pw16_bestCorrIndex = pw16_scratchPtr + SCRATCH_PW16_BEST_CORR_INDEX; + WebRtc_Word16 *pw16_bestCorr = pw16_scratchPtr + SCRATCH_PW16_BEST_CORR; + WebRtc_Word16 *pw16_bestDistIndex = pw16_scratchPtr + SCRATCH_PW16_BEST_DIST_INDEX; + WebRtc_Word16 *pw16_bestDist = pw16_scratchPtr + SCRATCH_PW16_BEST_DIST; + WebRtc_Word16 *pw16_corrVec = pw16_scratchPtr + SCRATCH_PW16_CORR_VEC; + WebRtc_Word32 *pw32_corr2 = (WebRtc_Word32*) (pw16_scratchPtr + SCRATCH_PW16_CORR2); +#else + WebRtc_Word32 pw32_autoCorr[UNVOICED_LPC_ORDER+1]; + WebRtc_Word16 pw16_rc[UNVOICED_LPC_ORDER]; + WebRtc_Word16 pw16_corrVec[FSMULT*102]; /* 102 for NB */ + WebRtc_Word16 pw16_bestCorrIndex[CHECK_NO_OF_CORRMAX]; + WebRtc_Word16 pw16_bestCorr[CHECK_NO_OF_CORRMAX]; + WebRtc_Word16 pw16_bestDistIndex[CHECK_NO_OF_CORRMAX]; + WebRtc_Word16 pw16_bestDist[CHECK_NO_OF_CORRMAX]; + WebRtc_Word32 pw32_corr2[(99*FSMULT)+1]; +#endif + WebRtc_Word32 pw32_bestDist[CHECK_NO_OF_CORRMAX]; + WebRtc_Word16 w16_ind = 0; + WebRtc_Word16 w16_corrVecLen; + WebRtc_Word16 w16_corrScale; + WebRtc_Word16 w16_distScale; + WebRtc_Word16 w16_indMin, w16_indMax; + WebRtc_Word16 w16_len; + WebRtc_Word32 w32_en1, w32_en2, w32_cc; + WebRtc_Word16 w16_en1Scale, w16_en2Scale; + WebRtc_Word16 w16_en1, w16_en2; + WebRtc_Word32 w32_en1_mul_en2; + WebRtc_Word16 w16_sqrt_en1en2; + WebRtc_Word16 w16_ccShiftL; + WebRtc_Word16 w16_bestcorr; /* Correlation in Q14 */ + WebRtc_Word16 *pw16_vec1, *pw16_vec2; + WebRtc_Word16 w16_factor; + WebRtc_Word16 w16_DistLag, w16_CorrLag, w16_diffLag; + WebRtc_Word16 w16_energyLen; + WebRtc_Word16 w16_slope; + WebRtc_Word16 w16_startInd; + WebRtc_Word16 w16_noOfcorr2; + WebRtc_Word16 w16_scale; + + /* Initialize some variables */ + ExpandState->w16_lagsDirection = 1; + ExpandState->w16_lagsPosition = -1; + ExpandState->w16_expandMuteFactor = 16384; /* Start from 1.0 (Q14) */ + BGNState->w16_mutefactor = 0; /* Start with 0 gain for BGN (value in Q14) */ + inst->w16_seedInc = 1; + +#ifdef NETEQ_STEREO + /* Sanity for msInfo */ + if (msInfo == NULL) + { + /* this should not happen here */ + return MASTER_SLAVE_ERROR; + } + + /* + * Do not calculate correlations for slave instance(s) + * unless lag info from master is corrupt + */ + if ((msInfo->msMode != NETEQ_SLAVE) + || ((msInfo->distLag <= 0) || (msInfo->corrLag <= 0))) + { +#endif + /* Calculate correlation vector in downsampled domain (4 kHz sample rate) */ + w16_corrVecLen = WebRtcNetEQ_Correlator(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQDSP_CORRELATOR, +#endif + inst->pw16_speechHistory, inst->w16_speechHistoryLen, pw16_corrVec, + &w16_corrScale); + + /* Find peaks in correlation vector using parabolic fit method */ + WebRtcNetEQ_PeakDetection(pw16_corrVec, w16_corrVecLen, CHECK_NO_OF_CORRMAX, fs_mult, + pw16_bestCorrIndex, pw16_bestCorr); + + /* + * Adjust peak locations; cross-correlation lags start at 2.5 ms + * (20*fs_mult samples) + */ + pw16_bestCorrIndex[0] += fsMult20; + pw16_bestCorrIndex[1] += fsMult20; + pw16_bestCorrIndex[2] += fsMult20; + + /* Calculate distortion around the 3 (CHECK_NO_OF_CORRMAX) best lags */ + w16_distScale = 0; + for (i = 0; i < CHECK_NO_OF_CORRMAX; i++) + { + w16_tmp = fsMult20; + w16_tmp2 = pw16_bestCorrIndex[i] - fsMult4; + w16_indMin = WEBRTC_SPL_MAX(w16_tmp, w16_tmp2); + w16_tmp = fsMult120 - 1; + w16_tmp2 = pw16_bestCorrIndex[i] + fsMult4; + w16_indMax = WEBRTC_SPL_MIN(w16_tmp, w16_tmp2); + + pw16_bestDistIndex[i] = WebRtcNetEQ_MinDistortion( + &(inst->pw16_speechHistory[inst->w16_speechHistoryLen - fsMultDistLen]), + w16_indMin, w16_indMax, fsMultDistLen, &pw32_bestDist[i]); + + w16_distScale + = WEBRTC_SPL_MAX(16 - WebRtcSpl_NormW32(pw32_bestDist[i]), w16_distScale); + + } + + /* Shift the distortion values to fit in WebRtc_Word16 */ + WebRtcSpl_VectorBitShiftW32ToW16(pw16_bestDist, CHECK_NO_OF_CORRMAX, pw32_bestDist, + w16_distScale); + + /* + * Find index of maximum criteria, where crit[i] = bestCorr[i])/(bestDist[i]) + * Do this by a cross multiplication. + */ + + w32_en1 = WEBRTC_SPL_MUL_16_16((WebRtc_Word32) pw16_bestCorr[0],pw16_bestDist[1]); + w32_en2 = WEBRTC_SPL_MUL_16_16((WebRtc_Word32) pw16_bestCorr[1],pw16_bestDist[0]); + if (w32_en1 >= w32_en2) + { + /* 0 wins over 1 */ + w32_en1 + = WEBRTC_SPL_MUL_16_16((WebRtc_Word32) pw16_bestCorr[0], pw16_bestDist[2]); + w32_en2 + = WEBRTC_SPL_MUL_16_16((WebRtc_Word32) pw16_bestCorr[2], pw16_bestDist[0]); + if (w32_en1 >= w32_en2) + { + /* 0 wins over 2 */ + w16_ind = 0; + } + else + { + /* 2 wins over 0 */ + w16_ind = 2; + } + } + else + { + /* 1 wins over 0 */ + w32_en1 + = WEBRTC_SPL_MUL_16_16((WebRtc_Word32) pw16_bestCorr[1],pw16_bestDist[2]); + w32_en2 + = WEBRTC_SPL_MUL_16_16((WebRtc_Word32) pw16_bestCorr[2],pw16_bestDist[1]); + if ((WebRtc_Word32) w32_en1 >= (WebRtc_Word32) w32_en2) + { + /* 1 wins over 2 */ + w16_ind = 1; + } + else + { + /* 2 wins over 1 */ + w16_ind = 2; + } + } + +#ifdef NETEQ_STEREO + } + + /* Store DistLag and CorrLag of the position with highest criteria */ + if ((msInfo->msMode == NETEQ_MASTER) || (msInfo->msMode == NETEQ_MONO) + || ((msInfo->msMode == NETEQ_SLAVE) && (msInfo->distLag <= 0 || msInfo->corrLag + <= 0))) + { + /* lags not provided externally */ + w16_DistLag = pw16_bestDistIndex[w16_ind]; + w16_CorrLag = pw16_bestCorrIndex[w16_ind]; + if (msInfo->msMode == NETEQ_MASTER) + { + msInfo->distLag = w16_DistLag; + msInfo->corrLag = w16_CorrLag; + } + } + else if (msInfo->msMode == NETEQ_SLAVE) + { + /* lags provided externally (from master) */ + w16_DistLag = msInfo->distLag; + w16_CorrLag = msInfo->corrLag; + + /* sanity for lag values */ + if ((w16_DistLag <= 0) || (w16_CorrLag <= 0)) + { + return MASTER_SLAVE_ERROR; + } + } + else + { + /* Invalid mode */ + return MASTER_SLAVE_ERROR; + } +#else /* not NETEQ_STEREO */ + w16_DistLag = pw16_bestDistIndex[w16_ind]; + w16_CorrLag = pw16_bestCorrIndex[w16_ind]; +#endif + + ExpandState->w16_maxLag = WEBRTC_SPL_MAX(w16_DistLag, w16_CorrLag); + + /* Calculate the exact best correlation (in the range within CorrLag-DistLag) */ + w16_len = w16_DistLag + 10; + w16_len = WEBRTC_SPL_MIN(w16_len, fsMult120); + w16_len = WEBRTC_SPL_MAX(w16_len, 60 * fs_mult); + + w16_startInd = WEBRTC_SPL_MIN(w16_DistLag, w16_CorrLag); + w16_noOfcorr2 = WEBRTC_SPL_ABS_W16((w16_DistLag-w16_CorrLag)) + 1; + /* w16_noOfcorr2 maximum value is 99*fs_mult + 1 */ + + /* Calculate suitable scaling */ + w16_tmp + = WebRtcSpl_MaxAbsValueW16( + &inst->pw16_speechHistory[inst->w16_speechHistoryLen - w16_len - w16_startInd + - w16_noOfcorr2], + (WebRtc_Word16) (w16_len + w16_startInd + w16_noOfcorr2 - 1)); + w16_corrScale = ((31 - WebRtcSpl_NormW32(WEBRTC_SPL_MUL_16_16(w16_tmp, w16_tmp))) + + (31 - WebRtcSpl_NormW32(w16_len))) - 31; + w16_corrScale = WEBRTC_SPL_MAX(0, w16_corrScale); + + /* + * Perform the correlation, store in pw32_corr2 + */ + + WebRtcNetEQ_CrossCorr(pw32_corr2, + &(inst->pw16_speechHistory[inst->w16_speechHistoryLen - w16_len]), + &(inst->pw16_speechHistory[inst->w16_speechHistoryLen - w16_len - w16_startInd]), + w16_len, w16_noOfcorr2, w16_corrScale, -1); + + /* Find maximizing index */ + w16_ind = WebRtcSpl_MaxIndexW32(pw32_corr2, w16_noOfcorr2); + w32_cc = pw32_corr2[w16_ind]; /* this is maximum correlation */ + w16_ind = w16_ind + w16_startInd; /* correct index for start offset */ + + /* Calculate energies */ + w32_en1 = WebRtcNetEQ_DotW16W16( + &(inst->pw16_speechHistory[inst->w16_speechHistoryLen - w16_len]), + &(inst->pw16_speechHistory[inst->w16_speechHistoryLen - w16_len]), w16_len, + w16_corrScale); + w32_en2 = WebRtcNetEQ_DotW16W16( + &(inst->pw16_speechHistory[inst->w16_speechHistoryLen - w16_len - w16_ind]), + &(inst->pw16_speechHistory[inst->w16_speechHistoryLen - w16_len - w16_ind]), + w16_len, w16_corrScale); + + /* Calculate the correlation value w16_bestcorr */ + if ((w32_en1 > 0) && (w32_en2 > 0)) + { + w16_en1Scale = 16 - WebRtcSpl_NormW32(w32_en1); + w16_en1Scale = WEBRTC_SPL_MAX(0, w16_en1Scale); + w16_en2Scale = 16 - WebRtcSpl_NormW32(w32_en2); + w16_en2Scale = WEBRTC_SPL_MAX(0, w16_en2Scale); + /* Make sure total scaling is even (to simplify scale factor after sqrt) */ + if ((w16_en1Scale + w16_en2Scale) & 1) + { + /* if sum is odd */ + w16_en1Scale += 1; + } + w16_en1 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(w32_en1, w16_en1Scale); + w16_en2 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(w32_en2, w16_en2Scale); + w32_en1_mul_en2 = WEBRTC_SPL_MUL_16_16(w16_en1, w16_en2); + w16_sqrt_en1en2 = (WebRtc_Word16) WebRtcSpl_Sqrt(w32_en1_mul_en2); + + /* Calculate cc/sqrt(en1*en2) in Q14 */ + w16_ccShiftL = 14 - ((w16_en1Scale + w16_en2Scale) >> 1); + w32_cc = WEBRTC_SPL_SHIFT_W32(w32_cc, w16_ccShiftL); + w16_bestcorr = (WebRtc_Word16) WebRtcSpl_DivW32W16(w32_cc, w16_sqrt_en1en2); + w16_bestcorr = WEBRTC_SPL_MIN(16384, w16_bestcorr); /* set maximum to 1.0 */ + + } + else + { + /* if either en1 or en2 is zero */ + w16_bestcorr = 0; + } + + /* + * Extract the two vectors, pw16_expVecs[0][] and pw16_expVecs[1][], + * from the SpeechHistory[] + */ + w16_expVecsLen = ExpandState->w16_maxLag + ExpandState->w16_overlap; + pw16_vec1 = &(inst->pw16_speechHistory[inst->w16_speechHistoryLen - w16_expVecsLen]); + pw16_vec2 = pw16_vec1 - w16_DistLag; + /* Normalize the second vector to the same energy as the first */ + w32_en1 = WebRtcNetEQ_DotW16W16(pw16_vec1, pw16_vec1, w16_expVecsLen, w16_corrScale); + w32_en2 = WebRtcNetEQ_DotW16W16(pw16_vec2, pw16_vec2, w16_expVecsLen, w16_corrScale); + + /* + * Confirm that energy factor sqrt(w32_en1/w32_en2) is within difference 0.5 - 2.0 + * w32_en1/w32_en2 within 0.25 - 4 + */ + if (((w32_en1 >> 2) < w32_en2) && ((w32_en1) > (w32_en2 >> 2))) + { + + /* Energy constraint fulfilled => use both vectors and scale them accordingly */ + w16_en2Scale = 16 - WebRtcSpl_NormW32(w32_en2); + w16_en2Scale = WEBRTC_SPL_MAX(0, w16_en2Scale); + w16_en1Scale = w16_en2Scale - 13; + + /* calculate w32_en1/w32_en2 in Q13 */ + w32_en1_mul_en2 = WebRtcSpl_DivW32W16( + WEBRTC_SPL_SHIFT_W32(w32_en1, -w16_en1Scale), + (WebRtc_Word16) (WEBRTC_SPL_RSHIFT_W32(w32_en2, w16_en2Scale))); + + /* calculate factor in Q13 (sqrt of en1/en2 in Q26) */ + w16_factor = (WebRtc_Word16) WebRtcSpl_Sqrt( + WEBRTC_SPL_LSHIFT_W32(w32_en1_mul_en2, 13)); + + /* Copy the two vectors and give them the same energy */ + + WEBRTC_SPL_MEMCPY_W16(ExpandState->pw16_expVecs[0], pw16_vec1, w16_expVecsLen); + WebRtcSpl_AffineTransformVector(ExpandState->pw16_expVecs[1], pw16_vec2, + w16_factor, 4096, 13, w16_expVecsLen); + + } + else + { + /* Energy change constraint not fulfilled => only use last vector */ + + WEBRTC_SPL_MEMCPY_W16(ExpandState->pw16_expVecs[0], pw16_vec1, w16_expVecsLen); + WEBRTC_SPL_MEMCPY_W16(ExpandState->pw16_expVecs[1], ExpandState->pw16_expVecs[0], + w16_expVecsLen); + + /* Set the w16_factor since it is used by muting slope */ + if (((w32_en1 >> 2) < w32_en2) || (w32_en2 == 0)) + { + w16_factor = 4096; /* 0.5 in Q13*/ + } + else + { + w16_factor = 16384; /* 2.0 in Q13*/ + } + } + + /* Set the 3 lag values */ + w16_diffLag = w16_DistLag - w16_CorrLag; + if (w16_diffLag == 0) + { + /* DistLag and CorrLag are equal */ + ExpandState->w16_lags[0] = w16_DistLag; + ExpandState->w16_lags[1] = w16_DistLag; + ExpandState->w16_lags[2] = w16_DistLag; + } + else + { + /* DistLag and CorrLag are not equal; use different combinations of the two */ + ExpandState->w16_lags[0] = w16_DistLag; /* DistLag only */ + ExpandState->w16_lags[1] = ((w16_DistLag + w16_CorrLag) >> 1); /* 50/50 */ + /* Third lag, move one half-step towards CorrLag (in both cases) */ + if (w16_diffLag > 0) + { + ExpandState->w16_lags[2] = (w16_DistLag + w16_CorrLag - 1) >> 1; + } + else + { + ExpandState->w16_lags[2] = (w16_DistLag + w16_CorrLag + 1) >> 1; + } + } + + /************************************************* + * Calculate the LPC and the gain of the filters * + *************************************************/ + + /* Calculate scale value needed for autocorrelation */ + w16_tmp = WebRtcSpl_MaxAbsValueW16( + &(inst->pw16_speechHistory[inst->w16_speechHistoryLen - fsMultLPCAnalasysLen]), + fsMultLPCAnalasysLen); + + w16_tmp = 16 - WebRtcSpl_NormW32(w16_tmp); + w16_tmp = WEBRTC_SPL_MIN(w16_tmp,0); + w16_tmp = (w16_tmp << 1) + 7; + w16_tmp = WEBRTC_SPL_MAX(w16_tmp,0); + + /* set w16_ind to simplify the following expressions */ + w16_ind = inst->w16_speechHistoryLen - fsMultLPCAnalasysLen - UNVOICED_LPC_ORDER; + + /* store first UNVOICED_LPC_ORDER samples in pw16_rc */ + + WEBRTC_SPL_MEMCPY_W16(pw16_rc, &inst->pw16_speechHistory[w16_ind], UNVOICED_LPC_ORDER); + + /* set first samples to zero */ + WebRtcSpl_MemSetW16(&inst->pw16_speechHistory[w16_ind], 0, UNVOICED_LPC_ORDER); + + /* Calculate UNVOICED_LPC_ORDER+1 lags of the ACF */ + + WebRtcNetEQ_CrossCorr( + pw32_autoCorr, &(inst->pw16_speechHistory[w16_ind + UNVOICED_LPC_ORDER]), + &(inst->pw16_speechHistory[w16_ind + UNVOICED_LPC_ORDER]), fsMultLPCAnalasysLen, + UNVOICED_LPC_ORDER + 1, w16_tmp, -1); + + /* Recover the stored samples from pw16_rc */ + + WEBRTC_SPL_MEMCPY_W16(&inst->pw16_speechHistory[w16_ind], pw16_rc, UNVOICED_LPC_ORDER); + + if (pw32_autoCorr[0] > 0) + { /* check that variance is positive */ + + /* estimate AR filter parameters using Levinson-Durbin algorithm + (UNVOICED_LPC_ORDER+1 filter coefficients) */ + stability = WebRtcSpl_LevinsonDurbin(pw32_autoCorr, ExpandState->pw16_arFilter, + pw16_rc, UNVOICED_LPC_ORDER); + + /* Only update BGN if filter is stable */ + if (stability != 1) + { + /* Set first coefficient to 4096 (1.0 in Q12)*/ + ExpandState->pw16_arFilter[0] = 4096; + /* Set remaining UNVOICED_LPC_ORDER coefficients to zero */ + WebRtcSpl_MemSetW16(ExpandState->pw16_arFilter + 1, 0, UNVOICED_LPC_ORDER); + } + + } + + if (w16_DistLag < 40) + { + w16_energyLen = 2 * w16_DistLag; + } + else + { + w16_energyLen = w16_DistLag; + } + w16_randLen = w16_energyLen + 30; /* Startup part */ + + /* Extract a noise segment */ + if (w16_randLen <= RANDVEC_NO_OF_SAMPLES) + { + WEBRTC_SPL_MEMCPY_W16(pw16_randVec, + (WebRtc_Word16*) WebRtcNetEQ_kRandnTbl, w16_randLen); + } + else + { /* only applies to SWB where length could be larger than 256 */ + WEBRTC_SPL_MEMCPY_W16(pw16_randVec, (WebRtc_Word16*) WebRtcNetEQ_kRandnTbl, + RANDVEC_NO_OF_SAMPLES); + inst->w16_seedInc = (inst->w16_seedInc + 2) & (RANDVEC_NO_OF_SAMPLES - 1); + WebRtcNetEQ_RandomVec(&inst->uw16_seed, &pw16_randVec[RANDVEC_NO_OF_SAMPLES], + (WebRtc_Word16) (w16_randLen - RANDVEC_NO_OF_SAMPLES), inst->w16_seedInc); + } + + /* Set up state vector and calculate scale factor for unvoiced filtering */ + + WEBRTC_SPL_MEMCPY_W16(ExpandState->pw16_arState, + &(inst->pw16_speechHistory[inst->w16_speechHistoryLen - UNVOICED_LPC_ORDER]), + UNVOICED_LPC_ORDER); + WEBRTC_SPL_MEMCPY_W16(pw16_unvoicedVec - UNVOICED_LPC_ORDER, + &(inst->pw16_speechHistory[inst->w16_speechHistoryLen - 128 - UNVOICED_LPC_ORDER]), + UNVOICED_LPC_ORDER); + WebRtcSpl_FilterMAFastQ12(&inst->pw16_speechHistory[inst->w16_speechHistoryLen - 128], + pw16_unvoicedVec, ExpandState->pw16_arFilter, UNVOICED_LPC_ORDER + 1, 128); + if (WebRtcSpl_MaxAbsValueW16(pw16_unvoicedVec, 128) > 4000) + { + w16_scale = 4; + } + else + { + w16_scale = 0; + } + w32_tmp = WebRtcNetEQ_DotW16W16(pw16_unvoicedVec, pw16_unvoicedVec, 128, w16_scale); + + /* Normalize w32_tmp to 28 or 29 bits to preserve sqrt() accuracy */ + w16_tmp = WebRtcSpl_NormW32(w32_tmp) - 3; + w16_tmp += ((w16_tmp & 0x1) ^ 0x1); /* Make sure we do an odd number of shifts since we + from earlier have 7 shifts from dividing with 128.*/ + w32_tmp = WEBRTC_SPL_SHIFT_W32(w32_tmp, w16_tmp); + w32_tmp = WebRtcSpl_Sqrt(w32_tmp); + ExpandState->w16_arGainScale = 13 + ((w16_tmp + 7 - w16_scale) >> 1); + ExpandState->w16_arGain = (WebRtc_Word16) w32_tmp; + + /******************************************************************** + * Calculate vfraction from bestcorr * + * if (bestcorr>0.480665) * + * vfraction = ((bestcorr-0.4)/(1-0.4)).^2 * + * else vfraction = 0 * + * * + * approximation (coefficients in Q12): * + * if (x>0.480665) (y(x)<0.3) * + * y(x) = -1.264421 + 4.8659148*x - 4.0092827*x^2 + 1.4100529*x^3 * + * else y(x) = 0; * + ********************************************************************/ + + if (w16_bestcorr > 7875) + { + /* if x>0.480665 */ + WebRtc_Word16 w16_x1, w16_x2, w16_x3; + w16_x1 = w16_bestcorr; + w32_tmp = WEBRTC_SPL_MUL_16_16((WebRtc_Word32) w16_x1, w16_x1); + w16_x2 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(w32_tmp, 14); + w32_tmp = WEBRTC_SPL_MUL_16_16(w16_x1, w16_x2); + w16_x3 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(w32_tmp, 14); + w32_tmp + = (WebRtc_Word32) WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) WebRtcNetEQ_kMixFractionFuncTbl[0], 14); + w32_tmp + += (WebRtc_Word32) WEBRTC_SPL_MUL_16_16(WebRtcNetEQ_kMixFractionFuncTbl[1], w16_x1); + w32_tmp + += (WebRtc_Word32) WEBRTC_SPL_MUL_16_16(WebRtcNetEQ_kMixFractionFuncTbl[2], w16_x2); + w32_tmp + += (WebRtc_Word32) WEBRTC_SPL_MUL_16_16(WebRtcNetEQ_kMixFractionFuncTbl[3], w16_x3); + ExpandState->w16_vFraction = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(w32_tmp, 12); + ExpandState->w16_vFraction = WEBRTC_SPL_MIN(ExpandState->w16_vFraction, 16384); + ExpandState->w16_vFraction = WEBRTC_SPL_MAX(ExpandState->w16_vFraction, 0); + } + else + { + ExpandState->w16_vFraction = 0; + } + + /*********************************************************************** + * Calculate muting slope, reuse value from earlier scaling of ExpVecs * + ***********************************************************************/ + w16_slope = w16_factor; + + if (w16_slope > 12288) + { + /* w16_slope > 1.5 ? */ + /* Calculate (1-(1/slope))/w16_DistLag = (slope-1)/(w16_DistLag*slope) */ + w32_tmp = w16_slope - 8192; + w32_tmp = WEBRTC_SPL_LSHIFT_W32(w32_tmp, 12); /* Value in Q25 (13+12=25) */ + w16_tmp = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(w16_DistLag, + w16_slope, 8); /* Value in Q5 (13-8=5) */ + w16_tmp = (WebRtc_Word16) WebRtcSpl_DivW32W16(w32_tmp, + w16_tmp); /* Res in Q20 (25-5=20) */ + + if (w16_slope > 14746) + { /* w16_slope > 1.8 ? */ + ExpandState->w16_muteSlope = (w16_tmp + 1) >> 1; + } + else + { + ExpandState->w16_muteSlope = (w16_tmp + 4) >> 3; + } + ExpandState->w16_onset = 1; + } + else if (ExpandState->w16_vFraction > 13107) + { + /* w16_vFraction > 0.8 ? */ + if (w16_slope > 8028) + { + /* w16_vFraction > 0.98 ? */ + ExpandState->w16_muteSlope = 0; + } + else + { + /* Calculate (1-slope)/w16_DistLag */ + w32_tmp = 8192 - w16_slope; + w32_tmp = WEBRTC_SPL_LSHIFT_W32(w32_tmp, 7); /* Value in Q20 (13+7=20) */ + ExpandState->w16_muteSlope = (WebRtc_Word16) WebRtcSpl_DivW32W16(w32_tmp, + w16_DistLag); /* Res in Q20 (20-0=20) */ + } + ExpandState->w16_onset = 0; + } + else + { + /* + * Use the minimum of 0.005 (0.9 on 50 samples in NB and the slope) + * and ((1-slope)/w16_DistLag) + */ + w32_tmp = 8192 - w16_slope; + w32_tmp = WEBRTC_SPL_LSHIFT_W32(w32_tmp, 7); /* Value in Q20 (13+7=20) */ + w32_tmp = WEBRTC_SPL_MAX(w32_tmp, 0); + ExpandState->w16_muteSlope = (WebRtc_Word16) WebRtcSpl_DivW32W16(w32_tmp, + w16_DistLag); /* Res in Q20 (20-0=20) */ + w16_tmp = WebRtcNetEQ_k5243div[fs_mult]; /* 0.005/fs_mult = 5243/fs_mult */ + ExpandState->w16_muteSlope = WEBRTC_SPL_MAX(w16_tmp, ExpandState->w16_muteSlope); + ExpandState->w16_onset = 0; + } + } + else + { + /* This is not the first Expansion, parameters are already estimated. */ + + /* Extract a noise segment */ + if (BGNonly) /* If we should produce nothing but background noise */ + { + if (*pw16_len > 0) + { + /* + * Set length to input parameter length, but not more than length + * of pw16_randVec + */ + w16_lag = WEBRTC_SPL_MIN(*pw16_len, FSMULT * 120 + 30); + } + else + { + /* set length to 15 ms */ + w16_lag = fsMult120; + } + w16_randLen = w16_lag; + } + else + { + w16_randLen = ExpandState->w16_maxLag; + } + + if (w16_randLen <= RANDVEC_NO_OF_SAMPLES) + { + inst->w16_seedInc = (inst->w16_seedInc + 2) & (RANDVEC_NO_OF_SAMPLES - 1); + WebRtcNetEQ_RandomVec(&inst->uw16_seed, pw16_randVec, w16_randLen, + inst->w16_seedInc); + } + else + { /* only applies to SWB where length could be larger than 256 */ + inst->w16_seedInc = (inst->w16_seedInc + 2) & (RANDVEC_NO_OF_SAMPLES - 1); + WebRtcNetEQ_RandomVec(&inst->uw16_seed, pw16_randVec, RANDVEC_NO_OF_SAMPLES, + inst->w16_seedInc); + inst->w16_seedInc = (inst->w16_seedInc + 2) & (RANDVEC_NO_OF_SAMPLES - 1); + WebRtcNetEQ_RandomVec(&inst->uw16_seed, &pw16_randVec[RANDVEC_NO_OF_SAMPLES], + (WebRtc_Word16) (w16_randLen - RANDVEC_NO_OF_SAMPLES), inst->w16_seedInc); + } + } /* end if(first expand or BGNonly) ... else ... */ + + if (!BGNonly) /* Voiced and unvoiced parts not used if generating BGN only */ + { + + /************************************************* + * Generate signal * + *************************************************/ + + /* + * Voiced part + */ + + /* Linearly mute the use_vfraction value from 1 to vfraction */ + if (ExpandState->w16_consecExp == 0) + { + ExpandState->w16_currentVFraction = 16384; /* 1.0 in Q14 */ + } + + ExpandState->w16_lagsPosition = ExpandState->w16_lagsPosition + + ExpandState->w16_lagsDirection; + + /* Change direction if needed */ + if (ExpandState->w16_lagsPosition == 0) + { + ExpandState->w16_lagsDirection = 1; + } + if (ExpandState->w16_lagsPosition == 2) + { + ExpandState->w16_lagsDirection = -1; + } + + /* Generate a weighted vector with the selected lag */ + w16_expVecsLen = ExpandState->w16_maxLag + ExpandState->w16_overlap; + w16_lag = ExpandState->w16_lags[ExpandState->w16_lagsPosition]; + /* Copy lag+overlap data */ + w16_expVecPos = w16_expVecsLen - w16_lag - ExpandState->w16_overlap; + w16_tmp = w16_lag + ExpandState->w16_overlap; + if (ExpandState->w16_lagsPosition == 0) + { + WEBRTC_SPL_MEMCPY_W16(pw16_voicedVecStorage, + &(ExpandState->pw16_expVecs[0][w16_expVecPos]), w16_tmp); + } + else if (ExpandState->w16_lagsPosition == 1) + { + WebRtcSpl_ScaleAndAddVectorsWithRound(&ExpandState->pw16_expVecs[0][w16_expVecPos], 3, + &ExpandState->pw16_expVecs[1][w16_expVecPos], 1, 2, pw16_voicedVecStorage, + w16_tmp); + + } + else if (ExpandState->w16_lagsPosition == 2) + { + WebRtcSpl_ScaleAndAddVectorsWithRound(&ExpandState->pw16_expVecs[0][w16_expVecPos], 1, + &ExpandState->pw16_expVecs[1][w16_expVecPos], 1, 1, pw16_voicedVecStorage, + w16_tmp); + } + + if (inst->fs == 8000) + { + /* Windowing in Q15 */ + w16_winMute = NETEQ_OVERLAP_WINMUTE_8KHZ_START; + w16_winMuteInc = NETEQ_OVERLAP_WINMUTE_8KHZ_INC; + w16_winUnMute = NETEQ_OVERLAP_WINUNMUTE_8KHZ_START; + w16_winUnMuteInc = NETEQ_OVERLAP_WINUNMUTE_8KHZ_INC; +#ifdef NETEQ_WIDEBAND + } + else if (inst->fs == 16000) + { + /* Windowing in Q15 */ + w16_winMute = NETEQ_OVERLAP_WINMUTE_16KHZ_START; + w16_winMuteInc = NETEQ_OVERLAP_WINMUTE_16KHZ_INC; + w16_winUnMute = NETEQ_OVERLAP_WINUNMUTE_16KHZ_START; + w16_winUnMuteInc = NETEQ_OVERLAP_WINUNMUTE_16KHZ_INC; +#endif +#ifdef NETEQ_32KHZ_WIDEBAND + } + else if (inst->fs == 32000) + { + /* Windowing in Q15 */ + w16_winMute = NETEQ_OVERLAP_WINMUTE_32KHZ_START; + w16_winMuteInc = NETEQ_OVERLAP_WINMUTE_32KHZ_INC; + w16_winUnMute = NETEQ_OVERLAP_WINUNMUTE_32KHZ_START; + w16_winUnMuteInc = NETEQ_OVERLAP_WINUNMUTE_32KHZ_INC; +#endif +#ifdef NETEQ_48KHZ_WIDEBAND + } + else /* if (inst->fs==48000) */ + { + /* Windowing in Q15 */ + w16_winMute = NETEQ_OVERLAP_WINMUTE_48KHZ_START; + w16_winMuteInc = NETEQ_OVERLAP_WINMUTE_48KHZ_INC; + w16_winUnMute = NETEQ_OVERLAP_WINUNMUTE_48KHZ_START; + w16_winUnMuteInc = NETEQ_OVERLAP_WINUNMUTE_48KHZ_INC; +#endif + } + + /* Smooth the expanded if it has not been muted to or vfraction is larger than 0.5 */ + if ((ExpandState->w16_expandMuteFactor > 819) && (ExpandState->w16_currentVFraction + > 8192)) + { + for (i = 0; i < ExpandState->w16_overlap; i++) + { + /* Do overlap add between new vector and overlap */ + ExpandState->pw16_overlapVec[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32( + WEBRTC_SPL_MUL_16_16(ExpandState->pw16_overlapVec[i], w16_winMute) + + WEBRTC_SPL_MUL_16_16( + WEBRTC_SPL_MUL_16_16_RSFT(ExpandState->w16_expandMuteFactor, + pw16_voicedVecStorage[i], 14), w16_winUnMute) + 16384, 15); + w16_winMute += w16_winMuteInc; + w16_winUnMute += w16_winUnMuteInc; + } + } + else if (ExpandState->w16_expandMuteFactor == 0 +#ifdef NETEQ_STEREO + && msInfo->msMode == NETEQ_MONO /* only if mono mode is selected */ +#endif + ) + { + /* if ExpandState->w16_expandMuteFactor = 0 => all is CNG component + set the output length to 15ms (for best CNG production) */ + w16_tmp = fsMult120; + ExpandState->w16_maxLag = w16_tmp; + ExpandState->w16_lags[0] = w16_tmp; + ExpandState->w16_lags[1] = w16_tmp; + ExpandState->w16_lags[2] = w16_tmp; + } + + /* + * Unvoiced part + */ + + WEBRTC_SPL_MEMCPY_W16(pw16_unvoicedVec - UNVOICED_LPC_ORDER, + ExpandState->pw16_arState, + UNVOICED_LPC_ORDER); + if (ExpandState->w16_arGainScale > 0) + { + w32_tmp = ((WebRtc_Word32) 1) << (ExpandState->w16_arGainScale - 1); + } + else + { + w32_tmp = 0; + } + + /* Note that shift value can be >16 which complicates things for some DSPs */ + WebRtcSpl_AffineTransformVector(pw16_scaledRandVec, pw16_randVec, + ExpandState->w16_arGain, w32_tmp, ExpandState->w16_arGainScale, w16_lag); + + WebRtcSpl_FilterARFastQ12(pw16_scaledRandVec, pw16_unvoicedVec, + ExpandState->pw16_arFilter, UNVOICED_LPC_ORDER + 1, w16_lag); + + WEBRTC_SPL_MEMCPY_W16(ExpandState->pw16_arState, + &(pw16_unvoicedVec[w16_lag - UNVOICED_LPC_ORDER]), + UNVOICED_LPC_ORDER); + + /* + * Voiced + Unvoiced + */ + + /* For lag = + <=31*fs_mult => go from 1 to 0 in about 8 ms + (>=31..<=63)*fs_mult => go from 1 to 0 in about 16 ms + >=64*fs_mult => go from 1 to 0 in about 32 ms + */ + w16_tmp = (31 - WebRtcSpl_NormW32(ExpandState->w16_maxLag)) - 5; /* getbits(w16_maxLag) -5 */ + w16_vfractionChange = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(256, w16_tmp); + if (ExpandState->w16_stopMuting == 1) + { + w16_vfractionChange = 0; + } + + /* Create combined signal (unmuted) by shifting in more and more of unvoiced part */ + w16_tmp = 8 - w16_tmp; /* getbits(w16_vfractionChange) */ + w16_tmp = (ExpandState->w16_currentVFraction - ExpandState->w16_vFraction) >> w16_tmp; + w16_tmp = WEBRTC_SPL_MIN(w16_tmp, w16_lag); + WebRtcNetEQ_MixVoiceUnvoice(pw16_outData, pw16_voicedVec, pw16_unvoicedVec, + &ExpandState->w16_currentVFraction, w16_vfractionChange, w16_tmp); + + if (w16_tmp < w16_lag) + { + if (w16_vfractionChange != 0) + { + ExpandState->w16_currentVFraction = ExpandState->w16_vFraction; + } + w16_tmp2 = 16384 - ExpandState->w16_currentVFraction; + WebRtcSpl_ScaleAndAddVectorsWithRound(pw16_voicedVec + w16_tmp, + ExpandState->w16_currentVFraction, pw16_unvoicedVec + w16_tmp, w16_tmp2, 14, + pw16_outData + w16_tmp, (WebRtc_Word16) (w16_lag - w16_tmp)); + } + + /* Select muting factor */ + if (ExpandState->w16_consecExp == 3) + { + /* 0.95 on 50 samples in NB (0.0010/fs_mult in Q20) */ + ExpandState->w16_muteSlope = WEBRTC_SPL_MAX(ExpandState->w16_muteSlope, + WebRtcNetEQ_k1049div[fs_mult]); + } + if (ExpandState->w16_consecExp == 7) + { + /* 0.90 on 50 samples in NB (0.0020/fs_mult in Q20) */ + ExpandState->w16_muteSlope = WEBRTC_SPL_MAX(ExpandState->w16_muteSlope, + WebRtcNetEQ_k2097div[fs_mult]); + } + + /* Mute segment according to slope value */ + if ((ExpandState->w16_consecExp != 0) || (ExpandState->w16_onset != 1)) + { + /* Mute to the previous level, then continue with the muting */ + WebRtcSpl_AffineTransformVector(pw16_outData, pw16_outData, + ExpandState->w16_expandMuteFactor, 8192, 14, w16_lag); + + if ((ExpandState->w16_stopMuting != 1)) + { + WebRtcNetEQ_MuteSignal(pw16_outData, ExpandState->w16_muteSlope, w16_lag); + + w16_tmp = 16384 - (WebRtc_Word16) ((WEBRTC_SPL_MUL_16_16(w16_lag, + ExpandState->w16_muteSlope) + 8192) >> 6); /* 20-14 = 6 */ + w16_tmp = (WebRtc_Word16) ((WEBRTC_SPL_MUL_16_16(w16_tmp, + ExpandState->w16_expandMuteFactor) + 8192) >> 14); + + /* Guard against getting stuck with very small (but sometimes audible) gain */ + if ((ExpandState->w16_consecExp > 3) && (w16_tmp + >= ExpandState->w16_expandMuteFactor)) + { + ExpandState->w16_expandMuteFactor = 0; + } + else + { + ExpandState->w16_expandMuteFactor = w16_tmp; + } + } + } + + } /* end if(!BGNonly) */ + + /* + * BGN + */ + + if (BGNState->w16_initialized == 1) + { + /* BGN parameters are initialized; use them */ + + WEBRTC_SPL_MEMCPY_W16(pw16_cngVec - BGN_LPC_ORDER, + BGNState->pw16_filterState, + BGN_LPC_ORDER); + + if (BGNState->w16_scaleShift > 1) + { + w32_tmp = ((WebRtc_Word32) 1) << (BGNState->w16_scaleShift - 1); + } + else + { + w32_tmp = 0; + } + + /* Scale random vector to correct energy level */ + /* Note that shift value can be >16 which complicates things for some DSPs */ + WebRtcSpl_AffineTransformVector(pw16_scaledRandVec, pw16_randVec, + BGNState->w16_scale, w32_tmp, BGNState->w16_scaleShift, w16_lag); + + WebRtcSpl_FilterARFastQ12(pw16_scaledRandVec, pw16_cngVec, BGNState->pw16_filter, + BGN_LPC_ORDER + 1, w16_lag); + + WEBRTC_SPL_MEMCPY_W16(BGNState->pw16_filterState, + &(pw16_cngVec[w16_lag-BGN_LPC_ORDER]), + BGN_LPC_ORDER); + + /* Unmute the insertion of background noise */ + + if (bgnMode == BGN_FADE && ExpandState->w16_consecExp >= FADE_BGN_TIME + && BGNState->w16_mutefactor > 0) + { + /* fade BGN to zero */ + /* calculate muting slope, approx 2^18/fsHz */ + WebRtc_Word16 muteFactor; + if (fs_mult == 1) + { + muteFactor = -32; + } + else if (fs_mult == 2) + { + muteFactor = -16; + } + else if (fs_mult == 4) + { + muteFactor = -8; + } + else + { + muteFactor = -5; + } + /* use UnmuteSignal function with negative slope */ + WebRtcNetEQ_UnmuteSignal(pw16_cngVec, &BGNState->w16_mutefactor, /* In Q14 */ + pw16_cngVec, muteFactor, /* In Q20 */ + w16_lag); + } + else if (BGNState->w16_mutefactor < 16384 && !BGNonly) + { + /* if (w16_mutefactor < 1) and not BGN only (since then we use no muting) */ + + /* + * If BGN_OFF, or if BNG_FADE has started fading, + * mutefactor should not be increased. + */ + if (ExpandState->w16_stopMuting != 1 && bgnMode != BGN_OFF && !(bgnMode + == BGN_FADE && ExpandState->w16_consecExp >= FADE_BGN_TIME)) + { + WebRtcNetEQ_UnmuteSignal(pw16_cngVec, &BGNState->w16_mutefactor, /* In Q14 */ + pw16_cngVec, ExpandState->w16_muteSlope, /* In Q20 */ + w16_lag); + } + else + { + /* BGN_ON and stop muting, or + * BGN_OFF (mute factor is always 0), or + * BGN_FADE has reached 0 */ + WebRtcSpl_AffineTransformVector(pw16_cngVec, pw16_cngVec, + BGNState->w16_mutefactor, 8192, 14, w16_lag); + } + } + } + else + { + /* BGN parameters have not been initialized; use zero noise */ + WebRtcSpl_MemSetW16(pw16_cngVec, 0, w16_lag); + } + + if (BGNonly) + { + /* Copy BGN to outdata */ + for (i = 0; i < w16_lag; i++) + { + pw16_outData[i] = pw16_cngVec[i]; + } + } + else + { + /* Add CNG vector to the Voiced + Unvoiced vectors */ + for (i = 0; i < w16_lag; i++) + { + pw16_outData[i] = pw16_outData[i] + pw16_cngVec[i]; + } + + /* increase call number */ + ExpandState->w16_consecExp = ExpandState->w16_consecExp + 1; + if (ExpandState->w16_consecExp < 0) /* Guard against overflow */ + ExpandState->w16_consecExp = FADE_BGN_TIME; /* "Arbitrary" large num of expands */ + } + + inst->w16_mode = MODE_EXPAND; + *pw16_len = w16_lag; + + /* Update in-call and post-call statistics */ + if (ExpandState->w16_stopMuting != 1 || BGNonly) + { + /* + * Only do this if StopMuting != 1 or if explicitly BGNonly, otherwise Expand is + * called from Merge or Normal and special measures must be taken. + */ + inst->statInst.expandLength += (WebRtc_UWord32) *pw16_len; + if (ExpandState->w16_expandMuteFactor == 0 || BGNonly) + { + /* Only noise expansion */ + inst->statInst.expandedNoiseSamples += *pw16_len; + } + else + { + /* Voice expand (note: not necessarily _voiced_) */ + inst->statInst.expandedVoiceSamples += *pw16_len; + } + } + + return 0; +} + +/**************************************************************************** + * WebRtcNetEQ_GenerateBGN(...) + * + * This function generates and writes len samples of background noise to the + * output vector. The Expand function will be called repeatedly until the + * correct number of samples is produced. + * + * Input: + * - inst : NetEq instance, i.e. the user that requests more + * speech/audio data + * - scratchPtr : Pointer to scratch vector + * - len : Desired length of produced BGN. + * + * + * Output: + * - pw16_outData : Pointer to a memory space where the output data + * should be stored + * + * Return value : >=0 - Number of noise samples produced and written + * to output + * -1 - Error + */ + +int WebRtcNetEQ_GenerateBGN(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + WebRtc_Word16 *pw16_outData, WebRtc_Word16 len) +{ + + WebRtc_Word16 pos = 0; + WebRtc_Word16 tempLen = len; + + while (tempLen > 0) + { + /* while we still need more noise samples, call Expand to obtain background noise */ + WebRtcNetEQ_Expand(inst, +#ifdef SCRATCH + pw16_scratchPtr, +#endif + &pw16_outData[pos], &tempLen, 1 /*BGNonly*/); + + pos += tempLen; /* we got this many samples */ + tempLen = len - pos; /* this is the number of samples we still need */ + } + + return pos; +} + +#undef SCRATCH_PW16_BEST_CORR_INDEX +#undef SCRATCH_PW16_BEST_CORR +#undef SCRATCH_PW16_BEST_DIST_INDEX +#undef SCRATCH_PW16_BEST_DIST +#undef SCRATCH_PW16_CORR_VEC +#undef SCRATCH_PW16_CORR2 +#undef SCRATCH_PW32_AUTO_CORR +#undef SCRATCH_PW16_RC +#undef SCRATCH_PW16_RAND_VEC +#undef SCRATCH_NETEQDSP_CORRELATOR +#undef SCRATCH_PW16_SCALED_RAND_VEC +#undef SCRATCH_PW16_UNVOICED_VEC_SPACE + diff --git a/src/libs/webrtc/neteq/mcu.h b/src/libs/webrtc/neteq/mcu.h new file mode 100644 index 00000000..2e759aa0 --- /dev/null +++ b/src/libs/webrtc/neteq/mcu.h @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * MCU struct and functions related to the MCU side operations. + */ + +#ifndef MCU_H +#define MCU_H + +#include "typedefs.h" + +#include "codec_db.h" +#include "rtcp.h" +#include "packet_buffer.h" +#include "buffer_stats.h" +#include "neteq_statistics.h" + +#ifdef NETEQ_ATEVENT_DECODE +#include "dtmf_buffer.h" +#endif + +#define MAX_ONE_DESC 5 /* cannot do more than this many consecutive one-descriptor decodings */ +#define MAX_LOSS_REPORT_PERIOD 60 /* number of seconds between auto-reset */ + +enum TsScaling +{ + kTSnoScaling = 0, + kTSscalingTwo, + kTSscalingTwoThirds, + kTSscalingFourThirds +}; + +typedef struct +{ + + WebRtc_Word16 current_Codec; + WebRtc_Word16 current_Payload; + WebRtc_UWord32 timeStamp; /* Next timestamp that should be played */ + WebRtc_Word16 millisecondsPerCall; + WebRtc_UWord16 timestampsPerCall; /* Output chunk size */ + WebRtc_UWord16 fs; + WebRtc_UWord32 ssrc; /* Current ssrc */ + WebRtc_Word16 new_codec; + WebRtc_Word16 first_packet; + + /* MCU/DSP Communication layer */ + WebRtc_Word16 *pw16_readAddress; + WebRtc_Word16 *pw16_writeAddress; + void *main_inst; + + CodecDbInst_t codec_DB_inst; /* Information about all the codecs, i.e. which + functions to use and which codpoints that + have been assigned */ + SplitInfo_t PayloadSplit_inst; /* Information about how the current codec + payload should be splitted */ + WebRtcNetEQ_RTCP_t RTCP_inst; /* RTCP statistics */ + PacketBuf_t PacketBuffer_inst; /* The packet buffer */ + BufstatsInst_t BufferStat_inst; /* Statistics that are used to make decision + for what the DSP should perform */ +#ifdef NETEQ_ATEVENT_DECODE + dtmf_inst_t DTMF_inst; +#endif + int NoOfExpandCalls; + WebRtc_Word16 AVT_PlayoutOn; + enum WebRtcNetEQPlayoutMode NetEqPlayoutMode; + + WebRtc_Word16 one_desc; /* Number of times running on one desc */ + + WebRtc_UWord32 lostTS; /* Number of timestamps lost */ + WebRtc_UWord32 lastReportTS; /* Timestamp elapsed since last report was given */ + + WebRtc_UWord32 externalTS; + WebRtc_UWord32 internalTS; + WebRtc_Word16 TSscalingInitialized; + enum TsScaling scalingFactor; + + MCUStats_t statInst; + +#ifdef NETEQ_STEREO + int usingStereo; +#endif + +} MCUInst_t; + +/**************************************************************************** + * WebRtcNetEQ_McuReset(...) + * + * Reset the MCU instance. + * + * Input: + * - inst : MCU instance + * + * Return value : 0 - Ok + * <0 - Error + */ +int WebRtcNetEQ_McuReset(MCUInst_t *inst); + +/**************************************************************************** + * WebRtcNetEQ_ResetMcuInCallStats(...) + * + * Reset MCU-side statistics variables for the in-call statistics. + * + * Input: + * - inst : MCU instance + * + * Return value : 0 - Ok + * <0 - Error + */ +int WebRtcNetEQ_ResetMcuInCallStats(MCUInst_t *inst); + +/**************************************************************************** + * WebRtcNetEQ_ResetMcuJitterStat(...) + * + * Reset MCU-side statistics variables for the post-call statistics. + * + * Input: + * - inst : MCU instance + * + * Return value : 0 - Ok + * <0 - Error + */ +int WebRtcNetEQ_ResetMcuJitterStat(MCUInst_t *inst); + +/**************************************************************************** + * WebRtcNetEQ_McuAddressInit(...) + * + * Initializes MCU with read address and write address. + * + * Input: + * - inst : MCU instance + * - Data2McuAddress : Pointer to MCU address + * - Data2DspAddress : Pointer to DSP address + * - main_inst : Pointer to NetEQ main instance + * + * Return value : 0 - Ok + * <0 - Error + */ +int WebRtcNetEQ_McuAddressInit(MCUInst_t *inst, void * Data2McuAddress, + void * Data2DspAddress, void *main_inst); + +/**************************************************************************** + * WebRtcNetEQ_McuSetFs(...) + * + * Initializes MCU with read address and write address. + * + * Input: + * - inst : MCU instance + * - fs_hz : Sample rate in Hz -- 8000, 16000, 32000, (48000) + * + * Return value : 0 - Ok + * <0 - Error + */ +int WebRtcNetEQ_McuSetFs(MCUInst_t *inst, WebRtc_UWord16 fs_hz); + +/**************************************************************************** + * WebRtcNetEQ_SignalMcu(...) + * + * Signal the MCU that data is available and ask for a RecOut decision. + * + * Input: + * - inst : MCU instance + * + * Return value : 0 - Ok + * <0 - Error + */ +int WebRtcNetEQ_SignalMcu(MCUInst_t *inst); + +/**************************************************************************** + * WebRtcNetEQ_RecInInternal(...) + * + * This function inserts a packet into the jitter buffer. + * + * Input: + * - MCU_inst : MCU instance + * - RTPpacket : The RTP packet, parsed into NetEQ's internal RTP struct + * - uw32_timeRec : Time stamp for the arrival of the packet (not RTP timestamp) + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_RecInInternal(MCUInst_t *MCU_inst, RTPPacket_t *RTPpacket, + WebRtc_UWord32 uw32_timeRec); + +/**************************************************************************** + * WebRtcNetEQ_RecInInternal(...) + * + * Split the packet according to split_inst and inserts the parts into + * Buffer_inst. + * + * Input: + * - MCU_inst : MCU instance + * - RTPpacket : The RTP packet, parsed into NetEQ's internal RTP struct + * - uw32_timeRec : Time stamp for the arrival of the packet (not RTP timestamp) + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNetEQ_SplitAndInsertPayload(RTPPacket_t *packet, PacketBuf_t *Buffer_inst, + SplitInfo_t *split_inst, WebRtc_Word16 *flushed); + +/**************************************************************************** + * WebRtcNetEQ_GetTimestampScaling(...) + * + * Update information about timestamp scaling for a payload type + * in MCU_inst->scalingFactor. + * + * Input: + * - MCU_inst : MCU instance + * - rtpPayloadType : RTP payload number + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_GetTimestampScaling(MCUInst_t *MCU_inst, int rtpPayloadType); + +/**************************************************************************** + * WebRtcNetEQ_ScaleTimestampExternalToInternal(...) + * + * Convert from external to internal timestamp using current scaling info. + * + * Input: + * - MCU_inst : MCU instance + * - externalTS : External timestamp + * + * Return value : Internal timestamp + */ + +WebRtc_UWord32 WebRtcNetEQ_ScaleTimestampExternalToInternal(const MCUInst_t *MCU_inst, + WebRtc_UWord32 externalTS); + +/**************************************************************************** + * WebRtcNetEQ_ScaleTimestampInternalToExternal(...) + * + * Convert from external to internal timestamp using current scaling info. + * + * Input: + * - MCU_inst : MCU instance + * - externalTS : Internal timestamp + * + * Return value : External timestamp + */ + +WebRtc_UWord32 WebRtcNetEQ_ScaleTimestampInternalToExternal(const MCUInst_t *MCU_inst, + WebRtc_UWord32 internalTS); +#endif diff --git a/src/libs/webrtc/neteq/mcu_address_init.c b/src/libs/webrtc/neteq/mcu_address_init.c new file mode 100644 index 00000000..0306a853 --- /dev/null +++ b/src/libs/webrtc/neteq/mcu_address_init.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "mcu.h" + +#include <string.h> /* to define NULL */ + +/* + * Initializes MCU with read address and write address + */ +int WebRtcNetEQ_McuAddressInit(MCUInst_t *inst, void * Data2McuAddress, + void * Data2DspAddress, void *main_inst) +{ + + inst->pw16_readAddress = (WebRtc_Word16*) Data2McuAddress; + inst->pw16_writeAddress = (WebRtc_Word16*) Data2DspAddress; + inst->main_inst = main_inst; + + inst->millisecondsPerCall = 10; + + /* Do expansions in the beginning */ + if (inst->pw16_writeAddress != NULL) inst->pw16_writeAddress[0] = DSP_INSTR_EXPAND; + + return (0); +} + diff --git a/src/libs/webrtc/neteq/mcu_dsp_common.c b/src/libs/webrtc/neteq/mcu_dsp_common.c new file mode 100644 index 00000000..13025d43 --- /dev/null +++ b/src/libs/webrtc/neteq/mcu_dsp_common.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Communication between MCU and DSP sides. + */ + +#include "mcu_dsp_common.h" + +#include <string.h> + +/* Initialize instances with read and write address */ +int WebRtcNetEQ_DSPinit(MainInst_t *inst) +{ + int res = 0; + + res |= WebRtcNetEQ_AddressInit(&inst->DSPinst, NULL, NULL, inst); + res |= WebRtcNetEQ_McuAddressInit(&inst->MCUinst, NULL, NULL, inst); + + return res; + +} + +/* The DSP side will call this function to interrupt the MCU side */ +int WebRtcNetEQ_DSP2MCUinterrupt(MainInst_t *inst, WebRtc_Word16 *pw16_shared_mem) +{ + inst->MCUinst.pw16_readAddress = pw16_shared_mem; + inst->MCUinst.pw16_writeAddress = pw16_shared_mem; + return WebRtcNetEQ_SignalMcu(&inst->MCUinst); +} diff --git a/src/libs/webrtc/neteq/mcu_dsp_common.h b/src/libs/webrtc/neteq/mcu_dsp_common.h new file mode 100644 index 00000000..e3f42137 --- /dev/null +++ b/src/libs/webrtc/neteq/mcu_dsp_common.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * The main NetEQ instance, which is where the DSP and MCU sides join. + */ + +#ifndef MCU_DSP_COMMON_H +#define MCU_DSP_COMMON_H + +#include "typedefs.h" + +#include "dsp.h" +#include "mcu.h" + +/* Define size of shared memory area. */ +#if defined(NETEQ_48KHZ_WIDEBAND) + #define SHARED_MEM_SIZE (6*640) +#elif defined(NETEQ_32KHZ_WIDEBAND) + #define SHARED_MEM_SIZE (4*640) +#elif defined(NETEQ_WIDEBAND) + #define SHARED_MEM_SIZE (2*640) +#else + #define SHARED_MEM_SIZE 640 +#endif + +/* Struct to hold the NetEQ instance */ +typedef struct +{ + DSPInst_t DSPinst; /* DSP part of the NetEQ instance */ + MCUInst_t MCUinst; /* MCU part of the NetEQ instance */ + WebRtc_Word16 ErrorCode; /* Store last error code */ +#ifdef NETEQ_STEREO + WebRtc_Word16 masterSlave; /* 0 = not set, 1 = master, 2 = slave */ +#endif /* NETEQ_STEREO */ +} MainInst_t; + +/* Struct used for communication between DSP and MCU sides of NetEQ */ +typedef struct +{ + WebRtc_UWord32 playedOutTS; /* Timestamp position at end of DSP data */ + WebRtc_UWord16 samplesLeft; /* Number of samples stored */ + WebRtc_Word16 MD; /* Multiple description codec information */ + WebRtc_Word16 lastMode; /* Latest mode of NetEQ playout */ + WebRtc_Word16 frameLen; /* Frame length of previously decoded packet */ +} DSP2MCU_info_t; + +/* Initialize instances with read and write address */ +int WebRtcNetEQ_DSPinit(MainInst_t *inst); + +/* The DSP side will call this function to interrupt the MCU side */ +int WebRtcNetEQ_DSP2MCUinterrupt(MainInst_t *inst, WebRtc_Word16 *pw16_shared_mem); + +#endif diff --git a/src/libs/webrtc/neteq/mcu_reset.c b/src/libs/webrtc/neteq/mcu_reset.c new file mode 100644 index 00000000..ef97296c --- /dev/null +++ b/src/libs/webrtc/neteq/mcu_reset.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Reset MCU side data. + */ + +#include "mcu.h" + +#include <string.h> + +#include "automode.h" + +int WebRtcNetEQ_McuReset(MCUInst_t *inst) +{ + +#ifdef NETEQ_ATEVENT_DECODE + int ok; +#endif + + /* MCU/DSP Communication layer */ + inst->pw16_readAddress = NULL; + inst->pw16_writeAddress = NULL; + inst->main_inst = NULL; + inst->one_desc = 0; + inst->BufferStat_inst.Automode_inst.extraDelayMs = 0; + inst->NetEqPlayoutMode = kPlayoutOn; + + WebRtcNetEQ_DbReset(&inst->codec_DB_inst); + memset(&inst->PayloadSplit_inst, 0, sizeof(SplitInfo_t)); + + /* Clear the Packet buffer and the pointer to memory storage */ + WebRtcNetEQ_PacketBufferFlush(&inst->PacketBuffer_inst); + inst->PacketBuffer_inst.memorySizeW16 = 0; + inst->PacketBuffer_inst.maxInsertPositions = 0; + + /* Clear the decision and delay history */ + memset(&inst->BufferStat_inst, 0, sizeof(BufstatsInst_t)); +#ifdef NETEQ_ATEVENT_DECODE + ok = WebRtcNetEQ_DtmfDecoderInit(&inst->DTMF_inst, 8000, 560); + if (ok != 0) + { + return ok; + } +#endif + inst->NoOfExpandCalls = 0; + inst->current_Codec = -1; + inst->current_Payload = -1; + + inst->millisecondsPerCall = 10; + inst->timestampsPerCall = inst->millisecondsPerCall * 8; + inst->fs = 8000; + inst->first_packet = 1; + + WebRtcNetEQ_ResetMcuInCallStats(inst); + + WebRtcNetEQ_ResetMcuJitterStat(inst); + + WebRtcNetEQ_ResetAutomode(&(inst->BufferStat_inst.Automode_inst), + inst->PacketBuffer_inst.maxInsertPositions); + + return 0; +} + +/* + * Reset MCU-side statistics variables for the in-call statistics. + */ + +int WebRtcNetEQ_ResetMcuInCallStats(MCUInst_t *inst) +{ + inst->lostTS = 0; + inst->lastReportTS = 0; + inst->PacketBuffer_inst.discardedPackets = 0; + + return 0; +} + +/* + * Reset all MCU-side statistics variables for the post-call statistics. + */ + +int WebRtcNetEQ_ResetMcuJitterStat(MCUInst_t *inst) +{ + inst->statInst.jbAvgCount = 0; + inst->statInst.jbAvgSizeQ16 = 0; + inst->statInst.jbMaxSize = 0; + inst->statInst.jbMinSize = 0xFFFFFFFF; + inst->statInst.avgPacketCount = 0; + inst->statInst.avgPacketDelayMs = 0; + inst->statInst.minPacketDelayMs = 0xFFFFFFFF; + inst->statInst.maxPacketDelayMs = 0; + inst->statInst.jbChangeCount = 0; + inst->statInst.generatedSilentMs = 0; + inst->statInst.countExpandMoreThan120ms = 0; + inst->statInst.countExpandMoreThan250ms = 0; + inst->statInst.countExpandMoreThan500ms = 0; + inst->statInst.countExpandMoreThan2000ms = 0; + inst->statInst.longestExpandDurationMs = 0; + inst->statInst.accelerateMs = 0; + + inst->PacketBuffer_inst.totalDiscardedPackets = 0; + inst->PacketBuffer_inst.totalFlushedPackets = 0; + + inst->BufferStat_inst.Automode_inst.countIAT500ms = 0; + inst->BufferStat_inst.Automode_inst.countIAT1000ms = 0; + inst->BufferStat_inst.Automode_inst.countIAT2000ms = 0; + inst->BufferStat_inst.Automode_inst.longestIATms = 0; + + return 0; +} + diff --git a/src/libs/webrtc/neteq/merge.c b/src/libs/webrtc/neteq/merge.c new file mode 100644 index 00000000..28e31c4d --- /dev/null +++ b/src/libs/webrtc/neteq/merge.c @@ -0,0 +1,548 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This is the function to merge a new packet with expanded data after a packet loss. + */ + +#include "dsp.h" + +#include "signal_processing_library.h" + +#include "dsp_helpfunctions.h" +#include "neteq_error_codes.h" + +/**************************************************************************** + * WebRtcNetEQ_Merge(...) + * + * This function... + * + * Input: + * - inst : NetEQ DSP instance + * - scratchPtr : Pointer to scratch vector. + * - decoded : Pointer to new decoded speech. + * - len : Number of samples in pw16_decoded. + * + * + * Output: + * - inst : Updated user information + * - outData : Pointer to a memory space where the output data + * should be stored + * - pw16_len : Number of samples written to pw16_outData + * + * Return value : 0 - Ok + * <0 - Error + */ + +/* Scratch usage: + + Type Name size startpos endpos + WebRtc_Word16 pw16_expanded 210*fs/8000 0 209*fs/8000 + WebRtc_Word16 pw16_expandedLB 100 210*fs/8000 99+210*fs/8000 + WebRtc_Word16 pw16_decodedLB 40 100+210*fs/8000 139+210*fs/8000 + WebRtc_Word32 pw32_corr 2*60 140+210*fs/8000 260+210*fs/8000 + WebRtc_Word16 pw16_corrVec 68 210*fs/8000 67+210*fs/8000 + + [gap in scratch vector] + + func WebRtcNetEQ_Expand 40+370*fs/8000 126*fs/8000 39+496*fs/8000 + + Total: 40+496*fs/8000 + */ + +#define SCRATCH_pw16_expanded 0 +#if (defined(NETEQ_48KHZ_WIDEBAND)) +#define SCRATCH_pw16_expandedLB 1260 +#define SCRATCH_pw16_decodedLB 1360 +#define SCRATCH_pw32_corr 1400 +#define SCRATCH_pw16_corrVec 1260 +#define SCRATCH_NETEQ_EXPAND 756 +#elif (defined(NETEQ_32KHZ_WIDEBAND)) +#define SCRATCH_pw16_expandedLB 840 +#define SCRATCH_pw16_decodedLB 940 +#define SCRATCH_pw32_corr 980 +#define SCRATCH_pw16_corrVec 840 +#define SCRATCH_NETEQ_EXPAND 504 +#elif (defined(NETEQ_WIDEBAND)) +#define SCRATCH_pw16_expandedLB 420 +#define SCRATCH_pw16_decodedLB 520 +#define SCRATCH_pw32_corr 560 +#define SCRATCH_pw16_corrVec 420 +#define SCRATCH_NETEQ_EXPAND 252 +#else /* NB */ +#define SCRATCH_pw16_expandedLB 210 +#define SCRATCH_pw16_decodedLB 310 +#define SCRATCH_pw32_corr 350 +#define SCRATCH_pw16_corrVec 210 +#define SCRATCH_NETEQ_EXPAND 126 +#endif + +int WebRtcNetEQ_Merge(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + WebRtc_Word16 *pw16_decoded, int len, WebRtc_Word16 *pw16_outData, + WebRtc_Word16 *pw16_len) +{ + + WebRtc_Word16 fs_mult; + WebRtc_Word16 fs_shift; + WebRtc_Word32 w32_En_new_frame, w32_En_old_frame; + WebRtc_Word16 w16_expmax, w16_newmax; + WebRtc_Word16 w16_tmp, w16_tmp2; + WebRtc_Word32 w32_tmp; +#ifdef SCRATCH + WebRtc_Word16 *pw16_expanded = pw16_scratchPtr + SCRATCH_pw16_expanded; + WebRtc_Word16 *pw16_expandedLB = pw16_scratchPtr + SCRATCH_pw16_expandedLB; + WebRtc_Word16 *pw16_decodedLB = pw16_scratchPtr + SCRATCH_pw16_decodedLB; + WebRtc_Word32 *pw32_corr = (WebRtc_Word32*) (pw16_scratchPtr + SCRATCH_pw32_corr); + WebRtc_Word16 *pw16_corrVec = pw16_scratchPtr + SCRATCH_pw16_corrVec; +#else + WebRtc_Word16 pw16_expanded[(125+80+5)*FSMULT]; + WebRtc_Word16 pw16_expandedLB[100]; + WebRtc_Word16 pw16_decodedLB[40]; + WebRtc_Word32 pw32_corr[60]; + WebRtc_Word16 pw16_corrVec[4+60+4]; +#endif + WebRtc_Word16 *pw16_corr = &pw16_corrVec[4]; + WebRtc_Word16 w16_stopPos, w16_bestIndex, w16_interpLen; + WebRtc_Word16 w16_bestVal; /* bestVal is dummy */ + WebRtc_Word16 w16_startfact, w16_inc; + WebRtc_Word16 w16_expandedLen; + WebRtc_Word16 w16_startPos; + WebRtc_Word16 w16_expLen, w16_newLen = 0; + WebRtc_Word16 *pw16_decodedOut; + WebRtc_Word16 w16_muted; + + int w16_decodedLen = len; + +#ifdef NETEQ_STEREO + MasterSlaveInfo *msInfo = inst->msInfo; +#endif + + fs_mult = WebRtcSpl_DivW32W16ResW16(inst->fs, 8000); + fs_shift = 30 - WebRtcSpl_NormW32(fs_mult); /* Note that this is not "exact" for 48kHz */ + + /************************************* + * Generate data to merge with + *************************************/ + /* + * Check how much data that is left since earlier + * (at least there should be the overlap)... + */ + w16_startPos = inst->endPosition - inst->curPosition; + /* Get one extra expansion to merge and overlap with */ + inst->ExpandInst.w16_stopMuting = 1; + inst->ExpandInst.w16_lagsDirection = 1; /* make sure we get the "optimal" lag */ + inst->ExpandInst.w16_lagsPosition = -1; /* out of the 3 possible ones */ + w16_expandedLen = 0; /* Does not fill any function currently */ + + if (w16_startPos >= 210 * FSMULT) + { + /* + * The number of samples available in the sync buffer is more than what fits in + * pw16_expanded.Keep the first 210*FSMULT samples, but shift them towards the end of + * the buffer. This is ok, since all of the buffer will be expand data anyway, so as + * long as the beginning is left untouched, we're fine. + */ + + w16_tmp = w16_startPos - 210 * FSMULT; /* length difference */ + + WEBRTC_SPL_MEMMOVE_W16(&inst->speechBuffer[inst->curPosition+w16_tmp] , + &inst->speechBuffer[inst->curPosition], 210*FSMULT); + + inst->curPosition += w16_tmp; /* move start position of sync buffer accordingly */ + w16_startPos = 210 * FSMULT; /* this is the truncated length */ + } + + WebRtcNetEQ_Expand(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, +#endif + pw16_expanded, /* let Expand write to beginning of pw16_expanded to avoid overflow */ + &w16_newLen, 0); + + /* + * Now shift the data in pw16_expanded to where it belongs. + * Truncate all that ends up outside the vector. + */ + + WEBRTC_SPL_MEMMOVE_W16(&pw16_expanded[w16_startPos], pw16_expanded, + WEBRTC_SPL_MIN(w16_newLen, + WEBRTC_SPL_MAX(210*FSMULT - w16_startPos, 0) ) ); + + inst->ExpandInst.w16_stopMuting = 0; + + /* Copy what is left since earlier into the expanded vector */ + + WEBRTC_SPL_MEMCPY_W16(pw16_expanded, &inst->speechBuffer[inst->curPosition], w16_startPos); + + /* + * Do "ugly" copy and paste from the expanded in order to generate more data + * to correlate (but not interpolate) with. + */ + w16_expandedLen = (120 + 80 + 2) * fs_mult; + w16_expLen = w16_startPos + w16_newLen; + + if (w16_expLen < w16_expandedLen) + { + while ((w16_expLen + w16_newLen) < w16_expandedLen) + { + WEBRTC_SPL_MEMCPY_W16(&pw16_expanded[w16_expLen], &pw16_expanded[w16_startPos], + w16_newLen); + w16_expLen += w16_newLen; + } + + /* Copy last part (fraction of a whole expansion) */ + + WEBRTC_SPL_MEMCPY_W16(&pw16_expanded[w16_expLen], &pw16_expanded[w16_startPos], + (w16_expandedLen-w16_expLen)); + } + w16_expLen = w16_expandedLen; + + /* Adjust muting factor (main muting factor times expand muting factor) */ + inst->w16_muteFactor + = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(inst->w16_muteFactor, + inst->ExpandInst.w16_expandMuteFactor, 14); + + /* Adjust muting factor if new vector is more or less of the BGN energy */ + len = WEBRTC_SPL_MIN(64*fs_mult, w16_decodedLen); + w16_expmax = WebRtcSpl_MaxAbsValueW16(pw16_expanded, (WebRtc_Word16) len); + w16_newmax = WebRtcSpl_MaxAbsValueW16(pw16_decoded, (WebRtc_Word16) len); + + /* Calculate energy of old data */ + w16_tmp = 6 + fs_shift - WebRtcSpl_NormW32(WEBRTC_SPL_MUL_16_16(w16_expmax, w16_expmax)); + w16_tmp = WEBRTC_SPL_MAX(w16_tmp,0); + w32_En_old_frame = WebRtcNetEQ_DotW16W16(pw16_expanded, pw16_expanded, len, w16_tmp); + + /* Calculate energy of new data */ + w16_tmp2 = 6 + fs_shift - WebRtcSpl_NormW32(WEBRTC_SPL_MUL_16_16(w16_newmax, w16_newmax)); + w16_tmp2 = WEBRTC_SPL_MAX(w16_tmp2,0); + w32_En_new_frame = WebRtcNetEQ_DotW16W16(pw16_decoded, pw16_decoded, len, w16_tmp2); + + /* Align to same Q-domain */ + if (w16_tmp2 > w16_tmp) + { + w32_En_old_frame = WEBRTC_SPL_RSHIFT_W32(w32_En_old_frame, (w16_tmp2-w16_tmp)); + } + else + { + w32_En_new_frame = WEBRTC_SPL_RSHIFT_W32(w32_En_new_frame, (w16_tmp-w16_tmp2)); + } + + /* Calculate muting factor to use for new frame */ + if (w32_En_new_frame > w32_En_old_frame) + { + /* Normalize w32_En_new_frame to 14 bits */ + w16_tmp = WebRtcSpl_NormW32(w32_En_new_frame) - 17; + w32_En_new_frame = WEBRTC_SPL_SHIFT_W32(w32_En_new_frame, w16_tmp); + + /* + * Put w32_En_old_frame in a domain 14 higher, so that + * w32_En_old_frame/w32_En_new_frame is in Q14 + */ + w16_tmp = w16_tmp + 14; + w32_En_old_frame = WEBRTC_SPL_SHIFT_W32(w32_En_old_frame, w16_tmp); + w16_tmp + = WebRtcSpl_DivW32W16ResW16(w32_En_old_frame, (WebRtc_Word16) w32_En_new_frame); + /* Calculate sqrt(w32_En_old_frame/w32_En_new_frame) in Q14 */ + w16_muted = (WebRtc_Word16) WebRtcSpl_Sqrt( + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)w16_tmp,14)); + } + else + { + w16_muted = 16384; /* Set = 1.0 when old frame has higher energy than new */ + } + + /* Set the raise the continued muting factor w16_muted if w16_muteFactor is lower */ + if (w16_muted > inst->w16_muteFactor) + { + inst->w16_muteFactor = WEBRTC_SPL_MIN(w16_muted, 16384); + } + +#ifdef NETEQ_STEREO + + /* Sanity for msInfo */ + if (msInfo == NULL) + { + /* this should not happen here */ + return MASTER_SLAVE_ERROR; + } + + /* do not downsample and calculate correlations for slave instance(s) */ + if ((msInfo->msMode == NETEQ_MASTER) || (msInfo->msMode == NETEQ_MONO)) + { +#endif + + /********************************************* + * Downsample to 4kHz and find best overlap + *********************************************/ + + /* Downsample to 4 kHz */ + if (inst->fs == 8000) + { + WebRtcSpl_DownsampleFast(&pw16_expanded[2], (WebRtc_Word16) (w16_expandedLen - 2), + pw16_expandedLB, (WebRtc_Word16) (100), + (WebRtc_Word16*) WebRtcNetEQ_kDownsample8kHzTbl, (WebRtc_Word16) 3, + (WebRtc_Word16) 2, (WebRtc_Word16) 0); + if (w16_decodedLen <= 80) + { + /* Not quite long enough, so we have to cheat a bit... */ + WebRtcSpl_DownsampleFast(&pw16_decoded[2], (WebRtc_Word16) 80, pw16_decodedLB, + (WebRtc_Word16) (40), (WebRtc_Word16*) WebRtcNetEQ_kDownsample8kHzTbl, + (WebRtc_Word16) 3, (WebRtc_Word16) 2, (WebRtc_Word16) 0); + w16_tmp = ((w16_decodedLen - 2) >> 1); + WebRtcSpl_MemSetW16(&pw16_decodedLB[w16_tmp], 0, (40 - w16_tmp)); + } + else + { + WebRtcSpl_DownsampleFast(&pw16_decoded[2], + (WebRtc_Word16) (w16_decodedLen - 2), pw16_decodedLB, + (WebRtc_Word16) (40), (WebRtc_Word16*) WebRtcNetEQ_kDownsample8kHzTbl, + (WebRtc_Word16) 3, (WebRtc_Word16) 2, (WebRtc_Word16) 0); + } +#ifdef NETEQ_WIDEBAND + } + else if (inst->fs==16000) + { + WebRtcSpl_DownsampleFast( + &pw16_expanded[4], (WebRtc_Word16)(w16_expandedLen-4), + pw16_expandedLB, (WebRtc_Word16)(100), + (WebRtc_Word16*)WebRtcNetEQ_kDownsample16kHzTbl, (WebRtc_Word16)5, + (WebRtc_Word16)4, (WebRtc_Word16)0); + if (w16_decodedLen<=160) + { + /* Not quite long enough, so we have to cheat a bit... */ + WebRtcSpl_DownsampleFast( + &pw16_decoded[4], (WebRtc_Word16)160, + pw16_decodedLB, (WebRtc_Word16)(40), + (WebRtc_Word16*)WebRtcNetEQ_kDownsample16kHzTbl, (WebRtc_Word16)5, + (WebRtc_Word16)4, (WebRtc_Word16)0); + w16_tmp = ((w16_decodedLen-4)>>2); + WebRtcSpl_MemSetW16(&pw16_decodedLB[w16_tmp], 0, (40-w16_tmp)); + } + else + { + WebRtcSpl_DownsampleFast( + &pw16_decoded[4], (WebRtc_Word16)(w16_decodedLen-4), + pw16_decodedLB, (WebRtc_Word16)(40), + (WebRtc_Word16*)WebRtcNetEQ_kDownsample16kHzTbl, (WebRtc_Word16)5, + (WebRtc_Word16)4, (WebRtc_Word16)0); + } +#endif +#ifdef NETEQ_32KHZ_WIDEBAND + } + else if (inst->fs==32000) + { + WebRtcSpl_DownsampleFast( + &pw16_expanded[6], (WebRtc_Word16)(w16_expandedLen-6), + pw16_expandedLB, (WebRtc_Word16)(100), + (WebRtc_Word16*)WebRtcNetEQ_kDownsample32kHzTbl, (WebRtc_Word16)7, + (WebRtc_Word16)8, (WebRtc_Word16)0); + if (w16_decodedLen<=320) + { + /* Not quite long enough, so we have to cheat a bit... */ + WebRtcSpl_DownsampleFast( + &pw16_decoded[6], (WebRtc_Word16)320, + pw16_decodedLB, (WebRtc_Word16)(40), + (WebRtc_Word16*)WebRtcNetEQ_kDownsample32kHzTbl, (WebRtc_Word16)7, + (WebRtc_Word16)8, (WebRtc_Word16)0); + w16_tmp = ((w16_decodedLen-6)>>3); + WebRtcSpl_MemSetW16(&pw16_decodedLB[w16_tmp], 0, (40-w16_tmp)); + } + else + { + WebRtcSpl_DownsampleFast( + &pw16_decoded[6], (WebRtc_Word16)(w16_decodedLen-6), + pw16_decodedLB, (WebRtc_Word16)(40), + (WebRtc_Word16*)WebRtcNetEQ_kDownsample32kHzTbl, (WebRtc_Word16)7, + (WebRtc_Word16)8, (WebRtc_Word16)0); + } +#endif +#ifdef NETEQ_48KHZ_WIDEBAND + } + else /* if (inst->fs==48000) */ + { + WebRtcSpl_DownsampleFast( + &pw16_expanded[6], (WebRtc_Word16)(w16_expandedLen-6), + pw16_expandedLB, (WebRtc_Word16)(100), + (WebRtc_Word16*)WebRtcNetEQ_kDownsample48kHzTbl, (WebRtc_Word16)7, + (WebRtc_Word16)12, (WebRtc_Word16)0); + if (w16_decodedLen<=320) + { + /* Not quite long enough, so we have to cheat a bit... */ + WebRtcSpl_DownsampleFast( + &pw16_decoded[6], (WebRtc_Word16)320, + pw16_decodedLB, (WebRtc_Word16)(40), + (WebRtc_Word16*)WebRtcNetEQ_kDownsample48kHzTbl, (WebRtc_Word16)7, + (WebRtc_Word16)12, (WebRtc_Word16)0); + w16_tmp = ((w16_decodedLen-6)>>3); + WebRtcSpl_MemSetW16(&pw16_decodedLB[w16_tmp], 0, (40-w16_tmp)); + } + else + { + WebRtcSpl_DownsampleFast( + &pw16_decoded[6], (WebRtc_Word16)(w16_decodedLen-6), + pw16_decodedLB, (WebRtc_Word16)(40), + (WebRtc_Word16*)WebRtcNetEQ_kDownsample48kHzTbl, (WebRtc_Word16)7, + (WebRtc_Word16)12, (WebRtc_Word16)0); + } +#endif + } + + /* Calculate correlation without any normalization (40 samples) */ + w16_tmp = WebRtcSpl_DivW32W16ResW16((WebRtc_Word32) inst->ExpandInst.w16_maxLag, + (WebRtc_Word16) (fs_mult * 2)) + 1; + w16_stopPos = WEBRTC_SPL_MIN(60, w16_tmp); + w32_tmp = WEBRTC_SPL_MUL_16_16(w16_expmax, w16_newmax); + if (w32_tmp > 26843546) + { + w16_tmp = 3; + } + else + { + w16_tmp = 0; + } + + WebRtcNetEQ_CrossCorr(pw32_corr, pw16_decodedLB, pw16_expandedLB, 40, + (WebRtc_Word16) w16_stopPos, w16_tmp, 1); + + /* Normalize correlation to 14 bits and put in a WebRtc_Word16 vector */ + WebRtcSpl_MemSetW16(pw16_corrVec, 0, (4 + 60 + 4)); + w32_tmp = WebRtcSpl_MaxAbsValueW32(pw32_corr, w16_stopPos); + w16_tmp = 17 - WebRtcSpl_NormW32(w32_tmp); + w16_tmp = WEBRTC_SPL_MAX(0, w16_tmp); + + WebRtcSpl_VectorBitShiftW32ToW16(pw16_corr, w16_stopPos, pw32_corr, w16_tmp); + + /* Calculate allowed starting point for peak finding. + The peak location bestIndex must fulfill two criteria: + (1) w16_bestIndex+w16_decodedLen < inst->timestampsPerCall+inst->ExpandInst.w16_overlap + (2) w16_bestIndex+w16_decodedLen < w16_startPos */ + w16_tmp = WEBRTC_SPL_MAX(0, WEBRTC_SPL_MAX(w16_startPos, + inst->timestampsPerCall+inst->ExpandInst.w16_overlap) - w16_decodedLen); + /* Downscale starting index to 4kHz domain */ + w16_tmp2 = WebRtcSpl_DivW32W16ResW16((WebRtc_Word32) w16_tmp, + (WebRtc_Word16) (fs_mult << 1)); + +#ifdef NETEQ_STEREO + } /* end if (msInfo->msMode != NETEQ_SLAVE) */ + + if ((msInfo->msMode == NETEQ_MASTER) || (msInfo->msMode == NETEQ_MONO)) + { + /* This is master or mono instance; find peak */ + WebRtcNetEQ_PeakDetection(&pw16_corr[w16_tmp2], w16_stopPos, 1, fs_mult, &w16_bestIndex, + &w16_bestVal); + w16_bestIndex += w16_tmp; /* compensate for modified starting index */ + msInfo->bestIndex = w16_bestIndex; + } + else if (msInfo->msMode == NETEQ_SLAVE) + { + /* Get peak location from master instance */ + w16_bestIndex = msInfo->bestIndex; + } + else + { + /* Invalid mode */ + return MASTER_SLAVE_ERROR; + } + +#else /* NETEQ_STEREO */ + + /* Find peak */ + WebRtcNetEQ_PeakDetection(&pw16_corr[w16_tmp2], w16_stopPos, 1, fs_mult, &w16_bestIndex, + &w16_bestVal); + w16_bestIndex += w16_tmp; /* compensate for modified starting index */ + +#endif /* NETEQ_STEREO */ + + /* + * Ensure that underrun does not occur for 10ms case => we have to get at least + * 10ms + overlap . (This should never happen thanks to the above modification of + * peak-finding starting point.) + * */ + while ((w16_bestIndex + w16_decodedLen) < (inst->timestampsPerCall + + inst->ExpandInst.w16_overlap) || w16_bestIndex + w16_decodedLen < w16_startPos) + { + w16_bestIndex += w16_newLen; /* Jump one lag ahead */ + } + pw16_decodedOut = pw16_outData + w16_bestIndex; + + /* Mute the new decoded data if needed (and unmute it linearly) */ + w16_interpLen = WEBRTC_SPL_MIN(60*fs_mult, + w16_expandedLen-w16_bestIndex); /* this is the overlapping part of pw16_expanded */ + w16_interpLen = WEBRTC_SPL_MIN(w16_interpLen, w16_decodedLen); + w16_inc = WebRtcSpl_DivW32W16ResW16(4194, + fs_mult); /* in Q20, 0.004 for NB and 0.002 for WB */ + if (inst->w16_muteFactor < 16384) + { + WebRtcNetEQ_UnmuteSignal(pw16_decoded, &inst->w16_muteFactor, pw16_decoded, w16_inc, + (WebRtc_Word16) w16_interpLen); + WebRtcNetEQ_UnmuteSignal(&pw16_decoded[w16_interpLen], &inst->w16_muteFactor, + &pw16_decodedOut[w16_interpLen], w16_inc, + (WebRtc_Word16) (w16_decodedLen - w16_interpLen)); + } + else + { + /* No muting needed */ + + WEBRTC_SPL_MEMMOVE_W16(&pw16_decodedOut[w16_interpLen], &pw16_decoded[w16_interpLen], + (w16_decodedLen-w16_interpLen)); + } + + /* Do overlap and interpolate linearly */ + w16_inc = WebRtcSpl_DivW32W16ResW16(16384, (WebRtc_Word16) (w16_interpLen + 1)); /* Q14 */ + w16_startfact = (16384 - w16_inc); + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_expanded, w16_bestIndex); + WebRtcNetEQ_MixVoiceUnvoice(pw16_decodedOut, &pw16_expanded[w16_bestIndex], pw16_decoded, + &w16_startfact, w16_inc, w16_interpLen); + + inst->w16_mode = MODE_MERGE; + inst->ExpandInst.w16_consecExp = 0; /* Last was not expand any more */ + + /* New added length (w16_startPos samples were borrowed) */ + *pw16_len = w16_bestIndex + w16_decodedLen - w16_startPos; + + /* Update VQmon parameter */ + inst->w16_concealedTS += (*pw16_len - w16_decodedLen); + inst->w16_concealedTS = WEBRTC_SPL_MAX(0, inst->w16_concealedTS); + + /* Update in-call and post-call statistics */ + if (inst->ExpandInst.w16_expandMuteFactor == 0) + { + /* expansion generates noise only */ + inst->statInst.expandedNoiseSamples += (*pw16_len - w16_decodedLen); + } + else + { + /* expansion generates more than only noise */ + inst->statInst.expandedVoiceSamples += (*pw16_len - w16_decodedLen); + } + inst->statInst.expandLength += (*pw16_len - w16_decodedLen); + + + /* Copy back the first part of the data to the speechHistory */ + + WEBRTC_SPL_MEMCPY_W16(&inst->speechBuffer[inst->curPosition], pw16_outData, w16_startPos); + + + /* Move data to within outData */ + + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, &pw16_outData[w16_startPos], (*pw16_len)); + + return 0; +} + +#undef SCRATCH_pw16_expanded +#undef SCRATCH_pw16_expandedLB +#undef SCRATCH_pw16_decodedLB +#undef SCRATCH_pw32_corr +#undef SCRATCH_pw16_corrVec +#undef SCRATCH_NETEQ_EXPAND diff --git a/src/libs/webrtc/neteq/min_distortion.c b/src/libs/webrtc/neteq/min_distortion.c new file mode 100644 index 00000000..4c9ee1cd --- /dev/null +++ b/src/libs/webrtc/neteq/min_distortion.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Calculate best overlap fit according to distortion measure. + */ + +#include "dsp_helpfunctions.h" + +#include "signal_processing_library.h" + +WebRtc_Word16 WebRtcNetEQ_MinDistortion(const WebRtc_Word16 *pw16_data, + WebRtc_Word16 w16_minLag, WebRtc_Word16 w16_maxLag, + WebRtc_Word16 len, WebRtc_Word32 *pw16_dist) +{ + int i, j; + const WebRtc_Word16 *pw16_data1; + const WebRtc_Word16 *pw16_data2; + WebRtc_Word32 w32_diff; + WebRtc_Word32 w32_sumdiff; + WebRtc_Word16 bestIndex = -1; + WebRtc_Word32 minDist = WEBRTC_SPL_WORD32_MAX; + + for (i = w16_minLag; i <= w16_maxLag; i++) + { + w32_sumdiff = 0; + pw16_data1 = pw16_data; + pw16_data2 = pw16_data - i; + + for (j = 0; j < len; j++) + { + w32_diff = pw16_data1[j] - pw16_data2[j]; + w32_sumdiff += WEBRTC_SPL_ABS_W32(w32_diff); + } + + /* Compare with previous minimum */ + if (w32_sumdiff < minDist) + { + minDist = w32_sumdiff; + bestIndex = i; + } + } + + *pw16_dist = minDist; + + return bestIndex; +} + diff --git a/src/libs/webrtc/neteq/mix_voice_unvoice.c b/src/libs/webrtc/neteq/mix_voice_unvoice.c new file mode 100644 index 00000000..98956307 --- /dev/null +++ b/src/libs/webrtc/neteq/mix_voice_unvoice.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This function mixes a voiced signal with an unvoiced signal and + * updates the weight on a sample by sample basis. + */ + +#include "dsp_helpfunctions.h" + +#include "signal_processing_library.h" + +void WebRtcNetEQ_MixVoiceUnvoice(WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_voicedVec, + WebRtc_Word16 *pw16_unvoicedVec, + WebRtc_Word16 *w16_current_vfraction, + WebRtc_Word16 w16_vfraction_change, WebRtc_Word16 N) +{ + int i; + WebRtc_Word16 w16_tmp2; + WebRtc_Word16 vfraction = *w16_current_vfraction; + + w16_tmp2 = 16384 - vfraction; + for (i = 0; i < N; i++) + { + pw16_outData[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32( + WEBRTC_SPL_MUL_16_16(vfraction, pw16_voicedVec[i]) + + WEBRTC_SPL_MUL_16_16(w16_tmp2, pw16_unvoicedVec[i]) + 8192, + 14); + vfraction -= w16_vfraction_change; + w16_tmp2 += w16_vfraction_change; + } + *w16_current_vfraction = vfraction; +} + diff --git a/src/libs/webrtc/neteq/mute_signal.c b/src/libs/webrtc/neteq/mute_signal.c new file mode 100644 index 00000000..ee899cf2 --- /dev/null +++ b/src/libs/webrtc/neteq/mute_signal.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This function mutes a signal linearly on a sample by sample basis. + */ + +#include "dsp_helpfunctions.h" + +#include "signal_processing_library.h" + +void WebRtcNetEQ_MuteSignal(WebRtc_Word16 *pw16_inout, WebRtc_Word16 muteSlope, + WebRtc_Word16 N) +{ + int i; + WebRtc_Word32 w32_tmp = 1048608; /* (16384<<6 + 32) */ + + for (i = 0; i < N; i++) + { + pw16_inout[i] + = (WebRtc_Word16) ((WEBRTC_SPL_MUL_16_16((WebRtc_Word16)(w32_tmp>>6), pw16_inout[i]) + + 8192) >> 14); + w32_tmp -= muteSlope; + } +} + diff --git a/src/libs/webrtc/neteq/neteq.gyp b/src/libs/webrtc/neteq/neteq.gyp new file mode 100644 index 00000000..a31fece4 --- /dev/null +++ b/src/libs/webrtc/neteq/neteq.gyp @@ -0,0 +1,301 @@ +# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +{ + 'includes': [ + '../../../../../common_settings.gypi', # Common settings + ], + 'targets': [ + { + 'target_name': 'NetEq', + 'type': '<(library)', + 'dependencies': [ + '../../../codecs/CNG/main/source/cng.gyp:CNG', + '../../../../../common_audio/signal_processing_library/main/source/spl.gyp:spl', + ], + 'defines': [ + 'NETEQ_VOICEENGINE_CODECS', # TODO: Should create a Chrome define which specifies a subset of codecs to support + 'SCRATCH', + ], + 'include_dirs': [ + '../interface', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '../interface', + ], + }, + 'sources': [ + '../interface/webrtc_neteq.h', + '../interface/webrtc_neteq_help_macros.h', + '../interface/webrtc_neteq_internal.h', + 'accelerate.c', + 'automode.c', + 'automode.h', + 'bgn_update.c', + 'buffer_stats.h', + 'bufstats_decision.c', + 'cng_internal.c', + 'codec_db.c', + 'codec_db.h', + 'codec_db_defines.h', + 'correlator.c', + 'delay_logging.h', + 'dsp.c', + 'dsp.h', + 'dsp_helpfunctions.c', + 'dsp_helpfunctions.h', + 'dtmf_buffer.c', + 'dtmf_buffer.h', + 'dtmf_tonegen.c', + 'dtmf_tonegen.h', + 'expand.c', + 'mcu.h', + 'mcu_address_init.c', + 'mcu_dsp_common.c', + 'mcu_dsp_common.h', + 'mcu_reset.c', + 'merge.c', + 'min_distortion.c', + 'mix_voice_unvoice.c', + 'mute_signal.c', + 'neteq_defines.h', + 'neteq_error_codes.h', + 'neteq_statistics.h', + 'normal.c', + 'packet_buffer.c', + 'packet_buffer.h', + 'peak_detection.c', + 'preemptive_expand.c', + 'random_vector.c', + 'recin.c', + 'recout.c', + 'rtcp.c', + 'rtcp.h', + 'rtp.c', + 'rtp.h', + 'set_fs.c', + 'signal_mcu.c', + 'split_and_insert.c', + 'unmute_signal.c', + 'webrtc_neteq.c', + ], + }, + { + 'target_name': 'NetEqRTPplay', + 'type': 'executable', + 'dependencies': [ + 'NetEq', # NetEQ library defined above + 'NetEqTestTools',# Test helpers + '../../../codecs/G711/main/source/g711.gyp:G711', + '../../../codecs/G722/main/source/g722.gyp:G722', + '../../../codecs/PCM16B/main/source/pcm16b.gyp:PCM16B', + '../../../codecs/iLBC/main/source/ilbc.gyp:iLBC', + '../../../codecs/iSAC/main/source/isac.gyp:iSAC', + '../../../codecs/CNG/main/source/cng.gyp:CNG', + ], + 'defines': [ + # TODO: Make codec selection conditional on definitions in target NetEq + 'CODEC_ILBC', + 'CODEC_PCM16B', + 'CODEC_G711', + 'CODEC_G722', + 'CODEC_ISAC', + 'CODEC_PCM16B_WB', + 'CODEC_ISAC_SWB', + 'CODEC_PCM16B_32KHZ', + 'CODEC_CNGCODEC8', + 'CODEC_CNGCODEC16', + 'CODEC_CNGCODEC32', + 'CODEC_ATEVENT_DECODE', + 'CODEC_RED', + ], + 'include_dirs': [ + '../source', + '../test', + ], + 'sources': [ + '../test/NetEqRTPplay.cc', + ], + }, + { + 'target_name': 'RTPencode', + 'type': 'executable', + 'dependencies': [ + 'NetEqTestTools',# Test helpers + '../../../codecs/G711/main/source/g711.gyp:G711', + '../../../codecs/G722/main/source/g722.gyp:G722', + '../../../codecs/PCM16B/main/source/pcm16b.gyp:PCM16B', + '../../../codecs/iLBC/main/source/ilbc.gyp:iLBC', + '../../../codecs/iSAC/main/source/isac.gyp:iSAC', + '../../../codecs/CNG/main/source/cng.gyp:CNG', + '../../../../../common_audio/vad/main/source/vad.gyp:vad', + ], + 'defines': [ + # TODO: Make codec selection conditional on definitions in target NetEq + 'CODEC_ILBC', + 'CODEC_PCM16B', + 'CODEC_G711', + 'CODEC_G722', + 'CODEC_ISAC', + 'CODEC_PCM16B_WB', + 'CODEC_ISAC_SWB', + 'CODEC_PCM16B_32KHZ', + 'CODEC_CNGCODEC8', + 'CODEC_CNGCODEC16', + 'CODEC_CNGCODEC32', + 'CODEC_ATEVENT_DECODE', + 'CODEC_RED', + ], + 'include_dirs': [ + '../interface', + '../test', + ], + 'sources': [ + '../test/RTPencode.cc', + ], + }, + + { + 'target_name': 'RTPjitter', + 'type': 'executable', + 'dependencies': [ + ], + 'defines': [ + ], + 'include_dirs': [ + ], + 'sources': [ + '../test/RTPjitter.cc', + ], + }, + + { + 'target_name': 'RTPanalyze', + 'type': 'executable', + 'dependencies': [ + 'NetEqTestTools', + ], + 'defines': [ + ], + 'include_dirs': [ + ], + 'sources': [ + '../test/RTPanalyze.cc', + ], + }, + + { + 'target_name': 'RTPchange', + 'type': 'executable', + 'dependencies': [ + 'NetEqTestTools', + ], + 'defines': [ + ], + 'include_dirs': [ + ], + 'sources': [ + '../test/RTPchange.cc', + ], + }, + + { + 'target_name': 'RTPtimeshift', + 'type': 'executable', + 'dependencies': [ + 'NetEqTestTools', + ], + 'defines': [ + ], + 'include_dirs': [ + ], + 'sources': [ + '../test/RTPtimeshift.cc', + ], + }, + + { + 'target_name': 'RTPcat', + 'type': 'executable', + 'dependencies': [ + 'NetEqTestTools', + ], + 'defines': [ + ], + 'include_dirs': [ + ], + 'sources': [ + '../test/RTPcat.cc', + ], + }, + + { + 'target_name': 'NetEqTestTools', + # Collection of useful functions used in other tests + 'type': '<(library)', + 'dependencies': [ + '../../../codecs/G711/main/source/g711.gyp:G711', + '../../../codecs/G722/main/source/g722.gyp:G722', + '../../../codecs/PCM16B/main/source/pcm16b.gyp:PCM16B', + '../../../codecs/iLBC/main/source/ilbc.gyp:iLBC', + '../../../codecs/iSAC/main/source/isac.gyp:iSAC', + '../../../codecs/CNG/main/source/cng.gyp:CNG', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '../test', + '../interface', + ], + }, + 'defines': [ + # TODO: Make codec selection conditional on definitions in target NetEq + 'CODEC_ILBC', + 'CODEC_PCM16B', + 'CODEC_G711', + 'CODEC_G722', + 'CODEC_ISAC', + 'CODEC_PCM16B_WB', + 'CODEC_ISAC_SWB', + 'CODEC_PCM16B_32KHZ', + 'CODEC_CNGCODEC8', + 'CODEC_CNGCODEC16', + 'CODEC_CNGCODEC32', + 'CODEC_ATEVENT_DECODE', + 'CODEC_RED', + ], + 'include_dirs': [ + '../source', + '../interface', + '../test', + ], + 'sources': [ + '../test/NETEQTEST_NetEQClass.cc', + '../test/NETEQTEST_RTPpacket.cc', + '../test/NETEQTEST_CodecClass.cc', + '../test/NETEQTEST_NetEQClass.h', + '../test/NETEQTEST_RTPpacket.h', + '../test/NETEQTEST_CodecClass.h', + ], + 'conditions': [ + ['OS=="linux"', { + 'cflags': [ + '-fexceptions', # enable exceptions + ], + }], + ], + }, + + ], +} + +# Local Variables: +# tab-width:2 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/src/libs/webrtc/neteq/neteq_defines.h b/src/libs/webrtc/neteq/neteq_defines.h new file mode 100644 index 00000000..83dae691 --- /dev/null +++ b/src/libs/webrtc/neteq/neteq_defines.h @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* Enable stereo */ +//#define NETEQ_STEREO +#define NETEQ_WIDEBAND +#define NETEQ_G711_CODEC +//#define NETEQ_CNG_CODEC +/***************************************************************************************** + * + * Compilation flags in NetEQ: + * + ***************************************************************************************** + * + ***** Platform flags ****** + * + * SCRATCH Run NetEQ with "Scratch memory" to save some stack memory. + * Definition can be used on all platforms + * + ***** Summary flags ****** + * + * NETEQ_ALL_SPECIAL_CODECS Add support for special codecs (CN/RED/DTMF) + * + * NETEQ_ALL_NB_CODECS Add support for all NB codecs (except CN/RED/DTMF) + * + * NETEQ_ALL_WB_CODECS Add support for all WB codecs (except CN/RED/DTMF) + * + * NETEQ_VOICEENGINE_CODECS Support for all NB, WB and SWB32 codecs and CN, RED and DTMF + * + * NETEQ_ALL_CODECS Support for all NB, WB, SWB 32kHz and SWB 48kHz as well as + * CN, RED and DTMF + * + ***** Sampling frequency ****** + * (Note: usually not needed when Summary flags are used) + * + * NETEQ_WIDEBAND Wideband enabled + * + * NETEQ_32KHZ_WIDEBAND Super wideband @ 32kHz enabled + * + * NETEQ_48KHZ_WIDEBAND Super wideband @ 48kHz enabled + * + ***** Special Codec ****** + * (Note: not needed if NETEQ_ALL_CODECS is used) + * + * NETEQ_RED_CODEC With this flag you enable NetEQ to understand redundancy in + * the RTP. NetEQ will use the redundancy if it's the same + * codec + * + * NETEQ_CNG_CODEC Enable DTX with the CN payload + * + * NETEQ_ATEVENT_DECODE Enable AVT event and play out the corresponding DTMF tone + * + ***** Speech Codecs ***** + * (Note: Not needed if Summary flags are used) + * + * NETEQ_G711_CODEC Enable G.711 u- and A-law + * + * NETEQ_PCM16B_CODEC Enable uncompressed 16-bit + * + * NETEQ_ILBC_CODEC Enable iLBC + * + * NETEQ_ISAC_CODEC Enable iSAC + * + * NETEQ_ISAC_SWB_CODEC Enable iSAC-SWB + * + * NETEQ_G722_CODEC Enable G.722 + * + * NETEQ_G729_CODEC Enable G.729 + * + * NETEQ_G729_1_CODEC Enable G.729.1 + * + * NETEQ_G726_CODEC Enable G.726 + * + * NETEQ_G722_1_CODEC Enable G722.1 + * + * NETEQ_G722_1C_CODEC Enable G722.1 Annex C + * + * NETEQ_SPEEX_CODEC Enable Speex (at 8 and 16 kHz sample rate) + * + * NETEQ_GSMFR_CODEC Enable GSM-FR + * + * NETEQ_AMR_CODEC Enable AMR (narrowband) + * + * NETEQ_AMRWB_CODEC Enable AMR-WB + * + * NETEQ_CNG_CODEC Enable DTX with the CNG payload + * + * NETEQ_ATEVENT_DECODE Enable AVT event and play out the corresponding DTMF tone + * + ***** Test flags ****** + * + * WEBRTC_NETEQ_40BITACC_TEST Run NetEQ with simulated 40-bit accumulator to run + * bit-exact to a DSP implementation where the main (splib + * and NetEQ) functions have been 40-bit optimized + * + ***************************************************************************************** + */ + +#if !defined NETEQ_DEFINES_H +#define NETEQ_DEFINES_H + +/* Data block structure for MCU to DSP communication: + * + * + * First 3 16-bit words are pre-header that contains instructions and timestamp update + * Fourth 16-bit word is length of data block 1 + * Rest is payload data + * + * 0 48 64 80 + * -------------...---------------------------------------------------------------------- + * | PreHeader ... | Length 1 | Payload data 1 ...... | Lenght 2| Data block 2.... | ... + * -------------...---------------------------------------------------------------------- + * + * + * Preheader: + * 4 MSB can be either of: + */ + +#define DSP_INSTR_NORMAL 0x1000 +/* Payload data will contain the encoded frames */ + +#define DSP_INSTR_MERGE 0x2000 +/* Payload data block 1 will contain the encoded frame */ +/* Info block will contain the number of missing samples */ + +#define DSP_INSTR_EXPAND 0x3000 +/* Payload data will be empty */ + +#define DSP_INSTR_ACCELERATE 0x4000 +/* Payload data will contain the encoded frame */ + +#define DSP_INSTR_DO_RFC3389CNG 0x5000 +/* Payload data will contain the SID frame if there is one*/ + +#define DSP_INSTR_DTMF_GENERATE 0x6000 +/* Payload data will be one WebRtc_Word16 with the current DTMF value and one + * WebRtc_Word16 with the current volume value + */ +#define DSP_INSTR_NORMAL_ONE_DESC 0x7000 +/* No encoded frames */ + +#define DSP_INSTR_DO_CODEC_INTERNAL_CNG 0x8000 +/* Codec has a built-in VAD/DTX scheme (use the above for "no transmission") */ + +#define DSP_INSTR_PREEMPTIVE_EXPAND 0x9000 +/* Payload data will contain the encoded frames, if any */ + +#define DSP_INSTR_DO_ALTERNATIVE_PLC 0xB000 +/* NetEQ switched off and packet missing... */ + +#define DSP_INSTR_DO_ALTERNATIVE_PLC_INC_TS 0xC000 +/* NetEQ switched off and packet missing... */ + +#define DSP_INSTR_DO_AUDIO_REPETITION 0xD000 +/* NetEQ switched off and packet missing... */ + +#define DSP_INSTR_DO_AUDIO_REPETITION_INC_TS 0xE000 +/* NetEQ switched off and packet missing... */ + +#define DSP_INSTR_FADE_TO_BGN 0xF000 +/* Exception handling: fade out to BGN (expand) */ + +/* + * Next 4 bits signal additional data that needs to be transmitted + */ + +#define DSP_CODEC_NO_CHANGE 0x0100 +#define DSP_CODEC_NEW_CODEC 0x0200 +#define DSP_CODEC_ADD_LATE_PKT 0x0300 +#define DSP_CODEC_RESET 0x0400 +#define DSP_DTMF_PAYLOAD 0x0010 + +/* + * The most significant bit of the payload-length + * is used to flag whether the associated payload + * is redundant payload. This currently useful only for + * iSAC, where redundant payloads have to be treated + * differently. Every time the length is read it must be + * masked by DSP_CODEC_MASK_RED_FLAG to ignore the flag. + * Use DSP_CODEC_RED_FLAG to set or retrieve the flag. + */ +#define DSP_CODEC_MASK_RED_FLAG 0x7FFF +#define DSP_CODEC_RED_FLAG 0x8000 + +/* + * The first block of payload data consist of decode function pointers, + * and then the speech blocks. + * + */ + + +/* + * The playout modes that NetEq produced (i.e. gives more info about if the + * Accelerate was successful or not) + */ + +#define MODE_NORMAL 0x0000 +#define MODE_EXPAND 0x0001 +#define MODE_MERGE 0x0002 +#define MODE_SUCCESS_ACCELERATE 0x0003 +#define MODE_UNSUCCESS_ACCELERATE 0x0004 +#define MODE_RFC3389CNG 0x0005 +#define MODE_LOWEN_ACCELERATE 0x0006 +#define MODE_DTMF 0x0007 +#define MODE_ONE_DESCRIPTOR 0x0008 +#define MODE_CODEC_INTERNAL_CNG 0x0009 +#define MODE_SUCCESS_PREEMPTIVE 0x000A +#define MODE_UNSUCCESS_PREEMPTIVE 0x000B +#define MODE_LOWEN_PREEMPTIVE 0x000C +#define MODE_FADE_TO_BGN 0x000D + +#define MODE_ERROR 0x0010 + +#define MODE_AWAITING_CODEC_PTR 0x0100 + +#define MODE_BGN_ONLY 0x0200 + +#define MODE_MASTER_DTMF_SIGNAL 0x0400 + +#define MODE_USING_STEREO 0x0800 + + + +/***********************/ +/* Group codec defines */ +/***********************/ + +#if (defined(NETEQ_ALL_SPECIAL_CODECS)) + #define NETEQ_CNG_CODEC + #define NETEQ_ATEVENT_DECODE + #define NETEQ_RED_CODEC + #define NETEQ_VAD + #define NETEQ_ARBITRARY_CODEC +#endif + +#if (defined(NETEQ_ALL_NB_CODECS)) /* Except RED, DTMF and CNG */ + #define NETEQ_PCM16B_CODEC + #define NETEQ_G711_CODEC + #define NETEQ_ILBC_CODEC + #define NETEQ_G729_CODEC + #define NETEQ_G726_CODEC + #define NETEQ_GSMFR_CODEC + #define NETEQ_AMR_CODEC +#endif + +#if (defined(NETEQ_ALL_WB_CODECS)) /* Except RED, DTMF and CNG */ + #define NETEQ_ISAC_CODEC + #define NETEQ_G722_CODEC + #define NETEQ_G722_1_CODEC + #define NETEQ_G729_1_CODEC + #define NETEQ_SPEEX_CODEC + #define NETEQ_AMRWB_CODEC + #define NETEQ_WIDEBAND +#endif + +#if (defined(NETEQ_ALL_WB32_CODECS)) /* AAC, RED, DTMF and CNG */ + #define NETEQ_ISAC_SWB_CODEC + #define NETEQ_32KHZ_WIDEBAND + #define NETEQ_G722_1C_CODEC +#endif + +#if (defined(NETEQ_VOICEENGINE_CODECS)) + /* Special codecs */ + #define NETEQ_CNG_CODEC + #define NETEQ_ATEVENT_DECODE + #define NETEQ_RED_CODEC + #define NETEQ_VAD + #define NETEQ_ARBITRARY_CODEC + + /* Narrowband codecs */ + #define NETEQ_PCM16B_CODEC + #define NETEQ_G711_CODEC + #define NETEQ_ILBC_CODEC + + /* Wideband codecs */ + #define NETEQ_WIDEBAND + #define NETEQ_ISAC_CODEC + #define NETEQ_G722_CODEC + + /* Super wideband 32kHz codecs */ + #define NETEQ_ISAC_SWB_CODEC + #define NETEQ_32KHZ_WIDEBAND + +#endif + +#if (defined(NETEQ_ALL_CODECS)) + /* Special codecs */ + #define NETEQ_CNG_CODEC + #define NETEQ_ATEVENT_DECODE + #define NETEQ_RED_CODEC + #define NETEQ_VAD + #define NETEQ_ARBITRARY_CODEC + + /* Narrowband codecs */ + #define NETEQ_PCM16B_CODEC + #define NETEQ_G711_CODEC + #define NETEQ_ILBC_CODEC + #define NETEQ_G729_CODEC + #define NETEQ_G726_CODEC + #define NETEQ_GSMFR_CODEC + #define NETEQ_AMR_CODEC + + /* Wideband codecs */ + #define NETEQ_WIDEBAND + #define NETEQ_ISAC_CODEC + #define NETEQ_G722_CODEC + #define NETEQ_G722_1_CODEC + #define NETEQ_G729_1_CODEC + #define NETEQ_SPEEX_CODEC + #define NETEQ_AMRWB_CODEC + + /* Super wideband 32kHz codecs */ + #define NETEQ_ISAC_SWB_CODEC + #define NETEQ_32KHZ_WIDEBAND + #define NETEQ_G722_1C_CODEC + + /* Super wideband 48kHz codecs */ + #define NETEQ_48KHZ_WIDEBAND +#endif + +/* Max output size from decoding one frame */ +#if defined(NETEQ_48KHZ_WIDEBAND) + #define NETEQ_MAX_FRAME_SIZE 2880 /* 60 ms super wideband */ + #define NETEQ_MAX_OUTPUT_SIZE 3600 /* 60+15 ms super wideband (60 ms decoded + 15 ms for merge overlap) */ +#elif defined(NETEQ_32KHZ_WIDEBAND) + #define NETEQ_MAX_FRAME_SIZE 1920 /* 60 ms super wideband */ + #define NETEQ_MAX_OUTPUT_SIZE 2400 /* 60+15 ms super wideband (60 ms decoded + 15 ms for merge overlap) */ +#elif defined(NETEQ_WIDEBAND) + #define NETEQ_MAX_FRAME_SIZE 960 /* 60 ms wideband */ + #define NETEQ_MAX_OUTPUT_SIZE 1200 /* 60+15 ms wideband (60 ms decoded + 10 ms for merge overlap) */ +#else + #define NETEQ_MAX_FRAME_SIZE 480 /* 60 ms narrowband */ + #define NETEQ_MAX_OUTPUT_SIZE 600 /* 60+15 ms narrowband (60 ms decoded + 10 ms for merge overlap) */ +#endif + + + +#endif /* #if !defined NETEQ_DEFINES_H */ + diff --git a/src/libs/webrtc/neteq/neteq_error_codes.h b/src/libs/webrtc/neteq/neteq_error_codes.h new file mode 100644 index 00000000..1ce46809 --- /dev/null +++ b/src/libs/webrtc/neteq/neteq_error_codes.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Definition of error codes. + * + * NOTE: When modifying the error codes, + * also modify the function WebRtcNetEQ_GetErrorCode! + */ + +#if !defined NETEQ_ERROR_CODES_H +#define NETEQ_ERROR_CODES_H + +/* Misc Error */ +#define NETEQ_OTHER_ERROR -1000 + +/* Misc Recout Errors */ +#define FAULTY_INSTRUCTION -1001 +#define FAULTY_NETWORK_TYPE -1002 +#define FAULTY_DELAYVALUE -1003 +#define FAULTY_PLAYOUTMODE -1004 +#define CORRUPT_INSTANCE -1005 +#define ILLEGAL_MASTER_SLAVE_SWITCH -1006 +#define MASTER_SLAVE_ERROR -1007 + +/* Misc Recout problems */ +#define UNKNOWN_BUFSTAT_DECISION -2001 +#define RECOUT_ERROR_DECODING -2002 +#define RECOUT_ERROR_SAMPLEUNDERRUN -2003 +#define RECOUT_ERROR_DECODED_TOO_MUCH -2004 + +/* Misc RecIn problems */ +#define RECIN_CNG_ERROR -3001 +#define RECIN_UNKNOWNPAYLOAD -3002 +#define RECIN_BUFFERINSERT_ERROR -3003 + +/* PBUFFER/BUFSTAT ERRORS */ +#define PBUFFER_INIT_ERROR -4001 +#define PBUFFER_INSERT_ERROR1 -4002 +#define PBUFFER_INSERT_ERROR2 -4003 +#define PBUFFER_INSERT_ERROR3 -4004 +#define PBUFFER_INSERT_ERROR4 -4005 +#define PBUFFER_INSERT_ERROR5 -4006 +#define UNKNOWN_G723_HEADER -4007 +#define PBUFFER_NONEXISTING_PACKET -4008 +#define PBUFFER_NOT_INITIALIZED -4009 +#define AMBIGUOUS_ILBC_FRAME_SIZE -4010 + +/* CODEC DATABASE ERRORS */ +#define CODEC_DB_FULL -5001 +#define CODEC_DB_NOT_EXIST1 -5002 +#define CODEC_DB_NOT_EXIST2 -5003 +#define CODEC_DB_NOT_EXIST3 -5004 +#define CODEC_DB_NOT_EXIST4 -5005 +#define CODEC_DB_UNKNOWN_CODEC -5006 +#define CODEC_DB_PAYLOAD_TAKEN -5007 +#define CODEC_DB_UNSUPPORTED_CODEC -5008 +#define CODEC_DB_UNSUPPORTED_FS -5009 + +/* DTMF ERRORS */ +#define DTMF_DEC_PARAMETER_ERROR -6001 +#define DTMF_INSERT_ERROR -6002 +#define DTMF_GEN_UNKNOWN_SAMP_FREQ -6003 +#define DTMF_NOT_SUPPORTED -6004 + +/* RTP/PACKET ERRORS */ +#define RED_SPLIT_ERROR1 -7001 +#define RED_SPLIT_ERROR2 -7002 +#define RTP_TOO_SHORT_PACKET -7003 +#define RTP_CORRUPT_PACKET -7004 + +#endif diff --git a/src/libs/webrtc/neteq/neteq_statistics.h b/src/libs/webrtc/neteq/neteq_statistics.h new file mode 100644 index 00000000..5a68ec3b --- /dev/null +++ b/src/libs/webrtc/neteq/neteq_statistics.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Definitions of statistics data structures for MCU and DSP sides. + */ + +#include "typedefs.h" + +#ifndef NETEQ_STATISTICS_H +#define NETEQ_STATISTICS_H + +/* + * Statistics struct on DSP side + */ +typedef struct +{ + + /* variables for in-call statistics; queried through WebRtcNetEQ_GetNetworkStatistics */ + WebRtc_UWord32 expandLength; /* number of samples produced through expand */ + WebRtc_UWord32 preemptiveLength; /* number of samples produced through pre-emptive + expand */ + WebRtc_UWord32 accelerateLength; /* number of samples removed through accelerate */ + + /* variables for post-call statistics; queried through WebRtcNetEQ_GetJitterStatistics */ + WebRtc_UWord32 expandedVoiceSamples; /* number of voice samples produced through expand */ + WebRtc_UWord32 expandedNoiseSamples; /* number of noise (background) samples produced + through expand */ + +} DSPStats_t; + +/* + * Statistics struct on MCU side + * All variables are for post-call statistics; queried through WebRtcNetEQ_GetJitterStatistics. + */ +typedef struct +{ + + WebRtc_UWord32 jbMinSize; /* smallest Jitter Buffer size during call in ms */ + WebRtc_UWord32 jbMaxSize; /* largest Jitter Buffer size during call in ms */ + WebRtc_UWord32 jbAvgSizeQ16; /* the average JB size, measured over time in ms (Q16) */ + WebRtc_UWord16 jbAvgCount; /* help counter for jbAveSize */ + WebRtc_UWord32 minPacketDelayMs; /* min time incoming packet "waited" to be played in ms */ + WebRtc_UWord32 maxPacketDelayMs; /* max time incoming packet "waited" to be played in ms */ + WebRtc_UWord16 avgPacketDelayMs; /* avg time incoming packet "waited" to be played in ms */ + WebRtc_UWord16 avgPacketCount; /* help counter for avgPacketDelayMs */ + WebRtc_UWord32 jbChangeCount; /* count number of successful accelerate and pre-emptive + expand operations */ + WebRtc_UWord32 generatedSilentMs; /* generated silence in ms */ + WebRtc_UWord32 countExpandMoreThan120ms; /* count of tiny expansions */ + WebRtc_UWord32 countExpandMoreThan250ms; /* count of small expansions */ + WebRtc_UWord32 countExpandMoreThan500ms; /* count of medium expansions */ + WebRtc_UWord32 countExpandMoreThan2000ms; /* count of large expansions */ + WebRtc_UWord32 longestExpandDurationMs; /* duration of longest expansions in ms */ + WebRtc_UWord32 accelerateMs; /* audio data removed through accelerate in ms */ + +} MCUStats_t; + +#endif + diff --git a/src/libs/webrtc/neteq/normal.c b/src/libs/webrtc/neteq/normal.c new file mode 100644 index 00000000..c8650523 --- /dev/null +++ b/src/libs/webrtc/neteq/normal.c @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the function for handling "normal" speech operation. + */ +#include "dsp.h" + +#include "signal_processing_library.h" + +#include "dsp_helpfunctions.h" + +/* Scratch usage: + + Type Name size startpos endpos + WebRtc_Word16 pw16_expanded 125*fs/8000 0 125*fs/8000-1 + + func WebRtcNetEQ_Expand 40+370*fs/8000 125*fs/8000 39+495*fs/8000 + + Total: 40+495*fs/8000 + */ + +#define SCRATCH_PW16_EXPANDED 0 +#if (defined(NETEQ_48KHZ_WIDEBAND)) +#define SCRATCH_NETEQ_EXPAND 756 +#elif (defined(NETEQ_32KHZ_WIDEBAND)) +#define SCRATCH_NETEQ_EXPAND 504 +#elif (defined(NETEQ_WIDEBAND)) +#define SCRATCH_NETEQ_EXPAND 252 +#else /* NB */ +#define SCRATCH_NETEQ_EXPAND 126 +#endif + +/**************************************************************************** + * WebRtcNetEQ_Normal(...) + * + * This function has the possibility to modify data that is played out in Normal + * mode, for example adjust the gain of the signal. The length of the signal + * can not be changed. + * + * Input: + * - inst : NetEq instance, i.e. the user that requests more + * speech/audio data + * - scratchPtr : Pointer to scratch vector + * - decoded : Pointer to vector of new data from decoder + * (Vector contents may be altered by the function) + * - len : Number of input samples + * + * Output: + * - inst : Updated user information + * - outData : Pointer to a memory space where the output data + * should be stored + * - pw16_len : Pointer to variable where the number of samples + * produced will be written + * + * Return value : >=0 - Number of samples written to outData + * -1 - Error + */ + +int WebRtcNetEQ_Normal(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + WebRtc_Word16 *pw16_decoded, WebRtc_Word16 len, + WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_len) +{ + + int i; + WebRtc_Word16 fs_mult; + WebRtc_Word16 fs_shift; + WebRtc_Word32 w32_En_speech; + WebRtc_Word16 enLen; + WebRtc_Word16 w16_muted; + WebRtc_Word16 w16_inc, w16_frac; + WebRtc_Word16 w16_tmp; + WebRtc_Word32 w32_tmp; + + /* Sanity check */ + if (len < 0) + { + /* Cannot have negative length of input vector */ + return (-1); + } + + if (len == 0) + { + /* Still got some data to play => continue with the same mode */ + *pw16_len = len; + return (len); + } + + fs_mult = WebRtcSpl_DivW32W16ResW16(inst->fs, 8000); + fs_shift = 30 - WebRtcSpl_NormW32(fs_mult); /* Note that this is not "exact" for 48kHz */ + + /* + * Check if last RecOut call resulted in an Expand or a FadeToBGN. If so, we have to take + * care of some cross-fading and unmuting. + */ + if (inst->w16_mode == MODE_EXPAND || inst->w16_mode == MODE_FADE_TO_BGN) + { + + /* Define memory where temporary result from Expand algorithm can be stored. */ +#ifdef SCRATCH + WebRtc_Word16 *pw16_expanded = pw16_scratchPtr + SCRATCH_PW16_EXPANDED; +#else + WebRtc_Word16 pw16_expanded[FSMULT * 125]; +#endif + WebRtc_Word16 expandedLen = 0; + WebRtc_Word16 w16_decodedMax; + + /* Find largest value in new data */ + w16_decodedMax = WebRtcSpl_MaxAbsValueW16(pw16_decoded, (WebRtc_Word16) len); + + /* Generate interpolation data using Expand */ + /* First, set Expand parameters to appropriate values. */ + inst->ExpandInst.w16_lagsPosition = 0; + inst->ExpandInst.w16_lagsDirection = 0; + inst->ExpandInst.w16_stopMuting = 1; /* Do not mute signal any more */ + + /* Call Expand */ + WebRtcNetEQ_Expand(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, +#endif + pw16_expanded, &expandedLen, (WebRtc_Word16) (inst->w16_mode == MODE_FADE_TO_BGN)); + + inst->ExpandInst.w16_stopMuting = 0; /* Restore value */ + inst->ExpandInst.w16_consecExp = 0; /* Last was not Expand any more */ + + /* Adjust muting factor (main muting factor times expand muting factor) */ + if (inst->w16_mode == MODE_FADE_TO_BGN) + { + /* If last mode was FadeToBGN, the mute factor should be zero. */ + inst->w16_muteFactor = 0; + } + else + { + /* w16_muteFactor * w16_expandMuteFactor */ + inst->w16_muteFactor + = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(inst->w16_muteFactor, + inst->ExpandInst.w16_expandMuteFactor, 14); + } + + /* Adjust muting factor if needed (to BGN level) */ + enLen = WEBRTC_SPL_MIN(fs_mult<<6, len); /* min( fs_mult * 64, len ) */ + w16_tmp = 6 + fs_shift - WebRtcSpl_NormW32( + WEBRTC_SPL_MUL_16_16(w16_decodedMax, w16_decodedMax)); + w16_tmp = WEBRTC_SPL_MAX(w16_tmp, 0); + w32_En_speech = WebRtcNetEQ_DotW16W16(pw16_decoded, pw16_decoded, enLen, w16_tmp); + w32_En_speech = WebRtcSpl_DivW32W16(w32_En_speech, (WebRtc_Word16) (enLen >> w16_tmp)); + + if ((w32_En_speech != 0) && (w32_En_speech > inst->BGNInst.w32_energy)) + { + /* Normalize new frame energy to 15 bits */ + w16_tmp = WebRtcSpl_NormW32(w32_En_speech) - 16; + /* we want inst->BGNInst.energy/En_speech in Q14 */ + w32_tmp = WEBRTC_SPL_SHIFT_W32(inst->BGNInst.w32_energy, (w16_tmp+14)); + w16_tmp = (WebRtc_Word16) WEBRTC_SPL_SHIFT_W32(w32_En_speech, w16_tmp); + w16_tmp = (WebRtc_Word16) WebRtcSpl_DivW32W16(w32_tmp, w16_tmp); + w16_muted = (WebRtc_Word16) WebRtcSpl_Sqrt( + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) w16_tmp, + 14)); /* w16_muted in Q14 (sqrt(Q28)) */ + } + else + { + w16_muted = 16384; /* 1.0 in Q14 */ + } + if (w16_muted > inst->w16_muteFactor) + { + inst->w16_muteFactor = WEBRTC_SPL_MIN(w16_muted, 16384); + } + + /* If muted increase by 0.64 for every 20 ms (NB/WB 0.0040/0.0020 in Q14) */ + w16_inc = WebRtcSpl_DivW32W16ResW16(64, fs_mult); + for (i = 0; i < len; i++) + { + /* scale with mute factor */ + w32_tmp = WEBRTC_SPL_MUL_16_16(pw16_decoded[i], inst->w16_muteFactor); + /* shift 14 with proper rounding */ + pw16_decoded[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32((w32_tmp + 8192), 14); + /* increase mute_factor towards 16384 */ + inst->w16_muteFactor = WEBRTC_SPL_MIN(16384, (inst->w16_muteFactor+w16_inc)); + } + + /* + * Interpolate the expanded data into the new vector + * (NB/WB/SWB32/SWB40 8/16/32/32 samples) + */ + fs_shift = WEBRTC_SPL_MIN(3, fs_shift); /* Set to 3 for >32kHz */ + w16_inc = 4 >> fs_shift; + w16_frac = w16_inc; + for (i = 0; i < 8 * fs_mult; i++) + { + pw16_decoded[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32( + (WEBRTC_SPL_MUL_16_16(w16_frac, pw16_decoded[i]) + + WEBRTC_SPL_MUL_16_16((32 - w16_frac), pw16_expanded[i]) + 8), + 5); + w16_frac += w16_inc; + } + +#ifdef NETEQ_CNG_CODEC + } + else if (inst->w16_mode==MODE_RFC3389CNG) + { /* previous was RFC 3389 CNG...*/ + WebRtc_Word16 pw16_CngInterp[32]; + /* Reset mute factor and start up fresh */ + inst->w16_muteFactor = 16384; + if (inst->CNG_Codec_inst != NULL) + { + /* Generate long enough for 32kHz */ + if(WebRtcCng_Generate(inst->CNG_Codec_inst,pw16_CngInterp, 32, 0)<0) + { + /* error returned; set return vector to all zeros */ + WebRtcSpl_MemSetW16(pw16_CngInterp, 0, 32); + } + } + else + { + /* + * If no CNG instance is defined, just copy from the decoded data. + * (This will result in interpolating the decoded with itself.) + */ + WEBRTC_SPL_MEMCPY_W16(pw16_CngInterp, pw16_decoded, fs_mult * 8); + } + /* + * Interpolate the CNG into the new vector + * (NB/WB/SWB32kHz/SWB48kHz 8/16/32/32 samples) + */ + fs_shift = WEBRTC_SPL_MIN(3, fs_shift); /* Set to 3 for >32kHz */ + w16_inc = 4>>fs_shift; + w16_frac = w16_inc; + for (i = 0; i < 8 * fs_mult; i++) + { + pw16_decoded[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32( + (WEBRTC_SPL_MUL_16_16(w16_frac, pw16_decoded[i]) + + WEBRTC_SPL_MUL_16_16((32-w16_frac), pw16_CngInterp[i]) + 8), + 5); + w16_frac += w16_inc; + } +#endif + + } + else if (inst->w16_muteFactor < 16384) + { + /* + * Previous was neither of Expand, FadeToBGN or RFC3389_CNG, but we are still + * ramping up from previous muting. + * If muted increase by 0.64 for every 20 ms (NB/WB 0.0040/0.0020 in Q14) + */ + w16_inc = WebRtcSpl_DivW32W16ResW16(64, fs_mult); + for (i = 0; i < len; i++) + { + /* scale with mute factor */ + w32_tmp = WEBRTC_SPL_MUL_16_16(pw16_decoded[i], inst->w16_muteFactor); + /* shift 14 with proper rounding */ + pw16_decoded[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32((w32_tmp + 8192), 14); + /* increase mute_factor towards 16384 */ + inst->w16_muteFactor = WEBRTC_SPL_MIN(16384, (inst->w16_muteFactor+w16_inc)); + } + } + + /* Copy data to other buffer */WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, len); + + inst->w16_mode = MODE_NORMAL; + *pw16_len = len; + return (len); + +} + +#undef SCRATCH_PW16_EXPANDED +#undef SCRATCH_NETEQ_EXPAND + diff --git a/src/libs/webrtc/neteq/packet_buffer.c b/src/libs/webrtc/neteq/packet_buffer.c new file mode 100644 index 00000000..95da7105 --- /dev/null +++ b/src/libs/webrtc/neteq/packet_buffer.c @@ -0,0 +1,707 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Implementation of the actual packet buffer data structure. + */ + +#include "packet_buffer.h" + +#include <string.h> /* to define NULL */ + +#include "signal_processing_library.h" + +#include "neteq_error_codes.h" + +#ifdef NETEQ_DELAY_LOGGING +/* special code for offline delay logging */ +#include "delay_logging.h" +#include <stdio.h> + +extern FILE *delay_fid2; /* file pointer to delay log file */ +extern WebRtc_UWord32 tot_received_packets; +#endif /* NETEQ_DELAY_LOGGING */ + + +int WebRtcNetEQ_PacketBufferInit(PacketBuf_t *bufferInst, int maxNoOfPackets, + WebRtc_Word16 *pw16_memory, int memorySize) +{ + int i; + int pos = 0; + + /* Sanity check */ + if ((memorySize < PBUFFER_MIN_MEMORY_SIZE) || (pw16_memory == NULL) + || (maxNoOfPackets < 2) || (maxNoOfPackets > 600)) + { + /* Invalid parameters */ + return (PBUFFER_INIT_ERROR); + } + + /* Clear the buffer instance */ + WebRtcSpl_MemSetW16((WebRtc_Word16*) bufferInst, 0, + sizeof(PacketBuf_t) / sizeof(WebRtc_Word16)); + + /* Clear the buffer memory */ + WebRtcSpl_MemSetW16((WebRtc_Word16*) pw16_memory, 0, memorySize); + + /* Set maximum number of packets */ + bufferInst->maxInsertPositions = maxNoOfPackets; + + /* Initialize array pointers */ + /* After each pointer has been set, the index pos is advanced to point immediately + * after the the recently allocated vector. Note that one step for the pos index + * corresponds to a WebRtc_Word16. + */ + + bufferInst->timeStamp = (WebRtc_UWord32*) &pw16_memory[pos]; + pos += maxNoOfPackets << 1; /* advance maxNoOfPackets * WebRtc_UWord32 */ + + bufferInst->payloadLocation = (WebRtc_Word16**) &pw16_memory[pos]; + pos += maxNoOfPackets * (sizeof(WebRtc_Word16*) / sizeof(WebRtc_Word16)); /* advance */ + + bufferInst->seqNumber = (WebRtc_UWord16*) &pw16_memory[pos]; + pos += maxNoOfPackets; /* advance maxNoOfPackets * WebRtc_UWord16 */ + + bufferInst->payloadType = &pw16_memory[pos]; + pos += maxNoOfPackets; /* advance maxNoOfPackets * WebRtc_Word16 */ + + bufferInst->payloadLengthBytes = &pw16_memory[pos]; + pos += maxNoOfPackets; /* advance maxNoOfPackets * WebRtc_Word16 */ + + bufferInst->rcuPlCntr = &pw16_memory[pos]; + pos += maxNoOfPackets; /* advance maxNoOfPackets * WebRtc_Word16 */ + + /* The payload memory starts after the slot arrays */ + bufferInst->startPayloadMemory = &pw16_memory[pos]; + bufferInst->currentMemoryPos = bufferInst->startPayloadMemory; + bufferInst->memorySizeW16 = (memorySize - pos); /* Remaining memory */ + + /* Initialize each payload slot as empty with infinite delay */ + for (i = 0; i < bufferInst->maxInsertPositions; i++) + { + bufferInst->payloadType[i] = -1; + } + + /* Reset buffer parameters */ + bufferInst->numPacketsInBuffer = 0; + bufferInst->packSizeSamples = 0; + bufferInst->insertPosition = 0; + + /* Reset buffer statistics */ + bufferInst->discardedPackets = 0; + bufferInst->totalDiscardedPackets = 0; + bufferInst->totalFlushedPackets = 0; + + return (0); +} + + +int WebRtcNetEQ_PacketBufferFlush(PacketBuf_t *bufferInst) +{ + int i; + + /* Sanity check */ + if (bufferInst->startPayloadMemory == NULL) + { + /* Packet buffer has not been initialized */ + /* Don't do the flushing operation, since we do not + know the state of the struct variables */ + return (0); + } + + /* Increase flush counter */ + bufferInst->totalFlushedPackets += bufferInst->numPacketsInBuffer; + + /* Set all payload lengths to zero */ + WebRtcSpl_MemSetW16(bufferInst->payloadLengthBytes, 0, bufferInst->maxInsertPositions); + + /* Reset buffer variables */ + bufferInst->numPacketsInBuffer = 0; + bufferInst->currentMemoryPos = bufferInst->startPayloadMemory; + bufferInst->insertPosition = 0; + + /* Clear all slots, starting with the last one */ + for (i = (bufferInst->maxInsertPositions - 1); i >= 0; i--) + { + bufferInst->payloadType[i] = -1; + bufferInst->timeStamp[i] = 0; + bufferInst->seqNumber[i] = 0; + } + + return (0); +} + + +int WebRtcNetEQ_PacketBufferInsert(PacketBuf_t *bufferInst, const RTPPacket_t *RTPpacket, + WebRtc_Word16 *flushed) +{ + int nextPos; + int i; + +#ifdef NETEQ_DELAY_LOGGING + /* special code for offline delay logging */ + int temp_var; +#endif /* NETEQ_DELAY_LOGGING */ + + /* Initialize to "no flush" */ + *flushed = 0; + + /* Sanity check */ + if (bufferInst->startPayloadMemory == NULL) + { + /* packet buffer has not been initialized */ + return (-1); + } + + /* Sanity check for payload length + (payloadLen in bytes and memory size in WebRtc_Word16) */ + if ((RTPpacket->payloadLen > (bufferInst->memorySizeW16 << 1)) || (RTPpacket->payloadLen + <= 0)) + { + /* faulty or too long payload length */ + return (-1); + } + + /* Find a position in the buffer for this packet */ + if (bufferInst->numPacketsInBuffer != 0) + { + /* Get the next slot */ + bufferInst->insertPosition++; + if (bufferInst->insertPosition >= bufferInst->maxInsertPositions) + { + /* "Wrap around" and start from the beginning */ + bufferInst->insertPosition = 0; + } + + /* Check if there is enough space for the new packet */ + if (bufferInst->currentMemoryPos + ((RTPpacket->payloadLen + 1) >> 1) + >= &bufferInst->startPayloadMemory[bufferInst->memorySizeW16]) + { + WebRtc_Word16 *tempMemAddress; + + /* + * Payload does not fit at the end of the memory, put it in the beginning + * instead + */ + bufferInst->currentMemoryPos = bufferInst->startPayloadMemory; + + /* + * Now, we must search for the next non-empty payload, + * finding the one with the lowest start address for the payload + */ + tempMemAddress = &bufferInst->startPayloadMemory[bufferInst->memorySizeW16]; + nextPos = -1; + + /* Loop through all slots again */ + for (i = 0; i < bufferInst->maxInsertPositions; i++) + { + /* Look for the non-empty slot with the lowest + payload location address */ + if (bufferInst->payloadLengthBytes[i] != 0 && bufferInst->payloadLocation[i] + < tempMemAddress) + { + tempMemAddress = bufferInst->payloadLocation[i]; + nextPos = i; + } + } + + /* Check that we did find a previous payload */ + if (nextPos == -1) + { + /* The buffer is corrupt => flush and return error */ + WebRtcNetEQ_PacketBufferFlush(bufferInst); + *flushed = 1; + return (-1); + } + } + else + { + /* Payload fits at the end of memory. */ + + /* Find the next non-empty slot. */ + nextPos = bufferInst->insertPosition + 1; + + /* Increase nextPos until a non-empty slot is found or end of array is encountered*/ + while ((bufferInst->payloadLengthBytes[nextPos] == 0) && (nextPos + < bufferInst->maxInsertPositions)) + { + nextPos++; + } + + if (nextPos == bufferInst->maxInsertPositions) + { + /* + * Reached the end of the array, so there must be a packet in the first + * position instead + */ + nextPos = 0; + + /* Increase nextPos until a non-empty slot is found */ + while (bufferInst->payloadLengthBytes[nextPos] == 0) + { + nextPos++; + } + } + } /* end if-else */ + + /* + * Check if the new payload will extend into a payload later in memory. + * If so, the buffer is full. + */ + if ((bufferInst->currentMemoryPos <= bufferInst->payloadLocation[nextPos]) + && ((&bufferInst->currentMemoryPos[(RTPpacket->payloadLen + 1) >> 1]) + > bufferInst->payloadLocation[nextPos])) + { + /* Buffer is full, so the buffer must be flushed */ + WebRtcNetEQ_PacketBufferFlush(bufferInst); + *flushed = 1; + } + + if (bufferInst->payloadLengthBytes[bufferInst->insertPosition] != 0) + { + /* All positions are already taken and entire buffer should be flushed */ + WebRtcNetEQ_PacketBufferFlush(bufferInst); + *flushed = 1; + } + + } + else + { + /* Buffer is empty, just insert the packet at the beginning */ + bufferInst->currentMemoryPos = bufferInst->startPayloadMemory; + bufferInst->insertPosition = 0; + } + + /* Insert packet in the found position */ + if (RTPpacket->starts_byte1 == 0) + { + /* Payload is 16-bit aligned => just copy it */ + + WEBRTC_SPL_MEMCPY_W16(bufferInst->currentMemoryPos, + RTPpacket->payload, (RTPpacket->payloadLen + 1) >> 1); + } + else + { + /* Payload is not 16-bit aligned => align it during copy operation */ + for (i = 0; i < RTPpacket->payloadLen; i++) + { + /* copy the (i+1)-th byte to the i-th byte */ + + WEBRTC_SPL_SET_BYTE(bufferInst->currentMemoryPos, + (WEBRTC_SPL_GET_BYTE(RTPpacket->payload, (i + 1))), i); + } + } + + /* Copy the packet information */ + bufferInst->payloadLocation[bufferInst->insertPosition] = bufferInst->currentMemoryPos; + bufferInst->payloadLengthBytes[bufferInst->insertPosition] = RTPpacket->payloadLen; + bufferInst->payloadType[bufferInst->insertPosition] = RTPpacket->payloadType; + bufferInst->seqNumber[bufferInst->insertPosition] = RTPpacket->seqNumber; + bufferInst->timeStamp[bufferInst->insertPosition] = RTPpacket->timeStamp; + bufferInst->rcuPlCntr[bufferInst->insertPosition] = RTPpacket->rcuPlCntr; + /* Update buffer parameters */ + bufferInst->numPacketsInBuffer++; + bufferInst->currentMemoryPos += (RTPpacket->payloadLen + 1) >> 1; + +#ifdef NETEQ_DELAY_LOGGING + /* special code for offline delay logging */ + if (*flushed) + { + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_FLUSH; + fwrite( &temp_var, sizeof(int), 1, delay_fid2 ); + } + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_RECIN; + fwrite( &temp_var, sizeof(int), 1, delay_fid2 ); + fwrite( &RTPpacket->timeStamp, sizeof(WebRtc_UWord32), 1, delay_fid2 ); + fwrite( &RTPpacket->seqNumber, sizeof(WebRtc_UWord16), 1, delay_fid2 ); + fwrite( &RTPpacket->payloadType, sizeof(int), 1, delay_fid2 ); + fwrite( &RTPpacket->payloadLen, sizeof(WebRtc_Word16), 1, delay_fid2 ); + tot_received_packets++; +#endif /* NETEQ_DELAY_LOGGING */ + + return (0); +} + + +int WebRtcNetEQ_PacketBufferExtract(PacketBuf_t *bufferInst, RTPPacket_t *RTPpacket, + int bufferPosition) +{ + + /* Sanity check */ + if (bufferInst->startPayloadMemory == NULL) + { + /* packet buffer has not been initialized */ + return (PBUFFER_NOT_INITIALIZED); + } + + if (bufferPosition < 0 || bufferPosition >= bufferInst->maxInsertPositions) + { + /* buffer position is outside valid range */ + return (NETEQ_OTHER_ERROR); + } + + /* Check that there is a valid payload in the specified position */ + if (bufferInst->payloadLengthBytes[bufferPosition] <= 0) + { + /* The position does not contain a valid payload */ + RTPpacket->payloadLen = 0; /* Set zero length */ + return (PBUFFER_NONEXISTING_PACKET); /* Return error */ + } + + /* Payload exists => extract payload data */ + + /* Copy the actual data payload to RTP packet struct */ + + WEBRTC_SPL_MEMCPY_W16((WebRtc_Word16*) RTPpacket->payload, + bufferInst->payloadLocation[bufferPosition], + (bufferInst->payloadLengthBytes[bufferPosition] + 1) >> 1); /*length in WebRtc_Word16*/ + + /* Copy payload parameters */ + RTPpacket->payloadLen = bufferInst->payloadLengthBytes[bufferPosition]; + RTPpacket->payloadType = bufferInst->payloadType[bufferPosition]; + RTPpacket->seqNumber = bufferInst->seqNumber[bufferPosition]; + RTPpacket->timeStamp = bufferInst->timeStamp[bufferPosition]; + RTPpacket->rcuPlCntr = bufferInst->rcuPlCntr[bufferPosition]; + RTPpacket->starts_byte1 = 0; /* payload is 16-bit aligned */ + + /* Clear the position in the packet buffer */ + bufferInst->payloadType[bufferPosition] = -1; + bufferInst->payloadLengthBytes[bufferPosition] = 0; + bufferInst->seqNumber[bufferPosition] = 0; + bufferInst->timeStamp[bufferPosition] = 0; + bufferInst->payloadLocation[bufferPosition] = bufferInst->startPayloadMemory; + + /* Reduce packet counter with one */ + bufferInst->numPacketsInBuffer--; + + return (0); +} + + +int WebRtcNetEQ_PacketBufferFindLowestTimestamp(PacketBuf_t *bufferInst, + WebRtc_UWord32 currentTS, + WebRtc_UWord32 *timestamp, + int *bufferPosition, int eraseOldPkts, + WebRtc_Word16 *payloadType) +{ + WebRtc_Word32 timeStampDiff = WEBRTC_SPL_WORD32_MAX; /* Smallest diff found */ + WebRtc_Word32 newDiff; + int i; + WebRtc_Word16 rcuPlCntr; + + /* Sanity check */ + if (bufferInst->startPayloadMemory == NULL) + { + /* packet buffer has not been initialized */ + return (PBUFFER_NOT_INITIALIZED); + } + + /* Initialize all return values */ + *timestamp = 0; + *payloadType = -1; /* indicates that no packet was found */ + *bufferPosition = -1; /* indicates that no packet was found */ + rcuPlCntr = WEBRTC_SPL_WORD16_MAX; /* indicates that no packet was found */ + + /* Check if buffer is empty */ + if (bufferInst->numPacketsInBuffer <= 0) + { + /* Empty buffer */ + return (0); + } + + /* Loop through all slots in buffer */ + for (i = 0; i < bufferInst->maxInsertPositions; i++) + { + /* Calculate difference between this slot and currentTS */ + newDiff = (WebRtc_Word32) (bufferInst->timeStamp[i] - currentTS); + + /* Check if payload should be discarded */ + if ((newDiff < 0) /* payload is too old */ + && (newDiff > -30000) /* account for TS wrap-around */ + && (eraseOldPkts) /* old payloads should be discarded */ + && (bufferInst->payloadLengthBytes[i] > 0)) /* the payload exists */ + { + /* Throw away old packet */ + + /* Clear the position in the buffer */ + bufferInst->payloadType[i] = -1; + bufferInst->payloadLengthBytes[i] = 0; + + /* Reduce packet counter by one */ + bufferInst->numPacketsInBuffer--; + + /* Increase discard counter for in-call and post-call statistics */ + bufferInst->discardedPackets++; + bufferInst->totalDiscardedPackets++; + } + else if (((newDiff < timeStampDiff) || ((newDiff == timeStampDiff) + && (bufferInst->rcuPlCntr[i] < rcuPlCntr))) && (bufferInst->payloadLengthBytes[i] + > 0)) + { + /* + * New diff is smaller than previous diffs or we have a candidate with a timestamp + * as previous candidate but better RCU-counter; and the payload exists. + */ + + /* Save this position as the best candidate */ + *bufferPosition = i; + timeStampDiff = newDiff; + *payloadType = bufferInst->payloadType[i]; + rcuPlCntr = bufferInst->rcuPlCntr[i]; + } + } /* end of for loop */ + + /* check that we did find a real position */ + if (*bufferPosition >= 0) + { + /* get the timestamp for the best position */ + *timestamp = bufferInst->timeStamp[*bufferPosition]; + } + + return 0; +} + + +WebRtc_Word32 WebRtcNetEQ_PacketBufferGetSize(const PacketBuf_t *bufferInst) +{ + int i, count; + WebRtc_Word32 sizeSamples; + + count = 0; + + /* Loop through all slots in the buffer */ + for (i = 0; i < bufferInst->maxInsertPositions; i++) + { + /* Only count the packets with non-zero size */ + if (bufferInst->payloadLengthBytes[i] != 0) + { + count++; + } + } + + /* + * Calculate buffer size as number of packets times packet size + * (packet size is that of the latest decoded packet) + */ + sizeSamples = WEBRTC_SPL_MUL_16_16(bufferInst->packSizeSamples, count); + + /* Sanity check; size cannot be negative */ + if (sizeSamples < 0) + { + sizeSamples = 0; + } + + return sizeSamples; +} + + +int WebRtcNetEQ_GetDefaultCodecSettings(const enum WebRtcNetEQDecoder *codecID, + int noOfCodecs, int *maxBytes, int *maxSlots) +{ + int i; + int ok = 0; + WebRtc_Word16 w16_tmp; + WebRtc_Word16 codecBytes; + WebRtc_Word16 codecBuffers; + + /* Initialize return variables to zero */ + *maxBytes = 0; + *maxSlots = 0; + + /* Loop through all codecs supplied to function */ + for (i = 0; i < noOfCodecs; i++) + { + /* Find current codec and set parameters accordingly */ + + if (codecID[i] == kDecoderPCMu) + { + codecBytes = 1680; /* Up to 210ms @ 64kbps */ + codecBuffers = 30; /* Down to 5ms frames */ + } + else if (codecID[i] == kDecoderPCMa) + { + codecBytes = 1680; /* Up to 210ms @ 64kbps */ + codecBuffers = 30; /* Down to 5ms frames */ + } + else if (codecID[i] == kDecoderILBC) + { + codecBytes = 380; /* 200ms @ 15.2kbps (20ms frames) */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderISAC) + { + codecBytes = 960; /* 240ms @ 32kbps (60ms frames) */ + codecBuffers = 8; + } + else if (codecID[i] == kDecoderISACswb) + { + codecBytes = 1560; /* 240ms @ 52kbps (30ms frames) */ + codecBuffers = 8; + } + else if (codecID[i] == kDecoderPCM16B) + { + codecBytes = 3360; /* 210ms */ + codecBuffers = 15; + } + else if (codecID[i] == kDecoderPCM16Bwb) + { + codecBytes = 6720; /* 210ms */ + codecBuffers = 15; + } + else if (codecID[i] == kDecoderPCM16Bswb32kHz) + { + codecBytes = 13440; /* 210ms */ + codecBuffers = 15; + } + else if (codecID[i] == kDecoderPCM16Bswb48kHz) + { + codecBytes = 20160; /* 210ms */ + codecBuffers = 15; + } + else if (codecID[i] == kDecoderG722) + { + codecBytes = 1680; /* 210ms @ 64kbps */ + codecBuffers = 15; + } + else if (codecID[i] == kDecoderRED) + { + codecBytes = 0; /* Should not be max... */ + codecBuffers = 0; + } + else if (codecID[i] == kDecoderAVT) + { + codecBytes = 0; /* Should not be max... */ + codecBuffers = 0; + } + else if (codecID[i] == kDecoderCNG) + { + codecBytes = 0; /* Should not be max... */ + codecBuffers = 0; + } + else if (codecID[i] == kDecoderG729) + { + codecBytes = 210; /* 210ms @ 8kbps */ + codecBuffers = 20; /* max 200ms supported for 10ms frames */ + } + else if (codecID[i] == kDecoderG729_1) + { + codecBytes = 840; /* 210ms @ 32kbps */ + codecBuffers = 10; /* max 200ms supported for 20ms frames */ + } + else if (codecID[i] == kDecoderG726_16) + { + codecBytes = 400; /* 200ms @ 16kbps */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderG726_24) + { + codecBytes = 600; /* 200ms @ 24kbps */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderG726_32) + { + codecBytes = 800; /* 200ms @ 32kbps */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderG726_40) + { + codecBytes = 1000; /* 200ms @ 40kbps */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderG722_1_16) + { + codecBytes = 420; /* 210ms @ 16kbps */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderG722_1_24) + { + codecBytes = 630; /* 210ms @ 24kbps */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderG722_1_32) + { + codecBytes = 840; /* 210ms @ 32kbps */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderG722_1C_24) + { + codecBytes = 630; /* 210ms @ 24kbps */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderG722_1C_32) + { + codecBytes = 840; /* 210ms @ 32kbps */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderG722_1C_48) + { + codecBytes = 1260; /* 210ms @ 48kbps */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderSPEEX_8) + { + codecBytes = 1250; /* 210ms @ 50kbps */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderSPEEX_16) + { + codecBytes = 1250; /* 210ms @ 50kbps */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderGSMFR) + { + codecBytes = 340; /* 200ms */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderAMR) + { + codecBytes = 384; /* 240ms @ 12.2kbps+headers (60ms frames) */ + codecBuffers = 10; + } + else if (codecID[i] == kDecoderAMRWB) + { + codecBytes = 744; + codecBuffers = 10; + } + else if (codecID[i] == kDecoderArbitrary) + { + codecBytes = 6720; /* Assume worst case uncompressed WB 210ms */ + codecBuffers = 15; + } + else + { + /*Unknow codec */ + codecBytes = 0; + codecBuffers = 0; + ok = CODEC_DB_UNKNOWN_CODEC; + } + + /* Update max variables */ + *maxBytes = WEBRTC_SPL_MAX((*maxBytes), codecBytes); + *maxSlots = WEBRTC_SPL_MAX((*maxSlots), codecBuffers); + + } /* end of for loop */ + + /* + * Add size needed by the additional pointers for each slot inside struct, + * as indicated on each line below. + */ + w16_tmp = (sizeof(WebRtc_UWord32) /* timeStamp */ + + sizeof(WebRtc_Word16*) /* payloadLocation */ + + sizeof(WebRtc_UWord16) /* seqNumber */ + + sizeof(WebRtc_Word16) /* payloadType */ + + sizeof(WebRtc_Word16) /* payloadLengthBytes */ + + sizeof(WebRtc_Word16)); /* rcuPlCntr */ + /* Add the extra size per slot to the memory count */ + *maxBytes += w16_tmp * (*maxSlots); + + return ok; +} + diff --git a/src/libs/webrtc/neteq/packet_buffer.h b/src/libs/webrtc/neteq/packet_buffer.h new file mode 100644 index 00000000..a71a812e --- /dev/null +++ b/src/libs/webrtc/neteq/packet_buffer.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Interface for the actual packet buffer data structure. + */ + +#ifndef PACKET_BUFFER_H +#define PACKET_BUFFER_H + +#include "typedefs.h" + +#include "webrtc_neteq.h" +#include "rtp.h" + +/* Define minimum allowed buffer memory, in 16-bit words */ +#define PBUFFER_MIN_MEMORY_SIZE 150 + +/****************************/ +/* The packet buffer struct */ +/****************************/ + +typedef struct +{ + + /* Variables common to the entire buffer */ + WebRtc_UWord16 packSizeSamples; /* packet size in samples of last decoded packet */ + WebRtc_Word16 *startPayloadMemory; /* pointer to the payload memory */ + int memorySizeW16; /* the size (in WebRtc_Word16) of the payload memory */ + WebRtc_Word16 *currentMemoryPos; /* The memory position to insert next payload */ + int numPacketsInBuffer; /* The number of packets in the buffer */ + int insertPosition; /* The position to insert next packet */ + int maxInsertPositions; /* Maximum number of packets allowed */ + + /* Arrays with one entry per packet slot */ + /* NOTE: If these are changed, the changes must be accounted for at the end of + the function WebRtcNetEQ_GetDefaultCodecSettings(). */ + WebRtc_UWord32 *timeStamp; /* Timestamp in slot n */ + WebRtc_Word16 **payloadLocation; /* Memory location of payload in slot n */ + WebRtc_UWord16 *seqNumber; /* Sequence number in slot n */ + WebRtc_Word16 *payloadType; /* Payload type of packet in slot n */ + WebRtc_Word16 *payloadLengthBytes; /* Payload length of packet in slot n */ + WebRtc_Word16 *rcuPlCntr; /* zero for non-RCU payload, 1 for main payload + 2 for redundant payload */ + + /* Statistics counters */ + WebRtc_UWord16 discardedPackets; /* Number of discarded packets */ + WebRtc_UWord32 totalDiscardedPackets; /* Total number of discarded packets */ + WebRtc_UWord32 totalFlushedPackets; /* Total number of flushed packets */ + +} PacketBuf_t; + +/*************************/ +/* Function declarations */ +/*************************/ + +/**************************************************************************** + * WebRtcNetEQ_PacketBufferInit(...) + * + * This function initializes the packet buffer. + * + * Input: + * - bufferInst : Buffer instance to be initialized + * - noOfPackets : Maximum number of packets that buffer should hold + * - memory : Pointer to the storage memory for the payloads + * - memorySize : The size of the payload memory (in WebRtc_Word16) + * + * Output: + * - bufferInst : Updated buffer instance + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_PacketBufferInit(PacketBuf_t *bufferInst, int maxNoOfPackets, + WebRtc_Word16 *pw16_memory, int memorySize); + +/**************************************************************************** + * WebRtcNetEQ_PacketBufferFlush(...) + * + * This function flushes all the packets in the buffer. + * + * Input: + * - bufferInst : Buffer instance to be flushed + * + * Output: + * - bufferInst : Flushed buffer instance + * + * Return value : 0 - Ok + */ + +int WebRtcNetEQ_PacketBufferFlush(PacketBuf_t *bufferInst); + +/**************************************************************************** + * WebRtcNetEQ_PacketBufferInsert(...) + * + * This function inserts an RTP packet into the packet buffer. + * + * Input: + * - bufferInst : Buffer instance + * - RTPpacket : An RTP packet struct (with payload, sequence + * number, etc.) + * + * Output: + * - bufferInst : Updated buffer instance + * - flushed : 1 if buffer was flushed, 0 otherwise + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_PacketBufferInsert(PacketBuf_t *bufferInst, const RTPPacket_t *RTPpacket, + WebRtc_Word16 *flushed); + +/**************************************************************************** + * WebRtcNetEQ_PacketBufferExtract(...) + * + * This function extracts a payload from the buffer. + * + * Input: + * - bufferInst : Buffer instance + * - bufferPosition: Position of the packet that should be extracted + * + * Output: + * - RTPpacket : An RTP packet struct (with payload, sequence + * number, etc) + * - bufferInst : Updated buffer instance + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_PacketBufferExtract(PacketBuf_t *bufferInst, RTPPacket_t *RTPpacket, + int bufferPosition); + +/**************************************************************************** + * WebRtcNetEQ_PacketBufferFindLowestTimestamp(...) + * + * This function finds the next packet with the lowest timestamp. + * + * Input: + * - bufferInst : Buffer instance + * - currentTS : The timestamp to compare packet timestamps with + * - eraseOldPkts : If non-zero, erase packets older than currentTS + * + * Output: + * - timestamp : Lowest timestamp that was found + * - bufferPosition: Position of this packet (-1 if there are no packets + * in the buffer) + * - payloadType : Payload type of the found payload + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_PacketBufferFindLowestTimestamp(PacketBuf_t *bufferInst, + WebRtc_UWord32 currentTS, + WebRtc_UWord32 *timestamp, + int *bufferPosition, int eraseOldPkts, + WebRtc_Word16 *payloadType); + +/**************************************************************************** + * WebRtcNetEQ_PacketBufferGetSize(...) + * + * Calculate and return an estimate of the total data length (in samples) + * currently in the buffer. The estimate is calculated as the number of + * packets currently in the buffer (which does not have any remaining waiting + * time), multiplied with the number of samples obtained from the last + * decoded packet. + * + * Input: + * - bufferInst : Buffer instance + * + * Return value : The buffer size in samples + */ + +WebRtc_Word32 WebRtcNetEQ_PacketBufferGetSize(const PacketBuf_t *bufferInst); + +/**************************************************************************** + * WebRtcNetEQ_GetDefaultCodecSettings(...) + * + * Calculates a recommended buffer size for a specific set of codecs. + * + * Input: + * - codecID : An array of codec types that will be used + * - noOfCodecs : Number of codecs in array codecID + * + * Output: + * - maxBytes : Recommended buffer memory size in bytes + * - maxSlots : Recommended number of slots in buffer + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_GetDefaultCodecSettings(const enum WebRtcNetEQDecoder *codecID, + int noOfCodecs, int *maxBytes, int *maxSlots); + +#endif /* PACKET_BUFFER_H */ diff --git a/src/libs/webrtc/neteq/peak_detection.c b/src/libs/webrtc/neteq/peak_detection.c new file mode 100644 index 00000000..678c7f91 --- /dev/null +++ b/src/libs/webrtc/neteq/peak_detection.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Implementation of the peak detection used for finding correlation peaks. + */ + +#include "dsp_helpfunctions.h" + +#include "signal_processing_library.h" + +/* Table of constants used in parabolic fit function WebRtcNetEQ_PrblFit */ +const WebRtc_Word16 WebRtcNetEQ_kPrblCf[17][3] = { { 120, 32, 64 }, { 140, 44, 75 }, + { 150, 50, 80 }, { 160, 57, 85 }, + { 180, 72, 96 }, { 200, 89, 107 }, + { 210, 98, 112 }, { 220, 108, 117 }, + { 240, 128, 128 }, { 260, 150, 139 }, + { 270, 162, 144 }, { 280, 174, 149 }, + { 300, 200, 160 }, { 320, 228, 171 }, + { 330, 242, 176 }, { 340, 257, 181 }, + { 360, 288, 192 } }; + +WebRtc_Word16 WebRtcNetEQ_PeakDetection(WebRtc_Word16 *pw16_data, WebRtc_Word16 w16_dataLen, + WebRtc_Word16 w16_nmbPeaks, WebRtc_Word16 fs_mult, + WebRtc_Word16 *pw16_winIndex, + WebRtc_Word16 *pw16_winValue) +{ + /* Local variables */ + int i; + WebRtc_Word16 w16_tmp; + WebRtc_Word16 w16_tmp2; + WebRtc_Word16 indMin = 0; + WebRtc_Word16 indMax = 0; + + /* Peak detection */ + + for (i = 0; i <= (w16_nmbPeaks - 1); i++) + { + if (w16_nmbPeaks == 1) + { + /* + * Single peak + * The parabola fit assumes that an extra point is available; worst case it gets + * a zero on the high end of the signal. + */ + w16_dataLen++; + } + + pw16_winIndex[i] = WebRtcSpl_MaxIndexW16(pw16_data, (WebRtc_Word16) (w16_dataLen - 1)); + + if (i != w16_nmbPeaks - 1) + { + w16_tmp = pw16_winIndex[i] - 2; /* *fs_mult; */ + indMin = WEBRTC_SPL_MAX(0, w16_tmp); + w16_tmp = pw16_winIndex[i] + 2; /* *fs_mult; */ + w16_tmp2 = w16_dataLen - 1; + indMax = WEBRTC_SPL_MIN(w16_tmp2, w16_tmp); + } + + if ((pw16_winIndex[i] != 0) && (pw16_winIndex[i] != (w16_dataLen - 2))) + { + /* Parabola fit*/ + WebRtcNetEQ_PrblFit(&(pw16_data[pw16_winIndex[i] - 1]), &(pw16_winIndex[i]), + &(pw16_winValue[i]), fs_mult); + } + else + { + if (pw16_winIndex[i] == (w16_dataLen - 2)) + { + if (pw16_data[pw16_winIndex[i]] > pw16_data[pw16_winIndex[i] + 1]) + { + WebRtcNetEQ_PrblFit(&(pw16_data[pw16_winIndex[i] - 1]), + &(pw16_winIndex[i]), &(pw16_winValue[i]), fs_mult); + } + else if (pw16_data[pw16_winIndex[i]] <= pw16_data[pw16_winIndex[i] + 1]) + { + pw16_winValue[i] = (pw16_data[pw16_winIndex[i]] + + pw16_data[pw16_winIndex[i] + 1]) >> 1; /* lin approx */ + pw16_winIndex[i] = (pw16_winIndex[i] * 2 + 1) * fs_mult; + } + } + else + { + pw16_winValue[i] = pw16_data[pw16_winIndex[i]]; + pw16_winIndex[i] = pw16_winIndex[i] * 2 * fs_mult; + } + } + + if (i != w16_nmbPeaks - 1) + { + WebRtcSpl_MemSetW16(&(pw16_data[indMin]), 0, (indMax - indMin + 1)); + /* for (j=indMin; j<=indMax; j++) pw16_data[j] = 0; */ + } + } + + return 0; +} + +WebRtc_Word16 WebRtcNetEQ_PrblFit(WebRtc_Word16 *pw16_3pts, WebRtc_Word16 *pw16_Ind, + WebRtc_Word16 *pw16_outVal, WebRtc_Word16 fs_mult) +{ + /* Variables */ + WebRtc_Word32 Num, Den; + WebRtc_Word32 temp; + WebRtc_Word16 flag, stp, strt, lmt; + WebRtc_UWord16 PFind[13]; + + if (fs_mult == 1) + { + PFind[0] = 0; + PFind[1] = 8; + PFind[2] = 16; + } + else if (fs_mult == 2) + { + PFind[0] = 0; + PFind[1] = 4; + PFind[2] = 8; + PFind[3] = 12; + PFind[4] = 16; + } + else if (fs_mult == 4) + { + PFind[0] = 0; + PFind[1] = 2; + PFind[2] = 4; + PFind[3] = 6; + PFind[4] = 8; + PFind[5] = 10; + PFind[6] = 12; + PFind[7] = 14; + PFind[8] = 16; + } + else + { + PFind[0] = 0; + PFind[1] = 1; + PFind[2] = 3; + PFind[3] = 4; + PFind[4] = 5; + PFind[5] = 7; + PFind[6] = 8; + PFind[7] = 9; + PFind[8] = 11; + PFind[9] = 12; + PFind[10] = 13; + PFind[11] = 15; + PFind[12] = 16; + } + + /* Num = -3*pw16_3pts[0] + 4*pw16_3pts[1] - pw16_3pts[2]; */ + /* Den = pw16_3pts[0] - 2*pw16_3pts[1] + pw16_3pts[2]; */ + Num = WEBRTC_SPL_MUL_16_16(pw16_3pts[0],-3) + WEBRTC_SPL_MUL_16_16(pw16_3pts[1],4) + - pw16_3pts[2]; + + Den = pw16_3pts[0] + WEBRTC_SPL_MUL_16_16(pw16_3pts[1],-2) + pw16_3pts[2]; + + temp = (WebRtc_Word32) WEBRTC_SPL_MUL(Num, (WebRtc_Word32)120); /* need 32_16 really */ + flag = 1; + stp = WebRtcNetEQ_kPrblCf[PFind[fs_mult]][0] - WebRtcNetEQ_kPrblCf[PFind[fs_mult - 1]][0]; + strt = (WebRtcNetEQ_kPrblCf[PFind[fs_mult]][0] + + WebRtcNetEQ_kPrblCf[PFind[fs_mult - 1]][0]) >> 1; + + if (temp < (WebRtc_Word32) WEBRTC_SPL_MUL(-Den,(WebRtc_Word32)strt)) + { + lmt = strt - stp; + while (flag) + { + if ((flag == fs_mult) || (temp + > (WebRtc_Word32) WEBRTC_SPL_MUL(-Den,(WebRtc_Word32)lmt))) + { + *pw16_outVal + = (WebRtc_Word16) + (((WebRtc_Word32) ((WebRtc_Word32) WEBRTC_SPL_MUL(Den,(WebRtc_Word32)WebRtcNetEQ_kPrblCf[PFind[fs_mult-flag]][1]) + + (WebRtc_Word32) WEBRTC_SPL_MUL(Num,(WebRtc_Word32)WebRtcNetEQ_kPrblCf[PFind[fs_mult-flag]][2]) + + WEBRTC_SPL_MUL_16_16(pw16_3pts[0],256))) >> 8); + *pw16_Ind = (*pw16_Ind) * (fs_mult << 1) - flag; + flag = 0; + } + else + { + flag++; + lmt -= stp; + } + } + } + else if (temp > (WebRtc_Word32) WEBRTC_SPL_MUL(-Den,(WebRtc_Word32)(strt+stp))) + { + lmt = strt + (stp << 1); + while (flag) + { + if ((flag == fs_mult) || (temp + < (WebRtc_Word32) WEBRTC_SPL_MUL(-Den,(WebRtc_Word32)lmt))) + { + WebRtc_Word32 temp_term_1, temp_term_2, temp_term_3; + + temp_term_1 = WEBRTC_SPL_MUL(Den, + (WebRtc_Word32) WebRtcNetEQ_kPrblCf[PFind[fs_mult+flag]][1]); + temp_term_2 = WEBRTC_SPL_MUL(Num, + (WebRtc_Word32) WebRtcNetEQ_kPrblCf[PFind[fs_mult+flag]][2]); + temp_term_3 = WEBRTC_SPL_MUL_16_16(pw16_3pts[0],256); + + *pw16_outVal + = (WebRtc_Word16) ((temp_term_1 + temp_term_2 + temp_term_3) >> 8); + + *pw16_Ind = (*pw16_Ind) * (fs_mult << 1) + flag; + flag = 0; + } + else + { + flag++; + lmt += stp; + } + } + + } + else + { + *pw16_outVal = pw16_3pts[1]; + *pw16_Ind = (*pw16_Ind) * 2 * fs_mult; + } + + return 0; +} + diff --git a/src/libs/webrtc/neteq/preemptive_expand.c b/src/libs/webrtc/neteq/preemptive_expand.c new file mode 100644 index 00000000..7867b36d --- /dev/null +++ b/src/libs/webrtc/neteq/preemptive_expand.c @@ -0,0 +1,525 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the Pre-emptive Expand algorithm that is used to increase + * the delay by repeating a part of the audio stream. + */ + +#include "dsp.h" + +#include "signal_processing_library.h" + +#include "dsp_helpfunctions.h" +#include "neteq_error_codes.h" + +#define PREEMPTIVE_CORR_LEN 50 +#define PREEMPTIVE_MIN_LAG 10 +#define PREEMPTIVE_MAX_LAG 60 +#define PREEMPTIVE_DOWNSAMPLED_LEN (PREEMPTIVE_CORR_LEN + PREEMPTIVE_MAX_LAG) + +/* Scratch usage: + + Type Name size startpos endpos + WebRtc_Word16 pw16_downSampSpeech 110 0 109 + WebRtc_Word32 pw32_corr 2*50 110 209 + WebRtc_Word16 pw16_corr 50 0 49 + + Total: 110+2*50 + */ + +#define SCRATCH_PW16_DS_SPEECH 0 +#define SCRATCH_PW32_CORR PREEMPTIVE_DOWNSAMPLED_LEN +#define SCRATCH_PW16_CORR 0 + +/**************************************************************************** + * WebRtcNetEQ_PreEmptiveExpand(...) + * + * This function tries to extend the audio data by repeating one or several + * pitch periods. The operation is only carried out if the correlation is + * strong or if the signal energy is very low. The algorithm is the + * reciprocal of the Accelerate algorithm. + * + * Input: + * - inst : NetEQ DSP instance + * - scratchPtr : Pointer to scratch vector. + * - decoded : Pointer to newly decoded speech. + * - len : Length of decoded speech. + * - oldDataLen : Length of the part of decoded that has already been played out. + * - BGNonly : If non-zero, Pre-emptive Expand will only copy + * the first DEFAULT_TIME_ADJUST seconds of the + * input and append to the end. No signal matching is + * done. + * + * Output: + * - inst : Updated instance + * - outData : Pointer to a memory space where the output data + * should be stored. The vector must be at least + * min(len + 120*fs/8000, NETEQ_MAX_OUTPUT_SIZE) + * elements long. + * - pw16_len : Number of samples written to outData. + * + * Return value : 0 - Ok + * <0 - Error + */ + +int WebRtcNetEQ_PreEmptiveExpand(DSPInst_t *inst, +#ifdef SCRATCH + WebRtc_Word16 *pw16_scratchPtr, +#endif + const WebRtc_Word16 *pw16_decoded, int len, int oldDataLen, + WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_len, + WebRtc_Word16 BGNonly) +{ + +#ifdef SCRATCH + /* Use scratch memory for internal temporary vectors */ + WebRtc_Word16 *pw16_downSampSpeech = pw16_scratchPtr + SCRATCH_PW16_DS_SPEECH; + WebRtc_Word32 *pw32_corr = (WebRtc_Word32*) (pw16_scratchPtr + SCRATCH_PW32_CORR); + WebRtc_Word16 *pw16_corr = pw16_scratchPtr + SCRATCH_PW16_CORR; +#else + /* Allocate memory for temporary vectors */ + WebRtc_Word16 pw16_downSampSpeech[PREEMPTIVE_DOWNSAMPLED_LEN]; + WebRtc_Word32 pw32_corr[PREEMPTIVE_CORR_LEN]; + WebRtc_Word16 pw16_corr[PREEMPTIVE_CORR_LEN]; +#endif + WebRtc_Word16 w16_decodedMax = 0; + WebRtc_Word16 w16_tmp; + WebRtc_Word16 w16_tmp2; + WebRtc_Word32 w32_tmp; + WebRtc_Word32 w32_tmp2; + + const WebRtc_Word16 w16_startLag = PREEMPTIVE_MIN_LAG; + const WebRtc_Word16 w16_endLag = PREEMPTIVE_MAX_LAG; + const WebRtc_Word16 w16_corrLen = PREEMPTIVE_CORR_LEN; + const WebRtc_Word16 *pw16_vec1, *pw16_vec2; + WebRtc_Word16 *pw16_vectmp; + WebRtc_Word16 w16_inc, w16_startfact; + WebRtc_Word16 w16_bestIndex, w16_bestVal; + WebRtc_Word16 w16_VAD = 1; + WebRtc_Word16 fsMult; + WebRtc_Word16 fsMult120; + WebRtc_Word32 w32_en1, w32_en2, w32_cc; + WebRtc_Word16 w16_en1, w16_en2; + WebRtc_Word16 w16_en1Scale, w16_en2Scale; + WebRtc_Word16 w16_sqrtEn1En2; + WebRtc_Word16 w16_bestCorr = 0; + int ok; + +#ifdef NETEQ_STEREO + MasterSlaveInfo *msInfo = inst->msInfo; +#endif + + fsMult = WebRtcNetEQ_CalcFsMult(inst->fs); /* Calculate fs/8000 */ + + /* Pre-calculate common multiplication with fsMult */ + fsMult120 = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16(fsMult, 120); /* 15 ms */ + + inst->ExpandInst.w16_consecExp = 0; /* Last was not expand any more */ + + /* + * Sanity check for len variable; must be (almost) 30 ms (120*fsMult + max(bestIndex)). + * Also, the new part must be at least .625 ms (w16_overlap). + */ + if (len < (WebRtc_Word16) WEBRTC_SPL_MUL_16_16((120 + 119), fsMult) || oldDataLen >= len + - inst->ExpandInst.w16_overlap) + { + /* Length of decoded data too short */ + inst->w16_mode = MODE_UNSUCCESS_PREEMPTIVE; + *pw16_len = len; + + + /* simply move all data from decoded to outData */ + + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, (WebRtc_Word16) len); + + return NETEQ_OTHER_ERROR; + } + + /***********************************/ + /* Special operations for BGN only */ + /***********************************/ + + /* Check if "background noise only" flag is set */ + if (BGNonly) + { + /* special operation for BGN only; simply insert a chunk of data */ + w16_bestIndex = DEFAULT_TIME_ADJUST * (fsMult << 3); /* X*fs/1000 */ + + /* Sanity check for bestIndex */ + if (w16_bestIndex > len) + { /* not good, do nothing instead */ + inst->w16_mode = MODE_UNSUCCESS_PREEMPTIVE; + *pw16_len = len; + + + /* simply move all data from decoded to outData */ + + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, (WebRtc_Word16) len); + + return NETEQ_OTHER_ERROR; + } + + /* set length parameter */ + *pw16_len = len + w16_bestIndex; + + + /* copy to output */ + + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, len); + WEBRTC_SPL_MEMCPY_W16(&pw16_outData[len], pw16_decoded, w16_bestIndex); + + /* set mode */ + inst->w16_mode = MODE_LOWEN_PREEMPTIVE; + + /* update statistics */ + inst->statInst.preemptiveLength += w16_bestIndex; + + return 0; + } /* end of special code for BGN mode */ + +#ifdef NETEQ_STEREO + + /* Sanity for msInfo */ + if (msInfo == NULL) + { + /* this should not happen here */ + return MASTER_SLAVE_ERROR; + } + + if ((msInfo->msMode == NETEQ_MASTER) || (msInfo->msMode == NETEQ_MONO)) + { + /* Find correlation lag only for non-slave instances */ + +#endif + + /****************************************************************/ + /* Find the strongest correlation lag by downsampling to 4 kHz, */ + /* calculating correlation for downsampled signal and finding */ + /* the strongest correlation peak. */ + /****************************************************************/ + + /* find maximum absolute value */ + w16_decodedMax = WebRtcSpl_MaxAbsValueW16(pw16_decoded, (WebRtc_Word16) len); + + /* downsample the decoded speech to 4 kHz */ + ok = WebRtcNetEQ_DownSampleTo4kHz(pw16_decoded, len, inst->fs, pw16_downSampSpeech, + PREEMPTIVE_DOWNSAMPLED_LEN, 1 /* compensate delay*/); + if (ok != 0) + { + /* error */ + inst->w16_mode = MODE_UNSUCCESS_PREEMPTIVE; + *pw16_len = len; + + + /* simply move all data from decoded to outData */ + + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, (WebRtc_Word16) len); + + return NETEQ_OTHER_ERROR; + } + + /* + * Set scaling factor for cross correlation to protect against + * overflow (log2(50) => 6) + */ + w16_tmp = 6 - WebRtcSpl_NormW32(WEBRTC_SPL_MUL_16_16(w16_decodedMax, w16_decodedMax)); + w16_tmp = WEBRTC_SPL_MAX(0, w16_tmp); + + /* Perform correlation from lag 10 to lag 60 in 4 kHz domain */WebRtcNetEQ_CrossCorr( + pw32_corr, &pw16_downSampSpeech[w16_endLag], + &pw16_downSampSpeech[w16_endLag - w16_startLag], w16_corrLen, + (WebRtc_Word16) (w16_endLag - w16_startLag), w16_tmp, -1); + + /* Normalize correlation to 14 bits and put in a WebRtc_Word16 vector */ + w32_tmp = WebRtcSpl_MaxAbsValueW32(pw32_corr, w16_corrLen); + w16_tmp = 17 - WebRtcSpl_NormW32(w32_tmp); + w16_tmp = WEBRTC_SPL_MAX(0, w16_tmp); + + WebRtcSpl_VectorBitShiftW32ToW16(pw16_corr, w16_corrLen, pw32_corr, w16_tmp); + + /* Find limits for peak finding, in order to avoid overful NetEQ algorithm buffer. */ + /* Calculate difference between MAX_OUTPUT_SIZE and len in 4 kHz domain. */ + w16_tmp = WebRtcSpl_DivW32W16ResW16((WebRtc_Word32) (NETEQ_MAX_OUTPUT_SIZE - len), + (WebRtc_Word16) (fsMult << 1)) - w16_startLag; + w16_tmp = WEBRTC_SPL_MIN(w16_corrLen, w16_tmp); /* no more than corrLen = 50 */ + +#ifdef NETEQ_STEREO + } /* end if (msInfo->msMode != NETEQ_SLAVE) */ + + if ((msInfo->msMode == NETEQ_MASTER) || (msInfo->msMode == NETEQ_MONO)) + { + /* Find the strongest correlation peak by using the parabolic fit method */ + WebRtcNetEQ_PeakDetection(pw16_corr, w16_tmp, 1, fsMult, &w16_bestIndex, &w16_bestVal); + /* 0 <= bestIndex <= (2*w16_tmp - 1)*fsMult <= (2*corrLen - 1)*fsMult = 99*fsMult */ + + /* Compensate bestIndex for displaced starting position */ + w16_bestIndex = w16_bestIndex + w16_startLag * WEBRTC_SPL_LSHIFT_W16(fsMult, 1); + /* 20*fsMult <= bestIndex <= 119*fsMult */ + + msInfo->bestIndex = w16_bestIndex; + } + else if (msInfo->msMode == NETEQ_SLAVE) + { + if (msInfo->extraInfo == PE_EXP_FAIL) + { + /* Master has signaled an unsuccessful preemptive expand */ + w16_bestIndex = 0; + } + else + { + /* Get best index from master */ + w16_bestIndex = msInfo->bestIndex; + } + } + else + { + /* Invalid mode */ + return (MASTER_SLAVE_ERROR); + } + +#else /* NETEQ_STEREO */ + + /* Find the strongest correlation peak by using the parabolic fit method */ + WebRtcNetEQ_PeakDetection(pw16_corr, w16_tmp, 1, fsMult, &w16_bestIndex, &w16_bestVal); + /* 0 <= bestIndex <= (2*w16_tmp - 1)*fsMult <= (2*corrLen - 1)*fsMult = 99*fsMult */ + + /* Compensate bestIndex for displaced starting position */ + w16_bestIndex = w16_bestIndex + w16_startLag * WEBRTC_SPL_LSHIFT_W16(fsMult, 1); + /* 20*fsMult <= bestIndex <= 119*fsMult */ + +#endif /* NETEQ_STEREO */ + +#ifdef NETEQ_STEREO + + if ((msInfo->msMode == NETEQ_MASTER) || (msInfo->msMode == NETEQ_MONO)) + { + /* Calculate correlation only for non-slave instances */ + +#endif /* NETEQ_STEREO */ + + /*****************************************************/ + /* Calculate correlation bestCorr for the found lag. */ + /* Also do a simple VAD decision. */ + /*****************************************************/ + + /* + * Calculate scaling to ensure that bestIndex samples can be square-summed + * without overflowing + */ + w16_tmp = (31 + - WebRtcSpl_NormW32(WEBRTC_SPL_MUL_16_16(w16_decodedMax, w16_decodedMax))); + w16_tmp += (31 - WebRtcSpl_NormW32(w16_bestIndex)); + w16_tmp -= 31; + w16_tmp = WEBRTC_SPL_MAX(0, w16_tmp); + + /* vec1 starts at 15 ms minus one pitch period */ + pw16_vec1 = &pw16_decoded[fsMult120 - w16_bestIndex]; + /* vec2 start at 15 ms */ + pw16_vec2 = &pw16_decoded[fsMult120]; + + /* Calculate energies for vec1 and vec2 */ + w32_en1 = WebRtcNetEQ_DotW16W16((WebRtc_Word16*) pw16_vec1, + (WebRtc_Word16*) pw16_vec1, w16_bestIndex, w16_tmp); + w32_en2 = WebRtcNetEQ_DotW16W16((WebRtc_Word16*) pw16_vec2, + (WebRtc_Word16*) pw16_vec2, w16_bestIndex, w16_tmp); + + /* Calculate cross-correlation at the found lag */ + w32_cc = WebRtcNetEQ_DotW16W16((WebRtc_Word16*) pw16_vec1, (WebRtc_Word16*) pw16_vec2, + w16_bestIndex, w16_tmp); + + /* Check VAD constraint + ((en1+en2)/(2*bestIndex)) <= 8*inst->BGNInst.energy */ + w32_tmp = WEBRTC_SPL_RSHIFT_W32(w32_en1 + w32_en2, 4); /* (en1+en2)/(2*8) */ + if (inst->BGNInst.w16_initialized == 1) + { + w32_tmp2 = inst->BGNInst.w32_energy; + } + else + { + /* if BGN parameters have not been estimated, use a fixed threshold */ + w32_tmp2 = 75000; + } + w16_tmp2 = 16 - WebRtcSpl_NormW32(w32_tmp2); + w16_tmp2 = WEBRTC_SPL_MAX(0, w16_tmp2); + w32_tmp = WEBRTC_SPL_RSHIFT_W32(w32_tmp, w16_tmp2); + w16_tmp2 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(w32_tmp2, w16_tmp2); + w32_tmp2 = WEBRTC_SPL_MUL_16_16(w16_bestIndex, w16_tmp2); + + /* Scale w32_tmp properly before comparing with w32_tmp2 */ + /* (w16_tmp is scaling before energy calculation, thus 2*w16_tmp) */ + if (WebRtcSpl_NormW32(w32_tmp) < WEBRTC_SPL_LSHIFT_W32(w16_tmp,1)) + { + /* Cannot scale only w32_tmp, must scale w32_temp2 too */ + WebRtc_Word16 tempshift = WebRtcSpl_NormW32(w32_tmp); + w32_tmp = WEBRTC_SPL_LSHIFT_W32(w32_tmp, tempshift); + w32_tmp2 = WEBRTC_SPL_RSHIFT_W32(w32_tmp2, + WEBRTC_SPL_LSHIFT_W32(w16_tmp,1) - tempshift); + } + else + { + w32_tmp = WEBRTC_SPL_LSHIFT_W32(w32_tmp, + WEBRTC_SPL_LSHIFT_W32(w16_tmp,1)); + } + + if (w32_tmp <= w32_tmp2) /*((en1+en2)/(2*bestIndex)) <= 8*inst->BGNInst.energy */ + { + /* The signal seems to be passive speech */ + w16_VAD = 0; + w16_bestCorr = 0; /* Correlation does not matter */ + + /* For low energy expansion, the new data can be less than 15 ms, + but we must ensure that bestIndex is not larger than the new data. */ + w16_bestIndex = WEBRTC_SPL_MIN( w16_bestIndex, len - oldDataLen ); + } + else + { + /* The signal is active speech */ + w16_VAD = 1; + + /* Calculate correlation (cc/sqrt(en1*en2)) */ + + /* Start with calculating scale values */ + w16_en1Scale = 16 - WebRtcSpl_NormW32(w32_en1); + w16_en1Scale = WEBRTC_SPL_MAX(0, w16_en1Scale); + w16_en2Scale = 16 - WebRtcSpl_NormW32(w32_en2); + w16_en2Scale = WEBRTC_SPL_MAX(0, w16_en2Scale); + + /* Make sure total scaling is even (to simplify scale factor after sqrt) */ + if ((w16_en1Scale + w16_en2Scale) & 1) + { + w16_en1Scale += 1; + } + + /* Convert energies to WebRtc_Word16 */ + w16_en1 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(w32_en1, w16_en1Scale); + w16_en2 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(w32_en2, w16_en2Scale); + + /* Calculate energy product */ + w32_tmp = WEBRTC_SPL_MUL_16_16(w16_en1, w16_en2); + + /* Calculate square-root of energy product */ + w16_sqrtEn1En2 = (WebRtc_Word16) WebRtcSpl_Sqrt(w32_tmp); + + /* Calculate cc/sqrt(en1*en2) in Q14 */ + w16_tmp = 14 - ((w16_en1Scale + w16_en2Scale) >> 1); + w32_cc = WEBRTC_SPL_SHIFT_W32(w32_cc, w16_tmp); + w32_cc = WEBRTC_SPL_MAX(0, w32_cc); /* Don't divide with negative number */ + w16_bestCorr = (WebRtc_Word16) WebRtcSpl_DivW32W16(w32_cc, w16_sqrtEn1En2); + w16_bestCorr = WEBRTC_SPL_MIN(16384, w16_bestCorr); /* set maximum to 1.0 */ + } + +#ifdef NETEQ_STEREO + + } /* end if (msInfo->msMode != NETEQ_SLAVE) */ + +#endif /* NETEQ_STEREO */ + + /*******************************************************/ + /* Check preemptive expand criteria and insert samples */ + /*******************************************************/ + + /* Check for strong correlation (>0.9) and at least 15 ms new data, + or passive speech */ +#ifdef NETEQ_STEREO + if (((((w16_bestCorr > 14746) && (oldDataLen <= fsMult120)) || (w16_VAD == 0)) + && (msInfo->msMode != NETEQ_SLAVE)) || ((msInfo->msMode == NETEQ_SLAVE) + && (msInfo->extraInfo != PE_EXP_FAIL))) +#else + if (((w16_bestCorr > 14746) && (oldDataLen <= fsMult120)) + || (w16_VAD == 0)) +#endif + { + /* Do expand operation by overlap add */ + + /* Set length of the first part, not to be modified */ + WebRtc_Word16 w16_startIndex = WEBRTC_SPL_MAX(oldDataLen, fsMult120); + + /* + * Calculate cross-fading slope so that the fading factor goes from + * 1 (16384 in Q14) to 0 in one pitch period (bestIndex). + */ + w16_inc = (WebRtc_Word16) WebRtcSpl_DivW32W16((WebRtc_Word32) 16384, + (WebRtc_Word16) (w16_bestIndex + 1)); /* in Q14 */ + + /* Initiate fading factor */ + w16_startfact = 16384 - w16_inc; + + /* vec1 starts at 15 ms minus one pitch period */ + pw16_vec1 = &pw16_decoded[w16_startIndex - w16_bestIndex]; + /* vec2 start at 15 ms */ + pw16_vec2 = &pw16_decoded[w16_startIndex]; + + + /* Copy unmodified part [0 to 15 ms] */ + + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, w16_startIndex); + + /* Generate interpolated part of length bestIndex (1 pitch period) */ + pw16_vectmp = pw16_outData + w16_startIndex; + /* Reuse mixing function from Expand */ + WebRtcNetEQ_MixVoiceUnvoice(pw16_vectmp, (WebRtc_Word16*) pw16_vec2, + (WebRtc_Word16*) pw16_vec1, &w16_startfact, w16_inc, w16_bestIndex); + + /* Move the last part (also unmodified) */ + /* Take from decoded at 15 ms */ + pw16_vec2 = &pw16_decoded[w16_startIndex]; + WEBRTC_SPL_MEMMOVE_W16(&pw16_outData[w16_startIndex + w16_bestIndex], pw16_vec2, + (WebRtc_Word16) (len - w16_startIndex)); + + /* Set the mode flag */ + if (w16_VAD) + { + inst->w16_mode = MODE_SUCCESS_PREEMPTIVE; + } + else + { + inst->w16_mode = MODE_LOWEN_PREEMPTIVE; + } + + /* Calculate resulting length = original length + pitch period */ + *pw16_len = len + w16_bestIndex; + + /* Update in-call statistics */ + inst->statInst.preemptiveLength += w16_bestIndex; + + return 0; + } + else + { + /* Preemptive Expand not allowed */ + +#ifdef NETEQ_STEREO + /* Signal to slave(s) that this was unsuccessful */ + if (msInfo->msMode == NETEQ_MASTER) + { + msInfo->extraInfo = PE_EXP_FAIL; + } +#endif + + /* Set mode flag to unsuccessful preemptive expand */ + inst->w16_mode = MODE_UNSUCCESS_PREEMPTIVE; + + /* Length is unmodified */ + *pw16_len = len; + + + /* Simply move all data from decoded to outData */ + + WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, (WebRtc_Word16) len); + + return 0; + } +} + +#undef SCRATCH_PW16_DS_SPEECH +#undef SCRATCH_PW32_CORR +#undef SCRATCH_PW16_CORR + diff --git a/src/libs/webrtc/neteq/random_vector.c b/src/libs/webrtc/neteq/random_vector.c new file mode 100644 index 00000000..217bacda --- /dev/null +++ b/src/libs/webrtc/neteq/random_vector.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This function generates a pseudo-random vector. + */ + +#include "dsp_helpfunctions.h" + +/* + * Values are normalized so that + * sqrt(dot(pw16_NETEQFIX_RANDN_TBL,pw16_NETEQFIX_RANDN_TBL)/256)=2^13 + */ +const WebRtc_Word16 WebRtcNetEQ_kRandnTbl[RANDVEC_NO_OF_SAMPLES] = +{ + 2680, 5532, 441, 5520, 16170, -5146, -1024, -8733, 3115, 9598, -10380, -4959, -1280, -21716, 7133, -1522, + 13458, -3902, 2789, -675, 3441, 5016, -13599, -4003, -2739, 3922, -7209, 13352, -11617, -7241, 12905, -2314, + 5426, 10121, -9702, 11207, -13542, 1373, 816, -5934, -12504, 4798, 1811, 4112, -613, 201, -10367, -2960, + -2419, 3442, 4299, -6116, -6092, 1552, -1650, -480, -1237, 18720, -11858, -8303, -8212, 865, -2890, -16968, + 12052, -5845, -5912, 9777, -5665, -6294, 5426, -4737, -6335, 1652, 761, 3832, 641, -8552, -9084, -5753, + 8146, 12156, -4915, 15086, -1231, -1869, 11749, -9319, -6403, 11407, 6232, -1683, 24340, -11166, 4017, -10448, + 3153, -2936, 6212, 2891, -866, -404, -4807, -2324, -1917, -2388, -6470, -3895, -10300, 5323, -5403, 2205, + 4640, 7022, -21186, -6244, -882, -10031, -3395, -12885, 7155, -5339, 5079, -2645, -9515, 6622, 14651, 15852, + 359, 122, 8246, -3502, -6696, -3679, -13535, -1409, -704, -7403, -4007, 1798, 279, -420, -12796, -14219, + 1141, 3359, 11434, 7049, -6684, -7473, 14283, -4115, -9123, -8969, 4152, 4117, 13792, 5742, 16168, 8661, + -1609, -6095, 1881, 14380, -5588, 6758, -6425, -22969, -7269, 7031, 1119, -1611, -5850, -11281, 3559, -8952, + -10146, -4667, -16251, -1538, 2062, -1012, -13073, 227, -3142, -5265, 20, 5770, -7559, 4740, -4819, 992, + -8208, -7130, -4652, 6725, 7369, -1036, 13144, -1588, -5304, -2344, -449, -5705, -8894, 5205, -17904, -11188, + -1022, 4852, 10101, -5255, -4200, -752, 7941, -1543, 5959, 14719, 13346, 17045, -15605, -1678, -1600, -9230, + 68, 23348, 1172, 7750, 11212, -18227, 9956, 4161, 883, 3947, 4341, 1014, -4889, -2603, 1246, -5630, + -3596, -870, -1298, 2784, -3317, -6612, -20541, 4166, 4181, -8625, 3562, 12890, 4761, 3205, -12259, -8579 +}; + + +void WebRtcNetEQ_RandomVec(WebRtc_UWord32 *w32_seed, WebRtc_Word16 *pw16_randVec, + WebRtc_Word16 w16_len, WebRtc_Word16 w16_incval) +{ + int i; + WebRtc_Word16 w16_pos; + for (i = 0; i < w16_len; i++) + { + *w32_seed = (*w32_seed) + w16_incval; + w16_pos = (WebRtc_Word16) ((*w32_seed) & (RANDVEC_NO_OF_SAMPLES - 1)); + pw16_randVec[i] = WebRtcNetEQ_kRandnTbl[w16_pos]; + } +} + diff --git a/src/libs/webrtc/neteq/recin.c b/src/libs/webrtc/neteq/recin.c new file mode 100644 index 00000000..b7fb5f27 --- /dev/null +++ b/src/libs/webrtc/neteq/recin.c @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Implementation of the RecIn function, which is the main function for inserting RTP + * packets into NetEQ. + */ + +#include "mcu.h" + +#include <string.h> + +#include "signal_processing_library.h" + +#include "automode.h" +#include "dtmf_buffer.h" +#include "neteq_defines.h" +#include "neteq_error_codes.h" + + +int WebRtcNetEQ_RecInInternal(MCUInst_t *MCU_inst, RTPPacket_t *RTPpacketInput, + WebRtc_UWord32 uw32_timeRec) +{ + RTPPacket_t RTPpacket[2]; + int i_k; + int i_ok = 0, i_No_Of_Payloads = 1; + WebRtc_Word16 flushed = 0; + WebRtc_Word16 codecPos; + WebRtc_UWord32 diffTS, uw32_tmp; + int curr_Codec; + WebRtc_Word16 isREDPayload = 0; + WebRtc_Word32 temp_bufsize = MCU_inst->PacketBuffer_inst.numPacketsInBuffer; +#ifdef NETEQ_RED_CODEC + RTPPacket_t* RTPpacketPtr[2]; /* Support for redundancy up to 2 payloads */ + RTPpacketPtr[0] = &RTPpacket[0]; + RTPpacketPtr[1] = &RTPpacket[1]; +#endif + + /* + * Copy from input RTP packet to local copy + * (mainly to enable multiple payloads using RED) + */ + + WEBRTC_SPL_MEMCPY_W8(&RTPpacket[0], RTPpacketInput, sizeof(RTPPacket_t)); + + /* Reinitialize NetEq if it's needed (changed SSRC or first call) */ + + if ((RTPpacket[0].ssrc != MCU_inst->ssrc) || (MCU_inst->first_packet == 1)) + { + WebRtcNetEQ_RTCPInit(&MCU_inst->RTCP_inst, RTPpacket[0].seqNumber); + MCU_inst->first_packet = 0; + + /* Flush the buffer */ + WebRtcNetEQ_PacketBufferFlush(&MCU_inst->PacketBuffer_inst); + + /* Store new SSRC */ + MCU_inst->ssrc = RTPpacket[0].ssrc; + + /* Update codecs */ + MCU_inst->timeStamp = RTPpacket[0].timeStamp; + MCU_inst->current_Payload = RTPpacket[0].payloadType; + + /*Set MCU to update codec on next SignalMCU call */ + MCU_inst->new_codec = 1; + + /* Reset timestamp scaling */ + MCU_inst->TSscalingInitialized = 0; + + } + + /* Call RTCP statistics */ + i_ok |= WebRtcNetEQ_RTCPUpdate(&(MCU_inst->RTCP_inst), RTPpacket[0].seqNumber, + RTPpacket[0].timeStamp, uw32_timeRec); + + /* If Redundancy is supported and this is the redundancy payload, separate the payloads */ +#ifdef NETEQ_RED_CODEC + if (RTPpacket[0].payloadType == WebRtcNetEQ_DbGetPayload(&MCU_inst->codec_DB_inst, + kDecoderRED)) + { + + /* Split the payload into a main and a redundancy payloads */ + i_ok = WebRtcNetEQ_RedundancySplit(RTPpacketPtr, 2, &i_No_Of_Payloads); + if (i_ok < 0) + { + /* error returned */ + return i_ok; + } + + /* + * Only accept a few redundancies of the same type as the main data, + * AVT events and CNG. + */ + if ((i_No_Of_Payloads > 1) && (RTPpacket[0].payloadType != RTPpacket[1].payloadType) + && (RTPpacket[0].payloadType != WebRtcNetEQ_DbGetPayload(&MCU_inst->codec_DB_inst, + kDecoderAVT)) && (RTPpacket[1].payloadType != WebRtcNetEQ_DbGetPayload( + &MCU_inst->codec_DB_inst, kDecoderAVT)) && (!WebRtcNetEQ_DbIsCNGPayload( + &MCU_inst->codec_DB_inst, RTPpacket[0].payloadType)) + && (!WebRtcNetEQ_DbIsCNGPayload(&MCU_inst->codec_DB_inst, RTPpacket[1].payloadType))) + { + i_No_Of_Payloads = 1; + } + isREDPayload = 1; + } +#endif + + /* loop over the number of payloads */ + for (i_k = 0; i_k < i_No_Of_Payloads; i_k++) + { + + if (isREDPayload == 1) + { + RTPpacket[i_k].rcuPlCntr = i_k; + } + else + { + RTPpacket[i_k].rcuPlCntr = 0; + } + + /* Force update of SplitInfo if it's iLBC because of potential change between 20/30ms */ + if (RTPpacket[i_k].payloadType == WebRtcNetEQ_DbGetPayload(&MCU_inst->codec_DB_inst, + kDecoderILBC)) + { + i_ok = WebRtcNetEQ_DbGetSplitInfo( + &MCU_inst->PayloadSplit_inst, + (enum WebRtcNetEQDecoder) WebRtcNetEQ_DbGetCodec(&MCU_inst->codec_DB_inst, + RTPpacket[i_k].payloadType), RTPpacket[i_k].payloadLen); + if (i_ok < 0) + { + /* error returned */ + return i_ok; + } + } + + /* Get information about timestamp scaling for this payload type */ + i_ok = WebRtcNetEQ_GetTimestampScaling(MCU_inst, RTPpacket[i_k].payloadType); + if (i_ok < 0) + { + /* error returned */ + return i_ok; + } + + if (MCU_inst->TSscalingInitialized == 0 && MCU_inst->scalingFactor != kTSnoScaling) + { + /* Must initialize scaling with current timestamps */ + MCU_inst->externalTS = RTPpacket[i_k].timeStamp; + MCU_inst->internalTS = RTPpacket[i_k].timeStamp; + MCU_inst->TSscalingInitialized = 1; + } + + /* Adjust timestamp if timestamp scaling is needed (e.g. SILK or G.722) */ + if (MCU_inst->TSscalingInitialized == 1) + { + WebRtc_UWord32 newTS = WebRtcNetEQ_ScaleTimestampExternalToInternal(MCU_inst, + RTPpacket[i_k].timeStamp); + + /* save the incoming timestamp for next time */ + MCU_inst->externalTS = RTPpacket[i_k].timeStamp; + + /* add the scaled difference to last scaled timestamp and save ... */ + MCU_inst->internalTS = newTS; + + RTPpacket[i_k].timeStamp = newTS; + } + + /* Is this a DTMF packet?*/ + if (RTPpacket[i_k].payloadType == WebRtcNetEQ_DbGetPayload(&MCU_inst->codec_DB_inst, + kDecoderAVT)) + { +#ifdef NETEQ_ATEVENT_DECODE + if (MCU_inst->AVT_PlayoutOn) + { + i_ok = WebRtcNetEQ_DtmfInsertEvent(&MCU_inst->DTMF_inst, + RTPpacket[i_k].payload, RTPpacket[i_k].payloadLen, + RTPpacket[i_k].timeStamp); + if (i_ok != 0) + { + return i_ok; + } + } +#endif +#ifdef NETEQ_STEREO + if (MCU_inst->usingStereo == 0) + { + /* do not set this for DTMF packets when using stereo mode */ + MCU_inst->BufferStat_inst.Automode_inst.lastPackCNGorDTMF = 1; + } +#else + MCU_inst->BufferStat_inst.Automode_inst.lastPackCNGorDTMF = 1; +#endif + } + else if (WebRtcNetEQ_DbIsCNGPayload(&MCU_inst->codec_DB_inst, + RTPpacket[i_k].payloadType)) + { + /* Is this a CNG packet? how should we handle this?*/ +#ifdef NETEQ_CNG_CODEC + /* Get CNG sample rate */ + WebRtc_UWord16 fsCng = WebRtcNetEQ_DbGetSampleRate(&MCU_inst->codec_DB_inst, + RTPpacket[i_k].payloadType); + if ((fsCng != MCU_inst->fs) && (fsCng > 8000)) + { + /* + * We have received CNG with a different sample rate from what we are using + * now (must be > 8000, since we may use only one CNG type (default) for all + * frequencies). Flush buffer and signal new codec. + */ + WebRtcNetEQ_PacketBufferFlush(&MCU_inst->PacketBuffer_inst); + MCU_inst->new_codec = 1; + MCU_inst->current_Codec = -1; + } + i_ok = WebRtcNetEQ_PacketBufferInsert(&MCU_inst->PacketBuffer_inst, + &RTPpacket[i_k], &flushed); + if (i_ok < 0) + { + return RECIN_CNG_ERROR; + } + MCU_inst->BufferStat_inst.Automode_inst.lastPackCNGorDTMF = 1; +#else /* NETEQ_CNG_CODEC not defined */ + return RECIN_UNKNOWNPAYLOAD; +#endif /* NETEQ_CNG_CODEC */ + } + else + { + /* Reinitialize the splitting if the payload and/or the payload length has changed */ + curr_Codec = WebRtcNetEQ_DbGetCodec(&MCU_inst->codec_DB_inst, + RTPpacket[i_k].payloadType); + if (curr_Codec != MCU_inst->current_Codec) + { + if (curr_Codec < 0) + { + return RECIN_UNKNOWNPAYLOAD; + } + MCU_inst->current_Codec = curr_Codec; + MCU_inst->current_Payload = RTPpacket[i_k].payloadType; + i_ok = WebRtcNetEQ_DbGetSplitInfo(&MCU_inst->PayloadSplit_inst, + (enum WebRtcNetEQDecoder) MCU_inst->current_Codec, + RTPpacket[i_k].payloadLen); + if (i_ok < 0) + { /* error returned */ + return i_ok; + } + WebRtcNetEQ_PacketBufferFlush(&MCU_inst->PacketBuffer_inst); + MCU_inst->new_codec = 1; + } + + /* update post-call statistics */ + if (MCU_inst->new_codec != 1) /* not if in codec change */ + { + diffTS = RTPpacket[i_k].timeStamp - MCU_inst->timeStamp; /* waiting time */ + if (diffTS < 0x0FFFFFFF) /* guard against re-ordering */ + { + /* waiting time in ms */ + diffTS = WEBRTC_SPL_UDIV(diffTS, + WEBRTC_SPL_UDIV((WebRtc_UWord32) MCU_inst->fs, 1000) ); + if (diffTS < MCU_inst->statInst.minPacketDelayMs) + { + /* new all-time low */ + MCU_inst->statInst.minPacketDelayMs = diffTS; + } + if (diffTS > MCU_inst->statInst.maxPacketDelayMs) + { + /* new all-time high */ + MCU_inst->statInst.maxPacketDelayMs = diffTS; + } + + /* Update avg waiting time: + * avgPacketDelayMs = + * (avgPacketCount * avgPacketDelayMs + diffTS)/(avgPacketCount+1) + * with proper rounding. + */ + uw32_tmp + = WEBRTC_SPL_UMUL((WebRtc_UWord32) MCU_inst->statInst.avgPacketCount, + (WebRtc_UWord32) MCU_inst->statInst.avgPacketDelayMs); + uw32_tmp + = WEBRTC_SPL_ADD_SAT_W32(uw32_tmp, + (diffTS + (MCU_inst->statInst.avgPacketCount>>1))); + uw32_tmp = WebRtcSpl_DivU32U16(uw32_tmp, + (WebRtc_UWord16) (MCU_inst->statInst.avgPacketCount + 1)); + MCU_inst->statInst.avgPacketDelayMs + = (WebRtc_UWord16) WEBRTC_SPL_MIN(uw32_tmp, (WebRtc_UWord32) 65535); + + /* increase counter, but not to more than 65534 */ + if (MCU_inst->statInst.avgPacketCount < (0xFFFF - 1)) + { + MCU_inst->statInst.avgPacketCount++; + } + } + } + + /* Parse the payload and insert it into the buffer */ + i_ok = WebRtcNetEQ_SplitAndInsertPayload(&RTPpacket[i_k], + &MCU_inst->PacketBuffer_inst, &MCU_inst->PayloadSplit_inst, &flushed); + if (i_ok < 0) + { + return i_ok; + } + if (MCU_inst->BufferStat_inst.Automode_inst.lastPackCNGorDTMF != 0) + { + /* first normal packet after CNG or DTMF */ + MCU_inst->BufferStat_inst.Automode_inst.lastPackCNGorDTMF = -1; + } + } + /* Reset DSP timestamp etc. if packet buffer flushed */ + if (flushed) + { + MCU_inst->new_codec = 1; + } + } + + /* + * Update Bandwidth Estimate + * Only send the main payload to BWE + */ + if ((curr_Codec = WebRtcNetEQ_DbGetCodec(&MCU_inst->codec_DB_inst, + RTPpacket[0].payloadType)) >= 0) + { + codecPos = MCU_inst->codec_DB_inst.position[curr_Codec]; + if (MCU_inst->codec_DB_inst.funcUpdBWEst[codecPos] != NULL) /* codec has BWE function */ + { + if (RTPpacket[0].starts_byte1) /* check for shifted byte alignment */ + { + /* re-align to 16-bit alignment */ + for (i_k = 0; i_k < RTPpacket[0].payloadLen; i_k++) + { + WEBRTC_SPL_SET_BYTE(RTPpacket[0].payload, + WEBRTC_SPL_GET_BYTE(RTPpacket[0].payload, i_k+1), + i_k); + } + RTPpacket[0].starts_byte1 = 0; + } + + MCU_inst->codec_DB_inst.funcUpdBWEst[codecPos]( + MCU_inst->codec_DB_inst.codec_state[codecPos], + (G_CONST WebRtc_UWord16 *) RTPpacket[0].payload, + (WebRtc_Word32) RTPpacket[0].payloadLen, RTPpacket[0].seqNumber, + (WebRtc_UWord32) RTPpacket[0].timeStamp, (WebRtc_UWord32) uw32_timeRec); + } + } + + if (MCU_inst->BufferStat_inst.Automode_inst.lastPackCNGorDTMF == 0) + { + /* Calculate the total speech length carried in each packet */ + temp_bufsize = MCU_inst->PacketBuffer_inst.numPacketsInBuffer - temp_bufsize; + temp_bufsize *= MCU_inst->PacketBuffer_inst.packSizeSamples; + + if ((temp_bufsize > 0) && (MCU_inst->BufferStat_inst.Automode_inst.lastPackCNGorDTMF + == 0) && (temp_bufsize + != MCU_inst->BufferStat_inst.Automode_inst.packetSpeechLenSamp)) + { + /* Change the auto-mode parameters if packet length has changed */ + WebRtcNetEQ_SetPacketSpeechLen(&(MCU_inst->BufferStat_inst.Automode_inst), + (WebRtc_Word16) temp_bufsize, MCU_inst->fs); + } + + /* update statistics */ + if ((WebRtc_Word32) (RTPpacket[0].timeStamp - MCU_inst->timeStamp) >= 0 + && !MCU_inst->new_codec) + { + /* + * Only update statistics if incoming packet is not older than last played out + * packet, and if new codec flag is not set. + */ + WebRtcNetEQ_UpdateIatStatistics(&MCU_inst->BufferStat_inst.Automode_inst, + MCU_inst->PacketBuffer_inst.maxInsertPositions, RTPpacket[0].seqNumber, + RTPpacket[0].timeStamp, MCU_inst->fs, + WebRtcNetEQ_DbIsMDCodec((enum WebRtcNetEQDecoder) MCU_inst->current_Codec), + (MCU_inst->NetEqPlayoutMode == kPlayoutStreaming)); + } + } + else if (MCU_inst->BufferStat_inst.Automode_inst.lastPackCNGorDTMF == -1) + { + /* + * This is first "normal" packet after CNG or DTMF. + * Reset packet time counter and measure time until next packet, + * but don't update statistics. + */ + MCU_inst->BufferStat_inst.Automode_inst.lastPackCNGorDTMF = 0; + MCU_inst->BufferStat_inst.Automode_inst.packetIatCountSamp = 0; + } + return 0; + +} + +int WebRtcNetEQ_GetTimestampScaling(MCUInst_t *MCU_inst, int rtpPayloadType) +{ + enum WebRtcNetEQDecoder codec; + int codecNumber; + + codecNumber = WebRtcNetEQ_DbGetCodec(&MCU_inst->codec_DB_inst, rtpPayloadType); + if (codecNumber < 0) + { + /* error */ + return codecNumber; + } + + /* cast to enumerator */ + codec = (enum WebRtcNetEQDecoder) codecNumber; + + /* + * The factor obtained below is the number with which the RTP timestamp must be + * multiplied to get the true sample count. + */ + switch (codec) + { + case kDecoderG722: + { + /* Use timestamp scaling with factor 2 (two output samples per RTP timestamp) */ + MCU_inst->scalingFactor = kTSscalingTwo; + break; + } + case kDecoderAVT: + case kDecoderCNG: + { + /* do not change the timestamp scaling settings */ + break; + } + default: + { + /* do not use timestamp scaling */ + MCU_inst->scalingFactor = kTSnoScaling; + break; + } + } + return 0; +} + +WebRtc_UWord32 WebRtcNetEQ_ScaleTimestampExternalToInternal(const MCUInst_t *MCU_inst, + WebRtc_UWord32 externalTS) +{ + WebRtc_Word32 timestampDiff; + WebRtc_UWord32 internalTS; + + /* difference between this and last incoming timestamp */ + timestampDiff = externalTS - MCU_inst->externalTS; + + switch (MCU_inst->scalingFactor) + { + case kTSscalingTwo: + { + /* multiply with 2 */ + timestampDiff = WEBRTC_SPL_LSHIFT_W32(timestampDiff, 1); + break; + } + case kTSscalingTwoThirds: + { + /* multiply with 2/3 */ + timestampDiff = WEBRTC_SPL_LSHIFT_W32(timestampDiff, 1); + timestampDiff = WebRtcSpl_DivW32W16(timestampDiff, 3); + break; + } + case kTSscalingFourThirds: + { + /* multiply with 4/3 */ + timestampDiff = WEBRTC_SPL_LSHIFT_W32(timestampDiff, 2); + timestampDiff = WebRtcSpl_DivW32W16(timestampDiff, 3); + break; + } + default: + { + /* no scaling */ + } + } + + /* add the scaled difference to last scaled timestamp and save ... */ + internalTS = MCU_inst->internalTS + timestampDiff; + + return internalTS; +} + +WebRtc_UWord32 WebRtcNetEQ_ScaleTimestampInternalToExternal(const MCUInst_t *MCU_inst, + WebRtc_UWord32 internalTS) +{ + WebRtc_Word32 timestampDiff; + WebRtc_UWord32 externalTS; + + /* difference between this and last incoming timestamp */ + timestampDiff = (WebRtc_Word32) internalTS - MCU_inst->internalTS; + + switch (MCU_inst->scalingFactor) + { + case kTSscalingTwo: + { + /* divide by 2 */ + timestampDiff = WEBRTC_SPL_RSHIFT_W32(timestampDiff, 1); + break; + } + case kTSscalingTwoThirds: + { + /* multiply with 3/2 */ + timestampDiff = WEBRTC_SPL_MUL_32_16(timestampDiff, 3); + timestampDiff = WEBRTC_SPL_RSHIFT_W32(timestampDiff, 1); + break; + } + case kTSscalingFourThirds: + { + /* multiply with 3/4 */ + timestampDiff = WEBRTC_SPL_MUL_32_16(timestampDiff, 3); + timestampDiff = WEBRTC_SPL_RSHIFT_W32(timestampDiff, 2); + break; + } + default: + { + /* no scaling */ + } + } + + /* add the scaled difference to last scaled timestamp and save ... */ + externalTS = MCU_inst->externalTS + timestampDiff; + + return externalTS; +} diff --git a/src/libs/webrtc/neteq/recout.c b/src/libs/webrtc/neteq/recout.c new file mode 100644 index 00000000..63296f90 --- /dev/null +++ b/src/libs/webrtc/neteq/recout.c @@ -0,0 +1,1427 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Implementation of RecOut function, which is the main function for the audio output + * process. This function must be called (through the NetEQ API) once every 10 ms. + */ + +#include "dsp.h" + +#include <assert.h> +#include <string.h> /* to define NULL */ + +#include "signal_processing_library.h" + +#include "dsp_helpfunctions.h" +#include "neteq_error_codes.h" +#include "neteq_defines.h" +#include "mcu_dsp_common.h" + +/* Audio types */ +#define TYPE_SPEECH 1 +#define TYPE_CNG 2 + +#ifdef NETEQ_DELAY_LOGGING +#include "delay_logging.h" +#include <stdio.h> +#pragma message("*******************************************************************") +#pragma message("You have specified to use NETEQ_DELAY_LOGGING in the NetEQ library.") +#pragma message("Make sure that your test application supports this.") +#pragma message("*******************************************************************") +#endif + +/* Scratch usage: + + Type Name size startpos endpos + WebRtc_Word16 pw16_NetEqAlgorithm_buffer 600*fs/8000 0 600*fs/8000-1 + struct dspInfo 6 600*fs/8000 605*fs/8000 + + func WebRtcNetEQ_Normal 40+495*fs/8000 0 39+495*fs/8000 + func WebRtcNetEQ_Merge 40+496*fs/8000 0 39+496*fs/8000 + func WebRtcNetEQ_Expand 40+370*fs/8000 126*fs/800 39+496*fs/8000 + func WebRtcNetEQ_Accelerate 210 240*fs/8000 209+240*fs/8000 + func WebRtcNetEQ_BGNUpdate 69 480*fs/8000 68+480*fs/8000 + + Total: 605*fs/8000 + */ + +#define SCRATCH_ALGORITHM_BUFFER 0 +#define SCRATCH_NETEQ_NORMAL 0 +#define SCRATCH_NETEQ_MERGE 0 + +#if (defined(NETEQ_48KHZ_WIDEBAND)) +#define SCRATCH_DSP_INFO 3600 +#define SCRATCH_NETEQ_ACCELERATE 1440 +#define SCRATCH_NETEQ_BGN_UPDATE 2880 +#define SCRATCH_NETEQ_EXPAND 756 +#elif (defined(NETEQ_32KHZ_WIDEBAND)) +#define SCRATCH_DSP_INFO 2400 +#define SCRATCH_NETEQ_ACCELERATE 960 +#define SCRATCH_NETEQ_BGN_UPDATE 1920 +#define SCRATCH_NETEQ_EXPAND 504 +#elif (defined(NETEQ_WIDEBAND)) +#define SCRATCH_DSP_INFO 1200 +#define SCRATCH_NETEQ_ACCELERATE 480 +#define SCRATCH_NETEQ_BGN_UPDATE 960 +#define SCRATCH_NETEQ_EXPAND 252 +#else /* NB */ +#define SCRATCH_DSP_INFO 600 +#define SCRATCH_NETEQ_ACCELERATE 240 +#define SCRATCH_NETEQ_BGN_UPDATE 480 +#define SCRATCH_NETEQ_EXPAND 126 +#endif + +#if (defined(NETEQ_48KHZ_WIDEBAND)) +#define SIZE_SCRATCH_BUFFER 3636 +#elif (defined(NETEQ_32KHZ_WIDEBAND)) +#define SIZE_SCRATCH_BUFFER 2424 +#elif (defined(NETEQ_WIDEBAND)) +#define SIZE_SCRATCH_BUFFER 1212 +#else /* NB */ +#define SIZE_SCRATCH_BUFFER 606 +#endif + +#ifdef NETEQ_DELAY_LOGGING +extern FILE *delay_fid2; /* file pointer to delay log file */ +extern WebRtc_UWord32 tot_received_packets; +#endif + + +int WebRtcNetEQ_RecOutInternal(DSPInst_t *inst, WebRtc_Word16 *pw16_outData, + WebRtc_Word16 *pw16_len, WebRtc_Word16 BGNonly) +{ + + WebRtc_Word16 blockLen, payloadLen, len = 0, pos; + WebRtc_Word16 w16_tmp1, w16_tmp2, w16_tmp3, DataEnough; + WebRtc_Word16 *blockPtr; + WebRtc_Word16 MD = 0; + + WebRtc_Word16 speechType = TYPE_SPEECH; + WebRtc_UWord16 instr; + WebRtc_UWord16 uw16_tmp; +#ifdef SCRATCH + char pw8_ScratchBuffer[((SIZE_SCRATCH_BUFFER + 1) * 2)]; + WebRtc_Word16 *pw16_scratchPtr = (WebRtc_Word16*) pw8_ScratchBuffer; + WebRtc_Word16 pw16_decoded_buffer[NETEQ_MAX_FRAME_SIZE]; + WebRtc_Word16 *pw16_NetEqAlgorithm_buffer = pw16_scratchPtr + + SCRATCH_ALGORITHM_BUFFER; + DSP2MCU_info_t *dspInfo = (DSP2MCU_info_t*) (pw16_scratchPtr + SCRATCH_DSP_INFO); +#else + WebRtc_Word16 pw16_decoded_buffer[NETEQ_MAX_FRAME_SIZE]; + WebRtc_Word16 pw16_NetEqAlgorithm_buffer[NETEQ_MAX_OUTPUT_SIZE]; + DSP2MCU_info_t dspInfoStruct; + DSP2MCU_info_t *dspInfo = &dspInfoStruct; +#endif + WebRtc_Word16 fs_mult; + int borrowedSamples; + int oldBorrowedSamples; + int return_value = 0; + WebRtc_Word16 lastModeBGNonly = (inst->w16_mode & MODE_BGN_ONLY) != 0; /* check BGN flag */ + void *mainInstBackup = inst->main_inst; + +#ifdef NETEQ_DELAY_LOGGING + int i, j, temp_var; +#endif + WebRtc_Word16 dtmfValue = -1; + WebRtc_Word16 dtmfVolume = -1; + int playDtmf = 0; + int dtmfSwitch = 0; +#ifdef NETEQ_STEREO + MasterSlaveInfo *msInfo = inst->msInfo; +#endif + WebRtc_Word16 *sharedMem = pw16_NetEqAlgorithm_buffer; /* Reuse memory SHARED_MEM_SIZE size */ + inst->pw16_readAddress = sharedMem; + inst->pw16_writeAddress = sharedMem; + + /* Get information about if there is one descriptor left */ + if (inst->codec_ptr_inst.funcGetMDinfo != NULL) + { + MD = inst->codec_ptr_inst.funcGetMDinfo(inst->codec_ptr_inst.codec_state); + if (MD > 0) + MD = 1; + else + MD = 0; + } + +#ifdef NETEQ_STEREO + if ((msInfo->msMode == NETEQ_SLAVE) && (inst->codec_ptr_inst.funcDecode != NULL)) + { + /* + * Valid function pointers indicate that we have decoded something, + * and that the timestamp information is correct. + */ + + /* Get the information from master to correct synchronization */ + WebRtc_UWord32 currentMasterTimestamp; + WebRtc_UWord32 currentSlaveTimestamp; + + currentMasterTimestamp = msInfo->endTimestamp - msInfo->samplesLeftWithOverlap; + currentSlaveTimestamp = inst->endTimestamp - (inst->endPosition - inst->curPosition); + + if (currentSlaveTimestamp < currentMasterTimestamp) + { + /* brute-force discard a number of samples to catch up */ + inst->curPosition += currentMasterTimestamp - currentSlaveTimestamp; + + /* make sure we have at least "overlap" samples left */ + inst->curPosition = WEBRTC_SPL_MIN(inst->curPosition, + inst->endPosition - inst->ExpandInst.w16_overlap); + } + else if (currentSlaveTimestamp > currentMasterTimestamp) + { + /* back off current position to slow down */ + inst->curPosition -= currentSlaveTimestamp - currentMasterTimestamp; + + /* make sure we do not end up outside the speech history */ + inst->curPosition = WEBRTC_SPL_MAX(inst->curPosition, 0); + } + } +#endif + + /* Write status data to shared memory */ + dspInfo->playedOutTS = inst->endTimestamp; + dspInfo->samplesLeft = inst->endPosition - inst->curPosition + - inst->ExpandInst.w16_overlap; + dspInfo->MD = MD; + dspInfo->lastMode = inst->w16_mode; + dspInfo->frameLen = inst->w16_frameLen; + + /* Force update of codec if codec function is NULL */ + if (inst->codec_ptr_inst.funcDecode == NULL) + { + dspInfo->lastMode |= MODE_AWAITING_CODEC_PTR; + } + +#ifdef NETEQ_STEREO + if (msInfo->msMode == NETEQ_SLAVE && (msInfo->extraInfo == DTMF_OVERDUB + || msInfo->extraInfo == DTMF_ONLY)) + { + /* Signal that the master instance generated DTMF tones */ + dspInfo->lastMode |= MODE_MASTER_DTMF_SIGNAL; + } + + if (msInfo->msMode != NETEQ_MONO) + { + /* We are using stereo mode; signal this to MCU side */ + dspInfo->lastMode |= MODE_USING_STEREO; + } +#endif + + WEBRTC_SPL_MEMCPY_W8(inst->pw16_writeAddress,dspInfo,sizeof(DSP2MCU_info_t)); + + /* Signal MCU with "interrupt" call to main inst*/ +#ifdef NETEQ_STEREO + assert(msInfo != NULL); + if (msInfo->msMode == NETEQ_MASTER) + { + /* clear info to slave */ + WebRtcSpl_MemSetW16((WebRtc_Word16 *) msInfo, 0, + sizeof(MasterSlaveInfo) / sizeof(WebRtc_Word16)); + /* re-set mode */ + msInfo->msMode = NETEQ_MASTER; + + /* Store some information to slave */ + msInfo->endTimestamp = inst->endTimestamp; + msInfo->samplesLeftWithOverlap = inst->endPosition - inst->curPosition; + } +#endif + + /* + * This call will trigger the MCU side to make a decision based on buffer contents and + * decision history. Instructions, encoded data and function pointers will be written + * to the shared memory. + */ + return_value = WebRtcNetEQ_DSP2MCUinterrupt((MainInst_t *) inst->main_inst, sharedMem); + + /* Read MCU data and instructions */ + instr = (WebRtc_UWord16) (inst->pw16_readAddress[0] & 0xf000); + +#ifdef NETEQ_STEREO + if (msInfo->msMode == NETEQ_MASTER) + { + msInfo->instruction = instr; + } + else if (msInfo->msMode == NETEQ_SLAVE) + { + /* Nothing to do */ + } +#endif + + /* check for error returned from MCU side, if so, return error */ + if (return_value < 0) + { + inst->w16_mode = MODE_ERROR; + dspInfo->lastMode = MODE_ERROR; + return return_value; + } + + blockPtr = &((inst->pw16_readAddress)[3]); + + /* Check for DTMF payload flag */ + if ((inst->pw16_readAddress[0] & DSP_DTMF_PAYLOAD) != 0) + { + playDtmf = 1; + dtmfValue = blockPtr[1]; + dtmfVolume = blockPtr[2]; + blockPtr += 3; + +#ifdef NETEQ_STEREO + if (msInfo->msMode == NETEQ_MASTER) + { + /* signal to slave that master is using DTMF */ + msInfo->extraInfo = DTMF_OVERDUB; + } +#endif + } + + blockLen = (((*blockPtr) & DSP_CODEC_MASK_RED_FLAG) + 1) >> 1; /* In # of WebRtc_Word16 */ + payloadLen = ((*blockPtr) & DSP_CODEC_MASK_RED_FLAG); + blockPtr++; + + /* Do we have to change our decoder? */ + if ((inst->pw16_readAddress[0] & 0x0f00) == DSP_CODEC_NEW_CODEC) + { + WEBRTC_SPL_MEMCPY_W16(&inst->codec_ptr_inst,blockPtr,(payloadLen+1)>>1); + if (inst->codec_ptr_inst.codec_fs != 0) + { + return_value = WebRtcNetEQ_DSPInit(inst, inst->codec_ptr_inst.codec_fs); + if (return_value != 0) + { /* error returned */ + instr = DSP_INSTR_FADE_TO_BGN; /* emergency instruction */ + } +#ifdef NETEQ_DELAY_LOGGING + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_CHANGE_FS; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); + fwrite(&inst->fs, sizeof(WebRtc_UWord16), 1, delay_fid2); +#endif + } + + /* Copy it again since the init destroys this part */ + + WEBRTC_SPL_MEMCPY_W16(&inst->codec_ptr_inst,blockPtr,(payloadLen+1)>>1); + inst->endTimestamp = inst->codec_ptr_inst.timeStamp; + inst->videoSyncTimestamp = inst->codec_ptr_inst.timeStamp; + blockPtr += blockLen; + blockLen = (((*blockPtr) & DSP_CODEC_MASK_RED_FLAG) + 1) >> 1; + payloadLen = ((*blockPtr) & DSP_CODEC_MASK_RED_FLAG); + blockPtr++; + if (inst->codec_ptr_inst.funcDecodeInit != NULL) + { + inst->codec_ptr_inst.funcDecodeInit(inst->codec_ptr_inst.codec_state); + } + +#ifdef NETEQ_CNG_CODEC + + /* Also update the CNG state as this might be uninitialized */ + + WEBRTC_SPL_MEMCPY_W16(&inst->CNG_Codec_inst,blockPtr,(payloadLen+1)>>1); + blockPtr += blockLen; + blockLen = (((*blockPtr) & DSP_CODEC_MASK_RED_FLAG) + 1) >> 1; + payloadLen = ((*blockPtr) & DSP_CODEC_MASK_RED_FLAG); + blockPtr++; + if (inst->CNG_Codec_inst != NULL) + { + WebRtcCng_InitDec(inst->CNG_Codec_inst); + } +#endif + } + else if ((inst->pw16_readAddress[0] & 0x0f00) == DSP_CODEC_RESET) + { + /* Reset the current codec (but not DSP struct) */ + if (inst->codec_ptr_inst.funcDecodeInit != NULL) + { + inst->codec_ptr_inst.funcDecodeInit(inst->codec_ptr_inst.codec_state); + } + +#ifdef NETEQ_CNG_CODEC + /* And reset CNG */ + if (inst->CNG_Codec_inst != NULL) + { + WebRtcCng_InitDec(inst->CNG_Codec_inst); + } +#endif /*NETEQ_CNG_CODEC*/ + } + + fs_mult = WebRtcNetEQ_CalcFsMult(inst->fs); + + /* Add late packet? */ + if ((inst->pw16_readAddress[0] & 0x0f00) == DSP_CODEC_ADD_LATE_PKT) + { + if (inst->codec_ptr_inst.funcAddLatePkt != NULL) + { + /* Only do this if the codec has support for Add Late Pkt */ + inst->codec_ptr_inst.funcAddLatePkt(inst->codec_ptr_inst.codec_state, blockPtr, + payloadLen); + } + blockPtr += blockLen; + blockLen = (((*blockPtr) & DSP_CODEC_MASK_RED_FLAG) + 1) >> 1; /* In # of Word16 */ + payloadLen = ((*blockPtr) & DSP_CODEC_MASK_RED_FLAG); + blockPtr++; + } + + /* Do we have to decode data? */ + if ((instr == DSP_INSTR_NORMAL) || (instr == DSP_INSTR_ACCELERATE) || (instr + == DSP_INSTR_MERGE) || (instr == DSP_INSTR_PREEMPTIVE_EXPAND)) + { + /* Do we need to update codec-internal PLC state? */ + if ((instr == DSP_INSTR_MERGE) && (inst->codec_ptr_inst.funcDecodePLC != NULL)) + { + len = 0; + len = inst->codec_ptr_inst.funcDecodePLC(inst->codec_ptr_inst.codec_state, + &pw16_decoded_buffer[len], 1); + } + len = 0; + + /* Do decoding */ + while ((blockLen > 0) && (len < (240 * fs_mult))) /* Guard somewhat against overflow */ + { + if (inst->codec_ptr_inst.funcDecode != NULL) + { + WebRtc_Word16 dec_Len; + if (!BGNonly) + { + /* Do decoding as normal + * + * blockPtr is pointing to payload, at this point, + * the most significant bit of *(blockPtr - 1) is a flag if set to 1 + * indicates that the following payload is the redundant payload. + */ + if (((*(blockPtr - 1) & DSP_CODEC_RED_FLAG) != 0) + && (inst->codec_ptr_inst.funcDecodeRCU != NULL)) + { + dec_Len = inst->codec_ptr_inst.funcDecodeRCU( + inst->codec_ptr_inst.codec_state, blockPtr, payloadLen, + &pw16_decoded_buffer[len], &speechType); + } + else + { + dec_Len = inst->codec_ptr_inst.funcDecode( + inst->codec_ptr_inst.codec_state, blockPtr, payloadLen, + &pw16_decoded_buffer[len], &speechType); + } + } + else + { + /* + * Background noise mode: don't decode, just produce the same length BGN. + * Don't call Expand for BGN here, since Expand uses the memory where the + * bitstreams are stored (sharemem). + */ + dec_Len = inst->w16_frameLen; + } + + if (dec_Len > 0) + { + len += dec_Len; + /* Update frameLen */ + inst->w16_frameLen = dec_Len; + } + else if (dec_Len < 0) + { + /* Error */ + len = -1; + break; + } + /* + * Sanity check (although we might still write outside memory when this + * happens...) + */ + if (len > NETEQ_MAX_FRAME_SIZE) + { + WebRtcSpl_MemSetW16(pw16_outData, 0, inst->timestampsPerCall); + *pw16_len = inst->timestampsPerCall; + inst->w16_mode = MODE_ERROR; + dspInfo->lastMode = MODE_ERROR; + return RECOUT_ERROR_DECODED_TOO_MUCH; + } + + /* Verify that instance was not corrupted by decoder */ + if (mainInstBackup != inst->main_inst) + { + /* Instance is corrupt */ + return CORRUPT_INSTANCE; + } + + } + blockPtr += blockLen; + blockLen = (((*blockPtr) & DSP_CODEC_MASK_RED_FLAG) + 1) >> 1; /* In # of Word16 */ + payloadLen = ((*blockPtr) & DSP_CODEC_MASK_RED_FLAG); + blockPtr++; + } + + if (len < 0) + { + len = 0; + inst->endTimestamp += inst->w16_frameLen; /* advance one frame */ + if (inst->codec_ptr_inst.funcGetErrorCode != NULL) + { + return_value = -inst->codec_ptr_inst.funcGetErrorCode( + inst->codec_ptr_inst.codec_state); + } + else + { + return_value = RECOUT_ERROR_DECODING; + } + instr = DSP_INSTR_FADE_TO_BGN; + } + if (speechType != TYPE_CNG) + { + /* + * Don't increment timestamp if codec returned CNG speech type + * since in this case, the MCU side will increment the CNGplayedTS counter. + */ + inst->endTimestamp += len; + } + } + else if (instr == DSP_INSTR_NORMAL_ONE_DESC) + { + if (inst->codec_ptr_inst.funcDecode != NULL) + { + len = inst->codec_ptr_inst.funcDecode(inst->codec_ptr_inst.codec_state, NULL, 0, + pw16_decoded_buffer, &speechType); +#ifdef NETEQ_DELAY_LOGGING + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_DECODE_ONE_DESC; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); + fwrite(&inst->endTimestamp, sizeof(WebRtc_UWord32), 1, delay_fid2); + fwrite(&dspInfo->samplesLeft, sizeof(WebRtc_UWord16), 1, delay_fid2); + tot_received_packets++; +#endif + } + if (speechType != TYPE_CNG) + { + /* + * Don't increment timestamp if codec returned CNG speech type + * since in this case, the MCU side will increment the CNGplayedTS counter. + */ + inst->endTimestamp += len; + } + + /* Verify that instance was not corrupted by decoder */ + if (mainInstBackup != inst->main_inst) + { + /* Instance is corrupt */ + return CORRUPT_INSTANCE; + } + + if (len <= 0) + { + len = 0; + if (inst->codec_ptr_inst.funcGetErrorCode != NULL) + { + return_value = -inst->codec_ptr_inst.funcGetErrorCode( + inst->codec_ptr_inst.codec_state); + } + else + { + return_value = RECOUT_ERROR_DECODING; + } + if ((inst->codec_ptr_inst.funcDecodeInit != NULL) + && (inst->codec_ptr_inst.codec_state != NULL)) + { + /* Reinitialize codec state as something is obviously wrong */ + inst->codec_ptr_inst.funcDecodeInit(inst->codec_ptr_inst.codec_state); + } + inst->endTimestamp += inst->w16_frameLen; /* advance one frame */ + instr = DSP_INSTR_FADE_TO_BGN; + } + } + + if (len == 0 && lastModeBGNonly) /* no new data */ + { + BGNonly = 1; /* force BGN this time too */ + } + +#ifdef NETEQ_VAD + if ((speechType == TYPE_CNG) /* decoder responded with codec-internal CNG */ + || ((instr == DSP_INSTR_DO_RFC3389CNG) && (blockLen > 0)) /* ... or, SID frame */ + || (inst->fs > 16000)) /* ... or, if not NB or WB */ + { + /* disable post-decode VAD upon first sign of send-side DTX/VAD active, or if SWB */ + inst->VADInst.VADEnabled = 0; + inst->VADInst.VADDecision = 1; /* set to always active, just to be on the safe side */ + inst->VADInst.SIDintervalCounter = 0; /* reset SID interval counter */ + } + else if (!inst->VADInst.VADEnabled) /* VAD disabled and no SID/CNG data observed this time */ + { + inst->VADInst.SIDintervalCounter++; /* increase counter */ + } + + /* check for re-enabling the VAD */ + if (inst->VADInst.SIDintervalCounter >= POST_DECODE_VAD_AUTO_ENABLE) + { + /* + * It's been a while since the last CNG/SID frame was observed => re-enable VAD. + * (Do not care to look for a VAD instance, since this is done inside the init + * function) + */ + WebRtcNetEQ_InitVAD(&inst->VADInst, inst->fs); + } + + if (len > 0 /* if we decoded any data */ + && inst->VADInst.VADEnabled /* and VAD enabled */ + && inst->fs <= 16000) /* can only do VAD for NB and WB */ + { + int VADframeSize; /* VAD frame size in ms */ + int VADSamplePtr = 0; + + inst->VADInst.VADDecision = 0; + + if (inst->VADInst.VADFunction != NULL) /* make sure that VAD function is provided */ + { + /* divide the data into groups, as large as possible */ + for (VADframeSize = 30; VADframeSize >= 10; VADframeSize -= 10) + { + /* loop through 30, 20, 10 */ + + while (inst->VADInst.VADDecision == 0 + && len - VADSamplePtr >= VADframeSize * fs_mult * 8) + { + /* + * Only continue until first active speech found, and as long as there is + * one VADframeSize left. + */ + + /* call VAD with new decoded data */ + inst->VADInst.VADDecision |= inst->VADInst.VADFunction( + inst->VADInst.VADState, (WebRtc_Word16) inst->fs, + (WebRtc_Word16 *) &pw16_decoded_buffer[VADSamplePtr], + (WebRtc_Word16) (VADframeSize * fs_mult * 8)); + + VADSamplePtr += VADframeSize * fs_mult * 8; /* increment sample counter */ + } + } + } + else + { /* VAD function is NULL */ + inst->VADInst.VADDecision = 1; /* set decision to active */ + inst->VADInst.VADEnabled = 0; /* disable VAD since we have no VAD function */ + } + + } +#endif /* NETEQ_VAD */ + + /* Adjust timestamp if needed */ + uw16_tmp = (WebRtc_UWord16) inst->pw16_readAddress[1]; + inst->endTimestamp += (((WebRtc_UWord32) uw16_tmp) << 16); + uw16_tmp = (WebRtc_UWord16) inst->pw16_readAddress[2]; + inst->endTimestamp += uw16_tmp; + + if (BGNonly && len > 0) + { + /* + * If BGN mode, we did not produce any data at decoding. + * Do it now instead. + */ + + WebRtcNetEQ_GenerateBGN(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, +#endif + pw16_decoded_buffer, len); + } + + /* Switch on the instruction received from the MCU side. */ + switch (instr) + { + case DSP_INSTR_NORMAL: + + /* Allow for signal processing to apply gain-back etc */ + WebRtcNetEQ_Normal(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_NORMAL, +#endif + pw16_decoded_buffer, len, pw16_NetEqAlgorithm_buffer, &len); + + /* If last packet was decoded as a inband CNG set mode to CNG instead */ + if ((speechType == TYPE_CNG) || ((inst->w16_mode == MODE_CODEC_INTERNAL_CNG) + && (len == 0))) + { + inst->w16_mode = MODE_CODEC_INTERNAL_CNG; + } + +#ifdef NETEQ_ATEVENT_DECODE + if (playDtmf == 0) + { + inst->DTMFInst.reinit = 1; + } +#endif + break; + case DSP_INSTR_NORMAL_ONE_DESC: + + /* Allow for signal processing to apply gain-back etc */ + WebRtcNetEQ_Normal(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_NORMAL, +#endif + pw16_decoded_buffer, len, pw16_NetEqAlgorithm_buffer, &len); +#ifdef NETEQ_ATEVENT_DECODE + if (playDtmf == 0) + { + inst->DTMFInst.reinit = 1; + } +#endif + inst->w16_mode = MODE_ONE_DESCRIPTOR; + break; + case DSP_INSTR_MERGE: +#ifdef NETEQ_DELAY_LOGGING + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_MERGE_INFO; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); + temp_var = -len; +#endif + /* Call Merge with history*/ + return_value = WebRtcNetEQ_Merge(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_MERGE, +#endif + pw16_decoded_buffer, len, pw16_NetEqAlgorithm_buffer, &len); + + if (return_value < 0) + { + /* error */ + return return_value; + } + +#ifdef NETEQ_DELAY_LOGGING + temp_var += len; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); +#endif + /* If last packet was decoded as a inband CNG set mode to CNG instead */ + if (speechType == TYPE_CNG) inst->w16_mode = MODE_CODEC_INTERNAL_CNG; +#ifdef NETEQ_ATEVENT_DECODE + if (playDtmf == 0) + { + inst->DTMFInst.reinit = 1; + } +#endif + break; + + case DSP_INSTR_EXPAND: + len = 0; + pos = 0; + while ((inst->endPosition - inst->curPosition - inst->ExpandInst.w16_overlap + pos) + < (inst->timestampsPerCall)) + { + return_value = WebRtcNetEQ_Expand(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, +#endif + pw16_NetEqAlgorithm_buffer, &len, BGNonly); + if (return_value < 0) + { + /* error */ + return return_value; + } + + /* + * Update buffer, but only end part (otherwise expand state is destroyed + * since it reuses speechBuffer[] memory + */ + + WEBRTC_SPL_MEMMOVE_W16(inst->pw16_speechHistory, + inst->pw16_speechHistory + len, + (inst->w16_speechHistoryLen-len)); + WEBRTC_SPL_MEMCPY_W16(&inst->pw16_speechHistory[inst->w16_speechHistoryLen-len], + pw16_NetEqAlgorithm_buffer, len); + + inst->curPosition -= len; + + /* Update variables for VQmon */ + inst->w16_concealedTS += len; +#ifdef NETEQ_DELAY_LOGGING + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_EXPAND_INFO; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); + temp_var = len; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); +#endif + len = 0; /* already written the data, so do not write it again further down. */ + } +#ifdef NETEQ_ATEVENT_DECODE + if (playDtmf == 0) + { + inst->DTMFInst.reinit = 1; + } +#endif + break; + + case DSP_INSTR_ACCELERATE: + if (len < 3 * 80 * fs_mult) + { + /* We need to move data from the speechBuffer[] in order to get 30 ms */ + borrowedSamples = 3 * 80 * fs_mult - len; + + WEBRTC_SPL_MEMMOVE_W16(&pw16_decoded_buffer[borrowedSamples], + pw16_decoded_buffer, len); + WEBRTC_SPL_MEMCPY_W16(pw16_decoded_buffer, + &(inst->speechBuffer[inst->endPosition-borrowedSamples]), + borrowedSamples); + + return_value = WebRtcNetEQ_Accelerate(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_ACCELERATE, +#endif + pw16_decoded_buffer, 3 * inst->timestampsPerCall, + pw16_NetEqAlgorithm_buffer, &len, BGNonly); + + if (return_value < 0) + { + /* error */ + return return_value; + } + + /* Copy back samples to the buffer */ + if (len < borrowedSamples) + { + /* + * This destroys the beginning of the buffer, but will not cause any + * problems + */ + + WEBRTC_SPL_MEMCPY_W16(&inst->speechBuffer[inst->endPosition-borrowedSamples], + pw16_NetEqAlgorithm_buffer, len); + WEBRTC_SPL_MEMMOVE_W16(&inst->speechBuffer[borrowedSamples-len], + inst->speechBuffer, + (inst->endPosition-(borrowedSamples-len))); + + inst->curPosition += (borrowedSamples - len); +#ifdef NETEQ_DELAY_LOGGING + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_ACCELERATE_INFO; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); + temp_var = 3 * inst->timestampsPerCall - len; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); +#endif + len = 0; + } + else + { + WEBRTC_SPL_MEMCPY_W16(&inst->speechBuffer[inst->endPosition-borrowedSamples], + pw16_NetEqAlgorithm_buffer, borrowedSamples); + WEBRTC_SPL_MEMMOVE_W16(pw16_NetEqAlgorithm_buffer, + &pw16_NetEqAlgorithm_buffer[borrowedSamples], + (len-borrowedSamples)); +#ifdef NETEQ_DELAY_LOGGING + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_ACCELERATE_INFO; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); + temp_var = 3 * inst->timestampsPerCall - len; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); +#endif + len = len - borrowedSamples; + } + + } + else + { +#ifdef NETEQ_DELAY_LOGGING + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_ACCELERATE_INFO; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); + temp_var = len; +#endif + return_value = WebRtcNetEQ_Accelerate(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_ACCELERATE, +#endif + pw16_decoded_buffer, len, pw16_NetEqAlgorithm_buffer, &len, BGNonly); + + if (return_value < 0) + { + /* error */ + return return_value; + } + +#ifdef NETEQ_DELAY_LOGGING + temp_var -= len; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); +#endif + } + /* If last packet was decoded as a inband CNG set mode to CNG instead */ + if (speechType == TYPE_CNG) inst->w16_mode = MODE_CODEC_INTERNAL_CNG; +#ifdef NETEQ_ATEVENT_DECODE + if (playDtmf == 0) + { + inst->DTMFInst.reinit = 1; + } +#endif + break; + + case DSP_INSTR_DO_RFC3389CNG: +#ifdef NETEQ_CNG_CODEC + if (blockLen > 0) + { + if (WebRtcCng_UpdateSid(inst->CNG_Codec_inst, (WebRtc_UWord8*) blockPtr, + payloadLen) < 0) + { + /* error returned from CNG function */ + return_value = -WebRtcCng_GetErrorCodeDec(inst->CNG_Codec_inst); + len = inst->timestampsPerCall; + WebRtcSpl_MemSetW16(pw16_NetEqAlgorithm_buffer, 0, len); + break; + } + } + + if (BGNonly) + { + /* Get data from BGN function instead of CNG */ + len = WebRtcNetEQ_GenerateBGN(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, +#endif + pw16_NetEqAlgorithm_buffer, inst->timestampsPerCall); + if (len != inst->timestampsPerCall) + { + /* this is not good, treat this as an error */ + return_value = -1; + } + } + else + { + return_value = WebRtcNetEQ_Cng(inst, pw16_NetEqAlgorithm_buffer, + inst->timestampsPerCall); + } + len = inst->timestampsPerCall; + inst->ExpandInst.w16_consecExp = 0; + inst->w16_mode = MODE_RFC3389CNG; +#ifdef NETEQ_ATEVENT_DECODE + if (playDtmf == 0) + { + inst->DTMFInst.reinit = 1; + } +#endif + + if (return_value < 0) + { + /* error returned */ + WebRtcSpl_MemSetW16(pw16_NetEqAlgorithm_buffer, 0, len); + } + + break; +#else + return FAULTY_INSTRUCTION; +#endif + case DSP_INSTR_DO_CODEC_INTERNAL_CNG: + /* + * This represents the case when there is no transmission and the decoder should + * do internal CNG. + */ + len = 0; + if (inst->codec_ptr_inst.funcDecode != NULL && !BGNonly) + { + len = inst->codec_ptr_inst.funcDecode(inst->codec_ptr_inst.codec_state, + blockPtr, 0, pw16_decoded_buffer, &speechType); + } + else + { + /* get BGN data */ + len = WebRtcNetEQ_GenerateBGN(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, +#endif + pw16_decoded_buffer, inst->timestampsPerCall); + } + WebRtcNetEQ_Normal(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_NORMAL, +#endif + pw16_decoded_buffer, len, pw16_NetEqAlgorithm_buffer, &len); + inst->w16_mode = MODE_CODEC_INTERNAL_CNG; + inst->ExpandInst.w16_consecExp = 0; + break; + + case DSP_INSTR_DTMF_GENERATE: +#ifdef NETEQ_ATEVENT_DECODE + dtmfSwitch = 0; + if ((inst->w16_mode != MODE_DTMF) && (inst->DTMFInst.reinit == 0)) + { + /* Special case; see below. + * We must catch this before calling DTMFGenerate, + * since reinit is set to 0 in that call. + */ + dtmfSwitch = 1; + } + + len = WebRtcNetEQ_DTMFGenerate(&inst->DTMFInst, dtmfValue, dtmfVolume, + pw16_NetEqAlgorithm_buffer, inst->fs, -1); + if (len < 0) + { + /* error occurred */ + return_value = len; + len = inst->timestampsPerCall; + WebRtcSpl_MemSetW16(pw16_NetEqAlgorithm_buffer, 0, len); + } + + if (dtmfSwitch == 1) + { + /* + * This is the special case where the previous operation was DTMF overdub. + * but the current instruction is "regular" DTMF. We must make sure that the + * DTMF does not have any discontinuities. The first DTMF sample that we + * generate now must be played out immediately, wherefore it must be copied to + * the speech buffer. + */ + + /* + * Generate extra DTMF data to fill the space between + * curPosition and endPosition + */ + WebRtc_Word16 tempLen; + + tempLen = WebRtcNetEQ_DTMFGenerate(&inst->DTMFInst, dtmfValue, dtmfVolume, + &pw16_NetEqAlgorithm_buffer[len], inst->fs, + inst->endPosition - inst->curPosition); + if (tempLen < 0) + { + /* error occurred */ + return_value = tempLen; + len = inst->endPosition - inst->curPosition; + WebRtcSpl_MemSetW16(pw16_NetEqAlgorithm_buffer, 0, + inst->endPosition - inst->curPosition); + } + + /* Add to total length */ + len += tempLen; + + /* Overwrite the "future" part of the speech buffer with the new DTMF data */ + + WEBRTC_SPL_MEMCPY_W16(&inst->speechBuffer[inst->curPosition], + pw16_NetEqAlgorithm_buffer, + inst->endPosition - inst->curPosition); + + /* Shuffle the remaining data to the beginning of algorithm buffer */ + len -= (inst->endPosition - inst->curPosition); + WEBRTC_SPL_MEMMOVE_W16(pw16_NetEqAlgorithm_buffer, + &pw16_NetEqAlgorithm_buffer[inst->endPosition - inst->curPosition], + len); + } + + inst->endTimestamp += inst->timestampsPerCall; + inst->DTMFInst.reinit = 0; + inst->ExpandInst.w16_consecExp = 0; + inst->w16_mode = MODE_DTMF; + BGNonly = 0; /* override BGN only and let DTMF through */ + + playDtmf = 0; /* set to zero because the DTMF is already in the Algorithm buffer */ + /* + * If playDtmf is 1, an extra DTMF vector will be generated and overdubbed + * on the output. + */ + +#ifdef NETEQ_STEREO + if (msInfo->msMode == NETEQ_MASTER) + { + /* signal to slave that master is using DTMF only */ + msInfo->extraInfo = DTMF_ONLY; + } +#endif + + break; +#else + inst->w16_mode = MODE_ERROR; + dspInfo->lastMode = MODE_ERROR; + return FAULTY_INSTRUCTION; +#endif + + case DSP_INSTR_DO_ALTERNATIVE_PLC: + if (inst->codec_ptr_inst.funcDecodePLC != 0) + { + len = inst->codec_ptr_inst.funcDecodePLC(inst->codec_ptr_inst.codec_state, + pw16_NetEqAlgorithm_buffer, 1); + } + else + { + len = inst->timestampsPerCall; + /* ZeroStuffing... */ + WebRtcSpl_MemSetW16(pw16_NetEqAlgorithm_buffer, 0, len); + } + inst->ExpandInst.w16_consecExp = 0; + break; + case DSP_INSTR_DO_ALTERNATIVE_PLC_INC_TS: + if (inst->codec_ptr_inst.funcDecodePLC != 0) + { + len = inst->codec_ptr_inst.funcDecodePLC(inst->codec_ptr_inst.codec_state, + pw16_NetEqAlgorithm_buffer, 1); + } + else + { + len = inst->timestampsPerCall; + /* ZeroStuffing... */ + WebRtcSpl_MemSetW16(pw16_NetEqAlgorithm_buffer, 0, len); + } + inst->ExpandInst.w16_consecExp = 0; + inst->endTimestamp += len; + break; + case DSP_INSTR_DO_AUDIO_REPETITION: + len = inst->timestampsPerCall; + /* copy->paste... */ + WEBRTC_SPL_MEMCPY_W16(pw16_NetEqAlgorithm_buffer, + &inst->speechBuffer[inst->endPosition-len], len); + inst->ExpandInst.w16_consecExp = 0; + break; + case DSP_INSTR_DO_AUDIO_REPETITION_INC_TS: + len = inst->timestampsPerCall; + /* copy->paste... */ + WEBRTC_SPL_MEMCPY_W16(pw16_NetEqAlgorithm_buffer, + &inst->speechBuffer[inst->endPosition-len], len); + inst->ExpandInst.w16_consecExp = 0; + inst->endTimestamp += len; + break; + + case DSP_INSTR_PREEMPTIVE_EXPAND: + if (len < 3 * inst->timestampsPerCall) + { + /* borrow samples from sync buffer if necessary */ + borrowedSamples = 3 * inst->timestampsPerCall - len; /* borrow this many samples */ + /* calculate how many of these are already played out */ + oldBorrowedSamples = WEBRTC_SPL_MAX(0, + borrowedSamples - (inst->endPosition - inst->curPosition)); + WEBRTC_SPL_MEMMOVE_W16(&pw16_decoded_buffer[borrowedSamples], + pw16_decoded_buffer, len); + WEBRTC_SPL_MEMCPY_W16(pw16_decoded_buffer, + &(inst->speechBuffer[inst->endPosition-borrowedSamples]), + borrowedSamples); + } + else + { + borrowedSamples = 0; + oldBorrowedSamples = 0; + } + +#ifdef NETEQ_DELAY_LOGGING + w16_tmp1 = len; +#endif + /* do the expand */ + return_value = WebRtcNetEQ_PreEmptiveExpand(inst, +#ifdef SCRATCH + /* use same scratch memory as Accelerate */ + pw16_scratchPtr + SCRATCH_NETEQ_ACCELERATE, +#endif + pw16_decoded_buffer, len + borrowedSamples, oldBorrowedSamples, + pw16_NetEqAlgorithm_buffer, &len, BGNonly); + + if (return_value < 0) + { + /* error */ + return return_value; + } + + if (borrowedSamples > 0) + { + /* return borrowed samples */ + + /* Copy back to last part of speechBuffer from beginning of output buffer */ + WEBRTC_SPL_MEMCPY_W16( &(inst->speechBuffer[inst->endPosition-borrowedSamples]), + pw16_NetEqAlgorithm_buffer, + borrowedSamples); + + len -= borrowedSamples; /* remove the borrowed samples from new total length */ + + /* Move to beginning of output buffer from end of output buffer */ + WEBRTC_SPL_MEMMOVE_W16( pw16_NetEqAlgorithm_buffer, + &pw16_NetEqAlgorithm_buffer[borrowedSamples], + len); + } + +#ifdef NETEQ_DELAY_LOGGING + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_PREEMPTIVE_INFO; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); + temp_var = len - w16_tmp1; /* number of samples added */ + fwrite(&temp_var, sizeof(int), 1, delay_fid2); +#endif + /* If last packet was decoded as inband CNG, set mode to CNG instead */ + if (speechType == TYPE_CNG) inst->w16_mode = MODE_CODEC_INTERNAL_CNG; +#ifdef NETEQ_ATEVENT_DECODE + if (playDtmf == 0) + { + inst->DTMFInst.reinit = 1; + } +#endif + break; + + case DSP_INSTR_FADE_TO_BGN: + { + int tempReturnValue; + /* do not overwrite return_value, since it likely contains an error code */ + + /* calculate interpolation length */ + w16_tmp3 = WEBRTC_SPL_MIN(inst->endPosition - inst->curPosition, + inst->timestampsPerCall); + /* check that it will fit in pw16_NetEqAlgorithm_buffer */ + if (w16_tmp3 + inst->w16_frameLen > NETEQ_MAX_OUTPUT_SIZE) + { + w16_tmp3 = NETEQ_MAX_OUTPUT_SIZE - inst->w16_frameLen; + } + + /* call Expand */ + len = inst->timestampsPerCall + inst->ExpandInst.w16_overlap; + pos = 0; + + tempReturnValue = WebRtcNetEQ_Expand(inst, +#ifdef SCRATCH + pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, +#endif + pw16_NetEqAlgorithm_buffer, &len, 1); + + if (tempReturnValue < 0) + { + /* error */ + /* this error value will override return_value */ + return tempReturnValue; + } + + pos += len; /* got len samples from expand */ + + /* copy to fill the demand */ + while (pos + len <= inst->w16_frameLen + w16_tmp3) + { + WEBRTC_SPL_MEMCPY_W16(&pw16_NetEqAlgorithm_buffer[pos], + pw16_NetEqAlgorithm_buffer, len); + pos += len; + } + + /* fill with fraction of the expand vector if needed */ + if (pos < inst->w16_frameLen + w16_tmp3) + { + WEBRTC_SPL_MEMCPY_W16(&pw16_NetEqAlgorithm_buffer[pos], pw16_NetEqAlgorithm_buffer, + inst->w16_frameLen + w16_tmp3 - pos); + } + + len = inst->w16_frameLen + w16_tmp3; /* truncate any surplus samples since we don't want these */ + + /* + * Mix with contents in sync buffer. Find largest power of two that is less than + * interpolate length divide 16384 with this number; result is in w16_tmp2. + */ + w16_tmp1 = 2; + w16_tmp2 = 16384; + while (w16_tmp1 <= w16_tmp3) + { + w16_tmp2 >>= 1; /* divide with 2 */ + w16_tmp1 <<= 1; /* increase with a factor of 2 */ + } + + w16_tmp1 = 0; + pos = 0; + while (w16_tmp1 < 16384) + { + inst->speechBuffer[inst->curPosition + pos] + = + (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32( + WEBRTC_SPL_MUL_16_16( inst->speechBuffer[inst->endPosition - w16_tmp3 + pos], + 16384-w16_tmp1 ) + + WEBRTC_SPL_MUL_16_16( pw16_NetEqAlgorithm_buffer[pos], w16_tmp1 ), + 14 ); + w16_tmp1 += w16_tmp2; + pos++; + } + + /* overwrite remainder of speech buffer */ + + WEBRTC_SPL_MEMCPY_W16( &inst->speechBuffer[inst->endPosition - w16_tmp3 + pos], + &pw16_NetEqAlgorithm_buffer[pos], w16_tmp3 - pos); + + len -= w16_tmp3; + /* shift algorithm buffer */ + + WEBRTC_SPL_MEMMOVE_W16( pw16_NetEqAlgorithm_buffer, + &pw16_NetEqAlgorithm_buffer[w16_tmp3], + len ); + + /* Update variables for VQmon */ + inst->w16_concealedTS += len; + + inst->w16_mode = MODE_FADE_TO_BGN; +#ifdef NETEQ_DELAY_LOGGING + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_EXPAND_INFO; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); + temp_var = len; + fwrite(&temp_var, sizeof(int), 1, delay_fid2); +#endif + + break; + } + + default: + inst->w16_mode = MODE_ERROR; + dspInfo->lastMode = MODE_ERROR; + return FAULTY_INSTRUCTION; + } /* end of grand switch */ + + /* Copy data directly to output buffer */ + + w16_tmp2 = 0; + if ((inst->endPosition + len - inst->curPosition - inst->ExpandInst.w16_overlap) + >= inst->timestampsPerCall) + { + w16_tmp2 = inst->endPosition - inst->curPosition; + w16_tmp2 = WEBRTC_SPL_MAX(w16_tmp2, 0); /* Additional error protection, just in case */ + w16_tmp1 = WEBRTC_SPL_MIN(w16_tmp2, inst->timestampsPerCall); + w16_tmp2 = inst->timestampsPerCall - w16_tmp1; + WEBRTC_SPL_MEMCPY_W16(pw16_outData, &inst->speechBuffer[inst->curPosition], w16_tmp1); + WEBRTC_SPL_MEMCPY_W16(&pw16_outData[w16_tmp1], pw16_NetEqAlgorithm_buffer, w16_tmp2); + DataEnough = 1; + } + else + { + DataEnough = 0; + } + + if (playDtmf != 0) + { + WebRtc_Word16 outDataIndex = 0; + WebRtc_Word16 overdubLen = -1; /* default len */ + WebRtc_Word16 dtmfLen; + + /* + * Overdub the output with DTMF. Note that this is not executed if the + * DSP_INSTR_DTMF_GENERATE operation is performed above. + */ +#ifdef NETEQ_ATEVENT_DECODE + if (inst->DTMFInst.lastDtmfSample - inst->curPosition > 0) + { + /* special operation for transition from "DTMF only" to "DTMF overdub" */ + outDataIndex + = WEBRTC_SPL_MIN(inst->DTMFInst.lastDtmfSample - inst->curPosition, + inst->timestampsPerCall); + overdubLen = inst->timestampsPerCall - outDataIndex; + } + + dtmfLen = WebRtcNetEQ_DTMFGenerate(&inst->DTMFInst, dtmfValue, dtmfVolume, + &pw16_outData[outDataIndex], inst->fs, overdubLen); + if (dtmfLen < 0) + { + /* error occurred */ + return_value = dtmfLen; + } + inst->DTMFInst.reinit = 0; +#else + inst->w16_mode = MODE_ERROR; + dspInfo->lastMode = MODE_ERROR; + return FAULTY_INSTRUCTION; +#endif + } + + /* + * Shuffle speech buffer to allow more data. Move data from pw16_NetEqAlgorithm_buffer + * to speechBuffer. + */ + if (instr != DSP_INSTR_EXPAND) + { + w16_tmp1 = WEBRTC_SPL_MIN(inst->endPosition, len); + WEBRTC_SPL_MEMMOVE_W16(inst->speechBuffer, inst->speechBuffer + w16_tmp1, + (inst->endPosition-w16_tmp1)); + WEBRTC_SPL_MEMCPY_W16(&inst->speechBuffer[inst->endPosition-w16_tmp1], + &pw16_NetEqAlgorithm_buffer[len-w16_tmp1], w16_tmp1); +#ifdef NETEQ_ATEVENT_DECODE + /* Update index to end of DTMF data in speech buffer */ + if (instr == DSP_INSTR_DTMF_GENERATE) + { + /* We have written DTMF data to the end of speech buffer */ + inst->DTMFInst.lastDtmfSample = inst->endPosition; + } + else if (inst->DTMFInst.lastDtmfSample > 0) + { + /* The end of DTMF data in speech buffer has been shuffled */ + inst->DTMFInst.lastDtmfSample -= w16_tmp1; + } +#endif + /* + * Update the BGN history if last operation was not expand (nor Merge, Accelerate + * or Pre-emptive expand, to save complexity). + */ + if ((inst->w16_mode != MODE_EXPAND) && (inst->w16_mode != MODE_MERGE) + && (inst->w16_mode != MODE_SUCCESS_ACCELERATE) && (inst->w16_mode + != MODE_LOWEN_ACCELERATE) && (inst->w16_mode != MODE_SUCCESS_PREEMPTIVE) + && (inst->w16_mode != MODE_LOWEN_PREEMPTIVE) && (inst->w16_mode + != MODE_FADE_TO_BGN) && (inst->w16_mode != MODE_DTMF) && (!BGNonly)) + { + WebRtcNetEQ_BGNUpdate(inst +#ifdef SCRATCH + , pw16_scratchPtr + SCRATCH_NETEQ_BGN_UPDATE +#endif + ); + } + } + else /* instr == DSP_INSTR_EXPAND */ + { + /* Nothing should be done since data is already copied to output. */ + } + + inst->curPosition -= len; + + /* + * Extra protection in case something should go totally wrong in terms of sizes... + * If everything is ok this should NEVER happen. + */ + if (inst->curPosition < -inst->timestampsPerCall) + { + inst->curPosition = -inst->timestampsPerCall; + } + + if ((instr != DSP_INSTR_EXPAND) && (instr != DSP_INSTR_MERGE) && (instr + != DSP_INSTR_FADE_TO_BGN)) + { + /* Reset concealed TS parameter if it does not seem to have been flushed */ + if (inst->w16_concealedTS > inst->timestampsPerCall) + { + inst->w16_concealedTS = 0; + } + } + + /* + * Double-check that we actually have 10 ms to play. If we haven't, there has been a + * serious error.The decoder might have returned way too few samples + */ + if (!DataEnough) + { + /* This should not happen. Set outdata to zeros, and return error. */ + WebRtcSpl_MemSetW16(pw16_outData, 0, inst->timestampsPerCall); + *pw16_len = inst->timestampsPerCall; + inst->w16_mode = MODE_ERROR; + dspInfo->lastMode = MODE_ERROR; + return RECOUT_ERROR_SAMPLEUNDERRUN; + } + + /* + * Update Videosync timestamp (this special timestamp is needed since the endTimestamp + * stops during CNG and Expand periods. + */ + if ((inst->w16_mode != MODE_EXPAND) && (inst->w16_mode != MODE_RFC3389CNG)) + { + WebRtc_UWord32 uw32_tmpTS; + uw32_tmpTS = inst->endTimestamp - (inst->endPosition - inst->curPosition); + if ((WebRtc_Word32) (uw32_tmpTS - inst->videoSyncTimestamp) > 0) + { + inst->videoSyncTimestamp = uw32_tmpTS; + } + } + else + { + inst->videoSyncTimestamp += inst->timestampsPerCall; + } + + /* After this, regardless of what has happened, deliver 10 ms of future data */ + inst->curPosition += inst->timestampsPerCall; + *pw16_len = inst->timestampsPerCall; + + /* Remember if BGNonly was used */ + if (BGNonly) + { + inst->w16_mode |= MODE_BGN_ONLY; + } + + return return_value; +} + +#undef SCRATCH_ALGORITHM_BUFFER +#undef SCRATCH_NETEQ_NORMAL +#undef SCRATCH_NETEQ_MERGE +#undef SCRATCH_NETEQ_BGN_UPDATE +#undef SCRATCH_NETEQ_EXPAND +#undef SCRATCH_DSP_INFO +#undef SCRATCH_NETEQ_ACCELERATE +#undef SIZE_SCRATCH_BUFFER diff --git a/src/libs/webrtc/neteq/rtcp.c b/src/libs/webrtc/neteq/rtcp.c new file mode 100644 index 00000000..35f73da8 --- /dev/null +++ b/src/libs/webrtc/neteq/rtcp.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Implementation of RTCP statistics reporting. + */ + +#include "rtcp.h" + +#include <string.h> + +#include "signal_processing_library.h" + +int WebRtcNetEQ_RTCPInit(WebRtcNetEQ_RTCP_t *RTCP_inst, WebRtc_UWord16 uw16_seqNo) +{ + /* + * Initialize everything to zero and then set the start values for the RTP packet stream. + */ + WebRtcSpl_MemSetW16((WebRtc_Word16*) RTCP_inst, 0, + sizeof(WebRtcNetEQ_RTCP_t) / sizeof(WebRtc_Word16)); + RTCP_inst->base_seq = uw16_seqNo; + RTCP_inst->max_seq = uw16_seqNo; + return 0; +} + +int WebRtcNetEQ_RTCPUpdate(WebRtcNetEQ_RTCP_t *RTCP_inst, WebRtc_UWord16 uw16_seqNo, + WebRtc_UWord32 uw32_timeStamp, WebRtc_UWord32 uw32_recTime) +{ + WebRtc_Word16 w16_SeqDiff; + WebRtc_Word32 w32_TimeDiff; + WebRtc_Word32 w32_JitterDiff; + + /* + * Update number of received packets, and largest packet number received. + */ + RTCP_inst->received++; + w16_SeqDiff = uw16_seqNo - RTCP_inst->max_seq; + if (w16_SeqDiff >= 0) + { + if (uw16_seqNo < RTCP_inst->max_seq) + { + /* Wrap around detected */ + RTCP_inst->cycles++; + } + RTCP_inst->max_seq = uw16_seqNo; + } + + /* Calculate Jitter, and update previous timestamps */ + /* Note that the value in RTCP_inst->jitter is in Q4. */ + if (RTCP_inst->received > 1) + { + w32_TimeDiff = (uw32_recTime - (uw32_timeStamp - RTCP_inst->transit)); + w32_TimeDiff = WEBRTC_SPL_ABS_W32(w32_TimeDiff); + w32_JitterDiff = WEBRTC_SPL_LSHIFT_W16(w32_TimeDiff, 4) - RTCP_inst->jitter; + RTCP_inst->jitter = RTCP_inst->jitter + WEBRTC_SPL_RSHIFT_W32((w32_JitterDiff + 8), 4); + } + RTCP_inst->transit = (uw32_timeStamp - uw32_recTime); + return 0; +} + +int WebRtcNetEQ_RTCPGetStats(WebRtcNetEQ_RTCP_t *RTCP_inst, + WebRtc_UWord16 *puw16_fraction_lost, + WebRtc_UWord32 *puw32_cum_lost, WebRtc_UWord32 *puw32_ext_max, + WebRtc_UWord32 *puw32_jitter, WebRtc_Word16 doNotReset) +{ + WebRtc_UWord32 uw32_exp_nr, uw32_exp_interval, uw32_rec_interval; + WebRtc_Word32 w32_lost; + + /* Extended highest sequence number received */ + *puw32_ext_max + = (WebRtc_UWord32) WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)RTCP_inst->cycles, 16) + + RTCP_inst->max_seq; + + /* + * Calculate expected number of packets and compare it to the number of packets that + * were actually received => the cumulative number of packets lost can be extracted. + */ + uw32_exp_nr = *puw32_ext_max - RTCP_inst->base_seq + 1; + if (RTCP_inst->received == 0) + { + /* no packets received, assume none lost */ + *puw32_cum_lost = 0; + } + else if (uw32_exp_nr > RTCP_inst->received) + { + *puw32_cum_lost = uw32_exp_nr - RTCP_inst->received; + if (*puw32_cum_lost > (WebRtc_UWord32) 0xFFFFFF) + { + *puw32_cum_lost = 0xFFFFFF; + } + } + else + { + *puw32_cum_lost = 0; + } + + /* Fraction lost (Since last report) */ + uw32_exp_interval = uw32_exp_nr - RTCP_inst->exp_prior; + if (!doNotReset) + { + RTCP_inst->exp_prior = uw32_exp_nr; + } + uw32_rec_interval = RTCP_inst->received - RTCP_inst->rec_prior; + if (!doNotReset) + { + RTCP_inst->rec_prior = RTCP_inst->received; + } + w32_lost = (WebRtc_Word32) (uw32_exp_interval - uw32_rec_interval); + if (uw32_exp_interval == 0 || w32_lost <= 0 || RTCP_inst->received == 0) + { + *puw16_fraction_lost = 0; + } + else + { + *puw16_fraction_lost = (WebRtc_UWord16) (WEBRTC_SPL_LSHIFT_W32(w32_lost, 8) + / uw32_exp_interval); + } + if (*puw16_fraction_lost > 0xFF) + { + *puw16_fraction_lost = 0xFF; + } + + /* Inter-arrival jitter */ + *puw32_jitter = (RTCP_inst->jitter) >> 4; /* scaling from Q4 */ + return 0; +} + diff --git a/src/libs/webrtc/neteq/rtcp.h b/src/libs/webrtc/neteq/rtcp.h new file mode 100644 index 00000000..009e019e --- /dev/null +++ b/src/libs/webrtc/neteq/rtcp.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * RTCP statistics reporting. + */ + +#ifndef RTCP_H +#define RTCP_H + +#include "typedefs.h" + +typedef struct +{ + WebRtc_UWord16 cycles; /* The number of wrap-arounds for the sequence number */ + WebRtc_UWord16 max_seq; /* The maximum sequence number received + (starts from 0 again after wrap around) */ + WebRtc_UWord16 base_seq; /* The sequence number of the first packet that arrived */ + WebRtc_UWord32 received; /* The number of packets that has been received */ + WebRtc_UWord32 rec_prior; /* Number of packets received when last report was generated */ + WebRtc_UWord32 exp_prior; /* Number of packets that should have been received if no + packets were lost. Stored value from last report. */ + WebRtc_UWord32 jitter; /* Jitter statistics at this instance (calculated according to RFC) */ + WebRtc_Word32 transit; /* Clock difference for previous packet (RTPtimestamp - LOCALtime_rec) */ +} WebRtcNetEQ_RTCP_t; + +/**************************************************************************** + * WebRtcNetEQ_RTCPInit(...) + * + * This function calculates the parameters that are needed for the RTCP + * report. + * + * Input: + * - RTCP_inst : RTCP instance, that contains information about the + * packets that have been received etc. + * - seqNo : Packet number of the first received frame. + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_RTCPInit(WebRtcNetEQ_RTCP_t *RTCP_inst, WebRtc_UWord16 uw16_seqNo); + +/**************************************************************************** + * WebRtcNetEQ_RTCPUpdate(...) + * + * This function calculates the parameters that are needed for the RTCP + * report. + * + * Input: + * - RTCP_inst : RTCP instance, that contains information about the + * packets that have been received etc. + * - seqNo : Packet number of the first received frame. + * - timeStamp : Time stamp from the RTP header. + * - recTime : Time (in RTP timestamps) when this packet was received. + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_RTCPUpdate(WebRtcNetEQ_RTCP_t *RTCP_inst, WebRtc_UWord16 uw16_seqNo, + WebRtc_UWord32 uw32_timeStamp, WebRtc_UWord32 uw32_recTime); + +/**************************************************************************** + * WebRtcNetEQ_RTCPGetStats(...) + * + * This function calculates the parameters that are needed for the RTCP + * report. + * + * Input: + * - RTCP_inst : RTCP instance, that contains information about the + * packets that have been received etc. + * - doNotReset : If non-zero, the fraction lost statistics will not + * be reset. + * + * Output: + * - RTCP_inst : Updated RTCP information (some statistics are + * reset when generating this report) + * - fraction_lost : Number of lost RTP packets divided by the number of + * expected packets, since the last RTCP Report. + * - cum_lost : Cumulative number of lost packets during this + * session. + * - ext_max : Extended highest sequence number received. + * - jitter : Inter-arrival jitter. + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_RTCPGetStats(WebRtcNetEQ_RTCP_t *RTCP_inst, + WebRtc_UWord16 *puw16_fraction_lost, + WebRtc_UWord32 *puw32_cum_lost, WebRtc_UWord32 *puw32_ext_max, + WebRtc_UWord32 *puw32_jitter, WebRtc_Word16 doNotReset); + +#endif diff --git a/src/libs/webrtc/neteq/rtp.c b/src/libs/webrtc/neteq/rtp.c new file mode 100644 index 00000000..bd4f9a22 --- /dev/null +++ b/src/libs/webrtc/neteq/rtp.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * RTP related functions. + */ + +#include "rtp.h" + +#include "typedefs.h" /* to define endianness */ + +#include "neteq_error_codes.h" + +int WebRtcNetEQ_RTPPayloadInfo(WebRtc_Word16* pw16_Datagram, int i_DatagramLen, + RTPPacket_t* RTPheader) +{ + int i_P, i_X, i_CC, i_startPosition; + int i_IPver; + int i_extlength = -1; /* Default value is there is no extension */ + int i_padlength = 0; /* Default value if there is no padding */ + + if (i_DatagramLen < 12) + { + return RTP_TOO_SHORT_PACKET; + } + +#ifdef WEBRTC_BIG_ENDIAN + i_IPver = (((WebRtc_UWord16) (pw16_Datagram[0] & 0xC000)) >> 14); /* Extract the version */ + i_P = (((WebRtc_UWord16) (pw16_Datagram[0] & 0x2000)) >> 13); /* Extract the P bit */ + i_X = (((WebRtc_UWord16) (pw16_Datagram[0] & 0x1000)) >> 12); /* Extract the X bit */ + i_CC = ((WebRtc_UWord16) (pw16_Datagram[0] >> 8) & 0xF); /* Get the CC number */ + RTPheader->payloadType = pw16_Datagram[0] & 0x7F; /* Get the coder type */ + RTPheader->seqNumber = pw16_Datagram[1]; /* Get the sequence number */ + RTPheader->timeStamp = ((((WebRtc_UWord32) ((WebRtc_UWord16) pw16_Datagram[2])) << 16) + | (WebRtc_UWord16) (pw16_Datagram[3])); /* Get timestamp */ + RTPheader->ssrc = (((WebRtc_UWord32) pw16_Datagram[4]) << 16) + + (((WebRtc_UWord32) pw16_Datagram[5])); /* Get the SSRC */ + + if (i_X == 1) + { + /* Extension header exists. Find out how many WebRtc_Word32 it consists of. */ + i_extlength = pw16_Datagram[7 + 2 * i_CC]; + } + if (i_P == 1) + { + /* Padding exists. Find out how many bytes the padding consists of. */ + if (i_DatagramLen & 0x1) + { + /* odd number of bytes => last byte in higher byte */ + i_padlength = (((WebRtc_UWord16) pw16_Datagram[i_DatagramLen >> 1]) >> 8); + } + else + { + /* even number of bytes => last byte in lower byte */ + i_padlength = ((pw16_Datagram[(i_DatagramLen >> 1) - 1]) & 0xFF); + } + } +#else /* WEBRTC_LITTLE_ENDIAN */ + i_IPver = (((WebRtc_UWord16) (pw16_Datagram[0] & 0xC0)) >> 6); /* Extract the IP version */ + i_P = (((WebRtc_UWord16) (pw16_Datagram[0] & 0x20)) >> 5); /* Extract the P bit */ + i_X = (((WebRtc_UWord16) (pw16_Datagram[0] & 0x10)) >> 4); /* Extract the X bit */ + i_CC = (WebRtc_UWord16) (pw16_Datagram[0] & 0xF); /* Get the CC number */ + RTPheader->payloadType = (pw16_Datagram[0] >> 8) & 0x7F; /* Get the coder type */ + RTPheader->seqNumber = (((((WebRtc_UWord16) pw16_Datagram[1]) >> 8) & 0xFF) + | (((WebRtc_UWord16) (pw16_Datagram[1] & 0xFF)) << 8)); /* Get the packet number */ + RTPheader->timeStamp = ((((WebRtc_UWord16) pw16_Datagram[2]) & 0xFF) << 24) + | ((((WebRtc_UWord16) pw16_Datagram[2]) & 0xFF00) << 8) + | ((((WebRtc_UWord16) pw16_Datagram[3]) >> 8) & 0xFF) + | ((((WebRtc_UWord16) pw16_Datagram[3]) & 0xFF) << 8); /* Get timestamp */ + RTPheader->ssrc = ((((WebRtc_UWord16) pw16_Datagram[4]) & 0xFF) << 24) + | ((((WebRtc_UWord16) pw16_Datagram[4]) & 0xFF00) << 8) + | ((((WebRtc_UWord16) pw16_Datagram[5]) >> 8) & 0xFF) + | ((((WebRtc_UWord16) pw16_Datagram[5]) & 0xFF) << 8); /* Get the SSRC */ + + if (i_X == 1) + { + /* Extension header exists. Find out how many WebRtc_Word32 it consists of. */ + i_extlength = (((((WebRtc_UWord16) pw16_Datagram[7 + 2 * i_CC]) >> 8) & 0xFF) + | (((WebRtc_UWord16) (pw16_Datagram[7 + 2 * i_CC] & 0xFF)) << 8)); + } + if (i_P == 1) + { + /* Padding exists. Find out how many bytes the padding consists of. */ + if (i_DatagramLen & 0x1) + { + /* odd number of bytes => last byte in higher byte */ + i_padlength = (pw16_Datagram[i_DatagramLen >> 1] & 0xFF); + } + else + { + /* even number of bytes => last byte in lower byte */ + i_padlength = (((WebRtc_UWord16) pw16_Datagram[(i_DatagramLen >> 1) - 1]) >> 8); + } + } +#endif + + i_startPosition = 12 + 4 * (i_extlength + 1) + 4 * i_CC; + RTPheader->payload = &pw16_Datagram[i_startPosition >> 1]; + RTPheader->payloadLen = i_DatagramLen - i_startPosition - i_padlength; + RTPheader->starts_byte1 = 0; + + if ((i_IPver != 2) || (RTPheader->payloadLen <= 0) || (RTPheader->payloadLen >= 16000) + || (i_startPosition < 12) || (i_startPosition > i_DatagramLen)) + { + return RTP_CORRUPT_PACKET; + } + + return 0; +} + +#ifdef NETEQ_RED_CODEC + +int WebRtcNetEQ_RedundancySplit(RTPPacket_t* RTPheader[], int i_MaximumPayloads, + int *i_No_Of_Payloads) +{ + const WebRtc_Word16 *pw16_data = RTPheader[0]->payload; /* Pointer to the data */ + WebRtc_UWord16 uw16_offsetTimeStamp = 65535, uw16_secondPayload = 65535; + int i_blockLength, i_k; + int i_discardedBlockLength = 0; + int singlePayload = 0; + +#ifdef WEBRTC_BIG_ENDIAN + if ((pw16_data[0] & 0x8000) == 0) + { + /* Only one payload in this packet*/ + singlePayload = 1; + /* set the blocklength to -4 to deduce the non-existent 4-byte RED header */ + i_blockLength = -4; + RTPheader[0]->payloadType = ((((WebRtc_UWord16)pw16_data[0]) & 0x7F00) >> 8); + } + else + { + /* Discard all but the two last payloads. */ + while (((pw16_data[2] & 0x8000) == 1)&& + (pw16_data<((RTPheader[0]->payload)+((RTPheader[0]->payloadLen+1)>>1)))) + { + i_discardedBlockLength += (4+(((WebRtc_UWord16)pw16_data[1]) & 0x3FF)); + pw16_data+=2; + } + if (pw16_data>=(RTPheader[0]->payload+((RTPheader[0]->payloadLen+1)>>1))) + { + return RED_SPLIT_ERROR2; /* Error, we are outside the packet */ + } + singlePayload = 0; /* the packet contains more than one payload */ + uw16_secondPayload = ((((WebRtc_UWord16)pw16_data[0]) & 0x7F00) >> 8); + RTPheader[0]->payloadType = ((((WebRtc_UWord16)pw16_data[2]) & 0x7F00) >> 8); + uw16_offsetTimeStamp = ((((WebRtc_UWord16)pw16_data[0]) & 0xFF) << 6) + + ((((WebRtc_UWord16)pw16_data[1]) & 0xFC00) >> 10); + i_blockLength = (((WebRtc_UWord16)pw16_data[1]) & 0x3FF); + } +#else /* WEBRTC_LITTLE_ENDIAN */ + if ((pw16_data[0] & 0x80) == 0) + { + /* Only one payload in this packet */ + singlePayload = 1; + /* set the blocklength to -4 to deduce the non-existent 4-byte RED header */ + i_blockLength = -4; + RTPheader[0]->payloadType = (((WebRtc_UWord16) pw16_data[0]) & 0x7F); + } + else + { + /* Discard all but the two last payloads. */ + while (((pw16_data[2] & 0x80) == 1) && (pw16_data < ((RTPheader[0]->payload) + + ((RTPheader[0]->payloadLen + 1) >> 1)))) + { + i_discardedBlockLength += (4 + ((((WebRtc_UWord16) pw16_data[1]) & 0x3) << 8) + + ((((WebRtc_UWord16) pw16_data[1]) & 0xFF00) >> 8)); + pw16_data += 2; + } + if (pw16_data >= (RTPheader[0]->payload + ((RTPheader[0]->payloadLen + 1) >> 1))) + { + return RED_SPLIT_ERROR2; /* Error, we are outside the packet */; + } + singlePayload = 0; /* the packet contains more than one payload */ + uw16_secondPayload = (((WebRtc_UWord16) pw16_data[0]) & 0x7F); + RTPheader[0]->payloadType = (((WebRtc_UWord16) pw16_data[2]) & 0x7F); + uw16_offsetTimeStamp = ((((WebRtc_UWord16) pw16_data[0]) & 0xFF00) >> 2) + + ((((WebRtc_UWord16) pw16_data[1]) & 0xFC) >> 2); + i_blockLength = ((((WebRtc_UWord16) pw16_data[1]) & 0x3) << 8) + + ((((WebRtc_UWord16) pw16_data[1]) & 0xFF00) >> 8); + } +#endif + + if (i_MaximumPayloads < 2 || singlePayload == 1) + { + /* Reject the redundancy; or no redundant payload present. */ + for (i_k = 1; i_k < i_MaximumPayloads; i_k++) + { + RTPheader[i_k]->payloadType = -1; + RTPheader[i_k]->payloadLen = 0; + } + + /* update the pointer for the main data */ + pw16_data = &pw16_data[(5 + i_blockLength) >> 1]; + RTPheader[0]->starts_byte1 = (5 + i_blockLength) & 0x1; + RTPheader[0]->payloadLen = RTPheader[0]->payloadLen - (i_blockLength + 5) + - i_discardedBlockLength; + RTPheader[0]->payload = pw16_data; + + *i_No_Of_Payloads = 1; + + } + else + { + /* Redundancy accepted, put the redundancy in second RTPheader. */ + RTPheader[1]->payloadType = uw16_secondPayload; + RTPheader[1]->payload = &pw16_data[5 >> 1]; + RTPheader[1]->starts_byte1 = 5 & 0x1; + RTPheader[1]->seqNumber = RTPheader[0]->seqNumber; + RTPheader[1]->timeStamp = RTPheader[0]->timeStamp - uw16_offsetTimeStamp; + RTPheader[1]->ssrc = RTPheader[0]->ssrc; + RTPheader[1]->payloadLen = i_blockLength; + + /* Modify first RTP packet, so that it contains the main data. */ + RTPheader[0]->payload = &pw16_data[(5 + i_blockLength) >> 1]; + RTPheader[0]->starts_byte1 = (5 + i_blockLength) & 0x1; + RTPheader[0]->payloadLen = RTPheader[0]->payloadLen - (i_blockLength + 5) + - i_discardedBlockLength; + + /* Clear the following payloads. */ + for (i_k = 2; i_k < i_MaximumPayloads; i_k++) + { + RTPheader[i_k]->payloadType = -1; + RTPheader[i_k]->payloadLen = 0; + } + + *i_No_Of_Payloads = 2; + } + return 0; +} + +#endif + diff --git a/src/libs/webrtc/neteq/rtp.h b/src/libs/webrtc/neteq/rtp.h new file mode 100644 index 00000000..8490d62e --- /dev/null +++ b/src/libs/webrtc/neteq/rtp.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * RTP data struct and related functions. + */ + +#ifndef RTP_H +#define RTP_H + +#include "typedefs.h" + +#include "codec_db.h" + +typedef struct +{ + WebRtc_UWord16 seqNumber; + WebRtc_UWord32 timeStamp; + WebRtc_UWord32 ssrc; + int payloadType; + const WebRtc_Word16 *payload; + WebRtc_Word16 payloadLen; + WebRtc_Word16 starts_byte1; + WebRtc_Word16 rcuPlCntr; +} RTPPacket_t; + +/**************************************************************************** + * WebRtcNetEQ_RTPPayloadInfo(...) + * + * Converts a datagram into an RTP header struct. + * + * Input: + * - Datagram : UDP datagram from the network + * - DatagramLen : Length in bytes of the datagram + * + * Output: + * - RTPheader : Structure with the datagram info + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_RTPPayloadInfo(WebRtc_Word16* pw16_Datagram, int i_DatagramLen, + RTPPacket_t* RTPheader); + +/**************************************************************************** + * WebRtcNetEQ_RedundancySplit(...) + * + * Splits a Redundancy RTP struct into two RTP structs. User has to check + * that it's really the redundancy payload. No such check is done inside this + * function. + * + * Input: + * - RTPheader : First header holds the whole RTP packet (with the redundancy payload) + * - MaximumPayloads: + * The maximum number of RTP payloads that should be + * extracted (1+maximum_no_of_Redundancies). + * + * Output: + * - RTPheader : First header holds the main RTP data, while 2..N + * holds the redundancy data. + * - No_Of + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_RedundancySplit(RTPPacket_t* RTPheader[], int i_MaximumPayloads, + int *i_No_Of_Payloads); + +#endif diff --git a/src/libs/webrtc/neteq/set_fs.c b/src/libs/webrtc/neteq/set_fs.c new file mode 100644 index 00000000..b2ad5cab --- /dev/null +++ b/src/libs/webrtc/neteq/set_fs.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Function were the sample rate is set. + */ + +#include "mcu.h" + +#include "dtmf_buffer.h" +#include "neteq_error_codes.h" + +int WebRtcNetEQ_McuSetFs(MCUInst_t *inst, WebRtc_UWord16 fs) +{ + WebRtc_Word16 ok = 0; + + switch (fs) + { + case 8000: + { +#ifdef NETEQ_ATEVENT_DECODE + ok = WebRtcNetEQ_DtmfDecoderInit(&inst->DTMF_inst, 8000, 560); +#endif + inst->timestampsPerCall = inst->millisecondsPerCall * 8; + break; + } + +#ifdef NETEQ_WIDEBAND + case 16000: + { +#ifdef NETEQ_ATEVENT_DECODE + ok = WebRtcNetEQ_DtmfDecoderInit(&inst->DTMF_inst, 16000, 1120); +#endif + inst->timestampsPerCall = inst->millisecondsPerCall * 16; + break; + } +#endif + +#ifdef NETEQ_32KHZ_WIDEBAND + case 32000: + { +#ifdef NETEQ_ATEVENT_DECODE + ok = WebRtcNetEQ_DtmfDecoderInit(&inst->DTMF_inst, 32000, 2240); +#endif + inst->timestampsPerCall = inst->millisecondsPerCall * 32; + break; + } +#endif + +#ifdef NETEQ_48KHZ_WIDEBAND + case 48000: + { +#ifdef NETEQ_ATEVENT_DECODE + ok = WebRtcNetEQ_DtmfDecoderInit(&inst->DTMF_inst, 48000, 3360); +#endif + inst->timestampsPerCall = inst->millisecondsPerCall * 48; + break; + } +#endif + + default: + { + /* Not supported yet */ + return CODEC_DB_UNSUPPORTED_FS; + } + } /* end switch */ + + inst->fs = fs; + + return ok; +} diff --git a/src/libs/webrtc/neteq/signal_mcu.c b/src/libs/webrtc/neteq/signal_mcu.c new file mode 100644 index 00000000..92929e26 --- /dev/null +++ b/src/libs/webrtc/neteq/signal_mcu.c @@ -0,0 +1,838 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Signal the MCU that data is available and ask for a RecOut decision. + */ + +#include "mcu.h" + +#include <string.h> + +#include "signal_processing_library.h" + +#include "automode.h" +#include "dtmf_buffer.h" +#include "mcu_dsp_common.h" +#include "neteq_error_codes.h" + +#ifdef NETEQ_DELAY_LOGGING +#include "delay_logging.h" +#include <stdio.h> + +extern FILE *delay_fid2; /* file pointer to delay log file */ +#endif + + +/* + * Signals the MCU that DSP status data is available. + */ +int WebRtcNetEQ_SignalMcu(MCUInst_t *inst) +{ + + int i_bufferpos, i_res; + WebRtc_UWord16 uw16_instr; + DSP2MCU_info_t dspInfo; + WebRtc_Word16 *blockPtr, blockLen; + WebRtc_UWord32 uw32_availableTS; + RTPPacket_t temp_pkt; + WebRtc_Word32 w32_bufsize, w32_tmp; + WebRtc_Word16 payloadType = -1; + WebRtc_Word16 wantedNoOfTimeStamps; + WebRtc_Word32 totalTS; + WebRtc_Word16 oldPT, latePacketExist = 0; + WebRtc_UWord32 oldTS, prevTS, uw32_tmp; + WebRtc_UWord16 prevSeqNo; + WebRtc_Word16 nextSeqNoAvail; + WebRtc_Word16 fs_mult, w16_tmp; + WebRtc_Word16 lastModeBGNonly = 0; +#ifdef NETEQ_DELAY_LOGGING + int temp_var; +#endif + int playDtmf = 0; + + fs_mult = WebRtcSpl_DivW32W16ResW16(inst->fs, 8000); + + /* Increment counter since last statistics report */ + inst->lastReportTS += inst->timestampsPerCall; + + /* Read info from DSP so we now current status */ + + WEBRTC_SPL_MEMCPY_W8(&dspInfo,inst->pw16_readAddress,sizeof(DSP2MCU_info_t)); + + /* Set blockPtr to first payload block */ + blockPtr = &inst->pw16_writeAddress[3]; + + /* Clear instruction word and number of lost samples (2*WebRtc_Word16) */ + inst->pw16_writeAddress[0] = 0; + inst->pw16_writeAddress[1] = 0; + inst->pw16_writeAddress[2] = 0; + + if ((dspInfo.lastMode & MODE_AWAITING_CODEC_PTR) != 0) + { + /* + * Make sure state is adjusted so that a codec update is + * performed when first packet arrives. + */ + if (inst->new_codec != 1) + { + inst->current_Codec = -1; + } + dspInfo.lastMode = (dspInfo.lastMode ^ MODE_AWAITING_CODEC_PTR); + } + +#ifdef NETEQ_STEREO + if ((dspInfo.lastMode & MODE_MASTER_DTMF_SIGNAL) != 0) + { + playDtmf = 1; /* force DTMF decision */ + dspInfo.lastMode = (dspInfo.lastMode ^ MODE_MASTER_DTMF_SIGNAL); + } + + if ((dspInfo.lastMode & MODE_USING_STEREO) != 0) + { + if (inst->usingStereo == 0) + { + /* stereo mode changed; reset automode instance to re-synchronize statistics */ + WebRtcNetEQ_ResetAutomode(&(inst->BufferStat_inst.Automode_inst), + inst->PacketBuffer_inst.maxInsertPositions); + } + inst->usingStereo = 1; + dspInfo.lastMode = (dspInfo.lastMode ^ MODE_USING_STEREO); + } + else + { + inst->usingStereo = 0; + } +#endif + + /* detect if BGN_ONLY flag is set in lastMode */ + if ((dspInfo.lastMode & MODE_BGN_ONLY) != 0) + { + lastModeBGNonly = 1; /* remember flag */ + dspInfo.lastMode ^= MODE_BGN_ONLY; /* clear the flag */ + } + + if ((dspInfo.lastMode == MODE_RFC3389CNG) || (dspInfo.lastMode == MODE_CODEC_INTERNAL_CNG) + || (dspInfo.lastMode == MODE_EXPAND)) + { + /* + * If last mode was CNG (or Expand, since this could be covering up for a lost CNG + * packet), increase the CNGplayedTS counter. + */ + inst->BufferStat_inst.uw32_CNGplayedTS += inst->timestampsPerCall; + + if (dspInfo.lastMode == MODE_RFC3389CNG) + { + /* remember that RFC3389CNG is on (needed if CNG is interrupted by DTMF) */ + inst->BufferStat_inst.w16_cngOn = CNG_RFC3389_ON; + } + else if (dspInfo.lastMode == MODE_CODEC_INTERNAL_CNG) + { + /* remember that internal CNG is on (needed if CNG is interrupted by DTMF) */ + inst->BufferStat_inst.w16_cngOn = CNG_INTERNAL_ON; + } + + } + + /* Update packet size from previously decoded packet */ + if (dspInfo.frameLen > 0) + { + inst->PacketBuffer_inst.packSizeSamples = dspInfo.frameLen; + } + + /* Look for late packet (unless codec has changed) */ + if (inst->new_codec != 1) + { + if (WebRtcNetEQ_DbIsMDCodec((enum WebRtcNetEQDecoder) inst->current_Codec)) + { + WebRtcNetEQ_PacketBufferFindLowestTimestamp(&inst->PacketBuffer_inst, + inst->timeStamp, &uw32_availableTS, &i_bufferpos, 1, &payloadType); + if ((inst->new_codec != 1) && (inst->timeStamp == uw32_availableTS) + && (inst->timeStamp < dspInfo.playedOutTS) && (i_bufferpos != -1) + && (WebRtcNetEQ_DbGetPayload(&(inst->codec_DB_inst), + (enum WebRtcNetEQDecoder) inst->current_Codec) == payloadType)) + { + temp_pkt.payload = blockPtr + 1; + i_res = WebRtcNetEQ_PacketBufferExtract(&inst->PacketBuffer_inst, &temp_pkt, + i_bufferpos); + if (i_res < 0) + { /* error returned */ + return i_res; + } + *blockPtr = temp_pkt.payloadLen; + /* set the flag if this is a redundant payload */ + if (temp_pkt.rcuPlCntr > 0) + { + *blockPtr = (*blockPtr) | (DSP_CODEC_RED_FLAG); + } + blockPtr += ((temp_pkt.payloadLen + 1) >> 1) + 1; + + /* + * Close the data with a zero size block, in case we will not write any + * more data. + */ + *blockPtr = 0; + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0xf0ff) + | DSP_CODEC_ADD_LATE_PKT; + latePacketExist = 1; + } + } + } + + i_res = WebRtcNetEQ_PacketBufferFindLowestTimestamp(&inst->PacketBuffer_inst, + dspInfo.playedOutTS, &uw32_availableTS, &i_bufferpos, (inst->new_codec == 0), + &payloadType); + if (i_res < 0) + { /* error returned */ + return i_res; + } + + if (inst->BufferStat_inst.w16_cngOn == CNG_RFC3389_ON) + { + /* + * Because of timestamp peculiarities, we have to "manually" disallow using a CNG + * packet with the same timestamp as the one that was last played. This can happen + * when using redundancy and will cause the timing to shift. + */ + while (i_bufferpos != -1 && WebRtcNetEQ_DbIsCNGPayload(&inst->codec_DB_inst, + payloadType) && dspInfo.playedOutTS >= uw32_availableTS) + { + + /* Don't use this packet, discard it */ + inst->PacketBuffer_inst.payloadType[i_bufferpos] = -1; + inst->PacketBuffer_inst.payloadLengthBytes[i_bufferpos] = 0; + inst->PacketBuffer_inst.numPacketsInBuffer--; + + /* Check buffer again */ + WebRtcNetEQ_PacketBufferFindLowestTimestamp(&inst->PacketBuffer_inst, + dspInfo.playedOutTS, &uw32_availableTS, &i_bufferpos, (inst->new_codec == 0), + &payloadType); + } + } + + /* Check packet buffer */ + w32_bufsize = WebRtcNetEQ_PacketBufferGetSize(&inst->PacketBuffer_inst); + + if (dspInfo.lastMode == MODE_SUCCESS_ACCELERATE || dspInfo.lastMode + == MODE_LOWEN_ACCELERATE || dspInfo.lastMode == MODE_SUCCESS_PREEMPTIVE + || dspInfo.lastMode == MODE_LOWEN_PREEMPTIVE) + { + /* Subtract (dspInfo.samplesLeft + inst->timestampsPerCall) from sampleMemory */ + inst->BufferStat_inst.Automode_inst.sampleMemory -= dspInfo.samplesLeft + + inst->timestampsPerCall; + /* Update post-call statistics */ + inst->statInst.jbChangeCount++; + } + + /* calculate total current buffer size (in ms*8), including sync buffer */ + w32_bufsize = WebRtcSpl_DivW32W16((w32_bufsize + dspInfo.samplesLeft), fs_mult); + + if (((WebRtc_UWord32) w32_bufsize >> 3) < inst->statInst.jbMinSize) + { + /* new all-time low */ + inst->statInst.jbMinSize = ((WebRtc_UWord32) w32_bufsize >> 3); /* shift to ms */ + } + if (((WebRtc_UWord32) w32_bufsize >> 3) > inst->statInst.jbMaxSize) + { + /* new all-time high */ + inst->statInst.jbMaxSize = ((WebRtc_UWord32) w32_bufsize >> 3); /* shift to ms */ + } + + /* Update avg bufsize: + * jbAvgSize = (jbAvgCount * jbAvgSize + w32_bufsize/8)/(jbAvgCount+1) + * with proper rounding + */ + { + WebRtc_Word32 avgTmp; + + /* Simplify the above formula to: + * jbAvgSizeQ16 = + * jbAvgSizeQ16 + ( (w32_bufsize/8 << 16) - jbAvgSizeQ16 + d ) / (jbAvgCount+1) + * where d = jbAvgCount/2 for proper rounding. + */ + + avgTmp = (((WebRtc_UWord32) w32_bufsize >> 3) << 16) - inst->statInst.jbAvgSizeQ16; + avgTmp = WEBRTC_SPL_DIV( avgTmp + (inst->statInst.jbAvgCount>>1), + inst->statInst.jbAvgCount + 1 ); + inst->statInst.jbAvgSizeQ16 += avgTmp; + + if (inst->statInst.jbAvgCount < (0xFFFF - 1)) + { + inst->statInst.jbAvgCount++; + } + } + +#ifdef NETEQ_ATEVENT_DECODE + /* DTMF data will affect the decision */ + if (WebRtcNetEQ_DtmfDecode(&inst->DTMF_inst, blockPtr + 1, blockPtr + 2, + dspInfo.playedOutTS + inst->BufferStat_inst.uw32_CNGplayedTS) > 0) + { + playDtmf = 1; + + /* Flag DTMF payload */ + inst->pw16_writeAddress[0] = inst->pw16_writeAddress[0] | DSP_DTMF_PAYLOAD; + + /* Block Length in bytes */ + blockPtr[0] = 4; + /* Advance to next payload position */ + blockPtr += 3; + } +#endif + + /* Update statistics and make decision */ + uw16_instr = WebRtcNetEQ_BufstatsDecision(&inst->BufferStat_inst, + inst->PacketBuffer_inst.packSizeSamples, w32_bufsize, dspInfo.playedOutTS, + uw32_availableTS, i_bufferpos == -1, + WebRtcNetEQ_DbIsCNGPayload(&inst->codec_DB_inst, payloadType), dspInfo.lastMode, + inst->NetEqPlayoutMode, inst->timestampsPerCall, inst->NoOfExpandCalls, fs_mult, + lastModeBGNonly, playDtmf); + + /* Check if time to reset loss counter */ + if (inst->lastReportTS > WEBRTC_SPL_UMUL(inst->fs, MAX_LOSS_REPORT_PERIOD)) + { + /* reset loss counter */ + WebRtcNetEQ_ResetMcuInCallStats(inst); + } + + /* Check sync buffer size */ + if ((dspInfo.samplesLeft >= inst->timestampsPerCall) && (uw16_instr + != BUFSTATS_DO_ACCELERATE) && (uw16_instr != BUFSTATS_DO_MERGE) && (uw16_instr + != BUFSTATS_DO_PREEMPTIVE_EXPAND)) + { + *blockPtr = 0; + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) | DSP_INSTR_NORMAL; + return 0; + } + + if (uw16_instr == BUFSTATS_DO_EXPAND) + { + inst->NoOfExpandCalls++; + } + else + { + /* update post-call statistics */ + WebRtc_UWord32 + expandTime = + WEBRTC_SPL_UDIV(WEBRTC_SPL_UMUL_32_16( + WEBRTC_SPL_UMUL_32_16((WebRtc_UWord32) inst->NoOfExpandCalls, + (WebRtc_UWord16) 1000), + inst->timestampsPerCall), inst->fs); /* expand time in ms */ + + if (expandTime > 2000) + { + inst->statInst.countExpandMoreThan2000ms++; + } + else if (expandTime > 500) + { + inst->statInst.countExpandMoreThan500ms++; + } + else if (expandTime > 250) + { + inst->statInst.countExpandMoreThan250ms++; + } + else if (expandTime > 120) + { + inst->statInst.countExpandMoreThan120ms++; + } + + if (expandTime > inst->statInst.longestExpandDurationMs) + { + inst->statInst.longestExpandDurationMs = expandTime; + } + + /* reset counter */ + inst->NoOfExpandCalls = 0; + } + + /* New codec or big change in packet number? */ + if (((inst->new_codec) || (uw16_instr == BUFSTAT_REINIT)) && (uw16_instr + != BUFSTATS_DO_EXPAND)) + { + CodecFuncInst_t cinst; + + /* Clear other instructions */ + blockPtr = &inst->pw16_writeAddress[3]; + /* Clear instruction word */ + inst->pw16_writeAddress[0] = 0; + + inst->timeStamp = uw32_availableTS; + dspInfo.playedOutTS = uw32_availableTS; + if (inst->current_Codec != -1) + { + i_res = WebRtcNetEQ_DbGetPtrs(&inst->codec_DB_inst, + (enum WebRtcNetEQDecoder) inst->current_Codec, &cinst); + if (i_res < 0) + { /* error returned */ + return i_res; + } + } + else + { + /* The main codec has not been initialized yet (first packets are DTMF or CNG). */ + if (WebRtcNetEQ_DbIsCNGPayload(&inst->codec_DB_inst, payloadType)) + { + /* The currently extracted packet is CNG; get CNG fs */ + WebRtc_UWord16 tempFs; + + tempFs = WebRtcNetEQ_DbGetSampleRate(&inst->codec_DB_inst, payloadType); + if (tempFs > 0) + { + inst->fs = tempFs; + } + } + WebRtcSpl_MemSetW16((WebRtc_Word16*) &cinst, 0, + sizeof(CodecFuncInst_t) / sizeof(WebRtc_Word16)); + cinst.codec_fs = inst->fs; + } + cinst.timeStamp = inst->timeStamp; + blockLen = (sizeof(CodecFuncInst_t)) >> (sizeof(WebRtc_Word16) - 1); /* in Word16 */ + *blockPtr = blockLen * 2; + blockPtr++; + WEBRTC_SPL_MEMCPY_W8(blockPtr,&cinst,sizeof(CodecFuncInst_t)); + blockPtr += blockLen; + inst->new_codec = 0; + + /* Reinitialize the MCU fs */ + i_res = WebRtcNetEQ_McuSetFs(inst, cinst.codec_fs); + if (i_res < 0) + { /* error returned */ + return i_res; + } + + /* Set the packet size by guessing */ + inst->PacketBuffer_inst.packSizeSamples = inst->timestampsPerCall * 3; + + WebRtcNetEQ_ResetAutomode(&(inst->BufferStat_inst.Automode_inst), + inst->PacketBuffer_inst.maxInsertPositions); + +#ifdef NETEQ_CNG_CODEC + /* Also insert CNG state as this might be needed by DSP */ + i_res = WebRtcNetEQ_DbGetPtrs(&inst->codec_DB_inst, kDecoderCNG, &cinst); + if ((i_res < 0) && (i_res != CODEC_DB_NOT_EXIST1)) + { + /* other error returned */ + /* (CODEC_DB_NOT_EXIST1 simply indicates that CNG is not used */ + return i_res; + } + else + { + /* CNG exists */ + blockLen = (sizeof(cinst.codec_state)) >> (sizeof(WebRtc_Word16) - 1); + *blockPtr = blockLen * 2; + blockPtr++; + WEBRTC_SPL_MEMCPY_W8(blockPtr,&cinst.codec_state,sizeof(cinst.codec_state)); + blockPtr += blockLen; + } +#endif + + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0xf0ff) + | DSP_CODEC_NEW_CODEC; + + if (uw16_instr == BUFSTATS_DO_RFC3389CNG_NOPACKET) + { + /* + * Change decision to CNG packet, since we do have a CNG packet, but it was + * considered too early to use. Now, use it anyway. + */ + uw16_instr = BUFSTATS_DO_RFC3389CNG_PACKET; + } + else if (uw16_instr != BUFSTATS_DO_RFC3389CNG_PACKET) + { + uw16_instr = BUFSTATS_DO_NORMAL; + } + + /* reset loss counter */ + WebRtcNetEQ_ResetMcuInCallStats(inst); + } + + /* Should we just reset the decoder? */ + if (uw16_instr == BUFSTAT_REINIT_DECODER) + { + /* Change decision to normal and flag decoder reset */ + uw16_instr = BUFSTATS_DO_NORMAL; + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0xf0ff) | DSP_CODEC_RESET; + } + + /* Expand requires no new packet */ + if (uw16_instr == BUFSTATS_DO_EXPAND) + { + + inst->timeStamp = dspInfo.playedOutTS; + + /* Have we got one descriptor left? */ + if (WebRtcNetEQ_DbIsMDCodec((enum WebRtcNetEQDecoder) inst->current_Codec) + && (dspInfo.MD || latePacketExist)) + { + + if (dspInfo.lastMode != MODE_ONE_DESCRIPTOR) + { + /* this is the first "consecutive" one-descriptor decoding; reset counter */ + inst->one_desc = 0; + } + if (inst->one_desc < MAX_ONE_DESC) + { + /* use that one descriptor */ + inst->one_desc++; /* increase counter */ + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_NORMAL_ONE_DESC; + + /* decrease counter since we did no Expand */ + inst->NoOfExpandCalls = WEBRTC_SPL_MAX(inst->NoOfExpandCalls - 1, 0); + return 0; + } + else + { + /* too many consecutive one-descriptor decodings; do expand instead */ + inst->one_desc = 0; /* reset counter */ + } + + } + + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) | DSP_INSTR_EXPAND; + return 0; + } + + /* Merge is not needed if we still have a descriptor */ + if ((uw16_instr == BUFSTATS_DO_MERGE) && (dspInfo.MD != 0)) + { + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_NORMAL_ONE_DESC; + *blockPtr = 0; + return 0; + } + + /* Do CNG without trying to extract any packets from buffer */ + if (uw16_instr == BUFSTATS_DO_RFC3389CNG_NOPACKET) + { + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_DO_RFC3389CNG; + *blockPtr = 0; + return 0; + } + + /* Do built-in CNG without extracting any new packets from buffer */ + if (uw16_instr == BUFSTATS_DO_INTERNAL_CNG_NOPACKET) + { + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_DO_CODEC_INTERNAL_CNG; + *blockPtr = 0; + return 0; + } + + /* Do DTMF without extracting any new packets from buffer */ + if (uw16_instr == BUFSTATS_DO_DTMF_ONLY) + { + WebRtc_UWord32 timeStampJump = 0; + + /* Update timestamp */ + if ((inst->BufferStat_inst.uw32_CNGplayedTS > 0) && (dspInfo.lastMode != MODE_DTMF)) + { + /* Jump in timestamps if needed */ + timeStampJump = inst->BufferStat_inst.uw32_CNGplayedTS; + inst->pw16_writeAddress[1] = (WebRtc_UWord16) (timeStampJump >> 16); + inst->pw16_writeAddress[2] = (WebRtc_UWord16) (timeStampJump & 0xFFFF); + } + + inst->timeStamp = dspInfo.playedOutTS + timeStampJump; + + /* update post-call statistics (since we will reset the CNG counter) */ + inst->statInst.generatedSilentMs + += WEBRTC_SPL_UDIV( + WEBRTC_SPL_UMUL_32_16(inst->BufferStat_inst.uw32_CNGplayedTS, (WebRtc_UWord16) 1000), + inst->fs); + + inst->BufferStat_inst.uw32_CNGplayedTS = 0; + inst->NoOfExpandCalls = 0; + + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_DTMF_GENERATE; + *blockPtr = 0; + return 0; + } + + if (uw16_instr == BUFSTATS_DO_ACCELERATE) + { + /* In order to do a Accelerate we need at least 30 ms of data */ + if (dspInfo.samplesLeft >= (3 * 80 * fs_mult)) + { + /* Already have enough data, so we do not need to extract any more */ + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_ACCELERATE; + *blockPtr = 0; + inst->BufferStat_inst.Automode_inst.sampleMemory + = (WebRtc_Word32) dspInfo.samplesLeft; + inst->BufferStat_inst.Automode_inst.prevTimeScale = 1; + return 0; + } + else if ((dspInfo.samplesLeft >= (1 * 80 * fs_mult)) + && (inst->PacketBuffer_inst.packSizeSamples >= (240 * fs_mult))) + { + /* Avoid decoding more data as it might overflow playout buffer */ + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_NORMAL; + *blockPtr = 0; + return 0; + } + else if ((dspInfo.samplesLeft < (1 * 80 * fs_mult)) + && (inst->PacketBuffer_inst.packSizeSamples >= (240 * fs_mult))) + { + /* For >= 30ms allow Accelerate with a decoding to avoid overflow in playout buffer */ + wantedNoOfTimeStamps = inst->timestampsPerCall; + } + else if (dspInfo.samplesLeft >= (2 * 80 * fs_mult)) + { + /* We need to decode another 10 ms in order to do an Accelerate */ + wantedNoOfTimeStamps = inst->timestampsPerCall; + } + else + { + /* + * Build up decoded data by decoding at least 20 ms of data. + * Do not perform Accelerate yet, but wait until we only need to do one decoding. + */ + wantedNoOfTimeStamps = 2 * inst->timestampsPerCall; + uw16_instr = BUFSTATS_DO_NORMAL; + } + } + else if (uw16_instr == BUFSTATS_DO_PREEMPTIVE_EXPAND) + { + /* In order to do a Preemptive Expand we need at least 30 ms of data */ + if (dspInfo.samplesLeft >= (3 * 80 * fs_mult)) + { + /* Already have enough data, so we do not need to extract any more */ + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_PREEMPTIVE_EXPAND; + *blockPtr = 0; + inst->BufferStat_inst.Automode_inst.sampleMemory + = (WebRtc_Word32) dspInfo.samplesLeft; + inst->BufferStat_inst.Automode_inst.prevTimeScale = 1; + return 0; + } + else if ((dspInfo.samplesLeft >= (1 * 80 * fs_mult)) + && (inst->PacketBuffer_inst.packSizeSamples >= (240 * fs_mult))) + { + /* + * Avoid decoding more data as it might overflow playout buffer; + * still try Preemptive Expand though. + */ + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_PREEMPTIVE_EXPAND; + *blockPtr = 0; + inst->BufferStat_inst.Automode_inst.sampleMemory + = (WebRtc_Word32) dspInfo.samplesLeft; + inst->BufferStat_inst.Automode_inst.prevTimeScale = 1; + return 0; + } + else if ((dspInfo.samplesLeft < (1 * 80 * fs_mult)) + && (inst->PacketBuffer_inst.packSizeSamples >= (240 * fs_mult))) + { + /* + * For >= 30ms allow Preemptive Expand with a decoding to avoid overflow in + * playout buffer + */ + wantedNoOfTimeStamps = inst->timestampsPerCall; + } + else if (dspInfo.samplesLeft >= (2 * 80 * fs_mult)) + { + /* We need to decode another 10 ms in order to do an Preemptive Expand */ + wantedNoOfTimeStamps = inst->timestampsPerCall; + } + else + { + /* + * Build up decoded data by decoding at least 20 ms of data, + * Still try to perform Preemptive Expand. + */ + wantedNoOfTimeStamps = 2 * inst->timestampsPerCall; + } + } + else + { + wantedNoOfTimeStamps = inst->timestampsPerCall; + } + + /* Otherwise get data from buffer, try to get at least 10ms */ + totalTS = 0; + oldTS = uw32_availableTS; + if ((i_bufferpos > -1) && (uw16_instr != BUFSTATS_DO_ALTERNATIVE_PLC) && (uw16_instr + != BUFSTATS_DO_ALTERNATIVE_PLC_INC_TS) && (uw16_instr != BUFSTATS_DO_AUDIO_REPETITION) + && (uw16_instr != BUFSTATS_DO_AUDIO_REPETITION_INC_TS)) + { + uw32_tmp = (uw32_availableTS - dspInfo.playedOutTS); + inst->pw16_writeAddress[1] = (WebRtc_UWord16) (uw32_tmp >> 16); + inst->pw16_writeAddress[2] = (WebRtc_UWord16) (uw32_tmp & 0xFFFF); + if (inst->BufferStat_inst.w16_cngOn == CNG_OFF) + { + /* + * Adjustment of TS only corresponds to an actual packet loss + * if comfort noise is not played. If comfort noise was just played, + * this adjustment of TS is only done to get back in sync with the + * stream TS; no loss to report. + */ + inst->lostTS += uw32_tmp; + } + + if (uw16_instr != BUFSTATS_DO_RFC3389CNG_PACKET) + { + /* We are about to decode and use a non-CNG packet => CNG period is ended */ + inst->BufferStat_inst.w16_cngOn = CNG_OFF; + } + + /* update post-call statistics */ + inst->statInst.generatedSilentMs + += WEBRTC_SPL_UDIV( + WEBRTC_SPL_UMUL_32_16(inst->BufferStat_inst.uw32_CNGplayedTS, (WebRtc_UWord16) 1000), + inst->fs); + + /* + * Reset CNG timestamp as a new packet will be delivered. + * (Also if CNG packet, since playedOutTS is updated.) + */ + inst->BufferStat_inst.uw32_CNGplayedTS = 0; + + prevSeqNo = inst->PacketBuffer_inst.seqNumber[i_bufferpos]; + prevTS = inst->PacketBuffer_inst.timeStamp[i_bufferpos]; + oldPT = inst->PacketBuffer_inst.payloadType[i_bufferpos]; + + /* clear flag bits */ + inst->pw16_writeAddress[0] = inst->pw16_writeAddress[0] & 0xFF3F; + do + { + inst->timeStamp = uw32_availableTS; + /* Write directly to shared memory */ + temp_pkt.payload = blockPtr + 1; + i_res = WebRtcNetEQ_PacketBufferExtract(&inst->PacketBuffer_inst, &temp_pkt, + i_bufferpos); + + if (i_res < 0) + { + /* error returned */ + return i_res; + } + +#ifdef NETEQ_DELAY_LOGGING + temp_var = NETEQ_DELAY_LOGGING_SIGNAL_DECODE; + fwrite(&temp_var,sizeof(int),1,delay_fid2); + fwrite(&temp_pkt.timeStamp,sizeof(WebRtc_UWord32),1,delay_fid2); + fwrite(&dspInfo.samplesLeft, sizeof(WebRtc_UWord16), 1, delay_fid2); +#endif + + *blockPtr = temp_pkt.payloadLen; + /* set the flag if this is a redundant payload */ + if (temp_pkt.rcuPlCntr > 0) + { + *blockPtr = (*blockPtr) | (DSP_CODEC_RED_FLAG); + } + blockPtr += ((temp_pkt.payloadLen + 1) >> 1) + 1; + + if (i_bufferpos > -1) + { + /* + * Store number of TS extracted (last extracted is assumed to be of + * packSizeSamples). + */ + totalTS = uw32_availableTS - oldTS + inst->PacketBuffer_inst.packSizeSamples; + } + /* Check what next packet is available */ + WebRtcNetEQ_PacketBufferFindLowestTimestamp(&inst->PacketBuffer_inst, + inst->timeStamp, &uw32_availableTS, &i_bufferpos, 0, &payloadType); + + nextSeqNoAvail = 0; + if ((i_bufferpos > -1) && (oldPT + == inst->PacketBuffer_inst.payloadType[i_bufferpos])) + { + w16_tmp = inst->PacketBuffer_inst.seqNumber[i_bufferpos] - prevSeqNo; + w32_tmp = inst->PacketBuffer_inst.timeStamp[i_bufferpos] - prevTS; + if ((w16_tmp == 1) || /* Next packet */ + ((w16_tmp == 0) && (w32_tmp == inst->PacketBuffer_inst.packSizeSamples))) + { /* or packet split into frames */ + nextSeqNoAvail = 1; + } + prevSeqNo = inst->PacketBuffer_inst.seqNumber[i_bufferpos]; + } + + } + while ((totalTS < wantedNoOfTimeStamps) && (nextSeqNoAvail == 1)); + } + + if ((uw16_instr == BUFSTATS_DO_ACCELERATE) + || (uw16_instr == BUFSTATS_DO_PREEMPTIVE_EXPAND)) + { + /* Check that we have enough data (30ms) to do the Accelearate */ + if ((totalTS + dspInfo.samplesLeft) < WEBRTC_SPL_MUL(3,inst->timestampsPerCall) + && (uw16_instr == BUFSTATS_DO_ACCELERATE)) + { + /* Not enough, do normal operation instead */ + uw16_instr = BUFSTATS_DO_NORMAL; + } + else + { + inst->BufferStat_inst.Automode_inst.sampleMemory + = (WebRtc_Word32) dspInfo.samplesLeft + totalTS; + inst->BufferStat_inst.Automode_inst.prevTimeScale = 1; + } + } + + /* Close the data with a zero size block */ + *blockPtr = 0; + + /* Write data to DSP */ + switch (uw16_instr) + { + case BUFSTATS_DO_NORMAL: + /* Normal with decoding included */ + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_NORMAL; + break; + case BUFSTATS_DO_ACCELERATE: + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_ACCELERATE; + break; + case BUFSTATS_DO_MERGE: + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_MERGE; + break; + case BUFSTATS_DO_RFC3389CNG_PACKET: + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_DO_RFC3389CNG; + break; + case BUFSTATS_DO_ALTERNATIVE_PLC: + inst->pw16_writeAddress[1] = 0; + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_DO_ALTERNATIVE_PLC; + break; + case BUFSTATS_DO_ALTERNATIVE_PLC_INC_TS: + inst->pw16_writeAddress[1] = 0; + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_DO_ALTERNATIVE_PLC_INC_TS; + break; + case BUFSTATS_DO_AUDIO_REPETITION: + inst->pw16_writeAddress[1] = 0; + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_DO_AUDIO_REPETITION; + break; + case BUFSTATS_DO_AUDIO_REPETITION_INC_TS: + inst->pw16_writeAddress[1] = 0; + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_DO_AUDIO_REPETITION_INC_TS; + break; + case BUFSTATS_DO_PREEMPTIVE_EXPAND: + inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0x0fff) + | DSP_INSTR_PREEMPTIVE_EXPAND; + break; + default: + return UNKNOWN_BUFSTAT_DECISION; + } + + inst->timeStamp = dspInfo.playedOutTS; + return 0; + +} + diff --git a/src/libs/webrtc/neteq/split_and_insert.c b/src/libs/webrtc/neteq/split_and_insert.c new file mode 100644 index 00000000..03c15692 --- /dev/null +++ b/src/libs/webrtc/neteq/split_and_insert.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Split an RTP payload (if possible and suitable) and insert into packet buffer. + */ + +#include "mcu.h" + +#include <string.h> + +#include "signal_processing_library.h" + +#include "neteq_error_codes.h" + +int WebRtcNetEQ_SplitAndInsertPayload(RTPPacket_t *packet, PacketBuf_t *Buffer_inst, + SplitInfo_t *split_inst, WebRtc_Word16 *flushed) +{ + + int i_ok; + int len; + int i; + RTPPacket_t temp_packet; + WebRtc_Word16 localFlushed = 0; + const WebRtc_Word16 *pw16_startPayload; + *flushed = 0; + + len = packet->payloadLen; + + /* Copy to temp packet that can be modified. */ + + WEBRTC_SPL_MEMCPY_W8(&temp_packet,packet,sizeof(RTPPacket_t)); + + if (split_inst->deltaBytes == NO_SPLIT) + { + /* Not splittable codec */ + i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, packet, &localFlushed); + *flushed |= localFlushed; + if (i_ok < 0) + { + return PBUFFER_INSERT_ERROR5; + } + } + else if (split_inst->deltaBytes < -10) + { + /* G711, PCM16B or G722, use "soft splitting" */ + int split_size = packet->payloadLen; + int mult = WEBRTC_SPL_ABS_W32(split_inst->deltaBytes) - 10; + + /* Find "chunk size" >= 20 ms and < 40 ms + * split_inst->deltaTime in this case contains the number of bytes per + * timestamp unit times 2 + */ + while (split_size >= ((80 << split_inst->deltaTime) * mult)) + { + split_size >>= 1; + } + + /* Make the size an even value. */ + if (split_size > 1) + { + split_size >>= 1; + split_size *= 2; + } + + temp_packet.payloadLen = split_size; + pw16_startPayload = temp_packet.payload; + i = 0; + while (len >= (2 * split_size)) + { + /* insert every chunk */ + i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet, &localFlushed); + *flushed |= localFlushed; + temp_packet.timeStamp += ((2 * split_size) >> split_inst->deltaTime); + i++; + temp_packet.payload = &(pw16_startPayload[(i * split_size) >> 1]); + temp_packet.starts_byte1 = temp_packet.starts_byte1 ^ (split_size & 0x1); + + len -= split_size; + if (i_ok < 0) + { + return PBUFFER_INSERT_ERROR1; + } + } + + /* Insert the rest */ + temp_packet.payloadLen = len; + i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet, &localFlushed); + *flushed |= localFlushed; + if (i_ok < 0) + { + return PBUFFER_INSERT_ERROR2; + } + } + else + { + /* Frame based codec, use hard splitting. */ + i = 0; + pw16_startPayload = temp_packet.payload; + while (len >= split_inst->deltaBytes) + { + + temp_packet.payloadLen = split_inst->deltaBytes; + i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet, &localFlushed); + *flushed |= localFlushed; + i++; + temp_packet.payload = &(pw16_startPayload[(i * split_inst->deltaBytes) >> 1]); + temp_packet.timeStamp += split_inst->deltaTime; + temp_packet.starts_byte1 = temp_packet.starts_byte1 ^ (split_inst->deltaBytes + & 0x1); + + if (i_ok < 0) + { + return PBUFFER_INSERT_ERROR3; + } + len -= split_inst->deltaBytes; + + } + if (len > 0) + { + /* Must be a either an error or a SID frame at the end of the packet. */ + temp_packet.payloadLen = len; + i_ok = WebRtcNetEQ_PacketBufferInsert(Buffer_inst, &temp_packet, &localFlushed); + *flushed |= localFlushed; + if (i_ok < 0) + { + return PBUFFER_INSERT_ERROR4; + } + } + } + + return 0; +} + diff --git a/src/libs/webrtc/neteq/unmute_signal.c b/src/libs/webrtc/neteq/unmute_signal.c new file mode 100644 index 00000000..ee9daa82 --- /dev/null +++ b/src/libs/webrtc/neteq/unmute_signal.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This function "unmutes" a vector on a sample by sample basis. + */ + +#include "dsp_helpfunctions.h" + +#include "signal_processing_library.h" + + +void WebRtcNetEQ_UnmuteSignal(WebRtc_Word16 *pw16_inVec, WebRtc_Word16 *startMuteFact, + WebRtc_Word16 *pw16_outVec, WebRtc_Word16 unmuteFact, + WebRtc_Word16 N) +{ + int i; + WebRtc_UWord16 w16_tmp; + WebRtc_Word32 w32_tmp; + + w16_tmp = (WebRtc_UWord16) *startMuteFact; + w32_tmp = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)w16_tmp,6) + 32; + for (i = 0; i < N; i++) + { + pw16_outVec[i] + = (WebRtc_Word16) ((WEBRTC_SPL_MUL_16_16(w16_tmp, pw16_inVec[i]) + 8192) >> 14); + w32_tmp += unmuteFact; + w32_tmp = WEBRTC_SPL_MAX(0, w32_tmp); + w16_tmp = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(w32_tmp, 6); /* 20 - 14 = 6 */ + w16_tmp = WEBRTC_SPL_MIN(16384, w16_tmp); + } + *startMuteFact = (WebRtc_Word16) w16_tmp; +} + diff --git a/src/libs/webrtc/neteq/webrtc_neteq.c b/src/libs/webrtc/neteq/webrtc_neteq.c new file mode 100644 index 00000000..29576d8e --- /dev/null +++ b/src/libs/webrtc/neteq/webrtc_neteq.c @@ -0,0 +1,1761 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Implementation of main NetEQ API. + */ + +#include "webrtc_neteq.h" +#include "webrtc_neteq_internal.h" + +#include <string.h> + +#include "typedefs.h" +#include "signal_processing_library.h" + +#include "neteq_error_codes.h" +#include "mcu_dsp_common.h" +#include "rtcp.h" + +#define RETURN_ON_ERROR( macroExpr, macroInstPtr ) { \ + if ((macroExpr) != 0) { \ + if ((macroExpr) == -1) { \ + (macroInstPtr)->ErrorCode = - (NETEQ_OTHER_ERROR); \ + } else { \ + (macroInstPtr)->ErrorCode = -((WebRtc_Word16) (macroExpr)); \ + } \ + return(-1); \ + } } + +int WebRtcNetEQ_strncpy(WebRtc_Word8 *strDest, int numberOfElements, + const WebRtc_Word8 *strSource, int count) +{ + /* check vector lengths */ + if (count > numberOfElements) + { + strDest[0] = '\0'; + return (-1); + } + else + { + strncpy(strDest, strSource, count); + return (0); + } +} + +/********************************************************** + * NETEQ Functions + */ + +/***************************************** + * Info functions + */ + +int WebRtcNetEQ_GetVersion(WebRtc_Word8 *version) +{ + char versionString[] = "3.3.0\0 "; + char endChar[] = " "; + int i = 0; + while ((versionString[i] != endChar[0]) && (i <= 20)) + { + version[i] = versionString[i]; /* To avoid using strcpy */ + i++; + } + return (0); +} + +int WebRtcNetEQ_GetErrorCode(void *inst) +{ + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + return (NetEqMainInst->ErrorCode); +} + +int WebRtcNetEQ_GetErrorName(int errorCode, WebRtc_Word8 *errorName, int maxStrLen) +{ + if ((errorName == NULL) || (maxStrLen <= 0)) + { + return (-1); + } + + if (errorCode < 0) + { + errorCode = -errorCode; // absolute value + } + + switch (errorCode) + { + case 1: // could be -1 + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "OTHER_ERROR", maxStrLen); + break; + } + case 1001: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "FAULTY_INSTRUCTION", maxStrLen); + break; + } + case 1002: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "FAULTY_NETWORK_TYPE", maxStrLen); + break; + } + case 1003: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "FAULTY_DELAYVALUE", maxStrLen); + break; + } + case 1004: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "FAULTY_PLAYOUTMODE", maxStrLen); + break; + } + case 1005: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "CORRUPT_INSTANCE", maxStrLen); + break; + } + case 1006: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "ILLEGAL_MASTER_SLAVE_SWITCH", maxStrLen); + break; + } + case 1007: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "MASTER_SLAVE_ERROR", maxStrLen); + break; + } + case 2001: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "UNKNOWN_BUFSTAT_DECISION", maxStrLen); + break; + } + case 2002: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "RECOUT_ERROR_DECODING", maxStrLen); + break; + } + case 2003: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "RECOUT_ERROR_SAMPLEUNDERRUN", maxStrLen); + break; + } + case 2004: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "RECOUT_ERROR_DECODED_TOO_MUCH", + maxStrLen); + break; + } + case 3001: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "RECIN_CNG_ERROR", maxStrLen); + break; + } + case 3002: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "RECIN_UNKNOWNPAYLOAD", maxStrLen); + break; + } + case 3003: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "RECIN_BUFFERINSERT_ERROR", maxStrLen); + break; + } + case 4001: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "PBUFFER_INIT_ERROR", maxStrLen); + break; + } + case 4002: + case 4003: + case 4004: + case 4005: + case 4006: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "PBUFFER_INSERT_ERROR1", maxStrLen); + break; + } + case 4007: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "UNKNOWN_G723_HEADER", maxStrLen); + break; + } + case 4008: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "PBUFFER_NONEXISTING_PACKET", maxStrLen); + break; + } + case 4009: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "PBUFFER_NOT_INITIALIZED", maxStrLen); + break; + } + case 4010: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "AMBIGUOUS_ILBC_FRAME_SIZE", maxStrLen); + break; + } + case 5001: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "CODEC_DB_FULL", maxStrLen); + break; + } + case 5002: + case 5003: + case 5004: + case 5005: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "CODEC_DB_NOT_EXIST", maxStrLen); + break; + } + case 5006: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "CODEC_DB_UNKNOWN_CODEC", maxStrLen); + break; + } + case 5007: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "CODEC_DB_PAYLOAD_TAKEN", maxStrLen); + break; + } + case 5008: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "CODEC_DB_UNSUPPORTED_CODEC", maxStrLen); + break; + } + case 5009: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "CODEC_DB_UNSUPPORTED_FS", maxStrLen); + break; + } + case 6001: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "DTMF_DEC_PARAMETER_ERROR", maxStrLen); + break; + } + case 6002: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "DTMF_INSERT_ERROR", maxStrLen); + break; + } + case 6003: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "DTMF_GEN_UNKNOWN_SAMP_FREQ", maxStrLen); + break; + } + case 6004: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "DTMF_NOT_SUPPORTED", maxStrLen); + break; + } + case 7001: + case 7002: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "RED_SPLIT_ERROR", maxStrLen); + break; + } + case 7003: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "RTP_TOO_SHORT_PACKET", maxStrLen); + break; + } + case 7004: + { + WebRtcNetEQ_strncpy(errorName, maxStrLen, "RTP_CORRUPT_PACKET", maxStrLen); + break; + } + default: + { + /* check for decoder error ranges */ + if (errorCode >= 6010 && errorCode <= 6810) + { + /* iSAC error code */ + WebRtcNetEQ_strncpy(errorName, maxStrLen, "iSAC ERROR", maxStrLen); + break; + } + + WebRtcNetEQ_strncpy(errorName, maxStrLen, "UNKNOWN_ERROR", maxStrLen); + return (-1); + } + } + + return (0); +} + +/* Assign functions (create not allowed in order to avoid malloc in lib) */ +int WebRtcNetEQ_AssignSize(int *sizeinbytes) +{ + *sizeinbytes = (sizeof(MainInst_t) * 2) / sizeof(WebRtc_Word16); + return (0); +} + +int WebRtcNetEQ_Assign(void **inst, void *NETEQ_inst_Addr) +{ + int ok = 0; + MainInst_t *NetEqMainInst = (MainInst_t*) NETEQ_inst_Addr; + *inst = NETEQ_inst_Addr; + if (*inst == NULL) return (-1); + /* Clear memory */ + WebRtcSpl_MemSetW16((WebRtc_Word16*) NetEqMainInst, 0, + (sizeof(MainInst_t) / sizeof(WebRtc_Word16))); + ok = WebRtcNetEQ_McuReset(&NetEqMainInst->MCUinst); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + return (0); +} + +int WebRtcNetEQ_GetRecommendedBufferSize(void *inst, enum WebRtcNetEQDecoder *codec, + int noOfCodecs, enum WebRtcNetEQNetworkType nwType, + int *MaxNoOfPackets, int *sizeinbytes) +{ + int ok = 0; + int multiplier; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + *MaxNoOfPackets = 0; + *sizeinbytes = 0; + ok = WebRtcNetEQ_GetDefaultCodecSettings(codec, noOfCodecs, sizeinbytes, MaxNoOfPackets); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + if (nwType == kUDPNormal) + { + multiplier = 1; + } + else if (nwType == kUDPVideoSync) + { + multiplier = 4; + } + else if (nwType == kTCPNormal) + { + multiplier = 4; + } + else if (nwType == kTCPLargeJitter) + { + multiplier = 8; + } + else if (nwType == kTCPXLargeJitter) + { + multiplier = 20; + } + else + { + NetEqMainInst->ErrorCode = -FAULTY_NETWORK_TYPE; + return (-1); + } + *MaxNoOfPackets = (*MaxNoOfPackets) * multiplier; + *sizeinbytes = (*sizeinbytes) * multiplier; + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + return (ok); +} + +int WebRtcNetEQ_AssignBuffer(void *inst, int MaxNoOfPackets, void *NETEQ_Buffer_Addr, + int sizeinbytes) +{ + int ok; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + ok = WebRtcNetEQ_PacketBufferInit(&NetEqMainInst->MCUinst.PacketBuffer_inst, + MaxNoOfPackets, (WebRtc_Word16*) NETEQ_Buffer_Addr, (sizeinbytes >> 1)); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + return (ok); +} + +/************************************************ + * Init functions + */ + +/**************************************************************************** + * WebRtcNetEQ_Init(...) + * + * Initialize NetEQ. + * + * Input: + * - inst : NetEQ instance + * - fs : Initial sample rate in Hz (may change with payload) + * + * Output: + * - inst : Initialized NetEQ instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_Init(void *inst, WebRtc_UWord16 fs) +{ + int ok = 0; + + /* Typecast inst to internal instance format */ + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + + if (NetEqMainInst == NULL) + { + return (-1); + } + +#ifdef NETEQ_VAD + /* Start out with no PostDecode VAD instance */ + NetEqMainInst->DSPinst.VADInst.VADState = NULL; + /* Also set all VAD function pointers to NULL */ + NetEqMainInst->DSPinst.VADInst.initFunction = NULL; + NetEqMainInst->DSPinst.VADInst.setmodeFunction = NULL; + NetEqMainInst->DSPinst.VADInst.VADFunction = NULL; +#endif /* NETEQ_VAD */ + + ok = WebRtcNetEQ_DSPinit(NetEqMainInst); /* Init addresses between MCU and DSP */ + RETURN_ON_ERROR(ok, NetEqMainInst); + + ok = WebRtcNetEQ_DSPInit(&NetEqMainInst->DSPinst, fs); /* Init dsp side */ + RETURN_ON_ERROR(ok, NetEqMainInst); + /* set BGN mode to default, since it is not cleared by DSP init function */ + NetEqMainInst->DSPinst.BGNInst.bgnMode = BGN_ON; + + /* init statistics functions and counters */ + ok = WebRtcNetEQ_ClearInCallStats(&NetEqMainInst->DSPinst); + RETURN_ON_ERROR(ok, NetEqMainInst); + ok = WebRtcNetEQ_ClearPostCallStats(&NetEqMainInst->DSPinst); + RETURN_ON_ERROR(ok, NetEqMainInst); + ok = WebRtcNetEQ_ResetMcuJitterStat(&NetEqMainInst->MCUinst); + RETURN_ON_ERROR(ok, NetEqMainInst); + + /* flush packet buffer */ + ok = WebRtcNetEQ_PacketBufferFlush(&NetEqMainInst->MCUinst.PacketBuffer_inst); + RETURN_ON_ERROR(ok, NetEqMainInst); + + /* set some variables to initial values */ + NetEqMainInst->MCUinst.current_Codec = -1; + NetEqMainInst->MCUinst.current_Payload = -1; + NetEqMainInst->MCUinst.first_packet = 1; + NetEqMainInst->MCUinst.one_desc = 0; + NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.extraDelayMs = 0; + NetEqMainInst->MCUinst.NoOfExpandCalls = 0; + NetEqMainInst->MCUinst.fs = fs; + +#ifdef NETEQ_ATEVENT_DECODE + /* init DTMF decoder */ + ok = WebRtcNetEQ_DtmfDecoderInit(&(NetEqMainInst->MCUinst.DTMF_inst),fs,560); + RETURN_ON_ERROR(ok, NetEqMainInst); +#endif + + /* init RTCP statistics */ + WebRtcNetEQ_RTCPInit(&(NetEqMainInst->MCUinst.RTCP_inst), 0); + + /* set BufferStat struct to zero */ + WebRtcSpl_MemSetW16((WebRtc_Word16*) &(NetEqMainInst->MCUinst.BufferStat_inst), 0, + sizeof(BufstatsInst_t) / sizeof(WebRtc_Word16)); + + /* reset automode */ + WebRtcNetEQ_ResetAutomode(&(NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst), + NetEqMainInst->MCUinst.PacketBuffer_inst.maxInsertPositions); + + NetEqMainInst->ErrorCode = 0; + +#ifdef NETEQ_STEREO + /* set master/slave info to undecided */ + NetEqMainInst->masterSlave = 0; +#endif + + return (ok); +} + +int WebRtcNetEQ_FlushBuffers(void *inst) +{ + int ok = 0; + + /* Typecast inst to internal instance format */ + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + + if (NetEqMainInst == NULL) + { + return (-1); + } + + /* Flush packet buffer */ + ok = WebRtcNetEQ_PacketBufferFlush(&NetEqMainInst->MCUinst.PacketBuffer_inst); + RETURN_ON_ERROR(ok, NetEqMainInst); + + /* Set MCU to wait for new codec */ + NetEqMainInst->MCUinst.first_packet = 1; + + /* Flush speech buffer */ + ok = WebRtcNetEQ_FlushSpeechBuffer(&NetEqMainInst->DSPinst); + RETURN_ON_ERROR(ok, NetEqMainInst); + + return 0; +} + +int WebRtcNetEQ_SetAVTPlayout(void *inst, int PlayoutAVTon) +{ + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); +#ifdef NETEQ_ATEVENT_DECODE + NetEqMainInst->MCUinst.AVT_PlayoutOn = PlayoutAVTon; + return(0); +#else + if (PlayoutAVTon != 0) + { + NetEqMainInst->ErrorCode = -DTMF_NOT_SUPPORTED; + return (-1); + } + else + { + return (0); + } +#endif +} + +int WebRtcNetEQ_SetExtraDelay(void *inst, int DelayInMs) +{ + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + if ((DelayInMs < 0) || (DelayInMs > 1000)) + { + NetEqMainInst->ErrorCode = -FAULTY_DELAYVALUE; + return (-1); + } + NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.extraDelayMs = DelayInMs; + return (0); +} + +int WebRtcNetEQ_SetPlayoutMode(void *inst, enum WebRtcNetEQPlayoutMode playoutMode) +{ + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + if ((playoutMode != kPlayoutOn) && (playoutMode != kPlayoutOff) && (playoutMode + != kPlayoutFax) && (playoutMode != kPlayoutStreaming)) + { + NetEqMainInst->ErrorCode = -FAULTY_PLAYOUTMODE; + return (-1); + } + else + { + NetEqMainInst->MCUinst.NetEqPlayoutMode = playoutMode; + return (0); + } +} + +int WebRtcNetEQ_SetBGNMode(void *inst, enum WebRtcNetEQBGNMode bgnMode) +{ + + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + + /* Instance sanity */ + if (NetEqMainInst == NULL) return (-1); + + /* Check for corrupt/cleared instance */ + if (NetEqMainInst->MCUinst.main_inst != NetEqMainInst) + { + /* Instance is corrupt */ + NetEqMainInst->ErrorCode = CORRUPT_INSTANCE; + return (-1); + } + + NetEqMainInst->DSPinst.BGNInst.bgnMode = (enum BGNMode) bgnMode; + + return (0); +} + +int WebRtcNetEQ_GetBGNMode(const void *inst, enum WebRtcNetEQBGNMode *bgnMode) +{ + + const MainInst_t *NetEqMainInst = (const MainInst_t*) inst; + + /* Instance sanity */ + if (NetEqMainInst == NULL) return (-1); + + *bgnMode = (enum WebRtcNetEQBGNMode) NetEqMainInst->DSPinst.BGNInst.bgnMode; + + return (0); +} + +/************************************************ + * CodecDB functions + */ + +int WebRtcNetEQ_CodecDbReset(void *inst) +{ + int ok = 0; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + ok = WebRtcNetEQ_DbReset(&NetEqMainInst->MCUinst.codec_DB_inst); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + + /* set function pointers to NULL to prevent RecOut from using the codec */ + NetEqMainInst->DSPinst.codec_ptr_inst.funcDecode = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcDecodeRCU = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcAddLatePkt = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcDecode = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcDecodeInit = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcDecodePLC = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcGetMDinfo = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcUpdBWEst = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcGetErrorCode = NULL; + + return (0); +} + +int WebRtcNetEQ_CodecDbGetSizeInfo(void *inst, WebRtc_Word16 *UsedEntries, + WebRtc_Word16 *MaxEntries) +{ + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + *MaxEntries = NUM_CODECS; + *UsedEntries = NetEqMainInst->MCUinst.codec_DB_inst.nrOfCodecs; + return (0); +} + +int WebRtcNetEQ_CodecDbGetCodecInfo(void *inst, WebRtc_Word16 Entry, + enum WebRtcNetEQDecoder *codec) +{ + int i; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + *codec = (enum WebRtcNetEQDecoder) 0; + if ((Entry >= 0) && (Entry < NetEqMainInst->MCUinst.codec_DB_inst.nrOfCodecs)) + { + for (i = 0; i < NUM_TOTAL_CODECS; i++) + { + if (NetEqMainInst->MCUinst.codec_DB_inst.position[i] == Entry) + { + *codec = (enum WebRtcNetEQDecoder) i; + } + } + } + else + { + NetEqMainInst->ErrorCode = -(CODEC_DB_NOT_EXIST1); + return (-1); + } + return (0); +} + +int WebRtcNetEQ_CodecDbAdd(void *inst, WebRtcNetEQ_CodecDef *codecInst) +{ + int ok = 0; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + ok = WebRtcNetEQ_DbAdd(&NetEqMainInst->MCUinst.codec_DB_inst, codecInst->codec, + codecInst->payloadType, codecInst->funcDecode, codecInst->funcDecodeRCU, + codecInst->funcDecodePLC, codecInst->funcDecodeInit, codecInst->funcAddLatePkt, + codecInst->funcGetMDinfo, codecInst->funcGetPitch, codecInst->funcUpdBWEst, + codecInst->funcGetErrorCode, codecInst->codec_state, codecInst->codec_fs); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + return (ok); +} + +int WebRtcNetEQ_CodecDbRemove(void *inst, enum WebRtcNetEQDecoder codec) +{ + int ok = 0; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + + /* check if currently used codec is being removed */ + if (NetEqMainInst->MCUinst.current_Codec == (WebRtc_Word16) codec) + { + /* set function pointers to NULL to prevent RecOut from using the codec */ + NetEqMainInst->DSPinst.codec_ptr_inst.funcDecode = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcDecodeRCU = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcAddLatePkt = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcDecode = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcDecodeInit = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcDecodePLC = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcGetMDinfo = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcUpdBWEst = NULL; + NetEqMainInst->DSPinst.codec_ptr_inst.funcGetErrorCode = NULL; + } + + ok = WebRtcNetEQ_DbRemove(&NetEqMainInst->MCUinst.codec_DB_inst, codec); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + return (ok); +} + +/********************************* + * Real-time functions + */ + +int WebRtcNetEQ_RecIn(void *inst, WebRtc_Word16 *p_w16datagramstart, WebRtc_Word16 w16_RTPlen, + WebRtc_UWord32 uw32_timeRec) +{ + int ok = 0; + RTPPacket_t RTPpacket; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + + /* Check for corrupt/cleared instance */ + if (NetEqMainInst->MCUinst.main_inst != NetEqMainInst) + { + /* Instance is corrupt */ + NetEqMainInst->ErrorCode = CORRUPT_INSTANCE; + return (-1); + } + + /* Parse RTP header */ + ok = WebRtcNetEQ_RTPPayloadInfo(p_w16datagramstart, w16_RTPlen, &RTPpacket); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + + ok = WebRtcNetEQ_RecInInternal(&NetEqMainInst->MCUinst, &RTPpacket, uw32_timeRec); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + return (ok); +} + +/**************************************************************************** + * WebRtcNetEQ_RecInRTPStruct(...) + * + * Alternative RecIn function, used when the RTP data has already been + * parsed into an RTP info struct (WebRtcNetEQ_RTPInfo). + * + * Input: + * - inst : NetEQ instance + * - rtpInfo : Pointer to RTP info + * - payloadPtr : Pointer to the RTP payload (first byte after header) + * - payloadLenBytes : Length (in bytes) of the payload in payloadPtr + * - timeRec : Receive time (in timestamps of the used codec) + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNetEQ_RecInRTPStruct(void *inst, WebRtcNetEQ_RTPInfo *rtpInfo, + const WebRtc_UWord8 *payloadPtr, WebRtc_Word16 payloadLenBytes, + WebRtc_UWord32 uw32_timeRec) +{ + int ok = 0; + RTPPacket_t RTPpacket; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) + { + return (-1); + } + + /* Check for corrupt/cleared instance */ + if (NetEqMainInst->MCUinst.main_inst != NetEqMainInst) + { + /* Instance is corrupt */ + NetEqMainInst->ErrorCode = CORRUPT_INSTANCE; + return (-1); + } + + /* Load NetEQ's RTP struct from Module RTP struct */ + RTPpacket.payloadType = rtpInfo->payloadType; + RTPpacket.seqNumber = rtpInfo->sequenceNumber; + RTPpacket.timeStamp = rtpInfo->timeStamp; + RTPpacket.ssrc = rtpInfo->SSRC; + RTPpacket.payload = (const WebRtc_Word16*) payloadPtr; + RTPpacket.payloadLen = payloadLenBytes; + RTPpacket.starts_byte1 = 0; + + ok = WebRtcNetEQ_RecInInternal(&NetEqMainInst->MCUinst, &RTPpacket, uw32_timeRec); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + return (ok); +} + +int WebRtcNetEQ_RecOut(void *inst, WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_len) +{ + int ok = 0; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; +#ifdef NETEQ_STEREO + MasterSlaveInfo msInfo; + msInfo.msMode = NETEQ_MONO; +#endif + + if (NetEqMainInst == NULL) return (-1); + + /* Check for corrupt/cleared instance */ + if (NetEqMainInst->DSPinst.main_inst != NetEqMainInst) + { + /* Instance is corrupt */ + NetEqMainInst->ErrorCode = CORRUPT_INSTANCE; + return (-1); + } + +#ifdef NETEQ_STEREO + NetEqMainInst->DSPinst.msInfo = &msInfo; +#endif + + ok = WebRtcNetEQ_RecOutInternal(&NetEqMainInst->DSPinst, pw16_outData, + pw16_len, 0 /* not BGN only */); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + return (ok); +} + +/**************************************************************************** + * WebRtcNetEQ_RecOutMasterSlave(...) + * + * RecOut function for running several NetEQ instances in master/slave mode. + * One master can be used to control several slaves. + * + * Input: + * - inst : NetEQ instance + * - isMaster : Non-zero indicates that this is the master channel + * - msInfo : (slave only) Information from master + * + * Output: + * - inst : Updated NetEQ instance + * - pw16_outData : Pointer to vector where output should be written + * - pw16_len : Pointer to variable where output length is returned + * - msInfo : (master only) Information to slave(s) + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_RecOutMasterSlave(void *inst, WebRtc_Word16 *pw16_outData, + WebRtc_Word16 *pw16_len, void *msInfo, + WebRtc_Word16 isMaster) +{ +#ifndef NETEQ_STEREO + /* Stereo not supported */ + return(-1); +#else + int ok = 0; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + + if (NetEqMainInst == NULL) return (-1); + + /* Check for corrupt/cleared instance */ + if (NetEqMainInst->DSPinst.main_inst != NetEqMainInst) + { + /* Instance is corrupt */ + NetEqMainInst->ErrorCode = CORRUPT_INSTANCE; + return (-1); + } + + if (msInfo == NULL) + { + /* msInfo not provided */ + NetEqMainInst->ErrorCode = NETEQ_OTHER_ERROR; + return (-1); + } + + /* translate from external to internal Master/Slave information */ + NetEqMainInst->DSPinst.msInfo = (MasterSlaveInfo *) msInfo; + + /* check that we have not done a master/slave switch without first re-initializing */ + if ((NetEqMainInst->masterSlave == 1 && !isMaster) || /* switch from master to slave */ + (NetEqMainInst->masterSlave == 2 && isMaster)) /* switch from slave to master */ + { + NetEqMainInst->ErrorCode = ILLEGAL_MASTER_SLAVE_SWITCH; + return (-1); + } + + if (!isMaster) + { + /* this is the slave */ + NetEqMainInst->masterSlave = 2; + NetEqMainInst->DSPinst.msInfo->msMode = NETEQ_SLAVE; + } + else + { + NetEqMainInst->DSPinst.msInfo->msMode = NETEQ_MASTER; + } + + ok = WebRtcNetEQ_RecOutInternal(&NetEqMainInst->DSPinst, pw16_outData, + pw16_len, 0 /* not BGN only */); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + + if (isMaster) + { + /* this is the master */ + NetEqMainInst->masterSlave = 1; + } + + return (ok); +#endif +} + +int WebRtcNetEQ_GetMasterSlaveInfoSize() +{ +#ifdef NETEQ_STEREO + return (sizeof(MasterSlaveInfo)); +#else + return(-1); +#endif +} + +/* Special RecOut that does not do any decoding. */ +int WebRtcNetEQ_RecOutNoDecode(void *inst, WebRtc_Word16 *pw16_outData, + WebRtc_Word16 *pw16_len) +{ + int ok = 0; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; +#ifdef NETEQ_STEREO + MasterSlaveInfo msInfo; +#endif + + if (NetEqMainInst == NULL) return (-1); + + /* Check for corrupt/cleared instance */ + if (NetEqMainInst->DSPinst.main_inst != NetEqMainInst) + { + /* Instance is corrupt */ + NetEqMainInst->ErrorCode = CORRUPT_INSTANCE; + return (-1); + } + +#ifdef NETEQ_STEREO + /* keep same mode as before */ + switch (NetEqMainInst->masterSlave) + { + case 1: + { + msInfo.msMode = NETEQ_MASTER; + break; + } + case 2: + { + msInfo.msMode = NETEQ_SLAVE; + break; + } + default: + { + msInfo.msMode = NETEQ_MONO; + break; + } + } + + NetEqMainInst->DSPinst.msInfo = &msInfo; +#endif + + ok = WebRtcNetEQ_RecOutInternal(&NetEqMainInst->DSPinst, pw16_outData, + pw16_len, 1 /* BGN only */); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + return (ok); +} + +int WebRtcNetEQ_GetRTCPStats(void *inst, WebRtcNetEQ_RTCPStat *RTCP_inst) +{ + int ok = 0; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + ok = WebRtcNetEQ_RTCPGetStats(&NetEqMainInst->MCUinst.RTCP_inst, + &RTCP_inst->fraction_lost, &RTCP_inst->cum_lost, &RTCP_inst->ext_max, + &RTCP_inst->jitter, 0); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + return (ok); +} + +int WebRtcNetEQ_GetRTCPStatsNoReset(void *inst, WebRtcNetEQ_RTCPStat *RTCP_inst) +{ + int ok = 0; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + ok = WebRtcNetEQ_RTCPGetStats(&NetEqMainInst->MCUinst.RTCP_inst, + &RTCP_inst->fraction_lost, &RTCP_inst->cum_lost, &RTCP_inst->ext_max, + &RTCP_inst->jitter, 1); + if (ok != 0) + { + NetEqMainInst->ErrorCode = -ok; + return (-1); + } + return (ok); +} + +int WebRtcNetEQ_GetSpeechTimeStamp(void *inst, WebRtc_UWord32 *timestamp) +{ + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + + if (NetEqMainInst->MCUinst.TSscalingInitialized) + { + *timestamp = WebRtcNetEQ_ScaleTimestampInternalToExternal(&NetEqMainInst->MCUinst, + NetEqMainInst->DSPinst.videoSyncTimestamp); + } + else + { + *timestamp = NetEqMainInst->DSPinst.videoSyncTimestamp; + } + + return (0); +} + +/**************************************************************************** + * WebRtcNetEQ_GetSpeechOutputType(...) + * + * Get the output type for the audio provided by the latest call to + * WebRtcNetEQ_RecOut(). + * + * kOutputNormal = normal audio (possibly processed) + * kOutputPLC = loss concealment through stretching audio + * kOutputCNG = comfort noise (codec-internal or RFC3389) + * kOutputPLCtoCNG = background noise only due to long expand or error + * kOutputVADPassive = PostDecode VAD signalling passive speaker + * + * Input: + * - inst : NetEQ instance + * + * Output: + * - outputType : Output type from enum list WebRtcNetEQOutputType + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_GetSpeechOutputType(void *inst, enum WebRtcNetEQOutputType *outputType) +{ + /* Typecast to internal instance type */ + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + + if (NetEqMainInst == NULL) + { + return (-1); + } + + if ((NetEqMainInst->DSPinst.w16_mode & MODE_BGN_ONLY) != 0) + { + /* If last mode was background noise only */ + *outputType = kOutputPLCtoCNG; + + } + else if ((NetEqMainInst->DSPinst.w16_mode == MODE_CODEC_INTERNAL_CNG) + || (NetEqMainInst->DSPinst.w16_mode == MODE_RFC3389CNG)) + { + /* If CN or internal CNG */ + *outputType = kOutputCNG; + +#ifdef NETEQ_VAD + } + else if ( NetEqMainInst->DSPinst.VADInst.VADDecision == 0 ) + { + /* post-decode VAD says passive speaker */ + *outputType = kOutputVADPassive; +#endif /* NETEQ_VAD */ + + } + else if ((NetEqMainInst->DSPinst.w16_mode == MODE_EXPAND) + && (NetEqMainInst->DSPinst.ExpandInst.w16_expandMuteFactor == 0)) + { + /* Expand mode has faded down to background noise only (very long expand) */ + *outputType = kOutputPLCtoCNG; + + } + else if (NetEqMainInst->DSPinst.w16_mode == MODE_EXPAND) + { + /* PLC mode */ + *outputType = kOutputPLC; + + } + else + { + /* Normal speech output type (can still be manipulated, e.g., accelerated) */ + *outputType = kOutputNormal; + } + + return (0); +} + +/********************************** + * Functions related to VQmon + */ + +#define WEBRTC_NETEQ_CONCEALMENTFLAG_LOST 0x01 +#define WEBRTC_NETEQ_CONCEALMENTFLAG_DISCARDED 0x02 +#define WEBRTC_NETEQ_CONCEALMENTFLAG_SUPRESS 0x04 +#define WEBRTC_NETEQ_CONCEALMENTFLAG_CNGACTIVE 0x80 + +int WebRtcNetEQ_VQmonRecOutStatistics(void *inst, WebRtc_UWord16 *validVoiceDurationMs, + WebRtc_UWord16 *concealedVoiceDurationMs, + WebRtc_UWord8 *concealedVoiceFlags) +{ + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + WebRtc_Word16 fs_mult; + WebRtc_Word16 ms_lost; + if (NetEqMainInst == NULL) return (-1); + fs_mult = WebRtcSpl_DivW32W16ResW16(NetEqMainInst->MCUinst.fs, 8000); + + ms_lost = WebRtcSpl_DivW32W16ResW16( + (WebRtc_Word32) NetEqMainInst->DSPinst.w16_concealedTS, (WebRtc_Word16) (8 * fs_mult)); + if (ms_lost > NetEqMainInst->DSPinst.millisecondsPerCall) ms_lost + = NetEqMainInst->DSPinst.millisecondsPerCall; + + *validVoiceDurationMs = NetEqMainInst->DSPinst.millisecondsPerCall - ms_lost; + *concealedVoiceDurationMs = ms_lost; + if (ms_lost > 0) + { + *concealedVoiceFlags = WEBRTC_NETEQ_CONCEALMENTFLAG_LOST; + } + else + { + *concealedVoiceFlags = 0; + } + NetEqMainInst->DSPinst.w16_concealedTS -= ms_lost * (8 * fs_mult); + + return (0); +} + +int WebRtcNetEQ_VQmonGetConfiguration(void *inst, WebRtc_UWord16 *absMaxDelayMs, + WebRtc_UWord8 *adaptationRate) +{ + /* Dummy check the inst, just to avoid compiler warnings. */ + if (inst == NULL) + { + /* Do nothing. */ + } + + /* Hardcoded variables that are used for VQmon as jitter buffer parameters */ + *absMaxDelayMs = 240; + *adaptationRate = 1; + return (0); +} + +int WebRtcNetEQ_VQmonGetRxStatistics(void *inst, WebRtc_UWord16 *avgDelayMs, + WebRtc_UWord16 *maxDelayMs) +{ + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) return (-1); + *avgDelayMs = (WebRtc_UWord16) (NetEqMainInst->MCUinst.BufferStat_inst.avgDelayMsQ8 >> 8); + *maxDelayMs = (WebRtc_UWord16) NetEqMainInst->MCUinst.BufferStat_inst.maxDelayMs; + return (0); +} + +/************************************* + * Statistics functions + */ + +/* Get the "in-call" statistics from NetEQ. + * The statistics are reset after the query. */ +int WebRtcNetEQ_GetNetworkStatistics(void *inst, WebRtcNetEQ_NetworkStatistics *stats) + +{ + + WebRtc_UWord16 tempU16; + WebRtc_UWord32 tempU32, tempU32_2; + int numShift; + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + + /* Instance sanity */ + if (NetEqMainInst == NULL) return (-1); + + /*******************/ + /* Get buffer size */ + /*******************/ + + if (WebRtcNetEQ_GetCurrentDelay((void *) inst, &(stats->currentBufferSize)) != 0) + { + return (-1); + } + + /***************************/ + /* Get optimal buffer size */ + /***************************/ + + if (NetEqMainInst->MCUinst.fs != 0 && NetEqMainInst->MCUinst.fs <= WEBRTC_SPL_WORD16_MAX) + { + /* preferredBufferSize = Bopt * packSizeSamples / (fs/1000) */ + stats->preferredBufferSize + = (WebRtc_UWord16) WEBRTC_SPL_MUL_16_16( + (WebRtc_Word16) ((NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.optBufLevel) >> 8), /* optimal buffer level in packets shifted to Q0 */ + WebRtcSpl_DivW32W16ResW16( + (WebRtc_Word32) NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.packetSpeechLenSamp, /* samples per packet */ + WebRtcSpl_DivW32W16ResW16( (WebRtc_Word32) NetEqMainInst->MCUinst.fs, (WebRtc_Word16) 1000 ) /* samples per ms */ + ) ); + + /* add extra delay */ + if (NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.extraDelayMs > 0) + { + stats->preferredBufferSize + += NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.extraDelayMs; + } + } + else + { + /* sample rate not initialized */ + stats->preferredBufferSize = 0; + } + + /***********************/ + /* Calculate loss rate */ + /***********************/ + + /* timestamps elapsed since last report */ + tempU32 = NetEqMainInst->MCUinst.lastReportTS; + + if (NetEqMainInst->MCUinst.lostTS == 0) + { + /* no losses */ + stats->currentPacketLossRate = 0; + } + else if (NetEqMainInst->MCUinst.lostTS < tempU32) + { + /* calculate shifts; we want the result in Q14 */ + numShift = WebRtcSpl_NormU32(NetEqMainInst->MCUinst.lostTS); /* numerator shift for normalize */ + + if (numShift < 14) + { + /* cannot shift numerator 14 steps; shift denominator too */ + tempU32 = WEBRTC_SPL_RSHIFT_U32(tempU32, 14-numShift); /* right-shift */ + } + else + { + /* shift no more than 14 steps */ + numShift = 14; + } + + if (tempU32 == 0) + { + /* check for zero denominator; result should be zero in this case */ + stats->currentPacketLossRate = 0; + } + else + { + /* check that denominator fits in signed 16-bit */ + while (tempU32 > WEBRTC_SPL_WORD16_MAX) + { + tempU32 >>= 1; /* right-shift 1 step */ + numShift--; /* compensate in numerator */ + } + tempU16 = (WebRtc_UWord16) tempU32; + + /* do the shift of numerator */ + tempU32 + = WEBRTC_SPL_SHIFT_W32( (WebRtc_UWord32) NetEqMainInst->MCUinst.lostTS, numShift); + + stats->currentPacketLossRate = (WebRtc_UWord16) WebRtcSpl_DivU32U16(tempU32, + tempU16); + } + } + else + { + /* lost count is larger than elapsed time count; probably timestamp wrap-around or something else wrong */ + /* set loss rate = 1 */ + stats->currentPacketLossRate = 1 << 14; /* 1 in Q14 */ + } + + /**************************/ + /* Calculate discard rate */ + /**************************/ + + /* timestamps elapsed since last report */ + tempU32 = NetEqMainInst->MCUinst.lastReportTS; + + /* number of discarded samples */ + tempU32_2 + = WEBRTC_SPL_MUL_16_U16( (WebRtc_Word16) NetEqMainInst->MCUinst.PacketBuffer_inst.packSizeSamples, + NetEqMainInst->MCUinst.PacketBuffer_inst.discardedPackets); + + if (tempU32_2 == 0) + { + /* no discarded samples */ + stats->currentDiscardRate = 0; + } + else if (tempU32_2 < tempU32) + { + /* calculate shifts; we want the result in Q14 */ + numShift = WebRtcSpl_NormU32(tempU32_2); /* numerator shift for normalize */ + + if (numShift < 14) + { + /* cannot shift numerator 14 steps; shift denominator too */ + tempU32 = WEBRTC_SPL_RSHIFT_U32(tempU32, 14-numShift); /* right-shift */ + } + else + { + /* shift no more than 14 steps */ + numShift = 14; + } + + if (tempU32 == 0) + { + /* check for zero denominator; result should be zero in this case */ + stats->currentDiscardRate = 0; + } + else + { + /* check that denominator fits in signed 16-bit */ + while (tempU32 > WEBRTC_SPL_WORD16_MAX) + { + tempU32 >>= 1; /* right-shift 1 step */ + numShift--; /* compensate in numerator */ + } + tempU16 = (WebRtc_UWord16) tempU32; + + /* do the shift of numerator */ + tempU32 = WEBRTC_SPL_SHIFT_W32( tempU32_2, numShift); + + stats->currentDiscardRate = (WebRtc_UWord16) WebRtcSpl_DivU32U16(tempU32, tempU16); + } + } + else + { + /* lost count is larger than elapsed time count; probably timestamp wrap-around or something else wrong */ + /* set loss rate = 1 */ + stats->currentDiscardRate = 1 << 14; /* 1 in Q14 */ + } + + /*************************************************************/ + /* Calculate Accelerate, Expand and Pre-emptive Expand rates */ + /*************************************************************/ + + /* timestamps elapsed since last report */ + tempU32 = NetEqMainInst->MCUinst.lastReportTS; + + if (NetEqMainInst->DSPinst.statInst.accelerateLength == 0) + { + /* no accelerate */ + stats->currentAccelerateRate = 0; + } + else if (NetEqMainInst->DSPinst.statInst.accelerateLength < tempU32) + { + /* calculate shifts; we want the result in Q14 */ + numShift = WebRtcSpl_NormU32(NetEqMainInst->DSPinst.statInst.accelerateLength); /* numerator shift for normalize */ + + if (numShift < 14) + { + /* cannot shift numerator 14 steps; shift denominator too */ + tempU32 = WEBRTC_SPL_RSHIFT_U32(tempU32, 14-numShift); /* right-shift */ + } + else + { + /* shift no more than 14 steps */ + numShift = 14; + } + + if (tempU32 == 0) + { + /* check for zero denominator; result should be zero in this case */ + stats->currentAccelerateRate = 0; + } + else + { + /* check that denominator fits in signed 16-bit */ + while (tempU32 > WEBRTC_SPL_WORD16_MAX) + { + tempU32 >>= 1; /* right-shift 1 step */ + numShift--; /* compensate in numerator */ + } + tempU16 = (WebRtc_UWord16) tempU32; + + /* do the shift of numerator */ + tempU32 + = WEBRTC_SPL_SHIFT_W32( NetEqMainInst->DSPinst.statInst.accelerateLength, numShift); + + stats->currentAccelerateRate = (WebRtc_UWord16) WebRtcSpl_DivU32U16(tempU32, + tempU16); + } + } + else + { + /* lost count is larger than elapsed time count; probably timestamp wrap-around or something else wrong */ + /* set loss rate = 1 */ + stats->currentAccelerateRate = 1 << 14; /* 1 in Q14 */ + } + + /* also transfer measure to post-call statistics */ + NetEqMainInst->MCUinst.statInst.accelerateMs + += WebRtcSpl_DivU32U16( + WEBRTC_SPL_UMUL_32_16( NetEqMainInst->DSPinst.statInst.accelerateLength, (WebRtc_UWord16) 1000), + NetEqMainInst->MCUinst.fs); + + /* timestamps elapsed since last report */ + tempU32 = NetEqMainInst->MCUinst.lastReportTS; + + if (NetEqMainInst->DSPinst.statInst.expandLength == 0) + { + /* no expand */ + stats->currentExpandRate = 0; + } + else if (NetEqMainInst->DSPinst.statInst.expandLength < tempU32) + { + /* calculate shifts; we want the result in Q14 */ + numShift = WebRtcSpl_NormU32(NetEqMainInst->DSPinst.statInst.expandLength); /* numerator shift for normalize */ + + if (numShift < 14) + { + /* cannot shift numerator 14 steps; shift denominator too */ + tempU32 = WEBRTC_SPL_RSHIFT_U32(tempU32, 14-numShift); /* right-shift */ + } + else + { + /* shift no more than 14 steps */ + numShift = 14; + } + + if (tempU32 == 0) + { + /* check for zero denominator; result should be zero in this case */ + stats->currentExpandRate = 0; + } + else + { + /* check that denominator fits in signed 16-bit */ + while (tempU32 > WEBRTC_SPL_WORD16_MAX) + { + tempU32 >>= 1; /* right-shift 1 step */ + numShift--; /* compensate in numerator */ + } + tempU16 = (WebRtc_UWord16) tempU32; + + /* do the shift of numerator */ + tempU32 + = WEBRTC_SPL_SHIFT_W32( NetEqMainInst->DSPinst.statInst.expandLength, numShift); + + stats->currentExpandRate = (WebRtc_UWord16) WebRtcSpl_DivU32U16(tempU32, tempU16); + } + } + else + { + /* lost count is larger than elapsed time count; probably timestamp wrap-around or something else wrong */ + /* set loss rate = 1 */ + stats->currentExpandRate = 1 << 14; /* 1 in Q14 */ + } + + /* timestamps elapsed since last report */ + tempU32 = NetEqMainInst->MCUinst.lastReportTS; + + if (NetEqMainInst->DSPinst.statInst.preemptiveLength == 0) + { + /* no pre-emptive expand */ + stats->currentPreemptiveRate = 0; + } + else if (NetEqMainInst->DSPinst.statInst.preemptiveLength < tempU32) + { + /* calculate shifts; we want the result in Q14 */ + numShift = WebRtcSpl_NormU32(NetEqMainInst->DSPinst.statInst.preemptiveLength); /* numerator shift for normalize */ + + if (numShift < 14) + { + /* cannot shift numerator 14 steps; shift denominator too */ + tempU32 = WEBRTC_SPL_RSHIFT_U32(tempU32, 14-numShift); /* right-shift */ + } + else + { + /* shift no more than 14 steps */ + numShift = 14; + } + + if (tempU32 == 0) + { + /* check for zero denominator; result should be zero in this case */ + stats->currentPreemptiveRate = 0; + } + else + { + /* check that denominator fits in signed 16-bit */ + while (tempU32 > WEBRTC_SPL_WORD16_MAX) + { + tempU32 >>= 1; /* right-shift 1 step */ + numShift--; /* compensate in numerator */ + } + tempU16 = (WebRtc_UWord16) tempU32; + + /* do the shift of numerator */ + tempU32 + = WEBRTC_SPL_SHIFT_W32( NetEqMainInst->DSPinst.statInst.preemptiveLength, numShift); + + stats->currentPreemptiveRate = (WebRtc_UWord16) WebRtcSpl_DivU32U16(tempU32, + tempU16); + } + } + else + { + /* lost count is larger than elapsed time count; probably timestamp wrap-around or something else wrong */ + /* set loss rate = 1 */ + stats->currentPreemptiveRate = 1 << 14; /* 1 in Q14 */ + } + + /* reset counters */ + WebRtcNetEQ_ResetMcuInCallStats(&(NetEqMainInst->MCUinst)); + WebRtcNetEQ_ClearInCallStats(&(NetEqMainInst->DSPinst)); + + return (0); +} + +/* Get the optimal buffer size calculated for the current network conditions. */ +int WebRtcNetEQ_GetPreferredBufferSize(void *inst, WebRtc_UWord16 *preferredBufferSize) +{ + + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + + /***************************/ + /* Get optimal buffer size */ + /***************************/ + + if (NetEqMainInst->MCUinst.fs != 0 && NetEqMainInst->MCUinst.fs <= WEBRTC_SPL_WORD16_MAX) + { + /* preferredBufferSize = Bopt * packSizeSamples / (fs/1000) */ + *preferredBufferSize + = (WebRtc_UWord16) WEBRTC_SPL_MUL_16_16( + (WebRtc_Word16) ((NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.optBufLevel) >> 8), /* optimal buffer level in packets shifted to Q0 */ + WebRtcSpl_DivW32W16ResW16( + (WebRtc_Word32) NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.packetSpeechLenSamp, /* samples per packet */ + WebRtcSpl_DivW32W16ResW16( (WebRtc_Word32) NetEqMainInst->MCUinst.fs, (WebRtc_Word16) 1000 ) /* samples per ms */ + ) ); + + /* add extra delay */ + if (NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.extraDelayMs > 0) + { + *preferredBufferSize + += NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.extraDelayMs; + } + } + else + { + /* sample rate not initialized */ + *preferredBufferSize = 0; + } + + return (0); + +} + +/* Get the current buffer size in ms. Return value is 0 if ok, -1 if error. */ +int WebRtcNetEQ_GetCurrentDelay(const void *inst, WebRtc_UWord16 *currentDelayMs) +{ + WebRtc_Word32 temp32; + const MainInst_t *NetEqMainInst = (const MainInst_t*) inst; + + /* Instance sanity */ + if (NetEqMainInst == NULL) return (-1); + + /*******************/ + /* Get buffer size */ + /*******************/ + + if (NetEqMainInst->MCUinst.fs != 0 && NetEqMainInst->MCUinst.fs <= WEBRTC_SPL_WORD16_MAX) + { + /* query packet buffer for number of samples */ + temp32 = WebRtcNetEQ_PacketBufferGetSize(&NetEqMainInst->MCUinst.PacketBuffer_inst); + + /* divide by sample rate */ + *currentDelayMs = WebRtcSpl_DivW32W16ResW16(temp32 * 1000, /* multiply by 1000 to get ms */ + (WebRtc_Word16) NetEqMainInst->MCUinst.fs); /* divide by fs in samples per second */ + + /* add number of samples yet to play in sync buffer */ + temp32 = (WebRtc_Word32) (NetEqMainInst->DSPinst.endPosition + - NetEqMainInst->DSPinst.curPosition); + *currentDelayMs += WebRtcSpl_DivW32W16ResW16(temp32 * 1000, /* multiply by 1000 to get ms */ + (WebRtc_Word16) NetEqMainInst->MCUinst.fs); /* divide by fs in samples per second */ + } + else + { + /* sample rate not initialized */ + *currentDelayMs = 0; + } + + return 0; +} + +/* Get the "post-call" jitter statistics from NetEQ. + * The statistics are not reset by the query. Use the function WebRtcNetEQ_ResetJitterStatistics + * to reset the statistics. */ +int WebRtcNetEQ_GetJitterStatistics(void *inst, WebRtcNetEQ_JitterStatistics *jitterStats) +{ + + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + + /* collect statistics not yet transfered to post-call statistics */ + NetEqMainInst->MCUinst.statInst.accelerateMs + += WebRtcSpl_DivU32U16( + WEBRTC_SPL_UMUL_32_16( NetEqMainInst->DSPinst.statInst.accelerateLength, (WebRtc_UWord16) 1000), + NetEqMainInst->MCUinst.fs); + + jitterStats->jbMinSize = NetEqMainInst->MCUinst.statInst.jbMinSize; /* smallest Jitter Buffer size during call - mSec */ + jitterStats->jbMaxSize = NetEqMainInst->MCUinst.statInst.jbMaxSize; /* largest Jitter Buffer size during call - mSec */ + jitterStats->jbAvgSize = NetEqMainInst->MCUinst.statInst.jbAvgSizeQ16 >> 16; /* the average JB size, measured over time - mSec */ + jitterStats->jbChangeCount = NetEqMainInst->MCUinst.statInst.jbChangeCount; /* number of times the Jitter Buffer changed */ + jitterStats->lateLossMs = (NetEqMainInst->MCUinst.PacketBuffer_inst.totalDiscardedPackets + * NetEqMainInst->MCUinst.PacketBuffer_inst.packSizeSamples * 1000) + / NetEqMainInst->MCUinst.fs; /* number of frames received late */ + jitterStats->accelerateMs = NetEqMainInst->MCUinst.statInst.accelerateMs; /* milliseconds removed to reduce jitter buffer size */ + jitterStats->flushedMs = (NetEqMainInst->MCUinst.PacketBuffer_inst.totalFlushedPackets + * NetEqMainInst->MCUinst.PacketBuffer_inst.packSizeSamples * 1000) + / NetEqMainInst->MCUinst.fs; + jitterStats->generatedSilentMs = NetEqMainInst->MCUinst.statInst.generatedSilentMs; /* number of generated silence frames */ + jitterStats->countExpandMoreThan120ms + = NetEqMainInst->MCUinst.statInst.countExpandMoreThan120ms; /* count of tiny BFI events output audio */ + jitterStats->countExpandMoreThan250ms + = NetEqMainInst->MCUinst.statInst.countExpandMoreThan250ms; /* count of small BFI events output audio */ + jitterStats->countExpandMoreThan500ms + = NetEqMainInst->MCUinst.statInst.countExpandMoreThan500ms; /* count of medium BFI events output audio */ + jitterStats->countExpandMoreThan2000ms + = NetEqMainInst->MCUinst.statInst.countExpandMoreThan2000ms; /* count of large BFI events output audio */ + jitterStats->longestExpandDurationMs + = NetEqMainInst->MCUinst.statInst.longestExpandDurationMs; /* mSec duration of longest audio drop-out */ + jitterStats->countIAT500ms + = NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.countIAT500ms; /* count of times we got small network outage */ + jitterStats->countIAT1000ms + = NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.countIAT1000ms; /* count of times we got medium network outage */ + jitterStats->countIAT2000ms + = NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.countIAT2000ms; /* count of times we got large network outage */ + jitterStats->longestIATms + = NetEqMainInst->MCUinst.BufferStat_inst.Automode_inst.longestIATms; /* mSec duration of longest network outage */ + jitterStats->minPacketDelayMs = NetEqMainInst->MCUinst.statInst.minPacketDelayMs; /* min time incoming frame "waited" to be played */ + jitterStats->maxPacketDelayMs = NetEqMainInst->MCUinst.statInst.maxPacketDelayMs; /* max time incoming frame "waited" to be played */ + jitterStats->avgPacketDelayMs = NetEqMainInst->MCUinst.statInst.avgPacketDelayMs; /* avg time incoming frame "waited" to be played */ + + jitterStats->interpolatedVoiceMs + = WebRtcSpl_DivU32U16( + WEBRTC_SPL_UMUL_32_16( NetEqMainInst->DSPinst.statInst.expandedVoiceSamples, (WebRtc_UWord16) 1000), + NetEqMainInst->MCUinst.fs); /* interpolated voice in ms */ + jitterStats->interpolatedSilentMs + = WebRtcSpl_DivU32U16( + WEBRTC_SPL_UMUL_32_16( NetEqMainInst->DSPinst.statInst.expandedNoiseSamples, (WebRtc_UWord16) 1000), + NetEqMainInst->MCUinst.fs); /* interpolated silence in ms */ + + return (0); +} + +/* Reset "post-call" jitter statistics. */ +int WebRtcNetEQ_ResetJitterStatistics(void *inst) +{ + + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + + WebRtcNetEQ_ResetMcuJitterStat(&(NetEqMainInst->MCUinst)); + + WebRtcNetEQ_ClearPostCallStats(&(NetEqMainInst->DSPinst)); + + return (0); +} + +/**************************************************************************** + * WebRtcNetEQ_SetVADInstance(...) + * + * Provide a pointer to an allocated VAD instance. If function is never + * called or it is called with NULL pointer as VAD_inst, the post-decode + * VAD functionality is disabled. Also provide pointers to init, setmode + * and VAD functions. These are typically pointers to WebRtcVad_Init, + * WebRtcVad_set_mode and WebRtcVad_Process, respectively, all found in the + * interface file webrtc_vad.h. + * + * Input: + * - NetEQ_inst : NetEQ instance + * - VADinst : VAD instance + * - initFunction : Pointer to VAD init function + * - setmodeFunction : Pointer to VAD setmode function + * - VADfunction : Pointer to VAD function + * + * Output: + * - NetEQ_inst : Updated NetEQ instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_SetVADInstance(void *NetEQ_inst, void *VAD_inst, + WebRtcNetEQ_VADInitFunction initFunction, + WebRtcNetEQ_VADSetmodeFunction setmodeFunction, + WebRtcNetEQ_VADFunction VADFunction) +{ + + /* Typecast to internal instance type */ + MainInst_t *NetEqMainInst = (MainInst_t*) NetEQ_inst; + if (NetEqMainInst == NULL) + { + return (-1); + } + +#ifdef NETEQ_VAD + + /* Store pointer in PostDecode VAD struct */ + NetEqMainInst->DSPinst.VADInst.VADState = VAD_inst; + + /* Store function pointers */ + NetEqMainInst->DSPinst.VADInst.initFunction = initFunction; + NetEqMainInst->DSPinst.VADInst.setmodeFunction = setmodeFunction; + NetEqMainInst->DSPinst.VADInst.VADFunction = VADFunction; + + /* Call init function and return the result (ok or fail) */ + return(WebRtcNetEQ_InitVAD(&NetEqMainInst->DSPinst.VADInst, NetEqMainInst->DSPinst.fs)); + +#else /* NETEQ_VAD not defined */ + return (-1); +#endif /* NETEQ_VAD */ + +} + +/**************************************************************************** + * WebRtcNetEQ_SetVADMode(...) + * + * Pass an aggressiveness mode parameter to the post-decode VAD instance. + * If this function is never called, mode 0 (quality mode) is used as default. + * + * Input: + * - inst : NetEQ instance + * - mode : mode parameter (same range as WebRtc VAD mode) + * + * Output: + * - inst : Updated NetEQ instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_SetVADMode(void *inst, WebRtc_Word16 mode) +{ + + /* Typecast to internal instance type */ + MainInst_t *NetEqMainInst = (MainInst_t*) inst; + if (NetEqMainInst == NULL) + { + return (-1); + } + +#ifdef NETEQ_VAD + + /* Set mode and return result */ + return(WebRtcNetEQ_SetVADModeInternal(&NetEqMainInst->DSPinst.VADInst, mode)); + +#else /* NETEQ_VAD not defined */ + return (-1); +#endif /* NETEQ_VAD */ + +} diff --git a/src/libs/webrtc/neteq/webrtc_neteq.h b/src/libs/webrtc/neteq/webrtc_neteq.h new file mode 100644 index 00000000..c25b0448 --- /dev/null +++ b/src/libs/webrtc/neteq/webrtc_neteq.h @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This is the main API for NetEQ. Helper macros are located in webrtc_neteq_help_macros.h, + * while some internal API functions are found in webrtc_neteq_internal.h. + */ + +#include "typedefs.h" + +#ifndef WEBRTC_NETEQ_H +#define WEBRTC_NETEQ_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************** + * Definitions + */ + +enum WebRtcNetEQDecoder +{ + kDecoderReservedStart, + kDecoderPCMu, + kDecoderPCMa, + kDecoderILBC, + kDecoderISAC, + kDecoderISACswb, + kDecoderPCM16B, + kDecoderPCM16Bwb, + kDecoderPCM16Bswb32kHz, + kDecoderPCM16Bswb48kHz, + kDecoderG722, + kDecoderRED, + kDecoderAVT, + kDecoderCNG, + kDecoderArbitrary, + kDecoderG729, + kDecoderG729_1, + kDecoderG726_16, + kDecoderG726_24, + kDecoderG726_32, + kDecoderG726_40, + kDecoderG722_1_16, + kDecoderG722_1_24, + kDecoderG722_1_32, + kDecoderG722_1C_24, + kDecoderG722_1C_32, + kDecoderG722_1C_48, + kDecoderSPEEX_8, + kDecoderSPEEX_16, + kDecoderGSMFR, + kDecoderAMR, + kDecoderAMRWB, + kDecoderReservedEnd +}; + +enum WebRtcNetEQNetworkType +{ + kUDPNormal, + kUDPVideoSync, + kTCPNormal, + kTCPLargeJitter, + kTCPXLargeJitter +}; + +enum WebRtcNetEQOutputType +{ + kOutputNormal, + kOutputPLC, + kOutputCNG, + kOutputPLCtoCNG, + kOutputVADPassive +}; + +enum WebRtcNetEQPlayoutMode +{ + kPlayoutOn, kPlayoutOff, kPlayoutFax, kPlayoutStreaming +}; + +/* Available modes for background noise (inserted after long expands) */ +enum WebRtcNetEQBGNMode +{ + kBGNOn, /* default "normal" behavior with eternal noise */ + kBGNFade, /* noise fades to zero after some time */ + kBGNOff +/* background noise is always zero */ +}; + +/************************************************* + * Definitions of decoder calls and the default + * API function calls for each codec + */ + +typedef WebRtc_Word16 (*WebRtcNetEQ_FuncDecode)(void* state, WebRtc_Word16* encoded, + WebRtc_Word16 len, WebRtc_Word16* decoded, + WebRtc_Word16* speechType); +typedef WebRtc_Word16 (*WebRtcNetEQ_FuncDecodePLC)(void* state, WebRtc_Word16* decoded, + WebRtc_Word16 frames); +typedef WebRtc_Word16 (*WebRtcNetEQ_FuncDecodeInit)(void* state); +typedef WebRtc_Word16 (*WebRtcNetEQ_FuncAddLatePkt)(void* state, WebRtc_Word16* encoded, + WebRtc_Word16 len); +typedef WebRtc_Word16 (*WebRtcNetEQ_FuncGetMDinfo)(void* state); +typedef WebRtc_Word16 (*WebRtcNetEQ_FuncGetPitchInfo)(void* state, WebRtc_Word16* encoded, + WebRtc_Word16* length); +typedef WebRtc_Word16 (*WebRtcNetEQ_FuncUpdBWEst)(void* state, const WebRtc_UWord16 *encoded, + WebRtc_Word32 packet_size, + WebRtc_UWord16 rtp_seq_number, + WebRtc_UWord32 send_ts, + WebRtc_UWord32 arr_ts); +typedef WebRtc_Word16 (*WebRtcNetEQ_FuncGetErrorCode)(void* state); + +/********************************************************** + * Structures + */ + +typedef struct +{ + enum WebRtcNetEQDecoder codec; + WebRtc_Word16 payloadType; + WebRtcNetEQ_FuncDecode funcDecode; + WebRtcNetEQ_FuncDecode funcDecodeRCU; + WebRtcNetEQ_FuncDecodePLC funcDecodePLC; + WebRtcNetEQ_FuncDecodeInit funcDecodeInit; + WebRtcNetEQ_FuncAddLatePkt funcAddLatePkt; + WebRtcNetEQ_FuncGetMDinfo funcGetMDinfo; + WebRtcNetEQ_FuncGetPitchInfo funcGetPitch; + WebRtcNetEQ_FuncUpdBWEst funcUpdBWEst; + WebRtcNetEQ_FuncGetErrorCode funcGetErrorCode; + void* codec_state; + WebRtc_UWord16 codec_fs; +} WebRtcNetEQ_CodecDef; + +typedef struct +{ + WebRtc_UWord16 fraction_lost; + WebRtc_UWord32 cum_lost; + WebRtc_UWord32 ext_max; + WebRtc_UWord32 jitter; +} WebRtcNetEQ_RTCPStat; + +/********************************************************** + * NETEQ Functions + */ + +/* Info functions */ + +#define WEBRTC_NETEQ_MAX_ERROR_NAME 40 +int WebRtcNetEQ_GetVersion(WebRtc_Word8 *version); +int WebRtcNetEQ_GetErrorCode(void *inst); +int WebRtcNetEQ_GetErrorName(int errorCode, WebRtc_Word8 *errorName, int maxStrLen); + +/* Instance memory assign functions */ + +int WebRtcNetEQ_AssignSize(int *sizeinbytes); +int WebRtcNetEQ_Assign(void **inst, void *NETEQ_inst_Addr); +int WebRtcNetEQ_GetRecommendedBufferSize(void *inst, enum WebRtcNetEQDecoder *codec, + int noOfCodecs, enum WebRtcNetEQNetworkType nwType, + int *MaxNoOfPackets, int *sizeinbytes); +int WebRtcNetEQ_AssignBuffer(void *inst, int MaxNoOfPackets, void *NETEQ_Buffer_Addr, + int sizeinbytes); + +/* Init functions */ + +int WebRtcNetEQ_Init(void *inst, WebRtc_UWord16 fs); +int WebRtcNetEQ_SetAVTPlayout(void *inst, int PlayoutAVTon); +int WebRtcNetEQ_SetExtraDelay(void *inst, int DelayInMs); +int WebRtcNetEQ_SetPlayoutMode(void *inst, enum WebRtcNetEQPlayoutMode playoutMode); +int WebRtcNetEQ_SetBGNMode(void *inst, enum WebRtcNetEQBGNMode bgnMode); +int WebRtcNetEQ_GetBGNMode(const void *inst, enum WebRtcNetEQBGNMode *bgnMode); + +/* Codec Database functions */ + +int WebRtcNetEQ_CodecDbReset(void *inst); +int WebRtcNetEQ_CodecDbAdd(void *inst, WebRtcNetEQ_CodecDef *codecInst); +int WebRtcNetEQ_CodecDbRemove(void *inst, enum WebRtcNetEQDecoder codec); +int WebRtcNetEQ_CodecDbGetSizeInfo(void *inst, WebRtc_Word16 *UsedEntries, + WebRtc_Word16 *MaxEntries); +int WebRtcNetEQ_CodecDbGetCodecInfo(void *inst, WebRtc_Word16 Entry, + enum WebRtcNetEQDecoder *codec); + +/* Real-time functions */ + +int WebRtcNetEQ_RecIn(void *inst, WebRtc_Word16 *p_w16datagramstart, WebRtc_Word16 w16_RTPlen, + WebRtc_UWord32 uw32_timeRec); +int WebRtcNetEQ_RecOut(void *inst, WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_len); +int WebRtcNetEQ_GetRTCPStats(void *inst, WebRtcNetEQ_RTCPStat *RTCP_inst); +int WebRtcNetEQ_GetRTCPStatsNoReset(void *inst, WebRtcNetEQ_RTCPStat *RTCP_inst); +int WebRtcNetEQ_GetSpeechTimeStamp(void *inst, WebRtc_UWord32 *timestamp); +int WebRtcNetEQ_GetSpeechOutputType(void *inst, enum WebRtcNetEQOutputType *outputType); + +/* VQmon related functions */ +int WebRtcNetEQ_VQmonRecOutStatistics(void *inst, WebRtc_UWord16 *validVoiceDurationMs, + WebRtc_UWord16 *concealedVoiceDurationMs, + WebRtc_UWord8 *concealedVoiceFlags); +int WebRtcNetEQ_VQmonGetConfiguration(void *inst, WebRtc_UWord16 *absMaxDelayMs, + WebRtc_UWord8 *adaptationRate); +int WebRtcNetEQ_VQmonGetRxStatistics(void *inst, WebRtc_UWord16 *avgDelayMs, + WebRtc_UWord16 *maxDelayMs); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/libs/webrtc/neteq/webrtc_neteq_help_macros.h b/src/libs/webrtc/neteq/webrtc_neteq_help_macros.h new file mode 100644 index 00000000..c63b3464 --- /dev/null +++ b/src/libs/webrtc/neteq/webrtc_neteq_help_macros.h @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains some helper macros that can be used when loading the + * NetEQ codec database. + */ + +#ifndef WEBRTC_NETEQ_HELP_MACROS_H +#define WEBRTC_NETEQ_HELP_MACROS_H + +#ifndef NULL +#define NULL 0 +#endif + +/********************************************************** + * Help macros for NetEQ initialization + */ + +#define SET_CODEC_PAR(inst,decoder,pt,state,fs) \ + inst.codec=decoder; \ + inst.payloadType=pt; \ + inst.codec_state=state; \ + inst.codec_fs=fs; + +#define SET_PCMU_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG711_DecodeU; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=NULL; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_PCMA_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG711_DecodeA; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=NULL; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_ILBC_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcIlbcfix_Decode; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=(WebRtcNetEQ_FuncDecodePLC)WebRtcIlbcfix_NetEqPlc; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcIlbcfix_Decoderinit30Ms; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_ISAC_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcIsac_Decode; \ + inst.funcDecodeRCU=(WebRtcNetEQ_FuncDecode)WebRtcIsac_DecodeRcu; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcIsac_DecoderInit; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=(WebRtcNetEQ_FuncUpdBWEst)WebRtcIsac_UpdateBwEstimate; \ + inst.funcGetErrorCode=(WebRtcNetEQ_FuncGetErrorCode)WebRtcIsac_GetErrorCode; + +#define SET_ISACfix_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcIsacfix_Decode; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcIsacfix_DecoderInit; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=(WebRtcNetEQ_FuncUpdBWEst)WebRtcIsacfix_UpdateBwEstimate; \ + inst.funcGetErrorCode=(WebRtcNetEQ_FuncGetErrorCode)WebRtcIsacfix_GetErrorCode; + +#define SET_ISACSWB_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcIsac_Decode; \ + inst.funcDecodeRCU=(WebRtcNetEQ_FuncDecode)WebRtcIsac_DecodeRcu; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcIsac_DecoderInit; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=(WebRtcNetEQ_FuncUpdBWEst)WebRtcIsac_UpdateBwEstimate; \ + inst.funcGetErrorCode=(WebRtcNetEQ_FuncGetErrorCode)WebRtcIsac_GetErrorCode; + +#define SET_G729_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG729_Decode; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=(WebRtcNetEQ_FuncDecodePLC)WebRtcG729_DecodePlc; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG729_DecoderInit; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_G729_1_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG7291_Decode; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG7291_DecoderInit; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=(WebRtcNetEQ_FuncUpdBWEst)WebRtcG7291_DecodeBwe; \ + inst.funcGetErrorCode=NULL; + +#define SET_PCM16B_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcPcm16b_DecodeW16; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=NULL; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_PCM16B_WB_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcPcm16b_DecodeW16; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=NULL; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_PCM16B_SWB32_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcPcm16b_DecodeW16; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=NULL; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + + +#define SET_PCM16B_SWB48_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcPcm16b_DecodeW16; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=NULL; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_G722_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG722_Decode; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG722_DecoderInit;\ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_G722_1_16_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG7221_Decode16; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=(WebRtcNetEQ_FuncDecodePLC)WebRtcG7221_DecodePlc16; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG7221_DecoderInit16; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_G722_1_24_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG7221_Decode24; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=(WebRtcNetEQ_FuncDecodePLC)WebRtcG7221_DecodePlc24; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG7221_DecoderInit24; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_G722_1_32_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG7221_Decode32; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=(WebRtcNetEQ_FuncDecodePLC)WebRtcG7221_DecodePlc32; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG7221_DecoderInit32; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_G722_1C_24_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG7221C_Decode24; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=(WebRtcNetEQ_FuncDecodePLC)WebRtcG7221C_DecodePlc24; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG7221C_DecoderInit24; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_G722_1C_32_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG7221C_Decode32; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=(WebRtcNetEQ_FuncDecodePLC)WebRtcG7221C_DecodePlc32; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG7221C_DecoderInit32; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_G722_1C_48_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG7221C_Decode48; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=(WebRtcNetEQ_FuncDecodePLC)WebRtcG7221C_DecodePlc48; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG7221C_DecoderInit48; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_AMR_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcAmr_Decode; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=(WebRtcNetEQ_FuncDecodePLC)WebRtcAmr_DecodePlc; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcAmr_DecoderInit; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_AMRWB_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcAmrWb_Decode; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=(WebRtcNetEQ_FuncDecodePLC)WebRtcAmrWb_DecodePlc; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcAmrWb_DecoderInit; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_GSMFR_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcGSMFR_Decode; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=(WebRtcNetEQ_FuncDecodePLC)WebRtcGSMFR_DecodePlc; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcGSMFR_DecoderInit; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_G726_16_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG726_decode16; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG726_decoderinit16; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_G726_24_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG726_decode24; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG726_decoderinit24; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_G726_32_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG726_decode32; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG726_decoderinit32; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_G726_40_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG726_decode40; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcG726_decoderinit40; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_SPEEX_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcSpeex_Decode; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=(WebRtcNetEQ_FuncDecodePLC)WebRtcSpeex_DecodePlc; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcSpeex_DecoderInit; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_RED_FUNCTIONS(inst) \ + inst.funcDecode=NULL; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=NULL; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_AVT_FUNCTIONS(inst) \ + inst.funcDecode=NULL; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=NULL; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#define SET_CNG_FUNCTIONS(inst) \ + inst.funcDecode=NULL; \ + inst.funcDecodeRCU=NULL; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=NULL; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=NULL; \ + inst.funcGetErrorCode=NULL; + +#endif /* WEBRTC_NETEQ_HELP_MACROS_H */ + diff --git a/src/libs/webrtc/neteq/webrtc_neteq_internal.h b/src/libs/webrtc/neteq/webrtc_neteq_internal.h new file mode 100644 index 00000000..a00cd961 --- /dev/null +++ b/src/libs/webrtc/neteq/webrtc_neteq_internal.h @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the internal API functions. + */ + +#include "typedefs.h" + +#ifndef WEBRTC_NETEQ_INTERNAL_H +#define WEBRTC_NETEQ_INTERNAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct +{ + WebRtc_UWord8 payloadType; + WebRtc_UWord16 sequenceNumber; + WebRtc_UWord32 timeStamp; + WebRtc_UWord32 SSRC; + WebRtc_UWord8 markerBit; +} WebRtcNetEQ_RTPInfo; + +/**************************************************************************** + * WebRtcNetEQ_RecInRTPStruct(...) + * + * Alternative RecIn function, used when the RTP data has already been + * parsed into an RTP info struct (WebRtcNetEQ_RTPInfo). + * + * Input: + * - inst : NetEQ instance + * - rtpInfo : Pointer to RTP info + * - payloadPtr : Pointer to the RTP payload (first byte after header) + * - payloadLenBytes : Length (in bytes) of the payload in payloadPtr + * - timeRec : Receive time (in timestamps of the used codec) + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNetEQ_RecInRTPStruct(void *inst, WebRtcNetEQ_RTPInfo *rtpInfo, + const WebRtc_UWord8 *payloadPtr, WebRtc_Word16 payloadLenBytes, + WebRtc_UWord32 timeRec); + +/**************************************************************************** + * WebRtcNetEQ_GetMasterSlaveInfoSize(...) + * + * Get size in bytes for master/slave struct msInfo used in + * WebRtcNetEQ_RecOutMasterSlave. + * + * Return value : Struct size in bytes + * + */ + +int WebRtcNetEQ_GetMasterSlaveInfoSize(); + +/**************************************************************************** + * WebRtcNetEQ_RecOutMasterSlave(...) + * + * RecOut function for running several NetEQ instances in master/slave mode. + * One master can be used to control several slaves. + * The MasterSlaveInfo struct must be allocated outside NetEQ. + * Use function WebRtcNetEQ_GetMasterSlaveInfoSize to get the size needed. + * + * Input: + * - inst : NetEQ instance + * - isMaster : Non-zero indicates that this is the master channel + * - msInfo : (slave only) Information from master + * + * Output: + * - inst : Updated NetEQ instance + * - pw16_outData : Pointer to vector where output should be written + * - pw16_len : Pointer to variable where output length is returned + * - msInfo : (master only) Information to slave(s) + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_RecOutMasterSlave(void *inst, WebRtc_Word16 *pw16_outData, + WebRtc_Word16 *pw16_len, void *msInfo, + WebRtc_Word16 isMaster); + +typedef struct +{ + WebRtc_UWord16 currentBufferSize; /* current jitter buffer size in ms */ + WebRtc_UWord16 preferredBufferSize; /* preferred (optimal) buffer size in ms */ + WebRtc_UWord16 currentPacketLossRate; /* loss rate (network + late) (in Q14) */ + WebRtc_UWord16 currentDiscardRate; /* late loss rate (in Q14) */ + WebRtc_UWord16 currentExpandRate; /* fraction (of original stream) of synthesized speech + * inserted through expansion (in Q14) */ + WebRtc_UWord16 currentPreemptiveRate; /* fraction of synthesized speech inserted through + * pre-emptive expansion (in Q14) */ + WebRtc_UWord16 currentAccelerateRate; /* fraction of data removed through acceleration + * (in Q14) */ +} WebRtcNetEQ_NetworkStatistics; + +typedef struct +{ + WebRtc_UWord32 jbMinSize; /* smallest Jitter Buffer size during call in ms */ + WebRtc_UWord32 jbMaxSize; /* largest Jitter Buffer size during call in ms */ + WebRtc_UWord32 jbAvgSize; /* the average JB size, measured over time - ms */ + WebRtc_UWord32 jbChangeCount; /* number of times the Jitter Buffer changed + * (using Accelerate or Pre-emptive Expand) */ + WebRtc_UWord32 lateLossMs; /* amount (in ms) of audio data received late */ + WebRtc_UWord32 accelerateMs; /* milliseconds removed to reduce jitter buffer size */ + WebRtc_UWord32 flushedMs; /* milliseconds discarded through buffer flushing */ + WebRtc_UWord32 generatedSilentMs; /* milliseconds of generated silence */ + WebRtc_UWord32 interpolatedVoiceMs; /* milliseconds of synthetic audio data + * (non-background noise) */ + WebRtc_UWord32 interpolatedSilentMs; /* milliseconds of synthetic audio data + * (background noise level) */ + WebRtc_UWord32 countExpandMoreThan120ms; /* count of tiny expansions in output audio */ + WebRtc_UWord32 countExpandMoreThan250ms; /* count of small expansions in output audio */ + WebRtc_UWord32 countExpandMoreThan500ms; /* count of medium expansions in output audio */ + WebRtc_UWord32 countExpandMoreThan2000ms; /* count of long expansions in output audio */ + WebRtc_UWord32 longestExpandDurationMs; /* duration of longest audio drop-out */ + WebRtc_UWord32 countIAT500ms; /* count of times we got small network outage (inter-arrival + * time in [500, 1000) ms) */ + WebRtc_UWord32 countIAT1000ms; /* count of times we got medium network outage + * (inter-arrival time in [1000, 2000) ms) */ + WebRtc_UWord32 countIAT2000ms; /* count of times we got large network outage + * (inter-arrival time >= 2000 ms) */ + WebRtc_UWord32 longestIATms; /* longest packet inter-arrival time in ms */ + WebRtc_UWord32 minPacketDelayMs; /* min time incoming Packet "waited" to be played */ + WebRtc_UWord32 maxPacketDelayMs; /* max time incoming Packet "waited" to be played */ + WebRtc_UWord32 avgPacketDelayMs; /* avg time incoming Packet "waited" to be played */ +} WebRtcNetEQ_JitterStatistics; + +/* + * Get the "in-call" statistics from NetEQ. + * The statistics are reset after the query. + */ +int WebRtcNetEQ_GetNetworkStatistics(void *inst, WebRtcNetEQ_NetworkStatistics *stats); + +/* + * Get the optimal buffer size calculated for the current network conditions. + */ +int WebRtcNetEQ_GetPreferredBufferSize(void *inst, WebRtc_UWord16 *preferredBufferSize); + +/* + * Get the current buffer size in ms. Return value is 0 if ok, -1 if error. + */ +int WebRtcNetEQ_GetCurrentDelay(const void *inst, WebRtc_UWord16 *currentDelayMs); + +/* + * Get the "post-call" jitter statistics from NetEQ. + * The statistics are not reset by the query. Use the function + * WebRtcNetEQ_ResetJitterStatistics to reset the statistics. + */ +int WebRtcNetEQ_GetJitterStatistics(void *inst, WebRtcNetEQ_JitterStatistics *jitterStats); + +/* + * Reset "post-call" jitter statistics. + */ +int WebRtcNetEQ_ResetJitterStatistics(void *inst); + +/***********************************************/ +/* Functions for post-decode VAD functionality */ +/***********************************************/ + +/* NetEQ must be compiled with the flag NETEQ_VAD enabled for these functions to work. */ + +/* + * VAD function pointer types + * + * These function pointers match the definitions of webrtc VAD functions WebRtcVad_Init, + * WebRtcVad_set_mode and WebRtcVad_Process, respectively, all found in webrtc_vad.h. + */ +typedef WebRtc_Word16 (*WebRtcNetEQ_VADInitFunction)(void *VAD_inst); +typedef WebRtc_Word16 (*WebRtcNetEQ_VADSetmodeFunction)(void *VAD_inst, WebRtc_Word16 mode); +typedef WebRtc_Word16 (*WebRtcNetEQ_VADFunction)(void *VAD_inst, WebRtc_Word16 fs, + WebRtc_Word16 *frame, WebRtc_Word16 frameLen); + +/**************************************************************************** + * WebRtcNetEQ_SetVADInstance(...) + * + * Provide a pointer to an allocated VAD instance. If function is never + * called or it is called with NULL pointer as VAD_inst, the post-decode + * VAD functionality is disabled. Also provide pointers to init, setmode + * and VAD functions. These are typically pointers to WebRtcVad_Init, + * WebRtcVad_set_mode and WebRtcVad_Process, respectively, all found in the + * interface file webrtc_vad.h. + * + * Input: + * - NetEQ_inst : NetEQ instance + * - VADinst : VAD instance + * - initFunction : Pointer to VAD init function + * - setmodeFunction : Pointer to VAD setmode function + * - VADfunction : Pointer to VAD function + * + * Output: + * - NetEQ_inst : Updated NetEQ instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_SetVADInstance(void *NetEQ_inst, void *VAD_inst, + WebRtcNetEQ_VADInitFunction initFunction, + WebRtcNetEQ_VADSetmodeFunction setmodeFunction, + WebRtcNetEQ_VADFunction VADFunction); + +/**************************************************************************** + * WebRtcNetEQ_SetVADMode(...) + * + * Pass an aggressiveness mode parameter to the post-decode VAD instance. + * If this function is never called, mode 0 (quality mode) is used as default. + * + * Input: + * - inst : NetEQ instance + * - mode : mode parameter (same range as WebRtc VAD mode) + * + * Output: + * - inst : Updated NetEQ instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_SetVADMode(void *NetEQ_inst, WebRtc_Word16 mode); + +/**************************************************************************** + * WebRtcNetEQ_RecOutNoDecode(...) + * + * Special RecOut that does not do any decoding. + * + * Input: + * - inst : NetEQ instance + * + * Output: + * - inst : Updated NetEQ instance + * - pw16_outData : Pointer to vector where output should be written + * - pw16_len : Pointer to variable where output length is returned + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_RecOutNoDecode(void *inst, WebRtc_Word16 *pw16_outData, + WebRtc_Word16 *pw16_len); + +/**************************************************************************** + * WebRtcNetEQ_FlushBuffers(...) + * + * Flush packet and speech buffers. Does not reset codec database or + * jitter statistics. + * + * Input: + * - inst : NetEQ instance + * + * Output: + * - inst : Updated NetEQ instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcNetEQ_FlushBuffers(void *inst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/webrtc/ns/defines.h b/src/libs/webrtc/ns/defines.h new file mode 100644 index 00000000..d2539679 --- /dev/null +++ b/src/libs/webrtc/ns/defines.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_ + +//#define PROCESS_FLOW_0 // Use the traditional method. +//#define PROCESS_FLOW_1 // Use traditional with DD estimate of prior SNR. +#define PROCESS_FLOW_2 // Use the new method of speech/noise classification. + +#define BLOCKL_MAX 160 // max processing block length: 160 +#define ANAL_BLOCKL_MAX 256 // max analysis block length: 256 +#define HALF_ANAL_BLOCKL 129 // half max analysis block length + 1 + +#define QUANTILE (float)0.25 + +#define SIMULT 3 +#define END_STARTUP_LONG 200 +#define END_STARTUP_SHORT 50 +#define FACTOR (float)40.0 +#define WIDTH (float)0.01 + +#define SMOOTH (float)0.75 // filter smoothing +// Length of fft work arrays. +#define IP_LENGTH (ANAL_BLOCKL_MAX >> 1) // must be at least ceil(2 + sqrt(ANAL_BLOCKL_MAX/2)) +#define W_LENGTH (ANAL_BLOCKL_MAX >> 1) + +//PARAMETERS FOR NEW METHOD +#define DD_PR_SNR (float)0.98 // DD update of prior SNR +#define LRT_TAVG (float)0.50 // tavg parameter for LRT (previously 0.90) +#define SPECT_FL_TAVG (float)0.30 // tavg parameter for spectral flatness measure +#define SPECT_DIFF_TAVG (float)0.30 // tavg parameter for spectral difference measure +#define PRIOR_UPDATE (float)0.10 // update parameter of prior model +#define NOISE_UPDATE (float)0.90 // update parameter for noise +#define SPEECH_UPDATE (float)0.99 // update parameter when likely speech +#define WIDTH_PR_MAP (float)4.0 // width parameter in sigmoid map for prior model +#define LRT_FEATURE_THR (float)0.5 // default threshold for LRT feature +#define SF_FEATURE_THR (float)0.5 // default threshold for Spectral Flatness feature +#define SD_FEATURE_THR (float)0.5 // default threshold for Spectral Difference feature +#define PROB_RANGE (float)0.20 // probability threshold for noise state in + // speech/noise likelihood +#define HIST_PAR_EST 1000 // histogram size for estimation of parameters +#define GAMMA_PAUSE (float)0.05 // update for conservative noise estimate +// +#define B_LIM (float)0.5 // threshold in final energy gain factor calculation +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_DEFINES_H_ diff --git a/src/libs/webrtc/ns/noise_suppression.c b/src/libs/webrtc/ns/noise_suppression.c new file mode 100644 index 00000000..aed10b14 --- /dev/null +++ b/src/libs/webrtc/ns/noise_suppression.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <stdlib.h> +#include <string.h> + +#include "noise_suppression.h" +#include "ns_core.h" +#include "defines.h" + +int WebRtcNs_get_version(char *versionStr, short length) +{ + const char version[] = "NS 2.2.0"; + const short versionLen = (short)strlen(version) + 1; // +1 for null-termination + + if (versionStr == NULL) { + return -1; + } + + if (versionLen > length) { + return -1; + } + + strncpy(versionStr, version, versionLen); + + return 0; +} + +int WebRtcNs_Create(NsHandle **NS_inst) +{ + *NS_inst = (NsHandle*) malloc(sizeof(NSinst_t)); + if (*NS_inst!=NULL) { + (*(NSinst_t**)NS_inst)->initFlag=0; + return 0; + } else { + return -1; + } + +} + +int WebRtcNs_Free(NsHandle *NS_inst) +{ + free(NS_inst); + return 0; +} + + +int WebRtcNs_Init(NsHandle *NS_inst, WebRtc_UWord32 fs) +{ + return WebRtcNs_InitCore((NSinst_t*) NS_inst, fs); +} + +int WebRtcNs_set_policy(NsHandle *NS_inst, int mode) +{ + return WebRtcNs_set_policy_core((NSinst_t*) NS_inst, mode); +} + + +int WebRtcNs_Process(NsHandle *NS_inst, short *spframe, short *spframe_H, short *outframe, short *outframe_H) +{ + return WebRtcNs_ProcessCore((NSinst_t*) NS_inst, spframe, spframe_H, outframe, outframe_H); +} diff --git a/src/libs/webrtc/ns/noise_suppression.h b/src/libs/webrtc/ns/noise_suppression.h new file mode 100644 index 00000000..b8983b07 --- /dev/null +++ b/src/libs/webrtc/ns/noise_suppression.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_INTERFACE_NOISE_SUPPRESSION_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_INTERFACE_NOISE_SUPPRESSION_H_ + +#include "typedefs.h" + +typedef struct NsHandleT NsHandle; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This function returns the version number of the code. + * + * Input: + * - version : Pointer to a character array where the version + * info is stored. + * - length : Length of version. + * + * Return value : 0 - Ok + * -1 - Error (probably length is not sufficient) + */ +int WebRtcNs_get_version(char *version, short length); + + +/* + * This function creates an instance to the noise reduction structure + * + * Input: + * - NS_inst : Pointer to noise reduction instance that should be + * created + * + * Output: + * - NS_inst : Pointer to created noise reduction instance + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNs_Create(NsHandle **NS_inst); + + +/* + * This function frees the dynamic memory of a specified Noise Reduction + * instance. + * + * Input: + * - NS_inst : Pointer to NS instance that should be freed + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNs_Free(NsHandle *NS_inst); + + +/* + * This function initializes a NS instance + * + * Input: + * - NS_inst : Instance that should be initialized + * - fs : sampling frequency + * + * Output: + * - NS_inst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNs_Init(NsHandle *NS_inst, WebRtc_UWord32 fs); + +/* + * This changes the aggressiveness of the noise suppression method. + * + * Input: + * - NS_inst : Instance that should be initialized + * - mode : 0: Mild, 1: Medium , 2: Aggressive + * + * Output: + * - NS_inst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNs_set_policy(NsHandle *NS_inst, int mode); + + +/* + * This functions does Noise Suppression for the inserted speech frame. The + * input and output signals should always be 10ms (80 or 160 samples). + * + * Input + * - NS_inst : VAD Instance. Needs to be initiated before call. + * - spframe : Pointer to speech frame buffer for L band + * - spframe_H : Pointer to speech frame buffer for H band + * - fs : sampling frequency + * + * Output: + * - NS_inst : Updated NS instance + * - outframe : Pointer to output frame for L band + * - outframe_H : Pointer to output frame for H band + * + * Return value : 0 - OK + * -1 - Error + */ +int WebRtcNs_Process(NsHandle *NS_inst, + short *spframe, + short *spframe_H, + short *outframe, + short *outframe_H); + +#ifdef __cplusplus +} +#endif + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_INTERFACE_NOISE_SUPPRESSION_H_ diff --git a/src/libs/webrtc/ns/noise_suppression_x.c b/src/libs/webrtc/ns/noise_suppression_x.c new file mode 100644 index 00000000..f1ad7306 --- /dev/null +++ b/src/libs/webrtc/ns/noise_suppression_x.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <stdlib.h> +#include <string.h> + +#include "noise_suppression_x.h" +#include "nsx_core.h" +#include "nsx_defines.h" + +int WebRtcNsx_get_version(char *versionStr, short length) +{ + const char version[] = "NS\t3.1.0"; + const short versionLen = (short)strlen(version) + 1; // +1 for null-termination + + if (versionStr == NULL) + { + return -1; + } + + if (versionLen > length) + { + return -1; + } + + strncpy(versionStr, version, versionLen); + + return 0; +} + +int WebRtcNsx_Create(NsxHandle **nsxInst) +{ + *nsxInst = (NsxHandle*)malloc(sizeof(NsxInst_t)); + if (*nsxInst != NULL) + { + (*(NsxInst_t**)nsxInst)->initFlag = 0; + return 0; + } else + { + return -1; + } + +} + +int WebRtcNsx_Free(NsxHandle *nsxInst) +{ + free(nsxInst); + return 0; +} + +int WebRtcNsx_Init(NsxHandle *nsxInst, WebRtc_UWord32 fs) +{ + return WebRtcNsx_InitCore((NsxInst_t*)nsxInst, fs); +} + +int WebRtcNsx_set_policy(NsxHandle *nsxInst, int mode) +{ + return WebRtcNsx_set_policy_core((NsxInst_t*)nsxInst, mode); +} + +int WebRtcNsx_Process(NsxHandle *nsxInst, short *speechFrame, short *speechFrameHB, + short *outFrame, short *outFrameHB) +{ + return WebRtcNsx_ProcessCore((NsxInst_t*)nsxInst, speechFrame, speechFrameHB, outFrame, + outFrameHB); +} + diff --git a/src/libs/webrtc/ns/noise_suppression_x.h b/src/libs/webrtc/ns/noise_suppression_x.h new file mode 100644 index 00000000..2543bfd3 --- /dev/null +++ b/src/libs/webrtc/ns/noise_suppression_x.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_INTERFACE_NOISE_SUPPRESSION_X_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_INTERFACE_NOISE_SUPPRESSION_X_H_ + +#include "signal_processing_library/signal_processing_library.h" + +typedef struct NsxHandleT NsxHandle; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This function returns the version number of the code. + * + * Input: + * - version : Pointer to a character array where the version + * info is stored. + * - length : Length of version. + * + * Return value : 0 - Ok + * -1 - Error (probably length is not sufficient) + */ +int WebRtcNsx_get_version(char *version, short length); + + +/* + * This function creates an instance to the noise reduction structure + * + * Input: + * - nsxInst : Pointer to noise reduction instance that should be + * created + * + * Output: + * - nsxInst : Pointer to created noise reduction instance + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNsx_Create(NsxHandle **nsxInst); + + +/* + * This function frees the dynamic memory of a specified Noise Suppression + * instance. + * + * Input: + * - nsxInst : Pointer to NS instance that should be freed + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNsx_Free(NsxHandle *nsxInst); + + +/* + * This function initializes a NS instance + * + * Input: + * - nsxInst : Instance that should be initialized + * - fs : sampling frequency + * + * Output: + * - nsxInst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNsx_Init(NsxHandle *nsxInst, WebRtc_UWord32 fs); + +/* + * This changes the aggressiveness of the noise suppression method. + * + * Input: + * - nsxInst : Instance that should be initialized + * - mode : 0: Mild, 1: Medium , 2: Aggressive + * + * Output: + * - nsxInst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNsx_set_policy(NsxHandle *nsxInst, int mode); + +/* + * This functions does noise suppression for the inserted speech frame. The + * input and output signals should always be 10ms (80 or 160 samples). + * + * Input + * - nsxInst : NSx instance. Needs to be initiated before call. + * - speechFrame : Pointer to speech frame buffer for L band + * - speechFrameHB : Pointer to speech frame buffer for H band + * - fs : sampling frequency + * + * Output: + * - nsxInst : Updated NSx instance + * - outFrame : Pointer to output frame for L band + * - outFrameHB : Pointer to output frame for H band + * + * Return value : 0 - OK + * -1 - Error + */ +int WebRtcNsx_Process(NsxHandle *nsxInst, + short *speechFrame, + short *speechFrameHB, + short *outFrame, + short *outFrameHB); + +#ifdef __cplusplus +} +#endif + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_INTERFACE_NOISE_SUPPRESSION_X_H_ diff --git a/src/libs/webrtc/ns/ns_core.c b/src/libs/webrtc/ns/ns_core.c new file mode 100644 index 00000000..20425e74 --- /dev/null +++ b/src/libs/webrtc/ns/ns_core.c @@ -0,0 +1,1500 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <string.h> +#include <math.h> +//#include <stdio.h> +#include <stdlib.h> +#include "noise_suppression.h" +#include "ns_core.h" +#include "windows_private.h" +#include "fft4g.h" +#include "signal_processing_library.h" + +// Set Feature Extraction Parameters +void WebRtcNs_set_feature_extraction_parameters(NSinst_t *inst) +{ + //bin size of histogram + inst->featureExtractionParams.binSizeLrt = (float)0.1; + inst->featureExtractionParams.binSizeSpecFlat = (float)0.05; + inst->featureExtractionParams.binSizeSpecDiff = (float)0.1; + + //range of histogram over which lrt threshold is computed + inst->featureExtractionParams.rangeAvgHistLrt = (float)1.0; + + //scale parameters: multiply dominant peaks of the histograms by scale factor to obtain + // thresholds for prior model + inst->featureExtractionParams.factor1ModelPars = (float)1.20; //for lrt and spectral diff + inst->featureExtractionParams.factor2ModelPars = (float)0.9; //for spectral_flatness: + // used when noise is flatter than speech + + //peak limit for spectral flatness (varies between 0 and 1) + inst->featureExtractionParams.thresPosSpecFlat = (float)0.6; + + //limit on spacing of two highest peaks in histogram: spacing determined by bin size + inst->featureExtractionParams.limitPeakSpacingSpecFlat = 2 + * inst->featureExtractionParams.binSizeSpecFlat; + inst->featureExtractionParams.limitPeakSpacingSpecDiff = 2 + * inst->featureExtractionParams.binSizeSpecDiff; + + //limit on relevance of second peak: + inst->featureExtractionParams.limitPeakWeightsSpecFlat = (float)0.5; + inst->featureExtractionParams.limitPeakWeightsSpecDiff = (float)0.5; + + // fluctuation limit of lrt feature + inst->featureExtractionParams.thresFluctLrt = (float)0.05; + + //limit on the max and min values for the feature thresholds + inst->featureExtractionParams.maxLrt = (float)1.0; + inst->featureExtractionParams.minLrt = (float)0.20; + + inst->featureExtractionParams.maxSpecFlat = (float)0.95; + inst->featureExtractionParams.minSpecFlat = (float)0.10; + + inst->featureExtractionParams.maxSpecDiff = (float)1.0; + inst->featureExtractionParams.minSpecDiff = (float)0.16; + + //criteria of weight of histogram peak to accept/reject feature + inst->featureExtractionParams.thresWeightSpecFlat = (int)(0.3 + * (inst->modelUpdatePars[1])); //for spectral flatness + inst->featureExtractionParams.thresWeightSpecDiff = (int)(0.3 + * (inst->modelUpdatePars[1])); //for spectral difference +} + +// Initialize state +int WebRtcNs_InitCore(NSinst_t *inst, WebRtc_UWord32 fs) +{ + int i; + //We only support 10ms frames + + //check for valid pointer + if (inst == NULL) + { + return -1; + } + + // Initialization of struct + if (fs == 8000 || fs == 16000 || fs == 32000) + { + inst->fs = fs; + } + else + { + return -1; + } + inst->windShift = 0; + if (fs == 8000) + { + // We only support 10ms frames + inst->blockLen = 80; + inst->blockLen10ms = 80; + inst->anaLen = 128; + inst->window = kBlocks80w128; + inst->outLen = 0; + } + else if (fs == 16000) + { + // We only support 10ms frames + inst->blockLen = 160; + inst->blockLen10ms = 160; + inst->anaLen = 256; + inst->window = kBlocks160w256; + inst->outLen = 0; + } + else if (fs==32000) + { + // We only support 10ms frames + inst->blockLen = 160; + inst->blockLen10ms = 160; + inst->anaLen = 256; + inst->window = kBlocks160w256; + inst->outLen = 0; + } + inst->magnLen = inst->anaLen / 2 + 1; // Number of frequency bins + + // Initialize fft work arrays. + inst->ip[0] = 0; // Setting this triggers initialization. + memset(inst->dataBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX); + rdft(inst->anaLen, 1, inst->dataBuf, inst->ip, inst->wfft); + + memset(inst->dataBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX); + memset(inst->syntBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX); + + //for HB processing + memset(inst->dataBufHB, 0, sizeof(float) * ANAL_BLOCKL_MAX); + + //for quantile noise estimation + memset(inst->quantile, 0, sizeof(float) * HALF_ANAL_BLOCKL); + for (i = 0; i < SIMULT * HALF_ANAL_BLOCKL; i++) + { + inst->lquantile[i] = (float)8.0; + inst->density[i] = (float)0.3; + } + + for (i = 0; i < SIMULT; i++) + { + inst->counter[i] = (int)floor((float)(END_STARTUP_LONG * (i + 1)) / (float)SIMULT); + } + + inst->updates = 0; + + // Wiener filter initialization + for (i = 0; i < HALF_ANAL_BLOCKL; i++) + { + inst->smooth[i] = (float)1.0; + } + + // Set the aggressiveness: default + inst->aggrMode = 0; + + //initialize variables for new method + inst->priorSpeechProb = (float)0.5; //prior prob for speech/noise + for (i = 0; i < HALF_ANAL_BLOCKL; i++) + { + inst->magnPrev[i] = (float)0.0; //previous mag spectrum + inst->noisePrev[i] = (float)0.0; //previous noise-spectrum + inst->logLrtTimeAvg[i] = LRT_FEATURE_THR; //smooth LR ratio (same as threshold) + inst->magnAvgPause[i] = (float)0.0; //conservative noise spectrum estimate + inst->speechProbHB[i] = (float)0.0; //for estimation of HB in second pass + inst->initMagnEst[i] = (float)0.0; //initial average mag spectrum + } + + //feature quantities + inst->featureData[0] = SF_FEATURE_THR; //spectral flatness (start on threshold) + inst->featureData[1] = (float)0.0; //spectral entropy: not used in this version + inst->featureData[2] = (float)0.0; //spectral variance: not used in this version + inst->featureData[3] = LRT_FEATURE_THR; //average lrt factor (start on threshold) + inst->featureData[4] = SF_FEATURE_THR; //spectral template diff (start on threshold) + inst->featureData[5] = (float)0.0; //normalization for spectral-diff + inst->featureData[6] = (float)0.0; //window time-average of input magnitude spectrum + + //histogram quantities: used to estimate/update thresholds for features + for (i = 0; i < HIST_PAR_EST; i++) + { + inst->histLrt[i] = 0; + inst->histSpecFlat[i] = 0; + inst->histSpecDiff[i] = 0; + } + + inst->blockInd = -1; //frame counter + inst->priorModelPars[0] = LRT_FEATURE_THR; //default threshold for lrt feature + inst->priorModelPars[1] = (float)0.5; //threshold for spectral flatness: + // determined on-line + inst->priorModelPars[2] = (float)1.0; //sgn_map par for spectral measure: + // 1 for flatness measure + inst->priorModelPars[3] = (float)0.5; //threshold for template-difference feature: + // determined on-line + inst->priorModelPars[4] = (float)1.0; //default weighting parameter for lrt feature + inst->priorModelPars[5] = (float)0.0; //default weighting parameter for + // spectral flatness feature + inst->priorModelPars[6] = (float)0.0; //default weighting parameter for + // spectral difference feature + + inst->modelUpdatePars[0] = 2; //update flag for parameters: + // 0 no update, 1=update once, 2=update every window + inst->modelUpdatePars[1] = 500; //window for update + inst->modelUpdatePars[2] = 0; //counter for update of conservative noise spectrum + //counter if the feature thresholds are updated during the sequence + inst->modelUpdatePars[3] = inst->modelUpdatePars[1]; + + inst->signalEnergy = 0.0; + inst->sumMagn = 0.0; + inst->whiteNoiseLevel = 0.0; + inst->pinkNoiseNumerator = 0.0; + inst->pinkNoiseExp = 0.0; + + WebRtcNs_set_feature_extraction_parameters(inst); // Set feature configuration + + //default mode + WebRtcNs_set_policy_core(inst, 0); + + + memset(inst->outBuf, 0, sizeof(float) * 3 * BLOCKL_MAX); + + inst->initFlag = 1; + return 0; +} + +int WebRtcNs_set_policy_core(NSinst_t *inst, int mode) +{ + // allow for modes:0,1,2,3 + if (mode < 0 || mode > 3) + { + return (-1); + } + + inst->aggrMode = mode; + if (mode == 0) + { + inst->overdrive = (float)1.0; + inst->denoiseBound = (float)0.5; + inst->gainmap = 0; + } + else if (mode == 1) + { + //inst->overdrive = (float)1.25; + inst->overdrive = (float)1.0; + inst->denoiseBound = (float)0.25; + inst->gainmap = 1; + } + else if (mode == 2) + { + //inst->overdrive = (float)1.25; + inst->overdrive = (float)1.1; + inst->denoiseBound = (float)0.125; + inst->gainmap = 1; + } + else if (mode == 3) + { + //inst->overdrive = (float)1.30; + inst->overdrive = (float)1.25; + inst->denoiseBound = (float)0.09; + inst->gainmap = 1; + } + return 0; +} + +// Estimate noise +void WebRtcNs_NoiseEstimation(NSinst_t *inst, float *magn, float *noise) +{ + int i, s, offset; + float lmagn[HALF_ANAL_BLOCKL], delta; + + if (inst->updates < END_STARTUP_LONG) + { + inst->updates++; + } + + for (i = 0; i < inst->magnLen; i++) + { + lmagn[i] = (float)log(magn[i]); + } + + // loop over simultaneous estimates + for (s = 0; s < SIMULT; s++) + { + offset = s * inst->magnLen; + + // newquantest(...) + for (i = 0; i < inst->magnLen; i++) + { + // compute delta + if (inst->density[offset + i] > 1.0) + { + delta = FACTOR * (float)1.0 / inst->density[offset + i]; + } + else + { + delta = FACTOR; + } + + // update log quantile estimate + if (lmagn[i] > inst->lquantile[offset + i]) + { + inst->lquantile[offset + i] += QUANTILE * delta + / (float)(inst->counter[s] + 1); + } + else + { + inst->lquantile[offset + i] -= ((float)1.0 - QUANTILE) * delta + / (float)(inst->counter[s] + 1); + } + + // update density estimate + if (fabs(lmagn[i] - inst->lquantile[offset + i]) < WIDTH) + { + inst->density[offset + i] = ((float)inst->counter[s] * inst->density[offset + + i] + (float)1.0 / ((float)2.0 * WIDTH)) / (float)(inst->counter[s] + + 1); + } + } // end loop over magnitude spectrum + + if (inst->counter[s] >= END_STARTUP_LONG) + { + inst->counter[s] = 0; + if (inst->updates >= END_STARTUP_LONG) + { + for (i = 0; i < inst->magnLen; i++) + { + inst->quantile[i] = (float)exp(inst->lquantile[offset + i]); + } + } + } + + inst->counter[s]++; + } // end loop over simultaneous estimates + + // Sequentially update the noise during startup + if (inst->updates < END_STARTUP_LONG) + { + // Use the last "s" to get noise during startup that differ from zero. + for (i = 0; i < inst->magnLen; i++) + { + inst->quantile[i] = (float)exp(inst->lquantile[offset + i]); + } + } + + for (i = 0; i < inst->magnLen; i++) + { + noise[i] = inst->quantile[i]; + } +} + +// Extract thresholds for feature parameters +// histograms are computed over some window_size (given by inst->modelUpdatePars[1]) +// thresholds and weights are extracted every window +// flag 0 means update histogram only, flag 1 means compute the thresholds/weights +// threshold and weights are returned in: inst->priorModelPars +void WebRtcNs_FeatureParameterExtraction(NSinst_t *inst, int flag) +{ + int i, useFeatureSpecFlat, useFeatureSpecDiff, numHistLrt; + int maxPeak1, maxPeak2; + int weightPeak1SpecFlat, weightPeak2SpecFlat, weightPeak1SpecDiff, weightPeak2SpecDiff; + + float binMid, featureSum; + float posPeak1SpecFlat, posPeak2SpecFlat, posPeak1SpecDiff, posPeak2SpecDiff; + float fluctLrt, avgHistLrt, avgSquareHistLrt, avgHistLrtCompl; + + //3 features: lrt, flatness, difference + //lrt_feature = inst->featureData[3]; + //flat_feature = inst->featureData[0]; + //diff_feature = inst->featureData[4]; + + //update histograms + if (flag == 0) + { + // LRT + if ((inst->featureData[3] < HIST_PAR_EST * inst->featureExtractionParams.binSizeLrt) + && (inst->featureData[3] >= 0.0)) + { + i = (int)(inst->featureData[3] / inst->featureExtractionParams.binSizeLrt); + inst->histLrt[i]++; + } + // Spectral flatness + if ((inst->featureData[0] < HIST_PAR_EST + * inst->featureExtractionParams.binSizeSpecFlat) + && (inst->featureData[0] >= 0.0)) + { + i = (int)(inst->featureData[0] / inst->featureExtractionParams.binSizeSpecFlat); + inst->histSpecFlat[i]++; + } + // Spectral difference + if ((inst->featureData[4] < HIST_PAR_EST + * inst->featureExtractionParams.binSizeSpecDiff) + && (inst->featureData[4] >= 0.0)) + { + i = (int)(inst->featureData[4] / inst->featureExtractionParams.binSizeSpecDiff); + inst->histSpecDiff[i]++; + } + } + + // extract parameters for speech/noise probability + if (flag == 1) + { + //lrt feature: compute the average over inst->featureExtractionParams.rangeAvgHistLrt + avgHistLrt = 0.0; + avgHistLrtCompl = 0.0; + avgSquareHistLrt = 0.0; + numHistLrt = 0; + for (i = 0; i < HIST_PAR_EST; i++) + { + binMid = ((float)i + (float)0.5) * inst->featureExtractionParams.binSizeLrt; + if (binMid <= inst->featureExtractionParams.rangeAvgHistLrt) + { + avgHistLrt += inst->histLrt[i] * binMid; + numHistLrt += inst->histLrt[i]; + } + avgSquareHistLrt += inst->histLrt[i] * binMid * binMid; + avgHistLrtCompl += inst->histLrt[i] * binMid; + } + if (numHistLrt > 0) + { + avgHistLrt = avgHistLrt / ((float)numHistLrt); + } + avgHistLrtCompl = avgHistLrtCompl / ((float)inst->modelUpdatePars[1]); + avgSquareHistLrt = avgSquareHistLrt / ((float)inst->modelUpdatePars[1]); + fluctLrt = avgSquareHistLrt - avgHistLrt * avgHistLrtCompl; + // get threshold for lrt feature: + if (fluctLrt < inst->featureExtractionParams.thresFluctLrt) + { + //very low fluct, so likely noise + inst->priorModelPars[0] = inst->featureExtractionParams.maxLrt; + } + else + { + inst->priorModelPars[0] = inst->featureExtractionParams.factor1ModelPars + * avgHistLrt; + // check if value is within min/max range + if (inst->priorModelPars[0] < inst->featureExtractionParams.minLrt) + { + inst->priorModelPars[0] = inst->featureExtractionParams.minLrt; + } + if (inst->priorModelPars[0] > inst->featureExtractionParams.maxLrt) + { + inst->priorModelPars[0] = inst->featureExtractionParams.maxLrt; + } + } + // done with lrt feature + + // + // for spectral flatness and spectral difference: compute the main peaks of histogram + maxPeak1 = 0; + maxPeak2 = 0; + posPeak1SpecFlat = 0.0; + posPeak2SpecFlat = 0.0; + weightPeak1SpecFlat = 0; + weightPeak2SpecFlat = 0; + + // peaks for flatness + for (i = 0; i < HIST_PAR_EST; i++) + { + binMid = ((float)i + (float)0.5) * inst->featureExtractionParams.binSizeSpecFlat; + if (inst->histSpecFlat[i] > maxPeak1) + { + // Found new "first" peak + maxPeak2 = maxPeak1; + weightPeak2SpecFlat = weightPeak1SpecFlat; + posPeak2SpecFlat = posPeak1SpecFlat; + + maxPeak1 = inst->histSpecFlat[i]; + weightPeak1SpecFlat = inst->histSpecFlat[i]; + posPeak1SpecFlat = binMid; + } + else if (inst->histSpecFlat[i] > maxPeak2) + { + // Found new "second" peak + maxPeak2 = inst->histSpecFlat[i]; + weightPeak2SpecFlat = inst->histSpecFlat[i]; + posPeak2SpecFlat = binMid; + } + } + + //compute two peaks for spectral difference + maxPeak1 = 0; + maxPeak2 = 0; + posPeak1SpecDiff = 0.0; + posPeak2SpecDiff = 0.0; + weightPeak1SpecDiff = 0; + weightPeak2SpecDiff = 0; + // peaks for spectral difference + for (i = 0; i < HIST_PAR_EST; i++) + { + binMid = ((float)i + (float)0.5) * inst->featureExtractionParams.binSizeSpecDiff; + if (inst->histSpecDiff[i] > maxPeak1) + { + // Found new "first" peak + maxPeak2 = maxPeak1; + weightPeak2SpecDiff = weightPeak1SpecDiff; + posPeak2SpecDiff = posPeak1SpecDiff; + + maxPeak1 = inst->histSpecDiff[i]; + weightPeak1SpecDiff = inst->histSpecDiff[i]; + posPeak1SpecDiff = binMid; + } + else if (inst->histSpecDiff[i] > maxPeak2) + { + // Found new "second" peak + maxPeak2 = inst->histSpecDiff[i]; + weightPeak2SpecDiff = inst->histSpecDiff[i]; + posPeak2SpecDiff = binMid; + } + } + + // for spectrum flatness feature + useFeatureSpecFlat = 1; + // merge the two peaks if they are close + if ((fabs(posPeak2SpecFlat - posPeak1SpecFlat) + < inst->featureExtractionParams.limitPeakSpacingSpecFlat) + && (weightPeak2SpecFlat + > inst->featureExtractionParams.limitPeakWeightsSpecFlat + * weightPeak1SpecFlat)) + { + weightPeak1SpecFlat += weightPeak2SpecFlat; + posPeak1SpecFlat = (float)0.5 * (posPeak1SpecFlat + posPeak2SpecFlat); + } + //reject if weight of peaks is not large enough, or peak value too small + if (weightPeak1SpecFlat < inst->featureExtractionParams.thresWeightSpecFlat + || posPeak1SpecFlat < inst->featureExtractionParams.thresPosSpecFlat) + { + useFeatureSpecFlat = 0; + } + // if selected, get the threshold + if (useFeatureSpecFlat == 1) + { + // compute the threshold + inst->priorModelPars[1] = inst->featureExtractionParams.factor2ModelPars + * posPeak1SpecFlat; + //check if value is within min/max range + if (inst->priorModelPars[1] < inst->featureExtractionParams.minSpecFlat) + { + inst->priorModelPars[1] = inst->featureExtractionParams.minSpecFlat; + } + if (inst->priorModelPars[1] > inst->featureExtractionParams.maxSpecFlat) + { + inst->priorModelPars[1] = inst->featureExtractionParams.maxSpecFlat; + } + } + // done with flatness feature + + // for template feature + useFeatureSpecDiff = 1; + // merge the two peaks if they are close + if ((fabs(posPeak2SpecDiff - posPeak1SpecDiff) + < inst->featureExtractionParams.limitPeakSpacingSpecDiff) + && (weightPeak2SpecDiff + > inst->featureExtractionParams.limitPeakWeightsSpecDiff + * weightPeak1SpecDiff)) + { + weightPeak1SpecDiff += weightPeak2SpecDiff; + posPeak1SpecDiff = (float)0.5 * (posPeak1SpecDiff + posPeak2SpecDiff); + } + // get the threshold value + inst->priorModelPars[3] = inst->featureExtractionParams.factor1ModelPars + * posPeak1SpecDiff; + //reject if weight of peaks is not large enough + if (weightPeak1SpecDiff < inst->featureExtractionParams.thresWeightSpecDiff) + { + useFeatureSpecDiff = 0; + } + //check if value is within min/max range + if (inst->priorModelPars[3] < inst->featureExtractionParams.minSpecDiff) + { + inst->priorModelPars[3] = inst->featureExtractionParams.minSpecDiff; + } + if (inst->priorModelPars[3] > inst->featureExtractionParams.maxSpecDiff) + { + inst->priorModelPars[3] = inst->featureExtractionParams.maxSpecDiff; + } + // done with spectral difference feature + + // don't use template feature if fluctuation of lrt feature is very low: + // most likely just noise state + if (fluctLrt < inst->featureExtractionParams.thresFluctLrt) + { + useFeatureSpecDiff = 0; + } + + // select the weights between the features + // inst->priorModelPars[4] is weight for lrt: always selected + // inst->priorModelPars[5] is weight for spectral flatness + // inst->priorModelPars[6] is weight for spectral difference + featureSum = (float)(1 + useFeatureSpecFlat + useFeatureSpecDiff); + inst->priorModelPars[4] = (float)1.0 / featureSum; + inst->priorModelPars[5] = ((float)useFeatureSpecFlat) / featureSum; + inst->priorModelPars[6] = ((float)useFeatureSpecDiff) / featureSum; + + // set hists to zero for next update + if (inst->modelUpdatePars[0] >= 1) + { + for (i = 0; i < HIST_PAR_EST; i++) + { + inst->histLrt[i] = 0; + inst->histSpecFlat[i] = 0; + inst->histSpecDiff[i] = 0; + } + } + } // end of flag == 1 +} + +// Compute spectral flatness on input spectrum +// magnIn is the magnitude spectrum +// spectral flatness is returned in inst->featureData[0] +void WebRtcNs_ComputeSpectralFlatness(NSinst_t *inst, float *magnIn) +{ + int i; + int shiftLP = 1; //option to remove first bin(s) from spectral measures + float avgSpectralFlatnessNum, avgSpectralFlatnessDen, spectralTmp; + + // comute spectral measures + // for flatness + avgSpectralFlatnessNum = 0.0; + avgSpectralFlatnessDen = inst->sumMagn; + for (i = 0; i < shiftLP; i++) + { + avgSpectralFlatnessDen -= magnIn[i]; + } + // compute log of ratio of the geometric to arithmetic mean: check for log(0) case + for (i = shiftLP; i < inst->magnLen; i++) + { + if (magnIn[i] > 0.0) + { + avgSpectralFlatnessNum += (float)log(magnIn[i]); + } + else + { + inst->featureData[0] -= SPECT_FL_TAVG * inst->featureData[0]; + return; + } + } + //normalize + avgSpectralFlatnessDen = avgSpectralFlatnessDen / inst->magnLen; + avgSpectralFlatnessNum = avgSpectralFlatnessNum / inst->magnLen; + + //ratio and inverse log: check for case of log(0) + spectralTmp = (float)exp(avgSpectralFlatnessNum) / avgSpectralFlatnessDen; + + //time-avg update of spectral flatness feature + inst->featureData[0] += SPECT_FL_TAVG * (spectralTmp - inst->featureData[0]); + // done with flatness feature +} + +// Compute the difference measure between input spectrum and a template/learned noise spectrum +// magnIn is the input spectrum +// the reference/template spectrum is inst->magnAvgPause[i] +// returns (normalized) spectral difference in inst->featureData[4] +void WebRtcNs_ComputeSpectralDifference(NSinst_t *inst, float *magnIn) +{ + // avgDiffNormMagn = var(magnIn) - cov(magnIn, magnAvgPause)^2 / var(magnAvgPause) + int i; + float avgPause, avgMagn, covMagnPause, varPause, varMagn, avgDiffNormMagn; + + avgPause = 0.0; + avgMagn = inst->sumMagn; + // compute average quantities + for (i = 0; i < inst->magnLen; i++) + { + //conservative smooth noise spectrum from pause frames + avgPause += inst->magnAvgPause[i]; + } + avgPause = avgPause / ((float)inst->magnLen); + avgMagn = avgMagn / ((float)inst->magnLen); + + covMagnPause = 0.0; + varPause = 0.0; + varMagn = 0.0; + // compute variance and covariance quantities + for (i = 0; i < inst->magnLen; i++) + { + covMagnPause += (magnIn[i] - avgMagn) * (inst->magnAvgPause[i] - avgPause); + varPause += (inst->magnAvgPause[i] - avgPause) * (inst->magnAvgPause[i] - avgPause); + varMagn += (magnIn[i] - avgMagn) * (magnIn[i] - avgMagn); + } + covMagnPause = covMagnPause / ((float)inst->magnLen); + varPause = varPause / ((float)inst->magnLen); + varMagn = varMagn / ((float)inst->magnLen); + // update of average magnitude spectrum + inst->featureData[6] += inst->signalEnergy; + + avgDiffNormMagn = varMagn - (covMagnPause * covMagnPause) / (varPause + (float)0.0001); + // normalize and compute time-avg update of difference feature + avgDiffNormMagn = (float)(avgDiffNormMagn / (inst->featureData[5] + (float)0.0001)); + inst->featureData[4] += SPECT_DIFF_TAVG * (avgDiffNormMagn - inst->featureData[4]); +} + +// Compute speech/noise probability +// speech/noise probability is returned in: probSpeechFinal +//magn is the input magnitude spectrum +//noise is the noise spectrum +//snrLocPrior is the prior snr for each freq. +//snr loc_post is the post snr for each freq. +void WebRtcNs_SpeechNoiseProb(NSinst_t *inst, float *probSpeechFinal, float *snrLocPrior, + float *snrLocPost) +{ + int i, sgnMap; + float invLrt, gainPrior, indPrior; + float logLrtTimeAvgKsum, besselTmp; + float indicator0, indicator1, indicator2; + float tmpFloat1, tmpFloat2; + float weightIndPrior0, weightIndPrior1, weightIndPrior2; + float threshPrior0, threshPrior1, threshPrior2; + float widthPrior, widthPrior0, widthPrior1, widthPrior2; + + widthPrior0 = WIDTH_PR_MAP; + widthPrior1 = (float)2.0 * WIDTH_PR_MAP; //width for pause region: + // lower range, so increase width in tanh map + widthPrior2 = (float)2.0 * WIDTH_PR_MAP; //for spectral-difference measure + + //threshold parameters for features + threshPrior0 = inst->priorModelPars[0]; + threshPrior1 = inst->priorModelPars[1]; + threshPrior2 = inst->priorModelPars[3]; + + //sign for flatness feature + sgnMap = (int)(inst->priorModelPars[2]); + + //weight parameters for features + weightIndPrior0 = inst->priorModelPars[4]; + weightIndPrior1 = inst->priorModelPars[5]; + weightIndPrior2 = inst->priorModelPars[6]; + + // compute feature based on average LR factor + // this is the average over all frequencies of the smooth log lrt + logLrtTimeAvgKsum = 0.0; + for (i = 0; i < inst->magnLen; i++) + { + tmpFloat1 = (float)1.0 + (float)2.0 * snrLocPrior[i]; + tmpFloat2 = (float)2.0 * snrLocPrior[i] / (tmpFloat1 + (float)0.0001); + besselTmp = (snrLocPost[i] + (float)1.0) * tmpFloat2; + inst->logLrtTimeAvg[i] += LRT_TAVG * (besselTmp - (float)log(tmpFloat1) + - inst->logLrtTimeAvg[i]); + logLrtTimeAvgKsum += inst->logLrtTimeAvg[i]; + } + logLrtTimeAvgKsum = (float)logLrtTimeAvgKsum / (inst->magnLen); + inst->featureData[3] = logLrtTimeAvgKsum; + // done with computation of LR factor + + // + //compute the indicator functions + // + + // average lrt feature + widthPrior = widthPrior0; + //use larger width in tanh map for pause regions + if (logLrtTimeAvgKsum < threshPrior0) + { + widthPrior = widthPrior1; + } + // compute indicator function: sigmoid map + indicator0 = (float)0.5 * ((float)tanh(widthPrior * (logLrtTimeAvgKsum - threshPrior0)) + + (float)1.0); + + //spectral flatness feature + tmpFloat1 = inst->featureData[0]; + widthPrior = widthPrior0; + //use larger width in tanh map for pause regions + if (sgnMap == 1 && (tmpFloat1 > threshPrior1)) + { + widthPrior = widthPrior1; + } + if (sgnMap == -1 && (tmpFloat1 < threshPrior1)) + { + widthPrior = widthPrior1; + } + // compute indicator function: sigmoid map + indicator1 = (float)0.5 * ((float)tanh( + (float)sgnMap * widthPrior * (threshPrior1 + - tmpFloat1)) + (float)1.0); + + //for template spectrum-difference + tmpFloat1 = inst->featureData[4]; + widthPrior = widthPrior0; + //use larger width in tanh map for pause regions + if (tmpFloat1 < threshPrior2) + { + widthPrior = widthPrior2; + } + // compute indicator function: sigmoid map + indicator2 = (float)0.5 * ((float)tanh(widthPrior * (tmpFloat1 - threshPrior2)) + + (float)1.0); + + //combine the indicator function with the feature weights + indPrior = weightIndPrior0 * indicator0 + weightIndPrior1 * indicator1 + weightIndPrior2 + * indicator2; + // done with computing indicator function + + //compute the prior probability + inst->priorSpeechProb += PRIOR_UPDATE * (indPrior - inst->priorSpeechProb); + // make sure probabilities are within range: keep floor to 0.01 + if (inst->priorSpeechProb > 1.0) + { + inst->priorSpeechProb = (float)1.0; + } + if (inst->priorSpeechProb < 0.01) + { + inst->priorSpeechProb = (float)0.01; + } + + //final speech probability: combine prior model with LR factor: + gainPrior = ((float)1.0 - inst->priorSpeechProb) / (inst->priorSpeechProb + (float)0.0001); + for (i = 0; i < inst->magnLen; i++) + { + invLrt = (float)exp(-inst->logLrtTimeAvg[i]); + invLrt = (float)gainPrior * invLrt; + probSpeechFinal[i] = (float)1.0 / ((float)1.0 + invLrt); + } +} + +int WebRtcNs_ProcessCore(NSinst_t *inst, + short *speechFrame, + short *speechFrameHB, + short *outFrame, + short *outFrameHB) +{ + // main routine for noise reduction + + int flagHB = 0; + int i; + const int kStartBand = 5; // Skip first frequency bins during estimation. + int updateParsFlag; + + float energy1, energy2, gain, factor, factor1, factor2; + float signalEnergy, sumMagn; + float snrPrior, currentEstimateStsa; + float tmpFloat1, tmpFloat2, tmpFloat3, probSpeech, probNonSpeech; + float gammaNoiseTmp, gammaNoiseOld; + float noiseUpdateTmp, fTmp, dTmp; + float fin[BLOCKL_MAX], fout[BLOCKL_MAX]; + float winData[ANAL_BLOCKL_MAX]; + float magn[HALF_ANAL_BLOCKL], noise[HALF_ANAL_BLOCKL]; + float theFilter[HALF_ANAL_BLOCKL], theFilterTmp[HALF_ANAL_BLOCKL]; + float snrLocPost[HALF_ANAL_BLOCKL], snrLocPrior[HALF_ANAL_BLOCKL]; + float probSpeechFinal[HALF_ANAL_BLOCKL], previousEstimateStsa[HALF_ANAL_BLOCKL]; + float real[ANAL_BLOCKL_MAX], imag[HALF_ANAL_BLOCKL]; + // Variables during startup + float sum_log_i = 0.0; + float sum_log_i_square = 0.0; + float sum_log_magn = 0.0; + float sum_log_i_log_magn = 0.0; + float parametric_noise = 0.0; + float parametric_exp = 0.0; + float parametric_num = 0.0; + + // SWB variables + int deltaBweHB = 1; + int deltaGainHB = 1; + float decayBweHB = 1.0; + float gainMapParHB = 1.0; + float gainTimeDomainHB = 1.0; + float avgProbSpeechHB, avgProbSpeechHBTmp, avgFilterGainHB, gainModHB; + + // Check that initiation has been done + if (inst->initFlag != 1) + { + return (-1); + } + // Check for valid pointers based on sampling rate + if (inst->fs == 32000) + { + if (speechFrameHB == NULL) + { + return -1; + } + flagHB = 1; + // range for averaging low band quantities for H band gain + deltaBweHB = (int)inst->magnLen / 4; + deltaGainHB = deltaBweHB; + } + // + inst->blockInd++; + // + updateParsFlag = inst->modelUpdatePars[0]; + // + + //for LB do all processing + // convert to float + for (i = 0; i < inst->blockLen10ms; i++) + { + fin[i] = (float)speechFrame[i]; + } + // update analysis buffer for L band + memcpy(inst->dataBuf, inst->dataBuf + inst->blockLen10ms, + sizeof(float) * (inst->anaLen - inst->blockLen10ms)); + memcpy(inst->dataBuf + inst->anaLen - inst->blockLen10ms, fin, + sizeof(float) * inst->blockLen10ms); + + if (flagHB == 1) + { + // convert to float + for (i = 0; i < inst->blockLen10ms; i++) + { + fin[i] = (float)speechFrameHB[i]; + } + // update analysis buffer for H band + memcpy(inst->dataBufHB, inst->dataBufHB + inst->blockLen10ms, + sizeof(float) * (inst->anaLen - inst->blockLen10ms)); + memcpy(inst->dataBufHB + inst->anaLen - inst->blockLen10ms, fin, + sizeof(float) * inst->blockLen10ms); + } + + // check if processing needed + if (inst->outLen == 0) + { + // windowing + energy1 = 0.0; + for (i = 0; i < inst->anaLen; i++) + { + winData[i] = inst->window[i] * inst->dataBuf[i]; + energy1 += winData[i] * winData[i]; + } + if (energy1 == 0.0) + { + // synthesize the special case of zero input + // we want to avoid updating statistics in this case: + // Updating feature statistics when we have zeros only will cause thresholds to + // move towards zero signal situations. This in turn has the effect that once the + // signal is "turned on" (non-zero values) everything will be treated as speech + // and there is no noise suppression effect. Depending on the duration of the + // inactive signal it takes a considerable amount of time for the system to learn + // what is noise and what is speech. + + // read out fully processed segment + for (i = inst->windShift; i < inst->blockLen + inst->windShift; i++) + { + fout[i - inst->windShift] = inst->syntBuf[i]; + } + // update synthesis buffer + memcpy(inst->syntBuf, inst->syntBuf + inst->blockLen, + sizeof(float) * (inst->anaLen - inst->blockLen)); + memset(inst->syntBuf + inst->anaLen - inst->blockLen, 0, + sizeof(float) * inst->blockLen); + + // out buffer + inst->outLen = inst->blockLen - inst->blockLen10ms; + if (inst->blockLen > inst->blockLen10ms) + { + for (i = 0; i < inst->outLen; i++) + { + inst->outBuf[i] = fout[i + inst->blockLen10ms]; + } + } + // convert to short + for (i = 0; i < inst->blockLen10ms; i++) + { + dTmp = fout[i]; + if (dTmp < WEBRTC_SPL_WORD16_MIN) + { + dTmp = WEBRTC_SPL_WORD16_MIN; + } + else if (dTmp > WEBRTC_SPL_WORD16_MAX) + { + dTmp = WEBRTC_SPL_WORD16_MAX; + } + outFrame[i] = (short)dTmp; + } + + // for time-domain gain of HB + if (flagHB == 1) + { + for (i = 0; i < inst->blockLen10ms; i++) + { + dTmp = inst->dataBufHB[i]; + if (dTmp < WEBRTC_SPL_WORD16_MIN) + { + dTmp = WEBRTC_SPL_WORD16_MIN; + } + else if (dTmp > WEBRTC_SPL_WORD16_MAX) + { + dTmp = WEBRTC_SPL_WORD16_MAX; + } + outFrameHB[i] = (short)dTmp; + } + } // end of H band gain computation + // + return 0; + } + + // FFT + rdft(inst->anaLen, 1, winData, inst->ip, inst->wfft); + + imag[0] = 0; + real[0] = winData[0]; + magn[0] = (float)(fabs(real[0]) + 1.0f); + imag[inst->magnLen - 1] = 0; + real[inst->magnLen - 1] = winData[1]; + magn[inst->magnLen - 1] = (float)(fabs(real[inst->magnLen - 1]) + 1.0f); + signalEnergy = (float)(real[0] * real[0]) + (float)(real[inst->magnLen - 1] + * real[inst->magnLen - 1]); + sumMagn = magn[0] + magn[inst->magnLen - 1]; + if (inst->blockInd < END_STARTUP_SHORT) + { + inst->initMagnEst[0] += magn[0]; + inst->initMagnEst[inst->magnLen - 1] += magn[inst->magnLen - 1]; + tmpFloat2 = log((float)(inst->magnLen - 1)); + sum_log_i = tmpFloat2; + sum_log_i_square = tmpFloat2 * tmpFloat2; + tmpFloat1 = log(magn[inst->magnLen - 1]); + sum_log_magn = tmpFloat1; + sum_log_i_log_magn = tmpFloat2 * tmpFloat1; + } + for (i = 1; i < inst->magnLen - 1; i++) + { + real[i] = winData[2 * i]; + imag[i] = winData[2 * i + 1]; + // magnitude spectrum + fTmp = real[i] * real[i]; + fTmp += imag[i] * imag[i]; + signalEnergy += fTmp; + magn[i] = ((float)sqrt(fTmp)) + 1.0f; + sumMagn += magn[i]; + if (inst->blockInd < END_STARTUP_SHORT) + { + inst->initMagnEst[i] += magn[i]; + if (i >= kStartBand) + { + tmpFloat2 = log((float)i); + sum_log_i += tmpFloat2; + sum_log_i_square += tmpFloat2 * tmpFloat2; + tmpFloat1 = log(magn[i]); + sum_log_magn += tmpFloat1; + sum_log_i_log_magn += tmpFloat2 * tmpFloat1; + } + } + } + signalEnergy = signalEnergy / ((float)inst->magnLen); + inst->signalEnergy = signalEnergy; + inst->sumMagn = sumMagn; + + //compute spectral flatness on input spectrum + WebRtcNs_ComputeSpectralFlatness(inst, magn); + // quantile noise estimate + WebRtcNs_NoiseEstimation(inst, magn, noise); + //compute simplified noise model during startup + if (inst->blockInd < END_STARTUP_SHORT) + { + // Estimate White noise + inst->whiteNoiseLevel += sumMagn / ((float)inst->magnLen) * inst->overdrive; + // Estimate Pink noise parameters + tmpFloat1 = sum_log_i_square * ((float)(inst->magnLen - kStartBand)); + tmpFloat1 -= (sum_log_i * sum_log_i); + tmpFloat2 = (sum_log_i_square * sum_log_magn - sum_log_i * sum_log_i_log_magn); + tmpFloat3 = tmpFloat2 / tmpFloat1; + // Constrain the estimated spectrum to be positive + if (tmpFloat3 < 0.0f) + { + tmpFloat3 = 0.0f; + } + inst->pinkNoiseNumerator += tmpFloat3; + tmpFloat2 = (sum_log_i * sum_log_magn); + tmpFloat2 -= ((float)(inst->magnLen - kStartBand)) * sum_log_i_log_magn; + tmpFloat3 = tmpFloat2 / tmpFloat1; + // Constrain the pink noise power to be in the interval [0, 1]; + if (tmpFloat3 < 0.0f) + { + tmpFloat3 = 0.0f; + } + if (tmpFloat3 > 1.0f) + { + tmpFloat3 = 1.0f; + } + inst->pinkNoiseExp += tmpFloat3; + + // Calculate frequency independent parts of parametric noise estimate. + if (inst->pinkNoiseExp == 0.0f) + { + // Use white noise estimate + parametric_noise = inst->whiteNoiseLevel; + } + else + { + // Use pink noise estimate + parametric_num = exp(inst->pinkNoiseNumerator / (float)(inst->blockInd + 1)); + parametric_num *= (float)(inst->blockInd + 1); + parametric_exp = inst->pinkNoiseExp / (float)(inst->blockInd + 1); + parametric_noise = parametric_num / pow((float)kStartBand, parametric_exp); + } + for (i = 0; i < inst->magnLen; i++) + { + // Estimate the background noise using the white and pink noise parameters + if ((inst->pinkNoiseExp > 0.0f) && (i >= kStartBand)) + { + // Use pink noise estimate + parametric_noise = parametric_num / pow((float)i, parametric_exp); + } + theFilterTmp[i] = (inst->initMagnEst[i] - inst->overdrive * parametric_noise); + theFilterTmp[i] /= (inst->initMagnEst[i] + (float)0.0001); + // Weight quantile noise with modeled noise + noise[i] *= (inst->blockInd); + tmpFloat2 = parametric_noise * (END_STARTUP_SHORT - inst->blockInd); + noise[i] += (tmpFloat2 / (float)(inst->blockInd + 1)); + noise[i] /= END_STARTUP_SHORT; + } + } + //compute average signal during END_STARTUP_LONG time: + // used to normalize spectral difference measure + if (inst->blockInd < END_STARTUP_LONG) + { + inst->featureData[5] *= inst->blockInd; + inst->featureData[5] += signalEnergy; + inst->featureData[5] /= (inst->blockInd + 1); + } + +#ifdef PROCESS_FLOW_0 + if (inst->blockInd > END_STARTUP_LONG) + { + //option: average the quantile noise: for check with AEC2 + for (i = 0; i < inst->magnLen; i++) + { + noise[i] = (float)0.6 * inst->noisePrev[i] + (float)0.4 * noise[i]; + } + for (i = 0; i < inst->magnLen; i++) + { + // Wiener with over sub-substraction: + theFilter[i] = (magn[i] - inst->overdrive * noise[i]) / (magn[i] + (float)0.0001); + } + } +#else + //start processing at frames == converged+1 + // + // STEP 1: compute prior and post snr based on quantile noise est + // + + // compute DD estimate of prior SNR: needed for new method + for (i = 0; i < inst->magnLen; i++) + { + // post snr + snrLocPost[i] = (float)0.0; + if (magn[i] > noise[i]) + { + snrLocPost[i] = magn[i] / (noise[i] + (float)0.0001) - (float)1.0; + } + // previous post snr + // previous estimate: based on previous frame with gain filter + previousEstimateStsa[i] = inst->magnPrev[i] / (inst->noisePrev[i] + (float)0.0001) + * (inst->smooth[i]); + // DD estimate is sum of two terms: current estimate and previous estimate + // directed decision update of snrPrior + snrLocPrior[i] = DD_PR_SNR * previousEstimateStsa[i] + ((float)1.0 - DD_PR_SNR) + * snrLocPost[i]; + // post and prior snr needed for step 2 + } // end of loop over freqs +#ifdef PROCESS_FLOW_1 + for (i = 0; i < inst->magnLen; i++) + { + // gain filter + tmpFloat1 = inst->overdrive + snrLocPrior[i]; + tmpFloat2 = (float)snrLocPrior[i] / tmpFloat1; + theFilter[i] = (float)tmpFloat2; + } // end of loop over freqs +#endif + // done with step 1: dd computation of prior and post snr + + // + //STEP 2: compute speech/noise likelihood + // +#ifdef PROCESS_FLOW_2 + // compute difference of input spectrum with learned/estimated noise spectrum + WebRtcNs_ComputeSpectralDifference(inst, magn); + // compute histograms for parameter decisions (thresholds and weights for features) + // parameters are extracted once every window time (=inst->modelUpdatePars[1]) + if (updateParsFlag >= 1) + { + // counter update + inst->modelUpdatePars[3]--; + // update histogram + if (inst->modelUpdatePars[3] > 0) + { + WebRtcNs_FeatureParameterExtraction(inst, 0); + } + // compute model parameters + if (inst->modelUpdatePars[3] == 0) + { + WebRtcNs_FeatureParameterExtraction(inst, 1); + inst->modelUpdatePars[3] = inst->modelUpdatePars[1]; + // if wish to update only once, set flag to zero + if (updateParsFlag == 1) + { + inst->modelUpdatePars[0] = 0; + } + else + { + // update every window: + // get normalization for spectral difference for next window estimate + inst->featureData[6] = inst->featureData[6] + / ((float)inst->modelUpdatePars[1]); + inst->featureData[5] = (float)0.5 * (inst->featureData[6] + + inst->featureData[5]); + inst->featureData[6] = (float)0.0; + } + } + } + // compute speech/noise probability + WebRtcNs_SpeechNoiseProb(inst, probSpeechFinal, snrLocPrior, snrLocPost); + // time-avg parameter for noise update + gammaNoiseTmp = NOISE_UPDATE; + for (i = 0; i < inst->magnLen; i++) + { + probSpeech = probSpeechFinal[i]; + probNonSpeech = (float)1.0 - probSpeech; + // temporary noise update: + // use it for speech frames if update value is less than previous + noiseUpdateTmp = gammaNoiseTmp * inst->noisePrev[i] + ((float)1.0 - gammaNoiseTmp) + * (probNonSpeech * magn[i] + probSpeech * inst->noisePrev[i]); + // + // time-constant based on speech/noise state + gammaNoiseOld = gammaNoiseTmp; + gammaNoiseTmp = NOISE_UPDATE; + // increase gamma (i.e., less noise update) for frame likely to be speech + if (probSpeech > PROB_RANGE) + { + gammaNoiseTmp = SPEECH_UPDATE; + } + // conservative noise update + if (probSpeech < PROB_RANGE) + { + inst->magnAvgPause[i] += GAMMA_PAUSE * (magn[i] - inst->magnAvgPause[i]); + } + // noise update + if (gammaNoiseTmp == gammaNoiseOld) + { + noise[i] = noiseUpdateTmp; + } + else + { + noise[i] = gammaNoiseTmp * inst->noisePrev[i] + ((float)1.0 - gammaNoiseTmp) + * (probNonSpeech * magn[i] + probSpeech * inst->noisePrev[i]); + // allow for noise update downwards: + // if noise update decreases the noise, it is safe, so allow it to happen + if (noiseUpdateTmp < noise[i]) + { + noise[i] = noiseUpdateTmp; + } + } + } // end of freq loop + // done with step 2: noise update + + // + // STEP 3: compute dd update of prior snr and post snr based on new noise estimate + // + for (i = 0; i < inst->magnLen; i++) + { + // post and prior snr + currentEstimateStsa = (float)0.0; + if (magn[i] > noise[i]) + { + currentEstimateStsa = magn[i] / (noise[i] + (float)0.0001) - (float)1.0; + } + // DD estimate is sume of two terms: current estimate and previous estimate + // directed decision update of snrPrior + snrPrior = DD_PR_SNR * previousEstimateStsa[i] + ((float)1.0 - DD_PR_SNR) + * currentEstimateStsa; + // gain filter + tmpFloat1 = inst->overdrive + snrPrior; + tmpFloat2 = (float)snrPrior / tmpFloat1; + theFilter[i] = (float)tmpFloat2; + } // end of loop over freqs + // done with step3 +#endif +#endif + + for (i = 0; i < inst->magnLen; i++) + { + // flooring bottom + if (theFilter[i] < inst->denoiseBound) + { + theFilter[i] = inst->denoiseBound; + } + // flooring top + if (theFilter[i] > (float)1.0) + { + theFilter[i] = 1.0; + } + if (inst->blockInd < END_STARTUP_SHORT) + { + // flooring bottom + if (theFilterTmp[i] < inst->denoiseBound) + { + theFilterTmp[i] = inst->denoiseBound; + } + // flooring top + if (theFilterTmp[i] > (float)1.0) + { + theFilterTmp[i] = 1.0; + } + // Weight the two suppression filters + theFilter[i] *= (inst->blockInd); + theFilterTmp[i] *= (END_STARTUP_SHORT - inst->blockInd); + theFilter[i] += theFilterTmp[i]; + theFilter[i] /= (END_STARTUP_SHORT); + } + // smoothing +#ifdef PROCESS_FLOW_0 + inst->smooth[i] *= SMOOTH; // value set to 0.7 in define.h file + inst->smooth[i] += ((float)1.0 - SMOOTH) * theFilter[i]; +#else + inst->smooth[i] = theFilter[i]; +#endif + real[i] *= inst->smooth[i]; + imag[i] *= inst->smooth[i]; + } + // keep track of noise and magn spectrum for next frame + for (i = 0; i < inst->magnLen; i++) + { + inst->noisePrev[i] = noise[i]; + inst->magnPrev[i] = magn[i]; + } + // back to time domain + winData[0] = real[0]; + winData[1] = real[inst->magnLen - 1]; + for (i = 1; i < inst->magnLen - 1; i++) + { + winData[2 * i] = real[i]; + winData[2 * i + 1] = imag[i]; + } + rdft(inst->anaLen, -1, winData, inst->ip, inst->wfft); + + for (i = 0; i < inst->anaLen; i++) + { + real[i] = 2.0f * winData[i] / inst->anaLen; // fft scaling + } + + //scale factor: only do it after END_STARTUP_LONG time + factor = (float)1.0; + if (inst->gainmap == 1 && inst->blockInd > END_STARTUP_LONG) + { + factor1 = (float)1.0; + factor2 = (float)1.0; + + energy2 = 0.0; + for (i = 0; i < inst->anaLen;i++) + { + energy2 += (float)real[i] * (float)real[i]; + } + gain = (float)sqrt(energy2 / (energy1 + (float)1.0)); + +#ifdef PROCESS_FLOW_2 + // scaling for new version + if (gain > B_LIM) + { + factor1 = (float)1.0 + (float)1.3 * (gain - B_LIM); + if (gain * factor1 > (float)1.0) + { + factor1 = (float)1.0 / gain; + } + } + if (gain < B_LIM) + { + //don't reduce scale too much for pause regions: + // attenuation here should be controlled by flooring + if (gain <= inst->denoiseBound) + { + gain = inst->denoiseBound; + } + factor2 = (float)1.0 - (float)0.3 * (B_LIM - gain); + } + //combine both scales with speech/noise prob: + // note prior (priorSpeechProb) is not frequency dependent + factor = inst->priorSpeechProb * factor1 + ((float)1.0 - inst->priorSpeechProb) + * factor2; +#else + if (gain > B_LIM) + { + factor = (float)1.0 + (float)1.3 * (gain - B_LIM); + } + else + { + factor = (float)1.0 + (float)2.0 * (gain - B_LIM); + } + if (gain * factor > (float)1.0) + { + factor = (float)1.0 / gain; + } +#endif + } // out of inst->gainmap==1 + + // synthesis + for (i = 0; i < inst->anaLen; i++) + { + inst->syntBuf[i] += factor * inst->window[i] * (float)real[i]; + } + // read out fully processed segment + for (i = inst->windShift; i < inst->blockLen + inst->windShift; i++) + { + fout[i - inst->windShift] = inst->syntBuf[i]; + } + // update synthesis buffer + memcpy(inst->syntBuf, inst->syntBuf + inst->blockLen, + sizeof(float) * (inst->anaLen - inst->blockLen)); + memset(inst->syntBuf + inst->anaLen - inst->blockLen, 0, + sizeof(float) * inst->blockLen); + + // out buffer + inst->outLen = inst->blockLen - inst->blockLen10ms; + if (inst->blockLen > inst->blockLen10ms) + { + for (i = 0; i < inst->outLen; i++) + { + inst->outBuf[i] = fout[i + inst->blockLen10ms]; + } + } + } // end of if out.len==0 + else + { + for (i = 0; i < inst->blockLen10ms; i++) + { + fout[i] = inst->outBuf[i]; + } + memcpy(inst->outBuf, inst->outBuf + inst->blockLen10ms, + sizeof(float) * (inst->outLen - inst->blockLen10ms)); + memset(inst->outBuf + inst->outLen - inst->blockLen10ms, 0, + sizeof(float) * inst->blockLen10ms); + inst->outLen -= inst->blockLen10ms; + } + + // convert to short + for (i = 0; i < inst->blockLen10ms; i++) + { + dTmp = fout[i]; + if (dTmp < WEBRTC_SPL_WORD16_MIN) + { + dTmp = WEBRTC_SPL_WORD16_MIN; + } + else if (dTmp > WEBRTC_SPL_WORD16_MAX) + { + dTmp = WEBRTC_SPL_WORD16_MAX; + } + outFrame[i] = (short)dTmp; + } + + // for time-domain gain of HB + if (flagHB == 1) + { + for (i = 0; i < inst->magnLen; i++) + { + inst->speechProbHB[i] = probSpeechFinal[i]; + } + if (inst->blockInd > END_STARTUP_LONG) + { + // average speech prob from low band + // avg over second half (i.e., 4->8kHz) of freq. spectrum + avgProbSpeechHB = 0.0; + for (i = inst->magnLen - deltaBweHB - 1; i < inst->magnLen - 1; i++) + { + avgProbSpeechHB += inst->speechProbHB[i]; + } + avgProbSpeechHB = avgProbSpeechHB / ((float)deltaBweHB); + // average filter gain from low band + // average over second half (i.e., 4->8kHz) of freq. spectrum + avgFilterGainHB = 0.0; + for (i = inst->magnLen - deltaGainHB - 1; i < inst->magnLen - 1; i++) + { + avgFilterGainHB += inst->smooth[i]; + } + avgFilterGainHB = avgFilterGainHB / ((float)(deltaGainHB)); + avgProbSpeechHBTmp = (float)2.0 * avgProbSpeechHB - (float)1.0; + // gain based on speech prob: + gainModHB = (float)0.5 * ((float)1.0 + (float)tanh(gainMapParHB * avgProbSpeechHBTmp)); + //combine gain with low band gain + gainTimeDomainHB = (float)0.5 * gainModHB + (float)0.5 * avgFilterGainHB; + if (avgProbSpeechHB >= (float)0.5) + { + gainTimeDomainHB = (float)0.25 * gainModHB + (float)0.75 * avgFilterGainHB; + } + gainTimeDomainHB = gainTimeDomainHB * decayBweHB; + } // end of converged + //make sure gain is within flooring range + // flooring bottom + if (gainTimeDomainHB < inst->denoiseBound) + { + gainTimeDomainHB = inst->denoiseBound; + } + // flooring top + if (gainTimeDomainHB > (float)1.0) + { + gainTimeDomainHB = 1.0; + } + //apply gain + for (i = 0; i < inst->blockLen10ms; i++) + { + dTmp = gainTimeDomainHB * inst->dataBufHB[i]; + if (dTmp < WEBRTC_SPL_WORD16_MIN) + { + dTmp = WEBRTC_SPL_WORD16_MIN; + } + else if (dTmp > WEBRTC_SPL_WORD16_MAX) + { + dTmp = WEBRTC_SPL_WORD16_MAX; + } + outFrameHB[i] = (short)dTmp; + } + } // end of H band gain computation + // + + return 0; +} diff --git a/src/libs/webrtc/ns/ns_core.h b/src/libs/webrtc/ns/ns_core.h new file mode 100644 index 00000000..f72e22bf --- /dev/null +++ b/src/libs/webrtc/ns/ns_core.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NS_CORE_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NS_CORE_H_ + +#include "defines.h" + +typedef struct NSParaExtract_t_ { + + //bin size of histogram + float binSizeLrt; + float binSizeSpecFlat; + float binSizeSpecDiff; + //range of histogram over which lrt threshold is computed + float rangeAvgHistLrt; + //scale parameters: multiply dominant peaks of the histograms by scale factor to obtain + //thresholds for prior model + float factor1ModelPars; //for lrt and spectral difference + float factor2ModelPars; //for spectral_flatness: used when noise is flatter than speech + //peak limit for spectral flatness (varies between 0 and 1) + float thresPosSpecFlat; + //limit on spacing of two highest peaks in histogram: spacing determined by bin size + float limitPeakSpacingSpecFlat; + float limitPeakSpacingSpecDiff; + //limit on relevance of second peak: + float limitPeakWeightsSpecFlat; + float limitPeakWeightsSpecDiff; + //limit on fluctuation of lrt feature + float thresFluctLrt; + //limit on the max and min values for the feature thresholds + float maxLrt; + float minLrt; + float maxSpecFlat; + float minSpecFlat; + float maxSpecDiff; + float minSpecDiff; + //criteria of weight of histogram peak to accept/reject feature + int thresWeightSpecFlat; + int thresWeightSpecDiff; + +} NSParaExtract_t; + +typedef struct NSinst_t_ { + + WebRtc_UWord32 fs; + int blockLen; + int blockLen10ms; + int windShift; + int outLen; + int anaLen; + int magnLen; + int aggrMode; + const float* window; + float dataBuf[ANAL_BLOCKL_MAX]; + float syntBuf[ANAL_BLOCKL_MAX]; + float outBuf[3 * BLOCKL_MAX]; + + int initFlag; + // parameters for quantile noise estimation + float density[SIMULT * HALF_ANAL_BLOCKL]; + float lquantile[SIMULT * HALF_ANAL_BLOCKL]; + float quantile[HALF_ANAL_BLOCKL]; + int counter[SIMULT]; + int updates; + // parameters for Wiener filter + float smooth[HALF_ANAL_BLOCKL]; + float overdrive; + float denoiseBound; + int gainmap; + // fft work arrays. + int ip[IP_LENGTH]; + float wfft[W_LENGTH]; + + // parameters for new method: some not needed, will reduce/cleanup later + WebRtc_Word32 blockInd; //frame index counter + int modelUpdatePars[4]; //parameters for updating or estimating + // thresholds/weights for prior model + float priorModelPars[7]; //parameters for prior model + float noisePrev[HALF_ANAL_BLOCKL]; //noise spectrum from previous frame + float magnPrev[HALF_ANAL_BLOCKL]; //magnitude spectrum of previous frame + float logLrtTimeAvg[HALF_ANAL_BLOCKL]; //log lrt factor with time-smoothing + float priorSpeechProb; //prior speech/noise probability + float featureData[7]; //data for features + float magnAvgPause[HALF_ANAL_BLOCKL]; //conservative noise spectrum estimate + float signalEnergy; //energy of magn + float sumMagn; //sum of magn + float whiteNoiseLevel; //initial noise estimate + float initMagnEst[HALF_ANAL_BLOCKL]; //initial magnitude spectrum estimate + float pinkNoiseNumerator; //pink noise parameter: numerator + float pinkNoiseExp; //pink noise parameter: power of freq + NSParaExtract_t featureExtractionParams; //parameters for feature extraction + //histograms for parameter estimation + int histLrt[HIST_PAR_EST]; + int histSpecFlat[HIST_PAR_EST]; + int histSpecDiff[HIST_PAR_EST]; + //quantities for high band estimate + float speechProbHB[HALF_ANAL_BLOCKL]; //final speech/noise prob: prior + LRT + float dataBufHB[ANAL_BLOCKL_MAX]; //buffering data for HB + +} NSinst_t; + + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************************************************************** + * WebRtcNs_InitCore(...) + * + * This function initializes a noise suppression instance + * + * Input: + * - inst : Instance that should be initialized + * - fs : Sampling frequency + * + * Output: + * - inst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNs_InitCore(NSinst_t *inst, WebRtc_UWord32 fs); + +/**************************************************************************** + * WebRtcNs_set_policy_core(...) + * + * This changes the aggressiveness of the noise suppression method. + * + * Input: + * - inst : Instance that should be initialized + * - mode : 0: Mild (6 dB), 1: Medium (10 dB), 2: Aggressive (15 dB) + * + * Output: + * - NS_inst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNs_set_policy_core(NSinst_t *inst, int mode); + +/**************************************************************************** + * WebRtcNs_ProcessCore + * + * Do noise suppression. + * + * Input: + * - inst : Instance that should be initialized + * - inFrameLow : Input speech frame for lower band + * - inFrameHigh : Input speech frame for higher band + * + * Output: + * - inst : Updated instance + * - outFrameLow : Output speech frame for lower band + * - outFrameHigh : Output speech frame for higher band + * + * Return value : 0 - OK + * -1 - Error + */ + + +int WebRtcNs_ProcessCore(NSinst_t *inst, + short *inFrameLow, + short *inFrameHigh, + short *outFrameLow, + short *outFrameHigh); + + +#ifdef __cplusplus +} +#endif +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NS_CORE_H_ diff --git a/src/libs/webrtc/ns/nsx_core.c b/src/libs/webrtc/ns/nsx_core.c new file mode 100644 index 00000000..6c62d64e --- /dev/null +++ b/src/libs/webrtc/ns/nsx_core.c @@ -0,0 +1,2493 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "noise_suppression_x.h" + +#include <assert.h> +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#include "nsx_core.h" + +// Skip first frequency bins during estimation. (0 <= value < 64) +static const int kStartBand = 5; + +// Rounding +static const WebRtc_Word16 kRoundTable[16] = {0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, + 2048, 4096, 8192, 16384}; + +// Constants to compensate for shifting signal log(2^shifts). +static const WebRtc_Word16 kLogTable[9] = {0, 177, 355, 532, 710, 887, 1065, 1242, 1420}; + +static const WebRtc_Word16 kCounterDiv[201] = {32767, 16384, 10923, 8192, 6554, 5461, 4681, + 4096, 3641, 3277, 2979, 2731, 2521, 2341, 2185, 2048, 1928, 1820, 1725, 1638, 1560, + 1489, 1425, 1365, 1311, 1260, 1214, 1170, 1130, 1092, 1057, 1024, 993, 964, 936, 910, + 886, 862, 840, 819, 799, 780, 762, 745, 728, 712, 697, 683, 669, 655, 643, 630, 618, + 607, 596, 585, 575, 565, 555, 546, 537, 529, 520, 512, 504, 496, 489, 482, 475, 468, + 462, 455, 449, 443, 437, 431, 426, 420, 415, 410, 405, 400, 395, 390, 386, 381, 377, + 372, 368, 364, 360, 356, 352, 349, 345, 341, 338, 334, 331, 328, 324, 321, 318, 315, + 312, 309, 306, 303, 301, 298, 295, 293, 290, 287, 285, 282, 280, 278, 275, 273, 271, + 269, 266, 264, 262, 260, 258, 256, 254, 252, 250, 248, 246, 245, 243, 241, 239, 237, + 236, 234, 232, 231, 229, 228, 226, 224, 223, 221, 220, 218, 217, 216, 214, 213, 211, + 210, 209, 207, 206, 205, 204, 202, 201, 200, 199, 197, 196, 195, 194, 193, 192, 191, + 189, 188, 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, + 172, 172, 171, 170, 169, 168, 167, 166, 165, 165, 164, 163}; + +static const WebRtc_Word16 kLogTableFrac[256] = { + 0, 1, 3, 4, 6, 7, 9, 10, 11, 13, 14, 16, 17, 18, 20, 21, + 22, 24, 25, 26, 28, 29, 30, 32, 33, 34, 36, 37, 38, 40, 41, 42, + 44, 45, 46, 47, 49, 50, 51, 52, 54, 55, 56, 57, 59, 60, 61, 62, + 63, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 77, 78, 79, 80, 81, + 82, 84, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 178, + 179, 180, 181, 182, 183, 184, 185, 185, 186, 187, 188, 189, 190, 191, 192, 192, + 193, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 203, 203, 204, 205, 206, + 207, 208, 208, 209, 210, 211, 212, 212, 213, 214, 215, 216, 216, 217, 218, 219, + 220, 220, 221, 222, 223, 224, 224, 225, 226, 227, 228, 228, 229, 230, 231, 231, + 232, 233, 234, 234, 235, 236, 237, 238, 238, 239, 240, 241, 241, 242, 243, 244, + 244, 245, 246, 247, 247, 248, 249, 249, 250, 251, 252, 252, 253, 254, 255, 255 +}; + +static const WebRtc_Word16 kPowTableFrac[1024] = { + 0, 1, 1, 2, 3, 3, 4, 5, + 6, 6, 7, 8, 8, 9, 10, 10, + 11, 12, 13, 13, 14, 15, 15, 16, + 17, 17, 18, 19, 20, 20, 21, 22, + 22, 23, 24, 25, 25, 26, 27, 27, + 28, 29, 30, 30, 31, 32, 32, 33, + 34, 35, 35, 36, 37, 37, 38, 39, + 40, 40, 41, 42, 42, 43, 44, 45, + 45, 46, 47, 48, 48, 49, 50, 50, + 51, 52, 53, 53, 54, 55, 56, 56, + 57, 58, 58, 59, 60, 61, 61, 62, + 63, 64, 64, 65, 66, 67, 67, 68, + 69, 69, 70, 71, 72, 72, 73, 74, + 75, 75, 76, 77, 78, 78, 79, 80, + 81, 81, 82, 83, 84, 84, 85, 86, + 87, 87, 88, 89, 90, 90, 91, 92, + 93, 93, 94, 95, 96, 96, 97, 98, + 99, 100, 100, 101, 102, 103, 103, 104, + 105, 106, 106, 107, 108, 109, 109, 110, + 111, 112, 113, 113, 114, 115, 116, 116, + 117, 118, 119, 119, 120, 121, 122, 123, + 123, 124, 125, 126, 126, 127, 128, 129, + 130, 130, 131, 132, 133, 133, 134, 135, + 136, 137, 137, 138, 139, 140, 141, 141, + 142, 143, 144, 144, 145, 146, 147, 148, + 148, 149, 150, 151, 152, 152, 153, 154, + 155, 156, 156, 157, 158, 159, 160, 160, + 161, 162, 163, 164, 164, 165, 166, 167, + 168, 168, 169, 170, 171, 172, 173, 173, + 174, 175, 176, 177, 177, 178, 179, 180, + 181, 181, 182, 183, 184, 185, 186, 186, + 187, 188, 189, 190, 190, 191, 192, 193, + 194, 195, 195, 196, 197, 198, 199, 200, + 200, 201, 202, 203, 204, 205, 205, 206, + 207, 208, 209, 210, 210, 211, 212, 213, + 214, 215, 215, 216, 217, 218, 219, 220, + 220, 221, 222, 223, 224, 225, 225, 226, + 227, 228, 229, 230, 231, 231, 232, 233, + 234, 235, 236, 237, 237, 238, 239, 240, + 241, 242, 243, 243, 244, 245, 246, 247, + 248, 249, 249, 250, 251, 252, 253, 254, + 255, 255, 256, 257, 258, 259, 260, 261, + 262, 262, 263, 264, 265, 266, 267, 268, + 268, 269, 270, 271, 272, 273, 274, 275, + 276, 276, 277, 278, 279, 280, 281, 282, + 283, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 308, 309, 310, + 311, 312, 313, 314, 315, 316, 317, 318, + 318, 319, 320, 321, 322, 323, 324, 325, + 326, 327, 328, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 339, + 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, 383, 384, 385, + 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 405, 406, 407, 408, + 409, 410, 410, 411, 412, 413, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 426, 427, 428, 429, 430, 431, + 432, 433, 434, 435, 436, 437, 438, 439, + 440, 441, 442, 443, 444, 445, 446, 447, + 448, 449, 450, 451, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, + 496, 498, 499, 500, 501, 502, 503, 504, + 505, 506, 507, 508, 509, 510, 511, 512, + 513, 514, 515, 516, 517, 518, 519, 520, + 521, 522, 523, 525, 526, 527, 528, 529, + 530, 531, 532, 533, 534, 535, 536, 537, + 538, 539, 540, 541, 542, 544, 545, 546, + 547, 548, 549, 550, 551, 552, 553, 554, + 555, 556, 557, 558, 560, 561, 562, 563, + 564, 565, 566, 567, 568, 569, 570, 571, + 572, 574, 575, 576, 577, 578, 579, 580, + 581, 582, 583, 584, 585, 587, 588, 589, + 590, 591, 592, 593, 594, 595, 596, 597, + 599, 600, 601, 602, 603, 604, 605, 606, + 607, 608, 610, 611, 612, 613, 614, 615, + 616, 617, 618, 620, 621, 622, 623, 624, + 625, 626, 627, 628, 630, 631, 632, 633, + 634, 635, 636, 637, 639, 640, 641, 642, + 643, 644, 645, 646, 648, 649, 650, 651, + 652, 653, 654, 656, 657, 658, 659, 660, + 661, 662, 664, 665, 666, 667, 668, 669, + 670, 672, 673, 674, 675, 676, 677, 678, + 680, 681, 682, 683, 684, 685, 687, 688, + 689, 690, 691, 692, 693, 695, 696, 697, + 698, 699, 700, 702, 703, 704, 705, 706, + 708, 709, 710, 711, 712, 713, 715, 716, + 717, 718, 719, 720, 722, 723, 724, 725, + 726, 728, 729, 730, 731, 732, 733, 735, + 736, 737, 738, 739, 741, 742, 743, 744, + 745, 747, 748, 749, 750, 751, 753, 754, + 755, 756, 757, 759, 760, 761, 762, 763, + 765, 766, 767, 768, 770, 771, 772, 773, + 774, 776, 777, 778, 779, 780, 782, 783, + 784, 785, 787, 788, 789, 790, 792, 793, + 794, 795, 796, 798, 799, 800, 801, 803, + 804, 805, 806, 808, 809, 810, 811, 813, + 814, 815, 816, 818, 819, 820, 821, 823, + 824, 825, 826, 828, 829, 830, 831, 833, + 834, 835, 836, 838, 839, 840, 841, 843, + 844, 845, 846, 848, 849, 850, 851, 853, + 854, 855, 857, 858, 859, 860, 862, 863, + 864, 866, 867, 868, 869, 871, 872, 873, + 874, 876, 877, 878, 880, 881, 882, 883, + 885, 886, 887, 889, 890, 891, 893, 894, + 895, 896, 898, 899, 900, 902, 903, 904, + 906, 907, 908, 909, 911, 912, 913, 915, + 916, 917, 919, 920, 921, 923, 924, 925, + 927, 928, 929, 931, 932, 933, 935, 936, + 937, 938, 940, 941, 942, 944, 945, 946, + 948, 949, 950, 952, 953, 955, 956, 957, + 959, 960, 961, 963, 964, 965, 967, 968, + 969, 971, 972, 973, 975, 976, 977, 979, + 980, 981, 983, 984, 986, 987, 988, 990, + 991, 992, 994, 995, 996, 998, 999, 1001, + 1002, 1003, 1005, 1006, 1007, 1009, 1010, 1012, + 1013, 1014, 1016, 1017, 1018, 1020, 1021, 1023 +}; + +static const WebRtc_Word16 kIndicatorTable[17] = {0, 2017, 3809, 5227, 6258, 6963, 7424, 7718, + 7901, 8014, 8084, 8126, 8152, 8168, 8177, 8183, 8187}; + +// hybrib Hanning & flat window +static const WebRtc_Word16 kBlocks80w128x[128] = { + 0, 536, 1072, 1606, 2139, 2669, 3196, 3720, 4240, 4756, 5266, + 5771, 6270, 6762, 7246, 7723, 8192, 8652, 9102, 9543, 9974, 10394, + 10803, 11200, 11585, 11958, 12318, 12665, 12998, 13318, 13623, 13913, 14189, + 14449, 14694, 14924, 15137, 15334, 15515, 15679, 15826, 15956, 16069, 16165, + 16244, 16305, 16349, 16375, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16375, 16349, 16305, 16244, 16165, 16069, 15956, + 15826, 15679, 15515, 15334, 15137, 14924, 14694, 14449, 14189, 13913, 13623, + 13318, 12998, 12665, 12318, 11958, 11585, 11200, 10803, 10394, 9974, 9543, + 9102, 8652, 8192, 7723, 7246, 6762, 6270, 5771, 5266, 4756, 4240, + 3720, 3196, 2669, 2139, 1606, 1072, 536 +}; + +// hybrib Hanning & flat window +static const WebRtc_Word16 kBlocks160w256x[256] = { + 0, 268, 536, 804, 1072, 1339, 1606, 1872, + 2139, 2404, 2669, 2933, 3196, 3459, 3720, 3981, + 4240, 4499, 4756, 5012, 5266, 5520, 5771, 6021, + 6270, 6517, 6762, 7005, 7246, 7486, 7723, 7959, + 8192, 8423, 8652, 8878, 9102, 9324, 9543, 9760, + 9974, 10185, 10394, 10600, 10803, 11003, 11200, 11394, +11585, 11773, 11958, 12140, 12318, 12493, 12665, 12833, +12998, 13160, 13318, 13472, 13623, 13770, 13913, 14053, +14189, 14321, 14449, 14574, 14694, 14811, 14924, 15032, +15137, 15237, 15334, 15426, 15515, 15599, 15679, 15754, +15826, 15893, 15956, 16015, 16069, 16119, 16165, 16207, +16244, 16277, 16305, 16329, 16349, 16364, 16375, 16382, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, +16384, 16382, 16375, 16364, 16349, 16329, 16305, 16277, +16244, 16207, 16165, 16119, 16069, 16015, 15956, 15893, +15826, 15754, 15679, 15599, 15515, 15426, 15334, 15237, +15137, 15032, 14924, 14811, 14694, 14574, 14449, 14321, +14189, 14053, 13913, 13770, 13623, 13472, 13318, 13160, +12998, 12833, 12665, 12493, 12318, 12140, 11958, 11773, +11585, 11394, 11200, 11003, 10803, 10600, 10394, 10185, + 9974, 9760, 9543, 9324, 9102, 8878, 8652, 8423, + 8192, 7959, 7723, 7486, 7246, 7005, 6762, 6517, + 6270, 6021, 5771, 5520, 5266, 5012, 4756, 4499, + 4240, 3981, 3720, 3459, 3196, 2933, 2669, 2404, + 2139, 1872, 1606, 1339, 1072, 804, 536, 268 +}; + +// Gain factor table: Input value in Q8 and output value in Q13 +static const WebRtc_Word16 kFactor1Table[257] = { + 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8233, 8274, 8315, 8355, 8396, 8436, 8475, 8515, 8554, 8592, 8631, 8669, + 8707, 8745, 8783, 8820, 8857, 8894, 8931, 8967, 9003, 9039, 9075, 9111, 9146, 9181, + 9216, 9251, 9286, 9320, 9354, 9388, 9422, 9456, 9489, 9523, 9556, 9589, 9622, 9655, + 9687, 9719, 9752, 9784, 9816, 9848, 9879, 9911, 9942, 9973, 10004, 10035, 10066, + 10097, 10128, 10158, 10188, 10218, 10249, 10279, 10308, 10338, 10368, 10397, 10426, + 10456, 10485, 10514, 10543, 10572, 10600, 10629, 10657, 10686, 10714, 10742, 10770, + 10798, 10826, 10854, 10882, 10847, 10810, 10774, 10737, 10701, 10666, 10631, 10596, + 10562, 10527, 10494, 10460, 10427, 10394, 10362, 10329, 10297, 10266, 10235, 10203, + 10173, 10142, 10112, 10082, 10052, 10023, 9994, 9965, 9936, 9908, 9879, 9851, 9824, + 9796, 9769, 9742, 9715, 9689, 9662, 9636, 9610, 9584, 9559, 9534, 9508, 9484, 9459, + 9434, 9410, 9386, 9362, 9338, 9314, 9291, 9268, 9245, 9222, 9199, 9176, 9154, 9132, + 9110, 9088, 9066, 9044, 9023, 9002, 8980, 8959, 8939, 8918, 8897, 8877, 8857, 8836, + 8816, 8796, 8777, 8757, 8738, 8718, 8699, 8680, 8661, 8642, 8623, 8605, 8586, 8568, + 8550, 8532, 8514, 8496, 8478, 8460, 8443, 8425, 8408, 8391, 8373, 8356, 8339, 8323, + 8306, 8289, 8273, 8256, 8240, 8224, 8208, 8192 +}; + +// Gain factor table: Input value in Q8 and output value in Q13 +static const WebRtc_Word16 kFactor2Aggressiveness1[257] = { + 7577, 7577, 7577, 7577, 7577, 7577, + 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7577, 7596, 7614, 7632, + 7650, 7667, 7683, 7699, 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845, + 7858, 7871, 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016, + 8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, 8152, 8162, + 8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192 +}; + +// Gain factor table: Input value in Q8 and output value in Q13 +static const WebRtc_Word16 kFactor2Aggressiveness2[257] = { + 7270, 7270, 7270, 7270, 7270, 7306, + 7339, 7369, 7397, 7424, 7448, 7472, 7495, 7517, 7537, 7558, 7577, 7596, 7614, 7632, + 7650, 7667, 7683, 7699, 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845, + 7858, 7871, 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016, + 8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, 8152, 8162, + 8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192 +}; + +// Gain factor table: Input value in Q8 and output value in Q13 +static const WebRtc_Word16 kFactor2Aggressiveness3[257] = { + 7184, 7184, 7184, 7229, 7270, 7306, + 7339, 7369, 7397, 7424, 7448, 7472, 7495, 7517, 7537, 7558, 7577, 7596, 7614, 7632, + 7650, 7667, 7683, 7699, 7715, 7731, 7746, 7761, 7775, 7790, 7804, 7818, 7832, 7845, + 7858, 7871, 7884, 7897, 7910, 7922, 7934, 7946, 7958, 7970, 7982, 7993, 8004, 8016, + 8027, 8038, 8049, 8060, 8070, 8081, 8091, 8102, 8112, 8122, 8132, 8143, 8152, 8162, + 8172, 8182, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192 +}; + +// sum of log2(i) from table index to inst->anaLen2 in Q5 +// Note that the first table value is invalid, since log2(0) = -infinity +static const WebRtc_Word16 kSumLogIndex[66] = { + 0, 22917, 22917, 22885, 22834, 22770, 22696, 22613, + 22524, 22428, 22326, 22220, 22109, 21994, 21876, 21754, + 21629, 21501, 21370, 21237, 21101, 20963, 20822, 20679, + 20535, 20388, 20239, 20089, 19937, 19783, 19628, 19470, + 19312, 19152, 18991, 18828, 18664, 18498, 18331, 18164, + 17994, 17824, 17653, 17480, 17306, 17132, 16956, 16779, + 16602, 16423, 16243, 16063, 15881, 15699, 15515, 15331, + 15146, 14960, 14774, 14586, 14398, 14209, 14019, 13829, + 13637, 13445 +}; + +// sum of log2(i)^2 from table index to inst->anaLen2 in Q2 +// Note that the first table value is invalid, since log2(0) = -infinity +static const WebRtc_Word16 kSumSquareLogIndex[66] = { + 0, 16959, 16959, 16955, 16945, 16929, 16908, 16881, + 16850, 16814, 16773, 16729, 16681, 16630, 16575, 16517, + 16456, 16392, 16325, 16256, 16184, 16109, 16032, 15952, + 15870, 15786, 15700, 15612, 15521, 15429, 15334, 15238, + 15140, 15040, 14938, 14834, 14729, 14622, 14514, 14404, + 14292, 14179, 14064, 13947, 13830, 13710, 13590, 13468, + 13344, 13220, 13094, 12966, 12837, 12707, 12576, 12444, + 12310, 12175, 12039, 11902, 11763, 11624, 11483, 11341, + 11198, 11054 +}; + +// log2(table index) in Q12 +// Note that the first table value is invalid, since log2(0) = -infinity +static const WebRtc_Word16 kLogIndex[129] = { + 0, 0, 4096, 6492, 8192, 9511, 10588, 11499, + 12288, 12984, 13607, 14170, 14684, 15157, 15595, 16003, + 16384, 16742, 17080, 17400, 17703, 17991, 18266, 18529, + 18780, 19021, 19253, 19476, 19691, 19898, 20099, 20292, + 20480, 20662, 20838, 21010, 21176, 21338, 21496, 21649, + 21799, 21945, 22087, 22226, 22362, 22495, 22625, 22752, + 22876, 22998, 23117, 23234, 23349, 23462, 23572, 23680, + 23787, 23892, 23994, 24095, 24195, 24292, 24388, 24483, + 24576, 24668, 24758, 24847, 24934, 25021, 25106, 25189, + 25272, 25354, 25434, 25513, 25592, 25669, 25745, 25820, + 25895, 25968, 26041, 26112, 26183, 26253, 26322, 26390, + 26458, 26525, 26591, 26656, 26721, 26784, 26848, 26910, + 26972, 27033, 27094, 27154, 27213, 27272, 27330, 27388, + 27445, 27502, 27558, 27613, 27668, 27722, 27776, 27830, + 27883, 27935, 27988, 28039, 28090, 28141, 28191, 28241, + 28291, 28340, 28388, 28437, 28484, 28532, 28579, 28626, + 28672 +}; + +// determinant of estimation matrix in Q0 corresponding to the log2 tables above +// Note that the first table value is invalid, since log2(0) = -infinity +static const WebRtc_Word16 kDeterminantEstMatrix[66] = { + 0, 29814, 25574, 22640, 20351, 18469, 16873, 15491, + 14277, 13199, 12233, 11362, 10571, 9851, 9192, 8587, + 8030, 7515, 7038, 6596, 6186, 5804, 5448, 5115, + 4805, 4514, 4242, 3988, 3749, 3524, 3314, 3116, + 2930, 2755, 2590, 2435, 2289, 2152, 2022, 1900, + 1785, 1677, 1575, 1478, 1388, 1302, 1221, 1145, + 1073, 1005, 942, 881, 825, 771, 721, 674, + 629, 587, 547, 510, 475, 442, 411, 382, + 355, 330 +}; + +void WebRtcNsx_UpdateNoiseEstimate(NsxInst_t *inst, int offset) +{ + WebRtc_Word32 tmp32no1 = 0; + WebRtc_Word32 tmp32no2 = 0; + + WebRtc_Word16 tmp16no1 = 0; + WebRtc_Word16 tmp16no2 = 0; + WebRtc_Word16 exp2Const = 11819; // Q13 + + int i = 0; + + tmp16no2 = WebRtcSpl_MaxValueW16(inst->noiseEstLogQuantile + offset, inst->magnLen); + inst->qNoise = 14 + - (int)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(exp2Const, tmp16no2, 21); + for (i = 0; i < inst->magnLen; i++) + { + // inst->quantile[i]=exp(inst->lquantile[offset+i]); + // in Q21 + tmp32no2 = WEBRTC_SPL_MUL_16_16(exp2Const, inst->noiseEstLogQuantile[offset + i]); + tmp32no1 = (0x00200000 | (tmp32no2 & 0x001FFFFF)); + tmp16no1 = -(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no2, 21); + tmp16no1 += 21;// shift 21 to get result in Q0 + tmp16no1 -= (WebRtc_Word16)inst->qNoise; //shift to get result in Q(qNoise) + if (tmp16no1 > 0) + { + inst->noiseEstQuantile[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no1 + + kRoundTable[tmp16no1], tmp16no1); + } + else + { + inst->noiseEstQuantile[i] = (WebRtc_Word16)WEBRTC_SPL_LSHIFT_W32(tmp32no1, + -tmp16no1); + } + } +} + +void WebRtcNsx_CalcParametricNoiseEstimate(NsxInst_t *inst, + WebRtc_Word16 pink_noise_exp_avg, + WebRtc_Word32 pink_noise_num_avg, + int freq_index, + WebRtc_UWord32 *noise_estimate, + WebRtc_UWord32 *noise_estimate_avg) +{ + WebRtc_Word32 tmp32no1 = 0; + WebRtc_Word32 tmp32no2 = 0; + + WebRtc_Word16 int_part = 0; + WebRtc_Word16 frac_part = 0; + + // Use pink noise estimate + // noise_estimate = 2^(pinkNoiseNumerator + pinkNoiseExp * log2(j)) + assert(freq_index > 0); + tmp32no2 = WEBRTC_SPL_MUL_16_16(pink_noise_exp_avg, kLogIndex[freq_index]); // Q26 + tmp32no2 = WEBRTC_SPL_RSHIFT_W32(tmp32no2, 15); // Q11 + tmp32no1 = pink_noise_num_avg - tmp32no2; // Q11 + + // Calculate output: 2^tmp32no1 + // Output in Q(minNorm-stages) + tmp32no1 += WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)(inst->minNorm - inst->stages), 11); + if (tmp32no1 > 0) + { + int_part = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no1, 11); + frac_part = (WebRtc_Word16)(tmp32no1 & 0x000007ff); // Q11 + // Piecewise linear approximation of 'b' in + // 2^(int_part+frac_part) = 2^int_part * (1 + b) + // 'b' is given in Q11 and below stored in frac_part. + if (WEBRTC_SPL_RSHIFT_W32(frac_part, 10)) + { + // Upper fractional part + tmp32no2 = WEBRTC_SPL_MUL_32_16(2048 - frac_part, 1244); // Q21 + tmp32no2 = 2048 - WEBRTC_SPL_RSHIFT_W32(tmp32no2, 10); + } + else + { + // Lower fractional part + tmp32no2 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_32_16(frac_part, 804), 10); + } + // Shift fractional part to Q(minNorm-stages) + tmp32no2 = WEBRTC_SPL_SHIFT_W32(tmp32no2, int_part - 11); + *noise_estimate_avg = WEBRTC_SPL_LSHIFT_U32(1, int_part) + (WebRtc_UWord32)tmp32no2; + // Scale up to initMagnEst, which is not block averaged + *noise_estimate = (*noise_estimate_avg) * (WebRtc_UWord32)(inst->blockIndex + 1); + } +} + +// Initialize state +WebRtc_Word32 WebRtcNsx_InitCore(NsxInst_t *inst, WebRtc_UWord32 fs) +{ + int i; + + //check for valid pointer + if (inst == NULL) + { + return -1; + } + // + + // Initialization of struct + if (fs == 8000 || fs == 16000 || fs == 32000) + { + inst->fs = fs; + } else + { + return -1; + } + + if (fs == 8000) + { + inst->blockLen10ms = 80; + inst->anaLen = 128; + inst->stages = 7; + inst->window = kBlocks80w128x; + inst->thresholdLogLrt = 131072; //default threshold for LRT feature + inst->maxLrt = 0x0040000; + inst->minLrt = 52429; + } else if (fs == 16000) + { + inst->blockLen10ms = 160; + inst->anaLen = 256; + inst->stages = 8; + inst->window = kBlocks160w256x; + inst->thresholdLogLrt = 212644; //default threshold for LRT feature + inst->maxLrt = 0x0080000; + inst->minLrt = 104858; + } else if (fs == 32000) + { + inst->blockLen10ms = 160; + inst->anaLen = 256; + inst->stages = 8; + inst->window = kBlocks160w256x; + inst->thresholdLogLrt = 212644; //default threshold for LRT feature + inst->maxLrt = 0x0080000; + inst->minLrt = 104858; + } + inst->anaLen2 = WEBRTC_SPL_RSHIFT_W16(inst->anaLen, 1); + inst->magnLen = inst->anaLen2 + 1; + + WebRtcSpl_ZerosArrayW16(inst->analysisBuffer, ANAL_BLOCKL_MAX); + WebRtcSpl_ZerosArrayW16(inst->synthesisBuffer, ANAL_BLOCKL_MAX); + + // for HB processing + WebRtcSpl_ZerosArrayW16(inst->dataBufHBFX, ANAL_BLOCKL_MAX); + // for quantile noise estimation + WebRtcSpl_ZerosArrayW16(inst->noiseEstQuantile, HALF_ANAL_BLOCKL); + for (i = 0; i < SIMULT * HALF_ANAL_BLOCKL; i++) + { + inst->noiseEstLogQuantile[i] = 2048; // Q8 + inst->noiseEstDensity[i] = 153; // Q9 + } + for (i = 0; i < SIMULT; i++) + { + inst->noiseEstCounter[i] = (WebRtc_Word16)(END_STARTUP_LONG * (i + 1)) / SIMULT; + } + + // Initialize suppression filter with ones + WebRtcSpl_MemSetW16((WebRtc_Word16*)inst->noiseSupFilter, 16384, HALF_ANAL_BLOCKL); + + // Set the aggressiveness: default + inst->aggrMode = 0; + + //initialize variables for new method + inst->priorNonSpeechProb = 8192; // Q14(0.5) prior probability for speech/noise + for (i = 0; i < HALF_ANAL_BLOCKL; i++) + { + inst->prevMagnU16[i] = 0; + inst->prevNoiseU32[i] = 0; //previous noise-spectrum + inst->logLrtTimeAvgW32[i] = 0; //smooth LR ratio + inst->avgMagnPause[i] = 0; //conservative noise spectrum estimate + inst->initMagnEst[i] = 0; //initial average magnitude spectrum + } + + //feature quantities + inst->thresholdSpecDiff = 50; //threshold for difference feature: determined on-line + inst->thresholdSpecFlat = 20480; //threshold for flatness: determined on-line + inst->featureLogLrt = inst->thresholdLogLrt; //average LRT factor (= threshold) + inst->featureSpecFlat = inst->thresholdSpecFlat; //spectral flatness (= threshold) + inst->featureSpecDiff = inst->thresholdSpecDiff; //spectral difference (= threshold) + inst->weightLogLrt = 6; //default weighting par for LRT feature + inst->weightSpecFlat = 0; //default weighting par for spectral flatness feature + inst->weightSpecDiff = 0; //default weighting par for spectral difference feature + + inst->curAvgMagnEnergy = 0; //window time-average of input magnitude spectrum + inst->timeAvgMagnEnergy = 0; //normalization for spectral difference + inst->timeAvgMagnEnergyTmp = 0; //normalization for spectral difference + + //histogram quantities: used to estimate/update thresholds for features + WebRtcSpl_ZerosArrayW16(inst->histLrt, HIST_PAR_EST); + WebRtcSpl_ZerosArrayW16(inst->histSpecDiff, HIST_PAR_EST); + WebRtcSpl_ZerosArrayW16(inst->histSpecFlat, HIST_PAR_EST); + + inst->blockIndex = -1; //frame counter + + //inst->modelUpdate = 500; //window for update + inst->modelUpdate = (1 << STAT_UPDATES); //window for update + inst->cntThresUpdate = 0; //counter feature thresholds updates + + inst->sumMagn = 0; + inst->magnEnergy = 0; + inst->prevQMagn = 0; + inst->qNoise = 0; + inst->prevQNoise = 0; + + inst->energyIn = 0; + inst->scaleEnergyIn = 0; + + inst->whiteNoiseLevel = 0; + inst->pinkNoiseNumerator = 0; + inst->pinkNoiseExp = 0; + inst->minNorm = 15; // Start with full scale + inst->zeroInputSignal = 0; + + //default mode + WebRtcNsx_set_policy_core(inst, 0); + +#ifdef NS_FILEDEBUG + inst->infile=fopen("indebug.pcm","wb"); + inst->outfile=fopen("outdebug.pcm","wb"); + inst->file1=fopen("file1.pcm","wb"); + inst->file2=fopen("file2.pcm","wb"); + inst->file3=fopen("file3.pcm","wb"); + inst->file4=fopen("file4.pcm","wb"); + inst->file5=fopen("file5.pcm","wb"); +#endif + + inst->initFlag = 1; + + return 0; +} + +int WebRtcNsx_set_policy_core(NsxInst_t *inst, int mode) +{ + // allow for modes:0,1,2,3 + if (mode < 0 || mode > 3) + { + return -1; + } + + inst->aggrMode = mode; + if (mode == 0) + { + inst->overdrive = 256; // Q8(1.0) + inst->denoiseBound = 8192; // Q14(0.5) + inst->gainMap = 0; // No gain compensation + } else if (mode == 1) + { + inst->overdrive = 256; // Q8(1.0) + inst->denoiseBound = 4096; // Q14(0.25) + inst->factor2Table = kFactor2Aggressiveness1; + inst->gainMap = 1; + } else if (mode == 2) + { + inst->overdrive = 282; // ~= Q8(1.1) + inst->denoiseBound = 2048; // Q14(0.125) + inst->factor2Table = kFactor2Aggressiveness2; + inst->gainMap = 1; + } else if (mode == 3) + { + inst->overdrive = 320; // Q8(1.25) + inst->denoiseBound = 1475; // ~= Q14(0.09) + inst->factor2Table = kFactor2Aggressiveness3; + inst->gainMap = 1; + } + return 0; +} + +void WebRtcNsx_NoiseEstimation(NsxInst_t *inst, WebRtc_UWord16 *magn, WebRtc_UWord32 *noise, + WebRtc_Word16 *qNoise) +{ + WebRtc_Word32 numerator; + + WebRtc_Word16 lmagn[HALF_ANAL_BLOCKL], counter, countDiv, countProd, delta, zeros, frac; + WebRtc_Word16 log2, tabind, logval, tmp16, tmp16no1, tmp16no2; + WebRtc_Word16 log2Const = 22713; // Q15 + WebRtc_Word16 widthFactor = 21845; + + int i, s, offset; + + numerator = FACTOR_Q16; + + tabind = inst->stages - inst->normData; + if (tabind < 0) + { + logval = -kLogTable[-tabind]; + } else + { + logval = kLogTable[tabind]; + } + + // lmagn(i)=log(magn(i))=log(2)*log2(magn(i)) + // magn is in Q(-stages), and the real lmagn values are: + // real_lmagn(i)=log(magn(i)*2^stages)=log(magn(i))+log(2^stages) + // lmagn in Q8 + for (i = 0; i < inst->magnLen; i++) + { + if (magn[i]) + { + zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magn[i]); + frac = (WebRtc_Word16)((((WebRtc_UWord32)magn[i] << zeros) & 0x7FFFFFFF) >> 23); + // log2(magn(i)) + log2 = (WebRtc_Word16)(((31 - zeros) << 8) + kLogTableFrac[frac]); + // log2(magn(i))*log(2) + lmagn[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(log2, log2Const, 15); + // + log(2^stages) + lmagn[i] += logval; + } else + { + lmagn[i] = logval;//0; + } + } + + // loop over simultaneous estimates + for (s = 0; s < SIMULT; s++) + { + offset = s * inst->magnLen; + + // Get counter values from state + counter = inst->noiseEstCounter[s]; + countDiv = kCounterDiv[counter]; + countProd = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(counter, countDiv); + + // quant_est(...) + for (i = 0; i < inst->magnLen; i++) + { + // compute delta + if (inst->noiseEstDensity[offset + i] > 512) + { + delta = WebRtcSpl_DivW32W16ResW16(numerator, + inst->noiseEstDensity[offset + i]); + } else + { + delta = FACTOR_Q7; + } + + // update log quantile estimate + tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(delta, countDiv, 14); + if (lmagn[i] > inst->noiseEstLogQuantile[offset + i]) + { + // +=QUANTILE*delta/(inst->counter[s]+1) QUANTILE=0.25, =1 in Q2 + // CounterDiv=1/inst->counter[s] in Q15 + tmp16 += 2; + tmp16no1 = WEBRTC_SPL_RSHIFT_W16(tmp16, 2); + inst->noiseEstLogQuantile[offset + i] += tmp16no1; + } else + { + tmp16 += 1; + tmp16no1 = WEBRTC_SPL_RSHIFT_W16(tmp16, 1); + // *(1-QUANTILE), in Q2 QUANTILE=0.25, 1-0.25=0.75=3 in Q2 + tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16no1, 3, 1); + inst->noiseEstLogQuantile[offset + i] -= tmp16no2; + } + + // update density estimate + if (WEBRTC_SPL_ABS_W16(lmagn[i] - inst->noiseEstLogQuantile[offset + i]) + < WIDTH_Q8) + { + tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND( + inst->noiseEstDensity[offset + i], countProd, 15); + tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(widthFactor, + countDiv, 15); + inst->noiseEstDensity[offset + i] = tmp16no1 + tmp16no2; + } + } // end loop over magnitude spectrum + + if (counter >= END_STARTUP_LONG) + { + inst->noiseEstCounter[s] = 0; + if (inst->blockIndex >= END_STARTUP_LONG) + { + WebRtcNsx_UpdateNoiseEstimate(inst, offset); + } + } + inst->noiseEstCounter[s]++; + + } // end loop over simultaneous estimates + + // Sequentially update the noise during startup + if (inst->blockIndex < END_STARTUP_LONG) + { + WebRtcNsx_UpdateNoiseEstimate(inst, offset); + } + + for (i = 0; i < inst->magnLen; i++) + { + noise[i] = (WebRtc_UWord32)(inst->noiseEstQuantile[i]); // Q(qNoise) + } + (*qNoise) = (WebRtc_Word16)inst->qNoise; +} + +// Extract thresholds for feature parameters +// histograms are computed over some window_size (given by window_pars) +// thresholds and weights are extracted every window +// flag 0 means update histogram only, flag 1 means compute the thresholds/weights +// threshold and weights are returned in: inst->priorModelPars +void WebRtcNsx_FeatureParameterExtraction(NsxInst_t *inst, int flag) +{ + WebRtc_UWord32 tmpU32; + WebRtc_UWord32 histIndex; + WebRtc_UWord32 posPeak1SpecFlatFX, posPeak2SpecFlatFX; + WebRtc_UWord32 posPeak1SpecDiffFX, posPeak2SpecDiffFX; + + WebRtc_Word32 tmp32; + WebRtc_Word32 fluctLrtFX, thresFluctLrtFX; + WebRtc_Word32 avgHistLrtFX, avgSquareHistLrtFX, avgHistLrtComplFX; + + WebRtc_Word16 j; + WebRtc_Word16 numHistLrt; + + int i; + int useFeatureSpecFlat, useFeatureSpecDiff, featureSum; + int maxPeak1, maxPeak2; + int weightPeak1SpecFlat, weightPeak2SpecFlat; + int weightPeak1SpecDiff, weightPeak2SpecDiff; + + //update histograms + if (!flag) + { + // LRT + // Type casting to UWord32 is safe since negative values will not be wrapped to larger + // values than HIST_PAR_EST + histIndex = (WebRtc_UWord32)(inst->featureLogLrt); + if (histIndex < HIST_PAR_EST) + { + inst->histLrt[histIndex]++; + } + // Spectral flatness + // (inst->featureSpecFlat*20)>>10 = (inst->featureSpecFlat*5)>>8 + histIndex = WEBRTC_SPL_RSHIFT_U32(inst->featureSpecFlat * 5, 8); + if (histIndex < HIST_PAR_EST) + { + inst->histSpecFlat[histIndex]++; + } + // Spectral difference + histIndex = HIST_PAR_EST; + if (inst->timeAvgMagnEnergy) + { + // Guard against division by zero + // If timeAvgMagnEnergy == 0 we have no normalizing statistics and therefore can't + // update the histogram + histIndex = WEBRTC_SPL_UDIV((inst->featureSpecDiff * 5) >> inst->stages, + inst->timeAvgMagnEnergy); + } + if (histIndex < HIST_PAR_EST) + { + inst->histSpecDiff[histIndex]++; + } + } + + // extract parameters for speech/noise probability + if (flag) + { + useFeatureSpecDiff = 1; + //for LRT feature: + // compute the average over inst->featureExtractionParams.rangeAvgHistLrt + avgHistLrtFX = 0; + avgSquareHistLrtFX = 0; + numHistLrt = 0; + for (i = 0; i < BIN_SIZE_LRT; i++) + { + j = (2 * i + 1); + tmp32 = WEBRTC_SPL_MUL_16_16(inst->histLrt[i], j); + avgHistLrtFX += tmp32; + numHistLrt += inst->histLrt[i]; + avgSquareHistLrtFX += WEBRTC_SPL_MUL_32_16(tmp32, j); + } + avgHistLrtComplFX = avgHistLrtFX; + for (; i < HIST_PAR_EST; i++) + { + j = (2 * i + 1); + tmp32 = WEBRTC_SPL_MUL_16_16(inst->histLrt[i], j); + avgHistLrtComplFX += tmp32; + avgSquareHistLrtFX += WEBRTC_SPL_MUL_32_16(tmp32, j); + } + fluctLrtFX = WEBRTC_SPL_MUL(avgSquareHistLrtFX, numHistLrt); + fluctLrtFX -= WEBRTC_SPL_MUL(avgHistLrtFX, avgHistLrtComplFX); + thresFluctLrtFX = THRES_FLUCT_LRT * numHistLrt; + // get threshold for LRT feature: + tmpU32 = (FACTOR_1_LRT_DIFF * (WebRtc_UWord32)avgHistLrtFX); + if ((fluctLrtFX < thresFluctLrtFX) || (numHistLrt == 0) || (tmpU32 + > (WebRtc_UWord32)(100 * numHistLrt))) + { + inst->thresholdLogLrt = inst->maxLrt; //very low fluctuation, so likely noise + } else + { + tmp32 = (WebRtc_Word32)((tmpU32 << (9 + inst->stages)) / numHistLrt / 25); + // check if value is within min/max range + inst->thresholdLogLrt = WEBRTC_SPL_SAT(inst->maxLrt, tmp32, inst->minLrt); + } + if (fluctLrtFX < thresFluctLrtFX) + { + // Do not use difference feature if fluctuation of LRT feature is very low: + // most likely just noise state + useFeatureSpecDiff = 0; + } + + // for spectral flatness and spectral difference: compute the main peaks of histogram + maxPeak1 = 0; + maxPeak2 = 0; + posPeak1SpecFlatFX = 0; + posPeak2SpecFlatFX = 0; + weightPeak1SpecFlat = 0; + weightPeak2SpecFlat = 0; + + // peaks for flatness + for (i = 0; i < HIST_PAR_EST; i++) + { + if (inst->histSpecFlat[i] > maxPeak1) + { + // Found new "first" peak + maxPeak2 = maxPeak1; + weightPeak2SpecFlat = weightPeak1SpecFlat; + posPeak2SpecFlatFX = posPeak1SpecFlatFX; + + maxPeak1 = inst->histSpecFlat[i]; + weightPeak1SpecFlat = inst->histSpecFlat[i]; + posPeak1SpecFlatFX = (WebRtc_UWord32)(2 * i + 1); + } else if (inst->histSpecFlat[i] > maxPeak2) + { + // Found new "second" peak + maxPeak2 = inst->histSpecFlat[i]; + weightPeak2SpecFlat = inst->histSpecFlat[i]; + posPeak2SpecFlatFX = (WebRtc_UWord32)(2 * i + 1); + } + } + + // for spectral flatness feature + useFeatureSpecFlat = 1; + // merge the two peaks if they are close + if ((posPeak1SpecFlatFX - posPeak2SpecFlatFX < LIM_PEAK_SPACE_FLAT_DIFF) + && (weightPeak2SpecFlat * LIM_PEAK_WEIGHT_FLAT_DIFF > weightPeak1SpecFlat)) + { + weightPeak1SpecFlat += weightPeak2SpecFlat; + posPeak1SpecFlatFX = (posPeak1SpecFlatFX + posPeak2SpecFlatFX) >> 1; + } + //reject if weight of peaks is not large enough, or peak value too small + if (weightPeak1SpecFlat < THRES_WEIGHT_FLAT_DIFF || posPeak1SpecFlatFX + < THRES_PEAK_FLAT) + { + useFeatureSpecFlat = 0; + } else // if selected, get the threshold + { + // compute the threshold and check if value is within min/max range + inst->thresholdSpecFlat = WEBRTC_SPL_SAT(MAX_FLAT_Q10, FACTOR_2_FLAT_Q10 + * posPeak1SpecFlatFX, MIN_FLAT_Q10); //Q10 + } + // done with flatness feature + + if (useFeatureSpecDiff) + { + //compute two peaks for spectral difference + maxPeak1 = 0; + maxPeak2 = 0; + posPeak1SpecDiffFX = 0; + posPeak2SpecDiffFX = 0; + weightPeak1SpecDiff = 0; + weightPeak2SpecDiff = 0; + // peaks for spectral difference + for (i = 0; i < HIST_PAR_EST; i++) + { + if (inst->histSpecDiff[i] > maxPeak1) + { + // Found new "first" peak + maxPeak2 = maxPeak1; + weightPeak2SpecDiff = weightPeak1SpecDiff; + posPeak2SpecDiffFX = posPeak1SpecDiffFX; + + maxPeak1 = inst->histSpecDiff[i]; + weightPeak1SpecDiff = inst->histSpecDiff[i]; + posPeak1SpecDiffFX = (WebRtc_UWord32)(2 * i + 1); + } else if (inst->histSpecDiff[i] > maxPeak2) + { + // Found new "second" peak + maxPeak2 = inst->histSpecDiff[i]; + weightPeak2SpecDiff = inst->histSpecDiff[i]; + posPeak2SpecDiffFX = (WebRtc_UWord32)(2 * i + 1); + } + } + + // merge the two peaks if they are close + if ((posPeak1SpecDiffFX - posPeak2SpecDiffFX < LIM_PEAK_SPACE_FLAT_DIFF) + && (weightPeak2SpecDiff * LIM_PEAK_WEIGHT_FLAT_DIFF > weightPeak1SpecDiff)) + { + weightPeak1SpecDiff += weightPeak2SpecDiff; + posPeak1SpecDiffFX = (posPeak1SpecDiffFX + posPeak2SpecDiffFX) >> 1; + } + // get the threshold value and check if value is within min/max range + inst->thresholdSpecDiff = WEBRTC_SPL_SAT(MAX_DIFF, FACTOR_1_LRT_DIFF + * posPeak1SpecDiffFX, MIN_DIFF); //5x bigger + //reject if weight of peaks is not large enough + if (weightPeak1SpecDiff < THRES_WEIGHT_FLAT_DIFF) + { + useFeatureSpecDiff = 0; + } + // done with spectral difference feature + } + + // select the weights between the features + // inst->priorModelPars[4] is weight for LRT: always selected + featureSum = 6 / (1 + useFeatureSpecFlat + useFeatureSpecDiff); + inst->weightLogLrt = featureSum; + inst->weightSpecFlat = useFeatureSpecFlat * featureSum; + inst->weightSpecDiff = useFeatureSpecDiff * featureSum; + + // set histograms to zero for next update + WebRtcSpl_ZerosArrayW16(inst->histLrt, HIST_PAR_EST); + WebRtcSpl_ZerosArrayW16(inst->histSpecDiff, HIST_PAR_EST); + WebRtcSpl_ZerosArrayW16(inst->histSpecFlat, HIST_PAR_EST); + } // end of flag == 1 +} + + +// Compute spectral flatness on input spectrum +// magn is the magnitude spectrum +// spectral flatness is returned in inst->featureSpecFlat +void WebRtcNsx_ComputeSpectralFlatness(NsxInst_t *inst, WebRtc_UWord16 *magn) +{ + WebRtc_UWord32 tmpU32; + WebRtc_UWord32 avgSpectralFlatnessNum, avgSpectralFlatnessDen; + + WebRtc_Word32 tmp32; + WebRtc_Word32 currentSpectralFlatness, logCurSpectralFlatness; + + WebRtc_Word16 zeros, frac, intPart; + + int i; + + // for flatness + avgSpectralFlatnessNum = 0; + avgSpectralFlatnessDen = inst->sumMagn - (WebRtc_UWord32)magn[0]; // Q(normData-stages) + + // compute log of ratio of the geometric to arithmetic mean: check for log(0) case + // flatness = exp( sum(log(magn[i]))/N - log(sum(magn[i])/N) ) + // = exp( sum(log(magn[i]))/N ) * N / sum(magn[i]) + // = 2^( sum(log2(magn[i]))/N - (log2(sum(magn[i])) - log2(N)) ) [This is used] + for (i = 1; i < inst->magnLen; i++) + { + // First bin is excluded from spectrum measures. Number of bins is now a power of 2 + if (magn[i]) + { + zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magn[i]); + frac = (WebRtc_Word16)(((WebRtc_UWord32)((WebRtc_UWord32)(magn[i]) << zeros) + & 0x7FFFFFFF) >> 23); + // log2(magn(i)) + tmpU32 = (WebRtc_UWord32)(((31 - zeros) << 8) + kLogTableFrac[frac]); // Q8 + avgSpectralFlatnessNum += tmpU32; // Q8 + } else + { + //if at least one frequency component is zero, treat separately + tmpU32 = WEBRTC_SPL_UMUL_32_16(inst->featureSpecFlat, SPECT_FLAT_TAVG_Q14); // Q24 + inst->featureSpecFlat -= WEBRTC_SPL_RSHIFT_U32(tmpU32, 14); // Q10 + return; + } + } + //ratio and inverse log: check for case of log(0) + zeros = WebRtcSpl_NormU32(avgSpectralFlatnessDen); + frac = (WebRtc_Word16)(((avgSpectralFlatnessDen << zeros) & 0x7FFFFFFF) >> 23); + // log2(avgSpectralFlatnessDen) + tmp32 = (WebRtc_Word32)(((31 - zeros) << 8) + kLogTableFrac[frac]); // Q8 + logCurSpectralFlatness = (WebRtc_Word32)avgSpectralFlatnessNum; + logCurSpectralFlatness += ((WebRtc_Word32)(inst->stages - 1) << (inst->stages + 7)); // Q(8+stages-1) + logCurSpectralFlatness -= (tmp32 << (inst->stages - 1)); + logCurSpectralFlatness = WEBRTC_SPL_LSHIFT_W32(logCurSpectralFlatness, 10 - inst->stages); // Q17 + tmp32 = (WebRtc_Word32)(0x00020000 | (WEBRTC_SPL_ABS_W32(logCurSpectralFlatness) + & 0x0001FFFF)); //Q17 + intPart = -(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(logCurSpectralFlatness, 17); + intPart += 7; // Shift 7 to get the output in Q10 (from Q17 = -17+10) + if (intPart > 0) + { + currentSpectralFlatness = WEBRTC_SPL_RSHIFT_W32(tmp32, intPart); + } else + { + currentSpectralFlatness = WEBRTC_SPL_LSHIFT_W32(tmp32, -intPart); + } + + //time average update of spectral flatness feature + tmp32 = currentSpectralFlatness - (WebRtc_Word32)inst->featureSpecFlat; // Q10 + tmp32 = WEBRTC_SPL_MUL_32_16(SPECT_FLAT_TAVG_Q14, tmp32); // Q24 + inst->featureSpecFlat = (WebRtc_UWord32)((WebRtc_Word32)inst->featureSpecFlat + + WEBRTC_SPL_RSHIFT_W32(tmp32, 14)); // Q10 + // done with flatness feature +} + + +// Compute the difference measure between input spectrum and a template/learned noise spectrum +// magn_tmp is the input spectrum +// the reference/template spectrum is inst->magn_avg_pause[i] +// returns (normalized) spectral difference in inst->featureSpecDiff +void WebRtcNsx_ComputeSpectralDifference(NsxInst_t *inst, WebRtc_UWord16 *magnIn) +{ + // This is to be calculated: + // avgDiffNormMagn = var(magnIn) - cov(magnIn, magnAvgPause)^2 / var(magnAvgPause) + + WebRtc_UWord32 tmpU32no1, tmpU32no2; + WebRtc_UWord32 varMagnUFX, varPauseUFX, avgDiffNormMagnUFX; + + WebRtc_Word32 tmp32no1, tmp32no2; + WebRtc_Word32 avgPauseFX, avgMagnFX, covMagnPauseFX; + WebRtc_Word32 maxPause, minPause; + + WebRtc_Word16 tmp16no1; + + int i, norm32, nShifts; + + avgPauseFX = 0; + maxPause = 0; + minPause = inst->avgMagnPause[0]; // Q(prevQMagn) + // compute average quantities + for (i = 0; i < inst->magnLen; i++) + { + // Compute mean of magn_pause + avgPauseFX += inst->avgMagnPause[i]; // in Q(prevQMagn) + maxPause = WEBRTC_SPL_MAX(maxPause, inst->avgMagnPause[i]); + minPause = WEBRTC_SPL_MIN(minPause, inst->avgMagnPause[i]); + } + // normalize by replacing div of "inst->magnLen" with "inst->stages-1" shifts + avgPauseFX = WEBRTC_SPL_RSHIFT_W32(avgPauseFX, inst->stages - 1); + avgMagnFX = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_U32(inst->sumMagn, inst->stages - 1); + // Largest possible deviation in magnPause for (co)var calculations + tmp32no1 = WEBRTC_SPL_MAX(maxPause - avgPauseFX, avgPauseFX - minPause); + // Get number of shifts to make sure we don't get wrap around in varPause + nShifts = WEBRTC_SPL_MAX(0, 10 + inst->stages - WebRtcSpl_NormW32(tmp32no1)); + + varMagnUFX = 0; + varPauseUFX = 0; + covMagnPauseFX = 0; + for (i = 0; i < inst->magnLen; i++) + { + // Compute var and cov of magn and magn_pause + tmp16no1 = (WebRtc_Word16)((WebRtc_Word32)magnIn[i] - avgMagnFX); + tmp32no2 = inst->avgMagnPause[i] - avgPauseFX; + varMagnUFX += (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(tmp16no1, tmp16no1); // Q(2*qMagn) + tmp32no1 = WEBRTC_SPL_MUL_32_16(tmp32no2, tmp16no1); // Q(prevQMagn+qMagn) + covMagnPauseFX += tmp32no1; // Q(prevQMagn+qMagn) + tmp32no1 = WEBRTC_SPL_RSHIFT_W32(tmp32no2, nShifts); // Q(prevQMagn-minPause) + varPauseUFX += (WebRtc_UWord32)WEBRTC_SPL_MUL(tmp32no1, tmp32no1); // Q(2*(prevQMagn-minPause)) + } + //update of average magnitude spectrum: Q(-2*stages) and averaging replaced by shifts + inst->curAvgMagnEnergy += WEBRTC_SPL_RSHIFT_U32(inst->magnEnergy, 2 * inst->normData + + inst->stages - 1); + + avgDiffNormMagnUFX = varMagnUFX; // Q(2*qMagn) + if ((varPauseUFX) && (covMagnPauseFX)) + { + tmpU32no1 = (WebRtc_UWord32)WEBRTC_SPL_ABS_W32(covMagnPauseFX); // Q(prevQMagn+qMagn) + norm32 = WebRtcSpl_NormU32(tmpU32no1) - 16; + if (norm32 > 0) + { + tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(tmpU32no1, norm32); // Q(prevQMagn+qMagn+norm32) + } else + { + tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, -norm32); // Q(prevQMagn+qMagn+norm32) + } + tmpU32no2 = WEBRTC_SPL_UMUL(tmpU32no1, tmpU32no1); // Q(2*(prevQMagn+qMagn-norm32)) + + nShifts += norm32; + nShifts <<= 1; + if (nShifts < 0) + { + varPauseUFX >>= (-nShifts); // Q(2*(qMagn+norm32+minPause)) + nShifts = 0; + } + tmpU32no1 = WEBRTC_SPL_UDIV(tmpU32no2, varPauseUFX); // Q(2*(qMagn+norm32-16+minPause)) + tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, nShifts); + + avgDiffNormMagnUFX -= WEBRTC_SPL_MIN(avgDiffNormMagnUFX, tmpU32no1); // Q(2*qMagn) + } + //normalize and compute time average update of difference feature + tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(avgDiffNormMagnUFX, 2 * inst->normData); + if (inst->featureSpecDiff > tmpU32no1) + { + tmpU32no2 = WEBRTC_SPL_UMUL_32_16(inst->featureSpecDiff - tmpU32no1, + SPECT_DIFF_TAVG_Q8); // Q(8-2*stages) + inst->featureSpecDiff -= WEBRTC_SPL_RSHIFT_U32(tmpU32no2, 8); // Q(-2*stages) + } else + { + tmpU32no2 = WEBRTC_SPL_UMUL_32_16(tmpU32no1 - inst->featureSpecDiff, + SPECT_DIFF_TAVG_Q8); // Q(8-2*stages) + inst->featureSpecDiff += WEBRTC_SPL_RSHIFT_U32(tmpU32no2, 8); // Q(-2*stages) + } +} + +// Compute speech/noise probability +// speech/noise probability is returned in: probSpeechFinal +//snrLocPrior is the prior SNR for each frequency (in Q11) +//snrLocPost is the post SNR for each frequency (in Q11) +void WebRtcNsx_SpeechNoiseProb(NsxInst_t *inst, WebRtc_UWord16 *nonSpeechProbFinal, + WebRtc_UWord32 *priorLocSnr, WebRtc_UWord32 *postLocSnr) +{ + WebRtc_UWord32 zeros, num, den, tmpU32no1, tmpU32no2, tmpU32no3; + + WebRtc_Word32 invLrtFX, indPriorFX, tmp32, tmp32no1, tmp32no2, besselTmpFX32; + WebRtc_Word32 frac32, logTmp; + WebRtc_Word32 logLrtTimeAvgKsumFX; + + WebRtc_Word16 indPriorFX16; + WebRtc_Word16 tmp16, tmp16no1, tmp16no2, tmpIndFX, tableIndex, frac, intPart; + + int i, normTmp, normTmp2, nShifts; + + // compute feature based on average LR factor + // this is the average over all frequencies of the smooth log LRT + logLrtTimeAvgKsumFX = 0; + for (i = 0; i < inst->magnLen; i++) + { + besselTmpFX32 = (WebRtc_Word32)postLocSnr[i]; // Q11 + normTmp = WebRtcSpl_NormU32(postLocSnr[i]); + num = WEBRTC_SPL_LSHIFT_U32(postLocSnr[i], normTmp); // Q(11+normTmp) + if (normTmp > 10) + { + den = WEBRTC_SPL_LSHIFT_U32(priorLocSnr[i], normTmp - 11); // Q(normTmp) + } else + { + den = WEBRTC_SPL_RSHIFT_U32(priorLocSnr[i], 11 - normTmp); // Q(normTmp) + } + besselTmpFX32 -= WEBRTC_SPL_UDIV(num, den); // Q11 + + // inst->logLrtTimeAvg[i] += LRT_TAVG * (besselTmp - log(snrLocPrior) - inst->logLrtTimeAvg[i]); + // Here, LRT_TAVG = 0.5 + zeros = WebRtcSpl_NormU32(priorLocSnr[i]); + frac32 = (WebRtc_Word32)(((priorLocSnr[i] << zeros) & 0x7FFFFFFF) >> 19); + tmp32 = WEBRTC_SPL_MUL(frac32, frac32); + tmp32 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(tmp32, -43), 19); + tmp32 += WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16)frac32, 5412, 12); + frac32 = tmp32 + 37; + // tmp32 = log2(priorLocSnr[i]) + tmp32 = (WebRtc_Word32)(((31 - zeros) << 12) + frac32) - (11 << 12); // Q12 + logTmp = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_32_16(tmp32, 178), 8); // log2(priorLocSnr[i])*log(2) + tmp32no1 = WEBRTC_SPL_RSHIFT_W32(logTmp + inst->logLrtTimeAvgW32[i], 1); // Q12 + inst->logLrtTimeAvgW32[i] += (besselTmpFX32 - tmp32no1); // Q12 + + logLrtTimeAvgKsumFX += inst->logLrtTimeAvgW32[i]; // Q12 + } + inst->featureLogLrt = WEBRTC_SPL_RSHIFT_W32(logLrtTimeAvgKsumFX * 5, inst->stages + 10); // 5 = BIN_SIZE_LRT / 2 + // done with computation of LR factor + + // + //compute the indicator functions + // + + // average LRT feature + // FLOAT code + // indicator0 = 0.5 * (tanh(widthPrior * (logLrtTimeAvgKsum - threshPrior0)) + 1.0); + tmpIndFX = 16384; // Q14(1.0) + tmp32no1 = logLrtTimeAvgKsumFX - inst->thresholdLogLrt; // Q12 + nShifts = 7 - inst->stages; // WIDTH_PR_MAP_SHIFT - inst->stages + 5; + //use larger width in tanh map for pause regions + if (tmp32no1 < 0) + { + tmpIndFX = 0; + tmp32no1 = -tmp32no1; + //widthPrior = widthPrior * 2.0; + nShifts++; + } + tmp32no1 = WEBRTC_SPL_SHIFT_W32(tmp32no1, nShifts); // Q14 + // compute indicator function: sigmoid map + tableIndex = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no1, 14); + if ((tableIndex < 16) && (tableIndex >= 0)) + { + tmp16no2 = kIndicatorTable[tableIndex]; + tmp16no1 = kIndicatorTable[tableIndex + 1] - kIndicatorTable[tableIndex]; + frac = (WebRtc_Word16)(tmp32no1 & 0x00003fff); // Q14 + tmp16no2 += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16no1, frac, 14); + if (tmpIndFX == 0) + { + tmpIndFX = 8192 - tmp16no2; // Q14 + } else + { + tmpIndFX = 8192 + tmp16no2; // Q14 + } + } + indPriorFX = WEBRTC_SPL_MUL_16_16(inst->weightLogLrt, tmpIndFX); // 6*Q14 + + //spectral flatness feature + if (inst->weightSpecFlat) + { + tmpU32no1 = WEBRTC_SPL_UMUL(inst->featureSpecFlat, 400); // Q10 + tmpIndFX = 16384; // Q14(1.0) + //use larger width in tanh map for pause regions + tmpU32no2 = inst->thresholdSpecFlat - tmpU32no1; //Q10 + nShifts = 4; + if (inst->thresholdSpecFlat < tmpU32no1) + { + tmpIndFX = 0; + tmpU32no2 = tmpU32no1 - inst->thresholdSpecFlat; + //widthPrior = widthPrior * 2.0; + nShifts++; + } + tmp32no1 = (WebRtc_Word32)WebRtcSpl_DivU32U16(WEBRTC_SPL_LSHIFT_U32(tmpU32no2, + nShifts), 25); //Q14 + tmpU32no1 = WebRtcSpl_DivU32U16(WEBRTC_SPL_LSHIFT_U32(tmpU32no2, nShifts), 25); //Q14 + // compute indicator function: sigmoid map + // FLOAT code + // indicator1 = 0.5 * (tanh(sgnMap * widthPrior * (threshPrior1 - tmpFloat1)) + 1.0); + tableIndex = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 14); + if (tableIndex < 16) + { + tmp16no2 = kIndicatorTable[tableIndex]; + tmp16no1 = kIndicatorTable[tableIndex + 1] - kIndicatorTable[tableIndex]; + frac = (WebRtc_Word16)(tmpU32no1 & 0x00003fff); // Q14 + tmp16no2 += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16no1, frac, 14); + if (tmpIndFX) + { + tmpIndFX = 8192 + tmp16no2; // Q14 + } else + { + tmpIndFX = 8192 - tmp16no2; // Q14 + } + } + indPriorFX += WEBRTC_SPL_MUL_16_16(inst->weightSpecFlat, tmpIndFX); // 6*Q14 + } + + //for template spectral-difference + if (inst->weightSpecDiff) + { + tmpU32no1 = 0; + if (inst->featureSpecDiff) + { + normTmp = WEBRTC_SPL_MIN(20 - inst->stages, + WebRtcSpl_NormU32(inst->featureSpecDiff)); + tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(inst->featureSpecDiff, normTmp); // Q(normTmp-2*stages) + tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(inst->timeAvgMagnEnergy, 20 - inst->stages + - normTmp); + if (tmpU32no2) + { + tmpU32no1 = WEBRTC_SPL_UDIV(tmpU32no1, tmpU32no2); // Q14?? Q(20 - inst->stages) + } else + { + tmpU32no1 = (WebRtc_UWord32)(0x7fffffff); + } + } + tmpU32no3 = WEBRTC_SPL_UDIV(WEBRTC_SPL_LSHIFT_U32(inst->thresholdSpecDiff, 17), 25); + tmpU32no2 = tmpU32no1 - tmpU32no3; + nShifts = 1; + tmpIndFX = 16384; // Q14(1.0) + //use larger width in tanh map for pause regions + if (tmpU32no2 & 0x80000000) + { + tmpIndFX = 0; + tmpU32no2 = tmpU32no3 - tmpU32no1; + //widthPrior = widthPrior * 2.0; + nShifts--; + } + tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no2, nShifts); + // compute indicator function: sigmoid map + /* FLOAT code + indicator2 = 0.5 * (tanh(widthPrior * (tmpFloat1 - threshPrior2)) + 1.0); + */ + tableIndex = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 14); + if (tableIndex < 16) + { + tmp16no2 = kIndicatorTable[tableIndex]; + tmp16no1 = kIndicatorTable[tableIndex + 1] - kIndicatorTable[tableIndex]; + frac = (WebRtc_Word16)(tmpU32no1 & 0x00003fff); // Q14 + tmp16no2 += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(tmp16no1, frac, + 14); + if (tmpIndFX) + { + tmpIndFX = 8192 + tmp16no2; + } else + { + tmpIndFX = 8192 - tmp16no2; + } + } + indPriorFX += WEBRTC_SPL_MUL_16_16(inst->weightSpecDiff, tmpIndFX); // 6*Q14 + } + + //combine the indicator function with the feature weights + // FLOAT code + // indPrior = 1 - (weightIndPrior0 * indicator0 + weightIndPrior1 * indicator1 + weightIndPrior2 * indicator2); + indPriorFX16 = WebRtcSpl_DivW32W16ResW16(98307 - indPriorFX, 6); // Q14 + // done with computing indicator function + + //compute the prior probability + // FLOAT code + // inst->priorNonSpeechProb += PRIOR_UPDATE * (indPriorNonSpeech - inst->priorNonSpeechProb); + tmp16 = indPriorFX16 - inst->priorNonSpeechProb; // Q14 + inst->priorNonSpeechProb += (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(PRIOR_UPDATE_Q14, + tmp16, 14); // Q14 + + //final speech probability: combine prior model with LR factor: + for (i = 0; i < inst->magnLen; i++) + { + // FLOAT code + // invLrt = exp(inst->logLrtTimeAvg[i]); + // invLrt = inst->priorSpeechProb * invLrt; + // nonSpeechProbFinal[i] = (1.0 - inst->priorSpeechProb) / (1.0 - inst->priorSpeechProb + invLrt); + // invLrt = (1.0 - inst->priorNonSpeechProb) * invLrt; + // nonSpeechProbFinal[i] = inst->priorNonSpeechProb / (inst->priorNonSpeechProb + invLrt); + nonSpeechProbFinal[i] = 0; // Q8 + if ((inst->logLrtTimeAvgW32[i] < 65300) && (inst->priorNonSpeechProb > 0)) + { + tmp32no1 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(inst->logLrtTimeAvgW32[i], 23637), + 14); // Q12 + intPart = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32no1, 12); + if (intPart < -8) + { + intPart = -8; + } + frac = (WebRtc_Word16)(tmp32no1 & 0x00000fff); // Q12 + // Quadratic approximation of 2^frac + tmp32no2 = WEBRTC_SPL_RSHIFT_W32(frac * frac * 44, 19); // Q12 + tmp32no2 += WEBRTC_SPL_MUL_16_16_RSFT(frac, 84, 7); // Q12 + invLrtFX = WEBRTC_SPL_LSHIFT_W32(1, 8 + intPart) + + WEBRTC_SPL_SHIFT_W32(tmp32no2, intPart - 4); // Q8 + + normTmp = WebRtcSpl_NormW32(invLrtFX); + normTmp2 = WebRtcSpl_NormW16((16384 - inst->priorNonSpeechProb)); + if (normTmp + normTmp2 < 15) + { + invLrtFX = WEBRTC_SPL_RSHIFT_W32(invLrtFX, 15 - normTmp2 - normTmp); // Q(normTmp+normTmp2-7) + tmp32no1 = WEBRTC_SPL_MUL_32_16(invLrtFX, (16384 - inst->priorNonSpeechProb)); // Q(normTmp+normTmp2+7) + invLrtFX = WEBRTC_SPL_SHIFT_W32(tmp32no1, 7 - normTmp - normTmp2); // Q14 + } else + { + tmp32no1 = WEBRTC_SPL_MUL_32_16(invLrtFX, (16384 - inst->priorNonSpeechProb)); // Q22 + invLrtFX = WEBRTC_SPL_RSHIFT_W32(tmp32no1, 8); // Q14 + } + + tmp32no1 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inst->priorNonSpeechProb, 8); // Q22 + nonSpeechProbFinal[i] = (WebRtc_UWord16)WEBRTC_SPL_DIV(tmp32no1, + (WebRtc_Word32)inst->priorNonSpeechProb + + invLrtFX); // Q8 + if (7 - normTmp - normTmp2 > 0) + { + nonSpeechProbFinal[i] = 0; // Q8 + } + } + } +} + +// Transform input (speechFrame) to frequency domain magnitude (magnU16) +void WebRtcNsx_DataAnalysis(NsxInst_t *inst, short *speechFrame, WebRtc_UWord16 *magnU16) +{ + + WebRtc_UWord32 tmpU32no1, tmpU32no2; + + WebRtc_Word32 tmp_1_w32 = 0; + WebRtc_Word32 tmp_2_w32 = 0; + WebRtc_Word32 sum_log_magn = 0; + WebRtc_Word32 sum_log_i_log_magn = 0; + + WebRtc_UWord16 sum_log_magn_u16 = 0; + WebRtc_UWord16 tmp_u16 = 0; + + WebRtc_Word16 sum_log_i = 0; + WebRtc_Word16 sum_log_i_square = 0; + WebRtc_Word16 frac = 0; + WebRtc_Word16 log2 = 0; + WebRtc_Word16 matrix_determinant = 0; + WebRtc_Word16 winData[ANAL_BLOCKL_MAX], maxWinData; + WebRtc_Word16 realImag[ANAL_BLOCKL_MAX << 1]; + + int i, j; + int outCFFT; + int zeros; + int net_norm = 0; + int right_shifts_in_magnU16 = 0; + int right_shifts_in_initMagnEst = 0; + + // For lower band do all processing + // update analysis buffer for L band + WEBRTC_SPL_MEMCPY_W16(inst->analysisBuffer, inst->analysisBuffer + inst->blockLen10ms, + inst->anaLen - inst->blockLen10ms); + WEBRTC_SPL_MEMCPY_W16(inst->analysisBuffer + inst->anaLen - inst->blockLen10ms, + speechFrame, inst->blockLen10ms); + + // Window data before FFT + for (i = 0; i < inst->anaLen; i++) + { + winData[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(inst->window[i], + inst->analysisBuffer[i], + 14); // Q0 + } + // Get input energy + inst->energyIn = WebRtcSpl_Energy(winData, (int)inst->anaLen, &(inst->scaleEnergyIn)); + + // Reset zero input flag + inst->zeroInputSignal = 0; + // Acquire norm for winData + maxWinData = WebRtcSpl_MaxAbsValueW16(winData, inst->anaLen); + inst->normData = WebRtcSpl_NormW16(maxWinData); + if (maxWinData == 0) + { + // Treat zero input separately. + inst->zeroInputSignal = 1; + return; + } + + // Determine the net normalization in the frequency domain + net_norm = inst->stages - inst->normData; + // Track lowest normalization factor and use it to prevent wrap around in shifting + right_shifts_in_magnU16 = inst->normData - inst->minNorm; + right_shifts_in_initMagnEst = WEBRTC_SPL_MAX(-right_shifts_in_magnU16, 0); + inst->minNorm -= right_shifts_in_initMagnEst; + right_shifts_in_magnU16 = WEBRTC_SPL_MAX(right_shifts_in_magnU16, 0); + + // create realImag as winData interleaved with zeros (= imag. part), normalize it + for (i = 0; i < inst->anaLen; i++) + { + j = WEBRTC_SPL_LSHIFT_W16(i, 1); + realImag[j] = WEBRTC_SPL_LSHIFT_W16(winData[i], inst->normData); // Q(normData) + realImag[j + 1] = 0; // Insert zeros in imaginary part + } + + // bit-reverse position of elements in array and FFT the array + WebRtcSpl_ComplexBitReverse(realImag, inst->stages); // Q(normData-stages) + outCFFT = WebRtcSpl_ComplexFFT(realImag, inst->stages, 1); + + inst->imag[0] = 0; // Q(normData-stages) + inst->imag[inst->anaLen2] = 0; + inst->real[0] = realImag[0]; // Q(normData-stages) + inst->real[inst->anaLen2] = realImag[inst->anaLen]; + // Q(2*(normData-stages)) + inst->magnEnergy = (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(inst->real[0], inst->real[0]); + inst->magnEnergy += (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(inst->real[inst->anaLen2], + inst->real[inst->anaLen2]); + magnU16[0] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(inst->real[0]); // Q(normData-stages) + magnU16[inst->anaLen2] = (WebRtc_UWord16)WEBRTC_SPL_ABS_W16(inst->real[inst->anaLen2]); + inst->sumMagn = (WebRtc_UWord32)magnU16[0]; // Q(normData-stages) + inst->sumMagn += (WebRtc_UWord32)magnU16[inst->anaLen2]; + + // Gather information during startup for noise parameter estimation + if (inst->blockIndex < END_STARTUP_SHORT) + { + // Switch initMagnEst to Q(minNorm-stages) + inst->initMagnEst[0] = WEBRTC_SPL_RSHIFT_U32(inst->initMagnEst[0], + right_shifts_in_initMagnEst); + inst->initMagnEst[inst->anaLen2] = + WEBRTC_SPL_RSHIFT_U32(inst->initMagnEst[inst->anaLen2], + right_shifts_in_initMagnEst); // Q(minNorm-stages) + + // Shift magnU16 to same domain as initMagnEst + tmpU32no1 = WEBRTC_SPL_RSHIFT_W32((WebRtc_UWord32)magnU16[0], + right_shifts_in_magnU16); // Q(minNorm-stages) + tmpU32no2 = WEBRTC_SPL_RSHIFT_W32((WebRtc_UWord32)magnU16[inst->anaLen2], + right_shifts_in_magnU16); // Q(minNorm-stages) + + // Update initMagnEst + inst->initMagnEst[0] += tmpU32no1; // Q(minNorm-stages) + inst->initMagnEst[inst->anaLen2] += tmpU32no2; // Q(minNorm-stages) + + log2 = 0; + if (magnU16[inst->anaLen2]) + { + // Calculate log2(magnU16[inst->anaLen2]) + zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magnU16[inst->anaLen2]); + frac = (WebRtc_Word16)((((WebRtc_UWord32)magnU16[inst->anaLen2] << zeros) & + 0x7FFFFFFF) >> 23); // Q8 + // log2(magnU16(i)) in Q8 + log2 = (WebRtc_Word16)(((31 - zeros) << 8) + kLogTableFrac[frac]); + } + + sum_log_magn = (WebRtc_Word32)log2; // Q8 + // sum_log_i_log_magn in Q17 + sum_log_i_log_magn = (WEBRTC_SPL_MUL_16_16(kLogIndex[inst->anaLen2], log2) >> 3); + } + + for (i = 1; i < inst->anaLen2; i++) + { + j = WEBRTC_SPL_LSHIFT_W16(i, 1); + inst->real[i] = realImag[j]; + inst->imag[i] = -realImag[j + 1]; + // magnitude spectrum + // energy in Q(2*(normData-stages)) + tmpU32no1 = (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(realImag[j], realImag[j]); + tmpU32no1 += (WebRtc_UWord32)WEBRTC_SPL_MUL_16_16(realImag[j + 1], realImag[j + 1]); + inst->magnEnergy += tmpU32no1; // Q(2*(normData-stages)) + + magnU16[i] = (WebRtc_UWord16)WebRtcSpl_Sqrt(tmpU32no1); // Q(normData-stages) + inst->sumMagn += (WebRtc_UWord32)magnU16[i]; // Q(normData-stages) + if (inst->blockIndex < END_STARTUP_SHORT) + { + // Switch initMagnEst to Q(minNorm-stages) + inst->initMagnEst[i] = WEBRTC_SPL_RSHIFT_U32(inst->initMagnEst[i], + right_shifts_in_initMagnEst); + + // Shift magnU16 to same domain as initMagnEst, i.e., Q(minNorm-stages) + tmpU32no1 = WEBRTC_SPL_RSHIFT_W32((WebRtc_UWord32)magnU16[i], + right_shifts_in_magnU16); + // Update initMagnEst + inst->initMagnEst[i] += tmpU32no1; // Q(minNorm-stages) + + if (i >= kStartBand) + { + // For pink noise estimation. Collect data neglecting lower frequency band + log2 = 0; + if (magnU16[i]) + { + zeros = WebRtcSpl_NormU32((WebRtc_UWord32)magnU16[i]); + frac = (WebRtc_Word16)((((WebRtc_UWord32)magnU16[i] << zeros) & + 0x7FFFFFFF) >> 23); + // log2(magnU16(i)) in Q8 + log2 = (WebRtc_Word16)(((31 - zeros) << 8) + kLogTableFrac[frac]); + } + sum_log_magn += (WebRtc_Word32)log2; // Q8 + // sum_log_i_log_magn in Q17 + sum_log_i_log_magn += (WEBRTC_SPL_MUL_16_16(kLogIndex[i], log2) >> 3); + } + } + } + + //compute simplified noise model during startup + if (inst->blockIndex < END_STARTUP_SHORT) + { + // Estimate White noise + // Switch whiteNoiseLevel to Q(minNorm-stages) + inst->whiteNoiseLevel = WEBRTC_SPL_RSHIFT_U32(inst->whiteNoiseLevel, + right_shifts_in_initMagnEst); + + // Update the average magnitude spectrum, used as noise estimate. + tmpU32no1 = WEBRTC_SPL_UMUL_32_16(inst->sumMagn, inst->overdrive); + tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, inst->stages + 8); + + // Replacing division above with 'stages' shifts + // Shift to same Q-domain as whiteNoiseLevel + tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, right_shifts_in_magnU16); + // This operation is safe from wrap around as long as END_STARTUP_SHORT < 128 + assert(END_STARTUP_SHORT < 128); + inst->whiteNoiseLevel += tmpU32no1; // Q(minNorm-stages) + + // Estimate Pink noise parameters + // Denominator used in both parameter estimates. + // The value is only dependent on the size of the frequency band (kStartBand) + // and to reduce computational complexity stored in a table (kDeterminantEstMatrix[]) + matrix_determinant = kDeterminantEstMatrix[kStartBand]; // Q0 + sum_log_i = kSumLogIndex[kStartBand]; // Q5 + sum_log_i_square = kSumSquareLogIndex[kStartBand]; // Q2 + if (inst->fs == 8000) + { + // Adjust values to shorter blocks in narrow band. + tmp_1_w32 = (WebRtc_Word32)matrix_determinant; + tmp_1_w32 += WEBRTC_SPL_MUL_16_16_RSFT(kSumLogIndex[65], sum_log_i, 9); + tmp_1_w32 -= WEBRTC_SPL_MUL_16_16_RSFT(kSumLogIndex[65], kSumLogIndex[65], 10); + tmp_1_w32 -= WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)sum_log_i_square, 4); + tmp_1_w32 -= WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16)(inst->magnLen + - kStartBand), kSumSquareLogIndex[65], 2); + matrix_determinant = (WebRtc_Word16)tmp_1_w32; + sum_log_i -= kSumLogIndex[65]; // Q5 + sum_log_i_square -= kSumSquareLogIndex[65]; // Q2 + } + + // Necessary number of shifts to fit sum_log_magn in a word16 + zeros = 16 - WebRtcSpl_NormW32(sum_log_magn); + if (zeros < 0) + { + zeros = 0; + } + tmp_1_w32 = WEBRTC_SPL_LSHIFT_W32(sum_log_magn, 1); // Q9 + sum_log_magn_u16 = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_W32(tmp_1_w32, zeros);//Q(9-zeros) + + // Calculate and update pinkNoiseNumerator. Result in Q11. + tmp_2_w32 = WEBRTC_SPL_MUL_16_U16(sum_log_i_square, sum_log_magn_u16); // Q(11-zeros) + tmpU32no1 = WEBRTC_SPL_RSHIFT_U32((WebRtc_UWord32)sum_log_i_log_magn, 12); // Q5 + + // Shift the largest value of sum_log_i and tmp32no3 before multiplication + tmp_u16 = WEBRTC_SPL_LSHIFT_U16((WebRtc_UWord16)sum_log_i, 1); // Q6 + if ((WebRtc_UWord32)sum_log_i > tmpU32no1) + { + tmp_u16 = WEBRTC_SPL_RSHIFT_U16(tmp_u16, zeros); + } + else + { + tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, zeros); + } + tmp_2_w32 -= (WebRtc_Word32)WEBRTC_SPL_UMUL_32_16(tmpU32no1, tmp_u16); // Q(11-zeros) + matrix_determinant = WEBRTC_SPL_RSHIFT_W16(matrix_determinant, zeros); // Q(-zeros) + tmp_2_w32 = WebRtcSpl_DivW32W16(tmp_2_w32, matrix_determinant); // Q11 + tmp_2_w32 += WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)net_norm, 11); // Q11 + if (tmp_2_w32 < 0) + { + tmp_2_w32 = 0; + } + inst->pinkNoiseNumerator += tmp_2_w32; // Q11 + + // Calculate and update pinkNoiseExp. Result in Q14. + tmp_2_w32 = WEBRTC_SPL_MUL_16_U16(sum_log_i, sum_log_magn_u16); // Q(14-zeros) + tmp_1_w32 = WEBRTC_SPL_RSHIFT_W32(sum_log_i_log_magn, 3 + zeros); + tmp_1_w32 = WEBRTC_SPL_MUL((WebRtc_Word32)(inst->magnLen - kStartBand), + tmp_1_w32); + tmp_2_w32 -= tmp_1_w32; // Q(14-zeros) + if (tmp_2_w32 > 0) + { + // If the exponential parameter is negative force it to zero, which means a + // flat spectrum. + tmp_1_w32 = WebRtcSpl_DivW32W16(tmp_2_w32, matrix_determinant); // Q14 + inst->pinkNoiseExp += WEBRTC_SPL_SAT(16384, tmp_1_w32, 0); // Q14 + } + } +} + +void WebRtcNsx_DataSynthesis(NsxInst_t *inst, short *outFrame) +{ + WebRtc_Word32 tmp32no1; + WebRtc_Word32 energyOut; + + WebRtc_Word16 realImag[ANAL_BLOCKL_MAX << 1]; + WebRtc_Word16 tmp16no1, tmp16no2; + WebRtc_Word16 energyRatio; + WebRtc_Word16 gainFactor, gainFactor1, gainFactor2; + + int i, j; + int outCIFFT; + int scaleEnergyOut = 0; + + if (inst->zeroInputSignal) + { + // synthesize the special case of zero input + // read out fully processed segment + for (i = 0; i < inst->blockLen10ms; i++) + { + outFrame[i] = inst->synthesisBuffer[i]; // Q0 + } + // update synthesis buffer + WEBRTC_SPL_MEMCPY_W16(inst->synthesisBuffer, + inst->synthesisBuffer + inst->blockLen10ms, + inst->anaLen - inst->blockLen10ms); + WebRtcSpl_ZerosArrayW16(inst->synthesisBuffer + inst->anaLen - inst->blockLen10ms, + inst->blockLen10ms); + return; + } + // Filter the data in the frequency domain + for (i = 0; i < inst->magnLen; i++) + { + inst->real[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->real[i], + (WebRtc_Word16)(inst->noiseSupFilter[i]), 14); // Q(normData-stages) + inst->imag[i] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->imag[i], + (WebRtc_Word16)(inst->noiseSupFilter[i]), 14); // Q(normData-stages) + } + // back to time domain + // Create spectrum + realImag[0] = inst->real[0]; + realImag[1] = -inst->imag[0]; + for (i = 1; i < inst->anaLen2; i++) + { + j = WEBRTC_SPL_LSHIFT_W16(i, 1); + tmp16no1 = (inst->anaLen << 1) - j; + realImag[j] = inst->real[i]; + realImag[j + 1] = -inst->imag[i]; + realImag[tmp16no1] = inst->real[i]; + realImag[tmp16no1 + 1] = inst->imag[i]; + } + realImag[inst->anaLen] = inst->real[inst->anaLen2]; + realImag[inst->anaLen + 1] = -inst->imag[inst->anaLen2]; + + // bit-reverse position of elements in array and IFFT it + WebRtcSpl_ComplexBitReverse(realImag, inst->stages); + outCIFFT = WebRtcSpl_ComplexIFFT(realImag, inst->stages, 1); + + for (i = 0; i < inst->anaLen; i++) + { + j = WEBRTC_SPL_LSHIFT_W16(i, 1); + tmp32no1 = WEBRTC_SPL_SHIFT_W32((WebRtc_Word32)realImag[j], outCIFFT - inst->normData); + inst->real[i] = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, tmp32no1, + WEBRTC_SPL_WORD16_MIN); + } + + //scale factor: only do it after END_STARTUP_LONG time + gainFactor = 8192; // 8192 = Q13(1.0) + if (inst->gainMap == 1 && + inst->blockIndex > END_STARTUP_LONG && + inst->energyIn > 0) + { + energyOut = WebRtcSpl_Energy(inst->real, (int)inst->anaLen, &scaleEnergyOut); // Q(-scaleEnergyOut) + if (scaleEnergyOut == 0 && !(energyOut & 0x7f800000)) + { + energyOut = WEBRTC_SPL_SHIFT_W32(energyOut, 8 + scaleEnergyOut + - inst->scaleEnergyIn); + } else + { + inst->energyIn = WEBRTC_SPL_RSHIFT_W32(inst->energyIn, 8 + scaleEnergyOut + - inst->scaleEnergyIn); // Q(-8-scaleEnergyOut) + } + + assert(inst->energyIn > 0); + energyRatio = (WebRtc_Word16)WEBRTC_SPL_DIV(energyOut + + WEBRTC_SPL_RSHIFT_W32(inst->energyIn, 1), inst->energyIn); // Q8 + + // // original FLOAT code + // if (gain > blim) { + // factor1=1.0+1.3*(gain-blim); + // if (gain*factor1 > 1.0) { // FLOAT + // factor1 = 1.0/gain; // FLOAT + // } + // } + // else { + // factor1=1.0; // FLOAT + // } + // + // if (gain > blim) { + // factor2=1.0; //FLOAT + // } + // else { + // //don't reduce scale too much for pause regions: attenuation here should be controlled by flooring + // factor2=1.0-0.3*(blim-gain); // FLOAT + // if (gain <= inst->denoiseBound) { + // factor2=1.0-0.3*(blim-inst->denoiseBound); // FLOAT + // } + // } + + // all done in lookup tables now + gainFactor1 = kFactor1Table[energyRatio]; // Q8 + gainFactor2 = inst->factor2Table[energyRatio]; // Q8 + + //combine both scales with speech/noise prob: note prior (priorSpeechProb) is not frequency dependent + + // factor = inst->priorSpeechProb*factor1 + (1.0-inst->priorSpeechProb)*factor2; // original code + tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(16384 - inst->priorNonSpeechProb, + gainFactor1, 14); // Q13 16384 = Q14(1.0) + tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(inst->priorNonSpeechProb, + gainFactor2, 14); // Q13; + gainFactor = tmp16no1 + tmp16no2; // Q13 + } // out of flag_gain_map==1 + + // synthesis + for (i = 0; i < inst->anaLen; i++) + { + tmp16no1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(inst->window[i], + inst->real[i], 14); // Q0, window in Q14 + tmp32no1 = WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(tmp16no1, gainFactor, 13); // Q0 + // Down shift with rounding + tmp16no2 = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, tmp32no1, + WEBRTC_SPL_WORD16_MIN); // Q0 + inst->synthesisBuffer[i] = WEBRTC_SPL_ADD_SAT_W16(inst->synthesisBuffer[i], tmp16no2); // Q0 + } + + // read out fully processed segment + for (i = 0; i < inst->blockLen10ms; i++) + { + outFrame[i] = inst->synthesisBuffer[i]; // Q0 + } + // update synthesis buffer + WEBRTC_SPL_MEMCPY_W16(inst->synthesisBuffer, inst->synthesisBuffer + inst->blockLen10ms, + inst->anaLen - inst->blockLen10ms); + WebRtcSpl_ZerosArrayW16(inst->synthesisBuffer + inst->anaLen - inst->blockLen10ms, + inst->blockLen10ms); +} + +int WebRtcNsx_ProcessCore(NsxInst_t *inst, short *speechFrame, short *speechFrameHB, + short *outFrame, short *outFrameHB) +{ + // main routine for noise suppression + + WebRtc_UWord32 tmpU32no1, tmpU32no2, tmpU32no3; + WebRtc_UWord32 satMax, maxNoiseU32; + WebRtc_UWord32 tmpMagnU32, tmpNoiseU32; + WebRtc_UWord32 nearMagnEst; + WebRtc_UWord32 noiseUpdateU32; + WebRtc_UWord32 noiseU32[HALF_ANAL_BLOCKL]; + WebRtc_UWord32 postLocSnr[HALF_ANAL_BLOCKL]; + WebRtc_UWord32 priorLocSnr[HALF_ANAL_BLOCKL]; + WebRtc_UWord32 prevNearSnr[HALF_ANAL_BLOCKL]; + WebRtc_UWord32 curNearSnr; + WebRtc_UWord32 priorSnr; + WebRtc_UWord32 noise_estimate = 0; + WebRtc_UWord32 noise_estimate_avg = 0; + WebRtc_UWord32 numerator = 0; + + WebRtc_Word32 tmp32no1, tmp32no2; + WebRtc_Word32 pink_noise_num_avg = 0; + + WebRtc_UWord16 tmpU16no1; + WebRtc_UWord16 magnU16[HALF_ANAL_BLOCKL]; + WebRtc_UWord16 prevNoiseU16[HALF_ANAL_BLOCKL]; + WebRtc_UWord16 nonSpeechProbFinal[HALF_ANAL_BLOCKL]; + WebRtc_UWord16 gammaNoise, prevGammaNoise; + WebRtc_UWord16 noiseSupFilterTmp[HALF_ANAL_BLOCKL]; + + WebRtc_Word16 qMagn, qNoise; + WebRtc_Word16 avgProbSpeechHB, gainModHB, avgFilterGainHB, gainTimeDomainHB; + WebRtc_Word16 tmp16no1; + WebRtc_Word16 int_part = 0; + WebRtc_Word16 frac_part = 0; + WebRtc_Word16 pink_noise_exp_avg = 0; + + int i; + int nShifts, postShifts; + int norm32no1, norm32no2; + int flag, sign; + int q_domain_to_use = 0; + +#ifdef NS_FILEDEBUG + fwrite(spframe, sizeof(short), inst->blockLen10ms, inst->infile); +#endif + + // Check that initialization has been done + if (inst->initFlag != 1) + { + return -1; + } + // Check for valid pointers based on sampling rate + if ((inst->fs == 32000) && (speechFrameHB == NULL)) + { + return -1; + } + + // Update block index + inst->blockIndex++; + // + + // Store speechFrame and transform to frequency domain + WebRtcNsx_DataAnalysis(inst, speechFrame, magnU16); + + if (inst->zeroInputSignal) + { + WebRtcNsx_DataSynthesis(inst, outFrame); + + if (inst->fs == 32000) + { + // update analysis buffer for H band + // append new data to buffer FX + WEBRTC_SPL_MEMCPY_W16(inst->dataBufHBFX, inst->dataBufHBFX + inst->blockLen10ms, + inst->anaLen - inst->blockLen10ms); + WEBRTC_SPL_MEMCPY_W16(inst->dataBufHBFX + inst->anaLen - inst->blockLen10ms, + speechFrameHB, inst->blockLen10ms); + for (i = 0; i < inst->blockLen10ms; i++) + { + outFrameHB[i] = inst->dataBufHBFX[i]; // Q0 + } + } // end of H band gain computation + return 0; + } + + // Norm of magn + qMagn = inst->normData - inst->stages; + + // Compute spectral flatness on input spectrum + WebRtcNsx_ComputeSpectralFlatness(inst, magnU16); + + // quantile noise estimate + WebRtcNsx_NoiseEstimation(inst, magnU16, noiseU32, &qNoise); + + //noise estimate from previous frame + for (i = 0; i < inst->magnLen; i++) + { + prevNoiseU16[i] = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32(inst->prevNoiseU32[i], 11); // Q(prevQNoise) + } + + if (inst->blockIndex < END_STARTUP_SHORT) + { + // Noise Q-domain to be used later; see description at end of section. + q_domain_to_use = WEBRTC_SPL_MIN((int)qNoise, inst->minNorm - inst->stages); + + // Calculate frequency independent parts in parametric noise estimate and calculate + // the estimate for the lower frequency band (same values for all frequency bins) + if (inst->pinkNoiseExp) + { + pink_noise_exp_avg = (WebRtc_Word16)WebRtcSpl_DivW32W16(inst->pinkNoiseExp, + (WebRtc_Word16)(inst->blockIndex + 1)); // Q14 + pink_noise_num_avg = WebRtcSpl_DivW32W16(inst->pinkNoiseNumerator, + (WebRtc_Word16)(inst->blockIndex + 1)); // Q11 + WebRtcNsx_CalcParametricNoiseEstimate(inst, + pink_noise_exp_avg, + pink_noise_num_avg, + kStartBand, + &noise_estimate, + &noise_estimate_avg); + } + else + { + // Use white noise estimate if we have poor pink noise parameter estimates + noise_estimate = inst->whiteNoiseLevel; // Q(minNorm-stages) + noise_estimate_avg = noise_estimate / (inst->blockIndex + 1); // Q(minNorm-stages) + } + for (i = 0; i < inst->magnLen; i++) + { + // Estimate the background noise using the pink noise parameters if permitted + if ((inst->pinkNoiseExp) && (i >= kStartBand)) + { + // Reset noise_estimate + noise_estimate = 0; + noise_estimate_avg = 0; + // Calculate the parametric noise estimate for current frequency bin + WebRtcNsx_CalcParametricNoiseEstimate(inst, + pink_noise_exp_avg, + pink_noise_num_avg, + i, + &noise_estimate, + &noise_estimate_avg); + } + // Calculate parametric Wiener filter + noiseSupFilterTmp[i] = inst->denoiseBound; + if (inst->initMagnEst[i]) + { + // numerator = (initMagnEst - noise_estimate * overdrive) + // Result in Q(8+minNorm-stages) + tmpU32no1 = WEBRTC_SPL_UMUL_32_16(noise_estimate, inst->overdrive); + numerator = WEBRTC_SPL_LSHIFT_U32(inst->initMagnEst[i], 8); + if (numerator > tmpU32no1) + { + // Suppression filter coefficient larger than zero, so calculate. + numerator -= tmpU32no1; + + // Determine number of left shifts in numerator for best accuracy after + // division + nShifts = WebRtcSpl_NormU32(numerator); + nShifts = WEBRTC_SPL_SAT(6, nShifts, 0); + + // Shift numerator to Q(nShifts+8+minNorm-stages) + numerator = WEBRTC_SPL_LSHIFT_U32(numerator, nShifts); + + // Shift denominator to Q(nShifts-6+minNorm-stages) + tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(inst->initMagnEst[i], 6 - nShifts); + tmpU32no2 = WEBRTC_SPL_UDIV(numerator, tmpU32no1); // Q14 + noiseSupFilterTmp[i] = (WebRtc_UWord16)WEBRTC_SPL_SAT(16384, tmpU32no2, + (WebRtc_UWord32)(inst->denoiseBound)); // Q14 + } + } + // Weight quantile noise 'noiseU32' with modeled noise 'noise_estimate_avg' + // 'noiseU32 is in Q(qNoise) and 'noise_estimate' in Q(minNorm-stages) + // To guarantee that we do not get wrap around when shifting to the same domain + // we use the lowest one. Furthermore, we need to save 6 bits for the weighting. + // 'noise_estimate_avg' can handle this operation by construction, but 'noiseU32' + // may not. + + // Shift 'noiseU32' to 'q_domain_to_use' + tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(noiseU32[i], (int)qNoise - q_domain_to_use); + // Shift 'noise_estimate_avg' to 'q_domain_to_use' + tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(noise_estimate_avg, inst->minNorm - inst->stages + - q_domain_to_use); + // Make a simple check to see if we have enough room for weighting 'tmpU32no1' + // without wrap around + nShifts = 0; + if (tmpU32no1 & 0xfc000000) { + tmpU32no1 = WEBRTC_SPL_RSHIFT_U32(tmpU32no1, 6); + tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(tmpU32no2, 6); + nShifts = 6; + } + // Add them together and divide by startup length + noiseU32[i] = WebRtcSpl_DivU32U16(tmpU32no1 + tmpU32no2, END_STARTUP_SHORT); + // Shift back if necessary + noiseU32[i] = WEBRTC_SPL_LSHIFT_U32(noiseU32[i], nShifts); + } + // Update new Q-domain for 'noiseU32' + qNoise = q_domain_to_use; + } + // compute average signal during END_STARTUP_LONG time: + // used to normalize spectral difference measure + if (inst->blockIndex < END_STARTUP_LONG) + { + // substituting division with shift ending up in Q(-2*stages) + inst->timeAvgMagnEnergyTmp + += WEBRTC_SPL_RSHIFT_U32(inst->magnEnergy, + 2 * inst->normData + inst->stages - 1); + inst->timeAvgMagnEnergy = WebRtcSpl_DivU32U16(inst->timeAvgMagnEnergyTmp, + inst->blockIndex + 1); + } + + //start processing at frames == converged+1 + // STEP 1: compute prior and post SNR based on quantile noise estimates + + // compute direct decision (DD) estimate of prior SNR: needed for new method + satMax = (WebRtc_UWord32)1048575;// Largest possible value without getting overflow despite shifting 12 steps + postShifts = 6 + qMagn - qNoise; + nShifts = 5 - inst->prevQMagn + inst->prevQNoise; + for (i = 0; i < inst->magnLen; i++) + { + // FLOAT: + // post SNR + // postLocSnr[i] = 0.0; + // if (magn[i] > noise[i]) + // { + // postLocSnr[i] = magn[i] / (noise[i] + 0.0001); + // } + // // previous post SNR + // // previous estimate: based on previous frame with gain filter (smooth is previous filter) + // + // prevNearSnr[i] = inst->prevMagnU16[i] / (inst->noisePrev[i] + 0.0001) * (inst->smooth[i]); + // + // // DD estimate is sum of two terms: current estimate and previous estimate + // // directed decision update of priorSnr (or we actually store [2*priorSnr+1]) + // + // priorLocSnr[i] = DD_PR_SNR * prevNearSnr[i] + (1.0 - DD_PR_SNR) * (postLocSnr[i] - 1.0); + + // calculate post SNR: output in Q11 + postLocSnr[i] = 2048; // 1.0 in Q11 + tmpU32no1 = WEBRTC_SPL_LSHIFT_U32((WebRtc_UWord32)magnU16[i], 6); // Q(6+qMagn) + if (postShifts < 0) + { + tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(noiseU32[i], -postShifts); // Q(6+qMagn) + } else + { + tmpU32no2 = WEBRTC_SPL_LSHIFT_U32(noiseU32[i], postShifts); // Q(6+qMagn) + } + if (tmpU32no1 > tmpU32no2) + { + // Current magnitude larger than noise + tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(tmpU32no1, 11); // Q(17+qMagn) + if (tmpU32no2) + { + tmpU32no1 = WEBRTC_SPL_UDIV(tmpU32no1, tmpU32no2); // Q11 + postLocSnr[i] = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11 + } else + { + postLocSnr[i] = satMax; + } + } + + // calculate prevNearSnr[i] and save for later instead of recalculating it later + nearMagnEst = WEBRTC_SPL_UMUL_16_16(inst->prevMagnU16[i], inst->noiseSupFilter[i]); // Q(prevQMagn+14) + tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(nearMagnEst, 3); // Q(prevQMagn+17) + tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(inst->prevNoiseU32[i], nShifts); // Q(prevQMagn+6) + + if (tmpU32no2) + { + tmpU32no1 = WEBRTC_SPL_DIV(tmpU32no1, tmpU32no2); // Q11 + tmpU32no1 = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11 + } else + { + tmpU32no1 = satMax; // Q11 + } + prevNearSnr[i] = tmpU32no1; // Q11 + + //directed decision update of priorSnr + tmpU32no1 = WEBRTC_SPL_UMUL_32_16(prevNearSnr[i], DD_PR_SNR_Q11); // Q22 + tmpU32no2 = WEBRTC_SPL_UMUL_32_16(postLocSnr[i] - 2048, ONE_MINUS_DD_PR_SNR_Q11); // Q22 + priorSnr = tmpU32no1 + tmpU32no2 + 512; // Q22 (added 512 for rounding) + // priorLocSnr = 1 + 2*priorSnr + priorLocSnr[i] = 2048 + WEBRTC_SPL_RSHIFT_U32(priorSnr, 10); // Q11 + } // end of loop over frequencies + // done with step 1: DD computation of prior and post SNR + + // STEP 2: compute speech/noise likelihood + + //compute difference of input spectrum with learned/estimated noise spectrum + WebRtcNsx_ComputeSpectralDifference(inst, magnU16); + //compute histograms for determination of parameters (thresholds and weights for features) + //parameters are extracted once every window time (=inst->modelUpdate) + //counter update + inst->cntThresUpdate++; + flag = (int)(inst->cntThresUpdate == inst->modelUpdate); + //update histogram + WebRtcNsx_FeatureParameterExtraction(inst, flag); + //compute model parameters + if (flag) + { + inst->cntThresUpdate = 0; // Reset counter + //update every window: + // get normalization for spectral difference for next window estimate + + // Shift to Q(-2*stages) + inst->curAvgMagnEnergy = WEBRTC_SPL_RSHIFT_U32(inst->curAvgMagnEnergy, STAT_UPDATES); + + tmpU32no1 = (inst->curAvgMagnEnergy + inst->timeAvgMagnEnergy + 1) >> 1; //Q(-2*stages) + // Update featureSpecDiff + if ((tmpU32no1 != inst->timeAvgMagnEnergy) && (inst->featureSpecDiff)) + { + norm32no1 = 0; + tmpU32no3 = tmpU32no1; + while (0xFFFF0000 & tmpU32no3) + { + tmpU32no3 >>= 1; + norm32no1++; + } + tmpU32no2 = inst->featureSpecDiff; + while (0xFFFF0000 & tmpU32no2) + { + tmpU32no2 >>= 1; + norm32no1++; + } + tmpU32no3 = WEBRTC_SPL_UMUL(tmpU32no3, tmpU32no2); + tmpU32no3 = WEBRTC_SPL_UDIV(tmpU32no3, inst->timeAvgMagnEnergy); + if (WebRtcSpl_NormU32(tmpU32no3) < norm32no1) + { + inst->featureSpecDiff = 0x007FFFFF; + } else + { + inst->featureSpecDiff = WEBRTC_SPL_MIN(0x007FFFFF, + WEBRTC_SPL_LSHIFT_U32(tmpU32no3, norm32no1)); + } + } + + inst->timeAvgMagnEnergy = tmpU32no1; // Q(-2*stages) + inst->curAvgMagnEnergy = 0; + } + + //compute speech/noise probability + WebRtcNsx_SpeechNoiseProb(inst, nonSpeechProbFinal, priorLocSnr, postLocSnr); + + //time-avg parameter for noise update + gammaNoise = NOISE_UPDATE_Q8; // Q8 + + maxNoiseU32 = 0; + postShifts = inst->prevQNoise - qMagn; + nShifts = inst->prevQMagn - qMagn; + for (i = 0; i < inst->magnLen; i++) + { + // temporary noise update: use it for speech frames if update value is less than previous + // the formula has been rewritten into: + // noiseUpdate = noisePrev[i] + (1 - gammaNoise) * nonSpeechProb * (magn[i] - noisePrev[i]) + + if (postShifts < 0) + { + tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(magnU16[i], -postShifts); // Q(prevQNoise) + } else + { + tmpU32no2 = WEBRTC_SPL_LSHIFT_U32(magnU16[i], postShifts); // Q(prevQNoise) + } + if (prevNoiseU16[i] > tmpU32no2) + { + sign = -1; + tmpU32no1 = prevNoiseU16[i] - tmpU32no2; + } else + { + sign = 1; + tmpU32no1 = tmpU32no2 - prevNoiseU16[i]; + } + noiseUpdateU32 = inst->prevNoiseU32[i]; // Q(prevQNoise+11) + tmpU32no3 = 0; + if ((tmpU32no1) && (nonSpeechProbFinal[i])) + { + // This value will be used later, if gammaNoise changes + tmpU32no3 = WEBRTC_SPL_UMUL_32_16(tmpU32no1, nonSpeechProbFinal[i]); // Q(prevQNoise+8) + if (0x7c000000 & tmpU32no3) + { + // Shifting required before multiplication + tmpU32no2 + = WEBRTC_SPL_UMUL_32_16(WEBRTC_SPL_RSHIFT_U32(tmpU32no3, 5), gammaNoise); // Q(prevQNoise+11) + } else + { + // We can do shifting after multiplication + tmpU32no2 + = WEBRTC_SPL_RSHIFT_U32(WEBRTC_SPL_UMUL_32_16(tmpU32no3, gammaNoise), 5); // Q(prevQNoise+11) + } + if (sign > 0) + { + noiseUpdateU32 += tmpU32no2; // Q(prevQNoise+11) + } else + { + // This operation is safe. We can never get wrap around, since worst + // case scenario means magnU16 = 0 + noiseUpdateU32 -= tmpU32no2; // Q(prevQNoise+11) + } + } + + //increase gamma (i.e., less noise update) for frame likely to be speech + prevGammaNoise = gammaNoise; + gammaNoise = NOISE_UPDATE_Q8; + //time-constant based on speech/noise state + //increase gamma (i.e., less noise update) for frames likely to be speech + if (nonSpeechProbFinal[i] < ONE_MINUS_PROB_RANGE_Q8) + { + gammaNoise = GAMMA_NOISE_TRANS_AND_SPEECH_Q8; + } + + if (prevGammaNoise != gammaNoise) + { + // new noise update + // this line is the same as above, only that the result is stored in a different variable and the gammaNoise + // has changed + // + // noiseUpdate = noisePrev[i] + (1 - gammaNoise) * nonSpeechProb * (magn[i] - noisePrev[i]) + + if (0x7c000000 & tmpU32no3) + { + // Shifting required before multiplication + tmpU32no2 + = WEBRTC_SPL_UMUL_32_16(WEBRTC_SPL_RSHIFT_U32(tmpU32no3, 5), gammaNoise); // Q(prevQNoise+11) + } else + { + // We can do shifting after multiplication + tmpU32no2 + = WEBRTC_SPL_RSHIFT_U32(WEBRTC_SPL_UMUL_32_16(tmpU32no3, gammaNoise), 5); // Q(prevQNoise+11) + } + if (sign > 0) + { + tmpU32no1 = inst->prevNoiseU32[i] + tmpU32no2; // Q(prevQNoise+11) + } else + { + tmpU32no1 = inst->prevNoiseU32[i] - tmpU32no2; // Q(prevQNoise+11) + } + if (noiseUpdateU32 > tmpU32no1) + { + noiseUpdateU32 = tmpU32no1; // Q(prevQNoise+11) + } + } + noiseU32[i] = noiseUpdateU32; // Q(prevQNoise+11) + if (noiseUpdateU32 > maxNoiseU32) + { + maxNoiseU32 = noiseUpdateU32; + } + + // conservative noise update + // // original FLOAT code + // if (prob_speech < PROB_RANGE) { + // inst->avgMagnPause[i] = inst->avgMagnPause[i] + (1.0 - gamma_pause)*(magn[i] - inst->avgMagnPause[i]); + // } + + tmp32no2 = WEBRTC_SPL_SHIFT_W32(inst->avgMagnPause[i], -nShifts); + if (nonSpeechProbFinal[i] > ONE_MINUS_PROB_RANGE_Q8) + { + if (nShifts < 0) + { + tmp32no1 = (WebRtc_Word32)magnU16[i] - tmp32no2; // Q(qMagn) + tmp32no1 = WEBRTC_SPL_MUL_32_16(tmp32no1, ONE_MINUS_GAMMA_PAUSE_Q8); // Q(8+prevQMagn+nShifts) + tmp32no1 = WEBRTC_SPL_RSHIFT_W32(tmp32no1 + 128, 8); // Q(qMagn) + } else + { + tmp32no1 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)magnU16[i], nShifts) + - inst->avgMagnPause[i]; // Q(qMagn+nShifts) + tmp32no1 = WEBRTC_SPL_MUL_32_16(tmp32no1, ONE_MINUS_GAMMA_PAUSE_Q8); // Q(8+prevQMagn+nShifts) + tmp32no1 = WEBRTC_SPL_RSHIFT_W32(tmp32no1 + (128 << nShifts), 8 + nShifts); // Q(qMagn) + } + tmp32no2 += tmp32no1; // Q(qMagn) + } + inst->avgMagnPause[i] = tmp32no2; + } // end of frequency loop + + norm32no1 = WebRtcSpl_NormU32(maxNoiseU32); + qNoise = inst->prevQNoise + norm32no1 - 5; + // done with step 2: noise update + + // STEP 3: compute dd update of prior snr and post snr based on new noise estimate + nShifts = inst->prevQNoise + 11 - qMagn; + for (i = 0; i < inst->magnLen; i++) + { + // FLOAT code + // // post and prior SNR + // curNearSnr = 0.0; + // if (magn[i] > noise[i]) + // { + // curNearSnr = magn[i] / (noise[i] + 0.0001) - 1.0; + // } + // // DD estimate is sum of two terms: current estimate and previous estimate + // // directed decision update of snrPrior + // snrPrior = DD_PR_SNR * prevNearSnr[i] + (1.0 - DD_PR_SNR) * curNearSnr; + // // gain filter + // tmpFloat1 = inst->overdrive + snrPrior; + // tmpFloat2 = snrPrior / tmpFloat1; + // theFilter[i] = tmpFloat2; + + // calculate curNearSnr again, this is necessary because a new noise estimate has been made since then. for the original + curNearSnr = 0; // Q11 + if (nShifts < 0) + { + // This case is equivalent with magn < noise which implies curNearSnr = 0; + tmpMagnU32 = (WebRtc_UWord32)magnU16[i]; // Q(qMagn) + tmpNoiseU32 = WEBRTC_SPL_LSHIFT_U32(noiseU32[i], -nShifts); // Q(qMagn) + } else if (nShifts > 17) + { + tmpMagnU32 = WEBRTC_SPL_LSHIFT_U32(magnU16[i], 17); // Q(qMagn+17) + tmpNoiseU32 = WEBRTC_SPL_RSHIFT_U32(noiseU32[i], nShifts - 17); // Q(qMagn+17) + } else + { + tmpMagnU32 = WEBRTC_SPL_LSHIFT_U32((WebRtc_UWord32)magnU16[i], nShifts); // Q(qNoise_prev+11) + tmpNoiseU32 = noiseU32[i]; // Q(qNoise_prev+11) + } + if (tmpMagnU32 > tmpNoiseU32) + { + tmpU32no1 = tmpMagnU32 - tmpNoiseU32; // Q(qCur) + norm32no2 = WEBRTC_SPL_MIN(11, WebRtcSpl_NormU32(tmpU32no1)); + tmpU32no1 = WEBRTC_SPL_LSHIFT_U32(tmpU32no1, norm32no2); // Q(qCur+norm32no2) + tmpU32no2 = WEBRTC_SPL_RSHIFT_U32(tmpNoiseU32, 11 - norm32no2); // Q(qCur+norm32no2-11) + if (tmpU32no2) + { + tmpU32no1 = WEBRTC_SPL_UDIV(tmpU32no1, tmpU32no2); // Q11 + } + curNearSnr = WEBRTC_SPL_MIN(satMax, tmpU32no1); // Q11 + } + + //directed decision update of priorSnr + // FLOAT + // priorSnr = DD_PR_SNR * prevNearSnr + (1.0-DD_PR_SNR) * curNearSnr; + + tmpU32no1 = WEBRTC_SPL_UMUL_32_16(prevNearSnr[i], DD_PR_SNR_Q11); // Q22 + tmpU32no2 = WEBRTC_SPL_UMUL_32_16(curNearSnr, ONE_MINUS_DD_PR_SNR_Q11); // Q22 + priorSnr = tmpU32no1 + tmpU32no2; // Q22 + + //gain filter + tmpU32no1 = (WebRtc_UWord32)(inst->overdrive) + + WEBRTC_SPL_RSHIFT_U32(priorSnr + 8192, 14); // Q8 + tmpU16no1 = (WebRtc_UWord16)WEBRTC_SPL_UDIV(priorSnr + (tmpU32no1 >> 1), tmpU32no1); // Q14 + inst->noiseSupFilter[i] = WEBRTC_SPL_SAT(16384, tmpU16no1, inst->denoiseBound); // 16384 = Q14(1.0) // Q14 + + // Weight in the parametric Wiener filter during startup + if (inst->blockIndex < END_STARTUP_SHORT) + { + // Weight the two suppression filters + tmpU32no1 = WEBRTC_SPL_UMUL_16_16(inst->noiseSupFilter[i], + (WebRtc_UWord16)inst->blockIndex); + tmpU32no2 = WEBRTC_SPL_UMUL_16_16(noiseSupFilterTmp[i], + (WebRtc_UWord16)(END_STARTUP_SHORT + - inst->blockIndex)); + tmpU32no1 += tmpU32no2; + inst->noiseSupFilter[i] = (WebRtc_UWord16)WebRtcSpl_DivU32U16(tmpU32no1, + END_STARTUP_SHORT); + } + } // end of loop over frequencies + //done with step3 + + // save noise and magnitude spectrum for next frame + inst->prevQNoise = qNoise; + inst->prevQMagn = qMagn; + if (norm32no1 > 5) + { + for (i = 0; i < inst->magnLen; i++) + { + inst->prevNoiseU32[i] = WEBRTC_SPL_LSHIFT_U32(noiseU32[i], norm32no1 - 5); // Q(qNoise+11) + inst->prevMagnU16[i] = magnU16[i]; // Q(qMagn) + } + } else + { + for (i = 0; i < inst->magnLen; i++) + { + inst->prevNoiseU32[i] = WEBRTC_SPL_RSHIFT_U32(noiseU32[i], 5 - norm32no1); // Q(qNoise+11) + inst->prevMagnU16[i] = magnU16[i]; // Q(qMagn) + } + } + + WebRtcNsx_DataSynthesis(inst, outFrame); +#ifdef NS_FILEDEBUG + fwrite(outframe, sizeof(short), inst->blockLen10ms, inst->outfile); +#endif + + //for H band: + // only update data buffer, then apply time-domain gain is applied derived from L band + if (inst->fs == 32000) + { + // update analysis buffer for H band + // append new data to buffer FX + WEBRTC_SPL_MEMCPY_W16(inst->dataBufHBFX, inst->dataBufHBFX + inst->blockLen10ms, inst->anaLen - inst->blockLen10ms); + WEBRTC_SPL_MEMCPY_W16(inst->dataBufHBFX + inst->anaLen - inst->blockLen10ms, speechFrameHB, inst->blockLen10ms); + // range for averaging low band quantities for H band gain + + gainTimeDomainHB = 16384; // 16384 = Q14(1.0) + //average speech prob from low band + //average filter gain from low band + //avg over second half (i.e., 4->8kHz) of freq. spectrum + tmpU32no1 = 0; // Q12 + tmpU16no1 = 0; // Q8 + for (i = inst->anaLen2 - (inst->anaLen2 >> 2); i < inst->anaLen2; i++) + { + tmpU16no1 += nonSpeechProbFinal[i]; // Q8 + tmpU32no1 += (WebRtc_UWord32)(inst->noiseSupFilter[i]); // Q14 + } + avgProbSpeechHB = (WebRtc_Word16)(4096 + - WEBRTC_SPL_RSHIFT_U16(tmpU16no1, inst->stages - 7)); // Q12 + avgFilterGainHB = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(tmpU32no1, inst->stages - 3); // Q14 + + // // original FLOAT code + // // gain based on speech probability: + // avg_prob_speech_tt=(float)2.0*avg_prob_speech-(float)1.0; + // gain_mod=(float)0.5*((float)1.0+(float)tanh(avg_prob_speech_tt)); // between 0 and 1 + + // gain based on speech probability: + // original expression: "0.5 * (1 + tanh(2x-1))" + // avgProbSpeechHB has been anyway saturated to a value between 0 and 1 so the other cases don't have to be dealt with + // avgProbSpeechHB and gainModHB are in Q12, 3607 = Q12(0.880615234375) which is a zero point of + // |0.5 * (1 + tanh(2x-1)) - x| - |0.5 * (1 + tanh(2x-1)) - 0.880615234375| meaning that from that point the error of approximating + // the expression with f(x) = x would be greater than the error of approximating the expression with f(x) = 0.880615234375 + // error: "|0.5 * (1 + tanh(2x-1)) - x| from x=0 to 0.880615234375" -> http://www.wolframalpha.com/input/?i=|0.5+*+(1+%2B+tanh(2x-1))+-+x|+from+x%3D0+to+0.880615234375 + // and: "|0.5 * (1 + tanh(2x-1)) - 0.880615234375| from x=0.880615234375 to 1" -> http://www.wolframalpha.com/input/?i=+|0.5+*+(1+%2B+tanh(2x-1))+-+0.880615234375|+from+x%3D0.880615234375+to+1 + gainModHB = WEBRTC_SPL_MIN(avgProbSpeechHB, 3607); + + // // original FLOAT code + // //combine gain with low band gain + // if (avg_prob_speech < (float)0.5) { + // gain_time_domain_HB=(float)0.5*gain_mod+(float)0.5*avg_filter_gain; + // } + // else { + // gain_time_domain_HB=(float)0.25*gain_mod+(float)0.75*avg_filter_gain; + // } + + + //combine gain with low band gain + if (avgProbSpeechHB < 2048) + { // 2048 = Q12(0.5) + // the next two lines in float are "gain_time_domain = 0.5 * gain_mod + 0.5 * avg_filter_gain"; Q2(0.5) = 2 equals one left shift + gainTimeDomainHB = (gainModHB << 1) + (avgFilterGainHB >> 1); // Q14 + } else + { + // "gain_time_domain = 0.25 * gain_mod + 0.75 * agv_filter_gain;" + gainTimeDomainHB = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(3, avgFilterGainHB, 2); // 3 = Q2(0.75); Q14 + gainTimeDomainHB += gainModHB; // Q14 + } + //make sure gain is within flooring range + gainTimeDomainHB + = WEBRTC_SPL_SAT(16384, gainTimeDomainHB, (WebRtc_Word16)(inst->denoiseBound)); // 16384 = Q14(1.0) + + + //apply gain + for (i = 0; i < inst->blockLen10ms; i++) + { + outFrameHB[i] + = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gainTimeDomainHB, inst->dataBufHBFX[i], 14); // Q0 + } + } // end of H band gain computation + + return 0; +} diff --git a/src/libs/webrtc/ns/nsx_core.h b/src/libs/webrtc/ns/nsx_core.h new file mode 100644 index 00000000..2e743035 --- /dev/null +++ b/src/libs/webrtc/ns/nsx_core.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_CORE_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_CORE_H_ + +#include "typedefs.h" +#include "signal_processing_library.h" + +#include "nsx_defines.h" + +#ifdef NS_FILEDEBUG +#include <stdio.h> +#endif + +typedef struct NsxInst_t_ +{ + WebRtc_UWord32 fs; + + const WebRtc_Word16* window; + WebRtc_Word16 analysisBuffer[ANAL_BLOCKL_MAX]; + WebRtc_Word16 synthesisBuffer[ANAL_BLOCKL_MAX]; + WebRtc_UWord16 noiseSupFilter[HALF_ANAL_BLOCKL]; + WebRtc_UWord16 overdrive; /* Q8 */ + WebRtc_UWord16 denoiseBound; /* Q14 */ + const WebRtc_Word16* factor2Table; + WebRtc_Word16 noiseEstLogQuantile[SIMULT * HALF_ANAL_BLOCKL]; + WebRtc_Word16 noiseEstDensity[SIMULT * HALF_ANAL_BLOCKL]; + WebRtc_Word16 noiseEstCounter[SIMULT]; + WebRtc_Word16 noiseEstQuantile[HALF_ANAL_BLOCKL]; + + WebRtc_Word16 anaLen; + int anaLen2; + int magnLen; + int aggrMode; + int stages; + int initFlag; + int gainMap; + + WebRtc_Word32 maxLrt; + WebRtc_Word32 minLrt; + WebRtc_Word32 logLrtTimeAvgW32[HALF_ANAL_BLOCKL]; //log lrt factor with time-smoothing in Q8 + WebRtc_Word32 featureLogLrt; + WebRtc_Word32 thresholdLogLrt; + WebRtc_Word16 weightLogLrt; + + WebRtc_UWord32 featureSpecDiff; + WebRtc_UWord32 thresholdSpecDiff; + WebRtc_Word16 weightSpecDiff; + + WebRtc_UWord32 featureSpecFlat; + WebRtc_UWord32 thresholdSpecFlat; + WebRtc_Word16 weightSpecFlat; + + WebRtc_Word32 avgMagnPause[HALF_ANAL_BLOCKL]; //conservative estimate of noise spectrum + WebRtc_UWord32 magnEnergy; + WebRtc_UWord32 sumMagn; + WebRtc_UWord32 curAvgMagnEnergy; + WebRtc_UWord32 timeAvgMagnEnergy; + WebRtc_UWord32 timeAvgMagnEnergyTmp; + + WebRtc_UWord32 whiteNoiseLevel; //initial noise estimate + WebRtc_UWord32 initMagnEst[HALF_ANAL_BLOCKL];//initial magnitude spectrum estimate + WebRtc_Word32 pinkNoiseNumerator; //pink noise parameter: numerator + WebRtc_Word32 pinkNoiseExp; //pink noise parameter: power of freq + int minNorm; //smallest normalization factor + int zeroInputSignal; //zero input signal flag + + WebRtc_UWord32 prevNoiseU32[HALF_ANAL_BLOCKL]; //noise spectrum from previous frame + WebRtc_UWord16 prevMagnU16[HALF_ANAL_BLOCKL]; //magnitude spectrum from previous frame + WebRtc_Word16 priorNonSpeechProb; //prior speech/noise probability // Q14 + + int blockIndex; //frame index counter + int modelUpdate; //parameter for updating or estimating thresholds/weights for prior model + int cntThresUpdate; + + //histograms for parameter estimation + WebRtc_Word16 histLrt[HIST_PAR_EST]; + WebRtc_Word16 histSpecFlat[HIST_PAR_EST]; + WebRtc_Word16 histSpecDiff[HIST_PAR_EST]; + + //quantities for high band estimate + WebRtc_Word16 dataBufHBFX[ANAL_BLOCKL_MAX]; /* Q0 */ + + int qNoise; + int prevQNoise; + int prevQMagn; + int blockLen10ms; + + WebRtc_Word16 real[ANAL_BLOCKL_MAX]; + WebRtc_Word16 imag[ANAL_BLOCKL_MAX]; + WebRtc_Word32 energyIn; + int scaleEnergyIn; + int normData; + +} NsxInst_t; + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * WebRtcNsx_InitCore(...) + * + * This function initializes a noise suppression instance + * + * Input: + * - inst : Instance that should be initialized + * - fs : Sampling frequency + * + * Output: + * - inst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ +WebRtc_Word32 WebRtcNsx_InitCore(NsxInst_t *inst, WebRtc_UWord32 fs); + +/**************************************************************************** + * WebRtcNsx_set_policy_core(...) + * + * This changes the aggressiveness of the noise suppression method. + * + * Input: + * - inst : Instance that should be initialized + * - mode : 0: Mild (6 dB), 1: Medium (10 dB), 2: Aggressive (15 dB) + * + * Output: + * - NS_inst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcNsx_set_policy_core(NsxInst_t *inst, int mode); + +/**************************************************************************** + * WebRtcNsx_ProcessCore + * + * Do noise suppression. + * + * Input: + * - inst : Instance that should be initialized + * - inFrameLow : Input speech frame for lower band + * - inFrameHigh : Input speech frame for higher band + * + * Output: + * - inst : Updated instance + * - outFrameLow : Output speech frame for lower band + * - outFrameHigh : Output speech frame for higher band + * + * Return value : 0 - OK + * -1 - Error + */ +int WebRtcNsx_ProcessCore(NsxInst_t *inst, short *inFrameLow, short *inFrameHigh, + short *outFrameLow, short *outFrameHigh); + +#ifdef __cplusplus +} +#endif + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_CORE_H_ diff --git a/src/libs/webrtc/ns/nsx_defines.h b/src/libs/webrtc/ns/nsx_defines.h new file mode 100644 index 00000000..58796b9a --- /dev/null +++ b/src/libs/webrtc/ns/nsx_defines.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_ + +#define ANAL_BLOCKL_MAX 256 // max analysis block length +#define HALF_ANAL_BLOCKL 129 // half max analysis block length + 1 +#define SIMULT 3 +#define END_STARTUP_LONG 200 +#define END_STARTUP_SHORT 50 +#define FACTOR_Q16 (WebRtc_Word32)2621440 // 40 in Q16 +#define FACTOR_Q7 (WebRtc_Word16)5120 // 40 in Q7 +#define WIDTH_Q8 3 // 0.01 in Q8 (or 25 ) +//PARAMETERS FOR NEW METHOD +#define DD_PR_SNR_Q11 2007 // ~= Q11(0.98) DD update of prior SNR +#define ONE_MINUS_DD_PR_SNR_Q11 41 // DD update of prior SNR +#define SPECT_FLAT_TAVG_Q14 4915 // (0.30) tavg parameter for spectral flatness measure +#define SPECT_DIFF_TAVG_Q8 77 // (0.30) tavg parameter for spectral flatness measure +#define PRIOR_UPDATE_Q14 1638 // Q14(0.1) update parameter of prior model +#define NOISE_UPDATE_Q8 26 // 26 ~= Q8(0.1) update parameter for noise +// probability threshold for noise state in speech/noise likelihood +#define ONE_MINUS_PROB_RANGE_Q8 205 // 205 ~= Q8(0.8) +#define HIST_PAR_EST 1000 // histogram size for estimation of parameters +//FEATURE EXTRACTION CONFIG +//bin size of histogram +#define BIN_SIZE_LRT 10 +//scale parameters: multiply dominant peaks of the histograms by scale factor to obtain +// thresholds for prior model +#define FACTOR_1_LRT_DIFF 6 //for LRT and spectral difference (5 times bigger) +//for spectral_flatness: used when noise is flatter than speech (10 times bigger) +#define FACTOR_2_FLAT_Q10 922 +//peak limit for spectral flatness (varies between 0 and 1) +#define THRES_PEAK_FLAT 24 // * 2 * BIN_SIZE_FLAT_FX +//limit on spacing of two highest peaks in histogram: spacing determined by bin size +#define LIM_PEAK_SPACE_FLAT_DIFF 4 // * 2 * BIN_SIZE_DIFF_FX +//limit on relevance of second peak: +#define LIM_PEAK_WEIGHT_FLAT_DIFF 2 +#define THRES_FLUCT_LRT 10240 //=20 * inst->modelUpdate; fluctuation limit of LRT feat. +//limit on the max and min values for the feature thresholds +#define MAX_FLAT_Q10 38912 // * 2 * BIN_SIZE_FLAT_FX +#define MIN_FLAT_Q10 4096 // * 2 * BIN_SIZE_FLAT_FX +#define MAX_DIFF 100 // * 2 * BIN_SIZE_DIFF_FX +#define MIN_DIFF 16 // * 2 * BIN_SIZE_DIFF_FX +//criteria of weight of histogram peak to accept/reject feature +#define THRES_WEIGHT_FLAT_DIFF 154//(int)(0.3*(inst->modelUpdate)) for flatness and difference +// +#define STAT_UPDATES 9 // Update every 512 = 1 << 9 block +#define ONE_MINUS_GAMMA_PAUSE_Q8 13 // ~= Q8(0.05) update for conservative noise estimate +#define GAMMA_NOISE_TRANS_AND_SPEECH_Q8 3 // ~= Q8(0.01) update for transition and noise region +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_NSX_DEFINES_H_ diff --git a/src/libs/webrtc/ns/windows_private.h b/src/libs/webrtc/ns/windows_private.h new file mode 100644 index 00000000..8f9006ed --- /dev/null +++ b/src/libs/webrtc/ns/windows_private.h @@ -0,0 +1,573 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_WINDOWS_PRIVATE_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_WINDOWS_PRIVATE_H_ + +// Hanning window for 4ms 16kHz +static const float kHanning64w128[128] = { +0.00000000000000f, 0.02454122852291f, 0.04906767432742f, +0.07356456359967f, 0.09801714032956f, 0.12241067519922f, +0.14673047445536f, 0.17096188876030f, 0.19509032201613f, +0.21910124015687f, 0.24298017990326f, 0.26671275747490f, +0.29028467725446f, 0.31368174039889f, 0.33688985339222f, +0.35989503653499f, 0.38268343236509f, 0.40524131400499f, +0.42755509343028f, 0.44961132965461f, 0.47139673682600f, +0.49289819222978f, 0.51410274419322f, 0.53499761988710f, +0.55557023301960f, 0.57580819141785f, 0.59569930449243f, +0.61523159058063f, 0.63439328416365f, 0.65317284295378f, +0.67155895484702f, 0.68954054473707f, 0.70710678118655f, +0.72424708295147f, 0.74095112535496f, 0.75720884650648f, +0.77301045336274f, 0.78834642762661f, 0.80320753148064f, +0.81758481315158f, 0.83146961230255f, 0.84485356524971f, +0.85772861000027f, 0.87008699110871f, 0.88192126434835f, +0.89322430119552f, 0.90398929312344f, 0.91420975570353f, +0.92387953251129f, 0.93299279883474f, 0.94154406518302f, +0.94952818059304f, 0.95694033573221f, 0.96377606579544f, +0.97003125319454f, 0.97570213003853f, 0.98078528040323f, +0.98527764238894f, 0.98917650996478f, 0.99247953459871f, +0.99518472667220f, 0.99729045667869f, 0.99879545620517f, +0.99969881869620f, 1.00000000000000f, +0.99969881869620f, 0.99879545620517f, 0.99729045667869f, +0.99518472667220f, 0.99247953459871f, 0.98917650996478f, +0.98527764238894f, 0.98078528040323f, 0.97570213003853f, +0.97003125319454f, 0.96377606579544f, 0.95694033573221f, +0.94952818059304f, 0.94154406518302f, 0.93299279883474f, +0.92387953251129f, 0.91420975570353f, 0.90398929312344f, +0.89322430119552f, 0.88192126434835f, 0.87008699110871f, +0.85772861000027f, 0.84485356524971f, 0.83146961230255f, +0.81758481315158f, 0.80320753148064f, 0.78834642762661f, +0.77301045336274f, 0.75720884650648f, 0.74095112535496f, +0.72424708295147f, 0.70710678118655f, 0.68954054473707f, +0.67155895484702f, 0.65317284295378f, 0.63439328416365f, +0.61523159058063f, 0.59569930449243f, 0.57580819141785f, +0.55557023301960f, 0.53499761988710f, 0.51410274419322f, +0.49289819222978f, 0.47139673682600f, 0.44961132965461f, +0.42755509343028f, 0.40524131400499f, 0.38268343236509f, +0.35989503653499f, 0.33688985339222f, 0.31368174039889f, +0.29028467725446f, 0.26671275747490f, 0.24298017990326f, +0.21910124015687f, 0.19509032201613f, 0.17096188876030f, +0.14673047445536f, 0.12241067519922f, 0.09801714032956f, +0.07356456359967f, 0.04906767432742f, 0.02454122852291f +}; + + + +// hybrib Hanning & flat window +static const float kBlocks80w128[128] = { +(float)0.00000000, (float)0.03271908, (float)0.06540313, (float)0.09801714, (float)0.13052619, +(float)0.16289547, (float)0.19509032, (float)0.22707626, (float)0.25881905, (float)0.29028468, +(float)0.32143947, (float)0.35225005, (float)0.38268343, (float)0.41270703, (float)0.44228869, +(float)0.47139674, (float)0.50000000, (float)0.52806785, (float)0.55557023, (float)0.58247770, +(float)0.60876143, (float)0.63439328, (float)0.65934582, (float)0.68359230, (float)0.70710678, +(float)0.72986407, (float)0.75183981, (float)0.77301045, (float)0.79335334, (float)0.81284668, +(float)0.83146961, (float)0.84920218, (float)0.86602540, (float)0.88192126, (float)0.89687274, +(float)0.91086382, (float)0.92387953, (float)0.93590593, (float)0.94693013, (float)0.95694034, +(float)0.96592583, (float)0.97387698, (float)0.98078528, (float)0.98664333, (float)0.99144486, +(float)0.99518473, (float)0.99785892, (float)0.99946459, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)0.99946459, (float)0.99785892, (float)0.99518473, (float)0.99144486, +(float)0.98664333, (float)0.98078528, (float)0.97387698, (float)0.96592583, (float)0.95694034, +(float)0.94693013, (float)0.93590593, (float)0.92387953, (float)0.91086382, (float)0.89687274, +(float)0.88192126, (float)0.86602540, (float)0.84920218, (float)0.83146961, (float)0.81284668, +(float)0.79335334, (float)0.77301045, (float)0.75183981, (float)0.72986407, (float)0.70710678, +(float)0.68359230, (float)0.65934582, (float)0.63439328, (float)0.60876143, (float)0.58247770, +(float)0.55557023, (float)0.52806785, (float)0.50000000, (float)0.47139674, (float)0.44228869, +(float)0.41270703, (float)0.38268343, (float)0.35225005, (float)0.32143947, (float)0.29028468, +(float)0.25881905, (float)0.22707626, (float)0.19509032, (float)0.16289547, (float)0.13052619, +(float)0.09801714, (float)0.06540313, (float)0.03271908 +}; + +// hybrib Hanning & flat window +static const float kBlocks160w256[256] = { +(float)0.00000000, (float)0.01636173, (float)0.03271908, (float)0.04906767, (float)0.06540313, +(float)0.08172107, (float)0.09801714, (float)0.11428696, (float)0.13052619, (float)0.14673047, +(float)0.16289547, (float)0.17901686, (float)0.19509032, (float)0.21111155, (float)0.22707626, +(float)0.24298018, (float)0.25881905, (float)0.27458862, (float)0.29028468, (float)0.30590302, +(float)0.32143947, (float)0.33688985, (float)0.35225005, (float)0.36751594, (float)0.38268343, +(float)0.39774847, (float)0.41270703, (float)0.42755509, (float)0.44228869, (float)0.45690388, +(float)0.47139674, (float)0.48576339, (float)0.50000000, (float)0.51410274, (float)0.52806785, +(float)0.54189158, (float)0.55557023, (float)0.56910015, (float)0.58247770, (float)0.59569930, +(float)0.60876143, (float)0.62166057, (float)0.63439328, (float)0.64695615, (float)0.65934582, +(float)0.67155895, (float)0.68359230, (float)0.69544264, (float)0.70710678, (float)0.71858162, +(float)0.72986407, (float)0.74095113, (float)0.75183981, (float)0.76252720, (float)0.77301045, +(float)0.78328675, (float)0.79335334, (float)0.80320753, (float)0.81284668, (float)0.82226822, +(float)0.83146961, (float)0.84044840, (float)0.84920218, (float)0.85772861, (float)0.86602540, +(float)0.87409034, (float)0.88192126, (float)0.88951608, (float)0.89687274, (float)0.90398929, +(float)0.91086382, (float)0.91749450, (float)0.92387953, (float)0.93001722, (float)0.93590593, +(float)0.94154407, (float)0.94693013, (float)0.95206268, (float)0.95694034, (float)0.96156180, +(float)0.96592583, (float)0.97003125, (float)0.97387698, (float)0.97746197, (float)0.98078528, +(float)0.98384601, (float)0.98664333, (float)0.98917651, (float)0.99144486, (float)0.99344778, +(float)0.99518473, (float)0.99665524, (float)0.99785892, (float)0.99879546, (float)0.99946459, +(float)0.99986614, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)0.99986614, (float)0.99946459, (float)0.99879546, (float)0.99785892, +(float)0.99665524, (float)0.99518473, (float)0.99344778, (float)0.99144486, (float)0.98917651, +(float)0.98664333, (float)0.98384601, (float)0.98078528, (float)0.97746197, (float)0.97387698, +(float)0.97003125, (float)0.96592583, (float)0.96156180, (float)0.95694034, (float)0.95206268, +(float)0.94693013, (float)0.94154407, (float)0.93590593, (float)0.93001722, (float)0.92387953, +(float)0.91749450, (float)0.91086382, (float)0.90398929, (float)0.89687274, (float)0.88951608, +(float)0.88192126, (float)0.87409034, (float)0.86602540, (float)0.85772861, (float)0.84920218, +(float)0.84044840, (float)0.83146961, (float)0.82226822, (float)0.81284668, (float)0.80320753, +(float)0.79335334, (float)0.78328675, (float)0.77301045, (float)0.76252720, (float)0.75183981, +(float)0.74095113, (float)0.72986407, (float)0.71858162, (float)0.70710678, (float)0.69544264, +(float)0.68359230, (float)0.67155895, (float)0.65934582, (float)0.64695615, (float)0.63439328, +(float)0.62166057, (float)0.60876143, (float)0.59569930, (float)0.58247770, (float)0.56910015, +(float)0.55557023, (float)0.54189158, (float)0.52806785, (float)0.51410274, (float)0.50000000, +(float)0.48576339, (float)0.47139674, (float)0.45690388, (float)0.44228869, (float)0.42755509, +(float)0.41270703, (float)0.39774847, (float)0.38268343, (float)0.36751594, (float)0.35225005, +(float)0.33688985, (float)0.32143947, (float)0.30590302, (float)0.29028468, (float)0.27458862, +(float)0.25881905, (float)0.24298018, (float)0.22707626, (float)0.21111155, (float)0.19509032, +(float)0.17901686, (float)0.16289547, (float)0.14673047, (float)0.13052619, (float)0.11428696, +(float)0.09801714, (float)0.08172107, (float)0.06540313, (float)0.04906767, (float)0.03271908, +(float)0.01636173 +}; + +// hybrib Hanning & flat window: for 20ms +static const float kBlocks320w512[512] = { +(float)0.00000000, (float)0.00818114, (float)0.01636173, (float)0.02454123, (float)0.03271908, +(float)0.04089475, (float)0.04906767, (float)0.05723732, (float)0.06540313, (float)0.07356456, +(float)0.08172107, (float)0.08987211, (float)0.09801714, (float)0.10615561, (float)0.11428696, +(float)0.12241068, (float)0.13052619, (float)0.13863297, (float)0.14673047, (float)0.15481816, +(float)0.16289547, (float)0.17096189, (float)0.17901686, (float)0.18705985, (float)0.19509032, +(float)0.20310773, (float)0.21111155, (float)0.21910124, (float)0.22707626, (float)0.23503609, +(float)0.24298018, (float)0.25090801, (float)0.25881905, (float)0.26671276, (float)0.27458862, +(float)0.28244610, (float)0.29028468, (float)0.29810383, (float)0.30590302, (float)0.31368174, +(float)0.32143947, (float)0.32917568, (float)0.33688985, (float)0.34458148, (float)0.35225005, +(float)0.35989504, (float)0.36751594, (float)0.37511224, (float)0.38268343, (float)0.39022901, +(float)0.39774847, (float)0.40524131, (float)0.41270703, (float)0.42014512, (float)0.42755509, +(float)0.43493645, (float)0.44228869, (float)0.44961133, (float)0.45690388, (float)0.46416584, +(float)0.47139674, (float)0.47859608, (float)0.48576339, (float)0.49289819, (float)0.50000000, +(float)0.50706834, (float)0.51410274, (float)0.52110274, (float)0.52806785, (float)0.53499762, +(float)0.54189158, (float)0.54874927, (float)0.55557023, (float)0.56235401, (float)0.56910015, +(float)0.57580819, (float)0.58247770, (float)0.58910822, (float)0.59569930, (float)0.60225052, +(float)0.60876143, (float)0.61523159, (float)0.62166057, (float)0.62804795, (float)0.63439328, +(float)0.64069616, (float)0.64695615, (float)0.65317284, (float)0.65934582, (float)0.66547466, +(float)0.67155895, (float)0.67759830, (float)0.68359230, (float)0.68954054, (float)0.69544264, +(float)0.70129818, (float)0.70710678, (float)0.71286806, (float)0.71858162, (float)0.72424708, +(float)0.72986407, (float)0.73543221, (float)0.74095113, (float)0.74642045, (float)0.75183981, +(float)0.75720885, (float)0.76252720, (float)0.76779452, (float)0.77301045, (float)0.77817464, +(float)0.78328675, (float)0.78834643, (float)0.79335334, (float)0.79830715, (float)0.80320753, +(float)0.80805415, (float)0.81284668, (float)0.81758481, (float)0.82226822, (float)0.82689659, +(float)0.83146961, (float)0.83598698, (float)0.84044840, (float)0.84485357, (float)0.84920218, +(float)0.85349396, (float)0.85772861, (float)0.86190585, (float)0.86602540, (float)0.87008699, +(float)0.87409034, (float)0.87803519, (float)0.88192126, (float)0.88574831, (float)0.88951608, +(float)0.89322430, (float)0.89687274, (float)0.90046115, (float)0.90398929, (float)0.90745693, +(float)0.91086382, (float)0.91420976, (float)0.91749450, (float)0.92071783, (float)0.92387953, +(float)0.92697940, (float)0.93001722, (float)0.93299280, (float)0.93590593, (float)0.93875641, +(float)0.94154407, (float)0.94426870, (float)0.94693013, (float)0.94952818, (float)0.95206268, +(float)0.95453345, (float)0.95694034, (float)0.95928317, (float)0.96156180, (float)0.96377607, +(float)0.96592583, (float)0.96801094, (float)0.97003125, (float)0.97198664, (float)0.97387698, +(float)0.97570213, (float)0.97746197, (float)0.97915640, (float)0.98078528, (float)0.98234852, +(float)0.98384601, (float)0.98527764, (float)0.98664333, (float)0.98794298, (float)0.98917651, +(float)0.99034383, (float)0.99144486, (float)0.99247953, (float)0.99344778, (float)0.99434953, +(float)0.99518473, (float)0.99595331, (float)0.99665524, (float)0.99729046, (float)0.99785892, +(float)0.99836060, (float)0.99879546, (float)0.99916346, (float)0.99946459, (float)0.99969882, +(float)0.99986614, (float)0.99996653, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, (float)1.00000000, +(float)1.00000000, (float)0.99996653, (float)0.99986614, (float)0.99969882, (float)0.99946459, +(float)0.99916346, (float)0.99879546, (float)0.99836060, (float)0.99785892, (float)0.99729046, +(float)0.99665524, (float)0.99595331, (float)0.99518473, (float)0.99434953, (float)0.99344778, +(float)0.99247953, (float)0.99144486, (float)0.99034383, (float)0.98917651, (float)0.98794298, +(float)0.98664333, (float)0.98527764, (float)0.98384601, (float)0.98234852, (float)0.98078528, +(float)0.97915640, (float)0.97746197, (float)0.97570213, (float)0.97387698, (float)0.97198664, +(float)0.97003125, (float)0.96801094, (float)0.96592583, (float)0.96377607, (float)0.96156180, +(float)0.95928317, (float)0.95694034, (float)0.95453345, (float)0.95206268, (float)0.94952818, +(float)0.94693013, (float)0.94426870, (float)0.94154407, (float)0.93875641, (float)0.93590593, +(float)0.93299280, (float)0.93001722, (float)0.92697940, (float)0.92387953, (float)0.92071783, +(float)0.91749450, (float)0.91420976, (float)0.91086382, (float)0.90745693, (float)0.90398929, +(float)0.90046115, (float)0.89687274, (float)0.89322430, (float)0.88951608, (float)0.88574831, +(float)0.88192126, (float)0.87803519, (float)0.87409034, (float)0.87008699, (float)0.86602540, +(float)0.86190585, (float)0.85772861, (float)0.85349396, (float)0.84920218, (float)0.84485357, +(float)0.84044840, (float)0.83598698, (float)0.83146961, (float)0.82689659, (float)0.82226822, +(float)0.81758481, (float)0.81284668, (float)0.80805415, (float)0.80320753, (float)0.79830715, +(float)0.79335334, (float)0.78834643, (float)0.78328675, (float)0.77817464, (float)0.77301045, +(float)0.76779452, (float)0.76252720, (float)0.75720885, (float)0.75183981, (float)0.74642045, +(float)0.74095113, (float)0.73543221, (float)0.72986407, (float)0.72424708, (float)0.71858162, +(float)0.71286806, (float)0.70710678, (float)0.70129818, (float)0.69544264, (float)0.68954054, +(float)0.68359230, (float)0.67759830, (float)0.67155895, (float)0.66547466, (float)0.65934582, +(float)0.65317284, (float)0.64695615, (float)0.64069616, (float)0.63439328, (float)0.62804795, +(float)0.62166057, (float)0.61523159, (float)0.60876143, (float)0.60225052, (float)0.59569930, +(float)0.58910822, (float)0.58247770, (float)0.57580819, (float)0.56910015, (float)0.56235401, +(float)0.55557023, (float)0.54874927, (float)0.54189158, (float)0.53499762, (float)0.52806785, +(float)0.52110274, (float)0.51410274, (float)0.50706834, (float)0.50000000, (float)0.49289819, +(float)0.48576339, (float)0.47859608, (float)0.47139674, (float)0.46416584, (float)0.45690388, +(float)0.44961133, (float)0.44228869, (float)0.43493645, (float)0.42755509, (float)0.42014512, +(float)0.41270703, (float)0.40524131, (float)0.39774847, (float)0.39022901, (float)0.38268343, +(float)0.37511224, (float)0.36751594, (float)0.35989504, (float)0.35225005, (float)0.34458148, +(float)0.33688985, (float)0.32917568, (float)0.32143947, (float)0.31368174, (float)0.30590302, +(float)0.29810383, (float)0.29028468, (float)0.28244610, (float)0.27458862, (float)0.26671276, +(float)0.25881905, (float)0.25090801, (float)0.24298018, (float)0.23503609, (float)0.22707626, +(float)0.21910124, (float)0.21111155, (float)0.20310773, (float)0.19509032, (float)0.18705985, +(float)0.17901686, (float)0.17096189, (float)0.16289547, (float)0.15481816, (float)0.14673047, +(float)0.13863297, (float)0.13052619, (float)0.12241068, (float)0.11428696, (float)0.10615561, +(float)0.09801714, (float)0.08987211, (float)0.08172107, (float)0.07356456, (float)0.06540313, +(float)0.05723732, (float)0.04906767, (float)0.04089475, (float)0.03271908, (float)0.02454123, +(float)0.01636173, (float)0.00818114 +}; + + +// Hanning window: for 15ms at 16kHz with symmetric zeros +static const float kBlocks240w512[512] = { +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00654494, (float)0.01308960, (float)0.01963369, +(float)0.02617695, (float)0.03271908, (float)0.03925982, (float)0.04579887, (float)0.05233596, +(float)0.05887080, (float)0.06540313, (float)0.07193266, (float)0.07845910, (float)0.08498218, +(float)0.09150162, (float)0.09801714, (float)0.10452846, (float)0.11103531, (float)0.11753740, +(float)0.12403446, (float)0.13052620, (float)0.13701233, (float)0.14349262, (float)0.14996676, +(float)0.15643448, (float)0.16289547, (float)0.16934951, (float)0.17579629, (float)0.18223552, +(float)0.18866697, (float)0.19509032, (float)0.20150533, (float)0.20791170, (float)0.21430916, +(float)0.22069745, (float)0.22707628, (float)0.23344538, (float)0.23980446, (float)0.24615330, +(float)0.25249159, (float)0.25881904, (float)0.26513544, (float)0.27144045, (float)0.27773386, +(float)0.28401536, (float)0.29028466, (float)0.29654160, (float)0.30278578, (float)0.30901700, +(float)0.31523499, (float)0.32143945, (float)0.32763019, (float)0.33380687, (float)0.33996925, +(float)0.34611708, (float)0.35225007, (float)0.35836795, (float)0.36447051, (float)0.37055743, +(float)0.37662852, (float)0.38268346, (float)0.38872197, (float)0.39474389, (float)0.40074885, +(float)0.40673664, (float)0.41270703, (float)0.41865975, (float)0.42459452, (float)0.43051112, +(float)0.43640924, (float)0.44228873, (float)0.44814920, (float)0.45399052, (float)0.45981237, +(float)0.46561453, (float)0.47139674, (float)0.47715878, (float)0.48290035, (float)0.48862126, +(float)0.49432120, (float)0.50000000, (float)0.50565743, (float)0.51129311, (float)0.51690692, +(float)0.52249855, (float)0.52806789, (float)0.53361452, (float)0.53913832, (float)0.54463905, +(float)0.55011642, (float)0.55557024, (float)0.56100029, (float)0.56640625, (float)0.57178795, +(float)0.57714522, (float)0.58247769, (float)0.58778524, (float)0.59306765, (float)0.59832460, +(float)0.60355598, (float)0.60876143, (float)0.61394083, (float)0.61909395, (float)0.62422055, +(float)0.62932038, (float)0.63439333, (float)0.63943899, (float)0.64445734, (float)0.64944810, +(float)0.65441096, (float)0.65934587, (float)0.66425246, (float)0.66913062, (float)0.67398012, +(float)0.67880076, (float)0.68359232, (float)0.68835455, (float)0.69308740, (float)0.69779050, +(float)0.70246369, (float)0.70710677, (float)0.71171963, (float)0.71630198, (float)0.72085363, +(float)0.72537440, (float)0.72986406, (float)0.73432255, (float)0.73874950, (float)0.74314487, +(float)0.74750835, (float)0.75183982, (float)0.75613910, (float)0.76040596, (float)0.76464027, +(float)0.76884186, (float)0.77301043, (float)0.77714598, (float)0.78124821, (float)0.78531694, +(float)0.78935206, (float)0.79335338, (float)0.79732066, (float)0.80125386, (float)0.80515265, +(float)0.80901700, (float)0.81284672, (float)0.81664157, (float)0.82040149, (float)0.82412618, +(float)0.82781565, (float)0.83146966, (float)0.83508795, (float)0.83867061, (float)0.84221727, +(float)0.84572780, (float)0.84920216, (float)0.85264021, (float)0.85604161, (float)0.85940641, +(float)0.86273444, (float)0.86602545, (float)0.86927933, (float)0.87249607, (float)0.87567532, +(float)0.87881714, (float)0.88192129, (float)0.88498765, (float)0.88801610, (float)0.89100653, +(float)0.89395881, (float)0.89687276, (float)0.89974827, (float)0.90258533, (float)0.90538365, +(float)0.90814316, (float)0.91086388, (float)0.91354549, (float)0.91618794, (float)0.91879123, +(float)0.92135513, (float)0.92387950, (float)0.92636442, (float)0.92880958, (float)0.93121493, +(float)0.93358046, (float)0.93590593, (float)0.93819135, (float)0.94043654, (float)0.94264150, +(float)0.94480604, (float)0.94693011, (float)0.94901365, (float)0.95105654, (float)0.95305866, +(float)0.95501995, (float)0.95694035, (float)0.95881975, (float)0.96065807, (float)0.96245527, +(float)0.96421117, (float)0.96592581, (float)0.96759909, (float)0.96923089, (float)0.97082120, +(float)0.97236991, (float)0.97387701, (float)0.97534233, (float)0.97676587, (float)0.97814763, +(float)0.97948742, (float)0.98078531, (float)0.98204112, (float)0.98325491, (float)0.98442656, +(float)0.98555607, (float)0.98664331, (float)0.98768836, (float)0.98869103, (float)0.98965138, +(float)0.99056935, (float)0.99144489, (float)0.99227792, (float)0.99306846, (float)0.99381649, +(float)0.99452192, (float)0.99518472, (float)0.99580491, (float)0.99638247, (float)0.99691731, +(float)0.99740952, (float)0.99785894, (float)0.99826562, (float)0.99862951, (float)0.99895066, +(float)0.99922901, (float)0.99946457, (float)0.99965733, (float)0.99980724, (float)0.99991435, +(float)0.99997860, (float)1.00000000, (float)0.99997860, (float)0.99991435, (float)0.99980724, +(float)0.99965733, (float)0.99946457, (float)0.99922901, (float)0.99895066, (float)0.99862951, +(float)0.99826562, (float)0.99785894, (float)0.99740946, (float)0.99691731, (float)0.99638247, +(float)0.99580491, (float)0.99518472, (float)0.99452192, (float)0.99381644, (float)0.99306846, +(float)0.99227792, (float)0.99144489, (float)0.99056935, (float)0.98965138, (float)0.98869103, +(float)0.98768836, (float)0.98664331, (float)0.98555607, (float)0.98442656, (float)0.98325491, +(float)0.98204112, (float)0.98078525, (float)0.97948742, (float)0.97814757, (float)0.97676587, +(float)0.97534227, (float)0.97387695, (float)0.97236991, (float)0.97082120, (float)0.96923089, +(float)0.96759909, (float)0.96592581, (float)0.96421117, (float)0.96245521, (float)0.96065807, +(float)0.95881969, (float)0.95694029, (float)0.95501995, (float)0.95305860, (float)0.95105648, +(float)0.94901365, (float)0.94693011, (float)0.94480604, (float)0.94264150, (float)0.94043654, +(float)0.93819129, (float)0.93590593, (float)0.93358046, (float)0.93121493, (float)0.92880952, +(float)0.92636436, (float)0.92387950, (float)0.92135507, (float)0.91879123, (float)0.91618794, +(float)0.91354543, (float)0.91086382, (float)0.90814310, (float)0.90538365, (float)0.90258527, +(float)0.89974827, (float)0.89687276, (float)0.89395875, (float)0.89100647, (float)0.88801610, +(float)0.88498759, (float)0.88192123, (float)0.87881714, (float)0.87567532, (float)0.87249595, +(float)0.86927933, (float)0.86602539, (float)0.86273432, (float)0.85940641, (float)0.85604161, +(float)0.85264009, (float)0.84920216, (float)0.84572780, (float)0.84221715, (float)0.83867055, +(float)0.83508795, (float)0.83146954, (float)0.82781565, (float)0.82412612, (float)0.82040137, +(float)0.81664157, (float)0.81284660, (float)0.80901700, (float)0.80515265, (float)0.80125374, +(float)0.79732066, (float)0.79335332, (float)0.78935200, (float)0.78531694, (float)0.78124815, +(float)0.77714586, (float)0.77301049, (float)0.76884180, (float)0.76464021, (float)0.76040596, +(float)0.75613904, (float)0.75183970, (float)0.74750835, (float)0.74314481, (float)0.73874938, +(float)0.73432249, (float)0.72986400, (float)0.72537428, (float)0.72085363, (float)0.71630186, +(float)0.71171951, (float)0.70710677, (float)0.70246363, (float)0.69779032, (float)0.69308734, +(float)0.68835449, (float)0.68359220, (float)0.67880070, (float)0.67398006, (float)0.66913044, +(float)0.66425240, (float)0.65934575, (float)0.65441096, (float)0.64944804, (float)0.64445722, +(float)0.63943905, (float)0.63439327, (float)0.62932026, (float)0.62422055, (float)0.61909389, +(float)0.61394072, (float)0.60876143, (float)0.60355592, (float)0.59832448, (float)0.59306765, +(float)0.58778518, (float)0.58247757, (float)0.57714522, (float)0.57178789, (float)0.56640613, +(float)0.56100023, (float)0.55557019, (float)0.55011630, (float)0.54463905, (float)0.53913826, +(float)0.53361434, (float)0.52806783, (float)0.52249849, (float)0.51690674, (float)0.51129305, +(float)0.50565726, (float)0.50000006, (float)0.49432117, (float)0.48862115, (float)0.48290038, +(float)0.47715873, (float)0.47139663, (float)0.46561456, (float)0.45981231, (float)0.45399037, +(float)0.44814920, (float)0.44228864, (float)0.43640912, (float)0.43051112, (float)0.42459446, +(float)0.41865960, (float)0.41270703, (float)0.40673658, (float)0.40074870, (float)0.39474386, +(float)0.38872188, (float)0.38268328, (float)0.37662849, (float)0.37055734, (float)0.36447033, +(float)0.35836792, (float)0.35224995, (float)0.34611690, (float)0.33996922, (float)0.33380675, +(float)0.32763001, (float)0.32143945, (float)0.31523487, (float)0.30901679, (float)0.30278572, +(float)0.29654145, (float)0.29028472, (float)0.28401530, (float)0.27773371, (float)0.27144048, +(float)0.26513538, (float)0.25881892, (float)0.25249159, (float)0.24615324, (float)0.23980433, +(float)0.23344538, (float)0.22707619, (float)0.22069728, (float)0.21430916, (float)0.20791161, +(float)0.20150517, (float)0.19509031, (float)0.18866688, (float)0.18223536, (float)0.17579627, +(float)0.16934940, (float)0.16289529, (float)0.15643445, (float)0.14996666, (float)0.14349243, +(float)0.13701232, (float)0.13052608, (float)0.12403426, (float)0.11753736, (float)0.11103519, +(float)0.10452849, (float)0.09801710, (float)0.09150149, (float)0.08498220, (float)0.07845904, +(float)0.07193252, (float)0.06540315, (float)0.05887074, (float)0.05233581, (float)0.04579888, +(float)0.03925974, (float)0.03271893, (float)0.02617695, (float)0.01963361, (float)0.01308943, +(float)0.00654493, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000 +}; + + +// Hanning window: for 30ms with 1024 fft with symmetric zeros at 16kHz +static const float kBlocks480w1024[1024] = { +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00327249, (float)0.00654494, +(float)0.00981732, (float)0.01308960, (float)0.01636173, (float)0.01963369, (float)0.02290544, +(float)0.02617695, (float)0.02944817, (float)0.03271908, (float)0.03598964, (float)0.03925982, +(float)0.04252957, (float)0.04579887, (float)0.04906768, (float)0.05233596, (float)0.05560368, +(float)0.05887080, (float)0.06213730, (float)0.06540313, (float)0.06866825, (float)0.07193266, +(float)0.07519628, (float)0.07845910, (float)0.08172107, (float)0.08498218, (float)0.08824237, +(float)0.09150162, (float)0.09475989, (float)0.09801714, (float)0.10127335, (float)0.10452846, +(float)0.10778246, (float)0.11103531, (float)0.11428697, (float)0.11753740, (float)0.12078657, +(float)0.12403446, (float)0.12728101, (float)0.13052620, (float)0.13376999, (float)0.13701233, +(float)0.14025325, (float)0.14349262, (float)0.14673047, (float)0.14996676, (float)0.15320145, +(float)0.15643448, (float)0.15966582, (float)0.16289547, (float)0.16612339, (float)0.16934951, +(float)0.17257382, (float)0.17579629, (float)0.17901687, (float)0.18223552, (float)0.18545224, +(float)0.18866697, (float)0.19187967, (float)0.19509032, (float)0.19829889, (float)0.20150533, +(float)0.20470962, (float)0.20791170, (float)0.21111156, (float)0.21430916, (float)0.21750447, +(float)0.22069745, (float)0.22388805, (float)0.22707628, (float)0.23026206, (float)0.23344538, +(float)0.23662618, (float)0.23980446, (float)0.24298020, (float)0.24615330, (float)0.24932377, +(float)0.25249159, (float)0.25565669, (float)0.25881904, (float)0.26197866, (float)0.26513544, +(float)0.26828939, (float)0.27144045, (float)0.27458861, (float)0.27773386, (float)0.28087610, +(float)0.28401536, (float)0.28715158, (float)0.29028466, (float)0.29341471, (float)0.29654160, +(float)0.29966527, (float)0.30278578, (float)0.30590302, (float)0.30901700, (float)0.31212768, +(float)0.31523499, (float)0.31833893, (float)0.32143945, (float)0.32453656, (float)0.32763019, +(float)0.33072028, (float)0.33380687, (float)0.33688986, (float)0.33996925, (float)0.34304500, +(float)0.34611708, (float)0.34918544, (float)0.35225007, (float)0.35531089, (float)0.35836795, +(float)0.36142117, (float)0.36447051, (float)0.36751595, (float)0.37055743, (float)0.37359497, +(float)0.37662852, (float)0.37965801, (float)0.38268346, (float)0.38570479, (float)0.38872197, +(float)0.39173502, (float)0.39474389, (float)0.39774847, (float)0.40074885, (float)0.40374491, +(float)0.40673664, (float)0.40972406, (float)0.41270703, (float)0.41568562, (float)0.41865975, +(float)0.42162940, (float)0.42459452, (float)0.42755508, (float)0.43051112, (float)0.43346250, +(float)0.43640924, (float)0.43935132, (float)0.44228873, (float)0.44522133, (float)0.44814920, +(float)0.45107228, (float)0.45399052, (float)0.45690390, (float)0.45981237, (float)0.46271592, +(float)0.46561453, (float)0.46850815, (float)0.47139674, (float)0.47428030, (float)0.47715878, +(float)0.48003215, (float)0.48290035, (float)0.48576337, (float)0.48862126, (float)0.49147385, +(float)0.49432120, (float)0.49716330, (float)0.50000000, (float)0.50283140, (float)0.50565743, +(float)0.50847799, (float)0.51129311, (float)0.51410276, (float)0.51690692, (float)0.51970553, +(float)0.52249855, (float)0.52528602, (float)0.52806789, (float)0.53084403, (float)0.53361452, +(float)0.53637928, (float)0.53913832, (float)0.54189163, (float)0.54463905, (float)0.54738063, +(float)0.55011642, (float)0.55284631, (float)0.55557024, (float)0.55828828, (float)0.56100029, +(float)0.56370628, (float)0.56640625, (float)0.56910014, (float)0.57178795, (float)0.57446963, +(float)0.57714522, (float)0.57981455, (float)0.58247769, (float)0.58513463, (float)0.58778524, +(float)0.59042960, (float)0.59306765, (float)0.59569931, (float)0.59832460, (float)0.60094351, +(float)0.60355598, (float)0.60616195, (float)0.60876143, (float)0.61135441, (float)0.61394083, +(float)0.61652070, (float)0.61909395, (float)0.62166059, (float)0.62422055, (float)0.62677383, +(float)0.62932038, (float)0.63186020, (float)0.63439333, (float)0.63691956, (float)0.63943899, +(float)0.64195162, (float)0.64445734, (float)0.64695615, (float)0.64944810, (float)0.65193301, +(float)0.65441096, (float)0.65688187, (float)0.65934587, (float)0.66180271, (float)0.66425246, +(float)0.66669512, (float)0.66913062, (float)0.67155898, (float)0.67398012, (float)0.67639405, +(float)0.67880076, (float)0.68120021, (float)0.68359232, (float)0.68597710, (float)0.68835455, +(float)0.69072467, (float)0.69308740, (float)0.69544262, (float)0.69779050, (float)0.70013082, +(float)0.70246369, (float)0.70478904, (float)0.70710677, (float)0.70941699, (float)0.71171963, +(float)0.71401459, (float)0.71630198, (float)0.71858168, (float)0.72085363, (float)0.72311789, +(float)0.72537440, (float)0.72762316, (float)0.72986406, (float)0.73209721, (float)0.73432255, +(float)0.73653996, (float)0.73874950, (float)0.74095118, (float)0.74314487, (float)0.74533057, +(float)0.74750835, (float)0.74967808, (float)0.75183982, (float)0.75399351, (float)0.75613910, +(float)0.75827658, (float)0.76040596, (float)0.76252723, (float)0.76464027, (float)0.76674515, +(float)0.76884186, (float)0.77093029, (float)0.77301043, (float)0.77508241, (float)0.77714598, +(float)0.77920127, (float)0.78124821, (float)0.78328675, (float)0.78531694, (float)0.78733873, +(float)0.78935206, (float)0.79135692, (float)0.79335338, (float)0.79534125, (float)0.79732066, +(float)0.79929149, (float)0.80125386, (float)0.80320752, (float)0.80515265, (float)0.80708915, +(float)0.80901700, (float)0.81093621, (float)0.81284672, (float)0.81474853, (float)0.81664157, +(float)0.81852591, (float)0.82040149, (float)0.82226825, (float)0.82412618, (float)0.82597536, +(float)0.82781565, (float)0.82964706, (float)0.83146966, (float)0.83328325, (float)0.83508795, +(float)0.83688378, (float)0.83867061, (float)0.84044838, (float)0.84221727, (float)0.84397703, +(float)0.84572780, (float)0.84746957, (float)0.84920216, (float)0.85092574, (float)0.85264021, +(float)0.85434544, (float)0.85604161, (float)0.85772866, (float)0.85940641, (float)0.86107504, +(float)0.86273444, (float)0.86438453, (float)0.86602545, (float)0.86765707, (float)0.86927933, +(float)0.87089235, (float)0.87249607, (float)0.87409031, (float)0.87567532, (float)0.87725097, +(float)0.87881714, (float)0.88037390, (float)0.88192129, (float)0.88345921, (float)0.88498765, +(float)0.88650668, (float)0.88801610, (float)0.88951612, (float)0.89100653, (float)0.89248741, +(float)0.89395881, (float)0.89542055, (float)0.89687276, (float)0.89831537, (float)0.89974827, +(float)0.90117162, (float)0.90258533, (float)0.90398932, (float)0.90538365, (float)0.90676826, +(float)0.90814316, (float)0.90950841, (float)0.91086388, (float)0.91220951, (float)0.91354549, +(float)0.91487163, (float)0.91618794, (float)0.91749454, (float)0.91879123, (float)0.92007810, +(float)0.92135513, (float)0.92262226, (float)0.92387950, (float)0.92512691, (float)0.92636442, +(float)0.92759192, (float)0.92880958, (float)0.93001723, (float)0.93121493, (float)0.93240267, +(float)0.93358046, (float)0.93474817, (float)0.93590593, (float)0.93705362, (float)0.93819135, +(float)0.93931901, (float)0.94043654, (float)0.94154406, (float)0.94264150, (float)0.94372880, +(float)0.94480604, (float)0.94587320, (float)0.94693011, (float)0.94797695, (float)0.94901365, +(float)0.95004016, (float)0.95105654, (float)0.95206273, (float)0.95305866, (float)0.95404440, +(float)0.95501995, (float)0.95598525, (float)0.95694035, (float)0.95788521, (float)0.95881975, +(float)0.95974404, (float)0.96065807, (float)0.96156180, (float)0.96245527, (float)0.96333838, +(float)0.96421117, (float)0.96507370, (float)0.96592581, (float)0.96676767, (float)0.96759909, +(float)0.96842021, (float)0.96923089, (float)0.97003126, (float)0.97082120, (float)0.97160077, +(float)0.97236991, (float)0.97312868, (float)0.97387701, (float)0.97461486, (float)0.97534233, +(float)0.97605932, (float)0.97676587, (float)0.97746199, (float)0.97814763, (float)0.97882277, +(float)0.97948742, (float)0.98014158, (float)0.98078531, (float)0.98141843, (float)0.98204112, +(float)0.98265332, (float)0.98325491, (float)0.98384601, (float)0.98442656, (float)0.98499662, +(float)0.98555607, (float)0.98610497, (float)0.98664331, (float)0.98717111, (float)0.98768836, +(float)0.98819500, (float)0.98869103, (float)0.98917651, (float)0.98965138, (float)0.99011570, +(float)0.99056935, (float)0.99101239, (float)0.99144489, (float)0.99186671, (float)0.99227792, +(float)0.99267852, (float)0.99306846, (float)0.99344778, (float)0.99381649, (float)0.99417448, +(float)0.99452192, (float)0.99485862, (float)0.99518472, (float)0.99550015, (float)0.99580491, +(float)0.99609905, (float)0.99638247, (float)0.99665523, (float)0.99691731, (float)0.99716878, +(float)0.99740952, (float)0.99763954, (float)0.99785894, (float)0.99806762, (float)0.99826562, +(float)0.99845290, (float)0.99862951, (float)0.99879545, (float)0.99895066, (float)0.99909520, +(float)0.99922901, (float)0.99935216, (float)0.99946457, (float)0.99956632, (float)0.99965733, +(float)0.99973762, (float)0.99980724, (float)0.99986613, (float)0.99991435, (float)0.99995178, +(float)0.99997860, (float)0.99999464, (float)1.00000000, (float)0.99999464, (float)0.99997860, +(float)0.99995178, (float)0.99991435, (float)0.99986613, (float)0.99980724, (float)0.99973762, +(float)0.99965733, (float)0.99956632, (float)0.99946457, (float)0.99935216, (float)0.99922901, +(float)0.99909520, (float)0.99895066, (float)0.99879545, (float)0.99862951, (float)0.99845290, +(float)0.99826562, (float)0.99806762, (float)0.99785894, (float)0.99763954, (float)0.99740946, +(float)0.99716872, (float)0.99691731, (float)0.99665523, (float)0.99638247, (float)0.99609905, +(float)0.99580491, (float)0.99550015, (float)0.99518472, (float)0.99485862, (float)0.99452192, +(float)0.99417448, (float)0.99381644, (float)0.99344778, (float)0.99306846, (float)0.99267852, +(float)0.99227792, (float)0.99186671, (float)0.99144489, (float)0.99101239, (float)0.99056935, +(float)0.99011564, (float)0.98965138, (float)0.98917651, (float)0.98869103, (float)0.98819494, +(float)0.98768836, (float)0.98717111, (float)0.98664331, (float)0.98610497, (float)0.98555607, +(float)0.98499656, (float)0.98442656, (float)0.98384601, (float)0.98325491, (float)0.98265326, +(float)0.98204112, (float)0.98141843, (float)0.98078525, (float)0.98014158, (float)0.97948742, +(float)0.97882277, (float)0.97814757, (float)0.97746193, (float)0.97676587, (float)0.97605932, +(float)0.97534227, (float)0.97461486, (float)0.97387695, (float)0.97312862, (float)0.97236991, +(float)0.97160077, (float)0.97082120, (float)0.97003126, (float)0.96923089, (float)0.96842015, +(float)0.96759909, (float)0.96676761, (float)0.96592581, (float)0.96507365, (float)0.96421117, +(float)0.96333838, (float)0.96245521, (float)0.96156180, (float)0.96065807, (float)0.95974404, +(float)0.95881969, (float)0.95788515, (float)0.95694029, (float)0.95598525, (float)0.95501995, +(float)0.95404440, (float)0.95305860, (float)0.95206267, (float)0.95105648, (float)0.95004016, +(float)0.94901365, (float)0.94797695, (float)0.94693011, (float)0.94587314, (float)0.94480604, +(float)0.94372880, (float)0.94264150, (float)0.94154406, (float)0.94043654, (float)0.93931895, +(float)0.93819129, (float)0.93705362, (float)0.93590593, (float)0.93474817, (float)0.93358046, +(float)0.93240267, (float)0.93121493, (float)0.93001723, (float)0.92880952, (float)0.92759192, +(float)0.92636436, (float)0.92512691, (float)0.92387950, (float)0.92262226, (float)0.92135507, +(float)0.92007804, (float)0.91879123, (float)0.91749448, (float)0.91618794, (float)0.91487157, +(float)0.91354543, (float)0.91220951, (float)0.91086382, (float)0.90950835, (float)0.90814310, +(float)0.90676820, (float)0.90538365, (float)0.90398932, (float)0.90258527, (float)0.90117157, +(float)0.89974827, (float)0.89831525, (float)0.89687276, (float)0.89542055, (float)0.89395875, +(float)0.89248741, (float)0.89100647, (float)0.88951600, (float)0.88801610, (float)0.88650662, +(float)0.88498759, (float)0.88345915, (float)0.88192123, (float)0.88037384, (float)0.87881714, +(float)0.87725091, (float)0.87567532, (float)0.87409031, (float)0.87249595, (float)0.87089223, +(float)0.86927933, (float)0.86765701, (float)0.86602539, (float)0.86438447, (float)0.86273432, +(float)0.86107504, (float)0.85940641, (float)0.85772860, (float)0.85604161, (float)0.85434544, +(float)0.85264009, (float)0.85092574, (float)0.84920216, (float)0.84746951, (float)0.84572780, +(float)0.84397697, (float)0.84221715, (float)0.84044844, (float)0.83867055, (float)0.83688372, +(float)0.83508795, (float)0.83328319, (float)0.83146954, (float)0.82964706, (float)0.82781565, +(float)0.82597530, (float)0.82412612, (float)0.82226813, (float)0.82040137, (float)0.81852591, +(float)0.81664157, (float)0.81474847, (float)0.81284660, (float)0.81093609, (float)0.80901700, +(float)0.80708915, (float)0.80515265, (float)0.80320752, (float)0.80125374, (float)0.79929143, +(float)0.79732066, (float)0.79534125, (float)0.79335332, (float)0.79135686, (float)0.78935200, +(float)0.78733861, (float)0.78531694, (float)0.78328675, (float)0.78124815, (float)0.77920121, +(float)0.77714586, (float)0.77508223, (float)0.77301049, (float)0.77093029, (float)0.76884180, +(float)0.76674509, (float)0.76464021, (float)0.76252711, (float)0.76040596, (float)0.75827658, +(float)0.75613904, (float)0.75399339, (float)0.75183970, (float)0.74967796, (float)0.74750835, +(float)0.74533057, (float)0.74314481, (float)0.74095106, (float)0.73874938, (float)0.73653996, +(float)0.73432249, (float)0.73209721, (float)0.72986400, (float)0.72762305, (float)0.72537428, +(float)0.72311789, (float)0.72085363, (float)0.71858162, (float)0.71630186, (float)0.71401453, +(float)0.71171951, (float)0.70941705, (float)0.70710677, (float)0.70478898, (float)0.70246363, +(float)0.70013070, (float)0.69779032, (float)0.69544268, (float)0.69308734, (float)0.69072461, +(float)0.68835449, (float)0.68597704, (float)0.68359220, (float)0.68120021, (float)0.67880070, +(float)0.67639399, (float)0.67398006, (float)0.67155886, (float)0.66913044, (float)0.66669512, +(float)0.66425240, (float)0.66180259, (float)0.65934575, (float)0.65688181, (float)0.65441096, +(float)0.65193301, (float)0.64944804, (float)0.64695609, (float)0.64445722, (float)0.64195150, +(float)0.63943905, (float)0.63691956, (float)0.63439327, (float)0.63186014, (float)0.62932026, +(float)0.62677372, (float)0.62422055, (float)0.62166059, (float)0.61909389, (float)0.61652064, +(float)0.61394072, (float)0.61135429, (float)0.60876143, (float)0.60616189, (float)0.60355592, +(float)0.60094339, (float)0.59832448, (float)0.59569913, (float)0.59306765, (float)0.59042960, +(float)0.58778518, (float)0.58513451, (float)0.58247757, (float)0.57981461, (float)0.57714522, +(float)0.57446963, (float)0.57178789, (float)0.56910002, (float)0.56640613, (float)0.56370628, +(float)0.56100023, (float)0.55828822, (float)0.55557019, (float)0.55284619, (float)0.55011630, +(float)0.54738069, (float)0.54463905, (float)0.54189152, (float)0.53913826, (float)0.53637916, +(float)0.53361434, (float)0.53084403, (float)0.52806783, (float)0.52528596, (float)0.52249849, +(float)0.51970541, (float)0.51690674, (float)0.51410276, (float)0.51129305, (float)0.50847787, +(float)0.50565726, (float)0.50283122, (float)0.50000006, (float)0.49716327, (float)0.49432117, +(float)0.49147379, (float)0.48862115, (float)0.48576325, (float)0.48290038, (float)0.48003212, +(float)0.47715873, (float)0.47428021, (float)0.47139663, (float)0.46850798, (float)0.46561456, +(float)0.46271589, (float)0.45981231, (float)0.45690379, (float)0.45399037, (float)0.45107210, +(float)0.44814920, (float)0.44522130, (float)0.44228864, (float)0.43935123, (float)0.43640912, +(float)0.43346232, (float)0.43051112, (float)0.42755505, (float)0.42459446, (float)0.42162928, +(float)0.41865960, (float)0.41568545, (float)0.41270703, (float)0.40972400, (float)0.40673658, +(float)0.40374479, (float)0.40074870, (float)0.39774850, (float)0.39474386, (float)0.39173496, +(float)0.38872188, (float)0.38570464, (float)0.38268328, (float)0.37965804, (float)0.37662849, +(float)0.37359491, (float)0.37055734, (float)0.36751580, (float)0.36447033, (float)0.36142117, +(float)0.35836792, (float)0.35531086, (float)0.35224995, (float)0.34918529, (float)0.34611690, +(float)0.34304500, (float)0.33996922, (float)0.33688980, (float)0.33380675, (float)0.33072016, +(float)0.32763001, (float)0.32453656, (float)0.32143945, (float)0.31833887, (float)0.31523487, +(float)0.31212750, (float)0.30901679, (float)0.30590302, (float)0.30278572, (float)0.29966521, +(float)0.29654145, (float)0.29341453, (float)0.29028472, (float)0.28715155, (float)0.28401530, +(float)0.28087601, (float)0.27773371, (float)0.27458847, (float)0.27144048, (float)0.26828936, +(float)0.26513538, (float)0.26197854, (float)0.25881892, (float)0.25565651, (float)0.25249159, +(float)0.24932374, (float)0.24615324, (float)0.24298008, (float)0.23980433, (float)0.23662600, +(float)0.23344538, (float)0.23026201, (float)0.22707619, (float)0.22388794, (float)0.22069728, +(float)0.21750426, (float)0.21430916, (float)0.21111152, (float)0.20791161, (float)0.20470949, +(float)0.20150517, (float)0.19829892, (float)0.19509031, (float)0.19187963, (float)0.18866688, +(float)0.18545210, (float)0.18223536, (float)0.17901689, (float)0.17579627, (float)0.17257376, +(float)0.16934940, (float)0.16612324, (float)0.16289529, (float)0.15966584, (float)0.15643445, +(float)0.15320137, (float)0.14996666, (float)0.14673033, (float)0.14349243, (float)0.14025325, +(float)0.13701232, (float)0.13376991, (float)0.13052608, (float)0.12728085, (float)0.12403426, +(float)0.12078657, (float)0.11753736, (float)0.11428688, (float)0.11103519, (float)0.10778230, +(float)0.10452849, (float)0.10127334, (float)0.09801710, (float)0.09475980, (float)0.09150149, +(float)0.08824220, (float)0.08498220, (float)0.08172106, (float)0.07845904, (float)0.07519618, +(float)0.07193252, (float)0.06866808, (float)0.06540315, (float)0.06213728, (float)0.05887074, +(float)0.05560357, (float)0.05233581, (float)0.04906749, (float)0.04579888, (float)0.04252954, +(float)0.03925974, (float)0.03598953, (float)0.03271893, (float)0.02944798, (float)0.02617695, +(float)0.02290541, (float)0.01963361, (float)0.01636161, (float)0.01308943, (float)0.00981712, +(float)0.00654493, (float)0.00327244, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000, +(float)0.00000000, (float)0.00000000, (float)0.00000000, (float)0.00000000}; + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_NS_MAIN_SOURCE_WINDOWS_PRIVATE_H_ diff --git a/src/libs/webrtc/signal_processing_library/add_sat_w16.c b/src/libs/webrtc/signal_processing_library/add_sat_w16.c new file mode 100644 index 00000000..d103999b --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/add_sat_w16.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_AddSatW16(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS + +WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 var1, WebRtc_Word16 var2) +{ + WebRtc_Word32 s_sum = (WebRtc_Word32)var1 + (WebRtc_Word32)var2; + + if (s_sum > WEBRTC_SPL_WORD16_MAX) + s_sum = WEBRTC_SPL_WORD16_MAX; + else if (s_sum < WEBRTC_SPL_WORD16_MIN) + s_sum = WEBRTC_SPL_WORD16_MIN; + + return (WebRtc_Word16)s_sum; +} + +#endif diff --git a/src/libs/webrtc/signal_processing_library/add_sat_w32.c b/src/libs/webrtc/signal_processing_library/add_sat_w32.c new file mode 100644 index 00000000..6d83e75b --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/add_sat_w32.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_AddSatW32(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS + +WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 var1, WebRtc_Word32 var2) +{ + WebRtc_Word32 l_sum; + + // perform long addition + l_sum = var1 + var2; + + // check for under or overflow + if (WEBRTC_SPL_IS_NEG(var1)) + { + if (WEBRTC_SPL_IS_NEG(var2) && !WEBRTC_SPL_IS_NEG(l_sum)) + { + l_sum = (WebRtc_Word32)0x80000000; + } + } else + { + if (!WEBRTC_SPL_IS_NEG(var2) && WEBRTC_SPL_IS_NEG(l_sum)) + { + l_sum = (WebRtc_Word32)0x7FFFFFFF; + } + } + + return l_sum; +} + +#endif diff --git a/src/libs/webrtc/signal_processing_library/auto_corr_to_refl_coef.c b/src/libs/webrtc/signal_processing_library/auto_corr_to_refl_coef.c new file mode 100644 index 00000000..b7e88589 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/auto_corr_to_refl_coef.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_AutoCorrToReflCoef(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRtc_Word16 *K) +{ + int i, n; + WebRtc_Word16 tmp; + G_CONST WebRtc_Word32 *rptr; + WebRtc_Word32 L_num, L_den; + WebRtc_Word16 *acfptr, *pptr, *wptr, *p1ptr, *w1ptr, ACF[WEBRTC_SPL_MAX_LPC_ORDER], + P[WEBRTC_SPL_MAX_LPC_ORDER], W[WEBRTC_SPL_MAX_LPC_ORDER]; + + // Initialize loop and pointers. + acfptr = ACF; + rptr = R; + pptr = P; + p1ptr = &P[1]; + w1ptr = &W[1]; + wptr = w1ptr; + + // First loop; n=0. Determine shifting. + tmp = WebRtcSpl_NormW32(*R); + *acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16); + *pptr++ = *acfptr++; + + // Initialize ACF, P and W. + for (i = 1; i <= use_order; i++) + { + *acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16); + *wptr++ = *acfptr; + *pptr++ = *acfptr++; + } + + // Compute reflection coefficients. + for (n = 1; n <= use_order; n++, K++) + { + tmp = WEBRTC_SPL_ABS_W16(*p1ptr); + if (*P < tmp) + { + for (i = n; i <= use_order; i++) + *K++ = 0; + + return; + } + + // Division: WebRtcSpl_div(tmp, *P) + *K = 0; + if (tmp != 0) + { + L_num = tmp; + L_den = *P; + i = 15; + while (i--) + { + (*K) <<= 1; + L_num <<= 1; + if (L_num >= L_den) + { + L_num -= L_den; + (*K)++; + } + } + if (*p1ptr > 0) + *K = -*K; + } + + // Last iteration; don't do Schur recursion. + if (n == use_order) + return; + + // Schur recursion. + pptr = P; + wptr = w1ptr; + tmp = (WebRtc_Word16)(((WebRtc_Word32)*p1ptr * (WebRtc_Word32)*K + 16384) >> 15); + *pptr = WEBRTC_SPL_ADD_SAT_W16( *pptr, tmp ); + pptr++; + for (i = 1; i <= use_order - n; i++) + { + tmp = (WebRtc_Word16)(((WebRtc_Word32)*wptr * (WebRtc_Word32)*K + 16384) >> 15); + *pptr = WEBRTC_SPL_ADD_SAT_W16( *(pptr+1), tmp ); + pptr++; + tmp = (WebRtc_Word16)(((WebRtc_Word32)*pptr * (WebRtc_Word32)*K + 16384) >> 15); + *wptr = WEBRTC_SPL_ADD_SAT_W16( *wptr, tmp ); + wptr++; + } + } +} diff --git a/src/libs/webrtc/signal_processing_library/auto_correlation.c b/src/libs/webrtc/signal_processing_library/auto_correlation.c new file mode 100644 index 00000000..a00fde4b --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/auto_correlation.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_AutoCorrelation(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +int WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* in_vector, + int in_vector_length, + int order, + WebRtc_Word32* result, + int* scale) +{ + WebRtc_Word32 sum; + int i, j; + WebRtc_Word16 smax; // Sample max + G_CONST WebRtc_Word16* xptr1; + G_CONST WebRtc_Word16* xptr2; + WebRtc_Word32* resultptr; + int scaling = 0; + +#ifdef _ARM_OPT_ +#pragma message("NOTE: _ARM_OPT_ optimizations are used") + WebRtc_Word16 loops4; +#endif + + if (order < 0) + order = in_vector_length; + + // Find the max. sample + smax = WebRtcSpl_MaxAbsValueW16(in_vector, in_vector_length); + + // In order to avoid overflow when computing the sum we should scale the samples so that + // (in_vector_length * smax * smax) will not overflow. + + if (smax == 0) + { + scaling = 0; + } else + { + int nbits = WebRtcSpl_GetSizeInBits(in_vector_length); // # of bits in the sum loop + int t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); // # of bits to normalize smax + + if (t > nbits) + { + scaling = 0; + } else + { + scaling = nbits - t; + } + + } + + resultptr = result; + + // Perform the actual correlation calculation + for (i = 0; i < order + 1; i++) + { + int loops = (in_vector_length - i); + sum = 0; + xptr1 = in_vector; + xptr2 = &in_vector[i]; +#ifndef _ARM_OPT_ + for (j = loops; j > 0; j--) + { + sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1++, *xptr2++, scaling); + } +#else + loops4 = (loops >> 2) << 2; + + if (scaling == 0) + { + for (j = 0; j < loops4; j = j + 4) + { + sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); + xptr1++; + xptr2++; + sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); + xptr1++; + xptr2++; + sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); + xptr1++; + xptr2++; + sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); + xptr1++; + xptr2++; + } + + for (j = loops4; j < loops; j++) + { + sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2); + xptr1++; + xptr2++; + } + } + else + { + for (j = 0; j < loops4; j = j + 4) + { + sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); + xptr1++; + xptr2++; + sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); + xptr1++; + xptr2++; + sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); + xptr1++; + xptr2++; + sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); + xptr1++; + xptr2++; + } + + for (j = loops4; j < loops; j++) + { + sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling); + xptr1++; + xptr2++; + } + } + +#endif + *resultptr++ = sum; + } + + *scale = scaling; + + return order + 1; +} diff --git a/src/libs/webrtc/signal_processing_library/complex_bit_reverse.c b/src/libs/webrtc/signal_processing_library/complex_bit_reverse.c new file mode 100644 index 00000000..85c76f82 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/complex_bit_reverse.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_ComplexBitReverse(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +void WebRtcSpl_ComplexBitReverse(WebRtc_Word16 frfi[], int stages) +{ + int mr, nn, n, l, m; + WebRtc_Word16 tr, ti; + + n = 1 << stages; + + mr = 0; + nn = n - 1; + + // decimation in time - re-order data + for (m = 1; m <= nn; ++m) + { + l = n; + do + { + l >>= 1; + } while (mr + l > nn); + mr = (mr & (l - 1)) + l; + + if (mr <= m) + continue; + + tr = frfi[2 * m]; + frfi[2 * m] = frfi[2 * mr]; + frfi[2 * mr] = tr; + + ti = frfi[2 * m + 1]; + frfi[2 * m + 1] = frfi[2 * mr + 1]; + frfi[2 * mr + 1] = ti; + } +} diff --git a/src/libs/webrtc/signal_processing_library/complex_fft.c b/src/libs/webrtc/signal_processing_library/complex_fft.c new file mode 100644 index 00000000..b6f0c4e1 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/complex_fft.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_ComplexFFT(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#define CFFTSFT 14 +#define CFFTRND 1 +#define CFFTRND2 16384 + +#if (defined ARM9E_GCC) || (defined ARM_WINM) || (defined ANDROID_AECOPT) +extern "C" int FFT_4OFQ14(void *src, void *dest, int NC, int shift); + +// For detailed description of the fft functions, check the readme files in fft_ARM9E folder. +int WebRtcSpl_ComplexFFT2(WebRtc_Word16 frfi[], WebRtc_Word16 frfiOut[], int stages, int mode) +{ + return FFT_4OFQ14(frfi, frfiOut, 1 << stages, 0); +} +#endif + +int WebRtcSpl_ComplexFFT(WebRtc_Word16 frfi[], int stages, int mode) +{ + int i, j, l, k, istep, n, m; + WebRtc_Word16 wr, wi; + WebRtc_Word32 tr32, ti32, qr32, qi32; + + /* The 1024-value is a constant given from the size of WebRtcSpl_kSinTable1024[], + * and should not be changed depending on the input parameter 'stages' + */ + n = 1 << stages; + if (n > 1024) + return -1; + + l = 1; + k = 10 - 1; /* Constant for given WebRtcSpl_kSinTable1024[]. Do not change + depending on the input parameter 'stages' */ + + if (mode == 0) + { + // mode==0: Low-complexity and Low-accuracy mode + while (l < n) + { + istep = l << 1; + + for (m = 0; m < l; ++m) + { + j = m << k; + + /* The 256-value is a constant given as 1/4 of the size of + * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input + * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 + */ + wr = WebRtcSpl_kSinTable1024[j + 256]; + wi = -WebRtcSpl_kSinTable1024[j]; + + for (i = m; i < n; i += istep) + { + j = i + l; + + tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j]) + - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1])), 15); + + ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1]) + + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j])), 15); + + qr32 = (WebRtc_Word32)frfi[2 * i]; + qi32 = (WebRtc_Word32)frfi[2 * i + 1]; + frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, 1); + frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, 1); + frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, 1); + frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, 1); + } + } + + --k; + l = istep; + + } + + } else + { + // mode==1: High-complexity and High-accuracy mode + while (l < n) + { + istep = l << 1; + + for (m = 0; m < l; ++m) + { + j = m << k; + + /* The 256-value is a constant given as 1/4 of the size of + * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input + * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 + */ + wr = WebRtcSpl_kSinTable1024[j + 256]; + wi = -WebRtcSpl_kSinTable1024[j]; + + for (i = m; i < n; i += istep) + { + j = i + l; + + tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j]) + - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CFFTRND), + 15 - CFFTSFT); + + ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1]) + + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CFFTRND), 15 - CFFTSFT); + + qr32 = ((WebRtc_Word32)frfi[2 * i]) << CFFTSFT; + qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CFFTSFT; + frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( + (qr32 - tr32 + CFFTRND2), 1 + CFFTSFT); + frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( + (qi32 - ti32 + CFFTRND2), 1 + CFFTSFT); + frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( + (qr32 + tr32 + CFFTRND2), 1 + CFFTSFT); + frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( + (qi32 + ti32 + CFFTRND2), 1 + CFFTSFT); + } + } + + --k; + l = istep; + } + } + return 0; +} diff --git a/src/libs/webrtc/signal_processing_library/complex_ifft.c b/src/libs/webrtc/signal_processing_library/complex_ifft.c new file mode 100644 index 00000000..184b8de5 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/complex_ifft.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_ComplexIFFT(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#define CIFFTSFT 14 +#define CIFFTRND 1 + +#if (defined ARM9E_GCC) || (defined ARM_WINM) || (defined ANDROID_AECOPT) +extern "C" int FFT_4OIQ14(void *src, void *dest, int NC, int shift); + +// For detailed description of the fft functions, check the readme files in fft_ARM9E folder. +int WebRtcSpl_ComplexIFFT2(WebRtc_Word16 frfi[], WebRtc_Word16 frfiOut[], int stages, int mode) +{ + FFT_4OIQ14(frfi, frfiOut, 1 << stages, 0); + return 0; +} +#endif + +int WebRtcSpl_ComplexIFFT(WebRtc_Word16 frfi[], int stages, int mode) +{ + int i, j, l, k, istep, n, m, scale, shift; + WebRtc_Word16 wr, wi; + WebRtc_Word32 tr32, ti32, qr32, qi32; + WebRtc_Word32 tmp32, round2; + + /* The 1024-value is a constant given from the size of WebRtcSpl_kSinTable1024[], + * and should not be changed depending on the input parameter 'stages' + */ + n = 1 << stages; + if (n > 1024) + return -1; + + scale = 0; + + l = 1; + k = 10 - 1; /* Constant for given WebRtcSpl_kSinTable1024[]. Do not change + depending on the input parameter 'stages' */ + + while (l < n) + { + // variable scaling, depending upon data + shift = 0; + round2 = 8192; + + tmp32 = (WebRtc_Word32)WebRtcSpl_MaxAbsValueW16(frfi, 2 * n); + if (tmp32 > 13573) + { + shift++; + scale++; + round2 <<= 1; + } + if (tmp32 > 27146) + { + shift++; + scale++; + round2 <<= 1; + } + + istep = l << 1; + + if (mode == 0) + { + // mode==0: Low-complexity and Low-accuracy mode + for (m = 0; m < l; ++m) + { + j = m << k; + + /* The 256-value is a constant given as 1/4 of the size of + * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input + * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 + */ + wr = WebRtcSpl_kSinTable1024[j + 256]; + wi = WebRtcSpl_kSinTable1024[j]; + + for (i = m; i < n; i += istep) + { + j = i + l; + + tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j], 0) + - WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j + 1], 0)), 15); + + ti32 = WEBRTC_SPL_RSHIFT_W32( + (WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j + 1], 0) + + WEBRTC_SPL_MUL_16_16_RSFT(wi,frfi[2*j],0)), 15); + + qr32 = (WebRtc_Word32)frfi[2 * i]; + qi32 = (WebRtc_Word32)frfi[2 * i + 1]; + frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, shift); + frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, shift); + frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, shift); + frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, shift); + } + } + } else + { + // mode==1: High-complexity and High-accuracy mode + + for (m = 0; m < l; ++m) + { + j = m << k; + + /* The 256-value is a constant given as 1/4 of the size of + * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input + * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2 + */ + wr = WebRtcSpl_kSinTable1024[j + 256]; + wi = WebRtcSpl_kSinTable1024[j]; + + for (i = m; i < n; i += istep) + { + j = i + l; + + tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j], 0) + - WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j + 1], 0) + CIFFTRND), + 15 - CIFFTSFT); + + ti32 = WEBRTC_SPL_RSHIFT_W32( + (WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j + 1], 0) + + WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j], 0) + + CIFFTRND), 15 - CIFFTSFT); + + qr32 = ((WebRtc_Word32)frfi[2 * i]) << CIFFTSFT; + qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CIFFTSFT; + frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 - tr32+round2), + shift+CIFFTSFT); + frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( + (qi32 - ti32 + round2), shift + CIFFTSFT); + frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 + tr32 + round2), + shift + CIFFTSFT); + frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( + (qi32 + ti32 + round2), shift + CIFFTSFT); + } + } + + } + --k; + l = istep; + } + return scale; +} diff --git a/src/libs/webrtc/signal_processing_library/copy_set_operations.c b/src/libs/webrtc/signal_processing_library/copy_set_operations.c new file mode 100644 index 00000000..82473377 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/copy_set_operations.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the implementation of functions + * WebRtcSpl_MemSetW16() + * WebRtcSpl_MemSetW32() + * WebRtcSpl_MemCpyReversedOrder() + * WebRtcSpl_CopyFromEndW16() + * WebRtcSpl_ZerosArrayW16() + * WebRtcSpl_ZerosArrayW32() + * WebRtcSpl_OnesArrayW16() + * WebRtcSpl_OnesArrayW32() + * + * The description header can be found in signal_processing_library.h + * + */ + +#include <string.h> +#include "signal_processing_library.h" + + +void WebRtcSpl_MemSetW16(WebRtc_Word16 *ptr, WebRtc_Word16 set_value, int length) +{ + int j; + WebRtc_Word16 *arrptr = ptr; + + for (j = length; j > 0; j--) + { + *arrptr++ = set_value; + } +} + +void WebRtcSpl_MemSetW32(WebRtc_Word32 *ptr, WebRtc_Word32 set_value, int length) +{ + int j; + WebRtc_Word32 *arrptr = ptr; + + for (j = length; j > 0; j--) + { + *arrptr++ = set_value; + } +} + +void WebRtcSpl_MemCpyReversedOrder(WebRtc_Word16* dest, WebRtc_Word16* source, int length) +{ + int j; + WebRtc_Word16* destPtr = dest; + WebRtc_Word16* sourcePtr = source; + + for (j = 0; j < length; j++) + { + *destPtr-- = *sourcePtr++; + } +} + +WebRtc_Word16 WebRtcSpl_CopyFromEndW16(G_CONST WebRtc_Word16 *vector_in, + WebRtc_Word16 length, + WebRtc_Word16 samples, + WebRtc_Word16 *vector_out) +{ + // Copy the last <samples> of the input vector to vector_out + WEBRTC_SPL_MEMCPY_W16(vector_out, &vector_in[length - samples], samples); + + return samples; +} + +WebRtc_Word16 WebRtcSpl_ZerosArrayW16(WebRtc_Word16 *vector, WebRtc_Word16 length) +{ + WebRtcSpl_MemSetW16(vector, 0, length); + return length; +} + +WebRtc_Word16 WebRtcSpl_ZerosArrayW32(WebRtc_Word32 *vector, WebRtc_Word16 length) +{ + WebRtcSpl_MemSetW32(vector, 0, length); + return length; +} + +WebRtc_Word16 WebRtcSpl_OnesArrayW16(WebRtc_Word16 *vector, WebRtc_Word16 length) +{ + WebRtc_Word16 i; + WebRtc_Word16 *tmpvec = vector; + for (i = 0; i < length; i++) + { + *tmpvec++ = 1; + } + return length; +} + +WebRtc_Word16 WebRtcSpl_OnesArrayW32(WebRtc_Word32 *vector, WebRtc_Word16 length) +{ + WebRtc_Word16 i; + WebRtc_Word32 *tmpvec = vector; + for (i = 0; i < length; i++) + { + *tmpvec++ = 1; + } + return length; +} diff --git a/src/libs/webrtc/signal_processing_library/cos_table.c b/src/libs/webrtc/signal_processing_library/cos_table.c new file mode 100644 index 00000000..7dba4b04 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/cos_table.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the 360 degree cos table. + * + */ + +#include "signal_processing_library.h" + +WebRtc_Word16 WebRtcSpl_kCosTable[] = { + 8192, 8190, 8187, 8180, 8172, 8160, 8147, 8130, 8112, + 8091, 8067, 8041, 8012, 7982, 7948, 7912, 7874, 7834, + 7791, 7745, 7697, 7647, 7595, 7540, 7483, 7424, 7362, + 7299, 7233, 7164, 7094, 7021, 6947, 6870, 6791, 6710, + 6627, 6542, 6455, 6366, 6275, 6182, 6087, 5991, 5892, + 5792, 5690, 5586, 5481, 5374, 5265, 5155, 5043, 4930, + 4815, 4698, 4580, 4461, 4341, 4219, 4096, 3971, 3845, + 3719, 3591, 3462, 3331, 3200, 3068, 2935, 2801, 2667, + 2531, 2395, 2258, 2120, 1981, 1842, 1703, 1563, 1422, + 1281, 1140, 998, 856, 713, 571, 428, 285, 142, + 0, -142, -285, -428, -571, -713, -856, -998, -1140, + -1281, -1422, -1563, -1703, -1842, -1981, -2120, -2258, -2395, + -2531, -2667, -2801, -2935, -3068, -3200, -3331, -3462, -3591, + -3719, -3845, -3971, -4095, -4219, -4341, -4461, -4580, -4698, + -4815, -4930, -5043, -5155, -5265, -5374, -5481, -5586, -5690, + -5792, -5892, -5991, -6087, -6182, -6275, -6366, -6455, -6542, + -6627, -6710, -6791, -6870, -6947, -7021, -7094, -7164, -7233, + -7299, -7362, -7424, -7483, -7540, -7595, -7647, -7697, -7745, + -7791, -7834, -7874, -7912, -7948, -7982, -8012, -8041, -8067, + -8091, -8112, -8130, -8147, -8160, -8172, -8180, -8187, -8190, + -8191, -8190, -8187, -8180, -8172, -8160, -8147, -8130, -8112, + -8091, -8067, -8041, -8012, -7982, -7948, -7912, -7874, -7834, + -7791, -7745, -7697, -7647, -7595, -7540, -7483, -7424, -7362, + -7299, -7233, -7164, -7094, -7021, -6947, -6870, -6791, -6710, + -6627, -6542, -6455, -6366, -6275, -6182, -6087, -5991, -5892, + -5792, -5690, -5586, -5481, -5374, -5265, -5155, -5043, -4930, + -4815, -4698, -4580, -4461, -4341, -4219, -4096, -3971, -3845, + -3719, -3591, -3462, -3331, -3200, -3068, -2935, -2801, -2667, + -2531, -2395, -2258, -2120, -1981, -1842, -1703, -1563, -1422, + -1281, -1140, -998, -856, -713, -571, -428, -285, -142, + 0, 142, 285, 428, 571, 713, 856, 998, 1140, + 1281, 1422, 1563, 1703, 1842, 1981, 2120, 2258, 2395, + 2531, 2667, 2801, 2935, 3068, 3200, 3331, 3462, 3591, + 3719, 3845, 3971, 4095, 4219, 4341, 4461, 4580, 4698, + 4815, 4930, 5043, 5155, 5265, 5374, 5481, 5586, 5690, + 5792, 5892, 5991, 6087, 6182, 6275, 6366, 6455, 6542, + 6627, 6710, 6791, 6870, 6947, 7021, 7094, 7164, 7233, + 7299, 7362, 7424, 7483, 7540, 7595, 7647, 7697, 7745, + 7791, 7834, 7874, 7912, 7948, 7982, 8012, 8041, 8067, + 8091, 8112, 8130, 8147, 8160, 8172, 8180, 8187, 8190 +}; diff --git a/src/libs/webrtc/signal_processing_library/cross_correlation.c b/src/libs/webrtc/signal_processing_library/cross_correlation.c new file mode 100644 index 00000000..1133d093 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/cross_correlation.c @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_CrossCorrelation(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +void WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_correlation, WebRtc_Word16* seq1, + WebRtc_Word16* seq2, WebRtc_Word16 dim_seq, + WebRtc_Word16 dim_cross_correlation, + WebRtc_Word16 right_shifts, + WebRtc_Word16 step_seq2) +{ + int i, j; + WebRtc_Word16* seq1Ptr; + WebRtc_Word16* seq2Ptr; + WebRtc_Word32* CrossCorrPtr; + +#ifdef _XSCALE_OPT_ + +#ifdef _WIN32 +#pragma message("NOTE: _XSCALE_OPT_ optimizations are used (overrides _ARM_OPT_ and requires /QRxscale compiler flag)") +#endif + + __int64 macc40; + + int iseq1[250]; + int iseq2[250]; + int iseq3[250]; + int * iseq1Ptr; + int * iseq2Ptr; + int * iseq3Ptr; + int len, i_len; + + seq1Ptr = seq1; + iseq1Ptr = iseq1; + for(i = 0; i < ((dim_seq + 1) >> 1); i++) + { + *iseq1Ptr = (unsigned short)*seq1Ptr++; + *iseq1Ptr++ |= (WebRtc_Word32)*seq1Ptr++ << 16; + + } + + if(dim_seq%2) + { + *(iseq1Ptr-1) &= 0x0000ffff; + } + *iseq1Ptr = 0; + iseq1Ptr++; + *iseq1Ptr = 0; + iseq1Ptr++; + *iseq1Ptr = 0; + + if(step_seq2 < 0) + { + seq2Ptr = seq2 - dim_cross_correlation + 1; + CrossCorrPtr = &cross_correlation[dim_cross_correlation - 1]; + } + else + { + seq2Ptr = seq2; + CrossCorrPtr = cross_correlation; + } + + len = dim_seq + dim_cross_correlation - 1; + i_len = (len + 1) >> 1; + iseq2Ptr = iseq2; + + iseq3Ptr = iseq3; + for(i = 0; i < i_len; i++) + { + *iseq2Ptr = (unsigned short)*seq2Ptr++; + *iseq3Ptr = (unsigned short)*seq2Ptr; + *iseq2Ptr++ |= (WebRtc_Word32)*seq2Ptr++ << 16; + *iseq3Ptr++ |= (WebRtc_Word32)*seq2Ptr << 16; + } + + if(len % 2) + { + iseq2[i_len - 1] &= 0x0000ffff; + iseq3[i_len - 1] = 0; + } + else + iseq3[i_len - 1] &= 0x0000ffff; + + iseq2[i_len] = 0; + iseq3[i_len] = 0; + iseq2[i_len + 1] = 0; + iseq3[i_len + 1] = 0; + iseq2[i_len + 2] = 0; + iseq3[i_len + 2] = 0; + + // Set pointer to start value + iseq2Ptr = iseq2; + iseq3Ptr = iseq3; + + i_len = (dim_seq + 7) >> 3; + for (i = 0; i < dim_cross_correlation; i++) + { + + iseq1Ptr = iseq1; + + macc40 = 0; + + _WriteCoProcessor(macc40, 0); + + if((i & 1)) + { + iseq3Ptr = iseq3 + (i >> 1); + for (j = i_len; j > 0; j--) + { + _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++); + _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++); + _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++); + _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++); + } + } + else + { + iseq2Ptr = iseq2 + (i >> 1); + for (j = i_len; j > 0; j--) + { + _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++); + _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++); + _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++); + _SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++); + } + + } + + macc40 = _ReadCoProcessor(0); + *CrossCorrPtr = (WebRtc_Word32)(macc40 >> right_shifts); + CrossCorrPtr += step_seq2; + } +#else // #ifdef _XSCALE_OPT_ +#ifdef _ARM_OPT_ + WebRtc_Word16 dim_seq8 = (dim_seq >> 3) << 3; +#endif + + CrossCorrPtr = cross_correlation; + + for (i = 0; i < dim_cross_correlation; i++) + { + // Set the pointer to the static vector, set the pointer to the sliding vector + // and initialize cross_correlation + seq1Ptr = seq1; + seq2Ptr = seq2 + (step_seq2 * i); + (*CrossCorrPtr) = 0; + +#ifndef _ARM_OPT_ +#ifdef _WIN32 +#pragma message("NOTE: default implementation is used") +#endif + // Perform the cross correlation + for (j = 0; j < dim_seq; j++) + { + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), right_shifts); + seq1Ptr++; + seq2Ptr++; + } +#else +#ifdef _WIN32 +#pragma message("NOTE: _ARM_OPT_ optimizations are used") +#endif + if (right_shifts == 0) + { + // Perform the optimized cross correlation + for (j = 0; j < dim_seq8; j = j + 8) + { + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); + seq1Ptr++; + seq2Ptr++; + } + + for (j = dim_seq8; j < dim_seq; j++) + { + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); + seq1Ptr++; + seq2Ptr++; + } + } + else // right_shifts != 0 + + { + // Perform the optimized cross correlation + for (j = 0; j < dim_seq8; j = j + 8) + { + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), + right_shifts); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), + right_shifts); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), + right_shifts); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), + right_shifts); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), + right_shifts); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), + right_shifts); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), + right_shifts); + seq1Ptr++; + seq2Ptr++; + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), + right_shifts); + seq1Ptr++; + seq2Ptr++; + } + + for (j = dim_seq8; j < dim_seq; j++) + { + (*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), + right_shifts); + seq1Ptr++; + seq2Ptr++; + } + } +#endif + CrossCorrPtr++; + } +#endif +} diff --git a/src/libs/webrtc/signal_processing_library/division_operations.c b/src/libs/webrtc/signal_processing_library/division_operations.c new file mode 100644 index 00000000..b143373a --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/division_operations.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains implementations of the divisions + * WebRtcSpl_DivU32U16() + * WebRtcSpl_DivW32W16() + * WebRtcSpl_DivW32W16ResW16() + * WebRtcSpl_DivResultInQ31() + * WebRtcSpl_DivW32HiLow() + * + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +WebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den) +{ + // Guard against division with 0 + if (den != 0) + { + return (WebRtc_UWord32)(num / den); + } else + { + return (WebRtc_UWord32)0xFFFFFFFF; + } +} + +WebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den) +{ + // Guard against division with 0 + if (den != 0) + { + return (WebRtc_Word32)(num / den); + } else + { + return (WebRtc_Word32)0x7FFFFFFF; + } +} + +WebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den) +{ + // Guard against division with 0 + if (den != 0) + { + return (WebRtc_Word16)(num / den); + } else + { + return (WebRtc_Word16)0x7FFF; + } +} + +WebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den) +{ + WebRtc_Word32 L_num = num; + WebRtc_Word32 L_den = den; + WebRtc_Word32 div = 0; + int k = 31; + int change_sign = 0; + + if (num == 0) + return 0; + + if (num < 0) + { + change_sign++; + L_num = -num; + } + if (den < 0) + { + change_sign++; + L_den = -den; + } + while (k--) + { + div <<= 1; + L_num <<= 1; + if (L_num >= L_den) + { + L_num -= L_den; + div++; + } + } + if (change_sign == 1) + { + div = -div; + } + return div; +} + +WebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi, + WebRtc_Word16 den_low) +{ + WebRtc_Word16 approx, tmp_hi, tmp_low, num_hi, num_low; + WebRtc_Word32 tmpW32; + + approx = (WebRtc_Word16)WebRtcSpl_DivW32W16((WebRtc_Word32)0x1FFFFFFF, den_hi); + // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30) + + // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30) + tmpW32 = (WEBRTC_SPL_MUL_16_16(den_hi, approx) << 1) + + ((WEBRTC_SPL_MUL_16_16(den_low, approx) >> 15) << 1); + // tmpW32 = den * approx + + tmpW32 = (WebRtc_Word32)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx)) + + // Store tmpW32 in hi and low format + tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16); + tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32 + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); + + // tmpW32 = 1/den in Q29 + tmpW32 = ((WEBRTC_SPL_MUL_16_16(tmp_hi, approx) + (WEBRTC_SPL_MUL_16_16(tmp_low, approx) + >> 15)) << 1); + + // 1/den in hi and low format + tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16); + tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32 + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); + + // Store num in hi and low format + num_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(num, 16); + num_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((num + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)num_hi, 16)), 1); + + // num * (1/den) by 32 bit multiplication (result in Q28) + + tmpW32 = (WEBRTC_SPL_MUL_16_16(num_hi, tmp_hi) + (WEBRTC_SPL_MUL_16_16(num_hi, tmp_low) + >> 15) + (WEBRTC_SPL_MUL_16_16(num_low, tmp_hi) >> 15)); + + // Put result in Q31 (convert from Q28) + tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3); + + return tmpW32; +} diff --git a/src/libs/webrtc/signal_processing_library/dot_product_with_scale.c b/src/libs/webrtc/signal_processing_library/dot_product_with_scale.c new file mode 100644 index 00000000..6e085fdb --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/dot_product_with_scale.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_DotProductWithScale(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +WebRtc_Word32 WebRtcSpl_DotProductWithScale(WebRtc_Word16 *vector1, WebRtc_Word16 *vector2, + int length, int scaling) +{ + WebRtc_Word32 sum; + int i; +#ifdef _ARM_OPT_ +#pragma message("NOTE: _ARM_OPT_ optimizations are used") + WebRtc_Word16 len4 = (length >> 2) << 2; +#endif + + sum = 0; + +#ifndef _ARM_OPT_ + for (i = 0; i < length; i++) + { + sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1++, *vector2++, scaling); + } +#else + if (scaling == 0) + { + for (i = 0; i < len4; i = i + 4) + { + sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); + vector1++; + vector2++; + sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); + vector1++; + vector2++; + sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); + vector1++; + vector2++; + sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); + vector1++; + vector2++; + } + + for (i = len4; i < length; i++) + { + sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); + vector1++; + vector2++; + } + } + else + { + for (i = 0; i < len4; i = i + 4) + { + sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); + vector1++; + vector2++; + sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); + vector1++; + vector2++; + sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); + vector1++; + vector2++; + sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); + vector1++; + vector2++; + } + + for (i = len4; i < length; i++) + { + sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling); + vector1++; + vector2++; + } + } +#endif + + return sum; +} diff --git a/src/libs/webrtc/signal_processing_library/downsample_fast.c b/src/libs/webrtc/signal_processing_library/downsample_fast.c new file mode 100644 index 00000000..93382751 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/downsample_fast.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_DownsampleFast(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +int WebRtcSpl_DownsampleFast(WebRtc_Word16 *in_ptr, WebRtc_Word16 in_length, + WebRtc_Word16 *out_ptr, WebRtc_Word16 out_length, + WebRtc_Word16 *B, WebRtc_Word16 B_length, WebRtc_Word16 factor, + WebRtc_Word16 delay) +{ + WebRtc_Word32 o; + int i, j; + + WebRtc_Word16 *downsampled_ptr = out_ptr; + WebRtc_Word16 *b_ptr; + WebRtc_Word16 *x_ptr; + WebRtc_Word16 endpos = delay + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(factor, (out_length - 1)) + 1; + + if (in_length < endpos) + { + return -1; + } + + for (i = delay; i < endpos; i += factor) + { + b_ptr = &B[0]; + x_ptr = &in_ptr[i]; + + o = (WebRtc_Word32)2048; // Round val + + for (j = 0; j < B_length; j++) + { + o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--); + } + + o = WEBRTC_SPL_RSHIFT_W32(o, 12); + + // If output is higher than 32768, saturate it. Same with negative side + + *downsampled_ptr++ = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, o, -32768); + } + + return 0; +} diff --git a/src/libs/webrtc/signal_processing_library/energy.c b/src/libs/webrtc/signal_processing_library/energy.c new file mode 100644 index 00000000..e8fdf94e --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/energy.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_Energy(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +WebRtc_Word32 WebRtcSpl_Energy(WebRtc_Word16* vector, int vector_length, int* scale_factor) +{ + WebRtc_Word32 en = 0; + int i; + int scaling = WebRtcSpl_GetScalingSquare(vector, vector_length, vector_length); + int looptimes = vector_length; + WebRtc_Word16 *vectorptr = vector; + + for (i = 0; i < looptimes; i++) + { + en += WEBRTC_SPL_MUL_16_16_RSFT(*vectorptr, *vectorptr, scaling); + vectorptr++; + } + *scale_factor = scaling; + + return en; +} diff --git a/src/libs/webrtc/signal_processing_library/fft_ARM9E/FFT_4OFQ14.s b/src/libs/webrtc/signal_processing_library/fft_ARM9E/FFT_4OFQ14.s new file mode 100644 index 00000000..6e260719 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/fft_ARM9E/FFT_4OFQ14.s @@ -0,0 +1,51 @@ +;// Optimised ARM assembler multi-radix FFT + INCLUDE fft_main_forward.h + + + MACRO + GENERATE_FFT_FUNCTION $flags + ; first work out a readable function name + ; based on the flags + FFT_OPTIONS_STRING $flags, name + + ; Entry: + ; r0 = input array + ; r1 = output array + ; r2 = number of points in FFT + ; r3 = pre-scale shift + ; + ; Exit: + ; r0 = 0 if successful + ; = 1 if table too small + ; + + EXPORT FFT_$name +FFT_4OFQ14 + STMFD sp!, {r4-r11, r14} + IF "$radix"="4O" +tablename SETS "_8" +tablename SETS "$qname$coeforder$tablename" + ELSE +tablename SETS "_4" +tablename SETS "$qname$coeforder$tablename" + ENDIF + IMPORT s_$tablename + LDR lr, =s_$tablename + LDR lr,[lr] + + CMP N, lr + MOVGT r0, #1 + LDMGTFD sp!, {r4-r11, pc} + GENERATE_FFT $flags + MOV r0, #0 + LDMFD sp!, {r4-r11, pc} + LTORG + MEND + + + AREA FFTCODE, CODE, READONLY + + + GENERATE_FFT_FUNCTION FFT_16bit +FFT_RADIX4_8F +FFT_FORWARD ; +FFT_REVERSED + + END diff --git a/src/libs/webrtc/signal_processing_library/fft_ARM9E/FFT_4OIQ14.s b/src/libs/webrtc/signal_processing_library/fft_ARM9E/FFT_4OIQ14.s new file mode 100644 index 00000000..e35f379e --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/fft_ARM9E/FFT_4OIQ14.s @@ -0,0 +1,51 @@ +;// Optimised ARM assembler multi-radix FFT + INCLUDE fft_main_inverse.h + + + MACRO + GENERATE_IFFT_FUNCTION $flags + ; first work out a readable function name + ; based on the flags + FFT_OPTIONS_STRING $flags, name + + ; Entry: + ; r0 = input array + ; r1 = output array + ; r2 = number of points in FFT + ; r3 = pre-scale shift + ; + ; Exit: + ; r0 = 0 if successful + ; = 1 if table too small + ; + + + EXPORT FFT_$name +FFT_4OIQ14 + STMFD sp!, {r4-r11, r14} + IF "$radix"="4O" +tablename SETS "_8" +tablename SETS "$qname$coeforder$tablename" + ELSE +tablename SETS "_4" +tablename SETS "$qname$coeforder$tablename" + ENDIF + IMPORT s_$tablename + LDR lr, =s_$tablename + LDR lr,[lr] + + CMP N, lr + MOVGT r0, #1 + LDMGTFD sp!, {r4-r11, pc} + GENERATE_FFT $flags + MOV r0, #0 + LDMFD sp!, {r4-r11, pc} + LTORG + MEND + + AREA FFTCODE, CODE, READONLY + + + GENERATE_IFFT_FUNCTION FFT_16bit +FFT_RADIX4_8F +FFT_INVERSE +FFT_NONORM ; +FFT_REVERSED + + END diff --git a/src/libs/webrtc/signal_processing_library/fft_ARM9E/fft_mac_forward.h b/src/libs/webrtc/signal_processing_library/fft_ARM9E/fft_mac_forward.h new file mode 100644 index 00000000..59f50b1d --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/fft_ARM9E/fft_mac_forward.h @@ -0,0 +1,774 @@ +; +; $Copyright: +; ---------------------------------------------------------------- +; This confidential and proprietary software may be used only as +; authorised by a licensing agreement from ARM Limited +; (C) COPYRIGHT 2000,2002 ARM Limited +; ALL RIGHTS RESERVED +; The entire notice above must be reproduced on all authorised +; copies and copies may only be made to the extent permitted +; by a licensing agreement from ARM Limited. +; ---------------------------------------------------------------- +; File: fft_mac.h,v +; Revision: 1.14 +; ---------------------------------------------------------------- +; $ +; +; Optimised ARM assembler multi-radix FFT +; Please read the readme.txt before this file +; +; Shared macros and interface definition file. + +; NB: All the algorithms in this code are Decimation in Time. ARM +; is much better at Decimation in Time (as opposed to Decimation +; in Frequency) due to the position of the barrel shifter. Decimation +; in time has the twiddeling at the start of the butterfly, where as +; decimation in frequency has it at the end of the butterfly. The +; post multiply shifts can be hidden for Decimation in Time. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; FIRST STAGE INTERFACE +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; The FIRST STAGE macros "FS_RAD<R>" have the following interface: +; +; ON ENTRY: +; REGISTERS: +; r0 = inptr => points to the input buffer consisting of N complex +; numbers of size (1<<datainlog) bytes each +; r1 = dptr => points to the output buffer consisting of N complex +; numbers of size (1<<datalog) bytes each +; r2 = N => is the number of points in the transform +; r3 = pscale => shift to prescale input by (if applicable) +; ASSEMBLER VARIABLES: +; reversed => logical variable, true if input data is already bit reversed +; The data needs to be bit reversed otherwise +; +; ACTION: +; The routine should +; (1) Bit reverse the data as required for the whole FFT (unless +; the reversed flag is set) +; (2) Prescale the input data by +; (3) Perform a radix R first stage on the data +; (4) Place the processed data in the output array pointed to be dptr +; +; ON EXIT: +; r1 = dptr => preserved and pointing to the output data +; r2 = dinc => number of bytes per "block" or "Group" in this stage +; this is: R<<datalog +; r3 = count => number of radix-R blocks or groups processed in this stage +; this is: N/R +; r0,r4-r12,r14 corrupted + +inptr RN 0 ; input buffer +dptr RN 1 ; output/scratch buffer +N RN 2 ; size of the FFT + +dptr RN 1 ; data pointer - points to end (load in reverse order) +dinc RN 2 ; bytes between data elements at this level of FFT +count RN 3 ; (elements per block<<16) | (blocks per stage) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; GENERAL STAGE INTERFACE +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; The GENERAL STAGE macros "GS_RAD<R>" have the following interface. +; +; To describe the arguments, suppose this routine is called as stage j +; in a k-stage FFT with N=R1*R2*...*Rk. This stage is radix R=Rj. +; +; ON ENTRY: +; REGISTERS: +; r0 = cptr => Pointer to twiddle coefficients for this stage consisting +; of complex numbers of size (1<<coeflog) bytes each in some +; stage dependent format. +; The format currently used in described in full in the +; ReadMe file in the tables subdirectory. +; r1 = dptr => points to the working buffer consisting of N complex +; numbers of size (1<<datalog) bytes each +; r2 = dinc => number of bytes per "block" or "Group" in the last stage: +; dinc = (R1*R2*...*R(j-1))<<datalog +; r3 = count => number of blocks or Groups in the last stage: +; count = Rj*R(j+1)*...*Rk +; NB dinc*count = N<<datalog +; +; ACTION: +; The routine should +; (1) Twiddle the input data +; (2) Perform a radix R stage on the data +; (3) Perform the actions in place, result written to the dptr buffer +; +; ON EXIT: +; r0 = cptr => Updated to the end of the coefficients for the stage +; (the coefficients for the next stage will usually follow) +; r1 = dptr => preserved and pointing to the output data +; r2 = dinc => number of bytes per "block" or "Group" in this stage: +; dinc = (R1*R2*..*Rj)<<datalog = (input dinc)*R +; r3 = count => number of radix-R blocks or groups processed in this stage +; count = R(j+1)*...*Rk = (input count)/R +; r0,r4-r12,r14 corrupted + +cptr RN 0 ; pointer to twiddle coefficients +dptr RN 1 ; pointer to FFT data working buffer +dinc RN 2 ; bytes per block/group at this stage +count RN 3 ; number of blocks/groups at this stage + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; LAST STAGE INTERFACE +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; The LAST STAGE macros "LS_RAD<R>" have the following interface. +; +; ON ENTRY: +; REGISTERS: +; r0 = cptr => Pointer to twiddle coefficients for this stage consisting +; of complex numbers of size (1<<coeflog) bytes each in some +; stage dependent format. +; The format currently used in described in full in the +; ReadMe file in the tables subdirectory. +; There is a possible stride between the coefficients +; specified by cinc +; r1 = dptr => points to the working buffer consisting of N complex +; numbers of size (1<<datalog) bytes each +; r2 = dinc => number of bytes per "block" or "Group" in the last stage: +; dinc = (N/R)<<datalog +; r3 = cinc => Bytes between twiddle values in the array pointed to by cptr +; +; ACTION: +; The routine should +; (1) Twiddle the input data +; (2) Perform a (last stage optimised) radix R stage on the data +; (3) Perform the actions in place, result written to the dptr buffer +; +; ON EXIT: +; r0 = cptr => Updated to point to real-to-complex conversion coefficients +; r1 = dptr => preserved and pointing to the output data +; r2 = dinc => number of bytes per "block" or "Group" in this stage: +; dinc = N<<datalog = (input dinc)*R +; r0,r4-r12,r14 corrupted + +cptr RN 0 ; pointer to twiddle coefficients +dptr RN 1 ; pointer to FFT data working buffer +dinc RN 2 ; bytes per block/group at this stage +cinc RN 3 ; stride between twiddle coefficients in bytes + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; COMPLEX TO REAL CONVERSION INTERFACE +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; The COMPLEX TO REAL macros "LS_ZTOR" have the following interface. +; +; Suppose that 'w' is the N'th root of unity being used for the real FFT +; (usually exp(-2*pi*i/N) for forward transforms and exp(+2*pi*i/N) for +; the inverse transform). +; +; ON ENTRY: +; REGISTERS: +; r0 = cptr => Pointer to twiddle coefficients for this stage +; This consists of (1,w,w^2,w^3,...,w^(N/4-1)). +; There is a stride between each coeficient specified by cinc +; r1 = dptr => points to the working buffer consisting of N/2 complex +; numbers of size (1<<datalog) bytes each +; r2 = dinc => (N/2)<<datalog, the size of the complex buffer in bytes +; r3 = cinc => Bytes between twiddle value in array pointed to by cptr +; r4 = dout => Output buffer (usually the same as dptr) +; +; ACTION: +; The routine should take the output of an N/2 point complex FFT and convert +; it to the output of an N point real FFT, assuming that the real input +; inputs were packed up into the real,imag,real,imag,... buffers of the complex +; input. The output is N/2 complex numbers of the form: +; y[0]+i*y[N/2], y[1], y[2], ..., y[N/2-1] +; where y[0],...,y[N-1] is the output from a complex transform of the N +; real inputs. +; +; ON EXIT: +; r0-r12,r14 corrupted + +cptr RN 0 ; pointer to twiddle coefficients +dptr RN 1 ; pointer to FFT data working buffer +dinc RN 2 ; (N/2)<<datalog, the size of the data in bytes +cinc RN 3 ; bytes between twiddle values in the coefficient buffer +dout RN 4 ; address to write the output (normally the same as dptr) + +;;;;;;;;;;;;;;;;;;;;;; END OF INTERFACES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; first stage/outer loop level +;inptr RN 0 +;dptr RN 1 +;N RN 2 ; size of FFT +;dinc RN 2 ; bytes between block size when bit reversed (scaling of N) +bitrev RN 3 + +; inner loop level +;cptr RN 0 ; coefficient pointer for this level +;dptr RN 1 ; data pointer - points to end (load in reverse order) +;dinc RN 2 ; bytes between data elements at this level of FFT +;count RN 3 ; (elements per block<<16) | (blocks per stage) + +; data registers +x0r RN 4 +x0i RN 5 +x1r RN 6 +x1i RN 7 +x2r RN 8 +x2i RN 9 +x3r RN 10 +x3i RN 11 + +t0 RN 12 ; these MUST be in correct order (t0<t1) for STM's +t1 RN 14 + + MACRO + SETREG $prefix,$v0,$v1 + GBLS $prefix.r + GBLS $prefix.i +$prefix.r SETS "$v0" +$prefix.i SETS "$v1" + MEND + + MACRO + SETREGS $prefix,$v0,$v1,$v2,$v3,$v4,$v5,$v6,$v7 + SETREG $prefix.0,$v0,$v1 + SETREG $prefix.1,$v2,$v3 + SETREG $prefix.2,$v4,$v5 + SETREG $prefix.3,$v6,$v7 + MEND + + MACRO + SET2REGS $prefix,$v0,$v1,$v2,$v3 + SETREG $prefix.0,$v0,$v1 + SETREG $prefix.1,$v2,$v3 + MEND + + ; Macro to load twiddle coeficients + ; Customise according to coeficient format + ; Load next 3 complex coeficients into thr given registers + ; Update the coeficient pointer + MACRO + LOADCOEFS $cp, $c0r, $c0i, $c1r, $c1i, $c2r, $c2i + IF "$coefformat"="W" + ; one word per scalar + LDMIA $cp!, {$c0r, $c0i, $c1r, $c1i, $c2r, $c2i} + MEXIT + ENDIF + IF "$coefformat"="H" + ; one half word per scalar + LDRSH $c0r, [$cp], #2 + LDRSH $c0i, [$cp], #2 + LDRSH $c1r, [$cp], #2 + LDRSH $c1i, [$cp], #2 + LDRSH $c2r, [$cp], #2 + LDRSH $c2i, [$cp], #2 + MEXIT + ENDIF + ERROR "Unsupported coeficient format: $coefformat" + MEND + + ; Macro to load one twiddle coeficient + ; $cp = address to load complex data + ; $ci = post index to make to address after load + MACRO + LOADCOEF $cp, $ci, $re, $im + IF "$coefformat"="W" + LDR $im, [$cp, #4] + LDR $re, [$cp], $ci + MEXIT + ENDIF + IF "$coefformat"="H" + LDRSH $im, [$cp, #2] + LDRSH $re, [$cp], $ci + MEXIT + ENDIF + ERROR "Unsupported coeficient format: $coefformat" + MEND + + ; Macro to load one component of one twiddle coeficient + ; $cp = address to load complex data + ; $ci = post index to make to address after load + MACRO + LOADCOEFR $cp, $re + IF "$coefformat"="W" + LDR $re, [$cp] + MEXIT + ENDIF + IF "$coefformat"="H" + LDRSH $re, [$cp] + MEXIT + ENDIF + ERROR "Unsupported coeficient format: $coefformat" + MEND + + ; Macro to load data elements in the given format + ; $dp = address to load complex data + ; $di = post index to make to address after load + MACRO + LOADDATAF $dp, $di, $re, $im, $format + IF "$format"="W" + LDR $im, [$dp, #4] + LDR $re, [$dp], $di + MEXIT + ENDIF + IF "$format"="H" + LDRSH $im, [$dp, #2] + LDRSH $re, [$dp], $di + MEXIT + ENDIF + ERROR "Unsupported load format: $format" + MEND + + MACRO + LOADDATAZ $dp, $re, $im + IF "$datainformat"="W" + LDMIA $dp, {$re,$im} + MEXIT + ENDIF + IF "$datainformat"="H" + LDRSH $im, [$dp, #2] + LDRSH $re, [$dp] + MEXIT + ENDIF + ERROR "Unsupported load format: $format" + MEND + + ; Load a complex data element from the working array + MACRO + LOADDATA $dp, $di, $re, $im + LOADDATAF $dp, $di, $re, $im, $dataformat + MEND + + ; Load a complex data element from the input array + MACRO + LOADDATAI $dp, $di, $re, $im + LOADDATAF $dp, $di, $re, $im, $datainformat + MEND + + MACRO + LOADDATA4 $dp, $re0,$im0, $re1,$im1, $re2,$im2, $re3,$im3 + IF "$datainformat"="W" + LDMIA $dp!, {$re0,$im0, $re1,$im1, $re2,$im2, $re3,$im3} + ELSE + LOADDATAI $dp, #1<<$datalog, $re0,$im0 + LOADDATAI $dp, #1<<$datalog, $re1,$im1 + LOADDATAI $dp, #1<<$datalog, $re2,$im2 + LOADDATAI $dp, #1<<$datalog, $re3,$im3 + ENDIF + MEND + + ; Shift data after load + MACRO + SHIFTDATA $dr, $di + IF "$postldshift"<>"" + IF "$di"<>"" + MOV $di, $di $postldshift + ENDIF + MOV $dr, $dr $postldshift + ENDIF + MEND + + ; Store a complex data item in the output data buffer + MACRO + STORE $dp, $di, $re, $im + IF "$dataformat"="W" + STR $im, [$dp, #4] + STR $re, [$dp], $di + MEXIT + ENDIF + IF "$dataformat"="H" + STRH $im, [$dp, #2] + STRH $re, [$dp], $di + MEXIT + ENDIF + ERROR "Unsupported save format: $dataformat" + MEND + + ; Store a complex data item in the output data buffer + MACRO + STOREP $dp, $re, $im + IF "$dataformat"="W" + STMIA $dp!, {$re,$im} + MEXIT + ENDIF + IF "$dataformat"="H" + STRH $im, [$dp, #2] + STRH $re, [$dp], #4 + MEXIT + ENDIF + ERROR "Unsupported save format: $dataformat" + MEND + + MACRO + STORE3P $dp, $re0, $im0, $re1, $im1, $re2, $im2 + IF "$dataformat"="W" + STMIA $dp!, {$re0,$im0, $re1,$im1, $re2,$im2} + MEXIT + ENDIF + IF "$dataformat"="H" + STRH $im0, [$dp, #2] + STRH $re0, [$dp], #4 + STRH $im1, [$dp, #2] + STRH $re1, [$dp], #4 + STRH $im2, [$dp, #2] + STRH $re2, [$dp], #4 + MEXIT + ENDIF + ERROR "Unsupported save format: $dataformat" + MEND + + ; do different command depending on forward/inverse FFT + MACRO + DOi $for, $bac, $d, $s1, $s2, $shift + IF "$shift"="" + $for $d, $s1, $s2 + ELSE + $for $d, $s1, $s2, $shift + ENDIF + MEND + + ; d = s1 + s2 if w=exp(+2*pi*i/N) j=+i - inverse transform + ; d = s1 - s2 if w=exp(-2*pi*i/N) j=-i - forward transform + MACRO + ADDi $d, $s1, $s2, $shift + DOi SUB, ADD, $d, $s1, $s2, $shift + MEND + + ; d = s1 - s2 if w=exp(+2*pi*i/N) j=+i - inverse transform + ; d = s1 + s2 if w=exp(-2*pi*i/N) j=-i - forward transform + MACRO + SUBi $d, $s1, $s2, $shift + DOi ADD, SUB, $d, $s1, $s2, $shift + MEND + + ; check that $val is in the range -$max to +$max-1 + ; set carry flag (sicky) if not (2 cycles) + ; has the advantage of not needing a separate register + ; to store the overflow state + MACRO + CHECKOV $val, $tmp, $max + EOR $tmp, $val, $val, ASR#31 + CMPCC $tmp, $max + MEND + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Macro's to perform the twiddle stage (complex multiply by coefficient) +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; The coefficients are stored in different formats according to the +; precision and processor architecture. The coefficients required +; will be of the form: +; +; c(k) = cos( + k*2*pi*i/N ), s(k) = sin( + k*2*pi*i/N ) +; +; c(k) + i*s(k) = exp(+2*pi*k*i/N) +; +; for some k's. The storage formats are: +; +; Format Data +; Q14S (c-s, s) in Q14 format, 16-bits per real +; Q14R (c, s) in Q14 format, 16-bits per real +; Q30S (c-s, s) in Q30 format, 32-bits per real +; +; The operation to be performed is one of: +; +; a+i*b = (x+i*y)*(c-i*s) => forward transform +; OR a+i*b = (x+i*y)*(c+i*s) => inverse transform +; +; For the R format the operation is quite simple - requiring 4 muls +; and 2 adds: +; +; Forward: a = x*c+y*s, b = y*c-x*s +; Inverse: a = x*c-y*s, b = y*c+x*s +; +; For the S format the operations is more complex but only requires +; three multiplies, and is simpler to schedule: +; +; Forward: a = (y-x)*s + x*(c+s) = x*(c-s) + (x+y)*s +; b = (y-x)*s + y*(c-s) = y*(c+s) - (x+y)*s +; +; Inverse: a = (x-y)*s + x*(c-s) +; b = (x-y)*s + y*(c+s) +; +; S advantage 16bit: 1ADD, 1SUB, 1MUL, 2MLA instead of 1SUB, 3MUL, 1MLA +; S advantage 32bit: 2ADD, 1SUB, 2SMULL, 1SMLAL instead of 1RSB, 2SMULL, 2SMLAL +; So S wins except for a very fast multiplier (eg 9E) +; +; NB The coefficients must always be the second operand on processor that +; take a variable number of cycles per multiply - so the FFT time remains constant + + ; This twiddle takes unpacked real and imaginary values + ; Expects (cr,ci) = (c-s,s) on input + ; Sets (cr,ci) = (a,b) on output + MACRO + TWIDDLE $xr, $xi, $cr, $ci, $t0, $t1 + IF qshift>=0 :LAND: qshift<32 + SUB $t1, $xi, $xr ; y-x + MUL $t0, $t1, $ci ; (y-x)*s + ADD $t1, $cr, $ci, LSL #1 ; t1 = c+s allow mul to finish on SA + MLA $ci, $xi, $cr, $t0 ; b + MLA $cr, $xr, $t1, $t0 ; a + ELSE + ADD $t1, $cr, $ci, LSL #1 ; t1 = c+s + SMULL $cr, $t0, $xi, $cr ; t0 = y*(c-s) + SUB $xi, $xi, $xr ; xr = y-x + allow mul to finish on SA + SMULL $ci, $cr, $xi, $ci ; cr = (y-x)*s + ADD $ci, $cr, $t0 ; b + allow mul to finish on SA + SMLAL $t0, $cr, $xr, $t1 ; a + ENDIF + MEND + + ; The following twiddle variant is similar to the above + ; except that it is for an "E" processor varient. A standard + ; 4 multiply twiddle is used as it requires the same number + ; of cycles and needs less intermediate precision + ; + ; $co = coeficent real and imaginary (c,s) (packed) + ; $xx = input data real and imaginary part (packed) + ; + ; $xr = destination register for real part of product + ; $xi = destination register for imaginary part of product + ; + ; All registers should be distinct + ; + MACRO + TWIDDLE_E $xr, $xi, $c0, $t0, $xx, $xxi + SMULBT $t0, $xx, $c0 + SMULBB $xr, $xx, $c0 + IF "$xxi"="" + SMULTB $xi, $xx, $c0 + SMLATT $xr, $xx, $c0, $xr + ELSE + SMULBB $xi, $xxi, $c0 + SMLABT $xr, $xxi, $c0, $xr + ENDIF + SUB $xi, $xi, $t0 + MEND + + ; Scale data value in by the coefficient, writing result to out + ; The coeficient must be the second multiplicand + ; The post mul shift need not be done so in most cases this + ; is just a multiply (unless you need higher precision) + ; coef must be preserved + MACRO + SCALE $out, $in, $coef, $tmp + IF qshift>=0 :LAND: qshift<32 + MUL $out, $in, $coef + ELSE + SMULL $tmp, $out, $in, $coef + ENDIF + MEND + + MACRO + DECODEFORMAT $out, $format + GBLS $out.log + GBLS $out.format +$out.format SETS "$format" + IF "$format"="B" +$out.log SETS "1" + MEXIT + ENDIF + IF "$format"="H" +$out.log SETS "2" + MEXIT + ENDIF + IF "$format"="W" +$out.log SETS "3" + MEXIT + ENDIF + ERROR "Unrecognised format for $out: $format" + MEND + + ; generate a string in $var of the correct right shift + ; amount - negative values = left shift + MACRO + SETSHIFT $var, $value + LCLA svalue +svalue SETA $value +$var SETS "" + IF svalue>0 :LAND: svalue<32 +$var SETS ",ASR #0x$svalue" + ENDIF +svalue SETA -svalue + IF svalue>0 :LAND: svalue<32 +$var SETS ",LSL #0x$svalue" + ENDIF + MEND + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; CODE to decipher the FFT options ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + ; The $flags variable specifies the FFT options + ; The global string $name is set to a textual version + ; The global string $table is set the table name + MACRO + FFT_OPTIONS_STRING $flags, $name + GBLS $name + GBLS qname ; name of the precision (eg Q14, Q30) + GBLS direction ; name of the direction (eg I, F) + GBLS radix ; name of the radix (2, 4E, 4B, 4O etc) + GBLS intype ; name of input data type (if real) + GBLS prescale ; flag to indicate prescale + GBLS outpos ; position for the output data + GBLS datainformat ; bytes per input data item + GBLS dataformat ; bytes per working item + GBLS coefformat ; bytes per coefficient working item + GBLS coeforder ; R=(c,s) S=(c-s,s) storage format + GBLA datainlog ; shift to bytes per input complex + GBLA datalog ; shift to bytes per working complex + GBLA coeflog ; shift to bytes per coefficient complex + GBLA qshift ; right shift after multiply + GBLA norm + GBLA architecture ; 4=Arch4(7TDMI,SA), 5=Arch5TE(ARM9E) + GBLS cdshift + GBLS postmulshift + GBLS postldshift + GBLS postmulshift1 + GBLS postldshift1 + GBLL reversed ; flag to indicate input is already bit reversed + GBLS tablename + + + ; find what sort of processor we are building the FFT for +architecture SETA 4 ; Architecture 4 (7TDMI, StrongARM etc) +;qname SETS {CPU} +; P $qname + IF ((({ARCHITECTURE}:CC:"aaaa"):LEFT:3="5TE") :LOR: (({ARCHITECTURE}:CC:"aa"):LEFT:1="6")) +architecture SETA 5 ; Architecture 5 (ARM9E, E extensions) +; P arch E + ENDIF + +reversed SETL {FALSE} + ; decode input order + IF ($flags:AND:FFT_INPUTORDER)=FFT_REVERSED +reversed SETL {TRUE} + ENDIF + + ; decode radix type to $radix + IF ($flags:AND:FFT_RADIX)=FFT_RADIX4 +radix SETS "4E" + ENDIF + IF ($flags:AND:FFT_RADIX)=FFT_RADIX4_8F +radix SETS "4O" + ENDIF + IF ($flags:AND:FFT_RADIX)=FFT_RADIX4_2L +radix SETS "4B" + ENDIF + + ; decode direction to $direction +direction SETS "F" + + ; decode data size to $qname, and *log's + IF ($flags:AND:FFT_DATA_SIZES)=FFT_32bit +qname SETS "Q30" +datainlog SETA 3 ; 8 bytes per complex +datalog SETA 3 +coeflog SETA 3 +datainformat SETS "W" +dataformat SETS "W" +coefformat SETS "W" +qshift SETA -2 ; shift left top word of 32 bit result + ENDIF + IF ($flags:AND:FFT_DATA_SIZES)=FFT_16bit +qname SETS "Q14" +datainlog SETA 2 +datalog SETA 2 +coeflog SETA 2 +datainformat SETS "H" +dataformat SETS "H" +coefformat SETS "H" +qshift SETA 14 + ENDIF + + ; find the coefficient ordering +coeforder SETS "S" + IF (architecture>=5):LAND:(qshift<16) +coeforder SETS "R" + ENDIF + + ; decode real vs complex input data type +intype SETS "" + IF ($flags:AND:FFT_INPUTTYPE)=FFT_REAL +intype SETS "R" + ENDIF + + ; decode on outpos +outpos SETS "" + IF ($flags:AND:FFT_OUTPUTPOS)=FFT_OUT_INBUF +outpos SETS "I" + ENDIF + + ; decode on prescale +prescale SETS "" + IF ($flags:AND:FFT_INPUTSCALE)=FFT_PRESCALE +prescale SETS "P" + ENDIF + + ; decode on output scale +norm SETA 1 + IF ($flags:AND:FFT_OUTPUTSCALE)=FFT_NONORM +norm SETA 0 + ENDIF + + ; calculate shift to convert data offsets to coefficient offsets + SETSHIFT cdshift, ($datalog)-($coeflog) + +$name SETS "$radix$direction$qname$intype$outpos$prescale" + MEND + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; FFT GENERATOR ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; FFT options bitfield + +FFT_DIRECTION EQU 0x00000001 ; direction select bit +FFT_FORWARD EQU 0x00000000 ; forward exp(-ijkw) coefficient FFT +FFT_INVERSE EQU 0x00000001 ; inverse exp(+ijkw) coefficient FFT + +FFT_INPUTORDER EQU 0x00000002 ; input order select field +FFT_BITREV EQU 0x00000000 ; input data is in normal order (bit reverse) +FFT_REVERSED EQU 0x00000002 ; assume input data is already bit revesed + +FFT_INPUTSCALE EQU 0x00000004 ; select scale on input data +FFT_NOPRESCALE EQU 0x00000000 ; do not scale input data +FFT_PRESCALE EQU 0x00000004 ; scale input data up by a register amount + +FFT_INPUTTYPE EQU 0x00000010 ; selector for real/complex input data +FFT_COMPLEX EQU 0x00000000 ; do complex FFT of N points +FFT_REAL EQU 0x00000010 ; do a 2*N point real FFT + +FFT_OUTPUTPOS EQU 0x00000020 ; where is the output placed? +FFT_OUT_OUTBUF EQU 0x00000000 ; default - in the output buffer +FFT_OUT_INBUF EQU 0x00000020 ; copy it back to the input buffer + +FFT_RADIX EQU 0x00000F00 ; radix select +FFT_RADIX4 EQU 0x00000000 ; radix 4 (log_2 N must be even) +FFT_RADIX4_8F EQU 0x00000100 ; radix 4 with radix 8 first stage +FFT_RADIX4_2L EQU 0x00000200 ; radix 4 with optional radix 2 last stage + +FFT_OUTPUTSCALE EQU 0x00001000 ; select output scale value +FFT_NORMALISE EQU 0x00000000 ; default - divide by N during algorithm +FFT_NONORM EQU 0x00001000 ; calculate the raw sum (no scale) + +FFT_DATA_SIZES EQU 0x000F0000 +FFT_16bit EQU 0x00000000 ; 16-bit data and Q14 coefs +FFT_32bit EQU 0x00010000 ; 32-bit data and Q30 coefs + + END diff --git a/src/libs/webrtc/signal_processing_library/fft_ARM9E/fft_mac_inverse.h b/src/libs/webrtc/signal_processing_library/fft_ARM9E/fft_mac_inverse.h new file mode 100644 index 00000000..785b8f02 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/fft_ARM9E/fft_mac_inverse.h @@ -0,0 +1,774 @@ +; +; $Copyright: +; ---------------------------------------------------------------- +; This confidential and proprietary software may be used only as +; authorised by a licensing agreement from ARM Limited +; (C) COPYRIGHT 2000,2002 ARM Limited +; ALL RIGHTS RESERVED +; The entire notice above must be reproduced on all authorised +; copies and copies may only be made to the extent permitted +; by a licensing agreement from ARM Limited. +; ---------------------------------------------------------------- +; File: fft_mac.h,v +; Revision: 1.14 +; ---------------------------------------------------------------- +; $ +; +; Optimised ARM assembler multi-radix FFT +; Please read the readme.txt before this file +; +; Shared macros and interface definition file. + +; NB: All the algorithms in this code are Decimation in Time. ARM +; is much better at Decimation in Time (as opposed to Decimation +; in Frequency) due to the position of the barrel shifter. Decimation +; in time has the twiddeling at the start of the butterfly, where as +; decimation in frequency has it at the end of the butterfly. The +; post multiply shifts can be hidden for Decimation in Time. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; FIRST STAGE INTERFACE +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; The FIRST STAGE macros "FS_RAD<R>" have the following interface: +; +; ON ENTRY: +; REGISTERS: +; r0 = inptr => points to the input buffer consisting of N complex +; numbers of size (1<<datainlog) bytes each +; r1 = dptr => points to the output buffer consisting of N complex +; numbers of size (1<<datalog) bytes each +; r2 = N => is the number of points in the transform +; r3 = pscale => shift to prescale input by (if applicable) +; ASSEMBLER VARIABLES: +; reversed => logical variable, true if input data is already bit reversed +; The data needs to be bit reversed otherwise +; +; ACTION: +; The routine should +; (1) Bit reverse the data as required for the whole FFT (unless +; the reversed flag is set) +; (2) Prescale the input data by +; (3) Perform a radix R first stage on the data +; (4) Place the processed data in the output array pointed to be dptr +; +; ON EXIT: +; r1 = dptr => preserved and pointing to the output data +; r2 = dinc => number of bytes per "block" or "Group" in this stage +; this is: R<<datalog +; r3 = count => number of radix-R blocks or groups processed in this stage +; this is: N/R +; r0,r4-r12,r14 corrupted + +inptr RN 0 ; input buffer +dptr RN 1 ; output/scratch buffer +N RN 2 ; size of the FFT + +dptr RN 1 ; data pointer - points to end (load in reverse order) +dinc RN 2 ; bytes between data elements at this level of FFT +count RN 3 ; (elements per block<<16) | (blocks per stage) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; GENERAL STAGE INTERFACE +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; The GENERAL STAGE macros "GS_RAD<R>" have the following interface. +; +; To describe the arguments, suppose this routine is called as stage j +; in a k-stage FFT with N=R1*R2*...*Rk. This stage is radix R=Rj. +; +; ON ENTRY: +; REGISTERS: +; r0 = cptr => Pointer to twiddle coefficients for this stage consisting +; of complex numbers of size (1<<coeflog) bytes each in some +; stage dependent format. +; The format currently used in described in full in the +; ReadMe file in the tables subdirectory. +; r1 = dptr => points to the working buffer consisting of N complex +; numbers of size (1<<datalog) bytes each +; r2 = dinc => number of bytes per "block" or "Group" in the last stage: +; dinc = (R1*R2*...*R(j-1))<<datalog +; r3 = count => number of blocks or Groups in the last stage: +; count = Rj*R(j+1)*...*Rk +; NB dinc*count = N<<datalog +; +; ACTION: +; The routine should +; (1) Twiddle the input data +; (2) Perform a radix R stage on the data +; (3) Perform the actions in place, result written to the dptr buffer +; +; ON EXIT: +; r0 = cptr => Updated to the end of the coefficients for the stage +; (the coefficients for the next stage will usually follow) +; r1 = dptr => preserved and pointing to the output data +; r2 = dinc => number of bytes per "block" or "Group" in this stage: +; dinc = (R1*R2*..*Rj)<<datalog = (input dinc)*R +; r3 = count => number of radix-R blocks or groups processed in this stage +; count = R(j+1)*...*Rk = (input count)/R +; r0,r4-r12,r14 corrupted + +cptr RN 0 ; pointer to twiddle coefficients +dptr RN 1 ; pointer to FFT data working buffer +dinc RN 2 ; bytes per block/group at this stage +count RN 3 ; number of blocks/groups at this stage + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; LAST STAGE INTERFACE +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; The LAST STAGE macros "LS_RAD<R>" have the following interface. +; +; ON ENTRY: +; REGISTERS: +; r0 = cptr => Pointer to twiddle coefficients for this stage consisting +; of complex numbers of size (1<<coeflog) bytes each in some +; stage dependent format. +; The format currently used in described in full in the +; ReadMe file in the tables subdirectory. +; There is a possible stride between the coefficients +; specified by cinc +; r1 = dptr => points to the working buffer consisting of N complex +; numbers of size (1<<datalog) bytes each +; r2 = dinc => number of bytes per "block" or "Group" in the last stage: +; dinc = (N/R)<<datalog +; r3 = cinc => Bytes between twiddle values in the array pointed to by cptr +; +; ACTION: +; The routine should +; (1) Twiddle the input data +; (2) Perform a (last stage optimised) radix R stage on the data +; (3) Perform the actions in place, result written to the dptr buffer +; +; ON EXIT: +; r0 = cptr => Updated to point to real-to-complex conversion coefficients +; r1 = dptr => preserved and pointing to the output data +; r2 = dinc => number of bytes per "block" or "Group" in this stage: +; dinc = N<<datalog = (input dinc)*R +; r0,r4-r12,r14 corrupted + +cptr RN 0 ; pointer to twiddle coefficients +dptr RN 1 ; pointer to FFT data working buffer +dinc RN 2 ; bytes per block/group at this stage +cinc RN 3 ; stride between twiddle coefficients in bytes + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; COMPLEX TO REAL CONVERSION INTERFACE +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; The COMPLEX TO REAL macros "LS_ZTOR" have the following interface. +; +; Suppose that 'w' is the N'th root of unity being used for the real FFT +; (usually exp(-2*pi*i/N) for forward transforms and exp(+2*pi*i/N) for +; the inverse transform). +; +; ON ENTRY: +; REGISTERS: +; r0 = cptr => Pointer to twiddle coefficients for this stage +; This consists of (1,w,w^2,w^3,...,w^(N/4-1)). +; There is a stride between each coeficient specified by cinc +; r1 = dptr => points to the working buffer consisting of N/2 complex +; numbers of size (1<<datalog) bytes each +; r2 = dinc => (N/2)<<datalog, the size of the complex buffer in bytes +; r3 = cinc => Bytes between twiddle value in array pointed to by cptr +; r4 = dout => Output buffer (usually the same as dptr) +; +; ACTION: +; The routine should take the output of an N/2 point complex FFT and convert +; it to the output of an N point real FFT, assuming that the real input +; inputs were packed up into the real,imag,real,imag,... buffers of the complex +; input. The output is N/2 complex numbers of the form: +; y[0]+i*y[N/2], y[1], y[2], ..., y[N/2-1] +; where y[0],...,y[N-1] is the output from a complex transform of the N +; real inputs. +; +; ON EXIT: +; r0-r12,r14 corrupted + +cptr RN 0 ; pointer to twiddle coefficients +dptr RN 1 ; pointer to FFT data working buffer +dinc RN 2 ; (N/2)<<datalog, the size of the data in bytes +cinc RN 3 ; bytes between twiddle values in the coefficient buffer +dout RN 4 ; address to write the output (normally the same as dptr) + +;;;;;;;;;;;;;;;;;;;;;; END OF INTERFACES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; first stage/outer loop level +;inptr RN 0 +;dptr RN 1 +;N RN 2 ; size of FFT +;dinc RN 2 ; bytes between block size when bit reversed (scaling of N) +bitrev RN 3 + +; inner loop level +;cptr RN 0 ; coefficient pointer for this level +;dptr RN 1 ; data pointer - points to end (load in reverse order) +;dinc RN 2 ; bytes between data elements at this level of FFT +;count RN 3 ; (elements per block<<16) | (blocks per stage) + +; data registers +x0r RN 4 +x0i RN 5 +x1r RN 6 +x1i RN 7 +x2r RN 8 +x2i RN 9 +x3r RN 10 +x3i RN 11 + +t0 RN 12 ; these MUST be in correct order (t0<t1) for STM's +t1 RN 14 + + MACRO + SETREG $prefix,$v0,$v1 + GBLS $prefix.r + GBLS $prefix.i +$prefix.r SETS "$v0" +$prefix.i SETS "$v1" + MEND + + MACRO + SETREGS $prefix,$v0,$v1,$v2,$v3,$v4,$v5,$v6,$v7 + SETREG $prefix.0,$v0,$v1 + SETREG $prefix.1,$v2,$v3 + SETREG $prefix.2,$v4,$v5 + SETREG $prefix.3,$v6,$v7 + MEND + + MACRO + SET2REGS $prefix,$v0,$v1,$v2,$v3 + SETREG $prefix.0,$v0,$v1 + SETREG $prefix.1,$v2,$v3 + MEND + + ; Macro to load twiddle coeficients + ; Customise according to coeficient format + ; Load next 3 complex coeficients into thr given registers + ; Update the coeficient pointer + MACRO + LOADCOEFS $cp, $c0r, $c0i, $c1r, $c1i, $c2r, $c2i + IF "$coefformat"="W" + ; one word per scalar + LDMIA $cp!, {$c0r, $c0i, $c1r, $c1i, $c2r, $c2i} + MEXIT + ENDIF + IF "$coefformat"="H" + ; one half word per scalar + LDRSH $c0r, [$cp], #2 + LDRSH $c0i, [$cp], #2 + LDRSH $c1r, [$cp], #2 + LDRSH $c1i, [$cp], #2 + LDRSH $c2r, [$cp], #2 + LDRSH $c2i, [$cp], #2 + MEXIT + ENDIF + ERROR "Unsupported coeficient format: $coefformat" + MEND + + ; Macro to load one twiddle coeficient + ; $cp = address to load complex data + ; $ci = post index to make to address after load + MACRO + LOADCOEF $cp, $ci, $re, $im + IF "$coefformat"="W" + LDR $im, [$cp, #4] + LDR $re, [$cp], $ci + MEXIT + ENDIF + IF "$coefformat"="H" + LDRSH $im, [$cp, #2] + LDRSH $re, [$cp], $ci + MEXIT + ENDIF + ERROR "Unsupported coeficient format: $coefformat" + MEND + + ; Macro to load one component of one twiddle coeficient + ; $cp = address to load complex data + ; $ci = post index to make to address after load + MACRO + LOADCOEFR $cp, $re + IF "$coefformat"="W" + LDR $re, [$cp] + MEXIT + ENDIF + IF "$coefformat"="H" + LDRSH $re, [$cp] + MEXIT + ENDIF + ERROR "Unsupported coeficient format: $coefformat" + MEND + + ; Macro to load data elements in the given format + ; $dp = address to load complex data + ; $di = post index to make to address after load + MACRO + LOADDATAF $dp, $di, $re, $im, $format + IF "$format"="W" + LDR $im, [$dp, #4] + LDR $re, [$dp], $di + MEXIT + ENDIF + IF "$format"="H" + LDRSH $im, [$dp, #2] + LDRSH $re, [$dp], $di + MEXIT + ENDIF + ERROR "Unsupported load format: $format" + MEND + + MACRO + LOADDATAZ $dp, $re, $im + IF "$datainformat"="W" + LDMIA $dp, {$re,$im} + MEXIT + ENDIF + IF "$datainformat"="H" + LDRSH $im, [$dp, #2] + LDRSH $re, [$dp] + MEXIT + ENDIF + ERROR "Unsupported load format: $format" + MEND + + ; Load a complex data element from the working array + MACRO + LOADDATA $dp, $di, $re, $im + LOADDATAF $dp, $di, $re, $im, $dataformat + MEND + + ; Load a complex data element from the input array + MACRO + LOADDATAI $dp, $di, $re, $im + LOADDATAF $dp, $di, $re, $im, $datainformat + MEND + + MACRO + LOADDATA4 $dp, $re0,$im0, $re1,$im1, $re2,$im2, $re3,$im3 + IF "$datainformat"="W" + LDMIA $dp!, {$re0,$im0, $re1,$im1, $re2,$im2, $re3,$im3} + ELSE + LOADDATAI $dp, #1<<$datalog, $re0,$im0 + LOADDATAI $dp, #1<<$datalog, $re1,$im1 + LOADDATAI $dp, #1<<$datalog, $re2,$im2 + LOADDATAI $dp, #1<<$datalog, $re3,$im3 + ENDIF + MEND + + ; Shift data after load + MACRO + SHIFTDATA $dr, $di + IF "$postldshift"<>"" + IF "$di"<>"" + MOV $di, $di $postldshift + ENDIF + MOV $dr, $dr $postldshift + ENDIF + MEND + + ; Store a complex data item in the output data buffer + MACRO + STORE $dp, $di, $re, $im + IF "$dataformat"="W" + STR $im, [$dp, #4] + STR $re, [$dp], $di + MEXIT + ENDIF + IF "$dataformat"="H" + STRH $im, [$dp, #2] + STRH $re, [$dp], $di + MEXIT + ENDIF + ERROR "Unsupported save format: $dataformat" + MEND + + ; Store a complex data item in the output data buffer + MACRO + STOREP $dp, $re, $im + IF "$dataformat"="W" + STMIA $dp!, {$re,$im} + MEXIT + ENDIF + IF "$dataformat"="H" + STRH $im, [$dp, #2] + STRH $re, [$dp], #4 + MEXIT + ENDIF + ERROR "Unsupported save format: $dataformat" + MEND + + MACRO + STORE3P $dp, $re0, $im0, $re1, $im1, $re2, $im2 + IF "$dataformat"="W" + STMIA $dp!, {$re0,$im0, $re1,$im1, $re2,$im2} + MEXIT + ENDIF + IF "$dataformat"="H" + STRH $im0, [$dp, #2] + STRH $re0, [$dp], #4 + STRH $im1, [$dp, #2] + STRH $re1, [$dp], #4 + STRH $im2, [$dp, #2] + STRH $re2, [$dp], #4 + MEXIT + ENDIF + ERROR "Unsupported save format: $dataformat" + MEND + + ; do different command depending on forward/inverse FFT + MACRO + DOi $for, $bac, $d, $s1, $s2, $shift + IF "$shift"="" + $bac $d, $s1, $s2 + ELSE + $bac $d, $s1, $s2, $shift + ENDIF + MEND + + ; d = s1 + s2 if w=exp(+2*pi*i/N) j=+i - inverse transform + ; d = s1 - s2 if w=exp(-2*pi*i/N) j=-i - forward transform + MACRO + ADDi $d, $s1, $s2, $shift + DOi SUB, ADD, $d, $s1, $s2, $shift + MEND + + ; d = s1 - s2 if w=exp(+2*pi*i/N) j=+i - inverse transform + ; d = s1 + s2 if w=exp(-2*pi*i/N) j=-i - forward transform + MACRO + SUBi $d, $s1, $s2, $shift + DOi ADD, SUB, $d, $s1, $s2, $shift + MEND + + ; check that $val is in the range -$max to +$max-1 + ; set carry flag (sicky) if not (2 cycles) + ; has the advantage of not needing a separate register + ; to store the overflow state + MACRO + CHECKOV $val, $tmp, $max + EOR $tmp, $val, $val, ASR#31 + CMPCC $tmp, $max + MEND + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Macro's to perform the twiddle stage (complex multiply by coefficient) +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; The coefficients are stored in different formats according to the +; precision and processor architecture. The coefficients required +; will be of the form: +; +; c(k) = cos( + k*2*pi*i/N ), s(k) = sin( + k*2*pi*i/N ) +; +; c(k) + i*s(k) = exp(+2*pi*k*i/N) +; +; for some k's. The storage formats are: +; +; Format Data +; Q14S (c-s, s) in Q14 format, 16-bits per real +; Q14R (c, s) in Q14 format, 16-bits per real +; Q30S (c-s, s) in Q30 format, 32-bits per real +; +; The operation to be performed is one of: +; +; a+i*b = (x+i*y)*(c-i*s) => forward transform +; OR a+i*b = (x+i*y)*(c+i*s) => inverse transform +; +; For the R format the operation is quite simple - requiring 4 muls +; and 2 adds: +; +; Forward: a = x*c+y*s, b = y*c-x*s +; Inverse: a = x*c-y*s, b = y*c+x*s +; +; For the S format the operations is more complex but only requires +; three multiplies, and is simpler to schedule: +; +; Forward: a = (y-x)*s + x*(c+s) = x*(c-s) + (x+y)*s +; b = (y-x)*s + y*(c-s) = y*(c+s) - (x+y)*s +; +; Inverse: a = (x-y)*s + x*(c-s) +; b = (x-y)*s + y*(c+s) +; +; S advantage 16bit: 1ADD, 1SUB, 1MUL, 2MLA instead of 1SUB, 3MUL, 1MLA +; S advantage 32bit: 2ADD, 1SUB, 2SMULL, 1SMLAL instead of 1RSB, 2SMULL, 2SMLAL +; So S wins except for a very fast multiplier (eg 9E) +; +; NB The coefficients must always be the second operand on processor that +; take a variable number of cycles per multiply - so the FFT time remains constant + + ; This twiddle takes unpacked real and imaginary values + ; Expects (cr,ci) = (c-s,s) on input + ; Sets (cr,ci) = (a,b) on output + MACRO + TWIDDLE $xr, $xi, $cr, $ci, $t0, $t1 + IF qshift>=0 :LAND: qshift<32 + SUB $t1, $xr, $xi ; x-y + MUL $t0, $t1, $ci ; (x-y)*s + ADD $ci, $cr, $ci, LSL #1 ; ci = c+s allow mul to finish on SA + MLA $cr, $xr, $cr, $t0 ; a + MLA $ci, $xi, $ci, $t0 ; b + ELSE + ADD $t1, $cr, $ci, LSL #1 ; c+s + SMULL $t0, $cr, $xr, $cr ; x*(c-s) + SUB $xr, $xr, $xi ; x-y + allow mul to finish on SA + SMULL $t0, $ci, $xr, $ci ; (x-y)*s + ADD $cr, $cr, $ci ; a + allow mul to finish on SA + SMLAL $t0, $ci, $xi, $t1 ; b + ENDIF + MEND + + ; The following twiddle variant is similar to the above + ; except that it is for an "E" processor varient. A standard + ; 4 multiply twiddle is used as it requires the same number + ; of cycles and needs less intermediate precision + ; + ; $co = coeficent real and imaginary (c,s) (packed) + ; $xx = input data real and imaginary part (packed) + ; + ; $xr = destination register for real part of product + ; $xi = destination register for imaginary part of product + ; + ; All registers should be distinct + ; + MACRO + TWIDDLE_E $xr, $xi, $c0, $t0, $xx, $xxi + SMULBB $t0, $xx, $c0 + SMULBT $xi, $xx, $c0 + IF "$xxi"="" + SMULTT $xr, $xx, $c0 + SMLATB $xi, $xx, $c0, $xi + ELSE + SMULBT $xr, $xxi, $c0 + SMLABB $xi, $xxi, $c0, $xi + ENDIF + SUB $xr, $t0, $xr + MEND + + ; Scale data value in by the coefficient, writing result to out + ; The coeficient must be the second multiplicand + ; The post mul shift need not be done so in most cases this + ; is just a multiply (unless you need higher precision) + ; coef must be preserved + MACRO + SCALE $out, $in, $coef, $tmp + IF qshift>=0 :LAND: qshift<32 + MUL $out, $in, $coef + ELSE + SMULL $tmp, $out, $in, $coef + ENDIF + MEND + + MACRO + DECODEFORMAT $out, $format + GBLS $out.log + GBLS $out.format +$out.format SETS "$format" + IF "$format"="B" +$out.log SETS "1" + MEXIT + ENDIF + IF "$format"="H" +$out.log SETS "2" + MEXIT + ENDIF + IF "$format"="W" +$out.log SETS "3" + MEXIT + ENDIF + ERROR "Unrecognised format for $out: $format" + MEND + + ; generate a string in $var of the correct right shift + ; amount - negative values = left shift + MACRO + SETSHIFT $var, $value + LCLA svalue +svalue SETA $value +$var SETS "" + IF svalue>0 :LAND: svalue<32 +$var SETS ",ASR #0x$svalue" + ENDIF +svalue SETA -svalue + IF svalue>0 :LAND: svalue<32 +$var SETS ",LSL #0x$svalue" + ENDIF + MEND + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; CODE to decipher the FFT options ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + ; The $flags variable specifies the FFT options + ; The global string $name is set to a textual version + ; The global string $table is set the table name + MACRO + FFT_OPTIONS_STRING $flags, $name + GBLS $name + GBLS qname ; name of the precision (eg Q14, Q30) + GBLS direction ; name of the direction (eg I, F) + GBLS radix ; name of the radix (2, 4E, 4B, 4O etc) + GBLS intype ; name of input data type (if real) + GBLS prescale ; flag to indicate prescale + GBLS outpos ; position for the output data + GBLS datainformat ; bytes per input data item + GBLS dataformat ; bytes per working item + GBLS coefformat ; bytes per coefficient working item + GBLS coeforder ; R=(c,s) S=(c-s,s) storage format + GBLA datainlog ; shift to bytes per input complex + GBLA datalog ; shift to bytes per working complex + GBLA coeflog ; shift to bytes per coefficient complex + GBLA qshift ; right shift after multiply + GBLA norm + GBLA architecture ; 4=Arch4(7TDMI,SA), 5=Arch5TE(ARM9E) + GBLS cdshift + GBLS postmulshift + GBLS postldshift + GBLS postmulshift1 + GBLS postldshift1 + GBLL reversed ; flag to indicate input is already bit reversed + GBLS tablename + + + ; find what sort of processor we are building the FFT for +architecture SETA 4 ; Architecture 4 (7TDMI, StrongARM etc) +;qname SETS {CPU} +; P $qname + IF ((({ARCHITECTURE}:CC:"aaaa"):LEFT:3="5TE") :LOR: (({ARCHITECTURE}:CC:"aa"):LEFT:1="6")) +architecture SETA 5 ; Architecture 5 (ARM9E, E extensions) +; P arch E + ENDIF + +reversed SETL {FALSE} + ; decode input order + IF ($flags:AND:FFT_INPUTORDER)=FFT_REVERSED +reversed SETL {TRUE} + ENDIF + + ; decode radix type to $radix + IF ($flags:AND:FFT_RADIX)=FFT_RADIX4 +radix SETS "4E" + ENDIF + IF ($flags:AND:FFT_RADIX)=FFT_RADIX4_8F +radix SETS "4O" + ENDIF + IF ($flags:AND:FFT_RADIX)=FFT_RADIX4_2L +radix SETS "4B" + ENDIF + + ; decode direction to $direction +direction SETS "I" + + ; decode data size to $qname, and *log's + IF ($flags:AND:FFT_DATA_SIZES)=FFT_32bit +qname SETS "Q30" +datainlog SETA 3 ; 8 bytes per complex +datalog SETA 3 +coeflog SETA 3 +datainformat SETS "W" +dataformat SETS "W" +coefformat SETS "W" +qshift SETA -2 ; shift left top word of 32 bit result + ENDIF + IF ($flags:AND:FFT_DATA_SIZES)=FFT_16bit +qname SETS "Q14" +datainlog SETA 2 +datalog SETA 2 +coeflog SETA 2 +datainformat SETS "H" +dataformat SETS "H" +coefformat SETS "H" +qshift SETA 14 + ENDIF + + ; find the coefficient ordering +coeforder SETS "S" + IF (architecture>=5):LAND:(qshift<16) +coeforder SETS "R" + ENDIF + + ; decode real vs complex input data type +intype SETS "" + IF ($flags:AND:FFT_INPUTTYPE)=FFT_REAL +intype SETS "R" + ENDIF + + ; decode on outpos +outpos SETS "" + IF ($flags:AND:FFT_OUTPUTPOS)=FFT_OUT_INBUF +outpos SETS "I" + ENDIF + + ; decode on prescale +prescale SETS "" + IF ($flags:AND:FFT_INPUTSCALE)=FFT_PRESCALE +prescale SETS "P" + ENDIF + + ; decode on output scale +norm SETA 1 + IF ($flags:AND:FFT_OUTPUTSCALE)=FFT_NONORM +norm SETA 0 + ENDIF + + ; calculate shift to convert data offsets to coefficient offsets + SETSHIFT cdshift, ($datalog)-($coeflog) + +$name SETS "$radix$direction$qname$intype$outpos$prescale" + MEND + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; FFT GENERATOR ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; FFT options bitfield + +FFT_DIRECTION EQU 0x00000001 ; direction select bit +FFT_FORWARD EQU 0x00000000 ; forward exp(-ijkw) coefficient FFT +FFT_INVERSE EQU 0x00000001 ; inverse exp(+ijkw) coefficient FFT + +FFT_INPUTORDER EQU 0x00000002 ; input order select field +FFT_BITREV EQU 0x00000000 ; input data is in normal order (bit reverse) +FFT_REVERSED EQU 0x00000002 ; assume input data is already bit revesed + +FFT_INPUTSCALE EQU 0x00000004 ; select scale on input data +FFT_NOPRESCALE EQU 0x00000000 ; do not scale input data +FFT_PRESCALE EQU 0x00000004 ; scale input data up by a register amount + +FFT_INPUTTYPE EQU 0x00000010 ; selector for real/complex input data +FFT_COMPLEX EQU 0x00000000 ; do complex FFT of N points +FFT_REAL EQU 0x00000010 ; do a 2*N point real FFT + +FFT_OUTPUTPOS EQU 0x00000020 ; where is the output placed? +FFT_OUT_OUTBUF EQU 0x00000000 ; default - in the output buffer +FFT_OUT_INBUF EQU 0x00000020 ; copy it back to the input buffer + +FFT_RADIX EQU 0x00000F00 ; radix select +FFT_RADIX4 EQU 0x00000000 ; radix 4 (log_2 N must be even) +FFT_RADIX4_8F EQU 0x00000100 ; radix 4 with radix 8 first stage +FFT_RADIX4_2L EQU 0x00000200 ; radix 4 with optional radix 2 last stage + +FFT_OUTPUTSCALE EQU 0x00001000 ; select output scale value +FFT_NORMALISE EQU 0x00000000 ; default - divide by N during algorithm +FFT_NONORM EQU 0x00001000 ; calculate the raw sum (no scale) + +FFT_DATA_SIZES EQU 0x000F0000 +FFT_16bit EQU 0x00000000 ; 16-bit data and Q14 coefs +FFT_32bit EQU 0x00010000 ; 32-bit data and Q30 coefs + + END diff --git a/src/libs/webrtc/signal_processing_library/fft_ARM9E/fft_main_forward.h b/src/libs/webrtc/signal_processing_library/fft_ARM9E/fft_main_forward.h new file mode 100644 index 00000000..aa49a010 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/fft_ARM9E/fft_main_forward.h @@ -0,0 +1,101 @@ +; +; $Copyright: +; ---------------------------------------------------------------- +; This confidential and proprietary software may be used only as +; authorised by a licensing agreement from ARM Limited +; (C) COPYRIGHT 2000,2002 ARM Limited +; ALL RIGHTS RESERVED +; The entire notice above must be reproduced on all authorised +; copies and copies may only be made to the extent permitted +; by a licensing agreement from ARM Limited. +; ---------------------------------------------------------------- +; File: fft_main.h,v +; Revision: 1.10 +; ---------------------------------------------------------------- +; $ +; +; Optimised ARM assembler multi-radix FFT +; Please read the readme.txt before this file +; + + INCLUDE fft_mac_forward.h ; general macros + INCLUDE fs_rad8_forward.h ; first stage, radix 8 macros + INCLUDE gs_rad4.h ; general stage, radix 4 macros + +; The macro in this file generates a whole FFT by glueing together +; FFT stage macros. It is designed to handle a range of power-of-2 +; FFT's, the power of 2 set at run time. + +; The following should be set up: +; +; $flags = a 32-bit integer indicating what FFT code to generate +; formed by a bitmask of the above FFT_* flag definitions +; (see fft_mac.h) +; +; r0 = inptr = address of the input buffer +; r1 = dptr = address of the output buffer +; r2 = N = the number of points in the FFT +; r3 = = optional pre-left shift to apply to the input data +; +; The contents of the input buffer are preserved (provided that the +; input and output buffer are different, which must be the case unless +; no bitreversal is required and the input is provided pre-reversed). + + MACRO + GENERATE_FFT $flags + ; decode the options word + FFT_OPTIONS_STRING $flags, name + + IF "$outpos"<>"" + ; stack the input buffer address for later on + STMFD sp!, {inptr} + ENDIF + + ; Do first stage - radix 4 or radix 8 depending on parity + IF "$radix"="4O" + FS_RAD8 +tablename SETS "_8" +tablename SETS "$qname$coeforder$tablename" + ELSE + FS_RAD4 +tablename SETS "_4" +tablename SETS "$qname$coeforder$tablename" + ENDIF + IMPORT t_$tablename + LDR cptr, =t_$tablename ; coefficient table + CMP count, #1 + BEQ %FT10 ; exit for small case + +12 ; General stage loop + GS_RAD4 + CMP count, #2 + BGT %BT12 + + IF "$radix"="4B" + ; support odd parity as well + ;BLT %FT10 ; less than 2 left (ie, finished) + ;LS_RAD2 ; finish off with a radix 2 stage + ENDIF + +10 ; we've finished the complex FFT + IF ($flags:AND:FFT_INPUTTYPE)=FFT_REAL + ; convert to a real FFT + IF "$outpos"="I" + LDMFD sp!, {dout} + ELSE + MOV dout, dptr + ENDIF + ; dinc = (N/2) >> datalog where N is the number of real points + IMPORT s_$tablename + LDR t0, = s_$tablename + LDR t0, [t0] ; max N handled by the table + MOV t1, dinc, LSR #($datalog-1) ; real N we want to handle + CMP t0, t1 + MOV cinc, #3<<$coeflog ; radix 4 table stage + MOVEQ cinc, #1<<$coeflog ; radix 4 table stage + LS_ZTOR + ENDIF + + MEND + + END diff --git a/src/libs/webrtc/signal_processing_library/fft_ARM9E/fft_main_inverse.h b/src/libs/webrtc/signal_processing_library/fft_ARM9E/fft_main_inverse.h new file mode 100644 index 00000000..0a0dfc45 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/fft_ARM9E/fft_main_inverse.h @@ -0,0 +1,101 @@ +; +; $Copyright: +; ---------------------------------------------------------------- +; This confidential and proprietary software may be used only as +; authorised by a licensing agreement from ARM Limited +; (C) COPYRIGHT 2000,2002 ARM Limited +; ALL RIGHTS RESERVED +; The entire notice above must be reproduced on all authorised +; copies and copies may only be made to the extent permitted +; by a licensing agreement from ARM Limited. +; ---------------------------------------------------------------- +; File: fft_main.h,v +; Revision: 1.10 +; ---------------------------------------------------------------- +; $ +; +; Optimised ARM assembler multi-radix FFT +; Please read the readme.txt before this file +; + + INCLUDE fft_mac_inverse.h ; general macros + INCLUDE fs_rad8_inverse.h ; first stage, radix 8 macros + INCLUDE gs_rad4.h ; general stage, radix 4 macros + +; The macro in this file generates a whole FFT by glueing together +; FFT stage macros. It is designed to handle a range of power-of-2 +; FFT's, the power of 2 set at run time. + +; The following should be set up: +; +; $flags = a 32-bit integer indicating what FFT code to generate +; formed by a bitmask of the above FFT_* flag definitions +; (see fft_mac.h) +; +; r0 = inptr = address of the input buffer +; r1 = dptr = address of the output buffer +; r2 = N = the number of points in the FFT +; r3 = = optional pre-left shift to apply to the input data +; +; The contents of the input buffer are preserved (provided that the +; input and output buffer are different, which must be the case unless +; no bitreversal is required and the input is provided pre-reversed). + + MACRO + GENERATE_FFT $flags + ; decode the options word + FFT_OPTIONS_STRING $flags, name + + IF "$outpos"<>"" + ; stack the input buffer address for later on + STMFD sp!, {inptr} + ENDIF + + ; Do first stage - radix 4 or radix 8 depending on parity + IF "$radix"="4O" + FS_RAD8 +tablename SETS "_8" +tablename SETS "$qname$coeforder$tablename" + ELSE + FS_RAD4 +tablename SETS "_4" +tablename SETS "$qname$coeforder$tablename" + ENDIF + IMPORT t_$tablename + LDR cptr, =t_$tablename ; coefficient table + CMP count, #1 + BEQ %FT10 ; exit for small case + +12 ; General stage loop + GS_RAD4 + CMP count, #2 + BGT %BT12 + + IF "$radix"="4B" + ; support odd parity as well + ;BLT %FT10 ; less than 2 left (ie, finished) + ;LS_RAD2 ; finish off with a radix 2 stage + ENDIF + +10 ; we've finished the complex FFT + IF ($flags:AND:FFT_INPUTTYPE)=FFT_REAL + ; convert to a real FFT + IF "$outpos"="I" + LDMFD sp!, {dout} + ELSE + MOV dout, dptr + ENDIF + ; dinc = (N/2) >> datalog where N is the number of real points + IMPORT s_$tablename + LDR t0, = s_$tablename + LDR t0, [t0] ; max N handled by the table + MOV t1, dinc, LSR #($datalog-1) ; real N we want to handle + CMP t0, t1 + MOV cinc, #3<<$coeflog ; radix 4 table stage + MOVEQ cinc, #1<<$coeflog ; radix 4 table stage + LS_ZTOR + ENDIF + + MEND + + END diff --git a/src/libs/webrtc/signal_processing_library/fft_ARM9E/fs_rad8_forward.h b/src/libs/webrtc/signal_processing_library/fft_ARM9E/fs_rad8_forward.h new file mode 100644 index 00000000..bcbf267a --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/fft_ARM9E/fs_rad8_forward.h @@ -0,0 +1,236 @@ +; +; $Copyright: +; ---------------------------------------------------------------- +; This confidential and proprietary software may be used only as +; authorised by a licensing agreement from ARM Limited +; (C) COPYRIGHT 2000,2002 ARM Limited +; ALL RIGHTS RESERVED +; The entire notice above must be reproduced on all authorised +; copies and copies may only be made to the extent permitted +; by a licensing agreement from ARM Limited. +; ---------------------------------------------------------------- +; File: fs_rad8.h,v +; Revision: 1.5 +; ---------------------------------------------------------------- +; $ +; +; Optimised ARM assembler multi-radix FFT +; Please read the readme.txt before this file +; +; This file contains first stage, radix-8 code +; It bit reverses (assuming a power of 2 FFT) and performs the first stage +; + + MACRO + FS_RAD8 + SETSHIFT postldshift, 3*norm + SETSHIFT postmulshift, 3*norm+qshift + SETSHIFT postldshift1, 3*norm-1 + SETSHIFT postmulshift1, 3*norm+qshift-1 + IF "$prescale"<>"" + STMFD sp!, {dptr, N, r3} + ELSE + STMFD sp!, {dptr, N} + ENDIF + MOV bitrev, #0 + MOV dinc, N, LSL #($datalog-2) +12 ; first (radix 8) stage loop + ; do first two (radix 2) stages + FIRST_STAGE_RADIX8_ODD dinc, "dinc, LSR #1", bitrev + FIRST_STAGE_RADIX8_EVEN dinc, bitrev + ; third (radix 2) stage + LDMFD sp!, {x0r, x0i} + ADD $h0r, $h0r, x0r $postldshift ; standard add + ADD $h0i, $h0i, x0i $postldshift + SUB x0r, $h0r, x0r $postldshift1 + SUB x0i, $h0i, x0i $postldshift1 + STORE dptr, #1<<$datalog, $h0r, $h0i + LDMFD sp!, {x1r, x1i} + ADD $h1r, $h1r, x1r $postmulshift + ADD $h1i, $h1i, x1i $postmulshift + SUB x1r, $h1r, x1r $postmulshift1 + SUB x1i, $h1i, x1i $postmulshift1 + STORE dptr, #1<<$datalog, $h1r, $h1i + LDMFD sp!, {x2r, x2i} + SUBi $h2r, $h2r, x2r $postldshift ; note that x2r & x2i were + ADDi $h2i, $h2i, x2i $postldshift ; swapped above + ADDi x2r, $h2r, x2r $postldshift1 + SUBi x2i, $h2i, x2i $postldshift1 + STORE dptr, #1<<$datalog, $h2r, $h2i + LDMFD sp!, {x3r, x3i} + ADD $h3r, $h3r, x3r $postmulshift + ADD $h3i, $h3i, x3i $postmulshift + SUB x3r, $h3r, x3r $postmulshift1 + SUB x3i, $h3i, x3i $postmulshift1 + STORE dptr, #1<<$datalog, $h3r, $h3i + STORE dptr, #1<<$datalog, x0r, x0i + STORE dptr, #1<<$datalog, x1r, x1i + STORE dptr, #1<<$datalog, x2r, x2i + STORE dptr, #1<<$datalog, x3r, x3i + + IF reversed + SUBS dinc, dinc, #2<<$datalog + BGT %BT12 + ELSE + ; increment the count in a bit reverse manner + EOR bitrev, bitrev, dinc, LSR #($datalog-2+4) ; t0 = (N/8)>>1 + TST bitrev, dinc, LSR #($datalog-2+4) + BNE %BT12 + ; get here for 1/2 the loops - carry to next bit + EOR bitrev, bitrev, dinc, LSR #($datalog-2+5) + TST bitrev, dinc, LSR #($datalog-2+5) + BNE %BT12 + ; get here for 1/4 of the loops - stop unrolling + MOV t0, dinc, LSR #($datalog-2+6) +15 ; bit reverse increment loop + EOR bitrev, bitrev, t0 + TST bitrev, t0 + BNE %BT12 + ; get here for 1/8 of the loops (or when finished) + MOVS t0, t0, LSR #1 ; move down to next bit + BNE %BT15 ; carry on if we haven't run off the bottom + ENDIF + + IF "$prescale"<>"" + LDMFD sp!, {dptr, N, r3} + ELSE + LDMFD sp!, {dptr, N} + ENDIF + MOV count, N, LSR #3 ; start with N/8 blocks 8 each + MOV dinc, #8<<$datalog ; initial skip is 8 elements + MEND + + + + MACRO + FIRST_STAGE_RADIX8_ODD $dinc, $dinc_lsr1, $bitrev + + IF reversed + ; load non bit reversed + ADD t0, inptr, #4<<$datalog + LOADDATAI t0, #1<<$datalog, x0r, x0i + LOADDATAI t0, #1<<$datalog, x1r, x1i + LOADDATAI t0, #1<<$datalog, x2r, x2i + LOADDATAI t0, #1<<$datalog, x3r, x3i + ELSE + ; load data elements 1,3,5,7 into register order 1,5,3,7 + ADD t0, inptr, $bitrev, LSL #$datalog + ADD t0, t0, $dinc_lsr1 ; load in odd terms first + LOADDATAI t0, $dinc, x0r, x0i + LOADDATAI t0, $dinc, x2r, x2i + LOADDATAI t0, $dinc, x1r, x1i + LOADDATAI t0, $dinc, x3r, x3i + ENDIF + + IF "$prescale"="P" + LDR t0, [sp, #8] + MOV x0r, x0r, LSL t0 + MOV x0i, x0i, LSL t0 + MOV x1r, x1r, LSL t0 + MOV x1i, x1i, LSL t0 + MOV x2r, x2r, LSL t0 + MOV x2i, x2i, LSL t0 + MOV x3r, x3r, LSL t0 + MOV x3i, x3i, LSL t0 + ENDIF + + SETREG h2, x3r, x3i + SETREG h3, t0, t1 + ; first stage (radix 2) butterflies + ADD x0r, x0r, x1r + ADD x0i, x0i, x1i + SUB x1r, x0r, x1r, LSL #1 + SUB x1i, x0i, x1i, LSL #1 + SUB $h3r, x2r, x3r + SUB $h3i, x2i, x3i + ADD $h2r, x2r, x3r + ADD $h2i, x2i, x3i + ; second stage (radix 2) butterflies + SUB x2i, x0r, $h2r ; swap real and imag here + SUB x2r, x0i, $h2i ; for use later + ADD x0r, x0r, $h2r + ADD x0i, x0i, $h2i + ADDi x3r, x1r, $h3i + SUBi x3i, x1i, $h3r + SUBi x1r, x1r, $h3i + ADDi x1i, x1i, $h3r + ; do the 1/sqrt(2) (+/-1 +/- i) twiddles for third stage + LCLS tempname +tempname SETS "R_rad8" + IMPORT t_$qname$tempname + LDR t1, =t_$qname$tempname +; IMPORT t_$qname.R_rad8 +; LDR t1, =t_$qname.R_rad8 + LOADCOEFR t1, t1 + + STMFD sp!, {dinc} ;;; FIXME!!! + + ADD t0, x1r, x1i ; real part when * (1-i) + SCALE x1r, t0, t1, dinc ; scale by 1/sqrt(2) + RSB t0, t0, x1i, LSL #1 ; imag part when * (1-i) + SCALE x1i, t0, t1, dinc ; scale by 1/sqrt(2) + SUB t0, x3i, x3r ; real part when * (-1-i) + SCALE x3r, t0, t1, dinc ; scale by 1/sqrt(2) + SUB t0, t0, x3i, LSL #1 ; imag part when * (-1-i) + SCALE x3i, t0, t1, dinc ; scale by 1/sqrt(2) + + LDMFD sp!, {dinc} ;;; FIXME!!! + STMFD sp!, {x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i} + MEND + + MACRO + FIRST_STAGE_RADIX8_EVEN $dinc, $bitrev + ; load elements 0,2,4,6 into register order 0,4,2,6 + SETREGS h, x1r, x1i, x2r, x2i, x3r, x3i, t0, t1 + SETREG g3, x0r, x0i + + IF reversed + ; load normally + LOADDATAI inptr, #1<<$datalog, $h0r, $h0i + LOADDATAI inptr, #1<<$datalog, $h1r, $h1i + LOADDATAI inptr, #1<<$datalog, $h2r, $h2i + LOADDATAI inptr, #1<<$datalog, $h3r, $h3i + ADD inptr, inptr, #4<<$datalog + ELSE + ; load bit reversed + ADD x0r, inptr, $bitrev, LSL #$datalog + LOADDATAI x0r, $dinc, $h0r, $h0i + LOADDATAI x0r, $dinc, $h2r, $h2i + LOADDATAI x0r, $dinc, $h1r, $h1i + LOADDATAI x0r, $dinc, $h3r, $h3i + ENDIF + + IF "$prescale"="P" + LDR x0r, [sp, #8+32] ; NB we've stacked 8 extra regs! + MOV $h0r, $h0r, LSL x0r + MOV $h0i, $h0i, LSL x0r + MOV $h1r, $h1r, LSL x0r + MOV $h1i, $h1i, LSL x0r + MOV $h2r, $h2r, LSL x0r + MOV $h2i, $h2i, LSL x0r + MOV $h3r, $h3r, LSL x0r + MOV $h3i, $h3i, LSL x0r + ENDIF + + SHIFTDATA $h0r, $h0i + ; first stage (radix 2) butterflies + ADD $h0r, $h0r, $h1r $postldshift + ADD $h0i, $h0i, $h1i $postldshift + SUB $h1r, $h0r, $h1r $postldshift1 + SUB $h1i, $h0i, $h1i $postldshift1 + SUB $g3r, $h2r, $h3r + SUB $g3i, $h2i, $h3i + ADD $h2r, $h2r, $h3r + ADD $h2i, $h2i, $h3i + ; second stage (radix 2) butterflies + ADD $h0r, $h0r, $h2r $postldshift + ADD $h0i, $h0i, $h2i $postldshift + SUB $h2r, $h0r, $h2r $postldshift1 + SUB $h2i, $h0i, $h2i $postldshift1 + ADDi $h3r, $h1r, $g3i $postldshift + SUBi $h3i, $h1i, $g3r $postldshift + SUBi $h1r, $h1r, $g3i $postldshift + ADDi $h1i, $h1i, $g3r $postldshift + MEND + + END diff --git a/src/libs/webrtc/signal_processing_library/fft_ARM9E/fs_rad8_inverse.h b/src/libs/webrtc/signal_processing_library/fft_ARM9E/fs_rad8_inverse.h new file mode 100644 index 00000000..e7d451c5 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/fft_ARM9E/fs_rad8_inverse.h @@ -0,0 +1,236 @@ +; +; $Copyright: +; ---------------------------------------------------------------- +; This confidential and proprietary software may be used only as +; authorised by a licensing agreement from ARM Limited +; (C) COPYRIGHT 2000,2002 ARM Limited +; ALL RIGHTS RESERVED +; The entire notice above must be reproduced on all authorised +; copies and copies may only be made to the extent permitted +; by a licensing agreement from ARM Limited. +; ---------------------------------------------------------------- +; File: fs_rad8.h,v +; Revision: 1.5 +; ---------------------------------------------------------------- +; $ +; +; Optimised ARM assembler multi-radix FFT +; Please read the readme.txt before this file +; +; This file contains first stage, radix-8 code +; It bit reverses (assuming a power of 2 FFT) and performs the first stage +; + + MACRO + FS_RAD8 + SETSHIFT postldshift, 3*norm + SETSHIFT postmulshift, 3*norm+qshift + SETSHIFT postldshift1, 3*norm-1 + SETSHIFT postmulshift1, 3*norm+qshift-1 + IF "$prescale"<>"" + STMFD sp!, {dptr, N, r3} + ELSE + STMFD sp!, {dptr, N} + ENDIF + MOV bitrev, #0 + MOV dinc, N, LSL #($datalog-2) +12 ; first (radix 8) stage loop + ; do first two (radix 2) stages + FIRST_STAGE_RADIX8_ODD dinc, "dinc, LSR #1", bitrev + FIRST_STAGE_RADIX8_EVEN dinc, bitrev + ; third (radix 2) stage + LDMFD sp!, {x0r, x0i} + ADD $h0r, $h0r, x0r $postldshift ; standard add + ADD $h0i, $h0i, x0i $postldshift + SUB x0r, $h0r, x0r $postldshift1 + SUB x0i, $h0i, x0i $postldshift1 + STORE dptr, #1<<$datalog, $h0r, $h0i + LDMFD sp!, {x1r, x1i} + ADD $h1r, $h1r, x1r $postmulshift + ADD $h1i, $h1i, x1i $postmulshift + SUB x1r, $h1r, x1r $postmulshift1 + SUB x1i, $h1i, x1i $postmulshift1 + STORE dptr, #1<<$datalog, $h1r, $h1i + LDMFD sp!, {x2r, x2i} + SUBi $h2r, $h2r, x2r $postldshift ; note that x2r & x2i were + ADDi $h2i, $h2i, x2i $postldshift ; swapped above + ADDi x2r, $h2r, x2r $postldshift1 + SUBi x2i, $h2i, x2i $postldshift1 + STORE dptr, #1<<$datalog, $h2r, $h2i + LDMFD sp!, {x3r, x3i} + ADD $h3r, $h3r, x3r $postmulshift + ADD $h3i, $h3i, x3i $postmulshift + SUB x3r, $h3r, x3r $postmulshift1 + SUB x3i, $h3i, x3i $postmulshift1 + STORE dptr, #1<<$datalog, $h3r, $h3i + STORE dptr, #1<<$datalog, x0r, x0i + STORE dptr, #1<<$datalog, x1r, x1i + STORE dptr, #1<<$datalog, x2r, x2i + STORE dptr, #1<<$datalog, x3r, x3i + + IF reversed + SUBS dinc, dinc, #2<<$datalog + BGT %BT12 + ELSE + ; increment the count in a bit reverse manner + EOR bitrev, bitrev, dinc, LSR #($datalog-2+4) ; t0 = (N/8)>>1 + TST bitrev, dinc, LSR #($datalog-2+4) + BNE %BT12 + ; get here for 1/2 the loops - carry to next bit + EOR bitrev, bitrev, dinc, LSR #($datalog-2+5) + TST bitrev, dinc, LSR #($datalog-2+5) + BNE %BT12 + ; get here for 1/4 of the loops - stop unrolling + MOV t0, dinc, LSR #($datalog-2+6) +15 ; bit reverse increment loop + EOR bitrev, bitrev, t0 + TST bitrev, t0 + BNE %BT12 + ; get here for 1/8 of the loops (or when finished) + MOVS t0, t0, LSR #1 ; move down to next bit + BNE %BT15 ; carry on if we haven't run off the bottom + ENDIF + + IF "$prescale"<>"" + LDMFD sp!, {dptr, N, r3} + ELSE + LDMFD sp!, {dptr, N} + ENDIF + MOV count, N, LSR #3 ; start with N/8 blocks 8 each + MOV dinc, #8<<$datalog ; initial skip is 8 elements + MEND + + + + MACRO + FIRST_STAGE_RADIX8_ODD $dinc, $dinc_lsr1, $bitrev + + IF reversed + ; load non bit reversed + ADD t0, inptr, #4<<$datalog + LOADDATAI t0, #1<<$datalog, x0r, x0i + LOADDATAI t0, #1<<$datalog, x1r, x1i + LOADDATAI t0, #1<<$datalog, x2r, x2i + LOADDATAI t0, #1<<$datalog, x3r, x3i + ELSE + ; load data elements 1,3,5,7 into register order 1,5,3,7 + ADD t0, inptr, $bitrev, LSL #$datalog + ADD t0, t0, $dinc_lsr1 ; load in odd terms first + LOADDATAI t0, $dinc, x0r, x0i + LOADDATAI t0, $dinc, x2r, x2i + LOADDATAI t0, $dinc, x1r, x1i + LOADDATAI t0, $dinc, x3r, x3i + ENDIF + + IF "$prescale"="P" + LDR t0, [sp, #8] + MOV x0r, x0r, LSL t0 + MOV x0i, x0i, LSL t0 + MOV x1r, x1r, LSL t0 + MOV x1i, x1i, LSL t0 + MOV x2r, x2r, LSL t0 + MOV x2i, x2i, LSL t0 + MOV x3r, x3r, LSL t0 + MOV x3i, x3i, LSL t0 + ENDIF + + SETREG h2, x3r, x3i + SETREG h3, t0, t1 + ; first stage (radix 2) butterflies + ADD x0r, x0r, x1r + ADD x0i, x0i, x1i + SUB x1r, x0r, x1r, LSL #1 + SUB x1i, x0i, x1i, LSL #1 + SUB $h3r, x2r, x3r + SUB $h3i, x2i, x3i + ADD $h2r, x2r, x3r + ADD $h2i, x2i, x3i + ; second stage (radix 2) butterflies + SUB x2i, x0r, $h2r ; swap real and imag here + SUB x2r, x0i, $h2i ; for use later + ADD x0r, x0r, $h2r + ADD x0i, x0i, $h2i + ADDi x3r, x1r, $h3i + SUBi x3i, x1i, $h3r + SUBi x1r, x1r, $h3i + ADDi x1i, x1i, $h3r + ; do the 1/sqrt(2) (+/-1 +/- i) twiddles for third stage + LCLS tempname +tempname SETS "R_rad8" + IMPORT t_$qname$tempname + LDR t1, =t_$qname$tempname +; IMPORT t_$qname.R_rad8 +; LDR t1, =t_$qname.R_rad8 + LOADCOEFR t1, t1 + + STMFD sp!, {dinc} ;;; FIXME!!! + + SUB t0, x1r, x1i ; real part when * (1+i) + SCALE x1r, t0, t1, dinc ; scale by 1/sqrt(2) + ADD t0, t0, x1i, LSL #1 ; imag part when * (1+i) + SCALE x1i, t0, t1, dinc ; scale by 1/sqrt(2) + SUB t0, x3r, x3i ; imag part when * (-1+i) + SCALE x3i, t0, t1, dinc ; scale by 1/sqrt(2) + SUB t0, t0, x3r, LSL #1 ; real part when * (-1+i) + SCALE x3r, t0, t1, dinc ; scale by 1/sqrt(2) + + LDMFD sp!, {dinc} ;;; FIXME!!! + STMFD sp!, {x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i} + MEND + + MACRO + FIRST_STAGE_RADIX8_EVEN $dinc, $bitrev + ; load elements 0,2,4,6 into register order 0,4,2,6 + SETREGS h, x1r, x1i, x2r, x2i, x3r, x3i, t0, t1 + SETREG g3, x0r, x0i + + IF reversed + ; load normally + LOADDATAI inptr, #1<<$datalog, $h0r, $h0i + LOADDATAI inptr, #1<<$datalog, $h1r, $h1i + LOADDATAI inptr, #1<<$datalog, $h2r, $h2i + LOADDATAI inptr, #1<<$datalog, $h3r, $h3i + ADD inptr, inptr, #4<<$datalog + ELSE + ; load bit reversed + ADD x0r, inptr, $bitrev, LSL #$datalog + LOADDATAI x0r, $dinc, $h0r, $h0i + LOADDATAI x0r, $dinc, $h2r, $h2i + LOADDATAI x0r, $dinc, $h1r, $h1i + LOADDATAI x0r, $dinc, $h3r, $h3i + ENDIF + + IF "$prescale"="P" + LDR x0r, [sp, #8+32] ; NB we've stacked 8 extra regs! + MOV $h0r, $h0r, LSL x0r + MOV $h0i, $h0i, LSL x0r + MOV $h1r, $h1r, LSL x0r + MOV $h1i, $h1i, LSL x0r + MOV $h2r, $h2r, LSL x0r + MOV $h2i, $h2i, LSL x0r + MOV $h3r, $h3r, LSL x0r + MOV $h3i, $h3i, LSL x0r + ENDIF + + SHIFTDATA $h0r, $h0i + ; first stage (radix 2) butterflies + ADD $h0r, $h0r, $h1r $postldshift + ADD $h0i, $h0i, $h1i $postldshift + SUB $h1r, $h0r, $h1r $postldshift1 + SUB $h1i, $h0i, $h1i $postldshift1 + SUB $g3r, $h2r, $h3r + SUB $g3i, $h2i, $h3i + ADD $h2r, $h2r, $h3r + ADD $h2i, $h2i, $h3i + ; second stage (radix 2) butterflies + ADD $h0r, $h0r, $h2r $postldshift + ADD $h0i, $h0i, $h2i $postldshift + SUB $h2r, $h0r, $h2r $postldshift1 + SUB $h2i, $h0i, $h2i $postldshift1 + ADDi $h3r, $h1r, $g3i $postldshift + SUBi $h3i, $h1i, $g3r $postldshift + SUBi $h1r, $h1r, $g3i $postldshift + ADDi $h1i, $h1i, $g3r $postldshift + MEND + + END diff --git a/src/libs/webrtc/signal_processing_library/fft_ARM9E/gs_rad4.h b/src/libs/webrtc/signal_processing_library/fft_ARM9E/gs_rad4.h new file mode 100644 index 00000000..ec392ea6 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/fft_ARM9E/gs_rad4.h @@ -0,0 +1,111 @@ +; +; $Copyright: +; ---------------------------------------------------------------- +; This confidential and proprietary software may be used only as +; authorised by a licensing agreement from ARM Limited +; (C) COPYRIGHT 2000,2002 ARM Limited +; ALL RIGHTS RESERVED +; The entire notice above must be reproduced on all authorised +; copies and copies may only be made to the extent permitted +; by a licensing agreement from ARM Limited. +; ---------------------------------------------------------------- +; File: gs_rad4.h,v +; Revision: 1.8 +; ---------------------------------------------------------------- +; $ +; +; Optimised ARM assembler multi-radix FFT +; Please read the readme.txt before this file +; +; This file contains the general stage, radix 4 macro + + MACRO + GS_RAD4 + SETSHIFT postldshift, 2*norm + SETSHIFT postmulshift, 2*norm+qshift + ; dinc contains the number of bytes between the values to read + ; for the radix 4 bufferfly + ; Thus: + ; dinc*4 = number of bytes between the blocks at this level + ; dinc>>datalog = number of elements in each block at this level + MOV count, count, LSR #2 ; a quarter the blocks per stage + STMFD sp!, {dptr, count} + ADD t0, dinc, dinc, LSL #1 ; 3*dinc + ADD dptr, dptr, t0 ; move to last of 4 butterflys + SUB count, count, #1<<16 ; prepare top half of counter +12 ; block loop + ; set top half of counter to (elements/block - 1) + ADD count, count, dinc, LSL #(16-$datalog) +15 ; butterfly loop + IF (architecture>=5):LAND:(qshift<16) + ; E extensions available (21 cycles) + ; But needs a different table format + LDMIA cptr!, {x0i, x1i, x2i} + LDR x2r, [dptr], -dinc + LDR x1r, [dptr], -dinc + LDR x0r, [dptr], -dinc + TWIDDLE_E x3r, x3i, x2i, t0, x2r + TWIDDLE_E x2r, x2i, x1i, t0, x1r + TWIDDLE_E x1r, x1i, x0i, t0, x0r + ELSE + ; load next three twiddle factors (66 @ 4 cycles/mul) + LOADCOEFS cptr, x1r, x1i, x2r, x2i, x3r, x3i + ; load data in reversed order & perform twiddles + LOADDATA dptr, -dinc, x0r, x0i + TWIDDLE x0r, x0i, x3r, x3i, t0, t1 + LOADDATA dptr, -dinc, x0r, x0i + TWIDDLE x0r, x0i, x2r, x2i, t0, t1 + LOADDATA dptr, -dinc, x0r, x0i + TWIDDLE x0r, x0i, x1r, x1i, t0, t1 + ENDIF + LOADDATAZ dptr, x0r, x0i + SHIFTDATA x0r, x0i + ; now calculate the h's + ; h[0,k] = g[0,k] + g[2,k] + ; h[1,k] = g[0,k] - g[2,k] + ; h[2,k] = g[1,k] + g[3,k] + ; h[3,k] = g[1,k] - g[3,k] + SETREGS h,t0,t1,x0r,x0i,x1r,x1i,x2r,x2i + ADD $h0r, x0r, x1r $postmulshift + ADD $h0i, x0i, x1i $postmulshift + SUB $h1r, x0r, x1r $postmulshift + SUB $h1i, x0i, x1i $postmulshift + ADD $h2r, x2r, x3r + ADD $h2i, x2i, x3i + SUB $h3r, x2r, x3r + SUB $h3i, x2i, x3i + ; now calculate the y's and store results + ; y[0*N/4+k] = h[0,k] + h[2,k] + ; y[1*N/4+k] = h[1,k] + j*h[3,k] + ; y[2*N/4+k] = h[0,k] - h[2,k] + ; y[3*N/4+k] = h[1,k] - j*h[3,k] + SETREG y0,x3r,x3i + ADD $y0r, $h0r, $h2r $postmulshift + ADD $y0i, $h0i, $h2i $postmulshift + STORE dptr, dinc, $y0r, $y0i + SUBi $y0r, $h1r, $h3i $postmulshift + ADDi $y0i, $h1i, $h3r $postmulshift + STORE dptr, dinc, $y0r, $y0i + SUB $y0r, $h0r, $h2r $postmulshift + SUB $y0i, $h0i, $h2i $postmulshift + STORE dptr, dinc, $y0r, $y0i + ADDi $y0r, $h1r, $h3i $postmulshift + SUBi $y0i, $h1i, $h3r $postmulshift + STOREP dptr, $y0r, $y0i + ; continue butterfly loop + SUBS count, count, #1<<16 + BGE %BT15 + ; decrement counts for block loop + ADD t0, dinc, dinc, LSL #1 ; dinc * 3 + ADD dptr, dptr, t0 ; move onto next block + SUB cptr, cptr, t0 $cdshift ; move back to coeficients start + SUB count, count, #1 ; done one more block + MOVS t1, count, LSL #16 + BNE %BT12 ; still more blocks to do + ; finished stage + ADD cptr, cptr, t0 $cdshift ; move onto next stage coeficients + LDMFD sp!, {dptr, count} + MOV dinc, dinc, LSL #2 ; four times the entries per block + MEND + + END diff --git a/src/libs/webrtc/signal_processing_library/fft_ARM9E/readme.txt b/src/libs/webrtc/signal_processing_library/fft_ARM9E/readme.txt new file mode 100644 index 00000000..a4929ef4 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/fft_ARM9E/readme.txt @@ -0,0 +1,91 @@ +# $Copyright: +# ---------------------------------------------------------------- +# This confidential and proprietary software may be used only as +# authorised by a licensing agreement from ARM Limited +# (C) COPYRIGHT 2000,2002 ARM Limited +# ALL RIGHTS RESERVED +# The entire notice above must be reproduced on all authorised +# copies and copies may only be made to the extent permitted +# by a licensing agreement from ARM Limited. +# ---------------------------------------------------------------- +# File: readme.txt,v +# Revision: 1.4 +# ---------------------------------------------------------------- +# $ + + + +!!! To fully understand the FFT/ARM9E/WIN_MOB implementation in SPLIB, +!!! you have to refer to the full set of files in RVDS' package: +!!! C:\Program Files\ARM\RVDS\Examples\3.0\79\windows\fft_v5te. + + + + ARM Assembler FFT implementation + ================================ + + Overview + ======== + +This implementation has been restructured to allow FFT's of varying radix +rather than the fixed radix-2 or radix-4 versions allowed earlier. The +implementation of an optimised assembler FFT of a given size (N points) +consists of chaining together a sequence of stages 1,2,3,...,k such that the +j'th stage has radix Rj and: + + N = R1*R2*R3*...*Rk + +For the ARM implementations we keep the size of the Rj's decreasing with +increasing j, EXCEPT that if there are any non power of 2 factors (ie, odd +prime factors) then these come before all the power of 2 factors. + +For example: + + N=64 would be implemented as stages: + radix 4, radix 4, radix 4 + + N=128 would be implemented as stages: + radix 8, radix 4, radix 4 + OR + radix 4, radix 4, radix 4, radix 2 + + N=192 would be implemented as stages: + radix 3, radix 4, radix 4, radix 4 + +The bitreversal is usally combined with the first stage where possible. + + + Structure + ========= + +The actual FFT routine is built out of a hierarchy of macros. All stage +macros and filenames are one of: + + fs_rad<n> => the macro implements a radix <n> First Stage (usually + including the bit reversal) + + gs_rad<n> => the macro implements a radix <n> General Stage (any + stage except the first - includes the twiddle operations) + + ls_rad<n> => the macro implements a radix <n> Last Stage (this macro + is like the gs_rad<n> version but is optimised for + efficiency in the last stage) + + ls_ztor => this macro converts the output of a complex FFT to + be the first half of the output of a real FFT of + double the number of input points. + +Other files are: + + fft_mac.h => Macro's and register definitions shared by all radix + implementations + + fft_main.h => Main FFT macros drawing together the stage macros + to produce a complete FFT + + + Interfaces + ========== + +The register interfaces for the different type of stage macros are described +at the start of fft_mac.h diff --git a/src/libs/webrtc/signal_processing_library/fft_ARM9E/t_01024_8.c b/src/libs/webrtc/signal_processing_library/fft_ARM9E/t_01024_8.c new file mode 100644 index 00000000..17efd07c --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/fft_ARM9E/t_01024_8.c @@ -0,0 +1,695 @@ +/* + * Copyright (C) ARM Limited 1998-2002. All rights reserved. + * + * t_01024_8.c + * + */ + +extern const int s_Q14S_8; +const int s_Q14S_8 = 1024; +extern const unsigned short t_Q14S_8[2032]; +const unsigned short t_Q14S_8[2032] = { + 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , + 0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e , + 0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 , + 0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 , + 0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 , + 0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c , + 0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 , + 0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 , + 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , + 0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 , + 0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 , + 0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d , + 0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e , + 0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb , + 0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 , + 0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 , + 0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 , + 0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 , + 0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 , + 0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec , + 0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 , + 0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 , + 0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 , + 0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 , + 0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 , + 0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 , + 0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b , + 0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 , + 0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c , + 0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 , + 0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba , + 0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 , + 0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 , + 0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 , + 0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 , + 0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 , + 0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 , + 0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 , + 0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 , + 0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 , + 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , + 0x3e69,0x0192 ,0x3f36,0x00c9 ,0x3d9a,0x025b , + 0x3cc8,0x0324 ,0x3e69,0x0192 ,0x3b1e,0x04b5 , + 0x3b1e,0x04b5 ,0x3d9a,0x025b ,0x388e,0x070e , + 0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 , + 0x37af,0x07d6 ,0x3bf4,0x03ed ,0x3334,0x0bb7 , + 0x35eb,0x0964 ,0x3b1e,0x04b5 ,0x306c,0x0e06 , + 0x341e,0x0af1 ,0x3a46,0x057e ,0x2d93,0x1050 , + 0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 , + 0x306c,0x0e06 ,0x388e,0x070e ,0x27b3,0x14d2 , + 0x2e88,0x0f8d ,0x37af,0x07d6 ,0x24ae,0x1709 , + 0x2c9d,0x1112 ,0x36ce,0x089d ,0x219c,0x1937 , + 0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d , + 0x28b2,0x1413 ,0x3505,0x0a2b ,0x1b56,0x1d79 , + 0x26b3,0x1590 ,0x341e,0x0af1 ,0x1824,0x1f8c , + 0x24ae,0x1709 ,0x3334,0x0bb7 ,0x14ea,0x2193 , + 0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e , + 0x2093,0x19ef ,0x315b,0x0d41 ,0x0e61,0x257e , + 0x1e7e,0x1b5d ,0x306c,0x0e06 ,0x0b14,0x2760 , + 0x1c64,0x1cc6 ,0x2f7b,0x0eca ,0x07c4,0x2935 , + 0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb , + 0x1824,0x1f8c ,0x2d93,0x1050 ,0x011c,0x2cb2 , + 0x15fe,0x20e7 ,0x2c9d,0x1112 ,0xfdc7,0x2e5a , + 0x13d5,0x223d ,0x2ba4,0x11d3 ,0xfa73,0x2ff2 , + 0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 , + 0x0f79,0x24da ,0x29af,0x1354 ,0xf3d2,0x32ef , + 0x0d48,0x2620 ,0x28b2,0x1413 ,0xf087,0x3453 , + 0x0b14,0x2760 ,0x27b3,0x14d2 ,0xed41,0x35a5 , + 0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 , + 0x06a9,0x29ce ,0x25b1,0x164c ,0xe6cb,0x3812 , + 0x0471,0x2afb ,0x24ae,0x1709 ,0xe39c,0x392b , + 0x0239,0x2c21 ,0x23a9,0x17c4 ,0xe077,0x3a30 , + 0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 , + 0xfdc7,0x2e5a ,0x219c,0x1937 ,0xda4f,0x3bfd , + 0xfb8f,0x2f6c ,0x2093,0x19ef ,0xd74e,0x3cc5 , + 0xf957,0x3076 ,0x1f89,0x1aa7 ,0xd45c,0x3d78 , + 0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 , + 0xf4ec,0x3274 ,0x1d72,0x1c12 ,0xcea5,0x3e9d , + 0xf2b8,0x3368 ,0x1c64,0x1cc6 ,0xcbe2,0x3f0f , + 0xf087,0x3453 ,0x1b56,0x1d79 ,0xc932,0x3f6b , + 0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 , + 0xec2b,0x3612 ,0x1935,0x1edc ,0xc40c,0x3fe1 , + 0xea02,0x36e5 ,0x1824,0x1f8c ,0xc197,0x3ffb , + 0xe7dc,0x37b0 ,0x1711,0x203a ,0xbf38,0x3fff , + 0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec , + 0xe39c,0x392b ,0x14ea,0x2193 ,0xbabf,0x3fc4 , + 0xe182,0x39db ,0x13d5,0x223d ,0xb8a6,0x3f85 , + 0xdf6d,0x3a82 ,0x12bf,0x22e7 ,0xb6a5,0x3f30 , + 0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 , + 0xdb52,0x3bb6 ,0x1091,0x2435 ,0xb2f2,0x3e45 , + 0xd94d,0x3c42 ,0x0f79,0x24da ,0xb140,0x3daf , + 0xd74e,0x3cc5 ,0x0e61,0x257e ,0xafa9,0x3d03 , + 0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 , + 0xd363,0x3daf ,0x0c2e,0x26c1 ,0xacd0,0x3b6d , + 0xd178,0x3e15 ,0x0b14,0x2760 ,0xab8e,0x3a82 , + 0xcf94,0x3e72 ,0x09fa,0x27fe ,0xaa6a,0x3984 , + 0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 , + 0xcbe2,0x3f0f ,0x07c4,0x2935 ,0xa87b,0x374b , + 0xca15,0x3f4f ,0x06a9,0x29ce ,0xa7b1,0x3612 , + 0xc851,0x3f85 ,0x058d,0x2a65 ,0xa705,0x34c6 , + 0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 , + 0xc4e2,0x3fd4 ,0x0355,0x2b8f ,0xa60b,0x31f8 , + 0xc338,0x3fec ,0x0239,0x2c21 ,0xa5bc,0x3076 , + 0xc197,0x3ffb ,0x011c,0x2cb2 ,0xa58d,0x2ee4 , + 0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 , + 0xbe73,0x3ffb ,0xfee4,0x2dcf ,0xa58d,0x2b8f , + 0xbcf0,0x3fec ,0xfdc7,0x2e5a ,0xa5bc,0x29ce , + 0xbb77,0x3fd4 ,0xfcab,0x2ee4 ,0xa60b,0x27fe , + 0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 , + 0xb8a6,0x3f85 ,0xfa73,0x2ff2 ,0xa705,0x2435 , + 0xb74d,0x3f4f ,0xf957,0x3076 ,0xa7b1,0x223d , + 0xb600,0x3f0f ,0xf83c,0x30f9 ,0xa87b,0x203a , + 0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b , + 0xb388,0x3e72 ,0xf606,0x31f8 ,0xaa6a,0x1c12 , + 0xb25e,0x3e15 ,0xf4ec,0x3274 ,0xab8e,0x19ef , + 0xb140,0x3daf ,0xf3d2,0x32ef ,0xacd0,0x17c4 , + 0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 , + 0xaf28,0x3cc5 ,0xf19f,0x33df ,0xafa9,0x1354 , + 0xae2e,0x3c42 ,0xf087,0x3453 ,0xb140,0x1112 , + 0xad41,0x3bb6 ,0xef6f,0x34c6 ,0xb2f2,0x0eca , + 0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c , + 0xab8e,0x3a82 ,0xed41,0x35a5 ,0xb6a5,0x0a2b , + 0xaac8,0x39db ,0xec2b,0x3612 ,0xb8a6,0x07d6 , + 0xaa0f,0x392b ,0xeb16,0x367d ,0xbabf,0x057e , + 0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 , + 0xa8c5,0x37b0 ,0xe8ef,0x374b ,0xbf38,0x00c9 , + 0xa834,0x36e5 ,0xe7dc,0x37b0 ,0xc197,0xfe6e , + 0xa7b1,0x3612 ,0xe6cb,0x3812 ,0xc40c,0xfc13 , + 0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba , + 0xa6d3,0x3453 ,0xe4aa,0x38cf ,0xc932,0xf763 , + 0xa678,0x3368 ,0xe39c,0x392b ,0xcbe2,0xf50f , + 0xa62c,0x3274 ,0xe28e,0x3984 ,0xcea5,0xf2bf , + 0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 , + 0xa5bc,0x3076 ,0xe077,0x3a30 ,0xd45c,0xee2d , + 0xa599,0x2f6c ,0xdf6d,0x3a82 ,0xd74e,0xebed , + 0xa585,0x2e5a ,0xde64,0x3ad3 ,0xda4f,0xe9b4 , + 0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 , + 0xa585,0x2c21 ,0xdc57,0x3b6d ,0xe077,0xe559 , + 0xa599,0x2afb ,0xdb52,0x3bb6 ,0xe39c,0xe33a , + 0xa5bc,0x29ce ,0xda4f,0x3bfd ,0xe6cb,0xe124 , + 0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 , + 0xa62c,0x2760 ,0xd84d,0x3c85 ,0xed41,0xdd19 , + 0xa678,0x2620 ,0xd74e,0x3cc5 ,0xf087,0xdb26 , + 0xa6d3,0x24da ,0xd651,0x3d03 ,0xf3d2,0xd93f , + 0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 , + 0xa7b1,0x223d ,0xd45c,0x3d78 ,0xfa73,0xd59b , + 0xa834,0x20e7 ,0xd363,0x3daf ,0xfdc7,0xd3df , + 0xa8c5,0x1f8c ,0xd26d,0x3de3 ,0x011c,0xd231 , + 0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 , + 0xaa0f,0x1cc6 ,0xd085,0x3e45 ,0x07c4,0xcf07 , + 0xaac8,0x1b5d ,0xcf94,0x3e72 ,0x0b14,0xcd8c , + 0xab8e,0x19ef ,0xcea5,0x3e9d ,0x0e61,0xcc21 , + 0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 , + 0xad41,0x1709 ,0xcccc,0x3eeb ,0x14ea,0xc983 , + 0xae2e,0x1590 ,0xcbe2,0x3f0f ,0x1824,0xc850 , + 0xaf28,0x1413 ,0xcafb,0x3f30 ,0x1b56,0xc731 , + 0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 , + 0xb140,0x1112 ,0xc932,0x3f6b ,0x219c,0xc52d , + 0xb25e,0x0f8d ,0xc851,0x3f85 ,0x24ae,0xc44a , + 0xb388,0x0e06 ,0xc772,0x3f9c ,0x27b3,0xc37b , + 0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 , + 0xb600,0x0af1 ,0xc5ba,0x3fc4 ,0x2d93,0xc21d , + 0xb74d,0x0964 ,0xc4e2,0x3fd4 ,0x306c,0xc18e , + 0xb8a6,0x07d6 ,0xc40c,0x3fe1 ,0x3334,0xc115 , + 0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 , + 0xbb77,0x04b5 ,0xc266,0x3ff5 ,0x388e,0xc064 , + 0xbcf0,0x0324 ,0xc197,0x3ffb ,0x3b1e,0xc02c , + 0xbe73,0x0192 ,0xc0ca,0x3fff ,0x3d9a,0xc00b , + 0x4000,0x0000 ,0x3f9b,0x0065 ,0x3f36,0x00c9 , + 0x3ed0,0x012e ,0x3e69,0x0192 ,0x3e02,0x01f7 , + 0x3d9a,0x025b ,0x3d31,0x02c0 ,0x3cc8,0x0324 , + 0x3c5f,0x0388 ,0x3bf4,0x03ed ,0x3b8a,0x0451 , + 0x3b1e,0x04b5 ,0x3ab2,0x051a ,0x3a46,0x057e , + 0x39d9,0x05e2 ,0x396b,0x0646 ,0x38fd,0x06aa , + 0x388e,0x070e ,0x381f,0x0772 ,0x37af,0x07d6 , + 0x373f,0x0839 ,0x36ce,0x089d ,0x365d,0x0901 , + 0x35eb,0x0964 ,0x3578,0x09c7 ,0x3505,0x0a2b , + 0x3492,0x0a8e ,0x341e,0x0af1 ,0x33a9,0x0b54 , + 0x3334,0x0bb7 ,0x32bf,0x0c1a ,0x3249,0x0c7c , + 0x31d2,0x0cdf ,0x315b,0x0d41 ,0x30e4,0x0da4 , + 0x306c,0x0e06 ,0x2ff4,0x0e68 ,0x2f7b,0x0eca , + 0x2f02,0x0f2b ,0x2e88,0x0f8d ,0x2e0e,0x0fee , + 0x2d93,0x1050 ,0x2d18,0x10b1 ,0x2c9d,0x1112 , + 0x2c21,0x1173 ,0x2ba4,0x11d3 ,0x2b28,0x1234 , + 0x2aaa,0x1294 ,0x2a2d,0x12f4 ,0x29af,0x1354 , + 0x2931,0x13b4 ,0x28b2,0x1413 ,0x2833,0x1473 , + 0x27b3,0x14d2 ,0x2733,0x1531 ,0x26b3,0x1590 , + 0x2632,0x15ee ,0x25b1,0x164c ,0x252f,0x16ab , + 0x24ae,0x1709 ,0x242b,0x1766 ,0x23a9,0x17c4 , + 0x2326,0x1821 ,0x22a3,0x187e ,0x221f,0x18db , + 0x219c,0x1937 ,0x2117,0x1993 ,0x2093,0x19ef , + 0x200e,0x1a4b ,0x1f89,0x1aa7 ,0x1f04,0x1b02 , + 0x1e7e,0x1b5d ,0x1df8,0x1bb8 ,0x1d72,0x1c12 , + 0x1ceb,0x1c6c ,0x1c64,0x1cc6 ,0x1bdd,0x1d20 , + 0x1b56,0x1d79 ,0x1ace,0x1dd3 ,0x1a46,0x1e2b , + 0x19be,0x1e84 ,0x1935,0x1edc ,0x18ad,0x1f34 , + 0x1824,0x1f8c ,0x179b,0x1fe3 ,0x1711,0x203a , + 0x1688,0x2091 ,0x15fe,0x20e7 ,0x1574,0x213d , + 0x14ea,0x2193 ,0x145f,0x21e8 ,0x13d5,0x223d , + 0x134a,0x2292 ,0x12bf,0x22e7 ,0x1234,0x233b , + 0x11a8,0x238e ,0x111d,0x23e2 ,0x1091,0x2435 , + 0x1005,0x2488 ,0x0f79,0x24da ,0x0eed,0x252c , + 0x0e61,0x257e ,0x0dd4,0x25cf ,0x0d48,0x2620 , + 0x0cbb,0x2671 ,0x0c2e,0x26c1 ,0x0ba1,0x2711 , + 0x0b14,0x2760 ,0x0a87,0x27af ,0x09fa,0x27fe , + 0x096d,0x284c ,0x08df,0x289a ,0x0852,0x28e7 , + 0x07c4,0x2935 ,0x0736,0x2981 ,0x06a9,0x29ce , + 0x061b,0x2a1a ,0x058d,0x2a65 ,0x04ff,0x2ab0 , + 0x0471,0x2afb ,0x03e3,0x2b45 ,0x0355,0x2b8f , + 0x02c7,0x2bd8 ,0x0239,0x2c21 ,0x01aa,0x2c6a , + 0x011c,0x2cb2 ,0x008e,0x2cfa ,0x0000,0x2d41 , + 0xff72,0x2d88 ,0xfee4,0x2dcf ,0xfe56,0x2e15 , + 0xfdc7,0x2e5a ,0xfd39,0x2e9f ,0xfcab,0x2ee4 , + 0xfc1d,0x2f28 ,0xfb8f,0x2f6c ,0xfb01,0x2faf , + 0xfa73,0x2ff2 ,0xf9e5,0x3034 ,0xf957,0x3076 , + 0xf8ca,0x30b8 ,0xf83c,0x30f9 ,0xf7ae,0x3139 , + 0xf721,0x3179 ,0xf693,0x31b9 ,0xf606,0x31f8 , + 0xf579,0x3236 ,0xf4ec,0x3274 ,0xf45f,0x32b2 , + 0xf3d2,0x32ef ,0xf345,0x332c ,0xf2b8,0x3368 , + 0xf22c,0x33a3 ,0xf19f,0x33df ,0xf113,0x3419 , + 0xf087,0x3453 ,0xeffb,0x348d ,0xef6f,0x34c6 , + 0xeee3,0x34ff ,0xee58,0x3537 ,0xedcc,0x356e , + 0xed41,0x35a5 ,0xecb6,0x35dc ,0xec2b,0x3612 , + 0xeba1,0x3648 ,0xeb16,0x367d ,0xea8c,0x36b1 , + 0xea02,0x36e5 ,0xe978,0x3718 ,0xe8ef,0x374b , + 0xe865,0x377e ,0xe7dc,0x37b0 ,0xe753,0x37e1 , + 0xe6cb,0x3812 ,0xe642,0x3842 ,0xe5ba,0x3871 , + 0xe532,0x38a1 ,0xe4aa,0x38cf ,0xe423,0x38fd , + 0xe39c,0x392b ,0xe315,0x3958 ,0xe28e,0x3984 , + 0xe208,0x39b0 ,0xe182,0x39db ,0xe0fc,0x3a06 , + 0xe077,0x3a30 ,0xdff2,0x3a59 ,0xdf6d,0x3a82 , + 0xdee9,0x3aab ,0xde64,0x3ad3 ,0xdde1,0x3afa , + 0xdd5d,0x3b21 ,0xdcda,0x3b47 ,0xdc57,0x3b6d , + 0xdbd5,0x3b92 ,0xdb52,0x3bb6 ,0xdad1,0x3bda , + 0xda4f,0x3bfd ,0xd9ce,0x3c20 ,0xd94d,0x3c42 , + 0xd8cd,0x3c64 ,0xd84d,0x3c85 ,0xd7cd,0x3ca5 , + 0xd74e,0x3cc5 ,0xd6cf,0x3ce4 ,0xd651,0x3d03 , + 0xd5d3,0x3d21 ,0xd556,0x3d3f ,0xd4d8,0x3d5b , + 0xd45c,0x3d78 ,0xd3df,0x3d93 ,0xd363,0x3daf , + 0xd2e8,0x3dc9 ,0xd26d,0x3de3 ,0xd1f2,0x3dfc , + 0xd178,0x3e15 ,0xd0fe,0x3e2d ,0xd085,0x3e45 , + 0xd00c,0x3e5c ,0xcf94,0x3e72 ,0xcf1c,0x3e88 , + 0xcea5,0x3e9d ,0xce2e,0x3eb1 ,0xcdb7,0x3ec5 , + 0xcd41,0x3ed8 ,0xcccc,0x3eeb ,0xcc57,0x3efd , + 0xcbe2,0x3f0f ,0xcb6e,0x3f20 ,0xcafb,0x3f30 , + 0xca88,0x3f40 ,0xca15,0x3f4f ,0xc9a3,0x3f5d , + 0xc932,0x3f6b ,0xc8c1,0x3f78 ,0xc851,0x3f85 , + 0xc7e1,0x3f91 ,0xc772,0x3f9c ,0xc703,0x3fa7 , + 0xc695,0x3fb1 ,0xc627,0x3fbb ,0xc5ba,0x3fc4 , + 0xc54e,0x3fcc ,0xc4e2,0x3fd4 ,0xc476,0x3fdb , + 0xc40c,0x3fe1 ,0xc3a1,0x3fe7 ,0xc338,0x3fec , + 0xc2cf,0x3ff1 ,0xc266,0x3ff5 ,0xc1fe,0x3ff8 , + 0xc197,0x3ffb ,0xc130,0x3ffd ,0xc0ca,0x3fff , + 0xc065,0x4000 ,0xc000,0x4000 ,0xbf9c,0x4000 , + 0xbf38,0x3fff ,0xbed5,0x3ffd ,0xbe73,0x3ffb , + 0xbe11,0x3ff8 ,0xbdb0,0x3ff5 ,0xbd50,0x3ff1 , + 0xbcf0,0x3fec ,0xbc91,0x3fe7 ,0xbc32,0x3fe1 , + 0xbbd4,0x3fdb ,0xbb77,0x3fd4 ,0xbb1b,0x3fcc , + 0xbabf,0x3fc4 ,0xba64,0x3fbb ,0xba09,0x3fb1 , + 0xb9af,0x3fa7 ,0xb956,0x3f9c ,0xb8fd,0x3f91 , + 0xb8a6,0x3f85 ,0xb84f,0x3f78 ,0xb7f8,0x3f6b , + 0xb7a2,0x3f5d ,0xb74d,0x3f4f ,0xb6f9,0x3f40 , + 0xb6a5,0x3f30 ,0xb652,0x3f20 ,0xb600,0x3f0f , + 0xb5af,0x3efd ,0xb55e,0x3eeb ,0xb50e,0x3ed8 , + 0xb4be,0x3ec5 ,0xb470,0x3eb1 ,0xb422,0x3e9d , + 0xb3d5,0x3e88 ,0xb388,0x3e72 ,0xb33d,0x3e5c , + 0xb2f2,0x3e45 ,0xb2a7,0x3e2d ,0xb25e,0x3e15 , + 0xb215,0x3dfc ,0xb1cd,0x3de3 ,0xb186,0x3dc9 , + 0xb140,0x3daf ,0xb0fa,0x3d93 ,0xb0b5,0x3d78 , + 0xb071,0x3d5b ,0xb02d,0x3d3f ,0xafeb,0x3d21 , + 0xafa9,0x3d03 ,0xaf68,0x3ce4 ,0xaf28,0x3cc5 , + 0xaee8,0x3ca5 ,0xaea9,0x3c85 ,0xae6b,0x3c64 , + 0xae2e,0x3c42 ,0xadf2,0x3c20 ,0xadb6,0x3bfd , + 0xad7b,0x3bda ,0xad41,0x3bb6 ,0xad08,0x3b92 , + 0xacd0,0x3b6d ,0xac98,0x3b47 ,0xac61,0x3b21 , + 0xac2b,0x3afa ,0xabf6,0x3ad3 ,0xabc2,0x3aab , + 0xab8e,0x3a82 ,0xab5b,0x3a59 ,0xab29,0x3a30 , + 0xaaf8,0x3a06 ,0xaac8,0x39db ,0xaa98,0x39b0 , + 0xaa6a,0x3984 ,0xaa3c,0x3958 ,0xaa0f,0x392b , + 0xa9e3,0x38fd ,0xa9b7,0x38cf ,0xa98d,0x38a1 , + 0xa963,0x3871 ,0xa93a,0x3842 ,0xa912,0x3812 , + 0xa8eb,0x37e1 ,0xa8c5,0x37b0 ,0xa89f,0x377e , + 0xa87b,0x374b ,0xa857,0x3718 ,0xa834,0x36e5 , + 0xa812,0x36b1 ,0xa7f1,0x367d ,0xa7d0,0x3648 , + 0xa7b1,0x3612 ,0xa792,0x35dc ,0xa774,0x35a5 , + 0xa757,0x356e ,0xa73b,0x3537 ,0xa71f,0x34ff , + 0xa705,0x34c6 ,0xa6eb,0x348d ,0xa6d3,0x3453 , + 0xa6bb,0x3419 ,0xa6a4,0x33df ,0xa68e,0x33a3 , + 0xa678,0x3368 ,0xa664,0x332c ,0xa650,0x32ef , + 0xa63e,0x32b2 ,0xa62c,0x3274 ,0xa61b,0x3236 , + 0xa60b,0x31f8 ,0xa5fb,0x31b9 ,0xa5ed,0x3179 , + 0xa5e0,0x3139 ,0xa5d3,0x30f9 ,0xa5c7,0x30b8 , + 0xa5bc,0x3076 ,0xa5b2,0x3034 ,0xa5a9,0x2ff2 , + 0xa5a1,0x2faf ,0xa599,0x2f6c ,0xa593,0x2f28 , + 0xa58d,0x2ee4 ,0xa588,0x2e9f ,0xa585,0x2e5a , + 0xa581,0x2e15 ,0xa57f,0x2dcf ,0xa57e,0x2d88 , + 0xa57e,0x2d41 ,0xa57e,0x2cfa ,0xa57f,0x2cb2 , + 0xa581,0x2c6a ,0xa585,0x2c21 ,0xa588,0x2bd8 , + 0xa58d,0x2b8f ,0xa593,0x2b45 ,0xa599,0x2afb , + 0xa5a1,0x2ab0 ,0xa5a9,0x2a65 ,0xa5b2,0x2a1a , + 0xa5bc,0x29ce ,0xa5c7,0x2981 ,0xa5d3,0x2935 , + 0xa5e0,0x28e7 ,0xa5ed,0x289a ,0xa5fb,0x284c , + 0xa60b,0x27fe ,0xa61b,0x27af ,0xa62c,0x2760 , + 0xa63e,0x2711 ,0xa650,0x26c1 ,0xa664,0x2671 , + 0xa678,0x2620 ,0xa68e,0x25cf ,0xa6a4,0x257e , + 0xa6bb,0x252c ,0xa6d3,0x24da ,0xa6eb,0x2488 , + 0xa705,0x2435 ,0xa71f,0x23e2 ,0xa73b,0x238e , + 0xa757,0x233b ,0xa774,0x22e7 ,0xa792,0x2292 , + 0xa7b1,0x223d ,0xa7d0,0x21e8 ,0xa7f1,0x2193 , + 0xa812,0x213d ,0xa834,0x20e7 ,0xa857,0x2091 , + 0xa87b,0x203a ,0xa89f,0x1fe3 ,0xa8c5,0x1f8c , + 0xa8eb,0x1f34 ,0xa912,0x1edc ,0xa93a,0x1e84 , + 0xa963,0x1e2b ,0xa98d,0x1dd3 ,0xa9b7,0x1d79 , + 0xa9e3,0x1d20 ,0xaa0f,0x1cc6 ,0xaa3c,0x1c6c , + 0xaa6a,0x1c12 ,0xaa98,0x1bb8 ,0xaac8,0x1b5d , + 0xaaf8,0x1b02 ,0xab29,0x1aa7 ,0xab5b,0x1a4b , + 0xab8e,0x19ef ,0xabc2,0x1993 ,0xabf6,0x1937 , + 0xac2b,0x18db ,0xac61,0x187e ,0xac98,0x1821 , + 0xacd0,0x17c4 ,0xad08,0x1766 ,0xad41,0x1709 , + 0xad7b,0x16ab ,0xadb6,0x164c ,0xadf2,0x15ee , + 0xae2e,0x1590 ,0xae6b,0x1531 ,0xaea9,0x14d2 , + 0xaee8,0x1473 ,0xaf28,0x1413 ,0xaf68,0x13b4 , + 0xafa9,0x1354 ,0xafeb,0x12f4 ,0xb02d,0x1294 , + 0xb071,0x1234 ,0xb0b5,0x11d3 ,0xb0fa,0x1173 , + 0xb140,0x1112 ,0xb186,0x10b1 ,0xb1cd,0x1050 , + 0xb215,0x0fee ,0xb25e,0x0f8d ,0xb2a7,0x0f2b , + 0xb2f2,0x0eca ,0xb33d,0x0e68 ,0xb388,0x0e06 , + 0xb3d5,0x0da4 ,0xb422,0x0d41 ,0xb470,0x0cdf , + 0xb4be,0x0c7c ,0xb50e,0x0c1a ,0xb55e,0x0bb7 , + 0xb5af,0x0b54 ,0xb600,0x0af1 ,0xb652,0x0a8e , + 0xb6a5,0x0a2b ,0xb6f9,0x09c7 ,0xb74d,0x0964 , + 0xb7a2,0x0901 ,0xb7f8,0x089d ,0xb84f,0x0839 , + 0xb8a6,0x07d6 ,0xb8fd,0x0772 ,0xb956,0x070e , + 0xb9af,0x06aa ,0xba09,0x0646 ,0xba64,0x05e2 , + 0xbabf,0x057e ,0xbb1b,0x051a ,0xbb77,0x04b5 , + 0xbbd4,0x0451 ,0xbc32,0x03ed ,0xbc91,0x0388 , + 0xbcf0,0x0324 ,0xbd50,0x02c0 ,0xbdb0,0x025b , + 0xbe11,0x01f7 ,0xbe73,0x0192 ,0xbed5,0x012e , + 0xbf38,0x00c9 ,0xbf9c,0x0065 }; + + +extern const int s_Q14R_8; +const int s_Q14R_8 = 1024; +extern const unsigned short t_Q14R_8[2032]; +const unsigned short t_Q14R_8[2032] = { + 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , + 0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e , + 0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 , + 0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 , + 0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 , + 0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c , + 0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 , + 0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 , + 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , + 0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 , + 0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 , + 0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d , + 0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e , + 0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb , + 0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 , + 0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 , + 0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 , + 0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 , + 0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 , + 0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec , + 0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 , + 0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 , + 0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 , + 0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 , + 0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 , + 0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 , + 0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b , + 0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 , + 0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c , + 0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 , + 0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba , + 0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 , + 0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 , + 0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 , + 0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 , + 0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 , + 0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 , + 0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 , + 0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 , + 0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 , + 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , + 0x3ffb,0x0192 ,0x3fff,0x00c9 ,0x3ff5,0x025b , + 0x3fec,0x0324 ,0x3ffb,0x0192 ,0x3fd4,0x04b5 , + 0x3fd4,0x04b5 ,0x3ff5,0x025b ,0x3f9c,0x070e , + 0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 , + 0x3f85,0x07d6 ,0x3fe1,0x03ed ,0x3eeb,0x0bb7 , + 0x3f4f,0x0964 ,0x3fd4,0x04b5 ,0x3e72,0x0e06 , + 0x3f0f,0x0af1 ,0x3fc4,0x057e ,0x3de3,0x1050 , + 0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 , + 0x3e72,0x0e06 ,0x3f9c,0x070e ,0x3c85,0x14d2 , + 0x3e15,0x0f8d ,0x3f85,0x07d6 ,0x3bb6,0x1709 , + 0x3daf,0x1112 ,0x3f6b,0x089d ,0x3ad3,0x1937 , + 0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d , + 0x3cc5,0x1413 ,0x3f30,0x0a2b ,0x38cf,0x1d79 , + 0x3c42,0x1590 ,0x3f0f,0x0af1 ,0x37b0,0x1f8c , + 0x3bb6,0x1709 ,0x3eeb,0x0bb7 ,0x367d,0x2193 , + 0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e , + 0x3a82,0x19ef ,0x3e9d,0x0d41 ,0x33df,0x257e , + 0x39db,0x1b5d ,0x3e72,0x0e06 ,0x3274,0x2760 , + 0x392b,0x1cc6 ,0x3e45,0x0eca ,0x30f9,0x2935 , + 0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb , + 0x37b0,0x1f8c ,0x3de3,0x1050 ,0x2dcf,0x2cb2 , + 0x36e5,0x20e7 ,0x3daf,0x1112 ,0x2c21,0x2e5a , + 0x3612,0x223d ,0x3d78,0x11d3 ,0x2a65,0x2ff2 , + 0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 , + 0x3453,0x24da ,0x3d03,0x1354 ,0x26c1,0x32ef , + 0x3368,0x2620 ,0x3cc5,0x1413 ,0x24da,0x3453 , + 0x3274,0x2760 ,0x3c85,0x14d2 ,0x22e7,0x35a5 , + 0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 , + 0x3076,0x29ce ,0x3bfd,0x164c ,0x1edc,0x3812 , + 0x2f6c,0x2afb ,0x3bb6,0x1709 ,0x1cc6,0x392b , + 0x2e5a,0x2c21 ,0x3b6d,0x17c4 ,0x1aa7,0x3a30 , + 0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 , + 0x2c21,0x2e5a ,0x3ad3,0x1937 ,0x164c,0x3bfd , + 0x2afb,0x2f6c ,0x3a82,0x19ef ,0x1413,0x3cc5 , + 0x29ce,0x3076 ,0x3a30,0x1aa7 ,0x11d3,0x3d78 , + 0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 , + 0x2760,0x3274 ,0x3984,0x1c12 ,0x0d41,0x3e9d , + 0x2620,0x3368 ,0x392b,0x1cc6 ,0x0af1,0x3f0f , + 0x24da,0x3453 ,0x38cf,0x1d79 ,0x089d,0x3f6b , + 0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 , + 0x223d,0x3612 ,0x3812,0x1edc ,0x03ed,0x3fe1 , + 0x20e7,0x36e5 ,0x37b0,0x1f8c ,0x0192,0x3ffb , + 0x1f8c,0x37b0 ,0x374b,0x203a ,0xff37,0x3fff , + 0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec , + 0x1cc6,0x392b ,0x367d,0x2193 ,0xfa82,0x3fc4 , + 0x1b5d,0x39db ,0x3612,0x223d ,0xf82a,0x3f85 , + 0x19ef,0x3a82 ,0x35a5,0x22e7 ,0xf5d5,0x3f30 , + 0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 , + 0x1709,0x3bb6 ,0x34c6,0x2435 ,0xf136,0x3e45 , + 0x1590,0x3c42 ,0x3453,0x24da ,0xeeee,0x3daf , + 0x1413,0x3cc5 ,0x33df,0x257e ,0xecac,0x3d03 , + 0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 , + 0x1112,0x3daf ,0x32ef,0x26c1 ,0xe83c,0x3b6d , + 0x0f8d,0x3e15 ,0x3274,0x2760 ,0xe611,0x3a82 , + 0x0e06,0x3e72 ,0x31f8,0x27fe ,0xe3ee,0x3984 , + 0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 , + 0x0af1,0x3f0f ,0x30f9,0x2935 ,0xdfc6,0x374b , + 0x0964,0x3f4f ,0x3076,0x29ce ,0xddc3,0x3612 , + 0x07d6,0x3f85 ,0x2ff2,0x2a65 ,0xdbcb,0x34c6 , + 0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 , + 0x04b5,0x3fd4 ,0x2ee4,0x2b8f ,0xd802,0x31f8 , + 0x0324,0x3fec ,0x2e5a,0x2c21 ,0xd632,0x3076 , + 0x0192,0x3ffb ,0x2dcf,0x2cb2 ,0xd471,0x2ee4 , + 0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 , + 0xfe6e,0x3ffb ,0x2cb2,0x2dcf ,0xd11c,0x2b8f , + 0xfcdc,0x3fec ,0x2c21,0x2e5a ,0xcf8a,0x29ce , + 0xfb4b,0x3fd4 ,0x2b8f,0x2ee4 ,0xce08,0x27fe , + 0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 , + 0xf82a,0x3f85 ,0x2a65,0x2ff2 ,0xcb3a,0x2435 , + 0xf69c,0x3f4f ,0x29ce,0x3076 ,0xc9ee,0x223d , + 0xf50f,0x3f0f ,0x2935,0x30f9 ,0xc8b5,0x203a , + 0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b , + 0xf1fa,0x3e72 ,0x27fe,0x31f8 ,0xc67c,0x1c12 , + 0xf073,0x3e15 ,0x2760,0x3274 ,0xc57e,0x19ef , + 0xeeee,0x3daf ,0x26c1,0x32ef ,0xc493,0x17c4 , + 0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 , + 0xebed,0x3cc5 ,0x257e,0x33df ,0xc2fd,0x1354 , + 0xea70,0x3c42 ,0x24da,0x3453 ,0xc251,0x1112 , + 0xe8f7,0x3bb6 ,0x2435,0x34c6 ,0xc1bb,0x0eca , + 0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c , + 0xe611,0x3a82 ,0x22e7,0x35a5 ,0xc0d0,0x0a2b , + 0xe4a3,0x39db ,0x223d,0x3612 ,0xc07b,0x07d6 , + 0xe33a,0x392b ,0x2193,0x367d ,0xc03c,0x057e , + 0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 , + 0xe074,0x37b0 ,0x203a,0x374b ,0xc001,0x00c9 , + 0xdf19,0x36e5 ,0x1f8c,0x37b0 ,0xc005,0xfe6e , + 0xddc3,0x3612 ,0x1edc,0x3812 ,0xc01f,0xfc13 , + 0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba , + 0xdb26,0x3453 ,0x1d79,0x38cf ,0xc095,0xf763 , + 0xd9e0,0x3368 ,0x1cc6,0x392b ,0xc0f1,0xf50f , + 0xd8a0,0x3274 ,0x1c12,0x3984 ,0xc163,0xf2bf , + 0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 , + 0xd632,0x3076 ,0x1aa7,0x3a30 ,0xc288,0xee2d , + 0xd505,0x2f6c ,0x19ef,0x3a82 ,0xc33b,0xebed , + 0xd3df,0x2e5a ,0x1937,0x3ad3 ,0xc403,0xe9b4 , + 0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 , + 0xd1a6,0x2c21 ,0x17c4,0x3b6d ,0xc5d0,0xe559 , + 0xd094,0x2afb ,0x1709,0x3bb6 ,0xc6d5,0xe33a , + 0xcf8a,0x29ce ,0x164c,0x3bfd ,0xc7ee,0xe124 , + 0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 , + 0xcd8c,0x2760 ,0x14d2,0x3c85 ,0xca5b,0xdd19 , + 0xcc98,0x2620 ,0x1413,0x3cc5 ,0xcbad,0xdb26 , + 0xcbad,0x24da ,0x1354,0x3d03 ,0xcd11,0xd93f , + 0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 , + 0xc9ee,0x223d ,0x11d3,0x3d78 ,0xd00e,0xd59b , + 0xc91b,0x20e7 ,0x1112,0x3daf ,0xd1a6,0xd3df , + 0xc850,0x1f8c ,0x1050,0x3de3 ,0xd34e,0xd231 , + 0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 , + 0xc6d5,0x1cc6 ,0x0eca,0x3e45 ,0xd6cb,0xcf07 , + 0xc625,0x1b5d ,0x0e06,0x3e72 ,0xd8a0,0xcd8c , + 0xc57e,0x19ef ,0x0d41,0x3e9d ,0xda82,0xcc21 , + 0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 , + 0xc44a,0x1709 ,0x0bb7,0x3eeb ,0xde6d,0xc983 , + 0xc3be,0x1590 ,0x0af1,0x3f0f ,0xe074,0xc850 , + 0xc33b,0x1413 ,0x0a2b,0x3f30 ,0xe287,0xc731 , + 0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 , + 0xc251,0x1112 ,0x089d,0x3f6b ,0xe6c9,0xc52d , + 0xc1eb,0x0f8d ,0x07d6,0x3f85 ,0xe8f7,0xc44a , + 0xc18e,0x0e06 ,0x070e,0x3f9c ,0xeb2e,0xc37b , + 0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 , + 0xc0f1,0x0af1 ,0x057e,0x3fc4 ,0xefb0,0xc21d , + 0xc0b1,0x0964 ,0x04b5,0x3fd4 ,0xf1fa,0xc18e , + 0xc07b,0x07d6 ,0x03ed,0x3fe1 ,0xf449,0xc115 , + 0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 , + 0xc02c,0x04b5 ,0x025b,0x3ff5 ,0xf8f2,0xc064 , + 0xc014,0x0324 ,0x0192,0x3ffb ,0xfb4b,0xc02c , + 0xc005,0x0192 ,0x00c9,0x3fff ,0xfda5,0xc00b , + 0x4000,0x0000 ,0x4000,0x0065 ,0x3fff,0x00c9 , + 0x3ffd,0x012e ,0x3ffb,0x0192 ,0x3ff8,0x01f7 , + 0x3ff5,0x025b ,0x3ff1,0x02c0 ,0x3fec,0x0324 , + 0x3fe7,0x0388 ,0x3fe1,0x03ed ,0x3fdb,0x0451 , + 0x3fd4,0x04b5 ,0x3fcc,0x051a ,0x3fc4,0x057e , + 0x3fbb,0x05e2 ,0x3fb1,0x0646 ,0x3fa7,0x06aa , + 0x3f9c,0x070e ,0x3f91,0x0772 ,0x3f85,0x07d6 , + 0x3f78,0x0839 ,0x3f6b,0x089d ,0x3f5d,0x0901 , + 0x3f4f,0x0964 ,0x3f40,0x09c7 ,0x3f30,0x0a2b , + 0x3f20,0x0a8e ,0x3f0f,0x0af1 ,0x3efd,0x0b54 , + 0x3eeb,0x0bb7 ,0x3ed8,0x0c1a ,0x3ec5,0x0c7c , + 0x3eb1,0x0cdf ,0x3e9d,0x0d41 ,0x3e88,0x0da4 , + 0x3e72,0x0e06 ,0x3e5c,0x0e68 ,0x3e45,0x0eca , + 0x3e2d,0x0f2b ,0x3e15,0x0f8d ,0x3dfc,0x0fee , + 0x3de3,0x1050 ,0x3dc9,0x10b1 ,0x3daf,0x1112 , + 0x3d93,0x1173 ,0x3d78,0x11d3 ,0x3d5b,0x1234 , + 0x3d3f,0x1294 ,0x3d21,0x12f4 ,0x3d03,0x1354 , + 0x3ce4,0x13b4 ,0x3cc5,0x1413 ,0x3ca5,0x1473 , + 0x3c85,0x14d2 ,0x3c64,0x1531 ,0x3c42,0x1590 , + 0x3c20,0x15ee ,0x3bfd,0x164c ,0x3bda,0x16ab , + 0x3bb6,0x1709 ,0x3b92,0x1766 ,0x3b6d,0x17c4 , + 0x3b47,0x1821 ,0x3b21,0x187e ,0x3afa,0x18db , + 0x3ad3,0x1937 ,0x3aab,0x1993 ,0x3a82,0x19ef , + 0x3a59,0x1a4b ,0x3a30,0x1aa7 ,0x3a06,0x1b02 , + 0x39db,0x1b5d ,0x39b0,0x1bb8 ,0x3984,0x1c12 , + 0x3958,0x1c6c ,0x392b,0x1cc6 ,0x38fd,0x1d20 , + 0x38cf,0x1d79 ,0x38a1,0x1dd3 ,0x3871,0x1e2b , + 0x3842,0x1e84 ,0x3812,0x1edc ,0x37e1,0x1f34 , + 0x37b0,0x1f8c ,0x377e,0x1fe3 ,0x374b,0x203a , + 0x3718,0x2091 ,0x36e5,0x20e7 ,0x36b1,0x213d , + 0x367d,0x2193 ,0x3648,0x21e8 ,0x3612,0x223d , + 0x35dc,0x2292 ,0x35a5,0x22e7 ,0x356e,0x233b , + 0x3537,0x238e ,0x34ff,0x23e2 ,0x34c6,0x2435 , + 0x348d,0x2488 ,0x3453,0x24da ,0x3419,0x252c , + 0x33df,0x257e ,0x33a3,0x25cf ,0x3368,0x2620 , + 0x332c,0x2671 ,0x32ef,0x26c1 ,0x32b2,0x2711 , + 0x3274,0x2760 ,0x3236,0x27af ,0x31f8,0x27fe , + 0x31b9,0x284c ,0x3179,0x289a ,0x3139,0x28e7 , + 0x30f9,0x2935 ,0x30b8,0x2981 ,0x3076,0x29ce , + 0x3034,0x2a1a ,0x2ff2,0x2a65 ,0x2faf,0x2ab0 , + 0x2f6c,0x2afb ,0x2f28,0x2b45 ,0x2ee4,0x2b8f , + 0x2e9f,0x2bd8 ,0x2e5a,0x2c21 ,0x2e15,0x2c6a , + 0x2dcf,0x2cb2 ,0x2d88,0x2cfa ,0x2d41,0x2d41 , + 0x2cfa,0x2d88 ,0x2cb2,0x2dcf ,0x2c6a,0x2e15 , + 0x2c21,0x2e5a ,0x2bd8,0x2e9f ,0x2b8f,0x2ee4 , + 0x2b45,0x2f28 ,0x2afb,0x2f6c ,0x2ab0,0x2faf , + 0x2a65,0x2ff2 ,0x2a1a,0x3034 ,0x29ce,0x3076 , + 0x2981,0x30b8 ,0x2935,0x30f9 ,0x28e7,0x3139 , + 0x289a,0x3179 ,0x284c,0x31b9 ,0x27fe,0x31f8 , + 0x27af,0x3236 ,0x2760,0x3274 ,0x2711,0x32b2 , + 0x26c1,0x32ef ,0x2671,0x332c ,0x2620,0x3368 , + 0x25cf,0x33a3 ,0x257e,0x33df ,0x252c,0x3419 , + 0x24da,0x3453 ,0x2488,0x348d ,0x2435,0x34c6 , + 0x23e2,0x34ff ,0x238e,0x3537 ,0x233b,0x356e , + 0x22e7,0x35a5 ,0x2292,0x35dc ,0x223d,0x3612 , + 0x21e8,0x3648 ,0x2193,0x367d ,0x213d,0x36b1 , + 0x20e7,0x36e5 ,0x2091,0x3718 ,0x203a,0x374b , + 0x1fe3,0x377e ,0x1f8c,0x37b0 ,0x1f34,0x37e1 , + 0x1edc,0x3812 ,0x1e84,0x3842 ,0x1e2b,0x3871 , + 0x1dd3,0x38a1 ,0x1d79,0x38cf ,0x1d20,0x38fd , + 0x1cc6,0x392b ,0x1c6c,0x3958 ,0x1c12,0x3984 , + 0x1bb8,0x39b0 ,0x1b5d,0x39db ,0x1b02,0x3a06 , + 0x1aa7,0x3a30 ,0x1a4b,0x3a59 ,0x19ef,0x3a82 , + 0x1993,0x3aab ,0x1937,0x3ad3 ,0x18db,0x3afa , + 0x187e,0x3b21 ,0x1821,0x3b47 ,0x17c4,0x3b6d , + 0x1766,0x3b92 ,0x1709,0x3bb6 ,0x16ab,0x3bda , + 0x164c,0x3bfd ,0x15ee,0x3c20 ,0x1590,0x3c42 , + 0x1531,0x3c64 ,0x14d2,0x3c85 ,0x1473,0x3ca5 , + 0x1413,0x3cc5 ,0x13b4,0x3ce4 ,0x1354,0x3d03 , + 0x12f4,0x3d21 ,0x1294,0x3d3f ,0x1234,0x3d5b , + 0x11d3,0x3d78 ,0x1173,0x3d93 ,0x1112,0x3daf , + 0x10b1,0x3dc9 ,0x1050,0x3de3 ,0x0fee,0x3dfc , + 0x0f8d,0x3e15 ,0x0f2b,0x3e2d ,0x0eca,0x3e45 , + 0x0e68,0x3e5c ,0x0e06,0x3e72 ,0x0da4,0x3e88 , + 0x0d41,0x3e9d ,0x0cdf,0x3eb1 ,0x0c7c,0x3ec5 , + 0x0c1a,0x3ed8 ,0x0bb7,0x3eeb ,0x0b54,0x3efd , + 0x0af1,0x3f0f ,0x0a8e,0x3f20 ,0x0a2b,0x3f30 , + 0x09c7,0x3f40 ,0x0964,0x3f4f ,0x0901,0x3f5d , + 0x089d,0x3f6b ,0x0839,0x3f78 ,0x07d6,0x3f85 , + 0x0772,0x3f91 ,0x070e,0x3f9c ,0x06aa,0x3fa7 , + 0x0646,0x3fb1 ,0x05e2,0x3fbb ,0x057e,0x3fc4 , + 0x051a,0x3fcc ,0x04b5,0x3fd4 ,0x0451,0x3fdb , + 0x03ed,0x3fe1 ,0x0388,0x3fe7 ,0x0324,0x3fec , + 0x02c0,0x3ff1 ,0x025b,0x3ff5 ,0x01f7,0x3ff8 , + 0x0192,0x3ffb ,0x012e,0x3ffd ,0x00c9,0x3fff , + 0x0065,0x4000 ,0x0000,0x4000 ,0xff9b,0x4000 , + 0xff37,0x3fff ,0xfed2,0x3ffd ,0xfe6e,0x3ffb , + 0xfe09,0x3ff8 ,0xfda5,0x3ff5 ,0xfd40,0x3ff1 , + 0xfcdc,0x3fec ,0xfc78,0x3fe7 ,0xfc13,0x3fe1 , + 0xfbaf,0x3fdb ,0xfb4b,0x3fd4 ,0xfae6,0x3fcc , + 0xfa82,0x3fc4 ,0xfa1e,0x3fbb ,0xf9ba,0x3fb1 , + 0xf956,0x3fa7 ,0xf8f2,0x3f9c ,0xf88e,0x3f91 , + 0xf82a,0x3f85 ,0xf7c7,0x3f78 ,0xf763,0x3f6b , + 0xf6ff,0x3f5d ,0xf69c,0x3f4f ,0xf639,0x3f40 , + 0xf5d5,0x3f30 ,0xf572,0x3f20 ,0xf50f,0x3f0f , + 0xf4ac,0x3efd ,0xf449,0x3eeb ,0xf3e6,0x3ed8 , + 0xf384,0x3ec5 ,0xf321,0x3eb1 ,0xf2bf,0x3e9d , + 0xf25c,0x3e88 ,0xf1fa,0x3e72 ,0xf198,0x3e5c , + 0xf136,0x3e45 ,0xf0d5,0x3e2d ,0xf073,0x3e15 , + 0xf012,0x3dfc ,0xefb0,0x3de3 ,0xef4f,0x3dc9 , + 0xeeee,0x3daf ,0xee8d,0x3d93 ,0xee2d,0x3d78 , + 0xedcc,0x3d5b ,0xed6c,0x3d3f ,0xed0c,0x3d21 , + 0xecac,0x3d03 ,0xec4c,0x3ce4 ,0xebed,0x3cc5 , + 0xeb8d,0x3ca5 ,0xeb2e,0x3c85 ,0xeacf,0x3c64 , + 0xea70,0x3c42 ,0xea12,0x3c20 ,0xe9b4,0x3bfd , + 0xe955,0x3bda ,0xe8f7,0x3bb6 ,0xe89a,0x3b92 , + 0xe83c,0x3b6d ,0xe7df,0x3b47 ,0xe782,0x3b21 , + 0xe725,0x3afa ,0xe6c9,0x3ad3 ,0xe66d,0x3aab , + 0xe611,0x3a82 ,0xe5b5,0x3a59 ,0xe559,0x3a30 , + 0xe4fe,0x3a06 ,0xe4a3,0x39db ,0xe448,0x39b0 , + 0xe3ee,0x3984 ,0xe394,0x3958 ,0xe33a,0x392b , + 0xe2e0,0x38fd ,0xe287,0x38cf ,0xe22d,0x38a1 , + 0xe1d5,0x3871 ,0xe17c,0x3842 ,0xe124,0x3812 , + 0xe0cc,0x37e1 ,0xe074,0x37b0 ,0xe01d,0x377e , + 0xdfc6,0x374b ,0xdf6f,0x3718 ,0xdf19,0x36e5 , + 0xdec3,0x36b1 ,0xde6d,0x367d ,0xde18,0x3648 , + 0xddc3,0x3612 ,0xdd6e,0x35dc ,0xdd19,0x35a5 , + 0xdcc5,0x356e ,0xdc72,0x3537 ,0xdc1e,0x34ff , + 0xdbcb,0x34c6 ,0xdb78,0x348d ,0xdb26,0x3453 , + 0xdad4,0x3419 ,0xda82,0x33df ,0xda31,0x33a3 , + 0xd9e0,0x3368 ,0xd98f,0x332c ,0xd93f,0x32ef , + 0xd8ef,0x32b2 ,0xd8a0,0x3274 ,0xd851,0x3236 , + 0xd802,0x31f8 ,0xd7b4,0x31b9 ,0xd766,0x3179 , + 0xd719,0x3139 ,0xd6cb,0x30f9 ,0xd67f,0x30b8 , + 0xd632,0x3076 ,0xd5e6,0x3034 ,0xd59b,0x2ff2 , + 0xd550,0x2faf ,0xd505,0x2f6c ,0xd4bb,0x2f28 , + 0xd471,0x2ee4 ,0xd428,0x2e9f ,0xd3df,0x2e5a , + 0xd396,0x2e15 ,0xd34e,0x2dcf ,0xd306,0x2d88 , + 0xd2bf,0x2d41 ,0xd278,0x2cfa ,0xd231,0x2cb2 , + 0xd1eb,0x2c6a ,0xd1a6,0x2c21 ,0xd161,0x2bd8 , + 0xd11c,0x2b8f ,0xd0d8,0x2b45 ,0xd094,0x2afb , + 0xd051,0x2ab0 ,0xd00e,0x2a65 ,0xcfcc,0x2a1a , + 0xcf8a,0x29ce ,0xcf48,0x2981 ,0xcf07,0x2935 , + 0xcec7,0x28e7 ,0xce87,0x289a ,0xce47,0x284c , + 0xce08,0x27fe ,0xcdca,0x27af ,0xcd8c,0x2760 , + 0xcd4e,0x2711 ,0xcd11,0x26c1 ,0xccd4,0x2671 , + 0xcc98,0x2620 ,0xcc5d,0x25cf ,0xcc21,0x257e , + 0xcbe7,0x252c ,0xcbad,0x24da ,0xcb73,0x2488 , + 0xcb3a,0x2435 ,0xcb01,0x23e2 ,0xcac9,0x238e , + 0xca92,0x233b ,0xca5b,0x22e7 ,0xca24,0x2292 , + 0xc9ee,0x223d ,0xc9b8,0x21e8 ,0xc983,0x2193 , + 0xc94f,0x213d ,0xc91b,0x20e7 ,0xc8e8,0x2091 , + 0xc8b5,0x203a ,0xc882,0x1fe3 ,0xc850,0x1f8c , + 0xc81f,0x1f34 ,0xc7ee,0x1edc ,0xc7be,0x1e84 , + 0xc78f,0x1e2b ,0xc75f,0x1dd3 ,0xc731,0x1d79 , + 0xc703,0x1d20 ,0xc6d5,0x1cc6 ,0xc6a8,0x1c6c , + 0xc67c,0x1c12 ,0xc650,0x1bb8 ,0xc625,0x1b5d , + 0xc5fa,0x1b02 ,0xc5d0,0x1aa7 ,0xc5a7,0x1a4b , + 0xc57e,0x19ef ,0xc555,0x1993 ,0xc52d,0x1937 , + 0xc506,0x18db ,0xc4df,0x187e ,0xc4b9,0x1821 , + 0xc493,0x17c4 ,0xc46e,0x1766 ,0xc44a,0x1709 , + 0xc426,0x16ab ,0xc403,0x164c ,0xc3e0,0x15ee , + 0xc3be,0x1590 ,0xc39c,0x1531 ,0xc37b,0x14d2 , + 0xc35b,0x1473 ,0xc33b,0x1413 ,0xc31c,0x13b4 , + 0xc2fd,0x1354 ,0xc2df,0x12f4 ,0xc2c1,0x1294 , + 0xc2a5,0x1234 ,0xc288,0x11d3 ,0xc26d,0x1173 , + 0xc251,0x1112 ,0xc237,0x10b1 ,0xc21d,0x1050 , + 0xc204,0x0fee ,0xc1eb,0x0f8d ,0xc1d3,0x0f2b , + 0xc1bb,0x0eca ,0xc1a4,0x0e68 ,0xc18e,0x0e06 , + 0xc178,0x0da4 ,0xc163,0x0d41 ,0xc14f,0x0cdf , + 0xc13b,0x0c7c ,0xc128,0x0c1a ,0xc115,0x0bb7 , + 0xc103,0x0b54 ,0xc0f1,0x0af1 ,0xc0e0,0x0a8e , + 0xc0d0,0x0a2b ,0xc0c0,0x09c7 ,0xc0b1,0x0964 , + 0xc0a3,0x0901 ,0xc095,0x089d ,0xc088,0x0839 , + 0xc07b,0x07d6 ,0xc06f,0x0772 ,0xc064,0x070e , + 0xc059,0x06aa ,0xc04f,0x0646 ,0xc045,0x05e2 , + 0xc03c,0x057e ,0xc034,0x051a ,0xc02c,0x04b5 , + 0xc025,0x0451 ,0xc01f,0x03ed ,0xc019,0x0388 , + 0xc014,0x0324 ,0xc00f,0x02c0 ,0xc00b,0x025b , + 0xc008,0x01f7 ,0xc005,0x0192 ,0xc003,0x012e , + 0xc001,0x00c9 ,0xc000,0x0065 }; diff --git a/src/libs/webrtc/signal_processing_library/fft_ARM9E/t_rad.c b/src/libs/webrtc/signal_processing_library/fft_ARM9E/t_rad.c new file mode 100644 index 00000000..66ed6add --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/fft_ARM9E/t_rad.c @@ -0,0 +1,19 @@ +/* + * Copyright (C) ARM Limited 1998-2000. All rights reserved. + * + * t_rad.c + * + */ + +extern const unsigned short t_Q14S_rad8[2]; +const unsigned short t_Q14S_rad8[2] = { 0x0000,0x2d41 }; +/* +extern const int t_Q30S_rad8[2]; +const int t_Q30S_rad8[2] = { 0x00000000,0x2d413ccd }; +*/ +extern const unsigned short t_Q14R_rad8[2]; +const unsigned short t_Q14R_rad8[2] = { 0x2d41,0x2d41 }; +/* +extern const int t_Q30R_rad8[2]; +const int t_Q30R_rad8[2] = { 0x2d413ccd,0x2d413ccd }; +*/ diff --git a/src/libs/webrtc/signal_processing_library/filter_ar.c b/src/libs/webrtc/signal_processing_library/filter_ar.c new file mode 100644 index 00000000..30a56c1c --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/filter_ar.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_FilterAR(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +int WebRtcSpl_FilterAR(G_CONST WebRtc_Word16* a, + int a_length, + G_CONST WebRtc_Word16* x, + int x_length, + WebRtc_Word16* state, + int state_length, + WebRtc_Word16* state_low, + int state_low_length, + WebRtc_Word16* filtered, + WebRtc_Word16* filtered_low, + int filtered_low_length) +{ + WebRtc_Word32 o; + WebRtc_Word32 oLOW; + int i, j, stop; + G_CONST WebRtc_Word16* x_ptr = &x[0]; + WebRtc_Word16* filteredFINAL_ptr = filtered; + WebRtc_Word16* filteredFINAL_LOW_ptr = filtered_low; + + state_low_length = state_low_length; + filtered_low_length = filtered_low_length; + + for (i = 0; i < x_length; i++) + { + // Calculate filtered[i] and filtered_low[i] + G_CONST WebRtc_Word16* a_ptr = &a[1]; + WebRtc_Word16* filtered_ptr = &filtered[i - 1]; + WebRtc_Word16* filtered_low_ptr = &filtered_low[i - 1]; + WebRtc_Word16* state_ptr = &state[state_length - 1]; + WebRtc_Word16* state_low_ptr = &state_low[state_length - 1]; + + o = (WebRtc_Word32)(*x_ptr++) << 12; + oLOW = (WebRtc_Word32)0; + + stop = (i < a_length) ? i + 1 : a_length; + for (j = 1; j < stop; j++) + { + o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *filtered_ptr--); + oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *filtered_low_ptr--); + } + for (j = i + 1; j < a_length; j++) + { + o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *state_ptr--); + oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *state_low_ptr--); + } + + o += (oLOW >> 12); + *filteredFINAL_ptr = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); + *filteredFINAL_LOW_ptr++ = (WebRtc_Word16)(o - ((WebRtc_Word32)(*filteredFINAL_ptr++) + << 12)); + } + + // Save the filter state + if (x_length >= state_length) + { + WebRtcSpl_CopyFromEndW16(filtered, x_length, a_length - 1, state); + WebRtcSpl_CopyFromEndW16(filtered_low, x_length, a_length - 1, state_low); + } else + { + for (i = 0; i < state_length - x_length; i++) + { + state[i] = state[i + x_length]; + state_low[i] = state_low[i + x_length]; + } + for (i = 0; i < x_length; i++) + { + state[state_length - x_length + i] = filtered[i]; + state[state_length - x_length + i] = filtered_low[i]; + } + } + + return x_length; +} diff --git a/src/libs/webrtc/signal_processing_library/filter_ar_fast_q12.c b/src/libs/webrtc/signal_processing_library/filter_ar_fast_q12.c new file mode 100644 index 00000000..6184da3f --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/filter_ar_fast_q12.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_FilterARFastQ12(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +void WebRtcSpl_FilterARFastQ12(WebRtc_Word16 *in, WebRtc_Word16 *out, WebRtc_Word16 *A, + WebRtc_Word16 A_length, WebRtc_Word16 length) +{ + WebRtc_Word32 o; + int i, j; + + WebRtc_Word16 *x_ptr = &in[0]; + WebRtc_Word16 *filtered_ptr = &out[0]; + + for (i = 0; i < length; i++) + { + // Calculate filtered[i] + G_CONST WebRtc_Word16 *a_ptr = &A[0]; + WebRtc_Word16 *state_ptr = &out[i - 1]; + + o = WEBRTC_SPL_MUL_16_16(*x_ptr++, *a_ptr++); + + for (j = 1; j < A_length; j++) + { + o -= WEBRTC_SPL_MUL_16_16(*a_ptr++,*state_ptr--); + } + + // Saturate the output + o = WEBRTC_SPL_SAT((WebRtc_Word32)134215679, o, (WebRtc_Word32)-134217728); + + *filtered_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); + } + + return; +} diff --git a/src/libs/webrtc/signal_processing_library/filter_ma_fast_q12.c b/src/libs/webrtc/signal_processing_library/filter_ma_fast_q12.c new file mode 100644 index 00000000..19ad9b16 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/filter_ma_fast_q12.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_FilterMAFastQ12(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +void WebRtcSpl_FilterMAFastQ12(WebRtc_Word16* in_ptr, + WebRtc_Word16* out_ptr, + WebRtc_Word16* B, + WebRtc_Word16 B_length, + WebRtc_Word16 length) +{ + WebRtc_Word32 o; + int i, j; + for (i = 0; i < length; i++) + { + G_CONST WebRtc_Word16* b_ptr = &B[0]; + G_CONST WebRtc_Word16* x_ptr = &in_ptr[i]; + + o = (WebRtc_Word32)0; + + for (j = 0; j < B_length; j++) + { + o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--); + } + + // If output is higher than 32768, saturate it. Same with negative side + // 2^27 = 134217728, which corresponds to 32768 in Q12 + + // Saturate the output + o = WEBRTC_SPL_SAT((WebRtc_Word32)134215679, o, (WebRtc_Word32)-134217728); + + *out_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); + } + return; +} diff --git a/src/libs/webrtc/signal_processing_library/get_hanning_window.c b/src/libs/webrtc/signal_processing_library/get_hanning_window.c new file mode 100644 index 00000000..2845c838 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/get_hanning_window.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_GetHanningWindow(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +void WebRtcSpl_GetHanningWindow(WebRtc_Word16 *v, WebRtc_Word16 size) +{ + int jj; + WebRtc_Word16 *vptr1; + + WebRtc_Word32 index; + WebRtc_Word32 factor = ((WebRtc_Word32)0x40000000); + + factor = WebRtcSpl_DivW32W16(factor, size); + if (size < 513) + index = (WebRtc_Word32)-0x200000; + else + index = (WebRtc_Word32)-0x100000; + vptr1 = v; + + for (jj = 0; jj < size; jj++) + { + index += factor; + (*vptr1++) = WebRtcSpl_kHanningTable[index >> 22]; + } + +} diff --git a/src/libs/webrtc/signal_processing_library/get_scaling_square.c b/src/libs/webrtc/signal_processing_library/get_scaling_square.c new file mode 100644 index 00000000..dccbf334 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/get_scaling_square.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_GetScalingSquare(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +int WebRtcSpl_GetScalingSquare(WebRtc_Word16 *in_vector, int in_vector_length, int times) +{ + int nbits = WebRtcSpl_GetSizeInBits(times); + int i; + WebRtc_Word16 smax = -1; + WebRtc_Word16 sabs; + WebRtc_Word16 *sptr = in_vector; + int t; + int looptimes = in_vector_length; + + for (i = looptimes; i > 0; i--) + { + sabs = (*sptr > 0 ? *sptr++ : -*sptr++); + smax = (sabs > smax ? sabs : smax); + } + t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); + + if (smax == 0) + { + return 0; // Since norm(0) returns 0 + } else + { + return (t > nbits) ? 0 : nbits - t; + } +} diff --git a/src/libs/webrtc/signal_processing_library/get_size_in_bits.c b/src/libs/webrtc/signal_processing_library/get_size_in_bits.c new file mode 100644 index 00000000..53853f05 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/get_size_in_bits.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_GetSizeInBits(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS + +WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 value) +{ + + int bits = 0; + + // Fast binary search to find the number of bits used + if ((0xFFFF0000 & value)) + bits = 16; + if ((0x0000FF00 & (value >> bits))) + bits += 8; + if ((0x000000F0 & (value >> bits))) + bits += 4; + if ((0x0000000C & (value >> bits))) + bits += 2; + if ((0x00000002 & (value >> bits))) + bits += 1; + if ((0x00000001 & (value >> bits))) + bits += 1; + + return bits; +} + +#endif diff --git a/src/libs/webrtc/signal_processing_library/hanning_table.c b/src/libs/webrtc/signal_processing_library/hanning_table.c new file mode 100644 index 00000000..112d0e59 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/hanning_table.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the Hanning table with 256 entries. + * + */ + +#include "signal_processing_library.h" + +// Hanning table with 256 entries +WebRtc_Word16 WebRtcSpl_kHanningTable[] = { + 1, 2, 6, 10, 15, 22, 30, 39, + 50, 62, 75, 89, 104, 121, 138, 157, + 178, 199, 222, 246, 271, 297, 324, 353, + 383, 413, 446, 479, 513, 549, 586, 624, + 663, 703, 744, 787, 830, 875, 920, 967, + 1015, 1064, 1114, 1165, 1218, 1271, 1325, 1381, + 1437, 1494, 1553, 1612, 1673, 1734, 1796, 1859, + 1924, 1989, 2055, 2122, 2190, 2259, 2329, 2399, + 2471, 2543, 2617, 2691, 2765, 2841, 2918, 2995, + 3073, 3152, 3232, 3312, 3393, 3475, 3558, 3641, + 3725, 3809, 3895, 3980, 4067, 4154, 4242, 4330, + 4419, 4509, 4599, 4689, 4781, 4872, 4964, 5057, + 5150, 5244, 5338, 5432, 5527, 5622, 5718, 5814, + 5910, 6007, 6104, 6202, 6299, 6397, 6495, 6594, + 6693, 6791, 6891, 6990, 7090, 7189, 7289, 7389, + 7489, 7589, 7690, 7790, 7890, 7991, 8091, 8192, + 8293, 8393, 8494, 8594, 8694, 8795, 8895, 8995, + 9095, 9195, 9294, 9394, 9493, 9593, 9691, 9790, + 9889, 9987, 10085, 10182, 10280, 10377, 10474, 10570, +10666, 10762, 10857, 10952, 11046, 11140, 11234, 11327, +11420, 11512, 11603, 11695, 11785, 11875, 11965, 12054, +12142, 12230, 12317, 12404, 12489, 12575, 12659, 12743, +12826, 12909, 12991, 13072, 13152, 13232, 13311, 13389, +13466, 13543, 13619, 13693, 13767, 13841, 13913, 13985, +14055, 14125, 14194, 14262, 14329, 14395, 14460, 14525, +14588, 14650, 14711, 14772, 14831, 14890, 14947, 15003, +15059, 15113, 15166, 15219, 15270, 15320, 15369, 15417, +15464, 15509, 15554, 15597, 15640, 15681, 15721, 15760, +15798, 15835, 15871, 15905, 15938, 15971, 16001, 16031, +16060, 16087, 16113, 16138, 16162, 16185, 16206, 16227, +16246, 16263, 16280, 16295, 16309, 16322, 16334, 16345, +16354, 16362, 16369, 16374, 16378, 16382, 16383, 16384 +}; diff --git a/src/libs/webrtc/signal_processing_library/ilbc_specific_functions.c b/src/libs/webrtc/signal_processing_library/ilbc_specific_functions.c new file mode 100644 index 00000000..5a9e5773 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/ilbc_specific_functions.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains implementations of the iLBC specific functions + * WebRtcSpl_ScaleAndAddVectorsWithRound() + * WebRtcSpl_ReverseOrderMultArrayElements() + * WebRtcSpl_ElementwiseVectorMult() + * WebRtcSpl_AddVectorsAndShift() + * WebRtcSpl_AddAffineVectorToVector() + * WebRtcSpl_AffineTransformVector() + * + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +void WebRtcSpl_ScaleAndAddVectorsWithRound(WebRtc_Word16 *vector1, WebRtc_Word16 scale1, + WebRtc_Word16 *vector2, WebRtc_Word16 scale2, + WebRtc_Word16 right_shifts, WebRtc_Word16 *out, + WebRtc_Word16 vector_length) +{ + int i; + WebRtc_Word16 roundVal; + roundVal = 1 << right_shifts; + roundVal = roundVal >> 1; + for (i = 0; i < vector_length; i++) + { + out[i] = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16(vector1[i], scale1) + + WEBRTC_SPL_MUL_16_16(vector2[i], scale2) + roundVal) >> right_shifts); + } +} + +void WebRtcSpl_ReverseOrderMultArrayElements(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in, + G_CONST WebRtc_Word16 *win, + WebRtc_Word16 vector_length, + WebRtc_Word16 right_shifts) +{ + int i; + WebRtc_Word16 *outptr = out; + G_CONST WebRtc_Word16 *inptr = in; + G_CONST WebRtc_Word16 *winptr = win; + for (i = 0; i < vector_length; i++) + { + (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, + *winptr--, right_shifts); + } +} + +void WebRtcSpl_ElementwiseVectorMult(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in, + G_CONST WebRtc_Word16 *win, WebRtc_Word16 vector_length, + WebRtc_Word16 right_shifts) +{ + int i; + WebRtc_Word16 *outptr = out; + G_CONST WebRtc_Word16 *inptr = in; + G_CONST WebRtc_Word16 *winptr = win; + for (i = 0; i < vector_length; i++) + { + (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, + *winptr++, right_shifts); + } +} + +void WebRtcSpl_AddVectorsAndShift(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in1, + G_CONST WebRtc_Word16 *in2, WebRtc_Word16 vector_length, + WebRtc_Word16 right_shifts) +{ + int i; + WebRtc_Word16 *outptr = out; + G_CONST WebRtc_Word16 *in1ptr = in1; + G_CONST WebRtc_Word16 *in2ptr = in2; + for (i = vector_length; i > 0; i--) + { + (*outptr++) = (WebRtc_Word16)(((*in1ptr++) + (*in2ptr++)) >> right_shifts); + } +} + +void WebRtcSpl_AddAffineVectorToVector(WebRtc_Word16 *out, WebRtc_Word16 *in, + WebRtc_Word16 gain, WebRtc_Word32 add_constant, + WebRtc_Word16 right_shifts, int vector_length) +{ + WebRtc_Word16 *inPtr; + WebRtc_Word16 *outPtr; + int i; + + inPtr = in; + outPtr = out; + for (i = 0; i < vector_length; i++) + { + (*outPtr++) += (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain) + + (WebRtc_Word32)add_constant) >> right_shifts); + } +} + +void WebRtcSpl_AffineTransformVector(WebRtc_Word16 *out, WebRtc_Word16 *in, + WebRtc_Word16 gain, WebRtc_Word32 add_constant, + WebRtc_Word16 right_shifts, int vector_length) +{ + WebRtc_Word16 *inPtr; + WebRtc_Word16 *outPtr; + int i; + + inPtr = in; + outPtr = out; + for (i = 0; i < vector_length; i++) + { + (*outPtr++) = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain) + + (WebRtc_Word32)add_constant) >> right_shifts); + } +} diff --git a/src/libs/webrtc/signal_processing_library/levinson_durbin.c b/src/libs/webrtc/signal_processing_library/levinson_durbin.c new file mode 100644 index 00000000..4e11cdb1 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/levinson_durbin.c @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_LevinsonDurbin(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#define SPL_LEVINSON_MAXORDER 20 + +WebRtc_Word16 WebRtcSpl_LevinsonDurbin(WebRtc_Word32 *R, WebRtc_Word16 *A, WebRtc_Word16 *K, + WebRtc_Word16 order) +{ + WebRtc_Word16 i, j; + // Auto-correlation coefficients in high precision + WebRtc_Word16 R_hi[SPL_LEVINSON_MAXORDER + 1], R_low[SPL_LEVINSON_MAXORDER + 1]; + // LPC coefficients in high precision + WebRtc_Word16 A_hi[SPL_LEVINSON_MAXORDER + 1], A_low[SPL_LEVINSON_MAXORDER + 1]; + // LPC coefficients for next iteration + WebRtc_Word16 A_upd_hi[SPL_LEVINSON_MAXORDER + 1], A_upd_low[SPL_LEVINSON_MAXORDER + 1]; + // Reflection coefficient in high precision + WebRtc_Word16 K_hi, K_low; + // Prediction gain Alpha in high precision and with scale factor + WebRtc_Word16 Alpha_hi, Alpha_low, Alpha_exp; + WebRtc_Word16 tmp_hi, tmp_low; + WebRtc_Word32 temp1W32, temp2W32, temp3W32; + WebRtc_Word16 norm; + + // Normalize the autocorrelation R[0]...R[order+1] + + norm = WebRtcSpl_NormW32(R[0]); + + for (i = order; i >= 0; i--) + { + temp1W32 = WEBRTC_SPL_LSHIFT_W32(R[i], norm); + // Put R in hi and low format + R_hi[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + R_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16)), 1); + } + + // K = A[1] = -R[1] / R[0] + + temp2W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[1],16) + + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[1],1); // R[1] in Q31 + temp3W32 = WEBRTC_SPL_ABS_W32(temp2W32); // abs R[1] + temp1W32 = WebRtcSpl_DivW32HiLow(temp3W32, R_hi[0], R_low[0]); // abs(R[1])/R[0] in Q31 + // Put back the sign on R[1] + if (temp2W32 > 0) + { + temp1W32 = -temp1W32; + } + + // Put K in hi and low format + K_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1); + + // Store first reflection coefficient + K[0] = K_hi; + + temp1W32 = WEBRTC_SPL_RSHIFT_W32(temp1W32, 4); // A[1] in Q27 + + // Put A[1] in hi and low format + A_hi[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + A_low[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[1], 16)), 1); + + // Alpha = R[0] * (1-K^2) + + temp1W32 = (((WEBRTC_SPL_MUL_16_16(K_hi, K_low) >> 14) + WEBRTC_SPL_MUL_16_16(K_hi, K_hi)) + << 1); // temp1W32 = k^2 in Q31 + + temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0 + temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; // temp1W32 = (1 - K[0]*K[0]) in Q31 + + // Store temp1W32 = 1 - K[0]*K[0] on hi and low format + tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); + + // Calculate Alpha in Q31 + temp1W32 = ((WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_hi) + + (WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_low) >> 15) + + (WEBRTC_SPL_MUL_16_16(R_low[0], tmp_hi) >> 15)) << 1); + + // Normalize Alpha and put it in hi and low format + + Alpha_exp = WebRtcSpl_NormW32(temp1W32); + temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp); + Alpha_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1); + + // Perform the iterative calculations in the Levinson-Durbin algorithm + + for (i = 2; i <= order; i++) + { + /* ---- + temp1W32 = R[i] + > R[j]*A[i-j] + / + ---- + j=1..i-1 + */ + + temp1W32 = 0; + + for (j = 1; j < i; j++) + { + // temp1W32 is in Q31 + temp1W32 += ((WEBRTC_SPL_MUL_16_16(R_hi[j], A_hi[i-j]) << 1) + + (((WEBRTC_SPL_MUL_16_16(R_hi[j], A_low[i-j]) >> 15) + + (WEBRTC_SPL_MUL_16_16(R_low[j], A_hi[i-j]) >> 15)) << 1)); + } + + temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, 4); + temp1W32 += (WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16) + + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[i], 1)); + + // K = -temp1W32 / Alpha + temp2W32 = WEBRTC_SPL_ABS_W32(temp1W32); // abs(temp1W32) + temp3W32 = WebRtcSpl_DivW32HiLow(temp2W32, Alpha_hi, Alpha_low); // abs(temp1W32)/Alpha + + // Put the sign of temp1W32 back again + if (temp1W32 > 0) + { + temp3W32 = -temp3W32; + } + + // Use the Alpha shifts from earlier to de-normalize + norm = WebRtcSpl_NormW32(temp3W32); + if ((Alpha_exp <= norm) || (temp3W32 == 0)) + { + temp3W32 = WEBRTC_SPL_LSHIFT_W32(temp3W32, Alpha_exp); + } else + { + if (temp3W32 > 0) + { + temp3W32 = (WebRtc_Word32)0x7fffffffL; + } else + { + temp3W32 = (WebRtc_Word32)0x80000000L; + } + } + + // Put K on hi and low format + K_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16); + K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32 + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1); + + // Store Reflection coefficient in Q15 + K[i - 1] = K_hi; + + // Test for unstable filter. + // If unstable return 0 and let the user decide what to do in that case + + if ((WebRtc_Word32)WEBRTC_SPL_ABS_W16(K_hi) > (WebRtc_Word32)32750) + { + return 0; // Unstable filter + } + + /* + Compute updated LPC coefficient: Anew[i] + Anew[j]= A[j] + K*A[i-j] for j=1..i-1 + Anew[i]= K + */ + + for (j = 1; j < i; j++) + { + // temp1W32 = A[j] in Q27 + temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[j],16) + + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[j],1); + + // temp1W32 += K*A[i-j] in Q27 + temp1W32 += ((WEBRTC_SPL_MUL_16_16(K_hi, A_hi[i-j]) + + (WEBRTC_SPL_MUL_16_16(K_hi, A_low[i-j]) >> 15) + + (WEBRTC_SPL_MUL_16_16(K_low, A_hi[i-j]) >> 15)) << 1); + + // Put Anew in hi and low format + A_upd_hi[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + A_upd_low[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[j], 16)), 1); + } + + // temp3W32 = K in Q27 (Convert from Q31 to Q27) + temp3W32 = WEBRTC_SPL_RSHIFT_W32(temp3W32, 4); + + // Store Anew in hi and low format + A_upd_hi[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16); + A_upd_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32 + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[i], 16)), 1); + + // Alpha = Alpha * (1-K^2) + + temp1W32 = (((WEBRTC_SPL_MUL_16_16(K_hi, K_low) >> 14) + + WEBRTC_SPL_MUL_16_16(K_hi, K_hi)) << 1); // K*K in Q31 + + temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0 + temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; // 1 - K*K in Q31 + + // Convert 1- K^2 in hi and low format + tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1); + + // Calculate Alpha = Alpha * (1-K^2) in Q31 + temp1W32 = ((WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_hi) + + (WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_low) >> 15) + + (WEBRTC_SPL_MUL_16_16(Alpha_low, tmp_hi) >> 15)) << 1); + + // Normalize Alpha and store it on hi and low format + + norm = WebRtcSpl_NormW32(temp1W32); + temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm); + + Alpha_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16); + Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 + - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1); + + // Update the total normalization of Alpha + Alpha_exp = Alpha_exp + norm; + + // Update A[] + + for (j = 1; j <= i; j++) + { + A_hi[j] = A_upd_hi[j]; + A_low[j] = A_upd_low[j]; + } + } + + /* + Set A[0] to 1.0 and store the A[i] i=1...order in Q12 + (Convert from Q27 and use rounding) + */ + + A[0] = 4096; + + for (i = 1; i <= order; i++) + { + // temp1W32 in Q27 + temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[i], 16) + + WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[i], 1); + // Round and store upper word + A[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32<<1)+(WebRtc_Word32)32768, 16); + } + return 1; // Stable filters +} diff --git a/src/libs/webrtc/signal_processing_library/lpc_to_refl_coef.c b/src/libs/webrtc/signal_processing_library/lpc_to_refl_coef.c new file mode 100644 index 00000000..2cb83c2e --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/lpc_to_refl_coef.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_LpcToReflCoef(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#define SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER 50 + +void WebRtcSpl_LpcToReflCoef(WebRtc_Word16* a16, int use_order, WebRtc_Word16* k16) +{ + int m, k; + WebRtc_Word32 tmp32[SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER]; + WebRtc_Word32 tmp_inv_denom32; + WebRtc_Word16 tmp_inv_denom16; + + k16[use_order - 1] = WEBRTC_SPL_LSHIFT_W16(a16[use_order], 3); //Q12<<3 => Q15 + for (m = use_order - 1; m > 0; m--) + { + // (1 - k^2) in Q30 + tmp_inv_denom32 = ((WebRtc_Word32)1073741823) - WEBRTC_SPL_MUL_16_16(k16[m], k16[m]); + // (1 - k^2) in Q15 + tmp_inv_denom16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp_inv_denom32, 15); + + for (k = 1; k <= m; k++) + { + // tmp[k] = (a[k] - RC[m] * a[m-k+1]) / (1.0 - RC[m]*RC[m]); + + // [Q12<<16 - (Q15*Q12)<<1] = [Q28 - Q28] = Q28 + tmp32[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)a16[k], 16) + - WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(k16[m], a16[m-k+1]), 1); + + tmp32[k] = WebRtcSpl_DivW32W16(tmp32[k], tmp_inv_denom16); //Q28/Q15 = Q13 + } + + for (k = 1; k < m; k++) + { + a16[k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32[k], 1); //Q13>>1 => Q12 + } + + tmp32[m] = WEBRTC_SPL_SAT(8191, tmp32[m], -8191); + k16[m - 1] = (WebRtc_Word16)WEBRTC_SPL_LSHIFT_W32(tmp32[m], 2); //Q13<<2 => Q15 + } + return; +} diff --git a/src/libs/webrtc/signal_processing_library/min_max_operations.c b/src/libs/webrtc/signal_processing_library/min_max_operations.c new file mode 100644 index 00000000..cf5e9a7d --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/min_max_operations.c @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the implementation of functions + * WebRtcSpl_MaxAbsValueW16() + * WebRtcSpl_MaxAbsIndexW16() + * WebRtcSpl_MaxAbsValueW32() + * WebRtcSpl_MaxValueW16() + * WebRtcSpl_MaxIndexW16() + * WebRtcSpl_MaxValueW32() + * WebRtcSpl_MaxIndexW32() + * WebRtcSpl_MinValueW16() + * WebRtcSpl_MinIndexW16() + * WebRtcSpl_MinValueW32() + * WebRtcSpl_MinIndexW32() + * + * The description header can be found in signal_processing_library.h. + * + */ + +#include "signal_processing_library.h" + +// Maximum absolute value of word16 vector. +WebRtc_Word16 WebRtcSpl_MaxAbsValueW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length) +{ + WebRtc_Word32 tempMax = 0; + WebRtc_Word32 absVal; + WebRtc_Word16 totMax; + int i; + G_CONST WebRtc_Word16 *tmpvector = vector; + +#ifdef _ARM_OPT_ +#pragma message("NOTE: _ARM_OPT_ optimizations are used") + + WebRtc_Word16 len4 = (length >> 2) << 2; + + for (i = 0; i < len4; i = i + 4) + { + absVal = WEBRTC_SPL_ABS_W32((*tmpvector)); + if (absVal > tempMax) + { + tempMax = absVal; + } + tmpvector++; + absVal = WEBRTC_SPL_ABS_W32((*tmpvector)); + if (absVal > tempMax) + { + tempMax = absVal; + } + tmpvector++; + absVal = WEBRTC_SPL_ABS_W32((*tmpvector)); + if (absVal > tempMax) + { + tempMax = absVal; + } + tmpvector++; + absVal = WEBRTC_SPL_ABS_W32((*tmpvector)); + if (absVal > tempMax) + { + tempMax = absVal; + } + tmpvector++; + } + + for (i = len4; i < len; i++) + { + absVal = WEBRTC_SPL_ABS_W32((*tmpvector)); + if (absVal > tempMax) + { + tempMax = absVal; + } + tmpvector++; + } +#else + for (i = 0; i < length; i++) + { + absVal = WEBRTC_SPL_ABS_W32((*tmpvector)); + if (absVal > tempMax) + { + tempMax = absVal; + } + tmpvector++; + } + totMax = (WebRtc_Word16)WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD16_MAX); + return totMax; +#endif +} + +// Index of maximum absolute value in a word16 vector. +WebRtc_Word16 WebRtcSpl_MaxAbsIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length) +{ + WebRtc_Word16 tempMax; + WebRtc_Word16 absTemp; + WebRtc_Word16 tempMaxIndex = 0; + WebRtc_Word16 i = 0; + G_CONST WebRtc_Word16 *tmpvector = vector; + + tempMax = WEBRTC_SPL_ABS_W16(*tmpvector); + tmpvector++; + for (i = 1; i < length; i++) + { + absTemp = WEBRTC_SPL_ABS_W16(*tmpvector); + tmpvector++; + if (absTemp > tempMax) + { + tempMax = absTemp; + tempMaxIndex = i; + } + } + return tempMaxIndex; +} + +// Maximum absolute value of word32 vector. +WebRtc_Word32 WebRtcSpl_MaxAbsValueW32(G_CONST WebRtc_Word32 *vector, WebRtc_Word16 length) +{ + WebRtc_UWord32 tempMax = 0; + WebRtc_UWord32 absVal; + WebRtc_Word32 retval; + int i; + G_CONST WebRtc_Word32 *tmpvector = vector; + + for (i = 0; i < length; i++) + { + absVal = WEBRTC_SPL_ABS_W32((*tmpvector)); + if (absVal > tempMax) + { + tempMax = absVal; + } + tmpvector++; + } + retval = (WebRtc_Word32)(WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD32_MAX)); + return retval; +} + +// Maximum value of word16 vector. +#ifndef XSCALE_OPT +WebRtc_Word16 WebRtcSpl_MaxValueW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length) +{ + WebRtc_Word16 tempMax; + WebRtc_Word16 i; + G_CONST WebRtc_Word16 *tmpvector = vector; + + tempMax = *tmpvector++; + for (i = 1; i < length; i++) + { + if (*tmpvector++ > tempMax) + tempMax = vector[i]; + } + return tempMax; +} +#else +#pragma message(">> WebRtcSpl_MaxValueW16 is excluded from this build") +#endif + +// Index of maximum value in a word16 vector. +WebRtc_Word16 WebRtcSpl_MaxIndexW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length) +{ + WebRtc_Word16 tempMax; + WebRtc_Word16 tempMaxIndex = 0; + WebRtc_Word16 i = 0; + G_CONST WebRtc_Word16 *tmpvector = vector; + + tempMax = *tmpvector++; + for (i = 1; i < length; i++) + { + if (*tmpvector++ > tempMax) + { + tempMax = vector[i]; + tempMaxIndex = i; + } + } + return tempMaxIndex; +} + +// Maximum value of word32 vector. +#ifndef XSCALE_OPT +WebRtc_Word32 WebRtcSpl_MaxValueW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length) +{ + WebRtc_Word32 tempMax; + WebRtc_Word16 i; + G_CONST WebRtc_Word32 *tmpvector = vector; + + tempMax = *tmpvector++; + for (i = 1; i < length; i++) + { + if (*tmpvector++ > tempMax) + tempMax = vector[i]; + } + return tempMax; +} +#else +#pragma message(">> WebRtcSpl_MaxValueW32 is excluded from this build") +#endif + +// Index of maximum value in a word32 vector. +WebRtc_Word16 WebRtcSpl_MaxIndexW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length) +{ + WebRtc_Word32 tempMax; + WebRtc_Word16 tempMaxIndex = 0; + WebRtc_Word16 i = 0; + G_CONST WebRtc_Word32 *tmpvector = vector; + + tempMax = *tmpvector++; + for (i = 1; i < length; i++) + { + if (*tmpvector++ > tempMax) + { + tempMax = vector[i]; + tempMaxIndex = i; + } + } + return tempMaxIndex; +} + +// Minimum value of word16 vector. +WebRtc_Word16 WebRtcSpl_MinValueW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length) +{ + WebRtc_Word16 tempMin; + WebRtc_Word16 i; + G_CONST WebRtc_Word16 *tmpvector = vector; + + // Find the minimum value + tempMin = *tmpvector++; + for (i = 1; i < length; i++) + { + if (*tmpvector++ < tempMin) + tempMin = (vector[i]); + } + return tempMin; +} + +// Index of minimum value in a word16 vector. +#ifndef XSCALE_OPT +WebRtc_Word16 WebRtcSpl_MinIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length) +{ + WebRtc_Word16 tempMin; + WebRtc_Word16 tempMinIndex = 0; + WebRtc_Word16 i = 0; + G_CONST WebRtc_Word16* tmpvector = vector; + + // Find index of smallest value + tempMin = *tmpvector++; + for (i = 1; i < length; i++) + { + if (*tmpvector++ < tempMin) + { + tempMin = vector[i]; + tempMinIndex = i; + } + } + return tempMinIndex; +} +#else +#pragma message(">> WebRtcSpl_MinIndexW16 is excluded from this build") +#endif + +// Minimum value of word32 vector. +WebRtc_Word32 WebRtcSpl_MinValueW32(G_CONST WebRtc_Word32 *vector, WebRtc_Word16 length) +{ + WebRtc_Word32 tempMin; + WebRtc_Word16 i; + G_CONST WebRtc_Word32 *tmpvector = vector; + + // Find the minimum value + tempMin = *tmpvector++; + for (i = 1; i < length; i++) + { + if (*tmpvector++ < tempMin) + tempMin = (vector[i]); + } + return tempMin; +} + +// Index of minimum value in a word32 vector. +#ifndef XSCALE_OPT +WebRtc_Word16 WebRtcSpl_MinIndexW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length) +{ + WebRtc_Word32 tempMin; + WebRtc_Word16 tempMinIndex = 0; + WebRtc_Word16 i = 0; + G_CONST WebRtc_Word32 *tmpvector = vector; + + // Find index of smallest value + tempMin = *tmpvector++; + for (i = 1; i < length; i++) + { + if (*tmpvector++ < tempMin) + { + tempMin = vector[i]; + tempMinIndex = i; + } + } + return tempMinIndex; +} +#else +#pragma message(">> WebRtcSpl_MinIndexW32 is excluded from this build") +#endif diff --git a/src/libs/webrtc/signal_processing_library/norm_u32.c b/src/libs/webrtc/signal_processing_library/norm_u32.c new file mode 100644 index 00000000..c903a646 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/norm_u32.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_NormU32(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS + +int WebRtcSpl_NormU32(WebRtc_UWord32 value) +{ + int zeros = 0; + + if (value == 0) + return 0; + + if (!(0xFFFF0000 & value)) + zeros = 16; + if (!(0xFF000000 & (value << zeros))) + zeros += 8; + if (!(0xF0000000 & (value << zeros))) + zeros += 4; + if (!(0xC0000000 & (value << zeros))) + zeros += 2; + if (!(0x80000000 & (value << zeros))) + zeros += 1; + + return zeros; +} +#endif diff --git a/src/libs/webrtc/signal_processing_library/norm_w16.c b/src/libs/webrtc/signal_processing_library/norm_w16.c new file mode 100644 index 00000000..be6711d5 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/norm_w16.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_NormW16(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS + +int WebRtcSpl_NormW16(WebRtc_Word16 value) +{ + int zeros = 0; + + if (value <= 0) + value ^= 0xFFFF; + + if ( !(0xFF80 & value)) + zeros = 8; + if ( !(0xF800 & (value << zeros))) + zeros += 4; + if ( !(0xE000 & (value << zeros))) + zeros += 2; + if ( !(0xC000 & (value << zeros))) + zeros += 1; + + return zeros; +} +#endif diff --git a/src/libs/webrtc/signal_processing_library/norm_w32.c b/src/libs/webrtc/signal_processing_library/norm_w32.c new file mode 100644 index 00000000..d4563350 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/norm_w32.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_NormW32(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS + +int WebRtcSpl_NormW32(WebRtc_Word32 value) +{ + int zeros = 0; + + if (value <= 0) + value ^= 0xFFFFFFFF; + + // Fast binary search to determine the number of left shifts required to 32-bit normalize + // the value + if (!(0xFFFF8000 & value)) + zeros = 16; + if (!(0xFF800000 & (value << zeros))) + zeros += 8; + if (!(0xF8000000 & (value << zeros))) + zeros += 4; + if (!(0xE0000000 & (value << zeros))) + zeros += 2; + if (!(0xC0000000 & (value << zeros))) + zeros += 1; + + return zeros; +} + +#endif diff --git a/src/libs/webrtc/signal_processing_library/randn_table.c b/src/libs/webrtc/signal_processing_library/randn_table.c new file mode 100644 index 00000000..734fa79a --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/randn_table.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * Table with 512 samples from a normal distribution with mean 1 and std 1 + * The values are shifted up 13 steps (multiplied by 8192) + */ + +#include "signal_processing_library.h" + +WebRtc_Word16 WebRtcSpl_kRandNTable[] = +{ + 9178, -7260, 40, 10189, 4894, -3531, -13779, 14764, + -4008, -8884, -8990, 1008, 7368, 5184, 3251, -5817, + -9786, 5963, 1770, 8066, -7135, 10772, -2298, 1361, + 6484, 2241, -8633, 792, 199, -3344, 6553, -10079, + -15040, 95, 11608, -12469, 14161, -4176, 2476, 6403, + 13685, -16005, 6646, 2239, 10916, -3004, -602, -3141, + 2142, 14144, -5829, 5305, 8209, 4713, 2697, -5112, + 16092, -1210, -2891, -6631, -5360, -11878, -6781, -2739, + -6392, 536, 10923, 10872, 5059, -4748, -7770, 5477, + 38, -1025, -2892, 1638, 6304, 14375, -11028, 1553, + -1565, 10762, -393, 4040, 5257, 12310, 6554, -4799, + 4899, -6354, 1603, -1048, -2220, 8247, -186, -8944, + -12004, 2332, 4801, -4933, 6371, 131, 8614, -5927, + -8287, -22760, 4033, -15162, 3385, 3246, 3153, -5250, + 3766, 784, 6494, -62, 3531, -1582, 15572, 662, + -3952, -330, -3196, 669, 7236, -2678, -6569, 23319, + -8645, -741, 14830, -15976, 4903, 315, -11342, 10311, + 1858, -7777, 2145, 5436, 5677, -113, -10033, 826, + -1353, 17210, 7768, 986, -1471, 8291, -4982, 8207, + -14911, -6255, -2449, -11881, -7059, -11703, -4338, 8025, + 7538, -2823, -12490, 9470, -1613, -2529, -10092, -7807, + 9480, 6970, -12844, 5123, 3532, 4816, 4803, -8455, + -5045, 14032, -4378, -1643, 5756, -11041, -2732, -16618, + -6430, -18375, -3320, 6098, 5131, -4269, -8840, 2482, + -7048, 1547, -21890, -6505, -7414, -424, -11722, 7955, + 1653, -17299, 1823, 473, -9232, 3337, 1111, 873, + 4018, -8982, 9889, 3531, -11763, -3799, 7373, -4539, + 3231, 7054, -8537, 7616, 6244, 16635, 447, -2915, + 13967, 705, -2669, -1520, -1771, -16188, 5956, 5117, + 6371, -9936, -1448, 2480, 5128, 7550, -8130, 5236, + 8213, -6443, 7707, -1950, -13811, 7218, 7031, -3883, + 67, 5731, -2874, 13480, -3743, 9298, -3280, 3552, + -4425, -18, -3785, -9988, -5357, 5477, -11794, 2117, + 1416, -9935, 3376, 802, -5079, -8243, 12652, 66, + 3653, -2368, 6781, -21895, -7227, 2487, 7839, -385, + 6646, -7016, -4658, 5531, -1705, 834, 129, 3694, + -1343, 2238, -22640, -6417, -11139, 11301, -2945, -3494, + -5626, 185, -3615, -2041, -7972, -3106, -60, -23497, + -1566, 17064, 3519, 2518, 304, -6805, -10269, 2105, + 1936, -426, -736, -8122, -1467, 4238, -6939, -13309, + 360, 7402, -7970, 12576, 3287, 12194, -6289, -16006, + 9171, 4042, -9193, 9123, -2512, 6388, -4734, -8739, + 1028, -5406, -1696, 5889, -666, -4736, 4971, 3565, + 9362, -6292, 3876, -3652, -19666, 7523, -4061, 391, + -11773, 7502, -3763, 4929, -9478, 13278, 2805, 4496, + 7814, 16419, 12455, -14773, 2127, -2746, 3763, 4847, + 3698, 6978, 4751, -6957, -3581, -45, 6252, 1513, + -4797, -7925, 11270, 16188, -2359, -5269, 9376, -10777, + 7262, 20031, -6515, -2208, -5353, 8085, -1341, -1303, + 7333, 5576, 3625, 5763, -7931, 9833, -3371, -10305, + 6534, -13539, -9971, 997, 8464, -4064, -1495, 1857, + 13624, 5458, 9490, -11086, -4524, 12022, -550, -198, + 408, -8455, -7068, 10289, 9712, -3366, 9028, -7621, + -5243, 2362, 6909, 4672, -4933, -1799, 4709, -4563, + -62, -566, 1624, -7010, 14730, -17791, -3697, -2344, + -1741, 7099, -9509, -6855, -1989, 3495, -2289, 2031, + 12784, 891, 14189, -3963, -5683, 421, -12575, 1724, + -12682, -5970, -8169, 3143, -1824, -5488, -5130, 8536, + 12799, 794, 5738, 3459, -11689, -258, -3738, -3775, + -8742, 2333, 8312, -9383, 10331, 13119, 8398, 10644, + -19433, -6446, -16277, -11793, 16284, 9345, 15222, 15834, + 2009, -7349, 130, -14547, 338, -5998, 3337, 21492, + 2406, 7703, -951, 11196, -564, 3406, 2217, 4806, + 2374, -5797, 11839, 8940, -11874, 18213, 2855, 10492 +}; diff --git a/src/libs/webrtc/signal_processing_library/randomization_functions.c b/src/libs/webrtc/signal_processing_library/randomization_functions.c new file mode 100644 index 00000000..6bc87c76 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/randomization_functions.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains implementations of the randomization functions + * WebRtcSpl_IncreaseSeed() + * WebRtcSpl_RandU() + * WebRtcSpl_RandN() + * WebRtcSpl_RandUArray() + * + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +WebRtc_UWord32 WebRtcSpl_IncreaseSeed(WebRtc_UWord32 *seed) +{ + seed[0] = (seed[0] * ((WebRtc_Word32)69069) + 1) & (WEBRTC_SPL_MAX_SEED_USED - 1); + return seed[0]; +} + +WebRtc_Word16 WebRtcSpl_RandU(WebRtc_UWord32 *seed) +{ + return (WebRtc_Word16)(WebRtcSpl_IncreaseSeed(seed) >> 16); +} + +WebRtc_Word16 WebRtcSpl_RandN(WebRtc_UWord32 *seed) +{ + return WebRtcSpl_kRandNTable[WebRtcSpl_IncreaseSeed(seed) >> 23]; +} + +// Creates an array of uniformly distributed variables +WebRtc_Word16 WebRtcSpl_RandUArray(WebRtc_Word16* vector, + WebRtc_Word16 vector_length, + WebRtc_UWord32* seed) +{ + int i; + for (i = 0; i < vector_length; i++) + { + vector[i] = WebRtcSpl_RandU(seed); + } + return vector_length; +} diff --git a/src/libs/webrtc/signal_processing_library/refl_coef_to_lpc.c b/src/libs/webrtc/signal_processing_library/refl_coef_to_lpc.c new file mode 100644 index 00000000..d07804de --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/refl_coef_to_lpc.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_ReflCoefToLpc(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16 *k, int use_order, WebRtc_Word16 *a) +{ + WebRtc_Word16 any[WEBRTC_SPL_MAX_LPC_ORDER + 1]; + WebRtc_Word16 *aptr, *aptr2, *anyptr; + G_CONST WebRtc_Word16 *kptr; + int m, i; + + kptr = k; + *a = 4096; // i.e., (Word16_MAX >> 3)+1. + *any = *a; + a[1] = WEBRTC_SPL_RSHIFT_W16((*k), 3); + + for (m = 1; m < use_order; m++) + { + kptr++; + aptr = a; + aptr++; + aptr2 = &a[m]; + anyptr = any; + anyptr++; + + any[m + 1] = WEBRTC_SPL_RSHIFT_W16((*kptr), 3); + for (i = 0; i < m; i++) + { + *anyptr = (*aptr) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((*aptr2), (*kptr), 15); + anyptr++; + aptr++; + aptr2--; + } + + aptr = a; + anyptr = any; + for (i = 0; i < (m + 2); i++) + { + *aptr = *anyptr; + aptr++; + anyptr++; + } + } +} diff --git a/src/libs/webrtc/signal_processing_library/resample.c b/src/libs/webrtc/signal_processing_library/resample.c new file mode 100644 index 00000000..19d17785 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/resample.c @@ -0,0 +1,505 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the resampling functions for 22 kHz. + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" +#include "resample_by_2_internal.h" + +// Declaration of internally used functions +static void WebRtcSpl_32khzTo22khzIntToShort(const WebRtc_Word32 *In, WebRtc_Word16 *Out, + const WebRtc_Word32 K); + +void WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32 *In, WebRtc_Word32 *Out, + const WebRtc_Word32 K); + +// interpolation coefficients +static const WebRtc_Word16 kCoefficients32To22[5][9] = { + {127, -712, 2359, -6333, 23456, 16775, -3695, 945, -154}, + {-39, 230, -830, 2785, 32366, -2324, 760, -218, 38}, + {117, -663, 2222, -6133, 26634, 13070, -3174, 831, -137}, + {-77, 457, -1677, 5958, 31175, -4136, 1405, -408, 71}, + { 98, -560, 1900, -5406, 29240, 9423, -2480, 663, -110} +}; + +////////////////////// +// 22 kHz -> 16 kHz // +////////////////////// + +// number of subblocks; options: 1, 2, 4, 5, 10 +#define SUB_BLOCKS_22_16 5 + +// 22 -> 16 resampler +void WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State22khzTo16khz* state, WebRtc_Word32* tmpmem) +{ + int k; + + // process two blocks of 10/SUB_BLOCKS_22_16 ms (to reduce temp buffer size) + for (k = 0; k < SUB_BLOCKS_22_16; k++) + { + ///// 22 --> 44 ///// + // WebRtc_Word16 in[220/SUB_BLOCKS_22_16] + // WebRtc_Word32 out[440/SUB_BLOCKS_22_16] + ///// + WebRtcSpl_UpBy2ShortToInt(in, 220 / SUB_BLOCKS_22_16, tmpmem + 16, state->S_22_44); + + ///// 44 --> 32 ///// + // WebRtc_Word32 in[440/SUB_BLOCKS_22_16] + // WebRtc_Word32 out[320/SUB_BLOCKS_22_16] + ///// + // copy state to and from input array + tmpmem[8] = state->S_44_32[0]; + tmpmem[9] = state->S_44_32[1]; + tmpmem[10] = state->S_44_32[2]; + tmpmem[11] = state->S_44_32[3]; + tmpmem[12] = state->S_44_32[4]; + tmpmem[13] = state->S_44_32[5]; + tmpmem[14] = state->S_44_32[6]; + tmpmem[15] = state->S_44_32[7]; + state->S_44_32[0] = tmpmem[440 / SUB_BLOCKS_22_16 + 8]; + state->S_44_32[1] = tmpmem[440 / SUB_BLOCKS_22_16 + 9]; + state->S_44_32[2] = tmpmem[440 / SUB_BLOCKS_22_16 + 10]; + state->S_44_32[3] = tmpmem[440 / SUB_BLOCKS_22_16 + 11]; + state->S_44_32[4] = tmpmem[440 / SUB_BLOCKS_22_16 + 12]; + state->S_44_32[5] = tmpmem[440 / SUB_BLOCKS_22_16 + 13]; + state->S_44_32[6] = tmpmem[440 / SUB_BLOCKS_22_16 + 14]; + state->S_44_32[7] = tmpmem[440 / SUB_BLOCKS_22_16 + 15]; + + WebRtcSpl_Resample44khzTo32khz(tmpmem + 8, tmpmem, 40 / SUB_BLOCKS_22_16); + + ///// 32 --> 16 ///// + // WebRtc_Word32 in[320/SUB_BLOCKS_22_16] + // WebRtc_Word32 out[160/SUB_BLOCKS_22_16] + ///// + WebRtcSpl_DownBy2IntToShort(tmpmem, 320 / SUB_BLOCKS_22_16, out, state->S_32_16); + + // move input/output pointers 10/SUB_BLOCKS_22_16 ms seconds ahead + in += 220 / SUB_BLOCKS_22_16; + out += 160 / SUB_BLOCKS_22_16; + } +} + +// initialize state of 22 -> 16 resampler +void WebRtcSpl_ResetResample22khzTo16khz(WebRtcSpl_State22khzTo16khz* state) +{ + int k; + for (k = 0; k < 8; k++) + { + state->S_22_44[k] = 0; + state->S_44_32[k] = 0; + state->S_32_16[k] = 0; + } +} + +////////////////////// +// 16 kHz -> 22 kHz // +////////////////////// + +// number of subblocks; options: 1, 2, 4, 5, 10 +#define SUB_BLOCKS_16_22 4 + +// 16 -> 22 resampler +void WebRtcSpl_Resample16khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State16khzTo22khz* state, WebRtc_Word32* tmpmem) +{ + int k; + + // process two blocks of 10/SUB_BLOCKS_16_22 ms (to reduce temp buffer size) + for (k = 0; k < SUB_BLOCKS_16_22; k++) + { + ///// 16 --> 32 ///// + // WebRtc_Word16 in[160/SUB_BLOCKS_16_22] + // WebRtc_Word32 out[320/SUB_BLOCKS_16_22] + ///// + WebRtcSpl_UpBy2ShortToInt(in, 160 / SUB_BLOCKS_16_22, tmpmem + 8, state->S_16_32); + + ///// 32 --> 22 ///// + // WebRtc_Word32 in[320/SUB_BLOCKS_16_22] + // WebRtc_Word32 out[220/SUB_BLOCKS_16_22] + ///// + // copy state to and from input array + tmpmem[0] = state->S_32_22[0]; + tmpmem[1] = state->S_32_22[1]; + tmpmem[2] = state->S_32_22[2]; + tmpmem[3] = state->S_32_22[3]; + tmpmem[4] = state->S_32_22[4]; + tmpmem[5] = state->S_32_22[5]; + tmpmem[6] = state->S_32_22[6]; + tmpmem[7] = state->S_32_22[7]; + state->S_32_22[0] = tmpmem[320 / SUB_BLOCKS_16_22]; + state->S_32_22[1] = tmpmem[320 / SUB_BLOCKS_16_22 + 1]; + state->S_32_22[2] = tmpmem[320 / SUB_BLOCKS_16_22 + 2]; + state->S_32_22[3] = tmpmem[320 / SUB_BLOCKS_16_22 + 3]; + state->S_32_22[4] = tmpmem[320 / SUB_BLOCKS_16_22 + 4]; + state->S_32_22[5] = tmpmem[320 / SUB_BLOCKS_16_22 + 5]; + state->S_32_22[6] = tmpmem[320 / SUB_BLOCKS_16_22 + 6]; + state->S_32_22[7] = tmpmem[320 / SUB_BLOCKS_16_22 + 7]; + + WebRtcSpl_32khzTo22khzIntToShort(tmpmem, out, 20 / SUB_BLOCKS_16_22); + + // move input/output pointers 10/SUB_BLOCKS_16_22 ms seconds ahead + in += 160 / SUB_BLOCKS_16_22; + out += 220 / SUB_BLOCKS_16_22; + } +} + +// initialize state of 16 -> 22 resampler +void WebRtcSpl_ResetResample16khzTo22khz(WebRtcSpl_State16khzTo22khz* state) +{ + int k; + for (k = 0; k < 8; k++) + { + state->S_16_32[k] = 0; + state->S_32_22[k] = 0; + } +} + +////////////////////// +// 22 kHz -> 8 kHz // +////////////////////// + +// number of subblocks; options: 1, 2, 5, 10 +#define SUB_BLOCKS_22_8 2 + +// 22 -> 8 resampler +void WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State22khzTo8khz* state, WebRtc_Word32* tmpmem) +{ + int k; + + // process two blocks of 10/SUB_BLOCKS_22_8 ms (to reduce temp buffer size) + for (k = 0; k < SUB_BLOCKS_22_8; k++) + { + ///// 22 --> 22 lowpass ///// + // WebRtc_Word16 in[220/SUB_BLOCKS_22_8] + // WebRtc_Word32 out[220/SUB_BLOCKS_22_8] + ///// + WebRtcSpl_LPBy2ShortToInt(in, 220 / SUB_BLOCKS_22_8, tmpmem + 16, state->S_22_22); + + ///// 22 --> 16 ///// + // WebRtc_Word32 in[220/SUB_BLOCKS_22_8] + // WebRtc_Word32 out[160/SUB_BLOCKS_22_8] + ///// + // copy state to and from input array + tmpmem[8] = state->S_22_16[0]; + tmpmem[9] = state->S_22_16[1]; + tmpmem[10] = state->S_22_16[2]; + tmpmem[11] = state->S_22_16[3]; + tmpmem[12] = state->S_22_16[4]; + tmpmem[13] = state->S_22_16[5]; + tmpmem[14] = state->S_22_16[6]; + tmpmem[15] = state->S_22_16[7]; + state->S_22_16[0] = tmpmem[220 / SUB_BLOCKS_22_8 + 8]; + state->S_22_16[1] = tmpmem[220 / SUB_BLOCKS_22_8 + 9]; + state->S_22_16[2] = tmpmem[220 / SUB_BLOCKS_22_8 + 10]; + state->S_22_16[3] = tmpmem[220 / SUB_BLOCKS_22_8 + 11]; + state->S_22_16[4] = tmpmem[220 / SUB_BLOCKS_22_8 + 12]; + state->S_22_16[5] = tmpmem[220 / SUB_BLOCKS_22_8 + 13]; + state->S_22_16[6] = tmpmem[220 / SUB_BLOCKS_22_8 + 14]; + state->S_22_16[7] = tmpmem[220 / SUB_BLOCKS_22_8 + 15]; + + WebRtcSpl_Resample44khzTo32khz(tmpmem + 8, tmpmem, 20 / SUB_BLOCKS_22_8); + + ///// 16 --> 8 ///// + // WebRtc_Word32 in[160/SUB_BLOCKS_22_8] + // WebRtc_Word32 out[80/SUB_BLOCKS_22_8] + ///// + WebRtcSpl_DownBy2IntToShort(tmpmem, 160 / SUB_BLOCKS_22_8, out, state->S_16_8); + + // move input/output pointers 10/SUB_BLOCKS_22_8 ms seconds ahead + in += 220 / SUB_BLOCKS_22_8; + out += 80 / SUB_BLOCKS_22_8; + } +} + +// initialize state of 22 -> 8 resampler +void WebRtcSpl_ResetResample22khzTo8khz(WebRtcSpl_State22khzTo8khz* state) +{ + int k; + for (k = 0; k < 8; k++) + { + state->S_22_22[k] = 0; + state->S_22_22[k + 8] = 0; + state->S_22_16[k] = 0; + state->S_16_8[k] = 0; + } +} + +////////////////////// +// 8 kHz -> 22 kHz // +////////////////////// + +// number of subblocks; options: 1, 2, 5, 10 +#define SUB_BLOCKS_8_22 2 + +// 8 -> 22 resampler +void WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State8khzTo22khz* state, WebRtc_Word32* tmpmem) +{ + int k; + + // process two blocks of 10/SUB_BLOCKS_8_22 ms (to reduce temp buffer size) + for (k = 0; k < SUB_BLOCKS_8_22; k++) + { + ///// 8 --> 16 ///// + // WebRtc_Word16 in[80/SUB_BLOCKS_8_22] + // WebRtc_Word32 out[160/SUB_BLOCKS_8_22] + ///// + WebRtcSpl_UpBy2ShortToInt(in, 80 / SUB_BLOCKS_8_22, tmpmem + 18, state->S_8_16); + + ///// 16 --> 11 ///// + // WebRtc_Word32 in[160/SUB_BLOCKS_8_22] + // WebRtc_Word32 out[110/SUB_BLOCKS_8_22] + ///// + // copy state to and from input array + tmpmem[10] = state->S_16_11[0]; + tmpmem[11] = state->S_16_11[1]; + tmpmem[12] = state->S_16_11[2]; + tmpmem[13] = state->S_16_11[3]; + tmpmem[14] = state->S_16_11[4]; + tmpmem[15] = state->S_16_11[5]; + tmpmem[16] = state->S_16_11[6]; + tmpmem[17] = state->S_16_11[7]; + state->S_16_11[0] = tmpmem[160 / SUB_BLOCKS_8_22 + 10]; + state->S_16_11[1] = tmpmem[160 / SUB_BLOCKS_8_22 + 11]; + state->S_16_11[2] = tmpmem[160 / SUB_BLOCKS_8_22 + 12]; + state->S_16_11[3] = tmpmem[160 / SUB_BLOCKS_8_22 + 13]; + state->S_16_11[4] = tmpmem[160 / SUB_BLOCKS_8_22 + 14]; + state->S_16_11[5] = tmpmem[160 / SUB_BLOCKS_8_22 + 15]; + state->S_16_11[6] = tmpmem[160 / SUB_BLOCKS_8_22 + 16]; + state->S_16_11[7] = tmpmem[160 / SUB_BLOCKS_8_22 + 17]; + + WebRtcSpl_32khzTo22khzIntToInt(tmpmem + 10, tmpmem, 10 / SUB_BLOCKS_8_22); + + ///// 11 --> 22 ///// + // WebRtc_Word32 in[110/SUB_BLOCKS_8_22] + // WebRtc_Word16 out[220/SUB_BLOCKS_8_22] + ///// + WebRtcSpl_UpBy2IntToShort(tmpmem, 110 / SUB_BLOCKS_8_22, out, state->S_11_22); + + // move input/output pointers 10/SUB_BLOCKS_8_22 ms seconds ahead + in += 80 / SUB_BLOCKS_8_22; + out += 220 / SUB_BLOCKS_8_22; + } +} + +// initialize state of 8 -> 22 resampler +void WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz* state) +{ + int k; + for (k = 0; k < 8; k++) + { + state->S_8_16[k] = 0; + state->S_16_11[k] = 0; + state->S_11_22[k] = 0; + } +} + +// compute two inner-products and store them to output array +static void WebRtcSpl_DotProdIntToInt(const WebRtc_Word32* in1, const WebRtc_Word32* in2, + const WebRtc_Word16* coef_ptr, WebRtc_Word32* out1, + WebRtc_Word32* out2) +{ + WebRtc_Word32 tmp1 = 16384; + WebRtc_Word32 tmp2 = 16384; + WebRtc_Word16 coef; + + coef = coef_ptr[0]; + tmp1 += coef * in1[0]; + tmp2 += coef * in2[-0]; + + coef = coef_ptr[1]; + tmp1 += coef * in1[1]; + tmp2 += coef * in2[-1]; + + coef = coef_ptr[2]; + tmp1 += coef * in1[2]; + tmp2 += coef * in2[-2]; + + coef = coef_ptr[3]; + tmp1 += coef * in1[3]; + tmp2 += coef * in2[-3]; + + coef = coef_ptr[4]; + tmp1 += coef * in1[4]; + tmp2 += coef * in2[-4]; + + coef = coef_ptr[5]; + tmp1 += coef * in1[5]; + tmp2 += coef * in2[-5]; + + coef = coef_ptr[6]; + tmp1 += coef * in1[6]; + tmp2 += coef * in2[-6]; + + coef = coef_ptr[7]; + tmp1 += coef * in1[7]; + tmp2 += coef * in2[-7]; + + coef = coef_ptr[8]; + *out1 = tmp1 + coef * in1[8]; + *out2 = tmp2 + coef * in2[-8]; +} + +// compute two inner-products and store them to output array +static void WebRtcSpl_DotProdIntToShort(const WebRtc_Word32* in1, const WebRtc_Word32* in2, + const WebRtc_Word16* coef_ptr, WebRtc_Word16* out1, + WebRtc_Word16* out2) +{ + WebRtc_Word32 tmp1 = 16384; + WebRtc_Word32 tmp2 = 16384; + WebRtc_Word16 coef; + + coef = coef_ptr[0]; + tmp1 += coef * in1[0]; + tmp2 += coef * in2[-0]; + + coef = coef_ptr[1]; + tmp1 += coef * in1[1]; + tmp2 += coef * in2[-1]; + + coef = coef_ptr[2]; + tmp1 += coef * in1[2]; + tmp2 += coef * in2[-2]; + + coef = coef_ptr[3]; + tmp1 += coef * in1[3]; + tmp2 += coef * in2[-3]; + + coef = coef_ptr[4]; + tmp1 += coef * in1[4]; + tmp2 += coef * in2[-4]; + + coef = coef_ptr[5]; + tmp1 += coef * in1[5]; + tmp2 += coef * in2[-5]; + + coef = coef_ptr[6]; + tmp1 += coef * in1[6]; + tmp2 += coef * in2[-6]; + + coef = coef_ptr[7]; + tmp1 += coef * in1[7]; + tmp2 += coef * in2[-7]; + + coef = coef_ptr[8]; + tmp1 += coef * in1[8]; + tmp2 += coef * in2[-8]; + + // scale down, round and saturate + tmp1 >>= 15; + if (tmp1 > (WebRtc_Word32)0x00007FFF) + tmp1 = 0x00007FFF; + if (tmp1 < (WebRtc_Word32)0xFFFF8000) + tmp1 = 0xFFFF8000; + tmp2 >>= 15; + if (tmp2 > (WebRtc_Word32)0x00007FFF) + tmp2 = 0x00007FFF; + if (tmp2 < (WebRtc_Word32)0xFFFF8000) + tmp2 = 0xFFFF8000; + *out1 = (WebRtc_Word16)tmp1; + *out2 = (WebRtc_Word16)tmp2; +} + +// Resampling ratio: 11/16 +// input: WebRtc_Word32 (normalized, not saturated) :: size 16 * K +// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 11 * K +// K: Number of blocks + +void WebRtcSpl_32khzTo22khzIntToInt(const WebRtc_Word32* In, + WebRtc_Word32* Out, + const WebRtc_Word32 K) +{ + ///////////////////////////////////////////////////////////// + // Filter operation: + // + // Perform resampling (16 input samples -> 11 output samples); + // process in sub blocks of size 16 samples. + WebRtc_Word32 m; + + for (m = 0; m < K; m++) + { + // first output sample + Out[0] = ((WebRtc_Word32)In[3] << 15) + (1 << 14); + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_DotProdIntToInt(&In[0], &In[22], kCoefficients32To22[0], &Out[1], &Out[10]); + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_DotProdIntToInt(&In[2], &In[20], kCoefficients32To22[1], &Out[2], &Out[9]); + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_DotProdIntToInt(&In[3], &In[19], kCoefficients32To22[2], &Out[3], &Out[8]); + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_DotProdIntToInt(&In[5], &In[17], kCoefficients32To22[3], &Out[4], &Out[7]); + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_DotProdIntToInt(&In[6], &In[16], kCoefficients32To22[4], &Out[5], &Out[6]); + + // update pointers + In += 16; + Out += 11; + } +} + +// Resampling ratio: 11/16 +// input: WebRtc_Word32 (normalized, not saturated) :: size 16 * K +// output: WebRtc_Word16 (saturated) :: size 11 * K +// K: Number of blocks + +void WebRtcSpl_32khzTo22khzIntToShort(const WebRtc_Word32 *In, + WebRtc_Word16 *Out, + const WebRtc_Word32 K) +{ + ///////////////////////////////////////////////////////////// + // Filter operation: + // + // Perform resampling (16 input samples -> 11 output samples); + // process in sub blocks of size 16 samples. + WebRtc_Word32 tmp; + WebRtc_Word32 m; + + for (m = 0; m < K; m++) + { + // first output sample + tmp = In[3]; + if (tmp > (WebRtc_Word32)0x00007FFF) + tmp = 0x00007FFF; + if (tmp < (WebRtc_Word32)0xFFFF8000) + tmp = 0xFFFF8000; + Out[0] = (WebRtc_Word16)tmp; + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_DotProdIntToShort(&In[0], &In[22], kCoefficients32To22[0], &Out[1], &Out[10]); + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_DotProdIntToShort(&In[2], &In[20], kCoefficients32To22[1], &Out[2], &Out[9]); + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_DotProdIntToShort(&In[3], &In[19], kCoefficients32To22[2], &Out[3], &Out[8]); + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_DotProdIntToShort(&In[5], &In[17], kCoefficients32To22[3], &Out[4], &Out[7]); + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_DotProdIntToShort(&In[6], &In[16], kCoefficients32To22[4], &Out[5], &Out[6]); + + // update pointers + In += 16; + Out += 11; + } +} diff --git a/src/libs/webrtc/signal_processing_library/resample_48khz.c b/src/libs/webrtc/signal_processing_library/resample_48khz.c new file mode 100644 index 00000000..31cbe6b6 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/resample_48khz.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains resampling functions between 48 kHz and nb/wb. + * The description header can be found in signal_processing_library.h + * + */ + +#include <string.h> +#include "signal_processing_library.h" +#include "resample_by_2_internal.h" + +//////////////////////////// +///// 48 kHz -> 16 kHz ///// +//////////////////////////// + +// 48 -> 16 resampler +void WebRtcSpl_Resample48khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State48khzTo16khz* state, WebRtc_Word32* tmpmem) +{ + ///// 48 --> 48(LP) ///// + // WebRtc_Word16 in[480] + // WebRtc_Word32 out[480] + ///// + WebRtcSpl_LPBy2ShortToInt(in, 480, tmpmem + 16, state->S_48_48); + + ///// 48 --> 32 ///// + // WebRtc_Word32 in[480] + // WebRtc_Word32 out[320] + ///// + // copy state to and from input array + memcpy(tmpmem + 8, state->S_48_32, 8 * sizeof(WebRtc_Word32)); + memcpy(state->S_48_32, tmpmem + 488, 8 * sizeof(WebRtc_Word32)); + WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 160); + + ///// 32 --> 16 ///// + // WebRtc_Word32 in[320] + // WebRtc_Word16 out[160] + ///// + WebRtcSpl_DownBy2IntToShort(tmpmem, 320, out, state->S_32_16); +} + +// initialize state of 48 -> 16 resampler +void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state) +{ + memset(state->S_48_48, 0, 16 * sizeof(WebRtc_Word32)); + memset(state->S_48_32, 0, 8 * sizeof(WebRtc_Word32)); + memset(state->S_32_16, 0, 8 * sizeof(WebRtc_Word32)); +} + +//////////////////////////// +///// 16 kHz -> 48 kHz ///// +//////////////////////////// + +// 16 -> 48 resampler +void WebRtcSpl_Resample16khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State16khzTo48khz* state, WebRtc_Word32* tmpmem) +{ + ///// 16 --> 32 ///// + // WebRtc_Word16 in[160] + // WebRtc_Word32 out[320] + ///// + WebRtcSpl_UpBy2ShortToInt(in, 160, tmpmem + 16, state->S_16_32); + + ///// 32 --> 24 ///// + // WebRtc_Word32 in[320] + // WebRtc_Word32 out[240] + // copy state to and from input array + ///// + memcpy(tmpmem + 8, state->S_32_24, 8 * sizeof(WebRtc_Word32)); + memcpy(state->S_32_24, tmpmem + 328, 8 * sizeof(WebRtc_Word32)); + WebRtcSpl_Resample32khzTo24khz(tmpmem + 8, tmpmem, 80); + + ///// 24 --> 48 ///// + // WebRtc_Word32 in[240] + // WebRtc_Word16 out[480] + ///// + WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48); +} + +// initialize state of 16 -> 48 resampler +void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state) +{ + memset(state->S_16_32, 0, 8 * sizeof(WebRtc_Word32)); + memset(state->S_32_24, 0, 8 * sizeof(WebRtc_Word32)); + memset(state->S_24_48, 0, 8 * sizeof(WebRtc_Word32)); +} + +//////////////////////////// +///// 48 kHz -> 8 kHz ///// +//////////////////////////// + +// 48 -> 8 resampler +void WebRtcSpl_Resample48khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State48khzTo8khz* state, WebRtc_Word32* tmpmem) +{ + ///// 48 --> 24 ///// + // WebRtc_Word16 in[480] + // WebRtc_Word32 out[240] + ///// + WebRtcSpl_DownBy2ShortToInt(in, 480, tmpmem + 256, state->S_48_24); + + ///// 24 --> 24(LP) ///// + // WebRtc_Word32 in[240] + // WebRtc_Word32 out[240] + ///// + WebRtcSpl_LPBy2IntToInt(tmpmem + 256, 240, tmpmem + 16, state->S_24_24); + + ///// 24 --> 16 ///// + // WebRtc_Word32 in[240] + // WebRtc_Word32 out[160] + ///// + // copy state to and from input array + memcpy(tmpmem + 8, state->S_24_16, 8 * sizeof(WebRtc_Word32)); + memcpy(state->S_24_16, tmpmem + 248, 8 * sizeof(WebRtc_Word32)); + WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 80); + + ///// 16 --> 8 ///// + // WebRtc_Word32 in[160] + // WebRtc_Word16 out[80] + ///// + WebRtcSpl_DownBy2IntToShort(tmpmem, 160, out, state->S_16_8); +} + +// initialize state of 48 -> 8 resampler +void WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state) +{ + memset(state->S_48_24, 0, 8 * sizeof(WebRtc_Word32)); + memset(state->S_24_24, 0, 16 * sizeof(WebRtc_Word32)); + memset(state->S_24_16, 0, 8 * sizeof(WebRtc_Word32)); + memset(state->S_16_8, 0, 8 * sizeof(WebRtc_Word32)); +} + +//////////////////////////// +///// 8 kHz -> 48 kHz ///// +//////////////////////////// + +// 8 -> 48 resampler +void WebRtcSpl_Resample8khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State8khzTo48khz* state, WebRtc_Word32* tmpmem) +{ + ///// 8 --> 16 ///// + // WebRtc_Word16 in[80] + // WebRtc_Word32 out[160] + ///// + WebRtcSpl_UpBy2ShortToInt(in, 80, tmpmem + 264, state->S_8_16); + + ///// 16 --> 12 ///// + // WebRtc_Word32 in[160] + // WebRtc_Word32 out[120] + ///// + // copy state to and from input array + memcpy(tmpmem + 256, state->S_16_12, 8 * sizeof(WebRtc_Word32)); + memcpy(state->S_16_12, tmpmem + 416, 8 * sizeof(WebRtc_Word32)); + WebRtcSpl_Resample32khzTo24khz(tmpmem + 256, tmpmem + 240, 40); + + ///// 12 --> 24 ///// + // WebRtc_Word32 in[120] + // WebRtc_Word16 out[240] + ///// + WebRtcSpl_UpBy2IntToInt(tmpmem + 240, 120, tmpmem, state->S_12_24); + + ///// 24 --> 48 ///// + // WebRtc_Word32 in[240] + // WebRtc_Word16 out[480] + ///// + WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48); +} + +// initialize state of 8 -> 48 resampler +void WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state) +{ + memset(state->S_8_16, 0, 8 * sizeof(WebRtc_Word32)); + memset(state->S_16_12, 0, 8 * sizeof(WebRtc_Word32)); + memset(state->S_12_24, 0, 8 * sizeof(WebRtc_Word32)); + memset(state->S_24_48, 0, 8 * sizeof(WebRtc_Word32)); +} diff --git a/src/libs/webrtc/signal_processing_library/resample_by_2.c b/src/libs/webrtc/signal_processing_library/resample_by_2.c new file mode 100644 index 00000000..7ed4cfde --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/resample_by_2.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the resampling by two functions. + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +// allpass filter coefficients. +static const WebRtc_UWord16 kResampleAllpass1[3] = {3284, 24441, 49528}; +static const WebRtc_UWord16 kResampleAllpass2[3] = {12199, 37471, 60255}; + +// decimator +void WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len, + WebRtc_Word16* out, WebRtc_Word32* filtState) +{ + const WebRtc_Word16 *inptr; + WebRtc_Word16 *outptr; + WebRtc_Word32 *state; + WebRtc_Word32 tmp1, tmp2, diff, in32, out32; + WebRtc_Word16 i; + + // local versions of pointers to input and output arrays + inptr = in; // input array + outptr = out; // output array (of length len/2) + state = filtState; // filter state array; length = 8 + + for (i = (len >> 1); i > 0; i--) + { + // lower allpass filter + in32 = (WebRtc_Word32)(*inptr++) << 10; + diff = in32 - state[1]; + tmp1 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[0], diff, state[0] ); + state[0] = in32; + diff = tmp1 - state[2]; + tmp2 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[1], diff, state[1] ); + state[1] = tmp1; + diff = tmp2 - state[3]; + state[3] = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[2], diff, state[2] ); + state[2] = tmp2; + + // upper allpass filter + in32 = (WebRtc_Word32)(*inptr++) << 10; + diff = in32 - state[5]; + tmp1 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[0], diff, state[4] ); + state[4] = in32; + diff = tmp1 - state[6]; + tmp2 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[1], diff, state[5] ); + state[5] = tmp1; + diff = tmp2 - state[7]; + state[7] = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[2], diff, state[6] ); + state[6] = tmp2; + + // add two allpass outputs, divide by two and round + out32 = (state[3] + state[7] + 1024) >> 11; + + // limit amplitude to prevent wrap-around, and write to output array + if (out32 > 32767) + *outptr++ = 32767; + else if (out32 < -32768) + *outptr++ = -32768; + else + *outptr++ = (WebRtc_Word16)out32; + } +} + +void WebRtcSpl_UpsampleBy2(const WebRtc_Word16* in, WebRtc_Word16 len, WebRtc_Word16* out, + WebRtc_Word32* filtState) +{ + const WebRtc_Word16 *inptr; + WebRtc_Word16 *outptr; + WebRtc_Word32 *state; + WebRtc_Word32 tmp1, tmp2, diff, in32, out32; + WebRtc_Word16 i; + + // local versions of pointers to input and output arrays + inptr = in; // input array + outptr = out; // output array (of length len*2) + state = filtState; // filter state array; length = 8 + + for (i = len; i > 0; i--) + { + // lower allpass filter + in32 = (WebRtc_Word32)(*inptr++) << 10; + diff = in32 - state[1]; + tmp1 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[0], diff, state[0] ); + state[0] = in32; + diff = tmp1 - state[2]; + tmp2 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[1], diff, state[1] ); + state[1] = tmp1; + diff = tmp2 - state[3]; + state[3] = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[2], diff, state[2] ); + state[2] = tmp2; + + // round; limit amplitude to prevent wrap-around; write to output array + out32 = (state[3] + 512) >> 10; + if (out32 > 32767) + *outptr++ = 32767; + else if (out32 < -32768) + *outptr++ = -32768; + else + *outptr++ = (WebRtc_Word16)out32; + + // upper allpass filter + diff = in32 - state[5]; + tmp1 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[0], diff, state[4] ); + state[4] = in32; + diff = tmp1 - state[6]; + tmp2 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[1], diff, state[5] ); + state[5] = tmp1; + diff = tmp2 - state[7]; + state[7] = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[2], diff, state[6] ); + state[6] = tmp2; + + // round; limit amplitude to prevent wrap-around; write to output array + out32 = (state[7] + 512) >> 10; + if (out32 > 32767) + *outptr++ = 32767; + else if (out32 < -32768) + *outptr++ = -32768; + else + *outptr++ = (WebRtc_Word16)out32; + } +} diff --git a/src/libs/webrtc/signal_processing_library/resample_by_2_internal.c b/src/libs/webrtc/signal_processing_library/resample_by_2_internal.c new file mode 100644 index 00000000..cbd23958 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/resample_by_2_internal.c @@ -0,0 +1,679 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file contains some internal resampling functions. + * + */ + +#include "resample_by_2_internal.h" + +// allpass filter coefficients. +static const WebRtc_Word16 kResampleAllpass[2][3] = { + {821, 6110, 12382}, + {3050, 9368, 15063} +}; + +// +// decimator +// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) OVERWRITTEN! +// output: WebRtc_Word16 (saturated) (of length len/2) +// state: filter state array; length = 8 + +void WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out, + WebRtc_Word32 *state) +{ + WebRtc_Word32 tmp0, tmp1, diff; + WebRtc_Word32 i; + + len >>= 1; + + // lower allpass filter (operates on even input samples) + for (i = 0; i < len; i++) + { + tmp0 = in[i << 1]; + diff = tmp0 - state[1]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[0] + diff * kResampleAllpass[1][0]; + state[0] = tmp0; + diff = tmp1 - state[2]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[1] + diff * kResampleAllpass[1][1]; + state[1] = tmp1; + diff = tmp0 - state[3]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[3] = state[2] + diff * kResampleAllpass[1][2]; + state[2] = tmp0; + + // divide by two and store temporarily + in[i << 1] = (state[3] >> 1); + } + + in++; + + // upper allpass filter (operates on odd input samples) + for (i = 0; i < len; i++) + { + tmp0 = in[i << 1]; + diff = tmp0 - state[5]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[4] + diff * kResampleAllpass[0][0]; + state[4] = tmp0; + diff = tmp1 - state[6]; + // scale down and round + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[5] + diff * kResampleAllpass[0][1]; + state[5] = tmp1; + diff = tmp0 - state[7]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[7] = state[6] + diff * kResampleAllpass[0][2]; + state[6] = tmp0; + + // divide by two and store temporarily + in[i << 1] = (state[7] >> 1); + } + + in--; + + // combine allpass outputs + for (i = 0; i < len; i += 2) + { + // divide by two, add both allpass outputs and round + tmp0 = (in[i << 1] + in[(i << 1) + 1]) >> 15; + tmp1 = (in[(i << 1) + 2] + in[(i << 1) + 3]) >> 15; + if (tmp0 > (WebRtc_Word32)0x00007FFF) + tmp0 = 0x00007FFF; + if (tmp0 < (WebRtc_Word32)0xFFFF8000) + tmp0 = 0xFFFF8000; + out[i] = (WebRtc_Word16)tmp0; + if (tmp1 > (WebRtc_Word32)0x00007FFF) + tmp1 = 0x00007FFF; + if (tmp1 < (WebRtc_Word32)0xFFFF8000) + tmp1 = 0xFFFF8000; + out[i + 1] = (WebRtc_Word16)tmp1; + } +} + +// +// decimator +// input: WebRtc_Word16 +// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len/2) +// state: filter state array; length = 8 + +void WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in, + WebRtc_Word32 len, + WebRtc_Word32 *out, + WebRtc_Word32 *state) +{ + WebRtc_Word32 tmp0, tmp1, diff; + WebRtc_Word32 i; + + len >>= 1; + + // lower allpass filter (operates on even input samples) + for (i = 0; i < len; i++) + { + tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); + diff = tmp0 - state[1]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[0] + diff * kResampleAllpass[1][0]; + state[0] = tmp0; + diff = tmp1 - state[2]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[1] + diff * kResampleAllpass[1][1]; + state[1] = tmp1; + diff = tmp0 - state[3]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[3] = state[2] + diff * kResampleAllpass[1][2]; + state[2] = tmp0; + + // divide by two and store temporarily + out[i] = (state[3] >> 1); + } + + in++; + + // upper allpass filter (operates on odd input samples) + for (i = 0; i < len; i++) + { + tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); + diff = tmp0 - state[5]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[4] + diff * kResampleAllpass[0][0]; + state[4] = tmp0; + diff = tmp1 - state[6]; + // scale down and round + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[5] + diff * kResampleAllpass[0][1]; + state[5] = tmp1; + diff = tmp0 - state[7]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[7] = state[6] + diff * kResampleAllpass[0][2]; + state[6] = tmp0; + + // divide by two and store temporarily + out[i] += (state[7] >> 1); + } + + in--; +} + +// +// interpolator +// input: WebRtc_Word16 +// output: WebRtc_Word32 (normalized, not saturated) (of length len*2) +// state: filter state array; length = 8 +void WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, WebRtc_Word32 *out, + WebRtc_Word32 *state) +{ + WebRtc_Word32 tmp0, tmp1, diff; + WebRtc_Word32 i; + + // upper allpass filter (generates odd output samples) + for (i = 0; i < len; i++) + { + tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14); + diff = tmp0 - state[5]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[4] + diff * kResampleAllpass[0][0]; + state[4] = tmp0; + diff = tmp1 - state[6]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[5] + diff * kResampleAllpass[0][1]; + state[5] = tmp1; + diff = tmp0 - state[7]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[7] = state[6] + diff * kResampleAllpass[0][2]; + state[6] = tmp0; + + // scale down, round and store + out[i << 1] = state[7] >> 15; + } + + out++; + + // lower allpass filter (generates even output samples) + for (i = 0; i < len; i++) + { + tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14); + diff = tmp0 - state[1]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[0] + diff * kResampleAllpass[1][0]; + state[0] = tmp0; + diff = tmp1 - state[2]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[1] + diff * kResampleAllpass[1][1]; + state[1] = tmp1; + diff = tmp0 - state[3]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[3] = state[2] + diff * kResampleAllpass[1][2]; + state[2] = tmp0; + + // scale down, round and store + out[i << 1] = state[3] >> 15; + } +} + +// +// interpolator +// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) +// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len*2) +// state: filter state array; length = 8 +void WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word32 *out, + WebRtc_Word32 *state) +{ + WebRtc_Word32 tmp0, tmp1, diff; + WebRtc_Word32 i; + + // upper allpass filter (generates odd output samples) + for (i = 0; i < len; i++) + { + tmp0 = in[i]; + diff = tmp0 - state[5]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[4] + diff * kResampleAllpass[0][0]; + state[4] = tmp0; + diff = tmp1 - state[6]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[5] + diff * kResampleAllpass[0][1]; + state[5] = tmp1; + diff = tmp0 - state[7]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[7] = state[6] + diff * kResampleAllpass[0][2]; + state[6] = tmp0; + + // scale down, round and store + out[i << 1] = state[7]; + } + + out++; + + // lower allpass filter (generates even output samples) + for (i = 0; i < len; i++) + { + tmp0 = in[i]; + diff = tmp0 - state[1]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[0] + diff * kResampleAllpass[1][0]; + state[0] = tmp0; + diff = tmp1 - state[2]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[1] + diff * kResampleAllpass[1][1]; + state[1] = tmp1; + diff = tmp0 - state[3]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[3] = state[2] + diff * kResampleAllpass[1][2]; + state[2] = tmp0; + + // scale down, round and store + out[i << 1] = state[3]; + } +} + +// +// interpolator +// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) +// output: WebRtc_Word16 (saturated) (of length len*2) +// state: filter state array; length = 8 +void WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out, + WebRtc_Word32 *state) +{ + WebRtc_Word32 tmp0, tmp1, diff; + WebRtc_Word32 i; + + // upper allpass filter (generates odd output samples) + for (i = 0; i < len; i++) + { + tmp0 = in[i]; + diff = tmp0 - state[5]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[4] + diff * kResampleAllpass[0][0]; + state[4] = tmp0; + diff = tmp1 - state[6]; + // scale down and round + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[5] + diff * kResampleAllpass[0][1]; + state[5] = tmp1; + diff = tmp0 - state[7]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[7] = state[6] + diff * kResampleAllpass[0][2]; + state[6] = tmp0; + + // scale down, saturate and store + tmp1 = state[7] >> 15; + if (tmp1 > (WebRtc_Word32)0x00007FFF) + tmp1 = 0x00007FFF; + if (tmp1 < (WebRtc_Word32)0xFFFF8000) + tmp1 = 0xFFFF8000; + out[i << 1] = (WebRtc_Word16)tmp1; + } + + out++; + + // lower allpass filter (generates even output samples) + for (i = 0; i < len; i++) + { + tmp0 = in[i]; + diff = tmp0 - state[1]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[0] + diff * kResampleAllpass[1][0]; + state[0] = tmp0; + diff = tmp1 - state[2]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[1] + diff * kResampleAllpass[1][1]; + state[1] = tmp1; + diff = tmp0 - state[3]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[3] = state[2] + diff * kResampleAllpass[1][2]; + state[2] = tmp0; + + // scale down, saturate and store + tmp1 = state[3] >> 15; + if (tmp1 > (WebRtc_Word32)0x00007FFF) + tmp1 = 0x00007FFF; + if (tmp1 < (WebRtc_Word32)0xFFFF8000) + tmp1 = 0xFFFF8000; + out[i << 1] = (WebRtc_Word16)tmp1; + } +} + +// lowpass filter +// input: WebRtc_Word16 +// output: WebRtc_Word32 (normalized, not saturated) +// state: filter state array; length = 8 +void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, WebRtc_Word32* out, + WebRtc_Word32* state) +{ + WebRtc_Word32 tmp0, tmp1, diff; + WebRtc_Word32 i; + + len >>= 1; + + // lower allpass filter: odd input -> even output samples + in++; + // initial state of polyphase delay element + tmp0 = state[12]; + for (i = 0; i < len; i++) + { + diff = tmp0 - state[1]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[0] + diff * kResampleAllpass[1][0]; + state[0] = tmp0; + diff = tmp1 - state[2]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[1] + diff * kResampleAllpass[1][1]; + state[1] = tmp1; + diff = tmp0 - state[3]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[3] = state[2] + diff * kResampleAllpass[1][2]; + state[2] = tmp0; + + // scale down, round and store + out[i << 1] = state[3] >> 1; + tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); + } + in--; + + // upper allpass filter: even input -> even output samples + for (i = 0; i < len; i++) + { + tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); + diff = tmp0 - state[5]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[4] + diff * kResampleAllpass[0][0]; + state[4] = tmp0; + diff = tmp1 - state[6]; + // scale down and round + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[5] + diff * kResampleAllpass[0][1]; + state[5] = tmp1; + diff = tmp0 - state[7]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[7] = state[6] + diff * kResampleAllpass[0][2]; + state[6] = tmp0; + + // average the two allpass outputs, scale down and store + out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15; + } + + // switch to odd output samples + out++; + + // lower allpass filter: even input -> odd output samples + for (i = 0; i < len; i++) + { + tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); + diff = tmp0 - state[9]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[8] + diff * kResampleAllpass[1][0]; + state[8] = tmp0; + diff = tmp1 - state[10]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[9] + diff * kResampleAllpass[1][1]; + state[9] = tmp1; + diff = tmp0 - state[11]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[11] = state[10] + diff * kResampleAllpass[1][2]; + state[10] = tmp0; + + // scale down, round and store + out[i << 1] = state[11] >> 1; + } + + // upper allpass filter: odd input -> odd output samples + in++; + for (i = 0; i < len; i++) + { + tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14); + diff = tmp0 - state[13]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[12] + diff * kResampleAllpass[0][0]; + state[12] = tmp0; + diff = tmp1 - state[14]; + // scale down and round + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[13] + diff * kResampleAllpass[0][1]; + state[13] = tmp1; + diff = tmp0 - state[15]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[15] = state[14] + diff * kResampleAllpass[0][2]; + state[14] = tmp0; + + // average the two allpass outputs, scale down and store + out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15; + } +} + +// lowpass filter +// input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) +// output: WebRtc_Word32 (normalized, not saturated) +// state: filter state array; length = 8 +void WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32* in, WebRtc_Word32 len, WebRtc_Word32* out, + WebRtc_Word32* state) +{ + WebRtc_Word32 tmp0, tmp1, diff; + WebRtc_Word32 i; + + len >>= 1; + + // lower allpass filter: odd input -> even output samples + in++; + // initial state of polyphase delay element + tmp0 = state[12]; + for (i = 0; i < len; i++) + { + diff = tmp0 - state[1]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[0] + diff * kResampleAllpass[1][0]; + state[0] = tmp0; + diff = tmp1 - state[2]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[1] + diff * kResampleAllpass[1][1]; + state[1] = tmp1; + diff = tmp0 - state[3]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[3] = state[2] + diff * kResampleAllpass[1][2]; + state[2] = tmp0; + + // scale down, round and store + out[i << 1] = state[3] >> 1; + tmp0 = in[i << 1]; + } + in--; + + // upper allpass filter: even input -> even output samples + for (i = 0; i < len; i++) + { + tmp0 = in[i << 1]; + diff = tmp0 - state[5]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[4] + diff * kResampleAllpass[0][0]; + state[4] = tmp0; + diff = tmp1 - state[6]; + // scale down and round + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[5] + diff * kResampleAllpass[0][1]; + state[5] = tmp1; + diff = tmp0 - state[7]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[7] = state[6] + diff * kResampleAllpass[0][2]; + state[6] = tmp0; + + // average the two allpass outputs, scale down and store + out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15; + } + + // switch to odd output samples + out++; + + // lower allpass filter: even input -> odd output samples + for (i = 0; i < len; i++) + { + tmp0 = in[i << 1]; + diff = tmp0 - state[9]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[8] + diff * kResampleAllpass[1][0]; + state[8] = tmp0; + diff = tmp1 - state[10]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[9] + diff * kResampleAllpass[1][1]; + state[9] = tmp1; + diff = tmp0 - state[11]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[11] = state[10] + diff * kResampleAllpass[1][2]; + state[10] = tmp0; + + // scale down, round and store + out[i << 1] = state[11] >> 1; + } + + // upper allpass filter: odd input -> odd output samples + in++; + for (i = 0; i < len; i++) + { + tmp0 = in[i << 1]; + diff = tmp0 - state[13]; + // scale down and round + diff = (diff + (1 << 13)) >> 14; + tmp1 = state[12] + diff * kResampleAllpass[0][0]; + state[12] = tmp0; + diff = tmp1 - state[14]; + // scale down and round + diff = diff >> 14; + if (diff < 0) + diff += 1; + tmp0 = state[13] + diff * kResampleAllpass[0][1]; + state[13] = tmp1; + diff = tmp0 - state[15]; + // scale down and truncate + diff = diff >> 14; + if (diff < 0) + diff += 1; + state[15] = state[14] + diff * kResampleAllpass[0][2]; + state[14] = tmp0; + + // average the two allpass outputs, scale down and store + out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15; + } +} diff --git a/src/libs/webrtc/signal_processing_library/resample_by_2_internal.h b/src/libs/webrtc/signal_processing_library/resample_by_2_internal.h new file mode 100644 index 00000000..b6ac9f0c --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/resample_by_2_internal.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file contains some internal resampling functions. + * + */ + +#ifndef WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_ +#define WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_ + +#include "typedefs.h" + +/******************************************************************* + * resample_by_2_fast.c + * Functions for internal use in the other resample functions + ******************************************************************/ +void WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out, + WebRtc_Word32 *state); + +void WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, + WebRtc_Word32 *out, WebRtc_Word32 *state); + +void WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, + WebRtc_Word32 *out, WebRtc_Word32 *state); + +void WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word32 *out, + WebRtc_Word32 *state); + +void WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len, + WebRtc_Word16 *out, WebRtc_Word32 *state); + +void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, + WebRtc_Word32* out, WebRtc_Word32* state); + +void WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32* in, WebRtc_Word32 len, WebRtc_Word32* out, + WebRtc_Word32* state); + +#endif // WEBRTC_SPL_RESAMPLE_BY_2_INTERNAL_H_ diff --git a/src/libs/webrtc/signal_processing_library/resample_fractional.c b/src/libs/webrtc/signal_processing_library/resample_fractional.c new file mode 100644 index 00000000..51003d45 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/resample_fractional.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the resampling functions between 48, 44, 32 and 24 kHz. + * The description headers can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +// interpolation coefficients +static const WebRtc_Word16 kCoefficients48To32[2][8] = { + {778, -2050, 1087, 23285, 12903, -3783, 441, 222}, + {222, 441, -3783, 12903, 23285, 1087, -2050, 778} +}; + +static const WebRtc_Word16 kCoefficients32To24[3][8] = { + {767, -2362, 2434, 24406, 10620, -3838, 721, 90}, + {386, -381, -2646, 19062, 19062, -2646, -381, 386}, + {90, 721, -3838, 10620, 24406, 2434, -2362, 767} +}; + +static const WebRtc_Word16 kCoefficients44To32[4][9] = { + {117, -669, 2245, -6183, 26267, 13529, -3245, 845, -138}, + {-101, 612, -2283, 8532, 29790, -5138, 1789, -524, 91}, + {50, -292, 1016, -3064, 32010, 3933, -1147, 315, -53}, + {-156, 974, -3863, 18603, 21691, -6246, 2353, -712, 126} +}; + +// Resampling ratio: 2/3 +// input: WebRtc_Word32 (normalized, not saturated) :: size 3 * K +// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 2 * K +// K: number of blocks + +void WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, + const WebRtc_Word32 K) +{ + ///////////////////////////////////////////////////////////// + // Filter operation: + // + // Perform resampling (3 input samples -> 2 output samples); + // process in sub blocks of size 3 samples. + WebRtc_Word32 tmp; + WebRtc_Word32 m; + + for (m = 0; m < K; m++) + { + tmp = 1 << 14; + tmp += kCoefficients48To32[0][0] * In[0]; + tmp += kCoefficients48To32[0][1] * In[1]; + tmp += kCoefficients48To32[0][2] * In[2]; + tmp += kCoefficients48To32[0][3] * In[3]; + tmp += kCoefficients48To32[0][4] * In[4]; + tmp += kCoefficients48To32[0][5] * In[5]; + tmp += kCoefficients48To32[0][6] * In[6]; + tmp += kCoefficients48To32[0][7] * In[7]; + Out[0] = tmp; + + tmp = 1 << 14; + tmp += kCoefficients48To32[1][0] * In[1]; + tmp += kCoefficients48To32[1][1] * In[2]; + tmp += kCoefficients48To32[1][2] * In[3]; + tmp += kCoefficients48To32[1][3] * In[4]; + tmp += kCoefficients48To32[1][4] * In[5]; + tmp += kCoefficients48To32[1][5] * In[6]; + tmp += kCoefficients48To32[1][6] * In[7]; + tmp += kCoefficients48To32[1][7] * In[8]; + Out[1] = tmp; + + // update pointers + In += 3; + Out += 2; + } +} + +// Resampling ratio: 3/4 +// input: WebRtc_Word32 (normalized, not saturated) :: size 4 * K +// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 3 * K +// K: number of blocks + +void WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, + const WebRtc_Word32 K) +{ + ///////////////////////////////////////////////////////////// + // Filter operation: + // + // Perform resampling (4 input samples -> 3 output samples); + // process in sub blocks of size 4 samples. + WebRtc_Word32 m; + WebRtc_Word32 tmp; + + for (m = 0; m < K; m++) + { + tmp = 1 << 14; + tmp += kCoefficients32To24[0][0] * In[0]; + tmp += kCoefficients32To24[0][1] * In[1]; + tmp += kCoefficients32To24[0][2] * In[2]; + tmp += kCoefficients32To24[0][3] * In[3]; + tmp += kCoefficients32To24[0][4] * In[4]; + tmp += kCoefficients32To24[0][5] * In[5]; + tmp += kCoefficients32To24[0][6] * In[6]; + tmp += kCoefficients32To24[0][7] * In[7]; + Out[0] = tmp; + + tmp = 1 << 14; + tmp += kCoefficients32To24[1][0] * In[1]; + tmp += kCoefficients32To24[1][1] * In[2]; + tmp += kCoefficients32To24[1][2] * In[3]; + tmp += kCoefficients32To24[1][3] * In[4]; + tmp += kCoefficients32To24[1][4] * In[5]; + tmp += kCoefficients32To24[1][5] * In[6]; + tmp += kCoefficients32To24[1][6] * In[7]; + tmp += kCoefficients32To24[1][7] * In[8]; + Out[1] = tmp; + + tmp = 1 << 14; + tmp += kCoefficients32To24[2][0] * In[2]; + tmp += kCoefficients32To24[2][1] * In[3]; + tmp += kCoefficients32To24[2][2] * In[4]; + tmp += kCoefficients32To24[2][3] * In[5]; + tmp += kCoefficients32To24[2][4] * In[6]; + tmp += kCoefficients32To24[2][5] * In[7]; + tmp += kCoefficients32To24[2][6] * In[8]; + tmp += kCoefficients32To24[2][7] * In[9]; + Out[2] = tmp; + + // update pointers + In += 4; + Out += 3; + } +} + +// +// fractional resampling filters +// Fout = 11/16 * Fin +// Fout = 8/11 * Fin +// + +// compute two inner-products and store them to output array +static void WebRtcSpl_ResampDotProduct(const WebRtc_Word32 *in1, const WebRtc_Word32 *in2, + const WebRtc_Word16 *coef_ptr, WebRtc_Word32 *out1, + WebRtc_Word32 *out2) +{ + WebRtc_Word32 tmp1 = 16384; + WebRtc_Word32 tmp2 = 16384; + WebRtc_Word16 coef; + + coef = coef_ptr[0]; + tmp1 += coef * in1[0]; + tmp2 += coef * in2[-0]; + + coef = coef_ptr[1]; + tmp1 += coef * in1[1]; + tmp2 += coef * in2[-1]; + + coef = coef_ptr[2]; + tmp1 += coef * in1[2]; + tmp2 += coef * in2[-2]; + + coef = coef_ptr[3]; + tmp1 += coef * in1[3]; + tmp2 += coef * in2[-3]; + + coef = coef_ptr[4]; + tmp1 += coef * in1[4]; + tmp2 += coef * in2[-4]; + + coef = coef_ptr[5]; + tmp1 += coef * in1[5]; + tmp2 += coef * in2[-5]; + + coef = coef_ptr[6]; + tmp1 += coef * in1[6]; + tmp2 += coef * in2[-6]; + + coef = coef_ptr[7]; + tmp1 += coef * in1[7]; + tmp2 += coef * in2[-7]; + + coef = coef_ptr[8]; + *out1 = tmp1 + coef * in1[8]; + *out2 = tmp2 + coef * in2[-8]; +} + +// Resampling ratio: 8/11 +// input: WebRtc_Word32 (normalized, not saturated) :: size 11 * K +// output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 8 * K +// K: number of blocks + +void WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, + const WebRtc_Word32 K) +{ + ///////////////////////////////////////////////////////////// + // Filter operation: + // + // Perform resampling (11 input samples -> 8 output samples); + // process in sub blocks of size 11 samples. + WebRtc_Word32 tmp; + WebRtc_Word32 m; + + for (m = 0; m < K; m++) + { + tmp = 1 << 14; + + // first output sample + Out[0] = ((WebRtc_Word32)In[3] << 15) + tmp; + + // sum and accumulate filter coefficients and input samples + tmp += kCoefficients44To32[3][0] * In[5]; + tmp += kCoefficients44To32[3][1] * In[6]; + tmp += kCoefficients44To32[3][2] * In[7]; + tmp += kCoefficients44To32[3][3] * In[8]; + tmp += kCoefficients44To32[3][4] * In[9]; + tmp += kCoefficients44To32[3][5] * In[10]; + tmp += kCoefficients44To32[3][6] * In[11]; + tmp += kCoefficients44To32[3][7] * In[12]; + tmp += kCoefficients44To32[3][8] * In[13]; + Out[4] = tmp; + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_ResampDotProduct(&In[0], &In[17], kCoefficients44To32[0], &Out[1], &Out[7]); + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_ResampDotProduct(&In[2], &In[15], kCoefficients44To32[1], &Out[2], &Out[6]); + + // sum and accumulate filter coefficients and input samples + WebRtcSpl_ResampDotProduct(&In[3], &In[14], kCoefficients44To32[2], &Out[3], &Out[5]); + + // update pointers + In += 11; + Out += 8; + } +} diff --git a/src/libs/webrtc/signal_processing_library/signal_processing_library.h b/src/libs/webrtc/signal_processing_library/signal_processing_library.h new file mode 100644 index 00000000..b59a236b --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/signal_processing_library.h @@ -0,0 +1,1753 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file includes all of the fix point signal processing library (SPL) function + * descriptions and declarations. + * For specific function calls, see bottom of file. + */ + +#ifndef WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_ +#define WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_ + +#include <string.h> +#include "typedefs.h" + +#ifdef ARM_WINM +#include <Armintr.h> // intrinsic file for windows mobile +#endif + +#ifdef WEBRTC_ANDROID +#define WEBRTC_SPL_INLINE_CALLS +#define SPL_NO_DOUBLE_IMPLEMENTATIONS +#endif + +// Macros specific for the fixed point implementation +#define WEBRTC_SPL_WORD16_MAX 32767 +#define WEBRTC_SPL_WORD16_MIN -32768 +#define WEBRTC_SPL_WORD32_MAX (WebRtc_Word32)0x7fffffff +#define WEBRTC_SPL_WORD32_MIN (WebRtc_Word32)0x80000000 +#define WEBRTC_SPL_MAX_LPC_ORDER 14 +#define WEBRTC_SPL_MAX_SEED_USED 0x80000000L +#define WEBRTC_SPL_MIN(A, B) (A < B ? A : B) // Get min value +#define WEBRTC_SPL_MAX(A, B) (A > B ? A : B) // Get max value +#define WEBRTC_SPL_ABS_W16(a)\ + (((WebRtc_Word16)a >= 0) ? ((WebRtc_Word16)a) : -((WebRtc_Word16)a)) +#define WEBRTC_SPL_ABS_W32(a)\ + (((WebRtc_Word32)a >= 0) ? ((WebRtc_Word32)a) : -((WebRtc_Word32)a)) + +#if (defined WEBRTC_TARGET_PC)||(defined __TARGET_XSCALE) +#define WEBRTC_SPL_GET_BYTE(a, nr) (((WebRtc_Word8 *)a)[nr]) +#define WEBRTC_SPL_SET_BYTE(d_ptr, val, index) \ + (((WebRtc_Word8 *)d_ptr)[index] = (val)) +#elif defined WEBRTC_BIG_ENDIAN +#define WEBRTC_SPL_GET_BYTE(a, nr)\ + ((((WebRtc_Word16 *)a)[nr >> 1]) >> (((nr + 1) & 0x1) * 8) & 0x00ff) +#define WEBRTC_SPL_SET_BYTE(d_ptr, val, index) \ + ((WebRtc_Word16 *)d_ptr)[index >> 1] = \ + ((((WebRtc_Word16 *)d_ptr)[index >> 1]) \ + & (0x00ff << (8 * ((index) & 0x1)))) | (val << (8 * ((index + 1) & 0x1))) +#else +#define WEBRTC_SPL_GET_BYTE(a,nr) \ + ((((WebRtc_Word16 *)(a))[(nr) >> 1]) >> (((nr) & 0x1) * 8) & 0x00ff) +#define WEBRTC_SPL_SET_BYTE(d_ptr, val, index) \ + ((WebRtc_Word16 *)(d_ptr))[(index) >> 1] = \ + ((((WebRtc_Word16 *)(d_ptr))[(index) >> 1]) \ + & (0x00ff << (8 * (((index) + 1) & 0x1)))) | \ + ((val) << (8 * ((index) & 0x1))) +#endif + +#ifndef WEBRTC_ANDROID +#define WEBRTC_SPL_MUL(a, b) \ + ((WebRtc_Word32) ((WebRtc_Word32)(a) * (WebRtc_Word32)(b))) +#endif + +#define WEBRTC_SPL_UMUL(a, b) \ + ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord32)(b))) +#define WEBRTC_SPL_UMUL_RSFT16(a, b)\ + ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord32)(b)) >> 16) +#define WEBRTC_SPL_UMUL_16_16(a, b)\ + ((WebRtc_UWord32) (WebRtc_UWord16)(a) * (WebRtc_UWord16)(b)) +#define WEBRTC_SPL_UMUL_16_16_RSFT16(a, b)\ + (((WebRtc_UWord32) (WebRtc_UWord16)(a) * (WebRtc_UWord16)(b)) >> 16) +#define WEBRTC_SPL_UMUL_32_16(a, b)\ + ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord16)(b))) +#define WEBRTC_SPL_UMUL_32_16_RSFT16(a, b)\ + ((WebRtc_UWord32) ((WebRtc_UWord32)(a) * (WebRtc_UWord16)(b)) >> 16) +#define WEBRTC_SPL_MUL_16_U16(a, b)\ + ((WebRtc_Word32)(WebRtc_Word16)(a) * (WebRtc_UWord16)(b)) +#define WEBRTC_SPL_DIV(a, b) \ + ((WebRtc_Word32) ((WebRtc_Word32)(a) / (WebRtc_Word32)(b))) +#define WEBRTC_SPL_UDIV(a, b) \ + ((WebRtc_UWord32) ((WebRtc_UWord32)(a) / (WebRtc_UWord32)(b))) + +#define WEBRTC_SPL_MUL_16_32_RSFT11(a, b)\ + ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) << 5) \ + + (((WEBRTC_SPL_MUL_16_U16(a, (WebRtc_UWord16)(b)) >> 1) + 0x0200) >> 10)) +#define WEBRTC_SPL_MUL_16_32_RSFT14(a, b)\ + ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) << 2) \ + + (((WEBRTC_SPL_MUL_16_U16(a, (WebRtc_UWord16)(b)) >> 1) + 0x1000) >> 13)) +#define WEBRTC_SPL_MUL_16_32_RSFT15(a, b) \ + ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) << 1) \ + + (((WEBRTC_SPL_MUL_16_U16(a, (WebRtc_UWord16)(b)) >> 1) + 0x2000) >> 14)) + +#ifndef WEBRTC_ANDROID +#define WEBRTC_SPL_MUL_16_32_RSFT16(a, b) \ + (WEBRTC_SPL_MUL_16_16(a, b >> 16) \ + + ((WEBRTC_SPL_MUL_16_16(a, (b & 0xffff) >> 1) + 0x4000) >> 15)) +#define WEBRTC_SPL_MUL_32_32_RSFT32(a32a, a32b, b32) \ + ((WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT16(a32a, b32) \ + + (WEBRTC_SPL_MUL_16_32_RSFT16(a32b, b32) >> 16))) +#define WEBRTC_SPL_MUL_32_32_RSFT32BI(a32, b32) \ + ((WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT16(( \ + (WebRtc_Word16)(a32 >> 16)), b32) + \ + (WEBRTC_SPL_MUL_16_32_RSFT16(( \ + (WebRtc_Word16)((a32 & 0x0000FFFF) >> 1)), b32) >> 15))) +#endif + +#ifdef ARM_WINM +#define WEBRTC_SPL_MUL_16_16(a, b) \ + _SmulLo_SW_SL((WebRtc_Word16)(a), (WebRtc_Word16)(b)) +#elif !defined (WEBRTC_ANDROID) +#define WEBRTC_SPL_MUL_16_16(a, b) \ + ((WebRtc_Word32) (((WebRtc_Word16)(a)) * ((WebRtc_Word16)(b)))) +#endif + +#define WEBRTC_SPL_MUL_16_16_RSFT(a, b, c) \ + (WEBRTC_SPL_MUL_16_16(a, b) >> (c)) + +#define WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(a, b, c) \ + ((WEBRTC_SPL_MUL_16_16(a, b) + ((WebRtc_Word32) \ + (((WebRtc_Word32)1) << ((c) - 1)))) >> (c)) +#define WEBRTC_SPL_MUL_16_16_RSFT_WITH_FIXROUND(a, b)\ + ((WEBRTC_SPL_MUL_16_16(a, b) + ((WebRtc_Word32) (1 << 14))) >> 15) + +// C + the 32 most significant bits of A * B +#define WEBRTC_SPL_SCALEDIFF32(A, B, C) \ + (C + (B >> 16) * A + (((WebRtc_UWord32)(0x0000FFFF & B) * A) >> 16)) + +#define WEBRTC_SPL_ADD_SAT_W32(a, b) WebRtcSpl_AddSatW32(a, b) +#define WEBRTC_SPL_SAT(a, b, c) (b > a ? a : b < c ? c : b) +#define WEBRTC_SPL_MUL_32_16(a, b) ((a) * (b)) + +#define WEBRTC_SPL_SUB_SAT_W32(a, b) WebRtcSpl_SubSatW32(a, b) +#define WEBRTC_SPL_ADD_SAT_W16(a, b) WebRtcSpl_AddSatW16(a, b) +#define WEBRTC_SPL_SUB_SAT_W16(a, b) WebRtcSpl_SubSatW16(a, b) + +// We cannot do casting here due to signed/unsigned problem +#define WEBRTC_SPL_IS_NEG(a) ((a) & 0x80000000) +// Shifting with negative numbers allowed +// Positive means left shift +#define WEBRTC_SPL_SHIFT_W16(x, c) \ + (((c) >= 0) ? ((x) << (c)) : ((x) >> (-(c)))) +#define WEBRTC_SPL_SHIFT_W32(x, c) \ + (((c) >= 0) ? ((x) << (c)) : ((x) >> (-(c)))) + +// Shifting with negative numbers not allowed +// We cannot do casting here due to signed/unsigned problem +#define WEBRTC_SPL_RSHIFT_W16(x, c) ((x) >> (c)) +#define WEBRTC_SPL_LSHIFT_W16(x, c) ((x) << (c)) +#define WEBRTC_SPL_RSHIFT_W32(x, c) ((x) >> (c)) +#define WEBRTC_SPL_LSHIFT_W32(x, c) ((x) << (c)) + +#define WEBRTC_SPL_RSHIFT_U16(x, c) ((WebRtc_UWord16)(x) >> (c)) +#define WEBRTC_SPL_LSHIFT_U16(x, c) ((WebRtc_UWord16)(x) << (c)) +#define WEBRTC_SPL_RSHIFT_U32(x, c) ((WebRtc_UWord32)(x) >> (c)) +#define WEBRTC_SPL_LSHIFT_U32(x, c) ((WebRtc_UWord32)(x) << (c)) + +#define WEBRTC_SPL_VNEW(t, n) (t *) malloc (sizeof (t) * (n)) +#define WEBRTC_SPL_FREE free + +#define WEBRTC_SPL_RAND(a)\ + ((WebRtc_Word16)(WEBRTC_SPL_MUL_16_16_RSFT((a), 18816, 7) & 0x00007fff)) + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define WEBRTC_SPL_MEMCPY_W8(v1, v2, length) \ + memcpy(v1, v2, (length) * sizeof(char)) +#define WEBRTC_SPL_MEMCPY_W16(v1, v2, length) \ + memcpy(v1, v2, (length) * sizeof(WebRtc_Word16)) + +#define WEBRTC_SPL_MEMMOVE_W16(v1, v2, length) \ + memmove(v1, v2, (length) * sizeof(WebRtc_Word16)) + +// Trigonometric tables used for quick lookup +// default declarations +extern WebRtc_Word16 WebRtcSpl_kCosTable[]; +extern WebRtc_Word16 WebRtcSpl_kSinTable[]; +extern WebRtc_Word16 WebRtcSpl_kSinTable1024[]; +// Hanning table +extern WebRtc_Word16 WebRtcSpl_kHanningTable[]; +// Random table +extern WebRtc_Word16 WebRtcSpl_kRandNTable[]; + +#ifndef WEBRTC_SPL_INLINE_CALLS +WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 var1, WebRtc_Word16 var2); +WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1, WebRtc_Word16 var2); +WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 var1, WebRtc_Word32 var2); +WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 var1, WebRtc_Word32 var2); +WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 value); +int WebRtcSpl_NormW32(WebRtc_Word32 value); +int WebRtcSpl_NormW16(WebRtc_Word16 value); +int WebRtcSpl_NormU32(WebRtc_UWord32 value); +#else +#include "spl_inl.h" +#endif + +// Get SPL Version +WebRtc_Word16 WebRtcSpl_get_version(char* version, + WebRtc_Word16 length_in_bytes); + +int WebRtcSpl_GetScalingSquare(WebRtc_Word16* in_vector, + int in_vector_length, + int times); + +// Copy and set operations. Implementation in copy_set_operations.c. +// Descriptions at bottom of file. +void WebRtcSpl_MemSetW16(WebRtc_Word16* vector, + WebRtc_Word16 set_value, + int vector_length); +void WebRtcSpl_MemSetW32(WebRtc_Word32* vector, + WebRtc_Word32 set_value, + int vector_length); +void WebRtcSpl_MemCpyReversedOrder(WebRtc_Word16* out_vector, + WebRtc_Word16* in_vector, + int vector_length); +WebRtc_Word16 WebRtcSpl_CopyFromEndW16(G_CONST WebRtc_Word16* in_vector, + WebRtc_Word16 in_vector_length, + WebRtc_Word16 samples, + WebRtc_Word16* out_vector); +WebRtc_Word16 WebRtcSpl_ZerosArrayW16(WebRtc_Word16* vector, + WebRtc_Word16 vector_length); +WebRtc_Word16 WebRtcSpl_ZerosArrayW32(WebRtc_Word32* vector, + WebRtc_Word16 vector_length); +WebRtc_Word16 WebRtcSpl_OnesArrayW16(WebRtc_Word16* vector, + WebRtc_Word16 vector_length); +WebRtc_Word16 WebRtcSpl_OnesArrayW32(WebRtc_Word32* vector, + WebRtc_Word16 vector_length); +// End: Copy and set operations. + +// Minimum and maximum operations. Implementation in min_max_operations.c. +// Descriptions at bottom of file. +WebRtc_Word16 WebRtcSpl_MaxAbsValueW16(G_CONST WebRtc_Word16* vector, + WebRtc_Word16 length); +WebRtc_Word32 WebRtcSpl_MaxAbsValueW32(G_CONST WebRtc_Word32* vector, + WebRtc_Word16 length); +WebRtc_Word16 WebRtcSpl_MinValueW16(G_CONST WebRtc_Word16* vector, + WebRtc_Word16 length); +WebRtc_Word32 WebRtcSpl_MinValueW32(G_CONST WebRtc_Word32* vector, + WebRtc_Word16 length); +WebRtc_Word16 WebRtcSpl_MaxValueW16(G_CONST WebRtc_Word16* vector, + WebRtc_Word16 length); + +WebRtc_Word16 WebRtcSpl_MaxAbsIndexW16(G_CONST WebRtc_Word16* vector, + WebRtc_Word16 length); +WebRtc_Word32 WebRtcSpl_MaxValueW32(G_CONST WebRtc_Word32* vector, + WebRtc_Word16 length); +WebRtc_Word16 WebRtcSpl_MinIndexW16(G_CONST WebRtc_Word16* vector, + WebRtc_Word16 length); +WebRtc_Word16 WebRtcSpl_MinIndexW32(G_CONST WebRtc_Word32* vector, + WebRtc_Word16 length); +WebRtc_Word16 WebRtcSpl_MaxIndexW16(G_CONST WebRtc_Word16* vector, + WebRtc_Word16 length); +WebRtc_Word16 WebRtcSpl_MaxIndexW32(G_CONST WebRtc_Word32* vector, + WebRtc_Word16 length); +// End: Minimum and maximum operations. + +// Vector scaling operations. Implementation in vector_scaling_operations.c. +// Description at bottom of file. +void WebRtcSpl_VectorBitShiftW16(WebRtc_Word16* out_vector, + WebRtc_Word16 vector_length, + G_CONST WebRtc_Word16* in_vector, + WebRtc_Word16 right_shifts); +void WebRtcSpl_VectorBitShiftW32(WebRtc_Word32* out_vector, + WebRtc_Word16 vector_length, + G_CONST WebRtc_Word32* in_vector, + WebRtc_Word16 right_shifts); +void WebRtcSpl_VectorBitShiftW32ToW16(WebRtc_Word16* out_vector, + WebRtc_Word16 vector_length, + G_CONST WebRtc_Word32* in_vector, + WebRtc_Word16 right_shifts); + +void WebRtcSpl_ScaleVector(G_CONST WebRtc_Word16* in_vector, + WebRtc_Word16* out_vector, + WebRtc_Word16 gain, + WebRtc_Word16 vector_length, + WebRtc_Word16 right_shifts); +void WebRtcSpl_ScaleVectorWithSat(G_CONST WebRtc_Word16* in_vector, + WebRtc_Word16* out_vector, + WebRtc_Word16 gain, + WebRtc_Word16 vector_length, + WebRtc_Word16 right_shifts); +void WebRtcSpl_ScaleAndAddVectors(G_CONST WebRtc_Word16* in_vector1, + WebRtc_Word16 gain1, int right_shifts1, + G_CONST WebRtc_Word16* in_vector2, + WebRtc_Word16 gain2, int right_shifts2, + WebRtc_Word16* out_vector, + int vector_length); +// End: Vector scaling operations. + +// iLBC specific functions. Implementations in ilbc_specific_functions.c. +// Description at bottom of file. +void WebRtcSpl_ScaleAndAddVectorsWithRound(WebRtc_Word16* in_vector1, + WebRtc_Word16 scale1, + WebRtc_Word16* in_vector2, + WebRtc_Word16 scale2, + WebRtc_Word16 right_shifts, + WebRtc_Word16* out_vector, + WebRtc_Word16 vector_length); +void WebRtcSpl_ReverseOrderMultArrayElements(WebRtc_Word16* out_vector, + G_CONST WebRtc_Word16* in_vector, + G_CONST WebRtc_Word16* window, + WebRtc_Word16 vector_length, + WebRtc_Word16 right_shifts); +void WebRtcSpl_ElementwiseVectorMult(WebRtc_Word16* out_vector, + G_CONST WebRtc_Word16* in_vector, + G_CONST WebRtc_Word16* window, + WebRtc_Word16 vector_length, + WebRtc_Word16 right_shifts); +void WebRtcSpl_AddVectorsAndShift(WebRtc_Word16* out_vector, + G_CONST WebRtc_Word16* in_vector1, + G_CONST WebRtc_Word16* in_vector2, + WebRtc_Word16 vector_length, + WebRtc_Word16 right_shifts); +void WebRtcSpl_AddAffineVectorToVector(WebRtc_Word16* out_vector, + WebRtc_Word16* in_vector, + WebRtc_Word16 gain, + WebRtc_Word32 add_constant, + WebRtc_Word16 right_shifts, + int vector_length); +void WebRtcSpl_AffineTransformVector(WebRtc_Word16* out_vector, + WebRtc_Word16* in_vector, + WebRtc_Word16 gain, + WebRtc_Word32 add_constant, + WebRtc_Word16 right_shifts, + int vector_length); +// End: iLBC specific functions. + +// Signal processing operations. Descriptions at bottom of this file. +int WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* vector, + int vector_length, int order, + WebRtc_Word32* result_vector, + int* scale); +WebRtc_Word16 WebRtcSpl_LevinsonDurbin(WebRtc_Word32* auto_corr, + WebRtc_Word16* lpc_coef, + WebRtc_Word16* refl_coef, + WebRtc_Word16 order); +void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16* refl_coef, + int use_order, + WebRtc_Word16* lpc_coef); +void WebRtcSpl_LpcToReflCoef(WebRtc_Word16* lpc_coef, + int use_order, + WebRtc_Word16* refl_coef); +void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32* auto_corr, + int use_order, + WebRtc_Word16* refl_coef); +void WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_corr, + WebRtc_Word16* vector1, + WebRtc_Word16* vector2, + WebRtc_Word16 dim_vector, + WebRtc_Word16 dim_cross_corr, + WebRtc_Word16 right_shifts, + WebRtc_Word16 step_vector2); +void WebRtcSpl_GetHanningWindow(WebRtc_Word16* window, WebRtc_Word16 size); +void WebRtcSpl_SqrtOfOneMinusXSquared(WebRtc_Word16* in_vector, + int vector_length, + WebRtc_Word16* out_vector); +// End: Signal processing operations. + +// Randomization functions. Implementations collected in randomization_functions.c and +// descriptions at bottom of this file. +WebRtc_UWord32 WebRtcSpl_IncreaseSeed(WebRtc_UWord32* seed); +WebRtc_Word16 WebRtcSpl_RandU(WebRtc_UWord32* seed); +WebRtc_Word16 WebRtcSpl_RandN(WebRtc_UWord32* seed); +WebRtc_Word16 WebRtcSpl_RandUArray(WebRtc_Word16* vector, + WebRtc_Word16 vector_length, + WebRtc_UWord32* seed); +// End: Randomization functions. + +// Math functions +WebRtc_Word32 WebRtcSpl_Sqrt(WebRtc_Word32 value); + +// Divisions. Implementations collected in division_operations.c and +// descriptions at bottom of this file. +WebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den); +WebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den); +WebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den); +WebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den); +WebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi, + WebRtc_Word16 den_low); +// End: Divisions. + +WebRtc_Word32 WebRtcSpl_Energy(WebRtc_Word16* vector, + int vector_length, + int* scale_factor); + +WebRtc_Word32 WebRtcSpl_DotProductWithScale(WebRtc_Word16* vector1, + WebRtc_Word16* vector2, + int vector_length, + int scaling); + +// Filter operations. +int WebRtcSpl_FilterAR(G_CONST WebRtc_Word16* ar_coef, int ar_coef_length, + G_CONST WebRtc_Word16* in_vector, int in_vector_length, + WebRtc_Word16* filter_state, int filter_state_length, + WebRtc_Word16* filter_state_low, + int filter_state_low_length, WebRtc_Word16* out_vector, + WebRtc_Word16* out_vector_low, int out_vector_low_length); + +void WebRtcSpl_FilterMAFastQ12(WebRtc_Word16* in_vector, + WebRtc_Word16* out_vector, + WebRtc_Word16* ma_coef, + WebRtc_Word16 ma_coef_length, + WebRtc_Word16 vector_length); +void WebRtcSpl_FilterARFastQ12(WebRtc_Word16* in_vector, + WebRtc_Word16* out_vector, + WebRtc_Word16* ar_coef, + WebRtc_Word16 ar_coef_length, + WebRtc_Word16 vector_length); +int WebRtcSpl_DownsampleFast(WebRtc_Word16* in_vector, + WebRtc_Word16 in_vector_length, + WebRtc_Word16* out_vector, + WebRtc_Word16 out_vector_length, + WebRtc_Word16* ma_coef, + WebRtc_Word16 ma_coef_length, + WebRtc_Word16 factor, + WebRtc_Word16 delay); +// End: Filter operations. + +// FFT operations +int WebRtcSpl_ComplexFFT(WebRtc_Word16 vector[], int stages, int mode); +int WebRtcSpl_ComplexIFFT(WebRtc_Word16 vector[], int stages, int mode); +#if (defined ARM9E_GCC) || (defined ARM_WINM) || (defined ANDROID_AECOPT) +int WebRtcSpl_ComplexFFT2(WebRtc_Word16 in_vector[], + WebRtc_Word16 out_vector[], + int stages, int mode); +int WebRtcSpl_ComplexIFFT2(WebRtc_Word16 in_vector[], + WebRtc_Word16 out_vector[], + int stages, int mode); +#endif +void WebRtcSpl_ComplexBitReverse(WebRtc_Word16 vector[], int stages); +// End: FFT operations + +/************************************************************ + * + * RESAMPLING FUNCTIONS AND THEIR STRUCTS ARE DEFINED BELOW + * + ************************************************************/ + +/******************************************************************* + * resample.c + * + * Includes the following resampling combinations + * 22 kHz -> 16 kHz + * 16 kHz -> 22 kHz + * 22 kHz -> 8 kHz + * 8 kHz -> 22 kHz + * + ******************************************************************/ + +// state structure for 22 -> 16 resampler +typedef struct +{ + WebRtc_Word32 S_22_44[8]; + WebRtc_Word32 S_44_32[8]; + WebRtc_Word32 S_32_16[8]; +} WebRtcSpl_State22khzTo16khz; + +void WebRtcSpl_Resample22khzTo16khz(const WebRtc_Word16* in, + WebRtc_Word16* out, + WebRtcSpl_State22khzTo16khz* state, + WebRtc_Word32* tmpmem); + +void WebRtcSpl_ResetResample22khzTo16khz(WebRtcSpl_State22khzTo16khz* state); + +// state structure for 16 -> 22 resampler +typedef struct +{ + WebRtc_Word32 S_16_32[8]; + WebRtc_Word32 S_32_22[8]; +} WebRtcSpl_State16khzTo22khz; + +void WebRtcSpl_Resample16khzTo22khz(const WebRtc_Word16* in, + WebRtc_Word16* out, + WebRtcSpl_State16khzTo22khz* state, + WebRtc_Word32* tmpmem); + +void WebRtcSpl_ResetResample16khzTo22khz(WebRtcSpl_State16khzTo22khz* state); + +// state structure for 22 -> 8 resampler +typedef struct +{ + WebRtc_Word32 S_22_22[16]; + WebRtc_Word32 S_22_16[8]; + WebRtc_Word32 S_16_8[8]; +} WebRtcSpl_State22khzTo8khz; + +void WebRtcSpl_Resample22khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State22khzTo8khz* state, + WebRtc_Word32* tmpmem); + +void WebRtcSpl_ResetResample22khzTo8khz(WebRtcSpl_State22khzTo8khz* state); + +// state structure for 8 -> 22 resampler +typedef struct +{ + WebRtc_Word32 S_8_16[8]; + WebRtc_Word32 S_16_11[8]; + WebRtc_Word32 S_11_22[8]; +} WebRtcSpl_State8khzTo22khz; + +void WebRtcSpl_Resample8khzTo22khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State8khzTo22khz* state, + WebRtc_Word32* tmpmem); + +void WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz* state); + +/******************************************************************* + * resample_fractional.c + * Functions for internal use in the other resample functions + * + * Includes the following resampling combinations + * 48 kHz -> 32 kHz + * 32 kHz -> 24 kHz + * 44 kHz -> 32 kHz + * + ******************************************************************/ + +void WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32* In, WebRtc_Word32* Out, + const WebRtc_Word32 K); + +void WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32* In, WebRtc_Word32* Out, + const WebRtc_Word32 K); + +void WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32* In, WebRtc_Word32* Out, + const WebRtc_Word32 K); + +/******************************************************************* + * resample_48khz.c + * + * Includes the following resampling combinations + * 48 kHz -> 16 kHz + * 16 kHz -> 48 kHz + * 48 kHz -> 8 kHz + * 8 kHz -> 48 kHz + * + ******************************************************************/ + +typedef struct +{ + WebRtc_Word32 S_48_48[16]; + WebRtc_Word32 S_48_32[8]; + WebRtc_Word32 S_32_16[8]; +} WebRtcSpl_State48khzTo16khz; + +void WebRtcSpl_Resample48khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State48khzTo16khz* state, + WebRtc_Word32* tmpmem); + +void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state); + +typedef struct +{ + WebRtc_Word32 S_16_32[8]; + WebRtc_Word32 S_32_24[8]; + WebRtc_Word32 S_24_48[8]; +} WebRtcSpl_State16khzTo48khz; + +void WebRtcSpl_Resample16khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State16khzTo48khz* state, + WebRtc_Word32* tmpmem); + +void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state); + +typedef struct +{ + WebRtc_Word32 S_48_24[8]; + WebRtc_Word32 S_24_24[16]; + WebRtc_Word32 S_24_16[8]; + WebRtc_Word32 S_16_8[8]; +} WebRtcSpl_State48khzTo8khz; + +void WebRtcSpl_Resample48khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State48khzTo8khz* state, + WebRtc_Word32* tmpmem); + +void WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state); + +typedef struct +{ + WebRtc_Word32 S_8_16[8]; + WebRtc_Word32 S_16_12[8]; + WebRtc_Word32 S_12_24[8]; + WebRtc_Word32 S_24_48[8]; +} WebRtcSpl_State8khzTo48khz; + +void WebRtcSpl_Resample8khzTo48khz(const WebRtc_Word16* in, WebRtc_Word16* out, + WebRtcSpl_State8khzTo48khz* state, + WebRtc_Word32* tmpmem); + +void WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state); + +/******************************************************************* + * resample_by_2.c + * + * Includes down and up sampling by a factor of two. + * + ******************************************************************/ + +void WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len, + WebRtc_Word16* out, WebRtc_Word32* filtState); + +void WebRtcSpl_UpsampleBy2(const WebRtc_Word16* in, WebRtc_Word16 len, WebRtc_Word16* out, + WebRtc_Word32* filtState); + +/************************************************************ + * END OF RESAMPLING FUNCTIONS + ************************************************************/ +void WebRtcSpl_AnalysisQMF(const WebRtc_Word16* in_data, + WebRtc_Word16* low_band, + WebRtc_Word16* high_band, + WebRtc_Word32* filter_state1, + WebRtc_Word32* filter_state2); +void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, + const WebRtc_Word16* high_band, + WebRtc_Word16* out_data, + WebRtc_Word32* filter_state1, + WebRtc_Word32* filter_state2); + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // WEBRTC_SPL_SIGNAL_PROCESSING_LIBRARY_H_ + +// +// WebRtcSpl_AddSatW16(...) +// WebRtcSpl_AddSatW32(...) +// +// Returns the result of a saturated 16-bit, respectively 32-bit, addition of +// the numbers specified by the |var1| and |var2| parameters. +// +// Input: +// - var1 : Input variable 1 +// - var2 : Input variable 2 +// +// Return value : Added and saturated value +// + +// +// WebRtcSpl_SubSatW16(...) +// WebRtcSpl_SubSatW32(...) +// +// Returns the result of a saturated 16-bit, respectively 32-bit, subtraction +// of the numbers specified by the |var1| and |var2| parameters. +// +// Input: +// - var1 : Input variable 1 +// - var2 : Input variable 2 +// +// Returned value : Subtracted and saturated value +// + +// +// WebRtcSpl_GetSizeInBits(...) +// +// Returns the # of bits that are needed at the most to represent the number +// specified by the |value| parameter. +// +// Input: +// - value : Input value +// +// Return value : Number of bits needed to represent |value| +// + +// +// WebRtcSpl_NormW32(...) +// +// Norm returns the # of left shifts required to 32-bit normalize the 32-bit +// signed number specified by the |value| parameter. +// +// Input: +// - value : Input value +// +// Return value : Number of bit shifts needed to 32-bit normalize |value| +// + +// +// WebRtcSpl_NormW16(...) +// +// Norm returns the # of left shifts required to 16-bit normalize the 16-bit +// signed number specified by the |value| parameter. +// +// Input: +// - value : Input value +// +// Return value : Number of bit shifts needed to 32-bit normalize |value| +// + +// +// WebRtcSpl_NormU32(...) +// +// Norm returns the # of left shifts required to 32-bit normalize the unsigned +// 32-bit number specified by the |value| parameter. +// +// Input: +// - value : Input value +// +// Return value : Number of bit shifts needed to 32-bit normalize |value| +// + +// +// WebRtcSpl_GetScalingSquare(...) +// +// Returns the # of bits required to scale the samples specified in the +// |in_vector| parameter so that, if the squares of the samples are added the +// # of times specified by the |times| parameter, the 32-bit addition will not +// overflow (result in WebRtc_Word32). +// +// Input: +// - in_vector : Input vector to check scaling on +// - in_vector_length : Samples in |in_vector| +// - times : Number of additions to be performed +// +// Return value : Number of right bit shifts needed to avoid +// overflow in the addition calculation +// + +// +// WebRtcSpl_MemSetW16(...) +// +// Sets all the values in the WebRtc_Word16 vector |vector| of length +// |vector_length| to the specified value |set_value| +// +// Input: +// - vector : Pointer to the WebRtc_Word16 vector +// - set_value : Value specified +// - vector_length : Length of vector +// + +// +// WebRtcSpl_MemSetW32(...) +// +// Sets all the values in the WebRtc_Word32 vector |vector| of length +// |vector_length| to the specified value |set_value| +// +// Input: +// - vector : Pointer to the WebRtc_Word16 vector +// - set_value : Value specified +// - vector_length : Length of vector +// + +// +// WebRtcSpl_MemCpyReversedOrder(...) +// +// Copies all the values from the source WebRtc_Word16 vector |in_vector| to a +// destination WebRtc_Word16 vector |out_vector|. It is done in reversed order, +// meaning that the first sample of |in_vector| is copied to the last sample of +// the |out_vector|. The procedure continues until the last sample of +// |in_vector| has been copied to the first sample of |out_vector|. This +// creates a reversed vector. Used in e.g. prediction in iLBC. +// +// Input: +// - in_vector : Pointer to the first sample in a WebRtc_Word16 vector +// of length |length| +// - vector_length : Number of elements to copy +// +// Output: +// - out_vector : Pointer to the last sample in a WebRtc_Word16 vector +// of length |length| +// + +// +// WebRtcSpl_CopyFromEndW16(...) +// +// Copies the rightmost |samples| of |in_vector| (of length |in_vector_length|) +// to the vector |out_vector|. +// +// Input: +// - in_vector : Input vector +// - in_vector_length : Number of samples in |in_vector| +// - samples : Number of samples to extract (from right side) +// from |in_vector| +// +// Output: +// - out_vector : Vector with the requested samples +// +// Return value : Number of copied samples in |out_vector| +// + +// +// WebRtcSpl_ZerosArrayW16(...) +// WebRtcSpl_ZerosArrayW32(...) +// +// Inserts the value "zero" in all positions of a w16 and a w32 vector +// respectively. +// +// Input: +// - vector_length : Number of samples in vector +// +// Output: +// - vector : Vector containing all zeros +// +// Return value : Number of samples in vector +// + +// +// WebRtcSpl_OnesArrayW16(...) +// WebRtcSpl_OnesArrayW32(...) +// +// Inserts the value "one" in all positions of a w16 and a w32 vector +// respectively. +// +// Input: +// - vector_length : Number of samples in vector +// +// Output: +// - vector : Vector containing all ones +// +// Return value : Number of samples in vector +// + +// +// WebRtcSpl_MinValueW16(...) +// WebRtcSpl_MinValueW32(...) +// +// Returns the minimum value of a vector +// +// Input: +// - vector : Input vector +// - vector_length : Number of samples in vector +// +// Return value : Minimum sample value in vector +// + +// +// WebRtcSpl_MaxValueW16(...) +// WebRtcSpl_MaxValueW32(...) +// +// Returns the maximum value of a vector +// +// Input: +// - vector : Input vector +// - vector_length : Number of samples in vector +// +// Return value : Maximum sample value in vector +// + +// +// WebRtcSpl_MaxAbsValueW16(...) +// WebRtcSpl_MaxAbsValueW32(...) +// +// Returns the largest absolute value of a vector +// +// Input: +// - vector : Input vector +// - vector_length : Number of samples in vector +// +// Return value : Maximum absolute value in vector +// + +// +// WebRtcSpl_MaxAbsIndexW16(...) +// +// Returns the vector index to the largest absolute value of a vector +// +// Input: +// - vector : Input vector +// - vector_length : Number of samples in vector +// +// Return value : Index to maximum absolute value in vector +// + +// +// WebRtcSpl_MinIndexW16(...) +// WebRtcSpl_MinIndexW32(...) +// +// Returns the vector index to the minimum sample value of a vector +// +// Input: +// - vector : Input vector +// - vector_length : Number of samples in vector +// +// Return value : Index to minimum sample value in vector +// + +// +// WebRtcSpl_MaxIndexW16(...) +// WebRtcSpl_MaxIndexW32(...) +// +// Returns the vector index to the maximum sample value of a vector +// +// Input: +// - vector : Input vector +// - vector_length : Number of samples in vector +// +// Return value : Index to maximum sample value in vector +// + +// +// WebRtcSpl_VectorBitShiftW16(...) +// WebRtcSpl_VectorBitShiftW32(...) +// +// Bit shifts all the values in a vector up or downwards. Different calls for +// WebRtc_Word16 and WebRtc_Word32 vectors respectively. +// +// Input: +// - vector_length : Length of vector +// - in_vector : Pointer to the vector that should be bit shifted +// - right_shifts : Number of right bit shifts (negative value gives left +// shifts) +// +// Output: +// - out_vector : Pointer to the result vector (can be the same as +// |in_vector|) +// + +// +// WebRtcSpl_VectorBitShiftW32ToW16(...) +// +// Bit shifts all the values in a WebRtc_Word32 vector up or downwards and +// stores the result as a WebRtc_Word16 vector +// +// Input: +// - vector_length : Length of vector +// - in_vector : Pointer to the vector that should be bit shifted +// - right_shifts : Number of right bit shifts (negative value gives left +// shifts) +// +// Output: +// - out_vector : Pointer to the result vector (can be the same as +// |in_vector|) +// + +// +// WebRtcSpl_ScaleVector(...) +// +// Performs the vector operation: +// out_vector[k] = (gain*in_vector[k])>>right_shifts +// +// Input: +// - in_vector : Input vector +// - gain : Scaling gain +// - vector_length : Elements in the |in_vector| +// - right_shifts : Number of right bit shifts applied +// +// Output: +// - out_vector : Output vector (can be the same as |in_vector|) +// + +// +// WebRtcSpl_ScaleVectorWithSat(...) +// +// Performs the vector operation: +// out_vector[k] = SATURATE( (gain*in_vector[k])>>right_shifts ) +// +// Input: +// - in_vector : Input vector +// - gain : Scaling gain +// - vector_length : Elements in the |in_vector| +// - right_shifts : Number of right bit shifts applied +// +// Output: +// - out_vector : Output vector (can be the same as |in_vector|) +// + +// +// WebRtcSpl_ScaleAndAddVectors(...) +// +// Performs the vector operation: +// out_vector[k] = (gain1*in_vector1[k])>>right_shifts1 +// + (gain2*in_vector2[k])>>right_shifts2 +// +// Input: +// - in_vector1 : Input vector 1 +// - gain1 : Gain to be used for vector 1 +// - right_shifts1 : Right bit shift to be used for vector 1 +// - in_vector2 : Input vector 2 +// - gain2 : Gain to be used for vector 2 +// - right_shifts2 : Right bit shift to be used for vector 2 +// - vector_length : Elements in the input vectors +// +// Output: +// - out_vector : Output vector +// + +// +// WebRtcSpl_ScaleAndAddVectorsWithRound(...) +// +// Performs the vector operation: +// +// out_vector[k] = ((scale1*in_vector1[k]) + (scale2*in_vector2[k]) +// + round_value) >> right_shifts +// +// where: +// +// round_value = (1<<right_shifts)>>1 +// +// Input: +// - in_vector1 : Input vector 1 +// - scale1 : Gain to be used for vector 1 +// - in_vector2 : Input vector 2 +// - scale2 : Gain to be used for vector 2 +// - right_shifts : Number of right bit shifts to be applied +// - vector_length : Number of elements in the input vectors +// +// Output: +// - out_vector : Output vector +// + +// +// WebRtcSpl_ReverseOrderMultArrayElements(...) +// +// Performs the vector operation: +// out_vector[n] = (in_vector[n]*window[-n])>>right_shifts +// +// Input: +// - in_vector : Input vector +// - window : Window vector (should be reversed). The pointer +// should be set to the last value in the vector +// - right_shifts : Number of right bit shift to be applied after the +// multiplication +// - vector_length : Number of elements in |in_vector| +// +// Output: +// - out_vector : Output vector (can be same as |in_vector|) +// + +// +// WebRtcSpl_ElementwiseVectorMult(...) +// +// Performs the vector operation: +// out_vector[n] = (in_vector[n]*window[n])>>right_shifts +// +// Input: +// - in_vector : Input vector +// - window : Window vector. +// - right_shifts : Number of right bit shift to be applied after the +// multiplication +// - vector_length : Number of elements in |in_vector| +// +// Output: +// - out_vector : Output vector (can be same as |in_vector|) +// + +// +// WebRtcSpl_AddVectorsAndShift(...) +// +// Performs the vector operation: +// out_vector[k] = (in_vector1[k] + in_vector2[k])>>right_shifts +// +// Input: +// - in_vector1 : Input vector 1 +// - in_vector2 : Input vector 2 +// - right_shifts : Number of right bit shift to be applied after the +// multiplication +// - vector_length : Number of elements in |in_vector1| and |in_vector2| +// +// Output: +// - out_vector : Output vector (can be same as |in_vector1|) +// + +// +// WebRtcSpl_AddAffineVectorToVector(...) +// +// Adds an affine transformed vector to another vector |out_vector|, i.e, +// performs +// out_vector[k] += (in_vector[k]*gain+add_constant)>>right_shifts +// +// Input: +// - in_vector : Input vector +// - gain : Gain value, used to multiply the in vector with +// - add_constant : Constant value to add (usually 1<<(right_shifts-1), +// but others can be used as well +// - right_shifts : Number of right bit shifts (0-16) +// - vector_length : Number of samples in |in_vector| and |out_vector| +// +// Output: +// - out_vector : Vector with the output +// + +// +// WebRtcSpl_AffineTransformVector(...) +// +// Affine transforms a vector, i.e, performs +// out_vector[k] = (in_vector[k]*gain+add_constant)>>right_shifts +// +// Input: +// - in_vector : Input vector +// - gain : Gain value, used to multiply the in vector with +// - add_constant : Constant value to add (usually 1<<(right_shifts-1), +// but others can be used as well +// - right_shifts : Number of right bit shifts (0-16) +// - vector_length : Number of samples in |in_vector| and |out_vector| +// +// Output: +// - out_vector : Vector with the output +// + +// +// WebRtcSpl_AutoCorrelation(...) +// +// A 32-bit fix-point implementation of auto-correlation computation +// +// Input: +// - vector : Vector to calculate autocorrelation upon +// - vector_length : Length (in samples) of |vector| +// - order : The order up to which the autocorrelation should be +// calculated +// +// Output: +// - result_vector : auto-correlation values (values should be seen +// relative to each other since the absolute values +// might have been down shifted to avoid overflow) +// +// - scale : The number of left shifts required to obtain the +// auto-correlation in Q0 +// +// Return value : Number of samples in |result_vector|, i.e., (order+1) +// + +// +// WebRtcSpl_LevinsonDurbin(...) +// +// A 32-bit fix-point implementation of the Levinson-Durbin algorithm that +// does NOT use the 64 bit class +// +// Input: +// - auto_corr : Vector with autocorrelation values of length >= +// |use_order|+1 +// - use_order : The LPC filter order (support up to order 20) +// +// Output: +// - lpc_coef : lpc_coef[0..use_order] LPC coefficients in Q12 +// - refl_coef : refl_coef[0...use_order-1]| Reflection coefficients in +// Q15 +// +// Return value : 1 for stable 0 for unstable +// + +// +// WebRtcSpl_ReflCoefToLpc(...) +// +// Converts reflection coefficients |refl_coef| to LPC coefficients |lpc_coef|. +// This version is a 16 bit operation. +// +// NOTE: The 16 bit refl_coef -> lpc_coef conversion might result in a +// "slightly unstable" filter (i.e., a pole just outside the unit circle) in +// "rare" cases even if the reflection coefficients are stable. +// +// Input: +// - refl_coef : Reflection coefficients in Q15 that should be converted +// to LPC coefficients +// - use_order : Number of coefficients in |refl_coef| +// +// Output: +// - lpc_coef : LPC coefficients in Q12 +// + +// +// WebRtcSpl_LpcToReflCoef(...) +// +// Converts LPC coefficients |lpc_coef| to reflection coefficients |refl_coef|. +// This version is a 16 bit operation. +// The conversion is implemented by the step-down algorithm. +// +// Input: +// - lpc_coef : LPC coefficients in Q12, that should be converted to +// reflection coefficients +// - use_order : Number of coefficients in |lpc_coef| +// +// Output: +// - refl_coef : Reflection coefficients in Q15. +// + +// +// WebRtcSpl_AutoCorrToReflCoef(...) +// +// Calculates reflection coefficients (16 bit) from auto-correlation values +// +// Input: +// - auto_corr : Auto-correlation values +// - use_order : Number of coefficients wanted be calculated +// +// Output: +// - refl_coef : Reflection coefficients in Q15. +// + +// +// WebRtcSpl_CrossCorrelation(...) +// +// Calculates the cross-correlation between two sequences |vector1| and +// |vector2|. |vector1| is fixed and |vector2| slides as the pointer is +// increased with the amount |step_vector2| +// +// Input: +// - vector1 : First sequence (fixed throughout the correlation) +// - vector2 : Second sequence (slides |step_vector2| for each +// new correlation) +// - dim_vector : Number of samples to use in the cross-correlation +// - dim_cross_corr : Number of cross-correlations to calculate (the +// start position for |vector2| is updated for each +// new one) +// - right_shifts : Number of right bit shifts to use. This will +// become the output Q-domain. +// - step_vector2 : How many (positive or negative) steps the +// |vector2| pointer should be updated for each new +// cross-correlation value. +// +// Output: +// - cross_corr : The cross-correlation in Q(-right_shifts) +// + +// +// WebRtcSpl_GetHanningWindow(...) +// +// Creates (the first half of) a Hanning window. Size must be at least 1 and +// at most 512. +// +// Input: +// - size : Length of the requested Hanning window (1 to 512) +// +// Output: +// - window : Hanning vector in Q14. +// + +// +// WebRtcSpl_SqrtOfOneMinusXSquared(...) +// +// Calculates y[k] = sqrt(1 - x[k]^2) for each element of the input vector +// |in_vector|. Input and output values are in Q15. +// +// Inputs: +// - in_vector : Values to calculate sqrt(1 - x^2) of +// - vector_length : Length of vector |in_vector| +// +// Output: +// - out_vector : Output values in Q15 +// + +// +// WebRtcSpl_IncreaseSeed(...) +// +// Increases the seed (and returns the new value) +// +// Input: +// - seed : Seed for random calculation +// +// Output: +// - seed : Updated seed value +// +// Return value : The new seed value +// + +// +// WebRtcSpl_RandU(...) +// +// Produces a uniformly distributed value in the WebRtc_Word16 range +// +// Input: +// - seed : Seed for random calculation +// +// Output: +// - seed : Updated seed value +// +// Return value : Uniformly distributed value in the range +// [Word16_MIN...Word16_MAX] +// + +// +// WebRtcSpl_RandN(...) +// +// Produces a normal distributed value in the WebRtc_Word16 range +// +// Input: +// - seed : Seed for random calculation +// +// Output: +// - seed : Updated seed value +// +// Return value : N(0,1) value in the Q13 domain +// + +// +// WebRtcSpl_RandUArray(...) +// +// Produces a uniformly distributed vector with elements in the WebRtc_Word16 +// range +// +// Input: +// - vector_length : Samples wanted in the vector +// - seed : Seed for random calculation +// +// Output: +// - vector : Vector with the uniform values +// - seed : Updated seed value +// +// Return value : Number of samples in vector, i.e., |vector_length| +// + +// +// WebRtcSpl_Sqrt(...) +// +// Returns the square root of the input value |value|. The precision of this +// function is integer precision, i.e., sqrt(8) gives 2 as answer. +// If |value| is a negative number then 0 is returned. +// +// Algorithm: +// +// A sixth order Taylor Series expansion is used here to compute the square +// root of a number y^0.5 = (1+x)^0.5 +// where +// x = y-1 +// = 1+(x/2)-0.5*((x/2)^2+0.5*((x/2)^3-0.625*((x/2)^4+0.875*((x/2)^5) +// 0.5 <= x < 1 +// +// Input: +// - value : Value to calculate sqrt of +// +// Return value : Result of the sqrt calculation +// + +// +// WebRtcSpl_DivU32U16(...) +// +// Divides a WebRtc_UWord32 |num| by a WebRtc_UWord16 |den|. +// +// If |den|==0, (WebRtc_UWord32)0xFFFFFFFF is returned. +// +// Input: +// - num : Numerator +// - den : Denominator +// +// Return value : Result of the division (as a WebRtc_UWord32), i.e., the +// integer part of num/den. +// + +// +// WebRtcSpl_DivW32W16(...) +// +// Divides a WebRtc_Word32 |num| by a WebRtc_Word16 |den|. +// +// If |den|==0, (WebRtc_Word32)0x7FFFFFFF is returned. +// +// Input: +// - num : Numerator +// - den : Denominator +// +// Return value : Result of the division (as a WebRtc_Word32), i.e., the +// integer part of num/den. +// + +// +// WebRtcSpl_DivW32W16ResW16(...) +// +// Divides a WebRtc_Word32 |num| by a WebRtc_Word16 |den|, assuming that the +// result is less than 32768, otherwise an unpredictable result will occur. +// +// If |den|==0, (WebRtc_Word16)0x7FFF is returned. +// +// Input: +// - num : Numerator +// - den : Denominator +// +// Return value : Result of the division (as a WebRtc_Word16), i.e., the +// integer part of num/den. +// + +// +// WebRtcSpl_DivResultInQ31(...) +// +// Divides a WebRtc_Word32 |num| by a WebRtc_Word16 |den|, assuming that the +// absolute value of the denominator is larger than the numerator, otherwise +// an unpredictable result will occur. +// +// Input: +// - num : Numerator +// - den : Denominator +// +// Return value : Result of the division in Q31. +// + +// +// WebRtcSpl_DivW32HiLow(...) +// +// Divides a WebRtc_Word32 |num| by a denominator in hi, low format. The +// absolute value of the denominator has to be larger (or equal to) the +// numerator. +// +// Input: +// - num : Numerator +// - den_hi : High part of denominator +// - den_low : Low part of denominator +// +// Return value : Divided value in Q31 +// + +// +// WebRtcSpl_Energy(...) +// +// Calculates the energy of a vector +// +// Input: +// - vector : Vector which the energy should be calculated on +// - vector_length : Number of samples in vector +// +// Output: +// - scale_factor : Number of left bit shifts needed to get the physical +// energy value, i.e, to get the Q0 value +// +// Return value : Energy value in Q(-|scale_factor|) +// + +// +// WebRtcSpl_FilterAR(...) +// +// Performs a 32-bit AR filtering on a vector in Q12 +// +// Input: +// - ar_coef : AR-coefficient vector (values in Q12), +// ar_coef[0] must be 4096. +// - ar_coef_length : Number of coefficients in |ar_coef|. +// - in_vector : Vector to be filtered. +// - in_vector_length : Number of samples in |in_vector|. +// - filter_state : Current state (higher part) of the filter. +// - filter_state_length : Length (in samples) of |filter_state|. +// - filter_state_low : Current state (lower part) of the filter. +// - filter_state_low_length : Length (in samples) of |filter_state_low|. +// - out_vector_low_length : Maximum length (in samples) of +// |out_vector_low|. +// +// Output: +// - filter_state : Updated state (upper part) vector. +// - filter_state_low : Updated state (lower part) vector. +// - out_vector : Vector containing the upper part of the +// filtered values. +// - out_vector_low : Vector containing the lower part of the +// filtered values. +// +// Return value : Number of samples in the |out_vector|. +// + +// +// WebRtcSpl_FilterMAFastQ12(...) +// +// Performs a MA filtering on a vector in Q12 +// +// Input: +// - in_vector : Input samples (state in positions +// in_vector[-order] .. in_vector[-1]) +// - ma_coef : Filter coefficients (in Q12) +// - ma_coef_length : Number of B coefficients (order+1) +// - vector_length : Number of samples to be filtered +// +// Output: +// - out_vector : Filtered samples +// + +// +// WebRtcSpl_FilterARFastQ12(...) +// +// Performs a AR filtering on a vector in Q12 +// +// Input: +// - in_vector : Input samples +// - out_vector : State information in positions +// out_vector[-order] .. out_vector[-1] +// - ar_coef : Filter coefficients (in Q12) +// - ar_coef_length : Number of B coefficients (order+1) +// - vector_length : Number of samples to be filtered +// +// Output: +// - out_vector : Filtered samples +// + +// +// WebRtcSpl_DownsampleFast(...) +// +// Performs a MA down sampling filter on a vector +// +// Input: +// - in_vector : Input samples (state in positions +// in_vector[-order] .. in_vector[-1]) +// - in_vector_length : Number of samples in |in_vector| to be filtered. +// This must be at least +// |delay| + |factor|*(|out_vector_length|-1) + 1) +// - out_vector_length : Number of down sampled samples desired +// - ma_coef : Filter coefficients (in Q12) +// - ma_coef_length : Number of B coefficients (order+1) +// - factor : Decimation factor +// - delay : Delay of filter (compensated for in out_vector) +// +// Output: +// - out_vector : Filtered samples +// +// Return value : 0 if OK, -1 if |in_vector| is too short +// + +// +// WebRtcSpl_DotProductWithScale(...) +// +// Calculates the dot product between two (WebRtc_Word16) vectors +// +// Input: +// - vector1 : Vector 1 +// - vector2 : Vector 2 +// - vector_length : Number of samples used in the dot product +// - scaling : The number of right bit shifts to apply on each term +// during calculation to avoid overflow, i.e., the +// output will be in Q(-|scaling|) +// +// Return value : The dot product in Q(-scaling) +// + +// +// WebRtcSpl_ComplexIFFT(...) +// +// Complex Inverse FFT +// +// Computes an inverse complex 2^|stages|-point FFT on the input vector, which +// is in bit-reversed order. The original content of the vector is destroyed in +// the process, since the input is overwritten by the output, normal-ordered, +// FFT vector. With X as the input complex vector, y as the output complex +// vector and with M = 2^|stages|, the following is computed: +// +// M-1 +// y(k) = sum[X(i)*[cos(2*pi*i*k/M) + j*sin(2*pi*i*k/M)]] +// i=0 +// +// The implementations are optimized for speed, not for code size. It uses the +// decimation-in-time algorithm with radix-2 butterfly technique. +// +// Input: +// - vector : In pointer to complex vector containing 2^|stages| +// real elements interleaved with 2^|stages| imaginary +// elements. +// [ReImReImReIm....] +// The elements are in Q(-scale) domain, see more on Return +// Value below. +// +// - stages : Number of FFT stages. Must be at least 3 and at most 10, +// since the table WebRtcSpl_kSinTable1024[] is 1024 +// elements long. +// +// - mode : This parameter gives the user to choose how the FFT +// should work. +// mode==0: Low-complexity and Low-accuracy mode +// mode==1: High-complexity and High-accuracy mode +// +// Output: +// - vector : Out pointer to the FFT vector (the same as input). +// +// Return Value : The scale value that tells the number of left bit shifts +// that the elements in the |vector| should be shifted with +// in order to get Q0 values, i.e. the physically correct +// values. The scale parameter is always 0 or positive, +// except if N>1024 (|stages|>10), which returns a scale +// value of -1, indicating error. +// + +#if (defined ARM9E_GCC) || (defined ARM_WINM) || (defined ANDROID_AECOPT) +// +// WebRtcSpl_ComplexIFFT2(...) +// +// Complex or Real inverse FFT, for ARM processor only +// +// Computes a 2^|stages|-point FFT on the input vector, which can be or not be +// in bit-reversed order. If it is bit-reversed, the original content of the +// vector could be overwritten by the output by setting the first two arguments +// the same. With X as the input complex vector, y as the output complex vector +// and with M = 2^|stages|, the following is computed: +// +// M-1 +// y(k) = sum[X(i)*[cos(2*pi*i*k/M) + j*sin(2*pi*i*k/M)]] +// i=0 +// +// The implementations are optimized for speed, not for code size. It uses the +// decimation-in-time algorithm with radix-2 butterfly technique. +// +// Arguments: +// - in_vector : In pointer to complex vector containing 2^|stages| +// real elements interleaved with 2^|stages| imaginary +// elements. [ReImReImReIm....] +// The elements are in Q(-scale) domain. +// - out_vector : Output pointer to vector containing 2^|stages| real +// elements interleaved with 2^|stages| imaginary +// elements. [ReImReImReIm....] +// The output is in the Q0 domain. +// - stages : Number of FFT stages. Must be at least 3 and at most +// 10. +// - mode : Dummy input. +// +// Return value : The scale parameter is always 0, except if N>1024, +// which returns a scale value of -1, indicating error. +// +#endif + +// +// WebRtcSpl_ComplexFFT(...) +// +// Complex FFT +// +// Computes a complex 2^|stages|-point FFT on the input vector, which is in +// bit-reversed order. The original content of the vector is destroyed in +// the process, since the input is overwritten by the output, normal-ordered, +// FFT vector. With x as the input complex vector, Y as the output complex +// vector and with M = 2^|stages|, the following is computed: +// +// M-1 +// Y(k) = 1/M * sum[x(i)*[cos(2*pi*i*k/M) + j*sin(2*pi*i*k/M)]] +// i=0 +// +// The implementations are optimized for speed, not for code size. It uses the +// decimation-in-time algorithm with radix-2 butterfly technique. +// +// This routine prevents overflow by scaling by 2 before each FFT stage. This is +// a fixed scaling, for proper normalization - there will be log2(n) passes, so +// this results in an overall factor of 1/n, distributed to maximize arithmetic +// accuracy. +// +// Input: +// - vector : In pointer to complex vector containing 2^|stages| real +// elements interleaved with 2^|stages| imaginary elements. +// [ReImReImReIm....] +// The output is in the Q0 domain. +// +// - stages : Number of FFT stages. Must be at least 3 and at most 10, +// since the table WebRtcSpl_kSinTable1024[] is 1024 +// elements long. +// +// - mode : This parameter gives the user to choose how the FFT +// should work. +// mode==0: Low-complexity and Low-accuracy mode +// mode==1: High-complexity and High-accuracy mode +// +// Output: +// - vector : The output FFT vector is in the Q0 domain. +// +// Return value : The scale parameter is always 0, except if N>1024, +// which returns a scale value of -1, indicating error. +// + +#if (defined ARM9E_GCC) || (defined ARM_WINM) || (defined ANDROID_AECOPT) +// +// WebRtcSpl_ComplexFFT2(...) +// +// Complex or Real FFT, for ARM processor only +// +// Computes a 2^|stages|-point FFT on the input vector, which can be or not be +// in bit-reversed order. If it is bit-reversed, the original content of the +// vector could be overwritten by the output by setting the first two arguments +// the same. With x as the input complex vector, Y as the output complex vector +// and with M = 2^|stages|, the following is computed: +// +// M-1 +// Y(k) = 1/M * sum[x(i)*[cos(2*pi*i*k/M) + j*sin(2*pi*i*k/M)]] +// i=0 +// +// The implementations are optimized for speed, not for code size. It uses the +// decimation-in-time algorithm with radix-2 butterfly technique. +// +// Arguments: +// - in_vector : In pointer to complex vector containing 2^|stages| +// real elements interleaved with 2^|stages| imaginary +// elements. [ReImReImReIm....] +// - out_vector : Output pointer to vector containing 2^|stages| real +// elements interleaved with 2^|stages| imaginary +// elements. [ReImReImReIm....] +// The output is in the Q0 domain. +// - stages : Number of FFT stages. Must be at least 3 and at most +// 10. +// - mode : Dummy input +// +// Return value : The scale parameter is always 0, except if N>1024, +// which returns a scale value of -1, indicating error. +// +#endif + +// +// WebRtcSpl_ComplexBitReverse(...) +// +// Complex Bit Reverse +// +// This function bit-reverses the position of elements in the complex input +// vector into the output vector. +// +// If you bit-reverse a linear-order array, you obtain a bit-reversed order +// array. If you bit-reverse a bit-reversed order array, you obtain a +// linear-order array. +// +// Input: +// - vector : In pointer to complex vector containing 2^|stages| real +// elements interleaved with 2^|stages| imaginary elements. +// [ReImReImReIm....] +// - stages : Number of FFT stages. Must be at least 3 and at most 10, +// since the table WebRtcSpl_kSinTable1024[] is 1024 +// elements long. +// +// Output: +// - vector : Out pointer to complex vector in bit-reversed order. +// The input vector is over written. +// + +// +// WebRtcSpl_AnalysisQMF(...) +// +// Splits a 0-2*F Hz signal into two sub bands: 0-F Hz and F-2*F Hz. The +// current version has F = 8000, therefore, a super-wideband audio signal is +// split to lower-band 0-8 kHz and upper-band 8-16 kHz. +// +// Input: +// - in_data : Wide band speech signal, 320 samples (10 ms) +// +// Input & Output: +// - filter_state1 : Filter state for first All-pass filter +// - filter_state2 : Filter state for second All-pass filter +// +// Output: +// - low_band : Lower-band signal 0-8 kHz band, 160 samples (10 ms) +// - high_band : Upper-band signal 8-16 kHz band (flipped in frequency +// domain), 160 samples (10 ms) +// + +// +// WebRtcSpl_SynthesisQMF(...) +// +// Combines the two sub bands (0-F and F-2*F Hz) into a signal of 0-2*F +// Hz, (current version has F = 8000 Hz). So the filter combines lower-band +// (0-8 kHz) and upper-band (8-16 kHz) channels to obtain super-wideband 0-16 +// kHz audio. +// +// Input: +// - low_band : The signal with the 0-8 kHz band, 160 samples (10 ms) +// - high_band : The signal with the 8-16 kHz band, 160 samples (10 ms) +// +// Input & Output: +// - filter_state1 : Filter state for first All-pass filter +// - filter_state2 : Filter state for second All-pass filter +// +// Output: +// - out_data : Super-wideband speech signal, 0-16 kHz +// + +// WebRtc_Word16 WebRtcSpl_get_version(...) +// +// This function gives the version string of the Signal Processing Library. +// +// Input: +// - length_in_bytes : The size of Allocated space (in Bytes) where +// the version number is written to (in string format). +// +// Output: +// - version : Pointer to a buffer where the version number is written to. +// diff --git a/src/libs/webrtc/signal_processing_library/sin_table.c b/src/libs/webrtc/signal_processing_library/sin_table.c new file mode 100644 index 00000000..ea44666b --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/sin_table.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the 360 degree sine table. + * + */ + +#include "signal_processing_library.h" + +WebRtc_Word16 WebRtcSpl_kSinTable[] = { + 0, 142, 285, 428, 571, 713, 856, 998, 1140, + 1281, 1422, 1563, 1703, 1842, 1981, 2120, 2258, 2395, + 2531, 2667, 2801, 2935, 3068, 3200, 3331, 3462, 3591, + 3719, 3845, 3971, 4095, 4219, 4341, 4461, 4580, 4698, + 4815, 4930, 5043, 5155, 5265, 5374, 5481, 5586, 5690, + 5792, 5892, 5991, 6087, 6182, 6275, 6366, 6455, 6542, + 6627, 6710, 6791, 6870, 6947, 7021, 7094, 7164, 7233, + 7299, 7362, 7424, 7483, 7540, 7595, 7647, 7697, 7745, + 7791, 7834, 7874, 7912, 7948, 7982, 8012, 8041, 8067, + 8091, 8112, 8130, 8147, 8160, 8172, 8180, 8187, 8190, + 8191, 8190, 8187, 8180, 8172, 8160, 8147, 8130, 8112, + 8091, 8067, 8041, 8012, 7982, 7948, 7912, 7874, 7834, + 7791, 7745, 7697, 7647, 7595, 7540, 7483, 7424, 7362, + 7299, 7233, 7164, 7094, 7021, 6947, 6870, 6791, 6710, + 6627, 6542, 6455, 6366, 6275, 6182, 6087, 5991, 5892, + 5792, 5690, 5586, 5481, 5374, 5265, 5155, 5043, 4930, + 4815, 4698, 4580, 4461, 4341, 4219, 4096, 3971, 3845, + 3719, 3591, 3462, 3331, 3200, 3068, 2935, 2801, 2667, + 2531, 2395, 2258, 2120, 1981, 1842, 1703, 1563, 1422, + 1281, 1140, 998, 856, 713, 571, 428, 285, 142, + 0, -142, -285, -428, -571, -713, -856, -998, -1140, + -1281, -1422, -1563, -1703, -1842, -1981, -2120, -2258, -2395, + -2531, -2667, -2801, -2935, -3068, -3200, -3331, -3462, -3591, + -3719, -3845, -3971, -4095, -4219, -4341, -4461, -4580, -4698, + -4815, -4930, -5043, -5155, -5265, -5374, -5481, -5586, -5690, + -5792, -5892, -5991, -6087, -6182, -6275, -6366, -6455, -6542, + -6627, -6710, -6791, -6870, -6947, -7021, -7094, -7164, -7233, + -7299, -7362, -7424, -7483, -7540, -7595, -7647, -7697, -7745, + -7791, -7834, -7874, -7912, -7948, -7982, -8012, -8041, -8067, + -8091, -8112, -8130, -8147, -8160, -8172, -8180, -8187, -8190, + -8191, -8190, -8187, -8180, -8172, -8160, -8147, -8130, -8112, + -8091, -8067, -8041, -8012, -7982, -7948, -7912, -7874, -7834, + -7791, -7745, -7697, -7647, -7595, -7540, -7483, -7424, -7362, + -7299, -7233, -7164, -7094, -7021, -6947, -6870, -6791, -6710, + -6627, -6542, -6455, -6366, -6275, -6182, -6087, -5991, -5892, + -5792, -5690, -5586, -5481, -5374, -5265, -5155, -5043, -4930, + -4815, -4698, -4580, -4461, -4341, -4219, -4096, -3971, -3845, + -3719, -3591, -3462, -3331, -3200, -3068, -2935, -2801, -2667, + -2531, -2395, -2258, -2120, -1981, -1842, -1703, -1563, -1422, + -1281, -1140, -998, -856, -713, -571, -428, -285, -142 +}; diff --git a/src/libs/webrtc/signal_processing_library/sin_table_1024.c b/src/libs/webrtc/signal_processing_library/sin_table_1024.c new file mode 100644 index 00000000..a2007f9d --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/sin_table_1024.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the 1024 point sine table. + * + */ + +#include "signal_processing_library.h" + +WebRtc_Word16 WebRtcSpl_kSinTable1024[] = +{ + 0, 201, 402, 603, 804, 1005, 1206, 1406, + 1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011, + 3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608, + 4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195, + 6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766, + 7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319, + 9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849, + 11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353, + 12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827, + 14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268, + 15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672, + 16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036, + 18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357, + 19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631, + 20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855, + 22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027, + 23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143, + 24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201, + 25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198, + 26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132, + 27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001, + 28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802, + 28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534, + 29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195, + 30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783, + 30851, 30918, 30984, 31049, + 31113, 31175, 31236, 31297, + 31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735, + 31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097, + 32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382, + 32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588, + 32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717, + 32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766, + 32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736, + 32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628, + 32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441, + 32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176, + 32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833, + 31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413, + 31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918, + 30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349, + 30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706, + 29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992, + 28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208, + 28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355, + 27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437, + 26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456, + 25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413, + 24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311, + 23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153, + 22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942, + 20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680, + 19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371, + 18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017, + 16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623, + 15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191, + 14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724, + 12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227, + 11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703, + 9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156, + 7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589, + 6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006, + 4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411, + 3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808, + 1607, 1406, 1206, 1005, 804, 603, 402, 201, + 0, -201, -402, -603, -804, -1005, -1206, -1406, + -1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011, + -3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608, + -4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195, + -6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766, + -7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319, + -9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849, + -11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353, + -12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827, + -14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268, + -15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672, + -16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036, + -18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357, + -19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631, + -20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855, + -22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027, + -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143, + -24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201, + -25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198, + -26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132, + -27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001, + -28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802, + -28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534, + -29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195, + -30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783, + -30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297, + -31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735, + -31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097, + -32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382, + -32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588, + -32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717, + -32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766, + -32767, -32766, -32764, -32761, -32757, -32751, -32744, -32736, + -32727, -32717, -32705, -32692, -32678, -32662, -32646, -32628, + -32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441, + -32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176, + -32137, -32097, -32056, -32014, -31970, -31926, -31880, -31833, + -31785, -31735, -31684, -31633, -31580, -31525, -31470, -31413, + -31356, -31297, -31236, -31175, -31113, -31049, -30984, -30918, + -30851, -30783, -30713, -30643, -30571, -30498, -30424, -30349, + -30272, -30195, -30116, -30036, -29955, -29873, -29790, -29706, + -29621, -29534, -29446, -29358, -29268, -29177, -29085, -28992, + -28897, -28802, -28706, -28608, -28510, -28410, -28309, -28208, + -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355, + -27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437, + -26318, -26198, -26077, -25954, -25831, -25707, -25582, -25456, + -25329, -25201, -25072, -24942, -24811, -24679, -24546, -24413, + -24278, -24143, -24006, -23869, -23731, -23592, -23452, -23311, + -23169, -23027, -22883, -22739, -22594, -22448, -22301, -22153, + -22004, -21855, -21705, -21554, -21402, -21249, -21096, -20942, + -20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680, + -19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371, + -18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017, + -16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623, + -15446, -15268, -15090, -14911, -14732, -14552, -14372, -14191, + -14009, -13827, -13645, -13462, -13278, -13094, -12909, -12724, + -12539, -12353, -12166, -11980, -11792, -11604, -11416, -11227, + -11038, -10849, -10659, -10469, -10278, -10087, -9895, -9703, + -9511, -9319, -9126, -8932, -8739, -8545, -8351, -8156, + -7961, -7766, -7571, -7375, -7179, -6982, -6786, -6589, + -6392, -6195, -5997, -5799, -5601, -5403, -5205, -5006, + -4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411, + -3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808, + -1607, -1406, -1206, -1005, -804, -603, -402, -201, +}; diff --git a/src/libs/webrtc/signal_processing_library/spl.gyp b/src/libs/webrtc/signal_processing_library/spl.gyp new file mode 100644 index 00000000..2dfa0fc9 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/spl.gyp @@ -0,0 +1,83 @@ +# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +{ + 'includes': [ + '../../../../common_settings.gypi', # Common settings + ], + 'targets': [ + { + 'target_name': 'spl', + 'type': '<(library)', + 'include_dirs': [ + '../interface', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '../interface', + ], + }, + 'sources': [ + '../interface/signal_processing_library.h', + '../interface/spl_inl.h', + 'add_sat_w16.c', + 'add_sat_w32.c', + 'auto_corr_to_refl_coef.c', + 'auto_correlation.c', + 'complex_fft.c', + 'complex_ifft.c', + 'complex_bit_reverse.c', + 'copy_set_operations.c', + 'cos_table.c', + 'cross_correlation.c', + 'division_operations.c', + 'dot_product_with_scale.c', + 'downsample_fast.c', + 'energy.c', + 'filter_ar.c', + 'filter_ar_fast_q12.c', + 'filter_ma_fast_q12.c', + 'get_hanning_window.c', + 'get_scaling_square.c', + 'get_size_in_bits.c', + 'hanning_table.c', + 'ilbc_specific_functions.c', + 'levinson_durbin.c', + 'lpc_to_refl_coef.c', + 'min_max_operations.c', + 'norm_u32.c', + 'norm_w16.c', + 'norm_w32.c', + 'randn_table.c', + 'randomization_functions.c', + 'refl_coef_to_lpc.c', + 'resample.c', + 'resample_48khz.c', + 'resample_by_2.c', + 'resample_by_2_internal.c', + 'resample_by_2_internal.h', + 'resample_fractional.c', + 'sin_table.c', + 'sin_table_1024.c', + 'spl_sqrt.c', + 'spl_version.c', + 'splitting_filter.c', + 'sqrt_of_one_minus_x_squared.c', + 'sub_sat_w16.c', + 'sub_sat_w32.c', + 'vector_scaling_operations.c', + ], + }, + ], +} + +# Local Variables: +# tab-width:2 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/src/libs/webrtc/signal_processing_library/spl_inl.h b/src/libs/webrtc/signal_processing_library/spl_inl.h new file mode 100644 index 00000000..8716ca9f --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/spl_inl.h @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +// This header file includes the inline functions in +// the fix point signal processing library. + +#ifndef WEBRTC_SPL_SPL_INL_H_ +#define WEBRTC_SPL_SPL_INL_H_ + +#ifdef WEBRTC_SPL_INLINE_CALLS + +#ifdef WEBRTC_ANDROID + +WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL(WebRtc_Word32 a, WebRtc_Word32 b) +{ + WebRtc_Word32 tmp; + __asm__("mul %0, %1, %2":"=r"(tmp):"r"(a), "r"(b)); + return tmp; +} + +WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL_16_32_RSFT16(WebRtc_Word16 a, + WebRtc_Word32 b) +{ + WebRtc_Word32 tmp; + __asm__("smulwb %0, %1, %2":"=r"(tmp):"r"(b), "r"(a)); + return tmp; +} + +WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32(WebRtc_Word16 a, + WebRtc_Word16 b, + WebRtc_Word32 c) +{ + WebRtc_Word32 tmp; + __asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(tmp) : "r"(b), "r"(a)); + __asm__("smmul %0, %1, %2":"=r"(tmp):"r"(tmp), "r"(c)); + return tmp; +} + +WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32BI( + WebRtc_Word32 a, + WebRtc_Word32 b) +{ + WebRtc_Word32 tmp; + __asm__("smmul %0, %1, %2":"=r"(tmp):"r"(a), "r"(b)); + return tmp; +} + +WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL_16_16(WebRtc_Word16 a, + WebRtc_Word16 b) +{ + WebRtc_Word32 tmp; + __asm__("smulbb %0, %1, %2":"=r"(tmp):"r"(a), "r"(b)); + return tmp; +} + +WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a, + WebRtc_Word16 b) +{ + WebRtc_Word32 s_sum; + + __asm__("qadd16 %0, %1, %2":"=r"(s_sum):"r"(a), "r"(b)); + + return (WebRtc_Word16) s_sum; +} + +WEBRTC_INLINE WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1, + WebRtc_Word32 l_var2) +{ + WebRtc_Word32 l_sum; + + __asm__("qadd %0, %1, %2":"=r"(l_sum):"r"(l_var1), "r"(l_var2)); + + return l_sum; +} + +WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1, + WebRtc_Word16 var2) +{ + WebRtc_Word32 s_sub; + + __asm__("qsub16 %0, %1, %2":"=r"(s_sub):"r"(var1), "r"(var2)); + + return (WebRtc_Word16)s_sub; +} + +WEBRTC_INLINE WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1, + WebRtc_Word32 l_var2) +{ + WebRtc_Word32 l_sub; + + __asm__("qsub %0, %1, %2":"=r"(l_sub):"r"(l_var1), "r"(l_var2)); + + return l_sub; +} + +WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) +{ + WebRtc_Word32 tmp; + + __asm__("clz %0, %1":"=r"(tmp):"r"(n)); + + return (WebRtc_Word16)(32 - tmp); +} + +WEBRTC_INLINE int WebRtcSpl_NormW32(WebRtc_Word32 a) +{ + WebRtc_Word32 tmp; + + if (a <= 0) a ^= 0xFFFFFFFF; + + __asm__("clz %0, %1":"=r"(tmp):"r"(a)); + + return tmp - 1; +} + +WEBRTC_INLINE int WebRtcSpl_NormW16(WebRtc_Word16 a) +{ + int zeros; + + if (a <= 0) a ^= 0xFFFF; + + if (!(0xFF80 & a)) zeros = 8; else zeros = 0; + if (!(0xF800 & (a << zeros))) zeros += 4; + if (!(0xE000 & (a << zeros))) zeros += 2; + if (!(0xC000 & (a << zeros))) zeros += 1; + + return zeros; +} + +WEBRTC_INLINE int WebRtcSpl_NormU32(WebRtc_UWord32 a) +{ + int tmp; + + if (a == 0) return 0; + + __asm__("clz %0, %1":"=r"(tmp):"r"(a)); + + return tmp; +} + +#else + +WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a, + WebRtc_Word16 b) +{ + WebRtc_Word32 s_sum = (WebRtc_Word32) a + (WebRtc_Word32) b; + + if (s_sum > WEBRTC_SPL_WORD16_MAX) + s_sum = WEBRTC_SPL_WORD16_MAX; + else if (s_sum < WEBRTC_SPL_WORD16_MIN) + s_sum = WEBRTC_SPL_WORD16_MIN; + + return (WebRtc_Word16)s_sum; +} + +WEBRTC_INLINE WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1, + WebRtc_Word32 l_var2) +{ + WebRtc_Word32 l_sum; + + // perform long addition + l_sum = l_var1 + l_var2; + + // check for under or overflow + if (WEBRTC_SPL_IS_NEG (l_var1)) + { + if (WEBRTC_SPL_IS_NEG (l_var2) && !WEBRTC_SPL_IS_NEG (l_sum)) + { + l_sum = (WebRtc_Word32)0x80000000; + } + } + else + { + if (!WEBRTC_SPL_IS_NEG (l_var2) && WEBRTC_SPL_IS_NEG (l_sum)) + { + l_sum = (WebRtc_Word32)0x7FFFFFFF; + } + } + + return l_sum; +} + +WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_SubSatW16( WebRtc_Word16 var1, + WebRtc_Word16 var2) +{ + WebRtc_Word32 l_diff; + WebRtc_Word16 s_diff; + + // perform subtraction + l_diff = (WebRtc_Word32)var1 - (WebRtc_Word32)var2; + + // default setting + s_diff = (WebRtc_Word16) l_diff; + + // check for overflow + if (l_diff > (WebRtc_Word32)32767) + s_diff = (WebRtc_Word16)32767; + + // check for underflow + if (l_diff < (WebRtc_Word32)-32768) + s_diff = (WebRtc_Word16)-32768; + + return s_diff; +} + +WEBRTC_INLINE WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1, + WebRtc_Word32 l_var2) +{ + WebRtc_Word32 l_diff; + + // perform subtraction + l_diff = l_var1 - l_var2; + + // check for underflow + if ((l_var1 < 0) && (l_var2 > 0) && (l_diff > 0)) + l_diff = (WebRtc_Word32)0x80000000; + // check for overflow + if ((l_var1 > 0) && (l_var2 < 0) && (l_diff < 0)) + l_diff = (WebRtc_Word32)0x7FFFFFFF; + + return l_diff; +} + +WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) +{ + + int bits; + + if ((0xFFFF0000 & n)) bits = 16; else bits = 0; + if ((0x0000FF00 & (n >> bits))) bits += 8; + if ((0x000000F0 & (n >> bits))) bits += 4; + if ((0x0000000C & (n >> bits))) bits += 2; + if ((0x00000002 & (n >> bits))) bits += 1; + if ((0x00000001 & (n >> bits))) bits += 1; + + return bits; +} + +WEBRTC_INLINE int WebRtcSpl_NormW32(WebRtc_Word32 a) +{ + int zeros; + + if (a <= 0) a ^= 0xFFFFFFFF; + + if (!(0xFFFF8000 & a)) zeros = 16; else zeros = 0; + if (!(0xFF800000 & (a << zeros))) zeros += 8; + if (!(0xF8000000 & (a << zeros))) zeros += 4; + if (!(0xE0000000 & (a << zeros))) zeros += 2; + if (!(0xC0000000 & (a << zeros))) zeros += 1; + + return zeros; +} + +WEBRTC_INLINE int WebRtcSpl_NormW16(WebRtc_Word16 a) +{ + int zeros; + + if (a <= 0) a ^= 0xFFFF; + + if (!(0xFF80 & a)) zeros = 8; else zeros = 0; + if (!(0xF800 & (a << zeros))) zeros += 4; + if (!(0xE000 & (a << zeros))) zeros += 2; + if (!(0xC000 & (a << zeros))) zeros += 1; + + return zeros; +} + +WEBRTC_INLINE int WebRtcSpl_NormU32(WebRtc_UWord32 a) +{ + int zeros; + + if (a == 0) return 0; + + if (!(0xFFFF0000 & a)) zeros = 16; else zeros = 0; + if (!(0xFF000000 & (a << zeros))) zeros += 8; + if (!(0xF0000000 & (a << zeros))) zeros += 4; + if (!(0xC0000000 & (a << zeros))) zeros += 2; + if (!(0x80000000 & (a << zeros))) zeros += 1; + + return zeros; +} + +#endif // WEBRTC_ANDROID +#endif // WEBRTC_SPL_INLINE_CALLS +#endif // WEBRTC_SPL_SPL_INL_H_ diff --git a/src/libs/webrtc/signal_processing_library/spl_sqrt.c b/src/libs/webrtc/signal_processing_library/spl_sqrt.c new file mode 100644 index 00000000..d00c9cf4 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/spl_sqrt.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the function WebRtcSpl_Sqrt(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#include <assert.h> +int32_t WebRtcSpl_SqrtLocal(int32_t in); +int32_t WebRtcSpl_SqrtLocal(int32_t in) +{ + int16_t x_half, t16; + int32_t A, B, x2; + /* The following block performs: + y=in/2 + x=y-2^30 + x_half=x/2^31 + t = 1 + (x_half) - 0.5*((x_half)^2) + 0.5*((x_half)^3) - 0.625*((x_half)^4) + + 0.875*((x_half)^5) + */ + B = in / 2; + B = B - ((int32_t)0x40000000); // B = in/2 - 1/2 + x_half = (int16_t)(B >> 16); // x_half = x/2 = (in-1)/2 + B = B + ((int32_t)0x40000000); // B = 1 + x/2 + B = B + ((int32_t)0x40000000); // Add 0.5 twice (since 1.0 does not exist in Q31) + x2 = ((int32_t)x_half) * ((int32_t)x_half) * 2; // A = (x/2)^2 + A = -x2; // A = -(x/2)^2 + B = B + (A >> 1); // B = 1 + x/2 - 0.5*(x/2)^2 + A >>= 16; + A = A * A * 2; // A = (x/2)^4 + t16 = (int16_t)(A >> 16); + B = B + WEBRTC_SPL_MUL_16_16(-20480, t16) * 2; // B = B - 0.625*A + // After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4 + A = WEBRTC_SPL_MUL_16_16(x_half, t16) * 2; // A = (x/2)^5 + t16 = (int16_t)(A >> 16); + B = B + WEBRTC_SPL_MUL_16_16(28672, t16) * 2; // B = B + 0.875*A + // After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4 + 0.875*(x/2)^5 + t16 = (int16_t)(x2 >> 16); + A = WEBRTC_SPL_MUL_16_16(x_half, t16) * 2; // A = x/2^3 + B = B + (A >> 1); // B = B + 0.5*A + // After this, B = 1 + x/2 - 0.5*(x/2)^2 + 0.5*(x/2)^3 - 0.625*(x/2)^4 + 0.875*(x/2)^5 + B = B + ((int32_t)32768); // Round off bit + return B; +} + +int32_t WebRtcSpl_Sqrt(int32_t value) +{ + /* + Algorithm: + Six term Taylor Series is used here to compute the square root of a number + y^0.5 = (1+x)^0.5 where x = y-1 + = 1+(x/2)-0.5*((x/2)^2+0.5*((x/2)^3-0.625*((x/2)^4+0.875*((x/2)^5) + 0.5 <= x < 1 + Example of how the algorithm works, with ut=sqrt(in), and + with in=73632 and ut=271 (even shift value case): + in=73632 + y= in/131072 + x=y-1 + t = 1 + (x/2) - 0.5*((x/2)^2) + 0.5*((x/2)^3) - 0.625*((x/2)^4) + 0.875*((x/2)^5) + ut=t*(1/sqrt(2))*512 + or: + in=73632 + in2=73632*2^14 + y= in2/2^31 + x=y-1 + t = 1 + (x/2) - 0.5*((x/2)^2) + 0.5*((x/2)^3) - 0.625*((x/2)^4) + 0.875*((x/2)^5) + ut=t*(1/sqrt(2)) + ut2=ut*2^9 + which gives: + in = 73632 + in2 = 1206386688 + y = 0.56176757812500 + x = -0.43823242187500 + t = 0.74973506527313 + ut = 0.53014274874797 + ut2 = 2.714330873589594e+002 + or: + in=73632 + in2=73632*2^14 + y=in2/2 + x=y-2^30 + x_half=x/2^31 + t = 1 + (x_half) - 0.5*((x_half)^2) + 0.5*((x_half)^3) - 0.625*((x_half)^4) + + 0.875*((x_half)^5) + ut=t*(1/sqrt(2)) + ut2=ut*2^9 + which gives: + in = 73632 + in2 = 1206386688 + y = 603193344 + x = -470548480 + x_half = -0.21911621093750 + t = 0.74973506527313 + ut = 0.53014274874797 + ut2 = 2.714330873589594e+002 + */ + int16_t x_norm, nshift, t16, sh; + int32_t A; + int16_t k_sqrt_2 = 23170; // 1/sqrt2 (==5a82) + A = value; + if (A == 0) + return (int32_t)0; // sqrt(0) = 0 + sh = WebRtcSpl_NormW32(A); // # shifts to normalize A + A = WEBRTC_SPL_LSHIFT_W32(A, sh); // Normalize A + if (A < (WEBRTC_SPL_WORD32_MAX - 32767)) + { + A = A + ((int32_t)32768); // Round off bit + } else + { + A = WEBRTC_SPL_WORD32_MAX; + } + x_norm = (int16_t)(A >> 16); // x_norm = AH + nshift = (sh / 2); + assert(nshift >= 0); + A = (int32_t)WEBRTC_SPL_LSHIFT_W32((int32_t)x_norm, 16); + A = WEBRTC_SPL_ABS_W32(A); // A = abs(x_norm<<16) + A = WebRtcSpl_SqrtLocal(A); // A = sqrt(A) + if (2 * nshift == sh) { + // Even shift value case + t16 = (int16_t)(A >> 16); // t16 = AH + A = WEBRTC_SPL_MUL_16_16(k_sqrt_2, t16) * 2; // A = 1/sqrt(2)*t16 + A = A + ((int32_t)32768); // Round off + A = A & ((int32_t)0x7fff0000); // Round off + A >>= 15; // A = A>>16 + } else + { + A >>= 16; // A = A>>16 + } + A = A & ((int32_t)0x0000ffff); + A >>= nshift; // De-normalize the result. + return A; +} diff --git a/src/libs/webrtc/signal_processing_library/spl_sqrt.s b/src/libs/webrtc/signal_processing_library/spl_sqrt.s new file mode 100644 index 00000000..f546fce4 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/spl_sqrt.s @@ -0,0 +1,93 @@ +@ +@ Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. +@ +@ Use of this source code is governed by a BSD-style license +@ that can be found in the LICENSE file in the root of the source +@ tree. An additional intellectual property rights grant can be found +@ in the file PATENTS. All contributing project authors may +@ be found in the AUTHORS file in the root of the source tree. + +@ sqrt() routine. 3 cycles/bit, total 51 cycles. +@ IN : r0 32 bit unsigned integer +@ OUT: r0 = INT (SQRT (r0)), precision is 16 bits +@ TMP: r1, r2 + +.global WebRtcSpl_Sqrt + +.align 2 +.section .text.WebRtcSpl_Sqrt: +WebRtcSpl_Sqrt: +.fnstart + + MOV r1, #3 << 30 + MOV r2, #1 << 30 + + @ unroll for i = 0 .. 15 + + CMP r0, r2, ROR #2 * 0 + SUBHS r0, r0, r2, ROR #2 * 0 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 1 + SUBHS r0, r0, r2, ROR #2 * 1 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 2 + SUBHS r0, r0, r2, ROR #2 * 2 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 3 + SUBHS r0, r0, r2, ROR #2 * 3 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 4 + SUBHS r0, r0, r2, ROR #2 * 4 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 5 + SUBHS r0, r0, r2, ROR #2 * 5 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 6 + SUBHS r0, r0, r2, ROR #2 * 6 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 7 + SUBHS r0, r0, r2, ROR #2 * 7 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 8 + SUBHS r0, r0, r2, ROR #2 * 8 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 9 + SUBHS r0, r0, r2, ROR #2 * 9 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 10 + SUBHS r0, r0, r2, ROR #2 * 10 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 11 + SUBHS r0, r0, r2, ROR #2 * 11 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 12 + SUBHS r0, r0, r2, ROR #2 * 12 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 13 + SUBHS r0, r0, r2, ROR #2 * 13 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 14 + SUBHS r0, r0, r2, ROR #2 * 14 + ADC r2, r1, r2, LSL #1 + + CMP r0, r2, ROR #2 * 15 + SUBHS r0, r0, r2, ROR #2 * 15 + ADC r2, r1, r2, LSL #1 + + BIC r0, r2, #3 << 30 @ for rounding add: CMP r0, r2 ADC r2, #1 + +.fnend diff --git a/src/libs/webrtc/signal_processing_library/spl_version.c b/src/libs/webrtc/signal_processing_library/spl_version.c new file mode 100644 index 00000000..936925ea --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/spl_version.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_get_version(). + * The description header can be found in signal_processing_library.h + * + */ + +#include <string.h> +#include "signal_processing_library.h" + +WebRtc_Word16 WebRtcSpl_get_version(char* version, WebRtc_Word16 length_in_bytes) +{ + strncpy(version, "1.2.0", length_in_bytes); + return 0; +} diff --git a/src/libs/webrtc/signal_processing_library/splitting_filter.c b/src/libs/webrtc/signal_processing_library/splitting_filter.c new file mode 100644 index 00000000..98442f43 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/splitting_filter.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file contains the splitting filter functions. + * + */ + +#include "signal_processing_library.h" + +// Number of samples in a low/high-band frame. +enum +{ + kBandFrameLength = 160 +}; + +// QMF filter coefficients in Q16. +static const WebRtc_UWord16 WebRtcSpl_kAllPassFilter1[3] = {6418, 36982, 57261}; +static const WebRtc_UWord16 WebRtcSpl_kAllPassFilter2[3] = {21333, 49062, 63010}; + +/////////////////////////////////////////////////////////////////////////////////////////////// +// WebRtcSpl_AllPassQMF(...) +// +// Allpass filter used by the analysis and synthesis parts of the QMF filter. +// +// Input: +// - in_data : Input data sequence (Q10) +// - data_length : Length of data sequence (>2) +// - filter_coefficients : Filter coefficients (length 3, Q16) +// +// Input & Output: +// - filter_state : Filter state (length 6, Q10). +// +// Output: +// - out_data : Output data sequence (Q10), length equal to +// |data_length| +// + +void WebRtcSpl_AllPassQMF(WebRtc_Word32* in_data, const WebRtc_Word16 data_length, + WebRtc_Word32* out_data, const WebRtc_UWord16* filter_coefficients, + WebRtc_Word32* filter_state) +{ + // The procedure is to filter the input with three first order all pass filters + // (cascade operations). + // + // a_3 + q^-1 a_2 + q^-1 a_1 + q^-1 + // y[n] = ----------- ----------- ----------- x[n] + // 1 + a_3q^-1 1 + a_2q^-1 1 + a_1q^-1 + // + // The input vector |filter_coefficients| includes these three filter coefficients. + // The filter state contains the in_data state, in_data[-1], followed by + // the out_data state, out_data[-1]. This is repeated for each cascade. + // The first cascade filter will filter the |in_data| and store the output in + // |out_data|. The second will the take the |out_data| as input and make an + // intermediate storage in |in_data|, to save memory. The third, and final, cascade + // filter operation takes the |in_data| (which is the output from the previous cascade + // filter) and store the output in |out_data|. + // Note that the input vector values are changed during the process. + WebRtc_Word16 k; + WebRtc_Word32 diff; + // First all-pass cascade; filter from in_data to out_data. + + // Let y_i[n] indicate the output of cascade filter i (with filter coefficient a_i) at + // vector position n. Then the final output will be y[n] = y_3[n] + + // First loop, use the states stored in memory. + // "diff" should be safe from wrap around since max values are 2^25 + diff = WEBRTC_SPL_SUB_SAT_W32(in_data[0], filter_state[1]); // = (x[0] - y_1[-1]) + // y_1[0] = x[-1] + a_1 * (x[0] - y_1[-1]) + out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, filter_state[0]); + + // For the remaining loops, use previous values. + for (k = 1; k < data_length; k++) + { + diff = WEBRTC_SPL_SUB_SAT_W32(in_data[k], out_data[k - 1]); // = (x[n] - y_1[n-1]) + // y_1[n] = x[n-1] + a_1 * (x[n] - y_1[n-1]) + out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[0], diff, in_data[k - 1]); + } + + // Update states. + filter_state[0] = in_data[data_length - 1]; // x[N-1], becomes x[-1] next time + filter_state[1] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time + + // Second all-pass cascade; filter from out_data to in_data. + diff = WEBRTC_SPL_SUB_SAT_W32(out_data[0], filter_state[3]); // = (y_1[0] - y_2[-1]) + // y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1]) + in_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, filter_state[2]); + for (k = 1; k < data_length; k++) + { + diff = WEBRTC_SPL_SUB_SAT_W32(out_data[k], in_data[k - 1]); // =(y_1[n] - y_2[n-1]) + // y_2[0] = y_1[-1] + a_2 * (y_1[0] - y_2[-1]) + in_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[1], diff, out_data[k-1]); + } + + filter_state[2] = out_data[data_length - 1]; // y_1[N-1], becomes y_1[-1] next time + filter_state[3] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time + + // Third all-pass cascade; filter from in_data to out_data. + diff = WEBRTC_SPL_SUB_SAT_W32(in_data[0], filter_state[5]); // = (y_2[0] - y[-1]) + // y[0] = y_2[-1] + a_3 * (y_2[0] - y[-1]) + out_data[0] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, filter_state[4]); + for (k = 1; k < data_length; k++) + { + diff = WEBRTC_SPL_SUB_SAT_W32(in_data[k], out_data[k - 1]); // = (y_2[n] - y[n-1]) + // y[n] = y_2[n-1] + a_3 * (y_2[n] - y[n-1]) + out_data[k] = WEBRTC_SPL_SCALEDIFF32(filter_coefficients[2], diff, in_data[k-1]); + } + filter_state[4] = in_data[data_length - 1]; // y_2[N-1], becomes y_2[-1] next time + filter_state[5] = out_data[data_length - 1]; // y[N-1], becomes y[-1] next time +} + +void WebRtcSpl_AnalysisQMF(const WebRtc_Word16* in_data, WebRtc_Word16* low_band, + WebRtc_Word16* high_band, WebRtc_Word32* filter_state1, + WebRtc_Word32* filter_state2) +{ + WebRtc_Word16 i; + WebRtc_Word16 k; + WebRtc_Word32 tmp; + WebRtc_Word32 half_in1[kBandFrameLength]; + WebRtc_Word32 half_in2[kBandFrameLength]; + WebRtc_Word32 filter1[kBandFrameLength]; + WebRtc_Word32 filter2[kBandFrameLength]; + + // Split even and odd samples. Also shift them to Q10. + for (i = 0, k = 0; i < kBandFrameLength; i++, k += 2) + { + half_in2[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in_data[k], 10); + half_in1[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in_data[k + 1], 10); + } + + // All pass filter even and odd samples, independently. + WebRtcSpl_AllPassQMF(half_in1, kBandFrameLength, filter1, WebRtcSpl_kAllPassFilter1, + filter_state1); + WebRtcSpl_AllPassQMF(half_in2, kBandFrameLength, filter2, WebRtcSpl_kAllPassFilter2, + filter_state2); + + // Take the sum and difference of filtered version of odd and even + // branches to get upper & lower band. + for (i = 0; i < kBandFrameLength; i++) + { + tmp = filter1[i] + filter2[i] + 1024; + tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11); + low_band[i] = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, + tmp, WEBRTC_SPL_WORD16_MIN); + + tmp = filter1[i] - filter2[i] + 1024; + tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11); + high_band[i] = (WebRtc_Word16)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, + tmp, WEBRTC_SPL_WORD16_MIN); + } +} + +void WebRtcSpl_SynthesisQMF(const WebRtc_Word16* low_band, const WebRtc_Word16* high_band, + WebRtc_Word16* out_data, WebRtc_Word32* filter_state1, + WebRtc_Word32* filter_state2) +{ + WebRtc_Word32 tmp; + WebRtc_Word32 half_in1[kBandFrameLength]; + WebRtc_Word32 half_in2[kBandFrameLength]; + WebRtc_Word32 filter1[kBandFrameLength]; + WebRtc_Word32 filter2[kBandFrameLength]; + WebRtc_Word16 i; + WebRtc_Word16 k; + + // Obtain the sum and difference channels out of upper and lower-band channels. + // Also shift to Q10 domain. + for (i = 0; i < kBandFrameLength; i++) + { + tmp = (WebRtc_Word32)low_band[i] + (WebRtc_Word32)high_band[i]; + half_in1[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10); + tmp = (WebRtc_Word32)low_band[i] - (WebRtc_Word32)high_band[i]; + half_in2[i] = WEBRTC_SPL_LSHIFT_W32(tmp, 10); + } + + // all-pass filter the sum and difference channels + WebRtcSpl_AllPassQMF(half_in1, kBandFrameLength, filter1, WebRtcSpl_kAllPassFilter2, + filter_state1); + WebRtcSpl_AllPassQMF(half_in2, kBandFrameLength, filter2, WebRtcSpl_kAllPassFilter1, + filter_state2); + + // The filtered signals are even and odd samples of the output. Combine + // them. The signals are Q10 should shift them back to Q0 and take care of + // saturation. + for (i = 0, k = 0; i < kBandFrameLength; i++) + { + tmp = WEBRTC_SPL_RSHIFT_W32(filter2[i] + 512, 10); + out_data[k++] = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmp, -32768); + + tmp = WEBRTC_SPL_RSHIFT_W32(filter1[i] + 512, 10); + out_data[k++] = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmp, -32768); + } + +} diff --git a/src/libs/webrtc/signal_processing_library/sqrt_of_one_minus_x_squared.c b/src/libs/webrtc/signal_processing_library/sqrt_of_one_minus_x_squared.c new file mode 100644 index 00000000..9fb2c73b --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/sqrt_of_one_minus_x_squared.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_SqrtOfOneMinusXSquared(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +void WebRtcSpl_SqrtOfOneMinusXSquared(WebRtc_Word16 *xQ15, int vector_length, + WebRtc_Word16 *yQ15) +{ + WebRtc_Word32 sq; + int m; + WebRtc_Word16 tmp; + + for (m = 0; m < vector_length; m++) + { + tmp = xQ15[m]; + sq = WEBRTC_SPL_MUL_16_16(tmp, tmp); // x^2 in Q30 + sq = 1073741823 - sq; // 1-x^2, where 1 ~= 0.99999999906 is 1073741823 in Q30 + sq = WebRtcSpl_Sqrt(sq); // sqrt(1-x^2) in Q15 + yQ15[m] = (WebRtc_Word16)sq; + } +} diff --git a/src/libs/webrtc/signal_processing_library/sub_sat_w16.c b/src/libs/webrtc/signal_processing_library/sub_sat_w16.c new file mode 100644 index 00000000..a48c3d5d --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/sub_sat_w16.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_SubSatW16(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS +#ifndef XSCALE_OPT + +WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1, WebRtc_Word16 var2) +{ + WebRtc_Word32 l_diff; + WebRtc_Word16 s_diff; + + // perform subtraction + l_diff = (WebRtc_Word32)var1 - (WebRtc_Word32)var2; + + // default setting + s_diff = (WebRtc_Word16)l_diff; + + // check for overflow + if (l_diff > (WebRtc_Word32)32767) + s_diff = (WebRtc_Word16)32767; + + // check for underflow + if (l_diff < (WebRtc_Word32)-32768) + s_diff = (WebRtc_Word16)-32768; + + return s_diff; +} + +#else +#pragma message(">> WebRtcSpl_SubSatW16.c is excluded from this build") +#endif // XSCALE_OPT +#endif // SPL_NO_DOUBLE_IMPLEMENTATIONS diff --git a/src/libs/webrtc/signal_processing_library/sub_sat_w32.c b/src/libs/webrtc/signal_processing_library/sub_sat_w32.c new file mode 100644 index 00000000..add3675b --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/sub_sat_w32.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the function WebRtcSpl_SubSatW32(). + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS + +WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 var1, WebRtc_Word32 var2) +{ + WebRtc_Word32 l_diff; + + // perform subtraction + l_diff = var1 - var2; + + // check for underflow + if ((var1 < 0) && (var2 > 0) && (l_diff > 0)) + l_diff = (WebRtc_Word32)0x80000000; + // check for overflow + if ((var1 > 0) && (var2 < 0) && (l_diff < 0)) + l_diff = (WebRtc_Word32)0x7FFFFFFF; + + return l_diff; +} + +#endif diff --git a/src/libs/webrtc/signal_processing_library/vector_scaling_operations.c b/src/libs/webrtc/signal_processing_library/vector_scaling_operations.c new file mode 100644 index 00000000..47362ee8 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/vector_scaling_operations.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains implementations of the functions + * WebRtcSpl_VectorBitShiftW16() + * WebRtcSpl_VectorBitShiftW32() + * WebRtcSpl_VectorBitShiftW32ToW16() + * WebRtcSpl_ScaleVector() + * WebRtcSpl_ScaleVectorWithSat() + * WebRtcSpl_ScaleAndAddVectors() + * + * The description header can be found in signal_processing_library.h + * + */ + +#include "signal_processing_library.h" + +void WebRtcSpl_VectorBitShiftW16(WebRtc_Word16 *res, + WebRtc_Word16 length, + G_CONST WebRtc_Word16 *in, + WebRtc_Word16 right_shifts) +{ + int i; + + if (right_shifts > 0) + { + for (i = length; i > 0; i--) + { + (*res++) = ((*in++) >> right_shifts); + } + } else + { + for (i = length; i > 0; i--) + { + (*res++) = ((*in++) << (-right_shifts)); + } + } +} + +void WebRtcSpl_VectorBitShiftW32(WebRtc_Word32 *out_vector, + WebRtc_Word16 vector_length, + G_CONST WebRtc_Word32 *in_vector, + WebRtc_Word16 right_shifts) +{ + int i; + + if (right_shifts > 0) + { + for (i = vector_length; i > 0; i--) + { + (*out_vector++) = ((*in_vector++) >> right_shifts); + } + } else + { + for (i = vector_length; i > 0; i--) + { + (*out_vector++) = ((*in_vector++) << (-right_shifts)); + } + } +} + +void WebRtcSpl_VectorBitShiftW32ToW16(WebRtc_Word16 *res, + WebRtc_Word16 length, + G_CONST WebRtc_Word32 *in, + WebRtc_Word16 right_shifts) +{ + int i; + + if (right_shifts >= 0) + { + for (i = length; i > 0; i--) + { + (*res++) = (WebRtc_Word16)((*in++) >> right_shifts); + } + } else + { + WebRtc_Word16 left_shifts = -right_shifts; + for (i = length; i > 0; i--) + { + (*res++) = (WebRtc_Word16)((*in++) << left_shifts); + } + } +} + +void WebRtcSpl_ScaleVector(G_CONST WebRtc_Word16 *in_vector, WebRtc_Word16 *out_vector, + WebRtc_Word16 gain, WebRtc_Word16 in_vector_length, + WebRtc_Word16 right_shifts) +{ + // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts + int i; + G_CONST WebRtc_Word16 *inptr; + WebRtc_Word16 *outptr; + + inptr = in_vector; + outptr = out_vector; + + for (i = 0; i < in_vector_length; i++) + { + (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts); + } +} + +void WebRtcSpl_ScaleVectorWithSat(G_CONST WebRtc_Word16 *in_vector, WebRtc_Word16 *out_vector, + WebRtc_Word16 gain, WebRtc_Word16 in_vector_length, + WebRtc_Word16 right_shifts) +{ + // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts + int i; + WebRtc_Word32 tmpW32; + G_CONST WebRtc_Word16 *inptr; + WebRtc_Word16 *outptr; + + inptr = in_vector; + outptr = out_vector; + + for (i = 0; i < in_vector_length; i++) + { + tmpW32 = WEBRTC_SPL_MUL_16_16_RSFT(*inptr++, gain, right_shifts); + ( *outptr++) = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, tmpW32, -32768); + } +} + +void WebRtcSpl_ScaleAndAddVectors(G_CONST WebRtc_Word16 *in1, WebRtc_Word16 gain1, int shift1, + G_CONST WebRtc_Word16 *in2, WebRtc_Word16 gain2, int shift2, + WebRtc_Word16 *out, int vector_length) +{ + // Performs vector operation: out = (gain1*in1)>>shift1 + (gain2*in2)>>shift2 + int i; + G_CONST WebRtc_Word16 *in1ptr; + G_CONST WebRtc_Word16 *in2ptr; + WebRtc_Word16 *outptr; + + in1ptr = in1; + in2ptr = in2; + outptr = out; + + for (i = 0; i < vector_length; i++) + { + (*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gain1, *in1ptr++, shift1) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gain2, *in2ptr++, shift2); + } +} diff --git a/src/libs/webrtc/signal_processing_library/webrtc_fft_4ofq14_gcc_android.s b/src/libs/webrtc/signal_processing_library/webrtc_fft_4ofq14_gcc_android.s new file mode 100644 index 00000000..e6926404 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/webrtc_fft_4ofq14_gcc_android.s @@ -0,0 +1,227 @@ + .globl FFT_4OFQ14 + +FFT_4OFQ14: + stmdb sp!, {r4 - r11, lr} + ldr lr, =s_Q14S_8 + ldr lr, [lr] + cmp r2, lr + movgt r0, #1 + ldmgtia sp!, {r4 - r11, pc} + stmdb sp!, {r1, r2} + mov r3, #0 + mov r2, r2 + +LBL1: + add r12, r0, r3, lsl #2 + add r12, r12, r2, lsr #1 + ldrsh r5, [r12, #2] + ldrsh r4, [r12], +r2 + ldrsh r9, [r12, #2] + ldrsh r8, [r12], +r2 + ldrsh r7, [r12, #2] + ldrsh r6, [r12], +r2 + ldrsh r11, [r12, #2] + ldrsh r10, [r12], +r2 + add r4, r4, r6 + add r5, r5, r7 + sub r6, r4, r6, lsl #1 + sub r7, r5, r7, lsl #1 + sub r12, r8, r10 + sub lr, r9, r11 + add r10, r8, r10 + add r11, r9, r11 + sub r9, r4, r10 + sub r8, r5, r11 + add r4, r4, r10 + add r5, r5, r11 + sub r10, r6, lr + add r11, r7, r12 + add r6, r6, lr + sub r7, r7, r12 + ldr lr, =t_Q14R_rad8 + ldrsh lr, [lr] + stmdb sp!, {r2} + add r12, r6, r7 + mul r6, r12, lr + rsb r12, r12, r7, lsl #1 + mul r7, r12, lr + sub r12, r11, r10 + mul r10, r12, lr + sub r12, r12, r11, lsl #1 + mul r11, r12, lr + ldmia sp!, {r2} + stmdb sp!, {r4 - r11} + add r4, r0, r3, lsl #2 + ldrsh r7, [r4, #2] + ldrsh r6, [r4], +r2 + ldrsh r11, [r4, #2] + ldrsh r10, [r4], +r2 + ldrsh r9, [r4, #2] + ldrsh r8, [r4], +r2 + ldrsh lr, [r4, #2] + ldrsh r12, [r4], +r2 + mov r7, r7, asr #3 + mov r6, r6, asr #3 + add r6, r6, r8, asr #3 + add r7, r7, r9, asr #3 + sub r8, r6, r8, asr #2 + sub r9, r7, r9, asr #2 + sub r4, r10, r12 + sub r5, r11, lr + add r10, r10, r12 + add r11, r11, lr + add r6, r6, r10, asr #3 + add r7, r7, r11, asr #3 + sub r10, r6, r10, asr #2 + sub r11, r7, r11, asr #2 + sub r12, r8, r5, asr #3 + add lr, r9, r4, asr #3 + add r8, r8, r5, asr #3 + sub r9, r9, r4, asr #3 + ldmia sp!, {r4, r5} + add r6, r6, r4, asr #3 + add r7, r7, r5, asr #3 + sub r4, r6, r4, asr #2 + sub r5, r7, r5, asr #2 + strh r7, [r1, #2] + strh r6, [r1], #4 + ldmia sp!, {r6, r7} + add r8, r8, r6, asr #17 + add r9, r9, r7, asr #17 + sub r6, r8, r6, asr #16 + sub r7, r9, r7, asr #16 + strh r9, [r1, #2] + strh r8, [r1], #4 + ldmia sp!, {r8, r9} + add r10, r10, r8, asr #3 + sub r11, r11, r9, asr #3 + sub r8, r10, r8, asr #2 + add r9, r11, r9, asr #2 + strh r11, [r1, #2] + strh r10, [r1], #4 + ldmia sp!, {r10, r11} + add r12, r12, r10, asr #17 + add lr, lr, r11, asr #17 + sub r10, r12, r10, asr #16 + sub r11, lr, r11, asr #16 + strh lr, [r1, #2] + strh r12, [r1], #4 + strh r5, [r1, #2] + strh r4, [r1], #4 + strh r7, [r1, #2] + strh r6, [r1], #4 + strh r9, [r1, #2] + strh r8, [r1], #4 + strh r11, [r1, #2] + strh r10, [r1], #4 + eor r3, r3, r2, lsr #4 + tst r3, r2, lsr #4 + bne LBL1 + + eor r3, r3, r2, lsr #5 + tst r3, r2, lsr #5 + bne LBL1 + + mov r12, r2, lsr #6 + +LBL2: + eor r3, r3, r12 + tst r3, r12 + bne LBL1 + + movs r12, r12, lsr #1 + bne LBL2 + + ldmia sp!, {r1, r2} + mov r3, r2, lsr #3 + mov r2, #0x20 + ldr r0, =t_Q14S_8 + cmp r3, #1 + beq LBL3 + +LBL6: + mov r3, r3, lsr #2 + stmdb sp!, {r1, r3} + add r12, r2, r2, lsl #1 + add r1, r1, r12 + sub r3, r3, #1, 16 + +LBL5: + add r3, r3, r2, lsl #14 + +LBL4: + ldrsh r6, [r0], #2 + ldrsh r7, [r0], #2 + ldrsh r8, [r0], #2 + ldrsh r9, [r0], #2 + ldrsh r10, [r0], #2 + ldrsh r11, [r0], #2 + ldrsh r5, [r1, #2] + ldrsh r4, [r1], -r2 + sub lr, r5, r4 + mul r12, lr, r11 + add lr, r10, r11, lsl #1 + mla r11, r5, r10, r12 + mla r10, r4, lr, r12 + ldrsh r5, [r1, #2] + ldrsh r4, [r1], -r2 + sub lr, r5, r4 + mul r12, lr, r9 + add lr, r8, r9, lsl #1 + mla r9, r5, r8, r12 + mla r8, r4, lr, r12 + ldrsh r5, [r1, #2] + ldrsh r4, [r1], -r2 + sub lr, r5, r4 + mul r12, lr, r7 + add lr, r6, r7, lsl #1 + mla r7, r5, r6, r12 + mla r6, r4, lr, r12 + ldrsh r5, [r1, #2] + ldrsh r4, [r1] + mov r5, r5, asr #2 + mov r4, r4, asr #2 + add r12, r4, r6, asr #16 + add lr, r5, r7, asr #16 + sub r4, r4, r6, asr #16 + sub r5, r5, r7, asr #16 + add r6, r8, r10 + add r7, r9, r11 + sub r8, r8, r10 + sub r9, r9, r11 + add r10, r12, r6, asr #16 + add r11, lr, r7, asr #16 + strh r11, [r1, #2] + strh r10, [r1], +r2 + add r10, r4, r9, asr #16 + sub r11, r5, r8, asr #16 + strh r11, [r1, #2] + strh r10, [r1], +r2 + sub r10, r12, r6, asr #16 + sub r11, lr, r7, asr #16 + strh r11, [r1, #2] + strh r10, [r1], +r2 + sub r10, r4, r9, asr #16 + add r11, r5, r8, asr #16 + strh r11, [r1, #2] + strh r10, [r1], #4 + subs r3, r3, #1, 16 + bge LBL4 + add r12, r2, r2, lsl #1 + add r1, r1, r12 + sub r0, r0, r12 + sub r3, r3, #1 + movs lr, r3, lsl #16 + bne LBL5 + add r0, r0, r12 + ldmia sp!, {r1, r3} + mov r2, r2, lsl #2 + cmp r3, #2 + bgt LBL6 + +LBL3: + mov r0, #0 + ldmia sp!, {r4 - r11, pc} + andeq r3, r1, r0, lsr #32 + andeq r10, r1, r12, ror #31 + andeq r3, r1, r8, lsr #32 diff --git a/src/libs/webrtc/signal_processing_library/webrtc_fft_4oiq14_gcc_android.s b/src/libs/webrtc/signal_processing_library/webrtc_fft_4oiq14_gcc_android.s new file mode 100644 index 00000000..7ba49066 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/webrtc_fft_4oiq14_gcc_android.s @@ -0,0 +1,221 @@ + .globl FFT_4OIQ14 + +FFT_4OIQ14: + stmdb sp!, {r4 - r11, lr} + ldr lr, =s_Q14S_8 + ldr lr, [lr] + cmp r2, lr + movgt r0, #1 + ldmgtia sp!, {r4 - r11, pc} + stmdb sp!, {r1, r2} + mov r3, #0 + mov r2, r2 + +LBL1: + add r12, r0, r3, lsl #2 + add r12, r12, r2, lsr #1 + ldrsh r5, [r12, #2] + ldrsh r4, [r12], +r2 + ldrsh r9, [r12, #2] + ldrsh r8, [r12], +r2 + ldrsh r7, [r12, #2] + ldrsh r6, [r12], +r2 + ldrsh r11, [r12, #2] + ldrsh r10, [r12], +r2 + add r4, r4, r6 + add r5, r5, r7 + sub r6, r4, r6, lsl #1 + sub r7, r5, r7, lsl #1 + sub r12, r8, r10 + sub lr, r9, r11 + add r10, r8, r10 + add r11, r9, r11 + sub r9, r4, r10 + sub r8, r5, r11 + add r4, r4, r10 + add r5, r5, r11 + add r10, r6, lr + sub r11, r7, r12 + sub r6, r6, lr + add r7, r7, r12 + ldr lr, =t_Q14R_rad8 + ldrsh lr, [lr] + stmdb sp!, {r2} + sub r12, r6, r7 + mul r6, r12, lr + add r12, r12, r7, lsl #1 + mul r7, r12, lr + sub r12, r10, r11 + mul r11, r12, lr + sub r12, r12, r10, lsl #1 + mul r10, r12, lr + ldmia sp!, {r2} + stmdb sp!, {r4 - r11} + add r4, r0, r3, lsl #2 + ldrsh r7, [r4, #2] + ldrsh r6, [r4], +r2 + ldrsh r11, [r4, #2] + ldrsh r10, [r4], +r2 + ldrsh r9, [r4, #2] + ldrsh r8, [r4], +r2 + ldrsh lr, [r4, #2] + ldrsh r12, [r4], +r2 + add r6, r6, r8 + add r7, r7, r9 + sub r8, r6, r8, lsl #1 + sub r9, r7, r9, lsl #1 + sub r4, r10, r12 + sub r5, r11, lr + add r10, r10, r12 + add r11, r11, lr + add r6, r6, r10 + add r7, r7, r11 + sub r10, r6, r10, lsl #1 + sub r11, r7, r11, lsl #1 + add r12, r8, r5 + sub lr, r9, r4 + sub r8, r8, r5 + add r9, r9, r4 + ldmia sp!, {r4, r5} + add r6, r6, r4 + add r7, r7, r5 + sub r4, r6, r4, lsl #1 + sub r5, r7, r5, lsl #1 + strh r7, [r1, #2] + strh r6, [r1], #4 + ldmia sp!, {r6, r7} + add r8, r8, r6, asr #14 + add r9, r9, r7, asr #14 + sub r6, r8, r6, asr #13 + sub r7, r9, r7, asr #13 + strh r9, [r1, #2] + strh r8, [r1], #4 + ldmia sp!, {r8, r9} + sub r10, r10, r8 + add r11, r11, r9 + add r8, r10, r8, lsl #1 + sub r9, r11, r9, lsl #1 + strh r11, [r1, #2] + strh r10, [r1], #4 + ldmia sp!, {r10, r11} + add r12, r12, r10, asr #14 + add lr, lr, r11, asr #14 + sub r10, r12, r10, asr #13 + sub r11, lr, r11, asr #13 + strh lr, [r1, #2] + strh r12, [r1], #4 + strh r5, [r1, #2] + strh r4, [r1], #4 + strh r7, [r1, #2] + strh r6, [r1], #4 + strh r9, [r1, #2] + strh r8, [r1], #4 + strh r11, [r1, #2] + strh r10, [r1], #4 + eor r3, r3, r2, lsr #4 + tst r3, r2, lsr #4 + bne LBL1 + eor r3, r3, r2, lsr #5 + tst r3, r2, lsr #5 + bne LBL1 + mov r12, r2, lsr #6 + + +LBL2: + eor r3, r3, r12 + tst r3, r12 + bne LBL1 + movs r12, r12, lsr #1 + bne LBL2 + ldmia sp!, {r1, r2} + mov r3, r2, lsr #3 + mov r2, #0x20 + ldr r0, =t_Q14S_8 + cmp r3, #1 + beq LBL3 + +LBL6: + mov r3, r3, lsr #2 + stmdb sp!, {r1, r3} + add r12, r2, r2, lsl #1 + add r1, r1, r12 + sub r3, r3, #1, 16 + +LBL5: + add r3, r3, r2, lsl #14 + +LBL4: + ldrsh r6, [r0], #2 + ldrsh r7, [r0], #2 + ldrsh r8, [r0], #2 + ldrsh r9, [r0], #2 + ldrsh r10, [r0], #2 + ldrsh r11, [r0], #2 + ldrsh r5, [r1, #2] + ldrsh r4, [r1], -r2 + sub lr, r4, r5 + mul r12, lr, r11 + add r11, r10, r11, lsl #1 + mla r10, r4, r10, r12 + mla r11, r5, r11, r12 + ldrsh r5, [r1, #2] + ldrsh r4, [r1], -r2 + sub lr, r4, r5 + mul r12, lr, r9 + add r9, r8, r9, lsl #1 + mla r8, r4, r8, r12 + mla r9, r5, r9, r12 + ldrsh r5, [r1, #2] + ldrsh r4, [r1], -r2 + sub lr, r4, r5 + mul r12, lr, r7 + add r7, r6, r7, lsl #1 + mla r6, r4, r6, r12 + mla r7, r5, r7, r12 + ldrsh r5, [r1, #2] + ldrsh r4, [r1] + add r12, r4, r6, asr #14 + add lr, r5, r7, asr #14 + sub r4, r4, r6, asr #14 + sub r5, r5, r7, asr #14 + add r6, r8, r10 + add r7, r9, r11 + sub r8, r8, r10 + sub r9, r9, r11 + add r10, r12, r6, asr #14 + add r11, lr, r7, asr #14 + strh r11, [r1, #2] + strh r10, [r1], +r2 + sub r10, r4, r9, asr #14 + add r11, r5, r8, asr #14 + strh r11, [r1, #2] + strh r10, [r1], +r2 + sub r10, r12, r6, asr #14 + sub r11, lr, r7, asr #14 + strh r11, [r1, #2] + strh r10, [r1], +r2 + add r10, r4, r9, asr #14 + sub r11, r5, r8, asr #14 + strh r11, [r1, #2] + strh r10, [r1], #4 + subs r3, r3, #1, 16 + bge LBL4 + add r12, r2, r2, lsl #1 + add r1, r1, r12 + sub r0, r0, r12 + sub r3, r3, #1 + movs lr, r3, lsl #16 + bne LBL5 + add r0, r0, r12 + ldmia sp!, {r1, r3} + mov r2, r2, lsl #2 + cmp r3, #2 + bgt LBL6 + +LBL3: + mov r0, #0 + ldmia sp!, {r4 - r11, pc} + andeq r3, r1, r0, lsr #32 + andeq r10, r1, r12, ror #31 + andeq r3, r1, r8, lsr #32 + diff --git a/src/libs/webrtc/signal_processing_library/webrtc_fft_t_1024_8.c b/src/libs/webrtc/signal_processing_library/webrtc_fft_t_1024_8.c new file mode 100644 index 00000000..b5873805 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/webrtc_fft_t_1024_8.c @@ -0,0 +1,704 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the Q14 radix-8 tables used in ARM9e optimizations. + * + */ + +extern const int s_Q14S_8; +const int s_Q14S_8 = 1024; +extern const unsigned short t_Q14S_8[2032]; +const unsigned short t_Q14S_8[2032] = { + 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , + 0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e , + 0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 , + 0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 , + 0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 , + 0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c , + 0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 , + 0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 , + 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , + 0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 , + 0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 , + 0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d , + 0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e , + 0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb , + 0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 , + 0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 , + 0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 , + 0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 , + 0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 , + 0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec , + 0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 , + 0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 , + 0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 , + 0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 , + 0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 , + 0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 , + 0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b , + 0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 , + 0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c , + 0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 , + 0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba , + 0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 , + 0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 , + 0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 , + 0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 , + 0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 , + 0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 , + 0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 , + 0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 , + 0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 , + 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , + 0x3e69,0x0192 ,0x3f36,0x00c9 ,0x3d9a,0x025b , + 0x3cc8,0x0324 ,0x3e69,0x0192 ,0x3b1e,0x04b5 , + 0x3b1e,0x04b5 ,0x3d9a,0x025b ,0x388e,0x070e , + 0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 , + 0x37af,0x07d6 ,0x3bf4,0x03ed ,0x3334,0x0bb7 , + 0x35eb,0x0964 ,0x3b1e,0x04b5 ,0x306c,0x0e06 , + 0x341e,0x0af1 ,0x3a46,0x057e ,0x2d93,0x1050 , + 0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 , + 0x306c,0x0e06 ,0x388e,0x070e ,0x27b3,0x14d2 , + 0x2e88,0x0f8d ,0x37af,0x07d6 ,0x24ae,0x1709 , + 0x2c9d,0x1112 ,0x36ce,0x089d ,0x219c,0x1937 , + 0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d , + 0x28b2,0x1413 ,0x3505,0x0a2b ,0x1b56,0x1d79 , + 0x26b3,0x1590 ,0x341e,0x0af1 ,0x1824,0x1f8c , + 0x24ae,0x1709 ,0x3334,0x0bb7 ,0x14ea,0x2193 , + 0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e , + 0x2093,0x19ef ,0x315b,0x0d41 ,0x0e61,0x257e , + 0x1e7e,0x1b5d ,0x306c,0x0e06 ,0x0b14,0x2760 , + 0x1c64,0x1cc6 ,0x2f7b,0x0eca ,0x07c4,0x2935 , + 0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb , + 0x1824,0x1f8c ,0x2d93,0x1050 ,0x011c,0x2cb2 , + 0x15fe,0x20e7 ,0x2c9d,0x1112 ,0xfdc7,0x2e5a , + 0x13d5,0x223d ,0x2ba4,0x11d3 ,0xfa73,0x2ff2 , + 0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 , + 0x0f79,0x24da ,0x29af,0x1354 ,0xf3d2,0x32ef , + 0x0d48,0x2620 ,0x28b2,0x1413 ,0xf087,0x3453 , + 0x0b14,0x2760 ,0x27b3,0x14d2 ,0xed41,0x35a5 , + 0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 , + 0x06a9,0x29ce ,0x25b1,0x164c ,0xe6cb,0x3812 , + 0x0471,0x2afb ,0x24ae,0x1709 ,0xe39c,0x392b , + 0x0239,0x2c21 ,0x23a9,0x17c4 ,0xe077,0x3a30 , + 0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 , + 0xfdc7,0x2e5a ,0x219c,0x1937 ,0xda4f,0x3bfd , + 0xfb8f,0x2f6c ,0x2093,0x19ef ,0xd74e,0x3cc5 , + 0xf957,0x3076 ,0x1f89,0x1aa7 ,0xd45c,0x3d78 , + 0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 , + 0xf4ec,0x3274 ,0x1d72,0x1c12 ,0xcea5,0x3e9d , + 0xf2b8,0x3368 ,0x1c64,0x1cc6 ,0xcbe2,0x3f0f , + 0xf087,0x3453 ,0x1b56,0x1d79 ,0xc932,0x3f6b , + 0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 , + 0xec2b,0x3612 ,0x1935,0x1edc ,0xc40c,0x3fe1 , + 0xea02,0x36e5 ,0x1824,0x1f8c ,0xc197,0x3ffb , + 0xe7dc,0x37b0 ,0x1711,0x203a ,0xbf38,0x3fff , + 0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec , + 0xe39c,0x392b ,0x14ea,0x2193 ,0xbabf,0x3fc4 , + 0xe182,0x39db ,0x13d5,0x223d ,0xb8a6,0x3f85 , + 0xdf6d,0x3a82 ,0x12bf,0x22e7 ,0xb6a5,0x3f30 , + 0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 , + 0xdb52,0x3bb6 ,0x1091,0x2435 ,0xb2f2,0x3e45 , + 0xd94d,0x3c42 ,0x0f79,0x24da ,0xb140,0x3daf , + 0xd74e,0x3cc5 ,0x0e61,0x257e ,0xafa9,0x3d03 , + 0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 , + 0xd363,0x3daf ,0x0c2e,0x26c1 ,0xacd0,0x3b6d , + 0xd178,0x3e15 ,0x0b14,0x2760 ,0xab8e,0x3a82 , + 0xcf94,0x3e72 ,0x09fa,0x27fe ,0xaa6a,0x3984 , + 0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 , + 0xcbe2,0x3f0f ,0x07c4,0x2935 ,0xa87b,0x374b , + 0xca15,0x3f4f ,0x06a9,0x29ce ,0xa7b1,0x3612 , + 0xc851,0x3f85 ,0x058d,0x2a65 ,0xa705,0x34c6 , + 0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 , + 0xc4e2,0x3fd4 ,0x0355,0x2b8f ,0xa60b,0x31f8 , + 0xc338,0x3fec ,0x0239,0x2c21 ,0xa5bc,0x3076 , + 0xc197,0x3ffb ,0x011c,0x2cb2 ,0xa58d,0x2ee4 , + 0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 , + 0xbe73,0x3ffb ,0xfee4,0x2dcf ,0xa58d,0x2b8f , + 0xbcf0,0x3fec ,0xfdc7,0x2e5a ,0xa5bc,0x29ce , + 0xbb77,0x3fd4 ,0xfcab,0x2ee4 ,0xa60b,0x27fe , + 0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 , + 0xb8a6,0x3f85 ,0xfa73,0x2ff2 ,0xa705,0x2435 , + 0xb74d,0x3f4f ,0xf957,0x3076 ,0xa7b1,0x223d , + 0xb600,0x3f0f ,0xf83c,0x30f9 ,0xa87b,0x203a , + 0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b , + 0xb388,0x3e72 ,0xf606,0x31f8 ,0xaa6a,0x1c12 , + 0xb25e,0x3e15 ,0xf4ec,0x3274 ,0xab8e,0x19ef , + 0xb140,0x3daf ,0xf3d2,0x32ef ,0xacd0,0x17c4 , + 0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 , + 0xaf28,0x3cc5 ,0xf19f,0x33df ,0xafa9,0x1354 , + 0xae2e,0x3c42 ,0xf087,0x3453 ,0xb140,0x1112 , + 0xad41,0x3bb6 ,0xef6f,0x34c6 ,0xb2f2,0x0eca , + 0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c , + 0xab8e,0x3a82 ,0xed41,0x35a5 ,0xb6a5,0x0a2b , + 0xaac8,0x39db ,0xec2b,0x3612 ,0xb8a6,0x07d6 , + 0xaa0f,0x392b ,0xeb16,0x367d ,0xbabf,0x057e , + 0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 , + 0xa8c5,0x37b0 ,0xe8ef,0x374b ,0xbf38,0x00c9 , + 0xa834,0x36e5 ,0xe7dc,0x37b0 ,0xc197,0xfe6e , + 0xa7b1,0x3612 ,0xe6cb,0x3812 ,0xc40c,0xfc13 , + 0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba , + 0xa6d3,0x3453 ,0xe4aa,0x38cf ,0xc932,0xf763 , + 0xa678,0x3368 ,0xe39c,0x392b ,0xcbe2,0xf50f , + 0xa62c,0x3274 ,0xe28e,0x3984 ,0xcea5,0xf2bf , + 0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 , + 0xa5bc,0x3076 ,0xe077,0x3a30 ,0xd45c,0xee2d , + 0xa599,0x2f6c ,0xdf6d,0x3a82 ,0xd74e,0xebed , + 0xa585,0x2e5a ,0xde64,0x3ad3 ,0xda4f,0xe9b4 , + 0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 , + 0xa585,0x2c21 ,0xdc57,0x3b6d ,0xe077,0xe559 , + 0xa599,0x2afb ,0xdb52,0x3bb6 ,0xe39c,0xe33a , + 0xa5bc,0x29ce ,0xda4f,0x3bfd ,0xe6cb,0xe124 , + 0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 , + 0xa62c,0x2760 ,0xd84d,0x3c85 ,0xed41,0xdd19 , + 0xa678,0x2620 ,0xd74e,0x3cc5 ,0xf087,0xdb26 , + 0xa6d3,0x24da ,0xd651,0x3d03 ,0xf3d2,0xd93f , + 0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 , + 0xa7b1,0x223d ,0xd45c,0x3d78 ,0xfa73,0xd59b , + 0xa834,0x20e7 ,0xd363,0x3daf ,0xfdc7,0xd3df , + 0xa8c5,0x1f8c ,0xd26d,0x3de3 ,0x011c,0xd231 , + 0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 , + 0xaa0f,0x1cc6 ,0xd085,0x3e45 ,0x07c4,0xcf07 , + 0xaac8,0x1b5d ,0xcf94,0x3e72 ,0x0b14,0xcd8c , + 0xab8e,0x19ef ,0xcea5,0x3e9d ,0x0e61,0xcc21 , + 0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 , + 0xad41,0x1709 ,0xcccc,0x3eeb ,0x14ea,0xc983 , + 0xae2e,0x1590 ,0xcbe2,0x3f0f ,0x1824,0xc850 , + 0xaf28,0x1413 ,0xcafb,0x3f30 ,0x1b56,0xc731 , + 0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 , + 0xb140,0x1112 ,0xc932,0x3f6b ,0x219c,0xc52d , + 0xb25e,0x0f8d ,0xc851,0x3f85 ,0x24ae,0xc44a , + 0xb388,0x0e06 ,0xc772,0x3f9c ,0x27b3,0xc37b , + 0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 , + 0xb600,0x0af1 ,0xc5ba,0x3fc4 ,0x2d93,0xc21d , + 0xb74d,0x0964 ,0xc4e2,0x3fd4 ,0x306c,0xc18e , + 0xb8a6,0x07d6 ,0xc40c,0x3fe1 ,0x3334,0xc115 , + 0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 , + 0xbb77,0x04b5 ,0xc266,0x3ff5 ,0x388e,0xc064 , + 0xbcf0,0x0324 ,0xc197,0x3ffb ,0x3b1e,0xc02c , + 0xbe73,0x0192 ,0xc0ca,0x3fff ,0x3d9a,0xc00b , + 0x4000,0x0000 ,0x3f9b,0x0065 ,0x3f36,0x00c9 , + 0x3ed0,0x012e ,0x3e69,0x0192 ,0x3e02,0x01f7 , + 0x3d9a,0x025b ,0x3d31,0x02c0 ,0x3cc8,0x0324 , + 0x3c5f,0x0388 ,0x3bf4,0x03ed ,0x3b8a,0x0451 , + 0x3b1e,0x04b5 ,0x3ab2,0x051a ,0x3a46,0x057e , + 0x39d9,0x05e2 ,0x396b,0x0646 ,0x38fd,0x06aa , + 0x388e,0x070e ,0x381f,0x0772 ,0x37af,0x07d6 , + 0x373f,0x0839 ,0x36ce,0x089d ,0x365d,0x0901 , + 0x35eb,0x0964 ,0x3578,0x09c7 ,0x3505,0x0a2b , + 0x3492,0x0a8e ,0x341e,0x0af1 ,0x33a9,0x0b54 , + 0x3334,0x0bb7 ,0x32bf,0x0c1a ,0x3249,0x0c7c , + 0x31d2,0x0cdf ,0x315b,0x0d41 ,0x30e4,0x0da4 , + 0x306c,0x0e06 ,0x2ff4,0x0e68 ,0x2f7b,0x0eca , + 0x2f02,0x0f2b ,0x2e88,0x0f8d ,0x2e0e,0x0fee , + 0x2d93,0x1050 ,0x2d18,0x10b1 ,0x2c9d,0x1112 , + 0x2c21,0x1173 ,0x2ba4,0x11d3 ,0x2b28,0x1234 , + 0x2aaa,0x1294 ,0x2a2d,0x12f4 ,0x29af,0x1354 , + 0x2931,0x13b4 ,0x28b2,0x1413 ,0x2833,0x1473 , + 0x27b3,0x14d2 ,0x2733,0x1531 ,0x26b3,0x1590 , + 0x2632,0x15ee ,0x25b1,0x164c ,0x252f,0x16ab , + 0x24ae,0x1709 ,0x242b,0x1766 ,0x23a9,0x17c4 , + 0x2326,0x1821 ,0x22a3,0x187e ,0x221f,0x18db , + 0x219c,0x1937 ,0x2117,0x1993 ,0x2093,0x19ef , + 0x200e,0x1a4b ,0x1f89,0x1aa7 ,0x1f04,0x1b02 , + 0x1e7e,0x1b5d ,0x1df8,0x1bb8 ,0x1d72,0x1c12 , + 0x1ceb,0x1c6c ,0x1c64,0x1cc6 ,0x1bdd,0x1d20 , + 0x1b56,0x1d79 ,0x1ace,0x1dd3 ,0x1a46,0x1e2b , + 0x19be,0x1e84 ,0x1935,0x1edc ,0x18ad,0x1f34 , + 0x1824,0x1f8c ,0x179b,0x1fe3 ,0x1711,0x203a , + 0x1688,0x2091 ,0x15fe,0x20e7 ,0x1574,0x213d , + 0x14ea,0x2193 ,0x145f,0x21e8 ,0x13d5,0x223d , + 0x134a,0x2292 ,0x12bf,0x22e7 ,0x1234,0x233b , + 0x11a8,0x238e ,0x111d,0x23e2 ,0x1091,0x2435 , + 0x1005,0x2488 ,0x0f79,0x24da ,0x0eed,0x252c , + 0x0e61,0x257e ,0x0dd4,0x25cf ,0x0d48,0x2620 , + 0x0cbb,0x2671 ,0x0c2e,0x26c1 ,0x0ba1,0x2711 , + 0x0b14,0x2760 ,0x0a87,0x27af ,0x09fa,0x27fe , + 0x096d,0x284c ,0x08df,0x289a ,0x0852,0x28e7 , + 0x07c4,0x2935 ,0x0736,0x2981 ,0x06a9,0x29ce , + 0x061b,0x2a1a ,0x058d,0x2a65 ,0x04ff,0x2ab0 , + 0x0471,0x2afb ,0x03e3,0x2b45 ,0x0355,0x2b8f , + 0x02c7,0x2bd8 ,0x0239,0x2c21 ,0x01aa,0x2c6a , + 0x011c,0x2cb2 ,0x008e,0x2cfa ,0x0000,0x2d41 , + 0xff72,0x2d88 ,0xfee4,0x2dcf ,0xfe56,0x2e15 , + 0xfdc7,0x2e5a ,0xfd39,0x2e9f ,0xfcab,0x2ee4 , + 0xfc1d,0x2f28 ,0xfb8f,0x2f6c ,0xfb01,0x2faf , + 0xfa73,0x2ff2 ,0xf9e5,0x3034 ,0xf957,0x3076 , + 0xf8ca,0x30b8 ,0xf83c,0x30f9 ,0xf7ae,0x3139 , + 0xf721,0x3179 ,0xf693,0x31b9 ,0xf606,0x31f8 , + 0xf579,0x3236 ,0xf4ec,0x3274 ,0xf45f,0x32b2 , + 0xf3d2,0x32ef ,0xf345,0x332c ,0xf2b8,0x3368 , + 0xf22c,0x33a3 ,0xf19f,0x33df ,0xf113,0x3419 , + 0xf087,0x3453 ,0xeffb,0x348d ,0xef6f,0x34c6 , + 0xeee3,0x34ff ,0xee58,0x3537 ,0xedcc,0x356e , + 0xed41,0x35a5 ,0xecb6,0x35dc ,0xec2b,0x3612 , + 0xeba1,0x3648 ,0xeb16,0x367d ,0xea8c,0x36b1 , + 0xea02,0x36e5 ,0xe978,0x3718 ,0xe8ef,0x374b , + 0xe865,0x377e ,0xe7dc,0x37b0 ,0xe753,0x37e1 , + 0xe6cb,0x3812 ,0xe642,0x3842 ,0xe5ba,0x3871 , + 0xe532,0x38a1 ,0xe4aa,0x38cf ,0xe423,0x38fd , + 0xe39c,0x392b ,0xe315,0x3958 ,0xe28e,0x3984 , + 0xe208,0x39b0 ,0xe182,0x39db ,0xe0fc,0x3a06 , + 0xe077,0x3a30 ,0xdff2,0x3a59 ,0xdf6d,0x3a82 , + 0xdee9,0x3aab ,0xde64,0x3ad3 ,0xdde1,0x3afa , + 0xdd5d,0x3b21 ,0xdcda,0x3b47 ,0xdc57,0x3b6d , + 0xdbd5,0x3b92 ,0xdb52,0x3bb6 ,0xdad1,0x3bda , + 0xda4f,0x3bfd ,0xd9ce,0x3c20 ,0xd94d,0x3c42 , + 0xd8cd,0x3c64 ,0xd84d,0x3c85 ,0xd7cd,0x3ca5 , + 0xd74e,0x3cc5 ,0xd6cf,0x3ce4 ,0xd651,0x3d03 , + 0xd5d3,0x3d21 ,0xd556,0x3d3f ,0xd4d8,0x3d5b , + 0xd45c,0x3d78 ,0xd3df,0x3d93 ,0xd363,0x3daf , + 0xd2e8,0x3dc9 ,0xd26d,0x3de3 ,0xd1f2,0x3dfc , + 0xd178,0x3e15 ,0xd0fe,0x3e2d ,0xd085,0x3e45 , + 0xd00c,0x3e5c ,0xcf94,0x3e72 ,0xcf1c,0x3e88 , + 0xcea5,0x3e9d ,0xce2e,0x3eb1 ,0xcdb7,0x3ec5 , + 0xcd41,0x3ed8 ,0xcccc,0x3eeb ,0xcc57,0x3efd , + 0xcbe2,0x3f0f ,0xcb6e,0x3f20 ,0xcafb,0x3f30 , + 0xca88,0x3f40 ,0xca15,0x3f4f ,0xc9a3,0x3f5d , + 0xc932,0x3f6b ,0xc8c1,0x3f78 ,0xc851,0x3f85 , + 0xc7e1,0x3f91 ,0xc772,0x3f9c ,0xc703,0x3fa7 , + 0xc695,0x3fb1 ,0xc627,0x3fbb ,0xc5ba,0x3fc4 , + 0xc54e,0x3fcc ,0xc4e2,0x3fd4 ,0xc476,0x3fdb , + 0xc40c,0x3fe1 ,0xc3a1,0x3fe7 ,0xc338,0x3fec , + 0xc2cf,0x3ff1 ,0xc266,0x3ff5 ,0xc1fe,0x3ff8 , + 0xc197,0x3ffb ,0xc130,0x3ffd ,0xc0ca,0x3fff , + 0xc065,0x4000 ,0xc000,0x4000 ,0xbf9c,0x4000 , + 0xbf38,0x3fff ,0xbed5,0x3ffd ,0xbe73,0x3ffb , + 0xbe11,0x3ff8 ,0xbdb0,0x3ff5 ,0xbd50,0x3ff1 , + 0xbcf0,0x3fec ,0xbc91,0x3fe7 ,0xbc32,0x3fe1 , + 0xbbd4,0x3fdb ,0xbb77,0x3fd4 ,0xbb1b,0x3fcc , + 0xbabf,0x3fc4 ,0xba64,0x3fbb ,0xba09,0x3fb1 , + 0xb9af,0x3fa7 ,0xb956,0x3f9c ,0xb8fd,0x3f91 , + 0xb8a6,0x3f85 ,0xb84f,0x3f78 ,0xb7f8,0x3f6b , + 0xb7a2,0x3f5d ,0xb74d,0x3f4f ,0xb6f9,0x3f40 , + 0xb6a5,0x3f30 ,0xb652,0x3f20 ,0xb600,0x3f0f , + 0xb5af,0x3efd ,0xb55e,0x3eeb ,0xb50e,0x3ed8 , + 0xb4be,0x3ec5 ,0xb470,0x3eb1 ,0xb422,0x3e9d , + 0xb3d5,0x3e88 ,0xb388,0x3e72 ,0xb33d,0x3e5c , + 0xb2f2,0x3e45 ,0xb2a7,0x3e2d ,0xb25e,0x3e15 , + 0xb215,0x3dfc ,0xb1cd,0x3de3 ,0xb186,0x3dc9 , + 0xb140,0x3daf ,0xb0fa,0x3d93 ,0xb0b5,0x3d78 , + 0xb071,0x3d5b ,0xb02d,0x3d3f ,0xafeb,0x3d21 , + 0xafa9,0x3d03 ,0xaf68,0x3ce4 ,0xaf28,0x3cc5 , + 0xaee8,0x3ca5 ,0xaea9,0x3c85 ,0xae6b,0x3c64 , + 0xae2e,0x3c42 ,0xadf2,0x3c20 ,0xadb6,0x3bfd , + 0xad7b,0x3bda ,0xad41,0x3bb6 ,0xad08,0x3b92 , + 0xacd0,0x3b6d ,0xac98,0x3b47 ,0xac61,0x3b21 , + 0xac2b,0x3afa ,0xabf6,0x3ad3 ,0xabc2,0x3aab , + 0xab8e,0x3a82 ,0xab5b,0x3a59 ,0xab29,0x3a30 , + 0xaaf8,0x3a06 ,0xaac8,0x39db ,0xaa98,0x39b0 , + 0xaa6a,0x3984 ,0xaa3c,0x3958 ,0xaa0f,0x392b , + 0xa9e3,0x38fd ,0xa9b7,0x38cf ,0xa98d,0x38a1 , + 0xa963,0x3871 ,0xa93a,0x3842 ,0xa912,0x3812 , + 0xa8eb,0x37e1 ,0xa8c5,0x37b0 ,0xa89f,0x377e , + 0xa87b,0x374b ,0xa857,0x3718 ,0xa834,0x36e5 , + 0xa812,0x36b1 ,0xa7f1,0x367d ,0xa7d0,0x3648 , + 0xa7b1,0x3612 ,0xa792,0x35dc ,0xa774,0x35a5 , + 0xa757,0x356e ,0xa73b,0x3537 ,0xa71f,0x34ff , + 0xa705,0x34c6 ,0xa6eb,0x348d ,0xa6d3,0x3453 , + 0xa6bb,0x3419 ,0xa6a4,0x33df ,0xa68e,0x33a3 , + 0xa678,0x3368 ,0xa664,0x332c ,0xa650,0x32ef , + 0xa63e,0x32b2 ,0xa62c,0x3274 ,0xa61b,0x3236 , + 0xa60b,0x31f8 ,0xa5fb,0x31b9 ,0xa5ed,0x3179 , + 0xa5e0,0x3139 ,0xa5d3,0x30f9 ,0xa5c7,0x30b8 , + 0xa5bc,0x3076 ,0xa5b2,0x3034 ,0xa5a9,0x2ff2 , + 0xa5a1,0x2faf ,0xa599,0x2f6c ,0xa593,0x2f28 , + 0xa58d,0x2ee4 ,0xa588,0x2e9f ,0xa585,0x2e5a , + 0xa581,0x2e15 ,0xa57f,0x2dcf ,0xa57e,0x2d88 , + 0xa57e,0x2d41 ,0xa57e,0x2cfa ,0xa57f,0x2cb2 , + 0xa581,0x2c6a ,0xa585,0x2c21 ,0xa588,0x2bd8 , + 0xa58d,0x2b8f ,0xa593,0x2b45 ,0xa599,0x2afb , + 0xa5a1,0x2ab0 ,0xa5a9,0x2a65 ,0xa5b2,0x2a1a , + 0xa5bc,0x29ce ,0xa5c7,0x2981 ,0xa5d3,0x2935 , + 0xa5e0,0x28e7 ,0xa5ed,0x289a ,0xa5fb,0x284c , + 0xa60b,0x27fe ,0xa61b,0x27af ,0xa62c,0x2760 , + 0xa63e,0x2711 ,0xa650,0x26c1 ,0xa664,0x2671 , + 0xa678,0x2620 ,0xa68e,0x25cf ,0xa6a4,0x257e , + 0xa6bb,0x252c ,0xa6d3,0x24da ,0xa6eb,0x2488 , + 0xa705,0x2435 ,0xa71f,0x23e2 ,0xa73b,0x238e , + 0xa757,0x233b ,0xa774,0x22e7 ,0xa792,0x2292 , + 0xa7b1,0x223d ,0xa7d0,0x21e8 ,0xa7f1,0x2193 , + 0xa812,0x213d ,0xa834,0x20e7 ,0xa857,0x2091 , + 0xa87b,0x203a ,0xa89f,0x1fe3 ,0xa8c5,0x1f8c , + 0xa8eb,0x1f34 ,0xa912,0x1edc ,0xa93a,0x1e84 , + 0xa963,0x1e2b ,0xa98d,0x1dd3 ,0xa9b7,0x1d79 , + 0xa9e3,0x1d20 ,0xaa0f,0x1cc6 ,0xaa3c,0x1c6c , + 0xaa6a,0x1c12 ,0xaa98,0x1bb8 ,0xaac8,0x1b5d , + 0xaaf8,0x1b02 ,0xab29,0x1aa7 ,0xab5b,0x1a4b , + 0xab8e,0x19ef ,0xabc2,0x1993 ,0xabf6,0x1937 , + 0xac2b,0x18db ,0xac61,0x187e ,0xac98,0x1821 , + 0xacd0,0x17c4 ,0xad08,0x1766 ,0xad41,0x1709 , + 0xad7b,0x16ab ,0xadb6,0x164c ,0xadf2,0x15ee , + 0xae2e,0x1590 ,0xae6b,0x1531 ,0xaea9,0x14d2 , + 0xaee8,0x1473 ,0xaf28,0x1413 ,0xaf68,0x13b4 , + 0xafa9,0x1354 ,0xafeb,0x12f4 ,0xb02d,0x1294 , + 0xb071,0x1234 ,0xb0b5,0x11d3 ,0xb0fa,0x1173 , + 0xb140,0x1112 ,0xb186,0x10b1 ,0xb1cd,0x1050 , + 0xb215,0x0fee ,0xb25e,0x0f8d ,0xb2a7,0x0f2b , + 0xb2f2,0x0eca ,0xb33d,0x0e68 ,0xb388,0x0e06 , + 0xb3d5,0x0da4 ,0xb422,0x0d41 ,0xb470,0x0cdf , + 0xb4be,0x0c7c ,0xb50e,0x0c1a ,0xb55e,0x0bb7 , + 0xb5af,0x0b54 ,0xb600,0x0af1 ,0xb652,0x0a8e , + 0xb6a5,0x0a2b ,0xb6f9,0x09c7 ,0xb74d,0x0964 , + 0xb7a2,0x0901 ,0xb7f8,0x089d ,0xb84f,0x0839 , + 0xb8a6,0x07d6 ,0xb8fd,0x0772 ,0xb956,0x070e , + 0xb9af,0x06aa ,0xba09,0x0646 ,0xba64,0x05e2 , + 0xbabf,0x057e ,0xbb1b,0x051a ,0xbb77,0x04b5 , + 0xbbd4,0x0451 ,0xbc32,0x03ed ,0xbc91,0x0388 , + 0xbcf0,0x0324 ,0xbd50,0x02c0 ,0xbdb0,0x025b , + 0xbe11,0x01f7 ,0xbe73,0x0192 ,0xbed5,0x012e , + 0xbf38,0x00c9 ,0xbf9c,0x0065 }; + + +extern const int s_Q14R_8; +const int s_Q14R_8 = 1024; +extern const unsigned short t_Q14R_8[2032]; +const unsigned short t_Q14R_8[2032] = { + 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , + 0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e , + 0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 , + 0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 , + 0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 , + 0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c , + 0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 , + 0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 , + 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , + 0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 , + 0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 , + 0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d , + 0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e , + 0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb , + 0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 , + 0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 , + 0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 , + 0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 , + 0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 , + 0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec , + 0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 , + 0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 , + 0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 , + 0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 , + 0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 , + 0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 , + 0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b , + 0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 , + 0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c , + 0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 , + 0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba , + 0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 , + 0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 , + 0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 , + 0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 , + 0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 , + 0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 , + 0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 , + 0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 , + 0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 , + 0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 , + 0x3ffb,0x0192 ,0x3fff,0x00c9 ,0x3ff5,0x025b , + 0x3fec,0x0324 ,0x3ffb,0x0192 ,0x3fd4,0x04b5 , + 0x3fd4,0x04b5 ,0x3ff5,0x025b ,0x3f9c,0x070e , + 0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 , + 0x3f85,0x07d6 ,0x3fe1,0x03ed ,0x3eeb,0x0bb7 , + 0x3f4f,0x0964 ,0x3fd4,0x04b5 ,0x3e72,0x0e06 , + 0x3f0f,0x0af1 ,0x3fc4,0x057e ,0x3de3,0x1050 , + 0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 , + 0x3e72,0x0e06 ,0x3f9c,0x070e ,0x3c85,0x14d2 , + 0x3e15,0x0f8d ,0x3f85,0x07d6 ,0x3bb6,0x1709 , + 0x3daf,0x1112 ,0x3f6b,0x089d ,0x3ad3,0x1937 , + 0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d , + 0x3cc5,0x1413 ,0x3f30,0x0a2b ,0x38cf,0x1d79 , + 0x3c42,0x1590 ,0x3f0f,0x0af1 ,0x37b0,0x1f8c , + 0x3bb6,0x1709 ,0x3eeb,0x0bb7 ,0x367d,0x2193 , + 0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e , + 0x3a82,0x19ef ,0x3e9d,0x0d41 ,0x33df,0x257e , + 0x39db,0x1b5d ,0x3e72,0x0e06 ,0x3274,0x2760 , + 0x392b,0x1cc6 ,0x3e45,0x0eca ,0x30f9,0x2935 , + 0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb , + 0x37b0,0x1f8c ,0x3de3,0x1050 ,0x2dcf,0x2cb2 , + 0x36e5,0x20e7 ,0x3daf,0x1112 ,0x2c21,0x2e5a , + 0x3612,0x223d ,0x3d78,0x11d3 ,0x2a65,0x2ff2 , + 0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 , + 0x3453,0x24da ,0x3d03,0x1354 ,0x26c1,0x32ef , + 0x3368,0x2620 ,0x3cc5,0x1413 ,0x24da,0x3453 , + 0x3274,0x2760 ,0x3c85,0x14d2 ,0x22e7,0x35a5 , + 0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 , + 0x3076,0x29ce ,0x3bfd,0x164c ,0x1edc,0x3812 , + 0x2f6c,0x2afb ,0x3bb6,0x1709 ,0x1cc6,0x392b , + 0x2e5a,0x2c21 ,0x3b6d,0x17c4 ,0x1aa7,0x3a30 , + 0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 , + 0x2c21,0x2e5a ,0x3ad3,0x1937 ,0x164c,0x3bfd , + 0x2afb,0x2f6c ,0x3a82,0x19ef ,0x1413,0x3cc5 , + 0x29ce,0x3076 ,0x3a30,0x1aa7 ,0x11d3,0x3d78 , + 0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 , + 0x2760,0x3274 ,0x3984,0x1c12 ,0x0d41,0x3e9d , + 0x2620,0x3368 ,0x392b,0x1cc6 ,0x0af1,0x3f0f , + 0x24da,0x3453 ,0x38cf,0x1d79 ,0x089d,0x3f6b , + 0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 , + 0x223d,0x3612 ,0x3812,0x1edc ,0x03ed,0x3fe1 , + 0x20e7,0x36e5 ,0x37b0,0x1f8c ,0x0192,0x3ffb , + 0x1f8c,0x37b0 ,0x374b,0x203a ,0xff37,0x3fff , + 0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec , + 0x1cc6,0x392b ,0x367d,0x2193 ,0xfa82,0x3fc4 , + 0x1b5d,0x39db ,0x3612,0x223d ,0xf82a,0x3f85 , + 0x19ef,0x3a82 ,0x35a5,0x22e7 ,0xf5d5,0x3f30 , + 0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 , + 0x1709,0x3bb6 ,0x34c6,0x2435 ,0xf136,0x3e45 , + 0x1590,0x3c42 ,0x3453,0x24da ,0xeeee,0x3daf , + 0x1413,0x3cc5 ,0x33df,0x257e ,0xecac,0x3d03 , + 0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 , + 0x1112,0x3daf ,0x32ef,0x26c1 ,0xe83c,0x3b6d , + 0x0f8d,0x3e15 ,0x3274,0x2760 ,0xe611,0x3a82 , + 0x0e06,0x3e72 ,0x31f8,0x27fe ,0xe3ee,0x3984 , + 0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 , + 0x0af1,0x3f0f ,0x30f9,0x2935 ,0xdfc6,0x374b , + 0x0964,0x3f4f ,0x3076,0x29ce ,0xddc3,0x3612 , + 0x07d6,0x3f85 ,0x2ff2,0x2a65 ,0xdbcb,0x34c6 , + 0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 , + 0x04b5,0x3fd4 ,0x2ee4,0x2b8f ,0xd802,0x31f8 , + 0x0324,0x3fec ,0x2e5a,0x2c21 ,0xd632,0x3076 , + 0x0192,0x3ffb ,0x2dcf,0x2cb2 ,0xd471,0x2ee4 , + 0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 , + 0xfe6e,0x3ffb ,0x2cb2,0x2dcf ,0xd11c,0x2b8f , + 0xfcdc,0x3fec ,0x2c21,0x2e5a ,0xcf8a,0x29ce , + 0xfb4b,0x3fd4 ,0x2b8f,0x2ee4 ,0xce08,0x27fe , + 0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 , + 0xf82a,0x3f85 ,0x2a65,0x2ff2 ,0xcb3a,0x2435 , + 0xf69c,0x3f4f ,0x29ce,0x3076 ,0xc9ee,0x223d , + 0xf50f,0x3f0f ,0x2935,0x30f9 ,0xc8b5,0x203a , + 0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b , + 0xf1fa,0x3e72 ,0x27fe,0x31f8 ,0xc67c,0x1c12 , + 0xf073,0x3e15 ,0x2760,0x3274 ,0xc57e,0x19ef , + 0xeeee,0x3daf ,0x26c1,0x32ef ,0xc493,0x17c4 , + 0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 , + 0xebed,0x3cc5 ,0x257e,0x33df ,0xc2fd,0x1354 , + 0xea70,0x3c42 ,0x24da,0x3453 ,0xc251,0x1112 , + 0xe8f7,0x3bb6 ,0x2435,0x34c6 ,0xc1bb,0x0eca , + 0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c , + 0xe611,0x3a82 ,0x22e7,0x35a5 ,0xc0d0,0x0a2b , + 0xe4a3,0x39db ,0x223d,0x3612 ,0xc07b,0x07d6 , + 0xe33a,0x392b ,0x2193,0x367d ,0xc03c,0x057e , + 0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 , + 0xe074,0x37b0 ,0x203a,0x374b ,0xc001,0x00c9 , + 0xdf19,0x36e5 ,0x1f8c,0x37b0 ,0xc005,0xfe6e , + 0xddc3,0x3612 ,0x1edc,0x3812 ,0xc01f,0xfc13 , + 0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba , + 0xdb26,0x3453 ,0x1d79,0x38cf ,0xc095,0xf763 , + 0xd9e0,0x3368 ,0x1cc6,0x392b ,0xc0f1,0xf50f , + 0xd8a0,0x3274 ,0x1c12,0x3984 ,0xc163,0xf2bf , + 0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 , + 0xd632,0x3076 ,0x1aa7,0x3a30 ,0xc288,0xee2d , + 0xd505,0x2f6c ,0x19ef,0x3a82 ,0xc33b,0xebed , + 0xd3df,0x2e5a ,0x1937,0x3ad3 ,0xc403,0xe9b4 , + 0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 , + 0xd1a6,0x2c21 ,0x17c4,0x3b6d ,0xc5d0,0xe559 , + 0xd094,0x2afb ,0x1709,0x3bb6 ,0xc6d5,0xe33a , + 0xcf8a,0x29ce ,0x164c,0x3bfd ,0xc7ee,0xe124 , + 0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 , + 0xcd8c,0x2760 ,0x14d2,0x3c85 ,0xca5b,0xdd19 , + 0xcc98,0x2620 ,0x1413,0x3cc5 ,0xcbad,0xdb26 , + 0xcbad,0x24da ,0x1354,0x3d03 ,0xcd11,0xd93f , + 0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 , + 0xc9ee,0x223d ,0x11d3,0x3d78 ,0xd00e,0xd59b , + 0xc91b,0x20e7 ,0x1112,0x3daf ,0xd1a6,0xd3df , + 0xc850,0x1f8c ,0x1050,0x3de3 ,0xd34e,0xd231 , + 0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 , + 0xc6d5,0x1cc6 ,0x0eca,0x3e45 ,0xd6cb,0xcf07 , + 0xc625,0x1b5d ,0x0e06,0x3e72 ,0xd8a0,0xcd8c , + 0xc57e,0x19ef ,0x0d41,0x3e9d ,0xda82,0xcc21 , + 0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 , + 0xc44a,0x1709 ,0x0bb7,0x3eeb ,0xde6d,0xc983 , + 0xc3be,0x1590 ,0x0af1,0x3f0f ,0xe074,0xc850 , + 0xc33b,0x1413 ,0x0a2b,0x3f30 ,0xe287,0xc731 , + 0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 , + 0xc251,0x1112 ,0x089d,0x3f6b ,0xe6c9,0xc52d , + 0xc1eb,0x0f8d ,0x07d6,0x3f85 ,0xe8f7,0xc44a , + 0xc18e,0x0e06 ,0x070e,0x3f9c ,0xeb2e,0xc37b , + 0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 , + 0xc0f1,0x0af1 ,0x057e,0x3fc4 ,0xefb0,0xc21d , + 0xc0b1,0x0964 ,0x04b5,0x3fd4 ,0xf1fa,0xc18e , + 0xc07b,0x07d6 ,0x03ed,0x3fe1 ,0xf449,0xc115 , + 0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 , + 0xc02c,0x04b5 ,0x025b,0x3ff5 ,0xf8f2,0xc064 , + 0xc014,0x0324 ,0x0192,0x3ffb ,0xfb4b,0xc02c , + 0xc005,0x0192 ,0x00c9,0x3fff ,0xfda5,0xc00b , + 0x4000,0x0000 ,0x4000,0x0065 ,0x3fff,0x00c9 , + 0x3ffd,0x012e ,0x3ffb,0x0192 ,0x3ff8,0x01f7 , + 0x3ff5,0x025b ,0x3ff1,0x02c0 ,0x3fec,0x0324 , + 0x3fe7,0x0388 ,0x3fe1,0x03ed ,0x3fdb,0x0451 , + 0x3fd4,0x04b5 ,0x3fcc,0x051a ,0x3fc4,0x057e , + 0x3fbb,0x05e2 ,0x3fb1,0x0646 ,0x3fa7,0x06aa , + 0x3f9c,0x070e ,0x3f91,0x0772 ,0x3f85,0x07d6 , + 0x3f78,0x0839 ,0x3f6b,0x089d ,0x3f5d,0x0901 , + 0x3f4f,0x0964 ,0x3f40,0x09c7 ,0x3f30,0x0a2b , + 0x3f20,0x0a8e ,0x3f0f,0x0af1 ,0x3efd,0x0b54 , + 0x3eeb,0x0bb7 ,0x3ed8,0x0c1a ,0x3ec5,0x0c7c , + 0x3eb1,0x0cdf ,0x3e9d,0x0d41 ,0x3e88,0x0da4 , + 0x3e72,0x0e06 ,0x3e5c,0x0e68 ,0x3e45,0x0eca , + 0x3e2d,0x0f2b ,0x3e15,0x0f8d ,0x3dfc,0x0fee , + 0x3de3,0x1050 ,0x3dc9,0x10b1 ,0x3daf,0x1112 , + 0x3d93,0x1173 ,0x3d78,0x11d3 ,0x3d5b,0x1234 , + 0x3d3f,0x1294 ,0x3d21,0x12f4 ,0x3d03,0x1354 , + 0x3ce4,0x13b4 ,0x3cc5,0x1413 ,0x3ca5,0x1473 , + 0x3c85,0x14d2 ,0x3c64,0x1531 ,0x3c42,0x1590 , + 0x3c20,0x15ee ,0x3bfd,0x164c ,0x3bda,0x16ab , + 0x3bb6,0x1709 ,0x3b92,0x1766 ,0x3b6d,0x17c4 , + 0x3b47,0x1821 ,0x3b21,0x187e ,0x3afa,0x18db , + 0x3ad3,0x1937 ,0x3aab,0x1993 ,0x3a82,0x19ef , + 0x3a59,0x1a4b ,0x3a30,0x1aa7 ,0x3a06,0x1b02 , + 0x39db,0x1b5d ,0x39b0,0x1bb8 ,0x3984,0x1c12 , + 0x3958,0x1c6c ,0x392b,0x1cc6 ,0x38fd,0x1d20 , + 0x38cf,0x1d79 ,0x38a1,0x1dd3 ,0x3871,0x1e2b , + 0x3842,0x1e84 ,0x3812,0x1edc ,0x37e1,0x1f34 , + 0x37b0,0x1f8c ,0x377e,0x1fe3 ,0x374b,0x203a , + 0x3718,0x2091 ,0x36e5,0x20e7 ,0x36b1,0x213d , + 0x367d,0x2193 ,0x3648,0x21e8 ,0x3612,0x223d , + 0x35dc,0x2292 ,0x35a5,0x22e7 ,0x356e,0x233b , + 0x3537,0x238e ,0x34ff,0x23e2 ,0x34c6,0x2435 , + 0x348d,0x2488 ,0x3453,0x24da ,0x3419,0x252c , + 0x33df,0x257e ,0x33a3,0x25cf ,0x3368,0x2620 , + 0x332c,0x2671 ,0x32ef,0x26c1 ,0x32b2,0x2711 , + 0x3274,0x2760 ,0x3236,0x27af ,0x31f8,0x27fe , + 0x31b9,0x284c ,0x3179,0x289a ,0x3139,0x28e7 , + 0x30f9,0x2935 ,0x30b8,0x2981 ,0x3076,0x29ce , + 0x3034,0x2a1a ,0x2ff2,0x2a65 ,0x2faf,0x2ab0 , + 0x2f6c,0x2afb ,0x2f28,0x2b45 ,0x2ee4,0x2b8f , + 0x2e9f,0x2bd8 ,0x2e5a,0x2c21 ,0x2e15,0x2c6a , + 0x2dcf,0x2cb2 ,0x2d88,0x2cfa ,0x2d41,0x2d41 , + 0x2cfa,0x2d88 ,0x2cb2,0x2dcf ,0x2c6a,0x2e15 , + 0x2c21,0x2e5a ,0x2bd8,0x2e9f ,0x2b8f,0x2ee4 , + 0x2b45,0x2f28 ,0x2afb,0x2f6c ,0x2ab0,0x2faf , + 0x2a65,0x2ff2 ,0x2a1a,0x3034 ,0x29ce,0x3076 , + 0x2981,0x30b8 ,0x2935,0x30f9 ,0x28e7,0x3139 , + 0x289a,0x3179 ,0x284c,0x31b9 ,0x27fe,0x31f8 , + 0x27af,0x3236 ,0x2760,0x3274 ,0x2711,0x32b2 , + 0x26c1,0x32ef ,0x2671,0x332c ,0x2620,0x3368 , + 0x25cf,0x33a3 ,0x257e,0x33df ,0x252c,0x3419 , + 0x24da,0x3453 ,0x2488,0x348d ,0x2435,0x34c6 , + 0x23e2,0x34ff ,0x238e,0x3537 ,0x233b,0x356e , + 0x22e7,0x35a5 ,0x2292,0x35dc ,0x223d,0x3612 , + 0x21e8,0x3648 ,0x2193,0x367d ,0x213d,0x36b1 , + 0x20e7,0x36e5 ,0x2091,0x3718 ,0x203a,0x374b , + 0x1fe3,0x377e ,0x1f8c,0x37b0 ,0x1f34,0x37e1 , + 0x1edc,0x3812 ,0x1e84,0x3842 ,0x1e2b,0x3871 , + 0x1dd3,0x38a1 ,0x1d79,0x38cf ,0x1d20,0x38fd , + 0x1cc6,0x392b ,0x1c6c,0x3958 ,0x1c12,0x3984 , + 0x1bb8,0x39b0 ,0x1b5d,0x39db ,0x1b02,0x3a06 , + 0x1aa7,0x3a30 ,0x1a4b,0x3a59 ,0x19ef,0x3a82 , + 0x1993,0x3aab ,0x1937,0x3ad3 ,0x18db,0x3afa , + 0x187e,0x3b21 ,0x1821,0x3b47 ,0x17c4,0x3b6d , + 0x1766,0x3b92 ,0x1709,0x3bb6 ,0x16ab,0x3bda , + 0x164c,0x3bfd ,0x15ee,0x3c20 ,0x1590,0x3c42 , + 0x1531,0x3c64 ,0x14d2,0x3c85 ,0x1473,0x3ca5 , + 0x1413,0x3cc5 ,0x13b4,0x3ce4 ,0x1354,0x3d03 , + 0x12f4,0x3d21 ,0x1294,0x3d3f ,0x1234,0x3d5b , + 0x11d3,0x3d78 ,0x1173,0x3d93 ,0x1112,0x3daf , + 0x10b1,0x3dc9 ,0x1050,0x3de3 ,0x0fee,0x3dfc , + 0x0f8d,0x3e15 ,0x0f2b,0x3e2d ,0x0eca,0x3e45 , + 0x0e68,0x3e5c ,0x0e06,0x3e72 ,0x0da4,0x3e88 , + 0x0d41,0x3e9d ,0x0cdf,0x3eb1 ,0x0c7c,0x3ec5 , + 0x0c1a,0x3ed8 ,0x0bb7,0x3eeb ,0x0b54,0x3efd , + 0x0af1,0x3f0f ,0x0a8e,0x3f20 ,0x0a2b,0x3f30 , + 0x09c7,0x3f40 ,0x0964,0x3f4f ,0x0901,0x3f5d , + 0x089d,0x3f6b ,0x0839,0x3f78 ,0x07d6,0x3f85 , + 0x0772,0x3f91 ,0x070e,0x3f9c ,0x06aa,0x3fa7 , + 0x0646,0x3fb1 ,0x05e2,0x3fbb ,0x057e,0x3fc4 , + 0x051a,0x3fcc ,0x04b5,0x3fd4 ,0x0451,0x3fdb , + 0x03ed,0x3fe1 ,0x0388,0x3fe7 ,0x0324,0x3fec , + 0x02c0,0x3ff1 ,0x025b,0x3ff5 ,0x01f7,0x3ff8 , + 0x0192,0x3ffb ,0x012e,0x3ffd ,0x00c9,0x3fff , + 0x0065,0x4000 ,0x0000,0x4000 ,0xff9b,0x4000 , + 0xff37,0x3fff ,0xfed2,0x3ffd ,0xfe6e,0x3ffb , + 0xfe09,0x3ff8 ,0xfda5,0x3ff5 ,0xfd40,0x3ff1 , + 0xfcdc,0x3fec ,0xfc78,0x3fe7 ,0xfc13,0x3fe1 , + 0xfbaf,0x3fdb ,0xfb4b,0x3fd4 ,0xfae6,0x3fcc , + 0xfa82,0x3fc4 ,0xfa1e,0x3fbb ,0xf9ba,0x3fb1 , + 0xf956,0x3fa7 ,0xf8f2,0x3f9c ,0xf88e,0x3f91 , + 0xf82a,0x3f85 ,0xf7c7,0x3f78 ,0xf763,0x3f6b , + 0xf6ff,0x3f5d ,0xf69c,0x3f4f ,0xf639,0x3f40 , + 0xf5d5,0x3f30 ,0xf572,0x3f20 ,0xf50f,0x3f0f , + 0xf4ac,0x3efd ,0xf449,0x3eeb ,0xf3e6,0x3ed8 , + 0xf384,0x3ec5 ,0xf321,0x3eb1 ,0xf2bf,0x3e9d , + 0xf25c,0x3e88 ,0xf1fa,0x3e72 ,0xf198,0x3e5c , + 0xf136,0x3e45 ,0xf0d5,0x3e2d ,0xf073,0x3e15 , + 0xf012,0x3dfc ,0xefb0,0x3de3 ,0xef4f,0x3dc9 , + 0xeeee,0x3daf ,0xee8d,0x3d93 ,0xee2d,0x3d78 , + 0xedcc,0x3d5b ,0xed6c,0x3d3f ,0xed0c,0x3d21 , + 0xecac,0x3d03 ,0xec4c,0x3ce4 ,0xebed,0x3cc5 , + 0xeb8d,0x3ca5 ,0xeb2e,0x3c85 ,0xeacf,0x3c64 , + 0xea70,0x3c42 ,0xea12,0x3c20 ,0xe9b4,0x3bfd , + 0xe955,0x3bda ,0xe8f7,0x3bb6 ,0xe89a,0x3b92 , + 0xe83c,0x3b6d ,0xe7df,0x3b47 ,0xe782,0x3b21 , + 0xe725,0x3afa ,0xe6c9,0x3ad3 ,0xe66d,0x3aab , + 0xe611,0x3a82 ,0xe5b5,0x3a59 ,0xe559,0x3a30 , + 0xe4fe,0x3a06 ,0xe4a3,0x39db ,0xe448,0x39b0 , + 0xe3ee,0x3984 ,0xe394,0x3958 ,0xe33a,0x392b , + 0xe2e0,0x38fd ,0xe287,0x38cf ,0xe22d,0x38a1 , + 0xe1d5,0x3871 ,0xe17c,0x3842 ,0xe124,0x3812 , + 0xe0cc,0x37e1 ,0xe074,0x37b0 ,0xe01d,0x377e , + 0xdfc6,0x374b ,0xdf6f,0x3718 ,0xdf19,0x36e5 , + 0xdec3,0x36b1 ,0xde6d,0x367d ,0xde18,0x3648 , + 0xddc3,0x3612 ,0xdd6e,0x35dc ,0xdd19,0x35a5 , + 0xdcc5,0x356e ,0xdc72,0x3537 ,0xdc1e,0x34ff , + 0xdbcb,0x34c6 ,0xdb78,0x348d ,0xdb26,0x3453 , + 0xdad4,0x3419 ,0xda82,0x33df ,0xda31,0x33a3 , + 0xd9e0,0x3368 ,0xd98f,0x332c ,0xd93f,0x32ef , + 0xd8ef,0x32b2 ,0xd8a0,0x3274 ,0xd851,0x3236 , + 0xd802,0x31f8 ,0xd7b4,0x31b9 ,0xd766,0x3179 , + 0xd719,0x3139 ,0xd6cb,0x30f9 ,0xd67f,0x30b8 , + 0xd632,0x3076 ,0xd5e6,0x3034 ,0xd59b,0x2ff2 , + 0xd550,0x2faf ,0xd505,0x2f6c ,0xd4bb,0x2f28 , + 0xd471,0x2ee4 ,0xd428,0x2e9f ,0xd3df,0x2e5a , + 0xd396,0x2e15 ,0xd34e,0x2dcf ,0xd306,0x2d88 , + 0xd2bf,0x2d41 ,0xd278,0x2cfa ,0xd231,0x2cb2 , + 0xd1eb,0x2c6a ,0xd1a6,0x2c21 ,0xd161,0x2bd8 , + 0xd11c,0x2b8f ,0xd0d8,0x2b45 ,0xd094,0x2afb , + 0xd051,0x2ab0 ,0xd00e,0x2a65 ,0xcfcc,0x2a1a , + 0xcf8a,0x29ce ,0xcf48,0x2981 ,0xcf07,0x2935 , + 0xcec7,0x28e7 ,0xce87,0x289a ,0xce47,0x284c , + 0xce08,0x27fe ,0xcdca,0x27af ,0xcd8c,0x2760 , + 0xcd4e,0x2711 ,0xcd11,0x26c1 ,0xccd4,0x2671 , + 0xcc98,0x2620 ,0xcc5d,0x25cf ,0xcc21,0x257e , + 0xcbe7,0x252c ,0xcbad,0x24da ,0xcb73,0x2488 , + 0xcb3a,0x2435 ,0xcb01,0x23e2 ,0xcac9,0x238e , + 0xca92,0x233b ,0xca5b,0x22e7 ,0xca24,0x2292 , + 0xc9ee,0x223d ,0xc9b8,0x21e8 ,0xc983,0x2193 , + 0xc94f,0x213d ,0xc91b,0x20e7 ,0xc8e8,0x2091 , + 0xc8b5,0x203a ,0xc882,0x1fe3 ,0xc850,0x1f8c , + 0xc81f,0x1f34 ,0xc7ee,0x1edc ,0xc7be,0x1e84 , + 0xc78f,0x1e2b ,0xc75f,0x1dd3 ,0xc731,0x1d79 , + 0xc703,0x1d20 ,0xc6d5,0x1cc6 ,0xc6a8,0x1c6c , + 0xc67c,0x1c12 ,0xc650,0x1bb8 ,0xc625,0x1b5d , + 0xc5fa,0x1b02 ,0xc5d0,0x1aa7 ,0xc5a7,0x1a4b , + 0xc57e,0x19ef ,0xc555,0x1993 ,0xc52d,0x1937 , + 0xc506,0x18db ,0xc4df,0x187e ,0xc4b9,0x1821 , + 0xc493,0x17c4 ,0xc46e,0x1766 ,0xc44a,0x1709 , + 0xc426,0x16ab ,0xc403,0x164c ,0xc3e0,0x15ee , + 0xc3be,0x1590 ,0xc39c,0x1531 ,0xc37b,0x14d2 , + 0xc35b,0x1473 ,0xc33b,0x1413 ,0xc31c,0x13b4 , + 0xc2fd,0x1354 ,0xc2df,0x12f4 ,0xc2c1,0x1294 , + 0xc2a5,0x1234 ,0xc288,0x11d3 ,0xc26d,0x1173 , + 0xc251,0x1112 ,0xc237,0x10b1 ,0xc21d,0x1050 , + 0xc204,0x0fee ,0xc1eb,0x0f8d ,0xc1d3,0x0f2b , + 0xc1bb,0x0eca ,0xc1a4,0x0e68 ,0xc18e,0x0e06 , + 0xc178,0x0da4 ,0xc163,0x0d41 ,0xc14f,0x0cdf , + 0xc13b,0x0c7c ,0xc128,0x0c1a ,0xc115,0x0bb7 , + 0xc103,0x0b54 ,0xc0f1,0x0af1 ,0xc0e0,0x0a8e , + 0xc0d0,0x0a2b ,0xc0c0,0x09c7 ,0xc0b1,0x0964 , + 0xc0a3,0x0901 ,0xc095,0x089d ,0xc088,0x0839 , + 0xc07b,0x07d6 ,0xc06f,0x0772 ,0xc064,0x070e , + 0xc059,0x06aa ,0xc04f,0x0646 ,0xc045,0x05e2 , + 0xc03c,0x057e ,0xc034,0x051a ,0xc02c,0x04b5 , + 0xc025,0x0451 ,0xc01f,0x03ed ,0xc019,0x0388 , + 0xc014,0x0324 ,0xc00f,0x02c0 ,0xc00b,0x025b , + 0xc008,0x01f7 ,0xc005,0x0192 ,0xc003,0x012e , + 0xc001,0x00c9 ,0xc000,0x0065 }; diff --git a/src/libs/webrtc/signal_processing_library/webrtc_fft_t_rad.c b/src/libs/webrtc/signal_processing_library/webrtc_fft_t_rad.c new file mode 100644 index 00000000..13fbd9f5 --- /dev/null +++ b/src/libs/webrtc/signal_processing_library/webrtc_fft_t_rad.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file contains the Q14 radix-2 tables used in ARM9E optimization routines. + * + */ + +extern const unsigned short t_Q14S_rad8[2]; +const unsigned short t_Q14S_rad8[2] = { 0x0000,0x2d41 }; + +//extern const int t_Q30S_rad8[2]; +//const int t_Q30S_rad8[2] = { 0x00000000,0x2d413ccd }; + +extern const unsigned short t_Q14R_rad8[2]; +const unsigned short t_Q14R_rad8[2] = { 0x2d41,0x2d41 }; + +//extern const int t_Q30R_rad8[2]; +//const int t_Q30R_rad8[2] = { 0x2d413ccd,0x2d413ccd }; diff --git a/src/libs/webrtc/system_wrappers/aligned_malloc.h b/src/libs/webrtc/system_wrappers/aligned_malloc.h new file mode 100644 index 00000000..c229435e --- /dev/null +++ b/src/libs/webrtc/system_wrappers/aligned_malloc.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ALIGNED_MALLOC_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ALIGNED_MALLOC_H_ + +#include <stddef.h> + +namespace webrtc +{ + void* AlignedMalloc( + size_t size, + size_t alignment); + void AlignedFree( + void* memBlock); +} + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ALIGNED_MALLOC_H_ diff --git a/src/libs/webrtc/system_wrappers/atomic32.cc b/src/libs/webrtc/system_wrappers/atomic32.cc new file mode 100644 index 00000000..3d6849ef --- /dev/null +++ b/src/libs/webrtc/system_wrappers/atomic32.cc @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "atomic32_wrapper.h" + +#if defined(_WIN32) + #include "atomic32_windows.h" +#elif defined(WEBRTC_LINUX) + #include "atomic32_linux.h" +#elif defined(WEBRTC_MAC) + #include "atomic32_mac.h" +#else + #error unsupported os! +#endif + +namespace webrtc { +Atomic32Wrapper::Atomic32Wrapper(WebRtc_Word32 initialValue) + : _impl(*new Atomic32Impl(initialValue)) +{ +} + +Atomic32Wrapper::~Atomic32Wrapper() +{ + delete &_impl; +} + +WebRtc_Word32 Atomic32Wrapper::operator++() +{ + return ++_impl; +} + +WebRtc_Word32 Atomic32Wrapper::operator--() +{ + return --_impl; +} + +// Read and write to properly aligned variables are atomic operations. +// Ex reference (for Windows): http://msdn.microsoft.com/en-us/library/ms684122(v=VS.85).aspx +// TODO (hellner) operator= and Atomic32Wrapper::Value() can be fully +// implemented here. +Atomic32Wrapper& Atomic32Wrapper::operator=(const Atomic32Wrapper& rhs) +{ + if(this == &rhs) + { + return *this; + } + _impl = rhs._impl; + return *this; +} + +Atomic32Wrapper& Atomic32Wrapper::operator=(WebRtc_Word32 rhs) +{ + _impl = rhs; + return *this; +} + +WebRtc_Word32 Atomic32Wrapper::operator+=(WebRtc_Word32 rhs) +{ + return _impl += rhs; +} + +WebRtc_Word32 Atomic32Wrapper::operator-=(WebRtc_Word32 rhs) +{ + return _impl -= rhs; +} + +bool Atomic32Wrapper::CompareExchange(WebRtc_Word32 newValue, + WebRtc_Word32 compareValue) +{ + return _impl.CompareExchange(newValue,compareValue); +} + +WebRtc_Word32 Atomic32Wrapper::Value() const +{ + return _impl.Value(); +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/atomic32_linux.h b/src/libs/webrtc/system_wrappers/atomic32_linux.h new file mode 100644 index 00000000..f9f5650f --- /dev/null +++ b/src/libs/webrtc/system_wrappers/atomic32_linux.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// Atomic system independant 32-bit signed integer. +// Linux implementation. +// Note: Requires gcc 4.1.2 or later. +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_LINUX_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_LINUX_H_ + +#include <inttypes.h> +#include <malloc.h> + +#include "common_types.h" + +namespace webrtc { +class Atomic32Impl +{ +public: + inline Atomic32Impl(WebRtc_Word32 initialValue); + inline ~Atomic32Impl(); + + inline WebRtc_Word32 operator++(); + inline WebRtc_Word32 operator--(); + + inline Atomic32Impl& operator=(const Atomic32Impl& rhs); + inline Atomic32Impl& operator=(WebRtc_Word32 rhs); + inline WebRtc_Word32 operator+=(WebRtc_Word32 rhs); + inline WebRtc_Word32 operator-=(WebRtc_Word32 rhs); + + inline bool CompareExchange(WebRtc_Word32 newValue, + WebRtc_Word32 compareValue); + + inline WebRtc_Word32 Value() const; +private: + void* _ptrMemory; + // Volatile ensures full memory barriers. + volatile WebRtc_Word32* _value; +}; + +// TODO (hellner) use aligned_malloc instead of doing it manually. +inline Atomic32Impl::Atomic32Impl(WebRtc_Word32 initialValue) + : _ptrMemory(NULL), + _value(NULL) +{ // Align the memory associated with _value on a 32-bit boundary. This is a + // requirement for the used Linux APIs to be atomic. + // Keep _ptrMemory to be able to reclaim memory. + _ptrMemory = malloc(sizeof(WebRtc_Word32)*2); + _value = (WebRtc_Word32*) (((uintptr_t)_ptrMemory+3)&(~0x3)); + *_value = initialValue; +} + +inline Atomic32Impl::~Atomic32Impl() +{ + if(_ptrMemory != NULL) + { + free(_ptrMemory); + } +} + +inline WebRtc_Word32 Atomic32Impl::operator++() +{ + WebRtc_Word32 returnValue = __sync_fetch_and_add(_value,1); + returnValue++; + return returnValue; +} + +inline WebRtc_Word32 Atomic32Impl::operator--() +{ + WebRtc_Word32 returnValue = __sync_fetch_and_sub(_value,1); + returnValue--; + return returnValue; +} + +inline Atomic32Impl& Atomic32Impl::operator=(const Atomic32Impl& rhs) +{ + *_value = *rhs._value; + return *this; +} + +inline Atomic32Impl& Atomic32Impl::operator=(WebRtc_Word32 rhs) +{ + *_value = rhs; + return *this; +} + +inline WebRtc_Word32 Atomic32Impl::operator+=(WebRtc_Word32 rhs) +{ + WebRtc_Word32 returnValue = __sync_fetch_and_add(_value,rhs); + returnValue += rhs; + return returnValue; +} + +inline WebRtc_Word32 Atomic32Impl::operator-=(WebRtc_Word32 rhs) +{ + WebRtc_Word32 returnValue = __sync_fetch_and_sub(_value,rhs); + returnValue -= rhs; + return returnValue; +} + +inline bool Atomic32Impl::CompareExchange(WebRtc_Word32 newValue, + WebRtc_Word32 compareValue) +{ + return __sync_bool_compare_and_swap(_value,compareValue,newValue); +} + +inline WebRtc_Word32 Atomic32Impl::Value() const +{ + return *_value; +} +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_LINUX_H_ diff --git a/src/libs/webrtc/system_wrappers/atomic32_mac.h b/src/libs/webrtc/system_wrappers/atomic32_mac.h new file mode 100644 index 00000000..bf8febcd --- /dev/null +++ b/src/libs/webrtc/system_wrappers/atomic32_mac.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// Atomic system independant 32-bit signed integer. +// Mac implementation. +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_MAC_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_MAC_H_ + +#include <stdlib.h> +#include <libkern/OSAtomic.h> + +#include "common_types.h" + +namespace webrtc { +class Atomic32Impl +{ +public: + inline Atomic32Impl(WebRtc_Word32 initialValue); + inline ~Atomic32Impl(); + + inline WebRtc_Word32 operator++(); + inline WebRtc_Word32 operator--(); + + inline Atomic32Impl& operator=(const Atomic32Impl& rhs); + inline Atomic32Impl& operator=(WebRtc_Word32 rhs); + inline WebRtc_Word32 operator+=(WebRtc_Word32 rhs); + inline WebRtc_Word32 operator-=(WebRtc_Word32 rhs); + + inline bool CompareExchange(WebRtc_Word32 newValue, + WebRtc_Word32 compareValue); + + inline WebRtc_Word32 Value() const; +private: + void* _ptrMemory; + // Volatile ensures full memory barriers. + volatile WebRtc_Word32* _value; +}; + +// TODO (hellner) use aligned_malloc instead of doing it manually. +inline Atomic32Impl::Atomic32Impl(WebRtc_Word32 initialValue) + : + _ptrMemory(NULL), + _value(NULL) +{ // Align the memory associated with _value on a 32-bit boundary. This is a + // requirement for the used Mac APIs to be atomic. + // Keep _ptrMemory to be able to reclaim memory. + _ptrMemory = malloc(sizeof(WebRtc_Word32)*2); + _value = (WebRtc_Word32*) (((uintptr_t)_ptrMemory+3)&(~0x3)); + *_value = initialValue; +} + +inline Atomic32Impl::~Atomic32Impl() +{ + if(_ptrMemory != NULL) + { + free(_ptrMemory); + } +} + +inline WebRtc_Word32 Atomic32Impl::operator++() +{ + return OSAtomicIncrement32Barrier( + reinterpret_cast<volatile int32_t*>(_value)); +} + +inline WebRtc_Word32 Atomic32Impl::operator--() +{ + return OSAtomicDecrement32Barrier( + reinterpret_cast<volatile int32_t*>(_value)); +} + +inline Atomic32Impl& Atomic32Impl::operator=(const Atomic32Impl& rhs) +{ + *_value = *rhs._value; + return *this; +} + +inline Atomic32Impl& Atomic32Impl::operator=(WebRtc_Word32 rhs) +{ + *_value = rhs; + return *this; +} + +inline WebRtc_Word32 Atomic32Impl::operator+=(WebRtc_Word32 rhs) +{ + return OSAtomicAdd32Barrier(rhs, + reinterpret_cast<volatile int32_t*>(_value)); +} + +inline WebRtc_Word32 Atomic32Impl::operator-=(WebRtc_Word32 rhs) +{ + return OSAtomicAdd32Barrier(-rhs, + reinterpret_cast<volatile int32_t*>(_value)); +} + +inline bool Atomic32Impl::CompareExchange(WebRtc_Word32 newValue, + WebRtc_Word32 compareValue) +{ + return OSAtomicCompareAndSwap32Barrier( + compareValue, + newValue, + reinterpret_cast<volatile int32_t*>(_value)); +} + +inline WebRtc_Word32 Atomic32Impl::Value() const +{ + return *_value; +} +} // namespace webrtc +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_MAC_H_ diff --git a/src/libs/webrtc/system_wrappers/atomic32_windows.h b/src/libs/webrtc/system_wrappers/atomic32_windows.h new file mode 100644 index 00000000..c27e48ea --- /dev/null +++ b/src/libs/webrtc/system_wrappers/atomic32_windows.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// Atomic system independant 32-bit signed integer. +// Windows implementation. +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_WINDOWS_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_WINDOWS_H_ + +#include <malloc.h> +#include <windows.h> + +#include "common_types.h" + +namespace webrtc { +class Atomic32Impl +{ +public: + inline Atomic32Impl(WebRtc_Word32 initialValue); + inline ~Atomic32Impl(); + + inline WebRtc_Word32 operator++(); + inline WebRtc_Word32 operator--(); + + inline Atomic32Impl& operator=(const Atomic32Impl& rhs); + inline Atomic32Impl& operator=(WebRtc_Word32 rhs); + inline WebRtc_Word32 operator+=(WebRtc_Word32 rhs); + inline WebRtc_Word32 operator-=(WebRtc_Word32 rhs); + + inline bool CompareExchange(WebRtc_Word32 newValue, + WebRtc_Word32 compareValue); + + inline WebRtc_Word32 Value() const; +private: + void* _ptrMemory; + // Volatile ensures full memory barriers. + volatile LONG* _value; +}; + +// TODO (hellner) use aligned_malloc instead of doing it manually. +inline Atomic32Impl::Atomic32Impl(WebRtc_Word32 initialValue) + : _ptrMemory(NULL), + _value(NULL) +{ // Align the memory associated with _value on a 32-bit boundary. This is a + // requirement for the used Windows APIs to be atomic. + // Keep _ptrMemory to be able to reclaim memory. + _ptrMemory = malloc(sizeof(WebRtc_Word32)*2); + _value = reinterpret_cast<LONG*> (((uintptr_t)_ptrMemory+3)&(~0x3)); + *_value = initialValue; +} + +inline Atomic32Impl::~Atomic32Impl() +{ + if(_ptrMemory != NULL) + { + free(_ptrMemory); + } +} + +inline WebRtc_Word32 Atomic32Impl::operator++() +{ + return (WebRtc_Word32)InterlockedIncrement(_value); +} + +inline WebRtc_Word32 Atomic32Impl::operator--() +{ + return (WebRtc_Word32)InterlockedDecrement(_value); +} + +inline Atomic32Impl& Atomic32Impl::operator=(const Atomic32Impl& rhs) +{ + *_value = *rhs._value; + return *this; +} + +inline Atomic32Impl& Atomic32Impl::operator=(WebRtc_Word32 rhs) +{ + *_value = rhs; + return *this; +} + +inline WebRtc_Word32 Atomic32Impl::operator+=(WebRtc_Word32 rhs) +{ + return InterlockedExchangeAdd(_value,rhs); +} + +inline WebRtc_Word32 Atomic32Impl::operator-=(WebRtc_Word32 rhs) +{ + return InterlockedExchangeAdd(_value,-rhs); +} + +inline bool Atomic32Impl::CompareExchange(WebRtc_Word32 newValue, + WebRtc_Word32 compareValue) +{ + const LONG oldValue = InterlockedCompareExchange(_value,newValue, + compareValue); + // If the old value and the compare value is the same an exchange happened. + return (oldValue == compareValue); +} + +inline WebRtc_Word32 Atomic32Impl::Value() const +{ + return *_value; +} +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_WINDOWS_H_ diff --git a/src/libs/webrtc/system_wrappers/atomic32_wrapper.h b/src/libs/webrtc/system_wrappers/atomic32_wrapper.h new file mode 100644 index 00000000..40862fb4 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/atomic32_wrapper.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// Atomic system independant 32-bit integer. +// Note: uses full memory barriers. +// Note: assumes 32-bit (or higher) system +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_WRAPPER_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_WRAPPER_H_ + +#include "common_types.h" + +namespace webrtc { +class Atomic32Impl; +class Atomic32Wrapper +{ +public: + Atomic32Wrapper(WebRtc_Word32 initialValue = 0); + ~Atomic32Wrapper(); + + // Prefix operator! + WebRtc_Word32 operator++(); + WebRtc_Word32 operator--(); + + Atomic32Wrapper& operator=(const Atomic32Wrapper& rhs); + Atomic32Wrapper& operator=(WebRtc_Word32 rhs); + + WebRtc_Word32 operator+=(WebRtc_Word32 rhs); + WebRtc_Word32 operator-=(WebRtc_Word32 rhs); + + // Sets the value atomically to newValue if the value equals compare value. + // The function returns true if the exchange happened. + bool CompareExchange(WebRtc_Word32 newValue, WebRtc_Word32 compareValue); + WebRtc_Word32 Value() const; +private: + // Disable the + and - operator since it's unclear what these operations + // should do. + Atomic32Wrapper operator+(const Atomic32Wrapper& rhs); + Atomic32Wrapper operator-(const Atomic32Wrapper& rhs); + + WebRtc_Word32& operator++(int); + WebRtc_Word32& operator--(int); + + // Cheshire cat to hide the implementation (faster than + // using virtual functions) + Atomic32Impl& _impl; +}; +} // namespace webrtc +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_WRAPPER_H_ diff --git a/src/libs/webrtc/system_wrappers/condition_variable.cc b/src/libs/webrtc/system_wrappers/condition_variable.cc new file mode 100644 index 00000000..7ca1b567 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/condition_variable.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#if defined(_WIN32) + #include <windows.h> + #include "condition_variable_wrapper.h" + #include "condition_variable_windows.h" +#elif defined(WEBRTC_LINUX) + #include <pthread.h> + #include "condition_variable_wrapper.h" + #include "condition_variable_linux.h" +#elif defined(WEBRTC_MAC) || defined(WEBRTC_MAC_INTEL) + #include <pthread.h> + #include "condition_variable_wrapper.h" + #include "condition_variable_linux.h" + #endif + +namespace webrtc { +ConditionVariableWrapper* +ConditionVariableWrapper::CreateConditionVariable() +{ +#if defined(_WIN32) + return new ConditionVariableWindows; +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) || defined(WEBRTC_MAC_INTEL) + return ConditionVariableLinux::Create(); +#else + return NULL; +#endif +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/condition_variable_linux.cc b/src/libs/webrtc/system_wrappers/condition_variable_linux.cc new file mode 100644 index 00000000..eb848bab --- /dev/null +++ b/src/libs/webrtc/system_wrappers/condition_variable_linux.cc @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "condition_variable_linux.h" + +#if defined(WEBRTC_LINUX) +#include <ctime> +#else +#include <sys/time.h> +#endif + +#include <errno.h> + +#include "critical_section_linux.h" + +namespace webrtc { +ConditionVariableWrapper* ConditionVariableLinux::Create() +{ + ConditionVariableLinux* ptr = new ConditionVariableLinux; + if (!ptr) + { + return NULL; + } + + const int error = ptr->Construct(); + if (error) + { + delete ptr; + return NULL; + } + + return ptr; +} + +ConditionVariableLinux::ConditionVariableLinux() +{ +} + +int ConditionVariableLinux::Construct() +{ + int result = 0; +#ifdef WEBRTC_CLOCK_TYPE_REALTIME + result = pthread_cond_init(&_cond, NULL); +#else + pthread_condattr_t condAttr; + result = pthread_condattr_init(&condAttr); + if (result != 0) + { + return -1; + } +#ifndef WEBRTC_MAC + result = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC); + if (result != 0) + { + return -1; + } +#endif + result = pthread_cond_init(&_cond, &condAttr); + if (result != 0) + { + return -1; + } + result = pthread_condattr_destroy(&condAttr); + if (result != 0) + { + return -1; + } +#endif + return 0; +} + +ConditionVariableLinux::~ConditionVariableLinux() +{ + pthread_cond_destroy(&_cond); +} + +void ConditionVariableLinux::SleepCS(CriticalSectionWrapper& critSect) +{ + CriticalSectionLinux* cs = reinterpret_cast<CriticalSectionLinux*>( + &critSect); + pthread_cond_wait(&_cond, &cs->_mutex); +} + + +bool +ConditionVariableLinux::SleepCS( + CriticalSectionWrapper& critSect, + unsigned long maxTimeInMS) +{ + const unsigned long INFINITE = 0xFFFFFFFF; + + const int MILLISECONDS_PER_SECOND = 1000; +#ifndef WEBRTC_LINUX + const int MICROSECONDS_PER_MILLISECOND = 1000; +#endif + const int NANOSECONDS_PER_SECOND = 1000000000; + const int NANOSECONDS_PER_MILLISECOND = 1000000; + + CriticalSectionLinux* cs = reinterpret_cast<CriticalSectionLinux*>( + &critSect); + + if (maxTimeInMS != INFINITE) + { + timespec ts; +#ifndef WEBRTC_MAC +#ifdef WEBRTC_CLOCK_TYPE_REALTIME + clock_gettime(CLOCK_REALTIME, &ts); +#else + clock_gettime(CLOCK_MONOTONIC, &ts); +#endif +#else + struct timeval tv; + gettimeofday(&tv, 0); + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * MICROSECONDS_PER_MILLISECOND; +#endif + + ts.tv_sec += maxTimeInMS / MILLISECONDS_PER_SECOND; + ts.tv_nsec += (maxTimeInMS - ((maxTimeInMS / MILLISECONDS_PER_SECOND)* + MILLISECONDS_PER_SECOND)) * NANOSECONDS_PER_MILLISECOND; + + if (ts.tv_nsec >= NANOSECONDS_PER_SECOND) + { + ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND; + ts.tv_nsec %= NANOSECONDS_PER_SECOND; + } + const int res = pthread_cond_timedwait(&_cond, &cs->_mutex, &ts); + return (res == ETIMEDOUT) ? false : true; + } + else + { + pthread_cond_wait(&_cond, &cs->_mutex); + return true; + } +} + +void ConditionVariableLinux::Wake() +{ + pthread_cond_signal(&_cond); +} + +void ConditionVariableLinux::WakeAll() +{ + pthread_cond_broadcast(&_cond); +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/condition_variable_linux.h b/src/libs/webrtc/system_wrappers/condition_variable_linux.h new file mode 100644 index 00000000..0300c5b5 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/condition_variable_linux.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_LINUX_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_LINUX_H_ + +#include "condition_variable_wrapper.h" + +#include <pthread.h> + +namespace webrtc { +class ConditionVariableLinux : public ConditionVariableWrapper +{ +public: + static ConditionVariableWrapper* Create(); + ~ConditionVariableLinux(); + + void SleepCS(CriticalSectionWrapper& critSect); + bool SleepCS(CriticalSectionWrapper& critSect, unsigned long maxTimeInMS); + void Wake(); + void WakeAll(); + +private: + ConditionVariableLinux(); + int Construct(); + +private: + pthread_cond_t _cond; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_LINUX_H_ diff --git a/src/libs/webrtc/system_wrappers/condition_variable_windows.cc b/src/libs/webrtc/system_wrappers/condition_variable_windows.cc new file mode 100644 index 00000000..1805d21b --- /dev/null +++ b/src/libs/webrtc/system_wrappers/condition_variable_windows.cc @@ -0,0 +1,224 @@ +/* + * Use of this source code is governed by the ACE copyright license which + * can be found in the LICENSE file in the third_party_mods/ace directory of + * the source tree or at http://www1.cse.wustl.edu/~schmidt/ACE-copying.html. + */ +/* + * This source code contain modifications to the original source code + * which can be found here: + * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html (section 3.2). + * Modifications: + * 1) Dynamic detection of native support for condition variables. + * 2) Use of WebRTC defined types and classes. Renaming of some functions. + * 3) Introduction of a second event for wake all functionality. This prevents + * a thread from spinning on the same condition variable, preventing other + * threads from waking up. + */ + +// TODO (hellner): probably nicer to split up native and generic +// implementation into two different files + +#include "condition_variable_windows.h" + +#include "critical_section_windows.h" +#include "trace.h" + +namespace webrtc { +bool ConditionVariableWindows::_winSupportConditionVariablesPrimitive = false; +static HMODULE library = NULL; + +PInitializeConditionVariable _PInitializeConditionVariable; +PSleepConditionVariableCS _PSleepConditionVariableCS; +PWakeConditionVariable _PWakeConditionVariable; +PWakeAllConditionVariable _PWakeAllConditionVariable; + +typedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE); +typedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE, + PCRITICAL_SECTION, DWORD); +typedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE); +typedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE); + +ConditionVariableWindows::ConditionVariableWindows() + : _eventID(WAKEALL_0) +{ + if (!library) + { + // Use native implementation if supported (i.e Vista+) + library = LoadLibrary(TEXT("Kernel32.dll")); + if (library) + { + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, + "Loaded Kernel.dll"); + + _PInitializeConditionVariable = + (PInitializeConditionVariable) GetProcAddress( + library, + "InitializeConditionVariable"); + _PSleepConditionVariableCS = + (PSleepConditionVariableCS)GetProcAddress( + library, + "SleepConditionVariableCS"); + _PWakeConditionVariable = + (PWakeConditionVariable)GetProcAddress( + library, + "WakeConditionVariable"); + _PWakeAllConditionVariable = + (PWakeAllConditionVariable)GetProcAddress( + library, + "WakeAllConditionVariable"); + + if(_PInitializeConditionVariable && + _PSleepConditionVariableCS && + _PWakeConditionVariable && + _PWakeAllConditionVariable) + { + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, + "Loaded native condition variables"); + _winSupportConditionVariablesPrimitive = true; + } + } + } + + if (_winSupportConditionVariablesPrimitive) + { + _PInitializeConditionVariable(&_conditionVariable); + + _events[WAKEALL_0] = NULL; + _events[WAKEALL_1] = NULL; + _events[WAKE] = NULL; + + } else { + memset(&_numWaiters[0],0,sizeof(_numWaiters)); + + InitializeCriticalSection(&_numWaitersCritSect); + + _events[WAKEALL_0] = CreateEvent(NULL, // no security attributes + TRUE, // manual-reset, sticky event + FALSE, // initial state non-signaled + NULL); // no name for event + + _events[WAKEALL_1] = CreateEvent(NULL, // no security attributes + TRUE, // manual-reset, sticky event + FALSE, // initial state non-signaled + NULL); // no name for event + + _events[WAKE] = CreateEvent(NULL, // no security attributes + FALSE, // auto-reset, sticky event + FALSE, // initial state non-signaled + NULL); // no name for event + } +} + +ConditionVariableWindows::~ConditionVariableWindows() +{ + if(!_winSupportConditionVariablesPrimitive) + { + CloseHandle(_events[WAKE]); + CloseHandle(_events[WAKEALL_1]); + CloseHandle(_events[WAKEALL_0]); + + DeleteCriticalSection(&_numWaitersCritSect); + } +} + +void ConditionVariableWindows::SleepCS(CriticalSectionWrapper& critSect) +{ + SleepCS(critSect, INFINITE); +} + +bool ConditionVariableWindows::SleepCS(CriticalSectionWrapper& critSect, + unsigned long maxTimeInMS) +{ + CriticalSectionWindows* cs = reinterpret_cast<CriticalSectionWindows*>( + &critSect); + + if(_winSupportConditionVariablesPrimitive) + { + BOOL retVal = _PSleepConditionVariableCS(&_conditionVariable, + &(cs->crit),maxTimeInMS); + return (retVal == 0) ? false : true; + + }else + { + EnterCriticalSection(&_numWaitersCritSect); + // Get the eventID for the event that will be triggered by next + // WakeAll() call and start waiting for it. + const EventWakeUpType eventID = (WAKEALL_0 == _eventID) ? + WAKEALL_1 : WAKEALL_0; + ++(_numWaiters[eventID]); + LeaveCriticalSection(&_numWaitersCritSect); + + LeaveCriticalSection(&cs->crit); + HANDLE events[2]; + events[0] = _events[WAKE]; + events[1] = _events[eventID]; + const DWORD result = WaitForMultipleObjects(2, // Wait on 2 events. + events, + FALSE, // Wait for either. + maxTimeInMS); + + const bool retVal = (result != WAIT_TIMEOUT); + + EnterCriticalSection(&_numWaitersCritSect); + --(_numWaiters[eventID]); + // Last waiter should only be true for WakeAll(). WakeAll() correspond + // to position 1 in events[] -> (result == WAIT_OBJECT_0 + 1) + const bool lastWaiter = (result == WAIT_OBJECT_0 + 1) && + (_numWaiters[eventID] == 0); + LeaveCriticalSection(&_numWaitersCritSect); + + if (lastWaiter) + { + // Reset/unset the WakeAll() event since all threads have been + // released. + ResetEvent(_events[eventID]); + } + + EnterCriticalSection(&cs->crit); + return retVal; + } +} + +void +ConditionVariableWindows::Wake() +{ + if(_winSupportConditionVariablesPrimitive) + { + _PWakeConditionVariable(&_conditionVariable); + }else + { + EnterCriticalSection(&_numWaitersCritSect); + const bool haveWaiters = (_numWaiters[WAKEALL_0] > 0) || + (_numWaiters[WAKEALL_1] > 0); + LeaveCriticalSection(&_numWaitersCritSect); + + if (haveWaiters) + { + SetEvent(_events[WAKE]); + } + } +} + +void +ConditionVariableWindows::WakeAll() +{ + if(_winSupportConditionVariablesPrimitive) + { + _PWakeAllConditionVariable(&_conditionVariable); + }else + { + EnterCriticalSection(&_numWaitersCritSect); + // Update current WakeAll() event + _eventID = (WAKEALL_0 == _eventID) ? WAKEALL_1 : WAKEALL_0; + // Trigger current event + const EventWakeUpType eventID = _eventID; + const bool haveWaiters = _numWaiters[eventID] > 0; + LeaveCriticalSection(&_numWaitersCritSect); + + if (haveWaiters) + { + SetEvent(_events[eventID]); + } + } +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/condition_variable_windows.h b/src/libs/webrtc/system_wrappers/condition_variable_windows.h new file mode 100644 index 00000000..aab2564d --- /dev/null +++ b/src/libs/webrtc/system_wrappers/condition_variable_windows.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WINDOWS_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WINDOWS_H_ + +#include "condition_variable_wrapper.h" + +#include <windows.h> + +namespace webrtc { +#if !defined CONDITION_VARIABLE_INIT + typedef struct _RTL_CONDITION_VARIABLE + { + void* Ptr; + } RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE; + + typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE; +#endif + +typedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE); +typedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE, + PCRITICAL_SECTION, DWORD); +typedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE); +typedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE); + + +class ConditionVariableWindows : public ConditionVariableWrapper +{ +public: + ConditionVariableWindows(); + ~ConditionVariableWindows(); + + void SleepCS(CriticalSectionWrapper& critSect); + bool SleepCS(CriticalSectionWrapper& critSect, unsigned long maxTimeInMS); + void Wake(); + void WakeAll(); + +private: + enum EventWakeUpType + { + WAKEALL_0 = 0, + WAKEALL_1 = 1, + WAKE = 2, + EVENT_COUNT = 3 + }; + +private: + // Native support for Windows Vista+ + static bool _winSupportConditionVariablesPrimitive; + CONDITION_VARIABLE _conditionVariable; + + unsigned int _numWaiters[2]; + EventWakeUpType _eventID; + CRITICAL_SECTION _numWaitersCritSect; + HANDLE _events[EVENT_COUNT]; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WINDOWS_H_ diff --git a/src/libs/webrtc/system_wrappers/condition_variable_wrapper.h b/src/libs/webrtc/system_wrappers/condition_variable_wrapper.h new file mode 100644 index 00000000..c040fbf2 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/condition_variable_wrapper.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONDITION_VARIABLE_WRAPPER_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONDITION_VARIABLE_WRAPPER_H_ + +namespace webrtc { +class CriticalSectionWrapper; + +class ConditionVariableWrapper +{ +public: + // Factory method, constructor disabled. + static ConditionVariableWrapper* CreateConditionVariable(); + + virtual ~ConditionVariableWrapper() {} + + // Calling thread will atomically release critSect and wait until next + // some other thread calls Wake() or WakeAll(). + virtual void SleepCS(CriticalSectionWrapper& critSect) = 0; + + // Same as above but with a timeout. + virtual bool SleepCS(CriticalSectionWrapper& critSect, + unsigned long maxTimeInMS) = 0; + + // Wakes one thread calling SleepCS(). + virtual void Wake() = 0; + + // Wakes all threads calling SleepCS(). + virtual void WakeAll() = 0; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONDITION_VARIABLE_WRAPPER_H_ diff --git a/src/libs/webrtc/system_wrappers/constructor_magic.h b/src/libs/webrtc/system_wrappers/constructor_magic.h new file mode 100644 index 00000000..b2aabc57 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/constructor_magic.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * WebRtc + * Copy from third_party/libjingle/source/talk/base/constructormagic.h + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONSTRUCTOR_MAGIC_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONSTRUCTOR_MAGIC_H_ + +#ifndef DISALLOW_ASSIGN +#define DISALLOW_ASSIGN(TypeName) \ + void operator=(const TypeName&) +#endif + +#ifndef DISALLOW_COPY_AND_ASSIGN +// A macro to disallow the evil copy constructor and operator= functions +// This should be used in the private: declarations for a class +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + DISALLOW_ASSIGN(TypeName) +#endif + +#ifndef DISALLOW_EVIL_CONSTRUCTORS +// Alternative, less-accurate legacy name. +#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ + DISALLOW_COPY_AND_ASSIGN(TypeName) +#endif + +#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS +// A macro to disallow all the implicit constructors, namely the +// default constructor, copy constructor and operator= functions. +// +// This should be used in the private: declarations for a class +// that wants to prevent anyone from instantiating it. This is +// especially useful for classes containing only static methods. +#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ + TypeName(); \ + DISALLOW_EVIL_CONSTRUCTORS(TypeName) +#endif + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONSTRUCTOR_MAGIC_H_ diff --git a/src/libs/webrtc/system_wrappers/cpu.cc b/src/libs/webrtc/system_wrappers/cpu.cc new file mode 100644 index 00000000..22858727 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/cpu.cc @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "cpu_wrapper.h" + +#if defined(_WIN32) + #include <Windows.h> + #include "engine_configurations.h" + #include "cpu_windows.h" +#elif defined(WEBRTC_MAC) + #include <sys/types.h> + #include <sys/sysctl.h> + #include "cpu_mac.h" +#elif defined(WEBRTC_MAC_INTEL) + #include "cpu_mac.h" +#elif defined(ANDROID) + // Not implemented yet, might be possible to use Linux implementation +#else // defined(WEBRTC_LINUX) + #include <sys/sysinfo.h> + #include "cpu_linux.h" +#endif + +#include "trace.h" + +namespace webrtc { +WebRtc_UWord32 CpuWrapper::_numberOfCores = 0; + +WebRtc_UWord32 CpuWrapper::DetectNumberOfCores() +{ + if (!_numberOfCores) + { +#if defined(_WIN32) + SYSTEM_INFO si; + GetSystemInfo(&si); + _numberOfCores = static_cast<WebRtc_UWord32>(si.dwNumberOfProcessors); + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, + "Available number of cores:%d", _numberOfCores); + +#elif defined(WEBRTC_LINUX) && !defined(ANDROID) + _numberOfCores = get_nprocs(); + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, + "Available number of cores:%d", _numberOfCores); + +#elif (defined(WEBRTC_MAC) || defined(WEBRTC_MAC_INTEL)) + int name[] = {CTL_HW, HW_AVAILCPU}; + int ncpu; + size_t size = sizeof(ncpu); + if(0 == sysctl(name, 2, &ncpu, &size, NULL, 0)) + { + _numberOfCores = static_cast<WebRtc_UWord32>(ncpu); + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, + "Available number of cores:%d", _numberOfCores); + } else + { + WEBRTC_TRACE(kTraceError, kTraceUtility, -1, + "Failed to get number of cores"); + _numberOfCores = 1; + } +#else + WEBRTC_TRACE(kTraceWarning, kTraceUtility, -1, + "No function to get number of cores"); + _numberOfCores = 1; +#endif + } + return _numberOfCores; +} + +CpuWrapper* CpuWrapper::CreateCpu() +{ +#if defined(_WIN32) + return new CpuWindows(); +#elif (defined(WEBRTC_MAC) || defined(WEBRTC_MAC_INTEL)) + return new CpuWrapperMac(); +#elif defined(ANDROID) + return 0; +#else + return new CpuLinux(); +#endif +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/cpu_features.cc b/src/libs/webrtc/system_wrappers/cpu_features.cc new file mode 100644 index 00000000..850dc9b0 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/cpu_features.cc @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "cpu_features_wrapper.h" + +// No CPU feature is available => straight C path. +int GetCPUInfoNoASM(CPUFeature feature) { + (void)feature; + return 0; +} + +// Intrinsic for "cpuid". +#if defined(__pic__) && defined(__i386__) +static inline void cpuid(int cpu_info[4], int info_type) { + __asm__ volatile ( + "mov %%ebx, %%edi\n" + "cpuid\n" + "xchg %%edi, %%ebx\n" + : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) + : "a"(info_type)); +} +#elif defined(__i386__) || defined(__x86_64__) +static inline void cpuid(int cpu_info[4], int info_type) { + __asm__ volatile ( + "cpuid\n" + : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) + : "a"(info_type)); +} +#endif + +#if defined(__i386__) || defined(__x86_64__) +// Actual feature detection for x86. +static int GetCPUInfo(CPUFeature feature) { + int cpu_info[4]; + cpuid(cpu_info, 1); + if (feature == kSSE2) { + return 0 != (cpu_info[3] & 0x04000000); + } + if (feature == kSSE3) { + return 0 != (cpu_info[2] & 0x00000001); + } + return 0; +} +#else +// Default to straight C for other platforms. +static int GetCPUInfo(CPUFeature feature) { + (void)feature; + return 0; +} +#endif + +WebRtc_CPUInfo WebRtc_GetCPUInfo = GetCPUInfo; +WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM = GetCPUInfoNoASM; diff --git a/src/libs/webrtc/system_wrappers/cpu_features_wrapper.h b/src/libs/webrtc/system_wrappers/cpu_features_wrapper.h new file mode 100644 index 00000000..5d8a828a --- /dev/null +++ b/src/libs/webrtc/system_wrappers/cpu_features_wrapper.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_ + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +// list of features. +typedef enum { + kSSE2, + kSSE3 +} CPUFeature; + +typedef int (*WebRtc_CPUInfo)(CPUFeature feature); +// returns true if the CPU supports the feature. +extern WebRtc_CPUInfo WebRtc_GetCPUInfo; +// No CPU feature is available => straight C path. +extern WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM; + +#if defined(__cplusplus) || defined(c_plusplus) +} // extern "C" +#endif + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_ diff --git a/src/libs/webrtc/system_wrappers/cpu_linux.cc b/src/libs/webrtc/system_wrappers/cpu_linux.cc new file mode 100644 index 00000000..eff9704d --- /dev/null +++ b/src/libs/webrtc/system_wrappers/cpu_linux.cc @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "cpu_linux.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +namespace webrtc { +CpuLinux::CpuLinux() +{ + m_oldBusyTime = 0; + m_oldIdleTime = 0; + m_numCores = 0; + m_numCores = GetNumCores(); + m_oldBusyTimeMulti = new long long[m_numCores]; + memset(m_oldBusyTimeMulti, 0, sizeof(long long) * m_numCores); + m_oldIdleTimeMulti = new long long[m_numCores]; + memset(m_oldIdleTimeMulti, 0, sizeof(long long) * m_numCores); + m_idleArray = new long long[m_numCores]; + memset(m_idleArray, 0, sizeof(long long) * m_numCores); + m_busyArray = new long long[m_numCores]; + memset(m_busyArray, 0, sizeof(long long) * m_numCores); + m_resultArray = new WebRtc_UWord32[m_numCores]; + + GetData(m_oldBusyTime, m_oldIdleTime, m_busyArray, m_idleArray); +} + +CpuLinux::~CpuLinux() +{ + delete [] m_oldBusyTimeMulti; + delete [] m_oldIdleTimeMulti; + delete [] m_idleArray; + delete [] m_busyArray; + delete [] m_resultArray; +} + +WebRtc_Word32 CpuLinux::CpuUsage() +{ + WebRtc_UWord32 dummy = 0; + WebRtc_UWord32* dummyArray = NULL; + return CpuUsageMultiCore(dummy, dummyArray); +} + +WebRtc_Word32 CpuLinux::CpuUsageMultiCore(WebRtc_UWord32& numCores, + WebRtc_UWord32*& coreArray) +{ + coreArray = m_resultArray; + numCores = m_numCores; + long long busy = 0; + long long idle = 0; + GetData(busy, idle, m_busyArray, m_idleArray); + + long long deltaBusy = busy - m_oldBusyTime; + long long deltaIdle = idle - m_oldIdleTime; + m_oldBusyTime = busy; + m_oldIdleTime = idle; + + int retVal = -1; + if (deltaBusy + deltaIdle == 0) + { + retVal = 0; + } + else + { + retVal = (int)(100 * (deltaBusy) / (deltaBusy + deltaIdle)); + } + + if (coreArray == NULL) + { + return retVal; + } + + for (WebRtc_UWord32 i = 0; i < m_numCores; i++) + { + deltaBusy = m_busyArray[i] - m_oldBusyTimeMulti[i]; + deltaIdle = m_idleArray[i] - m_oldIdleTimeMulti[i]; + m_oldBusyTimeMulti[i] = m_busyArray[i]; + m_oldIdleTimeMulti[i] = m_idleArray[i]; + if(deltaBusy + deltaIdle == 0) + { + coreArray[i] = 0; + } + else + { + coreArray[i] = (int)(100 * (deltaBusy) / (deltaBusy+deltaIdle)); + } + } + return retVal; +} + + +int CpuLinux::GetData(long long& busy, long long& idle, long long*& busyArray, + long long*& idleArray) +{ + FILE* fp = fopen("/proc/stat", "r"); + if (!fp) + { + return -1; + } + + char line[100]; + char* dummy = fgets(line, 100, fp); + char firstWord[100]; + sscanf(line, "%s ", firstWord); + if(strncmp(firstWord, "cpu", 3)!=0) + { + return -1; + } + char sUser[100]; + char sNice[100]; + char sSystem[100]; + char sIdle[100]; + sscanf(line, "%s %s %s %s %s ", firstWord, sUser, sNice, sSystem, sIdle); + long long luser = atoll(sUser); + long long lnice = atoll(sNice); + long long lsystem = atoll(sSystem); + long long lidle = atoll (sIdle); + + busy = luser + lnice + lsystem; + idle = lidle; + for (WebRtc_UWord32 i = 0; i < m_numCores; i++) + { + dummy = fgets(line, 100, fp); + sscanf(line, "%s %s %s %s %s ", firstWord, sUser, sNice, sSystem, + sIdle); + luser = atoll(sUser); + lnice = atoll(sNice); + lsystem = atoll(sSystem); + lidle = atoll (sIdle); + busyArray[i] = luser + lnice + lsystem; + idleArray[i] = lidle; + } + fclose(fp); + return 0; +} + +int CpuLinux::GetNumCores() +{ + FILE* fp = fopen("/proc/stat", "r"); + if (!fp) + { + return -1; + } + // Skip first line + char line[100]; + char* dummy = fgets(line, 100, fp); + int numCores = -1; + char firstWord[100]; + do + { + numCores++; + if (fgets(line, 100, fp)) + { + sscanf(line, "%s ", firstWord); + } else { + break; + } + } while (strncmp(firstWord, "cpu", 3) == 0); + fclose(fp); + return numCores; +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/cpu_linux.h b/src/libs/webrtc/system_wrappers/cpu_linux.h new file mode 100644 index 00000000..9b22e836 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/cpu_linux.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_LINUX_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_LINUX_H_ + +#include "cpu_wrapper.h" + +namespace webrtc { +class CpuLinux : public CpuWrapper +{ +public: + CpuLinux(); + virtual ~CpuLinux(); + + virtual WebRtc_Word32 CpuUsage(); + virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* /*pProcessName*/, + WebRtc_UWord32 /*length*/) {return 0;} + virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 /*dwProcessID*/) {return 0;} + + virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& numCores, + WebRtc_UWord32*& array); + + virtual void Reset() {return;} + virtual void Stop() {return;} +private: + int GetData(long long& busy, long long& idle, long long*& busyArray, + long long*& idleArray); + int GetNumCores(); + + long long m_oldBusyTime; + long long m_oldIdleTime; + + long long* m_oldBusyTimeMulti; + long long* m_oldIdleTimeMulti; + + long long* m_idleArray; + long long* m_busyArray; + WebRtc_UWord32* m_resultArray; + WebRtc_UWord32 m_numCores; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_LINUX_H_ diff --git a/src/libs/webrtc/system_wrappers/cpu_mac.cc b/src/libs/webrtc/system_wrappers/cpu_mac.cc new file mode 100644 index 00000000..c2a11e1b --- /dev/null +++ b/src/libs/webrtc/system_wrappers/cpu_mac.cc @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "cpu_mac.h" + +#include <iostream> +#include <mach/mach.h> +#include <mach/mach_error.h> + +#include "tick_util.h" + +namespace webrtc { +CpuWrapperMac::CpuWrapperMac() : _cpuUsage(NULL) +{ + natural_t cpuCount; + processor_info_array_t infoArray; + mach_msg_type_number_t infoCount; + + kern_return_t error = host_processor_info(mach_host_self(), + PROCESSOR_CPU_LOAD_INFO, + &cpuCount, + &infoArray, + &infoCount); + if (error) + { + return; + } + + _cpuUsage = new WebRtc_UWord32[cpuCount]; + _lastTickCount = new WebRtc_Word64[cpuCount]; + _lastTime = TickTime::MillisecondTimestamp(); + + processor_cpu_load_info_data_t* cpuLoadInfo = + (processor_cpu_load_info_data_t*) infoArray; + for (unsigned int cpu= 0; cpu < cpuCount; cpu++) + { + WebRtc_Word64 ticks = 0; + for (int state = 0; state < 2; state++) + { + ticks += cpuLoadInfo[cpu].cpu_ticks[state]; + } + _lastTickCount[cpu] = ticks; + } + vm_deallocate(mach_task_self(), (vm_address_t)infoArray, infoCount); +} + +CpuWrapperMac::~CpuWrapperMac() +{ + delete _cpuUsage; + delete _lastTickCount; +} + +WebRtc_Word32 CpuWrapperMac::CpuUsage() +{ + WebRtc_UWord32 numCores; + WebRtc_UWord32* array = NULL; + return CpuUsageMultiCore(numCores, array); +} + +WebRtc_Word32 +CpuWrapperMac::CpuUsageMultiCore(WebRtc_UWord32& numCores, + WebRtc_UWord32*& array) +{ + natural_t cpuCount; + processor_info_array_t infoArray; + mach_msg_type_number_t infoCount; + + // sanity check + if(_cpuUsage == NULL) + { + return -1; + } + WebRtc_Word64 now = TickTime::MillisecondTimestamp(); + WebRtc_Word64 timeDiffMS = now - _lastTime; + // TODO(hellner) why block here? Why not just return the old + // value? Is this behavior consistent across all + // platforms? + // Make sure that at least 500 ms pass between calls. + if(timeDiffMS < 500) + { + usleep((500-timeDiffMS)*1000); + return CpuUsageMultiCore(numCores, array); + } + _lastTime = now; + + kern_return_t error = host_processor_info(mach_host_self(), + PROCESSOR_CPU_LOAD_INFO, + &cpuCount, + &infoArray, + &infoCount); + if (error) + { + return -1; + } + + processor_cpu_load_info_data_t* cpuLoadInfo = + (processor_cpu_load_info_data_t*) infoArray; + + WebRtc_Word32 totalCpuUsage = 0; + for (unsigned int cpu = 0; cpu < cpuCount; cpu++) + { + WebRtc_Word64 ticks = 0; + for (int state = 0; state < 2; state++) + { + ticks += cpuLoadInfo[cpu].cpu_ticks[state]; + } + if(timeDiffMS <= 0) + { + _cpuUsage[cpu] = 0; + }else { + _cpuUsage[cpu] = (WebRtc_UWord32)((1000 * + (ticks - _lastTickCount[cpu])) / + timeDiffMS); + } + _lastTickCount[cpu] = ticks; + totalCpuUsage += _cpuUsage[cpu]; + } + + vm_deallocate(mach_task_self(), (vm_address_t)infoArray, infoCount); + + numCores = cpuCount; + array = _cpuUsage; + return totalCpuUsage/cpuCount; +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/cpu_mac.h b/src/libs/webrtc/system_wrappers/cpu_mac.h new file mode 100644 index 00000000..04cd097b --- /dev/null +++ b/src/libs/webrtc/system_wrappers/cpu_mac.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_MAC_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_MAC_H_ + +#include "cpu_wrapper.h" + +namespace webrtc { +class CpuWrapperMac : public CpuWrapper +{ +public: + CpuWrapperMac(); + virtual ~CpuWrapperMac(); + + virtual WebRtc_Word32 CpuUsage(); + virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* /*pProcessName*/, + WebRtc_UWord32 /*length*/) {return -1;} + virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 /*dwProcessID*/) {return -1;} + + // Note: this class will block the call and sleep if called too fast + // This function blocks the calling thread if the thread is calling it more + // often than every 500 ms. + virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& numCores, + WebRtc_UWord32*& array); + + virtual void Reset() {} + virtual void Stop() {} + +private: + WebRtc_UWord32* _cpuUsage; + WebRtc_Word64* _lastTickCount; + WebRtc_Word64 _lastTime; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_MAC_H_ diff --git a/src/libs/webrtc/system_wrappers/cpu_windows.cc b/src/libs/webrtc/system_wrappers/cpu_windows.cc new file mode 100644 index 00000000..22146bf7 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/cpu_windows.cc @@ -0,0 +1,532 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "cpu_windows.h" + +#define _WIN32_DCOM + +#include <assert.h> +#include <iostream> +#include <Wbemidl.h> + +#pragma comment(lib, "wbemuuid.lib") + +#include "condition_variable_wrapper.h" +#include "critical_section_wrapper.h" +#include "event_wrapper.h" +#include "thread_wrapper.h" + +namespace webrtc { +WebRtc_Word32 CpuWindows::CpuUsage() +{ + if (!has_initialized_) + { + return -1; + } + // Last element is the average + return cpu_usage_[number_of_objects_ - 1]; +} + +WebRtc_Word32 CpuWindows::CpuUsageMultiCore(WebRtc_UWord32& num_cores, + WebRtc_UWord32*& cpu_usage) +{ + if (!has_initialized_) + { + return -1; + } + num_cores = number_of_objects_ - 1; + cpu_usage = cpu_usage_; + return cpu_usage_[number_of_objects_-1]; +} + +CpuWindows::CpuWindows() + : cpu_polling_thread(NULL), + initialize_(true), + has_initialized_(false), + terminate_(false), + has_terminated_(false), + cpu_usage_(NULL), + wbem_enum_access_(NULL), + number_of_objects_(0), + cpu_usage_handle_(0), + previous_processor_timestamp_(NULL), + timestamp_sys_100_ns_handle_(0), + previous_100ns_timestamp_(NULL), + wbem_service_(NULL), + wbem_service_proxy_(NULL), + wbem_refresher_(NULL), + wbem_enum_(NULL) +{ + // All resources are allocated in PollingCpu(). + if (AllocateComplexDataTypes()) + { + const bool success = StartPollingCpu(); + assert(success); + } + else + { + assert(false); + } +} + +CpuWindows::~CpuWindows() +{ + // All resources are reclaimed in StopPollingCpu(). + const bool success = StopPollingCpu(); + assert(success); + DeAllocateComplexDataTypes(); +} + +bool CpuWindows::AllocateComplexDataTypes() +{ + cpu_polling_thread = ThreadWrapper::CreateThread( + CpuWindows::Process, + reinterpret_cast<void*>(this), + kNormalPriority, + "CpuWindows"); + init_crit_ = CriticalSectionWrapper::CreateCriticalSection(); + init_cond_ = ConditionVariableWrapper::CreateConditionVariable(); + terminate_crit_ = CriticalSectionWrapper::CreateCriticalSection(); + terminate_cond_ = ConditionVariableWrapper::CreateConditionVariable(); + sleep_event = EventWrapper::Create(); + return (cpu_polling_thread != NULL) && (init_crit_ != NULL) && + (init_cond_ != NULL) && (terminate_crit_ != NULL) && + (terminate_cond_ != NULL) && (sleep_event != NULL); +} + +void CpuWindows::DeAllocateComplexDataTypes() +{ + if (sleep_event != NULL) + { + delete sleep_event; + sleep_event = NULL; + } + if (terminate_cond_ != NULL) + { + delete terminate_cond_; + terminate_cond_ = NULL; + } + if (terminate_crit_ != NULL) + { + delete terminate_crit_; + terminate_crit_ = NULL; + } + if (init_cond_ != NULL) + { + delete init_cond_; + init_cond_ = NULL; + } + if (init_crit_ != NULL) + { + delete init_crit_; + init_crit_ = NULL; + } + if (cpu_polling_thread != NULL) + { + delete cpu_polling_thread; + cpu_polling_thread = NULL; + } +} + +bool CpuWindows::StartPollingCpu() +{ + unsigned int dummy_id = 0; + if (!cpu_polling_thread->Start(dummy_id)) + { + return false; + } + { + CriticalSectionScoped cs(*init_crit_); + while(initialize_) + { + init_cond_->SleepCS(*init_crit_); + } + } + if (!has_initialized_) + { + cpu_polling_thread->Stop(); + return false; + } + return has_initialized_; +} + +bool CpuWindows::StopPollingCpu() +{ + if (!has_initialized_) + { + return false; + } + CriticalSectionScoped cs(*terminate_crit_); + terminate_ = true; + sleep_event->Set(); + while (!has_terminated_) + { + terminate_cond_->SleepCS(*terminate_crit_); + } + cpu_polling_thread->Stop(); + delete cpu_polling_thread; + cpu_polling_thread = NULL; + return true; +} + +bool CpuWindows::Process(void* thread_object) +{ + return reinterpret_cast<CpuWindows*>(thread_object)->ProcessImpl(); +} + +bool CpuWindows::ProcessImpl() +{ + { + CriticalSectionScoped cs(*terminate_crit_); + if (terminate_) + { + const bool success = Terminate(); + assert(success); + terminate_cond_->WakeAll(); + return false; + } + } + // Initialize on first iteration + if (initialize_) + { + CriticalSectionScoped cs(*init_crit_); + initialize_ = false; + const bool success = Initialize(); + init_cond_->WakeAll(); + if (!success || !has_initialized_) + { + has_initialized_ = false; + terminate_ = true; + return false; + } + } + // Approximately one seconds sleep for each CPU measurement. Precision is + // not important. 1 second refresh rate is also used by Performance Monitor + // (perfmon). + if(kEventTimeout != sleep_event->Wait(1000)) + { + // Terminating. No need to update CPU usage. + assert(terminate_); + return true; + } + + // UpdateCpuUsage() returns false if a single (or more) CPU read(s) failed. + // Not a major problem if it happens but make sure it doesnt trigger in + // debug. + const bool success = UpdateCpuUsage(); + assert(success); + return true; +} + +bool CpuWindows::CreateWmiConnection() +{ + IWbemLocator* service_locator = NULL; + HRESULT hr = CoCreateInstance(CLSID_WbemLocator, NULL, + CLSCTX_INPROC_SERVER, IID_IWbemLocator, + reinterpret_cast<void**> (&service_locator)); + if (FAILED(hr)) + { + return false; + } + // To get the WMI service specify the WMI namespace. + BSTR wmi_namespace = SysAllocString(L"\\\\.\\root\\cimv2"); + if (wmi_namespace == NULL) + { + // This type of failure signifies running out of memory. + service_locator->Release(); + return false; + } + hr = service_locator->ConnectServer(wmi_namespace, NULL, NULL, NULL, 0L, + NULL, NULL, &wbem_service_); + SysFreeString(wmi_namespace); + service_locator->Release(); + return !FAILED(hr); +} + +// Sets up WMI refresher and enum +bool CpuWindows::CreatePerfOsRefresher() +{ + // Create refresher. + HRESULT hr = CoCreateInstance(CLSID_WbemRefresher, NULL, + CLSCTX_INPROC_SERVER, IID_IWbemRefresher, + reinterpret_cast<void**> (&wbem_refresher_)); + if (FAILED(hr)) + { + return false; + } + // Create PerfOS_Processor enum. + IWbemConfigureRefresher* wbem_refresher_config = NULL; + hr = wbem_refresher_->QueryInterface( + IID_IWbemConfigureRefresher, + reinterpret_cast<void**> (&wbem_refresher_config)); + if (FAILED(hr)) + { + return false; + } + + // Create a proxy to the IWbemServices so that a local authentication + // can be set up (this is needed to be able to successfully call + // IWbemConfigureRefresher::AddEnum). Setting authentication with + // CoInitializeSecurity is process-wide (which is too intrusive). + hr = CoCopyProxy(static_cast<IUnknown*> (wbem_service_), + reinterpret_cast<IUnknown**> (&wbem_service_proxy_)); + if(FAILED(hr)) + { + return false; + } + // Set local authentication. + // RPC_C_AUTHN_WINNT means using NTLM instead of Kerberos which is default. + hr = CoSetProxyBlanket(static_cast<IUnknown*> (wbem_service_proxy_), + RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, + RPC_C_AUTHN_LEVEL_DEFAULT, + RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); + if(FAILED(hr)) + { + return false; + } + + // Don't care about the particular id for the enum. + long enum_id = 0; + hr = wbem_refresher_config->AddEnum(wbem_service_proxy_, + L"Win32_PerfRawData_PerfOS_Processor", + 0, NULL, &wbem_enum_, &enum_id); + wbem_refresher_config->Release(); + wbem_refresher_config = NULL; + return !FAILED(hr); +} + +// Have to pull the first round of data to be able set the handles. +bool CpuWindows::CreatePerfOsCpuHandles() +{ + // Update the refresher so that there is data available in wbem_enum_. + wbem_refresher_->Refresh(0L); + + // The number of enumerators is the number of processor + 1 (the total). + // This is unknown at this point. + DWORD number_returned = 0; + HRESULT hr = wbem_enum_->GetObjects(0L, number_of_objects_, + wbem_enum_access_, &number_returned); + // number_returned indicates the number of enumerators that are needed. + if (hr == WBEM_E_BUFFER_TOO_SMALL && + number_returned > number_of_objects_) + { + // Allocate the number IWbemObjectAccess asked for by the + // GetObjects(..) function. + wbem_enum_access_ = new IWbemObjectAccess*[number_returned]; + cpu_usage_ = new WebRtc_UWord32[number_returned]; + previous_processor_timestamp_ = new unsigned __int64[number_returned]; + previous_100ns_timestamp_ = new unsigned __int64[number_returned]; + if ((wbem_enum_access_ == NULL) || (cpu_usage_ == NULL) || + (previous_processor_timestamp_ == NULL) || + (previous_100ns_timestamp_ == NULL)) + { + // Out of memory. + return false; + } + + SecureZeroMemory(wbem_enum_access_, number_returned * + sizeof(IWbemObjectAccess*)); + memset(cpu_usage_, 0, sizeof(int) * number_returned); + memset(previous_processor_timestamp_, 0, sizeof(unsigned __int64) * + number_returned); + memset(previous_100ns_timestamp_, 0, sizeof(unsigned __int64) * + number_returned); + + number_of_objects_ = number_returned; + // Read should be successfull now that memory has been allocated. + hr = wbem_enum_->GetObjects(0L, number_of_objects_, wbem_enum_access_, + &number_returned); + if (FAILED(hr)) + { + return false; + } + } + else + { + // 0 enumerators should not be enough. Something has gone wrong here. + return false; + } + + // Get the enumerator handles that are needed for calculating CPU usage. + CIMTYPE cpu_usage_type; + hr = wbem_enum_access_[0]->GetPropertyHandle(L"PercentProcessorTime", + &cpu_usage_type, + &cpu_usage_handle_); + if (FAILED(hr)) + { + return false; + } + CIMTYPE timestamp_sys_100_ns_type; + hr = wbem_enum_access_[0]->GetPropertyHandle(L"TimeStamp_Sys100NS", + &timestamp_sys_100_ns_type, + &timestamp_sys_100_ns_handle_); + return !FAILED(hr); +} + +bool CpuWindows::Initialize() +{ + if (terminate_) + { + return false; + } + // Initialize COM library. + HRESULT hr = CoInitializeEx(NULL,COINIT_MULTITHREADED); + if (FAILED(hr)) + { + return false; + } + if (FAILED(hr)) + { + return false; + } + + if (!CreateWmiConnection()) + { + return false; + } + if (!CreatePerfOsRefresher()) + { + return false; + } + if (!CreatePerfOsCpuHandles()) + { + return false; + } + has_initialized_ = true; + return true; +} + +bool CpuWindows::Terminate() +{ + if (has_terminated_) + { + return false; + } + // Reverse order of Initialize(). + // Some compilers complain about deleting NULL though it's well defined + if (previous_100ns_timestamp_ != NULL) + { + delete[] previous_100ns_timestamp_; + previous_100ns_timestamp_ = NULL; + } + if (previous_processor_timestamp_ != NULL) + { + delete[] previous_processor_timestamp_; + previous_processor_timestamp_ = NULL; + } + if (cpu_usage_ != NULL) + { + delete[] cpu_usage_; + cpu_usage_ = NULL; + } + if (wbem_enum_access_ != NULL) + { + for (DWORD i = 0; i < number_of_objects_; i++) + { + if(wbem_enum_access_[i] != NULL) + { + wbem_enum_access_[i]->Release(); + } + } + delete[] wbem_enum_access_; + wbem_enum_access_ = NULL; + } + if (wbem_enum_ != NULL) + { + wbem_enum_->Release(); + wbem_enum_ = NULL; + } + if (wbem_refresher_ != NULL) + { + wbem_refresher_->Release(); + wbem_refresher_ = NULL; + } + if (wbem_service_proxy_ != NULL) + { + wbem_service_proxy_->Release(); + wbem_service_proxy_ = NULL; + } + if (wbem_service_ != NULL) + { + wbem_service_->Release(); + wbem_service_ = NULL; + } + // CoUninitialized should be called once for every CoInitializeEx. + // Regardless if it failed or not. + CoUninitialize(); + has_terminated_ = true; + return true; +} + +bool CpuWindows::UpdateCpuUsage() +{ + wbem_refresher_->Refresh(0L); + DWORD number_returned = 0; + HRESULT hr = wbem_enum_->GetObjects(0L, number_of_objects_, + wbem_enum_access_,&number_returned); + if (FAILED(hr)) + { + // wbem_enum_access_ has already been allocated. Unless the number of + // CPUs change runtime this should not happen. + return false; + } + unsigned __int64 cpu_usage = 0; + unsigned __int64 timestamp_100ns = 0; + bool returnValue = true; + for (DWORD i = 0; i < number_returned; i++) + { + hr = wbem_enum_access_[i]->ReadQWORD(cpu_usage_handle_,&cpu_usage); + if (FAILED(hr)) + { + returnValue = false; + } + hr = wbem_enum_access_[i]->ReadQWORD(timestamp_sys_100_ns_handle_, + &timestamp_100ns); + if (FAILED(hr)) + { + returnValue = false; + } + wbem_enum_access_[i]->Release(); + wbem_enum_access_[i] = NULL; + + const bool wrapparound = + (previous_processor_timestamp_[i] > cpu_usage) || + (previous_100ns_timestamp_[i] > timestamp_100ns); + const bool first_time = (previous_processor_timestamp_[i] == 0) || + (previous_100ns_timestamp_[i] == 0); + if (wrapparound || first_time) + { + previous_processor_timestamp_[i] = cpu_usage; + previous_100ns_timestamp_[i] = timestamp_100ns; + continue; + } + const unsigned __int64 processor_timestamp_delta = + cpu_usage - previous_processor_timestamp_[i]; + const unsigned __int64 timestamp_100ns_delta = + timestamp_100ns - previous_100ns_timestamp_[i]; + + if (processor_timestamp_delta >= timestamp_100ns_delta) + { + cpu_usage_[i] = 0; + } else { + // Quotient must be float since the division is guaranteed to yield + // a value between 0 and 1 which is 0 in integer division. + const float delta_quotient = + static_cast<float>(processor_timestamp_delta) / + static_cast<float>(timestamp_100ns_delta); + cpu_usage_[i] = 100 - static_cast<WebRtc_UWord32>(delta_quotient * + 100); + } + previous_processor_timestamp_[i] = cpu_usage; + previous_100ns_timestamp_[i] = timestamp_100ns; + } + return returnValue; +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/cpu_windows.h b/src/libs/webrtc/system_wrappers/cpu_windows.h new file mode 100644 index 00000000..34f6181f --- /dev/null +++ b/src/libs/webrtc/system_wrappers/cpu_windows.h @@ -0,0 +1,103 @@ +// This file contains a Windows implementation of CpuWrapper. +// Note: Windows XP, Windows Server 2003 are the minimum requirements. +// The requirements are due to the implementation being based on +// WMI. +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_WINDOWS_NO_CPOL_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_WINDOWS_NO_CPOL_H_ + +#include "cpu_wrapper.h" + +#include <Wbemidl.h> + +namespace webrtc { +class ConditionVariableWrapper; +class CriticalSectionWrapper; +class EventWrapper; +class ThreadWrapper; + +class CpuWindows : public CpuWrapper +{ +public: + virtual WebRtc_Word32 CpuUsage(); + virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* /*pProcessName*/, + WebRtc_UWord32 /*length*/) {return -1;} + virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 /*dwProcessID*/) {return -1;} + + virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& num_cores, + WebRtc_UWord32*& cpu_usage); + + virtual void Reset() {} + virtual void Stop() {} + + CpuWindows(); + virtual ~CpuWindows(); +private: + bool AllocateComplexDataTypes(); + void DeAllocateComplexDataTypes(); + + bool StartPollingCpu(); + bool StopPollingCpu(); + + static bool Process(void* thread_object); + bool ProcessImpl(); + + bool CreateWmiConnection(); + bool CreatePerfOsRefresher(); + bool CreatePerfOsCpuHandles(); + bool Initialize(); + bool Terminate(); + + bool UpdateCpuUsage(); + + ThreadWrapper* cpu_polling_thread; + + bool initialize_; + bool has_initialized_; + CriticalSectionWrapper* init_crit_; + ConditionVariableWrapper* init_cond_; + + bool terminate_; + bool has_terminated_; + CriticalSectionWrapper* terminate_crit_; + ConditionVariableWrapper* terminate_cond_; + + // For sleep with wake-up functionality. + EventWrapper* sleep_event; + + // Will be an array. Just care about CPU 0 for now. + WebRtc_UWord32* cpu_usage_; + + // One IWbemObjectAccess for each processor and one for the total. + // 0-n-1 is the individual processors. + // n is the total. + IWbemObjectAccess** wbem_enum_access_; + DWORD number_of_objects_; + + // Cpu timestamp + long cpu_usage_handle_; + unsigned __int64* previous_processor_timestamp_; + + // Timestamp + long timestamp_sys_100_ns_handle_; + unsigned __int64* previous_100ns_timestamp_; + + IWbemServices* wbem_service_; + IWbemServices* wbem_service_proxy_; + + IWbemRefresher* wbem_refresher_; + + IWbemHiPerfEnum* wbem_enum_; + +}; +} // namespace webrtc +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_WINDOWS_NO_CPOL_H_ diff --git a/src/libs/webrtc/system_wrappers/cpu_wrapper.h b/src/libs/webrtc/system_wrappers/cpu_wrapper.h new file mode 100644 index 00000000..b72c20cd --- /dev/null +++ b/src/libs/webrtc/system_wrappers/cpu_wrapper.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_WRAPPER_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_WRAPPER_H_ + +#include "typedefs.h" + +namespace webrtc { +class CpuWrapper +{ +public: + static WebRtc_UWord32 DetectNumberOfCores(); + + static CpuWrapper* CreateCpu(); + virtual ~CpuWrapper() {} + + // Returns the average CPU usage for all processors. The CPU usage can be + // between and including 0 to 100 (%) + virtual WebRtc_Word32 CpuUsage() = 0; + virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* processName, + WebRtc_UWord32 length) = 0; + virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 dwProcessID) = 0; + + // The CPU usage per core is returned in cpu_usage. The CPU can be between + // and including 0 to 100 (%) + // Note that the pointer passed as cpu_usage is redirected to a local member + // of the CPU wrapper. + // numCores is the number of cores in the cpu_usage array. + virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& numCores, + WebRtc_UWord32*& cpu_usage) = 0; + + virtual void Reset() = 0; + virtual void Stop() = 0; + +protected: + CpuWrapper() {} + +private: + static WebRtc_UWord32 _numberOfCores; + +}; +} // namespace webrtc +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_WRAPPER_H_ diff --git a/src/libs/webrtc/system_wrappers/critical_section.cc b/src/libs/webrtc/system_wrappers/critical_section.cc new file mode 100644 index 00000000..213c3528 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/critical_section.cc @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#if defined(_WIN32) + #include <windows.h> + #include "critical_section_windows.h" +#else + #include "critical_section_linux.h" +#endif + +namespace webrtc { +CriticalSectionWrapper* CriticalSectionWrapper::CreateCriticalSection() +{ +#ifdef _WIN32 + return new CriticalSectionWindows(); +#else + return new CriticalSectionLinux(); +#endif +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/critical_section_linux.cc b/src/libs/webrtc/system_wrappers/critical_section_linux.cc new file mode 100644 index 00000000..35e81aea --- /dev/null +++ b/src/libs/webrtc/system_wrappers/critical_section_linux.cc @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "critical_section_linux.h" + +namespace webrtc { +CriticalSectionLinux::CriticalSectionLinux() +{ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&_mutex, &attr); +} + +CriticalSectionLinux::~CriticalSectionLinux() +{ + pthread_mutex_destroy(&_mutex); +} + +void +CriticalSectionLinux::Enter() +{ + pthread_mutex_lock(&_mutex); +} + +void +CriticalSectionLinux::Leave() +{ + pthread_mutex_unlock(&_mutex); +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/critical_section_linux.h b/src/libs/webrtc/system_wrappers/critical_section_linux.h new file mode 100644 index 00000000..5ada1cb4 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/critical_section_linux.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_LINUX_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_LINUX_H_ + +#include "critical_section_wrapper.h" + +#include <pthread.h> + +namespace webrtc { +class CriticalSectionLinux : public CriticalSectionWrapper +{ +public: + CriticalSectionLinux(); + + virtual ~CriticalSectionLinux(); + + virtual void Enter(); + virtual void Leave(); + +private: + pthread_mutex_t _mutex; + friend class ConditionVariableLinux; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_LINUX_H_ diff --git a/src/libs/webrtc/system_wrappers/critical_section_windows.cc b/src/libs/webrtc/system_wrappers/critical_section_windows.cc new file mode 100644 index 00000000..1ca57517 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/critical_section_windows.cc @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "critical_section_windows.h" + +namespace webrtc { +CriticalSectionWindows::CriticalSectionWindows() +{ + InitializeCriticalSection(&crit); +} + +CriticalSectionWindows::~CriticalSectionWindows() +{ + DeleteCriticalSection(&crit); +} + +void +CriticalSectionWindows::Enter() +{ + EnterCriticalSection(&crit); +} + +void +CriticalSectionWindows::Leave() +{ + LeaveCriticalSection(&crit); +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/critical_section_windows.h b/src/libs/webrtc/system_wrappers/critical_section_windows.h new file mode 100644 index 00000000..9556fa95 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/critical_section_windows.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_ + +#include "typedefs.h" +#include "critical_section_wrapper.h" +#include <windows.h> + +namespace webrtc { +class CriticalSectionWindows : public CriticalSectionWrapper +{ +public: + CriticalSectionWindows(); + + virtual ~CriticalSectionWindows(); + + virtual void Enter(); + virtual void Leave(); + +private: + CRITICAL_SECTION crit; + + friend class ConditionVariableWindows; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_ diff --git a/src/libs/webrtc/system_wrappers/critical_section_wrapper.h b/src/libs/webrtc/system_wrappers/critical_section_wrapper.h new file mode 100644 index 00000000..ad31497e --- /dev/null +++ b/src/libs/webrtc/system_wrappers/critical_section_wrapper.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_ + +// If the critical section is heavily contended it may be beneficial to use +// read/write locks instead. + +#include "common_types.h" + +namespace webrtc { +class CriticalSectionWrapper +{ +public: + // Factory method, constructor disabled + static CriticalSectionWrapper* CreateCriticalSection(); + + virtual ~CriticalSectionWrapper() {} + + // Tries to grab lock, beginning of a critical section. Will wait for the + // lock to become available if the grab failed. + virtual void Enter() = 0; + + // Returns a grabbed lock, end of critical section. + virtual void Leave() = 0; +}; + +// RAII extension of the critical section. Prevents Enter/Leave missmatches and +// provides more compact critical section syntax. +class CriticalSectionScoped +{ +public: + CriticalSectionScoped(CriticalSectionWrapper& critsec) + : + _ptrCritSec(&critsec) + { + _ptrCritSec->Enter(); + } + + ~CriticalSectionScoped() + { + if (_ptrCritSec) + { + Leave(); + } + } + +private: + void Leave() + { + _ptrCritSec->Leave(); + _ptrCritSec = 0; + } + + CriticalSectionWrapper* _ptrCritSec; +}; +} // namespace webrtc +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_ diff --git a/src/libs/webrtc/system_wrappers/event.cc b/src/libs/webrtc/system_wrappers/event.cc new file mode 100644 index 00000000..384b9614 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/event.cc @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "event_wrapper.h" + +#if defined(_WIN32) + #include <windows.h> + #include "event_windows.h" +#else + #include <pthread.h> + #include "event_linux.h" +#endif + +namespace webrtc { +EventWrapper* EventWrapper::Create() +{ +#if defined(_WIN32) + return new EventWindows(); +#else + return EventLinux::Create(); +#endif +} + +int EventWrapper::KeyPressed() +{ +#if defined(_WIN32) + int keyDown = 0; + for(int key = 0x20; key < 0x90; key++) + { + short res = GetAsyncKeyState(key); + keyDown |= res%2; // Get the LSB + } + if(keyDown) + { + return 1; + } + else + { + return 0; + } +#else + return -1; +#endif +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/event_linux.cc b/src/libs/webrtc/system_wrappers/event_linux.cc new file mode 100644 index 00000000..81c8b0f7 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/event_linux.cc @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "event_linux.h" + +#include <errno.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> +#include <sys/time.h> +#include <unistd.h> + +namespace webrtc { +const long int E6 = 1000000; +const long int E9 = 1000 * E6; + +EventWrapper* EventLinux::Create() +{ + EventLinux* ptr = new EventLinux; + if (!ptr) + { + return NULL; + } + + const int error = ptr->Construct(); + if (error) + { + delete ptr; + return NULL; + } + return ptr; +} + + +EventLinux::EventLinux() + : _timerThread(0), + _timerEvent(0), + _periodic(false), + _time(0), + _count(0), + _state(kDown) +{ +} + +int EventLinux::Construct() +{ + // Set start time to zero + memset(&_tCreate, 0, sizeof(_tCreate)); + + int result = pthread_mutex_init(&mutex, 0); + if (result != 0) + { + return -1; + } +#ifdef WEBRTC_CLOCK_TYPE_REALTIME + result = pthread_cond_init(&cond, 0); + if (result != 0) + { + return -1; + } +#else + pthread_condattr_t condAttr; + result = pthread_condattr_init(&condAttr); + if (result != 0) + { + return -1; + } +#ifndef WEBRTC_MAC + result = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC); + if (result != 0) + { + return -1; + } +#endif + result = pthread_cond_init(&cond, &condAttr); + if (result != 0) + { + return -1; + } + result = pthread_condattr_destroy(&condAttr); + if (result != 0) + { + return -1; + } +#endif + return 0; +} + +EventLinux::~EventLinux() +{ + StopTimer(); + pthread_cond_destroy(&cond); + pthread_mutex_destroy(&mutex); +} + +bool EventLinux::Reset() +{ + if (0 != pthread_mutex_lock(&mutex)) + { + return false; + } + _state = kDown; + pthread_mutex_unlock(&mutex); + return true; +} + +bool EventLinux::Set() +{ + if (0 != pthread_mutex_lock(&mutex)) + { + return false; + } + _state = kUp; + // Release all waiting threads + pthread_cond_broadcast(&cond); + pthread_mutex_unlock(&mutex); + return true; +} + +EventTypeWrapper EventLinux::Wait(unsigned long timeout) +{ + int retVal = 0; + if (0 != pthread_mutex_lock(&mutex)) + { + return kEventError; + } + + if (kDown == _state) + { + if (WEBRTC_EVENT_INFINITE != timeout) + { + timespec tEnd; +#ifndef WEBRTC_MAC +#ifdef WEBRTC_CLOCK_TYPE_REALTIME + clock_gettime(CLOCK_REALTIME, &tEnd); +#else + clock_gettime(CLOCK_MONOTONIC, &tEnd); +#endif +#else + timeval tVal; + struct timezone tZone; + tZone.tz_minuteswest = 0; + tZone.tz_dsttime = 0; + gettimeofday(&tVal,&tZone); + TIMEVAL_TO_TIMESPEC(&tVal,&tEnd); +#endif + tEnd.tv_sec += timeout / 1000; + tEnd.tv_nsec += (timeout - (timeout / 1000) * 1000) * E6; + + if (tEnd.tv_nsec >= E9) + { + tEnd.tv_sec++; + tEnd.tv_nsec -= E9; + } + retVal = pthread_cond_timedwait(&cond, &mutex, &tEnd); + } else { + retVal = pthread_cond_wait(&cond, &mutex); + } + } + + _state = kDown; + pthread_mutex_unlock(&mutex); + + switch(retVal) + { + case 0: + return kEventSignaled; + case ETIMEDOUT: + return kEventTimeout; + default: + return kEventError; + } +} + +EventTypeWrapper EventLinux::Wait(timespec& tPulse) +{ + int retVal = 0; + if (0 != pthread_mutex_lock(&mutex)) + { + return kEventError; + } + + if (kUp != _state) + { + retVal = pthread_cond_timedwait(&cond, &mutex, &tPulse); + } + _state = kDown; + + pthread_mutex_unlock(&mutex); + + switch(retVal) + { + case 0: + return kEventSignaled; + case ETIMEDOUT: + return kEventTimeout; + default: + return kEventError; + } +} + +bool EventLinux::StartTimer(bool periodic, unsigned long time) +{ + if (_timerThread) + { + if(_periodic) + { + // Timer already started. + return false; + } else { + // New one shot timer + _time = time; + _tCreate.tv_sec = 0; + _timerEvent->Set(); + return true; + } + } + + // Start the timer thread + _timerEvent = static_cast<EventLinux*>(EventWrapper::Create()); + const char* threadName = "WebRtc_event_timer_thread"; + _timerThread = ThreadWrapper::CreateThread(Run, this, kRealtimePriority, + threadName); + _periodic = periodic; + _time = time; + unsigned int id = 0; + if (_timerThread->Start(id)) + { + return true; + } + return false; +} + +bool EventLinux::Run(ThreadObj obj) +{ + return static_cast<EventLinux*>(obj)->Process(); +} + +bool EventLinux::Process() +{ + if (_tCreate.tv_sec == 0) + { +#ifndef WEBRTC_MAC +#ifdef WEBRTC_CLOCK_TYPE_REALTIME + clock_gettime(CLOCK_REALTIME, &_tCreate); +#else + clock_gettime(CLOCK_MONOTONIC, &_tCreate); +#endif +#else + timeval tVal; + struct timezone tZone; + tZone.tz_minuteswest = 0; + tZone.tz_dsttime = 0; + gettimeofday(&tVal,&tZone); + TIMEVAL_TO_TIMESPEC(&tVal,&_tCreate); +#endif + _count=0; + } + + timespec tEnd; + unsigned long long time = _time * ++_count; + tEnd.tv_sec = _tCreate.tv_sec + time/1000; + tEnd.tv_nsec = _tCreate.tv_nsec + (time - (time/1000)*1000)*E6; + + if ( tEnd.tv_nsec >= E9 ) + { + tEnd.tv_sec++; + tEnd.tv_nsec -= E9; + } + + switch(_timerEvent->Wait(tEnd)) + { + case kEventSignaled: + return true; + case kEventError: + return false; + case kEventTimeout: + break; + } + if(_periodic || _count==1) + { + Set(); + } + return true; +} + +bool EventLinux::StopTimer() +{ + if(_timerThread) + { + _timerThread->SetNotAlive(); + } + if (_timerEvent) + { + _timerEvent->Set(); + } + if (_timerThread) + { + if(!_timerThread->Stop()) + { + return false; + } + + delete _timerThread; + _timerThread = 0; + } + if (_timerEvent) + { + delete _timerEvent; + _timerEvent = 0; + } + + // Set time to zero to force new reference time for the timer. + memset(&_tCreate, 0, sizeof(_tCreate)); + _count=0; + return true; +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/event_linux.h b/src/libs/webrtc/system_wrappers/event_linux.h new file mode 100644 index 00000000..17d193f2 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/event_linux.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_LINUX_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_LINUX_H_ + +#include "event_wrapper.h" + +#include <pthread.h> +#include <time.h> + +#include "thread_wrapper.h" + +namespace webrtc { +enum State +{ + kUp = 1, + kDown = 2 +}; + +class EventLinux : public EventWrapper +{ +public: + static EventWrapper* Create(); + + virtual ~EventLinux(); + + virtual EventTypeWrapper Wait(unsigned long maxTime); + virtual bool Set(); + virtual bool Reset(); + + virtual bool StartTimer(bool periodic, unsigned long time); + virtual bool StopTimer(); + +private: + EventLinux(); + int Construct(); + + static bool Run(ThreadObj obj); + bool Process(); + EventTypeWrapper Wait(timespec& tPulse); + + +private: + pthread_cond_t cond; + pthread_mutex_t mutex; + + ThreadWrapper* _timerThread; + EventLinux* _timerEvent; + timespec _tCreate; + + bool _periodic; + unsigned long _time; // In ms + unsigned long _count; + State _state; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_LINUX_H_ diff --git a/src/libs/webrtc/system_wrappers/event_windows.cc b/src/libs/webrtc/system_wrappers/event_windows.cc new file mode 100644 index 00000000..a0d55927 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/event_windows.cc @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "event_windows.h" + +#include "Mmsystem.h" + +namespace webrtc { +EventWindows::EventWindows() + : _event(::CreateEvent(NULL /* security attributes */, + FALSE /* manual reset */, + FALSE /* initial state */, + NULL /* name of event */)), + _timerID(NULL) +{ +} + +EventWindows::~EventWindows() +{ + CloseHandle(_event); +} + +bool EventWindows::Set() +{ + // Note: setting an event that is already set has no effect. + return SetEvent(_event); +} + +bool EventWindows::Reset() +{ + return ResetEvent(_event); +} + +EventTypeWrapper EventWindows::Wait(unsigned long maxTime) +{ + unsigned long res = WaitForSingleObject(_event, maxTime); + switch(res) + { + case WAIT_OBJECT_0: + return kEventSignaled; + case WAIT_TIMEOUT: + return kEventTimeout; + default: + return kEventError; + } +} + +bool EventWindows::StartTimer(bool periodic, unsigned long time) +{ + if (_timerID != NULL) + { + timeKillEvent(_timerID); + _timerID=NULL; + } + if (periodic) + { + _timerID=timeSetEvent(time, 0,(LPTIMECALLBACK)HANDLE(_event),0, + TIME_PERIODIC|TIME_CALLBACK_EVENT_PULSE); + } else { + _timerID=timeSetEvent(time, 0,(LPTIMECALLBACK)HANDLE(_event),0, + TIME_ONESHOT|TIME_CALLBACK_EVENT_SET); + } + + if (_timerID == NULL) + { + return false; + } + return true; +} + +bool EventWindows::StopTimer() +{ + timeKillEvent(_timerID); + _timerID = NULL; + return true; +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/event_windows.h b/src/libs/webrtc/system_wrappers/event_windows.h new file mode 100644 index 00000000..8ca1360c --- /dev/null +++ b/src/libs/webrtc/system_wrappers/event_windows.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WINDOWS_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WINDOWS_H_ + +#include <windows.h> + +#include "event_wrapper.h" + +#include "typedefs.h" + +namespace webrtc { +class EventWindows : public EventWrapper +{ +public: + EventWindows(); + virtual ~EventWindows(); + + virtual EventTypeWrapper Wait(unsigned long maxTime); + virtual bool Set(); + virtual bool Reset(); + + virtual bool StartTimer(bool periodic, unsigned long time); + virtual bool StopTimer(); + +private: + HANDLE _event; + WebRtc_UWord32 _timerID; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WINDOWS_H_ diff --git a/src/libs/webrtc/system_wrappers/event_wrapper.h b/src/libs/webrtc/system_wrappers/event_wrapper.h new file mode 100644 index 00000000..0c9a9081 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/event_wrapper.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_ + +namespace webrtc { +enum EventTypeWrapper +{ + kEventSignaled = 1, + kEventError = 2, + kEventTimeout = 3 +}; + +#define WEBRTC_EVENT_10_SEC 10000 +#define WEBRTC_EVENT_INFINITE 0xffffffff + +class EventWrapper +{ +public: + // Factory method. Constructor disabled. + static EventWrapper* Create(); + virtual ~EventWrapper() {} + + // Releases threads who are calling Wait() and has started waiting. Please + // note that a thread calling Wait() will not start waiting immediately. + // assumptions to the contrary is a very common source of issues in + // multithreaded programming. + // Set is sticky in the sense that it will release at least one thread + // either immediately or some time in the future. + virtual bool Set() = 0; + + // Prevents future Wait() calls from finishing without a new Set() call. + virtual bool Reset() = 0; + + // Puts the calling thread into a wait state. The thread may be released + // by a Set() call depending on if other threads are waiting and if so on + // timing. The thread that was released will call Reset() before leaving + // preventing more threads from being released. If multiple threads + // are waiting for the same Set(), only one (random) thread is guaranteed to + // be released. It is possible that multiple (random) threads are released + // Depending on timing. + virtual EventTypeWrapper Wait(unsigned long maxTime) = 0; + + // Starts a timer that will call a non-sticky version of Set() either once + // or periodically. If the timer is periodic it ensures that there is no + // drift over time relative to the system clock. + virtual bool StartTimer(bool periodic, unsigned long time) = 0; + + virtual bool StopTimer() = 0; + + // Only implemented on Windows + // Returns 1 if a key has been pressed since last call to this function. + // -1 indicates failure + // 0 indicates no key has been pressed since last call + // TODO(hellner) this function does not seem to belong here + static int KeyPressed(); +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_ diff --git a/src/libs/webrtc/system_wrappers/file_impl.cc b/src/libs/webrtc/system_wrappers/file_impl.cc new file mode 100644 index 00000000..6046c2c7 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/file_impl.cc @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "file_impl.h" + +#include <cassert> + +#ifdef _WIN32 + #include <Windows.h> +#else + #include <stdarg.h> + #include <string.h> +#endif + +namespace webrtc { +FileWrapper* FileWrapper::Create() +{ + return new FileWrapperImpl(); +} + +FileWrapperImpl::FileWrapperImpl() + : _id(NULL), + _open(false), + _looping(false), + _readOnly(false), + _text(false), + _maxSizeInBytes(-1), + _sizeInBytes(0) +{ + memset(_fileNameUTF8, 0, kMaxFileNameSize); +} + +FileWrapperImpl::~FileWrapperImpl() +{ + if (_id != NULL) + { + fclose(_id); + } +} + +WebRtc_Word32 FileWrapperImpl::CloseFile() +{ + if (_id != NULL) + { + fclose(_id); + _id = NULL; + } + memset(_fileNameUTF8, 0, kMaxFileNameSize); + _open = false; + return 0; +} + +int FileWrapperImpl::Rewind() +{ + if(_looping || !_readOnly) + { + if (_id != NULL) + { + _sizeInBytes = 0; + return fseek(_id, 0, SEEK_SET); + } + } + return -1; +} + +WebRtc_Word32 FileWrapperImpl::SetMaxFileSize(WebRtc_Word32 bytes) +{ + _maxSizeInBytes = bytes; + return 0; +} + +WebRtc_Word32 FileWrapperImpl::Flush() +{ + if (_id != NULL) + { + return fflush(_id); + } + return -1; +} + +WebRtc_Word32 FileWrapperImpl::FileName(WebRtc_Word8* fileNameUTF8, + WebRtc_UWord32 size) const +{ + WebRtc_Word32 len = static_cast<WebRtc_Word32>(strlen(_fileNameUTF8)); + if(len > kMaxFileNameSize) + { + assert(false); + return -1; + } + if(len < 1) + { + return -1; + } + // Make sure to NULL terminate + if(size < (WebRtc_UWord32)len) + { + len = size - 1; + } + memcpy(fileNameUTF8, _fileNameUTF8, len); + fileNameUTF8[len] = 0; + return 0; +} + +bool +FileWrapperImpl::Open() const +{ + return _open; +} + +WebRtc_Word32 FileWrapperImpl::OpenFile(const WebRtc_Word8 *fileNameUTF8, + const bool readOnly, const bool loop, + const bool text) +{ + WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8); + if (length > kMaxFileNameSize) + { + return -1; + } + + _readOnly = readOnly; + + FILE *tmpId = NULL; +#if defined _WIN32 + wchar_t wideFileName[kMaxFileNameSize]; + wideFileName[0] = 0; + + MultiByteToWideChar(CP_UTF8, + 0 /*UTF8 flag*/, + fileNameUTF8, + -1 /*Null terminated string*/, + wideFileName, + kMaxFileNameSize); + if(text) + { + if(readOnly) + { + tmpId = _wfopen(wideFileName, L"rt"); + } else { + tmpId = _wfopen(wideFileName, L"wt"); + } + } else { + if(readOnly) + { + tmpId = _wfopen(wideFileName, L"rb"); + } else { + tmpId = _wfopen(wideFileName, L"wb"); + } + } +#else + if(text) + { + if(readOnly) + { + tmpId = fopen(fileNameUTF8, "rt"); + } else { + tmpId = fopen(fileNameUTF8, "wt"); + } + } else { + if(readOnly) + { + tmpId = fopen(fileNameUTF8, "rb"); + } else { + tmpId = fopen(fileNameUTF8, "wb"); + } + } +#endif + + if (tmpId != NULL) + { + // + 1 comes fro copying the NULL termination charachter too + memcpy(_fileNameUTF8, fileNameUTF8, length + 1); + if (_id != NULL) + { + fclose(_id); + } + _id = tmpId; + _looping = loop; + _open = true; + return 0; + } + return -1; +} + +int FileWrapperImpl::Read(void *buf, int len) +{ + if(len < 0) + { + return 0; + } + if (_id != NULL) + { + WebRtc_Word32 res = static_cast<WebRtc_Word32>(fread(buf, 1, len, _id)); + if (res != len) + { + if(!_looping) + { + CloseFile(); + } + } + return res; + } + return -1; +} + +WebRtc_Word32 FileWrapperImpl::WriteText(const WebRtc_Word8* text, ...) +{ + assert(!_readOnly); + assert(!_text); + + if (_id == NULL) + { + return -1; + } + + char tempBuff[kFileMaxTextMessageSize]; + if (text) + { + va_list args; + va_start(args, text); +#ifdef _WIN32 + _vsnprintf(tempBuff, kFileMaxTextMessageSize-1, text, args); +#else + vsnprintf(tempBuff, kFileMaxTextMessageSize-1, text, args); +#endif + va_end(args); + WebRtc_Word32 nBytes; + nBytes = fprintf(_id, "%s", tempBuff); + if (nBytes > 0) + { + return 0; + } + CloseFile(); + } + return -1; +} + +bool FileWrapperImpl::Write(const void* buf, int len) +{ + assert(!_readOnly); + if (_id != NULL) + { + // Check if it's time to stop writing. + if ((_maxSizeInBytes != -1) && + _sizeInBytes + len > (WebRtc_UWord32)_maxSizeInBytes) + { + Flush(); + return false; + } + + size_t nBytes = fwrite((WebRtc_UWord8*)buf, 1, len, _id); + if (nBytes > 0) + { + _sizeInBytes += static_cast<WebRtc_Word32>(nBytes); + return true; + } + CloseFile(); + } + return false; +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/file_impl.h b/src/libs/webrtc/system_wrappers/file_impl.h new file mode 100644 index 00000000..cf6b7347 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/file_impl.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_FILE_IMPL_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_FILE_IMPL_H_ + +#include "file_wrapper.h" + +#include <stdio.h> + +namespace webrtc { +class FileWrapperImpl : public FileWrapper +{ +public: + FileWrapperImpl(); + virtual ~FileWrapperImpl(); + + virtual WebRtc_Word32 FileName(WebRtc_Word8* fileNameUTF8, + WebRtc_UWord32 size) const; + + virtual bool Open() const; + + virtual WebRtc_Word32 OpenFile(const WebRtc_Word8* fileNameUTF8, + const bool readOnly, + const bool loop = false, + const bool text = false); + + virtual WebRtc_Word32 CloseFile(); + virtual WebRtc_Word32 SetMaxFileSize(WebRtc_Word32 bytes); + virtual WebRtc_Word32 Flush(); + + virtual int Read(void* buf, int len); + virtual bool Write(const void *buf, int len); + virtual int Rewind(); + + virtual WebRtc_Word32 WriteText(const WebRtc_Word8* text, ...); + +private: + FILE* _id; + bool _open; + bool _looping; + bool _readOnly; + bool _text; + WebRtc_Word32 _maxSizeInBytes; // -1 indicates file size limitation is off + WebRtc_UWord32 _sizeInBytes; + WebRtc_Word8 _fileNameUTF8[kMaxFileNameSize]; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_FILE_IMPL_H_ diff --git a/src/libs/webrtc/system_wrappers/file_wrapper.h b/src/libs/webrtc/system_wrappers/file_wrapper.h new file mode 100644 index 00000000..8f0cd8c2 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/file_wrapper.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_FILE_WRAPPER_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_FILE_WRAPPER_H_ + +#include "common_types.h" +#include "typedefs.h" + +// Implementation of an InStream and OutStream that can read (exclusive) or +// write from/to a file. + +namespace webrtc { +class FileWrapper : public InStream, public OutStream +{ +public: + enum { kMaxFileNameSize = 1024}; + enum { kFileMaxTextMessageSize = 1024}; + + // Factory method. Constructor disabled. + static FileWrapper* Create(); + + // Returns true if a file has been opened. + virtual bool Open() const = 0; + + // Opens a file in read or write mode, decided by the readOnly parameter. + virtual WebRtc_Word32 OpenFile(const WebRtc_Word8* fileNameUTF8, + const bool readOnly, + const bool loop = false, + const bool text = false) = 0; + + virtual WebRtc_Word32 CloseFile() = 0; + + // Limits the file size. + virtual WebRtc_Word32 SetMaxFileSize(WebRtc_Word32 bytes) = 0; + + // Flush any pending writes. + virtual WebRtc_Word32 Flush() = 0; + + // Returns the opened file's name in fileNameUTF8. size is the allocated + // size of fileNameUTF8. The name will be truncated if the size of + // fileNameUTF8 is to small. + virtual WebRtc_Word32 FileName(WebRtc_Word8* fileNameUTF8, + WebRtc_UWord32 size) const = 0; + + // Write text to the opened file. The written text can contain plain text + // and text with type specifiers in the same way as sprintf works. + virtual WebRtc_Word32 WriteText(const WebRtc_Word8* text, ...) = 0; + + // Reads len number of bytes from buf to file. + virtual int Read(void* buf, int len) = 0; + + // Writes len number of bytes to buf from file. Please note that the actual + // writing to file may happen some time later. Call flush to force a write + // to take affect + virtual bool Write(const void *buf,int len) = 0; + + // Rewinds the file to the start. Only available when OpenFile() has been + // called with loop argument set to true. Or readOnly argument has been set + // to false. + virtual int Rewind() = 0; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_FILE_WRAPPER_H_ diff --git a/src/libs/webrtc/system_wrappers/fix_interlocked_exchange_pointer_windows.h b/src/libs/webrtc/system_wrappers/fix_interlocked_exchange_pointer_windows.h new file mode 100644 index 00000000..d85c7247 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/fix_interlocked_exchange_pointer_windows.h @@ -0,0 +1,35 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file under third_party_mods/chromium directory of +// source tree or at +// http://src.chromium.org/viewvc/chrome/trunk/src/LICENSE + +// Various inline functions and macros to fix compilation of 32 bit target +// on MSVC with /Wp64 flag enabled. + +// The original code can be found here: +// http://src.chromium.org/svn/trunk/src/base/fix_wp64.h + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_FIX_INTERLOCKED_EXCHANGE_POINTER_WINDOWS_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_FIX_INTERLOCKED_EXCHANGE_POINTER_WINDOWS_H_ + +#include <windows.h> + +// Platform SDK fixes when building with /Wp64 for a 32 bits target. +#if !defined(_WIN64) && defined(_Wp64) + +#ifdef InterlockedExchangePointer +#undef InterlockedExchangePointer +// The problem is that the macro provided for InterlockedExchangePointer() is +// doing a (LONG) C-style cast that triggers invariably the warning C4312 when +// building on 32 bits. +inline void* InterlockedExchangePointer(void* volatile* target, void* value) { + return reinterpret_cast<void*>(static_cast<LONG_PTR>(InterlockedExchange( + reinterpret_cast<volatile LONG*>(target), + static_cast<LONG>(reinterpret_cast<LONG_PTR>(value))))); +} +#endif // #ifdef InterlockedExchangePointer + +#endif // #if !defined(_WIN64) && defined(_Wp64) + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_FIX_INTERLOCKED_EXCHANGE_POINTER_WINDOWS_H_ diff --git a/src/libs/webrtc/system_wrappers/list_no_stl.cc b/src/libs/webrtc/system_wrappers/list_no_stl.cc new file mode 100644 index 00000000..d45f27b3 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/list_no_stl.cc @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "list_wrapper.h" + +#include "critical_section_wrapper.h" +#include "trace.h" + +namespace webrtc { +ListItem::ListItem(const void* item) + : next_(0), + prev_(0), + item_ptr_(item), + item_(0) +{ +} + +ListItem::ListItem(const unsigned int item) + : next_(0), + prev_(0), + item_ptr_(0), + item_(item) +{ +} + +ListItem::~ListItem() +{ +} + +void* ListItem::GetItem() const +{ + return const_cast<void*>(item_ptr_); +} + +unsigned int ListItem::GetUnsignedItem() const +{ + return item_; +} + +ListWrapper::ListWrapper() + : critical_section_(CriticalSectionWrapper::CreateCriticalSection()), + first_(0), + last_(0), + size_(0) +{ +} + +ListWrapper::~ListWrapper() +{ + if (!Empty()) + { + // TODO (hellner) I'm not sure this loggin is useful. + WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, + "Potential memory leak in ListWrapper"); + // Remove all remaining list items. + while (Erase(First()) == 0) + {} + } + delete critical_section_; +} + +bool ListWrapper::Empty() const +{ + return !first_ && !last_; +} + +unsigned int ListWrapper::GetSize() const +{ + return size_; +} + +int ListWrapper::PushBack(const void* ptr) +{ + ListItem* item = new ListItem(ptr); + CriticalSectionScoped lock(*critical_section_); + PushBackImpl(item); + return 0; +} + +int ListWrapper::PushBack(const unsigned int item_id) +{ + ListItem* item = new ListItem(item_id); + CriticalSectionScoped lock(*critical_section_); + PushBackImpl(item); + return 0; +} + +int ListWrapper::PushFront(const unsigned int item_id) +{ + ListItem* item = new ListItem(item_id); + CriticalSectionScoped lock(*critical_section_); + PushFrontImpl(item); + return 0; +} + +int ListWrapper::PushFront(const void* ptr) +{ + ListItem* item = new ListItem(ptr); + CriticalSectionScoped lock(*critical_section_); + PushFrontImpl(item); + return 0; +} + +int ListWrapper::PopFront() +{ + return Erase(first_); +} + +int ListWrapper::PopBack() +{ + return Erase(last_); +} + +ListItem* ListWrapper::First() const +{ + return first_; +} + +ListItem* ListWrapper::Last() const +{ + return last_; +} + +ListItem* ListWrapper::Next(ListItem* item) const +{ + if(!item) + { + return 0; + } + return item->next_; +} + +ListItem* ListWrapper::Previous(ListItem* item) const +{ + if (!item) + { + return 0; + } + return item->prev_; +} + +int ListWrapper::Insert(ListItem* existing_previous_item, ListItem* new_item) +{ + if (!new_item) + { + return -1; + } + // Allow existing_previous_item to be NULL if the list is empty. + // TODO (hellner) why allow this? Keep it as is for now to avoid + // breaking API contract. + if (!existing_previous_item && !Empty()) + { + return -1; + } + CriticalSectionScoped lock(*critical_section_); + if (!existing_previous_item) + { + PushBackImpl(new_item); + return 0; + } + ListItem* next_item = existing_previous_item->next_; + new_item->next_ = existing_previous_item->next_; + new_item->prev_ = existing_previous_item; + existing_previous_item->next_ = new_item; + if (next_item) + { + next_item->prev_ = new_item; + } + else + { + last_ = new_item; + } + size_++; + return 0; +} + +int ListWrapper::InsertBefore(ListItem* existing_next_item, + ListItem* new_item) +{ + if (!new_item) + { + return -1; + } + // Allow existing_next_item to be NULL if the list is empty. + // Todo: why allow this? Keep it as is for now to avoid breaking API + // contract. + if (!existing_next_item && !Empty()) + { + return -1; + } + CriticalSectionScoped lock(*critical_section_); + if (!existing_next_item) + { + PushBackImpl(new_item); + return 0; + } + + ListItem* previous_item = existing_next_item->prev_; + new_item->next_ = existing_next_item; + new_item->prev_ = previous_item; + existing_next_item->prev_ = new_item; + if (previous_item) + { + previous_item->next_ = new_item; + } + else + { + first_ = new_item; + } + size_++; + return 0; +} + +int ListWrapper::Erase(ListItem* item) +{ + if (!item) + { + return -1; + } + size_--; + ListItem* previous_item = item->prev_; + ListItem* next_item = item->next_; + if (!previous_item) + { + if(next_item) + { + next_item->prev_ = 0; + } + first_ = next_item; + } + else + { + previous_item->next_ = next_item; + } + if (!next_item) + { + if(previous_item) + { + previous_item->next_ = 0; + } + last_ = previous_item; + } + else + { + next_item->prev_ = previous_item; + } + delete item; + return 0; +} + +void ListWrapper::PushBackImpl(ListItem* item) +{ + if (Empty()) + { + first_ = item; + last_ = item; + size_++; + return; + } + + item->prev_ = last_; + last_->next_ = item; + last_ = item; + size_++; +} + +void ListWrapper::PushFrontImpl(ListItem* item) +{ + if (Empty()) + { + first_ = item; + last_ = item; + size_++; + return; + } + + item->next_ = first_; + first_->prev_ = item; + first_ = item; + size_++; +} +} //namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/list_no_stl.h b/src/libs/webrtc/system_wrappers/list_no_stl.h new file mode 100644 index 00000000..26d844c7 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/list_no_stl.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_NO_STL_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_NO_STL_H_ + +#include "constructor_magic.h" + +namespace webrtc { +class CriticalSectionWrapper; + +class ListNoStlItem +{ +public: + ListNoStlItem(const void* ptr); + ListNoStlItem(const unsigned int item); + virtual ~ListNoStlItem(); + void* GetItem() const; + unsigned int GetUnsignedItem() const; + +protected: + ListNoStlItem* next_; + ListNoStlItem* prev_; + +private: + friend class ListNoStl; + + const void* item_ptr_; + const unsigned int item_; + DISALLOW_COPY_AND_ASSIGN(ListNoStlItem); +}; + + +class ListNoStl +{ +public: + ListNoStl(); + virtual ~ListNoStl(); + + // ListWrapper functions + unsigned int GetSize() const; + int PushBack(const void* ptr); + int PushBack(const unsigned int item_id); + int PushFront(const void* ptr); + int PushFront(const unsigned int item_id); + int PopFront(); + int PopBack(); + bool Empty() const; + ListNoStlItem* First() const; + ListNoStlItem* Last() const; + ListNoStlItem* Next(ListNoStlItem* item) const; + ListNoStlItem* Previous(ListNoStlItem* item) const; + int Erase(ListNoStlItem* item); + int Insert(ListNoStlItem* existing_previous_item, + ListNoStlItem* new_item); + + int InsertBefore(ListNoStlItem* existing_next_item, + ListNoStlItem* new_item); + +private: + void PushBack(ListNoStlItem* item); + void PushFront(ListNoStlItem* item); + + CriticalSectionWrapper* critical_section_; + ListNoStlItem* first_; + ListNoStlItem* last_; + unsigned int size_; + DISALLOW_COPY_AND_ASSIGN(ListNoStl); +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_NO_STL_H_ diff --git a/src/libs/webrtc/system_wrappers/list_stl.cc b/src/libs/webrtc/system_wrappers/list_stl.cc new file mode 100644 index 00000000..dcc63c3d --- /dev/null +++ b/src/libs/webrtc/system_wrappers/list_stl.cc @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "list_wrapper.h" + +#include "trace.h" + +namespace webrtc { +ListItem::ListItem(const void* item) + : this_iter_(), + item_ptr_(item), + item_(0) +{ +} + +ListItem::ListItem(const unsigned int item) + : this_iter_(), + item_ptr_(0), + item_(item) +{ +} + +ListItem::~ListItem() +{ +} + +void* ListItem::GetItem() const +{ + return const_cast<void*>(item_ptr_); +} + +unsigned int ListItem::GetUnsignedItem() const +{ + return item_; +} + +ListWrapper::ListWrapper() : list_() +{ +} + +ListWrapper::~ListWrapper() +{ + if (!Empty()) + { + // TODO (hellner) I'm not sure this loggin is useful. + WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, + "Potential memory leak in ListWrapper"); + // Remove all remaining list items. + while (Erase(First()) == 0) + {} + } +} + +bool ListWrapper::Empty() const +{ + return list_.empty(); +} + +unsigned int ListWrapper::GetSize() const +{ + return list_.size(); +} + +int ListWrapper::PushBack(const void* ptr) +{ + ListItem* item = new ListItem(ptr); + list_.push_back(item); + return 0; +} + +int ListWrapper::PushBack(const unsigned int item_id) +{ + ListItem* item = new ListItem(item_id); + list_.push_back(item); + return 0; +} + +int ListWrapper::PushFront(const unsigned int item_id) +{ + ListItem* item = new ListItem(item_id); + list_.push_front(item); + return 0; +} + +int ListWrapper::PushFront(const void* ptr) +{ + ListItem* item = new ListItem(ptr); + list_.push_front(item); + return 0; +} + +int ListWrapper::PopFront() +{ + if(list_.empty()) + { + return -1; + } + list_.pop_front(); + return 0; +} + +int ListWrapper::PopBack() +{ + if(list_.empty()) + { + return -1; + } + list_.pop_back(); + return 0; +} + +ListItem* ListWrapper::First() const +{ + if(list_.empty()) + { + return NULL; + } + std::list<ListItem*>::iterator item_iter = list_.begin(); + ListItem* return_item = (*item_iter); + return_item->this_iter_ = item_iter; + return return_item; +} + +ListItem* ListWrapper::Last() const +{ + if(list_.empty()) + { + return NULL; + } + // std::list::end() addresses the last item + 1. Decrement so that the + // actual last is accessed. + std::list<ListItem*>::iterator item_iter = list_.end(); + --item_iter; + ListItem* return_item = (*item_iter); + return_item->this_iter_ = item_iter; + return return_item; +} + +ListItem* ListWrapper::Next(ListItem* item) const +{ + if(item == NULL) + { + return NULL; + } + std::list<ListItem*>::iterator item_iter = item->this_iter_; + ++item_iter; + if (item_iter == list_.end()) + { + return NULL; + } + ListItem* return_item = (*item_iter); + return_item->this_iter_ = item_iter; + return return_item; +} + +ListItem* ListWrapper::Previous(ListItem* item) const +{ + if(item == NULL) + { + return NULL; + } + std::list<ListItem*>::iterator item_iter = item->this_iter_; + if (item_iter == list_.begin()) + { + return NULL; + } + --item_iter; + ListItem* return_item = (*item_iter); + return_item->this_iter_ = item_iter; + return return_item; +} + +int ListWrapper::Insert(ListItem* existing_previous_item, + ListItem* new_item) +{ + // Allow existingPreviousItem to be NULL if the list is empty. + // TODO (hellner) why allow this? Keep it as is for now to avoid + // breaking API contract. + if (!existing_previous_item && !Empty()) + { + return -1; + } + + if (!new_item) + { + return -1; + } + + std::list<ListItem*>::iterator insert_location = list_.begin(); + if (!Empty()) + { + insert_location = existing_previous_item->this_iter_; + if(insert_location != list_.end()) + { + ++insert_location; + } + } + + list_.insert(insert_location,new_item); + return 0; +} + +int ListWrapper::InsertBefore(ListItem* existing_next_item, + ListItem* new_item) +{ + // Allow existing_next_item to be NULL if the list is empty. + // Todo: why allow this? Keep it as is for now to avoid breaking API + // contract. + if (!existing_next_item && !Empty()) + { + return -1; + } + if (!new_item) + { + return -1; + } + + std::list<ListItem*>::iterator insert_location = list_.begin(); + if (!Empty()) + { + insert_location = existing_next_item->this_iter_; + } + + list_.insert(insert_location,new_item); + return 0; +} + +int ListWrapper::Erase(ListItem* item) +{ + if(item == NULL) + { + return -1; + } + list_.erase(item->this_iter_); + return 0; +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/list_stl.h b/src/libs/webrtc/system_wrappers/list_stl.h new file mode 100644 index 00000000..b83a6648 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/list_stl.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_STL_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_STL_H_ + +#include <list> + +#include "constructor_magic.h" + +namespace webrtc { +class ListItem +{ +friend class ListWrapper; + +public: + ListItem(const void* ptr); + ListItem(const unsigned int item); + virtual ~ListItem(); + void* GetItem() const; + unsigned int GetUnsignedItem() const; + +private: + mutable std::list<ListItem*>::iterator this_iter_; + const void* item_ptr_; + const unsigned int item_; + DISALLOW_COPY_AND_ASSIGN(ListItem); +}; + +class ListWrapper +{ +public: + ListWrapper(); + ~ListWrapper(); + + // ListWrapper functions + unsigned int GetSize() const; + int PushBack(const void* ptr); + int PushBack(const unsigned int item_id); + int PushFront(const void* ptr); + int PushFront(const unsigned int item_id); + int PopFront(); + int PopBack(); + bool Empty() const; + ListItem* First() const; + ListItem* Last() const; + ListItem* Next(ListItem* item) const; + ListItem* Previous(ListItem* item) const; + int Erase(ListItem* item); + int Insert(ListItem* existing_previous_item, ListItem* new_item); + int InsertBefore(ListItem* existing_next_item, ListItem* new_item); + +private: + mutable std::list<ListItem*> list_; + DISALLOW_COPY_AND_ASSIGN(ListWrapper); +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_STL_H_ diff --git a/src/libs/webrtc/system_wrappers/list_unittest.cc b/src/libs/webrtc/system_wrappers/list_unittest.cc new file mode 100644 index 00000000..3f3c88ff --- /dev/null +++ b/src/libs/webrtc/system_wrappers/list_unittest.cc @@ -0,0 +1,475 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "gtest/gtest.h" + +#include "list_wrapper.h" + +using ::webrtc::ListWrapper; +using ::webrtc::ListItem; + +// Note: kNumberOfElements needs to be even. +const unsigned int kNumberOfElements = 10; + +// An opaque implementation of dynamic or statically allocated unsigned ints. +// This class makes it possible to use the exact same code for testing of both +// the dynamic and static implementation of ListWrapper. +// Clarification: ListWrapper has two versions of PushBack(..). It takes an +// unsigned integer or a void pointer. The integer implementation takes care +// of memory management. The void pointer version expect the caller to manage +// the memory associated with the void pointer. +// This class works like the integer version but can be implemented on top of +// either the integer version or void pointer version of ListWrapper. +// Note: the non-virtual fuctions behave the same for both versions. +class ListWrapperSimple { +public: + static ListWrapperSimple* Create(bool static_allocation); + virtual ~ListWrapperSimple() {} + + // These three functions should be used for manipulating ListItems so that + // they are the type corresponding to the underlying implementation. + virtual unsigned int GetUnsignedItem( + const ListItem* item) const = 0; + virtual ListItem* CreateListItem(unsigned int item_id) = 0; + virtual bool DestroyListItem(ListItem* item) = 0; + + unsigned int GetSize() const { + return list_.GetSize(); + } + virtual int PushBack(const unsigned int item_id) = 0; + virtual int PushFront(const unsigned int item_id) = 0; + virtual int PopFront() = 0; + virtual int PopBack() = 0; + bool Empty() const { + return list_.Empty(); + } + ListItem* First() const { + return list_.First(); + } + ListItem* Last() const { + return list_.Last(); + } + ListItem* Next(ListItem* item) const { + return list_.Next(item); + } + ListItem* Previous(ListItem* item) const { + return list_.Previous(item); + } + virtual int Erase(ListItem* item) = 0; + int Insert(ListItem* existing_previous_item, + ListItem* new_item) { + return list_.Insert(existing_previous_item, new_item); + } + + int InsertBefore(ListItem* existing_next_item, + ListItem* new_item) { + return list_.InsertBefore(existing_next_item, new_item); + } +protected: + ListWrapperSimple() {} + + ListWrapper list_; +}; + +class ListWrapperStatic : public ListWrapperSimple { +public: + ListWrapperStatic() {} + virtual ~ListWrapperStatic() {} + + virtual unsigned int GetUnsignedItem(const ListItem* item) const { + return item->GetUnsignedItem(); + } + virtual ListItem* CreateListItem(unsigned int item_id) { + return new ListItem(item_id); + } + virtual bool DestroyListItem(ListItem* item) { + if (item == NULL) { + return false; + } + delete item; + return true; + } + virtual int PushBack(const unsigned int item_id) { + return list_.PushBack(item_id); + } + virtual int PushFront(const unsigned int item_id) { + return list_.PushFront(item_id); + } + virtual int PopFront() { + return list_.PopFront(); + } + virtual int PopBack() { + return list_.PopBack(); + } + virtual int Erase(ListItem* item) { + return list_.Erase(item); + } +}; + +class ListWrapperDynamic : public ListWrapperSimple { +public: + ListWrapperDynamic() {} + virtual ~ListWrapperDynamic() {} + + virtual unsigned int GetUnsignedItem(const ListItem* item) const { + const unsigned int* return_value_pointer = + reinterpret_cast<unsigned int*> (item->GetItem()); + if (return_value_pointer == NULL) { + return -1; + } + return *return_value_pointer; + } + virtual ListItem* CreateListItem(unsigned int item_id) { + unsigned int* item_id_pointer = new unsigned int; + if (item_id_pointer == NULL) { + return NULL; + } + *item_id_pointer = item_id; + ListItem* return_value = new ListItem( + reinterpret_cast<void*>(item_id_pointer)); + if (return_value == NULL) { + delete item_id_pointer; + return NULL; + } + return return_value; + } + virtual bool DestroyListItem(ListItem* item) { + if (item == NULL) { + return false; + } + bool return_value = false; + unsigned int* item_id_ptr = reinterpret_cast<unsigned int*>( + item->GetItem()); + if (item_id_ptr != NULL) { + return_value = true; + delete item_id_ptr; + } + delete item; + return return_value; + } + virtual int PushBack(const unsigned int item_id) { + unsigned int* item_id_ptr = new unsigned int; + if (item_id_ptr == NULL) { + return -1; + } + *item_id_ptr = item_id; + const int return_value = list_.PushBack( + reinterpret_cast<void*>(item_id_ptr)); + if (return_value != 0) { + delete item_id_ptr; + } + return return_value; + } + virtual int PushFront(const unsigned int item_id) { + unsigned int* item_id_ptr = new unsigned int; + if (item_id_ptr == NULL) { + return -1; + } + *item_id_ptr = item_id; + const int return_value = list_.PushFront( + reinterpret_cast<void*>(item_id_ptr)); + if (return_value != 0) { + delete item_id_ptr; + } + return return_value; + } + virtual int PopFront() { + return Erase(list_.First()); + } + virtual int PopBack() { + return Erase(list_.Last()); + } + virtual int Erase(ListItem* item) { + if (item == NULL) { + return -1; + } + unsigned int* item_id_ptr = reinterpret_cast<unsigned int*> ( + item->GetItem()); + int return_value = -1; + if (item_id_ptr != NULL) { + delete item_id_ptr; + return_value = 0; + } + if (list_.Erase(item) != 0) { + return -1; + } + return return_value; + } +}; + +ListWrapperSimple* ListWrapperSimple::Create(bool static_allocation) { + if(static_allocation) + { + return new ListWrapperStatic(); + } + return new ListWrapperDynamic(); +} + +void ClearList(ListWrapperSimple* list) { + if (list == NULL) + { + return; + } + while (list->Erase(list->First()) == 0) { + } +} + +ListWrapperSimple* CreateAscendingList(bool static_allocation) { + ListWrapperSimple* return_value = ListWrapperSimple::Create( + static_allocation); + if (return_value == NULL) { + return NULL; + } + for (unsigned int i = 0; i < kNumberOfElements; ++i) { + if (return_value->PushBack(i) == -1) { + ClearList(return_value); + delete return_value; + return NULL; + } + } + return return_value; +} + +ListWrapperSimple* CreateDecendingList(bool static_allocation) { + ListWrapperSimple* return_value = ListWrapperSimple::Create( + static_allocation); + if (return_value == NULL) { + return NULL; + } + for (unsigned int i = 0; i < kNumberOfElements; ++i) { + if (return_value->PushBack(kNumberOfElements - i - 1) == -1) { + ClearList(return_value); + delete return_value; + return NULL; + } + } + return return_value; +} + +// [0,kNumberOfElements - 1,1,kNumberOfElements - 2,...] (this is why +// kNumberOfElements need to be even) +ListWrapperSimple* CreateInterleavedList(bool static_allocation) { + ListWrapperSimple* return_value = ListWrapperSimple::Create( + static_allocation); + if (return_value == NULL) { + return NULL; + } + unsigned int uneven_count = 0; + unsigned int even_count = 0; + for (unsigned int i = 0; i < kNumberOfElements; i++) { + unsigned int push_value = 0; + if ((i % 2) == 0) { + push_value = even_count; + even_count++; + } else { + push_value = kNumberOfElements - uneven_count - 1; + uneven_count++; + } + if (return_value->PushBack(push_value) == -1) { + ClearList(return_value); + delete return_value; + return NULL; + } + } + return return_value; +} + +void PrintList(const ListWrapperSimple* list) { + ListItem* list_item = list->First(); + printf("["); + while (list_item != NULL) + { + printf("%3u", list->GetUnsignedItem(list_item)); + list_item = list->Next(list_item); + } + printf("]\n"); +} + +bool CompareLists(const ListWrapperSimple* lhs, const ListWrapperSimple* rhs) { + const unsigned int list_size = lhs->GetSize(); + if (lhs->GetSize() != rhs->GetSize()) { + return false; + } + if (lhs->Empty()) { + return rhs->Empty(); + } + unsigned int i = 0; + ListItem* lhs_item = lhs->First(); + ListItem* rhs_item = rhs->First(); + while (i < list_size) { + if (lhs_item == NULL) { + return false; + } + if (rhs_item == NULL) { + return false; + } + if (lhs->GetUnsignedItem(lhs_item) != rhs->GetUnsignedItem(rhs_item)) { + return false; + } + i++; + lhs_item = lhs->Next(lhs_item); + rhs_item = rhs->Next(rhs_item); + } + return true; +} + +TEST(ListWrapperTest,ReverseNewIntList) { + // Create a new temporary list with elements reversed those of + // new_int_list_ + const ListWrapperSimple* decending_list = CreateDecendingList(rand()%2); + ASSERT_FALSE(decending_list == NULL); + ASSERT_FALSE(decending_list->Empty()); + ASSERT_EQ(kNumberOfElements,decending_list->GetSize()); + + const ListWrapperSimple* ascending_list = CreateAscendingList(rand()%2); + ASSERT_FALSE(ascending_list == NULL); + ASSERT_FALSE(ascending_list->Empty()); + ASSERT_EQ(kNumberOfElements,ascending_list->GetSize()); + + ListWrapperSimple* list_to_reverse = ListWrapperSimple::Create(rand()%2); + + // Reverse the list using PushBack and Previous. + for (ListItem* item = ascending_list->Last(); item != NULL; + item = ascending_list->Previous(item)) { + list_to_reverse->PushBack(ascending_list->GetUnsignedItem(item)); + } + + ASSERT_TRUE(CompareLists(decending_list,list_to_reverse)); + + ListWrapperSimple* list_to_un_reverse = + ListWrapperSimple::Create(rand()%2); + ASSERT_FALSE(list_to_un_reverse == NULL); + // Reverse the reversed list using PushFront and Next. + for (ListItem* item = list_to_reverse->First(); item != NULL; + item = list_to_reverse->Next(item)) { + list_to_un_reverse->PushFront(list_to_reverse->GetUnsignedItem(item)); + } + + ASSERT_TRUE(CompareLists(ascending_list,list_to_un_reverse)); +} + +TEST(ListWrapperTest,PopTest) { + ListWrapperSimple* ascending_list = CreateAscendingList(rand()%2); + ASSERT_FALSE(ascending_list == NULL); + ASSERT_FALSE(ascending_list->Empty()); + EXPECT_EQ(0,ascending_list->PopFront()); + EXPECT_EQ(1,ascending_list->GetUnsignedItem(ascending_list->First())); + + EXPECT_EQ(0,ascending_list->PopBack()); + EXPECT_EQ(kNumberOfElements - 2,ascending_list->GetUnsignedItem( + ascending_list->Last())); + EXPECT_EQ(kNumberOfElements - 2, ascending_list->GetSize()); +} + +// Use Insert to interleave two lists. +TEST(ListWrapperTest,InterLeaveTest) { + ListWrapperSimple* interleave_list = CreateAscendingList(rand()%2); + ASSERT_FALSE(interleave_list == NULL); + ASSERT_FALSE(interleave_list->Empty()); + + ListWrapperSimple* decending_list = CreateDecendingList(rand()%2); + ASSERT_FALSE(decending_list == NULL); + + for (int i = 0; i < kNumberOfElements/2; ++i) { + ASSERT_EQ(0,interleave_list->PopBack()); + ASSERT_EQ(0,decending_list->PopBack()); + } + ASSERT_EQ(kNumberOfElements/2,interleave_list->GetSize()); + ASSERT_EQ(kNumberOfElements/2,decending_list->GetSize()); + + int insert_position = kNumberOfElements/2; + ASSERT_EQ(insert_position * 2, kNumberOfElements); + while (!decending_list->Empty()) + { + ListItem* item = decending_list->Last(); + ASSERT_FALSE(item == NULL); + + const unsigned int item_id = decending_list->GetUnsignedItem(item); + ASSERT_EQ(0,decending_list->Erase(item)); + + ListItem* insert_item = interleave_list->CreateListItem(item_id); + ASSERT_FALSE(insert_item == NULL); + item = interleave_list->First(); + ASSERT_FALSE(item == NULL); + for (int j = 0; j < insert_position - 1; ++j) { + item = interleave_list->Next(item); + ASSERT_FALSE(item == NULL); + } + if (0 != interleave_list->Insert(item,insert_item)) { + interleave_list->DestroyListItem(insert_item); + FAIL(); + } + --insert_position; + } + + ListWrapperSimple* interleaved_list = CreateInterleavedList(rand()%2); + ASSERT_FALSE(interleaved_list == NULL); + ASSERT_FALSE(interleaved_list->Empty()); + + ASSERT_TRUE(CompareLists(interleaved_list,interleave_list)); +} + +// Use InsertBefore to interleave two lists. +TEST(ListWrapperTest,InterLeaveTestII) { + ListWrapperSimple* interleave_list = CreateDecendingList(rand()%2); + ASSERT_FALSE(interleave_list == NULL); + ASSERT_FALSE(interleave_list->Empty()); + + ListWrapperSimple* ascending_list = CreateAscendingList(rand()%2); + ASSERT_FALSE(ascending_list == NULL); + + for (int i = 0; i < kNumberOfElements/2; ++i) { + ASSERT_EQ(0,interleave_list->PopBack()); + ASSERT_EQ(0,ascending_list->PopBack()); + } + ASSERT_EQ(kNumberOfElements/2,interleave_list->GetSize()); + ASSERT_EQ(kNumberOfElements/2,ascending_list->GetSize()); + + int insert_position = kNumberOfElements/2; + ASSERT_EQ(insert_position * 2, kNumberOfElements); + while (!ascending_list->Empty()) + { + ListItem* item = ascending_list->Last(); + ASSERT_FALSE(item == NULL); + + const unsigned int item_id = ascending_list->GetUnsignedItem(item); + ASSERT_EQ(0,ascending_list->Erase(item)); + + ListItem* insert_item = interleave_list->CreateListItem(item_id); + ASSERT_FALSE(insert_item == NULL); + item = interleave_list->First(); + ASSERT_FALSE(item == NULL); + for (int j = 0; j < insert_position - 1; ++j) { + item = interleave_list->Next(item); + ASSERT_FALSE(item == NULL); + } + if (0 != interleave_list->InsertBefore(item,insert_item)) { + interleave_list->DestroyListItem(insert_item); + FAIL(); + } + --insert_position; + } + + ListWrapperSimple* interleaved_list = CreateInterleavedList(rand()%2); + ASSERT_FALSE(interleaved_list == NULL); + ASSERT_FALSE(interleaved_list->Empty()); + + ASSERT_TRUE(CompareLists(interleaved_list,interleave_list)); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + // Added return_value so that it's convenient to put a breakpoint before + // exiting please note that the return value from RUN_ALL_TESTS() must + // be returned by the main function. + const int return_value = RUN_ALL_TESTS(); + return return_value; +} diff --git a/src/libs/webrtc/system_wrappers/list_wrapper.h b/src/libs/webrtc/system_wrappers/list_wrapper.h new file mode 100644 index 00000000..bc10ad4a --- /dev/null +++ b/src/libs/webrtc/system_wrappers/list_wrapper.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LIST_WRAPPER_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LIST_WRAPPER_H_ + +#include "constructor_magic.h" + +namespace webrtc { +class CriticalSectionWrapper; + +class ListItem +{ +friend class ListWrapper; + +public: + ListItem(const void* ptr); + ListItem(const unsigned int item); + virtual ~ListItem(); + void* GetItem() const; + unsigned int GetUnsignedItem() const; + +protected: + ListItem* next_; + ListItem* prev_; + +private: + const void* item_ptr_; + const unsigned int item_; + DISALLOW_COPY_AND_ASSIGN(ListItem); +}; + +class ListWrapper +{ +public: + ListWrapper(); + virtual ~ListWrapper(); + + // Returns the number of elements stored in the list. + unsigned int GetSize() const; + + // Puts a pointer to anything last in the list. + int PushBack(const void* ptr); + // Puts a pointer to anything first in the list. + int PushFront(const void* ptr); + + // Puts a copy of the specified integer last in the list. + int PushBack(const unsigned int item_id); + // Puts a copy of the specified integer first in the list. + int PushFront(const unsigned int item_id); + + // Pops the first ListItem from the list + int PopFront(); + + // Pops the last ListItem from the list + int PopBack(); + + // Returns true if the list is empty + bool Empty() const; + + // Returns a pointer to the first ListItem in the list. + ListItem* First() const; + + // Returns a pointer to the last ListItem in the list. + ListItem* Last() const; + + // Returns a pointer to the ListItem stored after item in the list. + ListItem* Next(ListItem* item) const; + + // Returns a pointer to the ListItem stored before item in the list. + ListItem* Previous(ListItem* item) const; + + // Removes item from the list. + int Erase(ListItem* item); + + // Insert list item after existing_previous_item. Please note that new_item + // must be created using new ListItem(). The map will take ownership of + // new_item following a successfull insert. If insert fails new_item will + // not be released by the List + int Insert(ListItem* existing_previous_item, + ListItem* new_item); + + // Insert list item before existing_next_item. Please note that new_item + // must be created using new ListItem(). The map will take ownership of + // new_item following a successfull insert. If insert fails new_item will + // not be released by the List + int InsertBefore(ListItem* existing_next_item, + ListItem* new_item); + +private: + void PushBackImpl(ListItem* item); + void PushFrontImpl(ListItem* item); + + CriticalSectionWrapper* critical_section_; + ListItem* first_; + ListItem* last_; + unsigned int size_; + DISALLOW_COPY_AND_ASSIGN(ListWrapper); +}; +} //namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LIST_WRAPPER_H_ diff --git a/src/libs/webrtc/system_wrappers/map.cc b/src/libs/webrtc/system_wrappers/map.cc new file mode 100644 index 00000000..0bff155b --- /dev/null +++ b/src/libs/webrtc/system_wrappers/map.cc @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "map_wrapper.h" + +#include "trace.h" + +namespace webrtc { +MapItem::MapItem(int id, void* item) : item_pointer_(item), item_id_(id) +{ +} + +MapItem::~MapItem() +{ +} + +void* MapItem::GetItem() +{ + return item_pointer_; +} + +int MapItem::GetId() +{ + return item_id_; +} + +unsigned int MapItem::GetUnsignedId() +{ + return static_cast<unsigned int>(item_id_); +} + +void MapItem::SetItem(void* ptr) +{ + item_pointer_ = ptr; +} + +MapWrapper::MapWrapper() : map_() +{ +} + +MapWrapper::~MapWrapper() +{ + if (!map_.empty()) + { + WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, + "Potential memory leak in MapWrapper"); + // Remove all map items. Please note that std::map::clear() can't be + // used because each item has some dynamically allocated memory + // associated with it (i.e. using std::map::clear would introduce a + // memory leak). + while (Erase(First()) == 0) + {} + } +} + +int MapWrapper::Size() const +{ + return (int)map_.size(); +} + +int MapWrapper::Insert(int id, void* ptr) +{ + map_[id] = new MapItem(id,ptr); + return 0; +} + +MapItem* MapWrapper::First() const +{ + std::map<int, MapItem*>::const_iterator it = map_.begin(); + if (it != map_.end()) + { + return it->second; + } + return 0; +} + +MapItem* MapWrapper::Last() const +{ + std::map<int, MapItem*>::const_reverse_iterator it = map_.rbegin(); + if (it != map_.rend()) + { + return it->second; + } + return 0; +} + +MapItem* MapWrapper::Next(MapItem* item) const +{ + if (item == 0) + { + return 0; + } + std::map<int, MapItem*>::const_iterator it = map_.find(item->item_id_); + if (it != map_.end()) + { + it++; + if (it != map_.end()) + { + return it->second; + } + } + return 0; +} + +MapItem* MapWrapper::Previous(MapItem* item) const +{ + if (item == 0) + { + return 0; + } + + std::map<int, MapItem*>::const_iterator it = map_.find(item->item_id_); + if ((it != map_.end()) && + (it != map_.begin())) + { + --it; + return it->second; + } + return 0; +} + +MapItem* MapWrapper::Find(int id) const +{ + std::map<int, MapItem*>::const_iterator it = map_.find(id); + if (it != map_.end()) + { + return it->second; + } + return 0; +} + +int MapWrapper::Erase(MapItem* item) +{ + if (item == 0) + { + return -1; + } + std::map<int, MapItem*>::iterator it = map_.find(item->item_id_); + if (it != map_.end()) + { + delete it->second; + map_.erase(it); + return 0; + } + return -1; +} + +int MapWrapper::Erase(const int id) +{ + std::map<int, MapItem*>::iterator it = map_.find(id); + if (it != map_.end()) + { + delete it->second; + map_.erase(it); + return 0; + } + return -1; +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/map_no_stl.cc b/src/libs/webrtc/system_wrappers/map_no_stl.cc new file mode 100644 index 00000000..cb0ac002 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/map_no_stl.cc @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "map_no_stl.h" + +#include "critical_section_wrapper.h" +#include "trace.h" + +namespace webrtc { +MapNoStlItem::MapNoStlItem(int id, void* item) + : next_(0), + prev_(0), + item_id_(id), + item_ptr_(item) +{ +} + +MapNoStlItem::~MapNoStlItem() +{ +} + +void* MapNoStlItem::GetItem() +{ + return item_ptr_; +} + +int MapNoStlItem::GetId() +{ + return item_id_; +} + +unsigned int MapNoStlItem::GetUnsignedId() +{ + return static_cast<unsigned int>(item_id_); +} + +void MapNoStlItem::SetItem(void* ptr) +{ + item_ptr_ = ptr; +} + +MapNoStl::MapNoStl() + : critical_section_(CriticalSectionWrapper::CreateCriticalSection()), + first_(0), + last_(0), + size_(0) +{ +} + +MapNoStl::~MapNoStl() +{ + if (First()) + { + WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, + "Potential memory leak in MapNoStl"); + while (Erase(First()) == 0) + {} + } + delete critical_section_; +} + +int MapNoStl::Size() const +{ + return size_; +} + +int MapNoStl::Insert(int id, void* ptr) +{ + MapNoStlItem* new_item = new MapNoStlItem(id, ptr); + + CriticalSectionScoped lock(*critical_section_); + MapNoStlItem* item = first_; + size_++; + if (!item) + { + first_ = new_item; + last_ = new_item; + return 0; + } + while(item->next_) + { + // Three scenarios + // 1. Item should be inserted first. + // 2. Item should be inserted between two items + // 3. Item should be inserted last + if (item->GetId() > id) + { + new_item->next_ = item; + item->prev_ = new_item; + if (item == first_) + { + first_ = new_item; + } + else + { + new_item->prev_ = item->prev_; + new_item->prev_->next_ = new_item; + } + return 0; + } + item = item->next_; + } + // 3 + item->next_ = new_item; + new_item->prev_ = item; + last_ = new_item; + return 0; +} + +MapNoStlItem* MapNoStl::First() const +{ + return first_; +} + +MapNoStlItem* MapNoStl::Last() const +{ + return last_; +} + +MapNoStlItem* MapNoStl::Next(MapNoStlItem* item) const +{ + if (!item) + { + return 0; + } + return item->next_; +} + +MapNoStlItem* MapNoStl::Previous(MapNoStlItem* item) const +{ + if (!item) + { + return 0; + } + return item->prev_; +} + +MapNoStlItem* MapNoStl::Find(int id) const +{ + CriticalSectionScoped lock(*critical_section_); + MapNoStlItem* item = Locate(id); + return item; +} + +int MapNoStl::Erase(MapNoStlItem* item) +{ + if(!item) + { + return -1; + } + CriticalSectionScoped lock(*critical_section_); + return Remove(item); +} + +int MapNoStl::Erase(const int id) +{ + CriticalSectionScoped lock(*critical_section_); + MapNoStlItem* item = Locate(id); + if(!item) + { + return -1; + } + return Remove(item); +} + +MapNoStlItem* MapNoStl::Locate(int id) const +{ + MapNoStlItem* item = first_; + while(item) + { + if (item->GetId() == id) + { + return item; + } + item = item->next_; + } + return 0; +} + +int MapNoStl::Remove(MapNoStlItem* item) +{ + if (!item) + { + return -1; + } + size_--; + MapNoStlItem* previous_item = item->prev_; + MapNoStlItem* next_item = item->next_; + if (!previous_item) + { + next_item->prev_ = 0; + first_ = next_item; + } + else + { + previous_item->next_ = next_item; + } + if (!next_item) + { + previous_item->next_ = 0; + last_ = previous_item; + } + else + { + next_item->prev_ = previous_item; + } + delete item; + return 0; +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/map_no_stl.h b/src/libs/webrtc/system_wrappers/map_no_stl.h new file mode 100644 index 00000000..51bc0114 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/map_no_stl.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_MAP_NO_STL_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_MAP_NO_STL_H_ + +#include "constructor_magic.h" + +namespace webrtc { +class CriticalSectionWrapper; + +class MapNoStlItem +{ +friend class Map; + +public: + MapNoStlItem(int id, void* ptr); + virtual ~MapNoStlItem(); + void* GetItem(); + int GetId(); + unsigned int GetUnsignedId(); + void SetItem(void* ptr); + +protected: + MapNoStlItem* next_; + MapNoStlItem* prev_; + +private: + int item_id_; + void* item_ptr_; + DISALLOW_COPY_AND_ASSIGN(MapNoStlItem); +}; + +class MapNoStl +{ +public: + MapNoStl(); + virtual ~MapNoStl(); + + // MapWrapper functions. + int Insert(int id, void* ptr); + int Erase(MapNoStlItem* item); + int Erase(int id); + int Size() const; + MapNoStlItem* First() const; + MapNoStlItem* Last() const; + MapNoStlItem* Next(MapNoStlItem* item) const; + MapNoStlItem* Previous(MapNoStlItem* item) const; + MapNoStlItem* Find(int id) const; + +private: + MapNoStlItem* Locate(int id) const; + int Remove(MapNoStlItem* item); + + CriticalSection* critical_section_; + MapNoStlItem* first_; + MapNoStlItem* last_; + int size_; + DISALLOW_COPY_AND_ASSIGN(MapNoStl); +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_MAP_NO_STL_H_ diff --git a/src/libs/webrtc/system_wrappers/map_unittest.cc b/src/libs/webrtc/system_wrappers/map_unittest.cc new file mode 100644 index 00000000..9e17637f --- /dev/null +++ b/src/libs/webrtc/system_wrappers/map_unittest.cc @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "gtest/gtest.h" + +#include "map_wrapper.h" + +using ::webrtc::MapWrapper; +using ::webrtc::MapItem; + +const unsigned int kNumberOfElements = 10; + +int* ItemPointer(MapItem* item) { + if (item == NULL) { + return NULL; + } + return reinterpret_cast<int*>(item->GetItem()); +} + +bool DeleteItemContent(MapItem* item) { + if(item == NULL) { + return false; + } + int* value_ptr = ItemPointer(item); + delete value_ptr; + return true; +} + +int ItemValue(MapItem* item) { + if (item == NULL) { + return -1; + } + const int* value_ptr = ItemPointer(item); + if (value_ptr == 0) { + return -1; + } + return *value_ptr; +} + +void PrintToConsole(const char* message, bool supress) { + if (supress) { + return; + } + printf(message); +} + +bool CreateAscendingMap(MapWrapper* ascending_map) { + int* insert_value = NULL; + for (int i = 0; i < kNumberOfElements; ++i) { + insert_value = new int; + if (insert_value == NULL) { + return false; + } + *insert_value = i; + if (0 != ascending_map->Insert( + i, + reinterpret_cast<void*>(insert_value))) { + return false; + } + } + return true; +} + +bool ClearMap(MapWrapper* clear_map) { + bool success = true; + while (clear_map->Size() != 0) { + MapItem* remove_item = clear_map->First(); + if (remove_item == NULL) { + return false; + } + if (!DeleteItemContent(remove_item)) { + success = false; + } + if (clear_map->Erase(remove_item) != 0) { + return false; + } + } + return success; +} + +void PrintMapItem(MapItem* item, bool supress) { + const int id = item->GetId(); + const int value = ItemValue(item); + char print_buffer[16]; + sprintf(print_buffer, "(%3i,%3i) ", id, value); + PrintToConsole(print_buffer, supress); +} + +// Succeeds only if all the items were printed. +bool PrintMap(const MapWrapper& print_map, bool supress) { + const int elements_to_print = print_map.Size(); + int elements_printed = 0; + MapItem* item = print_map.First(); + PrintToConsole("[", supress); + while (item != NULL) { + PrintMapItem(item, supress); + ++elements_printed; + item = print_map.Next(item); + } + PrintToConsole("]\n", supress); + return elements_printed == elements_to_print; +} + +// Succeeds only if all the items were printed. +bool ReversePrintMap(const MapWrapper& print_map, bool supress) { + const int elements_to_print = print_map.Size(); + int elements_printed = 0; + MapItem* item = print_map.Last(); + PrintToConsole("[", supress); + while (item != NULL) { + PrintMapItem(item, supress); + ++elements_printed; + item = print_map.Previous(item); + } + PrintToConsole("]\n", supress); + return elements_printed == elements_to_print; +} + +// Returns true if the map items contain the same item. +bool CompareItems(MapItem* lhs_item, MapItem* rhs_item) { + if ((lhs_item == NULL) || (rhs_item == NULL)) { + return false; + } + if (lhs_item->GetId() != rhs_item->GetId()) { + return false; + } + return lhs_item->GetItem() == rhs_item->GetItem(); +} + +// Returns true if the map contains the same items. +bool CompareMaps(const MapWrapper& lhs, const MapWrapper& rhs) { + const int map_size = lhs.Size(); + if (map_size != rhs.Size()) { + return false; + } + int item_count = 0; + MapItem* lhs_item = lhs.First(); + while (lhs_item != NULL) { + MapItem* rhs_item = rhs.Find(lhs_item->GetId()); + if (rhs_item == NULL) { + return false; + } + if (!CompareItems(lhs_item, rhs_item)) { + return false; + } + ++item_count; + lhs_item = lhs.Next(lhs_item); + } + return item_count == map_size; +} + +class MapWrapperTest : public ::testing::Test { +protected: + virtual void SetUp() { + ASSERT_TRUE(CreateAscendingMap(&ascending_map_)); + } + + virtual void TearDown() { + EXPECT_TRUE(ClearMap(&ascending_map_)); + } + MapWrapper ascending_map_; +}; + +TEST_F(MapWrapperTest,RemoveTest) { + // Erase using int id + { // Create local scope to avoid accidental re-use + MapItem* item_first = ascending_map_.First(); + ASSERT_FALSE(item_first == NULL); + const int first_value_id = item_first->GetId(); + const int first_value = ItemValue(item_first); + EXPECT_TRUE(first_value == 0); + EXPECT_EQ(first_value_id,first_value); + EXPECT_FALSE(NULL == ascending_map_.Find(first_value_id)); + EXPECT_TRUE(DeleteItemContent(item_first)); + ascending_map_.Erase(first_value_id); + EXPECT_TRUE(NULL == ascending_map_.Find(first_value_id)); + EXPECT_EQ(kNumberOfElements-1,ascending_map_.Size()); + } + + // Erase using MapItem* item + MapItem* item_last = ascending_map_.Last(); + ASSERT_FALSE(item_last == NULL); + const int last_value_id = item_last->GetId(); + const int last_value = ItemValue(item_last); + EXPECT_TRUE(last_value == kNumberOfElements - 1); + EXPECT_EQ(last_value_id, last_value); + EXPECT_FALSE(NULL == ascending_map_.Find(last_value_id)); + ascending_map_.Erase(last_value_id); + EXPECT_TRUE(DeleteItemContent(item_last)); + EXPECT_TRUE(NULL == ascending_map_.Find(last_value_id)); + EXPECT_EQ(kNumberOfElements-2,ascending_map_.Size()); +} + +TEST_F(MapWrapperTest, PrintTest) { + const bool supress = true; // Don't spam the console + + EXPECT_TRUE(PrintMap(ascending_map_, supress)); + EXPECT_TRUE(ReversePrintMap(ascending_map_, supress)); +} + +TEST_F(MapWrapperTest, CopyTest) { + MapWrapper compare_map; + ASSERT_TRUE(CreateAscendingMap(&compare_map)); + const int map_size = compare_map.Size(); + ASSERT_EQ(ascending_map_.Size(), map_size); + // CompareMaps compare the pointers not value of the pointers. + // (the values are the same since both are ascending maps). + EXPECT_FALSE(CompareMaps(compare_map,ascending_map_)); + + int copy_count = 0; + MapItem* ascend_item = ascending_map_.First(); + while (ascend_item != NULL) { + MapItem* compare_item = compare_map.Find(ascend_item->GetId()); + ASSERT_FALSE(compare_item == NULL); + DeleteItemContent(compare_item); + compare_item->SetItem(ascend_item->GetItem()); + ascend_item = ascending_map_.Next(ascend_item); + ++copy_count; + } + EXPECT_TRUE(CompareMaps(compare_map,ascending_map_)); + while (compare_map.Erase(compare_map.First()) == 0) { + } + EXPECT_EQ(map_size, copy_count); +} diff --git a/src/libs/webrtc/system_wrappers/map_wrapper.h b/src/libs/webrtc/system_wrappers/map_wrapper.h new file mode 100644 index 00000000..9297382c --- /dev/null +++ b/src/libs/webrtc/system_wrappers/map_wrapper.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_MAP_WRAPPER_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_MAP_WRAPPER_H_ + +#include <map> + +#include "constructor_magic.h" + +namespace webrtc { +class MapItem +{ +friend class MapWrapper; + +public: + MapItem(int id, void* ptr); + virtual ~MapItem(); + void* GetItem(); + int GetId(); + unsigned int GetUnsignedId(); + void SetItem(void* ptr); + +private: + int item_id_; + void* item_pointer_; + DISALLOW_COPY_AND_ASSIGN(MapItem); +}; + +class MapWrapper +{ +public: + MapWrapper(); + ~MapWrapper(); + + // Puts a pointer to anything in the map and associates it with id. Note, id + // needs to be unique for all items in the map. + int Insert(int id, void* ptr); + + // Removes item from map. + int Erase(MapItem* item); + + // Finds item with associated with id and removes it from the map. + int Erase(int id); + + // Returns the number of elements stored in the map. + int Size() const; + + // Returns a pointer to the first MapItem in the map. + MapItem* First() const; + + // Returns a pointer to the last MapItem in the map. + MapItem* Last() const; + + // Returns a pointer to the MapItem stored after item in the map. + MapItem* Next(MapItem* item) const; + + // Returns a pointer to the MapItem stored before item in the map. + MapItem* Previous(MapItem* item) const; + + // Returns a pointer to the MapItem associated with id from the map. + MapItem* Find(int id) const; + +private: + std::map<int, MapItem*> map_; + DISALLOW_COPY_AND_ASSIGN(MapWrapper); +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_MAP_WRAPPER_H_ diff --git a/src/libs/webrtc/system_wrappers/rw_lock.cc b/src/libs/webrtc/system_wrappers/rw_lock.cc new file mode 100644 index 00000000..47901d34 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/rw_lock.cc @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rw_lock_wrapper.h" + +#include <assert.h> + +#if defined(_WIN32) + #include "rw_lock_windows.h" +#elif defined(ANDROID) + #include <stdlib.h> + #include "rw_lock_generic.h" +#else + #include "rw_lock_linux.h" +#endif + +namespace webrtc { +RWLockWrapper* RWLockWrapper::CreateRWLock() +{ +#ifdef _WIN32 + RWLockWrapper* lock = new RWLockWindows(); +#elif defined(ANDROID) + RWLockWrapper* lock = new RWLockWrapperGeneric(); +#else + RWLockWrapper* lock = new RWLockLinux(); +#endif + if(lock->Init() != 0) + { + delete lock; + assert(false); + return NULL; + } + return lock; +} + +RWLockWrapper::~RWLockWrapper() +{ +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/rw_lock_generic.cc b/src/libs/webrtc/system_wrappers/rw_lock_generic.cc new file mode 100644 index 00000000..a468ef3b --- /dev/null +++ b/src/libs/webrtc/system_wrappers/rw_lock_generic.cc @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rw_lock_generic.h" + +#include "condition_variable_wrapper.h" +#include "critical_section_wrapper.h" + +namespace webrtc { +RWLockWrapperGeneric::RWLockWrapperGeneric() + : _readersActive(0), + _writerActive(false), + _readersWaiting(0), + _writersWaiting(0) +{ + _critSectPtr = CriticalSectionWrapper::CreateCriticalSection(); + _readCondPtr = ConditionVariableWrapper::CreateConditionVariable(); + _writeCondPtr = ConditionVariableWrapper::CreateConditionVariable(); +} + +RWLockWrapperGeneric::~RWLockWrapperGeneric() +{ + delete _writeCondPtr; + delete _readCondPtr; + delete _critSectPtr; +} + +int RWLockWrapperGeneric::Init() +{ + return 0; +} + +void RWLockWrapperGeneric::AcquireLockExclusive() +{ + _critSectPtr->Enter(); + + if (_writerActive || _readersActive > 0) + { + ++_writersWaiting; + + while (_writerActive || _readersActive > 0) + { + _writeCondPtr->SleepCS(*_critSectPtr); + } + + --_writersWaiting; + } + _writerActive = true; + _critSectPtr->Leave(); +} + +void RWLockWrapperGeneric::ReleaseLockExclusive() +{ + _critSectPtr->Enter(); + + _writerActive = false; + + if (_writersWaiting > 0) + { + _writeCondPtr->Wake(); + + }else if (_readersWaiting > 0) + { + _readCondPtr->WakeAll(); + } + _critSectPtr->Leave(); +} + +void RWLockWrapperGeneric::AcquireLockShared() +{ + _critSectPtr->Enter(); + + if (_writerActive || _writersWaiting > 0) + { + ++_readersWaiting; + + while (_writerActive || _writersWaiting > 0) + { + _readCondPtr->SleepCS(*_critSectPtr); + } + --_readersWaiting; + } + ++_readersActive; + _critSectPtr->Leave(); +} + +void RWLockWrapperGeneric::ReleaseLockShared() +{ + _critSectPtr->Enter(); + + --_readersActive; + + if (_readersActive == 0 && _writersWaiting > 0) + { + _writeCondPtr->Wake(); + } + _critSectPtr->Leave(); +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/rw_lock_generic.h b/src/libs/webrtc/system_wrappers/rw_lock_generic.h new file mode 100644 index 00000000..fff5e5d2 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/rw_lock_generic.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_GENERIC_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_GENERIC_H_ + +#include "rw_lock_wrapper.h" + +namespace webrtc { +class CriticalSectionWrapper; +class ConditionVariableWrapper; + +class RWLockWrapperGeneric : public RWLockWrapper +{ +public: + RWLockWrapperGeneric(); + virtual ~RWLockWrapperGeneric(); + + virtual void AcquireLockExclusive(); + virtual void ReleaseLockExclusive(); + + virtual void AcquireLockShared(); + virtual void ReleaseLockShared(); + +protected: + virtual int Init(); + +private: + CriticalSectionWrapper* _critSectPtr; + ConditionVariableWrapper* _readCondPtr; + ConditionVariableWrapper* _writeCondPtr; + + int _readersActive; + bool _writerActive; + int _readersWaiting; + int _writersWaiting; +}; +} // namespace webrtc +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_GENERIC_H_ diff --git a/src/libs/webrtc/system_wrappers/rw_lock_linux.cc b/src/libs/webrtc/system_wrappers/rw_lock_linux.cc new file mode 100644 index 00000000..084dce86 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/rw_lock_linux.cc @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rw_lock_linux.h" + +namespace webrtc { +RWLockLinux::RWLockLinux() : _lock() +{ +} + +RWLockLinux::~RWLockLinux() +{ + pthread_rwlock_destroy(&_lock); +} + +int RWLockLinux::Init() +{ + return pthread_rwlock_init(&_lock, 0); +} + +void RWLockLinux::AcquireLockExclusive() +{ + pthread_rwlock_wrlock(&_lock); +} + +void RWLockLinux::ReleaseLockExclusive() +{ + pthread_rwlock_unlock(&_lock); +} + +void RWLockLinux::AcquireLockShared() +{ + pthread_rwlock_rdlock(&_lock); +} + +void RWLockLinux::ReleaseLockShared() +{ + pthread_rwlock_unlock(&_lock); +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/rw_lock_linux.h b/src/libs/webrtc/system_wrappers/rw_lock_linux.h new file mode 100644 index 00000000..391ee8fe --- /dev/null +++ b/src/libs/webrtc/system_wrappers/rw_lock_linux.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_LINUX_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_LINUX_H_ + +#include "rw_lock_wrapper.h" + +#include <pthread.h> + +namespace webrtc { +class RWLockLinux : public RWLockWrapper +{ +public: + RWLockLinux(); + virtual ~RWLockLinux(); + + virtual void AcquireLockExclusive(); + virtual void ReleaseLockExclusive(); + + virtual void AcquireLockShared(); + virtual void ReleaseLockShared(); + +protected: + virtual int Init(); + +private: + pthread_rwlock_t _lock; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_LINUX_H_ diff --git a/src/libs/webrtc/system_wrappers/rw_lock_windows.cc b/src/libs/webrtc/system_wrappers/rw_lock_windows.cc new file mode 100644 index 00000000..cf5db575 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/rw_lock_windows.cc @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rw_lock_windows.h" + +#include "critical_section_wrapper.h" +#include "condition_variable_wrapper.h" +#include "trace.h" + +// TODO (hellner) why not just use the rw_lock_generic.cc solution if +// native is not supported? Unnecessary redundancy! + +namespace webrtc { +bool RWLockWindows::_winSupportRWLockPrimitive = false; +static HMODULE library = NULL; + +PInitializeSRWLock _PInitializeSRWLock; +PAcquireSRWLockExclusive _PAcquireSRWLockExclusive; +PAcquireSRWLockShared _PAcquireSRWLockShared; +PReleaseSRWLockShared _PReleaseSRWLockShared; +PReleaseSRWLockExclusive _PReleaseSRWLockExclusive; + +RWLockWindows::RWLockWindows() + : _critSectPtr(NULL), + _readCondPtr(NULL), + _writeCondPtr(NULL), + _readersActive(0), + _writerActive(false), + _readersWaiting(0), + _writersWaiting(0) +{ +} + +RWLockWindows::~RWLockWindows() +{ + delete _writeCondPtr; + delete _readCondPtr; + delete _critSectPtr; +} + +int RWLockWindows::Init() +{ + if(!library) + { + // Use native implementation if supported (i.e Vista+) + library = LoadLibrary(TEXT("Kernel32.dll")); + if(library) + { + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, + "Loaded Kernel.dll"); + + _PInitializeSRWLock = + (PInitializeSRWLock)GetProcAddress( + library, + "InitializeSRWLock"); + + _PAcquireSRWLockExclusive = + (PAcquireSRWLockExclusive)GetProcAddress( + library, + "AcquireSRWLockExclusive"); + _PReleaseSRWLockExclusive = + (PReleaseSRWLockExclusive)GetProcAddress( + library, + "ReleaseSRWLockExclusive"); + _PAcquireSRWLockShared = + (PAcquireSRWLockShared)GetProcAddress( + library, + "AcquireSRWLockShared"); + _PReleaseSRWLockShared = + (PReleaseSRWLockShared)GetProcAddress( + library, + "ReleaseSRWLockShared"); + + if( _PInitializeSRWLock && + _PAcquireSRWLockExclusive && + _PReleaseSRWLockExclusive && + _PAcquireSRWLockShared && + _PReleaseSRWLockShared ) + { + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, + "Loaded Simple RW Lock"); + _winSupportRWLockPrimitive = true; + } + } + } + if(_winSupportRWLockPrimitive) + { + _PInitializeSRWLock(&_lock); + } else { + _critSectPtr = CriticalSectionWrapper::CreateCriticalSection(); + _readCondPtr = ConditionVariableWrapper::CreateConditionVariable(); + _writeCondPtr = ConditionVariableWrapper::CreateConditionVariable(); + } + return 0; +} + +void RWLockWindows::AcquireLockExclusive() +{ + if (_winSupportRWLockPrimitive) + { + _PAcquireSRWLockExclusive(&_lock); + } else { + _critSectPtr->Enter(); + + if (_writerActive || _readersActive > 0) + { + ++_writersWaiting; + while (_writerActive || _readersActive > 0) + { + _writeCondPtr->SleepCS(*_critSectPtr); + } + --_writersWaiting; + } + _writerActive = true; + _critSectPtr->Leave(); + } +} + +void RWLockWindows::ReleaseLockExclusive() +{ + if(_winSupportRWLockPrimitive) + { + _PReleaseSRWLockExclusive(&_lock); + } else { + _critSectPtr->Enter(); + _writerActive = false; + if (_writersWaiting > 0) + { + _writeCondPtr->Wake(); + + }else if (_readersWaiting > 0) { + _readCondPtr->WakeAll(); + } + _critSectPtr->Leave(); + } +} + +void RWLockWindows::AcquireLockShared() +{ + if(_winSupportRWLockPrimitive) + { + _PAcquireSRWLockShared(&_lock); + } else + { + _critSectPtr->Enter(); + if (_writerActive || _writersWaiting > 0) + { + ++_readersWaiting; + + while (_writerActive || _writersWaiting > 0) + { + _readCondPtr->SleepCS(*_critSectPtr); + } + --_readersWaiting; + } + ++_readersActive; + _critSectPtr->Leave(); + } +} + +void RWLockWindows::ReleaseLockShared() +{ + if(_winSupportRWLockPrimitive) + { + _PReleaseSRWLockShared(&_lock); + } else + { + _critSectPtr->Enter(); + + --_readersActive; + + if (_readersActive == 0 && _writersWaiting > 0) + { + _writeCondPtr->Wake(); + } + _critSectPtr->Leave(); + } +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/rw_lock_windows.h b/src/libs/webrtc/system_wrappers/rw_lock_windows.h new file mode 100644 index 00000000..dc5355e4 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/rw_lock_windows.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_WINDOWS_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_WINDOWS_H_ + +#include "rw_lock_wrapper.h" + +#include <Windows.h> + +#if !defined(RTL_SRWLOCK_INIT) + typedef struct _RTL_SRWLOCK + { + void* Ptr; + } RTL_SRWLOCK, *PRTL_SRWLOCK; + typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK; +#endif + +namespace webrtc { +class CriticalSectionWrapper; +class ConditionVariableWrapper; + +typedef void (WINAPI *PInitializeSRWLock)(PSRWLOCK); + +typedef void (WINAPI *PAcquireSRWLockExclusive)(PSRWLOCK); +typedef void (WINAPI *PReleaseSRWLockExclusive)(PSRWLOCK); + +typedef void (WINAPI *PAcquireSRWLockShared)(PSRWLOCK); +typedef void (WINAPI *PReleaseSRWLockShared)(PSRWLOCK); + + +class RWLockWindows :public RWLockWrapper +{ +public: + RWLockWindows(); + virtual ~RWLockWindows(); + + virtual void AcquireLockExclusive(); + virtual void ReleaseLockExclusive(); + + virtual void AcquireLockShared(); + virtual void ReleaseLockShared(); + +protected: + virtual int Init(); + +private: + // For native implementation. + static bool _winSupportRWLockPrimitive; + SRWLOCK _lock; + + // Genric implementation, fallback if native is not supported. + CriticalSectionWrapper* _critSectPtr; + ConditionVariableWrapper* _readCondPtr; + ConditionVariableWrapper* _writeCondPtr; + + int _readersActive; + bool _writerActive; + int _readersWaiting; + int _writersWaiting; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_WINDOWS_H_ diff --git a/src/libs/webrtc/system_wrappers/rw_lock_wrapper.h b/src/libs/webrtc/system_wrappers/rw_lock_wrapper.h new file mode 100644 index 00000000..f0842ac8 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/rw_lock_wrapper.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_RW_LOCK_WRAPPER_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_RW_LOCK_WRAPPER_H_ + +// Note, Windows pre-Vista version of RW locks are not supported nativly. For +// these OSs regular critical sections have been used to approximate RW lock +// functionality and will therefore have worse performance. + +namespace webrtc { +class RWLockWrapper +{ +public: + static RWLockWrapper* CreateRWLock(); + virtual ~RWLockWrapper(); + + virtual void AcquireLockExclusive() = 0; + virtual void ReleaseLockExclusive() = 0; + + virtual void AcquireLockShared() = 0; + virtual void ReleaseLockShared() = 0; + +protected: + virtual int Init() = 0; +}; + +// RAII extensions of the RW lock. Prevents Acquire/Release missmatches and +// provides more compact locking syntax. +class ReadLockScoped +{ +public: + ReadLockScoped(RWLockWrapper& rwLock) + : + _rwLock(rwLock) + { + _rwLock.AcquireLockShared(); + } + + ~ReadLockScoped() + { + _rwLock.ReleaseLockShared(); + } + +private: + RWLockWrapper& _rwLock; +}; + +class WriteLockScoped +{ +public: + WriteLockScoped(RWLockWrapper& rwLock) + : + _rwLock(rwLock) + { + _rwLock.AcquireLockExclusive(); + } + + ~WriteLockScoped() + { + _rwLock.ReleaseLockExclusive(); + } + +private: + RWLockWrapper& _rwLock; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_RW_LOCK_WRAPPER_H_ diff --git a/src/libs/webrtc/system_wrappers/sort.cc b/src/libs/webrtc/system_wrappers/sort.cc new file mode 100644 index 00000000..0584b809 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/sort.cc @@ -0,0 +1,551 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// When the platform supports STL, the functions are implemented using a +// templated spreadsort algorithm (http://sourceforge.net/projects/spreadsort/), +// part of the Boost C++ library collection. Otherwise, the C standard library's +// qsort() will be used. + +#include "sort.h" + +#include <cassert> +#include <cstring> // memcpy +#include <new> // nothrow new + +#ifdef NO_STL +#include <cstdlib> // qsort +#else +#include <algorithm> // std::sort +#include <vector> +#include "spreadsortlib/spreadsort.hpp" // TODO (ajm) upgrade to spreadsortv2. +#endif + +#ifdef NO_STL +#define COMPARE_DEREFERENCED(XT, YT) \ + do \ + { \ + if ((XT) > (YT)) \ + { \ + return 1; \ + } \ + else if ((XT) < (YT)) \ + { \ + return -1; \ + } \ + \ + return 0; \ + } \ + while(0) + +#define COMPARE_FOR_QSORT(X, Y, TYPE) \ + do \ + { \ + TYPE xT = static_cast<TYPE>(*static_cast<const TYPE*>(X)); \ + TYPE yT = static_cast<TYPE>(*static_cast<const TYPE*>(Y)); \ + COMPARE_DEREFERENCED(xT, yT); \ + } \ + while(0) + +#define COMPARE_KEY_FOR_QSORT(SORT_KEY_X, SORT_KEY_Y, TYPE) \ + do \ + { \ + TYPE xT = static_cast<TYPE>(*static_cast<TYPE*> \ + (static_cast<const SortKey*>(SORT_KEY_X)->key)); \ + TYPE yT = static_cast<TYPE>(*static_cast<TYPE*> \ + (static_cast<const SortKey*>(SORT_KEY_Y)->key)); \ + COMPARE_DEREFERENCED(xT, yT); \ + } \ + while(0) + +#define KEY_QSORT(SORT_KEY, KEY, NUM_OF_ELEMENTS, KEY_TYPE, COMPARE_FUNC) \ + do \ + { \ + KEY_TYPE* keyT = (KEY_TYPE*)(key); \ + for (WebRtc_UWord32 i = 0; i < (NUM_OF_ELEMENTS); i++) \ + { \ + ptrSortKey[i].key = &keyT[i]; \ + ptrSortKey[i].index = i; \ + } \ + \ + qsort((SORT_KEY), (NUM_OF_ELEMENTS), sizeof(SortKey), (COMPARE_FUNC));\ + } \ + while(0) +#endif + +namespace webrtc +{ +#ifdef NO_STL + struct SortKey + { + void* key; + WebRtc_UWord32 index; + }; +#else + template<typename KeyType> + struct SortKey + { + KeyType key; + WebRtc_UWord32 index; + }; +#endif + + namespace // Unnamed namespace provides internal linkage. + { +#ifdef NO_STL + int CompareWord8(const void* x, const void* y) + { + COMPARE_FOR_QSORT(x, y, WebRtc_Word8); + } + + int CompareUWord8(const void* x, const void* y) + { + COMPARE_FOR_QSORT(x, y, WebRtc_UWord8); + } + + int CompareWord16(const void* x, const void* y) + { + COMPARE_FOR_QSORT(x, y, WebRtc_Word16); + } + + int CompareUWord16(const void* x, const void* y) + { + COMPARE_FOR_QSORT(x, y, WebRtc_UWord16); + } + + int CompareWord32(const void* x, const void* y) + { + COMPARE_FOR_QSORT(x, y, WebRtc_Word32); + } + + int CompareUWord32(const void* x, const void* y) + { + COMPARE_FOR_QSORT(x, y, WebRtc_UWord32); + } + + int CompareWord64(const void* x, const void* y) + { + COMPARE_FOR_QSORT(x, y, WebRtc_Word64); + } + + int CompareUWord64(const void* x, const void* y) + { + COMPARE_FOR_QSORT(x, y, WebRtc_UWord64); + } + + int CompareFloat32(const void* x, const void* y) + { + COMPARE_FOR_QSORT(x, y, float); + } + + int CompareFloat64(const void* x, const void* y) + { + COMPARE_FOR_QSORT(x, y, double); + } + + int CompareKeyWord8(const void* sortKeyX, const void* sortKeyY) + { + COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_Word8); + } + + int CompareKeyUWord8(const void* sortKeyX, const void* sortKeyY) + { + COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_UWord8); + } + + int CompareKeyWord16(const void* sortKeyX, const void* sortKeyY) + { + COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_Word16); + } + + int CompareKeyUWord16(const void* sortKeyX, const void* sortKeyY) + { + COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_UWord16); + } + + int CompareKeyWord32(const void* sortKeyX, const void* sortKeyY) + { + COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_Word32); + } + + int CompareKeyUWord32(const void* sortKeyX, const void* sortKeyY) + { + COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_UWord32); + } + + int CompareKeyWord64(const void* sortKeyX, const void* sortKeyY) + { + COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_Word64); + } + + int CompareKeyUWord64(const void* sortKeyX, const void* sortKeyY) + { + COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_UWord64); + } + + int CompareKeyFloat32(const void* sortKeyX, const void* sortKeyY) + { + COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, float); + } + + int CompareKeyFloat64(const void* sortKeyX, const void* sortKeyY) + { + COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, double); + } +#else + template <typename KeyType> + struct KeyLessThan + { + bool operator()(const SortKey<KeyType>& sortKeyX, + const SortKey<KeyType>& sortKeyY) const + { + return sortKeyX.key < sortKeyY.key; + } + }; + + template <typename KeyType> + struct KeyRightShift + { + KeyType operator()(const SortKey<KeyType>& sortKey, + const unsigned offset) const + { + return sortKey.key >> offset; + } + }; + + template <typename DataType> + inline void IntegerSort(void* data, WebRtc_UWord32 numOfElements) + { + DataType* dataT = static_cast<DataType*>(data); + boost::integer_sort(dataT, dataT + numOfElements); + } + + template <typename DataType, typename IntegerType> + inline void FloatSort(void* data, WebRtc_UWord32 numOfElements) + { + DataType* dataT = static_cast<DataType*>(data); + IntegerType cVal = 0; + boost::float_sort_cast(dataT, dataT + numOfElements, cVal); + } + + template <typename DataType> + inline void StdSort(void* data, WebRtc_UWord32 numOfElements) + { + DataType* dataT = static_cast<DataType*>(data); + std::sort(dataT, dataT + numOfElements); + } + + template<typename KeyType> + inline WebRtc_Word32 SetupKeySort(void* key, + SortKey<KeyType>*& ptrSortKey, + WebRtc_UWord32 numOfElements) + { + ptrSortKey = new(std::nothrow) SortKey<KeyType>[numOfElements]; + if (ptrSortKey == NULL) + { + return -1; + } + + KeyType* keyT = static_cast<KeyType*>(key); + for (WebRtc_UWord32 i = 0; i < numOfElements; i++) + { + ptrSortKey[i].key = keyT[i]; + ptrSortKey[i].index = i; + } + + return 0; + } + + template<typename KeyType> + inline WebRtc_Word32 TeardownKeySort(void* data, + SortKey<KeyType>* ptrSortKey, + WebRtc_UWord32 numOfElements, WebRtc_UWord32 sizeOfElement) + { + WebRtc_UWord8* ptrData = static_cast<WebRtc_UWord8*>(data); + WebRtc_UWord8* ptrDataSorted = new(std::nothrow) WebRtc_UWord8 + [numOfElements * sizeOfElement]; + if (ptrDataSorted == NULL) + { + return -1; + } + + for (WebRtc_UWord32 i = 0; i < numOfElements; i++) + { + memcpy(ptrDataSorted + i * sizeOfElement, ptrData + + ptrSortKey[i].index * sizeOfElement, sizeOfElement); + } + memcpy(ptrData, ptrDataSorted, numOfElements * sizeOfElement); + delete[] ptrSortKey; + delete[] ptrDataSorted; + return 0; + } + + template<typename KeyType> + inline WebRtc_Word32 IntegerKeySort(void* data, void* key, + WebRtc_UWord32 numOfElements, + WebRtc_UWord32 sizeOfElement) + { + SortKey<KeyType>* ptrSortKey; + if (SetupKeySort<KeyType>(key, ptrSortKey, numOfElements) != 0) + { + return -1; + } + + boost::integer_sort(ptrSortKey, ptrSortKey + numOfElements, + KeyRightShift<KeyType>(), KeyLessThan<KeyType>()); + + if (TeardownKeySort<KeyType>(data, ptrSortKey, numOfElements, + sizeOfElement) != 0) + { + return -1; + } + + return 0; + } + + template<typename KeyType> + inline WebRtc_Word32 StdKeySort(void* data, void* key, + WebRtc_UWord32 numOfElements, + WebRtc_UWord32 sizeOfElement) + { + SortKey<KeyType>* ptrSortKey; + if (SetupKeySort<KeyType>(key, ptrSortKey, numOfElements) != 0) + { + return -1; + } + + std::sort(ptrSortKey, ptrSortKey + numOfElements, + KeyLessThan<KeyType>()); + + if (TeardownKeySort<KeyType>(data, ptrSortKey, numOfElements, + sizeOfElement) != 0) + { + return -1; + } + + return 0; + } +#endif + } + + WebRtc_Word32 Sort(void* data, WebRtc_UWord32 numOfElements, Type type) + { + if (data == NULL) + { + return -1; + } + +#ifdef NO_STL + switch (type) + { + case TYPE_Word8: + qsort(data, numOfElements, sizeof(WebRtc_Word8), CompareWord8); + break; + case TYPE_UWord8: + qsort(data, numOfElements, sizeof(WebRtc_UWord8), CompareUWord8); + break; + case TYPE_Word16: + qsort(data, numOfElements, sizeof(WebRtc_Word16), CompareWord16); + break; + case TYPE_UWord16: + qsort(data, numOfElements, sizeof(WebRtc_UWord16), CompareUWord16); + break; + case TYPE_Word32: + qsort(data, numOfElements, sizeof(WebRtc_Word32), CompareWord32); + break; + case TYPE_UWord32: + qsort(data, numOfElements, sizeof(WebRtc_UWord32), CompareUWord32); + break; + case TYPE_Word64: + qsort(data, numOfElements, sizeof(WebRtc_Word64), CompareWord64); + break; + case TYPE_UWord64: + qsort(data, numOfElements, sizeof(WebRtc_UWord64), CompareUWord64); + break; + case TYPE_Float32: + qsort(data, numOfElements, sizeof(float), CompareFloat32); + break; + case TYPE_Float64: + qsort(data, numOfElements, sizeof(double), CompareFloat64); + break; + default: + return -1; + } +#else + // Fall back to std::sort for 64-bit types and floats due to compiler + // warnings and VS 2003 build crashes respectively with spreadsort. + switch (type) + { + case TYPE_Word8: + IntegerSort<WebRtc_Word8>(data, numOfElements); + break; + case TYPE_UWord8: + IntegerSort<WebRtc_UWord8>(data, numOfElements); + break; + case TYPE_Word16: + IntegerSort<WebRtc_Word16>(data, numOfElements); + break; + case TYPE_UWord16: + IntegerSort<WebRtc_UWord16>(data, numOfElements); + break; + case TYPE_Word32: + IntegerSort<WebRtc_Word32>(data, numOfElements); + break; + case TYPE_UWord32: + IntegerSort<WebRtc_UWord32>(data, numOfElements); + break; + case TYPE_Word64: + StdSort<WebRtc_Word64>(data, numOfElements); + break; + case TYPE_UWord64: + StdSort<WebRtc_UWord64>(data, numOfElements); + break; + case TYPE_Float32: + StdSort<float>(data, numOfElements); + break; + case TYPE_Float64: + StdSort<double>(data, numOfElements); + break; + default: + return -1; + } +#endif + return 0; + } + + WebRtc_Word32 KeySort(void* data, void* key, WebRtc_UWord32 numOfElements, + WebRtc_UWord32 sizeOfElement, Type keyType) + { + if (data == NULL) + { + return -1; + } + + if (key == NULL) + { + return -1; + } + + if ((WebRtc_UWord64)numOfElements * sizeOfElement > 0xffffffff) + { + return -1; + } + +#ifdef NO_STL + SortKey* ptrSortKey = new(std::nothrow) SortKey[numOfElements]; + if (ptrSortKey == NULL) + { + return -1; + } + + switch (keyType) + { + case TYPE_Word8: + KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_Word8, + CompareKeyWord8); + break; + case TYPE_UWord8: + KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_UWord8, + CompareKeyUWord8); + break; + case TYPE_Word16: + KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_Word16, + CompareKeyWord16); + break; + case TYPE_UWord16: + KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_UWord16, + CompareKeyUWord16); + break; + case TYPE_Word32: + KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_Word32, + CompareKeyWord32); + break; + case TYPE_UWord32: + KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_UWord32, + CompareKeyUWord32); + break; + case TYPE_Word64: + KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_Word64, + CompareKeyWord64); + break; + case TYPE_UWord64: + KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_UWord64, + CompareKeyUWord64); + break; + case TYPE_Float32: + KEY_QSORT(ptrSortKey, key, numOfElements, float, + CompareKeyFloat32); + break; + case TYPE_Float64: + KEY_QSORT(ptrSortKey, key, numOfElements, double, + CompareKeyFloat64); + break; + default: + return -1; + } + + // Shuffle into sorted position based on index map. + WebRtc_UWord8* ptrData = static_cast<WebRtc_UWord8*>(data); + WebRtc_UWord8* ptrDataSorted = new(std::nothrow) WebRtc_UWord8 + [numOfElements * sizeOfElement]; + if (ptrDataSorted == NULL) + { + return -1; + } + + for (WebRtc_UWord32 i = 0; i < numOfElements; i++) + { + memcpy(ptrDataSorted + i * sizeOfElement, ptrData + + ptrSortKey[i].index * sizeOfElement, sizeOfElement); + } + memcpy(ptrData, ptrDataSorted, numOfElements * sizeOfElement); + + delete[] ptrSortKey; + delete[] ptrDataSorted; + + return 0; +#else + // Fall back to std::sort for 64-bit types and floats due to compiler + // warnings and errors respectively with spreadsort. + switch (keyType) + { + case TYPE_Word8: + return IntegerKeySort<WebRtc_Word8>(data, key, numOfElements, + sizeOfElement); + case TYPE_UWord8: + return IntegerKeySort<WebRtc_UWord8>(data, key, numOfElements, + sizeOfElement); + case TYPE_Word16: + return IntegerKeySort<WebRtc_Word16>(data, key, numOfElements, + sizeOfElement); + case TYPE_UWord16: + return IntegerKeySort<WebRtc_UWord16>(data, key, numOfElements, + sizeOfElement); + case TYPE_Word32: + return IntegerKeySort<WebRtc_Word32>(data, key, numOfElements, + sizeOfElement); + case TYPE_UWord32: + return IntegerKeySort<WebRtc_UWord32>(data, key, numOfElements, + sizeOfElement); + case TYPE_Word64: + return StdKeySort<WebRtc_Word64>(data, key, numOfElements, + sizeOfElement); + case TYPE_UWord64: + return StdKeySort<WebRtc_UWord64>(data, key, numOfElements, + sizeOfElement); + case TYPE_Float32: + return StdKeySort<float>(data, key, numOfElements, sizeOfElement); + case TYPE_Float64: + return StdKeySort<double>(data, key, numOfElements, sizeOfElement); + default: + return -1; + } +#endif + } +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/sort.h b/src/libs/webrtc/system_wrappers/sort.h new file mode 100644 index 00000000..fb25ecfc --- /dev/null +++ b/src/libs/webrtc/system_wrappers/sort.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// Generic unstable sorting routines. + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SORT_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SORT_H_ + +#include "typedefs.h" +#include "common_types.h" + +namespace webrtc +{ + enum Type + { + TYPE_Word8, + TYPE_UWord8, + TYPE_Word16, + TYPE_UWord16, + TYPE_Word32, + TYPE_UWord32, + TYPE_Word64, + TYPE_UWord64, + TYPE_Float32, + TYPE_Float64 + }; + // Sorts intrinsic data types. + // + // data [in/out] A pointer to an array of intrinsic type. + // Upon return it will be sorted in ascending order. + // numOfElements The number of elements in the array. + // dataType Enum corresponding to the type of the array. + // + // returns 0 on success, -1 on failure. + WebRtc_Word32 Sort(void* data, WebRtc_UWord32 numOfElements, Type dataType); + + // Sorts arbitrary data types. This requires an array of intrinsically typed + // key values which will be used to sort the data array. There must be a + // one-to-one correspondence between data elements and key elements, with + // corresponding elements sharing the same position in their respective + // arrays. + // + // data [in/out] A pointer to an array of arbitrary type. + // Upon return it will be sorted in ascending order. + // key [in] A pointer to an array of keys used to sort the + // data array. + // numOfElements The number of elements in the arrays. + // sizeOfElement The size, in bytes, of the data array. + // keyType Enum corresponding to the type of the key array. + // + // returns 0 on success, -1 on failure. + // + WebRtc_Word32 KeySort(void* data, void* key, WebRtc_UWord32 numOfElements, + WebRtc_UWord32 sizeOfElement, Type keyType); +} + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SORT_H_ diff --git a/src/libs/webrtc/system_wrappers/spreadsortlib/constants.hpp b/src/libs/webrtc/system_wrappers/spreadsortlib/constants.hpp new file mode 100644 index 00000000..a41b0c44 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/spreadsortlib/constants.hpp @@ -0,0 +1,42 @@ +/*Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE.*/ +#ifndef BOOST_SPREADSORT_CONSTANTS +#define BOOST_SPREADSORT_CONSTANTS +namespace boost { +namespace detail { +//Tuning constants +//Sets the minimum number of items per bin. +static const unsigned LOG_MEAN_BIN_SIZE = 2; +//This should be tuned to your processor cache; if you go too large you get cache misses on bins +//The smaller this number, the less worst-case memory usage. If too small, too many recursions slow down spreadsort +static const unsigned MAX_SPLITS = 10; +//Used to force a comparison-based sorting for small bins, if it's faster. Minimum value 0 +static const unsigned LOG_MIN_SPLIT_COUNT = 5; +//There is a minimum size below which it is not worth using spreadsort +static const long MIN_SORT_SIZE = 1000; +//This is the constant on the log base n of m calculation; make this larger the faster std::sort is relative to spreadsort +static const unsigned LOG_CONST = 2; +} +} +#endif diff --git a/src/libs/webrtc/system_wrappers/spreadsortlib/spreadsort.hpp b/src/libs/webrtc/system_wrappers/spreadsortlib/spreadsort.hpp new file mode 100644 index 00000000..cfa75cd9 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/spreadsortlib/spreadsort.hpp @@ -0,0 +1,1688 @@ +//Templated spread_sort library + +// Copyright Steven J. Ross 2001 - 2009. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +/* +Some improvements suggested by: +Phil Endecott and Frank Gennari +Cygwin fix provided by: +Scott McMurray +*/ + +#ifndef BOOST_SPREAD_SORT_H +#define BOOST_SPREAD_SORT_H +#include <algorithm> +#include <vector> +#include "constants.hpp" +#include <cstring> + +namespace boost { + namespace detail { + //This only works on unsigned data types + template <typename T> + inline unsigned + rough_log_2_size(const T& input) + { + unsigned result = 0; + //The && is necessary on some compilers to avoid infinite loops; it doesn't significantly impair performance + while((input >> result) && (result < (8*sizeof(T)))) ++result; + return result; + } + + //Gets the maximum size which we'll call spread_sort on to control worst-case performance + //Maintains both a minimum size to recurse and a check of distribution size versus count + //This is called for a set of bins, instead of bin-by-bin, to avoid performance overhead + inline size_t + get_max_count(unsigned log_range, size_t count) + { + unsigned divisor = rough_log_2_size(count); + //Making sure the divisor is positive + if(divisor > LOG_MEAN_BIN_SIZE) + divisor -= LOG_MEAN_BIN_SIZE; + else + divisor = 1; + unsigned relative_width = (LOG_CONST * log_range)/((divisor > MAX_SPLITS) ? MAX_SPLITS : divisor); + //Don't try to bitshift more than the size of an element + if((8*sizeof(size_t)) <= relative_width) + relative_width = (8*sizeof(size_t)) - 1; + return (size_t)1 << ((relative_width < (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT)) ? + (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT) : relative_width); + } + + //Find the minimum and maximum using < + template <class RandomAccessIter> + inline void + find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min) + { + min = max = current; + //Start from the second item, as max and min are initialized to the first + while(++current < last) { + if(*max < *current) + max = current; + else if(*current < *min) + min = current; + } + } + + //Uses a user-defined comparison operator to find minimum and maximum + template <class RandomAccessIter, class compare> + inline void + find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min, compare comp) + { + min = max = current; + while(++current < last) { + if(comp(*max, *current)) + max = current; + else if(comp(*current, *min)) + min = current; + } + } + + //Gets a non-negative right bit shift to operate as a logarithmic divisor + inline int + get_log_divisor(size_t count, unsigned log_range) + { + int log_divisor; + //If we can finish in one iteration without exceeding either (2 to the MAX_SPLITS) or n bins, do so + if((log_divisor = log_range - rough_log_2_size(count)) <= 0 && log_range < MAX_SPLITS) + log_divisor = 0; + else { + //otherwise divide the data into an optimized number of pieces + log_divisor += LOG_MEAN_BIN_SIZE; + if(log_divisor < 0) + log_divisor = 0; + //Cannot exceed MAX_SPLITS or cache misses slow down bin lookups dramatically + if((log_range - log_divisor) > MAX_SPLITS) + log_divisor = log_range - MAX_SPLITS; + } + return log_divisor; + } + + template <class RandomAccessIter> + inline RandomAccessIter * + size_bins(std::vector<size_t> &bin_sizes, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset, unsigned &cache_end, unsigned bin_count) + { + //Assure space for the size of each bin, followed by initializing sizes + if(bin_count > bin_sizes.size()) + bin_sizes.resize(bin_count); + for(size_t u = 0; u < bin_count; u++) + bin_sizes[u] = 0; + //Make sure there is space for the bins + cache_end = cache_offset + bin_count; + if(cache_end > bin_cache.size()) + bin_cache.resize(cache_end); + return &(bin_cache[cache_offset]); + } + + //Implementation for recursive integer sorting + template <class RandomAccessIter, class div_type, class data_type> + inline void + spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset + , std::vector<size_t> &bin_sizes) + { + //This step is roughly 10% of runtime, but it helps avoid worst-case behavior and improve behavior with real data + //If you know the maximum and minimum ahead of time, you can pass those values in and skip this step for the first iteration + RandomAccessIter max, min; + find_extremes(first, last, max, min); + //max and min will be the same (the first item) iff all values are equivalent + if(max == min) + return; + RandomAccessIter * target_bin; + unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(*max >> 0) - (*min >> 0))); + div_type div_min = *min >> log_divisor; + div_type div_max = *max >> log_divisor; + unsigned bin_count = div_max - div_min + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); + + //Calculating the size of each bin; this takes roughly 10% of runtime + for (RandomAccessIter current = first; current != last;) + bin_sizes[(*(current++) >> log_divisor) - div_min]++; + //Assign the bin positions + bins[0] = first; + for(unsigned u = 0; u < bin_count - 1; u++) + bins[u + 1] = bins[u] + bin_sizes[u]; + + //Swap into place + //This dominates runtime, mostly in the swap and bin lookups + RandomAccessIter nextbinstart = first; + for(unsigned u = 0; u < bin_count - 1; ++u) { + RandomAccessIter * local_bin = bins + u; + nextbinstart += bin_sizes[u]; + //Iterating over each element in this bin + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + //Swapping elements in current into place until the correct element has been swapped in + for(target_bin = (bins + ((*current >> log_divisor) - div_min)); target_bin != local_bin; + target_bin = bins + ((*current >> log_divisor) - div_min)) { + //3-way swap; this is about 1% faster than a 2-way swap with integers + //The main advantage is less copies are involved per item put in the correct place + data_type tmp; + RandomAccessIter b = (*target_bin)++; + RandomAccessIter * b_bin = bins + ((*b >> log_divisor) - div_min); + if (b_bin != local_bin) { + RandomAccessIter c = (*b_bin)++; + tmp = *c; + *c = *b; + } + else + tmp = *b; + *b = *current; + *current = tmp; + } + } + *local_bin = nextbinstart; + } + bins[bin_count - 1] = last; + + //If we've bucketsorted, the array is sorted and we should skip recursion + if(!log_divisor) + return; + + //Recursing; log_divisor is the remaining range + size_t max_count = get_max_count(log_divisor, last - first); + RandomAccessIter lastPos = first; + for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { + size_t count = bin_cache[u] - lastPos; + //don't sort unless there are at least two items to compare + if(count < 2) + continue; + //using std::sort if its worst-case is better + if(count < max_count) + std::sort(lastPos, bin_cache[u]); + else + spread_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes); + } + } + + //Generic bitshift-based 3-way swapping code + template <class RandomAccessIter, class div_type, class data_type, class right_shift> + inline void inner_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift + , const unsigned log_divisor, const div_type div_min) + { + RandomAccessIter * local_bin = bins + ii; + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + for(RandomAccessIter * target_bin = (bins + (shift(*current, log_divisor) - div_min)); target_bin != local_bin; + target_bin = bins + (shift(*current, log_divisor) - div_min)) { + data_type tmp; + RandomAccessIter b = (*target_bin)++; + RandomAccessIter * b_bin = bins + (shift(*b, log_divisor) - div_min); + //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs + if (b_bin != local_bin) { + RandomAccessIter c = (*b_bin)++; + tmp = *c; + *c = *b; + } + //Note: we could increment current once the swap is done in this case, but that seems to impair performance + else + tmp = *b; + *b = *current; + *current = tmp; + } + } + *local_bin = nextbinstart; + } + + //Standard swapping wrapper for ascending values + template <class RandomAccessIter, class div_type, class data_type, class right_shift> + inline void swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift + , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min) + { + nextbinstart += bin_sizes[ii]; + inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, log_divisor, div_min); + } + + //Functor implementation for recursive sorting + template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> + inline void + spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset + , std::vector<size_t> &bin_sizes, right_shift shift, compare comp) + { + RandomAccessIter max, min; + find_extremes(first, last, max, min, comp); + if(max == min) + return; + unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0)))); + div_type div_min = shift(*min, log_divisor); + div_type div_max = shift(*max, log_divisor); + unsigned bin_count = div_max - div_min + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); + + //Calculating the size of each bin + for (RandomAccessIter current = first; current != last;) + bin_sizes[shift(*(current++), log_divisor) - div_min]++; + bins[0] = first; + for(unsigned u = 0; u < bin_count - 1; u++) + bins[u + 1] = bins[u] + bin_sizes[u]; + + //Swap into place + RandomAccessIter nextbinstart = first; + for(unsigned u = 0; u < bin_count - 1; ++u) + swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, bin_sizes, log_divisor, div_min); + bins[bin_count - 1] = last; + + //If we've bucketsorted, the array is sorted and we should skip recursion + if(!log_divisor) + return; + + //Recursing + size_t max_count = get_max_count(log_divisor, last - first); + RandomAccessIter lastPos = first; + for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { + size_t count = bin_cache[u] - lastPos; + if(count < 2) + continue; + if(count < max_count) + std::sort(lastPos, bin_cache[u], comp); + else + spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp); + } + } + + //Functor implementation for recursive sorting with only Shift overridden + template <class RandomAccessIter, class div_type, class data_type, class right_shift> + inline void + spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset + , std::vector<size_t> &bin_sizes, right_shift shift) + { + RandomAccessIter max, min; + find_extremes(first, last, max, min); + if(max == min) + return; + unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0)))); + div_type div_min = shift(*min, log_divisor); + div_type div_max = shift(*max, log_divisor); + unsigned bin_count = div_max - div_min + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); + + //Calculating the size of each bin + for (RandomAccessIter current = first; current != last;) + bin_sizes[shift(*(current++), log_divisor) - div_min]++; + bins[0] = first; + for(unsigned u = 0; u < bin_count - 1; u++) + bins[u + 1] = bins[u] + bin_sizes[u]; + + //Swap into place + RandomAccessIter nextbinstart = first; + for(unsigned ii = 0; ii < bin_count - 1; ++ii) + swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min); + bins[bin_count - 1] = last; + + //If we've bucketsorted, the array is sorted and we should skip recursion + if(!log_divisor) + return; + + //Recursing + size_t max_count = get_max_count(log_divisor, last - first); + RandomAccessIter lastPos = first; + for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { + size_t count = bin_cache[u] - lastPos; + if(count < 2) + continue; + if(count < max_count) + std::sort(lastPos, bin_cache[u]); + else + spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift); + } + } + + //Holds the bin vector and makes the initial recursive call + template <class RandomAccessIter, class div_type, class data_type> + inline void + spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type) + { + std::vector<size_t> bin_sizes; + std::vector<RandomAccessIter> bin_cache; + spread_sort_rec<RandomAccessIter, div_type, data_type>(first, last, bin_cache, 0, bin_sizes); + } + + template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> + inline void + spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp) + { + std::vector<size_t> bin_sizes; + std::vector<RandomAccessIter> bin_cache; + spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(first, last, bin_cache, 0, bin_sizes, shift, comp); + } + + template <class RandomAccessIter, class div_type, class data_type, class right_shift> + inline void + spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift) + { + std::vector<size_t> bin_sizes; + std::vector<RandomAccessIter> bin_cache; + spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift); + } + } + + //Top-level sorting call for integers + template <class RandomAccessIter> + inline void integer_sort(RandomAccessIter first, RandomAccessIter last) + { + //Don't sort if it's too small to optimize + if(last - first < detail::MIN_SORT_SIZE) + std::sort(first, last); + else + detail::spread_sort(first, last, *first >> 0, *first); + } + + //integer_sort with functors + template <class RandomAccessIter, class right_shift, class compare> + inline void integer_sort(RandomAccessIter first, RandomAccessIter last, + right_shift shift, compare comp) { + if(last - first < detail::MIN_SORT_SIZE) + std::sort(first, last, comp); + else + detail::spread_sort(first, last, shift(*first, 0), *first, shift, comp); + } + + //integer_sort with right_shift functor + template <class RandomAccessIter, class right_shift> + inline void integer_sort(RandomAccessIter first, RandomAccessIter last, + right_shift shift) { + if(last - first < detail::MIN_SORT_SIZE) + std::sort(first, last); + else + detail::spread_sort(first, last, shift(*first, 0), *first, shift); + } + + //------------------------------------------------------ float_sort source -------------------------------------- + //Casts a RandomAccessIter to the specified data type + template<class cast_type, class RandomAccessIter> + inline cast_type + cast_float_iter(const RandomAccessIter & floatiter) + { + cast_type result; + std::memcpy(&result, &(*floatiter), sizeof(cast_type)); + return result; + } + + //Casts a data element to the specified datinner_float_a type + template<class data_type, class cast_type> + inline cast_type + mem_cast(const data_type & data) + { + cast_type result; + std::memcpy(&result, &data, sizeof(cast_type)); + return result; + } + + namespace detail { + template <class RandomAccessIter, class div_type, class right_shift> + inline void + find_extremes(RandomAccessIter current, RandomAccessIter last, div_type & max, div_type & min, right_shift shift) + { + min = max = shift(*current, 0); + while(++current < last) { + div_type value = shift(*current, 0); + if(max < value) + max = value; + else if(value < min) + min = value; + } + } + + //Specialized swap loops for floating-point casting + template <class RandomAccessIter, class div_type, class data_type> + inline void inner_float_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii + , const unsigned log_divisor, const div_type div_min) + { + RandomAccessIter * local_bin = bins + ii; + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + for(RandomAccessIter * target_bin = (bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)); target_bin != local_bin; + target_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)) { + data_type tmp; + RandomAccessIter b = (*target_bin)++; + RandomAccessIter * b_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(b) >> log_divisor) - div_min); + //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs + if (b_bin != local_bin) { + RandomAccessIter c = (*b_bin)++; + tmp = *c; + *c = *b; + } + else + tmp = *b; + *b = *current; + *current = tmp; + } + } + *local_bin = nextbinstart; + } + + template <class RandomAccessIter, class div_type, class data_type> + inline void float_swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii + , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min) + { + nextbinstart += bin_sizes[ii]; + inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, log_divisor, div_min); + } + + template <class RandomAccessIter, class cast_type> + inline void + find_extremes(RandomAccessIter current, RandomAccessIter last, cast_type & max, cast_type & min) + { + min = max = cast_float_iter<cast_type, RandomAccessIter>(current); + while(++current < last) { + cast_type value = cast_float_iter<cast_type, RandomAccessIter>(current); + if(max < value) + max = value; + else if(value < min) + min = value; + } + } + + //Special-case sorting of positive floats with casting instead of a right_shift + template <class RandomAccessIter, class div_type, class data_type> + inline void + positive_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset + , std::vector<size_t> &bin_sizes) + { + div_type max, min; + find_extremes(first, last, max, min); + if(max == min) + return; + unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); + div_type div_min = min >> log_divisor; + div_type div_max = max >> log_divisor; + unsigned bin_count = div_max - div_min + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); + + //Calculating the size of each bin + for (RandomAccessIter current = first; current != last;) + bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++; + bins[0] = first; + for(unsigned u = 0; u < bin_count - 1; u++) + bins[u + 1] = bins[u] + bin_sizes[u]; + + //Swap into place + RandomAccessIter nextbinstart = first; + for(unsigned u = 0; u < bin_count - 1; ++u) + float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, bin_sizes, log_divisor, div_min); + bins[bin_count - 1] = last; + + //Return if we've completed bucketsorting + if(!log_divisor) + return; + + //Recursing + size_t max_count = get_max_count(log_divisor, last - first); + RandomAccessIter lastPos = first; + for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { + size_t count = bin_cache[u] - lastPos; + if(count < 2) + continue; + if(count < max_count) + std::sort(lastPos, bin_cache[u]); + else + positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes); + } + } + + //Sorting negative_ float_s + //Note that bins are iterated in reverse order because max_neg_float = min_neg_int + template <class RandomAccessIter, class div_type, class data_type> + inline void + negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset + , std::vector<size_t> &bin_sizes) + { + div_type max, min; + find_extremes(first, last, max, min); + if(max == min) + return; + unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); + div_type div_min = min >> log_divisor; + div_type div_max = max >> log_divisor; + unsigned bin_count = div_max - div_min + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); + + //Calculating the size of each bin + for (RandomAccessIter current = first; current != last;) + bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++; + bins[bin_count - 1] = first; + for(int ii = bin_count - 2; ii >= 0; --ii) + bins[ii] = bins[ii + 1] + bin_sizes[ii + 1]; + + //Swap into place + RandomAccessIter nextbinstart = first; + //The last bin will always have the correct elements in it + for(int ii = bin_count - 1; ii > 0; --ii) + float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, bin_sizes, log_divisor, div_min); + //Since we don't process the last bin, we need to update its end position + bin_cache[cache_offset] = last; + + //Return if we've completed bucketsorting + if(!log_divisor) + return; + + //Recursing + size_t max_count = get_max_count(log_divisor, last - first); + RandomAccessIter lastPos = first; + for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) { + size_t count = bin_cache[ii] - lastPos; + if(count < 2) + continue; + if(count < max_count) + std::sort(lastPos, bin_cache[ii]); + else + negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes); + } + } + + //Sorting negative_ float_s + //Note that bins are iterated in reverse order because max_neg_float = min_neg_int + template <class RandomAccessIter, class div_type, class data_type, class right_shift> + inline void + negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset + , std::vector<size_t> &bin_sizes, right_shift shift) + { + div_type max, min; + find_extremes(first, last, max, min, shift); + if(max == min) + return; + unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); + div_type div_min = min >> log_divisor; + div_type div_max = max >> log_divisor; + unsigned bin_count = div_max - div_min + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); + + //Calculating the size of each bin + for (RandomAccessIter current = first; current != last;) + bin_sizes[shift(*(current++), log_divisor) - div_min]++; + bins[bin_count - 1] = first; + for(int ii = bin_count - 2; ii >= 0; --ii) + bins[ii] = bins[ii + 1] + bin_sizes[ii + 1]; + + //Swap into place + RandomAccessIter nextbinstart = first; + //The last bin will always have the correct elements in it + for(int ii = bin_count - 1; ii > 0; --ii) + swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min); + //Since we don't process the last bin, we need to update its end position + bin_cache[cache_offset] = last; + + //Return if we've completed bucketsorting + if(!log_divisor) + return; + + //Recursing + size_t max_count = get_max_count(log_divisor, last - first); + RandomAccessIter lastPos = first; + for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) { + size_t count = bin_cache[ii] - lastPos; + if(count < 2) + continue; + if(count < max_count) + std::sort(lastPos, bin_cache[ii]); + else + negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift); + } + } + + template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> + inline void + negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset + , std::vector<size_t> &bin_sizes, right_shift shift, compare comp) + { + div_type max, min; + find_extremes(first, last, max, min, shift); + if(max == min) + return; + unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); + div_type div_min = min >> log_divisor; + div_type div_max = max >> log_divisor; + unsigned bin_count = div_max - div_min + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); + + //Calculating the size of each bin + for (RandomAccessIter current = first; current != last;) + bin_sizes[shift(*(current++), log_divisor) - div_min]++; + bins[bin_count - 1] = first; + for(int ii = bin_count - 2; ii >= 0; --ii) + bins[ii] = bins[ii + 1] + bin_sizes[ii + 1]; + + //Swap into place + RandomAccessIter nextbinstart = first; + //The last bin will always have the correct elements in it + for(int ii = bin_count - 1; ii > 0; --ii) + swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min); + //Since we don't process the last bin, we need to update its end position + bin_cache[cache_offset] = last; + + //Return if we've completed bucketsorting + if(!log_divisor) + return; + + //Recursing + size_t max_count = get_max_count(log_divisor, last - first); + RandomAccessIter lastPos = first; + for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) { + size_t count = bin_cache[ii] - lastPos; + if(count < 2) + continue; + if(count < max_count) + std::sort(lastPos, bin_cache[ii], comp); + else + negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp); + } + } + + //Casting special-case for floating-point sorting + template <class RandomAccessIter, class div_type, class data_type> + inline void + float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset + , std::vector<size_t> &bin_sizes) + { + div_type max, min; + find_extremes(first, last, max, min); + if(max == min) + return; + unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); + div_type div_min = min >> log_divisor; + div_type div_max = max >> log_divisor; + unsigned bin_count = div_max - div_min + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); + + //Calculating the size of each bin + for (RandomAccessIter current = first; current != last;) + bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++; + //The index of the first positive bin + div_type first_positive = (div_min < 0) ? -div_min : 0; + //Resetting if all bins are negative + if(cache_offset + first_positive > cache_end) + first_positive = cache_end - cache_offset; + //Reversing the order of the negative bins + //Note that because of the negative/positive ordering direction flip + //We can not depend upon bin order and positions matching up + //so bin_sizes must be reused to contain the end of the bin + if(first_positive > 0) { + bins[first_positive - 1] = first; + for(int ii = first_positive - 2; ii >= 0; --ii) { + bins[ii] = first + bin_sizes[ii + 1]; + bin_sizes[ii] += bin_sizes[ii + 1]; + } + //Handling positives following negatives + if((unsigned)first_positive < bin_count) { + bins[first_positive] = first + bin_sizes[0]; + bin_sizes[first_positive] += bin_sizes[0]; + } + } + else + bins[0] = first; + for(unsigned u = first_positive; u < bin_count - 1; u++) { + bins[u + 1] = first + bin_sizes[u]; + bin_sizes[u + 1] += bin_sizes[u]; + } + + //Swap into place + RandomAccessIter nextbinstart = first; + for(unsigned u = 0; u < bin_count; ++u) { + nextbinstart = first + bin_sizes[u]; + inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, log_divisor, div_min); + } + + if(!log_divisor) + return; + + //Handling negative values first + size_t max_count = get_max_count(log_divisor, last - first); + RandomAccessIter lastPos = first; + for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) { + size_t count = bin_cache[ii] - lastPos; + if(count < 2) + continue; + if(count < max_count) + std::sort(lastPos, bin_cache[ii]); + //sort negative values using reversed-bin spread_sort + else + negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes); + } + + for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) { + size_t count = bin_cache[u] - lastPos; + if(count < 2) + continue; + if(count < max_count) + std::sort(lastPos, bin_cache[u]); + //sort positive values using normal spread_sort + else + positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes); + } + } + + //Functor implementation for recursive sorting + template <class RandomAccessIter, class div_type, class data_type, class right_shift> + inline void + float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset + , std::vector<size_t> &bin_sizes, right_shift shift) + { + div_type max, min; + find_extremes(first, last, max, min, shift); + if(max == min) + return; + unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); + div_type div_min = min >> log_divisor; + div_type div_max = max >> log_divisor; + unsigned bin_count = div_max - div_min + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); + + //Calculating the size of each bin + for (RandomAccessIter current = first; current != last;) + bin_sizes[shift(*(current++), log_divisor) - div_min]++; + //The index of the first positive bin + div_type first_positive = (div_min < 0) ? -div_min : 0; + //Resetting if all bins are negative + if(cache_offset + first_positive > cache_end) + first_positive = cache_end - cache_offset; + //Reversing the order of the negative bins + //Note that because of the negative/positive ordering direction flip + //We can not depend upon bin order and positions matching up + //so bin_sizes must be reused to contain the end of the bin + if(first_positive > 0) { + bins[first_positive - 1] = first; + for(int ii = first_positive - 2; ii >= 0; --ii) { + bins[ii] = first + bin_sizes[ii + 1]; + bin_sizes[ii] += bin_sizes[ii + 1]; + } + //Handling positives following negatives + if((unsigned)first_positive < bin_count) { + bins[first_positive] = first + bin_sizes[0]; + bin_sizes[first_positive] += bin_sizes[0]; + } + } + else + bins[0] = first; + for(unsigned u = first_positive; u < bin_count - 1; u++) { + bins[u + 1] = first + bin_sizes[u]; + bin_sizes[u + 1] += bin_sizes[u]; + } + + //Swap into place + RandomAccessIter nextbinstart = first; + for(unsigned u = 0; u < bin_count; ++u) { + nextbinstart = first + bin_sizes[u]; + inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min); + } + + //Return if we've completed bucketsorting + if(!log_divisor) + return; + + //Handling negative values first + size_t max_count = get_max_count(log_divisor, last - first); + RandomAccessIter lastPos = first; + for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) { + size_t count = bin_cache[ii] - lastPos; + if(count < 2) + continue; + if(count < max_count) + std::sort(lastPos, bin_cache[ii]); + //sort negative values using reversed-bin spread_sort + else + negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift); + } + + for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) { + size_t count = bin_cache[u] - lastPos; + if(count < 2) + continue; + if(count < max_count) + std::sort(lastPos, bin_cache[u]); + //sort positive values using normal spread_sort + else + spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift); + } + } + + template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> + inline void + float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset + , std::vector<size_t> &bin_sizes, right_shift shift, compare comp) + { + div_type max, min; + find_extremes(first, last, max, min, shift); + if(max == min) + return; + unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); + div_type div_min = min >> log_divisor; + div_type div_max = max >> log_divisor; + unsigned bin_count = div_max - div_min + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); + + //Calculating the size of each bin + for (RandomAccessIter current = first; current != last;) + bin_sizes[shift(*(current++), log_divisor) - div_min]++; + //The index of the first positive bin + div_type first_positive = (div_min < 0) ? -div_min : 0; + //Resetting if all bins are negative + if(cache_offset + first_positive > cache_end) + first_positive = cache_end - cache_offset; + //Reversing the order of the negative bins + //Note that because of the negative/positive ordering direction flip + //We can not depend upon bin order and positions matching up + //so bin_sizes must be reused to contain the end of the bin + if(first_positive > 0) { + bins[first_positive - 1] = first; + for(int ii = first_positive - 2; ii >= 0; --ii) { + bins[ii] = first + bin_sizes[ii + 1]; + bin_sizes[ii] += bin_sizes[ii + 1]; + } + //Handling positives following negatives + if((unsigned)first_positive < bin_count) { + bins[first_positive] = first + bin_sizes[0]; + bin_sizes[first_positive] += bin_sizes[0]; + } + } + else + bins[0] = first; + for(unsigned u = first_positive; u < bin_count - 1; u++) { + bins[u + 1] = first + bin_sizes[u]; + bin_sizes[u + 1] += bin_sizes[u]; + } + + //Swap into place + RandomAccessIter nextbinstart = first; + for(unsigned u = 0; u < bin_count; ++u) { + nextbinstart = first + bin_sizes[u]; + inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min); + } + + //Return if we've completed bucketsorting + if(!log_divisor) + return; + + //Handling negative values first + size_t max_count = get_max_count(log_divisor, last - first); + RandomAccessIter lastPos = first; + for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) { + size_t count = bin_cache[ii] - lastPos; + if(count < 2) + continue; + if(count < max_count) + std::sort(lastPos, bin_cache[ii]); + //sort negative values using reversed-bin spread_sort + else + negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp); + } + + for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) { + size_t count = bin_cache[u] - lastPos; + if(count < 2) + continue; + if(count < max_count) + std::sort(lastPos, bin_cache[u]); + //sort positive values using normal spread_sort + else + spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp); + } + } + + template <class RandomAccessIter, class cast_type, class data_type> + inline void + float_Sort(RandomAccessIter first, RandomAccessIter last, cast_type, data_type) + { + std::vector<size_t> bin_sizes; + std::vector<RandomAccessIter> bin_cache; + float_sort_rec<RandomAccessIter, cast_type, data_type>(first, last, bin_cache, 0, bin_sizes); + } + + template <class RandomAccessIter, class div_type, class data_type, class right_shift> + inline void + float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift) + { + std::vector<size_t> bin_sizes; + std::vector<RandomAccessIter> bin_cache; + float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift); + } + + template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> + inline void + float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp) + { + std::vector<size_t> bin_sizes; + std::vector<RandomAccessIter> bin_cache; + float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift, comp); + } + } + + //float_sort with casting + //The cast_type must be equal in size to the data type, and must be a signed integer + template <class RandomAccessIter, class cast_type> + inline void float_sort_cast(RandomAccessIter first, RandomAccessIter last, cast_type cVal) + { + if(last - first < detail::MIN_SORT_SIZE) + std::sort(first, last); + else + detail::float_Sort(first, last, cVal, *first); + } + + //float_sort with casting to an int + //Only use this with IEEE floating-point numbers + template <class RandomAccessIter> + inline void float_sort_cast_to_int(RandomAccessIter first, RandomAccessIter last) + { + int cVal = 0; + float_sort_cast(first, last, cVal); + } + + //float_sort with functors + template <class RandomAccessIter, class right_shift> + inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift) + { + if(last - first < detail::MIN_SORT_SIZE) + std::sort(first, last); + else + detail::float_Sort(first, last, shift(*first, 0), *first, shift); + } + + template <class RandomAccessIter, class right_shift, class compare> + inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift, compare comp) + { + if(last - first < detail::MIN_SORT_SIZE) + std::sort(first, last, comp); + else + detail::float_Sort(first, last, shift(*first, 0), *first, shift, comp); + } + + //------------------------------------------------- string_sort source --------------------------------------------- + namespace detail { + //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance. + template<class RandomAccessIter> + inline void + update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset) + { + unsigned nextOffset = char_offset; + bool done = false; + while(!done) { + RandomAccessIter curr = first; + do { + //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character + if((*curr).size() > char_offset && ((*curr).size() <= (nextOffset + 1) || (*curr)[nextOffset] != (*first)[nextOffset])) { + done = true; + break; + } + } while(++curr != finish); + if(!done) + ++nextOffset; + } + char_offset = nextOffset; + } + + //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance. + template<class RandomAccessIter, class get_char, class get_length> + inline void + update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset, get_char getchar, get_length length) + { + unsigned nextOffset = char_offset; + bool done = false; + while(!done) { + RandomAccessIter curr = first; + do { + //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character + if(length(*curr) > char_offset && (length(*curr) <= (nextOffset + 1) || getchar((*curr), nextOffset) != getchar((*first), nextOffset))) { + done = true; + break; + } + } while(++curr != finish); + if(!done) + ++nextOffset; + } + char_offset = nextOffset; + } + + //A comparison functor for strings that assumes they are identical up to char_offset + template<class data_type, class unsignedchar_type> + struct offset_lessthan { + offset_lessthan(unsigned char_offset) : fchar_offset(char_offset){} + inline bool operator()(const data_type &x, const data_type &y) const + { + unsigned minSize = std::min(x.size(), y.size()); + for(unsigned u = fchar_offset; u < minSize; ++u) { + if(static_cast<unsignedchar_type>(x[u]) < static_cast<unsignedchar_type>(y[u])) + return true; + else if(static_cast<unsignedchar_type>(y[u]) < static_cast<unsignedchar_type>(x[u])) + return false; + } + return x.size() < y.size(); + } + unsigned fchar_offset; + }; + + //A comparison functor for strings that assumes they are identical up to char_offset + template<class data_type, class unsignedchar_type> + struct offset_greaterthan { + offset_greaterthan(unsigned char_offset) : fchar_offset(char_offset){} + inline bool operator()(const data_type &x, const data_type &y) const + { + unsigned minSize = std::min(x.size(), y.size()); + for(unsigned u = fchar_offset; u < minSize; ++u) { + if(static_cast<unsignedchar_type>(x[u]) > static_cast<unsignedchar_type>(y[u])) + return true; + else if(static_cast<unsignedchar_type>(y[u]) > static_cast<unsignedchar_type>(x[u])) + return false; + } + return x.size() > y.size(); + } + unsigned fchar_offset; + }; + + //A comparison functor for strings that assumes they are identical up to char_offset + template<class data_type, class get_char, class get_length> + struct offset_char_lessthan { + offset_char_lessthan(unsigned char_offset) : fchar_offset(char_offset){} + inline bool operator()(const data_type &x, const data_type &y) const + { + unsigned minSize = std::min(length(x), length(y)); + for(unsigned u = fchar_offset; u < minSize; ++u) { + if(getchar(x, u) < getchar(y, u)) + return true; + else if(getchar(y, u) < getchar(x, u)) + return false; + } + return length(x) < length(y); + } + unsigned fchar_offset; + get_char getchar; + get_length length; + }; + + //String sorting recursive implementation + template <class RandomAccessIter, class data_type, class unsignedchar_type> + inline void + string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache + , unsigned cache_offset, std::vector<size_t> &bin_sizes) + { + //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. + //Iterate to the end of the empties. If all empty, return + while((*first).size() <= char_offset) { + if(++first == last) + return; + } + RandomAccessIter finish = last - 1; + //Getting the last non-empty + for(;(*finish).size() <= char_offset; --finish) { } + ++finish; + //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance. + update_offset(first, finish, char_offset); + + const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); + //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). + const unsigned max_size = bin_count; + const unsigned membin_count = bin_count + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1; + + //Calculating the size of each bin; this takes roughly 10% of runtime + for (RandomAccessIter current = first; current != last; ++current) { + if((*current).size() <= char_offset) { + bin_sizes[0]++; + } + else + bin_sizes[static_cast<unsignedchar_type>((*current)[char_offset]) + 1]++; + } + //Assign the bin positions + bin_cache[cache_offset] = first; + for(unsigned u = 0; u < membin_count - 1; u++) + bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; + + //Swap into place + RandomAccessIter nextbinstart = first; + //handling empty bins + RandomAccessIter * local_bin = &(bin_cache[cache_offset]); + nextbinstart += bin_sizes[0]; + RandomAccessIter * target_bin; + //Iterating over each element in the bin of empties + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + //empties belong in this bin + while((*current).size() > char_offset) { + target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]); + iter_swap(current, (*target_bin)++); + } + } + *local_bin = nextbinstart; + //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops + unsigned last_bin = bin_count - 1; + for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { } + //This dominates runtime, mostly in the swap and bin lookups + for(unsigned u = 0; u < last_bin; ++u) { + local_bin = bins + u; + nextbinstart += bin_sizes[u + 1]; + //Iterating over each element in this bin + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + //Swapping elements in current into place until the correct element has been swapped in + for(target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin; + target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset])) + iter_swap(current, (*target_bin)++); + } + *local_bin = nextbinstart; + } + bins[last_bin] = last; + //Recursing + RandomAccessIter lastPos = bin_cache[cache_offset]; + //Skip this loop for empties + for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) { + size_t count = bin_cache[u] - lastPos; + //don't sort unless there are at least two items to compare + if(count < 2) + continue; + //using std::sort if its worst-case is better + if(count < max_size) + std::sort(lastPos, bin_cache[u], offset_lessthan<data_type, unsignedchar_type>(char_offset + 1)); + else + string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes); + } + } + + //Sorts strings in reverse order, with empties at the end + template <class RandomAccessIter, class data_type, class unsignedchar_type> + inline void + reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache + , unsigned cache_offset, std::vector<size_t> &bin_sizes) + { + //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. + RandomAccessIter curr = first; + //Iterate to the end of the empties. If all empty, return + while((*curr).size() <= char_offset) { + if(++curr == last) + return; + } + //Getting the last non-empty + while((*(--last)).size() <= char_offset) { } + ++last; + //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance. + update_offset(curr, last, char_offset); + RandomAccessIter * target_bin; + + const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); + //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). + const unsigned max_size = bin_count; + const unsigned membin_count = bin_count + 1; + const unsigned max_bin = bin_count - 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count); + RandomAccessIter * end_bin = &(bin_cache[cache_offset + max_bin]); + + //Calculating the size of each bin; this takes roughly 10% of runtime + for (RandomAccessIter current = first; current != last; ++current) { + if((*current).size() <= char_offset) { + bin_sizes[bin_count]++; + } + else + bin_sizes[max_bin - static_cast<unsignedchar_type>((*current)[char_offset])]++; + } + //Assign the bin positions + bin_cache[cache_offset] = first; + for(unsigned u = 0; u < membin_count - 1; u++) + bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; + + //Swap into place + RandomAccessIter nextbinstart = last; + //handling empty bins + RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]); + RandomAccessIter lastFull = *local_bin; + //Iterating over each element in the bin of empties + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + //empties belong in this bin + while((*current).size() > char_offset) { + target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]); + iter_swap(current, (*target_bin)++); + } + } + *local_bin = nextbinstart; + nextbinstart = first; + //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops + unsigned last_bin = max_bin; + for(; last_bin && !bin_sizes[last_bin]; --last_bin) { } + //This dominates runtime, mostly in the swap and bin lookups + for(unsigned u = 0; u < last_bin; ++u) { + local_bin = bins + u; + nextbinstart += bin_sizes[u]; + //Iterating over each element in this bin + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + //Swapping elements in current into place until the correct element has been swapped in + for(target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin; + target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset])) + iter_swap(current, (*target_bin)++); + } + *local_bin = nextbinstart; + } + bins[last_bin] = lastFull; + //Recursing + RandomAccessIter lastPos = first; + //Skip this loop for empties + for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) { + size_t count = bin_cache[u] - lastPos; + //don't sort unless there are at least two items to compare + if(count < 2) + continue; + //using std::sort if its worst-case is better + if(count < max_size) + std::sort(lastPos, bin_cache[u], offset_greaterthan<data_type, unsignedchar_type>(char_offset + 1)); + else + reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes); + } + } + + //String sorting recursive implementation + template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length> + inline void + string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache + , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length) + { + //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. + //Iterate to the end of the empties. If all empty, return + while(length(*first) <= char_offset) { + if(++first == last) + return; + } + RandomAccessIter finish = last - 1; + //Getting the last non-empty + for(;length(*finish) <= char_offset; --finish) { } + ++finish; + update_offset(first, finish, char_offset, getchar, length); + + const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); + //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). + const unsigned max_size = bin_count; + const unsigned membin_count = bin_count + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1; + + //Calculating the size of each bin; this takes roughly 10% of runtime + for (RandomAccessIter current = first; current != last; ++current) { + if(length(*current) <= char_offset) { + bin_sizes[0]++; + } + else + bin_sizes[getchar((*current), char_offset) + 1]++; + } + //Assign the bin positions + bin_cache[cache_offset] = first; + for(unsigned u = 0; u < membin_count - 1; u++) + bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; + + //Swap into place + RandomAccessIter nextbinstart = first; + //handling empty bins + RandomAccessIter * local_bin = &(bin_cache[cache_offset]); + nextbinstart += bin_sizes[0]; + RandomAccessIter * target_bin; + //Iterating over each element in the bin of empties + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + //empties belong in this bin + while(length(*current) > char_offset) { + target_bin = bins + getchar((*current), char_offset); + iter_swap(current, (*target_bin)++); + } + } + *local_bin = nextbinstart; + //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops + unsigned last_bin = bin_count - 1; + for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { } + //This dominates runtime, mostly in the swap and bin lookups + for(unsigned ii = 0; ii < last_bin; ++ii) { + local_bin = bins + ii; + nextbinstart += bin_sizes[ii + 1]; + //Iterating over each element in this bin + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + //Swapping elements in current into place until the correct element has been swapped in + for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin; + target_bin = bins + getchar((*current), char_offset)) + iter_swap(current, (*target_bin)++); + } + *local_bin = nextbinstart; + } + bins[last_bin] = last; + + //Recursing + RandomAccessIter lastPos = bin_cache[cache_offset]; + //Skip this loop for empties + for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) { + size_t count = bin_cache[u] - lastPos; + //don't sort unless there are at least two items to compare + if(count < 2) + continue; + //using std::sort if its worst-case is better + if(count < max_size) + std::sort(lastPos, bin_cache[u], offset_char_lessthan<data_type, get_char, get_length>(char_offset + 1)); + else + string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length); + } + } + + //String sorting recursive implementation + template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare> + inline void + string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache + , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp) + { + //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. + //Iterate to the end of the empties. If all empty, return + while(length(*first) <= char_offset) { + if(++first == last) + return; + } + RandomAccessIter finish = last - 1; + //Getting the last non-empty + for(;length(*finish) <= char_offset; --finish) { } + ++finish; + update_offset(first, finish, char_offset, getchar, length); + + const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); + //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). + const unsigned max_size = bin_count; + const unsigned membin_count = bin_count + 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1; + + //Calculating the size of each bin; this takes roughly 10% of runtime + for (RandomAccessIter current = first; current != last; ++current) { + if(length(*current) <= char_offset) { + bin_sizes[0]++; + } + else + bin_sizes[getchar((*current), char_offset) + 1]++; + } + //Assign the bin positions + bin_cache[cache_offset] = first; + for(unsigned u = 0; u < membin_count - 1; u++) + bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; + + //Swap into place + RandomAccessIter nextbinstart = first; + //handling empty bins + RandomAccessIter * local_bin = &(bin_cache[cache_offset]); + nextbinstart += bin_sizes[0]; + RandomAccessIter * target_bin; + //Iterating over each element in the bin of empties + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + //empties belong in this bin + while(length(*current) > char_offset) { + target_bin = bins + getchar((*current), char_offset); + iter_swap(current, (*target_bin)++); + } + } + *local_bin = nextbinstart; + //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops + unsigned last_bin = bin_count - 1; + for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { } + //This dominates runtime, mostly in the swap and bin lookups + for(unsigned u = 0; u < last_bin; ++u) { + local_bin = bins + u; + nextbinstart += bin_sizes[u + 1]; + //Iterating over each element in this bin + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + //Swapping elements in current into place until the correct element has been swapped in + for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin; + target_bin = bins + getchar((*current), char_offset)) + iter_swap(current, (*target_bin)++); + } + *local_bin = nextbinstart; + } + bins[last_bin] = last; + + //Recursing + RandomAccessIter lastPos = bin_cache[cache_offset]; + //Skip this loop for empties + for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) { + size_t count = bin_cache[u] - lastPos; + //don't sort unless there are at least two items to compare + if(count < 2) + continue; + //using std::sort if its worst-case is better + if(count < max_size) + std::sort(lastPos, bin_cache[u], comp); + else + string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos + , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp); + } + } + + //Sorts strings in reverse order, with empties at the end + template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare> + inline void + reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache + , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp) + { + //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. + RandomAccessIter curr = first; + //Iterate to the end of the empties. If all empty, return + while(length(*curr) <= char_offset) { + if(++curr == last) + return; + } + //Getting the last non-empty + while(length(*(--last)) <= char_offset) { } + ++last; + //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance. + update_offset(first, last, char_offset, getchar, length); + + const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); + //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). + const unsigned max_size = bin_count; + const unsigned membin_count = bin_count + 1; + const unsigned max_bin = bin_count - 1; + unsigned cache_end; + RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count); + RandomAccessIter *end_bin = &(bin_cache[cache_offset + max_bin]); + + //Calculating the size of each bin; this takes roughly 10% of runtime + for (RandomAccessIter current = first; current != last; ++current) { + if(length(*current) <= char_offset) { + bin_sizes[bin_count]++; + } + else + bin_sizes[max_bin - getchar((*current), char_offset)]++; + } + //Assign the bin positions + bin_cache[cache_offset] = first; + for(unsigned u = 0; u < membin_count - 1; u++) + bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; + + //Swap into place + RandomAccessIter nextbinstart = last; + //handling empty bins + RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]); + RandomAccessIter lastFull = *local_bin; + RandomAccessIter * target_bin; + //Iterating over each element in the bin of empties + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + //empties belong in this bin + while(length(*current) > char_offset) { + target_bin = end_bin - getchar((*current), char_offset); + iter_swap(current, (*target_bin)++); + } + } + *local_bin = nextbinstart; + nextbinstart = first; + //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops + unsigned last_bin = max_bin; + for(; last_bin && !bin_sizes[last_bin]; --last_bin) { } + //This dominates runtime, mostly in the swap and bin lookups + for(unsigned u = 0; u < last_bin; ++u) { + local_bin = bins + u; + nextbinstart += bin_sizes[u]; + //Iterating over each element in this bin + for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { + //Swapping elements in current into place until the correct element has been swapped in + for(target_bin = end_bin - getchar((*current), char_offset); target_bin != local_bin; + target_bin = end_bin - getchar((*current), char_offset)) + iter_swap(current, (*target_bin)++); + } + *local_bin = nextbinstart; + } + bins[last_bin] = lastFull; + //Recursing + RandomAccessIter lastPos = first; + //Skip this loop for empties + for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) { + size_t count = bin_cache[u] - lastPos; + //don't sort unless there are at least two items to compare + if(count < 2) + continue; + //using std::sort if its worst-case is better + if(count < max_size) + std::sort(lastPos, bin_cache[u], comp); + else + reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos + , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp); + } + } + + //Holds the bin vector and makes the initial recursive call + template <class RandomAccessIter, class data_type, class unsignedchar_type> + inline void + string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type) + { + std::vector<size_t> bin_sizes; + std::vector<RandomAccessIter> bin_cache; + string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes); + } + + //Holds the bin vector and makes the initial recursive call + template <class RandomAccessIter, class data_type, class unsignedchar_type> + inline void + reverse_string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type) + { + std::vector<size_t> bin_sizes; + std::vector<RandomAccessIter> bin_cache; + reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes); + } + + //Holds the bin vector and makes the initial recursive call + template <class RandomAccessIter, class get_char, class get_length, class data_type, class unsignedchar_type> + inline void + string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, data_type, unsignedchar_type) + { + std::vector<size_t> bin_sizes; + std::vector<RandomAccessIter> bin_cache; + string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length); + } + + //Holds the bin vector and makes the initial recursive call + template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type> + inline void + string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type) + { + std::vector<size_t> bin_sizes; + std::vector<RandomAccessIter> bin_cache; + string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp); + } + + //Holds the bin vector and makes the initial recursive call + template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type> + inline void + reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type) + { + std::vector<size_t> bin_sizes; + std::vector<RandomAccessIter> bin_cache; + reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp); + } + } + + //Allows character-type overloads + template <class RandomAccessIter, class unsignedchar_type> + inline void string_sort(RandomAccessIter first, RandomAccessIter last, unsignedchar_type unused) + { + //Don't sort if it's too small to optimize + if(last - first < detail::MIN_SORT_SIZE) + std::sort(first, last); + else + detail::string_sort(first, last, *first, unused); + } + + //Top-level sorting call; wraps using default of unsigned char + template <class RandomAccessIter> + inline void string_sort(RandomAccessIter first, RandomAccessIter last) + { + unsigned char unused = '\0'; + string_sort(first, last, unused); + } + + //Allows character-type overloads + template <class RandomAccessIter, class compare, class unsignedchar_type> + inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp, unsignedchar_type unused) + { + //Don't sort if it's too small to optimize + if(last - first < detail::MIN_SORT_SIZE) + std::sort(first, last, comp); + else + detail::reverse_string_sort(first, last, *first, unused); + } + + //Top-level sorting call; wraps using default of unsigned char + template <class RandomAccessIter, class compare> + inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp) + { + unsigned char unused = '\0'; + reverse_string_sort(first, last, comp, unused); + } + + template <class RandomAccessIter, class get_char, class get_length> + inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length) + { + //Don't sort if it's too small to optimize + if(last - first < detail::MIN_SORT_SIZE) + std::sort(first, last); + else { + //skipping past empties at the beginning, which allows us to get the character type + //.empty() is not used so as not to require a user declaration of it + while(!length(*first)) { + if(++first == last) + return; + } + detail::string_sort(first, last, getchar, length, *first, getchar((*first), 0)); + } + } + + template <class RandomAccessIter, class get_char, class get_length, class compare> + inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp) + { + //Don't sort if it's too small to optimize + if(last - first < detail::MIN_SORT_SIZE) + std::sort(first, last, comp); + else { + //skipping past empties at the beginning, which allows us to get the character type + //.empty() is not used so as not to require a user declaration of it + while(!length(*first)) { + if(++first == last) + return; + } + detail::string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0)); + } + } + + template <class RandomAccessIter, class get_char, class get_length, class compare> + inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp) + { + //Don't sort if it's too small to optimize + if(last - first < detail::MIN_SORT_SIZE) + std::sort(first, last, comp); + else { + //skipping past empties at the beginning, which allows us to get the character type + //.empty() is not used so as not to require a user declaration of it + while(!length(*(--last))) { + //Note: if there is just one non-empty, and it's at the beginning, then it's already in sorted order + if(first == last) + return; + } + //making last just after the end of the non-empty part of the array + ++last; + detail::reverse_string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0)); + } + } +} + +#endif diff --git a/src/libs/webrtc/system_wrappers/thread.cc b/src/libs/webrtc/system_wrappers/thread.cc new file mode 100644 index 00000000..a136cbaf --- /dev/null +++ b/src/libs/webrtc/system_wrappers/thread.cc @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "thread_wrapper.h" + +#if defined(_WIN32) + #include "thread_windows.h" +#else + #include "thread_linux.h" +#endif + +namespace webrtc { +ThreadWrapper* ThreadWrapper::CreateThread(ThreadRunFunction func, + ThreadObj obj, ThreadPriority prio, + const char* threadName) +{ +#if defined(_WIN32) + return new ThreadWindows(func, obj, prio, threadName); +#else + return ThreadLinux::Create(func, obj, prio, threadName); +#endif +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/thread_linux.cc b/src/libs/webrtc/system_wrappers/thread_linux.cc new file mode 100644 index 00000000..b1c341bd --- /dev/null +++ b/src/libs/webrtc/system_wrappers/thread_linux.cc @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "thread_linux.h" + +#include <errno.h> +#include <string.h> // strncpy +#include <time.h> // nanosleep +#include <unistd.h> +#ifdef WEBRTC_LINUX +#include <sys/types.h> +#include <sched.h> +#include <sys/syscall.h> +#include <linux/unistd.h> +#include <sys/prctl.h> +#endif + +#include "event_wrapper.h" +#include "trace.h" + +namespace webrtc { +extern "C" +{ + static void* StartThread(void* lpParameter) + { + static_cast<ThreadLinux*>(lpParameter)->Run(); + return 0; + } +} + +#if (defined(WEBRTC_LINUX) && !defined(ANDROID)) +static pid_t gettid() +{ +#if defined(__NR_gettid) + return syscall(__NR_gettid); +#else + return -1; +#endif +} +#endif + +ThreadWrapper* ThreadLinux::Create(ThreadRunFunction func, ThreadObj obj, + ThreadPriority prio, const char* threadName) +{ + ThreadLinux* ptr = new ThreadLinux(func, obj, prio, threadName); + if (!ptr) + { + return NULL; + } + const int error = ptr->Construct(); + if (error) + { + delete ptr; + return NULL; + } + return ptr; +} + +ThreadLinux::ThreadLinux(ThreadRunFunction func, ThreadObj obj, + ThreadPriority prio, const char* threadName) + : _runFunction(func), + _obj(obj), + _alive(false), + _dead(true), + _prio(prio), + _event(EventWrapper::Create()), + _setThreadName(false) +{ +#ifdef WEBRTC_LINUX + _linuxPid = -1; +#endif + if (threadName != NULL) + { + _setThreadName = true; + strncpy(_name, threadName, kThreadMaxNameLength); + } +} + +int ThreadLinux::Construct() +{ + int result = 0; +#if !defined(ANDROID) + // Enable immediate cancellation if requested, see Shutdown() + result = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + if (result != 0) + { + return -1; + } + result = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + if (result != 0) + { + return -1; + } +#endif + result = pthread_attr_init(&_attr); + if (result != 0) + { + return -1; + } + + return 0; +} + +ThreadLinux::~ThreadLinux() +{ + pthread_attr_destroy(&_attr); + delete _event; +} + +#undef HAS_THREAD_ID + +//#define HAS_THREAD_ID !defined(MAC_IPHONE) && !defined(MAC_IPHONE_SIM) && \ +// !defined(WEBRTC_MAC) && !defined(WEBRTC_MAC_INTEL) && \ +// !defined(MAC_DYLIB) && !defined(MAC_INTEL_DYLIB) +#if HAS_THREAD_ID +bool ThreadLinux::Start(unsigned int& threadID) +#else +bool ThreadLinux::Start(unsigned int& /*threadID*/) +#endif +{ + if (!_runFunction) + { + return false; + } + int result = pthread_attr_setdetachstate(&_attr, PTHREAD_CREATE_DETACHED); + // Set the stack stack size to 1M. + result |= pthread_attr_setstacksize(&_attr, 1024*1024); +#ifdef WEBRTC_THREAD_RR + const int policy = SCHED_RR; +#else + const int policy = SCHED_FIFO; +#endif + _event->Reset(); + result |= pthread_create(&_thread, &_attr, &StartThread, this); + if (result != 0) + { + return false; + } + + // Wait up to 10 seconds for the OS to call the callback function. Prevents + // race condition if Stop() is called too quickly after start. + if (kEventSignaled != _event->Wait(WEBRTC_EVENT_10_SEC)) + { + // Timed out. Something went wrong. + _runFunction = NULL; + return false; + } + +#if HAS_THREAD_ID + threadID = (unsigned int)(_thread); +#endif + sched_param param; + + const int minPrio = sched_get_priority_min(policy); + const int maxPrio = sched_get_priority_max(policy); + if ((minPrio == EINVAL) || (maxPrio == EINVAL)) + { + return false; + } + + switch (_prio) + { + case kLowPriority: + param.sched_priority = minPrio + 1; + break; + case kNormalPriority: + param.sched_priority = (minPrio + maxPrio) / 2; + break; + case kHighPriority: + param.sched_priority = maxPrio - 3; + break; + case kHighestPriority: + param.sched_priority = maxPrio - 2; + break; + case kRealtimePriority: + param.sched_priority = maxPrio - 1; + break; + default: + return false; + } + result = pthread_setschedparam(_thread, policy, &param); + if (result == EINVAL) + { + return false; + } + return true; +} + +#if (defined(WEBRTC_LINUX) && !defined(ANDROID)) +bool ThreadLinux::SetAffinity(const int* processorNumbers, + const unsigned int amountOfProcessors) +{ + if (!processorNumbers || (amountOfProcessors == 0)) + { + return false; + } + + cpu_set_t mask; + CPU_ZERO(&mask); + + for(unsigned int processor = 0; + processor < amountOfProcessors; + processor++) + { + CPU_SET(processorNumbers[processor], &mask); + } + const int result = sched_setaffinity(_linuxPid, (unsigned int)sizeof(mask), + &mask); + if (result != 0) + { + return false; + + } + return true; +} +#else +// NOTE: On Mac OS X, use the Thread affinity API in +// /usr/include/mach/thread_policy.h: thread_policy_set and mach_thread_self() +// instead of Linux gettid() syscall. +bool ThreadLinux::SetAffinity(const int* , const unsigned int) +{ + return false; +} +#endif + +void ThreadLinux::SetNotAlive() +{ + _alive = false; +} + +bool ThreadLinux::Shutdown() +{ +#if !defined(ANDROID) + if (_thread && (0 != pthread_cancel(_thread))) + { + return false; + } + + return true; +#else + return false; +#endif +} + +bool ThreadLinux::Stop() +{ + _alive = false; + + // TODO (hellner) why not use an event here? + // Wait up to 10 seconds for the thread to terminate + for (int i = 0; i < 1000 && !_dead; i++) + { + timespec t; + t.tv_sec = 0; + t.tv_nsec = 10*1000*1000; + nanosleep(&t, NULL); + } + if (_dead) + { + return true; + } + else + { + return false; + } +} + +void ThreadLinux::Run() +{ + _alive = true; + _dead = false; +#ifdef WEBRTC_LINUX + if(_linuxPid == -1) + { + _linuxPid = gettid(); + } +#endif + // The event the Start() is waiting for. + _event->Set(); + + if (_setThreadName) + { +#ifdef WEBRTC_LINUX + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,-1, + "Thread with id:%d name:%s started ", _linuxPid, _name); + prctl(PR_SET_NAME, (unsigned long)_name, 0, 0, 0); +#else + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,-1, + "Thread with name:%s started ", _name); +#endif + }else + { +#ifdef WEBRTC_LINUX + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, + "Thread with id:%d without name started", _linuxPid); +#else + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, + "Thread without name started"); +#endif + } + do + { + if (_runFunction) + { + if (!_runFunction(_obj)) + { + _alive = false; + } + } + else + { + _alive = false; + } + } + while (_alive); + + if (_setThreadName) + { + // Don't set the name for the trace thread because it may cause a + // deadlock. TODO (hellner) there should be a better solution than + // coupling the thread and the trace class like this. + if (strcmp(_name, "Trace")) + { + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,-1, + "Thread with name:%s stopped", _name); + } + } + else + { + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,-1, + "Thread without name stopped"); + } + _dead = true; +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/thread_linux.h b/src/libs/webrtc/system_wrappers/thread_linux.h new file mode 100644 index 00000000..3e2b9080 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/thread_linux.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_LINUX_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_LINUX_H_ + +#include "thread_wrapper.h" +#include <pthread.h> + +namespace webrtc { +class EventWrapper; + +class ThreadLinux : public ThreadWrapper +{ +public: + static ThreadWrapper* Create(ThreadRunFunction func, ThreadObj obj, + ThreadPriority prio, const char* threadName); + + ThreadLinux(ThreadRunFunction func, ThreadObj obj, ThreadPriority prio, + const char* threadName); + ~ThreadLinux(); + + // From ThreadWrapper + virtual void SetNotAlive(); + virtual bool Start(unsigned int& id); + // Not implemented on Mac + virtual bool SetAffinity(const int* processorNumbers, + unsigned int amountOfProcessors); + virtual bool Stop(); + virtual bool Shutdown(); + + void Run(); + +private: + int Construct(); + +private: + // processing function + ThreadRunFunction _runFunction; + ThreadObj _obj; + + // internal state + bool _alive; + bool _dead; + ThreadPriority _prio; + EventWrapper* _event; + + // zero-terminated thread name string + char _name[kThreadMaxNameLength]; + bool _setThreadName; + + // handle to thread + pthread_attr_t _attr; + pthread_t _thread; +#ifdef WEBRTC_LINUX + pid_t _linuxPid; +#endif + +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_LINUX_H_ diff --git a/src/libs/webrtc/system_wrappers/thread_windows.cc b/src/libs/webrtc/system_wrappers/thread_windows.cc new file mode 100644 index 00000000..c4a3d71a --- /dev/null +++ b/src/libs/webrtc/system_wrappers/thread_windows.cc @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "thread_windows.h" + +#include <assert.h> +#include <process.h> +#include <stdio.h> +#include <windows.h> + +#include "thread_windows_set_name.h" +#include "trace.h" + +#if defined(_WIN32) +// VS 2005: Disable warnings for default initialized arrays. +#pragma warning(disable:4351) +#endif + +namespace webrtc { +ThreadWindows::ThreadWindows(ThreadRunFunction func, ThreadObj obj, + ThreadPriority prio, const char* threadName) + : ThreadWrapper(), + _runFunction(func), + _obj(obj), + _alive(false), + _dead(true), + _doNotCloseHandle(false), + _prio(prio), + _event(NULL), + _thread(NULL), + _id(0), + _name(), + _setThreadName(false) +{ + _event = EventWrapper::Create(); + _critsectStop = CriticalSectionWrapper::CreateCriticalSection(); + if (threadName != NULL) + { + // Set the thread name to appear in the VS debugger. + _setThreadName = true; + strncpy(_name, threadName, kThreadMaxNameLength); + } +} + +ThreadWindows::~ThreadWindows() +{ +#ifdef _DEBUG + assert(!_alive); +#endif + if (_thread) + { + CloseHandle(_thread); + } + if(_event) + { + delete _event; + } + if(_critsectStop) + { + delete _critsectStop; + } +} + +unsigned int WINAPI ThreadWindows::StartThread(LPVOID lpParameter) +{ + static_cast<ThreadWindows*>(lpParameter)->Run(); + return 0; +} + +bool ThreadWindows::Start(unsigned int& threadID) +{ + _doNotCloseHandle = false; + + // Set stack size to 1M + _thread=(HANDLE)_beginthreadex(NULL, 1024*1024, StartThread, (void*)this, 0, + &threadID); + if(_thread == NULL) + { + return false; + } + _id = threadID; + _event->Wait(INFINITE); + + switch(_prio) + { + case kLowPriority: + SetThreadPriority(_thread, THREAD_PRIORITY_BELOW_NORMAL); + break; + case kNormalPriority: + SetThreadPriority(_thread, THREAD_PRIORITY_NORMAL); + break; + case kHighPriority: + SetThreadPriority(_thread, THREAD_PRIORITY_ABOVE_NORMAL); + break; + case kHighestPriority: + SetThreadPriority(_thread, THREAD_PRIORITY_HIGHEST); + break; + case kRealtimePriority: + SetThreadPriority(_thread, THREAD_PRIORITY_TIME_CRITICAL); + break; + }; + return true; +} + +bool ThreadWindows::SetAffinity(const int* processorNumbers, + const unsigned int amountOfProcessors) +{ + DWORD_PTR processorBitMask = 0; + for(unsigned int processorIndex = 0; + processorIndex < amountOfProcessors; + processorIndex++) + { + // Convert from an array with processor numbers to a bitmask + // Processor numbers start at zero. + // TODO (hellner): this looks like a bug. Shouldn't the '=' be a '+='? + // Or even better |= + processorBitMask = 1 << processorNumbers[processorIndex]; + } + return SetThreadAffinityMask(_thread,processorBitMask) != 0; +} + +void ThreadWindows::SetNotAlive() +{ + _alive = false; +} + +bool ThreadWindows::Shutdown() +{ + DWORD exitCode = 0; + BOOL ret = TRUE; + if (_thread) + { + ret = TerminateThread(_thread, exitCode); + _alive = false; + _dead = true; + _thread = NULL; + } + return ret == TRUE; +} + +bool ThreadWindows::Stop() +{ + _critsectStop->Enter(); + // Prevents the handle from being closed in ThreadWindows::Run() + _doNotCloseHandle = true; + _alive = false; + bool signaled = false; + if (_thread && !_dead) + { + _critsectStop->Leave(); + // Wait up to 2 seconds for the thread to complete. + if( WAIT_OBJECT_0 == WaitForSingleObject(_thread, 2000)) + { + signaled = true; + } + _critsectStop->Enter(); + } + if (_thread) + { + CloseHandle(_thread); + _thread = NULL; + } + _critsectStop->Leave(); + + if (_dead || signaled) + { + return true; + } + else + { + return false; + } +} + +void ThreadWindows::Run() +{ + _alive = true; + _dead = false; + _event->Set(); + + // All tracing must be after _event->Set to avoid deadlock in Trace. + if (_setThreadName) + { + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, _id, + "Thread with name:%s started ", _name); + SetThreadName(-1, _name); // -1, set thread name for the calling thread. + }else + { + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, _id, + "Thread without name started"); + } + + do + { + if (_runFunction) + { + if (!_runFunction(_obj)) + { + _alive = false; + } + } else { + _alive = false; + } + } while(_alive); + + if (_setThreadName) + { + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, _id, + "Thread with name:%s stopped", _name); + } else { + WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,_id, + "Thread without name stopped"); + } + + _critsectStop->Enter(); + + if (_thread && !_doNotCloseHandle) + { + HANDLE thread = _thread; + _thread = NULL; + CloseHandle(thread); + } + _dead = true; + + _critsectStop->Leave(); +}; +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/thread_windows.h b/src/libs/webrtc/system_wrappers/thread_windows.h new file mode 100644 index 00000000..4fd7523e --- /dev/null +++ b/src/libs/webrtc/system_wrappers/thread_windows.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_H_ + +#include "thread_wrapper.h" +#include "event_wrapper.h" +#include "critical_section_wrapper.h" + +#include <windows.h> + +namespace webrtc { + +class ThreadWindows : public ThreadWrapper +{ +public: + ThreadWindows(ThreadRunFunction func, ThreadObj obj, ThreadPriority prio, + const char* threadName); + virtual ~ThreadWindows(); + + virtual bool Start(unsigned int& id); + bool SetAffinity(const int* processorNumbers, + const unsigned int amountOfProcessors); + virtual bool Stop(); + virtual void SetNotAlive(); + + static unsigned int WINAPI StartThread(LPVOID lpParameter); + + virtual bool Shutdown(); + +protected: + virtual void Run(); + +private: + ThreadRunFunction _runFunction; + ThreadObj _obj; + + bool _alive; + bool _dead; + + // TODO (hellner) + // _doNotCloseHandle member seem pretty redundant. Should be able to remove + // it. Basically it should be fine to reclaim the handle when calling stop + // and in the destructor. + bool _doNotCloseHandle; + ThreadPriority _prio; + EventWrapper* _event; + CriticalSectionWrapper* _critsectStop; + + HANDLE _thread; + unsigned int _id; + char _name[kThreadMaxNameLength]; + bool _setThreadName; + +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_H_ diff --git a/src/libs/webrtc/system_wrappers/thread_windows_set_name.h b/src/libs/webrtc/system_wrappers/thread_windows_set_name.h new file mode 100644 index 00000000..a46f4d63 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/thread_windows_set_name.h @@ -0,0 +1,43 @@ +/* + * Use of this source code is governed by the MICROSOFT LIMITED PUBLIC LICENSE + * copyright license which can be found in the LICENSE file in the + * third_party_mods/mslpl directory of the source tree or at + * http://msdn.microsoft.com/en-us/cc300389.aspx#P. + */ +/* + * The original code can be found here: + * http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.71).aspx + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_SET_NAME_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_SET_NAME_H_ + +namespace webrtc { + +struct THREADNAME_INFO +{ + DWORD dwType; // must be 0x1000 + LPCSTR szName; // pointer to name (in user addr space) + DWORD dwThreadID; // thread ID (-1 = caller thread) + DWORD dwFlags; // reserved for future use, must be zero +}; + +void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName) +{ + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = szThreadName; + info.dwThreadID = dwThreadID; + info.dwFlags = 0; + + __try + { + RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD), + (ULONG_PTR*)&info); + } + __except (EXCEPTION_CONTINUE_EXECUTION) + { + } +} +} // namespace webrtc +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_SET_NAME_H_ diff --git a/src/libs/webrtc/system_wrappers/thread_wrapper.h b/src/libs/webrtc/system_wrappers/thread_wrapper.h new file mode 100644 index 00000000..eccf3c23 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/thread_wrapper.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// System independant wrapper for spawning threads +// Note: the spawned thread will loop over the callback function until stopped. +// Note: The callback function is expected to return every 2 seconds or more +// often. + +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_ + +namespace webrtc { +// Object that will be passed by the spawned thread when it enters the callback +// function. +#define ThreadObj void* + +// Callback function that the spawned thread will enter once spawned +typedef bool(*ThreadRunFunction)(ThreadObj); + +enum ThreadPriority +{ + kLowPriority = 1, + kNormalPriority = 2, + kHighPriority = 3, + kHighestPriority = 4, + kRealtimePriority = 5 +}; + +class ThreadWrapper +{ +public: + enum {kThreadMaxNameLength = 64}; + + virtual ~ThreadWrapper() {}; + + // Factory method. Constructor disabled. + // + // func Pointer to a, by user, specified callback function. + // obj Object associated with the thread. Passed in the callback + // function. + // prio Thread priority. May require root/admin rights. + // threadName NULL terminated thread name, will be visable in the Windows + // debugger. + static ThreadWrapper* CreateThread(ThreadRunFunction func = 0, + ThreadObj obj= 0, + ThreadPriority prio = kNormalPriority, + const char* threadName = 0); + + // Non blocking termination of the spawned thread. Note that it is not safe + // to delete this class until the spawned thread has been reclaimed. + virtual void SetNotAlive() = 0; + + // Spawns the thread. This will start the triggering of the callback + // function. + virtual bool Start(unsigned int& id) = 0; + + // Sets the threads CPU affinity. CPUs are listed 0 - (number of CPUs - 1). + // The numbers in processorNumbers specify which CPUs are allowed to run the + // thread. processorNumbers should not contain any duplicates and elements + // should be lower than (number of CPUs - 1). amountOfProcessors should be + // equal to the number of processors listed in processorNumbers + virtual bool SetAffinity(const int* /*processorNumbers*/, + const unsigned int /*amountOfProcessors*/) + {return false;} + + // Stops the spawned thread and waits for it to be reclaimed with a timeout + // of two seconds. Will return false if the thread was not reclaimed. + // Multiple tries to Stop are allowed (e.g. to wait longer than 2 seconds). + // It's ok to call Stop() even if the spawned thread has been reclaimed. + virtual bool Stop() = 0; + + // Stops the spawned thread dead in its tracks. Will likely result in a + // corrupt state. There should be an extremely good reason for even looking + // at this function. Can cause many problems deadlock being one of them. + virtual bool Shutdown() {return false;} +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_ diff --git a/src/libs/webrtc/system_wrappers/tick_util.h b/src/libs/webrtc/system_wrappers/tick_util.h new file mode 100644 index 00000000..4c280677 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/tick_util.h @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// System independant wrapper for polling elapsed time in ms and us. +// The implementation works in the tick domain which can be mapped over to the +// time domain. +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_ + +#if _WIN32 +#include <windows.h> +#include <mmsystem.h> +#elif WEBRTC_LINUX +#include <ctime> +#else +#include <sys/time.h> +#include <time.h> +#endif + +#include "typedefs.h" + +namespace webrtc { +class TickInterval; + +class TickTime +{ +public: + // Current time in the tick domain. + static TickTime Now(); + + // Now in the time domain in ms. + static WebRtc_Word64 MillisecondTimestamp(); + + // Now in the time domain in us. + static WebRtc_Word64 MicrosecondTimestamp(); + + WebRtc_Word64 Ticks() const; + + static WebRtc_Word64 MillisecondsToTicks(const WebRtc_Word64 ms); + + static WebRtc_Word64 TicksToMilliseconds(const WebRtc_Word64 ticks); + + // Returns a TickTime that is ticks later than the passed TickTime + friend TickTime operator+(const TickTime lhs, const WebRtc_Word64 ticks); + TickTime& operator+=(const WebRtc_Word64& rhs); + + + // Returns a TickInterval that is the difference in ticks beween rhs and lhs + friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs); +private: + WebRtc_Word64 _ticks; +}; + +class TickInterval +{ +public: + TickInterval(); + + WebRtc_Word64 Milliseconds() const; + WebRtc_Word64 Microseconds() const; + + // Returns the sum of two TickIntervals as a TickInterval + friend TickInterval operator+(const TickInterval& lhs, + const TickInterval& rhs); + TickInterval& operator-=(const TickInterval& rhs); + + // Returns a TickInterval corresponding to rhs - lhs + friend TickInterval operator-(const TickInterval& lhs, + const TickInterval& rhs); + TickInterval& operator+=(const TickInterval& rhs); + +private: + TickInterval(WebRtc_Word64 interval); + + friend class TickTime; + friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs); + +private: + WebRtc_Word64 _interval; +}; + +inline TickInterval operator+(const TickInterval& lhs, const TickInterval& rhs) +{ + return TickInterval(lhs._interval + rhs._interval); +} + +inline TickInterval operator-(const TickInterval& lhs, const TickInterval& rhs) +{ + return TickInterval(lhs._interval - rhs._interval); +} + +inline TickInterval operator-(const TickTime& lhs,const TickTime& rhs) +{ + return TickInterval(lhs._ticks - rhs._ticks); +} + +inline TickTime operator+(const TickTime lhs, const WebRtc_Word64 ticks) +{ + TickTime time = lhs; + time._ticks += ticks; + return time; +} + +inline TickTime TickTime::Now() +{ + TickTime result; +#if _WIN32 + #ifdef USE_QUERY_PERFORMANCE_COUNTER + // QueryPerformanceCounter returns the value from the TSC which is + // incremented at the CPU frequency. The algorithm used requires + // the CPU frequency to be constant. Technology like speed stepping + // which has variable CPU frequency will therefore yield unpredictable, + // incorrect time estimations. + LARGE_INTEGER qpcnt; + QueryPerformanceCounter(&qpcnt); + result._ticks = qpcnt.QuadPart; + #else + static volatile LONG lastTimeGetTime = 0; + static volatile WebRtc_Word64 numWrapTimeGetTime = 0; + volatile LONG* lastTimeGetTimePtr = &lastTimeGetTime; + DWORD now = timeGetTime(); + // Atomically update the last gotten time + DWORD old = InterlockedExchange(lastTimeGetTimePtr, now); + if(now < old) + { + // If now is earlier than old, there may have been a race between + // threads. + // 0x0fffffff ~3.1 days, the code will not take that long to execute + // so it must have been a wrap around. + if(old > 0xf0000000 && now < 0x0fffffff) + { + numWrapTimeGetTime++; + } + } + result._ticks = now + (numWrapTimeGetTime<<32); + #endif +#elif defined(WEBRTC_LINUX) + struct timespec ts; + #ifdef WEBRTC_CLOCK_TYPE_REALTIME + clock_gettime(CLOCK_REALTIME, &ts); + #else + clock_gettime(CLOCK_MONOTONIC, &ts); + #endif + result._ticks = 1000000000LL * static_cast<WebRtc_Word64>(ts.tv_sec) + static_cast<WebRtc_Word64>(ts.tv_nsec); +#else + struct timeval tv; + gettimeofday(&tv, NULL); + result._ticks = 1000000LL * static_cast<WebRtc_Word64>(tv.tv_sec) + static_cast<WebRtc_Word64>(tv.tv_usec); +#endif + return result; +} + +inline WebRtc_Word64 TickTime::MillisecondTimestamp() +{ + TickTime now = TickTime::Now(); +#if _WIN32 + #ifdef USE_QUERY_PERFORMANCE_COUNTER + LARGE_INTEGER qpfreq; + QueryPerformanceFrequency(&qpfreq); + return (now._ticks * 1000) / qpfreq.QuadPart; + #else + return now._ticks; + #endif +#elif WEBRTC_LINUX + return now._ticks / 1000000LL; +#else + return now._ticks / 1000LL; +#endif +} + +inline WebRtc_Word64 TickTime::MicrosecondTimestamp() +{ + TickTime now = TickTime::Now(); + +#if _WIN32 + #ifdef USE_QUERY_PERFORMANCE_COUNTER + LARGE_INTEGER qpfreq; + QueryPerformanceFrequency(&qpfreq); + return (now._ticks * 1000) / (qpfreq.QuadPart/1000); + #else + return now._ticks *1000LL; + #endif +#elif WEBRTC_LINUX + return now._ticks / 1000LL; +#else + return now._ticks; +#endif +} + +inline WebRtc_Word64 TickTime::Ticks() const +{ + return _ticks; +} + +inline WebRtc_Word64 TickTime::MillisecondsToTicks(const WebRtc_Word64 ms) +{ +#if _WIN32 + #ifdef USE_QUERY_PERFORMANCE_COUNTER + LARGE_INTEGER qpfreq; + QueryPerformanceFrequency(&qpfreq); + return (qpfreq.QuadPart * ms) / 1000; + #else + return ms; + #endif +#elif WEBRTC_LINUX + return ms * 1000000LL; +#else + return ms * 1000LL; +#endif +} + +inline WebRtc_Word64 TickTime::TicksToMilliseconds(const WebRtc_Word64 ticks) +{ +#if _WIN32 + #ifdef USE_QUERY_PERFORMANCE_COUNTER + LARGE_INTEGER qpfreq; + QueryPerformanceFrequency(&qpfreq); + return (ticks * 1000) / qpfreq.QuadPart; + #else + return ticks; + #endif +#elif WEBRTC_LINUX + return ticks / 1000000LL; +#else + return ticks / 1000LL; +#endif +} + +inline TickTime& TickTime::operator+=(const WebRtc_Word64& ticks) +{ + _ticks += ticks; + return *this; +} + +inline TickInterval::TickInterval() : _interval(0) +{ +} + +inline TickInterval::TickInterval(const WebRtc_Word64 interval) + : _interval(interval) +{ +} + +inline WebRtc_Word64 TickInterval::Milliseconds() const +{ +#if _WIN32 + #ifdef USE_QUERY_PERFORMANCE_COUNTER + LARGE_INTEGER qpfreq; + QueryPerformanceFrequency(&qpfreq); + return (_interval * 1000) / qpfreq.QuadPart; + #else + // _interval is in ms + return _interval; + #endif +#elif WEBRTC_LINUX + // _interval is in ns + return _interval / 1000000; +#else + // _interval is usecs + return _interval / 1000; +#endif +} + +inline WebRtc_Word64 TickInterval::Microseconds() const +{ +#if _WIN32 + #ifdef USE_QUERY_PERFORMANCE_COUNTER + LARGE_INTEGER qpfreq; + QueryPerformanceFrequency(&qpfreq); + return (_interval * 1000000) / qpfreq.QuadPart; + #else + // _interval is in ms + return _interval *1000LL; + #endif +#elif WEBRTC_LINUX + // _interval is in ns + return _interval / 1000; +#else + // _interval is usecs + return _interval; +#endif +} + +inline TickInterval& TickInterval::operator+=(const TickInterval& rhs) +{ + _interval += rhs._interval; + return *this; +} + +inline TickInterval& TickInterval::operator-=(const TickInterval& rhs) +{ + _interval -= rhs._interval; + return *this; +} +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_ diff --git a/src/libs/webrtc/system_wrappers/trace.h b/src/libs/webrtc/system_wrappers/trace.h new file mode 100644 index 00000000..0f7df4d4 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/trace.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// System independant wrapper for logging runtime information to file. +// Note: All log messages will be written to the same trace file. +// Note: If to many messages are written to file there will be a build up of +// messages. Apply filtering to avoid that. +#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_ +#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_ + +#include "common_types.h" +#include "typedefs.h" + +#ifdef WEBRTC_NO_TRACE + #define WEBRTC_TRACE +#else + // Ideally we would use __VA_ARGS__ but it's not supported by all compilers + // such as VS2003 (it's supported in VS2005). TODO (hellner) why + // would this be better than current implementation (not convinced)? + #define WEBRTC_TRACE Trace::Add +#endif + +namespace webrtc { +class Trace +{ +public: + + // Increments the reference count to the trace. + static void CreateTrace(); + // Decrements the reference count to the trace. + static void ReturnTrace(); + // Note: any instance that writes to the trace file should increment and + // decrement the reference count on construction and destruction + // respectively + + // Specifies what type of messages should be written to the trace file. The + // filter parameter is a bitmask where each message type is enumerated by + // the TraceLevel enumerator. TODO (hellner) why is the + // TraceLevel enumerator not defined in this file? + static WebRtc_Word32 SetLevelFilter(const WebRtc_UWord32 filter); + + // Returns what type of messages are written to the trace file. + static WebRtc_Word32 LevelFilter(WebRtc_UWord32& filter); + + // Sets the file name. If addFileCounter is false the same file will be + // reused when it fills up. If it's true a new file with incremented name + // will be used. + static WebRtc_Word32 SetTraceFile(const WebRtc_Word8* fileName, + const bool addFileCounter = false); + + // Returns the name of the file that the trace is currently writing to. + static WebRtc_Word32 TraceFile(WebRtc_Word8 fileName[1024]); + + // Registers callback to receive trace messages. TODO (hellner) + // why not use OutStream instead? Why is TraceCallback not defined in this + // file + static WebRtc_Word32 SetTraceCallback(TraceCallback* callback); + + // Adds a trace message for writing to file. The message is put in a queue + // for writing to file whenever possible for performance reasons. I.e. there + // is a crash it is possible that the last, vital logs are not logged yet. + // level is the the type of message to log. If that type of messages is + // filtered it will not be written to file. module is an identifier for what + // part of the code the message is comming. + // id is an identifier that should be unique for that set of classes that + // are associated (e.g. all instances owned by an engine). + // msg and the elipsis are the same as e.g. sprintf. + // TODO (hellner) Why is TraceModule not defined in this file? + static void Add(const TraceLevel level, + const TraceModule module, + const WebRtc_Word32 id, + const char* msg, ...); + +}; +} // namespace webrtc +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_ diff --git a/src/libs/webrtc/system_wrappers/trace_impl.cc b/src/libs/webrtc/system_wrappers/trace_impl.cc new file mode 100644 index 00000000..0a5f9db4 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/trace_impl.cc @@ -0,0 +1,949 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "trace_impl.h" + +#include <cassert> +#include <string.h> // memset + +#ifdef _WIN32 +#include "trace_windows.h" +#include "fix_interlocked_exchange_pointer_windows.h" +#else +#include <stdio.h> +#include <time.h> +#include <stdarg.h> +#include "trace_linux.h" +#endif // _WIN32 + +#define KEY_LEN_CHARS 31 + +#ifdef _WIN32 + #pragma warning(disable:4355) +// VS 2005: Disable warnings for default initialized arrays. + #pragma warning(disable:4351) +#endif // _WIN32 + +namespace webrtc { +static WebRtc_UWord32 levelFilter = kTraceDefault; + +// Construct On First Use idiom. Avoids "static initialization order fiasco". +Trace* TraceImpl::StaticInstance(TraceCount inc, const TraceLevel level) +{ + // TODO (hellner): use atomic wrapper instead. + static volatile long theTraceCount = 0; + static Trace* volatile theTrace = NULL; + + TraceCreate state = WEBRTC_TRACE_EXIST; + + // Sanitys to avoid taking lock unless absolutely necessary (for + // performance reasons). inc == WEBRTC_TRACE_INC_NO_CREATE) implies that + // a message will be written to file. + if(level != kTraceAll && inc == WEBRTC_TRACE_INC_NO_CREATE) + { + if(!(level & levelFilter)) + { + return NULL; + } + } + +#ifndef _WIN32 + // TODO (pwestin): crtiSect is never reclaimed. Fix memory leak. + static CriticalSectionWrapper* crtiSect( + CriticalSectionWrapper::CreateCriticalSection()); + CriticalSectionScoped lock(*crtiSect); + + if(inc == WEBRTC_TRACE_INC_NO_CREATE && theTraceCount == 0) + { + return NULL; + } + + if(inc == WEBRTC_TRACE_INC || inc == WEBRTC_TRACE_INC_NO_CREATE) + { + theTraceCount++; + if(theTraceCount == 1) + { + state = WEBRTC_TRACE_CREATE; + } + } else { + theTraceCount--; + if(theTraceCount == 0) + { + state = WEBRTC_TRACE_DESTROY; + } + } + if(state == WEBRTC_TRACE_CREATE) + { + theTrace = TraceImpl::CreateTrace(); + + } else if(state == WEBRTC_TRACE_DESTROY) { + Trace* oldValue = theTrace; + theTrace = NULL; + // The lock is held by the scoped critical section. Release the lock + // temporarily so that the trace can be safely deleted. If the lock + // was kept during the delete, e.g. creating and destroying the trace + // too quickly may lead to a deadlock. + // This is due to the fact that starting and stopping a ThreadWrapper + // thread will trigger writing of trace messages. + // TODO (hellner): remove the tight coupling with the thread + // implementation. + crtiSect->Leave(); + if(oldValue) + { + delete static_cast<TraceImpl*>(oldValue); + } + // Re-aqcuire the lock. + crtiSect->Enter(); + return NULL; + } +#else // _WIN32 + if(inc == WEBRTC_TRACE_INC_NO_CREATE && theTraceCount == 0) + { + return NULL; + } + if(inc == WEBRTC_TRACE_INC_NO_CREATE) + { + if(1 == InterlockedIncrement(&theTraceCount)) + { + // The trace has been destroyed by some other thread. Rollback. + InterlockedDecrement(&theTraceCount); + assert(false); + return NULL; + } + // Sanity to catch corrupt state. + if(theTrace == NULL) + { + assert(false); + InterlockedDecrement(&theTraceCount); + return NULL; + } + } else if(inc == WEBRTC_TRACE_INC) { + if(theTraceCount == 0) + { + state = WEBRTC_TRACE_CREATE; + } else { + if(1 == InterlockedIncrement(&theTraceCount)) + { + // InterlockedDecrement because reference count should not be + // updated just yet (that's done when the trace is created). + InterlockedDecrement(&theTraceCount); + state = WEBRTC_TRACE_CREATE; + } + } + } else { + int newValue = InterlockedDecrement(&theTraceCount); + if(newValue == 0) + { + state = WEBRTC_TRACE_DESTROY; + } + } + + if(state == WEBRTC_TRACE_CREATE) + { + // Create trace and let whichever thread finishes first assign its local + // copy to the global instance. All other threads reclaim their local + // copy. + Trace* newTrace = TraceImpl::CreateTrace(); + if(1 == InterlockedIncrement(&theTraceCount)) + { + Trace* oldValue = (Trace*)InterlockedExchangePointer( + reinterpret_cast<void* volatile*>(&theTrace), newTrace); + assert(oldValue == NULL); + assert(theTrace); + } else { + InterlockedDecrement(&theTraceCount); + if(newTrace) + { + delete static_cast<TraceImpl*>(newTrace); + } + } + return NULL; + } else if(state == WEBRTC_TRACE_DESTROY) + { + Trace* oldValue = (Trace*)InterlockedExchangePointer( + reinterpret_cast<void* volatile*>(&theTrace), NULL); + if(oldValue) + { + delete static_cast<TraceImpl*>(oldValue); + } + return NULL; + } +#endif // #ifndef _WIN32 + return theTrace; +} + +void Trace::CreateTrace() +{ + TraceImpl::StaticInstance(WEBRTC_TRACE_INC); +} + +void Trace::ReturnTrace() +{ + TraceImpl::StaticInstance(WEBRTC_TRACE_DEC); +} + +TraceImpl* TraceImpl::GetTrace(const TraceLevel level) +{ + return (TraceImpl*)StaticInstance(WEBRTC_TRACE_INC_NO_CREATE, level); +} + +Trace* TraceImpl::CreateTrace() +{ +#if defined(_WIN32) + return new TraceWindows(); +#else + return new TraceLinux(); +#endif +} + +TraceImpl::TraceImpl() + : _critsectInterface(*CriticalSectionWrapper::CreateCriticalSection()), + _callback(NULL), + _rowCountText(0), + _fileCountText(0), + _traceFile(*FileWrapper::Create()), + _thread(*ThreadWrapper::CreateThread(TraceImpl::Run, this, + kHighestPriority, "Trace")), + _event(*EventWrapper::Create()), + _critsectArray(*CriticalSectionWrapper::CreateCriticalSection()), + _nextFreeIdx(), + _level(), + _length(), + _messageQueue(), + _activeQueue(0) +{ + _nextFreeIdx[0] = 0; + _nextFreeIdx[1] = 0; + + unsigned int tid = 0; + _thread.Start(tid); + + for(int m = 0; m < WEBRTC_TRACE_NUM_ARRAY; m++) + { + for(int n = 0; n < WEBRTC_TRACE_MAX_QUEUE; n++) + { + _messageQueue[m][n] = new + WebRtc_Word8[WEBRTC_TRACE_MAX_MESSAGE_SIZE]; + } + } +} + +bool TraceImpl::StopThread() +{ + // Release the worker thread so that it can flush any lingering messages. + _event.Set(); + + // Allow 10 ms for pending messages to be flushed out. + // TODO (hellner): why not use condition variables to do this? Or let the + // worker thread die and let this thread flush remaining + // messages? +#ifdef _WIN32 + Sleep(10); +#else + timespec t; + t.tv_sec = 0; + t.tv_nsec = 10*1000000; + nanosleep(&t,NULL); +#endif + + _thread.SetNotAlive(); + // Make sure the thread finishes as quickly as possible (instead of having + // to wait for the timeout). + _event.Set(); + bool stopped = _thread.Stop(); + + CriticalSectionScoped lock(_critsectInterface); + _traceFile.Flush(); + _traceFile.CloseFile(); + return stopped; +} + +TraceImpl::~TraceImpl() +{ + StopThread(); + delete &_event; + delete &_traceFile; + delete &_thread; + delete &_critsectInterface; + delete &_critsectArray; + + for(int m = 0; m < WEBRTC_TRACE_NUM_ARRAY; m++) + { + for(int n = 0; n < WEBRTC_TRACE_MAX_QUEUE; n++) + { + delete [] _messageQueue[m][n]; + } + } +} + +WebRtc_Word32 TraceImpl::AddLevel(char* szMessage, const TraceLevel level) const +{ + switch (level) + { + case kTraceStateInfo: + sprintf (szMessage, "STATEINFO ; "); + break; + case kTraceWarning: + sprintf (szMessage, "WARNING ; "); + break; + case kTraceError: + sprintf (szMessage, "ERROR ; "); + break; + case kTraceCritical: + sprintf (szMessage, "CRITICAL ; "); + break; + case kTraceInfo: + sprintf (szMessage, "DEBUGINFO ; "); + break; + case kTraceModuleCall: + sprintf (szMessage, "MODULECALL; "); + break; + case kTraceMemory: + sprintf (szMessage, "MEMORY ; "); + break; + case kTraceTimer: + sprintf (szMessage, "TIMER ; "); + break; + case kTraceStream: + sprintf (szMessage, "STREAM ; "); + break; + case kTraceApiCall: + sprintf (szMessage, "APICALL ; "); + break; + case kTraceDebug: + sprintf (szMessage, "DEBUG ; "); + break; + default: + assert(false); + return 0; + } + // All messages are 12 characters. + return 12; +} + +WebRtc_Word32 TraceImpl::AddModuleAndId(char* traceMessage, + const TraceModule module, + const WebRtc_Word32 id) const +{ + // Use long int to prevent problems with different definitions of + // WebRtc_Word32. + // TODO (hellner): is this actually a problem? If so, it should be better to + // clean up WebRtc_Word32 + const long int idl = id; + if(idl != -1) + { + const unsigned long int idEngine = id>>16; + const unsigned long int idChannel = id & 0xffff; + + switch (module) + { + case kTraceVoice: + sprintf(traceMessage, " VOICE:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceVideo: + sprintf(traceMessage, " VIDEO:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceUtility: + sprintf(traceMessage, " UTILITY:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceRtpRtcp: + sprintf(traceMessage, " RTP/RTCP:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceTransport: + sprintf(traceMessage, " TRANSPORT:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceAudioCoding: + sprintf(traceMessage, "AUDIO CODING:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceSrtp: + sprintf(traceMessage, " SRTP:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceAudioMixerServer: + sprintf(traceMessage, " AUDIO MIX/S:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceAudioMixerClient: + sprintf(traceMessage, " AUDIO MIX/C:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceVideoCoding: + sprintf(traceMessage, "VIDEO CODING:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceVideoMixer: + // Print sleep time and API call + sprintf(traceMessage, " VIDEO MIX:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceFile: + sprintf(traceMessage, " FILE:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceAudioProcessing: + sprintf(traceMessage, " AUDIO PROC:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceAudioDevice: + sprintf(traceMessage, "AUDIO DEVICE:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceVideoRenderer: + sprintf(traceMessage, "VIDEO RENDER:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceVideoCapture: + sprintf(traceMessage, "VIDEO CAPTUR:%5ld %5ld;", idEngine, + idChannel); + break; + case kTraceVideoPreocessing: + sprintf(traceMessage, " VIDEO PROC:%5ld %5ld;", idEngine, + idChannel); + break; + default: + assert(false); + return 0; + } + } else { + switch (module) + { + case kTraceVoice: + sprintf (traceMessage, " VOICE:%11ld;", idl); + break; + case kTraceVideo: + sprintf (traceMessage, " VIDEO:%11ld;", idl); + break; + case kTraceUtility: + sprintf (traceMessage, " UTILITY:%11ld;", idl); + break; + case kTraceRtpRtcp: + sprintf (traceMessage, " RTP/RTCP:%11ld;", idl); + break; + case kTraceTransport: + sprintf (traceMessage, " TRANSPORT:%11ld;", idl); + break; + case kTraceAudioCoding: + sprintf (traceMessage, "AUDIO CODING:%11ld;", idl); + break; + case kTraceSrtp: + sprintf (traceMessage, " SRTP:%11ld;", idl); + break; + case kTraceAudioMixerServer: + sprintf (traceMessage, " AUDIO MIX/S:%11ld;", idl); + break; + case kTraceAudioMixerClient: + sprintf (traceMessage, " AUDIO MIX/C:%11ld;", idl); + break; + case kTraceVideoCoding: + sprintf (traceMessage, "VIDEO CODING:%11ld;", idl); + break; + case kTraceVideoMixer: + sprintf (traceMessage, " VIDEO MIX:%11ld;", idl); + break; + case kTraceFile: + sprintf (traceMessage, " FILE:%11ld;", idl); + break; + case kTraceAudioProcessing: + sprintf (traceMessage, " AUDIO PROC:%11ld;", idl); + break; + case kTraceAudioDevice: + sprintf (traceMessage, "AUDIO DEVICE:%11ld;", idl); + break; + case kTraceVideoRenderer: + sprintf (traceMessage, "VIDEO RENDER:%11ld;", idl); + break; + case kTraceVideoCapture: + sprintf (traceMessage, "VIDEO CAPTUR:%11ld;", idl); + break; + case kTraceVideoPreocessing: + sprintf (traceMessage, " VIDEO PROC:%11ld;", idl); + break; + default: + assert(false); + return 0; + } + } + // All messages are 25 characters. + return 25; +} + +WebRtc_Word32 TraceImpl::SetTraceFileImpl(const WebRtc_Word8* fileNameUTF8, + const bool addFileCounter) +{ + CriticalSectionScoped lock(_critsectInterface); + + _traceFile.Flush(); + _traceFile.CloseFile(); + + if(fileNameUTF8) + { + if(addFileCounter) + { + _fileCountText = 1; + + WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize]; + CreateFileName(fileNameUTF8, fileNameWithCounterUTF8, + _fileCountText); + if(_traceFile.OpenFile(fileNameWithCounterUTF8, false, false, + true) == -1) + { + return -1; + } + }else { + _fileCountText = 0; + if(_traceFile.OpenFile(fileNameUTF8, false, false, true) == -1) + { + return -1; + } + } + } + _rowCountText = 0; + return 0; +} + +WebRtc_Word32 TraceImpl::TraceFileImpl( + WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize]) +{ + CriticalSectionScoped lock(_critsectInterface); + return _traceFile.FileName(fileNameUTF8, FileWrapper::kMaxFileNameSize); +} + +WebRtc_Word32 TraceImpl::SetTraceCallbackImpl(TraceCallback* callback) +{ + CriticalSectionScoped lock(_critsectInterface); + _callback = callback; + return 0; +} + +WebRtc_Word32 TraceImpl::AddMessage( + char* traceMessage, + const char msg[WEBRTC_TRACE_MAX_MESSAGE_SIZE], + const WebRtc_UWord16 writtenSoFar) const + +{ + int length = 0; + if(writtenSoFar >= WEBRTC_TRACE_MAX_MESSAGE_SIZE) + { + return -1; + } + // - 2 to leave room for newline and NULL termination +#ifdef _WIN32 + length = _snprintf(traceMessage, + WEBRTC_TRACE_MAX_MESSAGE_SIZE - writtenSoFar - 2, + "%s",msg); + if(length < 0) + { + length = WEBRTC_TRACE_MAX_MESSAGE_SIZE - writtenSoFar - 2; + traceMessage[length] = 0; + } +#else + length = snprintf(traceMessage, + WEBRTC_TRACE_MAX_MESSAGE_SIZE-writtenSoFar-2, "%s",msg); + if(length < 0 || length > WEBRTC_TRACE_MAX_MESSAGE_SIZE-writtenSoFar - 2) + { + length = WEBRTC_TRACE_MAX_MESSAGE_SIZE - writtenSoFar - 2; + traceMessage[length] = 0; + } +#endif + // Length with NULL termination. + return length+1; +} + +void TraceImpl::AddMessageToList( + const char traceMessage[WEBRTC_TRACE_MAX_MESSAGE_SIZE], + const WebRtc_UWord16 length, + const TraceLevel level) +{ + CriticalSectionScoped lock(_critsectArray); + + if(_nextFreeIdx[_activeQueue] >= WEBRTC_TRACE_MAX_QUEUE) + { + if( ! _traceFile.Open() && + !_callback) + { + // Keep at least the last 1/4 of old messages when not logging. + // TODO (hellner): isn't this redundant. The user will make it known + // when to start logging. Why keep messages before + // that? + for(int n = 0; n < WEBRTC_TRACE_MAX_QUEUE/4; n++) + { + const int lastQuarterOffset = (3*WEBRTC_TRACE_MAX_QUEUE/4); + memcpy(_messageQueue[_activeQueue][n], + _messageQueue[_activeQueue][n + lastQuarterOffset], + WEBRTC_TRACE_MAX_MESSAGE_SIZE); + } + _nextFreeIdx[_activeQueue] = WEBRTC_TRACE_MAX_QUEUE/4; + } else { + // More messages are being written than there is room for in the + // buffer. Drop any new messages. + // TODO (hellner): its probably better to drop old messages instead + // of new ones. One step further: if this happens + // it's due to writing faster than what can be + // processed. Maybe modify the filter at this point. + // E.g. turn of STREAM. + return; + } + } + + WebRtc_UWord16 idx = _nextFreeIdx[_activeQueue]; + _nextFreeIdx[_activeQueue]++; + + _level[_activeQueue][idx] = level; + _length[_activeQueue][idx] = length; + memcpy(_messageQueue[_activeQueue][idx], traceMessage, length); + + if(_nextFreeIdx[_activeQueue] == WEBRTC_TRACE_MAX_QUEUE-1) + { + // Loggin more messages than can be worked off. Log a warning. + memcpy(_messageQueue[_activeQueue][_nextFreeIdx[_activeQueue]], + "WARNING MISSING TRACE MESSAGES\n", 32); + _nextFreeIdx[_activeQueue]++; + } +} + +bool TraceImpl::Run(void* obj) +{ + return static_cast<TraceImpl*>(obj)->Process(); +} + +bool TraceImpl::Process() +{ + if(_event.Wait(1000) == kEventSignaled) + { + if(_traceFile.Open() || _callback) + { + // File mode (not calback mode). + WriteToFile(); + } + } else { + _traceFile.Flush(); + } + return true; +} + +void TraceImpl::WriteToFile() +{ + WebRtc_UWord8 localQueueActive = 0; + WebRtc_UWord16 localNextFreeIdx = 0; + + // There are two buffer. One for reading (for writing to file) and one for + // writing (for storing new messages). Let new messages be posted to the + // unused buffer so that the current buffer can be flushed safely. + { + CriticalSectionScoped lock(_critsectArray); + localNextFreeIdx = _nextFreeIdx[_activeQueue]; + _nextFreeIdx[_activeQueue] = 0; + localQueueActive = _activeQueue; + if(_activeQueue == 0) + { + _activeQueue = 1; + } else + { + _activeQueue = 0; + } + } + if(localNextFreeIdx == 0) + { + return; + } + + CriticalSectionScoped lock(_critsectInterface); + + for(WebRtc_UWord16 idx = 0; idx <localNextFreeIdx; idx++) + { + TraceLevel localLevel = _level[localQueueActive][idx]; + if(_callback) + { + _callback->Print(localLevel, _messageQueue[localQueueActive][idx], + _length[localQueueActive][idx]); + } + if(_traceFile.Open()) + { + if(_rowCountText > WEBRTC_TRACE_MAX_FILE_SIZE) + { + // wrap file + _rowCountText = 0; + _traceFile.Flush(); + + if(_fileCountText == 0) + { + _traceFile.Rewind(); + } else + { + WebRtc_Word8 oldFileName[FileWrapper::kMaxFileNameSize]; + WebRtc_Word8 newFileName[FileWrapper::kMaxFileNameSize]; + + // get current name + _traceFile.FileName(oldFileName, + FileWrapper::kMaxFileNameSize); + _traceFile.CloseFile(); + + _fileCountText++; + + UpdateFileName(oldFileName, newFileName, _fileCountText); + + if(_traceFile.OpenFile(newFileName, false, false, + true) == -1) + { + return; + } + } + } + if(_rowCountText == 0) + { + WebRtc_Word8 message[WEBRTC_TRACE_MAX_MESSAGE_SIZE + 1]; + WebRtc_Word32 length = AddDateTimeInfo(message); + if(length != -1) + { + message[length] = 0; + message[length-1] = '\n'; + _traceFile.Write(message, length); + _rowCountText++; + } + length = AddBuildInfo(message); + if(length != -1) + { + message[length+1] = 0; + message[length] = '\n'; + message[length-1] = '\n'; + _traceFile.Write(message, length+1); + _rowCountText++; + _rowCountText++; + } + } + WebRtc_UWord16 length = _length[localQueueActive][idx]; + _messageQueue[localQueueActive][idx][length] = 0; + _messageQueue[localQueueActive][idx][length-1] = '\n'; + _traceFile.Write(_messageQueue[localQueueActive][idx], length); + _rowCountText++; + } + } +} + +void TraceImpl::AddImpl(const TraceLevel level, const TraceModule module, + const WebRtc_Word32 id, + const char msg[WEBRTC_TRACE_MAX_MESSAGE_SIZE]) +{ + if (TraceCheck(level)) + { + char traceMessage[WEBRTC_TRACE_MAX_MESSAGE_SIZE]; + char* meassagePtr = traceMessage; + + WebRtc_Word32 len = 0; + WebRtc_Word32 ackLen = 0; + + len = AddLevel(meassagePtr, level); + if(len == -1) + { + return; + } + meassagePtr += len; + ackLen += len; + + len = AddTime(meassagePtr, level); + if(len == -1) + { + return; + } + meassagePtr += len; + ackLen += len; + + len = AddModuleAndId(meassagePtr, module, id); + if(len == -1) + { + return; + } + meassagePtr += len; + ackLen += len; + + len = AddThreadId(meassagePtr); + if(len == -1) + { + return; + } + meassagePtr += len; + ackLen += len; + + len = AddMessage(meassagePtr, msg, (WebRtc_UWord16)ackLen); + if(len == -1) + { + return; + } + ackLen += len; + AddMessageToList(traceMessage,(WebRtc_UWord16)ackLen, level); + + // Make sure that messages are written as soon as possible. + _event.Set(); + } +} + +bool TraceImpl::TraceCheck(const TraceLevel level) const +{ + return (level & levelFilter)? true:false; +} + +bool TraceImpl::UpdateFileName( + const WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize], + WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize], + const WebRtc_UWord32 newCount) const +{ + WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8); + if(length < 0) + { + return false; + } + + WebRtc_Word32 lengthWithoutFileEnding = length-1; + while(lengthWithoutFileEnding > 0) + { + if(fileNameUTF8[lengthWithoutFileEnding] == '.') + { + break; + } else { + lengthWithoutFileEnding--; + } + } + if(lengthWithoutFileEnding == 0) + { + lengthWithoutFileEnding = length; + } + WebRtc_Word32 lengthTo_ = lengthWithoutFileEnding - 1; + while(lengthTo_ > 0) + { + if(fileNameUTF8[lengthTo_] == '_') + { + break; + } else { + lengthTo_--; + } + } + + memcpy(fileNameWithCounterUTF8, fileNameUTF8, lengthTo_); + sprintf(fileNameWithCounterUTF8+lengthTo_, "_%lu%s", newCount, + fileNameUTF8+lengthWithoutFileEnding); + return true; +} + +bool TraceImpl::CreateFileName( + const WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize], + WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize], + const WebRtc_UWord32 newCount) const +{ + WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8); + if(length < 0) + { + return false; + } + + WebRtc_Word32 lengthWithoutFileEnding = length-1; + while(lengthWithoutFileEnding > 0) + { + if(fileNameUTF8[lengthWithoutFileEnding] == '.') + { + break; + }else + { + lengthWithoutFileEnding--; + } + } + if(lengthWithoutFileEnding == 0) + { + lengthWithoutFileEnding = length; + } + memcpy(fileNameWithCounterUTF8, fileNameUTF8, lengthWithoutFileEnding); + sprintf(fileNameWithCounterUTF8+lengthWithoutFileEnding, "_%lu%s", + newCount, fileNameUTF8+lengthWithoutFileEnding); + return true; +} + +WebRtc_Word32 Trace::SetLevelFilter(WebRtc_UWord32 filter) +{ + levelFilter = filter; + return 0; +}; + +WebRtc_Word32 Trace::LevelFilter(WebRtc_UWord32& filter) +{ + filter = levelFilter; + return 0; +}; + +WebRtc_Word32 Trace::TraceFile(WebRtc_Word8 fileName[FileWrapper::kMaxFileNameSize]) +{ + TraceImpl* trace = TraceImpl::GetTrace(); + if(trace) + { + int retVal = trace->TraceFileImpl(fileName); + ReturnTrace(); + return retVal; + } + return -1; +} + +WebRtc_Word32 Trace::SetTraceFile(const WebRtc_Word8* fileName, + const bool addFileCounter) +{ + TraceImpl* trace = TraceImpl::GetTrace(); + if(trace) + { + int retVal = trace->SetTraceFileImpl(fileName, addFileCounter); + ReturnTrace(); + return retVal; + } + return -1; +} + +WebRtc_Word32 Trace::SetTraceCallback(TraceCallback* callback) +{ + TraceImpl* trace = TraceImpl::GetTrace(); + if(trace) + { + int retVal = trace->SetTraceCallbackImpl(callback); + ReturnTrace(); + return retVal; + } + return -1; +} + +void Trace::Add(const TraceLevel level, const TraceModule module, + const WebRtc_Word32 id, const char* msg, ...) + +{ + TraceImpl* trace = TraceImpl::GetTrace(level); + if(trace) + { + if(trace->TraceCheck(level)) + { + char tempBuff[WEBRTC_TRACE_MAX_MESSAGE_SIZE]; + char* buff = 0; + if(msg) + { + va_list args; + va_start(args, msg); +#ifdef _WIN32 + _vsnprintf(tempBuff,WEBRTC_TRACE_MAX_MESSAGE_SIZE-1,msg,args); +#else + vsnprintf(tempBuff,WEBRTC_TRACE_MAX_MESSAGE_SIZE-1,msg,args); +#endif + va_end(args); + buff = tempBuff; + } + trace->AddImpl(level, module, id, buff); + } + ReturnTrace(); + } +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/trace_impl.h b/src/libs/webrtc/system_wrappers/trace_impl.h new file mode 100644 index 00000000..e829a2d4 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/trace_impl.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_IMPL_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_IMPL_H_ + +#include "system_wrappers/critical_section_wrapper.h" +#include "system_wrappers/event_wrapper.h" +#include "system_wrappers/file_wrapper.h" +#include "system_wrappers/trace.h" +#include "system_wrappers/thread_wrapper.h" + +namespace webrtc { +enum TraceCount +{ + WEBRTC_TRACE_DEC = 0, + WEBRTC_TRACE_INC = 1, + WEBRTC_TRACE_INC_NO_CREATE = 2 +}; + +enum TraceCreate +{ + WEBRTC_TRACE_EXIST = 0, + WEBRTC_TRACE_CREATE = 1, + WEBRTC_TRACE_DESTROY = 2 +}; + +// TODO (pwestin) WEBRTC_TRACE_MAX_QUEUE needs to be tweaked +// TODO (hellner) the buffer should be close to how much the system can write to +// file. Increasing the buffer will not solve anything. Sooner or +// later the buffer is going to fill up anyways. +#if defined(MAC_IPHONE) + #define WEBRTC_TRACE_MAX_QUEUE 2000 +#else + #define WEBRTC_TRACE_MAX_QUEUE 8000 +#endif +#define WEBRTC_TRACE_NUM_ARRAY 2 +#define WEBRTC_TRACE_MAX_MESSAGE_SIZE 256 +// Total buffer size is WEBRTC_TRACE_NUM_ARRAY (number of buffer partitions) * +// WEBRTC_TRACE_MAX_QUEUE (number of lines per buffer partition) * +// WEBRTC_TRACE_MAX_MESSAGE_SIZE (number of 1 byte charachters per line) = +// 1 or 4 Mbyte + +#define WEBRTC_TRACE_MAX_FILE_SIZE 100*1000 +// Number of rows that may be written to file. On average 110 bytes per row (max +// 256 bytes per row). So on average 110*100*1000 = 11 Mbyte, max 256*100*1000 = +// 25.6 Mbyte + +class TraceImpl : public Trace +{ +public: + virtual ~TraceImpl(); + + static Trace* CreateTrace(); + static TraceImpl* GetTrace(const TraceLevel level = kTraceAll); + + static Trace* StaticInstance(TraceCount inc, + const TraceLevel level = kTraceAll); + + WebRtc_Word32 SetTraceFileImpl(const WebRtc_Word8* fileName, + const bool addFileCounter); + WebRtc_Word32 TraceFileImpl( + WebRtc_Word8 fileName[FileWrapper::kMaxFileNameSize]); + + WebRtc_Word32 SetTraceCallbackImpl(TraceCallback* callback); + + void AddImpl(const TraceLevel level, const TraceModule module, + const WebRtc_Word32 id, const char* msg); + + bool StopThread(); + + bool TraceCheck(const TraceLevel level) const; + +protected: + TraceImpl(); + + // OS specific implementations + virtual WebRtc_Word32 AddThreadId(char* traceMessage) const = 0; + virtual WebRtc_Word32 AddTime(char* traceMessage, + const TraceLevel level) const = 0; + + virtual WebRtc_Word32 AddBuildInfo(char* traceMessage) const = 0; + virtual WebRtc_Word32 AddDateTimeInfo(char* traceMessage) const = 0; + + static bool Run(void* obj); + bool Process(); + +private: + WebRtc_Word32 AddLevel(char* szMessage, const TraceLevel level) const; + + WebRtc_Word32 AddModuleAndId(char* traceMessage, const TraceModule module, + const WebRtc_Word32 id) const; + + WebRtc_Word32 AddMessage(char* traceMessage, + const char msg[WEBRTC_TRACE_MAX_MESSAGE_SIZE], + const WebRtc_UWord16 writtenSoFar) const; + + void AddMessageToList( + const char traceMessage[WEBRTC_TRACE_MAX_MESSAGE_SIZE], + const WebRtc_UWord16 length, + const TraceLevel level); + + bool UpdateFileName( + const WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize], + WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize], + const WebRtc_UWord32 newCount) const; + + bool CreateFileName( + const WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize], + WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize], + const WebRtc_UWord32 newCount) const; + + void WriteToFile(); + + CriticalSectionWrapper& _critsectInterface; + TraceCallback* _callback; + WebRtc_UWord32 _rowCountText; + WebRtc_UWord32 _fileCountText; + + FileWrapper& _traceFile; + ThreadWrapper& _thread; + EventWrapper& _event; + + // _critsectArray protects _activeQueue + CriticalSectionWrapper& _critsectArray; + WebRtc_UWord16 _nextFreeIdx[WEBRTC_TRACE_NUM_ARRAY]; + TraceLevel _level[WEBRTC_TRACE_NUM_ARRAY][WEBRTC_TRACE_MAX_QUEUE]; + WebRtc_UWord16 _length[WEBRTC_TRACE_NUM_ARRAY][WEBRTC_TRACE_MAX_QUEUE]; + WebRtc_Word8* _messageQueue[WEBRTC_TRACE_NUM_ARRAY][WEBRTC_TRACE_MAX_QUEUE]; + WebRtc_UWord8 _activeQueue; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_IMPL_H_ diff --git a/src/libs/webrtc/system_wrappers/trace_linux.cc b/src/libs/webrtc/system_wrappers/trace_linux.cc new file mode 100644 index 00000000..8dba3beb --- /dev/null +++ b/src/libs/webrtc/system_wrappers/trace_linux.cc @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "trace_linux.h" + +#include <cassert> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <time.h> + +#ifdef ANDROID + #include <pthread.h> +#else + #include <iostream> +#endif + +#if defined(_DEBUG) + #define BUILDMODE "d" +#elif defined(DEBUG) + #define BUILDMODE "d" +#elif defined(NDEBUG) + #define BUILDMODE "r" +#else + #define BUILDMODE "?" +#endif +#define BUILDTIME __TIME__ +#define BUILDDATE __DATE__ +// example: "Oct 10 2002 12:05:30 r" +#define BUILDINFO BUILDDATE " " BUILDTIME " " BUILDMODE + +namespace webrtc { +TraceLinux::TraceLinux() +{ + _prevAPITickCount = time(NULL); + _prevTickCount = _prevAPITickCount; +} + +TraceLinux::~TraceLinux() +{ + StopThread(); +} + +WebRtc_Word32 TraceLinux::AddThreadId(char* traceMessage) const +{ + WebRtc_UWord64 threadId = (WebRtc_UWord64)pthread_self(); + sprintf(traceMessage, "%10llu; ", threadId); + // 12 bytes are written. + return 12; +} + +WebRtc_Word32 TraceLinux::AddTime(char* traceMessage, + const TraceLevel level) const +{ + time_t dwCurrentTimeInSeconds = time(NULL); + struct tm systemTime; + gmtime_r(&dwCurrentTimeInSeconds, &systemTime); + + if(level == kTraceApiCall) + { + WebRtc_UWord32 dwDeltaTime = dwCurrentTimeInSeconds - _prevTickCount; + _prevTickCount = dwCurrentTimeInSeconds; + + if(_prevTickCount == 0) + { + dwDeltaTime = 0; + } + if(dwDeltaTime > 0x0fffffff) + { + // Either wraparound or data race. + dwDeltaTime = 0; + } + if(dwDeltaTime > 99999) + { + dwDeltaTime = 99999; + } + + sprintf(traceMessage, "(%2u:%2u:%2u:%3u |%5lu) ", systemTime.tm_hour, + systemTime.tm_min, systemTime.tm_sec, 0, + static_cast<unsigned long>(dwDeltaTime)); + } else { + WebRtc_UWord32 dwDeltaTime = dwCurrentTimeInSeconds - _prevAPITickCount; + _prevAPITickCount = dwCurrentTimeInSeconds; + if(_prevAPITickCount == 0) + { + dwDeltaTime = 0; + } + if(dwDeltaTime > 0x0fffffff) + { + // Either wraparound or data race. + dwDeltaTime = 0; + } + if(dwDeltaTime > 99999) + { + dwDeltaTime = 99999; + } + sprintf(traceMessage, "(%2u:%2u:%2u:%3u |%5lu) ", systemTime.tm_hour, + systemTime.tm_min, systemTime.tm_sec, 0, + static_cast<unsigned long>(dwDeltaTime)); + } + // Messages is 22 characters. + return 22; +} + +WebRtc_Word32 TraceLinux::AddBuildInfo(char* traceMessage) const +{ + sprintf(traceMessage, "Build info: %s", BUILDINFO); + // Include NULL termination (hence + 1). + return strlen(traceMessage) + 1; +} + +WebRtc_Word32 TraceLinux::AddDateTimeInfo(char* traceMessage) const +{ + time_t t; + time(&t); + sprintf(traceMessage, "Local Date: %s", ctime(&t)); + WebRtc_Word32 len = static_cast<WebRtc_Word32>(strlen(traceMessage)); + + if ('\n' == traceMessage[len - 1]) + { + traceMessage[len - 1] = '\0'; + --len; + } + + // Messages is 12 characters. + return len + 1; +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/trace_linux.h b/src/libs/webrtc/system_wrappers/trace_linux.h new file mode 100644 index 00000000..6e327a0b --- /dev/null +++ b/src/libs/webrtc/system_wrappers/trace_linux.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_LINUX_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_LINUX_H_ + +#include "critical_section_wrapper.h" +#include "trace_impl.h" + +namespace webrtc { +class TraceLinux : public TraceImpl +{ +public: + TraceLinux(); + virtual ~TraceLinux(); + + virtual WebRtc_Word32 AddThreadId(char *traceMessage) const; + virtual WebRtc_Word32 AddTime(char* traceMessage, + const TraceLevel level) const; + + virtual WebRtc_Word32 AddBuildInfo(char* traceMessage) const; + virtual WebRtc_Word32 AddDateTimeInfo(char* traceMessage) const; + +private: + volatile mutable WebRtc_UWord32 _prevAPITickCount; + volatile mutable WebRtc_UWord32 _prevTickCount; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_LINUX_H_ diff --git a/src/libs/webrtc/system_wrappers/trace_windows.cc b/src/libs/webrtc/system_wrappers/trace_windows.cc new file mode 100644 index 00000000..404ef851 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/trace_windows.cc @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "trace_windows.h" + +#include <cassert> +#include <stdarg.h> + +#include "Mmsystem.h" + +#if defined(_DEBUG) + #define BUILDMODE "d" +#elif defined(DEBUG) + #define BUILDMODE "d" +#elif defined(NDEBUG) + #define BUILDMODE "r" +#else + #define BUILDMODE "?" +#endif +#define BUILDTIME __TIME__ +#define BUILDDATE __DATE__ +// Example: "Oct 10 2002 12:05:30 r" +#define BUILDINFO BUILDDATE " " BUILDTIME " " BUILDMODE + +namespace webrtc { +TraceWindows::TraceWindows() + : _prevAPITickCount(0), + _prevTickCount(0) +{ +} + +TraceWindows::~TraceWindows() +{ + StopThread(); +} + +WebRtc_Word32 TraceWindows::AddThreadId(char* traceMessage) const +{ + WebRtc_UWord32 threadId= GetCurrentThreadId(); + sprintf (traceMessage, "%10u; ", threadId); + // Messages is 12 characters. + return 12; +} + +WebRtc_Word32 TraceWindows::AddTime(char* traceMessage, + const TraceLevel level) const +{ + WebRtc_UWord32 dwCurrentTime = timeGetTime(); + SYSTEMTIME systemTime; + GetSystemTime(&systemTime); + + if(level == kTraceApiCall) + { + WebRtc_UWord32 dwDeltaTime = dwCurrentTime- _prevTickCount; + _prevTickCount = dwCurrentTime; + + if(_prevTickCount == 0) + { + dwDeltaTime = 0; + } + if(dwDeltaTime > 0x0fffffff) + { + // Either wraparound or data race. + dwDeltaTime = 0; + } + if(dwDeltaTime > 99999) + { + dwDeltaTime = 99999; + } + + sprintf (traceMessage, "(%2u:%2u:%2u:%3u |%5lu) ", systemTime.wHour, + systemTime.wMinute, systemTime.wSecond, + systemTime.wMilliseconds, dwDeltaTime); + } else { + WebRtc_UWord32 dwDeltaTime = dwCurrentTime - _prevAPITickCount; + _prevAPITickCount = dwCurrentTime; + + if(_prevAPITickCount == 0) + { + dwDeltaTime = 0; + } + if(dwDeltaTime > 0x0fffffff) + { + // Either wraparound or data race. + dwDeltaTime = 0; + } + if(dwDeltaTime > 99999) + { + dwDeltaTime = 99999; + } + sprintf (traceMessage, "(%2u:%2u:%2u:%3u |%5lu) ", systemTime.wHour, + systemTime.wMinute, systemTime.wSecond, + systemTime.wMilliseconds, dwDeltaTime); + } + // Messages is 12 characters. + return 22; +} + +WebRtc_Word32 TraceWindows::AddBuildInfo(char* traceMessage) const +{ + // write data and time to text file + sprintf(traceMessage, "Build info: %s", BUILDINFO); + // Include NULL termination (hence + 1). + return static_cast<WebRtc_Word32>(strlen(traceMessage)+1); +} + +WebRtc_Word32 TraceWindows::AddDateTimeInfo(char* traceMessage) const +{ + _prevAPITickCount = timeGetTime(); + _prevTickCount = _prevAPITickCount; + + SYSTEMTIME sysTime; + GetLocalTime (&sysTime); + + TCHAR szDateStr[20]; + TCHAR szTimeStr[20]; + TCHAR *pSzDateStr = szDateStr; + TCHAR *pSzTimeStr = szTimeStr; + + // Create date string (e.g. Apr 04 2002) + GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, TEXT("MMM dd yyyy"), + szDateStr, 20); + + // Create time string (e.g. 15:32:08) + GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, TEXT("HH':'mm':'ss"), + szTimeStr, 20); + + sprintf(traceMessage, "Local Date: %s Local Time: %s", szDateStr, + szTimeStr); + + // Include NULL termination (hence + 1). + return static_cast<WebRtc_Word32>(strlen(traceMessage)+ 1); +} +} // namespace webrtc diff --git a/src/libs/webrtc/system_wrappers/trace_windows.h b/src/libs/webrtc/system_wrappers/trace_windows.h new file mode 100644 index 00000000..2ead7018 --- /dev/null +++ b/src/libs/webrtc/system_wrappers/trace_windows.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_WINDOWS_H_ +#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_WINDOWS_H_ + +#include "trace_impl.h" +#include <stdio.h> +#include <windows.h> + +namespace webrtc { +class TraceWindows : public TraceImpl +{ +public: + TraceWindows(); + virtual ~TraceWindows(); + + virtual WebRtc_Word32 AddThreadId(char *traceMessage) const; + virtual WebRtc_Word32 AddTime(char* traceMessage, + const TraceLevel level) const; + + virtual WebRtc_Word32 AddBuildInfo(char* traceMessage) const; + virtual WebRtc_Word32 AddDateTimeInfo(char* traceMessage) const; +private: + volatile mutable WebRtc_UWord32 _prevAPITickCount; + volatile mutable WebRtc_UWord32 _prevTickCount; +}; +} // namespace webrtc + +#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_WINDOWS_H_ diff --git a/src/libs/webrtc/typedefs.h b/src/libs/webrtc/typedefs.h new file mode 100644 index 00000000..ae71690f --- /dev/null +++ b/src/libs/webrtc/typedefs.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * + * This file contains type definitions used in all WebRtc APIs. + * + */ + +/* Reserved words definitions */ +#define WEBRTC_EXTERN extern +#define G_CONST const +#define WEBRTC_INLINE extern __inline + +#ifndef WEBRTC_TYPEDEFS_H +#define WEBRTC_TYPEDEFS_H + +/* Define WebRtc preprocessor identifiers based on the current build platform */ +#if defined(WIN32) + // Windows & Windows Mobile + #if !defined(WEBRTC_TARGET_PC) + #define WEBRTC_TARGET_PC + #endif +#elif defined(__APPLE__) + // Mac OS X + #if defined(__LITTLE_ENDIAN__ ) //TODO: is this used? + #if !defined(WEBRTC_TARGET_MAC_INTEL) + #define WEBRTC_TARGET_MAC_INTEL + #endif + #else + #if !defined(WEBRTC_TARGET_MAC) + #define WEBRTC_TARGET_MAC + #endif + #endif +#else + // Linux etc. + #if !defined(WEBRTC_TARGET_PC) + #define WEBRTC_TARGET_PC + #endif +#endif + +#if defined(WEBRTC_TARGET_PC) + +#if !defined(_MSC_VER) + #include <stdint.h> +#else + // Define C99 equivalent types. + // Since MSVC doesn't include these headers, we have to write our own + // version to provide a compatibility layer between MSVC and the WebRTC + // headers. + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef signed long long int64_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + typedef unsigned long long uint64_t; +#endif + +#if defined(WIN32) + typedef __int64 WebRtc_Word64; + typedef unsigned __int64 WebRtc_UWord64; +#else + typedef int64_t WebRtc_Word64; + typedef uint64_t WebRtc_UWord64; +#endif + typedef int32_t WebRtc_Word32; + typedef uint32_t WebRtc_UWord32; + typedef int16_t WebRtc_Word16; + typedef uint16_t WebRtc_UWord16; + typedef char WebRtc_Word8; + typedef uint8_t WebRtc_UWord8; + + /* Define endian for the platform */ + #define WEBRTC_LITTLE_ENDIAN + +#elif defined(WEBRTC_TARGET_MAC_INTEL) + #include <stdint.h> + + typedef int64_t WebRtc_Word64; + typedef uint64_t WebRtc_UWord64; + typedef int32_t WebRtc_Word32; + typedef uint32_t WebRtc_UWord32; + typedef int16_t WebRtc_Word16; + typedef char WebRtc_Word8; + typedef uint16_t WebRtc_UWord16; + typedef uint8_t WebRtc_UWord8; + + /* Define endian for the platform */ + #define WEBRTC_LITTLE_ENDIAN + +#else + + #error "No platform defined for WebRtc type definitions (webrtc_typedefs.h)" + +#endif + + +#endif // WEBRTC_TYPEDEFS_H diff --git a/src/libs/webrtc/utility/fft4g.c b/src/libs/webrtc/utility/fft4g.c new file mode 100644 index 00000000..9a84368c --- /dev/null +++ b/src/libs/webrtc/utility/fft4g.c @@ -0,0 +1,1356 @@ +/* + * http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html + * Copyright Takuya OOURA, 1996-2001 + * + * You may use, copy, modify and distribute this code for any purpose (include + * commercial use) and without fee. Please refer to this package when you modify + * this code. + * + * Changes: + * Trivial type modifications by the WebRTC authors. + */ + +/* +Fast Fourier/Cosine/Sine Transform + dimension :one + data length :power of 2 + decimation :frequency + radix :4, 2 + data :inplace + table :use +functions + cdft: Complex Discrete Fourier Transform + rdft: Real Discrete Fourier Transform + ddct: Discrete Cosine Transform + ddst: Discrete Sine Transform + dfct: Cosine Transform of RDFT (Real Symmetric DFT) + dfst: Sine Transform of RDFT (Real Anti-symmetric DFT) +function prototypes + void cdft(int, int, float *, int *, float *); + void rdft(int, int, float *, int *, float *); + void ddct(int, int, float *, int *, float *); + void ddst(int, int, float *, int *, float *); + void dfct(int, float *, float *, int *, float *); + void dfst(int, float *, float *, int *, float *); + + +-------- Complex DFT (Discrete Fourier Transform) -------- + [definition] + <case1> + X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n + <case2> + X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n + (notes: sum_j=0^n-1 is a summation from j=0 to n-1) + [usage] + <case1> + ip[0] = 0; // first time only + cdft(2*n, 1, a, ip, w); + <case2> + ip[0] = 0; // first time only + cdft(2*n, -1, a, ip, w); + [parameters] + 2*n :data length (int) + n >= 1, n = power of 2 + a[0...2*n-1] :input/output data (float *) + input data + a[2*j] = Re(x[j]), + a[2*j+1] = Im(x[j]), 0<=j<n + output data + a[2*k] = Re(X[k]), + a[2*k+1] = Im(X[k]), 0<=k<n + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n) + strictly, + length of ip >= + 2+(1<<(int)(log(n+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n/2-1] :cos/sin table (float *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + cdft(2*n, -1, a, ip, w); + is + cdft(2*n, 1, a, ip, w); + for (j = 0; j <= 2 * n - 1; j++) { + a[j] *= 1.0 / n; + } + . + + +-------- Real DFT / Inverse of Real DFT -------- + [definition] + <case1> RDFT + R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2 + I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2 + <case2> IRDFT (excluding scale) + a[k] = (R[0] + R[n/2]*cos(pi*k))/2 + + sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) + + sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n + [usage] + <case1> + ip[0] = 0; // first time only + rdft(n, 1, a, ip, w); + <case2> + ip[0] = 0; // first time only + rdft(n, -1, a, ip, w); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (float *) + <case1> + output data + a[2*k] = R[k], 0<=k<n/2 + a[2*k+1] = I[k], 0<k<n/2 + a[1] = R[n/2] + <case2> + input data + a[2*j] = R[j], 0<=j<n/2 + a[2*j+1] = I[j], 0<j<n/2 + a[1] = R[n/2] + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/2) + strictly, + length of ip >= + 2+(1<<(int)(log(n/2+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n/2-1] :cos/sin table (float *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + rdft(n, 1, a, ip, w); + is + rdft(n, -1, a, ip, w); + for (j = 0; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + +-------- DCT (Discrete Cosine Transform) / Inverse of DCT -------- + [definition] + <case1> IDCT (excluding scale) + C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n + <case2> DCT + C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k<n + [usage] + <case1> + ip[0] = 0; // first time only + ddct(n, 1, a, ip, w); + <case2> + ip[0] = 0; // first time only + ddct(n, -1, a, ip, w); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (float *) + output data + a[k] = C[k], 0<=k<n + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/2) + strictly, + length of ip >= + 2+(1<<(int)(log(n/2+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/4-1] :cos/sin table (float *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + ddct(n, -1, a, ip, w); + is + a[0] *= 0.5; + ddct(n, 1, a, ip, w); + for (j = 0; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + +-------- DST (Discrete Sine Transform) / Inverse of DST -------- + [definition] + <case1> IDST (excluding scale) + S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n + <case2> DST + S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0<k<=n + [usage] + <case1> + ip[0] = 0; // first time only + ddst(n, 1, a, ip, w); + <case2> + ip[0] = 0; // first time only + ddst(n, -1, a, ip, w); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (float *) + <case1> + input data + a[j] = A[j], 0<j<n + a[0] = A[n] + output data + a[k] = S[k], 0<=k<n + <case2> + output data + a[k] = S[k], 0<k<n + a[0] = S[n] + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/2) + strictly, + length of ip >= + 2+(1<<(int)(log(n/2+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/4-1] :cos/sin table (float *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + ddst(n, -1, a, ip, w); + is + a[0] *= 0.5; + ddst(n, 1, a, ip, w); + for (j = 0; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + +-------- Cosine Transform of RDFT (Real Symmetric DFT) -------- + [definition] + C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n + [usage] + ip[0] = 0; // first time only + dfct(n, a, t, ip, w); + [parameters] + n :data length - 1 (int) + n >= 2, n = power of 2 + a[0...n] :input/output data (float *) + output data + a[k] = C[k], 0<=k<=n + t[0...n/2] :work area (float *) + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/4) + strictly, + length of ip >= + 2+(1<<(int)(log(n/4+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/8-1] :cos/sin table (float *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + a[0] *= 0.5; + a[n] *= 0.5; + dfct(n, a, t, ip, w); + is + a[0] *= 0.5; + a[n] *= 0.5; + dfct(n, a, t, ip, w); + for (j = 0; j <= n; j++) { + a[j] *= 2.0 / n; + } + . + + +-------- Sine Transform of RDFT (Real Anti-symmetric DFT) -------- + [definition] + S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n + [usage] + ip[0] = 0; // first time only + dfst(n, a, t, ip, w); + [parameters] + n :data length + 1 (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (float *) + output data + a[k] = S[k], 0<k<n + (a[0] is used for work area) + t[0...n/2-1] :work area (float *) + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/4) + strictly, + length of ip >= + 2+(1<<(int)(log(n/4+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/8-1] :cos/sin table (float *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + dfst(n, a, t, ip, w); + is + dfst(n, a, t, ip, w); + for (j = 1; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + +Appendix : + The cos/sin table is recalculated when the larger table required. + w[] and ip[] are compatible with all routines. +*/ + +void cdft(int n, int isgn, float *a, int *ip, float *w) +{ + void makewt(int nw, int *ip, float *w); + void bitrv2(int n, int *ip, float *a); + void bitrv2conj(int n, int *ip, float *a); + void cftfsub(int n, float *a, float *w); + void cftbsub(int n, float *a, float *w); + + if (n > (ip[0] << 2)) { + makewt(n >> 2, ip, w); + } + if (n > 4) { + if (isgn >= 0) { + bitrv2(n, ip + 2, a); + cftfsub(n, a, w); + } else { + bitrv2conj(n, ip + 2, a); + cftbsub(n, a, w); + } + } else if (n == 4) { + cftfsub(n, a, w); + } +} + + +void rdft(int n, int isgn, float *a, int *ip, float *w) +{ + void makewt(int nw, int *ip, float *w); + void makect(int nc, int *ip, float *c); + void bitrv2(int n, int *ip, float *a); + void cftfsub(int n, float *a, float *w); + void cftbsub(int n, float *a, float *w); + void rftfsub(int n, float *a, int nc, float *c); + void rftbsub(int n, float *a, int nc, float *c); + int nw, nc; + float xi; + + nw = ip[0]; + if (n > (nw << 2)) { + nw = n >> 2; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > (nc << 2)) { + nc = n >> 2; + makect(nc, ip, w + nw); + } + if (isgn >= 0) { + if (n > 4) { + bitrv2(n, ip + 2, a); + cftfsub(n, a, w); + rftfsub(n, a, nc, w + nw); + } else if (n == 4) { + cftfsub(n, a, w); + } + xi = a[0] - a[1]; + a[0] += a[1]; + a[1] = xi; + } else { + a[1] = 0.5f * (a[0] - a[1]); + a[0] -= a[1]; + if (n > 4) { + rftbsub(n, a, nc, w + nw); + bitrv2(n, ip + 2, a); + cftbsub(n, a, w); + } else if (n == 4) { + cftfsub(n, a, w); + } + } +} + + +void ddct(int n, int isgn, float *a, int *ip, float *w) +{ + void makewt(int nw, int *ip, float *w); + void makect(int nc, int *ip, float *c); + void bitrv2(int n, int *ip, float *a); + void cftfsub(int n, float *a, float *w); + void cftbsub(int n, float *a, float *w); + void rftfsub(int n, float *a, int nc, float *c); + void rftbsub(int n, float *a, int nc, float *c); + void dctsub(int n, float *a, int nc, float *c); + int j, nw, nc; + float xr; + + nw = ip[0]; + if (n > (nw << 2)) { + nw = n >> 2; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > nc) { + nc = n; + makect(nc, ip, w + nw); + } + if (isgn < 0) { + xr = a[n - 1]; + for (j = n - 2; j >= 2; j -= 2) { + a[j + 1] = a[j] - a[j - 1]; + a[j] += a[j - 1]; + } + a[1] = a[0] - xr; + a[0] += xr; + if (n > 4) { + rftbsub(n, a, nc, w + nw); + bitrv2(n, ip + 2, a); + cftbsub(n, a, w); + } else if (n == 4) { + cftfsub(n, a, w); + } + } + dctsub(n, a, nc, w + nw); + if (isgn >= 0) { + if (n > 4) { + bitrv2(n, ip + 2, a); + cftfsub(n, a, w); + rftfsub(n, a, nc, w + nw); + } else if (n == 4) { + cftfsub(n, a, w); + } + xr = a[0] - a[1]; + a[0] += a[1]; + for (j = 2; j < n; j += 2) { + a[j - 1] = a[j] - a[j + 1]; + a[j] += a[j + 1]; + } + a[n - 1] = xr; + } +} + + +void ddst(int n, int isgn, float *a, int *ip, float *w) +{ + void makewt(int nw, int *ip, float *w); + void makect(int nc, int *ip, float *c); + void bitrv2(int n, int *ip, float *a); + void cftfsub(int n, float *a, float *w); + void cftbsub(int n, float *a, float *w); + void rftfsub(int n, float *a, int nc, float *c); + void rftbsub(int n, float *a, int nc, float *c); + void dstsub(int n, float *a, int nc, float *c); + int j, nw, nc; + float xr; + + nw = ip[0]; + if (n > (nw << 2)) { + nw = n >> 2; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > nc) { + nc = n; + makect(nc, ip, w + nw); + } + if (isgn < 0) { + xr = a[n - 1]; + for (j = n - 2; j >= 2; j -= 2) { + a[j + 1] = -a[j] - a[j - 1]; + a[j] -= a[j - 1]; + } + a[1] = a[0] + xr; + a[0] -= xr; + if (n > 4) { + rftbsub(n, a, nc, w + nw); + bitrv2(n, ip + 2, a); + cftbsub(n, a, w); + } else if (n == 4) { + cftfsub(n, a, w); + } + } + dstsub(n, a, nc, w + nw); + if (isgn >= 0) { + if (n > 4) { + bitrv2(n, ip + 2, a); + cftfsub(n, a, w); + rftfsub(n, a, nc, w + nw); + } else if (n == 4) { + cftfsub(n, a, w); + } + xr = a[0] - a[1]; + a[0] += a[1]; + for (j = 2; j < n; j += 2) { + a[j - 1] = -a[j] - a[j + 1]; + a[j] -= a[j + 1]; + } + a[n - 1] = -xr; + } +} + + +void dfct(int n, float *a, float *t, int *ip, float *w) +{ + void makewt(int nw, int *ip, float *w); + void makect(int nc, int *ip, float *c); + void bitrv2(int n, int *ip, float *a); + void cftfsub(int n, float *a, float *w); + void rftfsub(int n, float *a, int nc, float *c); + void dctsub(int n, float *a, int nc, float *c); + int j, k, l, m, mh, nw, nc; + float xr, xi, yr, yi; + + nw = ip[0]; + if (n > (nw << 3)) { + nw = n >> 3; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > (nc << 1)) { + nc = n >> 1; + makect(nc, ip, w + nw); + } + m = n >> 1; + yi = a[m]; + xi = a[0] + a[n]; + a[0] -= a[n]; + t[0] = xi - yi; + t[m] = xi + yi; + if (n > 2) { + mh = m >> 1; + for (j = 1; j < mh; j++) { + k = m - j; + xr = a[j] - a[n - j]; + xi = a[j] + a[n - j]; + yr = a[k] - a[n - k]; + yi = a[k] + a[n - k]; + a[j] = xr; + a[k] = yr; + t[j] = xi - yi; + t[k] = xi + yi; + } + t[mh] = a[mh] + a[n - mh]; + a[mh] -= a[n - mh]; + dctsub(m, a, nc, w + nw); + if (m > 4) { + bitrv2(m, ip + 2, a); + cftfsub(m, a, w); + rftfsub(m, a, nc, w + nw); + } else if (m == 4) { + cftfsub(m, a, w); + } + a[n - 1] = a[0] - a[1]; + a[1] = a[0] + a[1]; + for (j = m - 2; j >= 2; j -= 2) { + a[2 * j + 1] = a[j] + a[j + 1]; + a[2 * j - 1] = a[j] - a[j + 1]; + } + l = 2; + m = mh; + while (m >= 2) { + dctsub(m, t, nc, w + nw); + if (m > 4) { + bitrv2(m, ip + 2, t); + cftfsub(m, t, w); + rftfsub(m, t, nc, w + nw); + } else if (m == 4) { + cftfsub(m, t, w); + } + a[n - l] = t[0] - t[1]; + a[l] = t[0] + t[1]; + k = 0; + for (j = 2; j < m; j += 2) { + k += l << 2; + a[k - l] = t[j] - t[j + 1]; + a[k + l] = t[j] + t[j + 1]; + } + l <<= 1; + mh = m >> 1; + for (j = 0; j < mh; j++) { + k = m - j; + t[j] = t[m + k] - t[m + j]; + t[k] = t[m + k] + t[m + j]; + } + t[mh] = t[m + mh]; + m = mh; + } + a[l] = t[0]; + a[n] = t[2] - t[1]; + a[0] = t[2] + t[1]; + } else { + a[1] = a[0]; + a[2] = t[0]; + a[0] = t[1]; + } +} + + +void dfst(int n, float *a, float *t, int *ip, float *w) +{ + void makewt(int nw, int *ip, float *w); + void makect(int nc, int *ip, float *c); + void bitrv2(int n, int *ip, float *a); + void cftfsub(int n, float *a, float *w); + void rftfsub(int n, float *a, int nc, float *c); + void dstsub(int n, float *a, int nc, float *c); + int j, k, l, m, mh, nw, nc; + float xr, xi, yr, yi; + + nw = ip[0]; + if (n > (nw << 3)) { + nw = n >> 3; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > (nc << 1)) { + nc = n >> 1; + makect(nc, ip, w + nw); + } + if (n > 2) { + m = n >> 1; + mh = m >> 1; + for (j = 1; j < mh; j++) { + k = m - j; + xr = a[j] + a[n - j]; + xi = a[j] - a[n - j]; + yr = a[k] + a[n - k]; + yi = a[k] - a[n - k]; + a[j] = xr; + a[k] = yr; + t[j] = xi + yi; + t[k] = xi - yi; + } + t[0] = a[mh] - a[n - mh]; + a[mh] += a[n - mh]; + a[0] = a[m]; + dstsub(m, a, nc, w + nw); + if (m > 4) { + bitrv2(m, ip + 2, a); + cftfsub(m, a, w); + rftfsub(m, a, nc, w + nw); + } else if (m == 4) { + cftfsub(m, a, w); + } + a[n - 1] = a[1] - a[0]; + a[1] = a[0] + a[1]; + for (j = m - 2; j >= 2; j -= 2) { + a[2 * j + 1] = a[j] - a[j + 1]; + a[2 * j - 1] = -a[j] - a[j + 1]; + } + l = 2; + m = mh; + while (m >= 2) { + dstsub(m, t, nc, w + nw); + if (m > 4) { + bitrv2(m, ip + 2, t); + cftfsub(m, t, w); + rftfsub(m, t, nc, w + nw); + } else if (m == 4) { + cftfsub(m, t, w); + } + a[n - l] = t[1] - t[0]; + a[l] = t[0] + t[1]; + k = 0; + for (j = 2; j < m; j += 2) { + k += l << 2; + a[k - l] = -t[j] - t[j + 1]; + a[k + l] = t[j] - t[j + 1]; + } + l <<= 1; + mh = m >> 1; + for (j = 1; j < mh; j++) { + k = m - j; + t[j] = t[m + k] + t[m + j]; + t[k] = t[m + k] - t[m + j]; + } + t[0] = t[m + mh]; + m = mh; + } + a[l] = t[0]; + } + a[0] = 0; +} + + +/* -------- initializing routines -------- */ + + +#include <math.h> + +void makewt(int nw, int *ip, float *w) +{ + void bitrv2(int n, int *ip, float *a); + int j, nwh; + float delta, x, y; + + ip[0] = nw; + ip[1] = 1; + if (nw > 2) { + nwh = nw >> 1; + delta = (float)atan(1.0f) / nwh; + w[0] = 1; + w[1] = 0; + w[nwh] = (float)cos(delta * nwh); + w[nwh + 1] = w[nwh]; + if (nwh > 2) { + for (j = 2; j < nwh; j += 2) { + x = (float)cos(delta * j); + y = (float)sin(delta * j); + w[j] = x; + w[j + 1] = y; + w[nw - j] = y; + w[nw - j + 1] = x; + } + bitrv2(nw, ip + 2, w); + } + } +} + + +void makect(int nc, int *ip, float *c) +{ + int j, nch; + float delta; + + ip[1] = nc; + if (nc > 1) { + nch = nc >> 1; + delta = (float)atan(1.0f) / nch; + c[0] = (float)cos(delta * nch); + c[nch] = 0.5f * c[0]; + for (j = 1; j < nch; j++) { + c[j] = 0.5f * (float)cos(delta * j); + c[nc - j] = 0.5f * (float)sin(delta * j); + } + } +} + + +/* -------- child routines -------- */ + + +void bitrv2(int n, int *ip, float *a) +{ + int j, j1, k, k1, l, m, m2; + float xr, xi, yr, yi; + + ip[0] = 0; + l = n; + m = 1; + while ((m << 3) < l) { + l >>= 1; + for (j = 0; j < m; j++) { + ip[m + j] = ip[j] + l; + } + m <<= 1; + } + m2 = 2 * m; + if ((m << 3) == l) { + for (k = 0; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 2 * j + ip[k]; + k1 = 2 * k + ip[j]; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += 2 * m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 -= m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += 2 * m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + j1 = 2 * k + m2 + ip[k]; + k1 = j1 + m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + } else { + for (k = 1; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 2 * j + ip[k]; + k1 = 2 * k + ip[j]; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + } + } +} + + +void bitrv2conj(int n, int *ip, float *a) +{ + int j, j1, k, k1, l, m, m2; + float xr, xi, yr, yi; + + ip[0] = 0; + l = n; + m = 1; + while ((m << 3) < l) { + l >>= 1; + for (j = 0; j < m; j++) { + ip[m + j] = ip[j] + l; + } + m <<= 1; + } + m2 = 2 * m; + if ((m << 3) == l) { + for (k = 0; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 2 * j + ip[k]; + k1 = 2 * k + ip[j]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += 2 * m2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 -= m2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += 2 * m2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 2 * k + ip[k]; + a[k1 + 1] = -a[k1 + 1]; + j1 = k1 + m2; + k1 = j1 + m2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + k1 += m2; + a[k1 + 1] = -a[k1 + 1]; + } + } else { + a[1] = -a[1]; + a[m2 + 1] = -a[m2 + 1]; + for (k = 1; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 2 * j + ip[k]; + k1 = 2 * k + ip[j]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += m2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 2 * k + ip[k]; + a[k1 + 1] = -a[k1 + 1]; + a[k1 + m2 + 1] = -a[k1 + m2 + 1]; + } + } +} + + +void cftfsub(int n, float *a, float *w) +{ + void cft1st(int n, float *a, float *w); + void cftmdl(int n, int l, float *a, float *w); + int j, j1, j2, j3, l; + float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 2; + if (n > 8) { + cft1st(n, a, w); + l = 8; + while ((l << 2) < n) { + cftmdl(n, l, a, w); + l <<= 2; + } + } + if ((l << 2) == n) { + for (j = 0; j < l; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i - x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + } + } else { + for (j = 0; j < l; j += 2) { + j1 = j + l; + x0r = a[j] - a[j1]; + x0i = a[j + 1] - a[j1 + 1]; + a[j] += a[j1]; + a[j + 1] += a[j1 + 1]; + a[j1] = x0r; + a[j1 + 1] = x0i; + } + } +} + + +void cftbsub(int n, float *a, float *w) +{ + void cft1st(int n, float *a, float *w); + void cftmdl(int n, int l, float *a, float *w); + int j, j1, j2, j3, l; + float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 2; + if (n > 8) { + cft1st(n, a, w); + l = 8; + while ((l << 2) < n) { + cftmdl(n, l, a, w); + l <<= 2; + } + } + if ((l << 2) == n) { + for (j = 0; j < l; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = -a[j + 1] - a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = -a[j + 1] + a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i - x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i + x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i - x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i + x3r; + } + } else { + for (j = 0; j < l; j += 2) { + j1 = j + l; + x0r = a[j] - a[j1]; + x0i = -a[j + 1] + a[j1 + 1]; + a[j] += a[j1]; + a[j + 1] = -a[j + 1] - a[j1 + 1]; + a[j1] = x0r; + a[j1 + 1] = x0i; + } + } +} + + +void cft1st(int n, float *a, float *w) +{ + int j, k1, k2; + float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + x0r = a[0] + a[2]; + x0i = a[1] + a[3]; + x1r = a[0] - a[2]; + x1i = a[1] - a[3]; + x2r = a[4] + a[6]; + x2i = a[5] + a[7]; + x3r = a[4] - a[6]; + x3i = a[5] - a[7]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[4] = x0r - x2r; + a[5] = x0i - x2i; + a[2] = x1r - x3i; + a[3] = x1i + x3r; + a[6] = x1r + x3i; + a[7] = x1i - x3r; + wk1r = w[2]; + x0r = a[8] + a[10]; + x0i = a[9] + a[11]; + x1r = a[8] - a[10]; + x1i = a[9] - a[11]; + x2r = a[12] + a[14]; + x2i = a[13] + a[15]; + x3r = a[12] - a[14]; + x3i = a[13] - a[15]; + a[8] = x0r + x2r; + a[9] = x0i + x2i; + a[12] = x2i - x0i; + a[13] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[10] = wk1r * (x0r - x0i); + a[11] = wk1r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[14] = wk1r * (x0i - x0r); + a[15] = wk1r * (x0i + x0r); + k1 = 0; + for (j = 16; j < n; j += 16) { + k1 += 2; + k2 = 2 * k1; + wk2r = w[k1]; + wk2i = w[k1 + 1]; + wk1r = w[k2]; + wk1i = w[k2 + 1]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + x0r = a[j] + a[j + 2]; + x0i = a[j + 1] + a[j + 3]; + x1r = a[j] - a[j + 2]; + x1i = a[j + 1] - a[j + 3]; + x2r = a[j + 4] + a[j + 6]; + x2i = a[j + 5] + a[j + 7]; + x3r = a[j + 4] - a[j + 6]; + x3i = a[j + 5] - a[j + 7]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j + 4] = wk2r * x0r - wk2i * x0i; + a[j + 5] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j + 2] = wk1r * x0r - wk1i * x0i; + a[j + 3] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j + 6] = wk3r * x0r - wk3i * x0i; + a[j + 7] = wk3r * x0i + wk3i * x0r; + wk1r = w[k2 + 2]; + wk1i = w[k2 + 3]; + wk3r = wk1r - 2 * wk2r * wk1i; + wk3i = 2 * wk2r * wk1r - wk1i; + x0r = a[j + 8] + a[j + 10]; + x0i = a[j + 9] + a[j + 11]; + x1r = a[j + 8] - a[j + 10]; + x1i = a[j + 9] - a[j + 11]; + x2r = a[j + 12] + a[j + 14]; + x2i = a[j + 13] + a[j + 15]; + x3r = a[j + 12] - a[j + 14]; + x3i = a[j + 13] - a[j + 15]; + a[j + 8] = x0r + x2r; + a[j + 9] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j + 12] = -wk2i * x0r - wk2r * x0i; + a[j + 13] = -wk2i * x0i + wk2r * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j + 10] = wk1r * x0r - wk1i * x0i; + a[j + 11] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j + 14] = wk3r * x0r - wk3i * x0i; + a[j + 15] = wk3r * x0i + wk3i * x0r; + } +} + + +void cftmdl(int n, int l, float *a, float *w) +{ + int j, j1, j2, j3, k, k1, k2, m, m2; + float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + m = l << 2; + for (j = 0; j < l; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i - x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + } + wk1r = w[2]; + for (j = m; j < l + m; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x2i - x0i; + a[j2 + 1] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * (x0r - x0i); + a[j1 + 1] = wk1r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[j3] = wk1r * (x0i - x0r); + a[j3 + 1] = wk1r * (x0i + x0r); + } + k1 = 0; + m2 = 2 * m; + for (k = m2; k < n; k += m2) { + k1 += 2; + k2 = 2 * k1; + wk2r = w[k1]; + wk2i = w[k1 + 1]; + wk1r = w[k2]; + wk1i = w[k2 + 1]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for (j = k; j < l + k; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2] = wk2r * x0r - wk2i * x0i; + a[j2 + 1] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * x0r - wk1i * x0i; + a[j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r - wk3i * x0i; + a[j3 + 1] = wk3r * x0i + wk3i * x0r; + } + wk1r = w[k2 + 2]; + wk1i = w[k2 + 3]; + wk3r = wk1r - 2 * wk2r * wk1i; + wk3i = 2 * wk2r * wk1r - wk1i; + for (j = k + m; j < l + (k + m); j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2] = -wk2i * x0r - wk2r * x0i; + a[j2 + 1] = -wk2i * x0i + wk2r * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * x0r - wk1i * x0i; + a[j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r - wk3i * x0i; + a[j3 + 1] = wk3r * x0i + wk3i * x0r; + } + } +} + + +void rftfsub(int n, float *a, int nc, float *c) +{ + int j, k, kk, ks, m; + float wkr, wki, xr, xi, yr, yi; + + m = n >> 1; + ks = 2 * nc / m; + kk = 0; + for (j = 2; j < m; j += 2) { + k = n - j; + kk += ks; + wkr = 0.5f - c[nc - kk]; + wki = c[kk]; + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr - wki * xi; + yi = wkr * xi + wki * xr; + a[j] -= yr; + a[j + 1] -= yi; + a[k] += yr; + a[k + 1] -= yi; + } +} + + +void rftbsub(int n, float *a, int nc, float *c) +{ + int j, k, kk, ks, m; + float wkr, wki, xr, xi, yr, yi; + + a[1] = -a[1]; + m = n >> 1; + ks = 2 * nc / m; + kk = 0; + for (j = 2; j < m; j += 2) { + k = n - j; + kk += ks; + wkr = 0.5f - c[nc - kk]; + wki = c[kk]; + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr + wki * xi; + yi = wkr * xi - wki * xr; + a[j] -= yr; + a[j + 1] = yi - a[j + 1]; + a[k] += yr; + a[k + 1] = yi - a[k + 1]; + } + a[m + 1] = -a[m + 1]; +} + + +void dctsub(int n, float *a, int nc, float *c) +{ + int j, k, kk, ks, m; + float wkr, wki, xr; + + m = n >> 1; + ks = nc / n; + kk = 0; + for (j = 1; j < m; j++) { + k = n - j; + kk += ks; + wkr = c[kk] - c[nc - kk]; + wki = c[kk] + c[nc - kk]; + xr = wki * a[j] - wkr * a[k]; + a[j] = wkr * a[j] + wki * a[k]; + a[k] = xr; + } + a[m] *= c[0]; +} + + +void dstsub(int n, float *a, int nc, float *c) +{ + int j, k, kk, ks, m; + float wkr, wki, xr; + + m = n >> 1; + ks = nc / n; + kk = 0; + for (j = 1; j < m; j++) { + k = n - j; + kk += ks; + wkr = c[kk] - c[nc - kk]; + wki = c[kk] + c[nc - kk]; + xr = wki * a[k] - wkr * a[j]; + a[k] = wkr * a[k] + wki * a[j]; + a[j] = xr; + } + a[m] *= c[0]; +} + diff --git a/src/libs/webrtc/utility/fft4g.h b/src/libs/webrtc/utility/fft4g.h new file mode 100644 index 00000000..373ff148 --- /dev/null +++ b/src/libs/webrtc/utility/fft4g.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_FFT4G_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_FFT4G_H_ + +void rdft(int, int, float *, int *, float *); +void cdft(int, int, float *, int *, float *); + +#endif + diff --git a/src/libs/webrtc/utility/ring_buffer.c b/src/libs/webrtc/utility/ring_buffer.c new file mode 100644 index 00000000..ea2e3544 --- /dev/null +++ b/src/libs/webrtc/utility/ring_buffer.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Provides a generic ring buffer that can be written to and read from with + * arbitrarily sized blocks. The AEC uses this for several different tasks. + */ + +#include <stdlib.h> +#include <string.h> +#include "ring_buffer.h" + +typedef struct { + int readPos; + int writePos; + int size; + char rwWrap; + bufdata_t *data; +} buf_t; + +enum {SAME_WRAP, DIFF_WRAP}; + +int WebRtcApm_CreateBuffer(void **bufInst, int size) +{ + buf_t *buf = NULL; + + if (size < 0) { + return -1; + } + + buf = malloc(sizeof(buf_t)); + *bufInst = buf; + if (buf == NULL) { + return -1; + } + + buf->data = malloc(size*sizeof(bufdata_t)); + if (buf->data == NULL) { + free(buf); + buf = NULL; + return -1; + } + + buf->size = size; + return 0; +} + +int WebRtcApm_InitBuffer(void *bufInst) +{ + buf_t *buf = (buf_t*)bufInst; + + buf->readPos = 0; + buf->writePos = 0; + buf->rwWrap = SAME_WRAP; + + // Initialize buffer to zeros + memset(buf->data, 0, sizeof(bufdata_t)*buf->size); + + return 0; +} + +int WebRtcApm_FreeBuffer(void *bufInst) +{ + buf_t *buf = (buf_t*)bufInst; + + if (buf == NULL) { + return -1; + } + + free(buf->data); + free(buf); + + return 0; +} + +int WebRtcApm_ReadBuffer(void *bufInst, bufdata_t *data, int size) +{ + buf_t *buf = (buf_t*)bufInst; + int n = 0, margin = 0; + + if (size <= 0 || size > buf->size) { + return -1; + } + + n = size; + if (buf->rwWrap == DIFF_WRAP) { + margin = buf->size - buf->readPos; + if (n > margin) { + buf->rwWrap = SAME_WRAP; + memcpy(data, buf->data + buf->readPos, + sizeof(bufdata_t)*margin); + buf->readPos = 0; + n = size - margin; + } + else { + memcpy(data, buf->data + buf->readPos, + sizeof(bufdata_t)*n); + buf->readPos += n; + return n; + } + } + + if (buf->rwWrap == SAME_WRAP) { + margin = buf->writePos - buf->readPos; + if (margin > n) + margin = n; + memcpy(data + size - n, buf->data + buf->readPos, + sizeof(bufdata_t)*margin); + buf->readPos += margin; + n -= margin; + } + + return size - n; +} + +int WebRtcApm_WriteBuffer(void *bufInst, const bufdata_t *data, int size) +{ + buf_t *buf = (buf_t*)bufInst; + int n = 0, margin = 0; + + if (size < 0 || size > buf->size) { + return -1; + } + + n = size; + if (buf->rwWrap == SAME_WRAP) { + margin = buf->size - buf->writePos; + if (n > margin) { + buf->rwWrap = DIFF_WRAP; + memcpy(buf->data + buf->writePos, data, + sizeof(bufdata_t)*margin); + buf->writePos = 0; + n = size - margin; + } + else { + memcpy(buf->data + buf->writePos, data, + sizeof(bufdata_t)*n); + buf->writePos += n; + return n; + } + } + + if (buf->rwWrap == DIFF_WRAP) { + margin = buf->readPos - buf->writePos; + if (margin > n) + margin = n; + memcpy(buf->data + buf->writePos, data + size - n, + sizeof(bufdata_t)*margin); + buf->writePos += margin; + n -= margin; + } + + return size - n; +} + +int WebRtcApm_FlushBuffer(void *bufInst, int size) +{ + buf_t *buf = (buf_t*)bufInst; + int n = 0, margin = 0; + + if (size <= 0 || size > buf->size) { + return -1; + } + + n = size; + if (buf->rwWrap == DIFF_WRAP) { + margin = buf->size - buf->readPos; + if (n > margin) { + buf->rwWrap = SAME_WRAP; + buf->readPos = 0; + n = size - margin; + } + else { + buf->readPos += n; + return n; + } + } + + if (buf->rwWrap == SAME_WRAP) { + margin = buf->writePos - buf->readPos; + if (margin > n) + margin = n; + buf->readPos += margin; + n -= margin; + } + + return size - n; +} + +int WebRtcApm_StuffBuffer(void *bufInst, int size) +{ + buf_t *buf = (buf_t*)bufInst; + int n = 0, margin = 0; + + if (size <= 0 || size > buf->size) { + return -1; + } + + n = size; + if (buf->rwWrap == SAME_WRAP) { + margin = buf->readPos; + if (n > margin) { + buf->rwWrap = DIFF_WRAP; + buf->readPos = buf->size - 1; + n -= margin + 1; + } + else { + buf->readPos -= n; + return n; + } + } + + if (buf->rwWrap == DIFF_WRAP) { + margin = buf->readPos - buf->writePos; + if (margin > n) + margin = n; + buf->readPos -= margin; + n -= margin; + } + + return size - n; +} + +int WebRtcApm_get_buffer_size(const void *bufInst) +{ + const buf_t *buf = (buf_t*)bufInst; + + if (buf->rwWrap == SAME_WRAP) + return buf->writePos - buf->readPos; + else + return buf->size - buf->readPos + buf->writePos; +} diff --git a/src/libs/webrtc/utility/ring_buffer.h b/src/libs/webrtc/utility/ring_buffer.h new file mode 100644 index 00000000..0fd261df --- /dev/null +++ b/src/libs/webrtc/utility/ring_buffer.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * Specifies the interface for the AEC generic buffer. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_RING_BUFFER_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_RING_BUFFER_H_ + +// Determines buffer datatype +typedef short bufdata_t; + +// Unless otherwise specified, functions return 0 on success and -1 on error +int WebRtcApm_CreateBuffer(void **bufInst, int size); +int WebRtcApm_InitBuffer(void *bufInst); +int WebRtcApm_FreeBuffer(void *bufInst); + +// Returns number of samples read +int WebRtcApm_ReadBuffer(void *bufInst, bufdata_t *data, int size); + +// Returns number of samples written +int WebRtcApm_WriteBuffer(void *bufInst, const bufdata_t *data, int size); + +// Returns number of samples flushed +int WebRtcApm_FlushBuffer(void *bufInst, int size); + +// Returns number of samples stuffed +int WebRtcApm_StuffBuffer(void *bufInst, int size); + +// Returns number of samples in buffer +int WebRtcApm_get_buffer_size(const void *bufInst); + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_RING_BUFFER_H_ diff --git a/src/libs/webrtc/vad/vad_const.c b/src/libs/webrtc/vad/vad_const.c new file mode 100644 index 00000000..47b6a4b8 --- /dev/null +++ b/src/libs/webrtc/vad/vad_const.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * This file includes the constant values used internally in VAD. + */ + +#include "vad_const.h" + +// Spectrum Weighting +const WebRtc_Word16 kSpectrumWeight[6] = {6, 8, 10, 12, 14, 16}; + +const WebRtc_Word16 kCompVar = 22005; + +// Constant 160*log10(2) in Q9 +const WebRtc_Word16 kLogConst = 24660; + +// Constant log2(exp(1)) in Q12 +const WebRtc_Word16 kLog10Const = 5909; + +// Q15 +const WebRtc_Word16 kNoiseUpdateConst = 655; +const WebRtc_Word16 kSpeechUpdateConst = 6554; + +// Q8 +const WebRtc_Word16 kBackEta = 154; + +// Coefficients used by WebRtcVad_HpOutput, Q14 +const WebRtc_Word16 kHpZeroCoefs[3] = {6631, -13262, 6631}; +const WebRtc_Word16 kHpPoleCoefs[3] = {16384, -7756, 5620}; + +// Allpass filter coefficients, upper and lower, in Q15 +// Upper: 0.64, Lower: 0.17 +const WebRtc_Word16 kAllPassCoefsQ15[2] = {20972, 5571}; +const WebRtc_Word16 kAllPassCoefsQ13[2] = {5243, 1392}; // Q13 + +// Minimum difference between the two models, Q5 +const WebRtc_Word16 kMinimumDifference[6] = {544, 544, 576, 576, 576, 576}; + +// Upper limit of mean value for speech model, Q7 +const WebRtc_Word16 kMaximumSpeech[6] = {11392, 11392, 11520, 11520, 11520, 11520}; + +// Minimum value for mean value +const WebRtc_Word16 kMinimumMean[2] = {640, 768}; + +// Upper limit of mean value for noise model, Q7 +const WebRtc_Word16 kMaximumNoise[6] = {9216, 9088, 8960, 8832, 8704, 8576}; + +// Adjustment for division with two in WebRtcVad_SplitFilter +const WebRtc_Word16 kOffsetVector[6] = {368, 368, 272, 176, 176, 176}; + +// Start values for the Gaussian models, Q7 +// Weights for the two Gaussians for the six channels (noise) +const WebRtc_Word16 kNoiseDataWeights[12] = {34, 62, 72, 66, 53, 25, 94, 66, 56, 62, 75, 103}; + +// Weights for the two Gaussians for the six channels (speech) +const WebRtc_Word16 kSpeechDataWeights[12] = {48, 82, 45, 87, 50, 47, 80, 46, 83, 41, 78, 81}; + +// Means for the two Gaussians for the six channels (noise) +const WebRtc_Word16 kNoiseDataMeans[12] = {6738, 4892, 7065, 6715, 6771, 3369, 7646, 3863, + 7820, 7266, 5020, 4362}; + +// Means for the two Gaussians for the six channels (speech) +const WebRtc_Word16 kSpeechDataMeans[12] = {8306, 10085, 10078, 11823, 11843, 6309, 9473, + 9571, 10879, 7581, 8180, 7483}; + +// Stds for the two Gaussians for the six channels (noise) +const WebRtc_Word16 kNoiseDataStds[12] = {378, 1064, 493, 582, 688, 593, 474, 697, 475, 688, + 421, 455}; + +// Stds for the two Gaussians for the six channels (speech) +const WebRtc_Word16 kSpeechDataStds[12] = {555, 505, 567, 524, 585, 1231, 509, 828, 492, 1540, + 1079, 850}; diff --git a/src/libs/webrtc/vad/vad_const.h b/src/libs/webrtc/vad/vad_const.h new file mode 100644 index 00000000..89804379 --- /dev/null +++ b/src/libs/webrtc/vad/vad_const.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file includes the declarations of the internally used constants. + */ + +#ifndef WEBRTC_VAD_CONST_H_ +#define WEBRTC_VAD_CONST_H_ + +#include "typedefs.h" + +// TODO(ajm): give these internal-linkage by moving to the appropriate file +// where possible, and otherwise tag with WebRtcVad_. + +// Spectrum Weighting +extern const WebRtc_Word16 kSpectrumWeight[]; +extern const WebRtc_Word16 kCompVar; +// Logarithm constant +extern const WebRtc_Word16 kLogConst; +extern const WebRtc_Word16 kLog10Const; +// Q15 +extern const WebRtc_Word16 kNoiseUpdateConst; +extern const WebRtc_Word16 kSpeechUpdateConst; +// Q8 +extern const WebRtc_Word16 kBackEta; +// Coefficients used by WebRtcVad_HpOutput, Q14 +extern const WebRtc_Word16 kHpZeroCoefs[]; +extern const WebRtc_Word16 kHpPoleCoefs[]; +// Allpass filter coefficients, upper and lower, in Q15 resp. Q13 +extern const WebRtc_Word16 kAllPassCoefsQ15[]; +extern const WebRtc_Word16 kAllPassCoefsQ13[]; +// Minimum difference between the two models, Q5 +extern const WebRtc_Word16 kMinimumDifference[]; +// Maximum value when updating the speech model, Q7 +extern const WebRtc_Word16 kMaximumSpeech[]; +// Minimum value for mean value +extern const WebRtc_Word16 kMinimumMean[]; +// Upper limit of mean value for noise model, Q7 +extern const WebRtc_Word16 kMaximumNoise[]; +// Adjustment for division with two in WebRtcVad_SplitFilter +extern const WebRtc_Word16 kOffsetVector[]; +// Start values for the Gaussian models, Q7 +extern const WebRtc_Word16 kNoiseDataWeights[]; +extern const WebRtc_Word16 kSpeechDataWeights[]; +extern const WebRtc_Word16 kNoiseDataMeans[]; +extern const WebRtc_Word16 kSpeechDataMeans[]; +extern const WebRtc_Word16 kNoiseDataStds[]; +extern const WebRtc_Word16 kSpeechDataStds[]; + +#endif // WEBRTC_VAD_CONST_H_ diff --git a/src/libs/webrtc/vad/vad_core.c b/src/libs/webrtc/vad/vad_core.c new file mode 100644 index 00000000..e8829993 --- /dev/null +++ b/src/libs/webrtc/vad/vad_core.c @@ -0,0 +1,685 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file includes the implementation of the core functionality in VAD. + * For function description, see vad_core.h. + */ + +#include "vad_core.h" +#include "vad_const.h" +#include "vad_defines.h" +#include "vad_filterbank.h" +#include "vad_gmm.h" +#include "vad_sp.h" +#include "signal_processing_library.h" + +static const int kInitCheck = 42; + +// Initialize VAD +int WebRtcVad_InitCore(VadInstT *inst, short mode) +{ + int i; + + // Initialization of struct + inst->vad = 1; + inst->frame_counter = 0; + inst->over_hang = 0; + inst->num_of_speech = 0; + + // Initialization of downsampling filter state + inst->downsampling_filter_states[0] = 0; + inst->downsampling_filter_states[1] = 0; + inst->downsampling_filter_states[2] = 0; + inst->downsampling_filter_states[3] = 0; + + // Read initial PDF parameters + for (i = 0; i < NUM_TABLE_VALUES; i++) + { + inst->noise_means[i] = kNoiseDataMeans[i]; + inst->speech_means[i] = kSpeechDataMeans[i]; + inst->noise_stds[i] = kNoiseDataStds[i]; + inst->speech_stds[i] = kSpeechDataStds[i]; + } + + // Index and Minimum value vectors are initialized + for (i = 0; i < 16 * NUM_CHANNELS; i++) + { + inst->low_value_vector[i] = 10000; + inst->index_vector[i] = 0; + } + + for (i = 0; i < 5; i++) + { + inst->upper_state[i] = 0; + inst->lower_state[i] = 0; + } + + for (i = 0; i < 4; i++) + { + inst->hp_filter_state[i] = 0; + } + + // Init mean value memory, for FindMin function + inst->mean_value[0] = 1600; + inst->mean_value[1] = 1600; + inst->mean_value[2] = 1600; + inst->mean_value[3] = 1600; + inst->mean_value[4] = 1600; + inst->mean_value[5] = 1600; + + if (mode == 0) + { + // Quality mode + inst->over_hang_max_1[0] = OHMAX1_10MS_Q; // Overhang short speech burst + inst->over_hang_max_1[1] = OHMAX1_20MS_Q; // Overhang short speech burst + inst->over_hang_max_1[2] = OHMAX1_30MS_Q; // Overhang short speech burst + inst->over_hang_max_2[0] = OHMAX2_10MS_Q; // Overhang long speech burst + inst->over_hang_max_2[1] = OHMAX2_20MS_Q; // Overhang long speech burst + inst->over_hang_max_2[2] = OHMAX2_30MS_Q; // Overhang long speech burst + + inst->individual[0] = INDIVIDUAL_10MS_Q; + inst->individual[1] = INDIVIDUAL_20MS_Q; + inst->individual[2] = INDIVIDUAL_30MS_Q; + + inst->total[0] = TOTAL_10MS_Q; + inst->total[1] = TOTAL_20MS_Q; + inst->total[2] = TOTAL_30MS_Q; + } else if (mode == 1) + { + // Low bitrate mode + inst->over_hang_max_1[0] = OHMAX1_10MS_LBR; // Overhang short speech burst + inst->over_hang_max_1[1] = OHMAX1_20MS_LBR; // Overhang short speech burst + inst->over_hang_max_1[2] = OHMAX1_30MS_LBR; // Overhang short speech burst + inst->over_hang_max_2[0] = OHMAX2_10MS_LBR; // Overhang long speech burst + inst->over_hang_max_2[1] = OHMAX2_20MS_LBR; // Overhang long speech burst + inst->over_hang_max_2[2] = OHMAX2_30MS_LBR; // Overhang long speech burst + + inst->individual[0] = INDIVIDUAL_10MS_LBR; + inst->individual[1] = INDIVIDUAL_20MS_LBR; + inst->individual[2] = INDIVIDUAL_30MS_LBR; + + inst->total[0] = TOTAL_10MS_LBR; + inst->total[1] = TOTAL_20MS_LBR; + inst->total[2] = TOTAL_30MS_LBR; + } else if (mode == 2) + { + // Aggressive mode + inst->over_hang_max_1[0] = OHMAX1_10MS_AGG; // Overhang short speech burst + inst->over_hang_max_1[1] = OHMAX1_20MS_AGG; // Overhang short speech burst + inst->over_hang_max_1[2] = OHMAX1_30MS_AGG; // Overhang short speech burst + inst->over_hang_max_2[0] = OHMAX2_10MS_AGG; // Overhang long speech burst + inst->over_hang_max_2[1] = OHMAX2_20MS_AGG; // Overhang long speech burst + inst->over_hang_max_2[2] = OHMAX2_30MS_AGG; // Overhang long speech burst + + inst->individual[0] = INDIVIDUAL_10MS_AGG; + inst->individual[1] = INDIVIDUAL_20MS_AGG; + inst->individual[2] = INDIVIDUAL_30MS_AGG; + + inst->total[0] = TOTAL_10MS_AGG; + inst->total[1] = TOTAL_20MS_AGG; + inst->total[2] = TOTAL_30MS_AGG; + } else + { + // Very aggressive mode + inst->over_hang_max_1[0] = OHMAX1_10MS_VAG; // Overhang short speech burst + inst->over_hang_max_1[1] = OHMAX1_20MS_VAG; // Overhang short speech burst + inst->over_hang_max_1[2] = OHMAX1_30MS_VAG; // Overhang short speech burst + inst->over_hang_max_2[0] = OHMAX2_10MS_VAG; // Overhang long speech burst + inst->over_hang_max_2[1] = OHMAX2_20MS_VAG; // Overhang long speech burst + inst->over_hang_max_2[2] = OHMAX2_30MS_VAG; // Overhang long speech burst + + inst->individual[0] = INDIVIDUAL_10MS_VAG; + inst->individual[1] = INDIVIDUAL_20MS_VAG; + inst->individual[2] = INDIVIDUAL_30MS_VAG; + + inst->total[0] = TOTAL_10MS_VAG; + inst->total[1] = TOTAL_20MS_VAG; + inst->total[2] = TOTAL_30MS_VAG; + } + + inst->init_flag = kInitCheck; + + return 0; +} + +// Set aggressiveness mode +int WebRtcVad_set_mode_core(VadInstT *inst, short mode) +{ + + if (mode == 0) + { + // Quality mode + inst->over_hang_max_1[0] = OHMAX1_10MS_Q; // Overhang short speech burst + inst->over_hang_max_1[1] = OHMAX1_20MS_Q; // Overhang short speech burst + inst->over_hang_max_1[2] = OHMAX1_30MS_Q; // Overhang short speech burst + inst->over_hang_max_2[0] = OHMAX2_10MS_Q; // Overhang long speech burst + inst->over_hang_max_2[1] = OHMAX2_20MS_Q; // Overhang long speech burst + inst->over_hang_max_2[2] = OHMAX2_30MS_Q; // Overhang long speech burst + + inst->individual[0] = INDIVIDUAL_10MS_Q; + inst->individual[1] = INDIVIDUAL_20MS_Q; + inst->individual[2] = INDIVIDUAL_30MS_Q; + + inst->total[0] = TOTAL_10MS_Q; + inst->total[1] = TOTAL_20MS_Q; + inst->total[2] = TOTAL_30MS_Q; + } else if (mode == 1) + { + // Low bitrate mode + inst->over_hang_max_1[0] = OHMAX1_10MS_LBR; // Overhang short speech burst + inst->over_hang_max_1[1] = OHMAX1_20MS_LBR; // Overhang short speech burst + inst->over_hang_max_1[2] = OHMAX1_30MS_LBR; // Overhang short speech burst + inst->over_hang_max_2[0] = OHMAX2_10MS_LBR; // Overhang long speech burst + inst->over_hang_max_2[1] = OHMAX2_20MS_LBR; // Overhang long speech burst + inst->over_hang_max_2[2] = OHMAX2_30MS_LBR; // Overhang long speech burst + + inst->individual[0] = INDIVIDUAL_10MS_LBR; + inst->individual[1] = INDIVIDUAL_20MS_LBR; + inst->individual[2] = INDIVIDUAL_30MS_LBR; + + inst->total[0] = TOTAL_10MS_LBR; + inst->total[1] = TOTAL_20MS_LBR; + inst->total[2] = TOTAL_30MS_LBR; + } else if (mode == 2) + { + // Aggressive mode + inst->over_hang_max_1[0] = OHMAX1_10MS_AGG; // Overhang short speech burst + inst->over_hang_max_1[1] = OHMAX1_20MS_AGG; // Overhang short speech burst + inst->over_hang_max_1[2] = OHMAX1_30MS_AGG; // Overhang short speech burst + inst->over_hang_max_2[0] = OHMAX2_10MS_AGG; // Overhang long speech burst + inst->over_hang_max_2[1] = OHMAX2_20MS_AGG; // Overhang long speech burst + inst->over_hang_max_2[2] = OHMAX2_30MS_AGG; // Overhang long speech burst + + inst->individual[0] = INDIVIDUAL_10MS_AGG; + inst->individual[1] = INDIVIDUAL_20MS_AGG; + inst->individual[2] = INDIVIDUAL_30MS_AGG; + + inst->total[0] = TOTAL_10MS_AGG; + inst->total[1] = TOTAL_20MS_AGG; + inst->total[2] = TOTAL_30MS_AGG; + } else if (mode == 3) + { + // Very aggressive mode + inst->over_hang_max_1[0] = OHMAX1_10MS_VAG; // Overhang short speech burst + inst->over_hang_max_1[1] = OHMAX1_20MS_VAG; // Overhang short speech burst + inst->over_hang_max_1[2] = OHMAX1_30MS_VAG; // Overhang short speech burst + inst->over_hang_max_2[0] = OHMAX2_10MS_VAG; // Overhang long speech burst + inst->over_hang_max_2[1] = OHMAX2_20MS_VAG; // Overhang long speech burst + inst->over_hang_max_2[2] = OHMAX2_30MS_VAG; // Overhang long speech burst + + inst->individual[0] = INDIVIDUAL_10MS_VAG; + inst->individual[1] = INDIVIDUAL_20MS_VAG; + inst->individual[2] = INDIVIDUAL_30MS_VAG; + + inst->total[0] = TOTAL_10MS_VAG; + inst->total[1] = TOTAL_20MS_VAG; + inst->total[2] = TOTAL_30MS_VAG; + } else + { + return -1; + } + + return 0; +} + +// Calculate VAD decision by first extracting feature values and then calculate +// probability for both speech and background noise. + +WebRtc_Word16 WebRtcVad_CalcVad32khz(VadInstT *inst, WebRtc_Word16 *speech_frame, + int frame_length) +{ + WebRtc_Word16 len, vad; + WebRtc_Word16 speechWB[480]; // Downsampled speech frame: 960 samples (30ms in SWB) + WebRtc_Word16 speechNB[240]; // Downsampled speech frame: 480 samples (30ms in WB) + + + // Downsample signal 32->16->8 before doing VAD + WebRtcVad_Downsampling(speech_frame, speechWB, &(inst->downsampling_filter_states[2]), + frame_length); + len = WEBRTC_SPL_RSHIFT_W16(frame_length, 1); + + WebRtcVad_Downsampling(speechWB, speechNB, inst->downsampling_filter_states, len); + len = WEBRTC_SPL_RSHIFT_W16(len, 1); + + // Do VAD on an 8 kHz signal + vad = WebRtcVad_CalcVad8khz(inst, speechNB, len); + + return vad; +} + +WebRtc_Word16 WebRtcVad_CalcVad16khz(VadInstT *inst, WebRtc_Word16 *speech_frame, + int frame_length) +{ + WebRtc_Word16 len, vad; + WebRtc_Word16 speechNB[240]; // Downsampled speech frame: 480 samples (30ms in WB) + + // Wideband: Downsample signal before doing VAD + WebRtcVad_Downsampling(speech_frame, speechNB, inst->downsampling_filter_states, + frame_length); + + len = WEBRTC_SPL_RSHIFT_W16(frame_length, 1); + vad = WebRtcVad_CalcVad8khz(inst, speechNB, len); + + return vad; +} + +WebRtc_Word16 WebRtcVad_CalcVad8khz(VadInstT *inst, WebRtc_Word16 *speech_frame, + int frame_length) +{ + WebRtc_Word16 feature_vector[NUM_CHANNELS], total_power; + + // Get power in the bands + total_power = WebRtcVad_get_features(inst, speech_frame, frame_length, feature_vector); + + // Make a VAD + inst->vad = WebRtcVad_GmmProbability(inst, feature_vector, total_power, frame_length); + + return inst->vad; +} + +// Calculate probability for both speech and background noise, and perform a +// hypothesis-test. +WebRtc_Word16 WebRtcVad_GmmProbability(VadInstT *inst, WebRtc_Word16 *feature_vector, + WebRtc_Word16 total_power, int frame_length) +{ + int n, k; + WebRtc_Word16 backval; + WebRtc_Word16 h0, h1; + WebRtc_Word16 ratvec, xval; + WebRtc_Word16 vadflag; + WebRtc_Word16 shifts0, shifts1; + WebRtc_Word16 tmp16, tmp16_1, tmp16_2; + WebRtc_Word16 diff, nr, pos; + WebRtc_Word16 nmk, nmk2, nmk3, smk, smk2, nsk, ssk; + WebRtc_Word16 delt, ndelt; + WebRtc_Word16 maxspe, maxmu; + WebRtc_Word16 deltaN[NUM_TABLE_VALUES], deltaS[NUM_TABLE_VALUES]; + WebRtc_Word16 ngprvec[NUM_TABLE_VALUES], sgprvec[NUM_TABLE_VALUES]; + WebRtc_Word32 h0test, h1test; + WebRtc_Word32 tmp32_1, tmp32_2; + WebRtc_Word32 dotVal; + WebRtc_Word32 nmid, smid; + WebRtc_Word32 probn[NUM_MODELS], probs[NUM_MODELS]; + WebRtc_Word16 *nmean1ptr, *nmean2ptr, *smean1ptr, *smean2ptr, *nstd1ptr, *nstd2ptr, + *sstd1ptr, *sstd2ptr; + WebRtc_Word16 overhead1, overhead2, individualTest, totalTest; + + // Set the thresholds to different values based on frame length + if (frame_length == 80) + { + // 80 input samples + overhead1 = inst->over_hang_max_1[0]; + overhead2 = inst->over_hang_max_2[0]; + individualTest = inst->individual[0]; + totalTest = inst->total[0]; + } else if (frame_length == 160) + { + // 160 input samples + overhead1 = inst->over_hang_max_1[1]; + overhead2 = inst->over_hang_max_2[1]; + individualTest = inst->individual[1]; + totalTest = inst->total[1]; + } else + { + // 240 input samples + overhead1 = inst->over_hang_max_1[2]; + overhead2 = inst->over_hang_max_2[2]; + individualTest = inst->individual[2]; + totalTest = inst->total[2]; + } + + if (total_power > MIN_ENERGY) + { // If signal present at all + + // Set pointers to the gaussian parameters + nmean1ptr = &inst->noise_means[0]; + nmean2ptr = &inst->noise_means[NUM_CHANNELS]; + smean1ptr = &inst->speech_means[0]; + smean2ptr = &inst->speech_means[NUM_CHANNELS]; + nstd1ptr = &inst->noise_stds[0]; + nstd2ptr = &inst->noise_stds[NUM_CHANNELS]; + sstd1ptr = &inst->speech_stds[0]; + sstd2ptr = &inst->speech_stds[NUM_CHANNELS]; + + vadflag = 0; + dotVal = 0; + for (n = 0; n < NUM_CHANNELS; n++) + { // For all channels + + pos = WEBRTC_SPL_LSHIFT_W16(n, 1); + xval = feature_vector[n]; + + // Probability for Noise, Q7 * Q20 = Q27 + tmp32_1 = WebRtcVad_GaussianProbability(xval, *nmean1ptr++, *nstd1ptr++, + &deltaN[pos]); + probn[0] = (WebRtc_Word32)(kNoiseDataWeights[n] * tmp32_1); + tmp32_1 = WebRtcVad_GaussianProbability(xval, *nmean2ptr++, *nstd2ptr++, + &deltaN[pos + 1]); + probn[1] = (WebRtc_Word32)(kNoiseDataWeights[n + NUM_CHANNELS] * tmp32_1); + h0test = probn[0] + probn[1]; // Q27 + h0 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(h0test, 12); // Q15 + + // Probability for Speech + tmp32_1 = WebRtcVad_GaussianProbability(xval, *smean1ptr++, *sstd1ptr++, + &deltaS[pos]); + probs[0] = (WebRtc_Word32)(kSpeechDataWeights[n] * tmp32_1); + tmp32_1 = WebRtcVad_GaussianProbability(xval, *smean2ptr++, *sstd2ptr++, + &deltaS[pos + 1]); + probs[1] = (WebRtc_Word32)(kSpeechDataWeights[n + NUM_CHANNELS] * tmp32_1); + h1test = probs[0] + probs[1]; // Q27 + h1 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(h1test, 12); // Q15 + + // Get likelihood ratio. Approximate log2(H1/H0) with shifts0 - shifts1 + shifts0 = WebRtcSpl_NormW32(h0test); + shifts1 = WebRtcSpl_NormW32(h1test); + + if ((h0test > 0) && (h1test > 0)) + { + ratvec = shifts0 - shifts1; + } else if (h1test > 0) + { + ratvec = 31 - shifts1; + } else if (h0test > 0) + { + ratvec = shifts0 - 31; + } else + { + ratvec = 0; + } + + // VAD decision with spectrum weighting + dotVal += WEBRTC_SPL_MUL_16_16(ratvec, kSpectrumWeight[n]); + + // Individual channel test + if ((ratvec << 2) > individualTest) + { + vadflag = 1; + } + + // Probabilities used when updating model + if (h0 > 0) + { + tmp32_1 = probn[0] & 0xFFFFF000; // Q27 + tmp32_2 = WEBRTC_SPL_LSHIFT_W32(tmp32_1, 2); // Q29 + ngprvec[pos] = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_2, h0); + ngprvec[pos + 1] = 16384 - ngprvec[pos]; + } else + { + ngprvec[pos] = 16384; + ngprvec[pos + 1] = 0; + } + + // Probabilities used when updating model + if (h1 > 0) + { + tmp32_1 = probs[0] & 0xFFFFF000; + tmp32_2 = WEBRTC_SPL_LSHIFT_W32(tmp32_1, 2); + sgprvec[pos] = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_2, h1); + sgprvec[pos + 1] = 16384 - sgprvec[pos]; + } else + { + sgprvec[pos] = 0; + sgprvec[pos + 1] = 0; + } + } + + // Overall test + if (dotVal >= totalTest) + { + vadflag |= 1; + } + + // Set pointers to the means and standard deviations. + nmean1ptr = &inst->noise_means[0]; + smean1ptr = &inst->speech_means[0]; + nstd1ptr = &inst->noise_stds[0]; + sstd1ptr = &inst->speech_stds[0]; + + maxspe = 12800; + + // Update the model's parameters + for (n = 0; n < NUM_CHANNELS; n++) + { + + pos = WEBRTC_SPL_LSHIFT_W16(n, 1); + + // Get min value in past which is used for long term correction + backval = WebRtcVad_FindMinimum(inst, feature_vector[n], n); // Q4 + + // Compute the "global" mean, that is the sum of the two means weighted + nmid = WEBRTC_SPL_MUL_16_16(kNoiseDataWeights[n], *nmean1ptr); // Q7 * Q7 + nmid += WEBRTC_SPL_MUL_16_16(kNoiseDataWeights[n+NUM_CHANNELS], + *(nmean1ptr+NUM_CHANNELS)); + tmp16_1 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(nmid, 6); // Q8 + + for (k = 0; k < NUM_MODELS; k++) + { + + nr = pos + k; + + nmean2ptr = nmean1ptr + k * NUM_CHANNELS; + smean2ptr = smean1ptr + k * NUM_CHANNELS; + nstd2ptr = nstd1ptr + k * NUM_CHANNELS; + sstd2ptr = sstd1ptr + k * NUM_CHANNELS; + nmk = *nmean2ptr; + smk = *smean2ptr; + nsk = *nstd2ptr; + ssk = *sstd2ptr; + + // Update noise mean vector if the frame consists of noise only + nmk2 = nmk; + if (!vadflag) + { + // deltaN = (x-mu)/sigma^2 + // ngprvec[k] = probn[k]/(probn[0] + probn[1]) + + delt = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ngprvec[nr], + deltaN[nr], 11); // Q14*Q11 + nmk2 = nmk + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(delt, + kNoiseUpdateConst, + 22); // Q7+(Q14*Q15>>22) + } + + // Long term correction of the noise mean + ndelt = WEBRTC_SPL_LSHIFT_W16(backval, 4); + ndelt -= tmp16_1; // Q8 - Q8 + nmk3 = nmk2 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ndelt, + kBackEta, + 9); // Q7+(Q8*Q8)>>9 + + // Control that the noise mean does not drift to much + tmp16 = WEBRTC_SPL_LSHIFT_W16(k+5, 7); + if (nmk3 < tmp16) + nmk3 = tmp16; + tmp16 = WEBRTC_SPL_LSHIFT_W16(72+k-n, 7); + if (nmk3 > tmp16) + nmk3 = tmp16; + *nmean2ptr = nmk3; + + if (vadflag) + { + // Update speech mean vector: + // deltaS = (x-mu)/sigma^2 + // sgprvec[k] = probn[k]/(probn[0] + probn[1]) + + delt = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sgprvec[nr], + deltaS[nr], + 11); // (Q14*Q11)>>11=Q14 + tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(delt, + kSpeechUpdateConst, + 21) + 1; + smk2 = smk + (tmp16 >> 1); // Q7 + (Q14 * Q15 >> 22) + + // Control that the speech mean does not drift to much + maxmu = maxspe + 640; + if (smk2 < kMinimumMean[k]) + smk2 = kMinimumMean[k]; + if (smk2 > maxmu) + smk2 = maxmu; + + *smean2ptr = smk2; + + // (Q7>>3) = Q4 + tmp16 = WEBRTC_SPL_RSHIFT_W16((smk + 4), 3); + + tmp16 = feature_vector[n] - tmp16; // Q4 + tmp32_1 = WEBRTC_SPL_MUL_16_16_RSFT(deltaS[nr], tmp16, 3); + tmp32_2 = tmp32_1 - (WebRtc_Word32)4096; // Q12 + tmp16 = WEBRTC_SPL_RSHIFT_W16((sgprvec[nr]), 2); + tmp32_1 = (WebRtc_Word32)(tmp16 * tmp32_2);// (Q15>>3)*(Q14>>2)=Q12*Q12=Q24 + + tmp32_2 = WEBRTC_SPL_RSHIFT_W32(tmp32_1, 4); // Q20 + + // 0.1 * Q20 / Q7 = Q13 + if (tmp32_2 > 0) + tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_2, ssk * 10); + else + { + tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(-tmp32_2, ssk * 10); + tmp16 = -tmp16; + } + // divide by 4 giving an update factor of 0.025 + tmp16 += 128; // Rounding + ssk += WEBRTC_SPL_RSHIFT_W16(tmp16, 8); + // Division with 8 plus Q7 + if (ssk < MIN_STD) + ssk = MIN_STD; + *sstd2ptr = ssk; + } else + { + // Update GMM variance vectors + // deltaN * (feature_vector[n] - nmk) - 1, Q11 * Q4 + tmp16 = feature_vector[n] - WEBRTC_SPL_RSHIFT_W16(nmk, 3); + + // (Q15>>3) * (Q14>>2) = Q12 * Q12 = Q24 + tmp32_1 = WEBRTC_SPL_MUL_16_16_RSFT(deltaN[nr], tmp16, 3) - 4096; + tmp16 = WEBRTC_SPL_RSHIFT_W16((ngprvec[nr]+2), 2); + tmp32_2 = (WebRtc_Word32)(tmp16 * tmp32_1); + tmp32_1 = WEBRTC_SPL_RSHIFT_W32(tmp32_2, 14); + // Q20 * approx 0.001 (2^-10=0.0009766) + + // Q20 / Q7 = Q13 + tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_1, nsk); + if (tmp32_1 > 0) + tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32_1, nsk); + else + { + tmp16 = (WebRtc_Word16)WebRtcSpl_DivW32W16(-tmp32_1, nsk); + tmp16 = -tmp16; + } + tmp16 += 32; // Rounding + nsk += WEBRTC_SPL_RSHIFT_W16(tmp16, 6); + + if (nsk < MIN_STD) + nsk = MIN_STD; + + *nstd2ptr = nsk; + } + } + + // Separate models if they are too close - nmid in Q14 + nmid = WEBRTC_SPL_MUL_16_16(kNoiseDataWeights[n], *nmean1ptr); + nmid += WEBRTC_SPL_MUL_16_16(kNoiseDataWeights[n+NUM_CHANNELS], *nmean2ptr); + + // smid in Q14 + smid = WEBRTC_SPL_MUL_16_16(kSpeechDataWeights[n], *smean1ptr); + smid += WEBRTC_SPL_MUL_16_16(kSpeechDataWeights[n+NUM_CHANNELS], *smean2ptr); + + // diff = "global" speech mean - "global" noise mean + diff = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(smid, 9); + tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(nmid, 9); + diff -= tmp16; + + if (diff < kMinimumDifference[n]) + { + + tmp16 = kMinimumDifference[n] - diff; // Q5 + + // tmp16_1 = ~0.8 * (kMinimumDifference - diff) in Q7 + // tmp16_2 = ~0.2 * (kMinimumDifference - diff) in Q7 + tmp16_1 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(13, tmp16, 2); + tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(3, tmp16, 2); + + // First Gauss, speech model + tmp16 = tmp16_1 + *smean1ptr; + *smean1ptr = tmp16; + smid = WEBRTC_SPL_MUL_16_16(tmp16, kSpeechDataWeights[n]); + + // Second Gauss, speech model + tmp16 = tmp16_1 + *smean2ptr; + *smean2ptr = tmp16; + smid += WEBRTC_SPL_MUL_16_16(tmp16, kSpeechDataWeights[n+NUM_CHANNELS]); + + // First Gauss, noise model + tmp16 = *nmean1ptr - tmp16_2; + *nmean1ptr = tmp16; + + nmid = WEBRTC_SPL_MUL_16_16(tmp16, kNoiseDataWeights[n]); + + // Second Gauss, noise model + tmp16 = *nmean2ptr - tmp16_2; + *nmean2ptr = tmp16; + nmid += WEBRTC_SPL_MUL_16_16(tmp16, kNoiseDataWeights[n+NUM_CHANNELS]); + } + + // Control that the speech & noise means do not drift to much + maxspe = kMaximumSpeech[n]; + tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(smid, 7); + if (tmp16_2 > maxspe) + { // Upper limit of speech model + tmp16_2 -= maxspe; + + *smean1ptr -= tmp16_2; + *smean2ptr -= tmp16_2; + } + + tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(nmid, 7); + if (tmp16_2 > kMaximumNoise[n]) + { + tmp16_2 -= kMaximumNoise[n]; + + *nmean1ptr -= tmp16_2; + *nmean2ptr -= tmp16_2; + } + + *nmean1ptr++; + *smean1ptr++; + *nstd1ptr++; + *sstd1ptr++; + } + inst->frame_counter++; + } else + { + vadflag = 0; + } + + // Hangover smoothing + if (!vadflag) + { + if (inst->over_hang > 0) + { + vadflag = 2 + inst->over_hang; + inst->over_hang = inst->over_hang - 1; + } + inst->num_of_speech = 0; + } else + { + inst->num_of_speech = inst->num_of_speech + 1; + if (inst->num_of_speech > NSP_MAX) + { + inst->num_of_speech = NSP_MAX; + inst->over_hang = overhead2; + } else + inst->over_hang = overhead1; + } + return vadflag; +} diff --git a/src/libs/webrtc/vad/vad_core.h b/src/libs/webrtc/vad/vad_core.h new file mode 100644 index 00000000..544caf5a --- /dev/null +++ b/src/libs/webrtc/vad/vad_core.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file includes the descriptions of the core VAD calls. + */ + +#ifndef WEBRTC_VAD_CORE_H_ +#define WEBRTC_VAD_CORE_H_ + +#include "typedefs.h" +#include "vad_defines.h" + +typedef struct VadInstT_ +{ + + WebRtc_Word16 vad; + WebRtc_Word32 downsampling_filter_states[4]; + WebRtc_Word16 noise_means[NUM_TABLE_VALUES]; + WebRtc_Word16 speech_means[NUM_TABLE_VALUES]; + WebRtc_Word16 noise_stds[NUM_TABLE_VALUES]; + WebRtc_Word16 speech_stds[NUM_TABLE_VALUES]; + WebRtc_Word32 frame_counter; + WebRtc_Word16 over_hang; // Over Hang + WebRtc_Word16 num_of_speech; + WebRtc_Word16 index_vector[16 * NUM_CHANNELS]; + WebRtc_Word16 low_value_vector[16 * NUM_CHANNELS]; + WebRtc_Word16 mean_value[NUM_CHANNELS]; + WebRtc_Word16 upper_state[5]; + WebRtc_Word16 lower_state[5]; + WebRtc_Word16 hp_filter_state[4]; + WebRtc_Word16 over_hang_max_1[3]; + WebRtc_Word16 over_hang_max_2[3]; + WebRtc_Word16 individual[3]; + WebRtc_Word16 total[3]; + + short init_flag; + +} VadInstT; + +/**************************************************************************** + * WebRtcVad_InitCore(...) + * + * This function initializes a VAD instance + * + * Input: + * - inst : Instance that should be initialized + * - mode : Aggressiveness degree + * 0 (High quality) - 3 (Highly aggressive) + * + * Output: + * - inst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ +int WebRtcVad_InitCore(VadInstT* inst, short mode); + +/**************************************************************************** + * WebRtcVad_set_mode_core(...) + * + * This function changes the VAD settings + * + * Input: + * - inst : VAD instance + * - mode : Aggressiveness degree + * 0 (High quality) - 3 (Highly aggressive) + * + * Output: + * - inst : Changed instance + * + * Return value : 0 - Ok + * -1 - Error + */ + +int WebRtcVad_set_mode_core(VadInstT* inst, short mode); + +/**************************************************************************** + * WebRtcVad_CalcVad32khz(...) + * WebRtcVad_CalcVad16khz(...) + * WebRtcVad_CalcVad8khz(...) + * + * Calculate probability for active speech and make VAD decision. + * + * Input: + * - inst : Instance that should be initialized + * - speech_frame : Input speech frame + * - frame_length : Number of input samples + * + * Output: + * - inst : Updated filter states etc. + * + * Return value : VAD decision + * 0 - No active speech + * 1-6 - Active speech + */ +WebRtc_Word16 WebRtcVad_CalcVad32khz(VadInstT* inst, WebRtc_Word16* speech_frame, + int frame_length); +WebRtc_Word16 WebRtcVad_CalcVad16khz(VadInstT* inst, WebRtc_Word16* speech_frame, + int frame_length); +WebRtc_Word16 WebRtcVad_CalcVad8khz(VadInstT* inst, WebRtc_Word16* speech_frame, + int frame_length); + +/**************************************************************************** + * WebRtcVad_GmmProbability(...) + * + * This function calculates the probabilities for background noise and + * speech using Gaussian Mixture Models. A hypothesis-test is performed to decide + * which type of signal is most probable. + * + * Input: + * - inst : Pointer to VAD instance + * - feature_vector : Feature vector = log10(energy in frequency band) + * - total_power : Total power in frame. + * - frame_length : Number of input samples + * + * Output: + * VAD decision : 0 - noise, 1 - speech + * + */ +WebRtc_Word16 WebRtcVad_GmmProbability(VadInstT* inst, WebRtc_Word16* feature_vector, + WebRtc_Word16 total_power, int frame_length); + +#endif // WEBRTC_VAD_CORE_H_ diff --git a/src/libs/webrtc/vad/vad_defines.h b/src/libs/webrtc/vad/vad_defines.h new file mode 100644 index 00000000..b33af2ef --- /dev/null +++ b/src/libs/webrtc/vad/vad_defines.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file includes the macros used in VAD. + */ + +#ifndef WEBRTC_VAD_DEFINES_H_ +#define WEBRTC_VAD_DEFINES_H_ + +#define NUM_CHANNELS 6 // Eight frequency bands +#define NUM_MODELS 2 // Number of Gaussian models +#define NUM_TABLE_VALUES NUM_CHANNELS * NUM_MODELS + +#define MIN_ENERGY 10 +#define ALPHA1 6553 // 0.2 in Q15 +#define ALPHA2 32439 // 0.99 in Q15 +#define NSP_MAX 6 // Maximum number of VAD=1 frames in a row counted +#define MIN_STD 384 // Minimum standard deviation +// Mode 0, Quality thresholds - Different thresholds for the different frame lengths +#define INDIVIDUAL_10MS_Q 24 +#define INDIVIDUAL_20MS_Q 21 // (log10(2)*66)<<2 ~=16 +#define INDIVIDUAL_30MS_Q 24 + +#define TOTAL_10MS_Q 57 +#define TOTAL_20MS_Q 48 +#define TOTAL_30MS_Q 57 + +#define OHMAX1_10MS_Q 8 // Max Overhang 1 +#define OHMAX2_10MS_Q 14 // Max Overhang 2 +#define OHMAX1_20MS_Q 4 // Max Overhang 1 +#define OHMAX2_20MS_Q 7 // Max Overhang 2 +#define OHMAX1_30MS_Q 3 +#define OHMAX2_30MS_Q 5 + +// Mode 1, Low bitrate thresholds - Different thresholds for the different frame lengths +#define INDIVIDUAL_10MS_LBR 37 +#define INDIVIDUAL_20MS_LBR 32 +#define INDIVIDUAL_30MS_LBR 37 + +#define TOTAL_10MS_LBR 100 +#define TOTAL_20MS_LBR 80 +#define TOTAL_30MS_LBR 100 + +#define OHMAX1_10MS_LBR 8 // Max Overhang 1 +#define OHMAX2_10MS_LBR 14 // Max Overhang 2 +#define OHMAX1_20MS_LBR 4 +#define OHMAX2_20MS_LBR 7 + +#define OHMAX1_30MS_LBR 3 +#define OHMAX2_30MS_LBR 5 + +// Mode 2, Very aggressive thresholds - Different thresholds for the different frame lengths +#define INDIVIDUAL_10MS_AGG 82 +#define INDIVIDUAL_20MS_AGG 78 +#define INDIVIDUAL_30MS_AGG 82 + +#define TOTAL_10MS_AGG 285 //580 +#define TOTAL_20MS_AGG 260 +#define TOTAL_30MS_AGG 285 + +#define OHMAX1_10MS_AGG 6 // Max Overhang 1 +#define OHMAX2_10MS_AGG 9 // Max Overhang 2 +#define OHMAX1_20MS_AGG 3 +#define OHMAX2_20MS_AGG 5 + +#define OHMAX1_30MS_AGG 2 +#define OHMAX2_30MS_AGG 3 + +// Mode 3, Super aggressive thresholds - Different thresholds for the different frame lengths +#define INDIVIDUAL_10MS_VAG 94 +#define INDIVIDUAL_20MS_VAG 94 +#define INDIVIDUAL_30MS_VAG 94 + +#define TOTAL_10MS_VAG 1100 //1700 +#define TOTAL_20MS_VAG 1050 +#define TOTAL_30MS_VAG 1100 + +#define OHMAX1_10MS_VAG 6 // Max Overhang 1 +#define OHMAX2_10MS_VAG 9 // Max Overhang 2 +#define OHMAX1_20MS_VAG 3 +#define OHMAX2_20MS_VAG 5 + +#define OHMAX1_30MS_VAG 2 +#define OHMAX2_30MS_VAG 3 + +#endif // WEBRTC_VAD_DEFINES_H_ diff --git a/src/libs/webrtc/vad/vad_filterbank.c b/src/libs/webrtc/vad/vad_filterbank.c new file mode 100644 index 00000000..11392c91 --- /dev/null +++ b/src/libs/webrtc/vad/vad_filterbank.c @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file includes the implementation of the internal filterbank associated functions. + * For function description, see vad_filterbank.h. + */ + +#include "vad_filterbank.h" +#include "vad_defines.h" +#include "vad_const.h" +#include "signal_processing_library.h" + +void WebRtcVad_HpOutput(WebRtc_Word16 *in_vector, + WebRtc_Word16 in_vector_length, + WebRtc_Word16 *out_vector, + WebRtc_Word16 *filter_state) +{ + WebRtc_Word16 i, *pi, *outPtr; + WebRtc_Word32 tmpW32; + + pi = &in_vector[0]; + outPtr = &out_vector[0]; + + // The sum of the absolute values of the impulse response: + // The zero/pole-filter has a max amplification of a single sample of: 1.4546 + // Impulse response: 0.4047 -0.6179 -0.0266 0.1993 0.1035 -0.0194 + // The all-zero section has a max amplification of a single sample of: 1.6189 + // Impulse response: 0.4047 -0.8094 0.4047 0 0 0 + // The all-pole section has a max amplification of a single sample of: 1.9931 + // Impulse response: 1.0000 0.4734 -0.1189 -0.2187 -0.0627 0.04532 + + for (i = 0; i < in_vector_length; i++) + { + // all-zero section (filter coefficients in Q14) + tmpW32 = (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpZeroCoefs[0], (*pi)); + tmpW32 += (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpZeroCoefs[1], filter_state[0]); + tmpW32 += (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpZeroCoefs[2], filter_state[1]); // Q14 + filter_state[1] = filter_state[0]; + filter_state[0] = *pi++; + + // all-pole section + tmpW32 -= (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpPoleCoefs[1], filter_state[2]); // Q14 + tmpW32 -= (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpPoleCoefs[2], filter_state[3]); + filter_state[3] = filter_state[2]; + filter_state[2] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32 (tmpW32, 14); + *outPtr++ = filter_state[2]; + } +} + +void WebRtcVad_Allpass(WebRtc_Word16 *in_vector, + WebRtc_Word16 *out_vector, + WebRtc_Word16 filter_coefficients, + int vector_length, + WebRtc_Word16 *filter_state) +{ + // The filter can only cause overflow (in the w16 output variable) + // if more than 4 consecutive input numbers are of maximum value and + // has the the same sign as the impulse responses first taps. + // First 6 taps of the impulse response: 0.6399 0.5905 -0.3779 + // 0.2418 -0.1547 0.0990 + + int n; + WebRtc_Word16 tmp16; + WebRtc_Word32 tmp32, in32, state32; + + state32 = WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)(*filter_state)), 16); // Q31 + + for (n = 0; n < vector_length; n++) + { + + tmp32 = state32 + WEBRTC_SPL_MUL_16_16(filter_coefficients, (*in_vector)); + tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 16); + *out_vector++ = tmp16; + in32 = WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)(*in_vector)), 14); + state32 = in32 - WEBRTC_SPL_MUL_16_16(filter_coefficients, tmp16); + state32 = WEBRTC_SPL_LSHIFT_W32(state32, 1); + in_vector += 2; + } + + *filter_state = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(state32, 16); +} + +void WebRtcVad_SplitFilter(WebRtc_Word16 *in_vector, + WebRtc_Word16 *out_vector_hp, + WebRtc_Word16 *out_vector_lp, + WebRtc_Word16 *upper_state, + WebRtc_Word16 *lower_state, + int in_vector_length) +{ + WebRtc_Word16 tmpOut; + int k, halflen; + + // Downsampling by 2 and get two branches + halflen = WEBRTC_SPL_RSHIFT_W16(in_vector_length, 1); + + // All-pass filtering upper branch + WebRtcVad_Allpass(&in_vector[0], out_vector_hp, kAllPassCoefsQ15[0], halflen, upper_state); + + // All-pass filtering lower branch + WebRtcVad_Allpass(&in_vector[1], out_vector_lp, kAllPassCoefsQ15[1], halflen, lower_state); + + // Make LP and HP signals + for (k = 0; k < halflen; k++) + { + tmpOut = *out_vector_hp; + *out_vector_hp++ -= *out_vector_lp; + *out_vector_lp++ += tmpOut; + } +} + +WebRtc_Word16 WebRtcVad_get_features(VadInstT *inst, + WebRtc_Word16 *in_vector, + int frame_size, + WebRtc_Word16 *out_vector) +{ + int curlen, filtno; + WebRtc_Word16 vecHP1[120], vecLP1[120]; + WebRtc_Word16 vecHP2[60], vecLP2[60]; + WebRtc_Word16 *ptin; + WebRtc_Word16 *hptout, *lptout; + WebRtc_Word16 power = 0; + + // Split at 2000 Hz and downsample + filtno = 0; + ptin = in_vector; + hptout = vecHP1; + lptout = vecLP1; + curlen = frame_size; + WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno], + &inst->lower_state[filtno], curlen); + + // Split at 3000 Hz and downsample + filtno = 1; + ptin = vecHP1; + hptout = vecHP2; + lptout = vecLP2; + curlen = WEBRTC_SPL_RSHIFT_W16(frame_size, 1); + + WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno], + &inst->lower_state[filtno], curlen); + + // Energy in 3000 Hz - 4000 Hz + curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1); + WebRtcVad_LogOfEnergy(vecHP2, &out_vector[5], &power, kOffsetVector[5], curlen); + + // Energy in 2000 Hz - 3000 Hz + WebRtcVad_LogOfEnergy(vecLP2, &out_vector[4], &power, kOffsetVector[4], curlen); + + // Split at 1000 Hz and downsample + filtno = 2; + ptin = vecLP1; + hptout = vecHP2; + lptout = vecLP2; + curlen = WEBRTC_SPL_RSHIFT_W16(frame_size, 1); + WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno], + &inst->lower_state[filtno], curlen); + + // Energy in 1000 Hz - 2000 Hz + curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1); + WebRtcVad_LogOfEnergy(vecHP2, &out_vector[3], &power, kOffsetVector[3], curlen); + + // Split at 500 Hz + filtno = 3; + ptin = vecLP2; + hptout = vecHP1; + lptout = vecLP1; + + WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno], + &inst->lower_state[filtno], curlen); + + // Energy in 500 Hz - 1000 Hz + curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1); + WebRtcVad_LogOfEnergy(vecHP1, &out_vector[2], &power, kOffsetVector[2], curlen); + // Split at 250 Hz + filtno = 4; + ptin = vecLP1; + hptout = vecHP2; + lptout = vecLP2; + + WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno], + &inst->lower_state[filtno], curlen); + + // Energy in 250 Hz - 500 Hz + curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1); + WebRtcVad_LogOfEnergy(vecHP2, &out_vector[1], &power, kOffsetVector[1], curlen); + + // Remove DC and LFs + WebRtcVad_HpOutput(vecLP2, curlen, vecHP1, inst->hp_filter_state); + + // Power in 80 Hz - 250 Hz + WebRtcVad_LogOfEnergy(vecHP1, &out_vector[0], &power, kOffsetVector[0], curlen); + + return power; +} + +void WebRtcVad_LogOfEnergy(WebRtc_Word16 *vector, + WebRtc_Word16 *enerlogval, + WebRtc_Word16 *power, + WebRtc_Word16 offset, + int vector_length) +{ + WebRtc_Word16 enerSum = 0; + WebRtc_Word16 zeros, frac, log2; + WebRtc_Word32 energy; + + int shfts = 0, shfts2; + + energy = WebRtcSpl_Energy(vector, vector_length, &shfts); + + if (energy > 0) + { + + shfts2 = 16 - WebRtcSpl_NormW32(energy); + shfts += shfts2; + // "shfts" is the total number of right shifts that has been done to enerSum. + enerSum = (WebRtc_Word16)WEBRTC_SPL_SHIFT_W32(energy, -shfts2); + + // Find: + // 160*log10(enerSum*2^shfts) = 160*log10(2)*log2(enerSum*2^shfts) = + // 160*log10(2)*(log2(enerSum) + log2(2^shfts)) = + // 160*log10(2)*(log2(enerSum) + shfts) + + zeros = WebRtcSpl_NormU32(enerSum); + frac = (WebRtc_Word16)(((WebRtc_UWord32)((WebRtc_Word32)(enerSum) << zeros) + & 0x7FFFFFFF) >> 21); + log2 = (WebRtc_Word16)(((31 - zeros) << 10) + frac); + + *enerlogval = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(kLogConst, log2, 19) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(shfts, kLogConst, 9); + + if (*enerlogval < 0) + { + *enerlogval = 0; + } + } else + { + *enerlogval = 0; + shfts = -15; + enerSum = 0; + } + + *enerlogval += offset; + + // Total power in frame + if (*power <= MIN_ENERGY) + { + if (shfts > 0) + { + *power += MIN_ENERGY + 1; + } else if (WEBRTC_SPL_SHIFT_W16(enerSum, shfts) > MIN_ENERGY) + { + *power += MIN_ENERGY + 1; + } else + { + *power += WEBRTC_SPL_SHIFT_W16(enerSum, shfts); + } + } +} diff --git a/src/libs/webrtc/vad/vad_filterbank.h b/src/libs/webrtc/vad/vad_filterbank.h new file mode 100644 index 00000000..a5507ead --- /dev/null +++ b/src/libs/webrtc/vad/vad_filterbank.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file includes the description of the internal VAD call + * WebRtcVad_GaussianProbability. + */ + +#ifndef WEBRTC_VAD_FILTERBANK_H_ +#define WEBRTC_VAD_FILTERBANK_H_ + +#include "vad_core.h" + +/**************************************************************************** + * WebRtcVad_HpOutput(...) + * + * This function removes DC from the lowest frequency band + * + * Input: + * - in_vector : Samples in the frequency interval 0 - 250 Hz + * - in_vector_length : Length of input and output vector + * - filter_state : Current state of the filter + * + * Output: + * - out_vector : Samples in the frequency interval 80 - 250 Hz + * - filter_state : Updated state of the filter + * + */ +void WebRtcVad_HpOutput(WebRtc_Word16* in_vector, + WebRtc_Word16 in_vector_length, + WebRtc_Word16* out_vector, + WebRtc_Word16* filter_state); + +/**************************************************************************** + * WebRtcVad_Allpass(...) + * + * This function is used when before splitting a speech file into + * different frequency bands + * + * Note! Do NOT let the arrays in_vector and out_vector correspond to the same address. + * + * Input: + * - in_vector : (Q0) + * - filter_coefficients : (Q15) + * - vector_length : Length of input and output vector + * - filter_state : Current state of the filter (Q(-1)) + * + * Output: + * - out_vector : Output speech signal (Q(-1)) + * - filter_state : Updated state of the filter (Q(-1)) + * + */ +void WebRtcVad_Allpass(WebRtc_Word16* in_vector, + WebRtc_Word16* outw16, + WebRtc_Word16 filter_coefficients, + int vector_length, + WebRtc_Word16* filter_state); + +/**************************************************************************** + * WebRtcVad_SplitFilter(...) + * + * This function is used when before splitting a speech file into + * different frequency bands + * + * Input: + * - in_vector : Input signal to be split into two frequency bands. + * - upper_state : Current state of the upper filter + * - lower_state : Current state of the lower filter + * - in_vector_length : Length of input vector + * + * Output: + * - out_vector_hp : Upper half of the spectrum + * - out_vector_lp : Lower half of the spectrum + * - upper_state : Updated state of the upper filter + * - lower_state : Updated state of the lower filter + * + */ +void WebRtcVad_SplitFilter(WebRtc_Word16* in_vector, + WebRtc_Word16* out_vector_hp, + WebRtc_Word16* out_vector_lp, + WebRtc_Word16* upper_state, + WebRtc_Word16* lower_state, + int in_vector_length); + +/**************************************************************************** + * WebRtcVad_get_features(...) + * + * This function is used to get the logarithm of the power of each of the + * 6 frequency bands used by the VAD: + * 80 Hz - 250 Hz + * 250 Hz - 500 Hz + * 500 Hz - 1000 Hz + * 1000 Hz - 2000 Hz + * 2000 Hz - 3000 Hz + * 3000 Hz - 4000 Hz + * + * Input: + * - inst : Pointer to VAD instance + * - in_vector : Input speech signal + * - frame_size : Frame size, in number of samples + * + * Output: + * - out_vector : 10*log10(power in each freq. band), Q4 + * + * Return: total power in the signal (NOTE! This value is not exact since it + * is only used in a comparison. + */ +WebRtc_Word16 WebRtcVad_get_features(VadInstT* inst, + WebRtc_Word16* in_vector, + int frame_size, + WebRtc_Word16* out_vector); + +/**************************************************************************** + * WebRtcVad_LogOfEnergy(...) + * + * This function is used to get the logarithm of the power of one frequency band. + * + * Input: + * - vector : Input speech samples for one frequency band + * - offset : Offset value for the current frequency band + * - vector_length : Length of input vector + * + * Output: + * - enerlogval : 10*log10(energy); + * - power : Update total power in speech frame. NOTE! This value + * is not exact since it is only used in a comparison. + * + */ +void WebRtcVad_LogOfEnergy(WebRtc_Word16* vector, + WebRtc_Word16* enerlogval, + WebRtc_Word16* power, + WebRtc_Word16 offset, + int vector_length); + +#endif // WEBRTC_VAD_FILTERBANK_H_ diff --git a/src/libs/webrtc/vad/vad_gmm.c b/src/libs/webrtc/vad/vad_gmm.c new file mode 100644 index 00000000..23d12fb3 --- /dev/null +++ b/src/libs/webrtc/vad/vad_gmm.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file includes the implementation of the internal VAD call + * WebRtcVad_GaussianProbability. For function description, see vad_gmm.h. + */ + +#include "vad_gmm.h" +#include "signal_processing_library.h" +#include "vad_const.h" + +WebRtc_Word32 WebRtcVad_GaussianProbability(WebRtc_Word16 in_sample, + WebRtc_Word16 mean, + WebRtc_Word16 std, + WebRtc_Word16 *delta) +{ + WebRtc_Word16 tmp16, tmpDiv, tmpDiv2, expVal, tmp16_1, tmp16_2; + WebRtc_Word32 tmp32, y32; + + // Calculate tmpDiv=1/std, in Q10 + tmp32 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W16(std,1) + (WebRtc_Word32)131072; // 1 in Q17 + tmpDiv = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32, std); // Q17/Q7 = Q10 + + // Calculate tmpDiv2=1/std^2, in Q14 + tmp16 = WEBRTC_SPL_RSHIFT_W16(tmpDiv, 2); // From Q10 to Q8 + tmpDiv2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16, tmp16, 2); // (Q8 * Q8)>>2 = Q14 + + tmp16 = WEBRTC_SPL_LSHIFT_W16(in_sample, 3); // Q7 + tmp16 = tmp16 - mean; // Q7 - Q7 = Q7 + + // To be used later, when updating noise/speech model + // delta = (x-m)/std^2, in Q11 + *delta = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmpDiv2, tmp16, 10); //(Q14*Q7)>>10 = Q11 + + // Calculate tmp32=(x-m)^2/(2*std^2), in Q10 + tmp32 = (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT(*delta, tmp16, 9); // One shift for /2 + + // Calculate expVal ~= exp(-(x-m)^2/(2*std^2)) ~= exp2(-log2(exp(1))*tmp32) + if (tmp32 < kCompVar) + { + // Calculate tmp16 = log2(exp(1))*tmp32 , in Q10 + tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16)tmp32, + kLog10Const, 12); + tmp16 = -tmp16; + tmp16_2 = (WebRtc_Word16)(0x0400 | (tmp16 & 0x03FF)); + tmp16_1 = (WebRtc_Word16)(tmp16 ^ 0xFFFF); + tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(tmp16_1, 10); + tmp16 += 1; + // Calculate expVal=log2(-tmp32), in Q10 + expVal = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)tmp16_2, tmp16); + + } else + { + expVal = 0; + } + + // Calculate y32=(1/std)*exp(-(x-m)^2/(2*std^2)), in Q20 + y32 = WEBRTC_SPL_MUL_16_16(tmpDiv, expVal); // Q10 * Q10 = Q20 + + return y32; // Q20 +} diff --git a/src/libs/webrtc/vad/vad_gmm.h b/src/libs/webrtc/vad/vad_gmm.h new file mode 100644 index 00000000..e0747fb7 --- /dev/null +++ b/src/libs/webrtc/vad/vad_gmm.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file includes the description of the internal VAD call + * WebRtcVad_GaussianProbability. + */ + +#ifndef WEBRTC_VAD_GMM_H_ +#define WEBRTC_VAD_GMM_H_ + +#include "typedefs.h" + +/**************************************************************************** + * WebRtcVad_GaussianProbability(...) + * + * This function calculates the probability for the value 'in_sample', given that in_sample + * comes from a normal distribution with mean 'mean' and standard deviation 'std'. + * + * Input: + * - in_sample : Input sample in Q4 + * - mean : mean value in the statistical model, Q7 + * - std : standard deviation, Q7 + * + * Output: + * + * - delta : Value used when updating the model, Q11 + * + * Return: + * - out : out = 1/std * exp(-(x-m)^2/(2*std^2)); + * Probability for x. + * + */ +WebRtc_Word32 WebRtcVad_GaussianProbability(WebRtc_Word16 in_sample, + WebRtc_Word16 mean, + WebRtc_Word16 std, + WebRtc_Word16 *delta); + +#endif // WEBRTC_VAD_GMM_H_ diff --git a/src/libs/webrtc/vad/vad_sp.c b/src/libs/webrtc/vad/vad_sp.c new file mode 100644 index 00000000..f347ab59 --- /dev/null +++ b/src/libs/webrtc/vad/vad_sp.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file includes the implementation of the VAD internal calls for Downsampling and + * FindMinimum. + * For function call descriptions; See vad_sp.h. + */ + +#include "vad_sp.h" +#include "vad_defines.h" +#include "vad_const.h" +#include "signal_processing_library.h" + +// Downsampling filter based on the splitting filter and the allpass functions +// in vad_filterbank.c +void WebRtcVad_Downsampling(WebRtc_Word16* signal_in, + WebRtc_Word16* signal_out, + WebRtc_Word32* filter_state, + int inlen) +{ + WebRtc_Word16 tmp16_1, tmp16_2; + WebRtc_Word32 tmp32_1, tmp32_2; + int n, halflen; + + // Downsampling by 2 and get two branches + halflen = WEBRTC_SPL_RSHIFT_W16(inlen, 1); + + tmp32_1 = filter_state[0]; + tmp32_2 = filter_state[1]; + + // Filter coefficients in Q13, filter state in Q0 + for (n = 0; n < halflen; n++) + { + // All-pass filtering upper branch + tmp16_1 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32_1, 1) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[0]), + *signal_in, 14); + *signal_out = tmp16_1; + tmp32_1 = (WebRtc_Word32)(*signal_in++) + - (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[0]), tmp16_1, 12); + + // All-pass filtering lower branch + tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32_2, 1) + + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[1]), + *signal_in, 14); + *signal_out++ += tmp16_2; + tmp32_2 = (WebRtc_Word32)(*signal_in++) + - (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[1]), tmp16_2, 12); + } + filter_state[0] = tmp32_1; + filter_state[1] = tmp32_2; +} + +WebRtc_Word16 WebRtcVad_FindMinimum(VadInstT* inst, + WebRtc_Word16 x, + int n) +{ + int i, j, k, II = -1, offset; + WebRtc_Word16 meanV, alpha; + WebRtc_Word32 tmp32, tmp32_1; + WebRtc_Word16 *valptr, *idxptr, *p1, *p2, *p3; + + // Offset to beginning of the 16 minimum values in memory + offset = WEBRTC_SPL_LSHIFT_W16(n, 4); + + // Pointer to memory for the 16 minimum values and the age of each value + idxptr = &inst->index_vector[offset]; + valptr = &inst->low_value_vector[offset]; + + // Each value in low_value_vector is getting 1 loop older. + // Update age of each value in indexVal, and remove old values. + for (i = 0; i < 16; i++) + { + p3 = idxptr + i; + if (*p3 != 100) + { + *p3 += 1; + } else + { + p1 = valptr + i + 1; + p2 = p3 + 1; + for (j = i; j < 16; j++) + { + *(valptr + j) = *p1++; + *(idxptr + j) = *p2++; + } + *(idxptr + 15) = 101; + *(valptr + 15) = 10000; + } + } + + // Check if x smaller than any of the values in low_value_vector. + // If so, find position. + if (x < *(valptr + 7)) + { + if (x < *(valptr + 3)) + { + if (x < *(valptr + 1)) + { + if (x < *valptr) + { + II = 0; + } else + { + II = 1; + } + } else if (x < *(valptr + 2)) + { + II = 2; + } else + { + II = 3; + } + } else if (x < *(valptr + 5)) + { + if (x < *(valptr + 4)) + { + II = 4; + } else + { + II = 5; + } + } else if (x < *(valptr + 6)) + { + II = 6; + } else + { + II = 7; + } + } else if (x < *(valptr + 15)) + { + if (x < *(valptr + 11)) + { + if (x < *(valptr + 9)) + { + if (x < *(valptr + 8)) + { + II = 8; + } else + { + II = 9; + } + } else if (x < *(valptr + 10)) + { + II = 10; + } else + { + II = 11; + } + } else if (x < *(valptr + 13)) + { + if (x < *(valptr + 12)) + { + II = 12; + } else + { + II = 13; + } + } else if (x < *(valptr + 14)) + { + II = 14; + } else + { + II = 15; + } + } + + // Put new min value on right position and shift bigger values up + if (II > -1) + { + for (i = 15; i > II; i--) + { + k = i - 1; + *(valptr + i) = *(valptr + k); + *(idxptr + i) = *(idxptr + k); + } + *(valptr + II) = x; + *(idxptr + II) = 1; + } + + meanV = 0; + if ((inst->frame_counter) > 4) + { + j = 5; + } else + { + j = inst->frame_counter; + } + + if (j > 2) + { + meanV = *(valptr + 2); + } else if (j > 0) + { + meanV = *valptr; + } else + { + meanV = 1600; + } + + if (inst->frame_counter > 0) + { + if (meanV < inst->mean_value[n]) + { + alpha = (WebRtc_Word16)ALPHA1; // 0.2 in Q15 + } else + { + alpha = (WebRtc_Word16)ALPHA2; // 0.99 in Q15 + } + } else + { + alpha = 0; + } + + tmp32 = WEBRTC_SPL_MUL_16_16((alpha+1), inst->mean_value[n]); + tmp32_1 = WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_WORD16_MAX - alpha, meanV); + tmp32 += tmp32_1; + tmp32 += 16384; + inst->mean_value[n] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 15); + + return inst->mean_value[n]; +} diff --git a/src/libs/webrtc/vad/vad_sp.h b/src/libs/webrtc/vad/vad_sp.h new file mode 100644 index 00000000..ae15c11a --- /dev/null +++ b/src/libs/webrtc/vad/vad_sp.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file includes the VAD internal calls for Downsampling and FindMinimum. + * Specific function calls are given below. + */ + +#ifndef WEBRTC_VAD_SP_H_ +#define WEBRTC_VAD_SP_H_ + +#include "vad_core.h" + +/**************************************************************************** + * WebRtcVad_Downsampling(...) + * + * Downsamples the signal a factor 2, eg. 32->16 or 16->8 + * + * Input: + * - signal_in : Input signal + * - in_length : Length of input signal in samples + * + * Input & Output: + * - filter_state : Filter state for first all-pass filters + * + * Output: + * - signal_out : Downsampled signal (of length len/2) + */ +void WebRtcVad_Downsampling(WebRtc_Word16* signal_in, + WebRtc_Word16* signal_out, + WebRtc_Word32* filter_state, + int in_length); + +/**************************************************************************** + * WebRtcVad_FindMinimum(...) + * + * Find the five lowest values of x in 100 frames long window. Return a mean + * value of these five values. + * + * Input: + * - feature_value : Feature value + * - channel : Channel number + * + * Input & Output: + * - inst : State information + * + * Output: + * return value : Weighted minimum value for a moving window. + */ +WebRtc_Word16 WebRtcVad_FindMinimum(VadInstT* inst, WebRtc_Word16 feature_value, int channel); + +#endif // WEBRTC_VAD_SP_H_ diff --git a/src/libs/webrtc/vad/webrtc_vad.c b/src/libs/webrtc/vad/webrtc_vad.c new file mode 100644 index 00000000..dcfbda11 --- /dev/null +++ b/src/libs/webrtc/vad/webrtc_vad.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This file includes the VAD API calls. For a specific function call description, + * see webrtc_vad.h + */ + +#include <stdlib.h> +#include <string.h> + +#include "webrtc_vad.h" +#include "vad_core.h" + +static const int kInitCheck = 42; + +WebRtc_Word16 WebRtcVad_get_version(char *version, size_t size_bytes) +{ + const char my_version[] = "VAD 1.2.0"; + + if (version == NULL) + { + return -1; + } + + if (size_bytes < sizeof(my_version)) + { + return -1; + } + + memcpy(version, my_version, sizeof(my_version)); + return 0; +} + +WebRtc_Word16 WebRtcVad_AssignSize(int *size_in_bytes) +{ + *size_in_bytes = sizeof(VadInstT) * 2 / sizeof(WebRtc_Word16); + return 0; +} + +WebRtc_Word16 WebRtcVad_Assign(VadInst **vad_inst, void *vad_inst_addr) +{ + + if (vad_inst == NULL) + { + return -1; + } + + if (vad_inst_addr != NULL) + { + *vad_inst = (VadInst*)vad_inst_addr; + return 0; + } else + { + return -1; + } +} + +WebRtc_Word16 WebRtcVad_Create(VadInst **vad_inst) +{ + + VadInstT *vad_ptr = NULL; + + if (vad_inst == NULL) + { + return -1; + } + + *vad_inst = NULL; + + vad_ptr = (VadInstT *)malloc(sizeof(VadInstT)); + *vad_inst = (VadInst *)vad_ptr; + + if (vad_ptr == NULL) + { + return -1; + } + + vad_ptr->init_flag = 0; + + return 0; +} + +WebRtc_Word16 WebRtcVad_Free(VadInst *vad_inst) +{ + + if (vad_inst == NULL) + { + return -1; + } + + free(vad_inst); + return 0; +} + +WebRtc_Word16 WebRtcVad_Init(VadInst *vad_inst) +{ + short mode = 0; // Default high quality + + if (vad_inst == NULL) + { + return -1; + } + + return WebRtcVad_InitCore((VadInstT*)vad_inst, mode); +} + +WebRtc_Word16 WebRtcVad_set_mode(VadInst *vad_inst, WebRtc_Word16 mode) +{ + VadInstT* vad_ptr; + + if (vad_inst == NULL) + { + return -1; + } + + vad_ptr = (VadInstT*)vad_inst; + if (vad_ptr->init_flag != kInitCheck) + { + return -1; + } + + return WebRtcVad_set_mode_core((VadInstT*)vad_inst, mode); +} + +WebRtc_Word16 WebRtcVad_Process(VadInst *vad_inst, + WebRtc_Word16 fs, + WebRtc_Word16 *speech_frame, + WebRtc_Word16 frame_length) +{ + WebRtc_Word16 vad; + VadInstT* vad_ptr; + + if (vad_inst == NULL) + { + return -1; + } + + vad_ptr = (VadInstT*)vad_inst; + if (vad_ptr->init_flag != kInitCheck) + { + return -1; + } + + if (speech_frame == NULL) + { + return -1; + } + + if (fs == 32000) + { + if ((frame_length != 320) && (frame_length != 640) && (frame_length != 960)) + { + return -1; + } + vad = WebRtcVad_CalcVad32khz((VadInstT*)vad_inst, speech_frame, frame_length); + + } else if (fs == 16000) + { + if ((frame_length != 160) && (frame_length != 320) && (frame_length != 480)) + { + return -1; + } + vad = WebRtcVad_CalcVad16khz((VadInstT*)vad_inst, speech_frame, frame_length); + + } else if (fs == 8000) + { + if ((frame_length != 80) && (frame_length != 160) && (frame_length != 240)) + { + return -1; + } + vad = WebRtcVad_CalcVad8khz((VadInstT*)vad_inst, speech_frame, frame_length); + + } else + { + return -1; // Not a supported sampling frequency + } + + if (vad > 0) + { + return 1; + } else if (vad == 0) + { + return 0; + } else + { + return -1; + } +} diff --git a/src/libs/webrtc/vad/webrtc_vad.h b/src/libs/webrtc/vad/webrtc_vad.h new file mode 100644 index 00000000..6e3eb74a --- /dev/null +++ b/src/libs/webrtc/vad/webrtc_vad.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +/* + * This header file includes the VAD API calls. Specific function calls are given below. + */ + +#ifndef WEBRTC_VAD_WEBRTC_VAD_H_ +#define WEBRTC_VAD_WEBRTC_VAD_H_ + +#include "typedefs.h" + +typedef struct WebRtcVadInst VadInst; + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * WebRtcVad_get_version(...) + * + * This function returns the version number of the code. + * + * Output: + * - version : Pointer to a buffer where the version info will + * be stored. + * Input: + * - size_bytes : Size of the buffer. + * + */ +WebRtc_Word16 WebRtcVad_get_version(char *version, size_t size_bytes); + +/**************************************************************************** + * WebRtcVad_AssignSize(...) + * + * This functions get the size needed for storing the instance for encoder + * and decoder, respectively + * + * Input/Output: + * - size_in_bytes : Pointer to integer where the size is returned + * + * Return value : 0 + */ +WebRtc_Word16 WebRtcVad_AssignSize(int *size_in_bytes); + +/**************************************************************************** + * WebRtcVad_Assign(...) + * + * This functions Assigns memory for the instances. + * + * Input: + * - vad_inst_addr : Address to where to assign memory + * Output: + * - vad_inst : Pointer to the instance that should be created + * + * Return value : 0 - Ok + * -1 - Error + */ +WebRtc_Word16 WebRtcVad_Assign(VadInst **vad_inst, void *vad_inst_addr); + +/**************************************************************************** + * WebRtcVad_Create(...) + * + * This function creates an instance to the VAD structure + * + * Input: + * - vad_inst : Pointer to VAD instance that should be created + * + * Output: + * - vad_inst : Pointer to created VAD instance + * + * Return value : 0 - Ok + * -1 - Error + */ +WebRtc_Word16 WebRtcVad_Create(VadInst **vad_inst); + +/**************************************************************************** + * WebRtcVad_Free(...) + * + * This function frees the dynamic memory of a specified VAD instance + * + * Input: + * - vad_inst : Pointer to VAD instance that should be freed + * + * Return value : 0 - Ok + * -1 - Error + */ +WebRtc_Word16 WebRtcVad_Free(VadInst *vad_inst); + +/**************************************************************************** + * WebRtcVad_Init(...) + * + * This function initializes a VAD instance + * + * Input: + * - vad_inst : Instance that should be initialized + * + * Output: + * - vad_inst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ +WebRtc_Word16 WebRtcVad_Init(VadInst *vad_inst); + +/**************************************************************************** + * WebRtcVad_set_mode(...) + * + * This function initializes a VAD instance + * + * Input: + * - vad_inst : VAD instance + * - mode : Aggressiveness setting (0, 1, 2, or 3) + * + * Output: + * - vad_inst : Initialized instance + * + * Return value : 0 - Ok + * -1 - Error + */ +WebRtc_Word16 WebRtcVad_set_mode(VadInst *vad_inst, WebRtc_Word16 mode); + +/**************************************************************************** + * WebRtcVad_Process(...) + * + * This functions does a VAD for the inserted speech frame + * + * Input + * - vad_inst : VAD Instance. Needs to be initiated before call. + * - fs : sampling frequency (Hz): 8000, 16000, or 32000 + * - speech_frame : Pointer to speech frame buffer + * - frame_length : Length of speech frame buffer in number of samples + * + * Output: + * - vad_inst : Updated VAD instance + * + * Return value : 1 - Active Voice + * 0 - Non-active Voice + * -1 - Error + */ +WebRtc_Word16 WebRtcVad_Process(VadInst *vad_inst, + WebRtc_Word16 fs, + WebRtc_Word16 *speech_frame, + WebRtc_Word16 frame_length); + +#ifdef __cplusplus +} +#endif + +#endif // WEBRTC_VAD_WEBRTC_VAD_H_ diff --git a/src/libs/webrtc/webrtc.vcproj b/src/libs/webrtc/webrtc.vcproj new file mode 100644 index 00000000..86526e5a --- /dev/null +++ b/src/libs/webrtc/webrtc.vcproj @@ -0,0 +1,1732 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="webrtc" + ProjectGUID="{8D9570F8-0940-4359-99AB-7B71A229D426}" + RootNamespace="webrtc" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories=".;..;./signal_processing_library;./utility;./cng" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + WholeProgramOptimization="false" + AdditionalIncludeDirectories=".;..;./signal_processing_library;./utility;./cng" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB; _CRT_SECURE_NO_WARNINGS" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="vad" + > + <File + RelativePath=".\vad\vad_const.c" + > + </File> + <File + RelativePath=".\vad\vad_const.h" + > + </File> + <File + RelativePath=".\vad\vad_core.c" + > + </File> + <File + RelativePath=".\vad\vad_core.h" + > + </File> + <File + RelativePath=".\vad\vad_defines.h" + > + </File> + <File + RelativePath=".\vad\vad_filterbank.c" + > + </File> + <File + RelativePath=".\vad\vad_filterbank.h" + > + </File> + <File + RelativePath=".\vad\vad_gmm.c" + > + </File> + <File + RelativePath=".\vad\vad_gmm.h" + > + </File> + <File + RelativePath=".\vad\vad_sp.c" + > + </File> + <File + RelativePath=".\vad\vad_sp.h" + > + </File> + <File + RelativePath=".\vad\webrtc_vad.c" + > + </File> + <File + RelativePath=".\vad\webrtc_vad.h" + > + </File> + </Filter> + <Filter + Name="ns" + > + <File + RelativePath=".\ns\defines.h" + > + </File> + <File + RelativePath=".\ns\noise_suppression.c" + > + </File> + <File + RelativePath=".\ns\noise_suppression.h" + > + </File> + <File + RelativePath=".\ns\noise_suppression_x.c" + > + </File> + <File + RelativePath=".\ns\noise_suppression_x.h" + > + </File> + <File + RelativePath=".\ns\ns_core.c" + > + </File> + <File + RelativePath=".\ns\ns_core.h" + > + </File> + <File + RelativePath=".\ns\nsx_core.c" + > + </File> + <File + RelativePath=".\ns\nsx_core.h" + > + </File> + <File + RelativePath=".\ns\nsx_defines.h" + > + </File> + <File + RelativePath=".\ns\windows_private.h" + > + </File> + </Filter> + <Filter + Name="aec" + > + <File + RelativePath=".\aec\aec_core.c" + > + </File> + <File + RelativePath=".\aec\aec_core.h" + > + </File> + <File + RelativePath=".\aec\aec_core_rdft.c" + > + </File> + <File + RelativePath=".\aec\aec_core_sse2.c" + > + </File> + <File + RelativePath=".\aec\echo_cancellation.c" + > + </File> + <File + RelativePath=".\aec\echo_cancellation.h" + > + </File> + <File + RelativePath=".\aec\resampler.c" + > + </File> + <File + RelativePath=".\aec\resampler.h" + > + </File> + </Filter> + <Filter + Name="aecm" + > + <File + RelativePath=".\aecm\aecm_core.c" + > + </File> + <File + RelativePath=".\aecm\aecm_core.h" + > + </File> + <File + RelativePath=".\aecm\echo_control_mobile.c" + > + </File> + <File + RelativePath=".\aecm\echo_control_mobile.h" + > + </File> + </Filter> + <Filter + Name="agc" + > + <File + RelativePath=".\agc\analog_agc.c" + > + </File> + <File + RelativePath=".\agc\analog_agc.h" + > + </File> + <File + RelativePath=".\agc\digital_agc.c" + > + </File> + <File + RelativePath=".\agc\digital_agc.h" + > + </File> + <File + RelativePath=".\agc\gain_control.h" + > + </File> + </Filter> + <Filter + Name="utility" + > + <File + RelativePath=".\utility\fft4g.c" + > + </File> + <File + RelativePath=".\utility\fft4g.h" + > + </File> + <File + RelativePath=".\utility\ring_buffer.c" + > + </File> + <File + RelativePath=".\utility\ring_buffer.h" + > + </File> + </Filter> + <Filter + Name="system_wrappers" + > + <File + RelativePath=".\system_wrappers\aligned_malloc.h" + > + </File> + <File + RelativePath=".\system_wrappers\atomic32.cc" + > + </File> + <File + RelativePath=".\system_wrappers\atomic32_windows.h" + > + </File> + <File + RelativePath=".\system_wrappers\atomic32_wrapper.h" + > + </File> + <File + RelativePath=".\system_wrappers\condition_variable.cc" + > + </File> + <File + RelativePath=".\system_wrappers\condition_variable_windows.cc" + > + </File> + <File + RelativePath=".\system_wrappers\condition_variable_windows.h" + > + </File> + <File + RelativePath=".\system_wrappers\condition_variable_wrapper.h" + > + </File> + <File + RelativePath=".\system_wrappers\constructor_magic.h" + > + </File> + <File + RelativePath=".\system_wrappers\cpu.cc" + > + </File> + <File + RelativePath=".\system_wrappers\cpu_features.cc" + > + </File> + <File + RelativePath=".\system_wrappers\cpu_features_wrapper.h" + > + </File> + <File + RelativePath=".\system_wrappers\cpu_windows.cc" + > + </File> + <File + RelativePath=".\system_wrappers\cpu_windows.h" + > + </File> + <File + RelativePath=".\system_wrappers\cpu_wrapper.h" + > + </File> + <File + RelativePath=".\system_wrappers\critical_section.cc" + > + </File> + <File + RelativePath=".\system_wrappers\critical_section_windows.cc" + > + </File> + <File + RelativePath=".\system_wrappers\critical_section_windows.h" + > + </File> + <File + RelativePath=".\system_wrappers\critical_section_wrapper.h" + > + </File> + <File + RelativePath=".\system_wrappers\event.cc" + > + </File> + <File + RelativePath=".\system_wrappers\event_windows.cc" + > + </File> + <File + RelativePath=".\system_wrappers\event_windows.h" + > + </File> + <File + RelativePath=".\system_wrappers\event_wrapper.h" + > + </File> + <File + RelativePath=".\system_wrappers\file_impl.cc" + > + </File> + <File + RelativePath=".\system_wrappers\file_impl.h" + > + </File> + <File + RelativePath=".\system_wrappers\file_wrapper.h" + > + </File> + <File + RelativePath=".\system_wrappers\fix_interlocked_exchange_pointer_windows.h" + > + </File> + <File + RelativePath=".\system_wrappers\rw_lock.cc" + > + </File> + <File + RelativePath=".\system_wrappers\rw_lock_generic.cc" + > + </File> + <File + RelativePath=".\system_wrappers\rw_lock_generic.h" + > + </File> + <File + RelativePath=".\system_wrappers\rw_lock_windows.cc" + > + </File> + <File + RelativePath=".\system_wrappers\rw_lock_windows.h" + > + </File> + <File + RelativePath=".\system_wrappers\rw_lock_wrapper.h" + > + </File> + <File + RelativePath=".\system_wrappers\sort.cc" + > + </File> + <File + RelativePath=".\system_wrappers\sort.h" + > + </File> + <File + RelativePath=".\system_wrappers\thread.cc" + > + </File> + <File + RelativePath=".\system_wrappers\thread_windows.cc" + > + </File> + <File + RelativePath=".\system_wrappers\thread_windows.h" + > + </File> + <File + RelativePath=".\system_wrappers\thread_windows_set_name.h" + > + </File> + <File + RelativePath=".\system_wrappers\thread_wrapper.h" + > + </File> + <File + RelativePath=".\system_wrappers\tick_util.h" + > + </File> + <File + RelativePath=".\system_wrappers\trace.h" + > + </File> + <File + RelativePath=".\system_wrappers\trace_impl.cc" + > + </File> + <File + RelativePath=".\system_wrappers\trace_impl.h" + > + </File> + <File + RelativePath=".\system_wrappers\trace_windows.cc" + > + </File> + <File + RelativePath=".\system_wrappers\trace_windows.h" + > + </File> + </Filter> + <Filter + Name="neteq" + > + <File + RelativePath=".\neteq\accelerate.c" + > + </File> + <File + RelativePath=".\neteq\automode.c" + > + </File> + <File + RelativePath=".\neteq\automode.h" + > + </File> + <File + RelativePath=".\neteq\bgn_update.c" + > + </File> + <File + RelativePath=".\neteq\buffer_stats.h" + > + </File> + <File + RelativePath=".\neteq\bufstats_decision.c" + > + </File> + <File + RelativePath=".\neteq\cng_internal.c" + > + </File> + <File + RelativePath=".\neteq\codec_db.c" + > + </File> + <File + RelativePath=".\neteq\codec_db.h" + > + </File> + <File + RelativePath=".\neteq\codec_db_defines.h" + > + </File> + <File + RelativePath=".\neteq\correlator.c" + > + </File> + <File + RelativePath=".\neteq\delay_logging.h" + > + </File> + <File + RelativePath=".\neteq\dsp.c" + > + </File> + <File + RelativePath=".\neteq\dsp.h" + > + </File> + <File + RelativePath=".\neteq\dsp_helpfunctions.c" + > + </File> + <File + RelativePath=".\neteq\dsp_helpfunctions.h" + > + </File> + <File + RelativePath=".\neteq\dtmf_buffer.c" + > + </File> + <File + RelativePath=".\neteq\dtmf_buffer.h" + > + </File> + <File + RelativePath=".\neteq\dtmf_tonegen.c" + > + </File> + <File + RelativePath=".\neteq\dtmf_tonegen.h" + > + </File> + <File + RelativePath=".\neteq\expand.c" + > + </File> + <File + RelativePath=".\neteq\mcu.h" + > + </File> + <File + RelativePath=".\neteq\mcu_address_init.c" + > + </File> + <File + RelativePath=".\neteq\mcu_dsp_common.c" + > + </File> + <File + RelativePath=".\neteq\mcu_dsp_common.h" + > + </File> + <File + RelativePath=".\neteq\mcu_reset.c" + > + </File> + <File + RelativePath=".\neteq\merge.c" + > + </File> + <File + RelativePath=".\neteq\min_distortion.c" + > + </File> + <File + RelativePath=".\neteq\mix_voice_unvoice.c" + > + </File> + <File + RelativePath=".\neteq\mute_signal.c" + > + </File> + <File + RelativePath=".\neteq\neteq_defines.h" + > + </File> + <File + RelativePath=".\neteq\neteq_error_codes.h" + > + </File> + <File + RelativePath=".\neteq\neteq_statistics.h" + > + </File> + <File + RelativePath=".\neteq\normal.c" + > + </File> + <File + RelativePath=".\neteq\packet_buffer.c" + > + </File> + <File + RelativePath=".\neteq\packet_buffer.h" + > + </File> + <File + RelativePath=".\neteq\peak_detection.c" + > + </File> + <File + RelativePath=".\neteq\preemptive_expand.c" + > + </File> + <File + RelativePath=".\neteq\random_vector.c" + > + </File> + <File + RelativePath=".\neteq\recin.c" + > + </File> + <File + RelativePath=".\neteq\recout.c" + > + </File> + <File + RelativePath=".\neteq\rtcp.c" + > + </File> + <File + RelativePath=".\neteq\rtcp.h" + > + </File> + <File + RelativePath=".\neteq\rtp.c" + > + </File> + <File + RelativePath=".\neteq\rtp.h" + > + </File> + <File + RelativePath=".\neteq\set_fs.c" + > + </File> + <File + RelativePath=".\neteq\signal_mcu.c" + > + </File> + <File + RelativePath=".\neteq\split_and_insert.c" + > + </File> + <File + RelativePath=".\neteq\unmute_signal.c" + > + </File> + <File + RelativePath=".\neteq\webrtc_neteq.c" + > + </File> + <File + RelativePath=".\neteq\webrtc_neteq.h" + > + </File> + <File + RelativePath=".\neteq\webrtc_neteq_help_macros.h" + > + </File> + <File + RelativePath=".\neteq\webrtc_neteq_internal.h" + > + </File> + </Filter> + <Filter + Name="cng" + > + <File + RelativePath=".\cng\cng_helpfuns.c" + > + </File> + <File + RelativePath=".\cng\cng_helpfuns.h" + > + </File> + <File + RelativePath=".\cng\webrtc_cng.c" + > + </File> + <File + RelativePath=".\cng\webrtc_cng.h" + > + </File> + </Filter> + <Filter + Name="signal_processing_library" + > + <File + RelativePath=".\signal_processing_library\add_sat_w16.c" + > + </File> + <File + RelativePath=".\signal_processing_library\add_sat_w32.c" + > + </File> + <File + RelativePath=".\signal_processing_library\auto_corr_to_refl_coef.c" + > + </File> + <File + RelativePath=".\signal_processing_library\auto_correlation.c" + > + </File> + <File + RelativePath=".\signal_processing_library\complex_bit_reverse.c" + > + </File> + <File + RelativePath=".\signal_processing_library\complex_fft.c" + > + </File> + <File + RelativePath=".\signal_processing_library\complex_ifft.c" + > + </File> + <File + RelativePath=".\signal_processing_library\copy_set_operations.c" + > + </File> + <File + RelativePath=".\signal_processing_library\cos_table.c" + > + </File> + <File + RelativePath=".\signal_processing_library\cross_correlation.c" + > + </File> + <File + RelativePath=".\signal_processing_library\division_operations.c" + > + </File> + <File + RelativePath=".\signal_processing_library\dot_product_with_scale.c" + > + </File> + <File + RelativePath=".\signal_processing_library\downsample_fast.c" + > + </File> + <File + RelativePath=".\signal_processing_library\energy.c" + > + </File> + <File + RelativePath=".\signal_processing_library\filter_ar.c" + > + </File> + <File + RelativePath=".\signal_processing_library\filter_ar_fast_q12.c" + > + </File> + <File + RelativePath=".\signal_processing_library\filter_ma_fast_q12.c" + > + </File> + <File + RelativePath=".\signal_processing_library\get_hanning_window.c" + > + </File> + <File + RelativePath=".\signal_processing_library\get_scaling_square.c" + > + </File> + <File + RelativePath=".\signal_processing_library\get_size_in_bits.c" + > + </File> + <File + RelativePath=".\signal_processing_library\hanning_table.c" + > + </File> + <File + RelativePath=".\signal_processing_library\ilbc_specific_functions.c" + > + </File> + <File + RelativePath=".\signal_processing_library\levinson_durbin.c" + > + </File> + <File + RelativePath=".\signal_processing_library\lpc_to_refl_coef.c" + > + </File> + <File + RelativePath=".\signal_processing_library\min_max_operations.c" + > + </File> + <File + RelativePath=".\signal_processing_library\norm_u32.c" + > + </File> + <File + RelativePath=".\signal_processing_library\norm_w16.c" + > + </File> + <File + RelativePath=".\signal_processing_library\norm_w32.c" + > + </File> + <File + RelativePath=".\signal_processing_library\randn_table.c" + > + </File> + <File + RelativePath=".\signal_processing_library\randomization_functions.c" + > + </File> + <File + RelativePath=".\signal_processing_library\refl_coef_to_lpc.c" + > + </File> + <File + RelativePath=".\signal_processing_library\resample.c" + > + </File> + <File + RelativePath=".\signal_processing_library\resample_48khz.c" + > + </File> + <File + RelativePath=".\signal_processing_library\resample_by_2.c" + > + </File> + <File + RelativePath=".\signal_processing_library\resample_by_2_internal.c" + > + </File> + <File + RelativePath=".\signal_processing_library\resample_by_2_internal.h" + > + </File> + <File + RelativePath=".\signal_processing_library\resample_fractional.c" + > + </File> + <File + RelativePath=".\signal_processing_library\signal_processing_library.h" + > + </File> + <File + RelativePath=".\signal_processing_library\sin_table.c" + > + </File> + <File + RelativePath=".\signal_processing_library\sin_table_1024.c" + > + </File> + <File + RelativePath=".\signal_processing_library\spl_inl.h" + > + </File> + <File + RelativePath=".\signal_processing_library\spl_sqrt.c" + > + </File> + <File + RelativePath=".\signal_processing_library\spl_version.c" + > + </File> + <File + RelativePath=".\signal_processing_library\splitting_filter.c" + > + </File> + <File + RelativePath=".\signal_processing_library\sqrt_of_one_minus_x_squared.c" + > + </File> + <File + RelativePath=".\signal_processing_library\sub_sat_w16.c" + > + </File> + <File + RelativePath=".\signal_processing_library\sub_sat_w32.c" + > + </File> + <File + RelativePath=".\signal_processing_library\vector_scaling_operations.c" + > + </File> + <File + RelativePath=".\signal_processing_library\webrtc_fft_t_1024_8.c" + > + </File> + <File + RelativePath=".\signal_processing_library\webrtc_fft_t_rad.c" + > + </File> + </Filter> + <Filter + Name="isac" + > + <File + RelativePath=".\isac\arith_routines.c" + > + </File> + <File + RelativePath=".\isac\arith_routines_hist.c" + > + </File> + <File + RelativePath=".\isac\arith_routines_logist.c" + > + </File> + <File + RelativePath=".\isac\arith_routins.h" + > + </File> + <File + RelativePath=".\isac\bandwidth_estimator.c" + > + </File> + <File + RelativePath=".\isac\bandwidth_estimator.h" + > + </File> + <File + RelativePath=".\isac\codec.h" + > + </File> + <File + RelativePath=".\isac\decode_bwe.c" + > + </File> + <File + RelativePath=".\isac\decode_plc.c" + > + </File> + <File + RelativePath=".\isac\encode.c" + > + </File> + <File + RelativePath=".\isac\entropy_coding.c" + > + </File> + <File + RelativePath=".\isac\entropy_coding.h" + > + </File> + <File + RelativePath=".\isac\fft.c" + > + </File> + <File + RelativePath=".\isac\fft.h" + > + </File> + <File + RelativePath=".\isac\filterbank_tables.c" + > + </File> + <File + RelativePath=".\isac\filterbank_tables.h" + > + </File> + <File + RelativePath=".\isac\filterbanks.c" + > + </File> + <File + RelativePath=".\isac\initialize.c" + > + </File> + <File + RelativePath=".\isac\isac_decode.c" + > + </File> + <File + RelativePath=".\isac\isac_filters.c" + > + </File> + <File + RelativePath=".\isac\isacfix.c" + > + </File> + <File + RelativePath=".\isac\isacfix.h" + > + </File> + <File + RelativePath=".\isac\lattice.c" + > + </File> + <File + RelativePath=".\isac\lpc_masking_model.c" + > + </File> + <File + RelativePath=".\isac\lpc_masking_model.h" + > + </File> + <File + RelativePath=".\isac\lpc_tables.c" + > + </File> + <File + RelativePath=".\isac\lpc_tables.h" + > + </File> + <File + RelativePath=".\isac\pitch_estimator.c" + > + </File> + <File + RelativePath=".\isac\pitch_estimator.h" + > + </File> + <File + RelativePath=".\isac\pitch_filter.c" + > + </File> + <File + RelativePath=".\isac\pitch_gain_tables.c" + > + </File> + <File + RelativePath=".\isac\pitch_gain_tables.h" + > + </File> + <File + RelativePath=".\isac\pitch_lag_tables.c" + > + </File> + <File + RelativePath=".\isac\pitch_lag_tables.h" + > + </File> + <File + RelativePath=".\isac\settings.h" + > + </File> + <File + RelativePath=".\isac\spectrum_ar_model_tables.c" + > + </File> + <File + RelativePath=".\isac\spectrum_ar_model_tables.h" + > + </File> + <File + RelativePath=".\isac\structs.h" + > + </File> + <File + RelativePath=".\isac\transform.c" + > + </File> + </Filter> + <Filter + Name="ilbc" + > + <File + RelativePath=".\ilbcfix\abs_quant.c" + > + </File> + <File + RelativePath=".\ilbcfix\abs_quant.h" + > + </File> + <File + RelativePath=".\ilbcfix\abs_quant_loop.c" + > + </File> + <File + RelativePath=".\ilbcfix\abs_quant_loop.h" + > + </File> + <File + RelativePath=".\ilbcfix\augmented_cb_corr.c" + > + </File> + <File + RelativePath=".\ilbcfix\augmented_cb_corr.h" + > + </File> + <File + RelativePath=".\ilbcfix\bw_expand.c" + > + </File> + <File + RelativePath=".\ilbcfix\bw_expand.h" + > + </File> + <File + RelativePath=".\ilbcfix\cb_construct.c" + > + </File> + <File + RelativePath=".\ilbcfix\cb_construct.h" + > + </File> + <File + RelativePath=".\ilbcfix\cb_mem_energy.c" + > + </File> + <File + RelativePath=".\ilbcfix\cb_mem_energy.h" + > + </File> + <File + RelativePath=".\ilbcfix\cb_mem_energy_augmentation.c" + > + </File> + <File + RelativePath=".\ilbcfix\cb_mem_energy_augmentation.h" + > + </File> + <File + RelativePath=".\ilbcfix\cb_mem_energy_calc.c" + > + </File> + <File + RelativePath=".\ilbcfix\cb_mem_energy_calc.h" + > + </File> + <File + RelativePath=".\ilbcfix\cb_search.h" + > + </File> + <File + RelativePath=".\ilbcfix\cb_search_core.c" + > + </File> + <File + RelativePath=".\ilbcfix\cb_search_core.h" + > + </File> + <File + RelativePath=".\ilbcfix\cb_update_best_index.c" + > + </File> + <File + RelativePath=".\ilbcfix\cb_update_best_index.h" + > + </File> + <File + RelativePath=".\ilbcfix\chebyshev.c" + > + </File> + <File + RelativePath=".\ilbcfix\chebyshev.h" + > + </File> + <File + RelativePath=".\ilbcfix\comp_corr.c" + > + </File> + <File + RelativePath=".\ilbcfix\comp_corr.h" + > + </File> + <File + RelativePath=".\ilbcfix\complexityMeasures.m" + > + </File> + <File + RelativePath=".\ilbcfix\constants.h" + > + </File> + <File + RelativePath=".\ilbcfix\create_augmented_vec.c" + > + </File> + <File + RelativePath=".\ilbcfix\create_augmented_vec.h" + > + </File> + <File + RelativePath=".\ilbcfix\decode.h" + > + </File> + <File + RelativePath=".\ilbcfix\decode_residual.c" + > + </File> + <File + RelativePath=".\ilbcfix\decode_residual.h" + > + </File> + <File + RelativePath=".\ilbcfix\decoder_interpolate_lsf.c" + > + </File> + <File + RelativePath=".\ilbcfix\decoder_interpolate_lsf.h" + > + </File> + <File + RelativePath=".\ilbcfix\defines.h" + > + </File> + <File + RelativePath=".\ilbcfix\do_plc.c" + > + </File> + <File + RelativePath=".\ilbcfix\do_plc.h" + > + </File> + <File + RelativePath=".\ilbcfix\encode.h" + > + </File> + <File + RelativePath=".\ilbcfix\energy_inverse.c" + > + </File> + <File + RelativePath=".\ilbcfix\energy_inverse.h" + > + </File> + <File + RelativePath=".\ilbcfix\enh_upsample.c" + > + </File> + <File + RelativePath=".\ilbcfix\enh_upsample.h" + > + </File> + <File + RelativePath=".\ilbcfix\enhancer.c" + > + </File> + <File + RelativePath=".\ilbcfix\enhancer.h" + > + </File> + <File + RelativePath=".\ilbcfix\enhancer_interface.c" + > + </File> + <File + RelativePath=".\ilbcfix\enhancer_interface.h" + > + </File> + <File + RelativePath=".\ilbcfix\filtered_cb_vecs.c" + > + </File> + <File + RelativePath=".\ilbcfix\filtered_cb_vecs.h" + > + </File> + <File + RelativePath=".\ilbcfix\frame_classify.c" + > + </File> + <File + RelativePath=".\ilbcfix\frame_classify.h" + > + </File> + <File + RelativePath=".\ilbcfix\gain_dequant.c" + > + </File> + <File + RelativePath=".\ilbcfix\gain_dequant.h" + > + </File> + <File + RelativePath=".\ilbcfix\gain_quant.c" + > + </File> + <File + RelativePath=".\ilbcfix\gain_quant.h" + > + </File> + <File + RelativePath=".\ilbcfix\get_cd_vec.c" + > + </File> + <File + RelativePath=".\ilbcfix\get_cd_vec.h" + > + </File> + <File + RelativePath=".\ilbcfix\get_lsp_poly.c" + > + </File> + <File + RelativePath=".\ilbcfix\get_lsp_poly.h" + > + </File> + <File + RelativePath=".\ilbcfix\get_sync_seq.c" + > + </File> + <File + RelativePath=".\ilbcfix\get_sync_seq.h" + > + </File> + <File + RelativePath=".\ilbcfix\hp_input.c" + > + </File> + <File + RelativePath=".\ilbcfix\hp_input.h" + > + </File> + <File + RelativePath=".\ilbcfix\hp_output.c" + > + </File> + <File + RelativePath=".\ilbcfix\hp_output.h" + > + </File> + <File + RelativePath=".\ilbcfix\ilbc.c" + > + </File> + <File + RelativePath=".\ilbcfix\ilbc.gyp" + > + </File> + <File + RelativePath=".\ilbcfix\ilbc.h" + > + </File> + <File + RelativePath=".\ilbcfix\ilbc_cb_search.c" + > + </File> + <File + RelativePath=".\ilbcfix\ilbc_constants.c" + > + </File> + <File + RelativePath=".\ilbcfix\ilbc_decode.c" + > + </File> + <File + RelativePath=".\ilbcfix\ilbc_encode.c" + > + </File> + <File + RelativePath=".\ilbcfix\index_conv_dec.c" + > + </File> + <File + RelativePath=".\ilbcfix\index_conv_dec.h" + > + </File> + <File + RelativePath=".\ilbcfix\index_conv_enc.c" + > + </File> + <File + RelativePath=".\ilbcfix\index_conv_enc.h" + > + </File> + <File + RelativePath=".\ilbcfix\init_decode.c" + > + </File> + <File + RelativePath=".\ilbcfix\init_decode.h" + > + </File> + <File + RelativePath=".\ilbcfix\init_encode.c" + > + </File> + <File + RelativePath=".\ilbcfix\init_encode.h" + > + </File> + <File + RelativePath=".\ilbcfix\interpolate.c" + > + </File> + <File + RelativePath=".\ilbcfix\interpolate.h" + > + </File> + <File + RelativePath=".\ilbcfix\interpolate_samples.c" + > + </File> + <File + RelativePath=".\ilbcfix\interpolate_samples.h" + > + </File> + <File + RelativePath=".\ilbcfix\lpc_encode.c" + > + </File> + <File + RelativePath=".\ilbcfix\lpc_encode.h" + > + </File> + <File + RelativePath=".\ilbcfix\lsf_check.c" + > + </File> + <File + RelativePath=".\ilbcfix\lsf_check.h" + > + </File> + <File + RelativePath=".\ilbcfix\lsf_interpolate_to_poly_dec.c" + > + </File> + <File + RelativePath=".\ilbcfix\lsf_interpolate_to_poly_dec.h" + > + </File> + <File + RelativePath=".\ilbcfix\lsf_interpolate_to_poly_enc.c" + > + </File> + <File + RelativePath=".\ilbcfix\lsf_interpolate_to_poly_enc.h" + > + </File> + <File + RelativePath=".\ilbcfix\lsf_to_lsp.c" + > + </File> + <File + RelativePath=".\ilbcfix\lsf_to_lsp.h" + > + </File> + <File + RelativePath=".\ilbcfix\lsf_to_poly.c" + > + </File> + <File + RelativePath=".\ilbcfix\lsf_to_poly.h" + > + </File> + <File + RelativePath=".\ilbcfix\lsp_to_lsf.c" + > + </File> + <File + RelativePath=".\ilbcfix\lsp_to_lsf.h" + > + </File> + <File + RelativePath=".\ilbcfix\my_corr.c" + > + </File> + <File + RelativePath=".\ilbcfix\my_corr.h" + > + </File> + <File + RelativePath=".\ilbcfix\nearest_neighbor.c" + > + </File> + <File + RelativePath=".\ilbcfix\nearest_neighbor.h" + > + </File> + <File + RelativePath=".\ilbcfix\pack_bits.c" + > + </File> + <File + RelativePath=".\ilbcfix\pack_bits.h" + > + </File> + <File + RelativePath=".\ilbcfix\poly_to_lsf.c" + > + </File> + <File + RelativePath=".\ilbcfix\poly_to_lsf.h" + > + </File> + <File + RelativePath=".\ilbcfix\poly_to_lsp.c" + > + </File> + <File + RelativePath=".\ilbcfix\poly_to_lsp.h" + > + </File> + <File + RelativePath=".\ilbcfix\refiner.c" + > + </File> + <File + RelativePath=".\ilbcfix\refiner.h" + > + </File> + <File + RelativePath=".\ilbcfix\simple_interpolate_lsf.c" + > + </File> + <File + RelativePath=".\ilbcfix\simple_interpolate_lsf.h" + > + </File> + <File + RelativePath=".\ilbcfix\simple_lpc_analysis.c" + > + </File> + <File + RelativePath=".\ilbcfix\simple_lpc_analysis.h" + > + </File> + <File + RelativePath=".\ilbcfix\simple_lsf_dequant.c" + > + </File> + <File + RelativePath=".\ilbcfix\simple_lsf_dequant.h" + > + </File> + <File + RelativePath=".\ilbcfix\simple_lsf_quant.c" + > + </File> + <File + RelativePath=".\ilbcfix\simple_lsf_quant.h" + > + </File> + <File + RelativePath=".\ilbcfix\smooth.c" + > + </File> + <File + RelativePath=".\ilbcfix\smooth.h" + > + </File> + <File + RelativePath=".\ilbcfix\smooth_out_data.c" + > + </File> + <File + RelativePath=".\ilbcfix\smooth_out_data.h" + > + </File> + <File + RelativePath=".\ilbcfix\sort_sq.c" + > + </File> + <File + RelativePath=".\ilbcfix\sort_sq.h" + > + </File> + <File + RelativePath=".\ilbcfix\split_vq.c" + > + </File> + <File + RelativePath=".\ilbcfix\split_vq.h" + > + </File> + <File + RelativePath=".\ilbcfix\state_construct.c" + > + </File> + <File + RelativePath=".\ilbcfix\state_construct.h" + > + </File> + <File + RelativePath=".\ilbcfix\state_search.c" + > + </File> + <File + RelativePath=".\ilbcfix\state_search.h" + > + </File> + <File + RelativePath=".\ilbcfix\swap_bytes.c" + > + </File> + <File + RelativePath=".\ilbcfix\swap_bytes.h" + > + </File> + <File + RelativePath=".\ilbcfix\unpack_bits.c" + > + </File> + <File + RelativePath=".\ilbcfix\unpack_bits.h" + > + </File> + <File + RelativePath=".\ilbcfix\vq3.c" + > + </File> + <File + RelativePath=".\ilbcfix\vq3.h" + > + </File> + <File + RelativePath=".\ilbcfix\vq4.c" + > + </File> + <File + RelativePath=".\ilbcfix\vq4.h" + > + </File> + <File + RelativePath=".\ilbcfix\window32_w32.c" + > + </File> + <File + RelativePath=".\ilbcfix\window32_w32.h" + > + </File> + <File + RelativePath=".\ilbcfix\xcorr_coef.c" + > + </File> + <File + RelativePath=".\ilbcfix\xcorr_coef.h" + > + </File> + </Filter> + <Filter + Name="g711" + > + <File + RelativePath=".\g711\g711.c" + > + </File> + <File + RelativePath=".\g711\g711.h" + > + </File> + <File + RelativePath=".\g711\g711_interface.c" + > + </File> + <File + RelativePath=".\g711\g711_interface.h" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/webrtc/webrtc.vcxproj b/src/libs/webrtc/webrtc.vcxproj new file mode 100644 index 00000000..8993273e --- /dev/null +++ b/src/libs/webrtc/webrtc.vcxproj @@ -0,0 +1,469 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{8D9570F8-0940-4359-99AB-7B71A229D426}</ProjectGuid> + <RootNamespace>webrtc</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140_xp</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>.;..;./signal_processing_library;./utility;./cng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <WholeProgramOptimization>false</WholeProgramOptimization> + <AdditionalIncludeDirectories>.;..;./signal_processing_library;./utility;./cng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB; _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="vad\vad_const.c" /> + <ClCompile Include="vad\vad_core.c" /> + <ClCompile Include="vad\vad_filterbank.c" /> + <ClCompile Include="vad\vad_gmm.c" /> + <ClCompile Include="vad\vad_sp.c" /> + <ClCompile Include="vad\webrtc_vad.c" /> + <ClCompile Include="ns\noise_suppression.c" /> + <ClCompile Include="ns\noise_suppression_x.c" /> + <ClCompile Include="ns\ns_core.c" /> + <ClCompile Include="ns\nsx_core.c" /> + <ClCompile Include="aec\aec_core.c" /> + <ClCompile Include="aec\aec_core_rdft.c" /> + <ClCompile Include="aec\aec_core_sse2.c" /> + <ClCompile Include="aec\echo_cancellation.c" /> + <ClCompile Include="aec\resampler.c" /> + <ClCompile Include="aecm\aecm_core.c" /> + <ClCompile Include="aecm\echo_control_mobile.c" /> + <ClCompile Include="agc\analog_agc.c" /> + <ClCompile Include="agc\digital_agc.c" /> + <ClCompile Include="utility\fft4g.c" /> + <ClCompile Include="utility\ring_buffer.c" /> + <ClCompile Include="system_wrappers\atomic32.cc" /> + <ClCompile Include="system_wrappers\condition_variable.cc" /> + <ClCompile Include="system_wrappers\condition_variable_windows.cc" /> + <ClCompile Include="system_wrappers\cpu.cc" /> + <ClCompile Include="system_wrappers\cpu_features.cc" /> + <ClCompile Include="system_wrappers\cpu_windows.cc" /> + <ClCompile Include="system_wrappers\critical_section.cc" /> + <ClCompile Include="system_wrappers\critical_section_windows.cc" /> + <ClCompile Include="system_wrappers\event.cc" /> + <ClCompile Include="system_wrappers\event_windows.cc" /> + <ClCompile Include="system_wrappers\file_impl.cc" /> + <ClCompile Include="system_wrappers\rw_lock.cc" /> + <ClCompile Include="system_wrappers\rw_lock_generic.cc" /> + <ClCompile Include="system_wrappers\rw_lock_windows.cc" /> + <ClCompile Include="system_wrappers\sort.cc" /> + <ClCompile Include="system_wrappers\thread.cc" /> + <ClCompile Include="system_wrappers\thread_windows.cc" /> + <ClCompile Include="system_wrappers\trace_impl.cc" /> + <ClCompile Include="system_wrappers\trace_windows.cc" /> + <ClCompile Include="neteq\accelerate.c" /> + <ClCompile Include="neteq\automode.c" /> + <ClCompile Include="neteq\bgn_update.c" /> + <ClCompile Include="neteq\bufstats_decision.c" /> + <ClCompile Include="neteq\cng_internal.c" /> + <ClCompile Include="neteq\codec_db.c" /> + <ClCompile Include="neteq\correlator.c" /> + <ClCompile Include="neteq\dsp.c" /> + <ClCompile Include="neteq\dsp_helpfunctions.c" /> + <ClCompile Include="neteq\dtmf_buffer.c" /> + <ClCompile Include="neteq\dtmf_tonegen.c" /> + <ClCompile Include="neteq\expand.c" /> + <ClCompile Include="neteq\mcu_address_init.c" /> + <ClCompile Include="neteq\mcu_dsp_common.c" /> + <ClCompile Include="neteq\mcu_reset.c" /> + <ClCompile Include="neteq\merge.c" /> + <ClCompile Include="neteq\min_distortion.c" /> + <ClCompile Include="neteq\mix_voice_unvoice.c" /> + <ClCompile Include="neteq\mute_signal.c" /> + <ClCompile Include="neteq\normal.c" /> + <ClCompile Include="neteq\packet_buffer.c" /> + <ClCompile Include="neteq\peak_detection.c" /> + <ClCompile Include="neteq\preemptive_expand.c" /> + <ClCompile Include="neteq\random_vector.c" /> + <ClCompile Include="neteq\recin.c" /> + <ClCompile Include="neteq\recout.c" /> + <ClCompile Include="neteq\rtcp.c" /> + <ClCompile Include="neteq\rtp.c" /> + <ClCompile Include="neteq\set_fs.c" /> + <ClCompile Include="neteq\signal_mcu.c" /> + <ClCompile Include="neteq\split_and_insert.c" /> + <ClCompile Include="neteq\unmute_signal.c" /> + <ClCompile Include="neteq\webrtc_neteq.c" /> + <ClCompile Include="cng\cng_helpfuns.c" /> + <ClCompile Include="cng\webrtc_cng.c" /> + <ClCompile Include="signal_processing_library\add_sat_w16.c" /> + <ClCompile Include="signal_processing_library\add_sat_w32.c" /> + <ClCompile Include="signal_processing_library\auto_corr_to_refl_coef.c" /> + <ClCompile Include="signal_processing_library\auto_correlation.c" /> + <ClCompile Include="signal_processing_library\complex_bit_reverse.c" /> + <ClCompile Include="signal_processing_library\complex_fft.c" /> + <ClCompile Include="signal_processing_library\complex_ifft.c" /> + <ClCompile Include="signal_processing_library\copy_set_operations.c" /> + <ClCompile Include="signal_processing_library\cos_table.c" /> + <ClCompile Include="signal_processing_library\cross_correlation.c" /> + <ClCompile Include="signal_processing_library\division_operations.c" /> + <ClCompile Include="signal_processing_library\dot_product_with_scale.c" /> + <ClCompile Include="signal_processing_library\downsample_fast.c" /> + <ClCompile Include="signal_processing_library\energy.c" /> + <ClCompile Include="signal_processing_library\filter_ar.c" /> + <ClCompile Include="signal_processing_library\filter_ar_fast_q12.c" /> + <ClCompile Include="signal_processing_library\filter_ma_fast_q12.c" /> + <ClCompile Include="signal_processing_library\get_hanning_window.c" /> + <ClCompile Include="signal_processing_library\get_scaling_square.c" /> + <ClCompile Include="signal_processing_library\get_size_in_bits.c" /> + <ClCompile Include="signal_processing_library\hanning_table.c" /> + <ClCompile Include="signal_processing_library\ilbc_specific_functions.c" /> + <ClCompile Include="signal_processing_library\levinson_durbin.c" /> + <ClCompile Include="signal_processing_library\lpc_to_refl_coef.c" /> + <ClCompile Include="signal_processing_library\min_max_operations.c" /> + <ClCompile Include="signal_processing_library\norm_u32.c" /> + <ClCompile Include="signal_processing_library\norm_w16.c" /> + <ClCompile Include="signal_processing_library\norm_w32.c" /> + <ClCompile Include="signal_processing_library\randn_table.c" /> + <ClCompile Include="signal_processing_library\randomization_functions.c" /> + <ClCompile Include="signal_processing_library\refl_coef_to_lpc.c" /> + <ClCompile Include="signal_processing_library\resample.c" /> + <ClCompile Include="signal_processing_library\resample_48khz.c" /> + <ClCompile Include="signal_processing_library\resample_by_2.c" /> + <ClCompile Include="signal_processing_library\resample_by_2_internal.c" /> + <ClCompile Include="signal_processing_library\resample_fractional.c" /> + <ClCompile Include="signal_processing_library\sin_table.c" /> + <ClCompile Include="signal_processing_library\sin_table_1024.c" /> + <ClCompile Include="signal_processing_library\spl_sqrt.c" /> + <ClCompile Include="signal_processing_library\spl_version.c" /> + <ClCompile Include="signal_processing_library\splitting_filter.c" /> + <ClCompile Include="signal_processing_library\sqrt_of_one_minus_x_squared.c" /> + <ClCompile Include="signal_processing_library\sub_sat_w16.c" /> + <ClCompile Include="signal_processing_library\sub_sat_w32.c" /> + <ClCompile Include="signal_processing_library\vector_scaling_operations.c" /> + <ClCompile Include="signal_processing_library\webrtc_fft_t_1024_8.c" /> + <ClCompile Include="signal_processing_library\webrtc_fft_t_rad.c" /> + <ClCompile Include="isac\arith_routines.c" /> + <ClCompile Include="isac\arith_routines_hist.c" /> + <ClCompile Include="isac\arith_routines_logist.c" /> + <ClCompile Include="isac\bandwidth_estimator.c" /> + <ClCompile Include="isac\decode_bwe.c" /> + <ClCompile Include="isac\decode_plc.c" /> + <ClCompile Include="isac\encode.c" /> + <ClCompile Include="isac\entropy_coding.c" /> + <ClCompile Include="isac\fft.c" /> + <ClCompile Include="isac\filterbank_tables.c" /> + <ClCompile Include="isac\filterbanks.c" /> + <ClCompile Include="isac\initialize.c" /> + <ClCompile Include="isac\isac_decode.c" /> + <ClCompile Include="isac\isac_filters.c" /> + <ClCompile Include="isac\isacfix.c" /> + <ClCompile Include="isac\lattice.c" /> + <ClCompile Include="isac\lpc_masking_model.c" /> + <ClCompile Include="isac\lpc_tables.c" /> + <ClCompile Include="isac\pitch_estimator.c" /> + <ClCompile Include="isac\pitch_filter.c" /> + <ClCompile Include="isac\pitch_gain_tables.c" /> + <ClCompile Include="isac\pitch_lag_tables.c" /> + <ClCompile Include="isac\spectrum_ar_model_tables.c" /> + <ClCompile Include="isac\transform.c" /> + <ClCompile Include="ilbcfix\abs_quant.c" /> + <ClCompile Include="ilbcfix\abs_quant_loop.c" /> + <ClCompile Include="ilbcfix\augmented_cb_corr.c" /> + <ClCompile Include="ilbcfix\bw_expand.c" /> + <ClCompile Include="ilbcfix\cb_construct.c" /> + <ClCompile Include="ilbcfix\cb_mem_energy.c" /> + <ClCompile Include="ilbcfix\cb_mem_energy_augmentation.c" /> + <ClCompile Include="ilbcfix\cb_mem_energy_calc.c" /> + <ClCompile Include="ilbcfix\cb_search_core.c" /> + <ClCompile Include="ilbcfix\cb_update_best_index.c" /> + <ClCompile Include="ilbcfix\chebyshev.c" /> + <ClCompile Include="ilbcfix\comp_corr.c" /> + <ClCompile Include="ilbcfix\create_augmented_vec.c" /> + <ClCompile Include="ilbcfix\decode_residual.c" /> + <ClCompile Include="ilbcfix\decoder_interpolate_lsf.c" /> + <ClCompile Include="ilbcfix\do_plc.c" /> + <ClCompile Include="ilbcfix\energy_inverse.c" /> + <ClCompile Include="ilbcfix\enh_upsample.c" /> + <ClCompile Include="ilbcfix\enhancer.c" /> + <ClCompile Include="ilbcfix\enhancer_interface.c" /> + <ClCompile Include="ilbcfix\filtered_cb_vecs.c" /> + <ClCompile Include="ilbcfix\frame_classify.c" /> + <ClCompile Include="ilbcfix\gain_dequant.c" /> + <ClCompile Include="ilbcfix\gain_quant.c" /> + <ClCompile Include="ilbcfix\get_cd_vec.c" /> + <ClCompile Include="ilbcfix\get_lsp_poly.c" /> + <ClCompile Include="ilbcfix\get_sync_seq.c" /> + <ClCompile Include="ilbcfix\hp_input.c" /> + <ClCompile Include="ilbcfix\hp_output.c" /> + <ClCompile Include="ilbcfix\ilbc.c" /> + <ClCompile Include="ilbcfix\ilbc_cb_search.c" /> + <ClCompile Include="ilbcfix\ilbc_constants.c" /> + <ClCompile Include="ilbcfix\ilbc_decode.c" /> + <ClCompile Include="ilbcfix\ilbc_encode.c" /> + <ClCompile Include="ilbcfix\index_conv_dec.c" /> + <ClCompile Include="ilbcfix\index_conv_enc.c" /> + <ClCompile Include="ilbcfix\init_decode.c" /> + <ClCompile Include="ilbcfix\init_encode.c" /> + <ClCompile Include="ilbcfix\interpolate.c" /> + <ClCompile Include="ilbcfix\interpolate_samples.c" /> + <ClCompile Include="ilbcfix\lpc_encode.c" /> + <ClCompile Include="ilbcfix\lsf_check.c" /> + <ClCompile Include="ilbcfix\lsf_interpolate_to_poly_dec.c" /> + <ClCompile Include="ilbcfix\lsf_interpolate_to_poly_enc.c" /> + <ClCompile Include="ilbcfix\lsf_to_lsp.c" /> + <ClCompile Include="ilbcfix\lsf_to_poly.c" /> + <ClCompile Include="ilbcfix\lsp_to_lsf.c" /> + <ClCompile Include="ilbcfix\my_corr.c" /> + <ClCompile Include="ilbcfix\nearest_neighbor.c" /> + <ClCompile Include="ilbcfix\pack_bits.c" /> + <ClCompile Include="ilbcfix\poly_to_lsf.c" /> + <ClCompile Include="ilbcfix\poly_to_lsp.c" /> + <ClCompile Include="ilbcfix\refiner.c" /> + <ClCompile Include="ilbcfix\simple_interpolate_lsf.c" /> + <ClCompile Include="ilbcfix\simple_lpc_analysis.c" /> + <ClCompile Include="ilbcfix\simple_lsf_dequant.c" /> + <ClCompile Include="ilbcfix\simple_lsf_quant.c" /> + <ClCompile Include="ilbcfix\smooth.c" /> + <ClCompile Include="ilbcfix\smooth_out_data.c" /> + <ClCompile Include="ilbcfix\sort_sq.c" /> + <ClCompile Include="ilbcfix\split_vq.c" /> + <ClCompile Include="ilbcfix\state_construct.c" /> + <ClCompile Include="ilbcfix\state_search.c" /> + <ClCompile Include="ilbcfix\swap_bytes.c" /> + <ClCompile Include="ilbcfix\unpack_bits.c" /> + <ClCompile Include="ilbcfix\vq3.c" /> + <ClCompile Include="ilbcfix\vq4.c" /> + <ClCompile Include="ilbcfix\window32_w32.c" /> + <ClCompile Include="ilbcfix\xcorr_coef.c" /> + <ClCompile Include="g711\g711.c" /> + <ClCompile Include="g711\g711_interface.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="vad\vad_const.h" /> + <ClInclude Include="vad\vad_core.h" /> + <ClInclude Include="vad\vad_defines.h" /> + <ClInclude Include="vad\vad_filterbank.h" /> + <ClInclude Include="vad\vad_gmm.h" /> + <ClInclude Include="vad\vad_sp.h" /> + <ClInclude Include="vad\webrtc_vad.h" /> + <ClInclude Include="ns\defines.h" /> + <ClInclude Include="ns\noise_suppression.h" /> + <ClInclude Include="ns\noise_suppression_x.h" /> + <ClInclude Include="ns\ns_core.h" /> + <ClInclude Include="ns\nsx_core.h" /> + <ClInclude Include="ns\nsx_defines.h" /> + <ClInclude Include="ns\windows_private.h" /> + <ClInclude Include="aec\aec_core.h" /> + <ClInclude Include="aec\echo_cancellation.h" /> + <ClInclude Include="aec\resampler.h" /> + <ClInclude Include="aecm\aecm_core.h" /> + <ClInclude Include="aecm\echo_control_mobile.h" /> + <ClInclude Include="agc\analog_agc.h" /> + <ClInclude Include="agc\digital_agc.h" /> + <ClInclude Include="agc\gain_control.h" /> + <ClInclude Include="utility\fft4g.h" /> + <ClInclude Include="utility\ring_buffer.h" /> + <ClInclude Include="system_wrappers\aligned_malloc.h" /> + <ClInclude Include="system_wrappers\atomic32_windows.h" /> + <ClInclude Include="system_wrappers\atomic32_wrapper.h" /> + <ClInclude Include="system_wrappers\condition_variable_windows.h" /> + <ClInclude Include="system_wrappers\condition_variable_wrapper.h" /> + <ClInclude Include="system_wrappers\constructor_magic.h" /> + <ClInclude Include="system_wrappers\cpu_features_wrapper.h" /> + <ClInclude Include="system_wrappers\cpu_windows.h" /> + <ClInclude Include="system_wrappers\cpu_wrapper.h" /> + <ClInclude Include="system_wrappers\critical_section_windows.h" /> + <ClInclude Include="system_wrappers\critical_section_wrapper.h" /> + <ClInclude Include="system_wrappers\event_windows.h" /> + <ClInclude Include="system_wrappers\event_wrapper.h" /> + <ClInclude Include="system_wrappers\file_impl.h" /> + <ClInclude Include="system_wrappers\file_wrapper.h" /> + <ClInclude Include="system_wrappers\fix_interlocked_exchange_pointer_windows.h" /> + <ClInclude Include="system_wrappers\rw_lock_generic.h" /> + <ClInclude Include="system_wrappers\rw_lock_windows.h" /> + <ClInclude Include="system_wrappers\rw_lock_wrapper.h" /> + <ClInclude Include="system_wrappers\sort.h" /> + <ClInclude Include="system_wrappers\thread_windows.h" /> + <ClInclude Include="system_wrappers\thread_windows_set_name.h" /> + <ClInclude Include="system_wrappers\thread_wrapper.h" /> + <ClInclude Include="system_wrappers\tick_util.h" /> + <ClInclude Include="system_wrappers\trace.h" /> + <ClInclude Include="system_wrappers\trace_impl.h" /> + <ClInclude Include="system_wrappers\trace_windows.h" /> + <ClInclude Include="neteq\automode.h" /> + <ClInclude Include="neteq\buffer_stats.h" /> + <ClInclude Include="neteq\codec_db.h" /> + <ClInclude Include="neteq\codec_db_defines.h" /> + <ClInclude Include="neteq\delay_logging.h" /> + <ClInclude Include="neteq\dsp.h" /> + <ClInclude Include="neteq\dsp_helpfunctions.h" /> + <ClInclude Include="neteq\dtmf_buffer.h" /> + <ClInclude Include="neteq\dtmf_tonegen.h" /> + <ClInclude Include="neteq\mcu.h" /> + <ClInclude Include="neteq\mcu_dsp_common.h" /> + <ClInclude Include="neteq\neteq_defines.h" /> + <ClInclude Include="neteq\neteq_error_codes.h" /> + <ClInclude Include="neteq\neteq_statistics.h" /> + <ClInclude Include="neteq\packet_buffer.h" /> + <ClInclude Include="neteq\rtcp.h" /> + <ClInclude Include="neteq\rtp.h" /> + <ClInclude Include="neteq\webrtc_neteq.h" /> + <ClInclude Include="neteq\webrtc_neteq_help_macros.h" /> + <ClInclude Include="neteq\webrtc_neteq_internal.h" /> + <ClInclude Include="cng\cng_helpfuns.h" /> + <ClInclude Include="cng\webrtc_cng.h" /> + <ClInclude Include="signal_processing_library\resample_by_2_internal.h" /> + <ClInclude Include="signal_processing_library\signal_processing_library.h" /> + <ClInclude Include="signal_processing_library\spl_inl.h" /> + <ClInclude Include="isac\arith_routins.h" /> + <ClInclude Include="isac\bandwidth_estimator.h" /> + <ClInclude Include="isac\codec.h" /> + <ClInclude Include="isac\entropy_coding.h" /> + <ClInclude Include="isac\fft.h" /> + <ClInclude Include="isac\filterbank_tables.h" /> + <ClInclude Include="isac\isacfix.h" /> + <ClInclude Include="isac\lpc_masking_model.h" /> + <ClInclude Include="isac\lpc_tables.h" /> + <ClInclude Include="isac\pitch_estimator.h" /> + <ClInclude Include="isac\pitch_gain_tables.h" /> + <ClInclude Include="isac\pitch_lag_tables.h" /> + <ClInclude Include="isac\settings.h" /> + <ClInclude Include="isac\spectrum_ar_model_tables.h" /> + <ClInclude Include="isac\structs.h" /> + <ClInclude Include="ilbcfix\abs_quant.h" /> + <ClInclude Include="ilbcfix\abs_quant_loop.h" /> + <ClInclude Include="ilbcfix\augmented_cb_corr.h" /> + <ClInclude Include="ilbcfix\bw_expand.h" /> + <ClInclude Include="ilbcfix\cb_construct.h" /> + <ClInclude Include="ilbcfix\cb_mem_energy.h" /> + <ClInclude Include="ilbcfix\cb_mem_energy_augmentation.h" /> + <ClInclude Include="ilbcfix\cb_mem_energy_calc.h" /> + <ClInclude Include="ilbcfix\cb_search.h" /> + <ClInclude Include="ilbcfix\cb_search_core.h" /> + <ClInclude Include="ilbcfix\cb_update_best_index.h" /> + <ClInclude Include="ilbcfix\chebyshev.h" /> + <ClInclude Include="ilbcfix\comp_corr.h" /> + <ClInclude Include="ilbcfix\constants.h" /> + <ClInclude Include="ilbcfix\create_augmented_vec.h" /> + <ClInclude Include="ilbcfix\decode.h" /> + <ClInclude Include="ilbcfix\decode_residual.h" /> + <ClInclude Include="ilbcfix\decoder_interpolate_lsf.h" /> + <ClInclude Include="ilbcfix\defines.h" /> + <ClInclude Include="ilbcfix\do_plc.h" /> + <ClInclude Include="ilbcfix\encode.h" /> + <ClInclude Include="ilbcfix\energy_inverse.h" /> + <ClInclude Include="ilbcfix\enh_upsample.h" /> + <ClInclude Include="ilbcfix\enhancer.h" /> + <ClInclude Include="ilbcfix\enhancer_interface.h" /> + <ClInclude Include="ilbcfix\filtered_cb_vecs.h" /> + <ClInclude Include="ilbcfix\frame_classify.h" /> + <ClInclude Include="ilbcfix\gain_dequant.h" /> + <ClInclude Include="ilbcfix\gain_quant.h" /> + <ClInclude Include="ilbcfix\get_cd_vec.h" /> + <ClInclude Include="ilbcfix\get_lsp_poly.h" /> + <ClInclude Include="ilbcfix\get_sync_seq.h" /> + <ClInclude Include="ilbcfix\hp_input.h" /> + <ClInclude Include="ilbcfix\hp_output.h" /> + <ClInclude Include="ilbcfix\ilbc.h" /> + <ClInclude Include="ilbcfix\index_conv_dec.h" /> + <ClInclude Include="ilbcfix\index_conv_enc.h" /> + <ClInclude Include="ilbcfix\init_decode.h" /> + <ClInclude Include="ilbcfix\init_encode.h" /> + <ClInclude Include="ilbcfix\interpolate.h" /> + <ClInclude Include="ilbcfix\interpolate_samples.h" /> + <ClInclude Include="ilbcfix\lpc_encode.h" /> + <ClInclude Include="ilbcfix\lsf_check.h" /> + <ClInclude Include="ilbcfix\lsf_interpolate_to_poly_dec.h" /> + <ClInclude Include="ilbcfix\lsf_interpolate_to_poly_enc.h" /> + <ClInclude Include="ilbcfix\lsf_to_lsp.h" /> + <ClInclude Include="ilbcfix\lsf_to_poly.h" /> + <ClInclude Include="ilbcfix\lsp_to_lsf.h" /> + <ClInclude Include="ilbcfix\my_corr.h" /> + <ClInclude Include="ilbcfix\nearest_neighbor.h" /> + <ClInclude Include="ilbcfix\pack_bits.h" /> + <ClInclude Include="ilbcfix\poly_to_lsf.h" /> + <ClInclude Include="ilbcfix\poly_to_lsp.h" /> + <ClInclude Include="ilbcfix\refiner.h" /> + <ClInclude Include="ilbcfix\simple_interpolate_lsf.h" /> + <ClInclude Include="ilbcfix\simple_lpc_analysis.h" /> + <ClInclude Include="ilbcfix\simple_lsf_dequant.h" /> + <ClInclude Include="ilbcfix\simple_lsf_quant.h" /> + <ClInclude Include="ilbcfix\smooth.h" /> + <ClInclude Include="ilbcfix\smooth_out_data.h" /> + <ClInclude Include="ilbcfix\sort_sq.h" /> + <ClInclude Include="ilbcfix\split_vq.h" /> + <ClInclude Include="ilbcfix\state_construct.h" /> + <ClInclude Include="ilbcfix\state_search.h" /> + <ClInclude Include="ilbcfix\swap_bytes.h" /> + <ClInclude Include="ilbcfix\unpack_bits.h" /> + <ClInclude Include="ilbcfix\vq3.h" /> + <ClInclude Include="ilbcfix\vq4.h" /> + <ClInclude Include="ilbcfix\window32_w32.h" /> + <ClInclude Include="ilbcfix\xcorr_coef.h" /> + <ClInclude Include="g711\g711.h" /> + <ClInclude Include="g711\g711_interface.h" /> + </ItemGroup> + <ItemGroup> + <None Include="ilbcfix\complexityMeasures.m" /> + <None Include="ilbcfix\ilbc.gyp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/libs/webrtc/webrtc.vcxproj.filters b/src/libs/webrtc/webrtc.vcxproj.filters new file mode 100644 index 00000000..cdc006ad --- /dev/null +++ b/src/libs/webrtc/webrtc.vcxproj.filters @@ -0,0 +1,1196 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="vad"> + <UniqueIdentifier>{2ad8fa9f-4ef9-4657-a8cf-fc245d40c665}</UniqueIdentifier> + </Filter> + <Filter Include="ns"> + <UniqueIdentifier>{6048fbf6-1f8a-414b-817b-f3379d7b251c}</UniqueIdentifier> + </Filter> + <Filter Include="aec"> + <UniqueIdentifier>{f4614564-3c5c-4d77-bcc6-c09b47f6ebcb}</UniqueIdentifier> + </Filter> + <Filter Include="aecm"> + <UniqueIdentifier>{a5e859ec-621d-466b-acc6-b0dd5671e52d}</UniqueIdentifier> + </Filter> + <Filter Include="agc"> + <UniqueIdentifier>{c5f3a672-913e-4ce5-81db-a462db1dbedd}</UniqueIdentifier> + </Filter> + <Filter Include="utility"> + <UniqueIdentifier>{97dd2a01-db7e-4e3d-a569-318782404cf6}</UniqueIdentifier> + </Filter> + <Filter Include="system_wrappers"> + <UniqueIdentifier>{85a910e6-6810-4048-8731-47a78144d450}</UniqueIdentifier> + </Filter> + <Filter Include="neteq"> + <UniqueIdentifier>{e6ca5506-f0e8-4fbe-a270-4772c81799ff}</UniqueIdentifier> + </Filter> + <Filter Include="cng"> + <UniqueIdentifier>{9561d225-853b-433b-b4cf-842dfda8ac87}</UniqueIdentifier> + </Filter> + <Filter Include="signal_processing_library"> + <UniqueIdentifier>{85f7210d-7eef-4413-ad98-9ceb1f22c024}</UniqueIdentifier> + </Filter> + <Filter Include="isac"> + <UniqueIdentifier>{20d51533-0fc5-4f5f-9a6b-ca1bed458f0b}</UniqueIdentifier> + </Filter> + <Filter Include="ilbc"> + <UniqueIdentifier>{7d154d7a-4c42-4b59-aaa0-1fe681383f60}</UniqueIdentifier> + </Filter> + <Filter Include="g711"> + <UniqueIdentifier>{d40ee663-b254-470e-b0a7-4a35b274892a}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="vad\vad_const.c"> + <Filter>vad</Filter> + </ClCompile> + <ClCompile Include="vad\vad_core.c"> + <Filter>vad</Filter> + </ClCompile> + <ClCompile Include="vad\vad_filterbank.c"> + <Filter>vad</Filter> + </ClCompile> + <ClCompile Include="vad\vad_gmm.c"> + <Filter>vad</Filter> + </ClCompile> + <ClCompile Include="vad\vad_sp.c"> + <Filter>vad</Filter> + </ClCompile> + <ClCompile Include="vad\webrtc_vad.c"> + <Filter>vad</Filter> + </ClCompile> + <ClCompile Include="ns\noise_suppression.c"> + <Filter>ns</Filter> + </ClCompile> + <ClCompile Include="ns\noise_suppression_x.c"> + <Filter>ns</Filter> + </ClCompile> + <ClCompile Include="ns\ns_core.c"> + <Filter>ns</Filter> + </ClCompile> + <ClCompile Include="ns\nsx_core.c"> + <Filter>ns</Filter> + </ClCompile> + <ClCompile Include="aec\aec_core.c"> + <Filter>aec</Filter> + </ClCompile> + <ClCompile Include="aec\aec_core_rdft.c"> + <Filter>aec</Filter> + </ClCompile> + <ClCompile Include="aec\aec_core_sse2.c"> + <Filter>aec</Filter> + </ClCompile> + <ClCompile Include="aec\echo_cancellation.c"> + <Filter>aec</Filter> + </ClCompile> + <ClCompile Include="aec\resampler.c"> + <Filter>aec</Filter> + </ClCompile> + <ClCompile Include="aecm\aecm_core.c"> + <Filter>aecm</Filter> + </ClCompile> + <ClCompile Include="aecm\echo_control_mobile.c"> + <Filter>aecm</Filter> + </ClCompile> + <ClCompile Include="agc\analog_agc.c"> + <Filter>agc</Filter> + </ClCompile> + <ClCompile Include="agc\digital_agc.c"> + <Filter>agc</Filter> + </ClCompile> + <ClCompile Include="utility\fft4g.c"> + <Filter>utility</Filter> + </ClCompile> + <ClCompile Include="utility\ring_buffer.c"> + <Filter>utility</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\atomic32.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\condition_variable.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\condition_variable_windows.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\cpu.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\cpu_features.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\cpu_windows.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\critical_section.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\critical_section_windows.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\event.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\event_windows.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\file_impl.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\rw_lock.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\rw_lock_generic.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\rw_lock_windows.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\sort.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\thread.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\thread_windows.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\trace_impl.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="system_wrappers\trace_windows.cc"> + <Filter>system_wrappers</Filter> + </ClCompile> + <ClCompile Include="neteq\accelerate.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\automode.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\bgn_update.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\bufstats_decision.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\cng_internal.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\codec_db.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\correlator.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\dsp.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\dsp_helpfunctions.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\dtmf_buffer.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\dtmf_tonegen.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\expand.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\mcu_address_init.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\mcu_dsp_common.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\mcu_reset.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\merge.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\min_distortion.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\mix_voice_unvoice.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\mute_signal.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\normal.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\packet_buffer.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\peak_detection.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\preemptive_expand.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\random_vector.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\recin.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\recout.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\rtcp.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\rtp.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\set_fs.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\signal_mcu.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\split_and_insert.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\unmute_signal.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="neteq\webrtc_neteq.c"> + <Filter>neteq</Filter> + </ClCompile> + <ClCompile Include="cng\cng_helpfuns.c"> + <Filter>cng</Filter> + </ClCompile> + <ClCompile Include="cng\webrtc_cng.c"> + <Filter>cng</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\add_sat_w16.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\add_sat_w32.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\auto_corr_to_refl_coef.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\auto_correlation.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\complex_bit_reverse.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\complex_fft.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\complex_ifft.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\copy_set_operations.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\cos_table.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\cross_correlation.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\division_operations.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\dot_product_with_scale.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\downsample_fast.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\energy.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\filter_ar.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\filter_ar_fast_q12.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\filter_ma_fast_q12.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\get_hanning_window.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\get_scaling_square.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\get_size_in_bits.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\hanning_table.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\ilbc_specific_functions.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\levinson_durbin.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\lpc_to_refl_coef.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\min_max_operations.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\norm_u32.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\norm_w16.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\norm_w32.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\randn_table.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\randomization_functions.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\refl_coef_to_lpc.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\resample.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\resample_48khz.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\resample_by_2.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\resample_by_2_internal.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\resample_fractional.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\sin_table.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\sin_table_1024.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\spl_sqrt.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\spl_version.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\splitting_filter.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\sqrt_of_one_minus_x_squared.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\sub_sat_w16.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\sub_sat_w32.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\vector_scaling_operations.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\webrtc_fft_t_1024_8.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="signal_processing_library\webrtc_fft_t_rad.c"> + <Filter>signal_processing_library</Filter> + </ClCompile> + <ClCompile Include="isac\arith_routines.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\arith_routines_hist.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\arith_routines_logist.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\bandwidth_estimator.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\decode_bwe.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\decode_plc.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\encode.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\entropy_coding.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\fft.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\filterbank_tables.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\filterbanks.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\initialize.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\isac_decode.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\isac_filters.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\isacfix.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\lattice.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\lpc_masking_model.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\lpc_tables.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\pitch_estimator.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\pitch_filter.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\pitch_gain_tables.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\pitch_lag_tables.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\spectrum_ar_model_tables.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="isac\transform.c"> + <Filter>isac</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\abs_quant.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\abs_quant_loop.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\augmented_cb_corr.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\bw_expand.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\cb_construct.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\cb_mem_energy.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\cb_mem_energy_augmentation.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\cb_mem_energy_calc.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\cb_search_core.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\cb_update_best_index.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\chebyshev.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\comp_corr.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\create_augmented_vec.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\decode_residual.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\decoder_interpolate_lsf.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\do_plc.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\energy_inverse.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\enh_upsample.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\enhancer.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\enhancer_interface.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\filtered_cb_vecs.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\frame_classify.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\gain_dequant.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\gain_quant.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\get_cd_vec.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\get_lsp_poly.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\get_sync_seq.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\hp_input.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\hp_output.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\ilbc.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\ilbc_cb_search.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\ilbc_constants.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\ilbc_decode.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\ilbc_encode.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\index_conv_dec.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\index_conv_enc.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\init_decode.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\init_encode.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\interpolate.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\interpolate_samples.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\lpc_encode.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\lsf_check.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\lsf_interpolate_to_poly_dec.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\lsf_interpolate_to_poly_enc.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\lsf_to_lsp.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\lsf_to_poly.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\lsp_to_lsf.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\my_corr.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\nearest_neighbor.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\pack_bits.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\poly_to_lsf.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\poly_to_lsp.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\refiner.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\simple_interpolate_lsf.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\simple_lpc_analysis.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\simple_lsf_dequant.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\simple_lsf_quant.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\smooth.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\smooth_out_data.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\sort_sq.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\split_vq.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\state_construct.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\state_search.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\swap_bytes.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\unpack_bits.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\vq3.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\vq4.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\window32_w32.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="ilbcfix\xcorr_coef.c"> + <Filter>ilbc</Filter> + </ClCompile> + <ClCompile Include="g711\g711.c"> + <Filter>g711</Filter> + </ClCompile> + <ClCompile Include="g711\g711_interface.c"> + <Filter>g711</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="vad\vad_const.h"> + <Filter>vad</Filter> + </ClInclude> + <ClInclude Include="vad\vad_core.h"> + <Filter>vad</Filter> + </ClInclude> + <ClInclude Include="vad\vad_defines.h"> + <Filter>vad</Filter> + </ClInclude> + <ClInclude Include="vad\vad_filterbank.h"> + <Filter>vad</Filter> + </ClInclude> + <ClInclude Include="vad\vad_gmm.h"> + <Filter>vad</Filter> + </ClInclude> + <ClInclude Include="vad\vad_sp.h"> + <Filter>vad</Filter> + </ClInclude> + <ClInclude Include="vad\webrtc_vad.h"> + <Filter>vad</Filter> + </ClInclude> + <ClInclude Include="ns\defines.h"> + <Filter>ns</Filter> + </ClInclude> + <ClInclude Include="ns\noise_suppression.h"> + <Filter>ns</Filter> + </ClInclude> + <ClInclude Include="ns\noise_suppression_x.h"> + <Filter>ns</Filter> + </ClInclude> + <ClInclude Include="ns\ns_core.h"> + <Filter>ns</Filter> + </ClInclude> + <ClInclude Include="ns\nsx_core.h"> + <Filter>ns</Filter> + </ClInclude> + <ClInclude Include="ns\nsx_defines.h"> + <Filter>ns</Filter> + </ClInclude> + <ClInclude Include="ns\windows_private.h"> + <Filter>ns</Filter> + </ClInclude> + <ClInclude Include="aec\aec_core.h"> + <Filter>aec</Filter> + </ClInclude> + <ClInclude Include="aec\echo_cancellation.h"> + <Filter>aec</Filter> + </ClInclude> + <ClInclude Include="aec\resampler.h"> + <Filter>aec</Filter> + </ClInclude> + <ClInclude Include="aecm\aecm_core.h"> + <Filter>aecm</Filter> + </ClInclude> + <ClInclude Include="aecm\echo_control_mobile.h"> + <Filter>aecm</Filter> + </ClInclude> + <ClInclude Include="agc\analog_agc.h"> + <Filter>agc</Filter> + </ClInclude> + <ClInclude Include="agc\digital_agc.h"> + <Filter>agc</Filter> + </ClInclude> + <ClInclude Include="agc\gain_control.h"> + <Filter>agc</Filter> + </ClInclude> + <ClInclude Include="utility\fft4g.h"> + <Filter>utility</Filter> + </ClInclude> + <ClInclude Include="utility\ring_buffer.h"> + <Filter>utility</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\aligned_malloc.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\atomic32_windows.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\atomic32_wrapper.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\condition_variable_windows.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\condition_variable_wrapper.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\constructor_magic.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\cpu_features_wrapper.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\cpu_windows.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\cpu_wrapper.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\critical_section_windows.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\critical_section_wrapper.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\event_windows.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\event_wrapper.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\file_impl.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\file_wrapper.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\fix_interlocked_exchange_pointer_windows.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\rw_lock_generic.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\rw_lock_windows.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\rw_lock_wrapper.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\sort.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\thread_windows.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\thread_windows_set_name.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\thread_wrapper.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\tick_util.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\trace.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\trace_impl.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="system_wrappers\trace_windows.h"> + <Filter>system_wrappers</Filter> + </ClInclude> + <ClInclude Include="neteq\automode.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\buffer_stats.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\codec_db.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\codec_db_defines.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\delay_logging.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\dsp.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\dsp_helpfunctions.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\dtmf_buffer.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\dtmf_tonegen.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\mcu.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\mcu_dsp_common.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\neteq_defines.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\neteq_error_codes.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\neteq_statistics.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\packet_buffer.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\rtcp.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\rtp.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\webrtc_neteq.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\webrtc_neteq_help_macros.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="neteq\webrtc_neteq_internal.h"> + <Filter>neteq</Filter> + </ClInclude> + <ClInclude Include="cng\cng_helpfuns.h"> + <Filter>cng</Filter> + </ClInclude> + <ClInclude Include="cng\webrtc_cng.h"> + <Filter>cng</Filter> + </ClInclude> + <ClInclude Include="signal_processing_library\resample_by_2_internal.h"> + <Filter>signal_processing_library</Filter> + </ClInclude> + <ClInclude Include="signal_processing_library\signal_processing_library.h"> + <Filter>signal_processing_library</Filter> + </ClInclude> + <ClInclude Include="signal_processing_library\spl_inl.h"> + <Filter>signal_processing_library</Filter> + </ClInclude> + <ClInclude Include="isac\arith_routins.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\bandwidth_estimator.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\codec.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\entropy_coding.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\fft.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\filterbank_tables.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\isacfix.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\lpc_masking_model.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\lpc_tables.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\pitch_estimator.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\pitch_gain_tables.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\pitch_lag_tables.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\settings.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\spectrum_ar_model_tables.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="isac\structs.h"> + <Filter>isac</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\abs_quant.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\abs_quant_loop.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\augmented_cb_corr.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\bw_expand.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\cb_construct.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\cb_mem_energy.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\cb_mem_energy_augmentation.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\cb_mem_energy_calc.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\cb_search.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\cb_search_core.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\cb_update_best_index.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\chebyshev.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\comp_corr.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\constants.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\create_augmented_vec.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\decode.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\decode_residual.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\decoder_interpolate_lsf.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\defines.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\do_plc.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\encode.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\energy_inverse.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\enh_upsample.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\enhancer.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\enhancer_interface.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\filtered_cb_vecs.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\frame_classify.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\gain_dequant.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\gain_quant.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\get_cd_vec.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\get_lsp_poly.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\get_sync_seq.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\hp_input.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\hp_output.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\ilbc.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\index_conv_dec.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\index_conv_enc.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\init_decode.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\init_encode.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\interpolate.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\interpolate_samples.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\lpc_encode.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\lsf_check.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\lsf_interpolate_to_poly_dec.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\lsf_interpolate_to_poly_enc.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\lsf_to_lsp.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\lsf_to_poly.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\lsp_to_lsf.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\my_corr.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\nearest_neighbor.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\pack_bits.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\poly_to_lsf.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\poly_to_lsp.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\refiner.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\simple_interpolate_lsf.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\simple_lpc_analysis.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\simple_lsf_dequant.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\simple_lsf_quant.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\smooth.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\smooth_out_data.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\sort_sq.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\split_vq.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\state_construct.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\state_search.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\swap_bytes.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\unpack_bits.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\vq3.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\vq4.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\window32_w32.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="ilbcfix\xcorr_coef.h"> + <Filter>ilbc</Filter> + </ClInclude> + <ClInclude Include="g711\g711.h"> + <Filter>g711</Filter> + </ClInclude> + <ClInclude Include="g711\g711_interface.h"> + <Filter>g711</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="ilbcfix\complexityMeasures.m"> + <Filter>ilbc</Filter> + </None> + <None Include="ilbcfix\ilbc.gyp"> + <Filter>ilbc</Filter> + </None> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/libs/webrtc/webrtc.vcxproj.user b/src/libs/webrtc/webrtc.vcxproj.user new file mode 100644 index 00000000..abe8dd89 --- /dev/null +++ b/src/libs/webrtc/webrtc.vcxproj.user @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup /> +</Project> \ No newline at end of file diff --git a/src/media-engine.vcxproj b/src/media-engine.vcxproj new file mode 100644 index 00000000..4a280a93 --- /dev/null +++ b/src/media-engine.vcxproj @@ -0,0 +1,221 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="libs\jrtplib\jrtplib.vcxproj"> + <Project>{d39837a7-419f-4751-a090-429f4d3b0038}</Project> + </ProjectReference> + <ProjectReference Include="libs\opencore-amr\opencore-amr-nb.vcxproj"> + <Project>{3480045b-45d9-48b5-befa-1b7a75652606}</Project> + </ProjectReference> + <ProjectReference Include="libs\speex\win32\VS2008\libspeexdsp\libspeexdsp.vcxproj"> + <Project>{03207781-0d1c-4db3-a71d-45c608f28dbd}</Project> + </ProjectReference> + <ProjectReference Include="libs\srtp\srtp.vcxproj"> + <Project>{c12a2037-3000-49a1-a007-a7e641d4fc38}</Project> + </ProjectReference> + <ProjectReference Include="libs\webrtc\webrtc.vcxproj"> + <Project>{8d9570f8-0940-4359-99ab-7b71a229d426}</Project> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <ClCompile Include="engine\audio\Audio_DataWindow.cpp" /> + <ClCompile Include="engine\audio\Audio_Resampler.cpp" /> + <ClCompile Include="engine\helper\HL_AsyncCommand.cpp" /> + <ClCompile Include="engine\helper\HL_Log.cpp" /> + <ClCompile Include="engine\helper\HL_NetworkFrame.cpp" /> + <ClCompile Include="engine\helper\HL_NetworkSocket.cpp" /> + <ClCompile Include="engine\helper\HL_OsVersion.cpp" /> + <ClCompile Include="engine\helper\HL_Pointer.cpp" /> + <ClCompile Include="engine\helper\HL_Rtp.cpp" /> + <ClCompile Include="engine\helper\HL_SocketHeap.cpp" /> + <ClCompile Include="engine\helper\HL_String.cpp" /> + <ClCompile Include="engine\helper\HL_Sync.cpp" /> + <ClCompile Include="engine\helper\HL_Usb.cpp" /> + <ClCompile Include="engine\helper\HL_VariantMap.cpp" /> + <ClCompile Include="engine\helper\HL_WavFile.cpp" /> + <ClCompile Include="engine\media\MT_AudioCodec.cpp" /> + <ClCompile Include="engine\media\MT_AudioReceiver.cpp" /> + <ClCompile Include="engine\media\MT_AudioStream.cpp" /> + <ClCompile Include="engine\media\MT_Box.cpp" /> + <ClCompile Include="engine\media\MT_Codec.cpp" /> + <ClCompile Include="engine\media\MT_CodecList.cpp" /> + <ClCompile Include="engine\media\MT_Dtmf.cpp" /> + <ClCompile Include="engine\media\MT_NativeRtpSender.cpp" /> + <ClCompile Include="engine\media\MT_SingleAudioStream.cpp" /> + <ClCompile Include="engine\media\MT_SrtpHelper.cpp" /> + <ClCompile Include="engine\media\MT_Stream.cpp" /> + <ClCompile Include="engine\media\MT_WebRtc.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="engine\audio\Audio_DataWindow.h" /> + <ClInclude Include="engine\audio\Audio_Resampler.h" /> + <ClInclude Include="engine\config.h" /> + <ClInclude Include="engine\helper\HL_AsyncCommand.h" /> + <ClInclude Include="engine\helper\HL_ByteBuffer.h" /> + <ClInclude Include="engine\helper\HL_Exception.h" /> + <ClInclude Include="engine\helper\HL_InternetAddress.h" /> + <ClInclude Include="engine\helper\HL_Log.h" /> + <ClInclude Include="engine\helper\HL_NetworkFrame.h" /> + <ClInclude Include="engine\helper\HL_NetworkSocket.h" /> + <ClInclude Include="engine\helper\HL_OsVersion.h" /> + <ClInclude Include="engine\helper\HL_Pointer.h" /> + <ClInclude Include="engine\helper\HL_Rtp.h" /> + <ClInclude Include="engine\helper\HL_SocketHeap.h" /> + <ClInclude Include="engine\helper\HL_StreamState.h" /> + <ClInclude Include="engine\helper\HL_String.h" /> + <ClInclude Include="engine\helper\HL_Sync.h" /> + <ClInclude Include="engine\helper\HL_Types.h" /> + <ClInclude Include="engine\helper\HL_Usb.h" /> + <ClInclude Include="engine\helper\HL_VariantMap.h" /> + <ClInclude Include="engine\helper\HL_WavFile.h" /> + <ClInclude Include="engine\media\MT_AudioCodec.h" /> + <ClInclude Include="engine\media\MT_AudioReceiver.h" /> + <ClInclude Include="engine\media\MT_AudioStream.h" /> + <ClInclude Include="engine\media\MT_Box.h" /> + <ClInclude Include="engine\media\MT_Codec.h" /> + <ClInclude Include="engine\media\MT_CodecList.h" /> + <ClInclude Include="engine\media\MT_Dtmf.h" /> + <ClInclude Include="engine\media\MT_NativeRtpSender.h" /> + <ClInclude Include="engine\media\MT_SingleAudioStream.h" /> + <ClInclude Include="engine\media\MT_SrtpHelper.h" /> + <ClInclude Include="engine\media\MT_Stream.h" /> + <ClInclude Include="engine\media\MT_WebRtc.h" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{14853B13-AC80-4BE8-81BC-552FFADA910F}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>mediaengine</RootNamespace> + <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;USE_RESIP_INTEGRATION;TARGET_WIN;USE_NATIVE_SMARTPTR;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(ProjectDir)\libs;$(ProjectDir)\libs\jrtplib\src;$(ProjectDir)\libs\speex\include;$(ProjectDir)\libs\srtp\include;$(ProjectDir)\libs\srtp\crypto\include;$(ProjectDir)\libs\webrtc;$(ProjectDir)\libs\ice;$(ProjectDir)\libs\resiprocate\;$(ProjectDir)\libs\resiprocate\rutil;$(ProjectDir)\libs\resiprocate\resip\stack;$(ProjectDir)\libs\resiprocate\resip\dum;$(ProjectDir)\libs\resiprocate\contrib\ares</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;USE_RESIP_INTEGRATION;TARGET_WIN;USE_NATIVE_SMARTPTR;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(ProjectDir)\libs;$(ProjectDir)\libs\jrtplib\src;$(ProjectDir)\libs\speex\include;$(ProjectDir)\libs\srtp\include;$(ProjectDir)\libs\srtp\crypto\include;$(ProjectDir)\libs\webrtc;$(ProjectDir)\libs\ice;$(ProjectDir)\libs\resiprocate\;$(ProjectDir)\libs\resiprocate\rutil;$(ProjectDir)\libs\resiprocate\resip\stack;$(ProjectDir)\libs\resiprocate\resip\dum;$(ProjectDir)\libs\resiprocate\contrib\ares</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;USE_RESIP_INTEGRATION;TARGET_WIN;USE_NATIVE_SMARTPTR;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(ProjectDir)\libs;$(ProjectDir)\libs\jrtplib\src;$(ProjectDir)\libs\speex\include;$(ProjectDir)\libs\srtp\include;$(ProjectDir)\libs\srtp\crypto\include;$(ProjectDir)\libs\webrtc;$(ProjectDir)\libs\ice;$(ProjectDir)\libs\resiprocate\;$(ProjectDir)\libs\resiprocate\rutil;$(ProjectDir)\libs\resiprocate\resip\stack;$(ProjectDir)\libs\resiprocate\resip\dum;$(ProjectDir)\libs\resiprocate\contrib\ares</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;USE_RESIP_INTEGRATION;TARGET_WIN;USE_NATIVE_SMARTPTR;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(ProjectDir)\libs;$(ProjectDir)\libs\jrtplib\src;$(ProjectDir)\libs\speex\include;$(ProjectDir)\libs\srtp\include;$(ProjectDir)\libs\srtp\crypto\include;$(ProjectDir)\libs\webrtc;$(ProjectDir)\libs\ice;$(ProjectDir)\libs\resiprocate\;$(ProjectDir)\libs\resiprocate\rutil;$(ProjectDir)\libs\resiprocate\resip\stack;$(ProjectDir)\libs\resiprocate\resip\dum;$(ProjectDir)\libs\resiprocate\contrib\ares</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/media-engine.vcxproj.filters b/src/media-engine.vcxproj.filters new file mode 100644 index 00000000..4acf3e84 --- /dev/null +++ b/src/media-engine.vcxproj.filters @@ -0,0 +1,196 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="media"> + <UniqueIdentifier>{531df363-8c48-434c-a6e4-0bca1c14604c}</UniqueIdentifier> + </Filter> + <Filter Include="helper"> + <UniqueIdentifier>{6848d33a-bf28-4d5c-984e-75774898ecbd}</UniqueIdentifier> + </Filter> + <Filter Include="audio"> + <UniqueIdentifier>{2f7b9757-6023-46f5-874a-402f72213ad7}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="engine\helper\HL_AsyncCommand.cpp"> + <Filter>helper</Filter> + </ClCompile> + <ClCompile Include="engine\helper\HL_Log.cpp"> + <Filter>helper</Filter> + </ClCompile> + <ClCompile Include="engine\helper\HL_NetworkSocket.cpp"> + <Filter>helper</Filter> + </ClCompile> + <ClCompile Include="engine\helper\HL_OsVersion.cpp"> + <Filter>helper</Filter> + </ClCompile> + <ClCompile Include="engine\helper\HL_Pointer.cpp"> + <Filter>helper</Filter> + </ClCompile> + <ClCompile Include="engine\helper\HL_Rtp.cpp"> + <Filter>helper</Filter> + </ClCompile> + <ClCompile Include="engine\helper\HL_SocketHeap.cpp"> + <Filter>helper</Filter> + </ClCompile> + <ClCompile Include="engine\helper\HL_String.cpp"> + <Filter>helper</Filter> + </ClCompile> + <ClCompile Include="engine\helper\HL_Sync.cpp"> + <Filter>helper</Filter> + </ClCompile> + <ClCompile Include="engine\helper\HL_Usb.cpp"> + <Filter>helper</Filter> + </ClCompile> + <ClCompile Include="engine\helper\HL_VariantMap.cpp"> + <Filter>helper</Filter> + </ClCompile> + <ClCompile Include="engine\helper\HL_WavFile.cpp"> + <Filter>helper</Filter> + </ClCompile> + <ClCompile Include="engine\media\MT_AudioCodec.cpp"> + <Filter>media</Filter> + </ClCompile> + <ClCompile Include="engine\media\MT_AudioReceiver.cpp"> + <Filter>media</Filter> + </ClCompile> + <ClCompile Include="engine\media\MT_AudioStream.cpp"> + <Filter>media</Filter> + </ClCompile> + <ClCompile Include="engine\media\MT_Box.cpp"> + <Filter>media</Filter> + </ClCompile> + <ClCompile Include="engine\media\MT_Codec.cpp"> + <Filter>media</Filter> + </ClCompile> + <ClCompile Include="engine\media\MT_CodecList.cpp"> + <Filter>media</Filter> + </ClCompile> + <ClCompile Include="engine\media\MT_Dtmf.cpp"> + <Filter>media</Filter> + </ClCompile> + <ClCompile Include="engine\media\MT_NativeRtpSender.cpp"> + <Filter>media</Filter> + </ClCompile> + <ClCompile Include="engine\media\MT_SingleAudioStream.cpp"> + <Filter>media</Filter> + </ClCompile> + <ClCompile Include="engine\media\MT_SrtpHelper.cpp"> + <Filter>media</Filter> + </ClCompile> + <ClCompile Include="engine\media\MT_Stream.cpp"> + <Filter>media</Filter> + </ClCompile> + <ClCompile Include="engine\media\MT_WebRtc.cpp"> + <Filter>media</Filter> + </ClCompile> + <ClCompile Include="engine\audio\Audio_DataWindow.cpp"> + <Filter>audio</Filter> + </ClCompile> + <ClCompile Include="engine\audio\Audio_Resampler.cpp"> + <Filter>audio</Filter> + </ClCompile> + <ClCompile Include="engine\helper\HL_NetworkFrame.cpp"> + <Filter>helper</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="engine\helper\HL_AsyncCommand.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_ByteBuffer.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_Exception.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_InternetAddress.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_Log.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_NetworkSocket.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_OsVersion.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_Pointer.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_Rtp.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_SocketHeap.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_StreamState.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_String.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_Sync.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_Types.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_Usb.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_VariantMap.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_WavFile.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\media\MT_AudioCodec.h"> + <Filter>media</Filter> + </ClInclude> + <ClInclude Include="engine\media\MT_AudioReceiver.h"> + <Filter>media</Filter> + </ClInclude> + <ClInclude Include="engine\media\MT_AudioStream.h"> + <Filter>media</Filter> + </ClInclude> + <ClInclude Include="engine\media\MT_Box.h"> + <Filter>media</Filter> + </ClInclude> + <ClInclude Include="engine\media\MT_Codec.h"> + <Filter>media</Filter> + </ClInclude> + <ClInclude Include="engine\media\MT_CodecList.h"> + <Filter>media</Filter> + </ClInclude> + <ClInclude Include="engine\media\MT_Dtmf.h"> + <Filter>media</Filter> + </ClInclude> + <ClInclude Include="engine\media\MT_NativeRtpSender.h"> + <Filter>media</Filter> + </ClInclude> + <ClInclude Include="engine\media\MT_SingleAudioStream.h"> + <Filter>media</Filter> + </ClInclude> + <ClInclude Include="engine\media\MT_SrtpHelper.h"> + <Filter>media</Filter> + </ClInclude> + <ClInclude Include="engine\media\MT_Stream.h"> + <Filter>media</Filter> + </ClInclude> + <ClInclude Include="engine\media\MT_WebRtc.h"> + <Filter>media</Filter> + </ClInclude> + <ClInclude Include="engine\audio\Audio_DataWindow.h"> + <Filter>audio</Filter> + </ClInclude> + <ClInclude Include="engine\audio\Audio_Resampler.h"> + <Filter>audio</Filter> + </ClInclude> + <ClInclude Include="engine\helper\HL_NetworkFrame.h"> + <Filter>helper</Filter> + </ClInclude> + <ClInclude Include="engine\config.h" /> + </ItemGroup> +</Project> \ No newline at end of file